Compare commits

..

5 Commits

Author SHA1 Message Date
Evan Husted
ef1529a2d9 localize Turbo Mode for French 2025-03-03 13:38:52 -06:00
Evan Husted
768406cb67 Improve description of Turbo Mode in the UI and localize FPS/Turbo indicator on status bar 2025-03-03 12:42:00 -06:00
Evan Husted
ed5cb82aa8 feature: Turbo Mode
Adds an elapsed tick multiplier feature which speeds up games which are built upon delta time.
More information: https://web.archive.org/web/20240713135029/https://github.com/Ryujinx/Ryujinx/pull/6456
2025-03-03 02:33:28 -06:00
Evan Husted
c48a2e6ba0 join assignment and declaration for this local variable in ipc service 2025-03-03 02:30:26 -06:00
Evan Husted
90f2b089eb fix nullref when switching vsync mode with turbo mode 2025-03-02 23:51:56 -06:00
110 changed files with 947 additions and 589 deletions

View File

@@ -13,5 +13,7 @@ namespace Ryujinx.Common.Configuration.Hid
public Key VolumeDown { get; set; } public Key VolumeDown { get; set; }
public Key CustomVSyncIntervalIncrement { get; set; } public Key CustomVSyncIntervalIncrement { get; set; }
public Key CustomVSyncIntervalDecrement { get; set; } public Key CustomVSyncIntervalDecrement { get; set; }
public Key TurboMode { get; set; }
public bool TurboModeWhileHeld { get; set; }
} }
} }

View File

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

View File

@@ -14,12 +14,37 @@ namespace Ryujinx.Cpu
/// <inheritdoc/> /// <inheritdoc/>
public ulong Counter => (ulong)(ElapsedSeconds * Frequency); public ulong Counter => (ulong)(ElapsedSeconds * Frequency);
public long TickScalar { get; set; }
private static long _acumElapsedTicks;
private static long _lastElapsedTicks;
private long ElapsedTicks
{
get
{
long elapsedTicks = _tickCounter.ElapsedTicks;
_acumElapsedTicks += (elapsedTicks - _lastElapsedTicks) * TickScalar / 100;
_lastElapsedTicks = elapsedTicks;
return _acumElapsedTicks;
}
}
/// <inheritdoc/> /// <inheritdoc/>
public TimeSpan ElapsedTime => _tickCounter.Elapsed;
public TimeSpan ElapsedTime => Stopwatch.GetElapsedTime(0, ElapsedTicks);
/// <inheritdoc/> /// <inheritdoc/>
public double ElapsedSeconds => _tickCounter.ElapsedTicks * _hostTickFreq; public double ElapsedSeconds => ElapsedTicks * _hostTickFreq;
public TickSource(ulong frequency) public TickSource(ulong frequency)
{ {

View File

@@ -1,6 +1,4 @@
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL.Multithreading;
using System; using System;
using System.Threading; using System.Threading;
@@ -12,20 +10,6 @@ namespace Ryujinx.Graphics.GAL
bool PreferThreading { get; } bool PreferThreading { get; }
public IRenderer TryMakeThreaded(BackendThreading backendThreading = BackendThreading.Auto)
{
if (backendThreading is BackendThreading.On ||
(backendThreading is BackendThreading.Auto && PreferThreading))
{
Logger.Info?.PrintMsg(LogClass.Gpu, $"Backend Threading ({backendThreading}): True");
return new ThreadedRenderer(this);
}
Logger.Info?.PrintMsg(LogClass.Gpu, $"Backend Threading ({backendThreading}): False");
return this;
}
IPipeline Pipeline { get; } IPipeline Pipeline { get; }
IWindow Window { get; } IWindow Window { get; }

View File

@@ -1065,7 +1065,14 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
/// </summary> /// </summary>
private void UpdateIndexBufferState() private void UpdateIndexBufferState()
{ {
IndexBufferState indexBuffer = _state.State.IndexBufferState; IndexBufferState? indexBufferNullable = _state?.State.IndexBufferState;
if (!indexBufferNullable.HasValue)
{
return;
}
IndexBufferState indexBuffer = indexBufferNullable.Value;
if (_drawState.IndexCount == 0) if (_drawState.IndexCount == 0)
{ {

View File

@@ -15,55 +15,55 @@ namespace Ryujinx.HLE
/// <summary> /// <summary>
/// HLE configuration. /// HLE configuration.
/// </summary> /// </summary>
public class HleConfiguration public class HLEConfiguration
{ {
/// <summary> /// <summary>
/// The virtual file system used by the FS service. /// The virtual file system used by the FS service.
/// </summary> /// </summary>
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks> /// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
internal VirtualFileSystem VirtualFileSystem { get; private set; } internal readonly VirtualFileSystem VirtualFileSystem;
/// <summary> /// <summary>
/// The manager for handling a LibHac Horizon instance. /// The manager for handling a LibHac Horizon instance.
/// </summary> /// </summary>
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks> /// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
internal LibHacHorizonManager LibHacHorizonManager { get; private set; } internal readonly LibHacHorizonManager LibHacHorizonManager;
/// <summary> /// <summary>
/// The account manager used by the account service. /// The account manager used by the account service.
/// </summary> /// </summary>
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks> /// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
internal AccountManager AccountManager { get; private set; } internal readonly AccountManager AccountManager;
/// <summary> /// <summary>
/// The content manager used by the NCM service. /// The content manager used by the NCM service.
/// </summary> /// </summary>
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks> /// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
internal ContentManager ContentManager { get; private set; } internal readonly ContentManager ContentManager;
/// <summary> /// <summary>
/// The persistent information between run for multi-application capabilities. /// The persistent information between run for multi-application capabilities.
/// </summary> /// </summary>
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks> /// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
public UserChannelPersistence UserChannelPersistence { get; private set; } public readonly UserChannelPersistence UserChannelPersistence;
/// <summary> /// <summary>
/// The GPU renderer to use for all GPU operations. /// The GPU renderer to use for all GPU operations.
/// </summary> /// </summary>
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks> /// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
internal IRenderer GpuRenderer { get; private set; } internal readonly IRenderer GpuRenderer;
/// <summary> /// <summary>
/// The audio device driver to use for all audio operations. /// The audio device driver to use for all audio operations.
/// </summary> /// </summary>
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks> /// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
internal IHardwareDeviceDriver AudioDeviceDriver { get; private set; } internal readonly IHardwareDeviceDriver AudioDeviceDriver;
/// <summary> /// <summary>
/// The handler for various UI related operations needed outside of HLE. /// The handler for various UI related operations needed outside of HLE.
/// </summary> /// </summary>
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks> /// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
internal IHostUIHandler HostUIHandler { get; private set; } internal readonly IHostUIHandler HostUIHandler;
/// <summary> /// <summary>
/// Control the memory configuration used by the emulation context. /// Control the memory configuration used by the emulation context.
@@ -102,6 +102,11 @@ namespace Ryujinx.HLE
/// Control if the Profiled Translation Cache (PTC) should be used. /// Control if the Profiled Translation Cache (PTC) should be used.
/// </summary> /// </summary>
internal readonly bool EnablePtc; internal readonly bool EnablePtc;
/// <summary>
/// Control the arbitrary scalar applied to emulated CPU tick timing.
/// </summary>
public long TickScalar { get; set; }
/// <summary> /// <summary>
/// Control if the guest application should be told that there is a Internet connection available. /// Control if the guest application should be told that there is a Internet connection available.
@@ -195,7 +200,15 @@ namespace Ryujinx.HLE
/// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks> /// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks>
public EnabledDirtyHack[] Hacks { internal get; set; } public EnabledDirtyHack[] Hacks { internal get; set; }
public HleConfiguration(MemoryConfiguration memoryConfiguration, public HLEConfiguration(VirtualFileSystem virtualFileSystem,
LibHacHorizonManager libHacHorizonManager,
ContentManager contentManager,
AccountManager accountManager,
UserChannelPersistence userChannelPersistence,
IRenderer gpuRenderer,
IHardwareDeviceDriver audioDeviceDriver,
MemoryConfiguration memoryConfiguration,
IHostUIHandler hostUIHandler,
SystemLanguage systemLanguage, SystemLanguage systemLanguage,
RegionCode region, RegionCode region,
VSyncMode vSyncMode, VSyncMode vSyncMode,
@@ -217,9 +230,18 @@ namespace Ryujinx.HLE
string multiplayerLdnPassphrase, string multiplayerLdnPassphrase,
string multiplayerLdnServer, string multiplayerLdnServer,
int customVSyncInterval, int customVSyncInterval,
long tickScalar,
EnabledDirtyHack[] dirtyHacks = null) EnabledDirtyHack[] dirtyHacks = null)
{ {
VirtualFileSystem = virtualFileSystem;
LibHacHorizonManager = libHacHorizonManager;
AccountManager = accountManager;
ContentManager = contentManager;
UserChannelPersistence = userChannelPersistence;
GpuRenderer = gpuRenderer;
AudioDeviceDriver = audioDeviceDriver;
MemoryConfiguration = memoryConfiguration; MemoryConfiguration = memoryConfiguration;
HostUIHandler = hostUIHandler;
SystemLanguage = systemLanguage; SystemLanguage = systemLanguage;
Region = region; Region = region;
VSyncMode = vSyncMode; VSyncMode = vSyncMode;
@@ -241,32 +263,8 @@ namespace Ryujinx.HLE
MultiplayerDisableP2p = multiplayerDisableP2p; MultiplayerDisableP2p = multiplayerDisableP2p;
MultiplayerLdnPassphrase = multiplayerLdnPassphrase; MultiplayerLdnPassphrase = multiplayerLdnPassphrase;
MultiplayerLdnServer = multiplayerLdnServer; MultiplayerLdnServer = multiplayerLdnServer;
TickScalar = tickScalar;
Hacks = dirtyHacks ?? []; Hacks = dirtyHacks ?? [];
} }
/// <summary>
/// Set the pre-configured services to use for this <see cref="HleConfiguration"/> instance.
/// </summary>
public HleConfiguration Configure(
VirtualFileSystem virtualFileSystem,
LibHacHorizonManager libHacHorizonManager,
ContentManager contentManager,
AccountManager accountManager,
UserChannelPersistence userChannelPersistence,
IRenderer gpuRenderer,
IHardwareDeviceDriver audioDeviceDriver,
IHostUIHandler hostUIHandler
)
{
VirtualFileSystem = virtualFileSystem;
LibHacHorizonManager = libHacHorizonManager;
AccountManager = accountManager;
ContentManager = contentManager;
UserChannelPersistence = userChannelPersistence;
GpuRenderer = gpuRenderer;
AudioDeviceDriver = audioDeviceDriver;
HostUIHandler = hostUIHandler;
return this;
}
} }
} }

View File

@@ -127,10 +127,7 @@ namespace Ryujinx.HLE.HOS.Services
} }
else else
{ {
string serviceName; string serviceName = (service is not DummyService dummyService) ? service.GetType().FullName : dummyService.ServiceName;
serviceName = (service is not DummyService dummyService) ? service.GetType().FullName : dummyService.ServiceName;
Logger.Warning?.Print(LogClass.KernelIpc, $"Missing service {serviceName}: {commandId} ignored"); Logger.Warning?.Print(LogClass.KernelIpc, $"Missing service {serviceName}: {commandId} ignored");
} }

View File

@@ -19,7 +19,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.LdnMitm
private readonly LanDiscovery _lanDiscovery; private readonly LanDiscovery _lanDiscovery;
public LdnMitmClient(HleConfiguration config) public LdnMitmClient(HLEConfiguration config)
{ {
UnicastIPAddressInformation localIpInterface = NetworkHelpers.GetLocalInterface(config.MultiplayerLanInterfaceId).Item2; UnicastIPAddressInformation localIpInterface = NetworkHelpers.GetLocalInterface(config.MultiplayerLanInterfaceId).Item2;

View File

@@ -51,13 +51,13 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.LdnRyu
private string _passphrase; private string _passphrase;
private byte[] _gameVersion = new byte[0x10]; private byte[] _gameVersion = new byte[0x10];
private readonly HleConfiguration _config; private readonly HLEConfiguration _config;
public event EventHandler<NetworkChangeEventArgs> NetworkChange; public event EventHandler<NetworkChangeEventArgs> NetworkChange;
public ProxyConfig Config { get; private set; } public ProxyConfig Config { get; private set; }
public LdnMasterProxyClient(string address, int port, HleConfiguration config) : base(address, port) public LdnMasterProxyClient(string address, int port, HLEConfiguration config) : base(address, port)
{ {
if (ProxyHelpers.SupportsNoDelay()) if (ProxyHelpers.SupportsNoDelay())
{ {

View File

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

View File

@@ -6,6 +6,8 @@ namespace Ryujinx.HLE
{ {
public class PerformanceStatistics public class PerformanceStatistics
{ {
private readonly Switch _device;
private const int FrameTypeGame = 0; private const int FrameTypeGame = 0;
private const int PercentTypeFifo = 0; private const int PercentTypeFifo = 0;
@@ -28,8 +30,10 @@ namespace Ryujinx.HLE
private readonly System.Timers.Timer _resetTimer; private readonly System.Timers.Timer _resetTimer;
public PerformanceStatistics() public PerformanceStatistics(Switch device)
{ {
_device = device;
_frameRate = new double[1]; _frameRate = new double[1];
_accumulatedFrameTime = new double[1]; _accumulatedFrameTime = new double[1];
_previousFrameTime = new double[1]; _previousFrameTime = new double[1];
@@ -162,14 +166,6 @@ namespace Ryujinx.HLE
return 1000 / _frameRate[FrameTypeGame]; return 1000 / _frameRate[FrameTypeGame];
} }
public string FormatGameFrameRate()
{
double frameRate = GetGameFrameRate();
double frameTime = GetGameFrameTime();
return $"{frameRate:00.00} FPS ({frameTime:00.00}ms)";
}
public string FormatFifoPercent() public string FormatFifoPercent()
{ {
double fifoPercent = GetFifoPercent(); double fifoPercent = GetFifoPercent();

View File

@@ -20,31 +20,39 @@ namespace Ryujinx.HLE
{ {
public static Switch Shared { get; private set; } public static Switch Shared { get; private set; }
public HleConfiguration Configuration { get; } public HLEConfiguration Configuration { get; }
public IHardwareDeviceDriver AudioDeviceDriver { get; } public IHardwareDeviceDriver AudioDeviceDriver { get; }
public MemoryBlock Memory { get; } public MemoryBlock Memory { get; }
public GpuContext Gpu { get; } public GpuContext Gpu { get; }
public VirtualFileSystem FileSystem { get; } public VirtualFileSystem FileSystem { get; }
public HOS.Horizon System { get; } public HOS.Horizon System { get; }
public bool TurboMode = false;
public long TickScalar
{
get => System?.TickSource?.TickScalar ?? 100;
set => System.TickSource.TickScalar = value;
}
public ProcessLoader Processes { get; } public ProcessLoader Processes { get; }
public PerformanceStatistics Statistics { get; } public PerformanceStatistics Statistics { get; }
public Hid Hid { get; } public Hid Hid { get; }
public TamperMachine TamperMachine { get; } public TamperMachine TamperMachine { get; }
public IHostUIHandler UIHandler { get; } public IHostUIHandler UIHandler { get; }
public int CpuCoresCount = 4; //Switch 1 has 4 cores public int CpuCoresCount = 4; // Switch has a quad-core Tegra X1 SoC
public VSyncMode VSyncMode { get; set; } public VSyncMode VSyncMode { get; set; }
public bool CustomVSyncIntervalEnabled { get; set; } public bool CustomVSyncIntervalEnabled { get; set; }
public int CustomVSyncInterval { get; set; } public int CustomVSyncInterval { get; set; }
public long TargetVSyncInterval { get; set; } = 60; public long TargetVSyncInterval { get; set; } = 60;
public bool IsFrameAvailable => Gpu.Window.IsFrameAvailable; public bool IsFrameAvailable => Gpu.Window.IsFrameAvailable;
public DirtyHacks DirtyHacks { get; } public DirtyHacks DirtyHacks { get; }
public Switch(HleConfiguration configuration) public Switch(HLEConfiguration configuration)
{ {
ArgumentNullException.ThrowIfNull(configuration.GpuRenderer); ArgumentNullException.ThrowIfNull(configuration.GpuRenderer);
ArgumentNullException.ThrowIfNull(configuration.AudioDeviceDriver); ArgumentNullException.ThrowIfNull(configuration.AudioDeviceDriver);
@@ -64,7 +72,7 @@ namespace Ryujinx.HLE
Memory = new MemoryBlock(Configuration.MemoryConfiguration.ToDramSize(), memoryAllocationFlags); Memory = new MemoryBlock(Configuration.MemoryConfiguration.ToDramSize(), memoryAllocationFlags);
Gpu = new GpuContext(Configuration.GpuRenderer, DirtyHacks); Gpu = new GpuContext(Configuration.GpuRenderer, DirtyHacks);
System = new HOS.Horizon(this); System = new HOS.Horizon(this);
Statistics = new PerformanceStatistics(); Statistics = new PerformanceStatistics(this);
Hid = new Hid(this, System.HidStorage); Hid = new Hid(this, System.HidStorage);
Processes = new ProcessLoader(this); Processes = new ProcessLoader(this);
TamperMachine = new TamperMachine(); TamperMachine = new TamperMachine();
@@ -75,6 +83,7 @@ namespace Ryujinx.HLE
VSyncMode = Configuration.VSyncMode; VSyncMode = Configuration.VSyncMode;
CustomVSyncInterval = Configuration.CustomVSyncInterval; CustomVSyncInterval = Configuration.CustomVSyncInterval;
TickScalar = TurboMode ? Configuration.TickScalar : 100;
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;
@@ -94,20 +103,16 @@ namespace Ryujinx.HLE
Gpu.GPFifo.DispatchCalls(); Gpu.GPFifo.DispatchCalls();
} }
public int IncrementCustomVSyncInterval() public void IncrementCustomVSyncInterval()
{ {
CustomVSyncInterval += 1; CustomVSyncInterval += 1;
UpdateVSyncInterval(); UpdateVSyncInterval();
return CustomVSyncInterval;
} }
public int DecrementCustomVSyncInterval() public void DecrementCustomVSyncInterval()
{ {
CustomVSyncInterval -= 1; CustomVSyncInterval -= 1;
UpdateVSyncInterval(); UpdateVSyncInterval();
return CustomVSyncInterval;
} }
public void UpdateVSyncInterval() public void UpdateVSyncInterval()
@@ -126,6 +131,12 @@ namespace Ryujinx.HLE
} }
} }
public void ToggleTurbo()
{
TurboMode = !TurboMode;
TickScalar = TurboMode ? Configuration.TickScalar : 100;
}
public bool LoadCart(string exeFsDir, string romFsFile = null) => Processes.LoadUnpackedNca(exeFsDir, romFsFile); public bool 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, BlitStruct<ApplicationControlProperty>? customNacpData = null) => Processes.LoadNca(ncaFile, customNacpData); public bool LoadNca(string ncaFile, BlitStruct<ApplicationControlProperty>? customNacpData = null) => Processes.LoadNca(ncaFile, customNacpData);

View File

@@ -4,6 +4,7 @@ using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Threading; using Avalonia.Threading;
using DiscordRPC; using DiscordRPC;
using Gommon;
using LibHac.Common; using LibHac.Common;
using LibHac.Ns; using LibHac.Ns;
using LibHac.Tools.FsSystem; using LibHac.Tools.FsSystem;
@@ -21,8 +22,8 @@ using Ryujinx.Ava.UI.Renderer;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.UI.Windows; using Ryujinx.Ava.UI.Windows;
using Ryujinx.Ava.Utilities; using Ryujinx.Ava.Utilities;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Multiplayer; using Ryujinx.Common.Configuration.Multiplayer;
@@ -902,19 +903,54 @@ namespace Ryujinx.Ava
_ => new OpenGLRenderer() _ => new OpenGLRenderer()
}; };
BackendThreading threadingMode = ConfigurationState.Instance.Graphics.BackendThreading;
bool isGALThreaded = threadingMode == BackendThreading.On || (threadingMode == BackendThreading.Auto && renderer.PreferThreading);
if (isGALThreaded)
{
renderer = new ThreadedRenderer(renderer);
}
Logger.Info?.PrintMsg(LogClass.Gpu, $"Backend Threading ({threadingMode}): {isGALThreaded}");
// Initialize Configuration. // Initialize Configuration.
Device = new Switch(ConfigurationState.Instance.CreateHleConfiguration() MemoryConfiguration memoryConfiguration = ConfigurationState.Instance.System.DramSize.Value;
.Configure(
VirtualFileSystem, Device = new Switch(new HLEConfiguration(
_viewModel.LibHacHorizonManager, VirtualFileSystem,
ContentManager, _viewModel.LibHacHorizonManager,
_accountManager, ContentManager,
_userChannelPersistence, _accountManager,
renderer.TryMakeThreaded(ConfigurationState.Instance.Graphics.BackendThreading), _userChannelPersistence,
InitializeAudio(), renderer,
_viewModel.UiHandler InitializeAudio(),
) memoryConfiguration,
); _viewModel.UiHandler,
(SystemLanguage)ConfigurationState.Instance.System.Language.Value,
(RegionCode)ConfigurationState.Instance.System.Region.Value,
ConfigurationState.Instance.Graphics.VSyncMode,
ConfigurationState.Instance.System.EnableDockedMode,
ConfigurationState.Instance.System.EnablePtc,
ConfigurationState.Instance.System.EnableInternetAccess,
ConfigurationState.Instance.System.EnableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None,
ConfigurationState.Instance.System.FsGlobalAccessLogMode,
ConfigurationState.Instance.System.MatchSystemTime
? 0
: ConfigurationState.Instance.System.SystemTimeOffset,
ConfigurationState.Instance.System.TimeZone,
ConfigurationState.Instance.System.MemoryManagerMode,
ConfigurationState.Instance.System.IgnoreMissingServices,
ConfigurationState.Instance.Graphics.AspectRatio,
ConfigurationState.Instance.System.AudioVolume,
ConfigurationState.Instance.System.UseHypervisor,
ConfigurationState.Instance.Multiplayer.LanInterfaceId.Value,
ConfigurationState.Instance.Multiplayer.Mode,
ConfigurationState.Instance.Multiplayer.DisableP2p,
ConfigurationState.Instance.Multiplayer.LdnPassphrase,
ConfigurationState.Instance.Multiplayer.GetLdnServer(),
ConfigurationState.Instance.Graphics.CustomVSyncInterval,
ConfigurationState.Instance.System.TickScalar,
ConfigurationState.Instance.Hacks.ShowDirtyHacks ? ConfigurationState.Instance.Hacks.EnabledHacks : null));
} }
private static IHardwareDeviceDriver InitializeAudio() private static IHardwareDeviceDriver InitializeAudio()
@@ -1118,11 +1154,23 @@ namespace Ryujinx.Ava
LocaleManager.Instance[LocaleKeys.VolumeShort] + $": {(int)(Device.GetVolume() * 100)}%", LocaleManager.Instance[LocaleKeys.VolumeShort] + $": {(int)(Device.GetVolume() * 100)}%",
dockedMode, dockedMode,
ConfigurationState.Instance.Graphics.AspectRatio.Value.ToText(), ConfigurationState.Instance.Graphics.AspectRatio.Value.ToText(),
Device.Statistics.FormatGameFrameRate(), FormatGameFrameRate(),
Device.Statistics.FormatFifoPercent(), Device.Statistics.FormatFifoPercent(),
_displayCount)); _displayCount));
} }
private string FormatGameFrameRate()
{
string frameRate = Device.Statistics.GetGameFrameRate().ToString("00.00");
string frameTime = Device.Statistics.GetGameFrameTime().ToString("00.00");
return Device.TurboMode
? LocaleManager.GetUnformatted(LocaleKeys.FpsTurboStatusBarText)
.Format(frameRate, frameTime, Device.TickScalar)
: LocaleManager.GetUnformatted(LocaleKeys.FpsStatusBarText)
.Format(frameRate, frameTime);
}
public async Task ShowExitPrompt() public async Task ShowExitPrompt()
{ {
bool shouldExit = !ConfigurationState.Instance.ShowConfirmExit; bool shouldExit = !ConfigurationState.Instance.ShowConfirmExit;
@@ -1148,9 +1196,6 @@ namespace Ryujinx.Ava
private void UpdateShaderCount() private void UpdateShaderCount()
{ {
if (_displayCount is 0 && _renderer.ProgramCount is 0)
return;
// If there is a mismatch between total program compile and previous count // If there is a mismatch between total program compile and previous count
// this means new shaders have been compiled and should be displayed. // this means new shaders have been compiled and should be displayed.
if (_renderer.ProgramCount != _previousCount) if (_renderer.ProgramCount != _previousCount)
@@ -1218,16 +1263,30 @@ namespace Ryujinx.Ava
if (currentHotkeyState != _prevHotkeyState) if (currentHotkeyState != _prevHotkeyState)
{ {
if (ConfigurationState.Instance.Hid.Hotkeys.Value.TurboModeWhileHeld &&
_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.TurboMode) != Device.TurboMode)
{
Device.ToggleTurbo();
}
switch (currentHotkeyState) switch (currentHotkeyState)
{ {
case KeyboardHotkeyState.ToggleVSyncMode: case KeyboardHotkeyState.ToggleVSyncMode:
VSyncModeToggle(); VSyncModeToggle();
break; break;
case KeyboardHotkeyState.CustomVSyncIntervalDecrement: case KeyboardHotkeyState.CustomVSyncIntervalDecrement:
_viewModel.CustomVSyncInterval = Device.DecrementCustomVSyncInterval(); Device.DecrementCustomVSyncInterval();
_viewModel.CustomVSyncInterval -= 1;
break; break;
case KeyboardHotkeyState.CustomVSyncIntervalIncrement: case KeyboardHotkeyState.CustomVSyncIntervalIncrement:
_viewModel.CustomVSyncInterval = Device.IncrementCustomVSyncInterval(); Device.IncrementCustomVSyncInterval();
_viewModel.CustomVSyncInterval += 1;
break;
case KeyboardHotkeyState.TurboMode:
if (!ConfigurationState.Instance.Hid.Hotkeys.Value.TurboModeWhileHeld)
{
Device.ToggleTurbo();
}
break; break;
case KeyboardHotkeyState.Screenshot: case KeyboardHotkeyState.Screenshot:
ScreenshotRequested = true; ScreenshotRequested = true;
@@ -1358,6 +1417,10 @@ namespace Ryujinx.Ava
{ {
state = KeyboardHotkeyState.CustomVSyncIntervalDecrement; state = KeyboardHotkeyState.CustomVSyncIntervalDecrement;
} }
else if (_keyboardInterface.IsPressed((Key)ConfigurationState.Instance.Hid.Hotkeys.Value.TurboMode))
{
state = KeyboardHotkeyState.TurboMode;
}
return state; return state;
} }

View File

@@ -440,7 +440,7 @@
<x:Double x:Key="ControlContentThemeFontSize">13</x:Double> <x:Double x:Key="ControlContentThemeFontSize">13</x:Double>
<x:Double x:Key="MenuItemHeight">26</x:Double> <x:Double x:Key="MenuItemHeight">26</x:Double>
<x:Double x:Key="TabItemMinHeight">28</x:Double> <x:Double x:Key="TabItemMinHeight">28</x:Double>
<x:Double x:Key="ContentDialogMaxWidth">700</x:Double> <x:Double x:Key="ContentDialogMaxWidth">900</x:Double>
<x:Double x:Key="ContentDialogMaxHeight">756</x:Double> <x:Double x:Key="ContentDialogMaxHeight">756</x:Double>
</Styles.Resources> </Styles.Resources>
</Styles> </Styles>

View File

@@ -4897,6 +4897,81 @@
"zh_TW": "低功耗 PPTC" "zh_TW": "低功耗 PPTC"
} }
}, },
{
"ID": "SettingsTabSystemTurboMultiplier",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Turbo Mode multiplier:",
"es_ES": "",
"fr_FR": "Multiplicateur du Mode Turbo :",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "",
"zh_TW": ""
}
},
{
"ID": "SettingsTabSystemTurboMultiplierValueToolTip",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "The Turbo mode multiplier target value.\n\nLeave at 200 if unsure.",
"es_ES": "",
"fr_FR": "La valeur souhaitée du multiplicateur du Mode Turbo.\n\nGarder à 200 si incertain.",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "",
"zh_TW": ""
}
},
{
"ID": "SettingsTabSystemTurboMultiplierToolTip",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Turbo mode is an emulator feature which effectively causes speed up or slow down when a game is not frame-rate sensitive.\nYou can toggle this feature in-game with a hotkey, configurable in Ryujinx Keyboard Hotkeys settings.\n\nLeave at 200 if unsure.",
"es_ES": "",
"fr_FR": "Le Mode Turbo est une fonctionnalité de l'émulateur qui accélère ou ralentit le jeu lorsque ce dernier n'est pas sensible au framerate.\nVous pouvez changer cette option en jeu avec un raccourci clavier, configurable dans les paramètres de Raccourcis clavier de Ryujinx.\n\nGarder à 200 si incertain.",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "",
"zh_TW": ""
}
},
{ {
"ID": "SettingsTabSystemEnableFsIntegrityChecks", "ID": "SettingsTabSystemEnableFsIntegrityChecks",
"Translations": { "Translations": {
@@ -10480,7 +10555,7 @@
"el_GR": "", "el_GR": "",
"en_US": "Unbound", "en_US": "Unbound",
"es_ES": "", "es_ES": "",
"fr_FR": "Pas Attribuée", "fr_FR": "Non Attribuée",
"he_IL": "", "he_IL": "",
"it_IT": "Non assegnato", "it_IT": "Non assegnato",
"ja_JP": "", "ja_JP": "",
@@ -18072,6 +18147,56 @@
"zh_TW": "更新已停用!" "zh_TW": "更新已停用!"
} }
}, },
{
"ID": "FpsStatusBarText",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "{0} FPS ({1}ms)",
"es_ES": "",
"fr_FR": "",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "",
"zh_TW": ""
}
},
{
"ID": "FpsTurboStatusBarText",
"Translations": {
"ar_SA": "{0} FPS ({1}ms), التوربو %{2}",
"de_DE": "",
"el_GR": "",
"en_US": "{0} FPS ({1}ms), Turbo ({2}%)",
"es_ES": "",
"fr_FR": "",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "",
"zh_TW": ""
}
},
{ {
"ID": "UpdaterBackgroundStatusBarButtonText", "ID": "UpdaterBackgroundStatusBarButtonText",
"Translations": { "Translations": {
@@ -23797,6 +23922,81 @@
"zh_TW": "降低自訂的重新整理頻率" "zh_TW": "降低自訂的重新整理頻率"
} }
}, },
{
"ID": "SettingsTabHotkeysTurboMode",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Turbo mode:",
"es_ES": "",
"fr_FR": "Mode Turbo :",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "",
"zh_TW": ""
}
},
{
"ID": "SettingsTabHotkeysTurboModeToolTip",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "The Turbo mode hotkey.\nConfigure the behavior of Turbo mode in Ryujinx CPU settings.\n\nLeave Unbound if unsure.",
"es_ES": "",
"fr_FR": "Le raccourci clavier Mode Turbo.\nConfigurez le comportement du Mode Turbo dans les paramètres de CPU de Ryujinx.\n\nLaisser Non Attribuée si incertain.",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "",
"zh_TW": ""
}
},
{
"ID": "SettingsTabHotkeysOnlyWhilePressed",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Only while pressed",
"es_ES": "",
"fr_FR": "Seulement quand le raccourci est maintenu",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "",
"zh_TW": ""
}
},
{ {
"ID": "CompatibilityListLastUpdated", "ID": "CompatibilityListLastUpdated",
"Translations": { "Translations": {
@@ -23822,31 +24022,6 @@
"zh_TW": "上次更新時間: {0}" "zh_TW": "上次更新時間: {0}"
} }
}, },
{
"ID": "CompatibilityListTitle",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Compatibility List - {0} entries",
"es_ES": "",
"fr_FR": "",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "",
"zh_TW": ""
}
},
{ {
"ID": "CompatibilityListWarning", "ID": "CompatibilityListWarning",
"Translations": { "Translations": {
@@ -23897,31 +24072,6 @@
"zh_TW": "搜尋相容性列表紀錄..." "zh_TW": "搜尋相容性列表紀錄..."
} }
}, },
{
"ID": "CompatibilityListSearchBoxWatermarkWithCount",
"Translations": {
"ar_SA": "",
"de_DE": "",
"el_GR": "",
"en_US": "Search {0} compatibility entries...",
"es_ES": "",
"fr_FR": "",
"he_IL": "",
"it_IT": "",
"ja_JP": "",
"ko_KR": "",
"no_NO": "Søk i {0} kompatibilitetsoppføringer...",
"pl_PL": "",
"pt_BR": "",
"ru_RU": "",
"sv_SE": "",
"th_TH": "",
"tr_TR": "",
"uk_UA": "",
"zh_CN": "",
"zh_TW": ""
}
},
{ {
"ID": "CompatibilityListOpen", "ID": "CompatibilityListOpen",
"Translations": { "Translations": {

View File

@@ -16,7 +16,7 @@ using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Windows; using Ryujinx.Ava.UI.Windows;
using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.Utilities; using Ryujinx.Ava.Utilities;
using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common.Helper; using Ryujinx.Common.Helper;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.FileSystem;
@@ -216,7 +216,11 @@ namespace Ryujinx.Ava.Common
return; return;
} }
(Nca updatePatchNca, _) = mainNca.GetUpdateData(_virtualFileSystem, ConfigurationState.Instance.System.IntegrityCheckLevel, programIndex, out _); IntegrityCheckLevel checkLevel = ConfigurationState.Instance.System.EnableFsIntegrityChecks
? IntegrityCheckLevel.ErrorOnInvalid
: IntegrityCheckLevel.None;
(Nca updatePatchNca, _) = mainNca.GetUpdateData(_virtualFileSystem, checkLevel, programIndex, out _);
if (updatePatchNca is not null) if (updatePatchNca is not null)
{ {
patchNca = updatePatchNca; patchNca = updatePatchNca;

View File

@@ -14,5 +14,6 @@ namespace Ryujinx.Ava.Common
VolumeDown, VolumeDown,
CustomVSyncIntervalIncrement, CustomVSyncIntervalIncrement,
CustomVSyncIntervalDecrement, CustomVSyncIntervalDecrement,
TurboMode,
} }
} }

