diff --git a/source/core/audio/jail_audio.hpp b/source/core/audio/jail_audio.hpp index 63308e0..f6dc224 100644 --- a/source/core/audio/jail_audio.hpp +++ b/source/core/audio/jail_audio.hpp @@ -265,13 +265,13 @@ inline JA_Music_t* JA_LoadMusic(const Uint8* buffer, Uint32 length) { auto* music = new JA_Music_t(); music->ogg_data.assign(buffer, buffer + length); - int error = 0; + int err_code = 0; music->vorbis = stb_vorbis_open_memory(music->ogg_data.data(), static_cast(length), - &error, + &err_code, nullptr); if (!music->vorbis) { - std::cout << "JA_LoadMusic: stb_vorbis_open_memory failed (error " << error << ")" << '\n'; + std::cout << "JA_LoadMusic: stb_vorbis_open_memory failed (error " << err_code << ")" << '\n'; delete music; return nullptr; } diff --git a/source/core/input/define_buttons.cpp b/source/core/input/define_buttons.cpp index c7438a2..750b346 100644 --- a/source/core/input/define_buttons.cpp +++ b/source/core/input/define_buttons.cpp @@ -1,6 +1,7 @@ #include "core/input/define_buttons.hpp" -#include // Para __all_of_fn, all_of +#include // Para __all_of_fn, all_of, ranges::transform +#include // Para back_inserter #include // Para unique_ptr, allocator, shared_ptr, operator==, make_unique #include "core/input/input.hpp" // Para Input @@ -16,10 +17,9 @@ DefineButtons::DefineButtons() : input_(Input::get()) { clearButtons(); - auto gamepads = input_->getGamepads(); - for (const auto& gamepad : gamepads) { - controller_names_.emplace_back(Input::getControllerName(gamepad)); - } + const auto gamepads = input_->getGamepads(); + controller_names_.reserve(gamepads.size()); + std::ranges::transform(gamepads, std::back_inserter(controller_names_), Input::getControllerName); // Crear la ventana de mensaje WindowMessage::Config config(param.service_menu.window_message); diff --git a/source/core/input/input.cpp b/source/core/input/input.cpp index 2176e81..0ef77fe 100644 --- a/source/core/input/input.cpp +++ b/source/core/input/input.cpp @@ -118,53 +118,22 @@ auto Input::checkAction(Action action, bool repeat, bool check_keyboard, const s // Comprueba si hay almenos una acción activa auto Input::checkAnyInput(bool check_keyboard, const std::shared_ptr& gamepad) -> bool { - // Obtenemos el número total de acciones posibles para iterar sobre ellas. + const auto JUST_PRESSED = [](const auto& pair) { return pair.second.just_pressed; }; - // --- Comprobación del Teclado --- - if (check_keyboard) { - for (const auto& pair : keyboard_.bindings) { - // Simplemente leemos el estado pre-calculado por Input::update(). - // Ya no se llama a SDL_GetKeyboardState ni se modifica el estado '.active'. - if (pair.second.just_pressed) { - return true; // Se encontró una acción recién pulsada. - } - } + if (check_keyboard && std::ranges::any_of(keyboard_.bindings, JUST_PRESSED)) { + return true; } - - // --- Comprobación del Mando --- - // Comprobamos si hay mandos y si el índice solicitado es válido. - if (gamepad != nullptr) { - // Iteramos sobre todas las acciones, no sobre el número de mandos. - for (const auto& pair : gamepad->bindings) { - // Leemos el estado pre-calculado para el mando y la acción específicos. - if (pair.second.just_pressed) { - return true; // Se encontró una acción recién pulsada en el mando. - } - } - } - - // Si llegamos hasta aquí, no se detectó ninguna nueva pulsación. - return false; + return gamepad != nullptr && std::ranges::any_of(gamepad->bindings, JUST_PRESSED); } // 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) { - // Comprueba el teclado - if (checkAction(bi, repeat, CHECK_KEYBOARD)) { - return true; - } - - // Comprueba los mandos - for (const auto& gamepad : gamepads_) { - if (checkAction(bi, repeat, DO_NOT_CHECK_KEYBOARD, gamepad)) { - return true; - } - } - } - - return false; + return std::ranges::any_of(BUTTON_INPUTS, [this, repeat](auto bi) { + if (checkAction(bi, repeat, CHECK_KEYBOARD)) { return true; } + return std::ranges::any_of(gamepads_, [this, bi, repeat](const auto& gamepad) { + return checkAction(bi, repeat, DO_NOT_CHECK_KEYBOARD, gamepad); + }); + }); } // Comprueba si hay algun mando conectado @@ -178,9 +147,8 @@ auto Input::getControllerName(const std::shared_ptr& gamepad) -> std::s // Obtiene la lista de nombres de mandos auto Input::getControllerNames() const -> std::vector { std::vector names; - for (const auto& gamepad : gamepads_) { - names.push_back(gamepad->name); - } + names.reserve(gamepads_.size()); + std::ranges::transform(gamepads_, std::back_inserter(names), [](const auto& gamepad) { return gamepad->name; }); return names; } @@ -189,21 +157,15 @@ auto Input::getNumGamepads() const -> int { return gamepads_.size(); } // Obtiene el gamepad a partir de un event.id auto Input::getGamepad(SDL_JoystickID id) const -> std::shared_ptr { - for (const auto& gamepad : gamepads_) { - if (gamepad->instance_id == id) { - return gamepad; - } - } - return nullptr; + const auto it = std::ranges::find_if(gamepads_, + [id](const auto& gamepad) { return gamepad->instance_id == id; }); + return it != gamepads_.end() ? *it : nullptr; } auto Input::getGamepadByName(const std::string& name) const -> std::shared_ptr { - for (const auto& gamepad : gamepads_) { - if (gamepad && gamepad->name == name) { - return gamepad; - } - } - return nullptr; + const auto it = std::ranges::find_if(gamepads_, + [&name](const auto& gamepad) { return gamepad && gamepad->name == name; }); + return it != gamepads_.end() ? *it : nullptr; } // Obtiene el SDL_GamepadButton asignado a un action @@ -359,7 +321,7 @@ void Input::resetInputStates() { key.second.just_pressed = false; } // Resetear todos los ControllerBindings.active a false - for (auto& gamepad : gamepads_) { + for (const auto& gamepad : gamepads_) { for (auto& binding : gamepad->bindings) { binding.second.is_held = false; binding.second.just_pressed = false; @@ -568,19 +530,11 @@ auto Input::findAvailableGamepadByName(const std::string& gamepad_name) -> std:: } // Buscar por nombre - for (const auto& gamepad : gamepads_) { - if (gamepad && gamepad->name == gamepad_name) { - return gamepad; - } - } + auto by_name = std::ranges::find_if(gamepads_, + [&gamepad_name](const auto& gamepad) { return gamepad && gamepad->name == gamepad_name; }); + if (by_name != gamepads_.end()) { return *by_name; } // Si no se encuentra por nombre, devolver el primer gamepad válido - for (const auto& gamepad : gamepads_) { - if (gamepad) { - return gamepad; - } - } - - // Si llegamos aquí, no hay gamepads válidos - return nullptr; + auto first_valid = std::ranges::find_if(gamepads_, [](const auto& gamepad) { return gamepad != nullptr; }); + return first_valid != gamepads_.end() ? *first_valid : nullptr; } \ No newline at end of file diff --git a/source/core/input/input.hpp b/source/core/input/input.hpp index 21d2aa9..52bd6d0 100644 --- a/source/core/input/input.hpp +++ b/source/core/input/input.hpp @@ -32,7 +32,7 @@ class Input { bool is_held; // Está pulsada ahora mismo bool just_pressed; // Se acaba de pulsar en este fotograma - KeyState(Uint8 scancode = 0, bool is_held = false, bool just_pressed = false) + explicit KeyState(Uint8 scancode = 0, bool is_held = false, bool just_pressed = false) : scancode(scancode), is_held(is_held), just_pressed(just_pressed) {} @@ -45,7 +45,7 @@ class Input { bool axis_active; // Estado del eje bool trigger_active{false}; // Estado del trigger como botón digital - ButtonState(int btn = static_cast(SDL_GAMEPAD_BUTTON_INVALID), bool is_held = false, bool just_pressed = false, bool axis_act = false) + explicit ButtonState(int btn = static_cast(SDL_GAMEPAD_BUTTON_INVALID), bool is_held = false, bool just_pressed = false, bool axis_act = false) : button(btn), is_held(is_held), just_pressed(just_pressed), @@ -115,7 +115,7 @@ class Input { return s; } - Gamepad(SDL_Gamepad* gamepad) + explicit Gamepad(SDL_Gamepad* gamepad) : pad(gamepad), instance_id(SDL_GetJoystickID(SDL_GetGamepadJoystick(gamepad))), name(trimName(SDL_GetGamepadName(gamepad))), @@ -148,7 +148,7 @@ class Input { // Reasigna un botón a una acción void rebindAction(Action action, SDL_GamepadButton new_button) { - bindings[action] = static_cast(new_button); + bindings[action] = ButtonState{static_cast(new_button)}; } }; diff --git a/source/core/input/pause_manager.hpp b/source/core/input/pause_manager.hpp index 7eacbd7..26eec15 100644 --- a/source/core/input/pause_manager.hpp +++ b/source/core/input/pause_manager.hpp @@ -1,9 +1,11 @@ #pragma once +#include #include #include #include #include +#include // --- Clase PauseManager: maneja el sistema de pausa del juego --- class PauseManager { @@ -48,7 +50,7 @@ class PauseManager { // --- Métodos principales --- void setFlag(Source source, bool enable) { // Establece/quita una fuente de pausa específica - bool was_paused = isPaused(); + const bool WAS_PAUSED = isPaused(); if (enable) { flags_ |= source; @@ -56,7 +58,8 @@ class PauseManager { flags_ &= ~source; // Ahora funciona: Source &= uint8_t } - if (was_paused != isPaused()) { + // cppcheck-suppress knownConditionTrueFalse // false-positive: flags_ ha estat modificat entre les dues crides a isPaused() + if (WAS_PAUSED != isPaused()) { notifyPauseChanged(); } } @@ -88,30 +91,16 @@ class PauseManager { return "Active"; } + std::vector parts; + if (hasFlag(Source::PLAYER)) { parts.emplace_back("Player"); } + if (hasFlag(Source::SERVICE_MENU)) { parts.emplace_back("ServiceMenu"); } + if (hasFlag(Source::FOCUS_LOST)) { parts.emplace_back("FocusLoss"); } + std::string result = "Paused by: "; - bool first = true; - - if (hasFlag(Source::PLAYER)) { - if (!first) { - result += ", "; - } - result += "Player"; - first = false; + for (size_t i = 0; i < parts.size(); ++i) { + if (i > 0) { result += ", "; } + result += parts[i]; } - if (hasFlag(Source::SERVICE_MENU)) { - if (!first) { - result += ", "; - } - result += "ServiceMenu"; - first = false; - } - if (hasFlag(Source::FOCUS_LOST)) { - if (!first) { - result += ", "; - } - result += "FocusLoss"; - } - return result; } void setCallback(std::function callback) { // Permite cambiar el callback en runtime diff --git a/source/core/locale/lang.cpp b/source/core/locale/lang.cpp index fdbafeb..97eaa53 100644 --- a/source/core/locale/lang.cpp +++ b/source/core/locale/lang.cpp @@ -1,5 +1,6 @@ #include "core/locale/lang.hpp" +#include // Para ranges::find_if #include // Para size_t #include // Para exception #include // Para basic_ifstream, basic_istream, ifstream @@ -80,35 +81,23 @@ namespace Lang { // Obtiene un idioma del vector de idiomas a partir de un código auto getLanguage(Code code) -> Language { - for (const auto& lang : languages) { - if (lang.code == code) { - return lang; - } - } - // Si no se encuentra, devuelve el primero por defecto - return languages[0]; + const auto it = std::ranges::find_if(languages, + [code](const auto& lang) { return lang.code == code; }); + return it != languages.end() ? *it : languages[0]; } // Devuelve el código de un idioma a partir de un nombre auto getCodeFromName(const std::string& name) -> Code { - for (const auto& lang : languages) { - if (lang.name == name) { - return lang.code; - } - } - // Si no se encuentra, devuelve el primero por defecto - return languages[0].code; + const auto it = std::ranges::find_if(languages, + [&name](const auto& lang) { return lang.name == name; }); + return it != languages.end() ? it->code : languages[0].code; } // Devuelve el nombre de un idioma a partir de un código auto getNameFromCode(Code code) -> std::string { - for (const auto& lang : languages) { - if (lang.code == code) { - return lang.name; - } - } - // Si no se encuentra, devuelve el nombre del primer idioma por defecto - return languages[0].name; + const auto it = std::ranges::find_if(languages, + [code](const auto& lang) { return lang.code == code; }); + return it != languages.end() ? it->name : languages[0].name; } // Actualiza los nombres de los idiomas @@ -155,13 +144,10 @@ namespace Lang { // Obtiene una fichero a partir de un lang::Code auto getLanguageFileName(Lang::Code code) -> std::string { - for (const auto& lang : languages) { - if (lang.code == code) { - return Asset::get()->getPath(lang.file_name); - } - } - // Si no se encuentra, devuelve el fichero del primer idioma por defecto - return Asset::get()->getPath(languages[0].file_name); + const auto it = std::ranges::find_if(languages, + [code](const auto& lang) { return lang.code == code; }); + const auto& file = (it != languages.end()) ? it->file_name : languages[0].file_name; + return Asset::get()->getPath(file); } // Establece el idioma diff --git a/source/core/rendering/background.cpp b/source/core/rendering/background.cpp index ab5c689..86cebcb 100644 --- a/source/core/rendering/background.cpp +++ b/source/core/rendering/background.cpp @@ -562,14 +562,13 @@ void Background::createMoonPath() { const int FREEZE_START_INDEX = static_cast(NUM_STEPS * (1.0F - FREEZE_PERCENTAGE)); for (int i = 0; i < NUM_STEPS; ++i) { - double theta = i * STEP; - float x = CENTER_X + (RADIUS * cos(theta)); - float y = CENTER_Y - (RADIUS * sin(theta)); - if (i >= FREEZE_START_INDEX && !moon_path_.empty()) { moon_path_.push_back(moon_path_.back()); // Repite el último punto válido } else { - moon_path_.push_back({.x = x, .y = y}); + const double THETA = i * STEP; + const float X = CENTER_X + (RADIUS * cos(THETA)); + const float Y = CENTER_Y - (RADIUS * sin(THETA)); + moon_path_.push_back({.x = X, .y = Y}); } } } diff --git a/source/core/rendering/background.hpp b/source/core/rendering/background.hpp index ef62b8e..bd5b05c 100644 --- a/source/core/rendering/background.hpp +++ b/source/core/rendering/background.hpp @@ -28,8 +28,8 @@ class Background { using ProgressCallback = std::function; // Callback para sincronización // --- Constructor y destructor --- - Background(float total_progress_to_complete = 6100.0F); // Constructor principal - ~Background(); // Destructor + explicit Background(float total_progress_to_complete = 6100.0F); // Constructor principal + ~Background(); // Destructor // --- Métodos principales --- void update(float delta_time); // Actualiza la lógica del objeto diff --git a/source/core/rendering/screen.hpp b/source/core/rendering/screen.hpp index be80923..c34ee7f 100644 --- a/source/core/rendering/screen.hpp +++ b/source/core/rendering/screen.hpp @@ -66,7 +66,7 @@ class Screen { [[nodiscard]] auto getText() const -> std::shared_ptr { return text_; } // Obtiene el puntero al texto de Screen // --- Display Monitor getters --- - [[nodiscard]] auto getDisplayMonitorName() const -> std::string { return display_monitor_.name; } + [[nodiscard]] auto getDisplayMonitorName() const -> const std::string& { return display_monitor_.name; } [[nodiscard]] auto getDisplayMonitorWidth() const -> int { return display_monitor_.width; } [[nodiscard]] auto getDisplayMonitorHeight() const -> int { return display_monitor_.height; } [[nodiscard]] auto getDisplayMonitorRefreshRate() const -> int { return display_monitor_.refresh_rate; } diff --git a/source/core/rendering/sprite/path_sprite.hpp b/source/core/rendering/sprite/path_sprite.hpp index 03d9cc3..a8689db 100644 --- a/source/core/rendering/sprite/path_sprite.hpp +++ b/source/core/rendering/sprite/path_sprite.hpp @@ -25,12 +25,12 @@ enum class PathCentered { // Centrado del recorrido // --- Estructuras --- struct Path { // Define un recorrido para el sprite - float start_pos; // Posición inicial - float end_pos; // Posición final - PathType type; // Tipo de movimiento (horizontal/vertical) - float fixed_pos; // Posición fija en el eje contrario - float duration_s; // Duración de la animación en segundos - float waiting_time_s; // Tiempo de espera una vez en el destino + float start_pos = 0.0F; // Posición inicial + float end_pos = 0.0F; // Posición final + PathType type = PathType::HORIZONTAL; // Tipo de movimiento (horizontal/vertical) + float fixed_pos = 0.0F; // Posición fija en el eje contrario + float duration_s = 0.0F; // Duración de la animación en segundos + float waiting_time_s = 0.0F; // Tiempo de espera una vez en el destino std::function easing_function; // Función de easing float elapsed_time = 0.0F; // Tiempo transcurrido float waiting_elapsed = 0.0F; // Tiempo de espera transcurrido diff --git a/source/core/rendering/text.cpp b/source/core/rendering/text.cpp index 0b7921b..b2fb772 100644 --- a/source/core/rendering/text.cpp +++ b/source/core/rendering/text.cpp @@ -403,9 +403,8 @@ auto Text::loadFile(const std::string& file_path) -> std::shared_ptr file.open(file_path); } - std::istream& input_stream = using_resource_data ? stream : static_cast(file); - if ((using_resource_data && stream.good()) || (!using_resource_data && file.is_open() && file.good())) { + std::istream& input_stream = using_resource_data ? stream : static_cast(file); std::string buffer; // Lee los dos primeros valores del fichero diff --git a/source/core/rendering/text.hpp b/source/core/rendering/text.hpp index f558b37..bb130bd 100644 --- a/source/core/rendering/text.hpp +++ b/source/core/rendering/text.hpp @@ -39,7 +39,7 @@ class Text { int kerning; // Constructor con argumentos por defecto - Style(Uint8 flags = 0, + explicit Style(Uint8 flags = 0, Color text = Color(), Color shadow = Color(), Uint8 distance = 1, diff --git a/source/core/resources/resource.cpp b/source/core/resources/resource.cpp index ad90f51..26b19e0 100644 --- a/source/core/resources/resource.cpp +++ b/source/core/resources/resource.cpp @@ -2,12 +2,14 @@ #include // Para SDL_LogInfo, SDL_LogCategory, SDL_LogError, SDL_SetRenderDrawColor, SDL_EventType, SDL_PollEvent, SDL_RenderFillRect, SDL_RenderRect, SDLK_ESCAPE, SDL_Event +#include // Para ranges::transform, ranges::find_if #include // Para array #include // Para exit #include // Para exception #include // Para exists, path, remove #include // Para basic_ofstream, basic_ios, basic_ostream::write, ios, ofstream #include // Para std::cout +#include // Para back_inserter #include // Para __find_if_fn, find_if, __find_fn, find #include // Para runtime_error #include // Para move @@ -138,40 +140,37 @@ void Resource::loadEssentialTextures() { // Inicializa las listas de recursos sin cargar el contenido (modo lazy) void Resource::initResourceLists() { + const auto file_to_name = [](const auto& file) { return getFileName(file); }; + // Inicializa lista de sonidos - auto sound_list = Asset::get()->getListByType(Asset::Type::SOUND); + const auto sound_list = Asset::get()->getListByType(Asset::Type::SOUND); sounds_.clear(); - for (const auto& file : sound_list) { - sounds_.emplace_back(getFileName(file)); - } + sounds_.reserve(sound_list.size()); + std::ranges::transform(sound_list, std::back_inserter(sounds_), [&](const auto& file) { return ResourceSound(file_to_name(file)); }); // Inicializa lista de músicas - auto music_list = Asset::get()->getListByType(Asset::Type::MUSIC); + const auto music_list = Asset::get()->getListByType(Asset::Type::MUSIC); musics_.clear(); - for (const auto& file : music_list) { - musics_.emplace_back(getFileName(file)); - } + musics_.reserve(music_list.size()); + std::ranges::transform(music_list, std::back_inserter(musics_), [&](const auto& file) { return ResourceMusic(file_to_name(file)); }); // Inicializa lista de texturas - auto texture_list = Asset::get()->getListByType(Asset::Type::BITMAP); + const auto texture_list = Asset::get()->getListByType(Asset::Type::BITMAP); textures_.clear(); - for (const auto& file : texture_list) { - textures_.emplace_back(getFileName(file)); - } + textures_.reserve(texture_list.size()); + std::ranges::transform(texture_list, std::back_inserter(textures_), [&](const auto& file) { return ResourceTexture(file_to_name(file)); }); // Inicializa lista de ficheros de texto - auto text_file_list = Asset::get()->getListByType(Asset::Type::FONT); + const auto text_file_list = Asset::get()->getListByType(Asset::Type::FONT); text_files_.clear(); - for (const auto& file : text_file_list) { - text_files_.emplace_back(getFileName(file)); - } + text_files_.reserve(text_file_list.size()); + std::ranges::transform(text_file_list, std::back_inserter(text_files_), [&](const auto& file) { return ResourceTextFile(file_to_name(file)); }); // Inicializa lista de animaciones - auto animation_list = Asset::get()->getListByType(Asset::Type::ANIMATION); + const auto animation_list = Asset::get()->getListByType(Asset::Type::ANIMATION); animations_.clear(); - for (const auto& file : animation_list) { - animations_.emplace_back(getFileName(file)); - } + animations_.reserve(animation_list.size()); + std::ranges::transform(animation_list, std::back_inserter(animations_), [&](const auto& file) { return ResourceAnimation(file_to_name(file)); }); // Los demos se cargan directamente sin mostrar progreso (son pocos y pequeños) loadDemoDataQuiet(); @@ -192,9 +191,8 @@ void Resource::initResourceLists() { "smb2_grad"}; texts_.clear(); - for (const auto& text_name : TEXT_OBJECTS) { - texts_.emplace_back(text_name); // Constructor con nullptr por defecto - } + texts_.reserve(TEXT_OBJECTS.size()); + std::ranges::transform(TEXT_OBJECTS, std::back_inserter(texts_), [](const auto& text_name) { return ResourceText(text_name); }); } // Obtiene el sonido a partir de un nombre (con carga perezosa) @@ -336,23 +334,17 @@ auto Resource::loadMusicLazy(const std::string& name) -> JA_Music_t* { } auto Resource::loadTextureLazy(const std::string& name) -> std::shared_ptr { - auto texture_list = Asset::get()->getListByType(Asset::Type::BITMAP); - for (const auto& file : texture_list) { - if (getFileName(file) == name) { - return std::make_shared(Screen::get()->getRenderer(), file); - } - } - return nullptr; + const auto texture_list = Asset::get()->getListByType(Asset::Type::BITMAP); + const auto it = std::ranges::find_if(texture_list, + [&name](const auto& file) { return getFileName(file) == name; }); + return it != texture_list.end() ? std::make_shared(Screen::get()->getRenderer(), *it) : nullptr; } auto Resource::loadTextFileLazy(const std::string& name) -> std::shared_ptr { - auto text_file_list = Asset::get()->getListByType(Asset::Type::FONT); - for (const auto& file : text_file_list) { - if (getFileName(file) == name) { - return Text::loadFile(file); - } - } - return nullptr; + const auto text_file_list = Asset::get()->getListByType(Asset::Type::FONT); + const auto it = std::ranges::find_if(text_file_list, + [&name](const auto& file) { return getFileName(file) == name; }); + return it != text_file_list.end() ? Text::loadFile(*it) : nullptr; } auto Resource::loadTextLazy(const std::string& name) -> std::shared_ptr { @@ -377,27 +369,22 @@ auto Resource::loadTextLazy(const std::string& name) -> std::shared_ptr { {.key = "smb2", .texture_file = "smb2.png", .text_file = "smb2.txt"}, {.key = "smb2_grad", .texture_file = "smb2_grad.png", .text_file = "smb2.txt"}}; - for (const auto& mapping : TEXT_MAPPINGS) { - if (mapping.key == name) { - // Cargar las dependencias automáticamente - auto texture = getTexture(mapping.texture_file); // Esto cargará la textura si no está cargada - auto text_file = getTextFile(mapping.text_file); // Esto cargará el archivo de texto si no está cargado - - if (texture && text_file) { - return std::make_shared(texture, text_file); - } - } + const auto it = std::ranges::find_if(TEXT_MAPPINGS, + [&name](const auto& mapping) { return mapping.key == name; }); + if (it == TEXT_MAPPINGS.end()) { + return nullptr; } - - return nullptr; + auto texture = getTexture(it->texture_file); // Esto cargará la textura si no está cargada + auto text_file = getTextFile(it->text_file); // Esto cargará el archivo de texto si no está cargado + return (texture && text_file) ? std::make_shared(texture, text_file) : nullptr; } auto Resource::loadAnimationLazy(const std::string& name) -> AnimationsFileBuffer { - auto animation_list = Asset::get()->getListByType(Asset::Type::ANIMATION); - for (const auto& file : animation_list) { - if (getFileName(file) == name) { - return loadAnimationsFromFile(file); - } + const auto animation_list = Asset::get()->getListByType(Asset::Type::ANIMATION); + const auto it = std::ranges::find_if(animation_list, + [&name](const auto& file) { return getFileName(file) == name; }); + if (it != animation_list.end()) { + return loadAnimationsFromFile(*it); } // Si no se encuentra, retorna vector vacío return AnimationsFileBuffer{}; @@ -640,14 +627,10 @@ void Resource::createPlayerTextures() { const auto& player = players[player_idx]; // Obtenemos el jugador actual // Encontrar el archivo original de la textura - std::string texture_file_path; - auto texture_list = Asset::get()->getListByType(Asset::Type::BITMAP); - for (const auto& file : texture_list) { - if (getFileName(file) == player.base_texture) { - texture_file_path = file; - break; - } - } + const auto texture_list = Asset::get()->getListByType(Asset::Type::BITMAP); + const auto it = std::ranges::find_if(texture_list, + [&player](const auto& file) { return getFileName(file) == player.base_texture; }); + const std::string texture_file_path = (it != texture_list.end()) ? *it : std::string{}; // Crear las 4 texturas con sus respectivas paletas for (int palette_idx = 0; palette_idx < 4; ++palette_idx) { @@ -720,9 +703,9 @@ void Resource::createTextTextures() { {"game_text_1000000_points", Lang::getText("[GAME_TEXT] 8")}}; auto text1 = getText("04b_25_enhanced"); - for (const auto& s : strings1) { - textures_.emplace_back(s.name, text1->writeDXToTexture(Text::STROKE, s.text, -2, Colors::NO_COLOR_MOD, 1, param.game.item_text_outline_color)); - } + std::ranges::transform(strings1, std::back_inserter(textures_), [&](const auto& s) { + return ResourceTexture(s.name, text1->writeDXToTexture(Text::STROKE, s.text, -2, Colors::NO_COLOR_MOD, 1, param.game.item_text_outline_color)); + }); // Texturas de tamaño doble std::vector strings2 = { @@ -734,9 +717,9 @@ void Resource::createTextTextures() { {"game_text_game_over", "Game Over"}}; auto text2 = getText("04b_25_2x_enhanced"); - for (const auto& s : strings2) { - textures_.emplace_back(s.name, text2->writeDXToTexture(Text::STROKE, s.text, -4, Colors::NO_COLOR_MOD, 1, param.game.item_text_outline_color)); - } + std::ranges::transform(strings2, std::back_inserter(textures_), [&](const auto& s) { + return ResourceTexture(s.name, text2->writeDXToTexture(Text::STROKE, s.text, -4, Colors::NO_COLOR_MOD, 1, param.game.item_text_outline_color)); + }); } // Crea los objetos de texto a partir de los archivos de textura y texto @@ -897,12 +880,10 @@ void Resource::renderProgress() { // Carga los datos para el modo demostración (sin mostrar progreso) void Resource::loadDemoDataQuiet() { - auto list = Asset::get()->getListByType(Asset::Type::DEMODATA); + const auto list = Asset::get()->getListByType(Asset::Type::DEMODATA); demos_.clear(); - - for (const auto& l : list) { - demos_.emplace_back(loadDemoDataFromFile(l)); - } + demos_.reserve(list.size()); + std::ranges::transform(list, std::back_inserter(demos_), [this](const auto& l) { return loadDemoDataFromFile(l); }); } // Inicializa los rectangulos que definen la barra de progreso diff --git a/source/core/resources/resource.hpp b/source/core/resources/resource.hpp index d66cbbf..be69c07 100644 --- a/source/core/resources/resource.hpp +++ b/source/core/resources/resource.hpp @@ -60,7 +60,7 @@ class Resource { std::string name; // Nombre del sonido JA_Sound_t* sound; // Objeto con el sonido - ResourceSound(std::string name, JA_Sound_t* sound = nullptr) + explicit ResourceSound(std::string name, JA_Sound_t* sound = nullptr) : name(std::move(name)), sound(sound) {} }; @@ -69,7 +69,7 @@ class Resource { std::string name; // Nombre de la música JA_Music_t* music; // Objeto con la música - ResourceMusic(std::string name, JA_Music_t* music = nullptr) + explicit ResourceMusic(std::string name, JA_Music_t* music = nullptr) : name(std::move(name)), music(music) {} }; @@ -78,7 +78,7 @@ class Resource { std::string name; // Nombre de la textura std::shared_ptr texture; // Objeto con la textura - ResourceTexture(std::string name, std::shared_ptr texture = nullptr) + explicit ResourceTexture(std::string name, std::shared_ptr texture = nullptr) : name(std::move(name)), texture(std::move(texture)) {} }; @@ -87,7 +87,7 @@ class Resource { std::string name; // Nombre del fichero std::shared_ptr text_file; // Objeto con los descriptores de la fuente de texto - ResourceTextFile(std::string name, std::shared_ptr text_file = nullptr) + explicit ResourceTextFile(std::string name, std::shared_ptr text_file = nullptr) : name(std::move(name)), text_file(std::move(text_file)) {} }; @@ -96,7 +96,7 @@ class Resource { std::string name; // Nombre del objeto std::shared_ptr text; // Objeto de texto - ResourceText(std::string name, std::shared_ptr text = nullptr) + explicit ResourceText(std::string name, std::shared_ptr text = nullptr) : name(std::move(name)), text(std::move(text)) {} }; @@ -105,7 +105,7 @@ class Resource { std::string name; // Nombre de la animación AnimationsFileBuffer animation; // Objeto con las animaciones - ResourceAnimation(std::string name, AnimationsFileBuffer animation = {}) + explicit ResourceAnimation(std::string name, AnimationsFileBuffer animation = {}) : name(std::move(name)), animation(std::move(animation)) {} }; @@ -116,7 +116,7 @@ class Resource { size_t loaded{0}; // Número de recursos cargados ResourceCount() = default; - ResourceCount(size_t total) + explicit ResourceCount(size_t total) : total(total) {} void add(size_t amount) { loaded += amount; } diff --git a/source/core/resources/resource_helper.hpp b/source/core/resources/resource_helper.hpp index 2139c16..8b6732e 100644 --- a/source/core/resources/resource_helper.hpp +++ b/source/core/resources/resource_helper.hpp @@ -1,10 +1,8 @@ #pragma once -#include // Para uint8_t -#include // Para remove, path -#include // Para basic_ofstream, basic_ios, basic_ostream::write, ios, ofstream -#include // Para string, basic_string, hash, operator+, to_string, __str_hash_base -#include // Para vector +#include // Para uint8_t +#include // Para string +#include // Para vector // Helper functions para integrar ResourceLoader con el sistema existente namespace ResourceHelper { @@ -22,24 +20,4 @@ namespace ResourceHelper { // Convierte ruta Asset a ruta relativa para ResourceLoader auto getPackPath(const std::string& asset_path) -> std::string; - - // Wrappea la carga de archivos para mantener compatibilidad - template - auto loadResourceFile(const std::string& asset_path, T* (*loader_func)(const char*)) -> T* { - auto data = loadFile(asset_path); - if (data.empty()) { - return loader_func(asset_path.c_str()); - } - - // Crear archivo temporal para funciones que esperan path - std::string temp_path = "/tmp/ccae_" + std::to_string(std::hash{}(asset_path)); - std::ofstream temp_file(temp_path, std::ios::binary); - temp_file.write(reinterpret_cast(data.data()), data.size()); - temp_file.close(); - - T* result = loader_func(temp_path.c_str()); - std::filesystem::remove(temp_path); - - return result; - } } // namespace ResourceHelper \ No newline at end of file diff --git a/source/core/resources/resource_pack.cpp b/source/core/resources/resource_pack.cpp index b788484..540ddbf 100644 --- a/source/core/resources/resource_pack.cpp +++ b/source/core/resources/resource_pack.cpp @@ -1,10 +1,11 @@ #include "core/resources/resource_pack.hpp" -#include // Para replace +#include // Para replace, ranges::all_of #include // Para array #include // Para path, recursive_directory_iterator, directory_entry, exists, relative #include // Para basic_ifstream, basic_ostream, basic_ofstream, operator<<, basic_ios, basic_istream::read, basic_ostream::write, endl, ios, basic_istream, ifstream, operator|, basic_istream::seekg, basic_istream::tellg, ofstream, streamsize #include // Para cerr +#include // Para accumulate #include // Para pair const std::string ResourcePack::DEFAULT_ENCRYPT_KEY = "CCAE_RESOURCES__2024"; @@ -17,11 +18,7 @@ ResourcePack::~ResourcePack() { } auto ResourcePack::calculateChecksum(const std::vector& data) -> uint32_t { - uint32_t checksum = 0x12345678; - for (unsigned char i : data) { - checksum = ((checksum << 5) + checksum) + i; - } - return checksum; + return std::accumulate(data.begin(), data.end(), static_cast(0x12345678), [](uint32_t checksum, unsigned char i) { return ((checksum << 5) + checksum) + i; }); } void ResourcePack::encryptData(std::vector& data, const std::string& key) { @@ -162,20 +159,16 @@ auto ResourcePack::addDirectory(const std::string& directory) -> bool { return false; // NOLINT(readability-simplify-boolean-expr) } - for (const auto& entry : std::filesystem::recursive_directory_iterator(directory)) { - if (entry.is_regular_file()) { + return std::ranges::all_of(std::filesystem::recursive_directory_iterator(directory), + [this, &directory](const auto& entry) { + if (!entry.is_regular_file()) { + return true; + } std::string filepath = entry.path().string(); std::string filename = std::filesystem::relative(entry.path(), directory).string(); - std::ranges::replace(filename, '\\', '/'); - - if (!addFile(filename, filepath)) { - return false; - } - } - } - - return true; + return addFile(filename, filepath); + }); } auto ResourcePack::getResource(const std::string& filename) -> std::vector { diff --git a/source/core/system/director.cpp b/source/core/system/director.cpp index 6738d48..7920d4e 100644 --- a/source/core/system/director.cpp +++ b/source/core/system/director.cpp @@ -520,7 +520,7 @@ auto Director::iterate() -> SDL_AppResult { } // Procesa un evento SDL (llamado desde SDL_AppEvent) -auto Director::handleEvent(SDL_Event& event) -> SDL_AppResult { +auto Director::handleEvent(const SDL_Event& event) -> SDL_AppResult { // Eventos globales (SDL_EVENT_QUIT, resize, render target reset, hotplug, service menu, ratón) GlobalEvents::handle(event); diff --git a/source/core/system/director.hpp b/source/core/system/director.hpp index 31e02ed..6d44ad7 100644 --- a/source/core/system/director.hpp +++ b/source/core/system/director.hpp @@ -29,8 +29,8 @@ class Director { ~Director(); // --- Callbacks para SDL_MAIN_USE_CALLBACKS --- - auto iterate() -> SDL_AppResult; // Avanza un frame de la sección activa - auto handleEvent(SDL_Event& event) -> SDL_AppResult; // Procesa un evento SDL + auto iterate() -> SDL_AppResult; // Avanza un frame de la sección activa + auto handleEvent(const SDL_Event& event) -> SDL_AppResult; // Procesa un evento SDL // --- Debug config (accesible desde otras clases) --- struct DebugConfig { diff --git a/source/game/entities/balloon.hpp b/source/game/entities/balloon.hpp index 29bf696..957bcca 100644 --- a/source/game/entities/balloon.hpp +++ b/source/game/entities/balloon.hpp @@ -85,7 +85,7 @@ class Balloon { }; // --- Constructores y destructor --- - Balloon(const Config& config); + explicit Balloon(const Config& config); ~Balloon() = default; // --- Métodos principales --- diff --git a/source/game/entities/player.cpp b/source/game/entities/player.cpp index 130b7cd..ec8f5e8 100644 --- a/source/game/entities/player.cpp +++ b/source/game/entities/player.cpp @@ -977,7 +977,7 @@ void Player::playSound(const std::string& name) const { return; } - static auto* audio_ = Audio::get(); + static const auto* audio_ = Audio::get(); audio_->playSound(name); } diff --git a/source/game/entities/player.hpp b/source/game/entities/player.hpp index f4aca90..1ab93ef 100644 --- a/source/game/entities/player.hpp +++ b/source/game/entities/player.hpp @@ -114,7 +114,7 @@ class Player { }; // --- Constructor y destructor --- - Player(const Config& config); + explicit Player(const Config& config); ~Player() = default; // --- Inicialización y ciclo de vida --- @@ -201,16 +201,16 @@ class Player { [[nodiscard]] auto getCoffees() const -> int { return coffees_; } [[nodiscard]] auto getPowerUpCounter() const -> int { return power_up_counter_; } [[nodiscard]] auto getInvulnerableCounter() const -> int { return invulnerable_counter_; } - [[nodiscard]] auto getBulletColor() const -> Bullet::Color; // Devuelve el color actual de bala según el estado - auto getNextBulletColor() -> Bullet::Color; // Devuelve el color para la próxima bala (alterna si está en modo toggle) - void setBulletColors(Bullet::Color normal, Bullet::Color powered); // Establece los colores de bala para este jugador - [[nodiscard]] auto getBulletSoundFile() const -> std::string { return bullet_sound_file_; } // Devuelve el archivo de sonido de bala - void setBulletSoundFile(const std::string& filename); // Establece el archivo de sonido de bala para este jugador + [[nodiscard]] auto getBulletColor() const -> Bullet::Color; // Devuelve el color actual de bala según el estado + auto getNextBulletColor() -> Bullet::Color; // Devuelve el color para la próxima bala (alterna si está en modo toggle) + void setBulletColors(Bullet::Color normal, Bullet::Color powered); // Establece los colores de bala para este jugador + [[nodiscard]] auto getBulletSoundFile() const -> const std::string& { return bullet_sound_file_; } // Devuelve el archivo de sonido de bala + void setBulletSoundFile(const std::string& filename); // Establece el archivo de sonido de bala para este jugador // Contadores y timers [[nodiscard]] auto getContinueCounter() const -> int { return continue_counter_; } [[nodiscard]] auto getRecordName() const -> std::string { return enter_name_ ? enter_name_->getFinalName() : "xxx"; } - [[nodiscard]] auto getLastEnterName() const -> std::string { return last_enter_name_; } + [[nodiscard]] auto getLastEnterName() const -> const std::string& { return last_enter_name_; } // --- Configuración e interfaz externa --- void setName(const std::string& name) { name_ = name; } diff --git a/source/game/gameplay/balloon_formations.cpp b/source/game/gameplay/balloon_formations.cpp index 95b30e7..8c66904 100644 --- a/source/game/gameplay/balloon_formations.cpp +++ b/source/game/gameplay/balloon_formations.cpp @@ -222,13 +222,13 @@ void BalloonFormations::createFloaterVariants() { formations_.resize(100); // Crear variantes flotantes de las primeras 50 formaciones - for (size_t k = 0; k < 50 && k < formations_.size(); k++) { + for (size_t k = 0; k < 50; k++) { + const auto& source = formations_.at(k).balloons; std::vector floater_params; - floater_params.reserve(formations_.at(k).balloons.size()); - - 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); - } + floater_params.reserve(source.size()); + std::ranges::transform(source, std::back_inserter(floater_params), [](const auto& original) { + return SpawnParams{original.x, original.y, original.vel_x, Balloon::Type::FLOATER, original.size, original.creation_counter}; + }); formations_.at(k + 50) = Formation(floater_params); } @@ -395,24 +395,21 @@ void BalloonFormations::loadDefaultPools() { } } - // Pool 2: Mix de formaciones normales y floaters (50+) + // Pools 2 i 3: requereixen formacions de floaters (>50) if (total_formations > 50) { + // Pool 2: Mix de formacions normals i floaters Pool pool2; - // Agregar algunas formaciones básicas for (size_t i = 0; i < std::min(static_cast(5), total_formations); ++i) { pool2.push_back(static_cast(i)); } - // Agregar algunas floaters si existen for (size_t i = 50; i < std::min(static_cast(55), total_formations); ++i) { pool2.push_back(static_cast(i)); } if (!pool2.empty()) { pools_.push_back(pool2); } - } - // Pool 3: Solo floaters (si existen formaciones 50+) - if (total_formations > 50) { + // Pool 3: Només floaters Pool pool3; for (size_t i = 50; i < std::min(static_cast(70), total_formations); ++i) { pool3.push_back(static_cast(i)); diff --git a/source/game/gameplay/balloon_formations.hpp b/source/game/gameplay/balloon_formations.hpp index 2a0c6dd..58ea784 100644 --- a/source/game/gameplay/balloon_formations.hpp +++ b/source/game/gameplay/balloon_formations.hpp @@ -39,7 +39,7 @@ class BalloonFormations { std::vector balloons; // Vector con todas las inicializaciones de los globos de la formación // Constructor con parámetros - Formation(const std::vector& spawn_params) + explicit Formation(const std::vector& spawn_params) : balloons(spawn_params) {} // Constructor por defecto diff --git a/source/game/gameplay/balloon_manager.cpp b/source/game/gameplay/balloon_manager.cpp index cb234b4..c73bde6 100644 --- a/source/game/gameplay/balloon_manager.cpp +++ b/source/game/gameplay/balloon_manager.cpp @@ -106,7 +106,7 @@ void BalloonManager::deployRandomFormation(int stage) { // Crea los globos de la formación const auto BALLOONS = balloon_formations_->getFormationFromPool(stage, formation_id).balloons; - for (auto balloon : BALLOONS) { + for (const auto& balloon : BALLOONS) { Balloon::Config config = { .x = balloon.x, .y = balloon.y, @@ -127,7 +127,7 @@ void BalloonManager::deployRandomFormation(int stage) { // Crea una formación de globos específica void BalloonManager::deployFormation(int formation_id) { const auto BALLOONS = balloon_formations_->getFormation(formation_id).balloons; - for (auto balloon : BALLOONS) { + for (const auto& balloon : BALLOONS) { Balloon::Config config = { .x = balloon.x, .y = balloon.y, @@ -143,7 +143,7 @@ void BalloonManager::deployFormation(int formation_id) { // Crea una formación de globos específica a una altura determinada void BalloonManager::deployFormation(int formation_id, float y) { const auto BALLOONS = balloon_formations_->getFormation(formation_id).balloons; - for (auto balloon : BALLOONS) { + for (const auto& balloon : BALLOONS) { Balloon::Config config = { .x = balloon.x, .y = y, diff --git a/source/game/gameplay/balloon_manager.hpp b/source/game/gameplay/balloon_manager.hpp index 234ac1c..30607f0 100644 --- a/source/game/gameplay/balloon_manager.hpp +++ b/source/game/gameplay/balloon_manager.hpp @@ -24,7 +24,7 @@ using Balloons = std::list>; class BalloonManager { public: // --- Constructor y destructor --- - BalloonManager(IStageInfo* stage_info); + explicit BalloonManager(IStageInfo* stage_info); ~BalloonManager() = default; // --- Métodos principales --- diff --git a/source/game/gameplay/bullet_manager.cpp b/source/game/gameplay/bullet_manager.cpp index daf23c9..89629b3 100644 --- a/source/game/gameplay/bullet_manager.cpp +++ b/source/game/gameplay/bullet_manager.cpp @@ -14,7 +14,7 @@ BulletManager::BulletManager() // Actualiza el estado de todas las balas void BulletManager::update(float delta_time) { - for (auto& bullet : bullets_) { + for (const auto& bullet : bullets_) { if (bullet->isEnabled()) { processBulletUpdate(bullet, delta_time); } @@ -23,7 +23,7 @@ void BulletManager::update(float delta_time) { // Renderiza todas las balas activas void BulletManager::render() { - for (auto& bullet : bullets_) { + for (const auto& bullet : bullets_) { if (bullet->isEnabled()) { bullet->render(); } diff --git a/source/game/gameplay/cooldown.hpp b/source/game/gameplay/cooldown.hpp index 46eb8f2..c647a2a 100644 --- a/source/game/gameplay/cooldown.hpp +++ b/source/game/gameplay/cooldown.hpp @@ -4,7 +4,7 @@ class Cooldown { public: - Cooldown(float first_delay_s = 0.0F, float repeat_delay_s = 0.0F) + explicit Cooldown(float first_delay_s = 0.0F, float repeat_delay_s = 0.0F) : first_delay_s_(first_delay_s), repeat_delay_s_(repeat_delay_s) {} diff --git a/source/game/gameplay/difficulty.cpp b/source/game/gameplay/difficulty.cpp index f771702..05628ac 100644 --- a/source/game/gameplay/difficulty.cpp +++ b/source/game/gameplay/difficulty.cpp @@ -1,6 +1,7 @@ #include "game/gameplay/difficulty.hpp" -#include // Para vector +#include // Para ranges::find_if +#include // Para vector namespace Difficulty { @@ -18,19 +19,19 @@ namespace Difficulty { } auto getNameFromCode(Code code) -> std::string { - for (const auto& difficulty : difficulties_list) { - if (difficulty.code == code) { - return difficulty.name; - } + const auto it = std::ranges::find_if(difficulties_list, + [code](const auto& difficulty) { return difficulty.code == code; }); + if (it != difficulties_list.end()) { + return it->name; } return !difficulties_list.empty() ? difficulties_list.front().name : "Unknown"; } auto getCodeFromName(const std::string& name) -> Code { - for (const auto& difficulty : difficulties_list) { - if (difficulty.name == name) { - return difficulty.code; - } + const auto it = std::ranges::find_if(difficulties_list, + [&name](const auto& difficulty) { return difficulty.name == name; }); + if (it != difficulties_list.end()) { + return it->code; } return !difficulties_list.empty() ? difficulties_list.front().code : Code::NORMAL; } diff --git a/source/game/gameplay/enter_name.hpp b/source/game/gameplay/enter_name.hpp index 65abdfa..aa0fa5b 100644 --- a/source/game/gameplay/enter_name.hpp +++ b/source/game/gameplay/enter_name.hpp @@ -21,7 +21,7 @@ class EnterName { void removeLastCharacter(); // Elimina el último carácter del nombre auto getFinalName() -> std::string; // Obtiene el nombre final (o aleatorio si vacío) - [[nodiscard]] auto getCurrentName() const -> std::string { return name_; } // Obtiene el nombre actual en proceso + [[nodiscard]] auto getCurrentName() const -> const std::string& { return name_; } // Obtiene el nombre actual en proceso [[nodiscard]] auto getSelectedCharacter(int offset = 0) const -> std::string; // Devuelve el carácter seleccionado con offset relativo [[nodiscard]] auto getCarousel(int size) const -> std::string; // Devuelve el carrusel de caracteres (size debe ser impar) [[nodiscard]] auto getSelectedIndex() const -> int { return selected_index_; } // Obtiene el índice del carácter seleccionado diff --git a/source/game/gameplay/manage_hiscore_table.cpp b/source/game/gameplay/manage_hiscore_table.cpp index 3c852c6..b2cde74 100644 --- a/source/game/gameplay/manage_hiscore_table.cpp +++ b/source/game/gameplay/manage_hiscore_table.cpp @@ -8,6 +8,7 @@ #include // Para std::setw, std::setfill #include // Para std::cout #include // Para distance +#include // Para accumulate #include // Para __find_if_fn, find_if #include // Para move @@ -260,22 +261,11 @@ auto ManageHiScoreTable::verifyChecksum(SDL_IOStream* file, const std::string& f // Calcula checksum de la tabla auto ManageHiScoreTable::calculateChecksum(const Table& table) -> unsigned int { - unsigned int checksum = 0x12345678; // Magic seed - - for (const auto& entry : table) { - // Checksum del score + return std::accumulate(table.begin(), table.end(), 0x12345678U, [](unsigned int checksum, const auto& entry) { checksum = ((checksum << 5) + checksum) + static_cast(entry.score); - - // Checksum del nombre - for (char c : entry.name) { - checksum = ((checksum << 5) + checksum) + static_cast(c); - } - - // Checksum de one_credit_complete - checksum = ((checksum << 5) + checksum) + (entry.one_credit_complete ? 1U : 0U); - } - - return checksum; + checksum = std::accumulate(entry.name.begin(), entry.name.end(), checksum, [](unsigned int acc, char c) { return ((acc << 5) + acc) + static_cast(c); }); + return ((checksum << 5) + checksum) + (entry.one_credit_complete ? 1U : 0U); + }); } // Guarda la tabla en un fichero diff --git a/source/game/gameplay/scoreboard.cpp b/source/game/gameplay/scoreboard.cpp index 152cc0c..94e9454 100644 --- a/source/game/gameplay/scoreboard.cpp +++ b/source/game/gameplay/scoreboard.cpp @@ -724,7 +724,7 @@ void Scoreboard::renderSeparator() { // Pinta el carrusel de caracteres con efecto de color LERP y animación suave void Scoreboard::renderCarousel(size_t panel_index, int center_x, int y) { // Obtener referencia a EnterName - EnterName* enter_name = enter_name_ref_.at(panel_index); + const EnterName* enter_name = enter_name_ref_.at(panel_index); if (enter_name == nullptr) { return; } diff --git a/source/game/gameplay/stage.cpp b/source/game/gameplay/stage.cpp index 415cefe..9d549ec 100644 --- a/source/game/gameplay/stage.cpp +++ b/source/game/gameplay/stage.cpp @@ -3,6 +3,7 @@ #include // Para max, min #include // Para exception #include // Para basic_istream, basic_ifstream, ifstream, stringstream +#include // Para accumulate #include // Para basic_stringstream #include // Para move @@ -282,11 +283,7 @@ auto StageManager::getPowerNeededForCurrentStage() const -> int { } auto StageManager::getTotalPowerNeededToCompleteGame() const -> int { - int total_power_needed = 0; - for (const auto& stage : stages_) { - total_power_needed += stage.getPowerToComplete(); - } - return total_power_needed; + return std::accumulate(stages_.begin(), stages_.end(), 0, [](int total, const auto& stage) { return total + stage.getPowerToComplete(); }); } auto StageManager::getPowerNeededToReachStage(size_t target_stage_index) const -> int { diff --git a/source/game/options.cpp b/source/game/options.cpp index 1380742..e56c77c 100644 --- a/source/game/options.cpp +++ b/source/game/options.cpp @@ -2,7 +2,7 @@ #include // Para SDL_ScaleMode, SDL_LogCategory, SDL_LogError, SDL_LogInfo, SDL_LogWarn -#include // Para clamp +#include // Para clamp, ranges::find_if #include // Para size_t #include // Para ifstream, ofstream #include // Para std::cout @@ -820,14 +820,14 @@ namespace Options { continue; } - for (const auto& physical_gamepad : physical_gamepads) { - if (physical_gamepad->path == desired_path && !isGamepadAssigned(physical_gamepad, assigned_instances)) { - gamepads_[i].instance = physical_gamepad; - gamepads_[i].name = physical_gamepad->name; - - assigned_instances.push_back(physical_gamepad); - break; - } + const auto it = std::ranges::find_if(physical_gamepads, + [this, &desired_path, &assigned_instances](const auto& pg) { + return pg->path == desired_path && !isGamepadAssigned(pg, assigned_instances); + }); + if (it != physical_gamepads.end()) { + gamepads_[i].instance = *it; + gamepads_[i].name = (*it)->name; + assigned_instances.push_back(*it); } } } @@ -849,15 +849,15 @@ namespace Options { continue; } - for (const auto& physical_gamepad : physical_gamepads) { - if (physical_gamepad->name == desired_name && !isGamepadAssigned(physical_gamepad, assigned_instances)) { - gamepads_[i].instance = physical_gamepad; - gamepads_[i].name = physical_gamepad->name; - gamepads_[i].path = physical_gamepad->path; - - assigned_instances.push_back(physical_gamepad); - break; - } + const auto it = std::ranges::find_if(physical_gamepads, + [this, &desired_name, &assigned_instances](const auto& pg) { + return pg->name == desired_name && !isGamepadAssigned(pg, assigned_instances); + }); + if (it != physical_gamepads.end()) { + gamepads_[i].instance = *it; + gamepads_[i].name = (*it)->name; + gamepads_[i].path = (*it)->path; + assigned_instances.push_back(*it); } } } @@ -871,15 +871,15 @@ namespace Options { continue; } - for (const auto& physical_gamepad : physical_gamepads) { - if (!isGamepadAssigned(physical_gamepad, assigned_instances)) { - gamepads_[i].instance = physical_gamepad; - gamepads_[i].name = physical_gamepad->name; - gamepads_[i].path = physical_gamepad->path; - - assigned_instances.push_back(physical_gamepad); - break; - } + const auto it = std::ranges::find_if(physical_gamepads, + [this, &assigned_instances](const auto& pg) { + return !isGamepadAssigned(pg, assigned_instances); + }); + if (it != physical_gamepads.end()) { + gamepads_[i].instance = *it; + gamepads_[i].name = (*it)->name; + gamepads_[i].path = (*it)->path; + assigned_instances.push_back(*it); } } } diff --git a/source/game/options.hpp b/source/game/options.hpp index 7070b6f..f556743 100644 --- a/source/game/options.hpp +++ b/source/game/options.hpp @@ -141,7 +141,7 @@ namespace Options { std::string path; // Ruta física del dispositivo Player::Id player_id; // Jugador asociado al mando - Gamepad(Player::Id custom_player_id = Player::Id::NO_PLAYER) + explicit Gamepad(Player::Id custom_player_id = Player::Id::NO_PLAYER) : player_id(custom_player_id) {} }; diff --git a/source/game/scenes/credits.cpp b/source/game/scenes/credits.cpp index 842aedc..b1ccd73 100644 --- a/source/game/scenes/credits.cpp +++ b/source/game/scenes/credits.cpp @@ -683,10 +683,11 @@ void Credits::startCredits() { init_right_x_ = static_cast(right_black_rect_.x); // Objetivos + const int CENTER_X = param.game.game_area.center_x; int top_target_h = param.game.game_area.center_y - 1; int bottom_target_y = param.game.game_area.center_y + 1; - int left_target_w = param.game.game_area.center_x; - int right_target_x = param.game.game_area.center_x; + int left_target_w = CENTER_X; + int right_target_x = CENTER_X; // Pasos verticales int pasos_top = std::max(0, top_target_h - init_top_h_); diff --git a/source/game/scenes/game.cpp b/source/game/scenes/game.cpp index 908ffea..988542a 100644 --- a/source/game/scenes/game.cpp +++ b/source/game/scenes/game.cpp @@ -801,7 +801,7 @@ void Game::renderPathSprites() { } // Acciones a realizar cuando el jugador colisiona con un globo -void Game::handlePlayerCollision(std::shared_ptr& player, std::shared_ptr& balloon) { +void Game::handlePlayerCollision(std::shared_ptr& player, const std::shared_ptr& balloon) { if (!player->isPlaying() || player->isInvulnerable()) { return; // Si no está jugando o tiene inmunidad, no hace nada } @@ -1243,18 +1243,6 @@ auto Game::getPlayer(Player::Id id) -> std::shared_ptr { return nullptr; } -// Obtiene un controlador a partir del "id" del jugador -auto Game::getController(Player::Id player_id) -> int { - switch (player_id) { - case Player::Id::PLAYER1: - return 0; - case Player::Id::PLAYER2: - return 1; - default: - return -1; - } -} - // Gestiona la entrada durante el juego void Game::checkInput() { Input::get()->update(); @@ -1293,11 +1281,12 @@ void Game::checkInput() { // Verifica si alguno de los controladores ha solicitado una pausa y actualiza el estado de pausa del juego. void Game::checkPauseInput() { // Comprueba los mandos - for (const auto& gamepad : input_->getGamepads()) { - if (input_->checkAction(Input::Action::PAUSE, Input::DO_NOT_ALLOW_REPEAT, Input::DO_NOT_CHECK_KEYBOARD, gamepad)) { - pause_manager_->togglePlayerPause(); - return; - } + const auto& gamepads = input_->getGamepads(); + if (std::ranges::any_of(gamepads, [this](const auto& gamepad) { + return input_->checkAction(Input::Action::PAUSE, Input::DO_NOT_ALLOW_REPEAT, Input::DO_NOT_CHECK_KEYBOARD, gamepad); + })) { + pause_manager_->togglePlayerPause(); + return; } // Comprueba el teclado @@ -1973,7 +1962,7 @@ void Game::playSound(const std::string& name) const { return; } - static auto* audio_ = Audio::get(); + static const auto* audio_ = Audio::get(); audio_->playSound(name); } @@ -2048,9 +2037,7 @@ void Game::handleGameOverEvents() { void Game::buildPlayerDrawList(const Players& elements, Players& draw_list) { draw_list.clear(); draw_list.reserve(elements.size()); - for (const auto& e : elements) { - draw_list.push_back(e); // copia el shared_ptr - } + std::ranges::copy(elements, std::back_inserter(draw_list)); std::ranges::stable_sort(draw_list, [](const std::shared_ptr& a, const std::shared_ptr& b) -> bool { return a->getZOrder() < b->getZOrder(); }); @@ -2154,8 +2141,8 @@ void Game::autoplayHandleInput() { // Comprueba los eventos en el modo DEBUG void Game::handleDebugEvents(const SDL_Event& event) { - static int formation_id_ = 0; if (event.type == SDL_EVENT_KEY_DOWN && static_cast(event.key.repeat) == 0) { + static int formation_id_ = 0; switch (event.key.key) { case SDLK_1: { // Crea una powerball balloon_manager_->createPowerBall(); @@ -2196,12 +2183,11 @@ void Game::handleDebugEvents(const SDL_Event& event) { break; } case SDLK_8: { - for (const auto& player : players_) { - if (player->isPlaying()) { - createItem(ItemType::COFFEE_MACHINE, player->getPosX(), param.game.game_area.rect.y - Item::COFFEE_MACHINE_HEIGHT); - coffee_machine_enabled_ = true; - break; - } + const auto it = std::ranges::find_if(players_, + [](const auto& player) { return player->isPlaying(); }); + if (it != players_.end()) { + createItem(ItemType::COFFEE_MACHINE, (*it)->getPosX(), param.game.game_area.rect.y - Item::COFFEE_MACHINE_HEIGHT); + coffee_machine_enabled_ = true; } break; } diff --git a/source/game/scenes/game.hpp b/source/game/scenes/game.hpp index 3130f76..9f2ea99 100644 --- a/source/game/scenes/game.hpp +++ b/source/game/scenes/game.hpp @@ -227,7 +227,6 @@ class Game { void updatePlayers(float delta_time); // Actualiza las variables y estados de los jugadores void renderPlayers(); // Renderiza todos los jugadores en pantalla 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 @@ -237,9 +236,9 @@ class Game { auto allPlayersAreNotPlaying() -> bool; // Verifica si ningún jugador está activo // --- Colisiones de jugadores --- - void handlePlayerCollision(std::shared_ptr& player, std::shared_ptr& balloon); // Procesa colisión de jugador con globo - auto checkPlayerBalloonCollision(std::shared_ptr& player) -> std::shared_ptr; // Detecta colisión jugador-globo - void checkPlayerItemCollision(std::shared_ptr& player); // Detecta colisión jugador-ítem + void handlePlayerCollision(std::shared_ptr& player, const std::shared_ptr& balloon); // Procesa colisión de jugador con globo + auto checkPlayerBalloonCollision(std::shared_ptr& player) -> std::shared_ptr; // Detecta colisión jugador-globo + void checkPlayerItemCollision(std::shared_ptr& player); // Detecta colisión jugador-ítem // --- Sistema de entrada (input) --- void checkInput(); // Gestiona toda la entrada durante el juego diff --git a/source/game/scenes/title.cpp b/source/game/scenes/title.cpp index d7b40f0..646bda9 100644 --- a/source/game/scenes/title.cpp +++ b/source/game/scenes/title.cpp @@ -245,9 +245,6 @@ void Title::run() { } } -// Reinicia el contador interno -void Title::resetCounter() { counter_time_ = 0.0F; } - // Intercambia la asignación de mandos a los jugadores void Title::swapControllers() { if (Input::get()->getNumGamepads() == 0) { diff --git a/source/game/scenes/title.hpp b/source/game/scenes/title.hpp index 5855193..04e09c1 100644 --- a/source/game/scenes/title.hpp +++ b/source/game/scenes/title.hpp @@ -107,7 +107,6 @@ class Title { auto calculateDeltaTime() -> float; // Calcula el tiempo transcurrido desde el último frame void updateState(float delta_time); // Actualiza el estado actual del título void setState(State state); // Cambia el estado del título - void resetCounter(); // Reinicia el contador interno // --- Entrada de usuario --- void checkEvents(); // Comprueba los eventos diff --git a/source/game/ui/menu_option.hpp b/source/game/ui/menu_option.hpp index a0657f3..bbf3c19 100644 --- a/source/game/ui/menu_option.hpp +++ b/source/game/ui/menu_option.hpp @@ -3,6 +3,7 @@ #include // Para max, clamp #include // Para size_t #include // Para function +#include // Para accumulate #include // Para allocator, string, basic_string, to_string, operator==, char_traits #include // Para move #include // Para vector @@ -174,11 +175,7 @@ class ListOption : public MenuOption { setter_(value_list_[list_index_]); } auto getMaxValueWidth(Text* text_renderer) const -> int override { - int max_w = 0; - for (const auto& val : value_list_) { - max_w = std::max(max_w, text_renderer->length(val, -2)); - } - return max_w; + return std::accumulate(value_list_.begin(), value_list_.end(), 0, [text_renderer](int max_w, const auto& val) { return std::max(max_w, text_renderer->length(val, -2)); }); } private: diff --git a/source/game/ui/menu_renderer.cpp b/source/game/ui/menu_renderer.cpp index bd3cca7..4099e0e 100644 --- a/source/game/ui/menu_renderer.cpp +++ b/source/game/ui/menu_renderer.cpp @@ -381,9 +381,7 @@ void MenuRenderer::updatePosition() { // Resto de métodos (sin cambios significativos) void MenuRenderer::precalculateMenuWidths(const std::vector>& all_options, const ServiceMenu* menu_state) { // NOLINT(readability-named-parameter) - for (int& w : group_menu_widths_) { - w = ServiceMenu::MIN_WIDTH; - } + std::ranges::fill(group_menu_widths_, ServiceMenu::MIN_WIDTH); for (int group = 0; group < 5; ++group) { auto sg = static_cast(group); int max_option_width = 0; @@ -433,33 +431,6 @@ auto MenuRenderer::getAnimatedSelectedColor() const -> Color { static auto color_cycle_ = Colors::generateMirroredCycle(param.service_menu.selected_color, ColorCycleStyle::HUE_WAVE); return color_cycle_.at(color_counter_ % color_cycle_.size()); } -auto MenuRenderer::setRect(SDL_FRect rect) -> SDL_FRect { - border_rect_ = {.x = rect.x - 1, .y = rect.y + 1, .w = rect.w + 2, .h = rect.h - 2}; - return rect; -} -auto MenuRenderer::getTruncatedValueWidth(const std::string& value, int available_width) const -> int { - int value_width = element_text_->length(value, -2); - 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_->length("...", -2); - int available_for_text = available_width - ellipsis_width; - - if (available_for_text <= 0) { - return ellipsis_width; // Solo mostramos los puntos suspensivos - } - - // Calculamos aproximadamente cuántos caracteres caben - float char_width = static_cast(value_width) / value.length(); - 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_->length(truncated, -2); -} auto MenuRenderer::getTruncatedValue(const std::string& value, int available_width) const -> std::string { int value_width = element_text_->length(value, -2); diff --git a/source/game/ui/menu_renderer.hpp b/source/game/ui/menu_renderer.hpp index 10d3784..b8849a0 100644 --- a/source/game/ui/menu_renderer.hpp +++ b/source/game/ui/menu_renderer.hpp @@ -82,8 +82,10 @@ class MenuRenderer { // --- Estructuras de Animación --- struct ResizeAnimation { bool active = false; - float start_width, start_height; - float target_width, target_height; + float start_width = 0.0F; + float start_height = 0.0F; + float target_width = 0.0F; + float target_height = 0.0F; float elapsed = 0.0F; float duration = 0.2F; @@ -97,7 +99,8 @@ class MenuRenderer { HIDING }; Type type = Type::NONE; bool active = false; - float target_width, target_height; + float target_width = 0.0F; + float target_height = 0.0F; float elapsed = 0.0F; float duration = 0.25F; @@ -140,8 +143,6 @@ class MenuRenderer { [[nodiscard]] auto getMenuWidthForGroup(ServiceMenu::SettingsGroup group) const -> int; [[nodiscard]] auto getAnimatedSelectedColor() const -> Color; void updateColorCounter(); - auto setRect(SDL_FRect rect) -> SDL_FRect; - [[nodiscard]] auto getTruncatedValueWidth(const std::string& value, int available_width) const -> int; [[nodiscard]] auto getTruncatedValue(const std::string& value, int available_width) const -> std::string; [[nodiscard]] static auto easeOut(float t) -> float; [[nodiscard]] auto shouldShowContent() const -> bool; diff --git a/source/game/ui/notifier.cpp b/source/game/ui/notifier.cpp index 2fe1f85..58c9331 100644 --- a/source/game/ui/notifier.cpp +++ b/source/game/ui/notifier.cpp @@ -2,8 +2,9 @@ #include // Para SDL_RenderFillRect, SDL_FRect, SDL_RenderClear -#include // Para remove_if, min -#include // Para basic_string, string +#include // Para ranges::transform, min +#include // Para back_inserter +#include // Para basic_string, string, erase_if #include #include // Para vector @@ -77,7 +78,7 @@ void Notifier::playNotificationSoundIfNeeded(const Notification& notification) { } void Notifier::updateNotificationState(int index, float delta_time) { - auto& notification = notifications_[index]; + const auto& notification = notifications_[index]; switch (notification.state) { case State::RISING: @@ -167,7 +168,7 @@ void Notifier::show(std::vector texts, int icon, const std::string& } // Elimina las cadenas vacías - texts.erase(std::ranges::remove_if(texts, [](const std::string& s) -> bool { return s.empty(); }).begin(), texts.end()); + std::erase_if(texts, [](const std::string& s) -> bool { return s.empty(); }); // Encuentra la cadena más larga std::string longest; @@ -303,8 +304,6 @@ void Notifier::clearAllNotifications() { auto Notifier::getCodes() -> std::vector { std::vector codes; codes.reserve(notifications_.size()); - for (const auto& notification : notifications_) { - codes.emplace_back(notification.code); - } + std::ranges::transform(notifications_, std::back_inserter(codes), [](const auto& notification) { return notification.code; }); return codes; } \ No newline at end of file diff --git a/source/game/ui/service_menu.cpp b/source/game/ui/service_menu.cpp index 225599a..527f3d1 100644 --- a/source/game/ui/service_menu.cpp +++ b/source/game/ui/service_menu.cpp @@ -1,5 +1,8 @@ #include "game/ui/service_menu.hpp" +#include +#include +#include #include #include "core/audio/audio.hpp" // Para Audio @@ -175,7 +178,7 @@ void ServiceMenu::selectOption() { return; } - if (auto* folder = dynamic_cast(selected_option)) { + if (const auto* folder = dynamic_cast(selected_option)) { previous_settings_group_ = current_settings_group_; current_settings_group_ = folder->getTargetGroup(); selected_ = 0; @@ -200,9 +203,8 @@ void ServiceMenu::updateDisplayOptions() { void ServiceMenu::updateOptionPairs() { option_pairs_.clear(); - for (const auto& option : display_options_) { - option_pairs_.emplace_back(option->getCaption(), option->getValueAsString()); - } + option_pairs_.reserve(display_options_.size()); + std::ranges::transform(display_options_, std::back_inserter(option_pairs_), [](const auto* option) { return std::pair{option->getCaption(), option->getValueAsString()}; }); } void ServiceMenu::updateMenu() { @@ -250,12 +252,9 @@ void ServiceMenu::applySettingsSettings() { } auto ServiceMenu::getOptionByCaption(const std::string& caption) const -> MenuOption* { - for (const auto& option : options_) { - if (option->getCaption() == caption) { - return option.get(); - } - } - return nullptr; + const auto it = std::ranges::find_if(options_, + [&caption](const auto& option) { return option->getCaption() == caption; }); + return it != options_.end() ? it->get() : nullptr; } // --- Getters y otros --- @@ -273,13 +272,8 @@ auto ServiceMenu::getCurrentGroupAlignment() const -> ServiceMenu::GroupAlignmen } auto ServiceMenu::countOptionsInGroup(SettingsGroup group) const -> size_t { - size_t count = 0; - for (const auto& option : options_) { - if (option->getGroup() == group && !option->isHidden()) { - count++; - } - } - return count; + return std::ranges::count_if(options_, + [group](const auto& option) { return option->getGroup() == group && !option->isHidden(); }); } // Inicializa todas las opciones del menú @@ -300,7 +294,7 @@ void ServiceMenu::initializeOptions() { [this]() -> void { // Acción: configurar botones del mando del jugador 1 auto* gamepad = &Options::gamepad_manager.getGamepad(Player::Id::PLAYER1); - if ((gamepad != nullptr) && gamepad->instance) { + if (gamepad->instance != nullptr) { define_buttons_->enable(gamepad); } })); @@ -318,7 +312,7 @@ void ServiceMenu::initializeOptions() { [this]() -> void { // Acción: configurar botones del mando del jugador 2 auto* gamepad = &Options::gamepad_manager.getGamepad(Player::Id::PLAYER2); - if ((gamepad != nullptr) && gamepad->instance) { + if (gamepad->instance != nullptr) { define_buttons_->enable(gamepad); } })); @@ -436,11 +430,10 @@ void ServiceMenu::initializeOptions() { } Screen::initShaders(); }; - auto preset_max_width = [](Text* text) -> int { - int max_w = 0; - for (const auto& p : Options::postfx_presets) { max_w = std::max(max_w, text->length(p.name, -2)); } - for (const auto& p : Options::crtpi_presets) { max_w = std::max(max_w, text->length(p.name, -2)); } - return max_w; + auto preset_max_width = [](const Text* text) -> int { + const auto presets_length = [text](int max_w, const auto& p) { return std::max(max_w, text->length(p.name, -2)); }; + int max_w = std::accumulate(Options::postfx_presets.begin(), Options::postfx_presets.end(), 0, presets_length); + return std::accumulate(Options::crtpi_presets.begin(), Options::crtpi_presets.end(), max_w, presets_length); }; options_.push_back(std::make_unique( diff --git a/source/game/ui/window_message.hpp b/source/game/ui/window_message.hpp index f37a558..fee6804 100644 --- a/source/game/ui/window_message.hpp +++ b/source/game/ui/window_message.hpp @@ -51,7 +51,7 @@ class WindowMessage { text_color{200, 200, 200, 255} {} // Constructor que convierte desde ParamServiceMenu::WindowMessage - Config(const ParamServiceMenu::WindowMessage& param_config) + explicit Config(const ParamServiceMenu::WindowMessage& param_config) : bg_color(param_config.bg_color), border_color(param_config.border_color), title_color(param_config.title_color), @@ -67,7 +67,7 @@ class WindowMessage { animation_duration(param_config.animation_duration) {} }; - WindowMessage( + explicit WindowMessage( std::shared_ptr text_renderer, std::string title = "", const Config& config = Config{}); @@ -148,8 +148,10 @@ class WindowMessage { // Animación de redimensionado struct ResizeAnimation { bool active = false; - float start_width, start_height; - float target_width, target_height; + float start_width = 0.0F; + float start_height = 0.0F; + float target_width = 0.0F; + float target_height = 0.0F; float elapsed = 0.0F; void start(float from_w, float from_h, float to_w, float to_h) { @@ -183,7 +185,8 @@ class WindowMessage { Type type = Type::NONE; bool active = false; - float target_width, target_height; // Tamaño final al mostrar + float target_width = 0.0F; + float target_height = 0.0F; float elapsed = 0.0F; void startShow(float to_w, float to_h) { diff --git a/source/utils/color.cpp b/source/utils/color.cpp index 1bcd88c..fee3bbb 100644 --- a/source/utils/color.cpp +++ b/source/utils/color.cpp @@ -1,6 +1,7 @@ #define _USE_MATH_DEFINES #include "utils/color.hpp" +#include // Para ranges::any_of #include // Para isxdigit #include // Para sinf, fmaxf, fminf, M_PI, fmodf, roundf, fmod #include // Para uint8_t @@ -22,10 +23,8 @@ auto Color::fromHex(const std::string& hex_str) -> Color { } // Verificar que todos los caracteres sean hexadecimales válidos - for (char c : hex) { - if (std::isxdigit(c) == 0) { - throw std::invalid_argument("String contiene caracteres no hexadecimales"); - } + if (std::ranges::any_of(hex, [](char c) { return std::isxdigit(c) == 0; })) { + throw std::invalid_argument("String contiene caracteres no hexadecimales"); } // Convertir cada par de caracteres a valores RGB(A) diff --git a/source/utils/param.cpp b/source/utils/param.cpp index 3fe9889..a41ab1a 100644 --- a/source/utils/param.cpp +++ b/source/utils/param.cpp @@ -189,8 +189,6 @@ namespace { {"service_menu.window_message.text_safety_margin", [](const std::string& v) -> void { param.service_menu.window_message.text_safety_margin = std::stof(v); }}, {"service_menu.window_message.animation_duration", [](const std::string& v) -> void { param.service_menu.window_message.animation_duration = std::stof(v); }}}; - static const std::unordered_map> INT_PARAMS_EXTRA = {}; - // Colores válidos para globos static const std::unordered_map VALID_BALLOON_COLORS = { {"blue", true}, diff --git a/source/utils/param.hpp b/source/utils/param.hpp index 43e23ed..c6fdac8 100644 --- a/source/utils/param.hpp +++ b/source/utils/param.hpp @@ -52,7 +52,7 @@ struct ParamBalloon { float vel; // Constructor por defecto - constexpr Settings(float grav_val = 0.0F, float vel_val = 0.0F) + explicit constexpr Settings(float grav_val = 0.0F, float vel_val = 0.0F) : grav(grav_val), vel(vel_val) {} };