step 7: secreta_scene amb swap de tomba1→tomba2 i red pulse animat
This commit is contained in:
@@ -55,6 +55,7 @@ set(APP_SOURCES
|
|||||||
source/scenes/intro_new_logo_scene.cpp
|
source/scenes/intro_new_logo_scene.cpp
|
||||||
source/scenes/slides_scene.cpp
|
source/scenes/slides_scene.cpp
|
||||||
source/scenes/credits_scene.cpp
|
source/scenes/credits_scene.cpp
|
||||||
|
source/scenes/secreta_scene.cpp
|
||||||
|
|
||||||
# Game
|
# Game
|
||||||
source/game/options.cpp
|
source/game/options.cpp
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#include "scenes/mort_scene.hpp"
|
#include "scenes/mort_scene.hpp"
|
||||||
#include "scenes/scene.hpp"
|
#include "scenes/scene.hpp"
|
||||||
#include "scenes/scene_registry.hpp"
|
#include "scenes/scene_registry.hpp"
|
||||||
|
#include "scenes/secreta_scene.hpp"
|
||||||
#include "scenes/slides_scene.hpp"
|
#include "scenes/slides_scene.hpp"
|
||||||
|
|
||||||
// Cheats del joc original — declarats a jinput.cpp
|
// Cheats del joc original — declarats a jinput.cpp
|
||||||
@@ -43,7 +44,7 @@ namespace {
|
|||||||
void gameFiberEntry() {
|
void gameFiberEntry() {
|
||||||
info::ctx.num_habitacio = Options::game.habitacio_inicial;
|
info::ctx.num_habitacio = Options::game.habitacio_inicial;
|
||||||
info::ctx.num_piramide = Options::game.piramide_inicial;
|
info::ctx.num_piramide = Options::game.piramide_inicial;
|
||||||
info::ctx.diners = 0;
|
info::ctx.diners = Options::game.diners_inicial;
|
||||||
info::ctx.diamants = Options::game.diamants_inicial;
|
info::ctx.diamants = Options::game.diamants_inicial;
|
||||||
info::ctx.vida = Options::game.vides;
|
info::ctx.vida = Options::game.vides;
|
||||||
info::ctx.momies = 0;
|
info::ctx.momies = 0;
|
||||||
@@ -130,6 +131,7 @@ void Director::init() {
|
|||||||
// l'usuari no té prou diners per a la Secreta)
|
// l'usuari no té prou diners per a la Secreta)
|
||||||
registry.registerScene(1, [] { return std::make_unique<scenes::SlidesScene>(); });
|
registry.registerScene(1, [] { return std::make_unique<scenes::SlidesScene>(); });
|
||||||
registry.registerScene(7, [] { return std::make_unique<scenes::SlidesScene>(); });
|
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>(); });
|
registry.registerScene(8, [] { return std::make_unique<scenes::CreditsScene>(); });
|
||||||
// IntroNewLogoScene només es registra quan `use_new_logo` està actiu;
|
// IntroNewLogoScene només es registra quan `use_new_logo` està actiu;
|
||||||
// si no, la factory retorna nullptr i el gameFiberEntry cau al vell
|
// si no, la factory retorna nullptr i el gameFiberEntry cau al vell
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ namespace Defaults::Game {
|
|||||||
constexpr int PIRAMIDE_INICIAL = 255;
|
constexpr int PIRAMIDE_INICIAL = 255;
|
||||||
constexpr int VIDES = 5;
|
constexpr int VIDES = 5;
|
||||||
constexpr int DIAMANTS_INICIAL = 0;
|
constexpr int DIAMANTS_INICIAL = 0;
|
||||||
|
constexpr int DINERS_INICIAL = 0;
|
||||||
constexpr bool USE_NEW_LOGO = true;
|
constexpr bool USE_NEW_LOGO = true;
|
||||||
constexpr bool SHOW_TITLE_CREDITS = true;
|
constexpr bool SHOW_TITLE_CREDITS = true;
|
||||||
} // namespace Defaults::Game
|
} // namespace Defaults::Game
|
||||||
|
|||||||
@@ -41,9 +41,7 @@ int ModuleSequence::Go() {
|
|||||||
// case 0 (Menú) → migrat a scenes::MenuScene.
|
// case 0 (Menú) → migrat a scenes::MenuScene.
|
||||||
// case 1 i 7 (Slides) → migrat a scenes::SlidesScene.
|
// case 1 i 7 (Slides) → migrat a scenes::SlidesScene.
|
||||||
// case 2..5 (Pre-piràmide) → migrat a scenes::BannerScene.
|
// case 2..5 (Pre-piràmide) → migrat a scenes::BannerScene.
|
||||||
case 6: // Pre-Secreta
|
// case 6 (Pre-Secreta) → migrat a scenes::SecretaScene.
|
||||||
doSecreta();
|
|
||||||
break;
|
|
||||||
// case 8 (Credits) → migrat a scenes::CreditsScene.
|
// case 8 (Credits) → migrat a scenes::CreditsScene.
|
||||||
// case 100 (Mort) → migrat a scenes::MortScene, dispatch via SceneRegistry.
|
// case 100 (Mort) → migrat a scenes::MortScene, dispatch via SceneRegistry.
|
||||||
}
|
}
|
||||||
@@ -822,92 +820,7 @@ void ModuleSequence::doIntroSprites(JD8_Surface gfx) {
|
|||||||
|
|
||||||
// doBanner() — migrat a scenes::BannerScene (source/scenes/banner_scene.cpp)
|
// doBanner() — migrat a scenes::BannerScene (source/scenes/banner_scene.cpp)
|
||||||
|
|
||||||
void ModuleSequence::doSecreta() {
|
// doSecreta() — migrat a scenes::SecretaScene (source/scenes/secreta_scene.cpp)
|
||||||
play_music("00000002.ogg");
|
|
||||||
JG_SetUpdateTicks(20);
|
|
||||||
JD8_FadeOut();
|
|
||||||
JD8_Surface gfx = JD8_LoadSurface("tomba1.gif");
|
|
||||||
JD8_Palette pal_aux = JD8_LoadPalette("tomba1.gif");
|
|
||||||
JD8_Palette pal = (JD8_Palette)malloc(768);
|
|
||||||
memcpy(pal, pal_aux, 768);
|
|
||||||
JD8_ClearScreen(255);
|
|
||||||
JD8_SetScreenPalette(pal);
|
|
||||||
|
|
||||||
bool exit = false;
|
|
||||||
int step = 0;
|
|
||||||
contador = 1;
|
|
||||||
while (!exit && !JG_Quitting()) {
|
|
||||||
if (JG_ShouldUpdate()) {
|
|
||||||
JI_Update();
|
|
||||||
|
|
||||||
if (JI_AnyKey()) {
|
|
||||||
exit = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (step) {
|
|
||||||
case 0:
|
|
||||||
JD8_Blit(70, 60, gfx, 0, contador, 178, 70); // Put_Sprite(from, where, 0 + (320 * i), 178, 70, 70, 60);
|
|
||||||
JD8_BlitCK(70, 60, gfx, 178, contador >> 1, 142, 70, 255); // Put_Sprite(from, where, 178 + (320 * (i div 2)), 142, 70, 70, 60);
|
|
||||||
JD8_Flip();
|
|
||||||
contador++;
|
|
||||||
if (contador == 128) step++;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
case 4:
|
|
||||||
case 7:
|
|
||||||
case 9:
|
|
||||||
contador--;
|
|
||||||
if (contador == 0) step++;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
JD8_ClearScreen(255);
|
|
||||||
JD8_Flip();
|
|
||||||
gfx = JD8_LoadSurface("tomba2.gif");
|
|
||||||
pal_aux = JD8_LoadPalette("tomba2.gif");
|
|
||||||
memcpy(pal, pal_aux, 768);
|
|
||||||
JD8_SetScreenPalette(pal);
|
|
||||||
step++;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
JD8_Blit(55, 53, gfx, 0, 158 - contador, 211, contador); // Put_Sprite(from, where, 0 + ((158 - i) * 320), 211, i, 55, 53);
|
|
||||||
JD8_Flip();
|
|
||||||
contador++;
|
|
||||||
if (contador == 94) step++;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
JD8_ClearScreen(0);
|
|
||||||
JD8_Flip();
|
|
||||||
JD8_SetPaletteColor(254, 12, 11, 11);
|
|
||||||
JD8_SetPaletteColor(253, 12, 11, 11);
|
|
||||||
step++;
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
JD8_Blit(80, 68, gfx, 160 - (contador * 2), 0, contador * 2, 64); // Put_Sprite(from, where, 160 - (i * 2), (i * 2), 64, 80, 68);
|
|
||||||
JD8_Flip();
|
|
||||||
contador++;
|
|
||||||
if (contador == 80) step++;
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
JD8_SetPaletteColor(254, contador + 12, 11, 11);
|
|
||||||
JD8_SetPaletteColor(253, (contador + 12) >> 1, 11, 11);
|
|
||||||
JD8_Flip();
|
|
||||||
contador++;
|
|
||||||
if (contador == 51) step++;
|
|
||||||
break;
|
|
||||||
case 10:
|
|
||||||
JD8_FadeOut();
|
|
||||||
memcpy(pal, pal_aux, 768);
|
|
||||||
JD8_ClearScreen(255);
|
|
||||||
JA_FadeOutMusic(250);
|
|
||||||
exit = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
JD8_FreeSurface(gfx);
|
|
||||||
free(pal_aux);
|
|
||||||
}
|
|
||||||
|
|
||||||
// doCredits() — migrat a scenes::CreditsScene (source/scenes/credits_scene.cpp)
|
// doCredits() — migrat a scenes::CreditsScene (source/scenes/credits_scene.cpp)
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class ModuleSequence {
|
|||||||
// doMenu() → migrat a scenes::MenuScene
|
// doMenu() → migrat a scenes::MenuScene
|
||||||
// doSlides() → migrat a scenes::SlidesScene
|
// doSlides() → migrat a scenes::SlidesScene
|
||||||
// doBanner() → migrat a scenes::BannerScene
|
// doBanner() → migrat a scenes::BannerScene
|
||||||
void doSecreta();
|
// doSecreta() → migrat a scenes::SecretaScene
|
||||||
// doCredits() → migrat a scenes::CreditsScene
|
// doCredits() → migrat a scenes::CreditsScene
|
||||||
// doMort() → migrat a scenes::MortScene
|
// doMort() → migrat a scenes::MortScene
|
||||||
|
|
||||||
|
|||||||
@@ -146,6 +146,8 @@ namespace Options {
|
|||||||
game.vides = node["vides"].get_value<int>();
|
game.vides = node["vides"].get_value<int>();
|
||||||
if (node.contains("diamants_inicial"))
|
if (node.contains("diamants_inicial"))
|
||||||
game.diamants_inicial = node["diamants_inicial"].get_value<int>();
|
game.diamants_inicial = node["diamants_inicial"].get_value<int>();
|
||||||
|
if (node.contains("diners_inicial"))
|
||||||
|
game.diners_inicial = node["diners_inicial"].get_value<int>();
|
||||||
if (node.contains("use_new_logo"))
|
if (node.contains("use_new_logo"))
|
||||||
game.use_new_logo = node["use_new_logo"].get_value<bool>();
|
game.use_new_logo = node["use_new_logo"].get_value<bool>();
|
||||||
if (node.contains("show_title_credits"))
|
if (node.contains("show_title_credits"))
|
||||||
@@ -281,6 +283,7 @@ namespace Options {
|
|||||||
file << " piramide_inicial: " << game.piramide_inicial << "\n";
|
file << " piramide_inicial: " << game.piramide_inicial << "\n";
|
||||||
file << " vides: " << game.vides << "\n";
|
file << " vides: " << game.vides << "\n";
|
||||||
file << " diamants_inicial: " << game.diamants_inicial << "\n";
|
file << " diamants_inicial: " << game.diamants_inicial << "\n";
|
||||||
|
file << " diners_inicial: " << game.diners_inicial << "\n";
|
||||||
file << " use_new_logo: " << (game.use_new_logo ? "true" : "false") << "\n";
|
file << " use_new_logo: " << (game.use_new_logo ? "true" : "false") << "\n";
|
||||||
file << " show_title_credits: " << (game.show_title_credits ? "true" : "false") << "\n";
|
file << " show_title_credits: " << (game.show_title_credits ? "true" : "false") << "\n";
|
||||||
file << "\n";
|
file << "\n";
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ namespace Options {
|
|||||||
int piramide_inicial{Defaults::Game::PIRAMIDE_INICIAL};
|
int piramide_inicial{Defaults::Game::PIRAMIDE_INICIAL};
|
||||||
int vides{Defaults::Game::VIDES};
|
int vides{Defaults::Game::VIDES};
|
||||||
int diamants_inicial{Defaults::Game::DIAMANTS_INICIAL};
|
int diamants_inicial{Defaults::Game::DIAMANTS_INICIAL};
|
||||||
|
int diners_inicial{Defaults::Game::DINERS_INICIAL};
|
||||||
bool use_new_logo{Defaults::Game::USE_NEW_LOGO};
|
bool use_new_logo{Defaults::Game::USE_NEW_LOGO};
|
||||||
bool show_title_credits{Defaults::Game::SHOW_TITLE_CREDITS};
|
bool show_title_credits{Defaults::Game::SHOW_TITLE_CREDITS};
|
||||||
};
|
};
|
||||||
|
|||||||
205
source/scenes/secreta_scene.cpp
Normal file
205
source/scenes/secreta_scene.cpp
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
#include "scenes/secreta_scene.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#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 {
|
||||||
|
|
||||||
|
constexpr int TICK_MS = 20; // JG_SetUpdateTicks(20) del vell doSecreta
|
||||||
|
|
||||||
|
// Durades per fase, derivades dels contador-thresholds del vell:
|
||||||
|
// tomba1 scroll: 127 passos (contador 1→128) × 20ms
|
||||||
|
// tomba1 hold: 128 passos (contador 128→0) × 20ms
|
||||||
|
// tomba2 scroll: 94 passos × 20ms
|
||||||
|
// tomba2 hold: 94 passos × 20ms
|
||||||
|
// reveal horit: 80 passos × 20ms
|
||||||
|
// reveal hold: 80 passos × 20ms
|
||||||
|
// red pulse: 51 passos × 20ms
|
||||||
|
// red pulse hold: 51 passos × 20ms
|
||||||
|
constexpr int TOMBA1_SCROLL_MS = 127 * TICK_MS;
|
||||||
|
constexpr int TOMBA1_HOLD_MS = 128 * TICK_MS;
|
||||||
|
constexpr int TOMBA2_SCROLL_MS = 94 * TICK_MS;
|
||||||
|
constexpr int TOMBA2_HOLD_MS = 94 * TICK_MS;
|
||||||
|
constexpr int TOMBA2_REVEAL_MS = 80 * TICK_MS;
|
||||||
|
constexpr int TOMBA2_REVEAL_HOLD_MS = 80 * TICK_MS;
|
||||||
|
constexpr int RED_PULSE_MS = 51 * TICK_MS;
|
||||||
|
constexpr int RED_PULSE_HOLD_MS = 51 * TICK_MS;
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace scenes {
|
||||||
|
|
||||||
|
SecretaScene::~SecretaScene() {
|
||||||
|
if (pal_aux_) std::free(pal_aux_);
|
||||||
|
// pal_active_ NO s'allibera: propietat de main_palette via SetScreenPalette.
|
||||||
|
}
|
||||||
|
|
||||||
|
void SecretaScene::onEnter() {
|
||||||
|
playMusic("00000002.ogg");
|
||||||
|
|
||||||
|
// Fade-out de la paleta anterior. Els assets es carreguen ja
|
||||||
|
// però no fem SetScreenPalette fins que acabe el fade — així
|
||||||
|
// el fade opera sobre la paleta del mòdul anterior.
|
||||||
|
fade_.startFadeOut();
|
||||||
|
|
||||||
|
gfx_ = SurfaceHandle("tomba1.gif");
|
||||||
|
pal_aux_ = JD8_LoadPalette("tomba1.gif");
|
||||||
|
pal_active_ = static_cast<JD8_Palette>(std::malloc(768));
|
||||||
|
std::memcpy(pal_active_, pal_aux_, 768);
|
||||||
|
|
||||||
|
phase_ = Phase::InitialFadeOut;
|
||||||
|
phase_acc_ms_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SecretaScene::swapToTomba2() {
|
||||||
|
JD8_ClearScreen(255);
|
||||||
|
gfx_.reset("tomba2.gif");
|
||||||
|
|
||||||
|
std::free(pal_aux_);
|
||||||
|
pal_aux_ = JD8_LoadPalette("tomba2.gif");
|
||||||
|
// pal_active_ continua sent el mateix buffer: només actualitzem
|
||||||
|
// el seu contingut. main_palette ja apunta ací.
|
||||||
|
std::memcpy(pal_active_, pal_aux_, 768);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SecretaScene::beginRedPulseSetup() {
|
||||||
|
JD8_ClearScreen(0);
|
||||||
|
JD8_SetPaletteColor(254, 12, 11, 11);
|
||||||
|
JD8_SetPaletteColor(253, 12, 11, 11);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SecretaScene::beginFinalFade() {
|
||||||
|
JA_FadeOutMusic(250);
|
||||||
|
fade_.startFadeOut();
|
||||||
|
phase_ = Phase::FinalFadeOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SecretaScene::tick(int delta_ms) {
|
||||||
|
// Skip per tecla (després del fade inicial, no mentre). Salta
|
||||||
|
// directament al FinalFadeOut. Mateix patró que el vell, on
|
||||||
|
// qualsevol tecla sortia del loop.
|
||||||
|
if (!skip_triggered_ && phase_ != Phase::InitialFadeOut && JI_AnyKey()) {
|
||||||
|
skip_triggered_ = true;
|
||||||
|
beginFinalFade();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (phase_) {
|
||||||
|
case Phase::InitialFadeOut:
|
||||||
|
fade_.tick(delta_ms);
|
||||||
|
if (fade_.done()) {
|
||||||
|
// Ara main_palette (la vella) té tots els canals a 0.
|
||||||
|
// SetScreenPalette allibera la vella i adopta pal_active_
|
||||||
|
// — des d'ara main_palette == pal_active_, així que les
|
||||||
|
// futures escriptures a pal_active_ afecten la pantalla.
|
||||||
|
JD8_SetScreenPalette(pal_active_);
|
||||||
|
JD8_ClearScreen(255);
|
||||||
|
phase_ = Phase::Tomba1ScrollIn;
|
||||||
|
phase_acc_ms_ = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Phase::Tomba1ScrollIn: {
|
||||||
|
phase_acc_ms_ += delta_ms;
|
||||||
|
const int contador = std::min(128, phase_acc_ms_ / TICK_MS + 1);
|
||||||
|
// Dos blits solapats: el primer avança a velocitat completa,
|
||||||
|
// el segon (contingut de la dreta del src) a meitat (contador>>1).
|
||||||
|
JD8_Blit(70, 60, gfx_, 0, contador, 178, 70);
|
||||||
|
JD8_BlitCK(70, 60, gfx_, 178, contador >> 1, 142, 70, 255);
|
||||||
|
if (phase_acc_ms_ >= TOMBA1_SCROLL_MS) {
|
||||||
|
phase_ = Phase::Tomba1Hold;
|
||||||
|
phase_acc_ms_ = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Phase::Tomba1Hold:
|
||||||
|
phase_acc_ms_ += delta_ms;
|
||||||
|
if (phase_acc_ms_ >= TOMBA1_HOLD_MS) {
|
||||||
|
swapToTomba2();
|
||||||
|
phase_ = Phase::Tomba2ScrollIn;
|
||||||
|
phase_acc_ms_ = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Phase::Tomba2ScrollIn: {
|
||||||
|
phase_acc_ms_ += delta_ms;
|
||||||
|
const int contador = std::min(94, phase_acc_ms_ / TICK_MS + 1);
|
||||||
|
JD8_Blit(55, 53, gfx_, 0, 158 - contador, 211, contador);
|
||||||
|
if (phase_acc_ms_ >= TOMBA2_SCROLL_MS) {
|
||||||
|
phase_ = Phase::Tomba2Hold;
|
||||||
|
phase_acc_ms_ = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Phase::Tomba2Hold:
|
||||||
|
phase_acc_ms_ += delta_ms;
|
||||||
|
if (phase_acc_ms_ >= TOMBA2_HOLD_MS) {
|
||||||
|
beginRedPulseSetup();
|
||||||
|
phase_ = Phase::Tomba2Reveal;
|
||||||
|
phase_acc_ms_ = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Phase::Tomba2Reveal: {
|
||||||
|
phase_acc_ms_ += delta_ms;
|
||||||
|
const int contador = std::min(80, phase_acc_ms_ / TICK_MS + 1);
|
||||||
|
// Revelat horitzontal simètric: l'amplada creix 2px per tick
|
||||||
|
// i el src_x es desplaça a l'esquerra el mateix.
|
||||||
|
JD8_Blit(80, 68, gfx_, 160 - (contador * 2), 0, contador * 2, 64);
|
||||||
|
if (phase_acc_ms_ >= TOMBA2_REVEAL_MS) {
|
||||||
|
phase_ = Phase::Tomba2RevealHold;
|
||||||
|
phase_acc_ms_ = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Phase::Tomba2RevealHold:
|
||||||
|
phase_acc_ms_ += delta_ms;
|
||||||
|
if (phase_acc_ms_ >= TOMBA2_REVEAL_HOLD_MS) {
|
||||||
|
phase_ = Phase::RedPulse;
|
||||||
|
phase_acc_ms_ = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Phase::RedPulse: {
|
||||||
|
phase_acc_ms_ += delta_ms;
|
||||||
|
const int contador = std::min(51, phase_acc_ms_ / TICK_MS);
|
||||||
|
// Anima el canal R dels índexs 254 i 253 (aquest a la meitat
|
||||||
|
// de brillantor). Va de (12,11,11) fins a (63,11,11) / (31,11,11).
|
||||||
|
JD8_SetPaletteColor(254, contador + 12, 11, 11);
|
||||||
|
JD8_SetPaletteColor(253, (contador + 12) >> 1, 11, 11);
|
||||||
|
if (phase_acc_ms_ >= RED_PULSE_MS) {
|
||||||
|
phase_ = Phase::RedPulseHold;
|
||||||
|
phase_acc_ms_ = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Phase::RedPulseHold:
|
||||||
|
phase_acc_ms_ += delta_ms;
|
||||||
|
if (phase_acc_ms_ >= RED_PULSE_HOLD_MS) {
|
||||||
|
beginFinalFade();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Phase::FinalFadeOut:
|
||||||
|
fade_.tick(delta_ms);
|
||||||
|
if (fade_.done()) {
|
||||||
|
phase_ = Phase::Done;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Phase::Done:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace scenes
|
||||||
66
source/scenes/secreta_scene.hpp
Normal file
66
source/scenes/secreta_scene.hpp
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "core/jail/jdraw8.hpp"
|
||||||
|
#include "scenes/palette_fade.hpp"
|
||||||
|
#include "scenes/scene.hpp"
|
||||||
|
#include "scenes/surface_handle.hpp"
|
||||||
|
|
||||||
|
namespace scenes {
|
||||||
|
|
||||||
|
// Pre-Secreta. Reemplaça `ModuleSequence::doSecreta()`.
|
||||||
|
//
|
||||||
|
// Flux:
|
||||||
|
// 1. Arranca música "00000002.ogg" i fa fade-out de la paleta anterior.
|
||||||
|
// 2. Carrega tomba1.gif + paleta i pinta un scroll vertical doble
|
||||||
|
// (dos blits solapats, un a velocitat meitat que l'altre) durant
|
||||||
|
// ~2.5 s + ~2.5 s de pausa.
|
||||||
|
// 3. Swap a tomba2.gif + reset de paleta, scroll vertical del segon
|
||||||
|
// asset (~1.9 s + ~1.9 s de pausa).
|
||||||
|
// 4. ClearScreen a 0, set colors 253/254 a vermell fosc (12,11,11)
|
||||||
|
// i pinta un revelat horitzontal (~1.6 s + ~1.6 s de pausa).
|
||||||
|
// 5. "Red pulse": anima els colors 253/254 incrementant el canal R
|
||||||
|
// de 12 a 62 durant ~1 s (+ ~1 s de pausa).
|
||||||
|
// 6. FadeOut + JA_FadeOutMusic(250).
|
||||||
|
// 7. Retorna nextState=0 per entrar al ModuleGame amb num_piramide=6.
|
||||||
|
//
|
||||||
|
// Registrada al SceneRegistry amb state_key = 6.
|
||||||
|
class SecretaScene : public Scene {
|
||||||
|
public:
|
||||||
|
SecretaScene() = default;
|
||||||
|
~SecretaScene() override;
|
||||||
|
|
||||||
|
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 {
|
||||||
|
InitialFadeOut,
|
||||||
|
Tomba1ScrollIn,
|
||||||
|
Tomba1Hold,
|
||||||
|
Tomba2ScrollIn,
|
||||||
|
Tomba2Hold,
|
||||||
|
Tomba2Reveal,
|
||||||
|
Tomba2RevealHold,
|
||||||
|
RedPulse,
|
||||||
|
RedPulseHold,
|
||||||
|
FinalFadeOut,
|
||||||
|
Done,
|
||||||
|
};
|
||||||
|
|
||||||
|
void swapToTomba2();
|
||||||
|
void beginRedPulseSetup();
|
||||||
|
void beginFinalFade();
|
||||||
|
|
||||||
|
SurfaceHandle gfx_;
|
||||||
|
JD8_Palette pal_aux_{nullptr};
|
||||||
|
JD8_Palette pal_active_{nullptr}; // propietat transferida a main_palette
|
||||||
|
PaletteFade fade_;
|
||||||
|
|
||||||
|
Phase phase_{Phase::InitialFadeOut};
|
||||||
|
int phase_acc_ms_{0};
|
||||||
|
bool skip_triggered_{false};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace scenes
|
||||||
Reference in New Issue
Block a user