From d76da6e4dfa2c9f52ace2c985b8ec1de8a173c98 Mon Sep 17 00:00:00 2001 From: Vova Date: Wed, 29 Jan 2025 21:44:48 +1000 Subject: [PATCH 001/171] Added --backend-threading parameter for launching games via shortcut --- src/Ryujinx/Program.cs | 10 ++++++++++ src/Ryujinx/Utilities/CommandLineState.cs | 11 +++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/Ryujinx/Program.cs b/src/Ryujinx/Program.cs index 1f0df9b2f..c72aa689a 100644 --- a/src/Ryujinx/Program.cs +++ b/src/Ryujinx/Program.cs @@ -206,6 +206,16 @@ namespace Ryujinx.Ava _ => ConfigurationState.Instance.Graphics.GraphicsBackend }; + // Check if backend threading was overridden + if (CommandLineState.OverrideBackendThreading is not null) + ConfigurationState.Instance.Graphics.BackendThreading.Value = CommandLineState.OverrideBackendThreading.ToLower() switch + { + "auto" => BackendThreading.Auto, + "off" => BackendThreading.Off, + "on" => BackendThreading.On, + _ => ConfigurationState.Instance.Graphics.BackendThreading + }; + // Check if docked mode was overriden. if (CommandLineState.OverrideDockedMode.HasValue) ConfigurationState.Instance.System.EnableDockedMode.Value = CommandLineState.OverrideDockedMode.Value; diff --git a/src/Ryujinx/Utilities/CommandLineState.cs b/src/Ryujinx/Utilities/CommandLineState.cs index 96b5d1b86..3eafb8d01 100644 --- a/src/Ryujinx/Utilities/CommandLineState.cs +++ b/src/Ryujinx/Utilities/CommandLineState.cs @@ -10,6 +10,7 @@ namespace Ryujinx.Ava.Utilities public static bool? OverrideDockedMode { get; private set; } public static bool? OverrideHardwareAcceleration { get; private set; } public static string OverrideGraphicsBackend { get; private set; } + public static string OverrideBackendThreading { get; private set; } public static string OverrideHideCursor { get; private set; } public static string BaseDirPathArg { get; private set; } public static string Profile { get; private set; } @@ -74,6 +75,16 @@ namespace Ryujinx.Ava.Utilities OverrideGraphicsBackend = args[++i]; break; + case "--backend-threading": + if (i + 1 >= args.Length) + { + Logger.Error?.Print(LogClass.Application, $"Invalid option '{arg}'"); + + continue; + } + + OverrideBackendThreading = args[++i]; + break; case "-i": case "--application-id": LaunchApplicationId = args[++i]; -- 2.47.1 From b8fe778299bfd754410866739d11f59453f235e0 Mon Sep 17 00:00:00 2001 From: Vova Date: Sat, 1 Feb 2025 16:21:32 +1000 Subject: [PATCH 002/171] Added a window with settings for shortcuts. Added new arguments for shortcuts. When starting a game with arguments, a separate independent setting will be used --- src/Ryujinx.Common/ReleaseInformation.cs | 1 + src/Ryujinx/Program.cs | 51 +++- .../Controls/ApplicationContextMenu.axaml.cs | 10 +- .../UI/ViewModels/SettingsViewModel.cs | 76 ++++++ .../Settings/SettingsApplyOverride.axaml | 236 ++++++++++++++++++ .../Settings/SettingsApplyOverride.axaml.cs | 12 + .../UI/Windows/ArgumentsConfigWindows.axaml | 104 ++++++++ .../Windows/ArgumentsConfigWindows.axaml.cs | 167 +++++++++++++ src/Ryujinx/Utilities/CommandLineState.cs | 52 +++- src/Ryujinx/Utilities/ShortcutHelper.cs | 27 +- 10 files changed, 716 insertions(+), 20 deletions(-) create mode 100644 src/Ryujinx/UI/Views/Settings/SettingsApplyOverride.axaml create mode 100644 src/Ryujinx/UI/Views/Settings/SettingsApplyOverride.axaml.cs create mode 100644 src/Ryujinx/UI/Windows/ArgumentsConfigWindows.axaml create mode 100644 src/Ryujinx/UI/Windows/ArgumentsConfigWindows.axaml.cs diff --git a/src/Ryujinx.Common/ReleaseInformation.cs b/src/Ryujinx.Common/ReleaseInformation.cs index cbf93013f..33d0bd2b8 100644 --- a/src/Ryujinx.Common/ReleaseInformation.cs +++ b/src/Ryujinx.Common/ReleaseInformation.cs @@ -19,6 +19,7 @@ namespace Ryujinx.Common public const string ReleaseChannelRepo = "%%RYUJINX_TARGET_RELEASE_CHANNEL_REPO%%"; public static string ConfigName => !ConfigFileName.StartsWith("%%") ? ConfigFileName : "Config.json"; + public static string CustomConfigNameOverride => !ConfigFileName.StartsWith("%%") ? ConfigFileName : "CustomConfigOverride.json"; public static bool IsValid => !BuildGitHash.StartsWith("%%") && diff --git a/src/Ryujinx/Program.cs b/src/Ryujinx/Program.cs index c72aa689a..f62a9b983 100644 --- a/src/Ryujinx/Program.cs +++ b/src/Ryujinx/Program.cs @@ -159,6 +159,28 @@ namespace Ryujinx.Ava string localConfigurationPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ReleaseInformation.ConfigName); string appDataConfigurationPath = Path.Combine(AppDataManager.BaseDirPath, ReleaseInformation.ConfigName); + string overrideLocalConfigurationPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ReleaseInformation.CustomConfigNameOverride); + string overrideAppDataConfigurationPath = Path.Combine(AppDataManager.BaseDirPath, ReleaseInformation.CustomConfigNameOverride); + + // Copies and reloads the configuration file if the game was loaded with arguments + // based on global configuration + if (CommandLineState.CountArguments > 0) + { + if (File.Exists(localConfigurationPath)) + { + File.Copy(localConfigurationPath, overrideLocalConfigurationPath, overwrite: true); + } + + localConfigurationPath = overrideLocalConfigurationPath; + + if (File.Exists(appDataConfigurationPath)) + { + File.Copy(appDataConfigurationPath, overrideAppDataConfigurationPath, overwrite: true); + } + + appDataConfigurationPath = overrideAppDataConfigurationPath; + } + // Now load the configuration as the other subsystems are now registered if (File.Exists(localConfigurationPath)) { @@ -231,8 +253,35 @@ namespace Ryujinx.Ava _ => ConfigurationState.Instance.HideCursor, }; + // Check if memoryManagerMode was overridden. + if (CommandLineState.OverrideMemoryManagerMode is not null) + if (Enum.TryParse(CommandLineState.OverrideMemoryManagerMode, true, out MemoryManagerMode result)) + { + ConfigurationState.Instance.System.MemoryManagerMode.Value = result; + } - // Check if hardware-acceleration was overridden. + // Check if PPTC was overridden. + if (CommandLineState.OverridePPTC is not null) + if (Enum.TryParse(CommandLineState.OverridePPTC, true, out bool result)) + { + ConfigurationState.Instance.System.EnablePtc.Value = result; + } + + // Check if region was overridden. + if (CommandLineState.OverrideSystemRegion is not null) + if (Enum.TryParse(CommandLineState.OverrideSystemRegion, true, out Ryujinx.HLE.HOS.SystemState.RegionCode result)) + { + ConfigurationState.Instance.System.Region.Value = (Utilities.Configuration.System.Region)result; + } + + //Check if language was overridden. + if (CommandLineState.OverrideSystemLanguage is not null) + if (Enum.TryParse(CommandLineState.OverrideSystemLanguage, true, out Ryujinx.HLE.HOS.SystemState.SystemLanguage result)) + { + ConfigurationState.Instance.System.Language.Value = (Utilities.Configuration.System.Language)result; + } + + // Check if hardware-acceleration was overridden. MemoryManagerMode ( outdated! ) if (CommandLineState.OverrideHardwareAcceleration != null) UseHardwareAcceleration = CommandLineState.OverrideHardwareAcceleration.Value; } diff --git a/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml.cs b/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml.cs index dbf320465..c8b6f9604 100644 --- a/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml.cs +++ b/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml.cs @@ -377,15 +377,11 @@ namespace Ryujinx.Ava.UI.Controls png.SaveTo(fileStream); } - public void CreateApplicationShortcut_Click(object sender, RoutedEventArgs args) + public async void CreateApplicationShortcut_Click(object sender, RoutedEventArgs args) { if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel }) - ShortcutHelper.CreateAppShortcut( - viewModel.SelectedApplication.Path, - viewModel.SelectedApplication.Name, - viewModel.SelectedApplication.IdString, - viewModel.SelectedApplication.Icon - ); + await new ArgumentsConfigWindows(viewModel).ShowDialog((Window)viewModel.TopLevel); + } public async void RunApplication_Click(object sender, RoutedEventArgs args) diff --git a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs index 5a73dd574..355eb9a73 100644 --- a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs @@ -1,8 +1,10 @@ using Avalonia.Collections; using Avalonia.Controls; +using Avalonia.Media.Imaging; using Avalonia.Threading; using CommunityToolkit.Mvvm.ComponentModel; using Gommon; +using LibHac.Tools.Fs; using LibHac.Tools.FsSystem; using Ryujinx.Audio.Backends.OpenAL; using Ryujinx.Audio.Backends.SDL2; @@ -25,6 +27,7 @@ using Ryujinx.HLE.HOS.Services.Time.TimeZone; using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.IO; using System.Linq; using System.Net.NetworkInformation; using System.Runtime.InteropServices; @@ -62,12 +65,56 @@ namespace Ryujinx.Ava.UI.ViewModels public event Action CloseWindow; public event Action SaveSettingsEvent; + public event Action CompareSettingsEvent; private int _networkInterfaceIndex; private int _multiplayerModeIndex; private string _ldnPassphrase; [ObservableProperty] private string _ldnServer; public SettingsHacksViewModel DirtyHacks { get; } + public string GamePath { get; } + public string GameName { get; } + + private Bitmap _gameIcon; + + private string _gameTitle; + private string _gameId; + public Bitmap GameIcon + { + get => _gameIcon; + set + { + if (_gameIcon != value) + { + _gameIcon = value; + } + } + } + + public string GameTitle + { + get => _gameTitle; + set + { + if (_gameTitle != value) + { + _gameTitle = value; + } + } + } + + public string GameId + { + get => _gameId; + set + { + if (_gameId != value) + { + _gameId = value; + } + } + } + public int ResolutionScale { @@ -348,6 +395,30 @@ namespace Ryujinx.Ava.UI.ViewModels } } + public SettingsViewModel(VirtualFileSystem virtualFileSystem, ContentManager contentManager, string gamePath, string gameName, string gameId, byte[] gameIconData) : this() + { + _virtualFileSystem = virtualFileSystem; + _contentManager = contentManager; + + if (gameIconData != null && gameIconData.Length > 0) + { + using (var ms = new MemoryStream(gameIconData)) + { + GameIcon = new Bitmap(ms); + } + } + + GameTitle = gameName; + GameId = gameId; + + if (Program.PreviewerDetached) + { + Task.Run(LoadTimeZones); + + DirtyHacks = new SettingsHacksViewModel(this); + } + } + public SettingsViewModel() { GameDirectories = []; @@ -728,6 +799,11 @@ namespace Ryujinx.Ava.UI.ViewModels SaveSettings(); } + public void CreateShortcut() + { + CompareSettingsEvent?.Invoke(); //raises an event to create a shortcut with arguments + } + public void OkButton() { SaveSettings(); diff --git a/src/Ryujinx/UI/Views/Settings/SettingsApplyOverride.axaml b/src/Ryujinx/UI/Views/Settings/SettingsApplyOverride.axaml new file mode 100644 index 000000000..d549fe593 --- /dev/null +++ b/src/Ryujinx/UI/Views/Settings/SettingsApplyOverride.axaml @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Ryujinx/UI/Views/Settings/SettingsApplyOverride.axaml.cs b/src/Ryujinx/UI/Views/Settings/SettingsApplyOverride.axaml.cs new file mode 100644 index 000000000..d852fdc16 --- /dev/null +++ b/src/Ryujinx/UI/Views/Settings/SettingsApplyOverride.axaml.cs @@ -0,0 +1,12 @@ +using Avalonia.Controls; + +namespace Ryujinx.Ava.UI.Views.Settings +{ + public partial class SettingsApplyOverride : UserControl + { + public SettingsApplyOverride() + { + InitializeComponent(); + } + } +} diff --git a/src/Ryujinx/UI/Windows/ArgumentsConfigWindows.axaml b/src/Ryujinx/UI/Windows/ArgumentsConfigWindows.axaml new file mode 100644 index 000000000..14df02d1e --- /dev/null +++ b/src/Ryujinx/UI/Windows/ArgumentsConfigWindows.axaml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +