mirror of
https://github.com/GreemDev/Ryujinx.git
synced 2024-12-22 18:05:46 +00:00
Add custom refresh rate mode to VSync option (#238)
Rebased @jcm93's refreshinterval branch: https://github.com/jcm93/Ryujinx/tree/refreshinterval The option is placed under System/Hacks. Disabled, it's the default Ryujinx behavior. Enabled, the behavior is shown in the attached screenshots. If a framerate is too high or low, you can adjust the value where you normally toggle VSync on and off. It will also cycle through the default on/off toggles. Also, in order to reduce clutter, I made an adjustment to remove the target FPS and only show the percentage. --------- Co-authored-by: jcm <6864788+jcm93@users.noreply.github.com>
This commit is contained in:
parent
7e16fccfc1
commit
2e6794e69b
34 changed files with 678 additions and 110 deletions
|
@ -2,7 +2,7 @@ namespace Ryujinx.Common.Configuration.Hid
|
||||||
{
|
{
|
||||||
public class KeyboardHotkeys
|
public class KeyboardHotkeys
|
||||||
{
|
{
|
||||||
public Key ToggleVsync { get; set; }
|
public Key ToggleVSyncMode { get; set; }
|
||||||
public Key Screenshot { get; set; }
|
public Key Screenshot { get; set; }
|
||||||
public Key ShowUI { get; set; }
|
public Key ShowUI { get; set; }
|
||||||
public Key Pause { get; set; }
|
public Key Pause { get; set; }
|
||||||
|
@ -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 CustomVSyncIntervalIncrement { get; set; }
|
||||||
|
public Key CustomVSyncIntervalDecrement { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
9
src/Ryujinx.Common/Configuration/VSyncMode.cs
Normal file
9
src/Ryujinx.Common/Configuration/VSyncMode.cs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
namespace Ryujinx.Common.Configuration
|
||||||
|
{
|
||||||
|
public enum VSyncMode
|
||||||
|
{
|
||||||
|
Switch,
|
||||||
|
Unbounded,
|
||||||
|
Custom
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ namespace Ryujinx.Graphics.GAL
|
||||||
|
|
||||||
void SetSize(int width, int height);
|
void SetSize(int width, int height);
|
||||||
|
|
||||||
void ChangeVSyncMode(bool vsyncEnabled);
|
void ChangeVSyncMode(VSyncMode vSyncMode);
|
||||||
|
|
||||||
void SetAntiAliasing(AntiAliasing antialiasing);
|
void SetAntiAliasing(AntiAliasing antialiasing);
|
||||||
void SetScalingFilter(ScalingFilter type);
|
void SetScalingFilter(ScalingFilter type);
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
||||||
_impl.Window.SetSize(width, height);
|
_impl.Window.SetSize(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ChangeVSyncMode(bool vsyncEnabled) { }
|
public void ChangeVSyncMode(VSyncMode vSyncMode) { }
|
||||||
|
|
||||||
public void SetAntiAliasing(AntiAliasing effect) { }
|
public void SetAntiAliasing(AntiAliasing effect) { }
|
||||||
|
|
||||||
|
|
9
src/Ryujinx.Graphics.GAL/VSyncMode.cs
Normal file
9
src/Ryujinx.Graphics.GAL/VSyncMode.cs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
namespace Ryujinx.Graphics.GAL
|
||||||
|
{
|
||||||
|
public enum VSyncMode
|
||||||
|
{
|
||||||
|
Switch,
|
||||||
|
Unbounded,
|
||||||
|
Custom
|
||||||
|
}
|
||||||
|
}
|
|
@ -54,7 +54,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
GL.PixelStore(PixelStoreParameter.UnpackAlignment, 4);
|
GL.PixelStore(PixelStoreParameter.UnpackAlignment, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ChangeVSyncMode(bool vsyncEnabled) { }
|
public void ChangeVSyncMode(VSyncMode vSyncMode) { }
|
||||||
|
|
||||||
public void SetSize(int width, int height)
|
public void SetSize(int width, int height)
|
||||||
{
|
{
|
||||||
|
|
|
@ -29,7 +29,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
private int _width;
|
private int _width;
|
||||||
private int _height;
|
private int _height;
|
||||||
private bool _vsyncEnabled;
|
private VSyncMode _vSyncMode;
|
||||||
private bool _swapchainIsDirty;
|
private bool _swapchainIsDirty;
|
||||||
private VkFormat _format;
|
private VkFormat _format;
|
||||||
private AntiAliasing _currentAntiAliasing;
|
private AntiAliasing _currentAntiAliasing;
|
||||||
|
@ -139,7 +139,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
ImageArrayLayers = 1,
|
ImageArrayLayers = 1,
|
||||||
PreTransform = capabilities.CurrentTransform,
|
PreTransform = capabilities.CurrentTransform,
|
||||||
CompositeAlpha = ChooseCompositeAlpha(capabilities.SupportedCompositeAlpha),
|
CompositeAlpha = ChooseCompositeAlpha(capabilities.SupportedCompositeAlpha),
|
||||||
PresentMode = ChooseSwapPresentMode(presentModes, _vsyncEnabled),
|
PresentMode = ChooseSwapPresentMode(presentModes, _vSyncMode),
|
||||||
Clipped = true,
|
Clipped = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -279,9 +279,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PresentModeKHR ChooseSwapPresentMode(PresentModeKHR[] availablePresentModes, bool vsyncEnabled)
|
private static PresentModeKHR ChooseSwapPresentMode(PresentModeKHR[] availablePresentModes, VSyncMode vSyncMode)
|
||||||
{
|
{
|
||||||
if (!vsyncEnabled && availablePresentModes.Contains(PresentModeKHR.ImmediateKhr))
|
if (vSyncMode == VSyncMode.Unbounded && availablePresentModes.Contains(PresentModeKHR.ImmediateKhr))
|
||||||
{
|
{
|
||||||
return PresentModeKHR.ImmediateKhr;
|
return PresentModeKHR.ImmediateKhr;
|
||||||
}
|
}
|
||||||
|
@ -634,9 +634,10 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_swapchainIsDirty = true;
|
_swapchainIsDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ChangeVSyncMode(bool vsyncEnabled)
|
public override void ChangeVSyncMode(VSyncMode vSyncMode)
|
||||||
{
|
{
|
||||||
_vsyncEnabled = vsyncEnabled;
|
_vSyncMode = vSyncMode;
|
||||||
|
//present mode may change, so mark the swapchain for recreation
|
||||||
_swapchainIsDirty = true;
|
_swapchainIsDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
public abstract void Dispose();
|
public abstract void Dispose();
|
||||||
public abstract void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback);
|
public abstract void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback);
|
||||||
public abstract void SetSize(int width, int height);
|
public abstract void SetSize(int width, int height);
|
||||||
public abstract void ChangeVSyncMode(bool vsyncEnabled);
|
public abstract void ChangeVSyncMode(VSyncMode vSyncMode);
|
||||||
public abstract void SetAntiAliasing(AntiAliasing effect);
|
public abstract void SetAntiAliasing(AntiAliasing effect);
|
||||||
public abstract void SetScalingFilter(ScalingFilter scalerType);
|
public abstract void SetScalingFilter(ScalingFilter scalerType);
|
||||||
public abstract void SetScalingFilterLevel(float scale);
|
public abstract void SetScalingFilterLevel(float scale);
|
||||||
|
|
|
@ -9,6 +9,7 @@ using Ryujinx.HLE.HOS.Services.Account.Acc;
|
||||||
using Ryujinx.HLE.HOS.SystemState;
|
using Ryujinx.HLE.HOS.SystemState;
|
||||||
using Ryujinx.HLE.UI;
|
using Ryujinx.HLE.UI;
|
||||||
using System;
|
using System;
|
||||||
|
using VSyncMode = Ryujinx.Common.Configuration.VSyncMode;
|
||||||
|
|
||||||
namespace Ryujinx.HLE
|
namespace Ryujinx.HLE
|
||||||
{
|
{
|
||||||
|
@ -84,9 +85,14 @@ namespace Ryujinx.HLE
|
||||||
internal readonly RegionCode Region;
|
internal readonly RegionCode Region;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Control the initial state of the vertical sync in the SurfaceFlinger service.
|
/// Control the initial state of the present interval in the SurfaceFlinger service (previously Vsync).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal readonly bool EnableVsync;
|
internal readonly VSyncMode VSyncMode;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Control the custom VSync interval, if enabled and active.
|
||||||
|
/// </summary>
|
||||||
|
internal readonly int CustomVSyncInterval;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Control the initial state of the docked mode.
|
/// Control the initial state of the docked mode.
|
||||||
|
@ -195,7 +201,7 @@ namespace Ryujinx.HLE
|
||||||
IHostUIHandler hostUIHandler,
|
IHostUIHandler hostUIHandler,
|
||||||
SystemLanguage systemLanguage,
|
SystemLanguage systemLanguage,
|
||||||
RegionCode region,
|
RegionCode region,
|
||||||
bool enableVsync,
|
VSyncMode vSyncMode,
|
||||||
bool enableDockedMode,
|
bool enableDockedMode,
|
||||||
bool enablePtc,
|
bool enablePtc,
|
||||||
bool enableInternetAccess,
|
bool enableInternetAccess,
|
||||||
|
@ -212,7 +218,8 @@ namespace Ryujinx.HLE
|
||||||
MultiplayerMode multiplayerMode,
|
MultiplayerMode multiplayerMode,
|
||||||
bool multiplayerDisableP2p,
|
bool multiplayerDisableP2p,
|
||||||
string multiplayerLdnPassphrase,
|
string multiplayerLdnPassphrase,
|
||||||
string multiplayerLdnServer)
|
string multiplayerLdnServer,
|
||||||
|
int customVSyncInterval)
|
||||||
{
|
{
|
||||||
VirtualFileSystem = virtualFileSystem;
|
VirtualFileSystem = virtualFileSystem;
|
||||||
LibHacHorizonManager = libHacHorizonManager;
|
LibHacHorizonManager = libHacHorizonManager;
|
||||||
|
@ -225,7 +232,8 @@ namespace Ryujinx.HLE
|
||||||
HostUIHandler = hostUIHandler;
|
HostUIHandler = hostUIHandler;
|
||||||
SystemLanguage = systemLanguage;
|
SystemLanguage = systemLanguage;
|
||||||
Region = region;
|
Region = region;
|
||||||
EnableVsync = enableVsync;
|
VSyncMode = vSyncMode;
|
||||||
|
CustomVSyncInterval = customVSyncInterval;
|
||||||
EnableDockedMode = enableDockedMode;
|
EnableDockedMode = enableDockedMode;
|
||||||
EnablePtc = enablePtc;
|
EnablePtc = enablePtc;
|
||||||
EnableInternetAccess = enableInternetAccess;
|
EnableInternetAccess = enableInternetAccess;
|
||||||
|
|
|
@ -10,13 +10,12 @@ using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using VSyncMode = Ryujinx.Common.Configuration.VSyncMode;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
||||||
{
|
{
|
||||||
class SurfaceFlinger : IConsumerListener, IDisposable
|
class SurfaceFlinger : IConsumerListener, IDisposable
|
||||||
{
|
{
|
||||||
private const int TargetFps = 60;
|
|
||||||
|
|
||||||
private readonly Switch _device;
|
private readonly Switch _device;
|
||||||
|
|
||||||
private readonly Dictionary<long, Layer> _layers;
|
private readonly Dictionary<long, Layer> _layers;
|
||||||
|
@ -32,6 +31,9 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
||||||
private readonly long _spinTicks;
|
private readonly long _spinTicks;
|
||||||
private readonly long _1msTicks;
|
private readonly long _1msTicks;
|
||||||
|
|
||||||
|
private VSyncMode _vSyncMode;
|
||||||
|
private long _targetVSyncInterval;
|
||||||
|
|
||||||
private int _swapInterval;
|
private int _swapInterval;
|
||||||
private int _swapIntervalDelay;
|
private int _swapIntervalDelay;
|
||||||
|
|
||||||
|
@ -88,7 +90,8 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_ticksPerFrame = Stopwatch.Frequency / TargetFps;
|
_ticksPerFrame = Stopwatch.Frequency / _device.TargetVSyncInterval;
|
||||||
|
_targetVSyncInterval = _device.TargetVSyncInterval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,15 +373,20 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
||||||
|
|
||||||
if (acquireStatus == Status.Success)
|
if (acquireStatus == Status.Success)
|
||||||
{
|
{
|
||||||
// If device vsync is disabled, reflect the change.
|
if (_device.VSyncMode == VSyncMode.Unbounded)
|
||||||
if (!_device.EnableDeviceVsync)
|
|
||||||
{
|
{
|
||||||
if (_swapInterval != 0)
|
if (_swapInterval != 0)
|
||||||
{
|
{
|
||||||
UpdateSwapInterval(0);
|
UpdateSwapInterval(0);
|
||||||
|
_vSyncMode = _device.VSyncMode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (item.SwapInterval != _swapInterval)
|
else if (_device.VSyncMode != _vSyncMode)
|
||||||
|
{
|
||||||
|
UpdateSwapInterval(_device.VSyncMode == VSyncMode.Unbounded ? 0 : item.SwapInterval);
|
||||||
|
_vSyncMode = _device.VSyncMode;
|
||||||
|
}
|
||||||
|
else if (item.SwapInterval != _swapInterval || _device.TargetVSyncInterval != _targetVSyncInterval)
|
||||||
{
|
{
|
||||||
UpdateSwapInterval(item.SwapInterval);
|
UpdateSwapInterval(item.SwapInterval);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,11 @@ namespace Ryujinx.HLE
|
||||||
public TamperMachine TamperMachine { get; }
|
public TamperMachine TamperMachine { get; }
|
||||||
public IHostUIHandler UIHandler { get; }
|
public IHostUIHandler UIHandler { get; }
|
||||||
|
|
||||||
public bool EnableDeviceVsync { get; set; }
|
public VSyncMode VSyncMode { get; set; } = VSyncMode.Switch;
|
||||||
|
public bool CustomVSyncIntervalEnabled { get; set; } = false;
|
||||||
|
public int CustomVSyncInterval { get; set; }
|
||||||
|
|
||||||
|
public long TargetVSyncInterval { get; set; } = 60;
|
||||||
|
|
||||||
public bool IsFrameAvailable => Gpu.Window.IsFrameAvailable;
|
public bool IsFrameAvailable => Gpu.Window.IsFrameAvailable;
|
||||||
|
|
||||||
|
@ -59,12 +63,14 @@ namespace Ryujinx.HLE
|
||||||
System.State.SetLanguage(Configuration.SystemLanguage);
|
System.State.SetLanguage(Configuration.SystemLanguage);
|
||||||
System.State.SetRegion(Configuration.Region);
|
System.State.SetRegion(Configuration.Region);
|
||||||
|
|
||||||
EnableDeviceVsync = Configuration.EnableVsync;
|
VSyncMode = Configuration.VSyncMode;
|
||||||
|
CustomVSyncInterval = Configuration.CustomVSyncInterval;
|
||||||
System.State.DockedMode = Configuration.EnableDockedMode;
|
System.State.DockedMode = Configuration.EnableDockedMode;
|
||||||
System.PerformanceState.PerformanceMode = System.State.DockedMode ? PerformanceMode.Boost : PerformanceMode.Default;
|
System.PerformanceState.PerformanceMode = System.State.DockedMode ? PerformanceMode.Boost : PerformanceMode.Default;
|
||||||
System.EnablePtc = Configuration.EnablePtc;
|
System.EnablePtc = Configuration.EnablePtc;
|
||||||
System.FsIntegrityCheckLevel = Configuration.FsIntegrityCheckLevel;
|
System.FsIntegrityCheckLevel = Configuration.FsIntegrityCheckLevel;
|
||||||
System.GlobalAccessLogMode = Configuration.FsGlobalAccessLogMode;
|
System.GlobalAccessLogMode = Configuration.FsGlobalAccessLogMode;
|
||||||
|
UpdateVSyncInterval();
|
||||||
#pragma warning restore IDE0055
|
#pragma warning restore IDE0055
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,6 +81,34 @@ namespace Ryujinx.HLE
|
||||||
Gpu.GPFifo.DispatchCalls();
|
Gpu.GPFifo.DispatchCalls();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void IncrementCustomVSyncInterval()
|
||||||
|
{
|
||||||
|
CustomVSyncInterval += 1;
|
||||||
|
UpdateVSyncInterval();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DecrementCustomVSyncInterval()
|
||||||
|
{
|
||||||
|
CustomVSyncInterval -= 1;
|
||||||
|
UpdateVSyncInterval();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateVSyncInterval()
|
||||||
|
{
|
||||||
|
switch (VSyncMode)
|
||||||
|
{
|
||||||
|
case VSyncMode.Custom:
|
||||||
|
TargetVSyncInterval = CustomVSyncInterval;
|
||||||
|
break;
|
||||||
|
case VSyncMode.Switch:
|
||||||
|
TargetVSyncInterval = 60;
|
||||||
|
break;
|
||||||
|
case VSyncMode.Unbounded:
|
||||||
|
TargetVSyncInterval = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool LoadCart(string exeFsDir, string romFsFile = null) => Processes.LoadUnpackedNca(exeFsDir, romFsFile);
|
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 LoadXci(string xciFile, ulong applicationId = 0) => Processes.LoadXci(xciFile, applicationId);
|
||||||
public bool LoadNca(string ncaFile) => Processes.LoadNca(ncaFile);
|
public bool LoadNca(string ncaFile) => Processes.LoadNca(ncaFile);
|
||||||
|
|
|
@ -115,8 +115,11 @@ 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("disable-vsync", Required = false, HelpText = "Disables Vertical Sync.")]
|
[Option("vsync-mode", Required = false, Default = VSyncMode.Switch, HelpText = "Sets the emulated VSync mode (Switch, Unbounded, or Custom).")]
|
||||||
public bool DisableVSync { get; set; }
|
public VSyncMode VSyncMode { get; set; }
|
||||||
|
|
||||||
|
[Option("custom-refresh-rate", Required = false, Default = 90, HelpText = "Sets the custom refresh rate target value (integer).")]
|
||||||
|
public int CustomVSyncInterval { get; set; }
|
||||||
|
|
||||||
[Option("disable-shader-cache", Required = false, HelpText = "Disables Shader cache.")]
|
[Option("disable-shader-cache", Required = false, HelpText = "Disables Shader cache.")]
|
||||||
public bool DisableShaderCache { get; set; }
|
public bool DisableShaderCache { get; set; }
|
||||||
|
|
|
@ -563,7 +563,7 @@ namespace Ryujinx.Headless.SDL2
|
||||||
window,
|
window,
|
||||||
options.SystemLanguage,
|
options.SystemLanguage,
|
||||||
options.SystemRegion,
|
options.SystemRegion,
|
||||||
!options.DisableVSync,
|
options.VSyncMode,
|
||||||
!options.DisableDockedMode,
|
!options.DisableDockedMode,
|
||||||
!options.DisablePTC,
|
!options.DisablePTC,
|
||||||
options.EnableInternetAccess,
|
options.EnableInternetAccess,
|
||||||
|
@ -580,7 +580,8 @@ namespace Ryujinx.Headless.SDL2
|
||||||
Common.Configuration.Multiplayer.MultiplayerMode.Disabled,
|
Common.Configuration.Multiplayer.MultiplayerMode.Disabled,
|
||||||
false,
|
false,
|
||||||
"",
|
"",
|
||||||
"");
|
"",
|
||||||
|
options.CustomVSyncInterval);
|
||||||
|
|
||||||
return new Switch(configuration);
|
return new Switch(configuration);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ using System;
|
||||||
namespace Ryujinx.Headless.SDL2
|
namespace Ryujinx.Headless.SDL2
|
||||||
{
|
{
|
||||||
class StatusUpdatedEventArgs(
|
class StatusUpdatedEventArgs(
|
||||||
bool vSyncEnabled,
|
string vSyncMode,
|
||||||
string dockedMode,
|
string dockedMode,
|
||||||
string aspectRatio,
|
string aspectRatio,
|
||||||
string gameStatus,
|
string gameStatus,
|
||||||
|
@ -11,7 +11,7 @@ namespace Ryujinx.Headless.SDL2
|
||||||
string gpuName)
|
string gpuName)
|
||||||
: EventArgs
|
: EventArgs
|
||||||
{
|
{
|
||||||
public bool VSyncEnabled = vSyncEnabled;
|
public string VSyncMode = vSyncMode;
|
||||||
public string DockedMode = dockedMode;
|
public string DockedMode = dockedMode;
|
||||||
public string AspectRatio = aspectRatio;
|
public string AspectRatio = aspectRatio;
|
||||||
public string GameStatus = gameStatus;
|
public string GameStatus = gameStatus;
|
||||||
|
|
|
@ -314,7 +314,7 @@ namespace Ryujinx.Headless.SDL2
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusUpdatedEvent?.Invoke(this, new StatusUpdatedEventArgs(
|
StatusUpdatedEvent?.Invoke(this, new StatusUpdatedEventArgs(
|
||||||
Device.EnableDeviceVsync,
|
Device.VSyncMode.ToString(),
|
||||||
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)",
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Configuration.Hid;
|
using Ryujinx.Common.Configuration.Hid;
|
||||||
using Ryujinx.Common.Configuration.Multiplayer;
|
using Ryujinx.Common.Configuration.Multiplayer;
|
||||||
|
@ -16,7 +17,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 = 56;
|
public const int CurrentVersion = 57;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Version of the configuration file format
|
/// Version of the configuration file format
|
||||||
|
@ -191,8 +192,25 @@ namespace Ryujinx.UI.Common.Configuration
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enables or disables Vertical Sync
|
/// Enables or disables Vertical Sync
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <remarks>Kept for file format compatibility (to avoid possible failure when parsing configuration on old versions)</remarks>
|
||||||
|
/// TODO: Remove this when those older versions aren't in use anymore.
|
||||||
public bool EnableVsync { get; set; }
|
public bool EnableVsync { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Current VSync mode; 60 (Switch), unbounded ("Vsync off"), or custom
|
||||||
|
/// </summary>
|
||||||
|
public VSyncMode VSyncMode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enables or disables the custom present interval
|
||||||
|
/// </summary>
|
||||||
|
public bool EnableCustomVSyncInterval { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The custom present interval value
|
||||||
|
/// </summary>
|
||||||
|
public int CustomVSyncInterval { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enables or disables Shader cache
|
/// Enables or disables Shader cache
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -82,7 +82,7 @@ namespace Ryujinx.UI.Common.Configuration
|
||||||
|
|
||||||
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
||||||
{
|
{
|
||||||
ToggleVsync = Key.F1,
|
ToggleVSyncMode = Key.F1,
|
||||||
};
|
};
|
||||||
|
|
||||||
configurationFileUpdated = true;
|
configurationFileUpdated = true;
|
||||||
|
@ -276,7 +276,7 @@ namespace Ryujinx.UI.Common.Configuration
|
||||||
|
|
||||||
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
||||||
{
|
{
|
||||||
ToggleVsync = Key.F1,
|
ToggleVSyncMode = Key.F1,
|
||||||
Screenshot = Key.F8,
|
Screenshot = Key.F8,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -289,7 +289,7 @@ namespace Ryujinx.UI.Common.Configuration
|
||||||
|
|
||||||
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
||||||
{
|
{
|
||||||
ToggleVsync = Key.F1,
|
ToggleVSyncMode = Key.F1,
|
||||||
Screenshot = Key.F8,
|
Screenshot = Key.F8,
|
||||||
ShowUI = Key.F4,
|
ShowUI = Key.F4,
|
||||||
};
|
};
|
||||||
|
@ -332,7 +332,7 @@ namespace Ryujinx.UI.Common.Configuration
|
||||||
|
|
||||||
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
||||||
{
|
{
|
||||||
ToggleVsync = configurationFileFormat.Hotkeys.ToggleVsync,
|
ToggleVSyncMode = configurationFileFormat.Hotkeys.ToggleVSyncMode,
|
||||||
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
|
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
|
||||||
ShowUI = configurationFileFormat.Hotkeys.ShowUI,
|
ShowUI = configurationFileFormat.Hotkeys.ShowUI,
|
||||||
Pause = Key.F5,
|
Pause = Key.F5,
|
||||||
|
@ -347,7 +347,7 @@ namespace Ryujinx.UI.Common.Configuration
|
||||||
|
|
||||||
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
||||||
{
|
{
|
||||||
ToggleVsync = configurationFileFormat.Hotkeys.ToggleVsync,
|
ToggleVSyncMode = configurationFileFormat.Hotkeys.ToggleVSyncMode,
|
||||||
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
|
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
|
||||||
ShowUI = configurationFileFormat.Hotkeys.ShowUI,
|
ShowUI = configurationFileFormat.Hotkeys.ShowUI,
|
||||||
Pause = configurationFileFormat.Hotkeys.Pause,
|
Pause = configurationFileFormat.Hotkeys.Pause,
|
||||||
|
@ -421,7 +421,7 @@ namespace Ryujinx.UI.Common.Configuration
|
||||||
|
|
||||||
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
||||||
{
|
{
|
||||||
ToggleVsync = configurationFileFormat.Hotkeys.ToggleVsync,
|
ToggleVSyncMode = configurationFileFormat.Hotkeys.ToggleVSyncMode,
|
||||||
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
|
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
|
||||||
ShowUI = configurationFileFormat.Hotkeys.ShowUI,
|
ShowUI = configurationFileFormat.Hotkeys.ShowUI,
|
||||||
Pause = configurationFileFormat.Hotkeys.Pause,
|
Pause = configurationFileFormat.Hotkeys.Pause,
|
||||||
|
@ -448,7 +448,7 @@ namespace Ryujinx.UI.Common.Configuration
|
||||||
|
|
||||||
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
||||||
{
|
{
|
||||||
ToggleVsync = configurationFileFormat.Hotkeys.ToggleVsync,
|
ToggleVSyncMode = configurationFileFormat.Hotkeys.ToggleVSyncMode,
|
||||||
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
|
Screenshot = configurationFileFormat.Hotkeys.Screenshot,
|
||||||
ShowUI = configurationFileFormat.Hotkeys.ShowUI,
|
ShowUI = configurationFileFormat.Hotkeys.ShowUI,
|
||||||
Pause = configurationFileFormat.Hotkeys.Pause,
|
Pause = configurationFileFormat.Hotkeys.Pause,
|
||||||
|
@ -611,6 +611,33 @@ namespace Ryujinx.UI.Common.Configuration
|
||||||
configurationFileUpdated = true;
|
configurationFileUpdated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (configurationFileFormat.Version < 57)
|
||||||
|
{
|
||||||
|
Ryujinx.Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 57.");
|
||||||
|
|
||||||
|
configurationFileFormat.VSyncMode = VSyncMode.Switch;
|
||||||
|
configurationFileFormat.EnableCustomVSyncInterval = false;
|
||||||
|
|
||||||
|
configurationFileFormat.Hotkeys = new KeyboardHotkeys
|
||||||
|
{
|
||||||
|
ToggleVSyncMode = Key.F1,
|
||||||
|
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,
|
||||||
|
CustomVSyncIntervalIncrement = Key.Unbound,
|
||||||
|
CustomVSyncIntervalDecrement = Key.Unbound,
|
||||||
|
};
|
||||||
|
|
||||||
|
configurationFileFormat.CustomVSyncInterval = 120;
|
||||||
|
|
||||||
|
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;
|
||||||
|
@ -646,7 +673,9 @@ namespace Ryujinx.UI.Common.Configuration
|
||||||
ShowTitleBar.Value = configurationFileFormat.ShowTitleBar;
|
ShowTitleBar.Value = configurationFileFormat.ShowTitleBar;
|
||||||
EnableHardwareAcceleration.Value = configurationFileFormat.EnableHardwareAcceleration;
|
EnableHardwareAcceleration.Value = configurationFileFormat.EnableHardwareAcceleration;
|
||||||
HideCursor.Value = configurationFileFormat.HideCursor;
|
HideCursor.Value = configurationFileFormat.HideCursor;
|
||||||
Graphics.EnableVsync.Value = configurationFileFormat.EnableVsync;
|
Graphics.VSyncMode.Value = configurationFileFormat.VSyncMode;
|
||||||
|
Graphics.EnableCustomVSyncInterval.Value = configurationFileFormat.EnableCustomVSyncInterval;
|
||||||
|
Graphics.CustomVSyncInterval.Value = configurationFileFormat.CustomVSyncInterval;
|
||||||
Graphics.EnableShaderCache.Value = configurationFileFormat.EnableShaderCache;
|
Graphics.EnableShaderCache.Value = configurationFileFormat.EnableShaderCache;
|
||||||
Graphics.EnableTextureRecompression.Value = configurationFileFormat.EnableTextureRecompression;
|
Graphics.EnableTextureRecompression.Value = configurationFileFormat.EnableTextureRecompression;
|
||||||
Graphics.EnableMacroHLE.Value = configurationFileFormat.EnableMacroHLE;
|
Graphics.EnableMacroHLE.Value = configurationFileFormat.EnableMacroHLE;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using ARMeilleure;
|
using ARMeilleure;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Configuration.Hid;
|
using Ryujinx.Common.Configuration.Hid;
|
||||||
|
@ -474,9 +474,19 @@ namespace Ryujinx.UI.Common.Configuration
|
||||||
public ReactiveObject<string> ShadersDumpPath { get; private set; }
|
public ReactiveObject<string> ShadersDumpPath { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enables or disables Vertical Sync
|
/// Toggles the present interval mode. Options are Switch (60Hz), Unbounded (previously Vsync off), and Custom, if enabled.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReactiveObject<bool> EnableVsync { get; private set; }
|
public ReactiveObject<VSyncMode> VSyncMode { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enables or disables the custom present interval mode.
|
||||||
|
/// </summary>
|
||||||
|
public ReactiveObject<bool> EnableCustomVSyncInterval { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Changes the custom present interval.
|
||||||
|
/// </summary>
|
||||||
|
public ReactiveObject<int> CustomVSyncInterval { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enables or disables Shader cache
|
/// Enables or disables Shader cache
|
||||||
|
@ -536,8 +546,12 @@ namespace Ryujinx.UI.Common.Configuration
|
||||||
AspectRatio = new ReactiveObject<AspectRatio>();
|
AspectRatio = new ReactiveObject<AspectRatio>();
|
||||||
AspectRatio.LogChangesToValue(nameof(AspectRatio));
|
AspectRatio.LogChangesToValue(nameof(AspectRatio));
|
||||||
ShadersDumpPath = new ReactiveObject<string>();
|
ShadersDumpPath = new ReactiveObject<string>();
|
||||||
EnableVsync = new ReactiveObject<bool>();
|
VSyncMode = new ReactiveObject<VSyncMode>();
|
||||||
EnableVsync.LogChangesToValue(nameof(EnableVsync));
|
VSyncMode.LogChangesToValue(nameof(VSyncMode));
|
||||||
|
EnableCustomVSyncInterval = new ReactiveObject<bool>();
|
||||||
|
EnableCustomVSyncInterval.LogChangesToValue(nameof(EnableCustomVSyncInterval));
|
||||||
|
CustomVSyncInterval = new ReactiveObject<int>();
|
||||||
|
CustomVSyncInterval.LogChangesToValue(nameof(CustomVSyncInterval));
|
||||||
EnableShaderCache = new ReactiveObject<bool>();
|
EnableShaderCache = new ReactiveObject<bool>();
|
||||||
EnableShaderCache.LogChangesToValue(nameof(EnableShaderCache));
|
EnableShaderCache.LogChangesToValue(nameof(EnableShaderCache));
|
||||||
EnableTextureRecompression = new ReactiveObject<bool>();
|
EnableTextureRecompression = new ReactiveObject<bool>();
|
||||||
|
|
|
@ -64,7 +64,9 @@ namespace Ryujinx.UI.Common.Configuration
|
||||||
ShowTitleBar = ShowTitleBar,
|
ShowTitleBar = ShowTitleBar,
|
||||||
EnableHardwareAcceleration = EnableHardwareAcceleration,
|
EnableHardwareAcceleration = EnableHardwareAcceleration,
|
||||||
HideCursor = HideCursor,
|
HideCursor = HideCursor,
|
||||||
EnableVsync = Graphics.EnableVsync,
|
VSyncMode = Graphics.VSyncMode,
|
||||||
|
EnableCustomVSyncInterval = Graphics.EnableCustomVSyncInterval,
|
||||||
|
CustomVSyncInterval = Graphics.CustomVSyncInterval,
|
||||||
EnableShaderCache = Graphics.EnableShaderCache,
|
EnableShaderCache = Graphics.EnableShaderCache,
|
||||||
EnableTextureRecompression = Graphics.EnableTextureRecompression,
|
EnableTextureRecompression = Graphics.EnableTextureRecompression,
|
||||||
EnableMacroHLE = Graphics.EnableMacroHLE,
|
EnableMacroHLE = Graphics.EnableMacroHLE,
|
||||||
|
@ -179,7 +181,9 @@ namespace Ryujinx.UI.Common.Configuration
|
||||||
ShowTitleBar.Value = !OperatingSystem.IsWindows();
|
ShowTitleBar.Value = !OperatingSystem.IsWindows();
|
||||||
EnableHardwareAcceleration.Value = true;
|
EnableHardwareAcceleration.Value = true;
|
||||||
HideCursor.Value = HideCursorMode.OnIdle;
|
HideCursor.Value = HideCursorMode.OnIdle;
|
||||||
Graphics.EnableVsync.Value = true;
|
Graphics.VSyncMode.Value = VSyncMode.Switch;
|
||||||
|
Graphics.CustomVSyncInterval.Value = 120;
|
||||||
|
Graphics.EnableCustomVSyncInterval.Value = false;
|
||||||
Graphics.EnableShaderCache.Value = true;
|
Graphics.EnableShaderCache.Value = true;
|
||||||
Graphics.EnableTextureRecompression.Value = false;
|
Graphics.EnableTextureRecompression.Value = false;
|
||||||
Graphics.EnableMacroHLE.Value = true;
|
Graphics.EnableMacroHLE.Value = true;
|
||||||
|
@ -240,7 +244,7 @@ namespace Ryujinx.UI.Common.Configuration
|
||||||
Hid.EnableMouse.Value = false;
|
Hid.EnableMouse.Value = false;
|
||||||
Hid.Hotkeys.Value = new KeyboardHotkeys
|
Hid.Hotkeys.Value = new KeyboardHotkeys
|
||||||
{
|
{
|
||||||
ToggleVsync = Key.F1,
|
ToggleVSyncMode = Key.F1,
|
||||||
ToggleMute = Key.F2,
|
ToggleMute = Key.F2,
|
||||||
Screenshot = Key.F8,
|
Screenshot = Key.F8,
|
||||||
ShowUI = Key.F4,
|
ShowUI = Key.F4,
|
||||||
|
|
|
@ -57,6 +57,8 @@ using Key = Ryujinx.Input.Key;
|
||||||
using MouseButton = Ryujinx.Input.MouseButton;
|
using MouseButton = Ryujinx.Input.MouseButton;
|
||||||
using ScalingFilter = Ryujinx.Common.Configuration.ScalingFilter;
|
using ScalingFilter = Ryujinx.Common.Configuration.ScalingFilter;
|
||||||
using Size = Avalonia.Size;
|
using Size = Avalonia.Size;
|
||||||
|
using Switch = Ryujinx.HLE.Switch;
|
||||||
|
using VSyncMode = Ryujinx.Common.Configuration.VSyncMode;
|
||||||
|
|
||||||
namespace Ryujinx.Ava
|
namespace Ryujinx.Ava
|
||||||
{
|
{
|
||||||
|
@ -203,6 +205,9 @@ namespace Ryujinx.Ava
|
||||||
ConfigurationState.Instance.Graphics.ScalingFilter.Event += UpdateScalingFilter;
|
ConfigurationState.Instance.Graphics.ScalingFilter.Event += UpdateScalingFilter;
|
||||||
ConfigurationState.Instance.Graphics.ScalingFilterLevel.Event += UpdateScalingFilterLevel;
|
ConfigurationState.Instance.Graphics.ScalingFilterLevel.Event += UpdateScalingFilterLevel;
|
||||||
ConfigurationState.Instance.Graphics.EnableColorSpacePassthrough.Event += UpdateColorSpacePassthrough;
|
ConfigurationState.Instance.Graphics.EnableColorSpacePassthrough.Event += UpdateColorSpacePassthrough;
|
||||||
|
ConfigurationState.Instance.Graphics.VSyncMode.Event += UpdateVSyncMode;
|
||||||
|
ConfigurationState.Instance.Graphics.CustomVSyncInterval.Event += UpdateCustomVSyncIntervalValue;
|
||||||
|
ConfigurationState.Instance.Graphics.EnableCustomVSyncInterval.Event += UpdateCustomVSyncIntervalEnabled;
|
||||||
|
|
||||||
ConfigurationState.Instance.System.EnableInternetAccess.Event += UpdateEnableInternetAccessState;
|
ConfigurationState.Instance.System.EnableInternetAccess.Event += UpdateEnableInternetAccessState;
|
||||||
ConfigurationState.Instance.Multiplayer.LanInterfaceId.Event += UpdateLanInterfaceIdState;
|
ConfigurationState.Instance.Multiplayer.LanInterfaceId.Event += UpdateLanInterfaceIdState;
|
||||||
|
@ -295,6 +300,66 @@ namespace Ryujinx.Ava
|
||||||
_renderer.Window?.SetColorSpacePassthrough((bool)ConfigurationState.Instance.Graphics.EnableColorSpacePassthrough.Value);
|
_renderer.Window?.SetColorSpacePassthrough((bool)ConfigurationState.Instance.Graphics.EnableColorSpacePassthrough.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void UpdateVSyncMode(object sender, ReactiveEventArgs<VSyncMode> e)
|
||||||
|
{
|
||||||
|
if (Device != null)
|
||||||
|
{
|
||||||
|
Device.VSyncMode = e.NewValue;
|
||||||
|
Device.UpdateVSyncInterval();
|
||||||
|
}
|
||||||
|
_renderer.Window?.ChangeVSyncMode((Ryujinx.Graphics.GAL.VSyncMode)e.NewValue);
|
||||||
|
|
||||||
|
_viewModel.ShowCustomVSyncIntervalPicker = (e.NewValue == VSyncMode.Custom);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void VSyncModeToggle()
|
||||||
|
{
|
||||||
|
VSyncMode oldVSyncMode = Device.VSyncMode;
|
||||||
|
VSyncMode newVSyncMode = VSyncMode.Switch;
|
||||||
|
bool customVSyncIntervalEnabled = ConfigurationState.Instance.Graphics.EnableCustomVSyncInterval.Value;
|
||||||
|
|
||||||
|
switch (oldVSyncMode)
|
||||||
|
{
|
||||||
|
case VSyncMode.Switch:
|
||||||
|
newVSyncMode = VSyncMode.Unbounded;
|
||||||
|
break;
|
||||||
|
case VSyncMode.Unbounded:
|
||||||
|
if (customVSyncIntervalEnabled)
|
||||||
|
{
|
||||||
|
newVSyncMode = VSyncMode.Custom;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newVSyncMode = VSyncMode.Switch;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case VSyncMode.Custom:
|
||||||
|
newVSyncMode = VSyncMode.Switch;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateVSyncMode(this, new ReactiveEventArgs<VSyncMode>(oldVSyncMode, newVSyncMode));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateCustomVSyncIntervalValue(object sender, ReactiveEventArgs<int> e)
|
||||||
|
{
|
||||||
|
if (Device != null)
|
||||||
|
{
|
||||||
|
Device.TargetVSyncInterval = e.NewValue;
|
||||||
|
Device.UpdateVSyncInterval();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateCustomVSyncIntervalEnabled(object sender, ReactiveEventArgs<bool> e)
|
||||||
|
{
|
||||||
|
if (Device != null)
|
||||||
|
{
|
||||||
|
Device.CustomVSyncIntervalEnabled = e.NewValue;
|
||||||
|
Device.UpdateVSyncInterval();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void ShowCursor()
|
private void ShowCursor()
|
||||||
{
|
{
|
||||||
Dispatcher.UIThread.Post(() =>
|
Dispatcher.UIThread.Post(() =>
|
||||||
|
@ -505,12 +570,6 @@ namespace Ryujinx.Ava
|
||||||
Device.Configuration.MultiplayerDisableP2p = e.NewValue;
|
Device.Configuration.MultiplayerDisableP2p = e.NewValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ToggleVSync()
|
|
||||||
{
|
|
||||||
Device.EnableDeviceVsync = !Device.EnableDeviceVsync;
|
|
||||||
_renderer.Window.ChangeVSyncMode(Device.EnableDeviceVsync);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Stop()
|
public void Stop()
|
||||||
{
|
{
|
||||||
_isActive = false;
|
_isActive = false;
|
||||||
|
@ -864,7 +923,7 @@ namespace Ryujinx.Ava
|
||||||
_viewModel.UiHandler,
|
_viewModel.UiHandler,
|
||||||
(SystemLanguage)ConfigurationState.Instance.System.Language.Value,
|
(SystemLanguage)ConfigurationState.Instance.System.Language.Value,
|
||||||
(RegionCode)ConfigurationState.Instance.System.Region.Value,
|
(RegionCode)ConfigurationState.Instance.System.Region.Value,
|
||||||
ConfigurationState.Instance.Graphics.EnableVsync,
|
ConfigurationState.Instance.Graphics.VSyncMode,
|
||||||
ConfigurationState.Instance.System.EnableDockedMode,
|
ConfigurationState.Instance.System.EnableDockedMode,
|
||||||
ConfigurationState.Instance.System.EnablePtc,
|
ConfigurationState.Instance.System.EnablePtc,
|
||||||
ConfigurationState.Instance.System.EnableInternetAccess,
|
ConfigurationState.Instance.System.EnableInternetAccess,
|
||||||
|
@ -881,7 +940,8 @@ namespace Ryujinx.Ava
|
||||||
ConfigurationState.Instance.Multiplayer.Mode,
|
ConfigurationState.Instance.Multiplayer.Mode,
|
||||||
ConfigurationState.Instance.Multiplayer.DisableP2p,
|
ConfigurationState.Instance.Multiplayer.DisableP2p,
|
||||||
ConfigurationState.Instance.Multiplayer.LdnPassphrase,
|
ConfigurationState.Instance.Multiplayer.LdnPassphrase,
|
||||||
ConfigurationState.Instance.Multiplayer.LdnServer));
|
ConfigurationState.Instance.Multiplayer.LdnServer,
|
||||||
|
ConfigurationState.Instance.Graphics.CustomVSyncInterval.Value));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IHardwareDeviceDriver InitializeAudio()
|
private static IHardwareDeviceDriver InitializeAudio()
|
||||||
|
@ -1002,7 +1062,7 @@ namespace Ryujinx.Ava
|
||||||
Device.Gpu.SetGpuThread();
|
Device.Gpu.SetGpuThread();
|
||||||
Device.Gpu.InitializeShaderCache(_gpuCancellationTokenSource.Token);
|
Device.Gpu.InitializeShaderCache(_gpuCancellationTokenSource.Token);
|
||||||
|
|
||||||
_renderer.Window.ChangeVSyncMode(Device.EnableDeviceVsync);
|
_renderer.Window.ChangeVSyncMode((Ryujinx.Graphics.GAL.VSyncMode)Device.VSyncMode);
|
||||||
|
|
||||||
while (_isActive)
|
while (_isActive)
|
||||||
{
|
{
|
||||||
|
@ -1063,6 +1123,7 @@ namespace Ryujinx.Ava
|
||||||
{
|
{
|
||||||
// Run a status update only when a frame is to be drawn. This prevents from updating the ui and wasting a render when no frame is queued.
|
// Run a status update only when a frame is to be drawn. This prevents from updating the ui and wasting a render when no frame is queued.
|
||||||
string dockedMode = ConfigurationState.Instance.System.EnableDockedMode ? LocaleManager.Instance[LocaleKeys.Docked] : LocaleManager.Instance[LocaleKeys.Handheld];
|
string dockedMode = ConfigurationState.Instance.System.EnableDockedMode ? LocaleManager.Instance[LocaleKeys.Docked] : LocaleManager.Instance[LocaleKeys.Handheld];
|
||||||
|
string vSyncMode = Device.VSyncMode.ToString();
|
||||||
|
|
||||||
UpdateShaderCount();
|
UpdateShaderCount();
|
||||||
|
|
||||||
|
@ -1072,7 +1133,7 @@ namespace Ryujinx.Ava
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusUpdatedEvent?.Invoke(this, new StatusUpdatedEventArgs(
|
StatusUpdatedEvent?.Invoke(this, new StatusUpdatedEventArgs(
|
||||||
Device.EnableDeviceVsync,
|
vSyncMode,
|
||||||
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(),
|
||||||
|
@ -1175,8 +1236,16 @@ namespace Ryujinx.Ava
|
||||||
{
|
{
|
||||||
switch (currentHotkeyState)
|
switch (currentHotkeyState)
|
||||||
{
|
{
|
||||||
case KeyboardHotkeyState.ToggleVSync:
|
case KeyboardHotkeyState.ToggleVSyncMode:
|
||||||
ToggleVSync();
|
VSyncModeToggle();
|
||||||
|
break;
|
||||||
|
case KeyboardHotkeyState.CustomVSyncIntervalDecrement:
|
||||||
|
Device.DecrementCustomVSyncInterval();
|
||||||
|
_viewModel.CustomVSyncInterval -= 1;
|
||||||
|
break;
|
||||||
|
case KeyboardHotkeyState.CustomVSyncIntervalIncrement:
|
||||||
|
Device.IncrementCustomVSyncInterval();
|
||||||
|
_viewModel.CustomVSyncInterval += 1;
|
||||||
break;
|
break;
|
||||||
case KeyboardHotkeyState.Screenshot:
|
case KeyboardHotkeyState.Screenshot:
|
||||||
ScreenshotRequested = true;
|
ScreenshotRequested = true;
|
||||||
|
@ -1263,9 +1332,9 @@ namespace Ryujinx.Ava
|
||||||
{
|
{
|
||||||
KeyboardHotkeyState state = KeyboardHotkeyState.None;
|
KeyboardHotkeyState state = KeyboardHotkeyState.None;
|
||||||
|
|
||||||
if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.ToggleVsync))
|
if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.ToggleVSyncMode))
|
||||||
{
|
{
|
||||||
state = KeyboardHotkeyState.ToggleVSync;
|
state = KeyboardHotkeyState.ToggleVSyncMode;
|
||||||
}
|
}
|
||||||
else if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.Screenshot))
|
else if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.Screenshot))
|
||||||
{
|
{
|
||||||
|
@ -1299,6 +1368,14 @@ namespace Ryujinx.Ava
|
||||||
{
|
{
|
||||||
state = KeyboardHotkeyState.VolumeDown;
|
state = KeyboardHotkeyState.VolumeDown;
|
||||||
}
|
}
|
||||||
|
else if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.CustomVSyncIntervalIncrement))
|
||||||
|
{
|
||||||
|
state = KeyboardHotkeyState.CustomVSyncIntervalIncrement;
|
||||||
|
}
|
||||||
|
else if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.CustomVSyncIntervalDecrement))
|
||||||
|
{
|
||||||
|
state = KeyboardHotkeyState.CustomVSyncIntervalDecrement;
|
||||||
|
}
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,9 +142,20 @@
|
||||||
"SettingsTabSystemSystemLanguageLatinAmericanSpanish": "Latin American Spanish",
|
"SettingsTabSystemSystemLanguageLatinAmericanSpanish": "Latin American Spanish",
|
||||||
"SettingsTabSystemSystemLanguageSimplifiedChinese": "Simplified Chinese",
|
"SettingsTabSystemSystemLanguageSimplifiedChinese": "Simplified Chinese",
|
||||||
"SettingsTabSystemSystemLanguageTraditionalChinese": "Traditional Chinese",
|
"SettingsTabSystemSystemLanguageTraditionalChinese": "Traditional Chinese",
|
||||||
"SettingsTabSystemSystemTimeZone": "System TimeZone:",
|
"SettingsTabSystemSystemTimeZone": "System Time Zone:",
|
||||||
"SettingsTabSystemSystemTime": "System Time:",
|
"SettingsTabSystemSystemTime": "System Time:",
|
||||||
"SettingsTabSystemEnableVsync": "VSync",
|
"SettingsTabSystemVSyncMode": "VSync:",
|
||||||
|
"SettingsTabSystemEnableCustomVSyncInterval": "Enable custom refresh rate (Experimental)",
|
||||||
|
"SettingsTabSystemVSyncModeSwitch": "Switch",
|
||||||
|
"SettingsTabSystemVSyncModeUnbounded": "Unbounded",
|
||||||
|
"SettingsTabSystemVSyncModeCustom": "Custom Refresh Rate",
|
||||||
|
"SettingsTabSystemVSyncModeTooltip": "Emulated Vertical Sync. 'Switch' emulates the Switch's refresh rate of 60Hz. 'Unbounded' is an unbounded refresh rate.",
|
||||||
|
"SettingsTabSystemVSyncModeTooltipCustom": "Emulated Vertical Sync. 'Switch' emulates the Switch's refresh rate of 60Hz. 'Unbounded' is an unbounded refresh rate. 'Custom' emulates the specified custom refresh rate.",
|
||||||
|
"SettingsTabSystemEnableCustomVSyncIntervalTooltip": "Allows the user to specify an emulated refresh rate. In some titles, this may speed up or slow down the rate of gameplay logic. In other titles, it may allow for capping FPS at some multiple of the refresh rate, or lead to unpredictable behavior. This is an experimental feature, with no guarantees for how gameplay will be affected. \n\nLeave OFF if unsure.",
|
||||||
|
"SettingsTabSystemCustomVSyncIntervalValueTooltip": "The custom refresh rate target value.",
|
||||||
|
"SettingsTabSystemCustomVSyncIntervalSliderTooltip": "The custom refresh rate, as a percentage of the normal Switch refresh rate.",
|
||||||
|
"SettingsTabSystemCustomVSyncIntervalPercentage": "Custom Refresh Rate %:",
|
||||||
|
"SettingsTabSystemCustomVSyncIntervalValue": "Custom Refresh Rate Value:",
|
||||||
"SettingsTabSystemEnablePptc": "PPTC (Profiled Persistent Translation Cache)",
|
"SettingsTabSystemEnablePptc": "PPTC (Profiled Persistent Translation Cache)",
|
||||||
"SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC cache",
|
"SettingsTabSystemEnableLowPowerPptc": "Low-power PPTC cache",
|
||||||
"SettingsTabSystemEnableFsIntegrityChecks": "FS Integrity Checks",
|
"SettingsTabSystemEnableFsIntegrityChecks": "FS Integrity Checks",
|
||||||
|
@ -153,6 +164,7 @@
|
||||||
"SettingsTabSystemAudioBackendOpenAL": "OpenAL",
|
"SettingsTabSystemAudioBackendOpenAL": "OpenAL",
|
||||||
"SettingsTabSystemAudioBackendSoundIO": "SoundIO",
|
"SettingsTabSystemAudioBackendSoundIO": "SoundIO",
|
||||||
"SettingsTabSystemAudioBackendSDL2": "SDL2",
|
"SettingsTabSystemAudioBackendSDL2": "SDL2",
|
||||||
|
"SettingsTabSystemCustomVSyncInterval": "Interval",
|
||||||
"SettingsTabSystemHacks": "Hacks",
|
"SettingsTabSystemHacks": "Hacks",
|
||||||
"SettingsTabSystemHacksNote": "May cause instability",
|
"SettingsTabSystemHacksNote": "May cause instability",
|
||||||
"SettingsTabSystemDramSize": "DRAM size:",
|
"SettingsTabSystemDramSize": "DRAM size:",
|
||||||
|
@ -720,11 +732,13 @@
|
||||||
"RyujinxUpdater": "Ryujinx Updater",
|
"RyujinxUpdater": "Ryujinx Updater",
|
||||||
"SettingsTabHotkeys": "Keyboard Hotkeys",
|
"SettingsTabHotkeys": "Keyboard Hotkeys",
|
||||||
"SettingsTabHotkeysHotkeys": "Keyboard Hotkeys",
|
"SettingsTabHotkeysHotkeys": "Keyboard Hotkeys",
|
||||||
"SettingsTabHotkeysToggleVsyncHotkey": "Toggle VSync:",
|
"SettingsTabHotkeysToggleVSyncModeHotkey": "Toggle VSync mode:",
|
||||||
"SettingsTabHotkeysScreenshotHotkey": "Screenshot:",
|
"SettingsTabHotkeysScreenshotHotkey": "Screenshot:",
|
||||||
"SettingsTabHotkeysShowUiHotkey": "Show UI:",
|
"SettingsTabHotkeysShowUiHotkey": "Show UI:",
|
||||||
"SettingsTabHotkeysPauseHotkey": "Pause:",
|
"SettingsTabHotkeysPauseHotkey": "Pause:",
|
||||||
"SettingsTabHotkeysToggleMuteHotkey": "Mute:",
|
"SettingsTabHotkeysToggleMuteHotkey": "Mute:",
|
||||||
|
"SettingsTabHotkeysIncrementCustomVSyncIntervalHotkey": "Raise custom refresh rate",
|
||||||
|
"SettingsTabHotkeysDecrementCustomVSyncIntervalHotkey": "Lower custom refresh rate",
|
||||||
"ControllerMotionTitle": "Motion Control Settings",
|
"ControllerMotionTitle": "Motion Control Settings",
|
||||||
"ControllerRumbleTitle": "Rumble Settings",
|
"ControllerRumbleTitle": "Rumble Settings",
|
||||||
"SettingsSelectThemeFileDialogTitle": "Select Theme File",
|
"SettingsSelectThemeFileDialogTitle": "Select Theme File",
|
||||||
|
|
|
@ -26,8 +26,9 @@
|
||||||
<Color x:Key="AppListBackgroundColor">#b3ffffff</Color>
|
<Color x:Key="AppListBackgroundColor">#b3ffffff</Color>
|
||||||
<Color x:Key="AppListHoverBackgroundColor">#80cccccc</Color>
|
<Color x:Key="AppListHoverBackgroundColor">#80cccccc</Color>
|
||||||
<Color x:Key="SecondaryTextColor">#A0000000</Color>
|
<Color x:Key="SecondaryTextColor">#A0000000</Color>
|
||||||
<Color x:Key="VsyncEnabled">#FF2EEAC9</Color>
|
<Color x:Key="Switch">#FF2EEAC9</Color>
|
||||||
<Color x:Key="VsyncDisabled">#FFFF4554</Color>
|
<Color x:Key="Unbounded">#FFFF4554</Color>
|
||||||
|
<Color x:Key="Custom">#6483F5</Color>
|
||||||
</ResourceDictionary>
|
</ResourceDictionary>
|
||||||
<ResourceDictionary x:Key="Light">
|
<ResourceDictionary x:Key="Light">
|
||||||
<SolidColorBrush x:Key="DataGridSelectionBackgroundBrush"
|
<SolidColorBrush x:Key="DataGridSelectionBackgroundBrush"
|
||||||
|
|
|
@ -3,7 +3,7 @@ namespace Ryujinx.Ava.Common
|
||||||
public enum KeyboardHotkeyState
|
public enum KeyboardHotkeyState
|
||||||
{
|
{
|
||||||
None,
|
None,
|
||||||
ToggleVSync,
|
ToggleVSyncMode,
|
||||||
Screenshot,
|
Screenshot,
|
||||||
ShowUI,
|
ShowUI,
|
||||||
Pause,
|
Pause,
|
||||||
|
@ -12,5 +12,7 @@ namespace Ryujinx.Ava.Common
|
||||||
ResScaleDown,
|
ResScaleDown,
|
||||||
VolumeUp,
|
VolumeUp,
|
||||||
VolumeDown,
|
VolumeDown,
|
||||||
|
CustomVSyncIntervalIncrement,
|
||||||
|
CustomVSyncIntervalDecrement,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,13 +5,13 @@ namespace Ryujinx.Ava.UI.Models.Input
|
||||||
{
|
{
|
||||||
public class HotkeyConfig : BaseModel
|
public class HotkeyConfig : BaseModel
|
||||||
{
|
{
|
||||||
private Key _toggleVsync;
|
private Key _toggleVSyncMode;
|
||||||
public Key ToggleVsync
|
public Key ToggleVSyncMode
|
||||||
{
|
{
|
||||||
get => _toggleVsync;
|
get => _toggleVSyncMode;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_toggleVsync = value;
|
_toggleVSyncMode = value;
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,11 +104,33 @@ namespace Ryujinx.Ava.UI.Models.Input
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Key _customVSyncIntervalIncrement;
|
||||||
|
public Key CustomVSyncIntervalIncrement
|
||||||
|
{
|
||||||
|
get => _customVSyncIntervalIncrement;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_customVSyncIntervalIncrement = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Key _customVSyncIntervalDecrement;
|
||||||
|
public Key CustomVSyncIntervalDecrement
|
||||||
|
{
|
||||||
|
get => _customVSyncIntervalDecrement;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_customVSyncIntervalDecrement = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public HotkeyConfig(KeyboardHotkeys config)
|
public HotkeyConfig(KeyboardHotkeys config)
|
||||||
{
|
{
|
||||||
if (config != null)
|
if (config != null)
|
||||||
{
|
{
|
||||||
ToggleVsync = config.ToggleVsync;
|
ToggleVSyncMode = config.ToggleVSyncMode;
|
||||||
Screenshot = config.Screenshot;
|
Screenshot = config.Screenshot;
|
||||||
ShowUI = config.ShowUI;
|
ShowUI = config.ShowUI;
|
||||||
Pause = config.Pause;
|
Pause = config.Pause;
|
||||||
|
@ -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;
|
||||||
|
CustomVSyncIntervalIncrement = config.CustomVSyncIntervalIncrement;
|
||||||
|
CustomVSyncIntervalDecrement = config.CustomVSyncIntervalDecrement;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +148,7 @@ namespace Ryujinx.Ava.UI.Models.Input
|
||||||
{
|
{
|
||||||
var config = new KeyboardHotkeys
|
var config = new KeyboardHotkeys
|
||||||
{
|
{
|
||||||
ToggleVsync = ToggleVsync,
|
ToggleVSyncMode = ToggleVSyncMode,
|
||||||
Screenshot = Screenshot,
|
Screenshot = Screenshot,
|
||||||
ShowUI = ShowUI,
|
ShowUI = ShowUI,
|
||||||
Pause = Pause,
|
Pause = Pause,
|
||||||
|
@ -133,6 +157,8 @@ namespace Ryujinx.Ava.UI.Models.Input
|
||||||
ResScaleDown = ResScaleDown,
|
ResScaleDown = ResScaleDown,
|
||||||
VolumeUp = VolumeUp,
|
VolumeUp = VolumeUp,
|
||||||
VolumeDown = VolumeDown,
|
VolumeDown = VolumeDown,
|
||||||
|
CustomVSyncIntervalIncrement = CustomVSyncIntervalIncrement,
|
||||||
|
CustomVSyncIntervalDecrement = CustomVSyncIntervalDecrement,
|
||||||
};
|
};
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
|
|
|
@ -47,7 +47,7 @@ namespace Ryujinx.Ava.UI.Models
|
||||||
TitleId = info.ProgramId;
|
TitleId = info.ProgramId;
|
||||||
UserId = info.UserId;
|
UserId = info.UserId;
|
||||||
|
|
||||||
var appData = App.MainWindow.ViewModel.Applications.FirstOrDefault(x => x.IdString.Equals(TitleIdString, StringComparison.OrdinalIgnoreCase));
|
var appData = MainWindow.MainWindowViewModel.Applications.FirstOrDefault(x => x.IdString.Equals(TitleIdString, StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
InGameList = appData != null;
|
InGameList = appData != null;
|
||||||
|
|
||||||
|
|
|
@ -4,18 +4,17 @@ namespace Ryujinx.Ava.UI.Models
|
||||||
{
|
{
|
||||||
internal class StatusUpdatedEventArgs : EventArgs
|
internal class StatusUpdatedEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
public bool VSyncEnabled { get; }
|
public string VSyncMode { get; }
|
||||||
public string VolumeStatus { get; }
|
public string VolumeStatus { get; }
|
||||||
public string AspectRatio { get; }
|
public string AspectRatio { get; }
|
||||||
public string DockedMode { get; }
|
public string DockedMode { get; }
|
||||||
public string FifoStatus { get; }
|
public string FifoStatus { get; }
|
||||||
public string GameStatus { get; }
|
public string GameStatus { get; }
|
||||||
|
|
||||||
public uint ShaderCount { get; }
|
public uint ShaderCount { get; }
|
||||||
|
|
||||||
public StatusUpdatedEventArgs(bool vSyncEnabled, string volumeStatus, string dockedMode, string aspectRatio, string gameStatus, string fifoStatus, uint shaderCount)
|
public StatusUpdatedEventArgs(string vSyncMode, string volumeStatus, string dockedMode, string aspectRatio, string gameStatus, string fifoStatus, uint shaderCount)
|
||||||
{
|
{
|
||||||
VSyncEnabled = vSyncEnabled;
|
VSyncMode = vSyncMode;
|
||||||
VolumeStatus = volumeStatus;
|
VolumeStatus = volumeStatus;
|
||||||
DockedMode = dockedMode;
|
DockedMode = dockedMode;
|
||||||
AspectRatio = aspectRatio;
|
AspectRatio = aspectRatio;
|
||||||
|
|
|
@ -63,6 +63,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
private string _searchText;
|
private string _searchText;
|
||||||
private Timer _searchTimer;
|
private Timer _searchTimer;
|
||||||
private string _dockedStatusText;
|
private string _dockedStatusText;
|
||||||
|
private string _vSyncModeText;
|
||||||
private string _fifoStatusText;
|
private string _fifoStatusText;
|
||||||
private string _gameStatusText;
|
private string _gameStatusText;
|
||||||
private string _volumeStatusText;
|
private string _volumeStatusText;
|
||||||
|
@ -80,7 +81,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
private bool _showStatusSeparator;
|
private bool _showStatusSeparator;
|
||||||
private Brush _progressBarForegroundColor;
|
private Brush _progressBarForegroundColor;
|
||||||
private Brush _progressBarBackgroundColor;
|
private Brush _progressBarBackgroundColor;
|
||||||
private Brush _vsyncColor;
|
private Brush _vSyncModeColor;
|
||||||
private byte[] _selectedIcon;
|
private byte[] _selectedIcon;
|
||||||
private bool _isAppletMenuActive;
|
private bool _isAppletMenuActive;
|
||||||
private int _statusBarProgressMaximum;
|
private int _statusBarProgressMaximum;
|
||||||
|
@ -111,6 +112,8 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
private WindowState _windowState;
|
private WindowState _windowState;
|
||||||
private double _windowWidth;
|
private double _windowWidth;
|
||||||
private double _windowHeight;
|
private double _windowHeight;
|
||||||
|
private int _customVSyncInterval;
|
||||||
|
private int _customVSyncIntervalPercentageProxy;
|
||||||
|
|
||||||
private bool _isActive;
|
private bool _isActive;
|
||||||
private bool _isSubMenuOpen;
|
private bool _isSubMenuOpen;
|
||||||
|
@ -145,6 +148,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
|
|
||||||
Volume = ConfigurationState.Instance.System.AudioVolume;
|
Volume = ConfigurationState.Instance.System.AudioVolume;
|
||||||
}
|
}
|
||||||
|
CustomVSyncInterval = ConfigurationState.Instance.Graphics.CustomVSyncInterval.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Initialize(
|
public void Initialize(
|
||||||
|
@ -447,17 +451,87 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Brush VsyncColor
|
public Brush VSyncModeColor
|
||||||
{
|
{
|
||||||
get => _vsyncColor;
|
get => _vSyncModeColor;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_vsyncColor = value;
|
_vSyncModeColor = value;
|
||||||
|
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool ShowCustomVSyncIntervalPicker
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_isGameRunning)
|
||||||
|
{
|
||||||
|
return AppHost.Device.VSyncMode ==
|
||||||
|
VSyncMode.Custom;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int CustomVSyncIntervalPercentageProxy
|
||||||
|
{
|
||||||
|
get => _customVSyncIntervalPercentageProxy;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
int newInterval = (int)((value / 100f) * 60);
|
||||||
|
_customVSyncInterval = newInterval;
|
||||||
|
_customVSyncIntervalPercentageProxy = value;
|
||||||
|
if (_isGameRunning)
|
||||||
|
{
|
||||||
|
AppHost.Device.CustomVSyncInterval = newInterval;
|
||||||
|
AppHost.Device.UpdateVSyncInterval();
|
||||||
|
}
|
||||||
|
OnPropertyChanged((nameof(CustomVSyncInterval)));
|
||||||
|
OnPropertyChanged((nameof(CustomVSyncIntervalPercentageText)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string CustomVSyncIntervalPercentageText
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
string text = CustomVSyncIntervalPercentageProxy.ToString() + "%";
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int CustomVSyncInterval
|
||||||
|
{
|
||||||
|
get => _customVSyncInterval;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_customVSyncInterval = value;
|
||||||
|
int newPercent = (int)((value / 60f) * 100);
|
||||||
|
_customVSyncIntervalPercentageProxy = newPercent;
|
||||||
|
if (_isGameRunning)
|
||||||
|
{
|
||||||
|
AppHost.Device.CustomVSyncInterval = value;
|
||||||
|
AppHost.Device.UpdateVSyncInterval();
|
||||||
|
}
|
||||||
|
OnPropertyChanged(nameof(CustomVSyncIntervalPercentageProxy));
|
||||||
|
OnPropertyChanged(nameof(CustomVSyncIntervalPercentageText));
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public byte[] SelectedIcon
|
public byte[] SelectedIcon
|
||||||
{
|
{
|
||||||
get => _selectedIcon;
|
get => _selectedIcon;
|
||||||
|
@ -578,6 +652,17 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string VSyncModeText
|
||||||
|
{
|
||||||
|
get => _vSyncModeText;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_vSyncModeText = value;
|
||||||
|
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public string DockedStatusText
|
public string DockedStatusText
|
||||||
{
|
{
|
||||||
get => _dockedStatusText;
|
get => _dockedStatusText;
|
||||||
|
@ -1292,17 +1377,18 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
{
|
{
|
||||||
Dispatcher.UIThread.InvokeAsync(() =>
|
Dispatcher.UIThread.InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
Application.Current!.Styles.TryGetResource(args.VSyncEnabled
|
Application.Current!.Styles.TryGetResource(args.VSyncMode,
|
||||||
? "VsyncEnabled"
|
|
||||||
: "VsyncDisabled",
|
|
||||||
Application.Current.ActualThemeVariant,
|
Application.Current.ActualThemeVariant,
|
||||||
out object color);
|
out object color);
|
||||||
|
|
||||||
if (color is Color clr)
|
if (color is Color clr)
|
||||||
{
|
{
|
||||||
VsyncColor = new SolidColorBrush(clr);
|
VSyncModeColor = new SolidColorBrush(clr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VSyncModeText = args.VSyncMode == "Custom" ? "Custom" : "VSync";
|
||||||
|
ShowCustomVSyncIntervalPicker =
|
||||||
|
args.VSyncMode == VSyncMode.Custom.ToString();
|
||||||
DockedStatusText = args.DockedMode;
|
DockedStatusText = args.DockedMode;
|
||||||
AspectRatioStatusText = args.AspectRatio;
|
AspectRatioStatusText = args.AspectRatio;
|
||||||
GameStatusText = args.GameStatus;
|
GameStatusText = args.GameStatus;
|
||||||
|
@ -1495,6 +1581,27 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ToggleVSyncMode()
|
||||||
|
{
|
||||||
|
AppHost.VSyncModeToggle();
|
||||||
|
OnPropertyChanged(nameof(ShowCustomVSyncIntervalPicker));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void VSyncModeSettingChanged()
|
||||||
|
{
|
||||||
|
if (_isGameRunning)
|
||||||
|
{
|
||||||
|
AppHost.Device.CustomVSyncInterval = ConfigurationState.Instance.Graphics.CustomVSyncInterval.Value;
|
||||||
|
AppHost.Device.UpdateVSyncInterval();
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomVSyncInterval = ConfigurationState.Instance.Graphics.CustomVSyncInterval.Value;
|
||||||
|
OnPropertyChanged(nameof(ShowCustomVSyncIntervalPicker));
|
||||||
|
OnPropertyChanged(nameof(CustomVSyncIntervalPercentageProxy));
|
||||||
|
OnPropertyChanged(nameof(CustomVSyncIntervalPercentageText));
|
||||||
|
OnPropertyChanged(nameof(CustomVSyncInterval));
|
||||||
|
}
|
||||||
|
|
||||||
public async Task ExitCurrentState()
|
public async Task ExitCurrentState()
|
||||||
{
|
{
|
||||||
if (WindowState is WindowState.FullScreen)
|
if (WindowState is WindowState.FullScreen)
|
||||||
|
|
|
@ -52,6 +52,10 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
private int _graphicsBackendIndex;
|
private int _graphicsBackendIndex;
|
||||||
private int _scalingFilter;
|
private int _scalingFilter;
|
||||||
private int _scalingFilterLevel;
|
private int _scalingFilterLevel;
|
||||||
|
private int _customVSyncInterval;
|
||||||
|
private bool _enableCustomVSyncInterval;
|
||||||
|
private int _customVSyncIntervalPercentageProxy;
|
||||||
|
private VSyncMode _vSyncMode;
|
||||||
|
|
||||||
public event Action CloseWindow;
|
public event Action CloseWindow;
|
||||||
public event Action SaveSettingsEvent;
|
public event Action SaveSettingsEvent;
|
||||||
|
@ -154,7 +158,74 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
public bool EnableDockedMode { get; set; }
|
public bool EnableDockedMode { get; set; }
|
||||||
public bool EnableKeyboard { get; set; }
|
public bool EnableKeyboard { get; set; }
|
||||||
public bool EnableMouse { get; set; }
|
public bool EnableMouse { get; set; }
|
||||||
public bool EnableVsync { get; set; }
|
public VSyncMode VSyncMode
|
||||||
|
{
|
||||||
|
get => _vSyncMode;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == VSyncMode.Custom ||
|
||||||
|
value == VSyncMode.Switch ||
|
||||||
|
value == VSyncMode.Unbounded)
|
||||||
|
{
|
||||||
|
_vSyncMode = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int CustomVSyncIntervalPercentageProxy
|
||||||
|
{
|
||||||
|
get => _customVSyncIntervalPercentageProxy;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
int newInterval = (int)((value / 100f) * 60);
|
||||||
|
_customVSyncInterval = newInterval;
|
||||||
|
_customVSyncIntervalPercentageProxy = value;
|
||||||
|
OnPropertyChanged((nameof(CustomVSyncInterval)));
|
||||||
|
OnPropertyChanged((nameof(CustomVSyncIntervalPercentageText)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string CustomVSyncIntervalPercentageText
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
string text = CustomVSyncIntervalPercentageProxy.ToString() + "%";
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool EnableCustomVSyncInterval
|
||||||
|
{
|
||||||
|
get => _enableCustomVSyncInterval;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_enableCustomVSyncInterval = value;
|
||||||
|
if (_vSyncMode == VSyncMode.Custom && !value)
|
||||||
|
{
|
||||||
|
VSyncMode = VSyncMode.Switch;
|
||||||
|
}
|
||||||
|
else if (value)
|
||||||
|
{
|
||||||
|
VSyncMode = VSyncMode.Custom;
|
||||||
|
}
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int CustomVSyncInterval
|
||||||
|
{
|
||||||
|
get => _customVSyncInterval;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_customVSyncInterval = value;
|
||||||
|
int newPercent = (int)((value / 60f) * 100);
|
||||||
|
_customVSyncIntervalPercentageProxy = newPercent;
|
||||||
|
OnPropertyChanged(nameof(CustomVSyncIntervalPercentageProxy));
|
||||||
|
OnPropertyChanged(nameof(CustomVSyncIntervalPercentageText));
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
public bool EnablePptc { get; set; }
|
public bool EnablePptc { get; set; }
|
||||||
public bool EnableLowPowerPptc { get; set; }
|
public bool EnableLowPowerPptc { get; set; }
|
||||||
public bool EnableInternetAccess { get; set; }
|
public bool EnableInternetAccess { get; set; }
|
||||||
|
@ -484,7 +555,9 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
CurrentDate = currentDateTime.Date;
|
CurrentDate = currentDateTime.Date;
|
||||||
CurrentTime = currentDateTime.TimeOfDay;
|
CurrentTime = currentDateTime.TimeOfDay;
|
||||||
|
|
||||||
EnableVsync = config.Graphics.EnableVsync;
|
EnableCustomVSyncInterval = config.Graphics.EnableCustomVSyncInterval.Value;
|
||||||
|
CustomVSyncInterval = config.Graphics.CustomVSyncInterval;
|
||||||
|
VSyncMode = config.Graphics.VSyncMode;
|
||||||
EnableFsIntegrityChecks = config.System.EnableFsIntegrityChecks;
|
EnableFsIntegrityChecks = config.System.EnableFsIntegrityChecks;
|
||||||
DramSize = config.System.DramSize;
|
DramSize = config.System.DramSize;
|
||||||
IgnoreMissingServices = config.System.IgnoreMissingServices;
|
IgnoreMissingServices = config.System.IgnoreMissingServices;
|
||||||
|
@ -590,7 +663,9 @@ 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.Graphics.EnableVsync.Value = EnableVsync;
|
config.Graphics.VSyncMode.Value = VSyncMode;
|
||||||
|
config.Graphics.EnableCustomVSyncInterval.Value = EnableCustomVSyncInterval;
|
||||||
|
config.Graphics.CustomVSyncInterval.Value = CustomVSyncInterval;
|
||||||
config.System.EnableFsIntegrityChecks.Value = EnableFsIntegrityChecks;
|
config.System.EnableFsIntegrityChecks.Value = EnableFsIntegrityChecks;
|
||||||
config.System.DramSize.Value = DramSize;
|
config.System.DramSize.Value = DramSize;
|
||||||
config.System.IgnoreMissingServices.Value = IgnoreMissingServices;
|
config.System.IgnoreMissingServices.Value = IgnoreMissingServices;
|
||||||
|
@ -660,6 +735,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
config.ToFileFormat().SaveConfig(Program.ConfigurationPath);
|
config.ToFileFormat().SaveConfig(Program.ConfigurationPath);
|
||||||
|
|
||||||
MainWindow.UpdateGraphicsConfig();
|
MainWindow.UpdateGraphicsConfig();
|
||||||
|
MainWindow.MainWindowViewModel.VSyncModeSettingChanged();
|
||||||
|
|
||||||
SaveSettingsEvent?.Invoke();
|
SaveSettingsEvent?.Invoke();
|
||||||
|
|
||||||
|
|
|
@ -79,15 +79,59 @@
|
||||||
MaxHeight="18"
|
MaxHeight="18"
|
||||||
Orientation="Horizontal">
|
Orientation="Horizontal">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Name="VsyncStatus"
|
Name="VSyncMode"
|
||||||
Margin="5,0,5,0"
|
Margin="5,0,5,0"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Foreground="{Binding VsyncColor}"
|
Foreground="{Binding VSyncModeColor}"
|
||||||
IsVisible="{Binding !ShowLoadProgress}"
|
IsVisible="{Binding !ShowLoadProgress}"
|
||||||
PointerReleased="VsyncStatus_PointerReleased"
|
PointerReleased="VSyncMode_PointerReleased"
|
||||||
Text="VSync"
|
Text="{Binding VSyncModeText}"
|
||||||
TextAlignment="Start" />
|
TextAlignment="Start"/>
|
||||||
|
<Button MinWidth="0"
|
||||||
|
Width="20"
|
||||||
|
IsVisible="{Binding ShowCustomVSyncIntervalPicker}"
|
||||||
|
Margin="-5,0,5,0"
|
||||||
|
Background="Transparent"
|
||||||
|
BorderThickness="0">
|
||||||
|
<ui:SymbolIcon Symbol="Settings"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Width="14"
|
||||||
|
Height="14"/>
|
||||||
|
<Button.Styles>
|
||||||
|
<Style Selector=":checked">
|
||||||
|
<Style Selector="^:checked ContentPresenter">
|
||||||
|
<Setter Property="Foreground" Value="{DynamicResource ThemeForegroundColor}" />
|
||||||
|
</Style>
|
||||||
|
</Style>
|
||||||
|
<Style Selector="Border#SeparatorBorder">
|
||||||
|
<Setter Property="Opacity" Value="0" />
|
||||||
|
</Style>
|
||||||
|
</Button.Styles>
|
||||||
|
<Button.Flyout>
|
||||||
|
<Flyout Placement="Top" ShowMode="TransientWithDismissOnPointerMoveAway">
|
||||||
|
<StackPanel Margin="0,0,0,0"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<Slider Value="{Binding CustomVSyncIntervalPercentageProxy}"
|
||||||
|
MinWidth="175"
|
||||||
|
Margin="0,-3,0,0"
|
||||||
|
Height="32"
|
||||||
|
Padding="0,-5"
|
||||||
|
TickFrequency="1"
|
||||||
|
IsSnapToTickEnabled="True"
|
||||||
|
LargeChange="10"
|
||||||
|
SmallChange="1"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Minimum="10"
|
||||||
|
Maximum="400" />
|
||||||
|
<TextBlock Margin="5,0"
|
||||||
|
Width="40"
|
||||||
|
Text="{Binding CustomVSyncIntervalPercentageText}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Flyout>
|
||||||
|
</Button.Flyout>
|
||||||
|
</Button>
|
||||||
<Border
|
<Border
|
||||||
Width="2"
|
Width="2"
|
||||||
Height="12"
|
Height="12"
|
||||||
|
|
|
@ -38,11 +38,10 @@ namespace Ryujinx.Ava.UI.Views.Main
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void VsyncStatus_PointerReleased(object sender, PointerReleasedEventArgs e)
|
private void VSyncMode_PointerReleased(object sender, PointerReleasedEventArgs e)
|
||||||
{
|
{
|
||||||
Window.ViewModel.AppHost.ToggleVSync();
|
Window.ViewModel.ToggleVSyncMode();
|
||||||
|
Logger.Info?.Print(LogClass.Application, $"VSync Mode toggled to: {Window.ViewModel.AppHost.Device.VSyncMode}");
|
||||||
Logger.Info?.Print(LogClass.Application, $"VSync toggled to: {Window.ViewModel.AppHost.Device.EnableDeviceVsync}");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DockedStatus_PointerReleased(object sender, PointerReleasedEventArgs e)
|
private void DockedStatus_PointerReleased(object sender, PointerReleasedEventArgs e)
|
||||||
|
|
|
@ -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"
|
||||||
|
@ -50,9 +50,9 @@
|
||||||
Classes="h1"
|
Classes="h1"
|
||||||
Text="{ext:Locale SettingsTabHotkeysHotkeys}" />
|
Text="{ext:Locale SettingsTabHotkeysHotkeys}" />
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
<TextBlock Text="{ext:Locale SettingsTabHotkeysToggleVsyncHotkey}" />
|
<TextBlock Text="{ext:Locale SettingsTabHotkeysToggleVSyncModeHotkey}" />
|
||||||
<ToggleButton Name="ToggleVsync">
|
<ToggleButton Name="ToggleVSyncMode">
|
||||||
<TextBlock Text="{Binding KeyboardHotkey.ToggleVsync, Converter={StaticResource Key}}" />
|
<TextBlock Text="{Binding KeyboardHotkey.ToggleVSyncMode, Converter={StaticResource Key}}" />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
|
@ -103,6 +103,18 @@
|
||||||
<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 Text="{ext:Locale SettingsTabHotkeysIncrementCustomVSyncIntervalHotkey}" />
|
||||||
|
<ToggleButton Name="CustomVSyncIntervalIncrement">
|
||||||
|
<TextBlock Text="{Binding KeyboardHotkey.CustomVSyncIntervalIncrement, Converter={StaticResource Key}}" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Margin="10,0,0,0" Orientation="Horizontal">
|
||||||
|
<TextBlock Text="{ext:Locale SettingsTabHotkeysDecrementCustomVSyncIntervalHotkey}" />
|
||||||
|
<ToggleButton Name="CustomVSyncIntervalDecrement">
|
||||||
|
<TextBlock Text="{Binding KeyboardHotkey.CustomVSyncIntervalDecrement, Converter={StaticResource Key}}" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
|
|
|
@ -82,8 +82,8 @@ namespace Ryujinx.Ava.UI.Views.Settings
|
||||||
|
|
||||||
switch (button.Name)
|
switch (button.Name)
|
||||||
{
|
{
|
||||||
case "ToggleVsync":
|
case "ToggleVSyncMode":
|
||||||
viewModel.KeyboardHotkey.ToggleVsync = buttonValue.AsHidType<Key>();
|
viewModel.KeyboardHotkey.ToggleVSyncMode = buttonValue.AsHidType<Key>();
|
||||||
break;
|
break;
|
||||||
case "Screenshot":
|
case "Screenshot":
|
||||||
viewModel.KeyboardHotkey.Screenshot = buttonValue.AsHidType<Key>();
|
viewModel.KeyboardHotkey.Screenshot = buttonValue.AsHidType<Key>();
|
||||||
|
@ -109,6 +109,12 @@ 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 "CustomVSyncIntervalIncrement":
|
||||||
|
viewModel.KeyboardHotkey.CustomVSyncIntervalIncrement = buttonValue.AsHidType<Key>();
|
||||||
|
break;
|
||||||
|
case "CustomVSyncIntervalDecrement":
|
||||||
|
viewModel.KeyboardHotkey.CustomVSyncIntervalDecrement = buttonValue.AsHidType<Key>();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
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:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||||
xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup"
|
xmlns:ext="clr-namespace:Ryujinx.Ava.Common.Markup"
|
||||||
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
|
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
|
||||||
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
||||||
|
@ -181,11 +182,68 @@
|
||||||
Width="350"
|
Width="350"
|
||||||
ToolTip.Tip="{ext:Locale TimeTooltip}" />
|
ToolTip.Tip="{ext:Locale TimeTooltip}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<CheckBox IsChecked="{Binding EnableVsync}">
|
<StackPanel Margin="0,0,0,10"
|
||||||
|
Orientation="Horizontal">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{ext:Locale SettingsTabSystemEnableVsync}"
|
VerticalAlignment="Center"
|
||||||
ToolTip.Tip="{ext:Locale VSyncToggleTooltip}" />
|
Text="{ext:Locale SettingsTabSystemVSyncMode}"
|
||||||
</CheckBox>
|
ToolTip.Tip="{ext:Locale SettingsTabSystemVSyncModeTooltip}"
|
||||||
|
Width="250" />
|
||||||
|
<ComboBox
|
||||||
|
IsVisible="{Binding EnableCustomVSyncInterval}"
|
||||||
|
SelectedIndex="{Binding VSyncMode}"
|
||||||
|
ToolTip.Tip="{ext:Locale SettingsTabSystemVSyncModeTooltipCustom}"
|
||||||
|
HorizontalContentAlignment="Left"
|
||||||
|
Width="350">
|
||||||
|
<ComboBoxItem>
|
||||||
|
<TextBlock Text="{ext:Locale SettingsTabSystemVSyncModeSwitch}" />
|
||||||
|
</ComboBoxItem>
|
||||||
|
<ComboBoxItem>
|
||||||
|
<TextBlock Text="{ext:Locale SettingsTabSystemVSyncModeUnbounded}" />
|
||||||
|
</ComboBoxItem>
|
||||||
|
<ComboBoxItem>
|
||||||
|
<TextBlock Text="{ext:Locale SettingsTabSystemVSyncModeCustom}" />
|
||||||
|
</ComboBoxItem>
|
||||||
|
</ComboBox>
|
||||||
|
<ComboBox
|
||||||
|
IsVisible="{Binding !EnableCustomVSyncInterval}"
|
||||||
|
SelectedIndex="{Binding VSyncMode}"
|
||||||
|
ToolTip.Tip="{ext:Locale SettingsTabSystemVSyncModeTooltip}"
|
||||||
|
HorizontalContentAlignment="Left"
|
||||||
|
Width="350">
|
||||||
|
<ComboBoxItem>
|
||||||
|
<TextBlock Text="{ext:Locale SettingsTabSystemVSyncModeSwitch}" />
|
||||||
|
</ComboBoxItem>
|
||||||
|
<ComboBoxItem>
|
||||||
|
<TextBlock Text="{ext:Locale SettingsTabSystemVSyncModeUnbounded}" />
|
||||||
|
</ComboBoxItem>
|
||||||
|
</ComboBox>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel IsVisible="{Binding EnableCustomVSyncInterval}"
|
||||||
|
Margin="0,0,0,10"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{ext:Locale SettingsTabSystemCustomVSyncIntervalPercentage}"
|
||||||
|
ToolTip.Tip="{ext:Locale SettingsTabSystemCustomVSyncIntervalValueTooltip}"
|
||||||
|
Width="250" />
|
||||||
|
<Slider Value="{Binding CustomVSyncIntervalPercentageProxy}"
|
||||||
|
ToolTip.Tip="{ext:Locale SettingsTabSystemCustomVSyncIntervalSliderTooltip}"
|
||||||
|
MinWidth="175"
|
||||||
|
Margin="10,-3,0,0"
|
||||||
|
Height="32"
|
||||||
|
Padding="0,-5"
|
||||||
|
TickFrequency="1"
|
||||||
|
IsSnapToTickEnabled="True"
|
||||||
|
LargeChange="10"
|
||||||
|
SmallChange="1"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Minimum="10"
|
||||||
|
Maximum="400" />
|
||||||
|
<TextBlock Margin="5,0"
|
||||||
|
Width="40"
|
||||||
|
Text="{Binding CustomVSyncIntervalPercentageText}"/>
|
||||||
|
</StackPanel>
|
||||||
<CheckBox IsChecked="{Binding EnableFsIntegrityChecks}">
|
<CheckBox IsChecked="{Binding EnableFsIntegrityChecks}">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{ext:Locale SettingsTabSystemEnableFsIntegrityChecks}"
|
Text="{ext:Locale SettingsTabSystemEnableFsIntegrityChecks}"
|
||||||
|
@ -244,6 +302,11 @@
|
||||||
ToolTip.Tip="{ext:Locale IgnoreAppletTooltip}">
|
ToolTip.Tip="{ext:Locale IgnoreAppletTooltip}">
|
||||||
<TextBlock Text="{ext:Locale SettingsTabSystemIgnoreApplet}" />
|
<TextBlock Text="{ext:Locale SettingsTabSystemIgnoreApplet}" />
|
||||||
</CheckBox>
|
</CheckBox>
|
||||||
|
<CheckBox
|
||||||
|
IsChecked="{Binding EnableCustomVSyncInterval}"
|
||||||
|
ToolTip.Tip="{ext:Locale SettingsTabSystemEnableCustomVSyncIntervalTooltip}">
|
||||||
|
<TextBlock Text="{ext:Locale SettingsTabSystemEnableCustomVSyncInterval}" />
|
||||||
|
</CheckBox>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
|
@ -38,6 +38,8 @@ namespace Ryujinx.Ava.UI.Windows
|
||||||
{
|
{
|
||||||
public partial class MainWindow : StyleableAppWindow
|
public partial class MainWindow : StyleableAppWindow
|
||||||
{
|
{
|
||||||
|
internal static MainWindowViewModel MainWindowViewModel { get; private set; }
|
||||||
|
|
||||||
public MainWindowViewModel ViewModel { get; }
|
public MainWindowViewModel ViewModel { get; }
|
||||||
|
|
||||||
internal readonly AvaHostUIHandler UiHandler;
|
internal readonly AvaHostUIHandler UiHandler;
|
||||||
|
@ -73,7 +75,7 @@ namespace Ryujinx.Ava.UI.Windows
|
||||||
|
|
||||||
public MainWindow()
|
public MainWindow()
|
||||||
{
|
{
|
||||||
DataContext = ViewModel = new MainWindowViewModel
|
DataContext = ViewModel = MainWindowViewModel = new MainWindowViewModel
|
||||||
{
|
{
|
||||||
Window = this
|
Window = this
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue