Haptic subsystem handles haptic axes now. gsoc2008_force_feedback
authorEdgar Simo <bobbens@gmail.com>
Thu, 17 Jul 2008 11:47:48 +0000
branchgsoc2008_force_feedback
changeset 2523366d84fdf8d1
parent 2522 0877146be013
child 2524 1a55848ce198
Haptic subsystem handles haptic axes now.
Support for SDL_HAPTIC_SPHERICAL on linux.
More error checking.
Improved documentation.
Added missing SDLCALLs to SDL_haptic.h.
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	Tue Jul 15 17:35:06 2008 +0000
     1.2 +++ b/include/SDL_haptic.h	Thu Jul 17 11:47:48 2008 +0000
     1.3 @@ -292,36 +292,37 @@
     1.4   * Directions can be specified by:
     1.5   *   - SDL_HAPTIC_POLAR : Specified by polar coordinates.
     1.6   *   - SDL_HAPTIC_CARTESIAN : Specified by cartesian coordinates.
     1.7 + *   - SDL_HAPTIC_SHPERICAL : Specified by spherical coordinates.
     1.8   *
     1.9   * Cardinal directions of the haptic device are relative to the positioning
    1.10   *  of the device.  North is considered to be away from the user.
    1.11   *
    1.12   * The following diagram represents the cardinal directions:
    1.13   * \code
    1.14 - *            .--.
    1.15 - *            |__| .-------.
    1.16 - *            |=.| |.-----.|
    1.17 - *            |--| ||     ||
    1.18 - *            |  | |'-----'|
    1.19 - *            |__|~')_____('
    1.20 - *              [ COMPUTER ]
    1.21 + *              .--.
    1.22 + *              |__| .-------.
    1.23 + *              |=.| |.-----.|
    1.24 + *              |--| ||     ||
    1.25 + *              |  | |'-----'|
    1.26 + *              |__|~')_____('
    1.27 + *                [ COMPUTER ]
    1.28   *
    1.29   *
    1.30 - *                  North (-1)
    1.31 - *                    ^
    1.32 - *                    |
    1.33 - *                    |
    1.34 - * (1)  West <----[ HAPTIC ]----> East (-1)
    1.35 - *                    |
    1.36 - *                    |
    1.37 - *                    v
    1.38 - *                  South (1)
    1.39 + *                  North (0,-1)
    1.40 + *                      ^
    1.41 + *                      |
    1.42 + *                      |
    1.43 + * (1,0)  West <----[ HAPTIC ]----> East (-1,0)
    1.44 + *                      |
    1.45 + *                      |
    1.46 + *                      v
    1.47 + *                   South (0,1)
    1.48   *
    1.49   *
    1.50 - *                 [ USER ]
    1.51 - *                   \|||/
    1.52 - *                   (o o)
    1.53 - *             ---ooO-(_)-Ooo---
    1.54 + *                   [ USER ]
    1.55 + *                     \|||/
    1.56 + *                     (o o)
    1.57 + *               ---ooO-(_)-Ooo---
    1.58   * \endcode
    1.59   *
    1.60   * If type is SDL_HAPTIC_POLAR, direction is encoded by hundredths of a 
    1.61 @@ -332,35 +333,49 @@
    1.62   *   - South: 18000 (180 degrees)
    1.63   *   - West: 27000 (270 degrees)
    1.64   *
    1.65 - * If type is SDL_HAPTIC_CARTESIAN, direction is encoded by two positions
    1.66 - *  (X axis and Y axis).  SDL_HAPTIC_CARTESIAN uses the first two dir 
    1.67 - *  parameters.  The cardinal directions would be:
    1.68 - *   - North:  0,-1
    1.69 - *   - East:  -1, 0
    1.70 - *   - South:  0, 1
    1.71 - *   - West:   1, 0
    1.72 + * If type is SDL_HAPTIC_CARTESIAN, direction is encoded by three positions
    1.73 + *  (X axis, Y axis and Z axis (with 3 axes)).  SDL_HAPTIC_CARTESIAN uses
    1.74 + *  the first three dir parameters.  The cardinal directions would be:
    1.75 + *   - North:  0,-1, 0
    1.76 + *   - East:  -1, 0, 0
    1.77 + *   - South:  0, 1, 0
    1.78 + *   - West:   1, 0, 0
    1.79 + *  The Z axis represents the height of the effect if supported, otherwise
    1.80 + *  it's unused.  In cartesian encoding (1,2) would be the same as (2,4), you
    1.81 + *  can use any multiple you want, only the direction matters.
    1.82   *
    1.83 - * If type is SDL_HAPTIC_SPHERICAL, direction is encoded by three rotations.
    1.84 - *  All three dir parameters are used.  The dir parameters are as follows
    1.85 + * If type is SDL_HAPTIC_SPHERICAL, direction is encoded by two rotations.
    1.86 + *  The first two  dir parameters are used.  The dir parameters are as follows
    1.87   *  (all values are in hundredths of degrees):
    1.88   *    1) Degrees from (1, 0) rotated towards (0, 1).
    1.89   *    2) Degrees towards (0, 0, 1) (device needs at least 3 axes).
    1.90 - *    3) Degrees tworads (0, 0, 0, 1) (device needs at least 4 axes).
    1.91   *
    1.92   *
    1.93 - * Example:
    1.94 + * Example of force coming from the south with all encodings (force coming
    1.95 + *  from the south means the user will have to pull the stick to counteract):
    1.96   * \code
    1.97   * SDL_HapticDirection direction;
    1.98   *
    1.99 + * // Cartesian directions
   1.100 + * direction.type = SDL_HAPTIC_CARTESIAN; // Using cartesian direction encoding.
   1.101 + * direction.dir[0] = 0; // X position
   1.102 + * direction.dir[1] = 1; // Y position
   1.103 + * // Assuming the device has 2 axes, we don't need to specify third parameter.
   1.104 + *
   1.105 + * // Polar directions
   1.106   * direction.type = SDL_HAPTIC_POLAR; // We'll be using polar direction encoding.
   1.107 - * direction.dir = 18000; // Force comes from the south meaning the user will
   1.108 - *                         // have to pull the stick to counteract.
   1.109 + * direction.dir[0] = 18000; // Polar only uses first parameter
   1.110 + *
   1.111 + * // Spherical coordinates
   1.112 + * direction.type = SDL_HAPTIC_SPHERICAL; // Spherical encoding
   1.113 + * direction.dir[0] = 9000; // Since we only have two axes we don't need more parameters.
   1.114   * \endcode
   1.115   *
   1.116   * \sa SDL_HAPTIC_POLAR
   1.117   * \sa SDL_HAPTIC_CARTESIAN
   1.118   * \sa SDL_HAPTIC_SHPERICAL
   1.119   * \sa SDL_HapticEffect
   1.120 + * \sa SDL_HapticNumAxes
   1.121   */
   1.122  typedef struct SDL_HapticDirection {
   1.123     Uint8 type; /**< The type of encoding. */
   1.124 @@ -510,6 +525,7 @@
   1.125     /* Header */
   1.126     Uint16 type; /**< SDL_HAPTIC_SPRING, SDL_HAPTIC_DAMPER,
   1.127                       SDL_HAPTIC_INERTIA or SDL_HAPTIC_FRICTION */
   1.128 +   SDL_HapticDirection direction; /**< Direction of the effect - Not used ATM. */
   1.129  
   1.130     /* Replay */
   1.131     Uint32 length; /**< Duration of the effect. */
   1.132 @@ -679,7 +695,7 @@
   1.133   * \sa SDL_HapticSetGain
   1.134   * \sa SDL_HapticSetAutocenter
   1.135   */
   1.136 -extern DECLSPEC SDL_Haptic * SDL_HapticOpen(int device_index);
   1.137 +extern DECLSPEC SDL_Haptic *SDLCALL SDL_HapticOpen(int device_index);
   1.138  
   1.139  /**
   1.140   * \fn int SDL_HapticOpened(int device_index)
   1.141 @@ -692,7 +708,7 @@
   1.142   * \sa SDL_HapticOpen
   1.143   * \sa SDL_HapticIndex
   1.144   */
   1.145 -extern DECLSPEC int SDL_HapticOpened(int device_index);
   1.146 +extern DECLSPEC int SDLCALL SDL_HapticOpened(int device_index);
   1.147  
   1.148  /**
   1.149   * \fn int SDL_HapticIndex(SDL_Haptic * haptic)
   1.150 @@ -705,7 +721,7 @@
   1.151   * \sa SDL_HapticOpen
   1.152   * \sa SDL_HapticOpened
   1.153   */
   1.154 -extern DECLSPEC int SDL_HapticIndex(SDL_Haptic * haptic);
   1.155 +extern DECLSPEC int SDLCALL SDL_HapticIndex(SDL_Haptic * haptic);
   1.156  
   1.157  /**
   1.158   * \fn int SDL_MouseIsHaptic(void)
   1.159 @@ -716,7 +732,7 @@
   1.160   *
   1.161   * \sa SDL_HapticOpenFromMouse
   1.162   */
   1.163 -extern DECLSPEC int SDL_MouseIsHaptic(void);
   1.164 +extern DECLSPEC int SDLCALL SDL_MouseIsHaptic(void);
   1.165  
   1.166  /**
   1.167   * \fn SDL_Haptic * SDL_HapticOpenFromMouse(void)
   1.168 @@ -728,7 +744,7 @@
   1.169   * \sa SDL_MouseIsHaptic
   1.170   * \sa SDL_HapticOpen
   1.171   */
   1.172 -extern DECLSPEC SDL_Haptic * SDL_HapticOpenFromMouse(void);
   1.173 +extern DECLSPEC SDL_Haptic *SDLCALL SDL_HapticOpenFromMouse(void);
   1.174  
   1.175  /**
   1.176   * \fn int SDL_JoystickIsHaptic(SDL_Joystick * joystick)
   1.177 @@ -741,7 +757,7 @@
   1.178   *
   1.179   * \sa SDL_HapticOpenFromJoystick
   1.180   */
   1.181 -extern DECLSPEC int SDL_JoystickIsHaptic(SDL_Joystick * joystick);
   1.182 +extern DECLSPEC int SDLCALL SDL_JoystickIsHaptic(SDL_Joystick * joystick);
   1.183  
   1.184  /**
   1.185   * \fn SDL_Haptic * SDL_HapticOpenFromJoystick(SDL_Joystick * joystick)
   1.186 @@ -755,7 +771,7 @@
   1.187   * \sa SDL_HapticOpen
   1.188   * \sa SDL_HapticClose
   1.189   */
   1.190 -extern DECLSPEC SDL_Haptic * SDL_HapticOpenFromJoystick(SDL_Joystick * joystick);
   1.191 +extern DECLSPEC SDL_Haptic *SDLCALL SDL_HapticOpenFromJoystick(SDL_Joystick * joystick);
   1.192  
   1.193  /**
   1.194   * \fn void SDL_HapticClose(SDL_Haptic * haptic)
   1.195 @@ -764,7 +780,7 @@
   1.196   *
   1.197   *    \param haptic Haptic device to close.
   1.198   */
   1.199 -extern DECLSPEC void SDL_HapticClose(SDL_Haptic * haptic);
   1.200 +extern DECLSPEC void SDLCALL SDL_HapticClose(SDL_Haptic * haptic);
   1.201  
   1.202  /**
   1.203   * \fn int SDL_HapticNumEffects(SDL_Haptic * haptic)
   1.204 @@ -778,7 +794,7 @@
   1.205   * \sa SDL_HapticNumEffectsPlaying
   1.206   * \sa SDL_HapticQuery
   1.207   */
   1.208 -extern DECLSPEC int SDL_HapticNumEffects(SDL_Haptic * haptic);
   1.209 +extern DECLSPEC int SDLCALL SDL_HapticNumEffects(SDL_Haptic * haptic);
   1.210  
   1.211  /**
   1.212   * \fn int SDL_HapticNumEffectsPlaying(SDL_Haptic * haptic)
   1.213 @@ -792,7 +808,7 @@
   1.214   * \sa SDL_HapticNumEffects
   1.215   * \sa SDL_HapticQuery
   1.216   */
   1.217 -extern DECLSPEC int SDL_HapticNumEffectsPlaying(SDL_Haptic * haptic);
   1.218 +extern DECLSPEC int SDLCALL SDL_HapticNumEffectsPlaying(SDL_Haptic * haptic);
   1.219  
   1.220  /**
   1.221   * \fn unsigned int SDL_HapticQuery(SDL_Haptic * haptic)
   1.222 @@ -813,7 +829,17 @@
   1.223   * \sa SDL_HapticNumEffects
   1.224   * \sa SDL_HapticEffectSupported
   1.225   */
   1.226 -extern DECLSPEC unsigned int SDL_HapticQuery(SDL_Haptic * haptic);
   1.227 +extern DECLSPEC unsigned int SDLCALL SDL_HapticQuery(SDL_Haptic * haptic);
   1.228 +
   1.229 +
   1.230 +/**
   1.231 + * \fn int SDL_HapticNumAxes(SDL_Haptic * haptic)
   1.232 + *
   1.233 + * \brief Gets the number of haptic axes the device has.
   1.234 + *
   1.235 + * \sa SDL_HapticDirection
   1.236 + */
   1.237 +extern DECLSPEC int SDLCALL SDL_HapticNumAxes(SDL_Haptic * haptic);
   1.238  
   1.239  /**
   1.240   * \fn int SDL_HapticEffectSupported(SDL_Haptic * haptic, SDL_HapticEffect * effect)
   1.241 @@ -828,7 +854,7 @@
   1.242   * \sa SDL_HapticQuery
   1.243   * \sa SDL_HapticNewEffect
   1.244   */
   1.245 -extern DECLSPEC int SDL_HapticEffectSupported(SDL_Haptic * haptic, SDL_HapticEffect * effect);
   1.246 +extern DECLSPEC int SDLCALL SDL_HapticEffectSupported(SDL_Haptic * haptic, SDL_HapticEffect * effect);
   1.247  
   1.248  /**
   1.249   * \fn int SDL_HapticNewEffect(SDL_Haptic * haptic, SDL_HapticEffect * effect)
   1.250 @@ -843,7 +869,7 @@
   1.251   * \sa SDL_HapticRunEffect
   1.252   * \sa SDL_HapticDestroyEffect
   1.253   */
   1.254 -extern DECLSPEC int SDL_HapticNewEffect(SDL_Haptic * haptic, SDL_HapticEffect * effect);
   1.255 +extern DECLSPEC int SDLCALL SDL_HapticNewEffect(SDL_Haptic * haptic, SDL_HapticEffect * effect);
   1.256  
   1.257  /**
   1.258   * \fn int SDL_HapticUpdateEffect(SDL_Haptic * haptic, int effect, SDL_HapticEffect * data)
   1.259 @@ -862,7 +888,7 @@
   1.260   * \sa SDL_HapticRunEffect
   1.261   * \sa SDL_HapticDestroyEffect
   1.262   */
   1.263 -extern DECLSPEC int SDL_HapticUpdateEffect(SDL_Haptic * haptic, int effect, SDL_HapticEffect * data);
   1.264 +extern DECLSPEC int SDLCALL SDL_HapticUpdateEffect(SDL_Haptic * haptic, int effect, SDL_HapticEffect * data);
   1.265  
   1.266  /**
   1.267   * \fn int SDL_HapticRunEffect(SDL_Haptic * haptic, int effect, int iterations)
   1.268 @@ -879,7 +905,7 @@
   1.269   * \sa SDL_HapticDestroyEffect
   1.270   * \sa SDL_HapticGetEffectStatus
   1.271   */
   1.272 -extern DECLSPEC int SDL_HapticRunEffect(SDL_Haptic * haptic, int effect, Uint32 iterations);
   1.273 +extern DECLSPEC int SDLCALL SDL_HapticRunEffect(SDL_Haptic * haptic, int effect, Uint32 iterations);
   1.274  
   1.275  /**
   1.276   * \fn int SDL_HapticStopEffect(SDL_Haptic * haptic, int effect)
   1.277 @@ -893,7 +919,7 @@
   1.278   * \sa SDL_HapticRunEffect
   1.279   * \sa SDL_HapticDestroyEffect
   1.280   */
   1.281 -extern DECLSPEC int SDL_HapticStopEffect(SDL_Haptic * haptic, int effect);
   1.282 +extern DECLSPEC int SDLCALL SDL_HapticStopEffect(SDL_Haptic * haptic, int effect);
   1.283  
   1.284  /**
   1.285   * \fn void SDL_HapticDestroyEffect(SDL_Haptic * haptic, int effect)
   1.286 @@ -907,7 +933,7 @@
   1.287   * 
   1.288   * \sa SDL_HapticNewEffect
   1.289   */
   1.290 -extern DECLSPEC void SDL_HapticDestroyEffect(SDL_Haptic * haptic, int effect);
   1.291 +extern DECLSPEC void SDLCALL SDL_HapticDestroyEffect(SDL_Haptic * haptic, int effect);
   1.292  
   1.293  /**
   1.294   * \fn int SDL_HapticGetEffectStatus(SDL_Haptic *haptic, int effect)
   1.295 @@ -924,7 +950,7 @@
   1.296   * \sa SDL_HapticRunEffect
   1.297   * \sa SDL_HapticStopEffect
   1.298   */
   1.299 -extern DECLSPEC int SDL_HapticGetEffectStatus(SDL_Haptic *haptic, int effect);
   1.300 +extern DECLSPEC int SDLCALL SDL_HapticGetEffectStatus(SDL_Haptic *haptic, int effect);
   1.301  
   1.302  /**
   1.303   * \fn int SDL_HapticSetGain(SDL_Haptic * haptic, int gain)
   1.304 @@ -944,7 +970,7 @@
   1.305   *
   1.306   * \sa SDL_HapticQuery
   1.307   */
   1.308 -extern DECLSPEC int SDL_HapticSetGain(SDL_Haptic * haptic, int gain);
   1.309 +extern DECLSPEC int SDLCALL SDL_HapticSetGain(SDL_Haptic * haptic, int gain);
   1.310  
   1.311  /**
   1.312   * \fn int SDL_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter)
   1.313 @@ -960,7 +986,7 @@
   1.314   *
   1.315   * \sa SDL_HapticQuery
   1.316   */
   1.317 -extern DECLSPEC int SDL_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter);
   1.318 +extern DECLSPEC int SDLCALL SDL_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter);
   1.319  
   1.320  
   1.321  /* Ends C function definitions when using C++ */
     2.1 --- a/src/haptic/SDL_haptic.c	Tue Jul 15 17:35:06 2008 +0000
     2.2 +++ b/src/haptic/SDL_haptic.c	Thu Jul 17 11:47:48 2008 +0000
     2.3 @@ -384,6 +384,20 @@
     2.4     return haptic->supported;
     2.5  }
     2.6  
     2.7 +
     2.8 +/*
     2.9 + * Returns the number of axis on the device.
    2.10 + */
    2.11 +int
    2.12 +SDL_HapticNumAxes(SDL_Haptic * haptic)
    2.13 +{
    2.14 +   if (!ValidHaptic(&haptic)) {
    2.15 +      return -1;
    2.16 +   }
    2.17 +
    2.18 +   return haptic->naxes;
    2.19 +}
    2.20 +
    2.21  /*
    2.22   * Checks to see if the device can support the effect.
    2.23   */
     3.1 --- a/src/haptic/SDL_syshaptic.h	Tue Jul 15 17:35:06 2008 +0000
     3.2 +++ b/src/haptic/SDL_syshaptic.h	Thu Jul 17 11:47:48 2008 +0000
     3.3 @@ -49,6 +49,7 @@
     3.4     int neffects; /* Maximum amount of effects */
     3.5     int nplaying; /* Maximum amount of effects to play at the same time */
     3.6     unsigned int supported; /* Supported effects */
     3.7 +   int naxes; /* Number of axes on the device. */
     3.8  
     3.9     struct haptic_hwdata *hwdata; /* Driver dependent */
    3.10     int ref_count; /* Count for multiple opens */
     4.1 --- a/src/haptic/linux/SDL_syshaptic.c	Tue Jul 15 17:35:06 2008 +0000
     4.2 +++ b/src/haptic/linux/SDL_syshaptic.c	Thu Jul 17 11:47:48 2008 +0000
     4.3 @@ -255,6 +255,7 @@
     4.4     /* Set the data */
     4.5     haptic->hwdata->fd = fd;
     4.6     haptic->supported = EV_IsHaptic(fd);
     4.7 +   haptic->naxes = 2; /* Hardcoded for now, not sure if it's possible to find out. */
     4.8  
     4.9     /* Set the effects */
    4.10     if (ioctl(fd, EVIOCGEFFECTS, &haptic->neffects) < 0) {
    4.11 @@ -419,6 +420,7 @@
    4.12           /* Linux directions are inverted. */
    4.13           tmp = (((18000 + dir->dir[0]) % 36000) * 0xFFFF) / 36000;
    4.14           return (Uint16) tmp;
    4.15 +
    4.16        case SDL_HAPTIC_CARTESIAN:
    4.17           /* We must invert "x" and "y" to go clockwise. */
    4.18           f = atan2(dir->dir[0], dir->dir[1]);
    4.19 @@ -426,7 +428,13 @@
    4.20           tmp = (tmp * 0xFFFF) / 36000;
    4.21           return (Uint16) tmp;
    4.22  
    4.23 +      case SDL_HAPTIC_SPHERICAL:
    4.24 +         tmp = (36000 - dir->dir[0]) + 27000; /* Convert to polars */
    4.25 +         tmp = (((18000 + tmp) % 36000) * 0xFFFF) / 36000;
    4.26 +         return (Uint16) tmp;
    4.27 +
    4.28        default:
    4.29 +         SDL_SetError("Haptic: Unsupported direction type.");
    4.30           return -1;
    4.31     }
    4.32  
    4.33 @@ -456,6 +464,7 @@
    4.34           /* Header */
    4.35           dest->type = FF_CONSTANT;
    4.36           dest->direction = SDL_SYS_ToDirection(&constant->direction);
    4.37 +         if (dest->direction < 0) return -1;
    4.38  
    4.39           /* Replay */
    4.40           dest->replay.length = CLAMP(constant->length);
    4.41 @@ -486,6 +495,7 @@
    4.42           /* Header */
    4.43           dest->type = FF_PERIODIC;
    4.44           dest->direction = SDL_SYS_ToDirection(&periodic->direction);
    4.45 +         if (dest->direction < 0) return -1;
    4.46           
    4.47           /* Replay */
    4.48           dest->replay.length = CLAMP(periodic->length);
    4.49 @@ -568,6 +578,7 @@
    4.50           /* Header */
    4.51           dest->type = FF_RAMP;
    4.52           dest->direction = SDL_SYS_ToDirection(&ramp->direction);
    4.53 +         if (dest->direction < 0) return -1;
    4.54  
    4.55           /* Replay */
    4.56           dest->replay.length = CLAMP(ramp->length);