Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
Added custom effect with support on darwin.
Browse files Browse the repository at this point in the history
  • Loading branch information
bobbens committed Jul 19, 2008
1 parent 613d890 commit 7c55293
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 4 deletions.
42 changes: 42 additions & 0 deletions include/SDL_haptic.h
Expand Up @@ -590,6 +590,46 @@ typedef struct SDL_HapticRamp {
Uint16 fade_length; /**< Duration of the fade. */
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
*
Expand Down Expand Up @@ -652,6 +692,7 @@ typedef struct SDL_HapticRamp {
* \sa SDL_HapticPeriodic
* \sa SDL_HapticCondition
* \sa SDL_HapticRamp
* \sa SDL_HapticCustom
*/
typedef union SDL_HapticEffect {
/* Common for all force feedback effects */
Expand All @@ -660,6 +701,7 @@ typedef union SDL_HapticEffect {
SDL_HapticPeriodic periodic; /**< Periodic effect. */
SDL_HapticCondition condition; /**< Condition effect. */
SDL_HapticRamp ramp; /**< Ramp effect. */
SDL_HapticCustom custom; /**< Custom effect. */
} SDL_HapticEffect;


Expand Down
62 changes: 58 additions & 4 deletions src/haptic/darwin/SDL_syshaptic.c
Expand Up @@ -69,7 +69,7 @@ struct haptic_hweffect
/*
* Prototypes.
*/
static void SDL_SYS_HapticFreeFFEFFECT( FFEFFECT * effect );
static void SDL_SYS_HapticFreeFFEFFECT( FFEFFECT * effect, int type );


/*
Expand Down Expand Up @@ -314,7 +314,8 @@ SDL_SYS_HapticClose(SDL_Haptic * haptic)
/* 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);
}
}
Expand Down Expand Up @@ -414,6 +415,7 @@ SDL_SYS_ToFFEFFECT( SDL_Haptic * haptic, FFEFFECT * dest, SDL_HapticEffect * src
SDL_HapticPeriodic *hap_periodic;
SDL_HapticCondition *hap_condition;
SDL_HapticRamp *hap_ramp;
SDL_HapticCustom *hap_custom;
DWORD *axes;

/* Set global stuff. */
Expand Down Expand Up @@ -460,6 +462,7 @@ SDL_SYS_ToFFEFFECT( SDL_Haptic * haptic, FFEFFECT * dest, SDL_HapticEffect * src
SDL_OutOfMemory();
return -1;
}
SDL_memset(constant, 0, sizeof(FFCONSTANTFORCE));

/* Specifics */
constant->lMagnitude = CONVERT(hap_constant->level);
Expand Down Expand Up @@ -496,6 +499,7 @@ SDL_SYS_ToFFEFFECT( SDL_Haptic * haptic, FFEFFECT * dest, SDL_HapticEffect * src
SDL_OutOfMemory();
return -1;
}
SDL_memset(periodic, 0, sizeof(FFPERIODIC));

/* Specifics */
periodic->dwMagnitude = CONVERT(hap_periodic->magnitude);
Expand Down Expand Up @@ -534,6 +538,7 @@ SDL_SYS_ToFFEFFECT( SDL_Haptic * haptic, FFEFFECT * dest, SDL_HapticEffect * src
SDL_OutOfMemory();
return -1;
}
SDL_memset(condition, 0, sizeof(FFCONDITION));

/* Specifics */
for (i=0; i<dest->cAxes; i++) {
Expand Down Expand Up @@ -575,10 +580,13 @@ SDL_SYS_ToFFEFFECT( SDL_Haptic * haptic, FFEFFECT * dest, SDL_HapticEffect * src
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. */
Expand All @@ -599,6 +607,45 @@ SDL_SYS_ToFFEFFECT( SDL_Haptic * haptic, FFEFFECT * dest, SDL_HapticEffect * src

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.");
Expand All @@ -613,8 +660,10 @@ SDL_SYS_ToFFEFFECT( SDL_Haptic * haptic, FFEFFECT * dest, SDL_HapticEffect * src
* 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;
Expand All @@ -624,6 +673,11 @@ SDL_SYS_HapticFreeFFEFFECT( FFEFFECT * effect )
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;
}
Expand Down Expand Up @@ -725,7 +779,7 @@ SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect * effect,
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);
Expand Down

0 comments on commit 7c55293

Please sign in to comment.