diff --git a/libretro-common/include/retro_miscellaneous.h b/libretro-common/include/retro_miscellaneous.h index a91a97a1d8..f0dfb5c620 100644 --- a/libretro-common/include/retro_miscellaneous.h +++ b/libretro-common/include/retro_miscellaneous.h @@ -134,6 +134,16 @@ static INLINE bool bits_any_set(uint32_t* ptr, uint32_t count) #define BIT256_GET_PTR(a, bit) BIT256_GET(*a, bit) #define BIT256_CLEAR_ALL_PTR(a) BIT256_CLEAR_ALL(*a) +#define BIT512_SET(a, bit) BIT256_SET(a, bit) +#define BIT512_CLEAR(a, bit) BIT256_CLEAR(a, bit) +#define BIT512_GET(a, bit) BIT256_GET(a, bit) +#define BIT512_CLEAR_ALL(a) BIT256_CLEAR_ALL(a) + +#define BIT512_SET_PTR(a, bit) BIT512_SET(*a, bit) +#define BIT512_CLEAR_PTR(a, bit) BIT512_CLEAR(*a, bit) +#define BIT512_GET_PTR(a, bit) BIT512_GET(*a, bit) +#define BIT512_CLEAR_ALL_PTR(a) BIT512_CLEAR_ALL(*a) + #define BITS_COPY16_PTR(a,bits) \ { \ BIT128_CLEAR_ALL_PTR(a); \ @@ -160,6 +170,12 @@ typedef struct uint32_t data[8]; } retro_bits_t; +/* This struct has 512 bits. */ +typedef struct +{ + uint32_t data[16]; +} retro_bits_512_t; + #ifdef _WIN32 # ifdef _WIN64 # define PRI_SIZET PRIu64 diff --git a/menu/cbs/menu_cbs_scan.c b/menu/cbs/menu_cbs_scan.c index e44defc580..4f88ca7e78 100644 --- a/menu/cbs/menu_cbs_scan.c +++ b/menu/cbs/menu_cbs_scan.c @@ -180,6 +180,9 @@ static int action_scan_input_desc(const char *path, if (target) { + /* Clear mapping bit */ + input_keyboard_mapping_bits(0, target->key); + target->key = RETROK_UNKNOWN; target->joykey = NO_BTN; target->joyaxis = AXIS_NONE; diff --git a/menu/menu_cbs.h b/menu/menu_cbs.h index e005ec5904..1bc6be85a5 100644 --- a/menu/menu_cbs.h +++ b/menu/menu_cbs.h @@ -242,6 +242,8 @@ int core_setting_right(unsigned type, const char *label, int action_right_cheat(unsigned type, const char *label, bool wraparound); +void input_keyboard_mapping_bits(unsigned mode, unsigned key); + /* End of function callbacks */ int menu_cbs_init_bind_left(menu_file_list_cbs_t *cbs, diff --git a/menu/menu_setting.c b/menu/menu_setting.c index c622f32a49..e4e36478d5 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -561,6 +561,9 @@ static int setting_bind_action_start(rarch_setting_t *setting) keybind->joykey = NO_BTN; keybind->joyaxis = AXIS_NONE; + /* Clear old mapping bit */ + input_keyboard_mapping_bits(0, keybind->key); + if (setting->index_offset) def_binds = (struct retro_keybind*)retro_keybinds_rest; @@ -569,6 +572,9 @@ static int setting_bind_action_start(rarch_setting_t *setting) keybind->mbutton = NO_BTN; + /* Store new mapping bit */ + input_keyboard_mapping_bits(1, keybind->key); + return 0; } diff --git a/retroarch.c b/retroarch.c index f70821bdfb..a10d79211f 100644 --- a/retroarch.c +++ b/retroarch.c @@ -797,6 +797,22 @@ static void menu_dialog_reset(menu_dialog_t *p_dialog) p_dialog->current_type = MENU_DIALOG_NONE; } +void input_keyboard_mapping_bits(unsigned mode, unsigned key) +{ + struct rarch_state *p_rarch = &rarch_st; + switch (mode) + { + case 0: + BIT512_CLEAR_PTR(&p_rarch->keyboard_mapping_bits, key); + break; + case 1: + BIT512_SET_PTR(&p_rarch->keyboard_mapping_bits, key); + break; + default: + break; + } +} + static bool menu_input_key_bind_custom_bind_keyboard_cb( void *data, unsigned code) { @@ -807,9 +823,15 @@ static bool menu_input_key_bind_custom_bind_keyboard_cb( uint64_t input_bind_hold_us = settings->uints.input_bind_hold * 1000000; uint64_t input_bind_timeout_us = settings->uints.input_bind_timeout * 1000000; + /* Clear old mapping bit */ + input_keyboard_mapping_bits(0, binds->buffer.key); + /* store key in bind */ binds->buffer.key = (enum retro_key)code; + /* Store new mapping bit */ + input_keyboard_mapping_bits(1, binds->buffer.key); + /* write out the bind */ *(binds->output) = binds->buffer; @@ -21922,6 +21944,7 @@ static void input_driver_poll(void) && !MAPPER_GET_KEY(handle, remap_key)) { handle->key_button[remap_key] = j; + MAPPER_SET_KEY(handle, remap_key); input_keyboard_event(true, remap_key, @@ -21934,10 +21957,10 @@ static void input_driver_poll(void) if (handle->key_button[remap_key] != j) continue; - MAPPER_UNSET_KEY(handle, remap_key); input_keyboard_event(false, remap_key, 0, 0, RETRO_DEVICE_KEYBOARD); + MAPPER_UNSET_KEY(handle, remap_key); } } break; @@ -25463,6 +25486,24 @@ void input_keyboard_event(bool down, unsigned code, else { retro_keyboard_event_t *key_event = &p_rarch->runloop_key_event; + input_mapper_t *handle = p_rarch->input_driver_mapper; + bool block = false; + + if (code == RETROK_UNKNOWN || + key_event == NULL) + return; + + /* Block hotkey+RetroPad mapped keyboard key events, + * but not with game focus and from keyboard device type */ + if (!p_rarch->game_focus_state.enabled) + { + block = BIT512_GET(p_rarch->keyboard_mapping_bits, code); + if (block && MAPPER_GET_KEY(handle, code)) + block = false; + } + + if (block) + return; if (*key_event) (*key_event)(down, code, character, mod); @@ -25531,6 +25572,9 @@ static void input_config_parse_key( && (!string_is_empty(entry->value)) ) bind->key = input_config_translate_str_to_rk(entry->value); + + /* Store mapping bit */ + input_keyboard_mapping_bits(1, bind->key); } static const char *input_config_get_prefix(unsigned user, bool meta) diff --git a/retroarch_data.h b/retroarch_data.h index 6ff8d60e66..81cbe5286e 100644 --- a/retroarch_data.h +++ b/retroarch_data.h @@ -2340,6 +2340,7 @@ struct rarch_state bool main_ui_companion_is_on_foreground; bool keyboard_mapping_blocked; + retro_bits_512_t keyboard_mapping_bits; #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL) bool shader_presets_need_reload;