Merge pull request #12534 from jdgleaver/input-port-remapping

Add support for mapping multiple controllers to a single input device
This commit is contained in:
Autechre 2021-06-21 15:28:34 +02:00 committed by GitHub
commit 0a75b51b29
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 838 additions and 289 deletions

View File

@ -2435,10 +2435,8 @@ void config_set_defaults(void *data)
#endif
input_config_reset();
#ifdef HAVE_CONFIGFILE
input_remapping_deinit();
input_remapping_set_defaults();
#endif
input_remapping_set_defaults(false);
/* Verify that binds are in proper order. */
for (i = 0; i < MAX_USERS; i++)
@ -2461,7 +2459,7 @@ void config_set_defaults(void *data)
for (i = 0; i < MAX_USERS; i++)
{
settings->uints.input_joypad_map[i] = i;
settings->uints.input_joypad_index[i] = i;
#ifdef SWITCH /* Switch prefered default dpad mode */
settings->uints.input_analog_dpad_mode[i] = ANALOG_DPAD_LSTICK;
#else
@ -3196,7 +3194,7 @@ static bool config_load_file(global_t *global,
buf[0] = '\0';
snprintf(buf, sizeof(buf), "input_player%u_joypad_index", i + 1);
CONFIG_GET_INT_BASE(conf, settings, uints.input_joypad_map[i], buf);
CONFIG_GET_INT_BASE(conf, settings, uints.input_joypad_index[i], buf);
snprintf(buf, sizeof(buf), "input_player%u_analog_dpad_mode", i + 1);
CONFIG_GET_INT_BASE(conf, settings, uints.input_analog_dpad_mode[i], buf);
@ -3856,9 +3854,7 @@ bool config_load_remap(const char *directory_input_remapping,
FILE_PATH_REMAP_EXTENSION,
sizeof(game_path));
#ifdef HAVE_CONFIGFILE
input_remapping_set_defaults();
#endif
input_remapping_set_defaults(false);
/* If a game remap file exists, load it. */
if ((new_conf = config_file_new_from_path_to_string(game_path)))
@ -4229,7 +4225,7 @@ bool config_save_file(const char *path)
snprintf(cfg, sizeof(cfg), "input_device_p%u", i + 1);
config_set_int(conf, cfg, settings->uints.input_device[i]);
snprintf(cfg, sizeof(cfg), "input_player%u_joypad_index", i + 1);
config_set_int(conf, cfg, settings->uints.input_joypad_map[i]);
config_set_int(conf, cfg, settings->uints.input_joypad_index[i]);
snprintf(cfg, sizeof(cfg), "input_libretro_device_p%u", i + 1);
config_set_int(conf, cfg, input_config_get_device(i));
snprintf(cfg, sizeof(cfg), "input_player%u_analog_dpad_mode", i + 1);
@ -4492,11 +4488,11 @@ bool config_save_overrides(enum override_type type, void *data)
config_set_int(conf, cfg, overrides->uints.input_device[i]);
}
if (settings->uints.input_joypad_map[i]
!= overrides->uints.input_joypad_map[i])
if (settings->uints.input_joypad_index[i]
!= overrides->uints.input_joypad_index[i])
{
snprintf(cfg, sizeof(cfg), "input_player%u_joypad_index", i + 1);
config_set_int(conf, cfg, overrides->uints.input_joypad_map[i]);
config_set_int(conf, cfg, overrides->uints.input_joypad_index[i]);
}
}
@ -4609,7 +4605,7 @@ bool input_remapping_load_file(void *data, const char *path)
if (!string_is_empty(global->name.remapfile))
{
input_remapping_deinit();
input_remapping_set_defaults();
input_remapping_set_defaults(false);
}
global->name.remapfile = strdup(path);
@ -4617,9 +4613,6 @@ bool input_remapping_load_file(void *data, const char *path)
{
char s1[32], s2[32], s3[32];
global->old_analog_dpad_mode[i] = settings->uints.input_analog_dpad_mode[i];
global->old_libretro_device[i] = settings->uints.input_libretro_device[i];
s1[0] = '\0';
s2[0] = '\0';
s3[0] = '\0';
@ -4705,8 +4698,18 @@ bool input_remapping_load_file(void *data, const char *path)
snprintf(s1, sizeof(s1), "input_libretro_device_p%u", i + 1);
CONFIG_GET_INT_BASE(conf, settings, uints.input_libretro_device[i], s1);
snprintf(s1, sizeof(s1), "input_remap_port_p%u", i + 1);
CONFIG_GET_INT_BASE(conf, settings, uints.input_remap_ports[i], s1);
}
input_remapping_update_port_map();
/* Whenever a remap file is loaded, subsequent
* changes to global remap-related parameters
* must be reset at the next core deinitialisation */
input_remapping_enable_global_config_restore();
return true;
}
@ -4745,14 +4748,38 @@ bool input_remapping_save_file(const char *path)
return false;
}
for (i = 0; i < max_users; i++)
for (i = 0; i < MAX_USERS; i++)
{
char s1[32], s2[32], s3[32];
bool skip_port = true;
char s1[32];
char s2[32];
char s3[32];
s1[0] = '\0';
s2[0] = '\0';
s3[0] = '\0';
/* We must include all mapped ports + all those
* with an index less than max_users */
if (i < max_users)
skip_port = false;
else
{
/* Check whether current port is mapped
* to an input device */
for (j = 0; j < max_users; j++)
{
if (i == settings->uints.input_remap_ports[j])
{
skip_port = false;
break;
}
}
}
if (skip_port)
continue;
snprintf(s1, sizeof(s1), "input_player%u_btn", i + 1);
snprintf(s2, sizeof(s2), "input_player%u_key", i + 1);
snprintf(s3, sizeof(s3), "input_player%u_stk", i + 1);
@ -4825,8 +4852,12 @@ bool input_remapping_save_file(const char *path)
snprintf(s1, sizeof(s1), "input_libretro_device_p%u", i + 1);
config_set_int(conf, s1, input_config_get_device(i));
snprintf(s1, sizeof(s1), "input_player%u_analog_dpad_mode", i + 1);
config_set_int(conf, s1, settings->uints.input_analog_dpad_mode[i]);
snprintf(s1, sizeof(s1), "input_remap_port_p%u", i + 1);
config_set_int(conf, s1, settings->uints.input_remap_ports[i]);
}
ret = config_file_write(conf, remap_file, true);

View File

@ -122,7 +122,7 @@ typedef struct settings
unsigned placeholder;
unsigned input_split_joycon[MAX_USERS];
unsigned input_joypad_map[MAX_USERS];
unsigned input_joypad_index[MAX_USERS];
unsigned input_device[MAX_USERS];
unsigned input_mouse_index[MAX_USERS];
/* Set by autoconfiguration in joypad_autoconfig_dir.
@ -130,9 +130,10 @@ typedef struct settings
unsigned input_libretro_device[MAX_USERS];
unsigned input_analog_dpad_mode[MAX_USERS];
unsigned input_keymapper_ids[MAX_USERS][RARCH_CUSTOM_BIND_LIST_END];
unsigned input_remap_ports[MAX_USERS];
unsigned input_remap_ids[MAX_USERS][RARCH_CUSTOM_BIND_LIST_END];
unsigned input_keymapper_ids[MAX_USERS][RARCH_CUSTOM_BIND_LIST_END];
unsigned input_remap_port_map[MAX_USERS][MAX_USERS + 1];
unsigned led_map[MAX_LEDS];

View File

@ -220,7 +220,7 @@ static void handle_hotplug(unsigned port, uint32_t ptype)
static void check_port0_active(uint8_t pad_count)
{
settings_t *settings = config_get_ptr();
int idx = settings->uints.input_joypad_map[0];
int idx = settings->uints.input_joypad_index[0];
if(pad_count < 2 && idx != 0)
{
@ -229,7 +229,7 @@ static void check_port0_active(uint8_t pad_count)
#else
pad_type[0] = WPAD_EXP_GAMECUBE;
#endif
settings->uints.input_joypad_map[0] = 0;
settings->uints.input_joypad_index[0] = 0;
input_autoconfigure_connect(
gx_joypad_name(0),

View File

@ -48,9 +48,33 @@ bool input_remapping_save_file(const char *path);
bool input_remapping_remove_file(const char *path,
const char *dir_input_remapping);
void input_remapping_deinit(void);
/* Caches any global configuration settings that
* should not be overwritten by input remap
* changes made while content is running.
* Must be called on each core init. */
void input_remapping_cache_global_config(void);
/* Sets flags to enable the restoration of
* global configuration settings from the
* internal cache. Should be called independently
* from 'input_remapping_cache_global_config()'.
* Must be called:
* - Whenever content is loaded
* - Whenever a remap file is loaded */
void input_remapping_enable_global_config_restore(void);
/* Restores any cached global configuration settings
* *if* 'input_remapping_enable_global_config_restore()'
* has been called.
* Must be called on core deint.
* If 'clear_cache' is true, function becomes a NOOP
* until the next time input_remapping_cache_global_config()
* and input_remapping_enable_global_config_restore()
* are called. */
void input_remapping_restore_global_config(bool clear_cache);
void input_remapping_set_defaults(void);
void input_remapping_update_port_map(void);
void input_remapping_deinit(void);
void input_remapping_set_defaults(bool clear_cache);
RETRO_END_DECLS

View File

