This commit is contained in:
2025-11-03 09:52:54 +01:00
parent 1409ab5bff
commit 3f1c737247
32 changed files with 254 additions and 243 deletions

View File

@@ -16,6 +16,7 @@ Checks:
- -performance-inefficient-string-concatenation - -performance-inefficient-string-concatenation
- -bugprone-integer-division - -bugprone-integer-division
- -bugprone-easily-swappable-parameters - -bugprone-easily-swappable-parameters
- -modernize-avoid-c-arrays,-warnings-as-errors
WarningsAsErrors: '*' WarningsAsErrors: '*'
# Solo incluir archivos de tu código fuente # Solo incluir archivos de tu código fuente

View File

@@ -106,7 +106,7 @@ void handleShowDebugInfo() {
} }
// Detecta qué acción global ha sido presionada (si alguna) // Detecta qué acción global ha sido presionada (si alguna)
InputAction getPressedAction() { auto getPressedAction() -> InputAction {
if (Input::get()->checkAction(InputAction::EXIT, Input::DO_NOT_ALLOW_REPEAT)) { if (Input::get()->checkAction(InputAction::EXIT, Input::DO_NOT_ALLOW_REPEAT)) {
return InputAction::EXIT; return InputAction::EXIT;
} }

View File

@@ -395,7 +395,7 @@ auto Screen::getBorderSurface() -> std::shared_ptr<Surface> { return border_surf
auto loadData(const std::string& filepath) -> std::vector<uint8_t> { auto loadData(const std::string& filepath) -> std::vector<uint8_t> {
// Load using ResourceHelper (supports both filesystem and pack) // Load using ResourceHelper (supports both filesystem and pack)
return jdd::ResourceHelper::loadFile(filepath); return Jdd::ResourceHelper::loadFile(filepath);
} }
// Carga el contenido de los archivos GLSL // Carga el contenido de los archivos GLSL

View File

@@ -21,7 +21,7 @@
// Carga una paleta desde un archivo .gif // Carga una paleta desde un archivo .gif
auto loadPalette(const std::string& file_path) -> Palette { auto loadPalette(const std::string& file_path) -> Palette {
// Load file using ResourceHelper (supports both filesystem and pack) // Load file using ResourceHelper (supports both filesystem and pack)
auto buffer = jdd::ResourceHelper::loadFile(file_path); auto buffer = Jdd::ResourceHelper::loadFile(file_path);
if (buffer.empty()) { if (buffer.empty()) {
throw std::runtime_error("Error opening file: " + file_path); throw std::runtime_error("Error opening file: " + file_path);
} }
@@ -48,7 +48,7 @@ auto readPalFile(const std::string& file_path) -> Palette {
palette.fill(0); // Inicializar todo con 0 (transparente por defecto) palette.fill(0); // Inicializar todo con 0 (transparente por defecto)
// Load file using ResourceHelper (supports both filesystem and pack) // Load file using ResourceHelper (supports both filesystem and pack)
auto file_data = jdd::ResourceHelper::loadFile(file_path); auto file_data = Jdd::ResourceHelper::loadFile(file_path);
if (file_data.empty()) { if (file_data.empty()) {
throw std::runtime_error("No se pudo abrir el archivo .pal: " + file_path); throw std::runtime_error("No se pudo abrir el archivo .pal: " + file_path);
} }
@@ -106,7 +106,7 @@ Surface::Surface(const std::string& file_path)
// Carga una superficie desde un archivo // Carga una superficie desde un archivo
auto Surface::loadSurface(const std::string& file_path) -> SurfaceData { auto Surface::loadSurface(const std::string& file_path) -> SurfaceData {
// Load file using ResourceHelper (supports both filesystem and pack) // Load file using ResourceHelper (supports both filesystem and pack)
std::vector<Uint8> buffer = jdd::ResourceHelper::loadFile(file_path); std::vector<Uint8> buffer = Jdd::ResourceHelper::loadFile(file_path);
if (buffer.empty()) { if (buffer.empty()) {
std::cerr << "Error opening file: " << file_path << '\n'; std::cerr << "Error opening file: " << file_path << '\n';
throw std::runtime_error("Error opening file"); throw std::runtime_error("Error opening file");

View File

@@ -15,7 +15,7 @@
// Carga las animaciones en un vector(Animations) desde un fichero // Carga las animaciones en un vector(Animations) desde un fichero
auto loadAnimationsFromFile(const std::string& file_path) -> Animations { auto loadAnimationsFromFile(const std::string& file_path) -> Animations {
// Load file using ResourceHelper (supports both filesystem and pack) // Load file using ResourceHelper (supports both filesystem and pack)
auto file_data = jdd::ResourceHelper::loadFile(file_path); auto file_data = Jdd::ResourceHelper::loadFile(file_path);
if (file_data.empty()) { if (file_data.empty()) {
std::cerr << "Error: Fichero no encontrado " << file_path << '\n'; std::cerr << "Error: Fichero no encontrado " << file_path << '\n';
throw std::runtime_error("Fichero no encontrado: " + file_path); throw std::runtime_error("Fichero no encontrado: " + file_path);
@@ -43,8 +43,7 @@ auto loadAnimationsFromFile(const std::string& file_path) -> Animations {
} }
// Constructor // Constructor
SurfaceAnimatedSprite::SurfaceAnimatedSprite(const std::string& file_path) SurfaceAnimatedSprite::SurfaceAnimatedSprite(const std::string& file_path) {
: SurfaceMovingSprite() {
// Carga las animaciones // Carga las animaciones
if (!file_path.empty()) { if (!file_path.empty()) {
Animations v = loadAnimationsFromFile(file_path); Animations v = loadAnimationsFromFile(file_path);
@@ -53,8 +52,7 @@ SurfaceAnimatedSprite::SurfaceAnimatedSprite(const std::string& file_path)
} }
// Constructor // Constructor
SurfaceAnimatedSprite::SurfaceAnimatedSprite(const Animations& animations) SurfaceAnimatedSprite::SurfaceAnimatedSprite(const Animations& animations) {
: SurfaceMovingSprite() {
if (!animations.empty()) { if (!animations.empty()) {
setAnimations(animations); setAnimations(animations);
} }

View File

@@ -18,8 +18,7 @@ SurfaceMovingSprite::SurfaceMovingSprite(std::shared_ptr<Surface> surface, SDL_F
flip_(SDL_FLIP_NONE) { SurfaceSprite::pos_ = pos; } flip_(SDL_FLIP_NONE) { SurfaceSprite::pos_ = pos; }
SurfaceMovingSprite::SurfaceMovingSprite() SurfaceMovingSprite::SurfaceMovingSprite()
: SurfaceSprite(), : x_(0.0F),
x_(0.0F),
y_(0.0F), y_(0.0F),
flip_(SDL_FLIP_NONE) { SurfaceSprite::clear(); } flip_(SDL_FLIP_NONE) { SurfaceSprite::clear(); }

View File

@@ -28,7 +28,7 @@ auto loadTextFile(const std::string& file_path) -> std::shared_ptr<TextFile> {
} }
// Load file using ResourceHelper (supports both filesystem and pack) // Load file using ResourceHelper (supports both filesystem and pack)
auto file_data = jdd::ResourceHelper::loadFile(file_path); auto file_data = Jdd::ResourceHelper::loadFile(file_path);
if (file_data.empty()) { if (file_data.empty()) {
std::cerr << "Error: Fichero no encontrado " << getFileName(file_path) << '\n'; std::cerr << "Error: Fichero no encontrado " << getFileName(file_path) << '\n';
throw std::runtime_error("Fichero no encontrado: " + getFileName(file_path)); throw std::runtime_error("Fichero no encontrado: " + getFileName(file_path));

View File

@@ -223,7 +223,7 @@ auto Asset::check() const -> bool {
} }
// Comprueba que existe un fichero // Comprueba que existe un fichero
auto Asset::checkFile(const std::string& path) const -> bool { auto Asset::checkFile(const std::string& path) -> bool {
std::ifstream file(path); std::ifstream file(path);
bool success = file.good(); bool success = file.good();
file.close(); file.close();

View File

@@ -58,7 +58,7 @@ class Asset {
std::string executable_path_; // Ruta del ejecutable std::string executable_path_; // Ruta del ejecutable
// --- Métodos internos --- // --- Métodos internos ---
[[nodiscard]] auto checkFile(const std::string& path) const -> bool; // Verifica si un archivo existe [[nodiscard]] static auto checkFile(const std::string& path) -> bool; // Verifica si un archivo existe
[[nodiscard]] static auto getTypeName(Type type) -> std::string; // Obtiene el nombre del tipo [[nodiscard]] static auto getTypeName(Type type) -> std::string; // Obtiene el nombre del tipo
[[nodiscard]] static auto parseAssetType(const std::string& type_str) -> Type; // Convierte string a tipo [[nodiscard]] static auto parseAssetType(const std::string& type_str) -> Type; // Convierte string a tipo
void addToMap(const std::string& file_path, Type type, bool required, bool absolute); // Añade archivo al mapa void addToMap(const std::string& file_path, Type type, bool required, bool absolute); // Añade archivo al mapa

View File

@@ -198,7 +198,7 @@ void Resource::loadSounds() {
JA_Sound_t* sound = nullptr; JA_Sound_t* sound = nullptr;
// Try loading from resource pack first // Try loading from resource pack first
auto audio_data = jdd::ResourceHelper::loadFile(l); auto audio_data = Jdd::ResourceHelper::loadFile(l);
if (!audio_data.empty()) { if (!audio_data.empty()) {
sound = JA_LoadSound(audio_data.data(), static_cast<Uint32>(audio_data.size())); sound = JA_LoadSound(audio_data.data(), static_cast<Uint32>(audio_data.size()));
} }
@@ -225,7 +225,7 @@ void Resource::loadMusics() {
JA_Music_t* music = nullptr; JA_Music_t* music = nullptr;
// Try loading from resource pack first // Try loading from resource pack first
auto audio_data = jdd::ResourceHelper::loadFile(l); auto audio_data = Jdd::ResourceHelper::loadFile(l);
if (!audio_data.empty()) { if (!audio_data.empty()) {
music = JA_LoadMusic(audio_data.data(), static_cast<Uint32>(audio_data.size())); music = JA_LoadMusic(audio_data.data(), static_cast<Uint32>(audio_data.size()));
} }
@@ -415,8 +415,8 @@ void Resource::renderProgress() {
Screen::get()->clearSurface(static_cast<Uint8>(PaletteColor::BLACK)); Screen::get()->clearSurface(static_cast<Uint8>(PaletteColor::BLACK));
auto surface = Screen::get()->getRendererSurface(); auto surface = Screen::get()->getRendererSurface();
const Uint8 TEXT_COLOR = static_cast<Uint8>(PaletteColor::BRIGHT_WHITE); const auto TEXT_COLOR = static_cast<Uint8>(PaletteColor::BRIGHT_WHITE);
const Uint8 BAR_COLOR = static_cast<Uint8>(PaletteColor::WHITE); const auto BAR_COLOR = static_cast<Uint8>(PaletteColor::WHITE);
const int TEXT_HEIGHT = loading_text_->getCharacterSize(); const int TEXT_HEIGHT = loading_text_->getCharacterSize();
const int CENTER_X = Options::game.width / 2; const int CENTER_X = Options::game.width / 2;
const int CENTER_Y = Options::game.height / 2; const int CENTER_Y = Options::game.height / 2;

View File

@@ -10,7 +10,7 @@
#include "resource_loader.hpp" #include "resource_loader.hpp"
namespace jdd { namespace Jdd {
namespace ResourceHelper { namespace ResourceHelper {
static bool resource_system_initialized = false; static bool resource_system_initialized = false;
@@ -175,4 +175,4 @@ auto isPackLoaded() -> bool {
} }
} // namespace ResourceHelper } // namespace ResourceHelper
} // namespace jdd } // namespace Jdd

View File

@@ -8,7 +8,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
namespace jdd { namespace Jdd {
namespace ResourceHelper { namespace ResourceHelper {
// Initialize the resource system // Initialize the resource system
@@ -38,6 +38,6 @@ auto shouldUseResourcePack(const std::string& filepath) -> bool;
auto isPackLoaded() -> bool; auto isPackLoaded() -> bool;
} // namespace ResourceHelper } // namespace ResourceHelper
} // namespace jdd } // namespace Jdd
#endif // RESOURCE_HELPER_HPP #endif // RESOURCE_HELPER_HPP

View File

@@ -7,7 +7,7 @@
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
namespace jdd { namespace Jdd {
// Get singleton instance // Get singleton instance
auto ResourceLoader::get() -> ResourceLoader& { auto ResourceLoader::get() -> ResourceLoader& {
@@ -196,4 +196,4 @@ auto ResourceLoader::loadAssetsConfig() const -> std::string {
return config_content; return config_content;
} }
} // namespace jdd } // namespace Jdd

View File

@@ -10,7 +10,7 @@
#include "resource_pack.hpp" #include "resource_pack.hpp"
namespace jdd { namespace Jdd {
// Singleton class for loading resources from pack or filesystem // Singleton class for loading resources from pack or filesystem
class ResourceLoader { class ResourceLoader {
@@ -64,6 +64,6 @@ class ResourceLoader {
bool initialized_{false}; bool initialized_{false};
}; };
} // namespace jdd } // namespace Jdd
#endif // RESOURCE_LOADER_HPP #endif // RESOURCE_LOADER_HPP

View File

@@ -10,7 +10,7 @@
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
namespace jdd { namespace Jdd {
// Calculate CRC32 checksum for data verification // Calculate CRC32 checksum for data verification
auto ResourcePack::calculateChecksum(const std::vector<uint8_t>& data) -> uint32_t { auto ResourcePack::calculateChecksum(const std::vector<uint8_t>& data) -> uint32_t {
@@ -100,7 +100,7 @@ auto ResourcePack::addDirectory(const std::string& dir_path,
std::string relative_path = entry.path().lexically_relative(dir_path).string(); std::string relative_path = entry.path().lexically_relative(dir_path).string();
// Convert backslashes to forward slashes (Windows compatibility) // Convert backslashes to forward slashes (Windows compatibility)
std::replace(relative_path.begin(), relative_path.end(), '\\', '/'); std::ranges::replace(relative_path, '\\', '/');
// Skip development files // Skip development files
if (relative_path.find(".world") != std::string::npos || if (relative_path.find(".world") != std::string::npos ||
@@ -129,13 +129,13 @@ auto ResourcePack::savePack(const std::string& pack_file) -> bool {
file.write(reinterpret_cast<const char*>(&VERSION), sizeof(VERSION)); file.write(reinterpret_cast<const char*>(&VERSION), sizeof(VERSION));
// Write resource count // Write resource count
uint32_t resource_count = static_cast<uint32_t>(resources_.size()); auto resource_count = static_cast<uint32_t>(resources_.size());
file.write(reinterpret_cast<const char*>(&resource_count), sizeof(resource_count)); file.write(reinterpret_cast<const char*>(&resource_count), sizeof(resource_count));
// Write resource entries // Write resource entries
for (const auto& [name, entry] : resources_) { for (const auto& [name, entry] : resources_) {
// Write filename length and name // Write filename length and name
uint32_t name_len = static_cast<uint32_t>(entry.filename.length()); auto name_len = static_cast<uint32_t>(entry.filename.length());
file.write(reinterpret_cast<const char*>(&name_len), sizeof(name_len)); file.write(reinterpret_cast<const char*>(&name_len), sizeof(name_len));
file.write(entry.filename.c_str(), name_len); file.write(entry.filename.c_str(), name_len);
@@ -269,7 +269,7 @@ auto ResourcePack::getResourceList() const -> std::vector<std::string> {
for (const auto& [name, entry] : resources_) { for (const auto& [name, entry] : resources_) {
list.push_back(name); list.push_back(name);
} }
std::sort(list.begin(), list.end()); std::ranges::sort(list);
return list; return list;
} }
@@ -288,7 +288,7 @@ auto ResourcePack::calculatePackChecksum() const -> uint32_t {
for (const auto& [name, entry] : resources_) { for (const auto& [name, entry] : resources_) {
sorted_names.push_back(name); sorted_names.push_back(name);
} }
std::sort(sorted_names.begin(), sorted_names.end()); std::ranges::sort(sorted_names);
// Combine individual checksums // Combine individual checksums
for (const auto& name : sorted_names) { for (const auto& name : sorted_names) {
@@ -300,4 +300,4 @@ auto ResourcePack::calculatePackChecksum() const -> uint32_t {
return global_checksum; return global_checksum;
} }
} // namespace jdd } // namespace Jdd

View File

@@ -11,7 +11,7 @@
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
namespace jdd { namespace Jdd {
// Entry metadata for each resource in the pack // Entry metadata for each resource in the pack
struct ResourceEntry { struct ResourceEntry {
@@ -32,9 +32,9 @@ class ResourcePack {
// Disable copy/move // Disable copy/move
ResourcePack(const ResourcePack&) = delete; ResourcePack(const ResourcePack&) = delete;
ResourcePack& operator=(const ResourcePack&) = delete; auto operator=(const ResourcePack&) -> ResourcePack& = delete;
ResourcePack(ResourcePack&&) = delete; ResourcePack(ResourcePack&&) = delete;
ResourcePack& operator=(ResourcePack&&) = delete; auto operator=(ResourcePack&&) -> ResourcePack& = delete;
// Add a single file to the pack // Add a single file to the pack
auto addFile(const std::string& filepath, const std::string& pack_name) -> bool; auto addFile(const std::string& filepath, const std::string& pack_name) -> bool;
@@ -89,6 +89,6 @@ class ResourcePack {
bool loaded_{false}; bool loaded_{false};
}; };
} // namespace jdd } // namespace Jdd
#endif // RESOURCE_PACK_HPP #endif // RESOURCE_PACK_HPP

View File

@@ -112,7 +112,7 @@ Director::Director(std::vector<std::string> const& args) {
// 3. Initialize resource pack system (optional, with fallback) // 3. Initialize resource pack system (optional, with fallback)
std::cout << "Initializing resource pack (development mode): " << pack_path << '\n'; std::cout << "Initializing resource pack (development mode): " << pack_path << '\n';
jdd::ResourceHelper::initializeResourceSystem(pack_path, true); Jdd::ResourceHelper::initializeResourceSystem(pack_path, true);
#endif #endif
@@ -164,7 +164,7 @@ Director::~Director() {
Input::destroy(); Input::destroy();
Notifier::destroy(); Notifier::destroy();
Resource::destroy(); Resource::destroy();
jdd::ResourceHelper::shutdownResourceSystem(); // Shutdown resource pack system Jdd::ResourceHelper::shutdownResourceSystem(); // Shutdown resource pack system
Audio::destroy(); Audio::destroy();
Screen::destroy(); Screen::destroy();
Asset::destroy(); Asset::destroy();

View File

@@ -443,7 +443,7 @@ auto Player::isOnFloor() -> bool {
} }
// Comprueba las rampas // Comprueba las rampas
on_slope_l = room_->checkLeftSlopes(&under_feet_[0]); on_slope_l = room_->checkLeftSlopes(under_feet_.data());
on_slope_r = room_->checkRightSlopes(&under_feet_[1]); on_slope_r = room_->checkRightSlopes(&under_feet_[1]);
return on_floor || on_slope_l || on_slope_r; return on_floor || on_slope_l || on_slope_r;
@@ -473,8 +473,8 @@ auto Player::isOnDownSlope() -> bool {
// Hay que mirar otro pixel más por debajo // Hay que mirar otro pixel más por debajo
SDL_FPoint foot0 = under_feet_[0]; SDL_FPoint foot0 = under_feet_[0];
SDL_FPoint foot1 = under_feet_[1]; SDL_FPoint foot1 = under_feet_[1];
foot0.y += 1.0f; foot0.y += 1.0F;
foot1.y += 1.0f; foot1.y += 1.0F;
// Comprueba las rampas // Comprueba las rampas
on_slope |= room_->checkLeftSlopes(&foot0); on_slope |= room_->checkLeftSlopes(&foot0);

View File

@@ -656,14 +656,14 @@ void Room::updateAnimatedTiles() {
const int NUM_FRAMES = 4; const int NUM_FRAMES = 4;
// Calcular frame actual basado en tiempo // Calcular frame actual basado en tiempo
const int current_frame = static_cast<int>(time_accumulator_ / CONVEYOR_FRAME_DURATION) % NUM_FRAMES; const int CURRENT_FRAME = static_cast<int>(time_accumulator_ / CONVEYOR_FRAME_DURATION) % NUM_FRAMES;
// Calcular offset basado en dirección // Calcular offset basado en dirección
int offset = 0; int offset = 0;
if (conveyor_belt_direction_ == -1) { if (conveyor_belt_direction_ == -1) {
offset = current_frame * TILE_SIZE; offset = CURRENT_FRAME * TILE_SIZE;
} else { } else {
offset = (NUM_FRAMES - 1 - current_frame) * TILE_SIZE; offset = (NUM_FRAMES - 1 - CURRENT_FRAME) * TILE_SIZE;
} }
for (auto& a : animated_tiles_) { for (auto& a : animated_tiles_) {
@@ -950,7 +950,7 @@ auto Room::loadRoomTileFile(const std::string& file_path, bool verbose) -> std::
const std::string FILENAME = file_path.substr(file_path.find_last_of("\\/") + 1); const std::string FILENAME = file_path.substr(file_path.find_last_of("\\/") + 1);
// Load file using ResourceHelper (supports both filesystem and pack) // Load file using ResourceHelper (supports both filesystem and pack)
auto file_data = jdd::ResourceHelper::loadFile(file_path); auto file_data = Jdd::ResourceHelper::loadFile(file_path);
if (!file_data.empty()) { if (!file_data.empty()) {
// Convert bytes to string and parse // Convert bytes to string and parse
@@ -1012,7 +1012,7 @@ auto Room::loadRoomFile(const std::string& file_path, bool verbose) -> Data {
room.number = FILE_NAME.substr(0, FILE_NAME.find_last_of('.')); room.number = FILE_NAME.substr(0, FILE_NAME.find_last_of('.'));
// Load file using ResourceHelper (supports both filesystem and pack) // Load file using ResourceHelper (supports both filesystem and pack)
auto file_data = jdd::ResourceHelper::loadFile(file_path); auto file_data = Jdd::ResourceHelper::loadFile(file_path);
if (!file_data.empty()) { if (!file_data.empty()) {
// Convert bytes to string and parse // Convert bytes to string and parse

View File

@@ -170,7 +170,7 @@ void Credits::update() {
shining_sprite_->update(DELTA_TIME); shining_sprite_->update(DELTA_TIME);
} }
Audio::get()->update(); // Actualiza el objeto Audio Audio::update(); // Actualiza el objeto Audio
Screen::get()->update(DELTA_TIME); // Actualiza el objeto Screen Screen::get()->update(DELTA_TIME); // Actualiza el objeto Screen
} }

View File

@@ -55,7 +55,7 @@ void Ending::update() {
updateState(DELTA_TIME); // Actualiza la máquina de estados updateState(DELTA_TIME); // Actualiza la máquina de estados
updateSpriteCovers(); // Actualiza las cortinillas de los elementos updateSpriteCovers(); // Actualiza las cortinillas de los elementos
Audio::get()->update(); // Actualiza el objeto Audio Audio::update(); // Actualiza el objeto Audio
Screen::get()->update(DELTA_TIME); // Actualiza el objeto Screen Screen::get()->update(DELTA_TIME); // Actualiza el objeto Screen
} }
@@ -496,43 +496,43 @@ void Ending::updateSpriteCovers() {
// Comprueba si se ha de cambiar de escena // Comprueba si se ha de cambiar de escena
void Ending::checkChangeScene() { void Ending::checkChangeScene() {
// Obtener duración de la escena actual // Obtener duración de la escena actual
float CURRENT_DURATION = 0.0F; float current_duration = 0.0F;
State NEXT_STATE = State::ENDING; State next_state = State::ENDING;
switch (state_) { switch (state_) {
case State::SCENE_0: case State::SCENE_0:
CURRENT_DURATION = SCENE_0_DURATION; current_duration = SCENE_0_DURATION;
NEXT_STATE = State::SCENE_1; next_state = State::SCENE_1;
break; break;
case State::SCENE_1: case State::SCENE_1:
CURRENT_DURATION = SCENE_1_DURATION; current_duration = SCENE_1_DURATION;
NEXT_STATE = State::SCENE_2; next_state = State::SCENE_2;
break; break;
case State::SCENE_2: case State::SCENE_2:
CURRENT_DURATION = SCENE_2_DURATION; current_duration = SCENE_2_DURATION;
NEXT_STATE = State::SCENE_3; next_state = State::SCENE_3;
break; break;
case State::SCENE_3: case State::SCENE_3:
CURRENT_DURATION = SCENE_3_DURATION; current_duration = SCENE_3_DURATION;
NEXT_STATE = State::SCENE_4; next_state = State::SCENE_4;
break; break;
case State::SCENE_4: case State::SCENE_4:
CURRENT_DURATION = SCENE_4_DURATION; current_duration = SCENE_4_DURATION;
NEXT_STATE = State::ENDING; next_state = State::ENDING;
break; break;
default: default:
return; return;
} }
// Comprobar si ha pasado la duración de la escena // Comprobar si ha pasado la duración de la escena
if (state_time_ >= CURRENT_DURATION) { if (state_time_ >= current_duration) {
if (NEXT_STATE == State::ENDING) { if (next_state == State::ENDING) {
// Termina el bucle // Termina el bucle
SceneManager::current = SceneManager::Scene::ENDING2; SceneManager::current = SceneManager::Scene::ENDING2;
} else { } else {
// Transición a la siguiente escena // Transición a la siguiente escena
current_scene_++; current_scene_++;
transitionToState(NEXT_STATE); transitionToState(next_state);
} }
} }
} }

View File

@@ -79,7 +79,7 @@ void Ending2::update() {
break; break;
} }
Audio::get()->update(); // Actualiza el objeto Audio Audio::update(); // Actualiza el objeto Audio
Screen::get()->update(DELTA_TIME); // Actualiza el objeto Screen Screen::get()->update(DELTA_TIME); // Actualiza el objeto Screen
} }

View File

@@ -148,7 +148,7 @@ void Game::update() {
keepMusicPlaying(); keepMusicPlaying();
updateBlackScreen(DELTA_TIME); updateBlackScreen(DELTA_TIME);
Audio::get()->update(); // Actualiza el objeto Audio Audio::update(); // Actualiza el objeto Audio
Screen::get()->update(DELTA_TIME); // Actualiza el objeto Screen Screen::get()->update(DELTA_TIME); // Actualiza el objeto Screen
#ifdef _DEBUG #ifdef _DEBUG

View File

@@ -56,7 +56,7 @@ void GameOver::update() {
player_sprite_->update(DELTA_TIME); // Actualiza el sprite player_sprite_->update(DELTA_TIME); // Actualiza el sprite
tv_sprite_->update(DELTA_TIME); // Actualiza el sprite tv_sprite_->update(DELTA_TIME); // Actualiza el sprite
Audio::get()->update(); // Actualiza el objeto Audio Audio::update(); // Actualiza el objeto Audio
Screen::get()->update(DELTA_TIME); // Actualiza el objeto Screen Screen::get()->update(DELTA_TIME); // Actualiza el objeto Screen
} }
@@ -123,9 +123,9 @@ void GameOver::updateColor() {
case State::FADE_IN: { case State::FADE_IN: {
// Fade in: de black (último color) a white (primer color) // Fade in: de black (último color) a white (primer color)
// Progreso: 0.0 (black) -> 1.0 (white) // Progreso: 0.0 (black) -> 1.0 (white)
const float progress = std::min(elapsed_time_ / FADE_IN_DURATION, 1.0f); const float PROGRESS = std::min(elapsed_time_ / FADE_IN_DURATION, 1.0F);
const int index = (colors_.size() - 1) - static_cast<int>((colors_.size() - 1) * progress); const int INDEX = (colors_.size() - 1) - static_cast<int>((colors_.size() - 1) * PROGRESS);
color_ = colors_[std::clamp(index, 0, static_cast<int>(colors_.size() - 1))]; color_ = colors_[std::clamp(INDEX, 0, static_cast<int>(colors_.size() - 1))];
break; break;
} }
@@ -137,9 +137,9 @@ void GameOver::updateColor() {
case State::FADE_OUT: { case State::FADE_OUT: {
// Fade out: de white (primer color) a black (último color) // Fade out: de white (primer color) a black (último color)
// Progreso: 0.0 (white) -> 1.0 (black) // Progreso: 0.0 (white) -> 1.0 (black)
const float progress = std::min(elapsed_time_ / FADE_OUT_DURATION, 1.0f); const float PROGRESS = std::min(elapsed_time_ / FADE_OUT_DURATION, 1.0F);
const int index = static_cast<int>((colors_.size() - 1) * progress); const int INDEX = static_cast<int>((colors_.size() - 1) * PROGRESS);
color_ = colors_[std::clamp(index, 0, static_cast<int>(colors_.size() - 1))]; color_ = colors_[std::clamp(INDEX, 0, static_cast<int>(colors_.size() - 1))];
break; break;
} }
@@ -165,7 +165,7 @@ void GameOver::updateState() {
// Espera inicial antes de empezar // Espera inicial antes de empezar
if (elapsed_time_ >= WAITING_DURATION) { if (elapsed_time_ >= WAITING_DURATION) {
state_ = State::FADE_IN; state_ = State::FADE_IN;
elapsed_time_ = 0.0f; elapsed_time_ = 0.0F;
// Hace sonar la música cuando termina la espera // Hace sonar la música cuando termina la espera
Audio::get()->playMusic("game_over.ogg", 0); Audio::get()->playMusic("game_over.ogg", 0);
} }
@@ -175,7 +175,7 @@ void GameOver::updateState() {
// Fade in de colores desde black // Fade in de colores desde black
if (elapsed_time_ >= FADE_IN_DURATION) { if (elapsed_time_ >= FADE_IN_DURATION) {
state_ = State::DISPLAY; state_ = State::DISPLAY;
elapsed_time_ = 0.0f; elapsed_time_ = 0.0F;
} }
break; break;
@@ -183,7 +183,7 @@ void GameOver::updateState() {
// Mostrando contenido con color brillante // Mostrando contenido con color brillante
if (elapsed_time_ >= DISPLAY_DURATION) { if (elapsed_time_ >= DISPLAY_DURATION) {
state_ = State::FADE_OUT; state_ = State::FADE_OUT;
elapsed_time_ = 0.0f; elapsed_time_ = 0.0F;
} }
break; break;
@@ -191,7 +191,7 @@ void GameOver::updateState() {
// Fade out hacia black // Fade out hacia black
if (elapsed_time_ >= FADE_OUT_DURATION) { if (elapsed_time_ >= FADE_OUT_DURATION) {
state_ = State::ENDING; state_ = State::ENDING;
elapsed_time_ = 0.0f; elapsed_time_ = 0.0F;
} }
break; break;
@@ -199,7 +199,7 @@ void GameOver::updateState() {
// Pantalla en negro antes de salir // Pantalla en negro antes de salir
if (elapsed_time_ >= ENDING_DURATION) { if (elapsed_time_ >= ENDING_DURATION) {
state_ = State::TRANSITION; state_ = State::TRANSITION;
elapsed_time_ = 0.0f; elapsed_time_ = 0.0F;
} }
break; break;

View File

@@ -28,11 +28,11 @@ class GameOver {
}; };
// --- Constantes de Duración (segundos) --- // --- Constantes de Duración (segundos) ---
static constexpr float WAITING_DURATION = 0.8f; // Espera inicial static constexpr float WAITING_DURATION = 0.8F; // Espera inicial
static constexpr float FADE_IN_DURATION = 0.32f; // Duración del fade in static constexpr float FADE_IN_DURATION = 0.32F; // Duración del fade in
static constexpr float DISPLAY_DURATION = 4.64f; // Duración mostrando contenido static constexpr float DISPLAY_DURATION = 4.64F; // Duración mostrando contenido
static constexpr float FADE_OUT_DURATION = 0.32f; // Duración del fade out static constexpr float FADE_OUT_DURATION = 0.32F; // Duración del fade out
static constexpr float ENDING_DURATION = 1.12f; // Espera en negro antes de salir static constexpr float ENDING_DURATION = 1.12F; // Espera en negro antes de salir
// --- Constantes de Posición --- // --- Constantes de Posición ---
static constexpr int TEXT_Y = 32; // Posición Y del texto principal static constexpr int TEXT_Y = 32; // Posición Y del texto principal
@@ -51,7 +51,7 @@ class GameOver {
// --- Variables --- // --- Variables ---
State state_ = State::WAITING; // Estado actual de la escena State state_ = State::WAITING; // Estado actual de la escena
float elapsed_time_ = 0.0f; // Tiempo transcurrido en el estado actual float elapsed_time_ = 0.0F; // Tiempo transcurrido en el estado actual
std::vector<Uint8> colors_; // Vector con los colores para el fade std::vector<Uint8> colors_; // Vector con los colores para el fade
Uint8 color_; // Color usado para el texto y los sprites Uint8 color_; // Color usado para el texto y los sprites

View File

@@ -277,7 +277,7 @@ void LoadingScreen::renderDataBorder() {
} }
// Dibuja el efecto de carga rojo y azul en el borde // Dibuja el efecto de carga rojo y azul en el borde
void LoadingScreen::renderHeaderBorder() { void LoadingScreen::renderHeaderBorder() const {
// Obtiene la Surface del borde // Obtiene la Surface del borde
auto border = Screen::get()->getBorderSurface(); auto border = Screen::get()->getBorderSurface();
@@ -441,10 +441,10 @@ void LoadingScreen::updateCarrier(float delta_time) {
constexpr float CARRIER_HEIGHT = HEADER_DATAROW_HEIGHT; constexpr float CARRIER_HEIGHT = HEADER_DATAROW_HEIGHT;
// Oscilación compuesta: mezcla de dos frecuencias para evitar patrón predecible // Oscilación compuesta: mezcla de dos frecuencias para evitar patrón predecible
const float modulation = std::sin(carrier_.total_time * 1.2F) * std::sin(carrier_.total_time * 0.35F + 1.0F); const float MODULATION = std::sin(carrier_.total_time * 1.2F) * std::sin((carrier_.total_time * 0.35F) + 1.0F);
const float speed = CARRIER_BASE_SPEED * (0.5F + 0.5F * modulation); // rango [-200, 0] const float SPEED = CARRIER_BASE_SPEED * (0.5F + 0.5F * MODULATION); // rango [-200, 0]
carrier_.offset += speed * delta_time; carrier_.offset += SPEED * delta_time;
if (carrier_.offset < 0.0F) { if (carrier_.offset < 0.0F) {
carrier_.offset += CARRIER_HEIGHT; // reinicia al rango [0,HEADER_DATAROW_HEIGHT] carrier_.offset += CARRIER_HEIGHT; // reinicia al rango [0,HEADER_DATAROW_HEIGHT]
@@ -459,8 +459,8 @@ void LoadingScreen::updateSilent(float delta_time) {
constexpr float NOISE_THRESHOLD = 0.35F; constexpr float NOISE_THRESHOLD = 0.35F;
// Oscilación compuesta para simular picos de ruido // Oscilación compuesta para simular picos de ruido
const float modulation = std::sin(noise_.total_time * 4.2F) * std::sin(noise_.total_time * 1.7F + 0.5F); const float MODULATION = std::sin(noise_.total_time * 4.2F) * std::sin((noise_.total_time * 1.7F) + 0.5F);
noise_.value = std::fabs(modulation); // rango [0.0, 1.0] noise_.value = std::fabs(MODULATION); // rango [0.0, 1.0]
// Detecta cruce de umbral solo si venía de abajo // Detecta cruce de umbral solo si venía de abajo
if (noise_.value > NOISE_THRESHOLD && !noise_.crossed) { if (noise_.value > NOISE_THRESHOLD && !noise_.crossed) {

View File

@@ -106,7 +106,7 @@ class LoadingScreen {
void updateColorLoad(float delta_time); // Gestiona la carga en color (time-based) void updateColorLoad(float delta_time); // Gestiona la carga en color (time-based)
void renderBorder(); // Pinta el borde void renderBorder(); // Pinta el borde
static void renderDataBorder(); // Dibuja el efecto de carga amarillo y azul en el borde static void renderDataBorder(); // Dibuja el efecto de carga amarillo y azul en el borde
void renderHeaderBorder(); // Dibuja el efecto de carga rojo y azul en el borde void renderHeaderBorder() const; // Dibuja el efecto de carga rojo y azul en el borde
static void renderColoredBorder(PaletteColor color); // Dibuja el borde de color static void renderColoredBorder(PaletteColor color); // Dibuja el borde de color
void initLineIndexArray(); // Inicializa el array de índices de líneas void initLineIndexArray(); // Inicializa el array de índices de líneas
void printProgramName(); // Escribe el nombre del programa void printProgramName(); // Escribe el nombre del programa

View File

@@ -22,9 +22,7 @@ Logo::Logo()
: jailgames_surface_(Resource::get()->getSurface("jailgames.gif")), : jailgames_surface_(Resource::get()->getSurface("jailgames.gif")),
since_1998_surface_(Resource::get()->getSurface("since_1998.gif")), since_1998_surface_(Resource::get()->getSurface("since_1998.gif")),
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())), 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>()), delta_timer_(std::make_unique<DeltaTimer>()) {
state_(State::INITIAL),
state_time_(0.0F) {
// Configura variables // Configura variables
since_1998_sprite_->setClip(0, 0, since_1998_surface_->getWidth(), since_1998_surface_->getHeight()); since_1998_sprite_->setClip(0, 0, since_1998_surface_->getWidth(), since_1998_surface_->getHeight());
since_1998_color_ = static_cast<Uint8>(PaletteColor::BLACK); since_1998_color_ = static_cast<Uint8>(PaletteColor::BLACK);
@@ -86,7 +84,7 @@ void Logo::updateJAILGAMES(float delta_time) {
} }
// Verifica si todas las líneas están en su posición destino // Verifica si todas las líneas están en su posición destino
bool Logo::allJailgamesLinesInPosition() const { auto Logo::allJailgamesLinesInPosition() const -> bool {
// Iterar por todas las líneas (empezando desde 1, como en updateJAILGAMES) // Iterar por todas las líneas (empezando desde 1, como en updateJAILGAMES)
for (size_t i = 1; i < jailgames_sprite_.size(); ++i) { for (size_t i = 1; i < jailgames_sprite_.size(); ++i) {
if (jailgames_sprite_[i]->getX() != JAILGAMES_DEST_X) { if (jailgames_sprite_[i]->getX() != JAILGAMES_DEST_X) {
@@ -200,7 +198,7 @@ void Logo::update() {
updateJAILGAMES(DELTA_TIME); // Gestiona el logo de JAILGAME updateJAILGAMES(DELTA_TIME); // Gestiona el logo de JAILGAME
updateTextureColors(); // Gestiona el color de las texturas updateTextureColors(); // Gestiona el color de las texturas
Audio::get()->update(); // Actualiza el objeto Audio Audio::update(); // Actualiza el objeto Audio
Screen::get()->update(DELTA_TIME); // Actualiza el objeto Screen Screen::get()->update(DELTA_TIME); // Actualiza el objeto Screen
} }

View File

@@ -63,7 +63,7 @@ class Logo {
void updateState(float delta_time); // Actualiza el estado actual void updateState(float delta_time); // Actualiza el estado actual
void transitionToState(State new_state); // Transiciona a un nuevo estado void transitionToState(State new_state); // Transiciona a un nuevo estado
[[nodiscard]] auto getColorIndex(float progress) const -> int; // Calcula el índice de color según el progreso (0.0-1.0) [[nodiscard]] auto getColorIndex(float progress) const -> int; // Calcula el índice de color según el progreso (0.0-1.0)
[[nodiscard]] bool allJailgamesLinesInPosition() const; // Verifica si todas las líneas están en su posición destino [[nodiscard]] auto allJailgamesLinesInPosition() const -> bool; // Verifica si todas las líneas están en su posición destino
static void endSection(); // Termina la sección static void endSection(); // Termina la sección
void initColors(); // Inicializa el vector de colores void initColors(); // Inicializa el vector de colores
void initSprites(); // Crea los sprites de cada linea void initSprites(); // Crea los sprites de cada linea

View File

@@ -91,53 +91,13 @@ void Title::handleEvents() {
if (event.type == SDL_EVENT_KEY_DOWN) { if (event.type == SDL_EVENT_KEY_DOWN) {
switch (state_) { switch (state_) {
case State::MAIN_MENU: case State::MAIN_MENU:
switch (event.key.key) { handleMainMenuKeyPress(event.key.key);
case SDLK_1:
exit_scene_ = SceneManager::Scene::GAME;
transitionToState(State::FADE_MENU);
Audio::get()->fadeOutMusic(1000);
break;
case SDLK_2:
transitionToState(State::CONTROLS_MENU);
controls_menu_state_ = ControlsMenuState::MAIN;
break;
case SDLK_3:
transitionToState(State::CHEEVOS_MENU);
break;
default:
break;
}
break; break;
case State::CONTROLS_MENU: case State::CONTROLS_MENU:
if (controls_menu_state_ == ControlsMenuState::MAIN) { if (controls_menu_state_ == ControlsMenuState::MAIN) {
// Menu principal de controles handleControlsMenuKeyPress(event.key.key);
switch (event.key.key) {
case SDLK_1:
// Iniciar redefinicion de teclado
controls_menu_state_ = ControlsMenuState::KEYBOARD_REMAP;
remap_step_ = 0;
remap_error_message_.clear();
break;
case SDLK_2:
// Redefinir joystick - solo si hay gamepads conectados
if (Input::get()->gameControllerFound()) {
controls_menu_state_ = ControlsMenuState::JOYSTICK_REMAP;
remap_step_ = 0;
remap_error_message_.clear();
axis_cooldown_ = 0.0F; // Resetear cooldown
}
break;
default:
break;
}
} else if (controls_menu_state_ == ControlsMenuState::KEYBOARD_REMAP) { } else if (controls_menu_state_ == ControlsMenuState::KEYBOARD_REMAP) {
// Captura de teclas para redefinir
handleControlsMenuKeyboardRemap(event); handleControlsMenuKeyboardRemap(event);
} }
break; break;
@@ -149,6 +109,54 @@ void Title::handleEvents() {
} }
} }
// Maneja las teclas del menu principal
void Title::handleMainMenuKeyPress(SDL_Keycode key) {
switch (key) {
case SDLK_1:
exit_scene_ = SceneManager::Scene::GAME;
transitionToState(State::FADE_MENU);
Audio::get()->fadeOutMusic(1000);
break;
case SDLK_2:
transitionToState(State::CONTROLS_MENU);
controls_menu_state_ = ControlsMenuState::MAIN;
break;
case SDLK_3:
transitionToState(State::CHEEVOS_MENU);
break;
default:
break;
}
}
// Maneja las teclas del menu de controles
void Title::handleControlsMenuKeyPress(SDL_Keycode key) {
switch (key) {
case SDLK_1:
// Iniciar redefinicion de teclado
controls_menu_state_ = ControlsMenuState::KEYBOARD_REMAP;
remap_step_ = 0;
remap_error_message_.clear();
break;
case SDLK_2:
// Redefinir joystick - solo si hay gamepads conectados
if (Input::get()->gameControllerFound()) {
controls_menu_state_ = ControlsMenuState::JOYSTICK_REMAP;
remap_step_ = 0;
remap_error_message_.clear();
axis_cooldown_ = 0.0F; // Resetear cooldown
}
break;
default:
break;
}
}
// Comprueba las entradas // Comprueba las entradas
void Title::handleInput(float delta_time) { void Title::handleInput(float delta_time) {
Input::get()->update(); Input::get()->update();
@@ -247,7 +255,7 @@ void Title::update() {
updateState(DELTA_TIME); // Actualiza el estado actual updateState(DELTA_TIME); // Actualiza el estado actual
Audio::get()->update(); // Actualiza el objeto Audio Audio::update(); // Actualiza el objeto Audio
Screen::get()->update(DELTA_TIME); // Actualiza el objeto Screen Screen::get()->update(DELTA_TIME); // Actualiza el objeto Screen
} }
@@ -343,9 +351,7 @@ void Title::updateControlsMenu(float delta_time) {
// Decrementar cooldown de ejes si estamos capturando botones // Decrementar cooldown de ejes si estamos capturando botones
if (controls_menu_state_ == ControlsMenuState::JOYSTICK_REMAP && axis_cooldown_ > 0.0F) { if (controls_menu_state_ == ControlsMenuState::JOYSTICK_REMAP && axis_cooldown_ > 0.0F) {
axis_cooldown_ -= delta_time; axis_cooldown_ -= delta_time;
if (axis_cooldown_ < 0.0F) { axis_cooldown_ = std::max(axis_cooldown_, 0.0F);
axis_cooldown_ = 0.0F;
}
} }
// Si estamos mostrando las teclas definidas, esperar antes de guardar // Si estamos mostrando las teclas definidas, esperar antes de guardar
@@ -517,7 +523,7 @@ void Title::renderControlsMenu() {
controls_menu_state_ == ControlsMenuState::KEYBOARD_REMAP_COMPLETE) { controls_menu_state_ == ControlsMenuState::KEYBOARD_REMAP_COMPLETE) {
renderKeyboardRemap(); renderKeyboardRemap();
} else if (controls_menu_state_ == ControlsMenuState::JOYSTICK_REMAP || } else if (controls_menu_state_ == ControlsMenuState::JOYSTICK_REMAP ||
controls_menu_state_ == ControlsMenuState::JOYSTICK_REMAP_COMPLETE) { controls_menu_state_ == ControlsMenuState::JOYSTICK_REMAP_COMPLETE) {
renderJoystickRemap(); renderJoystickRemap();
} else { } else {
// Menu principal de controles // Menu principal de controles
@@ -527,9 +533,8 @@ void Title::renderControlsMenu() {
menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 11 * TEXT_SIZE, "1. REDEFINE KEYBOARD", 1, COLOR); menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 11 * TEXT_SIZE, "1. REDEFINE KEYBOARD", 1, COLOR);
// Deshabilitar opcion de joystick si no hay gamepads conectados // Deshabilitar opcion de joystick si no hay gamepads conectados
const bool gamepad_available = Input::get()->gameControllerFound(); const bool GAMEPAD_AVAILABLE = Input::get()->gameControllerFound();
menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 13 * TEXT_SIZE, menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 13 * TEXT_SIZE, "2. REDEFINE JOYSTICK", 1, GAMEPAD_AVAILABLE ? COLOR : DISABLED_COLOR);
"2. REDEFINE JOYSTICK", 1, gamepad_available ? COLOR : DISABLED_COLOR);
menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 17 * TEXT_SIZE, "ENTER TO GO BACK", 1, COLOR); menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 17 * TEXT_SIZE, "ENTER TO GO BACK", 1, COLOR);
} }
@@ -607,7 +612,7 @@ void Title::handleControlsMenuKeyboardRemap(const SDL_Event& event) {
} }
// Valida si una tecla es permitida // Valida si una tecla es permitida
bool Title::isKeyValid(SDL_Scancode scancode) { auto Title::isKeyValid(SDL_Scancode scancode) -> bool {
// Prohibir ESC (reservado para cancelar) // Prohibir ESC (reservado para cancelar)
if (scancode == SDL_SCANCODE_ESCAPE) { if (scancode == SDL_SCANCODE_ESCAPE) {
return false; return false;
@@ -627,7 +632,7 @@ bool Title::isKeyValid(SDL_Scancode scancode) {
} }
// Verifica si una tecla ya fue usada en pasos anteriores // Verifica si una tecla ya fue usada en pasos anteriores
bool Title::isKeyDuplicate(SDL_Scancode scancode, int current_step) { auto Title::isKeyDuplicate(SDL_Scancode scancode, int current_step) -> bool {
for (int i = 0; i < current_step; i++) { for (int i = 0; i < current_step; i++) {
if (temp_keys_[i] == scancode) { if (temp_keys_[i] == scancode) {
return true; return true;
@@ -637,7 +642,7 @@ bool Title::isKeyDuplicate(SDL_Scancode scancode, int current_step) {
} }
// Retorna el nombre de la accion para el paso actual // Retorna el nombre de la accion para el paso actual
std::string Title::getActionName(int step) { auto Title::getActionName(int step) -> std::string {
switch (step) { switch (step) {
case 0: case 0:
return "LEFT"; return "LEFT";
@@ -671,7 +676,7 @@ void Title::renderKeyboardRemap() {
const int TEXT_SIZE = menu_text_->getCharacterSize(); const int TEXT_SIZE = menu_text_->getCharacterSize();
// Titulo // Titulo
//menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 9 * TEXT_SIZE, "REDEFINE KEYBOARD", 1, COLOR); // menu_text_->writeDX(TEXT_CENTER | TEXT_COLOR, PLAY_AREA_CENTER_X, 9 * TEXT_SIZE, "REDEFINE KEYBOARD", 1, COLOR);
// Mensaje principal: "PRESS KEY FOR [ACTION]" o "KEYS DEFINED" si completado // Mensaje principal: "PRESS KEY FOR [ACTION]" o "KEYS DEFINED" si completado
if (remap_step_ >= 3) { if (remap_step_ >= 3) {
@@ -764,7 +769,7 @@ void Title::handleControlsMenuJoystickRemap(const SDL_Event& event) {
// Capturar triggers como botones (usando valores especiales 100/101) // Capturar triggers como botones (usando valores especiales 100/101)
if (event.gaxis.axis == SDL_GAMEPAD_AXIS_LEFT_TRIGGER && event.gaxis.value > TRIGGER_THRESHOLD) { if (event.gaxis.axis == SDL_GAMEPAD_AXIS_LEFT_TRIGGER && event.gaxis.value > TRIGGER_THRESHOLD) {
captured_button = Input::TRIGGER_L2_AS_BUTTON; // 100 captured_button = Input::TRIGGER_L2_AS_BUTTON; // 100
axis_cooldown_ = 0.5F; // Cooldown de medio segundo axis_cooldown_ = 0.5F; // Cooldown de medio segundo
} else if (event.gaxis.axis == SDL_GAMEPAD_AXIS_RIGHT_TRIGGER && event.gaxis.value > TRIGGER_THRESHOLD) { } else if (event.gaxis.axis == SDL_GAMEPAD_AXIS_RIGHT_TRIGGER && event.gaxis.value > TRIGGER_THRESHOLD) {
captured_button = Input::TRIGGER_R2_AS_BUTTON; // 101 captured_button = Input::TRIGGER_R2_AS_BUTTON; // 101
axis_cooldown_ = 0.5F; axis_cooldown_ = 0.5F;
@@ -805,7 +810,7 @@ void Title::handleControlsMenuJoystickRemap(const SDL_Event& event) {
} }
// Valida si un botón está duplicado // Valida si un botón está duplicado
bool Title::isButtonDuplicate(int button, int current_step) { auto Title::isButtonDuplicate(int button, int current_step) -> bool {
for (int i = 0; i < current_step; ++i) { for (int i = 0; i < current_step; ++i) {
if (temp_buttons_[i] == button) { if (temp_buttons_[i] == button) {
return true; return true;
@@ -829,7 +834,7 @@ void Title::applyJoystickRemap() {
} }
// Retorna el nombre amigable del botón del gamepad // Retorna el nombre amigable del botón del gamepad
std::string Title::getButtonName(int button) { auto Title::getButtonName(int button) -> std::string {
// Triggers especiales // Triggers especiales
if (button == Input::TRIGGER_L2_AS_BUTTON) { if (button == Input::TRIGGER_L2_AS_BUTTON) {
return "L2"; return "L2";
@@ -847,7 +852,7 @@ std::string Title::getButtonName(int button) {
} }
// Botones estándar SDL // Botones estándar SDL
const auto sdl_button = static_cast<SDL_GamepadButton>(button); const auto GAMEPAD_BUTTON = static_cast<SDL_GamepadButton>(button);
const char* button_name = SDL_GetGamepadStringForButton(sdl_button); const char* button_name = SDL_GetGamepadStringForButton(GAMEPAD_BUTTON);
return button_name ? std::string(button_name) : "UNKNOWN"; return (button_name != nullptr) ? std::string(button_name) : "UNKNOWN";
} }

View File

@@ -98,6 +98,8 @@ class Title {
void update(); // Actualiza las variables void update(); // Actualiza las variables
void render(); // Dibuja en pantalla void render(); // Dibuja en pantalla
void handleEvents(); // Comprueba el manejador de eventos void handleEvents(); // Comprueba el manejador de eventos
void handleMainMenuKeyPress(SDL_Keycode key); // Maneja las teclas del menu principal
void handleControlsMenuKeyPress(SDL_Keycode key); // Maneja las teclas del menu de controles
void handleInput(float delta_time); // Comprueba las entradas void handleInput(float delta_time); // Comprueba las entradas
void updateState(float delta_time); // Actualiza el estado actual void updateState(float delta_time); // Actualiza el estado actual
void transitionToState(State new_state); // Transiciona a un nuevo estado void transitionToState(State new_state); // Transiciona a un nuevo estado
@@ -120,13 +122,13 @@ class Title {
void moveCheevosList(int direction, float delta_time); // Desplaza la lista de logros (time-based) void moveCheevosList(int direction, float delta_time); // Desplaza la lista de logros (time-based)
void handleControlsMenuKeyboardRemap(const SDL_Event& event); // Maneja la captura de teclas void handleControlsMenuKeyboardRemap(const SDL_Event& event); // Maneja la captura de teclas
void handleControlsMenuJoystickRemap(const SDL_Event& event); // Maneja la captura de botones del gamepad void handleControlsMenuJoystickRemap(const SDL_Event& event); // Maneja la captura de botones del gamepad
bool isKeyValid(SDL_Scancode scancode); // Valida si una tecla es permitida static auto isKeyValid(SDL_Scancode scancode) -> bool; // Valida si una tecla es permitida
bool isKeyDuplicate(SDL_Scancode scancode, int current_step); // Valida si una tecla esta duplicada auto isKeyDuplicate(SDL_Scancode scancode, int current_step) -> bool; // Valida si una tecla esta duplicada
bool isButtonDuplicate(int button, int current_step); // Valida si un boton esta duplicado auto isButtonDuplicate(int button, int current_step) -> bool; // Valida si un boton esta duplicado
void applyKeyboardRemap(); // Aplica y guarda las teclas redefinidas void applyKeyboardRemap(); // Aplica y guarda las teclas redefinidas
void applyJoystickRemap(); // Aplica y guarda los botones del gamepad redefinidos void applyJoystickRemap(); // Aplica y guarda los botones del gamepad redestatic finidos
std::string getActionName(int step); // Retorna el nombre de la accion (LEFT/RIGHT/JUMP) static auto getActionName(int step) -> std::string; // Retorna el nombre de la accion (LEFT/RIGHstatic T/JUMP)
std::string getButtonName(int button); // Retorna el nombre amigable del boton del gamepad static auto getButtonName(int button) -> std::string; // Retorna el nombre amigable del boton del gamepad
void createCheevosTexture(); // Crea y rellena la surface para mostrar los logros void createCheevosTexture(); // Crea y rellena la surface para mostrar los logros
void resetCheevosScroll(); // Resetea el scroll de la lista de logros void resetCheevosScroll(); // Resetea el scroll de la lista de logros
void fillTitleSurface(); // Dibuja los elementos en la surface void fillTitleSurface(); // Dibuja los elementos en la surface

View File

@@ -21,41 +21,96 @@ void printUsage(const char* program_name) {
std::cout << " --list List contents of a pack file\n"; std::cout << " --list List contents of a pack file\n";
} }
int main(int argc, char* argv[]) { auto handleDefaultPack() -> int {
std::string input_dir = "data";
std::string output_file = "resources.pack";
std::cout << "Using defaults:\n";
std::cout << " Input: " << input_dir << "/\n";
std::cout << " Output: " << output_file << "\n\n";
Jdd::ResourcePack pack;
if (!pack.addDirectory(input_dir)) {
std::cerr << "Error: Failed to add directory: " << input_dir << '\n';
return 1;
}
// Add config/assets.txt to pack (required for release builds)
std::cout << "\nAdding config files...\n";
if (!pack.addFile("config/assets.txt", "config/assets.txt")) {
std::cerr << "Warning: Failed to add config/assets.txt (optional)\n";
}
if (!pack.savePack(output_file)) {
std::cerr << "Error: Failed to save pack file: " << output_file << '\n';
return 1;
}
std::cout << "\nSuccess! Pack created: " << output_file << '\n';
return 0;
}
auto handleListContents(const std::string& pack_file) -> int {
std::cout << "Loading pack: " << pack_file << "\n\n";
Jdd::ResourcePack pack;
if (!pack.loadPack(pack_file)) {
std::cerr << "Error: Failed to load pack file: " << pack_file << '\n';
return 1;
}
std::cout << "\nPack Contents:\n";
std::cout << "==============\n";
auto resources = pack.getResourceList();
size_t total_size = 0;
for (const auto& resource : resources) {
auto data = pack.getResource(resource);
total_size += data.size();
std::cout << " " << resource << " (" << data.size() << " bytes)\n";
}
std::cout << "\nTotal Resources: " << resources.size() << '\n';
std::cout << "Total Size: " << total_size << " bytes\n";
return 0;
}
auto handlePackDirectory(const std::string& input_dir, const std::string& output_file) -> int {
std::cout << "Input: " << input_dir << "/\n";
std::cout << "Output: " << output_file << "\n\n";
Jdd::ResourcePack pack;
if (!pack.addDirectory(input_dir)) {
std::cerr << "Error: Failed to add directory: " << input_dir << '\n';
return 1;
}
// Add config/assets.txt to pack (required for release builds)
std::cout << "\nAdding config files...\n";
if (!pack.addFile("config/assets.txt", "config/assets.txt")) {
std::cerr << "Warning: Failed to add config/assets.txt (optional)\n";
}
if (!pack.savePack(output_file)) {
std::cerr << "Error: Failed to save pack file: " << output_file << '\n';
return 1;
}
std::cout << "\nSuccess! Pack created: " << output_file << '\n';
return 0;
}
auto main(int argc, char* argv[]) -> int {
std::cout << "JailDoctor's Dilemma - Resource Packer\n"; std::cout << "JailDoctor's Dilemma - Resource Packer\n";
std::cout << "======================================\n\n"; std::cout << "======================================\n\n";
// Parse command line arguments // Default behavior: pack data/ into resources.pack
if (argc == 1) { if (argc == 1) {
// Default behavior: pack data/ into resources.pack return handleDefaultPack();
std::string input_dir = "data";
std::string output_file = "resources.pack";
std::cout << "Using defaults:\n";
std::cout << " Input: " << input_dir << "/\n";
std::cout << " Output: " << output_file << "\n\n";
jdd::ResourcePack pack;
if (!pack.addDirectory(input_dir)) {
std::cerr << "Error: Failed to add directory: " << input_dir << '\n';
return 1;
}
// Add config/assets.txt to pack (required for release builds)
std::cout << "\nAdding config files...\n";
if (!pack.addFile("config/assets.txt", "config/assets.txt")) {
std::cerr << "Warning: Failed to add config/assets.txt (optional)\n";
}
if (!pack.savePack(output_file)) {
std::cerr << "Error: Failed to save pack file: " << output_file << '\n';
return 1;
}
std::cout << "\nSuccess! Pack created: " << output_file << '\n';
return 0;
} }
// Help command
if (argc == 2) { if (argc == 2) {
std::string arg = argv[1]; std::string arg = argv[1];
if (arg == "--help" || arg == "-h") { if (arg == "--help" || arg == "-h") {
@@ -64,63 +119,16 @@ int main(int argc, char* argv[]) {
} }
} }
// List contents or pack directory
if (argc == 3) { if (argc == 3) {
std::string arg1 = argv[1]; std::string arg1 = argv[1];
std::string arg2 = argv[2]; std::string arg2 = argv[2];
// List contents
if (arg1 == "--list" || arg1 == "-l") { if (arg1 == "--list" || arg1 == "-l") {
std::cout << "Loading pack: " << arg2 << "\n\n"; return handleListContents(arg2);
jdd::ResourcePack pack;
if (!pack.loadPack(arg2)) {
std::cerr << "Error: Failed to load pack file: " << arg2 << '\n';
return 1;
}
std::cout << "\nPack Contents:\n";
std::cout << "==============\n";
auto resources = pack.getResourceList();
size_t total_size = 0;
for (const auto& resource : resources) {
auto data = pack.getResource(resource);
total_size += data.size();
std::cout << " " << resource << " (" << data.size() << " bytes)\n";
}
std::cout << "\nTotal Resources: " << resources.size() << '\n';
std::cout << "Total Size: " << total_size << " bytes\n";
return 0;
} }
// Pack directory return handlePackDirectory(arg1, arg2);
std::string input_dir = arg1;
std::string output_file = arg2;
std::cout << "Input: " << input_dir << "/\n";
std::cout << "Output: " << output_file << "\n\n";
jdd::ResourcePack pack;
if (!pack.addDirectory(input_dir)) {
std::cerr << "Error: Failed to add directory: " << input_dir << '\n';
return 1;
}
// Add config/assets.txt to pack (required for release builds)
std::cout << "\nAdding config files...\n";
if (!pack.addFile("config/assets.txt", "config/assets.txt")) {
std::cerr << "Warning: Failed to add config/assets.txt (optional)\n";
}
if (!pack.savePack(output_file)) {
std::cerr << "Error: Failed to save pack file: " << output_file << '\n';
return 1;
}
std::cout << "\nSuccess! Pack created: " << output_file << '\n';
return 0;
} }
// Invalid arguments // Invalid arguments