Files
RetroArch/input/input_remapping.h
T
LibretroAdmin 415d6c85fd config: saving does not reset the input in use, nor copy it aside to survive that
Saving the configuration with "save only what differs from the
defaults" - which is the default - has to know the defaults. It
filled a spare settings structure with them by calling
config_set_defaults() on it. But that call does more than fill the
structure it is handed: it resets the input's own state, whatever
the structure. So every save of the configuration, in the middle of
a game or not:

- forgot the active remap file and put every button, axis and key
  of the remap in use back to its default;
- put each port's kind of device and its analog-to-digital setting
  back (the lane below saw both at their defaults afterwards);
- reset every bind and forgot every connected controller's profile -
  which it had thought of, so it first copied all the binds, all
  their labels, all the profiles' binds and a strdup() of each of
  their labels aside, and afterwards copied them all back. Putting
  the binds back counted as a change to every bind, so everything
  kept from them was made again after each save.

Found by a lane in the frontend harness, run on master: a port's
kind of device, a remapped button and a stick's analog-to-digital
setting, set and then saved, were all three back at their defaults
after the save.

config_set_defaults() resets the input's state only for the settings
in use. For any other structure it writes the remap's defaults into
that structure (input_remapping_defaults_into(), the part of
input_remapping_set_defaults() that only writes settings) and sets
the ports' kind of device in it, and touches nothing in use.

The save then has nothing to put back, and copies nothing: not the
binds, their labels, the profiles or the profiles' labels. The copy
of the binds with the defaults loaded goes too: a bind's default is
made from its definition where it is compared, as a reset makes it.

What this does not look at: config_set_defaults() also sets the
audio gains, the video thread flag, the save and state directories,
the patch preferences and the recording directories of the program
in use from whatever structure it is filling. They are outside the
input's files, and are as they were.

The frame is not touched: 3,652,253 and 4,310,052 instructions over
300 frames (X11), against 3,652,209 and 4,310,063.

Checked: the harness's lane now holds a save to all of it - the
changed bind written and a default one not; the binds, a port's
device, a remap and a stick setting what they were afterwards; and no
bind counted as changed - and passes; so does every other lane.
samples/config/defaults_target passes with the new call stubbed
beside the others. The X11 keyboard session logs the same as before;
the hotkey and quit-combination sessions log what master's binary
logged.
2026-10-08 05:26:49 +02:00

197 lines
6.8 KiB
C

/* RetroArch - A frontend for libretro.
* Copyright (C) 2011-2017 - Daniel De Matteis
* Copyright (C) 2016-2019 - Andrés Suárez
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _INPUT_REMAPPING_H
#define _INPUT_REMAPPING_H
#include <stdint.h>
#include <stddef.h>
#include <boolean.h>
#include <retro_common_api.h>
#include "input_defines.h"
#include "input_types.h"
RETRO_BEGIN_DECLS
/**
* Loads a remap file from disk to memory.
*
* @param data Path to config file.
*
* @return true (1) if successful, otherwise false (0).
**/
bool input_remapping_load_file(void *data, const char *path);
/**
* Saves remapping values to file.
*
* @param path Path to remapping file.
*
* @return true (1) if successful, otherwise false (0).
**/
bool input_remapping_save_file(const char *path);
/**
* 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);
/**
* Restores any global configuration settings that were cached on the last core
* init if INP_FLAG_REMAPPING_CACHE_ACTIVE is set.
* Must be called on core deinitialization.
*
* @param clear_cache If true, function becomes a NOOP until the next time
* `input_remapping_cache_global_config()` is called, and
* INP_FLAG_REMAPPING_CACHE_ACTIVE is set.
* @param restore_analog_dpad_mode Treat 'Analog to Digital Type' like a regular setting,
* meaning this should be false when we're not using any
* remap file so its value is saved globally on close/quit,
* and it should be true when we're using a remap or if
* we're resetting settings, to restore its global value.
*/
void input_remapping_restore_global_config(bool clear_cache, bool restore_analog_dpad_mode);
/**
* Must be called whenever `settings->uints.input_remap_ports` is modified.
*/
void input_remapping_update_port_map(void);
/* First-press port assignment ("Assign Ports on First Button Press").
* Whether the policy applies now: the setting, and not in netplay. */
bool input_first_press_enabled(void);
/* Maps the users a press was seen on to the next free core ports.
* Called between frames, with the core off the stack. */
void input_first_press_apply(void);
/* The notification for @user having been given core port @port: it
* names everything the user has, its controller and its keys. */
size_t input_first_press_describe(unsigned user, unsigned port,
char *s, size_t len);
/* Whether @user's core port was given by a press: a remap file does
* not store such a port. */
bool input_first_press_assigned(unsigned user);
/* @user's mapped port was set in the menu: it is the user's choice. */
void input_first_press_set_by_hand(unsigned user);
/**
* Frees runloop_st->name.remapfile and sets these runloop_state flags to false:
* remaps_core_active, remaps_content_dir_active, and remaps_game_active.
*
* @param save_remap If true, current remap settings will be saved to
* runloop_st->name.remapfile before performing
* deinitialisation.
*/
void input_remapping_deinit(bool save_remap);
/**
* Used to set the default mapping values within the `settings` struct
* @param clear_cache This value is passed to
* `input_remapping_restore_global_config()`. Please see
* the documentation for that function for details.
*/
void input_remapping_set_defaults(bool clear_cache);
/* The same defaults written into @settings, which need not be the
* settings in use, and nothing else done: see the definition. */
struct settings;
void input_remapping_defaults_into(struct settings *settings);
/**
* Checks `input_config_bind_map` for the requested `input_bind_map`, and if
* the bind has been registered, returns its base.
*
* @param index
*
* @return the contents of the meta field, or NULL if there is no matching bind
*/
const char *input_config_bind_map_get_base(unsigned bind_index);
/**
* Checks `input_config_bind_map` for the requested `input_bind_map`, and if
* the bind has been registered, returns the value of its meta binds field.
*
* @param index
*
* @return the contents of the meta field, or 0 if there is no matching bind
*/
unsigned input_config_bind_map_get_meta(unsigned bind_index);
/**
* Checks `input_config_bind_map` for the requested `input_bind_map`, and if
* the bind has been registered, returns a pointer to its description field.
*
* @param index
*
* @return the contents of the description field, or NULL if there is no
* matching bind
*/
const char *input_config_bind_map_get_desc(unsigned index);
/**
* Checks `input_config_bind_map` for the requested `input_bind_map`, and if
* the bind has been registered, returns the value of its retro_key field.
*
* @param index
*
* @return the value of the retro_key field, or 0 if there is no matching bind
*/
uint8_t input_config_bind_map_get_retro_key(unsigned index);
/**
* Parses the string representation of a retro_key struct
*
* @param str String to parse.
*
* @return Key identifier.
**/
enum retro_key input_config_translate_str_to_rk(const char *str, size_t len);
/**
* Searches for a string among the "base" fields of the list of binds.
*
* @param str String to search for among the binds
*
* @return Bind index value on success or RARCH_BIND_LIST_END if not found.
**/
unsigned input_config_translate_str_to_bind_id(const char *str);
/**
* Parse the bind data of an object of config_file_t.
*
* @param data An object of type config_file_t. We assume it is passed as a
* void pointer like this to avoid including config_file.h.
**/
void config_read_keybinds_conf(void *data);
/**
* Apply autoconfig binds to the indicated control port.
*
* @param port
* @param data An object of type config_file_t. We assume it is passed as a
* void pointer like this to avoid including config_file.h.
*/
void input_config_set_autoconfig_binds(unsigned port, void *data);
void input_mapper_reset(void *data);
RETRO_END_DECLS
#endif