diff --git a/CMakeLists.txt b/CMakeLists.txt index 427218e..7cb5a6f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,7 +48,9 @@ set(APP_SOURCES source/scenes/palette_fade.cpp source/scenes/surface_handle.cpp source/scenes/scene_registry.cpp + source/scenes/scene_utils.cpp source/scenes/mort_scene.cpp + source/scenes/banner_scene.cpp # Game source/game/options.cpp diff --git a/source/core/system/director.cpp b/source/core/system/director.cpp index 5218e2b..737cbbc 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/banner_scene.hpp" #include "scenes/mort_scene.hpp" #include "scenes/scene.hpp" #include "scenes/scene_registry.hpp" @@ -102,6 +103,11 @@ void Director::init() { // rebre aquests states. auto& registry = scenes::SceneRegistry::instance(); registry.registerScene(100, [] { return std::make_unique(); }); + // BannerScene cobreix les piràmides 2..5 (el vell doBanner decideix + // pel switch intern llegint info::ctx.num_piramide). + for (int p = 2; p <= 5; ++p) { + registry.registerScene(p, [] { return std::make_unique(); }); + } GameFiber::init(gameFiberEntry); } diff --git a/source/game/modulesequence.cpp b/source/game/modulesequence.cpp index c444661..e59547c 100644 --- a/source/game/modulesequence.cpp +++ b/source/game/modulesequence.cpp @@ -45,12 +45,7 @@ int ModuleSequence::Go() { case 7: doSlides(); break; - case 2: // Pre-pir�mide - case 3: - case 4: - case 5: - doBanner(); - break; + // case 2..5 (Pre-piràmide) → migrat a scenes::BannerScene. case 6: // Pre-Secreta doSecreta(); break; @@ -1092,50 +1087,7 @@ void ModuleSequence::doSlides() { free(pal_aux); } -void ModuleSequence::doBanner() { - play_music("00000004.ogg"); - - this->contador = 5000; - - JD8_Surface gfx = JD8_LoadSurface("ffase.gif"); - JD8_Palette pal = JD8_LoadPalette("ffase.gif"); - - JD8_ClearScreen(0); - - JD8_Blit(81, 24, gfx, 81, 155, 168, 21); - JD8_Blit(39, 150, gfx, 39, 175, 248, 20); - - switch (info::ctx.num_piramide) { - case 2: - JD8_Blit(82, 60, gfx, 0, 0, 160, 75); - break; - case 3: - JD8_Blit(82, 60, gfx, 160, 0, 160, 75); - break; - case 4: - JD8_Blit(82, 60, gfx, 0, 75, 160, 75); - break; - case 5: - JD8_Blit(82, 60, gfx, 160, 75, 160, 75); - break; - } - 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; - } - } - JA_FadeOutMusic(250); -} +// doBanner() — migrat a scenes::BannerScene (source/scenes/banner_scene.cpp) void ModuleSequence::doSecreta() { play_music("00000002.ogg"); diff --git a/source/game/modulesequence.hpp b/source/game/modulesequence.hpp index 274d645..1d4cfce 100644 --- a/source/game/modulesequence.hpp +++ b/source/game/modulesequence.hpp @@ -17,7 +17,7 @@ class ModuleSequence { void doIntroSprites(Uint8* gfx); void doMenu(); void doSlides(); - void doBanner(); + // doBanner() → migrat a scenes::BannerScene void doSecreta(); void doCredits(); // doMort() → migrat a scenes::MortScene diff --git a/source/scenes/banner_scene.cpp b/source/scenes/banner_scene.cpp new file mode 100644 index 0000000..c255a6d --- /dev/null +++ b/source/scenes/banner_scene.cpp @@ -0,0 +1,71 @@ +#include "scenes/banner_scene.hpp" + +#include + +#include "core/jail/jail_audio.hpp" +#include "core/jail/jdraw8.hpp" +#include "core/jail/jinput.hpp" +#include "game/info.hpp" +#include "scenes/scene_utils.hpp" + +namespace scenes { + +void BannerScene::onEnter() { + playMusic("00000004.ogg"); + + gfx_ = SurfaceHandle("ffase.gif"); + + JD8_ClearScreen(0); + // Títols superior i inferior del banner (compartits per tots els nivells) + JD8_Blit(81, 24, gfx_, 81, 155, 168, 21); + JD8_Blit(39, 150, gfx_, 39, 175, 248, 20); + + // Número de piràmide: les 4 variants del vell `doBanner` es reduïxen + // a coordenades (sx,sy) calculades a partir de l'índex 0..3. + const int idx = info::ctx.num_piramide - 2; // 2..5 → 0..3 + if (idx >= 0 && idx <= 3) { + const int sx = (idx % 2) * 160; + const int sy = (idx / 2) * 75; + JD8_Blit(82, 60, gfx_, sx, sy, 160, 75); + } + + // PaletteFade copia internament amb memcpy; alliberem la paleta temporal. + JD8_Palette pal = JD8_LoadPalette("ffase.gif"); + fade_.startFadeTo(pal); + std::free(pal); + + phase_ = Phase::FadingIn; + remaining_ms_ = 5000; +} + +void BannerScene::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) { + JA_FadeOutMusic(250); + 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/banner_scene.hpp b/source/scenes/banner_scene.hpp new file mode 100644 index 0000000..ab85498 --- /dev/null +++ b/source/scenes/banner_scene.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include "scenes/palette_fade.hpp" +#include "scenes/scene.hpp" +#include "scenes/surface_handle.hpp" + +namespace scenes { + +// Banner pre-piràmide ("PIRÀMIDE X"). Reemplaça `ModuleSequence::doBanner()`. +// +// Flux: +// 1. Arranca música "00000004.ogg" i carrega ffase.gif. +// 2. Pinta títol, subtítol i número de piràmide segons info::ctx.num_piramide. +// 3. Fade-in de paleta. +// 4. Mostra ~5s o fins que es polse una tecla. +// 5. JA_FadeOutMusic(250) + fade-out de paleta. +// 6. Retorna nextState=0 per a entrar al ModuleGame. +// +// Registrat al SceneRegistry amb state_keys 2..5 (els num_piramide on +// el vell `doBanner()` es cridava). +class BannerScene : 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 0; } + + private: + enum class Phase { FadingIn, + Showing, + FadingOut, + Done }; + + SurfaceHandle gfx_; + PaletteFade fade_; + Phase phase_{Phase::FadingIn}; + int remaining_ms_{5000}; +}; + +} // namespace scenes diff --git a/source/scenes/mort_scene.cpp b/source/scenes/mort_scene.cpp index bcce6aa..fd663cc 100644 --- a/source/scenes/mort_scene.cpp +++ b/source/scenes/mort_scene.cpp @@ -2,31 +2,15 @@ #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 +#include "scenes/scene_utils.hpp" namespace scenes { void MortScene::onEnter() { - play_music("00000001.ogg"); + playMusic("00000001.ogg"); JI_DisableKeyboard(60); info::ctx.vida = 5; @@ -60,7 +44,7 @@ void MortScene::tick(int 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"); + playMusic("00000003.ogg"); info::ctx.num_piramide = 0; fade_.startFadeOut(); phase_ = Phase::FadingOut; diff --git a/source/scenes/scene_utils.cpp b/source/scenes/scene_utils.cpp new file mode 100644 index 0000000..3065c25 --- /dev/null +++ b/source/scenes/scene_utils.cpp @@ -0,0 +1,21 @@ +#include "scenes/scene_utils.hpp" + +#include + +#include "core/jail/jail_audio.hpp" +#include "core/jail/jfile.hpp" + +namespace scenes { + +void playMusic(const char* filename) { + if (!filename) return; + int size = 0; + char* buffer = file_getfilebuffer(filename, size); + if (!buffer) return; + // JA_LoadMusic fa una còpia del OGG comprimit (SDL_malloc), així que + // el `buffer` original es queda huérfano. Leak conegut heredat del + // codi original — es tractarà quan jfile tinga una API std::vector. + JA_PlayMusic(JA_LoadMusic(reinterpret_cast(buffer), size, filename)); +} + +} // namespace scenes diff --git a/source/scenes/scene_utils.hpp b/source/scenes/scene_utils.hpp new file mode 100644 index 0000000..01ff71d --- /dev/null +++ b/source/scenes/scene_utils.hpp @@ -0,0 +1,12 @@ +#pragma once + +// Helpers compartits per les escenes. Aquest header és petit i creix +// quan una abstracció comú apareix en dos o més escenes. + +namespace scenes { + +// Carrega un OGG de `data/` i arranca'l com a música de fons. Substituïx +// el `play_music()` repetit en tots els doX() del vell modulesequence. +void playMusic(const char* filename); + +} // namespace scenes