From 74e7edccdc340a56e862c1234626dbb276e88553 Mon Sep 17 00:00:00 2001 From: elvencache <45753710+elvencache@users.noreply.github.com> Date: Sun, 7 Jul 2024 18:52:23 -0700 Subject: [PATCH] Fix issues with controller in entry_sdl.cpp. (#3321) SDL2's concept of GameController is a like a PS or Xbox controller, two sticks, four face buttons, etc. These are the same as the bgfx example's Gamepad. SDL also has a concept of Joystick, which could be anything, like a flight stick. Game Controllers are implemented by these lower level joystick's. Entry SDL gets duplicate events, for both controller and the joystick implementing it. Game controller buttons are remapped to bgfx gamepad, but joystick buttons are not. This causes incorrect button presses. Additionally, the joystick z axis behaves differently than game controller or bgfx gamepad. With at-rest value being negative, not zero. Due to all of this, it seems like the best approach would be to ignore joystick events and only handle game controller events. Also, minor additional fix to get handle's index when using it as array index. Fixes compilation in Visual Studio. --- examples/common/entry/entry_sdl.cpp | 76 +++-------------------------- 1 file changed, 8 insertions(+), 68 deletions(-) diff --git a/examples/common/entry/entry_sdl.cpp b/examples/common/entry/entry_sdl.cpp index 3ad4ef9782..d185dd2c8d 100644 --- a/examples/common/entry/entry_sdl.cpp +++ b/examples/common/entry/entry_sdl.cpp @@ -217,22 +217,6 @@ namespace entry { _eventQueue.postAxisEvent(_handle, _gamepad, _axis, _value); - if (Key::None != s_axisDpad[_axis].first) - { - if (_value == 0) - { - _eventQueue.postKeyEvent(_handle, s_axisDpad[_axis].first, 0, false); - _eventQueue.postKeyEvent(_handle, s_axisDpad[_axis].second, 0, false); - } - else - { - _eventQueue.postKeyEvent(_handle - , 0 > _value ? s_axisDpad[_axis].first : s_axisDpad[_axis].second - , 0 - , true - ); - } - } } } @@ -702,16 +686,14 @@ namespace entry } break; + // Ignore Joystick events. Example's Gamepad concept mirrors SDL Game Controller. + // Game Controllers are higher level wrapper around Joystick and both events come through. + // Respond to only the controller events. Controller events are properly remapped. case SDL_JOYAXISMOTION: - { - const SDL_JoyAxisEvent& jev = event.jaxis; - GamepadHandle handle = findGamepad(jev.which); - if (isValid(handle) ) - { - GamepadAxis::Enum axis = translateGamepadAxis(jev.axis); - m_gamepad[handle.idx].update(m_eventQueue, defaultWindow, handle, axis, jev.value); - } - } + case SDL_JOYBUTTONDOWN: + case SDL_JOYBUTTONUP: + case SDL_JOYDEVICEADDED: + case SDL_JOYDEVICEREMOVED: break; case SDL_CONTROLLERAXISMOTION: @@ -726,23 +708,6 @@ namespace entry } break; - case SDL_JOYBUTTONDOWN: - case SDL_JOYBUTTONUP: - { - const SDL_JoyButtonEvent& bev = event.jbutton; - GamepadHandle handle = findGamepad(bev.which); - - if (isValid(handle) ) - { - Key::Enum key = translateGamepad(bev.button); - if (Key::Count != key) - { - m_eventQueue.postKeyEvent(defaultWindow, key, 0, event.type == SDL_JOYBUTTONDOWN); - } - } - } - break; - case SDL_CONTROLLERBUTTONDOWN: case SDL_CONTROLLERBUTTONUP: { @@ -759,31 +724,6 @@ namespace entry } break; - case SDL_JOYDEVICEADDED: - { - GamepadHandle handle = { m_gamepadAlloc.alloc() }; - if (isValid(handle) ) - { - const SDL_JoyDeviceEvent& jev = event.jdevice; - m_gamepad[handle.idx].create(jev); - m_eventQueue.postGamepadEvent(defaultWindow, handle, true); - } - } - break; - - case SDL_JOYDEVICEREMOVED: - { - const SDL_JoyDeviceEvent& jev = event.jdevice; - GamepadHandle handle = findGamepad(jev.which); - if (isValid(handle) ) - { - m_gamepad[handle.idx].destroy(); - m_gamepadAlloc.free(handle.idx); - m_eventQueue.postGamepadEvent(defaultWindow, handle, false); - } - } - break; - case SDL_CONTROLLERDEVICEADDED: { GamepadHandle handle = { m_gamepadAlloc.alloc() }; @@ -1164,7 +1104,7 @@ namespace entry { SDL_SysWMinfo wmi; SDL_VERSION(&wmi.version); - if (!SDL_GetWindowWMInfo(s_ctx.m_window[kDefaultWindowHandle], &wmi) ) + if (!SDL_GetWindowWMInfo(s_ctx.m_window[kDefaultWindowHandle.idx], &wmi) ) { return bgfx::NativeWindowHandleType::Default; }