diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/LdnMitmClient.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/LdnMitmClient.cs index 40697d122..35fc783c2 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/LdnMitmClient.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnMitm/LdnMitmClient.cs @@ -19,7 +19,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.LdnMitm private readonly LanDiscovery _lanDiscovery; - public LdnMitmClient(HLEConfiguration config) + public LdnMitmClient(HleConfiguration config) { UnicastIPAddressInformation localIpInterface = NetworkHelpers.GetLocalInterface(config.MultiplayerLanInterfaceId).Item2; diff --git a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnRyu/LdnMasterProxyClient.cs b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnRyu/LdnMasterProxyClient.cs index 712967180..c2bbcb471 100644 --- a/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnRyu/LdnMasterProxyClient.cs +++ b/src/Ryujinx.HLE/HOS/Services/Ldn/UserServiceCreator/LdnRyu/LdnMasterProxyClient.cs @@ -51,13 +51,13 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.LdnRyu private string _passphrase; private byte[] _gameVersion = new byte[0x10]; - private readonly HLEConfiguration _config; + private readonly HleConfiguration _config; public event EventHandler NetworkChange; 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()) { diff --git a/src/Ryujinx.HLE/HLEConfiguration.cs b/src/Ryujinx.HLE/HleConfiguration.cs similarity index 88% rename from src/Ryujinx.HLE/HLEConfiguration.cs rename to src/Ryujinx.HLE/HleConfiguration.cs index 0b7ae3974..97835033e 100644 --- a/src/Ryujinx.HLE/HLEConfiguration.cs +++ b/src/Ryujinx.HLE/HleConfiguration.cs @@ -15,55 +15,55 @@ namespace Ryujinx.HLE /// /// HLE configuration. /// - public class HLEConfiguration + public class HleConfiguration { /// /// The virtual file system used by the FS service. /// /// This cannot be changed after instantiation. - internal readonly VirtualFileSystem VirtualFileSystem; + internal VirtualFileSystem VirtualFileSystem { get; private set; } /// /// The manager for handling a LibHac Horizon instance. /// /// This cannot be changed after instantiation. - internal readonly LibHacHorizonManager LibHacHorizonManager; + internal LibHacHorizonManager LibHacHorizonManager { get; private set; } /// /// The account manager used by the account service. /// /// This cannot be changed after instantiation. - internal readonly AccountManager AccountManager; + internal AccountManager AccountManager { get; private set; } /// /// The content manager used by the NCM service. /// /// This cannot be changed after instantiation. - internal readonly ContentManager ContentManager; + internal ContentManager ContentManager { get; private set; } /// /// The persistent information between run for multi-application capabilities. /// /// This cannot be changed after instantiation. - public readonly UserChannelPersistence UserChannelPersistence; + public UserChannelPersistence UserChannelPersistence { get; private set; } /// /// The GPU renderer to use for all GPU operations. /// /// This cannot be changed after instantiation. - internal readonly IRenderer GpuRenderer; + internal IRenderer GpuRenderer { get; private set; } /// /// The audio device driver to use for all audio operations. /// /// This cannot be changed after instantiation. - internal readonly IHardwareDeviceDriver AudioDeviceDriver; + internal IHardwareDeviceDriver AudioDeviceDriver { get; private set; } /// /// The handler for various UI related operations needed outside of HLE. /// /// This cannot be changed after instantiation. - internal readonly IHostUIHandler HostUIHandler; + internal IHostUIHandler HostUIHandler { get; private set; } /// /// Control the memory configuration used by the emulation context. @@ -195,15 +195,7 @@ namespace Ryujinx.HLE /// This cannot be changed after instantiation. public EnabledDirtyHack[] Hacks { internal get; set; } - public HLEConfiguration(VirtualFileSystem virtualFileSystem, - LibHacHorizonManager libHacHorizonManager, - ContentManager contentManager, - AccountManager accountManager, - UserChannelPersistence userChannelPersistence, - IRenderer gpuRenderer, - IHardwareDeviceDriver audioDeviceDriver, - MemoryConfiguration memoryConfiguration, - IHostUIHandler hostUIHandler, + public HleConfiguration(MemoryConfiguration memoryConfiguration, SystemLanguage systemLanguage, RegionCode region, VSyncMode vSyncMode, @@ -227,15 +219,7 @@ namespace Ryujinx.HLE int customVSyncInterval, EnabledDirtyHack[] dirtyHacks = null) { - VirtualFileSystem = virtualFileSystem; - LibHacHorizonManager = libHacHorizonManager; - AccountManager = accountManager; - ContentManager = contentManager; - UserChannelPersistence = userChannelPersistence; - GpuRenderer = gpuRenderer; - AudioDeviceDriver = audioDeviceDriver; MemoryConfiguration = memoryConfiguration; - HostUIHandler = hostUIHandler; SystemLanguage = systemLanguage; Region = region; VSyncMode = vSyncMode; @@ -259,5 +243,30 @@ namespace Ryujinx.HLE MultiplayerLdnServer = multiplayerLdnServer; Hacks = dirtyHacks ?? []; } + + /// + /// Set the pre-configured services to use for this instance. + /// + 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; + } } } diff --git a/src/Ryujinx.HLE/Switch.cs b/src/Ryujinx.HLE/Switch.cs index 86b04061e..df5b48103 100644 --- a/src/Ryujinx.HLE/Switch.cs +++ b/src/Ryujinx.HLE/Switch.cs @@ -20,7 +20,7 @@ namespace Ryujinx.HLE { public static Switch Shared { get; private set; } - public HLEConfiguration Configuration { get; } + public HleConfiguration Configuration { get; } public IHardwareDeviceDriver AudioDeviceDriver { get; } public MemoryBlock Memory { get; } public GpuContext Gpu { get; } @@ -44,7 +44,7 @@ namespace Ryujinx.HLE public DirtyHacks DirtyHacks { get; } - public Switch(HLEConfiguration configuration) + public Switch(HleConfiguration configuration) { ArgumentNullException.ThrowIfNull(configuration.GpuRenderer); ArgumentNullException.ThrowIfNull(configuration.AudioDeviceDriver); @@ -94,16 +94,20 @@ namespace Ryujinx.HLE Gpu.GPFifo.DispatchCalls(); } - public void IncrementCustomVSyncInterval() + public int IncrementCustomVSyncInterval() { CustomVSyncInterval += 1; UpdateVSyncInterval(); + + return CustomVSyncInterval; } - public void DecrementCustomVSyncInterval() + public int DecrementCustomVSyncInterval() { CustomVSyncInterval -= 1; UpdateVSyncInterval(); + + return CustomVSyncInterval; } public void UpdateVSyncInterval() diff --git a/src/Ryujinx/AppHost.cs b/src/Ryujinx/AppHost.cs index b741eb977..95370fdc4 100644 --- a/src/Ryujinx/AppHost.cs +++ b/src/Ryujinx/AppHost.cs @@ -913,42 +913,18 @@ namespace Ryujinx.Ava Logger.Info?.PrintMsg(LogClass.Gpu, $"Backend Threading ({threadingMode}): {isGALThreaded}"); // Initialize Configuration. - MemoryConfiguration memoryConfiguration = ConfigurationState.Instance.System.DramSize.Value; - - Device = new Switch(new HLEConfiguration( - VirtualFileSystem, - _viewModel.LibHacHorizonManager, - ContentManager, - _accountManager, - _userChannelPersistence, - renderer, - 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.Value, - ConfigurationState.Instance.Hacks.ShowDirtyHacks ? ConfigurationState.Instance.Hacks.EnabledHacks : null)); + Device = new Switch(ConfigurationState.Instance.CreateHleConfiguration() + .Configure( + VirtualFileSystem, + _viewModel.LibHacHorizonManager, + ContentManager, + _accountManager, + _userChannelPersistence, + renderer, + InitializeAudio(), + _viewModel.UiHandler + ) + ); } private static IHardwareDeviceDriver InitializeAudio() @@ -1182,6 +1158,9 @@ namespace Ryujinx.Ava private void UpdateShaderCount() { + if (_displayCount is 0 && _renderer.ProgramCount is 0) + return; + // If there is a mismatch between total program compile and previous count // this means new shaders have been compiled and should be displayed. if (_renderer.ProgramCount != _previousCount) @@ -1255,12 +1234,10 @@ namespace Ryujinx.Ava VSyncModeToggle(); break; case KeyboardHotkeyState.CustomVSyncIntervalDecrement: - Device.DecrementCustomVSyncInterval(); - _viewModel.CustomVSyncInterval -= 1; + _viewModel.CustomVSyncInterval = Device.DecrementCustomVSyncInterval(); break; case KeyboardHotkeyState.CustomVSyncIntervalIncrement: - Device.IncrementCustomVSyncInterval(); - _viewModel.CustomVSyncInterval += 1; + _viewModel.CustomVSyncInterval = Device.IncrementCustomVSyncInterval(); break; case KeyboardHotkeyState.Screenshot: ScreenshotRequested = true; diff --git a/src/Ryujinx/Headless/HeadlessRyujinx.Init.cs b/src/Ryujinx/Headless/HeadlessRyujinx.Init.cs index 3ebfee751..f8936efd5 100644 --- a/src/Ryujinx/Headless/HeadlessRyujinx.Init.cs +++ b/src/Ryujinx/Headless/HeadlessRyujinx.Init.cs @@ -323,38 +323,42 @@ namespace Ryujinx.Headless renderer = new ThreadedRenderer(renderer); } - HLEConfiguration configuration = new(_virtualFileSystem, - _libHacHorizonManager, - _contentManager, - _accountManager, - _userChannelPersistence, - renderer, - new SDL2HardwareDeviceDriver(), - options.DramSize, - window, - options.SystemLanguage, - options.SystemRegion, - options.VSyncMode, - !options.DisableDockedMode, - !options.DisablePTC, - options.EnableInternetAccess, - !options.DisableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None, - options.FsGlobalAccessLogMode, - options.SystemTimeOffset, - options.SystemTimeZone, - options.MemoryManagerMode, - options.IgnoreMissingServices, - options.AspectRatio, - options.AudioVolume, - options.UseHypervisor ?? true, - options.MultiplayerLanInterfaceId, - Common.Configuration.Multiplayer.MultiplayerMode.Disabled, - false, - string.Empty, - string.Empty, - options.CustomVSyncInterval); - - return new Switch(configuration); + return new Switch( + new HleConfiguration( + options.DramSize, + options.SystemLanguage, + options.SystemRegion, + options.VSyncMode, + !options.DisableDockedMode, + !options.DisablePTC, + options.EnableInternetAccess, + !options.DisableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None, + options.FsGlobalAccessLogMode, + options.SystemTimeOffset, + options.SystemTimeZone, + options.MemoryManagerMode, + options.IgnoreMissingServices, + options.AspectRatio, + options.AudioVolume, + options.UseHypervisor ?? true, + options.MultiplayerLanInterfaceId, + Common.Configuration.Multiplayer.MultiplayerMode.Disabled, + false, + string.Empty, + string.Empty, + options.CustomVSyncInterval + ) + .Configure( + _virtualFileSystem, + _libHacHorizonManager, + _contentManager, + _accountManager, + _userChannelPersistence, + renderer, + new SDL2HardwareDeviceDriver(), + window + ) + ); } } } diff --git a/src/Ryujinx/Utilities/Configuration/ConfigurationState.Model.cs b/src/Ryujinx/Utilities/Configuration/ConfigurationState.Model.cs index ead99fbac..2ebf5725b 100644 --- a/src/Ryujinx/Utilities/Configuration/ConfigurationState.Model.cs +++ b/src/Ryujinx/Utilities/Configuration/ConfigurationState.Model.cs @@ -1,6 +1,6 @@ using ARMeilleure; using Gommon; -using Ryujinx.Ava.Utilities.AppLibrary; +using LibHac.Tools.FsSystem; using Ryujinx.Ava.Utilities.Configuration.System; using Ryujinx.Ava.Utilities.Configuration.UI; using Ryujinx.Common; @@ -11,6 +11,7 @@ using Ryujinx.Common.Helper; using Ryujinx.Common.Logging; using Ryujinx.Common.Utilities; using Ryujinx.HLE; +using Ryujinx.HLE.HOS.SystemState; using System.Collections.Generic; using System.Linq; using RyuLogger = Ryujinx.Common.Logging.Logger; @@ -19,7 +20,7 @@ namespace Ryujinx.Ava.Utilities.Configuration { public partial class ConfigurationState { - /// + /// /// UI configuration section /// public class UISection @@ -838,5 +839,35 @@ namespace Ryujinx.Ava.Utilities.Configuration EnableHardwareAcceleration = new ReactiveObject(); HideCursor = new ReactiveObject(); } + + public HleConfiguration CreateHleConfiguration() => + new( + System.DramSize, + (SystemLanguage)System.Language.Value, + (RegionCode)System.Region.Value, + 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); } } diff --git a/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs b/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs index 4fdf7c4f0..5fb313cad 100644 --- a/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs +++ b/src/Ryujinx/Utilities/Configuration/ConfigurationState.cs @@ -327,5 +327,5 @@ namespace Ryujinx.Ava.Utilities.Configuration return GraphicsBackend.OpenGl; } - } - } + } +}