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_GetJoystickGUIDInfo(guid, &vendor, &product, NULL);
SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL, NULL);
if ((vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_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)
{
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) {
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;
}
mapping = mapping->next;
@ -1836,7 +1844,7 @@ SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid)
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)) {
/* 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 */
}
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 bus = SDL_SwapLE16(guid16[0]);
/* If the GUID fits the form of BUS 0000 VENDOR 0000 PRODUCT 0000, return the data */
if (/* guid16[0] is device bus type */
guid16[1] == 0x0000 &&
/* guid16[2] is vendor ID */
guid16[3] == 0x0000 &&
/* guid16[4] is product ID */
guid16[5] == 0x0000
/* guid16[6] is product version */
) {
if (bus < ' ' && guid16[3] == 0x0000 && guid16[5] == 0x0000) {
/* This GUID fits the standard form:
* 16-bit bus
* 16-bit CRC16 of the joystick name (can be zero)
* 16-bit vendor ID
* 16-bit zero
* 16-bit product ID
* 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) {
*vendor = SDL_SwapLE16(guid16[2]);
}
@ -1790,6 +1794,27 @@ void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *prod
if (version) {
*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 {
if (vendor) {
*vendor = 0;
@ -1800,6 +1825,9 @@ void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *prod
if (version) {
*version = 0;
}
if (crc16) {
*crc16 = 0;
}
}
}
@ -2045,7 +2073,7 @@ SDL_GetJoystickGameControllerTypeFromGUID(SDL_JoystickGUID guid, const char *nam
SDL_GameControllerType type;
Uint16 vendor, product;
SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL);
SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL, NULL);
type = SDL_GetJoystickGameControllerTypeFromVIDPID(vendor, product, name, SDL_TRUE);
if (type == SDL_CONTROLLER_TYPE_UNKNOWN) {
if (SDL_IsJoystickXInput(guid)) {
@ -2379,7 +2407,7 @@ static SDL_JoystickType SDL_GetJoystickGUIDType(SDL_JoystickGUID guid)
return (SDL_JoystickType)guid.data[15];
}
SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL);
SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL, NULL);
vidpid = MAKE_VIDPID(vendor, product);
if (SDL_IsJoystickProductWheel(vidpid)) {
@ -2567,7 +2595,7 @@ SDL_bool SDL_ShouldIgnoreJoystick(const char *name, SDL_JoystickGUID guid)
Uint16 product;
SDL_GameControllerType type;
SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL);
SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL, NULL);
/* Check the joystick blacklist */
id = MAKE_VIDPID(vendor, product);
@ -2618,7 +2646,7 @@ Uint16 SDL_JoystickGetDeviceVendor(int device_index)
Uint16 vendor;
SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(device_index);
SDL_GetJoystickGUIDInfo(guid, &vendor, NULL, NULL);
SDL_GetJoystickGUIDInfo(guid, &vendor, NULL, NULL, NULL);
return vendor;
}
@ -2627,7 +2655,7 @@ Uint16 SDL_JoystickGetDeviceProduct(int device_index)
Uint16 product;
SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(device_index);
SDL_GetJoystickGUIDInfo(guid, NULL, &product, NULL);
SDL_GetJoystickGUIDInfo(guid, NULL, &product, NULL, NULL);
return product;
}
@ -2636,7 +2664,7 @@ Uint16 SDL_JoystickGetDeviceProductVersion(int device_index)
Uint16 version;
SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(device_index);
SDL_GetJoystickGUIDInfo(guid, NULL, NULL, &version);
SDL_GetJoystickGUIDInfo(guid, NULL, NULL, &version, NULL);
return version;
}
@ -2700,7 +2728,7 @@ Uint16 SDL_JoystickGetVendor(SDL_Joystick *joystick)
Uint16 vendor;
SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick);
SDL_GetJoystickGUIDInfo(guid, &vendor, NULL, NULL);
SDL_GetJoystickGUIDInfo(guid, &vendor, NULL, NULL, NULL);
return vendor;
}
@ -2709,7 +2737,7 @@ Uint16 SDL_JoystickGetProduct(SDL_Joystick *joystick)
Uint16 product;
SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick);
SDL_GetJoystickGUIDInfo(guid, NULL, &product, NULL);
SDL_GetJoystickGUIDInfo(guid, NULL, &product, NULL, NULL);
return product;
}
@ -2718,7 +2746,7 @@ Uint16 SDL_JoystickGetProductVersion(SDL_Joystick *joystick)
Uint16 version;
SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick);
SDL_GetJoystickGUIDInfo(guid, NULL, NULL, &version);
SDL_GetJoystickGUIDInfo(guid, NULL, NULL, &version, NULL);
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);
/* 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
This should be freed with SDL_free() when no longer needed

View File

@ -125,9 +125,10 @@ struct _SDL_Joystick
};
/* 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_BLUETOOTH 0x05
#define SDL_HARDWARE_BUS_VIRTUAL 0xFF
/* Joystick capability flags for GetCapabilities() */
#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. */
/* Byteswap so devices get same GUID on little/big endian platforms. */
*guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_BLUETOOTH);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(SDL_crc16(0, desc, SDL_strlen(desc)));
if (vendor_id && product_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++ = 0;
} else {
Uint32 crc = 0;
SDL_crc32(crc, desc, SDL_strlen(desc));
SDL_memcpy(guid16, desc, SDL_min(2*sizeof(*guid16), SDL_strlen(desc)));
guid16 += 2;
*(Uint32 *)guid16 = SDL_SwapLE32(crc);
guid16 += 2;
SDL_strlcpy((char*)guid16, name, 4*sizeof(Uint16));
guid16 += 4;
}
*guid16++ = SDL_SwapLE16(button_mask);

