@@ -109,16 +109,28 @@ ALLEGRO_JOYSTICK_DRIVER _al_joydrv_xinput =
109
109
#define XINPUT_MIN_VERSION 3
110
110
#define XINPUT_MAX_VERSION 4
111
111
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
+
112
122
typedef void (WINAPI * XInputEnablePROC )(BOOL );
113
123
typedef DWORD (WINAPI * XInputSetStatePROC )(DWORD , XINPUT_VIBRATION * );
114
124
typedef DWORD (WINAPI * XInputGetStatePROC )(DWORD , XINPUT_STATE * );
115
125
typedef DWORD (WINAPI * XInputGetCapabilitiesPROC )(DWORD , DWORD , XINPUT_CAPABILITIES * );
126
+ typedef DWORD (WINAPI * XInputGetCapabilitiesExPROC )(DWORD , DWORD , DWORD , XINPUT_CAPABILITIES_EX * );
116
127
117
128
static HMODULE _imp_xinput_module = 0 ;
118
129
119
130
static XInputEnablePROC _imp_XInputEnable = NULL ;
120
131
static XInputGetStatePROC _imp_XInputGetState = NULL ;
121
132
static XInputGetCapabilitiesPROC _imp_XInputGetCapabilities = NULL ;
133
+ static XInputGetCapabilitiesExPROC _imp_XInputGetCapabilitiesEx = NULL ;
122
134
XInputSetStatePROC _al_imp_XInputSetState = NULL ;
123
135
124
136
/* the joystick structures */
@@ -209,6 +221,8 @@ static bool _imp_load_xinput_module_version(int version)
209
221
}
210
222
_imp_XInputGetState = (XInputGetStatePROC )GetProcAddress (_imp_xinput_module , "XInputGetState" );
211
223
_imp_XInputGetCapabilities = (XInputGetCapabilitiesPROC )GetProcAddress (_imp_xinput_module , "XInputGetCapabilities" );
224
+ if (version == 4 )
225
+ _imp_XInputGetCapabilitiesEx = (XInputGetCapabilitiesExPROC )GetProcAddress (_imp_xinput_module , (char * )108 );
212
226
_al_imp_XInputSetState = (XInputSetStatePROC )GetProcAddress (_imp_xinput_module , "XInputSetState" );
213
227
214
228
ALLEGRO_INFO ("Module \"%s\" loaded.\n" , module_name );
@@ -567,7 +581,6 @@ static bool joyxi_init_joystick(void)
567
581
/* Fill in the joystick structs */
568
582
for (index = 0 ; index < MAX_JOYSTICKS ; index ++ ) {
569
583
joyxi_joysticks [index ].active = false;
570
- sprintf (joyxi_joysticks [index ].name , "XInput Joystick %d" , index );
571
584
joyxi_joysticks [index ].index = (DWORD )index ;
572
585
joyxi_init_joystick_info (joyxi_joysticks + index );
573
586
}
@@ -702,10 +715,92 @@ static void joyxi_get_joystick_state(ALLEGRO_JOYSTICK *joy, ALLEGRO_JOYSTICK_STA
702
715
}
703
716
704
717
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
+
705
782
static const char * joyxi_get_name (ALLEGRO_JOYSTICK * joy )
706
783
{
707
784
ALLEGRO_JOYSTICK_XINPUT * xjoy = (ALLEGRO_JOYSTICK_XINPUT * )joy ;
708
785
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
+
709
804
return xjoy -> name ;
710
805
}
711
806
0 commit comments