It has become important in my engine to support the Xbox 360 Controller For Windows, the API for this focuses on a single function (XInputGetState) which is much simpler than the SDL_Joystick API, and
is stateless by nature (calling this function yields a timestamped state struct, or tells you the controller is unplugged, or an error code), which makes it easy to develop games supporting this
controller in particular on Windows.
SDL 1.3 does not currently support the Windows XInput API necessary to support this controller (using it via DirectInput exposes the triggers incorrectly, aside from also lacking rumble and headset
capabilities), so I have begun implementing my own support in my engine in the interim.
At this point I took a step back and realized that there are certain market-dominating controllers (360, PS3, Wii, etc) that users greatly enjoy using with their games and fully expect them to work on
all platforms without any kind of ingame configuration menu, the burden of supporting these specific gamepads in an app is actually less than dealing with the common case of axes+balls+buttons, but
supporting each controller on each platform with different mappings is a major burden.
My proposal consists of these somewhat unrelated parts:
-
A simple function that fills in a user-supplied state struct with new information (bumps timestamp if anything has changed, updates axes/balls/buttons, controller status - unplugged/error/active),
this function would be an alternative to the SDL_Joystick API with significantly less burden on both the app and the SDL implementation itself, this struct would be somewhat large but only portions of
it are updated (according to the number of balls/axes/buttons on this controller), and accommodates hotplugging controllers if the app periodically polls for additional controllers.
-
Specific controllers having guaranteed mappings on all platforms; if state.controllerType == SDL_CONTROLLER_TYPE_360 then you can be sure that .buttons[SDL_CONTROLLER_360_A] is the A button on a
360 controller.
-
it would be possible to expose virtual controller mappings through this API, like keyboard + mouse as a single cohesive device consisting of axes and buttons (treating keys by physical position,
not by letter), so the user could pick keyboard+mouse or 360 controller or ps3 controller or wii controller in the menu, all would be enumerated appropriately and could be configured by the same
mechanism, and it is an important observation that the keyboard+mouse choice may be absent on some platforms (like a mobile phone or tablet), thus indicating to the app that this would be a poor
choice of control scheme and it should fall back to one of the other detected controllers (such as a touchscreen).
Expected result:
An SDL app can implement support for the 360 controller, and get expected results on most platforms, telling the user that their controller has been detected and configured automatically, and offering
the option of a custom configuration if desired by the user.
Generally the app would implement this by having a table of mappings to in-game controls for each known controller, and let the user make a custom mapping if desired (in .ini file format or a
graphical menu).
The majority of SDL apps that support controllers at all, would support all common controllers with a minimum of effort.
Comments?–
LordHavoc
Author of DarkPlaces Quake1 engine - http://icculus.org/twilight/darkplaces
Co-designer of Nexuiz - http://alientrap.org/nexuiz
"War does not prove who is right, it proves who is left." - Unknown
"Any sufficiently advanced technology is indistinguishable from a rigged demo." - James Klass
"A game is a series of interesting choices." - Sid Meier