mirror of
https://github.com/Relintai/sdl2_frt.git
synced 2024-12-29 20:27:12 +01:00
Wired up haptic hotplugging for Windows DirectInput/XInput code.
This commit is contained in:
parent
9cf8c49c39
commit
e42d46b463
@ -33,12 +33,12 @@
|
|||||||
#include "../../joystick/SDL_sysjoystick.h" /* For the real SDL_Joystick */
|
#include "../../joystick/SDL_sysjoystick.h" /* For the real SDL_Joystick */
|
||||||
#include "../../joystick/windows/SDL_dxjoystick_c.h" /* For joystick hwdata */
|
#include "../../joystick/windows/SDL_dxjoystick_c.h" /* For joystick hwdata */
|
||||||
|
|
||||||
#define MAX_HAPTICS 32
|
#include "SDL_syshaptic_c.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* List of available haptic devices.
|
* List of available haptic devices.
|
||||||
*/
|
*/
|
||||||
static struct
|
typedef struct SDL_hapticlist_item
|
||||||
{
|
{
|
||||||
DIDEVICEINSTANCE instance;
|
DIDEVICEINSTANCE instance;
|
||||||
char *name;
|
char *name;
|
||||||
@ -46,7 +46,8 @@ static struct
|
|||||||
DIDEVCAPS capabilities;
|
DIDEVCAPS capabilities;
|
||||||
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 */
|
||||||
} SDL_hapticlist[MAX_HAPTICS];
|
struct SDL_hapticlist_item *next;
|
||||||
|
} SDL_hapticlist_item;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -83,7 +84,9 @@ struct haptic_hweffect
|
|||||||
static SDL_bool coinitialized = SDL_FALSE;
|
static SDL_bool coinitialized = SDL_FALSE;
|
||||||
static LPDIRECTINPUT8 dinput = NULL;
|
static LPDIRECTINPUT8 dinput = NULL;
|
||||||
static SDL_bool loaded_xinput = SDL_FALSE;
|
static SDL_bool loaded_xinput = SDL_FALSE;
|
||||||
|
static SDL_hapticlist_item *SDL_hapticlist = NULL;
|
||||||
|
static SDL_hapticlist_item *SDL_hapticlist_tail = NULL;
|
||||||
|
static int numhaptics = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* External stuff.
|
* External stuff.
|
||||||
@ -101,7 +104,7 @@ static int SDL_SYS_HapticOpenFromInstance(SDL_Haptic * haptic,
|
|||||||
static int SDL_SYS_HapticOpenFromDevice8(SDL_Haptic * haptic,
|
static int SDL_SYS_HapticOpenFromDevice8(SDL_Haptic * haptic,
|
||||||
LPDIRECTINPUTDEVICE8 device8,
|
LPDIRECTINPUTDEVICE8 device8,
|
||||||
SDL_bool is_joystick);
|
SDL_bool is_joystick);
|
||||||
static int SDL_SYS_HapticOpenFromXInput(SDL_Haptic * haptic, Uint8 userid);
|
static int SDL_SYS_HapticOpenFromXInput(SDL_Haptic * haptic, const 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,
|
||||||
int naxes);
|
int naxes);
|
||||||
@ -155,11 +158,6 @@ SDL_SYS_HapticInit(void)
|
|||||||
return SDL_SetError("Haptic: SubSystem already open.");
|
return SDL_SetError("Haptic: SubSystem already open.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear all the memory. */
|
|
||||||
SDL_memset(SDL_hapticlist, 0, sizeof(SDL_hapticlist));
|
|
||||||
|
|
||||||
SDL_numhaptics = 0;
|
|
||||||
|
|
||||||
ret = WIN_CoInitialize();
|
ret = WIN_CoInitialize();
|
||||||
if (FAILED(ret)) {
|
if (FAILED(ret)) {
|
||||||
return DI_SetError("Coinitialize", ret);
|
return DI_SetError("Coinitialize", ret);
|
||||||
@ -205,81 +203,260 @@ SDL_SYS_HapticInit(void)
|
|||||||
|
|
||||||
if (loaded_xinput) {
|
if (loaded_xinput) {
|
||||||
DWORD i;
|
DWORD i;
|
||||||
const SDL_bool bIs14OrLater = (SDL_XInputVersion >= ((1<<16)|4));
|
for (i = 0; i < SDL_XINPUT_MAX_DEVICES; i++) {
|
||||||
|
XInputHaptic_MaybeAddDevice(i);
|
||||||
for (i = 0; (i < SDL_XINPUT_MAX_DEVICES) && (SDL_numhaptics < MAX_HAPTICS); i++) {
|
|
||||||
XINPUT_CAPABILITIES caps;
|
|
||||||
if (XINPUTGETCAPABILITIES(i, XINPUT_FLAG_GAMEPAD, &caps) == ERROR_SUCCESS) {
|
|
||||||
if ((!bIs14OrLater) || (caps.Flags & XINPUT_CAPS_FFB_SUPPORTED)) {
|
|
||||||
/* !!! FIXME: I'm not bothering to query for a real name right now. */
|
|
||||||
char buf[64];
|
|
||||||
SDL_snprintf(buf, sizeof (buf), "XInput Controller #%u", i+1);
|
|
||||||
SDL_hapticlist[SDL_numhaptics].name = SDL_strdup(buf);
|
|
||||||
SDL_hapticlist[SDL_numhaptics].bXInputHaptic = 1;
|
|
||||||
SDL_hapticlist[SDL_numhaptics].userid = (Uint8) i;
|
|
||||||
SDL_numhaptics++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return SDL_numhaptics;
|
return numhaptics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
DirectInputHaptic_MaybeAddDevice(const DIDEVICEINSTANCE * pdidInstance)
|
||||||
|
{
|
||||||
|
HRESULT ret;
|
||||||
|
LPDIRECTINPUTDEVICE8 device;
|
||||||
|
const DWORD needflags = DIDC_ATTACHED | DIDC_FORCEFEEDBACK;
|
||||||
|
DIDEVCAPS capabilities;
|
||||||
|
SDL_hapticlist_item *item = NULL;
|
||||||
|
|
||||||
|
/* Make sure we don't already have it */
|
||||||
|
for (item = SDL_hapticlist; item; item = item->next) {
|
||||||
|
if ( (!item->bXInputHaptic) && (SDL_memcmp(&item->instance, pdidInstance, sizeof (*pdidInstance)) == 0) ) {
|
||||||
|
return -1; /* Already added */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open the device */
|
||||||
|
ret = IDirectInput8_CreateDevice(dinput, &pdidInstance->guidInstance, &device, NULL);
|
||||||
|
if (FAILED(ret)) {
|
||||||
|
/* DI_SetError("Creating DirectInput device",ret); */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get capabilities. */
|
||||||
|
SDL_zero(capabilities);
|
||||||
|
capabilities.dwSize = sizeof (DIDEVCAPS);
|
||||||
|
ret = IDirectInputDevice8_GetCapabilities(device, &capabilities);
|
||||||
|
IDirectInputDevice8_Release(device);
|
||||||
|
if (FAILED(ret)) {
|
||||||
|
/* DI_SetError("Getting device capabilities",ret); */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((capabilities.dwFlags & needflags) != needflags) {
|
||||||
|
return -1; /* not a device we can use. */
|
||||||
|
}
|
||||||
|
|
||||||
|
item = (SDL_hapticlist_item *)SDL_malloc( sizeof(SDL_hapticlist_item));
|
||||||
|
if (item == NULL) {
|
||||||
|
return SDL_OutOfMemory();
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_zerop(item);
|
||||||
|
|
||||||
|
item->name = WIN_StringToUTF8(pdidInstance->tszProductName);
|
||||||
|
if (!item->name) {
|
||||||
|
SDL_free(item);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the instance over, useful for creating devices. */
|
||||||
|
SDL_memcpy(&item->instance, pdidInstance, sizeof (DIDEVICEINSTANCE));
|
||||||
|
SDL_memcpy(&item->capabilities, &capabilities, sizeof (capabilities));
|
||||||
|
|
||||||
|
if (SDL_hapticlist_tail == NULL) {
|
||||||
|
SDL_hapticlist = SDL_hapticlist_tail = item;
|
||||||
|
} else {
|
||||||
|
SDL_hapticlist_tail->next = item;
|
||||||
|
SDL_hapticlist_tail = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Device has been added. */
|
||||||
|
++numhaptics;
|
||||||
|
|
||||||
|
return numhaptics;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
DirectInputHaptic_MaybeRemoveDevice(const DIDEVICEINSTANCE * pdidInstance)
|
||||||
|
{
|
||||||
|
SDL_hapticlist_item *item;
|
||||||
|
SDL_hapticlist_item *prev = NULL;
|
||||||
|
|
||||||
|
for (item = SDL_hapticlist; item != NULL; item = item->next) {
|
||||||
|
if ( (!item->bXInputHaptic) && (SDL_memcmp(&item->instance, pdidInstance, sizeof (*pdidInstance)) == 0) ) {
|
||||||
|
/* found it, remove it. */
|
||||||
|
const int retval = item->haptic ? item->haptic->index : -1;
|
||||||
|
if (prev != NULL) {
|
||||||
|
prev->next = item->next;
|
||||||
|
} else {
|
||||||
|
SDL_assert(SDL_hapticlist == item);
|
||||||
|
SDL_hapticlist = item->next;
|
||||||
|
}
|
||||||
|
if (item == SDL_hapticlist_tail) {
|
||||||
|
SDL_hapticlist_tail = prev;
|
||||||
|
}
|
||||||
|
--numhaptics;
|
||||||
|
/* !!! TODO: Send a haptic remove event? */
|
||||||
|
SDL_free(item);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
prev = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
XInputHaptic_MaybeAddDevice(const DWORD dwUserid)
|
||||||
|
{
|
||||||
|
const Uint8 userid = (Uint8) dwUserid;
|
||||||
|
XINPUT_CAPABILITIES caps;
|
||||||
|
const SDL_bool bIs14OrLater = (SDL_XInputVersion >= ((1<<16)|4));
|
||||||
|
SDL_hapticlist_item *item;
|
||||||
|
|
||||||
|
if ((!loaded_xinput) || (dwUserid >= SDL_XINPUT_MAX_DEVICES)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure we don't already have it */
|
||||||
|
for (item = SDL_hapticlist; item; item = item->next) {
|
||||||
|
if ((item->bXInputHaptic) && (item->userid == userid)) {
|
||||||
|
return -1; /* Already added */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (XINPUTGETCAPABILITIES(dwUserid, XINPUT_FLAG_GAMEPAD, &caps) != ERROR_SUCCESS) {
|
||||||
|
return -1; /* maybe controller isn't plugged in. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* XInput < 1.4 is probably only for original XBox360 controllers,
|
||||||
|
which don't offer the flag, and always have force feedback */
|
||||||
|
if ( (bIs14OrLater) && ((caps.Flags & XINPUT_CAPS_FFB_SUPPORTED) == 0) ) {
|
||||||
|
return -1; /* no force feedback on this device. */
|
||||||
|
}
|
||||||
|
|
||||||
|
item = (SDL_hapticlist_item *)SDL_malloc( sizeof(SDL_hapticlist_item));
|
||||||
|
if (item == NULL) {
|
||||||
|
return SDL_OutOfMemory();
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_zerop(item);
|
||||||
|
|
||||||
|
/* !!! FIXME: I'm not bothering to query for a real name right now (can we even?) */
|
||||||
|
{
|
||||||
|
char buf[64];
|
||||||
|
SDL_snprintf(buf, sizeof (buf), "XInput Controller #%u", (unsigned int) (userid+1));
|
||||||
|
item->name = SDL_strdup(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!item->name) {
|
||||||
|
SDL_free(item);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the instance over, useful for creating devices. */
|
||||||
|
item->bXInputHaptic = 1;
|
||||||
|
item->userid = userid;
|
||||||
|
|
||||||
|
if (SDL_hapticlist_tail == NULL) {
|
||||||
|
SDL_hapticlist = SDL_hapticlist_tail = item;
|
||||||
|
} else {
|
||||||
|
SDL_hapticlist_tail->next = item;
|
||||||
|
SDL_hapticlist_tail = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Device has been added. */
|
||||||
|
++numhaptics;
|
||||||
|
|
||||||
|
return numhaptics;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
XInputHaptic_MaybeRemoveDevice(const DWORD dwUserid)
|
||||||
|
{
|
||||||
|
const Uint8 userid = (Uint8) dwUserid;
|
||||||
|
SDL_hapticlist_item *item;
|
||||||
|
SDL_hapticlist_item *prev = NULL;
|
||||||
|
|
||||||
|
if ((!loaded_xinput) || (dwUserid >= SDL_XINPUT_MAX_DEVICES)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (item = SDL_hapticlist; item != NULL; item = item->next) {
|
||||||
|
if ((item->bXInputHaptic) && (item->userid == userid)) {
|
||||||
|
/* found it, remove it. */
|
||||||
|
const int retval = item->haptic ? item->haptic->index : -1;
|
||||||
|
if (prev != NULL) {
|
||||||
|
prev->next = item->next;
|
||||||
|
} else {
|
||||||
|
SDL_assert(SDL_hapticlist == item);
|
||||||
|
SDL_hapticlist = item->next;
|
||||||
|
}
|
||||||
|
if (item == SDL_hapticlist_tail) {
|
||||||
|
SDL_hapticlist_tail = prev;
|
||||||
|
}
|
||||||
|
--numhaptics;
|
||||||
|
/* !!! TODO: Send a haptic remove event? */
|
||||||
|
SDL_free(item);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
prev = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Callback to find the haptic devices.
|
* Callback to find the haptic devices.
|
||||||
*/
|
*/
|
||||||
static BOOL CALLBACK
|
static BOOL CALLBACK
|
||||||
EnumHapticsCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext)
|
EnumHapticsCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext)
|
||||||
{
|
{
|
||||||
HRESULT ret;
|
(void) pContext;
|
||||||
LPDIRECTINPUTDEVICE8 device;
|
DirectInputHaptic_MaybeAddDevice(pdidInstance);
|
||||||
|
return DIENUM_CONTINUE; /* continue enumerating */
|
||||||
/* Copy the instance over, useful for creating devices. */
|
|
||||||
SDL_memcpy(&SDL_hapticlist[SDL_numhaptics].instance, pdidInstance,
|
|
||||||
sizeof(DIDEVICEINSTANCE));
|
|
||||||
|
|
||||||
/* Open the device */
|
|
||||||
ret = IDirectInput8_CreateDevice(dinput, &pdidInstance->guidInstance,
|
|
||||||
&device, NULL);
|
|
||||||
if (FAILED(ret)) {
|
|
||||||
/* DI_SetError("Creating DirectInput device",ret); */
|
|
||||||
return DIENUM_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get capabilities. */
|
|
||||||
SDL_hapticlist[SDL_numhaptics].capabilities.dwSize = sizeof(DIDEVCAPS);
|
|
||||||
ret = IDirectInputDevice8_GetCapabilities(device,
|
|
||||||
&SDL_hapticlist[SDL_numhaptics].
|
|
||||||
capabilities);
|
|
||||||
if (FAILED(ret)) {
|
|
||||||
/* DI_SetError("Getting device capabilities",ret); */
|
|
||||||
IDirectInputDevice8_Release(device);
|
|
||||||
return DIENUM_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy the name */
|
|
||||||
SDL_hapticlist[SDL_numhaptics].name = WIN_StringToUTF8(SDL_hapticlist[SDL_numhaptics].instance.tszProductName);
|
|
||||||
|
|
||||||
/* Close up device and count it. */
|
|
||||||
IDirectInputDevice8_Release(device);
|
|
||||||
SDL_numhaptics++;
|
|
||||||
|
|
||||||
/* Watch out for hard limit. */
|
|
||||||
if (SDL_numhaptics >= MAX_HAPTICS)
|
|
||||||
return DIENUM_STOP;
|
|
||||||
|
|
||||||
return DIENUM_CONTINUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
SDL_SYS_NumHaptics()
|
||||||
|
{
|
||||||
|
return numhaptics;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SDL_hapticlist_item *
|
||||||
|
HapticByDevIndex(int device_index)
|
||||||
|
{
|
||||||
|
SDL_hapticlist_item *item = SDL_hapticlist;
|
||||||
|
|
||||||
|
if ((device_index < 0) || (device_index >= numhaptics)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (device_index > 0) {
|
||||||
|
SDL_assert(item != NULL);
|
||||||
|
device_index--;
|
||||||
|
item = item->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return the name of a haptic device, does not need to be opened.
|
* Return the name of a haptic device, does not need to be opened.
|
||||||
*/
|
*/
|
||||||
const char *
|
const char *
|
||||||
SDL_SYS_HapticName(int index)
|
SDL_SYS_HapticName(int index)
|
||||||
{
|
{
|
||||||
return SDL_hapticlist[index].name;
|
SDL_hapticlist_item *item = HapticByDevIndex(index);
|
||||||
|
return item->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -384,7 +561,7 @@ SDL_SYS_HapticOpenFromInstance(SDL_Haptic * haptic, DIDEVICEINSTANCE instance)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
SDL_SYS_HapticOpenFromXInput(SDL_Haptic * haptic, Uint8 userid)
|
SDL_SYS_HapticOpenFromXInput(SDL_Haptic *haptic, const Uint8 userid)
|
||||||
{
|
{
|
||||||
char threadName[32];
|
char threadName[32];
|
||||||
XINPUT_VIBRATION vibration = { 0, 0 }; /* stop any current vibration */
|
XINPUT_VIBRATION vibration = { 0, 0 }; /* stop any current vibration */
|
||||||
@ -595,11 +772,8 @@ SDL_SYS_HapticOpenFromDevice8(SDL_Haptic * haptic,
|
|||||||
int
|
int
|
||||||
SDL_SYS_HapticOpen(SDL_Haptic * haptic)
|
SDL_SYS_HapticOpen(SDL_Haptic * haptic)
|
||||||
{
|
{
|
||||||
if (SDL_hapticlist[haptic->index].bXInputHaptic) {
|
SDL_hapticlist_item *item = HapticByDevIndex(haptic->index);
|
||||||
return SDL_SYS_HapticOpenFromXInput(haptic, SDL_hapticlist[haptic->index].userid);
|
return (item->bXInputHaptic) ? SDL_SYS_HapticOpenFromXInput(haptic, item->userid) : SDL_SYS_HapticOpenFromInstance(haptic, item->instance);
|
||||||
}
|
|
||||||
|
|
||||||
return SDL_SYS_HapticOpenFromInstance(haptic, SDL_hapticlist[haptic->index].instance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -609,13 +783,16 @@ SDL_SYS_HapticOpen(SDL_Haptic * haptic)
|
|||||||
int
|
int
|
||||||
SDL_SYS_HapticMouse(void)
|
SDL_SYS_HapticMouse(void)
|
||||||
{
|
{
|
||||||
int i;
|
SDL_hapticlist_item *item;
|
||||||
|
int index = numhaptics-1;
|
||||||
|
|
||||||
/* Grab the first mouse haptic device we find. */
|
/* Grab the first mouse haptic device we find. */
|
||||||
for (i = 0; i < SDL_numhaptics; i++) {
|
for (item = SDL_hapticlist; item != NULL; item = item->next) {
|
||||||
if (SDL_hapticlist[i].capabilities.dwDevType == DI8DEVCLASS_POINTER ) {
|
SDL_assert(index >= 0);
|
||||||
return i;
|
if (item->capabilities.dwDevType == DI8DEVCLASS_POINTER ) {
|
||||||
|
return index;
|
||||||
}
|
}
|
||||||
|
index--;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
@ -677,34 +854,39 @@ SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick)
|
|||||||
int
|
int
|
||||||
SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick)
|
SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick)
|
||||||
{
|
{
|
||||||
int i;
|
SDL_hapticlist_item *item;
|
||||||
HRESULT idret;
|
int index = numhaptics-1;
|
||||||
DIDEVICEINSTANCE joy_instance;
|
|
||||||
joy_instance.dwSize = sizeof(DIDEVICEINSTANCE);
|
|
||||||
|
|
||||||
/* Since it comes from a joystick we have to try to match it with a haptic device on our haptic list. */
|
/* Since it comes from a joystick we have to try to match it with a haptic device on our haptic list. */
|
||||||
if (joystick->hwdata->bXInputDevice) {
|
if (joystick->hwdata->bXInputDevice) {
|
||||||
const Uint8 userid = joystick->hwdata->userid;
|
const Uint8 userid = joystick->hwdata->userid;
|
||||||
for (i=0; i<SDL_numhaptics; i++) {
|
for (item = SDL_hapticlist; item != NULL; item = item->next) {
|
||||||
if ((SDL_hapticlist[i].bXInputHaptic) && (SDL_hapticlist[i].userid == userid)) {
|
if ((item->bXInputHaptic) && (item->userid == userid)) {
|
||||||
SDL_assert(joystick->hwdata->bXInputHaptic);
|
SDL_assert(joystick->hwdata->bXInputHaptic);
|
||||||
haptic->index = i;
|
haptic->index = index;
|
||||||
return SDL_SYS_HapticOpenFromXInput(haptic, SDL_hapticlist[haptic->index].userid);
|
return SDL_SYS_HapticOpenFromXInput(haptic, userid);
|
||||||
}
|
}
|
||||||
|
index--;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i=0; i<SDL_numhaptics; i++) {
|
HRESULT idret;
|
||||||
idret = IDirectInputDevice8_GetDeviceInfo(joystick->hwdata->InputDevice, &joy_instance);
|
DIDEVICEINSTANCE joy_instance;
|
||||||
if (FAILED(idret)) {
|
|
||||||
return -1;
|
joy_instance.dwSize = sizeof(DIDEVICEINSTANCE);
|
||||||
}
|
idret = IDirectInputDevice8_GetDeviceInfo(joystick->hwdata->InputDevice, &joy_instance);
|
||||||
if (DI_GUIDIsSame(&SDL_hapticlist[i].instance.guidInstance,
|
if (FAILED(idret)) {
|
||||||
&joy_instance.guidInstance)) {
|
return -1;
|
||||||
haptic->index = i;
|
}
|
||||||
|
|
||||||
|
for (item = SDL_hapticlist; item != NULL; item = item->next) {
|
||||||
|
if (DI_GUIDIsSame(&item->instance.guidInstance, &joy_instance.guidInstance)) {
|
||||||
|
haptic->index = index;
|
||||||
return SDL_SYS_HapticOpenFromDevice8(haptic, joystick->hwdata->InputDevice, SDL_TRUE);
|
return SDL_SYS_HapticOpenFromDevice8(haptic, joystick->hwdata->InputDevice, SDL_TRUE);
|
||||||
}
|
}
|
||||||
|
index--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No match to our haptic list */
|
/* No match to our haptic list */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -749,16 +931,20 @@ SDL_SYS_HapticClose(SDL_Haptic * haptic)
|
|||||||
void
|
void
|
||||||
SDL_SYS_HapticQuit(void)
|
SDL_SYS_HapticQuit(void)
|
||||||
{
|
{
|
||||||
int i;
|
SDL_hapticlist_item *item;
|
||||||
|
SDL_hapticlist_item *next = NULL;
|
||||||
|
|
||||||
if (loaded_xinput) {
|
if (loaded_xinput) {
|
||||||
WIN_UnloadXInputDLL();
|
WIN_UnloadXInputDLL();
|
||||||
loaded_xinput = SDL_FALSE;
|
loaded_xinput = SDL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < SDL_arraysize(SDL_hapticlist); ++i) {
|
for (item = SDL_hapticlist; item; item = next) {
|
||||||
SDL_free(SDL_hapticlist[i].name);
|
/* Opened and not closed haptics are leaked, this is on purpose.
|
||||||
SDL_hapticlist[i].name = NULL;
|
* Close your haptic devices after usage. */
|
||||||
|
next = item->next;
|
||||||
|
SDL_free(item->name);
|
||||||
|
SDL_free(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dinput != NULL) {
|
if (dinput != NULL) {
|
||||||
|
28
src/haptic/windows/SDL_syshaptic_c.h
Normal file
28
src/haptic/windows/SDL_syshaptic_c.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
Simple DirectMedia Layer
|
||||||
|
Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern int DirectInputHaptic_MaybeAddDevice(const DIDEVICEINSTANCE *pdidInstance);
|
||||||
|
extern int DirectInputHaptic_MaybeRemoveDevice(const DIDEVICEINSTANCE *pdidInstance);
|
||||||
|
extern int XInputHaptic_MaybeAddDevice(const DWORD dwUserid);
|
||||||
|
extern int XInputHaptic_MaybeRemoveDevice(const DWORD dwUserid);
|
||||||
|
|
||||||
|
/* vi: set ts=4 sw=4 expandtab: */
|
||||||
|
|
@ -49,6 +49,10 @@
|
|||||||
#define INITGUID /* Only set here, if set twice will cause mingw32 to break. */
|
#define INITGUID /* Only set here, if set twice will cause mingw32 to break. */
|
||||||
#include "SDL_dxjoystick_c.h"
|
#include "SDL_dxjoystick_c.h"
|
||||||
|
|
||||||
|
#if SDL_HAPTIC_DINPUT
|
||||||
|
#include "../../haptic/windows/SDL_syshaptic_c.h" /* For haptic hot plugging */
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef DIDFT_OPTIONAL
|
#ifndef DIDFT_OPTIONAL
|
||||||
#define DIDFT_OPTIONAL 0x80000000
|
#define DIDFT_OPTIONAL 0x80000000
|
||||||
#endif
|
#endif
|
||||||
@ -824,7 +828,17 @@ void SDL_SYS_JoystickDetect()
|
|||||||
while ( pCurList )
|
while ( pCurList )
|
||||||
{
|
{
|
||||||
JoyStick_DeviceData *pListNext = NULL;
|
JoyStick_DeviceData *pListNext = NULL;
|
||||||
|
|
||||||
|
#if SDL_HAPTIC_DINPUT
|
||||||
|
if (pCurList->bXInputDevice) {
|
||||||
|
XInputHaptic_MaybeRemoveDevice(pCurList->XInputUserId);
|
||||||
|
} else {
|
||||||
|
DirectInputHaptic_MaybeRemoveDevice(&pCurList->dxdevice);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !SDL_EVENTS_DISABLED
|
#if !SDL_EVENTS_DISABLED
|
||||||
|
{
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
event.type = SDL_JOYDEVICEREMOVED;
|
event.type = SDL_JOYDEVICEREMOVED;
|
||||||
|
|
||||||
@ -835,6 +849,7 @@ void SDL_SYS_JoystickDetect()
|
|||||||
SDL_PushEvent(&event);
|
SDL_PushEvent(&event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif /* !SDL_EVENTS_DISABLED */
|
#endif /* !SDL_EVENTS_DISABLED */
|
||||||
|
|
||||||
pListNext = pCurList->pNext;
|
pListNext = pCurList->pNext;
|
||||||
@ -855,7 +870,16 @@ void SDL_SYS_JoystickDetect()
|
|||||||
{
|
{
|
||||||
if ( pNewJoystick->send_add_event )
|
if ( pNewJoystick->send_add_event )
|
||||||
{
|
{
|
||||||
|
#if SDL_HAPTIC_DINPUT
|
||||||
|
if (pNewJoystick->bXInputDevice) {
|
||||||
|
XInputHaptic_MaybeAddDevice(pNewJoystick->XInputUserId);
|
||||||
|
} else {
|
||||||
|
DirectInputHaptic_MaybeAddDevice(&pNewJoystick->dxdevice);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !SDL_EVENTS_DISABLED
|
#if !SDL_EVENTS_DISABLED
|
||||||
|
{
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
event.type = SDL_JOYDEVICEADDED;
|
event.type = SDL_JOYDEVICEADDED;
|
||||||
|
|
||||||
@ -866,6 +890,7 @@ void SDL_SYS_JoystickDetect()
|
|||||||
SDL_PushEvent(&event);
|
SDL_PushEvent(&event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif /* !SDL_EVENTS_DISABLED */
|
#endif /* !SDL_EVENTS_DISABLED */
|
||||||
pNewJoystick->send_add_event = 0;
|
pNewJoystick->send_add_event = 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user