@ -1490,6 +1490,22 @@ MSG_HASH(
MENU_ENUM_LABEL_INPUT_LIBRETRO_DEVICE,
"input_libretro_device_p%u"
)
MSG_HASH(
MENU_ENUM_LABEL_INPUT_PLAYER_ANALOG_DPAD_MODE,
"input_player%u_analog_dpad_mode"
)
MSG_HASH(
MENU_ENUM_LABEL_INPUT_DEVICE_INDEX,
"input_device_p%u"
)
MSG_HASH(
MENU_ENUM_LABEL_INPUT_MOUSE_INDEX,
"input_player%u_mouse_index"
)
MSG_HASH(
MENU_ENUM_LABEL_INPUT_REMAP_PORT,
"input_remap_port_p%u"
)
MSG_HASH(
MENU_ENUM_LABEL_INPUT_MAX_USERS,
"input_max_users"
@ -1534,10 +1550,6 @@ MSG_HASH(
MENU_ENUM_LABEL_INPUT_OVERLAY_AUTO_SCALE,
"input_overlay_auto_scale"
)
MSG_HASH(
MENU_ENUM_LABEL_INPUT_PLAYER_ANALOG_DPAD_MODE,
"input_player%u_analog_dpad_mode"
)
MSG_HASH(
MENU_ENUM_LABEL_INPUT_POLL_TYPE_BEHAVIOR,
"input_poll_type_behavior"

View File

@ -2668,6 +2668,14 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_INPUT_DEVICE_INDEX,
"Device Index"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_INPUT_REMAP_PORT,
"Mapped Port"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_INPUT_REMAP_PORT,
"Specifies which 'core' port (typically player number) will receive input from frontend controller port %u."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_INPUT_BIND_ALL,
"Set All Controls"

View File

@ -709,20 +709,20 @@ static void menu_action_setting_disp_set_label_input_desc(
char *s2, size_t len2)
{
unsigned remap_idx;
settings_t *settings = config_get_ptr();
const char* descriptor = NULL;
unsigned user_idx = (type - MENU_SETTINGS_INPUT_DESC_BEGIN) / (RARCH_FIRST_CUSTOM_BIND + 8);
unsigned btn_idx = (type - MENU_SETTINGS_INPUT_DESC_BEGIN) - (RARCH_FIRST_CUSTOM_BIND + 8) * user_idx;
unsigned mapped_port;
settings_t *settings = config_get_ptr();
const char* descriptor = NULL;
unsigned user_idx = (type - MENU_SETTINGS_INPUT_DESC_BEGIN) / (RARCH_FIRST_CUSTOM_BIND + 8);
unsigned btn_idx = (type - MENU_SETTINGS_INPUT_DESC_BEGIN) - (RARCH_FIRST_CUSTOM_BIND + 8) * user_idx;
if (!settings)
return;
remap_idx =
settings->uints.input_remap_ids[user_idx][btn_idx];
mapped_port = settings->uints.input_remap_ports[user_idx];
remap_idx = settings->uints.input_remap_ids[user_idx][btn_idx];
if (remap_idx != RARCH_UNMAPPED)
descriptor =
runloop_get_system_info()->input_desc_btn[user_idx][remap_idx];
descriptor = runloop_get_system_info()->input_desc_btn[mapped_port][remap_idx];
s[0] = '-';
s[1] = '-';
@ -754,7 +754,7 @@ static void menu_action_setting_disp_set_label_input_desc_kbd(
char desc[PATH_MAX_LENGTH];
unsigned key_id, btn_idx;
unsigned remap_id;
unsigned user_idx = 0;
unsigned user_idx;
settings_t *settings = config_get_ptr();
@ -763,8 +763,7 @@ static void menu_action_setting_disp_set_label_input_desc_kbd(
user_idx = (type - MENU_SETTINGS_INPUT_DESC_KBD_BEGIN) / RARCH_ANALOG_BIND_LIST_END;
btn_idx = (type - MENU_SETTINGS_INPUT_DESC_KBD_BEGIN) - RARCH_ANALOG_BIND_LIST_END * user_idx;
remap_id =
settings->uints.input_keymapper_ids[user_idx][btn_idx];
remap_id = settings->uints.input_keymapper_ids[user_idx][btn_idx];
for (key_id = 0; key_id < RARCH_MAX_KEYS - 1; key_id++)
{

View File

@ -136,13 +136,18 @@ static int action_left_input_desc(unsigned type, const char *label,
{
rarch_system_info_t *system = runloop_get_system_info();
settings_t *settings = config_get_ptr();
unsigned btn_idx, user_idx, remap_idx, bind_idx;
unsigned btn_idx;
unsigned user_idx;
unsigned remap_idx;
unsigned bind_idx;
unsigned mapped_port;
if (!settings || !system)
return 0;
user_idx = (type - MENU_SETTINGS_INPUT_DESC_BEGIN) / (RARCH_FIRST_CUSTOM_BIND + 8);
btn_idx = (type - MENU_SETTINGS_INPUT_DESC_BEGIN) - (RARCH_FIRST_CUSTOM_BIND + 8) * user_idx;
user_idx = (type - MENU_SETTINGS_INPUT_DESC_BEGIN) / (RARCH_FIRST_CUSTOM_BIND + 8);
btn_idx = (type - MENU_SETTINGS_INPUT_DESC_BEGIN) - (RARCH_FIRST_CUSTOM_BIND + 8) * user_idx;
mapped_port = settings->uints.input_remap_ports[user_idx];
if (settings->uints.input_remap_ids[user_idx][btn_idx] == RARCH_UNMAPPED)
settings->uints.input_remap_ids[user_idx][btn_idx] = RARCH_CUSTOM_BIND_LIST_END - 1;
@ -176,7 +181,7 @@ static int action_left_input_desc(unsigned type, const char *label,
also skip all the axes until analog remapping is implemented */
if (remap_idx != RARCH_UNMAPPED)
{
if ((string_is_empty(system->input_desc_btn[user_idx][remap_idx]) && remap_idx < RARCH_CUSTOM_BIND_LIST_END) /*||
if ((string_is_empty(system->input_desc_btn[mapped_port][remap_idx]) && remap_idx < RARCH_CUSTOM_BIND_LIST_END) /*||
(remap_idx >= RARCH_FIRST_CUSTOM_BIND && remap_idx < RARCH_CUSTOM_BIND_LIST_END)*/)
action_left_input_desc(type, label, wraparound);
}

View File

@ -3411,32 +3411,30 @@ static int generic_action_ok_remap_file_operation(const char *path,
{
if (input_remapping_remove_file(file, path_dir_input_remapping))
{
#ifdef HAVE_CONFIGFILE
switch (action_type)
{
case ACTION_OK_REMAP_FILE_REMOVE_CORE:
if (rarch_ctl(RARCH_CTL_IS_REMAPS_CORE_ACTIVE, NULL))
{
input_remapping_deinit();
input_remapping_set_defaults();
input_remapping_set_defaults(false);
}
break;
case ACTION_OK_REMAP_FILE_REMOVE_GAME:
if (rarch_ctl(RARCH_CTL_IS_REMAPS_GAME_ACTIVE, NULL))
{
input_remapping_deinit();
input_remapping_set_defaults();
input_remapping_set_defaults(false);
}
break;
case ACTION_OK_REMAP_FILE_REMOVE_CONTENT_DIR:
if (rarch_ctl(RARCH_CTL_IS_REMAPS_CONTENT_DIR_ACTIVE, NULL))
{
input_remapping_deinit();
input_remapping_set_defaults();
input_remapping_set_defaults(false);
}
break;
}
#endif
runloop_msg_queue_push(
msg_hash_to_str(MSG_REMAP_FILE_REMOVED_SUCCESSFULLY),
@ -6520,7 +6518,7 @@ static int action_ok_push_dropdown_item_input_device_index(const char *path,
if (!setting)
return menu_cbs_exit();
settings->uints.input_joypad_map[setting->index_offset] = (unsigned)entry_idx;
settings->uints.input_joypad_index[setting->index_offset] = (unsigned)entry_idx;
return action_cancel_pop_default(NULL, NULL, 0, 0);
}

View File

@ -177,13 +177,18 @@ static int action_right_input_desc(unsigned type, const char *label,
{
rarch_system_info_t *system = runloop_get_system_info();
settings_t *settings = config_get_ptr();
unsigned btn_idx, user_idx, remap_idx, bind_idx;
unsigned btn_idx;
unsigned user_idx;
unsigned remap_idx;
unsigned bind_idx;
unsigned mapped_port;
if (!settings || !system)
return 0;
user_idx = (type - MENU_SETTINGS_INPUT_DESC_BEGIN) / (RARCH_FIRST_CUSTOM_BIND + 8);
btn_idx = (type - MENU_SETTINGS_INPUT_DESC_BEGIN) - (RARCH_FIRST_CUSTOM_BIND + 8) * user_idx;
user_idx = (type - MENU_SETTINGS_INPUT_DESC_BEGIN) / (RARCH_FIRST_CUSTOM_BIND + 8);
btn_idx = (type - MENU_SETTINGS_INPUT_DESC_BEGIN) - (RARCH_FIRST_CUSTOM_BIND + 8) * user_idx;
mapped_port = settings->uints.input_remap_ports[user_idx];
remap_idx = settings->uints.input_remap_ids[user_idx][btn_idx];
for (bind_idx = 0; bind_idx < RARCH_ANALOG_BIND_LIST_END; bind_idx++)
@ -221,7 +226,7 @@ static int action_right_input_desc(unsigned type, const char *label,
also skip all the axes until analog remapping is implemented */
if (remap_idx != RARCH_UNMAPPED)
{
if ((string_is_empty(system->input_desc_btn[user_idx][remap_idx]) && remap_idx < RARCH_CUSTOM_BIND_LIST_END))
if ((string_is_empty(system->input_desc_btn[mapped_port][remap_idx]) && remap_idx < RARCH_CUSTOM_BIND_LIST_END))
action_right_input_desc(type, label, wraparound);
}

View File

@ -168,8 +168,8 @@ static int action_scan_input_desc(const char *path,
{
settings_t *settings = config_get_ptr();
inp_desc_user = atoi(label);
/* Skip 'Device Type' and 'Analog to Digital Type' */
key = (unsigned)(idx - 2);
/* Skip 'Device Type', 'Analog to Digital Type' and 'Mapped Port' */
key = (unsigned)(idx - 3);
/* Select the reorderer bind */
key =
(key < RARCH_ANALOG_BIND_LIST_END) ? input_config_bind_order[key] : key;

View File

@ -80,10 +80,8 @@ static int action_start_remap_file_load(
const char *path, const char *label,
unsigned type, size_t idx, size_t entry_idx)
{
#ifdef HAVE_CONFIGFILE
input_remapping_deinit();
input_remapping_set_defaults();
#endif
input_remapping_set_defaults(false);
return 0;
}
@ -193,20 +191,24 @@ static int action_start_input_desc(
rarch_system_info_t *system = runloop_get_system_info();
unsigned user_idx;
unsigned btn_idx;
unsigned mapped_port;
(void)label;
if (!settings || !system)
return 0;
user_idx = (type - MENU_SETTINGS_INPUT_DESC_BEGIN) / (RARCH_FIRST_CUSTOM_BIND + 8);
btn_idx = (type - MENU_SETTINGS_INPUT_DESC_BEGIN) - (RARCH_FIRST_CUSTOM_BIND + 8) * user_idx;
user_idx = (type - MENU_SETTINGS_INPUT_DESC_BEGIN) / (RARCH_FIRST_CUSTOM_BIND + 8);
btn_idx = (type - MENU_SETTINGS_INPUT_DESC_BEGIN) - (RARCH_FIRST_CUSTOM_BIND + 8) * user_idx;
mapped_port = settings->uints.input_remap_ports[user_idx];
if ((user_idx >= MAX_USERS) || (btn_idx >= RARCH_CUSTOM_BIND_LIST_END))
if ((user_idx >= MAX_USERS) ||
(mapped_port >= MAX_USERS) ||
(btn_idx >= RARCH_CUSTOM_BIND_LIST_END))
return 0;
/* Check whether core has defined this input */
if (!string_is_empty(system->input_desc_btn[user_idx][btn_idx]))
if (!string_is_empty(system->input_desc_btn[mapped_port][btn_idx]))
{
const struct retro_keybind *keyptr = &input_config_binds[user_idx][btn_idx];
settings->uints.input_remap_ids[user_idx][btn_idx] = keyptr->id;

View File

@ -1199,20 +1199,69 @@ static int action_bind_sublabel_remap_sublabel(
const char *label, const char *path,
char *s, size_t len)
{
unsigned offset = (type - MENU_SETTINGS_INPUT_DESC_BEGIN)
/ (RARCH_FIRST_CUSTOM_BIND + 8);
settings_t *settings = config_get_ptr();
unsigned port = (type - MENU_SETTINGS_INPUT_DESC_BEGIN)
/ (RARCH_FIRST_CUSTOM_BIND + 8);
if (!settings || (port >= MAX_USERS))
return 0;
/* Device name is set per-port
* If the user changes the device index for
* a port, then we are effectively changing
* the port to which the corresponding
* controller is connected... */
port = settings->uints.input_joypad_index[port];
snprintf(s, len, "%s #%d: %s",
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PORT),
offset + 1,
input_config_get_device_display_name(offset) ?
input_config_get_device_display_name(offset) :
(input_config_get_device_name(offset) ?
input_config_get_device_name(offset) :
port + 1,
input_config_get_device_display_name(port) ?
input_config_get_device_display_name(port) :
(input_config_get_device_name(port) ?
input_config_get_device_name(port) :
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE)));
return 0;
}
static int action_bind_sublabel_input_remap_port(
file_list_t *list,
unsigned type, unsigned i,
const char *label, const char *path,
char *s, size_t len)
{
unsigned display_port = 0;
menu_entry_t entry;
MENU_ENTRY_INIT(entry);
entry.path_enabled = false;
entry.label_enabled = true;
entry.rich_label_enabled = false;
entry.value_enabled = false;
entry.sublabel_enabled = false;
menu_entry_get(&entry, 0, i, NULL, false);
/* We need the actual frontend port index.
* This is difficult to obtain here - the only
* way to get it is to parse the entry label
* (input_remap_port_p<port_index+1>) */
if (string_is_empty(entry.label) ||
(sscanf(entry.label,
msg_hash_to_str(MENU_ENUM_LABEL_INPUT_REMAP_PORT),
&display_port) != 1) ||
(display_port >= MAX_USERS + 1))
return 0;
snprintf(s, len,
msg_hash_to_str(MENU_ENUM_SUBLABEL_INPUT_REMAP_PORT),
display_port);
/* We can safely cache the sublabel here, since
* frontend port index cannot change while the
* current menu is displayed */
return 1;
}
#ifdef HAVE_CHEATS
static int action_bind_sublabel_cheat_desc(
file_list_t *list,
@ -1630,6 +1679,13 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
return 0;
}
/* Mapped input ports require special handling */
if (type == MENU_SETTINGS_INPUT_INPUT_REMAP_PORT)
{
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_input_remap_port);
return 0;
}
/* Hotkey binds require special handling */
if ((cbs->enum_idx >= MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN) &&
(cbs->enum_idx <= MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_END))

View File

@ -328,6 +328,11 @@ static int action_get_title_dropdown_item(
(enum_idx <= MENU_ENUM_LABEL_INPUT_MOUSE_INDEX_LAST))
enum_idx = MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_INDEX;
/* Mapped Port (virtual -> 'physical' port mapping) */
if ((enum_idx >= MENU_ENUM_LABEL_INPUT_REMAP_PORT) &&
(enum_idx <= MENU_ENUM_LABEL_INPUT_REMAP_PORT_LAST))
enum_idx = MENU_ENUM_LABEL_VALUE_INPUT_REMAP_PORT;
{
const char *title = msg_hash_to_str(enum_idx);

View File

@ -453,6 +453,7 @@ uintptr_t ozone_entries_icon_get_texture(ozone_handle_t *ozone,
case MENU_SETTING_ACTION:
return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_SETTING];
case MENU_SETTINGS_INPUT_LIBRETRO_DEVICE:
case MENU_SETTINGS_INPUT_INPUT_REMAP_PORT:
return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_SETTING];
case MENU_SETTINGS_INPUT_ANALOG_DPAD_MODE:
return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_INPUT_ADC];

View File

@ -2961,6 +2961,7 @@ static uintptr_t xmb_icon_get_id(xmb_handle_t *xmb,
return xmb->textures.list[XMB_TEXTURE_ROOM_RELAY];
#endif
case MENU_SETTINGS_INPUT_LIBRETRO_DEVICE:
case MENU_SETTINGS_INPUT_INPUT_REMAP_PORT:
return xmb->textures.list[XMB_TEXTURE_SETTING];
case MENU_SETTINGS_INPUT_ANALOG_DPAD_MODE:
return xmb->textures.list[XMB_TEXTURE_INPUT_ADC];

View File

@ -1354,7 +1354,7 @@ static unsigned menu_displaylist_parse_system_info(file_list_t *list)
MENU_SETTINGS_CORE_INFO_NONE, 0, 0))
count++;
snprintf(tmp, sizeof(tmp), " Device config name: %s",
input_config_get_device_display_name(controller) ?
input_config_get_device_config_name(controller) ?
input_config_get_device_config_name(controller) :
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE));
if (menu_entries_append_enum(list, tmp, "",
@ -4415,7 +4415,7 @@ static int menu_displaylist_parse_input_device_index_list(
goto end;
port = setting->index_offset;
map = settings->uints.input_joypad_map[port];
map = settings->uints.input_joypad_index[port];
if (port >= MAX_USERS)
goto end;
@ -4511,6 +4511,7 @@ static int menu_displaylist_parse_input_description_list(
unsigned user_idx;
unsigned btn_idx;
unsigned current_remap_idx;
unsigned mapped_port;
size_t i, j;
char entry_label[21];
@ -4520,10 +4521,16 @@ static int menu_displaylist_parse_input_description_list(
goto end;
/* Determine user/button indices */
user_idx = (info->type - MENU_SETTINGS_INPUT_DESC_BEGIN) / (RARCH_FIRST_CUSTOM_BIND + 8);
btn_idx = (info->type - MENU_SETTINGS_INPUT_DESC_BEGIN) - (RARCH_FIRST_CUSTOM_BIND + 8) * user_idx;
user_idx = (info->type - MENU_SETTINGS_INPUT_DESC_BEGIN) / (RARCH_FIRST_CUSTOM_BIND + 8);
btn_idx = (info->type - MENU_SETTINGS_INPUT_DESC_BEGIN) - (RARCH_FIRST_CUSTOM_BIND + 8) * user_idx;
if ((user_idx >= MAX_USERS) || (btn_idx >= RARCH_CUSTOM_BIND_LIST_END))
if ((user_idx >= MAX_USERS) ||
(btn_idx >= RARCH_CUSTOM_BIND_LIST_END))
goto end;
mapped_port = settings->uints.input_remap_ports[user_idx];
if (mapped_port >= MAX_USERS)
goto end;
/* Get current mapping for selected button */
@ -4548,7 +4555,7 @@ static int menu_displaylist_parse_input_description_list(
const char *input_desc_btn;
i = (j < RARCH_ANALOG_BIND_LIST_END) ? input_config_bind_order[j] : j;
input_desc_btn = system->input_desc_btn[user_idx][i];
input_desc_btn = system->input_desc_btn[mapped_port][i];
/* Check whether an input is defined for
* this button */
@ -4651,10 +4658,11 @@ static int menu_displaylist_parse_input_description_kbd_list(
goto end;
/* Determine user/button indices */
user_idx = (info->type - MENU_SETTINGS_INPUT_DESC_KBD_BEGIN) / RARCH_ANALOG_BIND_LIST_END;
btn_idx = (info->type - MENU_SETTINGS_INPUT_DESC_KBD_BEGIN) - RARCH_ANALOG_BIND_LIST_END * user_idx;
user_idx = (info->type - MENU_SETTINGS_INPUT_DESC_KBD_BEGIN) / RARCH_ANALOG_BIND_LIST_END;
btn_idx = (info->type - MENU_SETTINGS_INPUT_DESC_KBD_BEGIN) - RARCH_ANALOG_BIND_LIST_END * user_idx;
if ((user_idx >= MAX_USERS) || (btn_idx >= RARCH_CUSTOM_BIND_LIST_END))
if ((user_idx >= MAX_USERS) ||
(btn_idx >= RARCH_CUSTOM_BIND_LIST_END))
goto end;
/* Get current mapping for selected button */
@ -9577,22 +9585,27 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type,
const char *menu_driver = menu_driver_ident();
bool is_rgui = string_is_equal(menu_driver, "rgui");
file_list_t *list = info->list;
unsigned p = atoi(info->path);
unsigned port = string_to_unsigned(info->path);
unsigned mapped_port = settings->uints.input_remap_ports[port];
size_t selection = menu_navigation_get_selection();
menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list);
{
char key_type[PATH_MAX_LENGTH];
char key_analog[PATH_MAX_LENGTH];
unsigned val = p + 1;
char key_type[64];
char key_analog[64];
char key_port[64];
key_type[0] = key_analog[0] = '\0';
key_type[0] = '\0';
key_analog[0] = '\0';
key_port[0] = '\0';
snprintf(key_type, sizeof(key_type),
msg_hash_to_str(MENU_ENUM_LABEL_INPUT_LIBRETRO_DEVICE), val);
msg_hash_to_str(MENU_ENUM_LABEL_INPUT_LIBRETRO_DEVICE), mapped_port + 1);
snprintf(key_analog, sizeof(key_analog),
msg_hash_to_str(MENU_ENUM_LABEL_INPUT_PLAYER_ANALOG_DPAD_MODE), val);
msg_hash_to_str(MENU_ENUM_LABEL_INPUT_PLAYER_ANALOG_DPAD_MODE), port + 1);
snprintf(key_port, sizeof(key_port),
msg_hash_to_str(MENU_ENUM_LABEL_INPUT_REMAP_PORT), port + 1);
if (MENU_DISPLAYLIST_PARSE_SETTINGS(list,
key_type, PARSE_ONLY_UINT, true, MENU_SETTINGS_INPUT_LIBRETRO_DEVICE) == 0)
@ -9600,12 +9613,15 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type,
if (MENU_DISPLAYLIST_PARSE_SETTINGS(list,
key_analog, PARSE_ONLY_UINT, true, MENU_SETTINGS_INPUT_ANALOG_DPAD_MODE) == 0)
count++;
if (MENU_DISPLAYLIST_PARSE_SETTINGS(list,
key_port, PARSE_ONLY_UINT, true, MENU_SETTINGS_INPUT_INPUT_REMAP_PORT) == 0)
count++;
}
{
unsigned retro_id, j;
unsigned device = settings->uints.input_libretro_device[p];
device &= RETRO_DEVICE_MASK;
unsigned device = settings->uints.input_libretro_device[mapped_port];
device &= RETRO_DEVICE_MASK;
if (device == RETRO_DEVICE_JOYPAD || device == RETRO_DEVICE_ANALOG)
{
@ -9621,10 +9637,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type,
? input_config_bind_order[j]
: j;
keybind =
&input_config_binds[p][retro_id];
&input_config_binds[port][retro_id];
auto_bind =
(const struct retro_keybind*)
input_config_get_bind_auto(p, retro_id);
input_config_get_bind_auto(port, retro_id);
input_config_get_bind_string(descriptor,
keybind, auto_bind, sizeof(descriptor));
@ -9632,7 +9648,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type,
if (!strstr(descriptor, "Auto"))
{
const struct retro_keybind *keyptr =
&input_config_binds[p][retro_id];
&input_config_binds[port][retro_id];
snprintf(desc_label, sizeof(desc_label),
"%s %s", msg_hash_to_str(keyptr->enum_idx), descriptor);
@ -9646,14 +9662,15 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type,
&& !settings->bools.menu_show_sublabels)
{
snprintf(desc_label, sizeof(desc_label),
"%s [%s %u]", descriptor, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PORT), p + 1);
"%s [%s %u]", descriptor, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PORT), port + 1);
strlcpy(descriptor, desc_label, sizeof(descriptor));
}
/* Note: 'physical' port is passed as label */
if (menu_entries_append_enum(list, descriptor, info->path,
MSG_UNKNOWN,
MENU_SETTINGS_INPUT_DESC_BEGIN +
(p * (RARCH_FIRST_CUSTOM_BIND + 8)) + retro_id, 0, 0))
(port * (RARCH_FIRST_CUSTOM_BIND + 8)) + retro_id, 0, 0))
count++;
}
}
@ -9671,10 +9688,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type,
? input_config_bind_order[j]
: j;
keybind =
&input_config_binds[p][retro_id];
&input_config_binds[port][retro_id];
auto_bind =
(const struct retro_keybind*)
input_config_get_bind_auto(p, retro_id);
input_config_get_bind_auto(port, retro_id);
input_config_get_bind_string(descriptor,
keybind, auto_bind, sizeof(descriptor));
@ -9682,7 +9699,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type,
if (!strstr(descriptor, "Auto"))
{
const struct retro_keybind *keyptr =
&input_config_binds[p][retro_id];
&input_config_binds[port][retro_id];
snprintf(desc_label, sizeof(desc_label),
"%s %s", msg_hash_to_str(keyptr->enum_idx), descriptor);
@ -9697,14 +9714,15 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type,
{
snprintf(desc_label, sizeof(desc_label),
"%s [%s %u]", descriptor,
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PORT), p + 1);
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PORT), port + 1);
strlcpy(descriptor, desc_label, sizeof(descriptor));
}
/* Note: 'physical' port is passed as label */
if (menu_entries_append_enum(list, descriptor, info->path,
MSG_UNKNOWN,
MENU_SETTINGS_INPUT_DESC_KBD_BEGIN +
(p * RARCH_ANALOG_BIND_LIST_END) + retro_id, 0, 0))
(port * RARCH_ANALOG_BIND_LIST_END) + retro_id, 0, 0))
count++;
}
}

View File

@ -188,6 +188,7 @@ enum menu_settings_type
MENU_SETTINGS_INPUT_LIBRETRO_DEVICE,
MENU_SETTINGS_INPUT_ANALOG_DPAD_MODE,
MENU_SETTINGS_INPUT_INPUT_REMAP_PORT,
MENU_SETTINGS_INPUT_BEGIN,
MENU_SETTINGS_INPUT_END = MENU_SETTINGS_INPUT_BEGIN + RARCH_CUSTOM_BIND_LIST_END + 6,
MENU_SETTINGS_INPUT_DESC_BEGIN,

View File

@ -96,6 +96,7 @@
#include "../verbosity.h"
#include "../playlist.h"
#include "../manual_content_scan.h"
#include "../input/input_remapping.h"
#include "../tasks/tasks_internal.h"
@ -5386,6 +5387,37 @@ static int setting_action_left_libretro_device_type(
return 0;
}
static int setting_action_left_input_remap_port(
rarch_setting_t *setting, size_t idx, bool wraparound)
{
bool refresh = false;
unsigned port = 0;
settings_t *settings = config_get_ptr();
if (!setting)
return -1;
port = setting->index_offset;
if (settings->uints.input_remap_ports[port] > 0)
settings->uints.input_remap_ports[port]--;
else
settings->uints.input_remap_ports[port] = MAX_USERS - 1;
/* Must be called whenever settings->uints.input_remap_ports
* is modified */
input_remapping_update_port_map();
/* Changing mapped port may leave a core port unused;
* reinitialise controllers to ensure that any such
* ports are set to 'RETRO_DEVICE_NONE' */
command_event(CMD_EVENT_CONTROLLER_INIT, NULL);
menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
return 0;
}
static int setting_uint_action_left_crt_switch_resolution_super(
rarch_setting_t *setting, size_t idx, bool wraparound)
{
@ -5427,7 +5459,7 @@ static int setting_action_left_bind_device(
index_offset = setting->index_offset;
p = &settings->uints.input_joypad_map[index_offset];
p = &settings->uints.input_joypad_index[index_offset];
if ((*p) >= max_devices)
*p = max_devices - 1;
@ -6242,6 +6274,14 @@ static void setting_get_string_representation_uint_analog_dpad_mode(
strlcpy(s, modes[*setting->value.target.unsigned_integer % ANALOG_DPAD_LAST], len);
}
static void setting_get_string_representation_uint_input_remap_port(
rarch_setting_t *setting,
char *s, size_t len)
{
if (setting)
snprintf(s, len, "%u", *setting->value.target.unsigned_integer + 1);
}
#ifdef HAVE_THREADS
static void setting_get_string_representation_uint_autosave_interval(
rarch_setting_t *setting,
@ -6860,7 +6900,7 @@ static int setting_action_start_bind_device(rarch_setting_t *setting)
return -1;
configuration_set_uint(settings,
settings->uints.input_joypad_map[setting->index_offset], setting->index_offset);
settings->uints.input_joypad_index[setting->index_offset], setting->index_offset);
return 0;
}
@ -6962,6 +7002,32 @@ static int setting_action_start_libretro_device_type(rarch_setting_t *setting)
return 0;
}
static int setting_action_start_input_remap_port(rarch_setting_t *setting)
{
bool refresh = false;
settings_t *settings = config_get_ptr();
unsigned port;
if (!setting)
return -1;
port = setting->index_offset;
settings->uints.input_remap_ports[port] = port;
/* Must be called whenever settings->uints.input_remap_ports
* is modified */
input_remapping_update_port_map();
/* Changing mapped port may leave a core port unused;
* reinitialise controllers to ensure that any such
* ports are set to 'RETRO_DEVICE_NONE' */
command_event(CMD_EVENT_CONTROLLER_INIT, NULL);
menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
return 0;
}
static int setting_action_start_video_refresh_rate_auto(
rarch_setting_t *setting)
{
@ -7045,6 +7111,37 @@ static int setting_action_right_libretro_device_type(
return 0;
}
static int setting_action_right_input_remap_port(
rarch_setting_t *setting, size_t idx, bool wraparound)
{
bool refresh = false;
unsigned port = 0;
settings_t *settings = config_get_ptr();
if (!setting)
return -1;
port = setting->index_offset;
if (settings->uints.input_remap_ports[port] < MAX_USERS - 1)
settings->uints.input_remap_ports[port]++;
else
settings->uints.input_remap_ports[port] = 0;
/* Must be called whenever settings->uints.input_remap_ports
* is modified */
input_remapping_update_port_map();
/* Changing mapped port may leave a core port unused;
* reinitialise controllers to ensure that any such
* ports are set to 'RETRO_DEVICE_NONE' */
command_event(CMD_EVENT_CONTROLLER_INIT, NULL);
menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
return 0;
}
static int setting_action_right_bind_device(
rarch_setting_t *setting, size_t idx, bool wraparound)
{
@ -7058,7 +7155,7 @@ static int setting_action_right_bind_device(
index_offset = setting->index_offset;
p = &settings->uints.input_joypad_map[index_offset];
p = &settings->uints.input_joypad_index[index_offset];
if (*p < max_devices)
(*p)++;
@ -7142,7 +7239,7 @@ static void get_string_representation_bind_device(rarch_setting_t *setting, char
return;
index_offset = setting->index_offset;
map = settings->uints.input_joypad_map[index_offset];
map = settings->uints.input_joypad_index[index_offset];
if (map < max_devices)
{
@ -7213,7 +7310,7 @@ static void general_read_handler(rarch_setting_t *setting)
case MENU_ENUM_LABEL_INPUT_PLAYER3_JOYPAD_INDEX:
case MENU_ENUM_LABEL_INPUT_PLAYER4_JOYPAD_INDEX:
case MENU_ENUM_LABEL_INPUT_PLAYER5_JOYPAD_INDEX:
*setting->value.target.integer = settings->uints.input_joypad_map[setting->enum_idx - MENU_ENUM_LABEL_INPUT_PLAYER1_JOYPAD_INDEX];
*setting->value.target.integer = settings->uints.input_joypad_index[setting->enum_idx - MENU_ENUM_LABEL_INPUT_PLAYER1_JOYPAD_INDEX];
break;
default:
break;
@ -7474,7 +7571,7 @@ static void general_write_handler(rarch_setting_t *setting)
{
settings_t *settings = config_get_ptr();
settings->modified = true;
settings->uints.input_joypad_map[setting->enum_idx - MENU_ENUM_LABEL_INPUT_PLAYER1_JOYPAD_INDEX] = *setting->value.target.integer;
settings->uints.input_joypad_index[setting->enum_idx - MENU_ENUM_LABEL_INPUT_PLAYER1_JOYPAD_INDEX] = *setting->value.target.integer;
}
break;
case MENU_ENUM_LABEL_LOG_TO_FILE:
@ -7865,6 +7962,24 @@ static void general_write_handler(rarch_setting_t *setting)
}
break;
default:
/* Special cases */
/* > Mapped Port (virtual -> 'physical' port mapping)
* Occupies a range of enum indices, so cannot
* simply switch on the value */
if ((setting->enum_idx >= MENU_ENUM_LABEL_INPUT_REMAP_PORT) &&
(setting->enum_idx <= MENU_ENUM_LABEL_INPUT_REMAP_PORT_LAST))
{
/* Must be called whenever settings->uints.input_remap_ports
* is modified */
input_remapping_update_port_map();
/* Changing mapped port may leave a core port unused;
* reinitialise controllers to ensure that any such
* ports are set to 'RETRO_DEVICE_NONE' */
command_event(CMD_EVENT_CONTROLLER_INIT, NULL);
}
break;
}
@ -8398,6 +8513,72 @@ static bool setting_append_list_input_player_options(
return true;
}
static bool setting_append_list_input_remap_port_options(
rarch_setting_t **list,
rarch_setting_info_t *list_info,
const char *parent_group)
{
settings_t *settings = config_get_ptr();
rarch_setting_group_info_t group_info;
rarch_setting_group_info_t subgroup_info;
static char key_port[MAX_USERS][64];
static char label_port[MAX_USERS][64];
unsigned user;
group_info.name = NULL;
subgroup_info.name = NULL;
START_GROUP(list, list_info, &group_info,
"Mapped Ports", parent_group);
parent_group = msg_hash_to_str(MENU_ENUM_LABEL_SETTINGS);
START_SUB_GROUP(list, list_info, "State", &group_info,
&subgroup_info, parent_group);
for (user = 0; user < MAX_USERS; user++)
{
key_port[user][0] = '\0';
label_port[user][0] = '\0';
snprintf(key_port[user], sizeof(key_port[user]),
msg_hash_to_str(MENU_ENUM_LABEL_INPUT_REMAP_PORT),
user + 1);
snprintf(label_port[user], sizeof(label_port[user]), "%s",
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_INPUT_REMAP_PORT));
CONFIG_UINT_ALT(
list, list_info,
&settings->uints.input_remap_ports[user],
key_port[user],
label_port[user],
user,
&group_info,
&subgroup_info,
parent_group,
general_write_handler,
general_read_handler);
(*list)[list_info->index - 1].index = user + 1;
(*list)[list_info->index - 1].index_offset = user;
(*list)[list_info->index - 1].action_left = &setting_action_left_input_remap_port;
(*list)[list_info->index - 1].action_right = &setting_action_right_input_remap_port;
(*list)[list_info->index - 1].action_select = &setting_action_right_input_remap_port;
(*list)[list_info->index - 1].action_start = &setting_action_start_input_remap_port;
(*list)[list_info->index - 1].action_ok = &setting_action_ok_uint;
(*list)[list_info->index - 1].get_string_representation =
&setting_get_string_representation_uint_input_remap_port;
menu_settings_list_current_add_range(list, list_info, 0, MAX_USERS-1, 1.0, true, true);
MENU_SETTINGS_LIST_CURRENT_ADD_ENUM_IDX_PTR(list, list_info,
(enum msg_hash_enums)(MENU_ENUM_LABEL_INPUT_REMAP_PORT + user));
}
END_SUB_GROUP(list, list_info, parent_group);
END_GROUP(list, list_info, parent_group);
return true;
}
/**
* config_get_audio_resampler_driver_options:
*
@ -9244,6 +9425,8 @@ static bool setting_append_list(
for (user = 0; user < MAX_USERS; user++)
setting_append_list_input_player_options(list, list_info, parent_group, user);
setting_append_list_input_remap_port_options(list, list_info, parent_group);
END_SUB_GROUP(list, list_info, parent_group);
END_GROUP(list, list_info, parent_group);
break;

View File

@ -742,6 +742,9 @@ enum msg_hash_enums
MENU_ENUM_LABEL_INPUT_DEVICE_INDEX_LAST = MENU_ENUM_LABEL_INPUT_DEVICE_INDEX + MAX_USERS,
MENU_ENUM_LABEL_INPUT_MOUSE_INDEX,
MENU_ENUM_LABEL_INPUT_MOUSE_INDEX_LAST = MENU_ENUM_LABEL_INPUT_MOUSE_INDEX + MAX_USERS,
MENU_ENUM_LABEL_INPUT_REMAP_PORT,
MENU_ENUM_LABEL_INPUT_REMAP_PORT_LAST = MENU_ENUM_LABEL_INPUT_REMAP_PORT + MAX_USERS,
MENU_ENUM_LABEL_INPUT_SETTINGS_BEGIN,
MENU_LABEL(INPUT_HOTKEY_BINDS),
@ -889,6 +892,8 @@ enum msg_hash_enums
MENU_ENUM_LABEL_VALUE_INPUT_BIND_DEFAULT_ALL,
MENU_ENUM_LABEL_VALUE_INPUT_SAVE_AUTOCONFIG,
MENU_ENUM_LABEL_VALUE_INPUT_MOUSE_INDEX,
MENU_ENUM_LABEL_VALUE_INPUT_REMAP_PORT,
MENU_ENUM_SUBLABEL_INPUT_REMAP_PORT,
MENU_ENUM_SUBLABEL_INPUT_META_FAST_FORWARD_KEY,
MENU_ENUM_SUBLABEL_INPUT_META_FAST_FORWARD_HOLD_KEY,

View File

@ -1372,7 +1372,7 @@ bool menu_input_key_bind_set_mode(
return false;
index_offset = setting->index_offset;
binds->port = settings->uints.input_joypad_map[index_offset];
binds->port = settings->uints.input_joypad_index[index_offset];
menu_input_key_bind_poll_bind_get_rested_axes(
p_rarch->joypad,
@ -1382,7 +1382,7 @@ bool menu_input_key_bind_set_mode(
NULL,
#endif
binds);
menu_input_key_bind_poll_bind_state(p_rarch, settings->uints.input_joypad_map[binds->port],
menu_input_key_bind_poll_bind_state(p_rarch, settings->uints.input_joypad_index[binds->port],
binds, false);
current_usec = cpu_features_get_time_usec();
@ -1495,7 +1495,7 @@ static bool menu_input_key_bind_iterate(
p_rarch->keyboard_mapping_blocked = false;
menu_input_key_bind_poll_bind_state(p_rarch,
settings->uints.input_joypad_map[new_binds.port],
settings->uints.input_joypad_index[new_binds.port],
&new_binds, timed_out);
#ifdef ANDROID
@ -12139,20 +12139,39 @@ static void command_event_set_mixer_volume(
* Initialize libretro controllers.
**/
static void command_event_init_controllers(rarch_system_info_t *info,
unsigned num_active_users)
settings_t *settings, unsigned num_active_users)
{
unsigned i;
unsigned ports_size = info->ports.size;
unsigned num_core_ports = info->ports.size;
unsigned port;
for (i = 0; i < ports_size; i++)
for (port = 0; port < num_core_ports; port++)
{
unsigned device = RETRO_DEVICE_NONE;
const struct retro_controller_description *desc = NULL;
retro_ctx_controller_info_t pad;
unsigned device = (i < num_active_users)
? input_config_get_device(i)
: RETRO_DEVICE_NONE;
const struct retro_controller_description *desc =
libretro_find_controller_description(
&info->ports.data[i], device);
unsigned i;
/* Check whether current core port is mapped
* to an input device
* > If is not, leave 'device' set to
* 'RETRO_DEVICE_NONE'
* > For example: if input ports 0 and 1 are
* mapped to core port 0, core port 1 will
* be unmapped and should be disabled */
for (i = 0; i < num_active_users; i++)
{
if (i >= MAX_USERS)
break;
if (port == settings->uints.input_remap_ports[i])
{
device = input_config_get_device(port);
break;
}
}
desc = libretro_find_controller_description(
&info->ports.data[port], device);
if (desc && !desc->desc)
{
@ -12171,7 +12190,7 @@ static void command_event_init_controllers(rarch_system_info_t *info,
}
pad.device = device;
pad.port = i;
pad.port = port;
core_set_controller_port_device(&pad);
}
}
@ -12183,46 +12202,6 @@ static void command_event_disable_overrides(struct rarch_state *p_rarch)
config_unload_override();
runloop_state.overrides_active = false;
}
void input_remapping_set_defaults(void)
{
unsigned i, j;
struct rarch_state *p_rarch = &rarch_st;
settings_t *settings = p_rarch->configuration_settings;
global_t *global = &p_rarch->g_extern;
for (i = 0; i < MAX_USERS; i++)
{
for (j = 0; j < RARCH_FIRST_CUSTOM_BIND; j++)
{
const struct retro_keybind *keybind = &input_config_binds[i][j];
if (keybind)
configuration_set_uint(settings,
settings->uints.input_remap_ids[i][j], keybind->id);
configuration_set_uint(settings,
settings->uints.input_keymapper_ids[i][j], RETROK_UNKNOWN);
}
for (j = RARCH_FIRST_CUSTOM_BIND; j < (RARCH_FIRST_CUSTOM_BIND + 8); j++)
configuration_set_uint(settings,
settings->uints.input_remap_ids[i][j], j);
}
if (global)
{
for (i = 0; i < MAX_USERS; i++)
{
if (global->old_analog_dpad_mode[i])
configuration_set_uint(settings,
settings->uints.input_analog_dpad_mode[i],
global->old_analog_dpad_mode[i]);
if (global->old_libretro_device[i])
configuration_set_uint(settings,
settings->uints.input_libretro_device[i],
global->old_libretro_device[i]);
}
}
}
#endif
static void command_event_deinit_core(
@ -12254,16 +12233,16 @@ static void command_event_deinit_core(
p_rarch->runtime_shader_preset[0] = '\0';
#endif
#ifdef HAVE_CONFIGFILE
if ( runloop_state.remaps_core_active
|| runloop_state.remaps_content_dir_active
|| runloop_state.remaps_game_active
)
{
input_remapping_deinit();
input_remapping_set_defaults();
input_remapping_set_defaults(true);
}
#endif
else
input_remapping_restore_global_config(true);
}
#ifdef HAVE_CHEATS
@ -12770,6 +12749,15 @@ static bool command_event_init_core(
p_rarch->current_core.retro_set_environment(rarch_environment_cb);
/* Load any input remap files
* > Note that we always cache the current global
* input settings when initialising a core
* (regardless of whether remap files are loaded)
* so settings can be restored when the core is
* unloaded - i.e. core remapping options modified
* at runtime should not 'bleed through' into the
* master config file */
input_remapping_cache_global_config();
#ifdef HAVE_CONFIGFILE
if (auto_remaps_enable)
config_load_remap(dir_input_remapping, &runloop_state.system);
@ -13202,18 +13190,167 @@ static bool command_event_resize_windowed_scale(struct rarch_state *p_rarch)
return true;
}
void input_remapping_cache_global_config(void)
{
struct rarch_state *p_rarch = &rarch_st;
settings_t *settings = p_rarch->configuration_settings;
global_t *global = &p_rarch->g_extern;
unsigned i;
for (i = 0; i < MAX_USERS; i++)
{
global->old_analog_dpad_mode[i] = settings->uints.input_analog_dpad_mode[i];
global->old_libretro_device[i] = settings->uints.input_libretro_device[i];
}
global->old_analog_dpad_mode_set = true;
global->old_libretro_device_set = true;
}
void input_remapping_enable_global_config_restore(void)
{
struct rarch_state *p_rarch = &rarch_st;
global_t *global = &p_rarch->g_extern;
global->remapping_cache_active = true;
}
void input_remapping_restore_global_config(bool clear_cache)
{
struct rarch_state *p_rarch = &rarch_st;
settings_t *settings = p_rarch->configuration_settings;
global_t *global = &p_rarch->g_extern;
unsigned i;
if (!global->remapping_cache_active)
goto end;
for (i = 0; i < MAX_USERS; i++)
{
if (global->old_analog_dpad_mode_set &&
(settings->uints.input_analog_dpad_mode[i] !=
global->old_analog_dpad_mode[i]))
configuration_set_uint(settings,
settings->uints.input_analog_dpad_mode[i],
global->old_analog_dpad_mode[i]);
if (global->old_libretro_device_set &&
(settings->uints.input_libretro_device[i] !=
global->old_libretro_device[i]))
configuration_set_uint(settings,
settings->uints.input_libretro_device[i],
global->old_libretro_device[i]);
}
end:
if (clear_cache)
{
global->old_analog_dpad_mode_set = false;
global->old_libretro_device_set = false;
global->remapping_cache_active = false;
}
}
void input_remapping_update_port_map(void)
{
unsigned i, j;
struct rarch_state *p_rarch = &rarch_st;
settings_t *settings = p_rarch->configuration_settings;
unsigned port_map_index[MAX_USERS] = {0};
/* First pass: 'reset' port map */
for (i = 0; i < MAX_USERS; i++)
for (j = 0; j < (MAX_USERS + 1); j++)
settings->uints.input_remap_port_map[i][j] = MAX_USERS;
/* Second pass: assign port indices from
* 'input_remap_ports' */
for (i = 0; i < MAX_USERS; i++)
{
unsigned remap_port = settings->uints.input_remap_ports[i];
if (remap_port < MAX_USERS)
{
/* 'input_remap_port_map' provides a list of
* 'physical' ports for each 'virtual' port
* sampled in input_state().
* (Note: in the following explanation, port
* index starts from 0, rather than the frontend
* display convention of 1)
* For example - the following remap configuration
* will map input devices 0+1 to port 0, and input
* device 2 to port 1
* > input_remap_ports[0] = 0;
* input_remap_ports[1] = 0;
* input_remap_ports[2] = 1;
* This gives a port map of:
* > input_remap_port_map[0] = { 0, 1, MAX_USERS, ... };
* input_remap_port_map[1] = { 2, MAX_USERS, ... }
* input_remap_port_map[2] = { MAX_USERS, ... }
* ...
* A port map value of MAX_USERS indicates the end
* of the 'physical' port list */
settings->uints.input_remap_port_map[remap_port]
[port_map_index[remap_port]] = i;
port_map_index[remap_port]++;
}
}
}
void input_remapping_deinit(void)
{
struct rarch_state *p_rarch = &rarch_st;
global_t *global = &p_rarch->g_extern;
if (!string_is_empty(global->name.remapfile))
global_t *global = &p_rarch->g_extern;
if (global->name.remapfile)
free(global->name.remapfile);
global->name.remapfile = NULL;
global->name.remapfile = NULL;
runloop_state.remaps_core_active = false;
runloop_state.remaps_content_dir_active = false;
runloop_state.remaps_game_active = false;
}
void input_remapping_set_defaults(bool clear_cache)
{
unsigned i, j;
struct rarch_state *p_rarch = &rarch_st;
settings_t *settings = p_rarch->configuration_settings;
for (i = 0; i < MAX_USERS; i++)
{
/* Button/keyboard remaps */
for (j = 0; j < RARCH_FIRST_CUSTOM_BIND; j++)
{
const struct retro_keybind *keybind = &input_config_binds[i][j];
configuration_set_uint(settings,
settings->uints.input_remap_ids[i][j],
keybind ? keybind->id : RARCH_UNMAPPED);
configuration_set_uint(settings,
settings->uints.input_keymapper_ids[i][j], RETROK_UNKNOWN);
}
/* Analog stick remaps */
for (j = RARCH_FIRST_CUSTOM_BIND; j < (RARCH_FIRST_CUSTOM_BIND + 8); j++)
configuration_set_uint(settings,
settings->uints.input_remap_ids[i][j], j);
/* Controller port remaps */
configuration_set_uint(settings,
settings->uints.input_remap_ports[i], i);
}
/* Need to call 'input_remapping_update_port_map()'
* whenever 'settings->uints.input_remap_ports'
* is modified */
input_remapping_update_port_map();
/* Restore 'global' settings that were cached on
* the last core init
* > Prevents remap changes from 'bleeding through'
* into the main config file */
input_remapping_restore_global_config(clear_cache);
}
static bool input_driver_grab_mouse(struct rarch_state *p_rarch)
{
if (!p_rarch->current_input || !p_rarch->current_input->grab_mouse)
@ -13810,16 +13947,16 @@ bool command_event(enum event_command cmd, void *data)
video_driver_restore_cached(p_rarch, settings);
#ifdef HAVE_CONFIGFILE
if ( runloop_state.remaps_core_active
|| runloop_state.remaps_content_dir_active
|| runloop_state.remaps_game_active
)
{
input_remapping_deinit();
input_remapping_set_defaults();
input_remapping_set_defaults(true);
}
#endif
else
input_remapping_restore_global_config(true);
if (is_inited)
{
@ -15120,9 +15257,8 @@ bool command_event(enum event_command cmd, void *data)
{
rarch_system_info_t *info = &runloop_state.system;
if (info)
command_event_init_controllers(info,
p_rarch->input_driver_max_users
);
command_event_init_controllers(info, settings,
p_rarch->input_driver_max_users);
}
break;
case CMD_EVENT_NONE:
@ -17542,9 +17678,11 @@ static bool rarch_environment_cb(unsigned cmd, void *data)
p_rarch->input_driver_max_users;
for (p = 0; p < input_driver_max_users; p++)
{
unsigned mapped_port = settings->uints.input_remap_ports[p];
for (retro_id = 0; retro_id < RARCH_FIRST_CUSTOM_BIND; retro_id++)
{
const char *description = system->input_desc_btn[p][retro_id];
const char *description = system->input_desc_btn[mapped_port][retro_id];
if (!description)
continue;
@ -22313,7 +22451,7 @@ bool input_driver_set_rumble_state(unsigned port,
const input_device_driver_t *sec_joypad = NULL;
#endif
bool rumble_state = false;
unsigned joy_idx = settings->uints.input_joypad_map[port];
unsigned joy_idx = settings->uints.input_joypad_index[port];
if (joy_idx >= MAX_USERS)
return false;
@ -22455,8 +22593,9 @@ static void input_driver_poll(void)
for (i = 0; i < max_users; i++)
{
joypad_info[i].axis_threshold = p_rarch->input_driver_axis_threshold;
joypad_info[i].joy_idx = settings->uints.input_joypad_map[i];
joypad_info[i].joy_idx = settings->uints.input_joypad_index[i];
joypad_info[i].auto_binds = input_autoconf_binds[joypad_info[i].joy_idx];
p_rarch->input_driver_turbo_btns.frame_enable[i] = p_rarch->libretro_input_binds[i][RARCH_TURBO_ENABLE].valid ?
input_state_wrap(
p_rarch->current_input,
@ -22500,13 +22639,11 @@ static void input_driver_poll(void)
for (i = 0; i < max_users; i++)
{
input_bits_t current_inputs;
unsigned device
= settings->uints.input_libretro_device[i]
& RETRO_DEVICE_MASK;
input_bits_t *p_new_state
= (input_bits_t*)&current_inputs;
unsigned input_analog_dpad_mode =
settings->uints.input_analog_dpad_mode[i];
unsigned mapped_port = settings->uints.input_remap_ports[i];
unsigned device = settings->uints.input_libretro_device[mapped_port]
& RETRO_DEVICE_MASK;
input_bits_t *p_new_state = (input_bits_t*)&current_inputs;
unsigned input_analog_dpad_mode = settings->uints.input_analog_dpad_mode[i];
switch (device)
{
@ -22591,8 +22728,8 @@ static void input_driver_poll(void)
for (j = 0; j < RARCH_CUSTOM_BIND_LIST_END; j++)
{
unsigned current_button_value;
unsigned remap_key =
settings->uints.input_keymapper_ids[i][j];
unsigned remap_key =
settings->uints.input_keymapper_ids[i][j];
if (remap_key == RETROK_UNKNOWN)
continue;
@ -22665,9 +22802,9 @@ static void input_driver_poll(void)
{
bool remap_valid;
unsigned remap_button =
settings->uints.input_remap_ids[i][j];
settings->uints.input_remap_ids[i][j];
unsigned current_button_value =
BIT256_GET_PTR(p_new_state, j);
BIT256_GET_PTR(p_new_state, j);
#ifdef HAVE_OVERLAY
if (poll_overlay && i == 0)
@ -22721,8 +22858,7 @@ static void input_driver_poll(void)
{
unsigned k = (unsigned)j + RARCH_FIRST_CUSTOM_BIND;
int16_t current_axis_value = p_new_state->analogs[j];
unsigned remap_axis =
settings->uints.input_remap_ids[i][k];
unsigned remap_axis = settings->uints.input_remap_ids[i][k];
if (
(abs(current_axis_value) > 0 &&
@ -22831,7 +22967,7 @@ static int16_t input_state_device(
unsigned idx, unsigned id,
bool button_mask)
{
int16_t res = 0;
int16_t res = 0;
switch (device)
{
@ -23070,11 +23206,9 @@ static int16_t input_state_device(
unsigned offset = RARCH_FIRST_CUSTOM_BIND +
(idx * 4) + (id * 2);
if (settings->uints.input_remap_ids
[port][offset] != offset)
if (settings->uints.input_remap_ids[port][offset] != offset)
reset_state = true;
else if (settings->uints.input_remap_ids
[port][offset+1] != (offset+1))
else if (settings->uints.input_remap_ids[port][offset+1] != (offset+1))
reset_state = true;
}
@ -23156,26 +23290,31 @@ static int16_t input_state(unsigned port, unsigned device,
unsigned idx, unsigned id)
{
rarch_joypad_info_t joypad_info;
struct rarch_state *p_rarch = &rarch_st;
settings_t *settings = p_rarch->configuration_settings;
float input_analog_deadzone = settings->floats.input_analog_deadzone;
float input_analog_sensitivity = settings->floats.input_analog_sensitivity;
unsigned input_analog_dpad_mode = settings->uints.input_analog_dpad_mode[port];
int16_t result = 0;
int16_t ret = 0;
unsigned mapped_port;
struct rarch_state *p_rarch = &rarch_st;
settings_t *settings = p_rarch->configuration_settings;
float input_analog_deadzone = settings->floats.input_analog_deadzone;
float input_analog_sensitivity = settings->floats.input_analog_sensitivity;
unsigned *input_remap_port_map = settings->uints.input_remap_port_map[port];
const input_device_driver_t *joypad = p_rarch->joypad;
#ifdef HAVE_MFI
const input_device_driver_t
*sec_joypad = p_rarch->sec_joypad;
const input_device_driver_t *sec_joypad = p_rarch->sec_joypad;
#else
const input_device_driver_t
*sec_joypad = NULL;
const input_device_driver_t *sec_joypad = NULL;
#endif
bool input_blocked = (p_rarch->input_driver_flushing_input > 0) ||
p_rarch->input_driver_block_libretro_input;
bool bitmask_enabled = false;
unsigned max_users = p_rarch->input_driver_max_users;
int16_t result = 0;
joypad_info.axis_threshold = p_rarch->input_driver_axis_threshold;
joypad_info.joy_idx = settings->uints.input_joypad_map[port];
joypad_info.auto_binds = input_autoconf_binds[joypad_info.joy_idx];
device &= RETRO_DEVICE_MASK;
bitmask_enabled = (device == RETRO_DEVICE_JOYPAD) &&
(id == RETRO_DEVICE_ID_JOYPAD_MASK);
joypad_info.axis_threshold = p_rarch->input_driver_axis_threshold;
#ifdef HAVE_BSV_MOVIE
/* Load input from BSV record, if enabled */
if (BSV_MOVIE_IS_PLAYBACK_ON())
{
int16_t bsv_result;
@ -23191,97 +23330,138 @@ static int16_t input_state(unsigned port, unsigned device,
}
#endif
device &= RETRO_DEVICE_MASK;
ret = input_state_wrap(
p_rarch->current_input,
p_rarch->current_input_data,
p_rarch->joypad,
sec_joypad,
&joypad_info,
p_rarch->libretro_input_binds,
p_rarch->keyboard_mapping_blocked,
port, device, idx, id);
if ( (device == RETRO_DEVICE_ANALOG) &&
(ret == 0))
/* Loop over all 'physical' ports mapped to specified
* 'virtual' port index */
while ((mapped_port = *(input_remap_port_map++)) < MAX_USERS)
{
const input_device_driver_t *joypad = p_rarch->joypad;
#ifdef HAVE_MFI
const input_device_driver_t *sec_joypad = p_rarch->sec_joypad;
#else
const input_device_driver_t *sec_joypad = NULL;
#endif
if (p_rarch->libretro_input_binds[port])
int16_t ret = 0;
int16_t port_result = 0;
unsigned input_analog_dpad_mode = settings->uints.input_analog_dpad_mode[mapped_port];
joypad_info.joy_idx = settings->uints.input_joypad_index[mapped_port];
joypad_info.auto_binds = input_autoconf_binds[joypad_info.joy_idx];
/* Skip disabled input devices */
if (mapped_port >= max_users)
continue;
/* TODO/FIXME: This code is gibberish - a mess of nested
* refactors that make no sense whatsoever. The entire
* thing needs to be rewritten from scratch... */
ret = input_state_wrap(
p_rarch->current_input,
p_rarch->current_input_data,
joypad,
sec_joypad,
&joypad_info,
p_rarch->libretro_input_binds,
p_rarch->keyboard_mapping_blocked,
mapped_port, device, idx, id);
if ((device == RETRO_DEVICE_ANALOG) &&
(ret == 0))
{
if (idx == RETRO_DEVICE_INDEX_ANALOG_BUTTON)
if (p_rarch->libretro_input_binds[mapped_port])
{
if (id < RARCH_FIRST_CUSTOM_BIND)
if (idx == RETRO_DEVICE_INDEX_ANALOG_BUTTON)
{
bool valid_bind =
p_rarch->libretro_input_binds[port][id].valid;
if (valid_bind)
if (id < RARCH_FIRST_CUSTOM_BIND)
{
if (sec_joypad)
ret =
input_joypad_analog_button(
bool valid_bind = p_rarch->libretro_input_binds[mapped_port][id].valid;
if (valid_bind)
{
if (sec_joypad)
ret = input_joypad_analog_button(
input_analog_deadzone,
input_analog_sensitivity,
sec_joypad, &joypad_info,
id,
&p_rarch->libretro_input_binds[port][id]);
if (joypad && (ret == 0))
ret = input_joypad_analog_button(
input_analog_deadzone,
input_analog_sensitivity,
joypad, &joypad_info,
id,
&p_rarch->libretro_input_binds[port][id]);
&p_rarch->libretro_input_binds[mapped_port][id]);
if (joypad && (ret == 0))
ret = input_joypad_analog_button(
input_analog_deadzone,
input_analog_sensitivity,
joypad, &joypad_info,
id,
&p_rarch->libretro_input_binds[mapped_port][id]);
}
}
}
else
{
if (sec_joypad)
ret = input_joypad_analog_axis(
input_analog_dpad_mode,
input_analog_deadzone,
input_analog_sensitivity,
sec_joypad,
&joypad_info,
idx,
id,
p_rarch->libretro_input_binds[mapped_port]);
if (joypad && (ret == 0))
ret = input_joypad_analog_axis(
input_analog_dpad_mode,
input_analog_deadzone,
input_analog_sensitivity,
joypad,
&joypad_info,
idx,
id,
p_rarch->libretro_input_binds[mapped_port]);
}
}
}
if (!input_blocked)
{
input_mapper_t *handle = &p_rarch->input_driver_mapper;
if (bitmask_enabled)
{
unsigned i;
for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++)
if (input_state_device(p_rarch, settings, handle,
ret, mapped_port, device, idx, i, true))
port_result |= (1 << i);
}
else
port_result = input_state_device(p_rarch, settings, handle,
ret, mapped_port, device, idx, id, false);
}
/* Digital values are represented by a bitmap;
* we can just perform the logical OR of
* successive samples.
* Analog values are an integer corresponding
* to the extent of the analog motion; these
* cannot be OR'd together, we must instead
* keep the value with the largest magnitude */
if (device == RETRO_DEVICE_ANALOG)
{
if (result == 0)
result = port_result;
else
{
if (sec_joypad)
ret = input_joypad_analog_axis(
input_analog_dpad_mode,
input_analog_deadzone,
input_analog_sensitivity,
sec_joypad,
&joypad_info,
idx,
id,
p_rarch->libretro_input_binds[port]);
if (joypad && (ret == 0))
ret = input_joypad_analog_axis(
input_analog_dpad_mode,
input_analog_deadzone,
input_analog_sensitivity,
joypad,
&joypad_info,
idx,
id,
p_rarch->libretro_input_binds[port]);
int16_t port_result_abs = (port_result >= 0) ?
port_result : -port_result;
int16_t result_abs = (result >= 0) ?
result : -result;
result = (port_result_abs > result_abs) ?
port_result : result;
}
}
}
if ( (p_rarch->input_driver_flushing_input == 0)
&& !p_rarch->input_driver_block_libretro_input)
{
input_mapper_t *handle = &p_rarch->input_driver_mapper;
if ( (device == RETRO_DEVICE_JOYPAD) &&
(id == RETRO_DEVICE_ID_JOYPAD_MASK))
{
unsigned i;
for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++)
if (input_state_device(p_rarch, settings, handle, ret, port, device, idx, i, true))
result |= (1 << i);
}
else
result = input_state_device(p_rarch, settings, handle, ret, port, device, idx, id, false);
result |= port_result;
}
#ifdef HAVE_BSV_MOVIE
/* Save input to BSV record, if enabled */
if (BSV_MOVIE_IS_PLAYBACK_OFF())
{
result = swap_if_big16(result);
@ -27013,7 +27193,7 @@ const struct retro_keybind *input_config_get_bind_auto(
{
struct rarch_state *p_rarch = &rarch_st;
settings_t *settings = p_rarch->configuration_settings;
unsigned joy_idx = settings->uints.input_joypad_map[port];
unsigned joy_idx = settings->uints.input_joypad_index[port];
if (joy_idx < MAX_USERS)
return &input_autoconf_binds[joy_idx][id];
@ -37086,16 +37266,16 @@ bool retroarch_main_quit(void)
p_rarch->runtime_shader_preset[0] = '\0';
#endif
#ifdef HAVE_CONFIGFILE
if ( runloop_state.remaps_core_active
|| runloop_state.remaps_content_dir_active
|| runloop_state.remaps_game_active
)
{
input_remapping_deinit();
input_remapping_set_defaults();
input_remapping_set_defaults(true);
}
#endif
else
input_remapping_restore_global_config(true);
}
runloop_state.shutdown_initiated = true;
@ -37437,7 +37617,7 @@ static enum runloop_state runloop_check_state(
*sec_joypad = NULL;
#endif
joypad_info.joy_idx = settings->uints.input_joypad_map[port];
joypad_info.joy_idx = settings->uints.input_joypad_index[port];
joypad_info.auto_binds = input_autoconf_binds[joypad_info.joy_idx];
joypad_info.axis_threshold = p_rarch->input_driver_axis_threshold;
@ -38693,13 +38873,15 @@ int runloop_iterate(void)
/* Update binds for analog dpad modes. */
for (i = 0; i < max_users; i++)
{
enum analog_dpad_mode dpad_mode = (enum analog_dpad_mode)settings->uints.input_analog_dpad_mode[i];
enum analog_dpad_mode dpad_mode = (enum analog_dpad_mode)
settings->uints.input_analog_dpad_mode[i];
if (dpad_mode != ANALOG_DPAD_NONE)
{
unsigned k;
struct retro_keybind *general_binds = input_config_binds[i];
struct retro_keybind *auto_binds = input_autoconf_binds[i];
unsigned joy_idx = settings->uints.input_joypad_index[i];
struct retro_keybind *general_binds = input_config_binds[joy_idx];
struct retro_keybind *auto_binds = input_autoconf_binds[joy_idx];
unsigned x_plus = RARCH_ANALOG_RIGHT_X_PLUS;
unsigned y_plus = RARCH_ANALOG_RIGHT_Y_PLUS;
unsigned x_minus = RARCH_ANALOG_RIGHT_X_MINUS;
@ -38786,15 +38968,17 @@ int runloop_iterate(void)
for (i = 0; i < max_users; i++)
{
unsigned j;
enum analog_dpad_mode dpad_mode = (enum analog_dpad_mode)settings->uints.input_analog_dpad_mode[i];
enum analog_dpad_mode dpad_mode = (enum analog_dpad_mode)
settings->uints.input_analog_dpad_mode[i];
/* Restores analog D-pad binds temporarily overridden. */
if (dpad_mode != ANALOG_DPAD_NONE)
{
struct retro_keybind *general_binds = input_config_binds[i];
struct retro_keybind *auto_binds = input_autoconf_binds[i];
unsigned j;
unsigned joy_idx = settings->uints.input_joypad_index[i];
struct retro_keybind *general_binds = input_config_binds[joy_idx];
struct retro_keybind *auto_binds = input_autoconf_binds[joy_idx];
for (j = RETRO_DEVICE_ID_JOYPAD_UP; j <= RETRO_DEVICE_ID_JOYPAD_RIGHT; j++)
{
@ -39289,6 +39473,13 @@ bool core_load_game(retro_ctx_load_content_info_t *load_info)
p_rarch->current_core.game_loaded = game_loaded;
/* If 'game_loaded' is true at this point, then
* core is actually running; register that any
* changes to global remap-related parameters
* should be reset once core is deinitialised */
if (game_loaded)
input_remapping_enable_global_config_restore();
return game_loaded;
}

View File

@ -287,6 +287,9 @@ typedef struct global
} console;
unsigned old_analog_dpad_mode[MAX_USERS];
unsigned old_libretro_device[MAX_USERS];
bool old_analog_dpad_mode_set;
bool old_libretro_device_set;
bool remapping_cache_active;
/* Settings and/or global states specific to menus */
#ifdef HAVE_MENU
enum menu_action menu_prev_action;

View File

@ -1702,10 +1702,10 @@ struct runloop
bool autosave;
#ifdef HAVE_CONFIGFILE
bool overrides_active;
#endif
bool remaps_core_active;
bool remaps_game_active;
bool remaps_content_dir_active;
#endif
#ifdef HAVE_SCREENSHOTS
bool max_frames_screenshot;
char max_frames_screenshot_path[PATH_MAX_LENGTH];