input: treballant en la nova estructura per als controladors

This commit is contained in:
2025-07-30 10:16:44 +02:00
parent 989f081a25
commit 69ee847575
6 changed files with 129 additions and 74 deletions

View File

@@ -597,7 +597,7 @@ void Director::reset() {
{ {
Resource::get()->reload(); Resource::get()->reload();
} }
Input::get()->discoverGameControllers(); //Input::get()->discoverGameControllers();
bindInputs(); bindInputs();
ServiceMenu::get()->reset(); ServiceMenu::get()->reset();
Section::name = Section::Name::LOGO; Section::name = Section::Name::LOGO;

View File

@@ -163,7 +163,7 @@ void incWindowSize() {
// Comprueba el boton de servicio // Comprueba el boton de servicio
auto checkServiceButton() -> bool { auto checkServiceButton() -> bool {
// Teclado // Teclado
if (Input::get()->checkInput(Input::Action::SERVICE, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) { if (Input::get()->checkAction(Input::Action::SERVICE, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) {
toggleServiceMenu(); toggleServiceMenu();
return true; return true;
} }
@@ -171,7 +171,7 @@ auto checkServiceButton() -> bool {
// Mandos // Mandos
{ {
for (int i = 0; i < Input::get()->getNumControllers(); ++i) { for (int i = 0; i < Input::get()->getNumControllers(); ++i) {
if (Input::get()->checkInput(Input::Action::SERVICE, Input::DO_NOT_ALLOW_REPEAT, Input::Device::CONTROLLER, i)) { if (Input::get()->checkAction(Input::Action::SERVICE, Input::DO_NOT_ALLOW_REPEAT, Input::Device::CONTROLLER, i)) {
toggleServiceMenu(); toggleServiceMenu();
return true; return true;
} }
@@ -189,37 +189,37 @@ auto checkServiceInputs() -> bool {
// Teclado // Teclado
{ {
// Arriba // Arriba
if (Input::get()->checkInput(Input::Action::UP, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) { if (Input::get()->checkAction(Input::Action::UP, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) {
ServiceMenu::get()->setSelectorUp(); ServiceMenu::get()->setSelectorUp();
return true; return true;
} }
// Abajo // Abajo
if (Input::get()->checkInput(Input::Action::DOWN, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) { if (Input::get()->checkAction(Input::Action::DOWN, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) {
ServiceMenu::get()->setSelectorDown(); ServiceMenu::get()->setSelectorDown();
return true; return true;
} }
// Derecha // Derecha
if (Input::get()->checkInput(Input::Action::RIGHT, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) { if (Input::get()->checkAction(Input::Action::RIGHT, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) {
ServiceMenu::get()->adjustOption(true); ServiceMenu::get()->adjustOption(true);
return true; return true;
} }
// Izquierda // Izquierda
if (Input::get()->checkInput(Input::Action::LEFT, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) { if (Input::get()->checkAction(Input::Action::LEFT, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) {
ServiceMenu::get()->adjustOption(false); ServiceMenu::get()->adjustOption(false);
return true; return true;
} }
// Aceptar // Aceptar
if (Input::get()->checkInput(Input::Action::SM_SELECT, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) { if (Input::get()->checkAction(Input::Action::SM_SELECT, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) {
ServiceMenu::get()->selectOption(); ServiceMenu::get()->selectOption();
return true; return true;
} }
// Atras // Atras
if (Input::get()->checkInput(Input::Action::SM_BACK, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) { if (Input::get()->checkAction(Input::Action::SM_BACK, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) {
ServiceMenu::get()->moveBack(); ServiceMenu::get()->moveBack();
return true; return true;
} }
@@ -229,37 +229,37 @@ auto checkServiceInputs() -> bool {
{ {
for (int i = 0; i < Input::get()->getNumControllers(); ++i) { for (int i = 0; i < Input::get()->getNumControllers(); ++i) {
// Arriba // Arriba
if (Input::get()->checkInput(Input::Action::UP, Input::DO_NOT_ALLOW_REPEAT, Input::Device::CONTROLLER, i)) { if (Input::get()->checkAction(Input::Action::UP, Input::DO_NOT_ALLOW_REPEAT, Input::Device::CONTROLLER, i)) {
ServiceMenu::get()->setSelectorUp(); ServiceMenu::get()->setSelectorUp();
return true; return true;
} }
// Abajo // Abajo
if (Input::get()->checkInput(Input::Action::DOWN, Input::DO_NOT_ALLOW_REPEAT, Input::Device::CONTROLLER, i)) { if (Input::get()->checkAction(Input::Action::DOWN, Input::DO_NOT_ALLOW_REPEAT, Input::Device::CONTROLLER, i)) {
ServiceMenu::get()->setSelectorDown(); ServiceMenu::get()->setSelectorDown();
return true; return true;
} }
// Derecha // Derecha
if (Input::get()->checkInput(Input::Action::RIGHT, Input::DO_NOT_ALLOW_REPEAT, Input::Device::CONTROLLER, i)) { if (Input::get()->checkAction(Input::Action::RIGHT, Input::DO_NOT_ALLOW_REPEAT, Input::Device::CONTROLLER, i)) {
ServiceMenu::get()->adjustOption(true); ServiceMenu::get()->adjustOption(true);
return true; return true;
} }
// Izquierda // Izquierda
if (Input::get()->checkInput(Input::Action::LEFT, Input::DO_NOT_ALLOW_REPEAT, Input::Device::CONTROLLER, i)) { if (Input::get()->checkAction(Input::Action::LEFT, Input::DO_NOT_ALLOW_REPEAT, Input::Device::CONTROLLER, i)) {
ServiceMenu::get()->adjustOption(false); ServiceMenu::get()->adjustOption(false);
return true; return true;
} }
// Aceptar // Aceptar
if (Input::get()->checkInput(Input::Action::SM_SELECT, Input::DO_NOT_ALLOW_REPEAT, Input::Device::CONTROLLER, i)) { if (Input::get()->checkAction(Input::Action::SM_SELECT, Input::DO_NOT_ALLOW_REPEAT, Input::Device::CONTROLLER, i)) {
ServiceMenu::get()->selectOption(); ServiceMenu::get()->selectOption();
return true; return true;
} }
// Atras // Atras
if (Input::get()->checkInput(Input::Action::SM_BACK, Input::DO_NOT_ALLOW_REPEAT, Input::Device::CONTROLLER, i)) { if (Input::get()->checkAction(Input::Action::SM_BACK, Input::DO_NOT_ALLOW_REPEAT, Input::Device::CONTROLLER, i)) {
ServiceMenu::get()->moveBack(); ServiceMenu::get()->moveBack();
return true; return true;
} }
@@ -273,7 +273,7 @@ auto checkInputs() -> bool {
// Teclado // Teclado
{ {
// Comprueba el teclado para cambiar entre pantalla completa y ventana // Comprueba el teclado para cambiar entre pantalla completa y ventana
if (Input::get()->checkInput(Input::Action::WINDOW_FULLSCREEN, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) { if (Input::get()->checkAction(Input::Action::WINDOW_FULLSCREEN, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) {
Screen::get()->toggleFullscreen(); Screen::get()->toggleFullscreen();
const std::string MODE = Options::video.fullscreen ? Lang::getText("[NOTIFICATIONS] 11") : Lang::getText("[NOTIFICATIONS] 10"); const std::string MODE = Options::video.fullscreen ? Lang::getText("[NOTIFICATIONS] 11") : Lang::getText("[NOTIFICATIONS] 10");
Notifier::get()->show({MODE}); Notifier::get()->show({MODE});
@@ -281,7 +281,7 @@ auto checkInputs() -> bool {
} }
// Comprueba el teclado para decrementar el tamaño de la ventana // Comprueba el teclado para decrementar el tamaño de la ventana
if (Input::get()->checkInput(Input::Action::WINDOW_DEC_SIZE, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) { if (Input::get()->checkAction(Input::Action::WINDOW_DEC_SIZE, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) {
if (Screen::get()->decWindowSize()) { if (Screen::get()->decWindowSize()) {
Notifier::get()->show({Lang::getText("[NOTIFICATIONS] 09") + " x" + std::to_string(Options::window.zoom)}); Notifier::get()->show({Lang::getText("[NOTIFICATIONS] 09") + " x" + std::to_string(Options::window.zoom)});
} }
@@ -289,7 +289,7 @@ auto checkInputs() -> bool {
} }
// Comprueba el teclado para incrementar el tamaño de la ventana // Comprueba el teclado para incrementar el tamaño de la ventana
if (Input::get()->checkInput(Input::Action::WINDOW_INC_SIZE, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) { if (Input::get()->checkAction(Input::Action::WINDOW_INC_SIZE, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) {
if (Screen::get()->incWindowSize()) { if (Screen::get()->incWindowSize()) {
Notifier::get()->show({Lang::getText("[NOTIFICATIONS] 09") + " x" + std::to_string(Options::window.zoom)}); Notifier::get()->show({Lang::getText("[NOTIFICATIONS] 09") + " x" + std::to_string(Options::window.zoom)});
} }
@@ -297,7 +297,7 @@ auto checkInputs() -> bool {
} }
// Salir // Salir
if (Input::get()->checkInput(Input::Action::EXIT, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) { if (Input::get()->checkAction(Input::Action::EXIT, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) {
quit(); quit();
return true; return true;
} }
@@ -309,50 +309,50 @@ auto checkInputs() -> bool {
} }
// Reset // Reset
if (Input::get()->checkInput(Input::Action::RESET, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) { if (Input::get()->checkAction(Input::Action::RESET, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) {
reset(); reset();
return true; return true;
} }
// Audio // Audio
if (Input::get()->checkInput(Input::Action::TOGGLE_AUDIO, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) { if (Input::get()->checkAction(Input::Action::TOGGLE_AUDIO, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) {
toggleAudio(); toggleAudio();
return true; return true;
} }
// Autofire // Autofire
if (Input::get()->checkInput(Input::Action::TOGGLE_AUTO_FIRE, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) { if (Input::get()->checkAction(Input::Action::TOGGLE_AUTO_FIRE, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) {
toggleFireMode(); toggleFireMode();
return true; return true;
} }
// Idioma // Idioma
if (Input::get()->checkInput(Input::Action::CHANGE_LANG, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) { if (Input::get()->checkAction(Input::Action::CHANGE_LANG, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) {
changeLang(); changeLang();
return true; return true;
} }
// Shaders // Shaders
if (Input::get()->checkInput(Input::Action::TOGGLE_VIDEO_SHADERS, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) { if (Input::get()->checkAction(Input::Action::TOGGLE_VIDEO_SHADERS, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) {
toggleShaders(); toggleShaders();
return true; return true;
} }
// Integer Scale // Integer Scale
if (Input::get()->checkInput(Input::Action::TOGGLE_VIDEO_INTEGER_SCALE, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) { if (Input::get()->checkAction(Input::Action::TOGGLE_VIDEO_INTEGER_SCALE, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) {
toggleIntegerScale(); toggleIntegerScale();
return true; return true;
} }
// VSync // VSync
if (Input::get()->checkInput(Input::Action::TOGGLE_VIDEO_VSYNC, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) { if (Input::get()->checkAction(Input::Action::TOGGLE_VIDEO_VSYNC, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) {
toggleVSync(); toggleVSync();
return true; return true;
} }
#ifdef _DEBUG #ifdef _DEBUG
// Debug info // Debug info
if (Input::get()->checkInput(Input::Action::SHOW_INFO, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) { if (Input::get()->checkAction(Input::Action::SHOW_INFO, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) {
Screen::get()->toggleDebugInfo(); Screen::get()->toggleDebugInfo();
return true; return true;
} }

View File

@@ -5,6 +5,7 @@
#include <algorithm> // Para find #include <algorithm> // Para find
#include <cstddef> // Para size_t #include <cstddef> // Para size_t
#include <iterator> // Para distance #include <iterator> // Para distance
#include <memory> // Para std::unique_ptr
#include <unordered_map> // Para unordered_map, _Node_const_iterator, operat... #include <unordered_map> // Para unordered_map, _Node_const_iterator, operat...
#include <utility> // Para pair #include <utility> // Para pair
@@ -54,7 +55,7 @@ void Input::bindGameControllerButton(int controller_index, Action input_target,
} }
// Comprueba si un input esta activo // Comprueba si un input esta activo
auto Input::checkInput(Action input, bool repeat, Device device, int controller_index) -> bool { auto Input::checkAction(Action input, bool repeat, Device device, int controller_index) -> bool {
bool success_keyboard = false; bool success_keyboard = false;
bool success_controller = false; bool success_controller = false;
const int INPUT_INDEX = static_cast<int>(input); const int INPUT_INDEX = static_cast<int>(input);
@@ -123,13 +124,13 @@ auto Input::checkAnyButton(bool repeat) -> int {
// Solo comprueba los botones definidos previamente // Solo comprueba los botones definidos previamente
for (auto bi : button_inputs_) { for (auto bi : button_inputs_) {
// Comprueba el teclado // Comprueba el teclado
if (checkInput(bi, repeat, Device::KEYBOARD)) { if (checkAction(bi, repeat, Device::KEYBOARD)) {
return 1; return 1;
} }
// Comprueba los mandos // Comprueba los mandos
for (int i = 0; i < num_gamepads_; ++i) { for (int i = 0; i < num_gamepads_; ++i) {
if (checkInput(bi, repeat, Device::CONTROLLER, i)) { if (checkAction(bi, repeat, Device::CONTROLLER, i)) {
return i + 1; return i + 1;
} }
} }
@@ -139,7 +140,7 @@ auto Input::checkAnyButton(bool repeat) -> int {
} }
// Busca si hay mandos conectados // Busca si hay mandos conectados
auto Input::discoverGameControllers() -> bool { /*auto Input::discoverGameControllers() -> bool {
bool found = false; bool found = false;
if (SDL_AddGamepadMappingsFromFile(game_controller_db_path_.c_str()) < 0) { if (SDL_AddGamepadMappingsFromFile(game_controller_db_path_.c_str()) < 0) {
@@ -204,7 +205,7 @@ auto Input::discoverGameControllers() -> bool {
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n>> FINISHED LOOKING FOR GAME CONTROLLERS"); SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n>> FINISHED LOOKING FOR GAME CONTROLLERS");
return found; return found;
} }*/
// Comprueba si hay algun mando conectado // Comprueba si hay algun mando conectado
auto Input::gameControllerFound() const -> bool { return num_gamepads_ > 0; } auto Input::gameControllerFound() const -> bool { return num_gamepads_ > 0; }
@@ -335,9 +336,10 @@ void Input::initSDLGamePad() {
if (!SDL_InitSubSystem(SDL_INIT_GAMEPAD)) { if (!SDL_InitSubSystem(SDL_INIT_GAMEPAD)) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_GAMEPAD could not initialize! SDL Error: %s", SDL_GetError()); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_GAMEPAD could not initialize! SDL Error: %s", SDL_GetError());
} else { } else {
SDL_LogInfo(SDL_LOG_CATEGORY_TEST, "\n** SDL_GAMEPAD: INITIALIZING"); //SDL_LogInfo(SDL_LOG_CATEGORY_TEST, "\n** SDL_GAMEPAD: INITIALIZING");
discoverGameControllers(); //discoverGameControllers();
SDL_LogInfo(SDL_LOG_CATEGORY_TEST, "** SDL_GAMEPAD: INITIALIZATION COMPLETE\n"); //printConnectedGamepads();
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "** Input System initialized successfully\n");
} }
} }
} }
@@ -383,21 +385,50 @@ void Input::update() {
void Input::handleEvent(const SDL_Event &event) { void Input::handleEvent(const SDL_Event &event) {
switch (event.type) { switch (event.type) {
case SDL_EVENT_GAMEPAD_ADDED: { case SDL_EVENT_GAMEPAD_ADDED:
printf("¡Mando conectado! ID: %d\n", event.gdevice.which); add_gamepad(event.gdevice.which);
SDL_Gamepad *gamepad = SDL_OpenGamepad(event.gdevice.which);
if (gamepad) {
printf("Gamepad abierto correctamente.\n");
} else {
printf("Error al abrir el gamepad: %s\n", SDL_GetError());
}
break; break;
} case SDL_EVENT_GAMEPAD_REMOVED:
case SDL_EVENT_GAMEPAD_REMOVED: { remove_gamepad(event.gdevice.which);
printf("¡Mando desconectado! Instance ID: %d\n", event.gdevice.which);
// Aquí puedes cerrar el gamepad si lo tenías abierto
// SDL_CloseGamepad(gamepad); ← si tienes el puntero guardado
break; break;
} }
}
void Input::add_gamepad(int device_index) {
SDL_Gamepad *pad = SDL_OpenGamepad(device_index);
if (!pad) {
std::cerr << "Error al abrir el gamepad: " << SDL_GetError() << "\n";
return;
}
auto gamepad = std::make_unique<Gamepad>(pad);
std::cout << "Gamepad conectado (ID " << gamepad->instance_id << ")\n";
gamepads.push_back(std::move(gamepad));
}
void Input::remove_gamepad(SDL_JoystickID id) {
auto it = std::remove_if(gamepads.begin(), gamepads.end(), [id](const std::unique_ptr<Gamepad> &gamepad) {
return gamepad->instance_id == id;
});
if (it != gamepads.end()) {
std::cout << "Gamepad desconectado (ID " << id << ")\n";
gamepads.erase(it, gamepads.end());
} else {
std::cerr << "No se encontró el gamepad con ID " << id << "\n";
}
}
void Input::printConnectedGamepads() const {
if (gamepads.empty()) {
std::cout << "No hay gamepads conectados.\n";
return;
}
std::cout << "Gamepads conectados:\n";
for (const auto& gamepad : gamepads) {
const char* name = SDL_GetGamepadName(gamepad->pad);
std::cout << " - ID: " << gamepad->instance_id
<< ", Nombre: " << (name ? name : "Desconocido") << "\n";
} }
} }

View File

@@ -2,6 +2,8 @@
#include <SDL3/SDL.h> // Para SDL_GamepadButton, Uint8, SDL_Gamepad, SDL_Joystick, SDL_JoystickID, SDL_Scancode, Sint16 #include <SDL3/SDL.h> // Para SDL_GamepadButton, Uint8, SDL_Gamepad, SDL_Joystick, SDL_JoystickID, SDL_Scancode, Sint16
#include <iostream>
#include <memory> // Para std::unique_ptr
#include <string> // Para basic_string, string #include <string> // Para basic_string, string
#include <vector> // Para vector #include <vector> // Para vector
@@ -81,13 +83,14 @@ class Input {
void bindGameControllerButton(int controller_index, Action input_target, Action input_source); // Asigna inputs a otros inputs del mando void bindGameControllerButton(int controller_index, Action input_target, Action input_source); // Asigna inputs a otros inputs del mando
// --- Métodos de consulta de entrada --- // --- Métodos de consulta de entrada ---
void update(); // Comprueba fisicamente los botones y teclas que se han pulsado void update(); // Comprueba fisicamente los botones y teclas que se han pulsado
auto checkInput(Action input, bool repeat = true, Device device = Device::ANY, int controller_index = 0) -> bool; // Comprueba si un input está activo auto checkAction(Action input, bool repeat = true, Device device = Device::ANY, int controller_index = 0) -> bool; // Comprueba si un input está activo
auto checkAnyInput(Device device = Device::ANY, int controller_index = 0) -> bool; // Comprueba si hay al menos un input activo auto checkAnyInput(Device device = Device::ANY, int controller_index = 0) -> bool; // Comprueba si hay al menos un input activo
auto checkAnyButton(bool repeat = DO_NOT_ALLOW_REPEAT) -> int; // Comprueba si hay algún botón pulsado auto checkAnyButton(bool repeat = DO_NOT_ALLOW_REPEAT) -> int; // Comprueba si hay algún botón pulsado
// --- Métodos de gestión de mandos --- // --- Métodos de gestión de mandos ---
auto discoverGameControllers() -> bool; // Busca si hay mandos conectados //auto discoverGameControllers() -> bool; // Busca si hay mandos conectados
//void discoverGameControllers();
[[nodiscard]] auto gameControllerFound() const -> bool; // Comprueba si hay algún mando conectado [[nodiscard]] auto gameControllerFound() const -> bool; // Comprueba si hay algún mando conectado
[[nodiscard]] auto getNumControllers() const -> int; // Obtiene el número de mandos conectados [[nodiscard]] auto getNumControllers() const -> int; // Obtiene el número de mandos conectados
[[nodiscard]] auto getControllerName(int controller_index) const -> std::string; // Obtiene el nombre de un mando de juego [[nodiscard]] auto getControllerName(int controller_index) const -> std::string; // Obtiene el nombre de un mando de juego
@@ -106,6 +109,9 @@ class Input {
// --- Eventos --- // --- Eventos ---
void handleEvent(const SDL_Event &event); // Comprueba si se conecta algun mando void handleEvent(const SDL_Event &event); // Comprueba si se conecta algun mando
void printConnectedGamepads() const;
private: private:
// --- Estructuras internas --- // --- Estructuras internas ---
struct KeyBindings { struct KeyBindings {
@@ -127,6 +133,21 @@ class Input {
: button(btn), is_held(is_held), just_pressed(just_pressed), axis_active(axis_act) {} : button(btn), is_held(is_held), just_pressed(just_pressed), axis_active(axis_act) {}
}; };
struct Gamepad {
SDL_Gamepad *pad;
SDL_JoystickID instance_id;
Gamepad(SDL_Gamepad *p)
: pad(p), instance_id(SDL_GetJoystickID(SDL_GetGamepadJoystick(p))) {}
~Gamepad() {
if (pad) {
SDL_CloseGamepad(pad);
std::cout << "Gamepad cerrado (ID " << instance_id << ")\n";
}
}
};
// --- Constantes --- // --- Constantes ---
static constexpr Sint16 AXIS_THRESHOLD = 30000; static constexpr Sint16 AXIS_THRESHOLD = 30000;
@@ -140,10 +161,13 @@ class Input {
int num_joysticks_ = 0; // Número de joysticks conectados int num_joysticks_ = 0; // Número de joysticks conectados
int num_gamepads_ = 0; // Número de mandos conectados int num_gamepads_ = 0; // Número de mandos conectados
std::string game_controller_db_path_; // Ruta al archivo gamecontrollerdb.txt std::string game_controller_db_path_; // Ruta al archivo gamecontrollerdb.txt
std::vector<std::unique_ptr<Gamepad>> gamepads;
// --- Métodos internos --- // --- Métodos internos ---
void initSDLGamePad(); // Inicializa SDL para la gestión de mandos void initSDLGamePad(); // Inicializa SDL para la gestión de mandos
auto checkAxisInput(Action input, int controller_index, bool repeat) -> bool; // Comprueba el eje del mando auto checkAxisInput(Action input, int controller_index, bool repeat) -> bool; // Comprueba el eje del mando
void add_gamepad(int device_index);
void remove_gamepad(SDL_JoystickID id);
// --- Constructor y destructor --- // --- Constructor y destructor ---
explicit Input(std::string game_controller_db_path); // Constructor privado explicit Input(std::string game_controller_db_path); // Constructor privado

View File

@@ -1244,14 +1244,14 @@ void Game::checkInput() {
void Game::checkPauseInput() { void Game::checkPauseInput() {
// Comprueba los mandos // Comprueba los mandos
for (int i = 0; i < input_->getNumControllers(); ++i) { for (int i = 0; i < input_->getNumControllers(); ++i) {
if (input_->checkInput(Input::Action::PAUSE, Input::DO_NOT_ALLOW_REPEAT, Input::Device::CONTROLLER, i)) { if (input_->checkAction(Input::Action::PAUSE, Input::DO_NOT_ALLOW_REPEAT, Input::Device::CONTROLLER, i)) {
pause(!paused_); pause(!paused_);
return; return;
} }
} }
// Comprueba el teclado // Comprueba el teclado
if (input_->checkInput(Input::Action::PAUSE, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) { if (input_->checkAction(Input::Action::PAUSE, Input::DO_NOT_ALLOW_REPEAT, Input::Device::KEYBOARD)) {
pause(!paused_); pause(!paused_);
return; return;
} }
@@ -1362,12 +1362,12 @@ void Game::handlePlayersInput() {
void Game::handleNormalPlayerInput(const std::shared_ptr<Player> &player) { void Game::handleNormalPlayerInput(const std::shared_ptr<Player> &player) {
const auto &controller = Options::controllers.at(player->getController()); const auto &controller = Options::controllers.at(player->getController());
if (input_->checkInput(Input::Action::LEFT, Input::ALLOW_REPEAT, controller.type, controller.index)) { if (input_->checkAction(Input::Action::LEFT, Input::ALLOW_REPEAT, controller.type, controller.index)) {
player->setInput(Input::Action::LEFT); player->setInput(Input::Action::LEFT);
#ifdef RECORDING #ifdef RECORDING
demo_.keys.left = 1; demo_.keys.left = 1;
#endif #endif
} else if (input_->checkInput(Input::Action::RIGHT, Input::ALLOW_REPEAT, controller.type, controller.index)) { } else if (input_->checkAction(Input::Action::RIGHT, Input::ALLOW_REPEAT, controller.type, controller.index)) {
player->setInput(Input::Action::RIGHT); player->setInput(Input::Action::RIGHT);
#ifdef RECORDING #ifdef RECORDING
demo_.keys.right = 1; demo_.keys.right = 1;
@@ -1386,17 +1386,17 @@ void Game::handleNormalPlayerInput(const std::shared_ptr<Player> &player) {
// Procesa las entradas de disparo del jugador, permitiendo disparos automáticos si está habilitado. // Procesa las entradas de disparo del jugador, permitiendo disparos automáticos si está habilitado.
void Game::handleFireInputs(const std::shared_ptr<Player> &player, bool autofire, int controller_index) { void Game::handleFireInputs(const std::shared_ptr<Player> &player, bool autofire, int controller_index) {
const auto CONTROLLER = Options::controllers.at(player->getController()); const auto CONTROLLER = Options::controllers.at(player->getController());
if (input_->checkInput(Input::Action::FIRE_CENTER, autofire, CONTROLLER.type, CONTROLLER.index)) { if (input_->checkAction(Input::Action::FIRE_CENTER, autofire, CONTROLLER.type, CONTROLLER.index)) {
handleFireInput(player, BulletType::UP); handleFireInput(player, BulletType::UP);
#ifdef RECORDING #ifdef RECORDING
demo_.keys.fire = 1; demo_.keys.fire = 1;
#endif #endif
} else if (input_->checkInput(Input::Action::FIRE_LEFT, autofire, CONTROLLER.type, CONTROLLER.index)) { } else if (input_->checkAction(Input::Action::FIRE_LEFT, autofire, CONTROLLER.type, CONTROLLER.index)) {
handleFireInput(player, BulletType::LEFT); handleFireInput(player, BulletType::LEFT);
#ifdef RECORDING #ifdef RECORDING
demo_.keys.fire_left = 1; demo_.keys.fire_left = 1;
#endif #endif
} else if (input_->checkInput(Input::Action::FIRE_RIGHT, autofire, CONTROLLER.type, CONTROLLER.index)) { } else if (input_->checkAction(Input::Action::FIRE_RIGHT, autofire, CONTROLLER.type, CONTROLLER.index)) {
handleFireInput(player, BulletType::RIGHT); handleFireInput(player, BulletType::RIGHT);
#ifdef RECORDING #ifdef RECORDING
demo_.keys.fire_right = 1; demo_.keys.fire_right = 1;
@@ -1407,16 +1407,16 @@ void Game::handleFireInputs(const std::shared_ptr<Player> &player, bool autofire
// Maneja la continuación del jugador cuando no está jugando, permitiendo que continúe si se pulsa el botón de inicio. // Maneja la continuación del jugador cuando no está jugando, permitiendo que continúe si se pulsa el botón de inicio.
void Game::handlePlayerContinueInput(const std::shared_ptr<Player> &player) { void Game::handlePlayerContinueInput(const std::shared_ptr<Player> &player) {
const auto CONTROLLER = Options::controllers.at(player->getController()); const auto CONTROLLER = Options::controllers.at(player->getController());
if (input_->checkInput(Input::Action::START, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index)) { if (input_->checkAction(Input::Action::START, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index)) {
player->setPlayingState(Player::State::RESPAWNING); player->setPlayingState(Player::State::RESPAWNING);
player->addCredit(); player->addCredit();
sendPlayerToTheFront(player); sendPlayerToTheFront(player);
} }
// Disminuye el contador de continuación si se presiona cualquier botón de disparo. // Disminuye el contador de continuación si se presiona cualquier botón de disparo.
if (input_->checkInput(Input::Action::FIRE_LEFT, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index) || if (input_->checkAction(Input::Action::FIRE_LEFT, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index) ||
input_->checkInput(Input::Action::FIRE_CENTER, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index) || input_->checkAction(Input::Action::FIRE_CENTER, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index) ||
input_->checkInput(Input::Action::FIRE_RIGHT, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index)) { input_->checkAction(Input::Action::FIRE_RIGHT, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index)) {
if (player->getContinueCounter() < param.scoreboard.skip_countdown_value) { if (player->getContinueCounter() < param.scoreboard.skip_countdown_value) {
player->decContinueCounter(); player->decContinueCounter();
} }
@@ -1426,7 +1426,7 @@ void Game::handlePlayerContinueInput(const std::shared_ptr<Player> &player) {
// Maneja la continuación del jugador cuando no está jugando, permitiendo que continúe si se pulsa el botón de inicio. // Maneja la continuación del jugador cuando no está jugando, permitiendo que continúe si se pulsa el botón de inicio.
void Game::handlePlayerWaitingInput(const std::shared_ptr<Player> &player) { void Game::handlePlayerWaitingInput(const std::shared_ptr<Player> &player) {
const auto CONTROLLER = Options::controllers.at(player->getController()); const auto CONTROLLER = Options::controllers.at(player->getController());
if (input_->checkInput(Input::Action::START, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index)) { if (input_->checkAction(Input::Action::START, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index)) {
player->setPlayingState(Player::State::ENTERING_SCREEN); player->setPlayingState(Player::State::ENTERING_SCREEN);
player->addCredit(); player->addCredit();
sendPlayerToTheFront(player); sendPlayerToTheFront(player);
@@ -1436,7 +1436,7 @@ void Game::handlePlayerWaitingInput(const std::shared_ptr<Player> &player) {
// Procesa las entradas para la introducción del nombre del jugador. // Procesa las entradas para la introducción del nombre del jugador.
void Game::handleNameInput(const std::shared_ptr<Player> &player) { void Game::handleNameInput(const std::shared_ptr<Player> &player) {
const auto CONTROLLER = Options::controllers.at(player->getController()); const auto CONTROLLER = Options::controllers.at(player->getController());
if (input_->checkInput(Input::Action::FIRE_LEFT, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index)) { if (input_->checkAction(Input::Action::FIRE_LEFT, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index)) {
if (player->isShowingName()) { if (player->isShowingName()) {
player->setPlayingState(Player::State::CONTINUE); player->setPlayingState(Player::State::CONTINUE);
} else if (player->getEnterNamePositionOverflow()) { } else if (player->getEnterNamePositionOverflow()) {
@@ -1446,18 +1446,18 @@ void Game::handleNameInput(const std::shared_ptr<Player> &player) {
} else { } else {
player->setInput(Input::Action::RIGHT); player->setInput(Input::Action::RIGHT);
} }
} else if (input_->checkInput(Input::Action::FIRE_CENTER, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index) || } else if (input_->checkAction(Input::Action::FIRE_CENTER, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index) ||
input_->checkInput(Input::Action::FIRE_RIGHT, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index)) { input_->checkAction(Input::Action::FIRE_RIGHT, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index)) {
if (player->isShowingName()) { if (player->isShowingName()) {
player->setPlayingState(Player::State::CONTINUE); player->setPlayingState(Player::State::CONTINUE);
} else { } else {
player->setInput(Input::Action::LEFT); player->setInput(Input::Action::LEFT);
} }
} else if (input_->checkInput(Input::Action::UP, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index)) { } else if (input_->checkAction(Input::Action::UP, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index)) {
player->setInput(Input::Action::UP); player->setInput(Input::Action::UP);
} else if (input_->checkInput(Input::Action::DOWN, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index)) { } else if (input_->checkAction(Input::Action::DOWN, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index)) {
player->setInput(Input::Action::DOWN); player->setInput(Input::Action::DOWN);
} else if (input_->checkInput(Input::Action::START, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index)) { } else if (input_->checkAction(Input::Action::START, Input::DO_NOT_ALLOW_REPEAT, CONTROLLER.type, CONTROLLER.index)) {
if (player->isShowingName()) { if (player->isShowingName()) {
player->setPlayingState(Player::State::CONTINUE); player->setPlayingState(Player::State::CONTINUE);
} else { } else {

View File

@@ -270,7 +270,7 @@ void Title::processControllerInputs() {
} }
auto Title::isStartButtonPressed(const Options::GamepadOptions& controller) -> bool { auto Title::isStartButtonPressed(const Options::GamepadOptions& controller) -> bool {
return Input::get()->checkInput( return Input::get()->checkAction(
Input::Action::START, Input::Action::START,
Input::DO_NOT_ALLOW_REPEAT, Input::DO_NOT_ALLOW_REPEAT,
controller.type, controller.type,