View File

@@ -1,7 +1,6 @@
using Gommon; using Gommon;
using Ryujinx.Ava.Systems;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
using System; using System;
@@ -56,10 +55,15 @@ namespace Ryujinx.Ava.Common.Locale
SetDynamicValues(LocaleKeys.RyujinxConfirm, RyujinxApp.FullAppName); SetDynamicValues(LocaleKeys.RyujinxConfirm, RyujinxApp.FullAppName);
SetDynamicValues(LocaleKeys.RyujinxUpdater, RyujinxApp.FullAppName); SetDynamicValues(LocaleKeys.RyujinxUpdater, RyujinxApp.FullAppName);
SetDynamicValues(LocaleKeys.RyujinxRebooter, RyujinxApp.FullAppName); SetDynamicValues(LocaleKeys.RyujinxRebooter, RyujinxApp.FullAppName);
SetDynamicValues(LocaleKeys.CompatibilityListSearchBoxWatermarkWithCount, CompatibilityCsv.Entries.Length);
SetDynamicValues(LocaleKeys.CompatibilityListTitle, CompatibilityCsv.Entries.Length);
} }
public static string GetUnformatted(LocaleKeys key) => Instance.Get(key);
public string Get(LocaleKeys key) =>
_localeStrings.TryGetValue(key, out string value)
? value
: key.ToString();
public string this[LocaleKeys key] public string this[LocaleKeys key]
{ {
get get

View File

@@ -1,4 +1,4 @@
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;

View File

@@ -1,9 +1,9 @@
using DiscordRPC; using DiscordRPC;
using Gommon; using Gommon;
using Ryujinx.Ava.Utilities; using Ryujinx.Ava.Utilities;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Ava.Systems.PlayReport; using Ryujinx.Ava.Utilities.PlayReport;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.HLE; using Ryujinx.HLE;

View File

@@ -2,7 +2,7 @@ using DiscordRPC;
using LibHac.Tools.FsSystem; using LibHac.Tools.FsSystem;
using Ryujinx.Audio.Backends.SDL2; using Ryujinx.Audio.Backends.SDL2;
using Ryujinx.Ava; using Ryujinx.Ava;
using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Hid.Controller; using Ryujinx.Common.Configuration.Hid.Controller;
@@ -312,42 +312,50 @@ namespace Ryujinx.Headless
return new OpenGLRenderer(); return new OpenGLRenderer();
} }
private static Switch InitializeEmulationContext(WindowBase window, IRenderer renderer, Options options) => private static Switch InitializeEmulationContext(WindowBase window, IRenderer renderer, Options options)
new( {
new HleConfiguration( BackendThreading threadingMode = options.BackendThreading;
options.DramSize,
options.SystemLanguage, bool threadedGAL = threadingMode == BackendThreading.On || (threadingMode == BackendThreading.Auto && renderer.PreferThreading);
options.SystemRegion,
options.VSyncMode, if (threadedGAL)
!options.DisableDockedMode, {
!options.DisablePTC, renderer = new ThreadedRenderer(renderer);
options.EnableInternetAccess, }
!options.DisableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None,
options.FsGlobalAccessLogMode, HLEConfiguration configuration = new(_virtualFileSystem,
options.SystemTimeOffset, _libHacHorizonManager,
options.SystemTimeZone, _contentManager,
options.MemoryManagerMode, _accountManager,
options.IgnoreMissingServices, _userChannelPersistence,
options.AspectRatio, renderer,
options.AudioVolume, new SDL2HardwareDeviceDriver(),
options.UseHypervisor ?? true, options.DramSize,
options.MultiplayerLanInterfaceId, window,
Common.Configuration.Multiplayer.MultiplayerMode.Disabled, options.SystemLanguage,
false, options.SystemRegion,
string.Empty, options.VSyncMode,
string.Empty, !options.DisableDockedMode,
options.CustomVSyncInterval !options.DisablePTC,
) options.EnableInternetAccess,
.Configure( !options.DisableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None,
_virtualFileSystem, options.FsGlobalAccessLogMode,
_libHacHorizonManager, options.SystemTimeOffset,
_contentManager, options.SystemTimeZone,
_accountManager, options.MemoryManagerMode,
_userChannelPersistence, options.IgnoreMissingServices,
renderer.TryMakeThreaded(options.BackendThreading), options.AspectRatio,
new SDL2HardwareDeviceDriver(), options.AudioVolume,
window options.UseHypervisor ?? true,
) options.MultiplayerLanInterfaceId,
); Common.Configuration.Multiplayer.MultiplayerMode.Disabled,
false,
string.Empty,
string.Empty,
options.CustomVSyncInterval,
100);
return new Switch(configuration);
}
} }
} }

View File

@@ -1,7 +1,7 @@
using CommandLine; using CommandLine;
using Gommon; using Gommon;
using Ryujinx.Ava; using Ryujinx.Ava;
using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid;

View File

@@ -1,7 +1,6 @@
using CommandLine; using CommandLine;
using Gommon; using Gommon;
using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Ava.Systems.Configuration.System;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid;
using Ryujinx.HLE; using Ryujinx.HLE;
@@ -38,7 +37,7 @@ namespace Ryujinx.Headless
EnableInternetAccess = configurationState.System.EnableInternetAccess; EnableInternetAccess = configurationState.System.EnableInternetAccess;
if (NeedsOverride(nameof(DisableFsIntegrityChecks))) if (NeedsOverride(nameof(DisableFsIntegrityChecks)))
DisableFsIntegrityChecks = !configurationState.System.EnableFsIntegrityChecks; DisableFsIntegrityChecks = configurationState.System.EnableFsIntegrityChecks;
if (NeedsOverride(nameof(FsGlobalAccessLogMode))) if (NeedsOverride(nameof(FsGlobalAccessLogMode)))
FsGlobalAccessLogMode = configurationState.System.FsGlobalAccessLogMode; FsGlobalAccessLogMode = configurationState.System.FsGlobalAccessLogMode;
@@ -59,10 +58,10 @@ namespace Ryujinx.Headless
DisableDockedMode = !configurationState.System.EnableDockedMode; DisableDockedMode = !configurationState.System.EnableDockedMode;
if (NeedsOverride(nameof(SystemLanguage))) if (NeedsOverride(nameof(SystemLanguage)))
SystemLanguage = configurationState.System.Language.Value.ToHLE(); SystemLanguage = (SystemLanguage)(int)configurationState.System.Language.Value;
if (NeedsOverride(nameof(SystemRegion))) if (NeedsOverride(nameof(SystemRegion)))
SystemRegion = configurationState.System.Region.Value.ToHLE(); SystemRegion = (RegionCode)(int)configurationState.System.Region.Value;
if (NeedsOverride(nameof(SystemTimeZone))) if (NeedsOverride(nameof(SystemTimeZone)))
SystemTimeZone = configurationState.System.TimeZone; SystemTimeZone = configurationState.System.TimeZone;

View File

@@ -8,8 +8,7 @@ using Projektanker.Icons.Avalonia.MaterialDesign;
using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Windows; using Ryujinx.Ava.UI.Windows;
using Ryujinx.Ava.Utilities; using Ryujinx.Ava.Utilities;
using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Ava.Systems.Configuration.System;
using Ryujinx.Ava.Utilities.SystemInfo; using Ryujinx.Ava.Utilities.SystemInfo;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
@@ -283,16 +282,16 @@ namespace Ryujinx.Ava
// Check if region was overridden. // Check if region was overridden.
if (CommandLineState.OverrideSystemRegion is not null) if (CommandLineState.OverrideSystemRegion is not null)
if (Enum.TryParse(CommandLineState.OverrideSystemRegion, true, out HLE.HOS.SystemState.RegionCode result)) if (Enum.TryParse(CommandLineState.OverrideSystemRegion, true, out Ryujinx.HLE.HOS.SystemState.RegionCode result))
{ {
ConfigurationState.Instance.System.Region.Value = result.ToUI(); ConfigurationState.Instance.System.Region.Value = (Utilities.Configuration.System.Region)result;
} }
//Check if language was overridden. //Check if language was overridden.
if (CommandLineState.OverrideSystemLanguage is not null) if (CommandLineState.OverrideSystemLanguage is not null)
if (Enum.TryParse(CommandLineState.OverrideSystemLanguage, true, out HLE.HOS.SystemState.SystemLanguage result)) if (Enum.TryParse(CommandLineState.OverrideSystemLanguage, true, out Ryujinx.HLE.HOS.SystemState.SystemLanguage result))
{ {
ConfigurationState.Instance.System.Language.Value = result.ToUI(); ConfigurationState.Instance.System.Language.Value = (Utilities.Configuration.System.Language)result;
} }
// Check if hardware-acceleration was overridden. // Check if hardware-acceleration was overridden.

View File

@@ -17,9 +17,4 @@
<sty:FluentAvaloniaTheme PreferUserAccentColor="True" PreferSystemTheme="False" /> <sty:FluentAvaloniaTheme PreferUserAccentColor="True" PreferSystemTheme="False" />
<StyleInclude Source="/Assets/Styles/Styles.xaml" /> <StyleInclude Source="/Assets/Styles/Styles.xaml" />
</Application.Styles> </Application.Styles>
<NativeMenu.Menu>
<NativeMenu>
<NativeMenuItem Header="About Ryujinx" Click="AboutRyujinx_OnClick" />
</NativeMenu>
</NativeMenu.Menu>
</Application> </Application>

