# 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 laut `SRB.LST` 32 "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** (Signatur `PK\x03\x04`)! Enthält 3 Einträge: - `APPEND.LST` (Methode 6 "Imploded", 1945 Bytes entpackt) — Manifest mit 178 Dateinamen für die in `PCKELL.PRE` zusammengefügten Assets. - `SRB.LST` (Methode 1 "Shrink", 314 Bytes entpackt) — Manifest mit den 32 Dateinamen, die zu `PCKELL.DAT` gehö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 in `APPEND.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.c` in zlib/contrib — hab ich zuerst versucht, schlägt fehl mit "distance too far back", weil es ein anderer Algorithmus ist trotz gleichem Namen). Debian/Ubuntus `unzip` (Info-ZIP, kompiliert MIT Explode+Unshrink-Support) entpackt beide Methoden aber klaglos — auf `aria-wohnung` funktioniert `unzip PCKELL.SET` direkt. Das Alpine-`unzip` im 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) 1. **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. 2. **Ein PCC-Bild reverse-engineeren** — vermutlich klassisches Palette+RLE, das dürfte am leichtesten zu knacken sein (PCC ähnelt oft PCX-Varianten). 3. **BOB/SRB-Sprite-Format verstehen** — Kollisions-Header aus PCKELL.DAT (die Offset-Tabelle) mit den 32 SRB-Namen abgleichen. 4. **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 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 ` (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\.BOB"][ 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\` 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][ 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/.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-Screenshot `aria_kellogg_worldmap.png` von 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_*.png` zur Ansicht, dauerhafte Kopien aller **77 von 77 PCC-Dateien fehlerfrei batch-decodiert** liegen unter `png_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: 1. `PCKELL.DAT` Offset-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. 2. 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). 3. 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) 1. **BOB/SRB-Sprite-Format weiter reversen** — siehe Hypothesen direkt oben. Naechster Schritt: `PCKELL.DAT`-Offset-Tabelle mit `SRB.LST` abgleichen, danach `A.BOB`-Testdecoding. 2. MAP/ARE-Levelformat reversen (kleinste Dateien zuerst, z.B. ein simples frühes Level, z.B. `W1L0.MAP`/`W1L0.ARE` falls vorhanden — sonst kleinste Datei nach Groesse waehlen). 3. 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.PCC` nutzt 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)==0xC0` evtl. 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) 1. **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 32 `SRB.LST`-Namen abgleichen, danach `A.BOB` (kleinstes Beispiel) testdecodieren. 2. Rauser-Intro-Sequenz (3 Frames) zu einer zusammengesetzten Vorschau rendern/dokumentieren, sobald Zeit ist — niedrige Prioritaet, Assets sind schon da. 3. MAP/ARE-Levelformat reversen. 4. 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).