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

Fix Xbox One gamepad axis assignment on SDL_JOYSTICK_ANDROID API #7405

Merged
merged 5 commits into from Mar 6, 2023

Conversation

divVerent
Copy link
Contributor

Description

For gamepads with three axis pairs (like most standard layout ones), SDL currently groups them in X,Y Z,RX RY,RZ order.

It seems like the grouping X,Y RX,RY Z,RZ makes a lot more sense.

More details in the attached issue.

Tested: no degradation of with SDL_JOYSTICK_HIDAPI, and fixes axis assignment with SDL_JOYSTICK_ANDROID.

Existing Issue(s)

#7404

For gamepads with three axis pairs (like most standard layout ones),
SDL currently groups them in X,Y Z,RX RY,RZ order. It seems like the grouping
X,Y RX,RY Z,RZ makes a lot more sense.
@divVerent
Copy link
Contributor Author

divVerent commented Mar 4, 2023

I should note: I named the issue specific to my case, but I would suspect that right now and for quite a while, SDL_JOYSTICK_ANDROID handled all gamepads with two sticks and two triggers wrong unless they have a SDL_GameControllerDB entry.

@divVerent
Copy link
Contributor Author

divVerent commented Mar 4, 2023

Well, not ALL, but all that use AXIS_Z and AXIS_RZ for the trigger, which seems to be Xbox, Xbox One, Xbox 360 standard.

If they use AXIS_LTRIGGER and AXIS_RTRIGGER, they'd be previously handled right and become wrong with this patch.

Thus, we may need a better solution than this - I would suggest as an alternate option changing the sorting order of axes to sort AXIS_Z and AXIS_RZ after AXIS_RY, which seems cleanest, however that would break SDL_GameControllerDB mappings for existing gamepads. Thus, a decision needs to be made here.

@divVerent
Copy link
Contributor Author

divVerent commented Mar 4, 2023

That fixing of the sort order would be:

diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java b/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java
index 1486f4ed1..6aaa5491d 100644
--- a/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java
+++ b/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java
@@ -168,6 +168,18 @@ class SDLJoystickHandler_API16 extends SDLJoystickHandler {
                 arg1Axis = MotionEvent.AXIS_GAS;
             }
 
+            // Make sure the AXIS_Z is sorted between AXIS_RY and AXIS_RZ.
+            if (arg0Axis == MotionEvent.AXIS_Z) {
+                arg0Axis = MotionEvent.AXIS_RZ - 1;
+            } else if (arg0Axis > MotionEvent.AXIS_Z && arg0Axis < MotionEvent.AXIS_RZ) {
+                --arg0Axis;
+            }
+            if (arg1Axis == MotionEvent.AXIS_Z) {
+                arg1Axis = MotionEvent.AXIS_RZ - 1;
+            } else if (arg1Axis > MotionEvent.AXIS_Z && arg1Axis < MotionEvent.AXIS_RZ) {
+                --arg1Axis;
+            }
+
             return arg0Axis - arg1Axis;
         }
     }

@divVerent
Copy link
Contributor Author

divVerent commented Mar 6, 2023

Hm... as for the re-sorting approach...

I assume that any gamepads that currently have rightx or lefttrigger on a3 will be affected.

gamecontrollerdb has 40 Android gamepads with more than four axes:

$ grep '^05' gamecontrollerdb.txt | grep platform:Android | grep '\<a[45]'

Of those, only eight are likely broken if we change the sort oder:

$ grep '^05' gamecontrollerdb.txt | grep platform:Android | grep '\<a[45]' | grep -E 'x:a3|lefttrigger:a3'

Those are:

GPD XD Plus
NVIDIA Controller
PS5 Controller
Xbox One Controller
Xbox One Controller
Xbox One Controller
Xbox One Elite 2 Controller
Xbox Series Controller

That looks impactful.

Thus it may be required to first fix their mapping before doing the sort order change.

The change from this PR itself won't need this, but may break automatic gamepad mappings for gamepads that use AXIS_LEFTTRIGGER and AXIS_RIGHTTRIGGER instead of AXIS_Z and AXIS_RZ.

