Added automatic mapping support for Xbox controllers on the 6.x Linux kernels

This automatically adds support for the share button and paddles when present.

(cherry picked from commit db1d4d3d76f5e21b2547463710b513fe0ebd7fad)
This commit is contained in:
Sam Lantinga 2023-06-13 16:40:30 -07:00
parent 681f67d353
commit fc72f12e7f

View file

@ -1788,6 +1788,10 @@ static SDL_bool LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMap
/* We have a gamepad, start filling out the mappings */
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapping %s (VID/PID 0x%.4x/0x%.4x)", item->name, SDL_JoystickGetVendor(joystick), SDL_JoystickGetProduct(joystick));
#endif
if (joystick->hwdata->has_key[BTN_A]) {
out->a.kind = EMappingKind_Button;
out->a.target = joystick->hwdata->key_map[BTN_A];
@ -2143,37 +2147,36 @@ 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_JoystickGetVendor(joystick), SDL_JoystickGetProduct(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];
if (SDL_JoystickGetVendor(joystick) == USB_VENDOR_MICROSOFT) {
/* The Xbox Elite controllers have the paddles as BTN_TRIGGER_HAPPY4 - BTN_TRIGGER_HAPPY7 */
if (joystick->hwdata->has_key[BTN_TRIGGER_HAPPY5] &&
joystick->hwdata->has_key[BTN_TRIGGER_HAPPY6] &&
joystick->hwdata->has_key[BTN_TRIGGER_HAPPY7] &&
joystick->hwdata->has_key[BTN_TRIGGER_HAPPY8]) {
out->paddle1.kind = EMappingKind_Button;
out->paddle1.target = joystick->hwdata->key_map[BTN_TRIGGER_HAPPY5];
out->paddle2.kind = EMappingKind_Button;
out->paddle2.target = joystick->hwdata->key_map[BTN_TRIGGER_HAPPY7];
out->paddle3.kind = EMappingKind_Button;
out->paddle3.target = joystick->hwdata->key_map[BTN_TRIGGER_HAPPY6];
out->paddle4.kind = EMappingKind_Button;
out->paddle4.target = joystick->hwdata->key_map[BTN_TRIGGER_HAPPY8];
#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);
SDL_Log("Mapped PADDLE1 to button %d (BTN_TRIGGER_HAPPY4)", out->paddle1.target);
SDL_Log("Mapped PADDLE2 to button %d (BTN_TRIGGER_HAPPY6)", out->paddle2.target);
SDL_Log("Mapped PADDLE3 to button %d (BTN_TRIGGER_HAPPY5)", out->paddle3.target);
SDL_Log("Mapped PADDLE4 to button %d (BTN_TRIGGER_HAPPY7)", out->paddle4.target);
#endif
++paddle_index;
if (paddle_index == SDL_arraysize(paddles)) {
break;
}
}
/* The Xbox Series X controllers have the Share button as KEY_RECORD */
if (joystick->hwdata->has_key[KEY_RECORD]) {
out->misc1.kind = EMappingKind_Button;
out->misc1.target = joystick->hwdata->key_map[KEY_RECORD];
mapped |= MAPPED_DPAD_RIGHT;
#ifdef DEBUG_GAMEPAD_MAPPING
SDL_Log("Mapped MISC1 to button %d (KEY_RECORD)", out->misc1.target);
#endif
}
}