Эх сурвалжийг харах

Replace 'Expand DRAM' option with dropdown menu (#32)

Allows to use mods that require a larger memory pool to allocate from.
Keaton 1 жил өмнө
parent
commit
f76a97c976
54 өөрчлөгдсөн 416 нэмэгдсэн , 118 устгасан
  1. 1 1
      src/Ryujinx.Common/Collections/IntervalTree.cs
  2. 194 14
      src/Ryujinx.Common/Hash128.cs
  3. 2 2
      src/Ryujinx.Common/Utilities/BitUtils.cs
  4. 1 1
      src/Ryujinx.Graphics.Nvdec.FFmpeg/H264/H264BitStreamWriter.cs
  5. 1 1
      src/Ryujinx.Graphics.Texture/OffsetCalculator.cs
  6. 3 3
      src/Ryujinx.HLE/FileSystem/ContentManager.cs
  7. 4 1
      src/Ryujinx.HLE/HOS/Kernel/Common/KSystemControl.cs
  8. 1 0
      src/Ryujinx.HLE/HOS/Kernel/Common/MemoryArrange.cs
  9. 1 0
      src/Ryujinx.HLE/HOS/Kernel/Common/MemorySize.cs
  10. 9 5
      src/Ryujinx.HLE/MemoryConfiguration.cs
  11. 1 1
      src/Ryujinx.Headless.SDL2/HeadlessDynamicTextInputHandler.cs
  12. 3 2
      src/Ryujinx.Headless.SDL2/Options.cs
  13. 1 1
      src/Ryujinx.Headless.SDL2/Program.cs
  14. 4 2
      src/Ryujinx.Input.SDL2/SDL2Gamepad.cs
  15. 3 2
      src/Ryujinx.UI.Common/Configuration/ConfigurationFileFormat.cs
  16. 16 6
      src/Ryujinx.UI.Common/Configuration/ConfigurationState.cs
  17. 4 4
      src/Ryujinx.UI.Common/DiscordIntegrationModule.cs
  18. 0 1
      src/Ryujinx.UI.Common/Helper/SetupValidator.cs
  19. 1 1
      src/Ryujinx.UI.Common/Helper/TitleHelper.cs
  20. 4 3
      src/Ryujinx.UI.Common/Helper/TitleUpdatesHelper.cs
  21. 2 2
      src/Ryujinx.UI.Common/SystemInfo/SystemInfo.cs
  22. 2 2
      src/Ryujinx/App.axaml.cs
  23. 4 6
      src/Ryujinx/AppHost.cs
  24. 5 1
      src/Ryujinx/Assets/Locales/ar_SA.json
  25. 5 1
      src/Ryujinx/Assets/Locales/de_DE.json
  26. 5 1
      src/Ryujinx/Assets/Locales/el_GR.json
  27. 5 1
      src/Ryujinx/Assets/Locales/en_US.json
  28. 5 1
      src/Ryujinx/Assets/Locales/es_ES.json
  29. 5 1
      src/Ryujinx/Assets/Locales/fr_FR.json
  30. 5 1
      src/Ryujinx/Assets/Locales/he_IL.json
  31. 5 1
      src/Ryujinx/Assets/Locales/it_IT.json
  32. 5 1
      src/Ryujinx/Assets/Locales/ja_JP.json
  33. 5 1
      src/Ryujinx/Assets/Locales/ko_KR.json
  34. 5 1
      src/Ryujinx/Assets/Locales/pl_PL.json
  35. 5 1
      src/Ryujinx/Assets/Locales/pt_BR.json
  36. 5 1
      src/Ryujinx/Assets/Locales/ru_RU.json
  37. 5 1
      src/Ryujinx/Assets/Locales/th_TH.json
  38. 5 1
      src/Ryujinx/Assets/Locales/tr_TR.json
  39. 5 1
      src/Ryujinx/Assets/Locales/uk_UA.json
  40. 5 1
      src/Ryujinx/Assets/Locales/zh_CN.json
  41. 5 1
      src/Ryujinx/Assets/Locales/zh_TW.json
  42. 2 1
      src/Ryujinx/Common/Locale/LocaleExtension.cs
  43. 2 2
      src/Ryujinx/Common/Locale/LocaleManager.cs
  44. 9 9
      src/Ryujinx/Program.cs
  45. 1 1
      src/Ryujinx/UI/Applet/AvaloniaDynamicTextInputHandler.cs
  46. 1 1
      src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml.cs
  47. 5 5
      src/Ryujinx/UI/Helpers/ContentDialogHelper.cs
  48. 2 2
      src/Ryujinx/UI/Helpers/UserErrorDialog.cs
  49. 1 1
      src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs
  50. 1 1
      src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs
  51. 4 3
      src/Ryujinx/UI/ViewModels/SettingsViewModel.cs
  52. 4 3
      src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs
  53. 28 7
      src/Ryujinx/UI/Views/Settings/SettingsSystemView.axaml
  54. 4 3
      src/Ryujinx/UI/Windows/MainWindow.axaml.cs

+ 1 - 1
src/Ryujinx.Common/Collections/IntervalTree.cs

@@ -492,7 +492,7 @@ namespace Ryujinx.Common.Collections
             Start = start;
             End = end;
             Max = end;
-            Values = [ new RangeNode<TKey, TValue>(start, end, value) ];
+            Values = [new RangeNode<TKey, TValue>(start, end, value)];
             Parent = parent;
         }
     }

+ 194 - 14
src/Ryujinx.Common/Hash128.cs

@@ -4,8 +4,8 @@ using System.Diagnostics;
 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 @@ namespace Ryujinx.Common
 
         private static ReadOnlySpan<byte> 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 @@ namespace Ryujinx.Common
             };
         }
 
-#endregion
+        #endregion
     }
 }

+ 2 - 2
src/Ryujinx.Common/Utilities/BitUtils.cs

@@ -7,10 +7,10 @@ namespace Ryujinx.Common
         public static T AlignUp<T>(T value, T size) where T : IBinaryInteger<T>
             => (value + (size - T.One)) & -size;
 
-        public static T AlignDown<T>(T value, T size) where T : IBinaryInteger<T> 
+        public static T AlignDown<T>(T value, T size) where T : IBinaryInteger<T>
             => value & -size;
 
-        public static T DivRoundUp<T>(T value, T dividend) where T : IBinaryInteger<T> 
+        public static T DivRoundUp<T>(T value, T dividend) where T : IBinaryInteger<T>
             => (value + (dividend - T.One)) / dividend;
 
         public static int Pow2RoundDown(int value) => BitOperations.IsPow2(value) ? value : Pow2RoundUp(value) >> 1;

+ 1 - 1
src/Ryujinx.Graphics.Nvdec.FFmpeg/H264/H264BitStreamWriter.cs

@@ -72,7 +72,7 @@ namespace Ryujinx.Graphics.Nvdec.FFmpeg.H264
             Flush();
         }
 
-        public readonly Span<byte> AsSpan() 
+        public readonly Span<byte> AsSpan()
             => new Span<byte>(workBuffer)[.._offset];
 
         public void WriteU(uint value, int valueSize) => WriteBits((int)value, valueSize);

+ 1 - 1
src/Ryujinx.Graphics.Texture/OffsetCalculator.cs

@@ -114,7 +114,7 @@ namespace Ryujinx.Graphics.Texture
                        _height == other._height &&
                        _stride == other._stride &&
                        _bytesPerPixel == other._bytesPerPixel;
-            
+
 
             return !other._isLinear && _layoutConverter.LayoutMatches(other._layoutConverter);
         }

+ 3 - 3
src/Ryujinx.HLE/FileSystem/ContentManager.cs

@@ -589,12 +589,12 @@ namespace Ryujinx.HLE.FileSystem
             // 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<ulong, List<(NcaContentType type, string path)>> 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 @@ namespace Ryujinx.HLE.FileSystem
 
             return null;
 
-            SystemVersion VerifyAndGetVersionDirectory(string firmwareDirectory) 
+            SystemVersion VerifyAndGetVersionDirectory(string firmwareDirectory)
                 => VerifyAndGetVersion(new LocalFileSystem(firmwareDirectory));
 
             SystemVersion VerifyAndGetVersionZip(ZipArchive archive)

+ 4 - 1
src/Ryujinx.HLE/HOS/Kernel/Common/KSystemControl.cs

@@ -30,6 +30,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Common
                 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 @@ namespace Ryujinx.HLE.HOS.Kernel.Common
                 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 @@ namespace Ryujinx.HLE.HOS.Kernel.Common
                 MemorySize.MemorySize4GiB => 4 * GiB,
                 MemorySize.MemorySize6GiB => 6 * GiB,
                 MemorySize.MemorySize8GiB => 8 * GiB,
+                MemorySize.MemorySize12GiB => 12 * GiB,
                 _ => throw new ArgumentException($"Invalid memory size \"{size}\"."),
             };
         }

+ 1 - 0
src/Ryujinx.HLE/HOS/Kernel/Common/MemoryArrange.cs

@@ -8,5 +8,6 @@ namespace Ryujinx.HLE.HOS.Kernel.Common
         MemoryArrange6GiB,
         MemoryArrange6GiBAppletDev,
         MemoryArrange8GiB,
+        MemoryArrange12GiB,
     }
 }

+ 1 - 0
src/Ryujinx.HLE/HOS/Kernel/Common/MemorySize.cs

@@ -5,5 +5,6 @@ namespace Ryujinx.HLE.HOS.Kernel.Common
         MemorySize4GiB = 0,
         MemorySize6GiB = 1,
         MemorySize8GiB = 2,
+        MemorySize12GiB = 3,
     }
 }

+ 9 - 5
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 @@ namespace Ryujinx.HLE
                 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 @@ namespace Ryujinx.HLE
                 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 @@ namespace Ryujinx.HLE
                 MemoryConfiguration.MemoryConfiguration6GiB or
                 MemoryConfiguration.MemoryConfiguration6GiBAppletDev => 6 * GiB,
                 MemoryConfiguration.MemoryConfiguration8GiB          => 8 * GiB,
+                MemoryConfiguration.MemoryConfiguration12GiB         => 12 * GiB,
                 _ => throw new AggregateException($"Invalid memory configuration \"{configuration}\"."),
             };
         }

+ 1 - 1
src/Ryujinx.Headless.SDL2/HeadlessDynamicTextInputHandler.cs

@@ -18,7 +18,7 @@ namespace Ryujinx.Headless.SDL2
         public bool TextProcessingEnabled
         {
             get => Volatile.Read(ref _canProcessInput);
-            
+
             set
             {
                 Volatile.Write(ref _canProcessInput, value);

+ 3 - 2
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 @@ namespace Ryujinx.Headless.SDL2
 
         // 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; }

+ 1 - 1
src/Ryujinx.Headless.SDL2/Program.cs

@@ -562,7 +562,7 @@ namespace Ryujinx.Headless.SDL2
                 _userChannelPersistence,
                 renderer,
                 new SDL2HardwareDeviceDriver(),
-                options.ExpandRAM ? MemoryConfiguration.MemoryConfiguration8GiB : MemoryConfiguration.MemoryConfiguration4GiB,
+                options.DramSize,
                 window,
                 options.SystemLanguage,
                 options.SystemRegion,

+ 4 - 2
src/Ryujinx.Input.SDL2/SDL2Gamepad.cs

@@ -147,7 +147,8 @@ namespace Ryujinx.Input.SDL2
 
         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 @@ namespace Ryujinx.Input.SDL2
                 // 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))

+ 3 - 2
src/Ryujinx.UI.Common/Configuration/ConfigurationFileFormat.cs

@@ -3,6 +3,7 @@ using Ryujinx.Common.Configuration.Hid;
 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 @@ namespace Ryujinx.UI.Common.Configuration
         /// <summary>
         /// The current version of the file format
         /// </summary>
-        public const int CurrentVersion = 53;
+        public const int CurrentVersion = 54;
 
         /// <summary>
         /// Version of the configuration file format
@@ -245,7 +246,7 @@ namespace Ryujinx.UI.Common.Configuration
         /// <summary>
         /// Expands the RAM amount on the emulated system from 4GiB to 8GiB
         /// </summary>
-        public bool ExpandRam { get; set; }
+        public MemoryConfiguration DramSize { get; set; }
 
         /// <summary>
         /// Enable or disable ignoring missing services

+ 16 - 6
src/Ryujinx.UI.Common/Configuration/ConfigurationState.cs

@@ -7,6 +7,7 @@ using Ryujinx.Common.Configuration.Hid.Keyboard;
 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 @@ namespace Ryujinx.UI.Common.Configuration
             /// <summary>
             /// Defines the amount of RAM available on the emulated system, and how it is distributed
             /// </summary>
-            public ReactiveObject<bool> ExpandRam { get; private set; }
+            public ReactiveObject<MemoryConfiguration> DramSize { get; private set; }
 
             /// <summary>
             /// Enable or disable ignoring missing services
@@ -400,8 +401,8 @@ namespace Ryujinx.UI.Common.Configuration
                 AudioBackend.Event += static (sender, e) => LogValueChange(e, nameof(AudioBackend));
                 MemoryManagerMode = new ReactiveObject<MemoryManagerMode>();
                 MemoryManagerMode.Event += static (sender, e) => LogValueChange(e, nameof(MemoryManagerMode));
-                ExpandRam = new ReactiveObject<bool>();
-                ExpandRam.Event += static (sender, e) => LogValueChange(e, nameof(ExpandRam));
+                DramSize = new ReactiveObject<MemoryConfiguration>();
+                DramSize.Event += static (sender, e) => LogValueChange(e, nameof(DramSize));
                 IgnoreMissingServices = new ReactiveObject<bool>();
                 IgnoreMissingServices.Event += static (sender, e) => LogValueChange(e, nameof(IgnoreMissingServices));
                 AudioVolume = new ReactiveObject<float>();
@@ -721,7 +722,7 @@ namespace Ryujinx.UI.Common.Configuration
                 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 @@ namespace Ryujinx.UI.Common.Configuration
             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 @@ namespace Ryujinx.UI.Common.Configuration
                 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 @@ namespace Ryujinx.UI.Common.Configuration
             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;

+ 4 - 4
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 @@ namespace Ryujinx.UI.Common
                 },
                 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 @@ namespace Ryujinx.UI.Common
             _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

+ 0 - 1
src/Ryujinx.UI.Common/Helper/SetupValidator.cs

@@ -98,7 +98,6 @@ namespace Ryujinx.UI.Common.Helper
                 if (baseApplicationExtension is not (".nro" or ".nso"))
                     return IsFirmwareValid(contentManager, out error);
 
-                error = UserError.Success;
             }
 
             error = UserError.ApplicationNotFound;

+ 1 - 1
src/Ryujinx.UI.Common/Helper/TitleHelper.cs

@@ -9,7 +9,7 @@ namespace Ryujinx.UI.Common.Helper
         {
             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()})";

+ 4 - 3
src/Ryujinx.UI.Common/Helper/TitleUpdatesHelper.cs

@@ -87,7 +87,8 @@ namespace Ryujinx.UI.Common.Helper
 
             foreach (string path in titleUpdateMetadata.Paths)
             {
-                if (!File.Exists(path)) continue;
+                if (!File.Exists(path))
+                    continue;
 
                 try
                 {
@@ -104,7 +105,7 @@ namespace Ryujinx.UI.Common.Helper
 
                     if (controlNca is null || patchNca is null)
                         continue;
-                    
+
                     ApplicationControlProperty controlData = new();
 
                     using UniqueRef<IFile> nacpFile = new();
@@ -144,7 +145,7 @@ namespace Ryujinx.UI.Common.Helper
             return result;
         }
 
-        private static string PathToGameUpdatesJson(ulong applicationIdBase) 
+        private static string PathToGameUpdatesJson(ulong applicationIdBase)
             => Path.Combine(AppDataManager.GamesDirPath, applicationIdBase.ToString("x16"), "updates.json");
     }
 }

+ 2 - 2
src/Ryujinx.UI.Common/SystemInfo/SystemInfo.cs

