Refactor joystick GUID creation

This commit is contained in:
Sam Lantinga 2022-08-22 19:28:21 -07:00
parent aae566e196
commit 277b033e78
19 changed files with 78 additions and 221 deletions

View File

@ -1973,6 +1973,46 @@ SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, c
return name;
}
SDL_JoystickGUID
SDL_CreateJoystickGUID(Uint16 bus, Uint16 vendor, Uint16 product, Uint16 version, const char *name, Uint8 driver_signature, Uint8 driver_data)
{
SDL_JoystickGUID guid;
Uint16 *guid16 = (Uint16 *)guid.data;
SDL_zero(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(bus);
*guid16++ = SDL_SwapLE16(SDL_crc16(0, name, SDL_strlen(name)));
if (vendor && product) {
*guid16++ = SDL_SwapLE16(vendor);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(product);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(version);
guid.data[14] = driver_signature;
guid.data[15] = driver_data;
} else {
size_t available_space = sizeof(guid.data) - 4;
if (driver_signature) {
available_space -= 2;
guid.data[14] = driver_signature;
guid.data[15] = driver_data;
}
SDL_strlcpy((char*)guid16, name, available_space);
}
return guid;
}
SDL_JoystickGUID
SDL_CreateJoystickGUIDForName(const char *name)
{
return SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_UNKNOWN, 0, 0, 0, name, 0, 0);
}
SDL_GameControllerType
SDL_GetJoystickGameControllerTypeFromVIDPID(Uint16 vendor, Uint16 product, const char *name, SDL_bool forUI)
{

View File

@ -62,6 +62,12 @@ extern void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint1
*/
extern char *SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, const char *product_name);
/* Function to create a GUID for a joystick based on the VID/PID and name */
extern SDL_JoystickGUID SDL_CreateJoystickGUID(Uint16 bus, Uint16 vendor, Uint16 product, Uint16 version, const char *name, Uint8 driver_signature, Uint8 driver_data);
/* Function to create a GUID for a joystick based on the name, with no VID/PID information */
extern SDL_JoystickGUID SDL_CreateJoystickGUIDForName(const char *name);
/* Function to return the type of a controller */
extern SDL_GameControllerType SDL_GetJoystickGameControllerTypeFromVIDPID(Uint16 vendor, Uint16 product, const char *name, SDL_bool forUI);
extern SDL_GameControllerType SDL_GetJoystickGameControllerTypeFromGUID(SDL_JoystickGUID guid, const char *name);

View File

@ -303,7 +303,6 @@ Android_AddJoystick(int device_id, const char *name, const char *desc, int vendo
{
SDL_joylist_item *item;
SDL_JoystickGUID guid;
Uint16 *guid16 = (Uint16 *)guid.data;
int i;
int axis_mask;
@ -355,26 +354,15 @@ Android_AddJoystick(int device_id, const char *name, const char *desc, int vendo
nhats = 0;
}
SDL_memset(guid.data, 0, sizeof(guid.data));
guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_BLUETOOTH, vendor_id, product_id, 0, desc, 0, 0);
/* 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++ = SDL_SwapLE16(SDL_crc16(0, desc, SDL_strlen(desc)));
if (vendor_id && product_id) {
*guid16++ = SDL_SwapLE16(vendor_id);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(product_id);
*guid16++ = 0;
} else {
SDL_strlcpy((char*)guid16, name, 4*sizeof(Uint16));
guid16 += 4;
/* Update the GUID with capability bits */
{
Uint16 *guid16 = (Uint16 *)guid.data;
guid16[6] = SDL_SwapLE16(button_mask);
guid16[7] = SDL_SwapLE16(axis_mask);
}
*guid16++ = SDL_SwapLE16(button_mask);
*guid16++ = SDL_SwapLE16(axis_mask);
item = (SDL_joylist_item *) SDL_malloc(sizeof (SDL_joylist_item));
if (item == NULL) {
return -1;

View File

@ -704,14 +704,7 @@ BSD_JoystickGetDeviceGUID(int device_index)
{
/* the GUID is just the name for now */
const char *name = BSD_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;
return SDL_CreateJoystickGUIDForName(name);
}
static int

View File

@ -496,26 +496,11 @@ GetDeviceInfo(IOHIDDeviceRef hidDevice, recDevice *pDevice)
#ifdef SDL_JOYSTICK_HIDAPI
if (HIDAPI_IsDevicePresent(vendor, product, version, pDevice->product)) {
/* The HIDAPI driver is taking care of this device */
return 0;
return SDL_FALSE;
}
#endif
SDL_memset(pDevice->guid.data, 0, sizeof(pDevice->guid.data));
if (vendor && product) {
*guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_USB);
*guid16++ = SDL_SwapLE16(SDL_crc16(0, pDevice->product, SDL_strlen(pDevice->product)));
*guid16++ = SDL_SwapLE16((Uint16)vendor);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16((Uint16)product);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16((Uint16)version);
*guid16++ = 0;
} else {
*guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_BLUETOOTH);
*guid16++ = SDL_SwapLE16(SDL_crc16(0, pDevice->product, SDL_strlen(pDevice->product)));
SDL_strlcpy((char*)guid16, pDevice->product, sizeof(pDevice->guid.data) - 4);
}
pDevice->guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_USB, (Uint16)vendor, (Uint16)product, (Uint16)version, pDevice->product, 0, 0);
array = IOHIDDeviceCopyMatchingElements(hidDevice, NULL, kIOHIDOptionsTypeNone);
if (array) {

View File

@ -396,14 +396,7 @@ EMSCRIPTEN_JoystickGetDeviceGUID(int device_index)
{
/* 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);
*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 SDL_CreateJoystickGUIDForName(name);
}
static int

View File

@ -252,14 +252,7 @@ extern "C"
{
/* the GUID is just the name for now */
const char *name = HAIKU_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;
return SDL_CreateJoystickGUIDForName(name);
}
static int HAIKU_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)

View File

@ -634,26 +634,8 @@ 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;
}
device->guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_USB, device->vendor_id, device->product_id, device->version, device->name, 'h', 0);
if (num_children > 0) {
int i;

View File

@ -220,7 +220,6 @@ IsControllerSwitchJoyConPair(GCController *controller)
static BOOL
IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controller)
{
Uint16 *guid16 = (Uint16 *)device->guid.data;
Uint16 vendor = 0;
Uint16 product = 0;
Uint8 subtype = 0;
@ -472,23 +471,17 @@ IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controlle
}
#endif /* TARGET_OS_TV */
/* 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++ = SDL_SwapLE16(SDL_crc16(0, name, SDL_strlen(name)));
*guid16++ = SDL_SwapLE16(vendor);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(product);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(device->button_mask);
if (vendor == USB_VENDOR_APPLE) {
/* Note that this is an MFI controller and what subtype it is */
device->guid.data[14] = 'm';
device->guid.data[15] = subtype;
device->guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_BLUETOOTH, vendor, product, 0, name, 'm', subtype);
} else {
device->guid.data[15] = subtype;
device->guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_BLUETOOTH, vendor, product, 0, name, 0, subtype);
}
/* Update the GUID with capability bits */
{
Uint16 *guid16 = (Uint16 *)device->guid.data;
guid16[6] = SDL_SwapLE16(device->button_mask);
}
/* This will be set when the first button press of the controller is

View File

@ -192,7 +192,6 @@ static int
IsJoystick(const char *path, int fd, char **name_return, SDL_JoystickGUID *guid)
{
struct input_id inpid;
Uint16 *guid16 = (Uint16 *)guid->data;
char *name;
char product_string[128];
@ -236,23 +235,7 @@ IsJoystick(const char *path, int fd, char **name_return, SDL_JoystickGUID *guid)
SDL_Log("Joystick: %s, bustype = %d, vendor = 0x%.4x, product = 0x%.4x, version = %d\n", name, inpid.bustype, inpid.vendor, inpid.product, inpid.version);
#endif
SDL_memset(guid->data, 0, sizeof(guid->data));
/* 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++ = SDL_SwapLE16(SDL_crc16(0, name, SDL_strlen(name)));
if (inpid.vendor && inpid.product) {
*guid16++ = SDL_SwapLE16(inpid.vendor);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(inpid.product);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(inpid.version);
*guid16++ = 0;
} else {
SDL_strlcpy((char*)guid16, name, sizeof(guid->data) - 4);
}
*guid = SDL_CreateJoystickGUID(inpid.bustype, inpid.vendor, inpid.product, inpid.version, name, 0, 0);
if (SDL_ShouldIgnoreJoystick(name, *guid)) {
SDL_free(name);

View File

@ -401,14 +401,7 @@ static SDL_JoystickGUID OS2_JoystickGetDeviceGUID(int device_index)
{
/* 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;
return SDL_CreateJoystickGUIDForName(name);
}
static SDL_JoystickID OS2_JoystickGetDeviceInstanceID(int device_index)

View File

@ -171,14 +171,7 @@ static SDL_JoystickGUID PS2_JoystickGetDeviceGUID(int device_index)
{
/* 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);
*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 SDL_CreateJoystickGUIDForName(name);
}
/* Function to get the current instance id of the joystick located at device_index */

View File

@ -136,14 +136,7 @@ static SDL_JoystickGUID PSP_JoystickGetDeviceGUID(int device_index)
{
/* 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);
*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 SDL_CreateJoystickGUIDForName(name);
}
/* Function to perform the mapping from device index to the instance id for this index */

View File

@ -101,7 +101,6 @@ SDL_JoystickAttachVirtualInner(const SDL_VirtualJoystickDesc *desc)
joystick_hwdata *hwdata = NULL;
int device_index = -1;
const char *name = NULL;
Uint16 *guid16;
int axis_triggerleft = -1;
int axis_triggerright = -1;
@ -194,21 +193,7 @@ SDL_JoystickAttachVirtualInner(const SDL_VirtualJoystickDesc *desc)
}
}
/* 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 = (Uint16 *)hwdata->guid.data;
*guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_VIRTUAL);
*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);
*guid16++ = 0;
*guid16++ = 0;
*guid16++ = 0; /* This will be overwritten below with the virtual controller signature */
/* Note that this is a Virtual device and what subtype it is */
hwdata->guid.data[14] = 'v';
hwdata->guid.data[15] = (Uint8)hwdata->desc.type;
hwdata->guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_VIRTUAL, hwdata->desc.vendor_id, hwdata->desc.product_id, 0, name, 'v', (Uint8)hwdata->desc.type);
/* Allocate fields for different control-types */
if (hwdata->desc.naxes > 0) {

View File

@ -345,14 +345,7 @@ 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;
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;
return SDL_CreateJoystickGUIDForName(name);
}
static int

