Skip to content

Instantly share code, notes, and snippets.

@jdinalt
Last active September 7, 2019 21:49
Show Gist options
  • Save jdinalt/278d752ab3c898090b109b2297d82379 to your computer and use it in GitHub Desktop.
Save jdinalt/278d752ab3c898090b109b2297d82379 to your computer and use it in GitHub Desktop.
Debug Notes for Broken FFB on DiRT Rally 2.0, Linux
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