summaryrefslogtreecommitdiff
path: root/src/inputmanager.cpp
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2012-04-08 19:41:19 +0300
committerAndrei Karas <akaras@inbox.ru>2012-04-08 19:41:19 +0300
commit30ef016b0a14f36dc480284e2d775295b5501dd4 (patch)
treea269c0983efb8dc9160bfe10b1dba26a302aff0c /src/inputmanager.cpp
parent25a6eae7f4fb561bbf930be28ee09510b40ebc80 (diff)
downloadmv-30ef016b0a14f36dc480284e2d775295b5501dd4.tar.gz
mv-30ef016b0a14f36dc480284e2d775295b5501dd4.tar.bz2
mv-30ef016b0a14f36dc480284e2d775295b5501dd4.tar.xz
mv-30ef016b0a14f36dc480284e2d775295b5501dd4.zip
Move most input code from keyboardconfig to inputmanager.
Diffstat (limited to 'src/inputmanager.cpp')
-rw-r--r--src/inputmanager.cpp317
1 files changed, 308 insertions, 9 deletions
diff --git a/src/inputmanager.cpp b/src/inputmanager.cpp
index 7610acf29..3a0b22f3e 100644
--- a/src/inputmanager.cpp
+++ b/src/inputmanager.cpp
@@ -20,9 +20,10 @@
#include "inputmanager.h"
+#include "configuration.h"
#include "game.h"
#include "keyboardconfig.h"
-#include "keydata.h"
+#include "keyboarddata.h"
#include "localplayer.h"
#include "gui/chatwindow.h"
@@ -31,6 +32,7 @@
#include "gui/npcdialog.h"
#include "gui/npcpostdialog.h"
#include "gui/setup.h"
+#include "gui/setup_keyboard.h"
#include "gui/textdialog.h"
#include "gui/tradewindow.h"
@@ -43,20 +45,317 @@ InputManager inputManager;
extern QuitDialog *quitDialog;
-InputManager::InputManager()
+InputManager::InputManager() :
+ mSetupKey(nullptr),
+ mNewKeyIndex(Input::KEY_NO_VALUE)
{
}
+void InputManager::init()
+{
+ for (int i = 0; i < Input::KEY_TOTAL; i++)
+ {
+ for (int f = 0; f < KeyFunctionSize; f ++)
+ {
+ mKey[i].values[f].type = INPUT_UNKNOWN;
+ mKey[i].values[f].value = -1;
+ }
+ }
+
+ mNewKeyIndex = Input::KEY_NO_VALUE;
+
+ makeDefault();
+ retrieve();
+ keyboard.updateKeyActionMap();
+}
+
+void InputManager::retrieve()
+{
+ for (int i = 0; i < Input::KEY_TOTAL; i++)
+ {
+ if (*keyData[i].configField)
+ {
+ KeyFunction &kf = mKey[i];
+ std::string keyStr = config.getValue(keyData[i].configField,
+ toString(keyData[i].defaultValue));
+ StringVect keys;
+ splitToStringVector(keys, keyStr, ',');
+ StringVectCIter it = keys.begin();
+ StringVectCIter it_end = keys.end();
+ int i2 = 0;
+ for (; it != it_end && i2 < KeyFunctionSize; ++ it)
+ {
+ std::string keyStr2 = *it;
+ if (keyStr.size() < 2)
+ continue;
+ int type = INPUT_KEYBOARD;
+ if ((keyStr2[0] < '0' || keyStr2[0] > '9')
+ && keyStr2[0] != '-')
+ {
+ switch (keyStr2[0])
+ {
+ case 'm':
+ type = INPUT_MOUSE;
+ break;
+ case 'j':
+ type = INPUT_JOYSTICK;
+ break;
+ default:
+ break;
+ }
+ keyStr2 = keyStr2.substr(1);
+ }
+ int key = atoi(keyStr2.c_str());
+ if (key >= -255 && key < SDLK_LAST)
+ {
+ kf.values[i2] = KeyItem(type, key);
+ i2 ++;
+ }
+ }
+ }
+ }
+}
+
+void InputManager::store()
+{
+ for (int i = 0; i < Input::KEY_TOTAL; i++)
+ {
+ if (*keyData[i].configField)
+ {
+ std::string keyStr;
+
+ for (size_t i2 = 0; i2 < KeyFunctionSize; i2 ++)
+ {
+ const KeyItem &key = mKey[i].values[i2];
+ if (key.type != INPUT_UNKNOWN)
+ {
+ std::string tmp = "k";
+ switch(key.type)
+ {
+ case INPUT_MOUSE:
+ tmp = "m";
+ break;
+ case INPUT_JOYSTICK:
+ tmp = "j";
+ break;
+ default:
+ break;
+ }
+ if (key.value >= 0)
+ {
+ if (keyStr.empty())
+ {
+ keyStr = tmp + toString(key.value);
+ }
+ else
+ {
+ keyStr += strprintf(",%s%d", tmp.c_str(), key.value);
+ }
+ }
+ }
+ }
+ if (keyStr.empty())
+ keyStr = "-1";
+
+ config.setValue(keyData[i].configField, keyStr);
+ }
+ }
+}
+
+void InputManager::makeDefault()
+{
+ for (int i = 0; i < Input::KEY_TOTAL; i++)
+ {
+ for (size_t i2 = 1; i2 < KeyFunctionSize; i2 ++)
+ {
+ mKey[i].values[i2].type = INPUT_UNKNOWN;
+ mKey[i].values[i2].value = -1;
+ }
+ mKey[i].values[0].type = INPUT_KEYBOARD;
+ mKey[i].values[0].value = keyData[i].defaultValue;
+ }
+}
+
+bool InputManager::hasConflicts(int &key1, int &key2)
+{
+ size_t i;
+ size_t j;
+ /**
+ * No need to parse the square matrix: only check one triangle
+ * that's enough to detect conflicts
+ */
+ for (i = 0; i < Input::KEY_TOTAL; i++)
+ {
+ if (!*keyData[i].configField)
+ continue;
+
+ for (size_t i2 = 0; i2 < KeyFunctionSize; i2 ++)
+ {
+ if (mKey[i].values[i2].value == Input::KEY_NO_VALUE)
+ continue;
+
+ for (j = i, j++; j < Input::KEY_TOTAL; j++)
+ {
+
+ if ((keyData[i].grp & keyData[j].grp) == 0 ||
+ !*keyData[i].configField)
+ {
+ continue;
+ }
+
+ for (size_t j2 = 0; j2 < KeyFunctionSize; j2 ++)
+ {
+ // Allow for item shortcut and emote keys to overlap
+ // as well as emote and ignore keys, but no other keys
+ if (mKey[j].values[j2].type != INPUT_UNKNOWN
+ && mKey[i].values[i2].value == mKey[j].values[j2].value
+ && mKey[i].values[i2].type == mKey[j].values[j2].type)
+ {
+ key1 = i;
+ key2 = j;
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+}
+
+void InputManager::callbackNewKey()
+{
+ mSetupKey->newKeyCallback(mNewKeyIndex);
+}
+
+bool InputManager::isActionActive(int index) const
+{
+ return keyboard.isActionActive(index);
+}
+
+KeyFunction &InputManager::getKey(int index)
+{
+ if (index < 0 || index >= Input::KEY_TOTAL)
+ index = 0;
+ return mKey[index];
+}
+
+std::string InputManager::getKeyStringLong(int index) const
+{
+ std::string keyStr;
+
+ for (size_t i = 0; i < KeyFunctionSize; i ++)
+ {
+ const KeyItem &key = mKey[index].values[i];
+ if (key.type == INPUT_KEYBOARD)
+ {
+ if (key.value >= 0)
+ {
+ std::string str = keyboard.getKeyName(key.value);
+ if (!str.empty())
+ {
+ if (keyStr.empty())
+ keyStr = str;
+ else
+ keyStr += std::string(" ") + str;
+ }
+ }
+ }
+ }
+
+ if (keyStr.empty())
+ return _("unknown key");
+ return keyStr;
+}
+
+std::string InputManager::getKeyValueString(int index) const
+{
+ std::string keyStr;
+
+ for (size_t i = 0; i < KeyFunctionSize; i ++)
+ {
+ const KeyItem &key = mKey[index].values[i];
+ if (key.type == INPUT_KEYBOARD)
+ {
+ if (key.value >= 0)
+ {
+ std::string str = keyboard.getKeyShortString(
+ keyboard.getKeyName(key.value));
+ if (!str.empty())
+ {
+ if (keyStr.empty())
+ keyStr = str;
+ else
+ keyStr += std::string(" ") + str;
+ }
+ }
+ }
+ }
+
+ if (keyStr.empty())
+ return _("u key");
+ return keyStr;
+}
+
+void InputManager::addActionKey(int action, int type, int val)
+{
+ if (action < 0 || action >= Input::KEY_TOTAL)
+ return;
+
+ int idx = -1;
+ KeyFunction &key = mKey[action];
+ for (size_t i = 0; i < KeyFunctionSize; i ++)
+ {
+ if (key.values[i].type == INPUT_UNKNOWN
+ || (key.values[i].type == INPUT_KEYBOARD
+ && key.values[i].value == val))
+ {
+ idx = i;
+ break;
+ }
+ }
+ if (idx == -1)
+ {
+ for (size_t i = 1; i < KeyFunctionSize; i ++)
+ {
+ key.values[i - 1].type = key.values[i].type;
+ key.values[i - 1].value = key.values[i].value;
+ }
+ idx = KeyFunctionSize - 1;
+ }
+
+ key.values[idx] = KeyItem(type, val);
+}
+
+void InputManager::setNewKey(const SDL_Event &event)
+{
+ int val = keyboard.getKeyValueFromEvent(event);
+
+ addActionKey(mNewKeyIndex, INPUT_KEYBOARD, val);
+
+ keyboard.updateKeyActionMap();
+}
+
+void InputManager::unassignKey()
+{
+ KeyFunction &key = mKey[mNewKeyIndex];
+ for (size_t i = 0; i < KeyFunctionSize; i ++)
+ {
+ key.values[i].type = INPUT_UNKNOWN;
+ key.values[i].value = -1;
+ }
+ keyboard.updateKeyActionMap();
+}
+
bool InputManager::handleEvent(const SDL_Event &event)
{
if (event.type == SDL_KEYDOWN)
{
if (setupWindow && setupWindow->isVisible() &&
- keyboard.getNewKeyIndex() > Input::KEY_NO_VALUE)
+ getNewKeyIndex() > Input::KEY_NO_VALUE)
{
- keyboard.setNewKey(event);
- keyboard.callbackNewKey();
- keyboard.setNewKeyIndex(Input::KEY_NO_VALUE);
+ setNewKey(event);
+ callbackNewKey();
+ setNewKeyIndex(Input::KEY_NO_VALUE);
return true;
}
@@ -143,8 +442,8 @@ int InputManager::getInputConditionMask()
if (!player_node || !player_node->getDisableGameModifiers())
mask += COND_EMODS;
- if (!keyboard.isActionActive(Input::KEY_TARGET)
- && !keyboard.isActionActive(Input::KEY_UNTARGET))
+ if (!isActionActive(Input::KEY_TARGET)
+ && !isActionActive(Input::KEY_UNTARGET))
{
mask += COND_NOTARGET;
}
@@ -158,5 +457,5 @@ bool InputManager::checkKey(const KeyData *key, int mask)
return false;
return (key->modKeyIndex == Input::KEY_NO_VALUE
- || keyboard.isActionActive(key->modKeyIndex));
+ || isActionActive(key->modKeyIndex));
}