Hello, Guest the thread was viewed50k times and contains 240 replies

last post from Retrofan at the

Render-Engine für Proportionalfonts im Bitmap Mode

  • Im C64 OS/GUI-Thread wurde mal angeregt, man könne doch (zumindest) ein GUI-Projekt in viel kleine Teilaufgaben zerlegen und erstmal gucken, ob man die in den Griff bekommt. Und da ergeben sich ja auch kleine nützliche Projekte, die man völlig losgelöst von einem GUI oder OS gut gebrauchen kann, z.B. auch für Games. Was ein Bitmap-GUI angeht, benötigt man zwingend ein paar Routinen, wie z.B. zum Zeichnen von (min. horizontalen) Linien (mit denen man dann auch Kästen füllen/löschen kann), eine Scrollroutine und auch eine Font-Render-Engine. Und die ist jetzt mein Thema:


    Gäbe es interessierte Programmierer, die sich darauf einlassen würden, in einer Art Wettstreit zu versuchen, die schnellste und/oder RAM-sparendste Bitmap-Font-Render-Routine aller Zeiten für den C64 zu programmieren?


    Und wie sollten die Regeln/Vorgaben lauten, damit das ganze fair und interessant abläuft? Was mir so als erster Vorschlag in den Sinn kommt: Die Routine sollte mit 8-Bit-kodierten Fonts umgehen können, deren einzelne Zeichen max. 8x8 px groß sind (also im Prinzip übliche 2K C64-Charsets, nur halt nicht unbedingt mit PETSCII-Belegung und nicht monospaced). Die Zeichen im Charset sind unterschiedlich breit und es soll nach jedem Zeichen eine freie Pixelspalte (ergo: Zeichenabstand) folgen (denkbar wäre auch eine zusätzliche Breiten-Tabelle, falls das beschleunigend wirken könnte). Die Ausgabe soll linksbündig erfolgen und am (einstellbaren) Zeilenende (max. 320 px Breite) soll ein Wortumbruch erfolgen. Sollte man den Zeilenabstand fest oder frei definieren? Und dann sollte man zur guten und fairen Messung mit einem vorgegebenen Text den Bildschirm 10x von der Routine füllen lassen (kein Scrolling). Neben dem zeitlichen Ergebnis zählt aber auch der RAM-Verbrauch – da weiß ich nur noch nicht, wie man den bewerten soll. Ich denke, man sollte auch die Speicherbereiche definieren, in denen die Routine, der Font und die Bitmap liegen sollen.


    Was ich liefern könnte: In Zusammenarbeit mit interessierten Programmierern die Vorgaben festklopfen. Einen Zeichensatz liefern, der die Vorgaben erfüllt (ich habe einen proportionalen Zeichensatz im C64-Format – mit ASCII-Belegung). Einen Text, den alle Teilnehmer für die Zeitmessung nutzen können. Und ich würde mich um das Sammeln der Ergebnisse (bis zur Deadline geheim?) und Ausrufen des Gewinners kümmern. Einen Preis kann ich leider nicht bieten – die Ehre, die schnellste Font-Render-Routine aller Zeiten auf dem C64 programmiert zu haben, muss also reichen. ;)


    So, was haltet ihr davon – gibt es Interessenten für so einen Wettbewerb?


    Hier noch ein Beispiel für so eine Text-Routine in einem Spiel:



    Enchanter von Bit Shifter

  • Das Problem -im Zusammenhang mit einem OS- Düfte das Trade-Off zwischen Schnelligkeit und Größe sein. Man kann sicher etliche KB 'sinnvoll' verwenden, um einen Geschwindigkeitsrekord zu brechen.

    Vielleicht dann eher pragmatisch?

    Die kleinste Routine die einen Bildschirm im Schnitt unter 1/2 Sekunde = 25 Frames mit Proportional font beschreibt oder sowas.

  • Die kleinste Routine die einen Bildschirm im Schnitt unter 1/2 Sekunde = 25 Frames mit Proportional font beschreibt oder sowas.

    Das wäre dann quasi umgekehrt, also die Zeit vorgeben und dann die Größe bewerten?


    Hexworx hat so eine Routine auch schonmal programmiert

  • Ja, zumindest maximal Zeit um eben 'anwendbar' zu bleiben. Wenn man extrem Platz für ne Compo spart könnten absurde langsame Varianten entstehen. Ebenso wie 60KB für nen schnellen Plotter. Kein Problem.

    Als Beispiel für die kreative Auslegung bei Compos:

    Ein Code der alle denkbaren Bitmuster durch permutiert. Der Text ist dann garantiert auch dabei.

  • Ja, zumindest maximal Zeit um eben 'anwendbar' zu bleiben.

    Man könnte das aber auch wieder umdrehen, wenn man eine realistische Vorstellung davon hat, wieviel RAM so eine Routine überhaupt beanspruchen darf (wenn sie nur ein kleiner Teil eines großen Ganzen wäre). Man könnte sich vielleicht am Speicherverbrauch der Render-Engine von GEOS (oder der von Enchanter) orientieren und innerhalb dieser RAM-Grenzen dann versuchen, etwas schnelleres hinzubekommen. Aber letztlich können immer noch die potentiellen Teilnehmer entscheiden, was SIE spannender beim Programmieren fänden. Für mich als außenstehender ist Speed halt spektakulärer als Speicherbedarf, weswegen ich letzteren eher festsetzen würde.


    Hat denn überhaupt jemand Interesse an so einer Challenge?

  • Retrofan

    Die Idee eine GUI bzw. Hilfsroutinen schrittweise umzusetzen finde ich gut.


    (((Seit einigen Jahren habe ich mir bereits selbst viele Gedanken rund um eine GUI/ein OS gemacht und mir viele Details erträumt bzw. in meinem kleinen Köpfchen zurechtgelegt, über das Thema nachgedacht und meditiert...etc. pp. Ich finde das Thema sehr spannend.)))


    Ich würde keine Challenge starten, sondern einfach wie in dem anderen Programmierthread(s) loslegen, weil so anscheinend am schnellsten Ergebnisse zu sehen sind und Ideen/Sichtweisen eingebracht und kombiniert werden können. Die Hürde zum "Mitmachen/Mitdenken" ist scheinbar geringer, weil es keinen Aufwand gibt.

    Also starten wir einfach mal mit einer Skizze:

    - Ich gehe davon aus, dass die Y-Koordinate frei wählbar sein soll.

    - Die Aufgabe einen String auszugeben, lässt sich vorerst auf die effiziente Ausgabe eines Zeichens reduzieren.

    - Ein Zeichen auszugeben, lässt sich darauf reduzieren, max. 8 Zeilen mit je max. 2 Bytes auf eine Bitmap zu bringen (Wir gehen davon aus, dass der Hintergrund, auf der ein Zeichen ausgegeben wird, nicht gelöscht werden soll.)

    - Zur besseren Vorstellung: Ein 8x8 Zeichen berührt max. (und wahrscheinlich in den häufigsten Fällen) 4 Screenram-Adressen
    -- Die Ausnahmen sind, falls das Zeichen genau an den modulo == 0 Positionen gezeichnet wird oder die Breite und/oder Höhe des Zeichens nicht in die nächste ScreenAdresse hineinragt.

    - Angenommen man hat diese 4 Screenram-Adressen ermittelt, dann könnte man einfach mit einer Schleifen die Bytes für das Zeichen auf diese 4 Adressen verteile

    -- Falls man also noch eine Zeichenhöhe berücksichtigen würde, könnte man evtl. noch mehr sparen.
    - Am einfachsten ist es glaube ich, wenn man einfach 2 Screenram-Zeilen betrachtet.


    Bevor es ans Eingemachte geht, möchte ich noch folgendes bemerken:
    - Ich glaube, dass ein Kompromiss zwischen Programmgröße und Geschwindigkeit zu finden ist, wobei ich denke, dass eine geringere Speichergröße einwenig wichtiger ist.
    - Im nachfolgenden Code werden 4KByte für Shift-Tabellen benötigt. (Die Stellen an den Labels "ref..." sollen die Verweise aufnehmen, d.h. selbstmod. Code.)
    - Die BITMAPPTR könnte man teilweise so setzen, wie bei einer Putpixel-Funktion, d.h. hier könnte man auch Tabellen verwenden.
    - Da die PTR unabhängig sind, müsste man sie auch nur ändern, falls ein 8x8 Block verlassen wird oder bspw. das Zeichen geändert wird.
    - Es handelt sich bei dem Code auch nur um eine Skizze, d.h. alles ungetestet, aber die Idee sollte erkennbar sein und auch, dass es gar nicht kompliziert ist.
    -- evtl. würde die Berücksichtigung von Clipping nochmal einwenig Komplexität mit sich bringen, aber dafür könnte man ja einfach die Routine duplizieren und ändern. Selbiges gilt auch für eine Optimierung, indem man einfach alles 8 mal kopiert o.ä...

    Und noch ein Wort zum Benchmark: Ich würde einfach die benötigte Rasterzeit (Bordercolor) für die Darstellung eines Zeichen, Worts, Satzes o.ä. als Indikator nehmen... (((Es muss hier kein "Gegeneinander" geben.)))

    Retrofan Evtl. könntest Du nochmal den Font mit den Breiten verlinken. Ich habe ihn gerade auf die Schnelle nicht gefunden.



    ---------
    Noch ein kleines Offtopic-Thema, für welches ich keinen eigenen Thread eröffnen möchte, das mich jedoch total beeindruckt hat:
    Jemand ("Chiron Bramberger") hat herausgefunden, wie man die Temperatur des 6510 durch Software ermitteln kann.
    siehe

    ab ca. Minute 36:00.
    Github ab Zeile 290 https://github.com/chironb/Chi…main/source/chicli.c#L289

  • Da ich so was ja schon mal gemacht habe, bräuchte ich nur noch analysieren (weil ich selbst nicht mehr genau weiß, wie es anzuwenden ist) bzw. den Quellcode (hoffentlich!) finden und optimieren.


    Was habt ihr früher mit dem C64 "Tolles" gemacht?

    Unknown Realm - neues RPG fuer C64 und PC


    Leider habe ich aber im Moment kaum Zeit dazu. Ich könnte es dann höchstens nachreichen. Sobald die Zeit des Kaum-Zeit-habens vorbei ist (mehrere Wochen), habe ich wieder so viel Zeit wie vorher. Und wenn dann erst mal die Zeit des So-viel-Zeit-wie-vorher-habens vorbei ist (mehrere Monate), werde ich noch viel mehr Zeit haben.

  • Evtl. könntest Du nochmal den Font mit den Breiten verlinken. Ich habe ihn gerade auf die Schnelle nicht gefunden.

    Ich hänge hier mal einen Font an, den man verwenden könnte. Es ist ein schmaler, proportionaler Font, der grob auf meinem alternativen C64-Systemzeichensatz basiert (6 px hohe Versalien, 2 px starke Vertikal-Linien, einheitliche (5 px) x-Höhe etc.). Er ist in eine in Details überarbeitete Version des proportionalen Fonts, den ich für den Enchanter-Release von 2018 gezeichnet habe. Ich denke, die Schrift ist ein guter Kompromiss aus Lesbarkeit (auch auf CRTs) und geringem Platzbedarf (rund 60 Zeichen/Zeile).


    Weil es keinen guten Grund gibt, im Bitmap-Mode auf PETSCII-Kodierung zu setzen (wir brauchen hier weder Block-Grafik noch invertierte Zeichen), habe ich die Schrift auf ASCII-Belegung (plus ein paar Umlaute) umgestellt. Ich denke, das sollte für erfahrene Programmierer kein Hindernis darstellen, oder?


    In dem Font sind keine Breiten-Definitionen enthalten. Man sollte also davon ausgehen, dass jedes Zeichen so breit ist, wie die gesetzten Pixel es vorgeben. 1 px Zeichenabstand sollte man als Default annehmen. Auf Wunsch könnte man aber im Font auch Beitenangaben "verstecken". (Ich hatte an anderer Stelle dafür schonmal einen Vorschlag gemacht)

  • Wenn es nur um's Sammeln geht:

    HENG hat nen prop-font-plotter:

    https://csdb.dk/release/?id=114457

    Ah und die DOCS von Maniac Mansion Mercury

    https://csdb.dk/release/?id=96067

    Hier erahnt man die Geschwindigkeit vielleicht ganz gut.

    Es ist fast die Frage ob man Prop font ueberhaupt will?

    Netter geht es auch in half chars :)

    https://csdb.dk/release/?id=111244

  • Die Idee eine GUI bzw. Hilfsroutinen schrittweise umzusetzen finde ich gut.

    Ich würde keine Challenge starten, sondern einfach wie in dem anderen Programmierthread(s) loslegen, weil so anscheinend am schnellsten Ergebnisse zu sehen sind und Ideen/Sichtweisen eingebracht und kombiniert werden können.

    Ok, das wäre halt auch ein Ansatz. Wenn sich hier nicht genügend Teilnehmer für einen Contest melden, weil ein Wettbewerb nicht gewünscht ist, dann wäre deine Idee, so eine Routine eher im Dialog zu erstellen und zu optimieren, natürlich auch eine gute Sache. Für den Zuschauer wäre das wahrscheinlich sogar noch interessanter, weil man dabei etwas lernen kann. Wie ist hier die Stimmung dazu?


    Da ich so was ja schon mal gemacht habe, bräuchte ich nur noch analysieren (weil ich selbst nicht mehr genau weiß, wie es anzuwenden ist) bzw. den Quellcode (hoffentlich!) finden und optimieren.

    Stimmt, viele haben so eine Routine sicherlich schonmal geschrieben (ich hatte hier ja schon zwei andere Programmierer genannt). Und natürlich könnte man die hier weiternutzen und gegebenenfalls verbessern. Es geht ja darum, die beste Routine für den Zweck zu finden, egal ob neu geschrieben oder aus der Schublade gezogen. Nur müssen wir halt einheitliche Rahmenbedingungen schaffen, also Vorgaben für den zu verwendenden Text, die Zeilenlänge, den Font usw. – sonst können wir nichts vergleichen.


    Und man könnte noch überlegen (darauf kam ich beim Betrachten deiner Beispiele), ob die Engine irgendwelche "Zusatz-Features" beherrschen sollte, also z.B. Blocksatz, rechtsbündig usw.? Mir wäre das erstmal nicht so wichtig und ich will die Messlatte auch nicht zu hoch legen. Einfach linksbündig (mit Wortumbruch) fände ich persönlich auch OK.


    Deine Routine benötigt laut deiner Angabe unter 1 KB RAM (3 Blöcke). Ist das der komplette RAM-Verbrauch, oder wird da noch irgendwas ausgerollt etc.?

  • Wenn es nur um's Sammeln geht:

    Nein, eigentlich war ein Wettbewerb angedacht. Dafür müssten sich alle Teilnehmer den gleichen Bedingungen stellen. Da reicht keine Linksammlung. Aber man könnte natürlich die verlinkten Programmierer ansprechen, ob sie ihre Routinen gegen andere antreten lassen wollen.


    Es ist fast die Frage ob man Prop font ueberhaupt will?

    Also ich halt schon – deswegen hatte ich den Thread gestartet. Wenn man etwas ganz anderes will, kann man natürlich auch einen anderen Thread aufmachen.


    Netter geht es auch in half chars

    Dann hat man halt 80-Zeichendarstellung. Das ist vollkommen OK – aber ich finde es sehr unflexibel. Auf CRTs ist das an der Grenze des Lesbaren (geht – aber ist halt schon knapp), da sind breitere Fonts auf Dauer schon etwas augenfreundlicher. Wie gesagt, mein Beispielfont von oben kommt auf etwa 60 CPL und ist sicherlich leichter lesbar (wahrscheinlich auf dem Level der üblichen 40-Zeichendarstellung im Textmodus). Außerdem weiß ich nicht, ob es bei "half chars" noch viel Code zu optimieren gibt. Ich denke, bei proportionalen Schriften ist die Herausforderung für eine gute Routine einfach etwas höher.

  • Eine Compo ist nur sinnvoll, wenn es exakte Vorgaben gibt und ein eindeutig messbares objektives Vergleichskriterium. Und dann kriegt man ein auf Teufel komm raus optimiertes Ergebnis, das alles im Rahmen der Vorgaben radikal ausreizt, was gelegentlich für Überraschungen sorgen kann (siehe enthusi 's Beispiel mit der Permutation, die eine sehr kleine aber leider praktisch vollkommen unbrauchbare Lösung darstellt).


    Gibt es keine absolut eindeutigen und vollständige Bedingungen (und da ist fürchte ich noch einiges offen bei der Aufgabenstellung oben) oder kein objektives Gewinn-Kriterium, dann triggert das nicht den Ehrgeiz zu gewinnen und die Compo funktioniert nicht. So etwas wie "der beste Kompromiss aus Größe und Geschwindigkeit" ist leider nicht geeignet, obwohl das wohl genau das ist, was man hier eigentlich haben will. Tatsächlich glaube ich, dass Programmier-Compos nahezu ausschließlich für sehr "künstliche" Probleme funktionieren.

  • Falls jemand im Vorfeld etwas "herumspielen" will und Text zum Austesten seiner Routine benötigt – hier habe ich einen, u.a. aus Pangrammen, zusammengestellt:


    BTX, WDR, ZDF und RTL. Franz jagt im komplett verwahrlosten Taxi quer durch Bayern! Franziska quaelt an jedem Werktag vollendet Bach per Xylophon. Zwei flinke Boxer jagen die quirlige Eva und ihren Mops durch Sylt. Stanleys "Expeditionszug" quer durch Afrika wird von jedermann bewundert. Jener quadratisch geformte, viel bewunderte, Onyx befindet sich im Besitz des Papstes. The quick brown fox jumps over the lazy dog. Pack my box with five dozen liquor jugs. Alles dauerte 7.894 Stunden, 56 Minuten und 21,3 Sekunden. Franz jagt im komplett verwahrlosten Taxi quer durch Bayern! Franziska quaelt an jedem Werktag vollendet Bach per Xylophon. Zwei flinke Boxer jagen die quirlige Eva und ihren Mops durch Sylt. Stanleys "Expeditionszug" quer durch Afrika wird von jedermann bewundert. Jener quadratisch geformte, viel bewunderte, Onyx befindet sich im Besitz des Papstes. The quick brown fox jumps over the lazy dog. Pack my box with five dozen liquor jugs. Alles dauerte 7.894 Stunden, 56 Minuten.


    Das sollten genau 1.000 Zeichen (inkl. Spaces) sein und damit (selbst bei aktivem Wordwrap) locker auf einen C64-Bildschirm passen, ohne scrollen zu müssen. So etwas könnte man dann auch für einen Contest verwenden.

  • Eine Compo ist nur sinnvoll, wenn es exakte Vorgaben gibt und ein eindeutig messbares objektives Vergleichskriterium. [...] und da ist fürchte ich noch einiges offen bei der Aufgabenstellung oben

    Vollkommen korrekt. Ich hatte das aber auch so dargestellt, dass sich die "Angemeldeten" auf die konkreten Regeln einigen sollten. Was nützt es, wenn ich Regeln festklopfe und dann vielleicht deswegen keiner mitmacht, weil ich z.B. 1000 Zeichen gerendert haben möchte, alle Interessenten aber nur mitmachen würden, wenn 950 Zeichen die Vorgabe wären. ;)


    Also, natürlich soll es feste Regeln geben! Einige Vorgaben habe ich schon gemacht, auf andere sollten wir uns einigen. Ich würde gerne eine Speicherplatz-Vorgabe machen, weil RAM bei einem OS und auch bei einem GUI immer knapp ist. Ich könnte jetzt sagen: 512 Byte! Aber wenn das unrealistisch ist, müsste man halt einen anderen Wert nehmen. Programmierer könnten sich, so meine Intention, auf einen Wert einigen, der einerseits realistisch, andererseits eine Herausforderung ist.

  • Retrofan
    Danke für den Font.
    Ich denke man benötigt noch mindestens eine 256 Byte Tabelle, die die Zeichenbreiten beherbergt.
    - (0 für leere Zeichen, 2 für das "i", 8 für das "w" ....). In der Not könnte man (ich) sie schnell für diesen Font per Hand niederschreiben oder eine Subroutine dafür vorbereiten.

    Optional, je nachdem welche Features für die Ausgaberoutine gewünscht sind:
    - Allg. soll die Y-Pos frei wählbar sein oder ist sie immer an einer durch 8 teilbaren Stelle?
    -- Ich frage nur, weil die meisten verlinkten Beispiele auf Zeilengrenzen fixiert zu sein scheinen.

    - Sollen Zeichen in den "Keller", d.h. die nächste Zeilen rutschen können (bspw. beim "g")?
    -- dann benötigt man eine Tabelle mit Y-Offsets, die zur "CURSOR-YPOS" für ein Zeichen addiert werden.

    - Sollen weniger Schreibzugriffe für Buchstaben erfolgen, die leere Zeilen beherbergen? (Bspw. hat ein "u" nur 5 genutzte Zeilen, d.h. es könnte auch nur 5 statt 8 Zeilen ausgegeben werden)
    -- Ob das performanter ist, müsste man ausprobieren. Mir fallen 3 Möglichkeiten zur Umsetzung ein:
    --- a.) Man hat zwei 256 Byte Tabellen mit der YStart- und YEndZeile des Zeichens.
    --- b.) Man schiebt alle Zeichen nach oben und hat nur eine 256 Byte Tabelle, die die Zeichenhöhe angibt. Ein Vorteil könnte sein, dass der Font so nur "komprimiert", d.h. ohne leere Zeilen, vorliegen kann.
    --- c.) Wie b, jedoch verwendet man einfach den Offset ins nächste Zeichen als "Stopmarkierung", d.h. hier würde eine 16-Bit 256 Einträge Tabelle ausreichen.
    -- Die benötigten Tabellen könnte man beim Laden des Zeichensatzes automatisch erstellen. (Übrigens die ganz oben genannte Breitentabelle auch.) Die Frage ist dann also, ob auch eine Initialisierungsroutine geschrieben werden soll, oder ob die Daten vordefiniert vorgegeben werden.
    --- Auch hier ergeben sich einige "Einstellungsmöglichkeiten" für Performancesteigerungen, bspw. könnte in die Breitentabelle der Zeichenabstand gleich miteinberechnet werden.

    -----------------
    Das bisher geschriebene bezog sich nur auf die Routine zum Zeichnen eines Zeichens.

    Die Ausrichtung lässt sich beim Ausgeben eines Strings umsetzen:
    - Bevor eine Zeichenkette ausgegeben wird, wird vorher ein Teilabschnitt herausgesucht und zwar werden die Zeichenbreiten und X-Zeichenabstände solange aufaddiert, bis entweder ein Newline Zeichen eingelesen wird, oder der zur Verfügung stehende Platz für die Zeile nicht mehr ausreicht.
    -- Damit sind links-, rechtsbündige und zentrierte Zeilen möglich:
    --- links: Start bei X-Position 0
    --- rechts: Start bei X-Position = zur Verfügung stehende Restbreite der Zeile
    --- zentirert: Start bei X-Position = (zur Verfügung stehende Restbreite der Zeile)/2
    -- Blocksatz ließe sich (m.M.n.) nur durch eine Division erreichen, d.h. wenn man den Restplatz kennt und die Anzahl der Zeichen, die in die Zeile passen sollen, weiß man, wie groß der Zwischenabstand sein muss/kann.

    An diesem Punkt könnte man auch einen Textbereich umsetzen/definieren, d.h. es gibt X1, Y1, X2, Y2 bzw. X, Y, B, H, und ob ein automatischer Zeilenumbruch erfolgen soll, oder einfach der Text abgeschnitten werden soll.
    (...)

    -----------------
    1.) Es müssten also erst die Anforderungen (fett markiert) vorgegeben werden. (Hier ergeben sich dann auch die Eingabeparameter.)
    2.) Dann müssten evtl. die Tabellen bereitgestellt werden.
    3.) Dann bräuchte man eine schnelle Zeichenroutine.
    4.) Eine Routine zum Setzen und Fortbewegen des Cursors.
    5.) Eine Routine zum Ausgeben eines Strings/Textes, die die Zeichenbreiten und Parameter berücksichtigt und die Strings entsprechend aufteilt.

    Sollte alles machbar sein. Der Teufel steckt sicherlich im Detail.
    Ich denke, dass eine Routine nicht zu optimiert sein dürfte, sondern lieber "generell einsatzfähig".

    Nagut, das war jetzt nur Text bzw. eine Gedankensammlung.
    "Man" könnte ja schonmal mit dem Font einwenig spielen.

    -----------------
    Ich wollte noch einen Satz zu einer möglichen Competition schreiben:
    Man könnte einen Text vorbereiten und die benötigten Positionen etc. vorgeben und dann schauen, welche Routine wie weit in einem Frame kommt (= wieviele Zeichen oder Zeilen ausgegeben wurden). Ich sehe: zwischenzeitlich ist die Idee schon aufgekommen.

  • Da vielleicht nicht jeder damit klarkommt, sich zusammen mit anderen auf Regeln zu verständigen, erstelle ich mal basierend auf meinen vorherigen Angaben ein ...


    REGELWERK [Achtung, überarbeitet – und nach wie vor unvollständig]:

    Programmierung einer allgemein nutzbaren Font-Render-Engine für den C64-Hires-Bitmap-Modus.


    Der oben vorgegebene Text soll 15 x auf dem Bildschirm ausgegeben werden, jeweils mit kleinen Unterschieden (dazu später mehr). Dazwischen wird der Bildschirm gelöscht. Gemessen wird die Zeit ab Start der Routine, bis zur Ausgabe des letzten Zeichens.


    Die Routine soll mit 8-bit-codierten Zeichensätzen funktionieren, am Beispiel meines geposteten Fonts. Die enthaltene Breitentabelle soll genutzt werden. Die Ausgabe soll linksbündig erfolgen und am (flexiblen) Zeilenende soll gegebenenfalls ein Wortumbruch stattfinden. Der Zeilenabstand des Textblocks beträgt 8 px.


    Der Y-Startwert muss durch 4 teilbar sein, der X-Startwerte soll beliebig (innerhalb der Screengröße) sein.


    In jeder der 15 Wiederholungen sind andere Werte für die XY-Startposition, die Zeilenlänge (in px) und die Farbe vorgegeben. Die Startposition beginnt bei 0/0 und steigt in X-Richtung in 1px-Schritten und in Y-Richtung in 4px-Schritten bei jedem Neuaufbau an. Die Breite startet bei 320 px und verringert sich bei jedem Neuaufbau um 4 px.


    Farbe von Hintergrund und Vordergrund sollen flexibel sein, im Wettbewerb ist die Hintergrundfarbe schwarz, der Vordergrund wechselt bei jedem Neu-Aufbau (wobei schwarz ausgelassen wird.)


    Die Routine mit allen Hilfstabellen und ausgerollten Schleifen darf maximal 512 Byte belegen. [wenn die Vorgabe unrealistisch ist, dann intervenieren)


    Ein paar Variablen habe ich aber noch:

    Startadresse des Codes:

    Startadresse des Bildschirmspeichers:

    Startadresse des Fonts:

    Startadresse des Textes:


    Sieger ist der Beitrag mit der kürzesten gemessenen Zeit.


    Fehlt noch was?

  • Was ist mit RAM-Puffern? Eine naheliegende Optimierung für 15x darstellen wäre es, es einmal in einen Grafikpuffer zu rendern und dann 14x zu kopieren :). Wozu überhaupt 15x? Ich denke man würde lieber ein Framework vorgeben das die Zeit für einmal rendern misst.


    EDIT: und die Vorgabe des Texts ist zweischneidig. Zwar sorgt das für Vergleichbarkeit, aber vermutlich werden Leute die Routine auf diesen speziellen Text hin optimieren, also z.B. die am häufigsten vorkommenden Buchstaben(-folgen) besonders schnell rendern.

  • Ich denke man benötigt noch mindestens eine 256 Byte Tabelle, die die Zeichenbreiten beherbergt.

    Ich hatte schonmal an anderer Stelle vorgeschlagen, dass ich in die ersten 32 Darstellungs-freien Zeichen des ASCII/ISO-Zeichensatzes die Breitentabellen ablegen könnte. Die Frage ist halt, wie sehr man das optimieren möchte: für 8 Pixel Breite des Zeichens (plus Abstand) benötigt man 3 Bit, was ich auf 4 aufrunden würde (also ein Nibble, das 16 Werte annehmen kann). Dann bekäme man in eine Char-Zeile die Breiten von 2 Zeichen untergebracht, also 16 Breiten/Char. Würde man die Breiten für alle 256 Plätze definieren, würde man 16 Chars für die Werte benötigen (14, wenn man die ersten 32 Plätze auslässt).


    Kann ein Programmierer damit etwas anfangen, ohne sich die Breiten dort erst herauszuholen und nochmal (RAM-intensiv) irgendwo anders hinzulegen?


    Bis auf Weiteres würde ich sagen, dass man die Breiten auch selbst herausfinden kann – einfach über die gesetzten Pixel der Zeichen selbst. Das ist zwar etwas unflexibel, weil man so keine "Unterschneidungen" oder zusätzliche Abstände (für Satzzeichen sinnvoll) definieren kann aber fürs Erste sollte das ausreichend sein.


    - Allg. soll die Y-Pos frei wählbar sein oder ist sie immer an einer durch 8 teilbaren Stelle?
    -- Ich frage nur, weil die meisten verlinkten Beispiele auf Zeilengrenzen fixiert zu sein scheinen.

    Für meine Zwecke wäre es ausreichend, wenn die Y-Position durch 4 teilbar wäre, sodass man ein Zeichen entweder genau in einer Char-Zeile rendern würde oder genau zwischen (also in der Mitte von) zwei Zeilen. Aber ich will nicht ausschließen, dass es Gründe geben könnte, weswegen man noch feiner positionieren möchte. Mein Vorschlag daher: Y-Position durch 2 teilbar.


    - Sollen Zeichen in den "Keller", d.h. die nächste Zeilen rutschen können (bspw. beim "g")?

    Die Zeichen sind maximal 8 px hoch, das "g" belegt mit seiner Unterlänge die 8. Pixel-Zeile des Chars. Der Zeilenabstand innerhalb eines Textblocks soll auch 8 px betragen – daher gibt es keine Überlappungen.


    Sollen weniger Schreibzugriffe für Buchstaben erfolgen, die leere Zeilen beherbergen? (Bspw. hat ein "u" nur 5 genutzte Zeilen, d.h. es könnte auch nur 5 statt 8 Zeilen ausgegeben werden)

    Warum nicht? Da spricht nichts gegen, wenn das beschleunigend wirkt.