Implement basic keyboard binding in RGUI.

This commit is contained in:
Themaister 2014-04-13 12:12:12 +02:00
parent 4f27faf035
commit 255e43966a
7 changed files with 149 additions and 42 deletions

View File

@ -2,7 +2,7 @@
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2014 - Daniel De Matteis * Copyright (C) 2011-2014 - Daniel De Matteis
* Copyright (C) 2012-2014 - Michael Lelli * Copyright (C) 2012-2014 - Michael Lelli
* *
* RetroArch is free software: you can redistribute it and/or modify it under the terms * RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found- * of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version. * ation, either version 3 of the License, or (at your option) any later version.
@ -230,7 +230,7 @@ static void rgui_render_messagebox(void *data, const char *message)
unsigned height = FONT_HEIGHT_STRIDE * list->size + 6 + 10; unsigned height = FONT_HEIGHT_STRIDE * list->size + 6 + 10;
int x = (rgui->width - width) / 2; int x = (rgui->width - width) / 2;
int y = (rgui->height - height) / 2; int y = (rgui->height - height) / 2;
fill_rect(rgui->frame_buf, rgui->frame_buf_pitch, fill_rect(rgui->frame_buf, rgui->frame_buf_pitch,
x + 5, y + 5, width - 10, height - 10, gray_filler); x + 5, y + 5, width - 10, height - 10, gray_filler);
@ -261,7 +261,7 @@ static void rgui_render(void *data)
{ {
rgui_handle_t *rgui = (rgui_handle_t*)data; rgui_handle_t *rgui = (rgui_handle_t*)data;
if (rgui->need_refresh && if (rgui->need_refresh &&
(g_extern.lifecycle_state & (1ULL << MODE_MENU)) (g_extern.lifecycle_state & (1ULL << MODE_MENU))
&& !rgui->msg_force) && !rgui->msg_force)
return; return;
@ -270,7 +270,7 @@ static void rgui_render(void *data)
rgui->selection_ptr - RGUI_TERM_HEIGHT / 2 : 0; rgui->selection_ptr - RGUI_TERM_HEIGHT / 2 : 0;
size_t end = rgui->selection_ptr + RGUI_TERM_HEIGHT <= rgui->selection_buf->size ? size_t end = rgui->selection_ptr + RGUI_TERM_HEIGHT <= rgui->selection_buf->size ?
rgui->selection_ptr + RGUI_TERM_HEIGHT : rgui->selection_buf->size; rgui->selection_ptr + RGUI_TERM_HEIGHT : rgui->selection_buf->size;
// Do not scroll if all items are visible. // Do not scroll if all items are visible.
if (rgui->selection_buf->size <= RGUI_TERM_HEIGHT) if (rgui->selection_buf->size <= RGUI_TERM_HEIGHT)
begin = 0; begin = 0;
@ -295,7 +295,9 @@ static void rgui_render(void *data)
snprintf(title, sizeof(title), "DISK APPEND %s", dir); snprintf(title, sizeof(title), "DISK APPEND %s", dir);
else if (menu_type == RGUI_SETTINGS_VIDEO_OPTIONS) else if (menu_type == RGUI_SETTINGS_VIDEO_OPTIONS)
strlcpy(title, "VIDEO OPTIONS", sizeof(title)); 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)); strlcpy(title, "INPUT OPTIONS", sizeof(title));
else if (menu_type == RGUI_SETTINGS_OVERLAY_OPTIONS) else if (menu_type == RGUI_SETTINGS_OVERLAY_OPTIONS)
strlcpy(title, "OVERLAY OPTIONS", sizeof(title)); strlcpy(title, "OVERLAY OPTIONS", sizeof(title));
@ -322,18 +324,17 @@ static void rgui_render(void *data)
else if (menu_type == RGUI_SETTINGS_CORE_OPTIONS) else if (menu_type == RGUI_SETTINGS_CORE_OPTIONS)
strlcpy(title, "CORE OPTIONS", sizeof(title)); strlcpy(title, "CORE OPTIONS", sizeof(title));
else if (menu_type == RGUI_SETTINGS_CORE_INFO) else if (menu_type == RGUI_SETTINGS_CORE_INFO)
strlcpy(title, "CORE INFO", sizeof(title)); strlcpy(title, "CORE INFO", sizeof(title));
else if (menu_type == RGUI_SETTINGS_PRIVACY_OPTIONS) else if (menu_type == RGUI_SETTINGS_PRIVACY_OPTIONS)
strlcpy(title, "PRIVACY OPTIONS", sizeof(title)); strlcpy(title, "PRIVACY OPTIONS", sizeof(title));
#ifdef HAVE_SHADER_MANAGER #ifdef HAVE_SHADER_MANAGER
else if (menu_type_is(menu_type) == RGUI_SETTINGS_SHADER_OPTIONS) else if (menu_type_is(menu_type) == RGUI_SETTINGS_SHADER_OPTIONS)
snprintf(title, sizeof(title), "SHADER %s", dir); snprintf(title, sizeof(title), "SHADER %s", dir);
#endif #endif
else if ((menu_type == RGUI_SETTINGS_INPUT_OPTIONS) || else if (menu_type == RGUI_SETTINGS_PATH_OPTIONS ||
(menu_type == RGUI_SETTINGS_PATH_OPTIONS) || menu_type == RGUI_SETTINGS_OPTIONS ||
(menu_type == RGUI_SETTINGS_OPTIONS) || menu_type == RGUI_SETTINGS_CUSTOM_VIEWPORT ||
(menu_type == RGUI_SETTINGS_CUSTOM_VIEWPORT || menu_type == RGUI_SETTINGS_CUSTOM_VIEWPORT_2) || menu_type == RGUI_SETTINGS_CUSTOM_VIEWPORT_2 ||
menu_type == RGUI_SETTINGS_CUSTOM_BIND ||
menu_type == RGUI_START_SCREEN || menu_type == RGUI_START_SCREEN ||
menu_type == RGUI_SETTINGS) menu_type == RGUI_SETTINGS)
snprintf(title, sizeof(title), "MENU %s", dir); snprintf(title, sizeof(title), "MENU %s", dir);
@ -417,7 +418,7 @@ static void rgui_render(void *data)
char type_str[256]; char type_str[256];
unsigned w = 19; 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; w = 21;
else if (menu_type == RGUI_SETTINGS_PATH_OPTIONS) else if (menu_type == RGUI_SETTINGS_PATH_OPTIONS)
w = 24; w = 24;

View File

@ -1,7 +1,7 @@
/* RetroArch - A frontend for libretro. /* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2014 - Daniel De Matteis * Copyright (C) 2011-2014 - Daniel De Matteis
* *
* RetroArch is free software: you can redistribute it and/or modify it under the terms * RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found- * of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version. * ation, either version 3 of the License, or (at your option) any later version.
@ -29,6 +29,7 @@
#include "../../file.h" #include "../../file.h"
#include "../../file_ext.h" #include "../../file_ext.h"
#include "../../input/input_common.h" #include "../../input/input_common.h"
#include "../../input/keyboard_line.h"
#include "../../compat/posix_string.h" #include "../../compat/posix_string.h"
@ -594,6 +595,55 @@ static int menu_custom_bind_iterate(void *data, unsigned action)
return 0; 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) static int menu_start_screen_iterate(void *data, unsigned action)
{ {
unsigned i; unsigned i;
@ -808,7 +858,7 @@ static int menu_viewport_iterate(void *data, unsigned action)
base_msg, base_msg,
custom->width, custom->height, custom->width, custom->height,
custom->width / geom->base_width, custom->width / geom->base_width,
custom->height / geom->base_height); custom->height / geom->base_height);
} }
else else
{ {
@ -818,7 +868,7 @@ static int menu_viewport_iterate(void *data, unsigned action)
base_msg = "Set Bottom-Right Corner"; base_msg = "Set Bottom-Right Corner";
snprintf(msg, sizeof(msg), "%s (%d, %d : %4ux%4u)", snprintf(msg, sizeof(msg), "%s (%d, %d : %4ux%4u)",
base_msg, custom->x, custom->y, custom->width, custom->height); base_msg, custom->x, custom->y, custom->width, custom->height);
} }
if (driver.video_data && driver.menu_ctx && driver.menu_ctx->render_messagebox) if (driver.video_data && driver.menu_ctx && driver.menu_ctx->render_messagebox)
@ -970,8 +1020,8 @@ static int menu_settings_iterate(void *data, unsigned action)
|| menu_type == RGUI_SETTINGS_AUDIO_OPTIONS || menu_type == RGUI_SETTINGS_AUDIO_OPTIONS
|| menu_type == RGUI_SETTINGS_DISK_OPTIONS || menu_type == RGUI_SETTINGS_DISK_OPTIONS
|| menu_type == RGUI_SETTINGS_PRIVACY_OPTIONS || menu_type == RGUI_SETTINGS_PRIVACY_OPTIONS
|| menu_type == RGUI_SETTINGS_GENERAL_OPTIONS || menu_type == RGUI_SETTINGS_GENERAL_OPTIONS
|| menu_type == RGUI_SETTINGS_VIDEO_OPTIONS || menu_type == RGUI_SETTINGS_VIDEO_OPTIONS
|| menu_type == RGUI_SETTINGS_FONT_OPTIONS || menu_type == RGUI_SETTINGS_FONT_OPTIONS
|| menu_type == RGUI_SETTINGS_SHADER_OPTIONS || menu_type == RGUI_SETTINGS_SHADER_OPTIONS
) )
@ -1054,6 +1104,8 @@ static int menu_iterate_func(void *data, unsigned action)
return menu_viewport_iterate(rgui, action); return menu_viewport_iterate(rgui, action);
else if (menu_type == RGUI_SETTINGS_CUSTOM_BIND) else if (menu_type == RGUI_SETTINGS_CUSTOM_BIND)
return menu_custom_bind_iterate(rgui, action); 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) if (rgui->need_refresh && action != RGUI_ACTION_MESSAGE)
action = RGUI_ACTION_NOOP; action = RGUI_ACTION_NOOP;
@ -1097,7 +1149,7 @@ static int menu_iterate_func(void *data, unsigned action)
case RGUI_ACTION_SCROLL_DOWN: case RGUI_ACTION_SCROLL_DOWN:
menu_ascend_alphabet(rgui, &rgui->selection_ptr); menu_ascend_alphabet(rgui, &rgui->selection_ptr);
break; break;
case RGUI_ACTION_CANCEL: case RGUI_ACTION_CANCEL:
if (rgui->menu_stack->size > 1) if (rgui->menu_stack->size > 1)
{ {
@ -1367,7 +1419,7 @@ static int menu_iterate_func(void *data, unsigned action)
if (rgui->need_refresh && (menu_type == RGUI_FILE_DIRECTORY || if (rgui->need_refresh && (menu_type == RGUI_FILE_DIRECTORY ||
menu_type_is(menu_type) == RGUI_SETTINGS_SHADER_OPTIONS || menu_type_is(menu_type) == RGUI_SETTINGS_SHADER_OPTIONS ||
menu_type_is(menu_type) == RGUI_FILE_DIRECTORY || menu_type_is(menu_type) == RGUI_FILE_DIRECTORY ||
menu_type == RGUI_SETTINGS_OVERLAY_PRESET || menu_type == RGUI_SETTINGS_OVERLAY_PRESET ||
menu_type == RGUI_SETTINGS_DEFERRED_CORE || menu_type == RGUI_SETTINGS_DEFERRED_CORE ||
menu_type == RGUI_SETTINGS_CORE || menu_type == RGUI_SETTINGS_CORE ||
@ -1396,7 +1448,7 @@ bool menu_iterate(void)
static bool first_held = false; static bool first_held = false;
uint64_t input_state = 0; uint64_t input_state = 0;
int32_t input_entry_ret, ret; int32_t input_entry_ret, ret;
input_entry_ret = 0; input_entry_ret = 0;
ret = 0; ret = 0;
@ -1700,7 +1752,7 @@ static bool menu_poll_find_trigger_pad(struct rgui_bind_state *state, struct rgu
state->target->joykey = NO_BTN; state->target->joykey = NO_BTN;
// Lock the current axis. // Lock the current axis.
new_state->axis_state[p].locked_axes[a] = n->axes[a] > 0 ? 0x7fff : -0x7fff; new_state->axis_state[p].locked_axes[a] = n->axes[a] > 0 ? 0x7fff : -0x7fff;
return true; return true;
} }
@ -1751,7 +1803,7 @@ static inline int menu_list_get_first_char(file_list_t *buf, unsigned offset)
const char *path = NULL; const char *path = NULL;
file_list_get_alt_at_offset(buf, offset, &path); file_list_get_alt_at_offset(buf, offset, &path);
int ret = tolower(*path); int ret = tolower(*path);
// "Normalize" non-alphabetical entries so they are lumped together for purposes of jumping. // "Normalize" non-alphabetical entries so they are lumped together for purposes of jumping.
if (ret < 'a') if (ret < 'a')
ret = 'a' - 1; ret = 'a' - 1;
@ -1925,7 +1977,7 @@ void menu_populate_entries(void *data, unsigned menu_type)
} }
else else
file_list_push(rgui->selection_buf, "No options available.", RGUI_SETTINGS_CORE_OPTION_NONE, 0); file_list_push(rgui->selection_buf, "No options available.", RGUI_SETTINGS_CORE_OPTION_NONE, 0);
break; break;
case RGUI_SETTINGS_CORE_INFO: case RGUI_SETTINGS_CORE_INFO:
file_list_clear(rgui->selection_buf); file_list_clear(rgui->selection_buf);
if (rgui->core_info_current.data) if (rgui->core_info_current.data)
@ -1964,7 +2016,7 @@ void menu_populate_entries(void *data, unsigned menu_type)
for (i = 0; i < rgui->core_info_current.firmware_count; i++) for (i = 0; i < rgui->core_info_current.firmware_count; i++)
{ {
if (rgui->core_info_current.firmware[i].desc) if (rgui->core_info_current.firmware[i].desc)
{ {
snprintf(tmp, sizeof(tmp), " name: %s", snprintf(tmp, sizeof(tmp), " name: %s",
rgui->core_info_current.firmware[i].desc ? rgui->core_info_current.firmware[i].desc : ""); rgui->core_info_current.firmware[i].desc ? rgui->core_info_current.firmware[i].desc : "");
file_list_push(rgui->selection_buf, tmp, RGUI_SETTINGS_CORE_INFO_NONE, 0); file_list_push(rgui->selection_buf, tmp, RGUI_SETTINGS_CORE_INFO_NONE, 0);
@ -1991,7 +2043,7 @@ void menu_populate_entries(void *data, unsigned menu_type)
} }
else else
file_list_push(rgui->selection_buf, "No information available.", RGUI_SETTINGS_CORE_OPTION_NONE, 0); file_list_push(rgui->selection_buf, "No information available.", RGUI_SETTINGS_CORE_OPTION_NONE, 0);
break; break;
case RGUI_SETTINGS_OPTIONS: case RGUI_SETTINGS_OPTIONS:
file_list_clear(rgui->selection_buf); file_list_clear(rgui->selection_buf);
file_list_push(rgui->selection_buf, "General Options", RGUI_SETTINGS_GENERAL_OPTIONS, 0); file_list_push(rgui->selection_buf, "General Options", RGUI_SETTINGS_GENERAL_OPTIONS, 0);
@ -2136,7 +2188,7 @@ void menu_populate_entries(void *data, unsigned menu_type)
} }
file_list_push(rgui->selection_buf, "Core Options", RGUI_SETTINGS_CORE_OPTIONS, 0); file_list_push(rgui->selection_buf, "Core Options", RGUI_SETTINGS_CORE_OPTIONS, 0);
file_list_push(rgui->selection_buf, "Core Information", RGUI_SETTINGS_CORE_INFO, 0); file_list_push(rgui->selection_buf, "Core Information", RGUI_SETTINGS_CORE_INFO, 0);
file_list_push(rgui->selection_buf, "Settings", RGUI_SETTINGS_OPTIONS, 0); file_list_push(rgui->selection_buf, "Settings", RGUI_SETTINGS_OPTIONS, 0);
file_list_push(rgui->selection_buf, "Drivers", RGUI_SETTINGS_DRIVERS, 0); file_list_push(rgui->selection_buf, "Drivers", RGUI_SETTINGS_DRIVERS, 0);

View File

@ -1,7 +1,7 @@
/* RetroArch - A frontend for libretro. /* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2014 - Daniel De Matteis * Copyright (C) 2011-2014 - Daniel De Matteis
* *
* RetroArch is free software: you can redistribute it and/or modify it under the terms * RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found- * of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version. * ation, either version 3 of the License, or (at your option) any later version.
@ -249,6 +249,7 @@ typedef enum
RGUI_SETTINGS_BIND_GRAB_MOUSE_TOGGLE, RGUI_SETTINGS_BIND_GRAB_MOUSE_TOGGLE,
RGUI_SETTINGS_BIND_MENU_TOGGLE, RGUI_SETTINGS_BIND_MENU_TOGGLE,
RGUI_SETTINGS_CUSTOM_BIND, RGUI_SETTINGS_CUSTOM_BIND,
RGUI_SETTINGS_CUSTOM_BIND_KEYBOARD,
RGUI_SETTINGS_CUSTOM_BIND_ALL, RGUI_SETTINGS_CUSTOM_BIND_ALL,
RGUI_SETTINGS_CUSTOM_BIND_DEFAULT_ALL, RGUI_SETTINGS_CUSTOM_BIND_DEFAULT_ALL,
RGUI_SETTINGS_ONSCREEN_KEYBOARD_ENABLE, RGUI_SETTINGS_ONSCREEN_KEYBOARD_ENABLE,
@ -294,9 +295,11 @@ struct rgui_bind_axis_state
int16_t locked_axes[RGUI_MAX_AXES]; int16_t locked_axes[RGUI_MAX_AXES];
}; };
#define RGUI_KEYBOARD_BIND_TIMEOUT_SECONDS 3
struct rgui_bind_state struct rgui_bind_state
{ {
struct retro_keybind *target; struct retro_keybind *target;
int64_t timeout_end; // For keyboard binding.
unsigned begin; unsigned begin;
unsigned last; unsigned last;
unsigned player; 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_get_rested_axes(struct rgui_bind_state *state);
void menu_poll_bind_state(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_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 #ifdef GEKKO
enum enum
@ -337,12 +341,12 @@ enum
GX_RESOLUTIONS_448_448, GX_RESOLUTIONS_448_448,
GX_RESOLUTIONS_480_448, GX_RESOLUTIONS_480_448,
GX_RESOLUTIONS_512_448, GX_RESOLUTIONS_512_448,
GX_RESOLUTIONS_576_448, GX_RESOLUTIONS_576_448,
GX_RESOLUTIONS_608_448, GX_RESOLUTIONS_608_448,
GX_RESOLUTIONS_640_448, GX_RESOLUTIONS_640_448,
GX_RESOLUTIONS_340_464, GX_RESOLUTIONS_340_464,
GX_RESOLUTIONS_512_464, GX_RESOLUTIONS_512_464,
GX_RESOLUTIONS_512_472, GX_RESOLUTIONS_512_472,
GX_RESOLUTIONS_384_480, GX_RESOLUTIONS_384_480,
GX_RESOLUTIONS_512_480, GX_RESOLUTIONS_512_480,
GX_RESOLUTIONS_530_480, GX_RESOLUTIONS_530_480,

View File

@ -1,7 +1,7 @@
/* RetroArch - A frontend for libretro. /* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2014 - Daniel De Matteis * Copyright (C) 2011-2014 - Daniel De Matteis
* *
* RetroArch is free software: you can redistribute it and/or modify it under the terms * RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found- * of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version. * ation, either version 3 of the License, or (at your option) any later version.

View File

@ -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_get_rested_axes(&rgui->binds);
menu_poll_bind_state(&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; break;
case RGUI_SETTINGS_CUSTOM_BIND_DEFAULT_ALL: case RGUI_SETTINGS_CUSTOM_BIND_DEFAULT_ALL:
if (action == RGUI_ACTION_OK) if (action == RGUI_ACTION_OK)
@ -1087,15 +1096,26 @@ int menu_set_settings(void *data, unsigned setting, unsigned action)
else else
{ {
struct retro_keybind *bind = &g_settings.input.binds[port][setting - RGUI_SETTINGS_BIND_BEGIN]; 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.begin = setting;
rgui->binds.last = setting; rgui->binds.last = setting;
rgui->binds.target = bind; rgui->binds.target = bind;
rgui->binds.player = port; rgui->binds.player = port;
file_list_push(rgui->menu_stack, "", RGUI_SETTINGS_CUSTOM_BIND, rgui->selection_ptr); file_list_push(rgui->menu_stack, "",
menu_poll_bind_get_rested_axes(&rgui->binds); action == RGUI_ACTION_OK ? RGUI_SETTINGS_CUSTOM_BIND : RGUI_SETTINGS_CUSTOM_BIND_KEYBOARD, rgui->selection_ptr);
menu_poll_bind_state(&rgui->binds);
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) else if (action == RGUI_ACTION_START)
{ {

View File

@ -1,6 +1,6 @@
/* RetroArch - A frontend for libretro. /* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* *
* RetroArch is free software: you can redistribute it and/or modify it under the terms * RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found- * of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version. * ation, either version 3 of the License, or (at your option) any later version.
@ -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_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) const char **input_keyboard_start_line(void *userdata, input_keyboard_line_complete_t cb)
{ {
if (g_keyboard_line) 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); 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) 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)) if (input_keyboard_line_event(g_keyboard_line, character))
{ {

View File

@ -1,6 +1,6 @@
/* RetroArch - A frontend for libretro. /* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* *
* RetroArch is free software: you can redistribute it and/or modify it under the terms * RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found- * of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version. * ation, either version 3 of the License, or (at your option) any later version.
@ -31,6 +31,8 @@ typedef struct input_keyboard_line input_keyboard_line_t;
// line can be NULL. // line can be NULL.
typedef void (*input_keyboard_line_complete_t)(void *userdata, const char *line); 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_t *input_keyboard_line_new(void *userdata,
input_keyboard_line_complete_t cb); 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); 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); 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 #ifdef __cplusplus
} }
#endif #endif