Commit Graph
15 Commits
Author SHA1 Message Date
duffyduckandClaude Fable 5 0bb66b73a4 Level-Feedback: Laufrichtung, Schraegen-Kollision, HUD, Rennen
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>
2026-07-25 10:01:14 +02:00
duffyduckandClaude Fable 5 973e290cf6 LEVEL 1 SPIELBAR: game/level.py -- Tiles, Kamera, Tony-Physik, HUD, Musik
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>
2026-07-25 01:17:44 +02:00
duffyduckandClaude Fable 5 4517efbdf8 NOTES.md: Factor5-Tail + Menuesystem-Session dokumentiert; README: raw/-Restverweis
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 23:13:49 +02:00
duffyduckandClaude Fable 5 c8f7d4d990 Hauptmenue, Optionen, Anleitung, Highscores und Weltkarte implementiert
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>
2026-07-24 23:12:52 +02:00
duffyduckandClaude Fable 5 949a7eeda2 Factor5-Sound vollstaendig: Ausklang-Tail im TFMX-Renderer (loop_mode-Stopp + Fade)
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>
2026-07-24 22:22:31 +02:00
duffyduckandClaude Opus 4.8 ccad606a43 Titelbild in voller Aufloesung (320x480 anamorph statt halbiert)
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>
2026-07-24 01:59:19 +02:00
duffyduckandClaude Opus 4.8 95e5b1edb4 Intro: Endlosschleife raus, Alt+Enter-Vollbild, kelloggs.ini
- 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>
2026-07-24 01:49:47 +02:00
duffyduckandClaude Opus 4.8 7aea2fac26 Intro gegen echte DOSBox-Referenz korrigiert + Leertaste-Skip
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>
2026-07-24 01:39:28 +02:00
duffyduckandClaude Opus 4.8 e7d95190eb .gitignore: veraltete Eintraege entfernt
- 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>
2026-07-24 00:43:22 +02:00
duffyduckandClaude Opus 4.8 4e4110b67b Original-Spieldateien nach game/original/ verschoben
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>
2026-07-24 00:38:59 +02:00
duffyduckandClaude Opus 4.8 327236e277 preview/: vorgerenderte Archiv-Assets aus dem Wurzelverzeichnis gebuendelt
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>
2026-07-24 00:33:26 +02:00
duffyduckandClaude Opus 4.8 85404c91f4 Projektstruktur: game/-Package angelegt, README ergaenzt
Laufzeit-Code vom Dev-Werkzeug getrennt:
- game/: das eigentliche Spiel, startbar per `python -m game [--once]`.
  - formats.py  (war tools/kellogg_formats.py) -- Asset-Parser, Kern-Bibliothek
  - audio.py    (war tools/tfmx_audio.py)      -- TFMX-Musik-Wrapper
  - intro.py    (war tools/intro_sequence.py)  -- Boot-/Intro-Sequenz
  - tfmx_player/(war tools/tfmx_player/)        -- MIT-C-Renderer
  - __init__.py / __main__.py fuer `python -m game`
- tools/: nur noch Dev-Werkzeuge (dat_extract, pcc_to_png, render_assets),
  importieren jetzt aus game.formats.
- README.md: Ueberblick, Start, Struktur, Voraussetzungen, Rechtliches.
- .gitignore: tfmx_player-Binary-Pfad auf game/ nachgezogen.

Intro laeuft unveraendert (headless-Smoke-Test `python -m game --once` exit 0).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-24 00:29:03 +02:00
duffyduckandClaude Opus 4.8 3fe92d01b8 Original-Installer + deutsches Handbuch ins Repo aufgenommen
- Tony-Friends-in-Kellogg-s-Land_DOS_DE_Installer-Alt-1.zip: alternativer
  DOS-Installer (DE).
- Tony-Friends-in-Kellogg-s-Land_Manual_DOS_DE.pdf: deutsches Handbuch
  (Steuerung/Story-Referenz).
Gleiche Begruendung wie audio/: freies Werbespiel, innerhalb DE frei kopierbar.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-24 00:16:09 +02:00
duffyduckandClaude Opus 4.8 8b709f1cc3 NOTES.md: Cleanup-Eintrag (Duplikate entfernt, Soundfiles ins Repo)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-24 00:16:09 +02:00
duffyduckandClaude Opus 4.8 527bac1333 Soundfiles (gerenderte TFMX-WAVs) ins Repo aufgenommen, Duplikate aufgeraeumt
- 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>
2026-07-24 00:15:11 +02:00