From 1d3fd79a9e6faed28a1472318c3e1e7f1e46893d Mon Sep 17 00:00:00 2001 From: Sergio Date: Sat, 19 Jul 2025 22:25:46 +0200 Subject: [PATCH] jugant amb clang-tidy --- .clang-format | 3 +- .clang-format.bak | 12 + .clang-tidy | 48 ++-- .clang-tidy.bak | 68 ++++++ linux_utils/com_usar_clang-tidy.txt | 2 + source/audio.cpp | 10 +- source/audio.h | 10 +- source/input.cpp | 14 +- source/input.h | 130 +++++------ source/lang.h | 19 +- source/moving_sprite.cpp | 14 +- source/moving_sprite.h | 48 ++-- source/param.h | 2 +- source/resource.cpp | 2 +- source/resource.h | 51 +++-- source/scoreboard.cpp | 14 +- source/screen.cpp | 4 +- source/sections/credits.cpp | 2 +- source/sections/game.cpp | 2 +- source/sections/hiscore_table.cpp | 12 +- source/sections/intro.cpp | 6 +- source/sprite.cpp | 16 +- source/sprite.h | 36 +-- source/tabe.cpp | 106 ++++----- source/tabe.h | 101 +++++---- source/text.h | 12 +- source/texture.h | 27 +-- source/ui/menu_renderer.cpp | 4 +- source/utils.cpp | 338 ++++++++++++++++------------ source/utils.h | 272 ++++++++++++---------- 30 files changed, 779 insertions(+), 606 deletions(-) create mode 100644 .clang-format.bak create mode 100644 .clang-tidy.bak create mode 100644 linux_utils/com_usar_clang-tidy.txt diff --git a/.clang-format b/.clang-format index 3652702..72f58bf 100644 --- a/.clang-format +++ b/.clang-format @@ -1,5 +1,6 @@ BasedOnStyle: Google IndentWidth: 4 +IndentAccessModifiers: true ColumnLimit: 0 # Sin límite de longitud de línea BreakBeforeBraces: Attach # Llaves en la misma línea AllowShortIfStatementsOnASingleLine: true @@ -8,4 +9,4 @@ AllowShortFunctionsOnASingleLine: All AlignOperands: false AlignAfterOpenBracket: DontAlign BinPackArguments: false -BinPackParameters: false +BinPackParameters: false \ No newline at end of file diff --git a/.clang-format.bak b/.clang-format.bak new file mode 100644 index 0000000..6c97bba --- /dev/null +++ b/.clang-format.bak @@ -0,0 +1,12 @@ +BasedOnStyle: Google +IndentWidth: 4 +IndentAccessModifiers: true +ColumnLimit: 0 # Sin límite de longitud de línea +BreakBeforeBraces: Attach # Llaves en la misma línea +AllowShortIfStatementsOnASingleLine: true +AllowShortBlocksOnASingleLine: true +AllowShortFunctionsOnASingleLine: All +AlignOperands: false +AlignAfterOpenBracket: DontAlign +BinPackArguments: false +BinPackParameters: false diff --git a/.clang-tidy b/.clang-tidy index 1fc8f8e..fbf2f4a 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,12 +1,9 @@ Checks: > - readability-identifier-naming, - readability-*, - modernize-*, - clang-analyzer-* + readability-identifier-naming WarningsAsErrors: '*' - -HeaderFilterRegex: '.*' +# Excluir directorios third_party, external, vendor, etc. +HeaderFilterRegex: '^(?!.*(third_party|external|vendor|libs)).*' FormatStyle: file CheckOptions: @@ -16,25 +13,38 @@ CheckOptions: # Miembros privados en snake_case con sufijo _ - { key: readability-identifier-naming.PrivateMemberCase, value: lower_case } - { key: readability-identifier-naming.PrivateMemberSuffix, value: _ } - - { key: readability-identifier-naming.ClassMemberCase, value: lower_case } - - { key: readability-identifier-naming.ClassMemberSuffix, value: _ } + # Miembros protegidos en snake_case con sufijo _ + - { key: readability-identifier-naming.ProtectedMemberCase, value: lower_case } + - { key: readability-identifier-naming.ProtectedMemberSuffix, value: _ } + + # Miembros públicos en snake_case (sin sufijo) + - { key: readability-identifier-naming.PublicMemberCase, value: lower_case } # Namespaces en CamelCase - { key: readability-identifier-naming.NamespaceCase, value: CamelCase } - # Constantes y constexpr en UPPER_CASE + # Variables estáticas privadas como miembros privados + - { key: readability-identifier-naming.StaticVariableCase, value: lower_case } + - { key: readability-identifier-naming.StaticVariableSuffix, value: _ } + + # Constantes estáticas sin sufijo + - { key: readability-identifier-naming.StaticConstantCase, value: UPPER_CASE } + + # Constantes globales en UPPER_CASE - { key: readability-identifier-naming.GlobalConstantCase, value: UPPER_CASE } + + # Variables constexpr globales en UPPER_CASE - { key: readability-identifier-naming.ConstexprVariableCase, value: UPPER_CASE } + + # Constantes locales en UPPER_CASE - { key: readability-identifier-naming.LocalConstantCase, value: UPPER_CASE } - # Constantes estáticas dentro de clases con sufijo _ - - { key: readability-identifier-naming.ClassConstantCase, value: UPPER_CASE } - - { key: readability-identifier-naming.ClassConstantSuffix, value: _ } + # Constexpr miembros en UPPER_CASE (sin sufijo) + - { key: readability-identifier-naming.ConstexprMemberCase, value: UPPER_CASE } - # Constexpr variables con sufijo _ - - { key: readability-identifier-naming.ConstexprVariableCase, value: UPPER_CASE } - - { key: readability-identifier-naming.ConstexprVariableSuffix, value: _ } + # Constexpr miembros privados/protegidos con sufijo _ + - { key: readability-identifier-naming.ConstexprMethodCase, value: UPPER_CASE } # Clases, structs y enums en CamelCase - { key: readability-identifier-naming.ClassCase, value: CamelCase } @@ -44,8 +54,14 @@ CheckOptions: # Valores de enums en UPPER_CASE - { key: readability-identifier-naming.EnumConstantCase, value: UPPER_CASE } - # Métodos en camelBack + # Métodos en camelBack (sin sufijos) - { key: readability-identifier-naming.MethodCase, value: camelBack } + - { key: readability-identifier-naming.PrivateMethodCase, value: camelBack } + - { key: readability-identifier-naming.ProtectedMethodCase, value: camelBack } + - { key: readability-identifier-naming.PublicMethodCase, value: camelBack } # Funciones en camelBack - { key: readability-identifier-naming.FunctionCase, value: camelBack } + + # Parámetros en lower_case + - { key: readability-identifier-naming.ParameterCase, value: lower_case } \ No newline at end of file diff --git a/.clang-tidy.bak b/.clang-tidy.bak new file mode 100644 index 0000000..7011b46 --- /dev/null +++ b/.clang-tidy.bak @@ -0,0 +1,68 @@ +Checks: > + readability-identifier-naming, + readability-*, + modernize-*, + clang-analyzer-*, + -readability-identifier-length, + -readability-magic-numbers + +WarningsAsErrors: '*' + +HeaderFilterRegex: '.*' +FormatStyle: file + +CheckOptions: + # Variables locales en snake_case + - { key: readability-identifier-naming.VariableCase, value: lower_case } + + # Miembros privados en snake_case con sufijo _ + - { key: readability-identifier-naming.PrivateMemberCase, value: lower_case } + - { key: readability-identifier-naming.PrivateMemberSuffix, value: _ } + + # Miembros protegidos en snake_case con sufijo _ + - { key: readability-identifier-naming.ProtectedMemberCase, value: lower_case } + - { key: readability-identifier-naming.ProtectedMemberSuffix, value: _ } + + # Miembros públicos en snake_case (sin sufijo) + - { key: readability-identifier-naming.PublicMemberCase, value: lower_case } + + # Namespaces en CamelCase + - { key: readability-identifier-naming.NamespaceCase, value: CamelCase } + + # Constantes globales en UPPER_CASE + - { key: readability-identifier-naming.GlobalConstantCase, value: UPPER_CASE } + + # Variables constexpr globales en UPPER_CASE + - { key: readability-identifier-naming.ConstexprVariableCase, value: UPPER_CASE } + + # Constantes locales en UPPER_CASE + - { key: readability-identifier-naming.LocalConstantCase, value: UPPER_CASE } + + # Constantes estáticas dentro de clases en UPPER_CASE (sin sufijo) + - { key: readability-identifier-naming.StaticConstantCase, value: UPPER_CASE } + + # Constexpr miembros en UPPER_CASE (sin sufijo) + - { key: readability-identifier-naming.ConstexprMemberCase, value: UPPER_CASE } + + # Constexpr miembros privados/protegidos con sufijo _ + - { key: readability-identifier-naming.ConstexprMethodCase, value: UPPER_CASE } + + # Clases, structs y enums en CamelCase + - { key: readability-identifier-naming.ClassCase, value: CamelCase } + - { key: readability-identifier-naming.StructCase, value: CamelCase } + - { key: readability-identifier-naming.EnumCase, value: CamelCase } + + # Valores de enums en UPPER_CASE + - { key: readability-identifier-naming.EnumConstantCase, value: UPPER_CASE } + + # Métodos en camelBack (sin sufijos) + - { key: readability-identifier-naming.MethodCase, value: camelBack } + - { key: readability-identifier-naming.PrivateMethodCase, value: camelBack } + - { key: readability-identifier-naming.ProtectedMethodCase, value: camelBack } + - { key: readability-identifier-naming.PublicMethodCase, value: camelBack } + + # Funciones en camelBack + - { key: readability-identifier-naming.FunctionCase, value: camelBack } + + # Parámetros en lower_case + - { key: readability-identifier-naming.ParameterCase, value: lower_case } \ No newline at end of file diff --git a/linux_utils/com_usar_clang-tidy.txt b/linux_utils/com_usar_clang-tidy.txt new file mode 100644 index 0000000..eb53dd3 --- /dev/null +++ b/linux_utils/com_usar_clang-tidy.txt @@ -0,0 +1,2 @@ +Desde l'arrel del projecte executar: +clang-tidy source/fitxer.cpp -p build/ --fix \ No newline at end of file diff --git a/source/audio.cpp b/source/audio.cpp index 39a0032..e2869d0 100644 --- a/source/audio.cpp +++ b/source/audio.cpp @@ -77,7 +77,7 @@ void Audio::fadeOutMusic(int milliseconds) const { // Establece el volumen de los sonidos void Audio::setSoundVolume(int sound_volume, Group group) const { if (sound_enabled_) { - sound_volume = std::clamp(sound_volume, MIN_VOLUME_, MAX_VOLUME_); + sound_volume = std::clamp(sound_volume, MIN_VOLUME, MAX_VOLUME); const float CONVERTED_VOLUME = (sound_volume / 100.0F) * (Options::audio.volume / 100.0F); JA_SetSoundVolume(CONVERTED_VOLUME, static_cast(group)); } @@ -86,7 +86,7 @@ void Audio::setSoundVolume(int sound_volume, Group group) const { // Establece el volumen de la música void Audio::setMusicVolume(int music_volume) const { if (music_enabled_) { - music_volume = std::clamp(music_volume, MIN_VOLUME_, MAX_VOLUME_); + music_volume = std::clamp(music_volume, MIN_VOLUME, MAX_VOLUME); const float CONVERTED_VOLUME = (music_volume / 100.0F) * (Options::audio.volume / 100.0F); JA_SetMusicVolume(CONVERTED_VOLUME); } @@ -101,8 +101,8 @@ void Audio::applySettings() { void Audio::enable(bool value) { enabled_ = value; - setSoundVolume(enabled_ ? Options::audio.sound.volume : MIN_VOLUME_); - setMusicVolume(enabled_ ? Options::audio.music.volume : MIN_VOLUME_); + setSoundVolume(enabled_ ? Options::audio.sound.volume : MIN_VOLUME); + setMusicVolume(enabled_ ? Options::audio.music.volume : MIN_VOLUME); } // Inicializa SDL Audio @@ -112,7 +112,7 @@ void Audio::initSDLAudio() { } else { SDL_LogInfo(SDL_LOG_CATEGORY_TEST, "\n** SDL_AUDIO: INITIALIZING\n"); - JA_Init(FREQUENCY_, SDL_AUDIO_S16LE, 2); + JA_Init(FREQUENCY, SDL_AUDIO_S16LE, 2); enable(Options::audio.enabled); SDL_LogInfo(SDL_LOG_CATEGORY_TEST, "** SDL_AUDIO: INITIALIZATION COMPLETE\n"); diff --git a/source/audio.h b/source/audio.h index f4593f3..7ecf2b1 100644 --- a/source/audio.h +++ b/source/audio.h @@ -13,9 +13,9 @@ class Audio { }; // --- Constantes --- - static constexpr int MAX_VOLUME_ = 100; - static constexpr int MIN_VOLUME_ = 0; - static constexpr int FREQUENCY_ = 48000; + static constexpr int MAX_VOLUME = 100; + static constexpr int MIN_VOLUME = 0; + static constexpr int FREQUENCY = 48000; // --- Métodos de singleton --- static void init(); // Inicializa el objeto Audio @@ -71,8 +71,8 @@ class Audio { Music() : state(MusicState::STOPPED), loop(false) {} // Constructor para inicializar con valores específicos - Music(MusicState initState, std::string initName, bool initLoop) - : state(initState), name(std::move(initName)), loop(initLoop) {} + Music(MusicState init_state, std::string init_name, bool init_loop) + : state(init_state), name(std::move(init_name)), loop(init_loop) {} }; Music music_; diff --git a/source/input.cpp b/source/input.cpp index 18c1f5a..361b25b 100644 --- a/source/input.cpp +++ b/source/input.cpp @@ -241,7 +241,7 @@ void Input::printBindings(InputDevice device, int controller_index) const { // Muestra los botones asignados for (auto bi : button_inputs_) { - SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "%s : %d", to_string(bi).c_str(), controller_bindings_.at(controller_index).at(static_cast(bi)).button); + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "%s : %d", inputToString(bi).c_str(), controller_bindings_.at(controller_index).at(static_cast(bi)).button); } } } @@ -258,7 +258,7 @@ int Input::getIndexByName(const std::string &name) const { } // Convierte un InputAction a std::string -std::string Input::to_string(InputAction input) const { +std::string Input::inputToString(InputAction input) const { switch (input) { case InputAction::FIRE_LEFT: return "input_fire_left"; @@ -276,7 +276,7 @@ std::string Input::to_string(InputAction input) const { } // Convierte un std::string a InputAction -InputAction Input::to_inputs_e(const std::string &name) const { +InputAction Input::stringToInput(const std::string &name) const { static const std::unordered_map inputMap = { {"input_fire_left", InputAction::FIRE_LEFT}, {"input_fire_center", InputAction::FIRE_CENTER}, @@ -295,16 +295,16 @@ bool Input::checkAxisInput(InputAction input, int controller_index, bool repeat) switch (input) { case InputAction::LEFT: - axis_active_now = SDL_GetGamepadAxis(connected_controllers_[controller_index], SDL_GAMEPAD_AXIS_LEFTX) < -AXIS_THRESHOLD_; + axis_active_now = SDL_GetGamepadAxis(connected_controllers_[controller_index], SDL_GAMEPAD_AXIS_LEFTX) < -AXIS_THRESHOLD; break; case InputAction::RIGHT: - axis_active_now = SDL_GetGamepadAxis(connected_controllers_[controller_index], SDL_GAMEPAD_AXIS_LEFTX) > AXIS_THRESHOLD_; + axis_active_now = SDL_GetGamepadAxis(connected_controllers_[controller_index], SDL_GAMEPAD_AXIS_LEFTX) > AXIS_THRESHOLD; break; case InputAction::UP: - axis_active_now = SDL_GetGamepadAxis(connected_controllers_[controller_index], SDL_GAMEPAD_AXIS_LEFTY) < -AXIS_THRESHOLD_; + axis_active_now = SDL_GetGamepadAxis(connected_controllers_[controller_index], SDL_GAMEPAD_AXIS_LEFTY) < -AXIS_THRESHOLD; break; case InputAction::DOWN: - axis_active_now = SDL_GetGamepadAxis(connected_controllers_[controller_index], SDL_GAMEPAD_AXIS_LEFTY) > AXIS_THRESHOLD_; + axis_active_now = SDL_GetGamepadAxis(connected_controllers_[controller_index], SDL_GAMEPAD_AXIS_LEFTY) > AXIS_THRESHOLD; break; default: return false; diff --git a/source/input.h b/source/input.h index 9c3fd69..8ee2a60 100644 --- a/source/input.h +++ b/source/input.h @@ -68,83 +68,83 @@ enum class InputDevice : int { // Clase Input: gestiona la entrada de teclado y mandos (singleton) class Input { - public: - // --- Métodos de singleton --- - static void init(const std::string &game_controller_db_path); // Inicializa el singleton - static void destroy(); // Libera el singleton - static Input *get(); // Obtiene la instancia + public: + // --- Métodos de singleton --- + static void init(const std::string &game_controller_db_path); // Inicializa el singleton + static void destroy(); // Libera el singleton + static Input *get(); // Obtiene la instancia - // --- Métodos de configuración de controles --- - void bindKey(InputAction input, SDL_Scancode code); // Asigna inputs a teclas - void bindGameControllerButton(int controller_index, InputAction input, SDL_GamepadButton button); // Asigna inputs a botones del mando - void bindGameControllerButton(int controller_index, InputAction inputTarget, InputAction inputSource); // Asigna inputs a otros inputs del mando + // --- Métodos de configuración de controles --- + void bindKey(InputAction input, SDL_Scancode code); // Asigna inputs a teclas + void bindGameControllerButton(int controller_index, InputAction input, SDL_GamepadButton button); // Asigna inputs a botones del mando + void bindGameControllerButton(int controller_index, InputAction input_target, InputAction input_source); // Asigna inputs a otros inputs del mando - // --- Métodos de consulta de entrada --- - void update(); // Comprueba fisicamente los botones y teclas que se han pulsado - bool checkInput(InputAction input, bool repeat = true, InputDevice device = InputDevice::ANY, int controller_index = 0); // Comprueba si un input está activo - bool checkAnyInput(InputDevice device = InputDevice::ANY, int controller_index = 0); // Comprueba si hay al menos un input activo - int checkAnyButton(bool repeat = INPUT_DO_NOT_ALLOW_REPEAT); // Comprueba si hay algún botón pulsado + // --- Métodos de consulta de entrada --- + void update(); // Comprueba fisicamente los botones y teclas que se han pulsado + bool checkInput(InputAction input, bool repeat = true, InputDevice device = InputDevice::ANY, int controller_index = 0); // Comprueba si un input está activo + bool checkAnyInput(InputDevice device = InputDevice::ANY, int controller_index = 0); // Comprueba si hay al menos un input activo + int checkAnyButton(bool repeat = INPUT_DO_NOT_ALLOW_REPEAT); // Comprueba si hay algún botón pulsado - // --- Métodos de gestión de mandos --- - bool discoverGameControllers(); // Busca si hay mandos conectados - bool gameControllerFound(); // Comprueba si hay algún mando conectado - int getNumControllers() const; // Obtiene el número de mandos conectados - std::string getControllerName(int controller_index) const; // Obtiene el nombre de un mando de juego - int getJoyIndex(SDL_JoystickID id) const; // Obtiene el índice del controlador a partir de un event.id + // --- Métodos de gestión de mandos --- + bool discoverGameControllers(); // Busca si hay mandos conectados + bool gameControllerFound(); // Comprueba si hay algún mando conectado + int getNumControllers() const; // Obtiene el número de mandos conectados + std::string getControllerName(int controller_index) const; // Obtiene el nombre de un mando de juego + int getJoyIndex(SDL_JoystickID id) const; // Obtiene el índice del controlador a partir de un event.id - // --- Métodos de consulta y utilidades --- - void printBindings(InputDevice device = InputDevice::KEYBOARD, int controller_index = 0) const; // Muestra por consola los controles asignados - SDL_GamepadButton getControllerBinding(int controller_index, InputAction input) const; // Obtiene el SDL_GamepadButton asignado a un input - std::string to_string(InputAction input) const; // Convierte un InputAction a std::string - InputAction to_inputs_e(const std::string &name) const; // Convierte un std::string a InputAction - int getIndexByName(const std::string &name) const; // Obtiene el índice a partir del nombre del mando + // --- Métodos de consulta y utilidades --- + void printBindings(InputDevice device = InputDevice::KEYBOARD, int controller_index = 0) const; // Muestra por consola los controles asignados + SDL_GamepadButton getControllerBinding(int controller_index, InputAction input) const; // Obtiene el SDL_GamepadButton asignado a un input + std::string inputToString(InputAction input) const; // Convierte un InputAction a std::string + InputAction stringToInput(const std::string &name) const; // Convierte un std::string a InputAction + int getIndexByName(const std::string &name) const; // Obtiene el índice a partir del nombre del mando - // --- Métodos de reseteo de estado de entrada --- - void resetInputStates(); // Pone todos los KeyBindings.active y ControllerBindings.active a false + // --- Métodos de reseteo de estado de entrada --- + void resetInputStates(); // Pone todos los KeyBindings.active y ControllerBindings.active a false - private: - // --- Singleton --- - static Input *instance_; + private: + // --- Estructuras internas --- + struct KeyBindings { + Uint8 scancode; // Scancode asociado + bool is_held; // Está pulsada ahora mismo + bool just_pressed; // Se acaba de pulsar en este fotograma - // --- Estructuras internas --- - struct KeyBindings { - Uint8 scancode; // Scancode asociado - bool is_held; // Está pulsada ahora mismo - bool just_pressed; // Se acaba de pulsar en este fotograma + KeyBindings(Uint8 scancode = 0, bool is_held = false, bool just_pressed = false) + : scancode(scancode), is_held(is_held), just_pressed(just_pressed) {} + }; - KeyBindings(Uint8 scancode = 0, bool is_held = false, bool just_pressed = false) - : scancode(scancode), is_held(is_held), just_pressed(just_pressed) {} - }; + struct ControllerBindings { + SDL_GamepadButton button; // GameControllerButton asociado + bool is_held; // Está pulsada ahora mismo + bool just_pressed; // Se acaba de pulsar en este fotograma + bool axis_active; // Estado del eje - struct ControllerBindings { - SDL_GamepadButton button; // GameControllerButton asociado - bool is_held; // Está pulsada ahora mismo - bool just_pressed; // Se acaba de pulsar en este fotograma - bool axis_active; // Estado del eje + ControllerBindings(SDL_GamepadButton btn = 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), axis_active(axis_act) {} + }; - ControllerBindings(SDL_GamepadButton btn = 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), axis_active(axis_act) {} - }; + // --- Constantes --- + static constexpr Sint16 AXIS_THRESHOLD = 30000; - // --- Constantes --- - static constexpr Sint16 AXIS_THRESHOLD_ = 30000; + // --- Variables internas --- + std::vector connected_controllers_; // Vector con todos los mandos conectados + std::vector joysticks_; // Vector con todos los joysticks conectados + std::vector key_bindings_; // Vector con las teclas asociadas a los inputs predefinidos + std::vector> controller_bindings_; // Vector con los botones asociados a los inputs predefinidos para cada mando + std::vector controller_names_; // Vector con los nombres de los mandos + std::vector button_inputs_; // Inputs asignados al jugador y a botones, excluyendo direcciones + int num_joysticks_ = 0; // Número de joysticks conectados + int num_gamepads_ = 0; // Número de mandos conectados + std::string game_controller_db_path_; // Ruta al archivo gamecontrollerdb.txt - // --- Variables internas --- - std::vector connected_controllers_; // Vector con todos los mandos conectados - std::vector joysticks_; // Vector con todos los joysticks conectados - std::vector key_bindings_; // Vector con las teclas asociadas a los inputs predefinidos - std::vector> controller_bindings_; // Vector con los botones asociados a los inputs predefinidos para cada mando - std::vector controller_names_; // Vector con los nombres de los mandos - std::vector button_inputs_; // Inputs asignados al jugador y a botones, excluyendo direcciones - int num_joysticks_ = 0; // Número de joysticks conectados - int num_gamepads_ = 0; // Número de mandos conectados - std::string game_controller_db_path_; // Ruta al archivo gamecontrollerdb.txt + // --- Métodos internos --- + void initSDLGamePad(); // Inicializa SDL para la gestión de mandos + bool checkAxisInput(InputAction input, int controller_index, bool repeat); // Comprueba el eje del mando - // --- Métodos internos --- - void initSDLGamePad(); // Inicializa SDL para la gestión de mandos - bool checkAxisInput(InputAction input, int controller_index, bool repeat); // Comprueba el eje del mando + // --- Constructor y destructor --- + explicit Input(const std::string &game_controller_db_path); // Constructor privado + ~Input() = default; // Destructor privado - // --- Constructor y destructor --- - explicit Input(const std::string &game_controller_db_path); // Constructor privado - ~Input() = default; // Destructor privado + // --- Singleton --- + static Input *instance_; }; \ No newline at end of file diff --git a/source/lang.h b/source/lang.h index 0387434..9f94b19 100644 --- a/source/lang.h +++ b/source/lang.h @@ -1,6 +1,7 @@ #pragma once #include // Para string, basic_string +#include namespace Lang { // --- Códigos de idioma soportados --- @@ -16,33 +17,33 @@ struct Language { std::string name; // Nombre que identifica el idioma std::string file_name; // Nombre del fichero con los textos - Language(Code c, const std::string &n, const std::string &fn) - : code(c), name(n), file_name(fn) {} + Language(Code c, std::string n, std::string fn) + : code(c), name(std::move(n)), file_name(std::move(fn)) {} }; // Carga los textos desde el fichero JSON especificado -bool loadFromFile(const std::string &file_path); +auto loadFromFile(const std::string &file_path) -> bool; // Obtiene el texto por clave -std::string getText(const std::string &key); +auto getText(const std::string &key) -> std::string; // Obtiene el código del siguiente idioma (circular) -Code getNextLangCode(Code current_lang); +auto getNextLangCode(Code current_lang) -> Code; // Obtiene el idioma correspondiente al código proporcionado -Language getLanguage(Code code); +auto getLanguage(Code code) -> Language; // Devuelve el código de un idioma a partir de un nombre -Code getCodeFromName(const std::string &name); +auto getCodeFromName(const std::string &name) -> Code; // Devuelve el nombre de un idioma a partir de un código -std::string getNameFromCode(Code code); +auto getNameFromCode(Code code) -> std::string; // Actualiza los nombres de los idiomas void updateLanguageNames(); // Obtiene el nombre del fichero de textos asociado a un código de idioma -std::string getLanguageFileName(Code code); +auto getLanguageFileName(Code code) -> std::string; // Establece el idioma actual void setLanguage(Code lang); diff --git a/source/moving_sprite.cpp b/source/moving_sprite.cpp index 7032313..430fb20 100644 --- a/source/moving_sprite.cpp +++ b/source/moving_sprite.cpp @@ -98,22 +98,22 @@ void MovingSprite::setPos(SDL_FRect rect) { } // Establece el valor de las variables -void MovingSprite::setPos(float x, float y) { - x_ = x; - y_ = y; +void MovingSprite::setPos(float pos_x, float pos_y) { + x_ = pos_x; + y_ = pos_y; pos_.x = static_cast(x_); pos_.y = static_cast(y_); } // Establece el valor de la variable -void MovingSprite::setPosX(float value) { - x_ = value; +void MovingSprite::setPosX(float pos_x) { + x_ = pos_x; pos_.x = static_cast(x_); } // Establece el valor de la variable -void MovingSprite::setPosY(float value) { - y_ = value; +void MovingSprite::setPosY(float pos_y) { + y_ = pos_y; pos_.y = static_cast(y_); } \ No newline at end of file diff --git a/source/moving_sprite.h b/source/moving_sprite.h index 2381852..f3223d1 100644 --- a/source/moving_sprite.h +++ b/source/moving_sprite.h @@ -14,21 +14,21 @@ class MovingSprite : public Sprite { public: // --- Estructura para la rotación --- struct Rotate { - bool enabled; // Indica si ha de rotar - int counter; // Contador - int speed; // Velocidad de giro - double angle; // Ángulo para dibujarlo - float amount; // Cantidad de grados a girar en cada iteración + bool enabled{false}; // Indica si ha de rotar + int counter{0}; // Contador + int speed{1}; // Velocidad de giro + double angle{0.0}; // Ángulo para dibujarlo + float amount{0.0F}; // Cantidad de grados a girar en cada iteración SDL_FPoint center; // Centro de rotación - Rotate() : enabled(false), counter(0), speed(1), angle(0.0), amount(0.0f), center({0.0f, 0.0f}) {} + Rotate() : center({0.0F, 0.0F}) {} }; // --- Constructores y destructor --- MovingSprite(std::shared_ptr texture, SDL_FRect pos, MovingSprite::Rotate rotate, float zoom_w, float zoom_h, SDL_FlipMode flip); MovingSprite(std::shared_ptr texture, SDL_FRect pos); explicit MovingSprite(std::shared_ptr texture); - virtual ~MovingSprite() override = default; + ~MovingSprite() override = default; // --- Métodos principales --- virtual void update(); // Actualiza las variables internas del objeto @@ -36,12 +36,12 @@ class MovingSprite : public Sprite { void render() override; // Muestra el sprite por pantalla // --- Getters de posición y movimiento --- - float getPosX() const { return x_; } - float getPosY() const { return y_; } - float getVelX() const { return vx_; } - float getVelY() const { return vy_; } - float getAccelX() const { return ax_; } - float getAccelY() const { return ay_; } + [[nodiscard]] auto getPosX() const -> float { return x_; } + [[nodiscard]] auto getPosY() const -> float { return y_; } + [[nodiscard]] auto getVelX() const -> float { return vx_; } + [[nodiscard]] auto getVelY() const -> float { return vy_; } + [[nodiscard]] auto getAccelX() const -> float { return ax_; } + [[nodiscard]] auto getAccelY() const -> float { return ay_; } // --- Setters de movimiento --- void setVelX(float value) { vx_ = value; } @@ -50,7 +50,7 @@ class MovingSprite : public Sprite { void setAccelY(float value) { ay_ = value; } // --- Rotación --- - bool isRotating() const { return rotate_.enabled; } + [[nodiscard]] auto isRotating() const -> bool { return rotate_.enabled; } void setZoomW(float value) { zoom_w_ = value; } void setZoomH(float value) { zoom_h_ = value; } void setAngle(double value) { rotate_.angle = value; } @@ -63,24 +63,24 @@ class MovingSprite : public Sprite { // --- Flip --- void setFlip(SDL_FlipMode flip) { flip_ = flip; } void flip() { flip_ = (flip_ == SDL_FLIP_HORIZONTAL) ? SDL_FLIP_NONE : SDL_FLIP_HORIZONTAL; } - SDL_FlipMode getFlip() { return flip_; } + auto getFlip() -> SDL_FlipMode { return flip_; } // --- Posición y tamaño --- void setPos(SDL_FRect rect); // Establece la posición y el tamaño del objeto - void setPos(float x, float y); // Establece la posición del objeto - void setPosX(float value); // Establece la posición X - void setPosY(float value); // Establece la posición Y + void setPos(float pos_x, float pos_y); // Establece la posición del objeto + void setPosX(float pos_x); // Establece la posición X + void setPosY(float pos_y); // Establece la posición Y protected: // --- Variables de posición y movimiento --- - float x_ = 0.0f; // Posición en el eje X - float y_ = 0.0f; // Posición en el eje Y + float x_ = 0.0F; // Posición en el eje X + float y_ = 0.0F; // Posición en el eje Y - float vx_ = 0.0f; // Velocidad en el eje X. Cantidad de píxeles a desplazarse - float vy_ = 0.0f; // Velocidad en el eje Y. Cantidad de píxeles a desplazarse + float vx_ = 0.0F; // Velocidad en el eje X. Cantidad de píxeles a desplazarse + float vy_ = 0.0F; // Velocidad en el eje Y. Cantidad de píxeles a desplazarse - float ax_ = 0.0f; // Aceleración en el eje X. Variación de la velocidad - float ay_ = 0.0f; // Aceleración en el eje Y. Variación de la velocidad + float ax_ = 0.0F; // Aceleración en el eje X. Variación de la velocidad + float ay_ = 0.0F; // Aceleración en el eje Y. Variación de la velocidad // --- Efectos visuales --- Rotate rotate_; // Variables usadas para controlar la rotación del sprite diff --git a/source/param.h b/source/param.h index 8c40a44..5b32635 100644 --- a/source/param.h +++ b/source/param.h @@ -53,7 +53,7 @@ struct ParamBalloon { float vel; // Velocidad inicial al rebotar contra el suelo // Constructor - explicit Settings(float grav_val = 0.0f, float vel_val = 0.0f) + explicit Settings(float grav_val = 0.0F, float vel_val = 0.0F) : grav(grav_val), vel(vel_val) {} }; diff --git a/source/resource.cpp b/source/resource.cpp index ca5a679..0c74270 100644 --- a/source/resource.cpp +++ b/source/resource.cpp @@ -387,7 +387,7 @@ void Resource::renderProgress() { screen->start(); screen->clean(); - auto color = param.resource.color.darken(); + auto color = param.resource.color.DARKEN(); // Dibuja el interior de la barra de progreso SDL_SetRenderDrawColor(renderer, param.resource.color.r, param.resource.color.g, param.resource.color.b, param.resource.color.a); diff --git a/source/resource.h b/source/resource.h index c60df7b..9cc741a 100644 --- a/source/resource.h +++ b/source/resource.h @@ -5,6 +5,7 @@ #include // Para shared_ptr #include // Para basic_string, string +#include #include // Para vector #include "animated_sprite.h" // Para AnimationsFileBuffer @@ -21,16 +22,16 @@ class Resource { // --- Métodos de singleton --- static void init(); // Inicializa el objeto Resource static void destroy(); // Libera el objeto Resource - static Resource *get(); // Obtiene el puntero al objeto Resource + static auto get() -> Resource *; // Obtiene el puntero al objeto Resource // --- Métodos de acceso a recursos --- - JA_Sound_t *getSound(const std::string &name); // Obtiene el sonido por nombre - JA_Music_t *getMusic(const std::string &name); // Obtiene la música por nombre - std::shared_ptr getTexture(const std::string &name); // Obtiene la textura por nombre - std::shared_ptr getTextFile(const std::string &name); // Obtiene el fichero de texto por nombre - std::shared_ptr getText(const std::string &name); // Obtiene el objeto de texto por nombre - AnimationsFileBuffer &getAnimation(const std::string &name); // Obtiene la animación por nombre - DemoData &getDemoData(int index); // Obtiene los datos de demo por índice + auto getSound(const std::string &name) -> JA_Sound_t *; // Obtiene el sonido por nombre + auto getMusic(const std::string &name) -> JA_Music_t *; // Obtiene la música por nombre + auto getTexture(const std::string &name) -> std::shared_ptr; // Obtiene la textura por nombre + auto getTextFile(const std::string &name) -> std::shared_ptr; // Obtiene el fichero de texto por nombre + auto getText(const std::string &name) -> std::shared_ptr; // Obtiene el objeto de texto por nombre + auto getAnimation(const std::string &name) -> AnimationsFileBuffer &; // Obtiene la animación por nombre + auto getDemoData(int index) -> DemoData &; // Obtiene los datos de demo por índice // --- Métodos de recarga de recursos --- void reload(); // Recarga todos los recursos @@ -42,48 +43,48 @@ class Resource { std::string name; // Nombre del sonido JA_Sound_t *sound; // Objeto con el sonido - ResourceSound(const std::string &name, JA_Sound_t *sound) - : name(name), sound(sound) {} + ResourceSound(std::string name, JA_Sound_t *sound) + : name(std::move(name)), sound(sound) {} }; struct ResourceMusic { std::string name; // Nombre de la música JA_Music_t *music; // Objeto con la música - ResourceMusic(const std::string &name, JA_Music_t *music) - : name(name), music(music) {} + ResourceMusic(std::string name, JA_Music_t *music) + : name(std::move(name)), music(music) {} }; struct ResourceTexture { std::string name; // Nombre de la textura std::shared_ptr texture; // Objeto con la textura - ResourceTexture(const std::string &name, std::shared_ptr texture) - : name(name), texture(texture) {} + ResourceTexture(std::string name, std::shared_ptr texture) + : name(std::move(name)), texture(std::move(texture)) {} }; struct ResourceTextFile { std::string name; // Nombre del fichero std::shared_ptr text_file; // Objeto con los descriptores de la fuente de texto - ResourceTextFile(const std::string &name, std::shared_ptr text_file) - : name(name), text_file(text_file) {} + ResourceTextFile(std::string name, std::shared_ptr text_file) + : name(std::move(name)), text_file(std::move(text_file)) {} }; struct ResourceText { std::string name; // Nombre del objeto std::shared_ptr text; // Objeto de texto - ResourceText(const std::string &name, std::shared_ptr text) - : name(name), text(text) {} + ResourceText(std::string name, std::shared_ptr text) + : name(std::move(name)), text(std::move(text)) {} }; struct ResourceAnimation { std::string name; // Nombre de la animación AnimationsFileBuffer animation; // Objeto con las animaciones - ResourceAnimation(const std::string &name, const AnimationsFileBuffer &animation) - : name(name), animation(animation) {} + ResourceAnimation(std::string name, AnimationsFileBuffer animation) + : name(std::move(name)), animation(std::move(animation)) {} }; // --- Estructura para el progreso de carga --- @@ -96,14 +97,11 @@ class Resource { void add(size_t amount) { loaded += amount; } void increase() { loaded++; } - float getPercentage() const { - return total > 0 ? static_cast(loaded) / static_cast(total) : 0.0f; + [[nodiscard]] auto getPercentage() const -> float { + return total > 0 ? static_cast(loaded) / static_cast(total) : 0.0F; } }; - // --- Instancia singleton --- - static Resource *instance_; // Instancia única de Resource - // --- Vectores de recursos --- std::vector sounds_; // Vector con los sonidos std::vector musics_; // Vector con las músicas @@ -146,4 +144,7 @@ class Resource { // --- Constructores y destructor privados (singleton) --- Resource(); // Constructor privado ~Resource(); // Destructor privado + + // --- Instancia singleton --- + static Resource *instance_; // Instancia única de Resource }; \ No newline at end of file diff --git a/source/scoreboard.cpp b/source/scoreboard.cpp index 4a740c4..693a6b7 100644 --- a/source/scoreboard.cpp +++ b/source/scoreboard.cpp @@ -120,8 +120,8 @@ void Scoreboard::render() { void Scoreboard::setColor(Color color) { // Actualiza las variables de colores color_ = color; - text_color1_ = param.scoreboard.text_autocolor ? color_.lighten(100) : param.scoreboard.text_color1; - text_color2_ = param.scoreboard.text_autocolor ? color_.lighten(150) : param.scoreboard.text_color2; + text_color1_ = param.scoreboard.text_autocolor ? color_.LIGHTEN(100) : param.scoreboard.text_color1; + text_color2_ = param.scoreboard.text_autocolor ? color_.LIGHTEN(150) : param.scoreboard.text_color2; // Aplica los colores power_meter_sprite_->getTexture()->setColor(text_color2_); @@ -395,18 +395,18 @@ void Scoreboard::createPanelTextures() { // Dibuja la linea que separa la zona de juego del marcador void Scoreboard::renderSeparator() { // Dibuja la linea que separa el marcador de la zona de juego - auto color = param.scoreboard.separator_autocolor ? color_.darken() : param.scoreboard.separator_color; + auto color = param.scoreboard.separator_autocolor ? color_.DARKEN() : param.scoreboard.separator_color; SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, 255); SDL_RenderLine(renderer_, 0, 0, rect_.w, 0); } // Inicializa el vector de colores para el nombre void Scoreboard::iniNameColors() { - Color color = color_.inverse(); + Color color = color_.INVERSE(); name_colors_.clear(); - name_colors_.emplace_back(color.lighten(50)); - name_colors_.emplace_back(color.lighten(25)); + name_colors_.emplace_back(color.LIGHTEN(50)); + name_colors_.emplace_back(color.LIGHTEN(25)); name_colors_.emplace_back(color); - name_colors_.emplace_back(color.darken(25)); + name_colors_.emplace_back(color.DARKEN(25)); } \ No newline at end of file diff --git a/source/screen.cpp b/source/screen.cpp index 43ba035..b8e94a9 100644 --- a/source/screen.cpp +++ b/source/screen.cpp @@ -211,11 +211,11 @@ void Screen::renderShake() { void Screen::renderInfo() { if (debug_info_.show) { // Resolution - debug_info_.text->writeDX(TEXT_COLOR | TEXT_STROKE, param.game.width - debug_info_.text->lenght(Options::video.info) - 2, 1, Options::video.info, 1, param.debug.color, 1, param.debug.color.darken(150)); + debug_info_.text->writeDX(TEXT_COLOR | TEXT_STROKE, param.game.width - debug_info_.text->lenght(Options::video.info) - 2, 1, Options::video.info, 1, param.debug.color, 1, param.debug.color.DARKEN(150)); // FPS const std::string FPS_TEXT = std::to_string(fps_.lastValue) + " FPS"; - debug_info_.text->writeDX(TEXT_COLOR | TEXT_STROKE, param.game.width - debug_info_.text->lenght(FPS_TEXT) - 2, 1 + debug_info_.text->getCharacterSize(), FPS_TEXT, 1, param.debug.color, 1, param.debug.color.darken(150)); + debug_info_.text->writeDX(TEXT_COLOR | TEXT_STROKE, param.game.width - debug_info_.text->lenght(FPS_TEXT) - 2, 1 + debug_info_.text->getCharacterSize(), FPS_TEXT, 1, param.debug.color, 1, param.debug.color.DARKEN(150)); } } #endif diff --git a/source/sections/credits.cpp b/source/sections/credits.cpp index ce75ec9..3d3ad69 100644 --- a/source/sections/credits.cpp +++ b/source/sections/credits.cpp @@ -257,7 +257,7 @@ void Credits::fillCanvas() { // Dibuja el rectangulo rojo // SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 0xFF, 0, 0, 0xFF); - const Color color = color_.lighten(); + const Color color = color_.LIGHTEN(); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), color.r, color.g, color.b, 0xFF); SDL_RenderRect(Screen::get()->getRenderer(), &red_rect); diff --git a/source/sections/game.cpp b/source/sections/game.cpp index 5c3e179..780fe21 100644 --- a/source/sections/game.cpp +++ b/source/sections/game.cpp @@ -260,7 +260,7 @@ void Game::updateStage() { // Modifica el color de fondo al llegar a la Fase 10 if (Stage::number == 9) { - background_->setColor(Color(0xdd, 0x19, 0x1d).darken()); + background_->setColor(Color(0xdd, 0x19, 0x1d).DARKEN()); background_->setAlpha(96); } } diff --git a/source/sections/hiscore_table.cpp b/source/sections/hiscore_table.cpp index 4fd7c1b..98bf818 100644 --- a/source/sections/hiscore_table.cpp +++ b/source/sections/hiscore_table.cpp @@ -206,7 +206,7 @@ void HiScoreTable::createSprites() { const int first_line = (param.game.height - size) / 2; // Crea el sprite para el texto de cabecera - header_ = std::make_unique(header_text->writeDXToTexture(TEXT_COLOR, Lang::getText("[HIGHSCORE_TABLE] CAPTION"), -2, background_fade_color_.inverse().lighten(25))); + header_ = std::make_unique(header_text->writeDXToTexture(TEXT_COLOR, Lang::getText("[HIGHSCORE_TABLE] CAPTION"), -2, background_fade_color_.INVERSE().LIGHTEN(25))); header_->setPosition(param.game.game_area.center_x - (header_->getWidth() / 2), first_line); // Crea los sprites para las entradas en la tabla de puntuaciones @@ -358,10 +358,10 @@ Color HiScoreTable::getEntryColor(int counter_) { // Inicializa los colores de las entradas void HiScoreTable::iniEntryColors() { entry_colors_.clear(); - entry_colors_.emplace_back(background_fade_color_.inverse().lighten(75)); - entry_colors_.emplace_back(background_fade_color_.inverse().lighten(50)); - entry_colors_.emplace_back(background_fade_color_.inverse().lighten(25)); - entry_colors_.emplace_back(background_fade_color_.inverse()); + entry_colors_.emplace_back(background_fade_color_.INVERSE().LIGHTEN(75)); + entry_colors_.emplace_back(background_fade_color_.INVERSE().LIGHTEN(50)); + entry_colors_.emplace_back(background_fade_color_.INVERSE().LIGHTEN(25)); + entry_colors_.emplace_back(background_fade_color_.INVERSE()); } // Hace brillar los nombres de la tabla de records @@ -379,7 +379,7 @@ void HiScoreTable::updateCounter() { ++counter_; if (counter_ == 150) { - background_->setColor(background_fade_color_.darken()); + background_->setColor(background_fade_color_.DARKEN()); background_->setAlpha(96); } diff --git a/source/sections/intro.cpp b/source/sections/intro.cpp index 85c1a79..0ff7bf1 100644 --- a/source/sections/intro.cpp +++ b/source/sections/intro.cpp @@ -542,15 +542,15 @@ void Intro::updatePostState() { if (ELAPSED_TIME >= 1000) { tiled_bg_->stopGracefully(); - if (!bg_color_.isEqualTo(param.title.bg_color)) { - bg_color_ = bg_color_.approachTo(param.title.bg_color, 1); + if (!bg_color_.IS_EQUAL_TO(param.title.bg_color)) { + bg_color_ = bg_color_.APPROACH_TO(param.title.bg_color, 1); } tiled_bg_->setColor(bg_color_); } // Cambia de estado si el fondo se ha detenido y recuperado el color - if (tiled_bg_->isStopped() && bg_color_.isEqualTo(param.title.bg_color)) { + if (tiled_bg_->isStopped() && bg_color_.IS_EQUAL_TO(param.title.bg_color)) { post_state_ = IntroPostState::END; state_start_time_ = SDL_GetTicks(); } diff --git a/source/sprite.cpp b/source/sprite.cpp index ab6d0e8..290f539 100644 --- a/source/sprite.cpp +++ b/source/sprite.cpp @@ -3,9 +3,9 @@ #include "texture.h" // Para Texture // Constructor -Sprite::Sprite(std::shared_ptr texture, float x, float y, float w, float h) +Sprite::Sprite(std::shared_ptr texture, float pos_x, float pos_y, float width, float height) : texture_(texture), - pos_((SDL_FRect){x, y, w, h}), + pos_((SDL_FRect){pos_x, pos_y, width, height}), sprite_clip_((SDL_FRect){0, 0, pos_.w, pos_.h}) {} Sprite::Sprite(std::shared_ptr texture, SDL_FRect rect) @@ -24,15 +24,15 @@ void Sprite::render() { } // Establece la posición del objeto -void Sprite::setPosition(float x, float y) { - pos_.x = x; - pos_.y = y; +void Sprite::setPosition(float pos_x, float pos_y) { + pos_.x = pos_x; + pos_.y = pos_y; } // Establece la posición del objeto -void Sprite::setPosition(SDL_FPoint p) { - pos_.x = p.x; - pos_.y = p.y; +void Sprite::setPosition(SDL_FPoint point) { + pos_.x = point.x; + pos_.y = point.y; } // Reinicia las variables a cero diff --git a/source/sprite.h b/source/sprite.h index 933c00d..a83517a 100644 --- a/source/sprite.h +++ b/source/sprite.h @@ -10,7 +10,7 @@ class Texture; class Sprite { public: // --- Constructores y destructor --- - Sprite(std::shared_ptr texture, float x, float y, float w, float h); + Sprite(std::shared_ptr texture, float pos_x, float pos_y, float width, float height); Sprite(std::shared_ptr texture, SDL_FRect rect); explicit Sprite(std::shared_ptr texture); virtual ~Sprite() = default; @@ -20,21 +20,21 @@ class Sprite { virtual void clear(); // Reinicia las variables a cero // --- Getters de posición y tamaño --- - float getX() const { return pos_.x; } - float getY() const { return pos_.y; } - float getWidth() const { return pos_.w; } - float getHeight() const { return pos_.h; } - SDL_FRect getPosition() const { return pos_; } - SDL_FRect &getRect() { return pos_; } + [[nodiscard]] auto getX() const -> float { return pos_.x; } + [[nodiscard]] auto getY() const -> float { return pos_.y; } + [[nodiscard]] auto getWidth() const -> float { return pos_.w; } + [[nodiscard]] auto getHeight() const -> float { return pos_.h; } + [[nodiscard]] auto getPosition() const -> SDL_FRect { return pos_; } + auto getRect() -> SDL_FRect& { return pos_; } // --- Setters de posición y tamaño --- - void setX(float x) { pos_.x = x; } - void setY(float y) { pos_.y = y; } - void setWidth(float w) { pos_.w = w; } - void setHeight(float h) { pos_.h = h; } - void setPosition(float x, float y); - void setPosition(SDL_FPoint p); - void setPosition(SDL_FRect r) { pos_ = r; } + void setX(float pos_x) { pos_.x = pos_x; } + void setY(float pos_y) { pos_.y = pos_y; } + void setWidth(float width) { pos_.w = width; } + void setHeight(float height) { pos_.h = height; } + void setPosition(float pos_x, float pos_y); + void setPosition(SDL_FPoint point); + void setPosition(SDL_FRect rect) { pos_ = rect; } // --- Zoom --- void setZoom(float zoom) { zoom_ = zoom; } @@ -44,12 +44,12 @@ class Sprite { void incY(float value) { pos_.y += value; } // --- Sprite clip --- - SDL_FRect getSpriteClip() const { return sprite_clip_; } + [[nodiscard]] auto getSpriteClip() const -> SDL_FRect { return sprite_clip_; } void setSpriteClip(SDL_FRect rect) { sprite_clip_ = rect; } - void setSpriteClip(float x, float y, float w, float h) { sprite_clip_ = SDL_FRect{x, y, w, h}; } + void setSpriteClip(float pos_x, float pos_y, float width, float height) { sprite_clip_ = SDL_FRect{pos_x, pos_y, width, height}; } // --- Textura --- - std::shared_ptr getTexture() const { return texture_; } + [[nodiscard]] auto getTexture() const -> std::shared_ptr { return texture_; } void setTexture(std::shared_ptr texture) { texture_ = texture; } protected: @@ -57,5 +57,5 @@ class Sprite { std::shared_ptr texture_; // Textura donde están todos los dibujos del sprite SDL_FRect pos_; // Posición y tamaño donde dibujar el sprite SDL_FRect sprite_clip_; // Rectángulo de origen de la textura que se dibujará en pantalla - double zoom_ = 1.0f; // Zoom aplicado a la textura + double zoom_ = 1.0F; // Zoom aplicado a la textura }; \ No newline at end of file diff --git a/source/tabe.cpp b/source/tabe.cpp index 1abc542..72b86ef 100644 --- a/source/tabe.cpp +++ b/source/tabe.cpp @@ -2,10 +2,10 @@ #include "tabe.h" #include // Para SDL_FlipMode, SDL_GetTicks -#include // Para rand, abs #include // Para max #include // Para abs +#include // Para rand, abs #include // Para basic_string #include "audio.h" // Para Audio @@ -16,7 +16,7 @@ // Constructor Tabe::Tabe() : sprite_(std::make_unique(Resource::get()->getTexture("tabe.png"), Resource::get()->getAnimation("tabe.ani"))), - timer_(TabeTimer(2.5f, 4.0f)) {} + timer_(TabeTimer(2.5F, 4.0F)) {} // Actualiza la lógica void Tabe::update() { @@ -27,7 +27,7 @@ void Tabe::update() { } timer_.update(); - if (timer_.should_spawn()) { + if (timer_.shouldSpawn()) { enable(); } } @@ -41,50 +41,50 @@ void Tabe::render() { // Mueve el objeto void Tabe::move() { - const int x = static_cast(x_); - speed_ += accel_; - x_ += speed_; - fly_distance_ -= std::abs(x - static_cast(x_)); + const int X = static_cast(x_); + speed_ += accel_; + x_ += speed_; + fly_distance_ -= std::abs(X - static_cast(x_)); - // Comprueba si sale por los bordes - const float min_x = param.game.game_area.rect.x - WIDTH_; - const float max_x = param.game.game_area.rect.x + param.game.game_area.rect.w; - switch (destiny_) { - case TabeDirection::TO_THE_LEFT: { - if (x_ < min_x) { - disable(); - } - if (x_ > param.game.game_area.rect.x + param.game.game_area.rect.w - WIDTH_ && direction_ == TabeDirection::TO_THE_RIGHT) { - setRandomFlyPath(TabeDirection::TO_THE_LEFT, 80); - x_ = param.game.game_area.rect.x + param.game.game_area.rect.w - WIDTH_; - } - break; - } + // Comprueba si sale por los bordes + const float MIN_X = param.game.game_area.rect.x - WIDTH; + const float MAX_X = param.game.game_area.rect.x + param.game.game_area.rect.w; + switch (destiny_) { + case TabeDirection::TO_THE_LEFT: { + if (x_ < MIN_X) { + disable(); + } + if (x_ > param.game.game_area.rect.x + param.game.game_area.rect.w - WIDTH && direction_ == TabeDirection::TO_THE_RIGHT) { + setRandomFlyPath(TabeDirection::TO_THE_LEFT, 80); + x_ = param.game.game_area.rect.x + param.game.game_area.rect.w - WIDTH; + } + break; + } - case TabeDirection::TO_THE_RIGHT: { - if (x_ > max_x) { - disable(); - } - if (x_ < param.game.game_area.rect.x && direction_ == TabeDirection::TO_THE_LEFT) { - setRandomFlyPath(TabeDirection::TO_THE_RIGHT, 80); - x_ = param.game.game_area.rect.x; - } - break; - } - default: - break; + case TabeDirection::TO_THE_RIGHT: { + if (x_ > MAX_X) { + disable(); + } + if (x_ < param.game.game_area.rect.x && direction_ == TabeDirection::TO_THE_LEFT) { + setRandomFlyPath(TabeDirection::TO_THE_RIGHT, 80); + x_ = param.game.game_area.rect.x; + } + break; + } + default: + break; } if (fly_distance_ <= 0) { if (waiting_counter_ > 0) { - accel_ = speed_ = 0.0f; - --waiting_counter_; + accel_ = speed_ = 0.0F; + --waiting_counter_; } else { constexpr int CHOICES = 4; - const TabeDirection left[CHOICES] = {TabeDirection::TO_THE_LEFT, TabeDirection::TO_THE_LEFT, TabeDirection::TO_THE_LEFT, TabeDirection::TO_THE_RIGHT}; - const TabeDirection right[CHOICES] = {TabeDirection::TO_THE_LEFT, TabeDirection::TO_THE_RIGHT, TabeDirection::TO_THE_RIGHT, TabeDirection::TO_THE_RIGHT}; - const TabeDirection direction = destiny_ == TabeDirection::TO_THE_LEFT ? left[rand() % CHOICES] : right[rand() % CHOICES]; - setRandomFlyPath(direction, 20 + rand() % 40); + const TabeDirection LEFT[CHOICES] = {TabeDirection::TO_THE_LEFT, TabeDirection::TO_THE_LEFT, TabeDirection::TO_THE_LEFT, TabeDirection::TO_THE_RIGHT}; + const TabeDirection RIGHT[CHOICES] = {TabeDirection::TO_THE_LEFT, TabeDirection::TO_THE_RIGHT, TabeDirection::TO_THE_RIGHT, TabeDirection::TO_THE_RIGHT}; + const TabeDirection DIRECTION = destiny_ == TabeDirection::TO_THE_LEFT ? LEFT[rand() % CHOICES] : RIGHT[rand() % CHOICES]; + setRandomFlyPath(DIRECTION, 20 + rand() % 40); } } @@ -98,13 +98,13 @@ void Tabe::enable() { has_bonus_ = true; hit_counter_ = 0; number_of_hits_ = 0; - y_ = param.game.game_area.rect.y + 20.0f; + y_ = param.game.game_area.rect.y + 20.0F; // Establece una dirección aleatoria destiny_ = direction_ = rand() % 2 == 0 ? TabeDirection::TO_THE_LEFT : TabeDirection::TO_THE_RIGHT; // Establece la posición inicial - x_ = (direction_ == TabeDirection::TO_THE_LEFT) ? param.game.game_area.rect.x + param.game.game_area.rect.w : param.game.game_area.rect.x - WIDTH_; + x_ = (direction_ == TabeDirection::TO_THE_LEFT) ? param.game.game_area.rect.x + param.game.game_area.rect.w : param.game.game_area.rect.x - WIDTH; // Crea una ruta de vuelo setRandomFlyPath(direction_, 60); @@ -119,19 +119,19 @@ void Tabe::setRandomFlyPath(TabeDirection direction, int lenght) { waiting_counter_ = 5 + rand() % 15; Audio::get()->playSound("tabe.wav"); - constexpr float SPEED = 2.0f; + constexpr float SPEED = 2.0F; switch (direction) { case TabeDirection::TO_THE_LEFT: { - speed_ = -1.0f * SPEED; - accel_ = -1.0f * (1 + rand() % 10) / 30.0f; - sprite_->setFlip(SDL_FLIP_NONE); - break; + speed_ = -1.0F * SPEED; + accel_ = -1.0F * (1 + rand() % 10) / 30.0F; + sprite_->setFlip(SDL_FLIP_NONE); + break; } case TabeDirection::TO_THE_RIGHT: { speed_ = SPEED; - accel_ = (1 + rand() % 10) / 30.0f; + accel_ = (1 + rand() % 10) / 30.0F; sprite_->setFlip(SDL_FLIP_HORIZONTAL); break; } @@ -174,12 +174,12 @@ void Tabe::updateState() { } // Intenta obtener el bonus -bool Tabe::tryToGetBonus() { - if (has_bonus_ && rand() % std::max(1, 15 - number_of_hits_) == 0) { - has_bonus_ = false; - return true; - } - return false; +auto Tabe::tryToGetBonus() -> bool { + if (has_bonus_ && rand() % std::max(1, 15 - number_of_hits_) == 0) { + has_bonus_ = false; + return true; + } + return false; } // Actualiza el temporizador diff --git a/source/tabe.h b/source/tabe.h index 869868b..76daee4 100644 --- a/source/tabe.h +++ b/source/tabe.h @@ -1,86 +1,91 @@ #pragma once #include // Para Uint32, SDL_GetTicks, SDL_FRect -#include // Para rand -#include // Para unique_ptr +#include // Para rand +#include // Para unique_ptr #include "animated_sprite.h" // Para AnimatedSprite // --- Enumeraciones para dirección y estado --- enum class TabeDirection : int { - TO_THE_LEFT = 0, - TO_THE_RIGHT = 1, + TO_THE_LEFT = 0, + TO_THE_RIGHT = 1, }; enum class TabeState : int { - FLY = 0, - HIT = 1, + FLY = 0, + HIT = 1, }; // --- Estructura para el temporizador del Tabe --- struct TabeTimer { + private: + static constexpr Uint32 MINUTES_TO_MILLISECONDS = 60000; // Factor de conversión de minutos a milisegundos + + public: Uint32 time_until_next_spawn; // Tiempo restante para la próxima aparición - Uint32 min_spawn_time; // Tiempo mínimo entre apariciones - Uint32 max_spawn_time; // Tiempo máximo entre apariciones + Uint32 min_spawn_time; // Tiempo mínimo entre apariciones (en milisegundos) + Uint32 max_spawn_time; // Tiempo máximo entre apariciones (en milisegundos) Uint32 current_time; // Tiempo actual Uint32 delta_time; // Diferencia de tiempo desde la última actualización Uint32 last_time; // Tiempo de la última actualización - bool is_paused; // Indica si el temporizador está pausado + bool is_paused{false}; // Indica si el temporizador está pausado - // Constructor - TabeTimer(float minTime, float maxTime) - : min_spawn_time(minTime * 60000), max_spawn_time(maxTime * 60000), - current_time(SDL_GetTicks()), is_paused(false) { - reset(); + // Constructor - los parámetros min_time y max_time están en mintos + TabeTimer(float min_time, float max_time) + : min_spawn_time(static_cast(min_time * MINUTES_TO_MILLISECONDS)), + max_spawn_time(static_cast(max_time * MINUTES_TO_MILLISECONDS)), + current_time(SDL_GetTicks()) { + reset(); } // Restablece el temporizador con un nuevo tiempo hasta la próxima aparición void reset() { - Uint32 range = max_spawn_time - min_spawn_time; - time_until_next_spawn = min_spawn_time + rand() % (range + 1); - last_time = SDL_GetTicks(); + Uint32 range = max_spawn_time - min_spawn_time; + time_until_next_spawn = min_spawn_time + rand() % (range + 1); + last_time = SDL_GetTicks(); } // Actualiza el temporizador, decrementando el tiempo hasta la próxima aparición void update() { - current_time = SDL_GetTicks(); - - // Solo actualizar si no está pausado - if (!is_paused) { - delta_time = current_time - last_time; - - if (time_until_next_spawn > delta_time) { - time_until_next_spawn -= delta_time; - } else { - time_until_next_spawn = 0; - } + current_time = SDL_GetTicks(); + + // Solo actualizar si no está pausado + if (!is_paused) { + delta_time = current_time - last_time; + + if (time_until_next_spawn > delta_time) { + time_until_next_spawn -= delta_time; + } else { + time_until_next_spawn = 0; } - - // Siempre actualizar last_time para evitar saltos de tiempo al despausar - last_time = current_time; + } + + // Siempre actualizar last_time para evitar saltos de tiempo al despausar + last_time = current_time; } // Pausa o reanuda el temporizador void setPaused(bool paused) { - if (is_paused != paused) { - is_paused = paused; - // Al despausar, actualizar last_time para evitar saltos - if (!paused) { - last_time = SDL_GetTicks(); - } + if (is_paused != paused) { + is_paused = paused; + // Al despausar, actualizar last_time para evitar saltos + if (!paused) { + last_time = SDL_GetTicks(); } + } } // Indica si el temporizador ha finalizado - bool should_spawn() const { - return time_until_next_spawn == 0 && !is_paused; + [[nodiscard]] auto shouldSpawn() const -> bool { + return time_until_next_spawn == 0 && !is_paused; } }; // --- Clase Tabe --- class Tabe { - public: + public: // --- Constructores y destructor --- Tabe(); ~Tabe() = default; @@ -90,17 +95,17 @@ class Tabe { void render(); // Dibuja el objeto void enable(); // Habilita el objeto void setState(TabeState state); // Establece el estado - bool tryToGetBonus(); // Intenta obtener el bonus + auto tryToGetBonus() -> bool; // Intenta obtener el bonus void pauseTimer(bool value); // Detiene/activa el timer // --- Getters --- - SDL_FRect &getCollider() { return sprite_->getRect(); } // Obtiene el área de colisión - bool isEnabled() const { return enabled_; } // Indica si el objeto está activo + auto getCollider() -> SDL_FRect& { return sprite_->getRect(); } // Obtiene el área de colisión + [[nodiscard]] auto isEnabled() const -> bool { return enabled_; } // Indica si el objeto está activo - private: + private: // --- Constantes --- - static constexpr int WIDTH_ = 32; - static constexpr int HEIGHT_ = 32; + static constexpr int WIDTH = 32; + static constexpr int HEIGHT = 32; // --- Objetos y punteros --- std::unique_ptr sprite_; // Sprite con los gráficos y animaciones @@ -108,8 +113,8 @@ class Tabe { // --- Variables de estado --- float x_ = 0; // Posición X float y_ = 0; // Posición Y - float speed_ = 0.0f; // Velocidad de movimiento - float accel_ = 0.0f; // Aceleración + float speed_ = 0.0F; // Velocidad de movimiento + float accel_ = 0.0F; // Aceleración int fly_distance_ = 0; // Distancia de vuelo int waiting_counter_ = 0; // Tiempo que pasa quieto bool enabled_ = false; // Indica si el objeto está activo diff --git a/source/text.h b/source/text.h index 965bfd4..086bb81 100644 --- a/source/text.h +++ b/source/text.h @@ -28,7 +28,7 @@ struct TextFile { }; // Llena una estructura TextFile desde un fichero -std::shared_ptr loadTextFile(const std::string &file_path); +auto loadTextFile(const std::string &file_path) -> std::shared_ptr; // --- Clase Text: pinta texto en pantalla a partir de un bitmap --- class Text { @@ -43,18 +43,18 @@ class Text { void write2X(int x, int y, const std::string &text, int kerning = 1); // Escribe el texto al doble de tamaño // --- Escritura en textura --- - std::shared_ptr writeToTexture(const std::string &text, int zoom = 1, int kerning = 1); // Escribe el texto en una textura - std::shared_ptr writeDXToTexture(Uint8 flags, const std::string &text, int kerning = 1, Color textColor = Color(), Uint8 shadow_distance = 1, Color shadow_color = Color(), int lenght = -1); // Escribe el texto con extras en una textura + auto writeToTexture(const std::string &text, int zoom = 1, int kerning = 1) -> std::shared_ptr; // Escribe el texto en una textura + auto writeDXToTexture(Uint8 flags, const std::string &text, int kerning = 1, Color text_color = Color(), Uint8 shadow_distance = 1, Color shadow_color = Color(), int lenght = -1) -> std::shared_ptr; // Escribe el texto con extras en una textura // --- Métodos de escritura avanzada --- void writeColored(int x, int y, const std::string &text, Color color, int kerning = 1, int lenght = -1); // Escribe el texto con colores void writeShadowed(int x, int y, const std::string &text, Color color, Uint8 shadow_distance = 1, int kerning = 1, int lenght = -1); // Escribe el texto con sombra void writeCentered(int x, int y, const std::string &text, int kerning = 1, int lenght = -1); // Escribe el texto centrado en un punto x - void writeDX(Uint8 flags, int x, int y, const std::string &text, int kerning = 1, Color textColor = Color(), Uint8 shadow_distance = 1, Color shadow_color = Color(), int lenght = -1); // Escribe texto con extras + void writeDX(Uint8 flags, int x, int y, const std::string &text, int kerning = 1, Color text_color = Color(), Uint8 shadow_distance = 1, Color shadow_color = Color(), int lenght = -1); // Escribe texto con extras // --- Utilidades --- - int lenght(const std::string &text, int kerning = 1) const; // Obtiene la longitud en pixels de una cadena - int getCharacterSize() const; // Devuelve el tamaño de caracter actual + [[nodiscard]] auto lenght(const std::string &text, int kerning = 1) const -> int; // Obtiene la longitud en pixels de una cadena + [[nodiscard]] auto getCharacterSize() const -> int; // Devuelve el tamaño de caracter actual // --- Configuración --- void setFixedWidth(bool value); // Establece si se usa un tamaño fijo de letra diff --git a/source/texture.h b/source/texture.h index c66fb54..af6ecc8 100644 --- a/source/texture.h +++ b/source/texture.h @@ -6,6 +6,7 @@ #include // Para array #include // Para shared_ptr #include // Para string, basic_string +#include #include // Para vector struct Color; @@ -20,7 +21,7 @@ struct Surface { // Constructor Surface(Uint16 width, Uint16 height, std::shared_ptr pixels) - : data(pixels), w(width), h(height) {} + : data(std::move(pixels)), w(width), h(height) {} }; // Clase Texture: gestiona texturas, paletas y renderizado @@ -31,12 +32,12 @@ class Texture { ~Texture(); // --- Carga y creación --- - bool loadFromFile(const std::string &path); // Carga una imagen desde un fichero - bool createBlank(int width, int height, SDL_PixelFormat format = SDL_PIXELFORMAT_RGBA8888, SDL_TextureAccess access = SDL_TEXTUREACCESS_STREAMING); // Crea una textura en blanco - bool reLoad(); // Recarga la textura + auto loadFromFile(const std::string &path) -> bool; // Carga una imagen desde un fichero + auto createBlank(int width, int height, SDL_PixelFormat format = SDL_PIXELFORMAT_RGBA8888, SDL_TextureAccess access = SDL_TEXTUREACCESS_STREAMING) -> bool; // Crea una textura en blanco + auto reLoad() -> bool; // Recarga la textura // --- Renderizado --- - void render(int x, int y, SDL_FRect *clip = nullptr, float zoomW = 1, float zoomH = 1, double angle = 0.0, SDL_FPoint *center = nullptr, SDL_FlipMode flip = SDL_FLIP_NONE); // Renderiza la textura en un punto específico + void render(int x, int y, SDL_FRect *clip = nullptr, float zoom_w = 1, float zoom_h = 1, double angle = 0.0, SDL_FPoint *center = nullptr, SDL_FlipMode flip = SDL_FLIP_NONE); // Renderiza la textura en un punto específico void setAsRenderTarget(SDL_Renderer *renderer); // Establece la textura como objetivo de renderizado // --- Modificadores de color y blending --- @@ -52,12 +53,12 @@ class Texture { void setPalette(size_t palette); // Cambia la paleta de la textura // --- Getters --- - int getWidth(); // Obtiene el ancho de la imagen - int getHeight(); // Obtiene el alto de la imagen - SDL_Texture *getSDLTexture(); // Obtiene la textura SDL - SDL_Renderer *getRenderer(); // Obtiene el renderizador + auto getWidth() -> int; // Obtiene el ancho de la imagen + auto getHeight() -> int; // Obtiene el alto de la imagen + auto getSDLTexture() -> SDL_Texture *; // Obtiene la textura SDL + auto getRenderer() -> SDL_Renderer *; // Obtiene el renderizador - private: + private: // --- Objetos y punteros --- SDL_Renderer *renderer_; // Renderizador donde dibujar la textura SDL_Texture *texture_ = nullptr; // La textura @@ -71,10 +72,10 @@ class Texture { int current_palette_ = 0; // Índice de la paleta en uso // --- Métodos internos --- - std::shared_ptr loadSurface(const std::string &file_name); // Crea una surface desde un fichero .gif + auto loadSurface(const std::string &file_name) -> std::shared_ptr; // Crea una surface desde un fichero .gif void flipSurface(); // Vuelca la surface en la textura - Palette loadPaletteFromFile(const std::string &file_name); // Carga una paleta desde un fichero + auto loadPaletteFromFile(const std::string &file_name) -> Palette; // Carga una paleta desde un fichero void unloadTexture(); // Libera la memoria de la textura void unloadSurface(); // Libera la surface actual - Palette readPalFile(const std::string &file_path); // Carga una paleta desde un archivo .pal + auto readPalFile(const std::string &file_path) -> Palette; // Carga una paleta desde un archivo .pal }; \ No newline at end of file diff --git a/source/ui/menu_renderer.cpp b/source/ui/menu_renderer.cpp index 118b773..a533221 100644 --- a/source/ui/menu_renderer.cpp +++ b/source/ui/menu_renderer.cpp @@ -25,7 +25,7 @@ void MenuRenderer::render(const ServiceMenu *menu_state) { SDL_RenderFillRect(Screen::get()->getRenderer(), &rect_); // Dibuja el borde - const Color BORDER_COLOR = param.service_menu.title_color.darken(); + const Color BORDER_COLOR = param.service_menu.title_color.DARKEN(); SDL_SetRenderDrawColor(Screen::get()->getRenderer(), BORDER_COLOR.r, BORDER_COLOR.g, BORDER_COLOR.b, 255); SDL_RenderRect(Screen::get()->getRenderer(), &rect_); SDL_RenderRect(Screen::get()->getRenderer(), &border_rect_); @@ -186,7 +186,7 @@ void MenuRenderer::updateColorCounter() { } Color MenuRenderer::getAnimatedSelectedColor() { - static auto colorCycle = generateMirroredCycle(param.service_menu.selected_color, ColorCycleStyle::HueWave); + static auto colorCycle = generateMirroredCycle(param.service_menu.selected_color, ColorCycleStyle::HUE_WAVE); return colorCycle.at(color_counter_ % colorCycle.size()); } diff --git a/source/utils.cpp b/source/utils.cpp index 022275a..0277c30 100644 --- a/source/utils.cpp +++ b/source/utils.cpp @@ -17,9 +17,9 @@ Overrides overrides = Overrides(); // Obtiene un color del vector de colores imitando al Coche Fantástico -Color getColorLikeKnightRider(const std::vector &colors, int counter_) { +auto getColorLikeKnightRider(const std::vector &colors, int counter) -> Color { int cycle_length = colors.size() * 2 - 2; - size_t n = counter_ % cycle_length; + size_t n = counter % cycle_length; size_t index; if (n < colors.size()) { @@ -32,14 +32,14 @@ Color getColorLikeKnightRider(const std::vector &colors, int counter_) { } // Calcula el cuadrado de la distancia entre dos puntos -double distanceSquared(int x1, int y1, int x2, int y2) { - const int delta_x = x2 - x1; - const int delta_y = y2 - y1; - return delta_x * delta_x + delta_y * delta_y; +auto distanceSquared(int x1, int y1, int x2, int y2) -> double { + const int DELTA_X = x2 - x1; + const int DELTA_Y = y2 - y1; + return DELTA_X * DELTA_X + DELTA_Y * DELTA_Y; } // Detector de colisiones entre dos circulos -bool checkCollision(const Circle &a, const Circle &b) { +auto checkCollision(const Circle &a, const Circle &b) -> bool { // Calcula el radio total al cuadrado int total_radius_squared = (a.r + b.r) * (a.r + b.r); @@ -48,84 +48,96 @@ bool checkCollision(const Circle &a, const Circle &b) { } // Detector de colisiones entre un circulo y un rectangulo -bool checkCollision(const Circle &a, const SDL_FRect &b) { +auto checkCollision(const Circle &a, const SDL_FRect &b) -> bool { // Encuentra el punto más cercano en el rectángulo - float cX = std::clamp(static_cast(a.x), b.x, b.x + b.w); - float cY = std::clamp(static_cast(a.y), b.y, b.y + b.h); + float c_x = std::clamp(static_cast(a.x), b.x, b.x + b.w); + float c_y = std::clamp(static_cast(a.y), b.y, b.y + b.h); // Si el punto más cercano está dentro del círculo - return distanceSquared(static_cast(a.x), static_cast(a.y), cX, cY) < static_cast(a.r) * a.r; + return distanceSquared(static_cast(a.x), static_cast(a.y), c_x, c_y) < static_cast(a.r) * a.r; } // Detector de colisiones entre dos rectangulos -bool checkCollision(const SDL_FRect &a, const SDL_FRect &b) { - const int leftA = a.x, rightA = a.x + a.w, topA = a.y, bottomA = a.y + a.h; - const int leftB = b.x, rightB = b.x + b.w, topB = b.y, bottomB = b.y + b.h; +auto checkCollision(const SDL_FRect &a, const SDL_FRect &b) -> bool { + const int LEFT_A = a.x; + const int RIGHT_A = a.x + a.w; + const int TOP_A = a.y; + const int BOTTOM_A = a.y + a.h; + const int LEFT_B = b.x; + const int RIGHT_B = b.x + b.w; + const int TOP_B = b.y; + const int BOTTOM_B = b.y + b.h; - if (bottomA <= topB) + if (BOTTOM_A <= TOP_B) { return false; - if (topA >= bottomB) + } + if (TOP_A >= BOTTOM_B) { return false; - if (rightA <= leftB) + } + if (RIGHT_A <= LEFT_B) { return false; - if (leftA >= rightB) + } + if (LEFT_A >= RIGHT_B) { return false; + } return true; } // Detector de colisiones entre un punto y un rectangulo -bool checkCollision(const SDL_FPoint &p, const SDL_FRect &r) { - if (p.x < r.x || p.x > r.x + r.w) +auto checkCollision(const SDL_FPoint &p, const SDL_FRect &r) -> bool { + if (p.x < r.x || p.x > r.x + r.w) { return false; - if (p.y < r.y || p.y > r.y + r.h) + } + if (p.y < r.y || p.y > r.y + r.h) { return false; + } return true; } // Convierte una cadena en un valor booleano -bool stringToBool(const std::string &str) { +auto stringToBool(const std::string &str) -> bool { std::string s = trim(toLower(str)); return (s == "true" || s == "1" || s == "yes" || s == "on"); } // Convierte un valor booleano en una cadena -std::string boolToString(bool value) { +auto boolToString(bool value) -> std::string { return value ? "true" : "false"; } // Convierte un valor booleano en una cadena "on" o "off" -std::string boolToOnOff(bool value) { +auto boolToOnOff(bool value) -> std::string { return value ? Lang::getText("[NOTIFICATIONS] 06") : Lang::getText("[NOTIFICATIONS] 07"); } // Convierte una cadena a minusculas -std::string toLower(const std::string &str) { +auto toLower(const std::string &str) -> std::string { std::string result = str; std::transform(result.begin(), result.end(), result.begin(), [](unsigned char c) { return std::tolower(c); }); return result; } // Dibuja un circulo -void DrawCircle(SDL_Renderer *renderer, int32_t centerX, int32_t centerY, int32_t radius) { - const int32_t diameter = (radius * 2); +void drawCircle(SDL_Renderer *renderer, int32_t center_x, int32_t center_y, int32_t radius) { + const int32_t DIAMETER = (radius * 2); int32_t x = (radius - 1); int32_t y = 0; int32_t tx = 1; int32_t ty = 1; - int32_t error = (tx - diameter); + int32_t error = (tx - DIAMETER); while (x >= y) { // Each of the following renders an octant of the circle - SDL_RenderPoint(renderer, centerX + x, centerY - y); - SDL_RenderPoint(renderer, centerX + x, centerY + y); - SDL_RenderPoint(renderer, centerX - x, centerY - y); - SDL_RenderPoint(renderer, centerX - x, centerY + y); - SDL_RenderPoint(renderer, centerX + y, centerY - x); - SDL_RenderPoint(renderer, centerX + y, centerY + x); - SDL_RenderPoint(renderer, centerX - y, centerY - x); - SDL_RenderPoint(renderer, centerX - y, centerY + x); + SDL_RenderPoint(renderer, center_x + x, center_y - y); + SDL_RenderPoint(renderer, center_x + x, center_y + y); + SDL_RenderPoint(renderer, center_x - x, center_y - y); + SDL_RenderPoint(renderer, center_x - x, center_y + y); + SDL_RenderPoint(renderer, center_x + y, center_y - x); + SDL_RenderPoint(renderer, center_x + y, center_y + x); + SDL_RenderPoint(renderer, center_x - y, center_y - x); + SDL_RenderPoint(renderer, center_x - y, center_y + x); if (error <= 0) { ++y; @@ -136,110 +148,135 @@ void DrawCircle(SDL_Renderer *renderer, int32_t centerX, int32_t centerY, int32_ if (error > 0) { --x; tx += 2; - error += (tx - diameter); + error += (tx - DIAMETER); } } } // Aclara el color -Color lightenColor(const Color &color, int amount) { - Color newColor; - newColor.r = std::min(255, color.r + amount); - newColor.g = std::min(255, color.g + amount); - newColor.b = std::min(255, color.b + amount); - return newColor; +auto lightenColor(const Color &color, int amount) -> Color { + Color new_color; + new_color.r = std::min(255, color.r + amount); + new_color.g = std::min(255, color.g + amount); + new_color.b = std::min(255, color.b + amount); + return new_color; } // Oscurece el color -Color DarkenColor(const Color &color, int amount) { - Color newColor; - newColor.r = std::min(255, color.r - +amount); - newColor.g = std::min(255, color.g - +amount); - newColor.b = std::min(255, color.b - +amount); - return newColor; +auto darkenColor(const Color &color, int amount) -> Color { + Color new_color; + new_color.r = std::min(255, color.r - +amount); + new_color.g = std::min(255, color.g - +amount); + new_color.b = std::min(255, color.b - +amount); + return new_color; } // Quita los espacioes en un string -std::string trim(const std::string &str) { +auto trim(const std::string &str) -> std::string { auto start = std::find_if_not(str.begin(), str.end(), ::isspace); auto end = std::find_if_not(str.rbegin(), str.rend(), ::isspace).base(); return (start < end ? std::string(start, end) : std::string()); } // Función de suavizado -double easeOutQuint(double t) { - return 1 - std::pow(1 - t, 5); +auto easeOutQuint(double time) -> double { + return 1 - std::pow(1 - time, 5); } // Función de suavizado -double easeInQuint(double t) { - return pow(t, 5); +auto easeInQuint(double time) -> double { + return pow(time, 5); } // Función de suavizado -double easeInOutQuint(double t) { - return t < 0.5 ? 16 * pow(t, 5) : 1 - pow(-2 * t + 2, 5) / 2; +auto easeInOutQuint(double time) -> double { + return time < 0.5 ? 16 * pow(time, 5) : 1 - pow(-2 * time + 2, 5) / 2; } // Función de suavizado -double easeInQuad(double t) { - return t * t; +auto easeInQuad(double time) -> double { + return time * time; } // Función de suavizado -double easeOutQuad(double t) { - return 1 - (1 - t) * (1 - t); +auto easeOutQuad(double time) -> double { + return 1 - (1 - time) * (1 - time); } // Función de suavizado -double easeInOutSine(double t) { - return -0.5 * (std::cos(M_PI * t) - 1); +auto easeInOutSine(double time) -> double { + return -0.5 * (std::cos(M_PI * time) - 1); } // Función de suavizado -double easeInOut(double t) { - return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t; +auto easeInOut(double time) -> double { + return time < 0.5 ? 2 * time * time : -1 + (4 - 2 * time) * time; } -// Función de suavizado -double easeInOutExpo(double t) { - return t == 0 ? 0 : (t == 1 ? 1 : (t < 0.5 ? pow(2, 20 * t - 10) / 2 : (2 - pow(2, -20 * t + 10)) / 2)); +// Función de suavizado (easeInOutExpo) +auto easeInOutExpo(double time) -> double { + if (time == 0) { + return 0; + } + + if (time == 1) { + return 1; + } + + if (time < 0.5) { + return pow(2, 20 * time - 10) / 2; + } + + return (2 - pow(2, -20 * time + 10)) / 2; } // Función de suavizado (easeInElastic) -double easeInElastic(double t) { - return t == 0 ? 0 : (t == 1 ? 1 : -pow(2, 10 * t - 10) * sin((t * 10 - 10.75) * (2 * M_PI) / 3)); -} - -// Función de suavizado -double easeOutBounce(double t) { - if (t < 1 / 2.75) { - return 7.5625 * t * t; - } else if (t < 2 / 2.75) { - t -= 1.5 / 2.75; - return 7.5625 * t * t + 0.75; - } else if (t < 2.5 / 2.75) { - t -= 2.25 / 2.75; - return 7.5625 * t * t + 0.9375; - } else { - t -= 2.625 / 2.75; - return 7.5625 * t * t + 0.984375; +auto easeInElastic(double time) -> double { + if (time == 0) { + return 0; } + + if (time == 1) { + return 1; + } + + const double C4 = (2 * M_PI) / 3; + return -pow(2, 10 * time - 10) * sin((time * 10 - 10.75) * C4); } // Función de suavizado -double easeOutElastic(double t) { - const double c4 = (2 * M_PI) / 3; // Constante para controlar la elasticidad +auto easeOutBounce(double time) -> double { + if (time < 1 / 2.75) { + return 7.5625 * time * time; + } + if (time < 2 / 2.75) { + time -= 1.5 / 2.75; + return 7.5625 * time * time + 0.75; + } + if (time < 2.5 / 2.75) { + time -= 2.25 / 2.75; + return 7.5625 * time * time + 0.9375; + } + time -= 2.625 / 2.75; + return 7.5625 * time * time + 0.984375; +} - return t == 0 - ? 0 - : (t == 1 - ? 1 - : pow(2, -10 * t) * sin((t * 10 - 0.75) * c4) + 1); +// Función de suavizado (easeOutElastic) +auto easeOutElastic(double time) -> double { + if (time == 0) { + return 0; + } + + if (time == 1) { + return 1; + } + + const double C4 = (2 * M_PI) / 3; // Constante para controlar la elasticidad + return pow(2, -10 * time) * sin((time * 10 - 0.75) * C4) + 1; } // Comprueba si una vector contiene una cadena -bool stringInVector(const std::vector &vec, const std::string &str) { +auto stringInVector(const std::vector &vec, const std::string &str) -> bool { return std::find(vec.begin(), vec.end(), str) != vec.end(); } @@ -270,27 +307,26 @@ void printWithDots(const std::string &text1, const std::string &text2, const std } // Carga el fichero de datos para la demo -DemoData loadDemoDataFromFile(const std::string &file_path) { +auto loadDemoDataFromFile(const std::string &file_path) -> DemoData { DemoData dd; // Indicador de éxito en la carga - auto file = SDL_IOFromFile(file_path.c_str(), "r+b"); - if (!file) { + auto *file = SDL_IOFromFile(file_path.c_str(), "r+b"); + if (file == nullptr) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Fichero no encontrado %s", file_path.c_str()); throw std::runtime_error("Fichero no encontrado: " + file_path); - } else { - printWithDots("DemoData : ", getFileName(file_path), "[ LOADED ]"); - - // Lee todos los datos del fichero y los deja en el destino - for (int i = 0; i < TOTAL_DEMO_DATA; ++i) { - DemoKeys dk = DemoKeys(); - SDL_ReadIO(file, &dk, sizeof(DemoKeys)); - dd.push_back(dk); - } - - // Cierra el fichero - SDL_CloseIO(file); } + printWithDots("DemoData : ", getFileName(file_path), "[ LOADED ]"); + + // Lee todos los datos del fichero y los deja en el destino + for (int i = 0; i < TOTAL_DEMO_DATA; ++i) { + DemoKeys dk = DemoKeys(); + SDL_ReadIO(file, &dk, sizeof(DemoKeys)); + dd.push_back(dk); + } + + // Cierra el fichero + SDL_CloseIO(file); return dd; } @@ -325,50 +361,54 @@ bool saveDemoFile(const std::string &file_path, const DemoData &dd) { #endif // RECORDING // Obtiene el nombre de un fichero a partir de una ruta completa -std::string getFileName(const std::string &path) { +auto getFileName(const std::string &path) -> std::string { return std::filesystem::path(path).filename().string(); } // Obtiene la ruta eliminando el nombre del fichero -std::string getPath(const std::string &full_path) { +auto getPath(const std::string &full_path) -> std::string { std::filesystem::path path(full_path); return path.parent_path().string(); } -constexpr HSV rgbToHsv(Color color) { - float r = color.r / 255.0f; - float g = color.g / 255.0f; - float b = color.b / 255.0f; +constexpr auto rgbToHsv(Color color) -> HSV { + float r = color.r / 255.0F; + float g = color.g / 255.0F; + float b = color.b / 255.0F; float max = fmaxf(fmaxf(r, g), b); float min = fminf(fminf(r, g), b); float delta = max - min; - float h = 0.0f; - if (delta > 0.00001f) { - if (max == r) - h = fmodf((g - b) / delta, 6.0f); - else if (max == g) - h = ((b - r) / delta) + 2.0f; - else - h = ((r - g) / delta) + 4.0f; - h *= 60.0f; - if (h < 0.0f) - h += 360.0f; + float h = 0.0F; + if (delta > 0.00001F) { + if (max == r) { + h = fmodf((g - b) / delta, 6.0F); + } else if (max == g) { + h = ((b - r) / delta) + 2.0F; + } else { + h = ((r - g) / delta) + 4.0F; + } + h *= 60.0F; + if (h < 0.0F) { + h += 360.0F; + } } - float s = (max <= 0.0f) ? 0.0f : delta / max; + float s = (max <= 0.0F) ? 0.0F : delta / max; float v = max; return {h, s, v}; } -constexpr Color hsvToRgb(HSV hsv) { +constexpr auto hsvToRgb(HSV hsv) -> Color { float c = hsv.v * hsv.s; - float x = c * (1 - std::abs(std::fmod(hsv.h / 60.0f, 2) - 1)); + float x = c * (1 - std::abs(std::fmod(hsv.h / 60.0F, 2) - 1)); float m = hsv.v - c; - float r = 0, g = 0, b = 0; + float r = 0; + float g = 0; + float b = 0; if (hsv.h < 60) { r = c; @@ -402,50 +442,50 @@ constexpr Color hsvToRgb(HSV hsv) { static_cast(roundf((b + m) * 255))); } -ColorCycle generateMirroredCycle(Color base, ColorCycleStyle style) { +auto generateMirroredCycle(Color base, ColorCycleStyle style) -> ColorCycle { ColorCycle result{}; - HSV baseHSV = rgbToHsv(base); + HSV base_hsv = rgbToHsv(base); for (size_t i = 0; i < COLOR_CYCLE_SIZE; ++i) { float t = static_cast(i) / (COLOR_CYCLE_SIZE - 1); // 0 → 1 - float hueShift = 0.0f; - float satShift = 0.0f; - float valShift = 0.0f; + float hue_shift = 0.0F; + float sat_shift = 0.0F; + float val_shift = 0.0F; switch (style) { - case ColorCycleStyle::SubtlePulse: + case ColorCycleStyle::SUBTLE_PULSE: // Solo brillo suave - valShift = 0.07f * sinf(t * M_PI); + val_shift = 0.07F * sinf(t * M_PI); break; - case ColorCycleStyle::HueWave: + case ColorCycleStyle::HUE_WAVE: // Oscilación leve de tono - hueShift = 15.0f * (t - 0.5f) * 2.0f; - valShift = 0.05f * sinf(t * M_PI); + hue_shift = 15.0F * (t - 0.5F) * 2.0F; + val_shift = 0.05F * sinf(t * M_PI); break; - case ColorCycleStyle::Vibrant: + case ColorCycleStyle::VIBRANT: // Cambios fuertes en tono y brillo - hueShift = 35.0f * sinf(t * M_PI); - valShift = 0.2f * sinf(t * M_PI); - satShift = -0.2f * sinf(t * M_PI); + hue_shift = 35.0F * sinf(t * M_PI); + val_shift = 0.2F * sinf(t * M_PI); + sat_shift = -0.2F * sinf(t * M_PI); break; - case ColorCycleStyle::DarkenGlow: + case ColorCycleStyle::DARKEN_GLOW: // Se oscurece al centro - valShift = -0.15f * sinf(t * M_PI); + val_shift = -0.15F * sinf(t * M_PI); break; - case ColorCycleStyle::LightFlash: + case ColorCycleStyle::LIGHT_FLASH: // Se ilumina al centro - valShift = 0.25f * sinf(t * M_PI); + val_shift = 0.25F * sinf(t * M_PI); break; } HSV adjusted = { - fmodf(baseHSV.h + hueShift + 360.0f, 360.0f), - fminf(1.0f, fmaxf(0.0f, baseHSV.s + satShift)), - fminf(1.0f, fmaxf(0.0f, baseHSV.v + valShift))}; + fmodf(base_hsv.h + hue_shift + 360.0F, 360.0F), + fminf(1.0F, fmaxf(0.0F, base_hsv.s + sat_shift)), + fminf(1.0F, fmaxf(0.0F, base_hsv.v + val_shift))}; Color c = hsvToRgb(adjusted); result[i] = c; diff --git a/source/utils.h b/source/utils.h index 54fff54..3d5c132 100644 --- a/source/utils.h +++ b/source/utils.h @@ -1,11 +1,11 @@ #pragma once #include // Para Uint8, SDL_FRect, SDL_FPoint, SDL_Renderer -#include // Para int32_t #include // Para max, min #include // Para array #include // Para isxdigit +#include // Para int32_t #include // Para abs, size_t #include // Para invalid_argument #include // Para string, basic_string, stoi @@ -18,105 +18,131 @@ constexpr size_t COLOR_CYCLE_SIZE = 6; // Mitad del ciclo espejado // --- Estructuras y tipos --- struct Overrides { - std::string param_file; // Fichero de parametros a utilizar - bool clear_hi_score_table; // Reinicia la tabla de records + std::string param_file; // Fichero de parametros a utilizar + bool clear_hi_score_table{false}; // Reinicia la tabla de records - Overrides() - : param_file(""), clear_hi_score_table(false) {} + Overrides() = default; }; extern Overrides overrides; // Estructura para definir un circulo struct Circle { - int x, y, r; - Circle() : x(0), y(0), r(0) {} - Circle(int xCoord, int yCoord, int radius) - : x(xCoord), y(yCoord), r(radius) {} + int x, y, r; + Circle() : x(0), y(0), r(0) {} + Circle(int x_coord, int y_coord, int radius) + : x(x_coord), y(y_coord), r(radius) {} }; // Estructura para definir un color RGBA struct Color { - Uint8 r, g, b, a; - constexpr Color() : r(0), g(0), b(0), a(255) {} - explicit constexpr Color(Uint8 red, Uint8 green, Uint8 blue, Uint8 alpha = 255) : r(red), g(green), b(blue), a(alpha) {} + private: + static constexpr Uint8 MAX_COLOR_VALUE = 255; + static constexpr Uint8 MIN_COLOR_VALUE = 0; + static constexpr Uint8 DEFAULT_ALPHA = 255; + static constexpr int DEFAULT_LIGHTEN_AMOUNT = 50; + static constexpr int DEFAULT_DARKEN_AMOUNT = 50; + static constexpr int DEFAULT_APPROACH_STEP = 1; + static constexpr size_t HEX_RGB_LENGTH = 6; + static constexpr size_t HEX_RGBA_LENGTH = 8; + static constexpr int HEX_BASE = 16; + static constexpr size_t HEX_COMPONENT_LENGTH = 2; - constexpr Color inverse() const { return Color(255 - r, 255 - g, 255 - b, a); } - constexpr Color lighten(int amount = 50) const { - return Color( - std::min(255, r + amount), - std::min(255, g + amount), - std::min(255, b + amount), - a); - } - constexpr Color darken(int amount = 50) const { - return Color( - std::max(0, r - amount), - std::max(0, g - amount), - std::max(0, b - amount), - a); - } + public: + Uint8 r, g, b, a; - // Método estático para crear Color desde string hexadecimal - static Color fromHex(const std::string &hexStr) { - std::string hex = hexStr; + constexpr Color() : r(MIN_COLOR_VALUE), g(MIN_COLOR_VALUE), b(MIN_COLOR_VALUE), a(DEFAULT_ALPHA) {} - // Quitar '#' si existe - if (!hex.empty() && hex[0] == '#') { - hex = hex.substr(1); + explicit constexpr Color(Uint8 red, Uint8 green, Uint8 blue, Uint8 alpha = DEFAULT_ALPHA) + : r(red), g(green), b(blue), a(alpha) {} + + [[nodiscard]] constexpr auto INVERSE() const -> Color { + return Color(MAX_COLOR_VALUE - r, MAX_COLOR_VALUE - g, MAX_COLOR_VALUE - b, a); } - // Verificar longitud válida (6 para RGB o 8 para RGBA) - if (hex.length() != 6 && hex.length() != 8) { - throw std::invalid_argument("String hexadecimal debe tener 6 o 8 caracteres"); + [[nodiscard]] constexpr auto LIGHTEN(int amount = DEFAULT_LIGHTEN_AMOUNT) const -> Color { + return Color( + std::min(static_cast(MAX_COLOR_VALUE), r + amount), + std::min(static_cast(MAX_COLOR_VALUE), g + amount), + std::min(static_cast(MAX_COLOR_VALUE), b + amount), + a); } - // Verificar que todos los caracteres sean hexadecimales válidos - for (char c : hex) { - if (!std::isxdigit(c)) { - throw std::invalid_argument("String contiene caracteres no hexadecimales"); + [[nodiscard]] constexpr auto DARKEN(int amount = DEFAULT_DARKEN_AMOUNT) const -> Color { + return Color( + std::max(static_cast(MIN_COLOR_VALUE), r - amount), + std::max(static_cast(MIN_COLOR_VALUE), g - amount), + std::max(static_cast(MIN_COLOR_VALUE), b - amount), + a); + } + + // Método estático para crear Color desde string hexadecimal + static auto fromHex(const std::string &hex_str) -> Color { + std::string hex = hex_str; + + // Quitar '#' si existe + if (!hex.empty() && hex[0] == '#') { + hex = hex.substr(1); } + + // Verificar longitud válida (6 para RGB o 8 para RGBA) + if (hex.length() != HEX_RGB_LENGTH && hex.length() != HEX_RGBA_LENGTH) { + throw std::invalid_argument("String hexadecimal debe tener 6 o 8 caracteres"); + } + + // 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"); + } + } + + // Convertir cada par de caracteres a valores RGB(A) + Uint8 r = static_cast(std::stoi(hex.substr(0, HEX_COMPONENT_LENGTH), nullptr, HEX_BASE)); + Uint8 g = static_cast(std::stoi(hex.substr(HEX_COMPONENT_LENGTH, HEX_COMPONENT_LENGTH), nullptr, HEX_BASE)); + Uint8 b = static_cast(std::stoi(hex.substr(HEX_COMPONENT_LENGTH * 2, HEX_COMPONENT_LENGTH), nullptr, HEX_BASE)); + Uint8 a = DEFAULT_ALPHA; // Alpha por defecto + + // Si tiene 8 caracteres, extraer el alpha + if (hex.length() == HEX_RGBA_LENGTH) { + a = static_cast(std::stoi(hex.substr(HEX_COMPONENT_LENGTH * 3, HEX_COMPONENT_LENGTH), nullptr, HEX_BASE)); + } + + return Color(r, g, b, a); } - // Convertir cada par de caracteres a valores RGB(A) - Uint8 r = static_cast(std::stoi(hex.substr(0, 2), nullptr, 16)); - Uint8 g = static_cast(std::stoi(hex.substr(2, 2), nullptr, 16)); - Uint8 b = static_cast(std::stoi(hex.substr(4, 2), nullptr, 16)); - Uint8 a = 255; // Alpha por defecto - - // Si tiene 8 caracteres, extraer el alpha - if (hex.length() == 8) { - a = static_cast(std::stoi(hex.substr(6, 2), nullptr, 16)); + [[nodiscard]] constexpr auto IS_EQUAL_TO(const Color &other) const -> bool { + return r == other.r && g == other.g && b == other.b && a == other.a; } - return Color(r, g, b, a); - } + [[nodiscard]] constexpr auto APPROACH_TO(const Color &target, int step = DEFAULT_APPROACH_STEP) const -> Color { + auto approach_component = [step](Uint8 current, Uint8 target_val) -> Uint8 { + if (std::abs(current - target_val) <= step) { + return target_val; + } + return (current < target_val) ? current + step : current - step; + }; - constexpr bool isEqualTo(const Color &other) const { - return r == other.r && g == other.g && b == other.b && a == other.a; - } + Uint8 new_r = approach_component(r, target.r); + Uint8 new_g = approach_component(g, target.g); + Uint8 new_b = approach_component(b, target.b); + Uint8 new_a = approach_component(a, target.a); - constexpr Color approachTo(const Color &target, int step = 1) const { - Uint8 newR = (std::abs(r - target.r) <= step) ? target.r : (r < target.r ? r + step : r - step); - Uint8 newG = (std::abs(g - target.g) <= step) ? target.g : (g < target.g ? g + step : g - step); - Uint8 newB = (std::abs(b - target.b) <= step) ? target.b : (b < target.b ? b + step : b - step); - Uint8 newA = (std::abs(a - target.a) <= step) ? target.a : (a < target.a ? a + step : a - step); - - return Color(newR, newG, newB, newA); - } + return Color(new_r, new_g, new_b, new_a); + } }; // Estructura para definir un color HSV struct HSV { - float h, s, v; + float h, s, v; }; // Estructura para definir el ciclo de color enum class ColorCycleStyle { - SubtlePulse, // Variación leve en brillo (por defecto) - HueWave, // Variación suave en tono (sin verde) - Vibrant, // Cambios agresivos en tono y brillo - DarkenGlow, // Oscurece hacia el centro y regresa - LightFlash // Ilumina hacia el centro y regresa + SUBTLE_PULSE, // Variación leve en brillo (por defecto) + HUE_WAVE, // Variación suave en tono (sin verde) + VIBRANT, // Cambios agresivos en tono y brillo + DARKEN_GLOW, // Oscurece hacia el centro y regresa + LIGHT_FLASH // Ilumina hacia el centro y regresa }; // Posiciones de las notificaciones @@ -130,40 +156,40 @@ enum class NotifyPosition { // Estructura para datos de la demo struct DemoKeys { - Uint8 left; - Uint8 right; - Uint8 no_input; - Uint8 fire; - Uint8 fire_left; - Uint8 fire_right; + Uint8 left; + Uint8 right; + Uint8 no_input; + Uint8 fire; + Uint8 fire_left; + Uint8 fire_right; - explicit DemoKeys(Uint8 l = 0, Uint8 r = 0, Uint8 ni = 0, Uint8 f = 0, Uint8 fl = 0, Uint8 fr = 0) - : left(l), right(r), no_input(ni), fire(f), fire_left(fl), fire_right(fr) {} + explicit DemoKeys(Uint8 l = 0, Uint8 r = 0, Uint8 ni = 0, Uint8 f = 0, Uint8 fl = 0, Uint8 fr = 0) + : left(l), right(r), no_input(ni), fire(f), fire_left(fl), fire_right(fr) {} }; using DemoData = std::vector; struct Demo { - bool enabled; // Indica si está activo el modo demo - bool recording; // Indica si está activado el modo para grabar la demo - int counter; // Contador para el modo demo - DemoKeys keys; // Variable con las pulsaciones de teclas del modo demo - std::vector data; // Vector con diferentes sets de datos con los movimientos para la demo + bool enabled; // Indica si está activo el modo demo + bool recording; // Indica si está activado el modo para grabar la demo + int counter; // Contador para el modo demo + DemoKeys keys; // Variable con las pulsaciones de teclas del modo demo + std::vector data; // Vector con diferentes sets de datos con los movimientos para la demo - Demo() : enabled(false), recording(false), counter(0), keys(), data() {} - Demo(bool e, bool r, int c, const DemoKeys &k, const std::vector &d) - : enabled(e), recording(r), counter(c), keys(k), data(d) {} + Demo() : enabled(false), recording(false), counter(0) {} + Demo(bool e, bool r, int c, const DemoKeys &k, const std::vector &d) + : enabled(e), recording(r), counter(c), keys(k), data(d) {} }; // Posiciones dentro de un rectangulo struct Zone { - SDL_FRect rect; // Rectangulo que define la zona - float center_x; // Anclaje al 50% del eje X - float first_quarter_x; // Anclaje al 25% del eje X - float third_quarter_x; // Anclaje al 75% del eje X - float center_y; // Anclaje al 50% del eje Y - float first_quarter_y; // Anclaje al 25% del eje Y - float third_quarter_y; // Anclaje al 75% del eje Y + SDL_FRect rect; // Rectangulo que define la zona + float center_x; // Anclaje al 50% del eje X + float first_quarter_x; // Anclaje al 25% del eje X + float third_quarter_x; // Anclaje al 75% del eje X + float center_y; // Anclaje al 50% del eje Y + float first_quarter_y; // Anclaje al 25% del eje Y + float third_quarter_y; // Anclaje al 75% del eje Y }; // --- Alias --- @@ -183,56 +209,56 @@ constexpr Color PINK_SKY_COLOR = Color(0XFF, 0X6B, 0X97); constexpr Color GREEN_SKY_COLOR = Color(0X00, 0X79, 0X6B); // Colores y gráficos -Color getColorLikeKnightRider(const std::vector &colors, int counter_); -constexpr HSV rgbToHsv(Color color); -constexpr Color hsvToRgb(HSV hsv); -ColorCycle generateMirroredCycle(Color base, ColorCycleStyle style = ColorCycleStyle::SubtlePulse); +auto getColorLikeKnightRider(const std::vector &colors, int counter) -> Color; +constexpr auto rgbToHsv(Color color) -> HSV; +constexpr auto hsvToRgb(HSV hsv) -> Color; +auto generateMirroredCycle(Color base, ColorCycleStyle style = ColorCycleStyle::SUBTLE_PULSE) -> ColorCycle; // Colisiones y geometría -double distanceSquared(int x1, int y1, int x2, int y2); -bool checkCollision(const Circle &a, const Circle &b); -bool checkCollision(const Circle &a, const SDL_FRect &b); -bool checkCollision(const SDL_FRect &a, const SDL_FRect &b); -bool checkCollision(const SDL_FPoint &p, const SDL_FRect &r); +auto distanceSquared(int x1, int y1, int x2, int y2) -> double; +auto checkCollision(const Circle &a, const Circle &b) -> bool; +auto checkCollision(const Circle &a, const SDL_FRect &b) -> bool; +auto checkCollision(const SDL_FRect &a, const SDL_FRect &b) -> bool; +auto checkCollision(const SDL_FPoint &p, const SDL_FRect &r) -> bool; // Conversión y manipulación de cadenas -bool stringToBool(const std::string &str); -std::string boolToString(bool value); -std::string boolToOnOff(bool value); -std::string toLower(const std::string &str); -std::string trim(const std::string &str); +auto stringToBool(const std::string &str) -> bool; +auto boolToString(bool value) -> std::string; +auto boolToOnOff(bool value) -> std::string; +auto toLower(const std::string &str) -> std::string; +auto trim(const std::string &str) -> std::string; // Dibujo -void DrawCircle(SDL_Renderer *renderer, int32_t centerX, int32_t centerY, int32_t radius); +void drawCircle(SDL_Renderer *renderer, int32_t center_x, int32_t center_y, int32_t radius); // Manipulación de color -Color lightenColor(const Color &color, int amount); -Color DarkenColor(const Color &color, int amount); +auto lightenColor(const Color &color, int amount) -> Color; +auto darkenColor(const Color &color, int amount) -> Color; // Funciones de suavizado (easing) -double easeOutQuint(double t); -double easeInQuint(double t); -double easeInOutQuint(double t); -double easeInQuad(double t); -double easeOutQuad(double t); -double easeInOutSine(double t); -double easeInOut(double t); -double easeInOutExpo(double t); -double easeOutBounce(double t); -double easeOutElastic(double t); -double easeInElastic(double t); +auto easeOutQuint(double time) -> double; +auto easeInQuint(double time) -> double; +auto easeInOutQuint(double time) -> double; +auto easeInQuad(double time) -> double; +auto easeOutQuad(double time) -> double; +auto easeInOutSine(double time) -> double; +auto easeInOut(double time) -> double; +auto easeInOutExpo(double time) -> double; +auto easeOutBounce(double time) -> double; +auto easeOutElastic(double time) -> double; +auto easeInElastic(double time) -> double; // Utilidades varias -bool stringInVector(const std::vector &vec, const std::string &str); // Comprueba si un vector contiene una cadena +auto stringInVector(const std::vector &vec, const std::string &str) -> bool; // Comprueba si un vector contiene una cadena void printWithDots(const std::string &text1, const std::string &text2, const std::string &text3); // Imprime una línea con puntos // Demo -DemoData loadDemoDataFromFile(const std::string &file_path); +auto loadDemoDataFromFile(const std::string &file_path) -> DemoData; #ifdef RECORDING bool saveDemoFile(const std::string &file_path, const DemoData &dd); #endif // Ficheros y rutas -std::string getFileName(const std::string &path); // Obtiene el nombre de un fichero a partir de una ruta -std::string getPath(const std::string &full_path); // Obtiene la ruta eliminando el nombre del fichero \ No newline at end of file +auto getFileName(const std::string &path) -> std::string; // Obtiene el nombre de un fichero a partir de una ruta +auto getPath(const std::string &full_path) -> std::string; // Obtiene la ruta eliminando el nombre del fichero \ No newline at end of file