Added the ability to switch between local and global input in the user configuration

See merge request ryubing/ryujinx!8
This commit is contained in:
Goodfeat
2025-06-09 17:24:24 -05:00
committed by GreemDev
parent ef02194a77
commit d31d1f91cf
14 changed files with 250 additions and 61 deletions

View File

@@ -84,6 +84,10 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
public AvaloniaList<string> ProfilesList { get; set; }
public AvaloniaList<string> DeviceList { get; set; }
public bool _useExtraConfig;
public bool _useGlobalInput;
// XAML Flags
public bool ShowSettings => _device > 0;
public bool IsController => _device > 1;
@@ -290,12 +294,14 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
public InputConfig Config { get; set; }
public InputViewModel(UserControl owner) : this()
public InputViewModel(UserControl owner, bool UseGlobalInput = false) : this()
{
if (Program.PreviewerDetached)
{
_mainWindow = RyujinxApp.MainWindow;
_useExtraConfig = Program.UseExtraConfig;
AvaloniaKeyboardDriver = new AvaloniaKeyboardDriver(owner);
_mainWindow.InputManager.GamepadDriver.OnGamepadConnected += HandleOnGamepadConnected;
@@ -303,6 +309,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
_mainWindow.ViewModel.AppHost?.NpadManager.BlockInputUpdates();
_useGlobalInput = UseGlobalInput;
_isLoaded = false;
LoadDevices();
@@ -335,9 +343,18 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
PlayerIndexes.Add(new(PlayerIndex.Handheld, LocaleManager.Instance[LocaleKeys.ControllerSettingsHandheld]));
}
private void LoadConfiguration(InputConfig inputConfig = null)
{
Config = inputConfig ?? ConfigurationState.Instance.Hid.InputConfig.Value.FirstOrDefault(inputConfig => inputConfig.PlayerIndex == _playerId);
if (_useGlobalInput && _useExtraConfig)
{
Config = inputConfig ?? ConfigurationState.InstanceExtra.Hid.InputConfig.Value.FirstOrDefault(inputConfig => inputConfig.PlayerIndex == _playerId);
}
else
{
Config = inputConfig ?? ConfigurationState.Instance.Hid.InputConfig.Value.FirstOrDefault(inputConfig => inputConfig.PlayerIndex == _playerId);
}
if (Config is StandardKeyboardInputConfig keyboardInputConfig)
{
@@ -966,7 +983,14 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
List<InputConfig> newConfig = [];
newConfig.AddRange(ConfigurationState.Instance.Hid.InputConfig.Value);
if (_useGlobalInput && _useExtraConfig)
{
newConfig.AddRange(ConfigurationState.InstanceExtra.Hid.InputConfig.Value);
}
else
{
newConfig.AddRange(ConfigurationState.Instance.Hid.InputConfig.Value);
}
newConfig.Remove(newConfig.FirstOrDefault(x => x == null));
@@ -1007,13 +1031,22 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
}
}
_mainWindow.ViewModel.AppHost?.NpadManager.ReloadConfiguration(newConfig, ConfigurationState.Instance.Hid.EnableKeyboard, ConfigurationState.Instance.Hid.EnableMouse);
// Atomically replace and signal input change.
// NOTE: Do not modify InputConfig.Value directly as other code depends on the on-change event.
ConfigurationState.Instance.Hid.InputConfig.Value = newConfig;
_mainWindow.ViewModel.AppHost?.NpadManager.ReloadConfiguration(newConfig, ConfigurationState.Instance.Hid.EnableKeyboard, ConfigurationState.Instance.Hid.EnableMouse);
if (_useGlobalInput && _useExtraConfig)
{
// In User Settings when "Use Global Input" is enabled, it saves global input to global setting
ConfigurationState.InstanceExtra.Hid.InputConfig.Value = newConfig;
ConfigurationState.InstanceExtra.ToFileFormat().SaveConfig(Program.GlobalConfigurationPath);
}
else
{
ConfigurationState.Instance.Hid.InputConfig.Value = newConfig;
ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
}
ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
}
public void NotifyChange(string property)

View File

@@ -1583,8 +1583,15 @@ namespace Ryujinx.Ava.UI.ViewModels
string idGame = application.IdBaseString;
if (ConfigurationFileFormat.TryLoad(Program.GetDirGameUserConfig(idGame), out ConfigurationFileFormat configurationFileFormat))
{
// Loads the user configuration, having previously changed the global configuration to the user configuration
// Loads the user configuration, having previously changed the global configuration to the user configuration
ConfigurationState.Instance.Load(configurationFileFormat, Program.GetDirGameUserConfig(idGame, true, true), idGame);
if (ConfigurationFileFormat.TryLoad(Program.GlobalConfigurationPath, out ConfigurationFileFormat configurationFileFormatExtra))
{
//This is where the global configuration will be stored.
//This allows you to change the global configuration settings during the game (for example, the global input setting)
ConfigurationState.InstanceExtra.Load(configurationFileFormatExtra, Program.GlobalConfigurationPath);
}
}
// Code where conditions will be executed after loading user configuration

View File

@@ -53,6 +53,7 @@ namespace Ryujinx.Ava.UI.ViewModels
[ObservableProperty] private bool _isVulkanAvailable = true;
[ObservableProperty] private bool _gameListNeedsRefresh;
private readonly List<string> _gpuIds = [];
public bool _useInputGlobalConfig;
private int _graphicsBackendIndex;
private int _scalingFilter;
private int _scalingFilterLevel;
@@ -64,6 +65,7 @@ namespace Ryujinx.Ava.UI.ViewModels
public event Action CloseWindow;
public event Action SaveSettingsEvent;
public event Action<bool> LocalGlobalInputSwitchEvent;
private int _networkInterfaceIndex;
private int _multiplayerModeIndex;
private string _ldnPassphrase;
@@ -84,6 +86,7 @@ namespace Ryujinx.Ava.UI.ViewModels
public bool IsGameTitleNotNull => !string.IsNullOrEmpty(GameTitle);
public double PanelOpacity => IsGameTitleNotNull ? 0.5 : 1;
public int ResolutionScale
{
get => _resolutionScale;
@@ -141,13 +144,26 @@ namespace Ryujinx.Ava.UI.ViewModels
public bool EnableDockedMode { get; set; }
public bool EnableKeyboard { get; set; }
public bool EnableMouse { get; set; }
public bool DisableInputWhenOutOfFocus { get; set; }
public bool DisableInputWhenOutOfFocus { get; set; }
public int FocusLostActionType { get; set; }
public bool EnableConfigGlobal
{
get => _useInputGlobalConfig;
set
{
_useInputGlobalConfig = value;
LocalGlobalInputSwitchEvent?.Invoke(_useInputGlobalConfig);
OnPropertyChanged(nameof(PanelOpacityInput));
OnPropertyChanged();
}
}
public double PanelOpacityInput => EnableConfigGlobal ? 0.5 : 1;
public VSyncMode VSyncMode
{
get => _vSyncMode;
get => _vSyncMode;
set
{
if (value is VSyncMode.Custom or VSyncMode.Switch or VSyncMode.Unbounded)
@@ -410,7 +426,16 @@ namespace Ryujinx.Ava.UI.ViewModels
if (enableToLoadCustomConfig) // During the game. If there is no user config, then load the global config window
{
string gameDir = Program.GetDirGameUserConfig(gameId, false, true);
string gameDir = Program.GetDirGameUserConfig(gameId, true, true);
Program.SetUseExtraConfig(true);
if (ConfigurationFileFormat.TryLoad(Program.GlobalConfigurationPath, out ConfigurationFileFormat configurationFileFormatExtra))
{
// Extra load global configuration for input setting and save global input setting with other global config
ConfigurationState.InstanceExtra.Load(configurationFileFormatExtra, Program.GlobalConfigurationPath);
}
if (ConfigurationFileFormat.TryLoad(gameDir, out ConfigurationFileFormat configurationFileFormat))
{
ConfigurationState.Instance.Load(configurationFileFormat, gameDir, gameId);
@@ -550,9 +575,9 @@ namespace Ryujinx.Ava.UI.ViewModels
}
}
public void LoadCurrentConfiguration()
public void LoadCurrentConfiguration(bool global = false)
{
ConfigurationState config = ConfigurationState.Instance;
ConfigurationState config = global ? ConfigurationState.InstanceExtra: ConfigurationState.Instance;
// User Interface
EnableDiscordIntegration = config.EnableDiscordIntegration;
@@ -578,6 +603,7 @@ namespace Ryujinx.Ava.UI.ViewModels
};
// Input
EnableConfigGlobal = config.System.UseInputGlobalConfig;
EnableDockedMode = config.System.EnableDockedMode;
EnableKeyboard = config.Hid.EnableKeyboard;
EnableMouse = config.Hid.EnableMouse;
@@ -660,9 +686,9 @@ namespace Ryujinx.Ava.UI.ViewModels
LdnServer = config.Multiplayer.LdnServer;
}
public void SaveSettings()
public void SaveSettings(bool global = false)
{
ConfigurationState config = ConfigurationState.Instance;
ConfigurationState config = global ? ConfigurationState.InstanceExtra: ConfigurationState.Instance;
// User Interface
config.EnableDiscordIntegration.Value = EnableDiscordIntegration;
@@ -684,6 +710,7 @@ namespace Ryujinx.Ava.UI.ViewModels
};
// Input
config.System.UseInputGlobalConfig.Value = EnableConfigGlobal;
config.System.EnableDockedMode.Value = EnableDockedMode;
config.Hid.EnableKeyboard.Value = EnableKeyboard;
config.Hid.EnableMouse.Value = EnableMouse;
@@ -796,11 +823,14 @@ namespace Ryujinx.Ava.UI.ViewModels
private static void RevertIfNotSaved()
{
// maybe this is an unnecessary check(all options need to be tested)
/*
maybe this is an unnecessary check(all options need to be tested)
if (string.IsNullOrEmpty(Program.GlobalConfigurationPath))
{
Program.ReloadConfig();
}
*/
Program.ReloadConfig();
}
public void ApplyButton()