Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SDL_gamecontrollerdb mapping configuration format extension to handle inverted axis #1166

Closed
SDLBugzilla opened this issue Feb 10, 2021 · 0 comments
Labels
enhancement New feature or request

Comments

@SDLBugzilla
Copy link
Collaborator

SDLBugzilla commented Feb 10, 2021

This bug report was migrated from our old Bugzilla tracker.

Reported in version: HG 2.0
Reported for operating system, platform: All, All

Comments on the original bug report:

On 2013-10-24 10:14:39 +0000, devnewton wrote:

The SDL_gamecontroller API configuration format ( see http://hg.libsdl.org/SDL/file/4f0f7b64afa5/src/joystick/SDL_gamecontrollerdb.h ) does not seems to handle axis direction: for example when you have righty:a3 how do you know if a value is up or down when positive or negative?

I propose the following improvements:

For buttons:

  • a:a0 => a button is pressed, when axis 0 is not in dead zone.
  • a:a0+ => a button is pressed when axis 0 is positive.
  • a:a0- => a button is pressed when axis 0 is negative.

For directions:

  • lefty:a3 => move up when axis 3 is negative, move down when axis 3 is positive
  • lefty:a3i => move down when axis 3 is negative, move up when axis 3 is positive.

On 2013-11-11 01:48:25 +0000, Sam Lantinga wrote:

Joseph Carter also proposed an extension for handling directional pad in bug 2181.

On 2013-11-11 01:49:08 +0000, Sam Lantinga wrote:

*** Bug 2189 has been marked as a duplicate of this bug. ***

On 2013-11-11 01:52:45 +0000, Sam Lantinga wrote:

I discussed it with Alfred and we're both comfortable with extending the mapping syntax to handle different cases.

Joe, feel free to collect the different cases we want to handle on the mailing list and propose a syntax extension.

On 2013-11-11 01:53:43 +0000, Sam Lantinga wrote:

Also, for each of the proposed extensions, please have a real world use case in mind. devnewton, can you describe the device that you're trying to solve for?

On 2013-11-11 03:01:09 +0000, Joseph Carter wrote:

Sam, I've got a couple of USB controllers providing a digital DPad that appears as a pair of axes. The axes are fake, of course because the pads are digital. I think these are reasonable to map as GameControllers for the following reasons:

  1. The XBox 360 and XInput support retro/digital controllers for both retro games and modern games that work best with digital controls such as (fighting games)
  2. Though these pads simulate axes because that's typically what classic PC joysticks tend to look for, the XInput API would present any such XInput device as having no axes, one hat, A/B/X/Y, LB/RB, Back/Start/sometimes Guide, and if LT/RT are present (they're not in my examples) they'd be digital.

Because the bug is now merged as a duplicate, I can no longer see my original syntax proposal (and I do not remember precisely now if I suggested anything beyond the above suggestion for stuff like dpleft:a0-,dpright:a0+ etc.

Regarding inverted axes, I might have suggested lefty:a3- but that could be messy. Having lefty:-a3 might make more sense for that, though again I don't see any particularly good reasons to do that over lefty:a3i.

We can already invert and otherwise twiddle hats in creative ways, and unless someone has a good usage case for inverting a button state or something, I don't see a need for that.

Maybe some specifier for the dead zone size? On my actual actual XBox 360 controller the dead zone is disgusting—easily ±4096 and probably higher would be wise. I don't have the XInput header in front of me for what Microsoft's default is, but it's pathetic. :) Fortunately every Logitech, PDP, MadCatz, Sony, etc controller I've used with analog sticks has had a far less annoying value. Of course some controllers (such as Logitech F-?10 apparently) pretend to be just as crappy as Microsoft's controller in XInput mode. This is beyond SDL's ability to control, but specifying the typical dead zone if we know it would be useful.

Now might also be a good time to begin including a platform as context for the GUIDs. Since we know the platform for every controller currently in the database, that's easy to do. Any mapping added outside of SDL that doesn't specify a platform would be assumed to be using the current one for backward compatibility, but I need to think about the best syntax to avoid breaking anything that tries to parse the strings without using SDL to do it.

Sam, do you know if Steam parses those SDL mapping strings at all?

I'll think about this a little and propose something on the list in a bit. :)

On 2013-11-11 03:17:26 +0000, Sam Lantinga wrote:

Yes, Steam parses those mappings. Don't overthink it, just figure out what problem you're solving and go with that. :)

On 2013-11-11 12:21:15 +0000, devnewton wrote:

