Added SDL_HapticUpdateEffect(). gsoc2008_force_feedback
authorEdgar Simo <bobbens@gmail.com>
Tue, 01 Jul 2008 18:35:05 +0000
branchgsoc2008_force_feedback
changeset 2488 8e2bdbccf7ff
parent 2487 4c8e25ef2d97
child 2489 96adc8025331
Added SDL_HapticUpdateEffect().
include/SDL_haptic.h
src/haptic/SDL_haptic.c
src/haptic/SDL_syshaptic.h
src/haptic/linux/SDL_syshaptic.c
--- a/include/SDL_haptic.h	Tue Jul 01 16:42:12 2008 +0000
+++ b/include/SDL_haptic.h	Tue Jul 01 18:35:05 2008 +0000
@@ -241,6 +241,16 @@
 extern DECLSPEC int SDL_HapticNewEffect(SDL_Haptic * haptic, SDL_HapticEffect * effect);
 
 /*
+ * Uploads an effect.  Can be used dynamically, although behaviour when
+ * dynamically changing direction may be strange.  Specifically the effect
+ * may reupload itself and start playing from the start.  You cannot change
+ * the type either when running UpdateEffect.
+ *
+ * Returns the id of the effect on success, -1 on failure.
+ */
+extern DECLSPEC int SDL_HapticUpdateEffect(SDL_Haptic * haptic, int effect, SDL_HapticEffect * data);
+
+/*
  * Runs the haptic effect on it's assosciated haptic device.
  *
  * Returns 0 on success or -1 on failure.
--- a/src/haptic/SDL_haptic.c	Tue Jul 01 16:42:12 2008 +0000
+++ b/src/haptic/SDL_haptic.c	Tue Jul 01 18:35:05 2008 +0000
@@ -292,6 +292,25 @@
 }
 
 /*
+ * Updates an effect.
+ */
+int
+SDL_HapticUpdateEffect(SDL_Haptic * haptic, int effect, SDL_HapticEffect * data)
+{
+   if (!ValidHaptic(&haptic) || !ValidEffect(haptic,effect)) {
+      return -1;
+   }
+
+   /* Updates the effect */
+   if (SDL_SYS_HapticUpdateEffect(haptic,&haptic->effects[effect],data) < 0) {
+      return -1;
+   }
+
+   return 0;
+}
+
+
+/*
  * Runs the haptic effect on the device.
  */
 int
--- a/src/haptic/SDL_syshaptic.h	Tue Jul 01 16:42:12 2008 +0000
+++ b/src/haptic/SDL_syshaptic.h	Tue Jul 01 18:35:05 2008 +0000
@@ -54,6 +54,8 @@
 extern void SDL_SYS_HapticQuit(void);
 extern int SDL_SYS_HapticNewEffect(SDL_Haptic * haptic,
       struct haptic_effect * effect, SDL_HapticEffect * base);
+extern int SDL_SYS_HapticUpdateEffect(SDL_Haptic * haptic,
+      struct haptic_effect * effect, SDL_HapticEffect * data);
 extern int SDL_SYS_HapticRunEffect(SDL_Haptic * haptic,
       struct haptic_effect * effect);
 extern int SDL_SYS_HapticStopEffect(SDL_Haptic * haptic,
--- a/src/haptic/linux/SDL_syshaptic.c	Tue Jul 01 16:42:12 2008 +0000
+++ b/src/haptic/linux/SDL_syshaptic.c	Tue Jul 01 18:35:05 2008 +0000
@@ -456,17 +456,52 @@
    /* Prepare the ff_effect */
    linux_effect = &effect->hweffect->effect;
    if (SDL_SYS_ToFFEffect( linux_effect, base ) != 0) {
-      return -1;
+      goto new_effect_err;
    }
    linux_effect->id = -1; /* Have the kernel give it an id */
 
    /* Upload the effect */
    if (ioctl(haptic->hwdata->fd, EVIOCSFF, linux_effect) < 0) {
       SDL_SetError("Error uploading effect to the haptic device.");
+      goto new_effect_err;
+   }
+
+   return 0;
+
+new_effect_err:
+   free(effect->hweffect);
+   effect->hweffect = NULL;
+   return -1;
+}
+
+
+/*
+ * Updates an effect.
+ *
+ * Note: Dynamically updating the direction can in some cases force
+ * the effect to restart and run once.
+ */
+int SDL_SYS_HapticUpdateEffect(SDL_Haptic * haptic,
+      struct haptic_effect * effect, SDL_HapticEffect * data)
+{
+   struct ff_effect linux_effect;
+
+   /* Create the new effect */
+   if (SDL_SYS_ToFFEffect( &linux_effect, data ) != 0) {
+      return -1;
+   }
+   linux_effect.id = effect->hweffect->effect.id;
+
+   /* See if it can be uploaded. */
+   if (ioctl(haptic->hwdata->fd, EVIOCSFF, &linux_effect) < 0) {
+      SDL_SetError("Error updating the haptic effect.");
       return -1;
    }
 
-   return 0;
+   /* Copy the new effect into memory. */
+   SDL_memcpy( &effect->hweffect->effect, &linux_effect, sizeof(struct ff_effect) );
+
+   return effect->hweffect->effect.id;
 }