From 4a4f2b4278ed7ed671badd0ec6b9c8741790f3ba Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 18 Jan 2010 14:57:41 +0000 Subject: [PATCH] Fixed bug #920 From Martin: Alright... I corrected SDL_SYS_ToDirection in SDL_syshaptic.c in the linux directory of haptic. Now in all 3 cases the same value is returned, at least. Therefore now it should behave the same way as on Windows. I added some comments and corrected the cases SDL_HAPTIC_CARTESIAN and SDL_HAPTIC_SPHERICAL. --- src/haptic/linux/SDL_syshaptic.c | 45 +++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/src/haptic/linux/SDL_syshaptic.c b/src/haptic/linux/SDL_syshaptic.c index 303a3f851..f68061ca6 100644 --- a/src/haptic/linux/SDL_syshaptic.c +++ b/src/haptic/linux/SDL_syshaptic.c @@ -505,20 +505,45 @@ SDL_SYS_ToDirection(SDL_HapticDirection * dir) switch (dir->type) { case SDL_HAPTIC_POLAR: - /* Linux directions are inverted. */ - tmp = (((18000 + dir->dir[0]) % 36000) * 0xFFFF) / 36000; + /* Linux directions start from south. + (and range from 0 to 0xFFFF) + Quoting include/linux/input.h, line 926: + Direction of the effect is encoded as follows: + 0 deg -> 0x0000 (down) + 90 deg -> 0x4000 (left) + 180 deg -> 0x8000 (up) + 270 deg -> 0xC000 (right) + */ + tmp = (((18000 + dir->dir[0]) % 36000) * 0xFFFF) / 36000; // convert to range [0,0xFFFF] return (Uint16) tmp; - case SDL_HAPTIC_CARTESIAN: - /* We must invert "x" and "y" to go clockwise. */ - f = atan2(dir->dir[0], dir->dir[1]); - tmp = (int) (f * 18000. / M_PI) % 36000; - tmp = (tmp * 0xFFFF) / 36000; + case SDL_HAPTIC_SPHERICAL: + /* + We convert to polar, because that's the only supported direction on Linux. + The first value of a spherical direction is practically the same as a + Polar direction, except that we have to add 90 degrees. It is the angle + from EAST {1,0} towards SOUTH {0,1}. + --> add 9000 + --> finally add 18000 and convert to [0,0xFFFF] as in case SDL_HAPTIC_POLAR. + */ + tmp = ((dir->dir[0]) + 9000) % 36000; /* Convert to polars */ + tmp = (((18000 + tmp) % 36000) * 0xFFFF) / 36000; // convert to range [0,0xFFFF] return (Uint16) tmp; - case SDL_HAPTIC_SPHERICAL: - tmp = (36000 - dir->dir[0]) + 27000; /* Convert to polars */ - tmp = (((18000 + tmp) % 36000) * 0xFFFF) / 36000; + case SDL_HAPTIC_CARTESIAN: + f = atan2(dir->dir[1], dir->dir[0]); + /* + atan2 takes the parameters: Y-axis-value and X-axis-value (in that order) + - Y-axis-value is the second coordinate (from center to SOUTH) + - X-axis-value is the first coordinate (from center to EAST) + We add 36000, because atan2 also returns negative values. Then we practically + have the first spherical value. Therefore we proceed as in case + SDL_HAPTIC_SPHERICAL and add another 9000 to get the polar value. + --> add 45000 in total + --> finally add 18000 and convert to [0,0xFFFF] as in case SDL_HAPTIC_POLAR. + */ + tmp = (((int) (f * 18000. / M_PI)) + 45000) % 36000; + tmp = (((18000 + tmp) % 36000) * 0xFFFF) / 36000; // convert to range [0,0xFFFF] return (Uint16) tmp; default: