mirror of https://github.com/xemu-project/xemu.git
input: Use QTAILQ for available controllers list
This commit is contained in:
parent
5233f777cf
commit
64141f90e1
|
@ -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] = {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#define XEMU_INPUT_H
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#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);
|
||||
|
|
Loading…
Reference in New Issue