We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 2553 - Add support to all XInput devices
Summary: Add support to all XInput devices
Status: RESOLVED FIXED
Alias: None
Product: SDL
Classification: Unclassified
Component: joystick (show other bugs)
Version: 2.0.3
Hardware: x86 Windows 7
: P2 normal
Assignee: Sam Lantinga
QA Contact: Sam Lantinga
URL:
Keywords:
: 2432 (view as bug list)
Depends on:
Blocks:
 
Reported: 2014-05-19 14:34 UTC by Heikki Hämäläinen
Modified: 2014-06-24 22:04 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Heikki Hämäläinen 2014-05-19 14:34:35 UTC
Currently SDL supports only XInput devices which report XInput device subtype as XINPUT_DEVSUBTYPE_GAMEPAD.

PROBLEM
This means that any controller which tells any other subtype for example arcadestick or wheel doesnt have any support at all in programs which use Xinput. These arent used via Direct Input and are discarded.

For example this means that one cannot use in the Windows like Mad Catz Arcade Fightstick Pro. These controllers works fine in Linux and most propably also under OSX.

One good example is Luftrausers which as a arcade style game is logical to play with a arcade stick.

Also Steams Big Picture Interface doesnt recognise at all Mad Catz controller and most likely any other non GAMEPAD subtype controller.

This seems to be intentional but is not right way to do. User should have at least option to use any controller which she connects to computer. Fight sticks for example are normal controllers which doesnt normally have analog axes and triggers work like buttons but works anyway as a normal controller.

THE CAUSE
src\joystick\windows\SDL_dxjoystick.c
Function: EnumXInputDevices
Line: 784-788
/* Current version of XInput mistakenly returns 0 as the Type. Ignore it and ensure the subtype is a gamepad. */
/* !!! FIXME: we might want to support steering wheels or guitars or whatever later. */
if (capabilities.SubType == XINPUT_DEVSUBTYPE_GAMEPAD) {
                    AddXInputDevice(userid, pContext);
}

SOLUTION
Remove the check or at least allow XINPUT_DEVSUBTYPE_ARCADE_STICK to be supported.

I have compiled SDL without limiting XInput devices to GAMEPAD subtype and after that Luftrausers started to work with Mad Catz controller. I dont think that there will be any unintended side effects.
Comment 1 Sam Lantinga 2014-06-22 04:36:06 UTC
In theory these other types of devices should be available through DirectInput. Is that not happening in your case?

Also, even if we support these other devices through XInput, they look like a gamepad and we have no way of knowing which axes / buttons are supported.
Comment 2 Sam Lantinga 2014-06-22 17:47:26 UTC
*** Bug 2432 has been marked as a duplicate of this bug. ***
Comment 3 Heikki Hämäläinen 2014-06-23 16:07:43 UTC
No. This controller is not working at all with SDL. This is also the case when using Steams Big Picture Mode. No controller detected at all.

Controller works fine for example with Street Figter IV. I am not certain that does the controller even support direc input. Mad Catz controller is Xbox 360 version. Maybe there isnt even support for DInput? 

Is there any way to test this? 

I will try to compile SDL so it will treat Xbox 360 wireless controller same way - so EnumXInputDevices doesnt recognize controller as a XInput device. If Xbox 360 controller doesnt work that means that there is some bug in SDL. If I understood you correctly XInput device should alway be accesible through directinput if it is not added via EnumXInputDevices.
Comment 4 Heikki Hämäläinen 2014-06-23 16:30:30 UTC
Okey. Now it is confimed that Xinput capable controller doesnt work if it is not added via EnumXInputDevices.

Proof:

I have a wireless XBox 360 controller which I use via USB receiver. With standard SDL 2.0 library the controller is working fine. Tested with Luftrausers which uses SDL 2.

I changed EnumXInputDevices by commenting the line which adds the controller. This means that SDL is treating all the Xinput devices same way.

if (capabilities.SubType == XINPUT_DEVSUBTYPE_GAMEPAD) {
                    //AddXInputDevice(userid, pContext);
}

After that the controller (Xbox 360 Wireless) is not recognized in Luftrausers.

I think that means that if Xinput controller is not added via AddXInputDevice it cant be used at all.
Comment 5 Sam Lantinga 2014-06-24 20:55:46 UTC
Fixed, thanks!
https://hg.libsdl.org/SDL/rev/21ccd40c778a

We currently don't expose the other XInput devices through the game controller API since they don't have all of the expected controls. If you want to use the other XInput devices with the game controller API, you can do something like this:

SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID( device_index );
if ( SDL_memcmp( guid.data, "xinput", 6 ) == 0 && !SDL_IsGameController( device_index ) ) {
	char pszGUID[ 33 ], pszMapping[ 128 ];
	SDL_JoystickGetGUIDString( guid, pszGUID, sizeof( pszGUID ) );
	SDL_snprintf( pszMapping, sizeof( pszMapping ), "%s,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", pszGUID );
	SDL_GameControllerAddMapping( pszMapping );
}
Comment 6 Sam Lantinga 2014-06-24 22:04:10 UTC
The size of pszMapping above should be 280, not 128.