From e22e77dadc2f6188af9719a0517332e26dcbbb5c Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 19 Dec 2019 15:01:35 -0800 Subject: [PATCH] Added an untested driver for the Nintendo GameCube adapter, based on code contributed by Ethan Lee --- include/SDL_hints.h | 11 +++++++++++ src/hidapi/SDL_hidapi.c | 1 + src/joystick/SDL_joystick.c | 6 ++++++ src/joystick/hidapi/SDL_hidapi_switch.c | 4 ++-- src/joystick/hidapi/SDL_hidapijoystick.c | 14 +++++++++++--- src/joystick/hidapi/SDL_hidapijoystick_c.h | 3 +++ 6 files changed, 34 insertions(+), 5 deletions(-) diff --git a/include/SDL_hints.h b/include/SDL_hints.h index b90c9dce6..d36815b9f 100644 --- a/include/SDL_hints.h +++ b/include/SDL_hints.h @@ -609,6 +609,17 @@ extern "C" { */ #define SDL_HINT_JOYSTICK_HIDAPI_XBOX "SDL_JOYSTICK_HIDAPI_XBOX" +/** + * \brief A variable controlling whether the HIDAPI driver for Nintendo GameCube controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_GAMECUBE "SDL_JOYSTICK_HIDAPI_GAMECUBE" + /** * \brief A variable that controls whether Steam Controllers should be exposed using the SDL joystick and game controller APIs * diff --git a/src/hidapi/SDL_hidapi.c b/src/hidapi/SDL_hidapi.c index a06c2cfd3..c70119b99 100644 --- a/src/hidapi/SDL_hidapi.c +++ b/src/hidapi/SDL_hidapi.c @@ -66,6 +66,7 @@ #if __LINUX__ #include "../../core/linux/SDL_udev.h" +#undef SDL_USE_LIBUDEV #if SDL_USE_LIBUDEV static const SDL_UDEV_Symbols *udev_ctx = NULL; diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index 1948865d0..3990c8f17 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -33,6 +33,7 @@ #include "../events/SDL_events_c.h" #endif #include "../video/SDL_sysvideo.h" +#include "hidapi/SDL_hidapijoystick_c.h" /* This is included in only one place because it has a large static list of controllers */ #include "controller_type.h" @@ -1043,6 +1044,11 @@ SDL_JoystickUpdate(void) /* Make sure the list is unlocked while dispatching events to prevent application deadlocks */ SDL_UnlockJoysticks(); +#ifdef SDL_JOYSTICK_HIDAPI + /* Special function for HIDAPI devices, as a single device can provide multiple SDL_Joysticks */ + HIDAPI_UpdateDevices(); +#endif /* SDL_JOYSTICK_HIDAPI */ + for (joystick = SDL_joysticks; joystick; joystick = joystick->next) { if (joystick->attached) { /* This should always be true, but seeing a crash in the wild...? */ diff --git a/src/joystick/hidapi/SDL_hidapi_switch.c b/src/joystick/hidapi/SDL_hidapi_switch.c index 0cc01574e..81d0141cd 100644 --- a/src/joystick/hidapi/SDL_hidapi_switch.c +++ b/src/joystick/hidapi/SDL_hidapi_switch.c @@ -637,15 +637,15 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti ctx = (SDL_DriverSwitch_Context *)SDL_calloc(1, sizeof(*ctx)); if (!ctx) { SDL_OutOfMemory(); - return SDL_FALSE; + goto error; } + device->context = ctx; device->dev = ctx->dev = hid_open_path(device->path, 0); if (!device->dev) { SDL_SetError("Couldn't open %s", device->path); goto error; } - device->context = ctx; /* Find out whether or not we can send output reports */ ctx->m_bInputOnly = SDL_IsJoystickNintendoSwitchProInputOnly(device->vendor_id, device->product_id); diff --git a/src/joystick/hidapi/SDL_hidapijoystick.c b/src/joystick/hidapi/SDL_hidapijoystick.c index 9c7672b65..564a57076 100644 --- a/src/joystick/hidapi/SDL_hidapijoystick.c +++ b/src/joystick/hidapi/SDL_hidapijoystick.c @@ -74,6 +74,9 @@ static SDL_HIDAPI_DeviceDriver *SDL_HIDAPI_drivers[] = { #ifdef SDL_JOYSTICK_HIDAPI_XBOXONE &SDL_HIDAPI_DriverXboxOne, #endif +#ifdef SDL_JOYSTICK_HIDAPI_GAMECUBE + &SDL_HIDAPI_DriverGameCube, +#endif }; static int SDL_HIDAPI_numdrivers = 0; static SDL_mutex *SDL_HIDAPI_mutex; @@ -569,6 +572,7 @@ HIDAPI_JoystickInit(void) SDL_HIDAPIDriverHintChanged, NULL); HIDAPI_InitializeDiscovery(); HIDAPI_JoystickDetect(); + HIDAPI_UpdateDevices(); initialized = SDL_TRUE; @@ -842,14 +846,18 @@ HIDAPI_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, cons static void HIDAPI_JoystickDetect(void) { - SDL_HIDAPI_Device *device; - HIDAPI_UpdateDiscovery(); if (SDL_HIDAPI_discovery.m_bHaveDevicesChanged) { /* FIXME: We probably need to schedule an update in a few seconds as well */ HIDAPI_UpdateDeviceList(); SDL_HIDAPI_discovery.m_bHaveDevicesChanged = SDL_FALSE; } +} + +void +HIDAPI_UpdateDevices(void) +{ + SDL_HIDAPI_Device *device; /* Update the devices, which may change connected joysticks and send events */ SDL_LockMutex(SDL_HIDAPI_mutex); @@ -961,7 +969,7 @@ HIDAPI_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint static void HIDAPI_JoystickUpdate(SDL_Joystick * joystick) { - /* This is handled in HIDAPI_JoystickDetect() */ + /* This is handled in SDL_HIDAPI_UpdateDevices() */ } static void diff --git a/src/joystick/hidapi/SDL_hidapijoystick_c.h b/src/joystick/hidapi/SDL_hidapijoystick_c.h index 6c9efe3ae..1a09df397 100644 --- a/src/joystick/hidapi/SDL_hidapijoystick_c.h +++ b/src/joystick/hidapi/SDL_hidapijoystick_c.h @@ -30,6 +30,7 @@ #define SDL_JOYSTICK_HIDAPI_SWITCH #define SDL_JOYSTICK_HIDAPI_XBOX360 #define SDL_JOYSTICK_HIDAPI_XBOXONE +#define SDL_JOYSTICK_HIDAPI_GAMECUBE #ifdef __WINDOWS__ /* On Windows, Xbox One controllers are handled by the Xbox 360 driver */ @@ -95,10 +96,12 @@ extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSwitch; extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360; extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360W; extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXboxOne; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverGameCube; /* Return true if a HID device is present and supported as a joystick */ extern SDL_bool HIDAPI_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name); +extern void HIDAPI_UpdateDevices(void); extern SDL_bool HIDAPI_JoystickConnected(SDL_HIDAPI_Device *device, SDL_JoystickID *pJoystickID); extern void HIDAPI_JoystickDisconnected(SDL_HIDAPI_Device *device, SDL_JoystickID joystickID);