From eebc39228db4663e03fa73306e725424f7ce1273 Mon Sep 17 00:00:00 2001 From: TSRBerry <20988865+TSRBerry@users.noreply.github.com> Date: Sun, 13 Nov 2022 00:36:36 +0100 Subject: [PATCH] UI: Allow overriding graphics backend + Move command line parser into a new class (#3707) * Ava: Keep command line args when restarting * UI: Move common UI functions to ProgramHelper Add command line option to override the configured graphics backend * Ava: Add CleanupUpdate task back * Remove unused usings * Revert combining common UI functions Rename ProgramHelper to CommandLineState Move command line parsing to CommandLineState * Rename CommandLineProfile to Profile * Fix assigning the wrong array to Arguments --- Ryujinx.Ava/App.axaml.cs | 4 +- Ryujinx.Ava/Program.cs | 65 +++++---------- .../Ui/ViewModels/SettingsViewModel.cs | 4 - Ryujinx.Ava/Ui/Windows/MainWindow.axaml.cs | 5 +- Ryujinx.Ui.Common/Helper/CommandLineState.cs | 81 +++++++++++++++++++ Ryujinx/Modules/Updater/UpdateDialog.cs | 7 +- Ryujinx/Program.cs | 78 ++++++------------ Ryujinx/Ui/MainWindow.cs | 4 +- 8 files changed, 137 insertions(+), 111 deletions(-) create mode 100644 Ryujinx.Ui.Common/Helper/CommandLineState.cs diff --git a/Ryujinx.Ava/App.axaml.cs b/Ryujinx.Ava/App.axaml.cs index 180c74b43..3ab1b7b8f 100644 --- a/Ryujinx.Ava/App.axaml.cs +++ b/Ryujinx.Ava/App.axaml.cs @@ -10,6 +10,7 @@ using Ryujinx.Ava.Ui.Windows; using Ryujinx.Common; using Ryujinx.Common.Logging; using Ryujinx.Ui.Common.Configuration; +using Ryujinx.Ui.Common.Helper; using System; using System.Diagnostics; using System.IO; @@ -64,8 +65,7 @@ namespace Ryujinx.Ava if (result == UserResult.Yes) { var path = Process.GetCurrentProcess().MainModule.FileName; - var info = new ProcessStartInfo() { FileName = path, UseShellExecute = false }; - var proc = Process.Start(info); + var proc = Process.Start(path, CommandLineState.Arguments); desktop.Shutdown(); Environment.Exit(0); } diff --git a/Ryujinx.Ava/Program.cs b/Ryujinx.Ava/Program.cs index 61b184c61..053bccab6 100644 --- a/Ryujinx.Ava/Program.cs +++ b/Ryujinx.Ava/Program.cs @@ -13,6 +13,7 @@ using Ryujinx.Common.SystemInfo; using Ryujinx.Modules; using Ryujinx.Ui.Common; using Ryujinx.Ui.Common.Configuration; +using Ryujinx.Ui.Common.Helper; using System; using System.IO; using System.Runtime.InteropServices; @@ -26,7 +27,6 @@ namespace Ryujinx.Ava public static double ActualScaleFactor { get; set; } public static string Version { get; private set; } public static string ConfigurationPath { get; private set; } - public static string CommandLineProfile { get; set; } public static bool PreviewerDetached { get; private set; } public static RenderTimer RenderTimer { get; private set; } @@ -87,46 +87,8 @@ namespace Ryujinx.Ava private static void Initialize(string[] args) { - // Parse Arguments. - string launchPathArg = null; - string baseDirPathArg = null; - bool startFullscreenArg = false; - - for (int i = 0; i < args.Length; ++i) - { - string arg = args[i]; - - if (arg == "-r" || arg == "--root-data-dir") - { - if (i + 1 >= args.Length) - { - Logger.Error?.Print(LogClass.Application, $"Invalid option '{arg}'"); - - continue; - } - - baseDirPathArg = args[++i]; - } - else if (arg == "-p" || arg == "--profile") - { - if (i + 1 >= args.Length) - { - Logger.Error?.Print(LogClass.Application, $"Invalid option '{arg}'"); - - continue; - } - - CommandLineProfile = args[++i]; - } - else if (arg == "-f" || arg == "--fullscreen") - { - startFullscreenArg = true; - } - else - { - launchPathArg = arg; - } - } + // Parse arguments + CommandLineState.ParseArguments(args); // Delete backup files after updating. Task.Run(Updater.CleanupUpdate); @@ -135,10 +97,10 @@ namespace Ryujinx.Ava // Hook unhandled exception and process exit events. AppDomain.CurrentDomain.UnhandledException += (object sender, UnhandledExceptionEventArgs e) => ProcessUnhandledException(e.ExceptionObject as Exception, e.IsTerminating); - AppDomain.CurrentDomain.ProcessExit += (object sender, EventArgs e) => Exit(); + AppDomain.CurrentDomain.ProcessExit += (object sender, EventArgs e) => Exit(); // Setup base data directory. - AppDataManager.Initialize(baseDirPathArg); + AppDataManager.Initialize(CommandLineState.BaseDirPathArg); // Initialize the configuration. ConfigurationState.Initialize(); @@ -173,9 +135,9 @@ namespace Ryujinx.Ava } } - if (launchPathArg != null) + if (CommandLineState.LaunchPathArg != null) { - MainWindow.DeferLoadApplication(launchPathArg, startFullscreenArg); + MainWindow.DeferLoadApplication(CommandLineState.LaunchPathArg, CommandLineState.StartFullscreenArg); } } @@ -215,6 +177,19 @@ namespace Ryujinx.Ava Logger.Warning?.PrintMsg(LogClass.Application, $"Failed to load config! Loading the default config instead.\nFailed config location {ConfigurationPath}"); } } + + // Check if graphics backend was overridden + if (CommandLineState.OverrideGraphicsBackend != null) + { + if (CommandLineState.OverrideGraphicsBackend.ToLower() == "opengl") + { + ConfigurationState.Instance.Graphics.GraphicsBackend.Value = GraphicsBackend.OpenGl; + } + else if (CommandLineState.OverrideGraphicsBackend.ToLower() == "vulkan") + { + ConfigurationState.Instance.Graphics.GraphicsBackend.Value = GraphicsBackend.Vulkan; + } + } } private static void PrintSystemInfo() diff --git a/Ryujinx.Ava/Ui/ViewModels/SettingsViewModel.cs b/Ryujinx.Ava/Ui/ViewModels/SettingsViewModel.cs index f4807023d..088bf3ac9 100644 --- a/Ryujinx.Ava/Ui/ViewModels/SettingsViewModel.cs +++ b/Ryujinx.Ava/Ui/ViewModels/SettingsViewModel.cs @@ -21,14 +21,10 @@ using Ryujinx.HLE.HOS.Services.Time.TimeZone; using Ryujinx.Input; using Ryujinx.Ui.Common.Configuration; using Ryujinx.Ui.Common.Configuration.System; -using Silk.NET.Vulkan; using System; using System.Collections.Generic; using System.Collections.ObjectModel; -using System.Diagnostics; using System.Linq; -using System.Runtime.InteropServices; -using System.Threading.Tasks; using TimeZone = Ryujinx.Ava.Ui.Models.TimeZone; namespace Ryujinx.Ava.Ui.ViewModels diff --git a/Ryujinx.Ava/Ui/Windows/MainWindow.axaml.cs b/Ryujinx.Ava/Ui/Windows/MainWindow.axaml.cs index ae79b1c9d..774178d66 100644 --- a/Ryujinx.Ava/Ui/Windows/MainWindow.axaml.cs +++ b/Ryujinx.Ava/Ui/Windows/MainWindow.axaml.cs @@ -23,6 +23,7 @@ using Ryujinx.Modules; using Ryujinx.Ui.App.Common; using Ryujinx.Ui.Common; using Ryujinx.Ui.Common.Configuration; +using Ryujinx.Ui.Common.Helper; using SixLabors.ImageSharp.PixelFormats; using System; using System.ComponentModel; @@ -247,7 +248,7 @@ namespace Ryujinx.Ava.Ui.Windows { RendererControl.CreateVulkan(); } - + AppHost = new AppHost(RendererControl, InputManager, path, VirtualFileSystem, ContentManager, AccountManager, _userChannelPersistence, this); if (!AppHost.LoadGuestApplication().Result) @@ -432,7 +433,7 @@ namespace Ryujinx.Ava.Ui.Windows // Consider removing this at some point in the future when we don't need to worry about old saves. VirtualFileSystem.FixExtraData(LibHacHorizonManager.RyujinxClient); - AccountManager = new AccountManager(LibHacHorizonManager.RyujinxClient, Program.CommandLineProfile); + AccountManager = new AccountManager(LibHacHorizonManager.RyujinxClient, CommandLineState.Profile); VirtualFileSystem.ReloadKeySet(); diff --git a/Ryujinx.Ui.Common/Helper/CommandLineState.cs b/Ryujinx.Ui.Common/Helper/CommandLineState.cs new file mode 100644 index 000000000..cda4af4ed --- /dev/null +++ b/Ryujinx.Ui.Common/Helper/CommandLineState.cs @@ -0,0 +1,81 @@ +using Ryujinx.Common.Logging; +using System.Collections.Generic; + +namespace Ryujinx.Ui.Common.Helper +{ + public static class CommandLineState + { + public static string[] Arguments { get; private set; } + + public static string OverrideGraphicsBackend { get; private set; } + public static string BaseDirPathArg { get; private set; } + public static string Profile { get; private set; } + public static string LaunchPathArg { get; private set; } + public static bool StartFullscreenArg { get; private set; } + + public static void ParseArguments(string[] args) + { + List arguments = new(); + + // Parse Arguments. + for (int i = 0; i < args.Length; ++i) + { + string arg = args[i]; + + switch (arg) + { + case "-r": + case "--root-data-dir": + if (i + 1 >= args.Length) + { + Logger.Error?.Print(LogClass.Application, $"Invalid option '{arg}'"); + + continue; + } + + BaseDirPathArg = args[++i]; + + arguments.Add(arg); + arguments.Add(args[i]); + break; + case "-p": + case "--profile": + if (i + 1 >= args.Length) + { + Logger.Error?.Print(LogClass.Application, $"Invalid option '{arg}'"); + + continue; + } + + Profile = args[++i]; + + arguments.Add(arg); + arguments.Add(args[i]); + break; + case "-f": + case "--fullscreen": + StartFullscreenArg = true; + + arguments.Add(arg); + break; + case "-g": + case "--graphics-backend": + if (i + 1 >= args.Length) + { + Logger.Error?.Print(LogClass.Application, $"Invalid option '{arg}'"); + + continue; + } + + OverrideGraphicsBackend = args[++i]; + break; + default: + LaunchPathArg = arg; + break; + } + } + + Arguments = arguments.ToArray(); + } + } +} \ No newline at end of file diff --git a/Ryujinx/Modules/Updater/UpdateDialog.cs b/Ryujinx/Modules/Updater/UpdateDialog.cs index cdf85427e..cb71fafc9 100644 --- a/Ryujinx/Modules/Updater/UpdateDialog.cs +++ b/Ryujinx/Modules/Updater/UpdateDialog.cs @@ -2,9 +2,9 @@ using Gdk; using Gtk; using Ryujinx.Ui; using Ryujinx.Ui.Common.Configuration; +using Ryujinx.Ui.Common.Helper; using System; using System.Diagnostics; -using System.Linq; using System.Reflection; namespace Ryujinx.Modules @@ -48,9 +48,8 @@ namespace Ryujinx.Modules { string ryuName = OperatingSystem.IsWindows() ? "Ryujinx.exe" : "Ryujinx"; string ryuExe = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ryuName); - var ryuArg = Environment.GetCommandLineArgs().AsEnumerable().Skip(1); - Process.Start(ryuExe, ryuArg); + Process.Start(ryuExe, CommandLineState.Arguments); Environment.Exit(0); } @@ -81,4 +80,4 @@ namespace Ryujinx.Modules Dispose(); } } -} +} \ No newline at end of file diff --git a/Ryujinx/Program.cs b/Ryujinx/Program.cs index d9db941de..a91f9aa52 100644 --- a/Ryujinx/Program.cs +++ b/Ryujinx/Program.cs @@ -6,10 +6,11 @@ using Ryujinx.Common.GraphicsDriver; using Ryujinx.Common.Logging; using Ryujinx.Common.System; using Ryujinx.Common.SystemInfo; -using Ryujinx.Ui.Common.Configuration; using Ryujinx.Modules; using Ryujinx.Ui; using Ryujinx.Ui.Common; +using Ryujinx.Ui.Common.Configuration; +using Ryujinx.Ui.Common.Helper; using Ryujinx.Ui.Widgets; using SixLabors.ImageSharp.Formats.Jpeg; using System; @@ -28,8 +29,6 @@ namespace Ryujinx public static string ConfigurationPath { get; set; } - public static string CommandLineProfile { get; set; } - [DllImport("libX11")] private extern static int XInitThreads(); @@ -47,46 +46,13 @@ namespace Ryujinx MessageBoxA(IntPtr.Zero, "You are running an outdated version of Windows.\n\nStarting on June 1st 2022, Ryujinx will only support Windows 10 1803 and newer.\n", $"Ryujinx {Version}", MB_ICONWARNING); } - // Parse Arguments. - string launchPathArg = null; - string baseDirPathArg = null; - bool startFullscreenArg = false; + // Parse arguments + CommandLineState.ParseArguments(args); - for (int i = 0; i < args.Length; ++i) - { - string arg = args[i]; - - if (arg == "-r" || arg == "--root-data-dir") - { - if (i + 1 >= args.Length) - { - Logger.Error?.Print(LogClass.Application, $"Invalid option '{arg}'"); - - continue; - } - - baseDirPathArg = args[++i]; - } - else if (arg == "-p" || arg == "--profile") - { - if (i + 1 >= args.Length) - { - Logger.Error?.Print(LogClass.Application, $"Invalid option '{arg}'"); - - continue; - } - - CommandLineProfile = args[++i]; - } - else if (arg == "-f" || arg == "--fullscreen") - { - startFullscreenArg = true; - } - else if (launchPathArg == null) - { - launchPathArg = arg; - } - } + // Hook unhandled exception and process exit events. + GLib.ExceptionManager.UnhandledException += (GLib.UnhandledExceptionArgs e) => ProcessUnhandledException(e.ExceptionObject as Exception, e.IsTerminating); + AppDomain.CurrentDomain.UnhandledException += (object sender, UnhandledExceptionEventArgs e) => ProcessUnhandledException(e.ExceptionObject as Exception, e.IsTerminating); + AppDomain.CurrentDomain.ProcessExit += (object sender, EventArgs e) => Exit(); // Make process DPI aware for proper window sizing on high-res screens. ForceDpiAware.Windows(); @@ -95,8 +61,6 @@ namespace Ryujinx // Delete backup files after updating. Task.Run(Updater.CleanupUpdate); - Console.Title = $"Ryujinx Console {Version}"; - // NOTE: GTK3 doesn't init X11 in a multi threaded way. // This ends up causing race condition and abort of XCB when a context is created by SPB (even if SPB do call XInitThreads). if (OperatingSystem.IsLinux()) @@ -107,13 +71,8 @@ namespace Ryujinx string systemPath = Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.Machine); Environment.SetEnvironmentVariable("Path", $"{Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin")};{systemPath}"); - // Hook unhandled exception and process exit events. - GLib.ExceptionManager.UnhandledException += (GLib.UnhandledExceptionArgs e) => ProcessUnhandledException(e.ExceptionObject as Exception, e.IsTerminating); - AppDomain.CurrentDomain.UnhandledException += (object sender, UnhandledExceptionEventArgs e) => ProcessUnhandledException(e.ExceptionObject as Exception, e.IsTerminating); - AppDomain.CurrentDomain.ProcessExit += (object sender, EventArgs e) => Exit(); - // Setup base data directory. - AppDataManager.Initialize(baseDirPathArg); + AppDataManager.Initialize(CommandLineState.BaseDirPathArg); // Initialize the configuration. ConfigurationState.Initialize(); @@ -173,6 +132,21 @@ namespace Ryujinx } } + // Check if graphics backend was overridden + if (CommandLineState.OverrideGraphicsBackend != null) + { + if (CommandLineState.OverrideGraphicsBackend.ToLower() == "opengl") + { + ConfigurationState.Instance.Graphics.GraphicsBackend.Value = GraphicsBackend.OpenGl; + showVulkanPrompt = false; + } + else if (CommandLineState.OverrideGraphicsBackend.ToLower() == "vulkan") + { + ConfigurationState.Instance.Graphics.GraphicsBackend.Value = GraphicsBackend.Vulkan; + showVulkanPrompt = false; + } + } + // Logging system information. PrintSystemInfo(); @@ -195,9 +169,9 @@ namespace Ryujinx MainWindow mainWindow = new MainWindow(); mainWindow.Show(); - if (launchPathArg != null) + if (CommandLineState.LaunchPathArg != null) { - mainWindow.LoadApplication(launchPathArg, startFullscreenArg); + mainWindow.LoadApplication(CommandLineState.LaunchPathArg, CommandLineState.StartFullscreenArg); } if (ConfigurationState.Instance.CheckUpdatesOnStart.Value && Updater.CanUpdate(false)) diff --git a/Ryujinx/Ui/MainWindow.cs b/Ryujinx/Ui/MainWindow.cs index c0b2e1b66..c78b7a2f2 100644 --- a/Ryujinx/Ui/MainWindow.cs +++ b/Ryujinx/Ui/MainWindow.cs @@ -179,7 +179,7 @@ namespace Ryujinx.Ui VirtualFileSystem.FixExtraData(_libHacHorizonManager.RyujinxClient); _contentManager = new ContentManager(_virtualFileSystem); - _accountManager = new AccountManager(_libHacHorizonManager.RyujinxClient, Program.CommandLineProfile); + _accountManager = new AccountManager(_libHacHorizonManager.RyujinxClient, CommandLineState.Profile); _userChannelPersistence = new UserChannelPersistence(); // Instantiate GUI objects. @@ -1752,4 +1752,4 @@ namespace Ryujinx.Ui UpdateGameTable(); } } -} +} \ No newline at end of file