diff --git a/source/game/scenes/game_scene.cpp b/source/game/scenes/game_scene.cpp index 7022008..2e86219 100644 --- a/source/game/scenes/game_scene.cpp +++ b/source/game/scenes/game_scene.cpp @@ -269,10 +269,16 @@ void GameScene::handleEvent(const SDL_Event& event) { } void GameScene::update(float delta_time) { - // Pausa global: mentre el menu de servei esta obert, congelem la lògica - // de joc. El draw() segueix executant-se per a mantenir l'escena visible - // sota el menu. - if (const auto* menu = System::ServiceMenu::get(); menu != nullptr && menu->isOpen()) { + // El menu de servei "flota" sobre l'escena: l'input se'n va cap a ell, mai + // "a baix". En partida normal pausem la lògica de joc mentre està obert (el + // draw() segueix executant-se per a mantindre l'escena visible sota el menu). + // En DEMO (attract) NO pausem: la demo ha de seguir viva sota el menu; només + // evitem que l'input la trenque (flag MENU_OPEN cap a stepDemo). Amb l'overlay + // de redefinir controls actiu el menu segueix "open", així que aquest únic + // check ja cobreix tots dos casos. + const auto* menu = System::ServiceMenu::get(); + const bool MENU_OPEN = (menu != nullptr) && menu->isOpen(); + if (MENU_OPEN && match_config_.mode != GameConfig::Mode::DEMO) { return; } @@ -282,7 +288,7 @@ void GameScene::update(float delta_time) { if (match_config_.mode == GameConfig::Mode::DEMO) { // Mode demo (attract): salida por input/timeout/muerte + control del pilot. - if (stepDemo(delta_time)) { + if (stepDemo(delta_time, MENU_OPEN)) { return; } } else if (game_over_state_ == GameOverState::NONE) { @@ -376,11 +382,13 @@ void GameScene::updateShipsControl(float delta_time) { } } -auto GameScene::stepDemo(float delta_time) -> bool { +auto GameScene::stepDemo(float delta_time, bool input_blocked) -> bool { curtain_.update(delta_time); // cortinilla que destapa la demo - // Qualsevol input trenca la demo i torna al títol (música intacta). - if (Input::get()->checkAnyPlayerAction(DEMO_EXIT_ACTIONS)) { + // Qualsevol input trenca la demo i torna al títol (música intacta), pero NO + // mentre el menu de servei estiga obert: en eixe cas l'input va al menu i no + // arriba "a baix", així que la demo ha de seguir corrent sota seu. + if (!input_blocked && Input::get()->checkAnyPlayerAction(DEMO_EXIT_ACTIONS)) { context_.setNextScene(SceneType::TITLE, Option::JUMP_TO_TITLE_MAIN); return true; } diff --git a/source/game/scenes/game_scene.hpp b/source/game/scenes/game_scene.hpp index 2b18e2e..94f5141 100644 --- a/source/game/scenes/game_scene.hpp +++ b/source/game/scenes/game_scene.hpp @@ -153,7 +153,9 @@ class GameScene final : public Scene { void updateShipsControl(float delta_time); // Mode DEMO: gestiona salida (input→título, timeout/muerte→logo) y calcula // el control + disparo del pilot. Devuelve true si la escena transiciona. - [[nodiscard]] auto stepDemo(float delta_time) -> bool; + // input_blocked: si un overlay (menu de servei / redefinir controls) està + // capturant l'input, no es deixa que l'input trenque la demo (segueix viva). + [[nodiscard]] auto stepDemo(float delta_time, bool input_blocked) -> bool; void endDemo(); // Devuelven true si el frame debe salir tras esta sección. [[nodiscard]] auto stepContinueScreen(float delta_time) -> bool; diff --git a/source/game/scenes/title_scene.cpp b/source/game/scenes/title_scene.cpp index a2f96dd..81e6819 100644 --- a/source/game/scenes/title_scene.cpp +++ b/source/game/scenes/title_scene.cpp @@ -358,11 +358,16 @@ void TitleScene::update(float delta_time) { handleStartInput(); } - // Attract mode: al state MAIN, acumular inactivitat; qualsevol botó - // arcade la reseteja. En esgotar el timeout, saltar a la demo (mode DEMO, - // P1 actiu) sense fer fadeOut de la música (a diferència del START real). - if (current_state_ == TitleState::MAIN && !INPUT_BLOCKED) { - if (Input::get()->checkAnyPlayerAction(ARCADE_BUTTONS, Input::ALLOW_REPEAT)) { + // Attract mode: al state MAIN, acumular inactivitat; qualsevol botó arcade + // la reseteja. En esgotar el timeout, saltar a la demo (mode DEMO, P1 actiu) + // sense fer fadeOut de la música (a diferència del START real). El comptador + // segueix corrent encara que el menu de servei o l'overlay de redefinir + // controls estiguen oberts: floten sobre el títol i no aturen el fons, així + // que la demo arrenca igualment i les escenes poden canviar amb el menu + // obert. L'input, però, no arriba "a baix": només resetegem el comptador amb + // un botó arcade quan cap overlay l'està capturant. + if (current_state_ == TitleState::MAIN) { + if (!INPUT_BLOCKED && Input::get()->checkAnyPlayerAction(ARCADE_BUTTONS, Input::ALLOW_REPEAT)) { idle_timer_ = 0.0F; } else { idle_timer_ += delta_time;