From d1acc5931910d4c5370146ced7c8c73f07f3b8e3 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sun, 26 Oct 2025 19:51:08 +0100 Subject: [PATCH] migrant LoadingScreen a delta_time i estats --- source/game/scene_manager.hpp | 7 +- source/game/scenes/loading_screen.cpp | 224 ++++++++++++++++++-------- source/game/scenes/loading_screen.hpp | 97 +++++------ source/game/scenes/logo.cpp | 5 +- source/game/scenes/logo.hpp | 61 +++---- 5 files changed, 250 insertions(+), 144 deletions(-) diff --git a/source/game/scene_manager.hpp b/source/game/scene_manager.hpp index 72f5b8b..6271c30 100644 --- a/source/game/scene_manager.hpp +++ b/source/game/scene_manager.hpp @@ -32,8 +32,13 @@ enum class Options { TITLE_WITHOUT_LOADING_SCREEN // Al título sin pantalla de carga }; -// --- Variables de estado globales (inline C++17) --- +// --- Variables de estado globales --- +#ifndef _DEBUG inline Scene current = Scene::LOGO; // Escena actual inline Options options = Options::LOGO_TO_LOADING_SCREEN; // Opciones de la escena actual +#else +inline Scene current = Scene::LOADING_SCREEN; // Escena actual +inline Options options = Options::LOGO_TO_LOADING_SCREEN; // Opciones de la escena actual +#endif } // namespace SceneManager diff --git a/source/game/scenes/loading_screen.cpp b/source/game/scenes/loading_screen.cpp index 311073e..2e5406f 100644 --- a/source/game/scenes/loading_screen.cpp +++ b/source/game/scenes/loading_screen.cpp @@ -21,7 +21,11 @@ LoadingScreen::LoadingScreen() color_loading_screen_surface_(Resource::get()->getSurface("loading_screen_color.gif")), mono_loading_screen_sprite_(std::make_shared(mono_loading_screen_surface_, 0, 0, mono_loading_screen_surface_->getWidth(), mono_loading_screen_surface_->getHeight())), 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)) { + screen_surface_(std::make_shared(Options::game.width, Options::game.height)), + delta_timer_(std::make_unique()), + state_(LoadingState::PRE_LOADING), + state_time_(0.0f), + load_rect_{0, 0, 0, 1.0f} { // Configura la superficie donde se van a pintar los sprites screen_surface_->clear(static_cast(PaletteColor::WHITE)); @@ -29,16 +33,8 @@ LoadingScreen::LoadingScreen() SceneManager::current = SceneManager::Scene::LOADING_SCREEN; SceneManager::options = SceneManager::Options::NONE; - // Establece el orden de las lineas para imitar el direccionamiento de memoria del spectrum - for (int i = 0; i < 192; ++i) { - if (i < 64) { // Primer bloque de 2K - line_index_[i] = ((i % 8) * 8) + (i / 8); - } else if (i < 128) { // Segundo bloque de 2K - line_index_[i] = 64 + ((i % 8) * 8) + ((i - 64) / 8); - } else { // Tercer bloque de 2K - line_index_[i] = 128 + ((i % 8) * 8) + ((i - 128) / 8); - } - } + // Inicializa el array de índices de líneas + initLineIndexArray(); // Cambia el color del borde Screen::get()->setBorderColor(stringToColor("black")); @@ -62,63 +58,141 @@ void LoadingScreen::checkInput() { globalInputs::check(); } -// Gestiona el contador de carga -void LoadingScreen::updateLoad() { - // Primera parte de la carga, la parte en blanco y negro - if (loading_first_part_) { - // Cada 5 pasos el load_counter_ se incrementa en uno - constexpr int NUM_STEPS = 5; - constexpr int STEPS = 51; - load_counter_ = counter_ / NUM_STEPS; - - if (load_counter_ < 192) { - load_rect_.x = STEPS * (counter_ % NUM_STEPS); - load_rect_.y = line_index_[load_counter_]; - mono_loading_screen_sprite_->setClip(load_rect_); - mono_loading_screen_sprite_->setPosition(load_rect_); - } - // Una vez actualizadas las 192 lineas, pasa a la segunda fase de la carga - else if (load_counter_ == 192) { - loading_first_part_ = false; - load_counter_ = 0; - load_rect_ = {0, 0, 16, 8}; - color_loading_screen_sprite_->setClip(load_rect_); - color_loading_screen_sprite_->setPosition(load_rect_); - JA_PlayMusic(Resource::get()->getMusic("loading_sound3.ogg")); - } - } - // Segunda parte de la carga, la parte de los bloques en color - else { - load_counter_ += 2; - load_rect_.x = (load_counter_ * 8) % 256; - load_rect_.y = (load_counter_ / 32) * 8; - color_loading_screen_sprite_->setClip(load_rect_); - color_loading_screen_sprite_->setPosition(load_rect_); - - // Comprueba si ha terminado la intro - if (load_counter_ >= 768) { - SceneManager::current = SceneManager::Scene::TITLE; - SceneManager::options = SceneManager::Options::TITLE_WITH_LOADING_SCREEN; - JA_StopMusic(); +// Inicializa el array de índices de líneas (imita el direccionamiento de memoria del Spectrum) +void LoadingScreen::initLineIndexArray() { + for (int i = 0; i < MONO_TOTAL_LINES; ++i) { + if (i < 64) { // Primer bloque de 2K + line_index_[i] = ((i % 8) * 8) + (i / 8); + } else if (i < 128) { // Segundo bloque de 2K + line_index_[i] = 64 + ((i % 8) * 8) + ((i - 64) / 8); + } else { // Tercer bloque de 2K + line_index_[i] = 128 + ((i % 8) * 8) + ((i - 128) / 8); } } } -// Gestiona el contador interno -void LoadingScreen::updateCounter() { - (pre_counter_ >= 50) ? counter_++ : pre_counter_++; +// Transiciona a un nuevo estado +void LoadingScreen::transitionToState(LoadingState new_state) { + state_ = new_state; + state_time_ = 0.0f; - if (counter_ == 1) { - JA_PlayMusic(Resource::get()->getMusic("loading_sound2.ogg")); + // Acciones específicas al entrar en cada estado + switch (new_state) { + case LoadingState::PRE_LOADING: + // No hay acción específica + break; + + case LoadingState::LOADING_MONO: + // Reproducir sonido de carga monocromática + JA_PlayMusic(Resource::get()->getMusic("loading_sound2.ogg")); + break; + + case LoadingState::LOADING_COLOR: + // Reproducir sonido de carga en color + JA_PlayMusic(Resource::get()->getMusic("loading_sound3.ogg")); + break; + + case LoadingState::COMPLETE: + // Transicionar a la pantalla de título + SceneManager::current = SceneManager::Scene::TITLE; + SceneManager::options = SceneManager::Options::TITLE_WITH_LOADING_SCREEN; + JA_StopMusic(); + break; } } +// Actualiza el estado actual +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); + } + } +} + +// Gestiona la carga monocromática (time-based simplificado) +void LoadingScreen::updateMonoLoad(float delta_time) { + // Calcular progreso lineal (0.0 - 1.0) + float progress = state_time_ / LOADING_MONO_DURATION; + progress = std::min(progress, 1.0f); + + // Calcular paso total actual (0-959) + const int total_steps = MONO_TOTAL_LINES * MONO_STEPS_PER_LINE; // 192 * 5 = 960 + const int current_step = static_cast(progress * total_steps); + + // Calcular línea y sub-paso + const int current_line = current_step / MONO_STEPS_PER_LINE; // 0-191 + const int current_substep = current_step % MONO_STEPS_PER_LINE; // 0-4 + + // Verificar si ha completado todas las líneas + if (current_line >= MONO_TOTAL_LINES) { + transitionToState(LoadingState::LOADING_COLOR); + return; + } + + // Calcular rectángulo de clip (con floats para mayor precisión) + const float texture_width = static_cast(mono_loading_screen_surface_->getWidth()); + const float clip_width = texture_width / MONO_STEPS_PER_LINE; + const float clip_x = current_substep * clip_width; + + load_rect_.x = clip_x; + load_rect_.y = static_cast(line_index_[current_line]); + load_rect_.w = clip_width; + load_rect_.h = 1.0f; + + // Configurar y dibujar sobre screen_surface_ + mono_loading_screen_sprite_->setClip(load_rect_); + mono_loading_screen_sprite_->setPosition(load_rect_); + + auto previous_renderer = Screen::get()->getRendererSurface(); + Screen::get()->setRendererSurface(screen_surface_); + mono_loading_screen_sprite_->render(1, stringToColor("black")); + Screen::get()->setRendererSurface(previous_renderer); +} + +// Gestiona la carga en color (time-based simplificado) +void LoadingScreen::updateColorLoad(float delta_time) { + // Calcular progreso lineal (0.0 - 1.0) + float progress = state_time_ / LOADING_COLOR_DURATION; + progress = std::min(progress, 1.0f); + + // Calcular iteración actual (el código original incrementaba de 2 en 2) + const int total_iterations = COLOR_TOTAL_BLOCKS / 2; // 768 / 2 = 384 iteraciones + const int current_iteration = static_cast(progress * total_iterations); + + // Convertir a bloque (incrementa de 2 en 2, empezando en 2) + const int current_block = (current_iteration + 1) * 2; + + // Verificar si ha completado todos los bloques + if (current_block >= COLOR_TOTAL_BLOCKS) { + transitionToState(LoadingState::COMPLETE); + return; + } + + // Calcular posición del bloque + load_rect_.x = static_cast((current_block * COLOR_BLOCK_SPACING) % 256); + load_rect_.y = static_cast((current_block / COLOR_BLOCKS_PER_ROW) * COLOR_BLOCK_SPACING); + load_rect_.w = static_cast(COLOR_BLOCK_WIDTH); + load_rect_.h = static_cast(COLOR_BLOCK_HEIGHT); + + // Configurar y dibujar sobre screen_surface_ + color_loading_screen_sprite_->setClip(load_rect_); + color_loading_screen_sprite_->setPosition(load_rect_); + + auto previous_renderer = Screen::get()->getRendererSurface(); + Screen::get()->setRendererSurface(screen_surface_); + color_loading_screen_sprite_->render(); + Screen::get()->setRendererSurface(previous_renderer); +} + // Dibuja la pantalla de carga void LoadingScreen::renderLoad() { - auto previuos_renderer = Screen::get()->getRendererSurface(); - Screen::get()->setRendererSurface(screen_surface_); - loading_first_part_ ? mono_loading_screen_sprite_->render(1, stringToColor("black")) : color_loading_screen_sprite_->render(); - Screen::get()->setRendererSurface(previuos_renderer); + // 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 @@ -150,15 +224,33 @@ void LoadingScreen::renderBorder() { // Actualiza las variables void LoadingScreen::update() { - // Comprueba que la diferencia de ticks sea mayor a la velocidad del juego - if (SDL_GetTicks() - ticks_ > GAME_SPEED) { - ticks_ = SDL_GetTicks(); - checkInput(); - updateCounter(); - updateLoad(); - renderLoad(); - Screen::get()->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 + + // Actualizar la carga según el estado actual + switch (state_) { + case LoadingState::PRE_LOADING: + // No hay animación de carga durante la pausa inicial + break; + + case LoadingState::LOADING_MONO: + updateMonoLoad(delta_time); + break; + + case LoadingState::LOADING_COLOR: + updateColorLoad(delta_time); + break; + + case LoadingState::COMPLETE: + // No hay más actualizaciones + break; } + + renderLoad(); // Dibuja la pantalla de carga + Screen::get()->update(); // Actualiza el objeto Screen } // Dibuja en pantalla diff --git a/source/game/scenes/loading_screen.hpp b/source/game/scenes/loading_screen.hpp index 16e7a93..d61aefb 100644 --- a/source/game/scenes/loading_screen.hpp +++ b/source/game/scenes/loading_screen.hpp @@ -2,59 +2,66 @@ #include -#include // Para shared_ptr -class SurfaceSprite; // lines 7-7 -class Surface; // lines 8-8 +#include // Para std::array +#include // Para shared_ptr + +#include "utils/delta_timer.hpp" // Para DeltaTimer +class SurfaceSprite; // Forward declaration +class Surface; // Forward declaration + +// Estados de la secuencia de carga +enum class LoadingState { + PRE_LOADING, // Pausa inicial antes de empezar + LOADING_MONO, // Carga de pantalla monocromática (escaneo de líneas) + LOADING_COLOR, // Carga de pantalla en color (bloques) + COMPLETE // Carga completa +}; class LoadingScreen { + public: + LoadingScreen(); // Constructor + ~LoadingScreen(); // Destructor + void run(); // Bucle principal + private: - // Objetos y punteros + // --- 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 + + // --- Constantes de geometría --- + static constexpr int MONO_TOTAL_LINES = 192; // Total de líneas en carga monocromática + static constexpr int MONO_STEPS_PER_LINE = 5; // Pasos de animación por línea + static constexpr int COLOR_TOTAL_BLOCKS = 768; // Total de bloques en carga color + static constexpr int COLOR_BLOCK_WIDTH = 16; // Ancho del bloque de color + static constexpr int COLOR_BLOCK_HEIGHT = 8; // Alto del bloque de color + static constexpr int COLOR_BLOCKS_PER_ROW = 32; // Bloques por fila (256 / 8) + static constexpr int COLOR_BLOCK_SPACING = 8; // Espaciado entre bloques + + // --- Objetos y punteros --- std::shared_ptr mono_loading_screen_surface_; // Surface con la pantalla de carga en blanco y negro std::shared_ptr color_loading_screen_surface_; // Surface con la pantalla de carga en color std::shared_ptr mono_loading_screen_sprite_; // SSprite para manejar la textura loadingScreenTexture1 std::shared_ptr color_loading_screen_sprite_; // SSprite para manejar la textura loadingScreenTexture2 std::shared_ptr screen_surface_; // Surface para dibujar la pantalla de carga - // Variables - int pre_counter_ = 0; // Contador previo para realizar una pausa inicial - int counter_ = 0; // Contador - Uint32 ticks_ = 0; // Contador de ticks para ajustar la velocidad del programa - int load_counter_ = 0; // Contador para controlar las cargas - bool loading_first_part_ = true; // Para saber en que parte de la carga se encuentra - int line_index_[192]; // El orden en el que se procesan las 192 lineas de la pantalla de carga - SDL_FRect load_rect_ = {0, 0, 52, 1}; // Rectangulo para dibujar la pantalla de carga + // --- Variables de estado --- + 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 + 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 - // Actualiza las variables - void update(); - - // Dibuja en pantalla - void render(); - - // Comprueba el manejador de eventos - void checkEvents(); - - // Comprueba las entradas - void checkInput(); - - // Gestiona el contador interno - void updateCounter(); - - // Gestiona el contador de carga - void updateLoad(); - - // Dibuja la pantalla de carga - void renderLoad(); - - // Dibuja el efecto de carga en el borde - void renderBorder(); - - public: - // Constructor - LoadingScreen(); - - // Destructor - ~LoadingScreen(); - - // Bucle principal - void run(); + // --- Funciones --- + void update(); // Actualiza las variables + void render(); // Dibuja en pantalla + void checkEvents(); // Comprueba el manejador de eventos + void checkInput(); // Comprueba las entradas + void updateState(float delta_time); // Actualiza el estado actual + 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 initLineIndexArray(); // Inicializa el array de índices de líneas }; \ No newline at end of file diff --git a/source/game/scenes/logo.cpp b/source/game/scenes/logo.cpp index 56e3fc5..303c781 100644 --- a/source/game/scenes/logo.cpp +++ b/source/game/scenes/logo.cpp @@ -1,6 +1,7 @@ #include "game/scenes/logo.hpp" #include + #include // Para std::clamp #include "core/input/global_inputs.hpp" // Para check @@ -105,8 +106,8 @@ void Logo::updateTextureColors() { case LogoState::DISPLAY: { // Asegurar que ambos logos estén en blanco durante el display - jailgames_color_ = color_.back(); // BRIGHT_WHITE - since_1998_color_ = color_.back(); // BRIGHT_WHITE + jailgames_color_ = color_.back(); // BRIGHT_WHITE + since_1998_color_ = color_.back(); // BRIGHT_WHITE break; } diff --git a/source/game/scenes/logo.hpp b/source/game/scenes/logo.hpp index b64564b..ea910b2 100644 --- a/source/game/scenes/logo.hpp +++ b/source/game/scenes/logo.hpp @@ -2,20 +2,21 @@ #include -#include // Para shared_ptr -#include // Para vector +#include // Para shared_ptr +#include // Para vector + #include "utils/delta_timer.hpp" // Para DeltaTimer -class SurfaceSprite; // Forward declaration -class Surface; // Forward declaration +class SurfaceSprite; // Forward declaration +class Surface; // Forward declaration // Estados de la secuencia del logo enum class LogoState { - INITIAL, // Espera inicial - JAILGAMES_SLIDE_IN, // Las líneas de JAILGAMES se deslizan hacia el centro - SINCE_1998_FADE_IN, // Aparición gradual del texto "Since 1998" - DISPLAY, // Logo completo visible - FADE_OUT, // Desaparición gradual - END // Fin de la secuencia + INITIAL, // Espera inicial + JAILGAMES_SLIDE_IN, // Las líneas de JAILGAMES se deslizan hacia el centro + SINCE_1998_FADE_IN, // Aparición gradual del texto "Since 1998" + DISPLAY, // Logo completo visible + FADE_OUT, // Desaparición gradual + END // Fin de la secuencia }; class Logo { @@ -26,11 +27,11 @@ class Logo { private: // --- Constantes de tiempo (en segundos) --- - static constexpr float INITIAL_DELAY = 0.5f; // Tiempo antes de que empiece la animación - static constexpr float JAILGAMES_SLIDE_DURATION = 1.2f; // Duración del slide-in de JAILGAMES - static constexpr float SINCE_1998_FADE_DURATION = 0.5f; // Duración del fade-in de "Since 1998" - static constexpr float DISPLAY_DURATION = 3.5f; // Tiempo que el logo permanece visible - static constexpr float FADE_OUT_DURATION = 0.5f; // Duración del fade-out final + static constexpr float INITIAL_DELAY = 0.5f; // Tiempo antes de que empiece la animación + static constexpr float JAILGAMES_SLIDE_DURATION = 1.2f; // Duración del slide-in de JAILGAMES + static constexpr float SINCE_1998_FADE_DURATION = 0.5f; // Duración del fade-in de "Since 1998" + static constexpr float DISPLAY_DURATION = 3.5f; // Tiempo que el logo permanece visible + static constexpr float FADE_OUT_DURATION = 0.5f; // Duración del fade-out final // --- Constantes de animación --- static constexpr float JAILGAMES_SLIDE_SPEED = 800.0f; // Velocidad de slide-in (pixels/segundo) @@ -45,22 +46,22 @@ class Logo { Uint8 since_1998_color_ = 0; // Color para el sprite de "Since 1998" // --- Variables de estado --- - std::vector color_; // Vector con los colores para el fade + std::vector color_; // Vector con los colores para el fadeF std::unique_ptr delta_timer_; // Timer para delta time - LogoState state_; // Estado actual de la secuencia - float state_time_; // Tiempo acumulado en el estado actual + LogoState state_; // Estado actual de la secuencia + float state_time_; // Tiempo acumulado en el estado actual // --- Funciones --- - void update(); // Actualiza las variables - void render(); // Dibuja en pantalla - void checkEvents(); // Comprueba el manejador de eventos - void checkInput(); // Comprueba las entradas - void updateJAILGAMES(float delta_time); // Gestiona el logo de JAILGAME (time-based) - void updateTextureColors(); // Gestiona el color de las texturas - void updateState(float delta_time); // Actualiza el estado actual - void transitionToState(LogoState new_state); // Transiciona a un nuevo estado - int getColorIndex(float progress) const; // Calcula el índice de color según el progreso (0.0-1.0) - void endSection(); // Termina la sección - void initColors(); // Inicializa el vector de colores - void initSprites(); // Crea los sprites de cada linea + void update(); // Actualiza las variables + void render(); // Dibuja en pantalla + void checkEvents(); // Comprueba el manejador de eventos + void checkInput(); // Comprueba las entradas + void updateJAILGAMES(float delta_time); // Gestiona el logo de JAILGAME (time-based) + void updateTextureColors(); // Gestiona el color de las texturas + void updateState(float delta_time); // Actualiza el estado actual + void transitionToState(LogoState new_state); // Transiciona a un nuevo estado + int getColorIndex(float progress) const; // Calcula el índice de color según el progreso (0.0-1.0) + void endSection(); // Termina la sección + void initColors(); // Inicializa el vector de colores + void initSprites(); // Crea los sprites de cada linea }; \ No newline at end of file