diff --git a/source/game/scenes/game.cpp b/source/game/scenes/game.cpp index 54ed0e4..49ecc76 100644 --- a/source/game/scenes/game.cpp +++ b/source/game/scenes/game.cpp @@ -1315,7 +1315,13 @@ void Game::demoHandleInput() { // Procesa las entradas para un jugador específico durante el modo demo. void Game::demoHandlePlayerInput(const std::shared_ptr& player, int index) { - const auto& demo_data = demo_.data.at(index).at(demo_.index); + // Guarda: si el fade no s'arriba a disparar (frame skip al == TOTAL_DEMO_DATA-200) + // i demo_.index passa de 2000, fem loop al primer frame en comptes de petar. + const auto& demo_data_vec = demo_.data.at(index); + if (demo_data_vec.empty()) { + return; + } + const auto& demo_data = demo_data_vec.at(static_cast(demo_.index) % demo_data_vec.size()); if (demo_data.left == 1) { player->setInput(Input::Action::LEFT); @@ -1756,8 +1762,13 @@ void Game::updateDemo(float delta_time) { demo_.elapsed_s += delta_time; demo_.index = static_cast(demo_.elapsed_s * 60.0F); - // Activa el fundido antes de acabar con los datos de la demo - if (demo_.index == TOTAL_DEMO_DATA - 200) { + // Activa el fundido abans d'acabar amb les dades de la demo. + // Cal >= (no ==) perquè un frame lent (p.ex. canviar preset des del + // service menu) podria saltar exactament el frame 1800 i deixar la + // demo en bucle infinit fins a petar al .at(2000). + // fade_out_->activate() ja és idempotent (Fade::activate retorna si + // l'estat ja no és NOT_ENABLED). + if (demo_.index >= TOTAL_DEMO_DATA - 200) { fade_out_->setType(Fade::Type::RANDOM_SQUARE2); fade_out_->setPostDuration(param.fade.post_duration_ms); fade_out_->activate();