mirror of
https://github.com/libretro/RetroArch
synced 2025-03-25 16:44:01 +00:00
Implement basic keyboard binding in RGUI.
This commit is contained in:
parent
4f27faf035
commit
255e43966a
@ -295,7 +295,9 @@ static void rgui_render(void *data)
|
||||
snprintf(title, sizeof(title), "DISK APPEND %s", dir);
|
||||
else if (menu_type == RGUI_SETTINGS_VIDEO_OPTIONS)
|
||||
strlcpy(title, "VIDEO OPTIONS", sizeof(title));
|
||||
else if (menu_type == RGUI_SETTINGS_INPUT_OPTIONS)
|
||||
else if (menu_type == RGUI_SETTINGS_INPUT_OPTIONS ||
|
||||
menu_type == RGUI_SETTINGS_CUSTOM_BIND ||
|
||||
menu_type == RGUI_SETTINGS_CUSTOM_BIND_KEYBOARD)
|
||||
strlcpy(title, "INPUT OPTIONS", sizeof(title));
|
||||
else if (menu_type == RGUI_SETTINGS_OVERLAY_OPTIONS)
|
||||
strlcpy(title, "OVERLAY OPTIONS", sizeof(title));
|
||||
@ -329,11 +331,10 @@ static void rgui_render(void *data)
|
||||
else if (menu_type_is(menu_type) == RGUI_SETTINGS_SHADER_OPTIONS)
|
||||
snprintf(title, sizeof(title), "SHADER %s", dir);
|
||||
#endif
|
||||
else if ((menu_type == RGUI_SETTINGS_INPUT_OPTIONS) ||
|
||||
(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 ||
|
||||
else if (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_START_SCREEN ||
|
||||
menu_type == RGUI_SETTINGS)
|
||||
snprintf(title, sizeof(title), "MENU %s", dir);
|
||||
@ -417,7 +418,7 @@ static void rgui_render(void *data)
|
||||
char type_str[256];
|
||||
|
||||
unsigned w = 19;
|
||||
if (menu_type == RGUI_SETTINGS_INPUT_OPTIONS || menu_type == RGUI_SETTINGS_CUSTOM_BIND)
|
||||
if (menu_type == RGUI_SETTINGS_INPUT_OPTIONS || menu_type == RGUI_SETTINGS_CUSTOM_BIND || menu_type == RGUI_SETTINGS_CUSTOM_BIND_KEYBOARD)
|
||||
w = 21;
|
||||
else if (menu_type == RGUI_SETTINGS_PATH_OPTIONS)
|
||||
w = 24;
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "../../file.h"
|
||||
#include "../../file_ext.h"
|
||||
#include "../../input/input_common.h"
|
||||
#include "../../input/keyboard_line.h"
|
||||
|
||||
#include "../../compat/posix_string.h"
|
||||
|
||||
@ -594,6 +595,55 @@ static int menu_custom_bind_iterate(void *data, unsigned action)
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool menu_custom_bind_keyboard_cb(void *data, unsigned code)
|
||||
{
|
||||
rgui_handle_t *rgui = (rgui_handle_t*)data;
|
||||
rgui->binds.target->key = code;
|
||||
rgui->binds.begin++;
|
||||
rgui->binds.target++;
|
||||
rgui->binds.timeout_end = rarch_get_time_usec() + RGUI_KEYBOARD_BIND_TIMEOUT_SECONDS * 1000000;
|
||||
return rgui->binds.begin <= rgui->binds.last;
|
||||
}
|
||||
|
||||
static int menu_custom_bind_iterate_keyboard(void *data, unsigned action)
|
||||
{
|
||||
rgui_handle_t *rgui = (rgui_handle_t*)data;
|
||||
(void)action; // Have to ignore action here.
|
||||
|
||||
if (driver.video_data && driver.menu_ctx && driver.menu_ctx->render)
|
||||
driver.menu_ctx->render(rgui);
|
||||
|
||||
int64_t current = rarch_get_time_usec();
|
||||
int timeout = (rgui->binds.timeout_end - current) / 1000000;
|
||||
|
||||
char msg[256];
|
||||
snprintf(msg, sizeof(msg), "[%s]\npress keyboard\n(timeout %d seconds)",
|
||||
input_config_bind_map[rgui->binds.begin - RGUI_SETTINGS_BIND_BEGIN].desc, timeout);
|
||||
|
||||
if (driver.video_data && driver.menu_ctx && driver.menu_ctx->render_messagebox)
|
||||
driver.menu_ctx->render_messagebox(rgui, msg);
|
||||
|
||||
if (timeout <= 0)
|
||||
{
|
||||
rgui->binds.begin++;
|
||||
rgui->binds.target->key = RETROK_UNKNOWN; // Could be unsafe, but whatever.
|
||||
rgui->binds.target++;
|
||||
rgui->binds.timeout_end = rarch_get_time_usec() + RGUI_KEYBOARD_BIND_TIMEOUT_SECONDS * 1000000;
|
||||
}
|
||||
|
||||
// binds.begin is updated in keyboard_press callback.
|
||||
if (rgui->binds.begin > rgui->binds.last)
|
||||
{
|
||||
file_list_pop(rgui->menu_stack, &rgui->selection_ptr);
|
||||
|
||||
// Avoid new binds triggering things right away.
|
||||
rgui->trigger_state = 0;
|
||||
rgui->old_input_state = -1ULL;
|
||||
input_keyboard_wait_keys_cancel();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int menu_start_screen_iterate(void *data, unsigned action)
|
||||
{
|
||||
unsigned i;
|
||||
@ -1054,6 +1104,8 @@ static int menu_iterate_func(void *data, unsigned action)
|
||||
return menu_viewport_iterate(rgui, action);
|
||||
else if (menu_type == RGUI_SETTINGS_CUSTOM_BIND)
|
||||
return menu_custom_bind_iterate(rgui, action);
|
||||
else if (menu_type == RGUI_SETTINGS_CUSTOM_BIND_KEYBOARD)
|
||||
return menu_custom_bind_iterate_keyboard(rgui, action);
|
||||
|
||||
if (rgui->need_refresh && action != RGUI_ACTION_MESSAGE)
|
||||
action = RGUI_ACTION_NOOP;
|
||||
|
@ -249,6 +249,7 @@ typedef enum
|
||||
RGUI_SETTINGS_BIND_GRAB_MOUSE_TOGGLE,
|
||||
RGUI_SETTINGS_BIND_MENU_TOGGLE,
|
||||
RGUI_SETTINGS_CUSTOM_BIND,
|
||||
RGUI_SETTINGS_CUSTOM_BIND_KEYBOARD,
|
||||
RGUI_SETTINGS_CUSTOM_BIND_ALL,
|
||||
RGUI_SETTINGS_CUSTOM_BIND_DEFAULT_ALL,
|
||||
RGUI_SETTINGS_ONSCREEN_KEYBOARD_ENABLE,
|
||||
@ -294,9 +295,11 @@ struct rgui_bind_axis_state
|
||||
int16_t locked_axes[RGUI_MAX_AXES];
|
||||
};
|
||||
|
||||
#define RGUI_KEYBOARD_BIND_TIMEOUT_SECONDS 3
|
||||
struct rgui_bind_state
|
||||
{
|
||||
struct retro_keybind *target;
|
||||
int64_t timeout_end; // For keyboard binding.
|
||||
unsigned begin;
|
||||
unsigned last;
|
||||
unsigned player;
|
||||
@ -308,6 +311,7 @@ struct rgui_bind_state
|
||||
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, struct rgui_bind_state *new_state);
|
||||
bool menu_custom_bind_keyboard_cb(void *data, unsigned code);
|
||||
|
||||
#ifdef GEKKO
|
||||
enum
|
||||
|
@ -1001,6 +1001,15 @@ int menu_set_settings(void *data, unsigned setting, unsigned action)
|
||||
menu_poll_bind_get_rested_axes(&rgui->binds);
|
||||
menu_poll_bind_state(&rgui->binds);
|
||||
}
|
||||
else if (action == RGUI_ACTION_RIGHT) // Hack
|
||||
{
|
||||
rgui->binds.target = &g_settings.input.binds[port][0];
|
||||
rgui->binds.begin = RGUI_SETTINGS_BIND_BEGIN;
|
||||
rgui->binds.last = RGUI_SETTINGS_BIND_LAST;
|
||||
file_list_push(rgui->menu_stack, "", RGUI_SETTINGS_CUSTOM_BIND_KEYBOARD, rgui->selection_ptr);
|
||||
rgui->binds.timeout_end = rarch_get_time_usec() + RGUI_KEYBOARD_BIND_TIMEOUT_SECONDS * 1000000;
|
||||
input_keyboard_wait_keys(rgui, menu_custom_bind_keyboard_cb);
|
||||
}
|
||||
break;
|
||||
case RGUI_SETTINGS_CUSTOM_BIND_DEFAULT_ALL:
|
||||
if (action == RGUI_ACTION_OK)
|
||||
@ -1087,16 +1096,27 @@ int menu_set_settings(void *data, unsigned setting, unsigned action)
|
||||
else
|
||||
{
|
||||
struct retro_keybind *bind = &g_settings.input.binds[port][setting - RGUI_SETTINGS_BIND_BEGIN];
|
||||
if (action == RGUI_ACTION_OK)
|
||||
// FIXME: Hack, use RIGHT action to signal keyboard bind. Need something more sane.
|
||||
if (action == RGUI_ACTION_OK || action == RGUI_ACTION_RIGHT)
|
||||
{
|
||||
rgui->binds.begin = setting;
|
||||
rgui->binds.last = setting;
|
||||
rgui->binds.target = bind;
|
||||
rgui->binds.player = port;
|
||||
file_list_push(rgui->menu_stack, "", RGUI_SETTINGS_CUSTOM_BIND, rgui->selection_ptr);
|
||||
file_list_push(rgui->menu_stack, "",
|
||||
action == RGUI_ACTION_OK ? RGUI_SETTINGS_CUSTOM_BIND : RGUI_SETTINGS_CUSTOM_BIND_KEYBOARD, rgui->selection_ptr);
|
||||
|
||||
if (action == RGUI_ACTION_OK)
|
||||
{
|
||||
menu_poll_bind_get_rested_axes(&rgui->binds);
|
||||
menu_poll_bind_state(&rgui->binds);
|
||||
}
|
||||
else
|
||||
{
|
||||
rgui->binds.timeout_end = rarch_get_time_usec() + RGUI_KEYBOARD_BIND_TIMEOUT_SECONDS * 1000000;
|
||||
input_keyboard_wait_keys(rgui, menu_custom_bind_keyboard_cb);
|
||||
}
|
||||
}
|
||||
else if (action == RGUI_ACTION_START)
|
||||
{
|
||||
bind->joykey = NO_BTN;
|
||||
|
@ -98,6 +98,9 @@ const char **input_keyboard_line_get_buffer(const input_keyboard_line_t *state)
|
||||
|
||||
static input_keyboard_line_t *g_keyboard_line;
|
||||
|
||||
static input_keyboard_press_t g_keyboard_press_cb;
|
||||
static void *g_keyboard_press_data;
|
||||
|
||||
const char **input_keyboard_start_line(void *userdata, input_keyboard_line_complete_t cb)
|
||||
{
|
||||
if (g_keyboard_line)
|
||||
@ -110,9 +113,29 @@ const char **input_keyboard_start_line(void *userdata, input_keyboard_line_compl
|
||||
return input_keyboard_line_get_buffer(g_keyboard_line);
|
||||
}
|
||||
|
||||
void input_keyboard_wait_keys(void *userdata, input_keyboard_press_t cb)
|
||||
{
|
||||
g_keyboard_press_cb = cb;
|
||||
g_keyboard_press_data = userdata;
|
||||
// While waiting for input, we have to block all hotkeys.
|
||||
driver.block_input = true;
|
||||
}
|
||||
|
||||
void input_keyboard_wait_keys_cancel(void)
|
||||
{
|
||||
g_keyboard_press_cb = NULL;
|
||||
g_keyboard_press_data = NULL;
|
||||
driver.block_input = false;
|
||||
}
|
||||
|
||||
void input_keyboard_event(bool down, unsigned code, uint32_t character, uint16_t mod)
|
||||
{
|
||||
if (g_keyboard_line)
|
||||
if (g_keyboard_press_cb)
|
||||
{
|
||||
if (down && code != RETROK_UNKNOWN && !g_keyboard_press_cb(g_keyboard_press_data, code))
|
||||
input_keyboard_wait_keys_cancel();
|
||||
}
|
||||
else if (g_keyboard_line)
|
||||
{
|
||||
if (input_keyboard_line_event(g_keyboard_line, character))
|
||||
{
|
||||
|
@ -31,6 +31,8 @@ typedef struct input_keyboard_line input_keyboard_line_t;
|
||||
// line can be NULL.
|
||||
typedef void (*input_keyboard_line_complete_t)(void *userdata, const char *line);
|
||||
|
||||
typedef bool (*input_keyboard_press_t)(void *userdata, unsigned code);
|
||||
|
||||
input_keyboard_line_t *input_keyboard_line_new(void *userdata,
|
||||
input_keyboard_line_complete_t cb);
|
||||
|
||||
@ -46,6 +48,11 @@ void input_keyboard_line_free(input_keyboard_line_t *state);
|
||||
void input_keyboard_event(bool down, unsigned code, uint32_t character, uint16_t mod);
|
||||
const char **input_keyboard_start_line(void *userdata, input_keyboard_line_complete_t cb);
|
||||
|
||||
// Wait for keys to be pressed (used for binding keys in RGUI).
|
||||
// Callback returns false when all polling is done.
|
||||
void input_keyboard_wait_keys(void *userdata, input_keyboard_press_t cb);
|
||||
void input_keyboard_wait_keys_cancel(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user