(In reply to Sam Lantinga from comment # 4)

Also, for each of the proposed extensions, please have a real world use case
in mind. devnewton, can you describe the device that you're trying to solve
for?

Here is two case:

  1. I have a "Mega World USB Game Controllers" gamepad. On some game (like Trine 2), the right stick y axis is "inverted". I dont know if it is an hardware or driver issue, but some game does not provides a way to handle this case.

  2. On my own games, I would like to let the player associate an action to an axis move. For example, in 2d platformer, console gamers like to use a button to jump and press "up" to open doors, but PC gamers prefer to use "up" to jump and "down" to open doors.

On 2013-11-13 08:43:44 +0000, Joseph Carter wrote:

I don't consider the second case you provide there to be an appropriate use of game controller mappings in SDL, fwiw. The GameController mapper exists because there is absolutely no discernible correlation at the software level between two controllers that LOOK identical, but are made by different vendors.

Let's take the XBox 360 controller and the Logitech Dual Action as examples. Other than swapping DPad for left stick, they should be identical. But they're not. On the XB360 controller, button 0 is A. On the Logitech, the button in that spot is button 1. The equivalent of the X button is button 0. That's what GameController mappings are for.

So if you want dpdown to open a door, that's up to your game either to provide a controls profile or let the user choose. What GameController does is ensure that you can provide some sane defaults, assuming that what the user's got in their hand is either the XB360 controller, or some analogue SDL has made to appear to be an XB360 controller. It's not a general purpose input bindings system and isn't meant to be.

On 2013-11-13 15:44:16 +0000, devnewton wrote:

What GameController does is ensure that you can provide some sane defaults

If I am not able to know what is "up" and what is "down", I cannot provide sane defaults.

If you dont like my example, think about other game types: try to play a dual stick shooters with some axis inverted :-)

On 2013-11-13 17:01:52 +0000, Joseph Carter wrote:

I think you misunderstood me, and perhaps I misunderstood you as well.

SDL's job is to give you a controller such that if a control exists, it does what you expect. Up is up and down is down. What "up" and "down" do in your game would be up to your game.

Ryan and others have contributed suggestions, and the latest thought for syntax improvement is here:

http://forums.libsdl.org/viewtopic.php?p=40642# 40642

Inverted axes are definitely on the list as important to support.

On 2013-11-25 18:10:52 +0000, Gabriel Jacobo wrote:

What about cutting ourselves some future slack and add a tiny bit of versioning?

Let's say...if the string starts with the GUID we call that "v0"
If it starts with "vxx" (v1, v2, v1234) it means it follows a different protocol, which in turn could allow us to make backward incompatible changes if needed. I'm thinking about this not for the embedded strings, but for external mapping loading.

An example:

030000005e0400008e02000010010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,

vs

v1,NEW AWESOME BACKWARDS INCOMPATIBLE FIELD,030000005e0400008e02000010010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,

On 2013-11-25 21:14:30 +0000, Joseph Carter wrote:

I had considered that Gabriel. The reason I didn't go there was that all we really need beyond the current GUID for external loading later on is to know the platform associated with the GUID. Ryan's suggestion that we could just include platform:whatever in with the button mappings works there since old versions of SDL should ignore the "unknown button" properly and newer versions would see a mapping sans platform as belonging to the current platform. If asked for the mapping string for that GUID, SDL would return one with no platform, obviously.

The other things that there seems to be consensus on are specifying a half-axis using a0+ or a0-, inverting an axis with nobody objecting to the syntax of a1~, and that dead zones should be possible to specify.

I have NO simple and obvious solution for how to automatically determine a dead zone in something like Steam or otherwise. The best I've got is let the user fiddle with it until they're satisfied and find some method of crowdsourcing the users' preferences to determine a reasonable default. But I do have tokens for doing it: leftdzone, rightdzone, lefttriggerdzone, and righttriggerdzone. For XInput, it's obvious what to use by default because XInput specifies what you should use in the headers. It's intended to be hard-coded, apparently. And the values are STUPID high, resulting in much aggravation to anyone using a controller that isn't as pathetic as Microsoft's. ;)

Those things I think we should do—with the caveat about dead zone selection being what it is.

There was an additional suggestion which got no comments that we ought to add a token for determining the TYPE of controller so that one could show a generic controller with the appropriate button layout. PS, XBox, SNES, etc. I don't like this suggestion personally, simply because GameController is the "generic" controller type to be displayed. However you want to show it. XBox-like, PS2-like, or whatever you've got.

I would like to see SDL recognize some basic controller types or figure out what controls are and aren't present, but … I can't honestly come up with a good way to do this cross-platform. SDL can tell what is and isn't there based on the mapping string usually, except in the case of XInput where SDL's best bet is a Joystick API change that lets you ask XInput what kind of controller you've got. And older versions of XInput will simply lie because they don't actually know. ;) But even those that do can't tell you what buttons exist, only which ones are required, which are optional, and if your analog triggers might be digital (which is already the case with SDL anyway…)

And if XInput isn't frustrating enough, there's Apple's GCGamePad API which does not expose the start button as a button, but rather as a leading edge triggered callback whose expected behavior is fixed. But that rant is for another day. :)

I don't see a solution to this problem at the moment, so I suggest we do what we can do: Leave it be. Unless someone comes up with a more useful suggestion.

On 2016-12-27 09:51:40 +0000, Sam Lantinga wrote:

I've implemented support for inverted axes and independently binding separated halves of axes:
https://hg.libsdl.org/SDL/rev/5ea5f198879f

The syntax for binding half of a game controller axis is:
-leftx
+leftx

The syntax for binding half of a joystick axis is:
+a0
-a0

The syntax for inverting an axis is:
a0~

The controllermap test program has been updated to generate the new syntax controller config if it detects the appropriate binding types, and allows you to map a D-Pad as a thumbstick and vice versa.

@SDLBugzilla SDLBugzilla added the enhancement New feature or request label Feb 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant