mirror of https://github.com/encounter/SDL.git
Added SDL_JoystickGetSerial() and SDL_GameControllerGetSerial()
This commit is contained in:
parent
55e59a4f33
commit
d140d88744
|
@ -261,6 +261,13 @@ extern DECLSPEC Uint16 SDLCALL SDL_GameControllerGetProduct(SDL_GameController *
|
|||
*/
|
||||
extern DECLSPEC Uint16 SDLCALL SDL_GameControllerGetProductVersion(SDL_GameController *gamecontroller);
|
||||
|
||||
/**
|
||||
* Get the serial number of an opened controller, if available.
|
||||
*
|
||||
* Returns the serial number of the controller, or NULL if it is not available.
|
||||
*/
|
||||
extern DECLSPEC const char * SDLCALL SDL_GameControllerGetSerial(SDL_GameController *gamecontroller);
|
||||
|
||||
/**
|
||||
* Returns SDL_TRUE if the controller has been opened and currently connected,
|
||||
* or SDL_FALSE if it has not.
|
||||
|
|
|
@ -275,6 +275,13 @@ extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetProduct(SDL_Joystick * joystick);
|
|||
*/
|
||||
extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetProductVersion(SDL_Joystick *joystick);
|
||||
|
||||
/**
|
||||
* Get the serial number of an opened joystick, if available.
|
||||
*
|
||||
* Returns the serial number of the joystick, or NULL if it is not available.
|
||||
*/
|
||||
extern DECLSPEC const char * SDLCALL SDL_JoystickGetSerial(SDL_Joystick *joystick);
|
||||
|
||||
/**
|
||||
* Get the type of an opened joystick.
|
||||
*/
|
||||
|
|
|
@ -780,3 +780,5 @@
|
|||
#define SDL_GameControllerGetNumTouchpadFingers SDL_GameControllerGetNumTouchpadFingers_REAL
|
||||
#define SDL_GameControllerGetTouchpadFinger SDL_GameControllerGetTouchpadFinger_REAL
|
||||
#define SDL_crc32 SDL_crc32_REAL
|
||||
#define SDL_GameControllerGetSerial SDL_GameControllerGetSerial_REAL
|
||||
#define SDL_JoystickGetSerial SDL_JoystickGetSerial_REAL
|
||||
|
|
|
@ -841,3 +841,5 @@ SDL_DYNAPI_PROC(int,SDL_GameControllerGetNumTouchpads,(SDL_GameController *a),(a
|
|||
SDL_DYNAPI_PROC(int,SDL_GameControllerGetNumTouchpadFingers,(SDL_GameController *a, int b),(a,b),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_GameControllerGetTouchpadFinger,(SDL_GameController *a, int b, int c, Uint8 *d, float *e, float *f, float *g),(a,b,c,d,e,f,g),return)
|
||||
SDL_DYNAPI_PROC(Uint32,SDL_crc32,(Uint32 a, const void *b, size_t c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(const char*,SDL_GameControllerGetSerial,(SDL_GameController *a),(a),return)
|
||||
SDL_DYNAPI_PROC(const char*,SDL_JoystickGetSerial,(SDL_Joystick *a),(a),return)
|
||||
|
|
|
@ -2111,6 +2111,12 @@ SDL_GameControllerGetProductVersion(SDL_GameController * gamecontroller)
|
|||
return SDL_JoystickGetProductVersion(SDL_GameControllerGetJoystick(gamecontroller));
|
||||
}
|
||||
|
||||
const char *
|
||||
SDL_GameControllerGetSerial(SDL_GameController *gamecontroller)
|
||||
{
|
||||
return SDL_JoystickGetSerial(SDL_GameControllerGetJoystick(gamecontroller));
|
||||
}
|
||||
|
||||
/*
|
||||
* Return if the controller in question is currently attached to the system,
|
||||
* \return 0 if not plugged in, 1 if still present.
|
||||
|
@ -2127,7 +2133,8 @@ SDL_GameControllerGetAttached(SDL_GameController * gamecontroller)
|
|||
/*
|
||||
* Get the joystick for this controller
|
||||
*/
|
||||
SDL_Joystick *SDL_GameControllerGetJoystick(SDL_GameController * gamecontroller)
|
||||
SDL_Joystick *
|
||||
SDL_GameControllerGetJoystick(SDL_GameController *gamecontroller)
|
||||
{
|
||||
if (!gamecontroller)
|
||||
return NULL;
|
||||
|
|
|
@ -1025,6 +1025,7 @@ SDL_JoystickClose(SDL_Joystick * joystick)
|
|||
}
|
||||
|
||||
SDL_free(joystick->name);
|
||||
SDL_free(joystick->serial);
|
||||
|
||||
/* Free the data associated with this joystick */
|
||||
SDL_free(joystick->axes);
|
||||
|
@ -2354,6 +2355,14 @@ Uint16 SDL_JoystickGetProductVersion(SDL_Joystick * joystick)
|
|||
return version;
|
||||
}
|
||||
|
||||
const char *SDL_JoystickGetSerial(SDL_Joystick *joystick)
|
||||
{
|
||||
if (!SDL_PrivateJoystickValid(joystick)) {
|
||||
return NULL;
|
||||
}
|
||||
return joystick->serial;
|
||||
}
|
||||
|
||||
SDL_JoystickType SDL_JoystickGetType(SDL_Joystick *joystick)
|
||||
{
|
||||
SDL_JoystickType type;
|
||||
|
|
|
@ -57,6 +57,7 @@ struct _SDL_Joystick
|
|||
{
|
||||
SDL_JoystickID instance_id; /* Device instance, monotonically increasing from 0 */
|
||||
char *name; /* Joystick name - system dependent */
|
||||
char *serial; /* Joystick serial */
|
||||
SDL_JoystickGUID guid; /* Joystick guid */
|
||||
|
||||
int naxes; /* Number of axis controls on the joystick */
|
||||
|
|
|
@ -135,34 +135,11 @@ HIDAPI_DriverPS4_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static SDL_bool ReadFeatureReport(hid_device *dev, Uint8 report_id, Uint8 *data, size_t size)
|
||||
static int ReadFeatureReport(hid_device *dev, Uint8 report_id, Uint8 *report, size_t length)
|
||||
{
|
||||
Uint8 report[USB_PACKET_LENGTH + 1];
|
||||
|
||||
SDL_memset(report, 0, sizeof(report));
|
||||
SDL_memset(report, 0, length);
|
||||
report[0] = report_id;
|
||||
if (hid_get_feature_report(dev, report, sizeof(report)) < 0) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
SDL_memcpy(data, report, SDL_min(size, sizeof(report)));
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
static SDL_bool CheckUSBConnected(hid_device *dev)
|
||||
{
|
||||
int i;
|
||||
Uint8 data[16];
|
||||
|
||||
/* This will fail if we're on Bluetooth */
|
||||
if (ReadFeatureReport(dev, k_ePS4FeatureReportIdSerialNumber, data, sizeof(data))) {
|
||||
for (i = 0; i < sizeof(data); ++i) {
|
||||
if (data[i] != 0x00) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
}
|
||||
/* Maybe the dongle without a connected controller? */
|
||||
}
|
||||
return SDL_FALSE;
|
||||
return hid_get_feature_report(dev, report, length);
|
||||
}
|
||||
|
||||
static SDL_bool HIDAPI_DriverPS4_CanRumble(Uint16 vendor_id, Uint16 product_id)
|
||||
|
@ -310,7 +287,36 @@ HIDAPI_DriverPS4_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
|||
if (ctx->is_dongle) {
|
||||
ctx->is_bluetooth = SDL_FALSE;
|
||||
} else if (device->vendor_id == USB_VENDOR_SONY) {
|
||||
ctx->is_bluetooth = !CheckUSBConnected(device->dev);
|
||||
int i;
|
||||
Uint8 data[USB_PACKET_LENGTH];
|
||||
int length;
|
||||
|
||||
/* This will fail if we're on Bluetooth */
|
||||
length = ReadFeatureReport(device->dev, k_ePS4FeatureReportIdSerialNumber, data, sizeof(data));
|
||||
if (length >= 7) {
|
||||
SDL_bool had_data = SDL_FALSE;
|
||||
|
||||
for (i = 0; i < length; ++i) {
|
||||
if (data[i] != 0x00) {
|
||||
had_data = SDL_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (had_data) {
|
||||
char serial[18];
|
||||
|
||||
SDL_snprintf(serial, sizeof(serial), "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
|
||||
data[6], data[5], data[4], data[3], data[2], data[1]);
|
||||
joystick->serial = SDL_strdup(serial);
|
||||
} else {
|
||||
/* Maybe the dongle without a connected controller? */
|
||||
}
|
||||
|
||||
ctx->is_bluetooth = SDL_FALSE;
|
||||
} else {
|
||||
ctx->is_bluetooth = SDL_TRUE;
|
||||
}
|
||||
} else {
|
||||
/* Third party controllers appear to all be wired */
|
||||
ctx->is_bluetooth = SDL_FALSE;
|
||||
|
|
|
@ -140,16 +140,11 @@ HIDAPI_DriverPS5_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static SDL_bool ReadFeatureReport(hid_device *dev, Uint8 report_id)
|
||||
static int ReadFeatureReport(hid_device *dev, Uint8 report_id, Uint8 *report, size_t length)
|
||||
{
|
||||
Uint8 report[USB_PACKET_LENGTH + 1];
|
||||
|
||||
SDL_memset(report, 0, sizeof(report));
|
||||
SDL_memset(report, 0, length);
|
||||
report[0] = report_id;
|
||||
if (hid_get_feature_report(dev, report, sizeof(report)) < 0) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
return SDL_TRUE;
|
||||
return hid_get_feature_report(dev, report, length);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -277,6 +272,7 @@ static SDL_bool
|
|||
HIDAPI_DriverPS5_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
SDL_DriverPS5_Context *ctx;
|
||||
Uint8 data[USB_PACKET_LENGTH];
|
||||
|
||||
ctx = (SDL_DriverPS5_Context *)SDL_calloc(1, sizeof(*ctx));
|
||||
if (!ctx) {
|
||||
|
@ -295,7 +291,13 @@ HIDAPI_DriverPS5_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
|||
/* Read the serial number (Bluetooth address in reverse byte order)
|
||||
This will also enable enhanced reports over Bluetooth
|
||||
*/
|
||||
ReadFeatureReport(device->dev, k_EPS5FeatureReportIdSerialNumber);
|
||||
if (ReadFeatureReport(device->dev, k_EPS5FeatureReportIdSerialNumber, data, sizeof(data)) >= 7) {
|
||||
char serial[18];
|
||||
|
||||
SDL_snprintf(serial, sizeof(serial), "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x",
|
||||
data[6], data[5], data[4], data[3], data[2], data[1]);
|
||||
joystick->serial = SDL_strdup(serial);
|
||||
}
|
||||
|
||||
/* Initialize player index (needed for setting LEDs) */
|
||||
ctx->player_index = SDL_JoystickGetPlayerIndex(joystick);
|
||||
|
|
|
@ -690,6 +690,24 @@ HIDAPI_JoystickGetCount(void)
|
|||
return SDL_HIDAPI_numjoysticks;
|
||||
}
|
||||
|
||||
static char *
|
||||
HIDAPI_ConvertString(const wchar_t *wide_string)
|
||||
{
|
||||
char *string = NULL;
|
||||
|
||||
if (wide_string) {
|
||||
string = SDL_iconv_string("UTF-8", "WCHAR_T", (char*)wide_string, (SDL_wcslen(wide_string)+1)*sizeof(wchar_t));
|
||||
if (!string) {
|
||||
if (sizeof(wchar_t) == sizeof(Uint16)) {
|
||||
string = SDL_iconv_string("UTF-8", "UCS-2-INTERNAL", (char*)wide_string, (SDL_wcslen(wide_string)+1)*sizeof(wchar_t));
|
||||
} else if (sizeof(wchar_t) == sizeof(Uint32)) {
|
||||
string = SDL_iconv_string("UTF-8", "UCS-4-INTERNAL", (char*)wide_string, (SDL_wcslen(wide_string)+1)*sizeof(wchar_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
static void
|
||||
HIDAPI_AddDevice(struct hid_device_info *info)
|
||||
{
|
||||
|
@ -743,29 +761,9 @@ HIDAPI_AddDevice(struct hid_device_info *info)
|
|||
|
||||
/* Need the device name before getting the driver to know whether to ignore this device */
|
||||
{
|
||||
char *manufacturer_string = NULL;
|
||||
char *product_string = NULL;
|
||||
|
||||
if (info->manufacturer_string) {
|
||||
manufacturer_string = SDL_iconv_string("UTF-8", "WCHAR_T", (char*)info->manufacturer_string, (SDL_wcslen(info->manufacturer_string)+1)*sizeof(wchar_t));
|
||||
if (!manufacturer_string) {
|
||||
if (sizeof(wchar_t) == sizeof(Uint16)) {
|
||||
manufacturer_string = SDL_iconv_string("UTF-8", "UCS-2-INTERNAL", (char*)info->manufacturer_string, (SDL_wcslen(info->manufacturer_string)+1)*sizeof(wchar_t));
|
||||
} else if (sizeof(wchar_t) == sizeof(Uint32)) {
|
||||
manufacturer_string = SDL_iconv_string("UTF-8", "UCS-4-INTERNAL", (char*)info->manufacturer_string, (SDL_wcslen(info->manufacturer_string)+1)*sizeof(wchar_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (info->product_string) {
|
||||
product_string = SDL_iconv_string("UTF-8", "WCHAR_T", (char*)info->product_string, (SDL_wcslen(info->product_string)+1)*sizeof(wchar_t));
|
||||
if (!product_string) {
|
||||
if (sizeof(wchar_t) == sizeof(Uint16)) {
|
||||
product_string = SDL_iconv_string("UTF-8", "UCS-2-INTERNAL", (char*)info->product_string, (SDL_wcslen(info->product_string)+1)*sizeof(wchar_t));
|
||||
} else if (sizeof(wchar_t) == sizeof(Uint32)) {
|
||||
product_string = SDL_iconv_string("UTF-8", "UCS-4-INTERNAL", (char*)info->product_string, (SDL_wcslen(info->product_string)+1)*sizeof(wchar_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
char *manufacturer_string = HIDAPI_ConvertString(info->manufacturer_string);
|
||||
char *product_string = HIDAPI_ConvertString(info->product_string);
|
||||
char *serial_number = HIDAPI_ConvertString(info->serial_number);
|
||||
|
||||
device->name = SDL_CreateJoystickName(device->vendor_id, device->product_id, manufacturer_string, product_string);
|
||||
|
||||
|
@ -776,7 +774,14 @@ HIDAPI_AddDevice(struct hid_device_info *info)
|
|||
SDL_free(product_string);
|
||||
}
|
||||
|
||||
if (serial_number && *serial_number) {
|
||||
device->serial = serial_number;
|
||||
} else {
|
||||
SDL_free(serial_number);
|
||||
}
|
||||
|
||||
if (!device->name) {
|
||||
SDL_free(device->serial);
|
||||
SDL_free(device->path);
|
||||
SDL_free(device);
|
||||
return;
|
||||
|
@ -793,7 +798,7 @@ HIDAPI_AddDevice(struct hid_device_info *info)
|
|||
HIDAPI_SetupDeviceDriver(device);
|
||||
|
||||
#ifdef DEBUG_HIDAPI
|
||||
SDL_Log("Added HIDAPI device '%s' VID 0x%.4x, PID 0x%.4x, version %d, interface %d, interface_class %d, interface_subclass %d, interface_protocol %d, usage page 0x%.4x, usage 0x%.4x, path = %s, driver = %s (%s)\n", device->name, device->vendor_id, device->product_id, device->version, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol, device->usage_page, device->usage, device->path, device->driver ? device->driver->hint : "NONE", device->driver && device->driver->enabled ? "ENABLED" : "DISABLED");
|
||||
SDL_Log("Added HIDAPI device '%s' VID 0x%.4x, PID 0x%.4x, version %d, serial %s, interface %d, interface_class %d, interface_subclass %d, interface_protocol %d, usage page 0x%.4x, usage 0x%.4x, path = %s, driver = %s (%s)\n", device->name, device->vendor_id, device->product_id, device->version, device->serial ? device->serial : "NONE", device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol, device->usage_page, device->usage, device->path, device->driver ? device->driver->hint : "NONE", device->driver && device->driver->enabled ? "ENABLED" : "DISABLED");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -813,6 +818,7 @@ HIDAPI_DelDevice(SDL_HIDAPI_Device *device)
|
|||
HIDAPI_CleanupDeviceDriver(device);
|
||||
|
||||
SDL_DestroyMutex(device->dev_lock);
|
||||
SDL_free(device->serial);
|
||||
SDL_free(device->name);
|
||||
SDL_free(device->path);
|
||||
SDL_free(device);
|
||||
|
@ -1051,6 +1057,10 @@ HIDAPI_JoystickOpen(SDL_Joystick * joystick, int device_index)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (!joystick->serial && device->serial) {
|
||||
joystick->serial = SDL_strdup(device->serial);
|
||||
}
|
||||
|
||||
joystick->hwdata = hwdata;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@ typedef struct _SDL_HIDAPI_Device
|
|||
Uint16 vendor_id;
|
||||
Uint16 product_id;
|
||||
Uint16 version;
|
||||
char *serial;
|
||||
SDL_JoystickGUID guid;
|
||||
int interface_number; /* Available on Windows and Linux */
|
||||
int interface_class;
|
||||
|
|
|
@ -101,8 +101,9 @@ static void
|
|||
UpdateWindowTitle()
|
||||
{
|
||||
const char *name = SDL_GameControllerName(gamecontroller);
|
||||
const char *serial = SDL_GameControllerGetSerial(gamecontroller);
|
||||
const char *basetitle = "Game Controller Test: ";
|
||||
const size_t titlelen = SDL_strlen(basetitle) + SDL_strlen(name) + 1;
|
||||
const size_t titlelen = SDL_strlen(basetitle) + SDL_strlen(name) + (serial ? 3 + SDL_strlen(serial) : 0) + 1;
|
||||
char *title = (char *)SDL_malloc(titlelen);
|
||||
|
||||
retval = SDL_FALSE;
|
||||
|
@ -110,6 +111,11 @@ UpdateWindowTitle()
|
|||
|
||||
if (title) {
|
||||
SDL_snprintf(title, titlelen, "%s%s", basetitle, name);
|
||||
if (serial) {
|
||||
SDL_strlcat(title, " (", titlelen);
|
||||
SDL_strlcat(title, serial, titlelen);
|
||||
SDL_strlcat(title, ")", titlelen);
|
||||
}
|
||||
SDL_SetWindowTitle(window, title);
|
||||
SDL_free(title);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue