This commit is contained in:
2025-10-27 11:53:12 +01:00
parent 231dcd4b3b
commit 5d8811026d
69 changed files with 899 additions and 888 deletions

View File

@@ -41,18 +41,18 @@ Credits::Credits()
void Credits::checkEvents() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
globalEvents::check(event);
GlobalEvents::check(event);
}
}
// Comprueba las entradas
void Credits::checkInput() {
globalInputs::check();
GlobalInputs::check();
}
// Inicializa los textos
void Credits::iniTexts() {
std::string keys = "";
std::string keys;
switch (Options::keys) {
case Options::ControlScheme::CURSOR:
@@ -205,9 +205,9 @@ void Credits::render() {
text_surface_->render(0, 0);
// Dibuja la textura que cubre el texto
const int offset = std::min(counter_ / 8, 192 / 2);
SDL_FRect srcRect = {0.0F, 0.0F, 256.0F, 192.0F - (offset * 2.0F)};
cover_surface_->render(0, offset * 2, &srcRect);
const int OFFSET = std::min(counter_ / 8, 192 / 2);
SDL_FRect src_rect = {0.0F, 0.0F, 256.0F, 192.0F - (OFFSET * 2.0F)};
cover_surface_->render(0, OFFSET * 2, &src_rect);
// Dibuja el sprite con el brillo
shining_sprite_->render(1, static_cast<Uint8>(PaletteColor::BRIGHT_WHITE));

View File

@@ -34,10 +34,10 @@ class Credits {
void render();
// Comprueba el manejador de eventos
void checkEvents();
static void checkEvents();
// Comprueba las entradas
void checkInput();
static void checkInput();
// Actualiza el contador
void updateCounter();

View File

@@ -104,13 +104,13 @@ void Ending::render() {
void Ending::checkEvents() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
globalEvents::check(event);
GlobalEvents::check(event);
}
}
// Comprueba las entradas
void Ending::checkInput() {
globalInputs::check();
GlobalInputs::check();
}
// Inicializa los textos
@@ -407,9 +407,7 @@ void Ending::updateSpriteCovers() {
sprite_pics_.at(current_scene_).cover_clip_desp -= 2;
} else if (sprite_pics_.at(current_scene_).cover_clip_height > 0) {
sprite_pics_.at(current_scene_).cover_clip_height -= 2;
if (sprite_pics_.at(current_scene_).cover_clip_height < 0) {
sprite_pics_.at(current_scene_).cover_clip_height = 0;
}
sprite_pics_.at(current_scene_).cover_clip_height = std::max(sprite_pics_.at(current_scene_).cover_clip_height, 0);
sprite_pics_.at(current_scene_).cover_sprite->setY(sprite_pics_.at(current_scene_).cover_sprite->getY() + 2);
}
sprite_pics_.at(current_scene_).cover_sprite->setClip(0, sprite_pics_.at(current_scene_).cover_clip_desp, sprite_pics_.at(current_scene_).cover_sprite->getWidth(), sprite_pics_.at(current_scene_).cover_clip_height);
@@ -441,21 +439,21 @@ void Ending::fillCoverTexture() {
cover_surface_->clear(static_cast<Uint8>(PaletteColor::TRANSPARENT));
// Los primeros 8 pixels crea una malla
const Uint8 color = static_cast<Uint8>(PaletteColor::BLACK);
const Uint8 COLOR = static_cast<Uint8>(PaletteColor::BLACK);
auto surface = Screen::get()->getRendererSurface();
for (int i = 0; i < 256; i += 2) {
surface->putPixel(i + 0, Options::game.height + 0, color);
surface->putPixel(i + 1, Options::game.height + 1, color);
surface->putPixel(i + 0, Options::game.height + 2, color);
surface->putPixel(i + 1, Options::game.height + 3, color);
surface->putPixel(i + 0, Options::game.height + 0, COLOR);
surface->putPixel(i + 1, Options::game.height + 1, COLOR);
surface->putPixel(i + 0, Options::game.height + 2, COLOR);
surface->putPixel(i + 1, Options::game.height + 3, COLOR);
surface->putPixel(i, Options::game.height + 4, color);
surface->putPixel(i, Options::game.height + 6, color);
surface->putPixel(i, Options::game.height + 4, COLOR);
surface->putPixel(i, Options::game.height + 6, COLOR);
}
// El resto se rellena de color sólido
SDL_FRect rect = {0, 0, 256, Options::game.height};
surface->fillRect(&rect, color);
surface->fillRect(&rect, COLOR);
Screen::get()->setRendererSurface(previuos_renderer);
}
@@ -465,17 +463,17 @@ void Ending::renderCoverTexture() {
if (cover_counter_ > 0) {
// Dibuja la textura que cubre el texto
const int OFFSET = std::min(cover_counter_, 100);
SDL_FRect srcRect = {0.0F, 200.0F - (cover_counter_ * 2.0F), 256.0F, OFFSET * 2.0F};
SDL_FRect dstRect = {0.0F, 0.0F, 256.0F, OFFSET * 2.0F};
cover_surface_->render(&srcRect, &dstRect);
SDL_FRect src_rect = {0.0F, 200.0F - (cover_counter_ * 2.0F), 256.0F, OFFSET * 2.0F};
SDL_FRect dst_rect = {0.0F, 0.0F, 256.0F, OFFSET * 2.0F};
cover_surface_->render(&src_rect, &dst_rect);
}
}
// Actualiza el volumen de la musica
void Ending::updateMusicVolume() {
void Ending::updateMusicVolume() const {
if (current_scene_ == 4 && cover_counter_ > 0) {
const float step = (100.0f - cover_counter_) / 100.0f;
const int volume = 128 * step;
JA_SetVolume(volume);
const float STEP = (100.0F - cover_counter_) / 100.0F;
const int VOLUME = 128 * STEP;
JA_SetVolume(VOLUME);
}
}

View File

@@ -59,10 +59,10 @@ class Ending {
void render();
// Comprueba el manejador de eventos
void checkEvents();
static void checkEvents();
// Comprueba las entradas
void checkInput();
static void checkInput();
// Inicializa los textos
void iniTexts();
@@ -89,7 +89,7 @@ class Ending {
void renderCoverTexture();
// Actualiza el volumen de la musica
void updateMusicVolume();
void updateMusicVolume() const;
public:
// Constructor

View File

@@ -20,7 +20,7 @@
// Constructor
Ending2::Ending2()
: state_(EndingState::PRE_CREDITS, SDL_GetTicks(), STATE_PRE_CREDITS_DURATION_) {
: state_(EndingState::PRE_CREDITS, SDL_GetTicks(), STATE_PRE_CREDITS_DURATION) {
SceneManager::current = SceneManager::Scene::ENDING2;
SceneManager::options = SceneManager::Options::NONE;
@@ -134,13 +134,13 @@ void Ending2::render() {
void Ending2::checkEvents() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
globalEvents::check(event);
GlobalEvents::check(event);
}
}
// Comprueba las entradas
void Ending2::checkInput() {
globalInputs::check();
GlobalInputs::check();
}
// Bucle principal
@@ -168,13 +168,13 @@ void Ending2::updateState() {
case EndingState::CREDITS:
if (texts_.back()->getPosY() <= GAMECANVAS_CENTER_Y) {
state_.set(EndingState::POST_CREDITS, STATE_POST_CREDITS_DURATION_);
state_.set(EndingState::POST_CREDITS, STATE_POST_CREDITS_DURATION);
}
break;
case EndingState::POST_CREDITS:
if (state_.hasEnded(EndingState::POST_CREDITS)) {
state_.set(EndingState::FADING, STATE_FADE_DURATION_);
state_.set(EndingState::FADING, STATE_FADE_DURATION);
}
break;
@@ -344,15 +344,15 @@ void Ending2::renderTexts() {
// Coloca los sprites en su sito
void Ending2::placeSprites() {
for (int i = 0; i < static_cast<int>(sprites_.size()); ++i) {
const float X = i % 2 == 0 ? FIRST_COL_ : SECOND_COL_;
const float Y = (i / 1) * (sprite_max_height_ + DIST_SPRITE_TEXT_ + Resource::get()->getText("smb2")->getCharacterSize() + DIST_SPRITE_SPRITE_) + Options::game.height + 40;
const float X = i % 2 == 0 ? FIRST_COL : SECOND_COL;
const float Y = (i / 1) * (sprite_max_height_ + DIST_SPRITE_TEXT + Resource::get()->getText("smb2")->getCharacterSize() + DIST_SPRITE_SPRITE) + Options::game.height + 40;
const float W = sprites_.at(i)->getWidth();
const float H = sprites_.at(i)->getHeight();
const float DX = -(W / 2);
const float DY = sprite_max_height_ - H;
sprites_.at(i)->setPos({X + DX, Y + DY, W, H});
sprites_.at(i)->setVelY(SPRITE_DESP_SPEED_);
sprites_.at(i)->setVelY(SPRITE_DESP_SPEED);
}
// Recoloca el sprite del jugador, que es el último de la lista
@@ -382,10 +382,10 @@ void Ending2::createSpriteTexts() {
// Determina la columna y la posición X del texto
const float X = (i == sprite_list_.size() - 1)
? (GAMECANVAS_CENTER_X - (W / 2))
: ((i % 2 == 0 ? FIRST_COL_ : SECOND_COL_) - (W / 2));
: ((i % 2 == 0 ? FIRST_COL : SECOND_COL) - (W / 2));
// Calcula la posición Y del texto en base a la posición y altura del sprite
const float Y = sprites_.at(i)->getPosY() + sprites_.at(i)->getHeight() + DIST_SPRITE_TEXT_;
const float Y = sprites_.at(i)->getPosY() + sprites_.at(i)->getHeight() + DIST_SPRITE_TEXT;
// Crea la surface
auto surface = std::make_shared<Surface>(W, H);
@@ -396,7 +396,7 @@ void Ending2::createSpriteTexts() {
// Crea el sprite
SDL_FRect pos = {X, Y, W, H};
sprite_texts_.emplace_back(std::make_shared<SurfaceMovingSprite>(surface, pos));
sprite_texts_.back()->setVelY(SPRITE_DESP_SPEED_);
sprite_texts_.back()->setVelY(SPRITE_DESP_SPEED);
Screen::get()->setRendererSurface(previuos_renderer);
}
}
@@ -427,7 +427,7 @@ void Ending2::createTexts() {
// Crea el sprite
SDL_FRect pos = {X + DX, Y, W, H};
texts_.emplace_back(std::make_shared<SurfaceMovingSprite>(surface, pos));
texts_.back()->setVelY(SPRITE_DESP_SPEED_);
texts_.back()->setVelY(SPRITE_DESP_SPEED);
Screen::get()->setRendererSurface(previuos_renderer);
}
@@ -456,7 +456,7 @@ void Ending2::createTexts() {
// Crea el sprite
SDL_FRect pos = {X + DX, Y, W, H};
texts_.emplace_back(std::make_shared<SurfaceMovingSprite>(surface, pos));
texts_.back()->setVelY(SPRITE_DESP_SPEED_);
texts_.back()->setVelY(SPRITE_DESP_SPEED);
Screen::get()->setRendererSurface(previuos_renderer);
}
}

View File

@@ -27,15 +27,15 @@ class Ending2 {
Uint32 duration; // Duración en milisegundos para el estado actual
// Constructor parametrizado para inicializar la estructura
State(EndingState initialState, Uint32 initialTicks, Uint32 stateDuration)
: state(initialState),
init_ticks(initialTicks),
duration(stateDuration) {}
State(EndingState initial_state, Uint32 initial_ticks, Uint32 state_duration)
: state(initial_state),
init_ticks(initial_ticks),
duration(state_duration) {}
// Método para comprobar si el estado ha terminado y verifica el nombre del estado
bool hasEnded(EndingState expectedState) const {
bool hasEnded(EndingState expected_state) const {
// Comprobar si el estado actual coincide con el estado esperado
if (state != expectedState) {
if (state != expected_state) {
return false; // Si no coincide, considerar que no ha terminado
}
@@ -44,22 +44,22 @@ class Ending2 {
}
// Método para establecer un nuevo estado
void set(EndingState newState, Uint32 newDuration) {
state = newState; // Actualizar el estado
void set(EndingState new_state, Uint32 new_duration) {
state = new_state; // Actualizar el estado
init_ticks = SDL_GetTicks(); // Reiniciar el tiempo de inicio
duration = newDuration; // Actualizar la duración
duration = new_duration; // Actualizar la duración
}
};
// Constantes
static constexpr int FIRST_COL_ = GAMECANVAS_FIRST_QUARTER_X + (GAMECANVAS_WIDTH / 16); // Primera columna por donde desfilan los sprites
static constexpr int SECOND_COL_ = GAMECANVAS_THIRD_QUARTER_X - (GAMECANVAS_WIDTH / 16); // Segunda columna por donde desfilan los sprites
static constexpr int DIST_SPRITE_TEXT_ = 8; // Distancia entre el sprite y el texto que lo acompaña
static constexpr int DIST_SPRITE_SPRITE_ = 0; // Distancia entre dos sprites de la misma columna
static constexpr float SPRITE_DESP_SPEED_ = -0.2f; // Velocidad de desplazamiento de los sprites
static constexpr int STATE_PRE_CREDITS_DURATION_ = 3000;
static constexpr int STATE_POST_CREDITS_DURATION_ = 5000;
static constexpr int STATE_FADE_DURATION_ = 5000;
static constexpr int FIRST_COL = GAMECANVAS_FIRST_QUARTER_X + (GAMECANVAS_WIDTH / 16); // Primera columna por donde desfilan los sprites
static constexpr int SECOND_COL = GAMECANVAS_THIRD_QUARTER_X - (GAMECANVAS_WIDTH / 16); // Segunda columna por donde desfilan los sprites
static constexpr int DIST_SPRITE_TEXT = 8; // Distancia entre el sprite y el texto que lo acompaña
static constexpr int DIST_SPRITE_SPRITE = 0; // Distancia entre dos sprites de la misma columna
static constexpr float SPRITE_DESP_SPEED = -0.2F; // Velocidad de desplazamiento de los sprites
static constexpr int STATE_PRE_CREDITS_DURATION = 3000;
static constexpr int STATE_POST_CREDITS_DURATION = 5000;
static constexpr int STATE_FADE_DURATION = 5000;
// Objetos y punteros
std::vector<std::shared_ptr<SurfaceAnimatedSprite>> sprites_; // Vector con todos los sprites a dibujar

View File

@@ -47,7 +47,7 @@ Game::Game(GameMode mode)
// Crea objetos e inicializa variables
ItemTracker::init();
DEMO_init();
demoInit();
room_ = std::make_shared<Room>(current_room_, board_);
initPlayer(spawn_point_, room_);
initStats();
@@ -71,7 +71,7 @@ Game::~Game() {
void Game::checkEvents() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
globalEvents::check(event);
GlobalEvents::check(event);
#ifdef _DEBUG
checkDebugEvents(event);
#endif
@@ -91,7 +91,7 @@ void Game::checkInput() {
Notifier::get()->show({std::string(paused_ ? "GAME PAUSED" : "GAME RUNNING")}, NotificationText::CENTER);
}
globalInputs::check();
GlobalInputs::check();
}
// Bucle para el juego
@@ -139,7 +139,7 @@ void Game::update() {
checkRestoringJail();
checkSomeCheevos();
}
DEMO_checkRoomChange();
demoCheckRoomChange();
scoreboard_->update();
keepMusicPlaying();
updateBlackScreen();
@@ -270,7 +270,7 @@ bool Game::changeRoom(const std::string& room_path) {
}
// Verifica que exista el fichero que se va a cargar
if (Asset::get()->get(room_path) != "") {
if (!Asset::get()->get(room_path).empty()) {
// Crea un objeto habitación nuevo a partir del fichero
room_ = std::make_shared<Room>(room_path, board_);
@@ -304,8 +304,8 @@ bool Game::changeRoom(const std::string& room_path) {
// Comprueba si el jugador esta en el borde de la pantalla
void Game::checkPlayerIsOnBorder() {
if (player_->getOnBorder()) {
const std::string roomName = room_->getRoom(player_->getBorder());
if (changeRoom(roomName)) {
const std::string ROOM_NAME = room_->getRoom(player_->getBorder());
if (changeRoom(ROOM_NAME)) {
player_->switchBorders();
spawn_point_ = player_->getSpawnParams();
}
@@ -314,11 +314,11 @@ void Game::checkPlayerIsOnBorder() {
// Comprueba las colisiones del jugador con los enemigos
bool Game::checkPlayerAndEnemies() {
const bool death = room_->enemyCollision(player_->getCollider());
if (death) {
const bool DEATH = room_->enemyCollision(player_->getCollider());
if (DEATH) {
killPlayer();
}
return death;
return DEATH;
}
// Comprueba las colisiones del jugador con los objetos
@@ -393,12 +393,12 @@ void Game::updateBlackScreen() {
}
// Dibuja la pantalla negra
void Game::renderBlackScreen() {
void Game::renderBlackScreen() const {
if (black_screen_) {
auto const color = static_cast<Uint8>(PaletteColor::BLACK);
auto const COLOR = static_cast<Uint8>(PaletteColor::BLACK);
Screen::get()->setRendererSurface();
Screen::get()->clearSurface(color);
Screen::get()->setBorderColor(color);
Screen::get()->clearSurface(COLOR);
Screen::get()->setBorderColor(COLOR);
}
}
@@ -416,15 +416,15 @@ void Game::setScoreBoardColor() {
// Comprueba si ha finalizado el juego
bool Game::checkEndGame() {
const bool isOnTheRoom = room_->getName() == "THE JAIL"; // Estar en la habitación que toca
const bool haveTheItems = board_->items >= int(total_items_ * 0.9f) || Options::cheats.jail_is_open == Options::Cheat::State::ENABLED; // Con mas del 90% de los items recogidos
const bool isOnTheDoor = player_->getRect().x <= 128; // Y en la ubicación que toca (En la puerta)
const bool IS_ON_THE_ROOM = room_->getName() == "THE JAIL"; // Estar en la habitación que toca
const bool HAVE_THE_ITEMS = board_->items >= int(total_items_ * 0.9F) || Options::cheats.jail_is_open == Options::Cheat::State::ENABLED; // Con mas del 90% de los items recogidos
const bool IS_ON_THE_DOOR = player_->getRect().x <= 128; // Y en la ubicación que toca (En la puerta)
if (haveTheItems) {
if (HAVE_THE_ITEMS) {
board_->jail_is_open = true;
}
if (haveTheItems && isOnTheRoom && isOnTheDoor) {
if (HAVE_THE_ITEMS && IS_ON_THE_ROOM && IS_ON_THE_DOOR) {
// Comprueba los logros de completar el juego
checkEndGameCheevos();
@@ -462,21 +462,21 @@ void Game::checkRestoringJail() {
return;
}
static int counter = 0;
static int counter_ = 0;
if (!paused_) {
counter++;
counter_++;
}
// Incrementa el numero de vidas
if (counter == 100) {
counter = 0;
if (counter_ == 100) {
counter_ = 0;
board_->lives++;
JA_PlaySound(Resource::get()->getSound("death.wav"));
// Invalida el logro de completar el juego sin entrar a la jail
const bool haveTheItems = board_->items >= int(total_items_ * 0.9f);
if (!haveTheItems) {
const bool HAVE_THE_ITEMS = board_->items >= int(total_items_ * 0.9F);
if (!HAVE_THE_ITEMS) {
Cheevos::get()->setUnobtainable(9);
}
}
@@ -512,7 +512,7 @@ void Game::fillRoomNameTexture() {
// Comprueba algunos logros
void Game::checkSomeCheevos() {
auto cheevos = Cheevos::get();
auto* cheevos = Cheevos::get();
// Logros sobre la cantidad de items
if (board_->items == total_items_) {
@@ -520,14 +520,14 @@ void Game::checkSomeCheevos() {
cheevos->unlock(3);
cheevos->unlock(2);
cheevos->unlock(1);
} else if (board_->items >= total_items_ * 0.75f) {
} else if (board_->items >= total_items_ * 0.75F) {
cheevos->unlock(3);
cheevos->unlock(2);
cheevos->unlock(1);
} else if (board_->items >= total_items_ * 0.5f) {
} else if (board_->items >= total_items_ * 0.5F) {
cheevos->unlock(2);
cheevos->unlock(1);
} else if (board_->items >= total_items_ * 0.25f) {
} else if (board_->items >= total_items_ * 0.25F) {
cheevos->unlock(1);
}
@@ -546,7 +546,7 @@ void Game::checkSomeCheevos() {
// Comprueba los logros de completar el juego
void Game::checkEndGameCheevos() {
auto cheevos = Cheevos::get();
auto* cheevos = Cheevos::get();
// "Complete the game"
cheevos->unlock(8);
@@ -572,8 +572,8 @@ void Game::checkEndGameCheevos() {
void Game::initPlayer(const PlayerSpawn& spawn_point, std::shared_ptr<Room> room) {
std::string player_texture = Options::cheats.alternate_skin == Options::Cheat::State::ENABLED ? "player2.gif" : "player.gif";
std::string player_animations = Options::cheats.alternate_skin == Options::Cheat::State::ENABLED ? "player2.ani" : "player.ani";
const PlayerData player(spawn_point, player_texture, player_animations, room);
player_ = std::make_shared<Player>(player);
const PlayerData PLAYER(spawn_point, player_texture, player_animations, room);
player_ = std::make_shared<Player>(PLAYER);
}
// Crea la textura para poner el nombre de la habitación
@@ -587,16 +587,16 @@ void Game::createRoomNameTexture() {
// Hace sonar la música
void Game::keepMusicPlaying() {
const std::string music_path = mode_ == GameMode::GAME ? "game.ogg" : "title.ogg";
const std::string MUSIC_PATH = mode_ == GameMode::GAME ? "game.ogg" : "title.ogg";
// Si la música no está sonando
if (JA_GetMusicState() == JA_MUSIC_INVALID || JA_GetMusicState() == JA_MUSIC_STOPPED) {
JA_PlayMusic(Resource::get()->getMusic(music_path));
JA_PlayMusic(Resource::get()->getMusic(MUSIC_PATH));
}
}
// DEMO MODE: Inicializa las variables para el modo demo
void Game::DEMO_init() {
void Game::demoInit() {
if (mode_ == GameMode::DEMO) {
demo_ = DemoData(0, 400, 0, {"04.room", "54.room", "20.room", "09.room", "05.room", "11.room", "31.room", "44.room"});
current_room_ = demo_.rooms.front();
@@ -604,7 +604,7 @@ void Game::DEMO_init() {
}
// DEMO MODE: Comprueba si se ha de cambiar de habitación
void Game::DEMO_checkRoomChange() {
void Game::demoCheckRoomChange() {
if (mode_ == GameMode::DEMO) {
demo_.counter++;
if (demo_.counter == demo_.room_time) {

View File

@@ -119,7 +119,7 @@ class Game {
void updateBlackScreen();
// Dibuja la pantalla negra
void renderBlackScreen();
void renderBlackScreen() const;
// Pone el color del marcador en función del color del borde de la habitación
void setScoreBoardColor();
@@ -128,7 +128,7 @@ class Game {
bool checkEndGame();
// Obtiene la cantidad total de items que hay en el mapeado del juego
int getTotalItems();
static int getTotalItems();
// Pone el juego en pausa
void togglePause();
@@ -158,10 +158,10 @@ class Game {
void keepMusicPlaying();
// DEMO MODE: Inicializa las variables para el modo demo
void DEMO_init();
void demoInit();
// DEMO MODE: Comprueba si se ha de cambiar de habitación
void DEMO_checkRoomChange();
void demoCheckRoomChange();
public:
// Constructor

View File

@@ -102,13 +102,13 @@ void GameOver::render() {
void GameOver::checkEvents() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
globalEvents::check(event);
GlobalEvents::check(event);
}
}
// Comprueba las entradas
void GameOver::checkInput() {
globalInputs::check();
GlobalInputs::check();
}
// Bucle principal
@@ -122,14 +122,14 @@ void GameOver::run() {
// Actualiza el color usado para renderizar los textos e imagenes
void GameOver::updateColor() {
const int half = COUNTER_SECTION_END_ / 2;
const int HALF = COUNTER_SECTION_END / 2;
if (counter_ < half) {
const float STEP = std::min(counter_, COUNTER_FADE_LENGHT_) / (float)COUNTER_FADE_LENGHT_;
if (counter_ < HALF) {
const float STEP = std::min(counter_, COUNTER_FADE_LENGHT) / (float)COUNTER_FADE_LENGHT;
const int INDEX = (colors_.size() - 1) - int((colors_.size() - 1) * STEP);
color_ = colors_[INDEX];
} else {
const float STEP = std::min(std::max(counter_, COUNTER_INIT_FADE_) - COUNTER_INIT_FADE_, COUNTER_FADE_LENGHT_) / (float)COUNTER_FADE_LENGHT_;
const float STEP = std::min(std::max(counter_, COUNTER_INIT_FADE) - COUNTER_INIT_FADE, COUNTER_FADE_LENGHT) / (float)COUNTER_FADE_LENGHT;
const int INDEX = (colors_.size() - 1) * STEP;
color_ = colors_[INDEX];
}
@@ -156,7 +156,7 @@ void GameOver::updateCounters() {
}
// Comprueba si ha terminado la sección
else if (counter_ == COUNTER_SECTION_END_) {
else if (counter_ == COUNTER_SECTION_END) {
SceneManager::current = SceneManager::Scene::LOGO;
SceneManager::options = SceneManager::Options::LOGO_TO_TITLE;
}

View File

@@ -9,9 +9,9 @@ class SurfaceAnimatedSprite; // lines 7-7
class GameOver {
private:
// Constantes
static constexpr int COUNTER_SECTION_END_ = 400; // Contador: cuando acaba la sección
static constexpr int COUNTER_INIT_FADE_ = 310; // Contador: cuando emiepza el fade
static constexpr int COUNTER_FADE_LENGHT_ = 20; // Contador: duración del fade
static constexpr int COUNTER_SECTION_END = 400; // Contador: cuando acaba la sección
static constexpr int COUNTER_INIT_FADE = 310; // Contador: cuando emiepza el fade
static constexpr int COUNTER_FADE_LENGHT = 20; // Contador: duración del fade
// Objetos y punteros
std::shared_ptr<SurfaceAnimatedSprite> player_sprite_; // Sprite con el jugador
@@ -31,10 +31,10 @@ class GameOver {
void render();
// Comprueba el manejador de eventos
void checkEvents();
static void checkEvents();
// Comprueba las entradas
void checkInput();
static void checkInput();
// Actualiza el color usado para renderizar los textos e imagenes
void updateColor();

View File

@@ -24,9 +24,9 @@ LoadingScreen::LoadingScreen()
screen_surface_(std::make_shared<Surface>(Options::game.width, Options::game.height)),
delta_timer_(std::make_unique<DeltaTimer>()),
state_(LoadingState::SILENT1),
state_time_(0.0f),
state_time_(0.0F),
current_border_type_(BorderType::NONE),
load_rect_{0, 0, 0, 1.0f} {
load_rect_{0, 0, 0, 1.0F} {
// Configura la superficie donde se van a pintar los sprites
screen_surface_->clear(static_cast<Uint8>(PaletteColor::WHITE));
@@ -51,13 +51,13 @@ LoadingScreen::~LoadingScreen() {
void LoadingScreen::checkEvents() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
globalEvents::check(event);
GlobalEvents::check(event);
}
}
// Comprueba las entradas
void LoadingScreen::checkInput() {
globalInputs::check();
GlobalInputs::check();
}
// Inicializa el array de índices de líneas (imita el direccionamiento de memoria del Spectrum)
@@ -76,7 +76,7 @@ void LoadingScreen::initLineIndexArray() {
// Transiciona a un nuevo estado
void LoadingScreen::transitionToState(LoadingState new_state) {
state_ = new_state;
state_time_ = 0.0f;
state_time_ = 0.0F;
// Acciones específicas al entrar en cada estado
switch (new_state) {
@@ -172,31 +172,31 @@ void LoadingScreen::updateState(float delta_time) {
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);
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<int>(progress * total_steps);
const int TOTAL_STEPS = MONO_TOTAL_LINES * MONO_STEPS_PER_LINE; // 192 * 5 = 960
const int CURRENT_STEP = static_cast<int>(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
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) {
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<float>(mono_loading_screen_surface_->getWidth());
const float clip_width = texture_width / MONO_STEPS_PER_LINE;
const float clip_x = current_substep * clip_width;
const float TEXTURE_WIDTH = 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<float>(line_index_[current_line]);
load_rect_.w = clip_width;
load_rect_.h = 1.0f;
load_rect_.x = CLIP_X;
load_rect_.y = static_cast<float>(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_);
@@ -212,24 +212,24 @@ void LoadingScreen::updateMonoLoad(float delta_time) {
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);
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<int>(progress * total_iterations);
const int TOTAL_ITERATIONS = COLOR_TOTAL_BLOCKS / 2; // 768 / 2 = 384 iteraciones
const int CURRENT_ITERATION = static_cast<int>(progress * TOTAL_ITERATIONS);
// Convertir a bloque (incrementa de 2 en 2, empezando en 0)
const int current_block = current_iteration * 2;
const int CURRENT_BLOCK = CURRENT_ITERATION * 2;
// Verificar si ha completado todos los bloques
if (current_block >= COLOR_TOTAL_BLOCKS) {
if (CURRENT_BLOCK >= COLOR_TOTAL_BLOCKS) {
transitionToState(LoadingState::BYTES2);
return;
}
// Calcular posición del bloque
load_rect_.x = static_cast<float>((current_block * COLOR_BLOCK_SPACING) % 256);
load_rect_.y = static_cast<float>((current_block / COLOR_BLOCKS_PER_ROW) * COLOR_BLOCK_SPACING);
load_rect_.x = static_cast<float>((CURRENT_BLOCK * COLOR_BLOCK_SPACING) % 256);
load_rect_.y = static_cast<float>((CURRENT_BLOCK / COLOR_BLOCKS_PER_ROW) * COLOR_BLOCK_SPACING);
load_rect_.w = static_cast<float>(COLOR_BLOCK_WIDTH);
load_rect_.h = static_cast<float>(COLOR_BLOCK_HEIGHT);
@@ -255,7 +255,7 @@ void LoadingScreen::renderYellowBorder() {
const Uint8 COLOR = static_cast<Uint8>(PaletteColor::YELLOW);
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 = rand() % 2 == 0 ? true : false;
bool draw_enabled = rand() % 2 == 0;
int row = 0;
while (row < HEIGHT) {
@@ -320,10 +320,10 @@ void LoadingScreen::renderWhiteBorder() {
// Actualiza las variables
void LoadingScreen::update() {
// Obtener delta time desde el último frame
const float delta_time = delta_timer_->tick();
const float DELTA_TIME = delta_timer_->tick();
checkInput(); // Comprueba las entradas
updateState(delta_time); // Actualiza el estado y gestiona transiciones
updateState(DELTA_TIME); // Actualiza el estado y gestiona transiciones
// Actualizar la carga según el estado actual
switch (state_) {
@@ -338,11 +338,11 @@ void LoadingScreen::update() {
break;
case LoadingState::LOADING_MONO:
updateMonoLoad(delta_time);
updateMonoLoad(DELTA_TIME);
break;
case LoadingState::LOADING_COLOR:
updateColorLoad(delta_time);
updateColorLoad(DELTA_TIME);
break;
case LoadingState::COMPLETE:

View File

@@ -38,14 +38,14 @@ class LoadingScreen {
private:
// --- Constantes de tiempo (en segundos) ---
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
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
@@ -74,15 +74,15 @@ class LoadingScreen {
// --- Funciones ---
void update(); // Actualiza las variables
void render(); // Dibuja en pantalla
void checkEvents(); // Comprueba el manejador de eventos
void checkInput(); // Comprueba las entradas
static void checkEvents(); // Comprueba el manejador de eventos
static 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 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
static void renderYellowBorder(); // Dibuja el efecto de carga amarillo y azul en el borde
static void renderRedBorder(); // Dibuja el efecto de carga rojo y azul en el borde
static void renderWhiteBorder(); // Dibuja el borde de color blanco
void initLineIndexArray(); // Inicializa el array de índices de líneas
};

View File

@@ -22,7 +22,7 @@ Logo::Logo()
since_1998_sprite_(std::make_shared<SurfaceSprite>(since_1998_surface_, (256 - since_1998_surface_->getWidth()) / 2, 83 + jailgames_surface_->getHeight() + 5, since_1998_surface_->getWidth(), since_1998_surface_->getHeight())),
delta_timer_(std::make_unique<DeltaTimer>()),
state_(LogoState::INITIAL),
state_time_(0.0f) {
state_time_(0.0F) {
// Configura variables
since_1998_sprite_->setClip(0, 0, since_1998_surface_->getWidth(), since_1998_surface_->getHeight());
since_1998_color_ = static_cast<Uint8>(PaletteColor::BLACK);
@@ -42,13 +42,13 @@ Logo::Logo()
void Logo::checkEvents() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
globalEvents::check(event);
GlobalEvents::check(event);
}
}
// Comprueba las entradas
void Logo::checkInput() {
globalInputs::check();
GlobalInputs::check();
}
// Gestiona el logo de JAILGAME (time-based)
@@ -59,24 +59,24 @@ void Logo::updateJAILGAMES(float delta_time) {
}
// Calcular el desplazamiento basado en velocidad y delta time
const float displacement = JAILGAMES_SLIDE_SPEED * delta_time;
const float DISPLACEMENT = JAILGAMES_SLIDE_SPEED * delta_time;
// Actualizar cada línea del sprite JAILGAMES
for (size_t i = 1; i < jailgames_sprite_.size(); ++i) {
const int current_x = jailgames_sprite_[i]->getX();
const int CURRENT_X = jailgames_sprite_[i]->getX();
// Las líneas pares se mueven desde la derecha, las impares desde la izquierda
if (i % 2 == 0) {
// Mover hacia la izquierda
if (current_x > JAILGAMES_DEST_X) {
const int new_x = static_cast<int>(current_x - displacement);
jailgames_sprite_[i]->setX(new_x < JAILGAMES_DEST_X ? JAILGAMES_DEST_X : new_x);
if (CURRENT_X > JAILGAMES_DEST_X) {
const int NEW_X = static_cast<int>(CURRENT_X - DISPLACEMENT);
jailgames_sprite_[i]->setX(NEW_X < JAILGAMES_DEST_X ? JAILGAMES_DEST_X : NEW_X);
}
} else {
// Mover hacia la derecha
if (current_x < JAILGAMES_DEST_X) {
const int new_x = static_cast<int>(current_x + displacement);
jailgames_sprite_[i]->setX(new_x > JAILGAMES_DEST_X ? JAILGAMES_DEST_X : new_x);
if (CURRENT_X < JAILGAMES_DEST_X) {
const int NEW_X = static_cast<int>(CURRENT_X + DISPLACEMENT);
jailgames_sprite_[i]->setX(NEW_X > JAILGAMES_DEST_X ? JAILGAMES_DEST_X : NEW_X);
}
}
}
@@ -85,13 +85,13 @@ void Logo::updateJAILGAMES(float delta_time) {
// Calcula el índice de color según el progreso (0.0-1.0)
int Logo::getColorIndex(float progress) const {
// Asegurar que progress esté en el rango [0.0, 1.0]
progress = std::clamp(progress, 0.0f, 1.0f);
progress = std::clamp(progress, 0.0F, 1.0F);
// Mapear el progreso al índice de color (0-7)
const int max_index = static_cast<int>(color_.size()) - 1;
const int index = static_cast<int>(progress * max_index);
const int MAX_INDEX = static_cast<int>(color_.size()) - 1;
const int INDEX = static_cast<int>(progress * MAX_INDEX);
return index;
return INDEX;
}
// Gestiona el color de las texturas
@@ -99,8 +99,8 @@ void Logo::updateTextureColors() {
switch (state_) {
case LogoState::SINCE_1998_FADE_IN: {
// Fade-in de "Since 1998" de negro a blanco
const float progress = state_time_ / SINCE_1998_FADE_DURATION;
since_1998_color_ = color_[getColorIndex(progress)];
const float PROGRESS = state_time_ / SINCE_1998_FADE_DURATION;
since_1998_color_ = color_[getColorIndex(PROGRESS)];
break;
}
@@ -113,10 +113,10 @@ void Logo::updateTextureColors() {
case LogoState::FADE_OUT: {
// Fade-out de ambos logos de blanco a negro
const float progress = 1.0f - (state_time_ / FADE_OUT_DURATION);
const int color_index = getColorIndex(progress);
jailgames_color_ = color_[color_index];
since_1998_color_ = color_[color_index];
const float PROGRESS = 1.0F - (state_time_ / FADE_OUT_DURATION);
const int COLOR_INDEX = getColorIndex(PROGRESS);
jailgames_color_ = color_[COLOR_INDEX];
since_1998_color_ = color_[COLOR_INDEX];
break;
}
@@ -129,7 +129,7 @@ void Logo::updateTextureColors() {
// Transiciona a un nuevo estado
void Logo::transitionToState(LogoState new_state) {
state_ = new_state;
state_time_ = 0.0f;
state_time_ = 0.0F;
}
// Actualiza el estado actual
@@ -178,11 +178,11 @@ void Logo::updateState(float delta_time) {
// Actualiza las variables
void Logo::update() {
// Obtener delta time desde el último frame
const float delta_time = delta_timer_->tick();
const float DELTA_TIME = delta_timer_->tick();
checkInput(); // Comprueba las entradas
updateState(delta_time); // Actualiza el estado y gestiona transiciones
updateJAILGAMES(delta_time); // Gestiona el logo de JAILGAME
updateState(DELTA_TIME); // Actualiza el estado y gestiona transiciones
updateJAILGAMES(DELTA_TIME); // Gestiona el logo de JAILGAME
updateTextureColors(); // Gestiona el color de las texturas
Screen::get()->update(); // Actualiza el objeto Screen
}

View File

@@ -27,14 +27,14 @@ 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)
static constexpr float JAILGAMES_SLIDE_SPEED = 800.0F; // Velocidad de slide-in (pixels/segundo)
static constexpr int JAILGAMES_DEST_X = 37; // Posición X de destino para JAILGAMES
// --- Objetos y punteros ---
@@ -54,14 +54,14 @@ class Logo {
// --- Funciones ---
void update(); // Actualiza las variables
void render(); // Dibuja en pantalla
void checkEvents(); // Comprueba el manejador de eventos
void checkInput(); // Comprueba las entradas
static void checkEvents(); // Comprueba el manejador de eventos
static 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
static void endSection(); // Termina la sección
void initColors(); // Inicializa el vector de colores
void initSprites(); // Crea los sprites de cada linea
};

View File

@@ -29,9 +29,9 @@ Title::Title()
marquee_text_(Resource::get()->getText("gauntlet")),
first_active_letter_(0),
last_active_letter_(0),
state_time_(0.0f),
fade_accumulator_(0.0f),
current_delta_(0.0f) {
state_time_(0.0F),
fade_accumulator_(0.0F),
current_delta_(0.0F) {
// Inicializa variables
state_ = SceneManager::options == SceneManager::Options::TITLE_WITH_LOADING_SCREEN ? TitleState::SHOW_LOADING_SCREEN : TitleState::SHOW_MENU;
SceneManager::current = SceneManager::Scene::TITLE;
@@ -75,7 +75,7 @@ void Title::initMarquee() {
void Title::checkEvents() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
globalEvents::check(event);
GlobalEvents::check(event);
// Solo se comprueban estas teclas si no está activo el menu de logros
if (event.type == SDL_EVENT_KEY_DOWN) {
@@ -116,19 +116,19 @@ void Title::checkInput() {
}
}
globalInputs::check();
GlobalInputs::check();
}
// Actualiza la marquesina
void Title::updateMarquee(float delta_time) {
const float displacement = MARQUEE_SPEED * 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;
letter.x -= DISPLACEMENT;
// Desactivar si sale de pantalla
if (letter.x < MARQUEE_EXIT_X) {
@@ -196,7 +196,7 @@ void Title::updateState(float delta_time) {
case TitleState::FADE_LOADING_SCREEN:
fade_accumulator_ += delta_time;
if (fade_accumulator_ >= FADE_STEP_INTERVAL) {
fade_accumulator_ = 0.0f;
fade_accumulator_ = 0.0F;
if (loading_screen_surface_->fadeSubPalette()) {
transitionToState(TitleState::SHOW_MENU);
}
@@ -222,8 +222,8 @@ void Title::updateState(float delta_time) {
// Transiciona a un nuevo estado
void Title::transitionToState(TitleState new_state) {
state_ = new_state;
state_time_ = 0.0f;
fade_accumulator_ = 0.0f;
state_time_ = 0.0F;
fade_accumulator_ = 0.0F;
}
// Dibuja en pantalla
@@ -272,12 +272,12 @@ void Title::run() {
// Desplaza la lista de logros
void Title::moveCheevosList(int direction, float delta_time) {
// Calcula el desplazamiento basado en tiempo
const float displacement = CHEEVOS_SCROLL_SPEED * delta_time;
const float DISPLACEMENT = CHEEVOS_SCROLL_SPEED * delta_time;
// Modifica la posición de la ventana de vista
cheevos_surface_view_.y = direction == 0
? cheevos_surface_view_.y - displacement
: cheevos_surface_view_.y + displacement;
? cheevos_surface_view_.y - DISPLACEMENT
: cheevos_surface_view_.y + DISPLACEMENT;
// Ajusta los limites
const float BOTTOM = cheevos_surface_->getHeight() - cheevos_surface_view_.h;

View File

@@ -27,17 +27,17 @@ class Title {
};
// --- Constantes de tiempo (en segundos) ---
static constexpr float SHOW_LOADING_DURATION = 5.0f; // Tiempo mostrando loading screen (antes 500 frames)
static constexpr float FADE_STEP_INTERVAL = 0.033f; // Intervalo entre pasos de fade (antes cada 4 frames)
static constexpr float AUTO_CREDITS_TIMEOUT = 22.0f; // Timeout para ir a créditos (antes 2200 frames)
static constexpr float MARQUEE_SPEED = 100.0f; // Velocidad de marquesina (pixels/segundo)
static constexpr float CHEEVOS_SCROLL_SPEED = 120.0f; // Velocidad de scroll de logros (pixels/segundo)
static constexpr float SHOW_LOADING_DURATION = 5.0F; // Tiempo mostrando loading screen (antes 500 frames)
static constexpr float FADE_STEP_INTERVAL = 0.033F; // Intervalo entre pasos de fade (antes cada 4 frames)
static constexpr float AUTO_CREDITS_TIMEOUT = 22.0F; // Timeout para ir a créditos (antes 2200 frames)
static constexpr float MARQUEE_SPEED = 100.0F; // Velocidad de marquesina (pixels/segundo)
static constexpr float CHEEVOS_SCROLL_SPEED = 120.0F; // Velocidad de scroll de logros (pixels/segundo)
// --- Constantes de marquesina ---
static constexpr float MARQUEE_START_X = 256.0f; // Posición inicial (ancho pantalla)
static constexpr float MARQUEE_EXIT_X = -10.0f; // Cuando desaparece de pantalla
static constexpr float MARQUEE_Y = 184.0f; // Posición Y
static constexpr float MARQUEE_LETTER_SPACING = 1.0f; // Espaciado entre letras
static constexpr float MARQUEE_START_X = 256.0F; // Posición inicial (ancho pantalla)
static constexpr float MARQUEE_EXIT_X = -10.0F; // Cuando desaparece de pantalla
static constexpr float MARQUEE_Y = 184.0F; // Posición Y
static constexpr float MARQUEE_LETTER_SPACING = 1.0F; // Espaciado entre letras
// Objetos y punteros
std::shared_ptr<Surface> title_logo_surface_; // Textura con los graficos