If only we could change the sort order for the automatic mapping only but keep gamecontrollerdb mapping as is... like, if we could export an extra bit of info from Java (basically, it'd suffice to know whether AXIS_Z exists), so the automatic mapping can be correct.

The catch is, we can't put this info into the mask, as that ends up in the SDL ID.

@divVerent
Copy link
Contributor Author

We could set another bit of info down the line, but it'd be hard to plumb this into SDL_PrivateGetGamepadMappingForGUID.

@divVerent
Copy link
Contributor Author

If we were to do the alternate fix (sorting order), mappings would break as follows:

  • GPD XD Plus (05000000d6020000e5890000dfff3f00):
    • Would be mostly fixed by simply deleting its mapping, but trigger and right stick axes would be swapped (i.e. this one follows Android's docs, which put triggers on RX/RY and right stick on Z/RZ, as opposed to Linux's docs).
  • NVIDIA Controller (050000005509000014720000df7f3f00):
    • Would be mostly fixed by simply deleting its mapping, but trigger and right stick axes would be swapped (i.e. this one follows Android's docs, which put triggers on RX/RY and right stick on Z/RZ, as opposed to Linux's docs).
  • PS5 Controller (050000004c050000e60c0000fffe3f00):
    • Axis mapping would be mostly fixed (but same RX/RY and Z/RZ swap needed), but button mapping is very incompatible.
  • Xbox One Controller (050000005e04000091020000ff073f00):
    • Would be entirely fixed by simply deleting its mapping.
  • Xbox One Controller (050000005e040000e00200000ffe3f00):
    • Axis mapping would be entirely fixed, but button mapping is very incompatible.
  • Xbox One Controller (050000005e040000e0020000ffff3f00):
    • Axis mapping would be entirely fixed, but button mapping is very incompatible.
  • Xbox One Elite 2 Controller (050000005e040000000b000000783f00):
    • Would be entirely fixed by simply deleting its mapping.
  • Xbox Series Controller (050000005e040000120b000000783f00):
    • Would be entirely fixed by simply deleting its mapping.

So... the RX/RY vs Z/RZ swap is annoying (Android docs generally say the swap is correct, so SDL's axes correspond to X, Y, Z, RZ, RX, RY in this order).

Let's thus do some "surveying" of 05 entries for Android:

  • leftx:a0: 44 matches
  • lefty:a1: 44 matches
  • rightx:a2 has 37 entries, lefttrigger:a2 has 7 entries.
  • righty:a3 has 37 entries; rightx:a3 has 5 entries, lefttrigger:a3 has 3 entries, righttrigger:a3 has 2 entries
  • lefttrigger:a4 has 26 entries, righttrigger:a4 has 7 entries, righty:a4 has 5 entries
  • righttrigger:a5 has 31 entries, righty:a5 has 5 entries, lefttrigger:a5 has 4 entries

If axes are actually X, Y, Z, RX, RY, RZ, then two sensible possibilities exist:

  1. Linux's definitions: leftx:a0,lefty:a1,lefttrigger:a2,rightx:a3,righty:a4,righttrigger:a5 - 5 entries total
  2. Android's docs: leftx:a0,lefty:a1,rightx:a2,lefttrigger:a3,righttrigger:a4,righty:a5 - 3 entries total

If axes are actually X, Y, RX, RY, LEFTTRIGGER, RIGHTTRIGGER, then assignment is unambigous and we don't want to change it:

leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5 - this seems to have 26 entries total.

Changing the sorting order will ONLY break the mappings for the three gamepads listed above as not fixed: GPD XD Plus, NVIDIA Controller, PS5 Controller.

I'd thus vote for the Xbox solution - let's change sorting order so it is X, Y, RX, RY, Z, RZ.

Can anyone confirm this - I'll then change this PR to rather change the sorting function on the Java side. As for the broken mappings, I would suggest I could add code into SDL to simply ignore these eight lines until someone makes new ones (and could also send a PR to update them)?

@slouken
Copy link
Collaborator

slouken commented Mar 6, 2023

Thanks for the research!
I'm not opposed to changing the sorting, and I think the mappings can simply be fixed by changing the axes in the mapping. I can test the NVIDIA and PS5 controller entries.

@divVerent
Copy link
Contributor Author

Re-pushed it as the sorting order change then. Would ask to squash when merging, of course.

If you can cover PS5 and NVIDIA, that'd be great, as they're some of the more complicated cases.

@divVerent
Copy link
Contributor Author

(BTW, I noticed the 05 prefix is defined to mean bluetooth, but the gamepad I have is a USB one - well, by default SDL doesn't even use this code path for USB gamepads anymore, but e.g. Ebitengine has derived code from this code, and I would like to update it in sync with SDL whichever decision we make)

@slouken
Copy link
Collaborator

slouken commented Mar 6, 2023

Sure. Can you add the SDL_gamepad_db.h changes to this PR so we have working mappings before and after this is merged?

@slouken
Copy link
Collaborator

slouken commented Mar 6, 2023

We don't know whether the gamepad is USB or Bluetooth. I assumed Bluetooth because at the time it was harder to connect USB than pair wirelessly with most Android devices.

@divVerent
Copy link
Contributor Author

I will update these mappings in a few hours, sure!

(Xbox ones still TBD)
@divVerent
Copy link
Contributor Author

I updated the NVIDIA and PS5 ones right away; also, I did my previous analysis on gamecontrollerdb.txt, not the include file, so I'll also analyze that.

@divVerent
Copy link
Contributor Author

All mappings audited and updated. Now checking if I can delete some of the Xbox ones, i.e. if they fully match the default.

@divVerent
Copy link
Contributor Author

divVerent commented Mar 6, 2023

Hm... I found 33 mappings that MAY be redundant with the default mappings after this change, but am not 100% sure as there may be extra axes or buttons that are intentionally unmapped.

@divVerent
Copy link
Contributor Author

divVerent commented Mar 6, 2023

  • Xbox One Controller (050000005e04000091020000ff073f00):
  • Xbox One Elite 2 Controller (050000005e040000000b000000783f00):
  • Xbox Series Controller (050000005e040000120b000000783f00):

The SDLIDs of these seem wrong. Note how the latter two controllers have a button mask of just 0x7800, which only has four bits set (the dpad ones?), but assigns way more buttons.

The first one here has a button mask of 0x07ff, which assigns buttons 0 to 10, and will be perfectly mapped automatically - but I am not going to do that, as the code line for it has a comment about some dpad issue that is worth keeping.

@divVerent
Copy link
Contributor Author

So I conclude that I will delete none of these mappings. Some restrict available buttons or axes to a subset, and some have comments, and both may be worth keeping.

@slouken
Copy link
Collaborator

slouken commented Mar 6, 2023

So I confirmed the DualSense (PS5) controller mapping works correctly, but I connected an Xbox Elite 2 Core controller, which isn't in the mapping database, and the automatic mapping looked identical to the existing Xbox Elite 2 entry, but it didn't work correctly.

Pulling the left trigger activated the right trigger mapping and pressing up and down on the d-pad activated the left trigger.

Here's a log with the controller connected, pressing the d-pad in a clockwise circle, and then pulling the left trigger:

03-06 18:16:26.617 17687 17708 I SDL/APP : XBox One Controller: Xbox One Elite 2 Controller (guid 050054435e040000050b0000ffff3f00, VID 0x045e, PID 0x0b05, player index = 0)
03-06 18:16:26.617 17687 17708 I SDL/APP : Mapping: 050054435e040000050b0000ffff3f00,*,a:b0,b:b1,x:b2,y:b3,back:b4,start:b6,leftstick:b7,rightstick:b8,leftshoulder:b9,rightshoulder:b10,dpup:b11,dpdown:b12,dpleft:b13,dpright:b14,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,crc:4354,
03-06 18:19:06.413 17687 17708 I SDL/APP : Gamepad 4 axis righty changed to 0
03-06 18:19:06.418 17687 17708 I SDL/APP : Gamepad 4 axis righty changed to 560
03-06 18:19:06.713 17687 17708 I SDL/APP : Gamepad 4 axis lefttrigger changed to 16383
03-06 18:19:06.714 17687 17708 I SDL/APP : Gamepad 4 axis lefttrigger changed to 0
03-06 18:19:06.714 17687 17708 I SDL/APP : Gamepad 4 button dpup pressed
03-06 18:19:07.583 17687 17708 I SDL/APP : Gamepad 4 axis righty changed to 825
03-06 18:19:08.040 17687 17708 I SDL/APP : Gamepad 4 button dpup released
03-06 18:19:09.750 17687 17708 I SDL/APP : Gamepad 4 axis lefttrigger changed to 9362
03-06 18:19:09.751 17687 17708 I SDL/APP : Gamepad 4 button dpright pressed
03-06 18:19:11.126 17687 17708 I SDL/APP : Gamepad 4 button dpright released
03-06 18:19:12.693 17687 17708 I SDL/APP : Gamepad 4 axis lefttrigger changed to 18723
03-06 18:19:12.694 17687 17708 I SDL/APP : Gamepad 4 button dpdown pressed
03-06 18:19:13.601 17687 17708 I SDL/APP : Gamepad 4 button dpdown released
03-06 18:19:15.037 17687 17708 I SDL/APP : Gamepad 4 axis lefttrigger changed to 28085
03-06 18:19:15.037 17687 17708 I SDL/APP : Gamepad 4 button dpleft pressed
03-06 18:19:15.588 17687 17708 I SDL/APP : Gamepad 4 button dpleft released
03-06 18:19:21.951 17687 17708 I SDL/APP : Gamepad 4 axis lefttrigger changed to 0
03-06 18:19:21.952 17687 17708 I SDL/APP : Gamepad 4 button dpup pressed
03-06 18:19:22.362 17687 17708 I SDL/APP : Gamepad 4 button dpup released
03-06 18:19:33.326 17687 17708 I SDL/APP : Gamepad 4 axis righttrigger changed to 0
03-06 18:19:33.326 17687 17708 I SDL/APP : Gamepad 4 axis righttrigger changed to 577
03-06 18:19:33.353 17687 17708 I SDL/APP : Gamepad 4 axis righttrigger changed to 1281
03-06 18:19:33.380 17687 17708 I SDL/APP : Gamepad 4 axis righttrigger changed to 4965
03-06 18:19:33.380 17687 17708 I SDL/APP : Gamepad 4 axis righttrigger changed to 5605
03-06 18:19:33.407 17687 17708 I SDL/APP : Gamepad 4 axis righttrigger changed to 10666
03-06 18:19:33.407 17687 17708 I SDL/APP : Gamepad 4 axis righttrigger changed to 14958
03-06 18:19:33.463 17687 17708 I SDL/APP : Gamepad 4 axis righttrigger changed to 18993
03-06 18:19:33.464 17687 17708 I SDL/APP : Gamepad 4 axis righttrigger changed to 22293
03-06 18:19:33.464 17687 17708 I SDL/APP : Gamepad 4 axis righttrigger changed to 26585
03-06 18:19:33.486 17687 17708 I SDL/APP : Gamepad 4 axis righttrigger changed to 27610
03-06 18:19:33.487 17687 17708 I SDL/APP : Gamepad 4 axis righttrigger changed to 31870
03-06 18:19:33.509 17687 17708 I SDL/APP : Gamepad 4 axis righttrigger changed to 32767
03-06 18:19:34.779 17687 17708 I SDL/APP : Gamepad 4 axis righttrigger changed to 22197
03-06 18:19:34.798 17687 17708 I SDL/APP : Gamepad 4 axis righttrigger changed to 8712
03-06 18:19:34.819 17687 17708 I SDL/APP : Gamepad 4 axis righttrigger changed to 4100
03-06 18:19:34.841 17687 17708 I SDL/APP : Gamepad 4 axis righttrigger changed to 0

@slouken
Copy link
Collaborator

slouken commented Mar 6, 2023

I then connected an Xbox Series X controller, which was in the mapping database, and it worked correctly:

03-06 18:22:02.690 17687 17708 I SDL/APP : XBox One Controller: Xbox Series X Controller (guid 05004cb15e040000130b0000ffff3f00, VID 0x045e, PID 0x0b13, player index = 0)
03-06 18:22:02.690 17687 17708 I SDL/APP : Mapping: 05004cb15e040000130b0000ffff3f00,Xbox Series X Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,

@slouken
Copy link
Collaborator

slouken commented Mar 6, 2023

This might just be an oddity of this controller on Android. Android reports that it has 14 axes.

@slouken slouken merged commit 6f1f586 into libsdl-org:main Mar 6, 2023
slouken pushed a commit that referenced this pull request Mar 6, 2023
@slouken
Copy link
Collaborator

slouken commented Mar 6, 2023

I went ahead and added a mapping for the Xbox Elite controller in d08338d.

@slouken
Copy link
Collaborator

slouken commented Mar 6, 2023

Thanks for the research and the PR!

@divVerent
Copy link
Contributor Author

divVerent commented Mar 7, 2023 via email

@slouken
Copy link
Collaborator

slouken commented Mar 7, 2023

I just added a binding using gamepadmap, now it works fine. :)

@divVerent
Copy link
Contributor Author

divVerent commented Mar 7, 2023 via email

@slouken
Copy link
Collaborator

slouken commented Mar 7, 2023

It has AXIS_X, AXIS_Y, AXIS_Z, AXIS_RZ, AXIS_BRAKE, AXIS_RX, AXIS_RY, LTRIGGER, RTRIGGER, and AXIS_GAS.
The left stick is X/Y, right stick is Z/RZ, left trigger is BRAKE, right trigger is GAS.

@divVerent
Copy link
Contributor Author

Great, thanks.

So the old sorted order is:

(X, Y), (Z, RX), (RY, RZ), HAT_X, HAT_Y, LTRIGGER, RTRIGGER, BRAKE, GAS

The new sorted order is:

(X, Y), (RX, RY), (Z, RZ), HAT_X, HAT_Y, LTRIGGER, RTRIGGER, BRAKE, GAS

Pulling the left trigger activated the right trigger mapping and pressing up and down on the d-pad activated the left trigger.

To be fair I find that very odd - as the right stick is Z/RZ, I'd expect the right stick to control the triggers and the triggers to do nothing as unused LTRIGGER/RTRIGGER and RX/RY are unnecessarily taking up axis slots and SDL only ever auto assigns the three lowest axis pairs.

Either way, it doesn't seem possible that this pad worked with the previous mapping.

Your axis mapping is:

  • leftx:a0
  • lefty:a1
  • rightx:a2
  • righty:a3
  • lefttrigger:a5
  • righttrigger:a6

So the odd thing here is having an unused a4 that comes after righty (must be RZ) and before lefttrigger (which is BRAKE).

AXIS_BRAKE is 23, but sorted as 22 due to brake/gas swap. AXIS_RZ is 14, unchanged by this patch. The automatic mapping would be correct if there were nothing between those.

We have in between:

  • AXIS_HAT_X
  • AXIS_HAT_Y
  • AXIS_LTRIGGER
  • AXIS_RTRIGGER
  • AXIS_THROTTLE
  • AXIS_RUDDER
  • AXIS_WHEEL

Based on your description, it seems like AXIS_HAT_Y isn't skipped for some reason...

@divVerent
Copy link
Contributor Author

Also, without the sort order change, we should still get a wrong mapping, as all that'd happen is that Z (rightx) is sorted before RX. There's no space in the mapping for that. Even if I am totally mistaken, this would instead make the right stick misassigned.

@divVerent
Copy link
Contributor Author

Hm... skipping hat axes is done only if it has SOURCE_CLASS_JOYSTICK. Could it be that it has SOURCE_DPAD or SOURCE_GAMEPAD instead?

@slouken
Copy link
Collaborator

slouken commented Mar 9, 2023

Here's the output of axes as they're added:

03-09 12:25:14.765  8467  8493 V SDL     : Adding axis 0
03-09 12:25:14.765  8467  8493 V SDL     : Adding axis 1
03-09 12:25:14.765  8467  8493 V SDL     : Adding axis 11
03-09 12:25:14.765  8467  8493 V SDL     : Adding axis 14
03-09 12:25:14.765  8467  8493 V SDL     : Adding hat 15
03-09 12:25:14.765  8467  8493 V SDL     : Adding hat 16
03-09 12:25:14.765  8467  8493 V SDL     : Adding axis 20
03-09 12:25:14.765  8467  8493 V SDL     : Adding axis 23
03-09 12:25:14.765  8467  8493 V SDL     : Adding axis 22
03-09 12:25:14.765  8467  8493 V SDL     : Adding axis 32
03-09 12:25:14.765  8467  8493 V SDL     : Adding axis 33
03-09 12:25:14.765  8467  8493 V SDL     : Adding axis 34
03-09 12:25:14.765  8467  8493 V SDL     : Adding axis 35
03-09 12:25:14.765  8467  8493 V SDL     : Adding axis 36
03-09 12:25:14.766  8467  8493 V SDL     : Adding axis 37
03-09 12:25:14.766  8467  8493 V SDL     : Adding axis 38

The sorting isn't relevant because RX and RY aren't present.

@divVerent
Copy link
Contributor Author

I assume this is post-order, as I do see the GAS/BRAKE swap here:

Your order is, converted to Android's enums:

  • AXIS_X
  • AXIS_Y
  • AXIS_Z
  • AXIS_RZ
  • AXIS_HAT_X (reported as hat)
  • AXIS_HAT_Y (reported as hat)
  • AXIS_RUDDER
  • AXIS_BRAKE (note: higher id than AXIS_GAS but before it - intended and preexisting)
  • AXIS_GAS
  • AXIS_GENERIC_1
  • AXIS_GENERIC_2
  • AXIS_GENERIC_3
  • AXIS_GENERIC_4
  • AXIS_GENERIC_5
  • AXIS_GENERIC_6
  • AXIS_GENERIC_7

As AXIS_RX and AXIS_RY don't even exist, the change from this PR shouldn't even affect this gamepad at all.

The confusion you observe probably comes from AXIS_RUDDER. The automatic pairing would be (X, Y), (Z, RZ), (RUDDER, BRAKE), which is sure wrong for the last one. AXIS_RUDDER is your unused a4 that was messing things up - so your pad should have needed an explicit mapping both before and after this change (and the mapping is the same, even).

@slouken
Copy link
Collaborator

slouken commented Mar 9, 2023

Yes, I had never connected this controller to Android before, so I'm sure it would have needed a mapping.

From your description above, this looks correct to me.

@divVerent
Copy link
Contributor Author

divVerent commented Mar 9, 2023

Hm... should THROTTLE/RUDDER even be paired ever? Pairing BRAKE/GAS is also questionable, but seems right for your pad (and the pedals in a car are also kinda laid out like the triggers on a gamepad).

I wonder if the proper fix for gamepads like yours would be sorting AXIS_THROTTLE/AXIS_RUDDER behind the others. But this seems even more tricky to evaluate - anyway, it's established that this gamepad does require special handling for now and that it's not a bug.

@divVerent
Copy link
Contributor Author

Hm... if I understand it right, throttle and rudder are simply the Y and X axes of a flight joystick (with some fun reversal of direction that the flight simulators themselves usually take care of). In a real airplane, according to FAA, rudder is controlled with a pair of pedals, but as there's only one axis in the MotionEvent, this info doesn't really help here.

https://www.amazon.com/Thrustmaster-T-Flight-Hotas-One-xbox/dp/B07643TW2V/ref=sr_1_4?crid=2BL6LFTM230TY&keywords=joystick%2Bwith%2Bthrottle%2Band%2Brudder&qid=1678384004&sprefix=joystick%2Bwith%2Bthrottle%2Band%2Brudde%2Caps%2C110&sr=8-4&ufe=app_do%3Aamzn1.fos.006c50ae-5d4c-4777-9bc0-4513d670b6bc&th=1 seems to have a "progressive tilting lever" for rudder on the throttle stick. I guess that makes them behave a bit like a regular pair of axes of a joystick, except that at least the throttle doesn't snap back to center when you release it. It still kinda makes sense to pair them.

Of course... AXIS_THROTTLE has index 19 and AXIS_RUDDER has index 20, makes throttle appear as an X axis or left trigger, and rudder as an Y axis or a right trigger. Maybe these two should be flipped around just like gas/brake, then they kinda behave right when treated as a right stick X and Y axis - but OTOH, shouldn't only flight sticks even export these? And flight sticks are too specific to support by standard layout anyway... so, meh.

@slouken
Copy link
Collaborator

slouken commented Mar 9, 2023

Agreed, I think we shouldn't try to automatically map anything that has a throttle or rudder.

divVerent added a commit to divVerent/ebiten that referenced this pull request Mar 11, 2023
This commit mirrors libsdl-org/SDL#7405
(libsdl-org/SDL@6f1f586).

Note that for SDL, this code is used a lot less than for Ebitengine, as SDL
mostly migrated to HIDAPI and direct USB device access rather than using
Android's APIs. For Bluetooth devices, however, the Java APIs are used the
same way.

This was the remaining problem to be solved to automatically support standard
layout on most standard gamepads (this should cover most Xbox-ish and PS-ish
gamepads on the market).

In particular this covers gamepads with the following assignment:

- Left stick = X/Y, right stick = Z/RZ, triggers = LEFTTRIGGER/RIGHTTRIGGER
  (which basically is what Android docs say and some PS gamepads do)

- Left stick = X/Y, right stick = RX/RY, triggers = Z/RZ
  (Xbox gamepad style, apparently)

- Left stick = X/Y, right stick = RX/RY, triggers = LEFTTRIGGER/RIGHTTRIGGER
  (Not sure if this exists, but it's conceivable)

As we found on the SDL pull request discussion, gamepads that offer flight
controls (e.g. THROTTLE and RUDDER) will likely not work well, before and
after this change.

Fixes hajimehoshi#2557
@divVerent
Copy link
Contributor Author

Seems like I can't get this change into SDL_GameControllerDB - see here:

mdqinc/SDL_GameControllerDB#671 (comment)

I could offer setting an unused GUID bit (e.g. given axis mask can currently be at most 0x003f, could use 0x803f to represent pads where the sorting order change affected anything, i.e. where both AXIS_Z and any of AXIS_RX or AXIS_RY exist.

Would you be OK with me sending a followup PR for that?

@slouken
Copy link
Collaborator

slouken commented Mar 11, 2023

Yes, that would be fine. Maybe a sort order version of 2 bits or something like that?

hajimehoshi pushed a commit to hajimehoshi/ebiten that referenced this pull request Mar 12, 2023
This commit mirrors libsdl-org/SDL#7405
(libsdl-org/SDL@6f1f586).

Note that for SDL, this code is used a lot less than for Ebitengine, as SDL
mostly migrated to HIDAPI and direct USB device access rather than using
Android's APIs. For Bluetooth devices, however, the Java APIs are used the
same way.

This was the remaining problem to be solved to automatically support standard
layout on most standard gamepads (this should cover most Xbox-ish and PS-ish
gamepads on the market).

In particular this covers gamepads with the following assignment:

- Left stick = X/Y, right stick = Z/RZ, triggers = LEFTTRIGGER/RIGHTTRIGGER
  (which basically is what Android docs say and some PS gamepads do)

- Left stick = X/Y, right stick = RX/RY, triggers = Z/RZ
  (Xbox gamepad style, apparently)

- Left stick = X/Y, right stick = RX/RY, triggers = LEFTTRIGGER/RIGHTTRIGGER
  (Not sure if this exists, but it's conceivable)

As we found on the SDL pull request discussion, gamepads that offer flight
controls (e.g. THROTTLE and RUDDER) will likely not work well, before and
after this change.

Closes #2557
slouken pushed a commit that referenced this pull request Mar 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants