Mercurial > sdl-ios-xcode
changeset 2535:f0ed8471497d gsoc2008_force_feedback
Added custom effect with support on darwin.
author | Edgar Simo <bobbens@gmail.com> |
---|---|
date | Sat, 19 Jul 2008 15:57:07 +0000 |
parents | e597de8dccd5 |
children | fe3ee345a5d2 |
files | include/SDL_haptic.h src/haptic/darwin/SDL_syshaptic.c |
diffstat | 2 files changed, 100 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/include/SDL_haptic.h Fri Jul 18 19:22:56 2008 +0000 +++ b/include/SDL_haptic.h Sat Jul 19 15:57:07 2008 +0000 @@ -591,6 +591,46 @@ Uint16 fade_level; /**< Level at the end of the fade. */ } SDL_HapticRamp; /** + * \struct SDL_HapticCustom + * + * \brief A structure containing a template for the SDL_HAPTIC_CUSTOM effect. + * + * A custom force feedback effect is much like a periodic effect, where the + * application can define it's exact shape. You will have to allocate the + * data yourself. Data should consist of channels * samples Uint16 samples. + * + * If channels is one, the effect is rotated using the defined direction. + * Otherwise it uses the samples in data for the different axes. + * + * \sa SDL_HAPTIC_CUSTOM + * \sa SDL_HapticEffect + */ +typedef struct SDL_HapticCustom { + /* Header */ + Uint16 type; /**< SDL_HAPTIC_CUSTOM */ + SDL_HapticDirection direction; /**< Direction of the effect. */ + + /* Replay */ + Uint32 length; /**< Duration of the effect. */ + Uint16 delay; /**< Delay before starting the effect. */ + + /* Trigger */ + Uint16 button; /**< Button that triggers the effect. */ + Uint16 interval; /**< How soon it can be triggered again after button. */ + + /* Custom */ + Uint8 channels; /**< Axes to use, minimum of one. */ + Uint16 period; /**< Sample periods. */ + Uint16 samples; /**< Amount of samples. */ + Uint16 *data; /**< Should contain channels*samples items. */ + + /* 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. */ + Uint16 fade_level; /**< Level at the end of the fade. */ +} SDL_HapticCustom; +/** * \union SDL_HapticEffect * * \brief The generic template for any haptic effect. @@ -652,6 +692,7 @@ * \sa SDL_HapticPeriodic * \sa SDL_HapticCondition * \sa SDL_HapticRamp + * \sa SDL_HapticCustom */ typedef union SDL_HapticEffect { /* Common for all force feedback effects */ @@ -660,6 +701,7 @@ SDL_HapticPeriodic periodic; /**< Periodic effect. */ SDL_HapticCondition condition; /**< Condition effect. */ SDL_HapticRamp ramp; /**< Ramp effect. */ + SDL_HapticCustom custom; /**< Custom effect. */ } SDL_HapticEffect;
--- a/src/haptic/darwin/SDL_syshaptic.c Fri Jul 18 19:22:56 2008 +0000 +++ b/src/haptic/darwin/SDL_syshaptic.c Sat Jul 19 15:57:07 2008 +0000 @@ -69,7 +69,7 @@ /* * Prototypes. */ -static void SDL_SYS_HapticFreeFFEFFECT( FFEFFECT * effect ); +static void SDL_SYS_HapticFreeFFEFFECT( FFEFFECT * effect, int type ); /* @@ -314,7 +314,8 @@ /* Free the effects. */ for (i=0; i<haptic->neffects; i++) { if (haptic->effects[i].hweffect != NULL) { - SDL_SYS_HapticFreeFFEFFECT(&haptic->effects[i].hweffect->effect); + SDL_SYS_HapticFreeFFEFFECT(&haptic->effects[i].hweffect->effect, + haptic->effects[i].effect.type); SDL_free(haptic->effects[i].hweffect); } } @@ -414,6 +415,7 @@ SDL_HapticPeriodic *hap_periodic; SDL_HapticCondition *hap_condition; SDL_HapticRamp *hap_ramp; + SDL_HapticCustom *hap_custom; DWORD *axes; /* Set global stuff. */ @@ -460,6 +462,7 @@ SDL_OutOfMemory(); return -1; } + SDL_memset(constant, 0, sizeof(FFCONSTANTFORCE)); /* Specifics */ constant->lMagnitude = CONVERT(hap_constant->level); @@ -496,6 +499,7 @@ SDL_OutOfMemory(); return -1; } + SDL_memset(periodic, 0, sizeof(FFPERIODIC)); /* Specifics */ periodic->dwMagnitude = CONVERT(hap_periodic->magnitude); @@ -534,6 +538,7 @@ SDL_OutOfMemory(); return -1; } + SDL_memset(condition, 0, sizeof(FFCONDITION)); /* Specifics */ for (i=0; i<dest->cAxes; i++) { @@ -575,10 +580,13 @@ SDL_OutOfMemory(); return -1; } + SDL_memset(ramp, 0, sizeof(FFRAMPFORCE)); /* Specifics */ ramp->lStart = CONVERT(hap_ramp->start); ramp->lEnd = CONVERT(hap_ramp->end); + dest->cbTypeSpecificParams = sizeof(FFRAMPFORCE); + dest->lpvTypeSpecificParams = ramp; /* Generics */ dest->dwDuration = hap_ramp->length * 1000; /* In microseconds. */ @@ -599,6 +607,45 @@ break; + case SDL_HAPTIC_CUSTOM: + hap_custom = &src->custom; + custom = SDL_malloc(sizeof(FFCUSTOMFORCE)); + if (custom == NULL) { + SDL_OutOfMemory(); + return -1; + } + SDL_memset(custom, 0, sizeof(FFCUSTOMFORCE)); + + /* Specifics */ + custom->cChannels = hap_custom->channels; + custom->dwSamplePeriod = hap_custom->period * 1000; + custom->cSamples = hap_custom->samples; + custom->rglForceData = SDL_malloc(sizeof(LONG)*custom->cSamples*custom->cChannels); + for (i=0; i<hap_custom->samples*hap_custom->channels; i++) { /* Copy data. */ + custom->rglForceData[i] = CONVERT(hap_custom->data[i]); + } + dest->cbTypeSpecificParams = sizeof(FFCUSTOMFORCE); + dest->lpvTypeSpecificParams = custom; + + /* Generics */ + dest->dwDuration = hap_custom->length * 1000; /* In microseconds. */ + dest->dwTriggerButton = FFJOFS_BUTTON(hap_custom->button); + dest->dwTriggerRepeatInterval = hap_custom->interval; + dest->dwStartDelay = hap_custom->delay * 1000; /* In microseconds. */ + + /* Direction. */ + if (SDL_SYS_SetDirection(dest, &hap_custom->direction, dest->cAxes) < 0) { + return -1; + } + + /* Envelope */ + envelope->dwAttackLevel = CONVERT(hap_custom->attack_level); + envelope->dwAttackTime = hap_custom->attack_length * 1000; + envelope->dwFadeLevel = CONVERT(hap_custom->fade_level); + envelope->dwFadeTime = hap_custom->fade_length * 1000; + + break; + default: SDL_SetError("Haptic: Unknown effect type."); @@ -613,8 +660,10 @@ * Frees an FFEFFECT allocated by SDL_SYS_ToFFEFFECT. */ static void -SDL_SYS_HapticFreeFFEFFECT( FFEFFECT * effect ) +SDL_SYS_HapticFreeFFEFFECT( FFEFFECT * effect, int type ) { + FFCUSTOMFORCE *custom; + if (effect->lpEnvelope != NULL) { SDL_free(effect->lpEnvelope); effect->lpEnvelope = NULL; @@ -624,6 +673,11 @@ effect->rgdwAxes = NULL; } if (effect->lpvTypeSpecificParams != NULL) { + if (type == SDL_HAPTIC_CUSTOM) { /* Must free the custom data. */ + custom = (FFCUSTOMFORCE*) effect->lpvTypeSpecificParams; + SDL_free(custom->rglForceData); + custom->rglForceData = NULL; + } SDL_free(effect->lpvTypeSpecificParams); effect->lpvTypeSpecificParams = NULL; } @@ -725,7 +779,7 @@ return 0; err_effectdone: - SDL_SYS_HapticFreeFFEFFECT(&effect->hweffect->effect); + SDL_SYS_HapticFreeFFEFFECT(&effect->hweffect->effect, effect->effect.type); err_hweffect: if (effect->hweffect != NULL) { SDL_free(effect->hweffect);