From d86cb21efaa2d050af9d0a14448033c700cb3fcb Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Wed, 15 Apr 2026 23:05:45 +0200 Subject: [PATCH] step 1: mort_scene substituix doMort() amb la capa scenes:: --- CMakeLists.txt | 1 + source/core/system/director.cpp | 9 ++++ source/game/modulesequence.cpp | 37 +-------------- source/game/modulesequence.hpp | 2 +- source/scenes/mort_scene.cpp | 80 +++++++++++++++++++++++++++++++++ source/scenes/mort_scene.hpp | 36 +++++++++++++++ 6 files changed, 129 insertions(+), 36 deletions(-) create mode 100644 source/scenes/mort_scene.cpp create mode 100644 source/scenes/mort_scene.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 0013439..427218e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,6 +48,7 @@ set(APP_SOURCES source/scenes/palette_fade.cpp source/scenes/surface_handle.cpp source/scenes/scene_registry.cpp + source/scenes/mort_scene.cpp # Game source/game/options.cpp diff --git a/source/core/system/director.cpp b/source/core/system/director.cpp index 4155c00..5218e2b 100644 --- a/source/core/system/director.cpp +++ b/source/core/system/director.cpp @@ -20,6 +20,7 @@ #include "game/modulegame.hpp" #include "game/modulesequence.hpp" #include "game/options.hpp" +#include "scenes/mort_scene.hpp" #include "scenes/scene.hpp" #include "scenes/scene_registry.hpp" @@ -94,6 +95,14 @@ void gameFiberEntry() { void Director::init() { instance_ = new Director(); Gamepad::init(); + + // Registre d'escenes migrades. Cada entrada = una funció del vell + // ModuleSequence reescrita com a `scenes::*Scene`. Mentre vagen + // caient, el fallback al switch legacy de gameFiberEntry deixa de + // rebre aquests states. + auto& registry = scenes::SceneRegistry::instance(); + registry.registerScene(100, [] { return std::make_unique(); }); + GameFiber::init(gameFiberEntry); } diff --git a/source/game/modulesequence.cpp b/source/game/modulesequence.cpp index 884f4ea..c444661 100644 --- a/source/game/modulesequence.cpp +++ b/source/game/modulesequence.cpp @@ -57,9 +57,7 @@ int ModuleSequence::Go() { case 8: // Credits doCredits(); break; - case 100: // Mort - doMort(); - break; + // case 100 (Mort) → migrat a scenes::MortScene, dispatch via SceneRegistry. } JD8_FadeOut(); @@ -1292,35 +1290,4 @@ void ModuleSequence::doCredits() { JD8_FreeSurface(vaddr2); } -void ModuleSequence::doMort() { - play_music("00000001.ogg"); - - JI_DisableKeyboard(60); - - info::ctx.vida = 5; - this->contador = 1000; - - JD8_Surface gfx = JD8_LoadSurface("gameover.gif"); - JD8_Palette pal = JD8_LoadPalette("gameover.gif"); - - JD8_ClearScreen(0); - - JD8_Blit(gfx); - - JD8_FadeToPal(pal); - - bool exit = false; - while (!exit && !JG_Quitting()) { - if (JG_ShouldUpdate()) { - JI_Update(); - - if (JI_AnyKey()) { - exit = true; - } - - contador--; - if (contador == 0) exit = true; - } - } - play_music("00000003.ogg"); -} +// doMort() — migrat a scenes::MortScene (source/scenes/mort_scene.cpp) diff --git a/source/game/modulesequence.hpp b/source/game/modulesequence.hpp index 67d770d..274d645 100644 --- a/source/game/modulesequence.hpp +++ b/source/game/modulesequence.hpp @@ -20,7 +20,7 @@ class ModuleSequence { void doBanner(); void doSecreta(); void doCredits(); - void doMort(); + // doMort() → migrat a scenes::MortScene int contador; }; diff --git a/source/scenes/mort_scene.cpp b/source/scenes/mort_scene.cpp new file mode 100644 index 0000000..bcce6aa --- /dev/null +++ b/source/scenes/mort_scene.cpp @@ -0,0 +1,80 @@ +#include "scenes/mort_scene.hpp" + +#include + +#include "core/jail/jail_audio.hpp" +#include "core/jail/jdraw8.hpp" +#include "core/jail/jfile.hpp" +#include "core/jail/jinput.hpp" +#include "game/info.hpp" + +namespace { + +// Helper local: carrega un OGG del disc i l'envia a JA_PlayMusic. Equivalent +// al `play_music()` del modulesequence vell. El buffer es queda huérfano +// després de passar-lo a JA_LoadMusic (que n'ha fet una còpia SDL_malloc'd). +// Leak conegut del codi original, no el fixem en aquesta escena. +void play_music(const char* music) { + int size = 0; + char* buffer = file_getfilebuffer(music, size); + if (!buffer) return; + JA_PlayMusic(JA_LoadMusic(reinterpret_cast(buffer), size, music)); +} + +} // namespace + +namespace scenes { + +void MortScene::onEnter() { + play_music("00000001.ogg"); + JI_DisableKeyboard(60); + info::ctx.vida = 5; + + gfx_ = SurfaceHandle("gameover.gif"); + JD8_ClearScreen(0); + JD8_Blit(gfx_); + + // PaletteFade en fa una còpia interna via memcpy, així que alliberem + // la paleta temporal immediatament. + JD8_Palette pal = JD8_LoadPalette("gameover.gif"); + fade_.startFadeTo(pal); + std::free(pal); + + phase_ = Phase::FadingIn; + remaining_ms_ = 10000; +} + +void MortScene::tick(int delta_ms) { + switch (phase_) { + case Phase::FadingIn: + fade_.tick(delta_ms); + if (fade_.done()) phase_ = Phase::Showing; + break; + + case Phase::Showing: + if (JI_AnyKey()) { + remaining_ms_ = 0; + } else { + remaining_ms_ -= delta_ms; + } + if (remaining_ms_ <= 0) { + // Arrenca música del següent mòdul abans del fade out, + // igual que la versió vella feia al final de doMort(). + play_music("00000003.ogg"); + info::ctx.num_piramide = 0; + fade_.startFadeOut(); + phase_ = Phase::FadingOut; + } + break; + + case Phase::FadingOut: + fade_.tick(delta_ms); + if (fade_.done()) phase_ = Phase::Done; + break; + + case Phase::Done: + break; + } +} + +} // namespace scenes diff --git a/source/scenes/mort_scene.hpp b/source/scenes/mort_scene.hpp new file mode 100644 index 0000000..d121c52 --- /dev/null +++ b/source/scenes/mort_scene.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include "scenes/palette_fade.hpp" +#include "scenes/scene.hpp" +#include "scenes/surface_handle.hpp" + +namespace scenes { + +// Pantalla de "game over". Reemplaça `ModuleSequence::doMort()`. +// +// Flux: +// 1. Carrega gameover.gif, arranca música "00000001.ogg", fade-in de paleta. +// 2. Mostra la pantalla ~10 segons o fins que l'usuari polse una tecla. +// 3. Arranca música del menú ("00000003.ogg") i fade-out de paleta. +// 4. Marca num_piramide=0 i retorna nextState=1 perquè el Director +// passe a l'escena del menú. +class MortScene : public Scene { + public: + void onEnter() override; + void tick(int delta_ms) override; + bool done() const override { return phase_ == Phase::Done; } + int nextState() const override { return 1; } + + private: + enum class Phase { FadingIn, + Showing, + FadingOut, + Done }; + + SurfaceHandle gfx_; + PaletteFade fade_; + Phase phase_{Phase::FadingIn}; + int remaining_ms_{10000}; // 1000 ticks × 10 ms/tick del doMort original +}; + +} // namespace scenes