step 9: intro_sprites_scene com a sub-escena (elimina doIntroSprites + 3 variants aleatòries)

This commit is contained in:
2026-04-16 08:38:47 +02:00
parent e18b7321eb
commit d343e719ca
9 changed files with 459 additions and 624 deletions

View File

@@ -5,7 +5,6 @@
#include "core/jail/jdraw8.hpp"
#include "core/jail/jinput.hpp"
#include "game/info.hpp"
#include "game/modulesequence.hpp"
#include "scenes/scene_utils.hpp"
namespace {
@@ -98,7 +97,7 @@ void IntroNewLogoScene::render() {
LETTER_WIDTHS[8], LOGO_HEIGHT);
break;
case Phase::Delegate:
case Phase::Sprites:
case Phase::Done:
break;
}
@@ -122,10 +121,10 @@ void IntroNewLogoScene::advancePaletteCycle() {
void IntroNewLogoScene::tick(int delta_ms) {
// Qualsevol tecla durant el revelat o el ciclo de paleta salta
// TOTA la intro (inclou saltar doIntroSprites). Aquest era el
// comportament del vell `doIntroNewLogo`: a cada `waitTick()`
// retornava abans de cridar `doIntroSprites`.
if (phase_ != Phase::Delegate && phase_ != Phase::Done && JI_AnyKey()) {
// TOTA la intro (inclou saltar la fase de sprites). Durant Sprites
// deixem que la sub-escena gestione el seu propi skip (que a més
// respecta la fase "final" no skippable de la variant 0).
if (phase_ != Phase::Sprites && phase_ != Phase::Done && JI_AnyKey()) {
info::ctx.num_piramide = 0;
phase_ = Phase::Done;
return;
@@ -189,28 +188,27 @@ void IntroNewLogoScene::tick(int delta_ms) {
phase_acc_ms_ += delta_ms;
render();
if (phase_acc_ms_ >= FINAL_WAIT_MS) {
phase_ = Phase::Delegate;
phase_ = Phase::Sprites;
}
break;
case Phase::Delegate: {
// Delegació temporal al codi legacy: crea un ModuleSequence
// instància i li crida `doIntroSprites(gfx)`. La funció
// legacy *sempre* allibera `gfx` ella mateixa (al final o en
// els paths de skip amb JI_AnyKey), així que necessitem
// transferir-li ownership via `release()` per evitar un
// double free al destructor de SurfaceHandle. Step 9
// d'aquesta migració la reescriurà com a IntroSpritesScene
// i la delegació desapareixerà.
ModuleSequence legacy;
legacy.doIntroSprites(gfx_.release());
// El vell `Go()` post-switch feia `num_piramide = 0` per a
// passar al menú. Ho reproduïm ací — si no, el while extern
// del fiber tornaria a crear IntroNewLogoScene infinitament.
info::ctx.num_piramide = 0;
phase_ = Phase::Done;
case Phase::Sprites:
// Sub-escena construïda al primer tick. Transferim el gfx_
// per move — la sub-escena se n'ocupa fins que es destruix.
// Cada tick successiu delega l'animació dels sprites.
if (!sprites_scene_) {
sprites_scene_ = std::make_unique<IntroSpritesScene>(std::move(gfx_));
sprites_scene_->onEnter();
}
sprites_scene_->tick(delta_ms);
if (sprites_scene_->done()) {
// El vell `Go()` post-switch feia `num_piramide = 0`
// per passar al menú. Sense açò el while del fiber
// tornaria a crear IntroNewLogoScene infinitament.
info::ctx.num_piramide = 0;
phase_ = Phase::Done;
}
break;
}
case Phase::Done:
break;