mirror of
https://github.com/glfw/glfw.git
synced 2025-06-15 20:22:15 +00:00
input: Hold joystick GUID in binary form
This commit is contained in:
parent
11324968ee
commit
1698fb2af1
@ -155,8 +155,7 @@ cacheRead(const char *path, _GLFWmapping** out, int* count)
|
||||
{
|
||||
mapping = &mappings[i];
|
||||
FREAD_n(mapping->name, 128, f);
|
||||
FREAD_n(mapping->guid, 32, f);
|
||||
mapping->guid[32] = '\0';
|
||||
FREAD_n(mapping->guid, 16, f);
|
||||
FREAD_n(mapping->buttons, 15, f);
|
||||
FREAD_n(mapping->axes, 6, f);
|
||||
}
|
||||
@ -202,7 +201,7 @@ cacheWrite(const char *path, const _GLFWmapping* mappings, int count)
|
||||
for (i = 0; i < count; ++i) {
|
||||
mapping = &mappings[i];
|
||||
FWRITE_n(mapping->name, 128, f);
|
||||
FWRITE_n(mapping->guid, 32, f);
|
||||
FWRITE_n(mapping->guid, 16, f);
|
||||
FWRITE_n(mapping->buttons, 15, f);
|
||||
FWRITE_n(mapping->axes, 6, f);
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ static void matchCallback(void* context,
|
||||
{
|
||||
int jid;
|
||||
char name[256];
|
||||
char guid[33];
|
||||
uint8_t guid[16];
|
||||
CFIndex i;
|
||||
CFTypeRef property;
|
||||
uint32_t vendor = 0, product = 0, version = 0;
|
||||
@ -169,17 +169,18 @@ static void matchCallback(void* context,
|
||||
// Generate a joystick GUID that matches the SDL 2.0.5+ one
|
||||
if (vendor && product)
|
||||
{
|
||||
sprintf(guid, "03000000%02x%02x0000%02x%02x0000%02x%02x0000",
|
||||
(uint8_t) vendor, (uint8_t) (vendor >> 8),
|
||||
(uint8_t) product, (uint8_t) (product >> 8),
|
||||
(uint8_t) version, (uint8_t) (version >> 8));
|
||||
guid[0] = 3;
|
||||
guid[4] = vendor & 0xff;
|
||||
guid[5] = vendor >> 8;
|
||||
guid[8] = product & 0xff;
|
||||
guid[9] = product >> 8;
|
||||
guid[12] = version & 0xff;
|
||||
guid[13] = version >> 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(guid, "05000000%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x00",
|
||||
name[0], name[1], name[2], name[3],
|
||||
name[4], name[5], name[6], name[7],
|
||||
name[8], name[9], name[10]);
|
||||
guid[0] = 5;
|
||||
memcpy(&guid[4], name, 11);
|
||||
}
|
||||
|
||||
CFArrayRef elements =
|
||||
@ -469,15 +470,17 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
||||
return js->present;
|
||||
}
|
||||
|
||||
void _glfwPlatformUpdateGamepadGUID(char* guid)
|
||||
void _glfwPlatformUpdateGamepadGUID(uint8_t guid[16])
|
||||
{
|
||||
if ((strncmp(guid + 4, "000000000000", 12) == 0) &&
|
||||
(strncmp(guid + 20, "000000000000", 12) == 0))
|
||||
if ((memcmp(guid + 2, "\0\0\0\0\0\0", 6) == 0) &&
|
||||
(memcmp(guid + 10, "\0\0\0\0\0\0", 6) == 0))
|
||||
{
|
||||
char original[33];
|
||||
strncpy(original, guid, sizeof(original) - 1);
|
||||
sprintf(guid, "03000000%.4s0000%.4s000000000000",
|
||||
original, original + 16);
|
||||
uint8_t original[16];
|
||||
memcpy(original, guid, sizeof(original));
|
||||
memset(guid, '\0', sizeof(original));
|
||||
guid[0] = 3;
|
||||
memcpy(guid + 4, original, 2);
|
||||
memcpy(guid + 8, original + 8, 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
58
src/input.c
58
src/input.c
@ -30,8 +30,10 @@
|
||||
#include "internal.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -65,13 +67,13 @@ static GLFWbool initJoysticks(void)
|
||||
|
||||
// Finds a mapping based on joystick GUID
|
||||
//
|
||||
static _GLFWmapping* findMapping(const char* guid)
|
||||
static _GLFWmapping* findMapping(const uint8_t guid[16])
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < _glfw.mappingCount; i++)
|
||||
{
|
||||
if (strncmp(_glfw.mappings[i].guid, guid, 32) == 0)
|
||||
if (memcmp(_glfw.mappings[i].guid, guid, sizeof(_glfw.mappings[i].guid)) == 0)
|
||||
return _glfw.mappings + i;
|
||||
}
|
||||
|
||||
@ -93,6 +95,19 @@ static GLFWbool isValidElementForJoystick(const _GLFWmapelement* e,
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
// Converts a binary joystick GUID into a string
|
||||
//
|
||||
static void generateUserReadableGUID(const uint8_t guid[16],
|
||||
char out[33])
|
||||
{
|
||||
snprintf(out, 33,
|
||||
"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||
guid[0], guid[1], guid[2], guid[3],
|
||||
guid[4], guid[5], guid[6], guid[7],
|
||||
guid[8], guid[9], guid[10], guid[11],
|
||||
guid[12], guid[13], guid[14], guid[15]);
|
||||
}
|
||||
|
||||
// Finds a mapping based on joystick GUID and verifies element indices
|
||||
//
|
||||
static _GLFWmapping* findValidMapping(const _GLFWjoystick* js)
|
||||
@ -106,9 +121,11 @@ static _GLFWmapping* findValidMapping(const _GLFWjoystick* js)
|
||||
{
|
||||
if (!isValidElementForJoystick(mapping->buttons + i, js))
|
||||
{
|
||||
char guid[33];
|
||||
generateUserReadableGUID(mapping->guid, guid);
|
||||
_glfwInputError(GLFW_INVALID_VALUE,
|
||||
"Invalid button in gamepad mapping %s (%s)",
|
||||
mapping->guid,
|
||||
guid,
|
||||
mapping->name);
|
||||
return NULL;
|
||||
}
|
||||
@ -118,9 +135,11 @@ static _GLFWmapping* findValidMapping(const _GLFWjoystick* js)
|
||||
{
|
||||
if (!isValidElementForJoystick(mapping->axes + i, js))
|
||||
{
|
||||
char guid[33];
|
||||
generateUserReadableGUID(mapping->guid, guid);
|
||||
_glfwInputError(GLFW_INVALID_VALUE,
|
||||
"Invalid axis in gamepad mapping %s (%s)",
|
||||
mapping->guid,
|
||||
guid,
|
||||
mapping->name);
|
||||
return NULL;
|
||||
}
|
||||
@ -173,7 +192,23 @@ static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
memcpy(mapping->guid, c, length);
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
char nibble1 = c[2 * i];
|
||||
char nibble2 = c[2 * i + 1];
|
||||
uint8_t value;
|
||||
if (!isxdigit(nibble1) || !isxdigit(nibble2))
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_VALUE, NULL);
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
nibble1 = toupper(nibble1);
|
||||
nibble2 = toupper(nibble2);
|
||||
value = ((nibble1 >= 'A') ? nibble1 - 'A' + 10 : nibble1 - '0') << 4
|
||||
| ((nibble2 >= 'A') ? nibble2 - 'A' + 10 : nibble2 - '0');
|
||||
mapping->guid[i] = value;
|
||||
}
|
||||
|
||||
c += length + 1;
|
||||
|
||||
length = strcspn(c, ",");
|
||||
@ -261,12 +296,6 @@ static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
|
||||
c += strspn(c, ",");
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
if (mapping->guid[i] >= 'A' && mapping->guid[i] <= 'F')
|
||||
mapping->guid[i] += 'a' - 'A';
|
||||
}
|
||||
|
||||
_glfwPlatformUpdateGamepadGUID(mapping->guid);
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
@ -431,7 +460,7 @@ void _glfwInputJoystickHat(_GLFWjoystick* js, int hat, char value)
|
||||
// Returns an available joystick object with arrays and name allocated
|
||||
//
|
||||
_GLFWjoystick* _glfwAllocJoystick(const char* name,
|
||||
const char* guid,
|
||||
const uint8_t guid[16],
|
||||
int axisCount,
|
||||
int buttonCount,
|
||||
int hatCount)
|
||||
@ -458,7 +487,8 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name,
|
||||
js->buttonCount = buttonCount;
|
||||
js->hatCount = hatCount;
|
||||
|
||||
strncpy(js->guid, guid, sizeof(js->guid) - 1);
|
||||
memcpy(js->guid, guid, sizeof(js->guid));
|
||||
generateUserReadableGUID(guid, js->userReadableGUID);
|
||||
js->mapping = findValidMapping(js);
|
||||
|
||||
return js;
|
||||
@ -1112,7 +1142,7 @@ GLFWAPI const char* glfwGetJoystickGUID(int jid)
|
||||
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE))
|
||||
return NULL;
|
||||
|
||||
return js->guid;
|
||||
return js->userReadableGUID;
|
||||
}
|
||||
|
||||
GLFWAPI void glfwSetJoystickUserPointer(int jid, void* pointer)
|
||||
|
@ -477,7 +477,7 @@ struct _GLFWmapelement
|
||||
struct _GLFWmapping
|
||||
{
|
||||
char name[128];
|
||||
char guid[33];
|
||||
uint8_t guid[16];
|
||||
_GLFWmapelement buttons[15];
|
||||
_GLFWmapelement axes[6];
|
||||
};
|
||||
@ -495,7 +495,8 @@ struct _GLFWjoystick
|
||||
int hatCount;
|
||||
char* name;
|
||||
void* userPointer;
|
||||
char guid[33];
|
||||
uint8_t guid[16];
|
||||
char userReadableGUID[33];
|
||||
_GLFWmapping* mapping;
|
||||
|
||||
// This is defined in the joystick API's joystick.h
|
||||
@ -636,7 +637,7 @@ const char* _glfwPlatformGetClipboardString(void);
|
||||
GLFWbool _glfwPlatformInitJoysticks(void);
|
||||
void _glfwPlatformTerminateJoysticks(void);
|
||||
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode);
|
||||
void _glfwPlatformUpdateGamepadGUID(char* guid);
|
||||
void _glfwPlatformUpdateGamepadGUID(uint8_t guid[16]);
|
||||
|
||||
uint64_t _glfwPlatformGetTimerValue(void);
|
||||
uint64_t _glfwPlatformGetTimerFrequency(void);
|
||||
@ -778,7 +779,7 @@ void _glfwFreeGammaArrays(GLFWgammaramp* ramp);
|
||||
void _glfwSplitBPP(int bpp, int* red, int* green, int* blue);
|
||||
|
||||
_GLFWjoystick* _glfwAllocJoystick(const char* name,
|
||||
const char* guid,
|
||||
const uint8_t guid[16],
|
||||
int axisCount,
|
||||
int buttonCount,
|
||||
int hatCount);
|
||||
|
@ -168,24 +168,25 @@ static GLFWbool openJoystickDevice(const char* path)
|
||||
if (ioctl(linjs.fd, EVIOCGNAME(sizeof(name)), name) < 0)
|
||||
strncpy(name, "Unknown", sizeof(name));
|
||||
|
||||
char guid[33] = "";
|
||||
uint8_t guid[16] = {0};
|
||||
|
||||
// Generate a joystick GUID that matches the SDL 2.0.5+ one
|
||||
if (id.vendor && id.product && id.version)
|
||||
{
|
||||
sprintf(guid, "%02x%02x0000%02x%02x0000%02x%02x0000%02x%02x0000",
|
||||
id.bustype & 0xff, id.bustype >> 8,
|
||||
id.vendor & 0xff, id.vendor >> 8,
|
||||
id.product & 0xff, id.product >> 8,
|
||||
id.version & 0xff, id.version >> 8);
|
||||
guid[0] = id.bustype & 0xff;
|
||||
guid[1] = id.bustype >> 8;
|
||||
guid[4] = id.vendor & 0xff;
|
||||
guid[5] = id.vendor >> 8;
|
||||
guid[8] = id.product & 0xff;
|
||||
guid[9] = id.product >> 8;
|
||||
guid[12] = id.version & 0xff;
|
||||
guid[13] = id.version >> 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(guid, "%02x%02x0000%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x00",
|
||||
id.bustype & 0xff, id.bustype >> 8,
|
||||
name[0], name[1], name[2], name[3],
|
||||
name[4], name[5], name[6], name[7],
|
||||
name[8], name[9], name[10]);
|
||||
guid[0] = id.bustype & 0xff;
|
||||
guid[1] = id.bustype >> 8;
|
||||
memcpy(&guid[4], name, 11);
|
||||
}
|
||||
|
||||
int axisCount = 0, buttonCount = 0, hatCount = 0;
|
||||
@ -422,7 +423,7 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
||||
return js->present;
|
||||
}
|
||||
|
||||
void _glfwPlatformUpdateGamepadGUID(char* guid)
|
||||
void _glfwPlatformUpdateGamepadGUID(uint8_t guid[16])
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
void _glfwPlatformUpdateGamepadGUID(char* guid)
|
||||
void _glfwPlatformUpdateGamepadGUID(uint8_t guid[16])
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -351,7 +351,7 @@ static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user)
|
||||
IDirectInputDevice8* device;
|
||||
_GLFWobjenumWin32 data;
|
||||
_GLFWjoystick* js;
|
||||
char guid[33];
|
||||
uint8_t guid[16] = {0};
|
||||
char name[256];
|
||||
|
||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
@ -452,18 +452,16 @@ static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user)
|
||||
// Generate a joystick GUID that matches the SDL 2.0.5+ one
|
||||
if (memcmp(&di->guidProduct.Data4[2], "PIDVID", 6) == 0)
|
||||
{
|
||||
sprintf(guid, "03000000%02x%02x0000%02x%02x000000000000",
|
||||
(uint8_t) di->guidProduct.Data1,
|
||||
(uint8_t) (di->guidProduct.Data1 >> 8),
|
||||
(uint8_t) (di->guidProduct.Data1 >> 16),
|
||||
(uint8_t) (di->guidProduct.Data1 >> 24));
|
||||
guid[0] = 3;
|
||||
guid[4] = di->guidProduct.Data1 & 0xff;
|
||||
guid[5] = (di->guidProduct.Data1 >> 8) & 0xff;
|
||||
guid[8] = (di->guidProduct.Data1 >> 16) & 0xff;
|
||||
guid[9] = (di->guidProduct.Data1 >> 24) & 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(guid, "05000000%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x00",
|
||||
name[0], name[1], name[2], name[3],
|
||||
name[4], name[5], name[6], name[7],
|
||||
name[8], name[9], name[10]);
|
||||
guid[0] = 5;
|
||||
memcpy(&guid[4], name, 11);
|
||||
}
|
||||
|
||||
js = _glfwAllocJoystick(name, guid,
|
||||
@ -502,7 +500,7 @@ void _glfwDetectJoystickConnectionWin32(void)
|
||||
for (index = 0; index < XUSER_MAX_COUNT; index++)
|
||||
{
|
||||
int jid;
|
||||
char guid[33];
|
||||
uint8_t guid[16] = {0};
|
||||
XINPUT_CAPABILITIES xic;
|
||||
_GLFWjoystick* js;
|
||||
|
||||
@ -523,8 +521,8 @@ void _glfwDetectJoystickConnectionWin32(void)
|
||||
continue;
|
||||
|
||||
// Generate a joystick GUID that matches the SDL 2.0.5+ one
|
||||
sprintf(guid, "78696e707574%02x000000000000000000",
|
||||
xic.SubType & 0xff);
|
||||
memcpy(guid, "\x78\x69\x6e\x70\x75\x74", 6);
|
||||
guid[6] = xic.SubType & 0xff;
|
||||
|
||||
js = _glfwAllocJoystick(getDeviceDescription(&xic), guid, 6, 10, 1);
|
||||
if (!js)
|
||||
@ -740,14 +738,16 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
void _glfwPlatformUpdateGamepadGUID(char* guid)
|
||||
void _glfwPlatformUpdateGamepadGUID(uint8_t guid[16])
|
||||
{
|
||||
if (strcmp(guid + 20, "504944564944") == 0)
|
||||
if (memcmp(guid + 10, "\x50\x49\x44\x56\x49\x44", 6) == 0)
|
||||
{
|
||||
char original[33];
|
||||
strncpy(original, guid, sizeof(original) - 1);
|
||||
sprintf(guid, "03000000%.4s0000%.4s000000000000",
|
||||
original, original + 4);
|
||||
uint8_t original[16];
|
||||
memcpy(original, guid, sizeof(original));
|
||||
memset(guid, '\0', sizeof(original));
|
||||
guid[0] = 3;
|
||||
memcpy(guid + 4, original, 2);
|
||||
memcpy(guid + 8, original + 2, 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user