Some more error reporting. gsoc2008_force_feedback
authorEdgar Simo <bobbens@gmail.com>
Tue, 01 Jul 2008 09:22:22 +0000
branchgsoc2008_force_feedback
changeset 2480b883974445fc
parent 2479 b9eb2cfe16cd
child 2481 5d0ea4576f20
Some more error reporting.
Added periodic effect.
Confirmed it works.
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 30 21:38:29 2008 +0000
     1.2 +++ b/include/SDL_haptic.h	Tue Jul 01 09:22:22 2008 +0000
     1.3 @@ -60,15 +60,57 @@
     1.4  typedef struct SDL_HapticConstant {
     1.5     /* Header */
     1.6     Uint16 type;
     1.7 +   Uint16 direction;
     1.8 +
     1.9 +   /* Replay */
    1.10     Uint16 length;
    1.11     Uint16 delay;
    1.12 +
    1.13 +   /* Trigger */
    1.14 +   Uint16 button;
    1.15 +   Uint16 interval;
    1.16 +
    1.17 +   /* Constant */
    1.18 +   Sint16 level;
    1.19 +
    1.20 +   /* Envelope */
    1.21 +   Uint16 attack_length;
    1.22 +   Uint16 attack_level;
    1.23 +   Uint16 fade_length;
    1.24 +   Uint16 fade_level;
    1.25 +} SDL_HapticConstant;
    1.26 +typedef struct SDL_HapticPeriodic {
    1.27 +   /* Header */
    1.28 +   Uint16 type;
    1.29     Uint16 direction;
    1.30 -} SDL_HapticConstant;
    1.31 +
    1.32 +   /* Replay */
    1.33 +   Uint16 length;
    1.34 +   Uint16 delay;
    1.35 +
    1.36 +   /* Trigger */
    1.37 +   Uint16 button;
    1.38 +   Uint16 interval;
    1.39 +
    1.40 +   /* Periodic */
    1.41 +   Uint16 waveform;
    1.42 +   Uint16 period;
    1.43 +   Sint16 magnitude;
    1.44 +   Sint16 offset;
    1.45 +   Uint16 phase;
    1.46 +
    1.47 +   /* Envelope */
    1.48 +   Uint16 attack_length;
    1.49 +   Uint16 attack_level;
    1.50 +   Uint16 fade_length;
    1.51 +   Uint16 fade_level;
    1.52 +} SDL_HapticPeriodic;
    1.53  
    1.54  typedef union SDL_HapticEffect {
    1.55     /* Common for all force feedback effects */
    1.56     Uint16 type; /* Effect type */
    1.57     SDL_HapticConstant constant; /* Constant effect */
    1.58 +   SDL_HapticPeriodic periodic; /* Periodic effect */
    1.59  } SDL_HapticEffect;
    1.60  
    1.61  
     2.1 --- a/src/haptic/SDL_haptic.c	Mon Jun 30 21:38:29 2008 +0000
     2.2 +++ b/src/haptic/SDL_haptic.c	Tue Jul 01 09:22:22 2008 +0000
     2.3 @@ -166,7 +166,12 @@
     2.4        return;
     2.5     }
     2.6  
     2.7 -   /* Close it */
     2.8 +   /* Close it, properly removing effects if needed */
     2.9 +   for (i=0; i<haptic->neffects; i++) {
    2.10 +      if (haptic->effects[i].hweffect != NULL) {
    2.11 +         SDL_HapticDestroyEffect(haptic,i);
    2.12 +      }
    2.13 +   }
    2.14     SDL_SYS_HapticClose(haptic);
    2.15  
    2.16     /* Remove from the list */
    2.17 @@ -248,12 +253,18 @@
    2.18        return -1;
    2.19     }
    2.20  
    2.21 +   /* Check to see if effect is supported */
    2.22 +   if (SDL_HapticEffectSupported(haptic,effect)==SDL_FALSE) {
    2.23 +      SDL_SetError("Haptic effect not supported by haptic device.");
    2.24 +      return -1;
    2.25 +   }
    2.26 +
    2.27     /* See if there's a free slot */
    2.28     for (i=0; i<haptic->neffects; i++) {
    2.29        if (haptic->effects[i].hweffect == NULL) {
    2.30  
    2.31           /* Now let the backend create the real effect */
    2.32 -         if (SDL_SYS_HapticNewEffect(haptic,&haptic->effects[i]) != 0) {
    2.33 +         if (SDL_SYS_HapticNewEffect(haptic,&haptic->effects[i],effect) != 0) {
    2.34              return -1; /* Backend failed to create effect */
    2.35           }
    2.36           return i;
    2.37 @@ -265,12 +276,25 @@
    2.38  }
    2.39  
    2.40  /*
    2.41 + * Checks to see if an effect is valid.
    2.42 + */
    2.43 +static int
    2.44 +ValidEffect(SDL_Haptic * haptic, int effect)
    2.45 +{
    2.46 +   if ((effect < 0) || (effect >= haptic->neffects)) {
    2.47 +      SDL_SetError("Invalid haptic effect identifier.");
    2.48 +      return 0;
    2.49 +   }
    2.50 +   return 1;
    2.51 +}
    2.52 +
    2.53 +/*
    2.54   * Runs the haptic effect on the device.
    2.55   */
    2.56  int
    2.57  SDL_HapticRunEffect(SDL_Haptic * haptic, int effect)
    2.58  {
    2.59 -   if (!ValidHaptic(&haptic)) {
    2.60 +   if (!ValidHaptic(&haptic) || !ValidEffect(haptic,effect)) {
    2.61        return -1;
    2.62     }
    2.63  
    2.64 @@ -288,7 +312,7 @@
    2.65  void
    2.66  SDL_HapticDestroyEffect(SDL_Haptic * haptic, int effect)
    2.67  {
    2.68 -   if (!ValidHaptic(&haptic)) {
    2.69 +   if (!ValidHaptic(&haptic) || !ValidEffect(haptic,effect)) {
    2.70        return;
    2.71     }
    2.72  
     3.1 --- a/src/haptic/SDL_syshaptic.h	Mon Jun 30 21:38:29 2008 +0000
     3.2 +++ b/src/haptic/SDL_syshaptic.h	Tue Jul 01 09:22:22 2008 +0000
     3.3 @@ -53,7 +53,7 @@
     3.4  extern void SDL_SYS_HapticClose(SDL_Haptic * haptic);
     3.5  extern void SDL_SYS_HapticQuit(void);
     3.6  extern int SDL_SYS_HapticNewEffect(SDL_Haptic * haptic,
     3.7 -      struct haptic_effect * effect);
     3.8 +      struct haptic_effect * effect, SDL_HapticEffect * base);
     3.9  extern int SDL_SYS_HapticRunEffect(SDL_Haptic * haptic,
    3.10        struct haptic_effect * effect);
    3.11  extern void SDL_SYS_HapticDestroyEffect(SDL_Haptic * haptic,
     4.1 --- a/src/haptic/linux/SDL_syshaptic.c	Mon Jun 30 21:38:29 2008 +0000
     4.2 +++ b/src/haptic/linux/SDL_syshaptic.c	Tue Jul 01 09:22:22 2008 +0000
     4.3 @@ -35,6 +35,7 @@
     4.4  #include <fcntl.h>
     4.5  #include <linux/limits.h>
     4.6  #include <string.h>
     4.7 +#include <errno.h>
     4.8  
     4.9  
    4.10  #define MAX_HAPTICS  32
    4.11 @@ -274,12 +275,68 @@
    4.12   * Initializes the linux effect struct from a haptic_effect.
    4.13   */
    4.14  static int
    4.15 -SDL_SYS_ToFFEffect( struct ff_effect * dest, struct haptic_effect * src )
    4.16 +SDL_SYS_ToFFEffect( struct ff_effect * dest, SDL_HapticEffect * src )
    4.17  {
    4.18 +   SDL_HapticConstant *constant;
    4.19 +   SDL_HapticPeriodic *periodic;
    4.20 +
    4.21 +   /* Clear up */
    4.22     SDL_memset(dest, 0, sizeof(struct ff_effect));
    4.23 -   switch (src->effect.type) {
    4.24 +
    4.25 +   switch (src->type) {
    4.26        case SDL_HAPTIC_CONSTANT:
    4.27 +         constant = &src->constant;
    4.28 +
    4.29 +         /* Header */
    4.30           dest->type = FF_CONSTANT;
    4.31 +         dest->direction = constant->direction;
    4.32 +
    4.33 +         /* Replay */
    4.34 +         dest->replay.length = constant->length;
    4.35 +         dest->replay.delay = constant->delay;
    4.36 +
    4.37 +         /* Trigger */
    4.38 +         dest->trigger.button = constant->button;
    4.39 +         dest->trigger.interval = constant->interval;
    4.40 +
    4.41 +         /* Constant */
    4.42 +         dest->u.constant.level = constant->level;
    4.43 +
    4.44 +         /* Envelope */
    4.45 +         dest->u.constant.envelope.attack_length = constant->attack_length;
    4.46 +         dest->u.constant.envelope.attack_level = constant->attack_level;
    4.47 +         dest->u.constant.envelope.fade_length = constant->fade_length;
    4.48 +         dest->u.constant.envelope.fade_level = constant->fade_level;
    4.49 +
    4.50 +         break;
    4.51 +
    4.52 +      case SDL_HAPTIC_PERIODIC:
    4.53 +         periodic = &src->periodic;
    4.54 +
    4.55 +         /* Header */
    4.56 +         dest->type = FF_PERIODIC;
    4.57 +         dest->direction = periodic->direction;
    4.58 +         
    4.59 +         /* Replay */
    4.60 +         dest->replay.length = periodic->length;
    4.61 +         dest->replay.delay = periodic->delay;
    4.62 +         
    4.63 +         /* Trigger */
    4.64 +         dest->trigger.button = periodic->button;
    4.65 +         dest->trigger.interval = periodic->interval;
    4.66 +         
    4.67 +         /* Constant */
    4.68 +         dest->u.periodic.waveform = periodic->waveform;
    4.69 +         dest->u.periodic.period = periodic->period;
    4.70 +         dest->u.periodic.magnitude = periodic->magnitude;
    4.71 +         dest->u.periodic.offset = periodic->offset;
    4.72 +         dest->u.periodic.phase = periodic->phase;
    4.73 +         
    4.74 +         /* Envelope */
    4.75 +         dest->u.periodic.envelope.attack_length = periodic->attack_length;
    4.76 +         dest->u.periodic.envelope.attack_level = periodic->attack_level;
    4.77 +         dest->u.periodic.envelope.fade_length = periodic->fade_length;
    4.78 +         dest->u.periodic.envelope.fade_level = periodic->fade_level;
    4.79  
    4.80           break;
    4.81  
    4.82 @@ -295,8 +352,11 @@
    4.83   * Creates a new haptic effect.
    4.84   */
    4.85  int
    4.86 -SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect * effect)
    4.87 +SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect * effect,
    4.88 +      SDL_HapticEffect * base)
    4.89  {
    4.90 +   struct ff_effect * linux_effect;
    4.91 +
    4.92     /* Allocate the hardware effect */
    4.93     effect->hweffect = (struct haptic_hweffect *) 
    4.94           SDL_malloc(sizeof(struct haptic_hweffect));
    4.95 @@ -306,14 +366,16 @@
    4.96     }
    4.97  
    4.98     /* Prepare the ff_effect */
    4.99 -   if (SDL_SYS_ToFFEffect( &effect->hweffect->effect, effect ) != 0) {
   4.100 +   linux_effect = &effect->hweffect->effect;
   4.101 +   if (SDL_SYS_ToFFEffect( linux_effect, base ) != 0) {
   4.102        return -1;
   4.103     }
   4.104 -   effect->hweffect->effect.id = -1; /* Have the kernel give it an id */
   4.105 +   linux_effect->id = -1; /* Have the kernel give it an id */
   4.106  
   4.107     /* Upload the effect */
   4.108 -   if (ioctl(haptic->hwdata->fd, EVIOCSFF, &effect->hweffect->effect) < 0) {
   4.109 -      SDL_SetError("Error uploading effect to the haptic device.");
   4.110 +   if (ioctl(haptic->hwdata->fd, EVIOCSFF, linux_effect) < 0) {
   4.111 +      SDL_SetError("Error uploading effect to the haptic device: %s",
   4.112 +            strerror(errno));
   4.113        return -1;
   4.114     }
   4.115