diff --git a/input/drivers_joypad/xinput_joypad.c b/input/drivers_joypad/xinput_joypad.c index ddfb3d3be7..6caa2abf8d 100644 --- a/input/drivers_joypad/xinput_joypad.c +++ b/input/drivers_joypad/xinput_joypad.c @@ -171,42 +171,26 @@ static INLINE int pad_index_to_xuser_index(unsigned pad) #endif } -/* Generic "XInput" instead of "Xbox 360", because there are - * some other non-xbox third party PC controllers. - */ -static const char* const XBOX_CONTROLLER_NAMES[4] = -{ - "XInput Controller (User 1)", - "XInput Controller (User 2)", - "XInput Controller (User 3)", - "XInput Controller (User 4)" -}; - -static const char* const XBOX_ONE_CONTROLLER_NAMES[4] = -{ - "XBOX One Controller (User 1)", - "XBOX One Controller (User 2)", - "XBOX One Controller (User 3)", - "XBOX One Controller (User 4)" -}; +/* Generic 'XInput' instead of 'Xbox 360', because + * there are some other non-Xbox third party PC + * controllers */ +static const char XBOX_CONTROLLER_NAME[] = "XInput Controller"; static const char *xinput_joypad_name(unsigned pad) { - int xuser = pad_index_to_xuser_index(pad); #ifdef HAVE_DINPUT - /* Use the real controller name for XBOX One controllers since - they are slightly different */ - if (xuser < 0) - return dinput_joypad.name(pad); - - if (strstr(dinput_joypad.name(pad), "Xbox One For Windows")) - return XBOX_ONE_CONTROLLER_NAMES[xuser]; -#endif - - if (xuser < 0) + /* On platforms with dinput support, we are able + * to get a name from the device itself */ + return dinput_joypad.name(pad); +#else + if (pad_index_to_xuser_index(pad) < 0) return NULL; - return XBOX_CONTROLLER_NAMES[xuser]; + /* On platforms without dinput support, no + * device-specific name is available + * > Have to use generic names instead */ + return XBOX_CONTROLLER_NAME; +#endif } #if defined(HAVE_DYNAMIC) && !defined(__WINRT__) diff --git a/input/input_autodetect_builtin.c b/input/input_autodetect_builtin.c index 7196f00dbc..b2e4818ce5 100644 --- a/input/input_autodetect_builtin.c +++ b/input/input_autodetect_builtin.c @@ -40,8 +40,6 @@ #define DECL_AUTOCONF_DEVICE(device, driver, binds) "input_device = \"" device "\"\ninput_driver = \"" driver "\"\n" binds #define DECL_AUTOCONF_PID(pid, vid, driver, binds) "input_product_id = " #pid "\ninput_vendor_id = " #vid "\ninput_driver = \"" driver "\"\n" binds -/* TODO/FIXME - Missing L2/R2 */ - #define SDL2_DEFAULT_BINDS \ DECL_BTN(a, 1) \ DECL_BTN(b, 0) \ @@ -55,6 +53,8 @@ DECL_BTN(left, 13) \ DECL_BTN(right, 14) \ DECL_BTN(l, 9) \ DECL_BTN(r, 10) \ +DECL_AXIS(l2, +4) \ +DECL_AXIS(r2, +5) \ DECL_BTN(l3, 7) \ DECL_BTN(r3, 8) \ DECL_AXIS(l_x_plus, +0) \ @@ -665,14 +665,7 @@ const char* const input_builtin_autoconfs[] = DECL_AUTOCONF_DEVICE("XInput Controller (User 4)", "xdk", XINPUT_DEFAULT_BINDS), #elif defined(_WIN32) #if !defined(__STDC_C89__) && !defined(__STDC_C89_AMENDMENT_1__) - DECL_AUTOCONF_DEVICE("XInput Controller (User 1)", "xinput", XINPUT_DEFAULT_BINDS), - DECL_AUTOCONF_DEVICE("XInput Controller (User 2)", "xinput", XINPUT_DEFAULT_BINDS), - DECL_AUTOCONF_DEVICE("XInput Controller (User 3)", "xinput", XINPUT_DEFAULT_BINDS), - DECL_AUTOCONF_DEVICE("XInput Controller (User 4)", "xinput", XINPUT_DEFAULT_BINDS), - DECL_AUTOCONF_DEVICE("XBOX One Controller (User 1)", "xinput", XINPUT_DEFAULT_BINDS), - DECL_AUTOCONF_DEVICE("XBOX One Controller (User 2)", "xinput", XINPUT_DEFAULT_BINDS), - DECL_AUTOCONF_DEVICE("XBOX One Controller (User 3)", "xinput", XINPUT_DEFAULT_BINDS), - DECL_AUTOCONF_DEVICE("XBOX One Controller (User 4)", "xinput", XINPUT_DEFAULT_BINDS), + DECL_AUTOCONF_DEVICE("XInput Controller", "xinput", XINPUT_DEFAULT_BINDS), #endif #endif #ifdef HAVE_SDL2 diff --git a/tasks/task_autodetect.c b/tasks/task_autodetect.c index 3cf77ce37a..292f89cba7 100644 --- a/tasks/task_autodetect.c +++ b/tasks/task_autodetect.c @@ -42,6 +42,7 @@ typedef struct input_device_info_t device_info; bool autoconfig_enabled; bool suppress_notifcations; + char *driver; char *dir_autoconfig; char *dir_driver_autoconfig; config_file_t *autoconfig_file; @@ -56,6 +57,12 @@ static void free_autoconfig_handle(autoconfig_handle_t *autoconfig_handle) if (!autoconfig_handle) return; + if (autoconfig_handle->driver) + { + free(autoconfig_handle->driver); + autoconfig_handle->driver = NULL; + } + if (autoconfig_handle->dir_autoconfig) { free(autoconfig_handle->dir_autoconfig); @@ -477,34 +484,46 @@ static void input_autoconfigure_connect_handler(retro_task_t *task) match_found = input_autoconfigure_scan_config_files_internal( autoconfig_handle); - /* If we reach this point on Android, attempt - * to search for the internal 'Android Gamepad' - * definition */ -#ifdef ANDROID - if (!match_found && - !string_is_equal(autoconfig_handle->device_info.name, - "Android Gamepad")) + /* If no match was found, attempt to use + * fallback mapping + * > Only enabled for certain drivers */ + if (!match_found) { - char *name_backup = strdup(autoconfig_handle->device_info.name); + const char *fallback_device_name = NULL; - strlcpy(autoconfig_handle->device_info.name, - "Android Gamepad", - sizeof(autoconfig_handle->device_info.name)); + /* Preset fallback device names - must match + * those set in 'input_autodetect_builtin.c' */ + if (string_is_equal(autoconfig_handle->driver, "android")) + fallback_device_name = "Android Gamepad"; + else if (string_is_equal(autoconfig_handle->driver, "xinput")) + fallback_device_name = "XInput Controller"; + else if (string_is_equal(autoconfig_handle->driver, "sdl2")) + fallback_device_name = "Standard Gamepad"; - /* This is not a genuine match - leave - * match_found set to 'false' regardless - * of the outcome */ - input_autoconfigure_scan_config_files_internal( - autoconfig_handle); + if (!string_is_empty(fallback_device_name) && + !string_is_equal(autoconfig_handle->device_info.name, + fallback_device_name)) + { + char *name_backup = strdup(autoconfig_handle->device_info.name); - strlcpy(autoconfig_handle->device_info.name, - name_backup, - sizeof(autoconfig_handle->device_info.name)); + strlcpy(autoconfig_handle->device_info.name, + fallback_device_name, + sizeof(autoconfig_handle->device_info.name)); - free(name_backup); - name_backup = NULL; + /* This is not a genuine match - leave + * match_found set to 'false' regardless + * of the outcome */ + input_autoconfigure_scan_config_files_internal( + autoconfig_handle); + + strlcpy(autoconfig_handle->device_info.name, + name_backup, + sizeof(autoconfig_handle->device_info.name)); + + free(name_backup); + name_backup = NULL; + } } -#endif /* Get display name for task status message */ device_display_name = autoconfig_handle->device_info.display_name; @@ -593,9 +612,6 @@ void input_autoconfigure_connect( bool notification_show_autoconfig = settings ? settings->bools.notification_show_autoconfig : true; task_finder_data_t find_data; - char dir_driver_autoconfig[PATH_MAX_LENGTH]; - - dir_driver_autoconfig[0] = '\0'; if (port >= MAX_INPUT_DEVICES) goto error; @@ -625,6 +641,7 @@ void input_autoconfigure_connect( autoconfig_handle->device_info.name_index = 0; autoconfig_handle->autoconfig_enabled = autoconfig_enabled; autoconfig_handle->suppress_notifcations = !notification_show_autoconfig; + autoconfig_handle->driver = NULL; autoconfig_handle->dir_autoconfig = NULL; autoconfig_handle->dir_driver_autoconfig = NULL; autoconfig_handle->autoconfig_file = NULL; @@ -637,25 +654,37 @@ void input_autoconfigure_connect( strlcpy(autoconfig_handle->device_info.display_name, display_name, sizeof(autoconfig_handle->device_info.display_name)); + if (!string_is_empty(driver)) + autoconfig_handle->driver = strdup(driver); + /* > Have to cache both the base autoconfig directory * and the driver-specific autoconfig directory * - Driver-specific directory is scanned by * default, if available * - If driver-specific directory is unavailable, * we scan the base autoconfig directory as - * a fallback - * Note: fill_pathname_application_special() accesses - * the settings struct internally, so have to call it - * here and not in the task thread */ + * a fallback */ if (!string_is_empty(dir_autoconfig)) + { autoconfig_handle->dir_autoconfig = strdup(dir_autoconfig); - fill_pathname_application_special(dir_driver_autoconfig, - sizeof(dir_driver_autoconfig), - APPLICATION_SPECIAL_DIRECTORY_AUTOCONFIG); - if (!string_is_empty(dir_driver_autoconfig)) - autoconfig_handle->dir_driver_autoconfig = - strdup(dir_driver_autoconfig); + /* 'autoconfig_handle->driver' will only be + * non-NULL if 'driver' is a non-empty string */ + if (autoconfig_handle->driver) + { + char dir_driver_autoconfig[PATH_MAX_LENGTH]; + dir_driver_autoconfig[0] = '\0'; + + /* Generate driver-specific autoconfig directory */ + fill_pathname_join(dir_driver_autoconfig, + dir_autoconfig, autoconfig_handle->driver, + sizeof(dir_driver_autoconfig)); + + if (!string_is_empty(dir_driver_autoconfig)) + autoconfig_handle->dir_driver_autoconfig = + strdup(dir_driver_autoconfig); + } + } /* Bliss-Box shenanigans... */ #ifdef HAVE_BLISSBOX