Skip to content

Commit

Permalink
Handle ordinal joystick hat keys as combined cardinal hat keys
Browse files Browse the repository at this point in the history
Instead of considering diagonal hat inputs (e.g. up-left) as separate keys, consider them as inputs for both cardinal directions (e.g. up and left) at the same time.

This improves input with gamecontrollers that map the D-Pad to a joystick hat, as it was impossible with the previous handling to move with hat-left/right and jump with hat-up at the same time.

This means that diagonal hat buttons can no longer be used in binds, because they are no longer considered distinct buttons. It's unlikely that they would ever be useful in this game, as real joystick POV hats would not be used anyway.

Closes #6120.
  • Loading branch information
Robyt3 committed Dec 17, 2022
1 parent f51dd36 commit 1eaa88b
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 90 deletions.
14 changes: 2 additions & 12 deletions scripts/gen_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,22 +64,14 @@
print(f"\tKEY_JOYSTICK_BUTTON_10 = {int(highestid)},", file=f); keynames[highestid] = "joystick10"; highestid += 1
print(f"\tKEY_JOYSTICK_BUTTON_11 = {int(highestid)},", file=f); keynames[highestid] = "joystick11"; highestid += 1
print("", file=f)
print(f"\tKEY_JOY_HAT0_LEFTUP = {int(highestid)},", file=f); keynames[highestid] = "joy_hat0_leftup"; highestid += 1
print(f"\tKEY_JOY_HAT0_UP = {int(highestid)},", file=f); keynames[highestid] = "joy_hat0_up"; highestid += 1
print(f"\tKEY_JOY_HAT0_RIGHTUP = {int(highestid)},", file=f); keynames[highestid] = "joy_hat0_rightup"; highestid += 1
print(f"\tKEY_JOY_HAT0_LEFT = {int(highestid)},", file=f); keynames[highestid] = "joy_hat0_left"; highestid += 1
print(f"\tKEY_JOY_HAT0_RIGHT = {int(highestid)},", file=f); keynames[highestid] = "joy_hat0_right"; highestid += 1
print(f"\tKEY_JOY_HAT0_LEFTDOWN = {int(highestid)},", file=f); keynames[highestid] = "joy_hat0_leftdown"; highestid += 1
print(f"\tKEY_JOY_HAT0_DOWN = {int(highestid)},", file=f); keynames[highestid] = "joy_hat0_down"; highestid += 1
print(f"\tKEY_JOY_HAT0_RIGHTDOWN = {int(highestid)},", file=f); keynames[highestid] = "joy_hat0_rightdown"; highestid += 1
print(f"\tKEY_JOY_HAT1_LEFTUP = {int(highestid)},", file=f); keynames[highestid] = "joy_hat1_leftup"; highestid += 1
print(f"\tKEY_JOY_HAT1_UP = {int(highestid)},", file=f); keynames[highestid] = "joy_hat1_up"; highestid += 1
print(f"\tKEY_JOY_HAT1_RIGHTUP = {int(highestid)},", file=f); keynames[highestid] = "joy_hat1_rightup"; highestid += 1
print(f"\tKEY_JOY_HAT1_LEFT = {int(highestid)},", file=f); keynames[highestid] = "joy_hat1_left"; highestid += 1
print(f"\tKEY_JOY_HAT1_RIGHT = {int(highestid)},", file=f); keynames[highestid] = "joy_hat1_right"; highestid += 1
print(f"\tKEY_JOY_HAT1_LEFTDOWN = {int(highestid)},", file=f); keynames[highestid] = "joy_hat1_leftdown"; highestid += 1
print(f"\tKEY_JOY_HAT1_DOWN = {int(highestid)},", file=f); keynames[highestid] = "joy_hat1_down"; highestid += 1
print(f"\tKEY_JOY_HAT1_RIGHTDOWN = {int(highestid)},", file=f); keynames[highestid] = "joy_hat1_rightdown"; highestid += 1
print("", file=f)
print(f"\tKEY_JOY_AXIS_0_LEFT = {int(highestid)},", file=f); keynames[highestid] = "joy_axis0_left"; highestid += 1
print(f"\tKEY_JOY_AXIS_0_RIGHT = {int(highestid)},", file=f); keynames[highestid] = "joy_axis0_right"; highestid += 1
Expand Down Expand Up @@ -112,8 +104,8 @@
print("\tNUM_JOYSTICK_AXES_BUTTONS = KEY_JOY_AXIS_11_RIGHT - KEY_JOY_AXIS_0_LEFT + 1,", file=f)
print("\tNUM_JOYSTICK_BUTTONS_PER_AXIS = KEY_JOY_AXIS_0_RIGHT - KEY_JOY_AXIS_0_LEFT + 1,", file=f)
print("\tNUM_JOYSTICK_AXES = NUM_JOYSTICK_AXES_BUTTONS / NUM_JOYSTICK_BUTTONS_PER_AXIS,", file=f)
print("\tNUM_JOYSTICK_HAT_BUTTONS = KEY_JOY_HAT1_RIGHTDOWN - KEY_JOY_HAT0_LEFTUP + 1,", file=f)
print("\tNUM_JOYSTICK_BUTTONS_PER_HAT = KEY_JOY_HAT1_RIGHTDOWN - KEY_JOY_HAT1_LEFTUP + 1,", file=f)
print("\tNUM_JOYSTICK_HAT_BUTTONS = KEY_JOY_HAT1_DOWN - KEY_JOY_HAT0_UP + 1,", file=f)
print("\tNUM_JOYSTICK_BUTTONS_PER_HAT = KEY_JOY_HAT1_DOWN - KEY_JOY_HAT1_UP + 1,", file=f)
print("\tNUM_JOYSTICK_HATS = NUM_JOYSTICK_HAT_BUTTONS / NUM_JOYSTICK_BUTTONS_PER_HAT,", file=f)

print("};", file=f)
Expand All @@ -128,8 +120,6 @@
print('#error do not include this header!', file=f)
print('#endif', file=f)
print('', file=f)
print("#include <string.h>", file=f)
print("", file=f)
print("const char g_aaKeyStrings[512][20] = // NOLINT(misc-definitions-in-headers)", file=f)
print("{", file=f)
for n in keynames:
Expand Down
56 changes: 31 additions & 25 deletions src/engine/client/input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,25 +189,26 @@ float CInput::CJoystick::GetAxisValue(int Axis)
return (SDL_JoystickGetAxis(m_pDelegate, Axis) - SDL_JOYSTICK_AXIS_MIN) / (float)(SDL_JOYSTICK_AXIS_MAX - SDL_JOYSTICK_AXIS_MIN) * 2.0f - 1.0f;
}

int CInput::CJoystick::GetJoystickHatKey(int Hat, int HatValue)
void CInput::CJoystick::GetJoystickHatKeys(int Hat, int HatValue, int (&HatKeys)[2])
{
switch(HatValue)
{
case SDL_HAT_LEFTUP: return KEY_JOY_HAT0_LEFTUP + Hat * NUM_JOYSTICK_BUTTONS_PER_HAT;
case SDL_HAT_UP: return KEY_JOY_HAT0_UP + Hat * NUM_JOYSTICK_BUTTONS_PER_HAT;
case SDL_HAT_RIGHTUP: return KEY_JOY_HAT0_RIGHTUP + Hat * NUM_JOYSTICK_BUTTONS_PER_HAT;
case SDL_HAT_LEFT: return KEY_JOY_HAT0_LEFT + Hat * NUM_JOYSTICK_BUTTONS_PER_HAT;
case SDL_HAT_RIGHT: return KEY_JOY_HAT0_RIGHT + Hat * NUM_JOYSTICK_BUTTONS_PER_HAT;
case SDL_HAT_LEFTDOWN: return KEY_JOY_HAT0_LEFTDOWN + Hat * NUM_JOYSTICK_BUTTONS_PER_HAT;
case SDL_HAT_DOWN: return KEY_JOY_HAT0_DOWN + Hat * NUM_JOYSTICK_BUTTONS_PER_HAT;
case SDL_HAT_RIGHTDOWN: return KEY_JOY_HAT0_RIGHTDOWN + Hat * NUM_JOYSTICK_BUTTONS_PER_HAT;
}
return -1;
if(HatValue & SDL_HAT_UP)
HatKeys[0] = KEY_JOY_HAT0_UP + Hat * NUM_JOYSTICK_BUTTONS_PER_HAT;
else if(HatValue & SDL_HAT_DOWN)
HatKeys[0] = KEY_JOY_HAT0_DOWN + Hat * NUM_JOYSTICK_BUTTONS_PER_HAT;
else
HatKeys[0] = KEY_UNKNOWN;

if(HatValue & SDL_HAT_LEFT)
HatKeys[1] = KEY_JOY_HAT0_LEFT + Hat * NUM_JOYSTICK_BUTTONS_PER_HAT;
else if(HatValue & SDL_HAT_RIGHT)
HatKeys[1] = KEY_JOY_HAT0_RIGHT + Hat * NUM_JOYSTICK_BUTTONS_PER_HAT;
else
HatKeys[1] = KEY_UNKNOWN;
}

int CInput::CJoystick::GetHatValue(int Hat)
void CInput::CJoystick::GetHatValue(int Hat, int (&HatKeys)[2])
{
return GetJoystickHatKey(Hat, SDL_JoystickGetHat(m_pDelegate, Hat));
return GetJoystickHatKeys(Hat, SDL_JoystickGetHat(m_pDelegate, Hat), HatKeys);
}

bool CInput::CJoystick::Relative(float *pX, float *pY)
Expand Down Expand Up @@ -377,9 +378,10 @@ void CInput::UpdateJoystickState()

for(int Hat = 0; Hat < pJoystick->GetNumHats(); Hat++)
{
const int HatState = pJoystick->GetHatValue(Hat);
for(int Key = KEY_JOY_HAT0_LEFTUP + Hat * NUM_JOYSTICK_BUTTONS_PER_HAT; Key <= KEY_JOY_HAT0_RIGHTDOWN + Hat * NUM_JOYSTICK_BUTTONS_PER_HAT; Key++)
m_aInputState[Key] = Key == HatState;
int HatKeys[2];
pJoystick->GetHatValue(Hat, HatKeys);
for(int Key = KEY_JOY_HAT0_UP + Hat * NUM_JOYSTICK_BUTTONS_PER_HAT; Key <= KEY_JOY_HAT0_DOWN + Hat * NUM_JOYSTICK_BUTTONS_PER_HAT; Key++)
m_aInputState[Key] = HatKeys[0] == Key || HatKeys[1] == Key;
}
}

Expand Down Expand Up @@ -457,22 +459,26 @@ void CInput::HandleJoystickHatMotionEvent(const SDL_Event &Event)
if(Event.jhat.hat >= NUM_JOYSTICK_HATS)
return;

const int CurrentKey = CJoystick::GetJoystickHatKey(Event.jhat.hat, Event.jhat.value);
int HatKeys[2];
CJoystick::GetJoystickHatKeys(Event.jhat.hat, Event.jhat.value, HatKeys);

for(int Key = KEY_JOY_HAT0_LEFTUP + Event.jhat.hat * NUM_JOYSTICK_BUTTONS_PER_HAT; Key <= KEY_JOY_HAT0_RIGHTDOWN + Event.jhat.hat * NUM_JOYSTICK_BUTTONS_PER_HAT; Key++)
for(int Key = KEY_JOY_HAT0_UP + Event.jhat.hat * NUM_JOYSTICK_BUTTONS_PER_HAT; Key <= KEY_JOY_HAT0_DOWN + Event.jhat.hat * NUM_JOYSTICK_BUTTONS_PER_HAT; Key++)
{
if(Key != CurrentKey && m_aInputState[Key])
if(Key != HatKeys[0] && Key != HatKeys[1] && m_aInputState[Key])
{
m_aInputState[Key] = false;
AddEvent(0, Key, IInput::FLAG_RELEASE);
}
}

if(CurrentKey >= 0)
for(int CurrentKey : HatKeys)
{
m_aInputState[CurrentKey] = true;
m_aInputCount[CurrentKey] = m_InputCounter;
AddEvent(0, CurrentKey, IInput::FLAG_PRESS);
if(CurrentKey != KEY_UNKNOWN && !m_aInputState[CurrentKey])
{
m_aInputState[CurrentKey] = true;
m_aInputCount[CurrentKey] = m_InputCounter;
AddEvent(0, CurrentKey, IInput::FLAG_PRESS);
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/engine/client/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ class CInput : public IEngineInput
int GetNumBalls() const override { return m_NumBalls; }
int GetNumHats() const override { return m_NumHats; }
float GetAxisValue(int Axis) override;
int GetHatValue(int Hat) override;
void GetHatValue(int Hat, int (&HatKeys)[2]) override;
bool Relative(float *pX, float *pY) override;
bool Absolute(float *pX, float *pY) override;

static int GetJoystickHatKey(int Hat, int HatValue);
static void GetJoystickHatKeys(int Hat, int HatValue, int (&HatKeys)[2]);
};

private:
Expand Down
16 changes: 8 additions & 8 deletions src/engine/client/keynames.h
Original file line number Diff line number Diff line change
Expand Up @@ -316,22 +316,14 @@ const char g_aaKeyStrings[512][20] = // NOLINT(misc-definitions-in-headers)
"joystick9",
"joystick10",
"joystick11",
"joy_hat0_leftup",
"joy_hat0_up",
"joy_hat0_rightup",
"joy_hat0_left",
"joy_hat0_right",
"joy_hat0_leftdown",
"joy_hat0_down",
"joy_hat0_rightdown",
"joy_hat1_leftup",
"joy_hat1_up",
"joy_hat1_rightup",
"joy_hat1_left",
"joy_hat1_right",
"joy_hat1_leftdown",
"joy_hat1_down",
"joy_hat1_rightdown",
"joy_axis0_left",
"joy_axis0_right",
"joy_axis1_left",
Expand All @@ -356,6 +348,14 @@ const char g_aaKeyStrings[512][20] = // NOLINT(misc-definitions-in-headers)
"joy_axis10_right",
"joy_axis11_left",
"joy_axis11_right",
"&342",
"&343",
"&344",
"&345",
"&346",
"&347",
"&348",
"&349",
"&350",
"&351",
"&352",
Expand Down
2 changes: 1 addition & 1 deletion src/engine/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class IInput : public IInterface
virtual int GetNumBalls() const = 0;
virtual int GetNumHats() const = 0;
virtual float GetAxisValue(int Axis) = 0;
virtual int GetHatValue(int Hat) = 0;
virtual void GetHatValue(int Hat, int (&HatKeys)[2]) = 0;
virtual bool Relative(float *pX, float *pY) = 0;
virtual bool Absolute(float *pX, float *pY) = 0;
};
Expand Down
76 changes: 34 additions & 42 deletions src/engine/keys.h
Original file line number Diff line number Diff line change
Expand Up @@ -276,56 +276,48 @@ enum
KEY_JOYSTICK_BUTTON_10 = 308,
KEY_JOYSTICK_BUTTON_11 = 309,

KEY_JOY_HAT0_LEFTUP = 310,
KEY_JOY_HAT0_UP = 311,
KEY_JOY_HAT0_RIGHTUP = 312,
KEY_JOY_HAT0_LEFT = 313,
KEY_JOY_HAT0_RIGHT = 314,
KEY_JOY_HAT0_LEFTDOWN = 315,
KEY_JOY_HAT0_DOWN = 316,
KEY_JOY_HAT0_RIGHTDOWN = 317,
KEY_JOY_HAT1_LEFTUP = 318,
KEY_JOY_HAT1_UP = 319,
KEY_JOY_HAT1_RIGHTUP = 320,
KEY_JOY_HAT1_LEFT = 321,
KEY_JOY_HAT1_RIGHT = 322,
KEY_JOY_HAT1_LEFTDOWN = 323,
KEY_JOY_HAT1_DOWN = 324,
KEY_JOY_HAT1_RIGHTDOWN = 325,
KEY_JOY_HAT0_UP = 310,
KEY_JOY_HAT0_LEFT = 311,
KEY_JOY_HAT0_RIGHT = 312,
KEY_JOY_HAT0_DOWN = 313,
KEY_JOY_HAT1_UP = 314,
KEY_JOY_HAT1_LEFT = 315,
KEY_JOY_HAT1_RIGHT = 316,
KEY_JOY_HAT1_DOWN = 317,

