summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/input/inputmanager.cpp56
-rw-r--r--src/input/joystick.cpp83
-rw-r--r--src/input/joystick.h15
3 files changed, 125 insertions, 29 deletions
diff --git a/src/input/inputmanager.cpp b/src/input/inputmanager.cpp
index a379e0e86..7c07d1351 100644
--- a/src/input/inputmanager.cpp
+++ b/src/input/inputmanager.cpp
@@ -416,8 +416,31 @@ std::string InputManager::getKeyStringLong(const InputActionT index) const
}
else if (key.type == InputType::JOYSTICK)
{
- // TRANSLATORS: long joystick button name. must be short.
- str = strprintf(_("JButton%d"), key.value + 1);
+ if (key.value < Joystick::MAX_BUTTONS)
+ {
+ // TRANSLATORS: joystick button name. must be short.
+ str = strprintf(_("JButton%d"), key.value + 1);
+ }
+ else if (key.value == Joystick::KEY_UP)
+ {
+ // TRANSLATORS: joystick up button. must be short.
+ str = _("JUp");
+ }
+ else if (key.value == Joystick::KEY_DOWN)
+ {
+ // TRANSLATORS: joystick down button. must be short.
+ str = _("JDown");
+ }
+ else if (key.value == Joystick::KEY_LEFT)
+ {
+ // TRANSLATORS: joystick left button. must be short.
+ str = _("JLeft");
+ }
+ else if (key.value == Joystick::KEY_RIGHT)
+ {
+ // TRANSLATORS: joystick right button. must be short.
+ str = _("JRight");
+ }
}
if (!str.empty())
{
@@ -459,8 +482,31 @@ void InputManager::updateKeyString(const InputFunction &ki,
}
else if (key.type == InputType::JOYSTICK)
{
- // TRANSLATORS: short joystick button name. muse be very short
- str = strprintf(_("JB%d"), key.value + 1);
+ if (key.value < Joystick::MAX_BUTTONS)
+ {
+ // TRANSLATORS: joystick button name. muse be very short
+ str = strprintf(_("JB%d"), key.value + 1);
+ }
+ else if (key.value == Joystick::KEY_UP)
+ {
+ // TRANSLATORS: joystick up button. muse be very short
+ str = _("JUp");
+ }
+ else if (key.value == Joystick::KEY_DOWN)
+ {
+ // TRANSLATORS: joystick down button. muse be very short
+ str = _("JDn");
+ }
+ else if (key.value == Joystick::KEY_LEFT)
+ {
+ // TRANSLATORS: joystick left button. muse be very short
+ str = _("JLt");
+ }
+ else if (key.value == Joystick::KEY_RIGHT)
+ {
+ // TRANSLATORS: joystick right button. muse be very short
+ str = _("JRt");
+ }
}
if (!str.empty())
{
@@ -650,6 +696,7 @@ bool InputManager::handleEvent(const SDL_Event &restrict event) restrict2
break;
}
case SDL_JOYBUTTONDOWN:
+ case SDL_JOYHATMOTION:
{
updateConditionMask(true);
// joystick.handleActicateButton(event);
@@ -724,6 +771,7 @@ bool InputManager::handleEvent(const SDL_Event &restrict event) restrict2
// break;
case SDL_JOYBUTTONDOWN:
+ case SDL_JOYHATMOTION:
if ((joystick != nullptr) && joystick->validate())
{
if (triggerAction(joystick->getActionVector(event)))
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;
diff --git a/src/input/joystick.h b/src/input/joystick.h
index 32fdddf2e..bddf520a2 100644
--- a/src/input/joystick.h
+++ b/src/input/joystick.h
@@ -52,6 +52,18 @@ class Joystick final
};
/**
+ * Additional "buttons" for hat 0 (d-pad).
+ */
+ enum
+ {
+ KEY_UP = MAX_BUTTONS,
+ KEY_DOWN,
+ KEY_LEFT,
+ KEY_RIGHT,
+ KEY_LAST = KEY_RIGHT
+ };
+
+ /**
* Directions, to be used as bitmask values.
*/
enum
@@ -107,7 +119,7 @@ class Joystick final
*/
void logic();
- bool buttonPressed(const unsigned char no) const A_WARN_UNUSED;
+ bool buttonPressed(const int no) const A_WARN_UNUSED;
bool isUp() const noexcept2 A_WARN_UNUSED
{ return mEnabled && ((mDirection & UP) != 0); }
@@ -149,6 +161,7 @@ class Joystick final
protected:
unsigned char mDirection;
+ unsigned char mHatPosition;
bool mActiveButtons[MAX_BUTTONS];
SDL_Joystick *mJoystick;