From 89732989ff60119f74203e22116655027b503551 Mon Sep 17 00:00:00 2001 From: Edgar Simo Date: Mon, 30 Jun 2008 21:38:29 +0000 Subject: [PATCH] Added some preliminary support for haptic effect control. --- src/haptic/SDL_haptic.c | 14 ++++++ src/haptic/SDL_syshaptic.h | 7 +++ src/haptic/linux/SDL_syshaptic.c | 81 +++++++++++++++++++++++++++++++- 3 files changed, 100 insertions(+), 2 deletions(-) diff --git a/src/haptic/SDL_haptic.c b/src/haptic/SDL_haptic.c index a987ac65b..57a5c7671 100644 --- a/src/haptic/SDL_haptic.c +++ b/src/haptic/SDL_haptic.c @@ -273,6 +273,13 @@ SDL_HapticRunEffect(SDL_Haptic * haptic, int effect) if (!ValidHaptic(&haptic)) { return -1; } + + /* Run the effect */ + if (SDL_SYS_HapticRunEffect(haptic,&haptic->effects[effect]) < 0) { + return -1; + } + + return 0; } /* @@ -284,6 +291,13 @@ SDL_HapticDestroyEffect(SDL_Haptic * haptic, int effect) if (!ValidHaptic(&haptic)) { return; } + + /* Not allocated */ + if (haptic->effects[effect].hweffect == NULL) { + return; + } + + SDL_SYS_HapticDestroyEffect(haptic, &haptic->effects[effect]); } diff --git a/src/haptic/SDL_syshaptic.h b/src/haptic/SDL_syshaptic.h index 8b9a5ff34..2368f4d0a 100644 --- a/src/haptic/SDL_syshaptic.h +++ b/src/haptic/SDL_syshaptic.h @@ -52,4 +52,11 @@ extern const char * SDL_SYS_HapticName(int index); extern int SDL_SYS_HapticOpen(SDL_Haptic * haptic); 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); +extern int SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, + struct haptic_effect * effect); +extern void SDL_SYS_HapticDestroyEffect(SDL_Haptic * haptic, + struct haptic_effect * effect); + diff --git a/src/haptic/linux/SDL_syshaptic.c b/src/haptic/linux/SDL_syshaptic.c index df08ce5fa..8fdad82f6 100644 --- a/src/haptic/linux/SDL_syshaptic.c +++ b/src/haptic/linux/SDL_syshaptic.c @@ -64,7 +64,7 @@ struct haptic_hwdata */ struct haptic_hweffect { - int id; + struct ff_effect effect; }; @@ -270,13 +270,90 @@ SDL_SYS_HapticQuit(void) SDL_hapticlist[0].fname = NULL; } +/* + * Initializes the linux effect struct from a haptic_effect. + */ +static int +SDL_SYS_ToFFEffect( struct ff_effect * dest, struct haptic_effect * src ) +{ + SDL_memset(dest, 0, sizeof(struct ff_effect)); + switch (src->effect.type) { + case SDL_HAPTIC_CONSTANT: + dest->type = FF_CONSTANT; + + break; + + default: + SDL_SetError("Unknown haptic effect type."); + return -1; + } + + return 0; +} + /* * Creates a new haptic effect. */ int SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect * effect) { - return -1; + /* Allocate the hardware effect */ + effect->hweffect = (struct haptic_hweffect *) + SDL_malloc(sizeof(struct haptic_hweffect)); + if (effect->hweffect == NULL) { + SDL_OutOfMemory(); + return -1; + } + + /* Prepare the ff_effect */ + if (SDL_SYS_ToFFEffect( &effect->hweffect->effect, effect ) != 0) { + return -1; + } + effect->hweffect->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."); + return -1; + } + + return 0; +} + + +/* + * Runs an effect. + */ +int +SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect * effect) +{ + struct input_event run; + + /* Prepare to run the effect */ + run.type = EV_FF; + run.code = effect->hweffect->effect.id; + run.value = 1; + + if (write(haptic->hwdata->fd, (const void*) &run, sizeof(run)) < 0) { + SDL_SetError("Unable to run the haptic effect."); + return -1; + } + + return 0; +} + + +/* + * Frees the effect + */ +void +SDL_SYS_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect * effect) +{ + if (ioctl(haptic->hwdata->fd, EVIOCRMFF, effect->hweffect->effect.id) < 0) { + SDL_SetError("Error removing the effect from the haptic device."); + } + SDL_free(effect->hweffect); + effect->hweffect = NULL; }