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