shithub: cstory

Download patch

ref: 65325e2b34f68be94398df393e6156183a797590
parent: 7ee2e68c2e49fa5aa5706166e89c1aff7db7643b
author: Clownacy <[email protected]>
date: Sat Apr 4 15:50:52 EDT 2020

Add hotplugging support to SDL2 backend

--- a/src/Backends/GLFW3/Misc.cpp
+++ b/src/Backends/GLFW3/Misc.cpp
@@ -1,4 +1,5 @@
 #include "../Platform.h"
+#include "Platform.h"
 
 #include <chrono>
 #include <stddef.h>
@@ -9,11 +10,9 @@
 
 #include <GLFW/glfw3.h>
 
-#include "../Rendering.h"
-
 #include "../../WindowsWrapper.h"
 
-#include "Platform.h"
+#include "../Rendering.h"
 #include "../../Main.h"
 #include "../../Organya.h"
 #include "../../Profile.h"
--- a/src/Backends/SDL2/Controller.cpp
+++ b/src/Backends/SDL2/Controller.cpp
@@ -1,4 +1,5 @@
 #include "../Controller.h"
+#include "Controller.h"
 
 #include <stddef.h>
 #include <stdio.h>
@@ -11,23 +12,12 @@
 static int joystick_neutral_x;
 static int joystick_neutral_y;
 
+void ControllerBackend_JoystickCallback(int joystick_id, BOOL connected);
+
 BOOL ControllerBackend_Init(void)
 {
 	SDL_InitSubSystem(SDL_INIT_JOYSTICK);
 
-	for (int i = 0; i < SDL_NumJoysticks(); ++i)
-	{
-		printf("Joystick #%d connected - %s\n", i, SDL_JoystickNameForIndex(i));
-
-		if (joystick == NULL)
-		{
-			joystick = SDL_JoystickOpen(i);
-
-			if (joystick != NULL)
-				printf("Joystick #%d selected\n", i);
-		}
-	}
-
 	return TRUE;
 }
 
@@ -53,36 +43,21 @@
 		numButtons = 32;
 
 	// Read whatever buttons actually exist
-	int i = 0;
-	for (; i < numButtons; ++i)
-	{
-		if (SDL_JoystickGetButton(joystick, i) != 0)
-			status->bButton[i] = TRUE;
-		else
-			status->bButton[i] = FALSE;
-	}
+	for (int i = 0; i < numButtons; ++i)
+		status->bButton[i] = SDL_JoystickGetButton(joystick, i);
 
 	// Blank the buttons that do not
-	for (; i < 32; ++i)
+	for (int i = numButtons; i < 32; ++i)
 		status->bButton[i] = FALSE;
 
-	status->bDown = FALSE;
-	status->bRight = FALSE;
-	status->bUp = FALSE;
-	status->bLeft = FALSE;
-
 	const Sint16 joystick_x = SDL_JoystickGetAxis(joystick, 0);
-	if (joystick_x < joystick_neutral_x - 10000)
-		status->bLeft = TRUE;
-	else if (joystick_x > joystick_neutral_x + 10000)
-		status->bRight = TRUE;
-
 	const Sint16 joystick_y = SDL_JoystickGetAxis(joystick, 1);
-	if (joystick_y < joystick_neutral_y - 10000)
-		status->bUp = TRUE;
-	else if (joystick_y > joystick_neutral_y + 10000)
-		status->bDown = TRUE;
 
+	status->bLeft = joystick_x < joystick_neutral_x - 10000;
+	status->bRight = joystick_x > joystick_neutral_x + 10000;
+	status->bUp = joystick_y < joystick_neutral_y - 10000;
+	status->bDown = joystick_y > joystick_neutral_y + 10000;
+
 	return TRUE;
 }
 
@@ -91,8 +66,35 @@
 	if (joystick == NULL)
 		return FALSE;
 
-	joystick_neutral_x = SDL_JoystickGetAxis(joystick, 0);
-	joystick_neutral_y = SDL_JoystickGetAxis(joystick, 1);
+	// The code that would normally run here has been moved to JoystickCallback, to better-support hotplugging
 
 	return TRUE;
+}
+
+void ControllerBackend_JoystickConnect(Sint32 joystick_id)
+{
+	printf("Joystick #%d connected - %s\n", joystick_id, SDL_JoystickNameForIndex(joystick_id));
+
+	if (joystick == NULL)
+	{
+		joystick = SDL_JoystickOpen(joystick_id);
+
+		if (joystick != NULL)
+		{
+			printf("Joystick #%d selected\n", joystick_id);
+
+			// Reset default stick positions (this is performed in ResetJoystickStatus in vanilla Cave Story
+			joystick_neutral_x = SDL_JoystickGetAxis(joystick, 0);
+			joystick_neutral_y = SDL_JoystickGetAxis(joystick, 1);
+		}
+	}
+}
+
+void ControllerBackend_JoystickDisconnect(Sint32 joystick_id)
+{
+	if (joystick_id == SDL_JoystickInstanceID(joystick))
+	{
+		printf("Joystick #%d disconnected\n", joystick_id);
+		joystick = NULL;
+	}
 }
--- a/src/Backends/SDL2/Misc.cpp
+++ b/src/Backends/SDL2/Misc.cpp
@@ -1,4 +1,5 @@
 #include "../Platform.h"
+#include "Platform.h"
 
 #include <stddef.h>
 #include <stdio.h>
@@ -6,11 +7,10 @@
 
 #include "SDL.h"
 
-#include "../Rendering.h"
-
 #include "../../WindowsWrapper.h"
 
-#include "Platform.h"
+#include "Controller.h"
+#include "../Rendering.h"
 #include "../../Main.h"
 #include "../../Organya.h"
 #include "../../Profile.h"
@@ -194,6 +194,14 @@
 						break;
 				}
 
+				break;
+
+			case SDL_JOYDEVICEADDED:
+				ControllerBackend_JoystickConnect(event.jdevice.which);
+				break;
+
+			case SDL_JOYDEVICEREMOVED:
+				ControllerBackend_JoystickDisconnect(event.jdevice.which);
 				break;
 
 			case SDL_DROPFILE: