#include "app_logo.h" #include // for SDL_SCALEMODE_LINEAR #include "external/sprite.h" // for Sprite #include "external/texture.h" // for Texture bool AppLogo::initialize(SDL_Renderer* renderer, int screen_width, int screen_height) { screen_width_ = screen_width; screen_height_ = screen_height; // Cargar textura del logo desde data/logo/logo.png std::string resources_dir = getResourcesDirectory(); std::string logo_path = resources_dir + "/data/logo/logo.png"; logo_texture_ = std::make_shared(renderer, logo_path); if (logo_texture_->getWidth() == 0 || logo_texture_->getHeight() == 0) { // Error al cargar textura return false; } // Configurar filtrado LINEAR para suavizado (mejor para logos escalados) logo_texture_->setScaleMode(SDL_SCALEMODE_LINEAR); // Crear sprite con la textura logo_sprite_ = std::make_unique(logo_texture_); // IMPORTANTE: Configurar el clip para que use toda la textura float logo_width = static_cast(logo_texture_->getWidth()); float logo_height = static_cast(logo_texture_->getHeight()); logo_sprite_->setClip({0.0f, 0.0f, logo_width, logo_height}); // Calcular factor de escala para que el logo ocupe 1/4 de la pantalla (un cuadrante) // El logo debe caber en width/2 x height/2 float quadrant_width = screen_width_ / 2.0f; float quadrant_height = screen_height_ / 2.0f; float scale_x = quadrant_width / logo_width; float scale_y = quadrant_height / logo_height; float scale = (scale_x < scale_y) ? scale_x : scale_y; // Aplicar escala float scaled_width = logo_width * scale; float scaled_height = logo_height * scale; logo_sprite_->setSize(scaled_width, scaled_height); // Posicionar logo en el centro del cuadrante inferior derecho updateLogoPosition(); return true; } void AppLogo::update(float delta_time, AppMode current_mode) { // Si estamos en SANDBOX, resetear y no hacer nada (logo desactivado) if (current_mode == AppMode::SANDBOX) { state_ = AppLogoState::HIDDEN; timer_ = 0.0f; current_alpha_ = 0; return; } // Máquina de estados con fade in/out timer_ += delta_time; switch (state_) { case AppLogoState::HIDDEN: // Esperando el intervalo de espera if (timer_ >= APPLOGO_DISPLAY_INTERVAL) { state_ = AppLogoState::FADE_IN; timer_ = 0.0f; current_alpha_ = 0; } break; case AppLogoState::FADE_IN: // Fade in: alpha de 0 a 255 { float fade_progress = timer_ / APPLOGO_FADE_DURATION; if (fade_progress >= 1.0f) { // Fade in completado state_ = AppLogoState::VISIBLE; timer_ = 0.0f; current_alpha_ = 255; } else { // Interpolar alpha linealmente current_alpha_ = static_cast(fade_progress * 255.0f); } } break; case AppLogoState::VISIBLE: // Logo completamente visible, esperando duración if (timer_ >= APPLOGO_DISPLAY_DURATION) { state_ = AppLogoState::FADE_OUT; timer_ = 0.0f; current_alpha_ = 255; } break; case AppLogoState::FADE_OUT: // Fade out: alpha de 255 a 0 { float fade_progress = timer_ / APPLOGO_FADE_DURATION; if (fade_progress >= 1.0f) { // Fade out completado, volver a HIDDEN state_ = AppLogoState::HIDDEN; timer_ = 0.0f; current_alpha_ = 0; } else { // Interpolar alpha linealmente (inverso) current_alpha_ = static_cast((1.0f - fade_progress) * 255.0f); } } break; } // Aplicar alpha a la textura if (logo_texture_) { logo_texture_->setAlpha(current_alpha_); } } void AppLogo::render() { // Renderizar si NO está en estado HIDDEN (incluye FADE_IN, VISIBLE, FADE_OUT) if (state_ != AppLogoState::HIDDEN && logo_sprite_) { logo_sprite_->render(); } } void AppLogo::updateScreenSize(int screen_width, int screen_height) { screen_width_ = screen_width; screen_height_ = screen_height; // Recalcular escala y posición del logo if (logo_sprite_ && logo_texture_) { float logo_width = static_cast(logo_texture_->getWidth()); float logo_height = static_cast(logo_texture_->getHeight()); // Calcular factor de escala para que el logo ocupe 1/4 de la pantalla float quadrant_width = screen_width_ / 2.0f; float quadrant_height = screen_height_ / 2.0f; float scale_x = quadrant_width / logo_width; float scale_y = quadrant_height / logo_height; float scale = (scale_x < scale_y) ? scale_x : scale_y; // Aplicar escala float scaled_width = logo_width * scale; float scaled_height = logo_height * scale; logo_sprite_->setSize(scaled_width, scaled_height); // Posicionar logo updateLogoPosition(); } } void AppLogo::updateLogoPosition() { if (!logo_sprite_ || !logo_texture_) return; // Calcular tamaño escalado del logo (ya configurado en setSize) float logo_width = static_cast(logo_texture_->getWidth()); float logo_height = static_cast(logo_texture_->getHeight()); float quadrant_width = screen_width_ / 2.0f; float quadrant_height = screen_height_ / 2.0f; float scale_x = quadrant_width / logo_width; float scale_y = quadrant_height / logo_height; float scale = (scale_x < scale_y) ? scale_x : scale_y; float scaled_width = logo_width * scale; float scaled_height = logo_height * scale; // Centro del cuadrante inferior derecho // Cuadrante inferior derecho va de (width/2, height/2) a (width, height) // Su centro está en (3/4 * width, 3/4 * height) float quadrant_center_x = screen_width_ * 0.75f; float quadrant_center_y = screen_height_ * 0.75f; // Centrar el logo en ese punto (sprite se posiciona por esquina superior izquierda) float pos_x = quadrant_center_x - (scaled_width / 2.0f); float pos_y = quadrant_center_y - (scaled_height / 2.0f); logo_sprite_->setPos({pos_x, pos_y}); }