Added the CRC of the joystick name to the GUID

This will make it possible to have mappings for different controllers
that have the same VID/PID. This happens frequently with some generic
controller boards that have been reused in many products.

Fixes https://github.com/libsdl-org/SDL/issues/6004
This commit is contained in:
Sam Lantinga 2022-08-22 16:46:55 -07:00
parent 20715fa014
commit c1e0873940
21 changed files with 179 additions and 117 deletions

View File

@ -538,7 +538,7 @@ static ControllerMapping_t *SDL_CreateMappingForHIDAPIController(SDL_JoystickGUI
SDL_strlcpy(mapping_string, "none,*,", sizeof(mapping_string)); SDL_strlcpy(mapping_string, "none,*,", sizeof(mapping_string));
SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL); SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL, NULL);
if ((vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_GAMECUBE_ADAPTER) || if ((vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_GAMECUBE_ADAPTER) ||
(vendor == USB_VENDOR_SHENZHEN && product == USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER)) { (vendor == USB_VENDOR_SHENZHEN && product == USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER)) {
@ -664,9 +664,17 @@ static ControllerMapping_t *SDL_CreateMappingForWGIController(SDL_JoystickGUID g
static ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickGUID guid, SDL_bool exact_match) static ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickGUID guid, SDL_bool exact_match)
{ {
ControllerMapping_t *mapping = s_pSupportedControllers; ControllerMapping_t *mapping = s_pSupportedControllers;
SDL_JoystickGUID zero_crc_guid;
SDL_memcpy(&zero_crc_guid, &guid, sizeof(guid));
zero_crc_guid.data[3] = 0;
zero_crc_guid.data[4] = 0;
zero_crc_guid.data[5] = 0;
zero_crc_guid.data[6] = 0;
while (mapping) { while (mapping) {
if (SDL_memcmp(&guid, &mapping->guid, sizeof(guid)) == 0) { if (SDL_memcmp(&guid, &mapping->guid, sizeof(guid)) == 0 ||
SDL_memcmp(&zero_crc_guid, &mapping->guid, sizeof(guid)) == 0) {
return mapping; return mapping;
} }
mapping = mapping->next; mapping = mapping->next;
@ -1836,7 +1844,7 @@ SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid)
return SDL_FALSE; return SDL_FALSE;
} }
SDL_GetJoystickGUIDInfo(guid, &vendor, &product, &version); SDL_GetJoystickGUIDInfo(guid, &vendor, &product, &version, NULL);
if (SDL_GetHintBoolean("SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD", SDL_FALSE)) { if (SDL_GetHintBoolean("SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD", SDL_FALSE)) {
/* We shouldn't ignore Steam's virtual gamepad since it's using the hints to filter out the real controllers so it can remap input for the virtual controller */ /* We shouldn't ignore Steam's virtual gamepad since it's using the hints to filter out the real controllers so it can remap input for the virtual controller */

View File

@ -1768,19 +1768,23 @@ SDL_JoystickEventState(int state)
#endif /* SDL_EVENTS_DISABLED */ #endif /* SDL_EVENTS_DISABLED */
} }
void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *product, Uint16 *version) void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *product, Uint16 *version, Uint16 *crc16)
{ {
Uint16 *guid16 = (Uint16 *)guid.data; Uint16 *guid16 = (Uint16 *)guid.data;
Uint16 bus = SDL_SwapLE16(guid16[0]);
/* If the GUID fits the form of BUS 0000 VENDOR 0000 PRODUCT 0000, return the data */ if (bus < ' ' && guid16[3] == 0x0000 && guid16[5] == 0x0000) {
if (/* guid16[0] is device bus type */ /* This GUID fits the standard form:
guid16[1] == 0x0000 && * 16-bit bus
/* guid16[2] is vendor ID */ * 16-bit CRC16 of the joystick name (can be zero)
guid16[3] == 0x0000 && * 16-bit vendor ID
/* guid16[4] is product ID */ * 16-bit zero
guid16[5] == 0x0000 * 16-bit product ID
/* guid16[6] is product version */ * 16-bit zero
) { * 16-bit version
* 8-bit driver identifier ('h' for HIDAPI, 'x' for XInput, etc.)
* 8-bit driver-dependent type info
*/
if (vendor) { if (vendor) {
*vendor = SDL_SwapLE16(guid16[2]); *vendor = SDL_SwapLE16(guid16[2]);
} }
@ -1790,6 +1794,27 @@ void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *prod
if (version) { if (version) {
*version = SDL_SwapLE16(guid16[6]); *version = SDL_SwapLE16(guid16[6]);
} }
if (crc16) {
*crc16 = SDL_SwapLE16(guid16[1]);
}
} else if (bus < ' ') {
/* This GUID fits the unknown VID/PID form:
* 16-bit bus
* 16-bit CRC16 of the joystick name (can be zero)
* 11 characters of the joystick name, null terminated
*/
if (vendor) {
*vendor = 0;
}
if (product) {
*product = 0;
}
if (version) {
*version = 0;
}
if (crc16) {
*crc16 = SDL_SwapLE16(guid16[1]);
}
} else { } else {
if (vendor) { if (vendor) {
*vendor = 0; *vendor = 0;
@ -1800,6 +1825,9 @@ void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *prod
if (version) { if (version) {
*version = 0; *version = 0;
} }
if (crc16) {
*crc16 = 0;
}
} }
} }
@ -2045,7 +2073,7 @@ SDL_GetJoystickGameControllerTypeFromGUID(SDL_JoystickGUID guid, const char *nam
SDL_GameControllerType type; SDL_GameControllerType type;
Uint16 vendor, product; Uint16 vendor, product;
SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL); SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL, NULL);
type = SDL_GetJoystickGameControllerTypeFromVIDPID(vendor, product, name, SDL_TRUE); type = SDL_GetJoystickGameControllerTypeFromVIDPID(vendor, product, name, SDL_TRUE);
if (type == SDL_CONTROLLER_TYPE_UNKNOWN) { if (type == SDL_CONTROLLER_TYPE_UNKNOWN) {
if (SDL_IsJoystickXInput(guid)) { if (SDL_IsJoystickXInput(guid)) {
@ -2379,7 +2407,7 @@ static SDL_JoystickType SDL_GetJoystickGUIDType(SDL_JoystickGUID guid)
return (SDL_JoystickType)guid.data[15]; return (SDL_JoystickType)guid.data[15];
} }
SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL); SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL, NULL);
vidpid = MAKE_VIDPID(vendor, product); vidpid = MAKE_VIDPID(vendor, product);
if (SDL_IsJoystickProductWheel(vidpid)) { if (SDL_IsJoystickProductWheel(vidpid)) {
@ -2567,7 +2595,7 @@ SDL_bool SDL_ShouldIgnoreJoystick(const char *name, SDL_JoystickGUID guid)
Uint16 product; Uint16 product;
SDL_GameControllerType type; SDL_GameControllerType type;
SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL); SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL, NULL);
/* Check the joystick blacklist */ /* Check the joystick blacklist */
id = MAKE_VIDPID(vendor, product); id = MAKE_VIDPID(vendor, product);
@ -2618,7 +2646,7 @@ Uint16 SDL_JoystickGetDeviceVendor(int device_index)
Uint16 vendor; Uint16 vendor;
SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(device_index); SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(device_index);
SDL_GetJoystickGUIDInfo(guid, &vendor, NULL, NULL); SDL_GetJoystickGUIDInfo(guid, &vendor, NULL, NULL, NULL);
return vendor; return vendor;
} }
@ -2627,7 +2655,7 @@ Uint16 SDL_JoystickGetDeviceProduct(int device_index)
Uint16 product; Uint16 product;
SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(device_index); SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(device_index);
SDL_GetJoystickGUIDInfo(guid, NULL, &product, NULL); SDL_GetJoystickGUIDInfo(guid, NULL, &product, NULL, NULL);
return product; return product;
} }
@ -2636,7 +2664,7 @@ Uint16 SDL_JoystickGetDeviceProductVersion(int device_index)
Uint16 version; Uint16 version;
SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(device_index); SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(device_index);
SDL_GetJoystickGUIDInfo(guid, NULL, NULL, &version); SDL_GetJoystickGUIDInfo(guid, NULL, NULL, &version, NULL);
return version; return version;
} }
@ -2700,7 +2728,7 @@ Uint16 SDL_JoystickGetVendor(SDL_Joystick *joystick)
Uint16 vendor; Uint16 vendor;
SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick); SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick);
SDL_GetJoystickGUIDInfo(guid, &vendor, NULL, NULL); SDL_GetJoystickGUIDInfo(guid, &vendor, NULL, NULL, NULL);
return vendor; return vendor;
} }
@ -2709,7 +2737,7 @@ Uint16 SDL_JoystickGetProduct(SDL_Joystick *joystick)
Uint16 product; Uint16 product;
SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick); SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick);
SDL_GetJoystickGUIDInfo(guid, NULL, &product, NULL); SDL_GetJoystickGUIDInfo(guid, NULL, &product, NULL, NULL);
return product; return product;
} }
@ -2718,7 +2746,7 @@ Uint16 SDL_JoystickGetProductVersion(SDL_Joystick *joystick)
Uint16 version; Uint16 version;
SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick); SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick);
SDL_GetJoystickGUIDInfo(guid, NULL, NULL, &version); SDL_GetJoystickGUIDInfo(guid, NULL, NULL, &version, NULL);
return version; return version;
} }

View File

@ -55,7 +55,7 @@ extern SDL_bool SDL_GetDriverAndJoystickIndex(int device_index, struct _SDL_Joys
extern int SDL_JoystickGetDeviceIndexFromInstanceID(SDL_JoystickID instance_id); extern int SDL_JoystickGetDeviceIndexFromInstanceID(SDL_JoystickID instance_id);
/* Function to extract information from an SDL joystick GUID */ /* Function to extract information from an SDL joystick GUID */
extern void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *product, Uint16 *version); extern void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *product, Uint16 *version, Uint16 *crc16);
/* Function to standardize the name for a controller /* Function to standardize the name for a controller
This should be freed with SDL_free() when no longer needed This should be freed with SDL_free() when no longer needed

View File

@ -125,9 +125,10 @@ struct _SDL_Joystick
}; };
/* Device bus definitions */ /* Device bus definitions */
#define SDL_HARDWARE_BUS_VIRTUAL 0x00 #define SDL_HARDWARE_BUS_UNKNOWN 0x00
#define SDL_HARDWARE_BUS_USB 0x03 #define SDL_HARDWARE_BUS_USB 0x03
#define SDL_HARDWARE_BUS_BLUETOOTH 0x05 #define SDL_HARDWARE_BUS_BLUETOOTH 0x05
#define SDL_HARDWARE_BUS_VIRTUAL 0xFF
/* Joystick capability flags for GetCapabilities() */ /* Joystick capability flags for GetCapabilities() */
#define SDL_JOYCAP_LED 0x01 #define SDL_JOYCAP_LED 0x01

View File

@ -360,7 +360,7 @@ Android_AddJoystick(int device_id, const char *name, const char *desc, int vendo
/* We only need 16 bits for each of these; space them out to fill 128. */ /* We only need 16 bits for each of these; space them out to fill 128. */
/* Byteswap so devices get same GUID on little/big endian platforms. */ /* Byteswap so devices get same GUID on little/big endian platforms. */
*guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_BLUETOOTH); *guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_BLUETOOTH);
*guid16++ = 0; *guid16++ = SDL_SwapLE16(SDL_crc16(0, desc, SDL_strlen(desc)));
if (vendor_id && product_id) { if (vendor_id && product_id) {
*guid16++ = SDL_SwapLE16(vendor_id); *guid16++ = SDL_SwapLE16(vendor_id);
@ -368,12 +368,8 @@ Android_AddJoystick(int device_id, const char *name, const char *desc, int vendo
*guid16++ = SDL_SwapLE16(product_id); *guid16++ = SDL_SwapLE16(product_id);
*guid16++ = 0; *guid16++ = 0;
} else { } else {
Uint32 crc = 0; SDL_strlcpy((char*)guid16, name, 4*sizeof(Uint16));
SDL_crc32(crc, desc, SDL_strlen(desc)); guid16 += 4;
SDL_memcpy(guid16, desc, SDL_min(2*sizeof(*guid16), SDL_strlen(desc)));
guid16 += 2;
*(Uint32 *)guid16 = SDL_SwapLE32(crc);
guid16 += 2;
} }
*guid16++ = SDL_SwapLE16(button_mask); *guid16++ = SDL_SwapLE16(button_mask);

View File

@ -702,11 +702,15 @@ BSD_JoystickQuit(void)
static SDL_JoystickGUID static SDL_JoystickGUID
BSD_JoystickGetDeviceGUID(int device_index) BSD_JoystickGetDeviceGUID(int device_index)
{ {
SDL_JoystickGUID guid; /* the GUID is just the name for now */
/* the GUID is just the first 16 chars of the name for now */
const char *name = BSD_JoystickGetDeviceName(device_index); const char *name = BSD_JoystickGetDeviceName(device_index);
SDL_JoystickGUID guid;
Uint16 *guid16 = (Uint16 *)guid.data;
SDL_zero(guid); SDL_zero(guid);
SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); *guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_UNKNOWN);
*guid16++ = SDL_SwapLE16(SDL_crc16(0, name, SDL_strlen(name)));
SDL_strlcpy((char*)guid16, name, sizeof(guid.data) - 4);
return guid; return guid;
} }

View File

@ -504,7 +504,7 @@ GetDeviceInfo(IOHIDDeviceRef hidDevice, recDevice *pDevice)
if (vendor && product) { if (vendor && product) {
*guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_USB); *guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_USB);
*guid16++ = 0; *guid16++ = SDL_SwapLE16(SDL_crc16(0, pDevice->product, SDL_strlen(pDevice->product)));
*guid16++ = SDL_SwapLE16((Uint16)vendor); *guid16++ = SDL_SwapLE16((Uint16)vendor);
*guid16++ = 0; *guid16++ = 0;
*guid16++ = SDL_SwapLE16((Uint16)product); *guid16++ = SDL_SwapLE16((Uint16)product);
@ -513,7 +513,7 @@ GetDeviceInfo(IOHIDDeviceRef hidDevice, recDevice *pDevice)
*guid16++ = 0; *guid16++ = 0;
} else { } else {
*guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_BLUETOOTH); *guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_BLUETOOTH);
*guid16++ = 0; *guid16++ = SDL_SwapLE16(SDL_crc16(0, pDevice->product, SDL_strlen(pDevice->product)));
SDL_strlcpy((char*)guid16, pDevice->product, sizeof(pDevice->guid.data) - 4); SDL_strlcpy((char*)guid16, pDevice->product, sizeof(pDevice->guid.data) - 4);
} }

View File

@ -394,11 +394,15 @@ EMSCRIPTEN_JoystickClose(SDL_Joystick *joystick)
static SDL_JoystickGUID static SDL_JoystickGUID
EMSCRIPTEN_JoystickGetDeviceGUID(int device_index) EMSCRIPTEN_JoystickGetDeviceGUID(int device_index)
{ {
SDL_JoystickGUID guid; /* the GUID is just the name for now */
/* the GUID is just the first 16 chars of the name for now */
const char *name = EMSCRIPTEN_JoystickGetDeviceName(device_index); const char *name = EMSCRIPTEN_JoystickGetDeviceName(device_index);
SDL_JoystickGUID guid;
Uint16 *guid16 = (Uint16 *)guid.data;
SDL_zero(guid); SDL_zero(guid);
SDL_memcpy(&guid, name, SDL_min(sizeof(guid), SDL_strlen(name))); *guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_UNKNOWN);
*guid16++ = SDL_SwapLE16(SDL_crc16(0, name, SDL_strlen(name)));
SDL_strlcpy((char*)guid16, name, sizeof(guid.data) - 4);
return guid; return guid;
} }

View File

@ -250,11 +250,15 @@ extern "C"
static SDL_JoystickGUID HAIKU_JoystickGetDeviceGUID(int device_index) static SDL_JoystickGUID HAIKU_JoystickGetDeviceGUID(int device_index)
{ {
SDL_JoystickGUID guid; /* the GUID is just the name for now */
/* the GUID is just the first 16 chars of the name for now */
const char *name = HAIKU_JoystickGetDeviceName(device_index); const char *name = HAIKU_JoystickGetDeviceName(device_index);
SDL_JoystickGUID guid;
Uint16 *guid16 = (Uint16 *)guid.data;
SDL_zero(guid); SDL_zero(guid);
SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); *guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_UNKNOWN);
*guid16++ = SDL_SwapLE16(SDL_crc16(0, name, SDL_strlen(name)));
SDL_strlcpy((char*)guid16, name, sizeof(guid.data) - 4);
return guid; return guid;
} }

View File

@ -603,26 +603,6 @@ HIDAPI_AddDevice(const struct SDL_hid_device_info *info, int num_children, SDL_H
device->interface_protocol = info->interface_protocol; device->interface_protocol = info->interface_protocol;
device->usage_page = info->usage_page; device->usage_page = info->usage_page;
device->usage = info->usage; device->usage = info->usage;
{
/* FIXME: Is there any way to tell whether this is a Bluetooth device? */
const Uint16 vendor = device->vendor_id;
const Uint16 product = device->product_id;
const Uint16 version = device->version;
Uint16 *guid16 = (Uint16 *)device->guid.data;
*guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_USB);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(vendor);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(product);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(version);
*guid16++ = 0;
/* Note that this is a HIDAPI device for special handling elsewhere */
device->guid.data[14] = 'h';
device->guid.data[15] = 0;
}
device->dev_lock = SDL_CreateMutex(); device->dev_lock = SDL_CreateMutex();
/* Need the device name before getting the driver to know whether to ignore this device */ /* Need the device name before getting the driver to know whether to ignore this device */
@ -654,6 +634,27 @@ HIDAPI_AddDevice(const struct SDL_hid_device_info *info, int num_children, SDL_H
} }
} }
{
/* FIXME: Is there any way to tell whether this is a Bluetooth device? */
const Uint16 vendor = device->vendor_id;
const Uint16 product = device->product_id;
const Uint16 version = device->version;
Uint16 *guid16 = (Uint16 *)device->guid.data;
*guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_USB);
*guid16++ = SDL_SwapLE16(SDL_crc16(0, device->name, SDL_strlen(device->name)));
*guid16++ = SDL_SwapLE16(vendor);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(product);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(version);
*guid16++ = 0;
/* Note that this is a HIDAPI device for special handling elsewhere */
device->guid.data[14] = 'h';
device->guid.data[15] = 0;
}
if (num_children > 0) { if (num_children > 0) {
int i; int i;

View File

@ -475,7 +475,7 @@ IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controlle
/* We only need 16 bits for each of these; space them out to fill 128. */ /* We only need 16 bits for each of these; space them out to fill 128. */
/* Byteswap so devices get same GUID on little/big endian platforms. */ /* Byteswap so devices get same GUID on little/big endian platforms. */
*guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_BLUETOOTH); *guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_BLUETOOTH);
*guid16++ = 0; *guid16++ = SDL_SwapLE16(SDL_crc16(0, name, SDL_strlen(name)));
*guid16++ = SDL_SwapLE16(vendor); *guid16++ = SDL_SwapLE16(vendor);
*guid16++ = 0; *guid16++ = 0;
*guid16++ = SDL_SwapLE16(product); *guid16++ = SDL_SwapLE16(product);

View File

@ -241,7 +241,7 @@ IsJoystick(const char *path, int fd, char **name_return, SDL_JoystickGUID *guid)
/* We only need 16 bits for each of these; space them out to fill 128. */ /* We only need 16 bits for each of these; space them out to fill 128. */
/* Byteswap so devices get same GUID on little/big endian platforms. */ /* Byteswap so devices get same GUID on little/big endian platforms. */
*guid16++ = SDL_SwapLE16(inpid.bustype); *guid16++ = SDL_SwapLE16(inpid.bustype);
*guid16++ = 0; *guid16++ = SDL_SwapLE16(SDL_crc16(0, name, SDL_strlen(name)));
if (inpid.vendor && inpid.product) { if (inpid.vendor && inpid.product) {
*guid16++ = SDL_SwapLE16(inpid.vendor); *guid16++ = SDL_SwapLE16(inpid.vendor);

View File

@ -399,11 +399,15 @@ static void OS2_JoystickSetDevicePlayerIndex(int device_index, int player_index)
static SDL_JoystickGUID OS2_JoystickGetDeviceGUID(int device_index) static SDL_JoystickGUID OS2_JoystickGetDeviceGUID(int device_index)
{ {
SDL_JoystickGUID guid; /* the GUID is just the name for now */
/* the GUID is just the first 16 chars of the name for now */
const char *name = OS2_JoystickGetDeviceName(device_index); const char *name = OS2_JoystickGetDeviceName(device_index);
SDL_JoystickGUID guid;
Uint16 *guid16 = (Uint16 *)guid.data;
SDL_zero(guid); SDL_zero(guid);
SDL_memcpy(&guid, name, SDL_min(sizeof(guid), SDL_strlen(name))); *guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_UNKNOWN);
*guid16++ = SDL_SwapLE16(SDL_crc16(0, name, SDL_strlen(name)));
SDL_strlcpy((char*)guid16, name, sizeof(guid.data) - 4);
return guid; return guid;
} }

View File

@ -169,11 +169,15 @@ static void PS2_JoystickSetDevicePlayerIndex(int device_index, int player_index)
/* Function to return the stable GUID for a plugged in device */ /* Function to return the stable GUID for a plugged in device */
static SDL_JoystickGUID PS2_JoystickGetDeviceGUID(int device_index) static SDL_JoystickGUID PS2_JoystickGetDeviceGUID(int device_index)
{ {
SDL_JoystickGUID guid; /* the GUID is just the name for now */
/* the GUID is just the first 16 chars of the name for now */
const char *name = PS2_JoystickGetDeviceName(device_index); const char *name = PS2_JoystickGetDeviceName(device_index);
SDL_JoystickGUID guid;
Uint16 *guid16 = (Uint16 *)guid.data;
SDL_zero(guid); SDL_zero(guid);
SDL_memcpy(&guid, name, SDL_min(sizeof(guid), SDL_strlen(name))); *guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_UNKNOWN);
*guid16++ = SDL_SwapLE16(SDL_crc16(0, name, SDL_strlen(name)));
SDL_strlcpy((char*)guid16, name, sizeof(guid.data) - 4);
return guid; return guid;
} }

View File

@ -134,11 +134,15 @@ static void PSP_JoystickSetDevicePlayerIndex(int device_index, int player_index)
static SDL_JoystickGUID PSP_JoystickGetDeviceGUID(int device_index) static SDL_JoystickGUID PSP_JoystickGetDeviceGUID(int device_index)
{ {
SDL_JoystickGUID guid; /* the GUID is just the name for now */
/* the GUID is just the first 16 chars of the name for now */
const char *name = PSP_JoystickGetDeviceName(device_index); const char *name = PSP_JoystickGetDeviceName(device_index);
SDL_JoystickGUID guid;
Uint16 *guid16 = (Uint16 *)guid.data;
SDL_zero(guid); SDL_zero(guid);
SDL_memcpy(&guid, name, SDL_min(sizeof(guid), SDL_strlen(name))); *guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_UNKNOWN);
*guid16++ = SDL_SwapLE16(SDL_crc16(0, name, SDL_strlen(name)));
SDL_strlcpy((char*)guid16, name, sizeof(guid.data) - 4);
return guid; return guid;
} }

View File

@ -198,7 +198,7 @@ SDL_JoystickAttachVirtualInner(const SDL_VirtualJoystickDesc *desc)
/* Byteswap so devices get same GUID on little/big endian platforms. */ /* Byteswap so devices get same GUID on little/big endian platforms. */
guid16 = (Uint16 *)hwdata->guid.data; guid16 = (Uint16 *)hwdata->guid.data;
*guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_VIRTUAL); *guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_VIRTUAL);
*guid16++ = 0; *guid16++ = SDL_SwapLE16(SDL_crc16(0, name, SDL_strlen(name)));
*guid16++ = SDL_SwapLE16(hwdata->desc.vendor_id); *guid16++ = SDL_SwapLE16(hwdata->desc.vendor_id);
*guid16++ = 0; *guid16++ = 0;
*guid16++ = SDL_SwapLE16(hwdata->desc.product_id); *guid16++ = SDL_SwapLE16(hwdata->desc.product_id);

View File

@ -343,11 +343,15 @@ void VITA_JoystickQuit(void)
SDL_JoystickGUID VITA_JoystickGetDeviceGUID(int device_index) SDL_JoystickGUID VITA_JoystickGetDeviceGUID(int device_index)
{ {
SDL_JoystickGUID guid; /* the GUID is just the name for now */
/* the GUID is just the first 16 chars of the name for now */
const char *name = VITA_JoystickGetDeviceName(device_index); const char *name = VITA_JoystickGetDeviceName(device_index);
SDL_JoystickGUID guid;
Uint16 *guid16 = (Uint16 *)guid.data;
SDL_zero(guid); SDL_zero(guid);
SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); *guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_UNKNOWN);
*guid16++ = SDL_SwapLE16(SDL_crc16(0, name, SDL_strlen(name)));
SDL_strlcpy((char*)guid16, name, sizeof(guid.data) - 4);
return guid; return guid;
} }

View File

@ -501,7 +501,7 @@ EnumJoystickDetectCallback(LPCDIDEVICEINSTANCE pDeviceInstance, LPVOID pContext)
guid16 = (Uint16 *)pNewJoystick->guid.data; guid16 = (Uint16 *)pNewJoystick->guid.data;
if (vendor && product) { if (vendor && product) {
*guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_USB); *guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_USB);
*guid16++ = 0; *guid16++ = SDL_SwapLE16(SDL_crc16(0, pNewJoystick->joystickname, SDL_strlen(pNewJoystick->joystickname)));
*guid16++ = SDL_SwapLE16(vendor); *guid16++ = SDL_SwapLE16(vendor);
*guid16++ = 0; *guid16++ = 0;
*guid16++ = SDL_SwapLE16(product); *guid16++ = SDL_SwapLE16(product);
@ -510,7 +510,7 @@ EnumJoystickDetectCallback(LPCDIDEVICEINSTANCE pDeviceInstance, LPVOID pContext)
*guid16++ = 0; *guid16++ = 0;
} else { } else {
*guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_BLUETOOTH); *guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_BLUETOOTH);
*guid16++ = 0; *guid16++ = SDL_SwapLE16(SDL_crc16(0, pNewJoystick->joystickname, SDL_strlen(pNewJoystick->joystickname)));
SDL_strlcpy((char*)guid16, pNewJoystick->joystickname, sizeof(pNewJoystick->guid.data) - 4); SDL_strlcpy((char*)guid16, pNewJoystick->joystickname, sizeof(pNewJoystick->guid.data) - 4);
} }

View File

@ -755,26 +755,6 @@ RAWINPUT_AddDevice(HANDLE hDevice)
CHECK(device->preparsed_data = (PHIDP_PREPARSED_DATA)SDL_calloc(size, sizeof(BYTE))); CHECK(device->preparsed_data = (PHIDP_PREPARSED_DATA)SDL_calloc(size, sizeof(BYTE)));
CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_PREPARSEDDATA, device->preparsed_data, &size) != (UINT)-1); CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_PREPARSEDDATA, device->preparsed_data, &size) != (UINT)-1);
{
const Uint16 vendor = device->vendor_id;
const Uint16 product = device->product_id;
const Uint16 version = device->version;
Uint16 *guid16 = (Uint16 *)device->guid.data;
*guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_USB);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(vendor);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(product);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(version);
*guid16++ = 0;
/* Note that this is a RAWINPUT device for special handling elsewhere */
device->guid.data[14] = 'r';
device->guid.data[15] = 0;
}
hFile = CreateFileA(dev_name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); hFile = CreateFileA(dev_name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
CHECK(hFile != INVALID_HANDLE_VALUE); CHECK(hFile != INVALID_HANDLE_VALUE);
@ -799,6 +779,26 @@ RAWINPUT_AddDevice(HANDLE hDevice)
SDL_free(product_string); SDL_free(product_string);
} }
} }
{
const Uint16 vendor = device->vendor_id;
const Uint16 product = device->product_id;
const Uint16 version = device->version;
Uint16 *guid16 = (Uint16 *)device->guid.data;
*guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_USB);
*guid16++ = SDL_SwapLE16(SDL_crc16(0, device->name, SDL_strlen(device->name)));
*guid16++ = SDL_SwapLE16(vendor);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(product);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(version);
*guid16++ = 0;
/* Note that this is a RAWINPUT device for special handling elsewhere */
device->guid.data[14] = 'r';
device->guid.data[15] = 0;
}
device->path = SDL_strdup(dev_name); device->path = SDL_strdup(dev_name);
CloseHandle(hFile); CloseHandle(hFile);

