Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

Some more error reporting.

Added periodic effect.
Confirmed it works.
  • Loading branch information
bobbens committed Jul 1, 2008
1 parent 8973298 commit aed0c4b17ebce6c342bc1d5a4233d8e75cb90733
Showing with 141 additions and 13 deletions.
  1. +43 −1 include/SDL_haptic.h
  2. +28 −4 src/haptic/SDL_haptic.c
  3. +1 −1 src/haptic/SDL_syshaptic.h
  4. +69 −7 src/haptic/linux/SDL_syshaptic.c
@@ -60,15 +60,57 @@ typedef struct _SDL_Haptic SDL_Haptic;
typedef struct SDL_HapticConstant {
/* Header */
Uint16 type;
Uint16 direction;

/* Replay */
Uint16 length;
Uint16 delay;
Uint16 direction;

/* 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;

/* 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;


@@ -166,7 +166,12 @@ SDL_HapticClose(SDL_Haptic * haptic)
return;
}

/* Close it */
/* Close it, properly removing effects if needed */
for (i=0; i<haptic->neffects; i++) {
if (haptic->effects[i].hweffect != NULL) {
SDL_HapticDestroyEffect(haptic,i);
}
}
SDL_SYS_HapticClose(haptic);

/* Remove from the list */
@@ -248,12 +253,18 @@ SDL_HapticNewEffect(SDL_Haptic * haptic, SDL_HapticEffect * effect)
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; i<haptic->neffects; 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;
@@ -264,13 +275,26 @@ SDL_HapticNewEffect(SDL_Haptic * haptic, SDL_HapticEffect * effect)
return -1;
}

/*
* 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 @@ SDL_HapticRunEffect(SDL_Haptic * haptic, int effect)
void
SDL_HapticDestroyEffect(SDL_Haptic * haptic, int effect)
{
if (!ValidHaptic(&haptic)) {
if (!ValidHaptic(&haptic) || !ValidEffect(haptic,effect)) {
return;
}

@@ -53,7 +53,7 @@ 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);
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,
@@ -35,6 +35,7 @@
#include <fcntl.h>
#include <linux/limits.h>
#include <string.h>
#include <errno.h>


#define MAX_HAPTICS 32
@@ -274,12 +275,68 @@ SDL_SYS_HapticQuit(void)
* 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 @@ SDL_SYS_ToFFEffect( struct ff_effect * dest, struct haptic_effect * src )
* 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 @@ SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect * effect)
}

/* 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;
}

0 comments on commit aed0c4b

Please sign in to comment.