summaryrefslogtreecommitdiff
path: root/src/input
diff options
context:
space:
mode:
Diffstat (limited to 'src/input')
-rw-r--r--src/input/inputevent.cpp29
-rw-r--r--src/input/inputevent.h51
-rw-r--r--src/input/inputmanager.cpp804
-rw-r--r--src/input/inputmanager.h191
-rw-r--r--src/input/joystick.cpp369
-rw-r--r--src/input/joystick.h175
-rw-r--r--src/input/keyboardconfig.cpp283
-rw-r--r--src/input/keyboardconfig.h125
-rw-r--r--src/input/keyboarddata.h1965
-rw-r--r--src/input/keydata.h348
-rw-r--r--src/input/keyevent.cpp47
-rw-r--r--src/input/keyevent.h67
-rw-r--r--src/input/keyinput.cpp38
-rw-r--r--src/input/keyinput.h58
14 files changed, 4550 insertions, 0 deletions
diff --git a/src/input/inputevent.cpp b/src/input/inputevent.cpp
new file mode 100644
index 000000000..61e5dc2b1
--- /dev/null
+++ b/src/input/inputevent.cpp
@@ -0,0 +1,29 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2012-2013 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "input/inputevent.h"
+
+#include "debug.h"
+
+InputEvent::InputEvent(const int action0, const int mask0) :
+ action(action0),
+ mask(mask0)
+{
+}
diff --git a/src/input/inputevent.h b/src/input/inputevent.h
new file mode 100644
index 000000000..b65a4b8f2
--- /dev/null
+++ b/src/input/inputevent.h
@@ -0,0 +1,51 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2012-2013 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef INPUT_INPUTEVENT_H
+#define INPUT_INPUTEVENT_H
+
+#include <map>
+#include <vector>
+
+#include "localconsts.h"
+
+typedef std::vector<int> KeysVector;
+typedef KeysVector::iterator KeysVectorIter;
+typedef KeysVector::const_iterator KeysVectorCIter;
+
+typedef std::map<int, KeysVector> KeyToActionMap;
+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 final
+{
+ InputEvent(const int action0, const int mask0);
+
+ int action;
+
+ int mask;
+};
+
+#endif // INPUT_INPUTEVENT_H
diff --git a/src/input/inputmanager.cpp b/src/input/inputmanager.cpp
new file mode 100644
index 000000000..561437124
--- /dev/null
+++ b/src/input/inputmanager.cpp
@@ -0,0 +1,804 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2012-2013 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "input/inputmanager.h"
+
+#include "client.h"
+#include "configuration.h"
+#include "game.h"
+#include "localplayer.h"
+#include "touchmanager.h"
+
+#include "input/joystick.h"
+#include "input/keyboardconfig.h"
+#include "input/keyboarddata.h"
+
+#include "gui/chatwindow.h"
+#include "gui/gui.h"
+#include "gui/inventorywindow.h"
+#include "gui/npcdialog.h"
+#include "gui/npcpostdialog.h"
+#include "gui/sdlinput.h"
+#include "gui/setup.h"
+#include "gui/setup_input.h"
+#include "gui/textdialog.h"
+#include "gui/tradewindow.h"
+
+#include <guichan/exception.hpp>
+#include <guichan/focushandler.hpp>
+
+#include <algorithm>
+
+#include "debug.h"
+
+InputManager inputManager;
+
+extern QuitDialog *quitDialog;
+
+static class KeyFunctor final
+{
+ public:
+ bool operator() (const int key1, const int key2) const
+ {
+ return keys[key1].priority >= keys[key2].priority;
+ }
+
+ const KeyData *keys;
+} keyDataSorter;
+
+
+InputManager::InputManager() :
+ mSetupInput(nullptr),
+ mNewKeyIndex(Input::KEY_NO_VALUE),
+ mMask(1),
+ mNameMap()
+{
+}
+
+void InputManager::init()
+{
+ for (unsigned int i = 0; i < Input::KEY_TOTAL; i++)
+ {
+ KeyFunction &kf = mKey[i];
+ for (unsigned int f = 0; f < KeyFunctionSize; f ++)
+ {
+ KeyItem &ki = kf.values[f];
+ ki.type = INPUT_UNKNOWN;
+ ki.value = -1;
+ }
+ }
+
+ mNewKeyIndex = Input::KEY_NO_VALUE;
+
+ resetKeys();
+ retrieve();
+ update();
+}
+
+void InputManager::update() const
+{
+ keyboard.update();
+ if (joystick)
+ joystick->update();
+}
+
+void InputManager::retrieve()
+{
+ for (int i = 0; i < Input::KEY_TOTAL; i++)
+ {
+#ifdef USE_SDL2
+ const std::string cf = std::string("sdl2") + keyData[i].configField;
+#else
+ const std::string cf = keyData[i].configField;
+#endif
+ if (!cf.empty())
+ {
+ mNameMap[cf] = i;
+ KeyFunction &kf = mKey[i];
+ const std::string keyStr = config.getValue(cf, "");
+ const int keyStrSize = keyStr.size();
+ if (keyStr.empty())
+ continue;
+
+ StringVect keys;
+ splitToStringVector(keys, keyStr, ',');
+ unsigned int i2 = 0;
+ for (StringVectCIter it = keys.begin(), it_end = keys.end();
+ it != it_end && i2 < KeyFunctionSize; ++ it)
+ {
+ std::string keyStr2 = *it;
+ if (keyStrSize < 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);
+ }
+ const int key = atoi(keyStr2.c_str());
+ if (key >= -255 && key < SDLK_LAST)
+ {
+ kf.values[i2] = KeyItem(type, key);
+ i2 ++;
+ }
+ }
+ }
+ }
+}
+
+void InputManager::store() const
+{
+ for (int i = 0; i < Input::KEY_TOTAL; i++)
+ {
+#ifdef USE_SDL2
+ const std::string cf = std::string("sdl2") + keyData[i].configField;
+#else
+ const std::string cf = keyData[i].configField;
+#endif
+ if (!cf.empty())
+ {
+ std::string keyStr;
+ const KeyFunction &kf = mKey[i];
+
+ for (size_t i2 = 0; i2 < KeyFunctionSize; i2 ++)
+ {
+ const KeyItem &key = kf.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 != -1)
+ {
+ if (keyStr.empty())
+ {
+ keyStr.append(tmp).append(toString(key.value));
+ }
+ else
+ {
+ keyStr.append(strprintf(",%s%d",
+ tmp.c_str(), key.value));
+ }
+ }
+ }
+ }
+ if (keyStr.empty())
+ keyStr = "-1";
+
+ config.setValue(cf, keyStr);
+ }
+ }
+}
+
+void InputManager::resetKeys()
+{
+ for (int i = 0; i < Input::KEY_TOTAL; i++)
+ {
+ KeyFunction &key = mKey[i];
+ for (size_t i2 = 1; i2 < KeyFunctionSize; i2 ++)
+ {
+ KeyItem &ki2 = key.values[i2];
+ ki2.type = INPUT_UNKNOWN;
+ ki2.value = -1;
+ }
+ const KeyData &kd = keyData[i];
+ KeyItem &val0 = key.values[0];
+ val0.type = kd.defaultType1;
+ KeyItem &val1 = key.values[1];
+ val1.type = kd.defaultType2;
+#ifdef USE_SDL2
+ if (kd.defaultType1 == INPUT_KEYBOARD)
+ val0.value = SDL_GetScancodeFromKey(kd.defaultValue1);
+ else
+ val0.value = kd.defaultValue1;
+ if (kd.defaultType2 == INPUT_KEYBOARD)
+ val1.value = SDL_GetScancodeFromKey(kd.defaultValue2);
+ else
+ val1.value = kd.defaultValue2;
+#else
+ val0.value = kd.defaultValue1;
+ val1.value = kd.defaultValue2;
+#endif
+ }
+}
+
+void InputManager::makeDefault(const int i)
+{
+ if (i >= 0 && i < Input::KEY_TOTAL)
+ {
+ KeyFunction &key = mKey[i];
+ for (size_t i2 = 1; i2 < KeyFunctionSize; i2 ++)
+ {
+ KeyItem &ki2 = key.values[i2];
+ ki2.type = INPUT_UNKNOWN;
+ ki2.value = -1;
+ }
+ const KeyData &kd = keyData[i];
+ KeyItem &val0 = key.values[0];
+ val0.type = kd.defaultType1;
+ KeyItem &val1 = key.values[1];
+ val1.type = kd.defaultType2;
+
+#ifdef USE_SDL2
+ if (kd.defaultType1 == INPUT_KEYBOARD)
+ val0.value = SDL_GetScancodeFromKey(kd.defaultValue1);
+ else
+ val0.value = kd.defaultValue1;
+ if (kd.defaultType2 == INPUT_KEYBOARD)
+ val1.value = SDL_GetScancodeFromKey(kd.defaultValue2);
+ else
+ val1.value = kd.defaultValue2;
+#else
+ val0.value = kd.defaultValue1;
+ val1.value = kd.defaultValue2;
+#endif
+
+ update();
+ }
+}
+
+bool InputManager::hasConflicts(int &key1, int &key2) const
+{
+ /**
+ * No need to parse the square matrix: only check one triangle
+ * that's enough to detect conflicts
+ */
+ for (int i = 0; i < Input::KEY_TOTAL; i++)
+ {
+ const KeyData &kdi = keyData[i];
+ if (!*kdi.configField)
+ continue;
+
+ const KeyFunction &ki = mKey[i];
+ for (size_t i2 = 0; i2 < KeyFunctionSize; i2 ++)
+ {
+ const KeyItem &vali2 = ki.values[i2];
+ if (vali2.value == Input::KEY_NO_VALUE)
+ continue;
+
+ size_t j;
+ for (j = i, j++; j < Input::KEY_TOTAL; j++)
+ {
+ if ((kdi.grp & keyData[j].grp) == 0 || !*kdi.configField)
+ continue;
+
+ for (size_t j2 = 0; j2 < KeyFunctionSize; j2 ++)
+ {
+ const KeyItem &valj2 = mKey[j].values[j2];
+ // Allow for item shortcut and emote keys to overlap
+ // as well as emote and ignore keys, but no other keys
+ if (valj2.type != INPUT_UNKNOWN
+ && vali2.value == valj2.value
+ && vali2.type == valj2.type)
+ {
+ key1 = static_cast<int>(i);
+ key2 = static_cast<int>(j);
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+}
+
+void InputManager::callbackNewKey()
+{
+ mSetupInput->newKeyCallback(mNewKeyIndex);
+}
+
+bool InputManager::isActionActive(const int index)
+{
+ if (keyboard.isActionActive(index))
+ return true;
+ if (joystick && joystick->isActionActive(index))
+ return true;
+ return touchManager.isActionActive(index);
+}
+
+KeyFunction &InputManager::getKey(int index)
+{
+ if (index < 0 || index >= Input::KEY_TOTAL)
+ index = 0;
+ return mKey[index];
+}
+
+std::string InputManager::getKeyStringLong(const int index) const
+{
+ std::string keyStr;
+ const KeyFunction &ki = mKey[index];
+
+ for (size_t i = 0; i < KeyFunctionSize; i ++)
+ {
+ const KeyItem &key = ki.values[i];
+ std::string str;
+ if (key.type == INPUT_KEYBOARD)
+ {
+ if (key.value >= 0)
+ {
+ str = keyboard.getKeyName(key.value);
+ }
+ else if (key.value < -1)
+ {
+ // TRANSLATORS: long key name. must be short.
+ str = strprintf(_("key_%d"), -key.value);
+ }
+ }
+ else if (key.type == INPUT_JOYSTICK)
+ {
+ // TRANSLATORS: long joystick button name. must be short.
+ str = strprintf(_("JButton%d"), key.value + 1);
+ }
+ if (!str.empty())
+ {
+ if (keyStr.empty())
+ keyStr = str;
+ else
+ keyStr.append(" ").append(str);
+ }
+ }
+
+ if (keyStr.empty())
+ {
+ // TRANSLATORS: unknown long key type
+ return _("unknown key");
+ }
+ return keyStr;
+}
+
+std::string InputManager::getKeyValueString(const int index) const
+{
+ std::string keyStr;
+ const KeyFunction &ki = mKey[index];
+
+ for (size_t i = 0; i < KeyFunctionSize; i ++)
+ {
+ const KeyItem &key = ki.values[i];
+ std::string str;
+ if (key.type == INPUT_KEYBOARD)
+ {
+ if (key.value >= 0)
+ {
+ str = keyboard.getKeyShortString(
+ keyboard.getKeyName(key.value));
+ }
+ else if (key.value < -1)
+ {
+ // TRANSLATORS: short key name. must be very short.
+ str = strprintf(_("key_%d"), -key.value);
+ }
+ }
+ else if (key.type == INPUT_JOYSTICK)
+ {
+ // TRANSLATORS: short joystick button name. muse be very short
+ str = strprintf(_("JB%d"), key.value + 1);
+ }
+ if (!str.empty())
+ {
+ if (keyStr.empty())
+ keyStr = str;
+ else
+ keyStr.append(" ").append(str);
+ }
+ }
+
+ if (keyStr.empty())
+ {
+ // TRANSLATORS: unknown short key type. must be short
+ return _("u key");
+ }
+ return keyStr;
+}
+
+std::string InputManager::getKeyValueByName(const std::string &keyName)
+{
+ const std::map<std::string, int>::const_iterator
+ it = mNameMap.find(keyName);
+
+ if (it == mNameMap.end())
+ return std::string();
+ return getKeyValueString((*it).second);
+}
+
+void InputManager::addActionKey(const int action, const int type,
+ const 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 ++)
+ {
+ const KeyItem &val2 = key.values[i];
+ if (val2.type == INPUT_UNKNOWN || (val2.type == type
+ && val2.value == val))
+ {
+ idx = static_cast<int>(i);
+ break;
+ }
+ }
+ if (idx == -1)
+ {
+ for (size_t i = 1; i < KeyFunctionSize; i ++)
+ {
+ KeyItem &val1 = key.values[i - 1];
+ KeyItem &val2 = key.values[i];
+ val1.type = val2.type;
+ val1.value = val2.value;
+ }
+ idx = KeyFunctionSize - 1;
+ }
+
+ key.values[idx] = KeyItem(type, val);
+}
+
+void InputManager::setNewKey(const SDL_Event &event, const int type)
+{
+ int val = -1;
+ if (type == INPUT_KEYBOARD)
+ val = keyboard.getKeyValueFromEvent(event);
+ else if (type == INPUT_JOYSTICK && joystick)
+ val = joystick->getButtonFromEvent(event);
+
+ if (val != -1)
+ {
+ addActionKey(mNewKeyIndex, type, val);
+ update();
+ }
+}
+
+void InputManager::unassignKey()
+{
+ KeyFunction &key = mKey[mNewKeyIndex];
+ for (size_t i = 0; i < KeyFunctionSize; i ++)
+ {
+ KeyItem &val = key.values[i];
+ val.type = INPUT_UNKNOWN;
+ val.value = -1;
+ }
+ update();
+}
+
+bool InputManager::handleAssignKey(const SDL_Event &event, const int type)
+{
+ if (setupWindow && setupWindow->isWindowVisible() &&
+ getNewKeyIndex() > Input::KEY_NO_VALUE)
+ {
+ setNewKey(event, type);
+ callbackNewKey();
+ setNewKeyIndex(Input::KEY_NO_VALUE);
+ return true;
+ }
+ return false;
+}
+
+bool InputManager::handleEvent(const SDL_Event &event)
+{
+ switch (event.type)
+ {
+ case SDL_KEYDOWN:
+ {
+ updateConditionMask();
+ if (handleAssignKey(event, INPUT_KEYBOARD))
+ return true;
+
+ keyboard.handleActicateKey(event);
+ // send straight to gui for certain windows
+ if (quitDialog || TextDialog::isActive() ||
+ NpcPostDialog::isActive())
+ {
+ try
+ {
+ if (guiInput)
+ guiInput->pushInput(event);
+ if (gui)
+ gui->handleInput();
+ }
+ catch (const gcn::Exception &e)
+ {
+ const char *const err = e.getMessage().c_str();
+ logger->log("Warning: guichan input exception: %s", err);
+ }
+ return true;
+ }
+ break;
+ }
+ case SDL_KEYUP:
+ {
+ updateConditionMask();
+ keyboard.handleDeActicateKey(event);
+ break;
+ }
+ case SDL_JOYBUTTONDOWN:
+ {
+ updateConditionMask();
+// joystick.handleActicateButton(event);
+ if (handleAssignKey(event, INPUT_JOYSTICK))
+ return true;
+ break;
+ }
+ case SDL_JOYBUTTONUP:
+ {
+ updateConditionMask();
+// joystick.handleDeActicateButton(event);
+ break;
+ }
+#ifdef ANDROID
+ case SDL_ACCELEROMETER:
+ {
+ break;
+ }
+#endif
+ default:
+ break;
+ }
+
+ try
+ {
+ if (guiInput)
+ guiInput->pushInput(event);
+ }
+ catch (const gcn::Exception &e)
+ {
+ const char *const err = e.getMessage().c_str();
+ logger->log("Warning: guichan input exception: %s", err);
+ }
+ if (gui)
+ {
+ const bool res = gui->handleInput();
+ if (res && event.type == SDL_KEYDOWN)
+ return true;
+ }
+
+ switch (event.type)
+ {
+ case SDL_KEYDOWN:
+ if (triggerAction(keyboard.getActionVector(event)))
+ return true;
+ break;
+
+ case SDL_JOYBUTTONDOWN:
+ if (joystick && joystick->validate())
+ {
+ if (triggerAction(joystick->getActionVector(event)))
+ return true;
+ }
+ break;
+#ifdef ANDROID
+ case SDL_ACCELEROMETER:
+ {
+ break;
+ }
+#endif
+ default:
+ break;
+ }
+
+ return false;
+}
+
+void InputManager::handleRepeat() const
+{
+ const int time = tick_time;
+ keyboard.handleRepeat(time);
+ if (joystick)
+ joystick->handleRepeat(time);
+}
+
+void InputManager::updateConditionMask()
+{
+ mMask = 1;
+ if (keyboard.isEnabled())
+ mMask |= COND_ENABLED;
+ if ((!chatWindow || !chatWindow->isInputFocused()) &&
+ !NpcDialog::isAnyInputFocused() &&
+ !InventoryWindow::isAnyInputFocused() &&
+ (!tradeWindow || !tradeWindow->isInpupFocused()))
+ {
+ mMask |= COND_NOINPUT;
+ }
+
+ if (!player_node || !player_node->getAway())
+ mMask |= COND_NOAWAY;
+
+ if (!setupWindow || !setupWindow->isWindowVisible())
+ mMask |= COND_NOSETUP;
+
+ if (Game::instance() && Game::instance()->getValidSpeed())
+ mMask |= COND_VALIDSPEED;
+
+ if (gui && !gui->getFocusHandler()->getModalFocused())
+ mMask |= COND_NOMODAL;
+
+ const NpcDialog *const dialog = NpcDialog::getActive();
+ if (!dialog || !dialog->isTextInputFocused())
+ mMask |= COND_NONPCINPUT;
+
+ if (!player_node || !player_node->getDisableGameModifiers())
+ mMask |= COND_EMODS;
+
+ if (!isActionActive(Input::KEY_STOP_ATTACK)
+ && !isActionActive(Input::KEY_UNTARGET))
+ {
+ mMask |= COND_NOTARGET;
+ }
+ if (Game::instance())
+ mMask |= COND_INGAME;
+
+ if (!player_node || player_node->getFollow().empty())
+ mMask |= COND_NOFOLLOW;
+}
+
+bool InputManager::checkKey(const KeyData *const key) const
+{
+// logger->log("mask=%d, condition=%d", mMask, key->condition);
+ if (!key || (key->condition & mMask) != key->condition)
+ return false;
+
+ return (key->modKeyIndex == Input::KEY_NO_VALUE
+ || isActionActive(key->modKeyIndex));
+}
+
+bool InputManager::invokeKey(const KeyData *const key, const int keyNum)
+{
+ // no validation to keyNum because it validated in caller
+
+ if (checkKey(key))
+ {
+ InputEvent evt(keyNum, mMask);
+ ActionFuncPtr func = *(keyData[keyNum].action);
+ if (func && func(evt))
+ return true;
+ }
+ return false;
+}
+
+void InputManager::executeAction(const int keyNum)
+{
+ if (keyNum < 0 || keyNum >= Input::KEY_TOTAL)
+ return;
+
+ InputEvent evt(keyNum, mMask);
+ ActionFuncPtr func = *(keyData[keyNum].action);
+ if (func)
+ func(evt);
+}
+
+void InputManager::updateKeyActionMap(KeyToActionMap &actionMap,
+ KeyToIdMap &idMap,
+ KeyTimeMap &keyTimeMap,
+ const int type) const
+{
+ actionMap.clear();
+ keyTimeMap.clear();
+
+ for (size_t i = 0; i < Input::KEY_TOTAL; i ++)
+ {
+ const KeyFunction &key = mKey[i];
+ const KeyData &kd = keyData[i];
+ if (kd.action)
+ {
+ for (size_t i2 = 0; i2 < KeyFunctionSize; i2 ++)
+ {
+ const KeyItem &ki = key.values[i2];
+ if (ki.type == type && ki.value != -1)
+ actionMap[ki.value].push_back(static_cast<int>(i));
+ }
+ }
+ if (kd.configField && (kd.grp & Input::GRP_GUICHAN))
+ {
+ for (size_t i2 = 0; i2 < KeyFunctionSize; i2 ++)
+ {
+ const KeyItem &ki = key.values[i2];
+ if (ki.type == type && ki.value != -1)
+ idMap[ki.value] = static_cast<int>(i);
+ }
+ }
+ if (kd.configField && (kd.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;
+ }
+ }
+ }
+
+ keyDataSorter.keys = &keyData[0];
+ FOR_EACH (KeyToActionMapIter, it, actionMap)
+ {
+ KeysVector *const keys = &it->second;
+ if (keys && keys->size() > 1)
+ std::sort(keys->begin(), keys->end(), keyDataSorter);
+ }
+}
+
+bool InputManager::triggerAction(const KeysVector *const ptrs)
+{
+ if (!ptrs)
+ return false;
+
+// logger->log("ptrs: %d", (int)ptrs.size());
+
+ FOR_EACHP (KeysVectorCIter, it, ptrs)
+ {
+ const int keyNum = *it;
+ if (keyNum < 0 || keyNum >= Input::KEY_TOTAL)
+ continue;
+
+ if (invokeKey(&keyData[keyNum], keyNum))
+ return true;
+ }
+ return false;
+}
+
+int InputManager::getKeyIndex(const int value, const int grp,
+ const int type) const
+{
+ for (size_t i = 0; i < Input::KEY_TOTAL; i++)
+ {
+ const KeyFunction &key = mKey[i];
+ const KeyData &kd = keyData[i];
+ for (size_t i2 = 0; i2 < KeyFunctionSize; i2 ++)
+ {
+ const KeyItem &vali2 = key.values[i2];
+ if (value == vali2.value && (grp & kd.grp) != 0
+ && vali2.type == type)
+ {
+ return static_cast<int>(i);
+ }
+ }
+ }
+ return Input::KEY_NO_VALUE;
+}
+
+int InputManager::getActionByKey(const SDL_Event &event) const
+{
+ // for now support only keyboard events
+ if (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP)
+ {
+ const int idx = keyboard.getActionId(event);
+ if (idx >= 0 && checkKey(&keyData[idx]))
+ return idx;
+ }
+ return Input::KEY_NO_VALUE;
+}
diff --git a/src/input/inputmanager.h b/src/input/inputmanager.h
new file mode 100644
index 000000000..8611e19c3
--- /dev/null
+++ b/src/input/inputmanager.h
@@ -0,0 +1,191 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2012-2013 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef INPUT_INPUTMANAGER_H
+#define INPUT_INPUTMANAGER_H
+
+#include "input/inputevent.h"
+#include "input/keydata.h"
+
+#include <string>
+#include <map>
+
+#include <SDL.h>
+
+const unsigned int KeyFunctionSize = 3;
+
+// hack to avoid conflicts with windows headers.
+#ifdef INPUT_KEYBOARD
+#undef INPUT_KEYBOARD
+#endif
+#ifdef INPUT_MOUSE
+#undef INPUT_MOUSE
+#endif
+
+struct KeyData;
+
+class Setup_Input;
+
+enum KeyTypes
+{
+ INPUT_UNKNOWN = 0,
+ INPUT_KEYBOARD = 1,
+ INPUT_MOUSE = 2,
+ INPUT_JOYSTICK = 3
+};
+
+struct KeyItem final
+{
+ KeyItem() :
+ type(-1), value(-1)
+ { }
+
+ KeyItem(const int type0, const int value0) :
+ type(type0), value(value0)
+ { }
+
+ int type;
+
+ int value;
+};
+
+struct KeyFunction final
+{
+ KeyItem values[KeyFunctionSize];
+};
+
+enum KeyCondition
+{
+ COND_DEFAULT = 1, // default condition
+ COND_ENABLED = 2, // keyboard must be enabled
+ COND_NOINPUT = 4, // input items must be unfocused
+ COND_NOAWAY = 8, // player not in away mode
+ COND_NOSETUP = 16, // setup window is hidde
+ COND_VALIDSPEED = 32, // valid speed
+ COND_NOMODAL = 64, // modal windows inactive
+ COND_NONPCINPUT = 128, // npc input field inactive
+ COND_EMODS = 256, // game modifiers enabled
+ COND_NOTARGET = 512, // no target/untarget keys
+ // pressed
+ COND_NOFOLLOW = 1024, // follow mode disabled
+ COND_INGAME = 2048, // game must be started
+ COND_SHORTCUT = 2 + 4 + 16 + 512 + 2048, // flags for shortcut keys
+ COND_SHORTCUT0 = 2 + 4 + 16 + 512, // flags for shortcut keys
+ COND_GAME = 2 + 4 + 8 + 16 + 64 + 2048, // main game key
+ COND_GAME2 = 2 + 8 + 16 + 64 + 2048
+};
+
+class InputManager final
+{
+ public:
+ InputManager();
+
+ A_DELETE_COPY(InputManager)
+
+ void init();
+
+ bool handleEvent(const SDL_Event &event);
+
+ bool checkKey(const KeyData *const key) const A_WARN_UNUSED;
+
+ void retrieve();
+
+ void store() const;
+
+ void resetKeys();
+
+ void makeDefault(const int i);
+
+ bool hasConflicts(int &key1, int &key2) const A_WARN_UNUSED;
+
+ void callbackNewKey();
+
+ KeyFunction &getKey(int index) A_WARN_UNUSED;
+
+ std::string getKeyValueString(const int index) const A_WARN_UNUSED;
+
+ std::string getKeyStringLong(const int index) const A_WARN_UNUSED;
+
+ std::string getKeyValueByName(const std::string &keyName);
+
+ void addActionKey(const int action, const int type, const int val);
+
+ void setNewKey(const SDL_Event &event, const int type);
+
+ void unassignKey();
+
+ static bool isActionActive(const int index) A_WARN_UNUSED;
+
+ /**
+ * Set the index of the new key to be assigned.
+ */
+ void setNewKeyIndex(const int value)
+ { mNewKeyIndex = value; }
+
+ /**
+ * Set a reference to the key setup window.
+ */
+ void setSetupInput(Setup_Input *const setupInput)
+ { mSetupInput = setupInput; }
+
+ /**
+ * Get the index of the new key to be assigned.
+ */
+ int getNewKeyIndex() const A_WARN_UNUSED
+ { return mNewKeyIndex; }
+
+ void updateKeyActionMap(KeyToActionMap &actionMap,
+ KeyToIdMap &idMap, KeyTimeMap &keyTimeMap,
+ const int type) const;
+
+ bool invokeKey(const KeyData *const key, const int keyNum);
+
+ bool handleAssignKey(const SDL_Event &event, const int type);
+
+ void handleRepeat() const;
+
+ bool triggerAction(const KeysVector *const ptrs);
+
+ int getKeyIndex(const int value, const int grp,
+ const int type) const A_WARN_UNUSED;
+
+ void update() const;
+
+ void updateConditionMask();
+
+ int getActionByKey(const SDL_Event &event) const A_WARN_UNUSED;
+
+ void executeAction(const int keyNum);
+
+ protected:
+ Setup_Input *mSetupInput; /**< Reference to setup window */
+
+ int mNewKeyIndex; /**< Index of new key to be assigned */
+
+ int mMask;
+
+ std::map<std::string, int> mNameMap;
+
+ KeyFunction mKey[Input::KEY_TOTAL]; /**< Pointer to all the key data */
+};
+
+extern InputManager inputManager;
+
+#endif // INPUT_INPUTMANAGER_H
diff --git a/src/input/joystick.cpp b/src/input/joystick.cpp
new file mode 100644
index 000000000..99a751525
--- /dev/null
+++ b/src/input/joystick.cpp
@@ -0,0 +1,369 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ * Copyright (C) 2011-2013 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "input/joystick.h"
+
+#include "client.h"
+#include "configuration.h"
+#include "logger.h"
+#include "sdlshared.h"
+
+#include "input/inputmanager.h"
+
+#include "debug.h"
+
+int Joystick::joystickCount = 0;
+bool Joystick::mEnabled = false;
+
+Joystick::Joystick(const int no):
+ mDirection(0),
+ mJoystick(nullptr),
+ mUpTolerance(0),
+ mDownTolerance(0),
+ mLeftTolerance(0),
+ mRightTolerance(0),
+ mCalibrating(false),
+ mNumber(no >= joystickCount ? joystickCount : no),
+ mCalibrated(false),
+ mButtonsNumber(MAX_BUTTONS),
+ mUseInactive(false),
+ mHaveHats(false),
+ mKeyToAction(),
+ mKeyToId(),
+ mKeyTimeMap()
+{
+ for (int i = 0; i < MAX_BUTTONS; i++)
+ mActiveButtons[i] = false;
+}
+
+Joystick::~Joystick()
+{
+ close();
+}
+
+void Joystick::init()
+{
+ SDL_InitSubSystem(SDL_INIT_JOYSTICK);
+ SDL_JoystickEventState(SDL_ENABLE);
+ joystickCount = SDL_NumJoysticks();
+ logger->log("%i joysticks/gamepads found", joystickCount);
+ for (int i = 0; i < joystickCount; i++)
+ logger->log("- %s", SDL_JoystickNameForIndex(i));
+
+ mEnabled = config.getBoolValue("joystickEnabled");
+
+ if (joystickCount > 0)
+ {
+ joystick = new Joystick(config.getIntValue("selectedJoystick"));
+ if (mEnabled)
+ joystick->open();
+ }
+}
+
+bool Joystick::open()
+{
+ if (mNumber >= joystickCount)
+ mNumber = joystickCount - 1;
+ if (mNumber < 0)
+ {
+ logger->log1("error: incorrect joystick selection");
+ return false;
+ }
+ logger->log("open joystick %d", mNumber);
+
+ mJoystick = SDL_JoystickOpen(mNumber);
+
+ if (!mJoystick)
+ {
+ logger->log("Couldn't open joystick: %s", SDL_GetError());
+ return false;
+ }
+
+ mButtonsNumber = SDL_JoystickNumButtons(mJoystick);
+ logger->log("Joystick: %i ", mNumber);
+ logger->log("Axes: %i ", SDL_JoystickNumAxes(mJoystick));
+ logger->log("Balls: %i", SDL_JoystickNumBalls(mJoystick));
+ logger->log("Hats: %i", SDL_JoystickNumHats(mJoystick));
+ logger->log("Buttons: %i", mButtonsNumber);
+
+ mHaveHats = (SDL_JoystickNumHats(mJoystick) > 0);
+
+ if (mButtonsNumber > MAX_BUTTONS)
+ mButtonsNumber = MAX_BUTTONS;
+
+ mCalibrated = config.getValueBool("joystick"
+ + toString(mNumber) + "calibrated", false);
+ mUpTolerance = config.getIntValue("upTolerance" + toString(mNumber));
+ mDownTolerance = config.getIntValue("downTolerance" + toString(mNumber));
+ mLeftTolerance = config.getIntValue("leftTolerance" + toString(mNumber));
+ mRightTolerance = config.getIntValue("rightTolerance" + toString(mNumber));
+ mUseInactive = config.getBoolValue("useInactiveJoystick");
+
+ return true;
+}
+
+void Joystick::close()
+{
+ logger->log("close joystick %d", mNumber);
+ if (mJoystick)
+ {
+ SDL_JoystickClose(mJoystick);
+ mJoystick = nullptr;
+ }
+}
+
+void Joystick::reload()
+{
+ joystickCount = SDL_NumJoysticks();
+ setNumber(mNumber);
+}
+
+void Joystick::setNumber(const int n)
+{
+ if (mJoystick)
+ {
+ SDL_JoystickClose(mJoystick);
+ mNumber = n;
+ open();
+ }
+ else
+ {
+ mNumber = n;
+ }
+}
+
+void Joystick::logic()
+{
+ // When calibrating, don't bother the outside with our state
+ if (mCalibrating)
+ {
+ doCalibration();
+ return;
+ };
+
+ if (!mEnabled || !mCalibrated)
+ return;
+
+ mDirection = 0;
+
+ if (mUseInactive || client->getInputFocused())
+ {
+ // X-Axis
+ int position = SDL_JoystickGetAxis(mJoystick, 0);
+ if (position >= mRightTolerance)
+ mDirection |= RIGHT;
+ else if (position <= mLeftTolerance)
+ mDirection |= LEFT;
+
+ // Y-Axis
+ position = SDL_JoystickGetAxis(mJoystick, 1);
+ if (position <= mUpTolerance)
+ mDirection |= UP;
+ else if (position >= mDownTolerance)
+ mDirection |= DOWN;
+
+#ifdef DEBUG_JOYSTICK
+ if (SDL_JoystickGetAxis(mJoystick, 2))
+ logger->log("axis 2 pos: %d", SDL_JoystickGetAxis(mJoystick, 2));
+ if (SDL_JoystickGetAxis(mJoystick, 3))
+ logger->log("axis 3 pos: %d", SDL_JoystickGetAxis(mJoystick, 3));
+ if (SDL_JoystickGetAxis(mJoystick, 4))
+ logger->log("axis 4 pos: %d", SDL_JoystickGetAxis(mJoystick, 4));
+#endif
+
+ if (!mDirection && mHaveHats)
+ {
+ // reading only hat 0
+ const uint8_t hat = SDL_JoystickGetHat(mJoystick, 0);
+ if (hat & SDL_HAT_RIGHT)
+ mDirection |= RIGHT;
+ else if (hat & SDL_HAT_LEFT)
+ mDirection |= LEFT;
+ if (hat & SDL_HAT_UP)
+ mDirection |= UP;
+ else if (hat & SDL_HAT_DOWN)
+ mDirection |= DOWN;
+ }
+
+ // Buttons
+ for (int i = 0; i < mButtonsNumber; i++)
+ {
+ const bool state = (SDL_JoystickGetButton(mJoystick, i) == 1);
+ mActiveButtons[i] = state;
+ if (!state)
+ resetRepeat(i);
+#ifdef DEBUG_JOYSTICK
+ if (mActiveButtons[i])
+ logger->log("button: %d", i);
+#endif
+ }
+ }
+ else
+ {
+ for (int i = 0; i < mButtonsNumber; i++)
+ mActiveButtons[i] = false;
+ }
+}
+
+void Joystick::startCalibration()
+{
+ mUpTolerance = 0;
+ mDownTolerance = 0;
+ mLeftTolerance = 0;
+ mRightTolerance = 0;
+ mCalibrating = true;
+}
+
+void Joystick::doCalibration()
+{
+ // X-Axis
+ int position = SDL_JoystickGetAxis(mJoystick, 0);
+ if (position > mRightTolerance)
+ mRightTolerance = position;
+ else if (position < mLeftTolerance)
+ mLeftTolerance = position;
+
+ // Y-Axis
+ position = SDL_JoystickGetAxis(mJoystick, 1);
+ if (position > mDownTolerance)
+ mDownTolerance = position;
+ else if (position < mUpTolerance)
+ mUpTolerance = position;
+}
+
+void Joystick::finishCalibration()
+{
+ mCalibrated = true;
+ mCalibrating = false;
+ config.setValue("joystick" + toString(mNumber) + "calibrated", true);
+ config.setValue("leftTolerance" + toString(mNumber), mLeftTolerance);
+ config.setValue("rightTolerance" + toString(mNumber), mRightTolerance);
+ config.setValue("upTolerance" + toString(mNumber), mUpTolerance);
+ config.setValue("downTolerance" + toString(mNumber), mDownTolerance);
+}
+
+bool Joystick::buttonPressed(const unsigned char no) const
+{
+ return (mEnabled && no < MAX_BUTTONS) ? mActiveButtons[no] : false;
+}
+
+void Joystick::getNames(std::vector <std::string> &names)
+{
+ names.clear();
+ for (int i = 0; i < joystickCount; i++)
+ names.push_back(SDL_JoystickNameForIndex(i));
+}
+
+void Joystick::update()
+{
+ inputManager.updateKeyActionMap(mKeyToAction, mKeyToId,
+ mKeyTimeMap, INPUT_JOYSTICK);
+}
+
+KeysVector *Joystick::getActionVector(const SDL_Event &event)
+{
+ const int i = getButtonFromEvent(event);
+
+ if (i < 0 || i >= mButtonsNumber)
+ return nullptr;
+// logger->log("button triggerAction: %d", i);
+ if (mKeyToAction.find(i) != mKeyToAction.end())
+ return &mKeyToAction[i];
+ return nullptr;
+}
+
+KeysVector *Joystick::getActionVectorByKey(const 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)
+ return -1;
+ return event.jbutton.button;
+}
+
+bool Joystick::isActionActive(const int index) const
+{
+ if (!validate())
+ return false;
+
+ const KeyFunction &key = inputManager.getKey(index);
+ for (size_t i = 0; i < KeyFunctionSize; i ++)
+ {
+ const KeyItem &val = key.values[i];
+ if (val.type != INPUT_JOYSTICK)
+ continue;
+ const int value = val.value;
+ if (value >= 0 && value < mButtonsNumber)
+ {
+ if (mActiveButtons[value])
+ return true;
+ }
+ }
+ return false;
+}
+
+bool Joystick::validate() const
+{
+ if (mCalibrating || !mEnabled || !mCalibrated)
+ return false;
+
+ return (mUseInactive || client->getInputFocused());
+}
+
+void Joystick::handleRepeat(const int time)
+{
+ FOR_EACH (KeyTimeMapIter, it, mKeyTimeMap)
+ {
+ bool repeat(false);
+ const int key = (*it).first;
+ int &keyTime = (*it).second;
+ if (key >= 0 && key < mButtonsNumber)
+ {
+ if (mActiveButtons[key])
+ repeat = true;
+ }
+ if (repeat)
+ {
+ if (time > keyTime && abs(time - keyTime)
+ > SDL_DEFAULT_REPEAT_DELAY * 10)
+ {
+ keyTime = time;
+ inputManager.triggerAction(getActionVectorByKey(key));
+ }
+ }
+ }
+}
+
+void Joystick::resetRepeat(const int key)
+{
+ const KeyTimeMapIter it = mKeyTimeMap.find(key);
+ if (it != mKeyTimeMap.end())
+ (*it).second = tick_time;
+}
diff --git a/src/input/joystick.h b/src/input/joystick.h
new file mode 100644
index 000000000..528eb0c94
--- /dev/null
+++ b/src/input/joystick.h
@@ -0,0 +1,175 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ * Copyright (C) 2011-2013 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef INPUT_JOYSTICK_H
+#define INPUT_JOYSTICK_H
+
+#include "input/inputevent.h"
+
+#include <SDL.h>
+
+#include <string>
+#include <vector>
+
+class Joystick final
+{
+ public:
+ /**
+ * Number of buttons we can handle.
+ */
+ enum
+ {
+ MAX_BUTTONS = 64
+ };
+
+ /**
+ * Directions, to be used as bitmask values.
+ */
+ enum
+ {
+ UP = 1,
+ DOWN = 2,
+ LEFT = 4,
+ RIGHT = 8
+ };
+
+ /**
+ * Initializes the joystick subsystem.
+ */
+ static void init();
+
+ /**
+ * Returns the number of available joysticks.
+ */
+ static int getNumberOfJoysticks() A_WARN_UNUSED
+ { return joystickCount; }
+
+ /**
+ * Constructor, pass the number of the joystick the new object
+ * should access.
+ */
+ explicit Joystick(const int no);
+
+ A_DELETE_COPY(Joystick)
+
+ ~Joystick();
+
+ bool open();
+
+ void close();
+
+ bool isEnabled() const A_WARN_UNUSED
+ { return mEnabled; }
+
+ void setNumber(const int n);
+
+ static void setEnabled(const bool enabled)
+ { mEnabled = enabled; }
+
+ static void getNames(std::vector <std::string> &names);
+
+ /**
+ * Updates the direction and button information.
+ */
+ void logic();
+
+ void startCalibration();
+
+ void finishCalibration();
+
+ bool isCalibrating() const A_WARN_UNUSED
+ { return mCalibrating; }
+
+ bool buttonPressed(const unsigned char no) const A_WARN_UNUSED;
+
+ bool isUp() const A_WARN_UNUSED
+ { return mEnabled && (mDirection & UP); }
+
+ bool isDown() const A_WARN_UNUSED
+ { return mEnabled && (mDirection & DOWN); }
+
+ bool isLeft() const A_WARN_UNUSED
+ { return mEnabled && (mDirection & LEFT); }
+
+ bool isRight() const A_WARN_UNUSED
+ { return mEnabled && (mDirection & RIGHT); }
+
+ int getNumber() const A_WARN_UNUSED
+ { return mNumber; }
+
+ void setUseInactive(const bool b)
+ { mUseInactive = b; }
+
+ void update();
+
+ KeysVector *getActionVector(const SDL_Event &event) A_WARN_UNUSED;
+
+ KeysVector *getActionVectorByKey(const int i) A_WARN_UNUSED;
+
+ int getButtonFromEvent(const SDL_Event &event) const A_WARN_UNUSED;
+
+ bool isActionActive(const int index) const A_WARN_UNUSED;
+
+ bool validate() const A_WARN_UNUSED;
+
+ void handleRepeat(const int time);
+
+ void resetRepeat(const int key);
+
+ void reload();
+
+ protected:
+ unsigned char mDirection;
+
+ bool mActiveButtons[MAX_BUTTONS];
+
+ SDL_Joystick *mJoystick;
+
+ int mUpTolerance;
+ int mDownTolerance;
+ int mLeftTolerance;
+ int mRightTolerance;
+ bool mCalibrating;
+ int mNumber;
+ bool mCalibrated;
+ int mButtonsNumber;
+ bool mUseInactive;
+ bool mHaveHats;
+
+ KeyToActionMap mKeyToAction;
+
+ KeyToIdMap mKeyToId;
+
+ KeyTimeMap mKeyTimeMap;
+
+ /**
+ * Is joystick support enabled.
+ */
+ static bool mEnabled;
+ static int joystickCount;
+
+ void doCalibration();
+};
+
+extern Joystick *joystick;
+
+#endif // INPUT_JOYSTICK_H
diff --git a/src/input/keyboardconfig.cpp b/src/input/keyboardconfig.cpp
new file mode 100644
index 000000000..87d7a8d69
--- /dev/null
+++ b/src/input/keyboardconfig.cpp
@@ -0,0 +1,283 @@
+/*
+ * Custom keyboard shortcuts configuration
+ * Copyright (C) 2007 Joshua Langley <joshlangley@optusnet.com.au>
+ * Copyright (C) 2009-2010 The Mana Developers
+ * Copyright (C) 2011-2013 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "input/keyboardconfig.h"
+
+#include "configuration.h"
+#include "logger.h"
+
+#include "input/inputmanager.h"
+
+#include "utils/gettext.h"
+
+#include <SDL_events.h>
+
+#include "debug.h"
+
+extern volatile int tick_time;
+
+KeyboardConfig::KeyboardConfig() :
+ mEnabled(true),
+ mActiveKeys(nullptr),
+ mActiveKeys2(nullptr),
+ mRepeatTime(0),
+ mKeyToAction(),
+ mKeyToId(),
+ mKeyTimeMap()
+{
+}
+
+void KeyboardConfig::init()
+{
+ mEnabled = true;
+ delete mActiveKeys2;
+ mActiveKeys2 = new uint8_t[500];
+ mRepeatTime = config.getIntValue("repeateInterval2") / 10;
+}
+
+void KeyboardConfig::deinit()
+{
+ delete [] mActiveKeys2;
+ mActiveKeys2 = nullptr;
+}
+
+int KeyboardConfig::getKeyValueFromEvent(const SDL_Event &event) const
+{
+#ifdef USE_SDL2
+ return event.key.keysym.scancode;
+#else
+ if (event.key.keysym.sym)
+ return event.key.keysym.sym;
+ else if (event.key.keysym.scancode > 1)
+ return -event.key.keysym.scancode;
+#endif
+ return 0;
+}
+
+int KeyboardConfig::getKeyIndex(const SDL_Event &event, const int grp) const
+{
+ const int keyValue = getKeyValueFromEvent(event);
+ return inputManager.getKeyIndex(keyValue, grp, INPUT_KEYBOARD);
+}
+
+void KeyboardConfig::refreshActiveKeys()
+{
+ mActiveKeys = SDL_GetKeyState(nullptr);
+}
+
+std::string KeyboardConfig::getKeyName(const int key)
+{
+ if (key == Input::KEY_NO_VALUE)
+ return "";
+ if (key >= 0)
+ {
+#ifdef USE_SDL2
+ return SDL_GetKeyName(SDL_GetKeyFromScancode(
+ static_cast<SDL_Scancode>(key)));
+#else
+ return SDL_GetKeyName(static_cast<SDLKey>(key));
+#endif
+ }
+
+ // TRANSLATORS: long key name, should be short
+ return strprintf(_("key_%d"), key);
+}
+
+std::string KeyboardConfig::getKeyShortString(const std::string &key)
+{
+ if (key == "backspace")
+ return "bksp";
+ else if (key == "numlock")
+ return "numlock";
+ else if (key == "caps lock")
+ return "caplock";
+ else if (key == "scroll lock")
+ return "scrlock";
+ else if (key == "right shift")
+ return "rshift";
+ else if (key == "left shift")
+ return "lshift";
+ else if (key == "right ctrl")
+ return "rctrl";
+ else if (key == "left ctrl")
+ return "lctrl";
+ else if (key == "right alt")
+ return "ralt";
+ else if (key == "left alt")
+ return "lalt";
+ else if (key == "right meta")
+ return "rmeta";
+ else if (key == "left meta")
+ return "lmeta";
+ else if (key == "right super")
+ return "rsuper";
+ else if (key == "left super")
+ return "lsuper";
+ else if (key == "print screen")
+ return "print screen";
+ else if (key == "page up")
+ return "pg up";
+ else if (key == "page down")
+ return "pg down";
+
+ if (key == "unknown key")
+ {
+ // TRANSLATORS: Unknown key short string.
+ // TRANSLATORS: This string must be maximum 5 chars
+ return _("u key");
+ }
+ return key;
+}
+
+SDLKey KeyboardConfig::getKeyFromEvent(const SDL_Event &event)
+{
+#ifdef USE_SDL2
+ return event.key.keysym.scancode;
+#else
+ return event.key.keysym.sym;
+#endif
+}
+
+KeysVector *KeyboardConfig::getActionVector(const SDL_Event &event)
+{
+ const int i = getKeyValueFromEvent(event);
+// logger->log("key triggerAction: %d", i);
+ if (i != 0 && i < SDLK_LAST && mKeyToAction.find(i) != mKeyToAction.end())
+ return &mKeyToAction[i];
+ return nullptr;
+}
+
+KeysVector *KeyboardConfig::getActionVectorByKey(const 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);
+// logger->log("getActionId: %d", i);
+ if (i != 0 && i < SDLK_LAST && mKeyToId.find(i) != mKeyToId.end())
+ return mKeyToId[i];
+ return -1;
+}
+
+bool KeyboardConfig::isActionActive(const int index) const
+{
+ if (!mActiveKeys)
+ return false;
+
+ const KeyFunction &key = inputManager.getKey(index);
+ for (size_t i = 0; i < KeyFunctionSize; i ++)
+ {
+ const KeyItem &val = key.values[i];
+ if (val.type != INPUT_KEYBOARD)
+ continue;
+
+ const int value = val.value;
+ if (value >= 0)
+ {
+ if (mActiveKeys[value])
+ return true;
+ }
+ else if (value < -1 && value > -500)
+ {
+ if (mActiveKeys2[-value])
+ return true;
+ }
+ }
+ return false;
+}
+
+void KeyboardConfig::update()
+{
+ inputManager.updateKeyActionMap(mKeyToAction, mKeyToId,
+ mKeyTimeMap, INPUT_KEYBOARD);
+}
+
+void KeyboardConfig::handleActicateKey(const SDL_Event &event)
+{
+ const int key = getKeyValueFromEvent(event);
+ if (key < -1 && key > -500)
+ mActiveKeys2[-key] = 1;
+ resetRepeat(key);
+}
+
+void KeyboardConfig::handleActicateKey(const int key)
+{
+ if (key < -1 && key > -500)
+ mActiveKeys2[-key] = 1;
+ resetRepeat(key);
+}
+
+void KeyboardConfig::handleDeActicateKey(const SDL_Event &event)
+{
+ const int key = getKeyValueFromEvent(event);
+ if (key < -1 && key > -500)
+ mActiveKeys2[-key] = 0;
+ resetRepeat(key);
+}
+
+void KeyboardConfig::handleDeActicateKey(const int key)
+{
+ if (key < -1 && key > -500)
+ mActiveKeys2[-key] = 0;
+ resetRepeat(key);
+}
+
+void KeyboardConfig::handleRepeat(const int time)
+{
+ FOR_EACH (KeyTimeMapIter, it, mKeyTimeMap)
+ {
+ bool repeat(false);
+ const int key = (*it).first;
+ int &keyTime = (*it).second;
+ if (key >= 0)
+ {
+ if (mActiveKeys && mActiveKeys[key])
+ repeat = true;
+ }
+ else if (key < -1 && key > -500)
+ {
+ if (mActiveKeys2 && mActiveKeys2[-key])
+ repeat = true;
+ }
+ if (repeat)
+ {
+ if (time > keyTime && abs(time - keyTime)
+ > static_cast<signed>(mRepeatTime))
+ {
+ keyTime = time;
+ inputManager.triggerAction(getActionVectorByKey(key));
+ }
+ }
+ }
+}
+
+void KeyboardConfig::resetRepeat(const int key)
+{
+ const KeyTimeMapIter it = mKeyTimeMap.find(key);
+ if (it != mKeyTimeMap.end())
+ (*it).second = tick_time;
+}
diff --git a/src/input/keyboardconfig.h b/src/input/keyboardconfig.h
new file mode 100644
index 000000000..f6152fa1a
--- /dev/null
+++ b/src/input/keyboardconfig.h
@@ -0,0 +1,125 @@
+/*
+ * Custom keyboard shortcuts configuration
+ * Copyright (C) 2007 Joshua Langley <joshlangley@optusnet.com.au>
+ * Copyright (C) 2009-2010 The Mana Developers
+ * Copyright (C) 2011-2013 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef INPUT_KEYBOARDCONFIG_H
+#define INPUT_KEYBOARDCONFIG_H
+
+#include <SDL_types.h>
+#include <SDL_keyboard.h>
+
+#include "sdlshared.h"
+
+#include "input/inputevent.h"
+
+#include <map>
+#include <string>
+#include <vector>
+
+union SDL_Event;
+
+class KeyboardConfig final
+{
+ public:
+ KeyboardConfig();
+
+ A_DELETE_COPY(KeyboardConfig)
+
+ /**
+ * Initializes the keyboard config explicitly.
+ */
+ void init();
+
+ void deinit();
+
+ /**
+ * Get the enable flag, which will stop the user from doing actions.
+ */
+ bool isEnabled() const A_WARN_UNUSED
+ { return mEnabled; }
+
+ /**
+ * Get the key function index by providing the keys value.
+ */
+ int getKeyIndex(const SDL_Event &event,
+ const int grp = 1) const A_WARN_UNUSED;
+
+ /**
+ * Set the enable flag, which will stop the user from doing actions.
+ */
+ void setEnabled(const bool flag)
+ { mEnabled = flag; }
+
+ /**
+ * Takes a snapshot of all the active keys.
+ */
+ void refreshActiveKeys();
+
+ static std::string getKeyShortString(const std::string &key)
+ A_WARN_UNUSED;
+
+ static SDLKey getKeyFromEvent(const SDL_Event &event) A_WARN_UNUSED;
+
+ int getKeyValueFromEvent(const SDL_Event &event) const A_WARN_UNUSED;
+
+ KeysVector *getActionVector(const SDL_Event &event) A_WARN_UNUSED;
+
+ KeysVector *getActionVectorByKey(const int i) A_WARN_UNUSED;
+
+ static std::string getKeyName(const int key)A_WARN_UNUSED;
+
+ bool isActionActive(const int index) const A_WARN_UNUSED;
+
+ void update();
+
+ void handleActicateKey(const SDL_Event &event);
+
+ void handleActicateKey(const int key);
+
+ void handleDeActicateKey(const SDL_Event &event);
+
+ void handleDeActicateKey(const int key);
+
+ int getActionId(const SDL_Event &event) A_WARN_UNUSED;
+
+ void handleRepeat(const int time);
+
+ void resetRepeat(const int key);
+
+ private:
+ bool mEnabled; /**< Flag to respond to key input */
+
+ const uint8_t *mActiveKeys; /**< Stores a list of all the keys */
+
+ uint8_t *mActiveKeys2; /**< Stores a list of all the keys */
+
+ unsigned int mRepeatTime;
+
+ KeyToActionMap mKeyToAction;
+
+ KeyToIdMap mKeyToId;
+
+ KeyTimeMap mKeyTimeMap;
+};
+
+extern KeyboardConfig keyboard;
+
+#endif // INPUT_KEYBOARDCONFIG_H
diff --git a/src/input/keyboarddata.h b/src/input/keyboarddata.h
new file mode 100644
index 000000000..bd5395007
--- /dev/null
+++ b/src/input/keyboarddata.h
@@ -0,0 +1,1965 @@
+/*
+ * Custom keyboard shortcuts configuration
+ * Copyright (C) 2007 Joshua Langley <joshlangley@optusnet.com.au>
+ * Copyright (C) 2009-2010 The Mana Developers
+ * Copyright (C) 2011-2013 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef INPUT_KEYBOARDDATA_H
+#define INPUT_KEYBOARDDATA_H
+
+#include "actionmanager.h"
+#include "localconsts.h"
+
+#include "input/inputmanager.h"
+
+#include "utils/gettext.h"
+
+#include <string>
+
+// keyData must be in same order as enum keyAction.
+static const KeyData keyData[Input::KEY_TOTAL] = {
+ {"keyMoveUp",
+ INPUT_KEYBOARD, SDLK_UP,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::moveUp,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME2},
+ {"keyMoveDown",
+ INPUT_KEYBOARD, SDLK_DOWN,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::moveDown,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME2},
+ {"keyMoveLeft",
+ INPUT_KEYBOARD, SDLK_LEFT,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::moveLeft,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME},
+ {"keyMoveRight",
+ INPUT_KEYBOARD, SDLK_RIGHT,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::moveRight,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME},
+ {"keyAttack",
+ INPUT_KEYBOARD, SDLK_LCTRL,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT | Input::GRP_REPEAT,
+ &ActionManager::attack,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_NOFOLLOW | COND_VALIDSPEED},
+ {"keyTargetAttack",
+ INPUT_KEYBOARD, SDLK_x,
+ INPUT_JOYSTICK, 0,
+ Input::GRP_DEFAULT,
+ &ActionManager::targetAttack,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_NOFOLLOW | COND_VALIDSPEED},
+ {"keyMoveToTarget",
+ INPUT_KEYBOARD, SDLK_v,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::moveToTarget,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_VALIDSPEED},
+ {"keyChangeMoveToTarget",
+ INPUT_KEYBOARD, SDLK_PERIOD,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::changeMoveToTarget,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_VALIDSPEED | COND_EMODS},
+ {"keyMoveToHome",
+ INPUT_KEYBOARD, SDLK_d,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::moveToHome,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_VALIDSPEED},
+ {"keySetHome",
+ INPUT_KEYBOARD, SDLK_KP5,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::setHome,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_VALIDSPEED},
+ {"keyMoveToPoint",
+ INPUT_KEYBOARD, SDLK_RSHIFT,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ nullptr,
+ Input::KEY_NO_VALUE, 50,
+ COND_DEFAULT | COND_INGAME},
+ {"keyTalk",
+ INPUT_KEYBOARD, SDLK_t,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::talk,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME},
+ {"keyTarget",
+ INPUT_KEYBOARD, SDLK_LSHIFT,
+ INPUT_JOYSTICK, 4,
+ Input::GRP_DEFAULT,
+ &ActionManager::stopAttack,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME},
+ {"keyUnTarget",
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::untarget,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME},
+ {"keyTargetMonster",
+ INPUT_KEYBOARD, SDLK_a,
+ INPUT_JOYSTICK, 3,
+ Input::GRP_DEFAULT | Input::GRP_REPEAT,
+ &ActionManager::targetMonster,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_NOTARGET | COND_VALIDSPEED},
+ {"keyTargetNPC",
+ INPUT_KEYBOARD, SDLK_n,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::targetNPC,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_NOTARGET},
+ {"keyTargetPlayer",
+ INPUT_KEYBOARD, SDLK_q,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::targetPlayer,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_NOTARGET},
+ {"keyPickup",
+ INPUT_KEYBOARD, SDLK_z,
+ INPUT_JOYSTICK, 1,
+ Input::GRP_DEFAULT,
+ &ActionManager::pickup,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_NOTARGET},
+ {"keyChangePickupType",
+ INPUT_KEYBOARD, SDLK_o,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::changePickupType,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_VALIDSPEED | COND_EMODS},
+ {"keyHideWindows",
+ INPUT_KEYBOARD, SDLK_h,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT | Input::GRP_GUI,
+ &ActionManager::hideWindows,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_NOTARGET},
+ {"keyBeingSit",
+ INPUT_KEYBOARD, SDLK_s,
+ INPUT_JOYSTICK, 2,
+ Input::GRP_DEFAULT,
+ &ActionManager::sit,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_NOTARGET},
+ {"keyScreenshot",
+ INPUT_KEYBOARD, SDLK_p,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::screenshot,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_NOTARGET},
+ {"keyTrade",
+ INPUT_KEYBOARD, SDLK_r,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::changeTrade,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_NOTARGET},
+ {"keyPathfind",
+ INPUT_KEYBOARD, SDLK_f,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::changeMapMode,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_NOTARGET | COND_EMODS},
+ {"keyOK",
+ INPUT_KEYBOARD, SDLK_SPACE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT | Input::GRP_GUI,
+ &ActionManager::ok,
+ Input::KEY_NO_VALUE, 50,
+ COND_NOMODAL | COND_NOAWAY | COND_NONPCINPUT},
+ {"keyQuit",
+ INPUT_KEYBOARD, SDLK_ESCAPE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::quit,
+ Input::KEY_NO_VALUE, 50,
+ COND_DEFAULT},
+ {"keyShortcutsKey",
+ INPUT_KEYBOARD, SDLK_MENU,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ nullptr,
+ Input::KEY_NO_VALUE, 50,
+ COND_DEFAULT | COND_INGAME},
+ {"keyShortcut1",
+ INPUT_KEYBOARD, SDLK_1,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::shortcut,
+ Input::KEY_NO_VALUE, 50,
+ COND_SHORTCUT},
+ {"keyShortcut2",
+ INPUT_KEYBOARD, SDLK_2,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::shortcut,
+ Input::KEY_NO_VALUE, 50,
+ COND_SHORTCUT},
+ {"keyShortcut3",
+ INPUT_KEYBOARD, SDLK_3,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::shortcut,
+ Input::KEY_NO_VALUE, 50,
+ COND_SHORTCUT},
+ {"keyShortcut4",
+ INPUT_KEYBOARD, SDLK_4,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::shortcut,
+ Input::KEY_NO_VALUE, 50,
+ COND_SHORTCUT},
+ {"keyShortcut5",
+ INPUT_KEYBOARD, SDLK_5,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::shortcut,
+ Input::KEY_NO_VALUE, 50,
+ COND_SHORTCUT},
+ {"keyShortcut6",
+ INPUT_KEYBOARD, SDLK_6,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::shortcut,
+ Input::KEY_NO_VALUE, 50,
+ COND_SHORTCUT},
+ {"keyShortcut7",
+ INPUT_KEYBOARD, SDLK_7,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::shortcut,
+ Input::KEY_NO_VALUE, 50,
+ COND_SHORTCUT},
+ {"keyShortcut8",
+ INPUT_KEYBOARD, SDLK_8,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::shortcut,
+ Input::KEY_NO_VALUE, 50,
+ COND_SHORTCUT},
+ {"keyShortcut9",
+ INPUT_KEYBOARD, SDLK_9,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::shortcut,
+ Input::KEY_NO_VALUE, 50,
+ COND_SHORTCUT},
+ {"keyShortcut10",
+ INPUT_KEYBOARD, SDLK_0,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::shortcut,
+ Input::KEY_NO_VALUE, 50,
+ COND_SHORTCUT},
+ {"keyShortcut11",
+ INPUT_KEYBOARD, SDLK_MINUS,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::shortcut,
+ Input::KEY_NO_VALUE, 50,
+ COND_SHORTCUT},
+ {"keyShortcut12",
+ INPUT_KEYBOARD, SDLK_EQUALS,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::shortcut,
+ Input::KEY_NO_VALUE, 50,
+ COND_SHORTCUT},
+ {"keyShortcut13",
+ INPUT_KEYBOARD, SDLK_BACKSPACE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::shortcut,
+ Input::KEY_NO_VALUE, 50,
+ COND_SHORTCUT},
+ {"keyShortcut14",
+ INPUT_KEYBOARD, SDLK_INSERT,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::shortcut,
+ Input::KEY_NO_VALUE, 50,
+ COND_SHORTCUT},
+ {"keyShortcut15",
+ INPUT_KEYBOARD, SDLK_HOME,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::shortcut,
+ Input::KEY_NO_VALUE, 50,
+ COND_SHORTCUT},
+ {"keyShortcut16",
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::shortcut,
+ Input::KEY_NO_VALUE, 50,
+ COND_SHORTCUT},
+ {"keyShortcut17",
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::shortcut,
+ Input::KEY_NO_VALUE, 50,
+ COND_SHORTCUT},
+ {"keyShortcut18",
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::shortcut,
+ Input::KEY_NO_VALUE, 50,
+ COND_SHORTCUT},
+ {"keyShortcut19",
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::shortcut,
+ Input::KEY_NO_VALUE, 50,
+ COND_SHORTCUT},
+ {"keyShortcut20",
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::shortcut,
+ Input::KEY_NO_VALUE, 50,
+ COND_SHORTCUT},
+ {"keyWindowHelp",
+ INPUT_KEYBOARD, SDLK_F1,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT | Input::GRP_GUI,
+ &ActionManager::helpWindowShow,
+ Input::KEY_NO_VALUE, 50,
+ COND_SHORTCUT0},
+ {"keyWindowStatus",
+ INPUT_KEYBOARD, SDLK_F2,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT | Input::GRP_GUI,
+ &ActionManager::statusWindowShow,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_NOTARGET},
+ {"keyWindowInventory",
+ INPUT_KEYBOARD, SDLK_F3,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT | Input::GRP_GUI,
+ &ActionManager::inventoryWindowShow,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_NOTARGET},
+ {"keyWindowEquipment",
+ INPUT_KEYBOARD, SDLK_F4,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT | Input::GRP_GUI,
+ &ActionManager::equipmentWindowShow,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_NOTARGET},
+ {"keyWindowSkill",
+ INPUT_KEYBOARD, SDLK_F5,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT | Input::GRP_GUI,
+ &ActionManager::skillDialogShow,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_NOTARGET},
+ {"keyWindowMinimap",
+ INPUT_KEYBOARD, SDLK_F6,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT | Input::GRP_GUI,
+ &ActionManager::minimapWindowShow,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_NOTARGET},
+ {"keyWindowChat",
+ INPUT_KEYBOARD, SDLK_F7,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT | Input::GRP_GUI,
+ &ActionManager::chatWindowShow,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_NOTARGET},
+ {"keyWindowShortcut",
+ INPUT_KEYBOARD, SDLK_F8,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT | Input::GRP_GUI,
+ &ActionManager::shortcutWindowShow,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_NOTARGET},
+ {"keyWindowSetup",
+ INPUT_KEYBOARD, SDLK_F9,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT | Input::GRP_GUI,
+ &ActionManager::setupWindowShow,
+ Input::KEY_NO_VALUE, 50,
+ COND_NOTARGET | COND_NOINPUT | COND_ENABLED},
+ {"keyWindowDebug",
+ INPUT_KEYBOARD, SDLK_F10,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT | Input::GRP_GUI,
+ &ActionManager::debugWindowShow,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_NOTARGET},
+ {"keyWindowSocial",
+ INPUT_KEYBOARD, SDLK_F11,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT | Input::GRP_GUI,
+ &ActionManager::socialWindowShow,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_NOTARGET},
+ {"keyWindowEmoteBar",
+ INPUT_KEYBOARD, SDLK_F12,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT | Input::GRP_GUI,
+ &ActionManager::emoteShortcutWindowShow,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_NOTARGET},
+ {"keyWindowOutfit",
+ INPUT_KEYBOARD, SDLK_BACKQUOTE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT | Input::GRP_GUI,
+ &ActionManager::outfitWindowShow,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_NOTARGET},
+ {"keyWindowShop",
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT | Input::GRP_GUI,
+ &ActionManager::shopWindowShow,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_NOTARGET},
+ {"keyWindowDrop",
+ INPUT_KEYBOARD, SDLK_w,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT | Input::GRP_GUI,
+ &ActionManager::dropShortcutWindowShow,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_NOTARGET},
+ {"keyWindowKills",
+ INPUT_KEYBOARD, SDLK_e,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT | Input::GRP_GUI,
+ &ActionManager::killStatsWindowShow,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_NOTARGET},
+ {"keyWindowSpells",
+ INPUT_KEYBOARD, SDLK_j,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT | Input::GRP_GUI,
+ &ActionManager::spellShortcutWindowShow,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_NOTARGET},
+ {"keyWindowBotChecker",
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT | Input::GRP_GUI,
+ &ActionManager::botcheckerWindowShow,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_NOTARGET},
+ {"keyWindowOnline",
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT | Input::GRP_GUI,
+ &ActionManager::whoIsOnlineWindowShow,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_NOTARGET},
+ {"keyWindowDidYouKnow",
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT | Input::GRP_GUI,
+ &ActionManager::didYouKnowWindowShow,
+ Input::KEY_NO_VALUE, 50,
+ COND_SHORTCUT0},
+ {"keyWindowQuests",
+ INPUT_KEYBOARD, SDLK_LEFTBRACKET,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT | Input::GRP_GUI,
+ &ActionManager::questsWindowShow,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_NOTARGET},
+ {"keySocialPrevTab",
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT | Input::GRP_GUI,
+ &ActionManager::prevSocialTab,
+ Input::KEY_NO_VALUE, 50,
+ COND_NOINPUT | COND_INGAME},
+ {"keySocialNextTab",
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT | Input::GRP_GUI,
+ &ActionManager::nextSocialTab,
+ Input::KEY_NO_VALUE, 50,
+ COND_NOINPUT | COND_INGAME},
+ {"keySmilie",
+ INPUT_KEYBOARD, SDLK_LALT,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ nullptr,
+ Input::KEY_NO_VALUE, 50,
+ COND_DEFAULT | COND_INGAME},
+ {"keyEmoteShortcut1",
+ INPUT_KEYBOARD, SDLK_1,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut2",
+ INPUT_KEYBOARD, SDLK_2,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut3",
+ INPUT_KEYBOARD, SDLK_3,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut4",
+ INPUT_KEYBOARD, SDLK_4,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut5",
+ INPUT_KEYBOARD, SDLK_5,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut6",
+ INPUT_KEYBOARD, SDLK_6,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut7",
+ INPUT_KEYBOARD, SDLK_7,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut8",
+ INPUT_KEYBOARD, SDLK_8,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut9",
+ INPUT_KEYBOARD, SDLK_9,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut10",
+ INPUT_KEYBOARD, SDLK_0,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut11",
+ INPUT_KEYBOARD, SDLK_MINUS,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut12",
+ INPUT_KEYBOARD, SDLK_EQUALS,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut13",
+ INPUT_KEYBOARD, SDLK_BACKSPACE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut14",
+ INPUT_KEYBOARD, SDLK_INSERT,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut15",
+ INPUT_KEYBOARD, SDLK_HOME,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut16",
+ INPUT_KEYBOARD, SDLK_q,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut17",
+ INPUT_KEYBOARD, SDLK_w,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut18",
+ INPUT_KEYBOARD, SDLK_e,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut19",
+ INPUT_KEYBOARD, SDLK_r,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut20",
+ INPUT_KEYBOARD, SDLK_t,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut21",
+ INPUT_KEYBOARD, SDLK_y,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut22",
+ INPUT_KEYBOARD, SDLK_u,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut23",
+ INPUT_KEYBOARD, SDLK_i,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut24",
+ INPUT_KEYBOARD, SDLK_o,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut25",
+ INPUT_KEYBOARD, SDLK_p,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut26",
+ INPUT_KEYBOARD, SDLK_LEFTBRACKET,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut27",
+ INPUT_KEYBOARD, SDLK_RIGHTBRACKET,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut28",
+ INPUT_KEYBOARD, SDLK_BACKSLASH,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut29",
+ INPUT_KEYBOARD, SDLK_a,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut30",
+ INPUT_KEYBOARD, SDLK_s,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut31",
+ INPUT_KEYBOARD, SDLK_d,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut32",
+ INPUT_KEYBOARD, SDLK_f,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut33",
+ INPUT_KEYBOARD, SDLK_g,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut34",
+ INPUT_KEYBOARD, SDLK_h,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut35",
+ INPUT_KEYBOARD, SDLK_j,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut36",
+ INPUT_KEYBOARD, SDLK_k,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut37",
+ INPUT_KEYBOARD, SDLK_l,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut38",
+ INPUT_KEYBOARD, SDLK_SEMICOLON,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut39",
+ INPUT_KEYBOARD, SDLK_QUOTE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut40",
+ INPUT_KEYBOARD, SDLK_z,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut41",
+ INPUT_KEYBOARD, SDLK_x,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut42",
+ INPUT_KEYBOARD, SDLK_c,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut43",
+ INPUT_KEYBOARD, SDLK_v,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut44",
+ INPUT_KEYBOARD, SDLK_b,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut45",
+ INPUT_KEYBOARD, SDLK_n,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut46",
+ INPUT_KEYBOARD, SDLK_m,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut47",
+ INPUT_KEYBOARD, SDLK_COMMA,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyEmoteShortcut48",
+ INPUT_KEYBOARD, SDLK_PERIOD,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_EMOTION,
+ &ActionManager::emote,
+ Input::KEY_EMOTE, 100,
+ COND_GAME},
+ {"keyWearOutfit",
+ INPUT_KEYBOARD, SDLK_RCTRL,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ nullptr,
+ Input::KEY_NO_VALUE, 50,
+ COND_DEFAULT | COND_INGAME},
+ {"keyCopyOutfit",
+ INPUT_KEYBOARD, SDLK_RALT,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ nullptr,
+ Input::KEY_NO_VALUE, 50,
+ COND_DEFAULT | COND_INGAME},
+ {"keyCopyEquipedOutfit",
+ INPUT_KEYBOARD, SDLK_RIGHTBRACKET,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::copyEquippedToOutfit,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_VALIDSPEED},
+ {"keyOutfitShortcut1",
+ INPUT_KEYBOARD, SDLK_1,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut2",
+ INPUT_KEYBOARD, SDLK_2,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut3",
+ INPUT_KEYBOARD, SDLK_3,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut4",
+ INPUT_KEYBOARD, SDLK_4,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut5",
+ INPUT_KEYBOARD, SDLK_5,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut6",
+ INPUT_KEYBOARD, SDLK_6,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut7",
+ INPUT_KEYBOARD, SDLK_7,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut8",
+ INPUT_KEYBOARD, SDLK_8,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut9",
+ INPUT_KEYBOARD, SDLK_9,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut10",
+ INPUT_KEYBOARD, SDLK_0,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut11",
+ INPUT_KEYBOARD, SDLK_MINUS,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut12",
+ INPUT_KEYBOARD, SDLK_EQUALS,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut13",
+ INPUT_KEYBOARD, SDLK_BACKSPACE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut14",
+ INPUT_KEYBOARD, SDLK_INSERT,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut15",
+ INPUT_KEYBOARD, SDLK_HOME,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut16",
+ INPUT_KEYBOARD, SDLK_q,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut17",
+ INPUT_KEYBOARD, SDLK_w,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut18",
+ INPUT_KEYBOARD, SDLK_e,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut19",
+ INPUT_KEYBOARD, SDLK_r,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut20",
+ INPUT_KEYBOARD, SDLK_t,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut21",
+ INPUT_KEYBOARD, SDLK_y,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut22",
+ INPUT_KEYBOARD, SDLK_u,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut23",
+ INPUT_KEYBOARD, SDLK_i,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut24",
+ INPUT_KEYBOARD, SDLK_o,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut25",
+ INPUT_KEYBOARD, SDLK_p,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut26",
+ INPUT_KEYBOARD, SDLK_LEFTBRACKET,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut27",
+ INPUT_KEYBOARD, SDLK_RIGHTBRACKET,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut28",
+ INPUT_KEYBOARD, SDLK_BACKSLASH,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut29",
+ INPUT_KEYBOARD, SDLK_a,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut30",
+ INPUT_KEYBOARD, SDLK_s,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut31",
+ INPUT_KEYBOARD, SDLK_d,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut32",
+ INPUT_KEYBOARD, SDLK_f,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut33",
+ INPUT_KEYBOARD, SDLK_g,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut34",
+ INPUT_KEYBOARD, SDLK_h,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut35",
+ INPUT_KEYBOARD, SDLK_j,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut36",
+ INPUT_KEYBOARD, SDLK_k,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut37",
+ INPUT_KEYBOARD, SDLK_l,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut38",
+ INPUT_KEYBOARD, SDLK_SEMICOLON,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut39",
+ INPUT_KEYBOARD, SDLK_QUOTE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut40",
+ INPUT_KEYBOARD, SDLK_z,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut41",
+ INPUT_KEYBOARD, SDLK_x,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut42",
+ INPUT_KEYBOARD, SDLK_c,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut43",
+ INPUT_KEYBOARD, SDLK_v,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut44",
+ INPUT_KEYBOARD, SDLK_b,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut45",
+ INPUT_KEYBOARD, SDLK_n,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut46",
+ INPUT_KEYBOARD, SDLK_m,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut47",
+ INPUT_KEYBOARD, SDLK_COMMA,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyOutfitShortcut48",
+ INPUT_KEYBOARD, SDLK_PERIOD,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_OUTFIT,
+ &ActionManager::outfit,
+ Input::KEY_NO_VALUE, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut1",
+ INPUT_KEYBOARD, SDLK_1,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut2",
+ INPUT_KEYBOARD, SDLK_2,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut3",
+ INPUT_KEYBOARD, SDLK_3,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut4",
+ INPUT_KEYBOARD, SDLK_4,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut5",
+ INPUT_KEYBOARD, SDLK_5,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut6",
+ INPUT_KEYBOARD, SDLK_6,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut7",
+ INPUT_KEYBOARD, SDLK_7,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut8",
+ INPUT_KEYBOARD, SDLK_8,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut9",
+ INPUT_KEYBOARD, SDLK_9,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut10",
+ INPUT_KEYBOARD, SDLK_0,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut11",
+ INPUT_KEYBOARD, SDLK_MINUS,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut12",
+ INPUT_KEYBOARD, SDLK_EQUALS,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut13",
+ INPUT_KEYBOARD, SDLK_BACKSPACE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut14",
+ INPUT_KEYBOARD, SDLK_INSERT,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut15",
+ INPUT_KEYBOARD, SDLK_HOME,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut16",
+ INPUT_KEYBOARD, SDLK_q,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut17",
+ INPUT_KEYBOARD, SDLK_w,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut18",
+ INPUT_KEYBOARD, SDLK_e,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut19",
+ INPUT_KEYBOARD, SDLK_r,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut20",
+ INPUT_KEYBOARD, SDLK_t,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut21",
+ INPUT_KEYBOARD, SDLK_y,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut22",
+ INPUT_KEYBOARD, SDLK_u,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut23",
+ INPUT_KEYBOARD, SDLK_i,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut24",
+ INPUT_KEYBOARD, SDLK_o,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut25",
+ INPUT_KEYBOARD, SDLK_p,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut26",
+ INPUT_KEYBOARD, SDLK_LEFTBRACKET,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut27",
+ INPUT_KEYBOARD, SDLK_RIGHTBRACKET,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut28",
+ INPUT_KEYBOARD, SDLK_BACKSLASH,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut29",
+ INPUT_KEYBOARD, SDLK_a,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut30",
+ INPUT_KEYBOARD, SDLK_s,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut31",
+ INPUT_KEYBOARD, SDLK_d,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut32",
+ INPUT_KEYBOARD, SDLK_f,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut33",
+ INPUT_KEYBOARD, SDLK_g,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut34",
+ INPUT_KEYBOARD, SDLK_h,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut35",
+ INPUT_KEYBOARD, SDLK_j,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut36",
+ INPUT_KEYBOARD, SDLK_k,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut37",
+ INPUT_KEYBOARD, SDLK_l,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut38",
+ INPUT_KEYBOARD, SDLK_SEMICOLON,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut39",
+ INPUT_KEYBOARD, SDLK_QUOTE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut40",
+ INPUT_KEYBOARD, SDLK_z,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut41",
+ INPUT_KEYBOARD, SDLK_x,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut42",
+ INPUT_KEYBOARD, SDLK_c,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut43",
+ INPUT_KEYBOARD, SDLK_v,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut44",
+ INPUT_KEYBOARD, SDLK_b,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut45",
+ INPUT_KEYBOARD, SDLK_n,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut46",
+ INPUT_KEYBOARD, SDLK_m,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut47",
+ INPUT_KEYBOARD, SDLK_COMMA,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyMoveToPointShortcut48",
+ INPUT_KEYBOARD, SDLK_PERIOD,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_MOVETOPOINT,
+ &ActionManager::moveToPoint,
+ Input::KEY_MOVE_TO_POINT, 100,
+ COND_GAME},
+ {"keyChat",
+ INPUT_KEYBOARD, SDLK_RETURN,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT | Input::GRP_CHAT,
+ &ActionManager::toggleChat,
+ Input::KEY_NO_VALUE, 50,
+ COND_NOINPUT | COND_NOAWAY | COND_NOMODAL | COND_INGAME},
+ {"keyChatScrollUp",
+ INPUT_KEYBOARD, SDLK_PAGEUP,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT | Input::GRP_GUI,
+ &ActionManager::scrollChatUp,
+ Input::KEY_NO_VALUE, 50,
+ COND_DEFAULT | COND_INGAME},
+ {"keyChatScrollDown",
+ INPUT_KEYBOARD, SDLK_PAGEDOWN,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT | Input::GRP_GUI,
+ &ActionManager::scrollChatDown,
+ Input::KEY_NO_VALUE, 50,
+ COND_DEFAULT | COND_INGAME},
+ {"keyChatPrevTab",
+ INPUT_KEYBOARD, SDLK_KP7,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT | Input::GRP_GUI,
+ &ActionManager::prevChatTab,
+ Input::KEY_NO_VALUE, 50,
+ COND_NOINPUT | COND_INGAME},
+ {"keyChatNextTab",
+ INPUT_KEYBOARD, SDLK_KP9,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT | Input::GRP_GUI,
+ &ActionManager::nextChatTab,
+ Input::KEY_NO_VALUE, 50,
+ COND_NOINPUT | COND_INGAME},
+ {"keyChatCloseTab",
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT | Input::GRP_GUI,
+ &ActionManager::closeChatTab,
+ Input::KEY_NO_VALUE, 50,
+ COND_NOINPUT | COND_INGAME},
+ {"keyChatPrevHistory",
+ INPUT_KEYBOARD, SDLK_KP7,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_CHAT | Input::GRP_GUICHAN,
+ nullptr,
+ Input::KEY_NO_VALUE, 50,
+ COND_DEFAULT | COND_INGAME},
+ {"keyChatNextHistory",
+ INPUT_KEYBOARD, SDLK_KP9,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_CHAT | Input::GRP_GUICHAN,
+ nullptr,
+ Input::KEY_NO_VALUE, 50,
+ COND_DEFAULT | COND_INGAME},
+ {"keyIgnoreInput1",
+#ifdef USE_SDL2
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+#else
+ INPUT_KEYBOARD, SDLK_LSUPER,
+#endif
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::ignoreInput,
+ Input::KEY_NO_VALUE, 500,
+ COND_DEFAULT},
+ {"keyIgnoreInput2",
+#ifdef USE_SDL2
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+#else
+ INPUT_KEYBOARD, SDLK_RSUPER,
+#endif
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::ignoreInput,
+ Input::KEY_NO_VALUE, 500,
+ COND_DEFAULT},
+ {"keyDirectUp",
+ INPUT_KEYBOARD, SDLK_l,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::directUp,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME},
+ {"keyDirectDown",
+ INPUT_KEYBOARD, SDLK_SEMICOLON,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::directDown,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME},
+ {"keyDirectLeft",
+ INPUT_KEYBOARD, SDLK_k,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::directLeft,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME},
+ {"keyDirectRight",
+ INPUT_KEYBOARD, SDLK_QUOTE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::directRight,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME},
+ {"keyCrazyMoves",
+ INPUT_KEYBOARD, SDLK_SLASH,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::crazyMoves,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_VALIDSPEED},
+ {"keyChangeCrazyMoveType",
+ INPUT_KEYBOARD, SDLK_BACKSLASH,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::changeCrazyMove,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_VALIDSPEED | COND_EMODS},
+ {"keyQuickDrop",
+ INPUT_KEYBOARD, SDLK_y,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::dropItem0,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_VALIDSPEED},
+ {"keyQuickDropN",
+ INPUT_KEYBOARD, SDLK_u,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::dropItem,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_VALIDSPEED},
+ {"keySwitchQuickDrop",
+ INPUT_KEYBOARD, SDLK_i,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::switchQuickDrop,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_VALIDSPEED},
+ {"keyMagicInma1",
+ INPUT_KEYBOARD, SDLK_c,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::heal,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_VALIDSPEED},
+ {"keyMagicItenplz",
+ INPUT_KEYBOARD, SDLK_m,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::itenplz,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_VALIDSPEED},
+ {"keyMagicAttack",
+ INPUT_KEYBOARD, SDLK_b,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::magicAttack,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_VALIDSPEED},
+ {"keySwitchMagicAttack",
+ INPUT_KEYBOARD, SDLK_COMMA,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::changeMagicAttack,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_VALIDSPEED | COND_EMODS},
+ {"keySwitchPvpAttack",
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::changePvpMode,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_VALIDSPEED | COND_EMODS},
+ {"keyInvertDirection",
+ INPUT_KEYBOARD, Input::KEY_NO_VALUE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::changeMoveType,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_VALIDSPEED | COND_EMODS},
+ {"keyChangeAttackWeaponType",
+ INPUT_KEYBOARD, SDLK_g,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::changeAttackWeaponType,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_VALIDSPEED | COND_EMODS},
+ {"keyChangeAttackType",
+ INPUT_KEYBOARD, SDLK_END,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::changeAttackType,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_VALIDSPEED | COND_EMODS},
+ {"keyChangeFollowMode",
+ INPUT_KEYBOARD, SDLK_KP1,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::changeFollowMode,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_VALIDSPEED | COND_EMODS},
+ {"keyChangeImitationMode",
+ INPUT_KEYBOARD, SDLK_KP4,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::changeImitationMode,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_VALIDSPEED | COND_EMODS},
+ {"keyDisableGameModifiers",
+ INPUT_KEYBOARD, SDLK_KP8,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::changeGameModifier,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_VALIDSPEED},
+ {"keyChangeAudio",
+ INPUT_KEYBOARD, SDLK_KP3,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::changeAudio,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_VALIDSPEED},
+ {"keyAway",
+ INPUT_KEYBOARD, SDLK_KP2,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::away,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_VALIDSPEED},
+ {"keyRightClick",
+ INPUT_KEYBOARD, SDLK_TAB,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::mouseClick,
+ Input::KEY_NO_VALUE, 50,
+ COND_NOINPUT | COND_NOAWAY | COND_NOMODAL | COND_INGAME},
+ {"keyCameraMode",
+ INPUT_KEYBOARD, SDLK_KP_PLUS,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::camera,
+ Input::KEY_NO_VALUE, 50,
+ COND_GAME | COND_VALIDSPEED | COND_EMODS},
+ {"keyMod",
+ INPUT_KEYBOARD, SDLK_LSHIFT,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_GUI,
+ nullptr,
+ Input::KEY_NO_VALUE, 50,
+ COND_DEFAULT},
+ {"keyGUIUp",
+ INPUT_KEYBOARD, SDLK_UP,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_GUICHAN,
+ nullptr,
+ Input::KEY_NO_VALUE, 50,
+ COND_DEFAULT},
+ {"keyGUIDown",
+ INPUT_KEYBOARD, SDLK_DOWN,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_GUICHAN,
+ nullptr,
+ Input::KEY_NO_VALUE, 50,
+ COND_DEFAULT},
+ {"keyGUILeft",
+ INPUT_KEYBOARD, SDLK_LEFT,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_GUICHAN,
+ nullptr,
+ Input::KEY_NO_VALUE, 50,
+ COND_DEFAULT},
+ {"keyGUIRight",
+ INPUT_KEYBOARD, SDLK_RIGHT,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_GUICHAN,
+ nullptr,
+ Input::KEY_NO_VALUE, 50,
+ COND_DEFAULT},
+ {"keyGUISelect",
+ INPUT_KEYBOARD, SDLK_SPACE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_GUICHAN,
+ nullptr,
+ Input::KEY_NO_VALUE, 50,
+ COND_DEFAULT},
+ {"keyGUISelect2",
+ INPUT_KEYBOARD, SDLK_RETURN,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_GUICHAN,
+ nullptr,
+ Input::KEY_NO_VALUE, 50,
+ COND_DEFAULT},
+ {"keyGUICancel",
+ INPUT_KEYBOARD, SDLK_ESCAPE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_GUICHAN,
+ nullptr,
+ Input::KEY_NO_VALUE, 50,
+ COND_DEFAULT},
+ {"keyGUIHome",
+ INPUT_KEYBOARD, SDLK_HOME,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_GUICHAN,
+ nullptr,
+ Input::KEY_NO_VALUE, 50,
+ COND_DEFAULT},
+ {"keyGUIEnd",
+ INPUT_KEYBOARD, SDLK_END,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_GUICHAN,
+ nullptr,
+ Input::KEY_NO_VALUE, 50,
+ COND_DEFAULT},
+ {"keyGUIDelete",
+ INPUT_KEYBOARD, SDLK_DELETE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_GUICHAN,
+ nullptr,
+ Input::KEY_NO_VALUE, 50,
+ COND_DEFAULT},
+ {"keyGUIBackSpace",
+ INPUT_KEYBOARD, SDLK_BACKSPACE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_GUICHAN,
+ nullptr,
+ Input::KEY_NO_VALUE, 50,
+ COND_DEFAULT},
+ {"keyGUITab",
+ INPUT_KEYBOARD, SDLK_TAB,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_GUICHAN,
+ nullptr,
+ Input::KEY_NO_VALUE, 50,
+ COND_DEFAULT},
+ {"keyGUIPageUp",
+ INPUT_KEYBOARD, SDLK_PAGEUP,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_GUICHAN,
+ nullptr,
+ Input::KEY_NO_VALUE, 50,
+ COND_DEFAULT},
+ {"keyGUIPageDown",
+ INPUT_KEYBOARD, SDLK_PAGEDOWN,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_GUICHAN,
+ nullptr,
+ Input::KEY_NO_VALUE, 50,
+ COND_DEFAULT},
+ {"keyGUIInsert",
+ INPUT_KEYBOARD, SDLK_INSERT,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_GUICHAN,
+ nullptr,
+ Input::KEY_NO_VALUE, 50,
+ COND_DEFAULT},
+ {"keyGUIMod",
+ INPUT_KEYBOARD, SDLK_LSHIFT,
+ INPUT_KEYBOARD, SDLK_RSHIFT,
+ Input::GRP_GUICHAN,
+ nullptr,
+ Input::KEY_NO_VALUE, 50,
+ COND_DEFAULT},
+ {"keySafeVideo",
+ INPUT_KEYBOARD, SDLK_KP_MINUS,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::safeVideoMode,
+ Input::KEY_NO_VALUE, 50,
+ COND_DEFAULT},
+ {"keyStopSit",
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::stopSit,
+ Input::KEY_NO_VALUE, 50,
+ COND_DEFAULT | COND_INGAME},
+ {"keyShowKeyboard",
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::showKeyboard,
+ Input::KEY_NO_VALUE, 50,
+ COND_DEFAULT},
+ {"keyShowWindows",
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_DEFAULT,
+ &ActionManager::showWindows,
+ Input::KEY_NO_VALUE, 50,
+ COND_DEFAULT},
+ {"keyChatMod",
+ INPUT_KEYBOARD, SDLK_LSHIFT,
+ INPUT_UNKNOWN, Input::KEY_NO_VALUE,
+ Input::GRP_CHAT,
+ nullptr,
+ Input::KEY_NO_VALUE, 50,
+ COND_DEFAULT | COND_INGAME}
+};
+
+#endif // INPUT_KEYBOARDDATA_H
diff --git a/src/input/keydata.h b/src/input/keydata.h
new file mode 100644
index 000000000..bb5d27fd1
--- /dev/null
+++ b/src/input/keydata.h
@@ -0,0 +1,348 @@
+/*
+ * Custom keyboard shortcuts configuration
+ * Copyright (C) 2007 Joshua Langley <joshlangley@optusnet.com.au>
+ * Copyright (C) 2009-2010 The Mana Developers
+ * Copyright (C) 2011-2013 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef INPUT_KEYDATA_H
+#define INPUT_KEYDATA_H
+
+#include "input/inputevent.h"
+
+#include <string>
+
+typedef bool (*ActionFuncPtr) (const InputEvent &event);
+
+struct KeyData final
+{
+ const char *configField;
+ int defaultType1;
+ int defaultValue1;
+ int defaultType2;
+ int defaultValue2;
+ int grp;
+ ActionFuncPtr action;
+ int modKeyIndex;
+ int priority;
+ int condition;
+};
+
+namespace Input
+{
+ enum KeyGroup
+ {
+ GRP_DEFAULT = 1, // default game key
+ GRP_CHAT = 2, // chat key
+ GRP_EMOTION = 4, // emotions key
+ 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_REPEAT = 128 // repeat emulation keys
+ };
+
+ /**
+ * All the key functions.
+ * KEY_NO_VALUE is used in initialization, and should be unchanged.
+ * KEY_TOTAL should always be last (used as a conditional in loops).
+ * The key assignment view gets arranged according to the order of
+ * these values.
+ */
+ enum KeyAction
+ {
+ KEY_NO_VALUE = -1,
+ KEY_MOVE_UP,
+ KEY_MOVE_DOWN,
+ KEY_MOVE_LEFT,
+ KEY_MOVE_RIGHT,
+ KEY_ATTACK,
+ KEY_TARGET_ATTACK,
+ KEY_MOVE_TO_TARGET,
+ KEY_CHANGE_MOVE_TO_TARGET,
+ KEY_MOVE_TO_HOME,
+ KEY_SET_HOME,
+ KEY_MOVE_TO_POINT,
+ KEY_TALK,
+ KEY_STOP_ATTACK,
+ KEY_UNTARGET,
+ KEY_TARGET_MONSTER,
+ KEY_TARGET_NPC,
+ KEY_TARGET_PLAYER,
+ KEY_PICKUP,
+ KEY_CHANGE_PICKUP_TYPE,
+ KEY_HIDE_WINDOWS,
+ KEY_SIT,
+ KEY_SCREENSHOT,
+ KEY_TRADE,
+ KEY_PATHFIND,
+ KEY_OK,
+ KEY_QUIT,
+ KEY_SHORTCUTS_KEY,
+ KEY_SHORTCUT_1,
+ KEY_SHORTCUT_2,
+ KEY_SHORTCUT_3,
+ KEY_SHORTCUT_4,
+ KEY_SHORTCUT_5,
+ KEY_SHORTCUT_6,
+ KEY_SHORTCUT_7,
+ KEY_SHORTCUT_8,
+ KEY_SHORTCUT_9,
+ KEY_SHORTCUT_10,
+ KEY_SHORTCUT_11,
+ KEY_SHORTCUT_12,
+ KEY_SHORTCUT_13,
+ KEY_SHORTCUT_14,
+ KEY_SHORTCUT_15,
+ KEY_SHORTCUT_16,
+ KEY_SHORTCUT_17,
+ KEY_SHORTCUT_18,
+ KEY_SHORTCUT_19,
+ KEY_SHORTCUT_20,
+ KEY_WINDOW_HELP,
+ KEY_WINDOW_STATUS,
+ KEY_WINDOW_INVENTORY,
+ KEY_WINDOW_EQUIPMENT,
+ KEY_WINDOW_SKILL,
+ KEY_WINDOW_MINIMAP,
+ KEY_WINDOW_CHAT,
+ KEY_WINDOW_SHORTCUT,
+ KEY_WINDOW_SETUP,
+ KEY_WINDOW_DEBUG,
+ KEY_WINDOW_SOCIAL,
+ KEY_WINDOW_EMOTE_SHORTCUT,
+ KEY_WINDOW_OUTFIT,
+ KEY_WINDOW_SHOP,
+ KEY_WINDOW_DROP,
+ KEY_WINDOW_KILLS,
+ KEY_WINDOW_SPELLS,
+ KEY_WINDOW_BOT_CHECKER,
+ KEY_WINDOW_ONLINE,
+ KEY_WINDOW_DIDYOUKNOW,
+ KEY_WINDOW_QUESTS,
+ KEY_PREV_SOCIAL_TAB,
+ KEY_NEXT_SOCIAL_TAB,
+ KEY_EMOTE,
+ KEY_EMOTE_1,
+ KEY_EMOTE_2,
+ KEY_EMOTE_3,
+ KEY_EMOTE_4,
+ KEY_EMOTE_5,
+ KEY_EMOTE_6,
+ KEY_EMOTE_7,
+ KEY_EMOTE_8,
+ KEY_EMOTE_9,
+ KEY_EMOTE_10,
+ KEY_EMOTE_11,
+ KEY_EMOTE_12,
+ KEY_EMOTE_13,
+ KEY_EMOTE_14,
+ KEY_EMOTE_15,
+ KEY_EMOTE_16,
+ KEY_EMOTE_17,
+ KEY_EMOTE_18,
+ KEY_EMOTE_19,
+ KEY_EMOTE_20,
+ KEY_EMOTE_21,
+ KEY_EMOTE_22,
+ KEY_EMOTE_23,
+ KEY_EMOTE_24,
+ KEY_EMOTE_25,
+ KEY_EMOTE_26,
+ KEY_EMOTE_27,
+ KEY_EMOTE_28,
+ KEY_EMOTE_29,
+ KEY_EMOTE_30,
+ KEY_EMOTE_31,
+ KEY_EMOTE_32,
+ KEY_EMOTE_33,
+ KEY_EMOTE_34,
+ KEY_EMOTE_35,
+ KEY_EMOTE_36,
+ KEY_EMOTE_37,
+ KEY_EMOTE_38,
+ KEY_EMOTE_39,
+ KEY_EMOTE_40,
+ KEY_EMOTE_41,
+ KEY_EMOTE_42,
+ KEY_EMOTE_43,
+ KEY_EMOTE_44,
+ KEY_EMOTE_45,
+ KEY_EMOTE_46,
+ KEY_EMOTE_47,
+ KEY_EMOTE_48,
+ KEY_WEAR_OUTFIT,
+ KEY_COPY_OUTFIT,
+ KEY_COPY_EQUIPED_OUTFIT,
+ KEY_OUTFIT_1,
+ KEY_OUTFIT_2,
+ KEY_OUTFIT_3,
+ KEY_OUTFIT_4,
+ KEY_OUTFIT_5,
+ KEY_OUTFIT_6,
+ KEY_OUTFIT_7,
+ KEY_OUTFIT_8,
+ KEY_OUTFIT_9,
+ KEY_OUTFIT_10,
+ KEY_OUTFIT_11,
+ KEY_OUTFIT_12,
+ KEY_OUTFIT_13,
+ KEY_OUTFIT_14,
+ KEY_OUTFIT_15,
+ KEY_OUTFIT_16,
+ KEY_OUTFIT_17,
+ KEY_OUTFIT_18,
+ KEY_OUTFIT_19,
+ KEY_OUTFIT_20,
+ KEY_OUTFIT_21,
+ KEY_OUTFIT_22,
+ KEY_OUTFIT_23,
+ KEY_OUTFIT_24,
+ KEY_OUTFIT_25,
+ KEY_OUTFIT_26,
+ KEY_OUTFIT_27,
+ KEY_OUTFIT_28,
+ KEY_OUTFIT_29,
+ KEY_OUTFIT_30,
+ KEY_OUTFIT_31,
+ KEY_OUTFIT_32,
+ KEY_OUTFIT_33,
+ KEY_OUTFIT_34,
+ KEY_OUTFIT_35,
+ KEY_OUTFIT_36,
+ KEY_OUTFIT_37,
+ KEY_OUTFIT_38,
+ KEY_OUTFIT_39,
+ KEY_OUTFIT_40,
+ KEY_OUTFIT_41,
+ KEY_OUTFIT_42,
+ KEY_OUTFIT_43,
+ KEY_OUTFIT_44,
+ KEY_OUTFIT_45,
+ KEY_OUTFIT_46,
+ KEY_OUTFIT_47,
+ KEY_OUTFIT_48,
+ KEY_MOVE_TO_POINT_1,
+ KEY_MOVE_TO_POINT_2,
+ KEY_MOVE_TO_POINT_3,
+ KEY_MOVE_TO_POINT_4,
+ KEY_MOVE_TO_POINT_5,
+ KEY_MOVE_TO_POINT_6,
+ KEY_MOVE_TO_POINT_7,
+ KEY_MOVE_TO_POINT_8,
+ KEY_MOVE_TO_POINT_9,
+ KEY_MOVE_TO_POINT_10,
+ KEY_MOVE_TO_POINT_11,
+ KEY_MOVE_TO_POINT_12,
+ KEY_MOVE_TO_POINT_13,
+ KEY_MOVE_TO_POINT_14,
+ KEY_MOVE_TO_POINT_15,
+ KEY_MOVE_TO_POINT_16,
+ KEY_MOVE_TO_POINT_17,
+ KEY_MOVE_TO_POINT_18,
+ KEY_MOVE_TO_POINT_19,
+ KEY_MOVE_TO_POINT_20,
+ KEY_MOVE_TO_POINT_21,
+ KEY_MOVE_TO_POINT_22,
+ KEY_MOVE_TO_POINT_23,
+ KEY_MOVE_TO_POINT_24,
+ KEY_MOVE_TO_POINT_25,
+ KEY_MOVE_TO_POINT_26,
+ KEY_MOVE_TO_POINT_27,
+ KEY_MOVE_TO_POINT_28,
+ KEY_MOVE_TO_POINT_29,
+ KEY_MOVE_TO_POINT_30,
+ KEY_MOVE_TO_POINT_31,
+ KEY_MOVE_TO_POINT_32,
+ KEY_MOVE_TO_POINT_33,
+ KEY_MOVE_TO_POINT_34,
+ KEY_MOVE_TO_POINT_35,
+ KEY_MOVE_TO_POINT_36,
+ KEY_MOVE_TO_POINT_37,
+ KEY_MOVE_TO_POINT_38,
+ KEY_MOVE_TO_POINT_39,
+ KEY_MOVE_TO_POINT_40,
+ KEY_MOVE_TO_POINT_41,
+ KEY_MOVE_TO_POINT_42,
+ KEY_MOVE_TO_POINT_43,
+ KEY_MOVE_TO_POINT_44,
+ KEY_MOVE_TO_POINT_45,
+ KEY_MOVE_TO_POINT_46,
+ KEY_MOVE_TO_POINT_47,
+ KEY_MOVE_TO_POINT_48,
+ KEY_TOGGLE_CHAT,
+ KEY_SCROLL_CHAT_UP,
+ KEY_SCROLL_CHAT_DOWN,
+ KEY_PREV_CHAT_TAB,
+ KEY_NEXT_CHAT_TAB,
+ KEY_CLOSE_CHAT_TAB,
+ KEY_CHAT_PREV_HISTORY,
+ KEY_CHAT_NEXT_HISTORY,
+ KEY_IGNORE_INPUT_1,
+ KEY_IGNORE_INPUT_2,
+ KEY_DIRECT_UP,
+ KEY_DIRECT_DOWN,
+ KEY_DIRECT_LEFT,
+ KEY_DIRECT_RIGHT,
+ KEY_CRAZY_MOVES,
+ KEY_CHANGE_CRAZY_MOVES_TYPE,
+ KEY_QUICK_DROP,
+ KEY_QUICK_DROPN,
+ KEY_SWITCH_QUICK_DROP,
+ KEY_MAGIC_INMA1,
+ KEY_MAGIC_ITENPLZ,
+ KEY_MAGIC_ATTACK,
+ KEY_SWITCH_MAGIC_ATTACK,
+ KEY_SWITCH_PVP_ATTACK,
+ KEY_INVERT_DIRECTION,
+ KEY_CHANGE_ATTACK_WEAPON_TYPE,
+ KEY_CHANGE_ATTACK_TYPE,
+ KEY_CHANGE_FOLLOW_MODE,
+ KEY_CHANGE_IMITATION_MODE,
+ KEY_DISABLE_GAME_MODIFIERS,
+ KEY_CHANGE_AUDIO,
+ KEY_AWAY,
+ KEY_RIGHT_CLICK,
+ KEY_CAMERA,
+ KEY_MOD,
+ KEY_GUI_UP,
+ KEY_GUI_DOWN,
+ KEY_GUI_LEFT,
+ KEY_GUI_RIGHT,
+ KEY_GUI_SELECT,
+ KEY_GUI_SELECT2,
+ KEY_GUI_CANCEL,
+ KEY_GUI_HOME,
+ KEY_GUI_END,
+ KEY_GUI_DELETE,
+ KEY_GUI_BACKSPACE,
+ KEY_GUI_TAB,
+ KEY_GUI_PAGE_UP,
+ KEY_GUI_PAGE_DOWN,
+ KEY_GUI_INSERT,
+ KEY_GUI_MOD,
+ KEY_SAFE_VIDEO,
+ KEY_STOP_SIT,
+ KEY_SHOW_KEYBOARD,
+ KEY_SHOW_WINDOWS,
+ KEY_CHAT_MOD,
+ KEY_TOTAL
+ };
+} // namespace Input
+
+#endif // INPUT_KEYDATA_H
diff --git a/src/input/keyevent.cpp b/src/input/keyevent.cpp
new file mode 100644
index 000000000..6947af04a
--- /dev/null
+++ b/src/input/keyevent.cpp
@@ -0,0 +1,47 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2012-2013 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "input/keyevent.h"
+
+#include "debug.h"
+
+KeyEvent::KeyEvent(gcn::Widget *const source,
+ const bool shiftPressed,
+ const bool controlPressed,
+ const bool altPressed,
+ const bool metaPressed,
+ const unsigned int type,
+ const bool numericPad,
+ const int actionId,
+ const gcn::Key& key) :
+ gcn::KeyEvent(source, shiftPressed, controlPressed, altPressed,
+ metaPressed, type, numericPad, key),
+#ifdef USE_SDL2
+ mActionId(actionId),
+ mText()
+#else
+ mActionId(actionId)
+#endif
+{
+}
+
+KeyEvent::~KeyEvent()
+{
+}
diff --git a/src/input/keyevent.h b/src/input/keyevent.h
new file mode 100644
index 000000000..24623bda4
--- /dev/null
+++ b/src/input/keyevent.h
@@ -0,0 +1,67 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2012-2013 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef INPUT_KEYEVENT_H
+#define INPUT_KEYEVENT_H
+
+#include "input/keydata.h"
+
+#include <guichan/key.hpp>
+#include <guichan/keyevent.hpp>
+#include <guichan/widget.hpp>
+
+#include <string>
+
+class KeyEvent final : public gcn::KeyEvent
+{
+ public:
+ KeyEvent(gcn::Widget *const source,
+ const bool shiftPressed,
+ const bool controlPressed,
+ const bool altPressed,
+ const bool metaPressed,
+ const unsigned int type,
+ const bool numericPad,
+ const int actionId,
+ const gcn::Key& key);
+
+ A_DELETE_COPY(KeyEvent)
+
+ virtual ~KeyEvent();
+
+ int getActionId() const A_WARN_UNUSED
+ { return mActionId; }
+
+#ifdef USE_SDL2
+ void setText(const std::string &text)
+ { mText = text; }
+
+ std::string getText() const
+ { return mText; }
+#endif
+
+ protected:
+ int mActionId;
+#ifdef USE_SDL2
+ std::string mText;
+#endif
+};
+
+#endif // INPUT_KEYEVENT_H
diff --git a/src/input/keyinput.cpp b/src/input/keyinput.cpp
new file mode 100644
index 000000000..b7ffd3ac1
--- /dev/null
+++ b/src/input/keyinput.cpp
@@ -0,0 +1,38 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2012-2013 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "input/keyinput.h"
+
+#include "debug.h"
+
+KeyInput::KeyInput() :
+ gcn::KeyInput(),
+#ifdef USE_SDL2
+ mActionId(-2),
+ mText()
+#else
+ mActionId(-2)
+#endif
+{
+}
+
+KeyInput::~KeyInput()
+{
+}
diff --git a/src/input/keyinput.h b/src/input/keyinput.h
new file mode 100644
index 000000000..590995e2c
--- /dev/null
+++ b/src/input/keyinput.h
@@ -0,0 +1,58 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2012-2013 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef INPUT_KEYINPUT_H
+#define INPUT_KEYINPUT_H
+
+#include "input/keydata.h"
+
+#include <guichan/keyinput.hpp>
+
+#include <string>
+
+class KeyInput final : public gcn::KeyInput
+{
+ public:
+ KeyInput();
+
+ ~KeyInput();
+
+ void setActionId(const int n)
+ { mActionId = n; }
+
+ int getActionId() const A_WARN_UNUSED
+ { return mActionId; }
+
+#ifdef USE_SDL2
+ void setText(const std::string &text)
+ { mText = text; }
+
+ std::string getText() const
+ { return mText; }
+#endif
+
+ protected:
+ int mActionId;
+#ifdef USE_SDL2
+ std::string mText;
+#endif
+};
+
+#endif // INPUT_KEYINPUT_H