From b9850ce1a877eaeb92508a5e560efa63b11cb8a4 Mon Sep 17 00:00:00 2001 From: Don Honerbrink Date: Fri, 24 Jul 2015 16:40:51 -0500 Subject: [PATCH] Support for POV, hat, and buttons on joysticks. Support for the mouse button. --- RetroFE/Source/CMakeLists.txt | 8 ++ RetroFE/Source/Control/JoyAxisHandler.cpp | 28 ++++++ RetroFE/Source/Control/JoyAxisHandler.h | 20 ++++ RetroFE/Source/Control/JoyButtonHandler.cpp | 31 ++++++ RetroFE/Source/Control/JoyButtonHandler.h | 17 ++++ RetroFE/Source/Control/JoyHatHandler.cpp | 26 +++++ RetroFE/Source/Control/JoyHatHandler.h | 17 ++++ RetroFE/Source/Control/KeyboardHandler.cpp | 5 +- RetroFE/Source/Control/MouseButtonHandler.cpp | 31 ++++++ RetroFE/Source/Control/MouseButtonHandler.h | 17 ++++ RetroFE/Source/Control/UserInput.cpp | 99 ++++++++++++++----- 11 files changed, 271 insertions(+), 28 deletions(-) create mode 100644 RetroFE/Source/Control/JoyAxisHandler.cpp create mode 100644 RetroFE/Source/Control/JoyAxisHandler.h create mode 100644 RetroFE/Source/Control/JoyButtonHandler.cpp create mode 100644 RetroFE/Source/Control/JoyButtonHandler.h create mode 100644 RetroFE/Source/Control/JoyHatHandler.cpp create mode 100644 RetroFE/Source/Control/JoyHatHandler.h create mode 100644 RetroFE/Source/Control/MouseButtonHandler.cpp create mode 100644 RetroFE/Source/Control/MouseButtonHandler.h diff --git a/RetroFE/Source/CMakeLists.txt b/RetroFE/Source/CMakeLists.txt index 9e1dd0f..92d0625 100644 --- a/RetroFE/Source/CMakeLists.txt +++ b/RetroFE/Source/CMakeLists.txt @@ -93,7 +93,11 @@ set(RETROFE_HEADERS "${RETROFE_DIR}/Source/Collection/MenuParser.h" "${RETROFE_DIR}/Source/Control/UserInput.h" "${RETROFE_DIR}/Source/Control/InputHandler.h" + "${RETROFE_DIR}/Source/Control/JoyAxisHandler.h" + "${RETROFE_DIR}/Source/Control/JoyButtonHandler.h" + "${RETROFE_DIR}/Source/Control/JoyHatHandler.h" "${RETROFE_DIR}/Source/Control/KeyboardHandler.h" + "${RETROFE_DIR}/Source/Control/MouseButtonHandler.h" "${RETROFE_DIR}/Source/Database/Configuration.h" "${RETROFE_DIR}/Source/Database/DB.h" "${RETROFE_DIR}/Source/Database/MetadataDatabase.h" @@ -139,7 +143,11 @@ set(RETROFE_SOURCES "${RETROFE_DIR}/Source/Collection/Item.cpp" "${RETROFE_DIR}/Source/Collection/MenuParser.cpp" "${RETROFE_DIR}/Source/Control/UserInput.cpp" + "${RETROFE_DIR}/Source/Control/JoyAxisHandler.cpp" + "${RETROFE_DIR}/Source/Control/JoyButtonHandler.cpp" + "${RETROFE_DIR}/Source/Control/JoyHatHandler.cpp" "${RETROFE_DIR}/Source/Control/KeyboardHandler.cpp" + "${RETROFE_DIR}/Source/Control/MouseButtonHandler.cpp" "${RETROFE_DIR}/Source/Database/Configuration.cpp" "${RETROFE_DIR}/Source/Database/DB.cpp" "${RETROFE_DIR}/Source/Database/MetadataDatabase.cpp" diff --git a/RetroFE/Source/Control/JoyAxisHandler.cpp b/RetroFE/Source/Control/JoyAxisHandler.cpp new file mode 100644 index 0000000..67b37d5 --- /dev/null +++ b/RetroFE/Source/Control/JoyAxisHandler.cpp @@ -0,0 +1,28 @@ +#include "JoyAxisHandler.h" + +JoyAxisHandler::JoyAxisHandler(Uint8 axis, Sint16 min, Sint16 max) +: axis_(axis) +, min_(min) +, max_(max) +, pressed_(false) +{ +} + +void JoyAxisHandler::reset() +{ + pressed_= false; +} + +bool JoyAxisHandler::update(SDL_Event &e) +{ + if(e.type != SDL_JOYAXISMOTION || e.jaxis.axis != axis_) return false; + pressed_ = (min_ <= e.jaxis.value && e.jaxis.value <= max_); + + return true; +} + +bool JoyAxisHandler::pressed() +{ + return pressed_; +} + diff --git a/RetroFE/Source/Control/JoyAxisHandler.h b/RetroFE/Source/Control/JoyAxisHandler.h new file mode 100644 index 0000000..dd5255b --- /dev/null +++ b/RetroFE/Source/Control/JoyAxisHandler.h @@ -0,0 +1,20 @@ +#pragma once + +#include "InputHandler.h" + +class JoyAxisHandler : public InputHandler +{ +public: + JoyAxisHandler(Uint8 axis, Sint16 min, Sint16 max); + bool update(SDL_Event &e); + bool pressed(); + void reset(); + +private: + Uint8 axis_; + Sint16 min_; + Sint16 max_; + + bool pressed_; +}; + diff --git a/RetroFE/Source/Control/JoyButtonHandler.cpp b/RetroFE/Source/Control/JoyButtonHandler.cpp new file mode 100644 index 0000000..e33354e --- /dev/null +++ b/RetroFE/Source/Control/JoyButtonHandler.cpp @@ -0,0 +1,31 @@ +#include "JoyButtonHandler.h" + +JoyButtonHandler::JoyButtonHandler(Uint8 button) +: button_(button) +, pressed_(false) +{ +} + +void JoyButtonHandler::reset() +{ + pressed_= false; +} + +bool JoyButtonHandler::update(SDL_Event &e) +{ + if(e.type != SDL_JOYBUTTONUP && e.type != SDL_JOYBUTTONDOWN) return false; + + if(e.jbutton.button == button_) + { + pressed_ = (e.type == SDL_JOYBUTTONDOWN) ? true : false; + return true; + } + + return false; +} + +bool JoyButtonHandler::pressed() +{ + return pressed_; +} + diff --git a/RetroFE/Source/Control/JoyButtonHandler.h b/RetroFE/Source/Control/JoyButtonHandler.h new file mode 100644 index 0000000..13523ee --- /dev/null +++ b/RetroFE/Source/Control/JoyButtonHandler.h @@ -0,0 +1,17 @@ +#pragma once + +#include "InputHandler.h" + +class JoyButtonHandler : public InputHandler +{ +public: + JoyButtonHandler(Uint8 button); + bool update(SDL_Event &e); + bool pressed(); + void reset(); + +private: + Uint8 button_; + bool pressed_; +}; + diff --git a/RetroFE/Source/Control/JoyHatHandler.cpp b/RetroFE/Source/Control/JoyHatHandler.cpp new file mode 100644 index 0000000..95e13ec --- /dev/null +++ b/RetroFE/Source/Control/JoyHatHandler.cpp @@ -0,0 +1,26 @@ +#include "JoyHatHandler.h" + +JoyHatHandler::JoyHatHandler(Uint8 direction) +: direction_(direction) +, pressed_(false) +{ +} + +void JoyHatHandler::reset() +{ + pressed_= false; +} + +bool JoyHatHandler::update(SDL_Event &e) +{ + if(e.type != SDL_JOYHATMOTION) return false; + + pressed_ = (e.jhat.value == direction_); + return true; +} + +bool JoyHatHandler::pressed() +{ + return pressed_; +} + diff --git a/RetroFE/Source/Control/JoyHatHandler.h b/RetroFE/Source/Control/JoyHatHandler.h new file mode 100644 index 0000000..e82c0df --- /dev/null +++ b/RetroFE/Source/Control/JoyHatHandler.h @@ -0,0 +1,17 @@ +#pragma once + +#include "InputHandler.h" + +class JoyHatHandler : public InputHandler +{ +public: + JoyHatHandler(Uint8 direction); + bool update(SDL_Event &e); + bool pressed(); + void reset(); + +private: + Uint8 direction_; + bool pressed_; +}; + diff --git a/RetroFE/Source/Control/KeyboardHandler.cpp b/RetroFE/Source/Control/KeyboardHandler.cpp index dd2e5d8..e7bb72b 100644 --- a/RetroFE/Source/Control/KeyboardHandler.cpp +++ b/RetroFE/Source/Control/KeyboardHandler.cpp @@ -13,10 +13,11 @@ void KeyboardHandler::reset() bool KeyboardHandler::update(SDL_Event &e) { + if(e.type != SDL_KEYUP && e.type != SDL_KEYDOWN) return false; + if(e.key.keysym.scancode == scancode_) { - if(e.type == SDL_KEYUP) pressed_ = false; - if(e.type == SDL_KEYDOWN) pressed_ = true; + pressed_ = (e.type == SDL_KEYDOWN); return true; } diff --git a/RetroFE/Source/Control/MouseButtonHandler.cpp b/RetroFE/Source/Control/MouseButtonHandler.cpp new file mode 100644 index 0000000..0642ecf --- /dev/null +++ b/RetroFE/Source/Control/MouseButtonHandler.cpp @@ -0,0 +1,31 @@ +#include "MouseButtonHandler.h" + +MouseButtonHandler::MouseButtonHandler(Uint8 button) +: button_(button) +, pressed_(false) +{ +} + +void MouseButtonHandler::reset() +{ + pressed_= false; +} + +bool MouseButtonHandler::update(SDL_Event &e) +{ + if(e.type != SDL_MOUSEBUTTONUP && e.type != SDL_MOUSEBUTTONDOWN) return false; + + if(e.button.button == button_) + { + pressed_ = (e.type == SDL_MOUSEBUTTONDOWN) ? true : false; + return true; + } + + return false; +} + +bool MouseButtonHandler::pressed() +{ + return pressed_; +} + diff --git a/RetroFE/Source/Control/MouseButtonHandler.h b/RetroFE/Source/Control/MouseButtonHandler.h new file mode 100644 index 0000000..48fa476 --- /dev/null +++ b/RetroFE/Source/Control/MouseButtonHandler.h @@ -0,0 +1,17 @@ +#pragma once + +#include "InputHandler.h" + +class MouseButtonHandler : public InputHandler +{ +public: + MouseButtonHandler(Uint8 button); + bool update(SDL_Event &e); + bool pressed(); + void reset(); + +private: + Uint8 button_; + bool pressed_; +}; + diff --git a/RetroFE/Source/Control/UserInput.cpp b/RetroFE/Source/Control/UserInput.cpp index 77c2257..b9c1ede 100644 --- a/RetroFE/Source/Control/UserInput.cpp +++ b/RetroFE/Source/Control/UserInput.cpp @@ -18,7 +18,11 @@ #include "../Database/Configuration.h" #include "../Utility/Log.h" #include "../Utility/Utils.h" +#include "JoyAxisHandler.h" +#include "JoyButtonHandler.h" +#include "JoyHatHandler.h" #include "KeyboardHandler.h" +#include "MouseButtonHandler.h" UserInput::UserInput(Configuration &c) : config_(c) @@ -99,48 +103,91 @@ bool UserInput::MapKey(std::string keyDescription, KeyCode_E key) keyHandlers_[key] = new KeyboardHandler(scanCode); return true; } -/* + + description = Utils::toLower(description); + + if(description.find("mouse") == 0) + { + std::string mousedesc = Utils::replace(Utils::toLower(description), "mouse", ""); + if(mousedesc.find("button") == 0) + { + int button = 0; + std::stringstream ss; + mousedesc = Utils::replace(mousedesc, "button", ""); + if(mousedesc == "left") button = SDL_BUTTON_LEFT; + else if(mousedesc == "middle") button = SDL_BUTTON_MIDDLE; + else if(mousedesc == "right") button = SDL_BUTTON_RIGHT; + else if(mousedesc == "x1") button = SDL_BUTTON_X1; + else if(mousedesc == "x2") button = SDL_BUTTON_X2; + + keyHandlers_[key] = new MouseButtonHandler(button); + Logger::write(Logger::ZONE_INFO, "Input", "Binding mouse button " + ss.str() ); + return true; + } + } else if(description.find("joy") == 0) { std::string joydesc = Utils::replace(Utils::toLower(description), "joy", ""); - if(joydesc.find("button")) + if(joydesc.find("button") == 0) { unsigned int button; std::stringstream ss; ss << Utils::replace(joydesc, "button", ""); ss >> button; - buttonMap_[key] = button; - keyState_[key] = 0; + keyHandlers_[key] = new JoyButtonHandler(button); Logger::write(Logger::ZONE_INFO, "Input", "Binding joypad button " + ss.str() ); - } - else if(joydesc.find("axis")) - { - unsigned int axis; - std::stringstream ss; - ss << Utils::replace(joydesc, "axis", ""); - ss >> axis; - buttonMap_[key] = axis; - keyState_[key] = 0; - Logger::write(Logger::ZONE_INFO, "Input", "Binding joypad axis " + ss.str() ); - keyCallbacks_[key] = new JoyAxisHandler(); + return true; } else if(joydesc.find("hat")) { + Uint8 hat; + joydesc = Utils::replace(joydesc, "hat", ""); - if(joydesc == "leftup") hatMap_[key] = SDL_HAT_LEFTUP; - else if(joydesc == "left") hatMap_[key] = SDL_HAT_LEFT; - else if(joydesc == "leftdown") hatMap_[key] = SDL_HAT_LEFT_DOWN; - else if(joydesc == "up") hatMap_[key] = SDL_HAT_UP; - //else if(joydesc == "centered") hatMap_[key] = SDL_HAT_CENTERED; - else if(joydesc == "down") hatMap_[key] = SDL_HAT_DOWN; - else if(joydesc == "rightup") hatMap_[key] = SDL_HAT_RIGHTUP; - else if(joydesc == "right") hatMap_[key] = SDL_HAT_RIGHT; - else if(joydesc == "rightdown") hatMap_[key] = SDL_HAT_RIGHTDOWN; - keyState_[key] = 0; + if(joydesc == "leftup") hat = SDL_HAT_LEFTUP; + else if(joydesc == "left") hat = SDL_HAT_LEFT; + else if(joydesc == "leftdown") hat = SDL_HAT_LEFTDOWN; + else if(joydesc == "up") hat = SDL_HAT_UP; + //else if(joydesc == "centered") hat = SDL_HAT_CENTERED; + else if(joydesc == "down") hat = SDL_HAT_DOWN; + else if(joydesc == "rightup") hat = SDL_HAT_RIGHTUP; + else if(joydesc == "right") hat = SDL_HAT_RIGHT; + else if(joydesc == "rightdown") hat = SDL_HAT_RIGHTDOWN; + + keyHandlers_[key] = new JoyHatHandler(hat); Logger::write(Logger::ZONE_INFO, "Input", "Binding joypad hat " + joydesc ); + return true; + } + else if(joydesc.find("axis")) + { + // string is now axis0+ + unsigned int axis; + Sint16 min; + Sint16 max; + Utils::replace(joydesc, "axis", ""); + + // string is now 0+ + if(joydesc.find("-") != std::string::npos) + { + min = -32768; + max = -1000; + Utils::replace(joydesc, "-", ""); + } + else if(joydesc.find("+") != std::string::npos) + { + min = 1000; + max = 32767; + Utils::replace(joydesc, "+", ""); + } + + // string is now just the axis number + std::stringstream ss; + ss << joydesc; + ss >> axis; + Logger::write(Logger::ZONE_INFO, "Input", "Binding joypad axis " + ss.str() ); + keyHandlers_[key] = new JoyAxisHandler(axis, min, max); + return true; } } -*/ Logger::write(Logger::ZONE_ERROR, "Input", "Unsupported property value for " + configKey + "(" + description + "). See Documentation/Keycodes.txt for valid inputs"); return false; }