diff --git a/config.def.h b/config.def.h index 423bf80546d3..a2f36dab486c 100644 --- a/config.def.h +++ b/config.def.h @@ -1654,6 +1654,7 @@ #define DEFAULT_INPUT_POLL_TYPE_BEHAVIOR 2 #define DEFAULT_INPUT_HOTKEY_BLOCK_DELAY 5 #define DEFAULT_INPUT_HOTKEY_DEVICE_MERGE false +#define DEFAULT_INPUT_HOTKEY_FOLLOWS_PLAYER1 false #define DEFAULT_GFX_THUMBNAILS_DEFAULT 3 diff --git a/config.def.keybinds.h b/config.def.keybinds.h index 82e8914d88e7..0450af305fc4 100644 --- a/config.def.keybinds.h +++ b/config.def.keybinds.h @@ -2269,6 +2269,402 @@ static const struct retro_keybind retro_keybinds_rest[] = { RARCH_TURBO_ENABLE, NO_BTN, NO_BTN, 0, true }, + /* Hotkeys */ + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_ENABLE_HOTKEY, RETROK_UNKNOWN, + RARCH_ENABLE_HOTKEY, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_MENU_TOGGLE, RETROK_UNKNOWN, + RARCH_MENU_TOGGLE, NO_BTN, NO_BTN, 0, + true + }, +#ifdef HAVE_LAKKA + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_RESTART_KEY, RETROK_UNKNOWN, + RARCH_QUIT_KEY, NO_BTN, NO_BTN, 0, + true + }, +#else + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_QUIT_KEY, RETROK_UNKNOWN, + RARCH_QUIT_KEY, NO_BTN, NO_BTN, 0, + true + }, +#endif + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_CLOSE_CONTENT_KEY, RETROK_UNKNOWN, + RARCH_CLOSE_CONTENT_KEY, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_RESET, RETROK_UNKNOWN, + RARCH_RESET, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_FAST_FORWARD_KEY, RETROK_UNKNOWN, + RARCH_FAST_FORWARD_KEY, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_FAST_FORWARD_HOLD_KEY, RETROK_UNKNOWN, + RARCH_FAST_FORWARD_HOLD_KEY, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_SLOWMOTION_KEY, RETROK_UNKNOWN, + RARCH_SLOWMOTION_KEY, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_SLOWMOTION_HOLD_KEY, RETROK_UNKNOWN, + RARCH_SLOWMOTION_HOLD_KEY, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_REWIND, RETROK_UNKNOWN, + RARCH_REWIND, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_PAUSE_TOGGLE, RETROK_UNKNOWN, + RARCH_PAUSE_TOGGLE, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_FRAMEADVANCE, RETROK_UNKNOWN, + RARCH_FRAMEADVANCE, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE, RETROK_UNKNOWN, + RARCH_MUTE, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_UP, RETROK_UNKNOWN, + RARCH_VOLUME_UP, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_DOWN, RETROK_UNKNOWN, + RARCH_VOLUME_DOWN, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_KEY, RETROK_UNKNOWN, + RARCH_LOAD_STATE_KEY, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_KEY, RETROK_UNKNOWN, + RARCH_SAVE_STATE_KEY, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_PLUS, RETROK_UNKNOWN, + RARCH_STATE_SLOT_PLUS, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_MINUS, RETROK_UNKNOWN, + RARCH_STATE_SLOT_MINUS, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_PLAY_REPLAY_KEY, RETROK_UNKNOWN, + RARCH_PLAY_REPLAY_KEY, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_RECORD_REPLAY_KEY, RETROK_UNKNOWN, + RARCH_RECORD_REPLAY_KEY, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_HALT_REPLAY_KEY, RETROK_UNKNOWN, + RARCH_HALT_REPLAY_KEY, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_REPLAY_SLOT_PLUS, RETROK_UNKNOWN, + RARCH_REPLAY_SLOT_PLUS, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_REPLAY_SLOT_MINUS, RETROK_UNKNOWN, + RARCH_REPLAY_SLOT_MINUS, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_EJECT_TOGGLE, RETROK_UNKNOWN, + RARCH_DISK_EJECT_TOGGLE, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_NEXT, RETROK_UNKNOWN, + RARCH_DISK_NEXT, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_PREV, RETROK_UNKNOWN, + RARCH_DISK_PREV, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_SHADER_TOGGLE, RETROK_UNKNOWN, + RARCH_SHADER_TOGGLE, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_SHADER_HOLD, RETROK_UNKNOWN, + RARCH_SHADER_HOLD, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_SHADER_NEXT, RETROK_UNKNOWN, + RARCH_SHADER_NEXT, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_SHADER_PREV, RETROK_UNKNOWN, + RARCH_SHADER_PREV, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_TOGGLE, RETROK_UNKNOWN, + RARCH_CHEAT_TOGGLE, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_INDEX_PLUS, RETROK_UNKNOWN, + RARCH_CHEAT_INDEX_PLUS, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_INDEX_MINUS, RETROK_UNKNOWN, + RARCH_CHEAT_INDEX_MINUS, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_SCREENSHOT, RETROK_UNKNOWN, + RARCH_SCREENSHOT, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_RECORDING_TOGGLE, RETROK_UNKNOWN, + RARCH_RECORDING_TOGGLE, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_STREAMING_TOGGLE, RETROK_UNKNOWN, + RARCH_STREAMING_TOGGLE, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_TURBO_FIRE_TOGGLE, RETROK_UNKNOWN, + RARCH_TURBO_FIRE_TOGGLE, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_GRAB_MOUSE_TOGGLE, RETROK_UNKNOWN, + RARCH_GRAB_MOUSE_TOGGLE, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_GAME_FOCUS_TOGGLE, RETROK_UNKNOWN, + RARCH_GAME_FOCUS_TOGGLE, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_FULLSCREEN_TOGGLE_KEY, RETROK_UNKNOWN, + RARCH_FULLSCREEN_TOGGLE_KEY, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_UI_COMPANION_TOGGLE, RETROK_UNKNOWN, + RARCH_UI_COMPANION_TOGGLE, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_VRR_RUNLOOP_TOGGLE, RETROK_UNKNOWN, + RARCH_VRR_RUNLOOP_TOGGLE, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_RUNAHEAD_TOGGLE, RETROK_UNKNOWN, + RARCH_RUNAHEAD_TOGGLE, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_PREEMPT_TOGGLE, RETROK_UNKNOWN, + RARCH_PREEMPT_TOGGLE, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_FPS_TOGGLE, RETROK_UNKNOWN, + RARCH_FPS_TOGGLE, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_STATISTICS_TOGGLE, RETROK_UNKNOWN, + RARCH_STATISTICS_TOGGLE, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_AI_SERVICE, RETROK_UNKNOWN, + RARCH_AI_SERVICE, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_PING_TOGGLE, RETROK_UNKNOWN, + RARCH_NETPLAY_PING_TOGGLE, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_HOST_TOGGLE, RETROK_UNKNOWN, + RARCH_NETPLAY_HOST_TOGGLE, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH, RETROK_UNKNOWN, + RARCH_NETPLAY_GAME_WATCH, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_PLAYER_CHAT, RETROK_UNKNOWN, + RARCH_NETPLAY_PLAYER_CHAT, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_FADE_CHAT_TOGGLE, RETROK_UNKNOWN, + RARCH_NETPLAY_FADE_CHAT_TOGGLE, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_OVERLAY_NEXT, RETROK_UNKNOWN, + RARCH_OVERLAY_NEXT, NO_BTN, NO_BTN, 0, + true + }, + { + NULL, NULL, + AXIS_NONE, AXIS_NONE, + MENU_ENUM_LABEL_VALUE_INPUT_META_OSK, RETROK_UNKNOWN, + RARCH_OSK, NO_BTN, NO_BTN, 0, + true + }, }; #endif diff --git a/configuration.c b/configuration.c index 6ecfc5fe59c9..059eb9236707 100644 --- a/configuration.c +++ b/configuration.c @@ -2179,6 +2179,7 @@ static struct config_bool_setting *populate_settings_bool( SETTING_BOOL("input_remap_binds_enable", &settings->bools.input_remap_binds_enable, true, true, false); SETTING_BOOL("input_remap_sort_by_controller_enable", &settings->bools.input_remap_sort_by_controller_enable, true, false, false); SETTING_BOOL("input_hotkey_device_merge", &settings->bools.input_hotkey_device_merge, true, DEFAULT_INPUT_HOTKEY_DEVICE_MERGE, false); + SETTING_BOOL("input_hotkey_follows_player1", &settings->bools.input_hotkey_follows_player1, true, DEFAULT_INPUT_HOTKEY_FOLLOWS_PLAYER1, false); #ifdef HAVE_MENU SETTING_BOOL("all_users_control_menu", &settings->bools.input_all_users_control_menu, true, DEFAULT_ALL_USERS_CONTROL_MENU, false); SETTING_BOOL("menu_swap_ok_cancel_buttons", &settings->bools.input_menu_swap_ok_cancel_buttons, true, DEFAULT_MENU_SWAP_OK_CANCEL_BUTTONS, false); @@ -6621,6 +6622,7 @@ void input_config_reset_autoconfig_binds(unsigned port) { input_autoconf_binds[port][i].joykey = NO_BTN; input_autoconf_binds[port][i].joyaxis = AXIS_NONE; + input_autoconf_binds[port][i].valid = false; if (input_autoconf_binds[port][i].joykey_label) { @@ -6762,6 +6764,8 @@ void input_config_parse_joy_axis(char *s, bind->joyaxis = AXIS_POS(i_axis); else bind->joyaxis = AXIS_NEG(i_axis); + + bind->valid = true; } } @@ -6855,6 +6859,8 @@ void input_config_parse_joy_button( } else bind->joykey = strtoull(tmp, NULL, 0); + + bind->valid = true; } } diff --git a/configuration.h b/configuration.h index 8f1c49c23a40..57e8f129050a 100644 --- a/configuration.h +++ b/configuration.h @@ -733,6 +733,7 @@ typedef struct settings bool input_turbo_enable; bool input_turbo_allow_dpad; bool input_hotkey_device_merge; + bool input_hotkey_follows_player1; #if defined(HAVE_DINPUT) || defined(HAVE_WINRAWINPUT) bool input_nowinkey_enable; #endif diff --git a/input/input_driver.c b/input/input_driver.c index 11e3e4d42d34..d4c165981573 100644 --- a/input/input_driver.c +++ b/input/input_driver.c @@ -5638,6 +5638,7 @@ static bool input_keys_pressed_other_sources( */ static void input_keys_pressed( unsigned port, + unsigned hotkey_port, bool is_menu, unsigned input_hotkey_block_delay, input_bits_t *p_new_state, @@ -5650,17 +5651,19 @@ static void input_keys_pressed( bool input_hotkey_device_merge) { unsigned i; + /* Autoconf binds are indexed by joy_idx, not frontend port */ + unsigned joy_idx = joypad_info->joy_idx; int32_t ret = 0; input_driver_state_t *input_st = &input_driver_st; bool block_hotkey[RARCH_BIND_LIST_END]; bool any_pressed = false; bool libretro_hotkey_set = - binds[port][RARCH_ENABLE_HOTKEY].joykey != NO_BTN - || binds[port][RARCH_ENABLE_HOTKEY].joyaxis != AXIS_NONE - || input_autoconf_binds[port][RARCH_ENABLE_HOTKEY].joykey != NO_BTN - || input_autoconf_binds[port][RARCH_ENABLE_HOTKEY].joyaxis != AXIS_NONE; + binds_norm->joykey != NO_BTN + || binds_norm->joyaxis != AXIS_NONE + || binds_auto->joykey != NO_BTN + || binds_auto->joyaxis != AXIS_NONE; bool keyboard_hotkey_set = - binds[port][RARCH_ENABLE_HOTKEY].key != RETROK_UNKNOWN; + binds_norm->key != RETROK_UNKNOWN; if (!binds) return; @@ -5669,7 +5672,8 @@ static void input_keys_pressed( && (libretro_hotkey_set || keyboard_hotkey_set)) libretro_hotkey_set = keyboard_hotkey_set = true; - if ( binds[port][RARCH_ENABLE_HOTKEY].valid + if ( (port == hotkey_port) + && (binds_norm->valid || binds_auto->valid) && CHECK_INPUT_DRIVER_BLOCK_HOTKEY(binds_norm, binds_auto)) { if (input_state_wrap( @@ -5731,10 +5735,10 @@ static void input_keys_pressed( * unless 'enable_hotkey' is set in autoconf. */ if ( !any_pressed && !(input_st->flags & INP_FLAG_WAIT_INPUT_RELEASE) - && (input_autoconf_binds[port][RARCH_MENU_TOGGLE].joykey != NO_BTN) - && ( input_autoconf_binds[port][RARCH_ENABLE_HOTKEY].joykey == input_autoconf_binds[port][RARCH_MENU_TOGGLE].joykey - || input_autoconf_binds[port][RARCH_ENABLE_HOTKEY].joykey == NO_BTN) - && ( binds[port][RARCH_MENU_TOGGLE].joykey == input_autoconf_binds[port][RARCH_MENU_TOGGLE].joykey + && (input_autoconf_binds[joy_idx][RARCH_MENU_TOGGLE].joykey != NO_BTN) + && ( input_autoconf_binds[joy_idx][RARCH_ENABLE_HOTKEY].joykey == input_autoconf_binds[joy_idx][RARCH_MENU_TOGGLE].joykey + || input_autoconf_binds[joy_idx][RARCH_ENABLE_HOTKEY].joykey == NO_BTN) + && ( binds[port][RARCH_MENU_TOGGLE].joykey == input_autoconf_binds[joy_idx][RARCH_MENU_TOGGLE].joykey || binds[port][RARCH_MENU_TOGGLE].joykey == NO_BTN)) { /* Ignore keyboard menu toggle button and check @@ -5805,8 +5809,8 @@ static void input_keys_pressed( BIT256_SET_PTR(p_new_state, RARCH_ENABLE_HOTKEY); } - /* Hotkeys are only relevant for first port */ - if (port > 0) + /* Hotkeys are only relevant for the first user or core port */ + if (port != hotkey_port) return; /* Check hotkeys to block keyboard and joypad hotkeys separately. @@ -6777,6 +6781,7 @@ void input_driver_collect_system_input(input_driver_state_t *input_st, unsigned block_delay = settings->uints.input_hotkey_block_delay; uint8_t max_users = settings->uints.input_max_users; uint8_t port = 0; + uint8_t hotkey_port = 0; #ifdef HAVE_MENU bool all_users_control_menu = settings->bools.input_all_users_control_menu; bool display_kb = menu_input_dialog_get_display_kb(); @@ -6791,10 +6796,11 @@ void input_driver_collect_system_input(input_driver_state_t *input_st, for (port = 0; port < (int)max_users; port++) { const struct retro_keybind *binds_norm = &input_config_binds[port][RARCH_ENABLE_HOTKEY]; - const struct retro_keybind *binds_auto = &input_autoconf_binds[port][RARCH_ENABLE_HOTKEY]; + const struct retro_keybind *binds_auto = NULL; joypad_info.joy_idx = settings->uints.input_joypad_index[port]; joypad_info.auto_binds = input_autoconf_binds[joypad_info.joy_idx]; + binds_auto = &input_autoconf_binds[joypad_info.joy_idx][RARCH_ENABLE_HOTKEY]; #ifdef HAVE_MENU if (menu_is_alive) @@ -6879,7 +6885,19 @@ void input_driver_collect_system_input(input_driver_state_t *input_st, } #endif /* HAVE_MENU */ - input_keys_pressed(port, + if (settings->bools.input_hotkey_follows_player1) + { + /* Hotkeys are bound to player 1 (the first user mapped to core port 0), + * even if player 1 is remapped to a different user. */ + hotkey_port = settings->uints.input_remap_port_map[0][0]; + + if (hotkey_port >= MAX_USERS) + hotkey_port = 0; + } + + input_keys_pressed( + port, + hotkey_port, #ifdef HAVE_MENU menu_is_alive, #else diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index d502514a6398..c333347f5932 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -3807,6 +3807,14 @@ MSG_HASH( MENU_ENUM_SUBLABEL_INPUT_HOTKEY_DEVICE_MERGE, "Block all hotkeys from both keyboard and controller device types if either type has 'Hotkey Enable' set." ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_HOTKEY_FOLLOWS_PLAYER1, + "Hotkeys Follow Player 1" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_HOTKEY_FOLLOWS_PLAYER1, + "Hotkeys are bound to core port 1, even if core port 1 is remapped to a different user. Note: keyboard hotkeys will not work if core port 1 is remapped to any user > 1 (keyboard input is from user 1)." + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO, "Menu Toggle (Controller Combo)" diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index aa54592681a2..07a3962e76de 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -491,6 +491,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_meta_netplay_fade_chat_toggle, DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_hotkey_block_delay, MENU_ENUM_SUBLABEL_INPUT_HOTKEY_BLOCK_DELAY) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_hotkey_device_merge, MENU_ENUM_SUBLABEL_INPUT_HOTKEY_DEVICE_MERGE) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_hotkey_follows_player1, MENU_ENUM_SUBLABEL_INPUT_HOTKEY_FOLLOWS_PLAYER1) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_device_type, MENU_ENUM_SUBLABEL_INPUT_DEVICE_TYPE) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_device_index, MENU_ENUM_SUBLABEL_INPUT_DEVICE_INDEX) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_mouse_index, MENU_ENUM_SUBLABEL_INPUT_MOUSE_INDEX) @@ -5084,6 +5085,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_INPUT_HOTKEY_DEVICE_MERGE: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_hotkey_device_merge); break; + case MENU_ENUM_LABEL_INPUT_HOTKEY_FOLLOWS_PLAYER1: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_hotkey_follows_player1); + break; case MENU_ENUM_LABEL_INPUT_USER_1_BINDS: case MENU_ENUM_LABEL_INPUT_USER_2_BINDS: case MENU_ENUM_LABEL_INPUT_USER_3_BINDS: diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index cfdd37541743..8b3de10cbd22 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -7507,6 +7507,10 @@ unsigned menu_displaylist_build_list( MENU_ENUM_LABEL_INPUT_HOTKEY_DEVICE_MERGE, PARSE_ONLY_BOOL, false) == 0) count++; + if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list, + MENU_ENUM_LABEL_INPUT_HOTKEY_FOLLOWS_PLAYER1, + PARSE_ONLY_BOOL, false) == 0) + count++; /* All other binds come last */ for (i = 0; i < RARCH_BIND_LIST_END; i++) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 737bef6092cf..0acdd4b32eb4 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -15528,6 +15528,22 @@ static bool setting_append_list( SD_FLAG_NONE ); + CONFIG_BOOL( + list, list_info, + &settings->bools.input_hotkey_follows_player1, + MENU_ENUM_LABEL_INPUT_HOTKEY_FOLLOWS_PLAYER1, + MENU_ENUM_LABEL_VALUE_INPUT_HOTKEY_FOLLOWS_PLAYER1, + DEFAULT_INPUT_HOTKEY_FOLLOWS_PLAYER1, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_NONE + ); + CONFIG_BOOL( list, list_info, &settings->bools.input_menu_swap_ok_cancel_buttons, diff --git a/msg_hash.h b/msg_hash.h index 519520e5d894..7301c2e34584 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -922,6 +922,7 @@ enum msg_hash_enums MENU_LABEL(INPUT_HOTKEY_BINDS), MENU_LABEL(INPUT_HOTKEY_BLOCK_DELAY), MENU_LABEL(INPUT_HOTKEY_DEVICE_MERGE), + MENU_LABEL(INPUT_HOTKEY_FOLLOWS_PLAYER1), MENU_LABEL(INPUT_SPLIT_JOYCON), MENU_ENUM_LABEL_INPUT_HOTKEY_BINDS_BEGIN,