From 842b7fd4db44d85308afbb401023429621d9c586 Mon Sep 17 00:00:00 2001 From: ewewukek Date: Thu, 11 Jan 2024 15:04:28 +0300 Subject: Make sticks/triggers behave like regular buttons --- src/input/inputmanager.cpp | 33 ++++++++++++++++++++++++- src/input/joystick.cpp | 61 +++++++++++++++++++++++++++++++++++++++++++--- src/input/joystick.h | 15 ++++++++++-- 3 files changed, 102 insertions(+), 7 deletions(-) (limited to 'src/input') diff --git a/src/input/inputmanager.cpp b/src/input/inputmanager.cpp index ac5325e3b..fc2815b5e 100644 --- a/src/input/inputmanager.cpp +++ b/src/input/inputmanager.cpp @@ -441,6 +441,20 @@ std::string InputManager::getKeyStringLong(const InputActionT index) const // TRANSLATORS: joystick right button. must be short. str = _("JRight"); } + else if (key.value >= Joystick::KEY_NEGATIVE_AXIS_FIRST + && key.value < Joystick::KEY_POSITIVE_AXIS_FIRST) + { + // TRANSLATORS: joystick negative axis. must be short. + str = strprintf(_("JAxis%dMinus"), + key.value - Joystick::KEY_NEGATIVE_AXIS_FIRST); + } + else if (key.value >= Joystick::KEY_POSITIVE_AXIS_FIRST + && key.value < Joystick::KEY_END) + { + // TRANSLATORS: joystick positive axis. must be short. + str = strprintf(_("JAxis%dPlus"), + key.value - Joystick::KEY_POSITIVE_AXIS_FIRST); + } } if (!str.empty()) { @@ -507,6 +521,20 @@ void InputManager::updateKeyString(const InputFunction &ki, // TRANSLATORS: joystick right button. must be very short str = _("JRt"); } + else if (key.value >= Joystick::KEY_NEGATIVE_AXIS_FIRST + && key.value < Joystick::KEY_POSITIVE_AXIS_FIRST) + { + // TRANSLATORS: joystick negative axis. must be very short. + str = strprintf(_("JA%d-"), + key.value - Joystick::KEY_NEGATIVE_AXIS_FIRST); + } + else if (key.value >= Joystick::KEY_POSITIVE_AXIS_FIRST + && key.value < Joystick::KEY_END) + { + // TRANSLATORS: joystick positive axis. must be very short. + str = strprintf(_("JA%d+"), + key.value - Joystick::KEY_POSITIVE_AXIS_FIRST); + } } if (!str.empty()) { @@ -697,10 +725,12 @@ bool InputManager::handleEvent(const SDL_Event &restrict event) restrict2 } case SDL_JOYBUTTONDOWN: case SDL_JOYHATMOTION: + case SDL_JOYAXISMOTION: { updateConditionMask(true); // joystick.handleActicateButton(event); - if (handleAssignKey(event, InputType::JOYSTICK)) + if (joystick != nullptr && joystick->isActionEvent(event) + && handleAssignKey(event, InputType::JOYSTICK)) { BLOCK_END("InputManager::handleEvent") return true; @@ -774,6 +804,7 @@ bool InputManager::handleEvent(const SDL_Event &restrict event) restrict2 case SDL_JOYBUTTONDOWN: case SDL_JOYHATMOTION: + case SDL_JOYAXISMOTION: if ((joystick != nullptr) && joystick->validate()) { if (triggerAction(joystick->getActionVector(event))) diff --git a/src/input/joystick.cpp b/src/input/joystick.cpp index 1e375cb0a..21de2ad3d 100644 --- a/src/input/joystick.cpp +++ b/src/input/joystick.cpp @@ -51,6 +51,7 @@ Joystick::Joystick(const int no) : mJoystick(nullptr), mTolerance(0), mNumber(no >= joystickCount ? joystickCount : no), + mAxesNumber(MAX_AXES), mButtonsNumber(MAX_BUTTONS), mUseHatForMovement(true), mUseInactive(false), @@ -59,6 +60,8 @@ Joystick::Joystick(const int no) : mKeyToId(), mKeyTimeMap() { + for (int i = 0; i < MAX_AXES; i++) + mAxesPositions[i] = 0; for (int i = 0; i < MAX_BUTTONS; i++) mActiveButtons[i] = false; } @@ -127,7 +130,9 @@ bool Joystick::open() return false; } + mAxesNumber = SDL_JoystickNumAxes(mJoystick); mButtonsNumber = SDL_JoystickNumButtons(mJoystick); + logger->log("Joystick: %i ", mNumber); #ifdef USE_SDL2 logger->log("Name: %s", SDL_JoystickName(mJoystick)); @@ -186,13 +191,16 @@ bool Joystick::open() logger->log("Name: %s", SDL_JoystickName(mNumber)); #endif // USE_SDL2 - logger->log("Axes: %i ", SDL_JoystickNumAxes(mJoystick)); + logger->log("Axes: %i ", mAxesNumber); 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 (mAxesNumber > MAX_AXES) + mAxesNumber = mAxesNumber; + if (mButtonsNumber > MAX_BUTTONS) mButtonsNumber = MAX_BUTTONS; @@ -244,15 +252,18 @@ void Joystick::logic() if (mUseInactive || settings.inputFocused != KeyboardFocus::Unfocused) { + for (int i = 0; i < mAxesNumber; i++) + mAxesPositions[i] = SDL_JoystickGetAxis(mJoystick, i); + // X-Axis - int position = SDL_JoystickGetAxis(mJoystick, 0); + int position = mAxesPositions[0]; if (position >= mTolerance * SDL_JOYSTICK_AXIS_MAX) mDirection |= RIGHT; else if (position <= mTolerance * SDL_JOYSTICK_AXIS_MIN) mDirection |= LEFT; // Y-Axis - position = SDL_JoystickGetAxis(mJoystick, 1); + position = mAxesPositions[1]; if (position <= mTolerance * SDL_JOYSTICK_AXIS_MIN) mDirection |= UP; else if (position >= mTolerance * SDL_JOYSTICK_AXIS_MAX) @@ -300,6 +311,8 @@ void Joystick::logic() else { mHatPosition = 0; + for (int i = 0; i < mAxesNumber; i++) + mAxesPositions[i] = 0; for (int i = 0; i < mButtonsNumber; i++) mActiveButtons[i] = false; } @@ -325,6 +338,20 @@ bool Joystick::buttonPressed(const int no) const if (no == KEY_RIGHT) return (mHatPosition & RIGHT) != 0; } + if (KEY_NEGATIVE_AXIS_FIRST <= no && no < KEY_POSITIVE_AXIS_FIRST) + { + const int axis = no - KEY_NEGATIVE_AXIS_FIRST; + if (axis < RESERVED_AXES || axis >= mAxesNumber) + return false; + return mAxesPositions[axis] < mTolerance * SDL_JOYSTICK_AXIS_MIN; + } + if (KEY_POSITIVE_AXIS_FIRST <= no && no < KEY_END) + { + const int axis = no - KEY_POSITIVE_AXIS_FIRST; + if (axis < RESERVED_AXES || axis >= mAxesNumber) + return false; + return mAxesPositions[axis] > mTolerance * SDL_JOYSTICK_AXIS_MAX; + } return false; } @@ -354,7 +381,7 @@ KeysVector *Joystick::getActionVector(const SDL_Event &event) KeysVector *Joystick::getActionVectorByKey(const int i) { - if (i < 0 || (i >= mButtonsNumber && i < MAX_BUTTONS) || i > KEY_LAST) + if (i < 0 || (i >= mButtonsNumber && i < MAX_BUTTONS) || i >= KEY_END) return nullptr; // logger->log("button triggerAction: %d", i); if (mKeyToAction.find(i) != mKeyToAction.end()) @@ -397,6 +424,20 @@ int Joystick::getButtonFromEvent(const SDL_Event &event) const if ((mHatPosition & RIGHT) == 0 && (value & SDL_HAT_RIGHT) != 0) return KEY_RIGHT; } + if (event.type == SDL_JOYAXISMOTION) + { + if (event.jaxis.which != mNumber) + return -1; + const int axis = event.jaxis.axis; + if (axis < RESERVED_AXES) + return -1; + if (event.jaxis.value < mTolerance * SDL_JOYSTICK_AXIS_MIN + && mAxesPositions[axis] > mTolerance * SDL_JOYSTICK_AXIS_MIN) + return KEY_NEGATIVE_AXIS_FIRST + axis; + if (event.jaxis.value > mTolerance * SDL_JOYSTICK_AXIS_MAX + && mAxesPositions[axis] < mTolerance * SDL_JOYSTICK_AXIS_MAX) + return KEY_POSITIVE_AXIS_FIRST + axis; + } return -1; } @@ -448,6 +489,18 @@ void Joystick::handleRepeat(const int time) if (key == KEY_RIGHT && (mHatPosition & RIGHT) != 0) repeat = true; } + if (KEY_NEGATIVE_AXIS_FIRST <= key && key < KEY_POSITIVE_AXIS_FIRST) + { + const int axis = key - KEY_NEGATIVE_AXIS_FIRST; + if (axis >= RESERVED_AXES && mAxesPositions[axis] < mTolerance * SDL_JOYSTICK_AXIS_MIN) + repeat = true; + } + if (KEY_POSITIVE_AXIS_FIRST <= key && key < KEY_END) + { + const int axis = key - KEY_POSITIVE_AXIS_FIRST; + if (axis >= RESERVED_AXES && mAxesPositions[axis] > mTolerance * SDL_JOYSTICK_AXIS_MAX) + repeat = true; + } if (repeat) { int &keyTime = (*it).second; diff --git a/src/input/joystick.h b/src/input/joystick.h index 293e75a22..2a7e0f638 100644 --- a/src/input/joystick.h +++ b/src/input/joystick.h @@ -51,8 +51,15 @@ class Joystick final MAX_BUTTONS = 64 }; + enum + { + RESERVED_AXES = 2, // reserved for movement + MAX_AXES = 8 // number of axes we can handle + }; + /** - * Additional "buttons" for hat 0 (d-pad). + * Additional "buttons" for hat 0 (d-pad), + * sticks and triggers. */ enum { @@ -60,7 +67,9 @@ class Joystick final KEY_DOWN, KEY_LEFT, KEY_RIGHT, - KEY_LAST = KEY_RIGHT + KEY_NEGATIVE_AXIS_FIRST, + KEY_POSITIVE_AXIS_FIRST = KEY_NEGATIVE_AXIS_FIRST + MAX_AXES, + KEY_END = KEY_POSITIVE_AXIS_FIRST + MAX_AXES }; /** @@ -169,12 +178,14 @@ class Joystick final unsigned char mDirection; unsigned char mHatPosition; + int mAxesPositions[MAX_AXES]; bool mActiveButtons[MAX_BUTTONS]; SDL_Joystick *mJoystick; float mTolerance; int mNumber; + int mAxesNumber; int mButtonsNumber; bool mUseHatForMovement; bool mUseInactive; -- cgit v1.2.3-70-g09d2