From 026fea52ff29ce74cd0b05a6a70d63121a058556 Mon Sep 17 00:00:00 2001 From: Clownacy Date: Mon, 13 Apr 2020 14:49:07 +0100 Subject: [PATCH] Untangle Input.cpp from the controller backend --- src/Backends/Controller.h | 5 +- src/Backends/GLFW3/Controller.cpp | 110 ++++++++++++---------------- src/Backends/SDL2/Controller.cpp | 116 ++++++++++++------------------ src/Input.cpp | 64 ++++++++++++++++- 4 files changed, 154 insertions(+), 141 deletions(-) diff --git a/src/Backends/Controller.h b/src/Backends/Controller.h index 21339234..9c5c70fb 100644 --- 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); diff --git a/src/Backends/GLFW3/Controller.cpp b/src/Backends/GLFW3/Controller.cpp index 88885f35..b6123da1 100644 --- a/src/Backends/GLFW3/Controller.cpp +++ b/src/Backends/GLFW3/Controller.cpp @@ -97,93 +97,75 @@ void ControllerBackend_Deinit(void) 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_axes; - const float *axes = glfwGetJoystickAxes(connected_joystick_id, &total_axes); + int total_glfw_axes; + const float *glfw_axes = glfwGetJoystickAxes(connected_joystick_id, &total_glfw_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; + + 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 (new_button_buffer == NULL || new_axis_buffer == NULL) + return FALSE; + + button_buffer = new_button_buffer; + axis_buffer = new_axis_buffer; + + ////////////////////////// + // Handle button inputs // + ////////////////////////// + + unsigned int current_button = 0; // Start with the joystick buttons - for (int i = 0; i < total_buttons; ++i) - { - status->bButton[buttons_done] = buttons[i] == GLFW_PRESS; - - if (++buttons_done >= button_limit) - break; - } + 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_axes; ++i) + for (int i = 0; i < total_glfw_axes; ++i) { - status->bButton[buttons_done] = axes[i] < axis_neutrals[i] - DEADZONE; - - if (++buttons_done >= button_limit) - break; - - status->bButton[buttons_done] = axes[i] > axis_neutrals[i] + DEADZONE; - - if (++buttons_done >= button_limit) - break; + 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; - - return TRUE; -} - -BOOL ControllerBackend_ResetJoystickStatus(void) -{ - if (!joystick_connected) - return FALSE; + *buttons = button_buffer; + + //////////////////////// + // Handle axis inputs // + //////////////////////// + + for (int i = 0; i < total_glfw_axes; ++i) + axis_buffer[i] = (short)(glfw_axes[i] * 0x7FFF); + + *axes = axis_buffer; return TRUE; } diff --git a/src/Backends/SDL2/Controller.cpp b/src/Backends/SDL2/Controller.cpp index d91200d4..d9654729 100644 --- a/src/Backends/SDL2/Controller.cpp +++ b/src/Backends/SDL2/Controller.cpp @@ -37,104 +37,78 @@ void ControllerBackend_Deinit(void) 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]); - - // 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()); - - 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()); - - 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; - - // Handle button inputs - int total_buttons = SDL_JoystickNumButtons(joystick); - if (total_buttons < 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()); - int total_axes = SDL_JoystickNumAxes(joystick); - if (total_axes < 0) + 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()); - int total_hats = SDL_JoystickNumHats(joystick); - if (total_hats < 0) + 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()); - unsigned int buttons_done = 0; + *button_count = total_sdl_buttons + total_sdl_axes * 2 + total_sdl_hats * 4; + *axis_count = total_sdl_axes; + + static BOOL *button_buffer = NULL; + static short *axis_buffer = NULL; + + 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 (new_button_buffer == NULL || new_axis_buffer == NULL) + return FALSE; + + button_buffer = new_button_buffer; + axis_buffer = new_axis_buffer; + + ////////////////////////// + // Handle button inputs // + ////////////////////////// + + unsigned int current_button = 0; // Start with the joystick buttons - for (int i = 0; i < total_buttons; ++i) - { - status->bButton[buttons_done] = SDL_JoystickGetButton(joystick, i); - - if (++buttons_done >= button_limit) - break; - } + 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; } diff --git a/src/Input.cpp b/src/Input.cpp index e6135bcd..75117a15 100644 --- 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 InitDirectInput(void) 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; }