#pragma once #include #include #include #include #include "core/rendering/effects/heat_haze.hpp" #include "core/scene/scene.hpp" #include "game/debug_config.hpp" class Surface; class Text; // Escena TITLE provisional. Pinta dos blocs de text sobre un fons gairebé // negre i un prompt "press start" intermitent fins que apareix l'artwork // real. Tota la cosmètica (colors, durada, ritme del parpadeig) viu a // data/ui.yaml secció `title:` per poder afinar-la sense recompilar. class TitleScene : public Scene { public: using SceneFactory = std::function(DebugConfig::StartingPlayers)>; // Fases de l'escena. // - IDLE: animació atràctil. Cap tecla salta; només P1 START o // P2 START fan transició. El timeout (`title.duration_ms`) // salta a la següent escena amb BOTH (modus attract). // - STARTING: comptador fix entre la primera pulsació de START i // la transició. Si l'altre jugador prem START dins d'aquesta // finestra, el comptador es reseteja amb `pending_players_=BOTH`. enum class Phase : std::uint8_t { IDLE, STARTING }; TitleScene(std::shared_ptr display_font, std::shared_ptr condensed_font, std::shared_ptr background, std::shared_ptr mini_logo, SceneFactory next_factory); ~TitleScene() override; void update(int delta_ms) override; void render() override; private: void enterStarting(DebugConfig::StartingPlayers players); void advanceTo(DebugConfig::StartingPlayers players); std::shared_ptr display_font_; std::shared_ptr condensed_font_; std::shared_ptr background_; std::shared_ptr mini_logo_; SceneFactory next_factory_; int timer_ms_; int blink_elapsed_ms_{0}; std::optional heat_haze_; Phase phase_{Phase::IDLE}; int starting_timer_ms_{0}; DebugConfig::StartingPlayers pending_players_{DebugConfig::StartingPlayers::BOTH}; };