diff -r ce290de32f2a -r 7c18b38f0f9a src/haptic/linux/SDL_syshaptic.c --- a/src/haptic/linux/SDL_syshaptic.c Mon Jan 18 14:50:57 2010 +0000 +++ b/src/haptic/linux/SDL_syshaptic.c Mon Jan 18 14:57:41 2010 +0000 @@ -505,20 +505,45 @@ 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_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_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; - return (Uint16) tmp; - - case SDL_HAPTIC_SPHERICAL: - tmp = (36000 - dir->dir[0]) + 27000; /* Convert to polars */ - tmp = (((18000 + tmp) % 36000) * 0xFFFF) / 36000; + 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: