DOSBox-Nachmessung des blinkenden Level-1-Markers (real (59,153) vs
Binary-Label (53,56)): die Binary-y-Achse ist geflippt (screen_y=209-y).
Alle Pfade/Punkte jetzt an den Original-Positionen (W1 Wald unten, W2/W3
Berge/Schloss -- deckungsgleich mit Stefans Original-/Netz-Screenshots,
Kopf-am-Teich = W1L7). An der aktuellen Position wechseln Punkt und
Mini-Kopf im 0.5s-Rhythmus (Original-Verhalten laut Frame-Diff, die
Referenzbilder zeigen jeweils eine Phase).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
game/worldmap.py: parst Kartenpfad, Levelpunkt-Positionen und die 22
Levelnamen zur Laufzeit aus START.EXE (NE-Datensegment, Anker-Suche,
Fallback W1L1). Links/Rechts laesst die Kartenfigur (Mini-Kopf KARTE4-7
je Charakter) die Original-Wegpunkte ablaufen, der aktive Levelpunkt
blinkt orange/blau (KARTE0/2 -- Blinksequenz stand exakt so in der
Binary-Animationstabelle), Space/Return startet das Level, ESC -> Menue.
Kartenposition bleibt ueber Levelbesuche erhalten.
Level ohne handgepflegte LEVEL_INFO erhalten einen generischen Spawn
(erste Bodenstelle) -- damit sind ALLE 22 Level anwaehlbar und spielbar
(Basis-Physik; Wasser/Tueren dort folgen mit den echten Leveldaten).
E2E: Karte -> laufen -> W1L3 spielen -> zurueck -> W1L2 -> QUIT rc=0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Stefans Frage nach Disassembly: Byte-Muster-Suche nach Frame-Tabellen in
START.EXE/RTM.EXE ohne Treffer (nicht als nackte Tabellen im Binary);
stattdessen DOSBox-Frameserie (0.12s) mit Tuer-Charakterwechsel zu Smacks:
- Original-Sprung hat eine Absprung-Hocke (Kauer-Frame im Absprungmoment,
dann Streckung) -> JUMP_SQUAT_SECONDS=0.09 eingebaut (alle Charaktere).
- Original dimmt den Level waehrend der Tuer-Sequenz ab -> Overlay
waehrend door_open_t.
- Nebenbei verifiziert: unser Charakter-Menue ist deckungsgleich mit dem
Original (Layout, graue Koepfe fuer nicht verfuegbare Charaktere).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Nicht-Schwimmer koennen im Wasser nicht mehr ducken.
- Herzverlust im Wasser alle 1.5s statt 5s.
- Nach Schaden blinkt die Figur 0.9s (Sichtbarkeits-Toggle; beim Tod
deaktiviert, damit die Anim nicht unsichtbar haengt).
- Tuer-Reinschauen nutzt die echten Sprites: TONY 50 (Rueckenansicht),
SMACKS 48 (Stefans Fund -- jeweils letzter Frame vor den Platzhaltern).
Verifiziert: Duck-Verbot im Wasser, Blink-Muster wechselt, --once exit 0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Stefans fuenfte Feedback-Runde:
- Nicht-Schwimmer huepfen endlos auf der Wasseroberflaeche (~6px Auto-
Bounce) statt statisch zu stehen; Steuerung und voller Ausstiegs-Sprung
bleiben moeglich. Kein Idle im Wasser.
- Tod bei 0 Herzen: Tony verliert sein HALSTUCH (Frame 38 = Tony ohne
Tuch, Frame 40 = Tuch einzeln -- die Assets waren dafuer gebaut!),
fliegt aus dem Bild, Tuch flattert herab; Smacks analog mit Kappe
(26/29). Danach Respawn mit Leben-1, bei 0 Leben zurueck zur Karte.
- Tuer-Peek: Figur zeigt waehrend der Offen-Sekunde einen Reinschau-Frame.
- Duck-Kamera: 0.2s-Grace gegen X11-Autorepeat-/on_ground-Flackern
("Kamera geht sporadisch wieder rauf").
Verifiziert: Bounce-Amplitude ~6px endlos, voller Sprung aus dem Wasser,
Tod-Sprites gesichtet (Tuch/Kappe), --once exit 0, E2E rc=0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Stefans vierte Feedback-Runde:
- Sprites sinken 4px in den Boden ein (Fuesse standen sichtbar UEBER den
Blaettern; Original laesst sie einsinken).
- Echte Steh-Frames: Tony 16/17, Smacks-Walkzyklus ohne die Steh-Frames
12-15 ("letzter Lauf-Frame blieb beim Anhalten stehen").
- Tuer: DOORS[0] ist die OFFENE Tuer -> Ruhe = Tile-Tuer + Kopf-Schild
(DOORS[5]); ALT oeffnet die Tuer sichtbar und nach 1s folgt die Aktion
(Charakterwechsel-Menue) -- Muster fuer alle Tueren inkl. der
Schluessel-Tueren (DOORS 1-4).
- Slope-Landung: Swept-Kollision ueber alle ueberstrichenen Zeilen +
Herkunftsbedingung -- kein Durchfallen mehr bei schnellen Landungen
(Stress-Test: 50 Drops ueber die Hangbreite, 0 Durchfaller).
- Kamera: Figur steht bei ~75% Bildhoehe; DUCKEN gehalten (>=1.2s) faehrt
die Kamera sanft ~40px nach unten (Wasser unter Abgruenden sichtbar).
Verifiziert: Tunneling-Stresstest 0/50, Idle-Frames korrekt, Standbild
(Fuesse in Blaettern, Schild auf zu-Tuer, Kamerahoehe), --once exit 0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Charakter-Icon im HUD: nearest-skalierter WECH-Kopf + schwarzer 1px-
Umriss (Original-Look, Stefans Feedback). Eigene Mini-Kopf-Assets gibt
es nicht (GAMEBAR.BOB[16] leer).
- DOORS.BOB entschluesselt: Frame 0 (Tuer mit Kopf-Schild) wird jetzt auf
die Tuerposition geblittet; Frames 1-4 sind die Schluessel-Tueren mit
farbigen Knaeufen (fuer die spaetere Schluessel-Logik), Frame 5 das
Schild einzeln.
Szene deckungsgleich mit Stefans Original-Screenshot (Tuer mit Schild und
Punkten, pixeliger HUD-Kopf). --once exit 0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Stefans Korrektur: Box-Innenflaechen sind im Original WEISS (die Grafik
hatte es schon richtig -- Dunkelrot-Fuellung entfernt, Grafik-":" damit
nativ sichtbar). Zahlen jetzt in der Original-HUD-Font: GAMEBAR.BOB-
Ziffern (7x13), gerendert mit der GAMEBAR.PCC-Palette -> sattes Rot mit
dunkler Umrandung, gleiche Farbe wie der Doppelpunkt. Herzen: 6 Stueck im
3x2-Grid (Original-Screenshot), Start/Reset auf 6.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Stefans dritte Feedback-Runde:
- HUD nutzt jetzt die ECHTE GAMEBAR.PCC aus PCKELL.DAT (Stefans Fund):
Kellogg's-Leiste, Boxrahmen und Uhr-":" kommen aus der Original-Grafik;
weisse Box-Innenflaechen werden beim Laden dunkelrot gefuellt (macht die
Original-Engine zur Laufzeit ebenso). Inhalte an den gemessenen Box-
Positionen; HUD_H=25 (Grafikhoehe), VIEW_H=175.
- Slopes PIXELGENAU: Laufflaeche = oberster Nicht-Himmel-Pixel der Tile-
Grafik pro Spalte (die Haenge sind ~1:2, nicht 45 Grad -- Ursache des
restlichen Schwebens). Sky-Index vom haeufigsten Luft-Tile. Reine
Himmel-Spalten tragen nicht.
- STEP_UP=6: Mini-Stufen (Plateau-Kante ueber Hangende) werden beim Laufen
ueberwunden; hohe Waende blocken weiterhin.
- Unterste Map-Zeile immer solide (Grafik-Bodenstreifen ohne ctypes) --
kein Steckenbleiben mehr beim Tieftauchen.
- Smacks-Steh-Frames 12/13 statt 0/1 (Anhalte-Sprite-Bug).
Verifiziert: Slope-Drop exakt auf Grafikkante, Plateau-Aufstieg, Wand-
Integritaet, Smacks-Idle, --once exit 0, E2E rc=0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Stefans zweite Feedback-Runde:
- Nicht-Schwimmer (Tony & Co.) tauchen nicht mehr unter: die Wasser-
oberflaeche traegt (14px Eintauchtiefe, springen von dort moeglich,
Herzverlust laeuft) -- wie im Original-Screenshot. Schwimmer (Smacks)
loesen nahe der Oberflaeche mit der Sprungtaste einen echten Sprung aus
und kommen wieder aus dem Wasser raus (vorher unmoeglich).
- Slope-Schweben gefixt: Luft-Snap nur bei echter Durchdringung; Bergauf-
Toleranz nur fuer bereits Gelandete.
- Start-Sprite-Sequenz beim Levelstart/Charakterwechsel (Tony Arm hoch,
Smacks Daumen hoch, Frame 22, ~1.1s, durch Eingabe abbrechbar).
- Rennsprungweite: RUN_SPEED 185 -> 200 ("bis hinter die Blume").
- HUD v3 nach Original-Referenz: helle Creme-Rahmen, hoehere Boxen,
Cerealien-Icon in voller Groesse, leere Herz-Plaetze dunkel.
Verifiziert: Physik-Sims (Wade+Absprung, Smacks-Ausstiegssprung, Decken-
Kollision unter der Bruecke korrekt) + E2E rc=0 + --once exit 0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Stefans Feedback-Paket (7 annotierte Screenshots):
- Player-Klasse mit CHAR_DEFS: Tony (RENNEN mit ALT -- echte Rad-Animation,
Frames 26-33) und Smacks (SCHWIMMEN, Frames 37-44; kein Rennen) spielbar;
Coco/Toucan vorbereitet. Idle-Packungs-Animation nach 5s Stillstand
(Tony 44-49, Smacks 31-36). Sprung-Frames 18/19 (gestreckt).
- Sprunghoehe kalibriert (-360, ~72px: "Tony kommt mit dem Kopf an den Ast").
- WASSER (Stefans Fund: nur bei DOSBox machine=vgaonly sichtbar): water_y
pro Level + dunkelblaues Overlay; Nicht-Schwimmer verlieren alle 5s ein
Herz, 0 Herzen -> Respawn/Leben-1, 0 Leben -> Karte. Smacks schwimmt
schadlos (traege Wasserphysik, Space = Schwimmstoss).
- TUER mit Kopf-Symbol (Level-1-Haus): ALT im STEHEN oeffnet das
Charakter-Auswahlmenue "MIT WEM MOECHTEST DU SPIELEN?" -- WECH_1-4 =
farbige Koepfe, WECH_5-8 = grau (nicht verfuegbar; Level 1: nur
Tony+Smacks). Auswahl blinkt, Wechsel uebernimmt die Position.
- HUD nach Referenz-Screenshot: Keks-Box mit Cerealien-Icon (ITE0-3) des
aktiven Charakters, Herz-Box als 2x2-Grid, Charakter-Kopf-Box (zeigt die
gewaehlte Figur) + Leben, Uhr.
- Level-Metadaten (Charaktere/Wasserlinie/Tuer/Spawn) v1 als LEVEL_INFO-
Konstanten -- Original-Quelle ist vermutlich das .ARE-Format (Header
enthaelt BE-Pixelkoordinaten, Analyse in NOTES.md, noch offen).
Verifiziert: E2E (Xvfb+XTEST) -- Tuer->Menue->Smacks, HUD wechselt auf
Smacks-Kopf+Puff-Icon, Wasser-Overlay sichtbar, ESC/QUIT rc=0; --once ok.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Stefans annotierter Live-Test-Screenshot, alle 4 Punkte:
- Laufrichtung gefixt: TONY.BOB gerade Frames = rechts (war vertauscht,
Figur lief rueckwaerts).
- Schraegen-Kollision: ctype 16 = Slope-Tile (per ctype-Farbvisualisierung
exakt auf dem Grashang der Referenz identifiziert -- keine Tuer). 45-Grad-
Diagonale, Richtung per Nachbar-Heuristik, am Fussmittelpunkt geprueft,
Snap nur bei fallender Bewegung (kein Herunterziehen im Sprung).
Simulation verifiziert: Hang hoch bis Plateau, kein Durchfallen mehr.
- HUD: weisse Kellogg's-Leiste (Schriftzug aus KELLOGGS.PCC gecroppt),
Herzen als echte GAMEBAR-Sprites (10=voll/11=leer), Uhr-Box/Layout neu
verteilt und Startzeit 9:59 (4-stellige Anzeige passt immer in die Zeile).
- RENNEN: ALT halten (Original-Anleitung: Tonys Faehigkeit) bzw. LSHIFT,
185 px/s + schnellere Laufanimation.
Verifiziert: Slope-Simulation (min_y=559=Plateau, kein Durchfallen),
HUD-Standbild (Leiste/Herzen/Uhr komplett), E2E-Lauf rc=0, --once exit 0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Weltkarte: SPACE startet Level 1 (Original-Verhalten per DOSBox-Referenz:
Return tut dort nichts, kein sichtbarer Level-Cursor am Spielstart).
Level 1 = W1L1.MAP -- per Template-Matching des DOSBox-Gameplay-Screenshots
gegen die gerenderten Maps identifiziert (W1L0 ist NICHT Level 1).
game/level.py:
- Level: MAP+ICO+Weltpalette laden, komplette Map einmalig vorrendern,
Kamera blittet 320x176-Ausschnitt (HUD 320x24 darunter, wie Original).
- Kollision: MAP-ctype Bit 32 = solide (40=Boden, 32=Fuellung; empirisch
an der Spawn-Plattform verifiziert).
- Tony: TONY.BOB (53 Frames; 8-Phasen-Gehzyklus, gerade=links/ungerade=
rechts), AABB-Physik gegen das Tile-Grid, laufen/springen/ducken,
Fusspunkt-basiert. Physikwerte v1 nach Gefuehl (Feinschliff nach Test).
- HUD-Nachbildung (Keks/Item/Score/Herzen/Leben/Uhr 10:00-Countdown) mit
FON_1B-Ziffern; GAMEBAR-Icons geladen (Original-Ziffern-Palette unklar).
- Levelmusik: ONGAME2 Song 0 als v1-ANNAHME (nach Gehoer korrigieren, wie
beim Factor5-Sound); wird im Audio-Preload mitgerendert.
- ESC -> zurueck zur Karte (Titelmusik loopt wieder), Fenster-X -> Ende.
Verifiziert: E2E unter Xvfb mit gehaltenen XTEST-Tasten -- laufen (Kamera
scrollt), springen, Plattformkante runterfallen, unterm Brueckenbogen
zurueck, ESC->Karte->Menue->QUIT rc=0. Level-Standbild deckungsgleich zur
DOSBox-Referenz. --once-Regression exit 0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Per DOSBox-Referenzaufnahmen (Xvfb + XTEST-Tastensimulation) den kompletten
Original-Menuefluss erfasst und nachgebaut:
- ESC am stehenden Titelbild oeffnet das Hauptmenue (Original-Verhalten --
Space/Return tun dort nichts, per Einzeltasten-Sessions verifiziert; das
Original zeigt auch nach 115s passiv keinen Attract-Loop).
- Hauptmenue: HIGHSCORES/ANLEITUNG/OPTIONEN/START/QUIT in roter FON_2-
Schrift, Default-Auswahl START, der selektierte Eintrag BLINKT (so zeigt
das Original den Cursor). PARTY1/PARTY2-Charaktergruppen links/rechts,
Credits-Ticker in gelber FON_1-Schrift unter der Box.
- OPTIONEN: MUSIK EIN/AUS (wirkt auf pygame.mixer.music), EFFEKTE EIN/AUS
(Flag fuer spaeteres Gameplay), EXIT.
- ANLEITUNG: gelbe Texttafel (Original-Joystick-Text auf Tastatur uebertragen).
- HIGHSCORES: Tabelle NAME/SCORE/ITEMS/LEV mit den Original-Defaults.
- START: Weltkarte (KARTE.PCC, kompletter Screen) -- v1 statisch, Taste
zurueck ins Menue; Levelauswahl/Animationen folgen mit dem Gameplay.
- QUIT: Programm-Ende.
Technik (game/menu.py):
- BitmapFont-Parser fuer die Original-Fonts: FON_1/FON_1B (9x7-Zellen,
8px-Vorschub -- nur so passen die 32-Zeichen-Zeilen der Anleitung in die
Box) und FON_2 (16x15-Zellen, 3 Reihen). Outline-Rendering fuer die gelbe
Schrift (Original zeichnet sie ueberall mit schwarzem Rand).
- PARTY-Sprites via make_border_bg_transparent freigestellt (papierweisser
BG wie bei den Rauser-Assets -- ein Schwarz-Replace loescht faelschlich
die Konturen, per Vergleichsrender nachgewiesen und verworfen).
- intro.py: Zustandsautomat Titelbild <-> Menue <-> Weltkarte; wait_for_key
unterscheidet jetzt Fenster-X ('quit') von Taste ('key').
Verifiziert: End-to-End-Lauf des Remakes unter Xvfb mit echten XTEST-Tasten
-- Intro -> ESC -> Menue -> START -> Karte -> zurueck -> Optionen -> Anleitung
-> Highscores -> QUIT beendet sauber (rc=0); alle Screens als Screenshots
gegen die DOSBox-Referenz geprueft. python -m game --once weiterhin exit 0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Stefans Meldung "Factor5-Zeit zu kurz, Soundfile nicht ganz abgespielt" -- die
Ursache lag im Renderer: real_song_end markiert nur das Ende der TRACK-SEQUENZ
(2.4s), die dann noch klingenden Samples wurden hart abgeschnitten.
- render_tfmx.c: neues optionales 6. CLI-Arg tail_max_seconds. Im Tail-Modus
wird loop_mode=0 gesetzt -- tfmx.h laesst den Sequencer bei song_end dann
STEHEN (kein Restart, keine neuen Noten), waehrend die Paula-Voices weiter
ausklingen. (Erster Versuch ohne loop_mode-Stopp nahm stattdessen die
naechste Loop-Iteration auf -- per RMS-Selbstaehnlichkeit nachgewiesen.)
Tail endet bei ~300ms Stille oder tail-Limit; bei Limit-Ende (loopende
Samples ohne natuerliches Ende) wird ein 600ms-Fade-out angewendet.
- Factor5 ("Brausen") loopt auf Paula-Ebene endlos -> Tail 2.6s => Gesamt
exakt 5.0s (DOSBox-Messung ~4.8s Screendauer, Stefans "ca. 5 Sekunden"),
sauber ausgeblendet. Rauser-Sting endet natuerlich bei 2.34s.
- audio.py: tail_seconds-Parameter, Cache-Suffix _tail (alte abgeschnittene
Caches greifen nicht mehr). intro.py: Jingles mit Tail, Titelmusik bewusst
ohne (exakter Loop-Punkt-Schnitt fuers nahtlose pygame-Loopen).
Screen haelt weiterhin exakt Songlaenge (jetzt 5.0s), verifiziert: WAV klingt
aus (RMS 2065->261), --once headless exit 0.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Stefan-Frage "hatte das Titelbild nicht bessere Aufloesung?" -- ja, bestaetigt.
Die 4 Quadranten KELL256A-D (je 160x240 nativ) wurden bisher auf halbe Hoehe
(160x120) gestaucht -> 320x240, also die halbe vertikale Aufloesung verworfen
(gleiche Fehlklasse wie der Rauser-0.5x-Downscale). Ein RMSE-Vergleich der
beiden Varianten gegen die echte DOSBox-Referenzaufnahme belegt eindeutig die
volle Variante:
voll (320x480, anamorph angezeigt): RMSE 0.014
halbiert (320x240): RMSE 0.083 (6x schlechter)
Fix: build_title_quadrants nutzt die nativen 160x240-Quadranten -> 320x480-
Bild; angezeigt wird es anamorph auf die volle Fenstergroesse gestreckt
(_blit_title: 320x480 -> 960x720, x3 Breite / x1.5 Hoehe), womit alle 480
Zeilen erhalten bleiben. render_title_wipe_frame arbeitet automatisch bei
320x480 (Hoehe aus get_height()). pcc_surface_half_height entfernt (ungenutzt).
Verifiziert: neues Titelbild sichtbar schaerfer, deckungsgleich zur Referenz;
python -m game --once (headless) exit 0.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Keine Endlosschleife mehr: nach der Titelbild-Animation bleibt das fertige,
voll-farbige Titelbild STEHEN und die Titelmusik loopt weiter, bis Leertaste
oder ESC das Programm beendet (neue wait_for_key()). run_once() laeuft nur
noch einmal; scene_title haelt am Ende auf Tastendruck (hold_forever), --once
haelt stattdessen kurz (fuer headless/Tests).
- ALT+ENTER schaltet zwischen Fenster- und Vollbildmodus um (SCALED-Display
skaliert das 960x720-Logikbild sauber hoch). Zentrale Event-Behandlung in
_process_event(); Zeichenroutinen holen die aktuelle Surface per
pygame.display.get_surface(), damit das Neuerzeugen des Display-Modes beim
Umschalten keinen veralteten Screen-Bezug hinterlaesst (screen-Parameter aus
den Scenes entfernt).
- Vollbild-Zustand wird in kelloggs.ini gemerkt (load/save_fullscreen_pref) und
beim naechsten Start wiederhergestellt; ohne kelloggs.ini = Fenstermodus.
kelloggs.ini ist gitignored (pro-Rechner-Laufzeitzustand).
Verifiziert (headless): Config load/save, Alt+Enter-Toggle, Space/ESC,
wait_for_key(Space)->quit; python -m game --once exit 0 in ~17s.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Referenzaufnahmen aus DOSBox (Xvfb) gemacht und danach:
- Rauser-Aufloesung gefixt: die nativen PCC-Assets werden jetzt EINMAL direkt
auf Endgroesse hochskaliert (Nearest) und der Screen direkt in Fenster-
aufloesung gerendert -- statt vorher 0.5x-Downscale (verwirft Pixel) + x3-
Upscale ueber eine 320er-Zwischenleinwand. Gleiche Groesse wie bisher (~33%
Bildbreite, gegen Referenz gemessen), aber gestochen scharf. Zusaetzlich das
tuerkise "!"-Kaestchen nachgebaut (im Original Engine-gezeichnet, in keinem
Asset enthalten).
- Titelbild-Reveal: Grau/Entsaettigung raus (Stefan "das gray raus"); die
Scanlines auf der unteren Haelfte loesen sich jetzt von der Mitte nach unten
auf ("scanlines ab der mitte getrennt weg") statt gleichmaessig auszufaden.
- Factor5: Logo haelt exakt so lange wie sein Sound (TITEL2 Song 1) spielt,
dann weiter zu Kellogg's.
- Leertaste ueberspringt jetzt den aktuellen Intro-Screen, ESC beendet das
ganze Intro (wait_or_skip gibt 'quit'/'skip'/None; run_once ist in Scenes
zerlegt).
HANG-FIX (dabei gefunden): das kompilierte render_tfmx-Binary war veraltet
(vor dem Song-Index-Feature aus render_tfmx.c gebaut) und renderte TITEL2 Song1
mit 180s statt 2.4s -- gekoppelt an die neue "Factor5-Dauer = Songlaenge"-Logik
haette das Intro 3 Minuten eingefroren. Fixes: audio._ensure_binary() baut jetzt
neu, wenn die Quelle neuer ist als das Binary (verhindert stale Binary nach git
pull); zusaetzlich FACTOR5_MAX_SECONDS als Sicherheits-Obergrenze.
Verifiziert: python -m game --once (headless) exit 0 in ~30s; Rauser/Titelbild
visuell gegen die DOSBox-Referenz gegengeprueft.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- extracted_pre/ raus: der PCKELL.PRE-Workflow (split_pre.py) ist laengst durch
den DAT-Weg ersetzt, Ordner existiert nicht mehr, kein Code referenziert ihn.
- *.ppm raus: stammte aus dem alten ImageMagick-convert-Zwischenschritt; die
aktuellen Tools nutzen Pillow und erzeugen kein PPM mehr.
- extracted_dat/ mit Kurzkommentar versehen (was es ist).
Rest unveraendert und weiterhin korrekt (game/original/, audio_cache/,
tfmx_player-Binary, __pycache__).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
raw/ -> game/original/ (die Original-DOS-Dateien liegen jetzt neben dem Code,
der sie liest). Bleibt gitignored -- ist das Original-Spiel selbst, gehoert
nicht ins Repo.
Nachgezogen:
- Default-DAT-Pfad in game/intro.py, tools/dat_extract.py, tools/render_assets.py
-> game/original/PCKELL.DAT (KELLOGG_DAT-Override unveraendert).
- .gitignore: raw/ -> game/original/.
- Docstrings (game/audio.py, game/__init__.py), dosbox/dosbox.conf-Mountpfad,
README-Struktur/Verweise angepasst.
tfmx_player: KEINE Aenderung -- der Quellcode ist bereits getrackt (benoetigt),
nur das kompilierte Binary render_tfmx bleibt bewusst gitignored (plattform-
spezifisch, wird von build.sh automatisch neu gebaut).
Verifiziert: python -m game --once (headless) exit 0 mit neuem Pfad.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
audio/, png_out/, render_out/ nach preview/ verschoben -- das sind reine
Ansichts-/Archiv-Ausgaben (aus PCKELL.DAT gerendert), keine Laufzeit-
Abhaengigkeit. Das Spiel dekodiert zur Laufzeit alles selbst on the fly aus
raw/PCKELL.DAT; die Musik rendert game/tfmx_player/ frisch nach audio_cache/,
preview/audio/ wird vom Spiel nicht gelesen.
- render_assets.py: Default-Ausgabepfad -> preview/render_out/.
- README.md: Struktur-Abschnitt auf preview/ aktualisiert.
- tfmx_player/ bleibt bewusst in game/ (Laufzeit-Audio-Decoder, Gegenstueck
zu game/formats.py -- kein Dev-Tool).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- audio/: alle 25 gerenderten Musik-WAVs (TITEL/TITEL2/ONGAME2 inkl. aller
Songs) + .SAM/.TFX-Quellen. Bewusst mit eingecheckt: freies Werbespiel,
innerhalb DE frei kopierbar, WAVs nur aus PCKELL.DAT extrahiert.
- Umbenannt von aria_kelloggs_soundfiles_voll/ -> audio/.
- Entfernt (nicht in git): veralteter Snapshot aria_kelloggs_extrahierte_assets/
(+.zip) sowie redundantes aria_kelloggs_soundfiles_voll.tar.gz.
- audio_cache/ bleibt gitignored (Laufzeit-Cache, von intro_sequence.py
regeneriert).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Repo-Hygiene-Fund (23.07.2026): tools/tfmx_audio.py reicht song_index bereits
seit dem Factor5-Sound-Fix als 5. CLI-Arg an render_tfmx durch (siehe dessen
Docstring), aber die zugehoerige C-Quelle war nie committed -- nur lokal auf
der VM in /home/aria/kellogg_remake gebaut. Ein frischer Checkout+Build von
origin/master haette also render_tfmx OHNE song_index-Unterstuetzung erzeugt:
jeder render_wav(..., song_index=N)-Aufruf (z.B. TITEL2 Song 1 fuer den
Factor5-Sound) waere klanglich stillschweigend auf Song 0 zurueckgefallen --
kein Crash, aber ein 1:1-Port-Bruch, den man erst durchs Hoeren gemerkt haette.
Ursache: parallel zur Bugfix-Session ist zusaetzlich ein zweiter, veralteter
Git-Checkout unter /tmp entstanden (tmpfs, ueberlebt keinen Reboot) und dort
unabhaengig weitergearbeitet worden, ohne vorher zu fetchen -- dadurch ist
lokal vs. Remote auseinandergelaufen. Nach Abgleich: die tatsaechliche
Arbeitskopie auf der VM (/home/aria/kellogg_remake) war fuer alle anderen
Dateien bereits 1:1 identisch mit origin/master; nur diese eine C-Datei fehlte
im Repo. Die verwaisten, ueberholten Doppel-Commits im tmpfs-Checkout wurden
verworfen (kein Datenverlust, deren Inhalt war ein aelterer, bereits
ueberholter Zwischenstand).
Stefans Meldung 'nur noch ein schwarzes Bild, verschiebe ich das Fenster
wird der Desktop reingerendert, das Programm haengt' war real (per
Xvfb-Test verifiziert). Ursache: render_wav() rief render_tfmx als
blockierenden subprocess.run() auf -- bei einem frischen, ungecachten Song
(v.a. TITEL, ~109s) dauerte das reproduzierbar ~14s ohne dass die
pygame-Eventloop weiterlief, das OS stufte das Fenster dann als haengend
ein.
Fix: preload_all_audio() rendert alle benoetigten Songs jetzt EINMALIG vor
der eigentlichen Sequenz, per Hintergrund-Thread + responsivem
Ladebildschirm (render_audio_with_loading). run_once()/run_rauser() greifen
danach nur noch auf fertige WAV-Pfade zu, nie mehr Live-Rendering im
Hauptloop. Verifiziert per Xvfb-Testlauf: laeuft jetzt sauber durch.
Pixelvermessung von Stefans Referenz-Screenshot widerlegt die letzte
"native Groesse ist richtig"-Annahme -- das Logo ist im Original klein
(~34% Bildbreite), nicht bildschirmfuellend. Der eigentliche Bloedsinn war
smoothscale() (bilinear, verwaescht Pixel-Art), nicht die 0.5x-Groesse
selbst. Fix: 0.5x beibehalten, pygame.transform.scale() (Nearest-Neighbor)
statt smoothscale().
Factor5 spielte bisher faelschlich ONGAME2 (~123s Level-Musik) ab. Fund:
TFX-Module buendeln mehrere Songs (v_songs[]) -- TITEL2 hat 2 (Song0 =
2.04s Rauser-Sting, Song1 = 2.40s), TITEL 3, ONGAME2 sogar 14. TITEL2-Song1
passt laenge-maessig exakt zu "nur ein bisschen laenger als der
Rauser-Sound" -- jetzt der Factor5-Sound, feste 5s Anzeigedauer.
- intro_sequence.py, tfmx_audio.py, render_assets.py, dat_extract.py:
/home/aria/kellogg_remake/... durch PROJECT_ROOT-relative Pfade ersetzt
(mit optionalem ENV-Override), laeuft jetzt von jedem Checkout aus.
- Rauser-Logo: war 1:1 nativ gezeichnet (viel zu gross) und weisser statt
grauer Hintergrund. Per frischer DOSBox-Referenzaufnahme (Xvfb-Screenshot-
Serie) neu vermessen: 0.5x Skalierung, Slide-in-Animation (RAUSER-Box von
links, "!"-Box von oben, ADVERTAINMENT steht fest), Sound-Sting (TITEL2,
einmalig) bei Ankunft, danach Fade weiss->grau.
- Titelbild: fruehere Annahme (4 Quadranten voll gestapelt = 320x480) war
falsch und die Ursache fuer den gemeldeten Squish-Bug. Per Pixel-
Rekonstruktion verifiziert: jeder Quadrant wird nur auf halber HOEHE
(160x120 statt 160x240, Breite bleibt nativ) im 2x2-Raster angeordnet ->
korrektes 320x240-Bild. Zusaetzlich neu entdeckter und nachgebauter
Scanline/Graustufen-Reveal-Effekt auf der unteren Bildhaelfte.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Regression gefunden+gefixt: pcc_to_png.py war durch einen frueheren Commit
versehentlich auf den kaputten Hand-RLE-Decoder zurueckgefallen (der
ImageMagick-Fix ging verloren). Jetzt: kellogg_formats.load_pcc() nutzt
Pillows PCX-Decoder direkt, kein eigener RLE-Code mehr im Projekt. Alle
77 PCC neu gerendert, AE=0 (pixelidentisch) zu den alten guten PNGs.
- Boot-Sequenz per echter DOSBox-Screenshot-Serie (0.3s-Intervall) vermessen:
Rauser-Karte -> Factor5-Logo (statisch, keine Animation) -> Kellogg's-Logo
mit Palette-Fade des "praesentiert"-Texts (Indizes 34/42/43/44/45) ->
Titelbild "Tony & Friends in Kellogg's Land" mit echtem Vorhang-Wipe-Effekt
(320x480 aus 4 Quadranten KELL256A-D, obere Haelfte faehrt runter, untere
hoch, treffen sich in der Mitte). Korrigiert eine fruehere Fehlannahme:
der Wipe sitzt auf dem TITELBILD, nicht auf dem Kellogg's-Markenlogo.
- tools/intro_sequence.py: erster spielbarer pygame-Meilenstein, baut die
komplette Sequenz nach (Asset-Loading, Palette-Rendering, Timing, echter
Palette-Fade, Wipe-Effekt). Headless getestet, visuell verifiziert.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- PCKELL.DAT ist der eigentliche Asset-Container (Index am Dateiende),
nicht PCKELL.PRE -- alle 178 Assets fehlerfrei extrahierbar
(tools/dat_extract.py, tools/kellogg_formats.DATContainer)
- BOB (Sprites): self-modifying x86 draw-code decodiert, alle 32 Dateien /
462 Frames korrekt (Tony, Gegner, Items) -- tools/kellogg_formats.parse_bob
- ICO (16x16 EGA-Tilesets) und MAP (Level-Grids, big-endian) decodiert und
gerendert -- alle 19 ICO- und 22 MAP-Dateien fehlerfrei, Level W1L0 sieht
korrekt aus (Haeuser, Baeume, Berge an den erwarteten Stellen)
- Palette-Regeln (BOB/ICO/MAP -> passende PCC) aus der C#-Referenz
uebernommen und in Python neu implementiert
- Aufraeumen: PRE-basierte Extraktion (split_pre.py, extracted_pre) und
alle Blindflug-Explorationsskripte aus der ersten BOB-Sackgasse entfernt,
VM-Arbeitsverzeichnis von Debug-Screenshots befreit
- pcc_to_png.py aktualisiert (Xmax/Ymin-Dimensionsfix, jetzt visuell
gegen DOSBox-Referenz verifiziert statt nur behauptet)
Offen: ARE (Kollisionszonen, auch Referenz-Projekt unvollstaendig) und
SAM/TFX (TFMX-Sound) noch nicht angefasst.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Beide vorherigen Hand-RLE-Decoder (Row-Reset und kontinuierlich) waren
trotz gegenteiliger Behauptung sichtbar kaputt (Bildinhalt verschoben/
dupliziert) -- Stefan hat das im gepushten Repo sofort wieder gesehen.
Format-Referenz https://github.com/movAX13h/tony-and-friends-in-kelloggs-land
bestaetigt .PCC = Standard-PCX v5. Fix: convert pcx:datei.PCC statt
eigenem RLE-Parser. Verifiziert (visuell, nicht nur Byte-Stats) gegen
echte DOSBox-Screenshots -- KARTE.PCC und KELLOGGS.PCC jetzt wirklich
korrekt. Alle 77 PNGs neu erzeugt.
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)
- tools/pcc_to_png.py: PCX-artiger Decoder fuer die 77 PCC-Vollbild-/Logo-
Dateien, mit Fix fuer falsch gelesene Width/Height (muss aus Xmax-Xmin+1/
Ymax-Ymin+1 statt Offset 12-15 berechnet werden)
- tools/split_pre.py: Extrahiert alle 181 Dateien aus PCKELL.PRE
- png_out/: alle 77 konvertierten PNGs (Arbeitsergebnis, kein Original-Asset)
- NOTES.md: vollstaendiger Analyse-Stand inkl. offener Punkte
- dosbox/dosbox.conf: funktionierende Testkonfiguration (IRQ-Fix)
Bewusst ausgeschlossen (.gitignore): raw/ und extracted_pre/, da Original-
Spieldaten von Kellogg's Tony and Friends (1994), keine Weiterverbreitung.