aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Ui.Common/Helper
diff options
context:
space:
mode:
Diffstat (limited to 'src/Ryujinx.Ui.Common/Helper')
-rw-r--r--src/Ryujinx.Ui.Common/Helper/CommandLineState.cs99
-rw-r--r--src/Ryujinx.Ui.Common/Helper/ConsoleHelper.cs50
-rw-r--r--src/Ryujinx.Ui.Common/Helper/FileAssociationHelper.cs202
-rw-r--r--src/Ryujinx.Ui.Common/Helper/LinuxHelper.cs62
-rw-r--r--src/Ryujinx.Ui.Common/Helper/ObjectiveC.cs160
-rw-r--r--src/Ryujinx.Ui.Common/Helper/OpenHelper.cs112
-rw-r--r--src/Ryujinx.Ui.Common/Helper/SetupValidator.cs114
-rw-r--r--src/Ryujinx.Ui.Common/Helper/ShortcutHelper.cs162
-rw-r--r--src/Ryujinx.Ui.Common/Helper/TitleHelper.cs30
-rw-r--r--src/Ryujinx.Ui.Common/Helper/ValueFormatUtils.cs219
10 files changed, 0 insertions, 1210 deletions
diff --git a/src/Ryujinx.Ui.Common/Helper/CommandLineState.cs b/src/Ryujinx.Ui.Common/Helper/CommandLineState.cs
deleted file mode 100644
index 714cf2f0..00000000
--- a/src/Ryujinx.Ui.Common/Helper/CommandLineState.cs
+++ /dev/null
@@ -1,99 +0,0 @@
-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 bool? OverrideDockedMode { get; private set; }
- public static string OverrideGraphicsBackend { get; private set; }
- public static string OverrideHideCursor { 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<string> 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;
- 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;
- default:
- LaunchPathArg = arg;
- break;
- }
- }
-
- Arguments = arguments.ToArray();
- }
- }
-}
diff --git a/src/Ryujinx.Ui.Common/Helper/ConsoleHelper.cs b/src/Ryujinx.Ui.Common/Helper/ConsoleHelper.cs
deleted file mode 100644
index 65155641..00000000
--- a/src/Ryujinx.Ui.Common/Helper/ConsoleHelper.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-using Ryujinx.Common.Logging;
-using System;
-using System.Runtime.InteropServices;
-using System.Runtime.Versioning;
-
-namespace Ryujinx.Ui.Common.Helper
-{
- public static partial class ConsoleHelper
- {
- public static bool SetConsoleWindowStateSupported => OperatingSystem.IsWindows();
-
- public static void SetConsoleWindowState(bool show)
- {
- if (OperatingSystem.IsWindows())
- {
- SetConsoleWindowStateWindows(show);
- }
- else if (show == false)
- {
- Logger.Warning?.Print(LogClass.Application, "OS doesn't support hiding console window");
- }
- }
-
- [SupportedOSPlatform("windows")]
- private static void SetConsoleWindowStateWindows(bool show)
- {
- const int SW_HIDE = 0;
- const int SW_SHOW = 5;
-
- IntPtr hWnd = GetConsoleWindow();
-
- if (hWnd == IntPtr.Zero)
- {
- Logger.Warning?.Print(LogClass.Application, "Attempted to show/hide console window but console window does not exist");
- return;
- }
-
- ShowWindow(hWnd, show ? SW_SHOW : SW_HIDE);
- }
-
- [SupportedOSPlatform("windows")]
- [LibraryImport("kernel32")]
- private static partial IntPtr GetConsoleWindow();
-
- [SupportedOSPlatform("windows")]
- [LibraryImport("user32")]
- [return: MarshalAs(UnmanagedType.Bool)]
- private static partial bool ShowWindow(IntPtr hWnd, int nCmdShow);
- }
-}
diff --git a/src/Ryujinx.Ui.Common/Helper/FileAssociationHelper.cs b/src/Ryujinx.Ui.Common/Helper/FileAssociationHelper.cs
deleted file mode 100644
index daa59d25..00000000
--- a/src/Ryujinx.Ui.Common/Helper/FileAssociationHelper.cs
+++ /dev/null
@@ -1,202 +0,0 @@
-using Microsoft.Win32;
-using Ryujinx.Common;
-using Ryujinx.Common.Logging;
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Runtime.InteropServices;
-using System.Runtime.Versioning;
-
-namespace Ryujinx.Ui.Common.Helper
-{
- public static partial class FileAssociationHelper
- {
- private static readonly string[] _fileExtensions = { ".nca", ".nro", ".nso", ".nsp", ".xci" };
-
- [SupportedOSPlatform("linux")]
- private static readonly string _mimeDbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".local", "share", "mime");
-
- private const int SHCNE_ASSOCCHANGED = 0x8000000;
- private const int SHCNF_FLUSH = 0x1000;
-
- [LibraryImport("shell32.dll", SetLastError = true)]
- public static partial void SHChangeNotify(uint wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2);
-
- public static bool IsTypeAssociationSupported => (OperatingSystem.IsLinux() || OperatingSystem.IsWindows()) && !ReleaseInformation.IsFlatHubBuild;
-
- [SupportedOSPlatform("linux")]
- private static bool AreMimeTypesRegisteredLinux() => File.Exists(Path.Combine(_mimeDbPath, "packages", "Ryujinx.xml"));
-
- [SupportedOSPlatform("linux")]
- private static bool InstallLinuxMimeTypes(bool uninstall = false)
- {
- string installKeyword = uninstall ? "uninstall" : "install";
-
- if ((uninstall && AreMimeTypesRegisteredLinux()) || (!uninstall && !AreMimeTypesRegisteredLinux()))
- {
- string mimeTypesFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "mime", "Ryujinx.xml");
- string additionalArgs = !uninstall ? "--novendor" : "";
-
- using Process mimeProcess = new();
-
- mimeProcess.StartInfo.FileName = "xdg-mime";
- mimeProcess.StartInfo.Arguments = $"{installKeyword} {additionalArgs} --mode user {mimeTypesFile}";
-
- mimeProcess.Start();
- mimeProcess.WaitForExit();
-
- if (mimeProcess.ExitCode != 0)
- {
- Logger.Error?.PrintMsg(LogClass.Application, $"Unable to {installKeyword} mime types. Make sure xdg-utils is installed. Process exited with code: {mimeProcess.ExitCode}");
-
- return false;
- }
-
- using Process updateMimeProcess = new();
-
- updateMimeProcess.StartInfo.FileName = "update-mime-database";
- updateMimeProcess.StartInfo.Arguments = _mimeDbPath;
-
- updateMimeProcess.Start();
- updateMimeProcess.WaitForExit();
-
- if (updateMimeProcess.ExitCode != 0)
- {
- Logger.Error?.PrintMsg(LogClass.Application, $"Could not update local mime database. Process exited with code: {updateMimeProcess.ExitCode}");
- }
- }
-
- return true;
- }
-
- [SupportedOSPlatform("windows")]
- private static bool AreMimeTypesRegisteredWindows()
- {
- static bool CheckRegistering(string ext)
- {
- RegistryKey key = Registry.CurrentUser.OpenSubKey(@$"Software\Classes\{ext}");
-
- if (key is null)
- {
- return false;
- }
-
- var openCmd = key.OpenSubKey(@"shell\open\command");
-
- string keyValue = (string)openCmd.GetValue("");
-
- return keyValue is not null && (keyValue.Contains("Ryujinx") || keyValue.Contains(AppDomain.CurrentDomain.FriendlyName));
- }
-
- bool registered = false;
-
- foreach (string ext in _fileExtensions)
- {
- registered |= CheckRegistering(ext);
- }
-
- return registered;
- }
-
- [SupportedOSPlatform("windows")]
- private static bool InstallWindowsMimeTypes(bool uninstall = false)
- {
- static bool RegisterExtension(string ext, bool uninstall = false)
- {
- string keyString = @$"Software\Classes\{ext}";
-
- if (uninstall)
- {
- // If the types don't already exist, there's nothing to do and we can call this operation successful.
- if (!AreMimeTypesRegisteredWindows())
- {
- return true;
- }
- Logger.Debug?.Print(LogClass.Application, $"Removing type association {ext}");
- Registry.CurrentUser.DeleteSubKeyTree(keyString);
- Logger.Debug?.Print(LogClass.Application, $"Removed type association {ext}");
- }
- else
- {
- using var key = Registry.CurrentUser.CreateSubKey(keyString);
-
- if (key is null)
- {
- return false;
- }
-
- Logger.Debug?.Print(LogClass.Application, $"Adding type association {ext}");
- using var openCmd = key.CreateSubKey(@"shell\open\command");
- openCmd.SetValue("", $"\"{Environment.ProcessPath}\" \"%1\"");
- Logger.Debug?.Print(LogClass.Application, $"Added type association {ext}");
-
- }
-
- return true;
- }
-
- bool registered = false;
-
- foreach (string ext in _fileExtensions)
- {
- registered |= RegisterExtension(ext, uninstall);
- }
-
- // Notify Explorer the file association has been changed.
- SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_FLUSH, IntPtr.Zero, IntPtr.Zero);
-
- return registered;
- }
-
- public static bool AreMimeTypesRegistered()
- {
- if (OperatingSystem.IsLinux())
- {
- return AreMimeTypesRegisteredLinux();
- }
-
- if (OperatingSystem.IsWindows())
- {
- return AreMimeTypesRegisteredWindows();
- }
-
- // TODO: Add macOS support.
-
- return false;
- }
-
- public static bool Install()
- {
- if (OperatingSystem.IsLinux())
- {
- return InstallLinuxMimeTypes();
- }
-
- if (OperatingSystem.IsWindows())
- {
- return InstallWindowsMimeTypes();
- }
-
- // TODO: Add macOS support.
-
- return false;
- }
-
- public static bool Uninstall()
- {
- if (OperatingSystem.IsLinux())
- {
- return InstallLinuxMimeTypes(true);
- }
-
- if (OperatingSystem.IsWindows())
- {
- return InstallWindowsMimeTypes(true);
- }
-
- // TODO: Add macOS support.
-
- return false;
- }
- }
-}
diff --git a/src/Ryujinx.Ui.Common/Helper/LinuxHelper.cs b/src/Ryujinx.Ui.Common/Helper/LinuxHelper.cs
deleted file mode 100644
index bf647719..00000000
--- a/src/Ryujinx.Ui.Common/Helper/LinuxHelper.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Runtime.Versioning;
-
-namespace Ryujinx.Ui.Common.Helper
-{
- [SupportedOSPlatform("linux")]
- public static class LinuxHelper
- {
- // NOTE: This value was determined by manual tests and might need to be increased again.
- public const int RecommendedVmMaxMapCount = 524288;
- public const string VmMaxMapCountPath = "/proc/sys/vm/max_map_count";
- public const string SysCtlConfigPath = "/etc/sysctl.d/99-Ryujinx.conf";
- public static int VmMaxMapCount => int.Parse(File.ReadAllText(VmMaxMapCountPath));
- public static string PkExecPath { get; } = GetBinaryPath("pkexec");
-
- private static string GetBinaryPath(string binary)
- {
- string pathVar = Environment.GetEnvironmentVariable("PATH");
-
- if (pathVar is null || string.IsNullOrEmpty(binary))
- {
- return null;
- }
-
- foreach (var searchPath in pathVar.Split(":", StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries))
- {
- string binaryPath = Path.Combine(searchPath, binary);
-
- if (File.Exists(binaryPath))
- {
- return binaryPath;
- }
- }
-
- return null;
- }
-
- public static int RunPkExec(string command)
- {
- if (PkExecPath == null)
- {
- return 1;
- }
-
- using Process process = new()
- {
- StartInfo =
- {
- FileName = PkExecPath,
- ArgumentList = { "sh", "-c", command },
- },
- };
-
- process.Start();
- process.WaitForExit();
-
- return process.ExitCode;
- }
- }
-}
diff --git a/src/Ryujinx.Ui.Common/Helper/ObjectiveC.cs b/src/Ryujinx.Ui.Common/Helper/ObjectiveC.cs
deleted file mode 100644
index af8723e2..00000000
--- a/src/Ryujinx.Ui.Common/Helper/ObjectiveC.cs
+++ /dev/null
@@ -1,160 +0,0 @@
-using System;
-using System.Runtime.InteropServices;
-using System.Runtime.Versioning;
-
-namespace Ryujinx.Ui.Common.Helper
-{
- [SupportedOSPlatform("macos")]
- public static partial class ObjectiveC
- {
- private const string ObjCRuntime = "/usr/lib/libobjc.A.dylib";
-
- [LibraryImport(ObjCRuntime, StringMarshalling = StringMarshalling.Utf8)]
- private static partial IntPtr sel_getUid(string name);
-
- [LibraryImport(ObjCRuntime, StringMarshalling = StringMarshalling.Utf8)]
- private static partial IntPtr objc_getClass(string name);
-
- [LibraryImport(ObjCRuntime)]
- private static partial void objc_msgSend(IntPtr receiver, Selector selector);
-
- [LibraryImport(ObjCRuntime)]
- private static partial void objc_msgSend(IntPtr receiver, Selector selector, byte value);
-
- [LibraryImport(ObjCRuntime)]
- private static partial void objc_msgSend(IntPtr receiver, Selector selector, IntPtr value);
-
- [LibraryImport(ObjCRuntime)]
- private static partial void objc_msgSend(IntPtr receiver, Selector selector, NSRect point);
-
- [LibraryImport(ObjCRuntime)]
- private static partial void objc_msgSend(IntPtr receiver, Selector selector, double value);
-
- [LibraryImport(ObjCRuntime, EntryPoint = "objc_msgSend")]
- private static partial IntPtr IntPtr_objc_msgSend(IntPtr receiver, Selector selector);
-
- [LibraryImport(ObjCRuntime, EntryPoint = "objc_msgSend")]
- private static partial IntPtr IntPtr_objc_msgSend(IntPtr receiver, Selector selector, IntPtr param);
-
- [LibraryImport(ObjCRuntime, EntryPoint = "objc_msgSend", StringMarshalling = StringMarshalling.Utf8)]
- private static partial IntPtr IntPtr_objc_msgSend(IntPtr receiver, Selector selector, string param);
-
- [LibraryImport(ObjCRuntime, EntryPoint = "objc_msgSend")]
- [return: MarshalAs(UnmanagedType.Bool)]
- private static partial bool bool_objc_msgSend(IntPtr receiver, Selector selector, IntPtr param);
-
- public readonly struct Object
- {
- public readonly IntPtr ObjPtr;
-
- private Object(IntPtr pointer)
- {
- ObjPtr = pointer;
- }
-
- public Object(string name)
- {
- ObjPtr = objc_getClass(name);
- }
-
- public void SendMessage(Selector selector)
- {
- objc_msgSend(ObjPtr, selector);
- }
-
- public void SendMessage(Selector selector, byte value)
- {
- objc_msgSend(ObjPtr, selector, value);
- }
-
- public void SendMessage(Selector selector, Object obj)
- {
- objc_msgSend(ObjPtr, selector, obj.ObjPtr);
- }
-
- public void SendMessage(Selector selector, NSRect point)
- {
- objc_msgSend(ObjPtr, selector, point);
- }
-
- public void SendMessage(Selector selector, double value)
- {
- objc_msgSend(ObjPtr, selector, value);
- }
-
- public Object GetFromMessage(Selector selector)
- {
- return new Object(IntPtr_objc_msgSend(ObjPtr, selector));
- }
-
- public Object GetFromMessage(Selector selector, Object obj)
- {
- return new Object(IntPtr_objc_msgSend(ObjPtr, selector, obj.ObjPtr));
- }
-
- public Object GetFromMessage(Selector selector, NSString nsString)
- {
- return new Object(IntPtr_objc_msgSend(ObjPtr, selector, nsString.StrPtr));
- }
-
- public Object GetFromMessage(Selector selector, string param)
- {
- return new Object(IntPtr_objc_msgSend(ObjPtr, selector, param));
- }
-
- public bool GetBoolFromMessage(Selector selector, Object obj)
- {
- return bool_objc_msgSend(ObjPtr, selector, obj.ObjPtr);
- }
- }
-
- public readonly struct Selector
- {
- public readonly IntPtr SelPtr;
-
- private Selector(string name)
- {
- SelPtr = sel_getUid(name);
- }
-
- public static implicit operator Selector(string value) => new(value);
- }
-
- public readonly struct NSString
- {
- public readonly IntPtr StrPtr;
-
- public NSString(string aString)
- {
- IntPtr nsString = objc_getClass("NSString");
- StrPtr = IntPtr_objc_msgSend(nsString, "stringWithUTF8String:", aString);
- }
-
- public static implicit operator IntPtr(NSString nsString) => nsString.StrPtr;
- }
-
- public readonly struct NSPoint
- {
- public readonly double X;
- public readonly double Y;
-
- public NSPoint(double x, double y)
- {
- X = x;
- Y = y;
- }
- }
-
- public readonly struct NSRect
- {
- public readonly NSPoint Pos;
- public readonly NSPoint Size;
-
- public NSRect(double x, double y, double width, double height)
- {
- Pos = new NSPoint(x, y);
- Size = new NSPoint(width, height);
- }
- }
- }
-}
diff --git a/src/Ryujinx.Ui.Common/Helper/OpenHelper.cs b/src/Ryujinx.Ui.Common/Helper/OpenHelper.cs
deleted file mode 100644
index 04ebbf3b..00000000
--- a/src/Ryujinx.Ui.Common/Helper/OpenHelper.cs
+++ /dev/null
@@ -1,112 +0,0 @@
-using Ryujinx.Common.Logging;
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Runtime.InteropServices;
-
-namespace Ryujinx.Ui.Common.Helper
-{
- public static partial class OpenHelper
- {
- [LibraryImport("shell32.dll", SetLastError = true)]
- private static partial int SHOpenFolderAndSelectItems(IntPtr pidlFolder, uint cidl, IntPtr apidl, uint dwFlags);
-
- [LibraryImport("shell32.dll", SetLastError = true)]
- private static partial void ILFree(IntPtr pidlList);
-
- [LibraryImport("shell32.dll", SetLastError = true)]
- private static partial IntPtr ILCreateFromPathW([MarshalAs(UnmanagedType.LPWStr)] string pszPath);
-
- public static void OpenFolder(string path)
- {
- if (Directory.Exists(path))
- {
- Process.Start(new ProcessStartInfo
- {
- FileName = path,
- UseShellExecute = true,
- Verb = "open",
- });
- }
- else
- {
- Logger.Notice.Print(LogClass.Application, $"Directory \"{path}\" doesn't exist!");
- }
- }
-
- public static void LocateFile(string path)
- {
- if (File.Exists(path))
- {
- if (OperatingSystem.IsWindows())
- {
- IntPtr pidlList = ILCreateFromPathW(path);
- if (pidlList != IntPtr.Zero)
- {
- try
- {
- Marshal.ThrowExceptionForHR(SHOpenFolderAndSelectItems(pidlList, 0, IntPtr.Zero, 0));
- }
- finally
- {
- ILFree(pidlList);
- }
- }
- }
- else if (OperatingSystem.IsMacOS())
- {
- ObjectiveC.NSString nsStringPath = new(path);
- ObjectiveC.Object nsUrl = new("NSURL");
- var urlPtr = nsUrl.GetFromMessage("fileURLWithPath:", nsStringPath);
-
- ObjectiveC.Object nsArray = new("NSArray");
- ObjectiveC.Object urlArray = nsArray.GetFromMessage("arrayWithObject:", urlPtr);
-
- ObjectiveC.Object nsWorkspace = new("NSWorkspace");
- ObjectiveC.Object sharedWorkspace = nsWorkspace.GetFromMessage("sharedWorkspace");
-
- sharedWorkspace.SendMessage("activateFileViewerSelectingURLs:", urlArray);
- }
- else if (OperatingSystem.IsLinux())
- {
- Process.Start("dbus-send", $"--session --print-reply --dest=org.freedesktop.FileManager1 --type=method_call /org/freedesktop/FileManager1 org.freedesktop.FileManager1.ShowItems array:string:\"file://{path}\" string:\"\"");
- }
- else
- {
- OpenFolder(Path.GetDirectoryName(path));
- }
- }
- else
- {
- Logger.Notice.Print(LogClass.Application, $"File \"{path}\" doesn't exist!");
- }
- }
-
- public static void OpenUrl(string url)
- {
- if (OperatingSystem.IsWindows())
- {
- Process.Start(new ProcessStartInfo("cmd", $"/c start {url.Replace("&", "^&")}"));
- }
- else if (OperatingSystem.IsLinux())
- {
- Process.Start("xdg-open", url);
- }
- else if (OperatingSystem.IsMacOS())
- {
- ObjectiveC.NSString nsStringPath = new(url);
- ObjectiveC.Object nsUrl = new("NSURL");
- var urlPtr = nsUrl.GetFromMessage("URLWithString:", nsStringPath);
-
- ObjectiveC.Object nsWorkspace = new("NSWorkspace");
- ObjectiveC.Object sharedWorkspace = nsWorkspace.GetFromMessage("sharedWorkspace");
-
- sharedWorkspace.GetBoolFromMessage("openURL:", urlPtr);
- }
- else
- {
- Logger.Notice.Print(LogClass.Application, $"Cannot open url \"{url}\" on this platform!");
- }
- }
- }
-}
diff --git a/src/Ryujinx.Ui.Common/Helper/SetupValidator.cs b/src/Ryujinx.Ui.Common/Helper/SetupValidator.cs
deleted file mode 100644
index 65c38d7b..00000000
--- a/src/Ryujinx.Ui.Common/Helper/SetupValidator.cs
+++ /dev/null
@@ -1,114 +0,0 @@
-using Ryujinx.Common.Logging;
-using Ryujinx.HLE.FileSystem;
-using System;
-using System.IO;
-
-namespace Ryujinx.Ui.Common.Helper
-{
- /// <summary>
- /// Ensure installation validity
- /// </summary>
- public static class SetupValidator
- {
- public static bool IsFirmwareValid(ContentManager contentManager, out UserError error)
- {
- bool hasFirmware = contentManager.GetCurrentFirmwareVersion() != null;
-
- if (hasFirmware)
- {
- error = UserError.Success;
-
- return true;
- }
-
- error = UserError.NoFirmware;
-
- return false;
- }
-
- public static bool CanFixStartApplication(ContentManager contentManager, string baseApplicationPath, UserError error, out SystemVersion firmwareVersion)
- {
- try
- {
- firmwareVersion = contentManager.VerifyFirmwarePackage(baseApplicationPath);
- }
- catch (Exception)
- {
- firmwareVersion = null;
- }
-
- return error == UserError.NoFirmware && Path.GetExtension(baseApplicationPath).ToLowerInvariant() == ".xci" && firmwareVersion != null;
- }
-
- public static bool TryFixStartApplication(ContentManager contentManager, string baseApplicationPath, UserError error, out UserError outError)
- {
- if (error == UserError.NoFirmware)
- {
- string baseApplicationExtension = Path.GetExtension(baseApplicationPath).ToLowerInvariant();
-
- // If the target app to start is a XCI, try to install firmware from it
- if (baseApplicationExtension == ".xci")
- {
- SystemVersion firmwareVersion;
-
- try
- {
- firmwareVersion = contentManager.VerifyFirmwarePackage(baseApplicationPath);
- }
- catch (Exception)
- {
- firmwareVersion = null;
- }
-
- // The XCI is a valid firmware package, try to install the firmware from it!
- if (firmwareVersion != null)
- {
- try
- {
- Logger.Info?.Print(LogClass.Application, $"Installing firmware {firmwareVersion.VersionString}");
-
- contentManager.InstallFirmware(baseApplicationPath);
-
- Logger.Info?.Print(LogClass.Application, $"System version {firmwareVersion.VersionString} successfully installed.");
-
- outError = UserError.Success;
-
- return true;
- }
- catch (Exception) { }
- }
-
- outError = error;
-
- return false;
- }
- }
-
- outError = error;
-
- return false;
- }
-
- public static bool CanStartApplication(ContentManager contentManager, string baseApplicationPath, out UserError error)
- {
- if (Directory.Exists(baseApplicationPath) || File.Exists(baseApplicationPath))
- {
- string baseApplicationExtension = Path.GetExtension(baseApplicationPath).ToLowerInvariant();
-
- // NOTE: We don't force homebrew developers to install a system firmware.
- if (baseApplicationExtension == ".nro" || baseApplicationExtension == ".nso")
- {
- error = UserError.Success;
-
- return true;
- }
-
- return IsFirmwareValid(contentManager, out error);
- }
-
- error = UserError.ApplicationNotFound;
-
- return false;
- }
- }
-}
diff --git a/src/Ryujinx.Ui.Common/Helper/ShortcutHelper.cs b/src/Ryujinx.Ui.Common/Helper/ShortcutHelper.cs
deleted file mode 100644
index 3d27d3ff..00000000
--- a/src/Ryujinx.Ui.Common/Helper/ShortcutHelper.cs
+++ /dev/null
@@ -1,162 +0,0 @@
-using Ryujinx.Common;
-using Ryujinx.Common.Configuration;
-using ShellLink;
-using SixLabors.ImageSharp;
-using SixLabors.ImageSharp.Formats.Png;
-using SixLabors.ImageSharp.PixelFormats;
-using SixLabors.ImageSharp.Processing;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Runtime.Versioning;
-
-namespace Ryujinx.Ui.Common.Helper
-{
- public static class ShortcutHelper
- {
- [SupportedOSPlatform("windows")]
- private static void CreateShortcutWindows(string applicationFilePath, byte[] iconData, string iconPath, string cleanedAppName, string desktopPath)
- {
- string basePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, AppDomain.CurrentDomain.FriendlyName + ".exe");
- iconPath += ".ico";
-
- MemoryStream iconDataStream = new(iconData);
- var image = Image.Load(iconDataStream);
- image.Mutate(x => x.Resize(128, 128));
- SaveBitmapAsIcon(image, iconPath);
-
- var shortcut = Shortcut.CreateShortcut(basePath, GetArgsString(applicationFilePath), iconPath, 0);
- shortcut.StringData.NameString = cleanedAppName;
- shortcut.WriteToFile(Path.Combine(desktopPath, cleanedAppName + ".lnk"));
- }
-
- [SupportedOSPlatform("linux")]
- private static void CreateShortcutLinux(string applicationFilePath, byte[] iconData, string iconPath, string desktopPath, string cleanedAppName)
- {
- string basePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Ryujinx.sh");
- var desktopFile = EmbeddedResources.ReadAllText("Ryujinx.Ui.Common/shortcut-template.desktop");
- iconPath += ".png";
-
- var image = Image.Load<Rgba32>(iconData);
- image.SaveAsPng(iconPath);
-
- using StreamWriter outputFile = new(Path.Combine(desktopPath, cleanedAppName + ".desktop"));
- outputFile.Write(desktopFile, cleanedAppName, iconPath, $"{basePath} {GetArgsString(applicationFilePath)}");
- }
-
- [SupportedOSPlatform("macos")]
- private static void CreateShortcutMacos(string appFilePath, byte[] iconData, string desktopPath, string cleanedAppName)
- {
- string basePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Ryujinx");
- var plistFile = EmbeddedResources.ReadAllText("Ryujinx.Ui.Common/shortcut-template.plist");
- var shortcutScript = EmbeddedResources.ReadAllText("Ryujinx.Ui.Common/shortcut-launch-script.sh");
- // Macos .App folder
- string contentFolderPath = Path.Combine("/Applications", cleanedAppName + ".app", "Contents");
- string scriptFolderPath = Path.Combine(contentFolderPath, "MacOS");
-
- if (!Directory.Exists(scriptFolderPath))
- {
- Directory.CreateDirectory(scriptFolderPath);
- }
-
- // Runner script
- const string ScriptName = "runner.sh";
- string scriptPath = Path.Combine(scriptFolderPath, ScriptName);
- using StreamWriter scriptFile = new(scriptPath);
-
- scriptFile.Write(shortcutScript, basePath, GetArgsString(appFilePath));
-
- // Set execute permission
- FileInfo fileInfo = new(scriptPath);
- fileInfo.UnixFileMode |= UnixFileMode.UserExecute;
-
- // img
- string resourceFolderPath = Path.Combine(contentFolderPath, "Resources");
- if (!Directory.Exists(resourceFolderPath))
- {
- Directory.CreateDirectory(resourceFolderPath);
- }
-
- const string IconName = "icon.png";
- var image = Image.Load<Rgba32>(iconData);
- image.SaveAsPng(Path.Combine(resourceFolderPath, IconName));
-
- // plist file
- using StreamWriter outputFile = new(Path.Combine(contentFolderPath, "Info.plist"));
- outputFile.Write(plistFile, ScriptName, cleanedAppName, IconName);
- }
-
- public static void CreateAppShortcut(string applicationFilePath, string applicationName, string applicationId, byte[] iconData)
- {
- string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
- string cleanedAppName = string.Join("_", applicationName.Split(Path.GetInvalidFileNameChars()));
-
- if (OperatingSystem.IsWindows())
- {
- string iconPath = Path.Combine(AppDataManager.BaseDirPath, "games", applicationId, "app");
-
- CreateShortcutWindows(applicationFilePath, iconData, iconPath, cleanedAppName, desktopPath);
-
- return;
- }
-
- if (OperatingSystem.IsLinux())
- {
- string iconPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".local", "share", "icons", "Ryujinx");
-
- Directory.CreateDirectory(iconPath);
- CreateShortcutLinux(applicationFilePath, iconData, Path.Combine(iconPath, applicationId), desktopPath, cleanedAppName);
-
- return;
- }
-
- if (OperatingSystem.IsMacOS())
- {
- CreateShortcutMacos(applicationFilePath, iconData, desktopPath, cleanedAppName);
-
- return;
- }
-
- throw new NotImplementedException("Shortcut support has not been implemented yet for this OS.");
- }
-
- private static string GetArgsString(string appFilePath)
- {
- // args are first defined as a list, for easier adjustments in the future
- var argsList = new List<string>();
-
- if (!string.IsNullOrEmpty(CommandLineState.BaseDirPathArg))
- {
- argsList.Add("--root-data-dir");
- argsList.Add($"\"{CommandLineState.BaseDirPathArg}\"");
- }
-
- argsList.Add($"\"{appFilePath}\"");
-
- return String.Join(" ", argsList);
- }
-
- /// <summary>
- /// Creates a Icon (.ico) file using the source bitmap image at the specified file path.
- /// </summary>
- /// <param name="source">The source bitmap image that will be saved as an .ico file</param>
- /// <param name="filePath">The location that the new .ico file will be saved too (Make sure to include '.ico' in the path).</param>
- [SupportedOSPlatform("windows")]
- private static void SaveBitmapAsIcon(Image source, string filePath)
- {
- // Code Modified From https://stackoverflow.com/a/11448060/368354 by Benlitz
- byte[] header = { 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 32, 0, 0, 0, 0, 0, 22, 0, 0, 0 };
- using FileStream fs = new(filePath, FileMode.Create);
-
- fs.Write(header);
- // Writing actual data
- source.Save(fs, PngFormat.Instance);
- // Getting data length (file length minus header)
- long dataLength = fs.Length - header.Length;
- // Write it in the correct place
- fs.Seek(14, SeekOrigin.Begin);
- fs.WriteByte((byte)dataLength);
- fs.WriteByte((byte)(dataLength >> 8));
- }
- }
-}
diff --git a/src/Ryujinx.Ui.Common/Helper/TitleHelper.cs b/src/Ryujinx.Ui.Common/Helper/TitleHelper.cs
deleted file mode 100644
index 089b5215..00000000
--- a/src/Ryujinx.Ui.Common/Helper/TitleHelper.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using Ryujinx.HLE.Loaders.Processes;
-using System;
-
-namespace Ryujinx.Ui.Common.Helper
-{
- public static class TitleHelper
- {
- public static string ActiveApplicationTitle(ProcessResult activeProcess, string applicationVersion, string pauseString = "")
- {
- if (activeProcess == null)
- {
- return String.Empty;
- }
-
- string titleNameSection = string.IsNullOrWhiteSpace(activeProcess.Name) ? string.Empty : $" {activeProcess.Name}";
- string titleVersionSection = string.IsNullOrWhiteSpace(activeProcess.DisplayVersion) ? string.Empty : $" v{activeProcess.DisplayVersion}";
- string titleIdSection = $" ({activeProcess.ProgramIdText.ToUpper()})";
- string titleArchSection = activeProcess.Is64Bit ? " (64-bit)" : " (32-bit)";
-
- string appTitle = $"Ryujinx {applicationVersion} -{titleNameSection}{titleVersionSection}{titleIdSection}{titleArchSection}";
-
- if (!string.IsNullOrEmpty(pauseString))
- {
- appTitle += $" ({pauseString})";
- }
-
- return appTitle;
- }
- }
-}
diff --git a/src/Ryujinx.Ui.Common/Helper/ValueFormatUtils.cs b/src/Ryujinx.Ui.Common/Helper/ValueFormatUtils.cs
deleted file mode 100644
index b1597a7c..00000000
--- a/src/Ryujinx.Ui.Common/Helper/ValueFormatUtils.cs
+++ /dev/null
@@ -1,219 +0,0 @@
-using System;
-using System.Globalization;
-using System.Linq;
-
-namespace Ryujinx.Ui.Common.Helper
-{
- public static class ValueFormatUtils
- {
- private static readonly string[] _fileSizeUnitStrings =
- {
- "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", // Base 10 units, used for formatting and parsing
- "KB", "MB", "GB", "TB", "PB", "EB", // Base 2 units, used for parsing legacy values
- };
-
- /// <summary>
- /// Used by <see cref="FormatFileSize"/>.
- /// </summary>
- public enum FileSizeUnits
- {
- Auto = -1,
- Bytes = 0,
- Kibibytes = 1,
- Mebibytes = 2,
- Gibibytes = 3,
- Tebibytes = 4,
- Pebibytes = 5,
- Exbibytes = 6,
- Kilobytes = 7,
- Megabytes = 8,
- Gigabytes = 9,
- Terabytes = 10,
- Petabytes = 11,
- Exabytes = 12,
- }
-
- private const double SizeBase10 = 1000;
- private const double SizeBase2 = 1024;
- private const int UnitEBIndex = 6;
-
- #region Value formatters
-
- /// <summary>
- /// Creates a human-readable string from a <see cref="TimeSpan"/>.
- /// </summary>
- /// <param name="timeSpan">The <see cref="TimeSpan"/> to be formatted.</param>
- /// <returns>A formatted string that can be displayed in the UI.</returns>
- public static string FormatTimeSpan(TimeSpan? timeSpan)
- {
- if (!timeSpan.HasValue || timeSpan.Value.TotalSeconds < 1)
- {
- // Game was never played
- return TimeSpan.Zero.ToString("c", CultureInfo.InvariantCulture);
- }
-
- if (timeSpan.Value.TotalDays < 1)
- {
- // Game was played for less than a day
- return timeSpan.Value.ToString("c", CultureInfo.InvariantCulture);
- }
-
- // Game was played for more than a day
- TimeSpan onlyTime = timeSpan.Value.Subtract(TimeSpan.FromDays(timeSpan.Value.Days));
- string onlyTimeString = onlyTime.ToString("c", CultureInfo.InvariantCulture);
-
- return $"{timeSpan.Value.Days}d, {onlyTimeString}";
- }
-
- /// <summary>
- /// Creates a human-readable string from a <see cref="DateTime"/>.
- /// </summary>
- /// <param name="utcDateTime">The <see cref="DateTime"/> to be formatted. This is expected to be UTC-based.</param>
- /// <param name="culture">The <see cref="CultureInfo"/> that's used in formatting. Defaults to <see cref="CultureInfo.CurrentCulture"/>.</param>
- /// <returns>A formatted string that can be displayed in the UI.</returns>
- public static string FormatDateTime(DateTime? utcDateTime, CultureInfo culture = null)
- {
- culture ??= CultureInfo.CurrentCulture;
-
- if (!utcDateTime.HasValue)
- {
- // In the Avalonia UI, this is turned into a localized version of "Never" by LocalizedNeverConverter.
- return "Never";
- }
-
- return utcDateTime.Value.ToLocalTime().ToString(culture);
- }
-
- /// <summary>
- /// Creates a human-readable file size string.
- /// </summary>
- /// <param name="size">The file size in bytes.</param>
- /// <param name="forceUnit">Formats the passed size value as this unit, bypassing the automatic unit choice.</param>
- /// <returns>A human-readable file size string.</returns>
- public static string FormatFileSize(long size, FileSizeUnits forceUnit = FileSizeUnits.Auto)
- {
- if (size <= 0)
- {
- return $"0 {_fileSizeUnitStrings[0]}";
- }
-
- int unitIndex = (int)forceUnit;
- if (forceUnit == FileSizeUnits.Auto)
- {
- unitIndex = Convert.ToInt32(Math.Floor(Math.Log(size, SizeBase10)));
-
- // Apply an upper bound so that exabytes are the biggest unit used when formatting.
- if (unitIndex > UnitEBIndex)
- {
- unitIndex = UnitEBIndex;
- }
- }
-
- double sizeRounded;
-
- if (unitIndex > UnitEBIndex)
- {
- sizeRounded = Math.Round(size / Math.Pow(SizeBase10, unitIndex - UnitEBIndex), 1);
- }
- else
- {
- sizeRounded = Math.Round(size / Math.Pow(SizeBase2, unitIndex), 1);
- }
-
- string sizeFormatted = sizeRounded.ToString(CultureInfo.InvariantCulture);
-
- return $"{sizeFormatted} {_fileSizeUnitStrings[unitIndex]}";
- }
-
- #endregion
-
- #region Value parsers
-
- /// <summary>
- /// Parses a string generated by <see cref="FormatTimeSpan"/> and returns the original <see cref="TimeSpan"/>.
- /// </summary>
- /// <param name="timeSpanString">A string representing a <see cref="TimeSpan"/>.</param>
- /// <returns>A <see cref="TimeSpan"/> object. If the input string couldn't been parsed, <see cref="TimeSpan.Zero"/> is returned.</returns>
- public static TimeSpan ParseTimeSpan(string timeSpanString)
- {
- TimeSpan returnTimeSpan = TimeSpan.Zero;
-
- // An input string can either look like "01:23:45" or "1d, 01:23:45" if the timespan represents a duration of more than a day.
- // Here, we split the input string to check if it's the former or the latter.
- var valueSplit = timeSpanString.Split(", ");
- if (valueSplit.Length > 1)
- {
- var dayPart = valueSplit[0].Split("d")[0];
- if (int.TryParse(dayPart, out int days))
- {
- returnTimeSpan = returnTimeSpan.Add(TimeSpan.FromDays(days));
- }
- }
-
- if (TimeSpan.TryParse(valueSplit.Last(), out TimeSpan parsedTimeSpan))
- {
- returnTimeSpan = returnTimeSpan.Add(parsedTimeSpan);
- }
-
- return returnTimeSpan;
- }
-
- /// <summary>
- /// Parses a string generated by <see cref="FormatDateTime"/> and returns the original <see cref="DateTime"/>.
- /// </summary>
- /// <param name="dateTimeString">The string representing a <see cref="DateTime"/>.</param>
- /// <returns>A <see cref="DateTime"/> object. If the input string couldn't be parsed, <see cref="DateTime.UnixEpoch"/> is returned.</returns>
- public static DateTime ParseDateTime(string dateTimeString)
- {
- if (!DateTime.TryParse(dateTimeString, CultureInfo.CurrentCulture, out DateTime parsedDateTime))
- {
- // Games that were never played are supposed to appear before the oldest played games in the list,
- // so returning DateTime.UnixEpoch here makes sense.
- return DateTime.UnixEpoch;
- }
-
- return parsedDateTime;
- }
-
- /// <summary>
- /// Parses a string generated by <see cref="FormatFileSize"/> and returns a <see cref="long"/> representing a number of bytes.
- /// </summary>
- /// <param name="sizeString">A string representing a file size formatted with <see cref="FormatFileSize"/>.</param>
- /// <returns>A <see cref="long"/> representing a number of bytes.</returns>
- public static long ParseFileSize(string sizeString)
- {
- // Enumerating over the units backwards because otherwise, sizeString.EndsWith("B") would exit the loop in the first iteration.
- for (int i = _fileSizeUnitStrings.Length - 1; i >= 0; i--)
- {
- string unit = _fileSizeUnitStrings[i];
- if (!sizeString.EndsWith(unit))
- {
- continue;
- }
-
- string numberString = sizeString.Split(" ")[0];
- if (!double.TryParse(numberString, CultureInfo.InvariantCulture, out double number))
- {
- break;
- }
-
- double sizeBase = SizeBase2;
-
- // If the unit index is one that points to a base 10 unit in the FileSizeUnitStrings array, subtract 6 to arrive at a usable power value.
- if (i > UnitEBIndex)
- {
- i -= UnitEBIndex;
- sizeBase = SizeBase10;
- }
-
- number *= Math.Pow(sizeBase, i);
-
- return Convert.ToInt64(number);
- }
-
- return 0;
- }
-
- #endregion
- }
-}