Replaced SDL_HAPTIC_SQUARE with SDL_HAPTIC_LEFTRIGHT.

We needed a bit, so we're hoping no one needs this effect, especially when
it's fairly close to SDL_HAPTIC_SINE, we hope.

SDL_HAPTIC_LEFTRIGHT maps to XInput's functionality, so this removes the SINE
code for the XInput driver to keep things clean.

This also makes the simplified Rumble API use SDL_HAPTIC_LEFTRIGHT if
SDL_HAPTIC_SINE isn't available, to keep XInput working.

When we break the ABI, and can extend the supported capabilities field from
a Uint16, we'll add SDL_HAPTIC_SQUARE back in.

This patch is based on work by Ethan Lee.
This commit is contained in:
Ryan C. Gordon 2013-08-10 13:38:09 -04:00
parent 24097af6ac
commit c35c4a6f18
6 changed files with 146 additions and 62 deletions

View file

@ -303,7 +303,8 @@ DI_EffectCallback(LPCDIEFFECTINFO pei, LPVOID pv)
EFFECT_TEST(GUID_ConstantForce, SDL_HAPTIC_CONSTANT);
EFFECT_TEST(GUID_CustomForce, SDL_HAPTIC_CUSTOM);
EFFECT_TEST(GUID_Sine, SDL_HAPTIC_SINE);
EFFECT_TEST(GUID_Square, SDL_HAPTIC_SQUARE);
/* !!! FIXME: put this back when we have more bits in 2.1 */
/*EFFECT_TEST(GUID_Square, SDL_HAPTIC_SQUARE);*/
EFFECT_TEST(GUID_Triangle, SDL_HAPTIC_TRIANGLE);
EFFECT_TEST(GUID_SawtoothUp, SDL_HAPTIC_SAWTOOTHUP);
EFFECT_TEST(GUID_SawtoothDown, SDL_HAPTIC_SAWTOOTHDOWN);
@ -389,8 +390,7 @@ SDL_SYS_HapticOpenFromXInput(SDL_Haptic * haptic, Uint8 userid)
XINPUT_VIBRATION vibration = { 0, 0 }; /* stop any current vibration */
XINPUTSETSTATE(userid, &vibration);
/* !!! FIXME: we can probably do more than SINE if we figure out how to set up the left and right motors properly. */
haptic->supported = SDL_HAPTIC_SINE;
haptic->supported = SDL_HAPTIC_LEFTRIGHT;
haptic->neffects = 1;
haptic->nplaying = 1;
@ -935,7 +935,8 @@ SDL_SYS_ToDIEFFECT(SDL_Haptic * haptic, DIEFFECT * dest,
break;
case SDL_HAPTIC_SINE:
case SDL_HAPTIC_SQUARE:
/* !!! FIXME: put this back when we have more bits in 2.1 */
/*case SDL_HAPTIC_SQUARE:*/
case SDL_HAPTIC_TRIANGLE:
case SDL_HAPTIC_SAWTOOTHUP:
case SDL_HAPTIC_SAWTOOTHDOWN:
@ -1163,8 +1164,9 @@ SDL_SYS_HapticEffectType(SDL_HapticEffect * effect)
case SDL_HAPTIC_RAMP:
return &GUID_RampForce;
case SDL_HAPTIC_SQUARE:
return &GUID_Square;
/* !!! FIXME: put this back when we have more bits in 2.1 */
/*case SDL_HAPTIC_SQUARE:
return &GUID_Square;*/
case SDL_HAPTIC_SINE:
return &GUID_Sine;
@ -1210,7 +1212,7 @@ SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect,
HRESULT ret;
REFGUID type = SDL_SYS_HapticEffectType(base);
if (type == NULL) {
if ((type == NULL) && (!haptic->hwdata->bXInputHaptic)) {
goto err_hweffect;
}
@ -1225,7 +1227,7 @@ SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect,
SDL_zerop(effect->hweffect);
if (haptic->hwdata->bXInputHaptic) {
SDL_assert(base->type == SDL_HAPTIC_SINE); /* should catch this at higher level */
SDL_assert(base->type == SDL_HAPTIC_LEFTRIGHT); /* should catch this at higher level */
return SDL_SYS_HapticUpdateEffect(haptic, effect, base);
}
@ -1269,20 +1271,14 @@ SDL_SYS_HapticUpdateEffect(SDL_Haptic * haptic,
DIEFFECT temp;
if (haptic->hwdata->bXInputHaptic) {
/* !!! FIXME: this isn't close to right. We only support "sine" effects,
* !!! FIXME: we ignore most of the parameters, and we probably get
* !!! FIXME: the ones we don't ignore wrong, too.
* !!! FIXME: if I had a better understanding of how the two motors
* !!! FIXME: could be used in unison, perhaps I could implement other
* !!! FIXME: effect types?
*/
/* From MSDN:
"Note that the right motor is the high-frequency motor, the left
motor is the low-frequency motor. They do not always need to be
set to the same amount, as they provide different effects." */
XINPUT_VIBRATION *vib = &effect->hweffect->vibration;
SDL_assert(data->type == SDL_HAPTIC_SINE);
vib->wLeftMotorSpeed = vib->wRightMotorSpeed = data->periodic.magnitude * 2;
SDL_assert(data->type == SDL_HAPTIC_LEFTRIGHT);
vib->wLeftMotorSpeed = data->leftright.large_magnitude;
vib->wRightMotorSpeed = data->leftright.small_magnitude;
return 0;
}
@ -1333,9 +1329,9 @@ SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect,
if (haptic->hwdata->bXInputHaptic) {
XINPUT_VIBRATION *vib = &effect->hweffect->vibration;
SDL_assert(effect->effect.type == SDL_HAPTIC_SINE); /* should catch this at higher level */
SDL_assert(effect->effect.type == SDL_HAPTIC_LEFTRIGHT); /* should catch this at higher level */
SDL_LockMutex(haptic->hwdata->mutex);
haptic->hwdata->stopTicks = SDL_GetTicks() + (effect->effect.periodic.length * iterations);
haptic->hwdata->stopTicks = SDL_GetTicks() + (effect->effect.leftright.length * iterations);
SDL_UnlockMutex(haptic->hwdata->mutex);
return (XINPUTSETSTATE(haptic->hwdata->userid, vib) == ERROR_SUCCESS) ? 0 : -1;
}