summaryrefslogtreecommitdiff
path: root/src/input/joystick.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/input/joystick.cpp')
-rw-r--r--src/input/joystick.cpp83
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;