Skip to content

Add support for SDL-compatible joypad GUID and Input.get_joy_info() on Android#114338

Open
Nintorch wants to merge 1 commit intogodotengine:masterfrom
Nintorch:android-sdl-guid
Open

Add support for SDL-compatible joypad GUID and Input.get_joy_info() on Android#114338
Nintorch wants to merge 1 commit intogodotengine:masterfrom
Nintorch:android-sdl-guid

Conversation

@Nintorch
Copy link
Copy Markdown
Member

@Nintorch Nintorch commented Dec 25, 2025

Related to #56181 (if this PR doesn't fix this issue, then we need to create a mapping for Xbox controllers ourselves)

This PR adds support for SDL-compatible joypad GUIDs on Android, so now we should be able to use the mappings from SDL controller mapping database for Android controllers that start with 0500, while still keeping the compatibility with mappings that use the older GUID format (if a mapping with the new format can't be found, the code tries to find one with the old format).
This PR adds support for Input.get_joy_info() for Android as well.

See also SDL's Android_AddJoystick, SDL's SDLControllerManager, and the way GUID was constructed in Godot's Linux joypad driver prior to the SDL3 joystick driver PR here.

DualShock 4 GUID before this PR

(Ignore that there's no fingerprint sensor here, it's a screenshot with a different PR applied)
Screenshot_2025-12-25-18-17-15-579_org godotengine editor v4 debug

DualShock 4 GUID after this PR + Input.get_joy_info()

Screenshot_2025-12-25-21-29-55-945_org godotengine editor v4 debug

TODO:

  • Use SDL's internal mapping database
  • Add a note saying that changing the GUID-generating code to be different from SDL will make some GUIDs incompatible
  • Fix swapped triggers issue by looking at SDL's Android code
  • Fix triggers being mapped to [-1;1] on my Xbox One controller without breaking my Dualshock 4 triggers
  • If a mapping for an old GUID exists while a mapping for a new one doesn't, fallback to old mapping format
  • Don't introduce regressions for Nvidia Shield axis mapping

@Nintorch Nintorch requested review from a team as code owners December 25, 2025 16:40
@Nintorch Nintorch changed the title Add support for SDL-compatible joypad GUID Add support for SDL-compatible joypad GUID on Android Dec 25, 2025
Copy link
Copy Markdown
Contributor

@m4gr3d m4gr3d left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alongside manual testing, can you add unit tests to validate the added logic.

@Nintorch
Copy link
Copy Markdown
Member Author

Thank you for your review, m4gr3d! I will be able to fix the code later today!

@Nintorch Nintorch requested a review from a team as a code owner December 26, 2025 18:25
@Nintorch Nintorch force-pushed the android-sdl-guid branch 4 times, most recently from 60d7a23 to c258401 Compare December 26, 2025 19:02
// Generate GUID for compatibility with SDL controller mappings.
void generate_joy_guid(char *p_buf, int p_buf_len, int p_vendor_id, int p_product_id, int p_button_mask, int p_axis_mask) {
if (p_vendor_id != 0 || p_product_id != 0) {
snprintf(p_buf, p_buf_len, "05000000%04x0000%04x0000%04x%04x", BSWAP16(p_vendor_id), BSWAP16(p_product_id), BSWAP16(p_button_mask), BSWAP16(p_axis_mask));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary, Regressions Xbox Series Controller :

  • XBox Button is not recognized
  • The back button is not recognized
  • The Share button is displayed as a back button in the official demo.
Screenshot Image

The RL and LT buttons are swapped; this was incorrect before, either due to incorrect testing and configuration on my part or caused by other changes. (Probably the first; I pressed both buttons simultaneously during testing, and didn't notice that they were swapped.)


Tests, Rc2 and this PR

Godot Engine v4.6.rc2.official.78c6632eb
Found joypad #0: Xbox Series X Controller - 58626f7820576972656c65737320436f

58626f7820576972656c65737320436f,Xbox One Controller,a:b0,b:b1,back:b15,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,platform:Android,

I overwrote it some time ago with this configuration (godotcontrollerdb.txt):

58626f7820576972656c65737320436f,Xbox Series X Controller,a:b0,b:b1,back:b4,misc1:b15,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,platform:Android,


This PR: Godot Engine v4.6.rc.gh-114338.5db637116
Found joypad #0: Xbox Series Controller - 050000005e040000130b0000ffff3f00

i see also now:
print(Input.get_joy_info(joypad))
{ "raw_name": "Xbox Wireless Controller 4416", "vendor_id": "1118", "product_id": "2835" }

050000005e040000130b0000ffff3f00,Xbox Series Controller,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,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,platform:Android,


This PR adds support for SDL-compatible joypad GUIDs on Android, so now we should be able to use SDL controller mapping database for Android controllers.

I wasn't aware that the GUIDs were incompatible, but in this official (?) SDL file I also see many GUIDs that don't start with 05000000. Will there be more regressions if they are no longer found as before?


Godot configuration: Should we clean it up now?

Perhaps we should clean up the Godot configuration here now. Back then, I copied more GUIDs from the SDL configuration and adjusted them to match my controller. I asked several people in the community, and they all had the same GUIDs as me. According to the Git-Blame, Default Android Gamepad was added six years ago. It was last updated two months ago, but I'm not sure what effect this pull request has on this controller.

https://github.com/godotengine/godot/blob/master/core/input/godotcontrollerdb.txt#L7-L20

# Android
Default Android Gamepad,Default Controller,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b8,rightshoulder:b10,rightx:a2,start:b6,righty:a3,dpleft:h0.8,lefttrigger:a4,x:b2,dpup:h0.1,back:b4,leftstick:b7,leftshoulder:b9,y:b3,a:b0,dpright:h0.2,righttrigger:a5,b:b1,dpup:b11,dpdown:b12,dpleft:b13,dpright:b14,platform:Android,
58626f7820576972656c65737320436f,Xbox Series X Controller,a:b0,b:b1,back:b4,misc1:b15,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,platform:Android,
050000005e04000091020000ff073f00,Xbox One Controller,a:b0,b:b1,back:b4,misc1:b15,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,platform:Android,
050000005e04000091020000ff073f80,Xbox One Controller,a:b0,b:b1,back:b4,misc1:b15,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,platform:Android,
050000005e040000e00200000ffe3f00,Xbox One Controller,a:b0,b:b1,back:b4,misc1:b15,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,platform:Android,
050000005e040000e00200000ffe3f80,Xbox One Controller,a:b0,b:b1,back:b4,misc1:b15,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,platform:Android,
050000005e040000e0020000ffff3f00,Xbox One Controller,a:b0,b:b1,back:b4,misc1:b15,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,platform:Android,
050000005e040000e0020000ffff3f80,Xbox One Controller,a:b0,b:b1,back:b4,misc1:b15,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,platform:Android,
050000005e040000fd020000ffff3f00,Xbox One Controller,a:b0,b:b1,back:b4,misc1:b15,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,platform:Android,
33356661323266333733373865656366,Xbox One Controller,a:b0,b:b1,back:b4,misc1:b15,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,platform:Android,
34356136633366613530316338376136,Xbox One Controller,a:b0,b:b1,back:b4,misc1:b15,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,platform:Android,
35623965373264386238353433656138,Xbox One Controller,a:b0,b:b1,back:b4,misc1:b15,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,platform:Android,
36616131643361333337396261666433,Xbox One Controller,a:b0,b:b1,back:b4,misc1:b15,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,platform:Android,

Copy link
Copy Markdown
Member Author

@Nintorch Nintorch Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't aware that the GUIDs were incompatible, but in this official (?) SDL file I also see many GUIDs that don't start with 05000000

The GUIDs were indeed incompatible with the ones that start with 0500. I'm not entirely sure how we can check for more regressions other than just testing each controller :(
We can also modify the GUIDs in godotcontrollerdb.txt to match the new ones, if that's okay!
But, for example, this change makes my DualShock 4 behave better on Android, it gets a proper name ("PS4 Controller") and now when I press the left trigger Godot doesn't register it as also pressing the Back key (I need to retest it though, but I remember it surely fixed that problem)

About the Xbox controller regression, maybe that's an actual problem with the mappings that has to be reported in the mappings db repository? I see that the previous mapping that you overwrote and the one that is currently used are the same. I also have an old PR that "actually" integrated SDL so we can check if that's not entirely a Godot problem. I can share a link to it soon.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's the link to the PR I mentioned: #109645

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found something interesting: in SDL's internal gamepad mapping database there's a mapping for your exact GUID and the mapping itself is identical to the one you made in godotcontrollerdb.txt!
https://github.com/libsdl-org/SDL/blob/58c30a4451b715b7260c8a9b6dac846a3ef28cfb/src/joystick/SDL_gamepad_db.h#L821C6-L821C38
"050000005e040000130b0000ffff3f00,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,",
Maybe I should make the code use this mapping database in this PR

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, maybe. Unfortunately, I don't know the reasons why this external file from the SDL_GameControllerDB project is used; it seems to be incorrectly configured for my Xbox controller on Android. CC @akien-mga

How much effort would it take to eliminate the dependency?

godot/core/input/SCsub

Lines 8 to 18 in 63227bb

# Order matters here. Higher index controller database files write on top of lower index database files.
controller_databases = [
"gamecontrollerdb.txt",
"godotcontrollerdb.txt",
]
gensource = env.CommandNoCache(
"default_controller_mappings.gen.cpp",
controller_databases,
env.Run(input_builders.make_default_controller_mappings),
)


https://github.com/mdqinc/SDL_GameControllerDB/blob/master/gamecontrollerdb.txt

050000005e040000130b0000ffff3f00,Xbox Series Controller,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,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,platform:Android,

--> back:b15 and without b4. This is the reason for this behavior.
image

We last synchronized the gamecontrollerdb.txt file 7 months ago; it would still be incorrect for my controller if we did it again today. This might be different for other controllers, though. I think the Windows configuration is much more important for gamers.

Copy link
Copy Markdown
Member

@Alex2782 Alex2782 Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Notice:

https://github.com/libsdl-org/SDL/blob/58c30a4451b715b7260c8a9b6dac846a3ef28cfb/src/joystick/SDL_gamepad_db.h#L821C6-L821C38
"050000005e040000130b0000ffff3f00,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,",

Maybe I should make the code use this mapping database in this PR

misc1:b15 is not configured there (share button).
I believe Xbox One controllers are without this button and the Series X have a share button.

Xbox One

https://www.ebay.de/itm/117004992242
image

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can make a PR for SDL to include misc1 :D

Copy link
Copy Markdown
Member

@akien-mga akien-mga Jan 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If 050000005e040000130b0000ffff3f00 is present in both internal SDL and SDL_GameControllerDB, then it might be a bug that it's in SDL_GameControllerDB and it should likely be removed.

It seems like it was added in SDL_GameControllerDB in 2020 with mdqinc/SDL_GameControllerDB@d1f0e1e, and later to SDL itself in 2021 with libsdl-org/SDL@afd100f.

They're not too keen on receiving PRs from Godot contributors (understandably, as for several years we had our own non-SDL implementation and misunderstood the scope of that repo, and sent custom mappings that Godot needed but SDL itself didn't need). But I'll open an issue about it as I believe it's not a Godot specific issue, just one we happened to discover.

Edit: Done: mdqinc/SDL_GameControllerDB#913.

For Godot, we can override the invalid gamecontrollerdb.txt mapping with the latest SDL one in godotcontrollerdb.txt, until we switch to proper SDL on Android too, in which case the solution can be to instead remove the mapping from both gamecontrollerdb.txt and godotcontrollerdb.txt.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can make a PR for SDL to include misc1 :D

Done! libsdl-org/SDL#14921

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now this PR reads the internal SDL Android mappings database and fixes the regression for Xbox Series X's Share button

"uinput-atrus",
};

private static final int[] JOYPAD_BUTTON_MASK_KEYS = new int[] {
Copy link
Copy Markdown
Member

@Alex2782 Alex2782 Jan 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: This was my PR 8 months ago to fix some issues with the buttons.

https://github.com/godotengine/godot/pull/106021/changes#diff-ac0a85f7a1cc7ce3e662ed81bc873b1a3cc77c6d1eda48baa2e723b0e986e1afR453

			case KeyEvent.KEYCODE_BUTTON_MODE: // Home/Xbox Button on Xbox controllers
				button = 5;
				break;


			case KeyEvent.KEYCODE_MEDIA_RECORD: // Share Button on Xbox controllers
				button = 15;
				break;

and additionally: back:b4,misc1:b15 (file: godotcontrollerdb.txt),
to fix the issues I listed above --> #114338 (comment)

@Alex2782
Copy link
Copy Markdown
Member

This branch has conflicts that must be resolved

I'll probably have time again on Monday when an Xbox controller needs to be tested on Android.

https://developer.android.com/reference/android/view/KeyEvent#KEYCODE_MEDIA_RECORD

I don't see KEYCODE_MEDIA_RECORD in the JOYPAD_BUTTON_MASK_KEYS array yet. (for misc1:b15)
I think the share button isn't being recognized yet, or I'm missing something.

@Nintorch
Copy link
Copy Markdown
Member Author

Nintorch commented Jan 30, 2026

I think adding a new key in JOYPAD_BUTTON_MASK_KEYS would make the GUIDs sometimes incompatible (since we're adding something new that wasn't in the original GUID generation code) :(

@Nintorch Nintorch force-pushed the android-sdl-guid branch 3 times, most recently from e83ff26 to 1313dfe Compare February 6, 2026 11:08
@Nintorch Nintorch requested a review from Alex2782 February 6, 2026 11:08
Copy link
Copy Markdown
Member

@Alex2782 Alex2782 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All keys are recognized, but LT and RT are swapped.

Godot Engine v4.7.dev.gh-114338.b25248d22 (2026-02-06 11:08:17 UTC) - https://godotengine.org
OpenGL API OpenGL ES 3.2 V@0502.0 (GIT@193b2ee, I593c16c433, 1633593732) (Date:10/07/21) - Compatibility - Using Device: Qualcomm - Adreno (TM) 650

+ Found newly connected joypad #0: Xbox Series X Controller - 050000005e040000130b0000ffff3f00
{ "raw_name": "Xbox Wireless Controller 4416", "vendor_id": "1118", "product_id": "2835" }

I think this is coming from the header file, but when I tested your SDL-PR a few days ago using the Android SDL test app, everything was OK, so it seems it's not compatible with Godot.

"050000005e040000130b0000ffff3f00,Xbox Series X Controller,a:b0,b:b1,back:b4,misc1:b15,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,",


And I think we need to change the order; godotcontrollerdb.txt needs to be at the very bottom, right? So that we can override it properly.

controller_databases = [
    "gamecontrollerdb.txt",
    "godotcontrollerdb.txt",
    "../../thirdparty/sdl/joystick/SDL_gamepad_db.h",
]

@Nintorch
Copy link
Copy Markdown
Member Author

Nintorch commented Feb 9, 2026

Thank you for your review! I will see what I can do to fix this issue later when I can!

@Alex2782
Copy link
Copy Markdown
Member

Alex2782 commented Feb 9, 2026

lefttrigger:a4,righttrigger:a5

I also checked the official demo app, where they are simply mapped with Axes, a4 is on the left and a5 is on the right.
One possible solution would be to override (swap) the settings in the file godotcontrollerdb.txt.

Bildschirmfoto 2026-02-09 um 15 56 52

@Nintorch
Copy link
Copy Markdown
Member Author

Nintorch commented Feb 9, 2026

That does sound like a good solution that doesn't introduce any more regressions (besides, well, what this PR does for controller mappings that don't start with 0500...)
Thanks!

@Nintorch
Copy link
Copy Markdown
Member Author

Nintorch commented Feb 10, 2026

I just noticed that the triggers for the older GUID for your controller are mapped with +s in the godotcontrollerdb.txt mapping, while in SDL's internal mapping they are not. Maybe that's causing the problem? Maybe our Godot code can't map the triggers properly unless there are +s in the mapping?

I will see what I can do.

@Alex2782
Copy link
Copy Markdown
Member

Alex2782 commented Feb 10, 2026

I just noticed that the triggers for the older GUID for your controller are mapped with +s in the godotcontrollerdb.txt mapping, while in SDL's internal mapping they are not. Maybe that's causing the problem? Maybe our Godot code can't map the triggers properly unless there are +s in the mapping?

I will see what I can do.

In my PR I used this to solve a different problem; that shouldn't be necessary anymore.

Issue #99191 (lefttrigger:+a4,righttrigger:+a5)

On Android, Controller Triggers once pressed, stay pressed until the game is restarted

@Nintorch
Copy link
Copy Markdown
Member Author

But that's still strange that the trigger mapping hasn't changed between the previous used mapping and the current one aside of the +, but now they're swapped 😅

@Alex2782
Copy link
Copy Markdown
Member

I found an old custom template on my hard drive and tried it with Godot 4.4.1, but even then the buttons/triggers were swapped. And when released, they remained pressed at 0.5. That's what the + configuration was for.

I think back then I always pressed both triggers simultaneously during testing and didn't notice that they were swapped 😃

Godot Engine v4.3.beta.custom_build.7fea02856 (2024-06-06 15:14:24 UTC) - https://godotengine.org
OpenGL API OpenGL ES 3.2 V@0502.0 (GIT@193b2ee, I593c16c433, 1633593732) (Date:10/07/21) - Compatibility - Using Device: Qualcomm - Adreno (TM) 650

+ Found newly connected joypad #0: Xbox One Controller - 58626f7820576972656c65737320436f
Bildschirmfoto 2026-02-12 um 01 38 54

@Nintorch
Copy link
Copy Markdown
Member Author

Nintorch commented Feb 12, 2026

Ohh I see, thank you for testing! :D
I will see if I'm able to reproduce it with my Xbox controller too and I will see what I can do, maybe I will have to port more code from SDL.

EDIT: The triggers are not swapped on my controller, but they are mapped to [-1;1], this will also need to be fixed without breaking my Dualshock 4 triggers

@Nintorch
Copy link
Copy Markdown
Member Author

Nintorch commented Feb 12, 2026

So I found some differences between how Godot handles Android joypad axes and how SDL handles them.
Godot checks for duplicate axes:

Set<Integer> already = new HashSet<>();
for (InputDevice.MotionRange range : device.getMotionRanges()) {
boolean isJoystick = range.isFromSource(InputDevice.SOURCE_JOYSTICK);
boolean isGamepad = range.isFromSource(InputDevice.SOURCE_GAMEPAD);
if (!isJoystick && !isGamepad) {
continue;
}
final int axis = range.getAxis();
if (axis == MotionEvent.AXIS_HAT_X || axis == MotionEvent.AXIS_HAT_Y) {
joystick.hasAxisHat = true;
} else {
if (!already.contains(axis)) {
already.add(axis);
joystick.axes.add(axis);
} else {
Log.w(TAG, " - DUPLICATE AXIS VALUE IN LIST: " + axis);
}
}
}

SDL does not:
https://github.com/libsdl-org/SDL/blob/4e2fd57e77fb4a28c0eeef0670fc4121cc2cf1f9/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java#L230-L240

                    List<InputDevice.MotionRange> ranges = joystickDevice.getMotionRanges();
                    Collections.sort(ranges, new RangeComparator());
                    for (InputDevice.MotionRange range : ranges) {
                        if ((range.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
                            if (range.getAxis() == MotionEvent.AXIS_HAT_X || range.getAxis() == MotionEvent.AXIS_HAT_Y) {
                                joystick.hats.add(range);
                            } else {
                                joystick.axes.add(range);
                            }
                        }
                    }

Currently in master my Xbox triggers are mapped to [-1;1]. If I remove the duplicate checking functionality, they work just fine (Dualshock 4 triggers too).
Maybe that's also the reason the triggers are swapped in Godot for you?

This functionality was added in #45771 to fix #45712 , but to me the original issue looks more like a mapping issue that needs to be checked in SDL testcontroller too, just in case. It also provides a way to setup a mapping for the device, maybe that would be helpful too! Or if it doesn't help, we can leave the duplicate checking functionality only for Nvidia Shield controller.

I'm gonna add a commit to remove the duplicate checking functionality here. May I ask if you can test your controller with that commit too, please?

And I also just checked and #56181 was reported only after #45771 was merged. It may be a coincidence, or may be not :D

@Nintorch Nintorch requested a review from a team as a code owner February 23, 2026 14:24
@Nintorch Nintorch force-pushed the android-sdl-guid branch 2 times, most recently from a211339 to fb27976 Compare February 23, 2026 14:57
This PR adds support for SDL-compatible joypad GUIDs on Android, so now we should be able to use SDL controller mapping database for Android controllers.
This PR adds support for Input.get_joy_info() for Android as well.
@Nintorch
Copy link
Copy Markdown
Member Author

Nintorch commented Feb 23, 2026

I came up with a way to keep the joypad mapping system backwards-compatible with the old GUID format, see the changes in core/input/input.cpp. Basically, if a mapping with the new GUID format wasn't found, the system tries to find one with the old GUID format.
(If both fail, well, the joypad doesn't have a mapping :D)
I will need to test it later though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants