-
-
Notifications
You must be signed in to change notification settings - Fork 22.7k
Add support for SDL3 joystick input driver for Windows, Linux and macOS #106218
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
d9771ff
to
b00ec6a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested locally on Windows 11 24H2 and Linux (Fedora 42), it works as expected.
Tested controllers on the joypads demo (wired if not mentioned):
Windows
Controller | Name/GUID on master |
Name/GUID on this PR |
---|---|---|
DualSense | PS5 Controller 030000004c050000e60c000000000000 |
DualSense Wireless Controller 4475616c53656e736520576972656c65 |
DualSense Edge | PS5 Controller 030000004c050000f20d000000000000 |
DualSense Edge Wireless Controller 4475616c53656e736520456467652057 |
Xbox Elite Series 2 | Xbox One For Windows __XINPUT_DEVICE__ |
Xbox One Controller 58626f78204f6e6520436f6e74726f6c |
Xbox Elite Series 2 (Bluetooth) | (empty name) __XINPUT_DEVICE__ |
Xbox One Elite 2 Controller 58626f78204f6e6520456c6974652032 |
Switch Pro Controller | Nintendo Switch Pro Controller 030000007e0500000920000000000000 |
Nintendo Switch Pro Controller 4e696e74656e646f2053776974636820 |
Nyxi Warrior (emulates Xbox 360 controller) | XBOX 360 For Windows __XINPUT_DEVICE__ |
Xbox 360 Controller 58626f782033363020436f6e74726f6c |
Vibration doesn't work on the DualSense and DualSense Edge in master
, but this PR fixes it.
Mapping is broken on Switch Pro controller on master
(buttons flicker in and out randomly), but this PR fixes it.
macOS
Controller | Name/GUID on master |
Name/GUID on this PR |
---|---|---|
DualSense | DualSense Wireless Controller - 4475616c53656e736520576972656c65 | DualSense Wireless Controller - 4475616c53656e736520576972656c65 |
DualSense Edge | DualSense Edge Wireless Controller 4475616c53656e736520456467652057 |
DualSense Edge Wireless Controller 4475616c53656e736520456467652057 |
Xbox Elite Series 2 | Controller 436f6e74726f6c6c6572 |
Controller 436f6e74726f6c6c6572 |
Xbox Elite Series 2 (Bluetooth) | Xbox Wireless Controller 58626f7820576972656c65737320436f |
Xbox Wireless Controller 58626f7820576972656c65737320436f |
Switch Pro Controller | Pro Controller 50726f20436f6e74726f6c6c6572 |
Pro Controller 50726f20436f6e74726f6c6c6572 |
Vibration doesn't work on the Xbox Elite Series 2 controller when wired, both before and after this PR. It works in Bluetooth though.
DualSense (standard and Edge) trackpad presses are not recognized as a press of button index 20 on master
, but this PR fixes it.
On master
, pressing the Select button has a noticeable delay. This is because macOS waits for you to double-tap it to enable screen recording (it prompts a permission dialog when doing so). This behavior happens on all controllers except Switch Pro Controller.
On this PR, this behavior no longer happens. The Select button is effective immediately, but you can't start a recording by double-tapping it anymore. I think this is preferable as it better matches the behavior on other operating systems.
Similar behavior can be seen with the Xbox button on the Xbox Elite Series 2 in Bluetooth. In master
, pressing it will open macOS' games list, while it won't do anything with this PR.
Linux
Controller | Name/GUID on master |
Name/GUID on this PR |
---|---|---|
DualSense | PS5 Controller 030000004c050000e60c000011810000 |
Sony Interactive Entertainment DualSense Wireless Controller 536f6e7920496e746572616374697665 |
DualSense Edge | Sony Interactive Entertainment DualSense Edge Wireless Controller 030000004c050000f20d000011810000 |
Sony Interactive Entertainment DualSense Edge Wireless Controller 536f6e7920496e746572616374697665 |
Xbox Elite Series 2 | Microsoft X-Box One Elite 2 pad 030000005e040000000b00000d050000 |
Xbox One Elite 2 Controller 58626f78204f6e6520456c6974652032 |
Xbox Elite Series 2 (Bluetooth) | Xbox One Elite 2 Controller 050000005e040000220b000013050000 |
Xbox One Elite 2 Controller 58626f78204f6e6520456c6974652032 |
Switch Pro Controller | Nintendo Switch Pro Controller 030000007e0500000920000011810000 |
Nintendo Pro Controller 4e696e74656e646f2050726f20436f6e |
Nyxi Warrior (emulates Xbox 360 controller) | Xbox 360 Controller 030000005e0400008e02000010010000 |
Xbox 360 Controller 58626f782033363020436f6e74726f6c |
DualSense Edge and wired Xbox Series Elite 2 have incorrect mappings on master
, but this PR fixes them.
Xbox Series Elite 2's GUID no longer changes depending on whether the controller is wired or wireless, which I think makes more sense. However, the DualSense and DualSense Edge now have the same GUID, which is strange as they are physically different controllers (with the DualSense Edge having additional paddles).
Vibration is working on all controllers, both before and after this PR.
Binary size
Linux x86_64 stripped release export template (production=yes lto=full
):
master
: 68,988,216 bytes- This PR: 69,626,456 bytes (+ 638 KB)
This is non-negligible, but considering it only affects desktop platforms, I consider this reasonable. This will likely be more of an issue when we get to mobile/web platforms though, but hopefully the binary size impact is lower there (e.g. as a virtue of using optimize=size
on web).
Edit: Added Windows and macOS tests.
Tested on macOS, and seems to be working fine. And unlike native implementation, "start" button does not cause OS game menu to pop-up. But unused parts of the SDL probably should be removed (ideally would be nice to remove even dummy subsystems). |
Thank you so much for reviews! |
It depends, if it can be disabled with a few commented lines, it OK, a lot of third party code have some minor modifications (patches added to the subfolder in this case, e.g, https://github.com/godotengine/godot/tree/master/thirdparty/d3d12ma/patches). But if it's a big change, than it probably does not worth the effort. |
So I've tried to remove even the dummy subsystems but I found out it would probably either require a significant rewrite of SDL files or (maybe) creating our own files for SDL_events code (but I'm not sure if that's practical) |
e84811d
to
088a6df
Compare
I've removed unused SDL files, improved the code and made sure it works. The code should be ready for review |
Thank you so much, AThousandShips and bruvzg, for your reviews! |
May I also ask if I should disable the instantiation of older joypad systems? I don't want to remove them just yet, but I can disable them, and if after this PR gets merged people won't find strange behaviour in the joypad system, I think we can remove the old joypad systems since JoypadSDL supersedes them. |
Discussed on Rocket.chat with bruvzg:
We don't foresee anything that our current code would be able to do that SDL couldn't, so let's go all in. We can always bring it back if we get regressions and need a quick workaround.
iOS/visionOS should be easy as it should be pretty much the same code we already have for macOS. Can be done as a follow-up (CC @stuartcarnie @bruvzg ). For Android and Web we expect there's going to be a bit more work with Java and JavaScript code involved, so let's keep it for follow-ups (likely for 4.6). So let's go ahead and merge. I'll squash the commits. |
024c960
to
32d7915
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great to me!
Once this PR is merged, I'll implement the iOS/visionOS version and remove all the redundant code. |
Made possible by EIREXE, xsellier and the SDL team. This commit includes statically linked SDL3 for Windows, Linux and macOS. The vendored copy of SDL3 was setup to only build the required subsystems for gamepad/joystick support, with some patches to be able to make it as minimal as possible and reduce the impact on binary size and code size. Co-authored-by: Álex Román Núñez <eirexe123@gmail.com> Co-authored-by: Xavier Sellier <xsellier@gmail.com> Co-authored-by: Rémi Verschelde <rverschelde@gmail.com>
Thanks! This is one hell of a first contribution! 🎉 |
I will test this looking awesome |
Thank you so much, everyone, it was very fun to work on this PR! :D |
Thank you for all the hard work! Amazing first contribution, but don't feel any pressure to outdo it with your next 😆 |
Based on #87925, xsellier@2139868 and xsellier@734322b .
Supersedes #87925
Closes godotengine/godot-proposals#9000 .
Fixes #106618
Fixes #47874
Fixes #81191
Fixes #37675
Bugs that were reported to be fixed by the previous SDL input PR:
Fixes #90795
Fixes #50273
This PR is based on an earlier PR made by EIREXE and several commits made by xsellier (I hope they wouldn't mind...). The mentioned PR was made to work on Linux distributions, and commits by xsellier inspired me to implement support for Windows and MacOS and make SDL3 compile statically inside the Godot's build system.
This PR includes statically linked SDL3 library and it was tested on Windows, Linux and MacOS. On Windows before this PR Godot would print "030000004c050000cc09000000000000" as the GUID for my Dualshock 4 gamepad, after this PR it prints
"50533420436f6e74726f6c6c6572"(EDIT: that was a hex version of the gamepad's name, now the code should print its actual GUID).SDL3 was setup to only build the required subsystems
while using dummy code for subsystems that are not going to be used in this PR (for example, GPU, audio, video, etc.),(EDIT: now the dummy subsystems are not included either) and the SDL joystick driver code, alongside with SDL's source code, is ignored on platforms that aren't implemented yet (those are Android, iOS and Web platforms).This would be my first contribution to Godot. I really like this software and would like it to become even better every day! :)
EDIT: TODO:
remove dummy SDL systems if possibleNot sure it's possible to do practicallyI will push the changes once I'm done with the tasks
EDIT 2: TODO:
TODO 3:
TODO in a follow-up PR: