Haptic: Deal with negative periodic magnitudes (thanks, Elias!).
authorRyan C. Gordon <icculus@icculus.org>
Wed, 17 Sep 2014 14:49:36 -0400
changeset 91476bf589c8d549
parent 9146 dbef1f283c3f
child 9148 e9b6e9f4a10e
Haptic: Deal with negative periodic magnitudes (thanks, Elias!).

A negative periodic magnitude doesn't exist in Windows' and MacOS' FF APIs

The periodic magnitude parameter of the SDL Haptic API is based on the Linux
FF API, so it means they are not directly compatible:
'dwMagnitude' is a 'DWORD', which is unsigned.

Fixes Bugzilla #2701.
include/SDL_haptic.h
src/haptic/darwin/SDL_syshaptic.c
src/haptic/windows/SDL_dinputhaptic.c
test/testhaptic.c
     1.1 --- a/include/SDL_haptic.h	Wed Sep 17 14:47:42 2014 -0400
     1.2 +++ b/include/SDL_haptic.h	Wed Sep 17 14:49:36 2014 -0400
     1.3 @@ -553,7 +553,7 @@
     1.4  
     1.5      /* Periodic */
     1.6      Uint16 period;      /**< Period of the wave. */
     1.7 -    Sint16 magnitude;   /**< Peak value. */
     1.8 +    Sint16 magnitude;   /**< Peak value; if negative, equivalent to 180 degrees extra phase shift. */
     1.9      Sint16 offset;      /**< Mean value of the wave. */
    1.10      Uint16 phase;       /**< Horizontal shift given by hundredth of a degree. */
    1.11  
     2.1 --- a/src/haptic/darwin/SDL_syshaptic.c	Wed Sep 17 14:47:42 2014 -0400
     2.2 +++ b/src/haptic/darwin/SDL_syshaptic.c	Wed Sep 17 14:49:36 2014 -0400
     2.3 @@ -23,6 +23,7 @@
     2.4  #ifdef SDL_HAPTIC_IOKIT
     2.5  
     2.6  #include "SDL_assert.h"
     2.7 +#include "SDL_stdinc.h"
     2.8  #include "SDL_haptic.h"
     2.9  #include "../SDL_syshaptic.h"
    2.10  #include "SDL_joystick.h"
    2.11 @@ -872,9 +873,10 @@
    2.12          SDL_memset(periodic, 0, sizeof(FFPERIODIC));
    2.13  
    2.14          /* Specifics */
    2.15 -        periodic->dwMagnitude = CONVERT(hap_periodic->magnitude);
    2.16 +        periodic->dwMagnitude = CONVERT(SDL_abs(hap_periodic->magnitude));
    2.17          periodic->lOffset = CONVERT(hap_periodic->offset);
    2.18 -        periodic->dwPhase = hap_periodic->phase;
    2.19 +        periodic->dwPhase = 
    2.20 +                (hap_periodic->phase + (hap_periodic->magnitude < 0 ? 18000 : 0)) % 36000;
    2.21          periodic->dwPeriod = hap_periodic->period * 1000;
    2.22          dest->cbTypeSpecificParams = sizeof(FFPERIODIC);
    2.23          dest->lpvTypeSpecificParams = periodic;
     3.1 --- a/src/haptic/windows/SDL_dinputhaptic.c	Wed Sep 17 14:47:42 2014 -0400
     3.2 +++ b/src/haptic/windows/SDL_dinputhaptic.c	Wed Sep 17 14:49:36 2014 -0400
     3.3 @@ -21,6 +21,7 @@
     3.4  #include "../../SDL_internal.h"
     3.5  
     3.6  #include "SDL_error.h"
     3.7 +#include "SDL_stdinc.h"
     3.8  #include "SDL_haptic.h"
     3.9  #include "SDL_timer.h"
    3.10  #include "SDL_windowshaptic_c.h"
    3.11 @@ -714,9 +715,10 @@
    3.12          SDL_memset(periodic, 0, sizeof(DIPERIODIC));
    3.13  
    3.14          /* Specifics */
    3.15 -        periodic->dwMagnitude = CONVERT(hap_periodic->magnitude);
    3.16 +        periodic->dwMagnitude = CONVERT(SDL_abs(hap_periodic->magnitude));
    3.17          periodic->lOffset = CONVERT(hap_periodic->offset);
    3.18 -        periodic->dwPhase = hap_periodic->phase;
    3.19 +        periodic->dwPhase = 
    3.20 +                (hap_periodic->phase + (hap_periodic->magnitude < 0 ? 18000 : 0)) % 36000;
    3.21          periodic->dwPeriod = hap_periodic->period * 1000;
    3.22          dest->cbTypeSpecificParams = sizeof(DIPERIODIC);
    3.23          dest->lpvTypeSpecificParams = periodic;
     4.1 --- a/test/testhaptic.c	Wed Sep 17 14:47:42 2014 -0400
     4.2 +++ b/test/testhaptic.c	Wed Sep 17 14:49:36 2014 -0400
     4.3 @@ -122,7 +122,8 @@
     4.4          SDL_Log("   effect %d: Sine Wave\n", nefx);
     4.5          efx[nefx].type = SDL_HAPTIC_SINE;
     4.6          efx[nefx].periodic.period = 1000;
     4.7 -        efx[nefx].periodic.magnitude = 0x4000;
     4.8 +        efx[nefx].periodic.magnitude = -0x2000;    /* Negative magnitude and ...                      */
     4.9 +        efx[nefx].periodic.phase = 18000;          /* ... 180 degrees phase shift => cancel eachother */
    4.10          efx[nefx].periodic.length = 5000;
    4.11          efx[nefx].periodic.attack_length = 1000;
    4.12          efx[nefx].periodic.fade_length = 1000;