Skip to content

Instantly share code, notes, and snippets.

@jdinalt
Created September 5, 2019 18:58
Show Gist options
  • Save jdinalt/0616d7b4c4f509a443e85ecee201e12f to your computer and use it in GitHub Desktop.
Save jdinalt/0616d7b4c4f509a443e85ecee201e12f to your computer and use it in GitHub Desktop.
SDL2 Patch to fix FFB on DiRT Rally 2.0 on Linux
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
@@ -974,6 +974,7 @@
SDL_HapticEffect * data)
{
struct ff_effect linux_effect;
+ int retry_count = 0;
/* Create the new effect */
if (SDL_SYS_ToFFEffect(&linux_effect, data) != 0) {
@@ -981,10 +982,29 @@
}
linux_effect.id = effect->hweffect->effect.id;
+retry:
/* See if it can be uploaded. */
if (ioctl(haptic->hwdata->fd, EVIOCSFF, &linux_effect) < 0) {
- return SDL_SetError("Haptic: Error updating the effect: %s",
- strerror(errno));
+ int err = errno;
+ char const * err_str = strerror(err);
+
+ /*
+ * For some strange and inexplicable reason, the kernel driver appears
+ * to "forget" about our effect for... "reasons."
+ *
+ * The only difference between creating a "new" effect and "updating" an
+ * effect, in the kernel API, is the use of the effect id of "-1" to
+ * request a new id.
+ *
+ * If we get EINVAL, try to reinitialize the effect by setting the index
+ * back to -1, but don't retry more than once. EINVAL is pretty vague
+ * and there could be other causes.
+ */
+ if ((err == EINVAL) && (retry_count++ == 0)) {
+ linux_effect.id = -1;
+ goto retry;
+ }
+ return SDL_SetError("Haptic: Error updating the effect: %s", err_str);
}
/* Copy the new effect into memory. */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment