Skip to content

Commit fb8d438

Browse files
connorjclarkSiegeLord
authored andcommitted
Add name lookup for xinput controllers for limited set of devices
1 parent 92d9488 commit fb8d438

File tree

1 file changed

+96
-1
lines changed

1 file changed

+96
-1
lines changed

src/win/wjoyxi.c

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,16 +109,28 @@ ALLEGRO_JOYSTICK_DRIVER _al_joydrv_xinput =
109109
#define XINPUT_MIN_VERSION 3
110110
#define XINPUT_MAX_VERSION 4
111111

112+
typedef struct _XINPUT_CAPABILITIES_EX
113+
{
114+
XINPUT_CAPABILITIES Capabilities;
115+
WORD VendorId;
116+
WORD ProductId;
117+
WORD VersionNumber;
118+
WORD unk1;
119+
DWORD unk2;
120+
} XINPUT_CAPABILITIES_EX, * PXINPUT_CAPABILITIES_EX;
121+
112122
typedef void (WINAPI *XInputEnablePROC)(BOOL);
113123
typedef DWORD (WINAPI *XInputSetStatePROC)(DWORD, XINPUT_VIBRATION*);
114124
typedef DWORD (WINAPI *XInputGetStatePROC)(DWORD, XINPUT_STATE*);
115125
typedef DWORD (WINAPI *XInputGetCapabilitiesPROC)(DWORD, DWORD, XINPUT_CAPABILITIES*);
126+
typedef DWORD (WINAPI *XInputGetCapabilitiesExPROC)(DWORD, DWORD, DWORD, XINPUT_CAPABILITIES_EX*);
116127

117128
static HMODULE _imp_xinput_module = 0;
118129

119130
static XInputEnablePROC _imp_XInputEnable = NULL;
120131
static XInputGetStatePROC _imp_XInputGetState = NULL;
121132
static XInputGetCapabilitiesPROC _imp_XInputGetCapabilities = NULL;
133+
static XInputGetCapabilitiesExPROC _imp_XInputGetCapabilitiesEx = NULL;
122134
XInputSetStatePROC _al_imp_XInputSetState = NULL;
123135

124136
/* the joystick structures */
@@ -209,6 +221,8 @@ static bool _imp_load_xinput_module_version(int version)
209221
}
210222
_imp_XInputGetState = (XInputGetStatePROC)GetProcAddress(_imp_xinput_module, "XInputGetState");
211223
_imp_XInputGetCapabilities = (XInputGetCapabilitiesPROC)GetProcAddress(_imp_xinput_module, "XInputGetCapabilities");
224+
if (version == 4)
225+
_imp_XInputGetCapabilitiesEx = (XInputGetCapabilitiesExPROC)GetProcAddress(_imp_xinput_module, (char*)108);
212226
_al_imp_XInputSetState = (XInputSetStatePROC)GetProcAddress(_imp_xinput_module, "XInputSetState");
213227

214228
ALLEGRO_INFO("Module \"%s\" loaded.\n", module_name);
@@ -567,7 +581,6 @@ static bool joyxi_init_joystick(void)
567581
/* Fill in the joystick structs */
568582
for (index = 0; index < MAX_JOYSTICKS; index++) {
569583
joyxi_joysticks[index].active = false;
570-
sprintf(joyxi_joysticks[index].name, "XInput Joystick %d", index);
571584
joyxi_joysticks[index].index = (DWORD)index;
572585
joyxi_init_joystick_info(joyxi_joysticks + index);
573586
}
@@ -702,10 +715,92 @@ static void joyxi_get_joystick_state(ALLEGRO_JOYSTICK *joy, ALLEGRO_JOYSTICK_STA
702715
}
703716

704717

718+
// Source: https://github.com/xan105/node-xinput-ffi/blob/master/lib/util/HardwareID.js
719+
static const char *joyxi_lookup_device_name(WORD vid, WORD pid)
720+
{
721+
if (vid == 0x045E) {
722+
switch (pid) {
723+
case 0x028E: return "Xbox360 Controller";
724+
case 0x02A1: return "Xbox360 Controller";
725+
case 0x028F: return "Xbox360 Wireless Controller";
726+
case 0x02E0: return "Xbox One S Controller";
727+
case 0x02FF: return "Xbox One Elite Controller";
728+
case 0x0202: return "Xbox Controller";
729+
case 0x0285: return "Xbox Controller S";
730+
case 0x0289: return "Xbox Controller S";
731+
case 0x02E3: return "Xbox One Elite Controller";
732+
case 0x02EA: return "Xbox One S Controller";
733+
case 0x02FD: return "Xbox One S Controller";
734+
case 0x02D1: return "Xbox One Controller";
735+
case 0x02DD: return "Xbox One Controller";
736+
case 0x0B13: return "Xbox Series X/S controller";
737+
}
738+
return "Microsoft Corp.";
739+
}
740+
if (vid == 0x054C) {
741+
switch (pid) {
742+
case 0x0268: return "DualShock 3 / Sixaxis";
743+
case 0x05C4: return "DualShock 4";
744+
case 0x09CC: return "DualShock 4 (v2)";
745+
case 0x0BA0: return "DualShock 4 USB Wireless Adaptor";
746+
case 0x0CE6: return "DualSense Wireless Controller"; //PS5
747+
}
748+
return "Sony Corp.";
749+
}
750+
if (vid == 0x057E) {
751+
switch (pid) {
752+
case 0x0306: return "Wii Remote Controller";
753+
case 0x0337: return "Wii U GameCube Controller Adapter";
754+
case 0x2006: return "Joy-Con L";
755+
case 0x2007: return "Joy-Con R";
756+
case 0x2009: return "Switch Pro Controller";
757+
case 0x200E: return "Joy-Con Charging Grip";
758+
}
759+
return "Nintendo Co., Ltd";
760+
}
761+
if (vid == 0x28DE) {
762+
switch (pid) {
763+
case 0x11FC: return "Steam Controller";
764+
case 0x1102: return "Steam Controller";
765+
case 0x1142: return "Wireless Steam Controller";
766+
}
767+
return "Valve Corp.";
768+
}
769+
if (vid == 0x046D) {
770+
switch (pid) {
771+
case 0xC21D: return "Logitech Gamepad F310";
772+
case 0xC21E: return "Logitech Gamepad F510";
773+
case 0xC21F: return "Logitech Gamepad F710";
774+
case 0xC242: return "Logitech Chillstream Controller";
775+
}
776+
return "Logitech Inc.";
777+
}
778+
return "";
779+
}
780+
781+
705782
static const char *joyxi_get_name(ALLEGRO_JOYSTICK *joy)
706783
{
707784
ALLEGRO_JOYSTICK_XINPUT *xjoy = (ALLEGRO_JOYSTICK_XINPUT *)joy;
708785
ASSERT(xjoy);
786+
787+
if (xjoy->name[0] == '\0') {
788+
if (_imp_XInputGetCapabilitiesEx) {
789+
XINPUT_CAPABILITIES_EX xicapas;
790+
int res = _imp_XInputGetCapabilitiesEx(1, xjoy->index, 0, &xicapas);
791+
if (res == ERROR_SUCCESS) {
792+
const char *device_name = joyxi_lookup_device_name(xicapas.VendorId, xicapas.ProductId);
793+
if (device_name[0] != '\0')
794+
sprintf(xjoy->name, device_name);
795+
else
796+
sprintf(xjoy->name, "XInput Joystick vendor: %x product: %x", xicapas.VendorId, xicapas.ProductId);
797+
return xjoy->name;
798+
}
799+
}
800+
801+
sprintf(xjoy->name, "XInput Joystick %d", xjoy->index);
802+
}
803+
709804
return xjoy->name;
710805
}
711806

0 commit comments

Comments
 (0)