Hi all,
When I was using SDL joysticks on Windows 7 64bit in my project, I found
that SDL2 initializes XInput compatible device as a DirectInput device under
a specific circumstance. I looked into the joystick initialization code and
probably figured out how it occurs.
Things related:
- XInput assigns its internal user ID to each input device and usually it
starts from 0.
- But, sometimes, an input device may acquire ID 1 even if there’s no any
other device connected. I guess that could happen in such situation that we
connected multiple input devices to our machine, and then disconnected the
first connected one.
And, the senario of the case is that:
- SDL2 detects all XInput compatible devices in SDL_JoystickInit() (which is
called from SDL_Init(SDL_INIT_JOYSTICK) or
SDL_InitSubSystem(SDL_INIT_JOYSTICK)) and marks them as "XInput compatible"
by setting bXInputDevice to SDL_TRUE in EnumJoysticksCallback(). But they
are just detected at that time, and not opened.
- After that, in SDL_SYS_JoystickOpen() (which is called from
SDL_JoystickOpen()), SDL2 checks if a XInput compatible device is really
available by checking the result of call for XINPUTGETCAPABILITIES(). When
the capability check function is called, an user ID is passed to the
function. The point is that SDL_SYS_JoystickOpen() always tries passing user
ID 0 (and then increments the ID if there were multiple joysticks detected),
and if the capability check is failed with the use ID, it marks the device
is not XInput compatible by setting bXInputDevice to SDL_FALSE. In this
case, the device will be handled by DirectInput instead of XInput.
- If there is only one XInput compatible device connected with user ID 1
acquired, SDL_SYS_JoystickOpen() always marks it as “NOT XInput compatible”.
That’s it!
I don’t think it is the best behavior SDL2 can do. Is that a known problem
that already in a bug tracking system?
Yamamoto
Let me see if I’m getting this right: basically during the second step
SDL is trying to use the wrong ID when comparing the joystick when
opening and so it ends up misdetecting the joystick capabilities?
Because in that case it sounds like a rather serious bug that can
potentially result in even more side-effects.
It’d be probably better to not bother checking the joysticks until the
program tries to open them anyway.
2013/7/25, Yamamoto :> Hi all,
When I was using SDL joysticks on Windows 7 64bit in my project, I found
that SDL2 initializes XInput compatible device as a DirectInput device under
a specific circumstance. I looked into the joystick initialization code and
probably figured out how it occurs.
Things related:
- XInput assigns its internal user ID to each input device and usually it
starts from 0.
- But, sometimes, an input device may acquire ID 1 even if there’s no any
other device connected. I guess that could happen in such situation that we
connected multiple input devices to our machine, and then disconnected the
first connected one.
And, the senario of the case is that:
- SDL2 detects all XInput compatible devices in SDL_JoystickInit() (which is
called from SDL_Init(SDL_INIT_JOYSTICK) or
SDL_InitSubSystem(SDL_INIT_JOYSTICK)) and marks them as “XInput compatible”
by setting bXInputDevice to SDL_TRUE in EnumJoysticksCallback(). But they
are just detected at that time, and not opened.
- After that, in SDL_SYS_JoystickOpen() (which is called from
SDL_JoystickOpen()), SDL2 checks if a XInput compatible device is really
available by checking the result of call for XINPUTGETCAPABILITIES(). When
the capability check function is called, an user ID is passed to the
function. The point is that SDL_SYS_JoystickOpen() always tries passing user
ID 0 (and then increments the ID if there were multiple joysticks detected),
and if the capability check is failed with the use ID, it marks the device
is not XInput compatible by setting bXInputDevice to SDL_FALSE. In this
case, the device will be handled by DirectInput instead of XInput.
- If there is only one XInput compatible device connected with user ID 1
acquired, SDL_SYS_JoystickOpen() always marks it as “NOT XInput compatible”.
That’s it!
I don’t think it is the best behavior SDL2 can do. Is that a known problem
that already in a bug tracking system?
Yamamoto
SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Let me see if I’m getting this right: basically during the second step
SDL is trying to use the wrong ID when comparing the joystick when
opening and so it ends up misdetecting the joystick capabilities?
Yes. That’s the point.
If there’s only one XInput compatible device with user ID 1 (or greater) is
acquired, SDL_SYS_JoystickOpen() tries to see if the device is available by
using wrong ID (= 0). And XINPUTGETCAPABILITIES() ends up returning “device
is not connected” error and the code marks the device as “NOT XInput
compatible”.
Yeah that sounds like a serious bug.
Check in Bugzilla if there was a report with the search tool, if you
can’t find something similar just go ahead and report it (if it turned
out there was already a bug report then at worst it can just be merged
with that old report).
2013/7/25, Yamamoto :>>Let me see if I’m getting this right: basically during the second step
SDL is trying to use the wrong ID when comparing the joystick when
opening and so it ends up misdetecting the joystick capabilities?
Yes. That’s the point.
If there’s only one XInput compatible device with user ID 1 (or greater) is
acquired, SDL_SYS_JoystickOpen() tries to see if the device is available by
using wrong ID (= 0). And XINPUTGETCAPABILITIES() ends up returning "device
is not connected" error and the code marks the device as “NOT XInput
compatible”.
SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org