Added custom effect with support on darwin. gsoc2008_force_feedback
authorEdgar Simo <bobbens@gmail.com>
Sat, 19 Jul 2008 15:57:07 +0000
branchgsoc2008_force_feedback
changeset 2535f0ed8471497d
parent 2534 e597de8dccd5
child 2536 fe3ee345a5d2
Added custom effect with support on darwin.
include/SDL_haptic.h
src/haptic/darwin/SDL_syshaptic.c
     1.1 --- a/include/SDL_haptic.h	Fri Jul 18 19:22:56 2008 +0000
     1.2 +++ b/include/SDL_haptic.h	Sat Jul 19 15:57:07 2008 +0000
     1.3 @@ -591,6 +591,46 @@
     1.4     Uint16 fade_level; /**< Level at the end of the fade. */
     1.5  } SDL_HapticRamp;
     1.6  /**
     1.7 + * \struct SDL_HapticCustom
     1.8 + *
     1.9 + * \brief A structure containing a template for the SDL_HAPTIC_CUSTOM effect.
    1.10 + *
    1.11 + * A custom force feedback effect is much like a periodic effect, where the
    1.12 + *  application can define it's exact shape.  You will have to allocate the
    1.13 + *  data yourself.  Data should consist of channels * samples Uint16 samples.
    1.14 + *
    1.15 + * If channels is one, the effect is rotated using the defined direction.
    1.16 + *  Otherwise it uses the samples in data for the different axes.
    1.17 + *
    1.18 + * \sa SDL_HAPTIC_CUSTOM
    1.19 + * \sa SDL_HapticEffect
    1.20 + */
    1.21 +typedef struct SDL_HapticCustom {
    1.22 +   /* Header */
    1.23 +   Uint16 type; /**< SDL_HAPTIC_CUSTOM */
    1.24 +   SDL_HapticDirection direction; /**< Direction of the effect. */
    1.25 +
    1.26 +   /* Replay */
    1.27 +   Uint32 length; /**< Duration of the effect. */
    1.28 +   Uint16 delay; /**< Delay before starting the effect. */
    1.29 +
    1.30 +   /* Trigger */
    1.31 +   Uint16 button; /**< Button that triggers the effect. */
    1.32 +   Uint16 interval; /**< How soon it can be triggered again after button. */
    1.33 +
    1.34 +   /* Custom */
    1.35 +   Uint8 channels; /**< Axes to use, minimum of one. */
    1.36 +   Uint16 period; /**< Sample periods. */
    1.37 +   Uint16 samples; /**< Amount of samples. */
    1.38 +   Uint16 *data; /**< Should contain channels*samples items. */
    1.39 +
    1.40 +   /* Envelope */                                                         
    1.41 +   Uint16 attack_length; /**< Duration of the attack. */
    1.42 +   Uint16 attack_level; /**< Level at the start of the attack. */
    1.43 +   Uint16 fade_length; /**< Duration of the fade. */
    1.44 +   Uint16 fade_level; /**< Level at the end of the fade. */
    1.45 +} SDL_HapticCustom;
    1.46 +/**
    1.47   * \union SDL_HapticEffect
    1.48   *
    1.49   * \brief The generic template for any haptic effect.
    1.50 @@ -652,6 +692,7 @@
    1.51   * \sa SDL_HapticPeriodic
    1.52   * \sa SDL_HapticCondition
    1.53   * \sa SDL_HapticRamp
    1.54 + * \sa SDL_HapticCustom
    1.55   */
    1.56  typedef union SDL_HapticEffect {
    1.57     /* Common for all force feedback effects */
    1.58 @@ -660,6 +701,7 @@
    1.59     SDL_HapticPeriodic periodic; /**< Periodic effect. */
    1.60     SDL_HapticCondition condition; /**< Condition effect. */
    1.61     SDL_HapticRamp ramp; /**< Ramp effect. */
    1.62 +   SDL_HapticCustom custom; /**< Custom effect. */
    1.63  } SDL_HapticEffect;
    1.64  
    1.65  
     2.1 --- a/src/haptic/darwin/SDL_syshaptic.c	Fri Jul 18 19:22:56 2008 +0000
     2.2 +++ b/src/haptic/darwin/SDL_syshaptic.c	Sat Jul 19 15:57:07 2008 +0000
     2.3 @@ -69,7 +69,7 @@
     2.4  /*
     2.5   * Prototypes.
     2.6   */
     2.7 -static void SDL_SYS_HapticFreeFFEFFECT( FFEFFECT * effect );
     2.8 +static void SDL_SYS_HapticFreeFFEFFECT( FFEFFECT * effect, int type );
     2.9  
    2.10  
    2.11  /*
    2.12 @@ -314,7 +314,8 @@
    2.13        /* Free the effects. */
    2.14        for (i=0; i<haptic->neffects; i++) {        
    2.15           if (haptic->effects[i].hweffect != NULL) {
    2.16 -            SDL_SYS_HapticFreeFFEFFECT(&haptic->effects[i].hweffect->effect);
    2.17 +            SDL_SYS_HapticFreeFFEFFECT(&haptic->effects[i].hweffect->effect,
    2.18 +                                       haptic->effects[i].effect.type);
    2.19              SDL_free(haptic->effects[i].hweffect);
    2.20           } 
    2.21        }    
    2.22 @@ -414,6 +415,7 @@
    2.23     SDL_HapticPeriodic *hap_periodic;
    2.24     SDL_HapticCondition *hap_condition;
    2.25     SDL_HapticRamp *hap_ramp;
    2.26 +   SDL_HapticCustom *hap_custom;
    2.27     DWORD *axes;
    2.28  
    2.29     /* Set global stuff. */
    2.30 @@ -460,6 +462,7 @@
    2.31              SDL_OutOfMemory();
    2.32              return -1;
    2.33           }
    2.34 +         SDL_memset(constant, 0, sizeof(FFCONSTANTFORCE));
    2.35  
    2.36           /* Specifics */
    2.37           constant->lMagnitude = CONVERT(hap_constant->level);
    2.38 @@ -496,6 +499,7 @@
    2.39              SDL_OutOfMemory();
    2.40              return -1;
    2.41           }
    2.42 +         SDL_memset(periodic, 0, sizeof(FFPERIODIC));
    2.43  
    2.44           /* Specifics */
    2.45           periodic->dwMagnitude = CONVERT(hap_periodic->magnitude);
    2.46 @@ -534,6 +538,7 @@
    2.47              SDL_OutOfMemory();
    2.48              return -1;
    2.49           }
    2.50 +         SDL_memset(condition, 0, sizeof(FFCONDITION));
    2.51  
    2.52           /* Specifics */
    2.53           for (i=0; i<dest->cAxes; i++) {
    2.54 @@ -575,10 +580,13 @@
    2.55              SDL_OutOfMemory();
    2.56              return -1;
    2.57           }
    2.58 +         SDL_memset(ramp, 0, sizeof(FFRAMPFORCE));
    2.59  
    2.60           /* Specifics */
    2.61           ramp->lStart = CONVERT(hap_ramp->start);
    2.62           ramp->lEnd = CONVERT(hap_ramp->end);
    2.63 +         dest->cbTypeSpecificParams = sizeof(FFRAMPFORCE);
    2.64 +         dest->lpvTypeSpecificParams = ramp;
    2.65  
    2.66           /* Generics */
    2.67           dest->dwDuration = hap_ramp->length * 1000; /* In microseconds. */
    2.68 @@ -599,6 +607,45 @@
    2.69  
    2.70           break;
    2.71  
    2.72 +      case SDL_HAPTIC_CUSTOM:
    2.73 +         hap_custom = &src->custom;
    2.74 +         custom = SDL_malloc(sizeof(FFCUSTOMFORCE));
    2.75 +         if (custom == NULL) {
    2.76 +            SDL_OutOfMemory();
    2.77 +            return -1;
    2.78 +         }
    2.79 +         SDL_memset(custom, 0, sizeof(FFCUSTOMFORCE));
    2.80 +
    2.81 +         /* Specifics */
    2.82 +         custom->cChannels = hap_custom->channels;
    2.83 +         custom->dwSamplePeriod = hap_custom->period * 1000;
    2.84 +         custom->cSamples = hap_custom->samples;
    2.85 +         custom->rglForceData = SDL_malloc(sizeof(LONG)*custom->cSamples*custom->cChannels);
    2.86 +         for (i=0; i<hap_custom->samples*hap_custom->channels; i++) { /* Copy data. */
    2.87 +            custom->rglForceData[i] = CONVERT(hap_custom->data[i]);
    2.88 +         }
    2.89 +         dest->cbTypeSpecificParams = sizeof(FFCUSTOMFORCE);
    2.90 +         dest->lpvTypeSpecificParams = custom;
    2.91 +
    2.92 +         /* Generics */
    2.93 +         dest->dwDuration = hap_custom->length * 1000; /* In microseconds. */
    2.94 +         dest->dwTriggerButton = FFJOFS_BUTTON(hap_custom->button);
    2.95 +         dest->dwTriggerRepeatInterval = hap_custom->interval;
    2.96 +         dest->dwStartDelay = hap_custom->delay * 1000; /* In microseconds. */
    2.97 +
    2.98 +         /* Direction. */
    2.99 +         if (SDL_SYS_SetDirection(dest, &hap_custom->direction, dest->cAxes) < 0) {
   2.100 +            return -1;
   2.101 +         }
   2.102 +         
   2.103 +         /* Envelope */
   2.104 +         envelope->dwAttackLevel = CONVERT(hap_custom->attack_level);
   2.105 +         envelope->dwAttackTime = hap_custom->attack_length * 1000;
   2.106 +         envelope->dwFadeLevel = CONVERT(hap_custom->fade_level);
   2.107 +         envelope->dwFadeTime = hap_custom->fade_length * 1000;
   2.108 +
   2.109 +         break;
   2.110 +
   2.111  
   2.112        default:
   2.113           SDL_SetError("Haptic: Unknown effect type.");
   2.114 @@ -613,8 +660,10 @@
   2.115   * Frees an FFEFFECT allocated by SDL_SYS_ToFFEFFECT.
   2.116   */
   2.117  static void
   2.118 -SDL_SYS_HapticFreeFFEFFECT( FFEFFECT * effect )
   2.119 +SDL_SYS_HapticFreeFFEFFECT( FFEFFECT * effect, int type )
   2.120  {
   2.121 +   FFCUSTOMFORCE *custom;
   2.122 +
   2.123     if (effect->lpEnvelope != NULL) {
   2.124        SDL_free(effect->lpEnvelope);
   2.125        effect->lpEnvelope = NULL;
   2.126 @@ -624,6 +673,11 @@
   2.127        effect->rgdwAxes = NULL;
   2.128     }
   2.129     if (effect->lpvTypeSpecificParams != NULL) {
   2.130 +      if (type == SDL_HAPTIC_CUSTOM) { /* Must free the custom data. */
   2.131 +         custom = (FFCUSTOMFORCE*) effect->lpvTypeSpecificParams;
   2.132 +         SDL_free(custom->rglForceData);
   2.133 +         custom->rglForceData = NULL;
   2.134 +      }
   2.135        SDL_free(effect->lpvTypeSpecificParams);
   2.136        effect->lpvTypeSpecificParams = NULL;
   2.137     }
   2.138 @@ -725,7 +779,7 @@
   2.139     return 0;
   2.140  
   2.141  err_effectdone:
   2.142 -   SDL_SYS_HapticFreeFFEFFECT(&effect->hweffect->effect);
   2.143 +   SDL_SYS_HapticFreeFFEFFECT(&effect->hweffect->effect, effect->effect.type);
   2.144  err_hweffect:
   2.145     if (effect->hweffect != NULL) {
   2.146        SDL_free(effect->hweffect);