Replace CommandLineState with a more user-friendly CLI experience.

This commit is contained in:
GreemDev 2026-01-04 05:18:32 -06:00
parent fa55608587
commit 8ccbf33327
13 changed files with 283 additions and 319 deletions

View file

@ -44,7 +44,7 @@
<PackageVersion Include="Ryujinx.LibHac" Version="0.21.0-alpha.126" />
<PackageVersion Include="Ryujinx.UpdateClient" Version="1.0.44" />
<PackageVersion Include="Ryujinx.Systems.Update.Common" Version="1.0.44" />
<PackageVersion Include="Gommon" Version="2.8.0.1" />
<PackageVersion Include="Gommon" Version="2.8.0.4" />
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
<PackageVersion Include="Sep" Version="0.11.1" />
<PackageVersion Include="shaderc.net" Version="0.1.0" />
@ -59,4 +59,4 @@
<PackageVersion Include="System.Management" Version="9.0.2" />
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
</ItemGroup>
</Project>
</Project>

View file

@ -12,6 +12,8 @@ namespace Ryujinx.Common.Logging
{
public static class Logger
{
public static readonly TextWriter WriterProxy = new TextWriterProxy();
private static readonly Stopwatch _time;
private static readonly bool[] _enabledClasses;

View file

@ -0,0 +1,21 @@
using System;
using System.IO;
using System.Text;
namespace Ryujinx.Common.Logging
{
internal class TextWriterProxy : TextWriter
{
public override Encoding Encoding => Console.OutputEncoding;
public override void Write(string value)
{
if (value is null) return;
foreach (var line in value.Split(Console.Out.NewLine))
{
Logger.Info?.PrintMsg(LogClass.Application, line);
}
}
}
}

View file

@ -98,7 +98,14 @@ namespace Ryujinx.Ava
return 0;
}
Initialize(args);
try
{
Initialize(args);
}
catch
{
return 0;
}
LoggerAdapter.Register();
@ -143,7 +150,7 @@ namespace Ryujinx.Ava
DiscordIntegrationModule.EmulatorStartedAt = Timestamps.Now;
// Parse arguments
CommandLineState.ParseArguments(args);
RyujinxOptions.Read(args, out RyujinxOptions options);
if (OperatingSystem.IsMacOS())
{
@ -163,7 +170,7 @@ namespace Ryujinx.Ava
AppDomain.CurrentDomain.ProcessExit += (_, _) => Exit();
// Setup base data directory.
AppDataManager.Initialize(CommandLineState.BaseDirPathArg);
AppDataManager.Initialize(options.EmuDataBaseDirPath);
// Initialize the configuration.
ConfigurationState.Initialize();
@ -196,9 +203,9 @@ namespace Ryujinx.Ava
}
}
if (CommandLineState.LaunchPathArg != null)
if (options.LaunchPath != null)
{
MainWindow.DeferLoadApplication(CommandLineState.LaunchPathArg, CommandLineState.LaunchApplicationId, CommandLineState.StartFullscreenArg);
MainWindow.DeferLoadApplication(options.LaunchPath, options.LaunchApplicationId, options.StartFullscreen);
}
}
@ -222,7 +229,6 @@ namespace Ryujinx.Ava
public static void ReloadConfig(bool isRunGameWithCustomConfig = false)
{
string localConfigurationPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ReleaseInformation.ConfigName);
string appDataConfigurationPath = Path.Combine(AppDataManager.BaseDirPath, ReleaseInformation.ConfigName);
@ -273,74 +279,50 @@ namespace Ryujinx.Ava
UseHardwareAcceleration = ConfigurationState.Instance.EnableHardwareAcceleration;
// Check if graphics backend was overridden
if (CommandLineState.OverrideGraphicsBackend is not null)
ConfigurationState.Instance.Graphics.GraphicsBackend.Value = CommandLineState.OverrideGraphicsBackend.ToLower() switch
{
"opengl" => GraphicsBackend.OpenGl,
"vulkan" => GraphicsBackend.Vulkan,
_ => ConfigurationState.Instance.Graphics.GraphicsBackend
};
if (RyujinxOptions.Shared.GraphicsBackendOverride is not null)
ConfigurationState.Instance.Graphics.GraphicsBackend.Value =
RyujinxOptions.Shared.GraphicsBackendOverride.Value;
// 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
};
if (RyujinxOptions.Shared.BackendThreadingOverride is not null)
ConfigurationState.Instance.Graphics.BackendThreading.Value =
RyujinxOptions.Shared.BackendThreadingOverride.Value;
if (RyujinxOptions.Shared.BackendThreadingOverrideAfterReboot is not null)
BackendThreadingArg = RyujinxOptions.Shared.BackendThreadingOverrideAfterReboot.Value.ToString();
if (CommandLineState.OverrideBackendThreadingAfterReboot is not null)
{
BackendThreadingArg = CommandLineState.OverrideBackendThreadingAfterReboot;
}
// Check if docked mode was overriden.
if (CommandLineState.OverrideDockedMode.HasValue)
ConfigurationState.Instance.System.EnableDockedMode.Value = CommandLineState.OverrideDockedMode.Value;
if (RyujinxOptions.Shared.DockedModeOverride.HasValue)
ConfigurationState.Instance.System.EnableDockedMode.Value =
RyujinxOptions.Shared.DockedModeOverride.Value;
// Check if HideCursor was overridden.
if (CommandLineState.OverrideHideCursor is not null)
ConfigurationState.Instance.HideCursor.Value = CommandLineState.OverrideHideCursor.ToLower() switch
{
"never" => HideCursorMode.Never,
"onidle" => HideCursorMode.OnIdle,
"always" => HideCursorMode.Always,
_ => ConfigurationState.Instance.HideCursor,
};
if (RyujinxOptions.Shared.HideCursorOverride is not null)
ConfigurationState.Instance.HideCursor.Value = RyujinxOptions.Shared.HideCursorOverride.Value;
// 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;
}
if (RyujinxOptions.Shared.MemoryManagerModeOverride is not null)
ConfigurationState.Instance.System.MemoryManagerMode.Value = RyujinxOptions.Shared.MemoryManagerModeOverride.Value;
// Check if PPTC was overridden.
if (CommandLineState.OverridePPTC is not null)
if (Enum.TryParse(CommandLineState.OverridePPTC, true, out bool result))
if (RyujinxOptions.Shared.PptcOverride is not null)
if (Enum.TryParse(RyujinxOptions.Shared.PptcOverride, 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 Region result))
{
ConfigurationState.Instance.System.Region.Value = result;
}
if (RyujinxOptions.Shared.SystemRegionOverride is not null)
ConfigurationState.Instance.System.Region.Value = RyujinxOptions.Shared.SystemRegionOverride.Value;
//Check if language was overridden.
if (CommandLineState.OverrideSystemLanguage is not null)
if (Enum.TryParse(CommandLineState.OverrideSystemLanguage, true, out Language result))
{
ConfigurationState.Instance.System.Language.Value = result;
}
if (RyujinxOptions.Shared.SystemLanguageOverride is not null)
ConfigurationState.Instance.System.Language.Value = RyujinxOptions.Shared.SystemLanguageOverride.Value;
// Check if hardware-acceleration was overridden.
if (CommandLineState.OverrideHardwareAcceleration != null)
UseHardwareAcceleration = CommandLineState.OverrideHardwareAcceleration.Value;
if (RyujinxOptions.Shared.HardwareAccelerationOverride is not null)
UseHardwareAcceleration = RyujinxOptions.Shared.HardwareAccelerationOverride.Value;
}
internal static void PrintSystemInfo()

View file

@ -181,7 +181,7 @@ namespace Ryujinx.Ava.Systems
if (shouldRestart)
{
List<string> arguments = CommandLineState.Arguments.ToList();
List<string> arguments = RyujinxOptions.Shared.InputArguments.ToList();
string executableDirectory = AppDomain.CurrentDomain.BaseDirectory;
// On macOS we perform the update at relaunch.
@ -218,7 +218,7 @@ namespace Ryujinx.Ava.Systems
WorkingDirectory = executableDirectory,
};
foreach (string argument in CommandLineState.Arguments)
foreach (string argument in arguments)
{
processStart.ArgumentList.Add(argument);
}

View file

@ -95,7 +95,7 @@ namespace Ryujinx.Ava
if (result == UserResult.Yes)
{
_ = Process.Start(Environment.ProcessPath!, CommandLineState.Arguments);
_ = Process.Start(Environment.ProcessPath!, RyujinxOptions.Shared.InputArguments);
desktop.Shutdown();
Environment.Exit(0);
}

View file

@ -255,41 +255,27 @@ namespace Ryujinx.Ava.UI.ViewModels
return amiiboJson;
}
private async Task<AmiiboJson?> ReadLocalJsonFileAsync()
private AmiiboJson? ReadLocalJsonFile()
{
bool isValid = false;
AmiiboJson amiiboJson = new();
try
{
try
if (File.Exists(_amiiboJsonPath))
{
if (File.Exists(_amiiboJsonPath))
{
isValid = TryGetAmiiboJson(await File.ReadAllTextAsync(_amiiboJsonPath), out amiiboJson);
}
}
catch (Exception exception)
{
Logger.Warning?.Print(LogClass.Application, $"Unable to read data from '{_amiiboJsonPath}': {exception}");
isValid = false;
}
if (!isValid)
{
return null;
isValid = TryGetAmiiboJson(File.ReadAllText(_amiiboJsonPath), out amiiboJson);
}
}
catch (Exception exception)
{
if (!isValid)
{
Logger.Error?.Print(LogClass.Application, $"Couldn't get valid amiibo data: {exception}");
Logger.Warning?.Print(LogClass.Application, $"Unable to read data from '{_amiiboJsonPath}': {exception}");
isValid = false;
}
// Neither local file is not valid JSON, close window.
await ShowInfoDialog();
Close();
}
if (!isValid)
{
return null;
}
return amiiboJson;
@ -299,8 +285,8 @@ namespace Ryujinx.Ava.UI.ViewModels
{
AmiiboJson? amiiboJson;
if (CommandLineState.OnlyLocalAmiibo)
amiiboJson = await ReadLocalJsonFileAsync();
if (RyujinxOptions.Shared.OnlyLocalAmiibo)
amiiboJson = ReadLocalJsonFile();
else
amiiboJson = await GetMostRecentAmiiboListOrDefaultJson();

View file

@ -139,16 +139,11 @@ namespace Ryujinx.Ava.UI.Windows
Executor.ExecuteBackgroundAsync(async () =>
{
await ShowIntelMacWarningAsync();
if (CommandLineState.FirmwareToInstallPathArg.TryGet(out FilePath fwPath))
if (RyujinxOptions.Shared.FirmwareToInstallPath.TryGet(out FilePath fwPath))
{
if (fwPath is { ExistsAsFile: true, Extension: "xci" or "zip" } || fwPath.ExistsAsDirectory)
{
await Dispatcher.UIThread.InvokeAsync(() =>
ViewModel.HandleFirmwareInstallation(fwPath));
CommandLineState.FirmwareToInstallPathArg = default;
}
else
Logger.Notice.Print(LogClass.UI, "Invalid firmware type provided. Path must be a directory, or a .zip or .xci file.");
await Dispatcher.UIThread.InvokeAsync(() =>
ViewModel.HandleFirmwareInstallation(fwPath));
RyujinxOptions.Shared.FirmwareToInstallPath = default;
}
});
}
@ -278,7 +273,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, CommandLineState.Profile);
AccountManager = new AccountManager(LibHacHorizonManager.RyujinxClient, RyujinxOptions.Shared.Profile);
VirtualFileSystem.ReloadKeySet();
@ -406,7 +401,7 @@ namespace Ryujinx.Ava.UI.Windows
await Dispatcher.UIThread.InvokeAsync(async () => await UserErrorDialog.ShowUserErrorDialog(UserError.NoKeys));
}
if (!Updater.CanUpdate() || CommandLineState.HideAvailableUpdates)
if (!Updater.CanUpdate() || RyujinxOptions.Shared.HideAvailableUpdates)
return;
switch (ConfigurationState.Instance.UpdateCheckerType.Value)

