From 07af575faf0dc4bddee2f381975c3a3b71abf72b Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Mon, 21 Feb 2022 14:13:02 +0100 Subject: [PATCH] Add a configurable workaround for Android reconnecting devices Closes https://github.com/libretro/RetroArch/issues/3414 --- configuration.c | 4 ++++ configuration.h | 4 ++++ input/drivers/android_input.c | 24 ++++++++++++++++++++++-- intl/msg_hash_us.h | 9 +++++++++ menu/cbs/menu_cbs_sublabel.c | 1 + menu/menu_displaylist.c | 6 ++++++ menu/menu_setting.c | 18 ++++++++++++++++++ msg_hash.h | 2 ++ 8 files changed, 66 insertions(+), 2 deletions(-) diff --git a/configuration.c b/configuration.c index 7c725f2e92ff..e1022670bf34 100644 --- a/configuration.c +++ b/configuration.c @@ -2008,6 +2008,10 @@ static struct config_bool_setting *populate_settings_bool( SETTING_BOOL("wifi_enabled", &settings->bools.wifi_enabled, true, DEFAULT_WIFI_ENABLE, false); SETTING_BOOL("gamemode_enable", &settings->bools.gamemode_enable, true, DEFAULT_GAMEMODE_ENABLE, false); +#ifdef ANDROID + SETTING_BOOL("android_input_disconnect_workaround", &settings->bools.android_input_disconnect_workaround, true, false, false); +#endif + *size = count; return tmp; diff --git a/configuration.h b/configuration.h index a9712d441fb0..963e6223ca54 100644 --- a/configuration.h +++ b/configuration.h @@ -919,6 +919,10 @@ typedef struct settings bool ai_service_pause; bool gamemode_enable; + +#ifdef ANDROID + bool android_input_disconnect_workaround; +#endif } bools; } settings_t; diff --git a/input/drivers/android_input.c b/input/drivers/android_input.c index 4f20b0dbcbf6..e071fc4c4a52 100644 --- a/input/drivers/android_input.c +++ b/input/drivers/android_input.c @@ -838,7 +838,6 @@ static int android_input_get_id_port(android_input_t *android, int id, return ret; } -#ifdef HAVE_DYNAMIC /* Returns the index inside android->pad_state */ static int android_input_get_id_index_from_name(android_input_t *android, const char *name) @@ -852,7 +851,25 @@ static int android_input_get_id_index_from_name(android_input_t *android, return -1; } -#endif + +static int android_input_recover_port(android_input_t *android, int id) +{ + char device_name[256] = { 0 }; + int vendorId = 0; + int productId = 0; + settings_t *settings = config_get_ptr(); + + if (!settings->bools.android_input_disconnect_workaround) + return -1; + if (!engine_lookup_name(device_name, &vendorId, + &productId, sizeof(device_name), id)) + return -1; + int ret = android_input_get_id_index_from_name(android, device_name); + if (ret >= 0) + android->pad_states[ret].id = id; + return ret; +} + static void handle_hotplug(android_input_t *android, struct android_app *android_app, int *port, int id, @@ -1195,6 +1212,9 @@ static void android_input_poll_input(android_input_t *android, int id = android_input_get_id(event); int port = android_input_get_id_port(android, id, source); + if (port < 0 && !android_is_keyboard_id(id)) + port = android_input_recover_port(android, id); + if (port < 0 && !android_is_keyboard_id(id)) handle_hotplug(android, android_app, &port, id, source); diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 5c90086df70f..2b698b8ddeec 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -2456,6 +2456,15 @@ MSG_HASH( "Allow any user to control the menu. If disabled, only User 1 can control the menu." ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ANDROID_INPUT_DISCONNECT_WORKAROUND, + "Android disconnect workaround" + ) +MSG_HASH( + MENU_ENUM_LABEL_ANDROID_INPUT_DISCONNECT_WORKAROUND, + "Workaround for controllers disconnecting and reconnecting. Impedes 2 players with the identical controllers." + ) + /* Settings > Input > Hotkeys */ MSG_HASH( diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index e4e32cbd2221..f189f79a0416 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -562,6 +562,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_nowinkey_enable, MENU_ #endif DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_sensors_enable, MENU_ENUM_SUBLABEL_INPUT_SENSORS_ENABLE) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_auto_mouse_grab, MENU_ENUM_SUBLABEL_INPUT_AUTO_MOUSE_GRAB) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_android_input_disconnect_workaround, MENU_ENUM_SUBLABEL_ANDROID_INPUT_DISCONNECT_WORKAROUND) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_auto_game_focus, MENU_ENUM_SUBLABEL_INPUT_AUTO_GAME_FOCUS) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_swap_ok_cancel, MENU_ENUM_SUBLABEL_MENU_INPUT_SWAP_OK_CANCEL) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_pause_libretro, MENU_ENUM_SUBLABEL_PAUSE_LIBRETRO) diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 9d6563c35989..782c59b45067 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -6525,6 +6525,12 @@ unsigned menu_displaylist_build_list( MENU_ENUM_LABEL_INPUT_AUTO_MOUSE_GRAB, PARSE_ONLY_BOOL, false) == 0) count++; +#ifdef ANDROID + if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list, + MENU_ENUM_LABEL_ANDROID_INPUT_DISCONNECT_WORKAROUND, + PARSE_ONLY_BOOL, false) == 0) + count++; +#endif if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list, MENU_ENUM_LABEL_INPUT_AUTO_GAME_FOCUS, PARSE_ONLY_UINT, false) == 0) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 13a97f60026b..afcd23b72967 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -13406,6 +13406,24 @@ static bool setting_append_list( SD_FLAG_NONE ); +#ifdef ANDROID + CONFIG_BOOL( + list, list_info, + &settings->bools.android_input_disconnect_workaround, + MENU_ENUM_LABEL_ANDROID_INPUT_DISCONNECT_WORKAROUND, + MENU_ENUM_LABEL_VALUE_ANDROID_INPUT_DISCONNECT_WORKAROUND, + false, + 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 + ); +#endif + CONFIG_UINT( list, list_info, &settings->uints.input_auto_game_focus, diff --git a/msg_hash.h b/msg_hash.h index 9de5cb63b599..4deb5bfdb1f4 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -1041,6 +1041,8 @@ enum msg_hash_enums MENU_LABEL(QUIT_PRESS_TWICE), MENU_LABEL(QUIT_ON_CLOSE_CONTENT), + MENU_LABEL(ANDROID_INPUT_DISCONNECT_WORKAROUND), + MENU_ENUM_LABEL_VALUE_QUIT_ON_CLOSE_CONTENT_DISABLED, MENU_ENUM_LABEL_VALUE_QUIT_ON_CLOSE_CONTENT_ENABLED, MENU_ENUM_LABEL_VALUE_QUIT_ON_CLOSE_CONTENT_CLI,