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