sdl_callbacks

This commit is contained in:
2026-04-14 12:21:00 +02:00
parent c0accd25e2
commit f5da35bfb2
20 changed files with 406 additions and 177 deletions

View File

@@ -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,28 +339,48 @@ 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() {
// Destruye la sección anterior
resetActiveSection();
// Construye la nueva
switch (Section::name) {
case Section::Name::LOGO:
logo_ = std::make_unique<Logo>();
break;
case Section::Name::INTRO:
intro_ = std::make_unique<Intro>();
break;
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;
@@ -370,40 +394,41 @@ void Director::runGame() {
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();
}
game_ = std::make_unique<Game>(player_id, CURRENT_STAGE, Game::DEMO_OFF);
break;
}
// 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() {
case Section::Name::GAME_DEMO: {
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();
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;
}
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

View File

@@ -1,12 +1,26 @@
#pragma once
#include <SDL3/SDL.h> // Para SDL_AppResult, SDL_Event
#include <memory> // Para unique_ptr
#include <span> // Para Span
#include <string> // Para string
#include "section.hpp" // Para Section::Name
namespace Lang {
enum class Code : int;
}
// Declaraciones adelantadas de las secciones
class Logo;
class Intro;
class Title;
class Game;
class Instructions;
class HiScoreTable;
class Credits;
// --- Clase Director: gestor principal de la aplicación ---
class Director {
public:
@@ -14,8 +28,9 @@ class Director {
Director(int argc, std::span<char*> argv);
~Director();
// --- Bucle principal ---
static auto run() -> int;
// --- Callbacks para SDL_MAIN_USE_CALLBACKS ---
auto iterate() -> SDL_AppResult; // Avanza un frame de la sección activa
auto handleEvent(SDL_Event& event) -> SDL_AppResult; // Procesa un evento SDL
// --- Debug config (accesible desde otras clases) ---
struct DebugConfig {
@@ -37,6 +52,16 @@ class Director {
std::string executable_path_; // Ruta del ejecutable
std::string system_folder_; // Carpeta del sistema para almacenar datos
// --- Sección activa (una y sólo una viva en cada momento) ---
std::unique_ptr<Logo> logo_;
std::unique_ptr<Intro> intro_;
std::unique_ptr<Title> title_;
std::unique_ptr<Game> game_;
std::unique_ptr<Instructions> instructions_;
std::unique_ptr<HiScoreTable> hi_score_table_;
std::unique_ptr<Credits> credits_;
Section::Name last_built_section_name_ = Section::Name::RESET;
// --- Inicialización y cierre del sistema ---
void init(); // Inicializa la aplicación
static void close(); // Cierra y libera recursos
@@ -51,15 +76,9 @@ class Director {
void loadAssets(); // Crea el índice de archivos disponibles
void checkProgramArguments(int argc, std::span<char*> argv); // Verifica los parámetros del programa // NOLINT(modernize-avoid-c-arrays)
// --- Secciones del programa ---
static void runLogo(); // Ejecuta la pantalla con el logo
static void runIntro(); // Ejecuta la introducción del juego
static void runTitle(); // Ejecuta la pantalla de título
static void runGame(); // Inicia el juego
static void runInstructions(); // Muestra las instrucciones
static void runCredits(); // Muestra los créditos del juego
static void runHiScoreTable(); // Muestra la tabla de puntuaciones
static void runDemoGame(); // Ejecuta el modo demo
// --- Gestión de secciones ---
void handleSectionTransition(); // Destruye la sección anterior y construye la nueva si Section::name ha cambiado
void resetActiveSection(); // Libera todos los unique_ptr de sección
static void reset(); // Reinicia objetos y vuelve a la sección inicial
// --- Gestión de archivos de idioma ---

View File

@@ -306,10 +306,17 @@ void Input::addGamepadMappingsFromFile() {
}
void Input::discoverGamepads() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
handleEvent(event); // Comprueba mandos conectados
// Enumera los gamepads ya conectados sin drenar la cola de eventos de SDL
// (necesario con SDL_MAIN_USE_CALLBACKS, que entrega los eventos por SDL_AppEvent).
int count = 0;
SDL_JoystickID* joysticks = SDL_GetGamepads(&count);
if (joysticks == nullptr) {
return;
}
for (int i = 0; i < count; ++i) {
addGamepad(joysticks[i]);
}
SDL_free(joysticks);
}
void Input::initSDLGamePad() {

View File

@@ -7,15 +7,26 @@ Actualizando a la versión "Arcade Edition" en 08/05/2024
*/
#include <memory> // Para make_unique, unique_ptr
#define SDL_MAIN_USE_CALLBACKS 1
#include <SDL3/SDL_main.h>
#include <span> // Para span
#include "director.hpp" // Para Director
auto main(int argc, char* argv[]) -> int {
// Crea el objeto Director
auto director = std::make_unique<Director>(argc, std::span<char*>(argv, argc));
// Bucle principal
return Director::run();
SDL_AppResult SDL_AppInit(void** appstate, int argc, char* argv[]) {
*appstate = new Director(argc, std::span<char*>(argv, argc));
return SDL_APP_CONTINUE;
}
SDL_AppResult SDL_AppIterate(void* appstate) {
return static_cast<Director*>(appstate)->iterate();
}
SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event) {
return static_cast<Director*>(appstate)->handleEvent(*event);
}
void SDL_AppQuit(void* appstate, SDL_AppResult /*result*/) {
delete static_cast<Director*>(appstate);
}

View File

@@ -467,10 +467,10 @@ void Resource::reload() {
// Carga los sonidos del juego
void Resource::loadSounds() {
Logger::info("SOUND FILES");
auto list = Asset::get()->getListByType(Asset::Type::SOUND);
sounds_.clear();
int failed = 0;
for (const auto& l : list) {
auto name = getFileName(l);
updateLoadingProgress(name);
@@ -479,21 +479,23 @@ void Resource::loadSounds() {
if (!audio_data.data.empty()) {
sound = JA_LoadSound(audio_data.data.data(), audio_data.data.size());
} else {
// Fallback a cargar desde disco si no está en pack
sound = JA_LoadSound(l.c_str());
}
sounds_.emplace_back(name, sound);
Logger::dots("Sound : ", name, "[ LOADED ]");
if (sound == nullptr) {
Logger::error(" Sound load failed: " + name);
++failed;
}
sounds_.emplace_back(name, sound);
}
Logger::info("Sounds loaded: " + std::to_string(list.size() - failed) + "/" + std::to_string(list.size()));
}
// Carga las músicas del juego
void Resource::loadMusics() {
Logger::cr();
Logger::info("MUSIC FILES");
auto list = Asset::get()->getListByType(Asset::Type::MUSIC);
musics_.clear();
int failed = 0;
for (const auto& l : list) {
auto name = getFileName(l);
updateLoadingProgress(name);
@@ -502,18 +504,19 @@ void Resource::loadMusics() {
if (!audio_data.data.empty()) {
music = JA_LoadMusic(audio_data.data.data(), audio_data.data.size());
} else {
// Fallback a cargar desde disco si no está en pack
music = JA_LoadMusic(l.c_str());
}
musics_.emplace_back(name, music);
Logger::dots("Music : ", name, "[ LOADED ]");
if (music == nullptr) {
Logger::error(" Music load failed: " + name);
++failed;
}
musics_.emplace_back(name, music);
}
Logger::info("Musics loaded: " + std::to_string(list.size() - failed) + "/" + std::to_string(list.size()));
}
// Carga las texturas del juego
void Resource::loadTextures() {
Logger::cr();
Logger::info("TEXTURES");
auto list = Asset::get()->getListByType(Asset::Type::BITMAP);
textures_.clear();
@@ -522,12 +525,11 @@ void Resource::loadTextures() {
updateLoadingProgress(name);
textures_.emplace_back(name, std::make_shared<Texture>(Screen::get()->getRenderer(), l));
}
Logger::info("Textures loaded: " + std::to_string(list.size()));
}
// Carga los ficheros de texto del juego
void Resource::loadTextFiles() {
Logger::cr();
Logger::info("TEXT FILES");
auto list = Asset::get()->getListByType(Asset::Type::FONT);
text_files_.clear();
@@ -536,12 +538,11 @@ void Resource::loadTextFiles() {
updateLoadingProgress(name);
text_files_.emplace_back(name, Text::loadFile(l));
}
Logger::info("Text files loaded: " + std::to_string(list.size()));
}
// Carga las animaciones del juego
void Resource::loadAnimations() {
Logger::cr();
Logger::info("ANIMATIONS");
auto list = Asset::get()->getListByType(Asset::Type::ANIMATION);
animations_.clear();
@@ -550,12 +551,11 @@ void Resource::loadAnimations() {
updateLoadingProgress(name);
animations_.emplace_back(name, loadAnimationsFromFile(l));
}
Logger::info("Animations loaded: " + std::to_string(list.size()));
}
// Carga los datos para el modo demostración
void Resource::loadDemoData() {
Logger::cr();
Logger::info("DEMO FILES");
auto list = Asset::get()->getListByType(Asset::Type::DEMODATA);
demos_.clear();
@@ -564,13 +564,11 @@ void Resource::loadDemoData() {
updateLoadingProgress(name);
demos_.emplace_back(loadDemoDataFromFile(l));
}
Logger::info("Demo files loaded: " + std::to_string(list.size()));
}
// Crea las texturas de jugadores con todas sus variantes de paleta
void Resource::createPlayerTextures() {
Logger::cr();
Logger::info("CREATING PLAYER TEXTURES");
// Configuración de jugadores y sus paletas
struct PlayerConfig {
std::string base_texture;
@@ -641,9 +639,9 @@ void Resource::createPlayerTextures() {
// Guardar con nombre específico
std::string texture_name = player.name_prefix + "_pal" + std::to_string(palette_idx);
textures_.emplace_back(texture_name, texture);
Logger::dots("Player Texture : ", texture_name, "[ DONE ]");
}
}
Logger::info("Player textures created: " + std::to_string(players.size() * 4));
}
// Crea texturas a partir de textos para mostrar puntuaciones y mensajes
@@ -657,9 +655,6 @@ void Resource::createTextTextures() {
text(std::move(text_init)) {}
};
Logger::cr();
Logger::info("CREATING TEXTURES");
// Texturas de tamaño normal con outline
std::vector<NameAndText> strings1 = {
{"game_text_1000_points", "1.000"},
@@ -673,7 +668,6 @@ void Resource::createTextTextures() {
auto text1 = getText("04b_25_enhanced");
for (const auto& s : strings1) {
textures_.emplace_back(s.name, text1->writeDXToTexture(Text::STROKE, s.text, -2, Colors::NO_COLOR_MOD, 1, param.game.item_text_outline_color));
Logger::dots("Texture : ", s.name, "[ DONE ]");
}
// Texturas de tamaño doble
@@ -688,8 +682,9 @@ void Resource::createTextTextures() {
auto text2 = getText("04b_25_2x_enhanced");
for (const auto& s : strings2) {
textures_.emplace_back(s.name, text2->writeDXToTexture(Text::STROKE, s.text, -4, Colors::NO_COLOR_MOD, 1, param.game.item_text_outline_color));
Logger::dots("Texture : ", s.name, "[ DONE ]");
}
Logger::info("Text textures created: " + std::to_string(strings1.size() + strings2.size()));
}
// Crea los objetos de texto a partir de los archivos de textura y texto
@@ -707,9 +702,6 @@ void Resource::createText() {
white_texture_file(std::move(w_file)) {}
};
Logger::cr();
Logger::info("CREATING TEXT OBJECTS");
std::vector<ResourceInfo> resources = {
{"04b_25", "04b_25.png", "04b_25.txt"},
{"04b_25_enhanced", "04b_25.png", "04b_25.txt", "04b_25_white.png"}, // Nueva fuente con textura blanca
@@ -735,8 +727,8 @@ void Resource::createText() {
// Crear texto normal
texts_.emplace_back(resource.key, std::make_shared<Text>(getTexture(resource.texture_file), getTextFile(resource.text_file)));
}
Logger::dots("Text : ", resource.key, "[ DONE ]");
}
Logger::info("Text objects created: " + std::to_string(resources.size()));
}
// Vacía el vector de sonidos y libera la memoria asociada
@@ -853,23 +845,6 @@ void Resource::renderProgress() {
screen->coreRender();
}
// Comprueba los eventos durante la carga (permite salir con ESC o cerrar ventana)
void Resource::checkEvents() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_EVENT_QUIT:
exit(0);
break;
case SDL_EVENT_KEY_DOWN:
if (event.key.key == SDLK_ESCAPE) {
exit(0);
}
break;
}
}
}
// Carga los datos para el modo demostración (sin mostrar progreso)
void Resource::loadDemoDataQuiet() {
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n>> DEMO FILES (quiet load)");
@@ -892,13 +867,12 @@ void Resource::initProgressBar() {
loading_full_rect_ = {.x = X_PADDING, .y = BAR_Y_POSITION, .w = FULL_BAR_WIDTH, .h = BAR_HEIGHT};
}
// Actualiza el progreso de carga, muestra la barra y procesa eventos
// Actualiza el progreso de carga y muestra la barra
void Resource::updateLoadingProgress(std::string name) {
loading_resource_name_ = std::move(name);
loading_count_.increase();
updateProgressBar();
renderProgress();
checkEvents();
}
// Actualiza la barra de estado

View File

@@ -174,7 +174,6 @@ class Resource {
// --- Métodos internos para gestionar el progreso ---
void calculateTotalResources(); // Calcula el número de recursos para cargar
void renderProgress(); // Muestra el progreso de carga
static void checkEvents(); // Comprueba los eventos durante la carga
void updateLoadingProgress(std::string name); // Actualiza el progreso de carga
void initProgressBar(); // Inicializa los rectangulos que definen la barra de progreso
void updateProgressBar(); // Actualiza la barra de estado

View File

@@ -28,6 +28,7 @@
#include "text.hpp" // Para Text
#include "texture.hpp" // Para Texture
#include "tiled_bg.hpp" // Para TiledBG, TiledBGMode
#include "ui/logger.hpp" // Para section
#include "ui/service_menu.hpp" // Para ServiceMenu
#include "utils.hpp" // Para Zone
@@ -47,6 +48,11 @@ Credits::Credits()
}
initVars();
startCredits();
Logger::section("CREDITS");
// Inicializa el timer de delta time para el primer frame del callback
last_time_ = SDL_GetTicks();
}
// Destructor
@@ -69,7 +75,20 @@ auto Credits::calculateDeltaTime() -> float {
return DELTA_TIME;
}
// Bucle principal
// Avanza un frame (llamado desde Director::iterate)
void Credits::iterate() {
checkInput();
const float DELTA_TIME = calculateDeltaTime();
update(DELTA_TIME);
render();
}
// Procesa un evento (llamado desde Director::handleEvent)
void Credits::handleEvent(const SDL_Event& /*event*/) {
// Eventos globales ya gestionados por Director::handleEvent
}
// Bucle principal legacy (fallback)
void Credits::run() {
last_time_ = SDL_GetTicks();

View File

@@ -22,7 +22,11 @@ class Credits {
Credits();
~Credits();
// --- Bucle principal ---
// --- Callbacks para el bucle SDL_MAIN_USE_CALLBACKS ---
void iterate(); // Ejecuta un frame
void handleEvent(const SDL_Event& event); // Procesa un evento
// --- Bucle principal legacy (fallback) ---
void run();
private:

View File

@@ -41,6 +41,7 @@
#include "smart_sprite.hpp" // Para SmartSprite
#include "stage.hpp" // Para StageManager, StageData
#include "tabe.hpp" // Para Tabe
#include "ui/logger.hpp" // Para section
#include "text.hpp" // Para Text
#include "texture.hpp" // Para Texture
#include "ui/service_menu.hpp" // Para ServiceMenu
@@ -131,6 +132,11 @@ Game::Game(Player::Id player_id, int current_stage, bool demo_enabled)
#ifdef RECORDING
setState(State::PLAYING);
#endif
Logger::section(demo_.enabled ? "GAME (DEMO)" : "GAME");
// Inicializa el timer de delta time para el primer frame del callback
last_time_ = SDL_GetTicks();
}
Game::~Game() {
@@ -978,7 +984,33 @@ auto Game::calculateDeltaTime() -> float {
return DELTA_TIME_MS / 1000.0F; // Convertir de milisegundos a segundos
}
// Bucle para el juego
// Avanza un frame del juego (llamado desde Director::iterate)
void Game::iterate() {
const float DELTA_TIME = calculateDeltaTime();
checkInput();
update(DELTA_TIME);
render();
}
// Procesa un evento del juego (llamado desde Director::handleEvent)
void Game::handleEvent(const SDL_Event& event) {
switch (event.type) {
case SDL_EVENT_WINDOW_FOCUS_LOST:
pause_manager_->setFocusLossPause(!demo_.enabled);
break;
case SDL_EVENT_WINDOW_FOCUS_GAINED:
pause_manager_->setFocusLossPause(false);
break;
default:
break;
}
#ifdef _DEBUG
handleDebugEvents(event);
#endif
}
// Bucle para el juego (fallback legacy)
void Game::run() {
last_time_ = SDL_GetTicks();

View File

@@ -60,7 +60,11 @@ class Game {
Game(Player::Id player_id, int current_stage, bool demo_enabled); // Constructor principal
~Game(); // Destructor
// --- Bucle principal ---
// --- Callbacks para el bucle SDL_MAIN_USE_CALLBACKS ---
void iterate(); // Ejecuta un frame
void handleEvent(const SDL_Event& event); // Procesa un evento
// --- Bucle principal legacy (fallback) ---
void run(); // Ejecuta el bucle principal del juego
private:

View File

@@ -23,6 +23,7 @@
#include "resource.hpp" // Para Resource
#include "screen.hpp" // Para Screen
#include "section.hpp" // Para Name, name, Options, options
#include "ui/logger.hpp" // Para section
#include "sprite.hpp" // Para Sprite
#include "text.hpp" // Para Text, Text::SHADOW, Text::COLOR
#include "texture.hpp" // Para Texture
@@ -45,6 +46,12 @@ HiScoreTable::HiScoreTable()
initBackground();
iniEntryColors();
createSprites();
Logger::section("HI-SCORE TABLE");
// Inicializa el timer de delta time y arranca la música
last_time_ = SDL_GetTicks();
Audio::get()->playMusic("title.ogg");
}
// Destructor
@@ -126,7 +133,20 @@ auto HiScoreTable::calculateDeltaTime() -> float {
return DELTA_TIME;
}
// Bucle para la pantalla de instrucciones
// Avanza un frame (llamado desde Director::iterate)
void HiScoreTable::iterate() {
const float DELTA_TIME = calculateDeltaTime();
checkInput();
update(DELTA_TIME);
render();
}
// Procesa un evento (llamado desde Director::handleEvent)
void HiScoreTable::handleEvent(const SDL_Event& /*event*/) {
// Eventos globales ya gestionados por Director::handleEvent
}
// Bucle para la pantalla de puntuaciones (fallback legacy)
void HiScoreTable::run() {
last_time_ = SDL_GetTicks();
Audio::get()->playMusic("title.ogg");

View File

@@ -27,7 +27,11 @@ class HiScoreTable {
HiScoreTable();
~HiScoreTable();
// --- Bucle principal ---
// --- Callbacks para el bucle SDL_MAIN_USE_CALLBACKS ---
void iterate(); // Ejecuta un frame
void handleEvent(const SDL_Event& event); // Procesa un evento
// --- Bucle principal legacy (fallback) ---
void run();
private:

View File

@@ -23,6 +23,7 @@
#include "sprite.hpp" // Para Sprite
#include "text.hpp" // Para Text, Text::CENTER, Text::COLOR, Text::SHADOW
#include "tiled_bg.hpp" // Para TiledBG, TiledBGMode
#include "ui/logger.hpp" // Para section
#include "utils.hpp"
// Constructor
@@ -57,6 +58,12 @@ Instructions::Instructions()
// Inicializa los sprites de los items
iniSprites();
Logger::section("INSTRUCTIONS");
// Inicializa el timer de delta time y arranca la música
last_time_ = SDL_GetTicks();
Audio::get()->playMusic("title.ogg");
}
// Destructor
@@ -262,7 +269,20 @@ auto Instructions::calculateDeltaTime() -> float {
return DELTA_TIME;
}
// Bucle para la pantalla de instrucciones
// Avanza un frame (llamado desde Director::iterate)
void Instructions::iterate() {
const float DELTA_TIME = calculateDeltaTime();
checkInput();
update(DELTA_TIME);
render();
}
// Procesa un evento (llamado desde Director::handleEvent)
void Instructions::handleEvent(const SDL_Event& /*event*/) {
// Eventos globales ya gestionados por Director::handleEvent
}
// Bucle para la pantalla de instrucciones (fallback legacy)
void Instructions::run() {
last_time_ = SDL_GetTicks();
Audio::get()->playMusic("title.ogg");

View File

@@ -48,7 +48,11 @@ class Instructions {
Instructions();
~Instructions();
// --- Bucle principal ---
// --- Callbacks para el bucle SDL_MAIN_USE_CALLBACKS ---
void iterate(); // Ejecuta un frame
void handleEvent(const SDL_Event& event); // Procesa un evento
// --- Bucle principal legacy (fallback) ---
void run();
private:

View File

@@ -20,6 +20,7 @@
#include "text.hpp" // Para Text
#include "texture.hpp" // Para Texture
#include "tiled_bg.hpp" // Para TiledBG, TiledBGMode
#include "ui/logger.hpp" // Para section
#include "utils.hpp" // Para easeOutBounce
#include "writer.hpp" // Para Writer
@@ -39,6 +40,12 @@ Intro::Intro()
// Configura el fondo
tiled_bg_->setSpeed(TILED_BG_SPEED);
tiled_bg_->setColor(bg_color_);
Logger::section("INTRO");
// Inicializa el timer de delta time y arranca la música
last_time_ = SDL_GetTicks();
Audio::get()->playMusic("intro.ogg", 0);
}
// Comprueba los eventos
@@ -265,7 +272,20 @@ auto Intro::calculateDeltaTime() -> float {
return DELTA_TIME;
}
// Bucle principal
// Avanza un frame (llamado desde Director::iterate)
void Intro::iterate() {
const float DELTA_TIME = calculateDeltaTime();
checkInput();
update(DELTA_TIME);
render();
}
// Procesa un evento (llamado desde Director::handleEvent)
void Intro::handleEvent(const SDL_Event& /*event*/) {
// Eventos globales ya gestionados por Director::handleEvent
}
// Bucle principal legacy (fallback)
void Intro::run() {
last_time_ = SDL_GetTicks();
Audio::get()->playMusic("intro.ogg", 0);

View File

@@ -30,7 +30,11 @@ class Intro {
Intro();
~Intro() = default;
// --- Bucle principal ---
// --- Callbacks para el bucle SDL_MAIN_USE_CALLBACKS ---
void iterate(); // Ejecuta un frame
void handleEvent(const SDL_Event& event); // Procesa un evento
// --- Bucle principal legacy (fallback) ---
void run();
private:

View File

@@ -9,6 +9,7 @@
#include "audio.hpp" // Para Audio
#include "color.hpp" // Para Color
#include "global_events.hpp" // Para handle
#include "ui/logger.hpp" // Para section
#include "global_inputs.hpp" // Para check
#include "input.hpp" // Para Input
#include "param.hpp" // Para Param, ParamGame, param
@@ -47,6 +48,11 @@ Logo::Logo()
jail_sprite_.push_back(std::move(temp));
}
Logger::section("LOGO");
// Inicializa el timer de delta time para el primer frame del callback
last_time_ = SDL_GetTicks();
// Inicializa el vector de colores con la paleta ZX Spectrum
color_.emplace_back(SPECTRUM_BLACK);
color_.emplace_back(SPECTRUM_BLUE);
@@ -169,7 +175,20 @@ auto Logo::calculateDeltaTime() -> float {
return DELTA_TIME;
}
// Bucle para el logo del juego
// Avanza un frame del logo (llamado desde Director::iterate)
void Logo::iterate() {
const float DELTA_TIME = calculateDeltaTime();
checkInput();
update(DELTA_TIME);
render();
}
// Procesa un evento (llamado desde Director::handleEvent)
void Logo::handleEvent(const SDL_Event& /*event*/) {
// Eventos globales (QUIT, resize, hotplug) ya gestionados por Director::handleEvent
}
// Bucle para el logo del juego (fallback legacy)
void Logo::run() {
last_time_ = SDL_GetTicks();

View File

@@ -31,7 +31,11 @@ class Logo {
Logo();
~Logo();
// --- Bucle principal ---
// --- Callbacks para el bucle SDL_MAIN_USE_CALLBACKS ---
void iterate(); // Ejecuta un frame
void handleEvent(const SDL_Event& event); // Procesa un evento
// --- Bucle principal legacy (fallback) ---
void run();
private:

View File

@@ -24,6 +24,7 @@
#include "sprite.hpp" // Para Sprite
#include "text.hpp" // Para Text
#include "tiled_bg.hpp" // Para TiledBG, TiledBGMode
#include "ui/logger.hpp" // Para section
#include "ui/notifier.hpp" // Para Notifier
#include "ui/service_menu.hpp" // Para ServiceMenu
#include "utils.hpp" // Para Zone, BLOCK
@@ -59,6 +60,11 @@ Title::Title()
anchor_.mini_logo = (param.game.height / MINI_LOGO_Y_DIVISOR * MINI_LOGO_Y_FACTOR) + BLOCK;
mini_logo_sprite_->setY(anchor_.mini_logo);
anchor_.copyright_text = anchor_.mini_logo + mini_logo_sprite_->getHeight() + COPYRIGHT_TEXT_SPACING;
Logger::section("TITLE");
// Inicializa el timer de delta time para el primer frame del callback
last_time_ = SDL_GetTicks();
}
// Destructor
@@ -213,7 +219,22 @@ void Title::activatePlayerAndSetState(Player::Id player_id) {
counter_time_ = 0.0F;
}
// Bucle para el titulo del juego
// Avanza un frame (llamado desde Director::iterate)
void Title::iterate() {
const float DELTA_TIME = calculateDeltaTime();
checkInput();
update(DELTA_TIME);
render();
}
// Procesa un evento (llamado desde Director::handleEvent)
void Title::handleEvent(const SDL_Event& event) {
if (event.type == SDL_EVENT_KEY_DOWN) {
handleKeyDownEvent(event);
}
}
// Bucle para el titulo del juego (fallback legacy)
void Title::run() {
last_time_ = SDL_GetTicks();

View File

@@ -40,7 +40,11 @@ class Title {
Title();
~Title();
// --- Bucle principal ---
// --- Callbacks para el bucle SDL_MAIN_USE_CALLBACKS ---
void iterate(); // Ejecuta un frame
void handleEvent(const SDL_Event& event); // Procesa un evento
// --- Bucle principal legacy (fallback) ---
void run();
private: