|
@@ -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:
|
|
|
|
|
- ToggleVSync();
|
|
|
|
|
|
|
+ case KeyboardHotkeyState.ToggleVSyncMode:
|
|
|
|
|
+ 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;
|
|
|
}
|
|
}
|