I'm using the SDL2 event-based joystick API to obtain the positions of the analog joystick axes, and this is mostly working well.
However, SDL2 fails to reliably deliver those positions when the software is starting up. Even when forcing the generation of axis events using SDL_UpdateJoystick()
, the corresponding event reports the default position (0) instead of a value reflecting the actual, physical position of the attached stick.
Aside from calling SDL_UpdateJoystick()
, I also tried setting the SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS
hint prior to initialization, as well as calling SDL_GetJoystickGetAxis()
. Stepping into the source code of the latter function, I discovered that it does not actively query the axis position as I expected, but instead reports a stored value.
Through experimentation, I finally came up with a rather ugly hack that seems to "do the trick":
// My joystick axis querying function
SDL_JoystickUpdate();
for (auto i = 0U; i < 100; i ++) {
SDL_Delay(1);
SDL_PumpEvents();
}
return SDL_JoystickGetAxis((SDL_Joystick*)handle, axis);
I have no idea why this is working or what is going on behind the scenes. I'd be very thankful for a better solution.
UPDATE 2020-09-03: I still do not have a better solution, but I experimented with SDL's source code, specifically the function SDL_DINPUT_JoystickUpdate()
in SDL_dinputjoystick.c
. If I inject an artifical delay of 50ms between IDirectInputDevice8_Poll()
and the call to UpdateDINPUTJoystickState_Buffered()
, which in turn calls IDirectInputDevice8_GetDeviceData()
to collect the data, I get the correct values. (Unfortunately this cannot be used as a solution, as SDL_DINPUT_JoystickUpdate()
is being called constantly.) This would seem to indicate that there is a delay between a call Poll()
and the data becoming available.
UPDATE 2020-09-03 #2: I have submitted a tentative (not very satisfactory) patch proposal to SDL's Bugzilla.