#include "input.h" #include // Para SDL_INIT_GAMECONTROLLER, SDL_InitSubS... #include // Para SDL_GetError #include // Para SDL_ENABLE #include // Para SDL_NumJoysticks #include // Para SDL_GetKeyboardState #include // Para basic_ostream, operator<<, cout, basi... // [SINGLETON] Input *Input::input_ = nullptr; // [SINGLETON] Crearemos el objeto con esta función estática void Input::init(const std::string &game_controller_db_path) { Input::input_ = new Input(game_controller_db_path); } // [SINGLETON] Destruiremos el objeto con esta función estática void Input::destroy() { delete Input::input_; } // [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él Input *Input::get() { return Input::input_; } // Constructor Input::Input(const std::string &game_controller_db_path) : db_path_(game_controller_db_path) { // Inicializa las variables keyBindings_t kb; kb.scancode = 0; kb.active = false; key_bindings_.resize(static_cast(InputAction::SIZE), kb); GameControllerBindings_t gcb; gcb.button = SDL_CONTROLLER_BUTTON_INVALID; gcb.active = false; game_controller_bindings_.resize(static_cast(InputAction::SIZE), gcb); } // Asigna inputs a teclas void Input::bindKey(InputAction input, SDL_Scancode code) { key_bindings_.at(static_cast(input)).scancode = code; } // Asigna inputs a botones del mando void Input::bindGameControllerButton(InputAction input, SDL_GameControllerButton button) { game_controller_bindings_.at(static_cast(input)).button = button; } // Comprueba si un input esta activo bool Input::checkInput(InputAction input, bool repeat, int device, int index) { if (!enabled_) { return false; } bool successKeyboard = false; bool successGameController = false; if (device == INPUT_USE_ANY) { index = 0; } if (device == INPUT_USE_KEYBOARD || device == INPUT_USE_ANY) { const Uint8 *keyStates = SDL_GetKeyboardState(nullptr); if (repeat) { if (keyStates[key_bindings_.at(static_cast(input)).scancode] != 0) { successKeyboard = true; } else { successKeyboard = false; } } else { if (!key_bindings_.at(static_cast(input)).active) { if (keyStates[key_bindings_.at(static_cast(input)).scancode] != 0) { key_bindings_.at(static_cast(input)).active = true; successKeyboard = true; } else { successKeyboard = false; } } else { if (keyStates[key_bindings_.at(static_cast(input)).scancode] == 0) { key_bindings_.at(static_cast(input)).active = false; successKeyboard = false; } else { successKeyboard = false; } } } } if (gameControllerFound()) if ((device == INPUT_USE_GAMECONTROLLER) || (device == INPUT_USE_ANY)) { if (repeat) { if (SDL_GameControllerGetButton(connected_controllers_.at(index), game_controller_bindings_.at(static_cast(input)).button) != 0) { successGameController = true; } else { successGameController = false; } } else { if (!game_controller_bindings_.at(static_cast(input)).active) { if (SDL_GameControllerGetButton(connected_controllers_.at(index), game_controller_bindings_.at(static_cast(input)).button) != 0) { game_controller_bindings_.at(static_cast(input)).active = true; successGameController = true; } else { successGameController = false; } } else { if (SDL_GameControllerGetButton(connected_controllers_.at(index), game_controller_bindings_.at(static_cast(input)).button) == 0) { game_controller_bindings_.at(static_cast(input)).active = false; successGameController = false; } else { successGameController = false; } } } } return (successKeyboard || successGameController); } // Comprueba si hay almenos un input activo bool Input::checkAnyInput(int device, int index) { if (device == INPUT_USE_ANY) { index = 0; } if (device == INPUT_USE_KEYBOARD || device == INPUT_USE_ANY) { const Uint8 *mKeystates = SDL_GetKeyboardState(nullptr); for (int i = 0; i < (int)key_bindings_.size(); ++i) { if (mKeystates[key_bindings_[i].scancode] != 0) { return true; } } } if (gameControllerFound()) { if (device == INPUT_USE_GAMECONTROLLER || device == INPUT_USE_ANY) { for (int i = 0; i < (int)game_controller_bindings_.size(); ++i) { if (SDL_GameControllerGetButton(connected_controllers_.at(index), game_controller_bindings_[i].button) != 0) { return true; } } } } return false; } // Busca si hay un mando conectado bool Input::discoverGameController() { bool found = false; if (SDL_WasInit(SDL_INIT_GAMECONTROLLER) != 1) { SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER); } if (SDL_GameControllerAddMappingsFromFile(db_path_.c_str()) < 0) { if (verbose_) { std::cout << "Error, could not load " << db_path_.c_str() << " file: " << SDL_GetError() << std::endl; } } const int nJoysticks = SDL_NumJoysticks(); num_gamepads_ = 0; // Cuenta el numero de mandos for (int i = 0; i < nJoysticks; ++i) { if (SDL_IsGameController(i)) { num_gamepads_++; } } if (verbose_) { std::cout << "\nChecking for game controllers...\n"; std::cout << nJoysticks << " joysticks found, " << num_gamepads_ << " are gamepads\n"; } if (num_gamepads_ > 0) { found = true; for (int i = 0; i < num_gamepads_; i++) { // Abre el mando y lo añade a la lista SDL_GameController *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; } controller_names_.push_back(name); } else { if (verbose_) { std::cout << "SDL_GetError() = " << SDL_GetError() << std::endl; } } } SDL_GameControllerEventState(SDL_ENABLE); } return found; } // Comprueba si hay algun mando conectado bool Input::gameControllerFound() { if (num_gamepads_ > 0) { return true; } else { 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; }