From dd07817edea5a8f320e4275cc08eba895e4fcc3b Mon Sep 17 00:00:00 2001 From: Don Honerbrink Date: Fri, 24 Jul 2015 15:21:33 -0500 Subject: [PATCH 1/5] Refactoring UserInput to accomidate future changes (i.e. joystick support) --- Package/Environment/Common/settings.conf | 4 +- RetroFE/Source/CMakeLists.txt | 3 + RetroFE/Source/Control/InputHandler.h | 12 ++ RetroFE/Source/Control/KeyboardHandler.cpp | 30 +++++ RetroFE/Source/Control/KeyboardHandler.h | 17 +++ RetroFE/Source/Control/UserInput.cpp | 148 ++++++++++++--------- RetroFE/Source/Control/UserInput.h | 24 ++-- RetroFE/Source/RetroFE.cpp | 9 +- 8 files changed, 166 insertions(+), 81 deletions(-) create mode 100644 RetroFE/Source/Control/InputHandler.h create mode 100644 RetroFE/Source/Control/KeyboardHandler.cpp create mode 100644 RetroFE/Source/Control/KeyboardHandler.h diff --git a/Package/Environment/Common/settings.conf b/Package/Environment/Common/settings.conf index 0449473..38c073f 100644 --- a/Package/Environment/Common/settings.conf +++ b/Package/Environment/Common/settings.conf @@ -12,8 +12,8 @@ # Display ####################################### fullscreen = no -horizontal = stretch # or enter in the screen pixel width (i.e 1024) -vertical = stretch # or enter in the screen pixel width (i.e 768) +horizontal = 400 # or enter in the screen pixel width (i.e 1024) +vertical = 300 # or enter in the screen pixel width (i.e 768) layout = Default 16x9 hideMouse = yes showParenthesis = yes diff --git a/RetroFE/Source/CMakeLists.txt b/RetroFE/Source/CMakeLists.txt index 224d20f..9e1dd0f 100644 --- a/RetroFE/Source/CMakeLists.txt +++ b/RetroFE/Source/CMakeLists.txt @@ -92,6 +92,8 @@ set(RETROFE_HEADERS "${RETROFE_DIR}/Source/Collection/Item.h" "${RETROFE_DIR}/Source/Collection/MenuParser.h" "${RETROFE_DIR}/Source/Control/UserInput.h" + "${RETROFE_DIR}/Source/Control/InputHandler.h" + "${RETROFE_DIR}/Source/Control/KeyboardHandler.h" "${RETROFE_DIR}/Source/Database/Configuration.h" "${RETROFE_DIR}/Source/Database/DB.h" "${RETROFE_DIR}/Source/Database/MetadataDatabase.h" @@ -137,6 +139,7 @@ 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/KeyboardHandler.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/InputHandler.h b/RetroFE/Source/Control/InputHandler.h new file mode 100644 index 0000000..9996d4b --- /dev/null +++ b/RetroFE/Source/Control/InputHandler.h @@ -0,0 +1,12 @@ +#pragma once + +#include + +class InputHandler +{ +public: + virtual bool update(SDL_Event &e) = 0; + virtual bool pressed() = 0; + virtual void reset() = 0; +}; + diff --git a/RetroFE/Source/Control/KeyboardHandler.cpp b/RetroFE/Source/Control/KeyboardHandler.cpp new file mode 100644 index 0000000..dd2e5d8 --- /dev/null +++ b/RetroFE/Source/Control/KeyboardHandler.cpp @@ -0,0 +1,30 @@ +#include "KeyboardHandler.h" + +KeyboardHandler::KeyboardHandler(SDL_Scancode s) +: scancode_(s) +, pressed_(false) +{ +} + +void KeyboardHandler::reset() +{ + pressed_= false; +} + +bool KeyboardHandler::update(SDL_Event &e) +{ + if(e.key.keysym.scancode == scancode_) + { + if(e.type == SDL_KEYUP) pressed_ = false; + if(e.type == SDL_KEYDOWN) pressed_ = true; + return true; + } + + return false; +} + +bool KeyboardHandler::pressed() +{ + return pressed_; +} + diff --git a/RetroFE/Source/Control/KeyboardHandler.h b/RetroFE/Source/Control/KeyboardHandler.h new file mode 100644 index 0000000..b49097c --- /dev/null +++ b/RetroFE/Source/Control/KeyboardHandler.h @@ -0,0 +1,17 @@ +#pragma once + +#include "InputHandler.h" + +class KeyboardHandler : public InputHandler +{ +public: + KeyboardHandler(SDL_Scancode scancode); + bool update(SDL_Event &e); + bool pressed(); + void reset(); + +private: + SDL_Scancode scancode_; + bool pressed_; +}; + diff --git a/RetroFE/Source/Control/UserInput.cpp b/RetroFE/Source/Control/UserInput.cpp index 04da529..77c2257 100644 --- a/RetroFE/Source/Control/UserInput.cpp +++ b/RetroFE/Source/Control/UserInput.cpp @@ -17,10 +17,18 @@ #include "UserInput.h" #include "../Database/Configuration.h" #include "../Utility/Log.h" +#include "../Utility/Utils.h" +#include "KeyboardHandler.h" UserInput::UserInput(Configuration &c) : config_(c) + , joystick_(NULL) { + for(unsigned int i = 0; i < KeyCodeMax; ++i) + { + keyHandlers_[i] = NULL; + lastKeyState_[i] = false; + } } UserInput::~UserInput() @@ -59,46 +67,16 @@ bool UserInput::initialize() // retVal = MapKey("admin", KeyCodeAdminMode) && retVal; // retVal = MapKey("remove", KeyCodeHideItem) && retVal; + for(int i = 0; i < SDL_NumJoysticks(); ++i) + { + joystick_ = SDL_JoystickOpen(i); + break; + } + + return retVal; } -SDL_Scancode UserInput::scancode(KeyCode_E key) -{ - SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN; - std::map::iterator it = keyMap_.find(key); - - if(it != keyMap_.end()) - { - scancode = it->second; - } - - return scancode; -} - - -UserInput::KeyCode_E UserInput::keycode(SDL_Scancode scancode) -{ - KeyCode_E keycode = KeyCodeNull; - - std::map::iterator it = reverseKeyMap_.find(scancode); - - if(it != reverseKeyMap_.end()) - { - keycode = it->second; - } - - return keycode; -} - -void UserInput::resetKeyStates() -{ - for(std::map::iterator it = keyState_.begin(); it != keyState_.end(); it++) - { - it->second = false; - } -} - - bool UserInput::MapKey(std::string keyDescription, KeyCode_E key) { SDL_Scancode scanCode; @@ -108,40 +86,90 @@ bool UserInput::MapKey(std::string keyDescription, KeyCode_E key) if(!config_.getProperty(configKey, description)) { - Logger::write(Logger::ZONE_ERROR, "Configuration", "Missing property " + configKey); + Logger::write(Logger::ZONE_ERROR, "Input", "Missing property " + configKey); return false; } + scanCode = SDL_GetScancodeFromName(description.c_str()); - if(scanCode == SDL_SCANCODE_UNKNOWN) + if(scanCode != SDL_SCANCODE_UNKNOWN) { - Logger::write(Logger::ZONE_ERROR, "Configuration", "Unsupported property value for " + configKey + "(" + description + "). See Documentation/Keycodes.txt for valid inputs"); - return false; + Logger::write(Logger::ZONE_INFO, "Input", "Binding key " + configKey); + keyHandlers_[key] = new KeyboardHandler(scanCode); + return true; } - - keyMap_[key] = scanCode; - reverseKeyMap_[scanCode] = key; - keyState_[key] = false; - return true; +/* + else if(description.find("joy") == 0) + { + std::string joydesc = Utils::replace(Utils::toLower(description), "joy", ""); + if(joydesc.find("button")) + { + unsigned int button; + std::stringstream ss; + ss << Utils::replace(joydesc, "button", ""); + ss >> button; + buttonMap_[key] = button; + keyState_[key] = 0; + 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(); + } + else if(joydesc.find("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; + Logger::write(Logger::ZONE_INFO, "Input", "Binding joypad hat " + joydesc ); + } + } +*/ + Logger::write(Logger::ZONE_ERROR, "Input", "Unsupported property value for " + configKey + "(" + description + "). See Documentation/Keycodes.txt for valid inputs"); + return false; } -bool UserInput::keystate(SDL_Scancode code, bool state) +void UserInput::resetStates() { - KeyCode_E key = keycode(code); - - if(key == KeyCodeNull) { return false; } - if(keyState_.find(key) == keyState_.end()) { return false; } - - keyState_[key] = state; - return true; - + for(unsigned int i = 0; i < KeyCodeMax; ++i) + { + keyHandlers_[i]->reset(); + } } -bool UserInput::keystate(KeyCode_E key) +bool UserInput::update(SDL_Event &e) { - if(keyState_.find(key) == keyState_.end()) { return false; } - return keyState_[key]; + bool updated = false; + for(unsigned int i = 0; i < KeyCodeMax; ++i) + { + InputHandler *h = keyHandlers_[i]; + if(h) + { + if(h->update(e)) updated = true; + + lastKeyState_[i] = h->pressed(); + } + } + + return updated; } - - +bool UserInput::keystate(KeyCode_E code) +{ + return lastKeyState_[code]; +} diff --git a/RetroFE/Source/Control/UserInput.h b/RetroFE/Source/Control/UserInput.h index 3bc1e50..4fbb66a 100644 --- a/RetroFE/Source/Control/UserInput.h +++ b/RetroFE/Source/Control/UserInput.h @@ -16,9 +16,11 @@ #pragma once #include #include +#include #include class Configuration; +class InputHandler; class UserInput { @@ -38,26 +40,22 @@ public: KeyCodeLetterUp, KeyCodeAdminMode, KeyCodeHideItem, - KeyCodeQuit + KeyCodeQuit, + KeyCodeMax }; UserInput(Configuration &c); virtual ~UserInput(); bool initialize(); - SDL_Scancode scancode(KeyCode_E key); - KeyCode_E keycode(SDL_Scancode scancode); - bool keystate(SDL_Scancode code, bool state); - bool keystate(KeyCode_E key); - bool keyStateChanged(); - void resetKeyStates(); - - + void resetStates(); + bool update(SDL_Event &e); + bool keystate(KeyCode_E); private: bool MapKey(std::string keyDescription, KeyCode_E key); - std::map keyMap_; - std::map reverseKeyMap_; - std::map keyState_; Configuration &config_; - const Uint8 *sdlkeys_; + SDL_Joystick *joystick_; + InputHandler *keyHandlers_[KeyCodeMax]; + bool lastKeyState_[KeyCodeMax]; + }; diff --git a/RetroFE/Source/RetroFE.cpp b/RetroFE/Source/RetroFE.cpp index 95b18f4..6f14908 100644 --- a/RetroFE/Source/RetroFE.cpp +++ b/RetroFE/Source/RetroFE.cpp @@ -123,7 +123,7 @@ void RetroFE::launchExit() SDL_RestoreWindow(SDL::getWindow()); SDL_RaiseWindow(SDL::getWindow()); SDL_SetWindowGrab(SDL::getWindow(), SDL_TRUE); - input_.resetKeyStates(); + input_.resetStates(); attract_.reset(); currentTime_ = static_cast(SDL_GetTicks()) / 1000; @@ -400,14 +400,11 @@ RetroFE::RETROFE_STATE RetroFE::processUserInput(Page *page) bool rememberMenu = false; config_.getProperty("rememberMenu", rememberMenu); - if(e.type == SDL_KEYDOWN || e.type == SDL_KEYUP) + if(input_.update(e)) { - SDL_Scancode scancode = SDL_GetScancodeFromKey(e.key.keysym.sym); - input_.keystate(scancode, (e.type == SDL_KEYDOWN) ? true : false); - attract_.reset(); - if(page->isHorizontalScroll()) + if(page->isHorizontalScroll()) { if (input_.keystate(UserInput::KeyCodeLeft)) { From b9850ce1a877eaeb92508a5e560efa63b11cb8a4 Mon Sep 17 00:00:00 2001 From: Don Honerbrink Date: Fri, 24 Jul 2015 16:40:51 -0500 Subject: [PATCH 2/5] 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; } From fa439c831b4c59be5b8f89584188fc441c77397d Mon Sep 17 00:00:00 2001 From: Don Honerbrink Date: Fri, 24 Jul 2015 17:01:01 -0500 Subject: [PATCH 3/5] Added support for multiple sticks and hats on a gamepad --- RetroFE/Source/Control/JoyAxisHandler.cpp | 7 ++++--- RetroFE/Source/Control/JoyAxisHandler.h | 3 ++- RetroFE/Source/Control/JoyButtonHandler.cpp | 7 ++++--- RetroFE/Source/Control/JoyButtonHandler.h | 3 ++- RetroFE/Source/Control/JoyHatHandler.cpp | 8 +++++--- RetroFE/Source/Control/JoyHatHandler.h | 4 +++- RetroFE/Source/Control/UserInput.cpp | 19 ++++++++++++++++--- 7 files changed, 36 insertions(+), 15 deletions(-) diff --git a/RetroFE/Source/Control/JoyAxisHandler.cpp b/RetroFE/Source/Control/JoyAxisHandler.cpp index 67b37d5..5f2677b 100644 --- a/RetroFE/Source/Control/JoyAxisHandler.cpp +++ b/RetroFE/Source/Control/JoyAxisHandler.cpp @@ -1,7 +1,8 @@ #include "JoyAxisHandler.h" -JoyAxisHandler::JoyAxisHandler(Uint8 axis, Sint16 min, Sint16 max) -: axis_(axis) +JoyAxisHandler::JoyAxisHandler(SDL_JoystickID joyid, Uint8 axis, Sint16 min, Sint16 max) +: joyid_(joyid) +, axis_(axis) , min_(min) , max_(max) , pressed_(false) @@ -15,7 +16,7 @@ void JoyAxisHandler::reset() bool JoyAxisHandler::update(SDL_Event &e) { - if(e.type != SDL_JOYAXISMOTION || e.jaxis.axis != axis_) return false; + if(e.type != SDL_JOYAXISMOTION || e.jaxis.which != joyid_ || e.jaxis.axis != axis_) return false; pressed_ = (min_ <= e.jaxis.value && e.jaxis.value <= max_); return true; diff --git a/RetroFE/Source/Control/JoyAxisHandler.h b/RetroFE/Source/Control/JoyAxisHandler.h index dd5255b..55bee04 100644 --- a/RetroFE/Source/Control/JoyAxisHandler.h +++ b/RetroFE/Source/Control/JoyAxisHandler.h @@ -5,12 +5,13 @@ class JoyAxisHandler : public InputHandler { public: - JoyAxisHandler(Uint8 axis, Sint16 min, Sint16 max); + JoyAxisHandler(SDL_JoystickID joyid, Uint8 axis, Sint16 min, Sint16 max); bool update(SDL_Event &e); bool pressed(); void reset(); private: + SDL_JoystickID joyid_; Uint8 axis_; Sint16 min_; Sint16 max_; diff --git a/RetroFE/Source/Control/JoyButtonHandler.cpp b/RetroFE/Source/Control/JoyButtonHandler.cpp index e33354e..ff3e3ed 100644 --- a/RetroFE/Source/Control/JoyButtonHandler.cpp +++ b/RetroFE/Source/Control/JoyButtonHandler.cpp @@ -1,7 +1,8 @@ #include "JoyButtonHandler.h" -JoyButtonHandler::JoyButtonHandler(Uint8 button) -: button_(button) +JoyButtonHandler::JoyButtonHandler(SDL_JoystickID joynum, Uint8 button) +: joynum_(joynum) +, button_(button) , pressed_(false) { } @@ -15,7 +16,7 @@ bool JoyButtonHandler::update(SDL_Event &e) { if(e.type != SDL_JOYBUTTONUP && e.type != SDL_JOYBUTTONDOWN) return false; - if(e.jbutton.button == button_) + if(e.jbutton.which == joynum_ && e.jbutton.button == button_) { pressed_ = (e.type == SDL_JOYBUTTONDOWN) ? true : false; return true; diff --git a/RetroFE/Source/Control/JoyButtonHandler.h b/RetroFE/Source/Control/JoyButtonHandler.h index 13523ee..adee958 100644 --- a/RetroFE/Source/Control/JoyButtonHandler.h +++ b/RetroFE/Source/Control/JoyButtonHandler.h @@ -5,12 +5,13 @@ class JoyButtonHandler : public InputHandler { public: - JoyButtonHandler(Uint8 button); + JoyButtonHandler(SDL_JoystickID joynum, Uint8 button); bool update(SDL_Event &e); bool pressed(); void reset(); private: + SDL_JoystickID joynum_; Uint8 button_; bool pressed_; }; diff --git a/RetroFE/Source/Control/JoyHatHandler.cpp b/RetroFE/Source/Control/JoyHatHandler.cpp index 95e13ec..5b8c3c8 100644 --- a/RetroFE/Source/Control/JoyHatHandler.cpp +++ b/RetroFE/Source/Control/JoyHatHandler.cpp @@ -1,7 +1,9 @@ #include "JoyHatHandler.h" -JoyHatHandler::JoyHatHandler(Uint8 direction) -: direction_(direction) +JoyHatHandler::JoyHatHandler(SDL_JoystickID joynum, Uint8 hatnum, Uint8 direction) +: joynum_(joynum) +, hatnum_(hatnum) +, direction_(direction) , pressed_(false) { } @@ -13,7 +15,7 @@ void JoyHatHandler::reset() bool JoyHatHandler::update(SDL_Event &e) { - if(e.type != SDL_JOYHATMOTION) return false; + if(e.type != SDL_JOYHATMOTION || e.jhat.which != joynum_ || e.jhat.hat != hatnum_) return false; pressed_ = (e.jhat.value == direction_); return true; diff --git a/RetroFE/Source/Control/JoyHatHandler.h b/RetroFE/Source/Control/JoyHatHandler.h index e82c0df..ad249db 100644 --- a/RetroFE/Source/Control/JoyHatHandler.h +++ b/RetroFE/Source/Control/JoyHatHandler.h @@ -5,12 +5,14 @@ class JoyHatHandler : public InputHandler { public: - JoyHatHandler(Uint8 direction); + JoyHatHandler(SDL_JoystickID joynum, Uint8 hatnum, Uint8 direction); bool update(SDL_Event &e); bool pressed(); void reset(); private: + SDL_JoystickID joynum_; + Uint8 hatnum_; Uint8 direction_; bool pressed_; }; diff --git a/RetroFE/Source/Control/UserInput.cpp b/RetroFE/Source/Control/UserInput.cpp index b9c1ede..b9eca67 100644 --- a/RetroFE/Source/Control/UserInput.cpp +++ b/RetroFE/Source/Control/UserInput.cpp @@ -128,13 +128,20 @@ bool UserInput::MapKey(std::string keyDescription, KeyCode_E key) else if(description.find("joy") == 0) { std::string joydesc = Utils::replace(Utils::toLower(description), "joy", ""); + std::stringstream ssjoy; + ssjoy << joydesc.at(0); + int joynum; + ssjoy >> joynum; + joydesc = joydesc.erase(0, 1); + + if(joydesc.find("button") == 0) { unsigned int button; std::stringstream ss; ss << Utils::replace(joydesc, "button", ""); ss >> button; - keyHandlers_[key] = new JoyButtonHandler(button); + keyHandlers_[key] = new JoyButtonHandler(joynum, button); Logger::write(Logger::ZONE_INFO, "Input", "Binding joypad button " + ss.str() ); return true; } @@ -143,6 +150,12 @@ bool UserInput::MapKey(std::string keyDescription, KeyCode_E key) Uint8 hat; joydesc = Utils::replace(joydesc, "hat", ""); + std::stringstream sshat; + sshat << joydesc.at(0); + int hatnum; + ssjoy >> hatnum; + joydesc = joydesc.erase(0, 1); + if(joydesc == "leftup") hat = SDL_HAT_LEFTUP; else if(joydesc == "left") hat = SDL_HAT_LEFT; else if(joydesc == "leftdown") hat = SDL_HAT_LEFTDOWN; @@ -153,7 +166,7 @@ bool UserInput::MapKey(std::string keyDescription, KeyCode_E key) else if(joydesc == "right") hat = SDL_HAT_RIGHT; else if(joydesc == "rightdown") hat = SDL_HAT_RIGHTDOWN; - keyHandlers_[key] = new JoyHatHandler(hat); + keyHandlers_[key] = new JoyHatHandler(joynum, hatnum, hat); Logger::write(Logger::ZONE_INFO, "Input", "Binding joypad hat " + joydesc ); return true; } @@ -184,7 +197,7 @@ bool UserInput::MapKey(std::string keyDescription, KeyCode_E key) ss << joydesc; ss >> axis; Logger::write(Logger::ZONE_INFO, "Input", "Binding joypad axis " + ss.str() ); - keyHandlers_[key] = new JoyAxisHandler(axis, min, max); + keyHandlers_[key] = new JoyAxisHandler(joynum, axis, min, max); return true; } } From dcd5e942b3aefb616e822add7953b3416ef428db Mon Sep 17 00:00:00 2001 From: Don Honerbrink Date: Fri, 24 Jul 2015 17:23:22 -0500 Subject: [PATCH 4/5] updated controls.conf --- Package/Environment/Common/controls.conf | 50 +++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/Package/Environment/Common/controls.conf b/Package/Environment/Common/controls.conf index 954b2d6..6e8b4c1 100644 --- a/Package/Environment/Common/controls.conf +++ b/Package/Environment/Common/controls.conf @@ -11,8 +11,56 @@ back = Escape quit = Q -# See below for a list of key codes that can be used for configuring the controls: +############################################################################## + MOUSE CODES +###################### ###################################################### +# Code # Description +###################### ###################################################### +# mouseButtonLeft Left mouse click +# mouseButtonMiddle Middle mouse click +# mouseButtonRight Right mouse click +# mouseButtonX1 ? +# mouseButtonX2 ? +############################################################################## + JOYSTICK/GAMEPAD CODES +###################### ###################################################### +# Code # Description +###################### ###################################################### +# X is joypad number (0 is first joystick/gamepad) +# joyXHatYLeftUp Y=hat number (0 is the first dpad) (example joy0Hat0Up) +# joyXHatYLeft +# joyXHatYLeftDown +# joyXHatYUp +# joyXHatYDown +# joyXHatYRightUp +# joyXHatYRight +# joyXHatYRightDown +# joyXButtonY Y is button number (0 is first button) +# Example: joy1button7 -> second joystick, 8th button +# Open up the gamepad control panel in windows or use +# "jstest" in linux +# +# joyXAxis0+ First POV stick, first axis positive direction +# (axis 0 is usually x) +# joyXAxis0- First POV stick, first axis positive direction +# (axis 0 is usually x) +# joyXAxis1+ First POV stick, second axis positive direction +# (axis 0 is usually y) +#joyXAxis1- First POV stick, second axis positive direction +# (axis 0 is usually y) +# +# joyXAxis2+ Second POV stick, first axis positive direction +# (axis 2 is usually x) +# joyXAxis2- Second POV stick, first axis positive direction +# (axis 2 is usually x) +# joyXAxis3+ Second POV stick, second axis positive direction +# (axis 3 is usually y) +# joyXAxis3- Second POV stick, second axis positive direction +# (axis 3 is usually y) + +############################################################################## +KEYBOARD CODES ###################### ###################################################### # Code # Description ###################### ###################################################### From 1f0b2c70fae02601b27970bc30dade281dfad95b Mon Sep 17 00:00:00 2001 From: emb <> Date: Mon, 27 Jul 2015 12:50:31 -0500 Subject: [PATCH 5/5] Joysticks and buttons now work. Fixed alphetical scrolling bug when list was empty. --- RetroFE/Source/Control/UserInput.cpp | 10 +++++----- RetroFE/Source/Database/Configuration.cpp | 5 ++++- RetroFE/Source/Graphics/Component/Component.cpp | 2 +- RetroFE/Source/Graphics/Component/ScrollingList.cpp | 6 +++--- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/RetroFE/Source/Control/UserInput.cpp b/RetroFE/Source/Control/UserInput.cpp index b9eca67..7574252 100644 --- a/RetroFE/Source/Control/UserInput.cpp +++ b/RetroFE/Source/Control/UserInput.cpp @@ -145,7 +145,7 @@ bool UserInput::MapKey(std::string keyDescription, KeyCode_E key) Logger::write(Logger::ZONE_INFO, "Input", "Binding joypad button " + ss.str() ); return true; } - else if(joydesc.find("hat")) + else if(joydesc.find("hat") == 0) { Uint8 hat; @@ -170,26 +170,26 @@ bool UserInput::MapKey(std::string keyDescription, KeyCode_E key) Logger::write(Logger::ZONE_INFO, "Input", "Binding joypad hat " + joydesc ); return true; } - else if(joydesc.find("axis")) + else if(joydesc.find("axis") == 0) { // string is now axis0+ unsigned int axis; Sint16 min; Sint16 max; - Utils::replace(joydesc, "axis", ""); + joydesc = Utils::replace(joydesc, "axis", ""); // string is now 0+ if(joydesc.find("-") != std::string::npos) { min = -32768; max = -1000; - Utils::replace(joydesc, "-", ""); + joydesc = Utils::replace(joydesc, "-", ""); } else if(joydesc.find("+") != std::string::npos) { min = 1000; max = 32767; - Utils::replace(joydesc, "+", ""); + joydesc = Utils::replace(joydesc, "+", ""); } // string is now just the axis number diff --git a/RetroFE/Source/Database/Configuration.cpp b/RetroFE/Source/Database/Configuration.cpp index f9cf2dc..165317f 100644 --- a/RetroFE/Source/Database/Configuration.cpp +++ b/RetroFE/Source/Database/Configuration.cpp @@ -40,6 +40,9 @@ Configuration::~Configuration() void Configuration::initialize() { + absolutePath = "D:/RetroFE"; + return; + const char *environment = std::getenv("RETROFE_PATH"); std::string environmentStr; if (environment != NULL) @@ -55,7 +58,7 @@ void Configuration::initialize() GetModuleFileName(hModule, exe, MAX_PATH); std::string sPath(exe); sPath = Utils::getDirectory(sPath); - sPath = Utils::GetParentDirectory(sPath); + sPath = Utils::getParentDirectory(sPath); #else char exepath[1024]; sprintf(exepath, "/proc/%d/exe", getpid()); diff --git a/RetroFE/Source/Graphics/Component/Component.cpp b/RetroFE/Source/Graphics/Component/Component.cpp index 5540cb5..87a30d4 100644 --- a/RetroFE/Source/Graphics/Component/Component.cpp +++ b/RetroFE/Source/Graphics/Component/Component.cpp @@ -374,7 +374,7 @@ bool Component::animate(bool loop) for(unsigned int i = 0; i < tweens->size(); i++) { Tween *tween = tweens->tweens()->at(i); - float elapsedTime = elapsedTweenTime_; + double elapsedTime = elapsedTweenTime_; //todo: too many levels of nesting if(elapsedTime < tween->duration) diff --git a/RetroFE/Source/Graphics/Component/ScrollingList.cpp b/RetroFE/Source/Graphics/Component/ScrollingList.cpp index 6068bb0..c078072 100644 --- a/RetroFE/Source/Graphics/Component/ScrollingList.cpp +++ b/RetroFE/Source/Graphics/Component/ScrollingList.cpp @@ -179,7 +179,7 @@ void ScrollingList::deallocateSpritePoints() unsigned int spriteIndex = firstSpriteIndex_; - for(unsigned int i = 0; i < scrollPoints_->size(); ++i) + for(unsigned int i = 0; i < scrollPoints_->size() && spriteList_->size() > spriteIndex; ++i) { deallocateTexture(spriteList_->at(spriteIndex)); circularIncrement(spriteIndex, spriteList_); @@ -393,7 +393,7 @@ void ScrollingList::letterUp() notifyAllRequested_ = true; deallocateSpritePoints(); - if(spriteList_ && scrollPoints_) + if(spriteList_ && scrollPoints_ && getSelectedCollectionItemSprite()) { unsigned int i = 0; @@ -438,7 +438,7 @@ void ScrollingList::letterDown() notifyAllRequested_ = true; deallocateSpritePoints(); - if(spriteList_ && scrollPoints_) + if(spriteList_ && scrollPoints_ && getSelectedCollectionItemSprite()) { std::string startname = getSelectedCollectionItemSprite()->item->lowercaseFullTitle();