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).
This commit is contained in:
2026-06-24 16:35:06 +02:00
parent 4d7bb13bc3
commit 962ec56d59
3 changed files with 74 additions and 1 deletions
+5 -1
View File
@@ -11,7 +11,7 @@ BUILD_DIR = build
# C source files # 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)/next_level.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)/next_level.c $(SRC_DIR)/stamina.c $(SRC_DIR)/level.c $(SRC_DIR)/title_bg.c
all: $(BUILD_DIR)/hello_iso.gb $(BUILD_DIR)/test_gameover.gb all: $(BUILD_DIR)/hello_iso.gb $(BUILD_DIR)/test_gameover.gb $(BUILD_DIR)/test_finale.gb
# Generate image assets # Generate image assets
generate_images: $(SCRIPTS_DIR)/generate_assets.py $(SCRIPTS_DIR)/generate_enemy.py $(SCRIPTS_DIR)/generate_level.py generate_images: $(SCRIPTS_DIR)/generate_assets.py $(SCRIPTS_DIR)/generate_enemy.py $(SCRIPTS_DIR)/generate_level.py
@@ -40,6 +40,10 @@ $(BUILD_DIR)/test_gameover.gb: generate_c_assets $(SRC_DIR)/test_gameover_render
mkdir -p $(BUILD_DIR) mkdir -p $(BUILD_DIR)
$(LCC) -Wa-l -Wl-m -Wl-j -o $(BUILD_DIR)/test_gameover.gb $(SRC_DIR)/test_gameover_render.c $(SRC_DIR)/player.c $(SRC_DIR)/enemy.c $(SRC_DIR)/gameover.c $(SRC_DIR)/stamina.c $(LCC) -Wa-l -Wl-m -Wl-j -o $(BUILD_DIR)/test_gameover.gb $(SRC_DIR)/test_gameover_render.c $(SRC_DIR)/player.c $(SRC_DIR)/enemy.c $(SRC_DIR)/gameover.c $(SRC_DIR)/stamina.c
$(BUILD_DIR)/test_finale.gb: $(SRC_DIR)/test_finale_render.c
mkdir -p $(BUILD_DIR)
$(LCC) -Wa-l -Wl-m -Wl-j -o $(BUILD_DIR)/test_finale.gb $(SRC_DIR)/test_finale_render.c $(SRC_DIR)/globals.c $(SRC_DIR)/sound.c
clean: clean:
rm -rf $(BUILD_DIR)/* rm -rf $(BUILD_DIR)/*
rm -f $(SRC_DIR)/tiles.c $(SRC_DIR)/tiles.h rm -f $(SRC_DIR)/tiles.c $(SRC_DIR)/tiles.h
Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

+69
View File
@@ -0,0 +1,69 @@
#include <gb/gb.h>
#include <stdint.h>
#include <string.h>
#include <gbdk/font.h>
#include "globals.h"
#include "sound.h"
uint8_t app_state = 1; // sound.c references this; not used in this test
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++;
}
}
void main(void) {
SPRITES_8x16;
OBP0_REG = 0xE4;
OBP1_REG = 0x1B;
BGP_REG = 0x1B; // inverted palette: dark bg, light text
memset(map_buffer, 0, sizeof(map_buffer));
set_bkg_tiles(0, 0, 32, 32, map_buffer);
font_init();
font_t f = font_load(font_ibm);
font_set(f);
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);
NR52_REG = 0x80;
NR50_REG = 0x77;
NR51_REG = 0xFF;
sound_reset_music_state();
remove_VBL(play_music_tick);
add_VBL(play_music_tick);
// Trigger the finale music sequencer immediately (skip the 30-frame timer
// that the main game uses; here we want the music from frame 0).
game_over = 3;
game_over_timer = 0;
SHOW_BKG;
SHOW_SPRITES;
DISPLAY_ON;
uint8_t prev_keys = 0;
while (1) {
wait_vbl_done();
uint8_t keys = joypad();
if ((keys & J_START) && !(prev_keys & J_START)) {
level = 1;
break;
}
prev_keys = keys;
}
}