diff options
author | Mary <me@thog.eu> | 2021-05-16 17:12:14 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-16 17:12:14 +0200 |
commit | bec67dbef7a505fb5c4a1734be1517f67474fb4d (patch) | |
tree | 3a0353d8e0fce1c8e02544b465eb1d3aacadf125 /Ryujinx.HLE | |
parent | f48828351c759ef63e015ca9806406fab278c458 (diff) |
misc: Move configuration management to the Ryujinx project (#2269)
* Decouple configuration from Ryujinx.HLE and Ryujinx.Input
* Move Configuration to the Ryujinx project
Diffstat (limited to 'Ryujinx.HLE')
-rw-r--r-- | Ryujinx.HLE/FileSystem/Content/ContentManager.cs | 28 | ||||
-rw-r--r-- | Ryujinx.HLE/HLEConfiguration.cs | 179 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/ApplicationLoader.cs | 67 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Horizon.cs | 27 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/IApplicationFunctions.cs | 8 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs | 2 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Services/Hid/Hid.cs | 7 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Services/IpcService.cs | 4 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Services/ServiceConfiguration.cs | 7 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Services/Sm/IUserInterface.cs | 2 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs | 3 | ||||
-rw-r--r-- | Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneContentManager.cs | 9 | ||||
-rw-r--r-- | Ryujinx.HLE/Switch.cs | 106 |
13 files changed, 277 insertions, 172 deletions
diff --git a/Ryujinx.HLE/FileSystem/Content/ContentManager.cs b/Ryujinx.HLE/FileSystem/Content/ContentManager.cs index f2b62eef..a18838ab 100644 --- a/Ryujinx.HLE/FileSystem/Content/ContentManager.cs +++ b/Ryujinx.HLE/FileSystem/Content/ContentManager.cs @@ -197,7 +197,7 @@ namespace Ryujinx.HLE.FileSystem.Content } // fs must contain AOC nca files in its root - public void AddAocData(IFileSystem fs, string containerPath, ulong aocBaseId) + public void AddAocData(IFileSystem fs, string containerPath, ulong aocBaseId, IntegrityCheckLevel integrityCheckLevel) { _virtualFileSystem.ImportTickets(fs); @@ -214,7 +214,7 @@ namespace Ryujinx.HLE.FileSystem.Content continue; } - using var pfs0 = nca.OpenFileSystem(0, Switch.GetIntegrityCheckLevel()); + using var pfs0 = nca.OpenFileSystem(0, integrityCheckLevel); pfs0.OpenFile(out IFile cnmtFile, pfs0.EnumerateEntries().Single().FullPath.ToU8Span(), OpenMode.Read); @@ -265,7 +265,7 @@ namespace Ryujinx.HLE.FileSystem.Content public IList<ulong> GetAocTitleIds() => _aocData.Where(e => e.Value.Enabled).Select(e => e.Key).ToList(); - public bool GetAocDataStorage(ulong aocTitleId, out IStorage aocStorage) + public bool GetAocDataStorage(ulong aocTitleId, out IStorage aocStorage, IntegrityCheckLevel integrityCheckLevel) { aocStorage = null; @@ -289,7 +289,7 @@ namespace Ryujinx.HLE.FileSystem.Content return false; // Print error? } - aocStorage = new Nca(_virtualFileSystem.KeySet, ncaFile.AsStorage()).OpenStorage(NcaSectionType.Data, Switch.GetIntegrityCheckLevel()); + aocStorage = new Nca(_virtualFileSystem.KeySet, ncaFile.AsStorage()).OpenStorage(NcaSectionType.Data, integrityCheckLevel); return true; } @@ -710,8 +710,6 @@ namespace Ryujinx.HLE.FileSystem.Content SystemVersion VerifyAndGetVersionZip(ZipArchive archive) { - IntegrityCheckLevel integrityCheckLevel = Switch.GetIntegrityCheckLevel(); - SystemVersion systemVersion = null; foreach (var entry in archive.Entries) @@ -751,7 +749,7 @@ namespace Ryujinx.HLE.FileSystem.Content { Nca metaNca = new Nca(_virtualFileSystem.KeySet, ncaStream.AsStorage()); - IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, integrityCheckLevel); + IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid); string cnmtPath = fs.EnumerateEntries("/", "*.cnmt").Single().FullPath; @@ -781,7 +779,7 @@ namespace Ryujinx.HLE.FileSystem.Content { Nca nca = new Nca(_virtualFileSystem.KeySet, ncaStream.AsStorage()); - var romfs = nca.OpenFileSystem(NcaSectionType.Data, integrityCheckLevel); + var romfs = nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid); if (romfs.OpenFile(out IFile systemVersionFile, "/file".ToU8Span(), OpenMode.Read).IsSuccess()) { @@ -816,7 +814,7 @@ namespace Ryujinx.HLE.FileSystem.Content { Nca metaNca = new Nca(_virtualFileSystem.KeySet, metaNcaStream.AsStorage()); - IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, integrityCheckLevel); + IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid); string cnmtPath = fs.EnumerateEntries("/", "*.cnmt").Single().FullPath; @@ -873,8 +871,6 @@ namespace Ryujinx.HLE.FileSystem.Content SystemVersion VerifyAndGetVersion(IFileSystem filesystem) { - IntegrityCheckLevel integrityCheckLevel = Switch.GetIntegrityCheckLevel(); - SystemVersion systemVersion = null; CnmtContentMetaEntry[] metaEntries = null; @@ -887,7 +883,7 @@ namespace Ryujinx.HLE.FileSystem.Content if (nca.Header.TitleId == SystemUpdateTitleId && nca.Header.ContentType == NcaContentType.Meta) { - IFileSystem fs = nca.OpenFileSystem(NcaSectionType.Data, integrityCheckLevel); + IFileSystem fs = nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid); string cnmtPath = fs.EnumerateEntries("/", "*.cnmt").Single().FullPath; @@ -905,7 +901,7 @@ namespace Ryujinx.HLE.FileSystem.Content } else if (nca.Header.TitleId == SystemVersionTitleId && nca.Header.ContentType == NcaContentType.Data) { - var romfs = nca.OpenFileSystem(NcaSectionType.Data, integrityCheckLevel); + var romfs = nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid); if (romfs.OpenFile(out IFile systemVersionFile, "/file".ToU8Span(), OpenMode.Read).IsSuccess()) { @@ -952,7 +948,7 @@ namespace Ryujinx.HLE.FileSystem.Content Nca metaNca = new Nca(_virtualFileSystem.KeySet, metaStorage); - IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, integrityCheckLevel); + IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid); string cnmtPath = fs.EnumerateEntries("/", "*.cnmt").Single().FullPath; @@ -1004,8 +1000,6 @@ namespace Ryujinx.HLE.FileSystem.Content public SystemVersion GetCurrentFirmwareVersion() { - IntegrityCheckLevel integrityCheckLevel = Switch.GetIntegrityCheckLevel(); - LoadEntries(); lock (_lock) @@ -1024,7 +1018,7 @@ namespace Ryujinx.HLE.FileSystem.Content if (nca.Header.TitleId == SystemVersionTitleId && nca.Header.ContentType == NcaContentType.Data) { - var romfs = nca.OpenFileSystem(NcaSectionType.Data, integrityCheckLevel); + var romfs = nca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.ErrorOnInvalid); if (romfs.OpenFile(out IFile systemVersionFile, "/file".ToU8Span(), OpenMode.Read).IsSuccess()) { diff --git a/Ryujinx.HLE/HLEConfiguration.cs b/Ryujinx.HLE/HLEConfiguration.cs new file mode 100644 index 00000000..00c79169 --- /dev/null +++ b/Ryujinx.HLE/HLEConfiguration.cs @@ -0,0 +1,179 @@ +using LibHac.FsSystem; +using Ryujinx.Audio.Integration; +using Ryujinx.Common; +using Ryujinx.Common.Configuration; +using Ryujinx.Common.Configuration.Hid; +using Ryujinx.Graphics.GAL; +using Ryujinx.HLE.FileSystem; +using Ryujinx.HLE.FileSystem.Content; +using Ryujinx.HLE.HOS; +using Ryujinx.HLE.HOS.Services.Account.Acc; +using Ryujinx.HLE.HOS.SystemState; +using System; +using System.Collections.Generic; + +namespace Ryujinx.HLE +{ + /// <summary> + /// HLE configuration. + /// </summary> + public class HLEConfiguration + { + /// <summary> + /// The virtual file system used by the FS service. + /// </summary> + /// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks> + internal readonly VirtualFileSystem VirtualFileSystem; + + /// <summary> + /// The account manager used by the account service. + /// </summary> + /// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks> + internal readonly AccountManager AccountManager; + + /// <summary> + /// The content manager used by the NCM service. + /// </summary> + /// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks> + internal readonly ContentManager ContentManager; + + /// <summary> + /// The persistant information between run for multi-application capabilities. + /// </summary> + /// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks> + public readonly UserChannelPersistence UserChannelPersistence; + + /// <summary> + /// The GPU renderer to use for all GPU operations. + /// </summary> + /// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks> + internal readonly IRenderer GpuRenderer; + + /// <summary> + /// The audio device driver to use for all audio operations. + /// </summary> + /// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks> + internal readonly IHardwareDeviceDriver AudioDeviceDriver; + + /// <summary> + /// The handler for various UI related operations needed outside of HLE. + /// </summary> + /// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks> + internal readonly IHostUiHandler HostUiHandler; + + /// <summary> + /// Control the memory configuration used by the emulation context. + /// </summary> + /// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks> + internal readonly MemoryConfiguration MemoryConfiguration; + + /// <summary> + /// The system language to use in the settings service. + /// </summary> + /// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks> + internal readonly SystemLanguage SystemLanguage; + + /// <summary> + /// The system region to use in the settings service. + /// </summary> + /// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks> + internal readonly RegionCode Region; + + /// <summary> + /// Control the initial state of the vertical sync in the SurfaceFlinger service. + /// </summary> + internal readonly bool EnableVsync; + + /// <summary> + /// Control the initial state of the docked mode. + /// </summary> + internal readonly bool EnableDockedMode; + + /// <summary> + /// Control if the Profiled Translation Cache (PTC) should be used. + /// </summary> + internal readonly bool EnablePtc; + + /// <summary> + /// Control LibHac's integrity check level. + /// </summary> + /// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks> + internal readonly IntegrityCheckLevel FsIntegrityCheckLevel; + + /// <summary> + /// Control LibHac's global access logging level. Value must be between 0 and 3. + /// </summary> + /// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks> + internal readonly int FsGlobalAccessLogMode; + + /// <summary> + /// The system time offset to apply to the time service steady and local clocks. + /// </summary> + /// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks> + internal readonly long SystemTimeOffset; + + /// <summary> + /// The system timezone used by the time service. + /// </summary> + /// <remarks>This cannot be changed after <see cref="Switch"/> instantiation.</remarks> + internal readonly string TimeZone; + + /// <summary> + /// Control the inital state of the ignore missing services setting. + /// If this is set to true, when a missing service is encountered, it will try to automatically handle it instead of throwing an exception. + /// </summary> + /// TODO: Update this again. + public bool IgnoreMissingServices { internal get; set; } + + /// <summary> + /// Aspect Ratio applied to the renderer window by the SurfaceFlinger service. + /// </summary> + public AspectRatio AspectRatio { internal get; set; } + + /// <summary> + /// An action called when HLE force a refresh of output after docked mode changed. + /// </summary> + public Action RefreshInputConfig { internal get; set; } + + public HLEConfiguration(VirtualFileSystem virtualFileSystem, + ContentManager contentManager, + AccountManager accountManager, + UserChannelPersistence userChannelPersistence, + IRenderer gpuRenderer, + IHardwareDeviceDriver audioDeviceDriver, + MemoryConfiguration memoryConfiguration, + IHostUiHandler hostUiHandler, + SystemLanguage systemLanguage, + RegionCode region, + bool enableVsync, + bool enableDockedMode, + bool enablePtc, + IntegrityCheckLevel fsIntegrityCheckLevel, + int fsGlobalAccessLogMode, + long systemTimeOffset, + string timeZone, + bool ignoreMissingServices, + AspectRatio aspectRatio) + { + VirtualFileSystem = virtualFileSystem; + AccountManager = accountManager; + ContentManager = contentManager; + UserChannelPersistence = userChannelPersistence; + GpuRenderer = gpuRenderer; + AudioDeviceDriver = audioDeviceDriver; + MemoryConfiguration = memoryConfiguration; + HostUiHandler = hostUiHandler; + SystemLanguage = systemLanguage; + Region = region; + EnableVsync = enableVsync; + EnableDockedMode = enableDockedMode; + EnablePtc = enablePtc; + FsIntegrityCheckLevel = fsIntegrityCheckLevel; + FsGlobalAccessLogMode = fsGlobalAccessLogMode; + SystemTimeOffset = systemTimeOffset; + TimeZone = timeZone; + IgnoreMissingServices = ignoreMissingServices; + AspectRatio = aspectRatio; + } + } +} diff --git a/Ryujinx.HLE/HOS/ApplicationLoader.cs b/Ryujinx.HLE/HOS/ApplicationLoader.cs index 05db567a..3832dd3e 100644 --- a/Ryujinx.HLE/HOS/ApplicationLoader.cs +++ b/Ryujinx.HLE/HOS/ApplicationLoader.cs @@ -10,7 +10,6 @@ using LibHac.Ns; using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; using Ryujinx.HLE.FileSystem; -using Ryujinx.HLE.FileSystem.Content; using Ryujinx.HLE.HOS.Kernel.Process; using Ryujinx.HLE.Loaders.Executables; using Ryujinx.HLE.Loaders.Npdm; @@ -49,10 +48,7 @@ namespace Ryujinx.HLE.HOS "sdk" }; - private readonly Switch _device; - private readonly ContentManager _contentManager; - private readonly VirtualFileSystem _fileSystem; - + private readonly Switch _device; private string _titleName; private string _displayVersion; private BlitStruct<ApplicationControlProperty> _controlData; @@ -66,12 +62,9 @@ namespace Ryujinx.HLE.HOS public string TitleIdText => TitleId.ToString("x16"); - public ApplicationLoader(Switch device, VirtualFileSystem fileSystem, ContentManager contentManager) + public ApplicationLoader(Switch device) { - _device = device; - _contentManager = contentManager; - _fileSystem = fileSystem; - + _device = device; _controlData = new BlitStruct<ApplicationControlProperty>(1); } @@ -79,14 +72,14 @@ namespace Ryujinx.HLE.HOS { if (romFsFile != null) { - _fileSystem.LoadRomFs(romFsFile); + _device.Configuration.VirtualFileSystem.LoadRomFs(romFsFile); } LocalFileSystem codeFs = new LocalFileSystem(exeFsDir); Npdm metaData = ReadNpdm(codeFs); - _fileSystem.ModLoader.CollectMods(new[] { TitleId }, _fileSystem.ModLoader.GetModsBasePath()); + _device.Configuration.VirtualFileSystem.ModLoader.CollectMods(new[] { TitleId }, _device.Configuration.VirtualFileSystem.ModLoader.GetModsBasePath()); if (TitleId != 0) { @@ -209,7 +202,7 @@ namespace Ryujinx.HLE.HOS public void LoadXci(string xciFile) { FileStream file = new FileStream(xciFile, FileMode.Open, FileAccess.Read); - Xci xci = new Xci(_fileSystem.KeySet, file.AsStorage()); + Xci xci = new Xci(_device.Configuration.VirtualFileSystem.KeySet, file.AsStorage()); if (!xci.HasPartition(XciPartitionType.Secure)) { @@ -226,7 +219,7 @@ namespace Ryujinx.HLE.HOS try { - (mainNca, patchNca, controlNca) = GetGameData(_fileSystem, securePartition, _device.UserChannelPersistence.Index); + (mainNca, patchNca, controlNca) = GetGameData(_device.Configuration.VirtualFileSystem, securePartition, _device.Configuration.UserChannelPersistence.Index); } catch (Exception e) { @@ -242,9 +235,9 @@ namespace Ryujinx.HLE.HOS return; } - _contentManager.LoadEntries(_device); - _contentManager.ClearAocData(); - _contentManager.AddAocData(securePartition, xciFile, mainNca.Header.TitleId); + _device.Configuration.ContentManager.LoadEntries(_device); + _device.Configuration.ContentManager.ClearAocData(); + _device.Configuration.ContentManager.AddAocData(securePartition, xciFile, mainNca.Header.TitleId, _device.Configuration.FsIntegrityCheckLevel); LoadNca(mainNca, patchNca, controlNca); } @@ -260,7 +253,7 @@ namespace Ryujinx.HLE.HOS try { - (mainNca, patchNca, controlNca) = GetGameData(_fileSystem, nsp, _device.UserChannelPersistence.Index); + (mainNca, patchNca, controlNca) = GetGameData(_device.Configuration.VirtualFileSystem, nsp, _device.Configuration.UserChannelPersistence.Index); } catch (Exception e) { @@ -278,8 +271,8 @@ namespace Ryujinx.HLE.HOS if (mainNca != null) { - _contentManager.ClearAocData(); - _contentManager.AddAocData(nsp, nspFile, mainNca.Header.TitleId); + _device.Configuration.ContentManager.ClearAocData(); + _device.Configuration.ContentManager.AddAocData(nsp, nspFile, mainNca.Header.TitleId, _device.Configuration.FsIntegrityCheckLevel); LoadNca(mainNca, patchNca, controlNca); @@ -293,7 +286,7 @@ namespace Ryujinx.HLE.HOS public void LoadNca(string ncaFile) { FileStream file = new FileStream(ncaFile, FileMode.Open, FileAccess.Read); - Nca nca = new Nca(_fileSystem.KeySet, file.AsStorage(false)); + Nca nca = new Nca(_device.Configuration.VirtualFileSystem.KeySet, file.AsStorage(false)); LoadNca(nca, null, null); } @@ -310,7 +303,7 @@ namespace Ryujinx.HLE.HOS IStorage dataStorage = null; IFileSystem codeFs = null; - (Nca updatePatchNca, Nca updateControlNca) = GetGameUpdateData(_fileSystem, mainNca.Header.TitleId.ToString("x16"), _device.UserChannelPersistence.Index, out _); + (Nca updatePatchNca, Nca updateControlNca) = GetGameUpdateData(_device.Configuration.VirtualFileSystem, mainNca.Header.TitleId.ToString("x16"), _device.Configuration.UserChannelPersistence.Index, out _); if (updatePatchNca != null) { @@ -323,7 +316,7 @@ namespace Ryujinx.HLE.HOS } // Load program 0 control NCA as we are going to need it for display version. - (_, Nca updateProgram0ControlNca) = GetGameUpdateData(_fileSystem, mainNca.Header.TitleId.ToString("x16"), 0, out _); + (_, Nca updateProgram0ControlNca) = GetGameUpdateData(_device.Configuration.VirtualFileSystem, mainNca.Header.TitleId.ToString("x16"), 0, out _); // Load Aoc string titleAocMetadataPath = Path.Combine(AppDataManager.GamesDirPath, mainNca.Header.TitleId.ToString("x16"), "dlc.json"); @@ -336,7 +329,7 @@ namespace Ryujinx.HLE.HOS { foreach (DlcNca dlcNca in dlcContainer.DlcNcaList) { - _contentManager.AddAocItem(dlcNca.TitleId, dlcContainer.Path, dlcNca.Path, dlcNca.Enabled); + _device.Configuration.ContentManager.AddAocItem(dlcNca.TitleId, dlcContainer.Path, dlcNca.Path, dlcNca.Enabled); } } } @@ -375,7 +368,7 @@ namespace Ryujinx.HLE.HOS Npdm metaData = ReadNpdm(codeFs); - _fileSystem.ModLoader.CollectMods(_contentManager.GetAocTitleIds().Prepend(TitleId), _fileSystem.ModLoader.GetModsBasePath()); + _device.Configuration.VirtualFileSystem.ModLoader.CollectMods(_device.Configuration.ContentManager.GetAocTitleIds().Prepend(TitleId), _device.Configuration.VirtualFileSystem.ModLoader.GetModsBasePath()); if (controlNca != null) { @@ -388,7 +381,7 @@ namespace Ryujinx.HLE.HOS // NOTE: Nintendo doesn't guarantee that the display version will be updated on sub programs when updating a multi program application. // BODY: As such, to avoid PTC cache confusion, we only trust the the program 0 display version when launching a sub program. - if (updateProgram0ControlNca != null && _device.UserChannelPersistence.Index != 0) + if (updateProgram0ControlNca != null && _device.Configuration.UserChannelPersistence.Index != 0) { string dummyTitleName = ""; BlitStruct<ApplicationControlProperty> dummyControl = new BlitStruct<ApplicationControlProperty>(1); @@ -402,9 +395,9 @@ namespace Ryujinx.HLE.HOS } else { - IStorage newStorage = _fileSystem.ModLoader.ApplyRomFsMods(TitleId, dataStorage); + IStorage newStorage = _device.Configuration.VirtualFileSystem.ModLoader.ApplyRomFsMods(TitleId, dataStorage); - _fileSystem.SetRomFs(newStorage.AsStream(FileAccess.Read)); + _device.Configuration.VirtualFileSystem.SetRomFs(newStorage.AsStream(FileAccess.Read)); } if (TitleId != 0) @@ -470,7 +463,7 @@ namespace Ryujinx.HLE.HOS private void LoadExeFs(IFileSystem codeFs, Npdm metaData = null) { - if (_fileSystem.ModLoader.ReplaceExefsPartition(TitleId, ref codeFs)) + if (_device.Configuration.VirtualFileSystem.ModLoader.ReplaceExefsPartition(TitleId, ref codeFs)) { metaData = null; //TODO: Check if we should retain old npdm } @@ -496,7 +489,7 @@ namespace Ryujinx.HLE.HOS } // ExeFs file replacements - ModLoadResult modLoadResult = _fileSystem.ModLoader.ApplyExefsMods(TitleId, nsos); + ModLoadResult modLoadResult = _device.Configuration.VirtualFileSystem.ModLoader.ApplyExefsMods(TitleId, nsos); // collect the nsos, ignoring ones that aren't used NsoExecutable[] programs = nsos.Where(x => x != null).ToArray(); @@ -507,9 +500,9 @@ namespace Ryujinx.HLE.HOS metaData = modLoadResult.Npdm; } - _fileSystem.ModLoader.ApplyNsoPatches(TitleId, programs); + _device.Configuration.VirtualFileSystem.ModLoader.ApplyNsoPatches(TitleId, programs); - _contentManager.LoadEntries(_device); + _device.Configuration.ContentManager.LoadEntries(_device); bool usePtc = _device.System.EnablePtc; @@ -528,7 +521,7 @@ namespace Ryujinx.HLE.HOS ProgramLoader.LoadNsos(_device.System.KernelContext, out ProcessTamperInfo tamperInfo, metaData, executables: programs); - _fileSystem.ModLoader.LoadCheats(TitleId, tamperInfo, _device.TamperMachine); + _device.Configuration.VirtualFileSystem.ModLoader.LoadCheats(TitleId, tamperInfo, _device.TamperMachine); } public void LoadProgram(string filePath) @@ -569,7 +562,7 @@ namespace Ryujinx.HLE.HOS if (romfsSize != 0) { - _fileSystem.SetRomFs(new HomebrewRomFsStream(input, obj.FileSize + (long)romfsOffset)); + _device.Configuration.VirtualFileSystem.SetRomFs(new HomebrewRomFsStream(input, obj.FileSize + (long)romfsOffset)); } if (nacpSize != 0) @@ -617,7 +610,7 @@ namespace Ryujinx.HLE.HOS executable = new NsoExecutable(new LocalStorage(filePath, FileAccess.Read), Path.GetFileNameWithoutExtension(filePath)); } - _contentManager.LoadEntries(_device); + _device.Configuration.ContentManager.LoadEntries(_device); _titleName = metaData.TitleName; TitleId = metaData.Aci0.TitleId; @@ -629,7 +622,7 @@ namespace Ryujinx.HLE.HOS ProgramLoader.LoadNsos(_device.System.KernelContext, out ProcessTamperInfo tamperInfo, metaData, executables: executable); - _fileSystem.ModLoader.LoadCheats(TitleId, tamperInfo, _device.TamperMachine); + _device.Configuration.VirtualFileSystem.ModLoader.LoadCheats(TitleId, tamperInfo, _device.TamperMachine); } private Npdm GetDefaultNpdm() @@ -664,7 +657,7 @@ namespace Ryujinx.HLE.HOS "No control file was found for this game. Using a dummy one instead. This may cause inaccuracies in some games."); } - FileSystemClient fileSystem = _fileSystem.FsClient; + FileSystemClient fileSystem = _device.Configuration.VirtualFileSystem.FsClient; Result resultCode = fileSystem.EnsureApplicationCacheStorage(out _, applicationId, ref control); if (resultCode.IsFailure()) diff --git a/Ryujinx.HLE/HOS/Horizon.cs b/Ryujinx.HLE/HOS/Horizon.cs index d8e1605a..13d7a2af 100644 --- a/Ryujinx.HLE/HOS/Horizon.cs +++ b/Ryujinx.HLE/HOS/Horizon.cs @@ -8,8 +8,6 @@ using Ryujinx.Audio.Integration; using Ryujinx.Audio.Output; using Ryujinx.Audio.Renderer.Device; using Ryujinx.Audio.Renderer.Server; -using Ryujinx.Common; -using Ryujinx.Configuration; using Ryujinx.HLE.FileSystem.Content; using Ryujinx.HLE.HOS.Font; using Ryujinx.HLE.HOS.Kernel; @@ -111,13 +109,13 @@ namespace Ryujinx.HLE.HOS internal LibHac.Horizon LibHacHorizonServer { get; private set; } internal HorizonClient LibHacHorizonClient { get; private set; } - public Horizon(Switch device, ContentManager contentManager, AccountManager accountManager, MemoryConfiguration memoryConfiguration) + public Horizon(Switch device) { KernelContext = new KernelContext( device, device.Memory, - memoryConfiguration.ToKernelMemorySize(), - memoryConfiguration.ToKernelMemoryArrange()); + device.Configuration.MemoryConfiguration.ToKernelMemorySize(), + device.Configuration.MemoryConfiguration.ToKernelMemoryArrange()); Device = device; @@ -166,8 +164,8 @@ namespace Ryujinx.HLE.HOS DisplayResolutionChangeEvent = new KEvent(KernelContext); - AccountManager = accountManager; - ContentManager = contentManager; + AccountManager = device.Configuration.AccountManager; + ContentManager = device.Configuration.ContentManager; CaptureManager = new CaptureManager(device); // TODO: use set:sys (and get external clock source id from settings) @@ -179,7 +177,7 @@ namespace Ryujinx.HLE.HOS TimeSpanType systemTime = TimeSpanType.FromSeconds((long)rtcValue); // Configure and setup internal offset - TimeSpanType internalOffset = TimeSpanType.FromSeconds(ConfigurationState.Instance.System.SystemTimeOffset); + TimeSpanType internalOffset = TimeSpanType.FromSeconds(device.Configuration.SystemTimeOffset); TimeSpanType systemTimeOffset = new TimeSpanType(systemTime.NanoSeconds + internalOffset.NanoSeconds); @@ -219,8 +217,6 @@ namespace Ryujinx.HLE.HOS SurfaceFlinger = new SurfaceFlinger(device); - ConfigurationState.Instance.System.EnableDockedMode.Event += OnDockedModeChange; - InitLibHacHorizon(); InitializeAudioRenderer(); } @@ -313,11 +309,11 @@ namespace Ryujinx.HLE.HOS LibHacHorizonClient = ryujinxClient; } - private void OnDockedModeChange(object sender, ReactiveEventArgs<bool> e) + public void ChangeDockedModeState(bool newState) { - if (e.NewValue != State.DockedMode) + if (newState != State.DockedMode) { - State.DockedMode = e.NewValue; + State.DockedMode = newState; PerformanceState.PerformanceMode = State.DockedMode ? PerformanceMode.Boost : PerformanceMode.Default; AppletState.Messages.Enqueue(MessageInfo.OperationModeChanged); @@ -326,8 +322,7 @@ namespace Ryujinx.HLE.HOS SignalDisplayResolutionChange(); - // Reconfigure controllers - Device.Hid.RefreshInputConfig(ConfigurationState.Instance.Hid.InputConfig.Value); + Device.Configuration.RefreshInputConfig?.Invoke(); } } @@ -388,8 +383,6 @@ namespace Ryujinx.HLE.HOS { if (!_isDisposed && disposing) { - ConfigurationState.Instance.System.EnableDockedMode.Event -= OnDockedModeChange; - _isDisposed = true; KProcess terminationProcess = new KProcess(KernelContext); diff --git a/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/IApplicationFunctions.cs b/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/IApplicationFunctions.cs index 7c04a4d1..e0633145 100644 --- a/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/IApplicationFunctions.cs +++ b/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/IApplicationFunctions.cs @@ -57,7 +57,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati switch (kind) { case LaunchParameterKind.UserChannel: - storageData = context.Device.UserChannelPersistence.Pop(); + storageData = context.Device.Configuration.UserChannelPersistence.Pop(); break; case LaunchParameterKind.PreselectedUser: // Only the first 0x18 bytes of the Data seems to be actually used. @@ -453,7 +453,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati // ClearUserChannel() public ResultCode ClearUserChannel(ServiceCtx context) { - context.Device.UserChannelPersistence.Clear(); + context.Device.Configuration.UserChannelPersistence.Clear(); return ResultCode.Success; } @@ -464,7 +464,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati { AppletAE.IStorage data = GetObject<AppletAE.IStorage>(context, 0); - context.Device.UserChannelPersistence.Push(data.Data); + context.Device.Configuration.UserChannelPersistence.Push(data.Data); return ResultCode.Success; } @@ -473,7 +473,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati // GetPreviousProgramIndex() -> s32 program_index public ResultCode GetPreviousProgramIndex(ServiceCtx context) { - int previousProgramIndex = context.Device.UserChannelPersistence.PreviousIndex; + int previousProgramIndex = context.Device.Configuration.UserChannelPersistence.PreviousIndex; context.ResponseData.Write(previousProgramIndex); diff --git a/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs b/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs index 05ad19fb..fd8844c7 100644 --- a/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs +++ b/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs @@ -396,7 +396,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs // We do a mitm here to find if the request is for an AOC. // This is because AOC can be distributed over multiple containers in the emulator. - if (context.Device.System.ContentManager.GetAocDataStorage((ulong)titleId, out LibHac.Fs.IStorage aocStorage)) + if (context.Device.System.ContentManager.GetAocDataStorage((ulong)titleId, out LibHac.Fs.IStorage aocStorage, context.Device.Configuration.FsIntegrityCheckLevel)) { Logger.Info?.Print(LogClass.Loader, $"Opened AddOnContent Data TitleID={titleId:X16}"); diff --git a/Ryujinx.HLE/HOS/Services/Hid/Hid.cs b/Ryujinx.HLE/HOS/Services/Hid/Hid.cs index 1e85dbf7..61a12d9e 100644 --- a/Ryujinx.HLE/HOS/Services/Hid/Hid.cs +++ b/Ryujinx.HLE/HOS/Services/Hid/Hid.cs @@ -65,7 +65,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid Npads = new NpadDevices(_device, true); } - internal void RefreshInputConfig(List<InputConfig> inputConfig) + public void RefreshInputConfig(List<InputConfig> inputConfig) { ControllerConfig[] npadConfig = new ControllerConfig[inputConfig.Count]; @@ -78,11 +78,6 @@ namespace Ryujinx.HLE.HOS.Services.Hid _device.Hid.Npads.Configure(npadConfig); } - internal void RefreshInputConfigEvent(object _, ReactiveEventArgs<List<InputConfig>> args) - { - RefreshInputConfig(args.NewValue); - } - public ControllerKeys UpdateStickButtons(JoystickPosition leftStick, JoystickPosition rightStick) { const int stickButtonThreshold = short.MaxValue / 2; diff --git a/Ryujinx.HLE/HOS/Services/IpcService.cs b/Ryujinx.HLE/HOS/Services/IpcService.cs index 69d461de..e9582c26 100644 --- a/Ryujinx.HLE/HOS/Services/IpcService.cs +++ b/Ryujinx.HLE/HOS/Services/IpcService.cs @@ -109,7 +109,7 @@ namespace Ryujinx.HLE.HOS.Services bool serviceExists = service.HipcCommands.TryGetValue(commandId, out MethodInfo processRequest); - if (ServiceConfiguration.IgnoreMissingServices || serviceExists) + if (context.Device.Configuration.IgnoreMissingServices || serviceExists) { ResultCode result = ResultCode.Success; @@ -163,7 +163,7 @@ namespace Ryujinx.HLE.HOS.Services bool serviceExists = TipcCommands.TryGetValue(commandId, out MethodInfo processRequest); - if (ServiceConfiguration.IgnoreMissingServices || serviceExists) + if (context.Device.Configuration.IgnoreMissingServices || serviceExists) { ResultCode result = ResultCode.Success; diff --git a/Ryujinx.HLE/HOS/Services/ServiceConfiguration.cs b/Ryujinx.HLE/HOS/Services/ServiceConfiguration.cs deleted file mode 100644 index d73c76d9..00000000 --- a/Ryujinx.HLE/HOS/Services/ServiceConfiguration.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Ryujinx.HLE.HOS.Services -{ - public static class ServiceConfiguration - { - public static bool IgnoreMissingServices { get; set; } - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Sm/IUserInterface.cs b/Ryujinx.HLE/HOS/Services/Sm/IUserInterface.cs index 9a0ccbc3..8b1ec5b8 100644 --- a/Ryujinx.HLE/HOS/Services/Sm/IUserInterface.cs +++ b/Ryujinx.HLE/HOS/Services/Sm/IUserInterface.cs @@ -98,7 +98,7 @@ namespace Ryujinx.HLE.HOS.Services.Sm } else { - if (ServiceConfiguration.IgnoreMissingServices) + if (context.Device.Configuration.IgnoreMissingServices) { Logger.Warning?.Print(LogClass.Service, $"Missing service {name} ignored"); } diff --git a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs index 556e6a3b..9d8e526f 100644 --- a/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs +++ b/Ryujinx.HLE/HOS/Services/SurfaceFlinger/SurfaceFlinger.cs @@ -1,6 +1,5 @@ using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; -using Ryujinx.Configuration; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Gpu; using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices.NvMap; @@ -351,7 +350,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger bool flipX = item.Transform.HasFlag(NativeWindowTransform.FlipX); bool flipY = item.Transform.HasFlag(NativeWindowTransform.FlipY); - AspectRatio aspectRatio = ConfigurationState.Instance.Graphics.AspectRatio.Value; + AspectRatio aspectRatio = _device.Configuration.AspectRatio; bool isStretched = aspectRatio == AspectRatio.Stretched; ImageCrop crop = new ImageCrop( diff --git a/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneContentManager.cs b/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneContentManager.cs index b66ffc3f..963ea9fd 100644 --- a/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneContentManager.cs +++ b/Ryujinx.HLE/HOS/Services/Time/TimeZone/TimeZoneContentManager.cs @@ -5,7 +5,6 @@ using LibHac.Fs.Fsa; using LibHac.FsSystem; using LibHac.FsSystem.NcaUtils; using Ryujinx.Common.Logging; -using Ryujinx.Configuration; using Ryujinx.HLE.Exceptions; using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.FileSystem.Content; @@ -47,10 +46,8 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone InitializeLocationNameCache(); } - public string SanityCheckDeviceLocationName() + public string SanityCheckDeviceLocationName(string locationName) { - string locationName = ConfigurationState.Instance.System.TimeZone; - if (IsLocationNameValid(locationName)) { return locationName; @@ -58,8 +55,6 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone Logger.Warning?.Print(LogClass.ServiceTime, $"Invalid device TimeZone {locationName}, switching back to UTC"); - ConfigurationState.Instance.System.TimeZone.Value = "UTC"; - return "UTC"; } @@ -69,7 +64,7 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone SteadyClockTimePoint timeZoneUpdatedTimePoint = timeManager.StandardSteadyClock.GetCurrentTimePoint(null); - string deviceLocationName = SanityCheckDeviceLocationName(); + string deviceLocationName = SanityCheckDeviceLocationName(device.Configuration.TimeZone); ResultCode result = GetTimeZoneBinary(deviceLocationName, out Stream timeZoneBinaryStream, out LocalStorage ncaFile); diff --git a/Ryujinx.HLE/Switch.cs b/Ryujinx.HLE/Switch.cs index b88bdbfe..ee359dda 100644 --- a/Ryujinx.HLE/Switch.cs +++ b/Ryujinx.HLE/Switch.cs @@ -1,22 +1,14 @@ -using LibHac.FsSystem; using Ryujinx.Audio.Backends.CompatLayer; using Ryujinx.Audio.Integration; -using Ryujinx.Common; -using Ryujinx.Configuration; -using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Gpu; using Ryujinx.Graphics.Host1x; using Ryujinx.Graphics.Nvdec; using Ryujinx.Graphics.Vic; using Ryujinx.HLE.FileSystem; -using Ryujinx.HLE.FileSystem.Content; using Ryujinx.HLE.HOS; -using Ryujinx.HLE.HOS.Services; -using Ryujinx.HLE.HOS.Services.Account.Acc; using Ryujinx.HLE.HOS.Services.Apm; using Ryujinx.HLE.HOS.Services.Hid; using Ryujinx.HLE.HOS.Services.Nv.NvDrvServices; -using Ryujinx.HLE.HOS.SystemState; using Ryujinx.Memory; using System; @@ -24,69 +16,60 @@ namespace Ryujinx.HLE { public class Switch : IDisposable { - private MemoryConfiguration _memoryConfiguration; + public HLEConfiguration Configuration { get; } - public IHardwareDeviceDriver AudioDeviceDriver { get; private set; } + public IHardwareDeviceDriver AudioDeviceDriver { get; } - internal MemoryBlock Memory { get; private set; } + internal MemoryBlock Memory { get; } - public GpuContext Gpu { get; private set; } + public GpuContext Gpu { get; } - internal NvMemoryAllocator MemoryAllocator { get; private set; } + internal NvMemoryAllocator MemoryAllocator { get; } internal Host1xDevice Host1x { get; } - public VirtualFileSystem FileSystem { get; private set; } + public VirtualFileSystem FileSystem => Configuration.VirtualFileSystem; - public Horizon System { get; private set; } + public Horizon System { get; } public ApplicationLoader Application { get; } - public PerformanceStatistics Statistics { get; private set; } + public PerformanceStatistics Statistics { get; } - public UserChannelPersistence UserChannelPersistence { get; } + public Hid Hid { get; } - public Hid Hid { get; private set; } + public TamperMachine TamperMachine { get; } - public TamperMachine TamperMachine { get; private set; } - - public IHostUiHandler UiHandler { get; set; } + public IHostUiHandler UiHandler { get; } public bool EnableDeviceVsync { get; set; } = true; - public Switch( - VirtualFileSystem fileSystem, - ContentManager contentManager, - AccountManager accountManager, - UserChannelPersistence userChannelPersistence, - IRenderer renderer, - IHardwareDeviceDriver audioDeviceDriver, - MemoryConfiguration memoryConfiguration) + public Switch(HLEConfiguration configuration) { - if (renderer == null) + if (configuration.GpuRenderer == null) { - throw new ArgumentNullException(nameof(renderer)); + throw new ArgumentNullException(nameof(configuration.GpuRenderer)); } - if (audioDeviceDriver == null) + if (configuration.AudioDeviceDriver == null) { - throw new ArgumentNullException(nameof(audioDeviceDriver)); + throw new ArgumentNullException(nameof(configuration.AudioDeviceDriver)); } - if (userChannelPersistence == null) + if (configuration.UserChannelPersistence== null) { - throw new ArgumentNullException(nameof(userChannelPersistence)); + throw new ArgumentNullException(nameof(configuration.UserChannelPersistence)); } - UserChannelPersistence = userChannelPersistence; + Configuration = configuration; - _memoryConfiguration = memoryConfiguration; + UiHandler = configuration.HostUiHandler; - AudioDeviceDriver = new CompatLayerHardwareDeviceDriver(audioDeviceDriver); + AudioDeviceDriver = new CompatLayerHardwareDeviceDriver(configuration.AudioDeviceDriver); - Memory = new MemoryBlock(memoryConfiguration.ToDramSize()); + Memory = new MemoryBlock(configuration.MemoryConfiguration.ToDramSize()); - Gpu = new GpuContext(renderer); + Gpu = new GpuContext(configuration.GpuRenderer); MemoryAllocator = new NvMemoryAllocator(); @@ -111,9 +94,7 @@ namespace Ryujinx.HLE } }; - FileSystem = fileSystem; - - System = new Horizon(this, contentManager, accountManager, memoryConfiguration); + System = new Horizon(this); System.InitializeServices(); Statistics = new PerformanceStatistics(); @@ -121,45 +102,30 @@ namespace Ryujinx.HLE Hid = new Hid(this, System.HidBaseAddress); Hid.InitDevices(); - Application = new ApplicationLoader(this, fileSystem, contentManager); + Application = new ApplicationLoader(this); TamperMachine = new TamperMachine(); + + Initialize(); } - public void Initialize() + private void Initialize() { - System.State.SetLanguage((SystemLanguage)ConfigurationState.Instance.System.Language.Value); + System.State.SetLanguage(Configuration.SystemLanguage); - System.State.SetRegion((RegionCode)ConfigurationState.Instance.System.Region.Value); + System.State.SetRegion(Configuration.Region); - EnableDeviceVsync = ConfigurationState.Instance.Graphics.EnableVsync; + EnableDeviceVsync = Configuration.EnableVsync; - System.State.DockedMode = ConfigurationState.Instance.System.EnableDockedMode; + System.State.DockedMode = Configuration.EnableDockedMode; System.PerformanceState.PerformanceMode = System.State.DockedMode ? PerformanceMode.Boost : PerformanceMode.Default; - System.EnablePtc = ConfigurationState.Instance.System.EnablePtc; + System.EnablePtc = Configuration.EnablePtc; - System.FsIntegrityCheckLevel = GetIntegrityCheckLevel(); + System.FsIntegrityCheckLevel = Configuration.FsIntegrityCheckLevel; - System.GlobalAccessLogMode = ConfigurationState.Instance.System.FsGlobalAccessLogMode; - - ServiceConfiguration.IgnoreMissingServices = ConfigurationState.Instance.System.IgnoreMissingServices; - ConfigurationState.Instance.System.IgnoreMissingServices.Event += (object _, ReactiveEventArgs<bool> args) => - { - ServiceConfiguration.IgnoreMissingServices = args.NewValue; - }; - - // Configure controllers - Hid.RefreshInputConfig(ConfigurationState.Instance.Hid.InputConfig.Value); - ConfigurationState.Instance.Hid.InputConfig.Event += Hid.RefreshInputConfigEvent; - } - - public static IntegrityCheckLevel GetIntegrityCheckLevel() - { - return ConfigurationState.Instance.System.EnableFsIntegrityChecks - ? IntegrityCheckLevel.ErrorOnInvalid - : IntegrityCheckLevel.None; + System.GlobalAccessLogMode = Configuration.FsGlobalAccessLogMode; } public void LoadCart(string exeFsDir, string romFsFile = null) @@ -223,8 +189,6 @@ namespace Ryujinx.HLE { if (disposing) { - ConfigurationState.Instance.Hid.InputConfig.Event -= Hid.RefreshInputConfigEvent; - System.Dispose(); Host1x.Dispose(); AudioDeviceDriver.Dispose(); |