View File

@ -700,13 +700,17 @@ BSD_JoystickQuit(void)
}
static SDL_JoystickGUID
BSD_JoystickGetDeviceGUID( int device_index )
BSD_JoystickGetDeviceGUID(int device_index)
{
/* the GUID is just the name for now */
const char *name = BSD_JoystickGetDeviceName(device_index);
SDL_JoystickGUID guid;
/* the GUID is just the first 16 chars of the name for now */
const char *name = BSD_JoystickGetDeviceName( device_index );
SDL_zero( guid );
SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
Uint16 *guid16 = (Uint16 *)guid.data;
SDL_zero(guid);
*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;
}

View File

@ -504,7 +504,7 @@ GetDeviceInfo(IOHIDDeviceRef hidDevice, recDevice *pDevice)
if (vendor && product) {
*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++ = 0;
*guid16++ = SDL_SwapLE16((Uint16)product);
@ -513,7 +513,7 @@ GetDeviceInfo(IOHIDDeviceRef hidDevice, recDevice *pDevice)
*guid16++ = 0;
} else {
*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);
}

View File

@ -394,11 +394,15 @@ EMSCRIPTEN_JoystickClose(SDL_Joystick *joystick)
static SDL_JoystickGUID
EMSCRIPTEN_JoystickGetDeviceGUID(int device_index)
{
SDL_JoystickGUID guid;
/* the GUID is just the first 16 chars of the name for now */
/* the GUID is just the name for now */
const char *name = EMSCRIPTEN_JoystickGetDeviceName(device_index);
SDL_JoystickGUID guid;
Uint16 *guid16 = (Uint16 *)guid.data;
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;
}

View File

@ -248,13 +248,17 @@ extern "C"
SDL_joyname[0] = NULL;
}
static SDL_JoystickGUID HAIKU_JoystickGetDeviceGUID( int device_index )
static SDL_JoystickGUID HAIKU_JoystickGetDeviceGUID(int device_index)
{
/* the GUID is just the name for now */
const char *name = HAIKU_JoystickGetDeviceName(device_index);
SDL_JoystickGUID guid;
/* the GUID is just the first 16 chars of the name for now */
const char *name = HAIKU_JoystickGetDeviceName( device_index );
SDL_zero( guid );
SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
Uint16 *guid16 = (Uint16 *)guid.data;
SDL_zero(guid);
*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;
}

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->usage_page = info->usage_page;
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();
/* 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) {
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. */
/* Byteswap so devices get same GUID on little/big endian platforms. */
*guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_BLUETOOTH);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(SDL_crc16(0, name, SDL_strlen(name)));
*guid16++ = SDL_SwapLE16(vendor);
*guid16++ = 0;
*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. */
/* Byteswap so devices get same GUID on little/big endian platforms. */
*guid16++ = SDL_SwapLE16(inpid.bustype);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(SDL_crc16(0, name, SDL_strlen(name)));
if (inpid.vendor && inpid.product) {
*guid16++ = SDL_SwapLE16(inpid.vendor);

View File

@ -399,12 +399,16 @@ static void OS2_JoystickSetDevicePlayerIndex(int device_index, int player_index)
static SDL_JoystickGUID OS2_JoystickGetDeviceGUID(int device_index)
{
SDL_JoystickGUID guid;
/* the GUID is just the first 16 chars of the name for now */
const char *name = OS2_JoystickGetDeviceName(device_index);
SDL_zero(guid);
SDL_memcpy(&guid, name, SDL_min(sizeof(guid), SDL_strlen(name)));
return guid;
/* the GUID is just the name for now */
const char *name = OS2_JoystickGetDeviceName(device_index);
SDL_JoystickGUID guid;
Uint16 *guid16 = (Uint16 *)guid.data;
SDL_zero(guid);
*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;
}
static SDL_JoystickID OS2_JoystickGetDeviceInstanceID(int device_index)

View File

@ -167,13 +167,17 @@ static void PS2_JoystickSetDevicePlayerIndex(int device_index, int player_index)
}
/* 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 first 16 chars of the name for now */
/* the GUID is just the name for now */
const char *name = PS2_JoystickGetDeviceName(device_index);
SDL_JoystickGUID guid;
Uint16 *guid16 = (Uint16 *)guid.data;
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;
}

View File

@ -134,11 +134,15 @@ static void PSP_JoystickSetDevicePlayerIndex(int device_index, int player_index)
static SDL_JoystickGUID PSP_JoystickGetDeviceGUID(int device_index)
{
SDL_JoystickGUID guid;
/* the GUID is just the first 16 chars of the name for now */
/* the GUID is just the name for now */
const char *name = PSP_JoystickGetDeviceName(device_index);
SDL_JoystickGUID guid;
Uint16 *guid16 = (Uint16 *)guid.data;
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;
}

View File

@ -198,7 +198,7 @@ SDL_JoystickAttachVirtualInner(const SDL_VirtualJoystickDesc *desc)
/* Byteswap so devices get same GUID on little/big endian platforms. */
guid16 = (Uint16 *)hwdata->guid.data;
*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++ = 0;
*guid16++ = SDL_SwapLE16(hwdata->desc.product_id);

View File

@ -341,13 +341,17 @@ void VITA_JoystickQuit(void)
{
}
SDL_JoystickGUID VITA_JoystickGetDeviceGUID( int device_index )
SDL_JoystickGUID VITA_JoystickGetDeviceGUID(int device_index)
{
/* the GUID is just the name for now */
const char *name = VITA_JoystickGetDeviceName(device_index);
SDL_JoystickGUID guid;
/* the GUID is just the first 16 chars of the name for now */
const char *name = VITA_JoystickGetDeviceName( device_index );
SDL_zero( guid );
SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
Uint16 *guid16 = (Uint16 *)guid.data;
SDL_zero(guid);
*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;
}

View File

@ -501,7 +501,7 @@ EnumJoystickDetectCallback(LPCDIDEVICEINSTANCE pDeviceInstance, LPVOID pContext)
guid16 = (Uint16 *)pNewJoystick->guid.data;
if (vendor && product) {
*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++ = 0;
*guid16++ = SDL_SwapLE16(product);
@ -510,7 +510,7 @@ EnumJoystickDetectCallback(LPCDIDEVICEINSTANCE pDeviceInstance, LPVOID pContext)
*guid16++ = 0;
} else {
*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);
}

View File

@ -755,26 +755,6 @@ RAWINPUT_AddDevice(HANDLE hDevice)
CHECK(device->preparsed_data = (PHIDP_PREPARSED_DATA)SDL_calloc(size, sizeof(BYTE)));
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);
CHECK(hFile != INVALID_HANDLE_VALUE);
@ -799,6 +779,26 @@ RAWINPUT_AddDevice(HANDLE hDevice)
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);
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? */
*guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_USB);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(SDL_crc16(0, name, SDL_strlen(name)));
*guid16++ = SDL_SwapLE16(vendor);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(product);

View File

@ -279,13 +279,19 @@ AddXInputDevice(Uint8 userid, BYTE SubType, JoyStick_DeviceData **pContext)
}
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()) {
Uint16 *guid16 = (Uint16 *)pNewJoystick->guid.data;
GuessXInputDevice(userid, &vendor, &product, &version);
*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++ = 0;
*guid16++ = SDL_SwapLE16(product);
@ -299,12 +305,6 @@ AddXInputDevice(Uint8 userid, BYTE SubType, JoyStick_DeviceData **pContext)
}
pNewJoystick->SubType = SubType;
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)) {
SDL_free(pNewJoystick);