Jive
Ich habe einige kleinere Dinge geändert bzw. mir überlegt. (...)
Ich werde die Änderungen demnächst präsentieren.
Posts by 5ace
-
-
Mein Plan wäre:
1) Der Text sollte kompatibel zu modernen PCs/Macs sein, daher nicht PETSCII, sondern ISO 8859 (also ASCII mit internationaler Erweiterung) und Plaintext ohne irgendwelchen Steuercodes. Allenfalls Markdown sollte zur Formatierung erlaubt sein, da klartextliche "Tags" ohne problematische Konvertierung. So kann man ein und den gleichen Text abwechselnd mit C64 und PC bearbeiten und letztendlich vom PC aus drucken oder per Mail verschicken oder was auch immer.
2) Es wäre nicht unrealistisch, auf dem C64 einen PDF-Output zu generieren. Ein Minimal-PDF-Header ist sehr überschaubar (mit PS vergleichbar), der Rest ist auch wieder Plaintext. In Kombination mit einer Netzwerk-Verbindung (ich denke dabei vor allem an das WiC64, also WiFi) könnte man so ein Minimal-PDF wahrscheinlich zu einem modernen Netzwerkdrucker schicken, der auch Druckaufträge von iOS-Geräten oder Androiden entgegen nimmt. Das funktioniert ohne Treiber oder Konfiguration.Auch gut erklärt. Also soll es ein Textverarbeitungsprogramm/Editor werden?
-
Ja, im Prinzip wäre das schon, was die meisten Anforderungen erschlagen würde. Bei der Zeilenhöhe wäre es noch toll, wenn man irgendwie neben 8 auch 16 px hinbekommen würde. Das wäre für manche GUI-Sachen klasse. Also 8 px hohe Zeichen mittig in 16 px gelegt. Das müsste aber nicht unbedingt gescrollt werden und könnte notfalls statisch bleiben.
Die Routinen von TD1334 können das ja bereits. Er hat es mit seiner Demo bewiesen.
(Und ohne horiz. Scrolling ist die Darstellung einer Textdatei noch sehr viel einfacher.)
Ich selbst bin kein Fan von doppelt hohen Zeilen, weil ich finde, dass alles minimalistisch umgesetzt werden sollte/muss; aber das ist ja auch nur Geschmackssache und subjektiv.
(...)
Meiner Meinung nach gibt es 2 Wege: entweder man versucht sich an einem Programm oder an einem OS.Der Punkt für mich wäre: Der C64 könnte verschiedene Fonts, ggf. noch kleine Bilder im Text. Aber dann? Drucken würde ich es nicht, da kein Drucker passt bzw. was macht man damit? Am 68k Mac kann man daraus ein PDF erzeugen und das Ganze weitergeben. Und am C64?
Ich möchte hier keine Stellung beziehen, oder Partei für oder gegen die Aussage ergreifen, ob das Drucken direkt vom C64 aus möglich ist.
Evtl. bin ich auch nur einwenig naiv, was die Druckfunktion angeht.
Die "Druckfunktion" ist für mich erstmal einfach nur ein Programm, welches die Daten (Text + Zeichensatz und/oder Grafiken) erhält und an den "Drucker" sendet.
"Drucker" bedeutet hier an irgendeinen Port o.ä..
Es könnte ja auch eine Datei sein oder direkt eine Übertragung durch irgendeine Hardware irgendwo hin.
(((Ich wäre bspw. schon zufrieden, wenn eine Bitmap o.ä. als Ausgabedatei erstellt werden würde/könnte.
Zur Info: Ich selbst "arbeite" nicht mit oder am C64, sondern nutze nur den Emulator hobbymässig, d.h. um zu schauen, auzuprobieren und darüber nachzudenken/fantasieren, wie oder ob man etwas besser umsetzen kann oder könnte. etc...)))
Wie dieses Programm arbeitet, bleibt ihm selbst überlassen.
1.) Es gibt/gab eine Centronics-Schnittstelle für den C64. Im C64-Wiki gibt es sogar ein Programmbeispiel: https://www.c64-wiki.de/wiki/Centronics-Schnittstelle
2.) Eine kurze Google Suche hat ergeben, dass es angeblich noch Drucker mit Centronics Schnittstelle geben soll: https://windowsreport.com/parallel-port-printer/3.) Es gibt sogar Centronics-zu-Usb Adapter. Ob diese Verbindungen miteinander funktionieren würden, weiß ich nicht.
Zum Format/zur Sprache für die Druckeransteuerung:
4.) Angeblich gibt es noch Drucker, die ESC/P verstehen können sollen: https://www.c-nw.de/drucker-mf…prachen/esc-p-raster.html (Hier kann man auch nach anderen Druckersprachen filtern.)
5.) im Internet existieren auch Beispiele/Beschreibungen für HP PCL u.ä..
Ich denke mir, dass wenn ein DOS-Rechner mit Assembler oder C, ohne zusätzliche Treiber, einen Drucker über LPT 1 ansteuern kann, dass dies dann auch mit dem C64 möglich sein sollte.
Ob das wirklich funktioniert, weiß ich nicht.
Ich würde die Möglichkeit jedoch nicht einfach ausschließen.
Ob man das dann überhaupt nutzen möchte oder würde, ist wieder eine ganz andere Frage.
Für mich bleibt die "Druckfunktion" erstmal nur ein externes Programm, welches "irgendetwas" mit den Daten anstellt.
----
Das sollte jetzt alles keine Kontra Auflistung sein, sondern Deine Frage ist schon berechtigt: Die Frage nach dem "Wozu?"
Meine Antwort wäre: Um zu sehen, ob es möglich ist. -
In dem Text wurde schon gesagt, dass man mehre Zeichen aus dem Puffer gleichzeitig zeichnen könnte, wenn das Rendern mit der Eingabe nicht mitkommt. Ich würde noch die Idee beisteuern, dass man, solange zügig getippt wird, nur die aktuelle Zeile aktualisiert (und zwar vielleicht auf Bitmap-Zeilen-Basis, nicht durch Neuzeichnen der einzelnen Zeichen) und gegebenenfalls Text rechts heraus schiebt – und erst bei der nächsten kleinen Eingabe-Pause dann der Absatz aktualisiert/umbrochen wird.
Das ist in etwa auch das Vorgehen, das ich vorgeschlagen hätte.
Man sieht es konkret unter Windows Write 3.10 unter folgendem Link: https://www.pcjs.org/software/pcx86/sys/windows/3.10/ (Einfach Doppelklick auf die "Read Me"-Datei.)
(Und etwas schlechter bei Windows 3.11 unter folgendem, weil die Emulation etwas schneller ist: https://classicreload.com/win3x-windows-311.html )
Es gibt also 3 (?) unterschiedliche Arten von Refreshs bei Tastatureingaben:
- Bei sehr wenig Zeit: An der Cursorposition werden nur die neuen Zeichen gerendert und alles rechts vom Cursor in der aktuellen Zeile wird bitmapmäßig einfach nach rechts bis max. an den Bildschirmrand geschoben.
- Bei wenig Zeit: Nur die aktuelle Zeile wird gerendert und, falls die nachfolgende Zeile durch das Erreichen des Zeilenendes oder von einem Zeilen- oder Wortumbruch betroffen ist, wird die nächste Zeile mit gerendert. (Die alte Zeile wird einmal gerendert und die Ausrichtung wird sichtbar, da sie ja durch einen Zeilenumbruch "abgeschlossen" ist. Insgesamt werden also max. 2 Zeilen gerendert.)
- Nach einer kurzen Pause: Es findet ein Rendering von der ersten veränderten Zeile bis nach unten an den Bildschirmrand statt. (Hier könnte man auch evtl. nur bis an den nächsten Absatz gehen.)
Bei Scrolling nach oben oder unten: Der vorhandene brauchbare Bildschirmteil wird bitmapmäßig verschoben und es wird nur der neu hinzugekommene, vorher nicht sichtbare, Teil gerendert. (Ist ja auch einleuchtend.)
Bei Scrolling nach links oder rechts, wird der bereits vorhandene Teil einmal bitmapmäßig verschoben (=wahrscheinlich ergibt sich daraus ein psychologischer positiver Wahrnehmungseffekt) und es findet ein kompletter refresh statt.Das ist schon die x-te Disziplin, bei der GEOS unterperformt. Es wurde schon gezeigt, dass man Punkte/Linien 4 Mal so schnell zeichnen kann, wie GEOS es tut. Auch Scrolling ginge viel schneller (zeilenweise, also fast "smooth") und mit REU-DMA (sonst ja von GEOS unterstützt) besonders flink. Wie GEOS Dialogboxen (z.B. Filerequester) zeichnet, ist auch komplett ineffektiv. Da sind so viele Sachen, die man beschleunigen könnte – da würde wahrscheinlich niemand mehr meckern, der Bitmap-Mode sei zu langsam zum "Arbeiten".
GEOS wurde anscheindend so konzipiert, dass es auf externe Speicher angewiesen ist. (Bspw.: Fonts als VLIR und beim Erstellen einer neuen Datei wird sie gleich angelegt und es wird Speicherplatz auf der Disk reserviert.)
((( Richtig: Die Dialogboxen sind ein AlptraumAber hey, es war 1985. )))
Für schnelles Scrolling wäre auch die Simulation einer Bitmap mit 24 Zeilen (zweifarbig) im Textmodus interessant.Wenn es wirklich um eine Realisierung gehen würde, dann bräuchte ich persönlich z.B. keine unterschiedlichen Schriftgrößen und -arten oder WYSIWYG im engeren Sinn. Ich würde mit Plaintext (ISO-Encoding) arbeiten und Formatierungen (wenn überhaupt) über Markdown realisieren (was man dann rendern könnte – oder eben auch nicht).
Also etwas in der Art des "hires grafik scrollen möglich"-Programms von Acorn nur mit Eingabemöglichkeit?
(Ich meine Zeilenabstand 8 Pixel. Müsste man in Deiner Vorstellung den Bildschirm horiz. scrollen können?)
--------------
Bsp-Formel zum Zeichensatz:
Gesamtgröße = ((Summe der Zeichenbreiten in Pixel) /* 8 Zeilen + 3*Anzahl der Zeichen + sonst.Headergröße
Angenommen der Zeichensatz hat 102 Zeichen und die Zeichen wären (nur als Abschätzung) 8 Pixel breit, dann würde sich daraus ergeben:
826 + 306 = 1102 Bytes, d.h. kleiner als 2048, weil die leeren Zeichen nicht im Font gespeichert werden. Wie sie intern bei der Verwendung repräsentiert werden, kann natürlich wieder ganz anders aussehen. -
Die gesamte Thematik rund um GUI/OS und möglichen Anwendungen inkl. Textverarbeitungsprogramme ist sehr spannend.
Ich könnte seitenweise darüber schreiben.Aus meiner Sicht wäre das eine gute Basis für einen Font-Renderer, wie ihn GEOS verwendet, also für den WYSIWYG-Gebrauch, bzw. irgendwas DTP-artiges. Über ein Programm für einen solchen Renderer könnte man mal nachdenken.
Ja, mich hat interessiert, was speicherplatztechnisch möglich ist und wollte auch mal "Arial", "Helvetica" usw. auf dem C64 sehen.
Mit .ttf-Fonts würde der C64 auch ein Stück weiter "up-to-date" wirken.
Zum Speicherplatzverbrauch: Im Programm "bmfont" kann man noch die spacings auf 0 setzen, d.h. man würde evtl. noch einige wenige Bytes einsparen.Mir schwebte bisher ja eher ein (beschränkter) Renderer für typische GUI-Aufgaben oder einen No-WYSIWYG-Editor vor, der sich vor allem durch 2 Merkmale hervortun sollte: Performance (auch weil von der Text-Performance die Scroll-Performance abhängt) und geringe Größe. Dafür muss er dann aber auch weniger können: 8x8 px Chars wären das Maximum, das zu rendern wäre. Aber dein Ansatz hat auch was – wie gesagt, vielleicht fällt einem ein Programm ein, das davon profitieren könnte.
Bzgl. Performance:
Alle Bitmap-Textverarbeitungsprogramme/Editoren, die ich mir auf dem C64 angeschaut habe, inkl. Geowrite und Jasword, machen etwas grundsätzliches beim Aktualisieren von Benutzereingaben falsch.
(Tricks, die Geowrite verwendet: https://www.pagetable.com/?p=1490)
Dadurch wird der Trugschluss verstärkt, dass allgemein diese Art von Programmen auf dem C64 lahm sind.
Natürlich dauert ein Fullscreen-Refresh im Bitmap-Modus seine Zeit und es werden auch keine 1000 Seiten á 1800 Zeichen in den 64KB-Speicher passen, aber ein "besseres" Gefühl bei den Eingaben ließe sich m.M.n. durch eine andere Refresh-Strategie einfach realisieren.
(... bei Gelegenheit schreibe ich mehr dazu...)
Bei max. 8x8 Chars hast Du recht bzgl. der Performance. Der Font-Renderer ist dann natütlich auch kleiner.
Bei der Größe des Zeichensatzes selbst, könnte man ja mal ausrechnen, ob Dein Font in dem anderen Format weniger Bytes in Anspruch nehmen würde: 3 Bytes je Zeichen + die Font-Bytemuster (entspr. Anzahl der Zeichen * 8).
(Ich weiß, dass es Dir darum ging, Fonts mit Standard-Tools (8x8 Editoren) erstellen und austauschen zu können.)Wie zu erwarten, wird mit Kerning-Tabellen gearbeitet (da die ohnehin in TT- und ähnlichen Fonts verwendet werden und übernommen werden können). Ich hatte auch schon gesagt, dass man das vielleicht auch auf dem C64 ausprobieren könnte, wobei ich Kerning an sich schon fast zu viel für den kleinen 64er finde. Ich habe bei meinem handoptimierten Font die beiden größten Störenfriede (vor allem, wenn sie auf einander trafen), r und a, soweit entschärft, dass sie kein Problem mehr darstellen dürften. Von daher ist, von seltenen Ausnahmen abgesehen, das Schriftbild und der Lesefluss auch ohne Kerning sehr ruhig und angenehm.
Kerning würde bedeuten, dass man nach jedem ausgegeben Zeichen in der Liste nachschauen müsste. Evtl. gibt es hier auch Tricks, aber ich denke, dass man die Umsetzung mal ausprobieren sollte.
Zu Deinem Font: Er ist sehr brauchbar und ich denke auch, dass er noch Verwendung finden wird.
Eigentlich möchte ich noch viel mehr schreiben (...);
Es folgt jedoch ein weiteres Testprogramm, welches diesmal auf Geschwindigkeit ausgelegt ist:
- Es ist noch immer fehlerbehaftet.
- Es zeigt jedoch in etwa die obere Grenze beim Plotten.
-- Die Positionsberechnung könnte noch optimiert werden; das Plotten nicht, d.h.
--- es werden keine Zeropageadressen für die Zeichen verwendet und die Zerichen werden vertikal aufgebaut, d.h. mögliche Font-Effekt wären höchstens "underline" und "strike-through"...
--- zusätzlich werden 4KB für Rotationstabellen verwendet und ein Speicherbereich von max. 8KB ist für Speedcode reserviert. (Pro Pixelhöhe kostet der Speedcode ca. 208 Bytes, d.h. es sind Fonts bis zu einer Höhe von 39 Pixel möglich.)
---- Dadurch hatten nur noch die ersten 5 Fonts Platz im Speicher.
fontsizetest2.prg
Man erkennt den Geschwindikeitszuwachs, obwohl die Zeilen nicht voll ausgefüllt sind.
(...)--------------------------------------
Edit: Ich wollte Dich noch auf das Programm "Interword" (wegen der GUI) aufmerksam machen, bestimmt kennst Du es bereits.
Ich finde, dass es, bis auf die Wahl der Schriftart/Größe, vom Funktionsumfang inhaltlich Dein Mockup aus dem Thread "Textverarbeitung" Leben füllen könnte.
[External Media: https://www.youtube.com/watch?v=4W8n6y6cuOU] -
Moderne Fonts auf dem C64
Mit dem Programm
https://www.angelcode.com/products/bmfont/
lassen sich .ttf Fonts als Bitmap + Metadaten exportieren.
Die Schriftart "segoeui" (mit 219 Zeichen) benötigt nach einer Umwandlung in ein eigenes experimentelles Format folgenden Speicherplatz:Schriftgröße Gesamt (Bytes) Pages vollständig* Bitmapgröße (Bytes) Kerninginfos (Bytes) 8 3708 ja 1617 801 11 4920 ja 2561 1069 12 5594 ja 3120 1184 14 7275 ja 4522 1463 16 8496 (*) nein 5586 (*) 1620 22 13886 (*) nein 10710 (*) 1886 36 30684 (*) nein 27168 (*) 2226
Der Header umfasst hier immer 1290 Bytes je Schriftgröße, wovon je 512 Bytes Pointer für das Kerning enthalten sind.
* = Eine Page (sog. "Texture Page") ist eine Bitmap mit den Bitmustern für die Zeichen des Fonts. "Nicht vollständig" bedeutet hier, dass nur die erste Page berücksichtigt wurde und der Speicherplatzbedarf höher ausfallen würde, wenn mehr Grafikdaten berücksichtigt werden würden. Derzeit wird nur eine Page mit max. 256*8 = 2048 Pixel unterstützt.
Beispiel-Page für "Segoeui" Schriftgröße 12:
Metadaten aus dem "bmfont"-Programm dafür:Code- info face="Segoe UI" size=-12 bold=0 italic=0 charset="ANSI" unicode=0 stretchH=100 smooth=0 aa=1 padding=0,0,0,0 spacing=1,1 outline=0
- common lineHeight=15 base=12 scaleW=2048 scaleH=48 pages=1 packed=0 alphaChnl=0 redChnl=0 greenChnl=0 blueChnl=0
- page id=0 file="segoeui_12_0.png"
- chars count=219
- char id=13 x=1550 y=0 width=3 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15
- char id=32 x=1606 y=0 width=3 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15
- char id=33 x=1602 y=0 width=3 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15
- char id=34 x=1389 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=5 page=0 chnl=15
- char id=35 x=860 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=36 x=1096 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=37 x=135 y=0 width=10 height=15 xoffset=0 yoffset=0 xadvance=10 page=0 chnl=15
- char id=38 x=146 y=0 width=10 height=15 xoffset=0 yoffset=0 xadvance=10 page=0 chnl=15
- char id=39 x=1650 y=0 width=3 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15
- char id=40 x=1500 y=0 width=4 height=15 xoffset=0 yoffset=0 xadvance=4 page=0 chnl=15
- char id=41 x=1545 y=0 width=4 height=15 xoffset=0 yoffset=0 xadvance=4 page=0 chnl=15
- char id=42 x=1479 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=5 page=0 chnl=15
- char id=43 x=367 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=44 x=1642 y=0 width=3 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15
- char id=45 x=1473 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=5 page=0 chnl=15
- char id=46 x=1634 y=0 width=3 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15
- char id=47 x=1443 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=5 page=0 chnl=15
- char id=48 x=1103 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=49 x=1110 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=50 x=1117 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=51 x=1124 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=52 x=1131 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=53 x=1138 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=54 x=1145 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=55 x=1152 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=56 x=1159 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=57 x=1166 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=58 x=1626 y=0 width=3 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15
- char id=59 x=1622 y=0 width=3 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15
- char id=60 x=475 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=61 x=484 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=62 x=493 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=63 x=1461 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=5 page=0 chnl=15
- char id=64 x=75 y=0 width=11 height=15 xoffset=0 yoffset=0 xadvance=11 page=0 chnl=15
- char id=65 x=502 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=66 x=844 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=67 x=511 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=68 x=520 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=69 x=1173 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=70 x=1180 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=71 x=547 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=72 x=291 y=0 width=9 height=15 xoffset=0 yoffset=0 xadvance=9 page=0 chnl=15
- char id=73 x=1578 y=0 width=3 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15
- char id=74 x=1520 y=0 width=4 height=15 xoffset=0 yoffset=0 xadvance=4 page=0 chnl=15
- char id=75 x=812 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=76 x=1187 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=77 x=51 y=0 width=11 height=15 xoffset=0 yoffset=0 xadvance=11 page=0 chnl=15
- char id=78 x=221 y=0 width=9 height=15 xoffset=0 yoffset=0 xadvance=9 page=0 chnl=15
- char id=79 x=231 y=0 width=9 height=15 xoffset=0 yoffset=0 xadvance=9 page=0 chnl=15
- char id=80 x=1012 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=81 x=261 y=0 width=9 height=15 xoffset=0 yoffset=0 xadvance=9 page=0 chnl=15
- char id=82 x=916 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=83 x=1229 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=84 x=868 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=85 x=583 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=86 x=820 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=87 x=39 y=0 width=11 height=15 xoffset=0 yoffset=0 xadvance=11 page=0 chnl=15
- char id=88 x=796 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=89 x=948 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=90 x=900 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=91 x=1495 y=0 width=4 height=15 xoffset=0 yoffset=0 xadvance=4 page=0 chnl=15
- char id=92 x=1425 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=5 page=0 chnl=15
- char id=93 x=1505 y=0 width=4 height=15 xoffset=0 yoffset=0 xadvance=4 page=0 chnl=15
- char id=94 x=601 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=95 x=1383 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=5 page=0 chnl=15
- char id=96 x=1610 y=0 width=3 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15
- char id=97 x=1271 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=98 x=908 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=99 x=1278 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=100 x=804 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=101 x=1285 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=102 x=1515 y=0 width=4 height=15 xoffset=0 yoffset=0 xadvance=4 page=0 chnl=15
- char id=103 x=876 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=104 x=884 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=105 x=1562 y=0 width=3 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15
- char id=106 x=1558 y=0 width=3 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15
- char id=107 x=1292 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=108 x=1554 y=0 width=3 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15
- char id=109 x=87 y=0 width=11 height=15 xoffset=0 yoffset=0 xadvance=11 page=0 chnl=15
- char id=110 x=772 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=111 x=780 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=112 x=788 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=113 x=852 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=114 x=1485 y=0 width=4 height=15 xoffset=0 yoffset=0 xadvance=4 page=0 chnl=15
- char id=115 x=1455 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=5 page=0 chnl=15
- char id=116 x=1535 y=0 width=4 height=15 xoffset=0 yoffset=0 xadvance=4 page=0 chnl=15
- char id=117 x=828 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=118 x=1299 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=119 x=271 y=0 width=9 height=15 xoffset=0 yoffset=0 xadvance=9 page=0 chnl=15
- char id=120 x=1306 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=121 x=1313 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=122 x=1401 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=5 page=0 chnl=15
- char id=123 x=1510 y=0 width=4 height=15 xoffset=0 yoffset=0 xadvance=4 page=0 chnl=15
- char id=124 x=1638 y=0 width=3 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15
- char id=125 x=1490 y=0 width=4 height=15 xoffset=0 yoffset=0 xadvance=4 page=0 chnl=15
- char id=126 x=439 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=128 x=448 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=130 x=457 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=131 x=529 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=132 x=538 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=133 x=565 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=134 x=574 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=135 x=628 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=136 x=637 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=137 x=0 y=0 width=13 height=15 xoffset=0 yoffset=0 xadvance=13 page=0 chnl=15
- char id=138 x=664 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=139 x=331 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=140 x=168 y=0 width=10 height=15 xoffset=0 yoffset=0 xadvance=10 page=0 chnl=15
- char id=142 x=394 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=145 x=673 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=146 x=430 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=147 x=421 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=148 x=412 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=149 x=403 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=150 x=691 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=151 x=14 y=0 width=12 height=15 xoffset=0 yoffset=0 xadvance=12 page=0 chnl=15
- char id=152 x=682 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=153 x=281 y=0 width=9 height=15 xoffset=0 yoffset=0 xadvance=9 page=0 chnl=15
- char id=154 x=655 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=155 x=646 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=156 x=179 y=0 width=10 height=15 xoffset=0 yoffset=0 xadvance=10 page=0 chnl=15
- char id=158 x=619 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=159 x=610 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=160 x=1618 y=0 width=3 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15
- char id=161 x=1630 y=0 width=3 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15
- char id=162 x=1327 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=163 x=1334 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=164 x=892 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=165 x=1341 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=166 x=1646 y=0 width=3 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15
- char id=167 x=1413 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=5 page=0 chnl=15
- char id=168 x=1419 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=5 page=0 chnl=15
- char id=169 x=111 y=0 width=11 height=15 xoffset=0 yoffset=0 xadvance=11 page=0 chnl=15
- char id=170 x=1395 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=5 page=0 chnl=15
- char id=171 x=1348 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=172 x=592 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=173 x=1407 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=5 page=0 chnl=15
- char id=174 x=123 y=0 width=11 height=15 xoffset=0 yoffset=0 xadvance=11 page=0 chnl=15
- char id=175 x=1431 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=5 page=0 chnl=15
- char id=176 x=1437 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=5 page=0 chnl=15
- char id=177 x=556 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=178 x=1525 y=0 width=4 height=15 xoffset=0 yoffset=0 xadvance=4 page=0 chnl=15
- char id=179 x=1530 y=0 width=4 height=15 xoffset=0 yoffset=0 xadvance=4 page=0 chnl=15
- char id=180 x=1574 y=0 width=3 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15
- char id=181 x=836 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=182 x=1355 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=183 x=1654 y=0 width=3 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15
- char id=184 x=1658 y=0 width=2 height=15 xoffset=0 yoffset=0 xadvance=2 page=0 chnl=15
- char id=185 x=1540 y=0 width=4 height=15 xoffset=0 yoffset=0 xadvance=4 page=0 chnl=15
- char id=186 x=1449 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=5 page=0 chnl=15
- char id=187 x=1369 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=188 x=63 y=0 width=11 height=15 xoffset=0 yoffset=0 xadvance=11 page=0 chnl=15
- char id=189 x=27 y=0 width=11 height=15 xoffset=0 yoffset=0 xadvance=11 page=0 chnl=15
- char id=190 x=99 y=0 width=11 height=15 xoffset=0 yoffset=0 xadvance=11 page=0 chnl=15
- char id=191 x=1467 y=0 width=5 height=15 xoffset=0 yoffset=0 xadvance=5 page=0 chnl=15
- char id=192 x=385 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=193 x=466 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=194 x=376 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=195 x=358 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=196 x=349 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=197 x=340 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=198 x=157 y=0 width=10 height=15 xoffset=0 yoffset=0 xadvance=10 page=0 chnl=15
- char id=199 x=718 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=200 x=1068 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=201 x=1075 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=202 x=1082 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=203 x=1089 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=204 x=1566 y=0 width=3 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15
- char id=205 x=1614 y=0 width=3 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15
- char id=206 x=1570 y=0 width=3 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15
- char id=207 x=1598 y=0 width=3 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15
- char id=208 x=700 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=209 x=201 y=0 width=9 height=15 xoffset=0 yoffset=0 xadvance=9 page=0 chnl=15
- char id=210 x=251 y=0 width=9 height=15 xoffset=0 yoffset=0 xadvance=9 page=0 chnl=15
- char id=211 x=241 y=0 width=9 height=15 xoffset=0 yoffset=0 xadvance=9 page=0 chnl=15
- char id=212 x=301 y=0 width=9 height=15 xoffset=0 yoffset=0 xadvance=9 page=0 chnl=15
- char id=213 x=211 y=0 width=9 height=15 xoffset=0 yoffset=0 xadvance=9 page=0 chnl=15
- char id=214 x=311 y=0 width=9 height=15 xoffset=0 yoffset=0 xadvance=9 page=0 chnl=15
- char id=215 x=709 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=216 x=321 y=0 width=9 height=15 xoffset=0 yoffset=0 xadvance=9 page=0 chnl=15
- char id=217 x=727 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=218 x=736 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=219 x=745 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=220 x=754 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=221 x=924 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=222 x=932 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=223 x=940 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=224 x=1194 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=225 x=1201 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=226 x=1208 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=227 x=1215 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=228 x=1320 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=229 x=1222 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=230 x=190 y=0 width=10 height=15 xoffset=0 yoffset=0 xadvance=10 page=0 chnl=15
- char id=231 x=1236 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=232 x=1243 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=233 x=1250 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=234 x=1257 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=235 x=1264 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=236 x=1582 y=0 width=3 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15
- char id=237 x=1586 y=0 width=3 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15
- char id=238 x=1590 y=0 width=3 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15
- char id=239 x=1594 y=0 width=3 height=15 xoffset=0 yoffset=0 xadvance=3 page=0 chnl=15
- char id=240 x=956 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=241 x=964 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=242 x=972 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=243 x=980 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=244 x=988 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=245 x=996 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=246 x=1004 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=247 x=763 y=0 width=8 height=15 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
- char id=248 x=1020 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=249 x=1028 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=250 x=1036 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=251 x=1044 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=252 x=1052 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=253 x=1362 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- char id=254 x=1060 y=0 width=7 height=15 xoffset=0 yoffset=0 xadvance=7 page=0 chnl=15
- char id=255 x=1376 y=0 width=6 height=15 xoffset=0 yoffset=0 xadvance=6 page=0 chnl=15
- kernings count=560
- kerning first=121 second=132 amount=-1
- kerning first=121 second=130 amount=-1
- kerning first=121 second=133 amount=-1
- kerning first=121 second=46 amount=-1
- kerning first=121 second=44 amount=-1
- kerning first=89 second=117 amount=-1
- kerning first=133 second=145 amount=-1
- kerning first=133 second=146 amount=-1
- kerning first=192 second=74 amount=1
- kerning first=89 second=115 amount=-1
- kerning first=89 second=114 amount=-1
- kerning first=89 second=111 amount=-1
- kerning first=216 second=84 amount=-1
- kerning first=89 second=105 amount=1
- kerning first=147 second=46 amount=-1
- kerning first=147 second=65 amount=-1
- kerning first=89 second=103 amount=-1
- kerning first=147 second=133 amount=-1
- kerning first=42 second=65 amount=-1
- kerning first=42 second=74 amount=-1
- kerning first=42 second=99 amount=-1
- kerning first=42 second=100 amount=-1
- kerning first=42 second=101 amount=-1
- kerning first=42 second=103 amount=-1
- kerning first=42 second=111 amount=-1
- kerning first=42 second=113 amount=-1
- kerning first=148 second=44 amount=-1
- kerning first=147 second=99 amount=-1
- kerning first=147 second=103 amount=-1
- kerning first=148 second=115 amount=-1
- kerning first=147 second=101 amount=-1
- kerning first=214 second=84 amount=-1
- kerning first=148 second=65 amount=-1
- kerning first=147 second=74 amount=-1
- kerning first=197 second=89 amount=-1
- kerning first=148 second=198 amount=-1
- kerning first=148 second=46 amount=-1
- kerning first=197 second=84 amount=-1
- kerning first=148 second=100 amount=-1
- kerning first=197 second=74 amount=1
- kerning first=44 second=147 amount=-1
- kerning first=44 second=148 amount=-1
- kerning first=44 second=145 amount=-1
- kerning first=44 second=146 amount=-1
- kerning first=148 second=133 amount=-1
- kerning first=89 second=101 amount=-1
- kerning first=46 second=147 amount=-1
- kerning first=46 second=148 amount=-1
- kerning first=46 second=145 amount=-1
- kerning first=46 second=146 amount=-1
- kerning first=196 second=89 amount=-1
- kerning first=196 second=84 amount=-1
- kerning first=65 second=42 amount=-1
- kerning first=89 second=99 amount=-1
- kerning first=89 second=97 amount=-1
- kerning first=89 second=65 amount=-1
- kerning first=192 second=84 amount=-1
- kerning first=65 second=74 amount=1
- kerning first=192 second=86 amount=-1
- kerning first=65 second=84 amount=-1
- kerning first=145 second=103 amount=-1
- kerning first=65 second=86 amount=-1
- kerning first=213 second=84 amount=-1
- kerning first=65 second=89 amount=-1
- kerning first=146 second=101 amount=-1
- kerning first=195 second=84 amount=-1
- kerning first=89 second=110 amount=-1
- kerning first=155 second=89 amount=-1
- kerning first=196 second=74 amount=1
- kerning first=65 second=153 amount=-1
- kerning first=65 second=147 amount=-1
- kerning first=65 second=148 amount=-1
- kerning first=65 second=145 amount=-1
- kerning first=65 second=146 amount=-1
- kerning first=123 second=106 amount=1
- kerning first=65 second=159 amount=-1
- kerning first=89 second=100 amount=-1
- kerning first=65 second=221 amount=-1
- kerning first=145 second=145 amount=-1
- kerning first=145 second=100 amount=-1
- kerning first=146 second=99 amount=-1
- kerning first=187 second=89 amount=-1
- kerning first=132 second=74 amount=1
- kerning first=146 second=100 amount=-1
- kerning first=145 second=74 amount=-1
- kerning first=159 second=65 amount=-1
- kerning first=145 second=99 amount=-1
- kerning first=132 second=84 amount=-1
- kerning first=148 second=101 amount=-1
- kerning first=89 second=154 amount=-1
- kerning first=89 second=193 amount=-1
- kerning first=89 second=194 amount=-1
- kerning first=89 second=132 amount=-1
- kerning first=89 second=130 amount=-1
- kerning first=89 second=139 amount=-1
- kerning first=132 second=87 amount=-1
- kerning first=89 second=156 amount=-1
- kerning first=89 second=195 amount=-1
- kerning first=146 second=103 amount=-1
- kerning first=89 second=192 amount=-1
- kerning first=89 second=133 amount=-1
- kerning first=89 second=191 amount=-1
- kerning first=89 second=230 amount=-1
- kerning first=89 second=198 amount=-1
- kerning first=89 second=252 amount=-1
- kerning first=89 second=251 amount=-1
- kerning first=194 second=86 amount=-1
- kerning first=89 second=249 amount=-1
- kerning first=66 second=84 amount=-1
- kerning first=89 second=250 amount=-1
- kerning first=89 second=245 amount=-1
- kerning first=89 second=246 amount=-1
- kerning first=89 second=244 amount=-1
- kerning first=89 second=242 amount=-1
- kerning first=212 second=84 amount=-1
- kerning first=76 second=42 amount=-1
- kerning first=76 second=63 amount=-1
- kerning first=89 second=243 amount=-1
- kerning first=89 second=241 amount=-1
- kerning first=89 second=239 amount=1
- kerning first=89 second=235 amount=-1
- kerning first=89 second=234 amount=-1
- kerning first=89 second=232 amount=-1
- kerning first=89 second=233 amount=-1
- kerning first=89 second=231 amount=-1
- kerning first=89 second=229 amount=-1
- kerning first=89 second=227 amount=-1
- kerning first=89 second=228 amount=-1
- kerning first=89 second=226 amount=-1
- kerning first=89 second=224 amount=-1
- kerning first=89 second=225 amount=-1
- kerning first=89 second=197 amount=-1
- kerning first=89 second=196 amount=-1
- kerning first=161 second=106 amount=1
- kerning first=192 second=221 amount=-1
- kerning first=132 second=119 amount=-1
- kerning first=89 second=113 amount=-1
- kerning first=89 second=112 amount=-1
- kerning first=195 second=74 amount=1
- kerning first=155 second=221 amount=-1
- kerning first=89 second=109 amount=-1
- kerning first=148 second=103 amount=-1
- kerning first=221 second=97 amount=-1
- kerning first=194 second=89 amount=-1
- kerning first=132 second=221 amount=-1
- kerning first=119 second=46 amount=-1
- kerning first=187 second=221 amount=-1
- kerning first=68 second=44 amount=-1
- kerning first=68 second=46 amount=-1
- kerning first=89 second=46 amount=-1
- kerning first=68 second=84 amount=-1
- kerning first=89 second=44 amount=-1
- kerning first=119 second=133 amount=-1
- kerning first=221 second=112 amount=-1
- kerning first=119 second=44 amount=-1
- kerning first=87 second=105 amount=1
- kerning first=68 second=133 amount=-1
- kerning first=221 second=233 amount=-1
- kerning first=116 second=45 amount=-1
- kerning first=87 second=132 amount=-1
- kerning first=68 second=130 amount=-1
- kerning first=68 second=132 amount=-1
- kerning first=87 second=130 amount=-1
- kerning first=87 second=133 amount=-1
- kerning first=87 second=191 amount=-1
- kerning first=87 second=198 amount=-1
- kerning first=87 second=239 amount=1
- kerning first=221 second=117 amount=-1
- kerning first=221 second=196 amount=-1
- kerning first=87 second=46 amount=-1
- kerning first=87 second=44 amount=-1
- kerning first=85 second=132 amount=-1
- kerning first=221 second=197 amount=-1
- kerning first=85 second=130 amount=-1
- kerning first=85 second=198 amount=-1
- kerning first=221 second=132 amount=-1
- kerning first=221 second=99 amount=-1
- kerning first=114 second=147 amount=1
- kerning first=221 second=194 amount=-1
- kerning first=114 second=132 amount=-1
- kerning first=221 second=65 amount=-1
- kerning first=221 second=193 amount=-1
- kerning first=114 second=130 amount=-1
- kerning first=114 second=133 amount=-1
- kerning first=221 second=241 amount=-1
- kerning first=84 second=121 amount=-1
- kerning first=84 second=119 amount=-1
- kerning first=84 second=117 amount=-1
- kerning first=221 second=114 amount=-1
- kerning first=112 second=146 amount=-1
- kerning first=112 second=145 amount=-1
- kerning first=84 second=115 amount=-1
- kerning first=84 second=114 amount=-1
- kerning first=84 second=111 amount=-1
- kerning first=84 second=79 amount=-1
- kerning first=146 second=97 amount=-1
- kerning first=70 second=44 amount=-1
- kerning first=70 second=46 amount=-1
- kerning first=70 second=65 amount=-1
- kerning first=133 second=148 amount=-1
- kerning first=84 second=74 amount=-1
- kerning first=84 second=105 amount=1
- kerning first=102 second=147 amount=1
- kerning first=102 second=133 amount=-1
- kerning first=70 second=196 amount=-1
- kerning first=70 second=197 amount=-1
- kerning first=84 second=103 amount=-1
- kerning first=70 second=198 amount=-1
- kerning first=70 second=133 amount=-1
- kerning first=70 second=192 amount=-1
- kerning first=70 second=195 amount=-1
- kerning first=70 second=130 amount=-1
- kerning first=70 second=132 amount=-1
- kerning first=70 second=194 amount=-1
- kerning first=70 second=193 amount=-1
- kerning first=84 second=71 amount=-1
- kerning first=76 second=146 amount=-1
- kerning first=221 second=225 amount=-1
- kerning first=101 second=34 amount=-1
- kerning first=76 second=84 amount=-1
- kerning first=76 second=159 amount=-1
- kerning first=76 second=86 amount=-1
- kerning first=84 second=101 amount=-1
- kerning first=101 second=39 amount=-1
- kerning first=221 second=100 amount=-1
- kerning first=196 second=86 amount=-1
- kerning first=84 second=99 amount=-1
- kerning first=84 second=67 amount=-1
- kerning first=84 second=97 amount=-1
- kerning first=84 second=65 amount=-1
- kerning first=84 second=122 amount=-1
- kerning first=110 second=34 amount=-1
- kerning first=112 second=148 amount=-1
- kerning first=221 second=115 amount=-1
- kerning first=222 second=65 amount=-1
- kerning first=99 second=84 amount=-1
- kerning first=145 second=65 amount=-1
- kerning first=146 second=130 amount=-1
- kerning first=133 second=147 amount=-1
- kerning first=74 second=44 amount=-1
- kerning first=74 second=46 amount=-1
- kerning first=84 second=110 amount=-1
- kerning first=84 second=227 amount=-1
- kerning first=145 second=198 amount=-1
- kerning first=114 second=148 amount=1
- kerning first=84 second=100 amount=-1
- kerning first=210 second=84 amount=-1
- kerning first=208 second=84 amount=-1
- kerning first=84 second=195 amount=-1
- kerning first=208 second=133 amount=-1
- kerning first=221 second=235 amount=-1
- kerning first=132 second=71 amount=-1
- kerning first=74 second=198 amount=-1
- kerning first=221 second=156 amount=-1
- kerning first=74 second=133 amount=-1
- kerning first=114 second=46 amount=-1
- kerning first=221 second=111 amount=-1
- kerning first=74 second=130 amount=-1
- kerning first=74 second=132 amount=-1
- kerning first=76 second=148 amount=-1
- kerning first=76 second=221 amount=-1
- kerning first=76 second=89 amount=-1
- kerning first=84 second=253 amount=-1
- kerning first=84 second=158 amount=-1
- kerning first=84 second=154 amount=-1
- kerning first=84 second=210 amount=-1
- kerning first=84 second=212 amount=-1
- kerning first=84 second=211 amount=-1
- kerning first=84 second=193 amount=-1
- kerning first=84 second=194 amount=-1
- kerning first=75 second=67 amount=-1
- kerning first=75 second=71 amount=-1
- kerning first=75 second=74 amount=1
- kerning first=75 second=79 amount=-1
- kerning first=75 second=81 amount=-1
- kerning first=84 second=132 amount=-1
- kerning first=84 second=130 amount=-1
- kerning first=84 second=139 amount=-1
- kerning first=84 second=255 amount=-1
- kerning first=84 second=156 amount=-1
- kerning first=84 second=140 amount=-1
- kerning first=84 second=213 amount=-1
- kerning first=84 second=46 amount=-1
- kerning first=84 second=192 amount=-1
- kerning first=84 second=133 amount=-1
- kerning first=84 second=171 amount=-1
- kerning first=75 second=121 amount=-1
- kerning first=75 second=199 amount=-1
- kerning first=75 second=214 amount=-1
- kerning first=84 second=230 amount=-1
- kerning first=84 second=216 amount=-1
- kerning first=84 second=198 amount=-1
- kerning first=84 second=252 amount=-1
- kerning first=84 second=251 amount=-1
- kerning first=84 second=249 amount=-1
- kerning first=84 second=250 amount=-1
- kerning first=84 second=245 amount=-1
- kerning first=84 second=246 amount=-1
- kerning first=84 second=244 amount=-1
- kerning first=84 second=242 amount=-1
- kerning first=84 second=243 amount=-1
- kerning first=75 second=216 amount=-1
- kerning first=75 second=213 amount=-1
- kerning first=75 second=140 amount=-1
- kerning first=84 second=241 amount=-1
- kerning first=75 second=255 amount=-1
- kerning first=84 second=239 amount=1
- kerning first=84 second=235 amount=-1
- kerning first=75 second=211 amount=-1
- kerning first=75 second=212 amount=-1
- kerning first=75 second=210 amount=-1
- kerning first=84 second=234 amount=-1
- kerning first=75 second=253 amount=-1
- kerning first=86 second=111 amount=-1
- kerning first=84 second=232 amount=-1
- kerning first=155 second=84 amount=-1
- kerning first=84 second=233 amount=-1
- kerning first=76 second=147 amount=-1
- kerning first=84 second=231 amount=-1
- kerning first=84 second=229 amount=-1
- kerning first=86 second=224 amount=-1
- kerning first=84 second=228 amount=-1
- kerning first=84 second=226 amount=-1
- kerning first=86 second=101 amount=-1
- kerning first=84 second=224 amount=-1
- kerning first=84 second=225 amount=-1
- kerning first=84 second=214 amount=-1
- kerning first=84 second=199 amount=-1
- kerning first=84 second=197 amount=-1
- kerning first=102 second=145 amount=1
- kerning first=84 second=196 amount=-1
- kerning first=196 second=221 amount=-1
- kerning first=221 second=101 amount=-1
- kerning first=84 second=120 amount=-1
- kerning first=130 second=84 amount=-1
- kerning first=130 second=89 amount=-1
- kerning first=253 second=132 amount=-1
- kerning first=84 second=118 amount=-1
- kerning first=86 second=105 amount=1
- kerning first=221 second=192 amount=-1
- kerning first=111 second=39 amount=-1
- kerning first=102 second=105 amount=1
- kerning first=84 second=113 amount=-1
- kerning first=222 second=133 amount=-2
- kerning first=86 second=197 amount=-1
- kerning first=84 second=112 amount=-1
- kerning first=79 second=132 amount=-1
- kerning first=146 second=115 amount=-1
- kerning first=114 second=146 amount=1
- kerning first=84 second=109 amount=-1
- kerning first=86 second=130 amount=-1
- kerning first=79 second=84 amount=-1
- kerning first=76 second=153 amount=-1
- kerning first=130 second=221 amount=-1
- kerning first=84 second=102 amount=-1
- kerning first=211 second=84 amount=-1
- kerning first=76 second=74 amount=1
- kerning first=221 second=234 amount=-1
- kerning first=147 second=198 amount=-2
- kerning first=88 second=74 amount=1
- kerning first=84 second=81 amount=-1
- kerning first=146 second=74 amount=-1
- kerning first=221 second=231 amount=-1
- kerning first=86 second=99 amount=-1
- kerning first=146 second=65 amount=-1
- kerning first=79 second=46 amount=-1
- kerning first=76 second=118 amount=-1
- kerning first=102 second=46 amount=-1
- kerning first=193 second=221 amount=-1
- kerning first=86 second=65 amount=-1
- kerning first=194 second=84 amount=-1
- kerning first=84 second=44 amount=-1
- kerning first=221 second=44 amount=-1
- kerning first=221 second=110 amount=-1
- kerning first=221 second=195 amount=-1
- kerning first=86 second=132 amount=-1
- kerning first=113 second=106 amount=1
- kerning first=86 second=226 amount=-1
- kerning first=76 second=145 amount=-1
- kerning first=110 second=39 amount=-1
- kerning first=114 second=145 amount=1
- kerning first=197 second=221 amount=-1
- kerning first=86 second=235 amount=-1
- kerning first=222 second=193 amount=-1
- kerning first=130 second=86 amount=-1
- kerning first=130 second=74 amount=1
- kerning first=114 second=45 amount=-1
- kerning first=114 second=44 amount=-1
- kerning first=111 second=146 amount=-1
- kerning first=111 second=148 amount=-1
- kerning first=102 second=45 amount=-1
- kerning first=221 second=251 amount=-1
- kerning first=111 second=34 amount=-1
- kerning first=86 second=194 amount=-1
- kerning first=86 second=192 amount=-1
- kerning first=221 second=250 amount=-1
- kerning first=118 second=133 amount=-1
- kerning first=79 second=130 amount=-1
- kerning first=79 second=133 amount=-1
- kerning first=148 second=154 amount=-1
- kerning first=222 second=196 amount=-1
- kerning first=191 second=89 amount=-1
- kerning first=221 second=226 amount=-1
- kerning first=79 second=44 amount=-1
- kerning first=86 second=242 amount=-1
- kerning first=192 second=89 amount=-1
- kerning first=221 second=244 amount=-1
- kerning first=221 second=232 amount=-1
- kerning first=86 second=100 amount=-1
- kerning first=148 second=111 amount=-1
- kerning first=86 second=245 amount=-1
- kerning first=86 second=44 amount=-1
- kerning first=86 second=227 amount=-1
- kerning first=208 second=46 amount=-1
- kerning first=193 second=74 amount=1
- kerning first=191 second=106 amount=1
- kerning first=86 second=244 amount=-1
- kerning first=86 second=97 amount=-1
- kerning first=86 second=193 amount=-1
- kerning first=102 second=44 amount=-1
- kerning first=191 second=221 amount=-1
- kerning first=195 second=86 amount=-1
- kerning first=193 second=89 amount=-1
- kerning first=221 second=198 amount=-1
- kerning first=221 second=246 amount=-1
- kerning first=253 second=133 amount=-1
- kerning first=221 second=105 amount=1
- kerning first=147 second=100 amount=-1
- kerning first=222 second=74 amount=-1
- kerning first=86 second=239 amount=1
- kerning first=145 second=101 amount=-1
- kerning first=253 second=46 amount=-1
- kerning first=221 second=249 amount=-1
- kerning first=86 second=246 amount=-1
- kerning first=86 second=113 amount=-1
- kerning first=146 second=146 amount=-1
- kerning first=102 second=93 amount=1
- kerning first=221 second=229 amount=-1
- kerning first=197 second=86 amount=-1
- kerning first=195 second=221 amount=-1
- kerning first=86 second=191 amount=-1
- kerning first=221 second=46 amount=-1
- kerning first=222 second=194 amount=-1
- kerning first=221 second=103 amount=-1
- kerning first=221 second=139 amount=-1
- kerning first=107 second=45 amount=-1
- kerning first=91 second=106 amount=1
- kerning first=86 second=234 amount=-1
- kerning first=86 second=233 amount=-1
- kerning first=86 second=103 amount=-1
- kerning first=222 second=197 amount=-1
- kerning first=146 second=133 amount=-1
- kerning first=118 second=130 amount=-1
- kerning first=86 second=228 amount=-1
- kerning first=221 second=242 amount=-1
- kerning first=80 second=44 amount=-2
- kerning first=80 second=46 amount=-2
- kerning first=80 second=65 amount=-1
- kerning first=86 second=133 amount=-1
- kerning first=80 second=74 amount=-1
- kerning first=86 second=198 amount=-1
- kerning first=253 second=130 amount=-1
- kerning first=130 second=79 amount=-1
- kerning first=221 second=227 amount=-1
- kerning first=102 second=239 amount=1
- kerning first=86 second=46 amount=-1
- kerning first=86 second=196 amount=-1
- kerning first=86 second=231 amount=-1
- kerning first=130 second=118 amount=-1
- kerning first=80 second=196 amount=-1
- kerning first=80 second=197 amount=-1
- kerning first=86 second=229 amount=-1
- kerning first=221 second=113 amount=-1
- kerning first=208 second=44 amount=-1
- kerning first=195 second=89 amount=-1
- kerning first=132 second=86 amount=-1
- kerning first=118 second=132 amount=-1
- kerning first=86 second=156 amount=-1
- kerning first=221 second=252 amount=-1
- kerning first=118 second=46 amount=-1
- kerning first=222 second=198 amount=-2
- kerning first=221 second=228 amount=-1
- kerning first=221 second=245 amount=-1
- kerning first=193 second=84 amount=-1
- kerning first=194 second=74 amount=1
- kerning first=222 second=130 amount=-2
- kerning first=208 second=130 amount=-1
- kerning first=80 second=198 amount=-2
- kerning first=221 second=239 amount=1
- kerning first=80 second=133 amount=-2
- kerning first=80 second=192 amount=-1
- kerning first=80 second=195 amount=-1
- kerning first=222 second=44 amount=-2
- kerning first=80 second=130 amount=-2
- kerning first=80 second=132 amount=-2
- kerning first=80 second=194 amount=-1
- kerning first=80 second=193 amount=-1
- kerning first=130 second=87 amount=-1
- kerning first=86 second=225 amount=-1
- kerning first=222 second=132 amount=-2
- kerning first=194 second=221 amount=-1
- kerning first=193 second=86 amount=-1
- kerning first=253 second=44 amount=-1
- kerning first=102 second=153 amount=1
- kerning first=221 second=230 amount=-1
- kerning first=222 second=46 amount=-2
- kerning first=132 second=118 amount=-1
- kerning first=221 second=130 amount=-1
- kerning first=86 second=232 amount=-1
- kerning first=147 second=44 amount=-1
- kerning first=221 second=191 amount=-1
- kerning first=146 second=111 amount=-1
- kerning first=146 second=44 amount=-1
- kerning first=146 second=113 amount=-1
- kerning first=86 second=243 amount=-1
- kerning first=132 second=89 amount=-1
- kerning first=130 second=119 amount=-1
- kerning first=145 second=111 amount=-1
- kerning first=118 second=44 amount=-1
- kerning first=71 second=46 amount=-1
- kerning first=221 second=154 amount=-1
- kerning first=221 second=243 amount=-1
- kerning first=221 second=133 amount=-1
- kerning first=222 second=195 amount=-1
- kerning first=86 second=195 amount=-1
- kerning first=146 second=198 amount=-1
- kerning first=81 second=44 amount=-1
- kerning first=81 second=46 amount=-1
- kerning first=146 second=46 amount=-1
- kerning first=81 second=84 amount=-1
- kerning first=221 second=109 amount=-1
- kerning first=102 second=146 amount=-1
- kerning first=102 second=148 amount=-1
- kerning first=102 second=39 amount=-1
- kerning first=102 second=34 amount=-1
- kerning first=81 second=133 amount=-1
- kerning first=100 second=146 amount=-1
- kerning first=100 second=148 amount=-1
- kerning first=100 second=39 amount=-1
- kerning first=81 second=130 amount=-1
- kerning first=81 second=132 amount=-1
- kerning first=100 second=34 amount=-1
- kerning first=146 second=154 amount=-1
- kerning first=208 second=132 amount=-1
- kerning first=221 second=224 amount=-1
- kerning first=222 second=192 amount=-1
- kerning first=71 second=44 amount=-1
- kerning first=71 second=171 amount=-1
- kerning first=71 second=133 amount=-1
- kerning first=86 second=230 amount=-1
- kerning first=71 second=112 amount=-1
- kerning first=71 second=181 amount=-1
- kerning first=71 second=139 amount=-1
- kerning first=71 second=102 amount=-1
- kerning first=71 second=116 amount=-1
- kerning first=71 second=115 amount=-1
- kerning first=71 second=101 amount=-1
- kerning first=71 second=97 amount=-1
- kerning first=71 second=132 amount=-1
- kerning first=71 second=130 amount=-1
Folgendes Testprogramm konnte die ersten 6 Schriftgrößen im Speicher des C64 unterbringen:
fontsizetest1.prgKommentare zum Programm:
- Die Speicherplatzbelegung stand im Vordergrund.
- Die Ausgaberoutine ist fehlerbehaftet (Fehler im Shifting; deshalb habe ich auch kein Kerning verwendet, obwohl es einfach ist und möglich, d.h. vorbereitet).
- Die Ausgaberoutine ist sehr allgemein gehalten und deshalb auch sehr langsam. Theoretisch ist eine Fonthöhe von 255 Pixel möglich und eine Char-Breite bis 128 Pixel (oder sogar 255?).
- Der erste Font (Schriftgrößeist kaum lesbar, weil das Ausgangsmaterial bereits schlecht war, d.h. der Font braucht etwas mehr Platz, um gut auszusehen.
- Die wirr dargestellten Zeichen in der letzten Zeile (Schriftgröße 22) sind diejenigen, die auf einer anderen Page liegen würden. (siehe folgenden Screenshot für Schriftgröße 36 aus einem anderen Testprogramm.)Fazit:
- Die Bitmapgröße ändert sich bei Verwendung weniger Zeichen entsprechend.
Bspw. Schriftgröße 12:-- 102 Zeichen 740 Pixel breit 1395 Bytes statt 3120 Bytes
-- 95 Zeichen 680 Pixel breit 1275 Bytes
-- 91 Zeichen 653 Pixel breit 1230 Bytes
- Wenn man einwenig Zeit für das Wechseln eines Fonts in Kauf nimmt, kann man
-- den Header für nicht genutzte Zeichen verkleinern.
--- Formel mit Kerning: 10+(5*Zeichen). Formel ohne Kerning: 10+(3*Zeichen).
-- die Bilddaten komprimieren, weil viele 0 Bytes vorkommen. (Wahrscheinlich nur bei größeren Fonts sinnvoll; Das Entpacken müsste schnell sein.)
- Das Kerning (inkl. Header) beansprucht in diesem Format ca. 25%-35% der Gesamtgröße. Es könnte direkt auch anders gespeichert werden, so dass man ca. 1 Byte pro Zeichen, für das ein Kerning angegeben ist, spart. (Hatte ich der Einfachheit halber nicht gemacht.)- Mehr oder breitere Pages gehen mit einer Vergrößerung des Headers einher. (Wäre sinnvoll für größere Fonts, d.h. ab ca. durchschnittlich 2048/91 = 23 Pixel Breite pro Zeichen. Hier gibt es mehrere Methode. Für eine doppelt breite Page würde man bspw. 256*1Bit = 32 Bytes extra benötigen.)
- Die Geschwindigkeit wäre optimal, wenn beim Wechseln eines Fonts ein Speedcode für den jeweiligen Font generiert werden würde, so dass trotzdem alle Größen möglich sind. (Es gibt nat. noch viele weitere Features, die man einbauen könnte. Stichwort: Fonteffekte.)
Ein durchschnittlicher Font benötigt derzeit also ca. 2 - 2,5 KB ohne Kerning und ca. 4 KB mit Kerning.
(...) -
Antwort auf: "kann man 2022 noch produktiv mit dem C64 arbeiten":
Ja, mit der vorhandenen, genannten Software, lässt sich ein Text "retromäßig" erstellen, bearbeiten und evtl. auch einigermaßen ausreichend ausdrucken.
Unter "modernen" Gesichtspunkten, fallen jedoch der Vorgang (Aufwand/Komfort), die Möglichkeiten (Formate/Funktionen) und das Ergebnis (Qualität), negativ zu Lasten des C64 aus.
Ich bin mir sicher, dass auf einem C64 in der Grundausstattung (C64+1541), mit einem neu geschriebenen Textverarbeitungsprogramm,
deutlich "mehr" in den o.g. Bereichen herausgeholt werden kann und auch machbar ist.
(...) -
2 Farben pro Hires 8x8 Bitmap-Kachel plus eine Farbe in einer 48x21 "Sprite-Kachel".
Edit: Sollte heißen plus eine freie Farbe... Natürlich hat jedes MC-Sprite 3 Farben.
-
Wir haben also 2 Farben pro Hires 8x8 Bitmap-Kachel plus 3 Farben in einer 48x21 "Sprite-Kachel" , wobei ein "Pixel" hier 4x1 groß ist.
Pro Sprite-Kachel hätte das Format alle 3 Farben individuell, Du nimmst aber 2+schwarz.
So weit korrekt?
Übrig bleibt ein für den Pfeil nutzbares Sprite.
Fast richtig.
2 Farben pro Hires 8x8 Bitmap-Kachel plus eine Farbe in einer 48x21 "Sprite-Kachel".
Der Grund ist, dass die 2 Sprite-Multicolor-Farben für alle Sprites (((je Rasterzeile))) gelten.
Bzgl. der Demo mit der Einschränkung ergibt sich für den Sprite-Layer für das gesammte Bild nur die freie Wahl von 2 Farben (+ Schwarz ist fix).
Der Rest ist korrekt.Braucht man denn für die Gegenstände im "Fundus" keine Sprites?
Ich hatte in der DT-100 Demo nicht vor Gegenstände darzustellen, weil dort keine Sprites für die Objekte verwendet werden (siehe den Post #246 für mögliche Umsetzungen).
Falls Du mit "Fundus" unten das Panel meinst, dort habe ich nur 2 Sprites für das MouseOver bei den grünen Befehlen verwendet, weil dort der Zeilenabstand 9 Pixel beträgt.
Mouseover über den Rest der violett gefärbten Gegenstandslisten und der blauen Pfeile, die im Moment nicht sichtbar sind, sind einfach mit einer üblichen Farbänderung im Bitmapmodus umsetzbar, d.h. hier benötigt man keine weiteren Sprites, weil die Zeilenpositionen durch 8 teilbar sind und somit im Raster liegen."Findet" der Konverter für die EGA-Farben immer zuverlässig die (zumindest 14) entsprechenden C64 Farben oder würde es was bringen, die Farben schon vorher auszutauschen?
Weißt Du, auf welche Palette hin der Konverter umwandelt?
Bzgl. der ersten Frage müsstest Du das selbst austesten.
Bzgl. der zweiten Frage: In der Vorgängerversion des Konverters sind Paletten in der .zip-Datei enthalten. Evtl. werden diese auch in der neueren Version verwendet. (Konnte ich wegen der Dateiendung nicht anghängen.)
https://csdb.dk/release/?id=76055Andererseits muss ich auch feststellen, dass Pixeln eine sehr beruhigende Tätigkeit ist, die mir gut tut. Zum Glück habe ich bald viel mehr Zeit für diesen ganzen schönen Shice.
-
Tobias
Ich hoffe ich habe Deine Fragen richtig verstanden.Wie wird die MUSCU Grafik dann erzeugt
Soweit ich weiß, existiert derzeit kein Editor, d.h. eine Nachbearbeitung ist schwierig bzw. unpraktikabel bis fast unmöglich (?).
Ich habe die Screenshots mit dem Tool MUSC-Hires Converter von Algorithm konvertiert.
- Das Tool stellt neue Features für sein "MUSC-Format V2" Format bereit, welche ich in meiner Demo nicht verwenden wollte bzw. nicht als sinnvoll erachtet habe.- Es enthält jedoch zumindest Bugfixes im Vgl. zur Vorgängerversion.
Meine Vorgehensweise je Screenshot war:
1.) Bild geladen
2.) "none" beim Dithering gewählt.
3.) Im rechten Dropdown "$d027-$d02d - Manual selection" gewählt und die Felder $d027-$d02d auf 0 gesetzt.
4.) Im linken Dropdown "MUSC - Underlay Perceptual" gewählt und einmal auf "Process" gedrückt.
5.) Im linken Dropdown "MUCSU - Manual" gewählt und die 2 prominentesten Farben "durch scharfes hinsehen" identifiziert und in die Felder für $d025 und $d026 eingetragen.
6.) Nochmal auf "Process" gedrückt und die Datei als ".raw" gespeichert.
--------------Um die unnötigen Daten aus den gespeicherten ".raw"-Dateien zu entfernen, habe ich folgendes ".lua" Skript ausgeführt.
Aufruf mit:
lua54.exe muc2bin.lua dateiname.raw dateiname.muc
also bspw.: lua54.exe muc2bin.lua 00.raw 00.muc
Für weitere Infos bzgl. lua siehe https://www.lua.org/Code: muc2bin.lua- function _G.printf(...) print(string.format(...)) end
- _G.verbosity = 0
- function _G.vbsprintf(lv, ...) if verbosity >= lv then printf(...) end end
- function loadFile(name)
- local file, msg = io.open(name, "rb")
- if not file then return nil end
- assert(file, msg)
- local data = file:read("*a")
- file:close()
- assert(data, "error reading file " .. name)
- vbsprintf(0, "file %s - %d bytes read", name, data:len())
- return data
- end
- function writeFile(name, data)
- local file, msg = io.open(name, "wb")
- assert(file, msg)
- file:write(data)
- file:close()
- vbsprintf(0, "file %s written - %d bytes", name, data:len())
- end
- local data = loadFile(arg[1])
- local b = {}
- for i = 0, 719 do
- table.insert(b, string.char(data:byte(i +1)))
- end
- for j = 0, 6 do
- for i = 0, 447 do
- table.insert(b, string.char(data:byte(2048 + j * (8*64) + i +1)))
- end
- end
- table.insert(b, string.char(data:byte(7168 +1)))
- table.insert(b, string.char(data:byte(7424 +1)))
- for i = 0, 6 do
- table.insert(b, string.char(data:byte(7680 + i +1)))
- end
- for i = 0, 5759 do
- table.insert(b, string.char(data:byte(8192 + i +1)))
- end
- writeFile(arg[2], table.concat(b))
Um mehrere ".raw"-Dateien auf einmal zu konvertieren habe ich nat. eine Batch Datei verwendet.
--------------
Als letztes habe ich das Tool DirMaster von Style verwendet und die ".muc"-Dateien auf meine modifizierte DT100 .d64 zu bringen.
(Modifiziert in dem Sinne, dass die "main.prg" vorhanden ist und die Dateinamen wirklich nur aus 2 Buchstaben bestehen, d.h. die .d64 enthält keine Directory-Art.)
Es existieren natürlich auch andere Tools, welche auch automaisiert aufgerufen werden können, um Dateien auf eine .d64 zu übertragen.Wo ist der Vorteil?
Der Vorteil bei diesem Grafikmodus ist, im Vergleich zu MC, dass das Ergebnis im Falle von MI näher an die EGA Darstellung herankommt.
Der Vorteil im Vergleich zu NUFLI, liegt darin, dass er speicherplatzschonender, simpler aufgebaut und anzeigbar ist, und auch ein Sprite für den Mauspfeil frei ist.
Zusätzlich weiß ich nicht, ob bei NUFLI das Einfügen von Inhalten Colorclashes oder andere Auswirkungen auf den Rest der Grafik hat.
Und der subjektiv wichtigste Grund für mich ist, dass mein Skilllevel nicht ausreichend für eine Umsetzung mit NUFLI ist/wäre.Hast Du mal die "technischen Daten" aus Anwendersicht?
Da gibt es nicht viel:
- Hires-Bitmap-Modus mit einem SpriteLayer darunter, bestehend aus 7 horizontal gestreckten Multicolor-Sprites und in unserem Fall über 7 Sprites in der Höhe, da 7*21 = 147 Pixel hoch.
- Die aktuellen Speicherpositionen lassen sich aus dem lua Skript entnehmen. Jedoch handelt es sich bei dem hier verwendeten ".muc" Format um eines, welches sich noch kurzfristig ändern kann.
-- Zusätzlich haben wir folgende Einschränkung in dieser Demo bzgl. des Spritelayers:
--- Sprite-Mutlicolor1 und Sprite-Mutlicolor2 sind je Raumgrafik festgelegt.
--- Die SpriteColor ist für alle Sprites immer auf Schwarz festgelegt.
Ich hoffe ich konnte einige Unklarheiten beseitigen. -
Echte Hardwaresprites sind bei der MUSCU-Methode nicht möglich, da sie alle (7 + Mauszeiger) verwendet werden.
-----
Worüber man nachdenken könnte, wäre die benötigten Objektgrafiken für einen Raum separat als Grafikausschnitt (=Screen+Bitmap+Spritedaten) statt Sprites zu speichern.
Im D42-System sind für die ersten 56 Objekte jeweils 1 Sprite (="SpriteGrafik") definierbar.
In einem Raum können max. 8 Objekte gleichzeitig vorhanden sein bzw. initial mit einem Sprite und einer XY-Spriteposition definiert werden.
Im Verlauf des Spiels gehen diese Referenzen zwischen den Objekten und Spritepositionen verloren, so dass die max. 8 ursprünglich definierten Objekte, höchstens einmal zu Beginn beim Anzeigen eines Raumes an bestimmten Stellen gezeichnet werden müssen.
Darüberhinaus können sich die definierten Spritepositionen auch während des Spiels nicht ändern, was die Umsetzung für die "MUSCU-Methode" sehr vereinfacht.
-----
Es gibt mehrere Lösungen für eine Umsetzung der Objektgrafiken im MUSCU-Grafikmodus.
Sie sind abhängig davon,
- wie man die 8 initialen Objektgrafiken definieren möchte,
- wo man sie speichern/unterbringen möchte,
- ob zusätzliche Metadaten in irgendeiner Form mitgegeben werden, und
- wieviel Aufwand man betreiben möchte.-----
Im besten (erträumten) Fall, wären bspw. größere Flächen und Animationen u.ä. möglich.
Im einfachsten "Realrelevanten"-Fall, welchen ich bevorzugen würde, wären die max. 8 benötigten Spritegrafiken in der Bilddatei ".muc" unterhalb der 144. Pixelzeile definiert.
Der Bereich könnte bspw. folgende Maße haben: 8 * 32 Pixel (Breite) * 24 Pixel (Höhe).
Warum nicht 24*21 ?
Die Breite sollte durch 16 teilbar sein und die Höhe durch 8, um Schiebeoperationen/Colorclashes für die Darstellung in MUSC zu vermeiden und die Spritekoordinaten (8-Bit) aus dem D42-System einfach nutzen zu können.
Die Grafiken würden als Blöcke ohne Transparenz gezeichnet werden.
-----
Im primitivsten/trivialsten Fall, ignoriert man einfach die Sprite-Geschichte.
(Im DT100-Adventure werden Sprites nicht genutzt (bzw. habe ich keine gesehen ;))
==================
Noch ein Hinweis zu einer künstlichen Einschränkung, welche ich in meinem Beipsiel gesetzt habe:
- Obwohl das MUSCU-Format für jedes Sprite eine eigene Hintergrundfarbe ermöglicht, d.h. jeder vertikale Streifen im Abstand von 48 Pixel könnte eine eigene Spritefarbe haben, habe ich sie einfach auf Schwarz gesetzt.
Der Hintergrund ist der, dass in meiner Vorstellung, die Schrift, die auf der Raumgrafik gezeichnet werden soll, einen schwarzen Rand (4-Pixel grob!) haben können sollte.
Diese Einschränkung würde sich auch auf die Objektgrafiken auswirken.
----
Und noch ein Zusatzgedanke/ Gedanke am Rande:
Ich habe jetzt wieder viel geschrieben.
Ich denke mir, dass mittlerweile so tolle Dinge (=IDE + Compiler/Transpiler ?), wie TRSE jedem ermöglichen, schnell "etwas" zu erstellen/"programmieren".
M.M.n. ist TRSE sehr gut dokumentiert und mit vielen Beispielen versehen.
(Ich bin positiv sehr beeindruckt und werde das Programm mit Sicherheit in der Zukunft benutzen/ausprobieren!)
Als Anregung/Motivation/Einstiegspunkt für die Nutzung von etwas "Turbo Pascal"-ähnlichem für die Erstellung eines SCUMM-artigen Adventures könnte folgender Link dienen:
https://www.loekvandenouweland…-game-that-never-was.html
(Soweit ich das sehe, wird im Link kein Interpreter genutzt/umgesetzt, sondern jeder Raum ist eigens "programmiert".)
Im Internet findet man nat. noch mehr Turbo-Pascal Code/Beispiele/Anregungen.
-
Bolzgramm:
Die ursprünglichen Raumdaten sind mit einer einfachen RLE Kodierung gespeichert.
Max. werden ca. 31 Blöcke verwendet (=bestehend aus 12 Blöcke Daten und ca. 19 Blöcke Grafik).
Falls sich die Daten gut komprimieren lassen, wird entsprechend weniger Speicher benötigt.
-----
Ein MUSCU-Bild aus dem Beispiel beansprucht ca. 38 Blöcke, wobei keine Komprimierung verwendet wurde.
Die Idee war, dass man die Bilder einfach* mit auf die Disketten bei den jeweiligen Räumen speichert und die Endung ".muc" hinzufügt.
* = Im Endeffekt war es dann jedoch doch sinnvoll ein Skript zu nutzen, welches einmal die nicht benötigten/unsichtbaren Teile des ursprünglichen MUSCU-Bildformats entfernt. Statt 64 Blöcke (mit Lücken) werden jetzt also nur noch 38 für eine Raumgrafik mit 18 Zeilen Höhe (=144 Pixel) benötigt.
Zusammen mit den ursprünglichen unberührten Raumdaten ergibt das max. ca. 69 Blöcke pro Raum bzw. 664/69 = ca. 9 Räume pro Diskettenseite.
(Soweit wäre das für die DT100-Demo ausreichend.)
------------------------------
Bei der Anwendung des Konvertierungsskripts könnte man einen Schritt weiter gehen und auch über eine Komprimierung nachdenken bzw. man könnte ein komplett neues Raumdatenformat erzeugen, welches aus den ursprünglichen Raumdaten und einer neuen Grafik besteht, so dass die ursprünglichen Raumdaten nicht mehr auf der Diskette vorhanden sein müssten.
Das neue Raumdatenformat würde dann pro Raum unkomprimiert 50 Blöcke (= 12 Blöcke Daten und 38 Blöcke für die MUSCU-Grafik) benötigen.
664 / 50 = ergibt ca. 13 Räume pro Diskettenseite.-----Ich habe gerade aus Neugier Exomizer mit den MUSCU-Grafiken getestet:
- im Durchschnitt gab es eine Reduktion um ca. 40-55%, d.h. von 38 Blöcke auf ca. 22.
- Bei dem Bild "13.muc" gab es einen Ausreißer und es konnte nur um ca. 23% reduziert werden, d.h. von 38 Blöcke auf ca. 29.
Hier würden schätzungsweise also ca. 20 Räume pro Diskettenseite Platz finden.
(...)
Es fehlt noch ein Test mit dem oben beschriebenen neuen zusammengesetzten Raumformat.
Ich denke, dass man so auf ca. 22 Räume pro Diskettenseite kommen könnte;
Gedanken dazu:
- der Workflow würde sich dadurch jedoch auch ändern, d.h. falls man Korrekturen oder Änderungen mit dem D42-System an seinem Adventure vornehmen würde, müsste man danach erst immer das neue Format erzeugen, um im neuen Player zu testen usw. usf.
(...) -
"Secret of Monkey Island" auf dem Apple II von Vince "deater" Weaver (inkl. cc65 Sourcecode):
[External Media: https://www.youtube.com/watch?v=_KXncYyl2Mo]http://www.deater.net/weave/vmwprod/monkey/
https://github.com/deater/dos33fsprogs
Weitere interessante Demakes/Techdemos von ihm, anhand derer man sehen kann, was auf alten Rechnern umsetzbar ist, bspw. Apple II Peasant's Questhttp://www.deater.net/weave/vmwprod/demakes/
http://www.deater.net/weave/vmwprod/peasant/
[External Media: https://www.youtube.com/watch?v=ThCUvKhsdW4]
--------------------------------------------------------------------Zurück zum C64:
Anbei ein kleines Update zu dem muscu-Test mit den DT100 Daten.
mi-scummui-002.d64
- pro:
-- Man kann die Screens bewundern.
- contra:
-- kein Speedloader, da zusammengeschusterte Floppy-Routinen (Am besten Warp in Vice nutzen).
-- Es gibt eine Rasterzeile mit einem Grafikfehler.
(...) -
Du willst also diese D42-"Engine" umschreiben/verbessern, richtig? So ne Art "ScummVM-ultralight"-D42?
Genau, aber ganz ungezwungen, d.h. sofern Zeit, Lust und Energie da ist, ausprobieren, was machbar wäre.
Gibt's irgendwo ne Übersicht mit den Spezifiaktion zu den diversen Algotech-Formaten? Die txt-Dateien zu den Konvertern sind meist nicht sehr aufschlussreich.
Gibt es irgendwo eine genaue Spezifikation des Formats?
Ich kann mich daran erinnern eine Textdatei gesehen zu haben. Es könnte auf der inzwischen nicht mehr vorhandenen Seite gewesen sein.
Mittels Testbilder und JC64dis hatte ich versucht den Aufbau selbst zu bestimmen.
Nachfolgend eine Tabelle für MUSC oder MUSCU, die für meine Zwecke ausreichend ist/war.
Es sind Lücken im Format vorhanden, die Leer sind; evtl. waren sie für Erweiterungen oder unterschiedliche Versionen gedacht.Inhalt Adresse Kommentar Screen 0-1024 1000 Bytes werden benutzt Sprites 2048-??? 4480 Bytes, enstpr. 7*10 Sprites (theoretisch bis Adresse 6527) MCol1 7168-7423 200 von 256 Bytes für jede Zeile $d025 MCol2 7424-7679 200 von 256 Bytes für jede Zeile $d026 SprColors 7680-??? 7 Farben für die Sprite Hauptfarben, für mich war nur V1 von Interesse Bitmap 8192-16384 8000 Bytes werden benutzt Vielen Dank für die ganzen Überlegungen, aber aufgrund meiner geringen Kenntnisse begnüge ich mich mit dem vorhandenen System und bin da auch total zufrieden mit.
Vielen Dank auch, dass Ihr ein solches Projekt in Angriff nehmt. Ich freue mich immer über neue Programme und Spiele und bin schon sehr gespannt auf dieses Adventure.
Wenn Du das D42 System verbessern / flexibler machen kannst, ist das sicher eine gute Sache und viele werden Dir dankbar sein, solange es rückwärtskompatibel bleibt.
Das wird aber eher ein mitterlfristiges Projekt werden, oder?
@all
Es wird wohl am zielführensten sein, wenn Bolzgramm das jetzt so durchzieht, wie besprochen. Auch mit gestauchten und plattgedrückten Konvertierungen.Ich bin der letzte, der nicht immer rummäkelt und es am liebsten 120%ig hätte.
Aber wenn wir uns da jetzt schon am Anfang verkünsteln, wird es so werden, wie mit den beiden existierenden tSoMI-"Demos" oder dem gerade oben gezeigten Indiana Jones: es wird nie fertig werden. Wird schon seine Gründe haben, dass dem so ist.
Wenn das Vorhaben gelingt und später mal eine verbesserte D42 Engine exisitert, kann man immer noch eine aufwändigere tSoMI-Version nachlegen.
Es ist bestimmt schon alleine eine riesen Arbeit, die ganzen "Pfade", Kombinationen usw. zu programmieren. Das alles gibt's dann ja schon und man kann darauf zurückgreifen.Meinerseits sind das ja alles auch nur Ideen/Wunschvorstellungen/Tagträume, d.h. die vorhandenen Dateien und die Arbeit/Arbeitsweise Bolzgramm würden ohnehin unberührt/unverändert bleiben.
Ich wollte nur zusätzliche Sichtweisen/Meinungen bzw. Antworten auf die Frage, wo die Präferenzen liegen würden, falls man die Oberfläche doch anders (= "frei") aufbauen könnte.
(((
Weil "Monkey Island" doch sehr umfangreich ist, hatte ich aus neugier jedoch auch konkrete Fragen bzgl. des Umfangs des erstellten Adventures:
- Wieviele Objekte im D42 -System mussten verwendet werden, um die Story unterzubringen?
- Wurden Allgemeintexte und -Bedingungen genutzt (und wenn ja, in welchem Zusammenhang/für welche Funktion)?
- Wieviele Diskettenseiten werden benötigt?
)))
-----
Nachfolgend ein Testprogramm, welches teilweise zeigt, wie eine mögliche MUSC-Oberfläche aussehen könnte und wie die D42-Funktionen in dieser Wunschvorstellung angeordnet wären.
(Was auch nicht ganz stimmt, weil man noch Platz für die Liste der Raumobjekte unten schaffen müsste. Die einzige Möglichkeit, die ich sehe ist, wenn man die Befehle in 2 Spalten statt 3 anordnet. Den Befehl/die Funktion "Umschau" könnte man einfach in die Bildschirmmitte setzen. Was denkt ihr darüber? (Übrigens habe ich den Maustreiber "DuoDriver" von Marco Baye genutzt, d.h. das Fadenkreuz kann durch Maus und Joystick bewegt werden.))
mi-scummui-001.prg -
Mit z.B. NUFLI könnte man die EGA-Fassung (scheint nach etwas "Recherche" auch die Urfassung aller SoMI Versionen zu sein) fast 1:1 umsetzen.
Die Unterscheidung der beiden Helligkeiten für cyan und magenta in EGA fällt weg, und einige Color Clashes wird es noch geben.
Aber ich verstehe, dass dieses Format außer für "passive" Bilder leider eher ungeeignet ist.
Aus Konvertierungssicht wäre die Erweiterung von 96 auf 144 Linien auch bei Multicolor ein deutlicher Qualitätssprung.Pro: Das NUFLI müsste nur über 144 Pixel gehen.
Contra: Die Frage ist, ob man einen Mauszeiger auf der Grafik darstellen kann und, ob transparenter Text möglich ist.Es gibt einige Alternativen zu NUFLI:
Erst das modifizierte original Bild, d.h. die Farben etwas dunkler gemacht, damit nicht soviele auf engem Raum sind:
EHires: trans. Text ohne Clashes möglich, falls die Farbe korrekt gewählt wurden, bspw. Ink = schwarz.
MC: Hires-Text nur über Sprites lösbar
AFLI (Godot mit unmodifiz. Bild):
MUSC-V1: gefällt mir rein techn. am besten von den alternativen Grafikmodi
MUSC-V2: Evtl. Flicker mit zus. Maussprite ?
Ich habe mir bereits Quellen zu NUFLI herausgesucht und angeschaut, aber das Thema scheint mir zu kompliziert.
Evtl. gibt es irgendwo einen Viewer der gut erklärt ist. Dann könnte man schauen, ob sich das Format nutzen lässt.
Das Problem mit dem Mauszeiger bleibt m.M.n. jedoch bestehen.
Wenn man sich einen Schritt von der SCUMM-UI entfernt, könnte man auch auf die Maus verzichten und per Keyboard die Befehle wählen.Du willst also diese D42-"Engine" umschreiben/verbessern, richtig?
((("Wollen" ist übertrieben.)))
Aber ein Nachprogrammieren würde ich besser finden, weil auch der Spielfluss mit dem scrollenden Text und dem kleinen begrenzten Fenster im aktuellen D42-System geändert/verbessert werden könnte und alles einwenig mehr nach SCUMM, passend zum Threadthema, aussehen würde.
Emotional bin ich da auch nicht drin.
Mich interessiert nur, ob man gute Lösungen für bestimmte kleine Probleme finden kann.
(((Ich habe diesbezgl. ja auch einige Tests gemacht.)))Alles Handarbeit, auch die Schritte vorher in Photoshop
In Photoshop gibt es angeblich auch Batch-Processing.
Edit:
Im Anhang ist noch das MUSC-V1-Bild als .prg zum selber anschauen angehängt.
Ich denke, dass das die einzige einfache Alternative mit Hires-Pixeln zum subjektiv komplizierteren NUFLI ist. (Im Grunde sind damit auch alle Punkte, die ich oben beschrieben habe umsetzbar, falls ich nichts vergessen habe...)(Ich wollte noch schreiben, dass ich kein Brute-Force o.ä. bei der Konvertierung verwendet habe.)
-
Bolzgramm , Tobias , He-Man1982
Die d42_system.zip enthält das Skript "d42_dump.lua", welches
- gut kommentiert ist und
- die D42-Dateiformate beschreibt und
- den internen Aufbau des D42-Systems bzw. eines erstellten Adventures erahnen lässt.Code- -- D42 dumper V1.1
- strUsage = [[
- Usage: lua d42_dump.lua <data dir>
- Create a textual dump of a d42 adventure.
- The data dir must contain all files of the game.
- ]]
- --MODE_HOTSPOT = true
- if not MODE_HOTSPOT then
- -- for standard games
- OJ_OBJ_OFFSET = 0xe03
- else
- -- for Hotspot/32
- OJ_OBJ_OFFSET = 3
- end
- function _G.printf(...) print(string.format(...)) end
- _G.verbosity = 0
- function _G.vbsprintf(lv, ...) if verbosity >= lv then printf(...) end end
- function loadFile(name)
- local file, msg = io.open(name, "rb")
- if not file then return nil end
- assert(file, msg)
- local data = file:read("*a")
- file:close()
- assert(data, "error reading file " .. name)
- vbsprintf(2, "file %s - %d bytes read", name, data:len())
- return data
- end
- function writeFile(name, data)
- local file, msg = io.open(name, "wb+")
- assert(file, msg)
- file:write(data)
- file:close()
- vbsprintf(2, "file %s written - %d bytes", name, data:len())
- end
- function depackD4(bin)
- local pos = 0
- local function getbyte()
- pos = pos + 1
- return bin:byte(pos)
- end
- local unpacked = {}
- local function putbyte(b)
- table.insert(unpacked, string.char(b))
- end
- putbyte(getbyte()) -- copy load addr
- putbyte(getbyte())
- local packbyte = getbyte()
- while (pos<bin:len()) do
- local b = getbyte()
- if b == packbyte then
- local count = getbyte()
- b = getbyte()
- if count== 0 then break end
- for i=1,count do putbyte(b) end
- else
- putbyte(b)
- end
- end
- if #unpacked < 0x1f02 then
- printf("unpacked room file is too short: 0x%x", #unpacked)
- elseif #unpacked > 0x2002 then
- printf("unpacked room file exceeds area: 0x%x", #unpacked)
- end
- if pos < bin:len() then
- printf("depackD4: End marker before EOF: pos = 0x%x, packed len = 0x%x, unpacked len = 0x%x",
- pos, bin:len(), #unpacked)
- end
- return table.concat(unpacked)
- end
- bit = {}
- function bit.band(a, b)
- local x=128
- local c=0
- while x>=1 do
- if a>=x and b>=x then
- c=c+x
- end
- a = a % x
- b = b % x
- x = x/2
- end
- return c
- end
- -- Allgemeindaten:
- -- OJ/O2 Liste der Objekte
- -- FL Liste der Flags
- -- NW Objektverteilung auf Räume
- -- BA Allgemeinbedingungen
- -- Allgemeintexte
- --
- -- Raumdaten:
- -- Bedingungen
- -- Texte
- -- Richtungsflags
- -- Musiknr.
- -- BA
- -- Adresse Inhalt
- -- a000-a3ff 64 Bedingungen
- -- a400-a4ef Allgemeintext 1
- -- ... ...
- -- b300-b3ef Allgemeintext 16
- -- OJ/O2
- -- Objekte $40-$7f (File o2)
- -- Adresse Inhalt
- -- 5000-53ff Deskriptoren für Objekte $40-$7f
- -- Objekte $00-$37 (File oj)
- -- 6400-71ff Sprites für Objekte $00-$37
- -- 643f, 647f Sprite-Multicolorfarben
- -- 7200-757f Deskriptoren für Objekte $00-$37
- -- 7580-75ff frei
- -- NW
- -- Adresse Funktion
- -- 0c00-0c7f Objekt 0 für die R¨aume 00-7f
- -- ... ...
- -- 0f80-0?f Objekt 7 für die R¨aume 00-7f
- -- Objektdescriptor:
- -- Byte (Offset) Funktion
- -- 0-14 Objektname, Screencodes aufgefüllt mit Leerzeichen
- -- 15 Bit 0 0: Objekt kann genommen werden, 1: unbewegliches Objekt
- -- 15 Bit 1 0: Gegenstand, 1: Person
- -- 15 Bit 2 0: Hires-Sprites, 1: Multicolor-Sprite
- -- 15 Bit 3 reserviert
- -- 15 Bits 4-7 Spritefarbe
- -- Textcodierung:
- -- Hexcode Zeichen
- -- $00 oder $20 Space
- -- $1e Text-Endemarke
- -- $1b/$5b ä/Ä
- -- $1d/$5d ö/Ö
- -- $1c/$5c ü/Ü
- -- $5e ß
- -- $3a/$3b : / ;
- -- $3c/$3e < / >
- charset =
- " abcdefghijklmnopqrstuvwxyzäüö^<" -- Pfeil oben Pfeil links
- ..[==[ !"#$%&'()*+,-./0123456789:;<=>?]==]
- .. "?ABCDEFGHIJKLMNOPQRSTUVWXYZÄÜÖß"
- function decodechar(iChar)
- return charset:sub(iChar+1,iChar+1) or "?"
- end
- -- 1-based offsets
- function decodestring(str, iStart, iLen)
- assert(iStart+iLen-1 < str:len(), string.format("%d %d %d", str:len(), iStart, iLen))
- iStart = iStart or 1
- iLen = iLen or str:len()
- local chars = {}
- for i=iStart, iStart+iLen-1 do
- table.insert(chars, decodechar(str:byte(i)))
- end
- return table.concat(chars)
- end
- -- 0-14 Objektname, Screencodes aufgefüllt mit Leerzeichen
- -- 15 Bit 0 0: Objekt kann genommen werden, 1: unbewegliches Objekt
- -- 15 Bit 1 0: Gegenstand, 1: Person
- function getobj(objno)
- local bin, offset, obj
- if objno>=0 and objno<=0x37 then
- bin = game.oj
- offset = OJ_OBJ_OFFSET + objno*16
- obj = bin:sub(offset, offset+15)
- elseif objno>=0x40 and objno <= 0x7f then
- bin = game.o2
- offset = 0x03 + (objno-0x40)*16
- obj = bin:sub(offset, offset+15)
- else
- return string.format(" **** Objekt $%02x **** ", objno), false, false, true
- end
- if obj then
- local fEmpty = false
- local strName = decodestring(obj, 1, 15)
- strName = strName:gsub("%s+$", "")
- if strName=="" then
- fEmpty = true
- strName = string.format("Objekt $%02x", objno)
- end
- local iAttr = obj:byte(16)
- local fTake = bit.band(iAttr, 1) == 0
- local fPerson = bit.band(iAttr, 2) ~= 0
- assert(strName)
- return strName, fTake, fPerson, fEmpty
- end
- end
- function getflag(flagno)
- local offset
- local strName
- local fEmpty
- if flagno>=0 and flagno<=0x3f then
- if game.fl then
- offset = 3 + flagno*16
- strName = decodestring(game.fl, offset, 15)
- fEmpty = false
- strName = strName:gsub("%s+$", "")
- if strName=="" then
- strName = string.format("Flag %02x", flagno)
- fEmpty = true
- end
- else
- strName = string.format("Flag %02x", flagno)
- fEmpty = true
- end
- return strName, fEmpty
- end
- end
- function decodetextlines(strData, iOffset, iLines)
- local lines = {}
- local lastline = 0
- for i=1, iLines do
- local line = decodestring(strData, iOffset, 40)
- line = line:gsub("%s+$", "")
- lines[i] = line
- if line:len()>0 then
- lastline = i
- end
- iOffset = iOffset + 40
- end
- return lines, lastline
- end
- function printtext(iNo, strData, iOffset)
- local lines, lastline = decodetextlines(strData, iOffset, 6)
- if lastline>0 then
- for i=1, lastline do
- printf("%x%x %s", i, iNo, lines[i])
- end
- print()
- end
- end
- function printroomdescription(strUnpackedRoomData)
- local lines, lastline = decodetextlines(strUnpackedRoomData, 3, 10)
- for i=1, lastline do
- print(lines[i])
- end
- print()
- end
- -- trennen an *, ^, ^^
- function printroomdescription_hotspot(strUnpackedRoomData)
- local textlen = 400
- local strRaw = decodestring(strUnpackedRoomData, 3, textlen)
- strRaw = strRaw:gsub("%s+", " ")
- local lines = {}
- local iPos = 0 -- last word break
- local iLineStart = 1 -- starting position of line
- local iMaxlinelen = 64
- -- find the next space, *, ^, ^^
- -- str = word up to space, *, ...
- -- if it fits in the current line, append it
- -- otherwise, write out the current line and append to new line
- -- if str = *, ^, ^^, write out the current line and clear it
- while iPos < strRaw:len() do
- -- find the next break position
- local iStart, iEnd = strRaw:find("[%*%^ ]", iPos+1)
- local strBrk, strBrk2
- if iStart then
- strBrk = strRaw:sub(iStart, iEnd)
- strBr2 = strRaw:sub(iStart, iEnd+1)
- if strBrk2 == "^^" then
- iEnd = iEnd +1
- end
- else
- iEnd = strRaw:len()
- strBrk = ""
- end
- -- if break position - line start > max line len,
- -- break the line at the previous position
- if iEnd - iLineStart > iMaxlinelen then
- local strLine = strRaw:sub(iLineStart, iPos)
- table.insert(lines, strLine)
- iLineStart = iPos+1
- end
- -- if the break is not a space or the end of the text has
- -- been reached, break the line here.
- if strBrk ~= " " or iEnd == strRaw:len() then
- local strLine = strRaw:sub(iLineStart, iEnd)
- table.insert(lines, strLine)
- iLineStart = iEnd+1
- end
- iPos = iEnd
- end
- -- if iLineStart < strRaw:len() then
- -- local strLine = strRaw:sub(iLineStart, strRaw:len())
- -- table.insert(lines, strLine)
- -- end
- for i, line in ipairs(lines) do
- print(line)
- end
- print()
- end
- function printroomdescription_hotspot__(strUnpackedRoomData)
- local textlen = 400
- local strRaw = decodestring(strUnpackedRoomData, 3, textlen)
- strRaw = strRaw:gsub("%s+", " ")
- local lines = {}
- local strLine = ""
- local iPos = 0 -- last word break
- local iMaxlinelen = 64
- -- find the next space, *, ^, ^^
- -- str = word up to space, *, ...
- -- if it fits in the current line, append it
- -- otherwise, write out the current line and append to new line
- -- if str = *, ^, ^^, write out the current line and clear it
- while iPos < strRaw:len() do
- -- find the next break position
- local iStart, iEnd = strRaw:find("[%*%^ ]", iPos+1)
- local strBrk, strBrk2, strWord
- if iStart then
- print(iStart, iEnd)
- strBrk = strRaw:sub(iStart, iEnd)
- strBr2 = strRaw:sub(iStart, iEnd+1)
- if strBrk2 == "^^" then
- iEnd = iEnd +1
- end
- else
- iEnd = strRaw:len()
- strBrk = ""
- end
- strWord = strRaw:sub(iPos+1, iEnd)
- -- if break position - line start > max line len,
- -- break the line at the previous position
- if strLine:len() + strWord:len() > iMaxlinelen then
- table.insert(lines, strLine)
- strLine = ""
- end
- -- append the word
- strLine = strLine .. strWord
- -- if the break is not a space or the end of the text has been reached, break the line here.
- if strBrk ~= " " or iEnd == strRaw:len() then
- table.insert(lines, strLine)
- strLine = ""
- end
- iPos = iEnd
- end
- for i, line in ipairs(lines) do
- print(line)
- end
- print()
- end
- -- Bedingungsblock
- -- 0 Bit 0-5 Verb
- -- 0 Bit 6-7 Vorgehensweise nach Ausf¨uhren der Aktionen
- -- 1 Objektbedingung E oder Flagbedingung
- -- 2 Objektbedingung B oder Flagbedingung
- -- 3 Objektbedingung R oder Flagbedingung
- -- 4-5 Aktion 1 mit Parameter
- -- 6-7 Aktion 2 mit Parameter
- -- 8-9 Aktion 3 mit Parameter
- -- 10-11 Aktion 4 mit Parameter
- -- 12-13 Aktion 5 mit Parameter
- -- 14-15 Aktion 6 mit Parameter
- -- $00-$7f Testen, ob Objekt im Befehl vorkommt
- -- E: im Raum oder Inventar
- -- B: im Besitz (Inventarobjekt)
- -- R: im Raum
- -- $80-$bf Test ob Flag gesetzt
- -- $c0-$fe Test ob Flag gelöscht
- -- $ff Test ¨uberspringen
- --
- -- 00 Aktionen ausführen und Ende
- -- 10 Aktionen ausführen und weiter
- -- 11 Aktionen ausfphren und weiter, aber den Test
- -- der nächsten Bedingung überspringen
- verbs={
- [0]= "Bedingung ungültig",
- [1] = "Öffne",
- [2] = "Verschiebe",
- [3] = "Ein",
- [4] = "Untersuche",
- [5] = "Benutze",
- [6] = "Kombiniere",
- [7] = "Gib",
- [8] = "Nimm",
- [9] = "Verliere",
- [10] = "Rede mit",
- [11] = "Norden",
- [12] = "Osten",
- [13] = "Süden",
- [14] = "Westen",
- [63] = "Verb egal"
- }
- VERBNO_MASK = 0x3f
- CONT_MASK = 0xc0
- CONT_STRINGS = {[0] = "+", [0x40] = "??", [0x80] = "weiter", [0xc0] = "weiter Aktionen"}
- function act_msgno(iPar)
- local textno = iPar % 16
- local lineno = (iPar - textno)/16
- if lineno == 0 then
- return string.format("Text %d", textno)
- else
- return string.format("Text %d Zeile %d", textno, lineno)
- end
- end
- function act_hexno(iPar)
- return string.format("%02x", iPar)
- end
- actions = {
- [0] =
- {text = "----", paramfn = nil},
- {text = "Gegenstand in Besitz", paramfn = getobj}, -- Objektnr.
- {text = "Löschen aus Besitz", paramfn = getobj}, -- Objektnr.
- {text = "Löschen aus Raum", paramfn = getobj}, -- Objektnr.
- {text = "Flag setzen", paramfn = getflag}, -- Flagname/Nr.
- {text = "Flag löschen", paramfn = getflag}, -- Flagname/Nr.
- {text = "Meldung ausgeben", paramfn = act_msgno}, -- Text x [Zeile y]
- {text = "Allgemeinmeldung ausgeben", paramfn = act_msgno}, -- Text x [Zeile y]
- {text = "Sprung zu Raum", paramfn = act_hexno}, -- Raumnr.
- {text = "Game Over", paramfn = act_hexno}, -- Param.
- {text = "Endsequenz", paramfn = nil},
- {text = "Auf Button warten", paramfn = nil},
- {text = "Gegenstand in Raum", paramfn = getobj}, -- Ojektnr.
- }
- function printaction(iNo, iCode, iPar)
- local strAct, strPar
- local act = actions[iCode]
- if act then
- strAct = act.text
- if act.paramfn then
- strPar = act.paramfn(iPar) or "???"
- end
- else
- strAct = "???"
- end
- strPar = strPar or ""
- printf("%02x %02x %-25s %s", iCode, iPar, strAct, strPar)
- end
- -- Fälle:
- -- ganze Bedingung/Aktionen sind 0 -> nur "leer" ausgeben
- -- Verb = 0 -> gesperrt
- -- Normale Bedingung
- empty_cond_block = string.rep(string.char(0), 16)
- ebrtab = {"E", "B", "R"}
- function printcondition(iNo, strData, iOffset)
- if strData:sub(iOffset, iOffset+15) == empty_cond_block then
- --printf("Bedingung %02x: leer", iNo)
- else
- -- Bedingungen
- printf("Bedingung %02x", iNo)
- local iByte0, iByte1, iByte2, iByte3 = strData:byte(iOffset, iOffset + 3)
- local iVerbNo = bit.band(iByte0, VERBNO_MASK)
- local objconditions = {}
- local flagconditions = {}
- local strVerb
- if iVerbNo ~= 0x3f then
- strVerb = verbs[iVerbNo] or "???????????"
- else
- strVerb = ""
- end
- if iVerbNo ~= 0 then
- for i=1, 3 do
- local cond = strData:byte(iOffset+i)
- if cond <= 0x7f then
- local strObj = getobj(cond) or "????"
- table.insert(objconditions, string.format("%s:%s", ebrtab[i], strObj ))
- elseif cond <= 0xbf then
- table.insert(flagconditions, getflag(cond-0x80) .. " = 1")
- elseif cond < 0xff then
- table.insert(flagconditions, getflag(cond-0xc0) .. " = 0")
- end
- end
- end
- printf("%02x %02x %02x %02x %s %s %s", iByte0, iByte1, iByte2, iByte3,
- strVerb, table.concat(objconditions, " "), table.concat(flagconditions, " "))
- -- Aktionen
- iOffset = iOffset + 4
- for actno = 1, 6 do
- local iCode, iParam = strData:byte(iOffset, iOffset+1)
- if iCode ~= 0 then
- printaction(actno, iCode, iParam)
- end
- iOffset = iOffset + 2
- end
- local iCont = bit.band(iByte0, CONT_MASK)
- if iCont ~= 0 then
- print(CONT_STRINGS[iCont])
- end
- print()
- end
- end
- function printobjmap()
- for roomno = 0, 127 do
- local objects = {}
- local lastslot = nil
- for slot = 0, 7 do
- local offset = 3 + 128*slot + roomno
- local entry = game.nw:byte(offset)
- local objno = bit.band(entry, 127)
- local sprite = bit.band(entry, 128)
- if objno ~= 0x7f then
- lastslot = slot
- objects[slot] = string.format("%02x %-15s %s", objno, getobj(objno), sprite == 0 and "Sprite" or " ")
- end
- end
- if lastslot then
- printf("Raum %02x:", roomno)
- for slot = 0, lastslot do
- if objects[slot] then
- printf(" %d %s", slot, objects[slot])
- end
- end
- else
- --printf("Raum %02x: keine Objekte", roomno)
- end
- end
- end
- function printobjlist()
- for objno = 0, 0x7f do
- if objno < 0x38 or objno > 0x3f then
- local objname, fTake, fPerson, fEmpty = getobj(objno)
- if not fEmpty then
- printf("%02x %-15s %-13s %-10s", objno, objname,
- fTake and "tragbar" or "nicht tragbar",
- fPerson and "Person" or "Gegenstand")
- end
- end
- end
- end
- function printflaglist()
- for i=0, 0x3f do
- local strName, fEmpty = getflag(i)
- if not fEmpty then
- printf("%02x %s", i, strName)
- end
- end
- end
- -- Raumfile
- -- Adresse Inhalt
- -- 8000-81df Raumbeschreibung (12*40 Zeichen)
- -- 81e0 gesperrte Richtungen:
- -- 1 - Norden, 2 - Osten, 4 - Sueden, 8 - Westen
- -- 81e1 Musiknr.
- -- 81e2-81e9 Sprites X-Tabelle
- -- 81ea-81f1 Sprites Y-Tabelle
- -- 8200-82ef Raumtext 1
- -- ... ...
- -- 8900-89ef Raumtext 8
- -- 8a00-8bff 32 Bedingungen
- -- 8c00-8ddf Videoram: 12x40 Bytes
- -- 8e00-8fdf Colorram: 12x40 Bytes
- -- 8fff Hintergrundfarbe
- -- 9000-9eff Bitmap: 12x320 Bytes
- -- Varianten bei Texten:
- --PRINT_TEXTLIST = true
- --TEXT_IN_LOGIC_ALWAYS = false
- --TEXT_IN_LOGIC_FIRST = false
- function printroom(iRoomNo, strRoomData)
- print()
- print( "=========")
- printf("Raum %02x", iRoomNo)
- print( "=========")
- print()
- -- Raumbeschreibung
- print("Raumbeschreibung: ")
- if not MODE_HOTSPOT then
- printroomdescription(strRoomData)
- else
- printroomdescription_hotspot(strRoomData)
- end
- print()
- -- Raumtexte
- print("Texte:")
- for i=0, 7 do
- local iOffset = 0x203 + i*256
- printtext(i, strRoomData, iOffset)
- end
- print()
- -- Bedingungen
- print("Bedingungen:")
- for i=0, 31 do
- local iOffset = 0xa03 + i*16
- printcondition(i, strRoomData, iOffset)
- end
- print()
- end
- function printcommondata()
- print()
- print("==============")
- print("Allgemeindaten")
- print("==============")
- print()
- print("Objekte:")
- printobjlist()
- print()
- print("Gegenstandskarte:")
- printobjmap()
- print()
- print("Flags:")
- printflaglist()
- print()
- print("Allgemeintexte:")
- for i=0, 15 do
- printtext(i, game.ba, 0x0403 + i*256)
- end
- print()
- print("Allgemeinbedingungen:")
- for i=0, 63 do
- local iOffset = 3 + i*16
- printcondition(i, game.ba, iOffset)
- end
- print()
- end
- function loadgame(strDir)
- game = {}
- game.ba = loadFile(strDir.."/ba")
- game.oj = loadFile(strDir.."/oj")
- game.o2 = loadFile(strDir.."/o2")
- game.nw = loadFile(strDir.."/nw")
- game.fl = loadFile(strDir.."/fl")
- game.rooms = {}
- for iRoomNo = 0, 127 do
- local strFile = string.format("%02x", iRoomNo)
- local strPackedRoomData = loadFile(strDir .. "/" ..strFile)
- if strPackedRoomData then
- local strRoomData = depackD4(strPackedRoomData)
- game.rooms[iRoomNo] = strRoomData
- end
- end
- end
- -- 1 Norden, 2 Osten, 4 Süden, 8 Westen gesperrt
- directionflags = {
- [0] =
- "NOSW",
- " OSW",
- "N SW",
- " SW",
- "NO W",
- " O W",
- "N W",
- " W",
- "NOS ",
- " OS ",
- "N S ",
- " S ",
- "NO ",
- " O ",
- "N ",
- " "}
- function getroommatrixcell(iRoomNo, strRoomData)
- local iDir = strRoomData:byte(3 + 0x01e0)
- local iMus = strRoomData:byte(3 + 0x01e1)
- return {
- string.format(" %02x ", iRoomNo),
- string.format (" %02x ", iMus),
- directionflags[iDirFlags] .. " "
- }
- end
- function getroommatrixcell(iRoomNo, strRoomData)
- local iDir = strRoomData:byte(3 + 0x01e0)
- local iMus = strRoomData:byte(3 + 0x01e1)
- local strN = bit.band(iDir, 1)==0 and "+ +" or "+--+"
- local strO = bit.band(iDir, 2)==0 and " " or "|"
- local strS = bit.band(iDir, 4)==0 and "+ +" or "+--+"
- local strW = bit.band(iDir, 8)==0 and " " or "|"
- local strRoom = string.format("%02x", iRoomNo)
- local strMus = string.format("%02x", iMus)
- return {
- strN,
- strW .. strRoom .. strO,
- strW .. strMus .. strO,
- strS
- }
- end
- function printroommatrix()
- local ROWS = 4
- local COLS = 4
- local emptystring=string.rep(" ", COLS)
- for y = 0, 7 do
- local fLine = false
- local lines = {}
- for i=1, ROWS do lines[i] = {} end
- for x = 0, 15 do
- local iRoomNo = 16*y + x
- local strRoomData = game.rooms[iRoomNo]
- if strRoomData then
- local astr = getroommatrixcell(iRoomNo, strRoomData)
- for i=1, ROWS do table.insert(lines[i], astr[i]) end
- fLine = true
- else
- for i=1, ROWS do table.insert(lines[i], emptystring) end
- end
- end
- if fLine then
- for i=1, ROWS do print(table.concat(lines[i])) end
- else
- print()
- end
- end
- end
- if #arg ~= 1 then
- print (strUsage)
- os.exit(1)
- else
- loadgame(arg[1])
- printcommondata()
- print("Räume:")
- printroommatrix()
- -- Räume ausgeben
- for iRoomNo = 0, 127 do
- if game.rooms[iRoomNo] then
- local strRoomData = game.rooms[iRoomNo]
- printroom(iRoomNo, strRoomData)
- end
- end
- end
Code- ==============
- Allgemeindaten
- ==============
- Objekte:
- 00 Torbogen nicht tragbar Gegenstand
- 01 Feuer nicht tragbar Gegenstand
- 02 Späher nicht tragbar Person
- 03 Meer nicht tragbar Gegenstand
- 04 steiniger Weg nicht tragbar Gegenstand
- 05 Plakat tragbar Gegenstand
- 06 Steg nicht tragbar Gegenstand
- 07 Sternenhimmel nicht tragbar Gegenstand
- 08 Schild nicht tragbar Gegenstand
- 09 Tür nicht tragbar Gegenstand
- 0a SCUMM BAR tragbar Gegenstand
- 0b Fieser Pirat tragbar Person
- 0c Düsterer Pirat tragbar Person
- 0d Seltsamer Pirat tragbar Person
- 0e Kronleuchter nicht tragbar Gegenstand
- 0f Piratenhund tragbar Person
- 10 Anstecker tragbar Gegenstand
- 11 VIP-Piraten tragbar Person
- 12 Kamin nicht tragbar Gegenstand
- 13 Küchentür nicht tragbar Gegenstand
- 14 Blauer Pirat tragbar Person
- 15 Grüner Pirat tragbar Person
- 16 Schwarzer Pirat tragbar Person
- 17 Fleisch tragbar Gegenstand
- 18 Topf tragbar Gegenstand
- 19 Fisch tragbar Gegenstand
- 1a Möwe nicht tragbar Gegenstand
- 1b Planke nicht tragbar Gegenstand
- 1c Eintopf nicht tragbar Gegenstand
- 1d Fleischeintopf tragbar Gegenstand
- 1e Fischeintopf tragbar Gegenstand
- 1f Tisch nicht tragbar Gegenstand
- 20 Ofen nicht tragbar Gegenstand
- 21 Koch tragbar Person
- 22 Bürger tragbar Person
- 23 Uhr nicht tragbar Gegenstand
- Gegenstandskarte:
- Raum 01:
- 0 00 Torbogen Sprite
- 1 01 Feuer Sprite
- 2 02 Späher Sprite
- 3 03 Meer Sprite
- Raum 02:
- 0 0b Fieser Pirat Sprite
- 1 0c Düsterer Pirat Sprite
- 2 0d Seltsamer Pirat Sprite
- 3 0e Kronleuchter Sprite
- 4 0f Piratenhund Sprite
- Raum 03:
- 0 11 VIP-Piraten Sprite
- 1 12 Kamin Sprite
- 2 13 Küchentür Sprite
- Raum 04:
- 0 09 Tür Sprite
- 1 1f Tisch Sprite
- 2 20 Ofen Sprite
- Raum 10:
- 0 14 Blauer Pirat Sprite
- 1 15 Grüner Pirat Sprite
- 2 16 Schwarzer Pirat Sprite
- Raum 11:
- 0 04 steiniger Weg Sprite
- 1 05 Plakat Sprite
- 2 06 Steg Sprite
- 3 07 Sternenhimmel Sprite
- Raum 12:
- 0 08 Schild Sprite
- 1 0a SCUMM BAR Sprite
- 2 09 Tür Sprite
- Raum 13:
- 0 22 Bürger Sprite
- 1 00 Torbogen Sprite
- 2 23 Uhr Sprite
- Flags:
- 06 Koch aus Küche
- 07 Tisch 1x unters
- 08 Tisch 2x unters
- 09 Eintopf erstell
- 0a Steg zugänglich
- 0b Möwe erstellt
- 0c Planke erstellt
- 0d Möwe vertrieben
- Allgemeintexte:
- Allgemeinbedingungen:
- Räume:
- + ++--++--++--++--+
- 00 |01||02 03 04|
- 00 |11||31 41 51|
- + ++ ++ ++--++--+
- +--++ ++ ++--+
- 10||11 12 13
- 41||21 71 61
- +--++--++--++--+
- =========
- Raum 00
- =========
- Raumbeschreibung:
- Texte:
- 10
- 20 Tief in der Karibik...
- 30
- 40 ... die Insel Melee Island.
- 50
- 60 "Ich verfluchte nochmals mein Schicksal,
- 11 als ich mich in die Kehle des steinernen
- 21 Affen hinablies. Sind meine Träume vom
- 31 Plündern reicher Galeonen, von Schätzen
- 41 und Abenteuern derart zerplatzt? "Drei
- 51 kleine Prüfungen, dann gehörst du zu
- 61 uns!", haben sie gesagt. Das klang fair.
- 12 Wenn ich nur dieses seltsame Zeug run-
- 22 terkriegen würde, das diese Männer der
- 32 See in sich hineinschütten. Wie konnte
- 42 ich denn ahnen, dass ich eine mächtige
- 52 und schöne Frau treffen würde, mit einem
- 62 Geliebten, der vor lauter Eifersucht
- 13 nicht bemerkt, dass er schon mehrere
- 23 Jahre tot ist? Und jetzt krabble ich
- 33 durch die Eingeweide des steinernen
- 43 Affen, auf der Suche nach einem Mann,
- 53 der drei Zentimeter über dem Boden
- 63 schwebt und jeden Morgen seinen Bart
- 14 anzündet..."
- 24
- 34 (Auszug aus den Memoiren von Guybrush
- 44 Threepwood, "Meine Jahre auf Monkey
- 54 Island")
- 15
- 25 THE SECRET OF MONKEY ISLAND
- 35
- 45
- 55 (C) & (TM) by LUCASFILM GAMES
- 16
- 26 Monkey Island 64 - Demo
- 36
- 46 Programm: D42 - Adventure System
- 56 von Out of Order Softworks
- 17 Grafikkonversion: Project One
- 27 von Resource
- 37
- 47 Musiken: Smalltown Boy (Title Theme) &
- 57 Oedipus (Monkey Madness)
- Bedingungen:
- Bedingung 00
- 00 00 00 00 Bedingung ungültig
- 08 01 Sprung zu Raum 01
- =========
- Raum 01
- =========
- Raumbeschreibung:
- Du betrittst den höchsten Punkt von
- Melee Island, den Platz des Sehers.
- Ein Feuer brennt und wärmt den erfahre-
- nen Wachtposten, der westwärts auf das
- Meer hinaus blickt.
- Im Süden siehst du einen Torbogen, durch
- den du über ca. 351 Stufen zum Hafen
- gehen kannst.
- Texte:
- 10 Ein schöner, steinerner Torbogen. Wenn
- 20 ich durch ihn gehe, könnte ich zum Hafen
- 30 gelangen.^
- 40 Dieses heiß lodernde Feuer wärmt diesen
- 50 Späher dort drüben.^
- 60 Ist der Späher etwa blind?^
- 11 "Hallo! Mein Name ist Guybrush Threep-
- 21 wood und ich will Pirat werden."
- 31 "Huch!", erschreckt sich der Späher.
- 41 "Schleich dich nicht so an mich ran!"
- 51 "Äh... hier stehe ich", korrigierst du
- 61 den Seher, der dich nun anblickt.
- 12 "Nun, Thriftweed" - "Threepwood!" - "Ach
- 22 so. Also du willst Pirat werden, wie? Du
- 32 siehst eher wie ein Buchhalter aus. Aber
- 42 wenn das mit der Piraterie wirklich
- 52 ernst gemeint war, sprich mit den Anfüh-
- 62 rern. Du findest sie unten in der Scumm
- 13 Bar." - "Hey, danke", entgegnest du. Das
- 23 werde ich gleich tun! Ich gehe und suche
- 33 mein Glück!" - "Viel Glück", entgegnet
- 43 der alte Mann.^
- 53 Wow, das Meer. So weit das Auge reicht.
- 63 Zeit, dass ich auf ein Schiff komme.^
- 14 "Äh... wo sind nochmal diese Piraten-
- 24 Anführer?", fragst du erneut den Späher.
- 34 "In der SCUMM BAR", antwortet er dir ge-
- 44 nervt und blickt wieder aufs Wasser.^
- Bedingungen:
- Bedingung 00
- 04 ff ff 00 Untersuche R:Torbogen
- 06 10 Meldung ausgeben Text 0 Zeile 1
- Bedingung 01
- 04 ff ff 01 Untersuche R:Feuer
- 06 40 Meldung ausgeben Text 0 Zeile 4
- Bedingung 02
- 04 ff ff 02 Untersuche R:Späher
- 06 60 Meldung ausgeben Text 0 Zeile 6
- Bedingung 03
- 0a 02 ff 80 Rede mit E:Späher Flag 00 = 1
- 06 14 Meldung ausgeben Text 4 Zeile 1
- Bedingung 04
- 0a ff ff 02 Rede mit R:Späher
- 06 01 Meldung ausgeben Text 1
- 06 02 Meldung ausgeben Text 2
- 06 13 Meldung ausgeben Text 3 Zeile 1
- 04 00 Flag setzen Flag 00
- Bedingung 05
- 04 ff ff 03 Untersuche R:Meer
- 06 53 Meldung ausgeben Text 3 Zeile 5
- =========
- Raum 02
- =========
- Raumbeschreibung:
- Die heillos überfüllte SCUMM BAR hat die
- ganzen verwegenen Gestalten der Karibik
- angelockt. Der Geruch von Grog gemischt
- mit den Körpergerüchen der Haudegen ver-
- mittelt ein seltsames Gefühl.
- Irgendwie kommt es dir auf eigenartige
- Weise so vor, als seist du endlich zu
- Hause angekommen. Südlich geht es an die
- Luft und im Osten tiefer in die SCUMM
- BAR.
- Texte:
- 10 Sieht ganz schön fies aus.^
- 20 Sieht ganz schön düster aus.^
- 30 Sieht ganz schön seltsam aus. Der Pirat
- 40 hat einen Anstecker an seinem schmutzi-
- 50 gen Hemd.^
- 60 Selbst der Hund sieht gefährlich aus.^
- 11 Auf dem Anstecker steht: "Frag mich nach
- 21 Loom (TM)!".^
- 31 Ich sollte mir den Piraten genauer an-
- 41 sehen, bevor ich ihn anspreche.^
- 51 "Grrr", macht der Hund. Du antwortest
- 61 ihm: "Grrr... Wufff". Tolles Gespräch.^
- 12 Nein, ich will jetzt kein Gespräch über
- 22 ein Computerspiel führen, das ohnehin
- 32 nicht für den C64 umgesetzt wurde.^
- 42 Lass dem Piraten besser den Anstecker!^
- 52 Auf dem Kronleuchter rotieren zwei Pira-
- 62 ten wie wild im Kreis. Toll!^
- 13 "Hey, mein Name ist Guybrush Threepwood
- 23 und ich möchte Pirat werden", sprichst
- 33 du den Piraten an. Dieser entgegnet: "Da
- 43 kann ich dir nicht weiterhelfen. Sprich
- 53 mit den schrecklich wichtigen Piraten!".
- Bedingungen:
- Bedingung 00
- 04 ff ff 0b Untersuche R:Fieser Pirat
- 06 10 Meldung ausgeben Text 0 Zeile 1
- Bedingung 01
- 04 ff ff 0c Untersuche R:Düsterer Pirat
- 06 20 Meldung ausgeben Text 0 Zeile 2
- Bedingung 02
- 04 0d ff 82 Untersuche E:Seltsamer Pirat Flag 02 = 1
- 06 30 Meldung ausgeben Text 0 Zeile 3
- Bedingung 03
- 04 ff ff 0d Untersuche R:Seltsamer Pirat
- 06 30 Meldung ausgeben Text 0 Zeile 3
- 0c 10 Gegenstand in Raum Anstecker
- 04 02 Flag setzen Flag 02
- Bedingung 04
- 04 ff ff 0f Untersuche R:Piratenhund
- 06 60 Meldung ausgeben Text 0 Zeile 6
- Bedingung 05
- 0a ff ff 0f Rede mit R:Piratenhund
- 06 51 Meldung ausgeben Text 1 Zeile 5
- Bedingung 06
- 0a 0d ff 82 Rede mit E:Seltsamer Pirat Flag 02 = 1
- 06 12 Meldung ausgeben Text 2 Zeile 1
- Bedingung 07
- 0a ff ff 0d Rede mit R:Seltsamer Pirat
- 06 31 Meldung ausgeben Text 1 Zeile 3
- Bedingung 08
- 04 ff ff 0e Untersuche R:Kronleuchter
- 06 52 Meldung ausgeben Text 2 Zeile 5
- Bedingung 09
- 08 ff ff 10 Nimm R:Anstecker
- 06 42 Meldung ausgeben Text 2 Zeile 4
- Bedingung 0a
- 0a ff ff 0b Rede mit R:Fieser Pirat
- 06 03 Meldung ausgeben Text 3
- Bedingung 0b
- 0a ff ff 0c Rede mit R:Düsterer Pirat
- 06 03 Meldung ausgeben Text 3
- Bedingung 0c
- 04 ff ff 10 Untersuche R:Anstecker
- 06 11 Meldung ausgeben Text 1 Zeile 1
- =========
- Raum 03
- =========
- Raumbeschreibung:
- Hinter einem Vorhang, getrennt vom Rest
- der Schänke, befindet sich der hintere
- Teil der SCUMM BAR.
- Hier ist weniger Rummel.
- Westlich geht es zurück zum prallen
- Piratenleben.
- Im Osten befindet sich eine Tür.
- Texte:
- 10 Drei wohlbeleibte grogtrinkende Piraten.
- 20 Sie sehen schrecklich wichtig aus.^
- 30 Gemütlich.^
- 40 Die Tür hat ein Bullauge. Du kannst eine
- 50 ranzige Küche sehen, Über der Tür ist
- 60 ein Totenkopf gemalt. Zutritt verboten!^
- 11 Du sprichst die schrecklich wichtigen
- 21 Piraten an.
- 31 "Was willst du, Bursche?", entgegnet man
- 41 dir. -"Ich will Pirat werden." -"Na und?
- 51 Warum uns damit belästigen?", will man
- 61 dich abwimmeln. Der dritte Pirat im
- 12 Bunde wirft ein: "Hey, vergesst nicht,
- 22 wegen der LeChuck-Geschichte könnten wir
- 32 etwas Hilfe gebrauchen." Eine Diskussion
- 42 entbrennt: "Wieso?" -"Keine Piraten be-
- 52 deutet keine Beute, keine Beute bedeutet
- 62 keinen Grog und der Grog geht uns lang-
- 13 sam aus...". Schließlich wendet man sich
- 23 wieder an dich: "Hmmm, hast du besondere
- 33 Fähigkeiten?" -"Ich kann zehn Minuten
- 43 die Luft anhalten!", protzt du. "Nun...
- 53 Na gut, aber man wird nicht einfach
- 63 Pirat, weil man danach fragt...
- 14 Du musst durch... DIE DREI PRÜFUNGEN!".^
- 24 "Äh, was sind das für Prüfungen?",
- 34 fragst du die Piraten. Man erklärt dir:
- 44 "Es gibt drei Dinge, die jeder Pirat
- 54 beherrschen muss. Du musst fechten
- 64 lernen...^
- 15 ... die Kunst des Diebstahls anwenden...
- 25 ... und dich auf die Suche begeben."
- 35 -"Die was?" -"Die Schatzsuche, alter
- 45 Dummkopf!" -"Richtig, du musst dich in
- 55 jedem dieser Fachgebiete beweisen und
- 65 uns ein Beweismittel mitbringen. Und
- 16 dann musst du mit uns Grog trinken. GROG
- 26 !!! GROG!!! GROG!!!^
- 36 Verwirrt beschließt du, nach Details zu
- 46 fragen.^
- 56 Gerade kommt der Koch aus der Küche.^
- 66 Der Koch geht wieder in die Küche.^
- 17 Noch befindet sich der Koch im vorderen
- 27 Teil der SCUMM BAR und ist beschäftigt.^
- 37 Als du die Küche betreten willst, kommt
- 47 der Koch dir entgegen. "Verschwinde!".^
- 57 Schnell gehst du durch die offene Tür in
- 67 die Küche.^
- Bedingungen:
- Bedingung 00
- 01 13 ff 86 Öffne E:Küchentür Koch aus Küche = 1
- 06 57 Meldung ausgeben Text 7 Zeile 5
- 08 04 Sprung zu Raum 04
- Bedingung 01
- 3f ff ff 86 Koch aus Küche = 1
- 06 66 Meldung ausgeben Text 6 Zeile 6
- 05 06 Flag löschen Koch aus Küche
- 03 21 Löschen aus Raum Koch
- Bedingung 02
- 04 ff ff 11 Untersuche R:VIP-Piraten
- 06 10 Meldung ausgeben Text 0 Zeile 1
- Bedingung 03
- 0a 11 ff 84 Rede mit E:VIP-Piraten Flag 04 = 1
- 06 36 Meldung ausgeben Text 6 Zeile 3
- 04 05 Flag setzen Flag 05
- 08 10 Sprung zu Raum 10
- Bedingung 04
- 0a 11 ff 83 Rede mit E:VIP-Piraten Flag 03 = 1
- 06 24 Meldung ausgeben Text 4 Zeile 2
- 06 05 Meldung ausgeben Text 5
- 06 16 Meldung ausgeben Text 6 Zeile 1
- 04 04 Flag setzen Flag 04
- Bedingung 05
- 0a ff ff 11 Rede mit R:VIP-Piraten
- 06 01 Meldung ausgeben Text 1
- 06 02 Meldung ausgeben Text 2
- 06 03 Meldung ausgeben Text 3
- 06 14 Meldung ausgeben Text 4 Zeile 1
- 04 03 Flag setzen Flag 03
- Bedingung 06
- 04 ff ff 12 Untersuche R:Kamin
- 06 30 Meldung ausgeben Text 0 Zeile 3
- Bedingung 07
- 04 13 ff 86 Untersuche E:Küchentür Koch aus Küche = 1
- 06 40 Meldung ausgeben Text 0 Zeile 4
- Bedingung 08
- 04 ff ff 13 Untersuche R:Küchentür
- 06 40 Meldung ausgeben Text 0 Zeile 4
- 06 56 Meldung ausgeben Text 6 Zeile 5
- 04 06 Flag setzen Koch aus Küche
- 0c 21 Gegenstand in Raum Koch
- Bedingung 09
- 04 ff ff 21 Untersuche R:Koch
- 06 17 Meldung ausgeben Text 7 Zeile 1
- Bedingung 0a
- 01 ff ff 13 Öffne R:Küchentür
- 06 37 Meldung ausgeben Text 7 Zeile 3
- Bedingung 0b
- 0c ff ff c6 Osten Koch aus Küche = 0
- 06 37 Meldung ausgeben Text 7 Zeile 3
- =========
- Raum 04
- =========
- Raumbeschreibung:
- Unbemerkt betrittst du die Küche der
- SCUMM BAR. Ein offensichtlich heiliger
- Raum. Zumindest herrscht hier ziemliche
- Unordnung.
- Echte Piraten stören sich nicht an
- diesen Zuständen.
- Eine Tür im Osten weist den Weg zu einem
- Steg. Im Westen geht es zurück zu den
- Schankräumen.
- Texte:
- 10 Auf dem Tisch liegt ein Stück rohes
- 20 Fleisch.^
- 30 Unter dem Tisch liegt ein Topf.^
- 40 Ein schmutziger Tisch. Sonst nichts.^
- 50 Heiß... Dort köchelt ein Eintopf.^
- 11 Ein Eintopf ohne besondere Zutaten.^
- 21 Aua... Der Topf ist viel zu heiß.^
- 31 Du öffnest die östliche Tür zum Steg.^
- 41 Nochmal?^
- 51 Da liegt ein Fisch auf dem Steg.^
- 61 Die Möwe knabbert am Fisch.^
- 12 Am äußeren Ende des Stegs scheint eine
- 22 Planke lose zu sein.^
- 32 Die Möwe hat den Fisch in Beschlag ge-
- 42 nommen. Sie würde dir die Finger zer-
- 52 hacken.^
- 62 Schnell nimmst du den Fisch an dich.^
- 13 Mit voller Kraft trittst du auf die lose
- 23 Planke. Die Möwe, die am anderen Ende
- 33 der Planke sitzt, schreckt auf und
- 43 flattert in die Lüfte.^
- 53 Die Möwe kehrt zum Fisch zurück.^
- 63 Aua, ist dieser Eintopf heiß.^
- 14 Du wirfst das Fleisch in den Eintopf.^
- 24 Du wirfst den Fisch in den Eintopf.^
- Bedingungen:
- Bedingung 00
- 08 19 ff 8d Nimm E:Fisch Möwe vertrieben = 1
- 06 62 Meldung ausgeben Text 2 Zeile 6
- 03 19 Löschen aus Raum Fisch
- 01 19 Gegenstand in Besitz Fisch
- 03 1a Löschen aus Raum Möwe
- 03 1b Löschen aus Raum Planke
- 05 0d Flag löschen Möwe vertrieben
- Bedingung 01
- 3f ff ff 8d Möwe vertrieben = 1
- 06 53 Meldung ausgeben Text 3 Zeile 5
- 05 0d Flag löschen Möwe vertrieben
- Bedingung 02
- 04 1f ff 88 Untersuche E:Tisch Tisch 2x unters = 1
- 06 40 Meldung ausgeben Text 0 Zeile 4
- Bedingung 03
- 04 1f ff 87 Untersuche E:Tisch Tisch 1x unters = 1
- 06 30 Meldung ausgeben Text 0 Zeile 3
- 04 08 Flag setzen Tisch 2x unters
- 0c 18 Gegenstand in Raum Topf
- Bedingung 04
- 04 ff ff 1f Untersuche R:Tisch
- 06 10 Meldung ausgeben Text 0 Zeile 1
- 04 07 Flag setzen Tisch 1x unters
- 0c 17 Gegenstand in Raum Fleisch
- Bedingung 05
- 04 89 ff 20 Untersuche R:Ofen Eintopf erstell = 1
- 06 50 Meldung ausgeben Text 0 Zeile 5
- Bedingung 06
- 04 ff ff 20 Untersuche R:Ofen
- 06 50 Meldung ausgeben Text 0 Zeile 5
- 04 09 Flag setzen Eintopf erstell
- 0c 1c Gegenstand in Raum Eintopf
- Bedingung 07
- 04 ff ff 1c Untersuche R:Eintopf
- 06 11 Meldung ausgeben Text 1 Zeile 1
- Bedingung 08
- 08 ff ff 1c Nimm R:Eintopf
- 06 21 Meldung ausgeben Text 1 Zeile 2
- Bedingung 09
- 01 ff ff 09 Öffne R:Tür
- 06 31 Meldung ausgeben Text 1 Zeile 3
- 04 0a Flag setzen Steg zugänglich
- 0c 06 Gegenstand in Raum Steg
- 03 09 Löschen aus Raum Tür
- Bedingung 0a
- 04 06 ff 8c Untersuche E:Steg Planke erstellt = 1
- 06 51 Meldung ausgeben Text 1 Zeile 5
- 06 61 Meldung ausgeben Text 1 Zeile 6
- 06 12 Meldung ausgeben Text 2 Zeile 1
- Bedingung 0b
- 04 06 ff 8b Untersuche E:Steg Möwe erstellt = 1
- 06 51 Meldung ausgeben Text 1 Zeile 5
- 06 61 Meldung ausgeben Text 1 Zeile 6
- 06 12 Meldung ausgeben Text 2 Zeile 1
- 03 06 Löschen aus Raum Steg
- 04 0c Flag setzen Planke erstellt
- 0c 1b Gegenstand in Raum Planke
- Bedingung 0c
- 04 06 ff 8a Untersuche E:Steg Steg zugänglich = 1
- 06 51 Meldung ausgeben Text 1 Zeile 5
- 0c 19 Gegenstand in Raum Fisch
- 04 0b Flag setzen Möwe erstellt
- 0c 1a Gegenstand in Raum Möwe
- Bedingung 0d
- 04 ff ff 1a Untersuche R:Möwe
- 06 61 Meldung ausgeben Text 1 Zeile 6
- Bedingung 0e
- 08 ff ff 19 Nimm R:Fisch
- 06 32 Meldung ausgeben Text 2 Zeile 3
- Bedingung 0f
- 04 ff ff 1b Untersuche R:Planke
- 06 12 Meldung ausgeben Text 2 Zeile 1
- Bedingung 10
- 02 ff ff 1b Verschiebe R:Planke
- 06 13 Meldung ausgeben Text 3 Zeile 1
- 04 0d Flag setzen Möwe vertrieben
- Bedingung 11
- 06 ff 17 1c Kombiniere B:Fleisch R:Eintopf
- 02 17 Löschen aus Besitz Fleisch
- 03 1c Löschen aus Raum Eintopf
- 0c 1d Gegenstand in Raum Fleischeintopf
- 06 14 Meldung ausgeben Text 4 Zeile 1
- Bedingung 12
- 08 ff ff 1d Nimm R:Fleischeintopf
- 06 63 Meldung ausgeben Text 3 Zeile 6
- 03 1d Löschen aus Raum Fleischeintopf
- 01 1d Gegenstand in Besitz Fleischeintopf
- 0c 1c Gegenstand in Raum Eintopf
- Bedingung 13
- 06 ff 19 1c Kombiniere B:Fisch R:Eintopf
- 02 19 Löschen aus Besitz Fisch
- 03 1c Löschen aus Raum Eintopf
- 0c 1e Gegenstand in Raum Fischeintopf
- 06 24 Meldung ausgeben Text 4 Zeile 2
- Bedingung 14
- 08 ff ff 1e Nimm R:Fischeintopf
- 06 63 Meldung ausgeben Text 3 Zeile 6
- 03 1e Löschen aus Raum Fischeintopf
- 01 1e Gegenstand in Besitz Fischeintopf
- 0c 1c Gegenstand in Raum Eintopf
- =========
- Raum 10
- =========
- Raumbeschreibung:
- Du beschließt, noch mehr über die drei
- Prüfungen herauszufinden und sprichst
- die drei schrecklich wichtigen Piraten
- erneut an.
- Durch eine winzige Bewegung nach Westen
- kannst du dich wieder ein wenig von
- diesen furchteinflößenden Piraten
- entfernen.
- Texte:
- 10 "Erzähl mir mehr über die Fechterei".
- 20 Der blaue Pirat erklärt: "Zuerst
- 30 brauchst du ein Schwert. Dann musst du
- 40 den Schwertmeister finden und besiegen.
- 50 Jemand in der Stadt wird dir den Weg
- 60 zeigen können. Oh. Du solltest vorher
- 11 mit jemandem trainieren." "Haha!", lacht
- 21 der Pirat in schwarz. "Stell dir vor,
- 31 ohne Training gegen den Schwertmeister
- 41 anzutreten!". Die schrecklich wichtigen
- 51 Piraten lachen lauthals: "Har Har Har
- 61 Har Har!".
- 12 "Erzähl mir mehr über die Kunst des
- 22 Diebstahls", bittest du den anderen Pi-
- 32 raten. Dieser entgegnet: "Ich hätte
- 42 gerne, dass du uns eine Kleinigkeit be-
- 52 schaffst. Das Idol der Vielen Hände, das
- 62 am Sitz des Gouverneurs versteckt ist!".
- 13 Der Pirat in schwarz ergänzt: "Die Gou-
- 23 verneurin hat das Idol der Vielen Hände
- 33 in ihrem Landsitz. Natürlich musst du
- 43 zuerst an den Wachen vorbei. Am kniff-
- 53 ligsten ist es wohl, die Hunde draußen
- 63 zu überlisten. Die sind ziemlich bissig.
- 14 Man sollte sie irgendwie betäuben."^
- 24 "Erzähl mir mehr über die Schatzsuche",
- 34 bittest du schließlich den Piraten in
- 44 schwarz. "Die Legenden sagen, dass ein
- 54 Schatz auf dieser Insel vergraben ist.^
- 64 "Ich geh dann mal wieder."^
- 15 Du musst lediglich den Verlorenen Schatz
- 25 von Melee Island (TM) finden und hierher
- 35 bringen."
- 45 "Brauche ich dazu eine Karte oder
- 55 sowas?", fragst du die Piraten.
- 65 "Du wirst wohl nicht annehmen, den
- 16 Schatz einfach so zu finden?", entgegnet
- 26 man dir. Ein anderer der VIP-Piraten er-
- 36 gänzt: "Und nicht vergessen: Ein X mar-
- 46 kiert die Stelle!".^
- 56 "Har Har Har Har", lachen die drei
- 66 schrecklich wichtigen Piraten.^
- Bedingungen:
- Bedingung 00
- 0e ff ff ff Westen
- 06 64 Meldung ausgeben Text 4 Zeile 6
- 08 03 Sprung zu Raum 03
- Bedingung 01
- 0a ff ff 14 Rede mit R:Blauer Pirat
- 06 00 Meldung ausgeben Text 0
- 06 01 Meldung ausgeben Text 1
- Bedingung 02
- 0a ff ff 15 Rede mit R:Grüner Pirat
- 06 02 Meldung ausgeben Text 2
- 06 03 Meldung ausgeben Text 3
- 06 14 Meldung ausgeben Text 4 Zeile 1
- Bedingung 03
- 0a ff ff 16 Rede mit R:Schwarzer Pirat
- 06 24 Meldung ausgeben Text 4 Zeile 2
- 06 05 Meldung ausgeben Text 5
- 06 16 Meldung ausgeben Text 6 Zeile 1
- 06 56 Meldung ausgeben Text 6 Zeile 5
- =========
- Raum 11
- =========
- Raumbeschreibung:
- Du bist an dem kleinen Hafen von Melee
- Island angekommen.
- Meer soweit das Auge reicht.
- Nördlich kannst du zum Seher zurück-
- kehren.
- Östlich gelangst du über einen Steg
- weiter in Richtung Zentrum der Insel.
- Texte:
- 10 Wow, diesen gefährlichen Weg bin ich vom
- 20 Seher hier hinunter gelaufen. In nur
- 30 fünf Stunden. Reife Leistung. Ohne Not
- 40 will ich den nicht auch noch hoch lauf-
- 50 en.^
- 60 Ganz schön wackelig.^
- 11 An einem kleinen Dockhaus wurde ein Pla-
- 21 kat angebracht. "Wählen Sie Gouverneurin
- 31 Marley: Es gibt nur einen Kandidaten,
- 41 also fällt die Wahl nicht schwer!".^
- 51 Die Wahlkämpfer haben nicht mit Kleber
- 61 gegeizt. Das Plakat bleibt am Haus.^
- 12 Wirklich Überwältigend dieser Anblick.^
- Bedingungen:
- Bedingung 00
- 04 ff ff 04 Untersuche R:steiniger Weg
- 06 10 Meldung ausgeben Text 0 Zeile 1
- Bedingung 01
- 04 ff ff 05 Untersuche R:Plakat
- 06 11 Meldung ausgeben Text 1 Zeile 1
- Bedingung 02
- 08 ff ff 05 Nimm R:Plakat
- 06 51 Meldung ausgeben Text 1 Zeile 5
- Bedingung 03
- 04 06 ff ff Untersuche E:Steg
- 06 60 Meldung ausgeben Text 0 Zeile 6
- Bedingung 04
- 04 ff ff 07 Untersuche R:Sternenhimmel
- 06 12 Meldung ausgeben Text 2 Zeile 1
- =========
- Raum 12
- =========
- Raumbeschreibung:
- Du näherst dich dem Zentrum der Insel,
- dem größten Ort von Melee Island. Direkt
- und ganz nahe am Wasser gebaut wurde
- eine Bar, die ungemein einladend
- aussieht.
- Nördlich könntest du sie betreten.
- Westlich geht es zum Steg, östlich
- tiefer in die Stadt.
- Texte:
- 10 "SCUMM BAR" steht dort auf einem ver-
- 20 witterten Holzschild. Welch wohlklingen-
- 30 der Name.^
- 40 Die Tür zur Bar.^
- 50 Hell beleuchtet steht sie dort, direkt
- 60 am Meer. Die SCUMM BAR.^
- 11 Aber die ist bereits offen, die Tür!^
- 21 Mit leicht zittrigen Händen öffnest du
- 31 die Tür zur SCUMM BAR.^
- 41 Glaub es oder nicht, es gibt eine Tür.^
- 12 Voller Elan betrittst du die SCUMM BAR,
- 22 um doch nur gegen die geschlossene Tür
- 32 zu laufen. Was ein Pirat alles selber
- 42 machen muss...^
- Bedingungen:
- Bedingung 00
- 04 ff ff 08 Untersuche R:Schild
- 06 10 Meldung ausgeben Text 0 Zeile 1
- Bedingung 01
- 04 ff ff 09 Untersuche R:Tür
- 06 40 Meldung ausgeben Text 0 Zeile 4
- Bedingung 02
- 04 ff ff 0a Untersuche R:SCUMM BAR
- 06 50 Meldung ausgeben Text 0 Zeile 5
- Bedingung 03
- 01 09 ff 81 Öffne E:Tür Flag 01 = 1
- 06 11 Meldung ausgeben Text 1 Zeile 1
- Bedingung 04
- 01 ff ff 09 Öffne R:Tür
- 06 21 Meldung ausgeben Text 1 Zeile 2
- 04 01 Flag setzen Flag 01
- Bedingung 05
- 01 ff ff 0a Öffne R:SCUMM BAR
- 06 41 Meldung ausgeben Text 1 Zeile 4
- Bedingung 06
- 0b ff ff c1 Norden Flag 01 = 0
- 06 12 Meldung ausgeben Text 2 Zeile 1
- =========
- Raum 13
- =========
- Raumbeschreibung:
- Du betrittst die größte Stadt auf Melee
- Island.
- Durch einen großen Torbogen im Westen
- kannst du in Richtung der SCUMM BAR
- gehen.
- Im Osten geht es weiter in Richtung
- Stadtzentrum.
- Texte:
- 10 Schreibst du die Vollversion?^
- 11 Der Bürger von Melee Island sieht mit
- 21 seinem Trenchcoat und dem ständigen Um-
- 31 drehen nach Links und Rechts sehr unauf-
- 41 fällig aus.
- 12 Dankbar entreißt er dir Topf und
- 22 schlingt den Inhalt hastig hinunter.
- 32 Dann besieht er dich genauer:
- 42 "Entschuldigen Sie, haben Sie einen Vet-
- 52 ter namens Sven...?"
- 13 Was, schon so spät und ich bin immer
- 23 noch nicht Pirat!
- 14 Wirklich sehr schön.
- 15 Immer noch hastig in Bewegung, kommt er
- 25 dir zuvor und fragt nervös:
- 35 "Sagen Sie mal, junger Freund, hätten
- 45 Sie vielleicht einen kleinen Snack für
- 55 mich?"
- 16 "Das ist nett gemeint, guter Junge, aber
- 26 als Pesco-Vegetarier muss ich dies
- 36 leider streng ablehnen!"
- 46 Sein Magen gibt ein beeindruckend lautes
- 56 Grummeln von sich.
- Bedingungen:
- Bedingung 00
- 0c ff ff ff Osten
- 06 10 Meldung ausgeben Text 0 Zeile 1
- Bedingung 01
- 04 ff ff 22 Untersuche R:Bürger
- 06 01 Meldung ausgeben Text 1
- Bedingung 02
- 0a ff ff 22 Rede mit R:Bürger
- 06 05 Meldung ausgeben Text 5
- Bedingung 03
- 04 ff ff 23 Untersuche R:Uhr
- 06 03 Meldung ausgeben Text 3
- Bedingung 04
- 04 ff ff 00 Untersuche R:Torbogen
- 06 04 Meldung ausgeben Text 4
- Bedingung 05
- 07 ff 1d ff Gib B:Fleischeintopf
- 06 06 Meldung ausgeben Text 6
- Bedingung 06
- 07 ff 1e ff Gib B:Fischeintopf
- 06 02 Meldung ausgeben Text 2
- 0a 00 Endsequenz
Es wäre also evtl. nicht zu abwägig die "Game-Engine", so gut wie möglich bzw. es die eigenen Fähigkeiten hergeben, nachzuprogrammieren.
Alternativ könnte ein Cracker vielleicht den Einsprungspunkt zum Anzeigen einer Raumgrafik finden und auf eine eigene Routine umleiten, welche den benötigten Speicher auslagert/rettet und ein Bild in einem besseren Format nachlädt und anzeigt. ( He-Man1982 hattest Du ja bereits vorgeschlagen. Die Kommentare im Skript könnten jemanden diesen Vorgang erleichtern. Schwierig würde ich mir die Nutzung der vorhandenen Loader-Routinen vorstellen...)
----
Die Nachprogrammierung würde ich bevorzugen, wenn man alles auf einem einfachen/primitiven Niveau belässt.
Die Linie würde ich folgendermaßen ziehen:
Die Daten aus dem D42-System dürfen nicht verändert oder ergänzt werden, d.h. die neue "Game-Engine" würde/müsste auch mit allen anderen bereits erstellten/zukünftigen Adventures arbeiten können. Bolzgramm
Die neuen Bilder würden einfach am Dateinamen (bspw. Prefix + Raumnummer o.ä.) erkennbar/auffindbar sein.
Die Verbesserungen könnten im Detail sein:
- Oben die Grafik in 160x144 MC anzeigen
-- In dieser Vorstellungen sprechen viele Gründe diesmal für MC. (*)
- Die Bedienung unten in Hires und Proportionalfont, wie im Original-Scumm-UI.
-- Links die Verben; mitte bzw. rechts die Inventargegenstände; weiter rechts die Gegenstände im Raum.
-- Die Funktion in die Richtungen zu gehen würde ich in den Rändern der angezeigten Grafik verstecken. (Hier könnte es sein, dass bei einigen Adventures die Logik nicht mehr stimmt, wenn unten im Bild nicht mehr Süden ist o.ä..,)
-- Das Hervorheben mit Farben beim "Mouseover" würde ich auch mit Sprites machen, d.h. die Schrift müsste also nicht auf einer durch 8 teilbaren Y-Koordinate liegen. (Die Ausgabe erfolgt invertiert und lässt ein Sprite beim "mouseover" durchscheinen.)
- Die Texte (Raumbeschreibung/Antworten) würde ich auf der Grafik anzeigen.
-- Hierzu würden die verbleibenden 7 Sprites genutzt werden, d.h. die Schrift wäre in Hires lesbar. Die Farben der Bitmap an den Stellen, an der Zeichen dargestellt werden, könnten einfach auf Schwarz gesetzt werden. Dadurch müsste man die Bitmap nicht retten, sondern nur Screen und Colorram + die Lesbarkeit wäre besser als bei einfachen einfarbigen Chars über einer MC-Bitmap. Leider ergeben 7 Sprites nur 168 Pixel Fläche.
- Sprites für Gegenstände würde ich nicht anzeigen, sondern auch als Bitmaps nachladen (bspw. Prefix + Raumnummer + Objektnummer)
-- (*) Der Grund ist einfach der, dass keine Sprites mehr übrig sind, wenn Text über der Grafik angezeigt wird bzw. das zu kompliziert werden würde. Tobias
Was meinerseits unklar ist bzw. wo ich selbst Schwierigkeiten bei einer "Umsetzung" (Proof-Of-Concept ;)) hätte:
- Die Loader-Routinen (Beim Laden würde ich den Bildschirm ausschalten und den Kernal einsetzen, statt einen IRQ-Loader zu nutzen.)
- Musik würde ich auch erstmal nicht einsetzen, weil diese 1.) ja auch beim Laden unterbrochen werden würde und 2.) weil ich noch nicht weiß in welcher Datei die Musik gespeichert ist. (Die SongNr. wird bei den Räumen gespeichert.)
- Evtl. hätte ich Schwierigkeiten beim "originalgetreuen" Textumbruch der Nachrichten o.ä..
- Ob die Endsequenzen eine spezielle Behandlung benötigen oder einfach aufgerufen und ausgeführt werden können, weiß ich nicht.
...Ansonsten scheint alles recht überschaubar, soweit man sich das DT100-Adventure anschaut, weil hier
1.) Allgemeinbedingungen und -Texte nicht verwendet werden und
2.) die O2-Datei nicht benötigt wird, weil max. 56 Objekte verwendet werden und
3.) es werden keine Sprites verwendet.Und das könnte auch ein erstes Ziel sein, dieses "einfache" Adventure umzusetzen. Sobald es geschehen ist, könnte ein Grafiker die 8 Bilder nachbearbeiten.
(... soviel zur Vorstelllung/Idee ...)
Was sind eure Gedanken dazu?
===================================
Zurück zum Topic:
- Für die Konvertierungsschritte am PC gibt es für die Schneideoperationen Programme mit einer Batch Funktion. Für die Konvertierung nach MC nutze ich bspw. BMP2MC V2.12F von Seanser oder online mcdraw.xyz
-- Tobias Welches Tool nutzt Du im letzten Schritt für die Konvertierung nach Multicolor? (Evtl. gibt es ein gutes für die Kommandozeile? Dann wäre es möglich 100 Bilder unkompliziert auf einen Schlag zu konvertieren.)
- Bolzgramm Wieviele Objekte und Räume verwendest Du? Passt alles auf eine Diskette? Benutzt Du Allgemeinbedingungen/Texte ? -
Unabhängig vom D42:
Ich denke, dass es nur zwei Arten gibt, die Grafik umzusetzen:
a.) Erstellung neuer Grafiken, die sich an den Fähigkeiten/Stärken/Schwächen des C64 orientieren
oder
b.) Reduktion der Qualität der Originalgrafik (CGA oder EGA), so dass der C64 sie darstellen kann.
---
Zu a.)
Es würden wahrscheinlich Änderungen im Spieldesign notwendig werden. (Ich kenne MI nicht gut genug, aber ich kann mir vorstellen, dass bspw. bei der Nutzung von Sprites bestimmte Animationen oder Abläufe aufgrund der Farbzahl, Breite, Auflösung etc. nicht möglich sind/wären...)
Ein mögliches, m.M.n. sehr hübsches, optimales Ergebnis wäre (von veto?):
Quelle: https://www.deviantart.com/oli…sland-64-mockup-672903297
(((Natürlich müsste man wahrscheinlich den Spieler anders umsetzen...)))Zu b.)
Würde man die CGA-Version als Vorlage wählen, würden sich m.M.n. Softwaresprites und Schwarz-Weiß-Hires oder Extended-Hires anbieten.
Original PC-CGA:
C64-Hires:C64-Extended-Hires: (Hier könnten nat. auch Clashes vorkommen.)
Würde man die EGA-Version als Vorlage nehmen, könnte man darüber nachdenken, den MC-Bitmap-Modus mit doppelt hohen Pixeln zu nutzen und den Bildschirm anders aufzuteilen, anstatt die Grafik einfach zu quetschen.
C64-MC-Bitmap: (Auch hier mögliche Clashes bei dem Spieler, aber m.M.n. das insgesamt hübschere Ergebnis)---
Man könnte in allen Fällen darüber nachdenken, ob man Scrolling überhaupt umsetzen möchte/muss.
Ich denke auch, dass man für einen "Proof-of-Concept" (neues Lieblingswort) keine ScummVM und auch nicht die Original Skripte und Dateien von MI auf dem C64 lauffähig machen muss, weil das einfach zu aufwendig wäre.
Orientiert man sich an der Demo von Monkey Island, glaube ich schon, dass sie auf dem C64 auf die ein oder andere Art umsetzbar ist.
Link zur Demoversion:
https://archive.org/details/TheSecretOfMonkeyIslandDemo (online)
https://legendofmi.com/downloads/demos/ (download)
--------------------
Nachfolgend noch einige Links zur Technik von ScummVM und zu den Dateiformaten, auf die ich kam, weil ich nach einer Möglichkeit gesucht habe, die CGA oder EGA-Grafiken aus der Demo zu extrahieren.
Technische Links mit Hintergrundinfos:
https://wiki.scummvm.org/index…SCUMM/Technical_Reference
https://wiki.scummvm.org/index…ference/Costume_resources
https://github.com/AlbanBedel/scummc/wiki (Interessante Unterseiten über das Seitenmenü!)
http://jsg.id.au/scumm/scummrev/articles/image.html
https://robertodip.com/blog/scumm-internals-syntax/
https://web.archive.org/web/20…CUMM%20Tutorial%200.1.pdf
Hinweise zu Editoren und Tools zum Extrahieren:
https://forums.scummvm.org/viewtopic.php?t=13947
https://scummeditor.scummbr.com/
http://www.jestarjokin.net/apps/
http://lebostein.de/tomysoft/scumm/
https://quickandeasysoftware.net/software/scumm-16
Grafiklinks:
https://www.spriters-resource.com/pc_computer/secretofmonkeyisland/ (VGA)
https://legendofmi.com/characters/mi1/ega/ (zum Vergleichen EGA/VGA)
---
Interessantester Link zum Schluss, weil man hier auch einige Tools in Aktion sieht (siehe Screenshots):
https://www.youtube.com/watch?v=ikaqus5_QIg&t=10661s (Video: "The Secrets of Monkey Island - An Evening With Ron Gilbert") -
Es existiert ein externer Forumsthread, in dem es um die Optimierung von Zarch auf dem Acorn geht.
Ein Benutzer mit dem Namen "sirbod" (Jon Abbott) hat im folgenden verlinkten und zitierten Post die im Spiel gezeichneten Dreiecke analysiert: https://stardot.org.uk/forums/viewtopic.php?p=124254#p12425I've now have a test suite, which plays back a recording of all the triangles Zarch plots over the first two demo levels. Triangle stats from that are as follows:
Total triangles recorded: 16380
Widest triangle: 56 pixels
Average triangle width: 18 pixels
Graph showing totals of triangle widths over the recording:As I suspected, the bulk of the triangles are small, so we only need hand-crafted fills for the smaller range. Anything over 40 can be covered by a generic line fill.
Breaking these triangles down into their line fill length counts highlights where we need to optimize the fill routine:The bulk of the line fills are under 4 pixels, the longest is 53 pixels, above 43 pixels its in single digits. Based on these figures, we only need to optimize the line fill up to 32 pixels (so 128 routines including start alignment) and leave the rest to a generic routine.
Sein Fazit ist, dass in Zarch auf dem Acorn nur kleine Dreiecke bis max. 53 Pixel gezeichnet werden und dass die Zeichenroutinen daraufhin optimiert werden können.
Der Thread ist allgemein sehr interessant.
(...)
Zurück zum C64:
- Die Idee für den C64 wäre also auch, dass man sich nur auf das Zeichnen von kleinen Polygonen beschränkt und bspw. die Außenlinien nicht mit Bresenham ermittelt, sondern eine Divisonstabelle (bspw. 64*64) nutzt.
- Da die Bildschirmkoordinaten im Multicolor-Bitmapmodus in je 8-Bit passen, können zum größten Teil auch alle Berechnungen in 8-Bit erfolgen.Anbei ein kleiner Grafik- bzw. Geschwindigkeitstest bzgl. dem Zeichnen der Landschaft/Polygone.
- Die Fläche besteht aus 8x8 Punkten, d.h. 7x7 Flächen. Das Level aus 64x64 Werten.
- Die Punkte werden nicht aus dem Level ermittelt, d.h. es fehlt eine Berechnung von 3d-Koordinaten nach 2d und auch ein Softscrolling u.ä..
- Hier ging es mir nur um die Geschwindigkeit der Zeichenroutine für die Polygone.
-- Die Polygone werden in jedem Frame vollständig neu aus den 2d-Punkten berechnet und gezeichnet. Eine Füllung mit Bitmustern ist möglich. Es wird die oben erwähnte Divisionstabelle genutzt.
-- Das Wichtigste: Die Routinen sind ansonsten überhaupt nicht optimiert, d.h. sehr durchschnittlich und es gibt sehr viel Luft nach oben!
--- Ich gehe davon aus, dass eine "Spiellogik" die möglichen Optimierungen wieder relativieren würde, aber dennoch könnte man mit Sicherheit auch die Anforderungen einwenig/marginal herabsetzen. Bspw. könnte man die vertikale Auflösung (nicht die Bitmuster!) halbieren o.ä..
Hier das Testprogramm: testzarch6.prg -
Die Formeln lauten:Kurzes test.yab mit 4 Punkten:
Code- open window 320,200
- # Breite und Hoehe
- sw = 320
- sh = 200
- # Punktdefinitionen in 3d
- ax = -50
- ay = -50
- az = 2
- bx = 50
- by = -50
- bz = 2
- cx = 50
- cy = 50
- cz = 2
- dx = -50
- dy = 50
- dz = 2
- # Winkel für Projektion
- a = 26.565
- c = 0.8944 // cos(a) Bspw. Angaben in Grad (DEG)
- s = 0.4472 // sin(a)
- # Umrechnung in 2d
- x1 = (sw / 2) + (ax + az) * c
- y1 = (sh / 2) + (-ax + az) * s + ay
- x2 = (sw / 2) + (bx + bz) * c
- y2 = (sh / 2) + (-bx + bz) * s + by
- x3 = (sw / 2) + (cx + cz) * c
- y3 = (sh / 2) + (-cx + cz) * s + cy
- x4 = (sw / 2) + (dx + dz) * c
- y4 = (sh / 2) + (-dx + dz) * s + dy
- # Zeichnen
- line x1, y1, x2, y2
- line x2, y2, x3, y3
- line x3, y3, x4, y4
- line x4, y4, x1, y1
- clear screen
- inkey$
- close window
Quellen/Links:
http://www.gandraxa.com/isometric_projection.xml (kein https!)
https://observablehq.com/@kell…vascript-and-html5-canvas -
TD1334
Ich bin sehr beeindruckt, d.h. die Geschwindigkeit ist gut und ich glaube auch nicht, dass es noch wesentlich schneller gehen würde.
Kannst Du etwas zu der Umsetzung sagen: $190 Bytes sind ja nicht viel.
- Wie hast Du die Rotation umgesetzt? Werden überhaupt Tabellen eingesetzt bzw. wie hoch ist der benötigte Speicher während der Ausführung (auch ZP)?
- Beim Scrolling nehme ich an, dass Du nur die unterste Zeile aktualisierst. Soweit sieht das Ergebnis gut aus.
- Sind aus Deiner Sicht Verbesserungen möglich?