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