sdl_callbacks
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
#include "asset.hpp" // Para Asset
|
||||
#include "audio.hpp" // Para Audio
|
||||
#include "external/fkyaml_node.hpp" // Para fkyaml::node
|
||||
#include "global_events.hpp" // Para GlobalEvents::handle
|
||||
#include "input.hpp" // Para Input
|
||||
#include "lang.hpp" // Para setLanguage
|
||||
#include "manage_hiscore_table.hpp" // Para ManageHiScoreTable
|
||||
@@ -75,6 +76,9 @@ Director::Director(int argc, std::span<char*> argv) {
|
||||
}
|
||||
|
||||
Director::~Director() {
|
||||
// Libera las secciones primero: sus destructores pueden tocar Audio/Resource/Screen,
|
||||
// que close() destruye a continuación.
|
||||
resetActiveSection();
|
||||
close();
|
||||
Logger::put("\nBye!");
|
||||
}
|
||||
@@ -335,75 +339,96 @@ void Director::createSystemFolder(const std::string& folder) {
|
||||
}
|
||||
}
|
||||
|
||||
// Ejecuta la sección con el logo
|
||||
void Director::runLogo() {
|
||||
auto logo = std::make_unique<Logo>();
|
||||
logo->run();
|
||||
// Libera todos los unique_ptr de sección (solo uno tiene propiedad a la vez)
|
||||
void Director::resetActiveSection() {
|
||||
logo_.reset();
|
||||
intro_.reset();
|
||||
title_.reset();
|
||||
game_.reset();
|
||||
instructions_.reset();
|
||||
hi_score_table_.reset();
|
||||
credits_.reset();
|
||||
}
|
||||
|
||||
// Ejecuta la sección con la secuencia de introducción
|
||||
void Director::runIntro() {
|
||||
auto intro = std::make_unique<Intro>();
|
||||
intro->run();
|
||||
}
|
||||
// Destruye la sección anterior y construye la nueva cuando Section::name cambia
|
||||
void Director::handleSectionTransition() {
|
||||
// RESET: recarga recursos y vuelve a LOGO (el propio reset() cambia Section::name)
|
||||
if (Section::name == Section::Name::RESET) {
|
||||
resetActiveSection(); // libera recursos actuales antes del reload
|
||||
reset();
|
||||
}
|
||||
|
||||
// Ejecuta la sección con el título del juego
|
||||
void Director::runTitle() {
|
||||
auto title = std::make_unique<Title>();
|
||||
title->run();
|
||||
}
|
||||
if (Section::name == last_built_section_name_) {
|
||||
return; // ya tenemos la sección correcta viva
|
||||
}
|
||||
|
||||
// Ejecuta la sección donde se juega al juego
|
||||
void Director::runGame() {
|
||||
Player::Id player_id = Player::Id::PLAYER1;
|
||||
// Destruye la sección anterior
|
||||
resetActiveSection();
|
||||
|
||||
switch (Section::options) {
|
||||
case Section::Options::GAME_PLAY_1P:
|
||||
player_id = Player::Id::PLAYER1;
|
||||
// Construye la nueva
|
||||
switch (Section::name) {
|
||||
case Section::Name::LOGO:
|
||||
logo_ = std::make_unique<Logo>();
|
||||
break;
|
||||
case Section::Options::GAME_PLAY_2P:
|
||||
player_id = Player::Id::PLAYER2;
|
||||
|
||||
case Section::Name::INTRO:
|
||||
intro_ = std::make_unique<Intro>();
|
||||
break;
|
||||
case Section::Options::GAME_PLAY_BOTH:
|
||||
player_id = Player::Id::BOTH_PLAYERS;
|
||||
|
||||
case Section::Name::TITLE:
|
||||
title_ = std::make_unique<Title>();
|
||||
break;
|
||||
|
||||
case Section::Name::GAME: {
|
||||
Player::Id player_id = Player::Id::PLAYER1;
|
||||
switch (Section::options) {
|
||||
case Section::Options::GAME_PLAY_1P:
|
||||
player_id = Player::Id::PLAYER1;
|
||||
break;
|
||||
case Section::Options::GAME_PLAY_2P:
|
||||
player_id = Player::Id::PLAYER2;
|
||||
break;
|
||||
case Section::Options::GAME_PLAY_BOTH:
|
||||
player_id = Player::Id::BOTH_PLAYERS;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
const int CURRENT_STAGE = debug_config.initial_stage;
|
||||
#else
|
||||
constexpr int CURRENT_STAGE = 0;
|
||||
#endif
|
||||
game_ = std::make_unique<Game>(player_id, CURRENT_STAGE, Game::DEMO_OFF);
|
||||
break;
|
||||
}
|
||||
|
||||
case Section::Name::GAME_DEMO: {
|
||||
const auto PLAYER_ID = static_cast<Player::Id>((rand() % 2) + 1);
|
||||
constexpr auto CURRENT_STAGE = 0;
|
||||
game_ = std::make_unique<Game>(PLAYER_ID, CURRENT_STAGE, Game::DEMO_ON);
|
||||
break;
|
||||
}
|
||||
|
||||
case Section::Name::INSTRUCTIONS:
|
||||
instructions_ = std::make_unique<Instructions>();
|
||||
break;
|
||||
|
||||
case Section::Name::CREDITS:
|
||||
credits_ = std::make_unique<Credits>();
|
||||
break;
|
||||
|
||||
case Section::Name::HI_SCORE_TABLE:
|
||||
hi_score_table_ = std::make_unique<HiScoreTable>();
|
||||
break;
|
||||
|
||||
case Section::Name::RESET:
|
||||
case Section::Name::QUIT:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
const int CURRENT_STAGE = debug_config.initial_stage;
|
||||
#else
|
||||
constexpr int CURRENT_STAGE = 0;
|
||||
#endif
|
||||
auto game = std::make_unique<Game>(player_id, CURRENT_STAGE, Game::DEMO_OFF);
|
||||
game->run();
|
||||
}
|
||||
|
||||
// Ejecuta la sección donde se muestran las instrucciones
|
||||
void Director::runInstructions() {
|
||||
auto instructions = std::make_unique<Instructions>();
|
||||
instructions->run();
|
||||
}
|
||||
|
||||
// Ejecuta la sección donde se muestran los creditos del programa
|
||||
void Director::runCredits() {
|
||||
auto credits = std::make_unique<Credits>();
|
||||
credits->run();
|
||||
}
|
||||
|
||||
// Ejecuta la sección donde se muestra la tabla de puntuaciones
|
||||
void Director::runHiScoreTable() {
|
||||
auto hi_score_table = std::make_unique<HiScoreTable>();
|
||||
hi_score_table->run();
|
||||
}
|
||||
|
||||
// Ejecuta el juego en modo demo
|
||||
void Director::runDemoGame() {
|
||||
const auto PLAYER_ID = static_cast<Player::Id>((rand() % 2) + 1);
|
||||
constexpr auto CURRENT_STAGE = 0;
|
||||
auto game = std::make_unique<Game>(PLAYER_ID, CURRENT_STAGE, Game::DEMO_ON);
|
||||
game->run();
|
||||
last_built_section_name_ = Section::name;
|
||||
}
|
||||
|
||||
// Reinicia objetos y vuelve a la sección inicial
|
||||
@@ -418,43 +443,58 @@ void Director::reset() {
|
||||
Section::name = Section::Name::LOGO;
|
||||
}
|
||||
|
||||
auto Director::run() -> int {
|
||||
// Bucle principal
|
||||
while (Section::name != Section::Name::QUIT) {
|
||||
switch (Section::name) {
|
||||
case Section::Name::RESET:
|
||||
reset();
|
||||
break;
|
||||
case Section::Name::LOGO:
|
||||
runLogo();
|
||||
break;
|
||||
case Section::Name::INTRO:
|
||||
runIntro();
|
||||
break;
|
||||
case Section::Name::TITLE:
|
||||
runTitle();
|
||||
break;
|
||||
case Section::Name::GAME:
|
||||
runGame();
|
||||
break;
|
||||
case Section::Name::HI_SCORE_TABLE:
|
||||
runHiScoreTable();
|
||||
break;
|
||||
case Section::Name::GAME_DEMO:
|
||||
runDemoGame();
|
||||
break;
|
||||
case Section::Name::INSTRUCTIONS:
|
||||
runInstructions();
|
||||
break;
|
||||
case Section::Name::CREDITS:
|
||||
runCredits();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// Avanza un frame de la sección activa (llamado desde SDL_AppIterate)
|
||||
auto Director::iterate() -> SDL_AppResult {
|
||||
if (Section::name == Section::Name::QUIT) {
|
||||
return SDL_APP_SUCCESS;
|
||||
}
|
||||
|
||||
return 0;
|
||||
// Gestiona las transiciones entre secciones (destruye la anterior y construye la nueva)
|
||||
handleSectionTransition();
|
||||
|
||||
// Ejecuta un frame de la sección activa
|
||||
if (logo_) {
|
||||
logo_->iterate();
|
||||
} else if (intro_) {
|
||||
intro_->iterate();
|
||||
} else if (title_) {
|
||||
title_->iterate();
|
||||
} else if (game_) {
|
||||
game_->iterate();
|
||||
} else if (instructions_) {
|
||||
instructions_->iterate();
|
||||
} else if (hi_score_table_) {
|
||||
hi_score_table_->iterate();
|
||||
} else if (credits_) {
|
||||
credits_->iterate();
|
||||
}
|
||||
|
||||
return (Section::name == Section::Name::QUIT) ? SDL_APP_SUCCESS : SDL_APP_CONTINUE;
|
||||
}
|
||||
|
||||
// Procesa un evento SDL (llamado desde SDL_AppEvent)
|
||||
auto Director::handleEvent(SDL_Event& event) -> SDL_AppResult {
|
||||
// Eventos globales (SDL_EVENT_QUIT, resize, render target reset, hotplug, service menu, ratón)
|
||||
GlobalEvents::handle(event);
|
||||
|
||||
// Reenvía a la sección activa
|
||||
if (logo_) {
|
||||
logo_->handleEvent(event);
|
||||
} else if (intro_) {
|
||||
intro_->handleEvent(event);
|
||||
} else if (title_) {
|
||||
title_->handleEvent(event);
|
||||
} else if (game_) {
|
||||
game_->handleEvent(event);
|
||||
} else if (instructions_) {
|
||||
instructions_->handleEvent(event);
|
||||
} else if (hi_score_table_) {
|
||||
hi_score_table_->handleEvent(event);
|
||||
} else if (credits_) {
|
||||
credits_->handleEvent(event);
|
||||
}
|
||||
|
||||
return (Section::name == Section::Name::QUIT) ? SDL_APP_SUCCESS : SDL_APP_CONTINUE;
|
||||
}
|
||||
|
||||
// Apaga el sistema de forma segura
|
||||
|
||||
Reference in New Issue
Block a user