Starting to add infrastructure to handle haptic effects. gsoc2008_force_feedback
authorEdgar Simo <bobbens@gmail.com>
Mon, 30 Jun 2008 16:48:16 +0000
branchgsoc2008_force_feedback
changeset 2477 97f75ea43a93
parent 2476 242d8a668ebb
child 2478 4fd783e0f34b
Starting to add infrastructure to handle haptic effects.
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	Mon Jun 23 09:01:58 2008 +0000
+++ b/include/SDL_haptic.h	Mon Jun 30 16:48:16 2008 +0000
@@ -57,6 +57,20 @@
 #define SDL_HAPTIC_GAIN       (1<<8)
 #define SDL_HAPTIC_AUTOCENTER (1<<9)
 
+typedef struct SDL_HapticConstant {
+   /* Header */
+   Uint16 type;
+   Uint16 length;
+   Uint16 delay;
+   Uint16 direction;
+} SDL_HapticConstant;
+
+typedef union SDL_HapticEffect {
+   /* Common for all force feedback effects */
+   Uint16 type; /* Effect type */
+   SDL_HapticConstant constant; /* Constant effect */
+} SDL_HapticEffect;
+
 
 /* Function prototypes */
 /*
@@ -85,6 +99,21 @@
  */
 extern DECLSPEC void SDL_HapticClose(SDL_Haptic * haptic);
 
+/*
+ * Creates a new haptic effect on the device.
+ */
+extern DECLSPEC int SDL_HapticNewEffect(SDL_Haptic * haptic, SDL_HapticEffect * effect);
+
+/*
+ * Runs the haptic effect on it's assosciated haptic device.
+ */
+extern DECLSPEC int SDL_HapticRunEffect(SDL_Haptic * haptic, int effect);
+
+/*
+ * Destroys a haptic effect on the device.
+ */
+extern DECLSPEC void SDL_HapticDestroyEffect(SDL_Haptic * haptic, int effect);
+
 
 /* Ends C function definitions when using C++ */
 #ifdef __cplusplus
--- a/src/haptic/SDL_haptic.c	Mon Jun 23 09:01:58 2008 +0000
+++ b/src/haptic/SDL_haptic.c	Mon Jun 30 16:48:16 2008 +0000
@@ -97,7 +97,7 @@
    }
 
    /* If the haptic is already open, return it */
-   for (i = 0; SDL_haptics[i]; ++i) {             
+   for (i=0; SDL_haptics[i]; i++) {             
       if (device_index == SDL_haptics[i]->index) {
          haptic = SDL_haptics[i];
          ++haptic->ref_count;
@@ -105,23 +105,27 @@
       }
    }
 
-   /* Create and initialize the haptic */
+   /* Create the haptic device */
    haptic = (SDL_Haptic *) SDL_malloc((sizeof *haptic));
-   if (haptic != NULL) {
-      SDL_memset(haptic, 0, (sizeof *haptic));
-      haptic->index = device_index;
-      if (SDL_SYS_HapticOpen(haptic) < 0) {
-         SDL_free(haptic);
-         haptic = NULL;
-      }
+   if (haptic == NULL) {
+      SDL_OutOfMemory();
+      return NULL;
    }
-   if (haptic) {
-      /* Add haptic to list */
-      ++haptic->ref_count;
-      for (i = 0; SDL_haptics[i]; ++i)
-         /* Skip to next haptic */ ;
-      SDL_haptics[i] = haptic;
+
+   /* Initialize the haptic device */
+   SDL_memset(haptic, 0, (sizeof *haptic));
+   haptic->index = device_index;
+   if (SDL_SYS_HapticOpen(haptic) < 0) {
+      SDL_free(haptic);
+      return NULL;
    }
+
+   /* Add haptic to list */
+   ++haptic->ref_count;
+   for (i = 0; SDL_haptics[i]; ++i)
+      /* Skip to next haptic */ ;
+   SDL_haptics[i] = haptic;
+
    return haptic;
 }
 
@@ -192,3 +196,57 @@
       SDL_haptics = NULL;
    }
 }
+
+
+/*
+ * Creates a new haptic effect.
+ */
+int
+SDL_HapticNewEffect(SDL_Haptic * haptic, SDL_HapticEffect * effect)
+{
+   int i;
+
+   /* Check for device validity. */
+   if (!ValidHaptic(&haptic)) {
+      return -1;
+   }
+
+   /* See if there's a free slot */
+   for (i=0; i<haptic->neffects; i++) {
+      if (haptic->effects[i].hweffect == NULL) {
+
+         /* Now let the backend create the real effect */
+         if (SDL_SYS_HapticNewEffect(haptic,&haptic->effects[i]) != 0) {
+            return -1; /* Backend failed to create effect */
+         }
+         return i;
+      }
+   }
+
+   SDL_SetError("Haptic device has no free space left.");
+   return -1;
+}
+
+/*
+ * Runs the haptic effect on the device.
+ */
+int
+SDL_HapticRunEffect(SDL_Haptic * haptic, int effect)
+{
+   if (!ValidHaptic(&haptic)) {
+      return -1;
+   }
+}
+
+/*
+ * Gets rid of a haptic effect.
+ */
+void
+SDL_HapticDestroyEffect(SDL_Haptic * haptic, int effect)
+{
+   if (!ValidHaptic(&haptic)) {
+      return;
+   }
+}
+
+
--- a/src/haptic/SDL_syshaptic.h	Mon Jun 23 09:01:58 2008 +0000
+++ b/src/haptic/SDL_syshaptic.h	Mon Jun 30 16:48:16 2008 +0000
@@ -25,19 +25,28 @@
 #include "SDL_haptic.h"
 
 
+struct haptic_effect
+{
+   SDL_HapticEffect effect; /* The current event */
+   struct haptic_hweffect *hweffect; /* The hardware behind the event */
+};
+
+/*
+ * The real SDL_Haptic event.
+ */
 struct _SDL_Haptic
 {  
-   Uint8 index; /* stores index it is attached to */
-   const char* name; /* stores the name of the device */
+   Uint8 index; /* Stores index it is attached to */
+   const char* name; /* Stores the name of the device */
 
-   int neffects; /* maximum amount of effects */
-   unsigned int supported; /* supported effects */
+   struct haptic_effect *effects; /* Allocated effects */
+   int neffects; /* Maximum amount of effects */
+   unsigned int supported; /* Supported effects */
 
-   struct haptic_hwdata *hwdata; /* driver dependent */
-   int ref_count; /* count for multiple opens */
+   struct haptic_hwdata *hwdata; /* Driver dependent */
+   int ref_count; /* Count for multiple opens */
 };
 
-
 extern int SDL_SYS_HapticInit(void);
 extern const char * SDL_SYS_HapticName(int index);
 extern int SDL_SYS_HapticOpen(SDL_Haptic * haptic);
--- a/src/haptic/linux/SDL_syshaptic.c	Mon Jun 23 09:01:58 2008 +0000
+++ b/src/haptic/linux/SDL_syshaptic.c	Mon Jun 30 16:48:16 2008 +0000
@@ -59,6 +59,15 @@
 };
 
 
+/*
+ * Haptic system effect data.
+ */
+struct haptic_hweffect
+{
+   int id;
+};
+
+
 
 #define test_bit(nr, addr) \
    (((1UL << ((nr) & 31)) & (((const unsigned int *) addr)[(nr) >> 5])) != 0)
@@ -180,29 +189,49 @@
 int
 SDL_SYS_HapticOpen(SDL_Haptic * haptic)
 {
+   int i;
    int fd;
 
    /* Open the character device */
    fd = open(SDL_hapticlist[haptic->index].fname, O_RDWR, 0);
    if (fd < 0) {
       SDL_SetError("Unable to open %s\n", SDL_hapticlist[haptic->index]);
-      return (-1);
+      return -1;
    }
 
    /* Allocate the hwdata */
    haptic->hwdata = (struct haptic_hwdata *)
-      SDL_malloc(sizeof(*haptic->hwdata));
+         SDL_malloc(sizeof(*haptic->hwdata));
    if (haptic->hwdata == NULL) {
       SDL_OutOfMemory();
-      close(fd);
-      return (-1);
+      goto open_err;
    }
    SDL_memset(haptic->hwdata, 0, sizeof(*haptic->hwdata));
-
    /* Set the hwdata */
    haptic->hwdata->fd = fd;
 
+   /* Set the effects */
+   if (ioctl(fd, EVIOCGEFFECTS, &haptic->neffects) < 0) {
+      SDL_SetError("Unable to query haptic device memory.");
+      goto open_err;
+   }
+   haptic->effects = (struct haptic_effect *)
+         SDL_malloc(sizeof(struct haptic_effect) * haptic->neffects);
+   if (haptic->effects == NULL) {
+      SDL_OutOfMemory();
+      goto open_err;
+   }
+
    return 0;
+
+   /* Error handling */
+open_err:
+   close(fd);
+   if (haptic->hwdata != NULL) {
+      free(haptic->hwdata);
+      haptic->hwdata = NULL;
+   }
+   return -1;
 }
 
 
@@ -220,12 +249,15 @@
       /* Free */
       SDL_free(haptic->hwdata);
       haptic->hwdata = NULL;
-
+      SDL_free(haptic->effects);
+      haptic->neffects = 0;
    }
 }
 
 
-/* Clean up after system specific haptic stuff */
+/* 
+ * Clean up after system specific haptic stuff
+ */
 void
 SDL_SYS_HapticQuit(void)
 {
@@ -237,5 +269,14 @@
    SDL_hapticlist[0].fname = NULL;
 }
 
+/*
+ * Creates a new haptic effect.
+ */
+int
+SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect * effect)
+{
+   return -1;
+}
+
 
 #endif /* SDL_HAPTIC_LINUX */