From 8d55260438f90012786a7e50f68d7d51cbae5687 Mon Sep 17 00:00:00 2001 From: Edgar Simo Date: Sun, 6 Jul 2008 21:47:41 +0000 Subject: [PATCH] Implemented polar coordinates in linux. SDL_ConditionEffect now takes into account both axes. --- include/SDL_haptic.h | 18 ++++++---- src/haptic/linux/SDL_syshaptic.c | 58 ++++++++++++++++++++++++++------ 2 files changed, 58 insertions(+), 18 deletions(-) diff --git a/include/SDL_haptic.h b/include/SDL_haptic.h index 41b211dfc..d0cf3a81a 100644 --- a/include/SDL_haptic.h +++ b/include/SDL_haptic.h @@ -450,6 +450,9 @@ typedef struct SDL_HapticPeriodic { * \brief A structure containing a template for a Condition effect. * * Direction is handled by condition internals instead of a direction member. + * Each of right_sat, lefT-sat, right_coeff, left_coeff, deadband and center + * have two parameters, first is for x value, second is for y value following + * the scheme set by SDL_HapticDirection. * * The struct handles the following effects: * - SDL_HAPTIC_SPRING: Effect based on axes position. @@ -457,6 +460,7 @@ typedef struct SDL_HapticPeriodic { * - SDL_HAPTIC_INERTIA: Effect based on axes acceleration. * - SDL_HAPTIC_FRICTION: Effect based on axes movement. * + * \sa SDL_HapticDirection * \sa SDL_HAPTIC_SPRING * \sa SDL_HAPTIC_DAMPER * \sa SDL_HAPTIC_INERTIA @@ -476,12 +480,12 @@ typedef struct SDL_HapticCondition { Uint16 interval; /**< How soon it can be triggered again after button. */ /* Condition */ - Uint16 right_sat; /**< Level when joystick is to the right. */ - Uint16 left_sat; /**< Level when joystick is to the left. */ - Sint16 right_coeff; /**< How fast to increase the force towards the right. */ - Sint16 left_coeff; /**< How fast to increase the force towards the left. */ - Uint16 deadband; /**< Size of the dead zone. */ - Sint16 center; /**< Position of the dead zone. */ + Uint16 right_sat[2]; /**< Level when joystick is to the right. */ + Uint16 left_sat[2]; /**< Level when joystick is to the left. */ + Sint16 right_coeff[2]; /**< How fast to increase the force towards the right. */ + Sint16 left_coeff[2]; /**< How fast to increase the force towards the left. */ + Uint16 deadband[2]; /**< Size of the dead zone. */ + Sint16 center[2]; /**< Position of the dead zone. */ } SDL_HapticCondition; /** * \struct SDL_HapticRamp @@ -574,7 +578,7 @@ typedef union SDL_HapticEffect { Uint16 type; /**< Effect type. */ SDL_HapticConstant constant; /**< Constant effect. */ SDL_HapticPeriodic periodic; /**< Periodic effect. */ - SDL_HapticCondition condition[2]; /**< Condition effect, one for each axis. */ + SDL_HapticCondition condition; /**< Condition effect. */ SDL_HapticRamp ramp; /**< Ramp effect. */ } SDL_HapticEffect; diff --git a/src/haptic/linux/SDL_syshaptic.c b/src/haptic/linux/SDL_syshaptic.c index 7cc200106..b8558baac 100644 --- a/src/haptic/linux/SDL_syshaptic.c +++ b/src/haptic/linux/SDL_syshaptic.c @@ -111,6 +111,9 @@ EV_IsHaptic(int fd) return ret; } +/* + * Initializes the haptic subsystem by finding available devices. + */ int SDL_SYS_HapticInit(void) { @@ -328,6 +331,31 @@ SDL_SYS_HapticQuit(void) SDL_hapticlist[0].fname = NULL; } +/* + * Returns the ff_effect usable direction from a SDL_HapticDirection. + */ +static Uint16 +SDL_SYS_ToDirection( SDL_HapticDirection * dir ) +{ + Uint32 tmp; + + switch (dir->type) { + case SDL_HAPTIC_POLAR: + tmp = ((dir->dir[0] % 36000) * 0xFFFF) / 36000; + return (Uint16) tmp; + break; + case SDL_HAPTIC_CARTESIAN: + /* TODO implement cartesian for linux since it's not supported + * by driver */ + break; + + default: + return -1; + } + + return 0; +} + #define CLAMP(x) (((x) > 32767) ? 32767 : x) /* * Initializes the linux effect struct from a haptic_effect. @@ -351,7 +379,7 @@ SDL_SYS_ToFFEffect( struct ff_effect * dest, SDL_HapticEffect * src ) /* Header */ dest->type = FF_CONSTANT; - dest->direction = CLAMP(constant->direction); + dest->direction = SDL_SYS_ToDirection(&constant->direction); /* Replay */ dest->replay.length = CLAMP(constant->length); @@ -381,7 +409,7 @@ SDL_SYS_ToFFEffect( struct ff_effect * dest, SDL_HapticEffect * src ) /* Header */ dest->type = FF_PERIODIC; - dest->direction = CLAMP(periodic->direction); + dest->direction = SDL_SYS_ToDirection(&periodic->direction); /* Replay */ dest->replay.length = CLAMP(periodic->length); @@ -430,7 +458,7 @@ SDL_SYS_ToFFEffect( struct ff_effect * dest, SDL_HapticEffect * src ) dest->type = FF_INERTIA; else if (dest->type == SDL_HAPTIC_FRICTION) dest->type = FF_FRICTION; - dest->direction = CLAMP(condition->direction); + dest->direction = 0; /* Handled by the condition-specifics. */ /* Replay */ dest->replay.length = CLAMP(condition->length); @@ -440,13 +468,21 @@ SDL_SYS_ToFFEffect( struct ff_effect * dest, SDL_HapticEffect * src ) dest->trigger.button = CLAMP(condition->button); dest->trigger.interval = CLAMP(condition->interval); - /* Condition - TODO handle axes */ - dest->u.condition[0].right_saturation = CLAMP(condition->right_sat); - dest->u.condition[0].left_saturation = CLAMP(condition->left_sat); - dest->u.condition[0].right_coeff = condition->right_coeff; - dest->u.condition[0].left_coeff = condition->left_coeff; - dest->u.condition[0].deadband = CLAMP(condition->deadband); - dest->u.condition[0].center = condition->center; + /* Condition */ + /* X axis */ + dest->u.condition[0].right_saturation = CLAMP(condition->right_sat[0]); + dest->u.condition[0].left_saturation = CLAMP(condition->left_sat[0]); + dest->u.condition[0].right_coeff = condition->right_coeff[0]; + dest->u.condition[0].left_coeff = condition->left_coeff[0]; + dest->u.condition[0].deadband = CLAMP(condition->deadband[0]); + dest->u.condition[0].center = condition->center[0]; + /* Y axis */ + dest->u.condition[1].right_saturation = CLAMP(condition->right_sat[1]); + dest->u.condition[1].left_saturation = CLAMP(condition->left_sat[1]); + dest->u.condition[1].right_coeff = condition->right_coeff[1]; + dest->u.condition[1].left_coeff = condition->left_coeff[1]; + dest->u.condition[1].deadband = CLAMP(condition->deadband[1]); + dest->u.condition[1].center = condition->center[1]; break; @@ -455,7 +491,7 @@ SDL_SYS_ToFFEffect( struct ff_effect * dest, SDL_HapticEffect * src ) /* Header */ dest->type = FF_RAMP; - dest->direction = CLAMP(ramp->direction); + dest->direction = SDL_SYS_ToDirection(&ramp->direction); /* Replay */ dest->replay.length = CLAMP(ramp->length);