# HG changeset patch # User Edgar Simo # Date 1214909082 0 # Node ID 5d0ea4576f2080777b4d2ef0b4e0ecc5ee21c201 # Parent b883974445fc8bc5868f3f3ecee1896be5d09e26 More comments. Clamped values in struct ff_effect. Added waveforms. diff -r b883974445fc -r 5d0ea4576f20 include/SDL_haptic.h --- 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; diff -r b883974445fc -r 5d0ea4576f20 src/haptic/linux/SDL_syshaptic.c --- 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;