shithub: cstory

Download patch

ref: 026fea52ff29ce74cd0b05a6a70d63121a058556
parent: 58fc9a392ac3d868292eebdc0991247a9bca03be
author: Clownacy <Clownacy@users.noreply.github.com>
date: Mon Apr 13 10:49:07 EDT 2020

Untangle Input.cpp from the controller backend

--- a/src/Backends/Controller.h
+++ b/src/Backends/Controller.h
@@ -2,9 +2,6 @@
 
 #include "../WindowsWrapper.h"
 
-#include "../Input.h"
-
 BOOL ControllerBackend_Init(void);
 void ControllerBackend_Deinit(void);
-BOOL ControllerBackend_GetJoystickStatus(JOYSTICK_STATUS *status);
-BOOL ControllerBackend_ResetJoystickStatus(void);
+BOOL ControllerBackend_GetJoystickStatus(BOOL **buttons, unsigned int *button_count, short **axes, unsigned int *axis_count);
--- a/src/Backends/GLFW3/Controller.cpp
+++ b/src/Backends/GLFW3/Controller.cpp
@@ -97,93 +97,75 @@
 	axis_neutrals = NULL;
 }
 
-BOOL ControllerBackend_GetJoystickStatus(JOYSTICK_STATUS *status)
+BOOL ControllerBackend_GetJoystickStatus(BOOL **buttons, unsigned int *button_count, short **axes, unsigned int *axis_count)
 {
 	if (!joystick_connected)
 		return FALSE;
 
-	const size_t button_limit = sizeof(status->bButton) / sizeof(status->bButton[0]);
+	int total_glfw_buttons;
+	const unsigned char *glfw_buttons = glfwGetJoystickButtons(connected_joystick_id, &total_glfw_buttons);
 
-	int total_buttons;
-	const unsigned char *buttons = glfwGetJoystickButtons(connected_joystick_id, &total_buttons);
+	int total_glfw_axes;
+	const float *glfw_axes = glfwGetJoystickAxes(connected_joystick_id, &total_glfw_axes);
 
-	int total_axes;
-	const float *axes = glfwGetJoystickAxes(connected_joystick_id, &total_axes);
-
+	int total_glfw_hats = 0;
 #if GLFW_VERSION_MAJOR > 3 || (GLFW_VERSION_MAJOR == 3 && GLFW_VERSION_MINOR >= 3)
-	int total_hats;
-	const unsigned char *hats = glfwGetJoystickHats(connected_joystick_id, &total_hats);
+	const unsigned char *glfw_hats = glfwGetJoystickHats(connected_joystick_id, &total_glfw_hats);
 #endif
 
-	// Handle directional inputs
-	status->bLeft = axes[0] < axis_neutrals[0] - DEADZONE;
-	status->bRight = axes[0] > axis_neutrals[0] + DEADZONE;
-	status->bUp = axes[1] < axis_neutrals[1] - DEADZONE;
-	status->bDown = axes[1] > axis_neutrals[1] + DEADZONE;
+	*button_count = total_glfw_buttons + total_glfw_axes * 2 + total_glfw_hats * 4;
+	*axis_count = total_glfw_axes;
 
-	// Handle button inputs
-	unsigned int buttons_done = 0;
+	static BOOL *button_buffer = NULL;
+	static short *axis_buffer = NULL;
 
-	// Start with the joystick buttons
-	for (int i = 0; i < total_buttons; ++i)
-	{
-		status->bButton[buttons_done] = buttons[i] == GLFW_PRESS;
+	BOOL *new_button_buffer = (BOOL*)realloc(button_buffer, *button_count * sizeof(BOOL));
+	short *new_axis_buffer = (short*)realloc(axis_buffer, *axis_count * sizeof(short));
 
-		if (++buttons_done >= button_limit)
-			break;
-	}
+	if (new_button_buffer == NULL || new_axis_buffer == NULL)
+		return FALSE;
 
-	// Then the joystick axes
-	for (int i = 0; i < total_axes; ++i)
-	{
-		status->bButton[buttons_done] = axes[i] < axis_neutrals[i] - DEADZONE;
+	button_buffer = new_button_buffer;
+	axis_buffer = new_axis_buffer;
 
-		if (++buttons_done >= button_limit)
-			break;
+	//////////////////////////
+	// Handle button inputs //
+	//////////////////////////
 
-		status->bButton[buttons_done] = axes[i] > axis_neutrals[i] + DEADZONE;
+	unsigned int current_button = 0;
 
-		if (++buttons_done >= button_limit)
-			break;
+	// Start with the joystick buttons
+	for (int i = 0; i < total_glfw_buttons; ++i)
+		button_buffer[current_button++] = glfw_buttons[i] == GLFW_PRESS;
+
+	// Then the joystick axes
+	for (int i = 0; i < total_glfw_axes; ++i)
+	{
+		button_buffer[current_button++] = glfw_axes[i] < axis_neutrals[i] - DEADZONE;
+		button_buffer[current_button++] = glfw_axes[i] > axis_neutrals[i] + DEADZONE;
 	}
 
 #if GLFW_VERSION_MAJOR > 3 || (GLFW_VERSION_MAJOR == 3 && GLFW_VERSION_MINOR >= 3)
 	// Then the joystick hats
-	for (int i = 0; i < total_axes; ++i)
+	for (int i = 0; i < total_glfw_hats; ++i)
 	{
-		status->bButton[buttons_done] = hats[i] & GLFW_HAT_UP;
-
-		if (++buttons_done >= button_limit)
-			break;
-
-		status->bButton[buttons_done] = hats[i] & GLFW_HAT_RIGHT;
-
-		if (++buttons_done >= button_limit)
-			break;
-
-		status->bButton[buttons_done] = hats[i] & GLFW_HAT_DOWN;
-
-		if (++buttons_done >= button_limit)
-			break;
-
-		status->bButton[buttons_done] = hats[i] & GLFW_HAT_LEFT;
-
-		if (++buttons_done >= button_limit)
-			break;
+		button_buffer[current_button++] = glfw_hats[i] & GLFW_HAT_UP;
+		button_buffer[current_button++] = glfw_hats[i] & GLFW_HAT_RIGHT;
+		button_buffer[current_button++] = glfw_hats[i] & GLFW_HAT_DOWN;
+		button_buffer[current_button++] = glfw_hats[i] & GLFW_HAT_LEFT;
 	}
 #endif
 
-	// Blank any remaining buttons
-	for (size_t i = buttons_done; i < button_limit; ++i)
-		status->bButton[i] = FALSE;
+	*buttons = button_buffer;
 
-	return TRUE;
-}
+	////////////////////////
+	// Handle axis inputs //
+	////////////////////////
 
-BOOL ControllerBackend_ResetJoystickStatus(void)
-{
-	if (!joystick_connected)
-		return FALSE;
+	for (int i = 0; i < total_glfw_axes; ++i)
+		axis_buffer[i] = (short)(glfw_axes[i] * 0x7FFF);
+
+	*axes = axis_buffer;
 
 	return TRUE;
 }
--- a/src/Backends/SDL2/Controller.cpp
+++ b/src/Backends/SDL2/Controller.cpp
@@ -37,104 +37,78 @@
 	SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
 }
 
