Skip to content

[SDL3] Adding input and FFB support for Logitech G29(PS3) on hidapi #11598

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

Merged
merged 26 commits into from
Mar 17, 2025

Conversation

Kethen
Copy link
Contributor

@Kethen Kethen commented Dec 6, 2024

#11591 for SDL3

companion test program for SDL3 https://github.com/Kethen/sdl_lg4ff_util/tree/SDL3_lg4ff

WINE has not moved onto SDL3 so it cannot be tried on WINE at the moment

@slouken
Copy link
Collaborator

slouken commented Dec 6, 2024

This is an impressive PR. How does this interact with other drivers, like new-lg4ff? Is there any reason we'd want this active when those are available?

@Kethen
Copy link
Contributor Author

Kethen commented Dec 6, 2024

This is an impressive PR.

Thanks but a large portion of it was ported from https://github.com/berarma/new-lg4ff

How does this interact with other drivers, like new-lg4ff?

On Linux, it depends on how it was opened:

  • If it was opened on /dev/hidraw*, kernel drivers would stay active, and if the wheel is accessed through both drivers, it will be receiving confusing commands from two sources, tho it's generally fine if active effects are on only one side at a time
  • If it was opened on /dev/bus/usb/* using libusb, exclusive access should be obtained and kernel drivers will unprobe

Which path would happen depends on which hidapi backend SDL was built to use and device node permissions

On MacOS, if I understand correctly some games also use IOHIDManager to provide wheel support on their own. SDL3 currently does not grab exclusive access

hid_darwin_set_open_exclusive(0);

No idea if existing games grab exclusive access

On Windows, I have no idea how it would react with the Logitech driver, no idea if any exclusive access would happen when hidapi opens the device from CM_Get_Device_Interface_List fetched interface names

Is there any reason we'd want this active when those are available?

On Linux, evdev does not provide an analog to GetEffectStatus, user is expected to track that as effects are uploaded, I think https://bugzilla.kernel.org/show_bug.cgi?id=219189; otherwise I'd expect the kernel drivers to have better latency profiles

As for availability, unless udev rules were supplied (usb) (hidraw), the evdev backend would be used on SDL

On Windows, once again I have no idea

@Kethen
Copy link
Contributor Author

Kethen commented Dec 6, 2024

Added build fixes for platforms with hidapi disabled, without M_PI, and Android

Still need help with MSVC project files

@Kethen Kethen force-pushed the SDL3_lg4ff branch 4 times, most recently from f3c2dcc to c59ecbc Compare December 7, 2024 11:09
@Kethen
Copy link
Contributor Author

Kethen commented Dec 7, 2024

rebased and fixed windows building

@slime73
Copy link
Contributor

slime73 commented Dec 7, 2024

a large portion of it was ported from https://github.com/berarma/new-lg4ff

If code was taken from there, is there permission to relicense it from GPL to zlib?

@Kethen Kethen force-pushed the SDL3_lg4ff branch 2 times, most recently from 8857b97 to 7d16076 Compare December 29, 2024 12:28
@slouken slouken added this to the 3.4.0 milestone Jan 15, 2025
@Kethen
Copy link
Contributor Author

Kethen commented Jan 15, 2025

Thanks @mungewell , @MadCatX and @berarma once again for graciously allowing ported code to be used under Zlib license in SDL

#11591 (comment)
#11591 (comment)

@Lawstorant
Copy link
Contributor

Lawstorant commented Feb 26, 2025

WINE has not moved onto SDL3 so it cannot be tried on WINE at the moment

What about sdl2-compat? I've been using it lately as arch forced this move and it works great. It should allow you to test this with Wine.

@@ -2574,7 +2574,12 @@ bool SDL_IsGamepad(SDL_JoystickID instance_id)
SDL_LockJoysticks();
{
const void *value;
if (SDL_FindInHashTable(s_gamepadInstanceIDs, (void *)(uintptr_t)instance_id, &value)) {
SDL_JoystickType js_type = SDL_GetJoystickTypeForID(instance_id);
Copy link
Collaborator

Choose a reason for hiding this comment

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

You probably want this logic in the else case so you can cache the value and not call this every time the function is called.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah that would make more sense, sorry for not understanding the result caching before

Kethen and others added 8 commits March 12, 2025 10:50
Current implementation does not include SDL_Haptic integration
for force feedback

Supported devices:
G29, G27, G25, DFGT, DFP

Features:
Joystick button, hat and axis input
5 level rev light control on SDL_JoystickSetLED
raw hid command sending on SDL_JoystickSendEffect

all command sending are based on https://github.com/berarma/new-lg4ff

tested on G29 in various compat modes

shifter input is not tested because I don't have one
If a SDL_Joystick internal lookup manages to define a joystick
type that is not gamepad, it should stay as a joystick
Kethen and others added 17 commits March 12, 2025 10:50
…d, SDL_SetHapticGain and SDL_SetHapticAutocenter sequence
Original commit:

Author: Ozkan Sezer <sezeroz@gmail.com>
Date:   Sun Dec 29 17:55:04 2024 +0300

minor clean-ups:

- make _abs,_llabs, get_time_ms, effect_is_periodic, effect_is_condition
  helpers static inline.
- rename _abs and _llabs to abs32 and abs64 to avoid analyzers complain
  about reserved names.
- make the drivers[] array static.
- NULL terminate the drivers[] array to avoid an empty array in case if
  SDL_HAPTIC_HIDAPI_LG4FF isn't configured.
- minor formatting clean-ups here and there.
- remove #endif comments about SDL_JOYSTICK_HIDAPI for readability.
   those #if / #endif blocks are short enough already.
@Kethen
Copy link
Contributor Author

Kethen commented Mar 12, 2025

WINE has not moved onto SDL3 so it cannot be tried on WINE at the moment

What about sdl2-compat? I've been using it lately as arch forced this move and it works great. It should allow you to test this with Wine.

tested that a while back and it didn't quite work in WINE, it just didn't enumerate controllers, and I haven't gotten around to figure out why it didn't work

sdl2-compat does work with the companion test program however last time I tried

@slouken
Copy link
Collaborator

slouken commented Mar 14, 2025

WINE has not moved onto SDL3 so it cannot be tried on WINE at the moment

What about sdl2-compat? I've been using it lately as arch forced this move and it works great. It should allow you to test this with Wine.

tested that a while back and it didn't quite work in WINE, it just didn't enumerate controllers, and I haven't gotten around to figure out why it didn't work

Can you investigate this? I'm ready to merge once it's confirmed working.

@Kethen
Copy link
Contributor Author

Kethen commented Mar 17, 2025

WINE has not moved onto SDL3 so it cannot be tried on WINE at the moment

What about sdl2-compat? I've been using it lately as arch forced this move and it works great. It should allow you to test this with Wine.

tested that a while back and it didn't quite work in WINE, it just didn't enumerate controllers, and I haven't gotten around to figure out why it didn't work

Can you investigate this? I'm ready to merge once it's confirmed working.

Just gave it a test, as of writing, on Linux, freshly compiled sdl2-compat(4453e2d05881c3616af8ca71f7c4267c60f993d8) can enumerate controllers in wine (10.0 staging and GE-Proton9-25), and can be used with this PR to provide G29 ffb for assetto corsa on dinput8, with the appropriate udev rules

$ lsusb
...
Bus 001 Device 016: ID 046d:c24f Logitech, Inc. G29 Driving Force Racing Wheel [PS3]
...

$ WINEDEBUG="-all,+hid" LD_LIBRARY_PATH="$(realpath ./sdl_test)" wine ... 2>&1 | tee log.txt &
$ cat log.txt
...
0098:trace:hid:process_device_event Received action 605
0098:trace:hid:sdl_add_device Making up serial number for Logitech G29: 03009a206d0400004fc2000000646800.0
0098:trace:hid:sdl_add_device joystick id 0, axis_offset 0, desc {vid 046d, pid c24f, version 6400, input -1, uid 00000000, is_gamepad 0}.
...
0084:trace:hid:sdl_device_physical_device_control iface 0x7fb14802fe40, control 0x9a.
0084:trace:hid:sdl_device_physical_device_set_gain iface 0x7fb14802fe40, percent 0x64.
0084:trace:hid:sdl_device_physical_effect_update iface 0x7fb14802fe40, index 1, params 0x7fb14802ffe0.
...

$ lsof /dev/bus/usb/001/016 sdl_test/*
lsof: WARNING: can't stat() tracefs file system /sys/kernel/debug/tracing
      Output information may be incomplete.
COMMAND     PID      USER  FD   TYPE DEVICE SIZE/OFF    NODE NAME
winedevic 89380 katharine mem    REG   0,52          3975143 sdl_test/libSDL3.so.0 (stat: Operation not permitted)
winedevic 89380 katharine mem    REG   0,52          3975144 sdl_test/libSDL2-2.0.so.0 (stat: Operation not permitted)
winedevic 89380 katharine  43u   CHR 189,15      0t0    1176 /dev/bus/usb/001/016
winedevic 89380 katharine  51u   CHR 189,15      0t0    1176 /dev/bus/usb/001/016

@slouken slouken merged commit 35c0377 into libsdl-org:main Mar 17, 2025
39 checks passed
@slouken
Copy link
Collaborator

slouken commented Mar 17, 2025

Great! This is merged, thank you for all your work!

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.

5 participants