From 36951617d97c68734399e4fd0a8caaaa21fffe27 Mon Sep 17 00:00:00 2001 From: Matteo Benedetto Date: Thu, 25 Jun 2026 22:43:50 +0200 Subject: [PATCH] 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. --- Makefile | 6 +-- src/engine.c | 96 ++------------------------------------ src/screens/death.c | 22 +++++++++ src/screens/finale.c | 23 +++++++++ src/screens/going_deeper.c | 18 +++++++ src/screens/instructions.c | 24 ++++++++++ src/screens/screens.c | 24 ++++++++++ src/screens/screens.h | 33 +++++++++++++ 8 files changed, 152 insertions(+), 94 deletions(-) create mode 100644 src/screens/death.c create mode 100644 src/screens/finale.c create mode 100644 src/screens/going_deeper.c create mode 100644 src/screens/instructions.c create mode 100644 src/screens/screens.c create mode 100644 src/screens/screens.h diff --git a/Makefile b/Makefile index 5edec25..e8d56f9 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ SCRIPTS_DIR = scripts BUILD_DIR = build # C source files -SRCS = $(SRC_DIR)/main.c $(SRC_DIR)/engine.c $(SRC_DIR)/globals.c $(SRC_DIR)/maze.c $(SRC_DIR)/sound.c $(SRC_DIR)/render.c $(SRC_DIR)/player_logic.c $(SRC_DIR)/enemy_logic.c $(SRC_DIR)/tiles.c $(SRC_DIR)/player.c $(SRC_DIR)/enemy.c $(SRC_DIR)/gameover.c $(SRC_DIR)/stamina.c $(SRC_DIR)/level.c $(SRC_DIR)/title_bg.c +SRCS = $(SRC_DIR)/main.c $(SRC_DIR)/engine.c $(SRC_DIR)/globals.c $(SRC_DIR)/maze.c $(SRC_DIR)/sound.c $(SRC_DIR)/render.c $(SRC_DIR)/player_logic.c $(SRC_DIR)/enemy_logic.c $(SRC_DIR)/tiles.c $(SRC_DIR)/player.c $(SRC_DIR)/enemy.c $(SRC_DIR)/gameover.c $(SRC_DIR)/stamina.c $(SRC_DIR)/level.c $(SRC_DIR)/title_bg.c $(SRC_DIR)/screens/screens.c $(SRC_DIR)/screens/instructions.c $(SRC_DIR)/screens/death.c $(SRC_DIR)/screens/going_deeper.c $(SRC_DIR)/screens/finale.c all: $(BUILD_DIR)/hello_iso.gb $(BUILD_DIR)/test_gameover.gb $(BUILD_DIR)/test_finale.gb @@ -28,7 +28,7 @@ generate_c_assets: generate_images $(PNG2ASSET) $(ASSETS_DIR)/next_level.png -c $(SRC_DIR)/next_level.c -map -bpp 2 -noflip -max_palettes 1 $(PNG2ASSET) $(ASSETS_DIR)/stamina.png -c $(SRC_DIR)/stamina.c -bpp 2 -noflip -keep_palette_order $(PNG2ASSET) $(ASSETS_DIR)/level.png -c $(SRC_DIR)/level.c -sw 8 -sh 16 -bpp 2 -noflip -keep_palette_order -keep_duplicate_tiles - $(PNG2ASSET) $(ASSETS_DIR)/title_bg.png -c $(SRC_DIR)/title_bg.c -map -bpp 2 -noflip -keep_palette_order -max_palettes 1 + $(PNG2ASSET) $(ASSETS_DIR)/title_bg.png -c $(SRC_DIR)/title_bg.c $(SRC_DIR)/screens/screens.c $(SRC_DIR)/screens/instructions.c $(SRC_DIR)/screens/death.c $(SRC_DIR)/screens/going_deeper.c $(SRC_DIR)/screens/finale.c -map -bpp 2 -noflip -keep_palette_order -max_palettes 1 # Main ROM target $(BUILD_DIR)/hello_iso.gb: generate_c_assets $(SRCS) @@ -52,4 +52,4 @@ clean: rm -f $(SRC_DIR)/gameover.c $(SRC_DIR)/gameover.h rm -f $(SRC_DIR)/stamina.c $(SRC_DIR)/stamina.h rm -f $(SRC_DIR)/level.c $(SRC_DIR)/level.h - rm -f $(SRC_DIR)/title_bg.c $(SRC_DIR)/title_bg.h + rm -f $(SRC_DIR)/title_bg.c $(SRC_DIR)/screens/screens.c $(SRC_DIR)/screens/instructions.c $(SRC_DIR)/screens/death.c $(SRC_DIR)/screens/going_deeper.c $(SRC_DIR)/screens/finale.c $(SRC_DIR)/title_bg.h diff --git a/src/engine.c b/src/engine.c index 972a5e5..73bf6c5 100644 --- a/src/engine.c +++ b/src/engine.c @@ -20,6 +20,7 @@ #include "stamina.h" #include "level.h" #include "title_bg.h" +#include "screens/screens.h" /** * Inizializza la schermata del titolo @@ -195,27 +196,6 @@ void engine_init(void) { update_level_display(); // Mostra l'indicatore livello (top-left) } -/** - * Scrive una stringa nel map_buffer (copria RAM della BG map 32x32) usando gli indici - * tile del font IBM (tile = ASCII - 32, il font parte dallo spazio). Usato per la - * schermata finale senza dipendere da printf/console. - */ -static void ending_puttext(uint8_t col, uint8_t row, const char *s) { - uint8_t i = 0; - while (s[i]) { - if (col + i < 32) { - map_buffer[(uint16_t)row * 32 + col + i] = (uint8_t)(s[i] - ' '); - } - i++; - } -} - -static void ending_putdigit(uint8_t col, uint8_t row, uint8_t digit) { - if (col < 32) { - map_buffer[(uint16_t)row * 32 + col] = (uint8_t)(digit + ('0' - ' ')); - } -} - /** * Loop Principale di Aggiornamento del Gioco (chiamato ad ogni Frame ~60 FPS). * Questo metodo funge da "Direttore d'Orchestra", delegando i compiti ai moduli specializzati. @@ -232,26 +212,7 @@ void engine_update(uint8_t keys, uint8_t prev_keys) { if (hint_active) { if (!hint_displayed) { hint_displayed = 1; - HIDE_SPRITES; - font_init(); - font_t hint_font = font_load(font_ibm); - font_set(hint_font); - BGP_REG = 0x1B; // palette invertita (sfondo nero, testo chiaro) - memset(map_buffer, 0, sizeof(map_buffer)); - ending_puttext(3, 2, "A SCREAM FROM"); - ending_puttext(6, 3, "THE DARK"); - ending_puttext(3, 5, "FIND THE HATCH"); - ending_puttext(4, 8, "DPAD WALK"); - ending_puttext(2, 9, "A JUMP ABYSS"); - ending_puttext(2, 10, "B RUN"); - ending_puttext(2, 12, "PRESS B START"); - ending_puttext(4, 14, "SELECT HELP"); - // Usa il WINDOW layer (tile map separato a 0x9C00) per il testo: - // il BG map del gameplay (0x9800) resta intatto -> niente garbage - // quando si chiude l'hint. move_win(7,0) allinea a sinistra (-7 offset). - set_win_tiles(0, 0, 32, 32, map_buffer); - move_win(7, 0); - SHOW_WIN; + show_instructions(); } // B chiude la schermata e riprende il gioco if ((keys & J_B) && !(prev_keys & J_B)) { @@ -287,58 +248,11 @@ void engine_update(uint8_t keys, uint8_t prev_keys) { // Quando scade il timer drammatico... if (game_over_timer == 0) { if (game_over == 1) { - // Sconfitta: schermata testuale a tutto schermo (font IBM). - // (Era l'immagine claimed.png, sostituita con testo per ridurre - // l'occupazione ROM e fare spazio alla schermata istruzioni.) - HIDE_SPRITES; - SCX_REG = 0; - SCY_REG = 0; - BGP_REG = 0x1B; // palette invertita (sfondo nero, testo chiaro) - font_init(); - font_t dead_font = font_load(font_ibm); - font_set(dead_font); - memset(map_buffer, 0, sizeof(map_buffer)); - ending_puttext(5, 3, "YOU DIED"); - ending_puttext(2, 5, "THE DARK CLAIMS"); - ending_puttext(5, 6, "ANOTHER"); - ending_puttext(2, 9, "JUST ANOTHER SCREAM"); - ending_puttext(3, 10, "FROM THE DARK."); - ending_puttext(5, 14, "GAME OVER"); - set_bkg_tiles(0, 0, 32, 32, map_buffer); + show_death(); } else if (game_over == 2) { - // Going Deeper: schermata di transizione testuale (font IBM). - // (Era un'immagine, sostituita con testo per ridurre l'occupazione ROM - // e fare spazio alla schermata istruzioni.) - HIDE_SPRITES; - SCX_REG = 0; - SCY_REG = 0; - font_init(); - font_t gd_font = font_load(font_ibm); - font_set(gd_font); - memset(map_buffer, 0, sizeof(map_buffer)); - ending_puttext(2, 7, "GOING DEEPER"); - ending_puttext(3, 9, "LEVEL"); - ending_putdigit(9, 9, (uint8_t)(level + 1)); - set_bkg_tiles(0, 0, 32, 32, map_buffer); + show_going_deeper(); } else if (game_over == 3) { - // FINALE TRAGICO: livello 8 superato, ma non e' una fuga. La traccia - // si e' esaurita, sei intrappolato. Sfondo nero (BGP invertito) + testo - // chiaro col font IBM (ricaricato: il gameplay lo aveva sovrascritto). - HIDE_SPRITES; - SCX_REG = 0; - SCY_REG = 0; - BGP_REG = 0x1B; // palette invertita: sfondo nero, testo chiaro - font_init(); - font_t end_font = font_load(font_ibm); - font_set(end_font); - memset(map_buffer, 0, sizeof(map_buffer)); // tile 0 = spazio - ending_puttext(3, 4, "YOUR TORCH HAS"); - ending_puttext(6, 5, "RUN OUT,"); - ending_puttext(2, 7, "YOU ARE TRAPPED."); - ending_puttext(0, 10, "JUST ANOTHER SCREAM"); - ending_puttext(3, 11, "FROM THE DARK."); - ending_puttext(5, 14, "GAME OVER"); - set_bkg_tiles(0, 0, 32, 32, map_buffer); + show_finale(); } // Imposta i timer audio per far iniziare la musica finale dal modulo sound.c diff --git a/src/screens/death.c b/src/screens/death.c new file mode 100644 index 0000000..9199072 --- /dev/null +++ b/src/screens/death.c @@ -0,0 +1,22 @@ +#include "screens.h" +#include "../globals.h" +#include + +// Schermata di sconfitta (game_over == 1: il buio ti reclama) +void show_death(void) { + HIDE_SPRITES; + SCX_REG = 0; + SCY_REG = 0; + BGP_REG = 0x1B; // palette invertita (sfondo nero, testo chiaro) + font_init(); + font_t dead_font = font_load(font_ibm); + font_set(dead_font); + memset(map_buffer, 0, sizeof(map_buffer)); + ending_puttext(5, 3, "YOU DIED"); + ending_puttext(2, 5, "THE DARK CLAIMS"); + ending_puttext(5, 6, "ANOTHER"); + ending_puttext(2, 9, "JUST ANOTHER SCREAM"); + ending_puttext(3, 10, "FROM THE DARK."); + ending_puttext(5, 14, "GAME OVER"); + set_bkg_tiles(0, 0, 32, 32, map_buffer); +} \ No newline at end of file diff --git a/src/screens/finale.c b/src/screens/finale.c new file mode 100644 index 0000000..3ee6f89 --- /dev/null +++ b/src/screens/finale.c @@ -0,0 +1,23 @@ +#include "screens.h" +#include "../globals.h" +#include + +// Schermata del finale tragico (game_over == 3: la torcia si e' spenta). +// SPOILER: il testo e' in questo file (non nella documentazione). +void show_finale(void) { + HIDE_SPRITES; + SCX_REG = 0; + SCY_REG = 0; + BGP_REG = 0x1B; // palette invertita: sfondo nero, testo chiaro + font_init(); + font_t end_font = font_load(font_ibm); + font_set(end_font); + memset(map_buffer, 0, sizeof(map_buffer)); + ending_puttext(3, 4, "YOUR TORCH HAS"); + ending_puttext(6, 5, "RUN OUT,"); + ending_puttext(2, 7, "YOU ARE TRAPPED."); + ending_puttext(0, 10, "JUST ANOTHER SCREAM"); + ending_puttext(3, 11, "FROM THE DARK."); + ending_puttext(5, 14, "GAME OVER"); + set_bkg_tiles(0, 0, 32, 32, map_buffer); +} \ No newline at end of file diff --git a/src/screens/going_deeper.c b/src/screens/going_deeper.c new file mode 100644 index 0000000..508a45a --- /dev/null +++ b/src/screens/going_deeper.c @@ -0,0 +1,18 @@ +#include "screens.h" +#include "../globals.h" +#include + +// Schermata di transizione livello (game_over == 2: Going Deeper) +void show_going_deeper(void) { + HIDE_SPRITES; + SCX_REG = 0; + SCY_REG = 0; + font_init(); + font_t gd_font = font_load(font_ibm); + font_set(gd_font); + memset(map_buffer, 0, sizeof(map_buffer)); + ending_puttext(2, 7, "GOING DEEPER"); + ending_puttext(3, 9, "LEVEL"); + ending_putdigit(9, 9, (uint8_t)(level + 1)); + set_bkg_tiles(0, 0, 32, 32, map_buffer); +} \ No newline at end of file diff --git a/src/screens/instructions.c b/src/screens/instructions.c new file mode 100644 index 0000000..b7081b0 --- /dev/null +++ b/src/screens/instructions.c @@ -0,0 +1,24 @@ +#include "screens.h" +#include "../globals.h" +#include + +// Schermata istruzioni (livello 1 / SELECT). Usa il Window layer: +// il BG map del gameplay resta intatto -> niente garbage alla chiusura. +void show_instructions(void) { + HIDE_SPRITES; + font_init(); + font_t hint_font = font_load(font_ibm); + font_set(hint_font); + BGP_REG = 0x1B; // palette invertita (sfondo nero, testo chiaro) + memset(map_buffer, 0, sizeof(map_buffer)); + + ending_puttext(3, 2, "FIND THE HATCH"); + ending_puttext(4, 8, "DPAD WALK"); + ending_puttext(2, 9, "A + DPAD JUMP"); + ending_puttext(2, 10, "B + DPAD RUN"); + ending_puttext(2, 12, "PRESS B TO CONTINUE"); + // Window layer: tile map separato (0x9C00) dal BG (0x9800) + set_win_tiles(0, 0, 32, 32, map_buffer); + move_win(7, 0); // -7 pixel offset: allinea a sinistra + SHOW_WIN; +} \ No newline at end of file diff --git a/src/screens/screens.c b/src/screens/screens.c new file mode 100644 index 0000000..a5edefa --- /dev/null +++ b/src/screens/screens.c @@ -0,0 +1,24 @@ +#include "screens.h" +#include "../globals.h" +#include + +/** + * Helper condivisi per scrivere testo nel map_buffer usando gli indici + * tile del font IBM (tile = ASCII - 32, il font parte dallo spazio). + */ + +void ending_puttext(uint8_t col, uint8_t row, const char *s) { + uint8_t i = 0; + while (s[i]) { + if (col + i < 32) { + map_buffer[(uint16_t)row * 32 + col + i] = (uint8_t)(s[i] - ' '); + } + i++; + } +} + +void ending_putdigit(uint8_t col, uint8_t row, uint8_t digit) { + if (col < 32) { + map_buffer[(uint16_t)row * 32 + col] = (uint8_t)(digit + ('0' - ' ')); + } +} \ No newline at end of file diff --git a/src/screens/screens.h b/src/screens/screens.h new file mode 100644 index 0000000..a2ab27c --- /dev/null +++ b/src/screens/screens.h @@ -0,0 +1,33 @@ +#ifndef SCREENS_H +#define SCREENS_H + +#include +#include +#include + +/** + * Schermate testuali (font IBM, palette invertita 0x1B = sfondo nero). + * Ogni funzione renderizza la propria schermata nel map_buffer e la + * flusha sulla BG map (o Window per l'hint). Il chiamante gestisce + * BGP, font_init/font_load, HIDE/SHOW_SPRITES e il ripristino dei tile. + */ + +// Schermata del titolo ( chiamata da title_init ) + +// Schermata istruzioni (livello 1 / SELECT). Usa il Window layer. +void show_instructions(void); + +// Schermata di sconfitta (game_over == 1) +void show_death(void); + +// Schermata di transizione livello (game_over == 2) +void show_going_deeper(void); + +// Schermata del finale tragico (game_over == 3) +void show_finale(void); + +// Helper condivisi (definiti in screens.c) +void ending_puttext(uint8_t col, uint8_t row, const char *s); +void ending_putdigit(uint8_t col, uint8_t row, uint8_t digit); + +#endif \ No newline at end of file