WIP: Add TickSource-based turbo mode #747
@ -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; }
|
||||
}
|
||||
}
|
||||
|
@ -8,10 +8,17 @@ namespace Ryujinx.Cpu
|
||||
/// </summary>
|
||||
public interface ITickSource : ICounter
|
||||
{
|
||||
public const long RealityTickScalar = 100;
|
||||
|
||||
/// <summary>
|
||||
/// Time elapsed since the counter was created.
|
||||
/// </summary>
|
||||
TimeSpan ElapsedTime { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Clock tick scalar, in percent points (100 = 1.0).
|
||||
/// </summary>
|
||||
long TickScalar { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Time elapsed since the counter was created, in seconds.
|
||||
|
@ -14,12 +14,37 @@ namespace Ryujinx.Cpu
|
||||
|
||||
/// <inheritdoc/>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public TimeSpan ElapsedTime => _tickCounter.Elapsed;
|
||||
|
||||
public TimeSpan ElapsedTime => Stopwatch.GetElapsedTime(0, ElapsedTicks);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public double ElapsedSeconds => _tickCounter.ElapsedTicks * _hostTickFreq;
|
||||
public double ElapsedSeconds => ElapsedTicks * _hostTickFreq;
|
||||
|
||||
public TickSource(ulong frequency)
|
||||
{
|
||||
|
@ -1065,7 +1065,14 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
private void UpdateIndexBufferState()
|
||||
{
|
||||
IndexBufferState indexBuffer = _state.State.IndexBufferState;
|
||||
IndexBufferState? indexBufferNullable = _state?.State.IndexBufferState;
|
||||
|
||||
if (!indexBufferNullable.HasValue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IndexBufferState indexBuffer = indexBufferNullable.Value;
|
||||
|
||||
if (_drawState.IndexCount == 0)
|
||||
{
|
||||
|
@ -127,10 +127,7 @@ namespace Ryujinx.HLE.HOS.Services
|
||||
}
|
||||
else
|
||||
{
|
||||
string serviceName;
|
||||
|
||||
|
||||
serviceName = (service is not DummyService dummyService) ? service.GetType().FullName : dummyService.ServiceName;
|
||||
string serviceName = (service is not DummyService dummyService) ? service.GetType().FullName : dummyService.ServiceName;
|
||||
|
||||
Logger.Warning?.Print(LogClass.KernelIpc, $"Missing service {serviceName}: {commandId} ignored");
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -102,6 +102,11 @@ namespace Ryujinx.HLE
|
||||
/// Control if the Profiled Translation Cache (PTC) should be used.
|
||||
/// </summary>
|
||||
internal readonly bool EnablePtc;
|
||||
|
||||
/// <summary>
|
||||
/// Control the arbitrary scalar applied to emulated CPU tick timing.
|
||||
/// </summary>
|
||||
public long TickScalar { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Control if the guest application should be told that there is a Internet connection available.
|
||||
@ -201,6 +206,7 @@ namespace Ryujinx.HLE
|
||||
VSyncMode vSyncMode,
|
||||
bool enableDockedMode,
|
||||
bool enablePtc,
|
||||
long tickScalar,
|
||||
bool enableInternetAccess,
|
||||
IntegrityCheckLevel fsIntegrityCheckLevel,
|
||||
int fsGlobalAccessLogMode,
|
||||
@ -226,6 +232,7 @@ namespace Ryujinx.HLE
|
||||
CustomVSyncInterval = customVSyncInterval;
|
||||
EnableDockedMode = enableDockedMode;
|
||||
EnablePtc = enablePtc;
|
||||
TickScalar = tickScalar;
|
||||
EnableInternetAccess = enableInternetAccess;
|
||||
FsIntegrityCheckLevel = fsIntegrityCheckLevel;
|
||||
FsGlobalAccessLogMode = fsGlobalAccessLogMode;
|
||||
|
@ -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];
|
||||
@ -162,14 +166,6 @@ namespace Ryujinx.HLE
|
||||
return 1000 / _frameRate[FrameTypeGame];
|
||||
}
|
||||
|
||||
public string FormatGameFrameRate()
|
||||
{
|
||||
double frameRate = GetGameFrameRate();
|
||||
double frameTime = GetGameFrameTime();
|
||||
|
||||
return $"{frameRate:00.00} FPS ({frameTime:00.00}ms)";
|
||||
}
|
||||
|
||||
public string FormatFifoPercent()
|
||||
{
|
||||
double fifoPercent = GetFifoPercent();
|
||||
|
@ -4,6 +4,7 @@ using Ryujinx.Audio.Backends.CompatLayer;
|
||||
using Ryujinx.Audio.Integration;
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Cpu;
|
||||
using Ryujinx.Graphics.Gpu;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using Ryujinx.HLE.HOS;
|
||||
@ -26,18 +27,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 ?? ITickSource.RealityTickScalar;
|
||||
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 +73,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 +84,7 @@ namespace Ryujinx.HLE
|
||||
|
||||
VSyncMode = Configuration.VSyncMode;
|
||||
CustomVSyncInterval = Configuration.CustomVSyncInterval;
|
||||
TickScalar = TurboMode ? Configuration.TickScalar : ITickSource.RealityTickScalar;
|
||||
System.State.DockedMode = Configuration.EnableDockedMode;
|
||||
System.PerformanceState.PerformanceMode = System.State.DockedMode ? PerformanceMode.Boost : PerformanceMode.Default;
|
||||
System.EnablePtc = Configuration.EnablePtc;
|
||||
@ -126,6 +136,12 @@ namespace Ryujinx.HLE
|
||||
}
|
||||
}
|
||||
|
||||
public void ToggleTurbo()
|
||||
{
|
||||
TurboMode = !TurboMode;
|
||||
TickScalar = TurboMode ? Configuration.TickScalar : ITickSource.RealityTickScalar;
|
||||
}
|
||||
|
||||
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<ApplicationControlProperty>? customNacpData = null) => Processes.LoadNca(ncaFile, customNacpData);
|
||||
|
@ -4922,6 +4922,81 @@
|
||||
"zh_TW": "低功耗 PPTC"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "SettingsTabSystemTurboMultiplier",
|
||||
"Translations": {
|
||||
"ar_SA": "",
|
||||
"de_DE": "",
|
||||
"el_GR": "",
|
||||
"en_US": "Turbo Mode multiplier:",
|
||||
"es_ES": "",
|
||||
"fr_FR": "Multiplicateur du Mode Turbo :",
|
||||
"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 target value.\n\nLeave at 200 if unsure.",
|
||||
"es_ES": "",
|
||||
"fr_FR": "La valeur souhaitée du multiplicateur du Mode Turbo.\n\nGarder à 200 si incertain.",
|
||||
"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": "SettingsTabSystemTurboMultiplierToolTip",
|
||||
"Translations": {
|
||||
"ar_SA": "",
|
||||
"de_DE": "",
|
||||
"el_GR": "",
|
||||
"en_US": "Turbo mode is an emulator feature which effectively causes speed up or slow down when a game is not frame-rate sensitive.\nYou can toggle this feature in-game with a hotkey, configurable in Ryujinx Keyboard Hotkeys settings.\n\nLeave at 200 if unsure.",
|
||||
"es_ES": "",
|
||||
"fr_FR": "Le Mode Turbo est une fonctionnalité de l'émulateur qui accélère ou ralentit le jeu lorsque ce dernier n'est pas sensible au framerate.\nVous pouvez changer cette option en jeu avec un raccourci clavier, configurable dans les paramètres de Raccourcis clavier de Ryujinx.\n\nGarder à 200 si incertain.",
|
||||
"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": {
|
||||
@ -10505,7 +10580,7 @@
|
||||
"el_GR": "",
|
||||
"en_US": "Unbound",
|
||||
"es_ES": "",
|
||||
"fr_FR": "Pas Attribuée",
|
||||
"fr_FR": "Non Attribuée",
|
||||
"he_IL": "",
|
||||
"it_IT": "Non assegnato",
|
||||
"ja_JP": "",
|
||||
@ -18097,6 +18172,56 @@
|
||||
"zh_TW": "更新已停用!"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "FpsStatusBarText",
|
||||
"Translations": {
|
||||
"ar_SA": "",
|
||||
"de_DE": "",
|
||||
"el_GR": "",
|
||||
"en_US": "{0} FPS ({1}ms)",
|
||||
"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": "FpsTurboStatusBarText",
|
||||
"Translations": {
|
||||
"ar_SA": "{0} FPS ({1}ms), التوربو %{2}",
|
||||
"de_DE": "",
|
||||
"el_GR": "",
|
||||
"en_US": "{0} FPS ({1}ms), Turbo ({2}%)",
|
||||
"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": "UpdaterBackgroundStatusBarButtonText",
|
||||
"Translations": {
|
||||
@ -23822,6 +23947,81 @@
|
||||
"zh_TW": "降低自訂的重新整理頻率"
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": "SettingsTabHotkeysTurboMode",
|
||||
"Translations": {
|
||||
"ar_SA": "",
|
||||
"de_DE": "",
|
||||
"el_GR": "",
|
||||
"en_US": "Turbo mode:",
|
||||
"es_ES": "",
|
||||
"fr_FR": "Mode Turbo :",
|
||||
"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": "SettingsTabHotkeysTurboModeToolTip",
|
||||
"Translations": {
|
||||
"ar_SA": "",
|
||||
"de_DE": "",
|
||||
"el_GR": "",
|
||||
"en_US": "The Turbo mode hotkey.\nConfigure the behavior of Turbo mode in Ryujinx CPU settings.\n\nLeave Unbound if unsure.",
|
||||
"es_ES": "",
|
||||
"fr_FR": "Le raccourci clavier Mode Turbo.\nConfigurez le comportement du Mode Turbo dans les paramètres de CPU de Ryujinx.\n\nLaisser Non Attribuée si incertain.",
|
||||
"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": "Seulement quand le raccourci est maintenu",
|
||||
"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": {
|
||||
|
@ -14,5 +14,6 @@ namespace Ryujinx.Ava.Common
|
||||
VolumeDown,
|
||||
CustomVSyncIntervalIncrement,
|
||||
CustomVSyncIntervalDecrement,
|
||||
TurboMode,
|
||||
}
|
||||
}
|
||||
|
@ -61,6 +61,13 @@ namespace Ryujinx.Ava.Common.Locale
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetUnformatted(LocaleKeys key) => Instance.Get(key);
|
||||
|
||||
public string Get(LocaleKeys key) =>
|
||||
_localeStrings.TryGetValue(key, out string value)
|
||||
? value
|
||||
: key.ToString();
|
||||
|
||||
public string this[LocaleKeys key]
|
||||
{
|
||||
get
|
||||
|
@ -11,6 +11,7 @@ using Ryujinx.Common.Configuration.Hid.Controller.Motion;
|
||||
using Ryujinx.Common.Configuration.Hid.Keyboard;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Common.Utilities;
|
||||
using Ryujinx.Cpu;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.OpenGL;
|
||||
using Ryujinx.Graphics.Vulkan;
|
||||
@ -311,7 +312,7 @@ namespace Ryujinx.Headless
|
||||
|
||||
return new OpenGLRenderer();
|
||||
}
|
||||
|
||||
|
||||
private static Switch InitializeEmulationContext(WindowBase window, IRenderer renderer, Options options) =>
|
||||
new(
|
||||
new HleConfiguration(
|
||||
@ -321,6 +322,7 @@ namespace Ryujinx.Headless
|
||||
options.VSyncMode,
|
||||
!options.DisableDockedMode,
|
||||
!options.DisablePTC,
|
||||
ITickSource.RealityTickScalar,
|
||||
options.EnableInternetAccess,
|
||||
!options.DisableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None,
|
||||
options.FsGlobalAccessLogMode,
|
||||
|
@ -4,6 +4,7 @@ using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Threading;
|
||||
using DiscordRPC;
|
||||
using Gommon;
|
||||
using LibHac.Common;
|
||||
using LibHac.Ns;
|
||||
using Ryujinx.Audio.Backends.Dummy;
|
||||
@ -1115,11 +1116,23 @@ namespace Ryujinx.Ava.Systems
|
||||
LocaleManager.Instance[LocaleKeys.VolumeShort] + $": {(int)(Device.GetVolume() * 100)}%",
|
||||
dockedMode,
|
||||
ConfigurationState.Instance.Graphics.AspectRatio.Value.ToText(),
|
||||
Device.Statistics.FormatGameFrameRate(),
|
||||
FormatGameFrameRate(),
|
||||
Device.Statistics.FormatFifoPercent(),
|
||||
_displayCount));
|
||||
}
|
||||
|
||||
private string FormatGameFrameRate()
|
||||
{
|
||||
string frameRate = Device.Statistics.GetGameFrameRate().ToString("00.00");
|
||||
string frameTime = Device.Statistics.GetGameFrameTime().ToString("00.00");
|
||||
|
||||
return Device.TurboMode
|
||||
? LocaleManager.GetUnformatted(LocaleKeys.FpsTurboStatusBarText)
|
||||
.Format(frameRate, frameTime, Device.TickScalar)
|
||||
: LocaleManager.GetUnformatted(LocaleKeys.FpsStatusBarText)
|
||||
.Format(frameRate, frameTime);
|
||||
}
|
||||
|
||||
public async Task ShowExitPrompt()
|
||||
{
|
||||
bool shouldExit = !ConfigurationState.Instance.ShowConfirmExit;
|
||||
@ -1215,6 +1228,12 @@ namespace Ryujinx.Ava.Systems
|
||||
|
||||
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:
|
||||
@ -1226,6 +1245,12 @@ namespace Ryujinx.Ava.Systems
|
||||
case KeyboardHotkeyState.CustomVSyncIntervalIncrement:
|
||||
_viewModel.CustomVSyncInterval = Device.IncrementCustomVSyncInterval();
|
||||
break;
|
||||
case KeyboardHotkeyState.TurboMode:
|
||||
if (!ConfigurationState.Instance.Hid.Hotkeys.Value.TurboModeWhileHeld)
|
||||
{
|
||||
Device.ToggleTurbo();
|
||||
}
|
||||
break;
|
||||
case KeyboardHotkeyState.Screenshot:
|
||||
ScreenshotRequested = true;
|
||||
break;
|
||||
@ -1355,6 +1380,10 @@ namespace Ryujinx.Ava.Systems
|
||||
{
|
||||
state = KeyboardHotkeyState.CustomVSyncIntervalDecrement;
|
||||
}
|
||||
else if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.TurboMode))
|
||||
{
|
||||
state = KeyboardHotkeyState.TurboMode;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
@ -258,6 +258,11 @@ namespace Ryujinx.Ava.Systems.Configuration
|
||||
/// Enables or disables low-power profiled translation cache persistency loading
|
||||
/// </summary>
|
||||
public bool EnableLowPowerPtc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Clock tick scalar, in percent points (100 = 1.0).
|
||||
/// </summary>
|
||||
public long TickScalar { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Enables or disables guest Internet access
|
||||
|
@ -93,6 +93,7 @@ namespace Ryujinx.Ava.Systems.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;
|
||||
@ -438,9 +439,27 @@ namespace Ryujinx.Ava.Systems.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)
|
||||
// 68 was the version that added per-game configs; the file structure did not change
|
||||
// the version was increased so external tools could know that your Ryujinx version has per-game config capabilities.
|
||||
(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
|
||||
};
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -335,6 +335,11 @@ namespace Ryujinx.Ava.Systems.Configuration
|
||||
/// Enables or disables persistent profiled translation cache
|
||||
/// </summary>
|
||||
public ReactiveObject<bool> EnablePtc { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Clock tick scalar, in percent points (100 = 1.0).
|
||||
/// </summary>
|
||||
public ReactiveObject<long> TickScalar { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Enables or disables low-power persistent profiled translation cache loading
|
||||
@ -415,6 +420,15 @@ namespace Ryujinx.Ava.Systems.Configuration
|
||||
EnableLowPowerPtc.LogChangesToValue(nameof(EnableLowPowerPtc));
|
||||
EnableLowPowerPtc.Event += (_, evnt)
|
||||
=> Optimizations.LowPower = evnt.NewValue;
|
||||
TickScalar = new ReactiveObject<long>();
|
||||
TickScalar.LogChangesToValue(nameof(TickScalar));
|
||||
TickScalar.Event += (_, evnt) =>
|
||||
{
|
||||
if (Switch.Shared is null)
|
||||
return;
|
||||
|
||||
Switch.Shared.Configuration.TickScalar = evnt.NewValue;
|
||||
};
|
||||
EnableInternetAccess = new ReactiveObject<bool>();
|
||||
EnableInternetAccess.LogChangesToValue(nameof(EnableInternetAccess));
|
||||
EnableFsIntegrityChecks = new ReactiveObject<bool>();
|
||||
@ -842,6 +856,7 @@ namespace Ryujinx.Ava.Systems.Configuration
|
||||
Graphics.VSyncMode,
|
||||
System.EnableDockedMode,
|
||||
System.EnablePtc,
|
||||
System.TickScalar,
|
||||
System.EnableInternetAccess,
|
||||
System.EnableFsIntegrityChecks
|
||||
? IntegrityCheckLevel.ErrorOnInvalid
|
||||
@ -860,8 +875,8 @@ namespace Ryujinx.Ava.Systems.Configuration
|
||||
Multiplayer.Mode,
|
||||
Multiplayer.DisableP2p,
|
||||
Multiplayer.LdnPassphrase,
|
||||
Instance.Multiplayer.GetLdnServer(),
|
||||
Instance.Graphics.CustomVSyncInterval,
|
||||
Instance.Hacks.ShowDirtyHacks ? Instance.Hacks.EnabledHacks : null);
|
||||
Multiplayer.GetLdnServer(),
|
||||
Graphics.CustomVSyncInterval,
|
||||
Hacks.ShowDirtyHacks ? Hacks.EnabledHacks : null);
|
||||
}
|
||||
}
|
||||
|
@ -72,6 +72,7 @@ namespace Ryujinx.Ava.Systems.Configuration
|
||||
EnableColorSpacePassthrough = Graphics.EnableColorSpacePassthrough,
|
||||
EnablePtc = System.EnablePtc,
|
||||
EnableLowPowerPtc = System.EnableLowPowerPtc,
|
||||
TickScalar = System.TickScalar,
|
||||
EnableInternetAccess = System.EnableInternetAccess,
|
||||
EnableFsIntegrityChecks = System.EnableFsIntegrityChecks,
|
||||
FsGlobalAccessLogMode = System.FsGlobalAccessLogMode,
|
||||
@ -260,6 +261,10 @@ namespace Ryujinx.Ava.Systems.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 =
|
||||
|
@ -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
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
@ -206,6 +207,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; }
|
||||
@ -592,6 +612,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;
|
||||
@ -694,6 +715,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;
|
||||
|
@ -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">
|
||||
<Design.DataContext>
|
||||
@ -76,6 +77,57 @@
|
||||
ToolTip.Tip="{ext:Locale UseHypervisorTooltip}" />
|
||||
</CheckBox>
|
||||
</StackPanel>
|
||||
<Separator Height="1" />
|
||||
<StackPanel
|
||||
Orientation="Vertical"
|
||||
Spacing="5">
|
||||
<TextBlock
|
||||
Classes="h1"
|
||||
Text="{ext:Locale SettingsTabSystemHacks}" />
|
||||
<TextBlock
|
||||
Foreground="{DynamicResource SecondaryTextColor}"
|
||||
TextDecorations="Underline"
|
||||
Text="{ext:Locale SettingsTabSystemHacksNote}" />
|
||||
</StackPanel>
|
||||
<StackPanel
|
||||
Margin="10,0,0,0"
|
||||
HorizontalAlignment="Stretch"
|
||||
Orientation="Vertical">
|
||||
<StackPanel Margin="0,0,0,10"
|
||||
Orientation="Horizontal">
|
||||
<TextBlock
|
||||
VerticalAlignment="Center"
|
||||
Background="Transparent"
|
||||
Text="{ext:Locale SettingsTabSystemTurboMultiplier}"
|
||||
ToolTip.Tip="{ext:Locale SettingsTabSystemTurboMultiplierToolTip}"
|
||||
Width="250" />
|
||||
<ui:NumberBox ToolTip.Tip="{ext:Locale SettingsTabSystemTurboMultiplierValueToolTip}"
|
||||
Value="{Binding TurboMultiplier}"
|
||||
Width="165"
|
||||
SmallChange="1.0"
|
||||
LargeChange="10"
|
||||
SimpleNumberFormat="F0"
|
||||
SpinButtonPlacementMode="Hidden"
|
||||
Minimum="50"
|
||||
Maximum="300" />
|
||||
<Slider Value="{Binding TurboMultiplier}"
|
||||
ToolTip.Tip="{ext:Locale SettingsTabSystemTurboMultiplierValueToolTip}"
|
||||
MinWidth="175"
|
||||
Margin="10,-3,0,0"
|
||||
Height="32"
|
||||
Padding="0,-5"
|
||||
TickFrequency="1"
|
||||
IsSnapToTickEnabled="True"
|
||||
LargeChange="10"
|
||||
SmallChange="1"
|
||||
VerticalAlignment="Center"
|
||||
Minimum="50"
|
||||
Maximum="500" />
|
||||
<TextBlock Margin="5,0"
|
||||
Width="40"
|
||||
Text="{Binding TurboMultiplierPercentageText}"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</ScrollViewer>
|
||||
|
@ -19,7 +19,7 @@
|
||||
<Setter Property="Margin" Value="10, 0, 0, 0" />
|
||||
<Setter Property="Orientation" Value="Horizontal" />
|
||||
</Style>
|
||||
<Style Selector="StackPanel > StackPanel > TextBlock">
|
||||
<Style Selector="StackPanel > StackPanel > TextBlock.settingHeader">
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="Width" Value="230" />
|
||||
</Style>
|
||||
@ -47,71 +47,79 @@
|
||||
Classes="h1"
|
||||
Text="{ext:Locale SettingsTabHotkeysHotkeys}" />
|
||||
<StackPanel>
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysToggleVSyncModeHotkey}" />
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysToggleVSyncModeHotkey}" Classes="settingHeader" />
|
||||
<ToggleButton Name="ToggleVSyncMode">
|
||||
<TextBlock Text="{Binding KeyboardHotkey.ToggleVSyncMode, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysScreenshotHotkey}" />
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysScreenshotHotkey}" Classes="settingHeader" />
|
||||
<ToggleButton Name="Screenshot">
|
||||
<TextBlock Text="{Binding KeyboardHotkey.Screenshot, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysShowUiHotkey}" />
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysShowUiHotkey}" Classes="settingHeader" />
|
||||
<ToggleButton Name="ShowUI">
|
||||
<TextBlock Text="{Binding KeyboardHotkey.ShowUI, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysPauseHotkey}" />
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysPauseHotkey}" Classes="settingHeader" />
|
||||
<ToggleButton Name="Pause">
|
||||
<TextBlock Text="{Binding KeyboardHotkey.Pause, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysToggleMuteHotkey}" />
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysToggleMuteHotkey}" Classes="settingHeader" />
|
||||
<ToggleButton Name="ToggleMute">
|
||||
<TextBlock Text="{Binding KeyboardHotkey.ToggleMute, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysResScaleUpHotkey}" />
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysResScaleUpHotkey}" Classes="settingHeader" />
|
||||
<ToggleButton Name="ResScaleUp">
|
||||
<TextBlock Text="{Binding KeyboardHotkey.ResScaleUp, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysResScaleDownHotkey}" />
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysResScaleDownHotkey}" Classes="settingHeader" />
|
||||
<ToggleButton Name="ResScaleDown">
|
||||
<TextBlock Text="{Binding KeyboardHotkey.ResScaleDown, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysVolumeUpHotkey}" />
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysVolumeUpHotkey}" Classes="settingHeader" />
|
||||
<ToggleButton Name="VolumeUp">
|
||||
<TextBlock Text="{Binding KeyboardHotkey.VolumeUp, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
<StackPanel>
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysVolumeDownHotkey}" />
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysVolumeDownHotkey}" Classes="settingHeader" />
|
||||
<ToggleButton Name="VolumeDown">
|
||||
<TextBlock Text="{Binding KeyboardHotkey.VolumeDown, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
<StackPanel Margin="10,0,0,0" Orientation="Horizontal">
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysIncrementCustomVSyncIntervalHotkey}" />
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysIncrementCustomVSyncIntervalHotkey}" Classes="settingHeader" />
|
||||
<ToggleButton Name="CustomVSyncIntervalIncrement">
|
||||
<TextBlock Text="{Binding KeyboardHotkey.CustomVSyncIntervalIncrement, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
<StackPanel Margin="10,0,0,0" Orientation="Horizontal">
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysDecrementCustomVSyncIntervalHotkey}" />
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysDecrementCustomVSyncIntervalHotkey}" Classes="settingHeader" />
|
||||
<ToggleButton Name="CustomVSyncIntervalDecrement">
|
||||
<TextBlock Text="{Binding KeyboardHotkey.CustomVSyncIntervalDecrement, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysTurboMode}" Classes="settingHeader" ToolTip.Tip="{ext:Locale SettingsTabHotkeysTurboModeToolTip}" Background="Transparent" />
|
||||
<ToggleButton Name="TurboMode">
|
||||
<TextBlock Text="{Binding KeyboardHotkey.TurboMode, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
|
||||
</ToggleButton>
|
||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysOnlyWhilePressed}" Margin="10,0" />
|
||||
<CheckBox IsChecked="{Binding KeyboardHotkey.TurboModeWhileHeld}" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</ScrollViewer>
|
||||
|
@ -121,6 +121,9 @@ namespace Ryujinx.Ava.UI.Views.Settings
|
||||
ViewModel.KeyboardHotkey.CustomVSyncIntervalDecrement =
|
||||
buttonValue.AsHidType<Key>();
|
||||
break;
|
||||
case "TurboMode":
|
||||
ViewModel.KeyboardHotkey.TurboMode = buttonValue.AsHidType<Key>();
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user