diff --git a/linux_utils/check_all_includes.sh b/linux_utils/check_all_includes.sh index 3329bf3..2670b74 100755 --- a/linux_utils/check_all_includes.sh +++ b/linux_utils/check_all_includes.sh @@ -4,5 +4,5 @@ SOURCEPATH=../source/ for i in "$SOURCEPATH"/*.cpp do - include-what-you-use -D DEBUG -D VERBOSE -std=c++20 -Wall "$i" + include-what-you-use -D _DEBUG -std=c++20 -Wall "$i" done diff --git a/source/audio.h b/source/audio.h index b2f8762..54eeb8d 100644 --- a/source/audio.h +++ b/source/audio.h @@ -25,7 +25,7 @@ class Audio { auto operator=(const Audio &) -> Audio & = delete; // Evitar asignación // --- Método principal --- - void update(); + static void update(); // --- Control de Música --- void playMusic(const std::string &name, int loop = -1); // Reproducir música en bucle diff --git a/source/balloon.h b/source/balloon.h index 446d633..5ccd842 100644 --- a/source/balloon.h +++ b/source/balloon.h @@ -2,10 +2,11 @@ #include // Para Uint8, Uint16, SDL_FRect, Uint32 -#include // Para array -#include // Para allocator, shared_ptr, unique_ptr -#include // Para basic_string, string -#include // Para vector +#include // Para array +#include // Para allocator, shared_ptr, unique_ptr +#include // Para basic_string, string +#include // Para string_view +#include // Para vector #include "animated_sprite.h" // Para AnimatedSprite #include "utils.h" // Para Circle @@ -23,10 +24,10 @@ class Balloon { static constexpr std::array MENACE = {1, 2, 4, 8}; static constexpr std::array WIDTH = {10, 16, 26, 48, 49}; - const std::array BOUNCING_SOUND = { + static constexpr std::array BOUNCING_SOUND = { "balloon_bounce0.wav", "balloon_bounce1.wav", "balloon_bounce2.wav", "balloon_bounce3.wav"}; - const std::array POPPING_SOUND = { + static constexpr std::array POPPING_SOUND = { "balloon_pop0.wav", "balloon_pop1.wav", "balloon_pop2.wav", "balloon_pop3.wav"}; static constexpr float VELX_POSITIVE = 0.7F; @@ -111,22 +112,22 @@ class Balloon { static constexpr int BOUNCE_FRAMES = 10; // Cantidad de elementos del vector de deformación // Tablas de valores predefinidos para el efecto de rebote - static constexpr std::array horizontal_zoom_values = { + static constexpr std::array HORIZONTAL_ZOOM_VALUES = { 1.10F, 1.05F, 1.00F, 0.95F, 0.90F, 0.95F, 1.00F, 1.02F, 1.05F, 1.02F}; - static constexpr std::array vertical_zoom_values = { + static constexpr std::array VERTICAL_ZOOM_VALUES = { 0.90F, 0.95F, 1.00F, 1.05F, 1.10F, 1.05F, 1.00F, 0.98F, 0.95F, 0.98F}; // Estado del efecto - bool enabled = false; // Si el efecto está activo - Uint8 counter = 0; // Contador para el efecto - Uint8 speed = 2; // Velocidad del efecto + bool enabled_ = false; // Si el efecto está activo + Uint8 counter_ = 0; // Contador para el efecto + Uint8 speed_ = 2; // Velocidad del efecto // Valores actuales de transformación - float horizontal_zoom = 1.0F; // Zoom en anchura - float verical_zoom = 1.0F; // Zoom en altura - float x_offset = 0.0F; // Desplazamiento X antes de pintar - float y_offset = 0.0F; // Desplazamiento Y antes de pintar + float horizontal_zoom_ = 1.0F; // Zoom en anchura + float verical_zoom_ = 1.0F; // Zoom en altura + float x_offset_ = 0.0F; // Desplazamiento X antes de pintar + float y_offset_ = 0.0F; // Desplazamiento Y antes de pintar public: // Constructor por defecto @@ -134,18 +135,18 @@ class Balloon { // Reinicia el efecto a sus valores iniciales void reset() { - counter = 0; - horizontal_zoom = 1.0F; - verical_zoom = 1.0F; - x_offset = 0.0F; - y_offset = 0.0F; + counter_ = 0; + horizontal_zoom_ = 1.0F; + verical_zoom_ = 1.0F; + x_offset_ = 0.0F; + y_offset_ = 0.0F; } // Aplica la deformación visual al sprite - void apply(AnimatedSprite* sprite) { - if (sprite) { - sprite->setHorizontalZoom(horizontal_zoom); - sprite->setVerticalZoom(verical_zoom); + void apply(AnimatedSprite* sprite) const { + if (sprite != nullptr) { + sprite->setHorizontalZoom(horizontal_zoom_); + sprite->setVerticalZoom(verical_zoom_); } } @@ -155,46 +156,46 @@ class Balloon { if (balloon_size == Size::SMALL) { return; } - enabled = true; + enabled_ = true; reset(); apply(sprite); } // Detiene el efecto de rebote void disable(AnimatedSprite* sprite) { - enabled = false; + enabled_ = false; reset(); apply(sprite); } // Actualiza el efecto en cada frame void update(AnimatedSprite* sprite) { - if (!enabled) { + if (!enabled_) { return; } // Calcula el índice basado en el contador y velocidad - const int INDEX = counter / speed; + const int INDEX = counter_ / speed_; // Actualiza los valores de zoom desde las tablas predefinidas - horizontal_zoom = horizontal_zoom_values.at(INDEX); - verical_zoom = vertical_zoom_values.at(INDEX); + horizontal_zoom_ = HORIZONTAL_ZOOM_VALUES.at(INDEX); + verical_zoom_ = VERTICAL_ZOOM_VALUES.at(INDEX); // Aplica la deformación al sprite apply(sprite); // Incrementa el contador y verifica si el efecto debe terminar - if (++counter / speed >= BOUNCE_FRAMES) { + if (++counter_ / speed_ >= BOUNCE_FRAMES) { disable(sprite); } } // Getters para acceso a los valores actuales - bool isEnabled() const { return enabled; } - float getHorizontalZoom() const { return horizontal_zoom; } - float getVerticalZoom() const { return verical_zoom; } - float GetXOffset() const { return x_offset; } - float GetYOffset() const { return y_offset; } + [[nodiscard]] auto isEnabled() const -> bool { return enabled_; } + [[nodiscard]] auto getHorizontalZoom() const -> float { return horizontal_zoom_; } + [[nodiscard]] auto getVerticalZoom() const -> float { return verical_zoom_; } + [[nodiscard]] auto getXOffset() const -> float { return x_offset_; } + [[nodiscard]] auto getYOffset() const -> float { return y_offset_; } }; // --- Objetos y punteros --- diff --git a/source/balloon_formations.cpp b/source/balloon_formations.cpp index 849e925..7cd8cba 100644 --- a/source/balloon_formations.cpp +++ b/source/balloon_formations.cpp @@ -1,17 +1,18 @@ #include "balloon_formations.h" -#include // Para max +#include // Para max, min, copy #include // Para array #include // Para isdigit #include // Para size_t #include // Para exception #include // Para basic_istream, basic_ifstream, ifstream, istringstream -#include // Para map, operator== +#include // Para reverse_iterator +#include // Para map, operator==, _Rb_tree_iterator #include // Para basic_istringstream -#include // Para allocator, char_traits, operator==, string, operator<=>, basic_string, stoi, getline +#include // Para string, char_traits, allocator, operator==, stoi, getline, operator<=>, basic_string #include "asset.h" // Para Asset -#include "balloon.h" // Para Balloon::SIZE, Balloon::Size, Balloon::Type, Balloon::VELX_NEGATIVE, Balloon::VELX_POSITIVE +#include "balloon.h" // Para Balloon #include "param.h" // Para Param, ParamGame, param #include "utils.h" // Para Zone, BLOCK @@ -224,8 +225,7 @@ void BalloonFormations::createFloaterVariants() { std::vector floater_params; floater_params.reserve(formations_.at(k).balloons.size()); - for (size_t i = 0; i < formations_.at(k).balloons.size(); i++) { - const auto& original = formations_.at(k).balloons.at(i); + for (const auto& original : formations_.at(k).balloons) { floater_params.emplace_back(original.x, original.y, original.vel_x, Balloon::Type::FLOATER, original.size, original.creation_counter); } diff --git a/source/balloon_formations.h b/source/balloon_formations.h index 56429fd..c345735 100644 --- a/source/balloon_formations.h +++ b/source/balloon_formations.h @@ -1,12 +1,14 @@ #pragma once -#include // Para copy +#include // Para copy, max +#include // Para size_t #include // Para map #include // Para optional #include // Para string +#include // Para pair #include // Para vector -#include "balloon.h" // Para Balloon::Size, Balloon::Type +#include "balloon.h" // Para Balloon // --- Clase BalloonFormations --- class BalloonFormations { diff --git a/source/color.cpp b/source/color.cpp index 0752932..a4bea0e 100644 --- a/source/color.cpp +++ b/source/color.cpp @@ -1,10 +1,9 @@ #define _USE_MATH_DEFINES #include "color.h" -#include // Para uint8_t - #include // Para isxdigit #include // Para sinf, fmaxf, fminf, M_PI, fmodf, roundf, fmod +#include // Para uint8_t #include // Para invalid_argument #include // Para basic_string, stoi, string diff --git a/source/color.h b/source/color.h index a742dc5..d04998b 100644 --- a/source/color.h +++ b/source/color.h @@ -1,7 +1,7 @@ // IWYU pragma: no_include #pragma once -#include // Para Uint8 +#include // Para Uint8 #include // Para max, min #include // Para array diff --git a/source/define_buttons.cpp b/source/define_buttons.cpp index 551bd14..8cda907 100644 --- a/source/define_buttons.cpp +++ b/source/define_buttons.cpp @@ -1,38 +1,38 @@ #include "define_buttons.h" -#include // Para max, __all_of_fn, all_of +#include // Para __all_of_fn, all_of #include // Para identity +#include // Para allocator, shared_ptr, __shared_ptr_access, operator== -#include "input.h" // Para Input, InputAction -#include "lang.h" // Para getText -#include "options.h" // Para GamepadOptions, controllers -#include "param.h" // Para Param, param, ParamGame, ParamTitle -#include "resource.h" // Para Resource -#include "text.h" // Para Text +#include "input.h" // Para Input +#include "input_types.h" // Para InputAction +#include "lang.h" // Para getText +#include "options.h" // Para Gamepad +#include "param.h" // Para Param, param, ParamGame, ParamTitle +#include "resource.h" // Para Resource +#include "text.h" // Para Text // Constructor DefineButtons::DefineButtons() : input_(Input::get()), - enabled_(false), - finished_(false), + x_(param.game.width / 2), - y_(param.title.press_start_position), - index_button_(0) { + y_(param.title.press_start_position) { clearButtons(); auto gamepads = input_->getGamepads(); for (auto gamepad : gamepads) { - controller_names_.emplace_back(input_->getControllerName(gamepad)); + controller_names_.emplace_back(Input::getControllerName(gamepad)); } } // Dibuja el objeto en pantalla void DefineButtons::render() { - static auto text = Resource::get()->getText("8bithud"); + static auto text_ = Resource::get()->getText("8bithud"); if (enabled_) { - text->writeCentered(x_, y_ - 10, Lang::getText("[DEFINE_BUTTONS] PLAYER") + std::to_string(static_cast(options_gamepad_->player_id))); - text->writeCentered(x_, y_, options_gamepad_->name); - text->writeCentered(x_, y_ + 10, buttons_.at(index_button_).label); + text_->writeCentered(x_, y_ - 10, Lang::getText("[DEFINE_BUTTONS] PLAYER") + std::to_string(static_cast(options_gamepad_->player_id))); + text_->writeCentered(x_, y_, options_gamepad_->name); + text_->writeCentered(x_, y_ + 10, buttons_.at(index_button_).label); } } @@ -55,12 +55,12 @@ void DefineButtons::doControllerButtonDown(const SDL_GamepadButtonEvent &event) // Asigna los botones definidos al input_ void DefineButtons::bindButtons(Options::Gamepad *options_gamepad) { for (const auto &button : buttons_) { - input_->bindGameControllerButton(options_gamepad->instance, button.action, button.button); + Input::bindGameControllerButton(options_gamepad->instance, button.action, button.button); } // Remapea los inputs a inputs - input_->bindGameControllerButton(options_gamepad->instance, Input::Action::SM_SELECT, Input::Action::FIRE_LEFT); - input_->bindGameControllerButton(options_gamepad->instance, Input::Action::SM_BACK, Input::Action::FIRE_CENTER); + Input::bindGameControllerButton(options_gamepad->instance, Input::Action::SM_SELECT, Input::Action::FIRE_LEFT); + Input::bindGameControllerButton(options_gamepad->instance, Input::Action::SM_BACK, Input::Action::FIRE_CENTER); } // Comprueba los eventos @@ -121,9 +121,9 @@ void DefineButtons::clearButtons() { // Comprueba si ha finalizado void DefineButtons::checkEnd() { if (finished_) { - bindButtons(options_gamepad_); // Asigna los botones definidos al input_ - input_->saveGamepadConfigFromGamepad(options_gamepad_->instance); // Guarda los cambios - input_->resetInputStates(); // Reinicia los estados de las pulsaciones de los botones - enabled_ = false; // Deshabilita + bindButtons(options_gamepad_); // Asigna los botones definidos al input_ + input_->saveGamepadConfigFromGamepad(options_gamepad_->instance); // Guarda los cambios + input_->resetInputStates(); // Reinicia los estados de las pulsaciones de los botones + enabled_ = false; // Deshabilita } } \ No newline at end of file diff --git a/source/define_buttons.h b/source/define_buttons.h index 74c6667..a860509 100644 --- a/source/define_buttons.h +++ b/source/define_buttons.h @@ -3,13 +3,15 @@ #include // Para SDL_GamepadButton, SDL_Event, SDL_GamepadButtonEvent #include // Para size_t -#include // Para shared_ptr -#include // Para basic_string, string -#include -#include // Para vector +#include // Para string +#include // Para move +#include // Para vector -#include "input.h" -#include "options.h" +#include "input.h" // Para Input + +namespace Options { +struct Gamepad; +} // namespace Options // Clase DefineButtons class DefineButtons { diff --git a/source/director.cpp b/source/director.cpp index bd91119..f0131aa 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -1,33 +1,32 @@ // IWYU pragma: no_include #include "director.h" -#include // Para SDL_Scancode, SDL_GamepadButton, SDL_LogCategory, SDL_LogInfo, SDL_SetLogPriority, SDL_LogPriority, SDL_Quit +#include // Para SDL_LogCategory, SDL_LogInfo, SDL_SetLogPriority, SDL_LogPriority, SDL_Quit #include // Para mkdir, stat, S_IRWXU #include // Para getuid -#include // Para min #include // Para errno, EEXIST, EACCES, ENAMETOOLONG #include // Para printf, perror -#include // Para exit, EXIT_FAILURE, size_t, srand, rand, system +#include // Para exit, EXIT_FAILURE, srand, rand, system #include // Para time #include // Para make_unique, unique_ptr #include // Para span #include // Para runtime_error #include // Para operator+, allocator, char_traits, operator==, string, basic_string -#include // Para vector #include "asset.h" // Para Asset, AssetType #include "audio.h" // Para Audio -#include "input.h" // Para Input, InputAction +#include "input.h" // Para Input #include "lang.h" // Para setLanguage #include "manage_hiscore_table.h" // Para ManageHiScoreTable -#include "options.h" // Para GamepadOptions, controllers, loadFromFile, saveToFile, SettingsOptions, settings, getPlayerWhoUsesKeyboard, setKeyboardToPlayer +#include "options.h" // Para loadFromFile, saveToFile, Settings, settings, setConfigFile, setControllersFile #include "param.h" // Para loadParamsFromFile +#include "player.h" // Para Player #include "resource.h" // Para Resource #include "screen.h" // Para Screen #include "section.hpp" // Para Name, Options, name, options, AttractMode, attract_mode #include "sections/credits.h" // Para Credits -#include "sections/game.h" // Para Game, GAME_MODE_DEMO_OFF, GAME_MODE_DEMO_ON +#include "sections/game.h" // Para Game #include "sections/hiscore_table.h" // Para HiScoreTable #include "sections/instructions.h" // Para Instructions #include "sections/intro.h" // Para Intro @@ -82,13 +81,13 @@ Director::~Director() { // Inicializa todo void Director::init() { // Configuración inicial de parametros - Asset::init(executable_path_); // Inicializa el sistema de gestión de archivos - setFileList(); // Crea el índice de archivos - + Asset::init(executable_path_); // Inicializa el sistema de gestión de archivos + setFileList(); // Crea el índice de archivos + Input::init( Asset::get()->get("gamecontrollerdb.txt"), Asset::get()->get("controllers.json")); // Carga configuración de controles - + Options::setConfigFile(Asset::get()->get("config.txt")); // Establece el fichero de configuración Options::setControllersFile(Asset::get()->get("controllers.json")); // Establece el fichero de configuración de mandos Options::loadFromFile(); // Carga el archivo de configuración @@ -100,7 +99,7 @@ void Director::init() { Screen::init(); // Inicializa la pantalla y el sistema de renderizado Audio::init(); // Activa el sistema de audio Resource::init(); // Inicializa el sistema de gestión de recursos - //bindInputs(); // Asigna los controles a la entrada del sistema + // bindInputs(); // Asigna los controles a la entrada del sistema ServiceMenu::init(); // Inicializa el menú de servicio Notifier::init(std::string(), Resource::get()->getText("8bithud")); // Inicialización del sistema de notificaciones diff --git a/source/external/jail_audio.cpp b/source/external/jail_audio.cpp index 477e520..ba7f6c1 100644 --- a/source/external/jail_audio.cpp +++ b/source/external/jail_audio.cpp @@ -1,8 +1,13 @@ #ifndef JA_USESDLMIXER #include "jail_audio.h" -#include "stb_vorbis.h" -#include -#include + +#include // Para SDL_AudioFormat, SDL_BindAudioStream, SDL_SetAudioStreamGain, SDL_PutAudioStreamData, SDL_DestroyAudioStream, SDL_GetAudioStreamAvailable, Uint8, SDL_CreateAudioStream, SDL_UnbindAudioStream, Uint32, SDL_CloseAudioDevice, SDL_GetTicks, SDL_Log, SDL_free, SDL_AudioSpec, SDL_AudioStream, SDL_IOFromMem, SDL_LoadWAV, SDL_LoadWAV_IO, SDL_OpenAudioDevice, SDL_clamp, SDL_malloc, SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, SDL_AudioDeviceID, SDL_memcpy +#include // Para uint32_t, uint8_t +#include // Para NULL, fseek, printf, fclose, fopen, fread, ftell, FILE, SEEK_END, SEEK_SET +#include // Para free, malloc +#include // Para strcpy, strlen + +#include "stb_vorbis.h" // Para stb_vorbis_decode_memory #define JA_MAX_SIMULTANEOUS_CHANNELS 20 #define JA_MAX_GROUPS 2 diff --git a/source/gamepad_config_manager.h b/source/gamepad_config_manager.h index 7d88eb6..f52ee0c 100644 --- a/source/gamepad_config_manager.h +++ b/source/gamepad_config_manager.h @@ -1,10 +1,11 @@ #pragma once -#include #include #include #include +#include #include +#include "external/json.hpp" #include "input_types.h" // Solo incluimos los tipos compartidos struct GamepadConfig { @@ -12,9 +13,9 @@ struct GamepadConfig { std::string path; // Ruta física del dispositivo std::unordered_map bindings; // Asociación acción-botón - GamepadConfig(const std::string& name, const std::string& path) - : name(name), - path(path), + GamepadConfig(std::string name, std::string path) + : name(std::move(name)), + path(std::move(path)), bindings{ {InputAction::FIRE_LEFT, SDL_GAMEPAD_BUTTON_WEST}, {InputAction::FIRE_CENTER, SDL_GAMEPAD_BUTTON_NORTH}, @@ -33,28 +34,28 @@ using GamepadConfigs = std::vector; class GamepadConfigManager { public: // Escribir vector de GamepadConfig a archivo JSON - static bool writeToJson(const GamepadConfigs& configs, const std::string& filename) { + static auto writeToJson(const GamepadConfigs& configs, const std::string& filename) -> bool { try { nlohmann::json j; j["gamepads"] = nlohmann::json::array(); for (const auto& config : configs) { - nlohmann::json gamepadJson; - gamepadJson["name"] = config.name; - gamepadJson["path"] = config.path; - gamepadJson["bindings"] = nlohmann::json::object(); + nlohmann::json gamepad_json; + gamepad_json["name"] = config.name; + gamepad_json["path"] = config.path; + gamepad_json["bindings"] = nlohmann::json::object(); // Convertir bindings a JSON for (const auto& [action, button] : config.bindings) { - auto actionIt = actionToString.find(action); - auto buttonIt = buttonToString.find(button); + auto action_it = ACTION_TO_STRING.find(action); + auto button_it = BUTTON_TO_STRING.find(button); - if (actionIt != actionToString.end() && buttonIt != buttonToString.end()) { - gamepadJson["bindings"][actionIt->second] = buttonIt->second; + if (action_it != ACTION_TO_STRING.end() && button_it != BUTTON_TO_STRING.end()) { + gamepad_json["bindings"][action_it->second] = button_it->second; } } - j["gamepads"].push_back(gamepadJson); + j["gamepads"].push_back(gamepad_json); } // Escribir al archivo @@ -74,7 +75,7 @@ class GamepadConfigManager { } // Leer vector de GamepadConfig desde archivo JSON - static bool readFromJson(GamepadConfigs& configs, const std::string& filename) { + static auto readFromJson(GamepadConfigs& configs, const std::string& filename) -> bool { try { std::ifstream file(filename); if (!file.is_open()) { @@ -91,25 +92,25 @@ class GamepadConfigManager { return false; } - for (const auto& gamepadJson : j["gamepads"]) { - if (!gamepadJson.contains("name") || !gamepadJson.contains("bindings")) { + for (const auto& gamepad_json : j["gamepads"]) { + if (!gamepad_json.contains("name") || !gamepad_json.contains("bindings")) { continue; // Saltar configuraciones malformadas } // Leer el campo path si existe, si no dejarlo vacío - std::string path = gamepadJson.contains("path") ? gamepadJson["path"].get() : ""; - GamepadConfig config(gamepadJson["name"], path); + std::string path = gamepad_json.contains("path") ? gamepad_json["path"].get() : ""; + GamepadConfig config(gamepad_json["name"], path); // Limpiar bindings por defecto para cargar los del archivo config.bindings.clear(); // Cargar bindings desde JSON - for (const auto& [actionStr, buttonStr] : gamepadJson["bindings"].items()) { - auto actionIt = stringToAction.find(actionStr); - auto buttonIt = stringToButton.find(buttonStr); + for (const auto& [actionStr, buttonStr] : gamepad_json["bindings"].items()) { + auto action_it = STRING_TO_ACTION.find(actionStr); + auto button_it = STRING_TO_BUTTON.find(buttonStr); - if (actionIt != stringToAction.end() && buttonIt != stringToButton.end()) { - config.bindings[actionIt->second] = buttonIt->second; + if (action_it != STRING_TO_ACTION.end() && button_it != STRING_TO_BUTTON.end()) { + config.bindings[action_it->second] = button_it->second; } } @@ -125,7 +126,7 @@ class GamepadConfigManager { } // Método auxiliar para verificar si un archivo existe - static bool fileExists(const std::string& filename) { + static auto fileExists(const std::string& filename) -> bool { std::ifstream file(filename); return file.good(); } diff --git a/source/global_events.cpp b/source/global_events.cpp index 868017d..2477d84 100644 --- a/source/global_events.cpp +++ b/source/global_events.cpp @@ -2,10 +2,10 @@ #include // Para SDL_LogInfo, SDL_LogCategory +#include "input.h" #include "mouse.h" // Para handleEvent #include "screen.h" #include "section.hpp" // Para Name, Options, name, options -#include "input.h" namespace GlobalEvents { // Comprueba los eventos que se pueden producir en cualquier sección del juego @@ -30,8 +30,8 @@ void check(const SDL_Event &event) { } Mouse::handleEvent(event); - - static auto input = Input::get(); - input->handleEvent(event); + + static auto *input_ = Input::get(); + input_->handleEvent(event); } } // namespace GlobalEvents \ No newline at end of file diff --git a/source/global_inputs.cpp b/source/global_inputs.cpp index fb05cb7..2975b9b 100644 --- a/source/global_inputs.cpp +++ b/source/global_inputs.cpp @@ -1,13 +1,15 @@ #include "global_inputs.h" +#include // Para shared_ptr #include // Para operator+, allocator, char_traits, to_string, string #include // Para vector #include "asset.h" // Para Asset #include "audio.h" // Para Audio -#include "input.h" // Para Input, Input::DO_NOT_ALLOW_REPEAT, InputAction, InputDevice +#include "input.h" // Para Input +#include "input_types.h" // Para InputAction #include "lang.h" // Para getText, Code, getNextLangCode, loadFromFile -#include "options.h" // Para SettingsOptions, settings, VideoOptions, WindowOptions, video, window, AudioOptions, audio +#include "options.h" // Para Settings, settings, Video, Window, video, window, Audio, audio #include "screen.h" // Para Screen #include "section.hpp" // Para Name, name, Options, options, AttractMode, attract_mode #include "ui/notifier.h" // Para Notifier @@ -228,7 +230,7 @@ auto checkServiceInputs() -> bool { // Mandos { - auto gamepads = Input::get()->getGamepads(); + auto gamepads = Input::get()->getGamepads(); for (auto gamepad : gamepads) { // Arriba if (Input::get()->checkAction(Input::Action::UP, Input::DO_NOT_ALLOW_REPEAT, Input::DO_NOT_CHECK_KEYBOARD, gamepad)) { diff --git a/source/hit.h b/source/hit.h index 14cc2c7..1913341 100644 --- a/source/hit.h +++ b/source/hit.h @@ -11,10 +11,10 @@ struct Hit { private: // Indica si el Hit está activo o no - bool enabled{false}; + bool enabled_{false}; // Sprite asociado al Hit, gestionado con un puntero único - std::unique_ptr sprite; + std::unique_ptr sprite_; public: // Elimina el constructor por defecto para obligar a pasar una textura @@ -23,22 +23,22 @@ struct Hit { // Constructor que obliga a pasar una textura compartida para crear el Sprite // Esto evita que se pueda crear un Hit sin recursos gráficos válidos explicit Hit(std::shared_ptr texture) - : sprite(std::make_unique(texture)) {} + : sprite_(std::make_unique(texture)) {} // Establece la posición del Sprite en el espacio void setPos(SDL_FPoint position) { - SDL_FPoint centered_position = {position.x - (sprite->getWidth() / 2), position.y - (sprite->getHeight() / 2)}; - sprite->setPosition(centered_position); + SDL_FPoint centered_position = {position.x - (sprite_->getWidth() / 2), position.y - (sprite_->getHeight() / 2)}; + sprite_->setPosition(centered_position); } // Activa o desactiva el Hit void enable(bool value) { - enabled = value; + enabled_ = value; } // Consulta si el Hit está activo - bool isEnabled() const { - return enabled; + [[nodiscard]] auto isEnabled() const -> bool { + return enabled_; } // Crea un "Hit" en la posición especificada @@ -49,13 +49,13 @@ struct Hit { // Dibuja el hit void render() { - if (enabled) { - sprite->render(); + if (enabled_) { + sprite_->render(); } } // Deshabilita el hit void disable() { - enabled = false; + enabled_ = false; } }; diff --git a/source/input.cpp b/source/input.cpp index cae33f3..a86a8d2 100644 --- a/source/input.cpp +++ b/source/input.cpp @@ -1,13 +1,12 @@ #include "input.h" -#include // Para SDL_LogInfo, SDL_LogCategory, SDL_GetGamepa... +#include // Para SDL_GamepadButton, SDL_GetGamepadAxis, SDL_GetError, SDL_GamepadAxis, SDL_JoystickID, SDL_AddGamepadMappingsFromFile, SDL_Event, SDL_EventType, SDL_GetGamepadButton, SDL_GetKeyboardState, SDL_INIT_GAMEPAD, SDL_InitSubSystem, SDL_LogCategory, SDL_LogError, SDL_LogInfo, SDL_OpenGamepad, SDL_PollEvent, SDL_WasInit, SDL_Gamepad, SDL_Scancode -#include // Para find -#include // Para size_t -#include // Para distance -#include // Para std::unique_ptr -#include // Para unordered_map, _Node_const_iterator, operat... -#include // Para pair +#include // Para find_if, remove_if +#include // Para basic_ostream, operator<<, endl, cout, cerr +#include // Para shared_ptr, __shared_ptr_access, allocator, operator==, make_shared +#include // Para unordered_map, operator==, _Node_iterator_base, _Node_iterator, _Node_const_iterator +#include // Para pair, move // Singleton Input *Input::instance = nullptr; @@ -29,9 +28,6 @@ Input::Input(std::string game_controller_db_path, std::string gamepad_configs_fi gamepad_configs_file_(std::move(gamepad_configs_file)) { // Inicializa el subsistema SDL_INIT_GAMEPAD initSDLGamePad(); - - // Listado de los inputs para jugar que utilizan botones, ni palancas ni crucetas - button_inputs_ = {Action::FIRE_LEFT, Action::FIRE_CENTER, Action::FIRE_RIGHT, Action::START}; } // Asigna inputs a teclas @@ -47,13 +43,13 @@ void Input::bindGameControllerButton(std::shared_ptr gamepad, Action ac } // Asigna inputs a botones del mando -void Input::bindGameControllerButton(std::shared_ptr gamepad, Action input_target, Action input_source) { +void Input::bindGameControllerButton(std::shared_ptr gamepad, Action action_target, Action action_source) { if (gamepad != nullptr) { - gamepad->bindings[input_target].button = gamepad->bindings[input_source].button; + gamepad->bindings[action_target].button = gamepad->bindings[action_source].button; } } -// Comprueba si un input esta activo +// Comprueba si alguna acción está activa auto Input::checkAction(Action action, bool repeat, bool check_keyboard, std::shared_ptr gamepad) -> bool { bool success_keyboard = false; bool success_controller = false; @@ -81,7 +77,7 @@ auto Input::checkAction(Action action, bool repeat, bool check_keyboard, std::sh return (success_keyboard || success_controller); } -// Comprueba si hay almenos un input activo +// Comprueba si hay almenos una acción activa auto Input::checkAnyInput(bool check_keyboard, std::shared_ptr gamepad) -> bool { // Obtenemos el número total de acciones posibles para iterar sobre ellas. @@ -115,7 +111,7 @@ auto Input::checkAnyInput(bool check_keyboard, std::shared_ptr gamepad) // Comprueba si hay algún botón pulsado auto Input::checkAnyButton(bool repeat) -> bool { // Solo comprueba los botones definidos previamente - for (auto bi : button_inputs_) { + for (auto bi : BUTTON_INPUTS) { // Comprueba el teclado if (checkAction(bi, repeat, CHECK_KEYBOARD)) { return true; @@ -136,7 +132,7 @@ auto Input::checkAnyButton(bool repeat) -> bool { auto Input::gameControllerFound() const -> bool { return !gamepads_.empty(); } // Obten el nombre de un mando de juego -auto Input::getControllerName(std::shared_ptr gamepad) const -> std::string { return gamepad == nullptr ? std::string() : gamepad->name; } +auto Input::getControllerName(std::shared_ptr gamepad) -> std::string { return gamepad == nullptr ? std::string() : gamepad->name; } // Obtiene la lista de nombres de mandos auto Input::getControllerNames() const -> std::vector { @@ -151,7 +147,7 @@ auto Input::getControllerNames() const -> std::vector { auto Input::getNumGamepads() const -> int { return gamepads_.size(); } // Obtiene el gamepad a partir de un event.id -std::shared_ptr Input::getGamepad(SDL_JoystickID id) const { +auto Input::getGamepad(SDL_JoystickID id) const -> std::shared_ptr { for (const auto &gamepad : gamepads_) { if (gamepad->instance_id == id) { return gamepad; @@ -160,7 +156,7 @@ std::shared_ptr Input::getGamepad(SDL_JoystickID id) const { return nullptr; } -std::shared_ptr Input::getGamepadByName(const std::string &name) const { +auto Input::getGamepadByName(const std::string &name) const -> std::shared_ptr { for (const auto &gamepad : gamepads_) { if (gamepad && gamepad->name == name) { return gamepad; @@ -169,14 +165,14 @@ std::shared_ptr Input::getGamepadByName(const std::string &name) return nullptr; } -// Obtiene el SDL_GamepadButton asignado a un input -auto Input::getControllerBinding(std::shared_ptr gamepad, Action input) const -> SDL_GamepadButton { - return gamepad->bindings[input].button; +// Obtiene el SDL_GamepadButton asignado a un action +auto Input::getControllerBinding(std::shared_ptr gamepad, Action action) -> SDL_GamepadButton { + return gamepad->bindings[action].button; } // Convierte un InputAction a std::string -auto Input::inputToString(Action input) -> std::string { - switch (input) { +auto Input::inputToString(Action action) -> std::string { + switch (action) { case Action::FIRE_LEFT: return "input_fire_left"; case Action::FIRE_CENTER: @@ -206,11 +202,11 @@ auto Input::stringToInput(const std::string &name) -> Action { } // Comprueba el eje del mando -auto Input::checkAxisInput(Action input, std::shared_ptr gamepad, bool repeat) -> bool { +auto Input::checkAxisInput(Action action, std::shared_ptr gamepad, bool repeat) -> bool { // Umbral para considerar el eje como activo bool axis_active_now = false; - switch (input) { + switch (action) { case Action::LEFT: axis_active_now = SDL_GetGamepadAxis(gamepad->pad, SDL_GAMEPAD_AXIS_LEFTX) < -AXIS_THRESHOLD; break; @@ -228,7 +224,7 @@ auto Input::checkAxisInput(Action input, std::shared_ptr gamepad, bool } // Referencia al binding correspondiente - auto &binding = gamepad->bindings[input]; + auto &binding = gamepad->bindings[action]; if (repeat) { // Si se permite repetir, simplemente devolvemos el estado actual @@ -315,17 +311,17 @@ void Input::update() { void Input::handleEvent(const SDL_Event &event) { switch (event.type) { case SDL_EVENT_GAMEPAD_ADDED: - add_gamepad(event.gdevice.which); + addGamepad(event.gdevice.which); break; case SDL_EVENT_GAMEPAD_REMOVED: - remove_gamepad(event.gdevice.which); + removeGamepad(event.gdevice.which); break; } } -void Input::add_gamepad(int device_index) { +void Input::addGamepad(int device_index) { SDL_Gamepad *pad = SDL_OpenGamepad(device_index); - if (!pad) { + if (pad == nullptr) { std::cerr << "Error al abrir el gamepad: " << SDL_GetError() << std::endl; return; } @@ -337,7 +333,7 @@ void Input::add_gamepad(int device_index) { gamepads_.push_back(std::move(gamepad)); } -void Input::remove_gamepad(SDL_JoystickID id) { +void Input::removeGamepad(SDL_JoystickID id) { auto it = std::remove_if(gamepads_.begin(), gamepads_.end(), [id](const std::shared_ptr &gamepad) { return gamepad->instance_id == id; }); @@ -358,7 +354,7 @@ void Input::printConnectedGamepads() const { std::cout << "Gamepads conectados:\n"; for (const auto &gamepad : gamepads_) { - std::string name = gamepad->name == "" ? "Desconocido" : gamepad->name; + std::string name = gamepad->name.empty() ? "Desconocido" : gamepad->name; std::cout << " - ID: " << gamepad->instance_id << ", Nombre: " << name << ")" << std::endl; } @@ -375,20 +371,19 @@ void Input::saveGamepadConfigs() { } void Input::applyGamepadConfig(std::shared_ptr gamepad) { - if (!gamepad || gamepad->path.empty()) { // No podemos aplicar config sin una ruta + if (!gamepad || gamepad->path.empty()) { // No podemos aplicar config sin una ruta return; } // --- Buscar configuración por RUTA (path) --- - auto configIt = std::find_if(gamepad_configs_.begin(), gamepad_configs_.end(), - [&gamepad](const GamepadConfig &config) { - return config.path == gamepad->path; + auto config_it = std::find_if(gamepad_configs_.begin(), gamepad_configs_.end(), [&gamepad](const GamepadConfig &config) { + return config.path == gamepad->path; }); - if (configIt != gamepad_configs_.end()) { + if (config_it != gamepad_configs_.end()) { // Se encontró una configuración específica para este puerto/dispositivo. La aplicamos. std::cout << "Applying custom config for gamepad at path: " << gamepad->path << std::endl; - for (const auto &[action, button] : configIt->bindings) { + for (const auto &[action, button] : config_it->bindings) { if (gamepad->bindings.find(action) != gamepad->bindings.end()) { gamepad->bindings[action].button = button; } @@ -398,31 +393,30 @@ void Input::applyGamepadConfig(std::shared_ptr gamepad) { } void Input::saveGamepadConfigFromGamepad(std::shared_ptr gamepad) { - if (!gamepad || gamepad->path.empty()) { // No podemos guardar una config sin una ruta + if (!gamepad || gamepad->path.empty()) { // No podemos guardar una config sin una ruta return; } // --- CAMBIO CLAVE: Buscar si ya existe una configuración por RUTA (path) --- - auto configIt = std::find_if(gamepad_configs_.begin(), gamepad_configs_.end(), - [&gamepad](const GamepadConfig &config) { - return config.path == gamepad->path; + auto config_it = std::find_if(gamepad_configs_.begin(), gamepad_configs_.end(), [&gamepad](const GamepadConfig &config) { + return config.path == gamepad->path; }); // Crear nueva configuración desde el gamepad, incluyendo nombre y ruta - GamepadConfig newConfig(gamepad->name, gamepad->path); // <--- CAMBIO: Pasamos ambos - newConfig.bindings.clear(); + GamepadConfig new_config(gamepad->name, gamepad->path); // <--- CAMBIO: Pasamos ambos + new_config.bindings.clear(); // Copiar todos los bindings actuales del gamepad for (const auto &[action, buttonState] : gamepad->bindings) { - newConfig.bindings[action] = buttonState.button; + new_config.bindings[action] = buttonState.button; } - if (configIt != gamepad_configs_.end()) { + if (config_it != gamepad_configs_.end()) { // Sobreescribir configuración existente para esta ruta - *configIt = newConfig; + *config_it = new_config; } else { // Añadir nueva configuración - gamepad_configs_.push_back(newConfig); + gamepad_configs_.push_back(new_config); } // Guardar cambios inmediatamente @@ -436,22 +430,22 @@ void Input::setGamepadConfigsFile(const std::string &filename) { } // Método para obtener configuración de un gamepad específico (opcional) -GamepadConfig *Input::getGamepadConfig(const std::string &gamepadName) { - auto configIt = std::find_if(gamepad_configs_.begin(), gamepad_configs_.end(), [&gamepadName](const GamepadConfig &config) { - return config.name == gamepadName; +auto Input::getGamepadConfig(const std::string &gamepad_name) -> GamepadConfig * { + auto config_it = std::find_if(gamepad_configs_.begin(), gamepad_configs_.end(), [&gamepad_name](const GamepadConfig &config) { + return config.name == gamepad_name; }); - return (configIt != gamepad_configs_.end()) ? &(*configIt) : nullptr; + return (config_it != gamepad_configs_.end()) ? &(*config_it) : nullptr; } // Método para eliminar configuración de gamepad (opcional) -bool Input::removeGamepadConfig(const std::string &gamepadName) { - auto configIt = std::find_if(gamepad_configs_.begin(), gamepad_configs_.end(), [&gamepadName](const GamepadConfig &config) { - return config.name == gamepadName; +auto Input::removeGamepadConfig(const std::string &gamepad_name) -> bool { + auto config_it = std::find_if(gamepad_configs_.begin(), gamepad_configs_.end(), [&gamepad_name](const GamepadConfig &config) { + return config.name == gamepad_name; }); - if (configIt != gamepad_configs_.end()) { - gamepad_configs_.erase(configIt); + if (config_it != gamepad_configs_.end()) { + gamepad_configs_.erase(config_it); saveGamepadConfigs(); return true; } @@ -459,7 +453,7 @@ bool Input::removeGamepadConfig(const std::string &gamepadName) { return false; } -std::shared_ptr Input::findAvailableGamepadByName(const std::string &gamepad_name) { +auto Input::findAvailableGamepadByName(const std::string &gamepad_name) -> std::shared_ptr { // Si no hay gamepads disponibles, devolver gamepad por defecto if (gamepads_.empty()) { return nullptr; diff --git a/source/input.h b/source/input.h index 1aafad9..4c8dd2a 100644 --- a/source/input.h +++ b/source/input.h @@ -1,15 +1,15 @@ #pragma once -#include +#include // Para SDL_Scancode, SDL_GamepadButton, SDL_JoystickID, SDL_CloseGamepad, SDL_Gamepad, SDL_GetGamepadJoystick, SDL_GetGamepadName, SDL_GetGamepadPath, SDL_GetJoystickID, Uint8, SDL_Event, Sint16 -#include -#include -#include -#include -#include +#include // Para array +#include // Para shared_ptr, allocator +#include // Para string +#include // Para unordered_map +#include // Para vector -#include "gamepad_config_manager.h" -#include "input_types.h" +#include "gamepad_config_manager.h" // Para GamepadConfig (ptr only), GamepadConfigs +#include "input_types.h" // Para InputAction // Clase Input: gestiona la entrada de teclado y mandos (singleton) class Input { @@ -121,7 +121,7 @@ class Input { {Action::SM_BACK, ButtonState(SDL_GAMEPAD_BUTTON_NORTH)}} {} ~Gamepad() { - if (pad) { + if (pad != nullptr) { SDL_CloseGamepad(pad); } } @@ -140,28 +140,28 @@ class Input { static auto get() -> Input *; // --- Métodos de configuración de controles --- - void bindKey(Action input, SDL_Scancode code); - void bindGameControllerButton(std::shared_ptr gamepad, Action input, SDL_GamepadButton button); - void bindGameControllerButton(std::shared_ptr gamepad, Action input_target, Action input_source); + void bindKey(Action action, SDL_Scancode code); + static void bindGameControllerButton(std::shared_ptr gamepad, Action action, SDL_GamepadButton button); + static void bindGameControllerButton(std::shared_ptr gamepad, Action action_target, Action action_source); // --- Métodos de consulta de entrada --- void update(); - auto checkAction(Action input, bool repeat = true, bool check_keyboard = true, std::shared_ptr gamepad = nullptr) -> bool; + auto checkAction(Action action, bool repeat = true, bool check_keyboard = true, std::shared_ptr gamepad = nullptr) -> bool; auto checkAnyInput(bool check_keyboard = true, std::shared_ptr gamepad = nullptr) -> bool; auto checkAnyButton(bool repeat = DO_NOT_ALLOW_REPEAT) -> bool; // --- Métodos de gestión de mandos --- [[nodiscard]] auto gameControllerFound() const -> bool; - auto getControllerName(std::shared_ptr gamepad) const -> std::string; + static auto getControllerName(std::shared_ptr gamepad) -> std::string; auto getControllerNames() const -> std::vector; [[nodiscard]] auto getNumGamepads() const -> int; - std::shared_ptr getGamepad(SDL_JoystickID id) const; - std::shared_ptr getGamepadByName(const std::string &name) const; - const Gamepads &getGamepads() const { return gamepads_; } + auto getGamepad(SDL_JoystickID id) const -> std::shared_ptr; + auto getGamepadByName(const std::string &name) const -> std::shared_ptr; + auto getGamepads() const -> const Gamepads & { return gamepads_; } // --- Métodos de consulta y utilidades --- - [[nodiscard]] auto getControllerBinding(std::shared_ptr gamepad, Action input) const -> SDL_GamepadButton; - [[nodiscard]] static auto inputToString(Action input) -> std::string; + [[nodiscard]] static auto getControllerBinding(std::shared_ptr gamepad, Action action) -> SDL_GamepadButton; + [[nodiscard]] static auto inputToString(Action action) -> std::string; [[nodiscard]] static auto stringToInput(const std::string &name) -> Action; // --- Métodos de reseteo de estado de entrada --- @@ -172,26 +172,26 @@ class Input { void printConnectedGamepads() const; - std::shared_ptr findAvailableGamepadByName(const std::string &gamepad_name); + auto findAvailableGamepadByName(const std::string &gamepad_name) -> std::shared_ptr; void saveGamepadConfigFromGamepad(std::shared_ptr gamepad); private: // --- Constantes --- static constexpr Sint16 AXIS_THRESHOLD = 30000; + static constexpr std::array BUTTON_INPUTS = {Action::FIRE_LEFT, Action::FIRE_CENTER, Action::FIRE_RIGHT, Action::START}; // Listado de los inputs para jugar que utilizan botones, ni palancas ni crucetas // --- Variables internas --- Gamepads gamepads_; Keyboard keyboard_; - std::vector button_inputs_; std::string gamepad_mappings_file_; std::string gamepad_configs_file_; GamepadConfigs gamepad_configs_; // --- Métodos internos --- void initSDLGamePad(); - auto checkAxisInput(Action input, std::shared_ptr gamepad, bool repeat) -> bool; - void add_gamepad(int device_index); - void remove_gamepad(SDL_JoystickID id); + static auto checkAxisInput(Action action, std::shared_ptr gamepad, bool repeat) -> bool; + void addGamepad(int device_index); + void removeGamepad(SDL_JoystickID id); void addGamepadMappingsFromFile(); void discoverGamepads(); @@ -202,8 +202,8 @@ class Input { // Métodos auxiliares opcionales void setGamepadConfigsFile(const std::string &filename); - GamepadConfig *getGamepadConfig(const std::string &gamepadName); - bool removeGamepadConfig(const std::string &gamepadName); + auto getGamepadConfig(const std::string &gamepad_name) -> GamepadConfig *; + auto removeGamepadConfig(const std::string &gamepad_name) -> bool; // --- Constructor y destructor --- explicit Input(std::string game_controller_db_path, std::string gamepad_configs_file); diff --git a/source/input_types.cpp b/source/input_types.cpp index cfa3ef1..48437ac 100644 --- a/source/input_types.cpp +++ b/source/input_types.cpp @@ -1,7 +1,7 @@ #include "input_types.h" // Definición de los mapas -const std::unordered_map actionToString = { +const std::unordered_map ACTION_TO_STRING = { {InputAction::FIRE_LEFT, "FIRE_LEFT"}, {InputAction::FIRE_CENTER, "FIRE_CENTER"}, {InputAction::FIRE_RIGHT, "FIRE_RIGHT"}, @@ -29,10 +29,9 @@ const std::unordered_map actionToString = { {InputAction::CONFIG, "CONFIG"}, {InputAction::SWAP_CONTROLLERS, "SWAP_CONTROLLERS"}, {InputAction::TOGGLE_AUTO_FIRE, "TOGGLE_AUTO_FIRE"}, - {InputAction::NONE, "NONE"} -}; + {InputAction::NONE, "NONE"}}; -const std::unordered_map stringToAction = { +const std::unordered_map STRING_TO_ACTION = { {"FIRE_LEFT", InputAction::FIRE_LEFT}, {"FIRE_CENTER", InputAction::FIRE_CENTER}, {"FIRE_RIGHT", InputAction::FIRE_RIGHT}, @@ -60,10 +59,9 @@ const std::unordered_map stringToAction = { {"CONFIG", InputAction::CONFIG}, {"SWAP_CONTROLLERS", InputAction::SWAP_CONTROLLERS}, {"TOGGLE_AUTO_FIRE", InputAction::TOGGLE_AUTO_FIRE}, - {"NONE", InputAction::NONE} -}; + {"NONE", InputAction::NONE}}; -const std::unordered_map buttonToString = { +const std::unordered_map BUTTON_TO_STRING = { {SDL_GAMEPAD_BUTTON_WEST, "WEST"}, {SDL_GAMEPAD_BUTTON_NORTH, "NORTH"}, {SDL_GAMEPAD_BUTTON_EAST, "EAST"}, @@ -75,10 +73,9 @@ const std::unordered_map buttonToString = { {SDL_GAMEPAD_BUTTON_DPAD_UP, "DPAD_UP"}, {SDL_GAMEPAD_BUTTON_DPAD_DOWN, "DPAD_DOWN"}, {SDL_GAMEPAD_BUTTON_DPAD_LEFT, "DPAD_LEFT"}, - {SDL_GAMEPAD_BUTTON_DPAD_RIGHT, "DPAD_RIGHT"} -}; + {SDL_GAMEPAD_BUTTON_DPAD_RIGHT, "DPAD_RIGHT"}}; -const std::unordered_map stringToButton = { +const std::unordered_map STRING_TO_BUTTON = { {"WEST", SDL_GAMEPAD_BUTTON_WEST}, {"NORTH", SDL_GAMEPAD_BUTTON_NORTH}, {"EAST", SDL_GAMEPAD_BUTTON_EAST}, @@ -90,10 +87,9 @@ const std::unordered_map stringToButton = { {"DPAD_UP", SDL_GAMEPAD_BUTTON_DPAD_UP}, {"DPAD_DOWN", SDL_GAMEPAD_BUTTON_DPAD_DOWN}, {"DPAD_LEFT", SDL_GAMEPAD_BUTTON_DPAD_LEFT}, - {"DPAD_RIGHT", SDL_GAMEPAD_BUTTON_DPAD_RIGHT} -}; + {"DPAD_RIGHT", SDL_GAMEPAD_BUTTON_DPAD_RIGHT}}; -const std::unordered_map actionToAction = { +const std::unordered_map ACTION_TO_ACTION = { {InputAction::SM_SELECT, InputAction::FIRE_LEFT}, {InputAction::SM_BACK, InputAction::FIRE_CENTER}, }; \ No newline at end of file diff --git a/source/input_types.h b/source/input_types.h index 8952cd4..76357b2 100644 --- a/source/input_types.h +++ b/source/input_types.h @@ -1,6 +1,7 @@ #pragma once #include + #include #include @@ -47,8 +48,8 @@ enum class InputAction : int { }; // Mapas para convertir entre enums y strings -extern const std::unordered_map actionToString; -extern const std::unordered_map stringToAction; -extern const std::unordered_map buttonToString; -extern const std::unordered_map stringToButton; -extern const std::unordered_map actionToAction; \ No newline at end of file +extern const std::unordered_map ACTION_TO_STRING; +extern const std::unordered_map STRING_TO_ACTION; +extern const std::unordered_map BUTTON_TO_STRING; +extern const std::unordered_map STRING_TO_BUTTON; +extern const std::unordered_map ACTION_TO_ACTION; \ No newline at end of file diff --git a/source/moving_sprite.cpp b/source/moving_sprite.cpp index 96cd356..0275e6c 100644 --- a/source/moving_sprite.cpp +++ b/source/moving_sprite.cpp @@ -35,8 +35,7 @@ void MovingSprite::clear() { } // Elimina el movimiento del sprite -void MovingSprite::stop() -{ +void MovingSprite::stop() { x_ = 0.0F; // Posición en el eje X y_ = 0.0F; // Posición en el eje Y diff --git a/source/options.cpp b/source/options.cpp index 5a7a824..73798ae 100644 --- a/source/options.cpp +++ b/source/options.cpp @@ -1,9 +1,9 @@ #include "options.h" #include // Para SDL_ScaleMode, SDL_GamepadButton, SDL_LogCategory, SDL_LogInfo, SDL_LogError, SDL_LogWarn -#include // Para size_t #include // Para clamp, max +#include // Para size_t #include // Para basic_ostream, operator<<, basic_ostream::operator<<, basic_ofstream, basic_istream, basic_ifstream, ifstream, ofstream #include // Para function #include // Para map, operator==, _Rb_tree_const_iterator @@ -274,7 +274,7 @@ void checkPendingChanges() { } // Buscar y asignar un mando disponible por nombre -bool assignGamepadByName(const std::string& gamepad_name_to_find, Player::Id player_id) { +auto assignGamepadByName(const std::string& gamepad_name_to_find, Player::Id player_id) -> bool { auto found_gamepad = Input::get()->findAvailableGamepadByName(gamepad_name_to_find); if (found_gamepad) { @@ -284,7 +284,7 @@ bool assignGamepadByName(const std::string& gamepad_name_to_find, Player::Id pla } // Obtener información de un gamepad específico -std::string getGamepadInfo(Player::Id player_id) { +auto getGamepadInfo(Player::Id player_id) -> std::string { try { const auto& gamepad = gamepad_manager.getGamepad(player_id); return "Player " + std::to_string(static_cast(player_id)) + @@ -300,73 +300,77 @@ void GamepadManager::assignAndLinkGamepads() { auto physical_gamepads = Input::get()->getGamepads(); // 2. Reiniciamos las asignaciones actuales y guardamos los datos deseados de la config. - std::array desired_paths; // <--- CAMBIO: Guardamos las rutas deseadas. + std::array desired_paths; for (size_t i = 0; i < MAX_PLAYERS; ++i) { - desired_paths[i] = gamepads[i].path; // <--- CAMBIO: Obtenemos la ruta. - gamepads[i].instance = nullptr; // Limpiamos la instancia + desired_paths[i] = gamepads_[i].path; + gamepads_[i].instance = nullptr; } // 3. Vector para rastrear los mandos físicos que ya hemos asignado. std::vector> assigned_instances; - // --- PRIMERA PASADA: Buscar coincidencias exactas por RUTA (path) --- - // Este es el método más fiable para identificar un mando de forma única. + // --- Ejecutamos las pasadas de asignación --- + assignGamepadsByPath(desired_paths, physical_gamepads, assigned_instances); + assignRemainingGamepads(physical_gamepads, assigned_instances); +} + +// --- PRIMERA PASADA: Intenta asignar mandos basándose en la ruta guardada --- +void GamepadManager::assignGamepadsByPath( + const std::array& desired_paths, + const std::vector>& physical_gamepads, + std::vector>& assigned_instances) { for (size_t i = 0; i < MAX_PLAYERS; ++i) { - const std::string& desired_path = desired_paths[i]; // <--- CAMBIO: Usamos la ruta. + const std::string& desired_path = desired_paths[i]; if (desired_path.empty()) { - continue; // Si no hay una ruta guardada para este slot, lo saltamos. + continue; // No hay ruta guardada para este slot. } - // Buscamos un mando físico que coincida con la ruta deseada. + // Buscamos un mando físico que coincida con la ruta y no esté ya asignado. for (const auto& physical_gamepad : physical_gamepads) { - if (physical_gamepad->path == desired_path) { // <--- CAMBIO: Comparamos por ruta. - // ¡Coincidencia por ruta! Es casi seguro que es el mando correcto. - // La comprobación de 'already_assigned' es una seguridad extra. - bool already_assigned = false; - for (const auto& assigned : assigned_instances) { - if (assigned == physical_gamepad) { - already_assigned = true; - break; - } - } - - if (!already_assigned) { - gamepads[i].instance = physical_gamepad; // Enlazamos la instancia - // No actualizamos el nombre ni la ruta aquí, ya que coinciden con la config. - assigned_instances.push_back(physical_gamepad); // Lo marcamos como asignado - break; // Mando encontrado para este jugador, pasamos al siguiente. - } - } - } - } - - // --- SEGUNDA PASADA: Asignar los mandos restantes a los jugadores sin mando --- - // Esto se ejecuta para slots vacíos o si un mando guardado no se encontró (p. ej. se desconectó). - for (size_t i = 0; i < MAX_PLAYERS; ++i) { - if (gamepads[i].instance == nullptr) { // Si este jugador aún no tiene mando... - - // ...buscamos un mando físico que todavía esté libre. - for (const auto& physical_gamepad : physical_gamepads) { - bool already_assigned = false; - for (const auto& assigned : assigned_instances) { - if (assigned == physical_gamepad) { - already_assigned = true; - break; - } - } - - if (!already_assigned) { - gamepads[i].instance = physical_gamepad; // Se lo asignamos - - // MUY IMPORTANTE: Actualizamos la configuración para reflejar la realidad. - gamepads[i].name = physical_gamepad->name; // Actualizamos el nombre - gamepads[i].path = physical_gamepad->path; // <--- AÑADIDO: Y también la ruta! - - assigned_instances.push_back(physical_gamepad); // Lo marcamos como asignado - break; // Mando encontrado, pasamos al siguiente jugador. - } + if (physical_gamepad->path == desired_path && !isGamepadAssigned(physical_gamepad, assigned_instances)) { + gamepads_[i].instance = physical_gamepad; + assigned_instances.push_back(physical_gamepad); + break; // Mando encontrado para este jugador, pasamos al siguiente. } } } } + +// --- SEGUNDA PASADA: Asigna los mandos físicos restantes a los jugadores libres --- +void GamepadManager::assignRemainingGamepads( + const std::vector>& physical_gamepads, + std::vector>& assigned_instances) { + for (size_t i = 0; i < MAX_PLAYERS; ++i) { + if (gamepads_[i].instance != nullptr) { + continue; // Este jugador ya tiene un mando. + } + + // Buscamos un mando físico que todavía esté libre. + for (const auto& physical_gamepad : physical_gamepads) { + if (!isGamepadAssigned(physical_gamepad, assigned_instances)) { + gamepads_[i].instance = physical_gamepad; + + // MUY IMPORTANTE: Actualizamos la configuración para reflejar la realidad. + gamepads_[i].name = physical_gamepad->name; + gamepads_[i].path = physical_gamepad->path; + + assigned_instances.push_back(physical_gamepad); + break; // Mando encontrado, pasamos al siguiente jugador. + } + } + } +} + +// Función auxiliar para comprobar si un mando físico ya está en la lista de asignados. +// Devuelve 'true' si ya ha sido asignado, 'false' en caso contrario. +auto GamepadManager::isGamepadAssigned( + const std::shared_ptr& physical_gamepad, + const std::vector>& assigned_instances) -> bool { + for (const auto& assigned : assigned_instances) { + if (assigned == physical_gamepad) { + return true; // Encontrado, por lo tanto, ya está asignado. + } + } + return false; // No se encontró en la lista. +} } // namespace Options \ No newline at end of file diff --git a/source/options.h b/source/options.h index 691fdac..c290df4 100644 --- a/source/options.h +++ b/source/options.h @@ -1,19 +1,21 @@ #pragma once -#include // Para SDL_GamepadButton, SDL_ScaleMode +#include // Para SDL_ScaleMode #include // Para copy #include // Para array -#include // Para ofstream -#include // Para excepciones -#include // Para allocator, string -#include -#include // Para vector +#include // Para size_t +#include // Para exception +#include // Para basic_ostream, operator<<, basic_ofstream, basic_ostream::operator<<, ofstream +#include // Para shared_ptr, swap +#include // Para out_of_range, invalid_argument +#include // Para char_traits, string, allocator, operator==, swap, operator<<, basic_string, stoi +#include // Para vector #include "difficulty.h" // Para Code -#include "input.h" // Para InputAction, InputDevice +#include "input.h" // Para Input #include "lang.h" // Para Code -#include "manage_hiscore_table.h" // Para HiScoreEntry +#include "manage_hiscore_table.h" // Para ManageHiScoreTable, Table #include "player.h" // Para Player namespace Options { @@ -106,51 +108,39 @@ struct Gamepad { // --- Manager para los gamepads --- class GamepadManager { - private: - static constexpr size_t MAX_PLAYERS = 2; - std::array gamepads; - - // Convierte Player::Id a índice del array - size_t playerIdToIndex(Player::Id player_id) const { - switch (player_id) { - case Player::Id::PLAYER1: - return 0; - case Player::Id::PLAYER2: - return 1; - default: - throw std::invalid_argument("Invalid player ID"); - } - } - public: void init() { - gamepads[0] = Gamepad(Player::Id::PLAYER1); - gamepads[1] = Gamepad(Player::Id::PLAYER2); + gamepads_[0] = Gamepad(Player::Id::PLAYER1); + gamepads_[1] = Gamepad(Player::Id::PLAYER2); } // Acceso directo por player_id (más intuitivo) - Gamepad& getGamepad(Player::Id player_id) { - return gamepads[playerIdToIndex(player_id)]; + auto getGamepad(Player::Id player_id) -> Gamepad& { + return gamepads_[playerIdToIndex(player_id)]; } - const Gamepad& getGamepad(Player::Id player_id) const { - return gamepads[playerIdToIndex(player_id)]; + [[nodiscard]] auto getGamepad(Player::Id player_id) const -> const Gamepad& { + return gamepads_[playerIdToIndex(player_id)]; } // Acceso por índice (más eficiente si ya tienes el índice) - Gamepad& operator[](size_t index) { - if (index >= MAX_PLAYERS) throw std::out_of_range("Invalid gamepad index"); - return gamepads[index]; + auto operator[](size_t index) -> Gamepad& { + if (index >= MAX_PLAYERS) { + throw std::out_of_range("Invalid gamepad index"); + } + return gamepads_[index]; } - const Gamepad& operator[](size_t index) const { - if (index >= MAX_PLAYERS) throw std::out_of_range("Invalid gamepad index"); - return gamepads[index]; + auto operator[](size_t index) const -> const Gamepad& { + if (index >= MAX_PLAYERS) { + throw std::out_of_range("Invalid gamepad index"); + } + return gamepads_[index]; } - bool assignGamepadToPlayer(Player::Id player_id, + auto assignGamepadToPlayer(Player::Id player_id, std::shared_ptr instance, - const std::string& name) { + const std::string& name) -> bool { try { auto& gamepad = getGamepad(player_id); gamepad.instance = instance; @@ -162,15 +152,15 @@ class GamepadManager { } void swapPlayers() { - std::swap(gamepads[0].instance, gamepads[1].instance); - std::swap(gamepads[0].name, gamepads[1].name); - std::swap(gamepads[0].path, gamepads[1].path); + std::swap(gamepads_[0].instance, gamepads_[1].instance); + std::swap(gamepads_[0].name, gamepads_[1].name); + std::swap(gamepads_[0].path, gamepads_[1].path); } // Para serialización/deserialización void saveToFile(std::ofstream& file) const { for (size_t i = 0; i < MAX_PLAYERS; ++i) { - const auto& gamepad = gamepads[i]; + const auto& gamepad = gamepads_[i]; file << "controller." << i << ".name=" << gamepad.name << "\n"; file << "controller." << i << ".path=" << gamepad.path << "\n"; file << "controller." << i << ".player=" << static_cast(gamepad.player_id) << "\n"; @@ -178,28 +168,33 @@ class GamepadManager { } // Método helper para parseAndSetController - bool setControllerProperty(size_t controller_index, + auto setControllerProperty(size_t controller_index, const std::string& property, - const std::string& value) { - if (controller_index >= MAX_PLAYERS) return false; + const std::string& value) -> bool { + if (controller_index >= MAX_PLAYERS) { + return false; + } - auto& gamepad = gamepads[controller_index]; + auto& gamepad = gamepads_[controller_index]; if (property == "name") { gamepad.name = value; return true; - } else if (property == "path") { + } + if (property == "path") { gamepad.path = value; return true; - } else if (property == "player") { + } + if (property == "player") { try { int player_int = std::stoi(value); - if (player_int == 1) + if (player_int == 1) { gamepad.player_id = Player::Id::PLAYER1; - else if (player_int == 2) + } else if (player_int == 2) { gamepad.player_id = Player::Id::PLAYER2; - else + } else { return false; + } return true; } catch (const std::exception&) { return false; @@ -213,12 +208,39 @@ class GamepadManager { void assignAndLinkGamepads(); // Iteradores - auto begin() { return gamepads.begin(); } - auto end() { return gamepads.end(); } - auto begin() const { return gamepads.begin(); } - auto end() const { return gamepads.end(); } + auto begin() { return gamepads_.begin(); } + auto end() { return gamepads_.end(); } + [[nodiscard]] auto begin() const { return gamepads_.begin(); } + [[nodiscard]] auto end() const { return gamepads_.end(); } - size_t size() const { return MAX_PLAYERS; } + [[nodiscard]] static auto size() -> size_t { return MAX_PLAYERS; } + + private: + static constexpr size_t MAX_PLAYERS = 2; + std::array gamepads_; + + // Convierte Player::Id a índice del array + [[nodiscard]] static auto playerIdToIndex(Player::Id player_id) -> size_t { + switch (player_id) { + case Player::Id::PLAYER1: + return 0; + case Player::Id::PLAYER2: + return 1; + default: + throw std::invalid_argument("Invalid player ID"); + } + } + + void assignGamepadsByPath( + const std::array& desired_paths, + const std::vector>& physical_gamepads, + std::vector>& assigned_instances); + void assignRemainingGamepads( + const std::vector>& physical_gamepads, + std::vector>& assigned_instances); + [[nodiscard]] static auto isGamepadAssigned( + const std::shared_ptr& physical_gamepad, + const std::vector>& assigned_instances) -> bool; }; struct Keyboard { @@ -245,16 +267,16 @@ extern Keyboard keyboard; // Opciones para el teclado extern PendingChanges pending_changes; // Opciones que se aplican al cerrar // --- Funciones de configuración --- -void init(); // Inicializa las opciones del programa -void setConfigFile(const std::string& file_path); // Establece el fichero de configuración -void setControllersFile(const std::string& file_path); // Establece el fichero de configuración de mandos -auto loadFromFile() -> bool; // Carga el fichero de configuración -auto saveToFile() -> bool; // Guarda el fichero de configuración -void setKeyboardToPlayer(Player::Id player_id); // Asigna el teclado al jugador -void swapKeyboard(); // Intercambia el teclado de jugador -void swapControllers(); // Intercambia los jugadores asignados a los dos primeros mandos -auto getPlayerWhoUsesKeyboard() -> Player::Id; // Averigua quién está usando el teclado -void applyPendingChanges(); // Aplica los cambios pendientes copiando los valores a sus variables -void checkPendingChanges(); // Verifica si hay cambios pendientes -bool assignGamepadByName(const std::string& gamepad_name, Player::Id player_id); // Buscar y asignar un mando disponible por nombre +void init(); // Inicializa las opciones del programa +void setConfigFile(const std::string& file_path); // Establece el fichero de configuración +void setControllersFile(const std::string& file_path); // Establece el fichero de configuración de mandos +auto loadFromFile() -> bool; // Carga el fichero de configuración +auto saveToFile() -> bool; // Guarda el fichero de configuración +void setKeyboardToPlayer(Player::Id player_id); // Asigna el teclado al jugador +void swapKeyboard(); // Intercambia el teclado de jugador +void swapControllers(); // Intercambia los jugadores asignados a los dos primeros mandos +auto getPlayerWhoUsesKeyboard() -> Player::Id; // Averigua quién está usando el teclado +void applyPendingChanges(); // Aplica los cambios pendientes copiando los valores a sus variables +void checkPendingChanges(); // Verifica si hay cambios pendientes +auto assignGamepadByName(const std::string& gamepad_name, Player::Id player_id) -> bool; // Buscar y asignar un mando disponible por nombre } // namespace Options \ No newline at end of file diff --git a/source/player.cpp b/source/player.cpp index a99712b..bd7333d 100644 --- a/source/player.cpp +++ b/source/player.cpp @@ -1,6 +1,6 @@ #include "player.h" -#include // Para SDL_GetTicks, SDL_FlipMode, SDL_FRect +#include // Para SDL_GetTicks, SDL_FlipMode #include // Para clamp, max, min #include // Para rand @@ -8,24 +8,25 @@ #include "animated_sprite.h" // Para AnimatedSprite #include "asset.h" // Para Asset #include "audio.h" // Para Audio -#include "input.h" // Para InputAction +#include "input.h" // Para Input +#include "input_types.h" // Para InputAction #include "manage_hiscore_table.h" // Para ManageHiScoreTable, HiScoreEntry #include "param.h" // Para Param, ParamGame, param -#include "scoreboard.h" // Para ScoreboardMode, Scoreboard +#include "scoreboard.h" // Para Scoreboard #include "stage.h" // Para power_can_be_added #include "texture.h" // Para Texture // Constructor -Player::Player(const Config& config) +Player::Player(const Config &config) : player_sprite_(std::make_unique(config.texture.at(0), config.animations.at(0))), power_sprite_(std::make_unique(config.texture.at(1), config.animations.at(1))), enter_name_(std::make_unique()), - id_(config.id), - play_area_(*config.play_area), - default_pos_x_(config.x), - default_pos_y_(config.y), hi_score_table_(*config.hi_score_table), glowing_entry_(*config.glowing_entry), + play_area_(*config.play_area), + id_(config.id), + default_pos_x_(config.x), + default_pos_y_(config.y), demo_(config.demo) { // Configura objetos player_sprite_->getTexture()->setPalette(coffees_); diff --git a/source/player.h b/source/player.h index 4aaede8..e575112 100644 --- a/source/player.h +++ b/source/player.h @@ -2,20 +2,18 @@ #include // Para Uint32, SDL_FRect -#include // Para allocator, unique_ptr, shared_ptr +#include // Para shared_ptr, allocator, unique_ptr #include // Para string #include // Para vector -#include "animated_sprite.h" // Para AnimatedSprite -#include "enter_name.h" // Para EnterName -#include "input.h" -#include "manage_hiscore_table.h" // Para HiScoreEntry +#include "animated_sprite.h" // Para AnimatedSprite +#include "enter_name.h" // Para EnterName +#include "input.h" // Para Input +#include "manage_hiscore_table.h" // Para Table #include "scoreboard.h" // Para Scoreboard #include "utils.h" // Para Circle class Texture; -enum class Action : int; -enum class Mode; // --- Clase Player --- class Player { @@ -88,7 +86,7 @@ class Player { }; // --- Constructor y destructor --- - Player(const Config& config); + Player(const Config &config); ~Player() = default; // --- Inicialización y ciclo de vida --- @@ -185,11 +183,11 @@ class Player { void addCredit() { ++credits_used_; } void setGamepad(std::shared_ptr gamepad) { gamepad_ = gamepad; } - [[nodiscard]] std::shared_ptr getGamepad() const { return gamepad_; } + [[nodiscard]] auto getGamepad() const -> std::shared_ptr { return gamepad_; } void setUsesKeyboard(bool value) { uses_keyboard_ = value; } - [[nodiscard]] bool getUsesKeyboard() const { return uses_keyboard_; } + [[nodiscard]] auto getUsesKeyboard() const -> bool { return uses_keyboard_; } void setHiScoreTable(const Table &table) { hi_score_table_ = table; } - const Table &getHiScoreTable() const { return hi_score_table_; } + [[nodiscard]] auto getHiScoreTable() const -> const Table & { return hi_score_table_; } void setGlowingEntry(const int &entry) { glowing_entry_ = entry; } private: @@ -202,56 +200,64 @@ class Player { static constexpr int WAITING_COUNTER = 1000; // --- Objetos y punteros --- - std::unique_ptr player_sprite_; // Sprite para dibujar el jugador - std::unique_ptr power_sprite_; // Sprite para dibujar el aura del jugador con el poder a tope - std::unique_ptr enter_name_; // Clase utilizada para introducir el nombre + std::unique_ptr player_sprite_; // Sprite para dibujar el jugador + std::unique_ptr power_sprite_; // Sprite para dibujar el aura del jugador con el poder a tope + std::unique_ptr enter_name_; // Clase utilizada para introducir el nombre + std::shared_ptr gamepad_ = nullptr; // Dispositivo asociado + Table &hi_score_table_; // Tabla de máximas puntuaciones + int &glowing_entry_; // Entrada de la tabla de puntuaciones para hacerla brillar + std::string name_; // Nombre del jugador + std::string last_enter_name_; // Último nombre introducido en la tabla de puntuaciones - // --- Variables de estado --- - Id id_; // Identificador para el jugador + // --- Estructuras y enums --- SDL_FRect play_area_; // Rectángulo con la zona de juego - float pos_x_ = 0.0F; // Posición en el eje X - int pos_y_ = 0; // Posición en el eje Y - float default_pos_x_; // Posición inicial para el jugador - int default_pos_y_; // Posición inicial para el jugador - float vel_x_ = 0.0F; // Cantidad de píxeles a desplazarse en el eje X - int vel_y_ = 0.0F; // Cantidad de píxeles a desplazarse en el eje Y - int cant_fire_counter_ = 0; // Contador durante el cual no puede disparar - int recoiling_state_counter_ = 0; // Contador para la animación del estado de retroceso - int recoiling_state_duration_ = 0; // Numero de frames que dura el estado de retroceso - int cooling_state_counter_ = 0; // Contador para la animación del estado cooling - int score_ = 0; // Puntos del jugador - float score_multiplier_ = 1.0F; // Multiplicador de puntos - bool qualifies_for_high_score_ = false; // Indica si tiene una puntuación que le permite entrar en la tabla de records - Table &hi_score_table_; // Tabla de maximas puntuaciones - int &glowing_entry_; // Entrada de la tabla de puntuaciones para hacerla brillar + Circle collider_ = Circle(0, 0, 9); // Círculo de colisión del jugador + Scoreboard::Id scoreboard_panel_ = Scoreboard::Id::LEFT; // Panel del marcador asociado al jugador + Id id_; // Identificador para el jugador State walking_state_ = State::WALKING_STOP; // Estado del jugador al moverse State firing_state_ = State::FIRING_NONE; // Estado del jugador al disparar State playing_state_ = State::WAITING; // Estado del jugador en el juego - bool invulnerable_ = true; // Indica si el jugador es invulnerable - int invulnerable_counter_ = INVULNERABLE_COUNTER; // Contador para la invulnerabilidad - bool extra_hit_ = false; // Indica si el jugador tiene un toque extra - int coffees_ = 0; // Indica cuántos cafés lleva acumulados - bool power_up_ = false; // Indica si el jugador tiene activo el modo PowerUp - int power_up_counter_ = POWERUP_COUNTER; // Temporizador para el modo PowerUp - int power_up_x_offset_ = 0; // Desplazamiento del sprite de PowerUp respecto al sprite del jugador - Circle collider_ = Circle(0, 0, 9); // Círculo de colisión del jugador - int continue_counter_ = 10; // Contador para poder continuar - Uint32 continue_ticks_ = 0; // Variable para poder cambiar el contador de continue en función del tiempo - Scoreboard::Id scoreboard_panel_ = Scoreboard::Id::LEFT; // Panel del marcador asociado al jugador - std::string name_; // Nombre del jugador - int controller_index_ = 0; // Índice del array de mandos que utilizará para moverse - bool demo_ = false; // Para que el jugador sepa si está en el modo demostración - int name_entry_idle_counter_ = 0; // Contador para poner nombre - int name_entry_total_counter_ = 0; // Segundos totales que lleva acumulados poniendo nombre - Uint32 name_entry_ticks_ = 0; // Variable para poder cambiar el contador de poner nombre en función del tiempo - Uint32 showing_name_ticks_ = 0; // Tiempo en el que se entra al estado SHOWING_NAME - int step_counter_ = 0; // Cuenta los pasos para los estados en los que camina automáticamente - bool game_completed_ = false; // Indica si ha completado el juego - int credits_used_ = 0; // Indica el número de veces que ha continuado - std::string last_enter_name_; // Último nombre introducido en la tabla de puntuaciones - int waiting_counter_ = 0; // Contador para el estado de espera - std::shared_ptr gamepad_ = nullptr; // Dispositivo asociado - bool uses_keyboard_ = false; // Indica si usa el teclado como dispositivo de control + + // --- Variables float --- + float pos_x_ = 0.0F; // Posición en el eje X + float default_pos_x_; // Posición inicial para el jugador + float vel_x_ = 0.0F; // Cantidad de píxeles a desplazarse en el eje X + float score_multiplier_ = 1.0F; // Multiplicador de puntos + + // --- Variables int --- + int pos_y_ = 0; // Posición en el eje Y + int default_pos_y_; // Posición inicial para el jugador + int vel_y_ = 0; // Cantidad de píxeles a desplazarse en el eje Y + int cant_fire_counter_ = 0; // Contador durante el cual no puede disparar + int recoiling_state_counter_ = 0; // Contador para la animación del estado de retroceso + int recoiling_state_duration_ = 0; // Número de frames que dura el estado de retroceso + int cooling_state_counter_ = 0; // Contador para la animación del estado cooling + int invulnerable_counter_ = INVULNERABLE_COUNTER; // Contador para la invulnerabilidad + int score_ = 0; // Puntos del jugador + int coffees_ = 0; // Indica cuántos cafés lleva acumulados + int power_up_counter_ = POWERUP_COUNTER; // Temporizador para el modo PowerUp + int power_up_x_offset_ = 0; // Desplazamiento del sprite de PowerUp respecto al sprite del jugador + int continue_counter_ = 10; // Contador para poder continuar + int controller_index_ = 0; // Índice del array de mandos que utilizará para moverse + int name_entry_idle_counter_ = 0; // Contador para poner nombre + int name_entry_total_counter_ = 0; // Segundos totales que lleva acumulados poniendo nombre + int step_counter_ = 0; // Cuenta los pasos para los estados en los que camina automáticamente + int credits_used_ = 0; // Indica el número de veces que ha continuado + int waiting_counter_ = 0; // Contador para el estado de espera + + // --- Variables Uint32 --- + Uint32 continue_ticks_ = 0; // Variable para poder cambiar el contador de continue en función del tiempo + Uint32 name_entry_ticks_ = 0; // Variable para poder cambiar el contador de poner nombre en función del tiempo + Uint32 showing_name_ticks_ = 0; // Tiempo en el que se entra al estado SHOWING_NAME + + // --- Flags booleanas --- + bool qualifies_for_high_score_ = false; // Indica si tiene una puntuación que le permite entrar en la tabla de records + bool invulnerable_ = true; // Indica si el jugador es invulnerable + bool extra_hit_ = false; // Indica si el jugador tiene un toque extra + bool power_up_ = false; // Indica si el jugador tiene activo el modo PowerUp + bool demo_ = false; // Para que el jugador sepa si está en el modo demostración + bool game_completed_ = false; // Indica si ha completado el juego + bool uses_keyboard_ = false; // Indica si usa el teclado como dispositivo de control // --- Métodos internos --- void shiftColliders(); // Actualiza el círculo de colisión a la posición del jugador diff --git a/source/sections/credits.cpp b/source/sections/credits.cpp index 8256980..f6aef8d 100644 --- a/source/sections/credits.cpp +++ b/source/sections/credits.cpp @@ -104,17 +104,16 @@ void Credits::update() { fillCanvas(); } - static const auto audio = Audio::get(); - audio->update(); + Audio::update(); } // Dibuja Credits::en patalla void Credits::render() { - static const auto screen = Screen::get(); + static auto *const SCREEN = Screen::get(); - screen->start(); // Prepara para empezar a dibujar en la textura de juego - SDL_RenderTexture(screen->getRenderer(), canvas_, nullptr, nullptr); // Copia la textura con la zona de juego a la pantalla - screen->render(); // Vuelca el contenido del renderizador en pantalla + SCREEN->start(); // Prepara para empezar a dibujar en la textura de juego + SDL_RenderTexture(SCREEN->getRenderer(), canvas_, nullptr, nullptr); // Copia la textura con la zona de juego a la pantalla + SCREEN->render(); // Vuelca el contenido del renderizador en pantalla } // Comprueba el manejador de eventos diff --git a/source/sections/game.cpp b/source/sections/game.cpp index 476e6c4..14c0303 100644 --- a/source/sections/game.cpp +++ b/source/sections/game.cpp @@ -1,19 +1,20 @@ #include "game.h" -#include // Para SDL_GetTicks, SDL_SetRenderTarget, SDL_EventType, SDL_CreateTexture, SDL_Delay, SDL_DestroyTexture, SDL_Event, SDL_GetRenderTarget, SDL_PollEvent, SDL_RenderTexture, SDL_SetTextureBlendMode, SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_5, SDLK_6, SDLK_7, SDLK_8, SDLK_9, SDL_BLENDMODE_BLEND, SDL_PixelFormat, SDL_Point, SDL_TextureAccess +#include // Para SDL_GetTicks, SDL_SetRenderTarget, SDL_EventType, SDL_CreateTexture, SDL_Delay, SDL_DestroyTexture, SDL_Event, SDL_GetRenderTarget, SDL_PollEvent, SDL_RenderTexture, SDL_SetTextureBlendMode, SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_5, SDLK_6, SDLK_7, SDLK_8, SDLK_9, SDLK_KP_MINUS, SDLK_KP_PLUS, SDL_BLENDMODE_BLEND, SDL_PixelFormat, SDL_Point, SDL_TextureAccess -#include // Para max, find_if, clamp, find, min +#include // Para max, find, clamp, find_if, min #include // Para array #include // Para rand, size_t #include // Para function -#include // Para std::cout, std::endl -#include // Para distance, size -#include // Para std::make_unique +#include // Para basic_ostream, basic_ostream::operator<<, cout, endl +#include // Para size +#include // Para shared_ptr, unique_ptr, __shared_ptr_access, allocator, make_unique, operator==, make_shared +#include // Para move #include "asset.h" // Para Asset #include "audio.h" // Para Audio #include "background.h" // Para Background -#include "balloon.h" // Para Balloon, Balloon::SPEED +#include "balloon.h" // Para Balloon #include "balloon_manager.h" // Para BalloonManager #include "bullet.h" // Para Bullet, BulletType, BulletMoveStatus #include "color.h" // Para Color, FLASH_COLOR @@ -22,20 +23,21 @@ #include "global_events.h" // Para check #include "global_inputs.h" // Para check #include "hit.h" // Para Hit -#include "input.h" // Para InputAction, Input, Input::DO_NOT_ALLOW_REPEAT, Input::ALLOW_REPEAT, InputDevice +#include "input.h" // Para Input +#include "input_types.h" // Para InputAction #include "item.h" // Para Item, ItemType #include "lang.h" // Para getText -#include "manage_hiscore_table.h" // Para ManageHiScoreTable, HiScoreEntry +#include "manage_hiscore_table.h" // Para HiScoreEntry, ManageHiScoreTable #include "param.h" // Para Param, param, ParamGame, ParamScoreboard, ParamFade, ParamBalloon #include "path_sprite.h" // Para Path, PathSprite, createPath, PathType -#include "player.h" // Para Player, PlayerState +#include "player.h" // Para Player #include "resource.h" // Para Resource -#include "scoreboard.h" // Para Scoreboard, ScoreboardMode, SCOREBOARD_LEFT_PANEL, SCOREBOARD_RIGHT_PANEL, SCOREBOARD_CENTER_PANEL +#include "scoreboard.h" // Para Scoreboard #include "screen.h" // Para Screen #include "section.hpp" // Para Name, name, AttractMode, Options, attract_mode, options #include "smart_sprite.h" // Para SmartSprite #include "stage.h" // Para number, Stage, get, total_power, power, addPower, init, power_can_be_added, stages -#include "tabe.h" // Para Tabe, TabeState +#include "tabe.h" // Para Tabe #include "text.h" // Para Text #include "texture.h" // Para Texture #include "ui/notifier.h" // Para Notifier @@ -903,8 +905,7 @@ void Game::update() { fillCanvas(); } - static const auto audio = Audio::get(); - audio->update(); + Audio::update(); } // Dibuja el juego @@ -1834,8 +1835,8 @@ void Game::playSound(const std::string &name) const { return; } - static auto audio = Audio::get(); - audio->playSound(name); + static auto *audio_ = Audio::get(); + audio_->playSound(name); } // Organiza los jugadores para que los vivos se pinten sobre los muertos @@ -1903,7 +1904,7 @@ void Game::sendPlayerToTheFront(const std::shared_ptr &player) { #ifdef _DEBUG // Comprueba los eventos en el modo DEBUG void Game::checkDebugEvents(const SDL_Event &event) { - static int formation_id = 0; + static int formation_id_ = 0; if (event.type == SDL_EVENT_KEY_DOWN && static_cast(event.key.repeat) == 0) { switch (event.key.key) { case SDLK_1: // Crea una powerball @@ -1966,17 +1967,17 @@ void Game::checkDebugEvents(const SDL_Event &event) { break; } case SDLK_KP_PLUS: { - ++formation_id; + ++formation_id_; balloon_manager_->destroyAllBalloons(); - balloon_manager_->deployFormation(formation_id); - std::cout << formation_id << std::endl; + balloon_manager_->deployFormation(formation_id_); + std::cout << formation_id_ << std::endl; break; } case SDLK_KP_MINUS: { - --formation_id; + --formation_id_; balloon_manager_->destroyAllBalloons(); - balloon_manager_->deployFormation(formation_id); - std::cout << formation_id << std::endl; + balloon_manager_->deployFormation(formation_id_); + std::cout << formation_id_ << std::endl; break; } default: diff --git a/source/sections/game.h b/source/sections/game.h index 24da296..5b13217 100644 --- a/source/sections/game.h +++ b/source/sections/game.h @@ -171,12 +171,12 @@ class Game { void updateGameStateGameOver(); // Gestiona el estado de fin de partida // --- Gestión de jugadores --- - void initPlayers(Player::Id player_id); // Inicializa los datos de los jugadores - void updatePlayers(); // Actualiza las variables y estados de los jugadores - void renderPlayers(); // Renderiza todos los jugadores en pantalla - void sortPlayersByZOrder(); // Reorganiza el orden de dibujado de jugadores - auto getPlayer(Player::Id id) -> std::shared_ptr; // Obtiene un jugador por su identificador - static auto getController(Player::Id player_id) -> int; // Obtiene el controlador asignado a un jugador + void initPlayers(Player::Id player_id); // Inicializa los datos de los jugadores + void updatePlayers(); // Actualiza las variables y estados de los jugadores + void renderPlayers(); // Renderiza todos los jugadores en pantalla + void sortPlayersByZOrder(); // Reorganiza el orden de dibujado de jugadores + auto getPlayer(Player::Id id) -> std::shared_ptr; // Obtiene un jugador por su identificador + static auto getController(Player::Id player_id) -> int; // Obtiene el controlador asignado a un jugador // --- Estado de jugadores --- void checkAndUpdatePlayerStatus(int active_player_index, int inactive_player_index); // Actualiza estado entre jugadores @@ -209,11 +209,11 @@ class Game { void demoHandlePlayerInput(const std::shared_ptr &player, int index); // Procesa entrada de jugador en demo // --- Sistema de balas y proyectiles --- - void updateBullets(); // Actualiza posición y estado de todas las balas - void renderBullets(); // Renderiza todas las balas activas + void updateBullets(); // Actualiza posición y estado de todas las balas + void renderBullets(); // Renderiza todas las balas activas void createBullet(int x, int y, BulletType kind, bool powered_up, Player::Id owner); // Crea una nueva bala - void checkBulletCollision(); // Verifica colisiones de todas las balas - void freeBullets(); // Libera memoria del vector de balas + void checkBulletCollision(); // Verifica colisiones de todas las balas + void freeBullets(); // Libera memoria del vector de balas // --- Colisiones específicas de balas --- auto checkBulletTabeCollision(std::shared_ptr bullet) -> bool; // Detecta colisión bala-Tabe @@ -274,7 +274,7 @@ class Game { // --- Modo demostración --- void initDemo(Player::Id player_id); // Inicializa variables para el modo demostración - void updateDemo(); // Actualiza lógica específica del modo demo + void updateDemo(); // Actualiza lógica específica del modo demo // --- Recursos y renderizado --- void setResources(); // Asigna texturas y animaciones a los objetos @@ -285,8 +285,8 @@ class Game { // --- Sistema de audio --- static void playMusic(); // Reproduce la música de fondo void stopMusic() const; // Detiene la reproducción de música - void pauseMusic(); // Pausa la música - void resumeMusic(); // Retoma la música que eestaba pausada + static void pauseMusic(); // Pausa la música + static void resumeMusic(); // Retoma la música que eestaba pausada void playSound(const std::string &name) const; // Reproduce un efecto de sonido específico // --- Utilidades y servicios --- diff --git a/source/sections/hiscore_table.cpp b/source/sections/hiscore_table.cpp index 72a4f81..dcb6aaa 100644 --- a/source/sections/hiscore_table.cpp +++ b/source/sections/hiscore_table.cpp @@ -66,23 +66,22 @@ void HiScoreTable::update() { fillTexture(); // Dibuja los sprites en la textura } - static const auto audio = Audio::get(); - audio->update(); + Audio::update(); } // Pinta en pantalla void HiScoreTable::render() { - static const auto screen = Screen::get(); + static auto *const SCREEN = Screen::get(); - screen->start(); // Prepara para empezar a dibujar en la textura de juego - screen->clean(); // Limpia la pantalla + SCREEN->start(); // Prepara para empezar a dibujar en la textura de juego + SCREEN->clean(); // Limpia la pantalla background_->render(); // Pinta el fondo view_area_.y = std::max(0.0F, param.game.height - counter_ + 100); // Establece la ventana del backbuffer SDL_RenderTexture(renderer_, backbuffer_, nullptr, &view_area_); // Copia el backbuffer al renderizador fade_->render(); // Renderiza el fade - screen->render(); // Vuelca el contenido del renderizador en pantalla + SCREEN->render(); // Vuelca el contenido del renderizador en pantalla } // Dibuja los sprites en la textura diff --git a/source/sections/instructions.cpp b/source/sections/instructions.cpp index 1a85126..ef50fb0 100644 --- a/source/sections/instructions.cpp +++ b/source/sections/instructions.cpp @@ -209,26 +209,25 @@ void Instructions::update() { ticks_ = SDL_GetTicks(); // Actualiza el contador de ticks Screen::get()->update(); // Actualiza el objeto screen - counter_++; // Incrementa el contador - updateSprites(); // Actualiza los sprites - updateBackbuffer(); // Gestiona la textura con los graficos - tiled_bg_->update(); // Actualiza el mosaico de fondo - fade_->update(); // Actualiza el objeto "fade" - fillBackbuffer(); // Rellena el backbuffer + counter_++; // Incrementa el contador + updateSprites(); // Actualiza los sprites + updateBackbuffer(); // Gestiona la textura con los graficos + tiled_bg_->update(); // Actualiza el mosaico de fondo + fade_->update(); // Actualiza el objeto "fade" + fillBackbuffer(); // Rellena el backbuffer } - static const auto audio = Audio::get(); - audio->update(); + Audio::update(); } // Pinta en pantalla void Instructions::render() { - static const auto screen = Screen::get(); - - screen->start();// Prepara para empezar a dibujar en la textura de juego - screen->clean();// Limpia la pantalla + static auto *const SCREEN = Screen::get(); - tiled_bg_->render();// Dibuja el mosacico de fondo + SCREEN->start(); // Prepara para empezar a dibujar en la textura de juego + SCREEN->clean(); // Limpia la pantalla + + tiled_bg_->render(); // Dibuja el mosacico de fondo // Copia la textura y el backbuffer al renderizador if (view_.y == 0) { @@ -237,9 +236,9 @@ void Instructions::render() { SDL_RenderTexture(renderer_, backbuffer_, nullptr, &view_); } - fade_->render(); // Renderiza el fundido - - screen->render();// Vuelca el contenido del renderizador en pantalla + fade_->render(); // Renderiza el fundido + + SCREEN->render(); // Vuelca el contenido del renderizador en pantalla } // Comprueba los eventos diff --git a/source/sections/intro.cpp b/source/sections/intro.cpp index 18c7b03..423ae37 100644 --- a/source/sections/intro.cpp +++ b/source/sections/intro.cpp @@ -225,7 +225,7 @@ void Intro::update() { ticks_ = SDL_GetTicks(); // Actualiza el contador de ticks Screen::get()->update(); // Actualiza el objeto screen - tiled_bg_->update(); // Actualiza el fondo + tiled_bg_->update(); // Actualiza el fondo switch (state_) { case IntroState::SCENES: @@ -240,18 +240,17 @@ void Intro::update() { } } - static const auto audio = Audio::get(); - audio->update(); + Audio::update(); } // Dibuja el objeto en pantalla void Intro::render() { - static const auto screen = Screen::get(); - - screen->start();// Prepara para empezar a dibujar en la textura de juego - screen->clean();// Limpia la pantalla + static auto *const SCREEN = Screen::get(); - tiled_bg_->render();// Dibuja el fondo + SCREEN->start(); // Prepara para empezar a dibujar en la textura de juego + SCREEN->clean(); // Limpia la pantalla + + tiled_bg_->render(); // Dibuja el fondo switch (state_) { case IntroState::SCENES: { @@ -263,8 +262,8 @@ void Intro::render() { case IntroState::POST: break; } - - screen->render();// Vuelca el contenido del renderizador en pantalla + + SCREEN->render(); // Vuelca el contenido del renderizador en pantalla } // Bucle principal diff --git a/source/sections/logo.cpp b/source/sections/logo.cpp index de31cea..17ab9b9 100644 --- a/source/sections/logo.cpp +++ b/source/sections/logo.cpp @@ -134,26 +134,25 @@ void Logo::update() { if (SDL_GetTicks() - ticks_ > param.game.speed) { ticks_ = SDL_GetTicks(); // Actualiza el contador de ticks Screen::get()->update(); // Actualiza el objeto screen - - updateJAILGAMES(); // Actualiza el logo de JAILGAMES - updateTextureColors(); // Actualiza los colores de las texturas - ++counter_; // Gestiona el contador + + updateJAILGAMES(); // Actualiza el logo de JAILGAMES + updateTextureColors(); // Actualiza los colores de las texturas + ++counter_; // Gestiona el contador } - static const auto audio = Audio::get(); - audio->update(); + Audio::update(); } // Dibuja en pantalla void Logo::render() { - static const auto screen = Screen::get(); + static auto *const SCREEN = Screen::get(); - screen->start(); - screen->clean(); + SCREEN->start(); + SCREEN->clean(); renderJAILGAMES(); - screen->render(); + SCREEN->render(); } // Bucle para el logo del juego diff --git a/source/sections/title.cpp b/source/sections/title.cpp index 69122d1..396e427 100644 --- a/source/sections/title.cpp +++ b/source/sections/title.cpp @@ -1,34 +1,34 @@ #include "title.h" -#include // Para SDL_GetTicks, Uint32, SDL_EventType +#include // Para SDL_GetTicks, Uint32, SDL_Keycode, SDL_Event, SDL_PollEvent, SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_5, SDLK_A, SDLK_C, SDLK_D, SDLK_F, SDLK_S, SDLK_V, SDLK_X, SDLK_Z, SDL_EventType -#include // Para find_if -#include // Para size_t -#include // Para basic_ostream, basic_ostream::operator<< -#include // Para basic_string, char_traits, operator+ +#include // Para max, find_if +#include // Para basic_ostream, basic_ostream::operator<<, operator<<, cout, endl, hex +#include // Para char_traits, operator+, to_string, string, basic_string #include // Para vector #include "audio.h" // Para Audio -#include "color.h" // Para Color, Zone, NO_TEXT_COLOR, TITLE_SHADO... +#include "color.h" // Para Color, NO_TEXT_COLOR, TITLE_SHADOW_TEXT_COLOR #include "define_buttons.h" // Para DefineButtons #include "fade.h" // Para Fade, FadeType #include "game_logo.h" // Para GameLogo #include "global_events.h" // Para check #include "global_inputs.h" // Para check -#include "input.h" // Para Input, Input::DO_NOT_ALLOW_REPEAT, Input... +#include "input.h" // Para Input +#include "input_types.h" // Para InputAction #include "lang.h" // Para getText -#include "options.h" // Para GamepadOptions, controllers, getPlayerW... -#include "param.h" // Para Param, param, ParamGame, ParamTitle -#include "player.h" // Para Player, PlayerState +#include "options.h" // Para Gamepad, GamepadManager, gamepad_manager, Settings, settings, getPlayerWhoUsesKeyboard, swapControllers, swapKeyboard +#include "param.h" // Para Param, param, ParamGame, ParamTitle, ParamFade +#include "player.h" // Para Player #include "resource.h" // Para Resource #include "screen.h" // Para Screen -#include "section.hpp" // Para Name, name, Options, options, AttractMode +#include "section.hpp" // Para Name, name, Options, options, AttractMode, attract_mode #include "sprite.h" // Para Sprite #include "text.h" // Para TEXT_CENTER, TEXT_SHADOW, Text #include "tiled_bg.h" // Para TiledBG, TiledBGMode #include "ui/notifier.h" // Para Notifier #include "ui/service_menu.h" // Para ServiceMenu -#include "utils.h" +#include "utils.h" // Para Zone, BLOCK class Texture; @@ -87,16 +87,15 @@ void Title::update() { updatePlayers(); } - static const auto audio = Audio::get(); - audio->update(); + Audio::update(); } // Dibuja el objeto en pantalla void Title::render() { - static const auto screen = Screen::get(); + static auto* const SCREEN = Screen::get(); - screen->start(); - screen->clean(); + SCREEN->start(); + SCREEN->clean(); tiled_bg_->render(); game_logo_->render(); @@ -106,7 +105,7 @@ void Title::render() { define_buttons_->render(); fade_->render(); - screen->render(); + SCREEN->render(); } // Comprueba los eventos @@ -348,7 +347,7 @@ void Title::showControllers() { // Crea los textos std::string text1 = Lang::getText("[DEFINE_BUTTONS] PLAYER") + std::to_string(static_cast(Player::Id::PLAYER1)) + ": " + Options::gamepad_manager.getGamepad(Player::Id::PLAYER1).name; std::string text2 = Lang::getText("[DEFINE_BUTTONS] PLAYER") + std::to_string(static_cast(Player::Id::PLAYER2)) + ": " + Options::gamepad_manager.getGamepad(Player::Id::PLAYER2).name; - + // Muestra la notificación Notifier::get()->show({text1, text2}); } diff --git a/source/sections/title.h b/source/sections/title.h index ce2dcd0..5387288 100644 --- a/source/sections/title.h +++ b/source/sections/title.h @@ -1,8 +1,8 @@ #pragma once #include // Para SDL_Keycode, SDL_Event, Uint64 -#include // Para uint8_t +#include // Para uint8_t #include // Para unique_ptr, shared_ptr #include // Para string_view #include // Para vector @@ -87,18 +87,18 @@ class Title { void resetCounter(); // Reinicia el contador interno // --- Entrada de usuario --- - void checkEvents(); // Comprueba los eventos - void checkInput(); // Comprueba las entradas - void handleKeyDownEvent(const SDL_Event& event); // Maneja el evento de tecla presionada - void handleControlKeys(SDL_Keycode key); // Maneja las teclas de control específicas - [[nodiscard]] auto shouldSkipInputCheck() const -> bool; // Determina si se debe omitir la comprobación de entrada - void processControllerInputs(); // Procesa las entradas de los mandos - [[nodiscard]] static auto isStartButtonPressed(const Options::Gamepad *controller) -> bool; // Comprueba si se ha pulsado el botón Start - void handleStartButtonPress(const Options::Gamepad *controller); // Maneja la pulsación del botón Start - [[nodiscard]] auto canProcessStartButton() const -> bool; // Verifica si se puede procesar la pulsación del botón Start - void processPlayer1Start(); // Procesa el inicio del jugador 1 - void processPlayer2Start(); // Procesa el inicio del jugador 2 - void activatePlayerAndSetState(Player::Id player_id); // Activa al jugador y cambia el estado del título + void checkEvents(); // Comprueba los eventos + void checkInput(); // Comprueba las entradas + void handleKeyDownEvent(const SDL_Event& event); // Maneja el evento de tecla presionada + void handleControlKeys(SDL_Keycode key); // Maneja las teclas de control específicas + [[nodiscard]] auto shouldSkipInputCheck() const -> bool; // Determina si se debe omitir la comprobación de entrada + void processControllerInputs(); // Procesa las entradas de los mandos + [[nodiscard]] static auto isStartButtonPressed(const Options::Gamepad* controller) -> bool; // Comprueba si se ha pulsado el botón Start + void handleStartButtonPress(const Options::Gamepad* controller); // Maneja la pulsación del botón Start + [[nodiscard]] auto canProcessStartButton() const -> bool; // Verifica si se puede procesar la pulsación del botón Start + void processPlayer1Start(); // Procesa el inicio del jugador 1 + void processPlayer2Start(); // Procesa el inicio del jugador 2 + void activatePlayerAndSetState(Player::Id player_id); // Activa al jugador y cambia el estado del título // --- Gestión de jugadores --- void initPlayers(); // Inicializa los jugadores diff --git a/source/tabe.h b/source/tabe.h index 746fd7b..a4e8ae8 100644 --- a/source/tabe.h +++ b/source/tabe.h @@ -106,7 +106,7 @@ class Tabe { return time_until_next_spawn == 0 && !is_paused; } }; - + // --- Objetos y punteros --- std::unique_ptr sprite_; // Sprite con los gráficos y animaciones diff --git a/source/ui/menu_renderer.cpp b/source/ui/menu_renderer.cpp index 2da1da9..3c7a0c9 100644 --- a/source/ui/menu_renderer.cpp +++ b/source/ui/menu_renderer.cpp @@ -51,21 +51,21 @@ void MenuRenderer::render(const ServiceMenu *menu_state) { if (menu_state->getCurrentGroupAlignment() == ServiceMenu::GroupAlignment::LEFT) { // Para opciones alineadas a la izquierda, truncamos el valor si es necesario - const int available_width = rect_.w - (ServiceMenu::OPTIONS_HORIZONTAL_PADDING * 2) - - element_text_->lenght(option_pairs.at(i).first, -2) - - ServiceMenu::MIN_GAP_OPTION_VALUE; - - const std::string truncated_value = getTruncatedValue(option_pairs.at(i).second, available_width); - + const int AVAILABLE_WIDTH = rect_.w - (ServiceMenu::OPTIONS_HORIZONTAL_PADDING * 2) - + element_text_->lenght(option_pairs.at(i).first, -2) - + ServiceMenu::MIN_GAP_OPTION_VALUE; + + const std::string TRUNCATED_VALUE = getTruncatedValue(option_pairs.at(i).second, AVAILABLE_WIDTH); + element_text_->writeColored(rect_.x + ServiceMenu::OPTIONS_HORIZONTAL_PADDING, y, option_pairs.at(i).first, current_color, -2); - const int X = rect_.x + rect_.w - ServiceMenu::OPTIONS_HORIZONTAL_PADDING - element_text_->lenght(truncated_value, -2); - element_text_->writeColored(X, y, truncated_value, current_color, -2); + const int X = rect_.x + rect_.w - ServiceMenu::OPTIONS_HORIZONTAL_PADDING - element_text_->lenght(TRUNCATED_VALUE, -2); + element_text_->writeColored(X, y, TRUNCATED_VALUE, current_color, -2); } else { // Para opciones centradas, también truncamos si es necesario - const int available_width = rect_.w - (ServiceMenu::OPTIONS_HORIZONTAL_PADDING * 2); - const std::string truncated_caption = getTruncatedValue(option_pairs.at(i).first, available_width); - - element_text_->writeDX(TEXT_CENTER | TEXT_COLOR, rect_.x + rect_.w / 2, y, truncated_caption, -2, current_color); + const int AVAILABLE_WIDTH = rect_.w - (ServiceMenu::OPTIONS_HORIZONTAL_PADDING * 2); + const std::string TRUNCATED_CAPTION = getTruncatedValue(option_pairs.at(i).first, AVAILABLE_WIDTH); + + element_text_->writeDX(TEXT_CENTER | TEXT_COLOR, rect_.x + rect_.w / 2, y, TRUNCATED_CAPTION, -2, current_color); } y += options_height_ + options_padding_; } @@ -96,8 +96,8 @@ void MenuRenderer::setLayout(const ServiceMenu *menu_state) { void MenuRenderer::initializeMaxSizes() { // Establecemos los límites máximos basados en el tamaño de la pantalla // Dejamos un margen del 10% en cada lado para que el menú no ocupe toda la pantalla - max_menu_width_ = static_cast(param.game.game_area.rect.w * 0.9f); - max_menu_height_ = static_cast(param.game.game_area.rect.h * 0.9f); + max_menu_width_ = static_cast(param.game.game_area.rect.w * 0.9F); + max_menu_height_ = static_cast(param.game.game_area.rect.h * 0.9F); } void MenuRenderer::setAnchors(const ServiceMenu *menu_state) { @@ -123,7 +123,7 @@ void MenuRenderer::setAnchors(const ServiceMenu *menu_state) { auto MenuRenderer::calculateNewRect(const ServiceMenu *menu_state) -> SDL_FRect { width_ = std::min(static_cast(getMenuWidthForGroup(menu_state->getCurrentGroup())), max_menu_width_); - + const auto &display_options = menu_state->getDisplayOptions(); lower_height_ = ((!display_options.empty() ? display_options.size() - 1 : 0) * (options_height_ + options_padding_)) + options_height_ + (lower_padding_ * 2); height_ = std::min(upper_height_ + lower_height_, max_menu_height_); @@ -187,10 +187,10 @@ void MenuRenderer::precalculateMenuWidths(const std::vectorlenght(option->getCaption(), -2)); if (menu_state->getCurrentGroupAlignment() == ServiceMenu::GroupAlignment::LEFT) { // Para calcular el ancho máximo, necesitamos considerar la truncación - int max_available_value_width = static_cast(max_menu_width_) - max_option_width - - (ServiceMenu::OPTIONS_HORIZONTAL_PADDING * 2) - - ServiceMenu::MIN_GAP_OPTION_VALUE; - + int max_available_value_width = static_cast(max_menu_width_) - max_option_width - + (ServiceMenu::OPTIONS_HORIZONTAL_PADDING * 2) - + ServiceMenu::MIN_GAP_OPTION_VALUE; + int actual_value_width = getTruncatedValueWidth(option->getValueAsString(), max_available_value_width); max_value_width = std::max(max_value_width, actual_value_width); } @@ -199,8 +199,8 @@ void MenuRenderer::precalculateMenuWidths(const std::vectorgetCurrentGroupAlignment() == ServiceMenu::GroupAlignment::LEFT) { total_width += ServiceMenu::MIN_GAP_OPTION_VALUE + max_value_width; } - group_menu_widths_[group] = std::min(std::max((int)ServiceMenu::MIN_WIDTH, (int)total_width), - static_cast(max_menu_width_)); + group_menu_widths_[group] = std::min(std::max((int)ServiceMenu::MIN_WIDTH, (int)total_width), + static_cast(max_menu_width_)); } } @@ -232,20 +232,20 @@ auto MenuRenderer::getTruncatedValueWidth(const std::string &value, int availabl if (value_width <= available_width) { return value_width; } - + // Calculamos cuántos caracteres podemos mostrar más los puntos suspensivos // Estimamos el ancho de los puntos suspensivos como 3 caracteres promedio int ellipsis_width = element_text_->lenght("...", -2); int available_for_text = available_width - ellipsis_width; - + if (available_for_text <= 0) { - return ellipsis_width; // Solo mostramos los puntos suspensivos + return ellipsis_width; // Solo mostramos los puntos suspensivos } - + // Calculamos aproximadamente cuántos caracteres caben float char_width = static_cast(value_width) / value.length(); - size_t max_chars = static_cast(available_for_text / char_width); - + auto max_chars = static_cast(available_for_text / char_width); + // Verificamos el ancho real del texto truncado std::string truncated = truncateWithEllipsis(value, max_chars); return element_text_->lenght(truncated, -2); @@ -256,25 +256,25 @@ auto MenuRenderer::getTruncatedValue(const std::string &value, int available_wid if (value_width <= available_width) { return value; } - + // Calculamos cuántos caracteres podemos mostrar int ellipsis_width = element_text_->lenght("...", -2); int available_for_text = available_width - ellipsis_width; - + if (available_for_text <= 0) { - return "..."; // Solo mostramos los puntos suspensivos + return "..."; // Solo mostramos los puntos suspensivos } - + // Calculamos aproximadamente cuántos caracteres caben float char_width = static_cast(value_width) / value.length(); - size_t max_chars = static_cast(available_for_text / char_width); - + auto max_chars = static_cast(available_for_text / char_width); + // Ajustamos iterativamente hasta que el texto quepa std::string truncated = truncateWithEllipsis(value, max_chars); while (element_text_->lenght(truncated, -2) > available_width && max_chars > 1) { max_chars--; truncated = truncateWithEllipsis(value, max_chars); } - + return truncated; } \ No newline at end of file diff --git a/source/ui/menu_renderer.h b/source/ui/menu_renderer.h index 7f51520..d7008f1 100644 --- a/source/ui/menu_renderer.h +++ b/source/ui/menu_renderer.h @@ -5,6 +5,7 @@ #include // Para array #include // Para size_t #include // Para shared_ptr, unique_ptr +#include // Para string #include // Para vector #include "color.h" // Para Color diff --git a/source/ui/service_menu.cpp b/source/ui/service_menu.cpp index 0978273..6678d58 100644 --- a/source/ui/service_menu.cpp +++ b/source/ui/service_menu.cpp @@ -3,12 +3,14 @@ #include // Para max #include "audio.h" // Para Audio -#include "difficulty.h" // Para Difficulty +#include "difficulty.h" // Para getCodeFromName, getNameFromCode +#include "input.h" // Para Input #include "lang.h" // Para getText, getCodeFromName, getNameFromCode -#include "menu_option.h" // Para MenuOption, BoolOption, ActionOption, IntOption, FolderOption, ListOption +#include "menu_option.h" // Para MenuOption, ListOption, ActionOption, BoolOption, FolderOption, IntOption #include "menu_renderer.h" // Para MenuRenderer -#include "options.h" // Para PendingChanges, VideoOptions, pending_changes, video, AudioOptions, SettingsOptions, audio, checkPendingChanges, settings, WindowOptions, getDifficultyCodeFromName, getDifficultyNameFromCode, window, MusicOptions, SoundOptions +#include "options.h" // Para PendingChanges, pending_changes, checkPendingChanges, GamepadManager, Video, gamepad_manager, video, Audio, Settings, audio, settings, Gamepad, Window, window, Music, Sound #include "param.h" // Para Param, param, ParamGame, ParamServiceMenu +#include "player.h" // Para Player #include "resource.h" // Para Resource #include "screen.h" // Para Screen #include "section.hpp" // Para Name, name, Options, options @@ -285,7 +287,7 @@ void ServiceMenu::initializeOptions() { options_.push_back(std::make_unique( Lang::getText("[SERVICE_MENU] SWAP_CONTROLLERS"), SettingsGroup::CONTROLS, - [this]() { + []() { Options::gamepad_manager.swapPlayers(); })); diff --git a/source/ui/service_menu.h b/source/ui/service_menu.h index 5168622..82fb3db 100644 --- a/source/ui/service_menu.h +++ b/source/ui/service_menu.h @@ -9,7 +9,7 @@ #include "ui_message.h" // Para UIMessage class MenuOption; -class MenuRenderer; +class MenuRenderer; class ServiceMenu { public: diff --git a/source/utils.cpp b/source/utils.cpp index f936d4b..df00c20 100644 --- a/source/utils.cpp +++ b/source/utils.cpp @@ -42,7 +42,6 @@ auto getCollisionPoint(const Circle &a, const Circle &b) -> SDL_FPoint { return contact; } - // Detector de colisiones entre dos circulos auto checkCollision(const Circle &a, const Circle &b) -> bool { // Calcula el radio total al cuadrado @@ -264,24 +263,24 @@ auto easeOutElastic(double time) -> double { // Ease Out Expo - Muy suave al final (más dramático) auto easeOutExpo(double time) -> double { - return time == 1.0f ? 1.0f : 1.0f - pow(2.0f, -10.0f * time); + return time == 1.0F ? 1.0F : 1.0F - pow(2.0F, -10.0F * time); } // Ease In Expo - Arranque muy gradual auto easeInExpo(double time) -> double { - return time == 0.0f ? 0.0f : pow(2.0f, 10.0f * (time - 1.0f)); + return time == 0.0F ? 0.0F : pow(2.0F, 10.0F * (time - 1.0F)); } // Ease Out Back - Con un pequeño "rebote" auto easeOutBack(double time) -> double { - const double C1 = 1.70158f; - const double C3 = C1 + 1.0f; - return 1.0f + C3 * pow(time - 1.0f, 3.0f) + C1 * pow(time - 1.0f, 2.0f); + const double C1 = 1.70158F; + const double C3 = C1 + 1.0F; + return 1.0F + C3 * pow(time - 1.0F, 3.0F) + C1 * pow(time - 1.0F, 2.0F); } // Ease Out Cubic - Desaceleración suave al final auto easeOutCubic(double time) -> double { - return 1.0f - pow(1.0f - time, 3.0f); + return 1.0F - pow(1.0F - time, 3.0F); } // Ease In Cubic - Aceleración gradual @@ -391,7 +390,6 @@ auto truncateWithEllipsis(const std::string &input, size_t length) -> std::strin return input; } if (length <= 3) { - // Not enough space for any content plus ellipsis return std::string(length, '.'); } return input.substr(0, length) + "..."; diff --git a/source/utils.h b/source/utils.h index 4ba7a90..872133b 100644 --- a/source/utils.h +++ b/source/utils.h @@ -3,6 +3,7 @@ #include // Para Uint8, SDL_FRect, SDL_FPoint, SDL_Renderer +#include // Para size_t #include // Para int32_t #include // Para string #include // Para vector