Skip to content

Wireless Xbox 360 controller d-pad broken on Linux 6.17+ #14324

@turmoni

Description

@turmoni

Since updating my kernel to 6.17, the D-pad on my Xbox 360 controllers have been misaligned. I'm fairly sure this is related to the kernel changes mentioned in #13305 , so there is more context in there.

I currently have the following mapping:

Button pressed Button reported
Up Left
Right Down
Down Right
Left Up

The linked PR references the following custom mapping:

SDL/src/joystick/SDL_gamepad.c

Lines 2256 to 2258 in ac0915b

mapping = SDL_PrivateAddMappingForGUID(guid,
"none,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
&existing, SDL_GAMEPAD_MAPPING_PRIORITY_DEFAULT);

Fixing the mapping in testcontroller gives me the following (modified to fit the same format):

none,X360 Wireless Controller,b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,

Since the existing special case is specifically referencing the D-pad, I'm thinking it could be just made conditional on having an older version of the xpad module loaded, rather than updating the mapping. I'm currently struggling a bit with testing this, since even if I delete the #ifdef block entirely and do a fresh build of SDL, testcontroller still reports the (now-incorrect) mapping and I'm not sure where it's coming from.

I've now dug into this more and see that the mapping is in SDL_gamepad_db.h, which makes things a bit more complicated. I'm not sure how you'd go about allowing for different configurations based on different versions of the driver there; any ideas?

I'm happy to work on this myself (it feels pretty simple, and I'm the one who cares about it), but don't want to break things; I suppose the questions I have are:

  • Is there an acceptable way in SDL, in this function, to get the version of a kernel module (or the kernel itself, I suppose)?
  • Is there some reason why my freshly built SDL3 and testcontroller might still be picking up the mapping I deleted/changed from somewhere else? strace does seem to show that it is loading my SDL3 and not one provided by my distro.
  • Given SDL_gamepad_db.h, is there actually a way to fix this without breaking users of older kernels?

I'm assuming this also needs to be fixed in SDL2, but it looks like it would be pretty much the same change in there.

Edit: updated with more things I discovered (which make this a more challenging prospect)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions