[Ryujinx] Address dotnet-format issues (#5395)

* dotnet format style --severity info

Some changes were manually reverted.

* dotnet format analyzers --serverity info

Some changes have been minimally adapted.

* Restore a few unused methods and variables

* Address dotnet format CA1816 warnings

* Address or silence dotnet format CA2208 warnings

* Address or silence dotnet format CA1806 and a few CA1854 warnings

* Address dotnet format CA1822 warnings

* Make dotnet format succeed in style mode

* Address dotnet format CA2208 warnings properly

* Address most dotnet format whitespace warnings

* Apply dotnet format whitespace formatting

A few of them have been manually reverted and the corresponding warning was silenced

* Format if-blocks correctly

* Another rebase, another dotnet format run

* Run dotnet format whitespace after rebase

* Run dotnet format after rebase and remove unused usings

- analyzers
- style
- whitespace

* Add comments to disabled warnings

* Simplify properties and array initialization, Use const when possible, Remove trailing commas

* Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas"

This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e.

* dotnet format whitespace after rebase

* First dotnet format pass

* Fix build issues

* Apply suggestions from code review

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Second dotnet format pass

* Update src/Ryujinx/Modules/Updater/Updater.cs

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Add trailing commas and improve formatting

* Fix formatting and naming issues

* Rename nvStutterWorkaround to nvidiaStutterWorkaround

* Use using declarations and extend resource lifetimes

* Fix GTK issues

* Add formatting for generated files

* Add trailing commas

---------

Co-authored-by: Ac_K <Acoustik666@gmail.com>
This commit is contained in:
TSRBerry 2023-07-02 00:25:07 +02:00 committed by GitHub
parent 02b5c7ea89
commit 0684b00b3c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
39 changed files with 1891 additions and 1830 deletions

View file

@ -25,7 +25,7 @@ namespace Ryujinx.Input.GTK3
private readonly GTK3KeyboardDriver _driver; private readonly GTK3KeyboardDriver _driver;
private StandardKeyboardInputConfig _configuration; private StandardKeyboardInputConfig _configuration;
private List<ButtonMappingEntry> _buttonsUserMapping; private readonly List<ButtonMappingEntry> _buttonsUserMapping;
public GTK3Keyboard(GTK3KeyboardDriver driver, string id, string name) public GTK3Keyboard(GTK3KeyboardDriver driver, string id, string name)
{ {
@ -48,6 +48,7 @@ namespace Ryujinx.Input.GTK3
public void Dispose() public void Dispose()
{ {
// No operations // No operations
GC.SuppressFinalize(this);
} }
public KeyboardStateSnapshot GetKeyboardStateSnapshot() public KeyboardStateSnapshot GetKeyboardStateSnapshot()
@ -87,7 +88,7 @@ namespace Ryujinx.Input.GTK3
stickX -= 1; stickX -= 1;
} }
OpenTK.Mathematics.Vector2 stick = new OpenTK.Mathematics.Vector2(stickX, stickY); OpenTK.Mathematics.Vector2 stick = new(stickX, stickY);
stick.NormalizeFast(); stick.NormalizeFast();

View file

@ -9,7 +9,7 @@ namespace Ryujinx.Input.GTK3
public class GTK3KeyboardDriver : IGamepadDriver public class GTK3KeyboardDriver : IGamepadDriver
{ {
private readonly Widget _widget; private readonly Widget _widget;
private HashSet<GtkKey> _pressedKeys; private readonly HashSet<GtkKey> _pressedKeys;
public GTK3KeyboardDriver(Widget widget) public GTK3KeyboardDriver(Widget widget)
{ {
@ -49,6 +49,7 @@ namespace Ryujinx.Input.GTK3
public void Dispose() public void Dispose()
{ {
GC.SuppressFinalize(this);
Dispose(true); Dispose(true);
} }

View file

@ -83,6 +83,7 @@ namespace Ryujinx.Input.GTK3
public void Dispose() public void Dispose()
{ {
GC.SuppressFinalize(this);
_driver = null; _driver = null;
} }
} }

View file

@ -14,7 +14,7 @@ namespace Ryujinx.Input.GTK3
public bool[] PressedButtons { get; } public bool[] PressedButtons { get; }
public Vector2 CurrentPosition { get; private set; } public Vector2 CurrentPosition { get; private set; }
public Vector2 Scroll{ get; private set; } public Vector2 Scroll { get; private set; }
public GTK3MouseDriver(Widget parent) public GTK3MouseDriver(Widget parent)
{ {
@ -58,7 +58,7 @@ namespace Ryujinx.Input.GTK3
public bool IsButtonPressed(MouseButton button) public bool IsButtonPressed(MouseButton button)
{ {
return PressedButtons[(int) button]; return PressedButtons[(int)button];
} }
public Size GetClientSize() public Size GetClientSize()
@ -80,7 +80,7 @@ namespace Ryujinx.Input.GTK3
remove { } remove { }
} }
public ReadOnlySpan<string> GamepadsIds => new[] {"0"}; public ReadOnlySpan<string> GamepadsIds => new[] { "0" };
public IGamepad GetGamepad(string id) public IGamepad GetGamepad(string id)
{ {
@ -94,6 +94,8 @@ namespace Ryujinx.Input.GTK3
return; return;
} }
GC.SuppressFinalize(this);
_isDisposed = true; _isDisposed = true;
_widget.MotionNotifyEvent -= Parent_MotionNotifyEvent; _widget.MotionNotifyEvent -= Parent_MotionNotifyEvent;

View file

@ -12,7 +12,7 @@ namespace Ryujinx.Modules
{ {
public class UpdateDialog : Gtk.Window public class UpdateDialog : Gtk.Window
{ {
#pragma warning disable CS0649, IDE0044 #pragma warning disable CS0649, IDE0044 // Field is never assigned to, Add readonly modifier
[Builder.Object] public Label MainText; [Builder.Object] public Label MainText;
[Builder.Object] public Label SecondaryText; [Builder.Object] public Label SecondaryText;
[Builder.Object] public LevelBar ProgressBar; [Builder.Object] public LevelBar ProgressBar;
@ -52,7 +52,7 @@ namespace Ryujinx.Modules
ProcessStartInfo processStart = new(ryuName) ProcessStartInfo processStart = new(ryuName)
{ {
UseShellExecute = true, UseShellExecute = true,
WorkingDirectory = ReleaseInformation.GetBaseApplicationDirectory() WorkingDirectory = ReleaseInformation.GetBaseApplicationDirectory(),
}; };
foreach (string argument in CommandLineState.Arguments) foreach (string argument in CommandLineState.Arguments)

View file

@ -24,28 +24,28 @@ namespace Ryujinx.Modules
{ {
public static class Updater public static class Updater
{ {
private const string GitHubApiURL = "https://api.github.com"; private const string GitHubApiUrl = "https://api.github.com";
private const int ConnectionCount = 4; private const int ConnectionCount = 4;
internal static bool Running; internal static bool Running;
private static readonly string HomeDir = AppDomain.CurrentDomain.BaseDirectory; private static readonly string _homeDir = AppDomain.CurrentDomain.BaseDirectory;
private static readonly string UpdateDir = Path.Combine(Path.GetTempPath(), "Ryujinx", "update"); private static readonly string _updateDir = Path.Combine(Path.GetTempPath(), "Ryujinx", "update");
private static readonly string UpdatePublishDir = Path.Combine(UpdateDir, "publish"); private static readonly string _updatePublishDir = Path.Combine(_updateDir, "publish");
private static string _buildVer; private static string _buildVer;
private static string _platformExt; private static string _platformExt;
private static string _buildUrl; private static string _buildUrl;
private static long _buildSize; private static long _buildSize;
private static readonly GithubReleasesJsonSerializerContext SerializerContext = new(JsonHelper.GetDefaultSerializerOptions()); private static readonly GithubReleasesJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
// On Windows, GtkSharp.Dependencies adds these extra dirs that must be cleaned during updates. // On Windows, GtkSharp.Dependencies adds these extra dirs that must be cleaned during updates.
private static readonly string[] WindowsDependencyDirs = new string[] { "bin", "etc", "lib", "share" }; private static readonly string[] _windowsDependencyDirs = { "bin", "etc", "lib", "share" };
private static HttpClient ConstructHttpClient() private static HttpClient ConstructHttpClient()
{ {
HttpClient result = new HttpClient(); HttpClient result = new();
// Required by GitHub to interact with APIs. // Required by GitHub to interact with APIs.
result.DefaultRequestHeaders.Add("User-Agent", "Ryujinx-Updater/1.0.0"); result.DefaultRequestHeaders.Add("User-Agent", "Ryujinx-Updater/1.0.0");
@ -55,7 +55,10 @@ namespace Ryujinx.Modules
public static async Task BeginParse(MainWindow mainWindow, bool showVersionUpToDate) public static async Task BeginParse(MainWindow mainWindow, bool showVersionUpToDate)
{ {
if (Running) return; if (Running)
{
return;
}
Running = true; Running = true;
mainWindow.UpdateMenuItem.Sensitive = false; mainWindow.UpdateMenuItem.Sensitive = false;
@ -105,11 +108,11 @@ namespace Ryujinx.Modules
try try
{ {
using HttpClient jsonClient = ConstructHttpClient(); using HttpClient jsonClient = ConstructHttpClient();
string buildInfoURL = $"{GitHubApiURL}/repos/{ReleaseInformation.ReleaseChannelOwner}/{ReleaseInformation.ReleaseChannelRepo}/releases/latest"; string buildInfoUrl = $"{GitHubApiUrl}/repos/{ReleaseInformation.ReleaseChannelOwner}/{ReleaseInformation.ReleaseChannelRepo}/releases/latest";
// Fetch latest build information // Fetch latest build information
string fetchedJson = await jsonClient.GetStringAsync(buildInfoURL); string fetchedJson = await jsonClient.GetStringAsync(buildInfoUrl);
var fetched = JsonHelper.Deserialize(fetchedJson, SerializerContext.GithubReleasesJsonResponse); var fetched = JsonHelper.Deserialize(fetchedJson, _serializerContext.GithubReleasesJsonResponse);
_buildVer = fetched.Name; _buildVer = fetched.Name;
foreach (var asset in fetched.Assets) foreach (var asset in fetched.Assets)
@ -176,8 +179,7 @@ namespace Ryujinx.Modules
} }
// Fetch build size information to learn chunk sizes. // Fetch build size information to learn chunk sizes.
using (HttpClient buildSizeClient = ConstructHttpClient()) using HttpClient buildSizeClient = ConstructHttpClient();
{
try try
{ {
buildSizeClient.DefaultRequestHeaders.Add("Range", "bytes=0-0"); buildSizeClient.DefaultRequestHeaders.Add("Range", "bytes=0-0");
@ -193,24 +195,23 @@ namespace Ryujinx.Modules
_buildSize = -1; _buildSize = -1;
} }
}
// Show a message asking the user if they want to update // Show a message asking the user if they want to update
UpdateDialog updateDialog = new UpdateDialog(mainWindow, newVersion, _buildUrl); UpdateDialog updateDialog = new(mainWindow, newVersion, _buildUrl);
updateDialog.Show(); updateDialog.Show();
} }
public static void UpdateRyujinx(UpdateDialog updateDialog, string downloadUrl) public static void UpdateRyujinx(UpdateDialog updateDialog, string downloadUrl)
{ {
// Empty update dir, although it shouldn't ever have anything inside it // Empty update dir, although it shouldn't ever have anything inside it
if (Directory.Exists(UpdateDir)) if (Directory.Exists(_updateDir))
{ {
Directory.Delete(UpdateDir, true); Directory.Delete(_updateDir, true);
} }
Directory.CreateDirectory(UpdateDir); Directory.CreateDirectory(_updateDir);
string updateFile = Path.Combine(UpdateDir, "update.bin"); string updateFile = Path.Combine(_updateDir, "update.bin");
// Download the update .zip // Download the update .zip
updateDialog.MainText.Text = "Downloading Update..."; updateDialog.MainText.Text = "Downloading Update...";
@ -237,8 +238,8 @@ namespace Ryujinx.Modules
int totalProgressPercentage = 0; int totalProgressPercentage = 0;
int[] progressPercentage = new int[ConnectionCount]; int[] progressPercentage = new int[ConnectionCount];
List<byte[]> list = new List<byte[]>(ConnectionCount); List<byte[]> list = new(ConnectionCount);
List<WebClient> webClients = new List<WebClient>(ConnectionCount); List<WebClient> webClients = new(ConnectionCount);
for (int i = 0; i < ConnectionCount; i++) for (int i = 0; i < ConnectionCount; i++)
{ {
@ -249,7 +250,7 @@ namespace Ryujinx.Modules
{ {
#pragma warning disable SYSLIB0014 #pragma warning disable SYSLIB0014
// TODO: WebClient is obsolete and need to be replaced with a more complex logic using HttpClient. // TODO: WebClient is obsolete and need to be replaced with a more complex logic using HttpClient.
using WebClient client = new WebClient(); using WebClient client = new();
#pragma warning restore SYSLIB0014 #pragma warning restore SYSLIB0014
webClients.Add(client); webClients.Add(client);
@ -337,15 +338,14 @@ namespace Ryujinx.Modules
private static void DoUpdateWithSingleThreadWorker(UpdateDialog updateDialog, string downloadUrl, string updateFile) private static void DoUpdateWithSingleThreadWorker(UpdateDialog updateDialog, string downloadUrl, string updateFile)
{ {
using HttpClient client = new HttpClient(); using HttpClient client = new();
// We do not want to timeout while downloading // We do not want to timeout while downloading
client.Timeout = TimeSpan.FromDays(1); client.Timeout = TimeSpan.FromDays(1);
using (HttpResponseMessage response = client.GetAsync(downloadUrl, HttpCompletionOption.ResponseHeadersRead).Result) using HttpResponseMessage response = client.GetAsync(downloadUrl, HttpCompletionOption.ResponseHeadersRead).Result;
using (Stream remoteFileStream = response.Content.ReadAsStreamAsync().Result) using Stream remoteFileStream = response.Content.ReadAsStreamAsync().Result;
{ using Stream updateFileStream = File.Open(updateFile, FileMode.Create);
using (Stream updateFileStream = File.Open(updateFile, FileMode.Create))
{
long totalBytes = response.Content.Headers.ContentLength.Value; long totalBytes = response.Content.Headers.ContentLength.Value;
long byteWritten = 0; long byteWritten = 0;
@ -365,17 +365,15 @@ namespace Ryujinx.Modules
updateDialog.ProgressBar.Value = ((double)byteWritten / totalBytes) * 100; updateDialog.ProgressBar.Value = ((double)byteWritten / totalBytes) * 100;
updateFileStream.Write(buffer, 0, readSize); updateFileStream.Write(buffer, 0, readSize);
} }
}
}
InstallUpdate(updateDialog, updateFile); InstallUpdate(updateDialog, updateFile);
} }
private static void DoUpdateWithSingleThread(UpdateDialog updateDialog, string downloadUrl, string updateFile) private static void DoUpdateWithSingleThread(UpdateDialog updateDialog, string downloadUrl, string updateFile)
{ {
Thread worker = new Thread(() => DoUpdateWithSingleThreadWorker(updateDialog, downloadUrl, updateFile)) Thread worker = new(() => DoUpdateWithSingleThreadWorker(updateDialog, downloadUrl, updateFile))
{ {
Name = "Updater.SingleThreadWorker" Name = "Updater.SingleThreadWorker",
}; };
worker.Start(); worker.Start();
} }
@ -390,7 +388,7 @@ namespace Ryujinx.Modules
{ {
using Stream inStream = File.OpenRead(updateFile); using Stream inStream = File.OpenRead(updateFile);
using Stream gzipStream = new GZipInputStream(inStream); using Stream gzipStream = new GZipInputStream(inStream);
using TarInputStream tarStream = new TarInputStream(gzipStream, Encoding.ASCII); using TarInputStream tarStream = new(gzipStream, Encoding.ASCII);
updateDialog.ProgressBar.MaxValue = inStream.Length; updateDialog.ProgressBar.MaxValue = inStream.Length;
await Task.Run(() => await Task.Run(() =>
@ -401,16 +399,17 @@ namespace Ryujinx.Modules
{ {
while ((tarEntry = tarStream.GetNextEntry()) != null) while ((tarEntry = tarStream.GetNextEntry()) != null)
{ {
if (tarEntry.IsDirectory) continue; if (tarEntry.IsDirectory)
{
continue;
}
string outPath = Path.Combine(UpdateDir, tarEntry.Name); string outPath = Path.Combine(_updateDir, tarEntry.Name);
Directory.CreateDirectory(Path.GetDirectoryName(outPath)); Directory.CreateDirectory(Path.GetDirectoryName(outPath));
using (FileStream outStream = File.OpenWrite(outPath)) using FileStream outStream = File.OpenWrite(outPath);
{
tarStream.CopyEntryContents(outStream); tarStream.CopyEntryContents(outStream);
}
File.SetUnixFileMode(outPath, (UnixFileMode)tarEntry.TarHeader.Mode); File.SetUnixFileMode(outPath, (UnixFileMode)tarEntry.TarHeader.Mode);
File.SetLastWriteTime(outPath, DateTime.SpecifyKind(tarEntry.ModTime, DateTimeKind.Utc)); File.SetLastWriteTime(outPath, DateTime.SpecifyKind(tarEntry.ModTime, DateTimeKind.Utc));
@ -430,24 +429,25 @@ namespace Ryujinx.Modules
else else
{ {
using Stream inStream = File.OpenRead(updateFile); using Stream inStream = File.OpenRead(updateFile);
using ZipFile zipFile = new ZipFile(inStream); using ZipFile zipFile = new(inStream);
updateDialog.ProgressBar.MaxValue = zipFile.Count; updateDialog.ProgressBar.MaxValue = zipFile.Count;
await Task.Run(() => await Task.Run(() =>
{ {
foreach (ZipEntry zipEntry in zipFile) foreach (ZipEntry zipEntry in zipFile)
{ {
if (zipEntry.IsDirectory) continue; if (zipEntry.IsDirectory)
{
continue;
}
string outPath = Path.Combine(UpdateDir, zipEntry.Name); string outPath = Path.Combine(_updateDir, zipEntry.Name);
Directory.CreateDirectory(Path.GetDirectoryName(outPath)); Directory.CreateDirectory(Path.GetDirectoryName(outPath));
using (Stream zipStream = zipFile.GetInputStream(zipEntry)) using Stream zipStream = zipFile.GetInputStream(zipEntry);
using (FileStream outStream = File.OpenWrite(outPath)) using FileStream outStream = File.OpenWrite(outPath);
{
zipStream.CopyTo(outStream); zipStream.CopyTo(outStream);
}
File.SetLastWriteTime(outPath, DateTime.SpecifyKind(zipEntry.DateTime, DateTimeKind.Utc)); File.SetLastWriteTime(outPath, DateTime.SpecifyKind(zipEntry.DateTime, DateTimeKind.Utc));
@ -492,13 +492,13 @@ namespace Ryujinx.Modules
{ {
updateDialog.MainText.Text = "Adding New Files..."; updateDialog.MainText.Text = "Adding New Files...";
updateDialog.ProgressBar.Value = 0; updateDialog.ProgressBar.Value = 0;
updateDialog.ProgressBar.MaxValue = Directory.GetFiles(UpdatePublishDir, "*", SearchOption.AllDirectories).Length; updateDialog.ProgressBar.MaxValue = Directory.GetFiles(_updatePublishDir, "*", SearchOption.AllDirectories).Length;
}); });
MoveAllFilesOver(UpdatePublishDir, HomeDir, updateDialog); MoveAllFilesOver(_updatePublishDir, _homeDir, updateDialog);
}); });
Directory.Delete(UpdateDir, true); Directory.Delete(_updateDir, true);
updateDialog.MainText.Text = "Update Complete!"; updateDialog.MainText.Text = "Update Complete!";
updateDialog.SecondaryText.Text = "Do you want to restart Ryujinx now?"; updateDialog.SecondaryText.Text = "Do you want to restart Ryujinx now?";
@ -563,15 +563,15 @@ namespace Ryujinx.Modules
// NOTE: This method should always reflect the latest build layout. // NOTE: This method should always reflect the latest build layout.
private static IEnumerable<string> EnumerateFilesToDelete() private static IEnumerable<string> EnumerateFilesToDelete()
{ {
var files = Directory.EnumerateFiles(HomeDir); // All files directly in base dir. var files = Directory.EnumerateFiles(_homeDir); // All files directly in base dir.
// Determine and exclude user files only when the updater is running, not when cleaning old files // Determine and exclude user files only when the updater is running, not when cleaning old files
if (Running) if (Running)
{ {
// Compare the loose files in base directory against the loose files from the incoming update, and store foreign ones in a user list. // Compare the loose files in base directory against the loose files from the incoming update, and store foreign ones in a user list.
var oldFiles = Directory.EnumerateFiles(HomeDir, "*", SearchOption.TopDirectoryOnly).Select(Path.GetFileName); var oldFiles = Directory.EnumerateFiles(_homeDir, "*", SearchOption.TopDirectoryOnly).Select(Path.GetFileName);
var newFiles = Directory.EnumerateFiles(UpdatePublishDir, "*", SearchOption.TopDirectoryOnly).Select(Path.GetFileName); var newFiles = Directory.EnumerateFiles(_updatePublishDir, "*", SearchOption.TopDirectoryOnly).Select(Path.GetFileName);
var userFiles = oldFiles.Except(newFiles).Select(filename => Path.Combine(HomeDir, filename)); var userFiles = oldFiles.Except(newFiles).Select(filename => Path.Combine(_homeDir, filename));
// Remove user files from the paths in files. // Remove user files from the paths in files.
files = files.Except(userFiles); files = files.Except(userFiles);
@ -579,9 +579,9 @@ namespace Ryujinx.Modules
if (OperatingSystem.IsWindows()) if (OperatingSystem.IsWindows())
{ {
foreach (string dir in WindowsDependencyDirs) foreach (string dir in _windowsDependencyDirs)
{ {
string dirPath = Path.Combine(HomeDir, dir); string dirPath = Path.Combine(_homeDir, dir);
if (Directory.Exists(dirPath)) if (Directory.Exists(dirPath))
{ {
files = files.Concat(Directory.EnumerateFiles(dirPath, "*", SearchOption.AllDirectories)); files = files.Concat(Directory.EnumerateFiles(dirPath, "*", SearchOption.AllDirectories));

View file

@ -43,10 +43,7 @@ namespace Ryujinx
[LibraryImport("libc", SetLastError = true)] [LibraryImport("libc", SetLastError = true)]
private static partial int setenv([MarshalAs(UnmanagedType.LPStr)] string name, [MarshalAs(UnmanagedType.LPStr)] string value, int overwrite); private static partial int setenv([MarshalAs(UnmanagedType.LPStr)] string name, [MarshalAs(UnmanagedType.LPStr)] string value, int overwrite);
[LibraryImport("libc")] private const uint MbIconWarning = 0x30;
private static partial IntPtr getenv([MarshalAs(UnmanagedType.LPStr)] string name);
private const uint MB_ICONWARNING = 0x30;
static Program() static Program()
{ {
@ -78,7 +75,7 @@ namespace Ryujinx
if (OperatingSystem.IsWindows() && !OperatingSystem.IsWindowsVersionAtLeast(10, 0, 17134)) if (OperatingSystem.IsWindows() && !OperatingSystem.IsWindowsVersionAtLeast(10, 0, 17134))
{ {
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); 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}", MbIconWarning);
} }
// Parse arguments // Parse arguments
@ -102,7 +99,11 @@ namespace Ryujinx
// This ends up causing race condition and abort of XCB when a context is created by SPB (even if SPB do call XInitThreads). // 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()) if (OperatingSystem.IsLinux())
{ {
XInitThreads(); if (XInitThreads() == 0)
{
throw new NotSupportedException("Failed to initialize multi-threading support.");
}
Environment.SetEnvironmentVariable("GDK_BACKEND", "x11"); Environment.SetEnvironmentVariable("GDK_BACKEND", "x11");
setenv("GDK_BACKEND", "x11", 1); setenv("GDK_BACKEND", "x11", 1);
} }
@ -121,7 +122,7 @@ namespace Ryujinx
resourcesDataDir = baseDirectory; resourcesDataDir = baseDirectory;
} }
void SetEnvironmentVariableNoCaching(string key, string value) static void SetEnvironmentVariableNoCaching(string key, string value)
{ {
int res = setenv(key, value, 1); int res = setenv(key, value, 1);
Debug.Assert(res != -1); Debug.Assert(res != -1);
@ -163,7 +164,7 @@ namespace Ryujinx
// Sets ImageSharp Jpeg Encoder Quality. // Sets ImageSharp Jpeg Encoder Quality.
SixLabors.ImageSharp.Configuration.Default.ImageFormatsManager.SetEncoder(JpegFormat.Instance, new JpegEncoder() SixLabors.ImageSharp.Configuration.Default.ImageFormatsManager.SetEncoder(JpegFormat.Instance, new JpegEncoder()
{ {
Quality = 100 Quality = 100,
}); });
string localConfigurationPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json"); string localConfigurationPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json");
@ -232,7 +233,7 @@ namespace Ryujinx
"never" => HideCursorMode.Never, "never" => HideCursorMode.Never,
"onidle" => HideCursorMode.OnIdle, "onidle" => HideCursorMode.OnIdle,
"always" => HideCursorMode.Always, "always" => HideCursorMode.Always,
_ => ConfigurationState.Instance.HideCursor.Value _ => ConfigurationState.Instance.HideCursor.Value,
}; };
} }
@ -261,7 +262,7 @@ namespace Ryujinx
} }
// Show the main window UI. // Show the main window UI.
MainWindow mainWindow = new MainWindow(); MainWindow mainWindow = new();
mainWindow.Show(); mainWindow.Show();
if (OperatingSystem.IsLinux()) if (OperatingSystem.IsLinux())
@ -278,7 +279,7 @@ namespace Ryujinx
{ {
{ 0, "Yes, until the next restart" }, { 0, "Yes, until the next restart" },
{ 1, "Yes, permanently" }, { 1, "Yes, permanently" },
{ 2, "No" } { 2, "No" },
}; };
ResponseType response = GtkDialog.CreateCustomDialog( ResponseType response = GtkDialog.CreateCustomDialog(
@ -347,7 +348,7 @@ namespace Ryujinx
var buttonTexts = new Dictionary<int, string>() var buttonTexts = new Dictionary<int, string>()
{ {
{ 0, "Yes (Vulkan)" }, { 0, "Yes (Vulkan)" },
{ 1, "No (OpenGL)" } { 1, "No (OpenGL)" },
}; };
ResponseType response = GtkDialog.CreateCustomDialog( ResponseType response = GtkDialog.CreateCustomDialog(

View file

@ -12,8 +12,8 @@ namespace Ryujinx.Ui.Applet
internal class GtkDynamicTextInputHandler : IDynamicTextInputHandler internal class GtkDynamicTextInputHandler : IDynamicTextInputHandler
{ {
private readonly Window _parent; private readonly Window _parent;
private readonly OffscreenWindow _inputToTextWindow = new OffscreenWindow(); private readonly OffscreenWindow _inputToTextWindow = new();
private readonly RawInputToTextEntry _inputToTextEntry = new RawInputToTextEntry(); private readonly RawInputToTextEntry _inputToTextEntry = new();
private bool _canProcessInput; private bool _canProcessInput;

View file

@ -5,7 +5,6 @@ using Ryujinx.HLE.Ui;
using Ryujinx.Ui.Widgets; using Ryujinx.Ui.Widgets;
using System; using System;
using System.Threading; using System.Threading;
using Action = System.Action;
namespace Ryujinx.Ui.Applet namespace Ryujinx.Ui.Applet
{ {
@ -37,7 +36,7 @@ namespace Ryujinx.Ui.Applet
public bool DisplayMessageDialog(string title, string message) public bool DisplayMessageDialog(string title, string message)
{ {
ManualResetEvent dialogCloseEvent = new ManualResetEvent(false); ManualResetEvent dialogCloseEvent = new(false);
bool okPressed = false; bool okPressed = false;
@ -51,7 +50,7 @@ namespace Ryujinx.Ui.Applet
{ {
Title = title, Title = title,
Text = message, Text = message,
UseMarkup = true UseMarkup = true,
}; };
msgDialog.SetDefaultSize(400, 0); msgDialog.SetDefaultSize(400, 0);
@ -84,7 +83,7 @@ namespace Ryujinx.Ui.Applet
public bool DisplayInputDialog(SoftwareKeyboardUiArgs args, out string userText) public bool DisplayInputDialog(SoftwareKeyboardUiArgs args, out string userText)
{ {
ManualResetEvent dialogCloseEvent = new ManualResetEvent(false); ManualResetEvent dialogCloseEvent = new(false);
bool okPressed = false; bool okPressed = false;
bool error = false; bool error = false;
@ -98,7 +97,7 @@ namespace Ryujinx.Ui.Applet
{ {
Title = "Software Keyboard", Title = "Software Keyboard",
Text = args.HeaderText, Text = args.HeaderText,
SecondaryText = args.SubtitleText SecondaryText = args.SubtitleText,
}; };
swkbdDialog.InputEntry.Text = inputText; swkbdDialog.InputEntry.Text = inputText;
@ -143,7 +142,7 @@ namespace Ryujinx.Ui.Applet
public bool DisplayErrorAppletDialog(string title, string message, string[] buttons) public bool DisplayErrorAppletDialog(string title, string message, string[] buttons)
{ {
ManualResetEvent dialogCloseEvent = new ManualResetEvent(false); ManualResetEvent dialogCloseEvent = new(false);
bool showDetails = false; bool showDetails = false;
@ -151,12 +150,12 @@ namespace Ryujinx.Ui.Applet
{ {
try try
{ {
ErrorAppletDialog msgDialog = new ErrorAppletDialog(_parent, DialogFlags.DestroyWithParent, MessageType.Error, buttons) ErrorAppletDialog msgDialog = new(_parent, DialogFlags.DestroyWithParent, MessageType.Error, buttons)
{ {
Title = title, Title = title,
Text = message, Text = message,
UseMarkup = true, UseMarkup = true,
WindowPosition = WindowPosition.CenterAlways WindowPosition = WindowPosition.CenterAlways,
}; };
msgDialog.SetDefaultSize(400, 0); msgDialog.SetDefaultSize(400, 0);
@ -193,19 +192,6 @@ namespace Ryujinx.Ui.Applet
return showDetails; return showDetails;
} }
private void SynchronousGtkInvoke(Action action)
{
var waitHandle = new ManualResetEventSlim();
Application.Invoke(delegate
{
action();
waitHandle.Set();
});
waitHandle.Wait();
}
public IDynamicTextInputHandler CreateDynamicTextInputHandler() public IDynamicTextInputHandler CreateDynamicTextInputHandler()
{ {
return new GtkDynamicTextInputHandler(_parent); return new GtkDynamicTextInputHandler(_parent);

View file

@ -19,7 +19,7 @@ namespace Ryujinx.Ui.Applet
public GtkHostUiTheme(Window parent) public GtkHostUiTheme(Window parent)
{ {
Entry entry = new Entry(); Entry entry = new();
entry.SetStateFlags(StateFlags.Selected, true); entry.SetStateFlags(StateFlags.Selected, true);
// Get the font and some colors directly from GTK. // Get the font and some colors directly from GTK.
@ -30,10 +30,10 @@ namespace Ryujinx.Ui.Applet
var defaultForegroundColor = entry.StyleContext.GetColor(StateFlags.Normal); var defaultForegroundColor = entry.StyleContext.GetColor(StateFlags.Normal);
var selectedForegroundColor = entry.StyleContext.GetColor(StateFlags.Selected); var selectedForegroundColor = entry.StyleContext.GetColor(StateFlags.Selected);
DefaultForegroundColor = new ThemeColor((float) defaultForegroundColor.Alpha, (float) defaultForegroundColor.Red, (float) defaultForegroundColor.Green, (float) defaultForegroundColor.Blue); DefaultForegroundColor = new ThemeColor((float)defaultForegroundColor.Alpha, (float)defaultForegroundColor.Red, (float)defaultForegroundColor.Green, (float)defaultForegroundColor.Blue);
SelectionForegroundColor = new ThemeColor((float)selectedForegroundColor.Alpha, (float)selectedForegroundColor.Red, (float)selectedForegroundColor.Green, (float)selectedForegroundColor.Blue); SelectionForegroundColor = new ThemeColor((float)selectedForegroundColor.Alpha, (float)selectedForegroundColor.Red, (float)selectedForegroundColor.Green, (float)selectedForegroundColor.Blue);
ListBoxRow row = new ListBoxRow(); ListBoxRow row = new();
row.SetStateFlags(StateFlags.Selected, true); row.SetStateFlags(StateFlags.Selected, true);
// Request the main thread to render some UI elements to an image to get an approximation for the color. // Request the main thread to render some UI elements to an image to get an approximation for the color.
@ -67,7 +67,7 @@ namespace Ryujinx.Ui.Applet
SelectionBackgroundColor = DefaultBorderColor; SelectionBackgroundColor = DefaultBorderColor;
} }
private ThemeColor ToThemeColor(byte[] data) private static ThemeColor ToThemeColor(byte[] data)
{ {
Debug.Assert(data.Length == 4 * RenderSurfaceWidth * RenderSurfaceHeight); Debug.Assert(data.Length == 4 * RenderSurfaceWidth * RenderSurfaceHeight);

View file

@ -9,7 +9,9 @@ namespace Ryujinx.Ui.Applet
{ {
private int _inputMin; private int _inputMin;
private int _inputMax; private int _inputMax;
#pragma warning disable IDE0052 // Remove unread private member
private KeyboardMode _mode; private KeyboardMode _mode;
#pragma warning restore IDE0052
private string _validationInfoText = ""; private string _validationInfoText = "";
@ -28,12 +30,12 @@ namespace Ryujinx.Ui.Applet
_validationInfo = new Label() _validationInfo = new Label()
{ {
Visible = false Visible = false,
}; };
InputEntry = new Entry() InputEntry = new Entry()
{ {
Visible = true Visible = true,
}; };
InputEntry.Activated += OnInputActivated; InputEntry.Activated += OnInputActivated;

View file

@ -12,7 +12,7 @@ namespace Ryujinx.Ui.Helper
{ {
private const string LibObjCImport = "/usr/lib/libobjc.A.dylib"; private const string LibObjCImport = "/usr/lib/libobjc.A.dylib";
private struct Selector private readonly struct Selector
{ {
public readonly IntPtr NativePtr; public readonly IntPtr NativePtr;
@ -29,7 +29,7 @@ namespace Ryujinx.Ui.Helper
NativePtr = sel_registerName(data); NativePtr = sel_registerName(data);
} }
public static implicit operator Selector(string value) => new Selector(value); public static implicit operator Selector(string value) => new(value);
} }
private static unsafe IntPtr GetClass(string value) private static unsafe IntPtr GetClass(string value)
@ -45,27 +45,27 @@ namespace Ryujinx.Ui.Helper
return objc_getClass(data); return objc_getClass(data);
} }
private struct NSPoint private struct NsPoint
{ {
public double X; public double X;
public double Y; public double Y;
public NSPoint(double x, double y) public NsPoint(double x, double y)
{ {
X = x; X = x;
Y = y; Y = y;
} }
} }
private struct NSRect private struct NsRect
{ {
public NSPoint Pos; public NsPoint Pos;
public NSPoint Size; public NsPoint Size;
public NSRect(double x, double y, double width, double height) public NsRect(double x, double y, double width, double height)
{ {
Pos = new NSPoint(x, y); Pos = new NsPoint(x, y);
Size = new NSPoint(width, height); Size = new NsPoint(width, height);
} }
} }
@ -81,7 +81,7 @@ namespace Ryujinx.Ui.Helper
// Create a child NSView to render into. // Create a child NSView to render into.
IntPtr nsViewClass = GetClass("NSView"); IntPtr nsViewClass = GetClass("NSView");
IntPtr child = IntPtr_objc_msgSend(nsViewClass, "alloc"); IntPtr child = IntPtr_objc_msgSend(nsViewClass, "alloc");
objc_msgSend(child, "init", new NSRect()); objc_msgSend(child, "init", new NsRect());
// Add it as a child. // Add it as a child.
objc_msgSend(nsView, "addSubview:", child); objc_msgSend(nsView, "addSubview:", child);
@ -92,11 +92,12 @@ namespace Ryujinx.Ui.Helper
objc_msgSend(metalLayer, "setContentsScale:", (double)display.GetMonitorAtWindow(window).ScaleFactor); objc_msgSend(metalLayer, "setContentsScale:", (double)display.GetMonitorAtWindow(window).ScaleFactor);
// Set the frame position/location. // Set the frame position/location.
updateBounds = (Window window) => { updateBounds = (Window window) =>
{
window.GetPosition(out int x, out int y); window.GetPosition(out int x, out int y);
int width = window.Width; int width = window.Width;
int height = window.Height; int height = window.Height;
objc_msgSend(child, "setFrame:", new NSRect(x, y, width, height)); objc_msgSend(child, "setFrame:", new NsRect(x, y, width, height));
}; };
updateBounds(window); updateBounds(window);
@ -120,7 +121,7 @@ namespace Ryujinx.Ui.Helper
private static partial void objc_msgSend(IntPtr receiver, Selector selector, IntPtr value); private static partial void objc_msgSend(IntPtr receiver, Selector selector, IntPtr value);
[LibraryImport(LibObjCImport)] [LibraryImport(LibObjCImport)]
private static partial void objc_msgSend(IntPtr receiver, Selector selector, NSRect point); private static partial void objc_msgSend(IntPtr receiver, Selector selector, NsRect point);
[LibraryImport(LibObjCImport)] [LibraryImport(LibObjCImport)]
private static partial void objc_msgSend(IntPtr receiver, Selector selector, double value); private static partial void objc_msgSend(IntPtr receiver, Selector selector, double value);

View file

@ -16,7 +16,7 @@ namespace Ryujinx.Ui.Helper
if (File.Exists(ConfigurationState.Instance.Ui.CustomThemePath) && (Path.GetExtension(ConfigurationState.Instance.Ui.CustomThemePath) == ".css")) if (File.Exists(ConfigurationState.Instance.Ui.CustomThemePath) && (Path.GetExtension(ConfigurationState.Instance.Ui.CustomThemePath) == ".css"))
{ {
CssProvider cssProvider = new CssProvider(); CssProvider cssProvider = new();
cssProvider.LoadFromPath(ConfigurationState.Instance.Ui.CustomThemePath); cssProvider.LoadFromPath(ConfigurationState.Instance.Ui.CustomThemePath);

View file

@ -18,8 +18,6 @@ using Ryujinx.Common.SystemInterop;
using Ryujinx.Cpu; using Ryujinx.Cpu;
using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.GAL.Multithreading; using Ryujinx.Graphics.GAL.Multithreading;
using Ryujinx.Graphics.OpenGL;
using Ryujinx.Graphics.Vulkan;
using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS; using Ryujinx.HLE.HOS;
using Ryujinx.HLE.HOS.Services.Account.Acc; using Ryujinx.HLE.HOS.Services.Account.Acc;
@ -81,7 +79,7 @@ namespace Ryujinx.Ui
public bool IsFocused; public bool IsFocused;
#pragma warning disable CS0169, CS0649, IDE0044 #pragma warning disable CS0169, CS0649, IDE0044, IDE0051 // Field is never assigned to, Add readonly modifier, Remove unused private member
[GUI] public MenuItem ExitMenuItem; [GUI] public MenuItem ExitMenuItem;
[GUI] public MenuItem UpdateMenuItem; [GUI] public MenuItem UpdateMenuItem;
@ -143,7 +141,7 @@ namespace Ryujinx.Ui
[GUI] Label _loadingStatusLabel; [GUI] Label _loadingStatusLabel;
[GUI] Gtk.ProgressBar _loadingStatusBar; [GUI] Gtk.ProgressBar _loadingStatusBar;
#pragma warning restore CS0649, IDE0044, CS0169 #pragma warning restore CS0649, IDE0044, CS0169, IDE0051
public MainWindow() : this(new Builder("Ryujinx.Ui.MainWindow.glade")) { } public MainWindow() : this(new Builder("Ryujinx.Ui.MainWindow.glade")) { }
@ -237,16 +235,46 @@ namespace Ryujinx.Ui
_fileTypesSubMenu.Visible = FileAssociationHelper.IsTypeAssociationSupported; _fileTypesSubMenu.Visible = FileAssociationHelper.IsTypeAssociationSupported;
if (ConfigurationState.Instance.Ui.GuiColumns.FavColumn) _favToggle.Active = true; if (ConfigurationState.Instance.Ui.GuiColumns.FavColumn)
if (ConfigurationState.Instance.Ui.GuiColumns.IconColumn) _iconToggle.Active = true; {
if (ConfigurationState.Instance.Ui.GuiColumns.AppColumn) _appToggle.Active = true; _favToggle.Active = true;
if (ConfigurationState.Instance.Ui.GuiColumns.DevColumn) _developerToggle.Active = true; }
if (ConfigurationState.Instance.Ui.GuiColumns.VersionColumn) _versionToggle.Active = true; if (ConfigurationState.Instance.Ui.GuiColumns.IconColumn)
if (ConfigurationState.Instance.Ui.GuiColumns.TimePlayedColumn) _timePlayedToggle.Active = true; {
if (ConfigurationState.Instance.Ui.GuiColumns.LastPlayedColumn) _lastPlayedToggle.Active = true; _iconToggle.Active = true;
if (ConfigurationState.Instance.Ui.GuiColumns.FileExtColumn) _fileExtToggle.Active = true; }
if (ConfigurationState.Instance.Ui.GuiColumns.FileSizeColumn) _fileSizeToggle.Active = true; if (ConfigurationState.Instance.Ui.GuiColumns.AppColumn)
if (ConfigurationState.Instance.Ui.GuiColumns.PathColumn) _pathToggle.Active = true; {
_appToggle.Active = true;
}
if (ConfigurationState.Instance.Ui.GuiColumns.DevColumn)
{
_developerToggle.Active = true;
}
if (ConfigurationState.Instance.Ui.GuiColumns.VersionColumn)
{
_versionToggle.Active = true;
}
if (ConfigurationState.Instance.Ui.GuiColumns.TimePlayedColumn)
{
_timePlayedToggle.Active = true;
}
if (ConfigurationState.Instance.Ui.GuiColumns.LastPlayedColumn)
{
_lastPlayedToggle.Active = true;
}
if (ConfigurationState.Instance.Ui.GuiColumns.FileExtColumn)
{
_fileExtToggle.Active = true;
}
if (ConfigurationState.Instance.Ui.GuiColumns.FileSizeColumn)
{
_fileSizeToggle.Active = true;
}
if (ConfigurationState.Instance.Ui.GuiColumns.PathColumn)
{
_pathToggle.Active = true;
}
_favToggle.Toggled += Fav_Toggled; _favToggle.Toggled += Fav_Toggled;
_iconToggle.Toggled += Icon_Toggled; _iconToggle.Toggled += Icon_Toggled;
@ -321,10 +349,7 @@ namespace Ryujinx.Ui
private void UpdateDockedModeState(object sender, ReactiveEventArgs<bool> e) private void UpdateDockedModeState(object sender, ReactiveEventArgs<bool> e)
{ {
if (_emulationContext != null) _emulationContext?.System.ChangeDockedModeState(e.NewValue);
{
_emulationContext.System.ChangeDockedModeState(e.NewValue);
}
} }
private void UpdateAudioVolumeState(object sender, ReactiveEventArgs<float> e) private void UpdateAudioVolumeState(object sender, ReactiveEventArgs<float> e)
@ -354,19 +379,49 @@ namespace Ryujinx.Ui
_gameTable.RemoveColumn(column); _gameTable.RemoveColumn(column);
} }
CellRendererToggle favToggle = new CellRendererToggle(); CellRendererToggle favToggle = new();
favToggle.Toggled += FavToggle_Toggled; favToggle.Toggled += FavToggle_Toggled;
if (ConfigurationState.Instance.Ui.GuiColumns.FavColumn) _gameTable.AppendColumn("Fav", favToggle, "active", 0); if (ConfigurationState.Instance.Ui.GuiColumns.FavColumn)
if (ConfigurationState.Instance.Ui.GuiColumns.IconColumn) _gameTable.AppendColumn("Icon", new CellRendererPixbuf(), "pixbuf", 1); {
if (ConfigurationState.Instance.Ui.GuiColumns.AppColumn) _gameTable.AppendColumn("Application", new CellRendererText(), "text", 2); _gameTable.AppendColumn("Fav", favToggle, "active", 0);
if (ConfigurationState.Instance.Ui.GuiColumns.DevColumn) _gameTable.AppendColumn("Developer", new CellRendererText(), "text", 3); }
if (ConfigurationState.Instance.Ui.GuiColumns.VersionColumn) _gameTable.AppendColumn("Version", new CellRendererText(), "text", 4); if (ConfigurationState.Instance.Ui.GuiColumns.IconColumn)
if (ConfigurationState.Instance.Ui.GuiColumns.TimePlayedColumn) _gameTable.AppendColumn("Time Played", new CellRendererText(), "text", 5); {
if (ConfigurationState.Instance.Ui.GuiColumns.LastPlayedColumn) _gameTable.AppendColumn("Last Played", new CellRendererText(), "text", 6); _gameTable.AppendColumn("Icon", new CellRendererPixbuf(), "pixbuf", 1);
if (ConfigurationState.Instance.Ui.GuiColumns.FileExtColumn) _gameTable.AppendColumn("File Ext", new CellRendererText(), "text", 7); }
if (ConfigurationState.Instance.Ui.GuiColumns.FileSizeColumn) _gameTable.AppendColumn("File Size", new CellRendererText(), "text", 8); if (ConfigurationState.Instance.Ui.GuiColumns.AppColumn)
if (ConfigurationState.Instance.Ui.GuiColumns.PathColumn) _gameTable.AppendColumn("Path", new CellRendererText(), "text", 9); {
_gameTable.AppendColumn("Application", new CellRendererText(), "text", 2);
}
if (ConfigurationState.Instance.Ui.GuiColumns.DevColumn)
{
_gameTable.AppendColumn("Developer", new CellRendererText(), "text", 3);
}
if (ConfigurationState.Instance.Ui.GuiColumns.VersionColumn)
{
_gameTable.AppendColumn("Version", new CellRendererText(), "text", 4);
}
if (ConfigurationState.Instance.Ui.GuiColumns.TimePlayedColumn)
{
_gameTable.AppendColumn("Time Played", new CellRendererText(), "text", 5);
}
if (ConfigurationState.Instance.Ui.GuiColumns.LastPlayedColumn)
{
_gameTable.AppendColumn("Last Played", new CellRendererText(), "text", 6);
}
if (ConfigurationState.Instance.Ui.GuiColumns.FileExtColumn)
{
_gameTable.AppendColumn("File Ext", new CellRendererText(), "text", 7);
}
if (ConfigurationState.Instance.Ui.GuiColumns.FileSizeColumn)
{
_gameTable.AppendColumn("File Size", new CellRendererText(), "text", 8);
}
if (ConfigurationState.Instance.Ui.GuiColumns.PathColumn)
{
_gameTable.AppendColumn("Path", new CellRendererText(), "text", 9);
}
foreach (TreeViewColumn column in _gameTable.Columns) foreach (TreeViewColumn column in _gameTable.Columns)
{ {
@ -426,11 +481,11 @@ namespace Ryujinx.Ui
if (ConfigurationState.Instance.Graphics.GraphicsBackend == GraphicsBackend.Vulkan) if (ConfigurationState.Instance.Graphics.GraphicsBackend == GraphicsBackend.Vulkan)
{ {
string preferredGpu = ConfigurationState.Instance.Graphics.PreferredGpu.Value; string preferredGpu = ConfigurationState.Instance.Graphics.PreferredGpu.Value;
renderer = new VulkanRenderer(Vk.GetApi(), CreateVulkanSurface, VulkanHelper.GetRequiredInstanceExtensions, preferredGpu); renderer = new Graphics.Vulkan.VulkanRenderer(Vk.GetApi(), CreateVulkanSurface, VulkanHelper.GetRequiredInstanceExtensions, preferredGpu);
} }
else else
{ {
renderer = new OpenGLRenderer(); renderer = new Graphics.OpenGL.OpenGLRenderer();
} }
BackendThreading threadingMode = ConfigurationState.Instance.Graphics.BackendThreading; BackendThreading threadingMode = ConfigurationState.Instance.Graphics.BackendThreading;
@ -570,7 +625,7 @@ namespace Ryujinx.Ui
IntegrityCheckLevel fsIntegrityCheckLevel = ConfigurationState.Instance.System.EnableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None; IntegrityCheckLevel fsIntegrityCheckLevel = ConfigurationState.Instance.System.EnableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None;
HLE.HLEConfiguration configuration = new HLE.HLEConfiguration(_virtualFileSystem, HLE.HLEConfiguration configuration = new(_virtualFileSystem,
_libHacHorizonManager, _libHacHorizonManager,
_contentManager, _contentManager,
_accountManager, _accountManager,
@ -601,7 +656,7 @@ namespace Ryujinx.Ui
private SurfaceKHR CreateVulkanSurface(Instance instance, Vk vk) private SurfaceKHR CreateVulkanSurface(Instance instance, Vk vk)
{ {
return new SurfaceKHR((ulong)((VKRenderer)RendererWidget).CreateWindowSurface(instance.Handle)); return new SurfaceKHR((ulong)((VulkanRenderer)RendererWidget).CreateWindowSurface(instance.Handle));
} }
private void SetupProgressUiHandlers() private void SetupProgressUiHandlers()
@ -655,14 +710,16 @@ namespace Ryujinx.Ui
_tableStore.Clear(); _tableStore.Clear();
Thread applicationLibraryThread = new Thread(() => Thread applicationLibraryThread = new(() =>
{ {
_applicationLibrary.LoadApplications(ConfigurationState.Instance.Ui.GameDirs, ConfigurationState.Instance.System.Language); _applicationLibrary.LoadApplications(ConfigurationState.Instance.Ui.GameDirs, ConfigurationState.Instance.System.Language);
_updatingGameTable = false; _updatingGameTable = false;
}); })
applicationLibraryThread.Name = "GUI.ApplicationLibraryThread"; {
applicationLibraryThread.IsBackground = true; Name = "GUI.ApplicationLibraryThread",
IsBackground = true,
};
applicationLibraryThread.Start(); applicationLibraryThread.Start();
} }
@ -671,11 +728,11 @@ namespace Ryujinx.Ui
{ {
if (ConfigurationState.Instance.Logger.EnableTrace.Value) if (ConfigurationState.Instance.Logger.EnableTrace.Value)
{ {
MessageDialog debugWarningDialog = new MessageDialog(this, DialogFlags.Modal, MessageType.Warning, ButtonsType.YesNo, null) MessageDialog debugWarningDialog = new(this, DialogFlags.Modal, MessageType.Warning, ButtonsType.YesNo, null)
{ {
Title = "Ryujinx - Warning", Title = "Ryujinx - Warning",
Text = "You have trace logging enabled, which is designed to be used by developers only.", Text = "You have trace logging enabled, which is designed to be used by developers only.",
SecondaryText = "For optimal performance, it's recommended to disable trace logging. Would you like to disable trace logging now?" SecondaryText = "For optimal performance, it's recommended to disable trace logging. Would you like to disable trace logging now?",
}; };
if (debugWarningDialog.Run() == (int)ResponseType.Yes) if (debugWarningDialog.Run() == (int)ResponseType.Yes)
@ -689,11 +746,11 @@ namespace Ryujinx.Ui
if (!string.IsNullOrWhiteSpace(ConfigurationState.Instance.Graphics.ShadersDumpPath.Value)) if (!string.IsNullOrWhiteSpace(ConfigurationState.Instance.Graphics.ShadersDumpPath.Value))
{ {
MessageDialog shadersDumpWarningDialog = new MessageDialog(this, DialogFlags.Modal, MessageType.Warning, ButtonsType.YesNo, null) MessageDialog shadersDumpWarningDialog = new(this, DialogFlags.Modal, MessageType.Warning, ButtonsType.YesNo, null)
{ {
Title = "Ryujinx - Warning", Title = "Ryujinx - Warning",
Text = "You have shader dumping enabled, which is designed to be used by developers only.", Text = "You have shader dumping enabled, which is designed to be used by developers only.",
SecondaryText = "For optimal performance, it's recommended to disable shader dumping. Would you like to disable shader dumping now?" SecondaryText = "For optimal performance, it's recommended to disable shader dumping. Would you like to disable shader dumping now?",
}; };
if (shadersDumpWarningDialog.Run() == (int)ResponseType.Yes) if (shadersDumpWarningDialog.Run() == (int)ResponseType.Yes)
@ -857,7 +914,7 @@ namespace Ryujinx.Ui
Thread windowThread = new(CreateGameWindow) Thread windowThread = new(CreateGameWindow)
{ {
Name = "GUI.WindowThread" Name = "GUI.WindowThread",
}; };
windowThread.Start(); windowThread.Start();
@ -885,11 +942,11 @@ namespace Ryujinx.Ui
{ {
if (ConfigurationState.Instance.Graphics.GraphicsBackend == GraphicsBackend.Vulkan) if (ConfigurationState.Instance.Graphics.GraphicsBackend == GraphicsBackend.Vulkan)
{ {
return new VKRenderer(InputManager, ConfigurationState.Instance.Logger.GraphicsDebugLevel); return new VulkanRenderer(InputManager, ConfigurationState.Instance.Logger.GraphicsDebugLevel);
} }
else else
{ {
return new GlRenderer(InputManager, ConfigurationState.Instance.Logger.GraphicsDebugLevel); return new OpenGLRenderer(InputManager, ConfigurationState.Instance.Logger.GraphicsDebugLevel);
} }
} }
@ -1030,7 +1087,7 @@ namespace Ryujinx.Ui
} }
} }
public void UpdateGraphicsConfig() public static void UpdateGraphicsConfig()
{ {
int resScale = ConfigurationState.Instance.Graphics.ResScale; int resScale = ConfigurationState.Instance.Graphics.ResScale;
float resScaleCustom = ConfigurationState.Instance.Graphics.ResScaleCustom; float resScaleCustom = ConfigurationState.Instance.Graphics.ResScaleCustom;
@ -1043,7 +1100,7 @@ namespace Ryujinx.Ui
Graphics.Gpu.GraphicsConfig.EnableMacroHLE = ConfigurationState.Instance.Graphics.EnableMacroHLE; Graphics.Gpu.GraphicsConfig.EnableMacroHLE = ConfigurationState.Instance.Graphics.EnableMacroHLE;
} }
public void SaveConfig() public static void SaveConfig()
{ {
ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath); ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
} }
@ -1193,7 +1250,7 @@ namespace Ryujinx.Ui
ConfigurationState.Instance.System.EnableDockedMode.Value = !ConfigurationState.Instance.System.EnableDockedMode.Value; ConfigurationState.Instance.System.EnableDockedMode.Value = !ConfigurationState.Instance.System.EnableDockedMode.Value;
} }
private string GetVolumeLabelText(float volume) private static string GetVolumeLabelText(float volume)
{ {
string icon = volume == 0 ? "🔇" : "🔊"; string icon = volume == 0 ? "🔇" : "🔊";
@ -1247,11 +1304,11 @@ namespace Ryujinx.Ui
private void Load_Application_File(object sender, EventArgs args) private void Load_Application_File(object sender, EventArgs args)
{ {
using (FileChooserNative fileChooser = new FileChooserNative("Choose the file to open", this, FileChooserAction.Open, "Open", "Cancel")) using FileChooserNative fileChooser = new("Choose the file to open", this, FileChooserAction.Open, "Open", "Cancel");
FileFilter filter = new()
{ {
FileFilter filter = new FileFilter() Name = "Switch Executables",
{
Name = "Switch Executables"
}; };
filter.AddPattern("*.xci"); filter.AddPattern("*.xci");
filter.AddPattern("*.nsp"); filter.AddPattern("*.nsp");
@ -1267,18 +1324,16 @@ namespace Ryujinx.Ui
RunApplication(fileChooser.Filename); RunApplication(fileChooser.Filename);
} }
} }
}
private void Load_Application_Folder(object sender, EventArgs args) private void Load_Application_Folder(object sender, EventArgs args)
{ {
using (FileChooserNative fileChooser = new FileChooserNative("Choose the folder to open", this, FileChooserAction.SelectFolder, "Open", "Cancel")) using FileChooserNative fileChooser = new("Choose the folder to open", this, FileChooserAction.SelectFolder, "Open", "Cancel");
{
if (fileChooser.Run() == (int)ResponseType.Accept) if (fileChooser.Run() == (int)ResponseType.Accept)
{ {
RunApplication(fileChooser.Filename); RunApplication(fileChooser.Filename);
} }
} }
}
private void FileMenu_StateChanged(object o, StateChangedArgs args) private void FileMenu_StateChanged(object o, StateChangedArgs args)
{ {
@ -1399,11 +1454,11 @@ namespace Ryujinx.Ui
private void Installer_File_Pressed(object o, EventArgs args) private void Installer_File_Pressed(object o, EventArgs args)
{ {
FileChooserNative fileChooser = new FileChooserNative("Choose the firmware file to open", this, FileChooserAction.Open, "Open", "Cancel"); FileChooserNative fileChooser = new("Choose the firmware file to open", this, FileChooserAction.Open, "Open", "Cancel");
FileFilter filter = new FileFilter FileFilter filter = new()
{ {
Name = "Switch Firmware Files" Name = "Switch Firmware Files",
}; };
filter.AddPattern("*.zip"); filter.AddPattern("*.zip");
filter.AddPattern("*.xci"); filter.AddPattern("*.xci");
@ -1415,7 +1470,7 @@ namespace Ryujinx.Ui
private void Installer_Directory_Pressed(object o, EventArgs args) private void Installer_Directory_Pressed(object o, EventArgs args)
{ {
FileChooserNative directoryChooser = new FileChooserNative("Choose the firmware directory to open", this, FileChooserAction.SelectFolder, "Open", "Cancel"); FileChooserNative directoryChooser = new("Choose the firmware directory to open", this, FileChooserAction.SelectFolder, "Open", "Cancel");
HandleInstallerDialog(directoryChooser); HandleInstallerDialog(directoryChooser);
} }
@ -1460,7 +1515,7 @@ namespace Ryujinx.Ui
{ {
Logger.Info?.Print(LogClass.Application, $"Installing firmware {firmwareVersion.VersionString}"); Logger.Info?.Print(LogClass.Application, $"Installing firmware {firmwareVersion.VersionString}");
Thread thread = new Thread(() => Thread thread = new(() =>
{ {
Application.Invoke(delegate Application.Invoke(delegate
{ {
@ -1483,7 +1538,7 @@ namespace Ryujinx.Ui
// Purge Applet Cache. // Purge Applet Cache.
DirectoryInfo miiEditorCacheFolder = new DirectoryInfo(System.IO.Path.Combine(AppDataManager.GamesDirPath, "0100000000001009", "cache")); DirectoryInfo miiEditorCacheFolder = new(System.IO.Path.Combine(AppDataManager.GamesDirPath, "0100000000001009", "cache"));
if (miiEditorCacheFolder.Exists) if (miiEditorCacheFolder.Exists)
{ {
@ -1504,9 +1559,10 @@ namespace Ryujinx.Ui
{ {
RefreshFirmwareLabel(); RefreshFirmwareLabel();
} }
}); })
{
thread.Name = "GUI.FirmwareInstallerThread"; Name = "GUI.FirmwareInstallerThread",
};
thread.Start(); thread.Start();
} }
} }
@ -1616,7 +1672,7 @@ namespace Ryujinx.Ui
private void Settings_Pressed(object sender, EventArgs args) private void Settings_Pressed(object sender, EventArgs args)
{ {
SettingsWindow settingsWindow = new SettingsWindow(this, _virtualFileSystem, _contentManager); SettingsWindow settingsWindow = new(this, _virtualFileSystem, _contentManager);
settingsWindow.SetSizeRequest((int)(settingsWindow.DefaultWidth * Program.WindowScaleFactor), (int)(settingsWindow.DefaultHeight * Program.WindowScaleFactor)); settingsWindow.SetSizeRequest((int)(settingsWindow.DefaultWidth * Program.WindowScaleFactor), (int)(settingsWindow.DefaultHeight * Program.WindowScaleFactor));
settingsWindow.Show(); settingsWindow.Show();
@ -1648,7 +1704,7 @@ namespace Ryujinx.Ui
private void ManageUserProfiles_Pressed(object sender, EventArgs args) private void ManageUserProfiles_Pressed(object sender, EventArgs args)
{ {
UserProfilesManagerWindow userProfilesManagerWindow = new UserProfilesManagerWindow(_accountManager, _contentManager, _virtualFileSystem); UserProfilesManagerWindow userProfilesManagerWindow = new(_accountManager, _contentManager, _virtualFileSystem);
userProfilesManagerWindow.SetSizeRequest((int)(userProfilesManagerWindow.DefaultWidth * Program.WindowScaleFactor), (int)(userProfilesManagerWindow.DefaultHeight * Program.WindowScaleFactor)); userProfilesManagerWindow.SetSizeRequest((int)(userProfilesManagerWindow.DefaultWidth * Program.WindowScaleFactor), (int)(userProfilesManagerWindow.DefaultHeight * Program.WindowScaleFactor));
userProfilesManagerWindow.Show(); userProfilesManagerWindow.Show();
@ -1656,10 +1712,7 @@ namespace Ryujinx.Ui
private void Simulate_WakeUp_Message_Pressed(object sender, EventArgs args) private void Simulate_WakeUp_Message_Pressed(object sender, EventArgs args)
{ {
if (_emulationContext != null) _emulationContext?.System.SimulateWakeUpMessage();
{
_emulationContext.System.SimulateWakeUpMessage();
}
} }
private void ActionMenu_StateChanged(object o, StateChangedArgs args) private void ActionMenu_StateChanged(object o, StateChangedArgs args)
@ -1672,12 +1725,12 @@ namespace Ryujinx.Ui
{ {
if (_emulationContext.System.SearchingForAmiibo(out int deviceId)) if (_emulationContext.System.SearchingForAmiibo(out int deviceId))
{ {
AmiiboWindow amiiboWindow = new AmiiboWindow AmiiboWindow amiiboWindow = new()
{ {
LastScannedAmiiboShowAll = _lastScannedAmiiboShowAll, LastScannedAmiiboShowAll = _lastScannedAmiiboShowAll,
LastScannedAmiiboId = _lastScannedAmiiboId, LastScannedAmiiboId = _lastScannedAmiiboId,
DeviceId = deviceId, DeviceId = deviceId,
TitleId = _emulationContext.Processes.ActiveApplication.ProgramIdText.ToUpper() TitleId = _emulationContext.Processes.ActiveApplication.ProgramIdText.ToUpper(),
}; };
amiiboWindow.DeleteEvent += AmiiboWindow_DeleteEvent; amiiboWindow.DeleteEvent += AmiiboWindow_DeleteEvent;
@ -1722,7 +1775,7 @@ namespace Ryujinx.Ui
private void About_Pressed(object sender, EventArgs args) private void About_Pressed(object sender, EventArgs args)
{ {
AboutWindow aboutWindow = new AboutWindow(); AboutWindow aboutWindow = new();
aboutWindow.SetSizeRequest((int)(aboutWindow.DefaultWidth * Program.WindowScaleFactor), (int)(aboutWindow.DefaultHeight * Program.WindowScaleFactor)); aboutWindow.SetSizeRequest((int)(aboutWindow.DefaultWidth * Program.WindowScaleFactor), (int)(aboutWindow.DefaultHeight * Program.WindowScaleFactor));
aboutWindow.Show(); aboutWindow.Show();
@ -1824,7 +1877,7 @@ namespace Ryujinx.Ui
UpdateGameTable(); UpdateGameTable();
} }
private void XCI_Shown_Toggled (object sender, EventArgs args) private void XCI_Shown_Toggled(object sender, EventArgs args)
{ {
ConfigurationState.Instance.Ui.ShownFileTypes.XCI.Value = _xciShown.Active; ConfigurationState.Instance.Ui.ShownFileTypes.XCI.Value = _xciShown.Active;
@ -1832,7 +1885,7 @@ namespace Ryujinx.Ui
UpdateGameTable(); UpdateGameTable();
} }
private void NCA_Shown_Toggled (object sender, EventArgs args) private void NCA_Shown_Toggled(object sender, EventArgs args)
{ {
ConfigurationState.Instance.Ui.ShownFileTypes.NCA.Value = _ncaShown.Active; ConfigurationState.Instance.Ui.ShownFileTypes.NCA.Value = _ncaShown.Active;
@ -1840,7 +1893,7 @@ namespace Ryujinx.Ui
UpdateGameTable(); UpdateGameTable();
} }
private void NRO_Shown_Toggled (object sender, EventArgs args) private void NRO_Shown_Toggled(object sender, EventArgs args)
{ {
ConfigurationState.Instance.Ui.ShownFileTypes.NRO.Value = _nroShown.Active; ConfigurationState.Instance.Ui.ShownFileTypes.NRO.Value = _nroShown.Active;
@ -1848,7 +1901,7 @@ namespace Ryujinx.Ui
UpdateGameTable(); UpdateGameTable();
} }
private void NSO_Shown_Toggled (object sender, EventArgs args) private void NSO_Shown_Toggled(object sender, EventArgs args)
{ {
ConfigurationState.Instance.Ui.ShownFileTypes.NSO.Value = _nsoShown.Active; ConfigurationState.Instance.Ui.ShownFileTypes.NSO.Value = _nsoShown.Active;

View file

@ -1,7 +1,6 @@
using OpenTK.Graphics.OpenGL; using OpenTK.Graphics.OpenGL;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Graphics.OpenGL;
using Ryujinx.Input.HLE; using Ryujinx.Input.HLE;
using SPB.Graphics; using SPB.Graphics;
using SPB.Graphics.Exceptions; using SPB.Graphics.Exceptions;
@ -15,16 +14,16 @@ using System.Runtime.InteropServices;
namespace Ryujinx.Ui namespace Ryujinx.Ui
{ {
public partial class GlRenderer : RendererWidgetBase public partial class OpenGLRenderer : RendererWidgetBase
{ {
private GraphicsDebugLevel _glLogLevel; private readonly GraphicsDebugLevel _glLogLevel;
private bool _initializedOpenGL; private bool _initializedOpenGL;
private OpenGLContextBase _openGLContext; private OpenGLContextBase _openGLContext;
private SwappableNativeWindowBase _nativeWindow; private SwappableNativeWindowBase _nativeWindow;
public GlRenderer(InputManager inputManager, GraphicsDebugLevel glLogLevel) : base(inputManager, glLogLevel) public OpenGLRenderer(InputManager inputManager, GraphicsDebugLevel glLogLevel) : base(inputManager, glLogLevel)
{ {
_glLogLevel = glLogLevel; _glLogLevel = glLogLevel;
} }
@ -93,7 +92,7 @@ namespace Ryujinx.Ui
public override void InitializeRenderer() public override void InitializeRenderer()
{ {
// First take exclusivity on the OpenGL context. // First take exclusivity on the OpenGL context.
((OpenGLRenderer)Renderer).InitializeBackgroundContext(SPBOpenGLContext.CreateBackgroundContext(_openGLContext)); ((Graphics.OpenGL.OpenGLRenderer)Renderer).InitializeBackgroundContext(SPBOpenGLContext.CreateBackgroundContext(_openGLContext));
_openGLContext.MakeCurrent(_nativeWindow); _openGLContext.MakeCurrent(_nativeWindow);

View file

@ -5,7 +5,7 @@ namespace Ryujinx.Ui
{ {
public class OpenToolkitBindingsContext : OpenTK.IBindingsContext public class OpenToolkitBindingsContext : OpenTK.IBindingsContext
{ {
private IBindingsContext _bindingContext; private readonly IBindingsContext _bindingContext;
public OpenToolkitBindingsContext(IBindingsContext bindingsContext) public OpenToolkitBindingsContext(IBindingsContext bindingsContext)
{ {

View file

@ -21,14 +21,13 @@ using System.Diagnostics;
using System.IO; using System.IO;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Image = SixLabors.ImageSharp.Image;
using Key = Ryujinx.Input.Key;
using ScalingFilter = Ryujinx.Graphics.GAL.ScalingFilter;
using Switch = Ryujinx.HLE.Switch;
namespace Ryujinx.Ui namespace Ryujinx.Ui
{ {
using Image = SixLabors.ImageSharp.Image;
using Key = Input.Key;
using ScalingFilter = Graphics.GAL.ScalingFilter;
using Switch = HLE.Switch;
public abstract class RendererWidgetBase : DrawingArea public abstract class RendererWidgetBase : DrawingArea
{ {
private const int SwitchPanelWidth = 1280; private const int SwitchPanelWidth = 1280;
@ -71,12 +70,12 @@ namespace Ryujinx.Ui
// Hide Cursor // Hide Cursor
const int CursorHideIdleTime = 5; // seconds const int CursorHideIdleTime = 5; // seconds
private static readonly Cursor _invisibleCursor = new Cursor(Display.Default, CursorType.BlankCursor); private static readonly Cursor _invisibleCursor = new(Display.Default, CursorType.BlankCursor);
private long _lastCursorMoveTime; private long _lastCursorMoveTime;
private HideCursorMode _hideCursorMode; private HideCursorMode _hideCursorMode;
private InputManager _inputManager; private readonly InputManager _inputManager;
private IKeyboard _keyboardInterface; private readonly IKeyboard _keyboardInterface;
private GraphicsDebugLevel _glLogLevel; private readonly GraphicsDebugLevel _glLogLevel;
private string _gpuBackendName; private string _gpuBackendName;
private string _gpuVendorName; private string _gpuVendorName;
private bool _isMouseInClient; private bool _isMouseInClient;
@ -165,7 +164,7 @@ namespace Ryujinx.Ui
Window.Cursor = _invisibleCursor; Window.Cursor = _invisibleCursor;
break; break;
default: default:
throw new ArgumentOutOfRangeException(); throw new ArgumentOutOfRangeException(nameof(state));
} }
}); });
} }
@ -384,7 +383,7 @@ namespace Ryujinx.Ui
string directory = AppDataManager.Mode switch string directory = AppDataManager.Mode switch
{ {
AppDataManager.LaunchMode.Portable or AppDataManager.LaunchMode.Custom => System.IO.Path.Combine(AppDataManager.BaseDirPath, "screenshots"), AppDataManager.LaunchMode.Portable or AppDataManager.LaunchMode.Custom => System.IO.Path.Combine(AppDataManager.BaseDirPath, "screenshots"),
_ => System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), "Ryujinx") _ => System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), "Ryujinx"),
}; };
string path = System.IO.Path.Combine(directory, filename); string path = System.IO.Path.Combine(directory, filename);
@ -415,7 +414,7 @@ namespace Ryujinx.Ui
image.SaveAsPng(path, new PngEncoder() image.SaveAsPng(path, new PngEncoder()
{ {
ColorType = PngColorType.Rgb ColorType = PngColorType.Rgb,
}); });
image.Dispose(); image.Dispose();
@ -534,20 +533,20 @@ namespace Ryujinx.Ui
parent.Title = $"Ryujinx {Program.Version} -{titleNameSection}{titleVersionSection}{titleIdSection}{titleArchSection}"; parent.Title = $"Ryujinx {Program.Version} -{titleNameSection}{titleVersionSection}{titleIdSection}{titleArchSection}";
}); });
Thread renderLoopThread = new Thread(Render) Thread renderLoopThread = new(Render)
{ {
Name = "GUI.RenderLoop" Name = "GUI.RenderLoop",
}; };
renderLoopThread.Start(); renderLoopThread.Start();
Thread nvStutterWorkaround = null; Thread nvidiaStutterWorkaround = null;
if (Renderer is Graphics.OpenGL.OpenGLRenderer) if (Renderer is Graphics.OpenGL.OpenGLRenderer)
{ {
nvStutterWorkaround = new Thread(NVStutterWorkaround) nvidiaStutterWorkaround = new Thread(NvidiaStutterWorkaround)
{ {
Name = "GUI.NVStutterWorkaround" Name = "GUI.NvidiaStutterWorkaround",
}; };
nvStutterWorkaround.Start(); nvidiaStutterWorkaround.Start();
} }
MainLoop(); MainLoop();
@ -556,7 +555,7 @@ namespace Ryujinx.Ui
// We only need to wait for all commands submitted during the main gpu loop to be processed. // We only need to wait for all commands submitted during the main gpu loop to be processed.
_gpuDoneEvent.WaitOne(); _gpuDoneEvent.WaitOne();
_gpuDoneEvent.Dispose(); _gpuDoneEvent.Dispose();
nvStutterWorkaround?.Join(); nvidiaStutterWorkaround?.Join();
Exit(); Exit();
} }
@ -584,7 +583,7 @@ namespace Ryujinx.Ui
} }
} }
private void NVStutterWorkaround() private void NvidiaStutterWorkaround()
{ {
while (_isActive) while (_isActive)
{ {
@ -752,7 +751,7 @@ namespace Ryujinx.Ui
ResScaleUp = 1 << 5, ResScaleUp = 1 << 5,
ResScaleDown = 1 << 6, ResScaleDown = 1 << 6,
VolumeUp = 1 << 7, VolumeUp = 1 << 7,
VolumeDown = 1 << 8 VolumeDown = 1 << 8,
} }
private KeyboardHotkeyState GetHotkeyState() private KeyboardHotkeyState GetHotkeyState()

View file

@ -9,8 +9,8 @@ namespace Ryujinx.Ui
{ {
class SPBOpenGLContext : IOpenGLContext class SPBOpenGLContext : IOpenGLContext
{ {
private OpenGLContextBase _context; private readonly OpenGLContextBase _context;
private NativeWindowBase _window; private readonly NativeWindowBase _window;
private SPBOpenGLContext(OpenGLContextBase context, NativeWindowBase window) private SPBOpenGLContext(OpenGLContextBase context, NativeWindowBase window)
{ {

View file

@ -12,12 +12,12 @@ using System.Runtime.InteropServices;
namespace Ryujinx.Ui namespace Ryujinx.Ui
{ {
public partial class VKRenderer : RendererWidgetBase public partial class VulkanRenderer : RendererWidgetBase
{ {
public NativeWindowBase NativeWindow { get; private set; } public NativeWindowBase NativeWindow { get; private set; }
private UpdateBoundsCallbackDelegate _updateBoundsCallback; private UpdateBoundsCallbackDelegate _updateBoundsCallback;
public VKRenderer(InputManager inputManager, GraphicsDebugLevel glLogLevel) : base(inputManager, glLogLevel) { } public VulkanRenderer(InputManager inputManager, GraphicsDebugLevel glLogLevel) : base(inputManager, glLogLevel) { }
private NativeWindowBase RetrieveNativeWindow() private NativeWindowBase RetrieveNativeWindow()
{ {

View file

@ -31,7 +31,7 @@ namespace Ryujinx.Ui.Widgets
// //
_openSaveUserDirMenuItem = new MenuItem("Open User Save Directory") _openSaveUserDirMenuItem = new MenuItem("Open User Save Directory")
{ {
TooltipText = "Open the directory which contains Application's User Saves." TooltipText = "Open the directory which contains Application's User Saves.",
}; };
_openSaveUserDirMenuItem.Activated += OpenSaveUserDir_Clicked; _openSaveUserDirMenuItem.Activated += OpenSaveUserDir_Clicked;
@ -40,7 +40,7 @@ namespace Ryujinx.Ui.Widgets
// //
_openSaveDeviceDirMenuItem = new MenuItem("Open Device Save Directory") _openSaveDeviceDirMenuItem = new MenuItem("Open Device Save Directory")
{ {
TooltipText = "Open the directory which contains Application's Device Saves." TooltipText = "Open the directory which contains Application's Device Saves.",
}; };
_openSaveDeviceDirMenuItem.Activated += OpenSaveDeviceDir_Clicked; _openSaveDeviceDirMenuItem.Activated += OpenSaveDeviceDir_Clicked;
@ -49,7 +49,7 @@ namespace Ryujinx.Ui.Widgets
// //
_openSaveBcatDirMenuItem = new MenuItem("Open BCAT Save Directory") _openSaveBcatDirMenuItem = new MenuItem("Open BCAT Save Directory")
{ {
TooltipText = "Open the directory which contains Application's BCAT Saves." TooltipText = "Open the directory which contains Application's BCAT Saves.",
}; };
_openSaveBcatDirMenuItem.Activated += OpenSaveBcatDir_Clicked; _openSaveBcatDirMenuItem.Activated += OpenSaveBcatDir_Clicked;
@ -58,7 +58,7 @@ namespace Ryujinx.Ui.Widgets
// //
_manageTitleUpdatesMenuItem = new MenuItem("Manage Title Updates") _manageTitleUpdatesMenuItem = new MenuItem("Manage Title Updates")
{ {
TooltipText = "Open the Title Update management window" TooltipText = "Open the Title Update management window",
}; };
_manageTitleUpdatesMenuItem.Activated += ManageTitleUpdates_Clicked; _manageTitleUpdatesMenuItem.Activated += ManageTitleUpdates_Clicked;
@ -67,7 +67,7 @@ namespace Ryujinx.Ui.Widgets
// //
_manageDlcMenuItem = new MenuItem("Manage DLC") _manageDlcMenuItem = new MenuItem("Manage DLC")
{ {
TooltipText = "Open the DLC management window" TooltipText = "Open the DLC management window",
}; };
_manageDlcMenuItem.Activated += ManageDlc_Clicked; _manageDlcMenuItem.Activated += ManageDlc_Clicked;
@ -76,7 +76,7 @@ namespace Ryujinx.Ui.Widgets
// //
_manageCheatMenuItem = new MenuItem("Manage Cheats") _manageCheatMenuItem = new MenuItem("Manage Cheats")
{ {
TooltipText = "Open the Cheat management window" TooltipText = "Open the Cheat management window",
}; };
_manageCheatMenuItem.Activated += ManageCheats_Clicked; _manageCheatMenuItem.Activated += ManageCheats_Clicked;
@ -85,7 +85,7 @@ namespace Ryujinx.Ui.Widgets
// //
_openTitleModDirMenuItem = new MenuItem("Open Mods Directory") _openTitleModDirMenuItem = new MenuItem("Open Mods Directory")
{ {
TooltipText = "Open the directory which contains Application's Mods." TooltipText = "Open the directory which contains Application's Mods.",
}; };
_openTitleModDirMenuItem.Activated += OpenTitleModDir_Clicked; _openTitleModDirMenuItem.Activated += OpenTitleModDir_Clicked;
@ -94,7 +94,7 @@ namespace Ryujinx.Ui.Widgets
// //
_openTitleSdModDirMenuItem = new MenuItem("Open Atmosphere Mods Directory") _openTitleSdModDirMenuItem = new MenuItem("Open Atmosphere Mods Directory")
{ {
TooltipText = "Open the alternative SD card atmosphere directory which contains the Application's Mods." TooltipText = "Open the alternative SD card atmosphere directory which contains the Application's Mods.",
}; };
_openTitleSdModDirMenuItem.Activated += OpenTitleSdModDir_Clicked; _openTitleSdModDirMenuItem.Activated += OpenTitleSdModDir_Clicked;
@ -116,7 +116,7 @@ namespace Ryujinx.Ui.Widgets
// //
_extractRomFsMenuItem = new MenuItem("RomFS") _extractRomFsMenuItem = new MenuItem("RomFS")
{ {
TooltipText = "Extract the RomFS section from Application's current config (including updates)." TooltipText = "Extract the RomFS section from Application's current config (including updates).",
}; };
_extractRomFsMenuItem.Activated += ExtractRomFs_Clicked; _extractRomFsMenuItem.Activated += ExtractRomFs_Clicked;
@ -125,7 +125,7 @@ namespace Ryujinx.Ui.Widgets
// //
_extractExeFsMenuItem = new MenuItem("ExeFS") _extractExeFsMenuItem = new MenuItem("ExeFS")
{ {
TooltipText = "Extract the ExeFS section from Application's current config (including updates)." TooltipText = "Extract the ExeFS section from Application's current config (including updates).",
}; };
_extractExeFsMenuItem.Activated += ExtractExeFs_Clicked; _extractExeFsMenuItem.Activated += ExtractExeFs_Clicked;
@ -134,7 +134,7 @@ namespace Ryujinx.Ui.Widgets
// //
_extractLogoMenuItem = new MenuItem("Logo") _extractLogoMenuItem = new MenuItem("Logo")
{ {
TooltipText = "Extract the Logo section from Application's current config (including updates)." TooltipText = "Extract the Logo section from Application's current config (including updates).",
}; };
_extractLogoMenuItem.Activated += ExtractLogo_Clicked; _extractLogoMenuItem.Activated += ExtractLogo_Clicked;
@ -148,7 +148,7 @@ namespace Ryujinx.Ui.Widgets
// //
_manageCacheMenuItem = new MenuItem("Cache Management") _manageCacheMenuItem = new MenuItem("Cache Management")
{ {
Submenu = _manageSubMenu Submenu = _manageSubMenu,
}; };
// //
@ -156,7 +156,7 @@ namespace Ryujinx.Ui.Widgets
// //
_purgePtcCacheMenuItem = new MenuItem("Queue PPTC Rebuild") _purgePtcCacheMenuItem = new MenuItem("Queue PPTC Rebuild")
{ {
TooltipText = "Trigger PPTC to rebuild at boot time on the next game launch." TooltipText = "Trigger PPTC to rebuild at boot time on the next game launch.",
}; };
_purgePtcCacheMenuItem.Activated += PurgePtcCache_Clicked; _purgePtcCacheMenuItem.Activated += PurgePtcCache_Clicked;
@ -165,7 +165,7 @@ namespace Ryujinx.Ui.Widgets
// //
_purgeShaderCacheMenuItem = new MenuItem("Purge Shader Cache") _purgeShaderCacheMenuItem = new MenuItem("Purge Shader Cache")
{ {
TooltipText = "Delete the Application's shader cache." TooltipText = "Delete the Application's shader cache.",
}; };
_purgeShaderCacheMenuItem.Activated += PurgeShaderCache_Clicked; _purgeShaderCacheMenuItem.Activated += PurgeShaderCache_Clicked;
@ -174,7 +174,7 @@ namespace Ryujinx.Ui.Widgets
// //
_openPtcDirMenuItem = new MenuItem("Open PPTC Directory") _openPtcDirMenuItem = new MenuItem("Open PPTC Directory")
{ {
TooltipText = "Open the directory which contains the Application's PPTC cache." TooltipText = "Open the directory which contains the Application's PPTC cache.",
}; };
_openPtcDirMenuItem.Activated += OpenPtcDir_Clicked; _openPtcDirMenuItem.Activated += OpenPtcDir_Clicked;
@ -183,7 +183,7 @@ namespace Ryujinx.Ui.Widgets
// //
_openShaderCacheDirMenuItem = new MenuItem("Open Shader Cache Directory") _openShaderCacheDirMenuItem = new MenuItem("Open Shader Cache Directory")
{ {
TooltipText = "Open the directory which contains the Application's shader cache." TooltipText = "Open the directory which contains the Application's shader cache.",
}; };
_openShaderCacheDirMenuItem.Activated += OpenShaderCacheDir_Clicked; _openShaderCacheDirMenuItem.Activated += OpenShaderCacheDir_Clicked;

View file

@ -105,7 +105,7 @@ namespace Ryujinx.Ui.Widgets
Logger.Warning?.Print(LogClass.Application, "No control file was found for this game. Using a dummy one instead. This may cause inaccuracies in some games."); Logger.Warning?.Print(LogClass.Application, "No control file was found for this game. Using a dummy one instead. This may cause inaccuracies in some games.");
} }
Uid user = new Uid((ulong)_accountManager.LastOpenedUser.UserId.High, (ulong)_accountManager.LastOpenedUser.UserId.Low); Uid user = new((ulong)_accountManager.LastOpenedUser.UserId.High, (ulong)_accountManager.LastOpenedUser.UserId.Low);
result = _horizonClient.Fs.EnsureApplicationSaveData(out _, new LibHac.Ncm.ApplicationId(titleId), in control, in user); result = _horizonClient.Fs.EnsureApplicationSaveData(out _, new LibHac.Ncm.ApplicationId(titleId), in control, in user);
@ -170,7 +170,7 @@ namespace Ryujinx.Ui.Widgets
private void ExtractSection(NcaSectionType ncaSectionType, int programIndex = 0) private void ExtractSection(NcaSectionType ncaSectionType, int programIndex = 0)
{ {
FileChooserNative fileChooser = new FileChooserNative("Choose the folder to extract into", _parent, FileChooserAction.SelectFolder, "Extract", "Cancel"); FileChooserNative fileChooser = new("Choose the folder to extract into", _parent, FileChooserAction.SelectFolder, "Extract", "Cancel");
ResponseType response = (ResponseType)fileChooser.Run(); ResponseType response = (ResponseType)fileChooser.Run();
string destination = fileChooser.Filename; string destination = fileChooser.Filename;
@ -179,7 +179,7 @@ namespace Ryujinx.Ui.Widgets
if (response == ResponseType.Accept) if (response == ResponseType.Accept)
{ {
Thread extractorThread = new Thread(() => Thread extractorThread = new(() =>
{ {
Gtk.Application.Invoke(delegate Gtk.Application.Invoke(delegate
{ {
@ -188,7 +188,7 @@ namespace Ryujinx.Ui.Widgets
Title = "Ryujinx - NCA Section Extractor", Title = "Ryujinx - NCA Section Extractor",
Icon = new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png"), Icon = new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png"),
SecondaryText = $"Extracting {ncaSectionType} section from {System.IO.Path.GetFileName(_titleFilePath)}...", SecondaryText = $"Extracting {ncaSectionType} section from {System.IO.Path.GetFileName(_titleFilePath)}...",
WindowPosition = WindowPosition.Center WindowPosition = WindowPosition.Center,
}; };
int dialogResponse = _dialog.Run(); int dialogResponse = _dialog.Run();
@ -199,8 +199,8 @@ namespace Ryujinx.Ui.Widgets
} }
}); });
using (FileStream file = new FileStream(_titleFilePath, FileMode.Open, FileAccess.Read)) using FileStream file = new(_titleFilePath, FileMode.Open, FileAccess.Read);
{
Nca mainNca = null; Nca mainNca = null;
Nca patchNca = null; Nca patchNca = null;
@ -212,7 +212,7 @@ namespace Ryujinx.Ui.Widgets
if (System.IO.Path.GetExtension(_titleFilePath) == ".xci") if (System.IO.Path.GetExtension(_titleFilePath) == ".xci")
{ {
Xci xci = new Xci(_virtualFileSystem.KeySet, file.AsStorage()); Xci xci = new(_virtualFileSystem.KeySet, file.AsStorage());
pfs = xci.OpenPartition(XciPartitionType.Secure); pfs = xci.OpenPartition(XciPartitionType.Secure);
} }
@ -227,7 +227,7 @@ namespace Ryujinx.Ui.Widgets
pfs.OpenFile(ref ncaFile.Ref, fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure(); pfs.OpenFile(ref ncaFile.Ref, fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
Nca nca = new Nca(_virtualFileSystem.KeySet, ncaFile.Release().AsStorage()); Nca nca = new(_virtualFileSystem.KeySet, ncaFile.Release().AsStorage());
if (nca.Header.ContentType == NcaContentType.Program) if (nca.Header.ContentType == NcaContentType.Program)
{ {
@ -271,6 +271,7 @@ namespace Ryujinx.Ui.Widgets
int index = Nca.GetSectionIndexFromType(ncaSectionType, mainNca.Header.ContentType); int index = Nca.GetSectionIndexFromType(ncaSectionType, mainNca.Header.ContentType);
bool sectionExistsInPatch = false; bool sectionExistsInPatch = false;
if (patchNca != null) if (patchNca != null)
{ {
sectionExistsInPatch = patchNca.CanOpenSection(index); sectionExistsInPatch = patchNca.CanOpenSection(index);
@ -311,12 +312,12 @@ namespace Ryujinx.Ui.Widgets
{ {
_dialog?.Dispose(); _dialog?.Dispose();
MessageDialog dialog = new MessageDialog(null, DialogFlags.DestroyWithParent, MessageType.Info, ButtonsType.Ok, null) MessageDialog dialog = new(null, DialogFlags.DestroyWithParent, MessageType.Info, ButtonsType.Ok, null)
{ {
Title = "Ryujinx - NCA Section Extractor", Title = "Ryujinx - NCA Section Extractor",
Icon = new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png"), Icon = new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png"),
SecondaryText = "Extraction completed successfully.", SecondaryText = "Extraction completed successfully.",
WindowPosition = WindowPosition.Center WindowPosition = WindowPosition.Center,
}; };
dialog.Run(); dialog.Run();
@ -327,11 +328,11 @@ namespace Ryujinx.Ui.Widgets
fsClient.Unmount(source.ToU8Span()); fsClient.Unmount(source.ToU8Span());
fsClient.Unmount(output.ToU8Span()); fsClient.Unmount(output.ToU8Span());
} })
}); {
Name = "GUI.NcaSectionExtractorThread",
extractorThread.Name = "GUI.NcaSectionExtractorThread"; IsBackground = true,
extractorThread.IsBackground = true; };
extractorThread.Start(); extractorThread.Start();
} }
} }
@ -339,7 +340,10 @@ namespace Ryujinx.Ui.Widgets
private (Result? result, bool canceled) CopyDirectory(FileSystemClient fs, string sourcePath, string destPath) private (Result? result, bool canceled) CopyDirectory(FileSystemClient fs, string sourcePath, string destPath)
{ {
Result rc = fs.OpenDirectory(out DirectoryHandle sourceHandle, sourcePath.ToU8Span(), OpenDirectoryMode.All); Result rc = fs.OpenDirectory(out DirectoryHandle sourceHandle, sourcePath.ToU8Span(), OpenDirectoryMode.All);
if (rc.IsFailure()) return (rc, false); if (rc.IsFailure())
{
return (rc, false);
}
using (sourceHandle) using (sourceHandle)
{ {
@ -369,7 +373,10 @@ namespace Ryujinx.Ui.Widgets
fs.CreateOrOverwriteFile(subDstPath, entry.Size); fs.CreateOrOverwriteFile(subDstPath, entry.Size);
rc = CopyFile(fs, subSrcPath, subDstPath); rc = CopyFile(fs, subSrcPath, subDstPath);
if (rc.IsFailure()) return (rc, false); if (rc.IsFailure())
{
return (rc, false);
}
} }
} }
} }
@ -377,22 +384,31 @@ namespace Ryujinx.Ui.Widgets
return (Result.Success, false); return (Result.Success, false);
} }
public Result CopyFile(FileSystemClient fs, string sourcePath, string destPath) public static Result CopyFile(FileSystemClient fs, string sourcePath, string destPath)
{ {
Result rc = fs.OpenFile(out FileHandle sourceHandle, sourcePath.ToU8Span(), OpenMode.Read); Result rc = fs.OpenFile(out FileHandle sourceHandle, sourcePath.ToU8Span(), OpenMode.Read);
if (rc.IsFailure()) return rc; if (rc.IsFailure())
{
return rc;
}
using (sourceHandle) using (sourceHandle)
{ {
rc = fs.OpenFile(out FileHandle destHandle, destPath.ToU8Span(), OpenMode.Write | OpenMode.AllowAppend); rc = fs.OpenFile(out FileHandle destHandle, destPath.ToU8Span(), OpenMode.Write | OpenMode.AllowAppend);
if (rc.IsFailure()) return rc; if (rc.IsFailure())
{
return rc;
}
using (destHandle) using (destHandle)
{ {
const int MaxBufferSize = 1024 * 1024; const int MaxBufferSize = 1024 * 1024;
rc = fs.GetFileSize(out long fileSize, sourceHandle); rc = fs.GetFileSize(out long fileSize, sourceHandle);
if (rc.IsFailure()) return rc; if (rc.IsFailure())
{
return rc;
}
int bufferSize = (int)Math.Min(MaxBufferSize, fileSize); int bufferSize = (int)Math.Min(MaxBufferSize, fileSize);
@ -405,10 +421,16 @@ namespace Ryujinx.Ui.Widgets
Span<byte> buf = buffer.AsSpan(0, toRead); Span<byte> buf = buffer.AsSpan(0, toRead);
rc = fs.ReadFile(out long _, sourceHandle, offset, buf); rc = fs.ReadFile(out long _, sourceHandle, offset, buf);
if (rc.IsFailure()) return rc; if (rc.IsFailure())
{
return rc;
}
rc = fs.WriteFile(destHandle, offset, buf, WriteOption.None); rc = fs.WriteFile(destHandle, offset, buf, WriteOption.None);
if (rc.IsFailure()) return rc; if (rc.IsFailure())
{
return rc;
}
} }
} }
finally finally
@ -417,7 +439,10 @@ namespace Ryujinx.Ui.Widgets
} }
rc = fs.FlushFile(destHandle); rc = fs.FlushFile(destHandle);
if (rc.IsFailure()) return rc; if (rc.IsFailure())
{
return rc;
}
} }
} }
@ -526,12 +551,12 @@ namespace Ryujinx.Ui.Widgets
private void PurgePtcCache_Clicked(object sender, EventArgs args) private void PurgePtcCache_Clicked(object sender, EventArgs args)
{ {
DirectoryInfo mainDir = new DirectoryInfo(System.IO.Path.Combine(AppDataManager.GamesDirPath, _titleIdText, "cache", "cpu", "0")); DirectoryInfo mainDir = new(System.IO.Path.Combine(AppDataManager.GamesDirPath, _titleIdText, "cache", "cpu", "0"));
DirectoryInfo backupDir = new DirectoryInfo(System.IO.Path.Combine(AppDataManager.GamesDirPath, _titleIdText, "cache", "cpu", "1")); DirectoryInfo backupDir = new(System.IO.Path.Combine(AppDataManager.GamesDirPath, _titleIdText, "cache", "cpu", "1"));
MessageDialog warningDialog = GtkDialog.CreateConfirmationDialog("Warning", $"You are about to queue a PPTC rebuild on the next boot of:\n\n<b>{_titleName}</b>\n\nAre you sure you want to proceed?"); MessageDialog warningDialog = GtkDialog.CreateConfirmationDialog("Warning", $"You are about to queue a PPTC rebuild on the next boot of:\n\n<b>{_titleName}</b>\n\nAre you sure you want to proceed?");
List<FileInfo> cacheFiles = new List<FileInfo>(); List<FileInfo> cacheFiles = new();
if (mainDir.Exists) if (mainDir.Exists)
{ {
@ -551,7 +576,7 @@ namespace Ryujinx.Ui.Widgets
{ {
file.Delete(); file.Delete();
} }
catch(Exception e) catch (Exception e)
{ {
GtkDialog.CreateErrorDialog($"Error purging PPTC cache {file.Name}: {e}"); GtkDialog.CreateErrorDialog($"Error purging PPTC cache {file.Name}: {e}");
} }
@ -563,12 +588,12 @@ namespace Ryujinx.Ui.Widgets
private void PurgeShaderCache_Clicked(object sender, EventArgs args) private void PurgeShaderCache_Clicked(object sender, EventArgs args)
{ {
DirectoryInfo shaderCacheDir = new DirectoryInfo(System.IO.Path.Combine(AppDataManager.GamesDirPath, _titleIdText, "cache", "shader")); DirectoryInfo shaderCacheDir = new(System.IO.Path.Combine(AppDataManager.GamesDirPath, _titleIdText, "cache", "shader"));
using MessageDialog warningDialog = GtkDialog.CreateConfirmationDialog("Warning", $"You are about to delete the shader cache for :\n\n<b>{_titleName}</b>\n\nAre you sure you want to proceed?"); using MessageDialog warningDialog = GtkDialog.CreateConfirmationDialog("Warning", $"You are about to delete the shader cache for :\n\n<b>{_titleName}</b>\n\nAre you sure you want to proceed?");
List<DirectoryInfo> oldCacheDirectories = new List<DirectoryInfo>(); List<DirectoryInfo> oldCacheDirectories = new();
List<FileInfo> newCacheFiles = new List<FileInfo>(); List<FileInfo> newCacheFiles = new();
if (shaderCacheDir.Exists) if (shaderCacheDir.Exists)
{ {

View file

@ -80,7 +80,7 @@ namespace Ryujinx.Ui.Widgets
internal static ResponseType CreateCustomDialog(string title, string mainText, string secondaryText, Dictionary<int, string> buttons, MessageType messageType = MessageType.Other) internal static ResponseType CreateCustomDialog(string title, string mainText, string secondaryText, Dictionary<int, string> buttons, MessageType messageType = MessageType.Other)
{ {
GtkDialog gtkDialog = new GtkDialog(title, mainText, secondaryText, messageType, ButtonsType.None); GtkDialog gtkDialog = new(title, mainText, secondaryText, messageType, ButtonsType.None);
foreach (var button in buttons) foreach (var button in buttons)
{ {
@ -92,7 +92,7 @@ namespace Ryujinx.Ui.Widgets
internal static string CreateInputDialog(Window parent, string title, string mainText, uint inputMax) internal static string CreateInputDialog(Window parent, string title, string mainText, uint inputMax)
{ {
GtkInputDialog gtkDialog = new GtkInputDialog(parent, title, mainText, inputMax); GtkInputDialog gtkDialog = new(parent, title, mainText, inputMax);
ResponseType response = (ResponseType)gtkDialog.Run(); ResponseType response = (ResponseType)gtkDialog.Run();
string responseText = gtkDialog.InputEntry.Text.TrimEnd(); string responseText = gtkDialog.InputEntry.Text.TrimEnd();

View file

@ -12,19 +12,19 @@ namespace Ryujinx.Ui.Widgets
Title = title; Title = title;
Label mainTextLabel = new Label Label mainTextLabel = new()
{ {
Text = mainText Text = mainText,
}; };
InputEntry = new Entry InputEntry = new Entry
{ {
MaxLength = (int)inputMax MaxLength = (int)inputMax,
}; };
Label inputMaxTextLabel = new Label Label inputMaxTextLabel = new()
{ {
Text = $"(Max length: {inputMax})" Text = $"(Max length: {inputMax})",
}; };
((Box)MessageArea).PackStart(mainTextLabel, true, true, 0); ((Box)MessageArea).PackStart(mainTextLabel, true, true, 0);

View file

@ -10,7 +10,7 @@ namespace Ryujinx.Ui.Widgets
{ {
public string FileName { get; private set; } public string FileName { get; private set; }
#pragma warning disable CS0649, IDE0044 #pragma warning disable CS0649, IDE0044 // Field is never assigned to, Add readonly modifier
[GUI] Entry _profileEntry; [GUI] Entry _profileEntry;
[GUI] Label _errorMessage; [GUI] Label _errorMessage;
#pragma warning restore CS0649, IDE0044 #pragma warning restore CS0649, IDE0044

View file

@ -46,12 +46,12 @@ namespace Ryujinx.Ui.Widgets
} }
} }
private string GetErrorCode(UserError error) private static string GetErrorCode(UserError error)
{ {
return $"RYU-{(uint)error:X4}"; return $"RYU-{(uint)error:X4}";
} }
private string GetErrorTitle(UserError error) private static string GetErrorTitle(UserError error)
{ {
return error switch return error switch
{ {
@ -64,7 +64,7 @@ namespace Ryujinx.Ui.Widgets
}; };
} }
private string GetErrorDescription(UserError error) private static string GetErrorDescription(UserError error)
{ {
return error switch return error switch
{ {

View file

@ -54,8 +54,6 @@ namespace Ryujinx.Ui.Windows
private void InitializeComponent() private void InitializeComponent()
{ {
#pragma warning disable CS0612
// //
// AboutWindow // AboutWindow
// //
@ -78,8 +76,8 @@ namespace Ryujinx.Ui.Windows
_leftBox = new Box(Orientation.Vertical, 0) _leftBox = new Box(Orientation.Vertical, 0)
{ {
Margin = 15, Margin = 15,
MarginLeft = 30, MarginStart = 30,
MarginRight = 0 MarginEnd = 0,
}; };
// //
@ -93,7 +91,7 @@ namespace Ryujinx.Ui.Windows
_ryujinxLogo = new Image(new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png", 100, 100)) _ryujinxLogo = new Image(new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png", 100, 100))
{ {
Margin = 10, Margin = 10,
MarginLeft = 15 MarginStart = 15,
}; };
// //
@ -108,7 +106,7 @@ namespace Ryujinx.Ui.Windows
{ {
MarginTop = 15, MarginTop = 15,
Justify = Justification.Center, Justify = Justification.Center,
Attributes = new AttrList() Attributes = new AttrList(),
}; };
_ryujinxLabel.Attributes.Insert(new Pango.AttrScale(2.7f)); _ryujinxLabel.Attributes.Insert(new Pango.AttrScale(2.7f));
@ -117,7 +115,7 @@ namespace Ryujinx.Ui.Windows
// //
_ryujinxPhoneticLabel = new Label("(REE-YOU-JINX)") _ryujinxPhoneticLabel = new Label("(REE-YOU-JINX)")
{ {
Justify = Justification.Center Justify = Justification.Center,
}; };
// //
@ -136,7 +134,7 @@ namespace Ryujinx.Ui.Windows
{ {
TooltipText = "Click to open the Ryujinx website in your default browser.", TooltipText = "Click to open the Ryujinx website in your default browser.",
Justify = Justification.Center, Justify = Justification.Center,
Attributes = new AttrList() Attributes = new AttrList(),
}; };
_ryujinxLinkLabel.Attributes.Insert(new Pango.AttrUnderline(Underline.Single)); _ryujinxLinkLabel.Attributes.Insert(new Pango.AttrUnderline(Underline.Single));
@ -147,7 +145,7 @@ namespace Ryujinx.Ui.Windows
{ {
Expand = true, Expand = true,
Justify = Justification.Center, Justify = Justification.Center,
Margin = 5 Margin = 5,
}; };
// //
@ -163,7 +161,7 @@ namespace Ryujinx.Ui.Windows
{ {
TooltipText = "Click to open the changelog for this version in your default browser.", TooltipText = "Click to open the changelog for this version in your default browser.",
Justify = Justification.Center, Justify = Justification.Center,
Attributes = new AttrList() Attributes = new AttrList(),
}; };
_changelogLinkLabel.Attributes.Insert(new Pango.AttrUnderline(Underline.Single)); _changelogLinkLabel.Attributes.Insert(new Pango.AttrUnderline(Underline.Single));
@ -175,7 +173,7 @@ namespace Ryujinx.Ui.Windows
Expand = true, Expand = true,
Justify = Justification.Center, Justify = Justification.Center,
Margin = 5, Margin = 5,
Attributes = new AttrList() Attributes = new AttrList(),
}; };
_disclaimerLabel.Attributes.Insert(new Pango.AttrScale(0.8f)); _disclaimerLabel.Attributes.Insert(new Pango.AttrScale(0.8f));
@ -184,7 +182,7 @@ namespace Ryujinx.Ui.Windows
// //
_amiiboApiLink = new EventBox() _amiiboApiLink = new EventBox()
{ {
Margin = 5 Margin = 5,
}; };
_amiiboApiLink.ButtonPressEvent += AmiiboApiButton_Pressed; _amiiboApiLink.ButtonPressEvent += AmiiboApiButton_Pressed;
@ -195,7 +193,7 @@ namespace Ryujinx.Ui.Windows
{ {
TooltipText = "Click to open the AmiiboAPI website in your default browser.", TooltipText = "Click to open the AmiiboAPI website in your default browser.",
Justify = Justification.Center, Justify = Justification.Center,
Attributes = new AttrList() Attributes = new AttrList(),
}; };
_amiiboApiLinkLabel.Attributes.Insert(new Pango.AttrScale(0.9f)); _amiiboApiLinkLabel.Attributes.Insert(new Pango.AttrScale(0.9f));
@ -205,7 +203,7 @@ namespace Ryujinx.Ui.Windows
_socialBox = new Box(Orientation.Horizontal, 0) _socialBox = new Box(Orientation.Horizontal, 0)
{ {
Margin = 25, Margin = 25,
MarginBottom = 10 MarginBottom = 10,
}; };
// //
@ -213,7 +211,7 @@ namespace Ryujinx.Ui.Windows
// //
_patreonEventBox = new EventBox() _patreonEventBox = new EventBox()
{ {
TooltipText = "Click to open the Ryujinx Patreon page in your default browser." TooltipText = "Click to open the Ryujinx Patreon page in your default browser.",
}; };
_patreonEventBox.ButtonPressEvent += PatreonButton_Pressed; _patreonEventBox.ButtonPressEvent += PatreonButton_Pressed;
@ -227,7 +225,7 @@ namespace Ryujinx.Ui.Windows
// //
_patreonLogo = new Image(new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Patreon_Light.png", 30, 30)) _patreonLogo = new Image(new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Patreon_Light.png", 30, 30))
{ {
Margin = 10 Margin = 10,
}; };
// //
@ -235,7 +233,7 @@ namespace Ryujinx.Ui.Windows
// //
_patreonLabel = new Label("Patreon") _patreonLabel = new Label("Patreon")
{ {
Justify = Justification.Center Justify = Justification.Center,
}; };
// //
@ -243,7 +241,7 @@ namespace Ryujinx.Ui.Windows
// //
_githubEventBox = new EventBox() _githubEventBox = new EventBox()
{ {
TooltipText = "Click to open the Ryujinx GitHub page in your default browser." TooltipText = "Click to open the Ryujinx GitHub page in your default browser.",
}; };
_githubEventBox.ButtonPressEvent += GitHubButton_Pressed; _githubEventBox.ButtonPressEvent += GitHubButton_Pressed;
@ -257,7 +255,7 @@ namespace Ryujinx.Ui.Windows
// //
_githubLogo = new Image(new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_GitHub_Light.png", 30, 30)) _githubLogo = new Image(new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_GitHub_Light.png", 30, 30))
{ {
Margin = 10 Margin = 10,
}; };
// //
@ -265,7 +263,7 @@ namespace Ryujinx.Ui.Windows
// //
_githubLabel = new Label("GitHub") _githubLabel = new Label("GitHub")
{ {
Justify = Justification.Center Justify = Justification.Center,
}; };
// //
@ -278,7 +276,7 @@ namespace Ryujinx.Ui.Windows
// //
_discordEventBox = new EventBox() _discordEventBox = new EventBox()
{ {
TooltipText = "Click to open an invite to the Ryujinx Discord server in your default browser." TooltipText = "Click to open an invite to the Ryujinx Discord server in your default browser.",
}; };
_discordEventBox.ButtonPressEvent += DiscordButton_Pressed; _discordEventBox.ButtonPressEvent += DiscordButton_Pressed;
@ -287,7 +285,7 @@ namespace Ryujinx.Ui.Windows
// //
_discordLogo = new Image(new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Discord_Light.png", 30, 30)) _discordLogo = new Image(new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Discord_Light.png", 30, 30))
{ {
Margin = 10 Margin = 10,
}; };
// //
@ -295,7 +293,7 @@ namespace Ryujinx.Ui.Windows
// //
_discordLabel = new Label("Discord") _discordLabel = new Label("Discord")
{ {
Justify = Justification.Center Justify = Justification.Center,
}; };
// //
@ -303,7 +301,7 @@ namespace Ryujinx.Ui.Windows
// //
_twitterEventBox = new EventBox() _twitterEventBox = new EventBox()
{ {
TooltipText = "Click to open the Ryujinx Twitter page in your default browser." TooltipText = "Click to open the Ryujinx Twitter page in your default browser.",
}; };
_twitterEventBox.ButtonPressEvent += TwitterButton_Pressed; _twitterEventBox.ButtonPressEvent += TwitterButton_Pressed;
@ -317,7 +315,7 @@ namespace Ryujinx.Ui.Windows
// //
_twitterLogo = new Image(new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Twitter_Light.png", 30, 30)) _twitterLogo = new Image(new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Twitter_Light.png", 30, 30))
{ {
Margin = 10 Margin = 10,
}; };
// //
@ -325,7 +323,7 @@ namespace Ryujinx.Ui.Windows
// //
_twitterLabel = new Label("Twitter") _twitterLabel = new Label("Twitter")
{ {
Justify = Justification.Center Justify = Justification.Center,
}; };
// //
@ -333,7 +331,7 @@ namespace Ryujinx.Ui.Windows
// //
_separator = new Separator(Orientation.Vertical) _separator = new Separator(Orientation.Vertical)
{ {
Margin = 15 Margin = 15,
}; };
// //
@ -342,7 +340,7 @@ namespace Ryujinx.Ui.Windows
_rightBox = new Box(Orientation.Vertical, 0) _rightBox = new Box(Orientation.Vertical, 0)
{ {
Margin = 15, Margin = 15,
MarginTop = 40 MarginTop = 40,
}; };
// //
@ -351,7 +349,7 @@ namespace Ryujinx.Ui.Windows
_aboutLabel = new Label("About :") _aboutLabel = new Label("About :")
{ {
Halign = Align.Start, Halign = Align.Start,
Attributes = new AttrList() Attributes = new AttrList(),
}; };
_aboutLabel.Attributes.Insert(new Pango.AttrWeight(Weight.Bold)); _aboutLabel.Attributes.Insert(new Pango.AttrWeight(Weight.Bold));
_aboutLabel.Attributes.Insert(new Pango.AttrUnderline(Underline.Single)); _aboutLabel.Attributes.Insert(new Pango.AttrUnderline(Underline.Single));
@ -365,7 +363,7 @@ namespace Ryujinx.Ui.Windows
"Developers interested in contributing can find out more on our GitHub or Discord.") "Developers interested in contributing can find out more on our GitHub or Discord.")
{ {
Margin = 15, Margin = 15,
Halign = Align.Start Halign = Align.Start,
}; };
// //
@ -374,7 +372,7 @@ namespace Ryujinx.Ui.Windows
_createdByLabel = new Label("Maintained by :") _createdByLabel = new Label("Maintained by :")
{ {
Halign = Align.Start, Halign = Align.Start,
Attributes = new AttrList() Attributes = new AttrList(),
}; };
_createdByLabel.Attributes.Insert(new Pango.AttrWeight(Weight.Bold)); _createdByLabel.Attributes.Insert(new Pango.AttrWeight(Weight.Bold));
_createdByLabel.Attributes.Insert(new Pango.AttrUnderline(Underline.Single)); _createdByLabel.Attributes.Insert(new Pango.AttrUnderline(Underline.Single));
@ -388,7 +386,7 @@ namespace Ryujinx.Ui.Windows
Editable = false, Editable = false,
CursorVisible = false, CursorVisible = false,
Margin = 15, Margin = 15,
MarginRight = 30 MarginEnd = 30,
}; };
_createdByText.Buffer.Text = "gdkchan, Ac_K, Thog, rip in peri peri, LDj3SNuD, emmaus, Thealexbarney, Xpl0itR, GoffyDude, »jD« and more..."; _createdByText.Buffer.Text = "gdkchan, Ac_K, Thog, rip in peri peri, LDj3SNuD, emmaus, Thealexbarney, Xpl0itR, GoffyDude, »jD« and more...";
@ -404,9 +402,9 @@ namespace Ryujinx.Ui.Windows
_contributorsLinkLabel = new Label("See All Contributors...") _contributorsLinkLabel = new Label("See All Contributors...")
{ {
TooltipText = "Click to open the Contributors page in your default browser.", TooltipText = "Click to open the Contributors page in your default browser.",
MarginRight = 30, MarginEnd = 30,
Halign = Align.End, Halign = Align.End,
Attributes = new AttrList() Attributes = new AttrList(),
}; };
_contributorsLinkLabel.Attributes.Insert(new Pango.AttrUnderline(Underline.Single)); _contributorsLinkLabel.Attributes.Insert(new Pango.AttrUnderline(Underline.Single));
@ -416,7 +414,7 @@ namespace Ryujinx.Ui.Windows
_patreonNamesLabel = new Label("Supported on Patreon by :") _patreonNamesLabel = new Label("Supported on Patreon by :")
{ {
Halign = Align.Start, Halign = Align.Start,
Attributes = new AttrList() Attributes = new AttrList(),
}; };
_patreonNamesLabel.Attributes.Insert(new Pango.AttrWeight(Weight.Bold)); _patreonNamesLabel.Attributes.Insert(new Pango.AttrWeight(Weight.Bold));
_patreonNamesLabel.Attributes.Insert(new Pango.AttrUnderline(Underline.Single)); _patreonNamesLabel.Attributes.Insert(new Pango.AttrUnderline(Underline.Single));
@ -427,9 +425,9 @@ namespace Ryujinx.Ui.Windows
_patreonNamesScrolled = new ScrolledWindow() _patreonNamesScrolled = new ScrolledWindow()
{ {
Margin = 15, Margin = 15,
MarginRight = 30, MarginEnd = 30,
Expand = true, Expand = true,
ShadowType = ShadowType.In ShadowType = ShadowType.In,
}; };
_patreonNamesScrolled.SetPolicy(PolicyType.Never, PolicyType.Automatic); _patreonNamesScrolled.SetPolicy(PolicyType.Never, PolicyType.Automatic);
@ -438,13 +436,11 @@ namespace Ryujinx.Ui.Windows
// //
_patreonNamesText = new TextView() _patreonNamesText = new TextView()
{ {
WrapMode = Gtk.WrapMode.Word WrapMode = Gtk.WrapMode.Word,
}; };
_patreonNamesText.Buffer.Text = "Loading..."; _patreonNamesText.Buffer.Text = "Loading...";
_patreonNamesText.SetProperty("editable", new GLib.Value(false)); _patreonNamesText.SetProperty("editable", new GLib.Value(false));
#pragma warning restore CS0612
ShowComponent(); ShowComponent();
} }

View file

@ -25,7 +25,7 @@ namespace Ryujinx.Ui.Windows
_patreonNamesText.Buffer.Text = "Connection Error."; _patreonNamesText.Buffer.Text = "Connection Error.";
} }
HttpClient httpClient = new HttpClient(); HttpClient httpClient = new();
try try
{ {

View file

@ -23,8 +23,6 @@ namespace Ryujinx.Ui.Windows
private void InitializeComponent() private void InitializeComponent()
{ {
#pragma warning disable CS0612
// //
// AmiiboWindow // AmiiboWindow
// //
@ -47,7 +45,7 @@ namespace Ryujinx.Ui.Windows
_buttonBox = new ButtonBox(Orientation.Horizontal) _buttonBox = new ButtonBox(Orientation.Horizontal)
{ {
Margin = 20, Margin = 20,
LayoutStyle = ButtonBoxStyle.End LayoutStyle = ButtonBoxStyle.End,
}; };
// //
@ -58,7 +56,7 @@ namespace Ryujinx.Ui.Windows
Label = "Scan It!", Label = "Scan It!",
CanFocus = true, CanFocus = true,
ReceivesDefault = true, ReceivesDefault = true,
MarginLeft = 10 MarginStart = 10,
}; };
_scanButton.Clicked += ScanButton_Pressed; _scanButton.Clicked += ScanButton_Pressed;
@ -68,7 +66,7 @@ namespace Ryujinx.Ui.Windows
_randomUuidCheckBox = new CheckButton() _randomUuidCheckBox = new CheckButton()
{ {
Label = "Hack: Use Random Tag Uuid", Label = "Hack: Use Random Tag Uuid",
TooltipText = "This allows multiple scans of a single Amiibo.\n(used in The Legend of Zelda: Breath of the Wild)" TooltipText = "This allows multiple scans of a single Amiibo.\n(used in The Legend of Zelda: Breath of the Wild)",
}; };
// //
@ -79,7 +77,7 @@ namespace Ryujinx.Ui.Windows
Label = "Cancel", Label = "Cancel",
CanFocus = true, CanFocus = true,
ReceivesDefault = true, ReceivesDefault = true,
MarginLeft = 10 MarginStart = 10,
}; };
_cancelButton.Clicked += CancelButton_Pressed; _cancelButton.Clicked += CancelButton_Pressed;
@ -94,7 +92,7 @@ namespace Ryujinx.Ui.Windows
_amiiboHeadBox = new Box(Orientation.Horizontal, 0) _amiiboHeadBox = new Box(Orientation.Horizontal, 0)
{ {
Margin = 20, Margin = 20,
Hexpand = true Hexpand = true,
}; };
// //
@ -102,7 +100,7 @@ namespace Ryujinx.Ui.Windows
// //
_amiiboSeriesBox = new Box(Orientation.Horizontal, 0) _amiiboSeriesBox = new Box(Orientation.Horizontal, 0)
{ {
Hexpand = true Hexpand = true,
}; };
// //
@ -120,7 +118,7 @@ namespace Ryujinx.Ui.Windows
// //
_amiiboCharsBox = new Box(Orientation.Horizontal, 0) _amiiboCharsBox = new Box(Orientation.Horizontal, 0)
{ {
Hexpand = true Hexpand = true,
}; };
// //
@ -138,7 +136,7 @@ namespace Ryujinx.Ui.Windows
// //
_showAllCheckBox = new CheckButton() _showAllCheckBox = new CheckButton()
{ {
Label = "Show All Amiibo" Label = "Show All Amiibo",
}; };
// //
@ -147,7 +145,7 @@ namespace Ryujinx.Ui.Windows
_amiiboImage = new Image() _amiiboImage = new Image()
{ {
HeightRequest = 350, HeightRequest = 350,
WidthRequest = 350 WidthRequest = 350,
}; };
// //
@ -155,11 +153,9 @@ namespace Ryujinx.Ui.Windows
// //
_gameUsageLabel = new Label("") _gameUsageLabel = new Label("")
{ {
MarginTop = 20 MarginTop = 20,
}; };
#pragma warning restore CS0612
ShowComponent(); ShowComponent();
} }

View file

@ -14,14 +14,12 @@ using System.Net.Http;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using AmiiboApi = Ryujinx.Ui.Common.Models.Amiibo.AmiiboApi;
using AmiiboJsonSerializerContext = Ryujinx.Ui.Common.Models.Amiibo.AmiiboJsonSerializerContext;
namespace Ryujinx.Ui.Windows namespace Ryujinx.Ui.Windows
{ {
public partial class AmiiboWindow : Window public partial class AmiiboWindow : Window
{ {
private const string DEFAULT_JSON = "{ \"amiibo\": [] }"; private const string DefaultJson = "{ \"amiibo\": [] }";
public string AmiiboId { get; private set; } public string AmiiboId { get; private set; }
@ -47,7 +45,7 @@ namespace Ryujinx.Ui.Windows
private List<AmiiboApi> _amiiboList; private List<AmiiboApi> _amiiboList;
private static readonly AmiiboJsonSerializerContext SerializerContext = new(JsonHelper.GetDefaultSerializerOptions()); private static readonly AmiiboJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
public AmiiboWindow() : base($"Ryujinx {Program.Version} - Amiibo") public AmiiboWindow() : base($"Ryujinx {Program.Version} - Amiibo")
{ {
@ -57,7 +55,7 @@ namespace Ryujinx.Ui.Windows
_httpClient = new HttpClient() _httpClient = new HttpClient()
{ {
Timeout = TimeSpan.FromSeconds(30) Timeout = TimeSpan.FromSeconds(30),
}; };
Directory.CreateDirectory(System.IO.Path.Join(AppDataManager.BaseDirPath, "system", "amiibo")); Directory.CreateDirectory(System.IO.Path.Join(AppDataManager.BaseDirPath, "system", "amiibo"));
@ -76,13 +74,13 @@ namespace Ryujinx.Ui.Windows
private async Task LoadContentAsync() private async Task LoadContentAsync()
{ {
string amiiboJsonString = DEFAULT_JSON; string amiiboJsonString = DefaultJson;
if (File.Exists(_amiiboJsonPath)) if (File.Exists(_amiiboJsonPath))
{ {
amiiboJsonString = await File.ReadAllTextAsync(_amiiboJsonPath); amiiboJsonString = await File.ReadAllTextAsync(_amiiboJsonPath);
if (await NeedsUpdate(JsonHelper.Deserialize(amiiboJsonString, SerializerContext.AmiiboJson).LastUpdated)) if (await NeedsUpdate(JsonHelper.Deserialize(amiiboJsonString, _serializerContext.AmiiboJson).LastUpdated))
{ {
amiiboJsonString = await DownloadAmiiboJson(); amiiboJsonString = await DownloadAmiiboJson();
} }
@ -103,7 +101,7 @@ namespace Ryujinx.Ui.Windows
} }
} }
_amiiboList = JsonHelper.Deserialize(amiiboJsonString, SerializerContext.AmiiboJson).Amiibo; _amiiboList = JsonHelper.Deserialize(amiiboJsonString, _serializerContext.AmiiboJson).Amiibo;
_amiiboList = _amiiboList.OrderBy(amiibo => amiibo.AmiiboSeries).ToList(); _amiiboList = _amiiboList.OrderBy(amiibo => amiibo.AmiiboSeries).ToList();
if (LastScannedAmiiboShowAll) if (LastScannedAmiiboShowAll)
@ -118,7 +116,7 @@ namespace Ryujinx.Ui.Windows
private void ParseAmiiboData() private void ParseAmiiboData()
{ {
List<string> comboxItemList = new List<string>(); List<string> comboxItemList = new();
for (int i = 0; i < _amiiboList.Count; i++) for (int i = 0; i < _amiiboList.Count; i++)
{ {
@ -219,7 +217,7 @@ namespace Ryujinx.Ui.Windows
Close(); Close();
} }
return DEFAULT_JSON; return DefaultJson;
} }
private async Task UpdateAmiiboPreview(string imageUrl) private async Task UpdateAmiiboPreview(string imageUrl)
@ -229,7 +227,7 @@ namespace Ryujinx.Ui.Windows
if (response.IsSuccessStatusCode) if (response.IsSuccessStatusCode)
{ {
byte[] amiiboPreviewBytes = await response.Content.ReadAsByteArrayAsync(); byte[] amiiboPreviewBytes = await response.Content.ReadAsByteArrayAsync();
Gdk.Pixbuf amiiboPreview = new Gdk.Pixbuf(amiiboPreviewBytes); Gdk.Pixbuf amiiboPreview = new(amiiboPreviewBytes);
float ratio = Math.Min((float)_amiiboImage.AllocatedWidth / amiiboPreview.Width, float ratio = Math.Min((float)_amiiboImage.AllocatedWidth / amiiboPreview.Width,
(float)_amiiboImage.AllocatedHeight / amiiboPreview.Height); (float)_amiiboImage.AllocatedHeight / amiiboPreview.Height);
@ -245,7 +243,7 @@ namespace Ryujinx.Ui.Windows
} }
} }
private void ShowInfoDialog() private static void ShowInfoDialog()
{ {
GtkDialog.CreateInfoDialog($"Amiibo API", "Unable to connect to Amiibo API server. The service may be down or you may need to verify your internet connection is online."); GtkDialog.CreateInfoDialog($"Amiibo API", "Unable to connect to Amiibo API server. The service may be down or you may need to verify your internet connection is online.");
} }
@ -261,7 +259,7 @@ namespace Ryujinx.Ui.Windows
List<AmiiboApi> amiiboSortedList = _amiiboList.Where(amiibo => amiibo.AmiiboSeries == _amiiboSeriesComboBox.ActiveId).OrderBy(amiibo => amiibo.Name).ToList(); List<AmiiboApi> amiiboSortedList = _amiiboList.Where(amiibo => amiibo.AmiiboSeries == _amiiboSeriesComboBox.ActiveId).OrderBy(amiibo => amiibo.Name).ToList();
List<string> comboxItemList = new List<string>(); List<string> comboxItemList = new();
for (int i = 0; i < amiiboSortedList.Count; i++) for (int i = 0; i < amiiboSortedList.Count; i++)
{ {

View file

@ -18,7 +18,6 @@ using System.Buffers.Binary;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using Image = SixLabors.ImageSharp.Image; using Image = SixLabors.ImageSharp.Image;
namespace Ryujinx.Ui.Windows namespace Ryujinx.Ui.Windows
@ -28,11 +27,11 @@ namespace Ryujinx.Ui.Windows
public byte[] SelectedProfileImage; public byte[] SelectedProfileImage;
public bool NewUser; public bool NewUser;
private static Dictionary<string, byte[]> _avatarDict = new Dictionary<string, byte[]>(); private static readonly Dictionary<string, byte[]> _avatarDict = new();
private ListStore _listStore; private readonly ListStore _listStore;
private IconView _iconView; private readonly IconView _iconView;
private Button _setBackgroungColorButton; private readonly Button _setBackgroungColorButton;
private Gdk.RGBA _backgroundColor; private Gdk.RGBA _backgroundColor;
public AvatarWindow() : base($"Ryujinx {Program.Version} - Manage Accounts - Avatar") public AvatarWindow() : base($"Ryujinx {Program.Version} - Manage Accounts - Avatar")
@ -50,26 +49,26 @@ namespace Ryujinx.Ui.Windows
Box vbox = new(Orientation.Vertical, 0); Box vbox = new(Orientation.Vertical, 0);
Add(vbox); Add(vbox);
ScrolledWindow scrolledWindow = new ScrolledWindow ScrolledWindow scrolledWindow = new()
{ {
ShadowType = ShadowType.EtchedIn ShadowType = ShadowType.EtchedIn,
}; };
scrolledWindow.SetPolicy(PolicyType.Automatic, PolicyType.Automatic); scrolledWindow.SetPolicy(PolicyType.Automatic, PolicyType.Automatic);
Box hbox = new(Orientation.Horizontal, 0); Box hbox = new(Orientation.Horizontal, 0);
Button chooseButton = new Button() Button chooseButton = new()
{ {
Label = "Choose", Label = "Choose",
CanFocus = true, CanFocus = true,
ReceivesDefault = true ReceivesDefault = true,
}; };
chooseButton.Clicked += ChooseButton_Pressed; chooseButton.Clicked += ChooseButton_Pressed;
_setBackgroungColorButton = new Button() _setBackgroungColorButton = new Button()
{ {
Label = "Set Background Color", Label = "Set Background Color",
CanFocus = true CanFocus = true,
}; };
_setBackgroungColorButton.Clicked += SetBackgroungColorButton_Pressed; _setBackgroungColorButton.Clicked += SetBackgroungColorButton_Pressed;
@ -78,10 +77,10 @@ namespace Ryujinx.Ui.Windows
_backgroundColor.Blue = 1; _backgroundColor.Blue = 1;
_backgroundColor.Alpha = 1; _backgroundColor.Alpha = 1;
Button closeButton = new Button() Button closeButton = new()
{ {
Label = "Close", Label = "Close",
CanFocus = true CanFocus = true,
}; };
closeButton.Clicked += CloseButton_Pressed; closeButton.Clicked += CloseButton_Pressed;
@ -94,10 +93,12 @@ namespace Ryujinx.Ui.Windows
_listStore = new ListStore(typeof(string), typeof(Gdk.Pixbuf)); _listStore = new ListStore(typeof(string), typeof(Gdk.Pixbuf));
_listStore.SetSortColumnId(0, SortType.Ascending); _listStore.SetSortColumnId(0, SortType.Ascending);
_iconView = new IconView(_listStore); _iconView = new IconView(_listStore)
_iconView.ItemWidth = 64; {
_iconView.ItemPadding = 10; ItemWidth = 64,
_iconView.PixbufColumn = 1; ItemPadding = 10,
PixbufColumn = 1,
};
_iconView.SelectionChanged += IconView_SelectionChanged; _iconView.SelectionChanged += IconView_SelectionChanged;
@ -122,9 +123,9 @@ namespace Ryujinx.Ui.Windows
if (!string.IsNullOrWhiteSpace(avatarPath)) if (!string.IsNullOrWhiteSpace(avatarPath))
{ {
using (IStorage ncaFileStream = new LocalStorage(avatarPath, FileAccess.Read, FileMode.Open)) using IStorage ncaFileStream = new LocalStorage(avatarPath, FileAccess.Read, FileMode.Open);
{
Nca nca = new Nca(virtualFileSystem.KeySet, ncaFileStream); Nca nca = new(virtualFileSystem.KeySet, ncaFileStream);
IFileSystem romfs = nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid); IFileSystem romfs = nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid);
foreach (var item in romfs.EnumerateEntries()) foreach (var item in romfs.EnumerateEntries())
@ -137,9 +138,8 @@ namespace Ryujinx.Ui.Windows
romfs.OpenFile(ref file.Ref, ("/" + item.FullPath).ToU8Span(), OpenMode.Read).ThrowIfFailure(); romfs.OpenFile(ref file.Ref, ("/" + item.FullPath).ToU8Span(), OpenMode.Read).ThrowIfFailure();
using (MemoryStream stream = MemoryStreamManager.Shared.GetStream()) using MemoryStream stream = MemoryStreamManager.Shared.GetStream();
using (MemoryStream streamPng = MemoryStreamManager.Shared.GetStream()) using MemoryStream streamPng = MemoryStreamManager.Shared.GetStream();
{
file.Get.AsStream().CopyTo(stream); file.Get.AsStream().CopyTo(stream);
stream.Position = 0; stream.Position = 0;
@ -153,8 +153,6 @@ namespace Ryujinx.Ui.Windows
} }
} }
} }
}
}
private void ProcessAvatars() private void ProcessAvatars()
{ {
@ -165,24 +163,25 @@ namespace Ryujinx.Ui.Windows
_listStore.AppendValues(avatar.Key, new Gdk.Pixbuf(ProcessImage(avatar.Value), 96, 96)); _listStore.AppendValues(avatar.Key, new Gdk.Pixbuf(ProcessImage(avatar.Value), 96, 96));
} }
_iconView.SelectPath(new TreePath(new int[] { 0 })); _iconView.SelectPath(new TreePath(new[] { 0 }));
} }
private byte[] ProcessImage(byte[] data) private byte[] ProcessImage(byte[] data)
{ {
using (MemoryStream streamJpg = MemoryStreamManager.Shared.GetStream()) using MemoryStream streamJpg = MemoryStreamManager.Shared.GetStream();
{
Image avatarImage = Image.Load(data, new PngDecoder()); Image avatarImage = Image.Load(data, new PngDecoder());
avatarImage.Mutate(x => x.BackgroundColor(new Rgba32((byte)(_backgroundColor.Red * 255), avatarImage.Mutate(x => x.BackgroundColor(new Rgba32(
(byte)(_backgroundColor.Red * 255),
(byte)(_backgroundColor.Green * 255), (byte)(_backgroundColor.Green * 255),
(byte)(_backgroundColor.Blue * 255), (byte)(_backgroundColor.Blue * 255),
(byte)(_backgroundColor.Alpha * 255)))); (byte)(_backgroundColor.Alpha * 255)
)));
avatarImage.SaveAsJpeg(streamJpg); avatarImage.SaveAsJpeg(streamJpg);
return streamJpg.ToArray(); return streamJpg.ToArray();
} }
}
private void CloseButton_Pressed(object sender, EventArgs e) private void CloseButton_Pressed(object sender, EventArgs e)
{ {
@ -203,8 +202,8 @@ namespace Ryujinx.Ui.Windows
private void SetBackgroungColorButton_Pressed(object sender, EventArgs e) private void SetBackgroungColorButton_Pressed(object sender, EventArgs e)
{ {
using (ColorChooserDialog colorChooserDialog = new ColorChooserDialog("Set Background Color", this)) using ColorChooserDialog colorChooserDialog = new("Set Background Color", this);
{
colorChooserDialog.UseAlpha = false; colorChooserDialog.UseAlpha = false;
colorChooserDialog.Rgba = _backgroundColor; colorChooserDialog.Rgba = _backgroundColor;
@ -217,7 +216,6 @@ namespace Ryujinx.Ui.Windows
colorChooserDialog.Hide(); colorChooserDialog.Hide();
} }
}
private void ChooseButton_Pressed(object sender, EventArgs e) private void ChooseButton_Pressed(object sender, EventArgs e)
{ {
@ -226,8 +224,8 @@ namespace Ryujinx.Ui.Windows
private static byte[] DecompressYaz0(Stream stream) private static byte[] DecompressYaz0(Stream stream)
{ {
using (BinaryReader reader = new BinaryReader(stream)) using BinaryReader reader = new(stream);
{
reader.ReadInt32(); // Magic reader.ReadInt32(); // Magic
uint decodedLength = BinaryPrimitives.ReverseEndianness(reader.ReadUInt32()); uint decodedLength = BinaryPrimitives.ReverseEndianness(reader.ReadUInt32());
@ -290,5 +288,4 @@ namespace Ryujinx.Ui.Windows
return output; return output;
} }
} }
}
} }

View file

@ -6,7 +6,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using GUI = Gtk.Builder.ObjectAttribute; using GUI = Gtk.Builder.ObjectAttribute;
namespace Ryujinx.Ui.Windows namespace Ryujinx.Ui.Windows
@ -16,7 +15,7 @@ namespace Ryujinx.Ui.Windows
private readonly string _enabledCheatsPath; private readonly string _enabledCheatsPath;
private readonly bool _noCheatsFound; private readonly bool _noCheatsFound;
#pragma warning disable CS0649, IDE0044 #pragma warning disable CS0649, IDE0044 // Field is never assigned to, Add readonly modifier
[GUI] Label _baseTitleInfoLabel; [GUI] Label _baseTitleInfoLabel;
[GUI] TextView _buildIdTextView; [GUI] TextView _buildIdTextView;
[GUI] TreeView _cheatTreeView; [GUI] TreeView _cheatTreeView;
@ -38,7 +37,7 @@ namespace Ryujinx.Ui.Windows
_cheatTreeView.Model = new TreeStore(typeof(bool), typeof(string), typeof(string), typeof(string)); _cheatTreeView.Model = new TreeStore(typeof(bool), typeof(string), typeof(string), typeof(string));
CellRendererToggle enableToggle = new CellRendererToggle(); CellRendererToggle enableToggle = new();
enableToggle.Toggled += (sender, args) => enableToggle.Toggled += (sender, args) =>
{ {
_cheatTreeView.Model.GetIter(out TreeIter treeIter, new TreePath(args.Path)); _cheatTreeView.Model.GetIter(out TreeIter treeIter, new TreePath(args.Path));
@ -62,7 +61,7 @@ namespace Ryujinx.Ui.Windows
var buildIdColumn = _cheatTreeView.AppendColumn("Build Id", new CellRendererText(), "text", 3); var buildIdColumn = _cheatTreeView.AppendColumn("Build Id", new CellRendererText(), "text", 3);
buildIdColumn.Visible = false; buildIdColumn.Visible = false;
string[] enabled = { }; string[] enabled = Array.Empty<string>();
if (File.Exists(_enabledCheatsPath)) if (File.Exists(_enabledCheatsPath))
{ {
@ -90,7 +89,7 @@ namespace Ryujinx.Ui.Windows
parentIter = ((TreeStore)_cheatTreeView.Model).AppendValues(false, buildId, parentPath, ""); parentIter = ((TreeStore)_cheatTreeView.Model).AppendValues(false, buildId, parentPath, "");
} }
string cleanName = cheat.Name.Substring(1, cheat.Name.Length - 8); string cleanName = cheat.Name[1..^7];
((TreeStore)_cheatTreeView.Model).AppendValues(parentIter, enabled.Contains($"{buildId}-{cheat.Name}"), cleanName, "", buildId); ((TreeStore)_cheatTreeView.Model).AppendValues(parentIter, enabled.Contains($"{buildId}-{cheat.Name}"), cleanName, "", buildId);
cheatAdded++; cheatAdded++;
@ -116,7 +115,7 @@ namespace Ryujinx.Ui.Windows
return; return;
} }
List<string> enabledCheats = new List<string>(); List<string> enabledCheats = new();
if (_cheatTreeView.Model.GetIterFirst(out TreeIter parentIter)) if (_cheatTreeView.Model.GetIterFirst(out TreeIter parentIter))
{ {

View file

@ -31,7 +31,7 @@ namespace Ryujinx.Ui.Windows
private bool _isWaitingForInput; private bool _isWaitingForInput;
#pragma warning disable CS0649, IDE0044 #pragma warning disable CS0649, IDE0044 // Field is never assigned to, Add readonly modifier
[GUI] Adjustment _controllerStrongRumble; [GUI] Adjustment _controllerStrongRumble;
[GUI] Adjustment _controllerWeakRumble; [GUI] Adjustment _controllerWeakRumble;
[GUI] Adjustment _controllerDeadzoneLeft; [GUI] Adjustment _controllerDeadzoneLeft;
@ -87,7 +87,7 @@ namespace Ryujinx.Ui.Windows
[GUI] ToggleButton _rStick; [GUI] ToggleButton _rStick;
[GUI] CheckButton _invertRStickX; [GUI] CheckButton _invertRStickX;
[GUI] CheckButton _invertRStickY; [GUI] CheckButton _invertRStickY;
[GUI] CheckButton _rotateR90CW; [GUI] CheckButton _rotateR90Cw;
[GUI] ToggleButton _rStickUp; [GUI] ToggleButton _rStickUp;
[GUI] ToggleButton _rStickDown; [GUI] ToggleButton _rStickDown;
[GUI] ToggleButton _rStickLeft; [GUI] ToggleButton _rStickLeft;
@ -109,13 +109,13 @@ namespace Ryujinx.Ui.Windows
[GUI] Box _rumbleBox; [GUI] Box _rumbleBox;
#pragma warning restore CS0649, IDE0044 #pragma warning restore CS0649, IDE0044
private MainWindow _mainWindow; private readonly MainWindow _mainWindow;
private IGamepadDriver _gtk3KeyboardDriver; private readonly IGamepadDriver _gtk3KeyboardDriver;
private IGamepad _selectedGamepad; private IGamepad _selectedGamepad;
private bool _mousePressed; private bool _mousePressed;
private bool _middleMousePressed; private bool _middleMousePressed;
private static readonly InputConfigJsonSerializerContext SerializerContext = new(JsonHelper.GetDefaultSerializerOptions()); private static readonly InputConfigJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
public ControllerWindow(MainWindow mainWindow, PlayerIndex controllerId) : this(mainWindow, new Builder("Ryujinx.Ui.Windows.ControllerWindow.glade"), controllerId) { } public ControllerWindow(MainWindow mainWindow, PlayerIndex controllerId) : this(mainWindow, new Builder("Ryujinx.Ui.Windows.ControllerWindow.glade"), controllerId) { }
@ -197,10 +197,7 @@ namespace Ryujinx.Ui.Windows
mainWindow.InputManager.GamepadDriver.OnGamepadConnected += HandleOnGamepadConnected; mainWindow.InputManager.GamepadDriver.OnGamepadConnected += HandleOnGamepadConnected;
mainWindow.InputManager.GamepadDriver.OnGamepadDisconnected += HandleOnGamepadDisconnected; mainWindow.InputManager.GamepadDriver.OnGamepadDisconnected += HandleOnGamepadDisconnected;
if (_mainWindow.RendererWidget != null) _mainWindow.RendererWidget?.NpadManager.BlockInputUpdates();
{
_mainWindow.RendererWidget.NpadManager.BlockInputUpdates();
}
} }
private void CemuHookCheckButtonPressed(object sender, EventArgs e) private void CemuHookCheckButtonPressed(object sender, EventArgs e)
@ -229,10 +226,7 @@ namespace Ryujinx.Ui.Windows
_mainWindow.InputManager.GamepadDriver.OnGamepadConnected -= HandleOnGamepadConnected; _mainWindow.InputManager.GamepadDriver.OnGamepadConnected -= HandleOnGamepadConnected;
_mainWindow.InputManager.GamepadDriver.OnGamepadDisconnected -= HandleOnGamepadDisconnected; _mainWindow.InputManager.GamepadDriver.OnGamepadDisconnected -= HandleOnGamepadDisconnected;
if (_mainWindow.RendererWidget != null) _mainWindow.RendererWidget?.NpadManager.UnblockInputUpdates();
{
_mainWindow.RendererWidget.NpadManager.UnblockInputUpdates();
}
_selectedGamepad?.Dispose(); _selectedGamepad?.Dispose();
@ -509,7 +503,7 @@ namespace Ryujinx.Ui.Windows
_rStick.Label = controllerConfig.RightJoyconStick.Joystick.ToString(); _rStick.Label = controllerConfig.RightJoyconStick.Joystick.ToString();
_invertRStickX.Active = controllerConfig.RightJoyconStick.InvertStickX; _invertRStickX.Active = controllerConfig.RightJoyconStick.InvertStickX;
_invertRStickY.Active = controllerConfig.RightJoyconStick.InvertStickY; _invertRStickY.Active = controllerConfig.RightJoyconStick.InvertStickY;
_rotateR90CW.Active = controllerConfig.RightJoyconStick.Rotate90CW; _rotateR90Cw.Active = controllerConfig.RightJoyconStick.Rotate90CW;
_rStickButton.Label = controllerConfig.RightJoyconStick.StickButton.ToString(); _rStickButton.Label = controllerConfig.RightJoyconStick.StickButton.ToString();
_a.Label = controllerConfig.RightJoycon.ButtonA.ToString(); _a.Label = controllerConfig.RightJoycon.ButtonA.ToString();
_b.Label = controllerConfig.RightJoycon.ButtonB.ToString(); _b.Label = controllerConfig.RightJoycon.ButtonB.ToString();
@ -559,6 +553,7 @@ namespace Ryujinx.Ui.Windows
{ {
if (_inputDevice.ActiveId.StartsWith("keyboard")) if (_inputDevice.ActiveId.StartsWith("keyboard"))
{ {
#pragma warning disable CA1806, IDE0055 // Disable formatting
Enum.TryParse(_lStickUp.Label, out Key lStickUp); Enum.TryParse(_lStickUp.Label, out Key lStickUp);
Enum.TryParse(_lStickDown.Label, out Key lStickDown); Enum.TryParse(_lStickDown.Label, out Key lStickDown);
Enum.TryParse(_lStickLeft.Label, out Key lStickLeft); Enum.TryParse(_lStickLeft.Label, out Key lStickLeft);
@ -588,6 +583,7 @@ namespace Ryujinx.Ui.Windows
Enum.TryParse(_zR.Label, out Key rButtonZr); Enum.TryParse(_zR.Label, out Key rButtonZr);
Enum.TryParse(_rSl.Label, out Key rButtonSl); Enum.TryParse(_rSl.Label, out Key rButtonSl);
Enum.TryParse(_rSr.Label, out Key rButtonSr); Enum.TryParse(_rSr.Label, out Key rButtonSr);
#pragma warning restore CA1806, IDE0055
return new StandardKeyboardInputConfig return new StandardKeyboardInputConfig
{ {
@ -606,7 +602,7 @@ namespace Ryujinx.Ui.Windows
DpadUp = lDPadUp, DpadUp = lDPadUp,
DpadDown = lDPadDown, DpadDown = lDPadDown,
DpadLeft = lDPadLeft, DpadLeft = lDPadLeft,
DpadRight = lDPadRight DpadRight = lDPadRight,
}, },
LeftJoyconStick = new JoyconConfigKeyboardStick<Key> LeftJoyconStick = new JoyconConfigKeyboardStick<Key>
{ {
@ -626,7 +622,7 @@ namespace Ryujinx.Ui.Windows
ButtonR = rButtonR, ButtonR = rButtonR,
ButtonZr = rButtonZr, ButtonZr = rButtonZr,
ButtonSl = rButtonSl, ButtonSl = rButtonSl,
ButtonSr = rButtonSr ButtonSr = rButtonSr,
}, },
RightJoyconStick = new JoyconConfigKeyboardStick<Key> RightJoyconStick = new JoyconConfigKeyboardStick<Key>
{ {
@ -641,6 +637,7 @@ namespace Ryujinx.Ui.Windows
if (_inputDevice.ActiveId.StartsWith("controller")) if (_inputDevice.ActiveId.StartsWith("controller"))
{ {
#pragma warning disable CA1806, IDE0055 // Disable formatting
Enum.TryParse(_lStick.Label, out ConfigStickInputId lStick); Enum.TryParse(_lStick.Label, out ConfigStickInputId lStick);
Enum.TryParse(_lStickButton.Label, out ConfigGamepadInputId lStickButton); Enum.TryParse(_lStickButton.Label, out ConfigGamepadInputId lStickButton);
Enum.TryParse(_minus.Label, out ConfigGamepadInputId lButtonMinus); Enum.TryParse(_minus.Label, out ConfigGamepadInputId lButtonMinus);
@ -666,6 +663,7 @@ namespace Ryujinx.Ui.Windows
Enum.TryParse(_rSr.Label, out ConfigGamepadInputId rButtonSr); Enum.TryParse(_rSr.Label, out ConfigGamepadInputId rButtonSr);
int.TryParse(_dsuServerPort.Buffer.Text, out int port); int.TryParse(_dsuServerPort.Buffer.Text, out int port);
#pragma warning restore CA1806, IDE0055
MotionConfigController motionConfig; MotionConfigController motionConfig;
@ -681,7 +679,7 @@ namespace Ryujinx.Ui.Windows
Slot = (int)_slotNumber.Value, Slot = (int)_slotNumber.Value,
AltSlot = (int)_altSlotNumber.Value, AltSlot = (int)_altSlotNumber.Value,
DsuServerHost = _dsuServerHost.Buffer.Text, DsuServerHost = _dsuServerHost.Buffer.Text,
DsuServerPort = port DsuServerPort = port,
}; };
} }
else else
@ -717,7 +715,7 @@ namespace Ryujinx.Ui.Windows
DpadUp = lDPadUp, DpadUp = lDPadUp,
DpadDown = lDPadDown, DpadDown = lDPadDown,
DpadLeft = lDPadLeft, DpadLeft = lDPadLeft,
DpadRight = lDPadRight DpadRight = lDPadRight,
}, },
LeftJoyconStick = new JoyconConfigControllerStick<ConfigGamepadInputId, ConfigStickInputId> LeftJoyconStick = new JoyconConfigControllerStick<ConfigGamepadInputId, ConfigStickInputId>
{ {
@ -737,7 +735,7 @@ namespace Ryujinx.Ui.Windows
ButtonR = rButtonR, ButtonR = rButtonR,
ButtonZr = rButtonZr, ButtonZr = rButtonZr,
ButtonSl = rButtonSl, ButtonSl = rButtonSl,
ButtonSr = rButtonSr ButtonSr = rButtonSr,
}, },
RightJoyconStick = new JoyconConfigControllerStick<ConfigGamepadInputId, ConfigStickInputId> RightJoyconStick = new JoyconConfigControllerStick<ConfigGamepadInputId, ConfigStickInputId>
{ {
@ -745,15 +743,15 @@ namespace Ryujinx.Ui.Windows
Joystick = rStick, Joystick = rStick,
InvertStickY = _invertRStickY.Active, InvertStickY = _invertRStickY.Active,
StickButton = rStickButton, StickButton = rStickButton,
Rotate90CW = _rotateR90CW.Active, Rotate90CW = _rotateR90Cw.Active,
}, },
Motion = motionConfig, Motion = motionConfig,
Rumble = new RumbleConfigController Rumble = new RumbleConfigController
{ {
StrongRumble = (float)_controllerStrongRumble.Value, StrongRumble = (float)_controllerStrongRumble.Value,
WeakRumble = (float)_controllerWeakRumble.Value, WeakRumble = (float)_controllerWeakRumble.Value,
EnableRumble = _enableRumble.Active EnableRumble = _enableRumble.Active,
} },
}; };
} }
@ -880,7 +878,7 @@ namespace Ryujinx.Ui.Windows
// Open GTK3 keyboard for cancel operations // Open GTK3 keyboard for cancel operations
IKeyboard keyboard = (IKeyboard)_gtk3KeyboardDriver.GetGamepad("0"); IKeyboard keyboard = (IKeyboard)_gtk3KeyboardDriver.GetGamepad("0");
Thread inputThread = new Thread(() => Thread inputThread = new(() =>
{ {
assigner.Initialize(); assigner.Initialize();
@ -916,10 +914,11 @@ namespace Ryujinx.Ui.Windows
button.Active = false; button.Active = false;
_isWaitingForInput = false; _isWaitingForInput = false;
}); });
}); })
{
inputThread.Name = "GUI.InputThread"; Name = "GUI.InputThread",
inputThread.IsBackground = true; IsBackground = true,
};
inputThread.Start(); inputThread.Start();
} }
@ -950,7 +949,7 @@ namespace Ryujinx.Ui.Windows
Directory.CreateDirectory(basePath); Directory.CreateDirectory(basePath);
} }
if (_inputDevice.ActiveId == null|| _inputDevice.ActiveId.Equals("disabled")) if (_inputDevice.ActiveId == null || _inputDevice.ActiveId.Equals("disabled"))
{ {
_profile.Append("default", "None"); _profile.Append("default", "None");
} }
@ -971,7 +970,10 @@ namespace Ryujinx.Ui.Windows
{ {
((ToggleButton)sender).SetStateFlags(StateFlags.Normal, true); ((ToggleButton)sender).SetStateFlags(StateFlags.Normal, true);
if (_inputDevice.ActiveId == "disabled" || _profile.ActiveId == null) return; if (_inputDevice.ActiveId == "disabled" || _profile.ActiveId == null)
{
return;
}
InputConfig config = null; InputConfig config = null;
int pos = _profile.Active; int pos = _profile.Active;
@ -996,7 +998,7 @@ namespace Ryujinx.Ui.Windows
ButtonL = Key.E, ButtonL = Key.E,
ButtonZl = Key.Q, ButtonZl = Key.Q,
ButtonSl = Key.Unbound, ButtonSl = Key.Unbound,
ButtonSr = Key.Unbound ButtonSr = Key.Unbound,
}, },
LeftJoyconStick = new JoyconConfigKeyboardStick<Key> LeftJoyconStick = new JoyconConfigKeyboardStick<Key>
@ -1018,7 +1020,7 @@ namespace Ryujinx.Ui.Windows
ButtonR = Key.U, ButtonR = Key.U,
ButtonZr = Key.O, ButtonZr = Key.O,
ButtonSl = Key.Unbound, ButtonSl = Key.Unbound,
ButtonSr = Key.Unbound ButtonSr = Key.Unbound,
}, },
RightJoyconStick = new JoyconConfigKeyboardStick<Key> RightJoyconStick = new JoyconConfigKeyboardStick<Key>
@ -1028,7 +1030,7 @@ namespace Ryujinx.Ui.Windows
StickLeft = Key.J, StickLeft = Key.J,
StickRight = Key.L, StickRight = Key.L,
StickButton = Key.H, StickButton = Key.H,
} },
}; };
} }
else if (_inputDevice.ActiveId.StartsWith("controller")) else if (_inputDevice.ActiveId.StartsWith("controller"))
@ -1101,8 +1103,8 @@ namespace Ryujinx.Ui.Windows
{ {
StrongRumble = 1f, StrongRumble = 1f,
WeakRumble = 1f, WeakRumble = 1f,
EnableRumble = false EnableRumble = false,
} },
}; };
} }
} }
@ -1122,7 +1124,7 @@ namespace Ryujinx.Ui.Windows
try try
{ {
config = JsonHelper.DeserializeFromFile(path, SerializerContext.InputConfig); config = JsonHelper.DeserializeFromFile(path, _serializerContext.InputConfig);
} }
catch (JsonException) { } catch (JsonException) { }
} }
@ -1134,17 +1136,23 @@ namespace Ryujinx.Ui.Windows
{ {
((ToggleButton)sender).SetStateFlags(StateFlags.Normal, true); ((ToggleButton)sender).SetStateFlags(StateFlags.Normal, true);
if (_inputDevice.ActiveId == "disabled") return; if (_inputDevice.ActiveId == "disabled")
{
return;
}
InputConfig inputConfig = GetValues(); InputConfig inputConfig = GetValues();
ProfileDialog profileDialog = new ProfileDialog(); ProfileDialog profileDialog = new();
if (inputConfig == null) return; if (inputConfig == null)
{
return;
}
if (profileDialog.Run() == (int)ResponseType.Ok) if (profileDialog.Run() == (int)ResponseType.Ok)
{ {
string path = System.IO.Path.Combine(GetProfileBasePath(), profileDialog.FileName); string path = System.IO.Path.Combine(GetProfileBasePath(), profileDialog.FileName);
string jsonString = JsonHelper.Serialize(inputConfig, SerializerContext.InputConfig); string jsonString = JsonHelper.Serialize(inputConfig, _serializerContext.InputConfig);
File.WriteAllText(path, jsonString); File.WriteAllText(path, jsonString);
} }
@ -1156,9 +1164,12 @@ namespace Ryujinx.Ui.Windows
private void ProfileRemove_Activated(object sender, EventArgs args) private void ProfileRemove_Activated(object sender, EventArgs args)
{ {
((ToggleButton) sender).SetStateFlags(StateFlags.Normal, true); ((ToggleButton)sender).SetStateFlags(StateFlags.Normal, true);
if (_inputDevice.ActiveId == "disabled" || _profile.ActiveId == "default" || _profile.ActiveId == null) return; if (_inputDevice.ActiveId == "disabled" || _profile.ActiveId == "default" || _profile.ActiveId == null)
{
return;
}
MessageDialog confirmDialog = GtkDialog.CreateConfirmationDialog("Deleting Profile", "This action is irreversible, are you sure you want to continue?"); MessageDialog confirmDialog = GtkDialog.CreateConfirmationDialog("Deleting Profile", "This action is irreversible, are you sure you want to continue?");
@ -1200,10 +1211,7 @@ namespace Ryujinx.Ui.Windows
} }
} }
if (_mainWindow.RendererWidget != null) _mainWindow.RendererWidget?.NpadManager.ReloadConfiguration(newConfig, ConfigurationState.Instance.Hid.EnableKeyboard, ConfigurationState.Instance.Hid.EnableMouse);
{
_mainWindow.RendererWidget.NpadManager.ReloadConfiguration(newConfig, ConfigurationState.Instance.Hid.EnableKeyboard, ConfigurationState.Instance.Hid.EnableMouse);
}
// Atomically replace and signal input change. // Atomically replace and signal input change.
// NOTE: Do not modify InputConfig.Value directly as other code depends on the on-change event. // NOTE: Do not modify InputConfig.Value directly as other code depends on the on-change event.

View file

@ -24,9 +24,9 @@ namespace Ryujinx.Ui.Windows
private readonly string _dlcJsonPath; private readonly string _dlcJsonPath;
private readonly List<DownloadableContentContainer> _dlcContainerList; private readonly List<DownloadableContentContainer> _dlcContainerList;
private static readonly DownloadableContentJsonSerializerContext SerializerContext = new(JsonHelper.GetDefaultSerializerOptions()); private static readonly DownloadableContentJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
#pragma warning disable CS0649, IDE0044 #pragma warning disable CS0649, IDE0044 // Field is never assigned to, Add readonly modifier
[GUI] Label _baseTitleInfoLabel; [GUI] Label _baseTitleInfoLabel;
[GUI] TreeView _dlcTreeView; [GUI] TreeView _dlcTreeView;
[GUI] TreeSelection _dlcTreeSelection; [GUI] TreeSelection _dlcTreeSelection;
@ -45,7 +45,7 @@ namespace Ryujinx.Ui.Windows
try try
{ {
_dlcContainerList = JsonHelper.DeserializeFromFile(_dlcJsonPath, SerializerContext.ListDownloadableContentContainer); _dlcContainerList = JsonHelper.DeserializeFromFile(_dlcJsonPath, _serializerContext.ListDownloadableContentContainer);
} }
catch catch
{ {
@ -54,7 +54,7 @@ namespace Ryujinx.Ui.Windows
_dlcTreeView.Model = new TreeStore(typeof(bool), typeof(string), typeof(string)); _dlcTreeView.Model = new TreeStore(typeof(bool), typeof(string), typeof(string));
CellRendererToggle enableToggle = new CellRendererToggle(); CellRendererToggle enableToggle = new();
enableToggle.Toggled += (sender, args) => enableToggle.Toggled += (sender, args) =>
{ {
_dlcTreeView.Model.GetIter(out TreeIter treeIter, new TreePath(args.Path)); _dlcTreeView.Model.GetIter(out TreeIter treeIter, new TreePath(args.Path));
@ -85,8 +85,11 @@ namespace Ryujinx.Ui.Windows
// "enabled" box if all child NCAs are enabled. Usually fine since each nsp has only one nca. // "enabled" box if all child NCAs are enabled. Usually fine since each nsp has only one nca.
bool areAllContentPacksEnabled = dlcContainer.DownloadableContentNcaList.TrueForAll((nca) => nca.Enabled); bool areAllContentPacksEnabled = dlcContainer.DownloadableContentNcaList.TrueForAll((nca) => nca.Enabled);
TreeIter parentIter = ((TreeStore)_dlcTreeView.Model).AppendValues(areAllContentPacksEnabled, "", dlcContainer.ContainerPath); TreeIter parentIter = ((TreeStore)_dlcTreeView.Model).AppendValues(areAllContentPacksEnabled, "", dlcContainer.ContainerPath);
using FileStream containerFile = File.OpenRead(dlcContainer.ContainerPath); using FileStream containerFile = File.OpenRead(dlcContainer.ContainerPath);
PartitionFileSystem pfs = new PartitionFileSystem(containerFile.AsStorage());
PartitionFileSystem pfs = new(containerFile.AsStorage());
_virtualFileSystem.ImportTickets(pfs); _virtualFileSystem.ImportTickets(pfs);
foreach (DownloadableContentNca dlcNca in dlcContainer.DownloadableContentNcaList) foreach (DownloadableContentNca dlcNca in dlcContainer.DownloadableContentNcaList)
@ -126,14 +129,14 @@ namespace Ryujinx.Ui.Windows
private void AddButton_Clicked(object sender, EventArgs args) private void AddButton_Clicked(object sender, EventArgs args)
{ {
FileChooserNative fileChooser = new FileChooserNative("Select DLC files", this, FileChooserAction.Open, "Add", "Cancel") FileChooserNative fileChooser = new("Select DLC files", this, FileChooserAction.Open, "Add", "Cancel")
{ {
SelectMultiple = true SelectMultiple = true,
}; };
FileFilter filter = new FileFilter() FileFilter filter = new()
{ {
Name = "Switch Game DLCs" Name = "Switch Game DLCs",
}; };
filter.AddPattern("*.nsp"); filter.AddPattern("*.nsp");
@ -148,9 +151,9 @@ namespace Ryujinx.Ui.Windows
return; return;
} }
using (FileStream containerFile = File.OpenRead(containerPath)) using FileStream containerFile = File.OpenRead(containerPath);
{
PartitionFileSystem pfs = new PartitionFileSystem(containerFile.AsStorage()); PartitionFileSystem pfs = new(containerFile.AsStorage());
bool containsDlc = false; bool containsDlc = false;
_virtualFileSystem.ImportTickets(pfs); _virtualFileSystem.ImportTickets(pfs);
@ -165,7 +168,10 @@ namespace Ryujinx.Ui.Windows
Nca nca = TryCreateNca(ncaFile.Get.AsStorage(), containerPath); Nca nca = TryCreateNca(ncaFile.Get.AsStorage(), containerPath);
if (nca == null) continue; if (nca == null)
{
continue;
}
if (nca.Header.ContentType == NcaContentType.PublicData) if (nca.Header.ContentType == NcaContentType.PublicData)
{ {
@ -187,7 +193,6 @@ namespace Ryujinx.Ui.Windows
} }
} }
} }
}
fileChooser.Dispose(); fileChooser.Dispose();
} }
@ -209,7 +214,7 @@ namespace Ryujinx.Ui.Windows
private void RemoveAllButton_Clicked(object sender, EventArgs args) private void RemoveAllButton_Clicked(object sender, EventArgs args)
{ {
List<TreeIter> toRemove = new List<TreeIter>(); List<TreeIter> toRemove = new();
if (_dlcTreeView.Model.GetIterFirst(out TreeIter iter)) if (_dlcTreeView.Model.GetIterFirst(out TreeIter iter))
{ {
@ -237,10 +242,10 @@ namespace Ryujinx.Ui.Windows
{ {
if (_dlcTreeView.Model.IterChildren(out TreeIter childIter, parentIter)) if (_dlcTreeView.Model.IterChildren(out TreeIter childIter, parentIter))
{ {
DownloadableContentContainer dlcContainer = new DownloadableContentContainer DownloadableContentContainer dlcContainer = new()
{ {
ContainerPath = (string)_dlcTreeView.Model.GetValue(parentIter, 2), ContainerPath = (string)_dlcTreeView.Model.GetValue(parentIter, 2),
DownloadableContentNcaList = new List<DownloadableContentNca>() DownloadableContentNcaList = new List<DownloadableContentNca>(),
}; };
do do
@ -249,7 +254,7 @@ namespace Ryujinx.Ui.Windows
{ {
Enabled = (bool)_dlcTreeView.Model.GetValue(childIter, 0), Enabled = (bool)_dlcTreeView.Model.GetValue(childIter, 0),
TitleId = Convert.ToUInt64(_dlcTreeView.Model.GetValue(childIter, 1).ToString(), 16), TitleId = Convert.ToUInt64(_dlcTreeView.Model.GetValue(childIter, 1).ToString(), 16),
FullPath = (string)_dlcTreeView.Model.GetValue(childIter, 2) FullPath = (string)_dlcTreeView.Model.GetValue(childIter, 2),
}); });
} }
while (_dlcTreeView.Model.IterNext(ref childIter)); while (_dlcTreeView.Model.IterNext(ref childIter));
@ -260,7 +265,7 @@ namespace Ryujinx.Ui.Windows
while (_dlcTreeView.Model.IterNext(ref parentIter)); while (_dlcTreeView.Model.IterNext(ref parentIter));
} }
JsonHelper.SerializeToFile(_dlcJsonPath, _dlcContainerList, SerializerContext.ListDownloadableContentContainer); JsonHelper.SerializeToFile(_dlcJsonPath, _dlcContainerList, _serializerContext.ListDownloadableContentContainer);
Dispose(); Dispose();
} }

View file

@ -6,14 +6,12 @@ using Ryujinx.Audio.Backends.SoundIo;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.GraphicsDriver; using Ryujinx.Common.GraphicsDriver;
using Ryujinx.Graphics.Vulkan;
using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS.Services.Time.TimeZone; using Ryujinx.HLE.HOS.Services.Time.TimeZone;
using Ryujinx.Ui.Common.Configuration; using Ryujinx.Ui.Common.Configuration;
using Ryujinx.Ui.Common.Configuration.System; using Ryujinx.Ui.Common.Configuration.System;
using Ryujinx.Ui.Helper; using Ryujinx.Ui.Helper;
using Ryujinx.Ui.Widgets; using Ryujinx.Ui.Widgets;
using Silk.NET.Vulkan;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
@ -37,7 +35,7 @@ namespace Ryujinx.Ui.Windows
private float _previousVolumeLevel; private float _previousVolumeLevel;
private bool _directoryChanged = false; private bool _directoryChanged = false;
#pragma warning disable CS0649, IDE0044 #pragma warning disable CS0649, IDE0044 // Field is never assigned to, Add readonly modifier
[GUI] CheckButton _traceLogToggle; [GUI] CheckButton _traceLogToggle;
[GUI] CheckButton _errorLogToggle; [GUI] CheckButton _errorLogToggle;
[GUI] CheckButton _warningLogToggle; [GUI] CheckButton _warningLogToggle;
@ -316,11 +314,11 @@ namespace Ryujinx.Ui.Windows
} }
// Custom EntryCompletion Columns. If added to glade, need to override more signals // Custom EntryCompletion Columns. If added to glade, need to override more signals
ListStore tzList = new ListStore(typeof(string), typeof(string), typeof(string)); ListStore tzList = new(typeof(string), typeof(string), typeof(string));
_systemTimeZoneCompletion.Model = tzList; _systemTimeZoneCompletion.Model = tzList;
CellRendererText offsetCol = new CellRendererText(); CellRendererText offsetCol = new();
CellRendererText abbrevCol = new CellRendererText(); CellRendererText abbrevCol = new();
_systemTimeZoneCompletion.PackStart(offsetCol, false); _systemTimeZoneCompletion.PackStart(offsetCol, false);
_systemTimeZoneCompletion.AddAttribute(offsetCol, "text", 0); _systemTimeZoneCompletion.AddAttribute(offsetCol, "text", 0);
@ -418,7 +416,7 @@ namespace Ryujinx.Ui.Windows
_audioBackendSelect.SetActiveIter(dummyIter); _audioBackendSelect.SetActiveIter(dummyIter);
break; break;
default: default:
throw new ArgumentOutOfRangeException(); throw new InvalidOperationException($"{nameof(ConfigurationState.Instance.System.AudioBackend)} contains an invalid value: {ConfigurationState.Instance.System.AudioBackend.Value}");
} }
_audioBackendBox.Add(_audioBackendSelect); _audioBackendBox.Add(_audioBackendSelect);
@ -458,14 +456,14 @@ namespace Ryujinx.Ui.Windows
AudioBackend.SoundIo => soundIoIsSupported, AudioBackend.SoundIo => soundIoIsSupported,
AudioBackend.SDL2 => sdl2IsSupported, AudioBackend.SDL2 => sdl2IsSupported,
AudioBackend.Dummy => true, AudioBackend.Dummy => true,
_ => throw new ArgumentOutOfRangeException() _ => throw new InvalidOperationException($"{nameof(_audioBackendStore)} contains an invalid value for iteration {iter}: {_audioBackendStore.GetValue(iter, 1)}"),
}; };
}); });
if (OperatingSystem.IsMacOS()) if (OperatingSystem.IsMacOS())
{ {
var store = (_graphicsBackend.Model as ListStore); var store = (_graphicsBackend.Model as ListStore);
store.GetIter(out TreeIter openglIter, new TreePath(new int[] {1})); store.GetIter(out TreeIter openglIter, new TreePath(new[] { 1 }));
store.Remove(ref openglIter); store.Remove(ref openglIter);
_graphicsBackend.Model = store; _graphicsBackend.Model = store;
@ -478,15 +476,15 @@ namespace Ryujinx.Ui.Windows
if (Enum.Parse<GraphicsBackend>(_graphicsBackend.ActiveId) == GraphicsBackend.Vulkan) if (Enum.Parse<GraphicsBackend>(_graphicsBackend.ActiveId) == GraphicsBackend.Vulkan)
{ {
var devices = VulkanRenderer.GetPhysicalDevices(); var devices = Graphics.Vulkan.VulkanRenderer.GetPhysicalDevices();
string preferredGpuIdFromConfig = ConfigurationState.Instance.Graphics.PreferredGpu.Value; string preferredGpuIdFromConfig = ConfigurationState.Instance.Graphics.PreferredGpu.Value;
string preferredGpuId = preferredGpuIdFromConfig; string preferredGpuId = preferredGpuIdFromConfig;
bool noGpuId = string.IsNullOrEmpty(preferredGpuIdFromConfig); bool noGpuId = string.IsNullOrEmpty(preferredGpuIdFromConfig);
foreach (var device in devices) foreach (var device in devices)
{ {
string dGPU = device.IsDiscrete ? " (dGPU)" : ""; string dGpu = device.IsDiscrete ? " (dGPU)" : "";
_preferredGpu.Append(device.Id, $"{device.Name}{dGPU}"); _preferredGpu.Append(device.Id, $"{device.Name}{dGpu}");
// If there's no GPU selected yet, we just pick the first GPU. // If there's no GPU selected yet, we just pick the first GPU.
// If there's a discrete GPU available, we always prefer that over the previous selection, // If there's a discrete GPU available, we always prefer that over the previous selection,
@ -555,7 +553,7 @@ namespace Ryujinx.Ui.Windows
{ {
if (_directoryChanged) if (_directoryChanged)
{ {
List<string> gameDirs = new List<string>(); List<string> gameDirs = new();
_gameDirsBoxStore.GetIterFirst(out TreeIter treeIter); _gameDirsBoxStore.GetIterFirst(out TreeIter treeIter);
@ -666,7 +664,7 @@ namespace Ryujinx.Ui.Windows
} }
ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath); ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath);
_parent.UpdateGraphicsConfig(); MainWindow.UpdateGraphicsConfig();
ThemeHelper.ApplyTheme(); ThemeHelper.ApplyTheme();
} }
@ -725,9 +723,9 @@ namespace Ryujinx.Ui.Windows
} }
else else
{ {
FileChooserNative fileChooser = new FileChooserNative("Choose the game directory to add to the list", this, FileChooserAction.SelectFolder, "Add", "Cancel") FileChooserNative fileChooser = new("Choose the game directory to add to the list", this, FileChooserAction.SelectFolder, "Add", "Cancel")
{ {
SelectMultiple = true SelectMultiple = true,
}; };
if (fileChooser.Run() == (int)ResponseType.Accept) if (fileChooser.Run() == (int)ResponseType.Accept)
@ -786,11 +784,11 @@ namespace Ryujinx.Ui.Windows
private void BrowseThemeDir_Pressed(object sender, EventArgs args) private void BrowseThemeDir_Pressed(object sender, EventArgs args)
{ {
using (FileChooserNative fileChooser = new FileChooserNative("Choose the theme to load", this, FileChooserAction.Open, "Select", "Cancel")) using (FileChooserNative fileChooser = new("Choose the theme to load", this, FileChooserAction.Open, "Select", "Cancel"))
{ {
FileFilter filter = new FileFilter() FileFilter filter = new()
{ {
Name = "Theme Files" Name = "Theme Files",
}; };
filter.AddPattern("*.css"); filter.AddPattern("*.css");
@ -809,7 +807,7 @@ namespace Ryujinx.Ui.Windows
{ {
((ToggleButton)sender).SetStateFlags(StateFlags.Normal, true); ((ToggleButton)sender).SetStateFlags(StateFlags.Normal, true);
ControllerWindow controllerWindow = new ControllerWindow(_parent, playerIndex); ControllerWindow controllerWindow = new(_parent, playerIndex);
controllerWindow.SetSizeRequest((int)(controllerWindow.DefaultWidth * Program.WindowScaleFactor), (int)(controllerWindow.DefaultHeight * Program.WindowScaleFactor)); controllerWindow.SetSizeRequest((int)(controllerWindow.DefaultWidth * Program.WindowScaleFactor), (int)(controllerWindow.DefaultHeight * Program.WindowScaleFactor));
controllerWindow.Show(); controllerWindow.Show();

View file

@ -9,7 +9,6 @@ using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS;
using Ryujinx.Ui.App.Common; using Ryujinx.Ui.App.Common;
using Ryujinx.Ui.Widgets; using Ryujinx.Ui.Widgets;
using System; using System;
@ -31,9 +30,9 @@ namespace Ryujinx.Ui.Windows
private TitleUpdateMetadata _titleUpdateWindowData; private TitleUpdateMetadata _titleUpdateWindowData;
private readonly Dictionary<RadioButton, string> _radioButtonToPathDictionary; private readonly Dictionary<RadioButton, string> _radioButtonToPathDictionary;
private static readonly TitleUpdateMetadataJsonSerializerContext SerializerContext = new(JsonHelper.GetDefaultSerializerOptions()); private static readonly TitleUpdateMetadataJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
#pragma warning disable CS0649, IDE0044 #pragma warning disable CS0649, IDE0044 // Field is never assigned to, Add readonly modifier
[GUI] Label _baseTitleInfoLabel; [GUI] Label _baseTitleInfoLabel;
[GUI] Box _availableUpdatesBox; [GUI] Box _availableUpdatesBox;
[GUI] RadioButton _noUpdateRadioButton; [GUI] RadioButton _noUpdateRadioButton;
@ -54,14 +53,14 @@ namespace Ryujinx.Ui.Windows
try try
{ {
_titleUpdateWindowData = JsonHelper.DeserializeFromFile(_updateJsonPath, SerializerContext.TitleUpdateMetadata); _titleUpdateWindowData = JsonHelper.DeserializeFromFile(_updateJsonPath, _serializerContext.TitleUpdateMetadata);
} }
catch catch
{ {
_titleUpdateWindowData = new TitleUpdateMetadata _titleUpdateWindowData = new TitleUpdateMetadata
{ {
Selected = "", Selected = "",
Paths = new List<string>() Paths = new List<string>(),
}; };
} }
@ -89,9 +88,9 @@ namespace Ryujinx.Ui.Windows
{ {
if (File.Exists(path)) if (File.Exists(path))
{ {
using (FileStream file = new FileStream(path, FileMode.Open, FileAccess.Read)) using FileStream file = new(path, FileMode.Open, FileAccess.Read);
{
PartitionFileSystem nsp = new PartitionFileSystem(file.AsStorage()); PartitionFileSystem nsp = new(file.AsStorage());
try try
{ {
@ -99,14 +98,14 @@ namespace Ryujinx.Ui.Windows
if (controlNca != null && patchNca != null) if (controlNca != null && patchNca != null)
{ {
ApplicationControlProperty controlData = new ApplicationControlProperty(); ApplicationControlProperty controlData = new();
using var nacpFile = new UniqueRef<IFile>(); using var nacpFile = new UniqueRef<IFile>();
controlNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None).OpenFile(ref nacpFile.Ref, "/control.nacp".ToU8Span(), OpenMode.Read).ThrowIfFailure(); controlNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None).OpenFile(ref nacpFile.Ref, "/control.nacp".ToU8Span(), OpenMode.Read).ThrowIfFailure();
nacpFile.Get.Read(out _, 0, SpanHelpers.AsByteSpan(ref controlData), ReadOption.None).ThrowIfFailure(); nacpFile.Get.Read(out _, 0, SpanHelpers.AsByteSpan(ref controlData), ReadOption.None).ThrowIfFailure();
RadioButton radioButton = new RadioButton($"Version {controlData.DisplayVersionString.ToString()} - {path}"); RadioButton radioButton = new($"Version {controlData.DisplayVersionString.ToString()} - {path}");
radioButton.JoinGroup(_noUpdateRadioButton); radioButton.JoinGroup(_noUpdateRadioButton);
_availableUpdatesBox.Add(radioButton); _availableUpdatesBox.Add(radioButton);
@ -126,7 +125,6 @@ namespace Ryujinx.Ui.Windows
} }
} }
} }
}
private void RemoveUpdates(bool removeSelectedOnly = false) private void RemoveUpdates(bool removeSelectedOnly = false)
{ {
@ -143,13 +141,13 @@ namespace Ryujinx.Ui.Windows
private void AddButton_Clicked(object sender, EventArgs args) private void AddButton_Clicked(object sender, EventArgs args)
{ {
using (FileChooserNative fileChooser = new FileChooserNative("Select update files", this, FileChooserAction.Open, "Add", "Cancel")) using FileChooserNative fileChooser = new("Select update files", this, FileChooserAction.Open, "Add", "Cancel");
{
fileChooser.SelectMultiple = true; fileChooser.SelectMultiple = true;
FileFilter filter = new FileFilter() FileFilter filter = new()
{ {
Name = "Switch Game Updates" Name = "Switch Game Updates",
}; };
filter.AddPattern("*.nsp"); filter.AddPattern("*.nsp");
@ -163,7 +161,6 @@ namespace Ryujinx.Ui.Windows
} }
} }
} }
}
private void RemoveButton_Clicked(object sender, EventArgs args) private void RemoveButton_Clicked(object sender, EventArgs args)
{ {
@ -193,7 +190,7 @@ namespace Ryujinx.Ui.Windows
} }
} }
JsonHelper.SerializeToFile(_updateJsonPath, _titleUpdateWindowData, SerializerContext.TitleUpdateMetadata); JsonHelper.SerializeToFile(_updateJsonPath, _titleUpdateWindowData, _serializerContext.TitleUpdateMetadata);
_parent.UpdateGameTable(); _parent.UpdateGameTable();

View file

@ -1,5 +1,6 @@
using Gtk; using Gtk;
using Pango; using Pango;
using System;
namespace Ryujinx.Ui.Windows namespace Ryujinx.Ui.Windows
{ {
@ -9,10 +10,10 @@ namespace Ryujinx.Ui.Windows
private Label _selectedLabel; private Label _selectedLabel;
private Box _selectedUserBox; private Box _selectedUserBox;
private Image _selectedUserImage; private Image _selectedUserImage;
private VBox _selectedUserInfoBox; private Box _selectedUserInfoBox;
private Entry _selectedUserNameEntry; private Entry _selectedUserNameEntry;
private Label _selectedUserIdLabel; private Label _selectedUserIdLabel;
private VBox _selectedUserButtonsBox; private Box _selectedUserButtonsBox;
private Button _saveProfileNameButton; private Button _saveProfileNameButton;
private Button _changeProfileImageButton; private Button _changeProfileImageButton;
private Box _usersTreeViewBox; private Box _usersTreeViewBox;
@ -27,9 +28,6 @@ namespace Ryujinx.Ui.Windows
private void InitializeComponent() private void InitializeComponent()
{ {
#pragma warning disable CS0612
// //
// UserProfilesManagerWindow // UserProfilesManagerWindow
// //
@ -53,7 +51,7 @@ namespace Ryujinx.Ui.Windows
{ {
Margin = 15, Margin = 15,
Attributes = new AttrList(), Attributes = new AttrList(),
Halign = Align.Start Halign = Align.Start,
}; };
_selectedLabel.Attributes.Insert(new Pango.AttrWeight(Weight.Bold)); _selectedLabel.Attributes.Insert(new Pango.AttrWeight(Weight.Bold));
@ -67,7 +65,7 @@ namespace Ryujinx.Ui.Windows
// //
_selectedUserBox = new Box(Orientation.Horizontal, 0) _selectedUserBox = new Box(Orientation.Horizontal, 0)
{ {
MarginLeft = 30 MarginStart = 30,
}; };
// //
@ -78,15 +76,18 @@ namespace Ryujinx.Ui.Windows
// //
// _selectedUserInfoBox // _selectedUserInfoBox
// //
_selectedUserInfoBox = new VBox(true, 0); _selectedUserInfoBox = new Box(Orientation.Vertical, 0)
{
Homogeneous = true,
};
// //
// _selectedUserNameEntry // _selectedUserNameEntry
// //
_selectedUserNameEntry = new Entry("") _selectedUserNameEntry = new Entry("")
{ {
MarginLeft = 15, MarginStart = 15,
MaxLength = (int)MaxProfileNameLength MaxLength = (int)MaxProfileNameLength,
}; };
_selectedUserNameEntry.KeyReleaseEvent += SelectedUserNameEntry_KeyReleaseEvent; _selectedUserNameEntry.KeyReleaseEvent += SelectedUserNameEntry_KeyReleaseEvent;
@ -96,15 +97,15 @@ namespace Ryujinx.Ui.Windows
_selectedUserIdLabel = new Label("") _selectedUserIdLabel = new Label("")
{ {
MarginTop = 15, MarginTop = 15,
MarginLeft = 15 MarginStart = 15,
}; };
// //
// _selectedUserButtonsBox // _selectedUserButtonsBox
// //
_selectedUserButtonsBox = new VBox() _selectedUserButtonsBox = new Box(Orientation.Vertical, 0)
{ {
MarginRight = 30 MarginEnd = 30,
}; };
// //
@ -115,7 +116,7 @@ namespace Ryujinx.Ui.Windows
Label = "Save Profile Name", Label = "Save Profile Name",
CanFocus = true, CanFocus = true,
ReceivesDefault = true, ReceivesDefault = true,
Sensitive = false Sensitive = false,
}; };
_saveProfileNameButton.Clicked += EditProfileNameButton_Pressed; _saveProfileNameButton.Clicked += EditProfileNameButton_Pressed;
@ -127,7 +128,7 @@ namespace Ryujinx.Ui.Windows
Label = "Change Profile Image", Label = "Change Profile Image",
CanFocus = true, CanFocus = true,
ReceivesDefault = true, ReceivesDefault = true,
MarginTop = 10 MarginTop = 10,
}; };
_changeProfileImageButton.Clicked += ChangeProfileImageButton_Pressed; _changeProfileImageButton.Clicked += ChangeProfileImageButton_Pressed;
@ -138,7 +139,7 @@ namespace Ryujinx.Ui.Windows
{ {
Margin = 15, Margin = 15,
Attributes = new AttrList(), Attributes = new AttrList(),
Halign = Align.Start Halign = Align.Start,
}; };
_availableUsersLabel.Attributes.Insert(new Pango.AttrWeight(Weight.Bold)); _availableUsersLabel.Attributes.Insert(new Pango.AttrWeight(Weight.Bold));
@ -150,9 +151,9 @@ namespace Ryujinx.Ui.Windows
ShadowType = ShadowType.In, ShadowType = ShadowType.In,
CanFocus = true, CanFocus = true,
Expand = true, Expand = true,
MarginLeft = 30, MarginStart = 30,
MarginRight = 30, MarginEnd = 30,
MarginBottom = 15 MarginBottom = 15,
}; };
// //
@ -175,9 +176,9 @@ namespace Ryujinx.Ui.Windows
// //
_bottomBox = new Box(Orientation.Horizontal, 0) _bottomBox = new Box(Orientation.Horizontal, 0)
{ {
MarginLeft = 30, MarginStart = 30,
MarginRight = 30, MarginEnd = 30,
MarginBottom = 15 MarginBottom = 15,
}; };
// //
@ -188,7 +189,7 @@ namespace Ryujinx.Ui.Windows
Label = "Add New Profile", Label = "Add New Profile",
CanFocus = true, CanFocus = true,
ReceivesDefault = true, ReceivesDefault = true,
HeightRequest = 35 HeightRequest = 35,
}; };
_addButton.Clicked += AddButton_Pressed; _addButton.Clicked += AddButton_Pressed;
@ -201,7 +202,7 @@ namespace Ryujinx.Ui.Windows
CanFocus = true, CanFocus = true,
ReceivesDefault = true, ReceivesDefault = true,
HeightRequest = 35, HeightRequest = 35,
MarginLeft = 10 MarginStart = 10,
}; };
_deleteButton.Clicked += DeleteButton_Pressed; _deleteButton.Clicked += DeleteButton_Pressed;
@ -214,12 +215,10 @@ namespace Ryujinx.Ui.Windows
CanFocus = true, CanFocus = true,
ReceivesDefault = true, ReceivesDefault = true,
HeightRequest = 35, HeightRequest = 35,
WidthRequest = 80 WidthRequest = 80,
}; };
_closeButton.Clicked += CloseButton_Pressed; _closeButton.Clicked += CloseButton_Pressed;
#pragma warning restore CS0612
ShowComponent(); ShowComponent();
} }

View file

@ -13,7 +13,6 @@ using System.Reflection;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Image = SixLabors.ImageSharp.Image; using Image = SixLabors.ImageSharp.Image;
using UserId = Ryujinx.HLE.HOS.Services.Account.Acc.UserId;
namespace Ryujinx.Ui.Windows namespace Ryujinx.Ui.Windows
{ {
@ -29,7 +28,7 @@ namespace Ryujinx.Ui.Windows
private Gdk.RGBA _selectedColor; private Gdk.RGBA _selectedColor;
private ManualResetEvent _avatarsPreloadingEvent = new ManualResetEvent(false); private readonly ManualResetEvent _avatarsPreloadingEvent = new(false);
public UserProfilesManagerWindow(AccountManager accountManager, ContentManager contentManager, VirtualFileSystem virtualFileSystem) : base($"Ryujinx {Program.Version} - Manage User Profiles") public UserProfilesManagerWindow(AccountManager accountManager, ContentManager contentManager, VirtualFileSystem virtualFileSystem) : base($"Ryujinx {Program.Version} - Manage User Profiles")
{ {
@ -45,7 +44,7 @@ namespace Ryujinx.Ui.Windows
_accountManager = accountManager; _accountManager = accountManager;
_contentManager = contentManager; _contentManager = contentManager;
CellRendererToggle userSelectedToggle = new CellRendererToggle(); CellRendererToggle userSelectedToggle = new();
userSelectedToggle.Toggled += UserSelectedToggle_Toggled; userSelectedToggle.Toggled += UserSelectedToggle_Toggled;
// NOTE: Uncomment following line when multiple selection of user profiles is supported. // NOTE: Uncomment following line when multiple selection of user profiles is supported.
@ -178,29 +177,27 @@ namespace Ryujinx.Ui.Windows
private void ProcessProfileImage(byte[] buffer) private void ProcessProfileImage(byte[] buffer)
{ {
using (Image image = Image.Load(buffer)) using Image image = Image.Load(buffer);
{
image.Mutate(x => x.Resize(256, 256)); image.Mutate(x => x.Resize(256, 256));
using (MemoryStream streamJpg = MemoryStreamManager.Shared.GetStream()) using MemoryStream streamJpg = MemoryStreamManager.Shared.GetStream();
{
image.SaveAsJpeg(streamJpg); image.SaveAsJpeg(streamJpg);
_bufferImageProfile = streamJpg.ToArray(); _bufferImageProfile = streamJpg.ToArray();
} }
}
}
private void ProfileImageFileChooser() private void ProfileImageFileChooser()
{ {
FileChooserNative fileChooser = new FileChooserNative("Import Custom Profile Image", this, FileChooserAction.Open, "Import", "Cancel") FileChooserNative fileChooser = new("Import Custom Profile Image", this, FileChooserAction.Open, "Import", "Cancel")
{ {
SelectMultiple = false SelectMultiple = false,
}; };
FileFilter filter = new FileFilter() FileFilter filter = new()
{ {
Name = "Custom Profile Images" Name = "Custom Profile Images",
}; };
filter.AddPattern("*.jpg"); filter.AddPattern("*.jpg");
filter.AddPattern("*.jpeg"); filter.AddPattern("*.jpeg");
@ -225,10 +222,10 @@ namespace Ryujinx.Ui.Windows
} }
else else
{ {
Dictionary<int, string> buttons = new Dictionary<int, string>() Dictionary<int, string> buttons = new()
{ {
{ 0, "Import Image File" }, { 0, "Import Image File" },
{ 1, "Select Firmware Avatar" } { 1, "Select Firmware Avatar" },
}; };
ResponseType responseDialog = GtkDialog.CreateCustomDialog("Profile Image Selection", ResponseType responseDialog = GtkDialog.CreateCustomDialog("Profile Image Selection",
@ -242,9 +239,9 @@ namespace Ryujinx.Ui.Windows
} }
else if (responseDialog == (ResponseType)1) else if (responseDialog == (ResponseType)1)
{ {
AvatarWindow avatarWindow = new AvatarWindow() AvatarWindow avatarWindow = new()
{ {
NewUser = newUser NewUser = newUser,
}; };
avatarWindow.DeleteEvent += AvatarWindow_DeleteEvent; avatarWindow.DeleteEvent += AvatarWindow_DeleteEvent;