Untangle Input.cpp from the controller backend

This commit is contained in:
Clownacy 2020-04-13 14:49:07 +01:00
parent 58fc9a392a
commit 026fea52ff
4 changed files with 154 additions and 141 deletions

View file

@ -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);

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}