View file

@ -1,221 +0,0 @@
using Gommon;
using Ryujinx.Common.Logging;
using System.Collections.Generic;
namespace Ryujinx.Ava.Utilities
{
public static class CommandLineState
{
public static string[] Arguments { get; private set; }
public static int CountArguments { get; private set; }
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 OverrideBackendThreadingAfterReboot { get; private set; }
public static string OverridePPTC { get; private set; }
public static string OverrideMemoryManagerMode { get; private set; }
public static string OverrideSystemRegion { get; private set; }
public static string OverrideSystemLanguage { get; private set; }
public static string OverrideHideCursor { get; private set; }
public static string BaseDirPathArg { get; private set; }
public static string RenderDocCaptureTitleFormat { get; private set; } =
"{EmuVersion}\n{GuestName} {GuestVersion} {GuestTitleId} {GuestArch}";
public static Optional<FilePath> FirmwareToInstallPathArg { get; set; }
public static string Profile { get; private set; }
public static string LaunchPathArg { get; private set; }
public static string LaunchApplicationId { get; private set; }
public static bool StartFullscreenArg { get; private set; }
public static bool HideAvailableUpdates { get; private set; }
public static bool OnlyLocalAmiibo { get; private set; }
public static void ParseArguments(string[] args)
{
List<string> arguments = [];
// Parse Arguments.
for (int i = 0; i < args.Length; ++i)
{
string arg = args[i];
if (arg.Contains('-') || arg.Contains("--"))
{
CountArguments++;
}
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 "-rdct":
case "--rd-capture-title-format":
if (i + 1 >= args.Length)
{
Logger.Error?.Print(LogClass.Application, $"Invalid option '{arg}'");
continue;
}
RenderDocCaptureTitleFormat = args[++i];
arguments.Add(arg);
arguments.Add(args[i]);
break;
case "--install-firmware":
if (i + 1 >= args.Length)
{
Logger.Error?.Print(LogClass.Application, $"Invalid option '{arg}'");
continue;
}
FirmwareToInstallPathArg = new FilePath(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;
case "--backend-threading":
if (i + 1 >= args.Length)
{
Logger.Error?.Print(LogClass.Application, $"Invalid option '{arg}'");
continue;
}
OverrideBackendThreading = args[++i];
break;
case "--bt":
if (i + 1 >= args.Length)
{
Logger.Error?.Print(LogClass.Application, $"Invalid option '{arg}'");
continue;
}
OverrideBackendThreadingAfterReboot = args[++i];
break;
case "--pptc":
if (i + 1 >= args.Length)
{
Logger.Error?.Print(LogClass.Application, $"Invalid option '{arg}'");
continue;
}
OverridePPTC = args[++i];
break;
case "-la":
case "--local-only-amiibo":
OnlyLocalAmiibo = true;
break;
case "-m":
case "--memory-manager-mode":
if (i + 1 >= args.Length)
{
Logger.Error?.Print(LogClass.Application, $"Invalid option '{arg}'");
continue;
}
OverrideMemoryManagerMode = args[++i];
break;
case "--system-region":
if (i + 1 >= args.Length)
{
Logger.Error?.Print(LogClass.Application, $"Invalid option '{arg}'");
continue;
}
OverrideSystemRegion = args[++i];
break;
case "--system-language":
if (i + 1 >= args.Length)
{
Logger.Error?.Print(LogClass.Application, $"Invalid option '{arg}'");
continue;
}
OverrideSystemLanguage = args[++i];
break;
case "-i":
case "--application-id":
LaunchApplicationId = args[++i];
break;
case "--docked-mode":
OverrideDockedMode = true;
break;
case "--handheld-mode":
OverrideDockedMode = false;
break;
case "--hide-cursor":
if (i + 1 >= args.Length)
{
Logger.Error?.Print(LogClass.Application, $"Invalid option '{arg}'");
continue;
}
OverrideHideCursor = args[++i];
break;
case "--hide-updates":
HideAvailableUpdates = true;
break;
case "--software-gui":
OverrideHardwareAcceleration = false;
break;
default:
LaunchPathArg = arg;
break;
}
}
Arguments = arguments.ToArray();
}
}
}

View file

@ -0,0 +1,69 @@
using CommandLine;
using Gommon;
using Ryujinx.Common.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using Error = Gommon.Error;
namespace Ryujinx.Ava.Utilities
{
public partial class RyujinxOptions
{
public static RyujinxOptions Shared { get; private set; }
public static Result Read(string[] args, out RyujinxOptions options)
{
options = null;
args = PatchLegacyArgumentNames(args);
ParserResult<RyujinxOptions> parseResult =
Parser.ParseArguments<RyujinxOptions>(args);
if (parseResult is NotParsed<RyujinxOptions> notParsed)
{
if (notParsed.Errors.None(x =>
x.Tag is ErrorType.HelpRequestedError or ErrorType.HelpVerbRequestedError))
{
Logger.Notice.Print(LogClass.Application, "Failed to parse command-line arguments:");
foreach (var error in notParsed.Errors)
{
Logger.Notice.Print(LogClass.Application, $" - {error.Tag}");
}
}
return Result.Fail;
}
options = Shared = parseResult.Value;
return parseResult.Value.Init(args);
}
private static readonly Lazy<Parser> _parser = new(() => new Parser(settings =>
{
settings.HelpWriter = Logger.WriterProxy;
settings.CaseInsensitiveEnumValues = true;
settings.CaseSensitive = false;
settings.MaximumDisplayWidth -= (int)(settings.MaximumDisplayWidth * 0.175);
}));
public static Parser Parser => _parser.Value;
private static readonly Dictionary<string, string> _legacyArgs = new()
{
{ "-rdct", "--rd-capture-title-format" },
{ "-la", "--local-only-amiibo" }
};
public static string[] PatchLegacyArgumentNames(string[] args)
{
for (int i = 0; i < args.Length; i++)
args[i] = Patch(args[i]);
return args;
string Patch(string arg) => _legacyArgs.TryGetValue(arg, out string newArgName) ? newArgName : arg;
}
}
}

View file

@ -0,0 +1,130 @@
using Avalonia.Controls;
using CommandLine;
using Gommon;
using Ryujinx.Ava.Systems.Configuration.System;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
namespace Ryujinx.Ava.Utilities
{
public partial class RyujinxOptions
{
public string[] InputArguments { get; private set; }
public bool? DockedModeOverride { get; private set; }
public bool? HardwareAccelerationOverride { get; private set; }
public Optional<FilePath> FirmwareToInstallPath { get; set; }
// Ideally I'd use an enum parse, like --docked-mode=Handheld,
// but I want to maintain backwards compatibility with shortcuts made a long time ago, as best we can.
public Result Init(string[] args)
{
InputArguments = args;
{ // Docked Mode Override
if (DockedMode && HandheldMode)
{
return Result.MessageFailure(
"Cannot be in both docked and handheld mode at the same time; choose only one.");
}
if (DockedMode) DockedModeOverride = true;
if (HandheldMode) DockedModeOverride = false;
}
{ // Hardware Acceleration Override
if (SoftwareGui)
{
HardwareAccelerationOverride = false;
}
}
FirmwareToInstallPath = Optional.Of(FirmwareToInstallPathRaw)
.Convert(x => new FilePath(x))
.OnlyIf(fp =>
{
bool result = fp is { ExistsAsFile: true, Extension: "xci" or "zip" } || fp.ExistsAsDirectory;
if (!result)
{
Logger.Notice.PrintMsg(LogClass.UI,
"Invalid firmware type provided. Path must be a directory, or a .zip or .xci file.");
}
return result;
});
return Result.Success;
}
[Option("docked-mode", Required = false, Default = false, HelpText = "Launch the game in Docked mode.")]
public bool DockedMode { get; set; }
[Option("handheld-mode", Required = false, Default = false, HelpText = "Launch the game in Handheld mode.")]
public bool HandheldMode { get; set; }
[Option("software-gui", Required = false, Default = false,
HelpText = "Disables hardware-accelerated rendering for Avalonia. Required for launching with RenderDoc.")]
public bool SoftwareGui { get; set; }
[Option('g', "graphics-backend", Required = false, Default = null,
HelpText = "Select the Graphics backend to use when launching.")]
public GraphicsBackend? GraphicsBackendOverride { get; set; }
[Option("backend-threading", Required = false, Default = null,
HelpText = "Select the Graphics backend threading option to use when launching.")]
public BackendThreading? BackendThreadingOverride { get; set; }
[Option("bt", Required = false, Default = null, Hidden = true)]
public BackendThreading? BackendThreadingOverrideAfterReboot { get; set; }
[Option("pptc", Required = false, Default = null,
HelpText = "Enable/disable PPTC regardless of your settings when launching.")]
public string PptcOverride { get; set; }
[Option('m', "memory-manager-mode", Required = false, Default = null,
HelpText = "Select the memory manager mode to use when launching.")]
public MemoryManagerMode? MemoryManagerModeOverride { get; set; }
[Option("system-region", Required = false, Default = null,
HelpText = "Select the Region to use for the emulated Switch when launching.")]
public Region? SystemRegionOverride { get; set; }
[Option("system-language", Required = false, Default = null,
HelpText = "Select the Language to use for the emulated Switch when launching.")]
public Language? SystemLanguageOverride { get; set; }
[Option("hide-cursor", Required = false, Default = null,
HelpText = "Select the cursor hiding strategy to use when launching.")]
public HideCursorMode? HideCursorOverride { get; set; }
[Option('r', "root-data-dir", Required = false, Default = null,
HelpText = "Select the folder to use for all of your Ryujinx save data, configs, etc.")]
public string EmuDataBaseDirPath { get; set; }
[Option("rd-capture-title-format", Required = false,
HelpText =
"Set the format string used for RenderDoc Capture titles when using the Start/Stop Capture buttons in Ryujinx.",
Default = "{EmuVersion}\n{GuestName} {GuestVersion} {GuestTitleId} {GuestArch}")]
public string RenderDocCaptureTitleFormat { get; set; }
[Option("install-firmware", Required = false, Default = null, HelpText = "Specify a file path containing Switch firmware to install immediately after starting. Must be a directory or a .zip or .xci file.")]
public string FirmwareToInstallPathRaw { get; set; }
[Option('p', "profile", Required = false, Default = null, HelpText = "The profile name to open the application with. Defaults to your last used profile.")]
public string Profile { get; set; }
[Option('i', "application-id", Required = false, Default = null, HelpText = "Specify which application ID out of the specified content archive path to launch.")]
public string LaunchApplicationId { get; set; }
[Option('f', "fullscreen", Required = false, Default = false, HelpText = "Start the emulator in fullscreen mode.")]
public bool StartFullscreen { get; set; }
[Option("hide-updates", Required = false, Default = false, HelpText = "Hides update prompt/notification.")]
public bool HideAvailableUpdates { get; set; }
[Option("local-only-amiibo", Required = false, Default = false, HelpText = "Only use the local Amiibo cache; do not update it even if there is an update.")]
public bool OnlyLocalAmiibo { get; set; }
[Value(0, Default = null, Required = false,
HelpText =
"The Nintendo Switch application content archive to launch immediately after starting, if desired.")]
public string LaunchPath { get; set; }
}
}

View file

@ -126,10 +126,10 @@ namespace Ryujinx.Ava.Utilities
// args are first defined as a list, for easier adjustments in the future
List<string> argsList = [];
if (!string.IsNullOrEmpty(CommandLineState.BaseDirPathArg))
if (!string.IsNullOrEmpty(RyujinxOptions.Shared.EmuDataBaseDirPath))
{
argsList.Add("--root-data-dir");
argsList.Add($"\"{CommandLineState.BaseDirPathArg}\"");
argsList.Add($"\"{RyujinxOptions.Shared.EmuDataBaseDirPath}\"");
}
if (!string.IsNullOrEmpty(config))

View file

@ -34,7 +34,7 @@ namespace Ryujinx.Ava.Utilities
string titleIdSection = $"({activeProcess.ProgramIdText.ToUpper()})";
string titleArchSection = activeProcess.Is64Bit ? "(64-bit)" : "(32-bit)";
return CommandLineState.RenderDocCaptureTitleFormat
return RyujinxOptions.Shared.RenderDocCaptureTitleFormat
.ReplaceIgnoreCase("{EmuVersion}", applicationVersion)
.ReplaceIgnoreCase("{GuestName}", titleNameSection)
.ReplaceIgnoreCase("{GuestVersion}", titleVersionSection)