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 "../WindowsWrapper.h"
#include "../Input.h"
BOOL ControllerBackend_Init(void); BOOL ControllerBackend_Init(void);
void ControllerBackend_Deinit(void); void ControllerBackend_Deinit(void);
BOOL ControllerBackend_GetJoystickStatus(JOYSTICK_STATUS *status); BOOL ControllerBackend_GetJoystickStatus(BOOL **buttons, unsigned int *button_count, short **axes, unsigned int *axis_count);
BOOL ControllerBackend_ResetJoystickStatus(void);

View file

@ -97,93 +97,75 @@ void ControllerBackend_Deinit(void)
axis_neutrals = NULL; 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) if (!joystick_connected)
return FALSE; 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; int total_glfw_axes;
const unsigned char *buttons = glfwGetJoystickButtons(connected_joystick_id, &total_buttons); 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) #if GLFW_VERSION_MAJOR > 3 || (GLFW_VERSION_MAJOR == 3 && GLFW_VERSION_MINOR >= 3)
int total_hats; const unsigned char *glfw_hats = glfwGetJoystickHats(connected_joystick_id, &total_glfw_hats);
const unsigned char *hats = glfwGetJoystickHats(connected_joystick_id, &total_hats);
#endif #endif
// Handle directional inputs *button_count = total_glfw_buttons + total_glfw_axes * 2 + total_glfw_hats * 4;
status->bLeft = axes[0] < axis_neutrals[0] - DEADZONE; *axis_count = total_glfw_axes;
status->bRight = axes[0] > axis_neutrals[0] + DEADZONE;
status->bUp = axes[1] < axis_neutrals[1] - DEADZONE;
status->bDown = axes[1] > axis_neutrals[1] + DEADZONE;
// Handle button inputs static BOOL *button_buffer = NULL;
unsigned int buttons_done = 0; 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 // Start with the joystick buttons
for (int i = 0; i < total_buttons; ++i) for (int i = 0; i < total_glfw_buttons; ++i)
{ button_buffer[current_button++] = glfw_buttons[i] == GLFW_PRESS;
status->bButton[buttons_done] = buttons[i] == GLFW_PRESS;
if (++buttons_done >= button_limit)
break;
}
// Then the joystick axes // 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; button_buffer[current_button++] = glfw_axes[i] < axis_neutrals[i] - DEADZONE;
button_buffer[current_button++] = glfw_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;
} }
#if GLFW_VERSION_MAJOR > 3 || (GLFW_VERSION_MAJOR == 3 && GLFW_VERSION_MINOR >= 3) #if GLFW_VERSION_MAJOR > 3 || (GLFW_VERSION_MAJOR == 3 && GLFW_VERSION_MINOR >= 3)
// Then the joystick hats // 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; button_buffer[current_button++] = glfw_hats[i] & GLFW_HAT_UP;
button_buffer[current_button++] = glfw_hats[i] & GLFW_HAT_RIGHT;
if (++buttons_done >= button_limit) button_buffer[current_button++] = glfw_hats[i] & GLFW_HAT_DOWN;
break; button_buffer[current_button++] = glfw_hats[i] & GLFW_HAT_LEFT;
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;
} }
#endif #endif
// Blank any remaining buttons *buttons = button_buffer;
for (size_t i = buttons_done; i < button_limit; ++i)
status->bButton[i] = FALSE; ////////////////////////
// Handle axis inputs //
return TRUE; ////////////////////////
}
for (int i = 0; i < total_glfw_axes; ++i)
BOOL ControllerBackend_ResetJoystickStatus(void) axis_buffer[i] = (short)(glfw_axes[i] * 0x7FFF);
{
if (!joystick_connected) *axes = axis_buffer;
return FALSE;
return TRUE; return TRUE;
} }

View file

@ -37,104 +37,78 @@ void ControllerBackend_Deinit(void)
SDL_QuitSubSystem(SDL_INIT_JOYSTICK); 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) if (joystick == NULL)
return FALSE; 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)
// 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)
Backend_PrintError("Failed to get number of buttons on joystick: %s", SDL_GetError()); Backend_PrintError("Failed to get number of buttons on joystick: %s", SDL_GetError());
int total_axes = SDL_JoystickNumAxes(joystick); int total_sdl_axes = SDL_JoystickNumAxes(joystick);
if (total_axes < 0) if (total_sdl_axes < 0)
Backend_PrintError("Failed to get number of general axis controls on joystick: %s", SDL_GetError()); Backend_PrintError("Failed to get number of general axis controls on joystick: %s", SDL_GetError());
int total_hats = SDL_JoystickNumHats(joystick); int total_sdl_hats = SDL_JoystickNumHats(joystick);
if (total_hats < 0) if (total_sdl_hats < 0)
Backend_PrintError("Failed to get number of POV hats on joystick: %s", SDL_GetError()); 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 // Start with the joystick buttons
for (int i = 0; i < total_buttons; ++i) for (int i = 0; i < total_sdl_buttons; ++i)
{ button_buffer[current_button++] = SDL_JoystickGetButton(joystick, i);
status->bButton[buttons_done] = SDL_JoystickGetButton(joystick, i);
if (++buttons_done >= button_limit)
break;
}
// Then the joystick axes // 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); Sint16 axis = SDL_JoystickGetAxis(joystick, i);
status->bButton[buttons_done] = axis < axis_neutrals[i] - DEADZONE; button_buffer[current_button++] = axis < axis_neutrals[i] - DEADZONE;
button_buffer[current_button++] = 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;
} }
// Then the joystick hats // 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); Uint8 hat = SDL_JoystickGetHat(joystick, i);
status->bButton[buttons_done] = hat == SDL_HAT_UP || hat == SDL_HAT_LEFTUP || hat == SDL_HAT_RIGHTUP; 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;
if (++buttons_done >= button_limit) button_buffer[current_button++] = hat == SDL_HAT_DOWN || hat == SDL_HAT_LEFTDOWN || hat == SDL_HAT_RIGHTDOWN;
break; button_buffer[current_button++] = hat == SDL_HAT_LEFT || hat == SDL_HAT_LEFTUP || hat == SDL_HAT_LEFTDOWN;
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;
} }
// Blank any remaining buttons *buttons = button_buffer;
for (size_t i = buttons_done; i < button_limit; ++i)
status->bButton[i] = FALSE;
return TRUE; ////////////////////////
} // Handle axis inputs //
////////////////////////
BOOL ControllerBackend_ResetJoystickStatus(void) for (int i = 0; i < total_sdl_axes; ++i)
{ axis_buffer[i] = SDL_JoystickGetAxis(joystick, i);
if (joystick == NULL)
return FALSE; *axes = axis_buffer;
return TRUE; return TRUE;
} }

View file

@ -4,6 +4,9 @@
#include "WindowsWrapper.h" #include "WindowsWrapper.h"
static int joystick_neutral_x = 0;
static int joystick_neutral_y = 0;
void ReleaseDirectInput(void) void ReleaseDirectInput(void)
{ {
ControllerBackend_Deinit(); ControllerBackend_Deinit();
@ -16,10 +19,67 @@ BOOL InitDirectInput(void)
BOOL GetJoystickStatus(JOYSTICK_STATUS *status) 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) 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;
} }