# HG changeset patch # User Edgar Simo # Date 1214904142 0 # Node ID b883974445fc8bc5868f3f3ecee1896be5d09e26 # Parent b9eb2cfe16cdadddec0c0170edfe20db49a2b1d1 Some more error reporting. Added periodic effect. Confirmed it works. diff -r b9eb2cfe16cd -r b883974445fc include/SDL_haptic.h --- a/include/SDL_haptic.h Mon Jun 30 21:38:29 2008 +0000 +++ b/include/SDL_haptic.h Tue Jul 01 09:22:22 2008 +0000 @@ -60,15 +60,57 @@ typedef struct SDL_HapticConstant { /* Header */ Uint16 type; + Uint16 direction; + + /* Replay */ Uint16 length; Uint16 delay; + + /* Trigger */ + Uint16 button; + Uint16 interval; + + /* Constant */ + Sint16 level; + + /* Envelope */ + Uint16 attack_length; + Uint16 attack_level; + Uint16 fade_length; + Uint16 fade_level; +} SDL_HapticConstant; +typedef struct SDL_HapticPeriodic { + /* Header */ + Uint16 type; Uint16 direction; -} SDL_HapticConstant; + + /* Replay */ + Uint16 length; + Uint16 delay; + + /* Trigger */ + Uint16 button; + Uint16 interval; + + /* Periodic */ + Uint16 waveform; + Uint16 period; + Sint16 magnitude; + Sint16 offset; + Uint16 phase; + + /* Envelope */ + Uint16 attack_length; + Uint16 attack_level; + Uint16 fade_length; + Uint16 fade_level; +} SDL_HapticPeriodic; typedef union SDL_HapticEffect { /* Common for all force feedback effects */ Uint16 type; /* Effect type */ SDL_HapticConstant constant; /* Constant effect */ + SDL_HapticPeriodic periodic; /* Periodic effect */ } SDL_HapticEffect; diff -r b9eb2cfe16cd -r b883974445fc src/haptic/SDL_haptic.c --- a/src/haptic/SDL_haptic.c Mon Jun 30 21:38:29 2008 +0000 +++ b/src/haptic/SDL_haptic.c Tue Jul 01 09:22:22 2008 +0000 @@ -166,7 +166,12 @@ return; } - /* Close it */ + /* Close it, properly removing effects if needed */ + for (i=0; ineffects; i++) { + if (haptic->effects[i].hweffect != NULL) { + SDL_HapticDestroyEffect(haptic,i); + } + } SDL_SYS_HapticClose(haptic); /* Remove from the list */ @@ -248,12 +253,18 @@ return -1; } + /* Check to see if effect is supported */ + if (SDL_HapticEffectSupported(haptic,effect)==SDL_FALSE) { + SDL_SetError("Haptic effect not supported by haptic device."); + return -1; + } + /* See if there's a free slot */ for (i=0; ineffects; i++) { if (haptic->effects[i].hweffect == NULL) { /* Now let the backend create the real effect */ - if (SDL_SYS_HapticNewEffect(haptic,&haptic->effects[i]) != 0) { + if (SDL_SYS_HapticNewEffect(haptic,&haptic->effects[i],effect) != 0) { return -1; /* Backend failed to create effect */ } return i; @@ -265,12 +276,25 @@ } /* + * Checks to see if an effect is valid. + */ +static int +ValidEffect(SDL_Haptic * haptic, int effect) +{ + if ((effect < 0) || (effect >= haptic->neffects)) { + SDL_SetError("Invalid haptic effect identifier."); + return 0; + } + return 1; +} + +/* * Runs the haptic effect on the device. */ int SDL_HapticRunEffect(SDL_Haptic * haptic, int effect) { - if (!ValidHaptic(&haptic)) { + if (!ValidHaptic(&haptic) || !ValidEffect(haptic,effect)) { return -1; } @@ -288,7 +312,7 @@ void SDL_HapticDestroyEffect(SDL_Haptic * haptic, int effect) { - if (!ValidHaptic(&haptic)) { + if (!ValidHaptic(&haptic) || !ValidEffect(haptic,effect)) { return; } diff -r b9eb2cfe16cd -r b883974445fc src/haptic/SDL_syshaptic.h --- a/src/haptic/SDL_syshaptic.h Mon Jun 30 21:38:29 2008 +0000 +++ b/src/haptic/SDL_syshaptic.h Tue Jul 01 09:22:22 2008 +0000 @@ -53,7 +53,7 @@ extern void SDL_SYS_HapticClose(SDL_Haptic * haptic); extern void SDL_SYS_HapticQuit(void); extern int SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, - struct haptic_effect * effect); + struct haptic_effect * effect, SDL_HapticEffect * base); extern int SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect * effect); extern void SDL_SYS_HapticDestroyEffect(SDL_Haptic * haptic, diff -r b9eb2cfe16cd -r b883974445fc src/haptic/linux/SDL_syshaptic.c --- a/src/haptic/linux/SDL_syshaptic.c Mon Jun 30 21:38:29 2008 +0000 +++ b/src/haptic/linux/SDL_syshaptic.c Tue Jul 01 09:22:22 2008 +0000 @@ -35,6 +35,7 @@ #include #include #include +#include #define MAX_HAPTICS 32 @@ -274,12 +275,68 @@ * Initializes the linux effect struct from a haptic_effect. */ static int -SDL_SYS_ToFFEffect( struct ff_effect * dest, struct haptic_effect * src ) +SDL_SYS_ToFFEffect( struct ff_effect * dest, SDL_HapticEffect * src ) { + SDL_HapticConstant *constant; + SDL_HapticPeriodic *periodic; + + /* Clear up */ SDL_memset(dest, 0, sizeof(struct ff_effect)); - switch (src->effect.type) { + + switch (src->type) { case SDL_HAPTIC_CONSTANT: + constant = &src->constant; + + /* Header */ dest->type = FF_CONSTANT; + dest->direction = constant->direction; + + /* Replay */ + dest->replay.length = constant->length; + dest->replay.delay = constant->delay; + + /* Trigger */ + dest->trigger.button = constant->button; + dest->trigger.interval = 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; + + break; + + case SDL_HAPTIC_PERIODIC: + periodic = &src->periodic; + + /* Header */ + dest->type = FF_PERIODIC; + dest->direction = periodic->direction; + + /* Replay */ + dest->replay.length = periodic->length; + dest->replay.delay = periodic->delay; + + /* Trigger */ + dest->trigger.button = periodic->button; + dest->trigger.interval = periodic->interval; + + /* Constant */ + dest->u.periodic.waveform = periodic->waveform; + dest->u.periodic.period = periodic->period; + dest->u.periodic.magnitude = periodic->magnitude; + dest->u.periodic.offset = periodic->offset; + dest->u.periodic.phase = 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; break; @@ -295,8 +352,11 @@ * Creates a new haptic effect. */ int -SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect * effect) +SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect * effect, + SDL_HapticEffect * base) { + struct ff_effect * linux_effect; + /* Allocate the hardware effect */ effect->hweffect = (struct haptic_hweffect *) SDL_malloc(sizeof(struct haptic_hweffect)); @@ -306,14 +366,16 @@ } /* Prepare the ff_effect */ - if (SDL_SYS_ToFFEffect( &effect->hweffect->effect, effect ) != 0) { + linux_effect = &effect->hweffect->effect; + if (SDL_SYS_ToFFEffect( linux_effect, base ) != 0) { return -1; } - effect->hweffect->effect.id = -1; /* Have the kernel give it an id */ + linux_effect->id = -1; /* Have the kernel give it an id */ /* Upload the effect */ - if (ioctl(haptic->hwdata->fd, EVIOCSFF, &effect->hweffect->effect) < 0) { - SDL_SetError("Error uploading effect to the haptic device."); + if (ioctl(haptic->hwdata->fd, EVIOCSFF, linux_effect) < 0) { + SDL_SetError("Error uploading effect to the haptic device: %s", + strerror(errno)); return -1; }