pasada de granera

This commit is contained in:
2026-04-06 14:02:01 +02:00
parent cdf0665458
commit 67bf6b2017
32 changed files with 14 additions and 2701 deletions

View File

@@ -26,25 +26,21 @@
Title::Title()
: game_logo_surface_(Resource::Cache::get()->getSurface("title_logo.gif")),
game_logo_sprite_(std::make_unique<Sprite>(game_logo_surface_, 29, 9, game_logo_surface_->getWidth(), game_logo_surface_->getHeight())),
loading_screen_surface_(Resource::Cache::get()->getSurface("loading_screen_color.gif")),
loading_screen_sprite_(std::make_unique<Sprite>(loading_screen_surface_, 0, 0, loading_screen_surface_->getWidth(), loading_screen_surface_->getHeight())),
title_surface_(std::make_shared<Surface>(Options::game.width, Options::game.height)),
delta_timer_(std::make_unique<DeltaTimer>()),
marquee_text_(Resource::Cache::get()->getText("gauntlet")),
menu_text_(Resource::Cache::get()->getText("gauntlet")) {
// Inicializa arrays con valores por defecto
temp_keys_.fill(SDL_SCANCODE_UNKNOWN);
temp_buttons_.fill(-1);
// Determina el estado inicial basado en opciones
state_ = SceneManager::options == SceneManager::Options::TITLE_WITH_LOADING_SCREEN ? State::SHOW_LOADING_SCREEN : State::MAIN_MENU;
// Estado inicial: menú principal
state_ = State::MAIN_MENU;
// Establece SceneManager
SceneManager::current = SceneManager::Scene::TITLE;
SceneManager::options = SceneManager::Options::NONE;
// Acciones iniciales
initMarquee(); // Inicializa la marquesina
createCheevosTexture(); // Crea y rellena la textura para mostrar los logros
Screen::get()->setBorderColor(0); // Cambia el color del borde
Audio::get()->playMusic("574071_EA_DTV.ogg"); // Inicia la musica
@@ -52,35 +48,9 @@ Title::Title()
// Destructor
Title::~Title() { // NOLINT(modernize-use-equals-default)
loading_screen_surface_->resetSubPalette();
title_surface_->resetSubPalette();
}
// Inicializa la marquesina
void Title::initMarquee() {
letters_.clear();
long_text_ = Locale::get()->get("title.marquee");
// Pre-calcular anchos de caracteres para eficiencia (iteración por codepoints UTF-8)
size_t pos = 0;
while (pos < long_text_.size()) {
uint32_t cp = Text::nextCodepoint(long_text_, pos);
Glyph l;
l.codepoint = cp;
l.clip = marquee_text_->getGlyphClip(cp); // Pre-calcular clip rect (evita búsqueda por frame)
l.x = MARQUEE_START_X;
l.width = static_cast<float>(marquee_text_->glyphWidth(cp, 0)); // Pre-calcular ancho visual del glifo
l.enabled = false;
letters_.push_back(l);
}
if (!letters_.empty()) {
letters_[0].enabled = true;
}
first_active_letter_ = 0;
last_active_letter_ = 0;
}
// Comprueba el manejador de eventos
void Title::handleEvents() {
SDL_Event event;
@@ -170,12 +140,6 @@ void Title::handleInput(float delta_time) {
}
switch (state_) {
case State::SHOW_LOADING_SCREEN:
if (Input::get()->checkAction(InputAction::ACCEPT, Input::DO_NOT_ALLOW_REPEAT)) {
transitionToState(State::FADE_LOADING_SCREEN);
}
break;
case State::CHEEVOS_MENU:
if (Input::get()->checkAction(InputAction::ACCEPT, Input::DO_NOT_ALLOW_REPEAT) ||
Input::get()->checkAction(InputAction::CANCEL, Input::DO_NOT_ALLOW_REPEAT)) {
@@ -191,53 +155,6 @@ void Title::handleInput(float delta_time) {
GlobalInputs::handle();
}
// Actualiza la marquesina
void Title::updateMarquee(float delta_time) {
const float DISPLACEMENT = MARQUEE_SPEED * delta_time;
// Solo procesar letras en rango activo + 1 para poder activar la siguiente
for (int i = first_active_letter_; i <= last_active_letter_ + 1 && i < (int)letters_.size(); ++i) {
auto& letter = letters_[i];
if (letter.enabled) {
letter.x -= DISPLACEMENT;
// Desactivar si sale de pantalla
if (letter.x < MARQUEE_EXIT_X) {
letter.enabled = false;
if (i == first_active_letter_) {
first_active_letter_++; // Avanzar inicio del rango
}
}
} else if (i > 0 && letters_[i - 1].x < MARQUEE_START_X && letters_[i - 1].enabled) {
// Activar siguiente letra usando ancho pre-calculado
letter.enabled = true;
letter.x = letters_[i - 1].x + letters_[i - 1].width + MARQUEE_LETTER_SPACING;
last_active_letter_ = i; // Expandir fin del rango
}
}
// Comprueba si ha terminado la marquesina y la reinicia
if (letters_[letters_.size() - 1].x < MARQUEE_EXIT_X) {
initMarquee();
}
}
// Dibuja la marquesina
void Title::renderMarquee() const {
auto* sprite = marquee_text_->getSprite();
sprite->setY(MARQUEE_Y);
// Solo renderizar letras activas (optimización: usa cache y rangos)
for (int i = first_active_letter_; i <= last_active_letter_ + 1 && i < (int)letters_.size(); ++i) {
const auto& letter = letters_[i];
if (letter.enabled && letter.clip.w > 0.0F) {
sprite->setClip(letter.clip);
sprite->setX(letter.x);
sprite->render(1, 6);
}
}
}
// Actualiza las variables
void Title::update() {
const float DELTA_TIME = delta_timer_->tick();
@@ -254,14 +171,6 @@ void Title::update() {
// Actualiza el estado actual
void Title::updateState(float delta_time) {
switch (state_) {
case State::SHOW_LOADING_SCREEN:
updateShowLoadingScreen(delta_time);
break;
case State::FADE_LOADING_SCREEN:
updateFadeLoadingScreen(delta_time);
break;
case State::MAIN_MENU:
updateMainMenu(delta_time);
break;
@@ -290,30 +199,8 @@ void Title::transitionToState(State new_state) {
fade_accumulator_ = 0.0F;
}
// Actualiza el estado SHOW_LOADING_SCREEN
void Title::updateShowLoadingScreen(float delta_time) {
state_time_ += delta_time;
if (state_time_ >= SHOW_LOADING_DURATION) {
transitionToState(State::FADE_LOADING_SCREEN);
}
}
// Actualiza el estado FADE_LOADING_SCREEN
void Title::updateFadeLoadingScreen(float delta_time) {
fade_accumulator_ += delta_time;
if (fade_accumulator_ >= FADE_STEP_INTERVAL) {
fade_accumulator_ = 0.0F;
if (loading_screen_surface_->fadeSubPalette()) {
transitionToState(State::MAIN_MENU);
}
}
}
// Actualiza el estado MAIN_MENU
void Title::updateMainMenu(float delta_time) {
// Actualiza la marquesina
updateMarquee(delta_time);
// Si estamos en modo remap, manejar la lógica específica
if (is_remapping_keyboard_ || is_remapping_joystick_) {
// Decrementar cooldown de ejes si estamos capturando botones de joystick
@@ -341,19 +228,11 @@ void Title::updateMainMenu(float delta_time) {
} else {
// Incrementa el temporizador solo en el menú principal normal
state_time_ += delta_time;
// Si el tiempo alcanza el timeout, va a créditos con fade
if (state_time_ >= MAIN_MENU_IDLE_TIMEOUT) {
exit_scene_ = SceneManager::Scene::CREDITS;
transitionToState(State::FADE_MENU);
}
}
}
// Actualiza el estado CHEEVOS_MENU
void Title::updateCheevosMenu(float delta_time) {
// Actualiza la marquesina (sigue visible en fondo)
updateMarquee(delta_time);
// Determina la velocidad objetivo basada en el input
float target_velocity = 0.0F;
@@ -405,8 +284,6 @@ void Title::updateFadeMenu(float delta_time) {
transitionToState(State::POST_FADE_MENU);
}
}
// Actualiza la marquesina (sigue visible en fondo)
updateMarquee(delta_time);
}
// Actualiza el estado POST_FADE_MENU
@@ -561,19 +438,13 @@ void Title::fillTitleSurface() {
case State::FADE_MENU:
renderGameLogo();
renderMainMenu();
renderMarquee();
break;
case State::CHEEVOS_MENU:
renderGameLogo();
renderCheevosMenu();
renderMarquee();
break;
case State::SHOW_LOADING_SCREEN:
case State::FADE_LOADING_SCREEN:
loading_screen_sprite_->render();
renderGameLogo();
break;
default: