Skip to content

Add support for USB vendor/product IDs to Emscripten joysticks#14003

Merged
slouken merged 2 commits intolibsdl-org:mainfrom
Nintorch:main
Sep 22, 2025
Merged

Add support for USB vendor/product IDs to Emscripten joysticks#14003
slouken merged 2 commits intolibsdl-org:mainfrom
Nintorch:main

Conversation

@Nintorch
Copy link
Contributor

@Nintorch Nintorch commented Sep 21, 2025

Description

Add support for USB vendor/product IDs to Emscripten joystick backend for browsers that provide this information (all major desktop browsers should support this, I haven't tested it yet on mobile browsers and desktop browsers other than Microsoft Edge).
This will also allow us to create custom gamepad mappings for different controllers on web in the future.
This patch has been tested with Godot Engine in this PR: godotengine/godot#109645
Here's a piece of code I used to print joystick information in Godot (where Input.get_joy_info(i) contains vendor_id field that uses SDL_GetJoystickVendor and product_id field that uses SDL_GetJoystickProduct, both of them are in base 10, not hex):

	print(Input.get_connected_joypads())
	for i in Input.get_connected_joypads():
		print(Input.get_joy_name(i), ' ', Input.get_joy_guid(i), ' ', Input.get_joy_info(i))

Here's the result on Windows for my DualShock 4 controller:

[0]
PS4 Controller 03008fe54c050000cc09000000016800 { "raw_name": "PS4 Controller", "vendor_id": "1356", "product_id": "2508", "xinput_index": "0" }

And here's the result in Microsoft Edge with the same controller and this patch applied:

[0]
Wireless Controller (STANDARD GAMEPAD Vendor: 054c Product: 09c 0000d8284c050000cc09000000000000 { "raw_name": "Wireless Controller (STANDARD GAMEPAD Vendor: 054c Product: 09c", "vendor_id": "1356", "product_id": "2508", "xinput_index": "0" }

(Here the name is not "Standard Gamepad" because in my Godot PR I changed the web gamepad mapping a little bit so we can see the controller names, this change can be ignored here)
I've also tested several other controllers (usb gamepad (Vendor: 0810 Product: e501) and 8BitDo adapter with DualShock 4 in different modes: Xbox 360 Controller (XInput STANDARD GAMEPAD), Controller (Vendor: 054c Product: 0cda) (PlayStation Classic mode)) and I can confirm that the vendor/product IDs between Microsoft Edge and Windows Godot versions match (except for the Xbox 360 Controller (XInput STANDARD GAMEPAD)).
It also detects xinput_index that uses SDL_GetJoystickPlayerIndex behind the scenes, so I'm not sure why it reports 0 on web, but that's a different issue. 😅

In this PR I decided to use JavaScript instead of C for detecting vendor and product IDs, because, for some reason, gamepadEvent->id gets cut off at the end (you can see that by looking at the code results above, it's supposed to say Wireless Controller (STANDARD GAMEPAD Vendor: 054c Product: 09cc), but c) at the end gets cut off) and JS has easy to use string manipulation methods.

Relevant information links regarding Gamepad.id having vendor/product IDs inside: https://stackoverflow.com/questions/66885705/how-to-get-vendor-and-productid-of-joystick-device-with-javascript , https://gist.github.com/Enichan/de1618d2c481523bd0c1123800bfe747 , https://developer.mozilla.org/en-US/docs/Web/API/Gamepad_API/Using_the_Gamepad_API

Would using Regex instead be a better solution or the current one should be good enough?

TODO:

  • Fix tabs/spaces indentation
  • Detect XInput controllers and return generic Xbox 360 vendor/product IDs
  • Test on Firefox
  • Some buttons might be detected as axes (for analog triggers) or some buttons might be removed incorrectly (dpad gets detected as a hat) for non-standard controllers, but it probably should be fixed in a follow-up PR I just checked the code and it checks if a controller's mapping is standard to apply these features

Existing Issue(s)

I haven't found any.

@slouken
Copy link
Collaborator

slouken commented Sep 21, 2025

This looks good to me, @icculus?

@icculus
Copy link
Collaborator

icculus commented Sep 21, 2025

There's no guarantee these strings won't change tomorrow, but the layout is guaranteed regardless of the controller in use...so do we want this?

@slouken
Copy link
Collaborator

slouken commented Sep 21, 2025

There's no guarantee these strings won't change tomorrow, but the layout is guaranteed regardless of the controller in use...so do we want this?

Yes. It's very useful to know the vendor and product and have a real controller GUID.

@Nintorch
Copy link
Contributor Author

Nintorch commented Sep 22, 2025

I found several small issues with the code, I should be able to fix them later today!

Adds support for USB vendor/product IDs to Emscripten joystick backend.
@slouken slouken merged commit ea8d8d7 into libsdl-org:main Sep 22, 2025
1 check passed
@slouken
Copy link
Collaborator

slouken commented Sep 22, 2025

Merged, thanks!

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.

3 participants