-
-
Notifications
You must be signed in to change notification settings - Fork 21.5k
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
Use SDL for joypad input on Linux #87925
base: master
Are you sure you want to change the base?
Conversation
775a09f
to
87d9d91
Compare
Does this PR support using a more recent SDL library if it's statically linked using an environment variable? See #86180 (comment). |
This PR doesn't do static linking at all, it instead either does normal linux shared linking (without use_sowrap) or dynamic loading (if use_sowrap is enabled). As far as I understand, SDL_DYNAMIC_API is something SDL itself takes care of, not ourselves. (assuming the SDL we are linking or loading is built with dynamic api support that is). |
After some testing in production for Project Heartbeat I realised I made a mistake and was polling constantly, which is no bueno for CPU usage, so I switched to waiting with a timeout (so we can do the exit condition properly when the input thread is disposed of). |
8b6b8c2
to
52eff38
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 (rebased on top of master
f040a35) on Fedora 39 X11, it works as expected. All controllers were tested in wired mode only.
In terms of out-of-the-box functionality, this PR is a big improvement for many reasons:
- My motherboard's LED controller is no longer recognized as the first controller ID (it's properly ignored). This meant the first connected controller was previously always on device ID 1, not 0. This PR effectively fixes Laptop touchpads are seen as gamepads #59250.
- Switch Pro Controller works out of the box with correct mappings on Linux in USB-C, whereas it was previously not recognized at all.
- A DualSense controller was previously seen as 2 devices (the second device was likely for motion reporting but was ineffective in Godot). This also broke controller IDs if you had multiple controllers connected if you had at least one DualSense and it wasn't the last connected controller. This PR fixes this and makes only one DualSense appear.
- With this PR, the controller name also changed from
PS5 Controller
toDualSense Wireless Controller
which is more accurate.
- With this PR, the controller name also changed from
- With this PR, Xbox One V3 controller is now called
Xbox One S Controller
instead ofXbox One Controller
which is also more accurate.
There are 2 issues I noticed though:
- Weak and strong vibration motors seem to be inverted, at least on the Xbox One V3 controller. Setting weak vibration to 0 and keeping strong vibration to 1 will result in a weak vibration with this PR, whereas it'd result in a strong vibration in
master
. - I can't use Ctrl + C in a terminal to exit the project anymore with this PR. This occurs even if no controllers are ever connected before or during the project's runtime.
Controller UUIDs reported for reference:
Controller | master |
This PR |
---|---|---|
DualSense | 030000004c050000e60c000011810000 |
4475616c53656e736520576972656c65 |
Xbox One V3 | 030000005e040000ea02000001030000 |
58626f78204f6e65205320436f6e7472 |
Switch Pro Controller | 030000007e0500000920000011810000 |
4e696e74656e646f2053776974636820 |
Binary sizes (Linux x86_64 stripped release export template with LTO):
master
: 64,166,088 bytes- This PR: 64,186,568 bytes (+20 KB)
20 KB sounds pretty reasonable considering how much this improves controller usability and paves the way for gyro support. Of course, this will be higher on platforms where we can't rely on system-provided SDL if we decide to use SDL for input on other platforms as well.
SDL by default adds handlers for sigint/sigquit. You can use SDL_SetHint to disable that behavior before SDL_Init. For example: |
I'll implement these changes today, ty |
Changes should be done now |
I Had a problem wear Gamepads on Linux were being reported twice but not on Windows [90795] however this Pull Request [87925] from my testing has fixed all issues Output from 4.2.1 - Gentoo Linux Output from 4.3 PR [52eff38] - Gentoo Linux |
I am uncertain if this is intended behavior or a bug ether way if I connected my Left Joycon via Bluetooth it's eating 2 device slots causing issues with split-screen input
|
What version of SDL are you running in your OS? from what I can tell that issue was fixed in SDL two years ago. |
I am on Gentoo Linux everything is up to date and I am running SDL 2.30.2 |
I just ran some tests. I agree with the discussion and think this offers huge benefits in term of controller support and code re-usability. Thank you for your work. |
I've also been shipping it in Project Heartbeat Phoenix for a while without any major hiccup. |
Used |
483183f
to
c1d1da5
Compare
I confirm that this fixes the multiple problems my dualsense edge controller has with godot. Vibrations work correctly and I'm able to CTRL+C to quit the application normally. 20kb size increase is totally acceptable to me given that controller support for me or my users would be broken without it. Is this PR considered for 4.3? |
I'm generally favorable to exploring using SDL for gamepad input, as we've been playing catch up with them over the years and we're lacking in many areas. There are a couple problems with the approach in this PR though, which will require further work before a solution is mergeable (not suggesting to do it now, this requires more discussion with the team first):
|
I think we have to think of SDL like we do about Pulse or xlib, it's a system library that lets us do things, we wouldn't ship our own pulse library version ever, would we? If you really want to statically link SDL even though it's not a very good idea, SDL has a dynamic api loading mechanism that users can use to replace the library. Additionally, note that this PR falls back to the traditional Godot input driver if SDL is not present. |
Something to note, there should be a way to communicate that the user is missing SDL in this case, otherwise they might blame the game for poor input (especially since the built-in input driver will likely become neglected after this). Also telling people to install dependencies on things like itch pages is often a major turnaway for people. So I'd suggest just adding a checkbox in the export settings for bundling SDL with the game. |
Makes sense tbh, i'll work on static linking in a bit |
What's the status for this PR? Now that 4.4 has started, I'd appreciate it if this was merged early on to catch as many errors as possible before 4.4 reaches stable. Is it just static linking that needs to be worked on? Personally, I think it should be statically linked, just for those who don't have SDL installed on their system, since SDL comes with a dynamic loading system anyway. |
See #87925 (comment), which is still relevant. If we merge SDL gamepad support on Linux for 4.4, I feel this also needs to be done for Windows and macOS in the same release. |
Rebased against master, still haven't had time to work on statically linked SDL, but will do so ASAP. |
SDL is loaded in the same way other Linux system libraries are loaded by using a wrapped and dlopen. Optionally, SDL can be dynamically linked into the binary. Currently for Linux only since that platform direly needs it, but should be easy to make work on Windows once stable. Proposal at: godotengine/godot-proposals#9000
What do you want me to do with the SDL library? Should it be in thirdparty like all other builtin libraries? |
Nevermind, it's going to be big trouble to get it to compile inside godot, so we should just make static builds like we do with nir. |
Worth noting that SDL's buildsystem lets you avoid building any subsystems you're not interested in using. So we could just build the input subsystem and that should result in a smaller binary. |
SDL is loaded in the same way other Linux system libraries are loaded by using a wrapped and dlopen.
Optionally, SDL can be dynamically linked into the binary.
Currently for Linux only since that platform direly needs it, but should be easy to make work on Windows once stable.
Proposal at: godotengine/godot-proposals#9000
P.S: I've made sure to strip the files as much as possible, but unless you want to be pulling your hair out by stripping files individually this is the best we can do IMO.