From 0c87612a179a1500e08ffc6b99ce25782653b894 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sun, 26 Oct 2025 21:44:16 +0100 Subject: [PATCH] treballant en les novetats de LoadingScreen --- source/core/system/director.cpp | 23 +-- source/core/system/director.hpp | 74 +++------- source/game/scenes/loading_screen.cpp | 198 +++++++++++++++++++++----- source/game/scenes/loading_screen.hpp | 33 ++++- 4 files changed, 211 insertions(+), 117 deletions(-) diff --git a/source/core/system/director.cpp b/source/core/system/director.cpp index 1dc39e1..038ecfb 100644 --- a/source/core/system/director.cpp +++ b/source/core/system/director.cpp @@ -13,12 +13,12 @@ #include // Para make_unique, unique_ptr #include // Para operator+, allocator, char_traits +#include "core/audio/audio.hpp" // Para Audio #include "core/input/input.hpp" // Para Input, InputAction #include "core/rendering/screen.hpp" // Para Screen #include "core/resources/asset.hpp" // Para Asset, AssetType #include "core/resources/resource.hpp" // Para Resource #include "core/system/debug.hpp" // Para Debug -#include "external/jail_audio.h" // Para JA_SetMusicVolume, JA_SetSoundV... #include "game/gameplay/cheevos.hpp" // Para Cheevos #include "game/options.hpp" // Para Options, options, OptionsVideo #include "game/scenes/credits.hpp" // Para Credits @@ -62,7 +62,7 @@ Director::Director(int argc, const char* argv[]) { Options::loadFromFile(Asset::get()->get("config.txt")); // Inicializa JailAudio - initJailAudio(); + Audio::init(); // Crea los objetos Screen::init(); @@ -86,6 +86,7 @@ Director::~Director() { Input::destroy(); Notifier::destroy(); Resource::destroy(); + Audio::destroy(); Screen::destroy(); Asset::destroy(); @@ -237,22 +238,6 @@ void Director::initInput() { } } -// Inicializa JailAudio -void Director::initJailAudio() { - if (!SDL_Init(SDL_INIT_AUDIO)) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_AUDIO could not initialize! SDL Error: %s", SDL_GetError()); - } else { - JA_Init(48000, SDL_AUDIO_S16LE, 2); - if (Options::audio.enabled) { - JA_SetMusicVolume(Options::audio.music.volume); - JA_SetSoundVolume(Options::audio.sound.volume); - } else { - JA_SetMusicVolume(0); - JA_SetSoundVolume(0); - } - } -} - // Crea el indice de ficheros bool Director::setFileList() { #ifdef MACOS_BUNDLE @@ -537,7 +522,7 @@ void Director::runGameOver() { // Ejecuta la seccion de juego donde se juega void Director::runGame() { - JA_StopMusic(); + Audio::get()->stopMusic(); auto game = std::make_unique(GameMode::GAME); game->run(); } diff --git a/source/core/system/director.hpp b/source/core/system/director.hpp index 6f65382..022c561 100644 --- a/source/core/system/director.hpp +++ b/source/core/system/director.hpp @@ -5,60 +5,28 @@ #include // Para string class Director { - private: - // Variables - std::string executable_path_; // Path del ejecutable - std::string system_folder_; // Carpeta del sistema donde guardar datos - - // Comprueba los parametros del programa - std::string checkProgramArguments(int argc, const char* argv[]); - - // Crea la carpeta del sistema donde guardar datos - void createSystemFolder(const std::string& folder); - - // Inicializa jail_audio - void initJailAudio(); - - // Inicializa el objeto Input - void initInput(); - - // Crea el indice de ficheros - bool setFileList(); - - // Ejecuta la seccion de juego con el logo - void runLogo(); - - // Ejecuta la seccion de juego de la pantalla de carga - void runLoadingScreen(); - - // Ejecuta la seccion de juego con el titulo y los menus - void runTitle(); - - // Ejecuta la seccion de los creditos del juego - void runCredits(); - - // Ejecuta la seccion de la demo, donde se ven pantallas del juego - void runDemo(); - - // Ejecuta la seccion del final del juego - void runEnding(); - - // Ejecuta la seccion del final del juego - void runEnding2(); - - // Ejecuta la seccion del final de la partida - void runGameOver(); - - // Ejecuta la seccion de juego donde se juega - void runGame(); - public: - // Constructor - Director(int argc, const char* argv[]); + Director(int argc, const char* argv[]); // Constructor + ~Director(); // Destructor + int run(); // Bucle principal - // Destructor - ~Director(); + private: + // --- Variables --- + std::string executable_path_; // Path del ejecutable + std::string system_folder_; // Carpeta del sistema donde guardar datos + std::string checkProgramArguments(int argc, const char* argv[]); // Comprueba los parametros del programa - // Bucle principal - int run(); + // --- Funciones --- + void createSystemFolder(const std::string& folder); // Crea la carpeta del sistema donde guardar datos + void initInput(); // Inicializa el objeto Input + bool setFileList(); // Crea el indice de ficheros + void runLogo(); // Ejecuta la seccion de juego con el logo + void runLoadingScreen(); // Ejecuta la seccion de juego de la pantalla de carga + void runTitle(); // Ejecuta la seccion de juego con el titulo y los menus + void runCredits(); // Ejecuta la seccion de los creditos del juego + void runDemo(); // Ejecuta la seccion de la demo, donde se ven pantallas del juego + void runEnding(); // Ejecuta la seccion del final del juego + void runEnding2(); // Ejecuta la seccion del final del juego + void runGameOver(); // Ejecuta la seccion del final de la partida + void runGame(); // Ejecuta la seccion de juego donde se juega }; \ No newline at end of file diff --git a/source/game/scenes/loading_screen.cpp b/source/game/scenes/loading_screen.cpp index e8fb09c..4010674 100644 --- a/source/game/scenes/loading_screen.cpp +++ b/source/game/scenes/loading_screen.cpp @@ -3,12 +3,12 @@ #include #include // Para rand +#include "core/audio/audio.hpp" // Para Audio #include "core/input/global_inputs.hpp" // Para check #include "core/rendering/screen.hpp" // Para Screen #include "core/rendering/surface.hpp" // Para Surface #include "core/rendering/surface_sprite.hpp" // Para SSprite #include "core/resources/resource.hpp" // Para Resource -#include "external/jail_audio.h" // Para JA_PlayMusic, JA_SetVolume, JA_StopMusic #include "game/options.hpp" // Para Options, options, SectionState, Options... #include "game/scene_manager.hpp" // Para SceneManager #include "utils/defines.hpp" // Para GAME_SPEED @@ -23,8 +23,9 @@ LoadingScreen::LoadingScreen() color_loading_screen_sprite_(std::make_shared(color_loading_screen_surface_, 0, 0, color_loading_screen_surface_->getWidth(), color_loading_screen_surface_->getHeight())), screen_surface_(std::make_shared(Options::game.width, Options::game.height)), delta_timer_(std::make_unique()), - state_(LoadingState::PRE_LOADING), + state_(LoadingState::SILENT1), state_time_(0.0f), + current_border_type_(BorderType::NONE), load_rect_{0, 0, 0, 1.0f} { // Configura la superficie donde se van a pintar los sprites screen_surface_->clear(static_cast(PaletteColor::WHITE)); @@ -37,12 +38,13 @@ LoadingScreen::LoadingScreen() initLineIndexArray(); // Cambia el color del borde - Screen::get()->setBorderColor(stringToColor("black")); + Screen::get()->setBorderColor(stringToColor("white")); + transitionToState(LoadingState::SILENT1); } // Destructor LoadingScreen::~LoadingScreen() { - JA_StopMusic(); + Audio::get()->stopMusic(); } // Comprueba el manejador de eventos @@ -78,25 +80,39 @@ void LoadingScreen::transitionToState(LoadingState new_state) { // Acciones específicas al entrar en cada estado switch (new_state) { - case LoadingState::PRE_LOADING: - // No hay acción específica + case LoadingState::SILENT1: + case LoadingState::SILENT2: + current_border_type_ = BorderType::WHITE; + Audio::get()->stopMusic(); break; + case LoadingState::HEADER1: + case LoadingState::HEADER2: + current_border_type_ = BorderType::RED; + // Reproducir sonido de cargar el header + Audio::get()->playMusic("loading_sound1.ogg"); + break; + + case LoadingState::BYTES1: + case LoadingState::BYTES2: case LoadingState::LOADING_MONO: + current_border_type_ = BorderType::YELLOW; // Reproducir sonido de carga monocromática - JA_PlayMusic(Resource::get()->getMusic("loading_sound2.ogg")); + Audio::get()->playMusic("loading_sound2.ogg"); break; case LoadingState::LOADING_COLOR: + current_border_type_ = BorderType::YELLOW; // Reproducir sonido de carga en color - JA_PlayMusic(Resource::get()->getMusic("loading_sound3.ogg")); + Audio::get()->playMusic("loading_sound3.ogg"); break; case LoadingState::COMPLETE: + current_border_type_ = BorderType::WHITE; // Transicionar a la pantalla de título SceneManager::current = SceneManager::Scene::TITLE; SceneManager::options = SceneManager::Options::TITLE_WITH_LOADING_SCREEN; - JA_StopMusic(); + Audio::get()->stopMusic(); break; } } @@ -105,12 +121,50 @@ void LoadingScreen::transitionToState(LoadingState new_state) { void LoadingScreen::updateState(float delta_time) { state_time_ += delta_time; - // Solo PRE_LOADING transiciona por tiempo - // LOADING_MONO y LOADING_COLOR transicionan cuando completan su progreso - if (state_ == LoadingState::PRE_LOADING) { - if (state_time_ >= PRE_LOADING_DURATION) { - transitionToState(LoadingState::LOADING_MONO); - } + // Transiciones automáticas por tiempo para los estados iniciales + // LOADING_MONO y LOADING_COLOR transicionan en sus propias funciones + switch (state_) { + case LoadingState::SILENT1: + if (state_time_ >= SILENT1_DURATION) { + transitionToState(LoadingState::HEADER1); + } + break; + + case LoadingState::HEADER1: + if (state_time_ >= HEADER1_DURATION) { + transitionToState(LoadingState::BYTES1); + } + break; + + case LoadingState::BYTES1: + if (state_time_ >= BYTES1_DURATION) { + transitionToState(LoadingState::SILENT2); + } + break; + + case LoadingState::SILENT2: + if (state_time_ >= SILENT2_DURATION) { + transitionToState(LoadingState::HEADER2); + } + break; + + case LoadingState::HEADER2: + if (state_time_ >= HEADER2_DURATION) { + transitionToState(LoadingState::LOADING_MONO); + } + break; + + case LoadingState::BYTES2: + if (state_time_ >= BYTES2_DURATION) { + transitionToState(LoadingState::COMPLETE); + } + break; + + case LoadingState::LOADING_MONO: + case LoadingState::LOADING_COLOR: + case LoadingState::COMPLETE: + // Estos estados se gestionan en updateMonoLoad/updateColorLoad + break; } } @@ -154,7 +208,7 @@ void LoadingScreen::updateMonoLoad(float delta_time) { Screen::get()->setRendererSurface(previous_renderer); } -// Gestiona la carga en color (time-based simplificado) +// Gestiona la carga en color void LoadingScreen::updateColorLoad(float delta_time) { // Calcular progreso lineal (0.0 - 1.0) float progress = state_time_ / LOADING_COLOR_DURATION; @@ -169,7 +223,7 @@ void LoadingScreen::updateColorLoad(float delta_time) { // Verificar si ha completado todos los bloques if (current_block >= COLOR_TOTAL_BLOCKS) { - transitionToState(LoadingState::COMPLETE); + transitionToState(LoadingState::BYTES2); return; } @@ -189,14 +243,8 @@ void LoadingScreen::updateColorLoad(float delta_time) { Screen::get()->setRendererSurface(previous_renderer); } -// Dibuja la pantalla de carga -void LoadingScreen::renderLoad() { - // El dibujo incremental ya se realiza en updateMonoLoad() y updateColorLoad() - // Esta función ya no es necesaria, pero se mantiene por compatibilidad -} - -// Dibuja el efecto de carga en el borde -void LoadingScreen::renderBorder() { +// Dibuja el efecto de carga amarillo y azul en el borde +void LoadingScreen::renderYellowBorder() { // Obtiene la Surface del borde auto border = Screen::get()->getBorderSurface(); @@ -222,18 +270,71 @@ void LoadingScreen::renderBorder() { } } +// Dibuja el efecto de carga rojo y azul en el borde +void LoadingScreen::renderRedBorder() { + // Obtiene la Surface del borde + auto border = Screen::get()->getBorderSurface(); + + // Pinta el borde de color azul + border->clear(static_cast(PaletteColor::CYAN)); + + // Añade lineas rojas + const Uint8 COLOR = static_cast(PaletteColor::RED); + const int WIDTH = Options::game.width + (Options::video.border.width * 2); + const int HEIGHT = Options::game.height + (Options::video.border.height * 2); + bool draw_enabled = true; + + // Primera linea (para que tenga poca variacion) + int row = 0; + const int FIRST_ROW_HEIGHT = (rand() % 4) + 3; + if (draw_enabled) { + for (int i = row; i < row + FIRST_ROW_HEIGHT; ++i) { + border->drawLine(0, i, WIDTH, i, COLOR); + } + } + row += FIRST_ROW_HEIGHT; + draw_enabled = !draw_enabled; + + // Resto de lineas + while (row < HEIGHT) { + const int ROW_HEIGHT = (rand() % 3) + 8; + if (draw_enabled) { + for (int i = row; i < row + ROW_HEIGHT; ++i) { + border->drawLine(0, i, WIDTH, i, COLOR); + } + } + row += ROW_HEIGHT; + draw_enabled = !draw_enabled; + } +} + +// Dibuja el borde de color blanco +void LoadingScreen::renderWhiteBorder() { + // Obtiene la Surface del borde + auto border = Screen::get()->getBorderSurface(); + + // Pinta el borde de color azul + border->clear(static_cast(PaletteColor::WHITE)); +} + // Actualiza las variables void LoadingScreen::update() { // Obtener delta time desde el último frame const float delta_time = delta_timer_->tick(); - checkInput(); // Comprueba las entradas - updateState(delta_time); // Actualiza el estado y gestiona transiciones + checkInput(); // Comprueba las entradas + updateState(delta_time); // Actualiza el estado y gestiona transiciones // Actualizar la carga según el estado actual switch (state_) { - case LoadingState::PRE_LOADING: - // No hay animación de carga durante la pausa inicial + case LoadingState::SILENT1: + case LoadingState::HEADER1: + case LoadingState::BYTES1: + case LoadingState::SILENT2: + case LoadingState::HEADER2: + case LoadingState::BYTES2: + // Por ahora no hacen nada específico + // Tú definirás la lógica de cada estado aquí break; case LoadingState::LOADING_MONO: @@ -249,16 +350,15 @@ void LoadingScreen::update() { break; } - renderLoad(); // Dibuja la pantalla de carga - Screen::get()->update(); // Actualiza el objeto Screen + // Singletones + Audio::get()->update(); // Actualiza el objeto Audio + Screen::get()->update(); // Actualiza el objeto Screen } // Dibuja en pantalla void LoadingScreen::render() { - if (Options::video.border.enabled) { - // Dibuja el efecto de carga en el borde - renderBorder(); - } + // Pinta el borde + renderBorder(); // Prepara para empezar a dibujar en la textura de juego Screen::get()->start(); @@ -273,9 +373,8 @@ void LoadingScreen::render() { // Bucle para el logo del juego void LoadingScreen::run() { - // Inicia el sonido de carga - JA_SetVolume(64); - JA_PlayMusic(Resource::get()->getMusic("loading_sound1.ogg")); + // Ajusta el volumen + Audio::get()->setMusicVolume(50); // Limpia la pantalla Screen::get()->start(); @@ -288,5 +387,26 @@ void LoadingScreen::run() { render(); } - JA_SetVolume(128); + Audio::get()->setMusicVolume(100); +} + +// Pinta el borde +void LoadingScreen::renderBorder() { + if (Options::video.border.enabled) { + // Dibuja el efecto de carga en el borde según el tipo actual + switch (current_border_type_) { + case BorderType::YELLOW: + renderYellowBorder(); + break; + case BorderType::RED: + renderRedBorder(); + break; + case BorderType::WHITE: + renderWhiteBorder(); + break; + case BorderType::NONE: + // No renderizar borde + break; + } + } } \ No newline at end of file diff --git a/source/game/scenes/loading_screen.hpp b/source/game/scenes/loading_screen.hpp index d61aefb..2892c9e 100644 --- a/source/game/scenes/loading_screen.hpp +++ b/source/game/scenes/loading_screen.hpp @@ -11,12 +11,25 @@ class Surface; // Forward declaration // Estados de la secuencia de carga enum class LoadingState { - PRE_LOADING, // Pausa inicial antes de empezar + SILENT1, // Pausa inicial antes de empezar + HEADER1, // Cabecera + BYTES1, // Datos + SILENT2, // Segunda pausa + HEADER2, // Cabecera pantalla LOADING_MONO, // Carga de pantalla monocromática (escaneo de líneas) LOADING_COLOR, // Carga de pantalla en color (bloques) + BYTES2, // Datos COMPLETE // Carga completa }; +// Tipos de borde para la pantalla de carga +enum class BorderType { + NONE, + YELLOW, + RED, + WHITE +}; + class LoadingScreen { public: LoadingScreen(); // Constructor @@ -25,9 +38,14 @@ class LoadingScreen { private: // --- Constantes de tiempo (en segundos) --- - static constexpr float PRE_LOADING_DURATION = 1.0f; // Pausa inicial - static constexpr float LOADING_MONO_DURATION = 16.0f; // Duración total de la carga monocromática - static constexpr float LOADING_COLOR_DURATION = 4.0f; // Duración total de la carga en color + static constexpr float SILENT1_DURATION = 1.0f; // Pausa inicial + static constexpr float HEADER1_DURATION = 2.0f; // Cabecera + static constexpr float BYTES1_DURATION = 0.5f; // Datos + static constexpr float SILENT2_DURATION = 2.0f; // Segunda pausa + static constexpr float HEADER2_DURATION = 2.0f; // Cabecera pantalla + static constexpr float LOADING_MONO_DURATION = 16.0f; // Duración total de la carga monocromática + static constexpr float LOADING_COLOR_DURATION = 4.0f; // Duración total de la carga en color + static constexpr float BYTES2_DURATION = 2.0f; // Datos // --- Constantes de geometría --- static constexpr int MONO_TOTAL_LINES = 192; // Total de líneas en carga monocromática @@ -49,6 +67,7 @@ class LoadingScreen { std::unique_ptr delta_timer_; // Timer para delta time LoadingState state_; // Estado actual de la secuencia float state_time_; // Tiempo acumulado en el estado actual + BorderType current_border_type_; // Tipo de borde actual std::array line_index_; // El orden en el que se procesan las 192 líneas de la pantalla de carga SDL_FRect load_rect_; // Rectángulo para dibujar la pantalla de carga @@ -61,7 +80,9 @@ class LoadingScreen { void transitionToState(LoadingState new_state); // Transiciona a un nuevo estado void updateMonoLoad(float delta_time); // Gestiona la carga monocromática (time-based) void updateColorLoad(float delta_time); // Gestiona la carga en color (time-based) - void renderLoad(); // Dibuja la pantalla de carga - void renderBorder(); // Dibuja el efecto de carga en el borde + void renderBorder(); // Pinta el borde + void renderYellowBorder(); // Dibuja el efecto de carga amarillo y azul en el borde + void renderRedBorder(); // Dibuja el efecto de carga rojo y azul en el borde + void renderWhiteBorder(); // Dibuja el borde de color blanco void initLineIndexArray(); // Inicializa el array de índices de líneas }; \ No newline at end of file