diff --git a/src/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs b/src/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs
index 6b8152b9d..efdb422e7 100644
--- a/src/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs
+++ b/src/Ryujinx.Common/Configuration/Hid/KeyboardHotkeys.cs
@@ -13,5 +13,7 @@ namespace Ryujinx.Common.Configuration.Hid
public Key VolumeDown { get; set; }
public Key CustomVSyncIntervalIncrement { get; set; }
public Key CustomVSyncIntervalDecrement { get; set; }
+ public Key TurboMode { get; set; }
+ public bool TurboModeWhileHeld { get; set; }
}
}
diff --git a/src/Ryujinx.Cpu/ITickSource.cs b/src/Ryujinx.Cpu/ITickSource.cs
index e65e99e26..c352df85a 100644
--- a/src/Ryujinx.Cpu/ITickSource.cs
+++ b/src/Ryujinx.Cpu/ITickSource.cs
@@ -12,6 +12,11 @@ namespace Ryujinx.Cpu
/// Time elapsed since the counter was created.
///
TimeSpan ElapsedTime { get; }
+
+ ///
+ /// Clock tick scalar, in percent points (100 = 1.0).
+ ///
+ long TickScalar { get; set; }
///
/// Time elapsed since the counter was created, in seconds.
diff --git a/src/Ryujinx.Cpu/TickSource.cs b/src/Ryujinx.Cpu/TickSource.cs
index eee83fc62..3bc01d6b9 100644
--- a/src/Ryujinx.Cpu/TickSource.cs
+++ b/src/Ryujinx.Cpu/TickSource.cs
@@ -14,12 +14,37 @@ namespace Ryujinx.Cpu
///
public ulong Counter => (ulong)(ElapsedSeconds * Frequency);
+
+
+ public long TickScalar { get; set; }
+
+
+ private static long _acumElapsedTicks;
+
+
+ private static long _lastElapsedTicks;
+
+
+ private long ElapsedTicks
+ {
+ get
+ {
+ long elapsedTicks = _tickCounter.ElapsedTicks;
+
+ _acumElapsedTicks += (elapsedTicks - _lastElapsedTicks) * TickScalar / 100;
+
+ _lastElapsedTicks = elapsedTicks;
+
+ return _acumElapsedTicks;
+ }
+ }
///
- public TimeSpan ElapsedTime => _tickCounter.Elapsed;
+
+ public TimeSpan ElapsedTime => Stopwatch.GetElapsedTime(0, ElapsedTicks);
///
- public double ElapsedSeconds => _tickCounter.ElapsedTicks * _hostTickFreq;
+ public double ElapsedSeconds => ElapsedTicks * _hostTickFreq;
public TickSource(ulong frequency)
{
diff --git a/src/Ryujinx.HLE/HLEConfiguration.cs b/src/Ryujinx.HLE/HLEConfiguration.cs
index 0b7ae3974..e2132bb5a 100644
--- a/src/Ryujinx.HLE/HLEConfiguration.cs
+++ b/src/Ryujinx.HLE/HLEConfiguration.cs
@@ -102,6 +102,11 @@ namespace Ryujinx.HLE
/// Control if the Profiled Translation Cache (PTC) should be used.
///
internal readonly bool EnablePtc;
+
+ ///
+ /// Control the arbitrary scalar applied to emulated CPU tick timing.
+ ///
+ public long TickScalar { get; set; }
///
/// Control if the guest application should be told that there is a Internet connection available.
@@ -225,6 +230,7 @@ namespace Ryujinx.HLE
string multiplayerLdnPassphrase,
string multiplayerLdnServer,
int customVSyncInterval,
+ long tickScalar,
EnabledDirtyHack[] dirtyHacks = null)
{
VirtualFileSystem = virtualFileSystem;
@@ -257,6 +263,7 @@ namespace Ryujinx.HLE
MultiplayerDisableP2p = multiplayerDisableP2p;
MultiplayerLdnPassphrase = multiplayerLdnPassphrase;
MultiplayerLdnServer = multiplayerLdnServer;
+ TickScalar = tickScalar;
Hacks = dirtyHacks ?? [];
}
}
diff --git a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs
index 935e9895e..294192363 100644
--- a/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs
+++ b/src/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs
@@ -2,6 +2,7 @@ using Ryujinx.Common;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Common.PreciseSleep;
+using Ryujinx.Cpu;
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Gpu;
using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap;
@@ -89,7 +90,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
}
else
{
- _ticksPerFrame = Stopwatch.Frequency / _device.TargetVSyncInterval;
+ _ticksPerFrame = ((Stopwatch.Frequency / _device.TargetVSyncInterval) * 100) / _device.TickScalar;
_targetVSyncInterval = _device.TargetVSyncInterval;
}
}
diff --git a/src/Ryujinx.HLE/PerformanceStatistics.cs b/src/Ryujinx.HLE/PerformanceStatistics.cs
index e80faa7d2..48f4a0575 100644
--- a/src/Ryujinx.HLE/PerformanceStatistics.cs
+++ b/src/Ryujinx.HLE/PerformanceStatistics.cs
@@ -6,6 +6,8 @@ namespace Ryujinx.HLE
{
public class PerformanceStatistics
{
+ private readonly Switch _device;
+
private const int FrameTypeGame = 0;
private const int PercentTypeFifo = 0;
@@ -28,8 +30,10 @@ namespace Ryujinx.HLE
private readonly System.Timers.Timer _resetTimer;
- public PerformanceStatistics()
+ public PerformanceStatistics(Switch device)
{
+ _device = device;
+
_frameRate = new double[1];
_accumulatedFrameTime = new double[1];
_previousFrameTime = new double[1];
@@ -166,8 +170,11 @@ namespace Ryujinx.HLE
{
double frameRate = GetGameFrameRate();
double frameTime = GetGameFrameTime();
+ string turboSuffix = _device.TurboMode
+ ? $" Turbo ({_device.TickScalar}%)"
+ : string.Empty;
- return $"{frameRate:00.00} FPS ({frameTime:00.00}ms)";
+ return $"{frameRate:00.00} FPS ({frameTime:00.00}ms){turboSuffix}";
}
public string FormatFifoPercent()
diff --git a/src/Ryujinx.HLE/Switch.cs b/src/Ryujinx.HLE/Switch.cs
index 86b04061e..dfa81b342 100644
--- a/src/Ryujinx.HLE/Switch.cs
+++ b/src/Ryujinx.HLE/Switch.cs
@@ -26,18 +26,26 @@ namespace Ryujinx.HLE
public GpuContext Gpu { get; }
public VirtualFileSystem FileSystem { get; }
public HOS.Horizon System { get; }
+
+ public bool TurboMode = false;
+
+ public long TickScalar
+ {
+ get => System?.TickSource?.TickScalar ?? 100;
+ set => System.TickSource.TickScalar = value;
+ }
+
public ProcessLoader Processes { get; }
public PerformanceStatistics Statistics { get; }
public Hid Hid { get; }
public TamperMachine TamperMachine { get; }
public IHostUIHandler UIHandler { get; }
- public int CpuCoresCount = 4; //Switch 1 has 4 cores
+ public int CpuCoresCount = 4; // Switch has a quad-core Tegra X1 SoC
public VSyncMode VSyncMode { get; set; }
public bool CustomVSyncIntervalEnabled { get; set; }
public int CustomVSyncInterval { get; set; }
-
public long TargetVSyncInterval { get; set; } = 60;
public bool IsFrameAvailable => Gpu.Window.IsFrameAvailable;
@@ -64,7 +72,7 @@ namespace Ryujinx.HLE
Memory = new MemoryBlock(Configuration.MemoryConfiguration.ToDramSize(), memoryAllocationFlags);
Gpu = new GpuContext(Configuration.GpuRenderer, DirtyHacks);
System = new HOS.Horizon(this);
- Statistics = new PerformanceStatistics();
+ Statistics = new PerformanceStatistics(this);
Hid = new Hid(this, System.HidStorage);
Processes = new ProcessLoader(this);
TamperMachine = new TamperMachine();
@@ -75,6 +83,7 @@ namespace Ryujinx.HLE
VSyncMode = Configuration.VSyncMode;
CustomVSyncInterval = Configuration.CustomVSyncInterval;
+ TickScalar = TurboMode ? Configuration.TickScalar : 100;
System.State.DockedMode = Configuration.EnableDockedMode;
System.PerformanceState.PerformanceMode = System.State.DockedMode ? PerformanceMode.Boost : PerformanceMode.Default;
System.EnablePtc = Configuration.EnablePtc;
@@ -122,6 +131,12 @@ namespace Ryujinx.HLE
}
}
+ public void ToggleTurbo()
+ {
+ TurboMode = !TurboMode;
+ TickScalar = TurboMode ? Configuration.TickScalar : 100;
+ }
+
public bool LoadCart(string exeFsDir, string romFsFile = null) => Processes.LoadUnpackedNca(exeFsDir, romFsFile);
public bool LoadXci(string xciFile, ulong applicationId = 0) => Processes.LoadXci(xciFile, applicationId);
public bool LoadNca(string ncaFile, BlitStruct? customNacpData = null) => Processes.LoadNca(ncaFile, customNacpData);
diff --git a/src/Ryujinx/AppHost.cs b/src/Ryujinx/AppHost.cs
index b741eb977..36716a0cb 100644
--- a/src/Ryujinx/AppHost.cs
+++ b/src/Ryujinx/AppHost.cs
@@ -947,7 +947,8 @@ namespace Ryujinx.Ava
ConfigurationState.Instance.Multiplayer.DisableP2p,
ConfigurationState.Instance.Multiplayer.LdnPassphrase,
ConfigurationState.Instance.Multiplayer.GetLdnServer(),
- ConfigurationState.Instance.Graphics.CustomVSyncInterval.Value,
+ ConfigurationState.Instance.Graphics.CustomVSyncInterval,
+ ConfigurationState.Instance.System.TickScalar,
ConfigurationState.Instance.Hacks.ShowDirtyHacks ? ConfigurationState.Instance.Hacks.EnabledHacks : null));
}
@@ -1249,6 +1250,12 @@ namespace Ryujinx.Ava
if (currentHotkeyState != _prevHotkeyState)
{
+ if (ConfigurationState.Instance.Hid.Hotkeys.Value.TurboModeWhileHeld &&
+ _keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.TurboMode) != Device.TurboMode)
+ {
+ Device.ToggleTurbo();
+ }
+
switch (currentHotkeyState)
{
case KeyboardHotkeyState.ToggleVSyncMode:
@@ -1262,6 +1269,12 @@ namespace Ryujinx.Ava
Device.IncrementCustomVSyncInterval();
_viewModel.CustomVSyncInterval += 1;
break;
+ case KeyboardHotkeyState.TurboMode:
+ if (!ConfigurationState.Instance.Hid.Hotkeys.Value.TurboModeWhileHeld)
+ {
+ Device.ToggleTurbo();
+ }
+ break;
case KeyboardHotkeyState.Screenshot:
ScreenshotRequested = true;
break;
@@ -1391,6 +1404,10 @@ namespace Ryujinx.Ava
{
state = KeyboardHotkeyState.CustomVSyncIntervalDecrement;
}
+ else if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.TurboMode))
+ {
+ state = KeyboardHotkeyState.TurboMode;
+ }
return state;
}
diff --git a/src/Ryujinx/Assets/locales.json b/src/Ryujinx/Assets/locales.json
index d69c3ee9b..659f03f41 100644
--- a/src/Ryujinx/Assets/locales.json
+++ b/src/Ryujinx/Assets/locales.json
@@ -4897,6 +4897,81 @@
"zh_TW": "低功耗 PPTC"
}
},
+ {
+ "ID": "SettingsTabSystemTurboMultiplierValue",
+ "Translations": {
+ "ar_SA": "",
+ "de_DE": "",
+ "el_GR": "",
+ "en_US": "Turbo multiplier:",
+ "es_ES": "",
+ "fr_FR": "",
+ "he_IL": "",
+ "it_IT": "",
+ "ja_JP": "",
+ "ko_KR": "",
+ "no_NO": "",
+ "pl_PL": "",
+ "pt_BR": "",
+ "ru_RU": "",
+ "sv_SE": "",
+ "th_TH": "",
+ "tr_TR": "",
+ "uk_UA": "",
+ "zh_CN": "",
+ "zh_TW": ""
+ }
+ },
+ {
+ "ID": "SettingsTabSystemTurboMultiplierSliderToolTip",
+ "Translations": {
+ "ar_SA": "",
+ "de_DE": "",
+ "el_GR": "",
+ "en_US": "The Turbo mode multiplier target value.\n\nLeave at 100 if unsure.",
+ "es_ES": "",
+ "fr_FR": "",
+ "he_IL": "",
+ "it_IT": "",
+ "ja_JP": "",
+ "ko_KR": "",
+ "no_NO": "",
+ "pl_PL": "",
+ "pt_BR": "",
+ "ru_RU": "",
+ "sv_SE": "",
+ "th_TH": "",
+ "tr_TR": "",
+ "uk_UA": "",
+ "zh_CN": "",
+ "zh_TW": ""
+ }
+ },
+ {
+ "ID": "SettingsTabSystemTurboMultiplierValueToolTip",
+ "Translations": {
+ "ar_SA": "",
+ "de_DE": "",
+ "el_GR": "",
+ "en_US": "The Turbo mode multiplier, as a percentage of the normal Switch clock speed.\n\nLeave at 100 if unsure.",
+ "es_ES": "",
+ "fr_FR": "",
+ "he_IL": "",
+ "it_IT": "",
+ "ja_JP": "",
+ "ko_KR": "",
+ "no_NO": "",
+ "pl_PL": "",
+ "pt_BR": "",
+ "ru_RU": "",
+ "sv_SE": "",
+ "th_TH": "",
+ "tr_TR": "",
+ "uk_UA": "",
+ "zh_CN": "",
+ "zh_TW": ""
+ }
+ },
{
"ID": "SettingsTabSystemEnableFsIntegrityChecks",
"Translations": {
@@ -5097,6 +5172,31 @@
"zh_TW": "可能導致模擬器不穩定"
}
},
+ {
+ "ID": "SettingsTabCpuHacksNote",
+ "Translations": {
+ "ar_SA": "",
+ "de_DE": "",
+ "el_GR": "",
+ "en_US": "Can and will cause crashing, slow/too fast games, etc. Use with caution.",
+ "es_ES": "",
+ "fr_FR": "",
+ "he_IL": "",
+ "it_IT": "",
+ "ja_JP": "",
+ "ko_KR": "",
+ "no_NO": "",
+ "pl_PL": "",
+ "pt_BR": "",
+ "ru_RU": "",
+ "sv_SE": "",
+ "th_TH": "",
+ "tr_TR": "",
+ "uk_UA": "",
+ "zh_CN": "",
+ "zh_TW": ""
+ }
+ },
{
"ID": "SettingsTabSystemDramSize",
"Translations": {
@@ -23797,6 +23897,56 @@
"zh_TW": "降低自訂的重新整理頻率"
}
},
+ {
+ "ID": "SettingsTabHotkeysTurboMode",
+ "Translations": {
+ "ar_SA": "",
+ "de_DE": "",
+ "el_GR": "",
+ "en_US": "Turbo mode:",
+ "es_ES": "",
+ "fr_FR": "",
+ "he_IL": "",
+ "it_IT": "",
+ "ja_JP": "",
+ "ko_KR": "",
+ "no_NO": "",
+ "pl_PL": "",
+ "pt_BR": "",
+ "ru_RU": "",
+ "sv_SE": "",
+ "th_TH": "",
+ "tr_TR": "",
+ "uk_UA": "",
+ "zh_CN": "",
+ "zh_TW": ""
+ }
+ },
+ {
+ "ID": "SettingsTabHotkeysOnlyWhilePressed",
+ "Translations": {
+ "ar_SA": "",
+ "de_DE": "",
+ "el_GR": "",
+ "en_US": "Only while pressed",
+ "es_ES": "",
+ "fr_FR": "",
+ "he_IL": "",
+ "it_IT": "",
+ "ja_JP": "",
+ "ko_KR": "",
+ "no_NO": "",
+ "pl_PL": "",
+ "pt_BR": "",
+ "ru_RU": "",
+ "sv_SE": "",
+ "th_TH": "",
+ "tr_TR": "",
+ "uk_UA": "",
+ "zh_CN": "",
+ "zh_TW": ""
+ }
+ },
{
"ID": "CompatibilityListLastUpdated",
"Translations": {
diff --git a/src/Ryujinx/Common/KeyboardHotkeyState.cs b/src/Ryujinx/Common/KeyboardHotkeyState.cs
index 060c678d2..b6fb02f04 100644
--- a/src/Ryujinx/Common/KeyboardHotkeyState.cs
+++ b/src/Ryujinx/Common/KeyboardHotkeyState.cs
@@ -14,5 +14,6 @@ namespace Ryujinx.Ava.Common
VolumeDown,
CustomVSyncIntervalIncrement,
CustomVSyncIntervalDecrement,
+ TurboMode,
}
}
diff --git a/src/Ryujinx/Headless/HeadlessRyujinx.Init.cs b/src/Ryujinx/Headless/HeadlessRyujinx.Init.cs
index 3ebfee751..b676b104e 100644
--- a/src/Ryujinx/Headless/HeadlessRyujinx.Init.cs
+++ b/src/Ryujinx/Headless/HeadlessRyujinx.Init.cs
@@ -352,7 +352,8 @@ namespace Ryujinx.Headless
false,
string.Empty,
string.Empty,
- options.CustomVSyncInterval);
+ options.CustomVSyncInterval,
+ 100);
return new Switch(configuration);
}
diff --git a/src/Ryujinx/UI/Models/Input/HotkeyConfig.cs b/src/Ryujinx/UI/Models/Input/HotkeyConfig.cs
index 40f53c673..9e557d7b1 100644
--- a/src/Ryujinx/UI/Models/Input/HotkeyConfig.cs
+++ b/src/Ryujinx/UI/Models/Input/HotkeyConfig.cs
@@ -28,6 +28,10 @@ namespace Ryujinx.Ava.UI.Models.Input
[ObservableProperty] private Key _customVSyncIntervalDecrement;
+ [ObservableProperty] private Key _turboMode;
+
+ [ObservableProperty] private bool _turboModeWhileHeld;
+
public HotkeyConfig(KeyboardHotkeys config)
{
if (config == null)
@@ -44,6 +48,8 @@ namespace Ryujinx.Ava.UI.Models.Input
VolumeDown = config.VolumeDown;
CustomVSyncIntervalIncrement = config.CustomVSyncIntervalIncrement;
CustomVSyncIntervalDecrement = config.CustomVSyncIntervalDecrement;
+ TurboMode = config.TurboMode;
+ TurboModeWhileHeld = config.TurboModeWhileHeld;
}
public KeyboardHotkeys GetConfig() =>
@@ -60,6 +66,8 @@ namespace Ryujinx.Ava.UI.Models.Input
VolumeDown = VolumeDown,
CustomVSyncIntervalIncrement = CustomVSyncIntervalIncrement,
CustomVSyncIntervalDecrement = CustomVSyncIntervalDecrement,
+ TurboMode = TurboMode,
+ TurboModeWhileHeld = TurboModeWhileHeld
};
}
}
diff --git a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs
index d0a6c6d8a..e1ab57709 100644
--- a/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs
+++ b/src/Ryujinx/UI/ViewModels/SettingsViewModel.cs
@@ -60,6 +60,7 @@ namespace Ryujinx.Ava.UI.ViewModels
private bool _enableCustomVSyncInterval;
private int _customVSyncIntervalPercentageProxy;
private VSyncMode _vSyncMode;
+ private long _turboModeMultiplier;
public event Action CloseWindow;
public event Action SaveSettingsEvent;
@@ -207,6 +208,25 @@ namespace Ryujinx.Ava.UI.ViewModels
}
public bool EnablePptc { get; set; }
public bool EnableLowPowerPptc { get; set; }
+
+
+ public long TurboMultiplier
+ {
+ get => _turboModeMultiplier;
+ set
+ {
+ if (_turboModeMultiplier != value)
+ {
+ _turboModeMultiplier = value;
+
+ OnPropertyChanged();
+ OnPropertyChanged((nameof(TurboMultiplierPercentageText)));
+ }
+ }
+ }
+
+ public string TurboMultiplierPercentageText => $"{TurboMultiplier}%";
+
public bool EnableInternetAccess { get; set; }
public bool EnableFsIntegrityChecks { get; set; }
public bool IgnoreMissingServices { get; set; }
@@ -594,6 +614,7 @@ namespace Ryujinx.Ava.UI.ViewModels
EnableLowPowerPptc = config.System.EnableLowPowerPtc;
MemoryMode = (int)config.System.MemoryManagerMode.Value;
UseHypervisor = config.System.UseHypervisor;
+ TurboMultiplier = config.System.TickScalar;
// Graphics
GraphicsBackendIndex = (int)config.Graphics.GraphicsBackend.Value;
@@ -697,6 +718,7 @@ namespace Ryujinx.Ava.UI.ViewModels
config.System.EnableLowPowerPtc.Value = EnableLowPowerPptc;
config.System.MemoryManagerMode.Value = (MemoryManagerMode)MemoryMode;
config.System.UseHypervisor.Value = UseHypervisor;
+ config.System.TickScalar.Value = TurboMultiplier;
// Graphics
config.Graphics.VSyncMode.Value = VSyncMode;
diff --git a/src/Ryujinx/UI/Views/Settings/SettingsCPUView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsCPUView.axaml
index 62f087510..976309995 100644
--- a/src/Ryujinx/UI/Views/Settings/SettingsCPUView.axaml
+++ b/src/Ryujinx/UI/Views/Settings/SettingsCPUView.axaml
@@ -7,6 +7,7 @@
xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
xmlns:helper="clr-namespace:Ryujinx.Common.Helper;assembly=Ryujinx.Common"
+ xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
mc:Ignorable="d"
x:DataType="viewModels:SettingsViewModel">
@@ -76,6 +77,56 @@
ToolTip.Tip="{ext:Locale UseHypervisorTooltip}" />
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml b/src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml
index 87b6dda7d..40121c2e1 100644
--- a/src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml
+++ b/src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml
@@ -19,7 +19,7 @@
-
@@ -47,71 +47,79 @@
Classes="h1"
Text="{ext:Locale SettingsTabHotkeysHotkeys}" />
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
diff --git a/src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml.cs b/src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml.cs
index d3d1537e0..17b413b5c 100644
--- a/src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml.cs
+++ b/src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml.cs
@@ -116,6 +116,9 @@ namespace Ryujinx.Ava.UI.Views.Settings
case "CustomVSyncIntervalDecrement":
viewModel.KeyboardHotkey.CustomVSyncIntervalDecrement = buttonValue.AsHidType();
break;
+ case "TurboMode":
+ viewModel.KeyboardHotkey.TurboMode = buttonValue.AsHidType();
+ break;
}
}
};
diff --git a/src/Ryujinx/Utilities/Configuration/ConfigurationFileFormat.cs b/src/Ryujinx/Utilities/Configuration/ConfigurationFileFormat.cs
index 814a48e53..5d70ff5e1 100644
--- a/src/Ryujinx/Utilities/Configuration/ConfigurationFileFormat.cs
+++ b/src/Ryujinx/Utilities/Configuration/ConfigurationFileFormat.cs
@@ -15,7 +15,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
///
/// The current version of the file format
///
- public const int CurrentVersion = 67;
+ public const int CurrentVersion = 68;
///
/// Version of the configuration file format
@@ -258,6 +258,11 @@ namespace Ryujinx.Ava.Utilities.Configuration
/// Enables or disables low-power profiled translation cache persistency loading
///
public bool EnableLowPowerPtc { get; set; }
+
+ ///
+ /// Clock tick scalar, in percent points (100 = 1.0).
+ ///
+ public long TickScalar { get; set; }
///
/// Enables or disables guest Internet access
diff --git a/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs b/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs
index 8a0ddb560..7e693152e 100644
--- a/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs
+++ b/src/Ryujinx/Utilities/Configuration/ConfigurationState.Migration.cs
@@ -94,6 +94,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
System.EnableDockedMode.Value = cff.DockedMode;
System.EnablePtc.Value = cff.EnablePtc;
System.EnableLowPowerPtc.Value = cff.EnableLowPowerPtc;
+ System.TickScalar.Value = cff.TickScalar;
System.EnableInternetAccess.Value = cff.EnableInternetAccess;
System.EnableFsIntegrityChecks.Value = cff.EnableFsIntegrityChecks;
System.FsGlobalAccessLogMode.Value = cff.FsGlobalAccessLogMode;
@@ -441,7 +442,27 @@ namespace Ryujinx.Ava.Utilities.Configuration
(64, static cff => cff.LoggingEnableAvalonia = false),
(65, static cff => cff.UpdateCheckerType = cff.CheckUpdatesOnStart ? UpdaterType.PromptAtStartup : UpdaterType.Off),
(66, static cff => cff.DisableInputWhenOutOfFocus = false),
- (67, static cff => cff.FocusLostActionType = cff.DisableInputWhenOutOfFocus ? FocusLostType.BlockInput : FocusLostType.DoNothing)
+ (67, static cff => cff.FocusLostActionType = cff.DisableInputWhenOutOfFocus ? FocusLostType.BlockInput : FocusLostType.DoNothing),
+ (68, static cff =>
+ {
+ cff.TickScalar = 200;
+ cff.Hotkeys = new KeyboardHotkeys
+ {
+ ToggleVSyncMode = cff.Hotkeys.ToggleVSyncMode,
+ Screenshot = cff.Hotkeys.Screenshot,
+ ShowUI = cff.Hotkeys.ShowUI,
+ Pause = cff.Hotkeys.Pause,
+ ToggleMute = cff.Hotkeys.ToggleMute,
+ ResScaleUp = cff.Hotkeys.ResScaleUp,
+ ResScaleDown = cff.Hotkeys.ResScaleDown,
+ VolumeUp = cff.Hotkeys.VolumeUp,
+ VolumeDown = cff.Hotkeys.VolumeDown,
+ CustomVSyncIntervalIncrement = cff.Hotkeys.CustomVSyncIntervalIncrement,
+ CustomVSyncIntervalDecrement = cff.Hotkeys.CustomVSyncIntervalDecrement,
+ TurboMode = Key.Unbound,
+ TurboModeWhileHeld = false
+ };
+ })
);
}
}
diff --git a/src/Ryujinx/Utilities/Configuration/ConfigurationState.Model.cs b/src/Ryujinx/Utilities/Configuration/ConfigurationState.Model.cs
index ead99fbac..b27d27492 100644
--- a/src/Ryujinx/Utilities/Configuration/ConfigurationState.Model.cs
+++ b/src/Ryujinx/Utilities/Configuration/ConfigurationState.Model.cs
@@ -335,6 +335,11 @@ namespace Ryujinx.Ava.Utilities.Configuration
/// Enables or disables persistent profiled translation cache
///
public ReactiveObject EnablePtc { get; private set; }
+
+ ///
+ /// Clock tick scalar, in percent points (100 = 1.0).
+ ///
+ public ReactiveObject TickScalar { get; set; }
///
/// Enables or disables low-power persistent profiled translation cache loading
@@ -411,6 +416,15 @@ namespace Ryujinx.Ava.Utilities.Configuration
EnableLowPowerPtc.LogChangesToValue(nameof(EnableLowPowerPtc));
EnableLowPowerPtc.Event += (_, evnt)
=> Optimizations.LowPower = evnt.NewValue;
+ TickScalar = new ReactiveObject();
+ TickScalar.LogChangesToValue(nameof(TickScalar));
+ TickScalar.Event += (_, evnt) =>
+ {
+ if (Switch.Shared is null)
+ return;
+
+ Switch.Shared.Configuration.TickScalar = evnt.NewValue;
+ };
EnableInternetAccess = new ReactiveObject();
EnableInternetAccess.LogChangesToValue(nameof(EnableInternetAccess));
EnableFsIntegrityChecks = new ReactiveObject();
diff --git a/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs b/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs
index 4fdf7c4f0..44396aef4 100644
--- a/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs
+++ b/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs
@@ -73,6 +73,7 @@ namespace Ryujinx.Ava.Utilities.Configuration
EnableColorSpacePassthrough = Graphics.EnableColorSpacePassthrough,
EnablePtc = System.EnablePtc,
EnableLowPowerPtc = System.EnableLowPowerPtc,
+ TickScalar = System.TickScalar,
EnableInternetAccess = System.EnableInternetAccess,
EnableFsIntegrityChecks = System.EnableFsIntegrityChecks,
FsGlobalAccessLogMode = System.FsGlobalAccessLogMode,
@@ -261,6 +262,10 @@ namespace Ryujinx.Ava.Utilities.Configuration
ResScaleDown = Key.Unbound,
VolumeUp = Key.Unbound,
VolumeDown = Key.Unbound,
+ CustomVSyncIntervalIncrement = Key.Unbound,
+ CustomVSyncIntervalDecrement = Key.Unbound,
+ TurboMode = Key.Unbound,
+ TurboModeWhileHeld = false
};
Hid.RainbowSpeed.Value = 1f;
Hid.InputConfig.Value =
@@ -327,5 +332,5 @@ namespace Ryujinx.Ava.Utilities.Configuration
return GraphicsBackend.OpenGl;
}
- }
- }
+ }
+}