Fixed bug #920
authorSam Lantinga <slouken@libsdl.org>
Mon, 18 Jan 2010 14:57:41 +0000
changeset 36807c18b38f0f9a
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
     1.1 --- a/src/haptic/linux/SDL_syshaptic.c	Mon Jan 18 14:50:57 2010 +0000
     1.2 +++ b/src/haptic/linux/SDL_syshaptic.c	Mon Jan 18 14:57:41 2010 +0000
     1.3 @@ -505,20 +505,45 @@
     1.4  
     1.5      switch (dir->type) {
     1.6      case SDL_HAPTIC_POLAR:
     1.7 -        /* Linux directions are inverted. */
     1.8 -        tmp = (((18000 + dir->dir[0]) % 36000) * 0xFFFF) / 36000;
     1.9 +        /* Linux directions start from south.
    1.10 +        		(and range from 0 to 0xFFFF)
    1.11 +				   Quoting include/linux/input.h, line 926:
    1.12 +				   Direction of the effect is encoded as follows:
    1.13 +						0 deg -> 0x0000 (down)
    1.14 +						90 deg -> 0x4000 (left)
    1.15 +						180 deg -> 0x8000 (up)
    1.16 +						270 deg -> 0xC000 (right)
    1.17 +					*/
    1.18 +        tmp = (((18000 + dir->dir[0]) % 36000) * 0xFFFF) / 36000; // convert to range [0,0xFFFF]
    1.19 +        return (Uint16) tmp;
    1.20 +
    1.21 +	   case SDL_HAPTIC_SPHERICAL:
    1.22 +   			/*
    1.23 +   				We convert to polar, because that's the only supported direction on Linux.
    1.24 +   				The first value of a spherical direction is practically the same as a
    1.25 +   				Polar direction, except that we have to add 90 degrees. It is the angle
    1.26 +   				from EAST {1,0} towards SOUTH {0,1}.
    1.27 +   				--> add 9000
    1.28 +   				--> finally add 18000 and convert to [0,0xFFFF] as in case SDL_HAPTIC_POLAR.
    1.29 +   			*/
    1.30 +		   	tmp = ((dir->dir[0]) + 9000) % 36000;    /* Convert to polars */
    1.31 +        tmp = (((18000 + tmp) % 36000) * 0xFFFF) / 36000; // convert to range [0,0xFFFF]
    1.32          return (Uint16) tmp;
    1.33  
    1.34      case SDL_HAPTIC_CARTESIAN:
    1.35 -        /* We must invert "x" and "y" to go clockwise. */
    1.36 -        f = atan2(dir->dir[0], dir->dir[1]);
    1.37 -        tmp = (int) (f * 18000. / M_PI) % 36000;
    1.38 -        tmp = (tmp * 0xFFFF) / 36000;
    1.39 -        return (Uint16) tmp;
    1.40 -
    1.41 -    case SDL_HAPTIC_SPHERICAL:
    1.42 -        tmp = (36000 - dir->dir[0]) + 27000;    /* Convert to polars */
    1.43 -        tmp = (((18000 + tmp) % 36000) * 0xFFFF) / 36000;
    1.44 +        f = atan2(dir->dir[1], dir->dir[0]);
    1.45 +					/* 
    1.46 +					  atan2 takes the parameters: Y-axis-value and X-axis-value (in that order)
    1.47 +					   - Y-axis-value is the second coordinate (from center to SOUTH)
    1.48 +					   - X-axis-value is the first coordinate (from center to EAST)
    1.49 +						We add 36000, because atan2 also returns negative values. Then we practically
    1.50 +						have the first spherical value. Therefore we proceed as in case
    1.51 +						SDL_HAPTIC_SPHERICAL and add another 9000 to get the polar value.
    1.52 +					  --> add 45000 in total
    1.53 +					  --> finally add 18000 and convert to [0,0xFFFF] as in case SDL_HAPTIC_POLAR.
    1.54 +					*/
    1.55 +				tmp = (((int) (f * 18000. / M_PI)) + 45000) % 36000;
    1.56 +        tmp = (((18000 + tmp) % 36000) * 0xFFFF) / 36000; // convert to range [0,0xFFFF]
    1.57          return (Uint16) tmp;
    1.58  
    1.59      default: