From 6b7721db58c4d70ffa7bf27818fee5ff3f6e30e0 Mon Sep 17 00:00:00 2001 From: Matt Borgerson Date: Sat, 23 Apr 2022 14:19:36 -0700 Subject: [PATCH] input: Move from haptic to rumble API --- ui/xemu-input.c | 110 ++++++++++++++++++++---------------------------- ui/xemu-input.h | 6 +-- 2 files changed, 47 insertions(+), 69 deletions(-) diff --git a/ui/xemu-input.c b/ui/xemu-input.c index a0a4cca5e6..1549c7ccc1 100644 --- a/ui/xemu-input.c +++ b/ui/xemu-input.c @@ -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; diff --git a/ui/xemu-input.h b/ui/xemu-input.h index a21a06fac7..8a8ba6544e 100644 --- a/ui/xemu-input.h +++ b/ui/xemu-input.h @@ -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;