Files
aee/source/scenes/credits_scene.cpp
Sergio Valor fe41919e1e clang-format
mogudes coses de config.yaml a debug.yaml
2026-04-16 16:46:18 +02:00

147 lines
4.8 KiB
C++

#include "scenes/credits_scene.hpp"
#include <cstdio>
#include <cstdlib>
#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 {
// Frames del cotxe: 8 posicions dins del sprite sheet gfx/final.gif. El
// vell doCredits tenia aquesta taula inline — la reproduïm idèntica.
struct CocheFrame {
Uint16 x, y;
};
constexpr CocheFrame COCHE_FRAMES[8] = {
{214, 152},
{214, 104},
{214, 56},
{214, 104},
{214, 152},
{214, 8},
{108, 152},
{214, 8},
};
constexpr int CONTADOR_MAX = 3100; // ~62 s de crèdits a 20 ms/tick
constexpr int TICK_MS = 20; // JG_SetUpdateTicks heretat del doSlides previ
constexpr int BG_INDEX = 255;
} // namespace
namespace scenes {
CreditsScene::~CreditsScene() {
// No toquem la paleta activa: SetScreenPalette n'ha pres ownership.
}
void CreditsScene::onEnter() {
// El vell doCredits no tocava música — heretava la del doSlides
// previ ("music/00000005.ogg"). Si l'escena s'arrenca directament (test
// amb piramide_inicial=8) no hi ha res que heretar, així que
// arranquem la mateixa pista només si no sona res. Inocu en el
// flux normal: JA_MUSIC_PLAYING fa que no la tornem a tocar.
if (JA_GetMusicState() != JA_MUSIC_PLAYING) {
playMusic("music/00000005.ogg");
}
vaddr2_ = SurfaceHandle("gfx/final.gif");
vaddr3_ = SurfaceHandle("gfx/finals.gif");
JD8_Palette pal = JD8_LoadPalette("gfx/final.gif");
JD8_SetScreenPalette(pal);
// `pal` passa a ser propietat de main_palette — no l'alliberem.
phase_ = Phase::Rolling;
contador_ = 1;
contador_acc_ms_ = 0;
}
void CreditsScene::render() {
JD8_ClearScreen(BG_INDEX);
// Columna 1: scroll vertical del bloc (0,0,80,200) pujant des de
// y=200 fins que el contador supera 2750.
if (contador_ < 2750) {
JD8_BlitCKCut(115, 200 - (contador_ / 6), vaddr2_, 0, 0, 80, 200, 0);
}
// Columna 2: scroll vertical del bloc (85,0,120,140), arrenca
// a contador 1200 i s'atura (fix en y=20) a partir de 2250.
if ((contador_ > 1200) && (contador_ < 2280)) {
JD8_BlitCKCut(100, 200 - ((contador_ - 1200) / 6), vaddr2_, 85, 0, 120, 140, 0);
} else if (contador_ >= 2250) {
JD8_BlitCK(100, 20, vaddr2_, 85, 0, 120, 140, 0);
}
// Fons: 4 capes parallax + cotxe només si l'usuari ha aconseguit
// tots els diamants (final "bo"). Altrament fons estàtic.
if (info::ctx.diamants == 16) {
JD8_BlitCKScroll(50, vaddr3_, ((contador_ >> 3) % 320) + 1, 0, 50, 255);
JD8_BlitCKScroll(50, vaddr3_, ((contador_ >> 2) % 320) + 1, 50, 50, 255);
JD8_BlitCKScroll(50, vaddr3_, ((contador_ >> 1) % 320) + 1, 100, 50, 255);
JD8_BlitCKScroll(50, vaddr3_, (contador_ % 320) + 1, 150, 50, 255);
const CocheFrame& cf = COCHE_FRAMES[coche_.frame()];
JD8_BlitCK(100, 50, vaddr2_, cf.x, cf.y, 106, 48, 255);
} else {
JD8_BlitCK(0, 50, vaddr3_, 0, 0, 320, 50, 255);
JD8_BlitCK(0, 50, vaddr3_, 0, 50, 320, 50, 255);
}
// Barres de marc que cobreixen els extrems del scroll vertical.
JD8_FillSquare(0, 50, BG_INDEX);
JD8_FillSquare(100, 10, BG_INDEX);
}
void CreditsScene::writeTrickIni() {
FILE* ini = std::fopen("trick.ini", "wb");
if (ini) {
std::fwrite("1", 1, 1, ini);
std::fclose(ini);
}
info::ctx.nou_personatge = true;
}
void CreditsScene::tick(int delta_ms) {
switch (phase_) {
case Phase::Rolling: {
// Avancem el contador en passos discrets de 20 ms, igual
// que feia JG_ShouldUpdate(20) al vell doCredits.
contador_acc_ms_ += delta_ms;
while (contador_acc_ms_ >= TICK_MS) {
contador_acc_ms_ -= TICK_MS;
++contador_;
}
coche_.tick(delta_ms);
render();
if (JI_AnyKey() || contador_ >= CONTADOR_MAX) {
writeTrickIni();
fade_.startFadeOut();
phase_ = Phase::FadingOut;
}
break;
}
case Phase::FadingOut:
fade_.tick(delta_ms);
if (fade_.done()) {
info::ctx.num_piramide = 255;
phase_ = Phase::Done;
}
break;
case Phase::Done:
break;
}
}
} // namespace scenes