Commit d2372c853843def01b7adb9872cbb89b0d6079ec

Sam Lantinga 2023-06-13T10:06:36

Added automatic mapping for Xbox Elite paddles using the xpadneo driver We can't actually tell yet whether a controller has paddles, so this code isn't effective, but I'll file an upstream issue and see if we can get that resolved. (cherry picked from commit b0677f476fa43f4a113b04a959228fd38f95d740)

diff --git a/src/joystick/linux/SDL_sysjoystick.c b/src/joystick/linux/SDL_sysjoystick.c
index df73ced..24c6a00 100644
--- a/src/joystick/linux/SDL_sysjoystick.c
+++ b/src/joystick/linux/SDL_sysjoystick.c
@@ -75,6 +75,50 @@
 #define BTN_DPAD_RIGHT 0x223
 #endif
 
+#ifndef BTN_TRIGGER_HAPPY
+#define BTN_TRIGGER_HAPPY		0x2c0
+#define BTN_TRIGGER_HAPPY1		0x2c0
+#define BTN_TRIGGER_HAPPY2		0x2c1
+#define BTN_TRIGGER_HAPPY3		0x2c2
+#define BTN_TRIGGER_HAPPY4		0x2c3
+#define BTN_TRIGGER_HAPPY5		0x2c4
+#define BTN_TRIGGER_HAPPY6		0x2c5
+#define BTN_TRIGGER_HAPPY7		0x2c6
+#define BTN_TRIGGER_HAPPY8		0x2c7
+#define BTN_TRIGGER_HAPPY9		0x2c8
+#define BTN_TRIGGER_HAPPY10		0x2c9
+#define BTN_TRIGGER_HAPPY11		0x2ca
+#define BTN_TRIGGER_HAPPY12		0x2cb
+#define BTN_TRIGGER_HAPPY13		0x2cc
+#define BTN_TRIGGER_HAPPY14		0x2cd
+#define BTN_TRIGGER_HAPPY15		0x2ce
+#define BTN_TRIGGER_HAPPY16		0x2cf
+#define BTN_TRIGGER_HAPPY17		0x2d0
+#define BTN_TRIGGER_HAPPY18		0x2d1
+#define BTN_TRIGGER_HAPPY19		0x2d2
+#define BTN_TRIGGER_HAPPY20		0x2d3
+#define BTN_TRIGGER_HAPPY21		0x2d4
+#define BTN_TRIGGER_HAPPY22		0x2d5
+#define BTN_TRIGGER_HAPPY23		0x2d6
+#define BTN_TRIGGER_HAPPY24		0x2d7
+#define BTN_TRIGGER_HAPPY25		0x2d8
+#define BTN_TRIGGER_HAPPY26		0x2d9
+#define BTN_TRIGGER_HAPPY27		0x2da
+#define BTN_TRIGGER_HAPPY28		0x2db
+#define BTN_TRIGGER_HAPPY29		0x2dc
+#define BTN_TRIGGER_HAPPY30		0x2dd
+#define BTN_TRIGGER_HAPPY31		0x2de
+#define BTN_TRIGGER_HAPPY32		0x2df
+#define BTN_TRIGGER_HAPPY33		0x2e0
+#define BTN_TRIGGER_HAPPY34		0x2e1
+#define BTN_TRIGGER_HAPPY35		0x2e2
+#define BTN_TRIGGER_HAPPY36		0x2e3
+#define BTN_TRIGGER_HAPPY37		0x2e4
+#define BTN_TRIGGER_HAPPY38		0x2e5
+#define BTN_TRIGGER_HAPPY39		0x2e6
+#define BTN_TRIGGER_HAPPY40		0x2e7
+#endif
+
 #include "../../core/linux/SDL_evdev_capabilities.h"
 #include "../../core/linux/SDL_udev.h"
 #include "../../core/linux/SDL_sandbox.h"
@@ -2099,6 +2143,40 @@ static SDL_bool LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMap
 #endif
     }
 
+    /* The xpadneo driver uses the happy buttons for triggers.
+       Unfortunately it also reports them as available for all controllers,
+       and exposes the Xbox Elite with the VID/PID of an Xbox 360 controller,
+       so we can't really tell whether this is an Xbox Elite or Xbox One S
+       controller.
+
+       xpadneo has a note about this in the driver code:
+       https://github.com/atar-axis/xpadneo/blob/master/hid-xpadneo/src/hid-xpadneo.c#L1137
+     */
+    if (SDL_IsJoystickXboxOneElite(SDL_GetJoystickVendor(joystick), SDL_GetJoystickProduct(joystick))) {
+        int i;
+        unsigned int paddle_index = 0;
+        SDL_InputMapping *paddles[4] = {
+            &out->paddle1,
+            &out->paddle3,
+            &out->paddle2,
+            &out->paddle4
+        };
+
+        for (i = BTN_TRIGGER_HAPPY; i <= BTN_TRIGGER_HAPPY40; ++i) {
+            if (joystick->hwdata->has_key[i]) {
+                paddles[paddle_index]->kind = EMappingKind_Button;
+                paddles[paddle_index]->target = joystick->hwdata->key_map[i];
+#ifdef DEBUG_GAMEPAD_MAPPING
+                SDL_Log("Mapped PADDLE%u to button %d (BTN_TRIGGER_HAPPY%d)", 1 + paddle_index, paddles[paddle_index]->target, i - BTN_TRIGGER_HAPPY);
+#endif
+                ++paddle_index;
+                if (paddle_index == SDL_arraysize(paddles)) {
+                    break;
+                }
+            }
+        }
+    }
+
     LINUX_JoystickClose(joystick);
     SDL_free(joystick);