From f76a97c976d2de996b3941791e2ea16e25a57d69 Mon Sep 17 00:00:00 2001 From: Keaton Date: Mon, 21 Oct 2024 23:16:41 -0500 Subject: [PATCH] Replace 'Expand DRAM' option with dropdown menu (#32) Allows to use mods that require a larger memory pool to allocate from. --- .../Collections/IntervalTree.cs | 2 +- src/Ryujinx.Common/Hash128.cs | 208 ++++++++++++++++-- src/Ryujinx.Common/Utilities/BitUtils.cs | 4 +- .../H264/H264BitStreamWriter.cs | 2 +- .../OffsetCalculator.cs | 2 +- src/Ryujinx.HLE/FileSystem/ContentManager.cs | 6 +- .../HOS/Kernel/Common/KSystemControl.cs | 5 +- .../HOS/Kernel/Common/MemoryArrange.cs | 1 + .../HOS/Kernel/Common/MemorySize.cs | 1 + src/Ryujinx.HLE/MemoryConfiguration.cs | 14 +- .../HeadlessDynamicTextInputHandler.cs | 2 +- src/Ryujinx.Headless.SDL2/Options.cs | 5 +- src/Ryujinx.Headless.SDL2/Program.cs | 2 +- src/Ryujinx.Input.SDL2/SDL2Gamepad.cs | 6 +- .../Configuration/ConfigurationFileFormat.cs | 5 +- .../Configuration/ConfigurationState.cs | 22 +- .../DiscordIntegrationModule.cs | 8 +- .../Helper/SetupValidator.cs | 1 - src/Ryujinx.UI.Common/Helper/TitleHelper.cs | 2 +- .../Helper/TitleUpdatesHelper.cs | 7 +- .../SystemInfo/SystemInfo.cs | 4 +- src/Ryujinx/App.axaml.cs | 4 +- src/Ryujinx/AppHost.cs | 10 +- src/Ryujinx/Assets/Locales/ar_SA.json | 6 +- src/Ryujinx/Assets/Locales/de_DE.json | 6 +- src/Ryujinx/Assets/Locales/el_GR.json | 6 +- src/Ryujinx/Assets/Locales/en_US.json | 6 +- src/Ryujinx/Assets/Locales/es_ES.json | 6 +- src/Ryujinx/Assets/Locales/fr_FR.json | 6 +- src/Ryujinx/Assets/Locales/he_IL.json | 6 +- src/Ryujinx/Assets/Locales/it_IT.json | 6 +- src/Ryujinx/Assets/Locales/ja_JP.json | 6 +- src/Ryujinx/Assets/Locales/ko_KR.json | 6 +- src/Ryujinx/Assets/Locales/pl_PL.json | 6 +- src/Ryujinx/Assets/Locales/pt_BR.json | 6 +- src/Ryujinx/Assets/Locales/ru_RU.json | 6 +- src/Ryujinx/Assets/Locales/th_TH.json | 6 +- src/Ryujinx/Assets/Locales/tr_TR.json | 6 +- src/Ryujinx/Assets/Locales/uk_UA.json | 6 +- src/Ryujinx/Assets/Locales/zh_CN.json | 6 +- src/Ryujinx/Assets/Locales/zh_TW.json | 6 +- src/Ryujinx/Common/Locale/LocaleExtension.cs | 3 +- src/Ryujinx/Common/Locale/LocaleManager.cs | 4 +- src/Ryujinx/Program.cs | 18 +- .../Applet/AvaloniaDynamicTextInputHandler.cs | 2 +- .../Controls/ApplicationContextMenu.axaml.cs | 2 +- src/Ryujinx/UI/Helpers/ContentDialogHelper.cs | 10 +- src/Ryujinx/UI/Helpers/UserErrorDialog.cs | 4 +- .../UI/ViewModels/Input/InputViewModel.cs | 2 +- .../UI/ViewModels/MainWindowViewModel.cs | 2 +- .../UI/ViewModels/SettingsViewModel.cs | 7 +- .../UI/Views/Main/MainMenuBarView.axaml.cs | 7 +- .../Views/Settings/SettingsSystemView.axaml | 35 ++- src/Ryujinx/UI/Windows/MainWindow.axaml.cs | 7 +- 54 files changed, 416 insertions(+), 118 deletions(-) diff --git a/src/Ryujinx.Common/Collections/IntervalTree.cs b/src/Ryujinx.Common/Collections/IntervalTree.cs index c9bfe0e46..f804bca91 100644 --- a/src/Ryujinx.Common/Collections/IntervalTree.cs +++ b/src/Ryujinx.Common/Collections/IntervalTree.cs @@ -492,7 +492,7 @@ internal IntervalTreeNode(TKey start, TKey end, TValue value, IntervalTreeNode(start, end, value) ]; + Values = [new RangeNode(start, end, value)]; Parent = parent; } } diff --git a/src/Ryujinx.Common/Hash128.cs b/src/Ryujinx.Common/Hash128.cs index 69ab9f76e..baee3e7d2 100644 --- a/src/Ryujinx.Common/Hash128.cs +++ b/src/Ryujinx.Common/Hash128.cs @@ -4,8 +4,8 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using System.Runtime.Intrinsics.X86; using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; // ReSharper disable InconsistentNaming namespace Ryujinx.Common @@ -67,18 +67,198 @@ public struct Hash128(ulong low, ulong high) : IEquatable private static ReadOnlySpan Xxh3KSecret => [ - 0xb8, 0xfe, 0x6c, 0x39, 0x23, 0xa4, 0x4b, 0xbe, 0x7c, 0x01, 0x81, 0x2c, 0xf7, 0x21, 0xad, 0x1c, - 0xde, 0xd4, 0x6d, 0xe9, 0x83, 0x90, 0x97, 0xdb, 0x72, 0x40, 0xa4, 0xa4, 0xb7, 0xb3, 0x67, 0x1f, - 0xcb, 0x79, 0xe6, 0x4e, 0xcc, 0xc0, 0xe5, 0x78, 0x82, 0x5a, 0xd0, 0x7d, 0xcc, 0xff, 0x72, 0x21, - 0xb8, 0x08, 0x46, 0x74, 0xf7, 0x43, 0x24, 0x8e, 0xe0, 0x35, 0x90, 0xe6, 0x81, 0x3a, 0x26, 0x4c, - 0x3c, 0x28, 0x52, 0xbb, 0x91, 0xc3, 0x00, 0xcb, 0x88, 0xd0, 0x65, 0x8b, 0x1b, 0x53, 0x2e, 0xa3, - 0x71, 0x64, 0x48, 0x97, 0xa2, 0x0d, 0xf9, 0x4e, 0x38, 0x19, 0xef, 0x46, 0xa9, 0xde, 0xac, 0xd8, - 0xa8, 0xfa, 0x76, 0x3f, 0xe3, 0x9c, 0x34, 0x3f, 0xf9, 0xdc, 0xbb, 0xc7, 0xc7, 0x0b, 0x4f, 0x1d, - 0x8a, 0x51, 0xe0, 0x4b, 0xcd, 0xb4, 0x59, 0x31, 0xc8, 0x9f, 0x7e, 0xc9, 0xd9, 0x78, 0x73, 0x64, - 0xea, 0xc5, 0xac, 0x83, 0x34, 0xd3, 0xeb, 0xc3, 0xc5, 0x81, 0xa0, 0xff, 0xfa, 0x13, 0x63, 0xeb, - 0x17, 0x0d, 0xdd, 0x51, 0xb7, 0xf0, 0xda, 0x49, 0xd3, 0x16, 0x55, 0x26, 0x29, 0xd4, 0x68, 0x9e, - 0x2b, 0x16, 0xbe, 0x58, 0x7d, 0x47, 0xa1, 0xfc, 0x8f, 0xf8, 0xb8, 0xd1, 0x7a, 0xd0, 0x31, 0xce, - 0x45, 0xcb, 0x3a, 0x8f, 0x95, 0x16, 0x04, 0x28, 0xaf, 0xd7, 0xfb, 0xca, 0xbb, 0x4b, 0x40, 0x7e + 0xb8, + 0xfe, + 0x6c, + 0x39, + 0x23, + 0xa4, + 0x4b, + 0xbe, + 0x7c, + 0x01, + 0x81, + 0x2c, + 0xf7, + 0x21, + 0xad, + 0x1c, + 0xde, + 0xd4, + 0x6d, + 0xe9, + 0x83, + 0x90, + 0x97, + 0xdb, + 0x72, + 0x40, + 0xa4, + 0xa4, + 0xb7, + 0xb3, + 0x67, + 0x1f, + 0xcb, + 0x79, + 0xe6, + 0x4e, + 0xcc, + 0xc0, + 0xe5, + 0x78, + 0x82, + 0x5a, + 0xd0, + 0x7d, + 0xcc, + 0xff, + 0x72, + 0x21, + 0xb8, + 0x08, + 0x46, + 0x74, + 0xf7, + 0x43, + 0x24, + 0x8e, + 0xe0, + 0x35, + 0x90, + 0xe6, + 0x81, + 0x3a, + 0x26, + 0x4c, + 0x3c, + 0x28, + 0x52, + 0xbb, + 0x91, + 0xc3, + 0x00, + 0xcb, + 0x88, + 0xd0, + 0x65, + 0x8b, + 0x1b, + 0x53, + 0x2e, + 0xa3, + 0x71, + 0x64, + 0x48, + 0x97, + 0xa2, + 0x0d, + 0xf9, + 0x4e, + 0x38, + 0x19, + 0xef, + 0x46, + 0xa9, + 0xde, + 0xac, + 0xd8, + 0xa8, + 0xfa, + 0x76, + 0x3f, + 0xe3, + 0x9c, + 0x34, + 0x3f, + 0xf9, + 0xdc, + 0xbb, + 0xc7, + 0xc7, + 0x0b, + 0x4f, + 0x1d, + 0x8a, + 0x51, + 0xe0, + 0x4b, + 0xcd, + 0xb4, + 0x59, + 0x31, + 0xc8, + 0x9f, + 0x7e, + 0xc9, + 0xd9, + 0x78, + 0x73, + 0x64, + 0xea, + 0xc5, + 0xac, + 0x83, + 0x34, + 0xd3, + 0xeb, + 0xc3, + 0xc5, + 0x81, + 0xa0, + 0xff, + 0xfa, + 0x13, + 0x63, + 0xeb, + 0x17, + 0x0d, + 0xdd, + 0x51, + 0xb7, + 0xf0, + 0xda, + 0x49, + 0xd3, + 0x16, + 0x55, + 0x26, + 0x29, + 0xd4, + 0x68, + 0x9e, + 0x2b, + 0x16, + 0xbe, + 0x58, + 0x7d, + 0x47, + 0xa1, + 0xfc, + 0x8f, + 0xf8, + 0xb8, + 0xd1, + 0x7a, + 0xd0, + 0x31, + 0xce, + 0x45, + 0xcb, + 0x3a, + 0x8f, + 0x95, + 0x16, + 0x04, + 0x28, + 0xaf, + 0xd7, + 0xfb, + 0xca, + 0xbb, + 0x4b, + 0x40, + 0x7e ]; [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -551,6 +731,6 @@ private static Hash128 Xxh3128bitsInternal(ReadOnlySpan input, ReadOnlySpa }; } -#endregion + #endregion } } diff --git a/src/Ryujinx.Common/Utilities/BitUtils.cs b/src/Ryujinx.Common/Utilities/BitUtils.cs index 3277b0f82..b9dae2e53 100644 --- a/src/Ryujinx.Common/Utilities/BitUtils.cs +++ b/src/Ryujinx.Common/Utilities/BitUtils.cs @@ -7,10 +7,10 @@ public static class BitUtils public static T AlignUp(T value, T size) where T : IBinaryInteger => (value + (size - T.One)) & -size; - public static T AlignDown(T value, T size) where T : IBinaryInteger + public static T AlignDown(T value, T size) where T : IBinaryInteger => value & -size; - public static T DivRoundUp(T value, T dividend) where T : IBinaryInteger + public static T DivRoundUp(T value, T dividend) where T : IBinaryInteger => (value + (dividend - T.One)) / dividend; public static int Pow2RoundDown(int value) => BitOperations.IsPow2(value) ? value : Pow2RoundUp(value) >> 1; diff --git a/src/Ryujinx.Graphics.Nvdec.FFmpeg/H264/H264BitStreamWriter.cs b/src/Ryujinx.Graphics.Nvdec.FFmpeg/H264/H264BitStreamWriter.cs index 28ea47104..5cb7a7234 100644 --- a/src/Ryujinx.Graphics.Nvdec.FFmpeg/H264/H264BitStreamWriter.cs +++ b/src/Ryujinx.Graphics.Nvdec.FFmpeg/H264/H264BitStreamWriter.cs @@ -72,7 +72,7 @@ public void End() Flush(); } - public readonly Span AsSpan() + public readonly Span AsSpan() => new Span(workBuffer)[.._offset]; public void WriteU(uint value, int valueSize) => WriteBits((int)value, valueSize); diff --git a/src/Ryujinx.Graphics.Texture/OffsetCalculator.cs b/src/Ryujinx.Graphics.Texture/OffsetCalculator.cs index da357f57e..e519341e6 100644 --- a/src/Ryujinx.Graphics.Texture/OffsetCalculator.cs +++ b/src/Ryujinx.Graphics.Texture/OffsetCalculator.cs @@ -114,7 +114,7 @@ public bool LayoutMatches(OffsetCalculator other) _height == other._height && _stride == other._stride && _bytesPerPixel == other._bytesPerPixel; - + return !other._isLinear && _layoutConverter.LayoutMatches(other._layoutConverter); } diff --git a/src/Ryujinx.HLE/FileSystem/ContentManager.cs b/src/Ryujinx.HLE/FileSystem/ContentManager.cs index 293ff411c..952271fa1 100644 --- a/src/Ryujinx.HLE/FileSystem/ContentManager.cs +++ b/src/Ryujinx.HLE/FileSystem/ContentManager.cs @@ -589,12 +589,12 @@ public SystemVersion VerifyFirmwarePackage(string firmwarePackage) // So, we check it early for a better user experience. if (_virtualFileSystem.KeySet.HeaderKey.IsZeros()) throw new MissingKeyException("HeaderKey is empty. Cannot decrypt NCA headers."); - + Dictionary> updateNcas = new(); if (Directory.Exists(firmwarePackage)) return VerifyAndGetVersionDirectory(firmwarePackage); - + if (!File.Exists(firmwarePackage)) throw new FileNotFoundException("Firmware file does not exist."); @@ -620,7 +620,7 @@ public SystemVersion VerifyFirmwarePackage(string firmwarePackage) return null; - SystemVersion VerifyAndGetVersionDirectory(string firmwareDirectory) + SystemVersion VerifyAndGetVersionDirectory(string firmwareDirectory) => VerifyAndGetVersion(new LocalFileSystem(firmwareDirectory)); SystemVersion VerifyAndGetVersionZip(ZipArchive archive) diff --git a/src/Ryujinx.HLE/HOS/Kernel/Common/KSystemControl.cs b/src/Ryujinx.HLE/HOS/Kernel/Common/KSystemControl.cs index 3f194e0ed..119d18d27 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/Common/KSystemControl.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/Common/KSystemControl.cs @@ -30,6 +30,7 @@ MemoryArrange.MemoryArrange4GiBSystemDev or MemoryArrange.MemoryArrange4GiBAppletDev => 2048 * MiB, MemoryArrange.MemoryArrange6GiB => 4916 * MiB, MemoryArrange.MemoryArrange8GiB => 6964 * MiB, + MemoryArrange.MemoryArrange12GiB => 11060 * MiB, _ => throw new ArgumentException($"Invalid memory arrange \"{arrange}\"."), }; } @@ -43,7 +44,8 @@ public static ulong GetAppletPoolSize(MemoryArrange arrange) MemoryArrange.MemoryArrange4GiBSystemDev => 448 * MiB, MemoryArrange.MemoryArrange6GiB => 562 * MiB, MemoryArrange.MemoryArrange6GiBAppletDev => 2193 * MiB, - MemoryArrange.MemoryArrange8GiB => 562 * MiB, + MemoryArrange.MemoryArrange8GiB or + MemoryArrange.MemoryArrange12GiB => 562 * MiB, _ => throw new ArgumentException($"Invalid memory arrange \"{arrange}\"."), }; } @@ -71,6 +73,7 @@ public static ulong GetDramSize(MemorySize size) MemorySize.MemorySize4GiB => 4 * GiB, MemorySize.MemorySize6GiB => 6 * GiB, MemorySize.MemorySize8GiB => 8 * GiB, + MemorySize.MemorySize12GiB => 12 * GiB, _ => throw new ArgumentException($"Invalid memory size \"{size}\"."), }; } diff --git a/src/Ryujinx.HLE/HOS/Kernel/Common/MemoryArrange.cs b/src/Ryujinx.HLE/HOS/Kernel/Common/MemoryArrange.cs index 2c88d8b35..d06c97b68 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/Common/MemoryArrange.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/Common/MemoryArrange.cs @@ -8,5 +8,6 @@ enum MemoryArrange : byte MemoryArrange6GiB, MemoryArrange6GiBAppletDev, MemoryArrange8GiB, + MemoryArrange12GiB, } } diff --git a/src/Ryujinx.HLE/HOS/Kernel/Common/MemorySize.cs b/src/Ryujinx.HLE/HOS/Kernel/Common/MemorySize.cs index 7cc34a722..f92859db4 100644 --- a/src/Ryujinx.HLE/HOS/Kernel/Common/MemorySize.cs +++ b/src/Ryujinx.HLE/HOS/Kernel/Common/MemorySize.cs @@ -5,5 +5,6 @@ enum MemorySize : byte MemorySize4GiB = 0, MemorySize6GiB = 1, MemorySize8GiB = 2, + MemorySize12GiB = 3, } } diff --git a/src/Ryujinx.HLE/MemoryConfiguration.cs b/src/Ryujinx.HLE/MemoryConfiguration.cs index 45e8927db..21ecd737f 100644 --- a/src/Ryujinx.HLE/MemoryConfiguration.cs +++ b/src/Ryujinx.HLE/MemoryConfiguration.cs @@ -6,11 +6,12 @@ namespace Ryujinx.HLE public enum MemoryConfiguration { MemoryConfiguration4GiB = 0, - MemoryConfiguration4GiBAppletDev = 1, - MemoryConfiguration4GiBSystemDev = 2, - MemoryConfiguration6GiB = 3, - MemoryConfiguration6GiBAppletDev = 4, - MemoryConfiguration8GiB = 5, + MemoryConfiguration6GiB = 1, + MemoryConfiguration8GiB = 2, + MemoryConfiguration12GiB = 3, + MemoryConfiguration4GiBAppletDev = 4, + MemoryConfiguration4GiBSystemDev = 5, + MemoryConfiguration6GiBAppletDev = 6, } static class MemoryConfigurationExtensions @@ -28,6 +29,7 @@ public static MemoryArrange ToKernelMemoryArrange(this MemoryConfiguration confi MemoryConfiguration.MemoryConfiguration6GiB => MemoryArrange.MemoryArrange6GiB, MemoryConfiguration.MemoryConfiguration6GiBAppletDev => MemoryArrange.MemoryArrange6GiBAppletDev, MemoryConfiguration.MemoryConfiguration8GiB => MemoryArrange.MemoryArrange8GiB, + MemoryConfiguration.MemoryConfiguration12GiB => MemoryArrange.MemoryArrange12GiB, _ => throw new AggregateException($"Invalid memory configuration \"{configuration}\"."), }; } @@ -42,6 +44,7 @@ MemoryConfiguration.MemoryConfiguration4GiBAppletDev or MemoryConfiguration.MemoryConfiguration6GiB or MemoryConfiguration.MemoryConfiguration6GiBAppletDev => MemorySize.MemorySize6GiB, MemoryConfiguration.MemoryConfiguration8GiB => MemorySize.MemorySize8GiB, + MemoryConfiguration.MemoryConfiguration12GiB => MemorySize.MemorySize12GiB, _ => throw new AggregateException($"Invalid memory configuration \"{configuration}\"."), }; } @@ -56,6 +59,7 @@ MemoryConfiguration.MemoryConfiguration4GiBAppletDev or MemoryConfiguration.MemoryConfiguration6GiB or MemoryConfiguration.MemoryConfiguration6GiBAppletDev => 6 * GiB, MemoryConfiguration.MemoryConfiguration8GiB => 8 * GiB, + MemoryConfiguration.MemoryConfiguration12GiB => 12 * GiB, _ => throw new AggregateException($"Invalid memory configuration \"{configuration}\"."), }; } diff --git a/src/Ryujinx.Headless.SDL2/HeadlessDynamicTextInputHandler.cs b/src/Ryujinx.Headless.SDL2/HeadlessDynamicTextInputHandler.cs index f44f5a9d0..40eb5ba98 100644 --- a/src/Ryujinx.Headless.SDL2/HeadlessDynamicTextInputHandler.cs +++ b/src/Ryujinx.Headless.SDL2/HeadlessDynamicTextInputHandler.cs @@ -18,7 +18,7 @@ public event KeyReleasedHandler KeyReleasedEvent { add { } remove { } } public bool TextProcessingEnabled { get => Volatile.Read(ref _canProcessInput); - + set { Volatile.Write(ref _canProcessInput, value); diff --git a/src/Ryujinx.Headless.SDL2/Options.cs b/src/Ryujinx.Headless.SDL2/Options.cs index ef8849eea..2f86f3ebf 100644 --- a/src/Ryujinx.Headless.SDL2/Options.cs +++ b/src/Ryujinx.Headless.SDL2/Options.cs @@ -1,5 +1,6 @@ using CommandLine; using Ryujinx.Common.Configuration; +using Ryujinx.HLE; using Ryujinx.HLE.HOS.SystemState; namespace Ryujinx.Headless.SDL2 @@ -219,8 +220,8 @@ public class Options // Hacks - [Option("expand-ram", Required = false, Default = false, HelpText = "Expands the RAM amount on the emulated system from 4GiB to 8GiB.")] - public bool ExpandRAM { get; set; } + [Option("dram-size", Required = false, Default = MemoryConfiguration.MemoryConfiguration4GiB, HelpText = "Set the RAM amount on the emulated system.")] + public MemoryConfiguration DramSize { get; set; } [Option("ignore-missing-services", Required = false, Default = false, HelpText = "Enable ignoring missing services.")] public bool IgnoreMissingServices { get; set; } diff --git a/src/Ryujinx.Headless.SDL2/Program.cs b/src/Ryujinx.Headless.SDL2/Program.cs index 4ee271203..b8710d4de 100644 --- a/src/Ryujinx.Headless.SDL2/Program.cs +++ b/src/Ryujinx.Headless.SDL2/Program.cs @@ -562,7 +562,7 @@ private static Switch InitializeEmulationContext(WindowBase window, IRenderer re _userChannelPersistence, renderer, new SDL2HardwareDeviceDriver(), - options.ExpandRAM ? MemoryConfiguration.MemoryConfiguration8GiB : MemoryConfiguration.MemoryConfiguration4GiB, + options.DramSize, window, options.SystemLanguage, options.SystemRegion, diff --git a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs index dfc8ea57f..475855fd5 100644 --- a/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs +++ b/src/Ryujinx.Input.SDL2/SDL2Gamepad.cs @@ -147,7 +147,8 @@ public void SetTriggerThreshold(float triggerThreshold) public void Rumble(float lowFrequency, float highFrequency, uint durationMs) { - if (!Features.HasFlag(GamepadFeaturesFlag.Rumble)) return; + if (!Features.HasFlag(GamepadFeaturesFlag.Rumble)) + return; ushort lowFrequencyRaw = (ushort)(lowFrequency * ushort.MaxValue); ushort highFrequencyRaw = (ushort)(highFrequency * ushort.MaxValue); @@ -265,7 +266,8 @@ public GamepadStateSnapshot GetMappedStateSnapshot() // ReSharper disable once ForeachCanBePartlyConvertedToQueryUsingAnotherGetEnumerator foreach (ButtonMappingEntry entry in _buttonsUserMapping) { - if (!entry.IsValid) continue; + if (!entry.IsValid) + continue; // Do not touch state of button already pressed if (!result.IsPressed(entry.To)) diff --git a/src/Ryujinx.UI.Common/Configuration/ConfigurationFileFormat.cs b/src/Ryujinx.UI.Common/Configuration/ConfigurationFileFormat.cs index 5f3c1e21e..89dcdb3ad 100644 --- a/src/Ryujinx.UI.Common/Configuration/ConfigurationFileFormat.cs +++ b/src/Ryujinx.UI.Common/Configuration/ConfigurationFileFormat.cs @@ -3,6 +3,7 @@ using Ryujinx.Common.Configuration.Multiplayer; using Ryujinx.Common.Logging; using Ryujinx.Common.Utilities; +using Ryujinx.HLE; using Ryujinx.UI.Common.Configuration.System; using Ryujinx.UI.Common.Configuration.UI; using System.Collections.Generic; @@ -15,7 +16,7 @@ public class ConfigurationFileFormat /// /// The current version of the file format /// - public const int CurrentVersion = 53; + public const int CurrentVersion = 54; /// /// Version of the configuration file format @@ -245,7 +246,7 @@ public class ConfigurationFileFormat /// /// Expands the RAM amount on the emulated system from 4GiB to 8GiB /// - public bool ExpandRam { get; set; } + public MemoryConfiguration DramSize { get; set; } /// /// Enable or disable ignoring missing services diff --git a/src/Ryujinx.UI.Common/Configuration/ConfigurationState.cs b/src/Ryujinx.UI.Common/Configuration/ConfigurationState.cs index e6c5c065c..3c3bc458c 100644 --- a/src/Ryujinx.UI.Common/Configuration/ConfigurationState.cs +++ b/src/Ryujinx.UI.Common/Configuration/ConfigurationState.cs @@ -7,6 +7,7 @@ using Ryujinx.Common.Configuration.Multiplayer; using Ryujinx.Common.Logging; using Ryujinx.Graphics.Vulkan; +using Ryujinx.HLE; using Ryujinx.UI.Common.Configuration.System; using Ryujinx.UI.Common.Configuration.UI; using Ryujinx.UI.Common.Helper; @@ -366,7 +367,7 @@ public class SystemSection /// /// Defines the amount of RAM available on the emulated system, and how it is distributed /// - public ReactiveObject ExpandRam { get; private set; } + public ReactiveObject DramSize { get; private set; } /// /// Enable or disable ignoring missing services @@ -400,8 +401,8 @@ public SystemSection() AudioBackend.Event += static (sender, e) => LogValueChange(e, nameof(AudioBackend)); MemoryManagerMode = new ReactiveObject(); MemoryManagerMode.Event += static (sender, e) => LogValueChange(e, nameof(MemoryManagerMode)); - ExpandRam = new ReactiveObject(); - ExpandRam.Event += static (sender, e) => LogValueChange(e, nameof(ExpandRam)); + DramSize = new ReactiveObject(); + DramSize.Event += static (sender, e) => LogValueChange(e, nameof(DramSize)); IgnoreMissingServices = new ReactiveObject(); IgnoreMissingServices.Event += static (sender, e) => LogValueChange(e, nameof(IgnoreMissingServices)); AudioVolume = new ReactiveObject(); @@ -721,7 +722,7 @@ public ConfigurationFileFormat ToFileFormat() AudioBackend = System.AudioBackend, AudioVolume = System.AudioVolume, MemoryManagerMode = System.MemoryManagerMode, - ExpandRam = System.ExpandRam, + DramSize = System.DramSize, IgnoreMissingServices = System.IgnoreMissingServices, UseHypervisor = System.UseHypervisor, GuiColumns = new GuiColumns @@ -834,7 +835,7 @@ public void LoadDefault() System.AudioBackend.Value = AudioBackend.SDL2; System.AudioVolume.Value = 1; System.MemoryManagerMode.Value = MemoryManagerMode.HostMappedUnsafe; - System.ExpandRam.Value = false; + System.DramSize.Value = MemoryConfiguration.MemoryConfiguration4GiB; System.IgnoreMissingServices.Value = false; System.UseHypervisor.Value = true; Multiplayer.LanInterfaceId.Value = "0"; @@ -1513,6 +1514,15 @@ public void Load(ConfigurationFileFormat configurationFileFormat, string configu configurationFileUpdated = true; } + if (configurationFileFormat.Version < 54) + { + Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 54."); + + configurationFileFormat.DramSize = MemoryConfiguration.MemoryConfiguration4GiB; + + configurationFileUpdated = true; + } + Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog; Graphics.ResScale.Value = configurationFileFormat.ResScale; Graphics.ResScaleCustom.Value = configurationFileFormat.ResScaleCustom; @@ -1559,7 +1569,7 @@ public void Load(ConfigurationFileFormat configurationFileFormat, string configu System.AudioBackend.Value = configurationFileFormat.AudioBackend; System.AudioVolume.Value = configurationFileFormat.AudioVolume; System.MemoryManagerMode.Value = configurationFileFormat.MemoryManagerMode; - System.ExpandRam.Value = configurationFileFormat.ExpandRam; + System.DramSize.Value = configurationFileFormat.DramSize; System.IgnoreMissingServices.Value = configurationFileFormat.IgnoreMissingServices; System.UseHypervisor.Value = configurationFileFormat.UseHypervisor; UI.GuiColumns.FavColumn.Value = configurationFileFormat.GuiColumns.FavColumn; diff --git a/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs b/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs index c83872c09..420c8c0f5 100644 --- a/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs +++ b/src/Ryujinx.UI.Common/DiscordIntegrationModule.cs @@ -14,8 +14,8 @@ namespace Ryujinx.UI.Common public static class DiscordIntegrationModule { public static Timestamps StartedAt { get; set; } - - private static readonly string _description = ReleaseInformation.IsValid + + private static readonly string _description = ReleaseInformation.IsValid ? $"v{ReleaseInformation.Version} {ReleaseInformation.ReleaseChannelOwner}/{ReleaseInformation.ReleaseChannelRepo}@{ReleaseInformation.BuildGitHash}" : "dev build"; @@ -80,7 +80,7 @@ public static void SwitchToPlayingState(ApplicationMetadata appMeta, ProcessResu }, Details = TruncateToByteLength($"Playing {appMeta.Title}"), State = appMeta.LastPlayed.HasValue && appMeta.TimePlayed.TotalSeconds > 5 - ? $"Total play time: {appMeta.TimePlayed.Humanize(2, false)}" + ? $"Total play time: {appMeta.TimePlayed.Humanize(2, false)}" : "Never played", Timestamps = Timestamps.Now }); @@ -120,7 +120,7 @@ public static void Exit() _discordClient?.Dispose(); } - private static readonly string[] _discordGameAssetKeys = + private static readonly string[] _discordGameAssetKeys = [ "01002da013484000", // The Legend of Zelda: Skyward Sword HD "01007ef00011e000", // The Legend of Zelda: Breath of the Wild diff --git a/src/Ryujinx.UI.Common/Helper/SetupValidator.cs b/src/Ryujinx.UI.Common/Helper/SetupValidator.cs index 5e2d3a584..908476e48 100644 --- a/src/Ryujinx.UI.Common/Helper/SetupValidator.cs +++ b/src/Ryujinx.UI.Common/Helper/SetupValidator.cs @@ -98,7 +98,6 @@ public static bool CanStartApplication(ContentManager contentManager, string bas if (baseApplicationExtension is not (".nro" or ".nso")) return IsFirmwareValid(contentManager, out error); - error = UserError.Success; } error = UserError.ApplicationNotFound; diff --git a/src/Ryujinx.UI.Common/Helper/TitleHelper.cs b/src/Ryujinx.UI.Common/Helper/TitleHelper.cs index f0d2fd78a..9d73aea75 100644 --- a/src/Ryujinx.UI.Common/Helper/TitleHelper.cs +++ b/src/Ryujinx.UI.Common/Helper/TitleHelper.cs @@ -9,7 +9,7 @@ public static string ActiveApplicationTitle(ProcessResult activeProcess, string { if (activeProcess == null) return string.Empty; - + string titleNameSection = string.IsNullOrWhiteSpace(activeProcess.Name) ? string.Empty : $" {activeProcess.Name}"; string titleVersionSection = string.IsNullOrWhiteSpace(activeProcess.DisplayVersion) ? string.Empty : $" v{activeProcess.DisplayVersion}"; string titleIdSection = $" ({activeProcess.ProgramIdText.ToUpper()})"; diff --git a/src/Ryujinx.UI.Common/Helper/TitleUpdatesHelper.cs b/src/Ryujinx.UI.Common/Helper/TitleUpdatesHelper.cs index 6edd613b3..d9bc7b6fe 100644 --- a/src/Ryujinx.UI.Common/Helper/TitleUpdatesHelper.cs +++ b/src/Ryujinx.UI.Common/Helper/TitleUpdatesHelper.cs @@ -87,7 +87,8 @@ public static void SaveTitleUpdatesJson(VirtualFileSystem vfs, ulong application foreach (string path in titleUpdateMetadata.Paths) { - if (!File.Exists(path)) continue; + if (!File.Exists(path)) + continue; try { @@ -104,7 +105,7 @@ public static void SaveTitleUpdatesJson(VirtualFileSystem vfs, ulong application if (controlNca is null || patchNca is null) continue; - + ApplicationControlProperty controlData = new(); using UniqueRef nacpFile = new(); @@ -144,7 +145,7 @@ public static void SaveTitleUpdatesJson(VirtualFileSystem vfs, ulong application return result; } - private static string PathToGameUpdatesJson(ulong applicationIdBase) + private static string PathToGameUpdatesJson(ulong applicationIdBase) => Path.Combine(AppDataManager.GamesDirPath, applicationIdBase.ToString("x16"), "updates.json"); } } diff --git a/src/Ryujinx.UI.Common/SystemInfo/SystemInfo.cs b/src/Ryujinx.UI.Common/SystemInfo/SystemInfo.cs index c50703538..2dfa9160d 100644 --- a/src/Ryujinx.UI.Common/SystemInfo/SystemInfo.cs +++ b/src/Ryujinx.UI.Common/SystemInfo/SystemInfo.cs @@ -34,10 +34,10 @@ public static SystemInfo Gather() { if (OperatingSystem.IsWindows()) return new WindowsSystemInfo(); - + if (OperatingSystem.IsLinux()) return new LinuxSystemInfo(); - + if (OperatingSystem.IsMacOS()) return new MacOSSystemInfo(); diff --git a/src/Ryujinx/App.axaml.cs b/src/Ryujinx/App.axaml.cs index 66aebbe62..c834004e2 100644 --- a/src/Ryujinx/App.axaml.cs +++ b/src/Ryujinx/App.axaml.cs @@ -22,8 +22,8 @@ namespace Ryujinx.Ava public class App : Application { internal static string FormatTitle(LocaleKeys? windowTitleKey = null) - => windowTitleKey is null - ? $"Ryujinx {Program.Version}" + => windowTitleKey is null + ? $"Ryujinx {Program.Version}" : $"Ryujinx {Program.Version} - {LocaleManager.Instance[windowTitleKey.Value]}"; public static MainWindow MainWindow => Current! diff --git a/src/Ryujinx/AppHost.cs b/src/Ryujinx/AppHost.cs index 5bcb58218..eafcbb13a 100644 --- a/src/Ryujinx/AppHost.cs +++ b/src/Ryujinx/AppHost.cs @@ -541,7 +541,7 @@ private void Dispose() { if (Device.Processes != null) MainWindowViewModel.UpdateGameMetadata(Device.Processes.ActiveApplication.ProgramIdText); - + ConfigurationState.Instance.System.IgnoreMissingServices.Event -= UpdateIgnoreMissingServicesState; ConfigurationState.Instance.Graphics.AspectRatio.Event -= UpdateAspectRatioState; @@ -786,7 +786,7 @@ await ContentDialogHelper.CreateInfoDialog( return false; } - ApplicationMetadata appMeta = ApplicationLibrary.LoadAndSaveMetaData(Device.Processes.ActiveApplication.ProgramIdText, + ApplicationMetadata appMeta = ApplicationLibrary.LoadAndSaveMetaData(Device.Processes.ActiveApplication.ProgramIdText, appMetadata => appMetadata.UpdatePreGame() ); @@ -845,9 +845,7 @@ private void InitializeSwitchInstance() Logger.Info?.PrintMsg(LogClass.Gpu, $"Backend Threading ({threadingMode}): {isGALThreaded}"); // Initialize Configuration. - var memoryConfiguration = ConfigurationState.Instance.System.ExpandRam - ? MemoryConfiguration.MemoryConfiguration8GiB - : MemoryConfiguration.MemoryConfiguration4GiB; + var memoryConfiguration = ConfigurationState.Instance.System.DramSize.Value; Device = new Switch(new HLEConfiguration( VirtualFileSystem, @@ -867,7 +865,7 @@ private void InitializeSwitchInstance() ConfigurationState.Instance.System.EnableInternetAccess, ConfigurationState.Instance.System.EnableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None, ConfigurationState.Instance.System.FsGlobalAccessLogMode, - ConfigurationState.Instance.System.SystemTimeOffset, + ConfigurationState.Instance.System.SystemTimeOffset, ConfigurationState.Instance.System.TimeZone, ConfigurationState.Instance.System.MemoryManagerMode, ConfigurationState.Instance.System.IgnoreMissingServices, diff --git a/src/Ryujinx/Assets/Locales/ar_SA.json b/src/Ryujinx/Assets/Locales/ar_SA.json index 2263a0599..ed06778cb 100644 --- a/src/Ryujinx/Assets/Locales/ar_SA.json +++ b/src/Ryujinx/Assets/Locales/ar_SA.json @@ -145,7 +145,11 @@ "SettingsTabSystemAudioBackendSDL2": "SDL2", "SettingsTabSystemHacks": "هاكات", "SettingsTabSystemHacksNote": "قد يتسبب في عدم الاستقرار", - "SettingsTabSystemExpandDramSize": "استخدام تخطيط الذاكرة البديل (المطورين)", + "SettingsTabSystemDramSize": "استخدام تخطيط الذاكرة البديل (المطورين)", + "SettingsTabSystemDramSize4GiB": "4GiB", + "SettingsTabSystemDramSize6GiB": "6GiB", + "SettingsTabSystemDramSize8GiB": "8GiB", + "SettingsTabSystemDramSize12GiB": "12GiB", "SettingsTabSystemIgnoreMissingServices": "تجاهل الخدمات المفقودة", "SettingsTabGraphics": "الرسومات", "SettingsTabGraphicsAPI": "API الرسومات ", diff --git a/src/Ryujinx/Assets/Locales/de_DE.json b/src/Ryujinx/Assets/Locales/de_DE.json index eee287a53..b78e3ded8 100644 --- a/src/Ryujinx/Assets/Locales/de_DE.json +++ b/src/Ryujinx/Assets/Locales/de_DE.json @@ -145,7 +145,11 @@ "SettingsTabSystemAudioBackendSDL2": "SDL2", "SettingsTabSystemHacks": "Hacks", "SettingsTabSystemHacksNote": " (Kann Fehler verursachen)", - "SettingsTabSystemExpandDramSize": "Erweitere DRAM Größe auf 6GiB", + "SettingsTabSystemDramSize": "DRAM Größe:", + "SettingsTabSystemDramSize4GiB": "4GiB", + "SettingsTabSystemDramSize6GiB": "6GiB", + "SettingsTabSystemDramSize8GiB": "8GiB", + "SettingsTabSystemDramSize12GiB": "12GiB", "SettingsTabSystemIgnoreMissingServices": "Ignoriere fehlende Dienste", "SettingsTabGraphics": "Grafik", "SettingsTabGraphicsAPI": "Grafik-API", diff --git a/src/Ryujinx/Assets/Locales/el_GR.json b/src/Ryujinx/Assets/Locales/el_GR.json index a3739f9ad..7a6e5619d 100644 --- a/src/Ryujinx/Assets/Locales/el_GR.json +++ b/src/Ryujinx/Assets/Locales/el_GR.json @@ -145,7 +145,11 @@ "SettingsTabSystemAudioBackendSDL2": "SDL2", "SettingsTabSystemHacks": "Μικροδιορθώσεις", "SettingsTabSystemHacksNote": " (Μπορεί να προκαλέσουν αστάθεια)", - "SettingsTabSystemExpandDramSize": "Επέκταση μεγέθους DRAM στα 6GiB", + "SettingsTabSystemDramSize": "Μέγεθος DRAM:", + "SettingsTabSystemDramSize4GiB": "4GiB", + "SettingsTabSystemDramSize6GiB": "6GiB", + "SettingsTabSystemDramSize8GiB": "8GiB", + "SettingsTabSystemDramSize12GiB": "12GiB", "SettingsTabSystemIgnoreMissingServices": "Αγνόηση υπηρεσιών που λείπουν", "SettingsTabGraphics": "Γραφικά", "SettingsTabGraphicsAPI": "API Γραφικά", diff --git a/src/Ryujinx/Assets/Locales/en_US.json b/src/Ryujinx/Assets/Locales/en_US.json index c7ca1c2d5..1dfbb81f1 100644 --- a/src/Ryujinx/Assets/Locales/en_US.json +++ b/src/Ryujinx/Assets/Locales/en_US.json @@ -149,7 +149,11 @@ "SettingsTabSystemAudioBackendSDL2": "SDL2", "SettingsTabSystemHacks": "Hacks", "SettingsTabSystemHacksNote": "May cause instability", - "SettingsTabSystemExpandDramSize": "Expand DRAM to 8GiB", + "SettingsTabSystemDramSize": "DRAM size:", + "SettingsTabSystemDramSize4GiB": "4GiB", + "SettingsTabSystemDramSize6GiB": "6GiB", + "SettingsTabSystemDramSize8GiB": "8GiB", + "SettingsTabSystemDramSize12GiB": "12GiB", "SettingsTabSystemIgnoreMissingServices": "Ignore Missing Services", "SettingsTabGraphics": "Graphics", "SettingsTabGraphicsAPI": "Graphics API", diff --git a/src/Ryujinx/Assets/Locales/es_ES.json b/src/Ryujinx/Assets/Locales/es_ES.json index 8593498bc..55311d7fd 100644 --- a/src/Ryujinx/Assets/Locales/es_ES.json +++ b/src/Ryujinx/Assets/Locales/es_ES.json @@ -145,7 +145,11 @@ "SettingsTabSystemAudioBackendSDL2": "SDL2", "SettingsTabSystemHacks": "Hacks", "SettingsTabSystemHacksNote": " (Pueden causar inestabilidad)", - "SettingsTabSystemExpandDramSize": "Usar diseño alternativo de memoria (Desarrolladores)", + "SettingsTabSystemDramSize": "Tamaño DRAM:", + "SettingsTabSystemDramSize4GiB": "4GiB", + "SettingsTabSystemDramSize6GiB": "6GiB", + "SettingsTabSystemDramSize8GiB": "8GiB", + "SettingsTabSystemDramSize12GiB": "12GiB", "SettingsTabSystemIgnoreMissingServices": "Ignorar servicios no implementados", "SettingsTabGraphics": "Gráficos", "SettingsTabGraphicsAPI": "API de gráficos", diff --git a/src/Ryujinx/Assets/Locales/fr_FR.json b/src/Ryujinx/Assets/Locales/fr_FR.json index f056dbb84..6d6174f40 100644 --- a/src/Ryujinx/Assets/Locales/fr_FR.json +++ b/src/Ryujinx/Assets/Locales/fr_FR.json @@ -149,7 +149,11 @@ "SettingsTabSystemAudioBackendSDL2": "SDL2", "SettingsTabSystemHacks": "Hacks", "SettingsTabSystemHacksNote": "Cela peut causer des instabilités", - "SettingsTabSystemExpandDramSize": "Étendre la mémoire à 8GiO", + "SettingsTabSystemDramSize": "Taille de la DRAM:", + "SettingsTabSystemDramSize4GiB": "4GiO", + "SettingsTabSystemDramSize6GiB": "6GiO", + "SettingsTabSystemDramSize8GiB": "8GiO", + "SettingsTabSystemDramSize12GiB": "12GiO", "SettingsTabSystemIgnoreMissingServices": "Ignorer les services manquants", "SettingsTabGraphics": "Graphismes", "SettingsTabGraphicsAPI": "API Graphique", diff --git a/src/Ryujinx/Assets/Locales/he_IL.json b/src/Ryujinx/Assets/Locales/he_IL.json index 1e2cab8a7..129ef72ac 100644 --- a/src/Ryujinx/Assets/Locales/he_IL.json +++ b/src/Ryujinx/Assets/Locales/he_IL.json @@ -145,7 +145,11 @@ "SettingsTabSystemAudioBackendSDL2": "SDL2", "SettingsTabSystemHacks": "האצות", "SettingsTabSystemHacksNote": "עלול לגרום לאי יציבות", - "SettingsTabSystemExpandDramSize": "השתמש בפריסת זיכרון חלופית (נועד למפתחים)", + "SettingsTabSystemDramSize": "השתמש בפריסת זיכרון חלופית (נועד למפתחים)", + "SettingsTabSystemDramSize4GiB": "4GiB", + "SettingsTabSystemDramSize6GiB": "6GiB", + "SettingsTabSystemDramSize8GiB": "8GiB", + "SettingsTabSystemDramSize12GiB": "12GiB", "SettingsTabSystemIgnoreMissingServices": "התעלם משירותים חסרים", "SettingsTabGraphics": "גרפיקה", "SettingsTabGraphicsAPI": "ממשק גראפי", diff --git a/src/Ryujinx/Assets/Locales/it_IT.json b/src/Ryujinx/Assets/Locales/it_IT.json index dc75ce586..94fe67d78 100644 --- a/src/Ryujinx/Assets/Locales/it_IT.json +++ b/src/Ryujinx/Assets/Locales/it_IT.json @@ -145,7 +145,11 @@ "SettingsTabSystemAudioBackendSDL2": "SDL2", "SettingsTabSystemHacks": "Espedienti", "SettingsTabSystemHacksNote": "Possono causare instabilità", - "SettingsTabSystemExpandDramSize": "Usa layout di memoria alternativo (per sviluppatori)", + "SettingsTabSystemDramSize": "Usa layout di memoria alternativo (per sviluppatori)", + "SettingsTabSystemDramSize4GiB": "4GiB", + "SettingsTabSystemDramSize6GiB": "6GiB", + "SettingsTabSystemDramSize8GiB": "8GiB", + "SettingsTabSystemDramSize12GiB": "12GiB", "SettingsTabSystemIgnoreMissingServices": "Ignora servizi mancanti", "SettingsTabGraphics": "Grafica", "SettingsTabGraphicsAPI": "API grafica", diff --git a/src/Ryujinx/Assets/Locales/ja_JP.json b/src/Ryujinx/Assets/Locales/ja_JP.json index bb44e8f6d..67dec4229 100644 --- a/src/Ryujinx/Assets/Locales/ja_JP.json +++ b/src/Ryujinx/Assets/Locales/ja_JP.json @@ -145,7 +145,11 @@ "SettingsTabSystemAudioBackendSDL2": "SDL2", "SettingsTabSystemHacks": "ハック", "SettingsTabSystemHacksNote": " (挙動が不安定になる可能性があります)", - "SettingsTabSystemExpandDramSize": "DRAMサイズを6GiBに拡大する", + "SettingsTabSystemDramSize": "DRAMサイズ:", + "SettingsTabSystemDramSize4GiB": "4GiB", + "SettingsTabSystemDramSize6GiB": "6GiB", + "SettingsTabSystemDramSize8GiB": "8GiB", + "SettingsTabSystemDramSize12GiB": "12GiB", "SettingsTabSystemIgnoreMissingServices": "未実装サービスを無視する", "SettingsTabGraphics": "グラフィックス", "SettingsTabGraphicsAPI": "グラフィックスAPI", diff --git a/src/Ryujinx/Assets/Locales/ko_KR.json b/src/Ryujinx/Assets/Locales/ko_KR.json index f38308485..5552d233e 100644 --- a/src/Ryujinx/Assets/Locales/ko_KR.json +++ b/src/Ryujinx/Assets/Locales/ko_KR.json @@ -145,7 +145,11 @@ "SettingsTabSystemAudioBackendSDL2": "SDL2", "SettingsTabSystemHacks": "해킹", "SettingsTabSystemHacksNote": "불안정성을 유발할 수 있음", - "SettingsTabSystemExpandDramSize": "대체 메모리 레이아웃 사용(개발자)", + "SettingsTabSystemDramSize": "대체 메모리 레이아웃 사용(개발자)", + "SettingsTabSystemDramSize4GiB": "4GiB", + "SettingsTabSystemDramSize6GiB": "6GiB", + "SettingsTabSystemDramSize8GiB": "8GiB", + "SettingsTabSystemDramSize12GiB": "12GiB", "SettingsTabSystemIgnoreMissingServices": "누락된 서비스 무시", "SettingsTabGraphics": "그래픽", "SettingsTabGraphicsAPI": "그래픽 API", diff --git a/src/Ryujinx/Assets/Locales/pl_PL.json b/src/Ryujinx/Assets/Locales/pl_PL.json index c58d328f1..92573ee40 100644 --- a/src/Ryujinx/Assets/Locales/pl_PL.json +++ b/src/Ryujinx/Assets/Locales/pl_PL.json @@ -145,7 +145,11 @@ "SettingsTabSystemAudioBackendSDL2": "SDL2", "SettingsTabSystemHacks": "Hacki", "SettingsTabSystemHacksNote": " (mogą powodować niestabilność)", - "SettingsTabSystemExpandDramSize": "Użyj alternatywnego układu pamięci (Deweloperzy)", + "SettingsTabSystemDramSize": "Użyj alternatywnego układu pamięci (Deweloperzy)", + "SettingsTabSystemDramSize4GiB": "4GiB", + "SettingsTabSystemDramSize6GiB": "6GiB", + "SettingsTabSystemDramSize8GiB": "8GiB", + "SettingsTabSystemDramSize12GiB": "12GiB", "SettingsTabSystemIgnoreMissingServices": "Ignoruj Brakujące Usługi", "SettingsTabGraphics": "Grafika", "SettingsTabGraphicsAPI": "Graficzne API", diff --git a/src/Ryujinx/Assets/Locales/pt_BR.json b/src/Ryujinx/Assets/Locales/pt_BR.json index f2134b2f9..b951659f7 100644 --- a/src/Ryujinx/Assets/Locales/pt_BR.json +++ b/src/Ryujinx/Assets/Locales/pt_BR.json @@ -145,7 +145,11 @@ "SettingsTabSystemAudioBackendSDL2": "SDL2", "SettingsTabSystemHacks": "Hacks", "SettingsTabSystemHacksNote": " (Pode causar instabilidade)", - "SettingsTabSystemExpandDramSize": "Expandir memória para 6GiB", + "SettingsTabSystemDramSize": "Tamanho da DRAM:", + "SettingsTabSystemDramSize4GiB": "4GiB", + "SettingsTabSystemDramSize6GiB": "6GiB", + "SettingsTabSystemDramSize8GiB": "8GiB", + "SettingsTabSystemDramSize12GiB": "12GiB", "SettingsTabSystemIgnoreMissingServices": "Ignorar serviços não implementados", "SettingsTabGraphics": "Gráficos", "SettingsTabGraphicsAPI": "API gráfica", diff --git a/src/Ryujinx/Assets/Locales/ru_RU.json b/src/Ryujinx/Assets/Locales/ru_RU.json index f283bff56..299631306 100644 --- a/src/Ryujinx/Assets/Locales/ru_RU.json +++ b/src/Ryujinx/Assets/Locales/ru_RU.json @@ -145,7 +145,11 @@ "SettingsTabSystemAudioBackendSDL2": "SDL2", "SettingsTabSystemHacks": "Хаки", "SettingsTabSystemHacksNote": "Возможна нестабильная работа", - "SettingsTabSystemExpandDramSize": "Использовать альтернативный макет памяти (для разработчиков)", + "SettingsTabSystemDramSize": "Использовать альтернативный макет памяти (для разработчиков)", + "SettingsTabSystemDramSize4GiB": "4GiB", + "SettingsTabSystemDramSize6GiB": "6GiB", + "SettingsTabSystemDramSize8GiB": "8GiB", + "SettingsTabSystemDramSize12GiB": "12GiB", "SettingsTabSystemIgnoreMissingServices": "Игнорировать отсутствующие службы", "SettingsTabGraphics": "Графика", "SettingsTabGraphicsAPI": "Графические API", diff --git a/src/Ryujinx/Assets/Locales/th_TH.json b/src/Ryujinx/Assets/Locales/th_TH.json index 4f926dc93..2b795c872 100644 --- a/src/Ryujinx/Assets/Locales/th_TH.json +++ b/src/Ryujinx/Assets/Locales/th_TH.json @@ -145,7 +145,11 @@ "SettingsTabSystemAudioBackendSDL2": "SDL2", "SettingsTabSystemHacks": "แฮ็ก", "SettingsTabSystemHacksNote": "อาจทำให้เกิดข้อผิดพลาดได้", - "SettingsTabSystemExpandDramSize": "ใช้รูปแบบหน่วยความจำสำรอง (โหมดนักพัฒนา)", + "SettingsTabSystemDramSize": "ใช้รูปแบบหน่วยความจำสำรอง (โหมดนักพัฒนา)", + "SettingsTabSystemDramSize4GiB": "4GiB", + "SettingsTabSystemDramSize6GiB": "6GiB", + "SettingsTabSystemDramSize8GiB": "8GiB", + "SettingsTabSystemDramSize12GiB": "12GiB", "SettingsTabSystemIgnoreMissingServices": "ไม่สนใจบริการที่ขาดหายไป", "SettingsTabGraphics": "กราฟิก", "SettingsTabGraphicsAPI": "กราฟฟิก API", diff --git a/src/Ryujinx/Assets/Locales/tr_TR.json b/src/Ryujinx/Assets/Locales/tr_TR.json index 02c82aace..96c0fd61a 100644 --- a/src/Ryujinx/Assets/Locales/tr_TR.json +++ b/src/Ryujinx/Assets/Locales/tr_TR.json @@ -145,7 +145,11 @@ "SettingsTabSystemAudioBackendSDL2": "SDL2", "SettingsTabSystemHacks": "Hack'ler", "SettingsTabSystemHacksNote": " (dengesizlik oluşturabilir)", - "SettingsTabSystemExpandDramSize": "Alternatif bellek düzeni kullan (Geliştirici)", + "SettingsTabSystemDramSize": "Alternatif bellek düzeni kullan (Geliştirici)", + "SettingsTabSystemDramSize4GiB": "4GiB", + "SettingsTabSystemDramSize6GiB": "6GiB", + "SettingsTabSystemDramSize8GiB": "8GiB", + "SettingsTabSystemDramSize12GiB": "12GiB", "SettingsTabSystemIgnoreMissingServices": "Eksik Servisleri Görmezden Gel", "SettingsTabGraphics": "Grafikler", "SettingsTabGraphicsAPI": "Grafikler API", diff --git a/src/Ryujinx/Assets/Locales/uk_UA.json b/src/Ryujinx/Assets/Locales/uk_UA.json index 28e703a4a..39270fe1d 100644 --- a/src/Ryujinx/Assets/Locales/uk_UA.json +++ b/src/Ryujinx/Assets/Locales/uk_UA.json @@ -145,7 +145,11 @@ "SettingsTabSystemAudioBackendSDL2": "SDL2", "SettingsTabSystemHacks": "Хитрощі", "SettingsTabSystemHacksNote": " (може викликати нестабільність)", - "SettingsTabSystemExpandDramSize": "Використовувати альтернативне розташування пам'яті (розробники)", + "SettingsTabSystemDramSize": "Використовувати альтернативне розташування пам'яті (розробники)", + "SettingsTabSystemDramSize4GiB": "4GiB", + "SettingsTabSystemDramSize6GiB": "6GiB", + "SettingsTabSystemDramSize8GiB": "8GiB", + "SettingsTabSystemDramSize12GiB": "12GiB", "SettingsTabSystemIgnoreMissingServices": "Ігнорувати відсутні служби", "SettingsTabGraphics": "Графіка", "SettingsTabGraphicsAPI": "Графічний API", diff --git a/src/Ryujinx/Assets/Locales/zh_CN.json b/src/Ryujinx/Assets/Locales/zh_CN.json index 2b344604c..a7d92354d 100644 --- a/src/Ryujinx/Assets/Locales/zh_CN.json +++ b/src/Ryujinx/Assets/Locales/zh_CN.json @@ -145,7 +145,11 @@ "SettingsTabSystemAudioBackendSDL2": "SDL2", "SettingsTabSystemHacks": "修改", "SettingsTabSystemHacksNote": "会导致模拟器不稳定", - "SettingsTabSystemExpandDramSize": "使用开发机的内存布局(开发人员使用)", + "SettingsTabSystemDramSize": "使用开发机的内存布局(开发人员使用)", + "SettingsTabSystemDramSize4GiB": "4GiB", + "SettingsTabSystemDramSize6GiB": "6GiB", + "SettingsTabSystemDramSize8GiB": "8GiB", + "SettingsTabSystemDramSize12GiB": "12GiB", "SettingsTabSystemIgnoreMissingServices": "忽略缺失的服务", "SettingsTabGraphics": "图形", "SettingsTabGraphicsAPI": "图形 API", diff --git a/src/Ryujinx/Assets/Locales/zh_TW.json b/src/Ryujinx/Assets/Locales/zh_TW.json index 92fd16e01..b724a2697 100644 --- a/src/Ryujinx/Assets/Locales/zh_TW.json +++ b/src/Ryujinx/Assets/Locales/zh_TW.json @@ -145,7 +145,11 @@ "SettingsTabSystemAudioBackendSDL2": "SDL2", "SettingsTabSystemHacks": "補釘修正", "SettingsTabSystemHacksNote": "可能導致模擬器不穩定", - "SettingsTabSystemExpandDramSize": "使用替代的記憶體配置 (開發者專用)", + "SettingsTabSystemDramSize": "使用替代的記憶體配置 (開發者專用)", + "SettingsTabSystemDramSize4GiB": "4GiB", + "SettingsTabSystemDramSize6GiB": "6GiB", + "SettingsTabSystemDramSize8GiB": "8GiB", + "SettingsTabSystemDramSize12GiB": "12GiB", "SettingsTabSystemIgnoreMissingServices": "忽略缺少的模擬器功能", "SettingsTabGraphics": "圖形", "SettingsTabGraphicsAPI": "圖形 API", diff --git a/src/Ryujinx/Common/Locale/LocaleExtension.cs b/src/Ryujinx/Common/Locale/LocaleExtension.cs index fd7159c16..54441c4cc 100644 --- a/src/Ryujinx/Common/Locale/LocaleExtension.cs +++ b/src/Ryujinx/Common/Locale/LocaleExtension.cs @@ -21,7 +21,8 @@ public override object ProvideValue(IServiceProvider serviceProvider) => new CompiledBindingPathBuilder() .Property(PropertyInfo, PropertyInfoAccessorFactory.CreateInpcPropertyAccessor) .Build() - ) { Source = LocaleManager.Instance } + ) + { Source = LocaleManager.Instance } .ProvideValue(serviceProvider); } } diff --git a/src/Ryujinx/Common/Locale/LocaleManager.cs b/src/Ryujinx/Common/Locale/LocaleManager.cs index 995a07881..5cd2428a8 100644 --- a/src/Ryujinx/Common/Locale/LocaleManager.cs +++ b/src/Ryujinx/Common/Locale/LocaleManager.cs @@ -80,8 +80,8 @@ public string this[LocaleKeys key] } // If the locale doesn't contain the key return the default one. - return _localeDefaultStrings.TryGetValue(key, out string defaultValue) - ? defaultValue + return _localeDefaultStrings.TryGetValue(key, out string defaultValue) + ? defaultValue : key.ToString(); // If the locale text doesn't exist return the key. } set diff --git a/src/Ryujinx/Program.cs b/src/Ryujinx/Program.cs index 562530b2b..b77e05c12 100644 --- a/src/Ryujinx/Program.cs +++ b/src/Ryujinx/Program.cs @@ -72,23 +72,23 @@ public static AppBuilder BuildAvaloniaApp() => EnableMultiTouch = true, EnableIme = true, EnableInputFocusProxy = Environment.GetEnvironmentVariable("XDG_CURRENT_DESKTOP") == "gamescope", - RenderingMode = UseHardwareAcceleration - ? [ X11RenderingMode.Glx, X11RenderingMode.Software ] - : [ X11RenderingMode.Software ], + RenderingMode = UseHardwareAcceleration + ? [X11RenderingMode.Glx, X11RenderingMode.Software] + : [X11RenderingMode.Software], }) .With(new Win32PlatformOptions { WinUICompositionBackdropCornerRadius = 8.0f, - RenderingMode = UseHardwareAcceleration - ? [ Win32RenderingMode.AngleEgl, Win32RenderingMode.Software ] - : [ Win32RenderingMode.Software ], + RenderingMode = UseHardwareAcceleration + ? [Win32RenderingMode.AngleEgl, Win32RenderingMode.Software] + : [Win32RenderingMode.Software], }); private static void Initialize(string[] args) { // Ensure Discord presence timestamp begins at the absolute start of when Ryujinx is launched DiscordIntegrationModule.StartedAt = Timestamps.Now; - + // Parse arguments CommandLineState.ParseArguments(args); @@ -203,7 +203,7 @@ public static void ReloadConfig() // Check if docked mode was overriden. if (CommandLineState.OverrideDockedMode.HasValue) ConfigurationState.Instance.System.EnableDockedMode.Value = CommandLineState.OverrideDockedMode.Value; - + // Check if HideCursor was overridden. if (CommandLineState.OverrideHideCursor is not null) @@ -214,7 +214,7 @@ public static void ReloadConfig() "always" => HideCursorMode.Always, _ => ConfigurationState.Instance.HideCursor, }; - + // Check if hardware-acceleration was overridden. if (CommandLineState.OverrideHardwareAcceleration != null) diff --git a/src/Ryujinx/UI/Applet/AvaloniaDynamicTextInputHandler.cs b/src/Ryujinx/UI/Applet/AvaloniaDynamicTextInputHandler.cs index 56be50dce..1fc3c9c3c 100644 --- a/src/Ryujinx/UI/Applet/AvaloniaDynamicTextInputHandler.cs +++ b/src/Ryujinx/UI/Applet/AvaloniaDynamicTextInputHandler.cs @@ -136,7 +136,7 @@ public void SetText(string text, int cursorBegin) => _hiddenTextBox.CaretIndex = cursorBegin; }); - public void SetText(string text, int cursorBegin, int cursorEnd) => + public void SetText(string text, int cursorBegin, int cursorEnd) => Dispatcher.UIThread.Post(() => { _hiddenTextBox.Text = text; diff --git a/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml.cs b/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml.cs index ea061c5dc..ad9f1a0bc 100644 --- a/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml.cs +++ b/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml.cs @@ -224,7 +224,7 @@ public void OpenPtcDirectory_Click(object sender, RoutedEventArgs args) { if (sender is not MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel }) return; - + string ptcDir = Path.Combine(AppDataManager.GamesDirPath, viewModel.SelectedApplication.IdString, "cache", "cpu"); string mainDir = Path.Combine(ptcDir, "0"); string backupDir = Path.Combine(ptcDir, "1"); diff --git a/src/Ryujinx/UI/Helpers/ContentDialogHelper.cs b/src/Ryujinx/UI/Helpers/ContentDialogHelper.cs index 2caf1f0cb..19dd3fd33 100644 --- a/src/Ryujinx/UI/Helpers/ContentDialogHelper.cs +++ b/src/Ryujinx/UI/Helpers/ContentDialogHelper.cs @@ -199,7 +199,7 @@ public static Task CreateInfoDialog( string secondaryText, string acceptButton, string closeButton, - string title) + string title) => ShowTextDialog( title, primary, @@ -215,7 +215,7 @@ internal static async Task CreateConfirmationDialog( string acceptButtonText, string cancelButtonText, string title, - UserResult primaryButtonResult = UserResult.Yes) + UserResult primaryButtonResult = UserResult.Yes) => await ShowTextDialog( string.IsNullOrWhiteSpace(title) ? LocaleManager.Instance[LocaleKeys.DialogConfirmationTitle] : title, primaryText, @@ -226,7 +226,7 @@ internal static async Task CreateConfirmationDialog( (int)Symbol.Help, primaryButtonResult); - internal static async Task CreateLocalizedConfirmationDialog(string primaryText, string secondaryText) + internal static async Task CreateLocalizedConfirmationDialog(string primaryText, string secondaryText) => await CreateConfirmationDialog( primaryText, secondaryText, @@ -234,7 +234,7 @@ internal static async Task CreateLocalizedConfirmationDialog(string LocaleManager.Instance[LocaleKeys.InputDialogNo], LocaleManager.Instance[LocaleKeys.RyujinxConfirm]); - internal static async Task CreateUpdaterInfoDialog(string primary, string secondaryText) + internal static async Task CreateUpdaterInfoDialog(string primary, string secondaryText) => await ShowTextDialog( LocaleManager.Instance[LocaleKeys.DialogUpdaterTitle], primary, @@ -244,7 +244,7 @@ internal static async Task CreateUpdaterInfoDialog(string primary, string second LocaleManager.Instance[LocaleKeys.InputDialogOk], (int)Symbol.Important); - internal static async Task CreateWarningDialog(string primary, string secondaryText) + internal static async Task CreateWarningDialog(string primary, string secondaryText) => await ShowTextDialog( LocaleManager.Instance[LocaleKeys.DialogWarningTitle], primary, diff --git a/src/Ryujinx/UI/Helpers/UserErrorDialog.cs b/src/Ryujinx/UI/Helpers/UserErrorDialog.cs index a6ede18ea..c0b552454 100644 --- a/src/Ryujinx/UI/Helpers/UserErrorDialog.cs +++ b/src/Ryujinx/UI/Helpers/UserErrorDialog.cs @@ -39,8 +39,8 @@ public static async Task ShowUserErrorDialog(UserError error) await ContentDialogHelper.CreateInfoDialog( LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogUserErrorDialogMessage, errorCode, GetErrorTitle(error)), - GetErrorDescription(error), - "", + GetErrorDescription(error), + "", LocaleManager.Instance[LocaleKeys.InputDialogOk], LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogUserErrorDialogTitle, errorCode)); } diff --git a/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs b/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs index 2cad8aeca..3fb991531 100644 --- a/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs @@ -45,7 +45,7 @@ public class InputViewModel : BaseModel, IDisposable private PlayerIndex _playerId; private int _controller; - private int _controllerNumber; + private readonly int _controllerNumber; private string _controllerImage; private int _device; private object _configViewModel; diff --git a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs index ce6ae5b7f..f201bba6f 100644 --- a/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs @@ -913,7 +913,7 @@ public KeyGesture ScreenshotKey public KeyGesture PauseKey { - get => KeyGesture.Parse(_pauseKey); + get => KeyGesture.Parse(_pauseKey); set { _pauseKey = value.ToString(); diff --git a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs index 5c7d099d6..537418ea9 100644 --- a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs @@ -14,6 +14,7 @@ using Ryujinx.Common.GraphicsDriver; using Ryujinx.Common.Logging; using Ryujinx.Graphics.Vulkan; +using Ryujinx.HLE; using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.HOS.Services.Time.TimeZone; using Ryujinx.UI.Common.Configuration; @@ -154,7 +155,7 @@ public bool AutoloadDirectoryChanged public bool EnableInternetAccess { get; set; } public bool EnableFsIntegrityChecks { get; set; } public bool IgnoreMissingServices { get; set; } - public bool ExpandDramSize { get; set; } + public MemoryConfiguration DramSize { get; set; } public bool EnableShaderCache { get; set; } public bool EnableTextureRecompression { get; set; } public bool EnableMacroHLE { get; set; } @@ -444,7 +445,7 @@ public void LoadCurrentConfiguration() EnableVsync = config.Graphics.EnableVsync; EnableFsIntegrityChecks = config.System.EnableFsIntegrityChecks; - ExpandDramSize = config.System.ExpandRam; + DramSize = config.System.DramSize; IgnoreMissingServices = config.System.IgnoreMissingServices; // CPU @@ -545,7 +546,7 @@ public void SaveSettings() config.System.SystemTimeOffset.Value = Convert.ToInt64((CurrentDate.ToUnixTimeSeconds() + CurrentTime.TotalSeconds) - DateTimeOffset.Now.ToUnixTimeSeconds()); config.Graphics.EnableVsync.Value = EnableVsync; config.System.EnableFsIntegrityChecks.Value = EnableFsIntegrityChecks; - config.System.ExpandRam.Value = ExpandDramSize; + config.System.DramSize.Value = DramSize; config.System.IgnoreMissingServices.Value = IgnoreMissingServices; // CPU diff --git a/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs index e8e6cd8a2..fad7a08f7 100644 --- a/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs +++ b/src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs @@ -143,14 +143,14 @@ public async void OpenMiiApplet(object sender, RoutedEventArgs e) } } - public async void OpenAmiiboWindow(object sender, RoutedEventArgs e) + public async void OpenAmiiboWindow(object sender, RoutedEventArgs e) => await ViewModel.OpenAmiiboWindow(); public async void OpenCheatManagerForCurrentApp(object sender, RoutedEventArgs e) { if (!ViewModel.IsGameRunning) return; - + string name = ViewModel.AppHost.Device.Processes.ActiveApplication.ApplicationControlProperties.Title[(int)ViewModel.AppHost.Device.System.State.DesiredTitleLanguage].NameString.ToString(); await new CheatWindow( @@ -186,7 +186,8 @@ private async void UninstallFileTypes_Click(object sender, RoutedEventArgs e) private async void ChangeWindowSize_Click(object sender, RoutedEventArgs e) { - if (sender is not MenuItem { Tag: string resolution }) return; + if (sender is not MenuItem { Tag: string resolution }) + return; (int height, int width) = resolution.Split(' ') .Into(parts => (int.Parse(parts[0]), int.Parse(parts[1]))); diff --git a/src/Ryujinx/UI/Views/Settings/SettingsSystemView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsSystemView.axaml index e6f7c6e46..384231880 100644 --- a/src/Ryujinx/UI/Views/Settings/SettingsSystemView.axaml +++ b/src/Ryujinx/UI/Views/Settings/SettingsSystemView.axaml @@ -1,4 +1,4 @@ - + + + + + + + + + + + + + + + + + - - - @@ -221,4 +242,4 @@ - \ No newline at end of file + diff --git a/src/Ryujinx/UI/Windows/MainWindow.axaml.cs b/src/Ryujinx/UI/Windows/MainWindow.axaml.cs index ca6cd9fac..8a47447d9 100644 --- a/src/Ryujinx/UI/Windows/MainWindow.axaml.cs +++ b/src/Ryujinx/UI/Windows/MainWindow.axaml.cs @@ -83,7 +83,7 @@ public MainWindow() TitleBar.ExtendsContentIntoTitleBar = true; TitleBar.TitleBarHitTestType = TitleBarHitTestType.Complex; - + // NOTE: Height of MenuBar and StatusBar is not usable here, since it would still be 0 at this point. StatusBarHeight = StatusBarView.StatusBar.MinHeight; @@ -665,8 +665,9 @@ private void ShowNewContentAddedDialog(int numDlcAdded, int numUpdatesAdded) ? string.Format(LocaleManager.Instance[LocaleKeys.AutoloadUpdateAddedMessage], numUpdatesAdded) : null; - if (msg is null) return; - + if (msg is null) + return; + Dispatcher.UIThread.InvokeAsync(async () => {