From 7c0201f91352eb6df5313fd651792b5d7c230813 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Tue, 24 Aug 2021 17:57:21 +0200 Subject: [PATCH] working on game controller input --- source/director.cpp | 32 ++++---- source/input.cpp | 174 ++++++++++++++++++++++++++++++-------------- source/input.h | 31 ++++++-- 3 files changed, 156 insertions(+), 81 deletions(-) diff --git a/source/director.cpp b/source/director.cpp index b8763c4..711ad5d 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -11,8 +11,8 @@ Director::Director(std::string path) { // Crea los objetos - mInput1 = new Input(); - mInput2 = new Input(); + mInput1 = new Input(USE_KEYBOARD); + mInput2 = new Input(USE_GAMECONTROLLER); mOptions = new options_t; // Inicializa variables @@ -99,23 +99,17 @@ void Director::init() mInput1->bindKey(INPUT_BUTTON_4, SDL_SCANCODE_ESCAPE); // PAUSE mInput1->bindKey(INPUT_BUTTON_5, SDL_SCANCODE_ESCAPE); // ESCAPE - mInput2->bindKey(INPUT_UP, SDL_SCANCODE_UP); - mInput2->bindKey(INPUT_DOWN, SDL_SCANCODE_DOWN); - mInput2->bindKey(INPUT_LEFT, SDL_SCANCODE_LEFT); - mInput2->bindKey(INPUT_RIGHT, SDL_SCANCODE_RIGHT); - mInput2->bindKey(INPUT_ACCEPT, SDL_SCANCODE_RETURN); - mInput2->bindKey(INPUT_CANCEL, SDL_SCANCODE_ESCAPE); -#ifdef __MIPSEL__ - mInput2->bindKey(INPUT_BUTTON_1, SDL_SCANCODE_LSHIFT); - mInput2->bindKey(INPUT_BUTTON_2, SDL_SCANCODE_SPACE); - mInput2->bindKey(INPUT_BUTTON_3, SDL_SCANCODE_LCTRL); -#else - mInput2->bindKey(INPUT_BUTTON_1, SDL_SCANCODE_Q); - mInput2->bindKey(INPUT_BUTTON_2, SDL_SCANCODE_W); - mInput2->bindKey(INPUT_BUTTON_3, SDL_SCANCODE_E); -#endif - mInput2->bindKey(INPUT_BUTTON_4, SDL_SCANCODE_ESCAPE); // PAUSE - mInput2->bindKey(INPUT_BUTTON_5, SDL_SCANCODE_ESCAPE); // ESCAPE + mInput2->bindGameController(INPUT_UP, SDL_CONTROLLER_BUTTON_DPAD_UP); + mInput2->bindGameController(INPUT_DOWN, SDL_CONTROLLER_BUTTON_DPAD_DOWN); + mInput2->bindGameController(INPUT_LEFT, SDL_CONTROLLER_BUTTON_DPAD_LEFT); + mInput2->bindGameController(INPUT_RIGHT, SDL_CONTROLLER_BUTTON_DPAD_RIGHT); + mInput2->bindGameController(INPUT_ACCEPT, SDL_CONTROLLER_BUTTON_A); + mInput2->bindGameController(INPUT_CANCEL, SDL_CONTROLLER_BUTTON_B); + mInput2->bindGameController(INPUT_BUTTON_1, SDL_CONTROLLER_BUTTON_X); + mInput2->bindGameController(INPUT_BUTTON_2, SDL_CONTROLLER_BUTTON_Y); + mInput2->bindGameController(INPUT_BUTTON_3, SDL_CONTROLLER_BUTTON_B); + mInput2->bindGameController(INPUT_BUTTON_4, SDL_CONTROLLER_BUTTON_GUIDE); // PAUSE + mInput2->bindGameController(INPUT_BUTTON_5, SDL_CONTROLLER_BUTTON_GUIDE); // ESCAPE } // Inicializa JailAudio diff --git a/source/input.cpp b/source/input.cpp index a292a3e..41c36ed 100644 --- a/source/input.cpp +++ b/source/input.cpp @@ -1,13 +1,28 @@ #include "input.h" +#include // Constructor -Input::Input() +Input::Input(int source) { + // Inicializa las variables for (int i = 0; i < 15; i++) { - mInput[i].scancode = 0; - mInput[i].active = false; + mKeyBindings[i].scancode = 0; + mKeyBindings[i].active = false; + + mGameControllerBindings[i].button = SDL_CONTROLLER_BUTTON_INVALID; + mGameControllerBindings[i].active = false; } + + // Comprueba si hay algún mando conectado + discoverGameController(); + + // En caso de haber un mando, el objeto se puede utilizar con entradas de mando + if (mGameControllerFound) + mSource = source; + // Si no hay un mando, el objeto se configura como teclado + else + mSource = USE_KEYBOARD; } // Destructor @@ -18,57 +33,103 @@ Input::~Input() // Asigna uno de los posibles inputs a una tecla del teclado void Input::bindKey(Uint8 input, SDL_Scancode code) { - mInput[input].scancode = code; + mKeyBindings[input].scancode = code; +} + +// Asigna uno de los posibles inputs a un botón del mando +void Input::bindGameController(Uint8 input, SDL_GameControllerButton button) +{ + mGameControllerBindings[input].button = button; } // Comprueba si un input esta activo bool Input::checkInput(Uint8 input, bool repeat) { - const Uint8 *mKeystates = SDL_GetKeyboardState(NULL); + if (mSource == USE_KEYBOARD) + { + const Uint8 *mKeystates = SDL_GetKeyboardState(NULL); - if (repeat) - { - if (mKeystates[mInput[input].scancode] != 0) - return true; - else - return false; - } - else - { - if (!mInput[input].active) + if (repeat) { - if (mKeystates[mInput[input].scancode] != 0) - { - mInput[input].active = true; + if (mKeystates[mKeyBindings[input].scancode] != 0) return true; - } else - { return false; - } } else { - if (mKeystates[mInput[input].scancode] == 0) + if (!mKeyBindings[input].active) { - mInput[input].active = false; - return false; + if (mKeystates[mKeyBindings[input].scancode] != 0) + { + mKeyBindings[input].active = true; + return true; + } + else + { + return false; + } } else { + if (mKeystates[mKeyBindings[input].scancode] == 0) + { + mKeyBindings[input].active = false; + return false; + } + else + { + return false; + } + } + } + } + else // Utiliza mando + { + if (repeat) + { + if (SDL_GameControllerGetButton(mGameController, mGameControllerBindings[input].button) != 0) + return true; + else return false; + } + else + { + if (!mGameControllerBindings[input].active) + { + if (SDL_GameControllerGetButton(mGameController, mGameControllerBindings[input].button) != 0) + { + mGameControllerBindings[input].active = true; + return true; + } + else + { + return false; + } + } + else + { + if (SDL_GameControllerGetButton(mGameController, mGameControllerBindings[input].button) == 0) + { + mGameControllerBindings[input].active = false; + return false; + } + else + { + return false; + } } } } } // Gestiona las entradas desde el mando de juego -bool Input::checkGameController(Uint8 state) +/*bool Input::checkGameController(Uint8 state) { bool success = false; // No hay mando. Siempre devuelve falso salvo NO_INPUT que siempre es cierto - /*if (!mGameControllerFound) + if (!mGameControllerFound) { if (state == NO_INPUT) return true; @@ -117,47 +178,52 @@ bool Input::checkGameController(Uint8 state) default: break; - }*/ + } return success; -} +}*/ -// Comprueba si hay algun mando conectado - /*if (SDL_NumJoysticks() < 1) +// Comprueba si hay un mando conectado +bool Input::discoverGameController() +{ + if (SDL_NumJoysticks() < 1) + { + printf("Warning: No joysticks connected!\n"); + mGameControllerFound = false; + } + else + { + // Carga el mando + mGameController = SDL_GameControllerOpen(0); + mGameControllerFound = true; + + if (mGameController == NULL) { - printf("Warning: No joysticks connected!\n"); + printf("Warning: Unable to open game controller!\nSDL Error: %s\n", SDL_GetError()); mGameControllerFound = false; } else { - // Carga el mando - mGameController = SDL_JoystickOpen(0); - mGameControllerFound = true; + printf("%i joysticks were found.\n", SDL_NumJoysticks()); + //printf("%i buttons\n", SDL_JoystickNumButtons(mGameController)); - if (mGameController == NULL) + // Obtiene el dispositivo de control háptico + /*mControllerHaptic = SDL_HapticOpenFromJoystick(mGameController); + if (mControllerHaptic == NULL) { - printf("Warning: Unable to open game controller!\nSDL Error: %s\n", SDL_GetError()); - mGameControllerFound = false; + printf("Warning: Controller does not support haptics!\nSDL Error: %s\n", SDL_GetError()); } else { - printf("%i joysticks were found.\n", SDL_NumJoysticks()); - std::cout << SDL_JoystickNumButtons(mGameController) << " buttons\n"; + printf("Haptics detected\n"); - // Obtiene el dispositivo de control háptico - mControllerHaptic = SDL_HapticOpenFromJoystick(mGameController); - if (mControllerHaptic == NULL) + // Inicializa la vibración + if (SDL_HapticRumbleInit(mControllerHaptic) < 0) { - printf("Warning: Controller does not support haptics!\nSDL Error: %s\n", SDL_GetError()); + printf("Warning: Unable to initialize rumble!\nSDL Error: %s\n", SDL_GetError()); } - else - { - printf("Haptics detected\n"); + }*/ + } + } - // Inicializa la vibración - if (SDL_HapticRumbleInit(mControllerHaptic) < 0) - { - printf("Warning: Unable to initialize rumble!\nSDL Error: %s\n", SDL_GetError()); - } - } - } - }*/ + return mGameControllerFound; +} \ No newline at end of file diff --git a/source/input.h b/source/input.h index 523de6b..6b6c99e 100644 --- a/source/input.h +++ b/source/input.h @@ -23,24 +23,36 @@ #define REPEAT_TRUE true #define REPEAT_FALSE false +#define USE_KEYBOARD 0 +#define USE_GAMECONTROLLER 1 + // Clase Input class Input { private: - struct input_t + struct keyBindings_t { Uint8 scancode; // Scancode asociado bool active; // Indica si está activo }; - input_t mInput[15]; // Vector con las teclas asociadas a los inputs predefinidos + keyBindings_t mKeyBindings[15]; // Vector con las teclas asociadas a los inputs predefinidos - //SDL_Joystick *mGameController; // Manejador para el mando 1 - //SDL_Haptic *mControllerHaptic; // Manejador para el mando con vibración - //bool mGameControllerFound; // Variable para saber si hay un mando conectado + struct GameControllerBindings_t + { + SDL_GameControllerButton button; // GameControllerButton asociado + bool active; // Indica si está activo + }; + GameControllerBindings_t mGameControllerBindings[15]; // Vector con las teclas asociadas a los inputs predefinidos + + SDL_GameController *mGameController; // Manejador para el mando + SDL_Haptic *mControllerHaptic; // Manejador para el mando con vibración + bool mGameControllerFound; // Variable para saber si hay un mando conectado + + int mSource; // Indica si el objeto usará un mando o un teclado public: // Constructor - Input(); + Input(int source); // Destructor ~Input(); @@ -48,11 +60,14 @@ public: // Asigna uno de los posibles inputs a una tecla del teclado void bindKey(Uint8 input, SDL_Scancode code); + // Asigna uno de los posibles inputs a un botón del mando + void bindGameController(Uint8 input, SDL_GameControllerButton button); + // Comprueba si un input esta activo bool checkInput(Uint8 input, bool repeat); - // Gestiona las entradas desde el mando de juego - bool checkGameController(Uint8 state); + // Comprueba si hay un mando conectado + bool discoverGameController(); }; #endif