Windows returns all zeros in the 'value' output until the first interaction with the gamepad.
-- v3: windows.gaming.input: Zero 'value' in GetCurrentReading until first state change.
From: Brendan McGrath bmcgrath@codeweavers.com
Windows returns all zeros in the 'value' output until the first interaction with the gamepad. --- dlls/windows.gaming.input/gamepad.c | 112 +++++++++++++++------------- 1 file changed, 62 insertions(+), 50 deletions(-)
diff --git a/dlls/windows.gaming.input/gamepad.c b/dlls/windows.gaming.input/gamepad.c index 0d7cd690821..def2c9dcf5e 100644 --- a/dlls/windows.gaming.input/gamepad.c +++ b/dlls/windows.gaming.input/gamepad.c @@ -67,6 +67,9 @@ struct gamepad
IGameControllerProvider *provider; IWineGameControllerProvider *wine_provider; + + struct WineGameControllerState initial_state; + BOOL state_changed; };
static inline struct gamepad *impl_from_IGameControllerImpl( IGameControllerImpl *iface ) @@ -169,6 +172,10 @@ static HRESULT WINAPI controller_Initialize( IGameControllerImpl *iface, IGameCo
hr = IGameControllerProvider_QueryInterface( provider, &IID_IWineGameControllerProvider, (void **)&impl->wine_provider ); + + if (SUCCEEDED(hr)) + hr = IWineGameControllerProvider_get_State( impl->wine_provider, &impl->initial_state ); + if (FAILED(hr)) return hr;
EnterCriticalSection( &gamepad_cs ); @@ -266,59 +273,64 @@ static HRESULT WINAPI gamepad_GetCurrentReading( IGamepad *iface, struct Gamepad
if (FAILED(hr = IWineGameControllerProvider_get_State( impl->wine_provider, &state ))) return hr;
- value->Buttons = 0; - if (state.buttons[0]) value->Buttons |= GamepadButtons_A; - if (state.buttons[1]) value->Buttons |= GamepadButtons_B; - if (state.buttons[2]) value->Buttons |= GamepadButtons_X; - if (state.buttons[3]) value->Buttons |= GamepadButtons_Y; - if (state.buttons[4]) value->Buttons |= GamepadButtons_LeftShoulder; - if (state.buttons[5]) value->Buttons |= GamepadButtons_RightShoulder; - if (state.buttons[6]) value->Buttons |= GamepadButtons_View; - if (state.buttons[7]) value->Buttons |= GamepadButtons_Menu; - if (state.buttons[8]) value->Buttons |= GamepadButtons_LeftThumbstick; - if (state.buttons[9]) value->Buttons |= GamepadButtons_RightThumbstick; - - switch (state.switches[0]) - { - case GameControllerSwitchPosition_Up: - case GameControllerSwitchPosition_UpRight: - case GameControllerSwitchPosition_UpLeft: - value->Buttons |= GamepadButtons_DPadUp; - break; - case GameControllerSwitchPosition_Down: - case GameControllerSwitchPosition_DownRight: - case GameControllerSwitchPosition_DownLeft: - value->Buttons |= GamepadButtons_DPadDown; - break; - default: - break; - } - - switch (state.switches[0]) + memset(value, 0, sizeof(*value)); + if (impl->state_changed || + memcmp( impl->initial_state.axes, state.axes, sizeof(state) - offsetof(struct WineGameControllerState, axes)) ) { - case GameControllerSwitchPosition_Right: - case GameControllerSwitchPosition_UpRight: - case GameControllerSwitchPosition_DownRight: - value->Buttons |= GamepadButtons_DPadRight; - break; - case GameControllerSwitchPosition_Left: - case GameControllerSwitchPosition_UpLeft: - case GameControllerSwitchPosition_DownLeft: - value->Buttons |= GamepadButtons_DPadLeft; - break; - default: - break; + impl->state_changed = TRUE; + if (state.buttons[0]) value->Buttons |= GamepadButtons_A; + if (state.buttons[1]) value->Buttons |= GamepadButtons_B; + if (state.buttons[2]) value->Buttons |= GamepadButtons_X; + if (state.buttons[3]) value->Buttons |= GamepadButtons_Y; + if (state.buttons[4]) value->Buttons |= GamepadButtons_LeftShoulder; + if (state.buttons[5]) value->Buttons |= GamepadButtons_RightShoulder; + if (state.buttons[6]) value->Buttons |= GamepadButtons_View; + if (state.buttons[7]) value->Buttons |= GamepadButtons_Menu; + if (state.buttons[8]) value->Buttons |= GamepadButtons_LeftThumbstick; + if (state.buttons[9]) value->Buttons |= GamepadButtons_RightThumbstick; + + switch (state.switches[0]) + { + case GameControllerSwitchPosition_Up: + case GameControllerSwitchPosition_UpRight: + case GameControllerSwitchPosition_UpLeft: + value->Buttons |= GamepadButtons_DPadUp; + break; + case GameControllerSwitchPosition_Down: + case GameControllerSwitchPosition_DownRight: + case GameControllerSwitchPosition_DownLeft: + value->Buttons |= GamepadButtons_DPadDown; + break; + default: + break; + } + + switch (state.switches[0]) + { + case GameControllerSwitchPosition_Right: + case GameControllerSwitchPosition_UpRight: + case GameControllerSwitchPosition_DownRight: + value->Buttons |= GamepadButtons_DPadRight; + break; + case GameControllerSwitchPosition_Left: + case GameControllerSwitchPosition_UpLeft: + case GameControllerSwitchPosition_DownLeft: + value->Buttons |= GamepadButtons_DPadLeft; + break; + default: + break; + } + + value->LeftThumbstickX = 2. * state.axes[0] - 1.; + value->LeftThumbstickY = 1. - 2. * state.axes[1]; + value->LeftTrigger = state.axes[2]; + value->RightThumbstickX = 2. * state.axes[3] - 1.; + value->RightThumbstickY = 1. - 2. * state.axes[4]; + value->RightTrigger = state.axes[5]; + + value->Timestamp = state.timestamp; }
- value->LeftThumbstickX = 2. * state.axes[0] - 1.; - value->LeftThumbstickY = 1. - 2. * state.axes[1]; - value->LeftTrigger = state.axes[2]; - value->RightThumbstickX = 2. * state.axes[3] - 1.; - value->RightThumbstickY = 1. - 2. * state.axes[4]; - value->RightTrigger = state.axes[5]; - - value->Timestamp = state.timestamp; - return hr; }
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=148048
Your paranoid android.
=== debian11b (64 bit WoW report) ===
user32: input.c:733: Test failed: peek: raw_legacy: 0: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x1, flags 0, vkey F, message WM_KEYDOWN, extra 0 input.c:733: Test failed: peek: raw_legacy: 0: test->expect 1 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYDOWN, wparam 0x46, lparam 0x10001 input.c:733: Test failed: peek: raw_legacy: 0: test->expect 2 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_CHAR, wparam 0x66, lparam 0x10001 input.c:734: Test failed: peek: raw_legacy: 0: got F: 0 input.c:733: Test failed: peek: raw_legacy: 1: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x2, flags 0x1, vkey F, message WM_KEYUP, extra 0 input.c:733: Test failed: peek: raw_legacy: 1: test->expect 1 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYUP, wparam 0x46, lparam 0xffffffffc0020001 input.c:733: Test failed: peek: raw_vk_packet_legacy: 0: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x1, flags 0, vkey 0xe7, message WM_KEYDOWN, extra 0 input.c:733: Test failed: peek: raw_vk_packet_legacy: 0: test->expect 1 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYDOWN, wparam 0xe7, lparam 0x10001 input.c:734: Test failed: peek: raw_vk_packet_legacy: 0: got 0xe7: 0 input.c:733: Test failed: peek: raw_vk_packet_legacy: 1: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x2, flags 0x1, vkey 0xe7, message WM_KEYUP, extra 0 input.c:733: Test failed: peek: raw_vk_packet_legacy: 1: test->expect 1 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYUP, wparam 0xe7, lparam 0xffffffffc0020001 input.c:733: Test failed: peek: raw_unicode_legacy: 0: test->expect 1 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_CHAR, wparam 0x3c0, lparam 0x1 input.c:734: Test failed: peek: raw_unicode_legacy: 0: got 0xe7: 0 input.c:733: Test failed: peek: raw_unicode_vkey_ctrl_legacy: 0: test->expect 0 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYDOWN, wparam 0x11, lparam 0xc00001 input.c:734: Test failed: peek: raw_unicode_vkey_ctrl_legacy: 0: got VK_CONTROL: 0 input.c:734: Test failed: peek: raw_unicode_vkey_ctrl_legacy: 0: got VK_LCONTROL: 0 input.c:733: Test failed: peek: raw_unicode_vkey_ctrl_legacy: 1: test->expect 0 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYUP, wparam 0x11, lparam 0xffffffffc0c00001 input.c:733: Test failed: peek: raw_nolegacy: 0: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x1, flags 0, vkey F, message WM_KEYDOWN, extra 0 input.c:733: Test failed: peek: raw_nolegacy: 1: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x2, flags 0x1, vkey F, message WM_KEYUP, extra 0 input.c:733: Test failed: peek: raw_vk_packet_nolegacy: 0: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x1, flags 0, vkey 0xe7, message WM_KEYDOWN, extra 0 input.c:733: Test failed: peek: raw_vk_packet_nolegacy: 1: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x2, flags 0x1, vkey 0xe7, message WM_KEYUP, extra 0 input.c:733: Test failed: receive: raw_legacy: 0: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x1, flags 0, vkey F, message WM_KEYDOWN, extra 0 input.c:733: Test failed: receive: raw_legacy: 0: test->expect 1 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYDOWN, wparam 0x46, lparam 0x10001 input.c:733: Test failed: receive: raw_legacy: 0: test->expect 2 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_CHAR, wparam 0x66, lparam 0x10001 input.c:734: Test failed: receive: raw_legacy: 0: got F: 0 input.c:733: Test failed: receive: raw_legacy: 1: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x2, flags 0x1, vkey F, message WM_KEYUP, extra 0 input.c:733: Test failed: receive: raw_legacy: 1: test->expect 1 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYUP, wparam 0x46, lparam 0xffffffffc0020001 input.c:733: Test failed: receive: raw_vk_packet_legacy: 0: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x1, flags 0, vkey 0xe7, message WM_KEYDOWN, extra 0 input.c:733: Test failed: receive: raw_vk_packet_legacy: 0: test->expect 1 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYDOWN, wparam 0xe7, lparam 0x10001 input.c:734: Test failed: receive: raw_vk_packet_legacy: 0: got 0xe7: 0 input.c:733: Test failed: receive: raw_vk_packet_legacy: 1: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x2, flags 0x1, vkey 0xe7, message WM_KEYUP, extra 0 input.c:733: Test failed: receive: raw_vk_packet_legacy: 1: test->expect 1 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYUP, wparam 0xe7, lparam 0xffffffffc0020001 input.c:733: Test failed: receive: raw_unicode_legacy: 0: test->expect 1 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_CHAR, wparam 0x3c0, lparam 0x1 input.c:734: Test failed: receive: raw_unicode_legacy: 0: got 0xe7: 0 input.c:733: Test failed: receive: raw_unicode_vkey_ctrl_legacy: 0: test->expect 0 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYDOWN, wparam 0x11, lparam 0xc00001 input.c:734: Test failed: receive: raw_unicode_vkey_ctrl_legacy: 0: got VK_CONTROL: 0 input.c:734: Test failed: receive: raw_unicode_vkey_ctrl_legacy: 0: got VK_LCONTROL: 0 input.c:733: Test failed: receive: raw_unicode_vkey_ctrl_legacy: 1: test->expect 0 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYUP, wparam 0x11, lparam 0xffffffffc0c00001 input.c:733: Test failed: receive: raw_nolegacy: 0: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x1, flags 0, vkey F, message WM_KEYDOWN, extra 0 input.c:733: Test failed: receive: raw_nolegacy: 1: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x2, flags 0x1, vkey F, message WM_KEYUP, extra 0 input.c:733: Test failed: receive: raw_vk_packet_nolegacy: 0: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x1, flags 0, vkey 0xe7, message WM_KEYDOWN, extra 0 input.c:733: Test failed: receive: raw_vk_packet_nolegacy: 1: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x2, flags 0x1, vkey 0xe7, message WM_KEYUP, extra 0
On Wed Aug 28 06:49:19 2024 +0000, Rémi Bernon wrote:
memset(value, 0, sizeof(*value)); if (impl->state_changed || memcmp( impl->initial_state.axes, state.axes, sizeof(state) - offsetof(struct WineGameControllerState, axes) )) { impl->state_changed = TRUE; if (state.buttons[0]) value->Buttons |= GamepadButtons_A;
(Use `offsetof(struct WineGameControllerState, axes)`, style is a bit more of a nit.)
Thanks @rbernon
This merge request was approved by Rémi Bernon.