From 05844c649faa2e233819b1e6cf5bae29a0795ae9 Mon Sep 17 00:00:00 2001 From: zoltanvb <101990835+zoltanvb@users.noreply.github.com> Date: Thu, 12 Sep 2024 20:50:46 +0200 Subject: [PATCH] Autoconfig extension with alternative name/vid/pid (#16990) If there are several variants of a controller, but their button layout is exactly the same, allow alternative identifiers, e.g.: input_device_alt1 input_vendor_id_alt3 input_product_id_alt9 --- tasks/task_autodetect.c | 92 ++++++++++++------- tests-other/autoconf/TestpadD_alternative.cfg | 34 +++++++ ..._input_joypad_alternative_autoconfig.ratst | 18 ++++ .../testinput_alternative_autoconfig.cfg | 19 ++++ 4 files changed, 130 insertions(+), 33 deletions(-) create mode 100644 tests-other/autoconf/TestpadD_alternative.cfg create mode 100644 tests-other/test_input_joypad_alternative_autoconfig.ratst create mode 100644 tests-other/testinput_alternative_autoconfig.cfg diff --git a/tasks/task_autodetect.c b/tasks/task_autodetect.c index 161ec00179c..b029166e2c7 100644 --- a/tasks/task_autodetect.c +++ b/tasks/task_autodetect.c @@ -112,51 +112,77 @@ static unsigned input_autoconfigure_get_config_file_affinity( autoconfig_handle_t *autoconfig_handle, config_file_t *config) { - int tmp_int = 0; - uint16_t config_vid = 0; - uint16_t config_pid = 0; - bool pid_match = false; - unsigned affinity = 0; - struct config_entry_list - *entry = NULL; - - /* Parse config file */ - if (config_get_int(config, "input_vendor_id", &tmp_int)) - config_vid = (uint16_t)tmp_int; + int i, tmp_int; + uint16_t config_vid; + uint16_t config_pid; + bool pid_match = false; + unsigned affinity; + unsigned max_affinity = 0; + struct config_entry_list *entry = NULL; + char config_key[30]; + char config_key_postfix[7]; + + /* One main entry and up to 9 alternatives */ + for (i=0 ; i < 10; i++) + { + config_vid = 0; + config_pid = 0; + tmp_int = 0; + affinity = 0; - if (config_get_int(config, "input_product_id", &tmp_int)) - config_pid = (uint16_t)tmp_int; + if (i == 0) + config_key_postfix[0] = '\0'; + else + snprintf(config_key_postfix, sizeof(config_key_postfix), + "_alt%d",i); + + /* Parse config file */ + snprintf(config_key, sizeof(config_key), + "input_vendor_id%s",config_key_postfix); + if (config_get_int(config, config_key, &tmp_int)) + config_vid = (uint16_t)tmp_int; + + snprintf(config_key, sizeof(config_key), + "input_product_id%s",config_key_postfix); + if (config_get_int(config, config_key, &tmp_int)) + config_pid = (uint16_t)tmp_int; /* > Bliss-Box shenanigans... */ #ifdef HAVE_BLISSBOX - if (autoconfig_handle->device_info.vid == BLISSBOX_VID) - config_pid = BLISSBOX_PID; + if (autoconfig_handle->device_info.vid == BLISSBOX_VID) + config_pid = BLISSBOX_PID; #endif - /* Check for matching VID+PID */ - pid_match = (autoconfig_handle->device_info.vid == config_vid) - && (autoconfig_handle->device_info.pid == config_pid) - && (autoconfig_handle->device_info.vid != 0) - && (autoconfig_handle->device_info.pid != 0); + /* Check for matching VID+PID */ + pid_match = (autoconfig_handle->device_info.vid == config_vid) + && (autoconfig_handle->device_info.pid == config_pid) + && (autoconfig_handle->device_info.vid != 0) + && (autoconfig_handle->device_info.pid != 0); - /* > More Bliss-Box shenanigans... */ + /* > More Bliss-Box shenanigans... */ #ifdef HAVE_BLISSBOX - pid_match = pid_match - && (autoconfig_handle->device_info.vid != BLISSBOX_VID) - && (autoconfig_handle->device_info.pid != BLISSBOX_PID); + pid_match = pid_match + && (autoconfig_handle->device_info.vid != BLISSBOX_VID) + && (autoconfig_handle->device_info.pid != BLISSBOX_PID); #endif - if (pid_match) - affinity += 3; + if (pid_match) + affinity += 3; - /* Check for matching device name */ - if ( (entry = config_get_entry(config, "input_device")) - && !string_is_empty(entry->value) - && string_is_equal(entry->value, - autoconfig_handle->device_info.name)) - affinity += 2; + /* Check for matching device name */ + snprintf(config_key, sizeof(config_key), + "input_device%s",config_key_postfix); + if ( (entry = config_get_entry(config, config_key)) + && !string_is_empty(entry->value) + && string_is_equal(entry->value, + autoconfig_handle->device_info.name)) + affinity += 2; + + if (max_affinity < affinity) + max_affinity = affinity; + } - return affinity; + return max_affinity; } /* 'Attaches' specified autoconfig file to autoconfig diff --git a/tests-other/autoconf/TestpadD_alternative.cfg b/tests-other/autoconf/TestpadD_alternative.cfg new file mode 100644 index 00000000000..5e978627fe3 --- /dev/null +++ b/tests-other/autoconf/TestpadD_alternative.cfg @@ -0,0 +1,34 @@ +input_driver = "test" +input_device = "Test joypad device D" +input_vendor_id = 1 +input_product_id = 2 +input_device_alt1 = "Test joypad device E" +input_device_alt8 = "Test joypad device F" +input_vendor_id_alt8 = 21 +input_product_id_alt8 = 22 +input_device_display_name = "Test joypad device D/E/F" +input_b_btn = "0" +input_y_btn = "1" +input_select_btn = "2" +input_start_btn = "3" +input_up_btn = "4" +input_down_btn = "5" +input_left_btn = "6" +input_right_btn = "7" +input_a_btn = "8" +input_x_btn = "9" +input_l_btn = "10" +input_r_btn = "11" +input_l2_btn = "12" +input_r2_btn = "13" +input_l3_btn = "14" +input_r3_btn = "15" +input_l_x_plus_axis = "+0" +input_l_x_minus_axis = "-0" +input_l_y_plus_axis = "+1" +input_l_y_minus_axis = "-1" +input_r_x_plus_axis = "+2" +input_r_x_minus_axis = "-2" +input_r_y_plus_axis = "+3" +input_r_y_minus_axis = "-3" + diff --git a/tests-other/test_input_joypad_alternative_autoconfig.ratst b/tests-other/test_input_joypad_alternative_autoconfig.ratst new file mode 100644 index 00000000000..e95b59ee3c6 --- /dev/null +++ b/tests-other/test_input_joypad_alternative_autoconfig.ratst @@ -0,0 +1,18 @@ +[ +{ + "action": 1, + "param_num": 0, + "param_str": "(0001:0002) Test joypad device D", + "frame": 0 +}, +{ + "action": 1, + "param_num": 1, + "param_str": "(0003:0004) Test joypad device E" +}, +{ + "action": 1, + "param_num": 2, + "param_str": "(0015:0016) Test joypad device X" +} +] diff --git a/tests-other/testinput_alternative_autoconfig.cfg b/tests-other/testinput_alternative_autoconfig.cfg new file mode 100644 index 00000000000..091fecb3945 --- /dev/null +++ b/tests-other/testinput_alternative_autoconfig.cfg @@ -0,0 +1,19 @@ +# Test configuration file to be used with --appendconfig. +# Sets up joypad driver, test input file for the joypad driver, +# logging and autoconfig dir, and prevents saving. +# Usage: +# retroarch --appendconfig tests-other/testinput_alternative_autoconfig.cfg\|tests-other/all_binds_empty.cfg + +# Test scenario: +# - A device is connected with autoconfig profile +# - A second device is connected which matches autoconfig profile alt1 +# - A third device is connected which matches autoconfig profile alt8 (only by vid/pid) +# - VALIDATE: check that Player 1..3 have "Test joypad D/E/F" configured + +input_joypad_driver = "test" +test_input_file_joypad = "tests-other/test_input_joypad_alternative_autoconfig.ratst" +joypad_autoconfig_dir = "tests-other/autoconf" +frontend_log_level = "0" +libretro_log_level = "0" +log_verbosity = "true" +config_save_on_exit = "false"