step 8: intro_scene substituix doIntro() (revelat JAILGAMES lletra a lletra + cicle de paleta)
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
#include "scenes/banner_scene.hpp"
|
||||
#include "scenes/credits_scene.hpp"
|
||||
#include "scenes/intro_new_logo_scene.hpp"
|
||||
#include "scenes/intro_scene.hpp"
|
||||
#include "scenes/menu_scene.hpp"
|
||||
#include "scenes/mort_scene.hpp"
|
||||
#include "scenes/scene.hpp"
|
||||
@@ -133,14 +134,15 @@ void Director::init() {
|
||||
registry.registerScene(7, [] { return std::make_unique<scenes::SlidesScene>(); });
|
||||
registry.registerScene(6, [] { return std::make_unique<scenes::SecretaScene>(); });
|
||||
registry.registerScene(8, [] { return std::make_unique<scenes::CreditsScene>(); });
|
||||
// IntroNewLogoScene només es registra quan `use_new_logo` està actiu;
|
||||
// si no, la factory retorna nullptr i el gameFiberEntry cau al vell
|
||||
// ModuleSequence::doIntro() legacy que no ha sigut migrat encara.
|
||||
// State 255 (intro): dues variants segons `Options::game.use_new_logo`.
|
||||
// La factory tria a runtime — així es pot togglar des del menú sense
|
||||
// re-registrar. Les dues escenes acaben delegant a doIntroSprites
|
||||
// legacy fins al Step 9 de la migració.
|
||||
registry.registerScene(255, []() -> std::unique_ptr<scenes::Scene> {
|
||||
if (Options::game.use_new_logo) {
|
||||
return std::make_unique<scenes::IntroNewLogoScene>();
|
||||
}
|
||||
return nullptr;
|
||||
return std::make_unique<scenes::IntroScene>();
|
||||
});
|
||||
|
||||
GameFiber::init(gameFiberEntry);
|
||||
|
||||
@@ -2,11 +2,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "core/jail/jail_audio.hpp"
|
||||
#include "core/jail/jdraw8.hpp"
|
||||
#include "core/jail/jfile.hpp"
|
||||
#include "core/jail/jgame.hpp"
|
||||
#include "core/jail/jinput.hpp"
|
||||
#include "game/options.hpp"
|
||||
@@ -34,17 +30,18 @@ bool wait_frame_or_skip() {
|
||||
int ModuleSequence::Go() {
|
||||
if (info::ctx.num_piramide == 6 && info::ctx.diners < 200) info::ctx.num_piramide = 7;
|
||||
|
||||
switch (info::ctx.num_piramide) {
|
||||
case 255: // Intro
|
||||
doIntro();
|
||||
break;
|
||||
// case 0 (Menú) → migrat a scenes::MenuScene.
|
||||
// case 1 i 7 (Slides) → migrat a scenes::SlidesScene.
|
||||
// case 2..5 (Pre-piràmide) → migrat a scenes::BannerScene.
|
||||
// case 6 (Pre-Secreta) → migrat a scenes::SecretaScene.
|
||||
// case 8 (Credits) → migrat a scenes::CreditsScene.
|
||||
// case 100 (Mort) → migrat a scenes::MortScene, dispatch via SceneRegistry.
|
||||
}
|
||||
// Totes les branques del vell switch han estat migrades a scenes:
|
||||
// case 0 (Menú) → scenes::MenuScene
|
||||
// case 1 i 7 (Slides) → scenes::SlidesScene
|
||||
// case 2..5 (Banner) → scenes::BannerScene
|
||||
// case 6 (Secreta) → scenes::SecretaScene
|
||||
// case 8 (Credits) → scenes::CreditsScene
|
||||
// case 100 (Mort) → scenes::MortScene
|
||||
// case 255 (Intro) → scenes::IntroScene / scenes::IntroNewLogoScene
|
||||
// El gameFiberEntry les dispatcha via SceneRegistry abans de caure a
|
||||
// aquest Go() — així que en la pràctica ja no s'arriba ací. El codi
|
||||
// que queda sota (JD8_FadeOut + transicions de num_piramide) serà
|
||||
// eliminat al Step 10 del pla, junt amb ModuleSequence::Go() sencer.
|
||||
|
||||
JD8_FadeOut();
|
||||
|
||||
@@ -94,229 +91,6 @@ static void drawIntroWordmark(JD8_Surface gfx) {
|
||||
}
|
||||
}
|
||||
|
||||
void play_music(const char* music, bool loop = -1) {
|
||||
int size;
|
||||
char* buffer = file_getfilebuffer(music, size);
|
||||
JA_PlayMusic(JA_LoadMusic((Uint8*)buffer, size, music), loop);
|
||||
}
|
||||
|
||||
void ModuleSequence::doIntro() {
|
||||
// Branca `if (use_new_logo)` eliminada: scenes::IntroNewLogoScene
|
||||
// agafa eixe camí via el SceneRegistry. Aquest `doIntro()` legacy
|
||||
// només s'executa quan `use_new_logo == false`.
|
||||
|
||||
JG_SetUpdateTicks(1000);
|
||||
|
||||
play_music("00000003.ogg");
|
||||
|
||||
JD8_Surface gfx = JD8_LoadSurface("logo.gif");
|
||||
JD8_Palette pal = JD8_LoadPalette("logo.gif");
|
||||
JD8_SetScreenPalette(pal);
|
||||
|
||||
JD8_ClearScreen(0);
|
||||
JD8_Flip();
|
||||
if (wait_frame_or_skip()) {
|
||||
|
||||
JD8_FreeSurface(gfx);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
JG_SetUpdateTicks(100);
|
||||
|
||||
JD8_Blit(43, 78, gfx, 43, 155, 27, 45);
|
||||
JD8_Blit(68, 78, gfx, 274, 155, 27, 45);
|
||||
JD8_Flip();
|
||||
if (wait_frame_or_skip()) {
|
||||
|
||||
JD8_FreeSurface(gfx);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
JD8_Blit(43, 78, gfx, 43, 155, 53, 45);
|
||||
JD8_Blit(96, 78, gfx, 274, 155, 27, 45);
|
||||
JD8_Flip();
|
||||
if (wait_frame_or_skip()) {
|
||||
|
||||
JD8_FreeSurface(gfx);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
JD8_Blit(43, 78, gfx, 43, 155, 66, 45);
|
||||
JD8_Blit(109, 78, gfx, 274, 155, 27, 45);
|
||||
JD8_Flip();
|
||||
if (wait_frame_or_skip()) {
|
||||
|
||||
JD8_FreeSurface(gfx);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
JG_SetUpdateTicks(200);
|
||||
|
||||
JD8_Blit(43, 78, gfx, 43, 155, 92, 45);
|
||||
JD8_Blit(136, 78, gfx, 274, 155, 27, 45);
|
||||
JD8_Flip();
|
||||
if (wait_frame_or_skip()) {
|
||||
|
||||
JD8_FreeSurface(gfx);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
JD8_ClearScreen(0);
|
||||
JD8_Blit(43, 78, gfx, 43, 155, 92, 45);
|
||||
// JD8_Blit( 136, 78, gfx, 274, 155, 27, 45 );
|
||||
JD8_Flip();
|
||||
if (wait_frame_or_skip()) {
|
||||
|
||||
JD8_FreeSurface(gfx);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
JG_SetUpdateTicks(100);
|
||||
|
||||
JD8_Blit(43, 78, gfx, 43, 155, 118, 45);
|
||||
JD8_Blit(160, 78, gfx, 274, 155, 27, 45);
|
||||
JD8_Flip();
|
||||
if (wait_frame_or_skip()) {
|
||||
|
||||
JD8_FreeSurface(gfx);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
JD8_Blit(43, 78, gfx, 43, 155, 145, 45);
|
||||
JD8_Blit(188, 78, gfx, 274, 155, 27, 45);
|
||||
JD8_Flip();
|
||||
if (wait_frame_or_skip()) {
|
||||
|
||||
JD8_FreeSurface(gfx);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
JD8_Blit(43, 78, gfx, 43, 155, 178, 45);
|
||||
JD8_Blit(221, 78, gfx, 274, 155, 27, 45);
|
||||
JD8_Flip();
|
||||
if (wait_frame_or_skip()) {
|
||||
|
||||
JD8_FreeSurface(gfx);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
JD8_Blit(43, 78, gfx, 43, 155, 205, 45);
|
||||
JD8_Blit(248, 78, gfx, 274, 155, 27, 45);
|
||||
JD8_Flip();
|
||||
if (wait_frame_or_skip()) {
|
||||
|
||||
JD8_FreeSurface(gfx);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
JG_SetUpdateTicks(200);
|
||||
drawIntroWordmark(gfx);
|
||||
JD8_Blit(274, 78, gfx, 274, 155, 27, 45);
|
||||
JD8_Flip();
|
||||
if (wait_frame_or_skip()) {
|
||||
|
||||
JD8_FreeSurface(gfx);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
JD8_ClearScreen(0);
|
||||
drawIntroWordmark(gfx);
|
||||
JD8_Flip();
|
||||
if (wait_frame_or_skip()) {
|
||||
|
||||
JD8_FreeSurface(gfx);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
drawIntroWordmark(gfx);
|
||||
JD8_Blit(274, 78, gfx, 274, 155, 27, 45);
|
||||
JD8_Flip();
|
||||
if (wait_frame_or_skip()) {
|
||||
|
||||
JD8_FreeSurface(gfx);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
JD8_ClearScreen(0);
|
||||
drawIntroWordmark(gfx);
|
||||
JD8_Flip();
|
||||
if (wait_frame_or_skip()) {
|
||||
|
||||
JD8_FreeSurface(gfx);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
drawIntroWordmark(gfx);
|
||||
JD8_Blit(274, 78, gfx, 274, 155, 27, 45);
|
||||
JD8_Flip();
|
||||
if (wait_frame_or_skip()) {
|
||||
|
||||
JD8_FreeSurface(gfx);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
JD8_ClearScreen(0);
|
||||
drawIntroWordmark(gfx);
|
||||
JD8_Flip();
|
||||
if (wait_frame_or_skip()) {
|
||||
|
||||
JD8_FreeSurface(gfx);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
for (int j = 0; j < 256; j++) {
|
||||
for (int i = 16; i < 32; i++) {
|
||||
if (i == 17) {
|
||||
if (pal[i].r < 255) pal[i].r++;
|
||||
if (pal[i].g < 255) pal[i].g++;
|
||||
if (pal[i].b < 255) pal[i].b++;
|
||||
}
|
||||
if (pal[i].b < pal[i].g) pal[i].b++;
|
||||
if (pal[i].b > pal[i].g) pal[i].b--;
|
||||
if (pal[i].r < pal[i].g) pal[i].r++;
|
||||
if (pal[i].r > pal[i].g) pal[i].r--;
|
||||
}
|
||||
JD8_Flip();
|
||||
}
|
||||
|
||||
if (wait_frame_or_skip()) {
|
||||
|
||||
|
||||
JD8_FreeSurface(gfx);
|
||||
|
||||
|
||||
return;
|
||||
|
||||
|
||||
}
|
||||
|
||||
doIntroSprites(gfx);
|
||||
}
|
||||
|
||||
void ModuleSequence::doIntroSprites(JD8_Surface gfx) {
|
||||
JG_SetUpdateTicks(20);
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@ class ModuleSequence {
|
||||
void doIntroSprites(Uint8* gfx);
|
||||
|
||||
private:
|
||||
void doIntro();
|
||||
void doIntroNewLogo();
|
||||
// doIntro() → migrat a scenes::IntroScene
|
||||
// doIntroNewLogo() → migrat a scenes::IntroNewLogoScene
|
||||
// doMenu() → migrat a scenes::MenuScene
|
||||
// doSlides() → migrat a scenes::SlidesScene
|
||||
// doBanner() → migrat a scenes::BannerScene
|
||||
|
||||
218
source/scenes/intro_scene.cpp
Normal file
218
source/scenes/intro_scene.cpp
Normal file
@@ -0,0 +1,218 @@
|
||||
#include "scenes/intro_scene.hpp"
|
||||
|
||||
#include "core/jail/jdraw8.hpp"
|
||||
#include "core/jail/jinput.hpp"
|
||||
#include "game/info.hpp"
|
||||
#include "game/modulesequence.hpp"
|
||||
#include "scenes/scene_utils.hpp"
|
||||
|
||||
namespace {
|
||||
|
||||
// Timings idèntics als del vell `doIntro()`: el JG_SetUpdateTicks(1000)
|
||||
// inicial, (100) per a les 3 primeres lletres (J, A, I), (200) per a
|
||||
// "JAIL" i el seu clear, (100) per a les 4 lletres centrals
|
||||
// (G, A, M, E) i (200) per a la resta fins al cicle de paleta.
|
||||
constexpr int INITIAL_MS = 1000;
|
||||
constexpr int PALETTE_CYCLE_STEP_MS = 20;
|
||||
constexpr int PALETTE_CYCLE_STEPS = 256;
|
||||
constexpr int FINAL_WAIT_MS = 200;
|
||||
|
||||
// Un pas del revelat. Dos blits configurables (cos del wordmark + avió)
|
||||
// més una variant per al wordmark sencer i un flag de ClearScreen previ.
|
||||
struct RevealStep {
|
||||
int duration_ms;
|
||||
int body_w; // amplada del blit body (43,78) ← (43,155, body_w, 45); 0 si s'usa wordmark
|
||||
int plane_x; // x del blit de l'avió (274,155, 27×45); -1 = no avió
|
||||
bool clear; // fa ClearScreen(0) abans dels blits
|
||||
bool wordmark; // usa drawWordmark() en lloc del blit body (wordmark complet)
|
||||
};
|
||||
|
||||
constexpr RevealStep REVEAL_STEPS[] = {
|
||||
{100, 27, 68, false, false}, // J
|
||||
{100, 53, 96, false, false}, // JA
|
||||
{100, 66, 109, false, false}, // JAI
|
||||
{200, 92, 136, false, false}, // JAIL
|
||||
{200, 92, -1, true, false}, // JAIL (clear, sense avió — parpelleig)
|
||||
{100, 118, 160, false, false}, // JAILG
|
||||
{100, 145, 188, false, false}, // JAILGA
|
||||
{100, 178, 221, false, false}, // JAILGAM
|
||||
{100, 205, 248, false, false}, // JAILGAME
|
||||
{200, 0, 274, false, true}, // JAILGAMES (wordmark complet) + avió
|
||||
{200, 0, -1, true, true}, // JAILGAMES (clear, sense avió)
|
||||
{200, 0, 274, false, true}, // JAILGAMES + avió (sense clear)
|
||||
{200, 0, -1, true, true}, // JAILGAMES (clear, sense avió)
|
||||
{200, 0, 274, false, true}, // JAILGAMES + avió (sense clear)
|
||||
{200, 0, -1, true, true}, // JAILGAMES (clear, sense avió)
|
||||
};
|
||||
constexpr int REVEAL_COUNT = sizeof(REVEAL_STEPS) / sizeof(REVEAL_STEPS[0]);
|
||||
|
||||
// Branca `!use_new_logo` del drawIntroWordmark de modulesequence.cpp:
|
||||
// blit únic del wordmark "JAILGAMES" complet (231×45 al destí 43,78).
|
||||
// IntroScene només s'activa quan use_new_logo == false, així que la
|
||||
// branca use_new_logo d'aquell helper aquí no es necessita.
|
||||
void drawWordmark(JD8_Surface gfx) {
|
||||
JD8_Blit(43, 78, gfx, 43, 155, 231, 45);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace scenes {
|
||||
|
||||
IntroScene::IntroScene() = default;
|
||||
|
||||
IntroScene::~IntroScene() {
|
||||
// No alliberem `pal_`: JD8_SetScreenPalette n'ha pres ownership i el
|
||||
// proper SetScreenPalette / FadeToPal la lliurarà. Alliberar-la ací
|
||||
// provocaria double free.
|
||||
}
|
||||
|
||||
void IntroScene::onEnter() {
|
||||
playMusic("00000003.ogg");
|
||||
|
||||
gfx_ = SurfaceHandle("logo.gif");
|
||||
pal_ = JD8_LoadPalette("logo.gif");
|
||||
JD8_SetScreenPalette(pal_);
|
||||
|
||||
JD8_ClearScreen(0);
|
||||
|
||||
phase_ = Phase::InitialWait;
|
||||
phase_acc_ms_ = 0;
|
||||
reveal_index_ = 0;
|
||||
palette_step_ = 0;
|
||||
}
|
||||
|
||||
void IntroScene::render() {
|
||||
switch (phase_) {
|
||||
case Phase::InitialWait:
|
||||
JD8_ClearScreen(0);
|
||||
break;
|
||||
|
||||
case Phase::Reveal: {
|
||||
const RevealStep& s = REVEAL_STEPS[reveal_index_];
|
||||
if (s.clear) JD8_ClearScreen(0);
|
||||
if (s.wordmark) {
|
||||
drawWordmark(gfx_);
|
||||
} else if (s.body_w > 0) {
|
||||
JD8_Blit(43, 78, gfx_, 43, 155, s.body_w, 45);
|
||||
}
|
||||
if (s.plane_x >= 0) {
|
||||
JD8_Blit(s.plane_x, 78, gfx_, 274, 155, 27, 45);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Phase::PaletteCycle:
|
||||
case Phase::FinalWait:
|
||||
// Wordmark complet fix mentre cicla la paleta — l'últim
|
||||
// pas del revelat (PAS 15) deixa la pantalla en aquest mateix
|
||||
// estat, i el vell doIntro no redibuixava durant el cicle.
|
||||
JD8_ClearScreen(0);
|
||||
drawWordmark(gfx_);
|
||||
break;
|
||||
|
||||
case Phase::Delegate:
|
||||
case Phase::Done:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void IntroScene::advancePaletteCycle() {
|
||||
// Replica exacta del cicle del doIntro vell sobre pal[16..31] — el
|
||||
// grup del verd brillant del logo. Index 17 s'acosta a blanc mentre
|
||||
// els altres convergeixen cap al mateix gris mitjà.
|
||||
for (int i = 16; i < 32; i++) {
|
||||
if (i == 17) {
|
||||
if (pal_[i].r < 255) pal_[i].r++;
|
||||
if (pal_[i].g < 255) pal_[i].g++;
|
||||
if (pal_[i].b < 255) pal_[i].b++;
|
||||
}
|
||||
if (pal_[i].b < pal_[i].g) pal_[i].b++;
|
||||
if (pal_[i].b > pal_[i].g) pal_[i].b--;
|
||||
if (pal_[i].r < pal_[i].g) pal_[i].r++;
|
||||
if (pal_[i].r > pal_[i].g) pal_[i].r--;
|
||||
}
|
||||
}
|
||||
|
||||
void IntroScene::tick(int delta_ms) {
|
||||
// Qualsevol tecla durant el revelat/paleta salta TOTA la intro
|
||||
// (inclou saltar doIntroSprites). El vell `doIntro` tornava abans
|
||||
// de cridar doIntroSprites quan `wait_frame_or_skip` detectava una
|
||||
// tecla. Durant `Delegate` deixem que doIntroSprites gestione el
|
||||
// seu propi skip internament.
|
||||
if (phase_ != Phase::Delegate && phase_ != Phase::Done && JI_AnyKey()) {
|
||||
info::ctx.num_piramide = 0;
|
||||
phase_ = Phase::Done;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (phase_) {
|
||||
case Phase::InitialWait:
|
||||
phase_acc_ms_ += delta_ms;
|
||||
render();
|
||||
if (phase_acc_ms_ >= INITIAL_MS) {
|
||||
phase_ = Phase::Reveal;
|
||||
phase_acc_ms_ = 0;
|
||||
reveal_index_ = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case Phase::Reveal:
|
||||
phase_acc_ms_ += delta_ms;
|
||||
render();
|
||||
if (phase_acc_ms_ >= REVEAL_STEPS[reveal_index_].duration_ms) {
|
||||
phase_acc_ms_ = 0;
|
||||
++reveal_index_;
|
||||
if (reveal_index_ >= REVEAL_COUNT) {
|
||||
phase_ = Phase::PaletteCycle;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Phase::PaletteCycle:
|
||||
phase_acc_ms_ += delta_ms;
|
||||
// Avancem tants passos com permet el delta, per evitar
|
||||
// saltar-ne si el frame ha vingut lent.
|
||||
while (phase_acc_ms_ >= PALETTE_CYCLE_STEP_MS &&
|
||||
palette_step_ < PALETTE_CYCLE_STEPS) {
|
||||
phase_acc_ms_ -= PALETTE_CYCLE_STEP_MS;
|
||||
advancePaletteCycle();
|
||||
++palette_step_;
|
||||
}
|
||||
render();
|
||||
if (palette_step_ >= PALETTE_CYCLE_STEPS) {
|
||||
phase_ = Phase::FinalWait;
|
||||
phase_acc_ms_ = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case Phase::FinalWait:
|
||||
phase_acc_ms_ += delta_ms;
|
||||
render();
|
||||
if (phase_acc_ms_ >= FINAL_WAIT_MS) {
|
||||
phase_ = Phase::Delegate;
|
||||
}
|
||||
break;
|
||||
|
||||
case Phase::Delegate: {
|
||||
// Delegació temporal al codi legacy. La funció legacy sempre
|
||||
// allibera `gfx` ella mateixa (al final i als paths de skip
|
||||
// amb JI_AnyKey), així que transferim ownership via release()
|
||||
// per evitar double free al destructor de SurfaceHandle.
|
||||
// Step 9 reescriurà doIntroSprites com a IntroSpritesScene i
|
||||
// aquesta delegació desapareixerà.
|
||||
ModuleSequence legacy;
|
||||
legacy.doIntroSprites(gfx_.release());
|
||||
// El vell `Go()` post-switch feia `num_piramide = 0` per
|
||||
// passar al menú. Replicat ací: si no, el while del fiber
|
||||
// tornaria a crear IntroScene infinitament.
|
||||
info::ctx.num_piramide = 0;
|
||||
phase_ = Phase::Done;
|
||||
break;
|
||||
}
|
||||
|
||||
case Phase::Done:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace scenes
|
||||
61
source/scenes/intro_scene.hpp
Normal file
61
source/scenes/intro_scene.hpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#pragma once
|
||||
|
||||
#include "core/jail/jdraw8.hpp"
|
||||
#include "scenes/scene.hpp"
|
||||
#include "scenes/surface_handle.hpp"
|
||||
|
||||
namespace scenes {
|
||||
|
||||
// Intro "legacy" del wordmark JAILGAMES lletra a lletra + cicle de paleta.
|
||||
// Reemplaça `ModuleSequence::doIntro()`. S'activa quan
|
||||
// `Options::game.use_new_logo == false`; l'alternativa moderna és
|
||||
// `IntroNewLogoScene`.
|
||||
//
|
||||
// Flux:
|
||||
// 1. Carrega logo.gif, arranca música "00000003.ogg", pantalla negra
|
||||
// 1000 ms.
|
||||
// 2. Revelat: 15 passos (100 o 200 ms) que van acumulant les lletres
|
||||
// "JAILGAMES" d'esquerra a dreta amb un avió escombrant al final
|
||||
// de la paraula. Els passos 5, 11, 13 i 15 netegen la pantalla
|
||||
// per generar els parpelleigs finals.
|
||||
// 3. Cicle de paleta: 256 passos × 20 ms modificant els índexs 16..31.
|
||||
// 4. Espera final 200 ms.
|
||||
// 5. Delega a `ModuleSequence::doIntroSprites(gfx)` (temporal — Step 9
|
||||
// del pla la reescriurà com a IntroSpritesScene i la delegació
|
||||
// desapareixerà).
|
||||
//
|
||||
// Registrada al SceneRegistry amb state_key = 255: la mateixa factory que
|
||||
// per a IntroNewLogoScene, però retornada quan `use_new_logo == false`.
|
||||
class IntroScene : public Scene {
|
||||
public:
|
||||
IntroScene();
|
||||
~IntroScene() override;
|
||||
|
||||
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 {
|
||||
InitialWait, // 1000 ms pantalla negra
|
||||
Reveal, // 15 passos del wordmark
|
||||
PaletteCycle, // 256 × 20 ms mutant pal[16..31]
|
||||
FinalWait, // 200 ms abans de delegar
|
||||
Delegate, // crida ModuleSequence::doIntroSprites (Step 9 elimina)
|
||||
Done,
|
||||
};
|
||||
|
||||
void render();
|
||||
void advancePaletteCycle();
|
||||
|
||||
SurfaceHandle gfx_;
|
||||
JD8_Palette pal_{nullptr}; // propietat transferida a main_palette via SetScreenPalette
|
||||
|
||||
Phase phase_{Phase::InitialWait};
|
||||
int phase_acc_ms_{0};
|
||||
int reveal_index_{0};
|
||||
int palette_step_{0};
|
||||
};
|
||||
|
||||
} // namespace scenes
|
||||
Reference in New Issue
Block a user