diff --git a/docs/compatibility.csv b/docs/compatibility.csv index 570c93618..53ad389b6 100644 --- a/docs/compatibility.csv +++ b/docs/compatibility.csv @@ -2483,7 +2483,7 @@ 0100A5200C2E0000,"Safety First!",,playable,2021-01-06 09:05:23 0100A51013530000,"SaGa Frontier Remastered",nvdec,playable,2022-11-03 13:54:56 010003A00D0B4000,"SaGa SCARLET GRACE: AMBITIONS™",,playable,2022-10-06 13:20:31 -01008D100D43E000,"Saints Row IV®: Re-Elected™",ldn-untested;LAN,playable,2023-12-04 18:33:37 +01008D100D43E000,"Saints Row IV®: Re-Elected™",ldn-untested;LAN;deadlock,ingame,2025-02-02 16:57:53 0100DE600BEEE000,"SAINTS ROW®: THE THIRD™ - THE FULL PACKAGE",slow;LAN,playable,2023-08-24 02:40:58 01007F000EB36000,"Sakai and...",nvdec,playable,2022-12-15 13:53:19 0100B1400E8FE000,"Sakuna: Of Rice and Ruin",,playable,2023-07-24 13:47:13 diff --git a/src/ARMeilleure/CodeGen/CompiledFunction.cs b/src/ARMeilleure/CodeGen/CompiledFunction.cs index 8ea7ff532..7014f715a 100644 --- a/src/ARMeilleure/CodeGen/CompiledFunction.cs +++ b/src/ARMeilleure/CodeGen/CompiledFunction.cs @@ -1,7 +1,6 @@ using ARMeilleure.CodeGen.Linking; using ARMeilleure.CodeGen.Unwinding; using ARMeilleure.Translation.Cache; -using System; using System.Runtime.InteropServices; namespace ARMeilleure.CodeGen diff --git a/src/ARMeilleure/IntermediateRepresentation/MemoryOperand.cs b/src/ARMeilleure/IntermediateRepresentation/MemoryOperand.cs index 45695396f..d22c89a75 100644 --- a/src/ARMeilleure/IntermediateRepresentation/MemoryOperand.cs +++ b/src/ARMeilleure/IntermediateRepresentation/MemoryOperand.cs @@ -1,4 +1,3 @@ -using System; using System.Diagnostics; using System.Runtime.CompilerServices; diff --git a/src/ARMeilleure/Native/JitSupportDarwin.cs b/src/ARMeilleure/Native/JitSupportDarwin.cs index 39df3878f..9383b9a08 100644 --- a/src/ARMeilleure/Native/JitSupportDarwin.cs +++ b/src/ARMeilleure/Native/JitSupportDarwin.cs @@ -1,4 +1,3 @@ -using System; using System.Runtime.InteropServices; using System.Runtime.Versioning; diff --git a/src/ARMeilleure/Signal/TestMethods.cs b/src/ARMeilleure/Signal/TestMethods.cs index 5f9f456bc..684157860 100644 --- a/src/ARMeilleure/Signal/TestMethods.cs +++ b/src/ARMeilleure/Signal/TestMethods.cs @@ -1,6 +1,5 @@ using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; -using System; using System.Runtime.InteropServices; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; diff --git a/src/ARMeilleure/Signal/WindowsPartialUnmapHandler.cs b/src/ARMeilleure/Signal/WindowsPartialUnmapHandler.cs index 7aa3e4788..0df2f41cd 100644 --- a/src/ARMeilleure/Signal/WindowsPartialUnmapHandler.cs +++ b/src/ARMeilleure/Signal/WindowsPartialUnmapHandler.cs @@ -1,7 +1,6 @@ using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; using Ryujinx.Common.Memory.PartialUnmaps; -using System; using System.Runtime.InteropServices; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; diff --git a/src/ARMeilleure/State/ExecutionContext.cs b/src/ARMeilleure/State/ExecutionContext.cs index 314b06b13..6996ec221 100644 --- a/src/ARMeilleure/State/ExecutionContext.cs +++ b/src/ARMeilleure/State/ExecutionContext.cs @@ -1,5 +1,4 @@ using ARMeilleure.Memory; -using System; namespace ARMeilleure.State { diff --git a/src/ARMeilleure/Translation/ArmEmitterContext.cs b/src/ARMeilleure/Translation/ArmEmitterContext.cs index 5d09783ff..196120e92 100644 --- a/src/ARMeilleure/Translation/ArmEmitterContext.cs +++ b/src/ARMeilleure/Translation/ArmEmitterContext.cs @@ -6,7 +6,6 @@ using ARMeilleure.Instructions; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Memory; using ARMeilleure.State; -using System; using System.Collections.Generic; using System.Reflection; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; diff --git a/src/ARMeilleure/Translation/Cache/JitCacheInvalidation.cs b/src/ARMeilleure/Translation/Cache/JitCacheInvalidation.cs index e24f5e864..02e27b941 100644 --- a/src/ARMeilleure/Translation/Cache/JitCacheInvalidation.cs +++ b/src/ARMeilleure/Translation/Cache/JitCacheInvalidation.cs @@ -1,5 +1,4 @@ using ARMeilleure.Memory; -using System; using System.Runtime.InteropServices; namespace ARMeilleure.Translation.Cache diff --git a/src/ARMeilleure/Translation/DelegateInfo.cs b/src/ARMeilleure/Translation/DelegateInfo.cs index 64ee7bc9c..c27dbd6b4 100644 --- a/src/ARMeilleure/Translation/DelegateInfo.cs +++ b/src/ARMeilleure/Translation/DelegateInfo.cs @@ -1,5 +1,3 @@ -using System; - namespace ARMeilleure.Translation { class DelegateInfo diff --git a/src/ARMeilleure/Translation/DispatcherFunction.cs b/src/ARMeilleure/Translation/DispatcherFunction.cs index f8b9dc31e..db5e27344 100644 --- a/src/ARMeilleure/Translation/DispatcherFunction.cs +++ b/src/ARMeilleure/Translation/DispatcherFunction.cs @@ -1,5 +1,3 @@ -using System; - namespace ARMeilleure.Translation { delegate void DispatcherFunction(nint nativeContext, ulong startAddress); diff --git a/src/ARMeilleure/Translation/GuestFunction.cs b/src/ARMeilleure/Translation/GuestFunction.cs index 5c7c733f9..b02d260df 100644 --- a/src/ARMeilleure/Translation/GuestFunction.cs +++ b/src/ARMeilleure/Translation/GuestFunction.cs @@ -1,5 +1,3 @@ -using System; - namespace ARMeilleure.Translation { delegate ulong GuestFunction(nint nativeContextPtr); diff --git a/src/ARMeilleure/Translation/TranslatedFunction.cs b/src/ARMeilleure/Translation/TranslatedFunction.cs index 3d7ae9ffe..181cc5578 100644 --- a/src/ARMeilleure/Translation/TranslatedFunction.cs +++ b/src/ARMeilleure/Translation/TranslatedFunction.cs @@ -1,5 +1,4 @@ using ARMeilleure.Common; -using System; namespace ARMeilleure.Translation { diff --git a/src/ARMeilleure/Translation/Translator.cs b/src/ARMeilleure/Translation/Translator.cs index a50702add..14c80f24b 100644 --- a/src/ARMeilleure/Translation/Translator.cs +++ b/src/ARMeilleure/Translation/Translator.cs @@ -5,7 +5,6 @@ using ARMeilleure.Diagnostics; using ARMeilleure.Instructions; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Memory; -using ARMeilleure.Signal; using ARMeilleure.State; using ARMeilleure.Translation.Cache; using ARMeilleure.Translation.PTC; diff --git a/src/ARMeilleure/Translation/TranslatorStubs.cs b/src/ARMeilleure/Translation/TranslatorStubs.cs index f719dba31..458a42434 100644 --- a/src/ARMeilleure/Translation/TranslatorStubs.cs +++ b/src/ARMeilleure/Translation/TranslatorStubs.cs @@ -4,7 +4,6 @@ using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; using ARMeilleure.Translation.Cache; using System; -using System.Reflection; using System.Runtime.InteropServices; using static ARMeilleure.IntermediateRepresentation.Operand.Factory; diff --git a/src/Ryujinx.Audio.Backends.SDL2/SDL2HardwareDeviceSession.cs b/src/Ryujinx.Audio.Backends.SDL2/SDL2HardwareDeviceSession.cs index 51cd43c55..9170b73c7 100644 --- a/src/Ryujinx.Audio.Backends.SDL2/SDL2HardwareDeviceSession.cs +++ b/src/Ryujinx.Audio.Backends.SDL2/SDL2HardwareDeviceSession.cs @@ -4,7 +4,6 @@ using Ryujinx.Common.Logging; using Ryujinx.Common.Memory; using Ryujinx.Memory; using System; -using System.Buffers; using System.Collections.Concurrent; using System.Threading; diff --git a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIo.cs b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIo.cs index 9decd79fc..6a12e8c0c 100644 --- a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIo.cs +++ b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIo.cs @@ -1,5 +1,4 @@ using Ryujinx.Common.Memory; -using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceContext.cs b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceContext.cs index efea52b35..7c782bd76 100644 --- a/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceContext.cs +++ b/src/Ryujinx.Audio.Backends.SoundIo/Native/SoundIoDeviceContext.cs @@ -1,4 +1,3 @@ -using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using static Ryujinx.Audio.Backends.SoundIo.Native.SoundIo; diff --git a/src/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceSession.cs b/src/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceSession.cs index e9cc6a8e1..1540cd0e3 100644 --- a/src/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceSession.cs +++ b/src/Ryujinx.Audio.Backends.SoundIo/SoundIoHardwareDeviceSession.cs @@ -4,7 +4,6 @@ using Ryujinx.Audio.Common; using Ryujinx.Common.Memory; using Ryujinx.Memory; using System; -using System.Buffers; using System.Collections.Concurrent; using System.Runtime.CompilerServices; using System.Threading; diff --git a/src/Ryujinx.Audio/Backends/Common/DynamicRingBuffer.cs b/src/Ryujinx.Audio/Backends/Common/DynamicRingBuffer.cs index 6f31755a3..a06ab21a7 100644 --- a/src/Ryujinx.Audio/Backends/Common/DynamicRingBuffer.cs +++ b/src/Ryujinx.Audio/Backends/Common/DynamicRingBuffer.cs @@ -1,7 +1,6 @@ using Ryujinx.Common; using Ryujinx.Common.Memory; using System; -using System.Buffers; using System.Threading; namespace Ryujinx.Audio.Backends.Common diff --git a/src/Ryujinx.Audio/Renderer/Server/MemoryPool/MemoryPoolState.cs b/src/Ryujinx.Audio/Renderer/Server/MemoryPool/MemoryPoolState.cs index d0133622a..50153af37 100644 --- a/src/Ryujinx.Audio/Renderer/Server/MemoryPool/MemoryPoolState.cs +++ b/src/Ryujinx.Audio/Renderer/Server/MemoryPool/MemoryPoolState.cs @@ -1,4 +1,3 @@ -using System; using System.Runtime.InteropServices; using CpuAddress = System.UInt64; using DspAddress = System.UInt64; diff --git a/src/Ryujinx.Common/Configuration/VSyncMode.cs b/src/Ryujinx.Common/Configuration/VSyncMode.cs index ca93b5e1c..e0bf2591f 100644 --- a/src/Ryujinx.Common/Configuration/VSyncMode.cs +++ b/src/Ryujinx.Common/Configuration/VSyncMode.cs @@ -6,4 +6,16 @@ namespace Ryujinx.Common.Configuration Unbounded, Custom } + + public static class VSyncModeExtensions + { + public static VSyncMode Next(this VSyncMode vsync, bool customEnabled = false) => + vsync switch + { + VSyncMode.Switch => customEnabled ? VSyncMode.Custom : VSyncMode.Unbounded, + VSyncMode.Unbounded => VSyncMode.Switch, + VSyncMode.Custom => VSyncMode.Unbounded, + _ => VSyncMode.Switch + }; + } } diff --git a/src/Ryujinx.Common/Helpers/FileAssociationHelper.cs b/src/Ryujinx.Common/Helpers/FileAssociationHelper.cs index 7ed5e869a..6e14a796e 100644 --- a/src/Ryujinx.Common/Helpers/FileAssociationHelper.cs +++ b/src/Ryujinx.Common/Helpers/FileAssociationHelper.cs @@ -1,5 +1,4 @@ using Microsoft.Win32; -using Ryujinx.Common; using Ryujinx.Common.Logging; using System; using System.Diagnostics; diff --git a/src/Ryujinx.Common/Helpers/ObjectiveC.cs b/src/Ryujinx.Common/Helpers/ObjectiveC.cs index d8e02f54d..4c2481f6e 100644 --- a/src/Ryujinx.Common/Helpers/ObjectiveC.cs +++ b/src/Ryujinx.Common/Helpers/ObjectiveC.cs @@ -1,4 +1,3 @@ -using System; using System.Runtime.InteropServices; using System.Runtime.Versioning; diff --git a/src/Ryujinx.Common/Helpers/Patterns.cs b/src/Ryujinx.Common/Helpers/Patterns.cs new file mode 100644 index 000000000..84cc1353a --- /dev/null +++ b/src/Ryujinx.Common/Helpers/Patterns.cs @@ -0,0 +1,118 @@ +using System.Text.RegularExpressions; + +namespace Ryujinx.Common.Helper +{ + public static partial class Patterns + { + #region Accessors + + public static readonly Regex Numeric = NumericRegex(); + + public static readonly Regex AmdGcn = AmdGcnRegex(); + public static readonly Regex NvidiaConsumerClass = NvidiaConsumerClassRegex(); + + public static readonly Regex DomainLp1Ns = DomainLp1NsRegex(); + public static readonly Regex DomainLp1Lp1Npln = DomainLp1Lp1NplnRegex(); + public static readonly Regex DomainLp1Znc = DomainLp1ZncRegex(); + public static readonly Regex DomainSbApi = DomainSbApiRegex(); + public static readonly Regex DomainSbAccounts = DomainSbAccountsRegex(); + public static readonly Regex DomainAccounts = DomainAccountsRegex(); + + public static readonly Regex Module = ModuleRegex(); + public static readonly Regex FsSdk = FsSdkRegex(); + public static readonly Regex SdkMw = SdkMwRegex(); + + // ReSharper disable once InconsistentNaming + public static readonly Regex CJK = CJKRegex(); + + public static readonly Regex LdnPassphrase = LdnPassphraseRegex(); + + public static readonly Regex CleanText = CleanTextRegex(); + + #endregion + + #region Generated pattern stubs + + #region Numeric validation + + [GeneratedRegex("[0-9]|.")] + internal static partial Regex NumericRegex(); + + #endregion + + #region GPU names + + [GeneratedRegex( + "Radeon (((HD|R(5|7|9|X)) )?((M?[2-6]\\d{2}(\\D|$))|([7-8]\\d{3}(\\D|$))|Fury|Nano))|(Pro Duo)")] + internal static partial Regex AmdGcnRegex(); + + [GeneratedRegex("NVIDIA GeForce (R|G)?TX? (\\d{3}\\d?)M?")] + internal static partial Regex NvidiaConsumerClassRegex(); + + #endregion + + #region DNS blocking + + public static readonly Regex[] BlockedHosts = + [ + DomainLp1Ns, + DomainLp1Lp1Npln, + DomainLp1Znc, + DomainSbApi, + DomainSbAccounts, + DomainAccounts + ]; + + const RegexOptions DnsRegexOpts = + RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture; + + [GeneratedRegex(@"^(.*)\-lp1\.(n|s)\.n\.srv\.nintendo\.net$", DnsRegexOpts)] + internal static partial Regex DomainLp1NsRegex(); + + [GeneratedRegex(@"^(.*)\-lp1\.lp1\.t\.npln\.srv\.nintendo\.net$", DnsRegexOpts)] + internal static partial Regex DomainLp1Lp1NplnRegex(); + + [GeneratedRegex(@"^(.*)\-lp1\.(znc|p)\.srv\.nintendo\.net$", DnsRegexOpts)] + internal static partial Regex DomainLp1ZncRegex(); + + [GeneratedRegex(@"^(.*)\-sb\-api\.accounts\.nintendo\.com$", DnsRegexOpts)] + internal static partial Regex DomainSbApiRegex(); + + [GeneratedRegex(@"^(.*)\-sb\.accounts\.nintendo\.com$", DnsRegexOpts)] + internal static partial Regex DomainSbAccountsRegex(); + + [GeneratedRegex(@"^accounts\.nintendo\.com$", DnsRegexOpts)] + internal static partial Regex DomainAccountsRegex(); + + #endregion + + #region Executable information + + [GeneratedRegex(@"[a-z]:[\\/][ -~]{5,}\.nss", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)] + internal static partial Regex ModuleRegex(); + + [GeneratedRegex(@"sdk_version: ([0-9.]*)")] + internal static partial Regex FsSdkRegex(); + + [GeneratedRegex(@"SDK MW[ -~]*")] + internal static partial Regex SdkMwRegex(); + + #endregion + + #region CJK + + [GeneratedRegex( + "\\p{IsHangulJamo}|\\p{IsCJKRadicalsSupplement}|\\p{IsCJKSymbolsandPunctuation}|\\p{IsEnclosedCJKLettersandMonths}|\\p{IsCJKCompatibility}|\\p{IsCJKUnifiedIdeographsExtensionA}|\\p{IsCJKUnifiedIdeographs}|\\p{IsHangulSyllables}|\\p{IsCJKCompatibilityForms}")] + private static partial Regex CJKRegex(); + + #endregion + + [GeneratedRegex("Ryujinx-[0-9a-f]{8}")] + private static partial Regex LdnPassphraseRegex(); + + [GeneratedRegex(@"[^\u0000\u0009\u000A\u000D\u0020-\uFFFF]..")] + private static partial Regex CleanTextRegex(); + + #endregion + } +} diff --git a/src/Ryujinx.Common/Helpers/RefEvent.cs b/src/Ryujinx.Common/Helpers/RefEvent.cs new file mode 100644 index 000000000..f339dfb7c --- /dev/null +++ b/src/Ryujinx.Common/Helpers/RefEvent.cs @@ -0,0 +1,58 @@ +using Gommon; +using System.Collections.Generic; +using System.Threading; + +namespace Ryujinx.Common.Helper +{ + public class RefEvent + { + public delegate void Handler(ref T arg); + + private readonly Lock _subLock = new(); + private readonly List _subscriptions = []; + + public bool HasSubscribers + { + get + { + lock (_subLock) + return _subscriptions.Count != 0; + } + } + + public IReadOnlyList Subscriptions + { + get + { + lock (_subLock) + return _subscriptions; + } + } + + public void Add(Handler subscriber) + { + Guard.Require(subscriber, nameof(subscriber)); + lock (_subLock) + _subscriptions.Add(subscriber); + } + + public void Remove(Handler subscriber) + { + Guard.Require(subscriber, nameof(subscriber)); + lock (_subLock) + _subscriptions.Remove(subscriber); + } + + public void Clear() + { + lock (_subLock) + _subscriptions.Clear(); + } + + public void Call(ref T arg) + { + foreach (Handler subscription in Subscriptions) + subscription(ref arg); + } + } +} diff --git a/src/Ryujinx.Common/Helpers/RunningPlatform.cs b/src/Ryujinx.Common/Helpers/RunningPlatform.cs index 61f5bd614..8d85c4a3c 100644 --- a/src/Ryujinx.Common/Helpers/RunningPlatform.cs +++ b/src/Ryujinx.Common/Helpers/RunningPlatform.cs @@ -10,14 +10,18 @@ namespace Ryujinx.Common.Helper public static bool IsMacOS => OperatingSystem.IsMacOS(); public static bool IsWindows => OperatingSystem.IsWindows(); public static bool IsLinux => OperatingSystem.IsLinux(); + + public static bool IsArm => RuntimeInformation.OSArchitecture is Architecture.Arm64; + + public static bool IsX64 => RuntimeInformation.OSArchitecture is Architecture.X64; - public static bool IsIntelMac => IsMacOS && RuntimeInformation.OSArchitecture is Architecture.X64; - public static bool IsArmMac => IsMacOS && RuntimeInformation.OSArchitecture is Architecture.Arm64; + public static bool IsIntelMac => IsMacOS && IsX64; + public static bool IsArmMac => IsMacOS && IsArm; - public static bool IsX64Windows => IsWindows && (RuntimeInformation.OSArchitecture is Architecture.X64); - public static bool IsArmWindows => IsWindows && (RuntimeInformation.OSArchitecture is Architecture.Arm64); + public static bool IsX64Windows => IsWindows && IsX64; + public static bool IsArmWindows => IsWindows && IsArm; - public static bool IsX64Linux => IsLinux && (RuntimeInformation.OSArchitecture is Architecture.X64); - public static bool IsArmLinux => IsLinux && (RuntimeInformation.OSArchitecture is Architecture.Arm64); + public static bool IsX64Linux => IsLinux && IsX64; + public static bool IsArmLinux => IsLinux && IsArmMac; } } diff --git a/src/Ryujinx.Common/TitleIDs.cs b/src/Ryujinx.Common/TitleIDs.cs index 72262c6a0..42322c8a2 100644 --- a/src/Ryujinx.Common/TitleIDs.cs +++ b/src/Ryujinx.Common/TitleIDs.cs @@ -3,7 +3,6 @@ using Ryujinx.Common.Configuration; using Ryujinx.Common.Helper; using System; using System.Linq; -using System.Runtime.InteropServices; namespace Ryujinx.Common { @@ -30,10 +29,11 @@ namespace Ryujinx.Common public static readonly string[] GreatMetalTitles = [ - "010076f0049a2000", // Bayonetta + "01009b500007c000", // ARMS "0100a5c00d162000", // Cuphead "010023800d64a000", // Deltarune "01003a30012c0000", // LEGO City Undercover + "010048701995e000", // Luigi's Manion 2 HD "010028600EBDA000", // Mario 3D World "0100152000022000", // Mario Kart 8 Deluxe "010075a016a3a000", // Persona 4 Arena Ultimax @@ -47,11 +47,16 @@ namespace Ryujinx.Common "01006f8002326000", // Animal Crossings: New Horizons "01009bf0072d4000", // Captain Toad: Treasure Tracker "01009510001ca000", // Fast RMX - "01005CA01580E000", // Persona 5 Royale + "01005CA01580E000", // Persona 5 Royal + "0100b880154fc000", // Persona 5 The Royal (Japan) + "010015100b514000", // Super Mario Bros. Wonder "0100000000010000", // Super Mario Odyssey - //Isaac claims it has a issue in level 2, but I am not able to replicate it on my M3. More testing would be appreciated: - "010015100b514000", // Super Mario Bros. Wonder + // Further testing is appreciated, I did not test the entire game: + "01007300020fa000", // Astral Chain + "010076f0049a2000", // Bayonetta + "0100cf5010fec000", // Bayonetta Origins: Cereza and the Lost Demon + "0100f4300bf2c000", // New Pokemon Snap ]; public static string GetDiscordGameAsset(string titleId) diff --git a/src/Ryujinx.Common/Utilities/Rainbow.cs b/src/Ryujinx.Common/Utilities/Rainbow.cs index a3db94925..eb1c187c4 100644 --- a/src/Ryujinx.Common/Utilities/Rainbow.cs +++ b/src/Ryujinx.Common/Utilities/Rainbow.cs @@ -1,4 +1,5 @@ using Gommon; +using Ryujinx.Common.Helper; using System; using System.Drawing; using System.Threading; @@ -55,7 +56,7 @@ namespace Ryujinx.Common.Utilities { _color = HsbToRgb((_color.GetHue() + Speed) / 360); - _updatedHandler.Call(_color.ToArgb()); + _updatedHandler.Call(ref _color); } } @@ -67,13 +68,13 @@ namespace Ryujinx.Common.Utilities _color = Color.Blue; } - public static event Action Updated + public static event RefEvent.Handler Updated { add => _updatedHandler.Add(value); remove => _updatedHandler.Remove(value); } - private static readonly Event _updatedHandler = new(); + private static readonly RefEvent _updatedHandler = new(); private static Color HsbToRgb(float hue, float saturation = 1, float brightness = 1) { diff --git a/src/Ryujinx.Cpu/AppleHv/HvExecutionContextVcpu.cs b/src/Ryujinx.Cpu/AppleHv/HvExecutionContextVcpu.cs index 9d459d062..1949cabdf 100644 --- a/src/Ryujinx.Cpu/AppleHv/HvExecutionContextVcpu.cs +++ b/src/Ryujinx.Cpu/AppleHv/HvExecutionContextVcpu.cs @@ -1,6 +1,5 @@ using ARMeilleure.State; using Ryujinx.Memory; -using System; using System.Runtime.InteropServices; using System.Runtime.Versioning; diff --git a/src/Ryujinx.Cpu/AppleHv/HvMemoryManager.cs b/src/Ryujinx.Cpu/AppleHv/HvMemoryManager.cs index 28c78074d..decb0e4e3 100644 --- a/src/Ryujinx.Cpu/AppleHv/HvMemoryManager.cs +++ b/src/Ryujinx.Cpu/AppleHv/HvMemoryManager.cs @@ -5,7 +5,6 @@ using Ryujinx.Memory.Tracking; using System; using System.Buffers; using System.Collections.Generic; -using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.Versioning; diff --git a/src/Ryujinx.Cpu/AppleHv/HvVm.cs b/src/Ryujinx.Cpu/AppleHv/HvVm.cs index dc115f515..6ad44621b 100644 --- a/src/Ryujinx.Cpu/AppleHv/HvVm.cs +++ b/src/Ryujinx.Cpu/AppleHv/HvVm.cs @@ -1,5 +1,4 @@ using Ryujinx.Memory; -using System; using System.Runtime.Versioning; using System.Threading; diff --git a/src/Ryujinx.Cpu/Jit/JitCpuContext.cs b/src/Ryujinx.Cpu/Jit/JitCpuContext.cs index 0793f382d..a29def8e8 100644 --- a/src/Ryujinx.Cpu/Jit/JitCpuContext.cs +++ b/src/Ryujinx.Cpu/Jit/JitCpuContext.cs @@ -2,7 +2,6 @@ using ARMeilleure.Common; using ARMeilleure.Memory; using ARMeilleure.Translation; using Ryujinx.Cpu.Signal; -using Ryujinx.Memory; namespace Ryujinx.Cpu.Jit { diff --git a/src/Ryujinx.Cpu/Jit/MemoryManager.cs b/src/Ryujinx.Cpu/Jit/MemoryManager.cs index 2635a2c7d..9e5d29cca 100644 --- a/src/Ryujinx.Cpu/Jit/MemoryManager.cs +++ b/src/Ryujinx.Cpu/Jit/MemoryManager.cs @@ -5,7 +5,6 @@ using Ryujinx.Memory.Tracking; using System; using System.Buffers; using System.Collections.Generic; -using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading; diff --git a/src/Ryujinx.Cpu/Jit/MemoryManagerHostTracked.cs b/src/Ryujinx.Cpu/Jit/MemoryManagerHostTracked.cs index c2f7d3f4b..9ae4ca5a9 100644 --- a/src/Ryujinx.Cpu/Jit/MemoryManagerHostTracked.cs +++ b/src/Ryujinx.Cpu/Jit/MemoryManagerHostTracked.cs @@ -8,7 +8,6 @@ using Ryujinx.Memory.Tracking; using System; using System.Buffers; using System.Collections.Generic; -using System.Linq; using System.Runtime.CompilerServices; namespace Ryujinx.Cpu.Jit diff --git a/src/Ryujinx.Cpu/LightningJit/AarchCompiler.cs b/src/Ryujinx.Cpu/LightningJit/AarchCompiler.cs index 89e1499c0..68dff624c 100644 --- a/src/Ryujinx.Cpu/LightningJit/AarchCompiler.cs +++ b/src/Ryujinx.Cpu/LightningJit/AarchCompiler.cs @@ -3,7 +3,6 @@ using ARMeilleure.Memory; using Ryujinx.Cpu.LightningJit.Arm32; using Ryujinx.Cpu.LightningJit.Arm64; using Ryujinx.Cpu.LightningJit.State; -using System; using System.Runtime.InteropServices; namespace Ryujinx.Cpu.LightningJit diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/Compiler.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/Compiler.cs index 0d56f28c9..3121d4f95 100644 --- a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/Compiler.cs +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/Compiler.cs @@ -2,7 +2,6 @@ using ARMeilleure.Common; using ARMeilleure.Memory; using Ryujinx.Cpu.LightningJit.CodeGen; using Ryujinx.Cpu.LightningJit.CodeGen.Arm64; -using System; using System.Collections.Generic; using System.Diagnostics; using System.Numerics; diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpCompare.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpCompare.cs index f5f306099..c1b51750f 100644 --- a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpCompare.cs +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpCompare.cs @@ -1,5 +1,4 @@ using Ryujinx.Cpu.LightningJit.CodeGen; -using System; using System.Diagnostics; namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 diff --git a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpMove.cs b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpMove.cs index 5c1eefacf..2be82ff2a 100644 --- a/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpMove.cs +++ b/src/Ryujinx.Cpu/LightningJit/Arm32/Target/Arm64/InstEmitVfpMove.cs @@ -1,5 +1,3 @@ -using Ryujinx.Cpu.LightningJit.CodeGen; - namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64 { static class InstEmitVfpMove diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/SysUtils.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/SysUtils.cs index 69689a391..a61f35280 100644 --- a/src/Ryujinx.Cpu/LightningJit/Arm64/SysUtils.cs +++ b/src/Ryujinx.Cpu/LightningJit/Arm64/SysUtils.cs @@ -1,5 +1,3 @@ -using System.Diagnostics; - namespace Ryujinx.Cpu.LightningJit.Arm64 { static class SysUtils diff --git a/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/Compiler.cs b/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/Compiler.cs index 2900cbda4..1e087591c 100644 --- a/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/Compiler.cs +++ b/src/Ryujinx.Cpu/LightningJit/Arm64/Target/Arm64/Compiler.cs @@ -3,7 +3,6 @@ using ARMeilleure.Memory; using Ryujinx.Cpu.LightningJit.CodeGen; using Ryujinx.Cpu.LightningJit.CodeGen.Arm64; using Ryujinx.Cpu.LightningJit.Graph; -using System; using System.Collections.Generic; using System.Diagnostics; using System.Numerics; diff --git a/src/Ryujinx.Cpu/LightningJit/Cache/JitCacheInvalidation.cs b/src/Ryujinx.Cpu/LightningJit/Cache/JitCacheInvalidation.cs index e851327d4..ae71aa1d3 100644 --- a/src/Ryujinx.Cpu/LightningJit/Cache/JitCacheInvalidation.cs +++ b/src/Ryujinx.Cpu/LightningJit/Cache/JitCacheInvalidation.cs @@ -1,5 +1,4 @@ using ARMeilleure.Memory; -using System; using System.Runtime.InteropServices; namespace Ryujinx.Cpu.LightningJit.Cache diff --git a/src/Ryujinx.Cpu/LightningJit/Cache/JitSupportDarwin.cs b/src/Ryujinx.Cpu/LightningJit/Cache/JitSupportDarwin.cs index ed02a9c28..e0de1e7e0 100644 --- a/src/Ryujinx.Cpu/LightningJit/Cache/JitSupportDarwin.cs +++ b/src/Ryujinx.Cpu/LightningJit/Cache/JitSupportDarwin.cs @@ -1,4 +1,3 @@ -using System; using System.Runtime.InteropServices; using System.Runtime.Versioning; diff --git a/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/StackWalker.cs b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/StackWalker.cs index 1432c4598..491132408 100644 --- a/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/StackWalker.cs +++ b/src/Ryujinx.Cpu/LightningJit/CodeGen/Arm64/StackWalker.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Cpu/LightningJit/IStackWalker.cs b/src/Ryujinx.Cpu/LightningJit/IStackWalker.cs index 375c09d26..f5bbc65d3 100644 --- a/src/Ryujinx.Cpu/LightningJit/IStackWalker.cs +++ b/src/Ryujinx.Cpu/LightningJit/IStackWalker.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; namespace Ryujinx.Cpu.LightningJit diff --git a/src/Ryujinx.Cpu/LightningJit/TranslatedFunction.cs b/src/Ryujinx.Cpu/LightningJit/TranslatedFunction.cs index df0f52b8c..70cdd0bfe 100644 --- a/src/Ryujinx.Cpu/LightningJit/TranslatedFunction.cs +++ b/src/Ryujinx.Cpu/LightningJit/TranslatedFunction.cs @@ -1,5 +1,3 @@ -using System; - namespace Ryujinx.Cpu.LightningJit { class TranslatedFunction diff --git a/src/Ryujinx.Cpu/LightningJit/Translator.cs b/src/Ryujinx.Cpu/LightningJit/Translator.cs index cb3957490..5f3fe8783 100644 --- a/src/Ryujinx.Cpu/LightningJit/Translator.cs +++ b/src/Ryujinx.Cpu/LightningJit/Translator.cs @@ -5,7 +5,6 @@ using Ryujinx.Cpu.LightningJit.Cache; using Ryujinx.Cpu.LightningJit.CodeGen.Arm64; using Ryujinx.Cpu.LightningJit.State; using Ryujinx.Cpu.Signal; -using Ryujinx.Memory; using System; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/src/Ryujinx.Cpu/Signal/WindowsSignalHandlerRegistration.cs b/src/Ryujinx.Cpu/Signal/WindowsSignalHandlerRegistration.cs index 7ac15b816..8afaeef0f 100644 --- a/src/Ryujinx.Cpu/Signal/WindowsSignalHandlerRegistration.cs +++ b/src/Ryujinx.Cpu/Signal/WindowsSignalHandlerRegistration.cs @@ -1,4 +1,3 @@ -using System; using System.Runtime.InteropServices; namespace Ryujinx.Cpu.Signal diff --git a/src/Ryujinx.Graphics.Device/ISynchronizationManager.cs b/src/Ryujinx.Graphics.Device/ISynchronizationManager.cs index 2a8d1d9b7..5c2b6a2e3 100644 --- a/src/Ryujinx.Graphics.Device/ISynchronizationManager.cs +++ b/src/Ryujinx.Graphics.Device/ISynchronizationManager.cs @@ -1,6 +1,4 @@ -using Ryujinx.Common.Logging; using System; -using System.Threading; namespace Ryujinx.Graphics.Device { diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Threed/Blender/AdvancedBlendPreGenTable.cs b/src/Ryujinx.Graphics.Gpu/Engine/Threed/Blender/AdvancedBlendPreGenTable.cs index c2276480b..5d420a140 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Threed/Blender/AdvancedBlendPreGenTable.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Threed/Blender/AdvancedBlendPreGenTable.cs @@ -1,6 +1,5 @@ using Ryujinx.Common; using Ryujinx.Graphics.GAL; -using System; using System.Collections.Generic; namespace Ryujinx.Graphics.Gpu.Engine.Threed.Blender diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdateTracker.cs b/src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdateTracker.cs index d1a1cc35c..9383d3a3f 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdateTracker.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdateTracker.cs @@ -1,4 +1,3 @@ -using Ryujinx.Graphics.Device; using System; using System.Collections.Generic; using System.Diagnostics; diff --git a/src/Ryujinx.Graphics.Gpu/Image/TextureBindingsArrayCache.cs b/src/Ryujinx.Graphics.Gpu/Image/TextureBindingsArrayCache.cs index 17ed57d96..fc3b64c03 100644 --- a/src/Ryujinx.Graphics.Gpu/Image/TextureBindingsArrayCache.cs +++ b/src/Ryujinx.Graphics.Gpu/Image/TextureBindingsArrayCache.cs @@ -4,7 +4,6 @@ using Ryujinx.Graphics.Gpu.Memory; using Ryujinx.Graphics.Shader; using System; using System.Collections.Generic; -using System.Linq; using System.Runtime.InteropServices; namespace Ryujinx.Graphics.Gpu.Image diff --git a/src/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs b/src/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs index 0bd715d89..6efb7f334 100644 --- a/src/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs +++ b/src/Ryujinx.Graphics.Gpu/Memory/MemoryManager.cs @@ -1,5 +1,4 @@ using Ryujinx.Common.Memory; -using Ryujinx.Graphics.Gpu.Image; using Ryujinx.Memory; using Ryujinx.Memory.Range; using System; diff --git a/src/Ryujinx.Graphics.Gpu/Memory/PhysicalMemory.cs b/src/Ryujinx.Graphics.Gpu/Memory/PhysicalMemory.cs index d9dd7f1d9..8a78b99e0 100644 --- a/src/Ryujinx.Graphics.Gpu/Memory/PhysicalMemory.cs +++ b/src/Ryujinx.Graphics.Gpu/Memory/PhysicalMemory.cs @@ -7,7 +7,6 @@ using Ryujinx.Memory; using Ryujinx.Memory.Range; using Ryujinx.Memory.Tracking; using System; -using System.Buffers; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Graphics.Gpu/Memory/SupportBufferUpdater.cs b/src/Ryujinx.Graphics.Gpu/Memory/SupportBufferUpdater.cs index beaad0579..b6ece6f83 100644 --- a/src/Ryujinx.Graphics.Gpu/Memory/SupportBufferUpdater.cs +++ b/src/Ryujinx.Graphics.Gpu/Memory/SupportBufferUpdater.cs @@ -1,6 +1,5 @@ using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Shader; -using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Graphics.Gpu/Shader/CachedShaderBindings.cs b/src/Ryujinx.Graphics.Gpu/Shader/CachedShaderBindings.cs index ef314501d..4683a5d0c 100644 --- a/src/Ryujinx.Graphics.Gpu/Shader/CachedShaderBindings.cs +++ b/src/Ryujinx.Graphics.Gpu/Shader/CachedShaderBindings.cs @@ -2,7 +2,6 @@ using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Gpu.Engine; using Ryujinx.Graphics.Gpu.Image; using Ryujinx.Graphics.Shader; -using System; using System.Linq; namespace Ryujinx.Graphics.Gpu.Shader diff --git a/src/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs b/src/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs index e7e0ba154..476ae3d82 100644 --- a/src/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs +++ b/src/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs @@ -1,4 +1,3 @@ -using Ryujinx.Common; using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; using Ryujinx.Graphics.GAL; diff --git a/src/Ryujinx.Graphics.Gpu/Synchronization/SynchronizationManager.cs b/src/Ryujinx.Graphics.Gpu/Synchronization/SynchronizationManager.cs index b68a64a47..d51b0ef60 100644 --- a/src/Ryujinx.Graphics.Gpu/Synchronization/SynchronizationManager.cs +++ b/src/Ryujinx.Graphics.Gpu/Synchronization/SynchronizationManager.cs @@ -87,7 +87,7 @@ namespace Ryujinx.Graphics.Gpu.Synchronization } using ManualResetEvent waitEvent = new(false); - SyncpointWaiterHandle info = _syncpoints[id].RegisterCallback(threshold, (x) => waitEvent.Set()); + SyncpointWaiterHandle info = _syncpoints[id].RegisterCallback(threshold, _ => waitEvent.Set()); if (info == null) { @@ -96,7 +96,7 @@ namespace Ryujinx.Graphics.Gpu.Synchronization bool signaled = waitEvent.WaitOne(timeout); - if (!signaled && info != null) + if (!signaled) { Logger.Error?.Print(LogClass.Gpu, $"Wait on syncpoint {id} for threshold {threshold} took more than {timeout.TotalMilliseconds}ms, resuming execution..."); diff --git a/src/Ryujinx.Graphics.Metal/EnumConversion.cs b/src/Ryujinx.Graphics.Metal/EnumConversion.cs index e498546e8..7cfb5cbd4 100644 --- a/src/Ryujinx.Graphics.Metal/EnumConversion.cs +++ b/src/Ryujinx.Graphics.Metal/EnumConversion.cs @@ -1,7 +1,6 @@ using Ryujinx.Common.Logging; using Ryujinx.Graphics.GAL; using SharpMetal.Metal; -using System; using System.Runtime.Versioning; namespace Ryujinx.Graphics.Metal diff --git a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodec.cs b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodec.cs index b5ef710b1..098622b2a 100644 --- a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodec.cs +++ b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodec.cs @@ -1,5 +1,3 @@ -using System; - namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native { struct AVCodec diff --git a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodec501.cs b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodec501.cs index d745e9f04..256ccd0a8 100644 --- a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodec501.cs +++ b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodec501.cs @@ -1,5 +1,3 @@ -using System; - namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native { struct AVCodec501 diff --git a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecContext.cs b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecContext.cs index 1de0a13e4..96c1a0f67 100644 --- a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecContext.cs +++ b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVCodecContext.cs @@ -1,5 +1,4 @@ using Ryujinx.Common.Memory; -using System; namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native { diff --git a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVFrame.cs b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVFrame.cs index 97c30c718..46b1e06a7 100644 --- a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVFrame.cs +++ b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/AVFrame.cs @@ -1,5 +1,4 @@ using Ryujinx.Common.Memory; -using System; namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native { diff --git a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFCodec.cs b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFCodec.cs index 95926298c..09bcc9c31 100644 --- a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFCodec.cs +++ b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFCodec.cs @@ -1,5 +1,3 @@ -using System; - namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native { struct FFCodec where T : struct diff --git a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFCodecLegacy.cs b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFCodecLegacy.cs index 873d2518a..ee0db4730 100644 --- a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFCodecLegacy.cs +++ b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Native/FFCodecLegacy.cs @@ -1,5 +1,3 @@ -using System; - namespace Ryujinx.Graphics.Nvdec.FFmpeg.Native { struct FFCodecLegacy where T : struct diff --git a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Surface.cs b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Surface.cs index c13cfe1aa..023b470f2 100644 --- a/src/Ryujinx.Graphics.Nvdec.FFmpeg/Surface.cs +++ b/src/Ryujinx.Graphics.Nvdec.FFmpeg/Surface.cs @@ -1,6 +1,5 @@ using Ryujinx.Graphics.Nvdec.FFmpeg.Native; using Ryujinx.Graphics.Video; -using System; namespace Ryujinx.Graphics.Nvdec.FFmpeg { diff --git a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/Surface.cs b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/Surface.cs index d9bda185b..6bab536d1 100644 --- a/src/Ryujinx.Graphics.Nvdec.Vp9/Types/Surface.cs +++ b/src/Ryujinx.Graphics.Nvdec.Vp9/Types/Surface.cs @@ -1,6 +1,5 @@ using Ryujinx.Common.Memory; using Ryujinx.Graphics.Video; -using System; using System.Runtime.InteropServices; namespace Ryujinx.Graphics.Nvdec.Vp9.Types diff --git a/src/Ryujinx.Graphics.OpenGL/Effects/AreaScalingFilter.cs b/src/Ryujinx.Graphics.OpenGL/Effects/AreaScalingFilter.cs index 927f4cbfe..c95463e37 100644 --- a/src/Ryujinx.Graphics.OpenGL/Effects/AreaScalingFilter.cs +++ b/src/Ryujinx.Graphics.OpenGL/Effects/AreaScalingFilter.cs @@ -2,7 +2,6 @@ using OpenTK.Graphics.OpenGL; using Ryujinx.Common; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.OpenGL.Image; -using System; using static Ryujinx.Graphics.OpenGL.Effects.ShaderHelper; namespace Ryujinx.Graphics.OpenGL.Effects diff --git a/src/Ryujinx.Graphics.OpenGL/Helper/GLXHelper.cs b/src/Ryujinx.Graphics.OpenGL/Helper/GLXHelper.cs index b722bbf04..d7ca560a1 100644 --- a/src/Ryujinx.Graphics.OpenGL/Helper/GLXHelper.cs +++ b/src/Ryujinx.Graphics.OpenGL/Helper/GLXHelper.cs @@ -1,4 +1,3 @@ -using System; using System.Runtime.InteropServices; using System.Runtime.Versioning; diff --git a/src/Ryujinx.Graphics.OpenGL/Helper/WGLHelper.cs b/src/Ryujinx.Graphics.OpenGL/Helper/WGLHelper.cs index 7072bbd9f..54516c81e 100644 --- a/src/Ryujinx.Graphics.OpenGL/Helper/WGLHelper.cs +++ b/src/Ryujinx.Graphics.OpenGL/Helper/WGLHelper.cs @@ -1,4 +1,3 @@ -using System; using System.Runtime.InteropServices; using System.Runtime.Versioning; diff --git a/src/Ryujinx.Graphics.OpenGL/IOpenGLContext.cs b/src/Ryujinx.Graphics.OpenGL/IOpenGLContext.cs index 525418d74..5443465ea 100644 --- a/src/Ryujinx.Graphics.OpenGL/IOpenGLContext.cs +++ b/src/Ryujinx.Graphics.OpenGL/IOpenGLContext.cs @@ -1,4 +1,3 @@ -using Ryujinx.Graphics.OpenGL.Helper; using System; namespace Ryujinx.Graphics.OpenGL diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Declarations.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Declarations.cs index 081dd516b..a9464834a 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Declarations.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Msl/Declarations.cs @@ -1,5 +1,4 @@ using Ryujinx.Common; -using Ryujinx.Common.Logging; using Ryujinx.Graphics.Shader.IntermediateRepresentation; using Ryujinx.Graphics.Shader.StructuredIr; using Ryujinx.Graphics.Shader.Translation; diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs index 5abbf1fa8..4fe214778 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs @@ -4,7 +4,6 @@ using Ryujinx.Graphics.Shader.Translation; using Spv.Generator; using System; using System.Collections.Generic; -using static Spv.Specification; using Instruction = Spv.Generator.Instruction; namespace Ryujinx.Graphics.Shader.CodeGen.Spirv diff --git a/src/Ryujinx.Graphics.Shader/StructuredIr/AstOptimizer.cs b/src/Ryujinx.Graphics.Shader/StructuredIr/AstOptimizer.cs index 5d46ab498..3f2e4991f 100644 --- a/src/Ryujinx.Graphics.Shader/StructuredIr/AstOptimizer.cs +++ b/src/Ryujinx.Graphics.Shader/StructuredIr/AstOptimizer.cs @@ -1,5 +1,4 @@ using Ryujinx.Graphics.Shader.IntermediateRepresentation; -using Ryujinx.Graphics.Shader.Translation; using System.Collections.Generic; using System.Linq; diff --git a/src/Ryujinx.Graphics.Video/Plane.cs b/src/Ryujinx.Graphics.Video/Plane.cs index 4e4e65b32..338de1644 100644 --- a/src/Ryujinx.Graphics.Video/Plane.cs +++ b/src/Ryujinx.Graphics.Video/Plane.cs @@ -1,5 +1,3 @@ -using System; - namespace Ryujinx.Graphics.Video { public readonly record struct Plane(nint Pointer, int Length); diff --git a/src/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs b/src/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs index 5e3bf39db..406f33304 100644 --- a/src/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs +++ b/src/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs @@ -3,7 +3,6 @@ using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Shader; using Silk.NET.Vulkan; using System; -using System.Buffers; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs index ba8b3e499..191811593 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs @@ -11,7 +11,6 @@ using System.Runtime.InteropServices; using BlendOp = Silk.NET.Vulkan.BlendOp; using Buffer = Silk.NET.Vulkan.Buffer; using CompareOp = Ryujinx.Graphics.GAL.CompareOp; -using Format = Ryujinx.Graphics.GAL.Format; using FrontFace = Ryujinx.Graphics.GAL.FrontFace; using IndexType = Ryujinx.Graphics.GAL.IndexType; using PolygonMode = Ryujinx.Graphics.GAL.PolygonMode; diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineHelperShader.cs b/src/Ryujinx.Graphics.Vulkan/PipelineHelperShader.cs index dfbf19013..b9074dfdb 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineHelperShader.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineHelperShader.cs @@ -1,5 +1,4 @@ using Silk.NET.Vulkan; -using VkFormat = Silk.NET.Vulkan.Format; namespace Ryujinx.Graphics.Vulkan { diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineLayoutFactory.cs b/src/Ryujinx.Graphics.Vulkan/PipelineLayoutFactory.cs index 1cf569290..612a8b25d 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineLayoutFactory.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineLayoutFactory.cs @@ -1,7 +1,5 @@ -using Ryujinx.Common.Memory; using Ryujinx.Graphics.GAL; using Silk.NET.Vulkan; -using System; using System.Collections.ObjectModel; namespace Ryujinx.Graphics.Vulkan diff --git a/src/Ryujinx.Graphics.Vulkan/Queries/CounterQueue.cs b/src/Ryujinx.Graphics.Vulkan/Queries/CounterQueue.cs index 8dd94a42d..24b0e7787 100644 --- a/src/Ryujinx.Graphics.Vulkan/Queries/CounterQueue.cs +++ b/src/Ryujinx.Graphics.Vulkan/Queries/CounterQueue.cs @@ -2,7 +2,6 @@ using Ryujinx.Graphics.GAL; using Silk.NET.Vulkan; using System; using System.Collections.Generic; -using System.Linq; using System.Threading; namespace Ryujinx.Graphics.Vulkan.Queries diff --git a/src/Ryujinx.Graphics.Vulkan/TextureBuffer.cs b/src/Ryujinx.Graphics.Vulkan/TextureBuffer.cs index 073eee2ca..8a2cd2102 100644 --- a/src/Ryujinx.Graphics.Vulkan/TextureBuffer.cs +++ b/src/Ryujinx.Graphics.Vulkan/TextureBuffer.cs @@ -2,8 +2,6 @@ using Ryujinx.Common.Memory; using Ryujinx.Graphics.GAL; using Silk.NET.Vulkan; using System; -using System.Collections.Generic; -using Format = Ryujinx.Graphics.GAL.Format; using VkFormat = Silk.NET.Vulkan.Format; namespace Ryujinx.Graphics.Vulkan diff --git a/src/Ryujinx.Graphics.Vulkan/Vendor.cs b/src/Ryujinx.Graphics.Vulkan/Vendor.cs index 6a2a76a88..87c6407cd 100644 --- a/src/Ryujinx.Graphics.Vulkan/Vendor.cs +++ b/src/Ryujinx.Graphics.Vulkan/Vendor.cs @@ -16,14 +16,8 @@ namespace Ryujinx.Graphics.Vulkan Unknown, } - static partial class VendorUtils + static class VendorUtils { - [GeneratedRegex("Radeon (((HD|R(5|7|9|X)) )?((M?[2-6]\\d{2}(\\D|$))|([7-8]\\d{3}(\\D|$))|Fury|Nano))|(Pro Duo)")] - public static partial Regex AmdGcnRegex(); - - [GeneratedRegex("NVIDIA GeForce (R|G)?TX? (\\d{3}\\d?)M?")] - public static partial Regex NvidiaConsumerClassRegex(); - public static Vendor FromId(uint id) { return id switch diff --git a/src/Ryujinx.Graphics.Vulkan/VulkanException.cs b/src/Ryujinx.Graphics.Vulkan/VulkanException.cs index e203a3a21..5d67ab838 100644 --- a/src/Ryujinx.Graphics.Vulkan/VulkanException.cs +++ b/src/Ryujinx.Graphics.Vulkan/VulkanException.cs @@ -1,6 +1,5 @@ using Silk.NET.Vulkan; using System; -using System.Runtime.Serialization; namespace Ryujinx.Graphics.Vulkan { diff --git a/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs b/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs index 986baf91b..e90606dcf 100644 --- a/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs +++ b/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs @@ -1,5 +1,6 @@ using Gommon; using Ryujinx.Common.Configuration; +using Ryujinx.Common.Helper; using Ryujinx.Common.Logging; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Shader; @@ -375,11 +376,11 @@ namespace Ryujinx.Graphics.Vulkan GpuVersion = $"Vulkan v{ParseStandardVulkanVersion(properties.ApiVersion)}, Driver v{ParseDriverVersion(ref properties)}"; - IsAmdGcn = !IsMoltenVk && Vendor == Vendor.Amd && VendorUtils.AmdGcnRegex().IsMatch(GpuRenderer); + IsAmdGcn = !IsMoltenVk && Vendor == Vendor.Amd && Patterns.AmdGcn.IsMatch(GpuRenderer); if (Vendor == Vendor.Nvidia) { - Match match = VendorUtils.NvidiaConsumerClassRegex().Match(GpuRenderer); + Match match = Patterns.NvidiaConsumerClass.Match(GpuRenderer); if (match != null && int.TryParse(match.Groups[2].Value, out int gpuNumber)) { diff --git a/src/Ryujinx.HLE/Exceptions/ServiceNotImplementedException.cs b/src/Ryujinx.HLE/Exceptions/ServiceNotImplementedException.cs index 17aab8105..23068bf72 100644 --- a/src/Ryujinx.HLE/Exceptions/ServiceNotImplementedException.cs +++ b/src/Ryujinx.HLE/Exceptions/ServiceNotImplementedException.cs @@ -7,7 +7,6 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; -using System.Runtime.Serialization; using System.Text; namespace Ryujinx.HLE.Exceptions diff --git a/src/Ryujinx.HLE/HOS/Applets/AppletManager.cs b/src/Ryujinx.HLE/HOS/Applets/AppletManager.cs index 5895c67bb..5bda957bc 100644 --- a/src/Ryujinx.HLE/HOS/Applets/AppletManager.cs +++ b/src/Ryujinx.HLE/HOS/Applets/AppletManager.cs @@ -4,8 +4,6 @@ using Ryujinx.HLE.HOS.Applets.Cabinet; using Ryujinx.HLE.HOS.Applets.Dummy; using Ryujinx.HLE.HOS.Applets.Error; using Ryujinx.HLE.HOS.Services.Am.AppletAE; -using System; -using System.Collections.Generic; namespace Ryujinx.HLE.HOS.Applets { diff --git a/src/Ryujinx.HLE/HOS/Applets/Dummy/DummyApplet.cs b/src/Ryujinx.HLE/HOS/Applets/Dummy/DummyApplet.cs index 6b16aee7b..a581e1864 100644 --- a/src/Ryujinx.HLE/HOS/Applets/Dummy/DummyApplet.cs +++ b/src/Ryujinx.HLE/HOS/Applets/Dummy/DummyApplet.cs @@ -1,10 +1,8 @@ -using Ryujinx.Common.Logging; using Ryujinx.Common.Memory; -using Ryujinx.HLE.HOS.Applets; using Ryujinx.HLE.HOS.Services.Am.AppletAE; using System; using System.IO; -using System.Runtime.InteropServices; + namespace Ryujinx.HLE.HOS.Applets.Dummy { internal class DummyApplet : IApplet diff --git a/src/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs b/src/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs index 54b5721c1..b41bc60b1 100644 --- a/src/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs +++ b/src/Ryujinx.HLE/HOS/Applets/Error/ErrorApplet.cs @@ -5,6 +5,7 @@ using LibHac.FsSystem; using LibHac.Ncm; using LibHac.Tools.FsSystem; using LibHac.Tools.FsSystem.NcaUtils; +using Ryujinx.Common.Helper; using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Services.Am.AppletAE; using Ryujinx.HLE.HOS.SystemState; @@ -30,9 +31,6 @@ namespace Ryujinx.HLE.HOS.Applets.Error public event EventHandler AppletStateChanged; - [GeneratedRegex(@"[^\u0000\u0009\u000A\u000D\u0020-\uFFFF]..")] - private static partial Regex CleanTextRegex(); - public ErrorApplet(Horizon horizon) { _horizon = horizon; @@ -107,7 +105,7 @@ namespace Ryujinx.HLE.HOS.Applets.Error private static string CleanText(string value) { - return CleanTextRegex().Replace(value, string.Empty).Replace("\0", string.Empty); + return Patterns.CleanText.Replace(value, string.Empty).Replace("\0", string.Empty); } private string GetMessageText(uint module, uint description, string key) diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/CJKCharacterValidation.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/CJKCharacterValidation.cs deleted file mode 100644 index 6134a3cdd..000000000 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/CJKCharacterValidation.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Text.RegularExpressions; - -namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard -{ - public static partial class CJKCharacterValidation - { - public static bool IsCJK(char value) - { - Regex regex = CJKRegex(); - - return regex.IsMatch(value.ToString()); - } - - [GeneratedRegex("\\p{IsHangulJamo}|\\p{IsCJKRadicalsSupplement}|\\p{IsCJKSymbolsandPunctuation}|\\p{IsEnclosedCJKLettersandMonths}|\\p{IsCJKCompatibility}|\\p{IsCJKUnifiedIdeographsExtensionA}|\\p{IsCJKUnifiedIdeographs}|\\p{IsHangulSyllables}|\\p{IsCJKCompatibilityForms}")] - private static partial Regex CJKRegex(); - } -} diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/CharacterValidation.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/CharacterValidation.cs new file mode 100644 index 000000000..5ce8204cb --- /dev/null +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/CharacterValidation.cs @@ -0,0 +1,10 @@ +using Ryujinx.Common.Helper; + +namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard +{ + public static class CharacterValidation + { + public static bool IsNumeric(char value) => Patterns.Numeric.IsMatch(value.ToString()); + public static bool IsCJK(char value) => Patterns.CJK.IsMatch(value.ToString()); + } +} diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/NumericCharacterValidation.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/NumericCharacterValidation.cs deleted file mode 100644 index d72b68eae..000000000 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/NumericCharacterValidation.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Text.RegularExpressions; - -namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard -{ - public static partial class NumericCharacterValidation - { - public static bool IsNumeric(char value) - { - Regex regex = NumericRegex(); - - return regex.IsMatch(value.ToString()); - } - - [GeneratedRegex("[0-9]|.")] - private static partial Regex NumericRegex(); - } -} diff --git a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRendererBase.cs b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRendererBase.cs index 4d4ef8996..11f527285 100644 --- a/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRendererBase.cs +++ b/src/Ryujinx.HLE/HOS/Applets/SoftwareKeyboard/SoftwareKeyboardRendererBase.cs @@ -5,7 +5,6 @@ using System; using System.Diagnostics; using System.IO; using System.Reflection; -using System.Runtime.InteropServices; using System.Threading; namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard diff --git a/src/Ryujinx.HLE/HOS/Kernel/Common/KResourceLimit.cs b/src/Ryujinx.HLE/HOS/Kernel/Common/KResourceLimit.cs index e036f366b..25c663e9a 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/Common/KResourceLimit.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/Common/KResourceLimit.cs @@ -2,7 +2,6 @@ using Ryujinx.Common; using Ryujinx.HLE.HOS.Kernel.Threading; using Ryujinx.Horizon.Common; using System.Collections.Generic; -using System.Threading; namespace Ryujinx.HLE.HOS.Kernel.Common { diff --git a/src/Ryujinx.HLE/HOS/ModLoader.cs b/src/Ryujinx.HLE/HOS/ModLoader.cs index 0f2e09da6..c652024cf 100644 --- a/src/Ryujinx.HLE/HOS/ModLoader.cs +++ b/src/Ryujinx.HLE/HOS/ModLoader.cs @@ -296,7 +296,7 @@ namespace Ryujinx.HLE.HOS AddModsFromDirectory(mods, applicationDir, modMetadata); } - public static void QueryContentsDir(ModCache mods, DirectoryInfo contentsDir, ulong applicationId) + public static void QueryContentsDir(ModCache mods, DirectoryInfo contentsDir, ulong applicationId, ulong[] installedDlcs) { if (!contentsDir.Exists) { @@ -311,6 +311,16 @@ namespace Ryujinx.HLE.HOS { QueryApplicationDir(mods, applicationDir, applicationId); } + + foreach (ulong installedDlcId in installedDlcs) + { + DirectoryInfo dlcModDir = FindApplicationDir(contentsDir, $"{installedDlcId:x16}"); + + if (dlcModDir != null) + { + QueryApplicationDir(mods, dlcModDir, applicationId); + } + } } private static int QueryCheatsDir(ModCache mods, DirectoryInfo cheatsDir) @@ -417,7 +427,7 @@ namespace Ryujinx.HLE.HOS { foreach ((ulong applicationId, ModCache cache) in modCaches) { - QueryContentsDir(cache, searchDir, applicationId); + QueryContentsDir(cache, searchDir, applicationId, Array.Empty()); } return true; diff --git a/src/Ryujinx.HLE/HOS/Services/Mii/Types/Ver3StoreData.cs b/src/Ryujinx.HLE/HOS/Services/Mii/Types/Ver3StoreData.cs index 3930b3312..d3df58215 100644 --- a/src/Ryujinx.HLE/HOS/Services/Mii/Types/Ver3StoreData.cs +++ b/src/Ryujinx.HLE/HOS/Services/Mii/Types/Ver3StoreData.cs @@ -1,5 +1,4 @@ using Ryujinx.Common.Memory; -using Ryujinx.Common.Utilities; using System; using System.Runtime.InteropServices; diff --git a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/VirtualAmiibo.cs b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/VirtualAmiibo.cs index 36a89070d..7e3e4c0a2 100644 --- a/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/VirtualAmiibo.cs +++ b/src/Ryujinx.HLE/HOS/Services/Nfc/Nfp/VirtualAmiibo.cs @@ -7,7 +7,6 @@ using Ryujinx.HLE.HOS.Services.Mii.Types; using Ryujinx.HLE.HOS.Services.Nfc.AmiiboDecryption; using Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager; using System; -using System.Collections.Generic; using System.IO; using System.Linq; diff --git a/src/Ryujinx.HLE/HOS/Services/Sm/IUserInterface.cs b/src/Ryujinx.HLE/HOS/Services/Sm/IUserInterface.cs index 271b8fc84..6d03d8d05 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sm/IUserInterface.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sm/IUserInterface.cs @@ -2,7 +2,6 @@ using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Ipc; using Ryujinx.HLE.HOS.Kernel; using Ryujinx.HLE.HOS.Kernel.Ipc; -using Ryujinx.HLE.HOS.Services.Apm; using Ryujinx.Horizon.Common; using System; using System.Collections.Generic; diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Proxy/DnsBlacklist.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Proxy/DnsBlacklist.cs index 78c6be164..507e60573 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Proxy/DnsBlacklist.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Proxy/DnsBlacklist.cs @@ -1,37 +1,13 @@ +using Ryujinx.Common.Helper; using System.Text.RegularExpressions; namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres.Proxy { - static partial class DnsBlacklist + static class DnsBlacklist { - const RegexOptions RegexOpts = RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture; - - [GeneratedRegex(@"^(.*)\-lp1\.(n|s)\.n\.srv\.nintendo\.net$", RegexOpts)] - private static partial Regex BlockedHost1(); - [GeneratedRegex(@"^(.*)\-lp1\.lp1\.t\.npln\.srv\.nintendo\.net$", RegexOpts)] - private static partial Regex BlockedHost2(); - [GeneratedRegex(@"^(.*)\-lp1\.(znc|p)\.srv\.nintendo\.net$", RegexOpts)] - private static partial Regex BlockedHost3(); - [GeneratedRegex(@"^(.*)\-sb\-api\.accounts\.nintendo\.com$", RegexOpts)] - private static partial Regex BlockedHost4(); - [GeneratedRegex(@"^(.*)\-sb\.accounts\.nintendo\.com$", RegexOpts)] - private static partial Regex BlockedHost5(); - [GeneratedRegex(@"^accounts\.nintendo\.com$", RegexOpts)] - private static partial Regex BlockedHost6(); - - private static readonly Regex[] _blockedHosts = - [ - BlockedHost1(), - BlockedHost2(), - BlockedHost3(), - BlockedHost4(), - BlockedHost5(), - BlockedHost6() - ]; - public static bool IsHostBlocked(string host) { - foreach (Regex regex in _blockedHosts) + foreach (Regex regex in Patterns.BlockedHosts) { if (regex.IsMatch(host)) { diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IHOSBinderDriver.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IHOSBinderDriver.cs index 2ffa961cb..e23e6fa3f 100644 --- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IHOSBinderDriver.cs +++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/IHOSBinderDriver.cs @@ -3,7 +3,6 @@ using Ryujinx.HLE.HOS.Ipc; using Ryujinx.HLE.HOS.Kernel.Threading; using Ryujinx.Horizon.Common; using System; -using System.Buffers; namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger { diff --git a/src/Ryujinx.HLE/Loaders/Executables/NsoExecutable.cs b/src/Ryujinx.HLE/Loaders/Executables/NsoExecutable.cs index 5217612b9..84f229d8e 100644 --- a/src/Ryujinx.HLE/Loaders/Executables/NsoExecutable.cs +++ b/src/Ryujinx.HLE/Loaders/Executables/NsoExecutable.cs @@ -2,6 +2,7 @@ using LibHac.Common.FixedArrays; using LibHac.Fs; using LibHac.Loader; using LibHac.Tools.FsSystem; +using Ryujinx.Common.Helper; using Ryujinx.Common.Logging; using System; using System.Text; @@ -29,13 +30,6 @@ namespace Ryujinx.HLE.Loaders.Executables public string Name; public Array32 BuildId; - [GeneratedRegex(@"[a-z]:[\\/][ -~]{5,}\.nss", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)] - private static partial Regex ModuleRegex(); - [GeneratedRegex(@"sdk_version: ([0-9.]*)")] - private static partial Regex FsSdkRegex(); - [GeneratedRegex(@"SDK MW[ -~]*")] - private static partial Regex SdkMwRegex(); - public NsoExecutable(IStorage inStorage, string name = null) { NsoReader reader = new(); @@ -90,7 +84,7 @@ namespace Ryujinx.HLE.Loaders.Executables if (string.IsNullOrEmpty(modulePath)) { - Match moduleMatch = ModuleRegex().Match(rawTextBuffer); + Match moduleMatch = Patterns.Module.Match(rawTextBuffer); if (moduleMatch.Success) { modulePath = moduleMatch.Value; @@ -99,13 +93,13 @@ namespace Ryujinx.HLE.Loaders.Executables stringBuilder.AppendLine($" Module: {modulePath}"); - Match fsSdkMatch = FsSdkRegex().Match(rawTextBuffer); + Match fsSdkMatch = Patterns.FsSdk.Match(rawTextBuffer); if (fsSdkMatch.Success) { stringBuilder.AppendLine($" FS SDK Version: {fsSdkMatch.Value.Replace("sdk_version: ", string.Empty)}"); } - MatchCollection sdkMwMatches = SdkMwRegex().Matches(rawTextBuffer); + MatchCollection sdkMwMatches = Patterns.SdkMw.Matches(rawTextBuffer); if (sdkMwMatches.Count != 0) { string libHeader = " SDK Libraries: "; diff --git a/src/Ryujinx.HLE/Loaders/Processes/Extensions/FileSystemExtensions.cs b/src/Ryujinx.HLE/Loaders/Processes/Extensions/FileSystemExtensions.cs index 01f65206f..dec52e2e3 100644 --- a/src/Ryujinx.HLE/Loaders/Processes/Extensions/FileSystemExtensions.cs +++ b/src/Ryujinx.HLE/Loaders/Processes/Extensions/FileSystemExtensions.cs @@ -4,7 +4,6 @@ using LibHac.Fs.Fsa; using LibHac.Loader; using LibHac.Ns; using LibHac.Tools.FsSystem; -using Ryujinx.Common; using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; using Ryujinx.Graphics.Gpu; diff --git a/src/Ryujinx.HLE/Loaders/Processes/ProcessLoaderHelper.cs b/src/Ryujinx.HLE/Loaders/Processes/ProcessLoaderHelper.cs index badced1b9..cedd11ae9 100644 --- a/src/Ryujinx.HLE/Loaders/Processes/ProcessLoaderHelper.cs +++ b/src/Ryujinx.HLE/Loaders/Processes/ProcessLoaderHelper.cs @@ -21,7 +21,6 @@ using Ryujinx.HLE.Loaders.Processes.Extensions; using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Arp; using System; -using System.Linq; using System.Runtime.InteropServices; using ApplicationId = LibHac.Ncm.ApplicationId; diff --git a/src/Ryujinx.Horizon.Common/IExternalEvent.cs b/src/Ryujinx.Horizon.Common/IExternalEvent.cs index dedf4c72a..2cb96bf31 100644 --- a/src/Ryujinx.Horizon.Common/IExternalEvent.cs +++ b/src/Ryujinx.Horizon.Common/IExternalEvent.cs @@ -1,5 +1,3 @@ -using System; - namespace Ryujinx.Horizon.Common { public interface IExternalEvent diff --git a/src/Ryujinx.Horizon/HorizonStatic.cs b/src/Ryujinx.Horizon/HorizonStatic.cs index 305d54bd1..15689f0c8 100644 --- a/src/Ryujinx.Horizon/HorizonStatic.cs +++ b/src/Ryujinx.Horizon/HorizonStatic.cs @@ -1,31 +1,37 @@ +using MsgPack; using Ryujinx.Horizon.Common; using Ryujinx.Memory; using System; +using System.Threading; namespace Ryujinx.Horizon { public static class HorizonStatic { - [ThreadStatic] - private static HorizonOptions _options; + internal static void HandlePlayReport(MessagePackObject report) => + new Thread(() => PlayReport?.Invoke(report)) + { + Name = "HLE.PlayReportEvent", + IsBackground = true, + Priority = ThreadPriority.AboveNormal + }.Start(); + + public static event Action PlayReport; - [ThreadStatic] - private static ISyscallApi _syscall; + [field: ThreadStatic] + public static HorizonOptions Options { get; private set; } - [ThreadStatic] - private static IVirtualMemoryManager _addressSpace; + [field: ThreadStatic] + public static ISyscallApi Syscall { get; private set; } - [ThreadStatic] - private static IThreadContext _threadContext; + [field: ThreadStatic] + public static IVirtualMemoryManager AddressSpace { get; private set; } - [ThreadStatic] - private static int _threadHandle; + [field: ThreadStatic] + public static IThreadContext ThreadContext { get; private set; } - public static HorizonOptions Options => _options; - public static ISyscallApi Syscall => _syscall; - public static IVirtualMemoryManager AddressSpace => _addressSpace; - public static IThreadContext ThreadContext => _threadContext; - public static int CurrentThreadHandle => _threadHandle; + [field: ThreadStatic] + public static int CurrentThreadHandle { get; private set; } public static void Register( HorizonOptions options, @@ -34,11 +40,11 @@ namespace Ryujinx.Horizon IThreadContext threadContext, int threadHandle) { - _options = options; - _syscall = syscallApi; - _addressSpace = addressSpace; - _threadContext = threadContext; - _threadHandle = threadHandle; + Options = options; + Syscall = syscallApi; + AddressSpace = addressSpace; + ThreadContext = threadContext; + CurrentThreadHandle = threadHandle; } } } diff --git a/src/Ryujinx.Horizon/Prepo/Ipc/PrepoService.cs b/src/Ryujinx.Horizon/Prepo/Ipc/PrepoService.cs index 4ed7dd48e..2f8657e0b 100644 --- a/src/Ryujinx.Horizon/Prepo/Ipc/PrepoService.cs +++ b/src/Ryujinx.Horizon/Prepo/Ipc/PrepoService.cs @@ -1,3 +1,4 @@ +using Gommon; using MsgPack; using MsgPack.Serialization; using Ryujinx.Common.Logging; @@ -11,6 +12,7 @@ using Ryujinx.Horizon.Sdk.Sf; using Ryujinx.Horizon.Sdk.Sf.Hipc; using System; using System.Text; +using System.Threading; using ApplicationId = Ryujinx.Horizon.Sdk.Ncm.ApplicationId; namespace Ryujinx.Horizon.Prepo.Ipc @@ -230,6 +232,8 @@ namespace Ryujinx.Horizon.Prepo.Ipc builder.AppendLine($" Room: {gameRoom}"); builder.AppendLine($" Report: {MessagePackObjectFormatter.Format(deserializedReport)}"); + + HorizonStatic.HandlePlayReport(deserializedReport); Logger.Info?.Print(LogClass.ServicePrepo, builder.ToString()); diff --git a/src/Ryujinx.Horizon/Sdk/Audio/Detail/AudioRenderer.cs b/src/Ryujinx.Horizon/Sdk/Audio/Detail/AudioRenderer.cs index 168d58619..84c88d13b 100644 --- a/src/Ryujinx.Horizon/Sdk/Audio/Detail/AudioRenderer.cs +++ b/src/Ryujinx.Horizon/Sdk/Audio/Detail/AudioRenderer.cs @@ -1,7 +1,6 @@ using Ryujinx.Audio; using Ryujinx.Audio.Integration; using Ryujinx.Audio.Renderer.Server; -using Ryujinx.Common.Memory; using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Sf; using Ryujinx.Horizon.Sdk.Sf.Hipc; diff --git a/src/Ryujinx.Horizon/Sdk/Codec/Detail/HardwareOpusDecoderManager.cs b/src/Ryujinx.Horizon/Sdk/Codec/Detail/HardwareOpusDecoderManager.cs index acec66e82..d74e50a61 100644 --- a/src/Ryujinx.Horizon/Sdk/Codec/Detail/HardwareOpusDecoderManager.cs +++ b/src/Ryujinx.Horizon/Sdk/Codec/Detail/HardwareOpusDecoderManager.cs @@ -2,7 +2,6 @@ using Ryujinx.Common; using Ryujinx.Horizon.Common; using Ryujinx.Horizon.Sdk.Sf; using Ryujinx.Horizon.Sdk.Sf.Hipc; -using System; namespace Ryujinx.Horizon.Sdk.Codec.Detail { diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/BlockedUserImpl.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/BlockedUserImpl.cs index d5f8a0313..a7ede259f 100644 --- a/src/Ryujinx.Horizon/Sdk/Friends/Detail/BlockedUserImpl.cs +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/BlockedUserImpl.cs @@ -1,5 +1,3 @@ -using System.Runtime.InteropServices; - namespace Ryujinx.Horizon.Sdk.Friends.Detail { struct BlockedUserImpl diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendCandidateImpl.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendCandidateImpl.cs index 21e99c754..1051343d6 100644 --- a/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendCandidateImpl.cs +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendCandidateImpl.cs @@ -1,5 +1,3 @@ -using System.Runtime.InteropServices; - namespace Ryujinx.Horizon.Sdk.Friends.Detail { struct FriendCandidateImpl diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendInvitationForViewerImpl.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendInvitationForViewerImpl.cs index 416ba3655..06134f245 100644 --- a/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendInvitationForViewerImpl.cs +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendInvitationForViewerImpl.cs @@ -1,5 +1,3 @@ -using System.Runtime.InteropServices; - namespace Ryujinx.Horizon.Sdk.Friends.Detail { struct FriendInvitationForViewerImpl diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendRequestImpl.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendRequestImpl.cs index ba5671692..108b56008 100644 --- a/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendRequestImpl.cs +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/FriendRequestImpl.cs @@ -1,5 +1,3 @@ -using System.Runtime.InteropServices; - namespace Ryujinx.Horizon.Sdk.Friends.Detail { struct FriendRequestImpl diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/NintendoNetworkIdFriendImpl.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/NintendoNetworkIdFriendImpl.cs index 66d61e4c1..7b7460481 100644 --- a/src/Ryujinx.Horizon/Sdk/Friends/Detail/NintendoNetworkIdFriendImpl.cs +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/NintendoNetworkIdFriendImpl.cs @@ -1,5 +1,3 @@ -using System.Runtime.InteropServices; - namespace Ryujinx.Horizon.Sdk.Friends.Detail { struct NintendoNetworkIdFriendImpl diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/PlayHistoryImpl.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/PlayHistoryImpl.cs index 9f90f0c8f..37f4d7c2d 100644 --- a/src/Ryujinx.Horizon/Sdk/Friends/Detail/PlayHistoryImpl.cs +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/PlayHistoryImpl.cs @@ -1,5 +1,3 @@ -using System.Runtime.InteropServices; - namespace Ryujinx.Horizon.Sdk.Friends.Detail { struct PlayHistoryImpl diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/ProfileImpl.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/ProfileImpl.cs index f779d93cf..422f814ce 100644 --- a/src/Ryujinx.Horizon/Sdk/Friends/Detail/ProfileImpl.cs +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/ProfileImpl.cs @@ -1,5 +1,3 @@ -using System.Runtime.InteropServices; - namespace Ryujinx.Horizon.Sdk.Friends.Detail { struct ProfileImpl diff --git a/src/Ryujinx.Horizon/Sdk/Friends/Detail/SnsAccountFriendImpl.cs b/src/Ryujinx.Horizon/Sdk/Friends/Detail/SnsAccountFriendImpl.cs index dc6adf03a..f3d0cdce3 100644 --- a/src/Ryujinx.Horizon/Sdk/Friends/Detail/SnsAccountFriendImpl.cs +++ b/src/Ryujinx.Horizon/Sdk/Friends/Detail/SnsAccountFriendImpl.cs @@ -1,5 +1,3 @@ -using System.Runtime.InteropServices; - namespace Ryujinx.Horizon.Sdk.Friends.Detail { struct SnsAccountFriendImpl diff --git a/src/Ryujinx.Horizon/Sdk/Friends/FriendInvitationId.cs b/src/Ryujinx.Horizon/Sdk/Friends/FriendInvitationId.cs index 7be19d574..46e734ed2 100644 --- a/src/Ryujinx.Horizon/Sdk/Friends/FriendInvitationId.cs +++ b/src/Ryujinx.Horizon/Sdk/Friends/FriendInvitationId.cs @@ -1,5 +1,3 @@ -using System.Runtime.InteropServices; - namespace Ryujinx.Horizon.Sdk.Friends { struct FriendInvitationId diff --git a/src/Ryujinx.Horizon/Sdk/Ns/ApplicationControlProperty.cs b/src/Ryujinx.Horizon/Sdk/Ns/ApplicationControlProperty.cs index 12c19168d..7640967c6 100644 --- a/src/Ryujinx.Horizon/Sdk/Ns/ApplicationControlProperty.cs +++ b/src/Ryujinx.Horizon/Sdk/Ns/ApplicationControlProperty.cs @@ -1,8 +1,5 @@ using Ryujinx.Common.Memory; -using Ryujinx.Horizon.Sdk.Arp.Detail; using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using System.Text; namespace Ryujinx.Horizon.Sdk.Ns diff --git a/src/Ryujinx.Horizon/Sdk/OsTypes/OsEvent.cs b/src/Ryujinx.Horizon/Sdk/OsTypes/OsEvent.cs index 422f756e4..0cd147771 100644 --- a/src/Ryujinx.Horizon/Sdk/OsTypes/OsEvent.cs +++ b/src/Ryujinx.Horizon/Sdk/OsTypes/OsEvent.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Threading; namespace Ryujinx.Horizon.Sdk.OsTypes diff --git a/src/Ryujinx.Horizon/Sdk/Settings/Factory/CountryCode.cs b/src/Ryujinx.Horizon/Sdk/Settings/Factory/CountryCode.cs index daf2ba3b8..33234ed76 100644 --- a/src/Ryujinx.Horizon/Sdk/Settings/Factory/CountryCode.cs +++ b/src/Ryujinx.Horizon/Sdk/Settings/Factory/CountryCode.cs @@ -1,5 +1,3 @@ -using System.Runtime.InteropServices; - namespace Ryujinx.Horizon.Sdk.Settings.Factory { struct CountryCode diff --git a/src/Ryujinx.Horizon/Usb/Ipc/PdManager.cs b/src/Ryujinx.Horizon/Usb/Ipc/PdManager.cs index 1c502919b..120d7b51a 100644 --- a/src/Ryujinx.Horizon/Usb/Ipc/PdManager.cs +++ b/src/Ryujinx.Horizon/Usb/Ipc/PdManager.cs @@ -1,4 +1,3 @@ -using Ryujinx.Horizon.Sdk.Sf.Hipc; using Ryujinx.Horizon.Sdk.Usb; namespace Ryujinx.Horizon.Usb.Ipc diff --git a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs index a473d7042..3b243eed0 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs @@ -2,8 +2,6 @@ using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid.Controller; using Ryujinx.Common.Logging; using Ryujinx.Common.Utilities; -using Ryujinx.HLE.HOS.Services.Hid; -using SDL2; using System; using System.Collections.Generic; using System.Numerics; @@ -12,7 +10,7 @@ using static SDL2.SDL; namespace Ryujinx.Input.SDL2 { - class SDL2Gamepad : IGamepad + public class SDL2Gamepad : IGamepad { private bool HasConfiguration => _configuration != null; @@ -113,7 +111,7 @@ namespace Ryujinx.Input.SDL2 byte blue = packedRgb > 0 ? (byte)(packedRgb % 256) : (byte)0; if (SDL_GameControllerSetLED(_gamepadHandle, red, green, blue) != 0) - Logger.Error?.Print(LogClass.Hid, "LED is not supported on this game controller."); + Logger.Error?.Print(LogClass.Hid, "LED setting failed; probably in the middle of disconnecting."); } private GamepadFeaturesFlag GetFeaturesFlag() diff --git a/src/Ryujinx.Memory/AddressSpaceManager.cs b/src/Ryujinx.Memory/AddressSpaceManager.cs index 150e538fe..f9d514b55 100644 --- a/src/Ryujinx.Memory/AddressSpaceManager.cs +++ b/src/Ryujinx.Memory/AddressSpaceManager.cs @@ -1,7 +1,6 @@ using Ryujinx.Memory.Range; using System; using System.Collections.Generic; -using System.Linq; using System.Runtime.CompilerServices; namespace Ryujinx.Memory diff --git a/src/Ryujinx.Memory/Tracking/RegionFlags.cs b/src/Ryujinx.Memory/Tracking/RegionFlags.cs index ceb8e56a6..1eefdfbc0 100644 --- a/src/Ryujinx.Memory/Tracking/RegionFlags.cs +++ b/src/Ryujinx.Memory/Tracking/RegionFlags.cs @@ -1,8 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Ryujinx.Memory.Tracking { diff --git a/src/Ryujinx.Memory/WindowsShared/WindowsApi.cs b/src/Ryujinx.Memory/WindowsShared/WindowsApi.cs index 0d002dada..d146e55a4 100644 --- a/src/Ryujinx.Memory/WindowsShared/WindowsApi.cs +++ b/src/Ryujinx.Memory/WindowsShared/WindowsApi.cs @@ -1,4 +1,3 @@ -using System; using System.Runtime.InteropServices; using System.Runtime.Versioning; diff --git a/src/Ryujinx.SDL2.Common/SDL2Driver.cs b/src/Ryujinx.SDL2.Common/SDL2Driver.cs index 047ccbebf..851c07867 100644 --- a/src/Ryujinx.SDL2.Common/SDL2Driver.cs +++ b/src/Ryujinx.SDL2.Common/SDL2Driver.cs @@ -1,6 +1,5 @@ using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; -using Ryujinx.Common.Utilities; using System; using System.Collections.Concurrent; using System.Collections.Generic; diff --git a/src/Ryujinx.Tests/Cpu/CpuTest.cs b/src/Ryujinx.Tests/Cpu/CpuTest.cs index da0f03e6b..6f749463e 100644 --- a/src/Ryujinx.Tests/Cpu/CpuTest.cs +++ b/src/Ryujinx.Tests/Cpu/CpuTest.cs @@ -1,6 +1,5 @@ using ARMeilleure; using ARMeilleure.State; -using ARMeilleure.Translation; using NUnit.Framework; using Ryujinx.Cpu.Jit; using Ryujinx.Memory; diff --git a/src/Ryujinx.Tests/Cpu/CpuTest32.cs b/src/Ryujinx.Tests/Cpu/CpuTest32.cs index 81ed9bcc9..d4c8156d7 100644 --- a/src/Ryujinx.Tests/Cpu/CpuTest32.cs +++ b/src/Ryujinx.Tests/Cpu/CpuTest32.cs @@ -1,6 +1,5 @@ using ARMeilleure; using ARMeilleure.State; -using ARMeilleure.Translation; using NUnit.Framework; using Ryujinx.Cpu.Jit; using Ryujinx.Memory; diff --git a/src/Ryujinx.Tests/Cpu/CpuTestT32Mem.cs b/src/Ryujinx.Tests/Cpu/CpuTestT32Mem.cs index b7ad8efe7..3d8847dc4 100644 --- a/src/Ryujinx.Tests/Cpu/CpuTestT32Mem.cs +++ b/src/Ryujinx.Tests/Cpu/CpuTestT32Mem.cs @@ -1,5 +1,4 @@ using NUnit.Framework; -using System; namespace Ryujinx.Tests.Cpu { diff --git a/src/Ryujinx/AppHost.cs b/src/Ryujinx/AppHost.cs index b85b17b89..25f451858 100644 --- a/src/Ryujinx/AppHost.cs +++ b/src/Ryujinx/AppHost.cs @@ -319,31 +319,12 @@ namespace Ryujinx.Ava public void VSyncModeToggle() { VSyncMode oldVSyncMode = Device.VSyncMode; - VSyncMode newVSyncMode = VSyncMode.Switch; bool customVSyncIntervalEnabled = ConfigurationState.Instance.Graphics.EnableCustomVSyncInterval.Value; - switch (oldVSyncMode) - { - case VSyncMode.Switch: - newVSyncMode = VSyncMode.Unbounded; - break; - case VSyncMode.Unbounded: - if (customVSyncIntervalEnabled) - { - newVSyncMode = VSyncMode.Custom; - } - else - { - newVSyncMode = VSyncMode.Switch; - } - - break; - case VSyncMode.Custom: - newVSyncMode = VSyncMode.Switch; - break; - } - - UpdateVSyncMode(this, new ReactiveEventArgs(oldVSyncMode, newVSyncMode)); + UpdateVSyncMode(this, new ReactiveEventArgs( + oldVSyncMode, + oldVSyncMode.Next(customVSyncIntervalEnabled)) + ); } private void UpdateCustomVSyncIntervalValue(object sender, ReactiveEventArgs e) @@ -957,7 +938,9 @@ namespace Ryujinx.Ava ConfigurationState.Instance.System.EnableInternetAccess, ConfigurationState.Instance.System.EnableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None, ConfigurationState.Instance.System.FsGlobalAccessLogMode, - ConfigurationState.Instance.System.SystemTimeOffset, + ConfigurationState.Instance.System.MatchSystemTime + ? 0 + : ConfigurationState.Instance.System.SystemTimeOffset, ConfigurationState.Instance.System.TimeZone, ConfigurationState.Instance.System.MemoryManagerMode, ConfigurationState.Instance.System.IgnoreMissingServices, diff --git a/src/Ryujinx/Assets/Styles/CheckboxMenuItemStyle.axaml b/src/Ryujinx/Assets/Styles/CheckboxMenuItemStyle.axaml deleted file mode 100644 index 13176c84f..000000000 --- a/src/Ryujinx/Assets/Styles/CheckboxMenuItemStyle.axaml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - diff --git a/src/Ryujinx/Assets/Styles/Styles.xaml b/src/Ryujinx/Assets/Styles/Styles.xaml index 3d0c91840..5523f551a 100644 --- a/src/Ryujinx/Assets/Styles/Styles.xaml +++ b/src/Ryujinx/Assets/Styles/Styles.xaml @@ -218,6 +218,15 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Ryujinx/UI/Controls/ApplicationDataView.axaml.cs b/src/Ryujinx/UI/Controls/ApplicationDataView.axaml.cs new file mode 100644 index 000000000..e85e1188e --- /dev/null +++ b/src/Ryujinx/UI/Controls/ApplicationDataView.axaml.cs @@ -0,0 +1,86 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Input.Platform; +using Avalonia.Interactivity; +using Avalonia.Styling; +using FluentAvalonia.UI.Controls; +using Ryujinx.Ava; +using Ryujinx.Ava.Common.Locale; +using Ryujinx.Ava.UI.Controls; +using Ryujinx.Ava.UI.Helpers; +using Ryujinx.Ava.UI.ViewModels; +using Ryujinx.Ava.UI.Windows; +using Ryujinx.Ava.Utilities.AppLibrary; +using Ryujinx.Ava.Utilities.Compat; +using System.Linq; +using System.Threading.Tasks; + +namespace Ryujinx.Ava.UI.Controls +{ + public partial class ApplicationDataView : UserControl + { + public static async Task Show(ApplicationData appData) + { + ContentDialog contentDialog = new() + { + Title = appData.Name, + PrimaryButtonText = string.Empty, + SecondaryButtonText = string.Empty, + CloseButtonText = LocaleManager.Instance[LocaleKeys.SettingsButtonClose], + MinWidth = 256, + Content = new ApplicationDataView { DataContext = new ApplicationDataViewModel(appData) } + }; + + Style closeButton = new(x => x.Name("CloseButton")); + closeButton.Setters.Add(new Setter(WidthProperty, 160d)); + + Style closeButtonParent = new(x => x.Name("CommandSpace")); + closeButtonParent.Setters.Add(new Setter(HorizontalAlignmentProperty, + Avalonia.Layout.HorizontalAlignment.Center)); + + contentDialog.Styles.Add(closeButton); + contentDialog.Styles.Add(closeButtonParent); + + await ContentDialogHelper.ShowAsync(contentDialog); + } + + public ApplicationDataView() + { + InitializeComponent(); + } + + private async void PlayabilityStatus_OnClick(object sender, RoutedEventArgs e) + { + if (sender is not Button { Content: TextBlock playabilityLabel }) + return; + + if (RyujinxApp.AppLifetime.Windows.TryGetFirst(x => x is ContentDialogOverlayWindow, out Window window)) + window.Close(ContentDialogResult.None); + + await CompatibilityList.Show((string)playabilityLabel.Tag); + } + + private async void IdString_OnClick(object sender, RoutedEventArgs e) + { + if (DataContext is not MainWindowViewModel mwvm) + return; + + if (sender is not Button { Content: TextBlock idText }) + return; + + if (!RyujinxApp.IsClipboardAvailable(out IClipboard clipboard)) + return; + + ApplicationData appData = mwvm.Applications.FirstOrDefault(it => it.IdString == idText.Text); + if (appData is null) + return; + + await clipboard.SetTextAsync(appData.IdString); + + NotificationHelper.ShowInformation( + "Copied Title ID", + $"{appData.Name} ({appData.IdString})"); + } + } +} + diff --git a/src/Ryujinx/UI/Controls/ApplicationGridView.axaml.cs b/src/Ryujinx/UI/Controls/ApplicationGridView.axaml.cs index 80d1f7879..22aefc3b9 100644 --- a/src/Ryujinx/UI/Controls/ApplicationGridView.axaml.cs +++ b/src/Ryujinx/UI/Controls/ApplicationGridView.axaml.cs @@ -2,7 +2,6 @@ using Avalonia.Controls; using Avalonia.Input; using Avalonia.Interactivity; using Ryujinx.Ava.UI.Helpers; -using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.Utilities.AppLibrary; using System; diff --git a/src/Ryujinx/UI/Controls/ApplicationListView.axaml b/src/Ryujinx/UI/Controls/ApplicationListView.axaml index 9b87805e4..733500338 100644 --- a/src/Ryujinx/UI/Controls/ApplicationListView.axaml +++ b/src/Ryujinx/UI/Controls/ApplicationListView.axaml @@ -86,6 +86,30 @@ Text="{Binding Version}" TextAlignment="Start" TextWrapping="Wrap" /> + diff --git a/src/Ryujinx/UI/Controls/ApplicationListView.axaml.cs b/src/Ryujinx/UI/Controls/ApplicationListView.axaml.cs index 41919ebf5..7c6b0cf15 100644 --- a/src/Ryujinx/UI/Controls/ApplicationListView.axaml.cs +++ b/src/Ryujinx/UI/Controls/ApplicationListView.axaml.cs @@ -1,13 +1,13 @@ using Avalonia.Controls; -using Avalonia.Controls.Notifications; using Avalonia.Input; using Avalonia.Input.Platform; using Avalonia.Interactivity; -using FluentAvalonia.UI.Controls; using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.Utilities.AppLibrary; +using Ryujinx.Ava.Utilities.Compat; using System; +using System.Globalization; using System.Linq; namespace Ryujinx.Ava.UI.Controls @@ -30,6 +30,17 @@ namespace Ryujinx.Ava.UI.Controls if (sender is ListBox { SelectedItem: ApplicationData selected }) RaiseEvent(new ApplicationOpenedEventArgs(selected, ApplicationOpenedEvent)); } + + private async void PlayabilityStatus_OnClick(object sender, RoutedEventArgs e) + { + if (DataContext is not MainWindowViewModel mwvm) + return; + + if (sender is not Button { Content: TextBlock playabilityLabel }) + return; + + await CompatibilityList.Show((string)playabilityLabel.Tag); + } private async void IdString_OnClick(object sender, RoutedEventArgs e) { diff --git a/src/Ryujinx/UI/Controls/DlcSelectView.axaml.cs b/src/Ryujinx/UI/Controls/DlcSelectView.axaml.cs index c011ca110..939acc0a3 100644 --- a/src/Ryujinx/UI/Controls/DlcSelectView.axaml.cs +++ b/src/Ryujinx/UI/Controls/DlcSelectView.axaml.cs @@ -1,6 +1,4 @@ -using Avalonia; -using Avalonia.Controls; -using Avalonia.Markup.Xaml; +using Avalonia.Controls; using Avalonia.Styling; using FluentAvalonia.UI.Controls; using Ryujinx.Ava.Common.Locale; diff --git a/src/Ryujinx/UI/Helpers/ContentDialogHelper.cs b/src/Ryujinx/UI/Helpers/ContentDialogHelper.cs index b5d085ba1..ae83f9e98 100644 --- a/src/Ryujinx/UI/Helpers/ContentDialogHelper.cs +++ b/src/Ryujinx/UI/Helpers/ContentDialogHelper.cs @@ -159,6 +159,7 @@ namespace Ryujinx.Ava.UI.Helpers Symbol = (Symbol)symbol, Margin = new Thickness(10), FontSize = 40, + FlowDirection = FlowDirection.LeftToRight, VerticalAlignment = VerticalAlignment.Center, }; diff --git a/src/Ryujinx/UI/Helpers/Converters/MultiplayerInfoConverter.cs b/src/Ryujinx/UI/Helpers/Converters/MultiplayerInfoConverter.cs index 47d0b94d0..7694e8883 100644 --- a/src/Ryujinx/UI/Helpers/Converters/MultiplayerInfoConverter.cs +++ b/src/Ryujinx/UI/Helpers/Converters/MultiplayerInfoConverter.cs @@ -1,27 +1,31 @@ using Avalonia.Data.Converters; using Avalonia.Markup.Xaml; +using Gommon; +using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Utilities.AppLibrary; using System; using System.Globalization; +using System.Text; namespace Ryujinx.Ava.UI.Helpers { internal class MultiplayerInfoConverter : MarkupExtension, IValueConverter { - private static readonly MultiplayerInfoConverter _instance = new(); + public static readonly MultiplayerInfoConverter Instance = new(); public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { - if (value is ApplicationData applicationData) - { - if (applicationData.PlayerCount != 0 && applicationData.GameCount != 0) - { - return $"Hosted Games: {applicationData.GameCount}\nOnline Players: {applicationData.PlayerCount}"; - } - } - - return ""; + if (value is not ApplicationData { HasLdnGames: true } applicationData) + return ""; + return new StringBuilder() + .AppendLine( + LocaleManager.Instance[LocaleKeys.GameListHeaderHostedGames] + .Format(applicationData.GameCount)) + .Append( + LocaleManager.Instance[LocaleKeys.GameListHeaderPlayerCount] + .Format(applicationData.PlayerCount)) + .ToString(); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) @@ -31,7 +35,7 @@ namespace Ryujinx.Ava.UI.Helpers public override object ProvideValue(IServiceProvider serviceProvider) { - return _instance; + return Instance; } } } diff --git a/src/Ryujinx/UI/Models/Input/GamepadInputConfig.cs b/src/Ryujinx/UI/Models/Input/GamepadInputConfig.cs index 6f0f7f47f..300d7977c 100644 --- a/src/Ryujinx/UI/Models/Input/GamepadInputConfig.cs +++ b/src/Ryujinx/UI/Models/Input/GamepadInputConfig.cs @@ -1,13 +1,13 @@ using Avalonia.Media; +using CommunityToolkit.Mvvm.ComponentModel; using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid.Controller; using Ryujinx.Common.Configuration.Hid.Controller.Motion; -using System; namespace Ryujinx.Ava.UI.Models.Input { - public class GamepadInputConfig : BaseModel + public partial class GamepadInputConfig : BaseModel { public bool EnableCemuHookMotion { get; set; } public string DsuServerHost { get; set; } @@ -25,402 +25,58 @@ namespace Ryujinx.Ava.UI.Models.Input public ControllerType ControllerType { get; set; } public PlayerIndex PlayerIndex { get; set; } - private StickInputId _leftJoystick; - public StickInputId LeftJoystick - { - get => _leftJoystick; - set - { - _leftJoystick = value; - OnPropertyChanged(); - } - } + [ObservableProperty] private StickInputId _leftJoystick; + [ObservableProperty] private bool _leftInvertStickX; + [ObservableProperty] private bool _leftInvertStickY; + [ObservableProperty] private bool _leftRotate90; + [ObservableProperty] private GamepadInputId _leftStickButton; - private bool _leftInvertStickX; - public bool LeftInvertStickX - { - get => _leftInvertStickX; - set - { - _leftInvertStickX = value; - OnPropertyChanged(); - } - } + [ObservableProperty] private StickInputId _rightJoystick; + [ObservableProperty] private bool _rightInvertStickX; + [ObservableProperty] private bool _rightInvertStickY; + [ObservableProperty] private bool _rightRotate90; + [ObservableProperty] private GamepadInputId _rightStickButton; - private bool _leftInvertStickY; - public bool LeftInvertStickY - { - get => _leftInvertStickY; - set - { - _leftInvertStickY = value; - OnPropertyChanged(); - } - } + [ObservableProperty] private GamepadInputId _dpadUp; + [ObservableProperty] private GamepadInputId _dpadDown; + [ObservableProperty] private GamepadInputId _dpadLeft; + [ObservableProperty] private GamepadInputId _dpadRight; - private bool _leftRotate90; - public bool LeftRotate90 - { - get => _leftRotate90; - set - { - _leftRotate90 = value; - OnPropertyChanged(); - } - } - - private GamepadInputId _leftStickButton; - public GamepadInputId LeftStickButton - { - get => _leftStickButton; - set - { - _leftStickButton = value; - OnPropertyChanged(); - } - } - - private StickInputId _rightJoystick; - public StickInputId RightJoystick - { - get => _rightJoystick; - set - { - _rightJoystick = value; - OnPropertyChanged(); - } - } - - private bool _rightInvertStickX; - public bool RightInvertStickX - { - get => _rightInvertStickX; - set - { - _rightInvertStickX = value; - OnPropertyChanged(); - } - } - - private bool _rightInvertStickY; - public bool RightInvertStickY - { - get => _rightInvertStickY; - set - { - _rightInvertStickY = value; - OnPropertyChanged(); - } - } - - private bool _rightRotate90; - public bool RightRotate90 - { - get => _rightRotate90; - set - { - _rightRotate90 = value; - OnPropertyChanged(); - } - } - - private GamepadInputId _rightStickButton; - public GamepadInputId RightStickButton - { - get => _rightStickButton; - set - { - _rightStickButton = value; - OnPropertyChanged(); - } - } - - private GamepadInputId _dpadUp; - public GamepadInputId DpadUp - { - get => _dpadUp; - set - { - _dpadUp = value; - OnPropertyChanged(); - } - } - - private GamepadInputId _dpadDown; - public GamepadInputId DpadDown - { - get => _dpadDown; - set - { - _dpadDown = value; - OnPropertyChanged(); - } - } - - private GamepadInputId _dpadLeft; - public GamepadInputId DpadLeft - { - get => _dpadLeft; - set - { - _dpadLeft = value; - OnPropertyChanged(); - } - } - - private GamepadInputId _dpadRight; - public GamepadInputId DpadRight - { - get => _dpadRight; - set - { - _dpadRight = value; - OnPropertyChanged(); - } - } - - private GamepadInputId _buttonL; - public GamepadInputId ButtonL - { - get => _buttonL; - set - { - _buttonL = value; - OnPropertyChanged(); - } - } - - private GamepadInputId _buttonMinus; - public GamepadInputId ButtonMinus - { - get => _buttonMinus; - set - { - _buttonMinus = value; - OnPropertyChanged(); - } - } - - private GamepadInputId _leftButtonSl; - public GamepadInputId LeftButtonSl - { - get => _leftButtonSl; - set - { - _leftButtonSl = value; - OnPropertyChanged(); - } - } - - private GamepadInputId _leftButtonSr; - public GamepadInputId LeftButtonSr - { - get => _leftButtonSr; - set - { - _leftButtonSr = value; - OnPropertyChanged(); - } - } - - private GamepadInputId _buttonZl; - public GamepadInputId ButtonZl - { - get => _buttonZl; - set - { - _buttonZl = value; - OnPropertyChanged(); - } - } - - private GamepadInputId _buttonA; - public GamepadInputId ButtonA - { - get => _buttonA; - set - { - _buttonA = value; - OnPropertyChanged(); - } - } - - private GamepadInputId _buttonB; - public GamepadInputId ButtonB - { - get => _buttonB; - set - { - _buttonB = value; - OnPropertyChanged(); - } - } - - private GamepadInputId _buttonX; - public GamepadInputId ButtonX - { - get => _buttonX; - set - { - _buttonX = value; - OnPropertyChanged(); - } - } - - private GamepadInputId _buttonY; - public GamepadInputId ButtonY - { - get => _buttonY; - set - { - _buttonY = value; - OnPropertyChanged(); - } - } - - private GamepadInputId _buttonR; - public GamepadInputId ButtonR - { - get => _buttonR; - set - { - _buttonR = value; - OnPropertyChanged(); - } - } - - private GamepadInputId _buttonPlus; - public GamepadInputId ButtonPlus - { - get => _buttonPlus; - set - { - _buttonPlus = value; - OnPropertyChanged(); - } - } - - private GamepadInputId _rightButtonSl; - public GamepadInputId RightButtonSl - { - get => _rightButtonSl; - set - { - _rightButtonSl = value; - OnPropertyChanged(); - } - } - - private GamepadInputId _rightButtonSr; - public GamepadInputId RightButtonSr - { - get => _rightButtonSr; - set - { - _rightButtonSr = value; - OnPropertyChanged(); - } - } - - private GamepadInputId _buttonZr; - public GamepadInputId ButtonZr - { - get => _buttonZr; - set - { - _buttonZr = value; - OnPropertyChanged(); - } - } - - private float _deadzoneLeft; - public float DeadzoneLeft - { - get => _deadzoneLeft; - set - { - _deadzoneLeft = MathF.Round(value, 3); - OnPropertyChanged(); - } - } - - private float _deadzoneRight; - public float DeadzoneRight - { - get => _deadzoneRight; - set - { - _deadzoneRight = MathF.Round(value, 3); - OnPropertyChanged(); - } - } - - private float _rangeLeft; - public float RangeLeft - { - get => _rangeLeft; - set - { - _rangeLeft = MathF.Round(value, 3); - OnPropertyChanged(); - } - } - - private float _rangeRight; - public float RangeRight - { - get => _rangeRight; - set - { - _rangeRight = MathF.Round(value, 3); - OnPropertyChanged(); - } - } - - private float _triggerThreshold; - public float TriggerThreshold - { - get => _triggerThreshold; - set - { - _triggerThreshold = MathF.Round(value, 3); - OnPropertyChanged(); - } - } - - private bool _enableMotion; - public bool EnableMotion - { - get => _enableMotion; - set - { - _enableMotion = value; - OnPropertyChanged(); - } - } - - private bool _enableRumble; - public bool EnableRumble - { - get => _enableRumble; - set - { - _enableRumble = value; - OnPropertyChanged(); - } - } + [ObservableProperty] private GamepadInputId _buttonMinus; + [ObservableProperty] private GamepadInputId _buttonPlus; - private bool _enableLedChanging; + [ObservableProperty] private GamepadInputId _buttonA; + [ObservableProperty] private GamepadInputId _buttonB; + [ObservableProperty] private GamepadInputId _buttonX; + [ObservableProperty] private GamepadInputId _buttonY; + + [ObservableProperty] private GamepadInputId _buttonZl; + [ObservableProperty] private GamepadInputId _buttonZr; + + [ObservableProperty] private GamepadInputId _buttonL; + [ObservableProperty] private GamepadInputId _buttonR; + + [ObservableProperty] private GamepadInputId _leftButtonSl; + [ObservableProperty] private GamepadInputId _leftButtonSr; + + [ObservableProperty] private GamepadInputId _rightButtonSl; + [ObservableProperty] private GamepadInputId _rightButtonSr; - public bool EnableLedChanging - { - get => _enableLedChanging; - set - { - _enableLedChanging = value; - OnPropertyChanged(); - } - } + [ObservableProperty] private float _deadzoneLeft; + [ObservableProperty] private float _deadzoneRight; + + [ObservableProperty] private float _rangeLeft; + [ObservableProperty] private float _rangeRight; + + [ObservableProperty] private float _triggerThreshold; + + [ObservableProperty] private bool _enableMotion; + + [ObservableProperty] private bool _enableRumble; + + [ObservableProperty] private bool _enableLedChanging; + + [ObservableProperty] private Color _ledColor; public bool ShowLedColorPicker => !TurnOffLed && !UseRainbowLed; @@ -449,18 +105,6 @@ namespace Ryujinx.Ava.UI.Models.Input OnPropertyChanged(nameof(ShowLedColorPicker)); } } - - private Color _ledColor; - - public Color LedColor - { - get => _ledColor; - set - { - _ledColor = value; - OnPropertyChanged(); - } - } public GamepadInputConfig(InputConfig config) { diff --git a/src/Ryujinx/UI/Models/Input/KeyboardInputConfig.cs b/src/Ryujinx/UI/Models/Input/KeyboardInputConfig.cs index a71c85eba..2d2e95773 100644 --- a/src/Ryujinx/UI/Models/Input/KeyboardInputConfig.cs +++ b/src/Ryujinx/UI/Models/Input/KeyboardInputConfig.cs @@ -1,322 +1,52 @@ +using CommunityToolkit.Mvvm.ComponentModel; using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid.Keyboard; namespace Ryujinx.Ava.UI.Models.Input { - public class KeyboardInputConfig : BaseModel + public partial class KeyboardInputConfig : BaseModel { public string Id { get; set; } public ControllerType ControllerType { get; set; } public PlayerIndex PlayerIndex { get; set; } - private Key _leftStickUp; - public Key LeftStickUp - { - get => _leftStickUp; - set - { - _leftStickUp = value; - OnPropertyChanged(); - } - } + [ObservableProperty] private Key _leftStickUp; + [ObservableProperty] private Key _leftStickDown; + [ObservableProperty] private Key _leftStickLeft; + [ObservableProperty] private Key _leftStickRight; + [ObservableProperty] private Key _leftStickButton; - private Key _leftStickDown; - public Key LeftStickDown - { - get => _leftStickDown; - set - { - _leftStickDown = value; - OnPropertyChanged(); - } - } + [ObservableProperty] private Key _rightStickUp; + [ObservableProperty] private Key _rightStickDown; + [ObservableProperty] private Key _rightStickLeft; + [ObservableProperty] private Key _rightStickRight; + [ObservableProperty] private Key _rightStickButton; - private Key _leftStickLeft; - public Key LeftStickLeft - { - get => _leftStickLeft; - set - { - _leftStickLeft = value; - OnPropertyChanged(); - } - } - - private Key _leftStickRight; - public Key LeftStickRight - { - get => _leftStickRight; - set - { - _leftStickRight = value; - OnPropertyChanged(); - } - } - - private Key _leftStickButton; - public Key LeftStickButton - { - get => _leftStickButton; - set - { - _leftStickButton = value; - OnPropertyChanged(); - } - } - - private Key _rightStickUp; - public Key RightStickUp - { - get => _rightStickUp; - set - { - _rightStickUp = value; - OnPropertyChanged(); - } - } - - private Key _rightStickDown; - public Key RightStickDown - { - get => _rightStickDown; - set - { - _rightStickDown = value; - OnPropertyChanged(); - } - } - - private Key _rightStickLeft; - public Key RightStickLeft - { - get => _rightStickLeft; - set - { - _rightStickLeft = value; - OnPropertyChanged(); - } - } - - private Key _rightStickRight; - public Key RightStickRight - { - get => _rightStickRight; - set - { - _rightStickRight = value; - OnPropertyChanged(); - } - } - - private Key _rightStickButton; - public Key RightStickButton - { - get => _rightStickButton; - set - { - _rightStickButton = value; - OnPropertyChanged(); - } - } - - private Key _dpadUp; - public Key DpadUp - { - get => _dpadUp; - set - { - _dpadUp = value; - OnPropertyChanged(); - } - } - - private Key _dpadDown; - public Key DpadDown - { - get => _dpadDown; - set - { - _dpadDown = value; - OnPropertyChanged(); - } - } - - private Key _dpadLeft; - public Key DpadLeft - { - get => _dpadLeft; - set - { - _dpadLeft = value; - OnPropertyChanged(); - } - } - - private Key _dpadRight; - public Key DpadRight - { - get => _dpadRight; - set - { - _dpadRight = value; - OnPropertyChanged(); - } - } - - private Key _buttonL; - public Key ButtonL - { - get => _buttonL; - set - { - _buttonL = value; - OnPropertyChanged(); - } - } - - private Key _buttonMinus; - public Key ButtonMinus - { - get => _buttonMinus; - set - { - _buttonMinus = value; - OnPropertyChanged(); - } - } - - private Key _leftButtonSl; - public Key LeftButtonSl - { - get => _leftButtonSl; - set - { - _leftButtonSl = value; - OnPropertyChanged(); - } - } - - private Key _leftButtonSr; - public Key LeftButtonSr - { - get => _leftButtonSr; - set - { - _leftButtonSr = value; - OnPropertyChanged(); - } - } - - private Key _buttonZl; - public Key ButtonZl - { - get => _buttonZl; - set - { - _buttonZl = value; - OnPropertyChanged(); - } - } - - private Key _buttonA; - public Key ButtonA - { - get => _buttonA; - set - { - _buttonA = value; - OnPropertyChanged(); - } - } - - private Key _buttonB; - public Key ButtonB - { - get => _buttonB; - set - { - _buttonB = value; - OnPropertyChanged(); - } - } - - private Key _buttonX; - public Key ButtonX - { - get => _buttonX; - set - { - _buttonX = value; - OnPropertyChanged(); - } - } - - private Key _buttonY; - public Key ButtonY - { - get => _buttonY; - set - { - _buttonY = value; - OnPropertyChanged(); - } - } - - private Key _buttonR; - public Key ButtonR - { - get => _buttonR; - set - { - _buttonR = value; - OnPropertyChanged(); - } - } - - private Key _buttonPlus; - public Key ButtonPlus - { - get => _buttonPlus; - set - { - _buttonPlus = value; - OnPropertyChanged(); - } - } - - private Key _rightButtonSl; - public Key RightButtonSl - { - get => _rightButtonSl; - set - { - _rightButtonSl = value; - OnPropertyChanged(); - } - } - - private Key _rightButtonSr; - public Key RightButtonSr - { - get => _rightButtonSr; - set - { - _rightButtonSr = value; - OnPropertyChanged(); - } - } - - private Key _buttonZr; - public Key ButtonZr - { - get => _buttonZr; - set - { - _buttonZr = value; - OnPropertyChanged(); - } - } + [ObservableProperty] private Key _dpadUp; + [ObservableProperty] private Key _dpadDown; + [ObservableProperty] private Key _dpadLeft; + [ObservableProperty] private Key _dpadRight; + + [ObservableProperty] private Key _buttonMinus; + [ObservableProperty] private Key _buttonPlus; + + [ObservableProperty] private Key _buttonA; + [ObservableProperty] private Key _buttonB; + [ObservableProperty] private Key _buttonX; + [ObservableProperty] private Key _buttonY; + + [ObservableProperty] private Key _buttonL; + [ObservableProperty] private Key _buttonR; + + [ObservableProperty] private Key _buttonZl; + [ObservableProperty] private Key _buttonZr; + + [ObservableProperty] private Key _leftButtonSl; + [ObservableProperty] private Key _leftButtonSr; + + [ObservableProperty] private Key _rightButtonSl; + [ObservableProperty] private Key _rightButtonSr; public KeyboardInputConfig(InputConfig config) { diff --git a/src/Ryujinx/UI/Models/ModModel.cs b/src/Ryujinx/UI/Models/ModModel.cs index ee28ca5f5..3b3cbbbc9 100644 --- a/src/Ryujinx/UI/Models/ModModel.cs +++ b/src/Ryujinx/UI/Models/ModModel.cs @@ -1,26 +1,22 @@ +using CommunityToolkit.Mvvm.ComponentModel; using Ryujinx.Ava.UI.ViewModels; -using System.IO; +using System.Globalization; namespace Ryujinx.Ava.UI.Models { - public class ModModel : BaseModel + public partial class ModModel : BaseModel { - private bool _enabled; - - public bool Enabled - { - get => _enabled; - set - { - _enabled = value; - OnPropertyChanged(); - } - } + [ObservableProperty] private bool _enabled; public bool InSd { get; } public string Path { get; } public string Name { get; } + public string FormattedName => + InSd && ulong.TryParse(Name, NumberStyles.HexNumber, null, out ulong applicationId) + ? $"Atmosphère: {RyujinxApp.MainWindow.ApplicationLibrary.GetNameForApplicationId(applicationId)}" + : Name; + public ModModel(string path, string name, bool enabled, bool inSd) { Path = path; diff --git a/src/Ryujinx/UI/Models/ProfileImageModel.cs b/src/Ryujinx/UI/Models/ProfileImageModel.cs index 99365dfc7..f12aa7bd4 100644 --- a/src/Ryujinx/UI/Models/ProfileImageModel.cs +++ b/src/Ryujinx/UI/Models/ProfileImageModel.cs @@ -1,9 +1,10 @@ using Avalonia.Media; +using CommunityToolkit.Mvvm.ComponentModel; using Ryujinx.Ava.UI.ViewModels; namespace Ryujinx.Ava.UI.Models { - public class ProfileImageModel : BaseModel + public partial class ProfileImageModel : BaseModel { public ProfileImageModel(string name, byte[] data) { @@ -14,19 +15,6 @@ namespace Ryujinx.Ava.UI.Models public string Name { get; set; } public byte[] Data { get; set; } - private SolidColorBrush _backgroundColor = new(Colors.White); - - public SolidColorBrush BackgroundColor - { - get - { - return _backgroundColor; - } - set - { - _backgroundColor = value; - OnPropertyChanged(); - } - } + [ObservableProperty] private SolidColorBrush _backgroundColor = new(Colors.White); } } diff --git a/src/Ryujinx/UI/Models/SaveModel.cs b/src/Ryujinx/UI/Models/SaveModel.cs index 81be5ee93..d50aabc4e 100644 --- a/src/Ryujinx/UI/Models/SaveModel.cs +++ b/src/Ryujinx/UI/Models/SaveModel.cs @@ -2,11 +2,9 @@ using Gommon; using LibHac.Fs; using LibHac.Ncm; using Ryujinx.Ava.UI.ViewModels; -using Ryujinx.Ava.UI.Windows; using Ryujinx.Ava.Utilities; using Ryujinx.Ava.Utilities.AppLibrary; using Ryujinx.HLE.FileSystem; -using System; using System.IO; using System.Linq; using System.Threading.Tasks; diff --git a/src/Ryujinx/UI/Models/TempProfile.cs b/src/Ryujinx/UI/Models/TempProfile.cs index 659092e6d..51e86fb7f 100644 --- a/src/Ryujinx/UI/Models/TempProfile.cs +++ b/src/Ryujinx/UI/Models/TempProfile.cs @@ -1,28 +1,18 @@ +using CommunityToolkit.Mvvm.ComponentModel; using Ryujinx.Ava.UI.ViewModels; using Ryujinx.HLE.HOS.Services.Account.Acc; using System; namespace Ryujinx.Ava.UI.Models { - public class TempProfile : BaseModel + public partial class TempProfile : BaseModel { - private readonly UserProfile _profile; - private byte[] _image; - private string _name = String.Empty; + [ObservableProperty] private byte[] _image; + [ObservableProperty] private string _name = String.Empty; private UserId _userId; public static uint MaxProfileNameLength => 0x20; - public byte[] Image - { - get => _image; - set - { - _image = value; - OnPropertyChanged(); - } - } - public UserId UserId { get => _userId; @@ -36,21 +26,9 @@ namespace Ryujinx.Ava.UI.Models public string UserIdString => _userId.ToString(); - public string Name - { - get => _name; - set - { - _name = value; - OnPropertyChanged(); - } - } - public TempProfile(UserProfile profile) { - _profile = profile; - - if (_profile != null) + if (profile != null) { Image = profile.Image; Name = profile.Name; diff --git a/src/Ryujinx/UI/Models/UserProfile.cs b/src/Ryujinx/UI/Models/UserProfile.cs index 7aa365e36..f14e74d07 100644 --- a/src/Ryujinx/UI/Models/UserProfile.cs +++ b/src/Ryujinx/UI/Models/UserProfile.cs @@ -1,5 +1,6 @@ using Avalonia; using Avalonia.Media; +using CommunityToolkit.Mvvm.ComponentModel; using Ryujinx.Ava.UI.Controls; using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.Views.User; @@ -8,65 +9,15 @@ using Profile = Ryujinx.HLE.HOS.Services.Account.Acc.UserProfile; namespace Ryujinx.Ava.UI.Models { - public class UserProfile : BaseModel + public partial class UserProfile : BaseModel { private readonly Profile _profile; private readonly NavigationDialogHost _owner; - private byte[] _image; - private string _name; - private UserId _userId; - private bool _isPointerOver; - private IBrush _backgroundColor; - - public byte[] Image - { - get => _image; - set - { - _image = value; - OnPropertyChanged(); - } - } - - public UserId UserId - { - get => _userId; - set - { - _userId = value; - OnPropertyChanged(); - } - } - - public string Name - { - get => _name; - set - { - _name = value; - OnPropertyChanged(); - } - } - - public bool IsPointerOver - { - get => _isPointerOver; - set - { - _isPointerOver = value; - OnPropertyChanged(); - } - } - - public IBrush BackgroundColor - { - get => _backgroundColor; - set - { - _backgroundColor = value; - OnPropertyChanged(); - } - } + [ObservableProperty] private byte[] _image; + [ObservableProperty] private string _name; + [ObservableProperty] private UserId _userId; + [ObservableProperty] private bool _isPointerOver; + [ObservableProperty] private IBrush _backgroundColor; public UserProfile(Profile profile, NavigationDialogHost owner) { diff --git a/src/Ryujinx/UI/Renderer/EmbeddedWindow.cs b/src/Ryujinx/UI/Renderer/EmbeddedWindow.cs index eea9be283..21c39967f 100644 --- a/src/Ryujinx/UI/Renderer/EmbeddedWindow.cs +++ b/src/Ryujinx/UI/Renderer/EmbeddedWindow.cs @@ -1,6 +1,5 @@ using Avalonia; using Avalonia.Controls; -using Avalonia.Input; using Avalonia.Platform; using Ryujinx.Ava.Utilities.Configuration; using Ryujinx.Common.Configuration; diff --git a/src/Ryujinx/UI/Renderer/EmbeddedWindowMetal.cs b/src/Ryujinx/UI/Renderer/EmbeddedWindowMetal.cs index eaf6f7bdf..9e92d9289 100644 --- a/src/Ryujinx/UI/Renderer/EmbeddedWindowMetal.cs +++ b/src/Ryujinx/UI/Renderer/EmbeddedWindowMetal.cs @@ -1,3 +1,4 @@ +using Ryujinx.Common.Helper; using SharpMetal.QuartzCore; using System; @@ -7,14 +8,12 @@ namespace Ryujinx.Ava.UI.Renderer { public CAMetalLayer CreateSurface() { - if (OperatingSystem.IsMacOS()) + if (OperatingSystem.IsMacOS() && RunningPlatform.IsArm) { return new CAMetalLayer(MetalLayer); } - else - { - throw new NotSupportedException(); - } + + throw new NotSupportedException($"Cannot create a {nameof(CAMetalLayer)} without being on ARM Mac."); } } } diff --git a/src/Ryujinx/UI/Renderer/RendererHost.cs b/src/Ryujinx/UI/Renderer/RendererHost.cs index 7dfec8d62..f755b6d70 100644 --- a/src/Ryujinx/UI/Renderer/RendererHost.cs +++ b/src/Ryujinx/UI/Renderer/RendererHost.cs @@ -43,19 +43,19 @@ namespace Ryujinx.Ava.UI.Renderer public RendererHost(string titleId) { - switch (TitleIDs.SelectGraphicsBackend(titleId, ConfigurationState.Instance.Graphics.GraphicsBackend)) - { - case GraphicsBackend.OpenGl: - EmbeddedWindow = new EmbeddedWindowOpenGL(); - break; - case GraphicsBackend.Metal: - EmbeddedWindow = new EmbeddedWindowMetal(); - break; - case GraphicsBackend.Vulkan: - EmbeddedWindow = new EmbeddedWindowVulkan(); - break; - } - + Focusable = true; + FlowDirection = FlowDirection.LeftToRight; + + EmbeddedWindow = +#pragma warning disable CS8509 + TitleIDs.SelectGraphicsBackend(titleId, ConfigurationState.Instance.Graphics.GraphicsBackend) switch +#pragma warning restore CS8509 + { + GraphicsBackend.OpenGl => new EmbeddedWindowOpenGL(), + GraphicsBackend.Metal => new EmbeddedWindowMetal(), + GraphicsBackend.Vulkan => new EmbeddedWindowVulkan(), + }; + string backendText = EmbeddedWindow switch { EmbeddedWindowVulkan => "Vulkan", diff --git a/src/Ryujinx/UI/ViewModels/ApplicationDataViewModel.cs b/src/Ryujinx/UI/ViewModels/ApplicationDataViewModel.cs new file mode 100644 index 000000000..9e0a3554a --- /dev/null +++ b/src/Ryujinx/UI/ViewModels/ApplicationDataViewModel.cs @@ -0,0 +1,26 @@ +using Gommon; +using Ryujinx.Ava.Common.Locale; +using Ryujinx.Ava.Utilities.AppLibrary; + +namespace Ryujinx.Ava.UI.ViewModels +{ + public class ApplicationDataViewModel : BaseModel + { + public ApplicationData AppData { get; } + + public ApplicationDataViewModel(ApplicationData appData) => AppData = appData; + + public string FormattedVersion => LocaleManager.Instance[LocaleKeys.GameListHeaderVersion].Format(AppData.Version); + public string FormattedDeveloper => LocaleManager.Instance[LocaleKeys.GameListHeaderDeveloper].Format(AppData.Developer); + + public string FormattedFileExtension => LocaleManager.Instance[LocaleKeys.GameListHeaderFileExtension].Format(AppData.FileExtension); + public string FormattedLastPlayed => LocaleManager.Instance[LocaleKeys.GameListHeaderLastPlayed].Format(AppData.LastPlayedString); + public string FormattedPlayTime => LocaleManager.Instance[LocaleKeys.GameListHeaderTimePlayed].Format(AppData.TimePlayedString); + public string FormattedFileSize => LocaleManager.Instance[LocaleKeys.GameListHeaderFileSize].Format(AppData.FileSizeString); + + public string FormattedLdnInfo => + $"{LocaleManager.Instance[LocaleKeys.GameListHeaderHostedGames].Format(AppData.GameCount)}" + + $"\n" + + $"{LocaleManager.Instance[LocaleKeys.GameListHeaderPlayerCount].Format(AppData.PlayerCount)}"; + } +} diff --git a/src/Ryujinx/UI/ViewModels/DlcSelectViewModel.cs b/src/Ryujinx/UI/ViewModels/DlcSelectViewModel.cs index d50d8249a..b486aa766 100644 --- a/src/Ryujinx/UI/ViewModels/DlcSelectViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/DlcSelectViewModel.cs @@ -14,9 +14,7 @@ namespace Ryujinx.Ava.UI.ViewModels public DlcSelectViewModel(ulong titleId, ApplicationLibrary appLibrary) { - _dlcs = appLibrary.DownloadableContents.Items - .Where(x => x.Dlc.TitleIdBase == titleId) - .Select(x => x.Dlc) + _dlcs = appLibrary.FindDlcsFor(titleId) .OrderBy(it => it.IsBundled ? 0 : 1) .ThenBy(it => it.TitleId) .ToArray(); diff --git a/src/Ryujinx/UI/ViewModels/DownloadableContentManagerViewModel.cs b/src/Ryujinx/UI/ViewModels/DownloadableContentManagerViewModel.cs index d1358e658..a16a06ff5 100644 --- a/src/Ryujinx/UI/ViewModels/DownloadableContentManagerViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/DownloadableContentManagerViewModel.cs @@ -1,5 +1,4 @@ using Avalonia.Collections; -using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Platform.Storage; using Avalonia.Threading; using CommunityToolkit.Mvvm.ComponentModel; @@ -9,13 +8,11 @@ using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Models; using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.Utilities.AppLibrary; -using Ryujinx.HLE.FileSystem; using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using System.Linq; using System.Threading.Tasks; -using Application = Avalonia.Application; namespace Ryujinx.Ava.UI.ViewModels { @@ -72,8 +69,7 @@ namespace Ryujinx.Ava.UI.ViewModels private void LoadDownloadableContents() { - IEnumerable<(DownloadableContentModel Dlc, bool IsEnabled)> dlcs = _applicationLibrary.DownloadableContents.Items - .Where(it => it.Dlc.TitleIdBase == _applicationData.IdBase); + (DownloadableContentModel Dlc, bool IsEnabled)[] dlcs = _applicationLibrary.FindDlcConfigurationFor(_applicationData.Id); bool hasBundledContent = false; foreach ((DownloadableContentModel dlc, bool isEnabled) in dlcs) diff --git a/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs b/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs index ea9047982..96da58b5d 100644 --- a/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs @@ -2,11 +2,13 @@ using Avalonia.Svg.Skia; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using FluentAvalonia.UI.Controls; -using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.Input; +using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Models.Input; using Ryujinx.Ava.UI.Views.Input; +using Ryujinx.Common.Utilities; using Ryujinx.UI.Views.Input; +using System.Drawing; namespace Ryujinx.Ava.UI.ViewModels.Input { @@ -72,6 +74,23 @@ namespace Ryujinx.Ava.UI.ViewModels.Input Visualizer = visualizer; model.NotifyChangesEvent += OnParentModelChanged; OnParentModelChanged(); + config.PropertyChanged += (_, args) => + { + if (args.PropertyName is nameof(Config.UseRainbowLed)) + { + if (Config is { UseRainbowLed: true, TurnOffLed: false, EnableLedChanging: true }) + Rainbow.Updated += (ref Color color) => ParentModel.SelectedGamepad.SetLed((uint)color.ToArgb()); + else + { + Rainbow.Reset(); + + if (Config.TurnOffLed) + ParentModel.SelectedGamepad.ClearLed(); + else + ParentModel.SelectedGamepad.SetLed(Config.LedColor.ToUInt32()); + } + } + }; Config = config; } diff --git a/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs b/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs index 3e26dab69..b324d39e8 100644 --- a/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs @@ -23,6 +23,7 @@ using Ryujinx.Input; using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Drawing; using System.IO; using System.Linq; using System.Text.Json; @@ -63,7 +64,13 @@ namespace Ryujinx.Ava.UI.ViewModels.Input get => _selectedGamepad; private set { + Rainbow.Reset(); + _selectedGamepad = value; + + if (ConfigViewModel is ControllerInputViewModel { Config.UseRainbowLed: true }) + Rainbow.Updated += (ref Color color) => _selectedGamepad.SetLed((uint)color.ToArgb()); + OnPropertiesChanged(nameof(HasLed), nameof(CanClearLed)); } } diff --git a/src/Ryujinx/UI/ViewModels/Input/LedInputViewModel.cs b/src/Ryujinx/UI/ViewModels/Input/LedInputViewModel.cs index a9d14d894..521b13859 100644 --- a/src/Ryujinx/UI/ViewModels/Input/LedInputViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/Input/LedInputViewModel.cs @@ -1,7 +1,10 @@ using Avalonia.Media; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; +using Humanizer; using Ryujinx.Ava.UI.Helpers; +using Ryujinx.Ava.Utilities.Configuration; +using System.Globalization; namespace Ryujinx.Ava.UI.ViewModels.Input { @@ -21,6 +24,19 @@ namespace Ryujinx.Ava.UI.ViewModels.Input [ObservableProperty] private bool _enableLedChanging; [ObservableProperty] private Color _ledColor; + + public string RainbowSpeedText => RainbowSpeed.ToString(CultureInfo.CurrentCulture).Truncate(4, string.Empty); + + public float RainbowSpeed + { + get => ConfigurationState.Instance.Hid.RainbowSpeed; + set + { + ConfigurationState.Instance.Hid.RainbowSpeed.Value = value; + OnPropertyChanged(); + OnPropertyChanged(nameof(RainbowSpeedText)); + } + } public bool ShowLedColorPicker => !TurnOffLed && !UseRainbowLed; diff --git a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs index 3a6fc8d2f..499eedc8d 100644 --- a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs @@ -349,6 +349,10 @@ namespace Ryujinx.Ava.UI.ViewModels } } + public bool HasCompatibilityEntry => SelectedApplication.HasPlayabilityInfo; + + public bool HasDlc => ApplicationLibrary.HasDlcs(SelectedApplication.Id); + public bool OpenUserSaveDirectoryEnabled => SelectedApplication.HasControlHolder && SelectedApplication.ControlHolder.Value.UserAccountSaveDataSize > 0; public bool OpenDeviceSaveDirectoryEnabled => SelectedApplication.HasControlHolder && SelectedApplication.ControlHolder.Value.DeviceSaveDataSize > 0; @@ -629,15 +633,15 @@ namespace Ryujinx.Ava.UI.ViewModels { return SortMode switch { - ApplicationSort.Title => LocaleManager.Instance[LocaleKeys.GameListHeaderApplication], - ApplicationSort.Developer => LocaleManager.Instance[LocaleKeys.GameListHeaderDeveloper], - ApplicationSort.LastPlayed => LocaleManager.Instance[LocaleKeys.GameListHeaderLastPlayed], - ApplicationSort.TotalTimePlayed => LocaleManager.Instance[LocaleKeys.GameListHeaderTimePlayed], - ApplicationSort.FileType => LocaleManager.Instance[LocaleKeys.GameListHeaderFileExtension], - ApplicationSort.FileSize => LocaleManager.Instance[LocaleKeys.GameListHeaderFileSize], - ApplicationSort.Path => LocaleManager.Instance[LocaleKeys.GameListHeaderPath], ApplicationSort.Favorite => LocaleManager.Instance[LocaleKeys.CommonFavorite], ApplicationSort.TitleId => LocaleManager.Instance[LocaleKeys.DlcManagerTableHeadingTitleIdLabel], + ApplicationSort.Title => LocaleManager.Instance[LocaleKeys.GameListHeaderApplication], + ApplicationSort.Developer => LocaleManager.Instance[LocaleKeys.GameListSortDeveloper], + ApplicationSort.LastPlayed => LocaleManager.Instance[LocaleKeys.GameListSortLastPlayed], + ApplicationSort.TotalTimePlayed => LocaleManager.Instance[LocaleKeys.GameListSortTimePlayed], + ApplicationSort.FileType => LocaleManager.Instance[LocaleKeys.GameListSortFileExtension], + ApplicationSort.FileSize => LocaleManager.Instance[LocaleKeys.GameListSortFileSize], + ApplicationSort.Path => LocaleManager.Instance[LocaleKeys.GameListSortPath], _ => string.Empty, }; } diff --git a/src/Ryujinx/UI/ViewModels/ModManagerViewModel.cs b/src/Ryujinx/UI/ViewModels/ModManagerViewModel.cs index 603d8f7c5..cda7e34cf 100644 --- a/src/Ryujinx/UI/ViewModels/ModManagerViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/ModManagerViewModel.cs @@ -7,6 +7,7 @@ using Gommon; using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Models; +using Ryujinx.Ava.Utilities.AppLibrary; using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; using Ryujinx.Common.Utilities; @@ -29,6 +30,7 @@ namespace Ryujinx.Ava.UI.ViewModels private string _search; private readonly ulong _applicationId; + private readonly ulong[] _installedDlcIds; private readonly IStorageProvider _storageProvider; private static readonly ModMetadataJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions()); @@ -61,18 +63,23 @@ namespace Ryujinx.Ava.UI.ViewModels get => string.Format(LocaleManager.Instance[LocaleKeys.ModWindowHeading], Mods.Count); } - public ModManagerViewModel(ulong applicationId) + public ModManagerViewModel(ulong applicationId, ulong applicationIdBase, ApplicationLibrary appLibrary) { _applicationId = applicationId; + _installedDlcIds = appLibrary.DownloadableContents.Keys + .Where(x => x.TitleIdBase == applicationIdBase) + .Select(x => x.TitleId) + .ToArray(); + _modJsonPath = Path.Combine(AppDataManager.GamesDirPath, applicationId.ToString("x16"), "mods.json"); _storageProvider = RyujinxApp.MainWindow.StorageProvider; - LoadMods(applicationId); + LoadMods(applicationId, _installedDlcIds); } - private void LoadMods(ulong applicationId) + private void LoadMods(ulong applicationId, ulong[] installedDlcIds) { Mods.Clear(); SelectedMods.Clear(); @@ -84,7 +91,7 @@ namespace Ryujinx.Ava.UI.ViewModels bool inSd = path == ModLoader.GetSdModsBasePath(); ModLoader.ModCache modCache = new(); - ModLoader.QueryContentsDir(modCache, new DirectoryInfo(Path.Combine(path, "contents")), applicationId); + ModLoader.QueryContentsDir(modCache, new DirectoryInfo(Path.Combine(path, "contents")), applicationId, _installedDlcIds); foreach (ModLoader.Mod mod in modCache.RomfsDirs) { @@ -278,7 +285,7 @@ namespace Ryujinx.Ava.UI.ViewModels File.Copy(file, file.Replace(directory.Parent.ToString(), destinationDir), true); } - LoadMods(_applicationId); + LoadMods(_applicationId, _installedDlcIds); } public async void Add() diff --git a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs index 5a73dd574..bd649602c 100644 --- a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs @@ -2,7 +2,7 @@ using Avalonia.Collections; using Avalonia.Controls; using Avalonia.Threading; using CommunityToolkit.Mvvm.ComponentModel; -using Gommon; +using CommunityToolkit.Mvvm.Input; using LibHac.Tools.FsSystem; using Ryujinx.Audio.Backends.OpenAL; using Ryujinx.Audio.Backends.SDL2; @@ -16,6 +16,7 @@ using Ryujinx.Ava.Utilities.Configuration.System; using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration.Multiplayer; using Ryujinx.Common.GraphicsDriver; +using Ryujinx.Common.Helper; using Ryujinx.Common.Logging; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Vulkan; @@ -27,8 +28,6 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Net.NetworkInformation; -using System.Runtime.InteropServices; -using System.Text.RegularExpressions; using System.Threading.Tasks; using TimeZone = Ryujinx.Ava.UI.Models.TimeZone; @@ -115,10 +114,6 @@ namespace Ryujinx.Ava.UI.ViewModels public bool IsOpenGLAvailable => !OperatingSystem.IsMacOS(); - public bool IsAppleSiliconMac => OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture == Architecture.Arm64; - - public bool IsMacOS => OperatingSystem.IsMacOS(); - public bool EnableDiscordIntegration { get; set; } public bool CheckUpdatesOnStart { get; set; } public bool ShowConfirmExit { get; set; } @@ -200,7 +195,7 @@ namespace Ryujinx.Ava.UI.ViewModels public bool EnableTextureRecompression { get; set; } public bool EnableMacroHLE { get; set; } public bool EnableColorSpacePassthrough { get; set; } - public bool ColorSpacePassthroughAvailable => IsMacOS; + public bool ColorSpacePassthroughAvailable => RunningPlatform.IsMacOS; public bool EnableFileLog { get; set; } public bool EnableStub { get; set; } public bool EnableInfo { get; set; } @@ -296,6 +291,8 @@ namespace Ryujinx.Ava.UI.ViewModels } } + [ObservableProperty] private bool _matchSystemTime; + public DateTimeOffset CurrentDate { get; set; } public TimeSpan CurrentTime { get; set; } @@ -330,9 +327,6 @@ namespace Ryujinx.Ava.UI.ViewModels } } - [GeneratedRegex("Ryujinx-[0-9a-f]{8}")] - private static partial Regex LdnPassphraseRegex(); - public bool IsInvalidLdnPassphraseVisible { get; set; } public SettingsViewModel(VirtualFileSystem virtualFileSystem, ContentManager contentManager) : this() @@ -414,17 +408,6 @@ namespace Ryujinx.Ava.UI.ViewModels Dispatcher.UIThread.Post(() => OnPropertyChanged(nameof(PreferredGpuIndex))); } - public void MatchSystemTime() - { - (DateTimeOffset dto, TimeSpan timeOfDay) = DateTimeOffset.Now.Extract(); - - CurrentDate = dto; - CurrentTime = timeOfDay; - - OnPropertyChanged(nameof(CurrentDate)); - OnPropertyChanged(nameof(CurrentTime)); - } - public async Task LoadTimeZones() { _timeZoneContentManager = new TimeZoneContentManager(); @@ -470,7 +453,7 @@ namespace Ryujinx.Ava.UI.ViewModels private bool ValidateLdnPassphrase(string passphrase) { - return string.IsNullOrEmpty(passphrase) || (passphrase.Length == 16 && LdnPassphraseRegex().IsMatch(passphrase)); + return string.IsNullOrEmpty(passphrase) || (passphrase.Length == 16 && Patterns.LdnPassphrase.IsMatch(passphrase)); } public void ValidateAndSetTimeZone(string location) @@ -526,7 +509,9 @@ namespace Ryujinx.Ava.UI.ViewModels CurrentDate = currentDateTime.Date; CurrentTime = currentDateTime.TimeOfDay; - EnableCustomVSyncInterval = config.Graphics.EnableCustomVSyncInterval.Value; + MatchSystemTime = config.System.MatchSystemTime; + + EnableCustomVSyncInterval = config.Graphics.EnableCustomVSyncInterval; CustomVSyncInterval = config.Graphics.CustomVSyncInterval; VSyncMode = config.Graphics.VSyncMode; EnableFsIntegrityChecks = config.System.EnableFsIntegrityChecks; @@ -631,6 +616,7 @@ namespace Ryujinx.Ava.UI.ViewModels config.System.TimeZone.Value = TimeZone; } + config.System.MatchSystemTime.Value = MatchSystemTime; config.System.SystemTimeOffset.Value = Convert.ToInt64((CurrentDate.ToUnixTimeSeconds() + CurrentTime.TotalSeconds) - DateTimeOffset.Now.ToUnixTimeSeconds()); config.System.EnableFsIntegrityChecks.Value = EnableFsIntegrityChecks; config.System.DramSize.Value = DramSize; @@ -734,6 +720,25 @@ namespace Ryujinx.Ava.UI.ViewModels CloseWindow?.Invoke(); } + [ObservableProperty] private bool _wantsToReset; + + public AsyncRelayCommand ResetButton => Commands.Create(async () => + { + if (!WantsToReset) return; + + CloseWindow?.Invoke(); + ConfigurationState.Instance.LoadDefault(); + ConfigurationState.Instance.ToFileFormat().SaveConfig(Program.ConfigurationPath); + RyujinxApp.MainWindow.LoadApplications(); + + await ContentDialogHelper.CreateInfoDialog( + $"Your {RyujinxApp.FullAppName} configuration has been reset.", + "", + string.Empty, + LocaleManager.Instance[LocaleKeys.SettingsButtonClose], + "Configuration Reset"); + }); + public void CancelButton() { RevertIfNotSaved(); diff --git a/src/Ryujinx/UI/ViewModels/TitleUpdateViewModel.cs b/src/Ryujinx/UI/ViewModels/TitleUpdateViewModel.cs index aaafc3913..2b88aceed 100644 --- a/src/Ryujinx/UI/ViewModels/TitleUpdateViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/TitleUpdateViewModel.cs @@ -41,8 +41,7 @@ namespace Ryujinx.Ava.UI.ViewModels private void LoadUpdates() { - IEnumerable<(TitleUpdateModel TitleUpdate, bool IsSelected)> updates = ApplicationLibrary.TitleUpdates.Items - .Where(it => it.TitleUpdate.TitleIdBase == ApplicationData.IdBase); + (TitleUpdateModel TitleUpdate, bool IsSelected)[] updates = ApplicationLibrary.FindUpdateConfigurationFor(ApplicationData.Id); bool hasBundledContent = false; SelectedUpdate = new TitleUpdateViewModelNoUpdate(); diff --git a/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml.cs b/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml.cs index e7221bac4..d04085a89 100644 --- a/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml.cs +++ b/src/Ryujinx/UI/Views/Input/ControllerInputView.axaml.cs @@ -4,7 +4,6 @@ using Avalonia.Controls.Primitives; using Avalonia.Input; using Avalonia.Interactivity; using Avalonia.LogicalTree; -using FluentAvalonia.UI.Controls; using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.ViewModels.Input; using Ryujinx.Common.Configuration.Hid.Controller; diff --git a/src/Ryujinx/UI/Views/Input/LedInputView.axaml b/src/Ryujinx/UI/Views/Input/LedInputView.axaml index 39e464224..c6319f424 100644 --- a/src/Ryujinx/UI/Views/Input/LedInputView.axaml +++ b/src/Ryujinx/UI/Views/Input/LedInputView.axaml @@ -11,7 +11,7 @@ x:Class="Ryujinx.UI.Views.Input.LedInputView"> - + - + + + + + + - + CompatibilityList.Show()); UpdateMenuItem.Command = Commands.Create(async () => { @@ -134,7 +133,12 @@ namespace Ryujinx.Ava.UI.Views.Main { Window.SettingsWindow = new(Window.VirtualFileSystem, Window.ContentManager); + Rainbow.Enable(); + await Window.SettingsWindow.ShowDialog(Window); + + Rainbow.Disable(); + Rainbow.Reset(); Window.SettingsWindow = null; diff --git a/src/Ryujinx/UI/Views/Main/MainViewControls.axaml b/src/Ryujinx/UI/Views/Main/MainViewControls.axaml index cdc66a138..db557b417 100644 --- a/src/Ryujinx/UI/Views/Main/MainViewControls.axaml +++ b/src/Ryujinx/UI/Views/Main/MainViewControls.axaml @@ -113,37 +113,37 @@ Tag="TitleId" /> diff --git a/src/Ryujinx/UI/Views/Settings/SettingsCPUView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsCPUView.axaml index 83f908a9c..62f087510 100644 --- a/src/Ryujinx/UI/Views/Settings/SettingsCPUView.axaml +++ b/src/Ryujinx/UI/Views/Settings/SettingsCPUView.axaml @@ -6,6 +6,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup" xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels" + xmlns:helper="clr-namespace:Ryujinx.Common.Helper;assembly=Ryujinx.Common" mc:Ignorable="d" x:DataType="viewModels:SettingsViewModel"> @@ -69,7 +70,7 @@ diff --git a/src/Ryujinx/UI/Views/Settings/SettingsGraphicsView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsGraphicsView.axaml index a2559f393..42515a4e9 100644 --- a/src/Ryujinx/UI/Views/Settings/SettingsGraphicsView.axaml +++ b/src/Ryujinx/UI/Views/Settings/SettingsGraphicsView.axaml @@ -8,6 +8,7 @@ xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia" xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup" xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels" + xmlns:helper="clr-namespace:Ryujinx.Common.Helper;assembly=Ryujinx.Common" Design.Width="1000" mc:Ignorable="d" x:DataType="viewModels:SettingsViewModel"> @@ -48,7 +49,7 @@ - + diff --git a/src/Ryujinx/UI/Views/Settings/SettingsSystemView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsSystemView.axaml index d05f3b7bf..aa7144cf1 100644 --- a/src/Ryujinx/UI/Views/Settings/SettingsSystemView.axaml +++ b/src/Ryujinx/UI/Views/Settings/SettingsSystemView.axaml @@ -170,7 +170,8 @@ ToolTip.Tip="{ext:Locale TimeTooltip}" Width="250"/> @@ -181,17 +182,21 @@ - + Text="{ext:Locale SettingsTabSystemSystemTimeMatch}" + ToolTip.Tip="{ext:Locale MatchTimeTooltip}" + Width="250"/> + ViewModel.MatchSystemTime(); } } diff --git a/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml.cs b/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml.cs index 9707b3193..6d0d69e52 100644 --- a/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml.cs +++ b/src/Ryujinx/UI/Views/Settings/SettingsUIView.axaml.cs @@ -2,7 +2,6 @@ using Avalonia.Collections; using Avalonia.Controls; using Avalonia.Interactivity; using Avalonia.Platform.Storage; -using Avalonia.VisualTree; using Gommon; using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.ViewModels; diff --git a/src/Ryujinx/UI/Windows/CheatWindow.axaml.cs b/src/Ryujinx/UI/Windows/CheatWindow.axaml.cs index e0ba9e419..a9767bcca 100644 --- a/src/Ryujinx/UI/Windows/CheatWindow.axaml.cs +++ b/src/Ryujinx/UI/Windows/CheatWindow.axaml.cs @@ -64,7 +64,7 @@ namespace Ryujinx.Ava.UI.Windows ModLoader.ModCache mods = new(); - ModLoader.QueryContentsDir(mods, new DirectoryInfo(Path.Combine(modsBasePath, "contents")), titleIdValue); + ModLoader.QueryContentsDir(mods, new DirectoryInfo(Path.Combine(modsBasePath, "contents")), titleIdValue, []); string currentCheatFile = string.Empty; string buildId = string.Empty; diff --git a/src/Ryujinx/UI/Windows/DownloadableContentManagerWindow.axaml.cs b/src/Ryujinx/UI/Windows/DownloadableContentManagerWindow.axaml.cs index 777b462b5..c0897f910 100644 --- a/src/Ryujinx/UI/Windows/DownloadableContentManagerWindow.axaml.cs +++ b/src/Ryujinx/UI/Windows/DownloadableContentManagerWindow.axaml.cs @@ -2,8 +2,6 @@ using Avalonia.Controls; using Avalonia.Interactivity; using Avalonia.Styling; using FluentAvalonia.UI.Controls; -using LibHac.Tools.FsSystem.NcaUtils; -using Ryujinx.Ava.Common; using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Models; using Ryujinx.Ava.UI.ViewModels; diff --git a/src/Ryujinx/UI/Windows/MainWindow.axaml.cs b/src/Ryujinx/UI/Windows/MainWindow.axaml.cs index 14ec80019..669e338df 100644 --- a/src/Ryujinx/UI/Windows/MainWindow.axaml.cs +++ b/src/Ryujinx/UI/Windows/MainWindow.axaml.cs @@ -33,7 +33,6 @@ using System; using System.Collections.Generic; using System.Linq; using System.Reactive.Linq; -using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Threading; using System.Threading.Tasks; @@ -303,7 +302,7 @@ namespace Ryujinx.Ava.UI.Windows LinuxHelper.RecommendedVmMaxMapCount); UserResult response = await ContentDialogHelper.ShowTextDialog( - $"Ryujinx - {LocaleManager.Instance[LocaleKeys.LinuxVmMaxMapCountDialogTitle]}", + RyujinxApp.FormatTitle(LocaleKeys.LinuxVmMaxMapCountDialogTitle, false), LocaleManager.Instance[LocaleKeys.LinuxVmMaxMapCountDialogTextPrimary], LocaleManager.Instance[LocaleKeys.LinuxVmMaxMapCountDialogTextSecondary], LocaleManager.Instance[LocaleKeys.LinuxVmMaxMapCountDialogButtonUntilRestart], diff --git a/src/Ryujinx/UI/Windows/ModManagerWindow.axaml b/src/Ryujinx/UI/Windows/ModManagerWindow.axaml index a8fd3a2e7..b50ea2c8e 100644 --- a/src/Ryujinx/UI/Windows/ModManagerWindow.axaml +++ b/src/Ryujinx/UI/Windows/ModManagerWindow.axaml @@ -81,7 +81,7 @@ MaxLines="2" TextWrapping="Wrap" TextTrimming="CharacterEllipsis" - Text="{Binding Name}" /> + Text="{Binding FormattedName}" /> - -