From dd07817edea5a8f320e4275cc08eba895e4fcc3b Mon Sep 17 00:00:00 2001 From: Don Honerbrink Date: Fri, 24 Jul 2015 15:21:33 -0500 Subject: [PATCH] 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)) {