From 5f9ea7edebf99368d8ccb668abfae4cfeb412cd6 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 17 Sep 2014 14:49:36 -0400 Subject: [PATCH] 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 | 2 +- src/haptic/darwin/SDL_syshaptic.c | 6 ++++-- src/haptic/windows/SDL_dinputhaptic.c | 6 ++++-- test/testhaptic.c | 3 ++- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/include/SDL_haptic.h b/include/SDL_haptic.h index 9c4b4271f8f39..569c635edd072 100644 --- a/include/SDL_haptic.h +++ b/include/SDL_haptic.h @@ -553,7 +553,7 @@ typedef struct SDL_HapticPeriodic /* Periodic */ Uint16 period; /**< Period of the wave. */ - Sint16 magnitude; /**< Peak value. */ + Sint16 magnitude; /**< Peak value; if negative, equivalent to 180 degrees extra phase shift. */ Sint16 offset; /**< Mean value of the wave. */ Uint16 phase; /**< Horizontal shift given by hundredth of a degree. */ diff --git a/src/haptic/darwin/SDL_syshaptic.c b/src/haptic/darwin/SDL_syshaptic.c index dc9416ba49a8e..6d85bf0edcc70 100644 --- a/src/haptic/darwin/SDL_syshaptic.c +++ b/src/haptic/darwin/SDL_syshaptic.c @@ -23,6 +23,7 @@ #ifdef SDL_HAPTIC_IOKIT #include "SDL_assert.h" +#include "SDL_stdinc.h" #include "SDL_haptic.h" #include "../SDL_syshaptic.h" #include "SDL_joystick.h" @@ -872,9 +873,10 @@ SDL_SYS_ToFFEFFECT(SDL_Haptic * haptic, FFEFFECT * dest, SDL_HapticEffect * src) SDL_memset(periodic, 0, sizeof(FFPERIODIC)); /* Specifics */ - periodic->dwMagnitude = CONVERT(hap_periodic->magnitude); + periodic->dwMagnitude = CONVERT(SDL_abs(hap_periodic->magnitude)); periodic->lOffset = CONVERT(hap_periodic->offset); - periodic->dwPhase = hap_periodic->phase; + periodic->dwPhase = + (hap_periodic->phase + (hap_periodic->magnitude < 0 ? 18000 : 0)) % 36000; periodic->dwPeriod = hap_periodic->period * 1000; dest->cbTypeSpecificParams = sizeof(FFPERIODIC); dest->lpvTypeSpecificParams = periodic; diff --git a/src/haptic/windows/SDL_dinputhaptic.c b/src/haptic/windows/SDL_dinputhaptic.c index 35edcb3e9bbdc..9ff46a9d4f1ca 100644 --- a/src/haptic/windows/SDL_dinputhaptic.c +++ b/src/haptic/windows/SDL_dinputhaptic.c @@ -21,6 +21,7 @@ #include "../../SDL_internal.h" #include "SDL_error.h" +#include "SDL_stdinc.h" #include "SDL_haptic.h" #include "SDL_timer.h" #include "SDL_windowshaptic_c.h" @@ -714,9 +715,10 @@ SDL_SYS_ToDIEFFECT(SDL_Haptic * haptic, DIEFFECT * dest, SDL_memset(periodic, 0, sizeof(DIPERIODIC)); /* Specifics */ - periodic->dwMagnitude = CONVERT(hap_periodic->magnitude); + periodic->dwMagnitude = CONVERT(SDL_abs(hap_periodic->magnitude)); periodic->lOffset = CONVERT(hap_periodic->offset); - periodic->dwPhase = hap_periodic->phase; + periodic->dwPhase = + (hap_periodic->phase + (hap_periodic->magnitude < 0 ? 18000 : 0)) % 36000; periodic->dwPeriod = hap_periodic->period * 1000; dest->cbTypeSpecificParams = sizeof(DIPERIODIC); dest->lpvTypeSpecificParams = periodic; diff --git a/test/testhaptic.c b/test/testhaptic.c index 2efd214818b98..ac8ab4158f835 100644 --- a/test/testhaptic.c +++ b/test/testhaptic.c @@ -122,7 +122,8 @@ main(int argc, char **argv) SDL_Log(" effect %d: Sine Wave\n", nefx); efx[nefx].type = SDL_HAPTIC_SINE; efx[nefx].periodic.period = 1000; - efx[nefx].periodic.magnitude = 0x4000; + efx[nefx].periodic.magnitude = -0x2000; /* Negative magnitude and ... */ + efx[nefx].periodic.phase = 18000; /* ... 180 degrees phase shift => cancel eachother */ efx[nefx].periodic.length = 5000; efx[nefx].periodic.attack_length = 1000; efx[nefx].periodic.fade_length = 1000;