input: Move from haptic to rumble API

This commit is contained in:
Matt Borgerson 2022-04-23 14:19:36 -07:00 committed by mborgerson
parent 294437a28c
commit 6b7721db58
2 changed files with 47 additions and 69 deletions

View File

@ -44,7 +44,43 @@
#endif
#define XEMU_INPUT_MIN_INPUT_UPDATE_INTERVAL_US 2500
#define XEMU_INPUT_MIN_HAPTIC_UPDATE_INTERVAL_US 2500
#define XEMU_INPUT_MIN_RUMBLE_UPDATE_INTERVAL_US 2500
#if 0
static void xemu_input_print_controller_state(ControllerState *state)
{
DPRINTF(" A = %d, B = %d, X = %d, Y = %d\n"
" Left = %d, Up = %d, Right = %d, Down = %d\n"
" Back = %d, Start = %d, White = %d, Black = %d\n"
"Lstick = %d, Rstick = %d, Guide = %d\n"
"\n"
"LTrig = %.3f, RTrig = %.3f\n"
"LStickX = %.3f, RStickX = %.3f\n"
"LStickY = %.3f, RStickY = %.3f\n\n",
!!(state->buttons & CONTROLLER_BUTTON_A),
!!(state->buttons & CONTROLLER_BUTTON_B),
!!(state->buttons & CONTROLLER_BUTTON_X),
!!(state->buttons & CONTROLLER_BUTTON_Y),
!!(state->buttons & CONTROLLER_BUTTON_DPAD_LEFT),
!!(state->buttons & CONTROLLER_BUTTON_DPAD_UP),
!!(state->buttons & CONTROLLER_BUTTON_DPAD_RIGHT),
!!(state->buttons & CONTROLLER_BUTTON_DPAD_DOWN),
!!(state->buttons & CONTROLLER_BUTTON_BACK),
!!(state->buttons & CONTROLLER_BUTTON_START),
!!(state->buttons & CONTROLLER_BUTTON_WHITE),
!!(state->buttons & CONTROLLER_BUTTON_BLACK),
!!(state->buttons & CONTROLLER_BUTTON_LSTICK),
!!(state->buttons & CONTROLLER_BUTTON_RSTICK),
!!(state->buttons & CONTROLLER_BUTTON_GUIDE),
state->axis[CONTROLLER_AXIS_LTRIG],
state->axis[CONTROLLER_AXIS_RTRIG],
state->axis[CONTROLLER_AXIS_LSTICK_X],
state->axis[CONTROLLER_AXIS_RSTICK_X],
state->axis[CONTROLLER_AXIS_LSTICK_Y],
state->axis[CONTROLLER_AXIS_RSTICK_Y]
);
}
#endif
ControllerStateList available_controllers =
QTAILQ_HEAD_INITIALIZER(available_controllers);
@ -67,11 +103,6 @@ void xemu_input_init(void)
exit(1);
}
if (SDL_Init(SDL_INIT_HAPTIC) < 0) {
fprintf(stderr, "Failed to initialize SDL haptic subsystem: %s\n", SDL_GetError());
exit(1);
}
// Create the keyboard input (always first)
ControllerState *new_con = malloc(sizeof(ControllerState));
memset(new_con, 0, sizeof(ControllerState));
@ -138,12 +169,11 @@ void xemu_input_process_sdl_events(const SDL_Event *event)
memset(new_con, 0, sizeof(ControllerState));
new_con->type = INPUT_DEVICE_SDL_GAMECONTROLLER;
new_con->name = SDL_GameControllerName(sdl_con);
new_con->rumble_enabled = true;
new_con->sdl_gamecontroller = sdl_con;
new_con->sdl_joystick = SDL_GameControllerGetJoystick(new_con->sdl_gamecontroller);
new_con->sdl_joystick_id = SDL_JoystickInstanceID(new_con->sdl_joystick);
new_con->sdl_joystick_guid = SDL_JoystickGetGUID(new_con->sdl_joystick);
new_con->sdl_haptic = SDL_HapticOpenFromJoystick(new_con->sdl_joystick);
new_con->sdl_haptic_effect_id = -1;
new_con->bound = -1;
char guid_buf[35] = { 0 };
@ -210,9 +240,6 @@ void xemu_input_process_sdl_events(const SDL_Event *event)
QTAILQ_REMOVE(&available_controllers, iter, entry);
// Deallocate
if (iter->sdl_haptic) {
SDL_HapticClose(iter->sdl_haptic);
}
if (iter->sdl_gamecontroller) {
SDL_GameControllerClose(iter->sdl_gamecontroller);
}
@ -354,34 +381,24 @@ void xemu_input_update_sdl_controller_state(ControllerState *state)
// FIXME: Check range
state->axis[CONTROLLER_AXIS_LSTICK_Y] = -1 - state->axis[CONTROLLER_AXIS_LSTICK_Y];
state->axis[CONTROLLER_AXIS_RSTICK_Y] = -1 - state->axis[CONTROLLER_AXIS_RSTICK_Y];
// xemu_input_print_controller_state(state);
}
void xemu_input_update_rumble(ControllerState *state)
{
if (state->sdl_haptic == NULL) {
// Haptic not supported for this joystick
if (!state->rumble_enabled) {
return;
}
int64_t now = qemu_clock_get_us(QEMU_CLOCK_REALTIME);
if (ABS(now - state->last_haptic_updated_ts) <
XEMU_INPUT_MIN_HAPTIC_UPDATE_INTERVAL_US) {
if (ABS(now - state->last_rumble_updated_ts) <
XEMU_INPUT_MIN_RUMBLE_UPDATE_INTERVAL_US) {
return;
}
memset(&state->sdl_haptic_effect, 0, sizeof(state->sdl_haptic_effect));
state->sdl_haptic_effect.type = SDL_HAPTIC_LEFTRIGHT;
state->sdl_haptic_effect.leftright.length = SDL_HAPTIC_INFINITY;
state->sdl_haptic_effect.leftright.large_magnitude = state->rumble_l >> 1;
state->sdl_haptic_effect.leftright.small_magnitude = state->rumble_r >> 1;
if (state->sdl_haptic_effect_id == -1) {
state->sdl_haptic_effect_id = SDL_HapticNewEffect(state->sdl_haptic, &state->sdl_haptic_effect);
SDL_HapticRunEffect(state->sdl_haptic, state->sdl_haptic_effect_id, 1);
} else {
SDL_HapticUpdateEffect(state->sdl_haptic, state->sdl_haptic_effect_id, &state->sdl_haptic_effect);
}
state->last_haptic_updated_ts = qemu_clock_get_us(QEMU_CLOCK_REALTIME);
SDL_GameControllerRumble(state->sdl_gamecontroller, state->rumble_l, state->rumble_r, 250);
state->last_rumble_updated_ts = qemu_clock_get_us(QEMU_CLOCK_REALTIME);
}
ControllerState *xemu_input_get_bound(int index)
@ -476,43 +493,6 @@ void xemu_input_bind(int index, ControllerState *state, int save)
}
}
#if 0
static void xemu_input_print_controller_state(ControllerState *state)
{
DPRINTF(" A = %d, B = %d, X = %d, Y = %d\n"
" Left = %d, Up = %d, Right = %d, Down = %d\n"
" Back = %d, Start = %d, White = %d, Black = %d\n"
"Lstick = %d, Rstick = %d, Guide = %d\n"
"\n"
"LTrig = %.3f, RTrig = %.3f\n"
"LStickX = %.3f, RStickX = %.3f\n"
"LStickY = %.3f, RStickY = %.3f\n\n",
!!(state->buttons & CONTROLLER_BUTTON_A),
!!(state->buttons & CONTROLLER_BUTTON_B),
!!(state->buttons & CONTROLLER_BUTTON_X),
!!(state->buttons & CONTROLLER_BUTTON_Y),
!!(state->buttons & CONTROLLER_BUTTON_DPAD_LEFT),
!!(state->buttons & CONTROLLER_BUTTON_DPAD_UP),
!!(state->buttons & CONTROLLER_BUTTON_DPAD_RIGHT),
!!(state->buttons & CONTROLLER_BUTTON_DPAD_DOWN),
!!(state->buttons & CONTROLLER_BUTTON_BACK),
!!(state->buttons & CONTROLLER_BUTTON_START),
!!(state->buttons & CONTROLLER_BUTTON_WHITE),
!!(state->buttons & CONTROLLER_BUTTON_BLACK),
!!(state->buttons & CONTROLLER_BUTTON_LSTICK),
!!(state->buttons & CONTROLLER_BUTTON_RSTICK),
!!(state->buttons & CONTROLLER_BUTTON_GUIDE),
state->axis[CONTROLLER_AXIS_LTRIG],
state->axis[CONTROLLER_AXIS_RTRIG],
state->axis[CONTROLLER_AXIS_LSTICK_X],
state->axis[CONTROLLER_AXIS_RSTICK_X],
state->axis[CONTROLLER_AXIS_LSTICK_Y],
state->axis[CONTROLLER_AXIS_RSTICK_Y]
);
}
#endif
void xemu_input_set_test_mode(int enabled)
{
test_mode = enabled;

View File

@ -67,7 +67,7 @@ typedef struct ControllerState {
QTAILQ_ENTRY(ControllerState) entry;
int64_t last_input_updated_ts;
int64_t last_haptic_updated_ts;
int64_t last_rumble_updated_ts;
// Input state
uint16_t buttons;
@ -78,14 +78,12 @@ typedef struct ControllerState {
uint32_t animate_trigger_end;
// Rumble state
bool rumble_enabled;
uint16_t rumble_l, rumble_r;
enum controller_input_device_type type;
const char *name;
SDL_GameController *sdl_gamecontroller; // if type == INPUT_DEVICE_SDL_GAMECONTROLLER
SDL_Haptic *sdl_haptic;
SDL_HapticEffect sdl_haptic_effect;
int sdl_haptic_effect_id;
SDL_Joystick *sdl_joystick;
SDL_JoystickID sdl_joystick_id;
SDL_JoystickGUID sdl_joystick_guid;