From 64141f90e14d19bdaf4a7fbd9f526fb1f1ccde16 Mon Sep 17 00:00:00 2001 From: Matt Borgerson Date: Fri, 8 Jan 2021 00:29:57 -0700 Subject: [PATCH] input: Use QTAILQ for available controllers list --- hw/xbox/xid.c | 4 ++-- ui/xemu-custom-widgets.c | 2 +- ui/xemu-custom-widgets.h | 2 +- ui/xemu-hud.cc | 13 +++++----- ui/xemu-input.c | 52 ++++++++++++++++------------------------ ui/xemu-input.h | 27 +++++++++++---------- 6 files changed, 46 insertions(+), 54 deletions(-) diff --git a/hw/xbox/xid.c b/hw/xbox/xid.c index 7c3b2ccf7a..2224c44727 100644 --- a/hw/xbox/xid.c +++ b/hw/xbox/xid.c @@ -198,7 +198,7 @@ static void update_output(USBXIDState *s) return; } - struct controller_state *state = xemu_input_get_bound(s->device_index); + ControllerState *state = xemu_input_get_bound(s->device_index); assert(state); state->rumble_l = s->out_state.left_actuator_strength; state->rumble_r = s->out_state.right_actuator_strength; @@ -212,7 +212,7 @@ static void update_input(USBXIDState *s) return; } - struct controller_state *state = xemu_input_get_bound(s->device_index); + ControllerState *state = xemu_input_get_bound(s->device_index); assert(state); const int button_map_analog[6][2] = { diff --git a/ui/xemu-custom-widgets.c b/ui/xemu-custom-widgets.c index 1e495fc95e..d4b687b84b 100644 --- a/ui/xemu-custom-widgets.c +++ b/ui/xemu-custom-widgets.c @@ -85,7 +85,7 @@ void render_meter( render_decal(s, x, y, width*p, height ,0, 0, 1, 1, 0, 0, color_fg); } -void render_controller(float frame_x, float frame_y, uint32_t primary_color, uint32_t secondary_color, struct controller_state *state) +void render_controller(float frame_x, float frame_y, uint32_t primary_color, uint32_t secondary_color, ControllerState *state) { // Location within the controller texture of masked button locations, // relative to the origin of the controller diff --git a/ui/xemu-custom-widgets.h b/ui/xemu-custom-widgets.h index 398608ad66..a2234958cd 100644 --- a/ui/xemu-custom-widgets.h +++ b/ui/xemu-custom-widgets.h @@ -34,7 +34,7 @@ extern struct fbo *logo_fbo; void initialize_custom_ui_rendering(void); void render_meter(struct decal_shader *s, float x, float y, float width, float height, float p, uint32_t color_bg, uint32_t color_fg); -void render_controller(float frame_x, float frame_y, uint32_t primary_color, uint32_t secondary_color, struct controller_state *state); +void render_controller(float frame_x, float frame_y, uint32_t primary_color, uint32_t secondary_color, ControllerState *state); void render_controller_port(float frame_x, float frame_y, int i, uint32_t port_color); void render_logo(uint32_t time, uint32_t primary_color, uint32_t secondary_color, uint32_t fill_color); diff --git a/ui/xemu-hud.cc b/ui/xemu-hud.cc index ccb291fbd7..d43e969b97 100644 --- a/ui/xemu-hud.cc +++ b/ui/xemu-hud.cc @@ -437,7 +437,7 @@ public: // List available input devices const char *not_connected = "Not Connected"; - struct controller_state *bound_state = xemu_input_get_bound(active); + ControllerState *bound_state = xemu_input_get_bound(active); // Get current controller name const char *name; @@ -460,8 +460,8 @@ public: } // Handle all available input devices - struct controller_state *iter; - for (iter=available_controllers; iter != NULL; iter=iter->next) { + ControllerState *iter; + QTAILQ_FOREACH(iter, &available_controllers, entry) { is_selected = bound_state == iter; ImGui::PushID(iter); const char *selectable_label = iter->name; @@ -501,7 +501,7 @@ public: device_selected = true; render_controller(0, 0, 0x81dc8a00, 0x0f0f0f00, bound_state); } else { - static struct controller_state state = { 0 }; + static ControllerState state = { 0 }; render_controller(0, 0, 0x1f1f1f00, 0x0f0f0f00, &state); } @@ -1753,12 +1753,13 @@ void xemu_hud_render(void) { uint32_t now = SDL_GetTicks(); bool ui_wakeup = false; - struct controller_state *iter; // Combine all controller states to allow any controller to navigate uint32_t buttons = 0; int16_t axis[CONTROLLER_AXIS__COUNT] = {0}; - for (iter=available_controllers; iter != NULL; iter=iter->next) { + + ControllerState *iter; + QTAILQ_FOREACH(iter, &available_controllers, entry) { if (iter->type != INPUT_DEVICE_SDL_GAMECONTROLLER) continue; buttons |= iter->buttons; // We simply take any axis that is >10 % activation diff --git a/ui/xemu-input.c b/ui/xemu-input.c index 6913a0b716..ce8f8b637c 100644 --- a/ui/xemu-input.c +++ b/ui/xemu-input.c @@ -42,8 +42,9 @@ do { } while (0) #endif -struct controller_state *available_controllers; -struct controller_state *bound_controllers[4] = { NULL, NULL, NULL, NULL }; +ControllerStateList available_controllers = + QTAILQ_HEAD_INITIALIZER(available_controllers); +ControllerState *bound_controllers[4] = { NULL, NULL, NULL, NULL }; int test_mode; static const enum xemu_settings_keys port_index_to_settings_key_map[] = { @@ -68,8 +69,8 @@ void xemu_input_init(void) } // Create the keyboard input (always first) - struct controller_state *new_con = malloc(sizeof(struct controller_state)); - memset(new_con, 0, sizeof(struct controller_state)); + ControllerState *new_con = malloc(sizeof(ControllerState)); + memset(new_con, 0, sizeof(ControllerState)); new_con->type = INPUT_DEVICE_SDL_KEYBOARD; new_con->name = "Keyboard"; new_con->bound = -1; @@ -83,10 +84,10 @@ void xemu_input_init(void) xemu_queue_notification(buf); } - available_controllers = new_con; + QTAILQ_INSERT_TAIL(&available_controllers, new_con, entry); } -int xemu_input_get_controller_default_bind_port(struct controller_state *state, int start) +int xemu_input_get_controller_default_bind_port(ControllerState *state, int start) { char guid[35] = { 0 }; if (state->type == INPUT_DEVICE_SDL_GAMECONTROLLER) { @@ -120,8 +121,8 @@ void xemu_input_process_sdl_events(const SDL_Event *event) } // Success! Create a new node to track this controller and continue init - struct controller_state *new_con = malloc(sizeof(struct controller_state)); - memset(new_con, 0, sizeof(struct controller_state)); + ControllerState *new_con = malloc(sizeof(ControllerState)); + memset(new_con, 0, sizeof(ControllerState)); new_con->type = INPUT_DEVICE_SDL_GAMECONTROLLER; new_con->name = SDL_GameControllerName(sdl_con); new_con->sdl_gamecontroller = sdl_con; @@ -136,14 +137,7 @@ void xemu_input_process_sdl_events(const SDL_Event *event) SDL_JoystickGetGUIDString(new_con->sdl_joystick_guid, guid_buf, sizeof(guid_buf)); DPRINTF("Opened %s (%s)\n", new_con->name, guid_buf); - // Add to the list of controllers - if (available_controllers == NULL) { - available_controllers = new_con; - } else { - struct controller_state *iter = available_controllers; - while (iter->next != NULL) iter = iter->next; - iter->next = new_con; - } + QTAILQ_INSERT_TAIL(&available_controllers, new_con, entry); // Do not replace binding for a currently bound device. In the case that // the same GUID is specified multiple times, on different ports, allow @@ -178,8 +172,8 @@ void xemu_input_process_sdl_events(const SDL_Event *event) } else if (event->type == SDL_CONTROLLERDEVICEREMOVED) { DPRINTF("Controller Removed: %d\n", event->cdevice.which); int handled = 0; - struct controller_state *iter, *prev; - for (iter=available_controllers, prev=NULL; iter != NULL; prev = iter, iter = iter->next) { + ControllerState *iter, *next; + QTAILQ_FOREACH_SAFE(iter, &available_controllers, entry, next) { if (iter->type != INPUT_DEVICE_SDL_GAMECONTROLLER) continue; if (iter->sdl_joystick_id == event->cdevice.which) { @@ -200,11 +194,7 @@ void xemu_input_process_sdl_events(const SDL_Event *event) } // Unlink - if (prev) { - prev->next = iter->next; - } else { - available_controllers = iter->next; - } + QTAILQ_REMOVE(&available_controllers, iter, entry); // Deallocate if (iter->sdl_haptic) { @@ -229,8 +219,8 @@ void xemu_input_process_sdl_events(const SDL_Event *event) void xemu_input_update_controllers(void) { - struct controller_state *iter; - for (iter=available_controllers; iter != NULL; iter=iter->next) { + ControllerState *iter; + QTAILQ_FOREACH(iter, &available_controllers, entry) { if (iter->type == INPUT_DEVICE_SDL_KEYBOARD) { xemu_input_update_sdl_kbd_controller_state(iter); } else if (iter->type == INPUT_DEVICE_SDL_GAMECONTROLLER) { @@ -240,7 +230,7 @@ void xemu_input_update_controllers(void) } } -void xemu_input_update_sdl_kbd_controller_state(struct controller_state *state) +void xemu_input_update_sdl_kbd_controller_state(ControllerState *state) { state->buttons = 0; memset(state->axis, 0, sizeof(state->axis)); @@ -293,7 +283,7 @@ void xemu_input_update_sdl_kbd_controller_state(struct controller_state *state) if (kbd[SDL_SCANCODE_O]) state->axis[CONTROLLER_AXIS_RTRIG] = 32767; } -void xemu_input_update_sdl_controller_state(struct controller_state *state) +void xemu_input_update_sdl_controller_state(ControllerState *state) { state->buttons = 0; memset(state->axis, 0, sizeof(state->axis)); @@ -338,7 +328,7 @@ void xemu_input_update_sdl_controller_state(struct controller_state *state) state->axis[CONTROLLER_AXIS_RSTICK_Y] = -1 - state->axis[CONTROLLER_AXIS_RSTICK_Y]; } -void xemu_input_update_rumble(struct controller_state *state) +void xemu_input_update_rumble(ControllerState *state) { if (state->sdl_haptic == NULL) { // Haptic not supported for this joystick @@ -358,12 +348,12 @@ void xemu_input_update_rumble(struct controller_state *state) } } -struct controller_state *xemu_input_get_bound(int index) +ControllerState *xemu_input_get_bound(int index) { return bound_controllers[index]; } -void xemu_input_bind(int index, struct controller_state *state, int save) +void xemu_input_bind(int index, ControllerState *state, int save) { // FIXME: Attempt to disable rumble when unbinding so it's not left // in rumble mode @@ -434,7 +424,7 @@ void xemu_input_bind(int index, struct controller_state *state, int save) } #if 0 -static void xemu_input_print_controller_state(struct controller_state *state) +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" diff --git a/ui/xemu-input.h b/ui/xemu-input.h index 6a82b0052f..324b923466 100644 --- a/ui/xemu-input.h +++ b/ui/xemu-input.h @@ -26,6 +26,7 @@ #define XEMU_INPUT_H #include +#include "qemu/queue.h" enum controller_state_buttons_mask { CONTROLLER_BUTTON_A = (1 << 0), @@ -62,7 +63,9 @@ enum controller_input_device_type { INPUT_DEVICE_SDL_GAMECONTROLLER, }; -struct controller_state { +typedef struct ControllerState { + QTAILQ_ENTRY(ControllerState) entry; + // Input state uint16_t buttons; int16_t axis[CONTROLLER_AXIS__COUNT]; @@ -86,13 +89,11 @@ struct controller_state { int bound; // Which port this input device is bound to void *device; // DeviceState opaque +} ControllerState; - struct controller_state *next; -}; - -extern int num_available_controllers; -extern struct controller_state *available_controllers; -extern struct controller_state *bound_controllers[4]; +typedef QTAILQ_HEAD(, ControllerState) ControllerStateList; +extern ControllerStateList available_controllers; +extern ControllerState *bound_controllers[4]; #ifdef __cplusplus extern "C" { @@ -101,12 +102,12 @@ extern "C" { void xemu_input_init(void); void xemu_input_process_sdl_events(const SDL_Event *event); // SDL_CONTROLLERDEVICEADDED, SDL_CONTROLLERDEVICEREMOVED void xemu_input_update_controllers(void); -void xemu_input_update_sdl_kbd_controller_state(struct controller_state *state); -void xemu_input_update_sdl_controller_state(struct controller_state *state); -void xemu_input_update_rumble(struct controller_state *state); -struct controller_state *xemu_input_get_bound(int index); -void xemu_input_bind(int index, struct controller_state *state, int save); -int xemu_input_get_controller_default_bind_port(struct controller_state *state, int start); +void xemu_input_update_sdl_kbd_controller_state(ControllerState *state); +void xemu_input_update_sdl_controller_state(ControllerState *state); +void xemu_input_update_rumble(ControllerState *state); +ControllerState *xemu_input_get_bound(int index); +void xemu_input_bind(int index, ControllerState *state, int save); +int xemu_input_get_controller_default_bind_port(ControllerState *state, int start); void xemu_input_set_test_mode(int enabled); int xemu_input_get_test_mode(void);