View File

@ -320,7 +320,7 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdde
/* FIXME: Is there any way to tell whether this is a Bluetooth device? */ /* FIXME: Is there any way to tell whether this is a Bluetooth device? */
*guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_USB); *guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_USB);
*guid16++ = 0; *guid16++ = SDL_SwapLE16(SDL_crc16(0, name, SDL_strlen(name)));
*guid16++ = SDL_SwapLE16(vendor); *guid16++ = SDL_SwapLE16(vendor);
*guid16++ = 0; *guid16++ = 0;
*guid16++ = SDL_SwapLE16(product); *guid16++ = SDL_SwapLE16(product);

View File

@ -279,13 +279,19 @@ AddXInputDevice(Uint8 userid, BYTE SubType, JoyStick_DeviceData **pContext)
} }
pNewJoystick->bXInputDevice = SDL_TRUE; pNewJoystick->bXInputDevice = SDL_TRUE;
pNewJoystick->joystickname = SDL_CreateJoystickName(vendor, product, NULL, GetXInputName(userid, SubType));
if (!pNewJoystick->joystickname) {
SDL_free(pNewJoystick);
return; /* better luck next time? */
}
SDL_snprintf(pNewJoystick->path, sizeof(pNewJoystick->path), "XInput#%d", userid);
if (!SDL_XInputUseOldJoystickMapping()) { if (!SDL_XInputUseOldJoystickMapping()) {
Uint16 *guid16 = (Uint16 *)pNewJoystick->guid.data; Uint16 *guid16 = (Uint16 *)pNewJoystick->guid.data;
GuessXInputDevice(userid, &vendor, &product, &version); GuessXInputDevice(userid, &vendor, &product, &version);
*guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_USB); *guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_USB);
*guid16++ = 0; *guid16++ = SDL_SwapLE16(SDL_crc16(0, pNewJoystick->joystickname, SDL_strlen(pNewJoystick->joystickname)));
*guid16++ = SDL_SwapLE16(vendor); *guid16++ = SDL_SwapLE16(vendor);
*guid16++ = 0; *guid16++ = 0;
*guid16++ = SDL_SwapLE16(product); *guid16++ = SDL_SwapLE16(product);
@ -299,12 +305,6 @@ AddXInputDevice(Uint8 userid, BYTE SubType, JoyStick_DeviceData **pContext)
} }
pNewJoystick->SubType = SubType; pNewJoystick->SubType = SubType;
pNewJoystick->XInputUserId = userid; pNewJoystick->XInputUserId = userid;
pNewJoystick->joystickname = SDL_CreateJoystickName(vendor, product, NULL, GetXInputName(userid, SubType));
if (!pNewJoystick->joystickname) {
SDL_free(pNewJoystick);
return; /* better luck next time? */
}
SDL_snprintf(pNewJoystick->path, sizeof(pNewJoystick->path), "XInput#%d", userid);
if (SDL_ShouldIgnoreJoystick(pNewJoystick->joystickname, pNewJoystick->guid)) { if (SDL_ShouldIgnoreJoystick(pNewJoystick->joystickname, pNewJoystick->guid)) {
SDL_free(pNewJoystick); SDL_free(pNewJoystick);