Browse Source

Added an untested driver for the Nintendo GameCube adapter, based on code contributed by Ethan Lee

Sam Lantinga 5 years ago
parent
commit
e22e77dadc

+ 11 - 0
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
  *

+ 1 - 0
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;
 

+ 6 - 0
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...? */

+ 2 - 2
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);

+ 11 - 3
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

+ 3 - 0
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);