![]() |
Extending GameController mapping syntax | ![]() |
Joseph Carter
![]() |
![]() |
Hi everyone,
In reference to bug #2181: https://bugzilla.libsdl.org/show_bug.cgi?id=2181 Sam's asked me to put together a proposal for improving the mapping syntax used for GameControllers to cover a few cases that pop up, but which we cannot really address at present. TL;DR: uuid(:platform?),name,a1:a1i,dpleft:a4-,dpright:a4+,… Problem #1: Retro controllers tend to pretend their digital DPads are analog sticks. A modern Windows XInput device that implements retro or arcade-style controls will not provide an analog stick at all, and instead provides either a 4 or 8 way hat. SDL's GameControler interface is modeled on XInput, for better or worse. My opinion of this tends to vary widely. ![]() it is, and so we should map those fake analog sticks back to the digital buttons that they really are. I have two examples: Buffalo Classic USB Gamepad for PC http://is.gd/pbPPdR (Amazon link) Axis 0 is left/right and 1 is down/up. An EXCELLENT controller. If you find yourself wanting a retro controller that actually feels like the original, I can't recommend this one enough. It costs a little more than some, but the build quality makes up for it. Retrolink USB SNES Classic Controller http://is.gd/JtYLcs (Another Amazon link) Axis 4/5. Axes 0-3 do not actually exist. The controller feels light and cheap compared to the original or the Buffalo. Half the price, but you may find yourself taking it apart out of the box to remove flashing from the buttons, etc… (Mine was okay out of box.) I can see two ways to do this syntactically, but I think the sanest one is this for the Buffalo: dpup:a1+,dpdown:a1-,dpleft:a0-,dpright:a0+ It wouldn't be terribly hard to implement this syntax in SDL at all. Problem #2: Inverted axes. At least one example noted in the bug report above has an inverted Y axis. In the bug, devnewton reports that at least one gamepad produced by Mega World Holdings (he didn't specify which one) has the Y axis inverted. He proposed the syntax of a1:a1i for this. a1:a1- is already proposed for another use above, and a1:a-1 seems clumsy and confusing anyway. I think a1i works fine. Problem #3: We can decide to punt on this one. Currently, SDL's internal controller database includes #ifdef's based on platform—generally Linux, Windows, and Mac. Many other platforms don't actually have real GUIDs and for those that do, *shrug* At some point, we're going to need to keep the platform and the GUID together. We've kind of already talked about this on the list, but we got bogged down into the implementation details of servers and Steam and extension libraries and … everything. We could include a platform in the mapping string either before the GUID as either windows:341a3608000000000000504944564944 or possibly 341a3608000000000000504944564944:windows (with the latter being easier to implement in a backward-compatible way…) We might want to skip this one because of #4. Or we might want to expressly deal with it because of #4. I'd suggest the latter, and with the easier to implement syntax. If SDL encounters a UUID string with not platform, it would simply assume the platform was the current one. I do propose keeping the ifdefs for now nonetheless. No need for SDL to wade through Windows DB entries on Linux, or Darwin entries on Windows, but still avoids UUID clash on different platforms. Problem #4: Sam said I shouldn't over-think changes to the syntax here. Steam DOES parse these strings. Of course that means any changes we make at all are going to affect Steam, so perhaps the best thing to do is to make those changes now if we're going to and give Valve as much lead-time as possible. (This might qualify as over-thinking it…) Problem #5: If you've got some other edge-case thing that the mapping string cannot do at present, but you have a need for it, now's the time to speak up. :) Joseph _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
||||||||||
|
![]() |
Extending GameController mapping syntax | ![]() |
gabomdq
![]() |
![]() |
2013/11/13 T. Joseph Carter
What about following the venerable tradition of C and using ! as the operator in this case... a1:!a1 -- Gabriel. |
||||||||||||
|
![]() |
Extending GameController mapping syntax | ![]() |
Ryan C. Gordon
Guest
![]() |
![]() |
Dead zones? --ryan. _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
||||||||||||
|
![]() |
Extending GameController mapping syntax | ![]() |
Joseph Carter
![]() |
![]() |
On Wed, Nov 13, 2013 at 10:19:31AM -0200, Gabriel Jacobo wrote:
Mostly that SDL does a switch on the character following the : to determine what kind of control is being mapped, a, h, or b. Trackball isn't supported obviously, so there is no t! And since GameController is limited to XBox 360 controllers, The DS4, WiiMote, and Wii U controller relative inputs don't map to anything. Actually, the more I look at this stuff, the more I'm coming to realize that GameController isn't really the common standard I'd first hoped it'd be. In some cases it's too limited. In others, we're gonna try to shoehorn devices into it that don't really belong shoehorned into it. I don't really see an alternative, though, and at any rate the decision for SDL 2.x was already made. Joseph _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
||||||||||||||
|
![]() |
Extending GameController mapping syntax | ![]() |
Joseph Carter
![]() |
![]() |
On Wed, Nov 13, 2013 at 08:54:27AM -0500, Ryan C. Gordon wrote:
I've thought about that. I'm just not sure what to do with it. My Microsoft XBox 360 controller has a disgusting dead zone. I find that ±4096 is not quite big enough, and I understand under XInput it's actually bigger than that (and deservedly so if the slop and weak centering in this example is anything to go on!) My PDP AX.1 has a tiny dead zone by comparison, but with a noticeable jitter in the low order bit of at least one axis. My venerable old Logitech Dual Action has everything else I've got with real analog sticks totally beat with a dead zone literally of ±128. Joseph _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
||||||||||||||
|
![]() |
Extending GameController mapping syntax | ![]() |
Jonny D
![]() |
![]() |
Wow, those are nice deadzones.
Jonny D |
||||||||||
|
![]() |
Extending GameController mapping syntax | ![]() |
Ryan C. Gordon
Guest
![]() |
![]() |
Have the GameController API reports axis values smaller than the deadzone as zero? Default to a deadzone of 0 if not specified. Actually, maybe we should talk about the mapping string being a key/value thing, for future expansion? Something like: guid=9868734324234;name=X360 Controller;platform=windows;leftstick=axis1;leftstickdeadzone=8000;etc (or whatever.) Old strings would still parse and apply reasonable defaults for new fields. Just an idea. --ryan. _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
||||||||||||
|
![]() |
Extending GameController mapping syntax | ![]() |
Joseph Carter
![]() |
![]() |
When Microsoft kills a zone, they nuke it from orbit!
(Or did you mean the Logitech? Yeah, it's pretty awesome. Too bad it lacks analog triggers and a guide button eh?) Joseph On Wed, Nov 13, 2013 at 09:57:01AM -0500, Jonathan Dearborn wrote:
_______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
||||||||||||
|
![]() |
Extending GameController mapping syntax | ![]() |
Joseph Carter
![]() |
![]() |
I like it.
So I will revise the proposal thusly: To do this Use this ------------------------------------------------------------ Bind DPad to an axis dpleft:a0-,dpright:a0+ Invert an axis lefty:a1~ Define a deadzone leftdzone:5000 Indicate GUID context platform:happyos Edge cases/issues that come to mind: - Cannot invert half an axis. (Specify the other half, duh.) - Mapping half an axis to an axis ought to work? - Analog axis -> digital button will use a fixed threshold. - Inverted axis -> digital button is a no-op. - Platform string is probably case-sensitive. (Use lowercase.) - Specifying an unknown platform will disable a mapping. - If SDL is guessing about values, it shouldn't write them out. Seems ~ makes more sense than ! for inversion. Technically we're talking about ~a1+1 here, but whatever. ![]() to adapt to this. Same for half-axis mapping Again, if we sort it out now, they'll have lead time. The leftdzone, rightdzone, lefttriggerdzone, and righttriggerdzone additions work the same as platform. If you don't know what to do with the token, skip it. Defaults to 0 if unspecified. The platform being just another token allows it to be skipped by anything that doesn't recognize it. It's assumed to be "any" platform if unspecified, but an unrecognized platform will be disabled. Logically we would want to associate platform and GUID, but backwards compatibility doesn't allow that and anything that would care is going to parse the mapping string anyway, so it does not really matter except to my OCD. :) The fixed threshold for analogs as digitals is irrelevant in the real world because the threshold will be outside any realistic dead zone for an actually analog control, but much less than the simulated analog value of a digital control. It ain't broke, really. Anything else? Joseph On Wed, Nov 13, 2013 at 10:22:54AM -0500, Ryan C. Gordon wrote:
SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
||||||||||||||
|
![]() |
Extending GameController mapping syntax | ![]() |
mungewell
![]() |
![]() |
[Appologies if this email doesn't thread properly]
Regard D-Pads: The root cause of 'confusion' is that D-Pads are not Hats, and vice versa. The behaviour of the controller is declared in it's USB HID descriptor. D-PADs are described as switches, whilst a HAT is more like a dial with a null state. This is further compounded as Windows and Linux treats these differently. For the controller I have, the HAT is reported on the USB bus as degrees (with 8 possible positions) which Linux converts into an X-Y axis. – Logical Maximum (7), Physical Maximum (315), Report Size (4), Report Count (1), Unit (Degrees), Usage (Hat Switch), ; Hat switch (39h, dynamic value) Input (Variable, Null State), Unit, – Other comments: Please watch out of deadzones on axis with few positions, we need to ensure that all values are selectable. For example the Steelseries SWR-S1 has some dials (of 4 and 16 positions), which cause problems. Cheers, Simon. _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
||||||||||
|
![]() |
Extending GameController mapping syntax | ![]() |
Terry Welsh
Guest
![]() |
![]() |
No sure if anyone else has spotted this, but I have also seen a case
where the input mapping for Xbox controllers is different across linux distros. That might need to be accounted for in your platform field. Or that might just be over-thinking things a bit more. -- Terry Welsh www.reallyslick.com _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
||||||||||
|
![]() |
Extending GameController mapping syntax | ![]() |
Jared Maddox
Guest
![]() |
![]() |
I'm going to suggest adding bracket pairs and both single-quote and double-quote strings, under the rule that if they have anything OTHER than whitespace in them, they should be ignored. I suggest this only because it might allow us to avoid our present selves' stepping on our future selves' toes. With, of course, one exception (because there's always an exception ![]()
I would like to suggest the following range syntax: [0...128] What does it do? Match everything from 0 to 128. You could maybe select extra zones, like this: [0...128,192...256,1024] . Thus, a flexible syntax to specify deadzones, which can later be applied to other things, e.g. any case where two axes report as different halves of the same axis, or "throttle" axes that are only supposed to be used with specific positions, instead of all of the positions that the actual hardware reports. Certainly relevant to specifying partial-axes. Might be relevant to:
A "better" standard could be devised, but I suspect that ultimately it would generify things to the point that the only difference between e.g. a keyboard and a joystick was the bits-per-axis and the axis name (in the case of number pad keyboards the axis-count could even be the same...), which I suspect to be a little TOO generic for the average SDL user. Even more so when you consider that ANY "axis" could be either relative or absolute, and that you would need a way to find out about axis associations. Probably for the best that a "full-power" solution be kept seperate, and only the generically useful stuff be here.
If a valid meaning (preferable "ignore this") is assigned to empty bracket pairs, then a token could later be devised that takes non-empty brackets as a specification, and parses the contents however it wants. That could be a base for platform/GUID mapping. _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
||||||||||||||||||||||||||||||||||||||||||||
|
![]() |
Extending GameController mapping syntax | ![]() |
Sam Lantinga
![]() |
![]() |
Have you thought about how you would specify this in some sort of user interface? It should work naturally, not be a list of dropdowns. :)
On Wed, Nov 13, 2013 at 8:51 AM, T. Joseph Carter wrote:
|
||||||||||||||||
|
![]() |
Extending GameController mapping syntax | ![]() |
Joseph Carter
![]() |
![]() |
GameController does not actually expose a hat at all, however XInput
falsely claims the XBox 360 DPad is a hat. (I cannot recall if it is 4 or 8 position in Windows offhand, but I know what it is inside the controller itself!) The GameController API reports the DPad as four buttons: dpup, dpdown, dpleft, and dpright. Which is what they actually are. It is possible to map a hat to the DPad buttons and this is done already. The specific case we want to fix here is where a four digital switches as a DPad pretend to be two analog axes and report them as such via USB HID. If we happen to know they're not analog sticks, we should be able to tell SDL that they're actually a digital DPad and to use them as such. That's presently not possible due to syntactic deficiency in the GameController mapping string. Ryan's suggestion is that while we're at it, we add support in the joystick mapping syntax for specifying a given joystick's dead zone. All real analog sticks are going to have a dead zone, and some exhibit a small amount of jitter in their ADCs' low order bits. If you know of a given stick's dead zones, specifying it allows SDL to report the sticks as centered if they fall within that dead zone, and allowing an application to query it can help programs determine how to scale the analog data they receive. If unspecified for a joystick, there is no dead zone. Again for an analog stick that's simply not true, but all we can do is help developers out when we know what it is. Joseph On Wed, Nov 13, 2013 at 12:48:49PM -0500, wrote:
SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
||||||||||||
|
![]() |
Extending GameController mapping syntax | ![]() |
Joseph Carter
![]() |
![]() |
More information required. You're saying two different Linux
distributions report the same GUID but the controls are not consistent for that GUID? Please file a but with specifics. ![]() just SDL, and with documented instances we can send the Narn bat squad after those distributions' developers or something. Joseph On Wed, Nov 13, 2013 at 10:01:32AM -0800, Terry Welsh wrote:
SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
||||||||||||
|
![]() |
Extending GameController mapping syntax | ![]() |
Joseph Carter
![]() |
![]() |
All but the dead zones. The only sane way to collect dead zones if
we cannot get them from the device (as I understand we can with XInput, though I know we usually cannot) would be to have the user move the sticks and let them center several times, pad the values a bit, and rely on crowd sourced data otherwise. But also, I know that XInput absolutely lies about the dead zones for the Logitech F-?10 pads—but that's intentional on Logitech's part. They did it to make their controllers "more compatible" with Microsoft's despite Logitech using a quality part and Microsoft using something that centers like a cheap factory second from some Chinese forced labor camp. (Seriously, dead zone of probably 6000!) If XInput weren't mandatory for the Windows Store, a lot fewer people would be using it. :) Joseph On Wed, Nov 13, 2013 at 10:00:56PM -0800, Sam Lantinga wrote:
_______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
||||||||||||||||||
|
![]() |
Extending GameController mapping syntax | ![]() |
Joseph Carter
![]() |
![]() |
On Wed, Nov 13, 2013 at 11:00:29PM -0600, Jared Maddox wrote:
Currently the token separator is the comma. The GUID field is fixed format, the name field … probably does not provide a means to cope with a comma in the joystick name but can otherwise contain just about anything else, and the other fields are order-agnostic name:value. Some values (namely hats) can contain :'s. It's entirely possible that the name could contain an unterminated ' or " at the moment. We MIGHT want to make sure SDL replaces or somehow escapes those characters in the name of any mapping it creates. I'd suggest replacing them with _ is probably sufficient. Anything more complex in terms of balanced quotes and whatnot is currently not syntactically valid and probably need not be implemented until the possibility changes. Joseph _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
||||||||||||||
|
![]() |
Extending GameController mapping syntax | ![]() |
Ryan C. Gordon
Guest
![]() |
![]() |
It's not so much lying as it is a hardcoded number: #define XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE 7849 #define XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE 8689 ...you can't query for deadzone information through the XInput API, and the docs tell you to use these defines, effectively hardcoding it into your app. I presume it's on hardware makers to match the X360 controller here. :/ --ryan. _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
||||||||||||
|
![]() |
Extending GameController mapping syntax | ![]() |
Ryan C. Gordon
Guest
![]() |
![]() |
It's worth noting that the name field doesn't _have_ to map to what the HID device reports (and often doesn't), so we can simply say "you can't have a comma in the name, it won't work." Although, I'm sure there's a "Widget Factory, Inc GameCube to USB converter box" name out there waiting to strike. --ryan. _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
||||||||||||
|
![]() |
Extending GameController mapping syntax | ![]() |
Joseph Carter
![]() |
![]() |
ZOMG you've GOT to be kidding me. 7849 and 8689!? Seriously?
I wasn't kidding about nuking the dead zone from orbit, I guess. Joseph On Thu, Nov 14, 2013 at 10:57:09PM -0500, Ryan C. Gordon wrote:
SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
||||||||||||||
|
![]() |
Extending GameController mapping syntax | ![]() |
Joseph Carter
![]() |
![]() |
Unless we turn it into "Widget Factory_ Inc GameCube to USB converter
box". :) Joseph On Thu, Nov 14, 2013 at 11:00:11PM -0500, Ryan C. Gordon wrote:
SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
||||||||||||||
|
![]() |
Extending GameController mapping syntax | ![]() |
David Olofson
Guest
![]() |
![]() |
On Fri, Nov 15, 2013 at 8:36 AM, T. Joseph Carter
wrote:
Wait... Are these deadzones implemented per axis, or as a square or circular area? Large per-axis dead zones completely ruin the experience in twin stick shooters and the like where you're effectively using at least one of the sticks to indicate direction. There, the dead zones (which should preferably be relatively large, unless you have analog power control for movement) need to be implemented in 2D, after combining the directions of the respective stick - otherwise you simply cannot aim near the horizontal and vertical directions. BTW, I'm suspecting that my Logitech F-* pad is implementing (annoyingly large) per-axis dead zones in hardware or something... But, I've only used it with SDL 1.2 so far. Can't remember if I'm seeing the same problem on the OS level. Will check ASAP. -- //David Olofson - Consultant, Developer, Artist, Open Source Advocate .--- Games, examples, libraries, scripting, sound, music, graphics ---. | http://consulting.olofson.net http://olofsonarcade.com | '---------------------------------------------------------------------' _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
||||||||||||
|
![]() |
Extending GameController mapping syntax | ![]() |
Joseph Carter
![]() |
![]() |
On Fri, Nov 15, 2013 at 09:01:50AM +0100, David Olofson wrote:
Those are left and right stick, respectively. And while I do not have any of the F-?10 sticks to play with, on the Mac my older Logitech Dual Action uses the same driver as the F-310. It has a very solid centering and is within ±128. ![]() reported to have a very small dead zone under Linux, with many complaints that the gamepad is crippled by Logitech under Windows. Someone has a 3rd party driver that behaves better, just as there is a 3rd party driver that makes the XBox 360 controller under DirectInput map the triggers to separate axes with positive-only results basically just as SDL does it. Joseph _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
||||||||||||||
|
![]() |
Extending GameController mapping syntax | ![]() |
![]() |
Extending GameController mapping syntax | ![]() |
Gerry JJ
Guest
![]() |
![]() |
A few things.
I think it'd be neat if we added general controller type/labels to controller definitions, to be used by games to decide what to call various buttons. For example, if a game wants you to push the A button to continue, with xbox360 labels it'd show a green A button, with playstation/dualshock labels it'd show an X button, with SNES labels it'd show a yellow B button. Internally, they'd all be handled as the Xbox 360's A button of course, it'd be a purely optional cosmetic thing. Something like this: ...,x:b2,y:b3,labels=xbox ...,x:b2,y:b3,labels=psx ...,x:b2,y:b3,labels=snes SDL_Something SDL_GameControllerGetLabels (SDL_GameController*); Should probably return an enum value, but a string would work too. Another thing, has anyone thought of how Valve's Steam controller will work with SDL's controller API? It doesn't have the traditional face buttons in the usual constellation, so a game depending on that layout might want to map the buttons to clicks in the corresponding areas of the right trackpad. However, a different game might want clicks on the right trackpad to send stick-clicks instead, with ABXY mapped differently. I know Valve's going to have a config utility for controller mappings, but that will probably only work with Steam games (automatically, anyway). I was thinking this could be solved with SDL hints, but we could also add some functions to SDL that let games specify what inputs they're interested in ("i want two sticks, stick-clicks and a button", or "i want a dpad and 4 buttons (ABXY)", etc). That would provide SDL with enough information to select an appropriate mapping if several are available, but it'd also come in handy for other types of controllers that don't have all the inputs available on an Xbox 360 pad. If a game needs an analog stick, SDL could tell it that the SNES pad mapped to input #0 won't do, but the pad in #1 would work. Thoughts? (Oh, also, can we be sure that all controllers of a particular type will all have the same dead zone?) -g _______________________________________________ SDL mailing list http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org |
||||||||||
|