78 Commits

Author SHA1 Message Date
Matteo Benedetto e476638329 Remove broken subtitle from game page 2026-07-01 16:41:52 +02:00
Matteo Benedetto 038d4a4d86 Adaptive mobile layout: fluid canvas, responsive touch buttons, ctrl-row grouping 2026-07-01 16:16:58 +02:00
Matteo Benedetto 36e59a9e6b Fix keymap: B=Backspace, Select=Shift (WasmBoy native mapping, not X/Space) 2026-07-01 15:29:09 +02:00
Matteo Benedetto 5ea4ce3c16 Fix: dispatch synthetic keys on window (where WasmBoy listens), add keyCode for legacy compat 2026-07-01 15:22:55 +02:00
Matteo Benedetto c11dbc208d Mobile: touch controls with visual feedback, landscape support, larger hit areas 2026-07-01 15:17:47 +02:00
Matteo Benedetto edc093b633 feat: add spike assets and implement version 1.0 release documentation 2026-07-01 15:06:22 +02:00
Matteo Benedetto 1aac416ba7 Revert "Stop tracking ROM binary; release will be created via API"
This reverts commit 919d3b7ddc.
2026-07-01 14:37:52 +02:00
Matteo Benedetto 919d3b7ddc Stop tracking ROM binary; release will be created via API 2026-07-01 14:12:02 +02:00
Matteo Benedetto 902623dc8d Include ROM for GitHub Pages deployment 2026-07-01 14:08:35 +02:00
Matteo Benedetto 532396e95f Add GitHub Pages site with wasmboy WebAssembly emulator 2026-07-01 14:03:25 +02:00
Matteo Benedetto 73eb61ffed README: sposta hello_iso_gb.png nella sezione Coordinate isometriche 2026-07-01 12:01:25 +02:00
Matteo Benedetto 8b07299fe9 README: mostra hello_iso_gb.png come immagine inline 2026-07-01 11:59:04 +02:00
Matteo Benedetto 7ff553992c README: title banner + nota screenshot di sviluppo 2026-07-01 11:56:49 +02:00
Matteo Benedetto d0f1f3d054 README: aggiungi sezione Schermate con title/death/going-deeper 2026-07-01 11:49:18 +02:00
Matteo Benedetto d079f96208 Aggiungi sezione Autore e Release info al README; release target nel Makefile v1.0 2026-07-01 11:24:36 +02:00
Matteo Benedetto a8a6a321db Aggiungi suono di caduta nel vuoto
Quando il giocatore cade per un salto fallito:
- CH1: pitch sweep verso il basso (parte acuta, scende rapidamente)
- CH4: rumore medio-basso (colpo di caduta)

Effetto 'Wile E. Coyote': tono discendente + impatto.
2026-06-26 13:17:08 +02:00
Matteo Benedetto 114dadd050 Riduci caduta a pochi pixel (non si sovrappone ai tile)
fall_offset: max 8 step (era 32), mezzo pixel per step (era 2x).
Caduta totale: ~4 pixel invece di 64. Subtile, non copre i tile vicini.
2026-06-26 13:12:01 +02:00
Matteo Benedetto 1422edc8ca Fix caduta: usa DIV_REG per casualita', logica senza variabile locale
L'ottimizzatore SDCC eliminava la variabile locale will_fall (dead code
elimination). Riscritto senza variabile intermedia: fall_offset viene
impostato direttamente nel ramo if/else. Usa DIV_REG (registro hardware
che cambia ogni ciclo) invece di rand() per casualita' migliore.
2026-06-26 13:08:15 +02:00
Matteo Benedetto 14eb7893f7 Fix overflow calcolo probabilita' caduta (int 8-bit su GB)
Il calcolo (60 - stamina) * 255 overflow su 8-bit (int del Game Boy).
Cast a uint16_t per il calcolo corretto. Ora il rischio di caduta
funziona: 30 stamina = 50% caduta, 0 stamina = 100% caduta.
2026-06-26 13:04:28 +02:00
Matteo Benedetto 30111d6316 Aggiungi salto rischioso: stamina < 60 = rischio caduta nel vuoto
Ultima meccanica di gameplay: se hai meno di 60 stamina puoi comunque
tentare il salto, ma rischi di cadere nell'abisso. La probabilita' di
caduta e' proporzionale a quanto stamina ti manca da 60:
- 60 stamina: 0% caduta (salto sicuro)
- 30 stamina: 50% caduta
- 0 stamina: 100% caduta

