diff options
Diffstat (limited to 'src/input/joystick.cpp')
-rw-r--r-- | src/input/joystick.cpp | 83 |
1 files changed, 59 insertions, 24 deletions
diff --git a/src/input/joystick.cpp b/src/input/joystick.cpp index 0ab6102c5..59087c2c7 100644 --- a/src/input/joystick.cpp +++ b/src/input/joystick.cpp @@ -47,6 +47,7 @@ bool Joystick::mInitialized = false; Joystick::Joystick(const int no) : mDirection(0), + mHatPosition(0), mJoystick(nullptr), mTolerance(0), mNumber(no >= joystickCount ? joystickCount : no), @@ -264,18 +265,19 @@ void Joystick::logic() logger->log("axis 4 pos: %d", SDL_JoystickGetAxis(mJoystick, 4)); #endif // DEBUG_JOYSTICK - if ((mDirection == 0U) && mHaveHats) + if (mHaveHats) { // reading only hat 0 const uint8_t hat = SDL_JoystickGetHat(mJoystick, 0); + mHatPosition = 0; if ((hat & SDL_HAT_RIGHT) != 0) - mDirection |= RIGHT; + mHatPosition |= RIGHT; else if ((hat & SDL_HAT_LEFT) != 0) - mDirection |= LEFT; + mHatPosition |= LEFT; if ((hat & SDL_HAT_UP) != 0) - mDirection |= UP; + mHatPosition |= UP; else if ((hat & SDL_HAT_DOWN) != 0) - mDirection |= DOWN; + mHatPosition |= DOWN; } // Buttons @@ -293,15 +295,30 @@ void Joystick::logic() } else { + mHatPosition = 0; for (int i = 0; i < mButtonsNumber; i++) mActiveButtons[i] = false; } BLOCK_END("Joystick::logic") } -bool Joystick::buttonPressed(const unsigned char no) const +bool Joystick::buttonPressed(const int no) const { - return (mEnabled && no < MAX_BUTTONS) ? mActiveButtons[no] : false; + if (!mEnabled) + return false; + if (no < 0) + return false; + if (no < MAX_BUTTONS) + return mActiveButtons[no]; + if (no == KEY_UP) + return (mHatPosition & UP) != 0; + if (no == KEY_DOWN) + return (mHatPosition & DOWN) != 0; + if (no == KEY_LEFT) + return (mHatPosition & LEFT) != 0; + if (no == KEY_RIGHT) + return (mHatPosition & RIGHT) != 0; + return false; } void Joystick::getNames(STD_VECTOR <std::string> &names) @@ -320,18 +337,12 @@ void Joystick::update() 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; + return getActionVectorByKey(i); } KeysVector *Joystick::getActionVectorByKey(const int i) { - if (i < 0 || i >= mButtonsNumber) + if (i < 0 || (i >= mButtonsNumber && i < MAX_BUTTONS) || i > KEY_LAST) return nullptr; // logger->log("button triggerAction: %d", i); if (mKeyToAction.find(i) != mKeyToAction.end()) @@ -341,9 +352,30 @@ KeysVector *Joystick::getActionVectorByKey(const int i) int Joystick::getButtonFromEvent(const SDL_Event &event) const { - if (event.jbutton.which != mNumber) - return -1; - return event.jbutton.button; + if (event.type == SDL_JOYBUTTONDOWN) + { + if (event.jbutton.which != mNumber) + return -1; + return event.jbutton.button; + } + if (event.type == SDL_JOYHATMOTION) + { + // reading only hat 0 + if (event.jhat.which != mNumber || event.jhat.hat != 0) + return -1; + const int value = event.jhat.value; + // SDL reports new hat position, not when d-pad button is pressed. + // because of that we have to compare it to previously known state. + if ((mHatPosition & UP) == 0 && (value & SDL_HAT_UP) != 0) + return KEY_UP; + if ((mHatPosition & DOWN) == 0 && (value & SDL_HAT_DOWN) != 0) + return KEY_DOWN; + if ((mHatPosition & LEFT) == 0 && (value & SDL_HAT_LEFT) != 0) + return KEY_LEFT; + if ((mHatPosition & RIGHT) == 0 && (value & SDL_HAT_RIGHT) != 0) + return KEY_RIGHT; + } + return -1; } bool Joystick::isActionActive(const InputActionT index) const @@ -357,12 +389,7 @@ bool Joystick::isActionActive(const InputActionT index) const const InputItem &val = key.values[i]; if (val.type != InputType::JOYSTICK) continue; - const int value = val.value; - if (value >= 0 && value < mButtonsNumber) - { - if (mActiveButtons[value]) - return true; - } + return buttonPressed(val.value); } return false; } @@ -388,6 +415,14 @@ void Joystick::handleRepeat(const int time) if (mActiveButtons[key]) repeat = true; } + if (key == KEY_UP && (mHatPosition & UP) != 0) + repeat = true; + if (key == KEY_DOWN && (mHatPosition & DOWN) != 0) + repeat = true; + if (key == KEY_LEFT && (mHatPosition & LEFT) != 0) + repeat = true; + if (key == KEY_RIGHT && (mHatPosition & RIGHT) != 0) + repeat = true; if (repeat) { int &keyTime = (*it).second; |