diff --git a/configuration.c b/configuration.c index 8720d33ccb..9065cd1494 100644 --- a/configuration.c +++ b/configuration.c @@ -2023,6 +2023,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 f452a22bc7..4fc1d9b25a 100644 --- a/configuration.h +++ b/configuration.h @@ -940,6 +940,10 @@ typedef struct settings #ifdef _3DS bool new3ds_speedup_enable; #endif + +#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 4f20b0dbcb..e071fc4c4a 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 5aa389f066..11f924ec7f 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -2597,6 +2597,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 52ba84848b..810c605cb1 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -681,6 +681,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 1cd1db4c2f..65e0a6a552 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -6940,6 +6940,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 1f56f0783e..e7d639a79e 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -13618,6 +13618,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 bd202f926a..3ae2798aa8 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -1058,6 +1058,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,