Add support for joypad haptics (force feedback)#114642
Add support for joypad haptics (force feedback)#114642Nintorch wants to merge 1 commit intogodotengine:masterfrom
Conversation
42740b3 to
0360006
Compare
It's used in conditional effects (named center in SDL3) together with the deadband parameter to set a dead zone for this kind of effects. Wheels in real vehicles have a dead zone where the wheel is resting when driving straight. These parameters can simulate that dead zone, and when changing the offset it can also simulate a broken steering that has its center off. It's also used in periodic effects to the set the mean value.
The periodic effects should be included, they can be used to simulate vibrations on the wheel without having to update the effects periodically. We're missing parameters like direction, saturation, deadband, envelope, repetition, etc. I like better the SDL3 approach with generic functions for all effect types, and passing the effect as a parameter. It makes it easier to add many effects without duplicating code. It also has structs with all parameters that are standard nowadays for force-feedback. It's probably tedious to use, but it gives way more control over the effects, kinda professional versus a hobbyist implementation. I appreciate its simplicity but it would turn fast into excessive rigidity when using it seriously. It might be a bit tedious to implement but not much work since it's just mirroring what SDL3 (and all APIs) already does. We should have functions to handle this flow:
The reason to do it separately like this is because effects are uploaded into device slots. Creating an effect can have a performance cost depending on the device, so we want to create the effect once and maybe play it many times, update it many times, then remove it when it will be no longer used for a while to free the slot. Start and Stop can actually be handled in the same call by setting repetition to zero, or just updating the effect with length zero. We have to also make sure we're handling infinite duration and infinite repetition correctly. |
0360006 to
16377ae
Compare
16377ae to
9621efe
Compare
|
Although this PR is draft, I played a bit with this (using only constant_force_feedback). Seems that the force is likely set to 0 for a while every time it is set, at least when the previous value is still in use. Video (with sound): First tested this with another project, but then made this tiny test-project (as seen in the video) to understand the behavior better: In https://github.com/Dechode/Godot-FFB-SDL (that I originally used in the "another project" mentioned) there are no these kind of glitches. Steering wheel used: Logitech Driving Force GT (yes, it's old and noisy, but at least the glitches can be easily heard ;) ), OS: Linux (Mint) BTW: Compiling this seemed to fail due to some undefined references. Commented these lines out from core/register_core_types.cpp to make it compilable (don't know if worth mentioning as this is draft, though...): |
|
Looking at the code, the behaviour (the wheel rattling) GNSS-Stylist said is because calling constant_force_feedback() starts and plays a new ffb effect, always. When the code is updated to work as Berarma said (and the description of the commit now), we can start, update, stop and remove the effect as we please. Then it should work as intended, as long as the process()/physics_process() only updates the already uploaded effect. |
|
What about GameInput API? Idk much about APIs |
We thought about using GameInput for SDL, but the license looks incompatible with Godot's MIT license: #107967 (comment) |
|
I see, thx! |
f125636 to
49de134
Compare
|
I have just overcome my biggest problem with this PR: my laziness to write the boilerplate code. This evening (for me) I wrote a Python script that would read a file in a special format I came up with and it would transform this simple file into a This script will be useful later when I decide to add I open-sourced this script in case anyone would find it useful too :D |
416af54 to
f33b8bc
Compare
|
I have rewritten the code, so when the CI finishes you guys can try it out, please let me know if it works! :D |
f33b8bc to
5ed63b4
Compare
5ed63b4 to
a6afa34
Compare
|
Tried to test this. Compiled fine, but don't really know how to use this. Code like this runs: But of course this doesn't do anything. Looked at the commit and expected that the effect needs to be activated by using something like "Input.create_joy_haptic_effect(haptic)", but Godot doesn't recognize the function (it recognizes other functions from the same "block" on input/input.h like set_joy_motion_sensors_enabled). Then tried to add those functions to Input::_bind_methods() (pretty much shooting in the dark because those other function were there): But this fails to compile. So I'm a bit confused. How this should be used? |
|
Oh, you're right, I forgot to register the methods... |
b69b2c7 to
5ca0779
Compare
5ca0779 to
63a906d
Compare
|
Fixed! |
|
That was fast! Also tested quickly attack_length and fade_length-parameters and they seemed to work too. Needed a bit of trial and error to get working so may need some documentation (if not done already? Don't know how the documentation process goes). |
|
That's good to hear, thank you for testing! :D |
|
Works for me too, using linux and g29. I tried it with the ffb-test-v2 project GNSS-Stylist provided and it worked as it should. |
|
Thanks for testing! :) |
|
I can help with the documentation where i can. But i must say, i have never used other effects other than the constant force effect, so i don't have a lot of experience. |
I have found a way to use GameInput in Godot! #116055 |
Well! Progress Is progress! Even if it doesn't end to anything rn, but maybe there Is another way later on Fallback could be useful still, those are issues Which you seem to be already addressing Honestly you are carrying the entire PR lol Edit: Nvm, I expanded the PR, you got It working lol, nice! Tho nice coincidence that everyone here has a G29 XD |
|
OHHH |
Thanks, and yeah, I hope someone would be able to make a GameInput haptics backend for SDL at some point, then we'll be able to fully switch from DirectInput!
By the way, it's been fixed! Now the input when not in focus does work! :D
Thanks, any help would be appreciated! :)
Yes indeed it was me! :D |
|
Oops, misclick 😅 |
Np!
Hell yeah! Very nice! 👏👏👏 |
Closes godotengine/godot-proposals#8309
This PR exposes SDL's Haptic subsystem to the user.
(P.S. Personally, I don't know how to use this subsystem, but other people do, so it would be useful to them 😅)
Made possible by my small GodotBoilerplateGenerator :D
TODO:
What is anoffsetparameter mentioned in the original proposal exactly?Is this approach good enough or should we expose the entirety of the haptic subsystem? (WithInputHapticEffectclasses, constants and such, which sounds quite tedious to both use and implement 😅)Other effect types?M_PIwithMath::PIInput.create_joy_haptic_effect()Input.start_joy_haptic_effect()Input.update_joy_haptic_effect()Input.stop_joy_haptic_effect()Input.remove_joy_haptic_effect()InputHapticEffect.direction_degrees