forked from jaildesigner-jailgames/jaildoctors_dilemma
afegit soport per a axis del mando
This commit is contained in:
@@ -203,11 +203,8 @@ void Director::createSystemFolder(const std::string &folder)
|
||||
// Inicia las variables necesarias para arrancar el programa
|
||||
void Director::initInput()
|
||||
{
|
||||
// Establece si ha de mostrar mensajes
|
||||
Input::get()->setVerbose(options.console);
|
||||
|
||||
// Busca si hay un mando conectado
|
||||
Input::get()->discoverGameController();
|
||||
Input::get()->discoverGameControllers();
|
||||
|
||||
// Teclado - Movimiento
|
||||
if (options.keys == ControlScheme::CURSOR)
|
||||
@@ -250,24 +247,29 @@ void Director::initInput()
|
||||
Input::get()->bindKey(InputAction::TOGGLE_MUSIC, SDL_SCANCODE_M);
|
||||
Input::get()->bindKey(InputAction::TOGGLE_BORDER, SDL_SCANCODE_B);
|
||||
|
||||
// Mando - Movimiento
|
||||
Input::get()->bindGameControllerButton(InputAction::JUMP, SDL_CONTROLLER_BUTTON_B);
|
||||
Input::get()->bindGameControllerButton(InputAction::LEFT, SDL_CONTROLLER_BUTTON_DPAD_LEFT);
|
||||
Input::get()->bindGameControllerButton(InputAction::RIGHT, SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
|
||||
// MANDO
|
||||
const int NUM_GAMEPADS = Input::get()->getNumControllers();
|
||||
for (int i = 0; i < NUM_GAMEPADS; ++i)
|
||||
{
|
||||
// Movimiento
|
||||
Input::get()->bindGameControllerButton(i, InputAction::JUMP, SDL_CONTROLLER_BUTTON_B);
|
||||
Input::get()->bindGameControllerButton(i, InputAction::LEFT, SDL_CONTROLLER_BUTTON_DPAD_LEFT);
|
||||
Input::get()->bindGameControllerButton(i, InputAction::RIGHT, SDL_CONTROLLER_BUTTON_DPAD_RIGHT);
|
||||
|
||||
// Mando - Otros
|
||||
Input::get()->bindGameControllerButton(InputAction::ACCEPT, SDL_CONTROLLER_BUTTON_B);
|
||||
Input::get()->bindGameControllerButton(InputAction::CANCEL, SDL_CONTROLLER_BUTTON_A);
|
||||
// Otros
|
||||
Input::get()->bindGameControllerButton(i, InputAction::ACCEPT, SDL_CONTROLLER_BUTTON_B);
|
||||
Input::get()->bindGameControllerButton(i, InputAction::CANCEL, SDL_CONTROLLER_BUTTON_A);
|
||||
#ifdef GAME_CONSOLE
|
||||
Input::get()->bindGameControllerButton(InputAction::input_pause, SDL_CONTROLLER_BUTTON_BACK);
|
||||
Input::get()->bindGameControllerButton(InputAction::input_exit, SDL_CONTROLLER_BUTTON_START);
|
||||
Input::get()->bindGameControllerButton(i, InputAction::input_pause, SDL_CONTROLLER_BUTTON_BACK);
|
||||
Input::get()->bindGameControllerButton(i, InputAction::input_exit, SDL_CONTROLLER_BUTTON_START);
|
||||
#else
|
||||
Input::get()->bindGameControllerButton(InputAction::PAUSE, SDL_CONTROLLER_BUTTON_START);
|
||||
Input::get()->bindGameControllerButton(InputAction::EXIT, SDL_CONTROLLER_BUTTON_BACK);
|
||||
Input::get()->bindGameControllerButton(i, InputAction::PAUSE, SDL_CONTROLLER_BUTTON_START);
|
||||
Input::get()->bindGameControllerButton(i, InputAction::EXIT, SDL_CONTROLLER_BUTTON_BACK);
|
||||
#endif
|
||||
Input::get()->bindGameControllerButton(InputAction::NEXT_PALETTE, SDL_CONTROLLER_BUTTON_LEFTSHOULDER);
|
||||
Input::get()->bindGameControllerButton(InputAction::TOGGLE_MUSIC, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER);
|
||||
Input::get()->bindGameControllerButton(InputAction::TOGGLE_BORDER, SDL_CONTROLLER_BUTTON_X);
|
||||
Input::get()->bindGameControllerButton(i, InputAction::NEXT_PALETTE, SDL_CONTROLLER_BUTTON_LEFTSHOULDER);
|
||||
Input::get()->bindGameControllerButton(i, InputAction::TOGGLE_MUSIC, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER);
|
||||
Input::get()->bindGameControllerButton(i, InputAction::TOGGLE_BORDER, SDL_CONTROLLER_BUTTON_X);
|
||||
}
|
||||
}
|
||||
|
||||
// Inicializa JailAudio
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "defines.h" // Para BLOCK, PLAY_AREA_HEIGHT, BORDER_BOTTOM
|
||||
#include "global_events.h" // Para check
|
||||
#include "global_inputs.h" // Para check
|
||||
#include "input.h" // Para Input, InputAction, REPEAT_FALSE
|
||||
#include "input.h" // Para Input, InputAction, INPUT_DO_NOT_ALLOW_REPEAT
|
||||
#include "item_tracker.h" // Para ItemTracker
|
||||
#include "jail_audio.h" // Para JA_PauseMusic, JA_GetMusicState, JA_P...
|
||||
#include "notifier.h" // Para Notifier, NotificationText, CHEEVO_NO...
|
||||
@@ -82,14 +82,14 @@ void Game::checkEvents()
|
||||
// Comprueba el teclado
|
||||
void Game::checkInput()
|
||||
{
|
||||
if (Input::get()->checkInput(InputAction::TOGGLE_MUSIC, REPEAT_FALSE))
|
||||
if (Input::get()->checkInput(InputAction::TOGGLE_MUSIC, INPUT_DO_NOT_ALLOW_REPEAT))
|
||||
{
|
||||
board_->music = !board_->music;
|
||||
board_->music ? JA_ResumeMusic() : JA_PauseMusic();
|
||||
Notifier::get()->show({"MUSIC " + std::string(board_->music ? "ENABLED" : "DISABLED")}, NotificationText::CENTER);
|
||||
}
|
||||
|
||||
else if (Input::get()->checkInput(InputAction::PAUSE, REPEAT_FALSE))
|
||||
else if (Input::get()->checkInput(InputAction::PAUSE, INPUT_DO_NOT_ALLOW_REPEAT))
|
||||
{
|
||||
togglePause();
|
||||
Notifier::get()->show({std::string(paused_ ? "GAME PAUSED" : "GAME RUNNING")}, NotificationText::CENTER);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include <SDL2/SDL_stdinc.h> // Para SDL_FALSE, SDL_TRUE
|
||||
#include <string> // Para allocator, operator+, char_traits, string
|
||||
#include <vector> // Para vector
|
||||
#include "input.h" // Para Input, InputAction, REPEAT_FALSE
|
||||
#include "input.h" // Para Input, InputAction, INPUT_DO_NOT_ALLOW_REPEAT
|
||||
#include "notifier.h" // Para Notifier, NotificationText
|
||||
#include "options.h" // Para Options, options, OptionsVideo, Section
|
||||
#include "screen.h" // Para Screen
|
||||
@@ -51,29 +51,29 @@ namespace globalInputs
|
||||
// Comprueba los inputs que se pueden introducir en cualquier sección del juego
|
||||
void check()
|
||||
{
|
||||
if (Input::get()->checkInput(InputAction::EXIT, REPEAT_FALSE))
|
||||
if (Input::get()->checkInput(InputAction::EXIT, INPUT_DO_NOT_ALLOW_REPEAT))
|
||||
{
|
||||
quit();
|
||||
}
|
||||
|
||||
else if (Input::get()->checkInput(InputAction::ACCEPT, REPEAT_FALSE))
|
||||
else if (Input::get()->checkInput(InputAction::ACCEPT, INPUT_DO_NOT_ALLOW_REPEAT))
|
||||
{
|
||||
skip_section();
|
||||
}
|
||||
|
||||
else if (Input::get()->checkInput(InputAction::TOGGLE_BORDER, REPEAT_FALSE))
|
||||
else if (Input::get()->checkInput(InputAction::TOGGLE_BORDER, INPUT_DO_NOT_ALLOW_REPEAT))
|
||||
{
|
||||
Screen::get()->toggleBorder();
|
||||
Notifier::get()->show({"BORDER " + std::string(options.video.border.enabled ? "ENABLED" : "DISABLED")}, NotificationText::CENTER);
|
||||
}
|
||||
|
||||
else if (Input::get()->checkInput(InputAction::TOGGLE_VIDEOMODE, REPEAT_FALSE))
|
||||
else if (Input::get()->checkInput(InputAction::TOGGLE_VIDEOMODE, INPUT_DO_NOT_ALLOW_REPEAT))
|
||||
{
|
||||
Screen::get()->toggleVideoMode();
|
||||
Notifier::get()->show({"FULLSCREEN " + std::string(options.video.mode == 0 ? "DISABLED" : "ENABLED")}, NotificationText::CENTER);
|
||||
}
|
||||
|
||||
else if (Input::get()->checkInput(InputAction::WINDOW_DEC_ZOOM, REPEAT_FALSE))
|
||||
else if (Input::get()->checkInput(InputAction::WINDOW_DEC_ZOOM, INPUT_DO_NOT_ALLOW_REPEAT))
|
||||
{
|
||||
if (Screen::get()->decWindowZoom())
|
||||
{
|
||||
@@ -81,7 +81,7 @@ namespace globalInputs
|
||||
}
|
||||
}
|
||||
|
||||
else if (Input::get()->checkInput(InputAction::WINDOW_INC_ZOOM, REPEAT_FALSE))
|
||||
else if (Input::get()->checkInput(InputAction::WINDOW_INC_ZOOM, INPUT_DO_NOT_ALLOW_REPEAT))
|
||||
{
|
||||
if (Screen::get()->incWindowZoom())
|
||||
{
|
||||
@@ -89,25 +89,25 @@ namespace globalInputs
|
||||
}
|
||||
}
|
||||
|
||||
else if (Input::get()->checkInput(InputAction::TOGGLE_SHADERS, REPEAT_FALSE))
|
||||
else if (Input::get()->checkInput(InputAction::TOGGLE_SHADERS, INPUT_DO_NOT_ALLOW_REPEAT))
|
||||
{
|
||||
Screen::get()->toggleShaders();
|
||||
Notifier::get()->show({"SHADERS " + std::string(options.video.shaders ? "ENABLED" : "DISABLED")}, NotificationText::CENTER);
|
||||
}
|
||||
|
||||
else if (Input::get()->checkInput(InputAction::NEXT_PALETTE, REPEAT_FALSE))
|
||||
else if (Input::get()->checkInput(InputAction::NEXT_PALETTE, INPUT_DO_NOT_ALLOW_REPEAT))
|
||||
{
|
||||
Screen::get()->nextPalette();
|
||||
Notifier::get()->show({"PALETTE " + options.video.palette}, NotificationText::CENTER);
|
||||
}
|
||||
|
||||
else if (Input::get()->checkInput(InputAction::PREVIOUS_PALETTE, REPEAT_FALSE))
|
||||
else if (Input::get()->checkInput(InputAction::PREVIOUS_PALETTE, INPUT_DO_NOT_ALLOW_REPEAT))
|
||||
{
|
||||
Screen::get()->previousPalette();
|
||||
Notifier::get()->show({"PALETTE " + options.video.palette}, NotificationText::CENTER);
|
||||
}
|
||||
|
||||
else if (Input::get()->checkInput(InputAction::TOGGLE_INTEGER_SCALE, REPEAT_FALSE))
|
||||
else if (Input::get()->checkInput(InputAction::TOGGLE_INTEGER_SCALE, INPUT_DO_NOT_ALLOW_REPEAT))
|
||||
{
|
||||
options.video.integer_scale = !options.video.integer_scale;
|
||||
SDL_RenderSetIntegerScale(Screen::get()->getRenderer(), options.video.integer_scale ? SDL_TRUE : SDL_FALSE);
|
||||
|
||||
319
source/input.cpp
319
source/input.cpp
@@ -2,9 +2,12 @@
|
||||
#include <SDL2/SDL.h> // Para SDL_INIT_GAMECONTROLLER, SDL_InitSubS...
|
||||
#include <SDL2/SDL_error.h> // Para SDL_GetError
|
||||
#include <SDL2/SDL_events.h> // Para SDL_ENABLE
|
||||
#include <SDL2/SDL_joystick.h> // Para SDL_NumJoysticks
|
||||
#include <SDL2/SDL_keyboard.h> // Para SDL_GetKeyboardState
|
||||
#include <iostream> // Para basic_ostream, operator<<, cout, basi...
|
||||
#include <algorithm> // Para find
|
||||
#include <iostream> // Para basic_ostream, operator<<, cout, endl
|
||||
#include <iterator> // Para distance
|
||||
#include <unordered_map> // Para unordered_map, operator==, _Node_cons...
|
||||
#include <utility> // Para pair
|
||||
|
||||
// [SINGLETON]
|
||||
Input *Input::input_ = nullptr;
|
||||
@@ -29,18 +32,17 @@ Input *Input::get()
|
||||
|
||||
// Constructor
|
||||
Input::Input(const std::string &game_controller_db_path)
|
||||
: db_path_(game_controller_db_path)
|
||||
: game_controller_db_path_(game_controller_db_path)
|
||||
{
|
||||
// Inicializa las variables
|
||||
KeyBindings kb;
|
||||
kb.scancode = 0;
|
||||
kb.active = false;
|
||||
key_bindings_.resize(static_cast<int>(InputAction::SIZE), kb);
|
||||
// Busca si hay mandos conectados
|
||||
discoverGameControllers();
|
||||
|
||||
GameControllerBindings gcb;
|
||||
gcb.button = SDL_CONTROLLER_BUTTON_INVALID;
|
||||
gcb.active = false;
|
||||
game_controller_bindings_.resize(static_cast<int>(InputAction::SIZE), gcb);
|
||||
// Inicializa los vectores
|
||||
key_bindings_.resize(static_cast<int>(InputAction::SIZE), KeyBindings());
|
||||
controller_bindings_.resize(num_gamepads_, std::vector<ControllerBindings>(static_cast<int>(InputAction::SIZE), ControllerBindings()));
|
||||
|
||||
// Listado de los inputs para jugar que utilizan botones, ni palancas ni crucetas
|
||||
button_inputs_ = {InputAction::JUMP};
|
||||
}
|
||||
|
||||
// Asigna inputs a teclas
|
||||
@@ -50,133 +52,117 @@ void Input::bindKey(InputAction input, SDL_Scancode code)
|
||||
}
|
||||
|
||||
// Asigna inputs a botones del mando
|
||||
void Input::bindGameControllerButton(InputAction input, SDL_GameControllerButton button)
|
||||
void Input::bindGameControllerButton(int controller_index, InputAction input, SDL_GameControllerButton button)
|
||||
{
|
||||
game_controller_bindings_.at(static_cast<int>(input)).button = button;
|
||||
if (controller_index < num_gamepads_)
|
||||
{
|
||||
controller_bindings_.at(controller_index).at(static_cast<int>(input)).button = button;
|
||||
}
|
||||
}
|
||||
|
||||
// Asigna inputs a botones del mando
|
||||
void Input::bindGameControllerButton(int controller_index, InputAction input_target, InputAction input_source)
|
||||
{
|
||||
if (controller_index < num_gamepads_)
|
||||
{
|
||||
controller_bindings_.at(controller_index).at(static_cast<int>(input_target)).button = controller_bindings_.at(controller_index).at(static_cast<int>(input_source)).button;
|
||||
}
|
||||
}
|
||||
|
||||
// Comprueba si un input esta activo
|
||||
bool Input::checkInput(InputAction input, bool repeat, int device, int index)
|
||||
bool Input::checkInput(InputAction input, bool repeat, InputDeviceToUse device, int controller_index)
|
||||
{
|
||||
if (!enabled_)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool success_keyboard = false;
|
||||
bool success_controller = false;
|
||||
const int input_index = static_cast<int>(input);
|
||||
|
||||
bool successKeyboard = false;
|
||||
bool successGameController = false;
|
||||
|
||||
if (device == INPUT_USE_ANY)
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
|
||||
if (device == INPUT_USE_KEYBOARD || device == INPUT_USE_ANY)
|
||||
if (device == InputDeviceToUse::KEYBOARD || device == InputDeviceToUse::ANY)
|
||||
{
|
||||
const Uint8 *keyStates = SDL_GetKeyboardState(nullptr);
|
||||
|
||||
if (repeat)
|
||||
{
|
||||
if (keyStates[key_bindings_.at(static_cast<int>(input)).scancode] != 0)
|
||||
{
|
||||
successKeyboard = true;
|
||||
success_keyboard = keyStates[key_bindings_[input_index].scancode] != 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
successKeyboard = false;
|
||||
if (!key_bindings_[input_index].active)
|
||||
{
|
||||
if (keyStates[key_bindings_[input_index].scancode] != 0)
|
||||
{
|
||||
key_bindings_[input_index].active = true;
|
||||
success_keyboard = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
success_keyboard = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!key_bindings_.at(static_cast<int>(input)).active)
|
||||
if (keyStates[key_bindings_[input_index].scancode] == 0)
|
||||
{
|
||||
if (keyStates[key_bindings_.at(static_cast<int>(input)).scancode] != 0)
|
||||
{
|
||||
key_bindings_.at(static_cast<int>(input)).active = true;
|
||||
successKeyboard = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
successKeyboard = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (keyStates[key_bindings_.at(static_cast<int>(input)).scancode] == 0)
|
||||
{
|
||||
key_bindings_.at(static_cast<int>(input)).active = false;
|
||||
successKeyboard = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
successKeyboard = false;
|
||||
key_bindings_[input_index].active = false;
|
||||
}
|
||||
success_keyboard = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gameControllerFound())
|
||||
if ((device == INPUT_USE_GAMECONTROLLER) || (device == INPUT_USE_ANY))
|
||||
if (gameControllerFound() && controller_index >= 0 && controller_index < num_gamepads_)
|
||||
{
|
||||
if ((device == InputDeviceToUse::CONTROLLER) || (device == InputDeviceToUse::ANY))
|
||||
{
|
||||
success_controller = checkAxisInput(input, controller_index, repeat);
|
||||
|
||||
if (!success_controller)
|
||||
{
|
||||
if (repeat)
|
||||
{
|
||||
if (SDL_GameControllerGetButton(connected_controllers_.at(index), game_controller_bindings_.at(static_cast<int>(input)).button) != 0)
|
||||
{
|
||||
successGameController = true;
|
||||
success_controller = SDL_GameControllerGetButton(connected_controllers_.at(controller_index), controller_bindings_.at(controller_index).at(input_index).button) != 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
successGameController = false;
|
||||
if (!controller_bindings_.at(controller_index).at(input_index).active)
|
||||
{
|
||||
if (SDL_GameControllerGetButton(connected_controllers_.at(controller_index), controller_bindings_.at(controller_index).at(input_index).button) != 0)
|
||||
{
|
||||
controller_bindings_.at(controller_index).at(input_index).active = true;
|
||||
success_controller = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
success_controller = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!game_controller_bindings_.at(static_cast<int>(input)).active)
|
||||
if (SDL_GameControllerGetButton(connected_controllers_.at(controller_index), controller_bindings_.at(controller_index).at(input_index).button) == 0)
|
||||
{
|
||||
if (SDL_GameControllerGetButton(connected_controllers_.at(index), game_controller_bindings_.at(static_cast<int>(input)).button) != 0)
|
||||
{
|
||||
game_controller_bindings_.at(static_cast<int>(input)).active = true;
|
||||
successGameController = true;
|
||||
controller_bindings_.at(controller_index).at(input_index).active = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
successGameController = false;
|
||||
success_controller = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SDL_GameControllerGetButton(connected_controllers_.at(index), game_controller_bindings_.at(static_cast<int>(input)).button) == 0)
|
||||
{
|
||||
game_controller_bindings_.at(static_cast<int>(input)).active = false;
|
||||
successGameController = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
successGameController = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (successKeyboard || successGameController);
|
||||
return (success_keyboard || success_controller);
|
||||
}
|
||||
|
||||
// Comprueba si hay almenos un input activo
|
||||
bool Input::checkAnyInput(int device, int index)
|
||||
bool Input::checkAnyInput(InputDeviceToUse device, int controller_index)
|
||||
{
|
||||
if (device == INPUT_USE_ANY)
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
|
||||
if (device == INPUT_USE_KEYBOARD || device == INPUT_USE_ANY)
|
||||
if (device == InputDeviceToUse::KEYBOARD || device == InputDeviceToUse::ANY)
|
||||
{
|
||||
const Uint8 *mKeystates = SDL_GetKeyboardState(nullptr);
|
||||
|
||||
for (int i = 0; i < (int)key_bindings_.size(); ++i)
|
||||
{
|
||||
if (mKeystates[key_bindings_[i].scancode] != 0)
|
||||
if (mKeystates[key_bindings_[i].scancode] != 0 && !key_bindings_[i].active)
|
||||
{
|
||||
key_bindings_[i].active = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -184,12 +170,13 @@ bool Input::checkAnyInput(int device, int index)
|
||||
|
||||
if (gameControllerFound())
|
||||
{
|
||||
if (device == INPUT_USE_GAMECONTROLLER || device == INPUT_USE_ANY)
|
||||
if (device == InputDeviceToUse::CONTROLLER || device == InputDeviceToUse::ANY)
|
||||
{
|
||||
for (int i = 0; i < (int)game_controller_bindings_.size(); ++i)
|
||||
for (int i = 0; i < (int)controller_bindings_.size(); ++i)
|
||||
{
|
||||
if (SDL_GameControllerGetButton(connected_controllers_.at(index), game_controller_bindings_[i].button) != 0)
|
||||
if (SDL_GameControllerGetButton(connected_controllers_[controller_index], controller_bindings_[controller_index][i].button) != 0 && !controller_bindings_[controller_index][i].active)
|
||||
{
|
||||
controller_bindings_[controller_index][i].active = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -199,8 +186,8 @@ bool Input::checkAnyInput(int device, int index)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Busca si hay un mando conectado
|
||||
bool Input::discoverGameController()
|
||||
// Busca si hay mandos conectados
|
||||
bool Input::discoverGameControllers()
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
@@ -209,30 +196,35 @@ bool Input::discoverGameController()
|
||||
SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER);
|
||||
}
|
||||
|
||||
if (SDL_GameControllerAddMappingsFromFile(db_path_.c_str()) < 0)
|
||||
if (SDL_GameControllerAddMappingsFromFile(game_controller_db_path_.c_str()) < 0)
|
||||
{
|
||||
if (verbose_)
|
||||
{
|
||||
std::cout << "Error, could not load " << db_path_.c_str() << " file: " << SDL_GetError() << std::endl;
|
||||
}
|
||||
std::cout << "Error, could not load " << game_controller_db_path_.c_str() << " file: " << SDL_GetError() << std::endl;
|
||||
}
|
||||
|
||||
const int nJoysticks = SDL_NumJoysticks();
|
||||
num_joysticks_ = SDL_NumJoysticks();
|
||||
num_gamepads_ = 0;
|
||||
|
||||
// Cuenta el numero de mandos
|
||||
for (int i = 0; i < nJoysticks; ++i)
|
||||
// Cuenta el número de mandos
|
||||
joysticks_.clear();
|
||||
for (int i = 0; i < num_joysticks_; ++i)
|
||||
{
|
||||
auto joy = SDL_JoystickOpen(i);
|
||||
joysticks_.push_back(joy);
|
||||
if (SDL_IsGameController(i))
|
||||
{
|
||||
num_gamepads_++;
|
||||
}
|
||||
}
|
||||
|
||||
if (verbose_)
|
||||
std::cout << "\n** LOOKING FOR GAME CONTROLLERS" << std::endl;
|
||||
if (num_joysticks_ != num_gamepads_)
|
||||
{
|
||||
std::cout << "\nChecking for game controllers...\n";
|
||||
std::cout << nJoysticks << " joysticks found, " << num_gamepads_ << " are gamepads\n";
|
||||
std::cout << "Joysticks found: " << num_joysticks_ << std::endl;
|
||||
std::cout << "Gamepads found : " << num_gamepads_ << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Gamepads found: " << num_gamepads_ << std::endl;
|
||||
}
|
||||
|
||||
if (num_gamepads_ > 0)
|
||||
@@ -242,69 +234,110 @@ bool Input::discoverGameController()
|
||||
for (int i = 0; i < num_gamepads_; i++)
|
||||
{
|
||||
// Abre el mando y lo añade a la lista
|
||||
SDL_GameController *pad = SDL_GameControllerOpen(i);
|
||||
auto pad = SDL_GameControllerOpen(i);
|
||||
if (SDL_GameControllerGetAttached(pad) == 1)
|
||||
{
|
||||
connected_controllers_.push_back(pad);
|
||||
const std::string separator(" #");
|
||||
std::string name = SDL_GameControllerNameForIndex(i);
|
||||
name.resize(25);
|
||||
name = name + separator + std::to_string(i);
|
||||
if (verbose_)
|
||||
{
|
||||
std::cout << name << std::endl;
|
||||
}
|
||||
const std::string name = SDL_GameControllerNameForIndex(i);
|
||||
std::cout << "#" << i << ": " << name << std::endl;
|
||||
controller_names_.push_back(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (verbose_)
|
||||
{
|
||||
std::cout << "SDL_GetError() = " << SDL_GetError() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SDL_GameControllerEventState(SDL_ENABLE);
|
||||
}
|
||||
|
||||
std::cout << "\n** FINISHED LOOKING FOR GAME CONTROLLERS" << std::endl;
|
||||
return found;
|
||||
}
|
||||
|
||||
// Comprueba si hay algun mando conectado
|
||||
bool Input::gameControllerFound()
|
||||
bool Input::gameControllerFound() { return num_gamepads_ > 0 ? true : false; }
|
||||
|
||||
// Obten el nombre de un mando de juego
|
||||
std::string Input::getControllerName(int controller_index) const { return num_gamepads_ > 0 ? controller_names_.at(controller_index) : std::string(); }
|
||||
|
||||
// Obten el número de mandos conectados
|
||||
int Input::getNumControllers() const { return num_gamepads_; }
|
||||
|
||||
// Obtiene el indice del controlador a partir de un event.id
|
||||
int Input::getJoyIndex(int id) const
|
||||
{
|
||||
if (num_gamepads_ > 0)
|
||||
for (int i = 0; i < num_joysticks_; ++i)
|
||||
{
|
||||
return true;
|
||||
if (SDL_JoystickInstanceID(joysticks_[i]) == id)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Obtiene el SDL_GameControllerButton asignado a un input
|
||||
SDL_GameControllerButton Input::getControllerBinding(int controller_index, InputAction input) const
|
||||
{
|
||||
return controller_bindings_[controller_index][static_cast<int>(input)].button;
|
||||
}
|
||||
|
||||
// Obtiene el indice a partir del nombre del mando
|
||||
int Input::getIndexByName(const std::string &name) const
|
||||
{
|
||||
auto it = std::find(controller_names_.begin(), controller_names_.end(), name);
|
||||
return it != controller_names_.end() ? std::distance(controller_names_.begin(), it) : -1;
|
||||
}
|
||||
|
||||
// Comprueba el eje del mando
|
||||
bool Input::checkAxisInput(InputAction input, int controller_index, bool repeat)
|
||||
{
|
||||
// Umbral para considerar el eje como activo
|
||||
const Sint16 threshold = 30000;
|
||||
bool axis_active_now = false;
|
||||
|
||||
switch (input)
|
||||
{
|
||||
case InputAction::LEFT:
|
||||
axis_active_now = SDL_GameControllerGetAxis(connected_controllers_[controller_index], SDL_CONTROLLER_AXIS_LEFTX) < -threshold;
|
||||
break;
|
||||
case InputAction::RIGHT:
|
||||
axis_active_now = SDL_GameControllerGetAxis(connected_controllers_[controller_index], SDL_CONTROLLER_AXIS_LEFTX) > threshold;
|
||||
break;
|
||||
case InputAction::UP:
|
||||
axis_active_now = SDL_GameControllerGetAxis(connected_controllers_[controller_index], SDL_CONTROLLER_AXIS_LEFTY) < -threshold;
|
||||
break;
|
||||
case InputAction::DOWN:
|
||||
axis_active_now = SDL_GameControllerGetAxis(connected_controllers_[controller_index], SDL_CONTROLLER_AXIS_LEFTY) > threshold;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
// Referencia al binding correspondiente
|
||||
auto &binding = controller_bindings_.at(controller_index).at(static_cast<int>(input));
|
||||
|
||||
if (repeat)
|
||||
{
|
||||
// Si se permite repetir, simplemente devolvemos el estado actual
|
||||
return axis_active_now;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Si no se permite repetir, aplicamos la lógica de transición
|
||||
if (axis_active_now && !binding.axis_active)
|
||||
{
|
||||
// Transición de inactivo a activo
|
||||
binding.axis_active = true;
|
||||
return true;
|
||||
}
|
||||
else if (!axis_active_now && binding.axis_active)
|
||||
{
|
||||
// Transición de activo a inactivo
|
||||
binding.axis_active = false;
|
||||
}
|
||||
// Mantener el estado actual
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Obten el nombre de un mando de juego
|
||||
std::string Input::getControllerName(int index)
|
||||
{
|
||||
if (num_gamepads_ > 0)
|
||||
{
|
||||
return controller_names_[index];
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
// Obten el numero de mandos conectados
|
||||
int Input::getNumControllers()
|
||||
{
|
||||
return num_gamepads_;
|
||||
}
|
||||
|
||||
// Establece si ha de mostrar mensajes
|
||||
void Input::setVerbose(bool value)
|
||||
{
|
||||
verbose_ = value;
|
||||
}
|
||||
@@ -7,18 +7,20 @@
|
||||
#include <vector> // Para vector
|
||||
|
||||
// Definiciones de repetición
|
||||
constexpr bool REPEAT_TRUE = true;
|
||||
constexpr bool REPEAT_FALSE = false;
|
||||
constexpr bool INPUT_ALLOW_REPEAT = true;
|
||||
constexpr bool INPUT_DO_NOT_ALLOW_REPEAT = false;
|
||||
|
||||
// Tipos de entrada
|
||||
constexpr int INPUT_USE_KEYBOARD = 0;
|
||||
constexpr int INPUT_USE_GAMECONTROLLER = 1;
|
||||
constexpr int INPUT_USE_ANY = 2;
|
||||
enum class InputDeviceToUse : int
|
||||
{
|
||||
KEYBOARD = 0,
|
||||
CONTROLLER = 1,
|
||||
ANY = 2,
|
||||
};
|
||||
|
||||
enum class InputAction
|
||||
{
|
||||
// Inputs obligatorios
|
||||
NONE,
|
||||
UP,
|
||||
DOWN,
|
||||
LEFT,
|
||||
@@ -41,6 +43,7 @@ enum class InputAction
|
||||
TOGGLE_SHADERS,
|
||||
|
||||
// Input obligatorio
|
||||
NONE,
|
||||
SIZE
|
||||
};
|
||||
|
||||
@@ -54,25 +57,36 @@ private:
|
||||
{
|
||||
Uint8 scancode; // Scancode asociado
|
||||
bool active; // Indica si está activo
|
||||
|
||||
// Constructor
|
||||
explicit KeyBindings(Uint8 sc = 0, bool act = false)
|
||||
: scancode(sc), active(act) {}
|
||||
};
|
||||
|
||||
struct GameControllerBindings
|
||||
struct ControllerBindings
|
||||
{
|
||||
SDL_GameControllerButton button; // GameControllerButton asociado
|
||||
bool active; // Indica si está activo
|
||||
bool axis_active; // Estado del eje
|
||||
|
||||
// Constructor
|
||||
explicit ControllerBindings(SDL_GameControllerButton btn = SDL_CONTROLLER_BUTTON_INVALID, bool act = false, bool axis_act = false)
|
||||
: button(btn), active(act), axis_active(axis_act) {}
|
||||
};
|
||||
|
||||
// Objetos y punteros
|
||||
std::vector<SDL_GameController *> connected_controllers_; // Vector con todos los mandos conectados
|
||||
|
||||
// Variables
|
||||
std::vector<SDL_GameController *> connected_controllers_; // Vector con todos los mandos conectados
|
||||
std::vector<SDL_Joystick *> joysticks_; // Vector con todos los joysticks conectados
|
||||
std::vector<KeyBindings> key_bindings_; // Vector con las teclas asociadas a los inputs predefinidos
|
||||
std::vector<GameControllerBindings> game_controller_bindings_; // Vector con las teclas asociadas a los inputs predefinidos
|
||||
std::vector<std::vector<ControllerBindings>> controller_bindings_; // Vector con los botones asociadas a los inputs predefinidos para cada mando
|
||||
std::vector<std::string> controller_names_; // Vector con los nombres de los mandos
|
||||
int num_gamepads_ = 0; // Numero de mandos conectados
|
||||
std::string db_path_; // Ruta al archivo gamecontrollerdb.txt
|
||||
bool verbose_ = true; // Indica si ha de mostrar mensajes
|
||||
bool enabled_ = true; // Indica si está habilitado
|
||||
std::vector<InputAction> button_inputs_; // Inputs asignados al jugador y a botones, excluyendo direcciones
|
||||
int num_joysticks_ = 0; // Número de joysticks conectados
|
||||
int num_gamepads_ = 0; // Número de mandos conectados
|
||||
std::string game_controller_db_path_; // Ruta al archivo gamecontrollerdb.txt
|
||||
|
||||
// Comprueba el eje del mando
|
||||
bool checkAxisInput(InputAction input, int controller_index, bool repeat);
|
||||
|
||||
// Constructor
|
||||
explicit Input(const std::string &game_controller_db_path);
|
||||
@@ -94,26 +108,33 @@ public:
|
||||
void bindKey(InputAction input, SDL_Scancode code);
|
||||
|
||||
// Asigna inputs a botones del mando
|
||||
void bindGameControllerButton(InputAction input, SDL_GameControllerButton button);
|
||||
void bindGameControllerButton(int controller_index, InputAction input, SDL_GameControllerButton button);
|
||||
void bindGameControllerButton(int controller_index, InputAction inputTarget, InputAction inputSource);
|
||||
|
||||
// Comprueba si un input esta activo
|
||||
bool checkInput(InputAction input, bool repeat = true, int device = INPUT_USE_ANY, int index = 0);
|
||||
bool checkInput(InputAction input, bool repeat = true, InputDeviceToUse device = InputDeviceToUse::ANY, int controller_index = 0);
|
||||
|
||||
// Comprueba si hay almenos un input activo
|
||||
bool checkAnyInput(int device = INPUT_USE_ANY, int index = 0);
|
||||
bool checkAnyInput(InputDeviceToUse device = InputDeviceToUse::ANY, int controller_index = 0);
|
||||
|
||||
// Busca si hay un mando conectado
|
||||
bool discoverGameController();
|
||||
// Busca si hay mandos conectados
|
||||
bool discoverGameControllers();
|
||||
|
||||
// Comprueba si hay algun mando conectado
|
||||
bool gameControllerFound();
|
||||
|
||||
// Obten el numero de mandos conectados
|
||||
int getNumControllers();
|
||||
// Obten el número de mandos conectados
|
||||
int getNumControllers() const;
|
||||
|
||||
// Obten el nombre de un mando de juego
|
||||
std::string getControllerName(int index);
|
||||
std::string getControllerName(int controller_index) const;
|
||||
|
||||
// Establece si ha de mostrar mensajes
|
||||
void setVerbose(bool value);
|
||||
// Obtiene el indice del controlador a partir de un event.id
|
||||
int getJoyIndex(int id) const;
|
||||
|
||||
// Obtiene el SDL_GameControllerButton asignado a un input
|
||||
SDL_GameControllerButton getControllerBinding(int controller_index, InputAction input) const;
|
||||
|
||||
// Obtiene el indice a partir del nombre del mando
|
||||
int getIndexByName(const std::string &name) const;
|
||||
};
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "defines.h" // Para PLAY_AREA_CENTER_X, GAMECANVAS_WIDTH
|
||||
#include "global_events.h" // Para check
|
||||
#include "global_inputs.h" // Para check
|
||||
#include "input.h" // Para Input, InputAction, REPEAT_FALSE, REP...
|
||||
#include "input.h" // Para Input, InputAction, INPUT_DO_NOT_ALLOW_REPEAT, REP...
|
||||
#include "options.h" // Para Options, options, SectionState, Section
|
||||
#include "resource.h" // Para Resource
|
||||
#include "s_sprite.h" // Para SSprite
|
||||
@@ -96,22 +96,22 @@ void Title::checkInput()
|
||||
{
|
||||
if (show_cheevos_)
|
||||
{
|
||||
if (Input::get()->checkInput(InputAction::DOWN, REPEAT_TRUE))
|
||||
if (Input::get()->checkInput(InputAction::DOWN, INPUT_ALLOW_REPEAT))
|
||||
{
|
||||
moveCheevosList(1);
|
||||
}
|
||||
else if (Input::get()->checkInput(InputAction::UP, REPEAT_TRUE))
|
||||
else if (Input::get()->checkInput(InputAction::UP, INPUT_ALLOW_REPEAT))
|
||||
{
|
||||
moveCheevosList(0);
|
||||
}
|
||||
else if (Input::get()->checkInput(InputAction::ACCEPT, REPEAT_FALSE))
|
||||
else if (Input::get()->checkInput(InputAction::ACCEPT, INPUT_DO_NOT_ALLOW_REPEAT))
|
||||
{
|
||||
hideCheevosList();
|
||||
counter_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (Input::get()->checkInput(InputAction::ACCEPT, REPEAT_FALSE))
|
||||
if (Input::get()->checkInput(InputAction::ACCEPT, INPUT_DO_NOT_ALLOW_REPEAT))
|
||||
{
|
||||
if (state_ == TitleState::SHOW_LOADING_SCREEN)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user