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.
This commit is contained in:
2026-06-24 12:26:48 +02:00
parent 509f162380
commit 5e8709ade0
11 changed files with 112 additions and 90 deletions
+10 -7
View File
@@ -11,7 +11,7 @@
#include "maze.h"
uint8_t get_tile_state(int8_t cx, int8_t cy, int8_t lx, int8_t ly) {
if (lx < 0 || lx >= MAP_SIZE || ly < 0 || ly >= MAP_SIZE) return 0;
if (lx < 0 || (uint8_t)lx >= map_size || ly < 0 || (uint8_t)ly >= map_size) return 0;
if (maze[ly][lx] == 0) return 0;
int8_t dx = lx - cx;
int8_t dy = ly - cy;
@@ -150,12 +150,12 @@ void draw_map(uint8_t center_x, uint8_t center_y) {
int8_t start_x = center_x - 2;
if (start_x < 0) start_x = 0;
int8_t end_x = center_x + 2;
if (end_x >= MAP_SIZE) end_x = MAP_SIZE - 1;
if ((uint8_t)end_x >= map_size) end_x = map_size - 1;
int8_t start_y = center_y - 2;
if (start_y < 0) start_y = 0;
int8_t end_y = center_y + 2;
if (end_y >= MAP_SIZE) end_y = MAP_SIZE - 1;
if ((uint8_t)end_y >= map_size) end_y = map_size - 1;
// Processiamo la mappa in DUE passate per risolvere il problema dell'overlapping isometrico.
// L'engine disegna da Nord a Sud. I tile a Sud sovrascrivono la metà inferiore dei tile a Nord.
@@ -248,10 +248,13 @@ void draw_map(uint8_t center_x, uint8_t center_y) {
update_stamina_display();
// Ottimizzazione hardware critica: trasferire tutta la mappa (1024 bytes) via set_bkg_tiles
// causa lag e sfarfallii (VRAM access). Trasferiamo solo le righe da 2 a 17 (16 righe totali),
// che è la porzione visibile del Game Boy (160x144 px) in cui si svolge l'azione.
set_bkg_tiles(0, 2, 32, 16, &map_buffer[2 * 32]);
// Trasferiamo l'intera mappa 32x32 (1024 byte) al Background hardware.
// Con labirinti grandi (map_size > 7) la finestra fog-of-war 5x5, proiettata in
// coordinate isometriche assolute, puo' cadere in righe OLTRE il vecchio range
// 2-17 (a causa del wrapping & 31), quindi non basta piu' flussare solo 16 righe.
// draw_map e' chiamato solo ai passi del movimento (non ogni frame), quindi il
// costo del flush completo e' sostenibile.
set_bkg_tiles(0, 0, 32, 32, map_buffer);
}
/**