@@ -34,10 +34,10 @@ namespace Ryujinx.UI.Common.SystemInfo
         {
             if (OperatingSystem.IsWindows())
                 return new WindowsSystemInfo();
-            
+
             if (OperatingSystem.IsLinux())
                 return new LinuxSystemInfo();
-            
+
             if (OperatingSystem.IsMacOS())
                 return new MacOSSystemInfo();
 

+ 2 - 2
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!

+ 4 - 6
src/Ryujinx/AppHost.cs

@@ -541,7 +541,7 @@ namespace Ryujinx.Ava
         {
             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 @@ namespace Ryujinx.Ava
                 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 @@ namespace Ryujinx.Ava
             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 @@ 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.SystemTimeOffset,
                 ConfigurationState.Instance.System.TimeZone,
                 ConfigurationState.Instance.System.MemoryManagerMode,
                 ConfigurationState.Instance.System.IgnoreMissingServices,

+ 5 - 1
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 الرسومات ",

+ 5 - 1
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",

+ 5 - 1
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 Γραφικά",

+ 5 - 1
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",

+ 5 - 1
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",

+ 5 - 1
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",

+ 5 - 1
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": "ממשק גראפי",

+ 5 - 1
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",

+ 5 - 1
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",

+ 5 - 1
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",

+ 5 - 1
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",

+ 5 - 1
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",

+ 5 - 1
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",

+ 5 - 1
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",

+ 5 - 1
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",

+ 5 - 1
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",

+ 5 - 1
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",

+ 5 - 1
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",

+ 2 - 1
src/Ryujinx/Common/Locale/LocaleExtension.cs

@@ -21,7 +21,8 @@ namespace Ryujinx.Ava.Common.Locale
                     new CompiledBindingPathBuilder()
                         .Property(PropertyInfo, PropertyInfoAccessorFactory.CreateInpcPropertyAccessor)
                         .Build()
-                ) { Source = LocaleManager.Instance }
+                )
+            { Source = LocaleManager.Instance }
                 .ProvideValue(serviceProvider);
     }
 }

+ 2 - 2
src/Ryujinx/Common/Locale/LocaleManager.cs

@@ -80,8 +80,8 @@ namespace Ryujinx.Ava.Common.Locale
                 }
 
                 // 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

+ 9 - 9
src/Ryujinx/Program.cs

@@ -72,23 +72,23 @@ namespace Ryujinx.Ava
                     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 @@ namespace Ryujinx.Ava
             // 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 @@ namespace Ryujinx.Ava
                     "always" => HideCursorMode.Always,
                     _ => ConfigurationState.Instance.HideCursor,
                 };
-            
+
 
             // Check if hardware-acceleration was overridden.
             if (CommandLineState.OverrideHardwareAcceleration != null)

+ 1 - 1
src/Ryujinx/UI/Applet/AvaloniaDynamicTextInputHandler.cs

@@ -136,7 +136,7 @@ namespace Ryujinx.Ava.UI.Applet
                 _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;

+ 1 - 1
src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml.cs

@@ -224,7 +224,7 @@ namespace Ryujinx.Ava.UI.Controls
         {
             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");

+ 5 - 5
src/Ryujinx/UI/Helpers/ContentDialogHelper.cs

@@ -199,7 +199,7 @@ namespace Ryujinx.Ava.UI.Helpers
             string secondaryText,
             string acceptButton,
             string closeButton,
-            string title) 
+            string title)
             => ShowTextDialog(
                 title,
                 primary,
@@ -215,7 +215,7 @@ namespace Ryujinx.Ava.UI.Helpers
             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 @@ namespace Ryujinx.Ava.UI.Helpers
                 (int)Symbol.Help,
                 primaryButtonResult);
 
-        internal static async Task<UserResult> CreateLocalizedConfirmationDialog(string primaryText, string secondaryText) 
+        internal static async Task<UserResult> CreateLocalizedConfirmationDialog(string primaryText, string secondaryText)
             => await CreateConfirmationDialog(
                 primaryText,
                 secondaryText,
@@ -234,7 +234,7 @@ namespace Ryujinx.Ava.UI.Helpers
                 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 @@ namespace Ryujinx.Ava.UI.Helpers
                 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,

+ 2 - 2
src/Ryujinx/UI/Helpers/UserErrorDialog.cs

@@ -39,8 +39,8 @@ namespace Ryujinx.Ava.UI.Helpers
 
             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));
         }

+ 1 - 1
src/Ryujinx/UI/ViewModels/Input/InputViewModel.cs

@@ -45,7 +45,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
 
         private PlayerIndex _playerId;
         private int _controller;
-        private int _controllerNumber;
+        private readonly int _controllerNumber;
         private string _controllerImage;
         private int _device;
         private object _configViewModel;

+ 1 - 1
src/Ryujinx/UI/ViewModels/MainWindowViewModel.cs

@@ -913,7 +913,7 @@ namespace Ryujinx.Ava.UI.ViewModels
 
         public KeyGesture PauseKey
         {
-            get => KeyGesture.Parse(_pauseKey); 
+            get => KeyGesture.Parse(_pauseKey);
             set
             {
                 _pauseKey = value.ToString();

+ 4 - 3
src/Ryujinx/UI/ViewModels/SettingsViewModel.cs

@@ -14,6 +14,7 @@ using Ryujinx.Common.Configuration.Multiplayer;
 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 @@ namespace Ryujinx.Ava.UI.ViewModels
         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 @@ namespace Ryujinx.Ava.UI.ViewModels
 
             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 @@ namespace Ryujinx.Ava.UI.ViewModels
             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

+ 4 - 3
src/Ryujinx/UI/Views/Main/MainMenuBarView.axaml.cs

@@ -143,14 +143,14 @@ namespace Ryujinx.Ava.UI.Views.Main
             }
         }
 
-        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 @@ namespace Ryujinx.Ava.UI.Views.Main
 
         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])));

+ 28 - 7
src/Ryujinx/UI/Views/Settings/SettingsSystemView.axaml

@@ -1,4 +1,4 @@
-<UserControl
+<UserControl
     x:Class="Ryujinx.Ava.UI.Views.Settings.SettingsSystemView"
     xmlns="https://github.com/avaloniaui"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
@@ -203,15 +203,36 @@
                         Foreground="{DynamicResource SecondaryTextColor}"
                         Text="{locale:Locale SettingsTabSystemHacksNote}" />
                 </StackPanel>
+                <StackPanel
+                    Margin="10,0,0,0"
+                    Orientation="Horizontal">
+                    <TextBlock
+                        VerticalAlignment="Center"
+                        Text="{locale:Locale SettingsTabSystemDramSize}"
+                        Width="250" />
+                    <ComboBox
+                        SelectedIndex="{Binding DramSize}"
+                        ToolTip.Tip="{locale:Locale DRamTooltip}"
+                        HorizontalContentAlignment="Left"
+                        Width="350">
+                        <ComboBoxItem>
+                            <TextBlock Text="{locale:Locale SettingsTabSystemDramSize4GiB}" />
+                        </ComboBoxItem>
+                        <ComboBoxItem>
+                            <TextBlock Text="{locale:Locale SettingsTabSystemDramSize6GiB}" />
+                        </ComboBoxItem>
+                        <ComboBoxItem>
+                            <TextBlock Text="{locale:Locale SettingsTabSystemDramSize8GiB}" />
+                        </ComboBoxItem>
+                        <ComboBoxItem>
+                            <TextBlock Text="{locale:Locale SettingsTabSystemDramSize12GiB}" />
+                        </ComboBoxItem>
+                    </ComboBox>
+                </StackPanel>
                 <StackPanel
                     Margin="10,0,0,0"
                     HorizontalAlignment="Stretch"
                     Orientation="Vertical">
-                    <CheckBox
-                        IsChecked="{Binding ExpandDramSize}"
-                        ToolTip.Tip="{locale:Locale DRamTooltip}">
-                        <TextBlock Text="{locale:Locale SettingsTabSystemExpandDramSize}" />
-                    </CheckBox>
                     <CheckBox
                         IsChecked="{Binding IgnoreMissingServices}"
                         ToolTip.Tip="{locale:Locale IgnoreMissingServicesTooltip}">
@@ -221,4 +242,4 @@
             </StackPanel>
         </Border>
     </ScrollViewer>
-</UserControl>
+</UserControl>

+ 4 - 3
src/Ryujinx/UI/Windows/MainWindow.axaml.cs

@@ -83,7 +83,7 @@ namespace Ryujinx.Ava.UI.Windows
 
             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 @@ namespace Ryujinx.Ava.UI.Windows
                         ? string.Format(LocaleManager.Instance[LocaleKeys.AutoloadUpdateAddedMessage], numUpdatesAdded)
                         : null;
 
-            if (msg is null) return;
-            
+            if (msg is null)
+                return;
+
 
             Dispatcher.UIThread.InvokeAsync(async () =>
             {