diff --git a/source/director.cpp b/source/director.cpp index b5d3443..79db6a2 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -6,6 +6,7 @@ #include // Para srand, exit, rand, EXIT_FAILURE #include // Para time #include // Para path, absolute +#include // Para ifstream, ofstream #include // Para basic_ostream, operator<<, cerr #include // Para make_unique, unique_ptr #include // Para span @@ -14,6 +15,7 @@ #include "asset.hpp" // Para Asset #include "audio.hpp" // Para Audio +#include "external/fkyaml_node.hpp" // Para fkyaml::node #include "input.hpp" // Para Input #include "lang.hpp" // Para setLanguage #include "manage_hiscore_table.hpp" // Para ManageHiScoreTable @@ -40,16 +42,6 @@ // Constructor Director::Director(int argc, std::span argv) { -#ifdef RECORDING - Section::name = Section::Name::GAME; - Section::options = Section::Options::GAME_PLAY_1P; -#elif _DEBUG - Section::name = Section::Name::GAME; - Section::options = Section::Options::GAME_PLAY_1P; -#else // NORMAL GAME - Section::name = Section::Name::LOGO; - Section::options = Section::Options::NONE; -#endif Section::attract_mode = Section::AttractMode::TITLE_TO_DEMO; // Establece el nivel de prioridad de la categoría de registro @@ -68,6 +60,17 @@ Director::Director(int argc, std::span argv) { createSystemFolder("jailgames"); createSystemFolder("jailgames/coffee_crisis_arcade_edition"); + // Establecer sección inicial según modo de compilación +#ifdef RECORDING + Section::name = Section::Name::GAME; + Section::options = Section::Options::GAME_PLAY_1P; +#elif _DEBUG + loadDebugConfig(); +#else + Section::name = Section::Name::LOGO; + Section::options = Section::Options::NONE; +#endif + init(); } @@ -124,9 +127,9 @@ void Director::init() { Logger::section("INIT RESOURCES"); #ifdef _DEBUG - Resource::init(Resource::LoadingMode::PRELOAD); // Inicializa el sistema de gestión de recursos + Resource::init(debug_config.resource_loading == "lazy" ? Resource::LoadingMode::LAZY_LOAD : Resource::LoadingMode::PRELOAD); #else - Resource::init(Resource::LoadingMode::PRELOAD); // Inicializa el sistema de gestión de recursos + Resource::init(Resource::LoadingMode::PRELOAD); #endif ServiceMenu::init(); // Inicializa el menú de servicio Notifier::init(std::string(), Resource::get()->getText("8bithud")); // Inicialización del sistema de notificaciones @@ -224,6 +227,103 @@ void Director::checkProgramArguments(int argc, std::span argv) { } } +// Carga debug.yaml desde la carpeta del sistema (solo en _DEBUG) +void Director::loadDebugConfig() { + const std::string DEBUG_FILE = system_folder_ + "/debug.yaml"; + + std::ifstream file(DEBUG_FILE); + if (!file.good()) { + // Crear fichero por defecto + std::ofstream out(DEBUG_FILE); + if (out.is_open()) { + out << "# Coffee Crisis Arcade Edition - Debug Configuration\n"; + out << "# This file is only read in DEBUG builds.\n"; + out << "#\n"; + out << "# initial_section: logo, intro, title, game, credits, instructions, hiscore\n"; + out << "# initial_options: none, 1p, 2p, both\n"; + out << "# initial_stage: 0-based stage index (only when section is game)\n"; + out << "# show_render_info: show FPS/driver/preset overlay\n"; + out << "# resource_loading: preload, lazy\n"; + out << "\n"; + out << "initial_section: game\n"; + out << "initial_options: 1p\n"; + out << "initial_stage: 0\n"; + out << "show_render_info: true\n"; + out << "resource_loading: preload\n"; + out.close(); + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Debug config created: %s", DEBUG_FILE.c_str()); + } + // Usar defaults de DebugConfig + } else { + std::string content((std::istreambuf_iterator(file)), std::istreambuf_iterator()); + file.close(); + try { + auto yaml = fkyaml::node::deserialize(content); + if (yaml.contains("initial_section")) { + try { + debug_config.initial_section = yaml["initial_section"].get_value(); + } catch (...) {} + } + if (yaml.contains("initial_options")) { + try { + debug_config.initial_options = yaml["initial_options"].get_value(); + } catch (...) {} + } + if (yaml.contains("initial_stage")) { + try { + debug_config.initial_stage = yaml["initial_stage"].get_value(); + } catch (...) {} + } + if (yaml.contains("show_render_info")) { + try { + debug_config.show_render_info = yaml["show_render_info"].get_value(); + } catch (...) {} + } + if (yaml.contains("resource_loading")) { + try { + debug_config.resource_loading = yaml["resource_loading"].get_value(); + } catch (...) {} + } + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Debug config loaded: section=%s options=%s stage=%d", debug_config.initial_section.c_str(), debug_config.initial_options.c_str(), debug_config.initial_stage); + } catch (...) { + SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Error parsing debug.yaml, using defaults"); + } + } + + // Mapear strings a enums + const auto& sec = debug_config.initial_section; + if (sec == "logo") { + Section::name = Section::Name::LOGO; + } else if (sec == "intro") { + Section::name = Section::Name::INTRO; + } else if (sec == "title") { + Section::name = Section::Name::TITLE; + } else if (sec == "game") { + Section::name = Section::Name::GAME; + } else if (sec == "credits") { + Section::name = Section::Name::CREDITS; + } else if (sec == "instructions") { + Section::name = Section::Name::INSTRUCTIONS; + } else if (sec == "hiscore") { + Section::name = Section::Name::HI_SCORE_TABLE; + } else { + Section::name = Section::Name::GAME; + } + + const auto& opt = debug_config.initial_options; + if (opt == "none") { + Section::options = Section::Options::NONE; + } else if (opt == "1p") { + Section::options = Section::Options::GAME_PLAY_1P; + } else if (opt == "2p") { + Section::options = Section::Options::GAME_PLAY_2P; + } else if (opt == "both") { + Section::options = Section::Options::GAME_PLAY_BOTH; + } else { + Section::options = Section::Options::GAME_PLAY_1P; + } +} + // Crea la carpeta del sistema donde guardar datos void Director::createSystemFolder(const std::string& folder) { auto result = SystemUtils::createApplicationFolder(folder, system_folder_); @@ -272,7 +372,7 @@ void Director::runGame() { } #ifdef _DEBUG - constexpr int CURRENT_STAGE = 0; + const int CURRENT_STAGE = debug_config.initial_stage; #else constexpr int CURRENT_STAGE = 0; #endif diff --git a/source/director.hpp b/source/director.hpp index 88d8d65..ddd549e 100644 --- a/source/director.hpp +++ b/source/director.hpp @@ -17,6 +17,21 @@ class Director { // --- Bucle principal --- static auto run() -> int; + // --- Debug config (accesible desde otras clases) --- + struct DebugConfig { + std::string initial_section; + std::string initial_options; + int initial_stage = 0; + bool show_render_info = true; + std::string resource_loading; + + DebugConfig() + : initial_section("game"), + initial_options("1p"), + resource_loading("preload") {} + }; + static inline DebugConfig debug_config; + private: // --- Variables internas --- std::string executable_path_; // Ruta del ejecutable @@ -30,6 +45,7 @@ class Director { static void loadParams(); // Carga los parámetros del programa static void loadScoreFile(); // Carga el fichero de puntuaciones void createSystemFolder(const std::string& folder); // Crea la carpeta del sistema + void loadDebugConfig(); // Carga debug.yaml (solo en _DEBUG) // --- Gestión de entrada y archivos --- void loadAssets(); // Crea el índice de archivos disponibles diff --git a/source/screen.cpp b/source/screen.cpp index 6670d20..58dc0a6 100644 --- a/source/screen.cpp +++ b/source/screen.cpp @@ -9,6 +9,7 @@ #include // Para vector #include "asset.hpp" // Para Asset +#include "director.hpp" // Para Director::debug_config #include "mouse.hpp" // Para updateCursorVisibility #include "options.hpp" // Para Video, video, Window, window #include "param.hpp" // Para Param, param, ParamGame, ParamDebug @@ -60,7 +61,7 @@ Screen::Screen() #ifdef _DEBUG debug_info_.text = text_; - setDebugInfoEnabled(true); + setDebugInfoEnabled(Director::debug_config.show_render_info); #endif // Renderizar una vez la textura vacía para que tenga contenido válido antes de inicializar los shaders (evita pantalla negra) diff --git a/source/sections/title.cpp b/source/sections/title.cpp index e368d79..07f4c1f 100644 --- a/source/sections/title.cpp +++ b/source/sections/title.cpp @@ -30,11 +30,6 @@ class Texture; -#ifdef _DEBUG -#include // Para operator<<, setfill, setw -#include // Para basic_ostream, basic_ostream::operator<<, operator<<, cout, hex -#endif - // Constructor Title::Title() : text_(Resource::get()->getText("smb2_grad")), @@ -43,12 +38,7 @@ Title::Title() game_logo_(std::make_unique(param.game.game_area.center_x, param.title.title_c_c_position)), mini_logo_sprite_(std::make_unique(Resource::get()->getTexture("logo_jailgames_mini.png"))), state_(State::LOGO_ANIMATING), - num_controllers_(Input::get()->getNumGamepads()) -#ifdef _DEBUG - , - debug_color_(param.title.bg_color) -#endif -{ + num_controllers_(Input::get()->getNumGamepads()) { // Configura objetos tiled_bg_->setColor(param.title.bg_color); tiled_bg_->setSpeed(0.0F); @@ -132,88 +122,9 @@ void Title::checkEvents() { } } -void Title::handleKeyDownEvent(const SDL_Event& event) { -#ifdef _DEBUG - bool is_repeat = static_cast(event.key.repeat) == 1; - if (is_repeat) { - handleDebugColorKeys(event.key.key); - } -#endif +void Title::handleKeyDownEvent(const SDL_Event& /*event*/) { } -#ifdef _DEBUG -void Title::handleDebugColorKeys(SDL_Keycode key) { - adjustColorComponent(key, debug_color_); - - counter_time_ = 0.0F; - tiled_bg_->setColor(debug_color_); - printColorValue(debug_color_); -} - -void Title::adjustColorComponent(SDL_Keycode key, Color& color) { - switch (key) { - case SDLK_A: - incrementColorComponent(color.r); - break; - case SDLK_Z: - decrementColorComponent(color.r); - break; - case SDLK_S: - incrementColorComponent(color.g); - break; - case SDLK_X: - decrementColorComponent(color.g); - break; - case SDLK_D: - incrementColorComponent(color.b); - break; - case SDLK_C: - decrementColorComponent(color.b); - break; - case SDLK_F: - incrementAllComponents(color); - break; - case SDLK_V: - decrementAllComponents(color); - break; - default: - break; - } -} - -void Title::incrementColorComponent(uint8_t& component) { - if (component < 255) { - ++component; - } -} - -void Title::decrementColorComponent(uint8_t& component) { - if (component > 0) { - --component; - } -} - -void Title::incrementAllComponents(Color& color) { - incrementColorComponent(color.r); - incrementColorComponent(color.g); - incrementColorComponent(color.b); -} - -void Title::decrementAllComponents(Color& color) { - decrementColorComponent(color.r); - decrementColorComponent(color.g); - decrementColorComponent(color.b); -} - -void Title::printColorValue(const Color& color) { - std::cout << "#" - << std::hex << std::setw(2) << std::setfill('0') << static_cast(color.r) - << std::setw(2) << std::setfill('0') << static_cast(color.g) - << std::setw(2) << std::setfill('0') << static_cast(color.b) - << '\n'; -} -#endif - // Comprueba las entradas void Title::checkInput() { Input::get()->update(); diff --git a/source/sections/title.hpp b/source/sections/title.hpp index fddc4de..4683508 100644 --- a/source/sections/title.hpp +++ b/source/sections/title.hpp @@ -2,12 +2,10 @@ #include // Para SDL_Keycode, SDL_Event, Uint64 -#include // Para uint8_t #include // Para shared_ptr, unique_ptr #include // Para string_view #include // Para vector -#include "color.hpp" // for Color #include "player.hpp" // for Player #include "section.hpp" // for Options, Name (ptr only) @@ -33,7 +31,6 @@ namespace Options { // • Efectos visuales: parpadeos, transiciones y efectos de fondo // • Gestión de controles: soporte para teclado y múltiples gamepads // • Timeouts automáticos: transición automática si no hay interacción -// • Debug de colores: herramientas de depuración para ajustes visuales // // La clase utiliza un sistema de tiempo basado en segundos para garantizar // comportamiento consistente independientemente del framerate. @@ -101,10 +98,6 @@ class Title { bool player1_start_pressed_ = false; // Indica si se ha pulsado el botón de empezar para el jugador 1 bool player2_start_pressed_ = false; // Indica si se ha pulsado el botón de empezar para el jugador 2 -#ifdef _DEBUG - Color debug_color_; // Color para depuración en modo debug -#endif - // --- Ciclo de vida del título --- void update(float delta_time); // Actualiza las variables del objeto auto calculateDeltaTime() -> float; // Calcula el tiempo transcurrido desde el último frame @@ -142,15 +135,4 @@ class Title { static void swapControllers(); // Intercambia la asignación de mandos a los jugadores static void swapKeyboard(); // Intercambia el teclado de jugador static void showControllers(); // Muestra información sobre los controles y los jugadores - -// --- Depuración (solo en modo DEBUG) --- -#ifdef _DEBUG - void handleDebugColorKeys(SDL_Keycode key); // Maneja las teclas de depuración para colores - static void adjustColorComponent(SDL_Keycode key, Color& color); // Ajusta un componente del color según la tecla - static void incrementColorComponent(uint8_t& component); // Incrementa un componente de color - static void decrementColorComponent(uint8_t& component); // Decrementa un componente de color - static void incrementAllComponents(Color& color); // Incrementa todos los componentes del color - static void decrementAllComponents(Color& color); // Decrementa todos los componentes del color - static void printColorValue(const Color& color); // Imprime el valor actual del color en consola -#endif }; \ No newline at end of file