This commit is contained in:
Nicolas Abram 2024-10-01 09:33:19 +02:00 committed by GitHub
commit 0d14af521d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 255 additions and 16 deletions

View File

@ -11,5 +11,7 @@ namespace Ryujinx.Common.Configuration.Hid
public Key ResScaleDown { get; set; } public Key ResScaleDown { get; set; }
public Key VolumeUp { get; set; } public Key VolumeUp { get; set; }
public Key VolumeDown { get; set; } public Key VolumeDown { get; set; }
public Key ToggleTurbo { get; set; }
public bool TurboWhileHeld { get; set; }
} }
} }

View File

@ -13,6 +13,11 @@ namespace Ryujinx.Cpu
/// </summary> /// </summary>
TimeSpan ElapsedTime { get; } TimeSpan ElapsedTime { get; }
/// <summary>
/// Clock tick multiplier, in percent points (100 = 1.0).
/// </summary>
long TickMultiplier { get; set; }
/// <summary> /// <summary>
/// Time elapsed since the counter was created, in seconds. /// Time elapsed since the counter was created, in seconds.
/// </summary> /// </summary>

View File

@ -15,11 +15,25 @@ namespace Ryujinx.Cpu
/// <inheritdoc/> /// <inheritdoc/>
public ulong Counter => (ulong)(ElapsedSeconds * Frequency); public ulong Counter => (ulong)(ElapsedSeconds * Frequency);
/// <inheritdoc/> public long TickMultiplier { get; set; } = 100;
public TimeSpan ElapsedTime => _tickCounter.Elapsed; private static long AcumElapsedTicks = 0;
private static long LastElapsedTicks = 0;
private long Elapsedticks
{
get
{
long elapsedTicks = _tickCounter.ElapsedTicks;
AcumElapsedTicks += (elapsedTicks - LastElapsedTicks) * TickMultiplier / 100;
LastElapsedTicks = elapsedTicks;
return AcumElapsedTicks;
}
}
/// <inheritdoc/> /// <inheritdoc/>
public double ElapsedSeconds => _tickCounter.ElapsedTicks * _hostTickFreq; public TimeSpan ElapsedTime => Stopwatch.GetElapsedTime(0, Elapsedticks);
/// <inheritdoc/>
public double ElapsedSeconds => Elapsedticks * _hostTickFreq;
public TickSource(ulong frequency) public TickSource(ulong frequency)
{ {

View File

@ -677,7 +677,8 @@ namespace Ryujinx.UI
ConfigurationState.Instance.System.AudioVolume, ConfigurationState.Instance.System.AudioVolume,
ConfigurationState.Instance.System.UseHypervisor, ConfigurationState.Instance.System.UseHypervisor,
ConfigurationState.Instance.Multiplayer.LanInterfaceId.Value, ConfigurationState.Instance.Multiplayer.LanInterfaceId.Value,
ConfigurationState.Instance.Multiplayer.Mode); ConfigurationState.Instance.Multiplayer.Mode,
ConfigurationState.Instance.System.TurboMultiplier);
_emulationContext = new HLE.Switch(configuration); _emulationContext = new HLE.Switch(configuration);
} }

View File

@ -502,7 +502,8 @@ namespace Ryujinx.UI
_gpuBackendName, _gpuBackendName,
dockedMode, dockedMode,
ConfigurationState.Instance.Graphics.AspectRatio.Value.ToText(), ConfigurationState.Instance.Graphics.AspectRatio.Value.ToText(),
$"Game: {Device.Statistics.GetGameFrameRate():00.00} FPS ({Device.Statistics.GetGameFrameTime():00.00} ms)", $"Game: {Device.Statistics.GetGameFrameRate():00.00} FPS ({Device.Statistics.GetGameFrameTime():00.00} ms)"
+ (Device.TurboMode ? $" Turbo ({Device.Configuration.TurboMultiplier}%)" : ""),
$"FIFO: {Device.Statistics.GetFifoPercent():0.00} %", $"FIFO: {Device.Statistics.GetFifoPercent():0.00} %",
$"GPU: {_gpuDriverName}")); $"GPU: {_gpuDriverName}"));

View File

@ -83,6 +83,11 @@ namespace Ryujinx.HLE
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks> /// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
internal readonly RegionCode Region; internal readonly RegionCode Region;
/// <summary>
/// Turbo mode speed multiplier
/// </summary>
public long TurboMultiplier;
/// <summary> /// <summary>
/// Control the initial state of the vertical sync in the SurfaceFlinger service. /// Control the initial state of the vertical sync in the SurfaceFlinger service.
/// </summary> /// </summary>
@ -194,7 +199,8 @@ namespace Ryujinx.HLE
float audioVolume, float audioVolume,
bool useHypervisor, bool useHypervisor,
string multiplayerLanInterfaceId, string multiplayerLanInterfaceId,
MultiplayerMode multiplayerMode) MultiplayerMode multiplayerMode,
long turboMultiplier)
{ {
VirtualFileSystem = virtualFileSystem; VirtualFileSystem = virtualFileSystem;
LibHacHorizonManager = libHacHorizonManager; LibHacHorizonManager = libHacHorizonManager;
@ -207,6 +213,7 @@ namespace Ryujinx.HLE
HostUIHandler = hostUIHandler; HostUIHandler = hostUIHandler;
SystemLanguage = systemLanguage; SystemLanguage = systemLanguage;
Region = region; Region = region;
TurboMultiplier = turboMultiplier;
EnableVsync = enableVsync; EnableVsync = enableVsync;
EnableDockedMode = enableDockedMode; EnableDockedMode = enableDockedMode;
EnablePtc = enablePtc; EnablePtc = enablePtc;

View File

@ -2,6 +2,7 @@ using Ryujinx.Common;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Common.PreciseSleep; using Ryujinx.Common.PreciseSleep;
using Ryujinx.Cpu;
using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Gpu; using Ryujinx.Graphics.Gpu;
using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap; using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap;
@ -88,7 +89,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
} }
else else
{ {
_ticksPerFrame = Stopwatch.Frequency / TargetFps; _ticksPerFrame = (Stopwatch.Frequency / TargetFps * 100) / (_device.System?.TickSource?.TickMultiplier ?? 100);
} }
} }

View File

@ -28,6 +28,7 @@ namespace Ryujinx.HLE
public IHostUIHandler UIHandler { get; } public IHostUIHandler UIHandler { get; }
public bool EnableDeviceVsync { get; set; } = true; public bool EnableDeviceVsync { get; set; } = true;
public bool TurboMode { get; set; } = false;
public bool IsFrameAvailable => Gpu.Window.IsFrameAvailable; public bool IsFrameAvailable => Gpu.Window.IsFrameAvailable;
@ -125,6 +126,18 @@ namespace Ryujinx.HLE
return AudioDeviceDriver.Volume; return AudioDeviceDriver.Volume;
} }
public void SetTickSourceMultiplier(long tickMultiplier)
{
System.TickSource.TickMultiplier = tickMultiplier;
}
public void ToggleTurbo()
{
TurboMode = !TurboMode;
long turboMultiplier = TurboMode ? Configuration.TurboMultiplier : 100;
SetTickSourceMultiplier(turboMultiplier);
}
public void EnableCheats() public void EnableCheats()
{ {
ModLoader.EnableCheats(Processes.ActiveApplication.ProgramId, TamperMachine); ModLoader.EnableCheats(Processes.ActiveApplication.ProgramId, TamperMachine);

View File

@ -114,6 +114,9 @@ namespace Ryujinx.Headless.SDL2
[Option("fs-global-access-log-mode", Required = false, Default = 0, HelpText = "Enables FS access log output to the console.")] [Option("fs-global-access-log-mode", Required = false, Default = 0, HelpText = "Enables FS access log output to the console.")]
public int FsGlobalAccessLogMode { get; set; } public int FsGlobalAccessLogMode { get; set; }
[Option("turbo-multiplier", Required = false, Default = 200, HelpText = "The Turbo mode clock speed multiplier.")]
public long TurboMultiplier { get; set; }
[Option("disable-vsync", Required = false, HelpText = "Disables Vertical Sync.")] [Option("disable-vsync", Required = false, HelpText = "Disables Vertical Sync.")]
public bool DisableVSync { get; set; } public bool DisableVSync { get; set; }

View File

@ -580,7 +580,8 @@ namespace Ryujinx.Headless.SDL2
options.AudioVolume, options.AudioVolume,
options.UseHypervisor ?? true, options.UseHypervisor ?? true,
options.MultiplayerLanInterfaceId, options.MultiplayerLanInterfaceId,
Common.Configuration.Multiplayer.MultiplayerMode.Disabled); Common.Configuration.Multiplayer.MultiplayerMode.Disabled,
options.TurboMultiplier);
return new Switch(configuration); return new Switch(configuration);
} }

View File

@ -312,7 +312,8 @@ namespace Ryujinx.Headless.SDL2
Device.EnableDeviceVsync, Device.EnableDeviceVsync,
dockedMode, dockedMode,
Device.Configuration.AspectRatio.ToText(), Device.Configuration.AspectRatio.ToText(),
$"Game: {Device.Statistics.GetGameFrameRate():00.00} FPS ({Device.Statistics.GetGameFrameTime():00.00} ms)", $"Game: {Device.Statistics.GetGameFrameRate():00.00} FPS ({Device.Statistics.GetGameFrameTime():00.00} ms)"
+ (Device.TurboMode ? $" Turbo ({Device.Configuration.TurboMultiplier}%)" : ""),
$"FIFO: {Device.Statistics.GetFifoPercent():0.00} %", $"FIFO: {Device.Statistics.GetFifoPercent():0.00} %",
$"GPU: {_gpuDriverName}")); $"GPU: {_gpuDriverName}"));

View File

@ -15,7 +15,7 @@ namespace Ryujinx.UI.Common.Configuration
/// <summary> /// <summary>
/// The current version of the file format /// The current version of the file format
/// </summary> /// </summary>
public const int CurrentVersion = 51; public const int CurrentVersion = 52;
/// <summary> /// <summary>
/// Version of the configuration file format /// Version of the configuration file format
@ -177,6 +177,11 @@ namespace Ryujinx.UI.Common.Configuration
/// </summary> /// </summary>
public HideCursorMode HideCursor { get; set; } public HideCursorMode HideCursor { get; set; }
/// <summary>
/// Clock speed multiplier for Turbo mode
/// </summary>
public long TurboMultiplier { get; set; }
/// <summary> /// <summary>
/// Enables or disables Vertical Sync /// Enables or disables Vertical Sync
/// </summary> /// </summary>

View File

@ -366,6 +366,11 @@ namespace Ryujinx.UI.Common.Configuration
/// </summary> /// </summary>
public ReactiveObject<bool> UseHypervisor { get; private set; } public ReactiveObject<bool> UseHypervisor { get; private set; }
/// <summary>
/// Turbo mode clock speed multiplier
/// </summary>
public ReactiveObject<long> TurboMultiplier { get; private set; }
public SystemSection() public SystemSection()
{ {
Language = new ReactiveObject<Language>(); Language = new ReactiveObject<Language>();
@ -394,6 +399,8 @@ namespace Ryujinx.UI.Common.Configuration
AudioVolume.Event += static (sender, e) => LogValueChange(e, nameof(AudioVolume)); AudioVolume.Event += static (sender, e) => LogValueChange(e, nameof(AudioVolume));
UseHypervisor = new ReactiveObject<bool>(); UseHypervisor = new ReactiveObject<bool>();
UseHypervisor.Event += static (sender, e) => LogValueChange(e, nameof(UseHypervisor)); UseHypervisor.Event += static (sender, e) => LogValueChange(e, nameof(UseHypervisor));
TurboMultiplier = new ReactiveObject<long>();
TurboMultiplier.Event += static (sender, e) => LogValueChange(e, nameof(TurboMultiplier));
} }
} }
@ -688,6 +695,7 @@ namespace Ryujinx.UI.Common.Configuration
SystemTimeZone = System.TimeZone, SystemTimeZone = System.TimeZone,
SystemTimeOffset = System.SystemTimeOffset, SystemTimeOffset = System.SystemTimeOffset,
DockedMode = System.EnableDockedMode, DockedMode = System.EnableDockedMode,
TurboMultiplier = System.TurboMultiplier,
EnableDiscordIntegration = EnableDiscordIntegration, EnableDiscordIntegration = EnableDiscordIntegration,
CheckUpdatesOnStart = CheckUpdatesOnStart, CheckUpdatesOnStart = CheckUpdatesOnStart,
ShowConfirmExit = ShowConfirmExit, ShowConfirmExit = ShowConfirmExit,
@ -797,6 +805,7 @@ namespace Ryujinx.UI.Common.Configuration
System.TimeZone.Value = "UTC"; System.TimeZone.Value = "UTC";
System.SystemTimeOffset.Value = 0; System.SystemTimeOffset.Value = 0;
System.EnableDockedMode.Value = true; System.EnableDockedMode.Value = true;
System.TurboMultiplier.Value = 200;
EnableDiscordIntegration.Value = true; EnableDiscordIntegration.Value = true;
CheckUpdatesOnStart.Value = true; CheckUpdatesOnStart.Value = true;
ShowConfirmExit.Value = true; ShowConfirmExit.Value = true;
@ -871,6 +880,8 @@ namespace Ryujinx.UI.Common.Configuration
ResScaleDown = Key.Unbound, ResScaleDown = Key.Unbound,
VolumeUp = Key.Unbound, VolumeUp = Key.Unbound,
VolumeDown = Key.Unbound, VolumeDown = Key.Unbound,
ToggleTurbo = Key.Unbound,
TurboWhileHeld = false,
}; };
Hid.InputConfig.Value = new List<InputConfig> Hid.InputConfig.Value = new List<InputConfig>
{ {
@ -1477,6 +1488,30 @@ namespace Ryujinx.UI.Common.Configuration
configurationFileUpdated = true; configurationFileUpdated = true;
} }
if (configurationFileFormat.Version < 52)
{
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 52.");
configurationFileFormat.TurboMultiplier = 200;
configurationFileFormat.Hotkeys = new KeyboardHotkeys
{
ToggleTurbo = Key.Unbound,
TurboWhileHeld = false,
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
ShowUI = configurationFileFormat.Hotkeys.ShowUI,
Pause = configurationFileFormat.Hotkeys.Pause,
ToggleMute = configurationFileFormat.Hotkeys.ToggleMute,
ResScaleUp = configurationFileFormat.Hotkeys.ResScaleUp,
ResScaleDown = configurationFileFormat.Hotkeys.ResScaleDown,
VolumeUp = configurationFileFormat.Hotkeys.VolumeUp,
VolumeDown = configurationFileFormat.Hotkeys.VolumeDown,
ToggleVsync = configurationFileFormat.Hotkeys.ToggleVsync,
};
configurationFileUpdated = true;
}
Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog; Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog;
Graphics.ResScale.Value = configurationFileFormat.ResScale; Graphics.ResScale.Value = configurationFileFormat.ResScale;
Graphics.ResScaleCustom.Value = configurationFileFormat.ResScaleCustom; Graphics.ResScaleCustom.Value = configurationFileFormat.ResScaleCustom;
@ -1504,6 +1539,7 @@ namespace Ryujinx.UI.Common.Configuration
System.TimeZone.Value = configurationFileFormat.SystemTimeZone; System.TimeZone.Value = configurationFileFormat.SystemTimeZone;
System.SystemTimeOffset.Value = configurationFileFormat.SystemTimeOffset; System.SystemTimeOffset.Value = configurationFileFormat.SystemTimeOffset;
System.EnableDockedMode.Value = configurationFileFormat.DockedMode; System.EnableDockedMode.Value = configurationFileFormat.DockedMode;
System.TurboMultiplier.Value = configurationFileFormat.TurboMultiplier;
EnableDiscordIntegration.Value = configurationFileFormat.EnableDiscordIntegration; EnableDiscordIntegration.Value = configurationFileFormat.EnableDiscordIntegration;
CheckUpdatesOnStart.Value = configurationFileFormat.CheckUpdatesOnStart; CheckUpdatesOnStart.Value = configurationFileFormat.CheckUpdatesOnStart;
ShowConfirmExit.Value = configurationFileFormat.ShowConfirmExit; ShowConfirmExit.Value = configurationFileFormat.ShowConfirmExit;

View File

@ -23,6 +23,7 @@ using Ryujinx.Common.Configuration.Multiplayer;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Common.SystemInterop; using Ryujinx.Common.SystemInterop;
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
using Ryujinx.Cpu;
using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.GAL.Multithreading; using Ryujinx.Graphics.GAL.Multithreading;
using Ryujinx.Graphics.Gpu; using Ryujinx.Graphics.Gpu;
@ -872,7 +873,8 @@ namespace Ryujinx.Ava
ConfigurationState.Instance.System.AudioVolume, ConfigurationState.Instance.System.AudioVolume,
ConfigurationState.Instance.System.UseHypervisor, ConfigurationState.Instance.System.UseHypervisor,
ConfigurationState.Instance.Multiplayer.LanInterfaceId.Value, ConfigurationState.Instance.Multiplayer.LanInterfaceId.Value,
ConfigurationState.Instance.Multiplayer.Mode); ConfigurationState.Instance.Multiplayer.Mode,
ConfigurationState.Instance.System.TurboMultiplier);
Device = new Switch(configuration); Device = new Switch(configuration);
} }
@ -1069,7 +1071,8 @@ namespace Ryujinx.Ava
LocaleManager.Instance[LocaleKeys.VolumeShort] + $": {(int)(Device.GetVolume() * 100)}%", LocaleManager.Instance[LocaleKeys.VolumeShort] + $": {(int)(Device.GetVolume() * 100)}%",
dockedMode, dockedMode,
ConfigurationState.Instance.Graphics.AspectRatio.Value.ToText(), ConfigurationState.Instance.Graphics.AspectRatio.Value.ToText(),
LocaleManager.Instance[LocaleKeys.Game] + $": {Device.Statistics.GetGameFrameRate():00.00} FPS ({Device.Statistics.GetGameFrameTime():00.00} ms)", LocaleManager.Instance[LocaleKeys.Game] + $": {Device.Statistics.GetGameFrameRate():00.00} FPS ({Device.Statistics.GetGameFrameTime():00.00} ms)"
+ (Device.TurboMode ? $" Turbo ({Device.Configuration.TurboMultiplier}%)" : ""),
$"FIFO: {Device.Statistics.GetFifoPercent():00.00} %")); $"FIFO: {Device.Statistics.GetFifoPercent():00.00} %"));
} }
@ -1147,6 +1150,11 @@ namespace Ryujinx.Ava
if (currentHotkeyState != _prevHotkeyState) if (currentHotkeyState != _prevHotkeyState)
{ {
if (ConfigurationState.Instance.Hid.Hotkeys.Value.TurboWhileHeld &&
_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.ToggleTurbo) != Device.TurboMode)
{
Device.ToggleTurbo();
}
switch (currentHotkeyState) switch (currentHotkeyState)
{ {
case KeyboardHotkeyState.ToggleVSync: case KeyboardHotkeyState.ToggleVSync:
@ -1158,6 +1166,12 @@ namespace Ryujinx.Ava
case KeyboardHotkeyState.ShowUI: case KeyboardHotkeyState.ShowUI:
_viewModel.ShowMenuAndStatusBar = !_viewModel.ShowMenuAndStatusBar; _viewModel.ShowMenuAndStatusBar = !_viewModel.ShowMenuAndStatusBar;
break; break;
case KeyboardHotkeyState.ToggleTurbo:
if (!ConfigurationState.Instance.Hid.Hotkeys.Value.TurboWhileHeld)
{
Device.ToggleTurbo();
}
break;
case KeyboardHotkeyState.Pause: case KeyboardHotkeyState.Pause:
if (_viewModel.IsPaused) if (_viewModel.IsPaused)
{ {
@ -1273,6 +1287,10 @@ namespace Ryujinx.Ava
{ {
state = KeyboardHotkeyState.VolumeDown; state = KeyboardHotkeyState.VolumeDown;
} }
else if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.ToggleTurbo))
{
state = KeyboardHotkeyState.ToggleTurbo;
}
return state; return state;
} }

View File

@ -135,6 +135,9 @@
"SettingsTabSystemSystemLanguageTraditionalChinese": "Traditional Chinese", "SettingsTabSystemSystemLanguageTraditionalChinese": "Traditional Chinese",
"SettingsTabSystemSystemTimeZone": "System TimeZone:", "SettingsTabSystemSystemTimeZone": "System TimeZone:",
"SettingsTabSystemSystemTime": "System Time:", "SettingsTabSystemSystemTime": "System Time:",
"SettingsTabSystemTurboMultiplierValue": "Turbo multiplier:",
"SettingsTabSystemTurboMultiplierSliderTooltip": "The Turbo mode multiplier target value.",
"SettingsTabSystemTurboMultiplierValueTooltip": "The Turbo mode multiplier, as a percentage of the normal Switch clock speed.",
"SettingsTabSystemEnableVsync": "VSync", "SettingsTabSystemEnableVsync": "VSync",
"SettingsTabSystemEnablePptc": "PPTC (Profiled Persistent Translation Cache)", "SettingsTabSystemEnablePptc": "PPTC (Profiled Persistent Translation Cache)",
"SettingsTabSystemEnableFsIntegrityChecks": "FS Integrity Checks", "SettingsTabSystemEnableFsIntegrityChecks": "FS Integrity Checks",
@ -628,6 +631,7 @@
"SettingsTabNetworkConnection": "Network Connection", "SettingsTabNetworkConnection": "Network Connection",
"SettingsTabCpuCache": "CPU Cache", "SettingsTabCpuCache": "CPU Cache",
"SettingsTabCpuMemory": "CPU Mode", "SettingsTabCpuMemory": "CPU Mode",
"SettingsTabCpuHacks": "Hacks",
"DialogUpdaterFlatpakNotSupportedMessage": "Please update Ryujinx via FlatHub.", "DialogUpdaterFlatpakNotSupportedMessage": "Please update Ryujinx via FlatHub.",
"UpdaterDisabledWarningTitle": "Updater Disabled!", "UpdaterDisabledWarningTitle": "Updater Disabled!",
"ControllerSettingsRotate90": "Rotate 90° Clockwise", "ControllerSettingsRotate90": "Rotate 90° Clockwise",
@ -738,6 +742,9 @@
"RyujinxUpdaterMessage": "Do you want to update Ryujinx to the latest version?", "RyujinxUpdaterMessage": "Do you want to update Ryujinx to the latest version?",
"SettingsTabHotkeysVolumeUpHotkey": "Increase Volume:", "SettingsTabHotkeysVolumeUpHotkey": "Increase Volume:",
"SettingsTabHotkeysVolumeDownHotkey": "Decrease Volume:", "SettingsTabHotkeysVolumeDownHotkey": "Decrease Volume:",
"SettingsTabHotkeysToggleTurboHotkey": "Toggle turbo mode:",
"SettingsTabHotkeysToggleTurboToggleTooltip": "Makes the turbo hotkey enable turbo while held instead of toggling it.",
"SettingsTabHotkeysToggleTurboToggle": "Enable turbo while held:",
"SettingsEnableMacroHLE": "Enable Macro HLE", "SettingsEnableMacroHLE": "Enable Macro HLE",
"SettingsEnableMacroHLETooltip": "High-level emulation of GPU Macro code.\n\nImproves performance, but may cause graphical glitches in some games.\n\nLeave ON if unsure.", "SettingsEnableMacroHLETooltip": "High-level emulation of GPU Macro code.\n\nImproves performance, but may cause graphical glitches in some games.\n\nLeave ON if unsure.",
"SettingsEnableColorSpacePassthrough": "Color Space Passthrough", "SettingsEnableColorSpacePassthrough": "Color Space Passthrough",

View File

@ -12,5 +12,6 @@ namespace Ryujinx.Ava.Common
ResScaleDown, ResScaleDown,
VolumeUp, VolumeUp,
VolumeDown, VolumeDown,
ToggleTurbo,
} }
} }

View File

@ -104,6 +104,28 @@ namespace Ryujinx.Ava.UI.Models.Input
} }
} }
private Key _toggleTurbo;
public Key ToggleTurbo
{
get => _toggleTurbo;
set
{
_toggleTurbo = value;
OnPropertyChanged();
}
}
private bool _turboWhileHeld;
public bool TurboWhileHeld
{
get => _turboWhileHeld;
set
{
_turboWhileHeld = value;
OnPropertyChanged();
}
}
public HotkeyConfig(KeyboardHotkeys config) public HotkeyConfig(KeyboardHotkeys config)
{ {
if (config != null) if (config != null)
@ -117,6 +139,8 @@ namespace Ryujinx.Ava.UI.Models.Input
ResScaleDown = config.ResScaleDown; ResScaleDown = config.ResScaleDown;
VolumeUp = config.VolumeUp; VolumeUp = config.VolumeUp;
VolumeDown = config.VolumeDown; VolumeDown = config.VolumeDown;
ToggleTurbo = config.ToggleTurbo;
TurboWhileHeld = config.TurboWhileHeld;
} }
} }
@ -133,6 +157,8 @@ namespace Ryujinx.Ava.UI.Models.Input
ResScaleDown = ResScaleDown, ResScaleDown = ResScaleDown,
VolumeUp = VolumeUp, VolumeUp = VolumeUp,
VolumeDown = VolumeDown, VolumeDown = VolumeDown,
ToggleTurbo = ToggleTurbo,
TurboWhileHeld = TurboWhileHeld,
}; };
return config; return config;

View File

