From dad5e347d81e608a713eb1d9c3d4cf4d5056699b Mon Sep 17 00:00:00 2001 From: Themaister Date: Sun, 29 Sep 2013 17:58:46 +0200 Subject: [PATCH 01/16] Start adding joypad config. --- driver.h | 3 ++ frontend/menu/menu_common.c | 95 ++++++++++++++++++++++++++++++++ frontend/menu/menu_common.h | 34 ++++++++++-- frontend/menu/rgui.c | 96 +++++++++++++++++++-------------- frontend/menu/rguidisp_bitmap.c | 60 +++++++++++++++++---- input/x11_input.c | 7 +++ settings.c | 2 +- 7 files changed, 244 insertions(+), 53 deletions(-) diff --git a/driver.h b/driver.h index 764c1e4ab5..d5f3492260 100644 --- a/driver.h +++ b/driver.h @@ -323,6 +323,8 @@ enum keybind_set_id KEYBINDS_ACTION_LAST }; +typedef struct rarch_joypad_driver rarch_joypad_driver_t; + typedef struct input_driver { void *(*init)(void); @@ -336,6 +338,7 @@ typedef struct input_driver void (*grab_mouse)(void *data, bool state); bool (*set_rumble)(void *data, unsigned port, enum retro_rumble_effect effect, uint16_t state); + const rarch_joypad_driver_t *(*get_joypad_driver)(void *data); } input_driver_t; struct rarch_viewport; diff --git a/frontend/menu/menu_common.c b/frontend/menu/menu_common.c index 72541fda1a..14133f4170 100644 --- a/frontend/menu/menu_common.c +++ b/frontend/menu/menu_common.c @@ -22,8 +22,10 @@ #include "menu_common.h" #include "../../performance.h" +#include "../../driver.h" #include "../../file.h" #include "menu_context.h" +#include "../../input/input_common.h" #include "../../compat/posix_string.h" @@ -753,4 +755,97 @@ bool menu_save_new_config(void) return ret; } +void menu_poll_bind_state(struct rgui_bind_state *state) +{ + memset(state->state, 0, sizeof(state->state)); + state->skip = input_input_state_func(NULL, 0, RETRO_DEVICE_KEYBOARD, 0, RETROK_RETURN); + + const rarch_joypad_driver_t *joypad = NULL; + if (driver.input && driver.input_data && driver.input->get_joypad_driver) + joypad = driver.input->get_joypad_driver(driver.input_data); + + if (!joypad) + { + RARCH_ERR("Cannot poll raw joypad state."); + return; + } + + input_joypad_poll(joypad); + for (unsigned p = 0; p < MAX_PLAYERS; p++) + { + for (unsigned b = 0; b < RGUI_MAX_BUTTONS; b++) + state->state[p].buttons[b] = input_joypad_button_raw(joypad, p, b); + for (unsigned a = 0; a < RGUI_MAX_AXES; a++) + state->state[p].axes[a] = input_joypad_axis_raw(joypad, p, a); + for (unsigned h = 0; h < RGUI_MAX_HATS; h++) + { + state->state[p].hats[h] |= input_joypad_hat_raw(joypad, p, HAT_UP_MASK, h) ? HAT_UP_MASK : 0; + state->state[p].hats[h] |= input_joypad_hat_raw(joypad, p, HAT_DOWN_MASK, h) ? HAT_DOWN_MASK : 0; + state->state[p].hats[h] |= input_joypad_hat_raw(joypad, p, HAT_LEFT_MASK, h) ? HAT_LEFT_MASK : 0; + state->state[p].hats[h] |= input_joypad_hat_raw(joypad, p, HAT_RIGHT_MASK, h) ? HAT_RIGHT_MASK : 0; + } + } +} + +static bool menu_poll_find_trigger_pad(struct rgui_bind_state *state, const struct rgui_bind_state *new_state, unsigned p) +{ + const struct rgui_bind_state_port *n = &new_state->state[p]; + const struct rgui_bind_state_port *o = &state->state[p]; + for (unsigned b = 0; b < RGUI_MAX_BUTTONS; b++) + { + if (n->buttons[b] && !o->buttons[b]) + { + state->target->joykey = b; + state->target->joyaxis = AXIS_NONE; + return true; + } + } + + for (unsigned a = 0; a < RGUI_MAX_AXES; a++) + { + int axis_distance = abs(n->axes[a] - o->axes[a]); + if (abs(n->axes[a]) >= 20000 && axis_distance >= 20000) // Take care of case where axis rests on +/- 0x7fff (e.g. 360 controller on Linux) + { + state->target->joyaxis = n->axes[a] > 0 ? AXIS_POS(a) : AXIS_NEG(a); + state->target->joykey = NO_BTN; + return true; + } + } + + for (unsigned h = 0; h < RGUI_MAX_HATS; h++) + { + uint16_t trigged = n->hats[h] & (~o->hats[h]); + uint16_t sane_trigger = 0; + if (trigged & HAT_UP_MASK) + sane_trigger = HAT_UP_MASK; + else if (trigged & HAT_DOWN_MASK) + sane_trigger = HAT_DOWN_MASK; + else if (trigged & HAT_LEFT_MASK) + sane_trigger = HAT_LEFT_MASK; + else if (trigged & HAT_RIGHT_MASK) + sane_trigger = HAT_RIGHT_MASK; + + if (sane_trigger) + { + state->target->joykey = HAT_MAP(h, sane_trigger); + state->target->joyaxis = AXIS_NONE; + return true; + } + } + + return false; +} + +bool menu_poll_find_trigger(struct rgui_bind_state *state, const struct rgui_bind_state *new_state) +{ + for (unsigned p = 0; p < MAX_PLAYERS; p++) + { + if (menu_poll_find_trigger_pad(state, new_state, p)) + { + g_settings.input.joypad_map[state->player] = p; // Update the joypad mapping automatically. More friendly that way. + return true; + } + } + return false; +} diff --git a/frontend/menu/menu_common.h b/frontend/menu/menu_common.h index 36460a076d..0f0c26004a 100644 --- a/frontend/menu/menu_common.h +++ b/frontend/menu/menu_common.h @@ -147,22 +147,25 @@ typedef enum RGUI_SETTINGS_BIND_DEVICE, RGUI_SETTINGS_BIND_DEVICE_TYPE, RGUI_SETTINGS_BIND_DPAD_EMULATION, + + // Match up with libretro order for simplicity. + RGUI_SETTINGS_BIND_B, + RGUI_SETTINGS_BIND_Y, + RGUI_SETTINGS_BIND_SELECT, + RGUI_SETTINGS_BIND_START, RGUI_SETTINGS_BIND_UP, RGUI_SETTINGS_BIND_DOWN, RGUI_SETTINGS_BIND_LEFT, RGUI_SETTINGS_BIND_RIGHT, RGUI_SETTINGS_BIND_A, - RGUI_SETTINGS_BIND_B, RGUI_SETTINGS_BIND_X, - RGUI_SETTINGS_BIND_Y, - RGUI_SETTINGS_BIND_START, - RGUI_SETTINGS_BIND_SELECT, RGUI_SETTINGS_BIND_L, RGUI_SETTINGS_BIND_R, RGUI_SETTINGS_BIND_L2, RGUI_SETTINGS_BIND_R2, RGUI_SETTINGS_BIND_L3, RGUI_SETTINGS_BIND_R3, + RGUI_SETTINGS_CUSTOM_BIND, RGUI_SETTINGS_CORE_OPTION_NONE = 0xffff, RGUI_SETTINGS_CORE_OPTION_START = 0x10000 @@ -186,6 +189,27 @@ typedef enum RGUI_ACTION_NOOP } rgui_action_t; +#define RGUI_MAX_BUTTONS 32 +#define RGUI_MAX_AXES 32 +#define RGUI_MAX_HATS 4 +struct rgui_bind_state_port +{ + bool buttons[RGUI_MAX_BUTTONS]; + int16_t axes[RGUI_MAX_AXES]; + uint16_t hats[RGUI_MAX_HATS]; +}; + +struct rgui_bind_state +{ + struct retro_keybind *target; + unsigned player; + struct rgui_bind_state_port state[MAX_PLAYERS]; + bool skip; +}; + +void menu_poll_bind_state(struct rgui_bind_state *state); +bool menu_poll_find_trigger(struct rgui_bind_state *state, const struct rgui_bind_state *new_state); + typedef struct { uint64_t old_input_state; @@ -235,6 +259,8 @@ typedef struct rom_history_t *history; rarch_time_t last_time; // Used to throttle RGUI in case VSync is broken. + + struct rgui_bind_state binds; } rgui_handle_t; extern rgui_handle_t *rgui; diff --git a/frontend/menu/rgui.c b/frontend/menu/rgui.c index d367e8d757..d4f5baccc4 100644 --- a/frontend/menu/rgui.c +++ b/frontend/menu/rgui.c @@ -107,25 +107,6 @@ static int shader_manager_toggle_setting(rgui_handle_t *rgui, unsigned setting, #endif static int video_option_toggle_setting(rgui_handle_t *rgui, unsigned setting, rgui_action_t action); -static const unsigned rgui_controller_lut[] = { - RETRO_DEVICE_ID_JOYPAD_UP, - RETRO_DEVICE_ID_JOYPAD_DOWN, - RETRO_DEVICE_ID_JOYPAD_LEFT, - RETRO_DEVICE_ID_JOYPAD_RIGHT, - RETRO_DEVICE_ID_JOYPAD_A, - RETRO_DEVICE_ID_JOYPAD_B, - RETRO_DEVICE_ID_JOYPAD_X, - RETRO_DEVICE_ID_JOYPAD_Y, - RETRO_DEVICE_ID_JOYPAD_START, - RETRO_DEVICE_ID_JOYPAD_SELECT, - RETRO_DEVICE_ID_JOYPAD_L, - RETRO_DEVICE_ID_JOYPAD_R, - RETRO_DEVICE_ID_JOYPAD_L2, - RETRO_DEVICE_ID_JOYPAD_R2, - RETRO_DEVICE_ID_JOYPAD_L3, - RETRO_DEVICE_ID_JOYPAD_R3, -}; - static void rgui_flush_menu_stack_type(rgui_handle_t *rgui, unsigned final_type) { rgui->need_refresh = true; @@ -726,10 +707,28 @@ static int rgui_settings_toggle_setting(rgui_handle_t *rgui, unsigned setting, r else if (action == RGUI_ACTION_RIGHT) keybind_action = (1ULL << KEYBINDS_ACTION_INCREMENT_BIND); + // FIXME: The array indices here look totally wrong ... Fixed it so it looks sane for now. if (keybind_action != KEYBINDS_ACTION_NONE) - driver.input->set_keybinds(driver.input_data, g_settings.input.device[setting - RGUI_SETTINGS_BIND_UP], port, - rgui_controller_lut[setting - RGUI_SETTINGS_BIND_UP], keybind_action); + driver.input->set_keybinds(driver.input_data, g_settings.input.device[port], port, + setting - RGUI_SETTINGS_BIND_B, keybind_action); } + else + { + struct retro_keybind *bind = &g_settings.input.binds[port][setting - RGUI_SETTINGS_BIND_B]; + if (action == RGUI_ACTION_OK) + { + rgui->binds.target = bind; + rgui->binds.player = port; + rgui_list_push(rgui->menu_stack, "", RGUI_SETTINGS_CUSTOM_BIND, rgui->selection_ptr); + menu_poll_bind_state(&rgui->binds); + } + else if (action == RGUI_ACTION_START) + { + bind->joykey = NO_BTN; + bind->joyaxis = AXIS_NONE; + } + } + break; case RGUI_BROWSER_DIR_PATH: if (action == RGUI_ACTION_START) { @@ -1514,25 +1513,42 @@ static void rgui_settings_controller_populate_entries(rgui_handle_t *rgui) rgui_list_push(rgui->selection_buf, "Device Type", RGUI_SETTINGS_BIND_DEVICE_TYPE, 0); if (driver.input && driver.input->set_keybinds) - { rgui_list_push(rgui->selection_buf, "DPad Emulation", RGUI_SETTINGS_BIND_DPAD_EMULATION, 0); - rgui_list_push(rgui->selection_buf, "Up", RGUI_SETTINGS_BIND_UP, 0); - rgui_list_push(rgui->selection_buf, "Down", RGUI_SETTINGS_BIND_DOWN, 0); - rgui_list_push(rgui->selection_buf, "Left", RGUI_SETTINGS_BIND_LEFT, 0); - rgui_list_push(rgui->selection_buf, "Right", RGUI_SETTINGS_BIND_RIGHT, 0); - rgui_list_push(rgui->selection_buf, "A", RGUI_SETTINGS_BIND_A, 0); - rgui_list_push(rgui->selection_buf, "B", RGUI_SETTINGS_BIND_B, 0); - rgui_list_push(rgui->selection_buf, "X", RGUI_SETTINGS_BIND_X, 0); - rgui_list_push(rgui->selection_buf, "Y", RGUI_SETTINGS_BIND_Y, 0); - rgui_list_push(rgui->selection_buf, "Start", RGUI_SETTINGS_BIND_START, 0); - rgui_list_push(rgui->selection_buf, "Select", RGUI_SETTINGS_BIND_SELECT, 0); - rgui_list_push(rgui->selection_buf, "L", RGUI_SETTINGS_BIND_L, 0); - rgui_list_push(rgui->selection_buf, "R", RGUI_SETTINGS_BIND_R, 0); - rgui_list_push(rgui->selection_buf, "L2", RGUI_SETTINGS_BIND_L2, 0); - rgui_list_push(rgui->selection_buf, "R2", RGUI_SETTINGS_BIND_R2, 0); - rgui_list_push(rgui->selection_buf, "L3", RGUI_SETTINGS_BIND_L3, 0); - rgui_list_push(rgui->selection_buf, "R3", RGUI_SETTINGS_BIND_R3, 0); - } + + rgui_list_push(rgui->selection_buf, "Up", RGUI_SETTINGS_BIND_UP, 0); + rgui_list_push(rgui->selection_buf, "Down", RGUI_SETTINGS_BIND_DOWN, 0); + rgui_list_push(rgui->selection_buf, "Left", RGUI_SETTINGS_BIND_LEFT, 0); + rgui_list_push(rgui->selection_buf, "Right", RGUI_SETTINGS_BIND_RIGHT, 0); + rgui_list_push(rgui->selection_buf, "A (right)", RGUI_SETTINGS_BIND_A, 0); + rgui_list_push(rgui->selection_buf, "B (down)", RGUI_SETTINGS_BIND_B, 0); + rgui_list_push(rgui->selection_buf, "X (top)", RGUI_SETTINGS_BIND_X, 0); + rgui_list_push(rgui->selection_buf, "Y (left)", RGUI_SETTINGS_BIND_Y, 0); + rgui_list_push(rgui->selection_buf, "Start", RGUI_SETTINGS_BIND_START, 0); + rgui_list_push(rgui->selection_buf, "Select", RGUI_SETTINGS_BIND_SELECT, 0); + rgui_list_push(rgui->selection_buf, "L", RGUI_SETTINGS_BIND_L, 0); + rgui_list_push(rgui->selection_buf, "R", RGUI_SETTINGS_BIND_R, 0); + rgui_list_push(rgui->selection_buf, "L2", RGUI_SETTINGS_BIND_L2, 0); + rgui_list_push(rgui->selection_buf, "R2", RGUI_SETTINGS_BIND_R2, 0); + rgui_list_push(rgui->selection_buf, "L3", RGUI_SETTINGS_BIND_L3, 0); + rgui_list_push(rgui->selection_buf, "R3", RGUI_SETTINGS_BIND_R3, 0); +} + +// This only makes sense for PC so far. +// Consoles use set_keybind callbacks instead. +static int rgui_custom_bind_iterate(rgui_handle_t *rgui, rgui_action_t action) +{ + (void)action; // Have to ignore action here. Only bind that should work here is Quit RetroArch or something like that. + + render_text(rgui); + render_messagebox(rgui, "[key] press joypad (RETURN to skip)"); + + struct rgui_bind_state binds = rgui->binds; + menu_poll_bind_state(&binds); + + if ((binds.skip && !rgui->binds.skip) || menu_poll_find_trigger(&rgui->binds, &binds)) + rgui_list_pop(rgui->menu_stack, &rgui->selection_ptr); + rgui->binds = binds; + return 0; } static int rgui_viewport_iterate(rgui_handle_t *rgui, rgui_action_t action) @@ -2019,6 +2035,8 @@ static int rgui_iterate(void *data, unsigned action) return rgui_settings_iterate(rgui, action); else if (menu_type == RGUI_SETTINGS_CUSTOM_VIEWPORT || menu_type == RGUI_SETTINGS_CUSTOM_VIEWPORT_2) return rgui_viewport_iterate(rgui, action); + else if (menu_type == RGUI_SETTINGS_CUSTOM_BIND) + return rgui_custom_bind_iterate(rgui, action); if (rgui->need_refresh && action != RGUI_ACTION_MESSAGE) action = RGUI_ACTION_NOOP; diff --git a/frontend/menu/rguidisp_bitmap.c b/frontend/menu/rguidisp_bitmap.c index 30b994cc04..fde4167cd6 100644 --- a/frontend/menu/rguidisp_bitmap.c +++ b/frontend/menu/rguidisp_bitmap.c @@ -230,6 +230,7 @@ static void render_text(rgui_handle_t *rgui) (menu_type == RGUI_SETTINGS_PATH_OPTIONS) || (menu_type == RGUI_SETTINGS_OPTIONS) || (menu_type == RGUI_SETTINGS_CUSTOM_VIEWPORT || menu_type == RGUI_SETTINGS_CUSTOM_VIEWPORT_2) || + menu_type == RGUI_SETTINGS_CUSTOM_BIND || menu_type == RGUI_SETTINGS) snprintf(title, sizeof(title), "MENU %s", dir); else if (menu_type == RGUI_SETTINGS_OPEN_HISTORY) @@ -303,7 +304,7 @@ static void render_text(rgui_handle_t *rgui) rgui_list_get_at_offset(rgui->selection_buf, i, &path, &type); char message[256]; char type_str[256]; - unsigned w = (menu_type == RGUI_SETTINGS_INPUT_OPTIONS || menu_type == RGUI_SETTINGS_PATH_OPTIONS) ? 24 : 19; + unsigned w = (menu_type == RGUI_SETTINGS_INPUT_OPTIONS || menu_type == RGUI_SETTINGS_PATH_OPTIONS || menu_type == RGUI_SETTINGS_CUSTOM_BIND) ? 24 : 19; unsigned port = rgui->current_pad; #ifdef HAVE_SHADER_MANAGER @@ -624,18 +625,59 @@ static void render_text(rgui_handle_t *rgui) case RGUI_SETTINGS_BIND_R2: case RGUI_SETTINGS_BIND_L3: case RGUI_SETTINGS_BIND_R3: + { + unsigned id = type - RGUI_SETTINGS_BIND_B; + struct platform_bind key_label; + strlcpy(key_label.desc, "Unknown", sizeof(key_label.desc)); + key_label.joykey = g_settings.input.binds[port][id].joykey; + + if (driver.input->set_keybinds) { - unsigned id = rgui_controller_lut[type - RGUI_SETTINGS_BIND_UP]; - struct platform_bind key_label; - strlcpy(key_label.desc, "Unknown", sizeof(key_label.desc)); - key_label.joykey = g_settings.input.binds[port][id].joykey; - - if (driver.input->set_keybinds) - driver.input->set_keybinds(&key_label, 0, 0, 0, (1ULL << KEYBINDS_ACTION_GET_BIND_LABEL)); - + driver.input->set_keybinds(&key_label, 0, 0, 0, (1ULL << KEYBINDS_ACTION_GET_BIND_LABEL)); strlcpy(type_str, key_label.desc, sizeof(type_str)); } + else + { + const struct retro_keybind *bind = &g_settings.input.binds[port][type - RGUI_SETTINGS_BIND_B]; + if (bind->joykey != NO_BTN) + { + if (GET_HAT_DIR(bind->joykey)) + { + const char *dir; + switch (GET_HAT_DIR(bind->joykey)) + { + case HAT_UP_MASK: dir = "up"; break; + case HAT_DOWN_MASK: dir = "down"; break; + case HAT_LEFT_MASK: dir = "left"; break; + case HAT_RIGHT_MASK: dir = "right"; break; + default: dir = "?"; break; + } + snprintf(type_str, sizeof(type_str), "Hat #%u %s", (unsigned)GET_HAT(bind->joykey), dir); + } + else + snprintf(type_str, sizeof(type_str), "%u (btn)", (unsigned)bind->joykey); + } + else if (bind->joyaxis != AXIS_NONE) + { + unsigned axis = 0; + char dir = '\0'; + if (AXIS_NEG_GET(bind->joyaxis) != AXIS_DIR_NONE) + { + dir = '-'; + axis = AXIS_NEG_GET(bind->joyaxis); + } + else if (AXIS_POS_GET(bind->joyaxis) != AXIS_DIR_NONE) + { + dir = '+'; + axis = AXIS_POS_GET(bind->joyaxis); + } + snprintf(type_str, sizeof(type_str), "%c%u (axis)", dir, axis); + } + else + strlcpy(type_str, "", sizeof(type_str)); + } break; + } default: type_str[0] = 0; w = 0; diff --git a/input/x11_input.c b/input/x11_input.c index 1783698d42..76c9c19f34 100644 --- a/input/x11_input.c +++ b/input/x11_input.c @@ -275,6 +275,12 @@ static bool x_set_rumble(void *data, unsigned port, enum retro_rumble_effect eff return input_joypad_set_rumble(x11->joypad, port, effect, strength); } +static const rarch_joypad_driver_t *x_get_joypad_driver(void *data) +{ + x11_input_t *x11 = (x11_input_t*)data; + return x11->joypad; +} + const input_driver_t input_x = { x_input_init, x_input_poll, @@ -285,5 +291,6 @@ const input_driver_t input_x = { "x", x_grab_mouse, x_set_rumble, + x_get_joypad_driver, }; diff --git a/settings.c b/settings.c index 2916f04ff4..85d7a0302d 100644 --- a/settings.c +++ b/settings.c @@ -1179,7 +1179,7 @@ void settings_set(uint64_t settings) } if (settings & (1ULL << S_DEF_INPUT_OVERLAY_SCALE)) - g_settings.input.overlay_opacity = 1.0f; + g_settings.input.overlay_scale = 1.0f; #endif if (settings & (1ULL << S_REWIND_GRANULARITY_INCREMENT)) From c5a033f7e1cdeb7a1185cd89708438ac4254f49e Mon Sep 17 00:00:00 2001 From: Themaister Date: Sun, 29 Sep 2013 19:09:33 +0200 Subject: [PATCH 02/16] Basic configuration seems to work. --- frontend/menu/menu_common.c | 37 +++++++++++++++++++++++++++++++++---- frontend/menu/menu_common.h | 13 ++++++++++++- frontend/menu/rgui.c | 1 + 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/frontend/menu/menu_common.c b/frontend/menu/menu_common.c index 14133f4170..64f12bc92d 100644 --- a/frontend/menu/menu_common.c +++ b/frontend/menu/menu_common.c @@ -787,10 +787,28 @@ void menu_poll_bind_state(struct rgui_bind_state *state) } } -static bool menu_poll_find_trigger_pad(struct rgui_bind_state *state, const struct rgui_bind_state *new_state, unsigned p) +void menu_poll_bind_get_rested_axes(struct rgui_bind_state *state) +{ + const rarch_joypad_driver_t *joypad = NULL; + if (driver.input && driver.input_data && driver.input->get_joypad_driver) + joypad = driver.input->get_joypad_driver(driver.input_data); + + if (!joypad) + { + RARCH_ERR("Cannot poll raw joypad state."); + return; + } + + for (unsigned p = 0; p < MAX_PLAYERS; p++) + for (unsigned a = 0; a < RGUI_MAX_AXES; a++) + state->axis_state[p].rested_axes[a] = input_joypad_axis_raw(joypad, p, a); +} + +static bool menu_poll_find_trigger_pad(struct rgui_bind_state *state, struct rgui_bind_state *new_state, unsigned p) { const struct rgui_bind_state_port *n = &new_state->state[p]; const struct rgui_bind_state_port *o = &state->state[p]; + for (unsigned b = 0; b < RGUI_MAX_BUTTONS; b++) { if (n->buttons[b] && !o->buttons[b]) @@ -801,15 +819,26 @@ static bool menu_poll_find_trigger_pad(struct rgui_bind_state *state, const stru } } + // Axes are a bit tricky ... for (unsigned a = 0; a < RGUI_MAX_AXES; a++) { - int axis_distance = abs(n->axes[a] - o->axes[a]); - if (abs(n->axes[a]) >= 20000 && axis_distance >= 20000) // Take care of case where axis rests on +/- 0x7fff (e.g. 360 controller on Linux) + int locked_distance = abs(n->axes[a] - new_state->axis_state[p].locked_axes[a]); + int rested_distance = abs(n->axes[a] - new_state->axis_state[p].rested_axes[a]); + + if (abs(n->axes[a]) >= 20000 && + locked_distance >= 20000 && + rested_distance >= 20000) // Take care of case where axis rests on +/- 0x7fff (e.g. 360 controller on Linux) { state->target->joyaxis = n->axes[a] > 0 ? AXIS_POS(a) : AXIS_NEG(a); state->target->joykey = NO_BTN; + + // Lock the current axis. + new_state->axis_state[p].locked_axes[a] = n->axes[a] > 0 ? 0x7fff : -0x7fff; return true; } + + if (locked_distance >= 20000) // Unlock the axis. + new_state->axis_state[p].locked_axes[a] = 0; } for (unsigned h = 0; h < RGUI_MAX_HATS; h++) @@ -836,7 +865,7 @@ static bool menu_poll_find_trigger_pad(struct rgui_bind_state *state, const stru return false; } -bool menu_poll_find_trigger(struct rgui_bind_state *state, const struct rgui_bind_state *new_state) +bool menu_poll_find_trigger(struct rgui_bind_state *state, struct rgui_bind_state *new_state) { for (unsigned p = 0; p < MAX_PLAYERS; p++) { diff --git a/frontend/menu/menu_common.h b/frontend/menu/menu_common.h index 0f0c26004a..0307c0a662 100644 --- a/frontend/menu/menu_common.h +++ b/frontend/menu/menu_common.h @@ -197,6 +197,15 @@ struct rgui_bind_state_port bool buttons[RGUI_MAX_BUTTONS]; int16_t axes[RGUI_MAX_AXES]; uint16_t hats[RGUI_MAX_HATS]; + +}; + +struct rgui_bind_axis_state +{ + // Default axis state. + int16_t rested_axes[RGUI_MAX_AXES]; + // Locked axis state. If we configured an axis, avoid having the same axis state trigger something again right away. + int16_t locked_axes[RGUI_MAX_AXES]; }; struct rgui_bind_state @@ -204,11 +213,13 @@ struct rgui_bind_state struct retro_keybind *target; unsigned player; struct rgui_bind_state_port state[MAX_PLAYERS]; + struct rgui_bind_axis_state axis_state[MAX_PLAYERS]; bool skip; }; +void menu_poll_bind_get_rested_axes(struct rgui_bind_state *state); void menu_poll_bind_state(struct rgui_bind_state *state); -bool menu_poll_find_trigger(struct rgui_bind_state *state, const struct rgui_bind_state *new_state); +bool menu_poll_find_trigger(struct rgui_bind_state *state, struct rgui_bind_state *new_state); typedef struct { diff --git a/frontend/menu/rgui.c b/frontend/menu/rgui.c index d4f5baccc4..9a4f56f73c 100644 --- a/frontend/menu/rgui.c +++ b/frontend/menu/rgui.c @@ -720,6 +720,7 @@ static int rgui_settings_toggle_setting(rgui_handle_t *rgui, unsigned setting, r rgui->binds.target = bind; rgui->binds.player = port; rgui_list_push(rgui->menu_stack, "", RGUI_SETTINGS_CUSTOM_BIND, rgui->selection_ptr); + menu_poll_bind_get_rested_axes(&rgui->binds); menu_poll_bind_state(&rgui->binds); } else if (action == RGUI_ACTION_START) From f1bfaaf42062647c4d622c1cf2778f0458dedd4d Mon Sep 17 00:00:00 2001 From: Themaister Date: Sun, 29 Sep 2013 19:37:48 +0200 Subject: [PATCH 03/16] Allow to customize all. --- frontend/menu/menu_common.h | 3 ++ frontend/menu/rgui.c | 49 +++++++++++++++++++++++++++++++-- frontend/menu/rguidisp_bitmap.c | 1 + settings.c | 4 +++ 4 files changed, 54 insertions(+), 3 deletions(-) diff --git a/frontend/menu/menu_common.h b/frontend/menu/menu_common.h index 0307c0a662..70789f7df2 100644 --- a/frontend/menu/menu_common.h +++ b/frontend/menu/menu_common.h @@ -166,6 +166,7 @@ typedef enum RGUI_SETTINGS_BIND_L3, RGUI_SETTINGS_BIND_R3, RGUI_SETTINGS_CUSTOM_BIND, + RGUI_SETTINGS_CUSTOM_BIND_ALL, RGUI_SETTINGS_CORE_OPTION_NONE = 0xffff, RGUI_SETTINGS_CORE_OPTION_START = 0x10000 @@ -211,6 +212,8 @@ struct rgui_bind_axis_state struct rgui_bind_state { struct retro_keybind *target; + unsigned begin; + unsigned last; unsigned player; struct rgui_bind_state_port state[MAX_PLAYERS]; struct rgui_bind_axis_state axis_state[MAX_PLAYERS]; diff --git a/frontend/menu/rgui.c b/frontend/menu/rgui.c index 9a4f56f73c..5a7b8fb4bf 100644 --- a/frontend/menu/rgui.c +++ b/frontend/menu/rgui.c @@ -680,6 +680,17 @@ static int rgui_settings_toggle_setting(rgui_handle_t *rgui, unsigned setting, r keybind_action); } break; + case RGUI_SETTINGS_CUSTOM_BIND_ALL: + if (action == RGUI_ACTION_OK) + { + rgui->binds.target = &g_settings.input.binds[port][0]; + rgui->binds.begin = RGUI_SETTINGS_BIND_B; + rgui->binds.last = RGUI_SETTINGS_BIND_R3; + rgui_list_push(rgui->menu_stack, "", RGUI_SETTINGS_CUSTOM_BIND, rgui->selection_ptr); + menu_poll_bind_get_rested_axes(&rgui->binds); + menu_poll_bind_state(&rgui->binds); + } + break; case RGUI_SETTINGS_BIND_UP: case RGUI_SETTINGS_BIND_DOWN: case RGUI_SETTINGS_BIND_LEFT: @@ -707,7 +718,7 @@ static int rgui_settings_toggle_setting(rgui_handle_t *rgui, unsigned setting, r else if (action == RGUI_ACTION_RIGHT) keybind_action = (1ULL << KEYBINDS_ACTION_INCREMENT_BIND); - // FIXME: The array indices here look totally wrong ... Fixed it so it looks sane for now. + // FIXME: The array indices here look totally wrong ... Fixed it so it looks kind of sane for now. if (keybind_action != KEYBINDS_ACTION_NONE) driver.input->set_keybinds(driver.input_data, g_settings.input.device[port], port, setting - RGUI_SETTINGS_BIND_B, keybind_action); @@ -717,6 +728,8 @@ static int rgui_settings_toggle_setting(rgui_handle_t *rgui, unsigned setting, r struct retro_keybind *bind = &g_settings.input.binds[port][setting - RGUI_SETTINGS_BIND_B]; if (action == RGUI_ACTION_OK) { + rgui->binds.begin = setting; + rgui->binds.last = setting; rgui->binds.target = bind; rgui->binds.player = port; rgui_list_push(rgui->menu_stack, "", RGUI_SETTINGS_CUSTOM_BIND, rgui->selection_ptr); @@ -1515,6 +1528,8 @@ static void rgui_settings_controller_populate_entries(rgui_handle_t *rgui) if (driver.input && driver.input->set_keybinds) rgui_list_push(rgui->selection_buf, "DPad Emulation", RGUI_SETTINGS_BIND_DPAD_EMULATION, 0); + else + rgui_list_push(rgui->selection_buf, "Configure All", RGUI_SETTINGS_CUSTOM_BIND_ALL, 0); // This doesn't make sense on anything else than PC. rgui_list_push(rgui->selection_buf, "Up", RGUI_SETTINGS_BIND_UP, 0); rgui_list_push(rgui->selection_buf, "Down", RGUI_SETTINGS_BIND_DOWN, 0); @@ -1541,13 +1556,41 @@ static int rgui_custom_bind_iterate(rgui_handle_t *rgui, rgui_action_t action) (void)action; // Have to ignore action here. Only bind that should work here is Quit RetroArch or something like that. render_text(rgui); - render_messagebox(rgui, "[key] press joypad (RETURN to skip)"); + + static const char *rgui_key_to_str[] = { + "B (down)", + "Y (left)", + "Select", + "Start", + "D-pad Up", + "D-pad Down", + "D-pad Left", + "D-pad Right", + "A (right)", + "X (top)", + "L (trigger)", + "R (trigger)", + "L2 (trigger)", + "R2 (trigger)", + "L3 (thumb)", + "R3 (thumb)", + }; + + char msg[256]; + snprintf(msg, sizeof(msg), "[%s] press joypad (RETURN to skip)", rgui_key_to_str[rgui->binds.begin - RGUI_SETTINGS_BIND_B]); + render_messagebox(rgui, msg); struct rgui_bind_state binds = rgui->binds; menu_poll_bind_state(&binds); if ((binds.skip && !rgui->binds.skip) || menu_poll_find_trigger(&rgui->binds, &binds)) - rgui_list_pop(rgui->menu_stack, &rgui->selection_ptr); + { + binds.begin++; + if (binds.begin <= binds.last) + binds.target++; + else + rgui_list_pop(rgui->menu_stack, &rgui->selection_ptr); + } rgui->binds = binds; return 0; } diff --git a/frontend/menu/rguidisp_bitmap.c b/frontend/menu/rguidisp_bitmap.c index fde4167cd6..69560de319 100644 --- a/frontend/menu/rguidisp_bitmap.c +++ b/frontend/menu/rguidisp_bitmap.c @@ -534,6 +534,7 @@ static void render_text(rgui_handle_t *rgui) case RGUI_SETTINGS_INPUT_OPTIONS: case RGUI_SETTINGS_PATH_OPTIONS: case RGUI_SETTINGS_OPTIONS: + case RGUI_SETTINGS_CUSTOM_BIND_ALL: strlcpy(type_str, "...", sizeof(type_str)); break; #ifdef HAVE_OVERLAY diff --git a/settings.c b/settings.c index 85d7a0302d..248ebd4263 100644 --- a/settings.c +++ b/settings.c @@ -1119,11 +1119,15 @@ bool config_save_file(const char *path) config_set_int(conf, cfg, g_settings.input.libretro_device[i]); } + for (unsigned i = 0; i < MAX_PLAYERS; i++) + save_keybinds_player(conf, i); + bool ret = config_file_write(conf, path); config_file_free(conf); return ret; } +// FIXME: This is probably obsolete now. bool config_save_keybinds(const char *path) { config_file_t *conf = config_file_new(path); From 4f2de6d578f4d249741f1f004053c689f173f111 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sun, 29 Sep 2013 20:40:04 +0200 Subject: [PATCH 04/16] Add RGUI menu toggle config. --- frontend/menu/menu_common.h | 15 ++++++- frontend/menu/rgui.c | 78 ++++++++++++++++----------------- frontend/menu/rguidisp_bitmap.c | 18 +++++++- input/input_common.c | 71 ++++++++++++++++++++++++++++++ input/input_common.h | 1 + 5 files changed, 139 insertions(+), 44 deletions(-) diff --git a/frontend/menu/menu_common.h b/frontend/menu/menu_common.h index 70789f7df2..98418cec95 100644 --- a/frontend/menu/menu_common.h +++ b/frontend/menu/menu_common.h @@ -149,7 +149,8 @@ typedef enum RGUI_SETTINGS_BIND_DPAD_EMULATION, // Match up with libretro order for simplicity. - RGUI_SETTINGS_BIND_B, + RGUI_SETTINGS_BIND_BEGIN, + RGUI_SETTINGS_BIND_B = RGUI_SETTINGS_BIND_BEGIN, RGUI_SETTINGS_BIND_Y, RGUI_SETTINGS_BIND_SELECT, RGUI_SETTINGS_BIND_START, @@ -165,8 +166,19 @@ typedef enum RGUI_SETTINGS_BIND_R2, RGUI_SETTINGS_BIND_L3, RGUI_SETTINGS_BIND_R3, + RGUI_SETTINGS_BIND_ANALOG_LEFT_X_PLUS, + RGUI_SETTINGS_BIND_ANALOG_LEFT_X_MINUS, + RGUI_SETTINGS_BIND_ANALOG_LEFT_Y_PLUS, + RGUI_SETTINGS_BIND_ANALOG_LEFT_Y_MINUS, + RGUI_SETTINGS_BIND_ANALOG_RIGHT_X_PLUS, + RGUI_SETTINGS_BIND_ANALOG_RIGHT_X_MINUS, + RGUI_SETTINGS_BIND_ANALOG_RIGHT_Y_PLUS, + RGUI_SETTINGS_BIND_ANALOG_RIGHT_Y_MINUS, + RGUI_SETTINGS_BIND_LAST = RGUI_SETTINGS_BIND_ANALOG_RIGHT_Y_MINUS, + RGUI_SETTINGS_BIND_MENU_TOGGLE = RGUI_SETTINGS_BIND_BEGIN + RARCH_MENU_TOGGLE, RGUI_SETTINGS_CUSTOM_BIND, RGUI_SETTINGS_CUSTOM_BIND_ALL, + RGUI_SETTINGS_CUSTOM_BIND_DEFAULT_ALL, RGUI_SETTINGS_CORE_OPTION_NONE = 0xffff, RGUI_SETTINGS_CORE_OPTION_START = 0x10000 @@ -198,7 +210,6 @@ struct rgui_bind_state_port bool buttons[RGUI_MAX_BUTTONS]; int16_t axes[RGUI_MAX_AXES]; uint16_t hats[RGUI_MAX_HATS]; - }; struct rgui_bind_axis_state diff --git a/frontend/menu/rgui.c b/frontend/menu/rgui.c index 5a7b8fb4bf..ae89173194 100644 --- a/frontend/menu/rgui.c +++ b/frontend/menu/rgui.c @@ -33,6 +33,7 @@ #include "../../compat/posix_string.h" #include "../../gfx/shader_parse.h" #include "../../performance.h" +#include "../../input/input_common.h" #ifdef HAVE_OPENGL #include "../../gfx/gl_common.h" @@ -684,13 +685,26 @@ static int rgui_settings_toggle_setting(rgui_handle_t *rgui, unsigned setting, r if (action == RGUI_ACTION_OK) { rgui->binds.target = &g_settings.input.binds[port][0]; - rgui->binds.begin = RGUI_SETTINGS_BIND_B; - rgui->binds.last = RGUI_SETTINGS_BIND_R3; + rgui->binds.begin = RGUI_SETTINGS_BIND_BEGIN; + rgui->binds.last = RGUI_SETTINGS_BIND_LAST; rgui_list_push(rgui->menu_stack, "", RGUI_SETTINGS_CUSTOM_BIND, rgui->selection_ptr); menu_poll_bind_get_rested_axes(&rgui->binds); menu_poll_bind_state(&rgui->binds); } break; + case RGUI_SETTINGS_CUSTOM_BIND_DEFAULT_ALL: + if (action == RGUI_ACTION_OK) + { + struct retro_keybind *target = &g_settings.input.binds[port][0]; + rgui->binds.begin = RGUI_SETTINGS_BIND_BEGIN; + rgui->binds.last = RGUI_SETTINGS_BIND_LAST; + for (unsigned i = RGUI_SETTINGS_BIND_BEGIN; i < RGUI_SETTINGS_BIND_LAST; i++, target++) + { + target->joykey = NO_BTN; + target->joyaxis = AXIS_NONE; + } + } + break; case RGUI_SETTINGS_BIND_UP: case RGUI_SETTINGS_BIND_DOWN: case RGUI_SETTINGS_BIND_LEFT: @@ -707,6 +721,15 @@ static int rgui_settings_toggle_setting(rgui_handle_t *rgui, unsigned setting, r case RGUI_SETTINGS_BIND_R2: case RGUI_SETTINGS_BIND_L3: case RGUI_SETTINGS_BIND_R3: + case RGUI_SETTINGS_BIND_ANALOG_LEFT_X_PLUS: + case RGUI_SETTINGS_BIND_ANALOG_LEFT_X_MINUS: + case RGUI_SETTINGS_BIND_ANALOG_LEFT_Y_PLUS: + case RGUI_SETTINGS_BIND_ANALOG_LEFT_Y_MINUS: + case RGUI_SETTINGS_BIND_ANALOG_RIGHT_X_PLUS: + case RGUI_SETTINGS_BIND_ANALOG_RIGHT_X_MINUS: + case RGUI_SETTINGS_BIND_ANALOG_RIGHT_Y_PLUS: + case RGUI_SETTINGS_BIND_ANALOG_RIGHT_Y_MINUS: + case RGUI_SETTINGS_BIND_MENU_TOGGLE: if (driver.input->set_keybinds) { unsigned keybind_action = KEYBINDS_ACTION_NONE; @@ -721,11 +744,11 @@ static int rgui_settings_toggle_setting(rgui_handle_t *rgui, unsigned setting, r // FIXME: The array indices here look totally wrong ... Fixed it so it looks kind of sane for now. if (keybind_action != KEYBINDS_ACTION_NONE) driver.input->set_keybinds(driver.input_data, g_settings.input.device[port], port, - setting - RGUI_SETTINGS_BIND_B, keybind_action); + setting - RGUI_SETTINGS_BIND_BEGIN, keybind_action); } else { - struct retro_keybind *bind = &g_settings.input.binds[port][setting - RGUI_SETTINGS_BIND_B]; + struct retro_keybind *bind = &g_settings.input.binds[port][setting - RGUI_SETTINGS_BIND_BEGIN]; if (action == RGUI_ACTION_OK) { rgui->binds.begin = setting; @@ -1514,6 +1537,7 @@ static void rgui_settings_path_populate_entries(rgui_handle_t *rgui) #endif } +// TODO: Move to some extern. Maybe in input_common.c? static void rgui_settings_controller_populate_entries(rgui_handle_t *rgui) { rgui_list_clear(rgui->selection_buf); @@ -1529,24 +1553,15 @@ static void rgui_settings_controller_populate_entries(rgui_handle_t *rgui) if (driver.input && driver.input->set_keybinds) rgui_list_push(rgui->selection_buf, "DPad Emulation", RGUI_SETTINGS_BIND_DPAD_EMULATION, 0); else - rgui_list_push(rgui->selection_buf, "Configure All", RGUI_SETTINGS_CUSTOM_BIND_ALL, 0); // This doesn't make sense on anything else than PC. + { + rgui_list_push(rgui->selection_buf, "Configure All (RetroPad)", RGUI_SETTINGS_CUSTOM_BIND_ALL, 0); // This doesn't make sense on anything else than PC. + rgui_list_push(rgui->selection_buf, "Default All (RetroPad)", RGUI_SETTINGS_CUSTOM_BIND_DEFAULT_ALL, 0); // This doesn't make sense on anything else than PC. + } - rgui_list_push(rgui->selection_buf, "Up", RGUI_SETTINGS_BIND_UP, 0); - rgui_list_push(rgui->selection_buf, "Down", RGUI_SETTINGS_BIND_DOWN, 0); - rgui_list_push(rgui->selection_buf, "Left", RGUI_SETTINGS_BIND_LEFT, 0); - rgui_list_push(rgui->selection_buf, "Right", RGUI_SETTINGS_BIND_RIGHT, 0); - rgui_list_push(rgui->selection_buf, "A (right)", RGUI_SETTINGS_BIND_A, 0); - rgui_list_push(rgui->selection_buf, "B (down)", RGUI_SETTINGS_BIND_B, 0); - rgui_list_push(rgui->selection_buf, "X (top)", RGUI_SETTINGS_BIND_X, 0); - rgui_list_push(rgui->selection_buf, "Y (left)", RGUI_SETTINGS_BIND_Y, 0); - rgui_list_push(rgui->selection_buf, "Start", RGUI_SETTINGS_BIND_START, 0); - rgui_list_push(rgui->selection_buf, "Select", RGUI_SETTINGS_BIND_SELECT, 0); - rgui_list_push(rgui->selection_buf, "L", RGUI_SETTINGS_BIND_L, 0); - rgui_list_push(rgui->selection_buf, "R", RGUI_SETTINGS_BIND_R, 0); - rgui_list_push(rgui->selection_buf, "L2", RGUI_SETTINGS_BIND_L2, 0); - rgui_list_push(rgui->selection_buf, "R2", RGUI_SETTINGS_BIND_R2, 0); - rgui_list_push(rgui->selection_buf, "L3", RGUI_SETTINGS_BIND_L3, 0); - rgui_list_push(rgui->selection_buf, "R3", RGUI_SETTINGS_BIND_R3, 0); + rgui_list_push(rgui->selection_buf, "RGUI Menu Toggle", RGUI_SETTINGS_BIND_MENU_TOGGLE, 0); + unsigned last = (driver.input && driver.input->set_keybinds) ? RGUI_SETTINGS_BIND_R3 : RGUI_SETTINGS_BIND_LAST; + for (unsigned i = RGUI_SETTINGS_BIND_BEGIN; i <= last; i++) + rgui_list_push(rgui->selection_buf, input_bind_to_str[i - RGUI_SETTINGS_BIND_BEGIN], i, 0); } // This only makes sense for PC so far. @@ -1557,27 +1572,8 @@ static int rgui_custom_bind_iterate(rgui_handle_t *rgui, rgui_action_t action) render_text(rgui); - static const char *rgui_key_to_str[] = { - "B (down)", - "Y (left)", - "Select", - "Start", - "D-pad Up", - "D-pad Down", - "D-pad Left", - "D-pad Right", - "A (right)", - "X (top)", - "L (trigger)", - "R (trigger)", - "L2 (trigger)", - "R2 (trigger)", - "L3 (thumb)", - "R3 (thumb)", - }; - char msg[256]; - snprintf(msg, sizeof(msg), "[%s] press joypad (RETURN to skip)", rgui_key_to_str[rgui->binds.begin - RGUI_SETTINGS_BIND_B]); + snprintf(msg, sizeof(msg), "[%s] press joypad (RETURN to skip)", input_bind_to_str[rgui->binds.begin - RGUI_SETTINGS_BIND_BEGIN]); render_messagebox(rgui, msg); struct rgui_bind_state binds = rgui->binds; diff --git a/frontend/menu/rguidisp_bitmap.c b/frontend/menu/rguidisp_bitmap.c index 69560de319..cef420936c 100644 --- a/frontend/menu/rguidisp_bitmap.c +++ b/frontend/menu/rguidisp_bitmap.c @@ -304,7 +304,13 @@ static void render_text(rgui_handle_t *rgui) rgui_list_get_at_offset(rgui->selection_buf, i, &path, &type); char message[256]; char type_str[256]; - unsigned w = (menu_type == RGUI_SETTINGS_INPUT_OPTIONS || menu_type == RGUI_SETTINGS_PATH_OPTIONS || menu_type == RGUI_SETTINGS_CUSTOM_BIND) ? 24 : 19; + + unsigned w = 19; + if (menu_type == RGUI_SETTINGS_INPUT_OPTIONS || menu_type == RGUI_SETTINGS_CUSTOM_BIND) + w = 21; + else if (menu_type == RGUI_SETTINGS_PATH_OPTIONS) + w = 24; + unsigned port = rgui->current_pad; #ifdef HAVE_SHADER_MANAGER @@ -535,6 +541,7 @@ static void render_text(rgui_handle_t *rgui) case RGUI_SETTINGS_PATH_OPTIONS: case RGUI_SETTINGS_OPTIONS: case RGUI_SETTINGS_CUSTOM_BIND_ALL: + case RGUI_SETTINGS_CUSTOM_BIND_DEFAULT_ALL: strlcpy(type_str, "...", sizeof(type_str)); break; #ifdef HAVE_OVERLAY @@ -626,6 +633,15 @@ static void render_text(rgui_handle_t *rgui) case RGUI_SETTINGS_BIND_R2: case RGUI_SETTINGS_BIND_L3: case RGUI_SETTINGS_BIND_R3: + case RGUI_SETTINGS_BIND_ANALOG_LEFT_X_PLUS: + case RGUI_SETTINGS_BIND_ANALOG_LEFT_X_MINUS: + case RGUI_SETTINGS_BIND_ANALOG_LEFT_Y_PLUS: + case RGUI_SETTINGS_BIND_ANALOG_LEFT_Y_MINUS: + case RGUI_SETTINGS_BIND_ANALOG_RIGHT_X_PLUS: + case RGUI_SETTINGS_BIND_ANALOG_RIGHT_X_MINUS: + case RGUI_SETTINGS_BIND_ANALOG_RIGHT_Y_PLUS: + case RGUI_SETTINGS_BIND_ANALOG_RIGHT_Y_MINUS: + case RGUI_SETTINGS_BIND_MENU_TOGGLE: { unsigned id = type - RGUI_SETTINGS_BIND_B; struct platform_bind key_label; diff --git a/input/input_common.c b/input/input_common.c index c938b68128..3e6d21315d 100644 --- a/input/input_common.c +++ b/input/input_common.c @@ -794,6 +794,77 @@ const struct input_key_map input_config_key_map[] = { { NULL, RETROK_UNKNOWN }, }; +const char *input_bind_to_str[] = { + "B (down)", + "Y (left)", + "Select", + "Start", + "D-pad Up", + "D-pad Down", + "D-pad Left", + "D-pad Right", + "A (right)", + "X (top)", + "L (trigger)", + "R (trigger)", + "L2 (trigger)", + "R2 (trigger)", + "L3 (thumb)", + "R3 (thumb)", + "Left analog X+ (right)", + "Left analog X- (left)", + "Left analog Y+ (down)", + "Left analog Y- (up)", + "Right analog X+ (right)", + "Right analog X- (left)", + "Right analog Y+ (down)", + "Right analog Y- (up)", +#ifdef RARCH_CONSOLE + "Left analog X D-pad left", + "Left analog X D-pad right", + "Left analog Y D-pad up", + "Left analog Y D-pad down", + "Right analog X D-pad left", + "Right analog X D-pad right", + "Right analog Y D-pad up", + "Right analog Y D-pad down", +#endif + + "Turbo enable", + "Fast forward", + "Fast forward hold", + "Load state", + "Save state", + "Fullscreen toggle", + "Quit RetroArch", + "State slot (+)", + "State slot (-)", + "Rewind", + "Movie record toggle", + "Pause toggle", + "Frame advance", + "Reset game", + "Next shader", + "Previous shader", + "Cheat index (+)", + "Cheat index (-)", + "Cheat toggle", + "Take screenshot", + "DSP plugin config", + "Mute audio", + "Netplay flip players", + "Slow motion", + "Hotkey enable", + "Volume (+)", + "Volume (-)", + "Next overlay", + "Disk eject toggle", + "Disk next", + "Grab mouse toggle", + "RGUI menu toggle", +}; + + static enum retro_key find_sk_bind(const char *str) { for (size_t i = 0; input_config_key_map[i].str; i++) diff --git a/input/input_common.h b/input/input_common.h index 704ce42306..5f5e0c3458 100644 --- a/input/input_common.h +++ b/input/input_common.h @@ -133,6 +133,7 @@ struct input_bind_map unsigned retro_key; }; extern const struct input_bind_map input_config_bind_map[]; +extern const char *input_bind_to_str[]; struct input_key_map { From 3bdd3131a21ee41b2ff3b03c20f97fe74b018f7b Mon Sep 17 00:00:00 2001 From: Themaister Date: Sun, 29 Sep 2013 20:44:44 +0200 Subject: [PATCH 05/16] Only show RGUI menu toggle for player 1. All hotkeys are done in terms of player 1. --- frontend/menu/rgui.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frontend/menu/rgui.c b/frontend/menu/rgui.c index ae89173194..cc6bc4c7d1 100644 --- a/frontend/menu/rgui.c +++ b/frontend/menu/rgui.c @@ -539,6 +539,7 @@ static int rgui_settings_toggle_setting(rgui_handle_t *rgui, unsigned setting, r } port = rgui->current_pad; + rgui->need_refresh = true; break; case RGUI_SETTINGS_BIND_DEVICE: // If set_keybinds is supported, we do it more fancy, and scroll through @@ -1558,7 +1559,8 @@ static void rgui_settings_controller_populate_entries(rgui_handle_t *rgui) rgui_list_push(rgui->selection_buf, "Default All (RetroPad)", RGUI_SETTINGS_CUSTOM_BIND_DEFAULT_ALL, 0); // This doesn't make sense on anything else than PC. } - rgui_list_push(rgui->selection_buf, "RGUI Menu Toggle", RGUI_SETTINGS_BIND_MENU_TOGGLE, 0); + if (rgui->current_pad == 0) + rgui_list_push(rgui->selection_buf, "RGUI Menu Toggle", RGUI_SETTINGS_BIND_MENU_TOGGLE, 0); unsigned last = (driver.input && driver.input->set_keybinds) ? RGUI_SETTINGS_BIND_R3 : RGUI_SETTINGS_BIND_LAST; for (unsigned i = RGUI_SETTINGS_BIND_BEGIN; i <= last; i++) rgui_list_push(rgui->selection_buf, input_bind_to_str[i - RGUI_SETTINGS_BIND_BEGIN], i, 0); From 8cb77fa915e5c907c7a48120549bb0ae92b2a8b4 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sun, 29 Sep 2013 20:52:51 +0200 Subject: [PATCH 06/16] Add get_joypad_driver to more input drivers. --- input/dinput.c | 7 +++++++ input/linuxraw_input.c | 7 +++++++ input/sdl_input.c | 7 +++++++ 3 files changed, 21 insertions(+) diff --git a/input/dinput.c b/input/dinput.c index ac70e2d64d..e8f5674be2 100644 --- a/input/dinput.c +++ b/input/dinput.c @@ -340,6 +340,12 @@ static bool dinput_set_rumble(void *data, unsigned port, enum retro_rumble_effec return input_joypad_set_rumble(di->joypad, port, effect, strength); } +static const rarch_joypad_driver_t *dinput_get_joypad_driver(void *data) +{ + struct dinput_input *di = (struct dinput_input*)data; + return di->joypad; +} + const input_driver_t input_dinput = { dinput_init, dinput_poll, @@ -351,6 +357,7 @@ const input_driver_t input_dinput = { dinput_grab_mouse, dinput_set_rumble, + dinput_get_joypad_driver, }; // Keep track of which pad indexes are 360 controllers diff --git a/input/linuxraw_input.c b/input/linuxraw_input.c index 5467ccc68d..507f46e20d 100644 --- a/input/linuxraw_input.c +++ b/input/linuxraw_input.c @@ -291,6 +291,12 @@ static bool linuxraw_set_rumble(void *data, unsigned port, enum retro_rumble_eff return input_joypad_set_rumble(linuxraw->joypad, port, effect, strength); } +static const rarch_joypad_driver_t *linuxraw_get_joypad_driver(void *data) +{ + linuxraw_input_t *linuxraw = (linuxraw_input_t*)data; + return linuxraw->joypad; +} + static void linuxraw_input_poll(void *data) { linuxraw_input_t *linuxraw = (linuxraw_input_t*)data; @@ -325,4 +331,5 @@ const input_driver_t input_linuxraw = { "linuxraw", NULL, linuxraw_set_rumble, + linuxraw_get_joypad_driver, }; diff --git a/input/sdl_input.c b/input/sdl_input.c index 64e40b05aa..9b1262938d 100644 --- a/input/sdl_input.c +++ b/input/sdl_input.c @@ -220,6 +220,12 @@ static bool sdl_set_rumble(void *data, unsigned port, enum retro_rumble_effect e return input_joypad_set_rumble(sdl->joypad, port, effect, strength); } +static const rarch_joypad_driver_t *sdl_get_joypad_driver(void *data) +{ + sdl_input_t *sdl = (sdl_input_t*)data; + return sdl->joypad; +} + static void sdl_poll_mouse(sdl_input_t *sdl) { Uint8 btn = SDL_GetRelativeMouseState(&sdl->mouse_x, &sdl->mouse_y); @@ -248,5 +254,6 @@ const input_driver_t input_sdl = { "sdl", NULL, sdl_set_rumble, + sdl_get_joypad_driver, }; From d25313d0c1e9967fa9e2383961889a7ede075846 Mon Sep 17 00:00:00 2001 From: Themaister Date: Mon, 30 Sep 2013 17:39:44 +0200 Subject: [PATCH 07/16] Avoid new keybinds triggering stuff right away. Most relevant things here are RGUI toggle, back, start, etc. --- frontend/menu/rgui.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frontend/menu/rgui.c b/frontend/menu/rgui.c index cc6bc4c7d1..20b270a4cc 100644 --- a/frontend/menu/rgui.c +++ b/frontend/menu/rgui.c @@ -1588,6 +1588,10 @@ static int rgui_custom_bind_iterate(rgui_handle_t *rgui, rgui_action_t action) binds.target++; else rgui_list_pop(rgui->menu_stack, &rgui->selection_ptr); + + // Avoid new binds triggering things right away. + rgui->trigger_state = 0; + rgui->old_input_state = -1ULL; } rgui->binds = binds; return 0; From 02cd05550ee5f77c3fa9fc4581beff3221164ef1 Mon Sep 17 00:00:00 2001 From: Themaister Date: Mon, 30 Sep 2013 18:08:47 +0200 Subject: [PATCH 08/16] Reuse input_config_bind_map. --- frontend/menu/menu_settings.c | 2 +- frontend/menu/rgui.c | 4 +- frontend/menu/rguidisp_bitmap.c | 40 +--------- input/input_common.c | 129 +++++++++++++------------------- input/input_common.h | 5 +- 5 files changed, 63 insertions(+), 117 deletions(-) diff --git a/frontend/menu/menu_settings.c b/frontend/menu/menu_settings.c index a1800b398a..ba68426813 100644 --- a/frontend/menu/menu_settings.c +++ b/frontend/menu/menu_settings.c @@ -503,7 +503,7 @@ int menu_set_settings(unsigned setting, unsigned action) struct retro_keybind *target = &g_settings.input.binds[port][0]; rgui->binds.begin = RGUI_SETTINGS_BIND_BEGIN; rgui->binds.last = RGUI_SETTINGS_BIND_LAST; - for (unsigned i = RGUI_SETTINGS_BIND_BEGIN; i < RGUI_SETTINGS_BIND_LAST; i++, target++) + for (unsigned i = RGUI_SETTINGS_BIND_BEGIN; i <= RGUI_SETTINGS_BIND_LAST; i++, target++) { target->joykey = NO_BTN; target->joyaxis = AXIS_NONE; diff --git a/frontend/menu/rgui.c b/frontend/menu/rgui.c index a284d1df77..e2c8e594b9 100644 --- a/frontend/menu/rgui.c +++ b/frontend/menu/rgui.c @@ -540,7 +540,7 @@ static void rgui_settings_controller_populate_entries(rgui_handle_t *rgui) rgui_list_push(rgui->selection_buf, "RGUI Menu Toggle", RGUI_SETTINGS_BIND_MENU_TOGGLE, 0); unsigned last = (driver.input && driver.input->set_keybinds) ? RGUI_SETTINGS_BIND_R3 : RGUI_SETTINGS_BIND_LAST; for (unsigned i = RGUI_SETTINGS_BIND_BEGIN; i <= last; i++) - rgui_list_push(rgui->selection_buf, input_bind_to_str[i - RGUI_SETTINGS_BIND_BEGIN], i, 0); + rgui_list_push(rgui->selection_buf, input_config_bind_map[i - RGUI_SETTINGS_BIND_BEGIN].desc, i, 0); } // This only makes sense for PC so far. @@ -552,7 +552,7 @@ static int rgui_custom_bind_iterate(rgui_handle_t *rgui, rgui_action_t action) render_text(rgui); char msg[256]; - snprintf(msg, sizeof(msg), "[%s] press joypad (RETURN to skip)", input_bind_to_str[rgui->binds.begin - RGUI_SETTINGS_BIND_BEGIN]); + snprintf(msg, sizeof(msg), "[%s] press joypad (RETURN to skip)", input_config_bind_map[rgui->binds.begin - RGUI_SETTINGS_BIND_BEGIN].desc); render_messagebox(rgui, msg); struct rgui_bind_state binds = rgui->binds; diff --git a/frontend/menu/rguidisp_bitmap.c b/frontend/menu/rguidisp_bitmap.c index cef420936c..2dfbc2c887 100644 --- a/frontend/menu/rguidisp_bitmap.c +++ b/frontend/menu/rguidisp_bitmap.c @@ -655,43 +655,8 @@ static void render_text(rgui_handle_t *rgui) } else { - const struct retro_keybind *bind = &g_settings.input.binds[port][type - RGUI_SETTINGS_BIND_B]; - if (bind->joykey != NO_BTN) - { - if (GET_HAT_DIR(bind->joykey)) - { - const char *dir; - switch (GET_HAT_DIR(bind->joykey)) - { - case HAT_UP_MASK: dir = "up"; break; - case HAT_DOWN_MASK: dir = "down"; break; - case HAT_LEFT_MASK: dir = "left"; break; - case HAT_RIGHT_MASK: dir = "right"; break; - default: dir = "?"; break; - } - snprintf(type_str, sizeof(type_str), "Hat #%u %s", (unsigned)GET_HAT(bind->joykey), dir); - } - else - snprintf(type_str, sizeof(type_str), "%u (btn)", (unsigned)bind->joykey); - } - else if (bind->joyaxis != AXIS_NONE) - { - unsigned axis = 0; - char dir = '\0'; - if (AXIS_NEG_GET(bind->joyaxis) != AXIS_DIR_NONE) - { - dir = '-'; - axis = AXIS_NEG_GET(bind->joyaxis); - } - else if (AXIS_POS_GET(bind->joyaxis) != AXIS_DIR_NONE) - { - dir = '+'; - axis = AXIS_POS_GET(bind->joyaxis); - } - snprintf(type_str, sizeof(type_str), "%c%u (axis)", dir, axis); - } - else - strlcpy(type_str, "", sizeof(type_str)); + const struct retro_keybind *bind = &g_settings.input.binds[port][type - RGUI_SETTINGS_BIND_BEGIN]; + input_get_bind_string(type_str, bind, sizeof(type_str)); } break; } @@ -738,3 +703,4 @@ static void render_text(rgui_handle_t *rgui) render_messagebox(rgui, message_queue); #endif } + diff --git a/input/input_common.c b/input/input_common.c index 3e6d21315d..c8684a7656 100644 --- a/input/input_common.c +++ b/input/input_common.c @@ -642,6 +642,14 @@ enum retro_key input_translate_keysym_to_rk(unsigned sym) return RETROK_UNKNOWN; } +const char *input_translate_rk_to_str(enum retro_key key) +{ + for (unsigned i = 0; input_config_key_map[i].str; i++) + if (input_config_key_map[i].key == key) + return input_config_key_map[i].str; + return NULL; +} + unsigned input_translate_rk_to_keysym(enum retro_key key) { return rarch_keysym_lut[key]; @@ -672,12 +680,12 @@ const struct input_bind_map input_config_bind_map[RARCH_BIND_LIST_END_NULL] = { DECLARE_BIND(right, RETRO_DEVICE_ID_JOYPAD_RIGHT, "Right D-pad"), DECLARE_BIND(a, RETRO_DEVICE_ID_JOYPAD_A, "A button (right)"), DECLARE_BIND(x, RETRO_DEVICE_ID_JOYPAD_X, "X button (top)"), - DECLARE_BIND(l, RETRO_DEVICE_ID_JOYPAD_L, "L button (left shoulder)"), - DECLARE_BIND(r, RETRO_DEVICE_ID_JOYPAD_R, "R button (right shoulder)"), - DECLARE_BIND(l2, RETRO_DEVICE_ID_JOYPAD_L2, "L2 button (left shoulder #2)"), - DECLARE_BIND(r2, RETRO_DEVICE_ID_JOYPAD_R2, "R2 button (right shoulder #2)"), - DECLARE_BIND(l3, RETRO_DEVICE_ID_JOYPAD_L3, "L3 button (left analog button)"), - DECLARE_BIND(r3, RETRO_DEVICE_ID_JOYPAD_R3, "R3 button (right analog button)"), + DECLARE_BIND(l, RETRO_DEVICE_ID_JOYPAD_L, "L button (shoulder)"), + DECLARE_BIND(r, RETRO_DEVICE_ID_JOYPAD_R, "R button (shoulder)"), + DECLARE_BIND(l2, RETRO_DEVICE_ID_JOYPAD_L2, "L2 button (trigger)"), + DECLARE_BIND(r2, RETRO_DEVICE_ID_JOYPAD_R2, "R2 button (trigger)"), + DECLARE_BIND(l3, RETRO_DEVICE_ID_JOYPAD_L3, "L3 button (thumb)"), + DECLARE_BIND(r3, RETRO_DEVICE_ID_JOYPAD_R3, "R3 button (thumb)"), DECLARE_BIND(turbo, RARCH_TURBO_ENABLE, "Turbo enable"), DECLARE_BIND(l_x_plus, RARCH_ANALOG_LEFT_X_PLUS, "Left analog X+ (right)"), DECLARE_BIND(l_x_minus, RARCH_ANALOG_LEFT_X_MINUS, "Left analog X- (left)"), @@ -794,76 +802,45 @@ const struct input_key_map input_config_key_map[] = { { NULL, RETROK_UNKNOWN }, }; -const char *input_bind_to_str[] = { - "B (down)", - "Y (left)", - "Select", - "Start", - "D-pad Up", - "D-pad Down", - "D-pad Left", - "D-pad Right", - "A (right)", - "X (top)", - "L (trigger)", - "R (trigger)", - "L2 (trigger)", - "R2 (trigger)", - "L3 (thumb)", - "R3 (thumb)", - "Left analog X+ (right)", - "Left analog X- (left)", - "Left analog Y+ (down)", - "Left analog Y- (up)", - "Right analog X+ (right)", - "Right analog X- (left)", - "Right analog Y+ (down)", - "Right analog Y- (up)", -#ifdef RARCH_CONSOLE - "Left analog X D-pad left", - "Left analog X D-pad right", - "Left analog Y D-pad up", - "Left analog Y D-pad down", - "Right analog X D-pad left", - "Right analog X D-pad right", - "Right analog Y D-pad up", - "Right analog Y D-pad down", -#endif - - "Turbo enable", - "Fast forward", - "Fast forward hold", - "Load state", - "Save state", - "Fullscreen toggle", - "Quit RetroArch", - "State slot (+)", - "State slot (-)", - "Rewind", - "Movie record toggle", - "Pause toggle", - "Frame advance", - "Reset game", - "Next shader", - "Previous shader", - "Cheat index (+)", - "Cheat index (-)", - "Cheat toggle", - "Take screenshot", - "DSP plugin config", - "Mute audio", - "Netplay flip players", - "Slow motion", - "Hotkey enable", - "Volume (+)", - "Volume (-)", - "Next overlay", - "Disk eject toggle", - "Disk next", - "Grab mouse toggle", - "RGUI menu toggle", -}; - +void input_get_bind_string(char *buf, const struct retro_keybind *bind, size_t size) +{ + if (bind->joykey != NO_BTN) + { + if (GET_HAT_DIR(bind->joykey)) + { + const char *dir; + switch (GET_HAT_DIR(bind->joykey)) + { + case HAT_UP_MASK: dir = "up"; break; + case HAT_DOWN_MASK: dir = "down"; break; + case HAT_LEFT_MASK: dir = "left"; break; + case HAT_RIGHT_MASK: dir = "right"; break; + default: dir = "?"; break; + } + snprintf(buf, size, "Hat #%u %s", (unsigned)GET_HAT(bind->joykey), dir); + } + else + snprintf(buf, size, "%u (btn)", (unsigned)bind->joykey); + } + else if (bind->joyaxis != AXIS_NONE) + { + unsigned axis = 0; + char dir = '\0'; + if (AXIS_NEG_GET(bind->joyaxis) != AXIS_DIR_NONE) + { + dir = '-'; + axis = AXIS_NEG_GET(bind->joyaxis); + } + else if (AXIS_POS_GET(bind->joyaxis) != AXIS_DIR_NONE) + { + dir = '+'; + axis = AXIS_POS_GET(bind->joyaxis); + } + snprintf(buf, size, "%c%u (axis)", dir, axis); + } + else + strlcpy(buf, "", size); +} static enum retro_key find_sk_bind(const char *str) { diff --git a/input/input_common.h b/input/input_common.h index 5f5e0c3458..1117e4a2dd 100644 --- a/input/input_common.h +++ b/input/input_common.h @@ -132,8 +132,10 @@ struct input_bind_map const char *desc; unsigned retro_key; }; + extern const struct input_bind_map input_config_bind_map[]; -extern const char *input_bind_to_str[]; + +void input_get_bind_string(char *buf, const struct retro_keybind *bind, size_t size); struct input_key_map { @@ -141,6 +143,7 @@ struct input_key_map enum retro_key key; }; extern const struct input_key_map input_config_key_map[]; +const char *input_translate_rk_to_str(enum retro_key key); extern const char* const input_builtin_autoconfs[]; From 7229142e5702206cc0871b4f643a157049df88ae Mon Sep 17 00:00:00 2001 From: Themaister Date: Mon, 30 Sep 2013 18:27:35 +0200 Subject: [PATCH 09/16] Display current keybind in RGUI. --- input/input_common.c | 43 +++++++++++++++++++++++++++++++++---------- input/input_common.h | 2 +- settings.c | 19 ++----------------- 3 files changed, 36 insertions(+), 28 deletions(-) diff --git a/input/input_common.c b/input/input_common.c index c8684a7656..b404b65f32 100644 --- a/input/input_common.c +++ b/input/input_common.c @@ -642,12 +642,27 @@ enum retro_key input_translate_keysym_to_rk(unsigned sym) return RETROK_UNKNOWN; } -const char *input_translate_rk_to_str(enum retro_key key) +void input_translate_rk_to_str(enum retro_key key, char *buf, size_t size) { - for (unsigned i = 0; input_config_key_map[i].str; i++) - if (input_config_key_map[i].key == key) - return input_config_key_map[i].str; - return NULL; + rarch_assert(size >= 2); + *buf = '\0'; + + if (key >= RETROK_a && key <= RETROK_z) + { + buf[0] = (key - RETROK_a) + 'a'; + buf[1] = '\0'; + } + else + { + for (unsigned i = 0; input_config_key_map[i].str; i++) + { + if (input_config_key_map[i].key == key) + { + strlcpy(buf, input_config_key_map[i].str, size); + break; + } + } + } } unsigned input_translate_rk_to_keysym(enum retro_key key) @@ -804,6 +819,7 @@ const struct input_key_map input_config_key_map[] = { void input_get_bind_string(char *buf, const struct retro_keybind *bind, size_t size) { + *buf = '\0'; if (bind->joykey != NO_BTN) { if (GET_HAT_DIR(bind->joykey)) @@ -817,10 +833,10 @@ void input_get_bind_string(char *buf, const struct retro_keybind *bind, size_t s case HAT_RIGHT_MASK: dir = "right"; break; default: dir = "?"; break; } - snprintf(buf, size, "Hat #%u %s", (unsigned)GET_HAT(bind->joykey), dir); + snprintf(buf, size, "Hat #%u %s ", (unsigned)GET_HAT(bind->joykey), dir); } else - snprintf(buf, size, "%u (btn)", (unsigned)bind->joykey); + snprintf(buf, size, "%u (btn) ", (unsigned)bind->joykey); } else if (bind->joyaxis != AXIS_NONE) { @@ -836,10 +852,17 @@ void input_get_bind_string(char *buf, const struct retro_keybind *bind, size_t s dir = '+'; axis = AXIS_POS_GET(bind->joyaxis); } - snprintf(buf, size, "%c%u (axis)", dir, axis); + snprintf(buf, size, "%c%u (axis) ", dir, axis); } - else - strlcpy(buf, "", size); + + char key[64]; + input_translate_rk_to_str(bind->key, key, sizeof(key)); + if (!strcmp(key, "nul")) + *key = '\0'; + + char keybuf[64]; + snprintf(keybuf, sizeof(keybuf), "(Key: %s)", key); + strlcat(buf, keybuf, size); } static enum retro_key find_sk_bind(const char *str) diff --git a/input/input_common.h b/input/input_common.h index 1117e4a2dd..9f2afd2a17 100644 --- a/input/input_common.h +++ b/input/input_common.h @@ -143,7 +143,7 @@ struct input_key_map enum retro_key key; }; extern const struct input_key_map input_config_key_map[]; -const char *input_translate_rk_to_str(enum retro_key key); +void input_translate_rk_to_str(enum retro_key key, char *buf, size_t size); extern const char* const input_builtin_autoconfs[]; diff --git a/settings.c b/settings.c index 1935d9276e..b4af25ab4c 100644 --- a/settings.c +++ b/settings.c @@ -879,23 +879,8 @@ static void save_keybind_key(config_file_t *conf, const char *prefix, const char char key[64]; snprintf(key, sizeof(key), "%s_%s", prefix, base); - char ascii[2] = {0}; - const char *btn = ascii; - - if (bind->key >= RETROK_a && bind->key <= RETROK_z) - ascii[0] = 'a' + (bind->key - RETROK_a); - else - { - for (unsigned i = 0; input_config_key_map[i].str; i++) - { - if (input_config_key_map[i].key == bind->key) - { - btn = input_config_key_map[i].str; - break; - } - } - } - + char btn[64]; + input_translate_rk_to_str(bind->key, btn, sizeof(btn)); config_set_string(conf, key, btn); } From a3a8b762c32c1ec43be851e44818fcab89968e7f Mon Sep 17 00:00:00 2001 From: Themaister Date: Mon, 30 Sep 2013 18:42:44 +0200 Subject: [PATCH 10/16] Allow multi-line messages in RGUI. --- frontend/menu/rgui.c | 2 +- frontend/menu/rguidisp_bitmap.c | 46 ++++++++++++++++++++++++++------- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/frontend/menu/rgui.c b/frontend/menu/rgui.c index e2c8e594b9..2bda1cdef7 100644 --- a/frontend/menu/rgui.c +++ b/frontend/menu/rgui.c @@ -552,7 +552,7 @@ static int rgui_custom_bind_iterate(rgui_handle_t *rgui, rgui_action_t action) render_text(rgui); char msg[256]; - snprintf(msg, sizeof(msg), "[%s] press joypad (RETURN to skip)", input_config_bind_map[rgui->binds.begin - RGUI_SETTINGS_BIND_BEGIN].desc); + snprintf(msg, sizeof(msg), "[%s]\npress joypad\n(RETURN to skip)", input_config_bind_map[rgui->binds.begin - RGUI_SETTINGS_BIND_BEGIN].desc); render_messagebox(rgui, msg); struct rgui_bind_state binds = rgui->binds; diff --git a/frontend/menu/rguidisp_bitmap.c b/frontend/menu/rguidisp_bitmap.c index 2dfbc2c887..1a26173a96 100644 --- a/frontend/menu/rguidisp_bitmap.c +++ b/frontend/menu/rguidisp_bitmap.c @@ -145,17 +145,36 @@ static void render_messagebox(rgui_handle_t *rgui, const char *message) if (!message || !*message) return; - char *msg = strdup(message); - if (strlen(msg) > TERM_WIDTH) + struct string_list *list = string_split(message, "\n"); + if (!list) + return; + if (list->elems == 0) { - msg[TERM_WIDTH - 2] = '.'; - msg[TERM_WIDTH - 1] = '.'; - msg[TERM_WIDTH - 0] = '.'; - msg[TERM_WIDTH + 1] = '\0'; + string_list_free(list); + return; } - unsigned width = strlen(msg) * FONT_WIDTH_STRIDE - 1 + 6 + 10; - unsigned height = FONT_HEIGHT + 6 + 10; + unsigned width = 0; + unsigned glyphs_width = 0; + for (size_t i = 0; i < list->size; i++) + { + char *msg = list->elems[i].data; + unsigned msglen = strlen(msg); + if (msglen > TERM_WIDTH) + { + msg[TERM_WIDTH - 2] = '.'; + msg[TERM_WIDTH - 1] = '.'; + msg[TERM_WIDTH - 0] = '.'; + msg[TERM_WIDTH + 1] = '\0'; + msglen = TERM_WIDTH; + } + + unsigned line_width = msglen * FONT_WIDTH_STRIDE - 1 + 6 + 10; + width = max(width, line_width); + glyphs_width = max(glyphs_width, msglen); + } + + unsigned height = FONT_HEIGHT_STRIDE * list->size + 6 + 10; int x = (RGUI_WIDTH - width) / 2; int y = (RGUI_HEIGHT - height) / 2; @@ -174,8 +193,15 @@ static void render_messagebox(rgui_handle_t *rgui, const char *message) fill_rect(rgui->frame_buf, rgui->frame_buf_pitch, x, y + 5, 5, height - 5, green_filler); - blit_line(rgui, x + 8, y + 8, msg, false); - free(msg); + for (size_t i = 0; i < list->size; i++) + { + const char *msg = list->elems[i].data; + int offset_x = FONT_WIDTH_STRIDE * (glyphs_width - strlen(msg)) / 2; + int offset_y = FONT_HEIGHT_STRIDE * i; + blit_line(rgui, x + 8 + offset_x, y + 8 + offset_y, msg, false); + } + + string_list_free(list); } static void render_text(rgui_handle_t *rgui) From 6fe01e3fcfc9b32df1abd0c7a3ac5d795c65e73a Mon Sep 17 00:00:00 2001 From: Themaister Date: Mon, 30 Sep 2013 18:45:04 +0200 Subject: [PATCH 11/16] Remove an arbitrary hardcoded pad. Input config RGUI should avoid having to rely too much on autoconfigs. Keep Xinput pad autoconfig however, as its convenience is worth quite a lot. --- input/autoconf/builtin_win.c | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/input/autoconf/builtin_win.c b/input/autoconf/builtin_win.c index d28e9de1df..ba1a4e0da5 100644 --- a/input/autoconf/builtin_win.c +++ b/input/autoconf/builtin_win.c @@ -61,32 +61,6 @@ const char* const input_builtin_autoconfs[] = "input_driver = \"winxinput\" \n" XINPUT_DEFAULT_BINDS, - "input_device = \"Dual Trigger 3-in-1\" \n" - "input_driver = \"dinput\" \n" - DECL_BTN(a, 2) - DECL_BTN(b, 1) - DECL_BTN(x, 3) - DECL_BTN(y, 0) - DECL_BTN(start, 9) - DECL_BTN(select, 8) - DECL_BTN(up, h0up) - DECL_BTN(down, h0down) - DECL_BTN(left, h0left) - DECL_BTN(right, h0right) - DECL_BTN(l, 4) - DECL_BTN(r, 5) - DECL_BTN(l2, 6) - DECL_BTN(r2, 7) - DECL_BTN(l3, 10) - DECL_BTN(r3, 11) - DECL_AXIS(l_x_plus, +0) - DECL_AXIS(l_x_minus, -0) - DECL_AXIS(l_y_plus, +1) - DECL_AXIS(l_y_minus, -1) - DECL_AXIS(r_x_plus, +2) - DECL_AXIS(r_x_minus, -2) - DECL_AXIS(r_y_plus, +5) - DECL_AXIS(r_y_minus, -5), - NULL }; + From b3c1afe2ec2195cc6f23818c86d9f15787b2af8f Mon Sep 17 00:00:00 2001 From: Themaister Date: Mon, 30 Sep 2013 18:53:56 +0200 Subject: [PATCH 12/16] Redirect keyboard events to RGUI. Fixes issue where libretro cores receive keyboard events even though they are not running (inside RGUI). --- frontend/frontend.c | 8 ++++++++ frontend/menu/menu_common.c | 9 +++++++++ frontend/menu/menu_common.h | 2 ++ 3 files changed, 19 insertions(+) diff --git a/frontend/frontend.c b/frontend/frontend.c index c65796a18c..df559d44ac 100644 --- a/frontend/frontend.c +++ b/frontend/frontend.c @@ -215,6 +215,11 @@ int main_entry(int argc, char *argv[]) driver_set_rumble_state(i, RETRO_RUMBLE_WEAK, 0); } + // Override keyboard callback to redirect to menu instead. + // We'll use this later for something ... + retro_keyboard_event_t key_event = g_extern.system.key_event; + g_extern.system.key_event = menu_key_event; + if (driver.audio_data) audio_stop_func(); @@ -236,6 +241,9 @@ int main_entry(int argc, char *argv[]) } g_extern.lifecycle_mode_state &= ~(1ULL << MODE_MENU); + + // Restore libretro keyboard callback. + g_extern.system.key_event = key_event; } else break; diff --git a/frontend/menu/menu_common.c b/frontend/menu/menu_common.c index 5d3c10ad94..c5dfd931c8 100644 --- a/frontend/menu/menu_common.c +++ b/frontend/menu/menu_common.c @@ -911,3 +911,12 @@ bool menu_poll_find_trigger(struct rgui_bind_state *state, struct rgui_bind_stat return false; } +void menu_key_event(bool down, unsigned keycode, uint32_t character, uint16_t key_modifiers) +{ + // TODO: Do something with this. Stub for now. + (void)down; + (void)keycode; + (void)character; + (void)key_modifiers; +} + diff --git a/frontend/menu/menu_common.h b/frontend/menu/menu_common.h index 0036a92840..bafc3065be 100644 --- a/frontend/menu/menu_common.h +++ b/frontend/menu/menu_common.h @@ -355,6 +355,8 @@ bool menu_save_new_config(void); int menu_set_settings(unsigned setting, unsigned action); extern const unsigned rgui_controller_lut[]; +void menu_key_event(bool down, unsigned keycode, uint32_t character, uint16_t key_modifiers); + #ifdef __cplusplus } #endif From 36de3825811a4c3a10a269e01cfec97e3402d79f Mon Sep 17 00:00:00 2001 From: Themaister Date: Mon, 30 Sep 2013 18:56:19 +0200 Subject: [PATCH 13/16] Remove obsolete rgui_controller_lut. --- frontend/menu/menu_common.h | 1 - frontend/menu/menu_settings.c | 19 ------------------- 2 files changed, 20 deletions(-) diff --git a/frontend/menu/menu_common.h b/frontend/menu/menu_common.h index bafc3065be..9c2bbd47b2 100644 --- a/frontend/menu/menu_common.h +++ b/frontend/menu/menu_common.h @@ -353,7 +353,6 @@ bool menu_replace_config(const char *path); bool menu_save_new_config(void); int menu_set_settings(unsigned setting, unsigned action); -extern const unsigned rgui_controller_lut[]; void menu_key_event(bool down, unsigned keycode, uint32_t character, uint16_t key_modifiers); diff --git a/frontend/menu/menu_settings.c b/frontend/menu/menu_settings.c index ba68426813..4ba5c26e0e 100644 --- a/frontend/menu/menu_settings.c +++ b/frontend/menu/menu_settings.c @@ -26,25 +26,6 @@ #define MAX_GAMMA_SETTING 1 #endif -const unsigned rgui_controller_lut[] = { - RETRO_DEVICE_ID_JOYPAD_UP, - RETRO_DEVICE_ID_JOYPAD_DOWN, - RETRO_DEVICE_ID_JOYPAD_LEFT, - RETRO_DEVICE_ID_JOYPAD_RIGHT, - RETRO_DEVICE_ID_JOYPAD_A, - RETRO_DEVICE_ID_JOYPAD_B, - RETRO_DEVICE_ID_JOYPAD_X, - RETRO_DEVICE_ID_JOYPAD_Y, - RETRO_DEVICE_ID_JOYPAD_START, - RETRO_DEVICE_ID_JOYPAD_SELECT, - RETRO_DEVICE_ID_JOYPAD_L, - RETRO_DEVICE_ID_JOYPAD_R, - RETRO_DEVICE_ID_JOYPAD_L2, - RETRO_DEVICE_ID_JOYPAD_R2, - RETRO_DEVICE_ID_JOYPAD_L3, - RETRO_DEVICE_ID_JOYPAD_R3, -}; - #ifdef HAVE_SHADER_MANAGER static enum rarch_shader_type shader_manager_get_type(const struct gfx_shader *shader) { From 39bf64412ccd00764b2536c69d2172f7206c27b1 Mon Sep 17 00:00:00 2001 From: Themaister Date: Mon, 30 Sep 2013 18:57:34 +0200 Subject: [PATCH 14/16] Add a FIXME. --- frontend/frontend.c | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/frontend.c b/frontend/frontend.c index df559d44ac..799a0eca6b 100644 --- a/frontend/frontend.c +++ b/frontend/frontend.c @@ -217,6 +217,7 @@ int main_entry(int argc, char *argv[]) // Override keyboard callback to redirect to menu instead. // We'll use this later for something ... + // FIXME: This should probably be moved to menu_common somehow. retro_keyboard_event_t key_event = g_extern.system.key_event; g_extern.system.key_event = menu_key_event; From 21e5a08135e4dad000f0097c7ae7959412220bd5 Mon Sep 17 00:00:00 2001 From: Themaister Date: Mon, 30 Sep 2013 19:10:07 +0200 Subject: [PATCH 15/16] Drop strange comment. --- frontend/menu/rgui.c | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/menu/rgui.c b/frontend/menu/rgui.c index 2bda1cdef7..fe62fea1a5 100644 --- a/frontend/menu/rgui.c +++ b/frontend/menu/rgui.c @@ -515,7 +515,6 @@ static void rgui_settings_path_populate_entries(rgui_handle_t *rgui) #endif } -// TODO: Move to some extern. Maybe in input_common.c? static void rgui_settings_controller_populate_entries(rgui_handle_t *rgui) { rgui_list_clear(rgui->selection_buf); From 2bd065e35995f6fab483e77334c292e1ab1e6f16 Mon Sep 17 00:00:00 2001 From: Themaister Date: Mon, 30 Sep 2013 19:40:41 +0200 Subject: [PATCH 16/16] Move TURBO key below analogs. Avoid having it show up in menu. --- config.def.h | 4 ++-- driver.h | 9 +++++---- input/input_common.c | 15 ++++++++++++++- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/config.def.h b/config.def.h index 70a91ebea1..54eb968b6a 100644 --- a/config.def.h +++ b/config.def.h @@ -565,7 +565,6 @@ static const struct retro_keybind retro_keybinds_1[] = { { true, RETRO_DEVICE_ID_JOYPAD_L3, RETRO_LBL_JOYPAD_L3, RETROK_UNKNOWN, RETRO_DEF_JOYPAD_L3, 0, AXIS_NONE }, { true, RETRO_DEVICE_ID_JOYPAD_R3, RETRO_LBL_JOYPAD_R3, RETROK_UNKNOWN, RETRO_DEF_JOYPAD_R3, 0, AXIS_NONE }, - { true, RARCH_TURBO_ENABLE, RETRO_LBL_TURBO_ENABLE, RETROK_UNKNOWN, NO_BTN, 0, AXIS_NONE }, { true, RARCH_ANALOG_LEFT_X_PLUS, RETRO_LBL_ANALOG_LEFT_X_PLUS, RETROK_UNKNOWN, NO_BTN, 0, AXIS_NONE }, { true, RARCH_ANALOG_LEFT_X_MINUS, RETRO_LBL_ANALOG_LEFT_X_MINUS, RETROK_UNKNOWN, NO_BTN, 0, AXIS_NONE }, { true, RARCH_ANALOG_LEFT_Y_PLUS, RETRO_LBL_ANALOG_LEFT_Y_PLUS, RETROK_UNKNOWN, NO_BTN, 0, AXIS_NONE }, @@ -585,6 +584,7 @@ static const struct retro_keybind retro_keybinds_1[] = { { true, RARCH_ANALOG_RIGHT_Y_DPAD_DOWN, RETRO_LBL_ANALOG_RIGHT_Y_DPAD_D,RETROK_UNKNOWN, RETRO_DEF_ANALOGR_DPAD_DOWN, 0, AXIS_NONE }, #endif + { true, RARCH_TURBO_ENABLE, RETRO_LBL_TURBO_ENABLE, RETROK_UNKNOWN, NO_BTN, 0, AXIS_NONE }, { true, RARCH_FAST_FORWARD_KEY, RETRO_LBL_FAST_FORWARD_KEY, RETROK_SPACE, NO_BTN, 0, AXIS_NONE }, { true, RARCH_FAST_FORWARD_HOLD_KEY, RETRO_LBL_FAST_FORWARD_HOLD_KEY,RETROK_l, NO_BTN, 0, AXIS_NONE }, { true, RARCH_LOAD_STATE_KEY, RETRO_LBL_LOAD_STATE_KEY, RETROK_F4, NO_BTN, 0, AXIS_NONE }, @@ -640,7 +640,6 @@ static const struct retro_keybind retro_keybinds_rest[] = { { true, RETRO_DEVICE_ID_JOYPAD_L3, RETRO_LBL_JOYPAD_L3, RETROK_UNKNOWN, NO_BTN, 0, AXIS_NONE }, { true, RETRO_DEVICE_ID_JOYPAD_R3, RETRO_LBL_JOYPAD_R3, RETROK_UNKNOWN, NO_BTN, 0, AXIS_NONE }, - { true, RARCH_TURBO_ENABLE, RETRO_LBL_TURBO_ENABLE, RETROK_UNKNOWN, NO_BTN, 0, AXIS_NONE }, { true, RARCH_ANALOG_LEFT_X_PLUS, RETRO_LBL_ANALOG_LEFT_X_PLUS, RETROK_UNKNOWN, NO_BTN, 0, AXIS_NONE }, { true, RARCH_ANALOG_LEFT_X_MINUS, RETRO_LBL_ANALOG_LEFT_X_MINUS, RETROK_UNKNOWN, NO_BTN, 0, AXIS_NONE }, { true, RARCH_ANALOG_LEFT_Y_PLUS, RETRO_LBL_ANALOG_LEFT_Y_PLUS, RETROK_UNKNOWN, NO_BTN, 0, AXIS_NONE }, @@ -659,6 +658,7 @@ static const struct retro_keybind retro_keybinds_rest[] = { { true, RARCH_ANALOG_RIGHT_Y_DPAD_UP, RETRO_LBL_ANALOG_RIGHT_Y_DPAD_U,RETROK_UNKNOWN, NO_BTN, 0, AXIS_NONE }, { true, RARCH_ANALOG_RIGHT_Y_DPAD_DOWN, RETRO_LBL_ANALOG_RIGHT_Y_DPAD_D,RETROK_UNKNOWN, NO_BTN, 0, AXIS_NONE }, #endif + { true, RARCH_TURBO_ENABLE, RETRO_LBL_TURBO_ENABLE, RETROK_UNKNOWN, NO_BTN, 0, AXIS_NONE }, }; #endif diff --git a/driver.h b/driver.h index 4430ce7b65..f025fb3bc7 100644 --- a/driver.h +++ b/driver.h @@ -56,11 +56,8 @@ extern "C" { enum // RetroArch specific bind IDs. { // Custom binds that extend the scope of RETRO_DEVICE_JOYPAD for RetroArch specifically. - // Turbo - RARCH_TURBO_ENABLE = RARCH_FIRST_CUSTOM_BIND, - // Analogs (RETRO_DEVICE_ANALOG) - RARCH_ANALOG_LEFT_X_PLUS, + RARCH_ANALOG_LEFT_X_PLUS = RARCH_FIRST_CUSTOM_BIND, RARCH_ANALOG_LEFT_X_MINUS, RARCH_ANALOG_LEFT_Y_PLUS, RARCH_ANALOG_LEFT_Y_MINUS, @@ -69,6 +66,7 @@ enum // RetroArch specific bind IDs. RARCH_ANALOG_RIGHT_Y_PLUS, RARCH_ANALOG_RIGHT_Y_MINUS, #ifdef RARCH_CONSOLE + // D-pad emulation RARCH_ANALOG_LEFT_X_DPAD_LEFT, RARCH_ANALOG_LEFT_X_DPAD_RIGHT, RARCH_ANALOG_LEFT_Y_DPAD_UP, @@ -79,6 +77,9 @@ enum // RetroArch specific bind IDs. RARCH_ANALOG_RIGHT_Y_DPAD_DOWN, #endif + // Turbo + RARCH_TURBO_ENABLE, + RARCH_CUSTOM_BIND_LIST_END, // Command binds. Not related to game input, only usable for port 0. diff --git a/input/input_common.c b/input/input_common.c index b404b65f32..f0c7e2ae1e 100644 --- a/input/input_common.c +++ b/input/input_common.c @@ -701,7 +701,6 @@ const struct input_bind_map input_config_bind_map[RARCH_BIND_LIST_END_NULL] = { DECLARE_BIND(r2, RETRO_DEVICE_ID_JOYPAD_R2, "R2 button (trigger)"), DECLARE_BIND(l3, RETRO_DEVICE_ID_JOYPAD_L3, "L3 button (thumb)"), DECLARE_BIND(r3, RETRO_DEVICE_ID_JOYPAD_R3, "R3 button (thumb)"), - DECLARE_BIND(turbo, RARCH_TURBO_ENABLE, "Turbo enable"), DECLARE_BIND(l_x_plus, RARCH_ANALOG_LEFT_X_PLUS, "Left analog X+ (right)"), DECLARE_BIND(l_x_minus, RARCH_ANALOG_LEFT_X_MINUS, "Left analog X- (left)"), DECLARE_BIND(l_y_plus, RARCH_ANALOG_LEFT_Y_PLUS, "Left analog Y+ (down)"), @@ -711,6 +710,20 @@ const struct input_bind_map input_config_bind_map[RARCH_BIND_LIST_END_NULL] = { DECLARE_BIND(r_y_plus, RARCH_ANALOG_RIGHT_Y_PLUS, "Right analog Y+ (down)"), DECLARE_BIND(r_y_minus, RARCH_ANALOG_RIGHT_Y_MINUS, "Right analog Y- (up)"), + // FIXME: Unsure what to do here. + // The D-pad emulation concept really needs a rethink ... +#ifdef RARCH_CONSOLE + DECLARE_BIND(dpad_l_x_l, RARCH_ANALOG_LEFT_X_DPAD_LEFT, "Left analog D-pad left"), + DECLARE_BIND(dpad_l_x_r, RARCH_ANALOG_LEFT_X_DPAD_RIGHT, "Left analog D-pad right"), + DECLARE_BIND(dpad_l_y_u, RARCH_ANALOG_LEFT_Y_DPAD_UP, "Left analog D-pad up"), + DECLARE_BIND(dpad_l_y_d, RARCH_ANALOG_LEFT_Y_DPAD_DOWN, "Left analog D-pad down"), + DECLARE_BIND(dpad_r_x_l, RARCH_ANALOG_RIGHT_X_DPAD_LEFT, "Right analog D-pad left"), + DECLARE_BIND(dpad_r_x_r, RARCH_ANALOG_RIGHT_X_DPAD_RIGHT, "Right analog D-pad right"), + DECLARE_BIND(dpad_r_y_u, RARCH_ANALOG_RIGHT_Y_DPAD_UP, "Right analog D-pad up"), + DECLARE_BIND(dpad_r_y_d, RARCH_ANALOG_RIGHT_Y_DPAD_DOWN, "Right analog D-pad down"), +#endif + DECLARE_BIND(turbo, RARCH_TURBO_ENABLE, "Turbo enable"), + DECLARE_META_BIND(1, toggle_fast_forward, RARCH_FAST_FORWARD_KEY, "Fast forward toggle"), DECLARE_META_BIND(2, hold_fast_forward, RARCH_FAST_FORWARD_HOLD_KEY, "Fast forward hold"), DECLARE_META_BIND(1, load_state, RARCH_LOAD_STATE_KEY, "Load state"),