Re: SDL's gamecontrollerdb.txt vs. kernel fixes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi everyone!

I should add a tiny disclaimer and say kernel-level stuff is definitely out of my normal range, so the overwhelming majority of my experience is at a much higher level than this... but the least I can do is provide some context explaining what it's like on our end at the moment.

In the case of the GPD Win 2, the SDL_GameControllerDB addition was actually part 2; part 1 was the xpad patch I sent out yesterday:

https://patchwork.kernel.org/patch/10436745/

This is usually the entire process for me: Add/Fix a driver, bind it to our controller layout. Part 1 is pretty easy if a driver exists, not so easy for scenarios where a driver doesn't exist - the current example that's been bothering me lately is the Wii U GameCube adapter, which is currently just a program using udev/libusb:

https://github.com/ToadKing/wii-u-gc-adapter

How this could be made easier, I have absolutely no idea, mostly because I've never written a driver. So I'll be pretty useless/dumb on that front.

Where I _might_ be useful is Part 2, where we bind joystick index values to a known layout. I'm totally with Benjamin on this, we really should just make the SDL_GameController config an established standard, and to some extent this is already in progress; GLFW uses this format for their joystick implementation, Steam uses (well, _used_, but I'll talk about that in a second) it to bind joysticks to games that don't have config entries for new devices, GOG recommends an SDL config generator tool written by General Arcade to configure devices, and I believe Itch is looking into controller support via this system as well. Developers love it, customers love it, even digital game stores love it, it solved a long-standing problem extremely well in a whole lot of ways.

Where this gets ugly is the question of how low-level this standard should go. We have two horror stories that are worth looking at:

First is Microsoft's XInput2, meant to be the replacement for their old DirectInput API. When the Xbox 360 went out Microsoft basically scrapped the idea of a joystick with axes/buttons/hats and said screw it, we'll give them exactly one layout with these buttons/sticks, and forget hats entirely, and there will essentially be one controller and one controller only. It did a lot of good for making game input code _not_ a horrible mess of random integer values, but it came at the cost of having absolutely no idea what the actual controller is. For example, a PS4 controller has the same layout as an Xbox controller but XInput2 gives you no way to find out that it's a PS4 controller, which is a problem because the button names/glyphs are totally different. Without knowing what controller it really is, we can't make a good user interface, and the game will be hard to understand as a result. What a surprising amount of devs do (including the SDL team) is support both XInput2 and DirectInput at the same time, which is about as fun and reliable as it sounds.

So, in theory, someone could come up with a system for Linux that just maps everything before SDL gets it, and SDL could pick up that one generic device handle, but we risk losing critical information about the real device, and attempts to add device-specific information to what's supposed to be a generic system kind of defeats the point, and it risks having devs support two input APIs instead of one.

Then there's the second horror story, which is Steam Input. For reasons so bizarre I assume only Neil Breen could figure out what they even are let alone understand them, Valve quietly dropped their use of the SDL_GameController config format (which someone at Valve wrote, by the way) and came up with this HUGE monster of a system that basically tries to be a udev/libusb program for literally everything, blacklisting the real device in favor of a "Steam Virtual Gamepad" that not only does the generic-device-handle thing I just mentioned in the last paragraph, but also tries to make it so layouts can change arbitrarily and without context. For example, they recently added support for the Nintendo Switch Pro Controller, and Nintendo controllers have the glyphs for A/B and X/Y swapped, though it still matches the physical layout of a 360 controller, so they added this global flag that tries to force the _physical A/B X/Y locations_ to be swapped everywhere regardless of context!

If you can barely understand what I'm talking about, know that everyone else is just as confused as you are, especially when their reliable 10-year-old controller suddenly just stops getting recognized for no reason, which happens a LOT with this new system.

To bring it back around to Linux specifically, the _one_ argument that can be made for this absolute train wreck of a system is that you may need to re-bind button values to something else, which the game may not support. For example, a game might bind "jump" to the A button, but a customer might need it to be on something like Right Trigger, so Steam Input lets you do that. While we'll ignore that this is done behind the game's back and therefore makes the game user interface confusing, what's interesting is that config formats like SDL_GameController already let you do that...? Here's a trimmed down sample:

"030000005e0400008e02000000000000,X360 Controller,a:b0,b:b1,x:b2,y:b3"

Let's say this is in SDL's own database by default. If you wanted to swap A/B, for example, you can set an environment variable to just make it "a:b1,b:b0" for that specific title and it just works. This could probably even be extended to be changeable at runtime, so you can have one config layout for the menus and change it when you're in-game. And keep in mind, this is all assuming you don't have rebind support in your game, which, y'know, you could just support...


With all that in mind, this would be my personal wishlist for making joystick input easier to support: 1. Figure out how to quickly add new devices to drivers and make them work out of the box ASAP 2. Standardize SDL_GameController to simplify configuration without losing critical information 3. Look into extending SDL_GameController to support per-context configurations

I think #1 is what this thread should be about first and foremost. #2 is something the SDL team needs to do because it affects all platforms and shouldn't go at the OS level (unless we want another XInput2), and #3 is admittedly a hack that is driven largely by me wanting to catapult Steam Input into the sun and prevent anything like it from happening ever again. But I'd be interested in hearing perspectives in #1 that could affect #2/#3.

-Ethan

On 05/30/2018 05:26 AM, Benjamin Tissoires wrote:
Hi Bastien,

On Tue, May 29, 2018 at 12:17 PM, Bastien Nocera <hadess@xxxxxxxxxx> wrote:
Hey,

Ethan recently posted a patch to SDL's GameControllersDB to fix up
buttons on his GPDWin 2:
https://twitter.com/flibitijibibo/status/1000835085891973127

There are a couple of problems with this approach though:
- it only works with SDL, not with any other possible users of the
joystick API
- the parsing code depends on the SDL library, again problematic for
non-SDL programs

There are advantages as well:
- it's easy to write and test, there are test applications using SDL,
and fixing the problem is as easy as sharing a single line to add to a
file
- the documentation is pretty good:
https://github.com/gabomdq/SDL_GameControllerDB
which is better than:
https://www.kernel.org/doc/Documentation/input/joydev/joystick.rst

Can we think of a way where writing and testing "fixups" is easy enough
to do without having a kernel development tree ready, documentation
would better explain the different cases for fixups, and everybody can
benefit from having quirks written?
One thing that comes to my mind is that in evdev we have the ability
to remap a button/key from the userspace with an ioctl.
If it doesn't work for joysticks/gamepads, we should be able to have
an API that does it in the kernel and with a udev rule, or a hdwdb or
a udev intrinsic, we could just remap to the proper keys without
relying on an external lib.

Ideally, this should be carried (the hwdb / udev intrinsic) by SDL
developers so they can smoothly transition from their own file format
to a kernel fix.

OTOH, we had a somewhat similar issue with the Wacom devices. We ended
up having libwacom which provides a standalone library with those data
that any project can link against and use at will. So Maybe a solution
could be to ask the SDL devs to externalize this DB and have something
other projects can rely on.

You understand, I am not much in favor of fixing directly things in
the kernel, because you will end up breaking existing user configs,
for little benefits. I only agree with kernel fixes if the device
doesn't work or has missing features.

Cheers,
Benjamin


--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux