#include "logo.h" #include // Manejo de eventos de SDL (teclado, ratón, etc.) #include // Inicialización y limpieza de SDL #include // Manejo de logs en SDL #include // Funciones de temporización de SDL #include "global_inputs.h" // Funciones para manejar entradas globales #include "mouse.h" // Manejo de eventos del ratón #include "options.h" // Configuración global de opciones #include "s_sprite.h" // Clase para manejar sprites #include "screen.h" // Clase para manejar la pantalla #include "surface.h" // Clase para manejar superficies // Constructor de la clase Logo: inicializa los recursos necesarios Logo::Logo() { init(); } // Destructor de la clase Logo: libera los recursos utilizados Logo::~Logo() { close(); } // Método privado para inicializar los recursos del logotipo void Logo::init() { // Configura las prioridades de los logs SDL_SetLogPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); SDL_SetLogPriority(SDL_LOG_CATEGORY_TEST, SDL_LOG_PRIORITY_ERROR); // Inicializa la pantalla Screen::get()->init(); // Carga la superficie del logotipo desde un archivo y la escala logo_surface = std::make_shared("jailgames.gif"); logo_surface->setTransparentColor(0); blackOutPalette(); // Crea el sprite del logotipo y lo posiciona en el centro de la pantalla logo_sprite = std::make_unique(logo_surface); logo_sprite->setPosition( (options.logo.width - logo_sprite->getWidth()) / 2, (options.logo.height - logo_sprite->getHeight()) / 2); // Inicia el contador de tiempo init_time = SDL_GetTicks(); // Log de inicio del logotipo SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Logo start"); } // Método privado para liberar los recursos del logotipo void Logo::close() { // Destruye la pantalla Screen::get()->destroy(); // Log de finalización del logotipo SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\nBye!"); // Finaliza SDL SDL_Quit(); } // Método privado para manejar los eventos de entrada void Logo::checkEvents() { SDL_Event event; while (SDL_PollEvent(&event)) // Procesa todos los eventos en la cola { switch (event.type) { case SDL_EVENT_QUIT: // Evento de salida (cerrar la ventana) options.logo.running = false; // Detiene el bucle principal return; } // Maneja entradas globales y eventos del ratón globalInputs::check(event); Mouse::handleEvent(event); } } // Método privado para actualizar el estado del logotipo void Logo::update() { // Comprueba si ha pasado suficiente tiempo para actualizar if (SDL_GetTicks() - ticks > options.logo.speed) { ticks = SDL_GetTicks(); // Actualiza el contador de ticks // Actualiza la pantalla Screen::get()->update(); // Gestiona los diferentes estados del logo updateState(); } } // Método privado para renderizar el logotipo en pantalla void Logo::render() { Screen::get()->start(); // Inicia el proceso de renderizado logo_sprite->render(); // Renderiza el sprite del logotipo Screen::get()->render(); // Finaliza el renderizado } // Método principal que ejecuta el ciclo de vida del logotipo int Logo::run() { while (options.logo.running) // Bucle principal mientras el logotipo esté activo { update(); // Actualiza el estado del logotipo checkEvents(); // Maneja los eventos de entrada render(); // Renderiza el logotipo } return 0; // Devuelve 0 al finalizar } // Transforma todos los colores de la paleta a negro void Logo::blackOutPalette() { for (int i = 1; i < 256; ++i) { Screen::get()->getRendererSurface()->setColor(i, 0xFF000000); } } // Gestiona los diferentes estados del logo void Logo::updateState() { switch (state) { case LogoState::BLACK: elapsed_time = SDL_GetTicks() - init_time; if (elapsed_time > 2000) { state = LogoState::LINES; init_time = SDL_GetTicks(); steps[69] = 1; } break; case LogoState::LINES: elapsed_time = SDL_GetTicks() - init_time; if (elapsed_time > 50) { init_time = SDL_GetTicks(); if (advancePaletteStep(70, steps, max_step)) { state = LogoState::COMPLETE; } } break; case LogoState::COMPLETE: elapsed_time = SDL_GetTicks() - init_time; if (elapsed_time > 5000) { state = LogoState::END; } break; case LogoState::END: options.logo.running = false; break; default: break; } } bool Logo::advancePaletteStep(int size, int steps[], int max_step) { bool allDone = true; for (int i = 1; i < size; ++i) { if (steps[i] > 0 && steps[i] < max_step) { // Avanza un paso steps[i]++; // Calcula la intensidad del color int intensity = (steps[i] * 256) / max_step; if (intensity > 255) intensity = 255; // Actualiza el color al nuevo valor en formato ARGB Screen::get()->getRendererSurface()->setColor(i, 0xFF000000 | (intensity << 16) | (intensity << 8) | intensity); } if (i < size - 1 && steps[i + 1] >= 2 && steps[i] == 0) { // Inicia el paso de este color si el siguiente ha avanzado al menos dos pasos steps[i] = 1; Screen::get()->getRendererSurface()->setColor(i, 0xFF000000 | (64 << 16) | (64 << 8) | 64); // Paso inicial } if (steps[i] < max_step) { allDone = false; } } return allDone; }