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 247797f75ea43a93
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
     1.1 --- a/include/SDL_haptic.h	Mon Jun 23 09:01:58 2008 +0000
     1.2 +++ b/include/SDL_haptic.h	Mon Jun 30 16:48:16 2008 +0000
     1.3 @@ -57,6 +57,20 @@
     1.4  #define SDL_HAPTIC_GAIN       (1<<8)
     1.5  #define SDL_HAPTIC_AUTOCENTER (1<<9)
     1.6  
     1.7 +typedef struct SDL_HapticConstant {
     1.8 +   /* Header */
     1.9 +   Uint16 type;
    1.10 +   Uint16 length;
    1.11 +   Uint16 delay;
    1.12 +   Uint16 direction;
    1.13 +} SDL_HapticConstant;
    1.14 +
    1.15 +typedef union SDL_HapticEffect {
    1.16 +   /* Common for all force feedback effects */
    1.17 +   Uint16 type; /* Effect type */
    1.18 +   SDL_HapticConstant constant; /* Constant effect */
    1.19 +} SDL_HapticEffect;
    1.20 +
    1.21  
    1.22  /* Function prototypes */
    1.23  /*
    1.24 @@ -85,6 +99,21 @@
    1.25   */
    1.26  extern DECLSPEC void SDL_HapticClose(SDL_Haptic * haptic);
    1.27  
    1.28 +/*
    1.29 + * Creates a new haptic effect on the device.
    1.30 + */
    1.31 +extern DECLSPEC int SDL_HapticNewEffect(SDL_Haptic * haptic, SDL_HapticEffect * effect);
    1.32 +
    1.33 +/*
    1.34 + * Runs the haptic effect on it's assosciated haptic device.
    1.35 + */
    1.36 +extern DECLSPEC int SDL_HapticRunEffect(SDL_Haptic * haptic, int effect);
    1.37 +
    1.38 +/*
    1.39 + * Destroys a haptic effect on the device.
    1.40 + */
    1.41 +extern DECLSPEC void SDL_HapticDestroyEffect(SDL_Haptic * haptic, int effect);
    1.42 +
    1.43  
    1.44  /* Ends C function definitions when using C++ */
    1.45  #ifdef __cplusplus
     2.1 --- a/src/haptic/SDL_haptic.c	Mon Jun 23 09:01:58 2008 +0000
     2.2 +++ b/src/haptic/SDL_haptic.c	Mon Jun 30 16:48:16 2008 +0000
     2.3 @@ -97,7 +97,7 @@
     2.4     }
     2.5  
     2.6     /* If the haptic is already open, return it */
     2.7 -   for (i = 0; SDL_haptics[i]; ++i) {             
     2.8 +   for (i=0; SDL_haptics[i]; i++) {             
     2.9        if (device_index == SDL_haptics[i]->index) {
    2.10           haptic = SDL_haptics[i];
    2.11           ++haptic->ref_count;
    2.12 @@ -105,23 +105,27 @@
    2.13        }
    2.14     }
    2.15  
    2.16 -   /* Create and initialize the haptic */
    2.17 +   /* Create the haptic device */
    2.18     haptic = (SDL_Haptic *) SDL_malloc((sizeof *haptic));
    2.19 -   if (haptic != NULL) {
    2.20 -      SDL_memset(haptic, 0, (sizeof *haptic));
    2.21 -      haptic->index = device_index;
    2.22 -      if (SDL_SYS_HapticOpen(haptic) < 0) {
    2.23 -         SDL_free(haptic);
    2.24 -         haptic = NULL;
    2.25 -      }
    2.26 +   if (haptic == NULL) {
    2.27 +      SDL_OutOfMemory();
    2.28 +      return NULL;
    2.29     }
    2.30 -   if (haptic) {
    2.31 -      /* Add haptic to list */
    2.32 -      ++haptic->ref_count;
    2.33 -      for (i = 0; SDL_haptics[i]; ++i)
    2.34 -         /* Skip to next haptic */ ;
    2.35 -      SDL_haptics[i] = haptic;
    2.36 +
    2.37 +   /* Initialize the haptic device */
    2.38 +   SDL_memset(haptic, 0, (sizeof *haptic));
    2.39 +   haptic->index = device_index;
    2.40 +   if (SDL_SYS_HapticOpen(haptic) < 0) {
    2.41 +      SDL_free(haptic);
    2.42 +      return NULL;
    2.43     }
    2.44 +
    2.45 +   /* Add haptic to list */
    2.46 +   ++haptic->ref_count;
    2.47 +   for (i = 0; SDL_haptics[i]; ++i)
    2.48 +      /* Skip to next haptic */ ;
    2.49 +   SDL_haptics[i] = haptic;
    2.50 +
    2.51     return haptic;
    2.52  }
    2.53  
    2.54 @@ -192,3 +196,57 @@
    2.55        SDL_haptics = NULL;
    2.56     }
    2.57  }
    2.58 +
    2.59 +
    2.60 +/*
    2.61 + * Creates a new haptic effect.
    2.62 + */
    2.63 +int
    2.64 +SDL_HapticNewEffect(SDL_Haptic * haptic, SDL_HapticEffect * effect)
    2.65 +{
    2.66 +   int i;
    2.67 +
    2.68 +   /* Check for device validity. */
    2.69 +   if (!ValidHaptic(&haptic)) {
    2.70 +      return -1;
    2.71 +   }
    2.72 +
    2.73 +   /* See if there's a free slot */
    2.74 +   for (i=0; i<haptic->neffects; i++) {
    2.75 +      if (haptic->effects[i].hweffect == NULL) {
    2.76 +
    2.77 +         /* Now let the backend create the real effect */
    2.78 +         if (SDL_SYS_HapticNewEffect(haptic,&haptic->effects[i]) != 0) {
    2.79 +            return -1; /* Backend failed to create effect */
    2.80 +         }
    2.81 +         return i;
    2.82 +      }
    2.83 +   }
    2.84 +
    2.85 +   SDL_SetError("Haptic device has no free space left.");
    2.86 +   return -1;
    2.87 +}
    2.88 +
    2.89 +/*
    2.90 + * Runs the haptic effect on the device.
    2.91 + */
    2.92 +int
    2.93 +SDL_HapticRunEffect(SDL_Haptic * haptic, int effect)
    2.94 +{
    2.95 +   if (!ValidHaptic(&haptic)) {
    2.96 +      return -1;
    2.97 +   }
    2.98 +}
    2.99 +
   2.100 +/*
   2.101 + * Gets rid of a haptic effect.
   2.102 + */
   2.103 +void
   2.104 +SDL_HapticDestroyEffect(SDL_Haptic * haptic, int effect)
   2.105 +{
   2.106 +   if (!ValidHaptic(&haptic)) {
   2.107 +      return;
   2.108 +   }
   2.109 +}
   2.110 +
   2.111 +
     3.1 --- a/src/haptic/SDL_syshaptic.h	Mon Jun 23 09:01:58 2008 +0000
     3.2 +++ b/src/haptic/SDL_syshaptic.h	Mon Jun 30 16:48:16 2008 +0000
     3.3 @@ -25,19 +25,28 @@
     3.4  #include "SDL_haptic.h"
     3.5  
     3.6  
     3.7 +struct haptic_effect
     3.8 +{
     3.9 +   SDL_HapticEffect effect; /* The current event */
    3.10 +   struct haptic_hweffect *hweffect; /* The hardware behind the event */
    3.11 +};
    3.12 +
    3.13 +/*
    3.14 + * The real SDL_Haptic event.
    3.15 + */
    3.16  struct _SDL_Haptic
    3.17  {  
    3.18 -   Uint8 index; /* stores index it is attached to */
    3.19 -   const char* name; /* stores the name of the device */
    3.20 +   Uint8 index; /* Stores index it is attached to */
    3.21 +   const char* name; /* Stores the name of the device */
    3.22  
    3.23 -   int neffects; /* maximum amount of effects */
    3.24 -   unsigned int supported; /* supported effects */
    3.25 +   struct haptic_effect *effects; /* Allocated effects */
    3.26 +   int neffects; /* Maximum amount of effects */
    3.27 +   unsigned int supported; /* Supported effects */
    3.28  
    3.29 -   struct haptic_hwdata *hwdata; /* driver dependent */
    3.30 -   int ref_count; /* count for multiple opens */
    3.31 +   struct haptic_hwdata *hwdata; /* Driver dependent */
    3.32 +   int ref_count; /* Count for multiple opens */
    3.33  };
    3.34  
    3.35 -
    3.36  extern int SDL_SYS_HapticInit(void);
    3.37  extern const char * SDL_SYS_HapticName(int index);
    3.38  extern int SDL_SYS_HapticOpen(SDL_Haptic * haptic);
     4.1 --- a/src/haptic/linux/SDL_syshaptic.c	Mon Jun 23 09:01:58 2008 +0000
     4.2 +++ b/src/haptic/linux/SDL_syshaptic.c	Mon Jun 30 16:48:16 2008 +0000
     4.3 @@ -59,6 +59,15 @@
     4.4  };
     4.5  
     4.6  
     4.7 +/*
     4.8 + * Haptic system effect data.
     4.9 + */
    4.10 +struct haptic_hweffect
    4.11 +{
    4.12 +   int id;
    4.13 +};
    4.14 +
    4.15 +
    4.16  
    4.17  #define test_bit(nr, addr) \
    4.18     (((1UL << ((nr) & 31)) & (((const unsigned int *) addr)[(nr) >> 5])) != 0)
    4.19 @@ -180,29 +189,49 @@
    4.20  int
    4.21  SDL_SYS_HapticOpen(SDL_Haptic * haptic)
    4.22  {
    4.23 +   int i;
    4.24     int fd;
    4.25  
    4.26     /* Open the character device */
    4.27     fd = open(SDL_hapticlist[haptic->index].fname, O_RDWR, 0);
    4.28     if (fd < 0) {
    4.29        SDL_SetError("Unable to open %s\n", SDL_hapticlist[haptic->index]);
    4.30 -      return (-1);
    4.31 +      return -1;
    4.32     }
    4.33  
    4.34     /* Allocate the hwdata */
    4.35     haptic->hwdata = (struct haptic_hwdata *)
    4.36 -      SDL_malloc(sizeof(*haptic->hwdata));
    4.37 +         SDL_malloc(sizeof(*haptic->hwdata));
    4.38     if (haptic->hwdata == NULL) {
    4.39        SDL_OutOfMemory();
    4.40 -      close(fd);
    4.41 -      return (-1);
    4.42 +      goto open_err;
    4.43     }
    4.44     SDL_memset(haptic->hwdata, 0, sizeof(*haptic->hwdata));
    4.45 -
    4.46     /* Set the hwdata */
    4.47     haptic->hwdata->fd = fd;
    4.48  
    4.49 +   /* Set the effects */
    4.50 +   if (ioctl(fd, EVIOCGEFFECTS, &haptic->neffects) < 0) {
    4.51 +      SDL_SetError("Unable to query haptic device memory.");
    4.52 +      goto open_err;
    4.53 +   }
    4.54 +   haptic->effects = (struct haptic_effect *)
    4.55 +         SDL_malloc(sizeof(struct haptic_effect) * haptic->neffects);
    4.56 +   if (haptic->effects == NULL) {
    4.57 +      SDL_OutOfMemory();
    4.58 +      goto open_err;
    4.59 +   }
    4.60 +
    4.61     return 0;
    4.62 +
    4.63 +   /* Error handling */
    4.64 +open_err:
    4.65 +   close(fd);
    4.66 +   if (haptic->hwdata != NULL) {
    4.67 +      free(haptic->hwdata);
    4.68 +      haptic->hwdata = NULL;
    4.69 +   }
    4.70 +   return -1;
    4.71  }
    4.72  
    4.73  
    4.74 @@ -220,12 +249,15 @@
    4.75        /* Free */
    4.76        SDL_free(haptic->hwdata);
    4.77        haptic->hwdata = NULL;
    4.78 -
    4.79 +      SDL_free(haptic->effects);
    4.80 +      haptic->neffects = 0;
    4.81     }
    4.82  }
    4.83  
    4.84  
    4.85 -/* Clean up after system specific haptic stuff */
    4.86 +/* 
    4.87 + * Clean up after system specific haptic stuff
    4.88 + */
    4.89  void
    4.90  SDL_SYS_HapticQuit(void)
    4.91  {
    4.92 @@ -237,5 +269,14 @@
    4.93     SDL_hapticlist[0].fname = NULL;
    4.94  }
    4.95  
    4.96 +/*
    4.97 + * Creates a new haptic effect.
    4.98 + */
    4.99 +int
   4.100 +SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect * effect)
   4.101 +{
   4.102 +   return -1;
   4.103 +}
   4.104 +
   4.105  
   4.106  #endif /* SDL_HAPTIC_LINUX */