Last active
September 7, 2019 21:49
-
-
Save jdinalt/278d752ab3c898090b109b2297d82379 to your computer and use it in GitHub Desktop.
Debug Notes for Broken FFB on DiRT Rally 2.0, Linux
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
TL;DR | |
Force feedback does not work with the Logitech G29 driving wheel on "DiRT Rally | |
2.0" when running under the Linux/Proton environment. This leads to a | |
sub-satisfactory gaming experience. | |
I have traced the issue to a SDL2 call, SDL_HapticUpdateEffect(), made by the | |
the following Proton patch: | |
https://git.froggi.es/tkg/PKGBUILDS/blob/2b563056f83e555bef56616a9a48578b1ea0758c/wine-tkg-git/wine-tkg-patches/proton-sdl-joy.patch | |
The issue does not appear to lie with the above Proton patch or even the SDL2 | |
lib. After having instrumented the code, it appears that something is causing | |
the kernel hapatic driver to "forget" about a valid SDL hapatic effect. | |
When this happens, the next call into the driver to update what should be a | |
valid effect returns EINVAL. Later, when the library attempts to delete the | |
effect, the kernel also reports EINVAL. It appears that the effect has been | |
erased by "something." Possibly a bug in the driver or hapatic framework. | |
Possibly something else has opened the driver? | |
As a work around, I have created a patch to the SDL2 library to "regenerate" | |
the effect when this happens. | |
It appears to work: force feedback in DiRT Rally | |
2.0 works -- mostly. This does not fix the root-cause of the problem, but it | |
does make for a much more enjoyable experience. | |
When I say that FF "mostly" works, the instrumented code indicated that the | |
game is attempting to create three unsupported effects, in addition to the one | |
effect that it does support. | |
Specifically: | |
FF_CONSTANT : Supported by G29 driver | |
FF_SPRING : Unsupported | |
FF_FRICTION : Unsupported | |
FF_DAMPER : Unsupported | |
I can only assume that I am still not getting the complete experience. This | |
is something to follow up on to see if these effects can be added to the | |
driver, but that's a project for another day. I have checked up-stream and | |
these still have not been implemented. *sad-face* | |
I have briefly tested the game in Windows -- I know, "the horror... the | |
horror..." -- and as far as I can tell, the missing effects just add some | |
baseline resistance to the wheel. This lasted for about two games, before | |
DiRT stopped recognizing the wheel as a G29 and then force-feedback stopped | |
working, then I pulled the plug on Windows and put the contaminated SSD back | |
into the containment chamber. | |
For what it is worth,, I have found that I have fewer problems running | |
native Windows games with Linux/Proton than in the native Windows | |
environment. Go figure. | |
Test Environment: | |
Proton: 4.11-3 | |
DiRT Rally 2.0: 1.8 | |
Linux Distribution: Ubuntu 18.04.2 LTS | |
Kernel (not default for distro): 4.18.0-20-generic #21~18.04.1-Ubuntu SMP | |
CPU: i5-4570 CPU | |
Memory: 24635640 kB | |
GPU: GeForce RTX 2070 | |
NVIDIA Driver: 430.14 | |
Wheel: Logitech G29 | |
Note: | |
I have a pretty complete set of build tools and libraries installed. You | |
may find that you have to spend some time tracking down and installing the | |
missing components to make these instructions work. | |
Patching Instructions: | |
Create a new file, named "sdl2-hapatic-retry.patch", with the following contents: | |
https://gist.github.com/jdinalt/0616d7b4c4f509a443e85ecee201e12f | |
# Get a fresh copy of the SDL2 library source code -- this is a slightly newer | |
# version of the lib than the one used by Steam. The patch will /probably/ work | |
# on that version, but I have not tested it. | |
jdinalt@Ix:~/dev$ wget https://www.libsdl.org/release/SDL2-2.0.10.tar.gz | |
# Extract the source | |
jdinalt@Ix:~/dev$ tar -xzf SDL2-2.0.10.tar.gz | |
# Apply the patch | |
jdinalt@Ix:~/dev$ patch -p0 --verbose < sdl2-hapatic-retry.patch | |
Hmm... Looks like a unified diff to me... | |
The text leading up to this was: | |
-------------------------- | |
|diff -Naur SDL2-2.0.10/src/haptic/linux/SDL_syshaptic.c SDL2-2.0.10.patched/src/haptic/linux/SDL_syshaptic.c | |
|--- SDL2-2.0.10/src/haptic/linux/SDL_syshaptic.c 2019-07-24 21:32:36.000000000 -0700 | |
|+++ SDL2-2.0.10.patched/src/haptic/linux/SDL_syshaptic.c 2019-09-04 10:52:36.784736281 -0700 | |
-------------------------- | |
patching file SDL2-2.0.10/src/haptic/linux/SDL_syshaptic.c | |
Using Plan A... | |
Hunk #1 succeeded at 974. | |
Hunk #2 succeeded at 982. | |
done | |
# Configure the lib | |
jdinalt@Ix:~/dev$ cd SDL2-2.0.10/ | |
jdinalt@Ix:~/dev/SDL2-2.0.10$ ./configure | |
... | |
# Build the lib (the number after '-j' should be the number of cores you have to | |
# build with) | |
jdinalt@Ix:~/dev/SDL2-2.0.10$ make -j 4 | |
... | |
# Create an environment variable with the path to your steam directory | |
# The following is /probably/ right, but may need adjustment. | |
jdinalt@Ix:~/dev/SDL2-2.0.10$ STEAM_PATH="/home/${USER}/.local/share/Steam" | |
# Backup the steam version of the library | |
cp "${STEAM_PATH}/ubuntu12_32/steam-runtime/amd64/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.9.0" "${STEAM_PATH}/ubuntu12_32/steam-runtime/amd64/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.9.0.original" | |
# Replace the original steam SDL2 library with a symbolic link to the freshly | |
# build one. | |
jdinalt@Ix:~/dev/SDL2-2.0.10$ ln -fs "$(realpath ./build/.libs/libSDL2-2.0.so.0.10.0)" "${STEAM_PATH}/ubuntu12_32/steam-runtime/amd64/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.9.0" | |
# Verify that the link points to the right place | |
jdinalt@Ix:~/dev/SDL2-2.0.10$ ls -l "${STEAM_PATH}/ubuntu12_32/steam-runtime/amd64/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.9.0" | |
lrwxrwxrwx 1 jdinalt jdinalt 63 Sep 4 12:11 /home/jdinalt/.local/share/Steam/ubuntu12_32/steam-runtime/amd64/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.9.0 -> /home/jdinalt/dev/SDL2-2.0.10/build/.libs/libSDL2-2.0.so.0.10.0 | |
# Update the linker cache, just to be sure that we don't use an in-core version | |
# of the old library. | |
jdinalt@Ix:~/dev/SDL2-2.0.10$ sudo ldconfig | |
[sudo] password for jdinalt: | |
# You should be ready to test DiRT 2.0. Have fun! | |
# If things are "for malfunction," try restarting steam. If it is still borked, | |
# make sure you are using the software versions above, Your millage may vary. | |
<insert insane driving experience here> | |
# Should you wish to revert to the original library: | |
jdinalt@Ix:~/dev/SDL2-2.0.10$ cp "${STEAM_PATH}/ubuntu12_32/steam-runtime/amd64/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.9.0.original" "${STEAM_PATH}/ubuntu12_32/steam-runtime/amd64/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.9.0" | |
# If things are not working, my diagnostic patch is also available here: | |
https://gist.github.com/jdinalt/d9977cd1d7106487736ef0b43f0a427d | |
This patch includes the work-around, but also instruments the SDL library to log | |
nearly everything associated with FFB. The log output is appended to | |
"/tmp/sdl.log" when any process initializes the "hapatic" interface. | |
It is very verbose, so use with caution, as the log can grow very quickly. | |
To use this patch, I would recommend starting with a clean copy of the SDL2 | |
sources. Just extract the SDL2 archive into a location, absent any previously | |
patches versions of SDL2: | |
Something along the lines of the following: | |
# Assume we are in a directory containing: | |
# SDL2-2.0.10.tar.gz and sdl2-trace-plus-fix.patch | |
# Also assumes that the Steam version of the SDL2 lib has already been backed up | |
# and STEAM_PATH has been set. | |
mkdir sdl2-trace | |
tar -C sdl2-trace -xzf SDL2-2.0.10.tar.gz | |
cp sdl2-trace-plus-fix.patch sdl2-trace | |
cd sdl2-trace | |
patch -p0 --verbose < sdl2-trace-plus-fix.patch | |
cd SDL2-2.0.10/ | |
./configure | |
make | |
ln -fs "$(realpath ./build/.libs/libSDL2-2.0.so.0.10.0)" "${STEAM_PATH}/ubuntu12_32/steam-runtime/amd64/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.9.0" | |
The first step is to launch DiRT 2.0 and then immediately quit; check the | |
contents of "/tmp/sdl.log" | |
You should see a file containing a trace, much like the one at the end of this | |
file. The first column contains the process ID of the caller, then microseconds | |
since the log was initialized, followed by the calling function name and line, | |
and finally the debug message, if any. e.g. | |
22158 8 DSDL__init:75: Log initialized | |
22158 539684 SDL_HapticOpenFromJoystick_REAL:451: | |
22158 539696 SDL_SYS_HapticOpenFromJoystick:598: | |
If the log file does not exist, it is likely that your version of SDL2 is not being used. | |
You can check this by launching DiRT 2.0, then switching to a terminal: | |
# Get the PID of dirtrally2 | |
jdinalt@Ix:~/dev/SDL2-2.0.10$ ps -e | grep dirtrally2.exe | |
9463 ? 00:00:33 dirtrally2.exe | |
# See of it is using your SDL2 library | |
jdinalt@Ix:~/dev/SDL2-2.0.10$ lsof -p 9463 | grep SDL2 | |
dirtrally 9463 jdinalt mem REG 253,0 8292456 13503150 /home/jdinalt/dev/SDL2-2.0.10/build/.libs/libSDL2-2.0.so.0.10.0 | |
# Note: switching to a terminal usually causes DiRT to hang for me; you can use | |
# the script below to kill it and cleanup if this happens. Otherwise, you can | |
# ssh into your machine from a laptop, which is safer. | |
If you find that SDL2 points to the Steam version of the lib, check the install | |
instructions for the patch and try again. | |
If the correct version of SDL is linked in and the log does not exist, you may | |
be missing a dependency. Follow the instructions for getting a DOS prompt in | |
your DiRT sandbox below. If winebus is failing to start, debug from there. | |
Assuming you are getting log output, there should be a continuous stream of | |
update and run messages: | |
22158 1867905 SDL_SYS_HapticUpdateEffect:1073: Update, haptic=0x7fa020001fe0, effect=0x7d663850, type=0x52 FF_CONSTANT, id=0, dir=16384, len=0, del=0str=0, alen0, alev=0, flen=0, flev=0 | |
22158 1867949 SDL_SYS_HapticRunEffect:1099: Run: id=0, itr=1 | |
There will also be a stream of failed attempts to create a "friction" effect, | |
consequent to the Linux Logitech driver missing support; this does not appear to | |
cause any problems, but it is pretty noisy. | |
22158 30300409 SDL_HapticNewEffect_REAL:679: Request for unsupported effect 0x3001 & 0x400 == 0 | |
About 30 seconds in, I see a failed attempt to update the "constant force" | |
effect, with the corrective action being successful. | |
22158 30300356 SDL_SYS_HapticUpdateEffect:1054: Update, haptic=0x7fa020001fe0, effect=0x7d663850, type=0x52 FF_CONSTANT, id=0, dir=16384, len=0, del=0str=0, alen0, alev=0, flen=0, flev=0 | |
22158 30300373 SDL_SYS_HapticUpdateEffect:1056: Update failed Invalid argument | |
22158 30300387 SDL_SYS_HapticUpdateEffect:1059: Retry as id -1 | |
22158 30300390 SDL_SYS_HapticUpdateEffect:1069: retry success, new id = 0 | |
After that, things keep working. If you run the log "in-game," you will see that | |
the "update" calls are changing the strength (str) and direction (dir) of the | |
updates. | |
If you are not seeing this, check your FFB settings. | |
You can also enable Proton debug logging. You should be able to find | |
instructions for this online. | |
------------------------------------------------------------------------------ | |
# Background on initial stepsi 9-7-19: | |
# | |
# Having read through Codemaster's documentation on supporting multiple input | |
# devices, it is suggestive of DiRT 2.0 using the direct HID interface for input | |
# devices. | |
# | |
# DiRT 2.0 documentation: | |
# http://blog.codemasters.com/wp-content/uploads/2019/05/Multi-Input-Device-System-for-DiRT-Rally-2-0-Master.pdf | |
# | |
# HID is short for Human Interface Device and was originally a USB abstraction | |
# for mice and keyboards, but has grown to encompass a much wider swath of input | |
# devices. Essentially, it is a generic hardware abstraction allowing for | |
# enumerating and communicating with hardware. | |
# | |
# Windows provides an HID API for applications, think games, to directly | |
# communicate with these devices, without requiring a specialized kernel driver. | |
# | |
# https://docs.microsoft.com/en-us/windows-hardware/drivers/hid/introduction-to-hid-concepts | |
# | |
# Many games make use of this API, which had previously been an issue for | |
# running windows games under Wine, until support was added to the Linux kernel | |
# for direct HID device access, as well as support having been added to Wine to | |
# map the Windows API to the Linux direct HID kernel driver. | |
# | |
# https://www.kernel.org/doc/html/latest/hid/hidraw.html | |
# https://wiki.winehq.org/Hid | |
# | |
# That DiRT 2.0 supports the Windows HID interface is almost a given and that | |
# this would likely be the preferred method of accessing input devices. | |
# | |
# My initial thoughts were that Linux/Wine HID support has always been a bit | |
# fickle. | |
# | |
# On the Linux side, thee are security concerns with making HID devices | |
# accessible to everyone, as this would make it very easy to snoop a keyboard | |
# for passwords. As to ensure that this is not a security risk, normal users | |
# lack the permissions required to access the HID devices. | |
# | |
# On the Wine side, HID support is still relatively new and is poorly | |
# documented. To make use of HID devices, the "winehid" service must be enabled | |
# and this service depends upon the "winebus" service. | |
# | |
# Observationally, Proton 4.11 now enabled the winebus service by default, but | |
# not the winehid service. | |
# | |
# My thinking was that perhaps the failure was caused by an improperly | |
# configured winehid service in Proton leading to the use of SDL2 as a fallback | |
# for input device support. | |
# | |
# Having explored this further, it looks like even with working HID support, | |
# Proton will try to use the SDL2 interface. My guess is that this was a | |
# decision on the part of Valve, as to avoid having to deal with the raw HID | |
# permissions issues on Linux -- less to go wrong. | |
# | |
# It is less clear if winebus support is required. Prior to Proton 4.11, winebus | |
# was disabled by default in the registry. You could start it manually, but I | |
# had to deal with missing dependencies to get it to work. | |
# | |
# Proton 4.11 starts winebus automatically now, but I don't know if the | |
# dependencies have been fixed. If you see that your winebus is not starting, | |
# see the debug notes below for the issues I encountered and how to fix them. | |
# | |
# Enabling Raw HID support in Proton would probably fix things, but my | |
# workaround appears to be pretty usable. Perhaps something to look into down | |
# the road? | |
# | |
# And back to the raw notes... | |
# --- | |
Debug Notes: | |
# Show info about the G29 | |
dmesg | less | |
... | |
47484.273110] usb 3-3.1: new full-speed USB device number 23 using xhci_hcd | |
[647484.495440] usb 3-3.1: New USB device found, idVendor=046d, idProduct=c294, bcdDevice=13.50 | |
[647484.495442] usb 3-3.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0 | |
[647484.495443] usb 3-3.1: Product: G29 Driving Force Racing Wheel | |
[647484.495444] usb 3-3.1: Manufacturer: Logitech | |
[647484.503101] input: Logitech G29 Driving Force Racing Wheel as /devices/pci0000:00/0000:00:14.0/usb3/3-3/3-3.1/3-3.1:1.0/0003:046D:C294.0012/input/input29 | |
[647484.503401] logitech 0003:046D:C294.0012: input,hidraw0: USB HID v1.00 Gamepad [Logitech G29 Driving Force Racing Wheel] on usb-0000:00:14.0-3.1/input0 | |
[647485.365251] usb 3-3.1: reset full-speed USB device number 23 using xhci_hcd | |
[647485.585407] usb 3-3.1: device firmware changed | |
[647485.585530] usb 3-3.1: USB disconnect, device number 23 | |
[647485.817112] usb 3-3.1: new full-speed USB device number 24 using xhci_hcd | |
[647486.043294] usb 3-3.1: New USB device found, idVendor=046d, idProduct=c24f, bcdDevice=89.00 | |
[647486.043296] usb 3-3.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0 | |
[647486.043297] usb 3-3.1: Product: G29 Driving Force Racing Wheel | |
[647486.043298] usb 3-3.1: Manufacturer: Logitech | |
[647486.052638] input: Logitech G29 Driving Force Racing Wheel as /devices/pci0000:00/0000:00:14.0/usb3/3-3/3-3.1/3-3.1:1.0/0003:046D:C24F.0013/input/input30 | |
[647486.052786] logitech 0003:046D:C24F.0013: input,hidraw0: USB HID v1.11 Joystick [Logitech G29 Driving Force Racing Wheel] on usb-0000:00:14.0-3.1/input0 | |
[647486.052845] logitech 0003:046D:C24F.0013: Force feedback support for Logitech Gaming Wheels | |
# I believe what we /may/ need Direct HID support, which essentially exports raw | |
# HID devices, joysticks and steering-wheels for example, to Windows programs? | |
# Just a guess... | |
# The source for the "hclient.exe" tool, listed in the link above, is here: | |
https://github.com/microsoft/Windows-driver-samples/tree/master/hid/hclient | |
# We are going to need to examine the "Wine" execution environment for the | |
# target steam app-id. | |
# One may launch into a "DOS prompt" for the environment associated with a given | |
# steam app-id with something along the liens of the following command: | |
# | |
# Start command line interface | |
env WINEPREFIX="/home/jdinalt/.local/share/Steam/steamapps/compatdata/690790/pfx" "/home/jdinalt/.local/share/Steam/steamapps/common/Proton 4.2/dist/bin/wine64" cmd | |
# The above is a bit clunky and would require changes for most users, so let's | |
# abstract them into bash functions, with arguments. | |
# Init Proton path variables | |
# usage : lcl_setup_protonenv <proton_version> <steam_app_id> | |
function lcl_setup_protonenv () { | |
local proton_version="$1" | |
local steam_app_id="$2" | |
local steam_apps_pfx="/home/${USER}/.local/share/Steam/steamapps" | |
local proton_pfx="${steam_apps_pfx}/common/Proton ${proton_version}" | |
# Declare path to wine executables | |
LCL_WINE_BIN="${proton_pfx}/dist/bin" | |
# Declare path to steam app prefix | |
LCL_APP_PFX="${steam_apps_pfx}/compatdata/${steam_app_id}/pfx" | |
echo "LCL_WINE_BIN=${LCL_WINE_BIN}" | |
echo "LCL_APP_PFX=${LCL_APP_PFX}" | |
} | |
# usage: lcl_wine [arg1...N] | |
function lcl_wine () { | |
local proton_version="$1" | |
shift | |
local steam_app_id="$1" | |
shift | |
declare LCL_WINE_BIN | |
declare LCL_APP_PFX | |
lcl_setup_protonenv "${proton_version}" "${steam_app_id}" | |
# Setup local WINEPREFIX | |
declare -x WINEPREFIX="${LCL_APP_PFX}" | |
# Start Wine with whatever args were passed in | |
"${LCL_WINE_BIN}/wine64" ${@} | |
} | |
# Wine may leave "services" running, even though the environment is not in use. | |
# You can kill all processes for a given app-id with this: | |
function lcl_wine_kill () { | |
local proton_version="$1" | |
shift | |
local steam_app_id="$1" | |
shift | |
declare LCL_WINE_BIN | |
declare LCL_APP_PFX | |
lcl_setup_protonenv "${proton_version}" "${steam_app_id}" | |
# Setup local WINEPREFIX | |
declare -x WINEPREFIX="${LCL_APP_PFX}" | |
# Kill wine server | |
"${LCL_WINE_BIN}/wineserver" -k | |
# Wait for termination | |
"${LCL_WINE_BIN}/wineserver" -w | |
} | |
# One can now start a command-line for DiRT 2.0, Proton 4.11, with the | |
# following: | |
lcl_wine 4.11 690790 cmd | |
# And kill everything running under this instance with | |
lcl_wine_kill 4.11 690790 | |
# HID devices are exported by the 'winebus' service, so let's try and start | |
# that... | |
# With "cmd" running, let's try to start the "winebus" service. | |
Z:\home\jdinalt\.local\share\Steam>net start winebus | |
# We are missing a required shared library | |
The Platform Bus Kernel service is starting. | |
0029:err:module:load_builtin_dll failed to load .so lib for builtin L"winebus.sys": libudev.so.0: cannot open shared object file: No such file or directory | |
0029:err:ntoskrnl:ZwLoadDriver failed to create driver L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\WineBus": c0000142 | |
002b:err:service:process_send_command service protocol error - failed to write pipe! | |
DLL initialization failed. | |
# Get the missing shared lib and install it | |
wget http://mirrors.kernel.org/ubuntu/pool/main/u/udev/libudev0_175-0ubuntu9_amd64.deb | |
sudo dpkg -i libudev0_175-0ubuntu9_amd64.deb | |
# Now we can start the winebus service | |
Z:\home\jdinalt\.local\share\Steam>net start winebus | |
The Platform Bus Kernel service is starting. | |
0048:err:plugplay:sdl_driver_init SDL installation is old! Please upgrade to >=2.0.6 to get accurate joystick information. | |
The Platform Bus Kernel service was started successfully. | |
# Now Wine is complaining about an out-of-date version of libsdl2... | |
# The above message originates from this patch, which is Proton specific. | |
#https://git.froggi.es/tkg/PKGBUILDS/commit/1760ad9f1cd6b27f9fa1ba290042f0ceedc65860?expanded=1&view=parallel | |
# If not already configured to do so, the winebus service can be configured to | |
# start automatically with a change to the registery. -- You can run "regedit" | |
#[System\\CurrentControlSet\\Services\\WineBus] "Start"=dword:00000002 | |
# Looks like my distribution needs a newer version of libsdl2. Having checked, | |
# it looks like version 2.0.8 IS available and we only need 2.0.6, so... | |
sudo apt-get install libsdl2-2.0-0 | |
Reading package lists... Done | |
Building dependency tree | |
Reading state information... Done | |
Selected version '2.0.8+dfsg1-1ubuntu1.18.04.3' (Ubuntu:18.04/bionic-updates [amd64]) for 'libsdl2-2.0-0' | |
... | |
# Having updated to a more current version of SDL 2.0, I am now seeing this: | |
001f:err:ntoskrnl:IoCreateDriver failed to insert driver L"\\Driver\\WineHID" in tree | |
# A preliminary search suggests that this /may/ not actually represent a real | |
# error, but is an artifact of attempting to load the same driver more than | |
# once. There is a bug and patch, dated 2018-12-28, to address the message. | |
# -- probably not actually required for things to work... | |
# https://bugs.winehq.org/show_bug.cgi?id=45805 | |
jdinalt@Ix:~/.local/share/Steam$ ls -l /dev/*hid* | |
crw------- 1 root root 243, 0 Aug 10 23:03 /dev/hidraw0 | |
crw------- 1 root root 243, 1 Aug 12 11:18 /dev/hidraw1 | |
crw------- 1 root root 243, 10 Aug 10 23:03 /dev/hidraw10 | |
crw------- 1 root root 243, 2 Aug 12 11:18 /dev/hidraw2 | |
crw------- 1 root root 243, 3 Aug 12 11:18 /dev/hidraw3 | |
crw------- 1 root root 243, 4 Aug 10 23:03 /dev/hidraw4 | |
crw------- 1 root root 243, 5 Aug 10 23:03 /dev/hidraw5 | |
crw------- 1 root root 243, 6 Aug 12 11:18 /dev/hidraw6 | |
crw------- 1 root root 243, 7 Aug 12 11:18 /dev/hidraw7 | |
crw------- 1 root root 243, 8 Aug 10 23:03 /dev/hidraw8 | |
crw------- 1 root root 243, 9 Aug 10 23:03 /dev/hidraw9 | |
crw------- 1 root root 10, 239 Aug 10 23:03 /dev/uhid | |
jdinalt@Ix:~/.local/share/Steam$ sudo chmod 666 /dev/*hid* | |
[sudo] password for jdinalt: | |
jdinalt@Ix:~/.local/share/Steam$ ls -l /dev/*hid* | |
crw-rw-rw- 1 root root 243, 0 Aug 10 23:03 /dev/hidraw0 | |
crw-rw-rw- 1 root root 243, 1 Aug 12 11:18 /dev/hidraw1 | |
crw-rw-rw- 1 root root 243, 10 Aug 10 23:03 /dev/hidraw10 | |
crw-rw-rw- 1 root root 243, 2 Aug 12 11:18 /dev/hidraw2 | |
crw-rw-rw- 1 root root 243, 3 Aug 12 11:18 /dev/hidraw3 | |
crw-rw-rw- 1 root root 243, 4 Aug 10 23:03 /dev/hidraw4 | |
crw-rw-rw- 1 root root 243, 5 Aug 10 23:03 /dev/hidraw5 | |
crw-rw-rw- 1 root root 243, 6 Aug 12 11:18 /dev/hidraw6 | |
crw-rw-rw- 1 root root 243, 7 Aug 12 11:18 /dev/hidraw7 | |
crw-rw-rw- 1 root root 243, 8 Aug 10 23:03 /dev/hidraw8 | |
crw-rw-rw- 1 root root 243, 9 Aug 10 23:03 /dev/hidraw9 | |
crw-rw-rw- 1 root root 10, 239 Aug 10 23:03 /dev/uhid | |
# Where HID devices are enumerated | |
/HKEY_LOCAL_MACHINE/System/CurrentControlSet/Enum/... | |
# Auto-start HID services | |
/HKEY_LOCAL_MACHINE/System/CurrentControlSet/Services/WineBus/Start=2 | |
/HKEY_LOCAL_MACHINE/System/CurrentControlSet/Services/WineHID/Start=2 | |
# Updated to Proton 4.11 | |
# The G29 device is no longer showing up as a generic, but as with the | |
# proper "Logitech G29" header in the user interface. | |
# | |
# This provides for reasonably sane defaults, proper PS3/4 button icons, | |
# and the steering control feels much better. Unfortunately, FFB is stil not | |
# working. | |
# Grabbed the latest version of SDL2, version SDL2-2.0.10 | |
# I uninstalled the distribution copy via "apt-get remove," then installed the | |
# fresh-built copy. | |
# | |
# Steam maintains a "runtime" copy of SDL2, which was apparently version 2.0.9 | |
# As a quick hack to force usage of the newer lib, I linked the newer version to | |
# where steam keeps 2.0.0 | |
# Backup original | |
mv /home/jdinalt/.local/share/Steam/ubuntu12_32/steam-runtime/amd64/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.9.0 /home/jdinalt/.local/share/Steam/ubuntu12_32/steam-runtime/amd64/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.9.0.old | |
# Link in 0.10.0 | |
sudo ln /usr/local/lib/libSDL2-2.0.so.0.10.0 /home/jdinalt/.local/share/Steam/ubuntu12_32/steam-runtime/amd64/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.9.0 | |
# Verfied that this version is loaded into Dirt via 'lsof -p <pid> | |
dirtrally 29360 jdinalt mem REG 253,0 8280856 6032246 /home/jdinalt/.local/share/Steam/ubuntu12_32/steam-runtime/amd64/usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.9.0 | |
# While at it, checked to see if we have the regular input device open or the | |
# "raw" hid interace -- it looks like the "normal" device is being used. | |
dirtrally 29360 jdinalt 86u CHR 13,67 0t0 413 /dev/input/event3 | |
dirtrally 29360 jdinalt 87u CHR 13,66 0t0 403 /dev/input/event2 | |
dirtrally 29360 jdinalt 88u CHR 13,66 0t0 403 /dev/input/event2 | |
dirtrally 29360 jdinalt 89u CHR 13,78 0t0 463 /dev/input/event14 | |
# And it is still not doing FFB -- looking at the proton log, there is a stream | |
# of these messages: | |
# ... | |
654279.702:002a:005f:err:dinput:effect_SetParameters SDL_HapticUpdateEffect failed: Haptic: Error updating the effect: Invalid argument | |
654279.712:002a:005f:err:dinput:effect_SetParameters SDL_HapticUpdateEffect failed: Haptic: Error updating the effect: Invalid argument | |
654279.722:002a:005f:err:dinput:effect_SetParameters SDL_HapticUpdateEffect failed: Haptic: Error updating the effect: Invalid argument | |
# The above messages appear to originate from this Proton patch: | |
https://git.froggi.es/tkg/PKGBUILDS/blob/2b563056f83e555bef56616a9a48578b1ea0758c/wine-tkg-git/wine-tkg-patches/proton-sdl-joy.patch | |
+static HRESULT WINAPI effect_SetParameters(IDirectInputEffect *iface, | |
+ const DIEFFECT *effect, DWORD flags) | |
+{ | |
... | |
+ if (This->effect_id >= 0) | |
+ { | |
+ if (SDL_HapticUpdateEffect(This->haptic, This->effect_id, &This->effect) < 0) | |
+ { | |
+ ERR("SDL_HapticUpdateEffect failed: %s\n",SDL_GetError()); | |
+ return E_FAIL; | |
+ } | |
+ | |
+ } | |
# There is obviously more to this message from the SDL lib: | |
src/haptic/linux/SDL_syshaptic.c | |
971 int | |
972 SDL_SYS_HapticUpdateEffect(SDL_Haptic * haptic, | |
973 struct haptic_effect *effect, | |
974 SDL_HapticEffect * data) | |
975 { | |
... | |
984 /* See if it can be uploaded. */ | |
985 if (ioctl(haptic->hwdata->fd, EVIOCSFF, &linux_effect) < 0) { | |
986 return SDL_SetError("Haptic: Error updating the effect: %s", | |
987 strerror(errno)); | |
988 } | |
# This is an error being returned by an ioctl to the "input" driver. | |
# Cross-referencing my kernel version, 4.18, with EVIOCSFF, shows that it is | |
# used in the kernel here: | |
https://elixir.bootlin.com/linux/v4.18/source/drivers/input/evdev.c#L1215 | |
case EVIOC_MASK_SIZE(EVIOCSFF): | |
if (input_ff_effect_from_user(p, size, &effect)) | |
return -EFAULT; | |
error = input_ff_upload(dev, &effect, file); | |
if (error) | |
return error; | |
if (put_user(effect.id, &(((struct ff_effect __user *)p)->id))) | |
return -EFAULT; | |
return 0; | |
} | |
# Given that our error was not EFAULT, we can assume that the EINVAL is from | |
# input_ff_upload() | |
https://elixir.bootlin.com/linux/v4.18/source/drivers/input/ff-core.c#L104 | |
# There are multiple direct return points for EINVAL, e.g. | |
if (effect->type < FF_EFFECT_MIN || effect->type > FF_EFFECT_MAX || | |
!test_bit(effect->type, dev->ffbit)) { | |
dev_dbg(&dev->dev, "invalid or not supported effect type in upload\n"); | |
return -EINVAL; | |
} | |
# The diagnostic messages, printed by "dev_dbg," are disabled by default, but we | |
# can turn them on. See: | |
https://www.kernel.org/doc/html/v4.15/admin-guide/dynamic-debug-howto.html | |
# Enable debug messages for this file | |
sudo bash | |
root@Ix:~# echo -n 'file ff-core.c +p' > /sys/kernel/debug/dynamic_debug/control | |
# Verify dynamic logging is enabled (p = print) | |
cat /sys/kernel/debug/dynamic_debug/control | |
... | |
drivers/input/ff-core.c:253 [input_core]input_ff_flush =p "flushing now\012" | |
drivers/input/ff-core.c:125 [input_core]input_ff_upload =p "invalid or not supported wave form in upload\012" | |
drivers/input/ff-core.c:117 [input_core]input_ff_upload =p "invalid or not supported effect type in upload\012" | |
# After running DiRT 2.0 again, we have this: | |
# KERN_DEBUG = 7 | |
dmesg -l 7 | |
[661653.551200] input input30: flushing now | |
[661704.376274] input input30: flushing now | |
[661704.660265] input input30: flushing now | |
[661705.324270] input input30: flushing now | |
[661705.420434] input input30: flushing now | |
[661705.751860] input input30: flushing now | |
[661706.804259] input input30: flushing now | |
[661707.084250] input input30: flushing now | |
[661707.744271] input input30: flushing now | |
[661707.844385] input input30: flushing now | |
[661710.897260] input input30: flushing now | |
[661711.041512] input input30: flushing now | |
[661711.520835] input input30: flushing now | |
[661711.540240] input input30: flushing now | |
[661731.135559] input input30: flushing now | |
[661731.135562] input input30: flushing now | |
[661824.490862] input input30: flushing now | |
[661824.490864] input input30: flushing now | |
[661826.044298] input input30: flushing now | |
# That's interesting -- we are printing the "flushing now" messages, but we have | |
# not hit either of the two "EINVAL" cases!? | |
# It looks like there are indirect cases of EINVAL, which do not have an | |
# associated message. This implies that the error is neither of the above. So | |
# let's go down the list... | |
https://elixir.bootlin.com/linux/v4.18/source/drivers/input/ff-core.c#L130 | |
ret = compat_effect(ff, effect); | |
https://elixir.bootlin.com/linux/v4.18/source/drivers/input/ff-core.c#L153 | |
ret = check_effect_access(ff, id, file); | |
https://elixir.bootlin.com/linux/v4.18/source/drivers/input/ff-core.c#L159 | |
if (!check_effects_compatible(effect, old)) { | |
ret = -EINVAL; | |
goto out; | |
} | |
https://elixir.bootlin.com/linux/v4.18/source/drivers/input/ff-core.c#L165 | |
ret = ff->upload(dev, effect, old); | |
# That last one is by indirect function pointer -- hopefully not that one! | |
static int compat_effect(struct ff_device *ff, struct ff_effect *effect) | |
... | |
https://elixir.bootlin.com/linux/v4.18/source/drivers/input/ff-core.c#L69 | |
case FF_RUMBLE: | |
if (!test_bit(FF_PERIODIC, ff->ffbit)) | |
return -EINVAL; | |
# This appears to convert FF_RUMBLE to FF_PERIODIC and fails if the later is not | |
# supported by the hardware. | |
# There's this... acceess permissions for effects? Not sure what this is about. | |
/* | |
* Check that the effect_id is a valid effect and whether the user | |
* is the owner | |
*/ | |
static int check_effect_access(struct ff_device *ff, int effect_id, | |
struct file *file) | |
{ | |
if (effect_id < 0 || effect_id >= ff->max_effects || | |
!ff->effect_owners[effect_id]) | |
return -EINVAL; | |
/* | |
* Checks whether 2 effects can be combined together | |
*/ | |
static inline int check_effects_compatible(struct ff_effect *e1, | |
struct ff_effect *e2) | |
{ | |
return e1->type == e2->type && | |
(e1->type != FF_PERIODIC || | |
e1->u.periodic.waveform == e2->u.periodic.waveform); | |
} | |
# The last one, the function pointer to "upload" looks like it goes here: | |
https://elixir.bootlin.com/linux/v4.18/source/drivers/hid/usbhid/hid-pidff.c#L564 | |
# To figure out where that function pointer goes (and to figure out what the | |
# device capabilites are) we will need to go digging around in sysfs.. | |
# Get some info on this device... (path is from dmesg, above) | |
/sys/devices/pci0000:00/0000:00:14.0/usb3/3-3/3-3.1/3-3.1:1.0/0003:046D:C24F.0013/input/input30/device$ ls -l | |
total 0 | |
-rw-rw-r-- 1 root root 4096 Aug 18 16:28 alternate_modes | |
-rw-rw-r-- 1 root root 4096 Aug 18 16:28 combine_pedals | |
-r--r--r-- 1 root root 4096 Aug 18 16:28 country | |
# Uses the logitech HID driver (/drivers/hid/hid-lg*) | |
lrwxrwxrwx 1 root root 0 Aug 18 10:54 driver -> ../../../../../../../../bus/hid/drivers/logitech | |
drwxr-xr-x 3 root root 0 Aug 18 10:54 hidraw | |
drwxr-xr-x 3 root root 0 Aug 18 10:54 input | |
drwxrwxrwx 7 root root 0 Aug 18 10:54 leds | |
-r--r--r-- 1 root root 4096 Aug 18 16:28 modalias | |
drwxr-xr-x 2 root root 0 Aug 18 16:28 power | |
-rw-rw-rw- 1 root root 4096 Aug 18 10:54 range | |
-r--r--r-- 1 root root 4096 Aug 18 16:28 real_id | |
-r--r--r-- 1 root root 4096 Aug 18 16:28 report_descriptor | |
lrwxrwxrwx 1 root root 0 Aug 18 10:54 subsystem -> ../../../../../../../../bus/hid | |
-rw-r--r-- 1 root root 4096 Aug 18 10:54 uevent | |
# Force Feedback capbilities | |
/sys/devices/pci0000:00/0000:00:14.0/usb3/3-3/3-3.1/3-3.1:1.0/0003:046D:C24F.0013/input/input30$ cat capabilities/ff | |
300040000 0 | |
# LED's? I have to have a look... | |
ls -l leds | |
total 0 | |
drwxrwxrwx 3 root root 0 Aug 18 10:54 0003:046D:C24F.0013::RPM1 | |
drwxrwxrwx 3 root root 0 Aug 18 10:54 0003:046D:C24F.0013::RPM2 | |
drwxrwxrwx 3 root root 0 Aug 18 10:54 0003:046D:C24F.0013::RPM3 | |
drwxrwxrwx 3 root root 0 Aug 18 10:54 0003:046D:C24F.0013::RPM4 | |
drwxrwxrwx 3 root root 0 Aug 18 10:54 0003:046D:C24F.0013::RPM5 | |
ls leds/0003\:046D\:C24F.0013\:\:RPM1 | |
brightness device max_brightness power subsystem trigger uevent | |
# Cool! You can turn on the shift LEDs from here! | |
# But, I'm getting off track... | |
echo 1 > leds/0003\:046D\:C24F.0013\:\:RPM1/brightness | |
# Now that's interesting... could always try another mode? | |
cat alternate_modes | |
native: G29 Racing Wheel * | |
DF-EX: Driving Force / Formula EX | |
DFP: Driving Force Pro | |
G25: G25 Racing Wheel | |
DFGT: Driving Force GT | |
G27: G27 Racing Wheel | |
G29: G29 Racing Wheel * | |
# Now about that Logitech driver... what exactly are we doing in there? | |
https://elixir.bootlin.com/linux/v4.18/source/drivers/hid/hid-lg.c#L852 | |
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G29_WHEEL), | |
.driver_data = LG_FF4 }, | |
# The above inicates that our Force Feedback code is here: | |
https://elixir.bootlin.com/linux/v4.18/source/drivers/hid/hid-lg4ff.c | |
# Some definitions, as applies to capabilities in various modes: | |
struct lg4ff_wheel { | |
const u32 product_id; | |
const signed short *ff_effects; | |
const u16 min_range; | |
const u16 max_range; | |
void (*set_range)(struct hid_device *hid, u16 range); | |
}; | |
... | |
static const struct lg4ff_wheel lg4ff_devices[] = { | |
{USB_DEVICE_ID_LOGITECH_WINGMAN_FFG, lg4ff_wheel_effects, 40, 180, NULL}, | |
{USB_DEVICE_ID_LOGITECH_WHEEL, lg4ff_wheel_effects, 40, 270, NULL}, | |
{USB_DEVICE_ID_LOGITECH_MOMO_WHEEL, lg4ff_wheel_effects, 40, 270, NULL}, | |
{USB_DEVICE_ID_LOGITECH_DFP_WHEEL, lg4ff_wheel_effects, 40, 900, lg4ff_set_range_dfp}, | |
{USB_DEVICE_ID_LOGITECH_G25_WHEEL, lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25}, | |
{USB_DEVICE_ID_LOGITECH_DFGT_WHEEL, lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25}, | |
{USB_DEVICE_ID_LOGITECH_G27_WHEEL, lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25}, | |
{USB_DEVICE_ID_LOGITECH_G29_WHEEL, lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25}, | |
{USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2, lg4ff_wheel_effects, 40, 270, NULL}, | |
{USB_DEVICE_ID_LOGITECH_WII_WHEEL, lg4ff_wheel_effects, 40, 270, NULL} | |
}; | |
# Interesting... it looks like the only defined effects are: | |
static const signed short lg4ff_wheel_effects[] = { | |
FF_CONSTANT, | |
FF_AUTOCENTER, | |
-1 | |
}; | |
# Digging around further, I see that the hooks in question are set here: | |
https://elixir.bootlin.com/linux/v4.18/source/drivers/input/ff-memless.c#L541 | |
/** | |
* input_ff_create_memless() - create memoryless force-feedback device | |
* @dev: input device supporting force-feedback | |
* @data: driver-specific data to be passed into @play_effect | |
* @play_effect: driver-specific method for playing FF effect | |
*/ | |
int input_ff_create_memless(struct input_dev *dev, void *data, | |
int (*play_effect)(struct input_dev *, void *, struct ff_effect *)) | |
{ | |
... | |
set_bit(FF_GAIN, dev->ffbit); | |
error = input_ff_create(dev, FF_MEMLESS_EFFECTS); | |
if (error) { | |
kfree(ml); | |
return error; | |
} | |
ff = dev->ff; | |
ff->private = ml; | |
ff->upload = ml_ff_upload; | |
ff->playback = ml_ff_playback; | |
ff->set_gain = ml_ff_set_gain; | |
ff->destroy = ml_ff_destroy; | |
/* we can emulate periodic effects with RUMBLE */ | |
if (test_bit(FF_RUMBLE, ff->ffbit)) { | |
set_bit(FF_PERIODIC, dev->ffbit); | |
set_bit(FF_SINE, dev->ffbit); | |
set_bit(FF_TRIANGLE, dev->ffbit); | |
set_bit(FF_SQUARE, dev->ffbit); | |
} | |
# Without Rumble, it looks like we will not be setting any more capabilities | |
# Grab the definitons for FF_* | |
https://elixir.bootlin.com/linux/v4.18/source/include/uapi/linux/input.h#L465 | |
/* | |
* Force feedback effect types | |
*/ | |
#define FF_RUMBLE 0x50 | |
#define FF_PERIODIC 0x51 | |
#define FF_CONSTANT 0x52 | |
#define FF_SPRING 0x53 | |
#define FF_FRICTION 0x54 | |
#define FF_DAMPER 0x55 | |
#define FF_INERTIA 0x56 | |
#define FF_RAMP 0x57 | |
#define FF_EFFECT_MIN FF_RUMBLE | |
#define FF_EFFECT_MAX FF_RAMP | |
/* | |
* Force feedback periodic effect types | |
*/ | |
#define FF_SQUARE 0x58 | |
#define FF_TRIANGLE 0x59 | |
#define FF_SINE 0x5a | |
#define FF_SAW_UP 0x5b | |
#define FF_SAW_DOWN 0x5c | |
#define FF_CUSTOM 0x5d | |
#define FF_WAVEFORM_MIN FF_SQUARE | |
#define FF_WAVEFORM_MAX FF_CUSTOM | |
/* | |
* Set ff device properties | |
*/ | |
#define FF_GAIN 0x60 | |
#define FF_AUTOCENTER 0x61 | |
# That would make our call to 'upload' look like this: | |
static int ml_ff_upload(struct input_dev *dev, | |
struct ff_effect *effect, struct ff_effect *old) | |
{ | |
struct ml_device *ml = dev->ff->private; | |
struct ml_effect_state *state = &ml->states[effect->id]; | |
spin_lock_irq(&dev->event_lock); | |
if (test_bit(FF_EFFECT_STARTED, &state->flags)) { | |
__clear_bit(FF_EFFECT_PLAYING, &state->flags); | |
state->play_at = jiffies + | |
msecs_to_jiffies(state->effect->replay.delay); | |
state->stop_at = state->play_at + | |
msecs_to_jiffies(state->effect->replay.length); | |
state->adj_at = state->play_at; | |
ml_schedule_timer(ml); | |
} | |
spin_unlock_irq(&dev->event_lock); | |
return 0; | |
} | |
# This can't fail, so this is not the source of our error... but we have more | |
# information now. | |
# | |
# What we can conclude is that SDL should not be requesting anything other than | |
# FF_CONSTANT or FF_AUTOCENTER; otherwise there will be trouble. | |
# | |
# A quick scan of up-steam shows that kernel 5.2, these are still the only | |
# supported FFB effects. | |
# OK... I have instrumented the SDL lib to trace what calls are being made: | |
1 Set autocenter 0 | |
2 New: | |
3 0x52 FF_CONSTANT, id=-1, dir=16384, len=0, del=0 : | |
4 str=3277, alen0, alev=0, flen=0, flev=0 | |
5 Update: | |
6 0x52 FF_CONSTANT, id=0, dir=16384, len=0, del=0 : | |
7 str=0, alen0, alev=0, flen=0, flev=0 | |
8 Run: 0, i=1 | |
9 Update: | |
10 0x52 FF_CONSTANT, id=0, dir=16384, len=0, del=0 : | |
11 str=0, alen0, alev=0, flen=0, flev=0 | |
12 Run: 0, i=1 | |
13 Update: | |
14 0x52 FF_CONSTANT, id=0, dir=16384, len=0, del=0 : | |
15 str=0, alen0, alev=0, flen=0, flev=0 | |
16 Run: 0, i=1 | |
... | |
# This pattern holds, until here: | |
7257 Update: | |
7258 0x52 FF_CONSTANT, id=0, dir=16384, len=0, del=0 : | |
7259 str=0, alen0, alev=0, flen=0, flev=0 | |
7260 Run: 0, i=1 | |
7261 Update: | |
7262 0x52 FF_CONSTANT, id=0, dir=16384, len=0, del=0 : | |
7263 str=0, alen0, alev=0, flen=0, flev=0 | |
7264 Update: | |
7265 0x52 FF_CONSTANT, id=0, dir=16384, len=0, del=0 : | |
7266 str=0, alen0, alev=0, flen=0, flev=0 | |
... | |
# Then the above holds, until here... now we start seeing both positive and | |
# negagive "strength" values being passed in. | |
# I did a brief test-drive, so this makes sense. | |
25672 Update: | |
25673 0x52 FF_CONSTANT, id=0, dir=16384, len=0, del=0 : | |
25674 str=0, alen0, alev=0, flen=0, flev=0 | |
25675 Update: | |
25676 0x52 FF_CONSTANT, id=0, dir=16384, len=0, del=0 : | |
25677 str=46, alen0, alev=0, flen=0, flev=0 | |
25678 Update: | |
25679 0x52 FF_CONSTANT, id=0, dir=16384, len=0, del=0 : | |
25680 str=46, alen0, alev=0, flen=0, flev=0 | |
25681 Update: | |
25682 0x52 FF_CONSTANT, id=0, dir=16384, len=0, del=0 : | |
25683 str=128, alen0, alev=0, flen=0, flev=0 | |
... | |
# And then they return to zero | |
30793 Update: | |
30794 0x52 FF_CONSTANT, id=0, dir=16384, len=0, del=0 : | |
30795 str=-33, alen0, alev=0, flen=0, flev=0 | |
30796 Update: | |
30797 0x52 FF_CONSTANT, id=0, dir=16384, len=0, del=0 : | |
30798 str=0, alen0, alev=0, flen=0, flev=0 | |
New patch, with fix: | |
https://gist.github.com/jdinalt/d9977cd1d7106487736ef0b43f0a427d | |
Trace Log: | |
PID, Time (microseconds), Log Data | |
21195 17 DSDL__init:75: Log initialized | |
21195 859406 SDL_HapticOpenFromJoystick_REAL:451: | |
21195 859411 SDL_SYS_HapticOpenFromJoystick:598: | |
21195 859420 SDL_SYS_HapticOpenFromFD:451: | |
21195 859424 SDL_HapticQuery_REAL:617: | |
21195 859425 SDL_HapticQuery_REAL:622: Supported=0x3001 | |
21254 11 DSDL__init:75: Log initialized | |
21254 862824 SDL_HapticOpenFromJoystick_REAL:451: | |
21254 862829 SDL_SYS_HapticOpenFromJoystick:598: | |
21254 862839 SDL_SYS_HapticOpenFromFD:451: | |
21254 862842 SDL_HapticQuery_REAL:617: | |
21254 862843 SDL_HapticQuery_REAL:622: Supported=0x3001 | |
22070 10 DSDL__init:75: Log initialized | |
22070 826560 SDL_HapticOpenFromJoystick_REAL:451: | |
22070 826565 SDL_SYS_HapticOpenFromJoystick:598: | |
22070 826573 SDL_SYS_HapticOpenFromFD:451: | |
22070 826577 SDL_HapticQuery_REAL:617: | |
22070 826578 SDL_HapticQuery_REAL:622: Supported=0x3001 | |
22130 29 DSDL__init:75: Log initialized | |
22130 858710 SDL_HapticOpenFromJoystick_REAL:451: | |
22130 858715 SDL_SYS_HapticOpenFromJoystick:598: | |
22130 858726 SDL_SYS_HapticOpenFromFD:451: | |
22130 858730 SDL_HapticQuery_REAL:617: | |
22130 858731 SDL_HapticQuery_REAL:622: Supported=0x3001 | |
22158 8 DSDL__init:75: Log initialized | |
22158 539684 SDL_HapticOpenFromJoystick_REAL:451: | |
22158 539696 SDL_SYS_HapticOpenFromJoystick:598: | |
22158 539719 SDL_SYS_HapticOpenFromFD:451: | |
22158 539729 SDL_HapticClose_REAL:520: | |
22158 1828135 SDL_HapticOpenFromJoystick_REAL:451: | |
22158 1828596 SDL_HapticOpenFromJoystick_REAL:451: | |
22158 1828604 SDL_SYS_HapticOpenFromJoystick:598: | |
22158 1828615 SDL_SYS_HapticOpenFromFD:451: | |
22158 1828870 SDL_HapticOpenFromJoystick_REAL:451: | |
22158 1830666 SDL_HapticSetAutocenter_REAL:879: autocenter=0 | |
22158 1830696 SDL_SYS_HapticSetAutocenter:1216: Set autocenter 0, 0 | |
22158 1830784 SDL_SYS_HapticNewEffect:989: | |
Our "constant force" effect is created, with an ID of 0 | |
22158 1830792 SDL_SYS_HapticNewEffect:1017: New haptic=0x7fa020001fe0, effect=0x7d663850, type=0x52 FF_CONSTANT, id=0, dir=16384, len=0, del=0str=3277, alen0, alev=0, flen=0, flev=0 | |
22158 1830807 SDL_HapticNewEffect_REAL:696: effect index=0 | |
Then we see an attempt to create three more effects, which fail -- these are unsupported by the Logitech driver | |
Specifically, they are for: spring, damper, and friction | |
22158 1830816 SDL_HapticNewEffect_REAL:679: Request for unsupported effect 0x3001 & 0x80 == 0 | |
22158 1830825 SDL_HapticNewEffect_REAL:679: Request for unsupported effect 0x3001 & 0x100 == 0 | |
22158 1830833 SDL_HapticNewEffect_REAL:679: Request for unsupported effect 0x3001 & 0x400 == 0 | |
Then we see a constant stream of update/run operation on the constant force effect... | |
22158 1837575 SDL_SYS_HapticUpdateEffect:1073: Update, haptic=0x7fa020001fe0, effect=0x7d663850, type=0x52 FF_CONSTANT, id=0, dir=16384, len=0, del=0str=0, alen0, alev=0, flen=0, flev=0 | |
22158 1837599 SDL_SYS_HapticRunEffect:1099: Run: id=0, itr=1 | |
22158 1837619 SDL_HapticNewEffect_REAL:679: Request for unsupported effect 0x3001 & 0x400 == 0 | |
22158 1847701 SDL_SYS_HapticUpdateEffect:1073: Update, haptic=0x7fa020001fe0, effect=0x7d663850, type=0x52 FF_CONSTANT, id=0, dir=16384, len=0, del=0str=0, alen0, alev=0, flen=0, flev=0 | |
22158 1847723 SDL_SYS_HapticRunEffect:1099: Run: id=0, itr=1 | |
22158 1847736 SDL_HapticNewEffect_REAL:679: Request for unsupported effect 0x3001 & 0x400 == 0 | |
22158 1857810 SDL_SYS_HapticUpdateEffect:1073: Update, haptic=0x7fa020001fe0, effect=0x7d663850, type=0x52 FF_CONSTANT, id=0, dir=16384, len=0, del=0str=0, alen0, alev=0, flen=0, flev=0 | |
22158 1857826 SDL_SYS_HapticRunEffect:1099: Run: id=0, itr=1 | |
22158 1857837 SDL_HapticNewEffect_REAL:679: Request for unsupported effect 0x3001 & 0x400 == 0 | |
22158 1867905 SDL_SYS_HapticUpdateEffect:1073: Update, haptic=0x7fa020001fe0, effect=0x7d663850, type=0x52 FF_CONSTANT, id=0, dir=16384, len=0, del=0str=0, alen0, alev=0, flen=0, flev=0 | |
22158 1867949 SDL_SYS_HapticRunEffect:1099: Run: id=0, itr=1 | |
... | |
The above continues for a fair amount of time, then we suddenly find that our effect is no longer valid. | |
I have not identified any specific trigger for the above change. It's like the effect was just forgotten about by the driver. | |
The "retry" code regenerates the effect and we keep going. | |
Without the retry, the "update" fails and "run" is not called; this pattern repeats until the game is stopped, at | |
which point an attempt is made to delete the effect, which also fails. | |
22158 30300356 SDL_SYS_HapticUpdateEffect:1054: Update, haptic=0x7fa020001fe0, effect=0x7d663850, type=0x52 FF_CONSTANT, id=0, dir=16384, len=0, del=0str=0, alen0, alev=0, flen=0, flev=0 | |
22158 30300373 SDL_SYS_HapticUpdateEffect:1056: Update failed Invalid argument | |
22158 30300387 SDL_SYS_HapticUpdateEffect:1059: Retry as id -1 | |
22158 30300390 SDL_SYS_HapticUpdateEffect:1069: retry success, new id = 0 | |
22158 30300393 SDL_SYS_HapticUpdateEffect:1073: Update, haptic=0x7fa020001fe0, effect=0x7d663850, type=0x52 FF_CONSTANT, id=0, dir=16384, len=0, del=0str=0, alen0, alev=0, flen=0, flev=0 | |
22158 30300397 SDL_SYS_HapticRunEffect:1099: Run: id=0, itr=1 | |
22158 30300409 SDL_HapticNewEffect_REAL:679: Request for unsupported effect 0x3001 & 0x400 == 0 | |
22158 30310509 SDL_SYS_HapticUpdateEffect:1073: Update, haptic=0x7fa020001fe0, effect=0x7d663850, type=0x52 FF_CONSTANT, id=0, dir=16384, len=0, del=0str=0, alen0, alev=0, flen=0, flev=0 | |
22158 30310535 SDL_SYS_HapticRunEffect:1099: Run: id=0, itr=1 | |
22158 30310556 SDL_HapticNewEffect_REAL:679: Request for unsupported effect 0x3001 & 0x400 == 0 | |
22158 30320632 SDL_SYS_HapticUpdateEffect:1073: Update, haptic=0x7fa020001fe0, effect=0x7d663850, type=0x52 FF_CONSTANT, id=0, dir=16384, len=0, del=0str=0, alen0, alev=0, flen=0, flev=0 | |
22158 30320654 SDL_SYS_HapticRunEffect:1099: Run: id=0, itr=1 | |
22158 30320672 SDL_HapticNewEffect_REAL:679: Request for unsupported effect 0x3001 & 0x400 == 0 | |
22158 30330747 SDL_SYS_HapticUpdateEffect:1073: Update, haptic=0x7fa020001fe0, effect=0x7d663850, type=0x52 FF_CONSTANT, id=0, dir=16384, len=0, del=0str=0, alen0, alev=0, flen=0, flev=0 | |
22158 30330767 SDL_SYS_HapticRunEffect:1099: Run: id=0, itr=1 | |
... | |
Then the game is stopped | |
22158 52839073 SDL_SYS_HapticUpdateEffect:1073: Update, haptic=0x7fa020001fe0, effect=0x7d663850, type=0x52 FF_CONSTANT, id=0, dir=16384, len=0, del=0str=0, alen0, alev=0, flen=0, flev=0 | |
22158 52839089 SDL_SYS_HapticRunEffect:1099: Run: id=0, itr=1 | |
22158 52839099 SDL_HapticNewEffect_REAL:679: Request for unsupported effect 0x3001 & 0x400 == 0 | |
22158 52845767 SDL_HapticStopEffect_REAL:773: | |
22158 52845772 SDL_SYS_HapticStopEffect:1124: Stop: 0 | |
22158 52845802 SDL_HapticDestroyEffect_REAL:793: | |
22158 52845805 SDL_SYS_HapticDestroyEffect:1142: Destroy: 0 | |
22158 52845816 SDL_HapticStopEffect_REAL:773: | |
22158 52845821 SDL_HapticStopEffect_REAL:775: Invalid effect -1 | |
22158 52845827 SDL_HapticStopEffect_REAL:773: | |
22158 52845830 SDL_HapticStopEffect_REAL:775: Invalid effect -1 | |
22158 52845835 SDL_HapticStopEffect_REAL:773: | |
22158 52845837 SDL_HapticStopEffect_REAL:775: Invalid effect -1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment