mirror of
https://github.com/libretro/RetroArch
synced 2025-04-16 08:43:10 +00:00
Hopefully improved detection of third-party dual xinput/dinput pads
This commit is contained in:
parent
283c6f9c6d
commit
09651cbe21
@ -29,7 +29,8 @@ static const d3d_font_renderer_t *d3d_font_backends[] = {
|
|||||||
|
|
||||||
const d3d_font_renderer_t *d3d_font_init_first(void *data, const char *font_path, unsigned font_size)
|
const d3d_font_renderer_t *d3d_font_init_first(void *data, const char *font_path, unsigned font_size)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < ARRAY_SIZE(d3d_font_backends); i++)
|
unsigned i;
|
||||||
|
for (i = 0; i < ARRAY_SIZE(d3d_font_backends); i++)
|
||||||
{
|
{
|
||||||
if (d3d_font_backends[i]->init(data, font_path, font_size))
|
if (d3d_font_backends[i]->init(data, font_path, font_size))
|
||||||
return d3d_font_backends[i];
|
return d3d_font_backends[i];
|
||||||
|
@ -611,49 +611,63 @@ static BOOL CALLBACK enum_axes_cb(const DIDEVICEOBJECTINSTANCE *inst, void *p)
|
|||||||
return DIENUM_CONTINUE;
|
return DIENUM_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Use a better way of detecting dual XInput/DInput pads. This current method
|
static const GUID common_xinput_guids[] = {
|
||||||
// will not work correctly for third-party controllers or future MS pads (Xbox One?).
|
{MAKELONG(0x28DE, 0x11FF),0x0000,0x0000,{0x00,0x00,0x50,0x49,0x44,0x56,0x49,0x44}}, // valve streaming pad
|
||||||
// An example of this is provided in the DX SDK, which advises "Enum each PNP device
|
{MAKELONG(0x045E, 0x02A1),0x0000,0x0000,{0x00,0x00,0x50,0x49,0x44,0x56,0x49,0x44}}, // wired 360 pad
|
||||||
// using WMI and check each device ID to see if it contains "IG_"". Unfortunately the
|
{MAKELONG(0x045E, 0x028E),0x0000,0x0000,{0x00,0x00,0x50,0x49,0x44,0x56,0x49,0x44}} // wireless 360 pad
|
||||||
// example code is a horrible unsightly mess.
|
|
||||||
static const char* const XINPUT_PAD_NAMES[] =
|
|
||||||
{
|
|
||||||
"XBOX 360 For Windows",
|
|
||||||
"Controller (Gamepad for Xbox 360)",
|
|
||||||
"Controller (XBOX 360 For Windows)",
|
|
||||||
"Controller (Xbox 360 Wireless Receiver for Windows)",
|
|
||||||
"Controller (Xbox wireless receiver for windows)",
|
|
||||||
"XBOX 360 For Windows (Controller)",
|
|
||||||
"Xbox 360 Wireless Receiver",
|
|
||||||
"Xbox 360 Wireless Controller",
|
|
||||||
"Xbox Receiver for Windows (Wireless Controller)",
|
|
||||||
"Xbox wireless receiver for windows (Controller)",
|
|
||||||
"Gamepad F310 (Controller)",
|
|
||||||
"Controller (Gamepad F310)",
|
|
||||||
"Wireless Gamepad F710 (Controller)",
|
|
||||||
"Controller (Batarang wired controller (XBOX))",
|
|
||||||
"Afterglow Gamepad for Xbox 360 (Controller)"
|
|
||||||
"Controller (Rumble Gamepad F510)",
|
|
||||||
"Controller (Wireless Gamepad F710)",
|
|
||||||
"Controller (Xbox 360 Wireless Receiver for Windows)",
|
|
||||||
"Controller (Xbox wireless receiver for windows)",
|
|
||||||
"Controller (XBOX360 GAMEPAD)",
|
|
||||||
"MadCatz GamePad",
|
|
||||||
"MadCatz GamePad (Controller)",
|
|
||||||
"Controller (MadCatz GamePad)",
|
|
||||||
"Controller (GPX Gamepad)",
|
|
||||||
NULL
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool name_is_xinput_pad(const char* name)
|
// Based on SDL2's implementation
|
||||||
|
static bool guid_is_xinput_device(const GUID* product_guid)
|
||||||
{
|
{
|
||||||
|
PRAWINPUTDEVICELIST raw_devs = NULL;
|
||||||
|
unsigned num_raw_devs = 0;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
for (i = 0; XINPUT_PAD_NAMES[i]; i++)
|
|
||||||
|
// Check for well known XInput device GUIDs, thereby removing the need for the IG_ check.
|
||||||
|
// This lets us skip RAWINPUT for popular devices. Also, we need to do this for the Valve Streaming Gamepad because it's virtualized and doesn't show up in the device list.
|
||||||
|
for (i = 0; i < ARRAY_SIZE(common_xinput_guids); ++i)
|
||||||
{
|
{
|
||||||
if (strcasecmp(name, XINPUT_PAD_NAMES[i]) == 0)
|
if (memcmp(product_guid, &common_xinput_guids[i], sizeof(GUID)) == 0)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Go through RAWINPUT (WinXP and later) to find HID devices. */
|
||||||
|
if (!raw_devs)
|
||||||
|
{
|
||||||
|
if ((GetRawInputDeviceList(NULL, &num_raw_devs, sizeof (RAWINPUTDEVICELIST)) == -1) || (!num_raw_devs))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
raw_devs = (PRAWINPUTDEVICELIST) malloc(sizeof(RAWINPUTDEVICELIST) * num_raw_devs);
|
||||||
|
if (!raw_devs)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (GetRawInputDeviceList(raw_devs, &num_raw_devs, sizeof (RAWINPUTDEVICELIST)) == -1)
|
||||||
|
{
|
||||||
|
free(raw_devs);
|
||||||
|
raw_devs = NULL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < num_raw_devs; i++)
|
||||||
|
{
|
||||||
|
RID_DEVICE_INFO rdi;
|
||||||
|
char devName[128];
|
||||||
|
UINT rdiSize = sizeof(rdi);
|
||||||
|
UINT nameSize = sizeof(devName);
|
||||||
|
|
||||||
|
rdi.cbSize = sizeof (rdi);
|
||||||
|
if ((raw_devs[i].dwType == RIM_TYPEHID) &&
|
||||||
|
(GetRawInputDeviceInfoA(raw_devs[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != ((UINT)-1)) &&
|
||||||
|
(MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) == ((LONG)product_guid->Data1)) &&
|
||||||
|
(GetRawInputDeviceInfoA(raw_devs[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) != ((UINT)-1)) &&
|
||||||
|
(strstr(devName, "IG_") != NULL) )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -679,7 +693,8 @@ static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p)
|
|||||||
g_pads[g_joypad_cnt].joy_name = strdup(inst->tszProductName);
|
g_pads[g_joypad_cnt].joy_name = strdup(inst->tszProductName);
|
||||||
|
|
||||||
#ifdef HAVE_WINXINPUT
|
#ifdef HAVE_WINXINPUT
|
||||||
bool is_xinput_pad = g_xinput_block_pads && name_is_xinput_pad(inst->tszProductName);
|
//bool is_xinput_pad = g_xinput_block_pads && name_is_xinput_pad(inst->tszProductName);
|
||||||
|
bool is_xinput_pad = g_xinput_block_pads && guid_is_xinput_device(&inst->guidProduct);
|
||||||
|
|
||||||
if (is_xinput_pad)
|
if (is_xinput_pad)
|
||||||
{
|
{
|
||||||
|
@ -92,7 +92,7 @@ typedef struct
|
|||||||
extern int g_xinput_pad_indexes[MAX_PLAYERS];
|
extern int g_xinput_pad_indexes[MAX_PLAYERS];
|
||||||
extern bool g_xinput_block_pads;
|
extern bool g_xinput_block_pads;
|
||||||
|
|
||||||
// For xinput1_3.dll
|
// For xinput1_n.dll
|
||||||
static HINSTANCE g_winxinput_dll;
|
static HINSTANCE g_winxinput_dll;
|
||||||
|
|
||||||
// Function pointer, to be assigned with GetProcAddress
|
// Function pointer, to be assigned with GetProcAddress
|
||||||
@ -141,8 +141,6 @@ const char* winxinput_joypad_name (unsigned pad)
|
|||||||
return XBOX_CONTROLLER_NAMES[xplayer];
|
return XBOX_CONTROLLER_NAMES[xplayer];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static bool winxinput_joypad_init(void)
|
static bool winxinput_joypad_init(void)
|
||||||
{
|
{
|
||||||
unsigned i, autoconf_pad;
|
unsigned i, autoconf_pad;
|
||||||
@ -240,7 +238,6 @@ static bool winxinput_joypad_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool winxinput_joypad_query_pad(unsigned pad)
|
static bool winxinput_joypad_query_pad(unsigned pad)
|
||||||
@ -261,6 +258,7 @@ static void winxinput_joypad_destroy(void)
|
|||||||
FreeLibrary(g_winxinput_dll);
|
FreeLibrary(g_winxinput_dll);
|
||||||
g_winxinput_dll = NULL;
|
g_winxinput_dll = NULL;
|
||||||
g_XInputGetStateEx = NULL;
|
g_XInputGetStateEx = NULL;
|
||||||
|
g_XInputSetState = NULL;
|
||||||
|
|
||||||
dinput_joypad.destroy();
|
dinput_joypad.destroy();
|
||||||
g_xinput_block_pads = false;
|
g_xinput_block_pads = false;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user