Fixed bug #920
authorSam Lantinga <slouken@libsdl.org>
Mon, 18 Jan 2010 14:57:41 +0000
changeset 3680 7c18b38f0f9a
parent 3679 ce290de32f2a
child 3681 be6fe5f0b1db
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
--- 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: