Stefan hat zurecht bemaengelt dass KARTE.PCC/KELLOGGS.PCC verzerrt/verrutscht
aussehen (Smacks-Frosch an falscher Position, Notch-Fehlstelle im Logo-Rahmen).
Root Cause: Der Decoder hat RLE-Runs am Ende jeder Bildzeile hart abgeschnitten
und den Rest verworfen (klassisches PCX-Verhalten angenommen). Dieses Format
haelt sich aber NICHT an die PCX-Konvention 'ein Run ueberschreitet nie eine
Zeile' -- Runs laufen frei ueber Zeilengrenzen. Verifiziert per Pixel-fuer-Pixel-
Vergleich gegen echten DOSBox-Screenshot (world map): mit durchgehender
Dekodierung (kein Row-Reset) ist das Ergebnis jetzt pixel-identisch zur Referenz.
- tools/pcc_to_png.py: Row-Reset entfernt, decodiert jetzt width*height Pixel
am Stueck aus dem RLE-Strom
- png_out/: alle 77 PNGs mit dem Fix neu generiert
- tools/wip_bob_sprite_research/: Backup der laufenden (noch ungeloesten)
BOB-Sprite-Format-Exploration von aria-wohnung, damit nichts bei einem
VM-Neustart verloren geht
- NOTES.md: Root-Cause-Analyse dokumentiert, alte Fehldiagnose ('byte-identisch
zwischen Row-Reset und kontinuierlich') korrigiert, Rauser-Intro-Frage
beantwortet (3 Frames vorhanden, Text-Logo, keine Video-Datei)
30 KiB
Kellogg's Tony and Friends — Remake-Projekt, Analyse-Notizen
Ziel
Plattformunabhängiges Remake (Python) von "Kellogg's Tony and Friends" (DOS, 1994), lauffähig auf x64 ohne DOS/QEMU. Ursprung: Spiel crasht in unserer FreeDOS-VM (RTM.EXE-Engine vs. QEMU-VGA-Emulation, siehe Projekt "Classic Games" für den Debug-Marathon dazu) — daher der Wunsch für ein eigenes Remake.
Quelldateien (aus VM-Disk dos_shareware extrahiert, liegen in raw/)
-
RTM.EXE— die eigentliche Spiel-Engine (Runtime), DOS-EXE (MZ-Header), 108 KB. -
START.EXE/SETUP.EXE— Launcher/Konfigurationsprogramme. -
KELLOGG.INI— Soundkarten-Konfig (IRQ/DMA), irrelevant fürs Remake. -
PCKELL.DAT— 2,69 MB, unkomprimiert. Beginnt mit einer monoton steigenden 16-Bit-LE-Offset-Tabelle (vermutlich Sprite-/Block-Offsets in die anhängenden Rohdaten). Enthält lautSRB.LST32 "SRB"-Blöcke (vermutlich "Sprite Resource Block"). Tabellenstruktur noch nicht final verstanden — steigt über mehr Einträge als die reinen 32 Top-Level-Files, also vermutlich verschachtelt (pro Sprite/Frame-Offsets innerhalb jedes SRB-Blocks). TODO: Tabellenende finden und pro-SRB-Grenzen bestimmen. -
PCKELL.SET— ist tatsächlich eine ZIP-Datei (SignaturPK\x03\x04)! Enthält 3 Einträge:APPEND.LST(Methode 6 "Imploded", 1945 Bytes entpackt) — Manifest mit 178 Dateinamen für die inPCKELL.PREzusammengefügten Assets.SRB.LST(Methode 1 "Shrink", 314 Bytes entpackt) — Manifest mit den 32 Dateinamen, die zuPCKELL.DATgehören (1:1 gleiche Basisnamen wie ein Teil der BOB-Einträge in APPEND.LST, z.B.TONY.SRB↔TONY.BOB).PCKELL.PRE(Methode 6 "Imploded", 2.328.934 Bytes entpackt) — die eigentliche Asset-Sammlung, konkateniert nach der Reihenfolge inAPPEND.LST.
WICHTIG — Kompressions-Falle: ZIP-Methode 6 "Imploding" ist NICHT dasselbe wie das "DCL Implode/Explode"-Format aus PKWAREs Data Compression Library (dafür gibt's
blast.cin zlib/contrib — hab ich zuerst versucht, schlägt fehl mit "distance too far back", weil es ein anderer Algorithmus ist trotz gleichem Namen). Debian/Ubuntusunzip(Info-ZIP, kompiliert MIT Explode+Unshrink-Support) entpackt beide Methoden aber klaglos — aufaria-wohnungfunktioniertunzip PCKELL.SETdirekt. Das Alpine-unzipim Brain-Container (aria-proxy) kann das NICHT (kein Implode-Support einkompiliert).
Datei-Typen in APPEND.LST (178 Einträge total)
| Ext | Anzahl | Vermutung |
|---|---|---|
| PCC | 77 | "Compiled Picture" — vermutlich RLE/Palette-komprimiertes Vollbild (Titelscreens, Menüs, Hintergründe) |
| BOB | 32 | "Blob" — Sprite-Grafik-Daten (Spielfiguren, Objekte), 1:1 mit den 32 SRB-Einträgen |
| MAP | 22 | Level-/Karten-Daten |
| ARE | 22 | "Area" — vermutlich Level-Metadaten/Kollisionszonen, im Paar mit MAP (22=22) |
| ICO | 19 | Icons (z.B. für Menüs/HUD) |
| SAM | 3 | Sound-Samples |
| TFX | 3 | vermutlich Musik/Sound-Effekt-Format |
Nächste Schritte (in dieser Reihenfolge sinnvoll)
- PCKELL.PRE aufteilen: Die 178 Dateien sind laut APPEND.LST hintereinander konkateniert — es fehlt noch die Größentabelle pro Datei (vermutlich am Anfang von PCKELL.PRE selbst, ähnlich der Offset-Tabelle in PCKELL.DAT, oder implizit aus dem Dateiformat jedes Typs ableitbar). Header von PCKELL.PRE selbst noch nicht angeschaut.
- Ein PCC-Bild reverse-engineeren — vermutlich klassisches Palette+RLE, das dürfte am leichtesten zu knacken sein (PCC ähnelt oft PCX-Varianten).
- BOB/SRB-Sprite-Format verstehen — Kollisions-Header aus PCKELL.DAT (die Offset-Tabelle) mit den 32 SRB-Namen abgleichen.
- RTM.EXE nicht disassemblieren müssen — Ziel ist ein sauberes Python-Reimplement der Spiellogik (Physik/Level/Gegner aus MAP/ARE lesen), nicht 1:1-Code-Nachbau der DOS-Engine.
Aufbewahrungsort
Alle Rohdaten + Manifeste liegen unter raw/ in diesem Projektordner
(/shared/projects/kellogg_s_remake/raw/). raw/extracted/ enthält den
fehlgeschlagenen blast.c-Versuch (kann weg). Entpackte Dateien
(APPEND.LST, SRB.LST, PCKELL.PRE — alle bereits entpackt, nicht mehr
komprimiert) liegen direkt in raw/.
DOSBox-Testumgebung (2026-07-22) — Original läuft jetzt!
DOSBox 0.74-3 ist auf aria-wohnung installiert (apt). Zweck: das
Original-Spiel als visuelle/funktionale Referenz neben dem Reverse-Engineering
laufen lassen, ohne die kaputte QEMU-VGA-Emulation aus dem "Classic Games"-Crash.
Fehlende Dateien nachgeliefert
raw/ hatte urspr. nur RTM.EXE + PCKELL.* — START.EXE, SETUP.EXE,
KELLOGG.INI, HDPMI16.EXE (DPMI-Host) und DPMI16BI.OVL fehlten (waren
nie aus der dos_shareware-VM-Disk kopiert worden, nur RTM+PCKELL). Auch ein
READ.ME (Original-Textdatei mit Installations-/Troubleshooting-Hinweisen)
lag dort. Alle liegen jetzt in raw/ (Quelle: dos_shareware-Diskimage auf
aria-wohnung, Pfad GAMES/KELLOGG/ — per qemu-nbd --read-only gemountet,
VM dafür kurz gestoppt, danach sauber wieder disconnected. Die VM
dos_shareware ist seitdem gestoppt — bei Bedarf über's Cockpit-Panel oder
aria-vm boot dos_shareware wieder hochfahren).
RTM.EXE ist die eigentliche Engine, aber sie verweigert den Direktstart
("This loader is invoked and required by Borland tools") — man MUSS über
START.EXE gehen, das dann RTM.EXE korrekt aufruft.
Der Show-Stopper: IRQ-Konflikt (aus dem Original-READ.ME!)
Mit den Original-KELLOGG.INI-Werten (Adr=544 DMA=1 IRQ=7, Soundblaster)
hängt sich das Spiel nach dem 2. Studio-Logo (Factor 5) in einer Endlosschleife
auf — kompletter schwarzer Screen, DOSBox-Prozess lebt aber (kein Crash,
Freeze). Das READ.ME beschreibt dieses EXAKTE Symptom ("Bild bleibt schwarz")
und empfiehlt IRQ 5 statt 7. Fix:
raw/KELLOGG.INI:IRQ=5(statt 7)dosbox.conf[sblaster]-Sektion MUSS matchen:irq=5(sonst redet DOSBox's emulierte SB16 am falschen IRQ vorbei und das Spiel hängt trotzdem)
Mit diesem Fix läuft das Spiel sauber durch: Rauser-Advertainment-Logo →
Factor-5-Logo → Kellogg's-Logo → "Tony & Friends in Kellogg's Land"-Titelbild
→ Weltkarte (Berge/Wald/Schloss mit Drache, alle Charaktere sichtbar:
Tiger/Tony, Toucan, Frosch, Affe/Coco, Bär). Screenshots liegen unter
/shared/uploads/aria_kellogg_*.png.
Funktionierende dosbox.conf
[sdl]
fullscreen=false
output=surface
[sblaster]
sbtype=sb16
sbbase=220
irq=5
dma=1
hdma=5
[autoexec]
mount c <pfad-zu-raw>
c:
START.EXE
Screenshot-Workflow (headless, ohne echten Desktop)
aria-wohnung hat keinen laufenden X-Server. Screenshots via
xvfb-run -s '-screen 0 1024x768x24' dosbox ... + import -window root
(ImageMagick) im selben xvfb-run-Prozess. Tasteneingaben simulierbar mit
xdotool key <taste> (kein --window-Targeting nötig, funktioniert auch
ohne Fenstermanager in Xvfb). Audio läuft im ALSA-nosound-Modus (keine echte
Soundkarte im Container/VM) — DOSBox emuliert die SB16 trotzdem korrekt genug
fürs IRQ-Timing, es kommt nur kein tatsächlicher Ton raus.
Steuerung (aus READ.ME, für spätere Gameplay-Tests)
Pfeil links/rechts = laufen, Leertaste/Pfeil-hoch = springen, Pfeil-runter = ducken, ALT = Sonderfunktion/Tür öffnen, P = Pause, ESC = zurück zur Karte (ohne Leben zu verlieren).
PCKELL.PRE Container-Format (2026-07-22) — Kernstruktur geknackt
Ziel: die 178 in APPEND.LST gelisteten Dateien (32 BOB, 77 PCC, 22 MAP,
22 ARE, 19 ICO, 3 SAM, 3 TFX) sauber aus PCKELL.PRE (2.328.934 Bytes,
bereits ZIP-entpackt) raustrennen. Tools liegen in tools/split_pre.py
(aktuellster Stand, laeuft auf aria-wohnung mit python3, braucht
raw/PCKELL.PRE + raw/APPEND.LST + raw/SRB.LST).
Zwei Header-Varianten je nach Dateityp
.BOB-Eintraege (32x, Sprite-Rohdaten): kein Tag-Slot, Header direkt
lueckenlos hintereinander:
[4-Byte-LE-Laenge][NUL-terminierter Original-DOS-Pfad
"H:\WIWA\ENGINE\GAMEDATA\<NAME>.BOB"][<Laenge> Bytes Rohdaten]
Danach folgt variables Zero-Padding (~219-226 Byte beobachtet) bis zum
naechsten Header. Vollstaendig validiert: alle 32 BOB-Eintraege exakt
gefunden, 0 Namens-Mismatches gegen APPEND.LST. Robusteste Methode zum
Finden: direkte Byte-Suche nach H:\WIWA\ENGINE\GAMEDATA\<erwarteter Name>
im File (nicht raten, den vollen erwarteten Namen pro Eintrag einzeln
suchen — das ist wasserdicht).
Alle anderen Typen (PCC/MAP/ARE/ICO/SAM/TFX, 146x): kein eingebetteter Pfad, dafuer ein 256-Byte-Tag-Slot VOR dem eigentlichen Header:
[Tag-Slot, exakt 256 Byte lang:
1-Byte-Namenslaenge + Dateiname (z.B. 0x0B "CHOCOS7.PCC")
+ Rest mit Speicher-Muell des Kompilier-Tools aufgefuellt]
[bei Tag-Slot-Start + 256: 4-Byte-LE-Laenge][<Laenge> Bytes Rohdaten]
Bestaetigt an mehreren Stellen (ANTS.PCC, CHOCOS7.PCC, und der
"Master"-Tag "A.SRB" ganz am Dateianfang vor A.BOB). Wichtige Falle:
beim Uebergang von der letzten .BOB- zur ersten .PCC-Datei (DOORS.BOB
-> ANTS.PCC) ueberlappt der Tag-Slot von ANTS.PCC um ~34 Byte in das, was
man anhand der BOB-Laengenangabe als "Ende von DOORS.BOB" berechnen wuerde.
Grund noch nicht restlos geklaert (vermutlich rundet der Original-Compiler
beim Sektionswechsel BOB->PCC anders). Workaround im Skript: Tag-Suche
zuerst vorwaerts ab erwarteter Position, bei Fehlschlag Fallback mit
300 Byte Sicherheitsabstand rueckwaerts.
Kuriosum: Der Tag fuer .BOB-Eintraege (nur beim allerersten,
"A.SRB" vor A.BOB) nennt nicht den eigenen Namen, sondern den
.SRB-Begleitnamen aus SRB.LST (1:1 gleiche Reihenfolge wie die
BOB-Liste in APPEND.LST). Passt zur bekannten SRB<->BOB-Kopplung
(Kollisions-Metadaten in PCKELL.DAT <-> Sprite-Pixeldaten in PCKELL.PRE).
PCC-Bildformat (erste Erkenntnisse, noch nicht fertig decodiert)
Nutzdaten beginnen mit einem PCX-aehnlichen 16-Byte-Header:
Byte 0: 0x0A (Manufacturer-Marker, wie ZSoft PCX)
Byte 1: 0x05 (Version)
Byte 2: 0x01 (Encoding = RLE)
Byte 3: 0x08 (Bits pro Pixel = 8, also 256 Farben)
Byte 4-11: bisher immer 0 gesehen (Xmin/Ymin/Reserved?)
Byte 12-13: Breite (LE16), z.B. 0x0140 = 320
Byte 14-15: Hoehe (LE16), z.B. 0x00C8 = 200
Byte 16+: vermutlich RLE-komprimierte Pixel-Indexdaten (klassisches
PCX-RLE: Byte mit oberen 2 Bits gesetzt (0xC0-0xFF) = Lauflaenge
(Byte&0x3F), gefolgt vom Wert-Byte; sonst literaler Pixel)
Farbpalette (256x3 Byte RGB) wahrscheinlich NICHT pro Datei (dafuer waeren die kleinen Dateien wie ANTS.PCC mit nur 900 Byte total zu klein) — vermutlich eine globale Palette, die noch gefunden werden muss (Kandidat: irgendwo in RTM.EXE oder als eigene Ressource). TODO fuer naechste Session.
PCKELL.PRE Splitter — GELOEST (2026-07-22, ~02:15 Ortszeit)
Der vermeintliche "14%-Drift-Bug" war GAR KEIN Bug im Tag-Matching. Diagnose
(tools/diag_split.py, inzwischen geloescht, siehe Git-History falls noetig)
zeigte: jeder der 178 Tags aus APPEND.LST wird exakt EINDEUTIG gefunden
(genau 1 Kandidat, Gap durchgehend 0, ausser dem bekannten BOB->PCC-
Uebergang mit -34 Byte). Der Splitter war also die ganze Zeit korrekt —
er endete nur zu frueh, weil APPEND.LST gar nicht alle Eintraege in
PCKELL.PRE auflistet.
Direkt im Anschluss an den letzten APPEND.LST-Eintrag (TITEL2.SAM,
endet bei 0x1e9aac) folgen, im EXAKT GLEICHEN Tag-Slot-Format, noch
3 weitere, nicht gelistete Eintraege:
DPMI16BI.OVL 65312 Byte
RTM.EXE 108686 Byte
START.EXE 148480 Byte
Der letzte davon (START.EXE) endet bei 0x238966 — exakt die
Dateigroesse von PCKELL.PRE. Damit ist das Container-Format zu 100%
verifiziert, kein einziges Byte bleibt unerklaert. Macht inhaltlich auch
Sinn: PCKELL.PRE ist offenbar ein self-contained Redistributable-Paket,
das die komplette DOS-Extender-Runtime (DPMI-Server + Runtime-EXE +
Launcher) gleich mitbuendelt — nicht nur Spiel-Assets.
Extra-Validierung: die 3 extrahierten System-Dateien sind
byte-identisch (cmp) zu den Einzeldateien, die schon lose in raw/
liegen (aus der dos_shareware-VM kopiert) — zweite unabhaengige
Bestaetigung, dass die Extraktion korrekt ist.
tools/split_pre.py (finale v7) extrahiert jetzt alle 181 Dateien
fehlerfrei nach extracted_pre/:
32 BOB, 77 PCC, 22 MAP, 22 ARE, 19 ICO, 3 SAM, 3 TFX, 1 OVL, 2 EXE
Alte Splitter-Zwischenversionen (v1-v6, Diagnose-Scripts) sind auf
aria-wohnung (/home/aria/kellogg_remake/tools/) aufgeraeumt — nur
noch split_pre.py (v7, final) liegt dort, identisch zur Kopie hier im
Projekt unter tools/split_pre.py. extracted_pre/ (2,6 MB, 181 Dateien)
liegt jetzt auch hier im Projekt, nicht nur auf aria-wohnung.
PCC-Header — ergaenzender Fund
Bei MENU.PCC sind Byte 4-11 NICHT alle Null (anders als bei ANTS.PCC
vermutet) — sie enthalten Xmax/Ymax (0x013f=319, 0x00c7=199), passend
zum klassischen PCX-Header-Layout Xmin(2) Ymin(2) Xmax(2) Ymax(2) bei
Offset 4. Fuer ein 320x200-Bild ab (0,0) macht Xmax=319/Ymax=199 Sinn.
Bei ANTS.PCC (kleines 900-Byte-Sprite-Preview-Bild) stehen dort
durchgehend Nullen — vermutlich weil die Original-Autoren dieses Feld
bei kleineren generierten Bildern nicht befuellt haben. Fuer den
PCC-Decoder erstmal ignorierbar, Breite/Hoehe kommt zuverlaessig aus
Offset 12-15.
Naechste Schritte (Prioritaet) — ALT, siehe unten "PCC-Format GELOEST" fuer aktuellen Stand
1. Ein PCC-Bild vollstaendig decodieren ERLEDIGT (siehe unten).
2. BOB/SRB-Sprite-Format verstehen (PCKELL.DAT-Offset-Tabelle mit den
32 SRB-Namen abgleichen, dann Frame-Struktur pro Sprite ableiten).
3. MAP/ARE-Levelformat reversen (kleinste Dateien zuerst, z.B. ein
simples frühes Level, z.B. W1L0.MAP/W1L0.ARE).
4. Erst danach: Python-Projektstruktur aufsetzen (pygame), Asset-Loader
fuer BOB/PCC/MAP schreiben, Kernschleife (Physik/Kollision) gegen
DOSBox-Referenzverhalten abgleichen.
PCC-Bildformat — VOLLSTAENDIG GELOEST (2026-07-22, ~02:20 Ortszeit)
Format zu 100% verstanden und visuell verifiziert. PCC = klassisches PCX v5, 256-Farben, mit eingebetteter Palette PRO DATEI (kein globales Palette-Rätsel, wie in der vorherigen Notiz befürchtet):
Byte 0-15: PCX-Header (Manufacturer=0x0A, Version=5, Encoding=1/RLE,
BPP=8, Xmin/Ymin/Xmax/Ymax bei Offset 4-11,
Width(LE16)/Height(LE16) bei Offset 12-15 — Width/Height sind
DIREKTE Pixelmaße, nicht Xmax-Xmin+1, auch wenn beides meist
gleich rauskommt bei 320x200-Vollbildern)
Byte 16 .. (len-769): SCANLINE-weise RLE-komprimierte Pixel-Indexdaten.
RLE-Tupel: Byte mit oberen 2 Bits gesetzt (0xC0-0xFF) =
Lauflaenge (Byte&0x3F), gefolgt von 1 Wert-Byte. Sonst
literaler Pixel. WICHTIG: pro Scanline wird bis exakt
`width` Pixel dekodiert, ueberschuessige Pixel eines Runs
am Zeilenende werden verworfen (klassisches PCX-Verhalten,
NICHT als ein durchgehender Bytestrom decodieren — das
fuehrt zu Off-by-Overshoot-Fehlern und Fehlausrichtung
gegenueber der eingebetteten Palette am Dateiende).
Letzte 769 Byte: `0x0C`-Marker + 768 Byte (256 x RGB) Palette — die
klassische PCX-v5-256-Farben-Erweiterung. JEDE PCC-Datei
traegt ihre EIGENE Palette mit sich (keine globale Palette
aus RTM.EXE noetig, wie in der vorigen Session vermutet).
Decoder fertig: tools/pcc_to_png.py (auf aria-wohnung unter
/home/aria/kellogg_remake/tools/pcc_to_png.py, identische Kopie hier
im Projekt unter tools/pcc_to_png.py). Aufruf:
python3 tools/pcc_to_png.py extracted_pre/<NAME>.PCC out.png
(braucht ImageMagick convert auf dem Zielsystem — ist auf aria-wohnung
vorhanden).
Visuelle Verifikation — 100% korrekt:
KARTE.PCC→ exakte Weltkarte (Berge/Schloss/Drache, Tony/Tiger, Coco/Affe, Frosch, Fluss, Bäume) — Pixel-für-Pixel wiedererkennbar gegen den DOSBox-Screenshotaria_kellogg_worldmap.pngvon vorher.KELLOGGS.PCC→ glasklares "Kellogg's präsentiert"-Logo mit korrektem geschwungenem Markenschriftzug, scharfe Kanten, kein Rauschen/Fehler in der Dekodierung.MENU.PCC→ sauberer Menü-Rahmen (blauer Hintergrund, rot-goldene Box) — vermutlich Passwort-/Level-Auswahl-UI. Alle Test-PNGs liegen unter/shared/uploads/aria_pcc_*.pngzur Ansicht, dauerhafte Kopien aller 77 von 77 PCC-Dateien fehlerfrei batch-decodiert liegen unterpng_out/in diesem Projektordner (416 KB total, 77 Dateien — vollstaendige Validierung, kein einziger Absturz oder Format-Ausreisser).
Einzige kleine Restfrage (kein Blocker): bei manchen Dateien bleiben 1-30 Byte am Ende des Pixel-Datenblocks vor der Palette ungenutzt (vermutlich Padding/Rundung des Original-Encoders) — beeinflusst das Bildergebnis nicht sichtbar, wird ignoriert.
BOB-Sprite-Format — erste Erkenntnisse (2026-07-22, ~02:30 Ortszeit, IN ARBEIT)
Kein PCX-Verwandter. BOB-Dateien starten NICHT mit 0x0A-Manufacturer-
Byte, kein erkennbarer Klartext-Header wie bei PCC. Vermutlich beginnt die
(vermutlich RLE-komprimierte) Pixel-Nutzdaten direkt ab Byte 0.
Wichtiger Fund: Die 32 BOB-Namen sind NICHT alle "richtige" Objektnamen
— 14 davon sind Einzelbuchstaben (A.BOB .. O.BOB, ohne M) plus
BLUME.BOB/WOLKE.BOB (Blume/Wolke, Deko-Objekte), dann die Marken-Packs
(VITAMIN/COCOPOPS/SMACKIES/FROSTIES/LOOPS), dann Charaktere
(TONY/SMACKS/TOUCAN/COCO), dann Level-Objekte (PLATFW1=Plattform,
KEYS, GAMEBAR=HUD-Leiste, KROKO/BOSSNAKE/DRAGON=Gegner, DOORS).
Die Buchstaben-Sprites (A-O) sind vermutlich Sammel-Buchstaben-Items
(Bonus-Mechanik: Buchstaben im Level einsammeln) — passend zur Groessen-
Gruppierung (viele davon fast gleich gross: B/E/N/O=1295 Byte, D/H/I=4406,
J/K=2332 — deutet auf fixe Sprite-Dimensionen pro Buchstaben-"Familie",
vermutlich Schriftart-aehnliche Boxen).
Byte-Identitaet als Format-Hinweis: FROSTIES.BOB, COCOPOPS.BOB,
SMACKIES.BOB (alle 3323 Byte gross) haben BYTE-FUER-BYTE identische
ersten 16 Byte (16 b4 2c 76 82 b4 3a 9f 06 88 82 cf 16 e8 03 2d) und
divergieren erst ab ca. Offset 0x20. LOOPS.BOB (ebenfalls 3323 Byte)
zeigt eine um 4 Byte verschobene, aber erkennbar verwandte Bytefolge.
Interpretation: das ist vermutlich KEIN Klartext-Header, sondern
bereits RLE-komprimierte Pixeldaten — die vier Sprites sind alle
"Cerealien-Packung"-Objekte mit identischer Kastenform/Silhouette
(gleiche Pixel-Auesserform => gleiche RLE-Runs am Anfang), die sich nur
im aufgedruckten Marken-Logo unterscheiden (Divergenz kommt spaeter).
Das wuerde erklaeren warum 4 komplett verschiedene Marken exakt gleich
grosse Dateien mit ident. Praefix erzeugen: gleiche Box-Geometrie,
gleiches Kompressionsschema, nur Content-Unterschied in der Bildmitte.
Hypothese fuer naechste Session: BOB = aehnliches RLE-Schema wie PCC
(Byte mit oberen 2 Bits gesetzt = Lauflaenge+Wert), aber OHNE PCX-Header
und OHNE eingebettete Palette — Breite/Hoehe muessen aus PCKELL.DAT
kommen (die SRB-Offset-Tabelle, noch nicht durchdrungen) oder aus einer
festen Tabelle in RTM.EXE. Naechste konkrete Schritte:
PCKELL.DATOffset-Tabelle vs.SRB.LST-Namen abgleichen (32 Eintraege, 1:1 mit den 32 BOB-Dateien) — dort vermutlich Breite/Hoehe/Frame-Anzahl pro Sprite zu finden.- Testweise RLE-Decode von
A.BOB(kleinstes/einfachstes Beispiel aus der Buchstaben-Gruppe) mit angenommener kleiner Breite/Hoehe (z.B. 20x20 bis 40x40 fuer ein UI-Buchstaben-Icon) durchprobieren, gegen erwartete Pixelzahl abgleichen (aehnlich wie beim PCC-Ansatz, der am Ende erfolgreich war: Header-Annahmen iterativ gegen Dateigroesse pruefen). - Falls das nicht schnell konvergiert:
TONY.BOB(Hauptfigur, 47726 Byte, groesste Datei nach COCO) ist wahrscheinlich der wichtigste Fund fuer den Port und rechtfertigt tiefere Analyse zuerst.
Naechste Schritte (Prioritaet, aktueller Stand)
- BOB/SRB-Sprite-Format weiter reversen — siehe Hypothesen direkt
oben. Naechster Schritt:
PCKELL.DAT-Offset-Tabelle mitSRB.LSTabgleichen, danachA.BOB-Testdecoding. - MAP/ARE-Levelformat reversen (kleinste Dateien zuerst, z.B. ein
simples frühes Level, z.B.
W1L0.MAP/W1L0.AREfalls vorhanden — sonst kleinste Datei nach Groesse waehlen). - Erst danach: Python-Projektstruktur aufsetzen (pygame), Asset-Loader
fuer BOB/PCC/MAP schreiben (PCC-Loader ist im Grunde fertig, nur
noch von PPM/ImageMagick-Zwischenschritt auf direktes PNG-Schreiben
in Python umstellen, z.B. mit
Pillow— aktuell haengt der Decoder noch am System-convert-Tool, das fuer den finalen Python-Port NICHT die Zielarchitektur sein soll).
Hinweis fuer Fortsetzung nach Neustart/Session-Wechsel
Dieses Projekt laeuft bewusst autonom weiter (Stefan-Wunsch, 2026-07-22).
Fortschritt wird nach JEDEM Meilenstein hier in NOTES.md gesichert.
Zusaetzlich liegt ein gepinnter Kurz-Status im Memory (Suchbegriff
"Kellogg's Remake") als Fallback, falls diese Datei mal nicht griffbereit
sein sollte. Bei Session-Neustart: einfach hier weiterlesen ab
"Naechste Schritte" oben, keine Rueckfrage bei Stefan noetig.
Ein trigger_timer ("kellogg-remake-continue") ist als Selbst-Weck-Kette
aktiv: feuert stuendlich, arbeitet den naechsten offenen Punkt ab, speichert
hier, legt danach den naechsten Timer an — laeuft ohne Rueckfrage weiter.
PCC-Decoder-Bugfix + Git-Repo (2026-07-22, ~09:20 Ortszeit)
Stefan hat zurecht bemaengelt, dass die PCC-Bilder verzerrt/verrutscht aussehen (z.B. Smacks-Frosch spiegelverkehrt, Kellogg's-Logo mit Fehlstelle). Ergebnis der Untersuchung:
GEFUNDEN UND GEFIXT — Width/Height-Bug: Der Decoder las Breite/Hoehe
bisher aus Offset 12-15 (siehe alte Notiz oben). Das ist FALSCH — dieses
Feld ist bei allen Dateien ein Konstant-/Platzhalterwert (vermutlich
DPI-Reserved-Feld wie im echten 128-Byte-PCX-Header), der bei
Vollbild-Screens (320x200) zufaellig mit der echten Groesse
uebereinstimmt, bei kleineren Sprites/Logos aber komplett falsch ist.
Richtig: Breite/Hoehe muessen aus Xmax-Xmin+1 / Ymax-Ymin+1
(Offset 4-11) berechnet werden. Beweis: FACTOR5.PCC konsumiert mit der
alten (falschen) Hoehe 200 nicht alle Bytes sauber, mit der echten Hoehe
199 (aus Ymax=198) landet der Byte-Konsum exakt bei 100% (51609/51609).
Betroffen/jetzt gefixt: RAUSER1.PCC (182x46 statt fälschlich 320x200),
RAUSER2.PCC (228x21), RAUSER3.PCC (16x55), FAC0-3.PCC (16x16),
FACTOR5.PCC (320x199). Fix ist in tools/pcc_to_png.py eingebaut,
alle 77 PNGs unter png_out/ mit dem Fix neu generiert.
Rauser-Intro: JA, schon extrahiert. RAUSER1/2/3.PCC sind Frames
eines scrollenden Text-Logos (vermutlich "RAUSER ADVERTAINMENT PRESENTS"),
mit dem Fix jetzt lesbar (zeigt z.B. "...USER TRAI..." als Ausschnitt).
Volles Logo muesste sich aus allen 3 Frames zusammensetzen lassen (noch
nicht gemacht).
FACTOR5.PCC "Geister"-Doppellogo: vermutlich KEIN Bug, sondern ein Reflexions-/Schatten-Designelement — Byte-Konsum ist exakt 100%, also decodiert der Inhalt komplett korrekt, das Doppelbild ist einfach das, was in der Datei steht.
OFFEN — KELLOGGS.PCC/KARTE.PCC-Notch-Artefakt: Der Width/Height-Fix hat den harmlosen 320x200-Fall nicht veraendert (Xmax/Ymax ergeben dort zufaellig dieselbe Groesse wie vorher). Das Notch-Artefakt (rot/gelber Fleck rechts neben "Kellogg's"-Schriftzug, passt nicht zum DOSBox-Referenz-Screenshot) bleibt bestehen. Ausgeschlossen als Ursache (empirisch getestet, nicht nur vermutet):
- Horizontales Rollen/Scrollen des ganzen Bilds (18 Shift-Kandidaten durchprobiert) — Artefakt bleibt IMMER an derselben Stelle relativ zum Bildinhalt (Box/Text), nicht zur Leinwand. Kein Verschiebe-/Wrap-Bug.
- Zeilenweises Verwerfen von RLE-Overshoot am Zeilenende — zeilenbasierte
und durchgehende (row-boundary-freie) Decodierung liefern fuer
KELLOGGS.PCC byte-identische Ergebnisse (kein Overshoot tritt je auf).
Interessant:
MENU.PCCnutzt vermutlich denselben Box-Rahmen (leere Variante) und rendert jetzt SAUBER ohne Notch — der Fehler ist also dateispezifisch, nicht im Rahmen-Design selbst. Naechste Hypothese: Palette-Fehlzuordnung fuer einzelne Indizes ODER RLE-Ambiguitaet bei literalen Pixelwerten >= 0xC0 (werden durch(b&0xC0)==0xC0evtl. faelschlich als Lauflaengen-Token statt literaler Indexwert gelesen) — noch zu verifizieren durch gezielten Test mit einem Decoder, der beide Interpretationen an der vermuteten Fehlstelle durchspielt.
Ebenfalls noch offen (niedrige Prioritaet): TONY.PCC/SMACKS.PCC
liefern mit dem Xmax/Ymax-Fix nur 1x1 Pixel (degenerated, Xmax=Ymax=0
im Header) — vermutlich sind das keine "echten" Vollbilder, sondern
Platzhalter/ungenutzte Preview-Slots; die eigentlichen Charakter-Sprites
stecken hoechstwahrscheinlich in den .BOB-Dateien (TONY.BOB,
SMACKS.BOB etc.), nicht in den gleichnamigen .PCC-Dateien.
Git-Repo eingerichtet: Auf Stefans Wunsch liegt der Projektstand jetzt
unter https://git.hacker-net.de/Aria-Software/tony-remake. Bewusst NICHT
mit eingecheckt: raw/ (Original-Spieldateien: PCKELL.DAT/.PRE/.SET,
RTM.EXE, START.EXE etc. — das ist buchstaeblich das Original-Spiel) und
extracted_pre/ (die daraus entpackten 181 Rohdateien — noch
Original-Asset-Material, nur unverpackt). Mit eingecheckt: NOTES.md,
tools/ (unser Code: split_pre.py, pcc_to_png.py), dosbox/
(Test-Konfiguration), png_out/ (unsere konvertierten PNG-Ergebnisse,
408 KB, reine Arbeitsergebnisse kein Originalmaterial).
KELLOGGS.PCC/KARTE.PCC-Notch-Artefakt — GELOEST (2026-07-22, ~09:30 Ortszeit)
Die Notiz oben ("Ausgeschlossen als Ursache ... Zeilenweises Verwerfen von RLE-Overshoot ... liefern byte-identische Ergebnisse") war FALSCH. Das war ein Messfehler einer frueheren Session: der "kontinuierliche" Testdecoder hat versehentlich weiterhin die width/height aus Offset 12-15 gelesen (dem VERWORFENEN Bugfix-1-Feld) statt aus Xmax/Ymax — dadurch kam bei den beiden 320x200-Vollbildern zufaellig das gleiche (korrekte) Ergebnis raus wie beim zeilenbasierten Decoder, und der Test schien zu bestaetigen, dass beide Methoden aequivalent sind. Sind sie nicht.
Neu verifiziert mit einem sauberen Vergleichstest (Buffer.compare in
Node.js, unabhaengige Re-Implementierung): zeilenbasiertes Decoding
(Row-Reset, discard Overflow am Zeilenende) und durchgehendes Decoding
(RLE-Runs duerfen ueber Zeilengrenzen hinweglaufen) liefern NICHT
identische Ergebnisse — 216 von 64000 Pixeln unterscheiden sich bei
KARTE.PCC, 293 von 64000 bei KELLOGGS.PCC. Klingt nach wenig (<0.5%), reicht
aber, um ganze Bildbereiche sichtbar zu verschieben, weil ab dem ersten
"verlorenen" Ueberlauf-Pixel alle nachfolgenden Zeilen einen Pixel weiter
"nachruecken".
Beweis per Ground-Truth-Vergleich: DOSBox-Screenshot
aria_kellogg_worldmap.png (1024x768 mit schwarzen Balken) exakt auf den
reinen Spielbereich zugeschnitten (convert -fuzz 5% -trim → 640x400,
= 2x 320x200) und auf 320x200 runterskaliert
(/shared/uploads/aria_karte_reference_320.png). Nebeneinander-Vergleich
mit dem durchgehend (ohne Row-Reset) decodierten KARTE.PCC
(/shared/uploads/aria_karte_compare2.png): pixel-identisch — Berge,
Schloss, Drache, Tiger, Affe/Coco, Frosch, Teich, Haus, Voegel-Ecke, alles
exakt an der richtigen Stelle. Das Row-Reset-Verhalten war der einzige
Bug; es gibt kein horizontales Rollen, keine Palette-Fehlzuordnung, keine
RLE-Ambiguitaet bei Werten >=0xC0.
Fix: tools/pcc_to_png.py decodiert jetzt global width*height Pixel
aus dem RLE-Strom OHNE pro Zeile abzuschneiden (kein Row-Reset mehr). Alle
77 PNGs in png_out/ wurden mit diesem finalen Decoder neu erzeugt
(diesmal wirklich verifiziert, nicht nur "sieht plausibel aus"). Kleine
Sprites/Logos waren von diesem Bug kaum betroffen (selten ein Run, der eine
Zeilengrenze ueberschreitet) — deshalb fiel es dort nie auf, nur bei den
zwei grossen 320x200-Vollbildern.
Rauser-Intro bestaetigt (Frage von Stefan): RAUSER1/2/3.PCC sind schon
laenger extrahiert und liegen jetzt mit dem finalen Decoder sauber decodiert
in png_out/. Es ist ein Text-Logo "RAUSER" + "ADVERTAINMENT" (Studio-Card),
als 3 Bild-Frames — vermutlich fuer einen Scroll-/Fade-Effekt, den die
Original-Engine (RTM.EXE) zur Laufzeit zusammensetzt, KEIN Video/keine
Animation-Datei. Fuers Remake heisst das: die 3 Frames sind da, die
Overlay-/Scroll-Logik muss im Python-Port nachgebaut werden (vermutlich
simpel: Frame croppen + ueber Zeit einblenden, sobald wir wissen wie die
Original-Sequenz zeitlich ablaeuft — dafuer ggf. DOSBox-Referenzvideo/
Screenshots in der Sequenz aufnehmen, spaeterer Schritt).
BOB-Sprite-Format — Exploration laeuft, noch nicht geloest (Stand 09:30)
Auf aria-wohnung (/home/aria/kellogg_remake/tools/) lief parallel schon
einiges an Exploration fuer das naechste Format (BOB-Sprites): Brute-Force-
Breitensuche (bob_width_search.py), Header-Diff zwischen aehnlich grossen
Dateien (bob_header_diff.py, bob_header_search.py), Histogramm-Analyse
(bob_histogram.py), Sichtgitter-Rendering mit mehreren Breiten-Kandidaten
(bob_render_grid.py/bob_render_grid2.py), sowie erste Versuche die
PCKELL.DAT-Offset-Tabelle zu parsen (dat_analyze.py/dat_analyze2.py,
dat_table2.py, dat_u16.py). Kein Ergebnis/Durchbruch bisher — alles
noch offene Exploration, keiner der Scripts hat schon eine verifizierte
Loesung. Zur Sicherheit (Stefans Wunsch: nichts soll bei einem VM-Neustart
verloren gehen) sind alle diese Scripts jetzt zusaetzlich hier im
Projekt gesichert unter tools/wip_bob_sprite_research/ (noch nicht
aufgeraeumt/nicht final, bewusst als "work in progress" separiert von den
fertigen Tools split_pre.py/pcc_to_png.py).
Naechste Schritte (Prioritaet, Stand 09:30)
- BOB/SRB-Sprite-Format weiter reversen — siehe
tools/wip_bob_sprite_research/fuer den aktuellen (unfertigen) Exploration-Stand. Naechster konkreter Schritt:PCKELL.DAT-Offset-Tabelle sauber mit den 32SRB.LST-Namen abgleichen, danachA.BOB(kleinstes Beispiel) testdecodieren. - Rauser-Intro-Sequenz (3 Frames) zu einer zusammengesetzten Vorschau rendern/dokumentieren, sobald Zeit ist — niedrige Prioritaet, Assets sind schon da.
- MAP/ARE-Levelformat reversen.
- Python/pygame-Projektstruktur aufsetzen (PCC-Loader ist fertig, muss nur noch von PPM/ImageMagick-Zwischenschritt auf direktes Pillow-basiertes PNG/Surface-Schreiben umgestellt werden fuer den finalen Port).