Commit Graph

38 Commits

Author SHA1 Message Date
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
Matteo Benedetto 5e8709ade0 Grow maze size with level (7x7 -> 17x17, +2 per level)
The maze side length is now a runtime global 'map_size' (MAP_SIZE=7 at
level 1, +2 per level, capped at MAX_MAP_SIZE=17), while the maze array
is allocated with the MAX_MAP_SIZE bound. All modules (maze DFS, fog
rendering, player/enemy bounds, hatch and enemy-spawn placement) now use
map_size at runtime.

- globals: maze[MAX_MAP_SIZE][MAX_MAP_SIZE], map_size global, MAX_MAP_SIZE=17.
- maze.c: DFS on map_size; stack/valid arrays made static (WRAM) and sized
  for the max maze to avoid hardware-stack overflow; hatch min distance
  scales with map_size/2.
- engine.c: sets map_size from level before generate_maze; enemy spawn min
  distance scales with map_size/2.
- render.c: flush the full 32x32 background map (the old rows 2-17
  optimization broke for large mazes where the 5x5 fog window wraps outside
  that range); dynamic bounds; signed/unsigned casts.
- player_logic/enemy_logic: dynamic map_size bounds.

Verified via PyBoy: sizes 7,9,11,13,15,17,17 across levels 1-7, each with
a hatch; rendering and movement intact at 17x17 and at 7x7.
2026-06-24 12:26:48 +02:00
Matteo Benedetto 509f162380 Keep current level on defeat instead of resetting to 1
On game over (defeat) + START, restart the maze at the same level the
player had reached instead of resetting to 1. Only starting a new game
from the title screen zeroes the counter. Victory still increments as
before.
2026-06-24 12:12:17 +02:00
Matteo Benedetto 36e52d4d1a Implement run mechanic and level progression with top-left HUD indicator
Run (B + direction):
- player_logic.c: while holding B + direction with stamina >= 10, each tile
  takes 8 frames instead of 16 (move_progress += 2, LERP >>4 unchanged) and
  costs 10 stamina per tile. DAS_REPEAT_RUN=2 chains tiles fluidly.
- Falls back silently to normal walk when stamina < 10.

Level progression:
- New global 'level' (starts at 1). title->game resets to 1; reaching the
  hatch (victory/Going Deeper) + START increments before engine_init (new
  maze); defeat + START resets to 1.
- Top-left HUD 'L<n>' via 3 sprites (OAM 23-25) from new level.png asset
  (glyphs L, 0-9), generated by scripts/generate_level.py and converted
  with png2asset -keep_duplicate_tiles for predictable tile ordering.
- VRAM base aligned to an EVEN index (8x16 hardware ignores tile LSB) and
  placed after the stamina load claim to avoid the shared BG tile block.
- update_level_display() called every frame; hides during game over/title.

Docs: README, doc/gameplay.md and the technical report updated.
2026-06-24 11:56:19 +02:00
Matteo Benedetto ae0706ccfb Place the hatch on any sufficiently-distant tile, not just the south edge
The victory hatch (maze[y][x]==2) is now chosen among all walkable cells
at Chebyshev distance >= MIN_GOAL_DIST (3) from the player start (1,1),
instead of being constrained to the bottom row. This lets the goal appear
anywhere in the maze while always staying far from the start.

- maze.c: collect all floor cells with chebyshev(1,1) >= 3 and pick one
  at random; fallback to the farthest floor cell if none qualifies.
- doc/generation.md + report: document the new placement rule.
2026-06-24 11:18:31 +02:00
Matteo Benedetto 8244790603 Add technical report, update docs/README, remove orphaned victory asset
- Add doc/AScreamFromTheDark_report.md: deep technical report covering
  architecture, features, historical workarounds and known debt.
- Rewrite README.md to reflect the current 'A Scream from the Dark'
  identity (ghost enemy, stamina/jump, fog of war, going-deeper victory)
  instead of the stale 'gioco carino' copy with old file paths.
- Update doc/generation.md: goal is now a random south-edge hatch,
  not the max-Manhattan-distance portal.
- Remove orphaned src/victory.{c,h} and its include in render.c;
  the victory sequence was replaced by the full-screen next_level image.
- Regenerate tracked png2asset outputs to match current build.
2026-06-24 11:11:17 +02:00
enne2 cc656d01cc Make next level music more audible and end smoothly descending 2026-06-23 22:18:51 +02:00
enne2 d8fd7460ae Fix next_level image quantization to preserve dark tones using fixed thresholds 2026-06-23 22:12:43 +02:00
enne2 cb19677f98 Fix next_level image glitch: reset camera scroll and improve image color quantization 2026-06-23 22:05:10 +02:00
enne2 3aa20fdb60 Replace victory sequence with going deeper background and mysterious music 2026-06-23 22:01:09 +02:00
enne2 f14e2645d2 Redesign stairs as a hole in the ground and allow ghost to walk over it 2026-06-23 20:17:46 +02:00
enne2 93deb35f86 Fix GameBoy VRAM shared memory overlap bug between background tiles and stamina UI sprites 2026-06-23 20:10:27 +02:00
enne2 1b0e1a057b Revert sprite-based stairs back to tile-based stairs 2026-06-23 19:57:13 +02:00
enne2 8d71a23ae9 Fix sprite artifacts on stairs by generating all metasprites with -spr8x16 2026-06-23 19:51:09 +02:00
enne2 7d3003203c Refactoring: Project structure, sprite stairs & fog masks rendering fix 2026-06-23 19:43:55 +02:00
enne2 0ceae6f98b Optimize bg.png conversion without scaling and with correct color mapping 2026-06-23 11:10:17 +02:00
enne2 f00b533581 Update title screen image 2026-06-23 00:14:13 +02:00
enne2 c0c217f4f6 Fix game over restart logic and update README 2026-06-23 00:09:42 +02:00
enne2 e07e8c6e56 Fix off-screen enemy invisibility with modulo 256 scroll wrapping 2026-06-22 20:02:58 +02:00
enne2 c98363126b Fix DMG sprite palette selection for enemy and add Game Over transition delay 2026-06-22 19:57:02 +02:00
enne2 b47455c5d2 Fix enemy rendering screen offset and implement pixel-perfect sprite collision 2026-06-22 19:50:44 +02:00
enne2 9311e5d1d3 Refine enemy AI pathfinding and update walkthrough documentation 2026-06-22 19:45:04 +02:00
enne2 6d94992e58 Fix DAS and movement transition synchronization to eliminate 2-frame lag between tiles 2026-06-22 19:34:05 +02:00
enne2 7d85aec6ec Implement random wall reopening to generate alternative paths and cycles 2026-06-22 19:30:44 +02:00
enne2 d1bb95f166 Optimize fog of war visibility to 5x5 for enhanced gameplay and performance 2026-06-22 19:25:16 +02:00
enne2 d82008dac0 Optimize map rendering and implement dynamic fog of war 2026-06-22 19:21:19 +02:00
enne2 f774171bae Fix: DAS delay timer now synchronized with movement cycle for continuous walk 2026-06-22 18:59:03 +02:00
enne2 991afd1749 Aggiunto README e aggiornati file del progetto 2026-06-22 18:50:25 +02:00
enne2 20a5d8604b Initial commit of isometric Game Boy adventure prototype 2026-06-20 16:30:15 +02:00