View File

@@ -12,7 +12,7 @@ using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Windows; using Ryujinx.Ava.UI.Windows;
using Ryujinx.Ava.Utilities; using Ryujinx.Ava.Utilities;
using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using System; using System;
@@ -147,10 +147,5 @@ namespace Ryujinx.Ava
Current is RyujinxApp { PlatformSettings: not null } app Current is RyujinxApp { PlatformSettings: not null } app
? ConvertThemeVariant(app.PlatformSettings.GetColorValues().ThemeVariant) ? ConvertThemeVariant(app.PlatformSettings.GetColorValues().ThemeVariant)
: ThemeVariant.Default; : ThemeVariant.Default;
private async void AboutRyujinx_OnClick(object sender, EventArgs e)
{
await AboutWindow.Show();
}
} }
} }

View File

@@ -1,26 +0,0 @@
using Ryujinx.Common.Utilities;
using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Systems.Configuration.System
{
[JsonConverter(typeof(TypedStringEnumConverter<Region>))]
public enum Region
{
Japan,
USA,
Europe,
Australia,
China,
Korea,
Taiwan,
}
public static class RegionEnumHelper
{
public static Region ToUI(this HLE.HOS.SystemState.RegionCode hleRegion)
=> (Region)hleRegion;
public static HLE.HOS.SystemState.RegionCode ToHLE(this Region uiRegion)
=> (HLE.HOS.SystemState.RegionCode)uiRegion;
}
}

View File

@@ -7,7 +7,7 @@ using Ryujinx.Ava.UI.Controls;
using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.UI.Windows; using Ryujinx.Ava.UI.Windows;
using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.HLE; using Ryujinx.HLE;
using Ryujinx.HLE.HOS.Applets; using Ryujinx.HLE.HOS.Applets;

View File

@@ -12,7 +12,8 @@ using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.UI.Views.Misc; using Ryujinx.Ava.UI.Views.Misc;
using Ryujinx.Ava.UI.Windows; using Ryujinx.Ava.UI.Windows;
using Ryujinx.Ava.Utilities; using Ryujinx.Ava.Utilities;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Ava.Utilities.Compat;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Helper; using Ryujinx.Common.Helper;
using Ryujinx.HLE.HOS; using Ryujinx.HLE.HOS;
@@ -407,7 +408,7 @@ namespace Ryujinx.Ava.UI.Controls
public async void OpenApplicationCompatibility_Click(object sender, RoutedEventArgs args) public async void OpenApplicationCompatibility_Click(object sender, RoutedEventArgs args)
{ {
if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel }) if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
await CompatibilityListWindow.Show(viewModel.SelectedApplication.IdString); await CompatibilityList.Show(viewModel.SelectedApplication.IdString);
} }
public async void OpenApplicationData_Click(object sender, RoutedEventArgs args) public async void OpenApplicationData_Click(object sender, RoutedEventArgs args)

View File

@@ -1,5 +1,5 @@
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
namespace Ryujinx.Ava.UI.Helpers namespace Ryujinx.Ava.UI.Helpers
{ {

View File

@@ -4,7 +4,6 @@ using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Layout; using Avalonia.Layout;
using Avalonia.Media; using Avalonia.Media;
using Avalonia.Styling;
using Avalonia.Threading; using Avalonia.Threading;
using FluentAvalonia.Core; using FluentAvalonia.Core;
using FluentAvalonia.UI.Controls; using FluentAvalonia.UI.Controls;
@@ -22,23 +21,6 @@ namespace Ryujinx.Ava.UI.Helpers
private static bool _isChoiceDialogOpen; private static bool _isChoiceDialogOpen;
private static ContentDialogOverlayWindow _contentDialogOverlayWindow; private static ContentDialogOverlayWindow _contentDialogOverlayWindow;
public static ContentDialog ApplyStyles(
this ContentDialog contentDialog,
double closeButtonWidth = 80,
HorizontalAlignment buttonSpaceAlignment = HorizontalAlignment.Right)
{
Style closeButton = new(x => x.Name("CloseButton"));
closeButton.Setters.Add(new Setter(Layoutable.WidthProperty, closeButtonWidth));
Style closeButtonParent = new(x => x.Name("CommandSpace"));
closeButtonParent.Setters.Add(new Setter(Layoutable.HorizontalAlignmentProperty, buttonSpaceAlignment));
contentDialog.Styles.Add(closeButton);
contentDialog.Styles.Add(closeButtonParent);
return contentDialog;
}
private async static Task<UserResult> ShowContentDialog( private async static Task<UserResult> ShowContentDialog(
string title, string title,
object content, object content,

View File

@@ -2,7 +2,7 @@ using Avalonia.Data.Converters;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using Gommon; using Gommon;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using System; using System;
using System.Globalization; using System.Globalization;
using System.Text; using System.Text;

View File

@@ -1,7 +1,7 @@
using Avalonia.Logging; using Avalonia.Logging;
using Avalonia.Utilities; using Avalonia.Utilities;
using Gommon; using Gommon;
using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using System; using System;
using System.Text; using System.Text;

View File

@@ -1,4 +1,4 @@
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;

View File

@@ -1,4 +1,4 @@
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;

View File

@@ -28,6 +28,10 @@ namespace Ryujinx.Ava.UI.Models.Input
[ObservableProperty] private Key _customVSyncIntervalDecrement; [ObservableProperty] private Key _customVSyncIntervalDecrement;
[ObservableProperty] private Key _turboMode;
[ObservableProperty] private bool _turboModeWhileHeld;
public HotkeyConfig(KeyboardHotkeys config) public HotkeyConfig(KeyboardHotkeys config)
{ {
if (config == null) if (config == null)
@@ -44,6 +48,8 @@ namespace Ryujinx.Ava.UI.Models.Input
VolumeDown = config.VolumeDown; VolumeDown = config.VolumeDown;
CustomVSyncIntervalIncrement = config.CustomVSyncIntervalIncrement; CustomVSyncIntervalIncrement = config.CustomVSyncIntervalIncrement;
CustomVSyncIntervalDecrement = config.CustomVSyncIntervalDecrement; CustomVSyncIntervalDecrement = config.CustomVSyncIntervalDecrement;
TurboMode = config.TurboMode;
TurboModeWhileHeld = config.TurboModeWhileHeld;
} }
public KeyboardHotkeys GetConfig() => public KeyboardHotkeys GetConfig() =>
@@ -60,6 +66,8 @@ namespace Ryujinx.Ava.UI.Models.Input
VolumeDown = VolumeDown, VolumeDown = VolumeDown,
CustomVSyncIntervalIncrement = CustomVSyncIntervalIncrement, CustomVSyncIntervalIncrement = CustomVSyncIntervalIncrement,
CustomVSyncIntervalDecrement = CustomVSyncIntervalDecrement, CustomVSyncIntervalDecrement = CustomVSyncIntervalDecrement,
TurboMode = TurboMode,
TurboModeWhileHeld = TurboModeWhileHeld
}; };
} }
} }

View File

@@ -3,7 +3,7 @@ using LibHac.Fs;
using LibHac.Ncm; using LibHac.Ncm;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.Utilities; using Ryujinx.Ava.Utilities;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.FileSystem;
using System.IO; using System.IO;
using System.Linq; using System.Linq;

View File

@@ -1,7 +1,7 @@
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Platform; using Avalonia.Platform;
using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Helper; using Ryujinx.Common.Helper;
using SPB.Graphics; using SPB.Graphics;

View File

@@ -1,5 +1,5 @@
using OpenTK.Graphics.OpenGL; using OpenTK.Graphics.OpenGL;
using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL;

View File

@@ -1,7 +1,7 @@
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Media; using Avalonia.Media;
using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using System; using System;

View File

@@ -5,7 +5,7 @@ using CommunityToolkit.Mvvm.ComponentModel;
using Gommon; using Gommon;
using Ryujinx.Ava.Common; using Ryujinx.Ava.Common;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Utilities.Configuration;
using System; using System;
namespace Ryujinx.Ava.UI.ViewModels namespace Ryujinx.Ava.UI.ViewModels

View File

@@ -1,4 +1,4 @@
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using System; using System;
namespace Ryujinx.Ava.UI.ViewModels namespace Ryujinx.Ava.UI.ViewModels

View File

@@ -1,7 +1,7 @@
using Gommon; using Gommon;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Ava.Systems.PlayReport; using Ryujinx.Ava.Utilities.PlayReport;
namespace Ryujinx.Ava.UI.ViewModels namespace Ryujinx.Ava.UI.ViewModels
{ {

View File

@@ -1,6 +1,6 @@
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using Ryujinx.Ava.Common.Models; using Ryujinx.Ava.Common.Models;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using System.Linq; using System.Linq;
namespace Ryujinx.Ava.UI.ViewModels namespace Ryujinx.Ava.UI.ViewModels

View File

@@ -7,7 +7,7 @@ using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Common.Models; using Ryujinx.Ava.Common.Models;
using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.IO; using System.IO;

View File

@@ -10,7 +10,7 @@ using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Models; using Ryujinx.Ava.UI.Models;
using Ryujinx.Ava.UI.Models.Input; using Ryujinx.Ava.UI.Models.Input;
using Ryujinx.Ava.UI.Windows; using Ryujinx.Ava.UI.Windows;
using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid;

View File

@@ -3,7 +3,7 @@ using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input; using CommunityToolkit.Mvvm.Input;
using Humanizer; using Humanizer;
using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Utilities.Configuration;
using System.Globalization; using System.Globalization;
namespace Ryujinx.Ava.UI.ViewModels.Input namespace Ryujinx.Ava.UI.ViewModels.Input

View File

@@ -23,8 +23,8 @@ using Ryujinx.Ava.UI.Models;
using Ryujinx.Ava.UI.Models.Generic; using Ryujinx.Ava.UI.Models.Generic;
using Ryujinx.Ava.UI.Renderer; using Ryujinx.Ava.UI.Renderer;
using Ryujinx.Ava.UI.Windows; using Ryujinx.Ava.UI.Windows;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Helper; using Ryujinx.Common.Helper;

View File

@@ -7,7 +7,7 @@ using Gommon;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Models; using Ryujinx.Ava.UI.Models;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;

View File

@@ -1,6 +1,6 @@
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using Gommon; using Gommon;
using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Utilities.Configuration;
namespace Ryujinx.Ava.UI.ViewModels namespace Ryujinx.Ava.UI.ViewModels
{ {

View File

@@ -12,9 +12,9 @@ using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Models.Input; using Ryujinx.Ava.UI.Models.Input;
using Ryujinx.Ava.UI.Windows; using Ryujinx.Ava.UI.Windows;
using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Ava.Systems.Configuration.System; using Ryujinx.Ava.Utilities.Configuration.System;
using Ryujinx.Ava.Systems.Configuration.UI; using Ryujinx.Ava.Utilities.Configuration.UI;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Multiplayer; using Ryujinx.Common.Configuration.Multiplayer;
using Ryujinx.Common.GraphicsDriver; using Ryujinx.Common.GraphicsDriver;
@@ -60,6 +60,7 @@ namespace Ryujinx.Ava.UI.ViewModels
private bool _enableCustomVSyncInterval; private bool _enableCustomVSyncInterval;
private int _customVSyncIntervalPercentageProxy; private int _customVSyncIntervalPercentageProxy;
private VSyncMode _vSyncMode; private VSyncMode _vSyncMode;
private long _turboModeMultiplier;
public event Action CloseWindow; public event Action CloseWindow;
public event Action SaveSettingsEvent; public event Action SaveSettingsEvent;
@@ -207,6 +208,25 @@ namespace Ryujinx.Ava.UI.ViewModels
} }
public bool EnablePptc { get; set; } public bool EnablePptc { get; set; }
public bool EnableLowPowerPptc { get; set; } public bool EnableLowPowerPptc { get; set; }
public long TurboMultiplier
{
get => _turboModeMultiplier;
set
{
if (_turboModeMultiplier != value)
{
_turboModeMultiplier = value;
OnPropertyChanged();
OnPropertyChanged((nameof(TurboMultiplierPercentageText)));
}
}
}
public string TurboMultiplierPercentageText => $"{TurboMultiplier}%";
public bool EnableInternetAccess { get; set; } public bool EnableInternetAccess { get; set; }
public bool EnableFsIntegrityChecks { get; set; } public bool EnableFsIntegrityChecks { get; set; }
public bool IgnoreMissingServices { get; set; } public bool IgnoreMissingServices { get; set; }
@@ -594,6 +614,7 @@ namespace Ryujinx.Ava.UI.ViewModels
EnableLowPowerPptc = config.System.EnableLowPowerPtc; EnableLowPowerPptc = config.System.EnableLowPowerPtc;
MemoryMode = (int)config.System.MemoryManagerMode.Value; MemoryMode = (int)config.System.MemoryManagerMode.Value;
UseHypervisor = config.System.UseHypervisor; UseHypervisor = config.System.UseHypervisor;
TurboMultiplier = config.System.TickScalar;
// Graphics // Graphics
GraphicsBackendIndex = (int)config.Graphics.GraphicsBackend.Value; GraphicsBackendIndex = (int)config.Graphics.GraphicsBackend.Value;
@@ -697,6 +718,7 @@ namespace Ryujinx.Ava.UI.ViewModels
config.System.EnableLowPowerPtc.Value = EnableLowPowerPptc; config.System.EnableLowPowerPtc.Value = EnableLowPowerPptc;
config.System.MemoryManagerMode.Value = (MemoryManagerMode)MemoryMode; config.System.MemoryManagerMode.Value = (MemoryManagerMode)MemoryMode;
config.System.UseHypervisor.Value = UseHypervisor; config.System.UseHypervisor.Value = UseHypervisor;
config.System.TickScalar.Value = TurboMultiplier;
// Graphics // Graphics
config.Graphics.VSyncMode.Value = VSyncMode; config.Graphics.VSyncMode.Value = VSyncMode;

View File

@@ -6,7 +6,7 @@ using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Common.Models; using Ryujinx.Ava.Common.Models;
using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;

View File

@@ -6,7 +6,7 @@ using Ryujinx.Ava.Common;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Common.Models; using Ryujinx.Ava.Common.Models;
using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;

View File

@@ -11,9 +11,9 @@ using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.UI.Windows; using Ryujinx.Ava.UI.Windows;
using Ryujinx.Ava.Utilities; using Ryujinx.Ava.Utilities;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Utilities.Compat;
using Ryujinx.Ava.UI.Views.Misc; using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Helper; using Ryujinx.Common.Helper;
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
@@ -51,7 +51,7 @@ namespace Ryujinx.Ava.UI.Views.Main
UninstallFileTypesMenuItem.Command = Commands.Create(UninstallFileTypes); UninstallFileTypesMenuItem.Command = Commands.Create(UninstallFileTypes);
XciTrimmerMenuItem.Command = Commands.Create(XCITrimmerWindow.Show); XciTrimmerMenuItem.Command = Commands.Create(XCITrimmerWindow.Show);
AboutWindowMenuItem.Command = Commands.Create(AboutWindow.Show); AboutWindowMenuItem.Command = Commands.Create(AboutWindow.Show);
CompatibilityListMenuItem.Command = Commands.Create(() => CompatibilityListWindow.Show()); CompatibilityListMenuItem.Command = Commands.Create(() => CompatibilityList.Show());
UpdateMenuItem.Command = MainWindowViewModel.UpdateCommand; UpdateMenuItem.Command = MainWindowViewModel.UpdateCommand;

View File

@@ -7,7 +7,7 @@ using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Controls; using Ryujinx.Ava.UI.Controls;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.UI.Windows; using Ryujinx.Ava.UI.Windows;
using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;

View File

@@ -1,14 +1,15 @@
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Input.Platform; using Avalonia.Input.Platform;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.Layout; using Avalonia.Styling;
using FluentAvalonia.UI.Controls; using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Controls; using Ryujinx.Ava.UI.Controls;
using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.UI.Windows; using Ryujinx.Ava.UI.Windows;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Ava.Utilities.Compat;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -28,7 +29,17 @@ namespace Ryujinx.Ava.UI.Views.Misc
Content = new ApplicationDataView { ViewModel = new ApplicationDataViewModel(appData) } Content = new ApplicationDataView { ViewModel = new ApplicationDataViewModel(appData) }
}; };
await ContentDialogHelper.ShowAsync(contentDialog.ApplyStyles(160, HorizontalAlignment.Center)); Style closeButton = new(x => x.Name("CloseButton"));
closeButton.Setters.Add(new Setter(WidthProperty, 160d));
Style closeButtonParent = new(x => x.Name("CommandSpace"));
closeButtonParent.Setters.Add(new Setter(HorizontalAlignmentProperty,
Avalonia.Layout.HorizontalAlignment.Center));
contentDialog.Styles.Add(closeButton);
contentDialog.Styles.Add(closeButtonParent);
await ContentDialogHelper.ShowAsync(contentDialog);
} }
public ApplicationDataView() public ApplicationDataView()
@@ -44,18 +55,21 @@ namespace Ryujinx.Ava.UI.Views.Misc
if (RyujinxApp.AppLifetime.Windows.TryGetFirst(x => x is ContentDialogOverlayWindow, out Window window)) if (RyujinxApp.AppLifetime.Windows.TryGetFirst(x => x is ContentDialogOverlayWindow, out Window window))
window.Close(ContentDialogResult.None); window.Close(ContentDialogResult.None);
await CompatibilityListWindow.Show((string)playabilityLabel.Tag); await CompatibilityList.Show((string)playabilityLabel.Tag);
} }
private async void IdString_OnClick(object sender, RoutedEventArgs e) private async void IdString_OnClick(object sender, RoutedEventArgs e)
{ {
if (DataContext is not MainWindowViewModel mwvm)
return;
if (sender is not Button { Content: TextBlock idText }) if (sender is not Button { Content: TextBlock idText })
return; return;
if (!RyujinxApp.IsClipboardAvailable(out IClipboard clipboard)) if (!RyujinxApp.IsClipboardAvailable(out IClipboard clipboard))
return; return;
ApplicationData appData = RyujinxApp.MainWindow.ViewModel.Applications.FirstOrDefault(it => it.IdString == idText.Text); ApplicationData appData = mwvm.Applications.FirstOrDefault(it => it.IdString == idText.Text);
if (appData is null) if (appData is null)
return; return;

View File

@@ -4,7 +4,7 @@ using Avalonia.Interactivity;
using Ryujinx.Ava.UI.Controls; using Ryujinx.Ava.UI.Controls;
using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using System; using System;
namespace Ryujinx.Ava.UI.Views.Misc namespace Ryujinx.Ava.UI.Views.Misc

View File

@@ -5,8 +5,8 @@ using Avalonia.Interactivity;
using Ryujinx.Ava.UI.Controls; using Ryujinx.Ava.UI.Controls;
using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Ava.UI.Windows; using Ryujinx.Ava.Utilities.Compat;
using System; using System;
using System.Linq; using System.Linq;
@@ -36,7 +36,7 @@ namespace Ryujinx.Ava.UI.Views.Misc
if (sender is not Button { Content: TextBlock playabilityLabel }) if (sender is not Button { Content: TextBlock playabilityLabel })
return; return;
await CompatibilityListWindow.Show((string)playabilityLabel.Tag); await CompatibilityList.Show((string)playabilityLabel.Tag);
} }
private async void IdString_OnClick(object sender, RoutedEventArgs e) private async void IdString_OnClick(object sender, RoutedEventArgs e)

