libsdl-org / SDL

Simple Directmedia Layer
https://libsdl.org
zlib License
9.79k stars 1.82k forks source link

Hint SDL_HINT_JOYSTICK_HIDAPI_XBOX_ONE is useless #7068

Open pjaholkowski opened 1 year ago

pjaholkowski commented 1 year ago

Hint SDL_HINT_JOYSTICK_HIDAPI_XBOX_ONE is not working

I recently had problems with reading of Microsoft Xbox One controlled VID 0x045 PID 0x02EA on one Windows 10 machine. Because I had the same setup on other machine where that gamepad works (I checked cables, and other gamepads (PS4 gamepad)) I decided to change gamepad api for reading input instead fixing probably some bug in Windows.

I found hint SDL_HINT_JOYSTICK_HIDAPI_XBOX_ONE and added it to testgamecontroller.c

SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_XBOX_ONE, "1");

It didn't work (I set breakpoint in HIDAPI_DriverXboxOne_UpdateDevice(SDL_HIDAPI_Device *device) -> SDL_hidapi_xboxone.c and it was not called even once) So in order to determine which API reads gamepad I put breakpoint in SDL_PrivateJoystickButton, SDL_joystick.c It was hit by code from SDL_rawinpujoystick.c to disable it I used:

SDL_SetHint(SDL_HINT_JOYSTICK_RAWINPUT, "0");

Gamepad input events started working but it was thanks to XInput API from SDL_xinputjoystick.c, so to disabled it:

SDL_SetHint(SDL_HINT_XINPUT_ENABLED, "0");

but then gamepad api uses SDL_windows_gaming_input.c for reading and I did not find way to disable it (with using SDL_Hints I could rebuild SDL2.dll without SDL_JOYSTICK_WGI).

In Windows 7 it could work because there is no Windows.Gaming.Input API there. I think that after disabling XInput it should fallback to HIDAPI or some other api because Windows.Gaming.Input does not allow reading input when window is not focused.

In my opinion XInput is API which works the best for XBox One Controllers. I did some tests in Windows 10 and found out that RAWInput background events do not always work. For example when I clicked on Desktop (windows lost focus) it worked but when I clicked on "Device Manager" window from "Control Panel" it stopped reading input after changing focus back to Desktop or SDL app again it returned back to normal (I did that test on previously mentioned other Windows 10 machine which works with RAWInput).

slouken commented 1 year ago

Yes, these are all quirks of Microsoft Xbox support. The raw input API doesn't provide input in the background, but supports more than 4 controllers. Microsoft also doesn't provide low level access to the Xbox controllers so the HIDAPI back end isn't functional on Windows.

I'll leave this open so we can document this better in SDL3 so people don't have to do the experimentation you did to understand how Xbox controllers work on Windows.