diff --git a/config.def.h b/config.def.h index f3e767e259..b4df733283 100644 --- a/config.def.h +++ b/config.def.h @@ -1520,8 +1520,8 @@ #define DEFAULT_INPUT_MAX_USERS 8 #endif -#define DEFAULT_INPUT_BIND_TIMEOUT 5 -#define DEFAULT_INPUT_BIND_HOLD 2 +#define DEFAULT_INPUT_BIND_TIMEOUT 3 +#define DEFAULT_INPUT_BIND_HOLD 1 #define DEFAULT_INPUT_POLL_TYPE_BEHAVIOR 2 #define DEFAULT_INPUT_HOTKEY_BLOCK_DELAY 5 diff --git a/input/input_driver.c b/input/input_driver.c index 8b2cedf713..ca522158f5 100644 --- a/input/input_driver.c +++ b/input/input_driver.c @@ -97,10 +97,10 @@ const unsigned input_config_bind_order[24] = { 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_A, RETRO_DEVICE_ID_JOYPAD_Y, + RETRO_DEVICE_ID_JOYPAD_X, RETRO_DEVICE_ID_JOYPAD_SELECT, RETRO_DEVICE_ID_JOYPAD_START, RETRO_DEVICE_ID_JOYPAD_L, @@ -3024,18 +3024,20 @@ void input_config_get_bind_string( if (bind && bind->joykey != NO_BTN) input_config_get_bind_string_joykey( - input_descriptor_label_show, buf, "", bind, size); + input_descriptor_label_show, + buf, "", bind, size); else if (bind && bind->joyaxis != AXIS_NONE) input_config_get_bind_string_joyaxis( input_descriptor_label_show, buf, "", bind, size); else if (auto_bind && auto_bind->joykey != NO_BTN) input_config_get_bind_string_joykey( - input_descriptor_label_show, buf, "Auto: ", auto_bind, size); + input_descriptor_label_show, + buf, "(Auto)", auto_bind, size); else if (auto_bind && auto_bind->joyaxis != AXIS_NONE) input_config_get_bind_string_joyaxis( input_descriptor_label_show, - buf, "Auto: ", auto_bind, size); + buf, "(Auto)", auto_bind, size); if (*buf) delim = 1; @@ -3118,7 +3120,7 @@ void input_config_get_bind_string( void input_config_get_bind_string_joykey( bool input_descriptor_label_show, - char *buf, const char *prefix, + char *buf, const char *suffix, const struct retro_keybind *bind, size_t size) { if (GET_HAT_DIR(bind->joykey)) @@ -3127,39 +3129,32 @@ void input_config_get_bind_string_joykey( && !string_is_empty(bind->joykey_label) && input_descriptor_label_show) { - size_t len = fill_pathname_join_delim(buf, prefix, - bind->joykey_label, ' ', size); - strlcpy(buf + len, " (hat)", size - len); + size_t len = fill_pathname_join_delim(buf, + bind->joykey_label, suffix, ' ', size); } else { - size_t len = strlcpy(buf, prefix, size); - len += snprintf(buf + len, size - len, "Hat #%u ", - (unsigned)GET_HAT(bind->joykey)); + size_t len = snprintf(buf, size, + "Hat #%u ", (unsigned)GET_HAT(bind->joykey)); switch (GET_HAT_DIR(bind->joykey)) { case HAT_UP_MASK: - len += strlcpy(buf + len, "up (", size - len); + len += strlcpy(buf + len, "Up", size - len); break; case HAT_DOWN_MASK: - len += strlcpy(buf + len, "down (", size - len); + len += strlcpy(buf + len, "Down", size - len); break; case HAT_LEFT_MASK: - len += strlcpy(buf + len, "left (", size - len); + len += strlcpy(buf + len, "Left", size - len); break; case HAT_RIGHT_MASK: - len += strlcpy(buf + len, "right (", size - len); + len += strlcpy(buf + len, "Right", size - len); break; default: - len += strlcpy(buf + len, "? (", size - len); + len += strlcpy(buf + len, "?", size - len); break; } - len += strlcpy(buf + len, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE), - size - len); - buf[ len] = ')'; - buf[++len] = '\0'; } } else @@ -3168,43 +3163,35 @@ void input_config_get_bind_string_joykey( !string_is_empty(bind->joykey_label) && input_descriptor_label_show) { - size_t len = fill_pathname_join_delim(buf, prefix, - bind->joykey_label, ' ', size); - strlcpy(buf + len, " (btn)", size - len); + size_t len = fill_pathname_join_delim(buf, + bind->joykey_label, suffix, ' ', size); } else - snprintf(buf, size, "%s%u (%s)", prefix, (unsigned)bind->joykey, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE)); + snprintf(buf, size, "%s%u", + "Button ", (unsigned)bind->joykey); } } void input_config_get_bind_string_joyaxis( bool input_descriptor_label_show, - char *buf, const char *prefix, + char *buf, const char *suffix, const struct retro_keybind *bind, size_t size) { if (bind->joyaxis_label && !string_is_empty(bind->joyaxis_label) && input_descriptor_label_show) { - size_t len = fill_pathname_join_delim(buf, prefix, - bind->joyaxis_label, ' ', size); - strlcpy(buf + len, " (axis)", size - len); + size_t len = fill_pathname_join_delim(buf, + bind->joyaxis_label, suffix, ' ', size); } else { if (AXIS_NEG_GET(bind->joyaxis) != AXIS_DIR_NONE) - { - unsigned axis = AXIS_NEG_GET(bind->joyaxis); - snprintf(buf, size, "%s-%u (%s)", prefix, axis, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE)); - } + snprintf(buf, size, "%s-%u", + "Axis ", (unsigned)AXIS_NEG_GET(bind->joyaxis)); else if (AXIS_POS_GET(bind->joyaxis) != AXIS_DIR_NONE) - { - unsigned axis = AXIS_POS_GET(bind->joyaxis); - snprintf(buf, size, "%s+%u (%s)", prefix, axis, - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE)); - } + snprintf(buf, size, "%s+%u", + "Axis ", (unsigned)AXIS_POS_GET(bind->joyaxis)); } } diff --git a/input/input_driver.h b/input/input_driver.h index c353229902..84ad1b39af 100644 --- a/input/input_driver.h +++ b/input/input_driver.h @@ -156,7 +156,8 @@ enum input_driver_state_flags INP_FLAG_OLD_ANALOG_DPAD_MODE_SET = (1 << 7), INP_FLAG_OLD_LIBRETRO_DEVICE_SET = (1 << 8), INP_FLAG_REMAPPING_CACHE_ACTIVE = (1 << 9), - INP_FLAG_DEFERRED_WAIT_KEYS = (1 << 10) + INP_FLAG_DEFERRED_WAIT_KEYS = (1 << 10), + INP_FLAG_WAIT_INPUT_RELEASE = (1 << 11) }; #ifdef HAVE_BSV_MOVIE diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index 3cc864e196..5b2db27a4b 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -1891,10 +1891,6 @@ MSG_HASH( "input_touch_vmouse_gesture" ) #endif -MSG_HASH( - MENU_ENUM_LABEL_INPUT_BIND_MODE, - "input_bind_mode" - ) MSG_HASH( MENU_ENUM_LABEL_INPUT_BIND_TIMEOUT, "input_bind_timeout" diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index da1c5453c3..ca64234558 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -3162,6 +3162,22 @@ MSG_HASH( MENU_ENUM_SUBLABEL_INPUT_BIND_HOLD, "Amount of seconds to hold an input to bind it." ) +MSG_HASH( + MSG_INPUT_BIND_PRESS, + "Press keyboard, mouse or controller" + ) +MSG_HASH( + MSG_INPUT_BIND_RELEASE, + "Release keys and buttons!" + ) +MSG_HASH( + MSG_INPUT_BIND_TIMEOUT, + "Timeout" + ) +MSG_HASH( + MSG_INPUT_BIND_HOLD, + "Hold" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_TURBO_PERIOD, "Turbo Period" @@ -10550,7 +10566,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_KEY, - "(Key: %s)" + "Key %s" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_LEFT, diff --git a/menu/drivers/ozone.c b/menu/drivers/ozone.c index d00418a652..b0a18205a0 100644 --- a/menu/drivers/ozone.c +++ b/menu/drivers/ozone.c @@ -2406,13 +2406,13 @@ static uintptr_t ozone_entries_icon_get_texture( if (type == (input_id + 3)) return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_INPUT_DPAD_R]; if (type == (input_id + 4)) - return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_INPUT_BTN_R]; - if (type == (input_id + 5)) return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_INPUT_BTN_D]; + if (type == (input_id + 5)) + return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_INPUT_BTN_R]; if (type == (input_id + 6)) - return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_INPUT_BTN_U]; - if (type == (input_id + 7)) return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_INPUT_BTN_L]; + if (type == (input_id + 7)) + return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_INPUT_BTN_U]; if (type == (input_id + 8)) return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_INPUT_SELECT]; if (type == (input_id + 9)) diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index b9b2b9420b..e1473b4efe 100644 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -3554,13 +3554,13 @@ static uintptr_t xmb_icon_get_id(xmb_handle_t *xmb, else if (type == (input_id + 3)) return xmb->textures.list[XMB_TEXTURE_INPUT_DPAD_R]; else if (type == (input_id + 4)) - return xmb->textures.list[XMB_TEXTURE_INPUT_BTN_R]; - else if (type == (input_id + 5)) return xmb->textures.list[XMB_TEXTURE_INPUT_BTN_D]; + else if (type == (input_id + 5)) + return xmb->textures.list[XMB_TEXTURE_INPUT_BTN_R]; else if (type == (input_id + 6)) - return xmb->textures.list[XMB_TEXTURE_INPUT_BTN_U]; - else if (type == (input_id + 7)) return xmb->textures.list[XMB_TEXTURE_INPUT_BTN_L]; + else if (type == (input_id + 7)) + return xmb->textures.list[XMB_TEXTURE_INPUT_BTN_U]; else if (type == (input_id + 8)) return xmb->textures.list[XMB_TEXTURE_INPUT_SELECT]; else if (type == (input_id + 9)) diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 36e8dd20b0..878a6471e9 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -7601,7 +7601,6 @@ unsigned menu_displaylist_build_list( #endif {MENU_ENUM_LABEL_INPUT_BIND_TIMEOUT, PARSE_ONLY_UINT, true }, {MENU_ENUM_LABEL_INPUT_BIND_HOLD, PARSE_ONLY_UINT, true }, - {MENU_ENUM_LABEL_INPUT_BIND_MODE, PARSE_ONLY_UINT, true }, {MENU_ENUM_LABEL_QUIT_PRESS_TWICE, PARSE_ONLY_BOOL, true }, {MENU_ENUM_LABEL_PAUSE_ON_DISCONNECT, PARSE_ONLY_BOOL, true }, {MENU_ENUM_LABEL_INPUT_AUTO_MOUSE_GRAB, PARSE_ONLY_BOOL, true }, diff --git a/menu/menu_driver.c b/menu/menu_driver.c index cf6bbdea5b..cf2c30f7c7 100644 --- a/menu/menu_driver.c +++ b/menu/menu_driver.c @@ -1446,6 +1446,7 @@ static int menu_input_key_bind_set_mode_common( bind_type = setting->bind_type; + binds->order = 0; binds->begin = bind_type; binds->last = bind_type; binds->output = keybind; @@ -1472,9 +1473,12 @@ static int menu_input_key_bind_set_mode_common( menu_displaylist_info_init(&info); - binds->begin = MENU_SETTINGS_BIND_BEGIN; + binds->order = 0; + binds->begin = MENU_SETTINGS_BIND_BEGIN + + input_config_bind_order[0]; binds->last = MENU_SETTINGS_BIND_LAST; - binds->output = &input_config_binds[setting->index_offset][0]; + binds->output = &input_config_binds[setting->index_offset][0] + + input_config_bind_order[0]; binds->buffer = *(binds->output); info.list = menu_stack; @@ -1496,10 +1500,9 @@ static int menu_input_key_bind_set_mode_common( return 0; } -#ifdef ANDROID static bool menu_input_key_bind_poll_find_hold_pad( struct menu_bind_state *new_state, - struct retro_keybind * output, + struct retro_keybind *output, unsigned p) { unsigned a, b, h; @@ -1507,11 +1510,22 @@ static bool menu_input_key_bind_poll_find_hold_pad( (const struct menu_bind_state_port*) &new_state->state[p]; + for (b = RETROK_BACKSPACE; b < RETROK_LAST; b++) + { + bool found = n->keys[b]; + + if (!found) + continue; + + output->key = b; + return true; + } + for (b = 0; b < MENU_MAX_MBUTTONS; b++) { - bool iterate = n->mouse_buttons[b]; + bool found = n->mouse_buttons[b]; - if (!iterate) + if (!found) continue; switch (b) @@ -1532,9 +1546,9 @@ static bool menu_input_key_bind_poll_find_hold_pad( for (b = 0; b < MENU_MAX_BUTTONS; b++) { - bool iterate = n->buttons[b]; + bool found = n->buttons[b]; - if (!iterate) + if (!found) continue; output->joykey = b; @@ -1549,10 +1563,8 @@ static bool menu_input_key_bind_poll_find_hold_pad( { /* Take care of case where axis rests on +/- 0x7fff * (e.g. 360 controller on Linux) */ - output->joyaxis = n->axes[a] > 0 - ? AXIS_POS(a) : AXIS_NEG(a); + output->joyaxis = n->axes[a] > 0 ? AXIS_POS(a) : AXIS_NEG(a); output->joykey = NO_BTN; - return true; } } @@ -1585,7 +1597,7 @@ static bool menu_input_key_bind_poll_find_hold_pad( static bool menu_input_key_bind_poll_find_hold( unsigned max_users, struct menu_bind_state *new_state, - struct retro_keybind * output) + struct retro_keybind *output) { if (new_state) { @@ -1600,12 +1612,11 @@ static bool menu_input_key_bind_poll_find_hold( return false; } -#endif static bool menu_input_key_bind_poll_find_trigger_pad( struct menu_bind_state *state, struct menu_bind_state *new_state, - struct retro_keybind * output, + struct retro_keybind *output, unsigned p) { unsigned a, b, h; @@ -1614,11 +1625,22 @@ static bool menu_input_key_bind_poll_find_trigger_pad( const struct menu_bind_state_port *o = (const struct menu_bind_state_port*) &state->state[p]; + for (b = RETROK_BACKSPACE; b < RETROK_LAST; b++) + { + bool found = n->keys[b] && !o->keys[b]; + + if (!found) + continue; + + output->key = b; + return true; + } + for (b = 0; b < MENU_MAX_MBUTTONS; b++) { - bool iterate = n->mouse_buttons[b] && !o->mouse_buttons[b]; + bool found = n->mouse_buttons[b] && !o->mouse_buttons[b]; - if (!iterate) + if (!found) continue; switch (b) @@ -1639,9 +1661,9 @@ static bool menu_input_key_bind_poll_find_trigger_pad( for (b = 0; b < MENU_MAX_BUTTONS; b++) { - bool iterate = n->buttons[b] && !o->buttons[b]; + bool found = n->buttons[b] && !o->buttons[b]; - if (!iterate) + if (!found) continue; output->joykey = b; @@ -1663,14 +1685,12 @@ static bool menu_input_key_bind_poll_find_trigger_pad( { /* Take care of case where axis rests on +/- 0x7fff * (e.g. 360 controller on Linux) */ - output->joyaxis = (n->axes[a] > 0) - ? AXIS_POS(a) : AXIS_NEG(a); + output->joyaxis = (n->axes[a] > 0) ? AXIS_POS(a) : AXIS_NEG(a); output->joykey = NO_BTN; /* 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; } @@ -1707,7 +1727,7 @@ static bool menu_input_key_bind_poll_find_trigger( unsigned max_users, struct menu_bind_state *state, struct menu_bind_state *new_state, - struct retro_keybind * output) + struct retro_keybind *output) { if (state && new_state) { @@ -3328,7 +3348,6 @@ static void menu_input_key_bind_poll_bind_state( unsigned b; rarch_joypad_info_t joypad_info; input_driver_t *current_input = input_st->current_driver; - void *input_data = input_st->current_data; unsigned port = state->port; const input_device_driver_t *joypad = input_st->primary_joypad; #ifdef HAVE_MFI @@ -3366,6 +3385,20 @@ static void menu_input_key_bind_poll_bind_state( port, RETRO_DEVICE_MOUSE, 0, b); } + + for (b = RETROK_BACKSPACE; b < RETROK_LAST; b++) + { + state->state[port].keys[b] = + current_input->input_state( + input_st->current_data, + joypad, + sec_joypad, + &joypad_info, + binds, + keyboard_mapping_blocked, + 0, + RETRO_DEVICE_KEYBOARD, 0, b); + } } joypad_info.joy_idx = 0; @@ -3373,19 +3406,6 @@ static void menu_input_key_bind_poll_bind_state( joypad_info.axis_threshold = 0.0f; state->skip = timed_out; - if (current_input->input_state) - state->skip |= - current_input->input_state( - input_data, - joypad, - sec_joypad, - &joypad_info, - NULL, - keyboard_mapping_blocked, - 0, - RETRO_DEVICE_KEYBOARD, - 0, - RETROK_RETURN); if (joypad) { @@ -4054,7 +4074,7 @@ void menu_entries_get_last_stack(const char **path, const char **label, if (path) *path = list->list[list->size - 1].path; if (label) - *label = list->list[list->size - 1].label; + *label = list->list[list->size - 1].label; if (file_type) *file_type = list->list[list->size - 1].type; if (entry_idx) @@ -4703,45 +4723,45 @@ const menu_ctx_driver_t *menu_driver_find_driver( return (const menu_ctx_driver_t*)menu_ctx_drivers[0]; } +#ifdef USE_CUSTOM_BIND_KEYBOARD_CB static bool menu_input_key_bind_custom_bind_keyboard_cb( void *data, unsigned code) { - uint64_t current_usec; - input_driver_state_t *input_st = input_state_get_ptr(); - struct menu_state *menu_st = &menu_driver_state; settings_t *settings = config_get_ptr(); + struct menu_state *menu_st = &menu_driver_state; struct menu_bind_state *binds = &menu_st->input_binds; uint64_t input_bind_hold_us = settings->uints.input_bind_hold * 1000000; uint64_t input_bind_timeout_us = settings->uints.input_bind_timeout * 1000000; + uint64_t current_usec = cpu_features_get_time_usec(); /* Clear old mapping bit */ - BIT512_CLEAR_PTR(&input_st->keyboard_mapping_bits, binds->buffer.key); + input_keyboard_mapping_bits(0, binds->buffer.key); - /* store key in bind */ + /* Store key in bind */ binds->buffer.key = (enum retro_key)code; /* Store new mapping bit */ - BIT512_SET_PTR(&input_st->keyboard_mapping_bits, binds->buffer.key); + input_keyboard_mapping_bits(1, binds->buffer.key); - /* write out the bind */ + /* Write out the bind */ *(binds->output) = binds->buffer; - /* next bind */ + /* Next bind */ binds->begin++; binds->output++; binds->buffer =* (binds->output); - current_usec = cpu_features_get_time_usec(); - binds->timer_hold.timeout_us = input_bind_hold_us; binds->timer_hold.current = current_usec; binds->timer_hold.timeout_end = current_usec + input_bind_hold_us; + binds->timer_timeout.timeout_us = input_bind_timeout_us; binds->timer_timeout.current = current_usec; - binds->timer_timeout.timeout_end = current_usec +input_bind_timeout_us; + binds->timer_timeout.timeout_end = current_usec + input_bind_timeout_us; return (binds->begin <= binds->last); } +#endif bool menu_input_key_bind_set_mode( enum menu_input_binds_ctl_state state, void *data) @@ -4771,6 +4791,7 @@ bool menu_input_key_bind_set_mode( if (!setting || !menu) return false; + if (menu_input_key_bind_set_mode_common(menu_st, binds, state, setting, settings) == -1) return false; @@ -4793,20 +4814,25 @@ bool menu_input_key_bind_set_mode( current_usec = cpu_features_get_time_usec(); - binds->timer_hold . timeout_us = input_bind_hold_us; - binds->timer_hold . current = current_usec; - binds->timer_hold . timeout_end = current_usec + input_bind_hold_us; + binds->timer_hold .timeout_us = input_bind_hold_us; + binds->timer_hold .current = current_usec; + binds->timer_hold .timeout_end = current_usec + input_bind_hold_us; - binds->timer_timeout. timeout_us = input_bind_timeout_us; - binds->timer_timeout. current = current_usec; - binds->timer_timeout. timeout_end = current_usec + input_bind_timeout_us; + binds->timer_timeout.timeout_us = input_bind_timeout_us; + binds->timer_timeout.current = current_usec; + binds->timer_timeout.timeout_end = current_usec + input_bind_timeout_us; - input_st->keyboard_press_cb = - menu_input_key_bind_custom_bind_keyboard_cb; +#ifdef USE_CUSTOM_BIND_KEYBOARD_CB + input_st->keyboard_press_cb = menu_input_key_bind_custom_bind_keyboard_cb; input_st->keyboard_press_data = menu; +#endif + /* While waiting for input, we have to block all hotkeys. */ input_st->flags |= INP_FLAG_KB_MAPPING_BLOCKED; + /* Wait until keys are released before starting bind timeout. */ + input_st->flags |= INP_FLAG_WAIT_INPUT_RELEASE; + /* Upon triggering an input bind operation, * pointer input must be inhibited - otherwise * attempting to bind mouse buttons will cause @@ -4830,40 +4856,43 @@ static bool menu_input_key_bind_iterate( uint64_t input_bind_hold_us = settings->uints.input_bind_hold * 1000000; uint64_t input_bind_timeout_us = settings->uints.input_bind_timeout * 1000000; - /* TODO/FIXME - localize */ snprintf(bind->s, bind->len, - "[%s]\nPress keyboard, mouse or joypad\n(Timeout %d %s)", - input_config_bind_map_get_desc( - _binds->begin - MENU_SETTINGS_BIND_BEGIN), - (int)(_binds->timer_timeout.timeout_us / 1000000), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SECONDS)); + "%s..\n(%s %1.1f %s)\n \n%s\n \n", + msg_hash_to_str(MSG_INPUT_BIND_PRESS), + msg_hash_to_str(MSG_INPUT_BIND_TIMEOUT), + ((float)_binds->timer_timeout.timeout_us / 1000000), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SECONDS), + input_config_bind_map_get_desc(_binds->begin - MENU_SETTINGS_BIND_BEGIN)); /* Tick main timers */ - _binds->timer_timeout.current = current_time; - _binds->timer_timeout.timeout_us = _binds->timer_timeout.timeout_end - - current_time; _binds->timer_hold .current = current_time; - _binds->timer_hold .timeout_us = _binds->timer_hold .timeout_end - - current_time; + _binds->timer_hold .timeout_us = _binds->timer_hold .timeout_end - current_time; + + _binds->timer_timeout.current = current_time; + _binds->timer_timeout.timeout_us = _binds->timer_timeout.timeout_end - current_time; if (_binds->timer_timeout.timeout_us <= 0) { - uint64_t current_usec = cpu_features_get_time_usec(); - input_st->flags &= ~INP_FLAG_KB_MAPPING_BLOCKED; - /*skip to next bind*/ +#if 1 + /* Give up on first timeout */ + return true; +#else + /* Skip to next bind */ _binds->begin++; _binds->output++; - _binds->timer_hold . timeout_us = input_bind_hold_us; - _binds->timer_hold . current = current_usec; - _binds->timer_hold . timeout_end = current_usec + input_bind_hold_us; - _binds->timer_timeout. timeout_us = input_bind_timeout_us; - _binds->timer_timeout. current = current_usec; - _binds->timer_timeout. timeout_end = current_usec + input_bind_timeout_us; + _binds->timer_hold .timeout_us = input_bind_hold_us; + _binds->timer_hold .current = current_time; + _binds->timer_hold .timeout_end = current_time + input_bind_hold_us; + + _binds->timer_timeout.timeout_us = input_bind_timeout_us; + _binds->timer_timeout.current = current_time; + _binds->timer_timeout.timeout_end = current_time + input_bind_timeout_us; timed_out = true; +#endif } /* binds.begin is updated in keyboard_press callback. */ @@ -4889,6 +4918,9 @@ static bool menu_input_key_bind_iterate( { bool complete = false; struct menu_bind_state new_binds = *_binds; + unsigned bind_index = _binds->begin - MENU_SETTINGS_BIND_BEGIN; + const struct retro_keybind *old_binds = &input_config_binds[new_binds.port][bind_index]; + unsigned old_key = old_binds->key; input_st->flags &= ~INP_FLAG_KB_MAPPING_BLOCKED; @@ -4900,60 +4932,105 @@ static bool menu_input_key_bind_iterate( &new_binds, timed_out, (input_st->flags & INP_FLAG_KB_MAPPING_BLOCKED) ? true : false); -#ifdef ANDROID - /* Keep resetting bind during the hold period, - * or we'll potentially bind joystick and mouse, etc.*/ - new_binds.buffer = *(new_binds.output); + /* Wait until keys and buttons are released */ + if (input_st->flags & INP_FLAG_WAIT_INPUT_RELEASE) + { + if (input_bind_hold_us) + { + if (!menu_input_key_bind_poll_find_hold( + settings->uints.input_max_users, + &new_binds, &(new_binds.buffer))) + input_st->flags &= ~INP_FLAG_WAIT_INPUT_RELEASE; + } + else + { + if (!menu_input_key_bind_poll_find_trigger( + settings->uints.input_max_users, + _binds, &new_binds, &(new_binds.buffer))) + input_st->flags &= ~INP_FLAG_WAIT_INPUT_RELEASE; + } - if (menu_input_key_bind_poll_find_hold( + if (!(input_st->flags & INP_FLAG_WAIT_INPUT_RELEASE)) + { + /* Reset timeout */ + new_binds.timer_timeout.timeout_us = input_bind_timeout_us; + new_binds.timer_timeout.current = current_time; + new_binds.timer_timeout.timeout_end = current_time + input_bind_timeout_us; + } + else + snprintf(bind->s, bind->len, + "%s..\n(%s %1.1f %s)\n \n--- %s ---\n \n", + msg_hash_to_str(MSG_INPUT_BIND_PRESS), + msg_hash_to_str(MSG_INPUT_BIND_TIMEOUT), + ((float)_binds->timer_timeout.timeout_us / 1000000), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SECONDS), + msg_hash_to_str(MSG_INPUT_BIND_RELEASE) + ); + } + else if (input_bind_hold_us) + { + /* Keep resetting bind during the hold period, + * or we'll potentially bind joystick and mouse, etc. */ + new_binds.buffer = *(new_binds.output); + + if (menu_input_key_bind_poll_find_hold( settings->uints.input_max_users, &new_binds, &new_binds.buffer)) - { - uint64_t current_usec = cpu_features_get_time_usec(); - /* Inhibit timeout*/ - new_binds.timer_timeout. timeout_us = input_bind_timeout_us; - new_binds.timer_timeout. current = current_usec; - new_binds.timer_timeout. timeout_end = current_usec + input_bind_timeout_us; + { + char hold_label[256]; - /* Run hold timer*/ - new_binds.timer_hold.current = current_time; - new_binds.timer_hold.timeout_us = - new_binds.timer_hold.timeout_end - current_time; + hold_label[0] = '\0'; - /* TODO/FIXME - localize */ - snprintf(bind->s, bind->len, - "[%s]\nPress keyboard, mouse or joypad\nand hold ...", - input_config_bind_map_get_desc( - _binds->begin - MENU_SETTINGS_BIND_BEGIN)); + /* Inhibit timeout */ + new_binds.timer_timeout.timeout_us = input_bind_timeout_us; + new_binds.timer_timeout.current = current_time; + new_binds.timer_timeout.timeout_end = current_time + input_bind_timeout_us; - /* Hold complete? */ - if (new_binds.timer_hold.timeout_us <= 0) - complete = true; + /* Run hold timer */ + new_binds.timer_hold.current = current_time; + new_binds.timer_hold.timeout_us = new_binds.timer_hold.timeout_end - current_time; + + input_config_get_bind_string(settings, hold_label, + &new_binds.buffer, NULL, sizeof(hold_label)); + + snprintf(bind->s, bind->len, + "%s..\n(%s %1.1f %s)\n \n%s\n %s", + msg_hash_to_str(MSG_INPUT_BIND_PRESS), + msg_hash_to_str(MSG_INPUT_BIND_HOLD), + ((float)new_binds.timer_hold.timeout_us / 1000000), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SECONDS), + input_config_bind_map_get_desc(_binds->begin - MENU_SETTINGS_BIND_BEGIN), + hold_label); + + /* Hold complete? */ + if (new_binds.timer_hold.timeout_us <= 0) + complete = true; + } + else + { + /* Reset hold countdown */ + new_binds.timer_hold.timeout_us = input_bind_hold_us; + new_binds.timer_hold.current = current_time; + new_binds.timer_hold.timeout_end = current_time + input_bind_hold_us; + } } - else - { - uint64_t current_usec = cpu_features_get_time_usec(); - - /* Reset hold countdown*/ - new_binds.timer_hold .timeout_us = input_bind_hold_us; - new_binds.timer_hold .current = current_usec; - new_binds.timer_hold .timeout_end = current_usec + input_bind_hold_us; - } -#else - if ( (new_binds.skip && !_binds->skip) + else if ((new_binds.skip && !_binds->skip) || menu_input_key_bind_poll_find_trigger( settings->uints.input_max_users, _binds, &new_binds, &(new_binds.buffer))) complete = true; -#endif if (complete) { - /* Update bind */ - uint64_t current_usec = cpu_features_get_time_usec(); - *(new_binds.output) = new_binds.buffer; + /* Update bind */ + *(new_binds.output) = new_binds.buffer; - input_st->flags &= ~INP_FLAG_KB_MAPPING_BLOCKED; + /* Update keyboard mapping bits */ + if (new_binds.buffer.key) + { + input_keyboard_mapping_bits(0, old_key); + input_keyboard_mapping_bits(1, new_binds.buffer.key); + } /* Avoid new binds triggering things right away. */ /* Inhibits input for 2 frames @@ -4961,25 +5038,33 @@ static bool menu_input_key_bind_iterate( * after certain events - e.g. closing the OSK */ menu_st->input_driver_flushing_input = 2; - new_binds.begin++; + /* Use human readable order instead */ + new_binds.order++; + new_binds.begin = MENU_SETTINGS_BIND_BEGIN + input_config_bind_order[new_binds.order]; - if (new_binds.begin > new_binds.last) + if ( new_binds.order > ARRAY_SIZE(input_config_bind_order) - 1 + || new_binds.last != MENU_SETTINGS_BIND_LAST) { - input_st->keyboard_press_cb = NULL; - input_st->keyboard_press_data = NULL; - input_st->flags &= ~INP_FLAG_KB_MAPPING_BLOCKED; + input_st->keyboard_press_cb = NULL; + input_st->keyboard_press_data = NULL; + input_st->flags &= ~INP_FLAG_KB_MAPPING_BLOCKED; return true; } - /*next bind*/ - new_binds.output++; + input_st->flags &= ~INP_FLAG_KB_MAPPING_BLOCKED; + input_st->flags |= INP_FLAG_WAIT_INPUT_RELEASE; + + /* Next bind */ + new_binds.output = + &input_config_binds[new_binds.port][0] + + input_config_bind_order[new_binds.order]; new_binds.buffer = *(new_binds.output); - new_binds.timer_hold .timeout_us = input_bind_hold_us; - new_binds.timer_hold .current = current_usec; - new_binds.timer_hold .timeout_end = current_usec + input_bind_hold_us; - new_binds.timer_timeout. timeout_us = input_bind_timeout_us; - new_binds.timer_timeout. current = current_usec; - new_binds.timer_timeout. timeout_end = current_usec + input_bind_timeout_us; + new_binds.timer_hold .timeout_us = input_bind_hold_us; + new_binds.timer_hold .current = current_time; + new_binds.timer_hold .timeout_end = current_time + input_bind_hold_us; + new_binds.timer_timeout.timeout_us = input_bind_timeout_us; + new_binds.timer_timeout.current = current_time; + new_binds.timer_timeout.timeout_end = current_time + input_bind_timeout_us; } *(_binds) = new_binds; @@ -7327,15 +7412,15 @@ int generic_menu_entry_action( menu_driver_ctl(MENU_NAVIGATION_CTL_CLEAR, &pending_push); } else - { - size_t menu_list_size = menu_st->entries.list ? MENU_LIST_GET_SELECTION(menu_st->entries.list, 0)->size : 0; - size_t new_selection = menu_list_size - 1; + { + size_t menu_list_size = menu_st->entries.list ? MENU_LIST_GET_SELECTION(menu_st->entries.list, 0)->size : 0; + size_t new_selection = menu_list_size - 1; - menu_st->selection_ptr = new_selection; + menu_st->selection_ptr = new_selection; - if (menu_st->driver_ctx->navigation_set_last) - menu_st->driver_ctx->navigation_set_last(menu_st->userdata); - } + if (menu_st->driver_ctx->navigation_set_last) + menu_st->driver_ctx->navigation_set_last(menu_st->userdata); + } } if (menu_driver_ctx->navigation_increment) @@ -7423,15 +7508,15 @@ int generic_menu_entry_action( menu_st->driver_ctx->navigation_set(menu_st->userdata, true); } else - { - size_t menu_list_size = menu_st->entries.list ? MENU_LIST_GET_SELECTION(menu_st->entries.list, 0)->size : 0; - size_t new_selection = menu_list_size - 1; + { + size_t menu_list_size = menu_st->entries.list ? MENU_LIST_GET_SELECTION(menu_st->entries.list, 0)->size : 0; + size_t new_selection = menu_list_size - 1; - menu_st->selection_ptr = new_selection; + menu_st->selection_ptr = new_selection; - if (menu_st->driver_ctx->navigation_set_last) - menu_st->driver_ctx->navigation_set_last(menu_st->userdata); - } + if (menu_st->driver_ctx->navigation_set_last) + menu_st->driver_ctx->navigation_set_last(menu_st->userdata); + } if (menu_driver_ctx->navigation_increment) menu_driver_ctx->navigation_increment(menu_userdata); @@ -7606,7 +7691,7 @@ int generic_menu_entry_action( if (!string_is_empty(title_name)) { - size_t _len = strlcpy(speak_string, + size_t _len = strlcpy(speak_string, title_name, sizeof(speak_string)); speak_string[ _len] = ' '; speak_string[++_len] = '\0'; diff --git a/menu/menu_input.h b/menu/menu_input.h index 1e9e0ddd34..887db4557b 100644 --- a/menu/menu_input.h +++ b/menu/menu_input.h @@ -150,6 +150,7 @@ struct menu_bind_state_port uint16_t hats[MENU_MAX_HATS]; bool mouse_buttons[MENU_MAX_MBUTTONS]; bool buttons[MENU_MAX_BUTTONS]; + bool keys[RETROK_LAST]; }; struct menu_bind_axis_state @@ -174,6 +175,7 @@ struct menu_bind_state unsigned begin; unsigned last; + unsigned order; unsigned user; unsigned port; diff --git a/menu/menu_setting.c b/menu/menu_setting.c index fabad7434d..33b2eee85e 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -14883,7 +14883,7 @@ static bool setting_append_list( general_read_handler); (*list)[list_info->index - 1].action_ok = &setting_action_ok_uint; (*list)[list_info->index - 1].offset_by = 1; - menu_settings_list_current_add_range(list, list_info, 1, 10, 1, true, true); + menu_settings_list_current_add_range(list, list_info, 1, 5, 1, true, true); SETTINGS_DATA_LIST_CURRENT_ADD_FLAGS(list, list_info, SD_FLAG_ADVANCED); CONFIG_UINT( @@ -14898,8 +14898,8 @@ static bool setting_append_list( general_write_handler, general_read_handler); (*list)[list_info->index - 1].action_ok = &setting_action_ok_uint; - (*list)[list_info->index - 1].offset_by = 1; - menu_settings_list_current_add_range(list, list_info, 1, 10, 1, true, true); + (*list)[list_info->index - 1].offset_by = 0; + menu_settings_list_current_add_range(list, list_info, 0, 5, 1, true, true); SETTINGS_DATA_LIST_CURRENT_ADD_FLAGS(list, list_info, SD_FLAG_ADVANCED); CONFIG_ACTION( diff --git a/msg_hash.h b/msg_hash.h index eca16c043e..c11f8c112d 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -391,6 +391,10 @@ enum msg_hash_enums MSG_REMAP_FILE_SAVED_SUCCESSFULLY, MSG_REMAP_FILE_REMOVED_SUCCESSFULLY, MSG_REMAP_FILE_RESET, + MSG_INPUT_BIND_PRESS, + MSG_INPUT_BIND_RELEASE, + MSG_INPUT_BIND_TIMEOUT, + MSG_INPUT_BIND_HOLD, MSG_OVERRIDE_UNLOAD, MSG_SHADER_PRESET_SAVED_SUCCESSFULLY, MSG_SHADER_PRESET_REMOVED_SUCCESSFULLY, @@ -961,7 +965,6 @@ enum msg_hash_enums MENU_LABEL(INPUT_REMAPPING_DIRECTORY), - MENU_ENUM_LABEL_INPUT_BIND_MODE, MENU_ENUM_LABEL_INPUT_OVERLAY, MENU_ENUM_LABEL_INPUT_OSK_OVERLAY, diff --git a/runloop.c b/runloop.c index 2e45d9cf76..aba490154c 100644 --- a/runloop.c +++ b/runloop.c @@ -2049,13 +2049,6 @@ bool runloop_environment_cb(unsigned cmd, void *data) case RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS: { - static const char *libretro_btn_desc[] = { - "B (bottom)", "Y (left)", "Select", "Start", - "D-Pad Up", "D-Pad Down", "D-Pad Left", "D-Pad Right", - "A (right)", "X (up)", - "L", "R", "L2", "R2", "L3", "R3", - }; - if (sys_info) { unsigned retro_id; @@ -2156,15 +2149,19 @@ bool runloop_environment_cb(unsigned cmd, void *data) { unsigned mapped_port = settings->uints.input_remap_ports[p]; + RARCH_DBG(" %s %u:\n", msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PORT), p + 1); + for (retro_id = 0; retro_id < RARCH_FIRST_CUSTOM_BIND; retro_id++) { - const char *description = sys_info->input_desc_btn[mapped_port][retro_id]; + unsigned bind_index = input_config_bind_order[retro_id]; + const char *description = sys_info->input_desc_btn[mapped_port][bind_index]; if (!description) continue; - RARCH_DBG(" RetroPad, Port %u, Button \"%s\" => \"%s\"\n", - p + 1, libretro_btn_desc[retro_id], description); + RARCH_DBG(" \"%s\" => \"%s\"\n", + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_B + bind_index), + description); } } } @@ -2802,10 +2799,12 @@ bool runloop_environment_cb(unsigned cmd, void *data) if (log_level != RETRO_LOG_DEBUG) continue; - RARCH_DBG(" Controller port: %u\n", i + 1); + RARCH_DBG(" %s %u:\n", msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PORT), i + 1); for (j = 0; j < info[i].num_types; j++) - RARCH_DBG(" %s (ID: %u)\n", info[i].types[j].desc, + if (info[i].types[j].desc) + RARCH_DBG(" \"%s\" (%u)\n", + info[i].types[j].desc, info[i].types[j].id); }