From 37aedc173c70eb5434304ffb0bf830468de115b6 Mon Sep 17 00:00:00 2001 From: Edgar Simo Date: Mon, 30 Jun 2008 16:48:16 +0000 Subject: [PATCH] Starting to add infrastructure to handle haptic effects. --- include/SDL_haptic.h | 29 +++++++++++ src/haptic/SDL_haptic.c | 88 ++++++++++++++++++++++++++------ src/haptic/SDL_syshaptic.h | 23 ++++++--- src/haptic/linux/SDL_syshaptic.c | 55 +++++++++++++++++--- 4 files changed, 166 insertions(+), 29 deletions(-) diff --git a/include/SDL_haptic.h b/include/SDL_haptic.h index 1eef62d8d..db6b4ac22 100644 --- a/include/SDL_haptic.h +++ b/include/SDL_haptic.h @@ -57,6 +57,20 @@ typedef struct _SDL_Haptic SDL_Haptic; #define SDL_HAPTIC_GAIN (1<<8) #define SDL_HAPTIC_AUTOCENTER (1<<9) +typedef struct SDL_HapticConstant { + /* Header */ + Uint16 type; + Uint16 length; + Uint16 delay; + Uint16 direction; +} SDL_HapticConstant; + +typedef union SDL_HapticEffect { + /* Common for all force feedback effects */ + Uint16 type; /* Effect type */ + SDL_HapticConstant constant; /* Constant effect */ +} SDL_HapticEffect; + /* Function prototypes */ /* @@ -85,6 +99,21 @@ extern DECLSPEC SDL_Haptic * SDL_HapticOpen(int device_index); */ extern DECLSPEC void SDL_HapticClose(SDL_Haptic * haptic); +/* + * Creates a new haptic effect on the device. + */ +extern DECLSPEC int SDL_HapticNewEffect(SDL_Haptic * haptic, SDL_HapticEffect * effect); + +/* + * Runs the haptic effect on it's assosciated haptic device. + */ +extern DECLSPEC int SDL_HapticRunEffect(SDL_Haptic * haptic, int effect); + +/* + * Destroys a haptic effect on the device. + */ +extern DECLSPEC void SDL_HapticDestroyEffect(SDL_Haptic * haptic, int effect); + /* Ends C function definitions when using C++ */ #ifdef __cplusplus diff --git a/src/haptic/SDL_haptic.c b/src/haptic/SDL_haptic.c index 7ffb367b6..dc380f64c 100644 --- a/src/haptic/SDL_haptic.c +++ b/src/haptic/SDL_haptic.c @@ -97,7 +97,7 @@ SDL_HapticOpen(int device_index) } /* If the haptic is already open, return it */ - for (i = 0; SDL_haptics[i]; ++i) { + for (i=0; SDL_haptics[i]; i++) { if (device_index == SDL_haptics[i]->index) { haptic = SDL_haptics[i]; ++haptic->ref_count; @@ -105,23 +105,27 @@ SDL_HapticOpen(int device_index) } } - /* Create and initialize the haptic */ + /* Create the haptic device */ haptic = (SDL_Haptic *) SDL_malloc((sizeof *haptic)); - if (haptic != NULL) { - SDL_memset(haptic, 0, (sizeof *haptic)); - haptic->index = device_index; - if (SDL_SYS_HapticOpen(haptic) < 0) { - SDL_free(haptic); - haptic = NULL; - } + if (haptic == NULL) { + SDL_OutOfMemory(); + return NULL; } - if (haptic) { - /* Add haptic to list */ - ++haptic->ref_count; - for (i = 0; SDL_haptics[i]; ++i) - /* Skip to next haptic */ ; - SDL_haptics[i] = haptic; + + /* Initialize the haptic device */ + SDL_memset(haptic, 0, (sizeof *haptic)); + haptic->index = device_index; + if (SDL_SYS_HapticOpen(haptic) < 0) { + SDL_free(haptic); + return NULL; } + + /* Add haptic to list */ + ++haptic->ref_count; + for (i = 0; SDL_haptics[i]; ++i) + /* Skip to next haptic */ ; + SDL_haptics[i] = haptic; + return haptic; } @@ -192,3 +196,57 @@ SDL_HapticQuit(void) SDL_haptics = NULL; } } + + +/* + * Creates a new haptic effect. + */ +int +SDL_HapticNewEffect(SDL_Haptic * haptic, SDL_HapticEffect * effect) +{ + int i; + + /* Check for device validity. */ + if (!ValidHaptic(&haptic)) { + 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) { + return -1; /* Backend failed to create effect */ + } + return i; + } + } + + SDL_SetError("Haptic device has no free space left."); + return -1; +} + +/* + * Runs the haptic effect on the device. + */ +int +SDL_HapticRunEffect(SDL_Haptic * haptic, int effect) +{ + if (!ValidHaptic(&haptic)) { + return -1; + } +} + +/* + * Gets rid of a haptic effect. + */ +void +SDL_HapticDestroyEffect(SDL_Haptic * haptic, int effect) +{ + if (!ValidHaptic(&haptic)) { + return; + } +} + + diff --git a/src/haptic/SDL_syshaptic.h b/src/haptic/SDL_syshaptic.h index d7d29db7e..8b9a5ff34 100644 --- a/src/haptic/SDL_syshaptic.h +++ b/src/haptic/SDL_syshaptic.h @@ -25,19 +25,28 @@ #include "SDL_haptic.h" +struct haptic_effect +{ + SDL_HapticEffect effect; /* The current event */ + struct haptic_hweffect *hweffect; /* The hardware behind the event */ +}; + +/* + * The real SDL_Haptic event. + */ struct _SDL_Haptic { - Uint8 index; /* stores index it is attached to */ - const char* name; /* stores the name of the device */ + Uint8 index; /* Stores index it is attached to */ + const char* name; /* Stores the name of the device */ - int neffects; /* maximum amount of effects */ - unsigned int supported; /* supported effects */ + struct haptic_effect *effects; /* Allocated effects */ + int neffects; /* Maximum amount of effects */ + unsigned int supported; /* Supported effects */ - struct haptic_hwdata *hwdata; /* driver dependent */ - int ref_count; /* count for multiple opens */ + struct haptic_hwdata *hwdata; /* Driver dependent */ + int ref_count; /* Count for multiple opens */ }; - extern int SDL_SYS_HapticInit(void); extern const char * SDL_SYS_HapticName(int index); extern int SDL_SYS_HapticOpen(SDL_Haptic * haptic); diff --git a/src/haptic/linux/SDL_syshaptic.c b/src/haptic/linux/SDL_syshaptic.c index fa29f9f53..8a01e0a66 100644 --- a/src/haptic/linux/SDL_syshaptic.c +++ b/src/haptic/linux/SDL_syshaptic.c @@ -59,6 +59,15 @@ struct haptic_hwdata }; +/* + * Haptic system effect data. + */ +struct haptic_hweffect +{ + int id; +}; + + #define test_bit(nr, addr) \ (((1UL << ((nr) & 31)) & (((const unsigned int *) addr)[(nr) >> 5])) != 0) @@ -180,29 +189,49 @@ SDL_SYS_HapticName(int index) int SDL_SYS_HapticOpen(SDL_Haptic * haptic) { + int i; int fd; /* Open the character device */ fd = open(SDL_hapticlist[haptic->index].fname, O_RDWR, 0); if (fd < 0) { SDL_SetError("Unable to open %s\n", SDL_hapticlist[haptic->index]); - return (-1); + return -1; } /* Allocate the hwdata */ haptic->hwdata = (struct haptic_hwdata *) - SDL_malloc(sizeof(*haptic->hwdata)); + SDL_malloc(sizeof(*haptic->hwdata)); if (haptic->hwdata == NULL) { SDL_OutOfMemory(); - close(fd); - return (-1); + goto open_err; } SDL_memset(haptic->hwdata, 0, sizeof(*haptic->hwdata)); - /* Set the hwdata */ haptic->hwdata->fd = fd; + /* Set the effects */ + if (ioctl(fd, EVIOCGEFFECTS, &haptic->neffects) < 0) { + SDL_SetError("Unable to query haptic device memory."); + goto open_err; + } + haptic->effects = (struct haptic_effect *) + SDL_malloc(sizeof(struct haptic_effect) * haptic->neffects); + if (haptic->effects == NULL) { + SDL_OutOfMemory(); + goto open_err; + } + return 0; + + /* Error handling */ +open_err: + close(fd); + if (haptic->hwdata != NULL) { + free(haptic->hwdata); + haptic->hwdata = NULL; + } + return -1; } @@ -220,12 +249,15 @@ SDL_SYS_HapticClose(SDL_Haptic * haptic) /* Free */ SDL_free(haptic->hwdata); haptic->hwdata = NULL; - + SDL_free(haptic->effects); + haptic->neffects = 0; } } -/* Clean up after system specific haptic stuff */ +/* + * Clean up after system specific haptic stuff + */ void SDL_SYS_HapticQuit(void) { @@ -237,5 +269,14 @@ SDL_SYS_HapticQuit(void) SDL_hapticlist[0].fname = NULL; } +/* + * Creates a new haptic effect. + */ +int +SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect * effect) +{ + return -1; +} + #endif /* SDL_HAPTIC_LINUX */