View File

@@ -6,7 +6,7 @@ using Ryujinx.Ava.Common.Models;
using Ryujinx.Ava.UI.Controls; using Ryujinx.Ava.UI.Controls;
using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Ryujinx.Ava.UI.Views.Misc namespace Ryujinx.Ava.UI.Views.Misc
@@ -32,7 +32,17 @@ namespace Ryujinx.Ava.UI.Views.Misc
Content = new DlcSelectView { ViewModel = viewModel } Content = new DlcSelectView { ViewModel = viewModel }
}; };
await ContentDialogHelper.ShowAsync(contentDialog.ApplyStyles()); Style closeButton = new(x => x.Name("CloseButton"));
closeButton.Setters.Add(new Setter(WidthProperty, 80d));
Style closeButtonParent = new(x => x.Name("CommandSpace"));
closeButtonParent.Setters.Add(new Setter(HorizontalAlignmentProperty,
Avalonia.Layout.HorizontalAlignment.Right));
contentDialog.Styles.Add(closeButton);
contentDialog.Styles.Add(closeButtonParent);
await ContentDialogHelper.ShowAsync(contentDialog);
return viewModel.SelectedDlc; return viewModel.SelectedDlc;
} }

View File

@@ -7,6 +7,7 @@
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:helper="clr-namespace:Ryujinx.Common.Helper;assembly=Ryujinx.Common" xmlns:helper="clr-namespace:Ryujinx.Common.Helper;assembly=Ryujinx.Common"
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
mc:Ignorable="d" mc:Ignorable="d"
x:DataType="viewModels:SettingsViewModel"> x:DataType="viewModels:SettingsViewModel">
<Design.DataContext> <Design.DataContext>
@@ -76,6 +77,57 @@
ToolTip.Tip="{ext:Locale UseHypervisorTooltip}" /> ToolTip.Tip="{ext:Locale UseHypervisorTooltip}" />
</CheckBox> </CheckBox>
</StackPanel> </StackPanel>
<Separator Height="1" />
<StackPanel
Orientation="Vertical"
Spacing="5">
<TextBlock
Classes="h1"
Text="{ext:Locale SettingsTabSystemHacks}" />
<TextBlock
Foreground="{DynamicResource SecondaryTextColor}"
TextDecorations="Underline"
Text="{ext:Locale SettingsTabSystemHacksNote}" />
</StackPanel>
<StackPanel
Margin="10,0,0,0"
HorizontalAlignment="Stretch"
Orientation="Vertical">
<StackPanel Margin="0,0,0,10"
Orientation="Horizontal">
<TextBlock
VerticalAlignment="Center"
Background="Transparent"
Text="{ext:Locale SettingsTabSystemTurboMultiplier}"
ToolTip.Tip="{ext:Locale SettingsTabSystemTurboMultiplierToolTip}"
Width="250" />
<ui:NumberBox ToolTip.Tip="{ext:Locale SettingsTabSystemTurboMultiplierValueToolTip}"
Value="{Binding TurboMultiplier}"
Width="165"
SmallChange="1.0"
LargeChange="10"
SimpleNumberFormat="F0"
SpinButtonPlacementMode="Hidden"
Minimum="50"
Maximum="500" />
<Slider Value="{Binding TurboMultiplier}"
ToolTip.Tip="{ext:Locale SettingsTabSystemTurboMultiplierValueToolTip}"
MinWidth="175"
Margin="10,-3,0,0"
Height="32"
Padding="0,-5"
TickFrequency="1"
IsSnapToTickEnabled="True"
LargeChange="10"
SmallChange="1"
VerticalAlignment="Center"
Minimum="50"
Maximum="500" />
<TextBlock Margin="5,0"
Width="40"
Text="{Binding TurboMultiplierPercentageText}"/>
</StackPanel>
</StackPanel>
</StackPanel> </StackPanel>
</Border> </Border>
</ScrollViewer> </ScrollViewer>

View File

@@ -19,7 +19,7 @@
<Setter Property="Margin" Value="10, 0, 0, 0" /> <Setter Property="Margin" Value="10, 0, 0, 0" />
<Setter Property="Orientation" Value="Horizontal" /> <Setter Property="Orientation" Value="Horizontal" />
</Style> </Style>
<Style Selector="StackPanel > StackPanel > TextBlock"> <Style Selector="StackPanel > StackPanel > TextBlock.settingHeader">
<Setter Property="VerticalAlignment" Value="Center" /> <Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Width" Value="230" /> <Setter Property="Width" Value="230" />
</Style> </Style>
@@ -47,71 +47,79 @@
Classes="h1" Classes="h1"
Text="{ext:Locale SettingsTabHotkeysHotkeys}" /> Text="{ext:Locale SettingsTabHotkeysHotkeys}" />
<StackPanel> <StackPanel>
<TextBlock Text="{ext:Locale SettingsTabHotkeysToggleVSyncModeHotkey}" /> <TextBlock Text="{ext:Locale SettingsTabHotkeysToggleVSyncModeHotkey}" Classes="settingHeader" />
<ToggleButton Name="ToggleVSyncMode"> <ToggleButton Name="ToggleVSyncMode">
<TextBlock Text="{Binding KeyboardHotkey.ToggleVSyncMode, Converter={x:Static helpers:KeyValueConverter.Instance}}" /> <TextBlock Text="{Binding KeyboardHotkey.ToggleVSyncMode, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton> </ToggleButton>
</StackPanel> </StackPanel>
<StackPanel> <StackPanel>
<TextBlock Text="{ext:Locale SettingsTabHotkeysScreenshotHotkey}" /> <TextBlock Text="{ext:Locale SettingsTabHotkeysScreenshotHotkey}" Classes="settingHeader" />
<ToggleButton Name="Screenshot"> <ToggleButton Name="Screenshot">
<TextBlock Text="{Binding KeyboardHotkey.Screenshot, Converter={x:Static helpers:KeyValueConverter.Instance}}" /> <TextBlock Text="{Binding KeyboardHotkey.Screenshot, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton> </ToggleButton>
</StackPanel> </StackPanel>
<StackPanel> <StackPanel>
<TextBlock Text="{ext:Locale SettingsTabHotkeysShowUiHotkey}" /> <TextBlock Text="{ext:Locale SettingsTabHotkeysShowUiHotkey}" Classes="settingHeader" />
<ToggleButton Name="ShowUI"> <ToggleButton Name="ShowUI">
<TextBlock Text="{Binding KeyboardHotkey.ShowUI, Converter={x:Static helpers:KeyValueConverter.Instance}}" /> <TextBlock Text="{Binding KeyboardHotkey.ShowUI, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton> </ToggleButton>
</StackPanel> </StackPanel>
<StackPanel> <StackPanel>
<TextBlock Text="{ext:Locale SettingsTabHotkeysPauseHotkey}" /> <TextBlock Text="{ext:Locale SettingsTabHotkeysPauseHotkey}" Classes="settingHeader" />
<ToggleButton Name="Pause"> <ToggleButton Name="Pause">
<TextBlock Text="{Binding KeyboardHotkey.Pause, Converter={x:Static helpers:KeyValueConverter.Instance}}" /> <TextBlock Text="{Binding KeyboardHotkey.Pause, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton> </ToggleButton>
</StackPanel> </StackPanel>
<StackPanel> <StackPanel>
<TextBlock Text="{ext:Locale SettingsTabHotkeysToggleMuteHotkey}" /> <TextBlock Text="{ext:Locale SettingsTabHotkeysToggleMuteHotkey}" Classes="settingHeader" />
<ToggleButton Name="ToggleMute"> <ToggleButton Name="ToggleMute">
<TextBlock Text="{Binding KeyboardHotkey.ToggleMute, Converter={x:Static helpers:KeyValueConverter.Instance}}" /> <TextBlock Text="{Binding KeyboardHotkey.ToggleMute, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton> </ToggleButton>
</StackPanel> </StackPanel>
<StackPanel> <StackPanel>
<TextBlock Text="{ext:Locale SettingsTabHotkeysResScaleUpHotkey}" /> <TextBlock Text="{ext:Locale SettingsTabHotkeysResScaleUpHotkey}" Classes="settingHeader" />
<ToggleButton Name="ResScaleUp"> <ToggleButton Name="ResScaleUp">
<TextBlock Text="{Binding KeyboardHotkey.ResScaleUp, Converter={x:Static helpers:KeyValueConverter.Instance}}" /> <TextBlock Text="{Binding KeyboardHotkey.ResScaleUp, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton> </ToggleButton>
</StackPanel> </StackPanel>
<StackPanel> <StackPanel>
<TextBlock Text="{ext:Locale SettingsTabHotkeysResScaleDownHotkey}" /> <TextBlock Text="{ext:Locale SettingsTabHotkeysResScaleDownHotkey}" Classes="settingHeader" />
<ToggleButton Name="ResScaleDown"> <ToggleButton Name="ResScaleDown">
<TextBlock Text="{Binding KeyboardHotkey.ResScaleDown, Converter={x:Static helpers:KeyValueConverter.Instance}}" /> <TextBlock Text="{Binding KeyboardHotkey.ResScaleDown, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton> </ToggleButton>
</StackPanel> </StackPanel>
<StackPanel> <StackPanel>
<TextBlock Text="{ext:Locale SettingsTabHotkeysVolumeUpHotkey}" /> <TextBlock Text="{ext:Locale SettingsTabHotkeysVolumeUpHotkey}" Classes="settingHeader" />
<ToggleButton Name="VolumeUp"> <ToggleButton Name="VolumeUp">
<TextBlock Text="{Binding KeyboardHotkey.VolumeUp, Converter={x:Static helpers:KeyValueConverter.Instance}}" /> <TextBlock Text="{Binding KeyboardHotkey.VolumeUp, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton> </ToggleButton>
</StackPanel> </StackPanel>
<StackPanel> <StackPanel>
<TextBlock Text="{ext:Locale SettingsTabHotkeysVolumeDownHotkey}" /> <TextBlock Text="{ext:Locale SettingsTabHotkeysVolumeDownHotkey}" Classes="settingHeader" />
<ToggleButton Name="VolumeDown"> <ToggleButton Name="VolumeDown">
<TextBlock Text="{Binding KeyboardHotkey.VolumeDown, Converter={x:Static helpers:KeyValueConverter.Instance}}" /> <TextBlock Text="{Binding KeyboardHotkey.VolumeDown, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton> </ToggleButton>
</StackPanel> </StackPanel>
<StackPanel Margin="10,0,0,0" Orientation="Horizontal"> <StackPanel Margin="10,0,0,0" Orientation="Horizontal">
<TextBlock Text="{ext:Locale SettingsTabHotkeysIncrementCustomVSyncIntervalHotkey}" /> <TextBlock Text="{ext:Locale SettingsTabHotkeysIncrementCustomVSyncIntervalHotkey}" Classes="settingHeader" />
<ToggleButton Name="CustomVSyncIntervalIncrement"> <ToggleButton Name="CustomVSyncIntervalIncrement">
<TextBlock Text="{Binding KeyboardHotkey.CustomVSyncIntervalIncrement, Converter={x:Static helpers:KeyValueConverter.Instance}}" /> <TextBlock Text="{Binding KeyboardHotkey.CustomVSyncIntervalIncrement, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton> </ToggleButton>
</StackPanel> </StackPanel>
<StackPanel Margin="10,0,0,0" Orientation="Horizontal"> <StackPanel Margin="10,0,0,0" Orientation="Horizontal">
<TextBlock Text="{ext:Locale SettingsTabHotkeysDecrementCustomVSyncIntervalHotkey}" /> <TextBlock Text="{ext:Locale SettingsTabHotkeysDecrementCustomVSyncIntervalHotkey}" Classes="settingHeader" />
<ToggleButton Name="CustomVSyncIntervalDecrement"> <ToggleButton Name="CustomVSyncIntervalDecrement">
<TextBlock Text="{Binding KeyboardHotkey.CustomVSyncIntervalDecrement, Converter={x:Static helpers:KeyValueConverter.Instance}}" /> <TextBlock Text="{Binding KeyboardHotkey.CustomVSyncIntervalDecrement, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton> </ToggleButton>
</StackPanel> </StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{ext:Locale SettingsTabHotkeysTurboMode}" Classes="settingHeader" ToolTip.Tip="{ext:Locale SettingsTabHotkeysTurboModeToolTip}" Background="Transparent" />
<ToggleButton Name="TurboMode">
<TextBlock Text="{Binding KeyboardHotkey.TurboMode, Converter={x:Static helpers:KeyValueConverter.Instance}}" />
</ToggleButton>
<TextBlock Text="{ext:Locale SettingsTabHotkeysOnlyWhilePressed}" Margin="10,0" />
<CheckBox IsChecked="{Binding KeyboardHotkey.TurboModeWhileHeld}" />
</StackPanel>
</StackPanel> </StackPanel>
</Border> </Border>
</ScrollViewer> </ScrollViewer>