@ -13,6 +13,7 @@ using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Multiplayer; using Ryujinx.Common.Configuration.Multiplayer;
using Ryujinx.Common.GraphicsDriver; using Ryujinx.Common.GraphicsDriver;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Cpu;
using Ryujinx.Graphics.Vulkan; using Ryujinx.Graphics.Vulkan;
using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS.Services.Time.TimeZone; using Ryujinx.HLE.HOS.Services.Time.TimeZone;
@ -49,6 +50,7 @@ namespace Ryujinx.Ava.UI.ViewModels
private int _graphicsBackendIndex; private int _graphicsBackendIndex;
private int _scalingFilter; private int _scalingFilter;
private int _scalingFilterLevel; private int _scalingFilterLevel;
private long _turboModeMultiplier;
public event Action CloseWindow; public event Action CloseWindow;
public event Action SaveSettingsEvent; public event Action SaveSettingsEvent;
@ -135,6 +137,26 @@ namespace Ryujinx.Ava.UI.ViewModels
public int HideCursor { get; set; } public int HideCursor { get; set; }
public bool EnableDockedMode { get; set; } public bool EnableDockedMode { get; set; }
public bool EnableKeyboard { get; set; } public bool EnableKeyboard { get; set; }
public long TurboMultiplier
{
get => _turboModeMultiplier;
set
{
if (_turboModeMultiplier != value)
{
_turboModeMultiplier = value;
OnPropertyChanged();
OnPropertyChanged((nameof(TurboMultiplierPercentageText)));
}
}
}
public string TurboMultiplierPercentageText
{
get
{
return TurboMultiplier.ToString() + "%";
}
}
public bool EnableMouse { get; set; } public bool EnableMouse { get; set; }
public bool EnableVsync { get; set; } public bool EnableVsync { get; set; }
public bool EnablePptc { get; set; } public bool EnablePptc { get; set; }
@ -433,6 +455,7 @@ namespace Ryujinx.Ava.UI.ViewModels
EnablePptc = config.System.EnablePtc; EnablePptc = config.System.EnablePtc;
MemoryMode = (int)config.System.MemoryManagerMode.Value; MemoryMode = (int)config.System.MemoryManagerMode.Value;
UseHypervisor = config.System.UseHypervisor; UseHypervisor = config.System.UseHypervisor;
_turboModeMultiplier = config.System.TurboMultiplier;
// Graphics // Graphics
GraphicsBackendIndex = (int)config.Graphics.GraphicsBackend.Value; GraphicsBackendIndex = (int)config.Graphics.GraphicsBackend.Value;
@ -518,6 +541,7 @@ namespace Ryujinx.Ava.UI.ViewModels
} }
config.System.SystemTimeOffset.Value = Convert.ToInt64((CurrentDate.ToUnixTimeSeconds() + CurrentTime.TotalSeconds) - DateTimeOffset.Now.ToUnixTimeSeconds()); config.System.SystemTimeOffset.Value = Convert.ToInt64((CurrentDate.ToUnixTimeSeconds() + CurrentTime.TotalSeconds) - DateTimeOffset.Now.ToUnixTimeSeconds());
config.System.TurboMultiplier.Value = TurboMultiplier;
config.Graphics.EnableVsync.Value = EnableVsync; config.Graphics.EnableVsync.Value = EnableVsync;
config.System.EnableFsIntegrityChecks.Value = EnableFsIntegrityChecks; config.System.EnableFsIntegrityChecks.Value = EnableFsIntegrityChecks;
config.System.ExpandRam.Value = ExpandDramSize; config.System.ExpandRam.Value = ExpandDramSize;
@ -584,6 +608,7 @@ namespace Ryujinx.Ava.UI.ViewModels
config.ToFileFormat().SaveConfig(Program.ConfigurationPath); config.ToFileFormat().SaveConfig(Program.ConfigurationPath);
MainWindow.UpdateGraphicsConfig(); MainWindow.UpdateGraphicsConfig();
MainWindow.UpdateTurboConfig(TurboMultiplier);
SaveSettingsEvent?.Invoke(); SaveSettingsEvent?.Invoke();

View File

@ -1,10 +1,11 @@
<UserControl <UserControl
x:Class="Ryujinx.Ava.UI.Views.Settings.SettingsCPUView" x:Class="Ryujinx.Ava.UI.Views.Settings.SettingsCPUView"
xmlns="https://github.com/avaloniaui" xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale" xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels" xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
mc:Ignorable="d" mc:Ignorable="d"
x:DataType="viewModels:SettingsViewModel"> x:DataType="viewModels:SettingsViewModel">
@ -71,6 +72,48 @@
ToolTip.Tip="{locale:Locale UseHypervisorTooltip}" /> ToolTip.Tip="{locale:Locale UseHypervisorTooltip}" />
</CheckBox> </CheckBox>
</StackPanel> </StackPanel>
<Separator Height="1" />
<StackPanel
Orientation="Vertical"
Spacing="2">
<TextBlock
Classes="h1"
Text="{locale:Locale SettingsTabCpuHacks}" />
<TextBlock
Foreground="{DynamicResource SecondaryTextColor}"
Text="{locale:Locale SettingsTabSystemHacksNote}" />
</StackPanel>
<StackPanel Margin="0,0,0,10"
Orientation="Horizontal">
<TextBlock
VerticalAlignment="Center"
Text="{locale:Locale SettingsTabSystemTurboMultiplierValue}"
ToolTip.Tip="{locale:Locale SettingsTabSystemTurboMultiplierValueTooltip}"
Width="250" />
<ui:NumberBox ToolTip.Tip="{locale:Locale SettingsTabSystemTurboMultiplierValueTooltip}"
Value="{Binding TurboMultiplier}"
Width="165"
SmallChange="1.0"
LargeChange="10"
SimpleNumberFormat="F0"
SpinButtonPlacementMode="Hidden"
Minimum="50"
Maximum="500" />
<Slider Value="{Binding TurboMultiplier}"
ToolTip.Tip="{locale:Locale SettingsTabSystemTurboMultiplierSliderTooltip}"
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" />
</StackPanel>
</StackPanel> </StackPanel>
</Border> </Border>
</ScrollViewer> </ScrollViewer>

View File

@ -1,4 +1,4 @@
<UserControl <UserControl
x:Class="Ryujinx.Ava.UI.Views.Settings.SettingsHotkeysView" x:Class="Ryujinx.Ava.UI.Views.Settings.SettingsHotkeysView"
xmlns="https://github.com/avaloniaui" xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
@ -103,6 +103,20 @@
<TextBlock Text="{Binding KeyboardHotkey.VolumeDown, Converter={StaticResource Key}}" /> <TextBlock Text="{Binding KeyboardHotkey.VolumeDown, Converter={StaticResource Key}}" />
</ToggleButton> </ToggleButton>
</StackPanel> </StackPanel>
<StackPanel Margin="10,0,0,0" Orientation="Horizontal">
<TextBlock VerticalAlignment="Center" Text="{locale:Locale SettingsTabHotkeysToggleTurboHotkey}" Width="230" />
<ToggleButton Name="ToggleTurbo">
<TextBlock
Text="{Binding KeyboardHotkey.ToggleTurbo, Mode=TwoWay, Converter={StaticResource Key}}"
TextAlignment="Center" />
</ToggleButton>
</StackPanel>
<StackPanel Margin="10,0,0,0" Orientation="Horizontal">
<TextBlock Text="{locale:Locale SettingsTabHotkeysToggleTurboToggle}"
ToolTip.Tip="{locale:Locale SettingsTabHotkeysToggleTurboToggleTooltip}"
Width="230" />
<CheckBox IsChecked="{Binding KeyboardHotkey.TurboWhileHeld}" />
</StackPanel>
</StackPanel> </StackPanel>
</Border> </Border>
</ScrollViewer> </ScrollViewer>

View File

@ -109,6 +109,9 @@ namespace Ryujinx.Ava.UI.Views.Settings
case "VolumeDown": case "VolumeDown":
viewModel.KeyboardHotkey.VolumeDown = buttonValue.AsHidType<Key>(); viewModel.KeyboardHotkey.VolumeDown = buttonValue.AsHidType<Key>();
break; break;
case "ToggleTurbo":
viewModel.KeyboardHotkey.ToggleTurbo = buttonValue.AsHidType<Key>();
break;
} }
} }
}; };

View File

@ -1,4 +1,4 @@
<UserControl <UserControl
x:Class="Ryujinx.Ava.UI.Views.Settings.SettingsSystemView" x:Class="Ryujinx.Ava.UI.Views.Settings.SettingsSystemView"
xmlns="https://github.com/avaloniaui" xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
@ -221,4 +221,4 @@
</StackPanel> </StackPanel>
</Border> </Border>
</ScrollViewer> </ScrollViewer>
</UserControl> </UserControl>

View File

@ -503,6 +503,18 @@ namespace Ryujinx.Ava.UI.Windows
} }
} }
public static void UpdateTurboConfig(long turboMultiplier)
{
if (MainWindow.MainWindowViewModel.IsGameRunning)
{
MainWindow.MainWindowViewModel.AppHost.Device.Configuration.TurboMultiplier = turboMultiplier;
if (MainWindow.MainWindowViewModel.AppHost.Device.TurboMode)
{
MainWindow.MainWindowViewModel.AppHost.Device.SetTickSourceMultiplier(turboMultiplier);
}
}
}
public static void UpdateGraphicsConfig() public static void UpdateGraphicsConfig()
{ {
#pragma warning disable IDE0055 // Disable formatting #pragma warning disable IDE0055 // Disable formatting