From 2556c72eea6a7d28d543d991e5d5c519726028f0 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Tue, 10 Apr 2012 02:51:44 +0300 Subject: Add joystick key assign ability in keyboard dialog. --- src/client.cpp | 6 +- src/game.cpp | 2 +- src/inputmanager.cpp | 185 ++++++++++++++++++++++++++++++++++--------------- src/inputmanager.h | 8 +-- src/joystick.cpp | 59 +++++++++++++--- src/joystick.h | 26 +++++-- src/keyboardconfig.cpp | 30 +++----- src/keyboardconfig.h | 2 +- 8 files changed, 219 insertions(+), 99 deletions(-) (limited to 'src') diff --git a/src/client.cpp b/src/client.cpp index a7ee6a32c..c8755b499 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -857,7 +857,11 @@ int Client::gameExec() break; case SDL_KEYDOWN: - inputManager.handleAssignKey(event); + inputManager.handleAssignKey(event, INPUT_KEYBOARD); + break; + + case SDL_JOYBUTTONDOWN: + inputManager.handleAssignKey(event, INPUT_JOYSTICK); break; default: diff --git a/src/game.cpp b/src/game.cpp index 95e450dbf..7e514c3fd 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -949,7 +949,7 @@ void Game::handleActive(SDL_Event &event) void Game::handleInput() { if (joystick) - joystick->update(); + joystick->logic(); // Events SDL_Event event; diff --git a/src/inputmanager.cpp b/src/inputmanager.cpp index 3c73376df..6ae93b88e 100644 --- a/src/inputmanager.cpp +++ b/src/inputmanager.cpp @@ -22,6 +22,7 @@ #include "configuration.h" #include "game.h" +#include "joystick.h" #include "keyboardconfig.h" #include "keyboarddata.h" #include "localplayer.h" @@ -82,6 +83,8 @@ void InputManager::init() makeDefault(); retrieve(); keyboard.update(); + if (joystick) + joystick->update(); } void InputManager::retrieve() @@ -245,7 +248,11 @@ void InputManager::callbackNewKey() bool InputManager::isActionActive(int index) const { - return keyboard.isActionActive(index); + if (keyboard.isActionActive(index)) + return true; + if (joystick) + return joystick->isActionActive(index); + return false; } KeyFunction &InputManager::getKey(int index) @@ -262,20 +269,25 @@ std::string InputManager::getKeyStringLong(int index) const for (size_t i = 0; i < KeyFunctionSize; i ++) { const KeyItem &key = mKey[index].values[i]; + std::string str; if (key.type == INPUT_KEYBOARD) { - std::string str; if (key.value >= 0) str = keyboard.getKeyName(key.value); else if (key.value < -1) str = strprintf(_("key_%d"), -key.value); - if (!str.empty()) - { - if (keyStr.empty()) - keyStr = str; - else - keyStr += std::string(" ") + str; - } + } + else if (key.type == INPUT_JOYSTICK) + { + // TRANSLATORS: this is long joystick button name + str = strprintf(_("Button%d"), key.value + 1); + } + if (!str.empty()) + { + if (keyStr.empty()) + keyStr = str; + else + keyStr += std::string(" ") + str; } } @@ -291,9 +303,9 @@ std::string InputManager::getKeyValueString(int index) const for (size_t i = 0; i < KeyFunctionSize; i ++) { const KeyItem &key = mKey[index].values[i]; + std::string str; if (key.type == INPUT_KEYBOARD) { - std::string str; if (key.value >= 0) { str = keyboard.getKeyShortString( @@ -303,13 +315,18 @@ std::string InputManager::getKeyValueString(int index) const { str = strprintf(_("key_%d"), -key.value); } - if (!str.empty()) - { - if (keyStr.empty()) - keyStr = str; - else - keyStr += std::string(" ") + str; - } + } + else if (key.type == INPUT_JOYSTICK) + { + // TRANSLATORS: this is short joystick button name + str = strprintf(_("But%d"), key.value + 1); + } + if (!str.empty()) + { + if (keyStr.empty()) + keyStr = str; + else + keyStr += std::string(" ") + str; } } @@ -328,7 +345,7 @@ void InputManager::addActionKey(int action, int type, int val) for (size_t i = 0; i < KeyFunctionSize; i ++) { if (key.values[i].type == INPUT_UNKNOWN - || (key.values[i].type == INPUT_KEYBOARD + || (key.values[i].type == type && key.values[i].value == val)) { idx = i; @@ -348,13 +365,21 @@ void InputManager::addActionKey(int action, int type, int val) key.values[idx] = KeyItem(type, val); } -void InputManager::setNewKey(const SDL_Event &event) +void InputManager::setNewKey(const SDL_Event &event, int type) { - int val = keyboard.getKeyValueFromEvent(event); - - addActionKey(mNewKeyIndex, INPUT_KEYBOARD, val); + int val = -1; + if (type == INPUT_KEYBOARD) + val = keyboard.getKeyValueFromEvent(event); + else if (type == INPUT_JOYSTICK && joystick) + val = joystick->getButtonFromEvent(event); - keyboard.update(); + if (val != -1) + { + addActionKey(mNewKeyIndex, type, val); + keyboard.update(); + if (joystick) + joystick->update(); + } } void InputManager::unassignKey() @@ -366,14 +391,16 @@ void InputManager::unassignKey() key.values[i].value = -1; } keyboard.update(); + if (joystick) + joystick->update(); } -bool InputManager::handleAssignKey(const SDL_Event &event) +bool InputManager::handleAssignKey(const SDL_Event &event, int type) { if (setupWindow && setupWindow->isVisible() && getNewKeyIndex() > Input::KEY_NO_VALUE) { - setNewKey(event); + setNewKey(event, type); callbackNewKey(); setNewKeyIndex(Input::KEY_NO_VALUE); return true; @@ -383,34 +410,53 @@ bool InputManager::handleAssignKey(const SDL_Event &event) bool InputManager::handleEvent(const SDL_Event &event) { - if (event.type == SDL_KEYDOWN) + switch (event.type) { - if (handleAssignKey(event)) - return true; - - keyboard.handleActicateKey(event); - // send straight to gui for certain windows - if (quitDialog || TextDialog::isActive() || - NpcPostDialog::isActive()) + case SDL_KEYDOWN: { - try - { - if (guiInput) - guiInput->pushInput(event); - if (gui) - gui->handleInput(); - } - catch (const gcn::Exception &e) + if (handleAssignKey(event, INPUT_KEYBOARD)) + return true; + + keyboard.handleActicateKey(event); + // send straight to gui for certain windows + if (quitDialog || TextDialog::isActive() || + NpcPostDialog::isActive()) { - const char* err = e.getMessage().c_str(); - logger->log("Warning: guichan input exception: %s", err); + try + { + if (guiInput) + guiInput->pushInput(event); + if (gui) + gui->handleInput(); + } + catch (const gcn::Exception &e) + { + const char* err = e.getMessage().c_str(); + logger->log("Warning: guichan input exception: %s", err); + } + return true; } - return true; + break; } - } - else if (event.type == SDL_KEYUP) - { - keyboard.handleDeActicateKey(event); + case SDL_KEYUP: + { + keyboard.handleDeActicateKey(event); + break; + } + case SDL_JOYBUTTONDOWN: + { +// joystick.handleActicateButton(event); + if (handleAssignKey(event, INPUT_JOYSTICK)) + return true; + break; + } + case SDL_JOYBUTTONUP: + { +// joystick.handleDeActicateButton(event); + break; + } + default: + break; } try @@ -430,20 +476,24 @@ bool InputManager::handleEvent(const SDL_Event &event) return true; } - if (event.type == SDL_KEYDOWN) + switch (event.type) { - if (handleKeyEvent(event)) - return true; + case SDL_KEYDOWN: + if (triggerAction(keyboard.getActionVector(event))) + return true; + break; + + case SDL_JOYBUTTONDOWN: + if (triggerAction(joystick->getActionVector(event))) + return true; + break; + default: + break; } return false; } -bool InputManager::handleKeyEvent(const SDL_Event &event) -{ - return keyboard.triggerAction(event); -} - int InputManager::getInputConditionMask() { int mask = 1; @@ -532,3 +582,26 @@ void InputManager::updateKeyActionMap(KeyToActionMap &actionMap, int type) sort(keys->begin(), keys->end(), keySorter); } } + +bool InputManager::triggerAction(const KeysVector *ptrs) +{ + if (!ptrs) + return false; + +// logger->log("ptrs: %d", (int)ptrs.size()); + KeysVectorCIter it = ptrs->begin(); + KeysVectorCIter it_end = ptrs->end(); + + int mask = getInputConditionMask(); + + for (; it != it_end; ++ it) + { + const int keyNum = *it; + if (keyNum < 0 || keyNum >= Input::KEY_TOTAL) + continue; + + if (invokeKey(&keyData[keyNum], keyNum, mask)) + return true; + } + return false; +} diff --git a/src/inputmanager.h b/src/inputmanager.h index 374b402fb..2469e2e10 100644 --- a/src/inputmanager.h +++ b/src/inputmanager.h @@ -87,8 +87,6 @@ class InputManager bool handleEvent(const SDL_Event &event); - bool handleKeyEvent(const SDL_Event &event); - int getInputConditionMask(); bool checkKey(const KeyData *key, int mask); @@ -111,7 +109,7 @@ class InputManager void addActionKey(int action, int type, int val); - void setNewKey(const SDL_Event &event); + void setNewKey(const SDL_Event &event, int type); void unassignKey(); @@ -139,7 +137,9 @@ class InputManager bool invokeKey(const KeyData *key, int keyNum, int mask); - bool handleAssignKey(const SDL_Event &event); + bool handleAssignKey(const SDL_Event &event, int type); + + bool triggerAction(const KeysVector *ptrs); protected: Setup_Keyboard *mSetupKey; /**< Reference to setup window */ diff --git a/src/joystick.cpp b/src/joystick.cpp index 035232e41..2bd8b582a 100644 --- a/src/joystick.cpp +++ b/src/joystick.cpp @@ -24,6 +24,7 @@ #include "client.h" #include "configuration.h" +#include "inputmanager.h" #include "logger.h" #include "debug.h" @@ -69,7 +70,7 @@ Joystick::Joystick(int no): mNumber = no; for (int i = 0; i < MAX_BUTTONS; i++) - mButtons[i] = false; + mActiveButtons[i] = false; } Joystick::~Joystick() @@ -137,10 +138,8 @@ void Joystick::setNumber(int n) } } -void Joystick::update() +void Joystick::logic() { - mDirection = 0; - // When calibrating, don't bother the outside with our state if (mCalibrating) { @@ -151,6 +150,8 @@ void Joystick::update() if (!mEnabled || !mCalibrated) return; + mDirection = 0; + if (mUseInactive || Client::getInputFocused()) { // X-Axis @@ -193,9 +194,10 @@ void Joystick::update() // Buttons for (int i = 0; i < mButtonsNumber; i++) { - mButtons[i] = (SDL_JoystickGetButton(mJoystick, i) == 1); + const bool state = (SDL_JoystickGetButton(mJoystick, i) == 1); + mActiveButtons[i] = state; #ifdef DEBUG_JOYSTICK - if (mButtons[i]) + if (mActiveButtons[i]) logger->log("button: %d", i); #endif } @@ -203,7 +205,7 @@ void Joystick::update() else { for (int i = 0; i < mButtonsNumber; i++) - mButtons[i] = false; + mActiveButtons[i] = false; } } @@ -246,7 +248,7 @@ void Joystick::finishCalibration() bool Joystick::buttonPressed(unsigned char no) const { - return (mEnabled && no < MAX_BUTTONS) ? mButtons[no] : false; + return (mEnabled && no < MAX_BUTTONS) ? mActiveButtons[no] : false; } void Joystick::getNames(std::vector &names) @@ -255,3 +257,44 @@ void Joystick::getNames(std::vector &names) for (int i = 0; i < joystickCount; i++) names.push_back(SDL_JoystickName(i)); } + +void Joystick::update() +{ + inputManager.updateKeyActionMap(mKeyToAction, 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; +} + +int Joystick::getButtonFromEvent(const SDL_Event &event) +{ + if (event.jbutton.which != mNumber) + return -1; + return event.jbutton.button; +} + +bool Joystick::isActionActive(int index) const +{ + const KeyFunction &key = inputManager.getKey(index); + for (size_t i = 0; i < KeyFunctionSize; i ++) + { + if (key.values[i].type != INPUT_JOYSTICK) + continue; + const int value = key.values[i].value; + if (value >= 0 && value < mButtonsNumber) + { + if (mActiveButtons[value]) + return true; + } + } + return false; +} diff --git a/src/joystick.h b/src/joystick.h index 87d1e81a9..55b75d373 100644 --- a/src/joystick.h +++ b/src/joystick.h @@ -23,6 +23,8 @@ #ifndef JOYSTICK_H #define JOYSTICK_H +#include "inputevent.h" + #include #include @@ -86,7 +88,7 @@ class Joystick /** * Updates the direction and button information. */ - void update(); + void logic(); void startCalibration(); @@ -98,16 +100,16 @@ class Joystick bool buttonPressed(unsigned char no) const; bool isUp() const - { return mEnabled && (mDirection & UP); }; + { return mEnabled && (mDirection & UP); } bool isDown() const - { return mEnabled && (mDirection & DOWN); }; + { return mEnabled && (mDirection & DOWN); } bool isLeft() const - { return mEnabled && (mDirection & LEFT); }; + { return mEnabled && (mDirection & LEFT); } bool isRight() const - { return mEnabled && (mDirection & RIGHT); }; + { return mEnabled && (mDirection & RIGHT); } int getNumber() const { return mNumber; } @@ -115,9 +117,19 @@ class Joystick void setUseInactive(bool b) { mUseInactive = b; } + void update(); + + KeysVector *getActionVector(const SDL_Event &event); + + int getButtonFromEvent(const SDL_Event &event); + + bool isActionActive(int index) const; + protected: unsigned char mDirection; - bool mButtons[MAX_BUTTONS]; + + bool mActiveButtons[MAX_BUTTONS]; + SDL_Joystick *mJoystick; int mUpTolerance; @@ -131,6 +143,8 @@ class Joystick bool mUseInactive; bool mHaveHats; + KeyToActionMap mKeyToAction; + /** * Is joystick support enabled. */ diff --git a/src/keyboardconfig.cpp b/src/keyboardconfig.cpp index ae095f01d..bcc10d553 100644 --- a/src/keyboardconfig.cpp +++ b/src/keyboardconfig.cpp @@ -23,7 +23,6 @@ #include "keyboardconfig.h" #include "configuration.h" -#include "inputevent.h" #include "inputmanager.h" #include "keyboarddata.h" #include "logger.h" @@ -114,30 +113,13 @@ SDLKey KeyboardConfig::getKeyFromEvent(const SDL_Event &event) const return event.key.keysym.sym; } -bool KeyboardConfig::triggerAction(const SDL_Event &event) +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()) - { - const KeysVector &ptrs = mKeyToAction[i]; -// logger->log("ptrs: %d", (int)ptrs.size()); - KeysVectorCIter it = ptrs.begin(); - KeysVectorCIter it_end = ptrs.end(); - - int mask = inputManager.getInputConditionMask(); - - for (; it != it_end; ++ it) - { - const int keyNum = *it; - if (keyNum < 0 || keyNum >= Input::KEY_TOTAL) - continue; - - if (inputManager.invokeKey(&keyData[keyNum], keyNum, mask)) - return true; - } - } - return false; + return &mKeyToAction[i]; + return nullptr; } bool KeyboardConfig::isActionActive(int index) const @@ -145,9 +127,13 @@ bool KeyboardConfig::isActionActive(int index) const if (!mActiveKeys) return false; + const KeyFunction &key = inputManager.getKey(index); for (size_t i = 0; i < KeyFunctionSize; i ++) { - const int value = inputManager.getKey(index).values[i].value; + if (key.values[i].type != INPUT_KEYBOARD) + continue; + + const int value = key.values[i].value; if (value >= 0) { if (mActiveKeys[value]) diff --git a/src/keyboardconfig.h b/src/keyboardconfig.h index ce09de898..c06699b21 100644 --- a/src/keyboardconfig.h +++ b/src/keyboardconfig.h @@ -73,7 +73,7 @@ class KeyboardConfig int getKeyValueFromEvent(const SDL_Event &event) const; - bool triggerAction(const SDL_Event &event); + KeysVector *getActionVector(const SDL_Event &event); std::string getKeyName(int key); -- cgit v1.2.3-70-g09d2