View File

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

View File

@@ -5,7 +5,6 @@ using Avalonia.Layout;
using Avalonia.Styling; using Avalonia.Styling;
using FluentAvalonia.UI.Controls; using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Controls;
using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Common; using Ryujinx.Common;
@@ -15,7 +14,7 @@ using Button = Avalonia.Controls.Button;
namespace Ryujinx.Ava.UI.Windows namespace Ryujinx.Ava.UI.Windows
{ {
public partial class AboutWindow : RyujinxControl<AboutWindowViewModel> public partial class AboutWindow : UserControl
{ {
public AboutWindow() public AboutWindow()
{ {
@@ -34,10 +33,19 @@ namespace Ryujinx.Ava.UI.Windows
PrimaryButtonText = string.Empty, PrimaryButtonText = string.Empty,
SecondaryButtonText = string.Empty, SecondaryButtonText = string.Empty,
CloseButtonText = LocaleManager.Instance[LocaleKeys.UserProfilesClose], CloseButtonText = LocaleManager.Instance[LocaleKeys.UserProfilesClose],
Content = new AboutWindow { ViewModel = viewModel } Content = new AboutWindow { DataContext = viewModel }
}; };
await ContentDialogHelper.ShowAsync(contentDialog.ApplyStyles()); Style closeButton = new(x => x.Name("CloseButton"));
closeButton.Setters.Add(new Setter(WidthProperty, 80d));
Style closeButtonParent = new(x => x.Name("CommandSpace"));
closeButtonParent.Setters.Add(new Setter(HorizontalAlignmentProperty, HorizontalAlignment.Right));
contentDialog.Styles.Add(closeButton);
contentDialog.Styles.Add(closeButtonParent);
await ContentDialogHelper.ShowAsync(contentDialog);
} }
private void Button_OnClick(object sender, RoutedEventArgs e) private void Button_OnClick(object sender, RoutedEventArgs e)

View File

@@ -2,8 +2,8 @@ using Avalonia.Collections;
using LibHac.Tools.FsSystem; using LibHac.Tools.FsSystem;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Models; using Ryujinx.Ava.UI.Models;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS; using Ryujinx.HLE.HOS;
using System.Collections.Generic; using System.Collections.Generic;
@@ -38,9 +38,12 @@ namespace Ryujinx.Ava.UI.Windows
MinHeight = 650; MinHeight = 650;
LoadedCheats = []; LoadedCheats = [];
IntegrityCheckLevel checkLevel = ConfigurationState.Instance.System.EnableFsIntegrityChecks
? IntegrityCheckLevel.ErrorOnInvalid
: IntegrityCheckLevel.None;
Heading = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.CheatWindowHeading, titleName, titleId.ToUpper()); Heading = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.CheatWindowHeading, titleName, titleId.ToUpper());
BuildId = ApplicationData.GetBuildId(virtualFileSystem, ConfigurationState.Instance.System.IntegrityCheckLevel, titlePath); BuildId = ApplicationData.GetBuildId(virtualFileSystem, checkLevel, titlePath);
InitializeComponent(); InitializeComponent();

View File

@@ -1,82 +0,0 @@
<window:StyleableAppWindow xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:helpers="using:Ryujinx.Ava.UI.Helpers"
xmlns:ext="using:Ryujinx.Ava.Common.Markup"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
xmlns:systems="clr-namespace:Ryujinx.Ava.Systems"
xmlns:window="clr-namespace:Ryujinx.Ava.UI.Windows"
CanResize="False"
mc:Ignorable="d"
MinWidth="800"
MinHeight="745"
x:Class="Ryujinx.Ava.UI.Windows.CompatibilityListWindow"
x:DataType="viewModels:CompatibilityViewModel">
<window:StyleableAppWindow.DataContext>
<viewModels:CompatibilityViewModel />
</window:StyleableAppWindow.DataContext>
<Grid RowDefinitions="Auto,*">
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto,Auto" Name="FlushControls">
<Image
Name="RyuLogo"
Margin="15, 0, 7, 0"
Height="25"
Width="25" />
<TextBox Name="SearchBoxFlush" Grid.Column="1" Margin="0, 5, 0, 5" HorizontalAlignment="Stretch" Watermark="{ext:Locale CompatibilityListSearchBoxWatermarkWithCount}" TextChanged="TextBox_OnTextChanged" />
<CheckBox Grid.Column="2" Margin="7, 0, 0, 0" IsChecked="{Binding OnlyShowOwnedGames}" />
<TextBlock Grid.Column="3" Padding="0, 0, 138, 0" Margin="-10, 0, 18, 0" Text="{ext:Locale CompatibilityListOnlyShowOwnedGames}" />
</Grid>
<Grid Grid.Row="0" ColumnDefinitions="*,Auto,Auto" Name="NormalControls">
<TextBox Name="SearchBoxNormal" Grid.Column="0" Margin="15, 0, 0, 5" HorizontalAlignment="Stretch" Watermark="{ext:Locale CompatibilityListSearchBoxWatermark}" TextChanged="TextBox_OnTextChanged" />
<CheckBox Grid.Column="1" Margin="7, 0, 0, 0" IsChecked="{Binding OnlyShowOwnedGames}" />
<TextBlock Grid.Column="2" Padding="0, 0, 1, 0" Margin="-10, 0, 18, 0" Text="{ext:Locale CompatibilityListOnlyShowOwnedGames}" />
</Grid>
<ScrollViewer Grid.Row="1">
<ListBox Margin="12, 0, 13, 0"
Background="Transparent"
ItemsSource="{Binding CurrentEntries}">
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type systems:CompatibilityEntry}">
<Grid MinWidth="800"
Margin="10"
ColumnDefinitions="*,Auto,Auto,*"
Background="Transparent"
ToolTip.Tip="{Binding LocalizedLastUpdated}">
<TextBlock Grid.Column="0"
Text="{Binding GameName}"
Width="525"
VerticalAlignment="Center"
HorizontalAlignment="Center"
TextWrapping="Wrap" />
<TextBlock Grid.Column="1"
Width="135"
Padding="7, 0, 0, 0"
FontFamily="{StaticResource JetBrainsMono}"
Text="{Binding FormattedTitleId}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
TextWrapping="Wrap" />
<TextBlock Grid.Column="2"
Padding="7, 0"
Text="{Binding LocalizedStatus}"
Width="90"
Background="Transparent"
ToolTip.Tip="{Binding LocalizedStatusDescription}"
Foreground="{Binding Status, Converter={x:Static helpers:PlayabilityStatusConverter.Shared}}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
TextWrapping="NoWrap" />
<TextBlock Grid.Column="3"
Text="{Binding FormattedIssueLabels}"
VerticalAlignment="Center"
HorizontalAlignment="Left"
TextWrapping="WrapWithOverflow" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</ScrollViewer>
<Grid></Grid>
</Grid>
</window:StyleableAppWindow>

View File

@@ -1,50 +0,0 @@
using Avalonia.Controls;
using Avalonia.Styling;
using FluentAvalonia.UI.Controls;
using FluentAvalonia.UI.Windowing;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.UI.Windows;
using System.Threading.Tasks;
namespace Ryujinx.Ava.UI.Windows
{
public partial class CompatibilityListWindow : StyleableAppWindow
{
public static Task Show(string titleId = null) =>
ShowAsync(new CompatibilityListWindow
{
DataContext = new CompatibilityViewModel(RyujinxApp.MainWindow.ViewModel.ApplicationLibrary),
SearchBoxFlush = { Text = titleId ?? string.Empty },
SearchBoxNormal = { Text = titleId ?? string.Empty }
});
public CompatibilityListWindow() : base(useCustomTitleBar: true)
{
Title = RyujinxApp.FormatTitle(LocaleKeys.CompatibilityListTitle);
TitleBar.Height = 37;
InitializeComponent();
RyuLogo.Source = MainWindowViewModel.IconBitmap;
FlushControls.IsVisible = !ConfigurationState.Instance.ShowTitleBar;
NormalControls.IsVisible = ConfigurationState.Instance.ShowTitleBar;
}
// ReSharper disable once UnusedMember.Local
// its referenced in the axaml but rider keeps yelling at me that its unused so
private void TextBox_OnTextChanged(object sender, TextChangedEventArgs e)
{
if (DataContext is not CompatibilityViewModel cvm)
return;
if (sender is not TextBox searchBox)
return;
cvm.Search(searchBox.Text);
}
}
}

View File

@@ -5,7 +5,7 @@ using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Common.Models; using Ryujinx.Ava.Common.Models;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Common.Helper; using Ryujinx.Common.Helper;
using System.Threading.Tasks; using System.Threading.Tasks;

View File

@@ -11,7 +11,7 @@ using Ryujinx.Ava.UI.Models;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.UI.ViewModels.Input; using Ryujinx.Ava.UI.ViewModels.Input;
using Ryujinx.Ava.Utilities; using Ryujinx.Ava.Utilities;
using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS.SystemState; using Ryujinx.HLE.HOS.SystemState;

View File