View File

@ -443,7 +443,6 @@ EnumJoystickDetectCallback(LPCDIDEVICEINSTANCE pDeviceInstance, LPVOID pContext)
#define CHECK(expression) { if(!(expression)) goto err; }
JoyStick_DeviceData *pNewJoystick = NULL;
JoyStick_DeviceData *pPrevJoystick = NULL;
Uint16 *guid16;
Uint16 vendor = 0;
Uint16 product = 0;
Uint16 version = 0;
@ -493,25 +492,14 @@ EnumJoystickDetectCallback(LPCDIDEVICEINSTANCE pDeviceInstance, LPVOID pContext)
SDL_zerop(pNewJoystick);
SDL_strlcpy(pNewJoystick->path, hidPath, SDL_arraysize(pNewJoystick->path));
SDL_memcpy(&pNewJoystick->dxdevice, pDeviceInstance, sizeof(DIDEVICEINSTANCE));
SDL_memset(pNewJoystick->guid.data, 0, sizeof(pNewJoystick->guid.data));
pNewJoystick->joystickname = SDL_CreateJoystickName(vendor, product, NULL, name);
CHECK(pNewJoystick->joystickname);
guid16 = (Uint16 *)pNewJoystick->guid.data;
if (vendor && product) {
*guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_USB);
*guid16++ = SDL_SwapLE16(SDL_crc16(0, pNewJoystick->joystickname, SDL_strlen(pNewJoystick->joystickname)));
*guid16++ = SDL_SwapLE16(vendor);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(product);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(version);
*guid16++ = 0;
pNewJoystick->guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_USB, vendor, product, version, pNewJoystick->joystickname, 0, 0);
} else {
*guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_BLUETOOTH);
*guid16++ = SDL_SwapLE16(SDL_crc16(0, pNewJoystick->joystickname, SDL_strlen(pNewJoystick->joystickname)));
SDL_strlcpy((char*)guid16, pNewJoystick->joystickname, sizeof(pNewJoystick->guid.data) - 4);
pNewJoystick->guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_BLUETOOTH, vendor, product, version, pNewJoystick->joystickname, 0, 0);
}
CHECK(!SDL_ShouldIgnoreJoystick(pNewJoystick->joystickname, pNewJoystick->guid));

View File

@ -779,25 +779,8 @@ 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->guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_USB, device->vendor_id, device->product_id, device->version, device->name, 'r', 0);
device->path = SDL_strdup(dev_name);

View File

@ -254,7 +254,6 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdde
Uint16 product = 0;
Uint16 version = 0;
SDL_JoystickType type = SDL_JOYSTICK_TYPE_UNKNOWN;
Uint16 *guid16 = (Uint16 *)guid.data;
__x_ABI_CWindows_CGaming_CInput_CIRawGameController2 *controller2 = NULL;
__x_ABI_CWindows_CGaming_CInput_CIGameController *gamecontroller = NULL;
SDL_bool ignore_joystick = SDL_FALSE;
@ -319,18 +318,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++ = SDL_SwapLE16(SDL_crc16(0, name, SDL_strlen(name)));
*guid16++ = SDL_SwapLE16(vendor);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(product);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(version);
*guid16++ = 0;
/* Note that this is a Windows Gaming Input device for special handling elsewhere */
guid.data[14] = 'w';
guid.data[15] = (Uint8)type;
guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_USB, vendor, product, version, name, 'w', (Uint8)type);
#ifdef SDL_JOYSTICK_HIDAPI
if (!ignore_joystick && HIDAPI_IsDevicePresent(vendor, product, version, name)) {

View File

@ -286,22 +286,7 @@ AddXInputDevice(Uint8 userid, BYTE SubType, JoyStick_DeviceData **pContext)
}
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++ = SDL_SwapLE16(SDL_crc16(0, pNewJoystick->joystickname, SDL_strlen(pNewJoystick->joystickname)));
*guid16++ = SDL_SwapLE16(vendor);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(product);
*guid16++ = 0;
*guid16++ = SDL_SwapLE16(version);
*guid16++ = 0;
/* Note that this is an XInput device and what subtype it is */
pNewJoystick->guid.data[14] = 'x';
pNewJoystick->guid.data[15] = SubType;
pNewJoystick->guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_USB, vendor, product, version, pNewJoystick->joystickname, 'x', SubType);
}
pNewJoystick->SubType = SubType;
pNewJoystick->XInputUserId = userid;