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
|
||||
|
||||
@@ -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,16 +76,10 @@ 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
|
||||
static void reset(); // Reinicia objetos y vuelve a la sección inicial
|
||||
// --- 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 ---
|
||||
auto getLangFile(Lang::Code code) -> std::string; // Obtiene un fichero de idioma según el código
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -7,15 +7,26 @@ Actualizando a la versión "Arcade Edition" en 08/05/2024
|
||||
|
||||
*/
|
||||
|
||||
#include <memory> // Para make_unique, unique_ptr
|
||||
#include <span> // Para span
|
||||
#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);
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
if (sound == nullptr) {
|
||||
Logger::error(" Sound load failed: " + name);
|
||||
++failed;
|
||||
}
|
||||
sounds_.emplace_back(name, sound);
|
||||
Logger::dots("Sound : ", name, "[ LOADED ]");
|
||||
}
|
||||
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());
|
||||
}
|
||||
if (music == nullptr) {
|
||||
Logger::error(" Music load failed: " + name);
|
||||
++failed;
|
||||
}
|
||||
musics_.emplace_back(name, music);
|
||||
Logger::dots("Music : ", name, "[ LOADED ]");
|
||||
}
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user