-BOOL ControllerBackend_GetJoystickStatus(JOYSTICK_STATUS *status)
+BOOL ControllerBackend_GetJoystickStatus(BOOL **buttons, unsigned int *button_count, short **axes, unsigned int *axis_count)
 {
 	if (joystick == NULL)
 		return FALSE;
 
-	const size_t button_limit = sizeof(status->bButton) / sizeof(status->bButton[0]);
+	int total_sdl_buttons = SDL_JoystickNumButtons(joystick);
+	if (total_sdl_buttons < 0)
+		Backend_PrintError("Failed to get number of buttons on joystick: %s", SDL_GetError());
 
-	// Handle directional inputs
-	const Sint16 joystick_x = SDL_JoystickGetAxis(joystick, 0);
-	if (joystick_x == 0)
-		Backend_PrintError("Failed to get current state of X axis control on joystick: %s", SDL_GetError());
+	int total_sdl_axes = SDL_JoystickNumAxes(joystick);
+	if (total_sdl_axes < 0)
+		Backend_PrintError("Failed to get number of general axis controls on joystick: %s", SDL_GetError());
 
-	const Sint16 joystick_y = SDL_JoystickGetAxis(joystick, 1);
-	if (joystick_y == 0)
-		Backend_PrintError("Failed to get current state of Y axis control on joystick: %s", SDL_GetError());
+	int total_sdl_hats = SDL_JoystickNumHats(joystick);
+	if (total_sdl_hats < 0)
+		Backend_PrintError("Failed to get number of POV hats on joystick: %s", SDL_GetError());
 
-	status->bLeft = joystick_x < axis_neutrals[0] - DEADZONE;
-	status->bRight = joystick_x > axis_neutrals[0] + DEADZONE;
-	status->bUp = joystick_y < axis_neutrals[1] - DEADZONE;
-	status->bDown = joystick_y > axis_neutrals[1] + DEADZONE;
+	*button_count = total_sdl_buttons + total_sdl_axes * 2 + total_sdl_hats * 4;
+	*axis_count = total_sdl_axes;
 
-	// Handle button inputs
-	int total_buttons = SDL_JoystickNumButtons(joystick);
-	if (total_buttons < 0)
-		Backend_PrintError("Failed to get number of buttons on joystick: %s", SDL_GetError());
+	static BOOL *button_buffer = NULL;
+	static short *axis_buffer = NULL;
 
-	int total_axes = SDL_JoystickNumAxes(joystick);
-	if (total_axes < 0)
-		Backend_PrintError("Failed to get number of general axis controls on joystick: %s", SDL_GetError());
+	BOOL *new_button_buffer = (BOOL*)realloc(button_buffer, *button_count * sizeof(BOOL));
+	short *new_axis_buffer = (short*)realloc(axis_buffer, *axis_count * sizeof(short));
 
-	int total_hats = SDL_JoystickNumHats(joystick);
-	if (total_hats < 0)
-		Backend_PrintError("Failed to get number of POV hats on joystick: %s", SDL_GetError());
+	if (new_button_buffer == NULL || new_axis_buffer == NULL)
+		return FALSE;
 
-	unsigned int buttons_done = 0;
+	button_buffer = new_button_buffer;
+	axis_buffer = new_axis_buffer;
 
-	// Start with the joystick buttons
-	for (int i = 0; i < total_buttons; ++i)
-	{
-		status->bButton[buttons_done] = SDL_JoystickGetButton(joystick, i);
+	//////////////////////////
+	// Handle button inputs //
+	//////////////////////////
 
-		if (++buttons_done >= button_limit)
-			break;
-	}
+	unsigned int current_button = 0;
 
+	// Start with the joystick buttons
+	for (int i = 0; i < total_sdl_buttons; ++i)
+		button_buffer[current_button++] = SDL_JoystickGetButton(joystick, i);
+
 	// Then the joystick axes
-	for (int i = 0; i < total_axes; ++i)
+	for (int i = 0; i < total_sdl_axes; ++i)
 	{
 		Sint16 axis = SDL_JoystickGetAxis(joystick, i);
 
-		status->bButton[buttons_done] = axis < axis_neutrals[i] - DEADZONE;
-
-		if (++buttons_done >= button_limit)
-			break;
-
-		status->bButton[buttons_done] = axis > axis_neutrals[i] + DEADZONE;
-
-		if (++buttons_done >= button_limit)
-			break;
+		button_buffer[current_button++] = axis < axis_neutrals[i] - DEADZONE;
+		button_buffer[current_button++] = axis > axis_neutrals[i] + DEADZONE;
 	}
 
 	// Then the joystick hats
-	for (int i = 0; i < total_hats; ++i)
+	for (int i = 0; i < total_sdl_hats; ++i)
 	{
 		Uint8 hat = SDL_JoystickGetHat(joystick, i);
 
-		status->bButton[buttons_done] = hat == SDL_HAT_UP || hat == SDL_HAT_LEFTUP || hat == SDL_HAT_RIGHTUP;
-
-		if (++buttons_done >= button_limit)
-			break;
-
-		status->bButton[buttons_done] = hat == SDL_HAT_RIGHT || hat == SDL_HAT_RIGHTUP || hat == SDL_HAT_RIGHTDOWN;
-
-		if (++buttons_done >= button_limit)
-			break;
-
-		status->bButton[buttons_done] = hat == SDL_HAT_DOWN || hat == SDL_HAT_LEFTDOWN || hat == SDL_HAT_RIGHTDOWN;
-
-		if (++buttons_done >= button_limit)
-			break;
-
-		status->bButton[buttons_done] = hat == SDL_HAT_LEFT || hat == SDL_HAT_LEFTUP || hat == SDL_HAT_LEFTDOWN;
-
-		if (++buttons_done >= button_limit)
-			break;
+		button_buffer[current_button++] = hat == SDL_HAT_UP || hat == SDL_HAT_LEFTUP || hat == SDL_HAT_RIGHTUP;
+		button_buffer[current_button++] = hat == SDL_HAT_RIGHT || hat == SDL_HAT_RIGHTUP || hat == SDL_HAT_RIGHTDOWN;
+		button_buffer[current_button++] = hat == SDL_HAT_DOWN || hat == SDL_HAT_LEFTDOWN || hat == SDL_HAT_RIGHTDOWN;
+		button_buffer[current_button++] = hat == SDL_HAT_LEFT || hat == SDL_HAT_LEFTUP || hat == SDL_HAT_LEFTDOWN;
 	}
 
-	// Blank any remaining buttons
-	for (size_t i = buttons_done; i < button_limit; ++i)
-		status->bButton[i] = FALSE;
+	*buttons = button_buffer;
 
-	return TRUE;
-}
+	////////////////////////
+	// Handle axis inputs //
+	////////////////////////
 
-BOOL ControllerBackend_ResetJoystickStatus(void)
-{
-	if (joystick == NULL)
-		return FALSE;
+	for (int i = 0; i < total_sdl_axes; ++i)
+		axis_buffer[i] = SDL_JoystickGetAxis(joystick, i);
+
+	*axes = axis_buffer;
 
 	return TRUE;
 }
--- a/src/Input.cpp
+++ b/src/Input.cpp
@@ -4,6 +4,9 @@
 
 #include "WindowsWrapper.h"
 
+static int joystick_neutral_x = 0;
+static int joystick_neutral_y = 0;
+
 void ReleaseDirectInput(void)
 {
 	ControllerBackend_Deinit();
@@ -16,10 +19,67 @@
 
 BOOL GetJoystickStatus(JOYSTICK_STATUS *status)
 {
-	return ControllerBackend_GetJoystickStatus(status);
+	BOOL *buttons;
+	unsigned int button_count;
+
+	short *axes;
+	unsigned int axis_count;
+
+	if (!ControllerBackend_GetJoystickStatus(&buttons, &button_count, &axes, &axis_count))
+		return FALSE;
+
+	if (button_count > 32)
+		button_count = 32;
+
+	for (unsigned int i = 0; i < button_count; ++i)
+		status->bButton[i] = buttons[i];
+
+	for (unsigned int i = button_count; i < 32; ++i)
+		status->bButton[i] = FALSE;
+
+	status->bDown = FALSE;
+	status->bRight = FALSE;
+	status->bUp = FALSE;
+	status->bLeft = FALSE;
+
+	if (axis_count >= 1)
+	{
+		if (axes[0] < joystick_neutral_x - 10000)
+			status->bLeft = TRUE;
+		else if (axes[0] > joystick_neutral_x + 10000)
+			status->bRight = TRUE;
+	}
+
+	if (axis_count >= 2)
+	{
+		if (axes[1] < joystick_neutral_y - 10000)
+			status->bUp = TRUE;
+		else if (axes[1] > joystick_neutral_y + 10000)
+			status->bDown = TRUE;
+	}
+
+	return TRUE;
 }
 
 BOOL ResetJoystickStatus(void)
 {
-	return ControllerBackend_ResetJoystickStatus();
+	BOOL *buttons;
+	unsigned int button_count;
+
+	short *axes;
+	unsigned int axis_count;
+
+	if (!ControllerBackend_GetJoystickStatus(&buttons, &button_count, &axes, &axis_count))
+		return FALSE;
+
+	joystick_neutral_x = 0;
+	joystick_neutral_y = 0;
+
+	if (axis_count >= 1)
+		joystick_neutral_x = axes[0];
+
+	if (axis_count >= 2)
+		joystick_neutral_y = axes[1];
+
+	return TRUE;
 }