KEY_JOY_AXIS_0_LEFT = 326,
KEY_JOY_AXIS_0_RIGHT = 327,
KEY_JOY_AXIS_1_LEFT = 328,
KEY_JOY_AXIS_1_RIGHT = 329,
KEY_JOY_AXIS_2_LEFT = 330,
KEY_JOY_AXIS_2_RIGHT = 331,
KEY_JOY_AXIS_3_LEFT = 332,
KEY_JOY_AXIS_3_RIGHT = 333,
KEY_JOY_AXIS_4_LEFT = 334,
KEY_JOY_AXIS_4_RIGHT = 335,
KEY_JOY_AXIS_5_LEFT = 336,
KEY_JOY_AXIS_5_RIGHT = 337,
KEY_JOY_AXIS_6_LEFT = 338,
KEY_JOY_AXIS_6_RIGHT = 339,
KEY_JOY_AXIS_7_LEFT = 340,
KEY_JOY_AXIS_7_RIGHT = 341,
KEY_JOY_AXIS_8_LEFT = 342,
KEY_JOY_AXIS_8_RIGHT = 343,
KEY_JOY_AXIS_9_LEFT = 344,
KEY_JOY_AXIS_9_RIGHT = 345,
KEY_JOY_AXIS_10_LEFT = 346,
KEY_JOY_AXIS_10_RIGHT = 347,
KEY_JOY_AXIS_11_LEFT = 348,
KEY_JOY_AXIS_11_RIGHT = 349,
KEY_JOY_AXIS_0_LEFT = 318,
KEY_JOY_AXIS_0_RIGHT = 319,
KEY_JOY_AXIS_1_LEFT = 320,
KEY_JOY_AXIS_1_RIGHT = 321,
KEY_JOY_AXIS_2_LEFT = 322,
KEY_JOY_AXIS_2_RIGHT = 323,
KEY_JOY_AXIS_3_LEFT = 324,
KEY_JOY_AXIS_3_RIGHT = 325,
KEY_JOY_AXIS_4_LEFT = 326,
KEY_JOY_AXIS_4_RIGHT = 327,
KEY_JOY_AXIS_5_LEFT = 328,
KEY_JOY_AXIS_5_RIGHT = 329,
KEY_JOY_AXIS_6_LEFT = 330,
KEY_JOY_AXIS_6_RIGHT = 331,
KEY_JOY_AXIS_7_LEFT = 332,
KEY_JOY_AXIS_7_RIGHT = 333,
KEY_JOY_AXIS_8_LEFT = 334,
KEY_JOY_AXIS_8_RIGHT = 335,
KEY_JOY_AXIS_9_LEFT = 336,
KEY_JOY_AXIS_9_RIGHT = 337,
KEY_JOY_AXIS_10_LEFT = 338,
KEY_JOY_AXIS_10_RIGHT = 339,
KEY_JOY_AXIS_11_LEFT = 340,
KEY_JOY_AXIS_11_RIGHT = 341,

KEY_LAST = 512,

NUM_JOYSTICK_BUTTONS = KEY_JOYSTICK_BUTTON_11 - KEY_JOYSTICK_BUTTON_0 + 1,
NUM_JOYSTICK_AXES_BUTTONS = KEY_JOY_AXIS_11_RIGHT - KEY_JOY_AXIS_0_LEFT + 1,
NUM_JOYSTICK_BUTTONS_PER_AXIS = KEY_JOY_AXIS_0_RIGHT - KEY_JOY_AXIS_0_LEFT + 1,
NUM_JOYSTICK_AXES = NUM_JOYSTICK_AXES_BUTTONS / NUM_JOYSTICK_BUTTONS_PER_AXIS,
NUM_JOYSTICK_HAT_BUTTONS = KEY_JOY_HAT1_RIGHTDOWN - KEY_JOY_HAT0_LEFTUP + 1,
NUM_JOYSTICK_BUTTONS_PER_HAT = KEY_JOY_HAT1_RIGHTDOWN - KEY_JOY_HAT1_LEFTUP + 1,
NUM_JOYSTICK_HAT_BUTTONS = KEY_JOY_HAT1_DOWN - KEY_JOY_HAT0_UP + 1,
NUM_JOYSTICK_BUTTONS_PER_HAT = KEY_JOY_HAT1_DOWN - KEY_JOY_HAT1_UP + 1,
NUM_JOYSTICK_HATS = NUM_JOYSTICK_HAT_BUTTONS / NUM_JOYSTICK_BUTTONS_PER_HAT,
};

Expand Down

0 comments on commit 1eaa88b

Please sign in to comment.