changeset 2481:5d0ea4576f20 gsoc2008_force_feedback

More comments. Clamped values in struct ff_effect. Added waveforms.
author Edgar Simo <bobbens@gmail.com>
date Tue, 01 Jul 2008 10:44:42 +0000
parents b883974445fc
children b51ad78812d5
files include/SDL_haptic.h src/haptic/linux/SDL_syshaptic.c
diffstat 2 files changed, 80 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/include/SDL_haptic.h	Tue Jul 01 09:22:22 2008 +0000
+++ b/include/SDL_haptic.h	Tue Jul 01 10:44:42 2008 +0000
@@ -57,9 +57,38 @@
 #define SDL_HAPTIC_GAIN       (1<<8)
 #define SDL_HAPTIC_AUTOCENTER (1<<9)
 
+typedef enum SDL_waveform {
+   SDL_WAVEFORM_SINE,
+   SDL_WAVEFORM_SQUARE,
+   SDL_WAVEFORM_TRIANGLE,
+   SDL_WAVEFORM_SAWTOOTHUP,
+   SDL_WAVEFORM_SAWTOOTHDOWN
+} SDL_waveform;
+
+
+/*
+ * All values max at 32767 (0x7fff).  Signed values also can be negative.
+ * Time values unless specified otherwise are in milliseconds.
+ *
+ * Common parts:
+ * 
+ * Replay:
+ *    Uint16 length;    Duration of effect.
+ *    Uint16 delay;     Delay before starting effect.
+ *
+ * Trigger:
+ *    Uint16 button;    Button that triggers effect.
+ *    Uint16 interval;  How soon before effect can be triggered again.
+ *
+ * Envelope:
+ *    Uint16 attack_length;   Duration of the attack.
+ *    Uint16 attack_level;    Level at the start of the attack.
+ *    Uint16 fade_length;     Duration of the fade out.
+ *    Uint16 fade_level;      Level at the end of the fade.
+ */
 typedef struct SDL_HapticConstant {
    /* Header */
-   Uint16 type;
+   Uint16 type; /* SDL_HAPTIC_CONSTANT */
    Uint16 direction;
 
    /* Replay */
@@ -71,7 +100,7 @@
    Uint16 interval;
 
    /* Constant */
-   Sint16 level;
+   Sint16 level; /* Strength of the constant effect. */
 
    /* Envelope */
    Uint16 attack_length;
@@ -81,7 +110,7 @@
 } SDL_HapticConstant;
 typedef struct SDL_HapticPeriodic {
    /* Header */
-   Uint16 type;
+   Uint16 type; /* SDL_HAPTIC_PERIODIC */
    Uint16 direction;
 
    /* Replay */
@@ -93,11 +122,11 @@
    Uint16 interval;
 
    /* Periodic */
-   Uint16 waveform;
-   Uint16 period;
-   Sint16 magnitude;
-   Sint16 offset;
-   Uint16 phase;
+   SDL_waveform waveform; /* Type of effect */
+   Uint16 period; /* Period of the wave */
+   Sint16 magnitude; /* Peak value */
+   Sint16 offset; /* Mean value of the wave */
+   Uint16 phase; /* Horizontal shift */
 
    /* Envelope */
    Uint16 attack_length;
--- a/src/haptic/linux/SDL_syshaptic.c	Tue Jul 01 09:22:22 2008 +0000
+++ b/src/haptic/linux/SDL_syshaptic.c	Tue Jul 01 10:44:42 2008 +0000
@@ -271,8 +271,10 @@
    SDL_hapticlist[0].fname = NULL;
 }
 
+#define  CLAMP(x)    (((x) > 32767) ? 32767 : x)
 /*
  * Initializes the linux effect struct from a haptic_effect.
+ * Values above 32767 (for unsigned) are unspecified so we must clamp.
  */
 static int
 SDL_SYS_ToFFEffect( struct ff_effect * dest, SDL_HapticEffect * src )
@@ -289,24 +291,24 @@
 
          /* Header */
          dest->type = FF_CONSTANT;
-         dest->direction = constant->direction;
+         dest->direction = CLAMP(constant->direction);
 
          /* Replay */
-         dest->replay.length = constant->length;
-         dest->replay.delay = constant->delay;
+         dest->replay.length = CLAMP(constant->length);
+         dest->replay.delay = CLAMP(constant->delay);
 
          /* Trigger */
-         dest->trigger.button = constant->button;
-         dest->trigger.interval = constant->interval;
+         dest->trigger.button = CLAMP(constant->button);
+         dest->trigger.interval = CLAMP(constant->interval);
 
          /* Constant */
          dest->u.constant.level = constant->level;
 
          /* Envelope */
-         dest->u.constant.envelope.attack_length = constant->attack_length;
-         dest->u.constant.envelope.attack_level = constant->attack_level;
-         dest->u.constant.envelope.fade_length = constant->fade_length;
-         dest->u.constant.envelope.fade_level = constant->fade_level;
+         dest->u.constant.envelope.attack_length = CLAMP(constant->attack_length);
+         dest->u.constant.envelope.attack_level = CLAMP(constant->attack_level);
+         dest->u.constant.envelope.fade_length = CLAMP(constant->fade_length);
+         dest->u.constant.envelope.fade_level = CLAMP(constant->fade_level);
 
          break;
 
@@ -315,28 +317,48 @@
 
          /* Header */
          dest->type = FF_PERIODIC;
-         dest->direction = periodic->direction;
+         dest->direction = CLAMP(periodic->direction);
          
          /* Replay */
-         dest->replay.length = periodic->length;
-         dest->replay.delay = periodic->delay;
+         dest->replay.length = CLAMP(periodic->length);
+         dest->replay.delay = CLAMP(periodic->delay);
          
          /* Trigger */
-         dest->trigger.button = periodic->button;
-         dest->trigger.interval = periodic->interval;
+         dest->trigger.button = CLAMP(periodic->button);
+         dest->trigger.interval = CLAMP(periodic->interval);
          
          /* Constant */
-         dest->u.periodic.waveform = periodic->waveform;
-         dest->u.periodic.period = periodic->period;
+         switch (periodic->waveform) {
+            case SDL_WAVEFORM_SINE:
+               dest->u.periodic.waveform = FF_SINE;
+               break;
+            case SDL_WAVEFORM_SQUARE:
+               dest->u.periodic.waveform = FF_SQUARE;
+               break;
+            case SDL_WAVEFORM_TRIANGLE:
+               dest->u.periodic.waveform = FF_TRIANGLE;
+               break;
+            case SDL_WAVEFORM_SAWTOOTHUP:
+               dest->u.periodic.waveform = FF_SAW_UP;
+               break;
+            case SDL_WAVEFORM_SAWTOOTHDOWN:
+               dest->u.periodic.waveform = FF_SAW_DOWN;
+               break;
+
+            default:
+               SDL_SetError("Unknown waveform.");
+               return -1;
+         }
+         dest->u.periodic.period = CLAMP(periodic->period);
          dest->u.periodic.magnitude = periodic->magnitude;
          dest->u.periodic.offset = periodic->offset;
-         dest->u.periodic.phase = periodic->phase;
+         dest->u.periodic.phase = CLAMP(periodic->phase);
          
          /* Envelope */
-         dest->u.periodic.envelope.attack_length = periodic->attack_length;
-         dest->u.periodic.envelope.attack_level = periodic->attack_level;
-         dest->u.periodic.envelope.fade_length = periodic->fade_length;
-         dest->u.periodic.envelope.fade_level = periodic->fade_level;
+         dest->u.periodic.envelope.attack_length = CLAMP(periodic->attack_length);
+         dest->u.periodic.envelope.attack_level = CLAMP(periodic->attack_level);
+         dest->u.periodic.envelope.fade_length = CLAMP(periodic->fade_length);
+         dest->u.periodic.envelope.fade_level = CLAMP(periodic->fade_level);
 
          break;