@@ -18,9 +18,9 @@ using Ryujinx.Ava.UI.Applet;
using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.Utilities; using Ryujinx.Ava.Utilities;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Ava.Systems.Configuration.UI; using Ryujinx.Ava.Utilities.Configuration.UI;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Helper; using Ryujinx.Common.Helper;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
@@ -76,7 +76,7 @@ namespace Ryujinx.Ava.UI.Windows
public readonly double StatusBarHeight; public readonly double StatusBarHeight;
public readonly double MenuBarHeight; public readonly double MenuBarHeight;
public MainWindow() : base(useCustomTitleBar: true) public MainWindow()
{ {
DataContext = ViewModel = new MainWindowViewModel DataContext = ViewModel = new MainWindowViewModel
{ {
@@ -90,6 +90,9 @@ namespace Ryujinx.Ava.UI.Windows
ViewModel.Title = RyujinxApp.FormatTitle(); ViewModel.Title = RyujinxApp.FormatTitle();
TitleBar.ExtendsContentIntoTitleBar = !ConfigurationState.Instance.ShowTitleBar;
TitleBar.TitleBarHitTestType = (ConfigurationState.Instance.ShowTitleBar) ? TitleBarHitTestType.Simple : TitleBarHitTestType.Complex;
// NOTE: Height of MenuBar and StatusBar is not usable here, since it would still be 0 at this point. // NOTE: Height of MenuBar and StatusBar is not usable here, since it would still be 0 at this point.
StatusBarHeight = StatusBarView.StatusBar.MinHeight; StatusBarHeight = StatusBarView.StatusBar.MinHeight;
MenuBarHeight = MenuBar.MinHeight; MenuBarHeight = MenuBar.MinHeight;
@@ -270,7 +273,11 @@ namespace Ryujinx.Ava.UI.Windows
LibHacHorizonManager.InitializeBcatServer(); LibHacHorizonManager.InitializeBcatServer();
LibHacHorizonManager.InitializeSystemClients(); LibHacHorizonManager.InitializeSystemClients();
ApplicationLibrary = new ApplicationLibrary(VirtualFileSystem, ConfigurationState.Instance.System.IntegrityCheckLevel) IntegrityCheckLevel checkLevel = ConfigurationState.Instance.System.EnableFsIntegrityChecks
? IntegrityCheckLevel.ErrorOnInvalid
: IntegrityCheckLevel.None;
ApplicationLibrary = new ApplicationLibrary(VirtualFileSystem, checkLevel)
{ {
DesiredLanguage = ConfigurationState.Instance.System.Language, DesiredLanguage = ConfigurationState.Instance.System.Language,
}; };

View File

@@ -6,7 +6,7 @@ using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Models; using Ryujinx.Ava.UI.Models;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Common.Helper; using Ryujinx.Common.Helper;
using System.Threading.Tasks; using System.Threading.Tasks;
using Button = Avalonia.Controls.Button; using Button = Avalonia.Controls.Button;

View File

@@ -6,7 +6,6 @@ using Avalonia.Media;
using Avalonia.Platform; using Avalonia.Platform;
using FluentAvalonia.UI.Windowing; using FluentAvalonia.UI.Windowing;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Systems.Configuration;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -22,7 +21,7 @@ namespace Ryujinx.Ava.UI.Windows
await appWindow.ShowDialog(owner ?? RyujinxApp.MainWindow); await appWindow.ShowDialog(owner ?? RyujinxApp.MainWindow);
} }
protected StyleableAppWindow(bool useCustomTitleBar = false) protected StyleableAppWindow()
{ {
WindowStartupLocation = WindowStartupLocation.CenterOwner; WindowStartupLocation = WindowStartupLocation.CenterOwner;
TransparencyLevelHint = [WindowTransparencyLevel.None]; TransparencyLevelHint = [WindowTransparencyLevel.None];
@@ -30,12 +29,6 @@ namespace Ryujinx.Ava.UI.Windows
LocaleManager.Instance.LocaleChanged += LocaleChanged; LocaleManager.Instance.LocaleChanged += LocaleChanged;
LocaleChanged(); LocaleChanged();
if (useCustomTitleBar)
{
TitleBar.ExtendsContentIntoTitleBar = !ConfigurationState.Instance.ShowTitleBar;
TitleBar.TitleBarHitTestType = ConfigurationState.Instance.ShowTitleBar ? TitleBarHitTestType.Simple : TitleBarHitTestType.Complex;
}
Icon = MainWindowViewModel.IconBitmap; Icon = MainWindowViewModel.IconBitmap;
} }

View File

@@ -5,7 +5,7 @@ using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Common.Models; using Ryujinx.Ava.Common.Models;
using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Common.Helper; using Ryujinx.Common.Helper;
using System.Threading.Tasks; using System.Threading.Tasks;

View File

@@ -1,6 +1,6 @@
using System; using System;
namespace Ryujinx.Ava.Systems.AppLibrary namespace Ryujinx.Ava.Utilities.AppLibrary
{ {
public class ApplicationCountUpdatedEventArgs : EventArgs public class ApplicationCountUpdatedEventArgs : EventArgs
{ {

View File

@@ -9,8 +9,8 @@ using LibHac.Tools.Fs;
using LibHac.Tools.FsSystem; using LibHac.Tools.FsSystem;
using LibHac.Tools.FsSystem.NcaUtils; using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Utilities; using Ryujinx.Ava.Utilities.Compat;
using Ryujinx.Ava.Systems.PlayReport; using Ryujinx.Ava.Utilities.PlayReport;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.Loaders.Processes.Extensions; using Ryujinx.HLE.Loaders.Processes.Extensions;
@@ -18,7 +18,7 @@ using System;
using System.IO; using System.IO;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Systems.AppLibrary namespace Ryujinx.Ava.Utilities.AppLibrary
{ {
public class ApplicationData public class ApplicationData
{ {

View File

@@ -1,6 +1,6 @@
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Systems.AppLibrary namespace Ryujinx.Ava.Utilities.AppLibrary
{ {
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(ApplicationMetadata))] [JsonSerializable(typeof(ApplicationMetadata))]

View File

@@ -12,9 +12,8 @@ using LibHac.Tools.Fs;
using LibHac.Tools.FsSystem; using LibHac.Tools.FsSystem;
using LibHac.Tools.FsSystem.NcaUtils; using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Ava.Common.Models; using Ryujinx.Ava.Common.Models;
using Ryujinx.Ava.Utilities; using Ryujinx.Ava.Utilities.Configuration;
using Ryujinx.Ava.Systems.Configuration; using Ryujinx.Ava.Utilities.Configuration.System;
using Ryujinx.Ava.Systems.Configuration.System;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Multiplayer; using Ryujinx.Common.Configuration.Multiplayer;
@@ -39,7 +38,7 @@ using MissingKeyException = LibHac.Common.Keys.MissingKeyException;
using Path = System.IO.Path; using Path = System.IO.Path;
using TimeSpan = System.TimeSpan; using TimeSpan = System.TimeSpan;
namespace Ryujinx.Ava.Systems.AppLibrary namespace Ryujinx.Ava.Utilities.AppLibrary
{ {
public class ApplicationLibrary public class ApplicationLibrary
{ {
@@ -618,11 +617,15 @@ namespace Ryujinx.Ava.Systems.AppLibrary
case ".xci": case ".xci":
case ".nsp": case ".nsp":
{ {
IntegrityCheckLevel checkLevel = ConfigurationState.Instance.System.EnableFsIntegrityChecks
? IntegrityCheckLevel.ErrorOnInvalid
: IntegrityCheckLevel.None;
using IFileSystem pfs = using IFileSystem pfs =
PartitionFileSystemUtils.OpenApplicationFileSystem(filePath, _virtualFileSystem); PartitionFileSystemUtils.OpenApplicationFileSystem(filePath, _virtualFileSystem);
Dictionary<ulong, ContentMetaData> updates = Dictionary<ulong, ContentMetaData> updates =
pfs.GetContentData(ContentMetaType.Patch, _virtualFileSystem, ConfigurationState.Instance.System.IntegrityCheckLevel); pfs.GetContentData(ContentMetaType.Patch, _virtualFileSystem, checkLevel);
if (updates.Count == 0) if (updates.Count == 0)
{ {

View File

@@ -1,7 +1,7 @@
using System; using System;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Systems.AppLibrary namespace Ryujinx.Ava.Utilities.AppLibrary
{ {
public class ApplicationMetadata public class ApplicationMetadata
{ {

View File

@@ -4,7 +4,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
namespace Ryujinx.Ava.Systems.AppLibrary namespace Ryujinx.Ava.Utilities.AppLibrary
{ {
public struct LdnGameData public struct LdnGameData
{ {

View File

@@ -1,7 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Ryujinx.Ava.Systems.AppLibrary namespace Ryujinx.Ava.Utilities.AppLibrary
{ {
public class LdnGameDataReceivedEventArgs : EventArgs public class LdnGameDataReceivedEventArgs : EventArgs
{ {

View File

@@ -1,7 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Systems.AppLibrary namespace Ryujinx.Ava.Utilities.AppLibrary
{ {
[JsonSerializable(typeof(IEnumerable<LdnGameData>))] [JsonSerializable(typeof(IEnumerable<LdnGameData>))]
internal partial class LdnGameDataSerializerContext : JsonSerializerContext; internal partial class LdnGameDataSerializerContext : JsonSerializerContext;

View File

@@ -2,7 +2,7 @@
using LibHac.Ncm; using LibHac.Ncm;
using LibHac.Ns; using LibHac.Ns;
using LibHac.Tools.FsSystem.NcaUtils; using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.HLE; using Ryujinx.HLE;
using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.FileSystem;

View File

@@ -9,7 +9,7 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
namespace Ryujinx.Ava.Systems namespace Ryujinx.Ava.Utilities.Compat
{ {
public struct ColumnIndices(Func<ReadOnlySpan<char>, int> getIndex) public struct ColumnIndices(Func<ReadOnlySpan<char>, int> getIndex)
{ {

View File

@@ -0,0 +1,81 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:Ryujinx.Ava.Utilities.Compat"
xmlns:helpers="using:Ryujinx.Ava.UI.Helpers"
xmlns:ext="using:Ryujinx.Ava.Common.Markup"
xmlns:ui="using:FluentAvalonia.UI.Controls"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Ryujinx.Ava.Utilities.Compat.CompatibilityList"
x:DataType="local:CompatibilityViewModel">
<UserControl.DataContext>
<local:CompatibilityViewModel />
</UserControl.DataContext>
<Grid RowDefinitions="*,Auto,*">
<Grid
Grid.Row="0"
HorizontalAlignment="Center"
ColumnDefinitions="Auto,*"
Margin="0 0 0 10">
<ui:FontIcon
Grid.Column="0"
Margin="0"
HorizontalAlignment="Stretch"
FontFamily="avares://FluentAvalonia/Fonts#Symbols"
Glyph="{helpers:GlyphValueConverter Important}" />
<!-- NOTE: aligning to bottom for better visual alignment with glyph -->
<TextBlock
Grid.Column="1"
Margin="5, 0, 0, 0"
FontStyle="Italic"
VerticalAlignment="Center"
TextWrapping="Wrap"
Text="{ext:Locale CompatibilityListWarning}" />
</Grid>
<Grid Grid.Row="1" ColumnDefinitions="*,Auto,Auto">
<TextBox Name="SearchBox" Grid.Column="0" HorizontalAlignment="Stretch" Watermark="{ext:Locale CompatibilityListSearchBoxWatermark}" TextChanged="TextBox_OnTextChanged" />
<CheckBox Grid.Column="1" Margin="7, 0, 0, 0" IsChecked="{Binding OnlyShowOwnedGames}" />
<TextBlock Grid.Column="2" Margin="-10, 0, 0, 0" Text="{ext:Locale CompatibilityListOnlyShowOwnedGames}" />
</Grid>
<ScrollViewer Grid.Row="2">
<ListBox Margin="0,5, 0, 0"
Background="Transparent"
ItemsSource="{Binding CurrentEntries}">
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type local:CompatibilityEntry}">
<Grid Width="750"
Margin="5"
ColumnDefinitions="Auto,Auto,Auto,*"
Background="Transparent"
ToolTip.Tip="{Binding LocalizedLastUpdated}">
<TextBlock Grid.Column="0"
Text="{Binding GameName}"
Width="320"
TextWrapping="Wrap" />
<TextBlock Grid.Column="1"
Width="135"
Padding="7, 0, 0, 0"
FontFamily="{StaticResource JetBrainsMono}"
Text="{Binding FormattedTitleId}"
TextWrapping="Wrap" />
<TextBlock Grid.Column="2"
Padding="7, 0"
VerticalAlignment="Center"
Text="{Binding LocalizedStatus}"
Width="85"
Background="Transparent"
ToolTip.Tip="{Binding LocalizedStatusDescription}"
Foreground="{Binding Status, Converter={x:Static helpers:PlayabilityStatusConverter.Shared}}"
TextWrapping="NoWrap" />
<TextBlock Grid.Column="3"
VerticalAlignment="Center"
Text="{Binding FormattedIssueLabels}"
TextWrapping="WrapWithOverflow" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</ScrollViewer>
</Grid>
</UserControl>

View File

@@ -0,0 +1,56 @@
using Avalonia.Controls;
using Avalonia.Styling;
using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Helpers;
using System.Threading.Tasks;
namespace Ryujinx.Ava.Utilities.Compat
{
public partial class CompatibilityList : UserControl
{
public static async Task Show(string titleId = null)
{
ContentDialog contentDialog = new()
{
PrimaryButtonText = string.Empty,
SecondaryButtonText = string.Empty,
CloseButtonText = LocaleManager.Instance[LocaleKeys.SettingsButtonClose],
Content = new CompatibilityList
{
DataContext = new CompatibilityViewModel(RyujinxApp.MainWindow.ViewModel.ApplicationLibrary),
SearchBox = {
Text = titleId ?? ""
}
}
};
Style closeButton = new(x => x.Name("CloseButton"));
closeButton.Setters.Add(new Setter(WidthProperty, 80d));
Style closeButtonParent = new(x => x.Name("CommandSpace"));
closeButtonParent.Setters.Add(new Setter(HorizontalAlignmentProperty, Avalonia.Layout.HorizontalAlignment.Right));
contentDialog.Styles.Add(closeButton);
contentDialog.Styles.Add(closeButtonParent);
await ContentDialogHelper.ShowAsync(contentDialog);
}
public CompatibilityList()
{
InitializeComponent();
}
private void TextBox_OnTextChanged(object sender, TextChangedEventArgs e)
{
if (DataContext is not CompatibilityViewModel cvm)
return;
if (sender is not TextBox searchBox)
return;
cvm.Search(searchBox.Text);
}
}
}

View File

@@ -1,11 +1,10 @@
using Gommon; using Gommon;
using Ryujinx.Ava.Systems; using Ryujinx.Ava.UI.ViewModels;
using Ryujinx.Ava.Systems.AppLibrary; using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Ava.UI.Windows;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
namespace Ryujinx.Ava.UI.ViewModels namespace Ryujinx.Ava.Utilities.Compat
{ {
public class CompatibilityViewModel : BaseModel public class CompatibilityViewModel : BaseModel
{ {

View File

@@ -1,7 +1,7 @@
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Systems.Configuration namespace Ryujinx.Ava.Utilities.Configuration
{ {
[JsonConverter(typeof(TypedStringEnumConverter<AudioBackend>))] [JsonConverter(typeof(TypedStringEnumConverter<AudioBackend>))]
public enum AudioBackend public enum AudioBackend

View File

@@ -1,5 +1,5 @@
using Ryujinx.Ava.Systems.Configuration.System; using Ryujinx.Ava.Utilities.Configuration.System;
using Ryujinx.Ava.Systems.Configuration.UI; using Ryujinx.Ava.Utilities.Configuration.UI;
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;
@@ -8,14 +8,14 @@ using Ryujinx.Common.Utilities;
using Ryujinx.HLE; using Ryujinx.HLE;
using System.Collections.Generic; using System.Collections.Generic;
namespace Ryujinx.Ava.Systems.Configuration namespace Ryujinx.Ava.Utilities.Configuration
{ {
public class ConfigurationFileFormat public class ConfigurationFileFormat
{ {
/// <summary> /// <summary>
/// The current version of the file format /// The current version of the file format
/// </summary> /// </summary>
public const int CurrentVersion = 67; public const int CurrentVersion = 68;
/// <summary> /// <summary>
/// Version of the configuration file format /// Version of the configuration file format
@@ -258,6 +258,11 @@ namespace Ryujinx.Ava.Systems.Configuration
/// Enables or disables low-power profiled translation cache persistency loading /// Enables or disables low-power profiled translation cache persistency loading
/// </summary> /// </summary>
public bool EnableLowPowerPtc { get; set; } public bool EnableLowPowerPtc { get; set; }
/// <summary>
/// Clock tick scalar, in percent points (100 = 1.0).
/// </summary>
public long TickScalar { get; set; }
/// <summary> /// <summary>
/// Enables or disables guest Internet access /// Enables or disables guest Internet access

View File

@@ -1,6 +1,6 @@
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
namespace Ryujinx.Ava.Systems.Configuration namespace Ryujinx.Ava.Utilities.Configuration
{ {
internal static class ConfigurationFileFormatSettings internal static class ConfigurationFileFormatSettings
{ {

View File

@@ -1,6 +1,6 @@
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Systems.Configuration namespace Ryujinx.Ava.Utilities.Configuration
{ {
[JsonSourceGenerationOptions(WriteIndented = true)] [JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(ConfigurationFileFormat))] [JsonSerializable(typeof(ConfigurationFileFormat))]

View File

@@ -1,7 +1,7 @@
using Avalonia.Media; using Avalonia.Media;
using Gommon; using Gommon;
using Ryujinx.Ava.Systems.Configuration.System; using Ryujinx.Ava.Utilities.Configuration.System;
using Ryujinx.Ava.Systems.Configuration.UI; using Ryujinx.Ava.Utilities.Configuration.UI;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Hid.Controller; using Ryujinx.Common.Configuration.Hid.Controller;
@@ -14,7 +14,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using RyuLogger = Ryujinx.Common.Logging.Logger; using RyuLogger = Ryujinx.Common.Logging.Logger;
namespace Ryujinx.Ava.Systems.Configuration namespace Ryujinx.Ava.Utilities.Configuration
{ {
public partial class ConfigurationState public partial class ConfigurationState
{ {
@@ -94,6 +94,7 @@ namespace Ryujinx.Ava.Systems.Configuration
System.EnableDockedMode.Value = cff.DockedMode; System.EnableDockedMode.Value = cff.DockedMode;
System.EnablePtc.Value = cff.EnablePtc; System.EnablePtc.Value = cff.EnablePtc;
System.EnableLowPowerPtc.Value = cff.EnableLowPowerPtc; System.EnableLowPowerPtc.Value = cff.EnableLowPowerPtc;
System.TickScalar.Value = cff.TickScalar;
System.EnableInternetAccess.Value = cff.EnableInternetAccess; System.EnableInternetAccess.Value = cff.EnableInternetAccess;
System.EnableFsIntegrityChecks.Value = cff.EnableFsIntegrityChecks; System.EnableFsIntegrityChecks.Value = cff.EnableFsIntegrityChecks;
System.FsGlobalAccessLogMode.Value = cff.FsGlobalAccessLogMode; System.FsGlobalAccessLogMode.Value = cff.FsGlobalAccessLogMode;
@@ -441,7 +442,27 @@ namespace Ryujinx.Ava.Systems.Configuration
(64, static cff => cff.LoggingEnableAvalonia = false), (64, static cff => cff.LoggingEnableAvalonia = false),
(65, static cff => cff.UpdateCheckerType = cff.CheckUpdatesOnStart ? UpdaterType.PromptAtStartup : UpdaterType.Off), (65, static cff => cff.UpdateCheckerType = cff.CheckUpdatesOnStart ? UpdaterType.PromptAtStartup : UpdaterType.Off),
(66, static cff => cff.DisableInputWhenOutOfFocus = false), (66, static cff => cff.DisableInputWhenOutOfFocus = false),
(67, static cff => cff.FocusLostActionType = cff.DisableInputWhenOutOfFocus ? FocusLostType.BlockInput : FocusLostType.DoNothing) (67, static cff => cff.FocusLostActionType = cff.DisableInputWhenOutOfFocus ? FocusLostType.BlockInput : FocusLostType.DoNothing),
(68, static cff =>
{
cff.TickScalar = 200;
cff.Hotkeys = new KeyboardHotkeys
{
ToggleVSyncMode = cff.Hotkeys.ToggleVSyncMode,
Screenshot = cff.Hotkeys.Screenshot,
ShowUI = cff.Hotkeys.ShowUI,
Pause = cff.Hotkeys.Pause,
ToggleMute = cff.Hotkeys.ToggleMute,
ResScaleUp = cff.Hotkeys.ResScaleUp,
ResScaleDown = cff.Hotkeys.ResScaleDown,
VolumeUp = cff.Hotkeys.VolumeUp,
VolumeDown = cff.Hotkeys.VolumeDown,
CustomVSyncIntervalIncrement = cff.Hotkeys.CustomVSyncIntervalIncrement,
CustomVSyncIntervalDecrement = cff.Hotkeys.CustomVSyncIntervalDecrement,
TurboMode = Key.Unbound,
TurboModeWhileHeld = false
};
})
); );
} }
} }

View File

@@ -1,8 +1,8 @@
using ARMeilleure; using ARMeilleure;
using Gommon; using Gommon;
using LibHac.Tools.FsSystem; using Ryujinx.Ava.Utilities.AppLibrary;
using Ryujinx.Ava.Systems.Configuration.System; using Ryujinx.Ava.Utilities.Configuration.System;
using Ryujinx.Ava.Systems.Configuration.UI; using Ryujinx.Ava.Utilities.Configuration.UI;
using Ryujinx.Common; using Ryujinx.Common;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid;
@@ -11,16 +11,15 @@ using Ryujinx.Common.Helper;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
using Ryujinx.HLE; using Ryujinx.HLE;
using Ryujinx.HLE.HOS.SystemState;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using RyuLogger = Ryujinx.Common.Logging.Logger; using RyuLogger = Ryujinx.Common.Logging.Logger;
namespace Ryujinx.Ava.Systems.Configuration namespace Ryujinx.Ava.Utilities.Configuration
{ {
public partial class ConfigurationState public partial class ConfigurationState
{ {
/// <summary> /// <summary>
/// UI configuration section /// UI configuration section
/// </summary> /// </summary>
public class UISection public class UISection
@@ -336,6 +335,11 @@ namespace Ryujinx.Ava.Systems.Configuration
/// Enables or disables persistent profiled translation cache /// Enables or disables persistent profiled translation cache
/// </summary> /// </summary>
public ReactiveObject<bool> EnablePtc { get; private set; } public ReactiveObject<bool> EnablePtc { get; private set; }
/// <summary>
/// Clock tick scalar, in percent points (100 = 1.0).
/// </summary>
public ReactiveObject<long> TickScalar { get; set; }
/// <summary> /// <summary>
/// Enables or disables low-power persistent profiled translation cache loading /// Enables or disables low-power persistent profiled translation cache loading
@@ -352,10 +356,6 @@ namespace Ryujinx.Ava.Systems.Configuration
/// </summary> /// </summary>
public ReactiveObject<bool> EnableFsIntegrityChecks { get; private set; } public ReactiveObject<bool> EnableFsIntegrityChecks { get; private set; }
public IntegrityCheckLevel IntegrityCheckLevel => EnableFsIntegrityChecks
? IntegrityCheckLevel.ErrorOnInvalid
: IntegrityCheckLevel.None;
/// <summary> /// <summary>
/// Enables FS access log output to the console. Possible modes are 0-3 /// Enables FS access log output to the console. Possible modes are 0-3
/// </summary> /// </summary>
@@ -416,6 +416,15 @@ namespace Ryujinx.Ava.Systems.Configuration
EnableLowPowerPtc.LogChangesToValue(nameof(EnableLowPowerPtc)); EnableLowPowerPtc.LogChangesToValue(nameof(EnableLowPowerPtc));
EnableLowPowerPtc.Event += (_, evnt) EnableLowPowerPtc.Event += (_, evnt)
=> Optimizations.LowPower = evnt.NewValue; => Optimizations.LowPower = evnt.NewValue;
TickScalar = new ReactiveObject<long>();
TickScalar.LogChangesToValue(nameof(TickScalar));
TickScalar.Event += (_, evnt) =>
{
if (Switch.Shared is null)
return;
Switch.Shared.Configuration.TickScalar = evnt.NewValue;
};
EnableInternetAccess = new ReactiveObject<bool>(); EnableInternetAccess = new ReactiveObject<bool>();
EnableInternetAccess.LogChangesToValue(nameof(EnableInternetAccess)); EnableInternetAccess.LogChangesToValue(nameof(EnableInternetAccess));
EnableFsIntegrityChecks = new ReactiveObject<bool>(); EnableFsIntegrityChecks = new ReactiveObject<bool>();
@@ -843,35 +852,5 @@ namespace Ryujinx.Ava.Systems.Configuration
EnableHardwareAcceleration = new ReactiveObject<bool>(); EnableHardwareAcceleration = new ReactiveObject<bool>();
HideCursor = new ReactiveObject<HideCursorMode>(); HideCursor = new ReactiveObject<HideCursorMode>();
} }
public HleConfiguration CreateHleConfiguration() =>
new(
System.DramSize,
System.Language.Value.ToHLE(),
System.Region.Value.ToHLE(),
Graphics.VSyncMode,
System.EnableDockedMode,
System.EnablePtc,
System.EnableInternetAccess,
System.EnableFsIntegrityChecks
? IntegrityCheckLevel.ErrorOnInvalid
: IntegrityCheckLevel.None,
System.FsGlobalAccessLogMode,
System.MatchSystemTime
? 0
: System.SystemTimeOffset,
System.TimeZone,
System.MemoryManagerMode,
System.IgnoreMissingServices,
Graphics.AspectRatio,
System.AudioVolume,
System.UseHypervisor,
Multiplayer.LanInterfaceId,
Multiplayer.Mode,
Multiplayer.DisableP2p,
Multiplayer.LdnPassphrase,
Instance.Multiplayer.GetLdnServer(),
Instance.Graphics.CustomVSyncInterval,
Instance.Hacks.ShowDirtyHacks ? Instance.Hacks.EnabledHacks : null);
} }
} }

View File

@@ -1,5 +1,5 @@
using Ryujinx.Ava.Systems.Configuration.System; using Ryujinx.Ava.Utilities.Configuration.System;
using Ryujinx.Ava.Systems.Configuration.UI; using Ryujinx.Ava.Utilities.Configuration.UI;
using Ryujinx.Common.Configuration; using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid; using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Hid.Keyboard; using Ryujinx.Common.Configuration.Hid.Keyboard;
@@ -9,7 +9,7 @@ using Ryujinx.HLE;
using System; using System;
using System.Linq; using System.Linq;
namespace Ryujinx.Ava.Systems.Configuration namespace Ryujinx.Ava.Utilities.Configuration
{ {
public partial class ConfigurationState public partial class ConfigurationState
{ {
@@ -73,6 +73,7 @@ namespace Ryujinx.Ava.Systems.Configuration
EnableColorSpacePassthrough = Graphics.EnableColorSpacePassthrough, EnableColorSpacePassthrough = Graphics.EnableColorSpacePassthrough,
EnablePtc = System.EnablePtc, EnablePtc = System.EnablePtc,
EnableLowPowerPtc = System.EnableLowPowerPtc, EnableLowPowerPtc = System.EnableLowPowerPtc,
TickScalar = System.TickScalar,
EnableInternetAccess = System.EnableInternetAccess, EnableInternetAccess = System.EnableInternetAccess,
EnableFsIntegrityChecks = System.EnableFsIntegrityChecks, EnableFsIntegrityChecks = System.EnableFsIntegrityChecks,
FsGlobalAccessLogMode = System.FsGlobalAccessLogMode, FsGlobalAccessLogMode = System.FsGlobalAccessLogMode,
@@ -261,6 +262,10 @@ namespace Ryujinx.Ava.Systems.Configuration
ResScaleDown = Key.Unbound, ResScaleDown = Key.Unbound,
VolumeUp = Key.Unbound, VolumeUp = Key.Unbound,
VolumeDown = Key.Unbound, VolumeDown = Key.Unbound,
CustomVSyncIntervalIncrement = Key.Unbound,
CustomVSyncIntervalDecrement = Key.Unbound,
TurboMode = Key.Unbound,
TurboModeWhileHeld = false
}; };
Hid.RainbowSpeed.Value = 1f; Hid.RainbowSpeed.Value = 1f;
Hid.InputConfig.Value = Hid.InputConfig.Value =

View File

@@ -1,8 +1,8 @@
using System; using System;
using static Ryujinx.Ava.Systems.Configuration.ConfigurationState.UISection; using static Ryujinx.Ava.Utilities.Configuration.ConfigurationState.UISection;
namespace Ryujinx.Ava.Systems.Configuration namespace Ryujinx.Ava.Utilities.Configuration
{ {
public enum FileTypes public enum FileTypes
{ {

View File

@@ -4,7 +4,7 @@ using Ryujinx.Common.Logging.Targets;
using System; using System;
using System.IO; using System.IO;
namespace Ryujinx.Ava.Systems.Configuration namespace Ryujinx.Ava.Utilities.Configuration
{ {
public static class LoggerModule public static class LoggerModule
{ {

View File

@@ -1,7 +1,7 @@
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Systems.Configuration.System namespace Ryujinx.Ava.Utilities.Configuration.System
{ {
[JsonConverter(typeof(TypedStringEnumConverter<Language>))] [JsonConverter(typeof(TypedStringEnumConverter<Language>))]
public enum Language public enum Language
@@ -25,13 +25,4 @@ namespace Ryujinx.Ava.Systems.Configuration.System
TraditionalChinese, TraditionalChinese,
BrazilianPortuguese, BrazilianPortuguese,
} }
public static class LanguageEnumHelper
{
public static Language ToUI(this HLE.HOS.SystemState.SystemLanguage hleLanguage)
=> (Language)hleLanguage;
public static HLE.HOS.SystemState.SystemLanguage ToHLE(this Language uiLanguage)
=> (HLE.HOS.SystemState.SystemLanguage)uiLanguage;
}
} }

View File

@@ -0,0 +1,17 @@
using Ryujinx.Common.Utilities;
using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Utilities.Configuration.System
{
[JsonConverter(typeof(TypedStringEnumConverter<Region>))]
public enum Region
{
Japan,
USA,
Europe,
Australia,
China,
Korea,
Taiwan,
}
}

View File

@@ -1,4 +1,4 @@
namespace Ryujinx.Ava.Systems.Configuration.UI namespace Ryujinx.Ava.Utilities.Configuration.UI
{ {
public struct ColumnSort public struct ColumnSort
{ {

View File

@@ -1,7 +1,7 @@
using Ryujinx.Common.Utilities; using Ryujinx.Common.Utilities;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
namespace Ryujinx.Ava.Systems.Configuration.UI namespace Ryujinx.Ava.Utilities.Configuration.UI
{ {
[JsonConverter(typeof(TypedStringEnumConverter<FocusLostType>))] [JsonConverter(typeof(TypedStringEnumConverter<FocusLostType>))]
public enum FocusLostType public enum FocusLostType

View File

@@ -1,4 +1,4 @@
namespace Ryujinx.Ava.Systems.Configuration.UI namespace Ryujinx.Ava.Utilities.Configuration.UI
{ {
public struct GuiColumns public struct GuiColumns
{ {

View File

@@ -1,4 +1,4 @@
namespace Ryujinx.Ava.Systems.Configuration.UI namespace Ryujinx.Ava.Utilities.Configuration.UI
{ {
public struct ShownFileTypes public struct ShownFileTypes
{ {

Some files were not shown because too many files have changed in this diff Show More