step 3: menu_scene substituix doMenu() + fix JI_Update al fiber loop

This commit is contained in:
2026-04-15 23:19:58 +02:00
parent 2cb38ffb49
commit 8720e775a0
6 changed files with 177 additions and 65 deletions

View File

@@ -0,0 +1,113 @@
#include "scenes/menu_scene.hpp"
#include <cstdlib>
#include "core/jail/jdraw8.hpp"
#include "core/jail/jinput.hpp"
#include "game/info.hpp"
namespace scenes {
void MenuScene::onEnter() {
fondo_ = SurfaceHandle("menu.gif");
gfx_ = SurfaceHandle("menu2.gif");
// Pintat inicial (congelat durant el fade-in de paleta). El loop
// d'animació repintarà tot des de zero en el primer tick de Showing.
JD8_Blit(fondo_);
JD8_BlitCK(100, 25, gfx_, 0, 74, 124, 68, 255); // logo
JD8_BlitCK(130, 100, gfx_, 0, 0, 80, 74, 255); // camell (frame 0)
JD8_BlitCK(0, 150, gfx_, 0, 150, 320, 50, 255); // base "jdes"
JD8_Palette pal = JD8_LoadPalette("menu2.gif");
fade_.startFadeTo(pal);
std::free(pal);
phase_ = Phase::FadingIn;
}
void MenuScene::render() {
// Cel estàtic (els primers 100 pixels verticals)
JD8_Blit(0, 0, fondo_, 0, 0, 320, 100);
// Fondo mòvil (horitzó) amb wrap a 320
JD8_BlitCK(horitzo_, 100, fondo_, 0, 100, 320 - horitzo_, 100, 255);
JD8_BlitCK(0, 100, fondo_, 320 - horitzo_, 100, horitzo_, 100, 255);
// Logo i camell animat
JD8_BlitCK(100, 25, gfx_, 0, 74, 124, 68, 255);
JD8_BlitCK(130, 100, gfx_, camello_.frame() * 80, 0, 80, 74, 255);
// Palmeres mòvils amb wrap a 320
JD8_BlitCK(palmeres_, 150, gfx_, 0, 150, 320 - palmeres_, 50, 255);
JD8_BlitCK(0, 150, gfx_, 320 - palmeres_, 150, palmeres_, 50, 255);
// "jdes" estàtic (davant dels scrollers) i versió a la cantonada
JD8_BlitCK(87, 167, gfx_, 127, 124, 150, 24, 255);
JD8_BlitCK(303, 193, gfx_, 305, 143, 15, 5, 255);
// "Polsa tecla" parpallejant. Al vell `contador % 100 > 30` amb
// updateTicks=20 ms, el cicle són 2000 ms amb un llindar de 600 ms:
// amagat els primers 600 ms, visible els següents 1400 ms.
const bool blink_on = (blink_ms_ % 2000) > 600;
if (blink_on) {
JD8_BlitCK(98, 130, gfx_, 161, 92, 127, 9, 255);
if (info::ctx.nou_personatge) {
JD8_BlitCK(68, 141, gfx_, 128, 105, 189, 9, 255);
}
}
}
void MenuScene::tick(int delta_ms) {
switch (phase_) {
case Phase::FadingIn:
fade_.tick(delta_ms);
if (fade_.done()) phase_ = Phase::Showing;
break;
case Phase::Showing: {
// Palmeres: 1 pixel cada 80 ms (= cada 4 ticks × 20 ms originals)
palmeres_acc_ms_ += delta_ms;
while (palmeres_acc_ms_ >= 80) {
palmeres_acc_ms_ -= 80;
if (--palmeres_ < 0) palmeres_ = 319;
}
// Horitzó: 1 pixel cada 320 ms (= cada 16 ticks × 20 ms)
horitzo_acc_ms_ += delta_ms;
while (horitzo_acc_ms_ >= 320) {
horitzo_acc_ms_ -= 320;
if (--horitzo_ < 0) horitzo_ = 319;
}
camello_.tick(delta_ms);
blink_ms_ += delta_ms;
if (blink_ms_ >= 2000) blink_ms_ %= 2000;
render();
// Qualsevol tecla tanca el menú. Llegim 'P' explícitament abans
// de reiniciar el flag de input perquè `info::ctx.pepe_activat`
// reflecteixca si l'usuari estava polsant P al moment d'eixir.
if (JI_AnyKey() || JI_KeyPressed(SDL_SCANCODE_P)) {
info::ctx.pepe_activat = JI_KeyPressed(SDL_SCANCODE_P);
JI_DisableKeyboard(60);
info::ctx.num_piramide = 1;
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

View File

@@ -0,0 +1,57 @@
#pragma once
#include "scenes/frame_animator.hpp"
#include "scenes/palette_fade.hpp"
#include "scenes/scene.hpp"
#include "scenes/surface_handle.hpp"
namespace scenes {
// Menú del títol. Reemplaça `ModuleSequence::doMenu()`.
//
// Flux:
// 1. Carrega menu.gif (fondo) i menu2.gif (sprites) + paleta.
// 2. Pintat inicial estàtic (fondo, logo, camell frame 0, base "jdes"),
// fade-in de paleta.
// 3. Loop d'animació: escroll parallax de horitzó (cada 320 ms) i
// palmeres (cada 80 ms), cicle del camell (4 frames × 160 ms),
// i el text "polsa tecla" parpallejant cada 2 s (visible 1.4 s,
// amagat 0.6 s, igual que el `contador % 100 > 30` original).
// 4. Quan l'usuari polsa qualsevol tecla — o 'P' per a activar Pepe —
// llegim `info::ctx.pepe_activat`, disparem fade-out i marquem
// num_piramide=1 (vas a doSlides).
//
// Registrat al SceneRegistry amb state_key = 0.
class MenuScene : 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 1; }
private:
enum class Phase { FadingIn,
Showing,
FadingOut,
Done };
void render();
SurfaceHandle fondo_;
SurfaceHandle gfx_;
PaletteFade fade_;
FrameAnimator camello_{4, 160, true};
Phase phase_{Phase::FadingIn};
// Scrollers horizontals. Mouen 1 pixel per pas.
int palmeres_{0};
int horitzo_{0};
int palmeres_acc_ms_{0};
int horitzo_acc_ms_{0};
// Acumulador per al parpalleig del text "polsa tecla".
int blink_ms_{0};
};
} // namespace scenes