From aab80ddc8f56d6a383182ce5c241e9d94ca27bab Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Wed, 9 May 2012 21:16:31 +0300 Subject: Add ability to auto repeat some keys presses. --- src/game.cpp | 1 + src/inputevent.h | 3 +++ src/inputmanager.cpp | 22 +++++++++++++++++++++- src/inputmanager.h | 5 ++++- src/joystick.cpp | 41 ++++++++++++++++++++++++++++++++++++++++- src/joystick.h | 8 ++++++++ src/keyboardconfig.cpp | 48 +++++++++++++++++++++++++++++++++++++++++++++++- src/keyboardconfig.h | 8 ++++++++ src/keyboarddata.h | 4 ++-- src/keydata.h | 3 ++- 10 files changed, 136 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/game.cpp b/src/game.cpp index 77a95120d..363a30ad4 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -902,6 +902,7 @@ void Game::handleInput() } handleMove(); + inputManager.handleRepeat(); } /** diff --git a/src/inputevent.h b/src/inputevent.h index b8e4ebd1b..cbcc9cc99 100644 --- a/src/inputevent.h +++ b/src/inputevent.h @@ -34,6 +34,9 @@ typedef KeyToActionMap::iterator KeyToActionMapIter; typedef std::map KeyToIdMap; typedef KeyToIdMap::iterator KeyToIdMapIter; +typedef std::map KeyTimeMap; +typedef KeyTimeMap::iterator KeyTimeMapIter; + struct InputEvent { InputEvent(int action0, int mask0); diff --git a/src/inputmanager.cpp b/src/inputmanager.cpp index 3a4ee1b9b..9f07d1fe9 100644 --- a/src/inputmanager.cpp +++ b/src/inputmanager.cpp @@ -526,6 +526,14 @@ bool InputManager::handleEvent(const SDL_Event &event) return false; } +void InputManager::handleRepeat() +{ + const int time = tick_time; + keyboard.handleRepeat(time); + if (joystick) + joystick->handleRepeat(time); +} + void InputManager::updateConditionMask() { mMask = 1; @@ -590,9 +598,12 @@ bool InputManager::invokeKey(const KeyData *key, int keyNum) } void InputManager::updateKeyActionMap(KeyToActionMap &actionMap, - KeyToIdMap &idMap, int type) + KeyToIdMap &idMap, + KeyTimeMap &keyTimeMap, + int type) { actionMap.clear(); + keyTimeMap.clear(); for (size_t i = 0; i < Input::KEY_TOTAL; i ++) { @@ -615,6 +626,15 @@ void InputManager::updateKeyActionMap(KeyToActionMap &actionMap, idMap[ki.value] = i; } } + if (keyData[i].configField && (keyData[i].grp & Input::GRP_REPEAT)) + { + for (size_t i2 = 0; i2 < KeyFunctionSize; i2 ++) + { + const KeyItem &ki = key.values[i2]; + if (ki.type == type && ki.value != -1) + keyTimeMap[ki.value] = 0; + } + } } keySorter.keys = &keyData[0]; diff --git a/src/inputmanager.h b/src/inputmanager.h index 82e5fd5b7..de5003a3b 100644 --- a/src/inputmanager.h +++ b/src/inputmanager.h @@ -135,12 +135,15 @@ class InputManager { return mNewKeyIndex; } void updateKeyActionMap(KeyToActionMap &actionMap, - KeyToIdMap &idMap, int type); + KeyToIdMap &idMap, KeyTimeMap &keyTimeMap, + int type); bool invokeKey(const KeyData *key, int keyNum); bool handleAssignKey(const SDL_Event &event, int type); + void handleRepeat(); + bool triggerAction(const KeysVector *ptrs); int getKeyIndex(int value, int grp, int type) const; diff --git a/src/joystick.cpp b/src/joystick.cpp index 694ac1526..09d5c6226 100644 --- a/src/joystick.cpp +++ b/src/joystick.cpp @@ -260,7 +260,8 @@ void Joystick::getNames(std::vector &names) void Joystick::update() { - inputManager.updateKeyActionMap(mKeyToAction, mKeyToId, INPUT_JOYSTICK); + inputManager.updateKeyActionMap(mKeyToAction, mKeyToId, + mKeyTimeMap, INPUT_JOYSTICK); } KeysVector *Joystick::getActionVector(const SDL_Event &event) @@ -275,6 +276,16 @@ KeysVector *Joystick::getActionVector(const SDL_Event &event) return nullptr; } +KeysVector *Joystick::getActionVectorByKey(int i) +{ + if (i < 0 || i >= mButtonsNumber) + return nullptr; +// logger->log("button triggerAction: %d", i); + if (mKeyToAction.find(i) != mKeyToAction.end()) + return &mKeyToAction[i]; + return nullptr; +} + int Joystick::getButtonFromEvent(const SDL_Event &event) const { if (event.jbutton.which != mNumber) @@ -309,3 +320,31 @@ bool Joystick::validate() const return (mUseInactive || Client::getInputFocused()); } + +void Joystick::handleRepeat(int time) +{ + for (KeyTimeMapIter it = mKeyTimeMap.begin(), it_end = mKeyTimeMap.end(); + it != it_end; ++ it) + { + bool repeat(false); + const int key = (*it).first; + int &keyTime = (*it).second; + if (key >= 0 && key < mButtonsNumber) + { + if (mActiveButtons[key]) + repeat = true; + } + if (repeat && abs(keyTime - time) > 10) + { + keyTime = time; + inputManager.triggerAction(getActionVectorByKey(key)); + } + } +} + +void Joystick::resetRepeat(int key) +{ + KeyTimeMapIter it = mKeyTimeMap.find(key); + if (it != mKeyTimeMap.end()) + (*it).second = tick_time; +} diff --git a/src/joystick.h b/src/joystick.h index 39e96964f..f5495b83e 100644 --- a/src/joystick.h +++ b/src/joystick.h @@ -121,12 +121,18 @@ class Joystick KeysVector *getActionVector(const SDL_Event &event); + KeysVector *getActionVectorByKey(int i); + int getButtonFromEvent(const SDL_Event &event) const; bool isActionActive(int index) const; bool validate() const; + void handleRepeat(int time); + + void resetRepeat(int key); + protected: unsigned char mDirection; @@ -149,6 +155,8 @@ class Joystick KeyToIdMap mKeyToId; + KeyTimeMap mKeyTimeMap; + /** * Is joystick support enabled. */ diff --git a/src/keyboardconfig.cpp b/src/keyboardconfig.cpp index 1dc68df79..fe794cc02 100644 --- a/src/keyboardconfig.cpp +++ b/src/keyboardconfig.cpp @@ -35,6 +35,8 @@ #include "debug.h" +extern volatile int tick_time; + KeyboardConfig::KeyboardConfig() : mEnabled(true), mActiveKeys(nullptr), @@ -108,6 +110,14 @@ KeysVector *KeyboardConfig::getActionVector(const SDL_Event &event) return nullptr; } +KeysVector *KeyboardConfig::getActionVectorByKey(int i) +{ +// logger->log("key triggerAction: %d", i); + if (i != 0 && i < SDLK_LAST && mKeyToAction.find(i) != mKeyToAction.end()) + return &mKeyToAction[i]; + return nullptr; +} + int KeyboardConfig::getActionId(const SDL_Event &event) { const int i = getKeyValueFromEvent(event); @@ -145,7 +155,8 @@ bool KeyboardConfig::isActionActive(int index) const void KeyboardConfig::update() { - inputManager.updateKeyActionMap(mKeyToAction, mKeyToId, INPUT_KEYBOARD); + inputManager.updateKeyActionMap(mKeyToAction, mKeyToId, + mKeyTimeMap, INPUT_KEYBOARD); } void KeyboardConfig::handleActicateKey(const SDL_Event &event) @@ -153,6 +164,7 @@ void KeyboardConfig::handleActicateKey(const SDL_Event &event) const int key = getKeyValueFromEvent(event); if (key < -1 && key > -500) mActiveKeys2[-key] = 1; + resetRepeat(key); } void KeyboardConfig::handleDeActicateKey(const SDL_Event &event) @@ -160,4 +172,38 @@ void KeyboardConfig::handleDeActicateKey(const SDL_Event &event) const int key = getKeyValueFromEvent(event); if (key < -1 && key > -500) mActiveKeys2[-key] = 0; + resetRepeat(key); +} + +void KeyboardConfig::handleRepeat(int time) +{ + for (KeyTimeMapIter it = mKeyTimeMap.begin(), it_end = mKeyTimeMap.end(); + it != it_end; ++ it) + { + bool repeat(false); + const int key = (*it).first; + int &keyTime = (*it).second; + if (key >= 0) + { + if (mActiveKeys[key]) + repeat = true; + } + else if (key < -1 && key > -500) + { + if (mActiveKeys2[-key]) + repeat = true; + } + if (repeat && abs(keyTime - time) > 10) + { + keyTime = time; + inputManager.triggerAction(getActionVectorByKey(key)); + } + } +} + +void KeyboardConfig::resetRepeat(int key) +{ + KeyTimeMapIter it = mKeyTimeMap.find(key); + if (it != mKeyTimeMap.end()) + (*it).second = tick_time; } diff --git a/src/keyboardconfig.h b/src/keyboardconfig.h index 88d525522..4fc1bdc51 100644 --- a/src/keyboardconfig.h +++ b/src/keyboardconfig.h @@ -75,6 +75,8 @@ class KeyboardConfig KeysVector *getActionVector(const SDL_Event &event); + KeysVector *getActionVectorByKey(int i); + std::string getKeyName(int key); bool isActionActive(int index) const; @@ -87,6 +89,10 @@ class KeyboardConfig int getActionId(const SDL_Event &event); + void handleRepeat(int time); + + void resetRepeat(int key); + private: bool mEnabled; /**< Flag to respond to key input */ @@ -97,6 +103,8 @@ class KeyboardConfig KeyToActionMap mKeyToAction; KeyToIdMap mKeyToId; + + KeyTimeMap mKeyTimeMap; }; extern KeyboardConfig keyboard; diff --git a/src/keyboarddata.h b/src/keyboarddata.h index 8ece6cdfb..6d8abf712 100644 --- a/src/keyboarddata.h +++ b/src/keyboarddata.h @@ -66,7 +66,7 @@ static KeyData const keyData[Input::KEY_TOTAL] = { {"keyAttack", INPUT_KEYBOARD, SDLK_LCTRL, INPUT_UNKNOWN, Input::KEY_NO_VALUE, - Input::GRP_DEFAULT, + Input::GRP_DEFAULT | Input::GRP_REPEAT, &ActionManager::attack, Input::KEY_NO_VALUE, 50, COND_GAME | COND_NOFOLLOW | COND_VALIDSPEED}, @@ -136,7 +136,7 @@ static KeyData const keyData[Input::KEY_TOTAL] = { {"keyTargetMonster", INPUT_KEYBOARD, SDLK_a, INPUT_JOYSTICK, 3, - Input::GRP_DEFAULT, + Input::GRP_DEFAULT | Input::GRP_REPEAT, &ActionManager::targetMonster, Input::KEY_NO_VALUE, 50, COND_GAME | COND_NOTARGET}, diff --git a/src/keydata.h b/src/keydata.h index d9d584a6b..352f61f6a 100644 --- a/src/keydata.h +++ b/src/keydata.h @@ -53,7 +53,8 @@ namespace Input GRP_OUTFIT = 8, // outfit key GRP_GUI = 16, // gui key GRP_MOVETOPOINT = 32, // move to point key - GRP_GUICHAN = 64 // for guichan based controls + GRP_GUICHAN = 64, // for guichan based controls + GRP_REPEAT = 128 // repeat emulation keys }; /** -- cgit v1.2.3-60-g2f50