From 1eaa88b236db521cd6d4ffda6c8935f0fb9da374 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Sat, 17 Dec 2022 17:18:01 +0100 Subject: [PATCH] Handle ordinal joystick hat keys as combined cardinal hat keys 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. --- scripts/gen_keys.py | 14 +------ src/engine/client/input.cpp | 56 ++++++++++++++------------ src/engine/client/input.h | 4 +- src/engine/client/keynames.h | 16 ++++---- src/engine/input.h | 2 +- src/engine/keys.h | 76 ++++++++++++++++-------------------- 6 files changed, 78 insertions(+), 90 deletions(-) diff --git a/scripts/gen_keys.py b/scripts/gen_keys.py index 03da7bf6c..09407eb94 100644 --- a/scripts/gen_keys.py +++ b/scripts/gen_keys.py @@ -64,22 +64,14 @@ print(f"\tKEY_JOYSTICK_BUTTON_9 = {int(highestid)},", file=f); keynames[highesti 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 @@ -112,8 +104,8 @@ print("\tNUM_JOYSTICK_BUTTONS = KEY_JOYSTICK_BUTTON_11 - KEY_JOYSTICK_BUTTON_0 + 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) @@ -128,8 +120,6 @@ print('#ifndef KEYS_INCLUDE', file=f) print('#error do not include this header!', file=f) print('#endif', file=f) print('', file=f) -print("#include ", 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: diff --git a/src/engine/client/input.cpp b/src/engine/client/input.cpp index b01313bad..07d644583 100644 --- a/src/engine/client/input.cpp +++ b/src/engine/client/input.cpp @@ -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) @@ -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; } } @@ -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); + } } } diff --git a/src/engine/client/input.h b/src/engine/client/input.h index b6cfb0fc4..092cb7aeb 100644 --- a/src/engine/client/input.h +++ b/src/engine/client/input.h @@ -40,11 +40,11 @@ public: 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: diff --git a/src/engine/client/keynames.h b/src/engine/client/keynames.h index be103c50e..30df8db34 100644 --- a/src/engine/client/keynames.h +++ b/src/engine/client/keynames.h @@ -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", @@ -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", diff --git a/src/engine/input.h b/src/engine/input.h index 67f372b72..504f327a9 100644 --- a/src/engine/input.h +++ b/src/engine/input.h @@ -86,7 +86,7 @@ public: 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; }; diff --git a/src/engine/keys.h b/src/engine/keys.h index 184ca1926..a294513fb 100644 --- a/src/engine/keys.h +++ b/src/engine/keys.h @@ -276,47 +276,39 @@ 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, @@ -324,8 +316,8 @@ enum 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, };