Comments (10)
Steam provides SDL mappings by an internal vendor-bundled database to games automatically, it does this on all platforms. And it uses SDL itself as I could figure out by coincidence.
I would pretend that the most-common use-case is using xpadneo to run Steam games in Linux. So we should stick to the mapping what Steam expects.
The other use-case is running Windows games through wine. It would be important to document how to pass SDL controller mappings to wine, and distribute mappings matching what xpadneo uses with the driver. From wine 3.3 onwards, it will support using SDL for gamepads, so passing SDL gamepad mappings via env is easy.
What other use-cases can we think of?
BTW: Native Linux games will always be a problem if they don't use SDL. Maybe the driver could implement a flip switch (defaulting to off) which switches to standard event codes. The problem here is that applications may expect the left trigger to be event code ABS_Z instead of ABS_BRAKE (the latter being what the controller natively sends).
There are very few games which seem to depend on order in jsX
, e.g. Metro Last Light and Cradle seem to be such games: They expect gamepads in DINPUT
mode (that mode does not have analog triggers but only digital triggers, have fewer axes, and the reported order of buttons is different). So having a mode parameter in the driver would be nice to support modes xbox
, android
, dinput
.
Apart from that, we should stick with the names that the physical controller has on the buttons: The event code for BTN_SOUTH
and BTN_A
is identical according to Linux sources. These buttons are not directional (multiple can be pressed at once, even across), and this A button has a green A printed on it. So it should be called BTN_A
in the driver source.
The dpad is actually implemented as distinct buttons (tho you are not able to press two opposite buttons at the same time, they are directional). It's not a hat switch. And as far as I found, it's exposed as absolute axes in Linux. According to Wine, Windows instead expects a radial measure, that is, it returns the section of a circle, one of eight directions. Not sure, if it could be exposed as DPAD_*
and how the Linux input layer would map that... The current implementation works for Steam and Wine.
from xpadneo.
Thank you for the answer, I will comment and think about the rest a bit later when I finished the other issues, but I remembered something I read somewhere and I will post it here to remember when I come back to this issue:
Apart from that, we should stick with the names that the physical controller has on the buttons: The event code for BTN_SOUTH and BTN_A is identical according to Linux sources. These buttons are not directional (multiple can be pressed at once, even across), and this A button has a green A printed on it. So it should be called BTN_A in the driver source.
VS.
Every gamepad device has at least 2 action buttons. This means, that every device reports BTN_SOUTH (which BTN_GAMEPAD is an alias for). Regardless of the labels on the buttons, the codes are sent according to the physical position of the buttons.
If all 4 action-buttons are present, they can be aligned in two different formations. If diamond-shaped, they are reported as BTN_NORTH, BTN_WEST, BTN_SOUTH, BTN_EAST according to their physical location. If rectangular-shaped, the upper-left button is BTN_NORTH, lower-left is BTN_WEST, lower-right is BTN_SOUTH and upper-right is BTN_EAST.
from xpadneo.
If all games have swapped X and Y buttons just because the Linux codes insists that the Y button should be west, and the X button north, then resistance is futile (tm). It's just against all expectations. I think the design is many years old. I can't think of a controller which has the buttons in rectangular shape, all are diamond shaped. The kernel is wrong here, hardware was implemented differently. Nobody cared.
BTN_X and BTN_NORTH are just aliases for the same hex code, let's not try to be smart. Let's call them BTN_X etc and be done with it.
Except for very unusual clunky controllers nobody would use today, the buttons are X left, Y top, B right, A bottom. The few exceptions that have X and Y swapped (which would fit the linux bill) also have A and B swapped (which is where it collides).
Maybe the north/south/east/west naming was made for controllers having shapes like Play Station controllers. Maybe those buttons have swapped roles there. Then everything would fit. The shapes there apply to roles: O and X mean yes and no, [] symbolizes a paper sheet meaning menu, /\ symbolizes point of view, or angle. Yes and no matches mostly the usage of A and B (A confirms, B cancels in menus). The Y button is used by some games as a weapon menu which would fit the west button on PS controllers. So that would explain it. The X button is used as an action/use button in most games, so do something you're looking at = point of view.
from xpadneo.
If all games have swapped X and Y buttons just because the Linux codes insists that the Y button should be west, and the X button north, then resistance is futile (tm). It's just against all expectations. I think the design is many years old. I can't think of a controller which has the buttons in rectangular shape, all are diamond shaped. The kernel is wrong here, hardware was implemented differently. Nobody cared.
BTN_NORTH
, BTN_SOUTH
,... was introduced by 3.11, so at the end of 2013 - that's not very old I think.
The xpad
driver was introduced 2002.
So we, as driver developers, should definitely stick to the relatively new kernel design guide. But, for sure, we have to take care for legacy too.
Concerning Input Codes BTN_A
, BTN_B
, ...
It is completely legal in my eyes to use BTN_A
for e.g. the Wii Controller, and the Cobra Gamepad and others which simply do not follow the diamond-shaped layout, but it is not for the rest. BTN_A
is not always equal to BTN_NORTH
- e.g. BTN_X
is not BTN_NORTH
on the Xbox Controller (but it is the same at the kernel code).
If you take a look here, you will see that the xpad
driver is one of the rare drivers for a diamond shaped layout which uses BTN_A
, BTN_B
and so on. All the others are joysticks or somehow special devices.
Today
The one who is wrong today is xpad - not the others, not the kernel π But it isn't xpad's fault - because it was developed before 2013...
The problem is that xpad is the de facto standard for the Xbox Controller. Therefore all the games think it is the xpad layout which is used when an Xbox Controller is recognized.
How can we support both?
I would suggest to offer a xpad
layout (which is in fact the one we use at the moment). As a second layout I would suggest one which follows the kernel standard, I would call this standard
or kernel
. I would start with these two layouts if you agree and we can discuss others (like dinput
) afterwards.
from xpadneo.
button | xpad |
kernel |
android preset |
microsoft preset |
---|---|---|---|---|
A | BTN_A |
BTN_SOUTH |
||
B | BTN_B |
BTN_EAST |
||
X | BTN_X |
BTN_WEST |
||
Y | BTN_Y |
BTN_NORTH |
||
Start | BTN_START |
BTN_START |
||
Select | BTN_SELECT |
BTN_SELECT |
||
Xbox | BTN_MODE |
BTN_MODE |
||
L1 | BTN_TL |
BTN_TL |
||
L2 | ABS_Z |
ABS_HAT2Y |
||
R1 | BTN_TR |
BTN_TR |
||
R2 | ABS_RZ |
ABS_HAT2X |
||
L Thumb | BTN_THUMBL |
BTN_THUMBL |
||
R Thumb | BTN_THUMBR |
BTN_THUMBR |
||
Left Stick X | ABS_X |
ABS_X |
||
Left Stick Y | ABS_Y |
ABS_Y |
||
Right Stick X | ABS_RX |
ABS_RX |
||
Right Stick Y | ABS_RY |
ABS_RY |
||
Dpad Up | ABS_HAT0Y |
BTN_DPAD_UP |
||
Dpad Right | ABS_HAT0X |
BTN_DPAD_RIGHT |
||
Dpad Down | ABS_HAT0Y |
BTN_DPAD_DOWN |
||
Dpad Left | ABS_HAT0X |
BTN_DPAD_LEFT |
from xpadneo.
The mapping goes like this: physical button
<--> HID usage
<--> Input Event
The xpad
and kernel
mapping are straightforward: we know how xpad maps an physical button to an event and we know how the kernel documentation prefers it. So we simply do not care about the inner HID usage
here.
Unfortunately, the android
and microsoft
presets are not really on the same layer... they describe how a physical button is mapped to an HID usage
but not to which Input Event
.
Anyway - I would simply use the default mapping there.
The problem now is, that the android
preset is simply wrong! It e.g. assigns usage_page: SIMULATION, usage: GAS
to the right shoulder trigger, but also usage_page: GENERIC_DESKTOP, usage: Rz
to right stick horizontal axis...
As a result, we have a mapping which does not map ABS_RX
or ABS_RY
, but ABS_Z
/ABS_RZ
and ABS_BRAKE
/ABS_GAS
I am still not sure if it makes senses to offer a mapping which is in fact corrupted - the only reason I can think of, is that maybe some higher layer is trying to fix the misbehaviour too.
from xpadneo.
As far as I can tell, "native" Android controllers (which you pair to your phone) have additional buttons (C and Z right of A,B and X,Y). That explains why the button order is mangled up. They also expose the triggers as gas and brake. There are additional shoulder buttons (L2 and R2) like on an PS4 controller. Now the crazy part is: Someone who made up his mind about it totally intuitively guessed Rx and Ry are right X and right Y - but of course it's rudder/roll X and Y for a third pair of axes of movement. OTOH, one could say "why the heck did controller driver designers put the rudder axes on the triggers?" - those aren't even axes. Not to mention that it makes no sense to have a pair of axes on two different rudders. But that was probably done for compatibility with all those controllers out there already.
The Android controller designer guy is probably the one who broke compatibility. I cannot see any reasoning behind this. The problem is that standard configuration expects the three X axes first, then the Y axes. That is, X1, X2, Rx, Y1, Y2, Ry, which is then exposed by drivers as (X1,Y1),(X2,Y2),(Rx,Ry). But the controller sends X1,X2,Y1,Y2,Rx,Ry or something similar weird. Usually, with the wrong mapping, the right Y axis is dead while I can use one trigger to change the right X axis.
It would probably work (and indeed does with some games), if games would not rely on offsets into an array of values but the actual meaning of those values exposed by the event layer.
And yes, then there's the Z axes, too.
It's hard to wrap your head around. The driver should simply correct this. In Windows mode, everything is probably okay and the gamepad exposes a standard mapping. I never tried that.
The Wine code has means of mapping Rx,Ry onto Z1,Z2 or vice-versa, depending on how many axes are reported - probably to compensate for those two common mappings. But it only works for the joystick interface, not for games using the xinput API. Those get passed through the Linux HID data. So Windows has exactly the same split architecture as Linux: an old API, and a new one = jsX vs eventX = winjoy vs xinput. The latter one has the additional layer (HID usage), the first one maps directly from button to reported event.
So, for consistency, we need to patch the middle layer as xpadneo currently does.
from xpadneo.
Wait, what?! Okay now everything becomes... even more confusing...
I'm not sure if I understood that correctly, what you are talking about is how the "original" Android controller does report it's buttons/axis - right?
They also expose the triggers as gas and brake.
If you say "triggers" you are talking about the L1/R1 buttons - right? What the heck? I always thought that the GAS/BRAKE is meant to be on the L2/R2 axis. That would explain why the HID report is reporting both, ABS_GAS/ABS_BRAKE and ABS_Z/ABS_RZ.
Now the crazy part is: Someone who made up his mind about it totally intuitively guessed Rx and Ry are right X and right Y - but of course it's rudder/roll X and Y for a third pair of axes of movement.
I'm out... Rx and Ry are on the shoulders? That's totally in contrary to what the Linux Gamepad Specification says (The left analog-stick is reported as ABS_X, ABS_Y. The right analog stick is reported as ABS_RX, ABS_RY.)
Can you maybe tell me where I can find some information about the "andoid controller" and its mapping?
I still do not really understand why they do it as they do.
It's hard to wrap your head around. The driver should simply correct this.
It is... I am really confused about what is the right way to correct it^^ By "simply correct this" you mean to offer an android
mapping which does... what? Like this?
L1 -> ABS_BRAKE
R1 -> ABS_GAS
L2 -> Ry
L1 -> Rx
Left Stick X -> ABS_X
Left Stick Y -Y ABS_Y
Right Stick X -> ???
Right Stick Y -> ???
I'm not even sure if we really need a android
mapping in linux
from xpadneo.
okay I slept on it for a night and I still don't know how the android mapping was meant to be by microsoft.
I therefore won't fix it in a magical way, our best bet is maybe to offer a mode which simply perform no mapping, so overall we will have then:
kernel
- as defined in the Linux Gamepad Specification. This Mapping will be the default (since "All new gamepads are supposed to comply with this mapping. Please report any bugs, if they donβt.").
xpad
- simulates the behaviour which is known from the legacy xpad driver, this is how it is right now
and
none
- which leaves is up to the HID/input system and behaves just as wrong as the hid-generic driver would, this is maybe necessary for higher layers that fix the misbehaviour themself.
Is this fine for everybody?
button/axis | xpad |
kernel |
none |
---|---|---|---|
A | BTN_A |
BTN_SOUTH |
untouched |
B | BTN_B |
BTN_EAST |
untouched |
X | BTN_X |
BTN_WEST |
untouched |
Y | BTN_Y |
BTN_NORTH |
untouched |
Start | BTN_START |
BTN_START |
untouched |
Select | BTN_SELECT |
BTN_SELECT |
untouched |
Xbox | BTN_MODE |
BTN_MODE |
untouched |
L1 | BTN_TL |
BTN_TL |
untouched |
L2 | ABS_Z |
ABS_HAT2Y |
untouched |
R1 | BTN_TR |
BTN_TR |
untouched |
R2 | ABS_RZ |
ABS_HAT2X |
untouched |
L Thumb | BTN_THUMBL |
BTN_THUMBL |
untouched |
R Thumb | BTN_THUMBR |
BTN_THUMBR |
untouched |
Left Stick X | ABS_X |
ABS_X |
untouched |
Left Stick Y | ABS_Y |
ABS_Y |
untouched |
Right Stick X | ABS_RX |
ABS_RX |
untouched |
Right Stick Y | ABS_RY |
ABS_RY |
untouched |
Dpad Up | ABS_HAT0Y |
BTN_DPAD_UP |
untouched |
Dpad Right | ABS_HAT0X |
BTN_DPAD_RIGHT |
untouched |
Dpad Down | ABS_HAT0Y |
BTN_DPAD_DOWN |
untouched |
Dpad Left | ABS_HAT0X |
BTN_DPAD_LEFT |
untouched |
from xpadneo.
Your best bet is to look at the SDL gamepad mappings. And don't take my memory of what Rx,Ry etc are too serious. While trying to figure out what goes wrong, browsing thru source codes over source codes, seeing how they shuffle around axes to fix non-standard mappings, I'm totally confused about what is what. And there even seems to be no exact clue which axis is named what. It may have one meaning in Wine, and another in the Linux kernel. Then patching the source only to see that it fixes one case (winjoy API) but not the other (xinput API) only adds to this confusion, then I tried patching the kernel (which fixed eventX but not jsX), I gave up and was a little pissed why this piece of hardware has such incompatible mapping for non-obvious reasons. Only later, I came across how SDL does this (it's not documented very well, the mapping helper tool also disappeared from libSDL). That helped in almost any cases except jsX and winjoy API were still wrong.
But it worked for me mostly until Steam introduced some fixes at which everything broke into pieces again and I was kind of tired trying to figure out what's gone wrong now. Then I stumbled across your driver, and I liked it was in kernel and not some user-space thing. Mapping was wrong, but it had force-feedback (no other driver had), and it looked simple enough to be promising in fixing the mapping issue.
So now, you may get the background image of why I was happily donating this peace of hardware to you. All this gave me grey hairs, and then your driver and your changes could fix it in just a few days. :-)
So from your table I get:
none
would just be pass-thru, nothing touched. If your gamepad comes in Windows mapping flavor, then it's that, otherwise it's the Android flavored mapping. xpad
would be compatible with all games as that is what's expected, while kernel
adheres to the Gamepad Standard which no one else seems to adhere to (Y and X are swapped), so just for the sake of "correctness".
from xpadneo.
Related Issues (20)
- xpadneo 0.9.5 not loading on Ubuntu 22.04 Linux kernel 6.5.0 HOT 7
- Double Input / Ghost Input HOT 9
- Controller rumble has stopped working HOT 21
- Vibration not work on Gamesir T4 Pro HOT 7
- When xbox controller is not actively connected to bluetooth, bluetooth will suddenly stop working for other bluetooth devices. HOT 1
- Did not find any bluetooth devices fedora 39. HOT 4
- Packaging issue HOT 4
- Gulikit kk3 max recognized as 360 and rumble issues HOT 1
- Series controller not found at all HOT 7
- How To Update Controller Firmware through Xbox Accessories and VirtualBox HOT 1
- Steam and Wine not seeing any sort of input on the controls HOT 2
- Triggers getting stuck after releasing them HOT 9
- Xbox Controller still shown as connected after disconnecting HOT 11
- Controllers do not register as joysticks after reboot HOT 2
- Xbox elite Series 2 - MAC address not showing
- Steam deck support (haptics) HOT 3
- xbox cloud gaming with xbox series x controller x and y swapped and trigger not working HOT 1
- gentoo + 045e:02ea Microsoft Corp. Xbox One Controller (wired usb) HOT 7
- Can't get it to compile on an aarch64(snapdragon 845) phone HOT 11
- Programm not working / driver problems HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from xpadneo.