summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2012-05-09 21:16:31 +0300
committerAndrei Karas <akaras@inbox.ru>2012-05-09 21:17:31 +0300
commitaab80ddc8f56d6a383182ce5c241e9d94ca27bab (patch)
tree9e81b97354b666820ab6e2bb9575dc1127a486a8
parent0af9ff98876426c096d2b4b8a4f17172af92b8d0 (diff)
downloadmv-aab80ddc8f56d6a383182ce5c241e9d94ca27bab.tar.gz
mv-aab80ddc8f56d6a383182ce5c241e9d94ca27bab.tar.bz2
mv-aab80ddc8f56d6a383182ce5c241e9d94ca27bab.tar.xz
mv-aab80ddc8f56d6a383182ce5c241e9d94ca27bab.zip
Add ability to auto repeat some keys presses.
-rw-r--r--src/game.cpp1
-rw-r--r--src/inputevent.h3
-rw-r--r--src/inputmanager.cpp22
-rw-r--r--src/inputmanager.h5
-rw-r--r--src/joystick.cpp41
-rw-r--r--src/joystick.h8
-rw-r--r--src/keyboardconfig.cpp48
-rw-r--r--src/keyboardconfig.h8
-rw-r--r--src/keyboarddata.h4
-rw-r--r--src/keydata.h3
10 files changed, 136 insertions, 7 deletions
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<int, int> KeyToIdMap;
typedef KeyToIdMap::iterator KeyToIdMapIter;
+typedef std::map<int, int> 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 <std::string> &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
};
/**