Se cadi: il giocatore salta verso la cella intermedia (vuoto) invece di
quella di atterraggio, poi cade velocemente verso il basso (animazione
fall_offset, 2x pixel per frame) e game over con la schermata di morte.

Differenza chiave: il salto sicuro atterra a distanza 2; il salto fallito
si ferma a distanza 1 (sopra l'abisso) e cade.
2026-06-26 12:49:08 +02:00
Matteo Benedetto 768429a7f9 Aggiungi animazione di discesa nella botola
Quando il giocatore raggiunge la botola (vittoria/finale), invece di
pulire subito lo schermo, il giocatore scende di pochi pixel verso il
basso (descend_offset) per 30 frame prima che appaia la schermata
Going Deeper / finale.

- descend_offset: variabile globale, incrementata durante game_over_timer
- render.c: y_offset negativo (discesa graduale, >>1 = meta' pixel)
- player_logic.c: rimossa la dissolvenza immediata, avviata l'animazione
- engine.c: animazione durante il timer, max 12 step (~6 pixel)
2026-06-26 12:44:00 +02:00
Matteo Benedetto de55ba092e Evita che le istruzioni riappaiano ripetendo il livello 1
Aggiunge hint_shown_once: le istruzioni appaiono solo la prima volta
che si gioca il livello 1. Se il giocatore muore e riprova, o torna al
titolo e ricomincia, le istruzioni non si rimostrano.
SELECT in gioco rimane disponibile per rivederle quando si vuole.
2026-06-26 12:24:04 +02:00
Matteo Benedetto f0a4647752 Title music: brano d'inseguimento veloce e complesso
Sostituisce il lamento lento (30 frame/nota, cupo) con un brano
d'azione veloce (8 frame/nota, ~7.5 note/sec):
- Melodia: arpeggi ascendenti D-F-A-D, salita cromatica verso climax,
  accordo D5 ripetuto (colpo di caccia), discesa drammatica
- Basso: ottavi pulsanti (inseguimento), pedale di D al climax
- Percussioni: kick sui downbeat + hi-hat sugli upbeat (ogni 2/4 step)
- Envelope staccato/urgente (fade down veloce)
- 128 step (era 112), loop infinito

Aggiunge note mancanti: N_D2, N_DS3, N_DS4.

Stile: il mostro ti insegue — tensione crescente, climax, arresto.
2026-06-26 12:19:38 +02:00
Matteo Benedetto 220ab389e7 Aggiungi schermata introduttiva alla storia (dopo START, prima del gioco)
Premendo START nel menu titolo appare l'introduzione narrativa:
'You were walking alone in the dead of night. Without warning, an
unnatural darkness consumed the world around you. Your only comfort
is a faint torch. The path behind you is gone. Descend deeper into
the unknown.'

Si chiude con un tasto qualsiasi, poi avvia la partita.
Usa il Window layer come le altre schermate testuali.

Ripristina anche death.c e instructions.c dai commit precedenti.
2026-06-26 12:11:25 +02:00
Matteo Benedetto 7757e414a4 Aggiungi schermata crediti (SELECT nel menu titolo)
SELECT nel menu titolo mostra i crediti: titolo, autore (Matteo B.),
strumenti (GBDK 2020, SDCC SM83, PyBoy). B per tornare al titolo.
Usa il Window layer (come le istruzioni) per non corrompere il BG map.

Ricrea i file src/screens/ rimossi da make clean (death.c,
instructions.c, screens.c) e aggiunge credits.c.
2026-06-26 11:12:29 +02:00
Matteo Benedetto 402b713477 Aggiorna sfondo del titolo con bg.png modificato dall'utente
L'utente ha modificato assets/bg.png. Convertito in PNG indicizzato
2-bit con la palette GB (4 colori) e rigenerato title_bg.c/.h con
png2asset. 205 tile unici (era 196).

ROM: 28198/32768 byte usati (86%), 4570 byte liberi.
2026-06-25 23:59:15 +02:00
Matteo Benedetto d34887e511 Aggiungi script Python per renderizzare la musica del finale in WAV
scripts/render_finale_wav.py estrae le sequenze CH1+CH2 dal sorgente
sound.c, le converte in frequenze (formula Game Boy: 131072/(2048-value)),
sintetizza 3 tracce (melodia onda quadra + basso + rintocchi LFSR) con
envelope del Game Boy, le mixa e scrive un file WAV 16-bit mono 22050Hz.

Output: 44.8 secondi (192 step x 0.233s), un loop completo del lamento
tragico in D minore.

Uso: python3 scripts/render_finale_wav.py [output.wav]
2026-06-25 23:42:34 +02:00
Matteo Benedetto d786805cab Riattiva la musica del finale (lamento in D minore, 192 step)
Ripristina gli array finale_ch1_seq[192] e finale_ch2_seq[192] e la
funzione play_finale_step completa (CH1 melodia, CH2 basso, CH4 rintocchi)
dal commit 0e2e383. La musica era stata rimossa in 5569de8 per fare
spazio alle istruzioni; ora che la ROM ha 4714 byte liberi (14%)
c'e' spazio sufficiente per reintrodurla.

Il finale suona il lamento tragico discendente A5 -> D3 -> C2 -> abisso,
in loop infinito.
2026-06-25 23:34:20 +02:00
Matteo Benedetto 89e9bb42d5 Fix cheat e level cap: SELECT+A+B al livello 8 va al finale
Il cheat SELECT+A+B ora controlla il livello: se >= 8 triggera
game_over=3 (finale tragico) invece di game_over=2. Aggiunge anche
un cap level < 8 nel level++ per evitare overflow al livello 9.
2026-06-25 23:28:13 +02:00
Matteo Benedetto 1f22280723 Cheat SELECT+A+B per vincere livello + ricrea file screens mancanti
Aggiunge un cheat code in engine_update: premendo SELECT+A+B insieme
durante il gameplay si vince il livello corrente (game_over=2, Going
Deeper). Utile per testare rapidamente le schermate di transizione e
avanzare fino al finale (livello 8).

Ricrea i file src/screens/ che erano stati rimossi (death.c,
going_deeper.c, finale.c, screens.c) e aggiorna instructions.c con il
testo allineato allo screenshot dell'utente (FIND THE HATCH, A+DPAD
JUMP, B+DPAD RUN, PRESS B TO CONTINUE).
2026-06-25 23:19:41 +02:00
Matteo Benedetto 36951617d9 Estrai schermate testuali in src/screens/ (un file per schermata)
Ogni schermata testuale (font IBM) ora vive in un file separato nella
sottocartella src/screens/:
- screens.h: dichiarazioni + helper (ending_puttext/putdigit)
- screens.c: implementazione degli helper condivisi
- instructions.c: schermata istruzioni (Window layer)
- death.c: schermata di sconfitta (game_over==1)
- going_deeper.c: transizione livello (game_over==2)
- finale.c: finale tragico (game_over==3, spoiler)

engine.c ora chiama show_instructions(), show_death(),
show_going_deeper(), show_finale() invece di avere il codice inline.
Il titolo resta un'immagine (title_bg.png), non testuale.
2026-06-25 22:43:50 +02:00
Matteo Benedetto fb22126458 Fix garbage dopo chiusura hint: usa Window layer invece di BG
Best practice GBDK: il Window layer ha un tile map separato (0x9C00)
rispetto al BG (0x9800). Usando set_win_tiles + SHOW_WIN per il testo
delle istruzioni, il BG map del gameplay non viene mai toccato.
Alla chiusura basta HIDE_WIN: niente garbage, niente flush differito.

Ripristino tile: set_bkg_data (maze) + set_sprite_data (player/enemy/
stamina/level) + draw_map + update_camera + update_player_sprite.
2026-06-25 22:31:28 +02:00
Matteo Benedetto d75a44c2d1 Aggiungi schermata istruzioni testuale (font IBM)
Schermata istruzioni mostrata all'inizio del livello 1, chiudibile con B,
ri-apribile in gioco con SELECT. Testo con font IBM (stesso pattern del
finale game_over==3 e della sconfitta game_over==1).

Contenuto: titolo, obiettivo (find the hatch), controlli (DPAD walk,
A jump abyss, B run), istruzioni di chiusura (press B, select help).

Per fare spazio: rimosso claimed.png (schermata di morte ora testuale
con lo stesso font, stesso pattern del finale).
2026-06-25 22:16:28 +02:00
Matteo Benedetto 1fecf81395 Add instructions.png asset (160x144 hint screen)
Immagine 2bpp con il testo delle istruzioni (controlli, obiettivo).
Non ancora integrata nel gioco (la ROM a 32KB e' piena). Da usare
quando si passera' a MBC5 banking (64KB) o si ottimizzera' il codice.
2026-06-25 21:55:47 +02:00
Matteo Benedetto 5569de864c Remove finale music from ROM (archived in assets/finale_music.txt)
The 192-step D minor lament for CH1+CH2 has been extracted to an external
text file (ignored from git) for preservation. The finale now plays dramatic
silence (channels off) - the tragic tone is already conveyed by the 'YOUR
TORCH HAS RUN OUT...' text on a black screen. Frees ~2KB of ROM space
for upcoming features (e.g. instructions screen).
2026-06-25 16:02:31 +02:00
Matteo Benedetto 0e2e383ad7 Rimuovi spoiler del finale dalla documentazione
Il testo del finale tragico ('YOUR TORCH HAS RUN OUT...') e' uno
spoiler che va scoperto giocando. Sostituito con 'messaggio tragico
(spoiler-free, da scoprire giocando)' in gameplay.md e nel report
tecnico. Le info tecniche (game_over=3, 192 note, musica dedicata,
BGP invertito) restano, ma il contenuto narrativo non viene rivelato.
2026-06-24 20:43:38 +02:00
Matteo Benedetto e5c37c7c86 Aggiorna e approfondisci tutta la documentazione
Riscritti tutti i file doc/ e README.md per riflettere lo stato attuale
del gioco (8 livelli, multi-nemico, corsa, finale tragico, musica
dedicata, fog scalabile, flush dinamico, claimed.png death screen, ecc.):

- index.md: nuovo indice con riferimenti ai 7 capitoli aggiornati.
- architecture.md: tabella moduli con righe, variabili chiave globals,
  pipeline asset, vincoli hardware (ROM/WRAM/VRAM/OAM).
- graphics.md: proiezione iso, fog scalabile (fog_radius), auto-tiling
  multi-pass, flush dinamico 16-righe con wrap, HUD stamina + livello.
- generation.md: DFS con stack WRAM, dimensioni crescenti 7->21, botola
  a distanza scalabile, spawn multi-nemico.
- gameplay.md: DAS, camminata, corsa, salto, stamina scalabile,
  progressione 8 livelli, schermate (death/going deeper/finale).
- ai.md: multi-entity (8 fantasmi), greedy, cooldown scalabile, hitbox,
  culling.
- audio.md: 4 canali APU, 5 tracce (title 112/3canali, gameplay 96,
  gameover 128, finale 192 loop, going deeper 96), SFX.
- AScreamFromTheDark_report.md: riscritto completamente (~200 righe),
  tutte le sezioni aggiornate, workaround storici, debiti tecnici.
- README.md: intro, caratteristiche, soundtrack, architettura, test.
2026-06-24 20:42:35 +02:00
Matteo Benedetto 3b72782225 Title screen: usa bg.png (2-bit) come sfondo del menu
Sostituito title_bg.png con bg.png quantizzato a 2-bit (160x144,
palette Game Boy). La schermata del titolo ora mostra il nuovo sfondo.
2026-06-24 20:31:44 +02:00
Matteo Benedetto c9bdef4094 Title music: brano complesso e ricco di pathos (112 note, 3 canali)
Riscritta completamente la title music. Ora e' un brano di 112 note
(~56 sec, in loop) su 3 canali invece del precedente semplice 32-note
su 2 canali:

- CH1 melodia: 112 note con envelope sostenuto (NR12=0x87, fade up
  lungo) per un suono haunting/cantabile. Progressione armonica ricca:
  Dm - Bb - F - C - Dm - A7(con C#, tensione) - Dm(climb al C5) -
  Gm - A7 - discesa cromatica finale nell'abisso.
- CH2 basso: linea indipendente (title_bass[112]) che segue gli accordi
  con movimento, non piu' semplice ottava sotto. Envelope deep plucked.
- CH4 noise: rintocchi sparsi (toll) ad ogni cambio d'accordo (ogni 8
  step) per atmosfera desolata stile Metroid II / Castlevania.

Struttura: intro sparso (Dm) - lamento (Bb-F-C-Dm) - tensione/climax
(A7 con leading tone, climb al C5) - crollo cromatico e discesa
nell'abisso (D3...A2).

Ispirazione: Castlevania (arpeggi gotici), Metroid II (desolazione
sparsa), Link's Awakening (melancolia onirica).
2026-06-24 20:27:42 +02:00
Matteo Benedetto 0a2757c03a Title music: lamento tragico discendente (piu pathos)
Sostituisco title_melody (32 note) con un lamento in 4 frasi da 8
note che scende da La3 fino a Mi2, con respiri (R) e salti
drammatici. Armonizza con la progressione Dm-C-Bb-A del finale,
impostando il tono sinistro del gioco fin dal menu. Le frasi:

1. Dm: A3 .. A2 (respiro)
2. C:  F3 .. A2 (caduta)
3. Bb: E3 .. A2 (sospeso, con Bb2)
4. A:  D3 .. E2 (abisso)

La nota finale E2 (Mi2) e' la piu' bassa della title music, dando
un senso di discesa definitiva. Verificato via PyBoy: entrambi i
canali (ch1 melodia + ch2 basso) attivi sul title screen.
2026-06-24 19:26:14 +02:00
Matteo Benedetto 3927c90f4c gitignore: ignora i file intermedi *.state di lcc
build/hello_iso.gb.state e' un file intermedio generato dal
compilatore lcc/SDCC; non deve essere committato. Rimosso dal repo.
2026-06-24 19:23:34 +02:00
Matteo Benedetto f4869c5ec6 Death screen: ricarica claimed.png modificata dall'utente
L'utente ha modificato nuovamente l'immagine claimed.png (160x144).
Riquantizzata a 2-bit palette GB e ricompilata. La schermata di morte
mostra la versione aggiornata.
2026-06-24 19:19:30 +02:00
Matteo Benedetto 6d20ef6ee5 Death screen: ricarica claimed.png a risoluzione originale 160x144
L'utente ha ricaricato l'immagine claimed.png a 160x144 (versione
originale, non croppata). Riquantizzata a 2-bit palette GB e ricompilata.
La schermata di morte ora mostra l'immagine intera invece della versione
128x96 centrata. Verificato via PyBoy: ROM 32KB, schermata mostra
l'arte completa.
2026-06-24 19:01:12 +02:00
Matteo Benedetto b4f22b7100 Death screen: usa assets/claimed.png; Going Deeper ora testuale
- assets/claimed.png (160x144, 2-bit GB) usata come schermata di morte al
  posto dello schermo nero. Il tile data e' caricato con set_bkg_data
  e la mappa 20x18 con set_bkg_tiles; il GAME OVER metasprite resta
  sovrapposto sopra l'immagine.
- Going Deeper (game_over==2) ora usa una schermata testuale col font
  IBM ('GOING DEEPER / LEVEL N') invece dell'immagine next_level.png.
  Necessario per ridurre l'occupazione ROM (la ROM era >32KB con
  title_bg + next_level + claimed + maze + tutto il resto) e far
  entrare la schermata claimed. Rimosso next_level.c/.h e l'asset.
- engine.c: nuovi helper ending_putdigit per scrivere una cifra;
  game_over==2/3 entrambi usano il font IBM per le schermate di
  transizione.
- Makefile: rimosso next_level da SRCS e dal clean; aggiunto
  claimed.png/png2asset/-c claimed.c.

Verificato via PyBoy: schermata di morte mostra l'immagine claimed
(sfondo nero + carta 128x96 centrata), going deeper mostra il testo
'GOING DEEPER / LEVEL 2'.
2026-06-24 16:58:16 +02:00
Matteo Benedetto 238bef9672 Finale music: loop infinito (il brano ricomincia dopo 192 step)
Il sequencer del finale (game_over==3) ora ricomincia da capo quando
finale_music_step raggiunge 192, cosi' la musica tragica continua a
suonare finche' il giocatore non preme START. Stesso loop applicato al
sequencer inline della test ROM (test_finale.gb).

Verificato via PyBoy: NR52 mostra ch1+ch2+ch4 attivi per 6000/6000 frame
(~100s), confermando che il brano suona continuamente sia nella ROM
principale sia nella test ROM.
2026-06-24 16:48:00 +02:00
Matteo Benedetto e805e6e3e6 test_finale: inline sequencer nel main loop per suonare SOLO il finale
Il test ROM precedente registrava play_music_tick come VBL e settava
game_over=3, ma il sequencer del finale non risultava udibile (suonava
invece la traccia di gameplay o altre). Per garantire che suoni solo la
musica del finale, il test ROM ora NON registra play_music_tick e pilota
direttamente play_finale_step dal main loop ogni 14 frame (inline
sequencer). Verificato via PyBoy: tutti e 3 i canali APU (CH1 melodia,
CH2 basso, CH4 rintocco) attivi per l'intero test.
2026-06-24 16:41:05 +02:00
Matteo Benedetto 962ec56d59 Add test_finale.gb: ROM che porta subito al finale per test rapidi
build/test_finale.gb mostra immediatamente la schermata finale (testo
tragico + musica del finale su tutti e 3 i canali) all'avvio, senza
dover completare gli 8 livelli. Premi START per uscire.

- src/test_finale_render.c: setup palette invertita, font IBM,
  scrittura del messaggio nel map_buffer, init audio + VBL +
  game_over=3/timer=0 per far partire il sequencer del finale.
- Makefile: nuovo target build/test_finale.gb (aggiunto ad all).
2026-06-24 16:35:06 +02:00
Matteo Benedetto 4d7bb13bc3 Dedicated richer, coherent tragic finale music
Replace the reused gameover music for game_over==3 with an original
192-step (24-chord) finale piece: a descending D-minor lament
(Dm-C-Bb-A7) that intensifies with high arpeggios (the 'scream'),
then plunges into the abyss as the bass descends to the lowest C and
fades to silence. Three channels: CH1 melody, CH2 bass, CH4 noise toll
(mid toll on chord changes, crash at the climax, deep toll in the abyss),
at a somber 14 frames/note.

- sound.c: finale_ch1_seq[192], finale_ch2_seq[192], play_finale_step(),
  finale_music_timer/step, sequencer branch for game_over==3.
- sound.h: play_finale_step prototype.

Verified via PyBoy: all three APU channels active throughout the finale.
2026-06-24 16:10:47 +02:00
Matteo Benedetto 0f88cea912 Finale: 'YOUR TORCH HAS RUN OUT' — tragic ending text
The finale text is now 'YOUR TORCH HAS / RUN OUT, / YOU ARE TRAPPED. /
JUST ANOTHER SCREAM / FROM THE DARK. / GAME OVER' — matching the
tragic dark theme of the game. BGP inverted for black background with
white text.
2026-06-24 14:23:47 +02:00
Matteo Benedetto 4968d2e885 8-level progression with scaling difficulty and a finale
Maze size grows +2/level from 7x7 to 21x21 (cap MAX_MAP_SIZE=21, reached
at level 8). Additional difficulty axes scale with level:
- +1 ghost per level (up to MAX_ENEMIES=8); enemy state moved to arrays,
  enemy_logic.c rewritten as a multi-entity loop (own AI, render at OAM
  2+i*2, staggered cooldowns).
- Ghost cooldown shrinks: 60 -> ~11 frames between steps.
- Stamina recharge slows: 60 -> 144 frames per point.
- Fog tightens to 3x3 (fog_radius=1) from level 7.
Fog rendering uses a dynamic 16-row centered flush (with wrap) instead of
the fixed rows 2-17 / full 32x32, so the fog stays correct on big mazes
without the multi-frame stall of the full flush.

Game ends after level 8: reaching the hatch at level 8 sets game_over=3
(finale) instead of 2. Finale screen reloads the IBM font and writes
'YOU ESCAPED / THE DARKNESS / LEVEL 8 CLEARED / PRESS START' into the BG
map; START returns to the title (new game starts at level 1).

Verified via PyBoy: sizes 7..21, fog 2->1 at L7, enemies 1..8 (distinct,
on floor, can catch the player), cooldown/recharge scaling, L1 hatch ->
game_over=2, L8 hatch -> game_over=3, finale renders + START->title->L1.
2026-06-24 13:04:39 +02:00