Fixed initializing the haptic system from an XInput joystick

Thanks to Franz Schrober for the fix inspiration.
This commit is contained in:
Sam Lantinga 2013-06-27 10:59:30 -07:00
parent 86e40a29d3
commit bc51b6f628

View file

@ -53,7 +53,7 @@ struct haptic_hwdata
{ {
LPDIRECTINPUTDEVICE8 device; LPDIRECTINPUTDEVICE8 device;
DWORD axes[3]; /* Axes to use. */ DWORD axes[3]; /* Axes to use. */
int is_joystick; /* Device is loaded as joystick. */ SDL_bool is_joystick; /* Device is loaded as joystick. */
Uint8 bXInputHaptic; /* Supports force feedback via XInput. */ Uint8 bXInputHaptic; /* Supports force feedback via XInput. */
Uint8 userid; /* XInput userid index for this joystick */ Uint8 userid; /* XInput userid index for this joystick */
}; };
@ -92,7 +92,8 @@ static int DI_GUIDIsSame(const GUID * a, const GUID * b);
static int SDL_SYS_HapticOpenFromInstance(SDL_Haptic * haptic, static int SDL_SYS_HapticOpenFromInstance(SDL_Haptic * haptic,
DIDEVICEINSTANCE instance); DIDEVICEINSTANCE instance);
static int SDL_SYS_HapticOpenFromDevice8(SDL_Haptic * haptic, static int SDL_SYS_HapticOpenFromDevice8(SDL_Haptic * haptic,
LPDIRECTINPUTDEVICE8 device8); LPDIRECTINPUTDEVICE8 device8,
SDL_bool is_joystick);
static int SDL_SYS_HapticOpenFromXInput(SDL_Haptic * haptic, Uint8 userid); static int SDL_SYS_HapticOpenFromXInput(SDL_Haptic * haptic, Uint8 userid);
static DWORD DIGetTriggerButton(Uint16 button); static DWORD DIGetTriggerButton(Uint16 button);
static int SDL_SYS_SetDirection(DIEFFECT * effect, SDL_HapticDirection * dir, static int SDL_SYS_SetDirection(DIEFFECT * effect, SDL_HapticDirection * dir,
@ -342,51 +343,34 @@ SDL_SYS_HapticOpenFromInstance(SDL_Haptic * haptic, DIDEVICEINSTANCE instance)
HRESULT ret; HRESULT ret;
int ret2; int ret2;
LPDIRECTINPUTDEVICE8 device; LPDIRECTINPUTDEVICE8 device;
LPDIRECTINPUTDEVICE8 device8;
/* Allocate the hwdata */
haptic->hwdata = (struct haptic_hwdata *)
SDL_malloc(sizeof(*haptic->hwdata));
if (haptic->hwdata == NULL) {
SDL_OutOfMemory();
goto creat_err;
}
SDL_memset(haptic->hwdata, 0, sizeof(*haptic->hwdata));
/* Open the device */ /* Open the device */
ret = IDirectInput8_CreateDevice(dinput, &instance.guidInstance, ret = IDirectInput8_CreateDevice(dinput, &instance.guidInstance,
&device, NULL); &device, NULL);
if (FAILED(ret)) { if (FAILED(ret)) {
DI_SetError("Creating DirectInput device", ret); DI_SetError("Creating DirectInput device", ret);
goto creat_err; return -1;
} }
/* Now get the IDirectInputDevice8 interface, instead. */ /* Now get the IDirectInputDevice8 interface, instead. */
ret = IDirectInputDevice8_QueryInterface(device, ret = IDirectInputDevice8_QueryInterface(device,
&IID_IDirectInputDevice8, &IID_IDirectInputDevice8,
(LPVOID *) & haptic->hwdata-> (LPVOID *) &device8);
device);
/* Done with the temporary one now. */ /* Done with the temporary one now. */
IDirectInputDevice8_Release(device); IDirectInputDevice8_Release(device);
if (FAILED(ret)) { if (FAILED(ret)) {
DI_SetError("Querying DirectInput interface", ret); DI_SetError("Querying DirectInput interface", ret);
goto creat_err; return -1;
} }
ret2 = SDL_SYS_HapticOpenFromDevice8(haptic, haptic->hwdata->device); ret2 = SDL_SYS_HapticOpenFromDevice8(haptic, device8, SDL_FALSE);
if (ret2 < 0) { if (ret2 < 0) {
goto query_err; IDirectInputDevice8_Release(device8);
return -1;
} }
return 0; return 0;
query_err:
IDirectInputDevice8_Release(haptic->hwdata->device);
creat_err:
if (haptic->hwdata != NULL) {
SDL_free(haptic->hwdata);
haptic->hwdata = NULL;
}
return -1;
} }
static int static int
@ -437,13 +421,21 @@ SDL_SYS_HapticOpenFromXInput(SDL_Haptic * haptic, Uint8 userid)
*/ */
static int static int
SDL_SYS_HapticOpenFromDevice8(SDL_Haptic * haptic, SDL_SYS_HapticOpenFromDevice8(SDL_Haptic * haptic,
LPDIRECTINPUTDEVICE8 device8) LPDIRECTINPUTDEVICE8 device8, SDL_bool is_joystick)
{ {
HRESULT ret; HRESULT ret;
DIPROPDWORD dipdw; DIPROPDWORD dipdw;
/* Allocate the hwdata */
haptic->hwdata = (struct haptic_hwdata *)SDL_malloc(sizeof(*haptic->hwdata));
if (haptic->hwdata == NULL) {
return SDL_OutOfMemory();
}
SDL_memset(haptic->hwdata, 0, sizeof(*haptic->hwdata));
/* We'll use the device8 from now on. */ /* We'll use the device8 from now on. */
haptic->hwdata->device = device8; haptic->hwdata->device = device8;
haptic->hwdata->is_joystick = is_joystick;
/* Grab it exclusively to use force feedback stuff. */ /* Grab it exclusively to use force feedback stuff. */
ret = IDirectInputDevice8_SetCooperativeLevel(haptic->hwdata->device, ret = IDirectInputDevice8_SetCooperativeLevel(haptic->hwdata->device,
@ -657,49 +649,24 @@ SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick)
if ((SDL_hapticlist[i].bXInputHaptic) && (SDL_hapticlist[i].userid == userid)) { if ((SDL_hapticlist[i].bXInputHaptic) && (SDL_hapticlist[i].userid == userid)) {
SDL_assert(joystick->hwdata->bXInputHaptic); SDL_assert(joystick->hwdata->bXInputHaptic);
haptic->index = i; haptic->index = i;
break; return SDL_SYS_HapticOpenFromXInput(haptic, SDL_hapticlist[haptic->index].userid);
} }
} }
} else { } else {
for (i=0; i<SDL_numhaptics; i++) { for (i=0; i<SDL_numhaptics; i++) {
idret = IDirectInputDevice8_GetDeviceInfo(joystick->hwdata->InputDevice, idret = IDirectInputDevice8_GetDeviceInfo(joystick->hwdata->InputDevice, &joy_instance);
&joy_instance);
if (FAILED(idret)) { if (FAILED(idret)) {
return -1; return -1;
} }
if (DI_GUIDIsSame(&SDL_hapticlist[i].instance.guidInstance, if (DI_GUIDIsSame(&SDL_hapticlist[i].instance.guidInstance,
&joy_instance.guidInstance)) { &joy_instance.guidInstance)) {
haptic->index = i; haptic->index = i;
break; return SDL_SYS_HapticOpenFromDevice8(haptic, joystick->hwdata->InputDevice, SDL_TRUE);
} }
} }
} }
if (i >= SDL_numhaptics) { /* No match to our haptic list */
return -1; return -1;
}
/* Allocate the hwdata */
haptic->hwdata = (struct haptic_hwdata *)
SDL_malloc(sizeof(*haptic->hwdata));
if (haptic->hwdata == NULL) {
return SDL_OutOfMemory();
}
SDL_memset(haptic->hwdata, 0, sizeof(*haptic->hwdata));
/* Now open the device. */
if (!joystick->hwdata->bXInputHaptic) {
ret = SDL_SYS_HapticOpenFromDevice8(haptic, joystick->hwdata->InputDevice);
if (ret < 0) {
return -1;
}
}
/* It's using the joystick device. */
haptic->hwdata->is_joystick = 1;
haptic->hwdata->bXInputHaptic = joystick->hwdata->bXInputHaptic;
haptic->hwdata->userid = joystick->hwdata->userid;
return 0;
} }