Keep the GUI alive when closing a game (#888)
* Keep the GUI alive when closing a game Make HLE.Switch init when starting a game and dispose it when closing the GlScreen. This also make HLE in charge of disposing the audio and gpu backend. * Address Ac_k's comments * Make sure to dispose the Discord module and use GTK quit method Also update Discord Precense when closing a game. * Make sure to dispose MainWindow * Address gdk's comments
This commit is contained in:
parent
b4b2b8b162
commit
d6b9babe1d
16 changed files with 284 additions and 215 deletions
|
@ -14,7 +14,7 @@ using System.Linq;
|
|||
|
||||
namespace Ryujinx.HLE.FileSystem.Content
|
||||
{
|
||||
internal class ContentManager
|
||||
public class ContentManager
|
||||
{
|
||||
private const ulong SystemVersionTitleId = 0x0100000000000809;
|
||||
private const ulong SystemUpdateTitleId = 0x0100000000000816;
|
||||
|
@ -26,11 +26,11 @@ namespace Ryujinx.HLE.FileSystem.Content
|
|||
|
||||
private SortedDictionary<(ulong titleId, NcaContentType type), string> _contentDictionary;
|
||||
|
||||
private Switch _device;
|
||||
private VirtualFileSystem _virtualFileSystem;
|
||||
|
||||
private readonly object _lock = new object();
|
||||
|
||||
public ContentManager(Switch device)
|
||||
public ContentManager(VirtualFileSystem virtualFileSystem)
|
||||
{
|
||||
_contentDictionary = new SortedDictionary<(ulong, NcaContentType), string>();
|
||||
_locationEntries = new Dictionary<StorageId, LinkedList<LocationEntry>>();
|
||||
|
@ -55,10 +55,10 @@ namespace Ryujinx.HLE.FileSystem.Content
|
|||
{ "FontNintendoExtended", "nintendo_ext_003.bfttf" }
|
||||
};
|
||||
|
||||
_device = device;
|
||||
_virtualFileSystem = virtualFileSystem;
|
||||
}
|
||||
|
||||
public void LoadEntries(bool ignoreMissingFonts = false)
|
||||
public void LoadEntries(Switch device = null)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
|
@ -74,7 +74,7 @@ namespace Ryujinx.HLE.FileSystem.Content
|
|||
try
|
||||
{
|
||||
contentPathString = LocationHelper.GetContentRoot(storageId);
|
||||
contentDirectory = LocationHelper.GetRealPath(_device.FileSystem, contentPathString);
|
||||
contentDirectory = LocationHelper.GetRealPath(_virtualFileSystem, contentPathString);
|
||||
registeredDirectory = Path.Combine(contentDirectory, "registered");
|
||||
}
|
||||
catch (NotSupportedException)
|
||||
|
@ -99,7 +99,7 @@ namespace Ryujinx.HLE.FileSystem.Content
|
|||
|
||||
using (FileStream ncaFile = File.OpenRead(Directory.GetFiles(directoryPath)[0]))
|
||||
{
|
||||
Nca nca = new Nca(_device.System.KeySet, ncaFile.AsStorage());
|
||||
Nca nca = new Nca(_virtualFileSystem.KeySet, ncaFile.AsStorage());
|
||||
|
||||
string switchPath = contentPathString + ":/" + ncaFile.Name.Replace(contentDirectory, string.Empty).TrimStart(Path.DirectorySeparatorChar);
|
||||
|
||||
|
@ -126,7 +126,7 @@ namespace Ryujinx.HLE.FileSystem.Content
|
|||
|
||||
using (FileStream ncaFile = new FileStream(filePath, FileMode.Open, FileAccess.Read))
|
||||
{
|
||||
Nca nca = new Nca(_device.System.KeySet, ncaFile.AsStorage());
|
||||
Nca nca = new Nca(_virtualFileSystem.KeySet, ncaFile.AsStorage());
|
||||
|
||||
string switchPath = contentPathString + ":/" + filePath.Replace(contentDirectory, string.Empty).TrimStart(Path.DirectorySeparatorChar);
|
||||
|
||||
|
@ -156,9 +156,11 @@ namespace Ryujinx.HLE.FileSystem.Content
|
|||
}
|
||||
}
|
||||
|
||||
TimeManager.Instance.InitializeTimeZone(_device);
|
||||
|
||||
_device.System.Font.Initialize(this, ignoreMissingFonts);
|
||||
if (device != null)
|
||||
{
|
||||
TimeManager.Instance.InitializeTimeZone(device);
|
||||
device.System.Font.Initialize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -271,7 +273,7 @@ namespace Ryujinx.HLE.FileSystem.Content
|
|||
return false;
|
||||
}
|
||||
|
||||
string installedPath = _device.FileSystem.SwitchPathToSystemPath(locationEntry.ContentPath);
|
||||
string installedPath = _virtualFileSystem.SwitchPathToSystemPath(locationEntry.ContentPath);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(installedPath))
|
||||
{
|
||||
|
@ -279,7 +281,7 @@ namespace Ryujinx.HLE.FileSystem.Content
|
|||
{
|
||||
using (FileStream file = new FileStream(installedPath, FileMode.Open, FileAccess.Read))
|
||||
{
|
||||
Nca nca = new Nca(_device.System.KeySet, file.AsStorage());
|
||||
Nca nca = new Nca(_virtualFileSystem.KeySet, file.AsStorage());
|
||||
bool contentCheck = nca.Header.ContentType == contentType;
|
||||
|
||||
return contentCheck;
|
||||
|
@ -351,7 +353,7 @@ namespace Ryujinx.HLE.FileSystem.Content
|
|||
public void InstallFirmware(string firmwareSource)
|
||||
{
|
||||
string contentPathString = LocationHelper.GetContentRoot(StorageId.NandSystem);
|
||||
string contentDirectory = LocationHelper.GetRealPath(_device.FileSystem, contentPathString);
|
||||
string contentDirectory = LocationHelper.GetRealPath(_virtualFileSystem, contentPathString);
|
||||
string registeredDirectory = Path.Combine(contentDirectory, "registered");
|
||||
string temporaryDirectory = Path.Combine(contentDirectory, "temp");
|
||||
|
||||
|
@ -386,7 +388,7 @@ namespace Ryujinx.HLE.FileSystem.Content
|
|||
}
|
||||
break;
|
||||
case ".xci":
|
||||
Xci xci = new Xci(_device.System.KeySet, file.AsStorage());
|
||||
Xci xci = new Xci(_virtualFileSystem.KeySet, file.AsStorage());
|
||||
InstallFromCart(xci, temporaryDirectory);
|
||||
break;
|
||||
default:
|
||||
|
@ -418,7 +420,7 @@ namespace Ryujinx.HLE.FileSystem.Content
|
|||
{
|
||||
foreach (var entry in filesystem.EnumerateEntries("/", "*.nca"))
|
||||
{
|
||||
Nca nca = new Nca(_device.System.KeySet, OpenPossibleFragmentedFile(filesystem, entry.FullPath, OpenMode.Read).AsStorage());
|
||||
Nca nca = new Nca(_virtualFileSystem.KeySet, OpenPossibleFragmentedFile(filesystem, entry.FullPath, OpenMode.Read).AsStorage());
|
||||
|
||||
SaveNca(nca, entry.Name.Remove(entry.Name.IndexOf('.')), temporaryDirectory);
|
||||
}
|
||||
|
@ -537,7 +539,7 @@ namespace Ryujinx.HLE.FileSystem.Content
|
|||
return VerifyAndGetVersionZip(archive);
|
||||
}
|
||||
case ".xci":
|
||||
Xci xci = new Xci(_device.System.KeySet, file.AsStorage());
|
||||
Xci xci = new Xci(_virtualFileSystem.KeySet, file.AsStorage());
|
||||
|
||||
if (xci.HasPartition(XciPartitionType.Update))
|
||||
{
|
||||
|
@ -561,6 +563,8 @@ namespace Ryujinx.HLE.FileSystem.Content
|
|||
|
||||
SystemVersion VerifyAndGetVersionZip(ZipArchive archive)
|
||||
{
|
||||
IntegrityCheckLevel integrityCheckLevel = Switch.GetIntigrityCheckLevel();
|
||||
|
||||
SystemVersion systemVersion = null;
|
||||
|
||||
foreach (var entry in archive.Entries)
|
||||
|
@ -571,7 +575,7 @@ namespace Ryujinx.HLE.FileSystem.Content
|
|||
{
|
||||
IStorage storage = ncaStream.AsStorage();
|
||||
|
||||
Nca nca = new Nca(_device.System.KeySet, storage);
|
||||
Nca nca = new Nca(_virtualFileSystem.KeySet, storage);
|
||||
|
||||
if (updateNcas.ContainsKey(nca.Header.TitleId))
|
||||
{
|
||||
|
@ -598,9 +602,9 @@ namespace Ryujinx.HLE.FileSystem.Content
|
|||
|
||||
using (Stream ncaStream = GetZipStream(fileEntry))
|
||||
{
|
||||
Nca metaNca = new Nca(_device.System.KeySet, ncaStream.AsStorage());
|
||||
Nca metaNca = new Nca(_virtualFileSystem.KeySet, ncaStream.AsStorage());
|
||||
|
||||
IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, _device.System.FsIntegrityCheckLevel);
|
||||
IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, integrityCheckLevel);
|
||||
|
||||
string cnmtPath = fs.EnumerateEntries("/", "*.cnmt").Single().FullPath;
|
||||
|
||||
|
@ -628,9 +632,9 @@ namespace Ryujinx.HLE.FileSystem.Content
|
|||
|
||||
using (Stream ncaStream = GetZipStream(archive.GetEntry(versionEntry)))
|
||||
{
|
||||
Nca nca = new Nca(_device.System.KeySet, ncaStream.AsStorage());
|
||||
Nca nca = new Nca(_virtualFileSystem.KeySet, ncaStream.AsStorage());
|
||||
|
||||
var romfs = nca.OpenFileSystem(NcaSectionType.Data, _device.System.FsIntegrityCheckLevel);
|
||||
var romfs = nca.OpenFileSystem(NcaSectionType.Data, integrityCheckLevel);
|
||||
|
||||
if (romfs.OpenFile(out IFile systemVersionFile, "/file", OpenMode.Read).IsSuccess())
|
||||
{
|
||||
|
@ -663,9 +667,9 @@ namespace Ryujinx.HLE.FileSystem.Content
|
|||
{
|
||||
using (Stream contentNcaStream = GetZipStream(contentZipEntry))
|
||||
{
|
||||
Nca metaNca = new Nca(_device.System.KeySet, metaNcaStream.AsStorage());
|
||||
Nca metaNca = new Nca(_virtualFileSystem.KeySet, metaNcaStream.AsStorage());
|
||||
|
||||
IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, _device.System.FsIntegrityCheckLevel);
|
||||
IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, integrityCheckLevel);
|
||||
|
||||
string cnmtPath = fs.EnumerateEntries("/", "*.cnmt").Single().FullPath;
|
||||
|
||||
|
@ -722,6 +726,8 @@ namespace Ryujinx.HLE.FileSystem.Content
|
|||
|
||||
SystemVersion VerifyAndGetVersion(IFileSystem filesystem)
|
||||
{
|
||||
IntegrityCheckLevel integrityCheckLevel = Switch.GetIntigrityCheckLevel();
|
||||
|
||||
SystemVersion systemVersion = null;
|
||||
|
||||
CnmtContentMetaEntry[] metaEntries = null;
|
||||
|
@ -730,11 +736,11 @@ namespace Ryujinx.HLE.FileSystem.Content
|
|||
{
|
||||
IStorage ncaStorage = OpenPossibleFragmentedFile(filesystem, entry.FullPath, OpenMode.Read).AsStorage();
|
||||
|
||||
Nca nca = new Nca(_device.System.KeySet, ncaStorage);
|
||||
Nca nca = new Nca(_virtualFileSystem.KeySet, ncaStorage);
|
||||
|
||||
if (nca.Header.TitleId == SystemUpdateTitleId && nca.Header.ContentType == NcaContentType.Meta)
|
||||
{
|
||||
IFileSystem fs = nca.OpenFileSystem(NcaSectionType.Data, _device.System.FsIntegrityCheckLevel);
|
||||
IFileSystem fs = nca.OpenFileSystem(NcaSectionType.Data, integrityCheckLevel);
|
||||
|
||||
string cnmtPath = fs.EnumerateEntries("/", "*.cnmt").Single().FullPath;
|
||||
|
||||
|
@ -752,7 +758,7 @@ namespace Ryujinx.HLE.FileSystem.Content
|
|||
}
|
||||
else if (nca.Header.TitleId == SystemVersionTitleId && nca.Header.ContentType == NcaContentType.Data)
|
||||
{
|
||||
var romfs = nca.OpenFileSystem(NcaSectionType.Data, _device.System.FsIntegrityCheckLevel);
|
||||
var romfs = nca.OpenFileSystem(NcaSectionType.Data, integrityCheckLevel);
|
||||
|
||||
if (romfs.OpenFile(out IFile systemVersionFile, "/file", OpenMode.Read).IsSuccess())
|
||||
{
|
||||
|
@ -797,9 +803,9 @@ namespace Ryujinx.HLE.FileSystem.Content
|
|||
IStorage metaStorage = OpenPossibleFragmentedFile(filesystem, metaNcaEntry.path, OpenMode.Read).AsStorage();
|
||||
IStorage contentStorage = OpenPossibleFragmentedFile(filesystem, contentPath, OpenMode.Read).AsStorage();
|
||||
|
||||
Nca metaNca = new Nca(_device.System.KeySet, metaStorage);
|
||||
Nca metaNca = new Nca(_virtualFileSystem.KeySet, metaStorage);
|
||||
|
||||
IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, _device.System.FsIntegrityCheckLevel);
|
||||
IFileSystem fs = metaNca.OpenFileSystem(NcaSectionType.Data, integrityCheckLevel);
|
||||
|
||||
string cnmtPath = fs.EnumerateEntries("/", "*.cnmt").Single().FullPath;
|
||||
|
||||
|
@ -851,7 +857,9 @@ namespace Ryujinx.HLE.FileSystem.Content
|
|||
|
||||
public SystemVersion GetCurrentFirmwareVersion()
|
||||
{
|
||||
LoadEntries(true);
|
||||
IntegrityCheckLevel integrityCheckLevel = Switch.GetIntigrityCheckLevel();
|
||||
|
||||
LoadEntries();
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
|
@ -861,15 +869,15 @@ namespace Ryujinx.HLE.FileSystem.Content
|
|||
{
|
||||
if (entry.ContentType == NcaContentType.Data)
|
||||
{
|
||||
var path = _device.FileSystem.SwitchPathToSystemPath(entry.ContentPath);
|
||||
var path = _virtualFileSystem.SwitchPathToSystemPath(entry.ContentPath);
|
||||
|
||||
using (FileStream fileStream = File.OpenRead(path))
|
||||
{
|
||||
Nca nca = new Nca(_device.System.KeySet, fileStream.AsStorage());
|
||||
Nca nca = new Nca(_virtualFileSystem.KeySet, fileStream.AsStorage());
|
||||
|
||||
if (nca.Header.TitleId == SystemVersionTitleId && nca.Header.ContentType == NcaContentType.Data)
|
||||
{
|
||||
var romfs = nca.OpenFileSystem(NcaSectionType.Data, _device.System.FsIntegrityCheckLevel);
|
||||
var romfs = nca.OpenFileSystem(NcaSectionType.Data, integrityCheckLevel);
|
||||
|
||||
if (romfs.OpenFile(out IFile systemVersionFile, "/file", OpenMode.Read).IsSuccess())
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
namespace Ryujinx.HLE.FileSystem
|
||||
{
|
||||
internal enum StorageId
|
||||
public enum StorageId
|
||||
{
|
||||
None,
|
||||
Host,
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
using LibHac;
|
||||
using LibHac.Fs;
|
||||
using LibHac.FsService;
|
||||
using LibHac.FsSystem;
|
||||
using Ryujinx.HLE.FileSystem.Content;
|
||||
using Ryujinx.HLE.HOS;
|
||||
using System;
|
||||
|
@ -16,6 +20,16 @@ namespace Ryujinx.HLE.FileSystem
|
|||
public static string SystemNandPath = Path.Combine(NandPath, "system");
|
||||
public static string UserNandPath = Path.Combine(NandPath, "user");
|
||||
|
||||
public Keyset KeySet { get; private set; }
|
||||
public FileSystemServer FsServer { get; private set; }
|
||||
public FileSystemClient FsClient { get; private set; }
|
||||
public EmulatedGameCard GameCard { get; private set; }
|
||||
|
||||
public VirtualFileSystem()
|
||||
{
|
||||
Reload();
|
||||
}
|
||||
|
||||
public Stream RomFs { get; private set; }
|
||||
|
||||
public void LoadRomFs(string fileName)
|
||||
|
@ -183,6 +197,69 @@ namespace Ryujinx.HLE.FileSystem
|
|||
return Path.Combine(appDataPath, BasePath);
|
||||
}
|
||||
|
||||
public void Reload()
|
||||
{
|
||||
ReloadKeySet();
|
||||
|
||||
LocalFileSystem serverBaseFs = new LocalFileSystem(GetBasePath());
|
||||
|
||||
DefaultFsServerObjects fsServerObjects = DefaultFsServerObjects.GetDefaultEmulatedCreators(serverBaseFs, KeySet);
|
||||
|
||||
GameCard = fsServerObjects.GameCard;
|
||||
|
||||
FileSystemServerConfig fsServerConfig = new FileSystemServerConfig
|
||||
{
|
||||
FsCreators = fsServerObjects.FsCreators,
|
||||
DeviceOperator = fsServerObjects.DeviceOperator,
|
||||
ExternalKeySet = KeySet.ExternalKeySet
|
||||
};
|
||||
|
||||
FsServer = new FileSystemServer(fsServerConfig);
|
||||
FsClient = FsServer.CreateFileSystemClient();
|
||||
}
|
||||
|
||||
|
||||
private void ReloadKeySet()
|
||||
{
|
||||
string keyFile = null;
|
||||
string titleKeyFile = null;
|
||||
string consoleKeyFile = null;
|
||||
|
||||
string home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
|
||||
|
||||
LoadSetAtPath(Path.Combine(home, ".switch"));
|
||||
LoadSetAtPath(GetSystemPath());
|
||||
|
||||
void LoadSetAtPath(string basePath)
|
||||
{
|
||||
string localKeyFile = Path.Combine(basePath, "prod.keys");
|
||||
string localTitleKeyFile = Path.Combine(basePath, "title.keys");
|
||||
string localConsoleKeyFile = Path.Combine(basePath, "console.keys");
|
||||
|
||||
if (File.Exists(localKeyFile))
|
||||
{
|
||||
keyFile = localKeyFile;
|
||||
}
|
||||
|
||||
if (File.Exists(localTitleKeyFile))
|
||||
{
|
||||
titleKeyFile = localTitleKeyFile;
|
||||
}
|
||||
|
||||
if (File.Exists(localConsoleKeyFile))
|
||||
{
|
||||
consoleKeyFile = localConsoleKeyFile;
|
||||
}
|
||||
}
|
||||
|
||||
KeySet = ExternalKeyReader.ReadKeyFile(keyFile, titleKeyFile, consoleKeyFile);
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
RomFs?.Dispose();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
|
@ -192,7 +269,7 @@ namespace Ryujinx.HLE.FileSystem
|
|||
{
|
||||
if (disposing)
|
||||
{
|
||||
RomFs?.Dispose();
|
||||
Unload();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,15 +44,15 @@ namespace Ryujinx.HLE.HOS.Font
|
|||
_fontsPath = Path.Combine(device.FileSystem.GetSystemPath(), "fonts");
|
||||
}
|
||||
|
||||
public void Initialize(ContentManager contentManager, bool ignoreMissingFonts)
|
||||
public void Initialize(ContentManager contentManager)
|
||||
{
|
||||
_fontData?.Clear();
|
||||
_fontData = null;
|
||||
|
||||
EnsureInitialized(contentManager, ignoreMissingFonts);
|
||||
EnsureInitialized(contentManager);
|
||||
}
|
||||
|
||||
public void EnsureInitialized(ContentManager contentManager, bool ignoreMissingFonts)
|
||||
public void EnsureInitialized(ContentManager contentManager)
|
||||
{
|
||||
if (_fontData == null)
|
||||
{
|
||||
|
@ -120,12 +120,10 @@ namespace Ryujinx.HLE.HOS.Font
|
|||
|
||||
return info;
|
||||
}
|
||||
else if (!ignoreMissingFonts)
|
||||
else
|
||||
{
|
||||
throw new InvalidSystemResourceException($"Font \"{name}.ttf\" not found. Please provide it in \"{_fontsPath}\".");
|
||||
}
|
||||
|
||||
return new FontInfo();
|
||||
}
|
||||
|
||||
_fontData = new Dictionary<SharedFontType, FontInfo>
|
||||
|
@ -138,7 +136,7 @@ namespace Ryujinx.HLE.HOS.Font
|
|||
{ SharedFontType.NintendoEx, CreateFont("FontNintendoExtended") }
|
||||
};
|
||||
|
||||
if (fontOffset > Horizon.FontSize && !ignoreMissingFonts)
|
||||
if (fontOffset > Horizon.FontSize)
|
||||
{
|
||||
throw new InvalidSystemResourceException(
|
||||
$"The sum of all fonts size exceed the shared memory size. " +
|
||||
|
@ -161,14 +159,14 @@ namespace Ryujinx.HLE.HOS.Font
|
|||
|
||||
public int GetFontSize(SharedFontType fontType)
|
||||
{
|
||||
EnsureInitialized(_device.System.ContentManager, false);
|
||||
EnsureInitialized(_device.System.ContentManager);
|
||||
|
||||
return _fontData[fontType].Size;
|
||||
}
|
||||
|
||||
public int GetSharedMemoryAddressOffset(SharedFontType fontType)
|
||||
{
|
||||
EnsureInitialized(_device.System.ContentManager, false);
|
||||
EnsureInitialized(_device.System.ContentManager);
|
||||
|
||||
return _fontData[fontType].Offset + 8;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ using LibHac;
|
|||
using LibHac.Account;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.FsService;
|
||||
using LibHac.FsSystem;
|
||||
using LibHac.FsSystem.NcaUtils;
|
||||
using LibHac.Ncm;
|
||||
|
@ -105,7 +104,7 @@ namespace Ryujinx.HLE.HOS
|
|||
|
||||
internal KEvent VsyncEvent { get; private set; }
|
||||
|
||||
public Keyset KeySet { get; private set; }
|
||||
public Keyset KeySet => Device.FileSystem.KeySet;
|
||||
|
||||
private bool _hasStarted;
|
||||
|
||||
|
@ -122,12 +121,7 @@ namespace Ryujinx.HLE.HOS
|
|||
|
||||
internal long HidBaseAddress { get; private set; }
|
||||
|
||||
internal FileSystemServer FsServer { get; private set; }
|
||||
public FileSystemClient FsClient { get; private set; }
|
||||
|
||||
internal EmulatedGameCard GameCard { get; private set; }
|
||||
|
||||
public Horizon(Switch device)
|
||||
public Horizon(Switch device, ContentManager contentManager)
|
||||
{
|
||||
ControlData = new BlitStruct<ApplicationControlProperty>(1);
|
||||
|
||||
|
@ -211,9 +205,7 @@ namespace Ryujinx.HLE.HOS
|
|||
|
||||
VsyncEvent = new KEvent(this);
|
||||
|
||||
LoadKeySet();
|
||||
|
||||
ContentManager = new ContentManager(device);
|
||||
ContentManager = contentManager;
|
||||
|
||||
// TODO: use set:sys (and get external clock source id from settings)
|
||||
// TODO: use "time!standard_steady_clock_rtc_update_interval_minutes" and implement a worker thread to be accurate.
|
||||
|
@ -239,22 +231,6 @@ namespace Ryujinx.HLE.HOS
|
|||
// FIXME: TimeZone shoud be init here but it's actually done in ContentManager
|
||||
|
||||
TimeServiceManager.Instance.SetupEphemeralNetworkSystemClock();
|
||||
|
||||
LocalFileSystem serverBaseFs = new LocalFileSystem(device.FileSystem.GetBasePath());
|
||||
|
||||
DefaultFsServerObjects fsServerObjects = DefaultFsServerObjects.GetDefaultEmulatedCreators(serverBaseFs, KeySet);
|
||||
|
||||
GameCard = fsServerObjects.GameCard;
|
||||
|
||||
FileSystemServerConfig fsServerConfig = new FileSystemServerConfig
|
||||
{
|
||||
FsCreators = fsServerObjects.FsCreators,
|
||||
DeviceOperator = fsServerObjects.DeviceOperator,
|
||||
ExternalKeySet = KeySet.ExternalKeySet
|
||||
};
|
||||
|
||||
FsServer = new FileSystemServer(fsServerConfig);
|
||||
FsClient = FsServer.CreateFileSystemClient();
|
||||
}
|
||||
|
||||
public void LoadCart(string exeFsDir, string romFsFile = null)
|
||||
|
@ -284,7 +260,7 @@ namespace Ryujinx.HLE.HOS
|
|||
return;
|
||||
}
|
||||
|
||||
ContentManager.LoadEntries();
|
||||
ContentManager.LoadEntries(Device);
|
||||
|
||||
LoadNca(mainNca, patchNca, controlNca);
|
||||
}
|
||||
|
@ -578,7 +554,7 @@ namespace Ryujinx.HLE.HOS
|
|||
LoadNso("subsdk");
|
||||
LoadNso("sdk");
|
||||
|
||||
ContentManager.LoadEntries();
|
||||
ContentManager.LoadEntries(Device);
|
||||
|
||||
ProgramLoader.LoadStaticObjects(this, metaData, staticObjects.ToArray());
|
||||
}
|
||||
|
@ -671,7 +647,7 @@ namespace Ryujinx.HLE.HOS
|
|||
staticObject = new NxStaticObject(input);
|
||||
}
|
||||
|
||||
ContentManager.LoadEntries();
|
||||
ContentManager.LoadEntries(Device);
|
||||
|
||||
TitleName = metaData.TitleName;
|
||||
TitleId = metaData.Aci0.TitleId;
|
||||
|
@ -712,7 +688,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.");
|
||||
}
|
||||
|
||||
Result rc = EnsureApplicationSaveData(FsClient, out _, titleId, ref ControlData.Value, ref user);
|
||||
Result rc = EnsureApplicationSaveData(Device.FileSystem.FsClient, out _, titleId, ref ControlData.Value, ref user);
|
||||
|
||||
if (rc.IsFailure())
|
||||
{
|
||||
|
@ -722,57 +698,6 @@ namespace Ryujinx.HLE.HOS
|
|||
return rc;
|
||||
}
|
||||
|
||||
public void LoadKeySet()
|
||||
{
|
||||
string keyFile = null;
|
||||
string titleKeyFile = null;
|
||||
string consoleKeyFile = null;
|
||||
|
||||
string home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
|
||||
|
||||
LoadSetAtPath(Path.Combine(home, ".switch"));
|
||||
LoadSetAtPath(Device.FileSystem.GetSystemPath());
|
||||
|
||||
KeySet = ExternalKeyReader.ReadKeyFile(keyFile, titleKeyFile, consoleKeyFile);
|
||||
|
||||
void LoadSetAtPath(string basePath)
|
||||
{
|
||||
string localKeyFile = Path.Combine(basePath, "prod.keys");
|
||||
string localTitleKeyFile = Path.Combine(basePath, "title.keys");
|
||||
string localConsoleKeyFile = Path.Combine(basePath, "console.keys");
|
||||
|
||||
if (File.Exists(localKeyFile))
|
||||
{
|
||||
keyFile = localKeyFile;
|
||||
}
|
||||
|
||||
if (File.Exists(localTitleKeyFile))
|
||||
{
|
||||
titleKeyFile = localTitleKeyFile;
|
||||
}
|
||||
|
||||
if (File.Exists(localConsoleKeyFile))
|
||||
{
|
||||
consoleKeyFile = localConsoleKeyFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public SystemVersion VerifyFirmwarePackage(string firmwarePackage)
|
||||
{
|
||||
return ContentManager.VerifyFirmwarePackage(firmwarePackage);
|
||||
}
|
||||
|
||||
public SystemVersion GetCurrentFirmwareVersion()
|
||||
{
|
||||
return ContentManager.GetCurrentFirmwareVersion();
|
||||
}
|
||||
|
||||
public void InstallFirmware(string firmwarePackage)
|
||||
{
|
||||
ContentManager.InstallFirmware(firmwarePackage);
|
||||
}
|
||||
|
||||
public void SignalVsync()
|
||||
{
|
||||
VsyncEvent.ReadableEvent.Signal();
|
||||
|
|
|
@ -60,7 +60,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati
|
|||
"No control file was found for this game. Using a dummy one instead. This may cause inaccuracies in some games.");
|
||||
}
|
||||
|
||||
Result result = EnsureApplicationSaveData(context.Device.System.FsClient, out long requiredSize, titleId,
|
||||
Result result = EnsureApplicationSaveData(context.Device.FileSystem.FsClient, out long requiredSize, titleId,
|
||||
ref context.Device.System.ControlData.Value, ref userId);
|
||||
|
||||
context.ResponseData.Write(requiredSize);
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace Ryujinx.HLE.HOS.Services.Fs
|
|||
|
||||
public IFileSystemProxy(ServiceCtx context)
|
||||
{
|
||||
_baseFileSystemProxy = context.Device.System.FsServer.CreateFileSystemProxyService();
|
||||
_baseFileSystemProxy = context.Device.FileSystem.FsServer.CreateFileSystemProxyService();
|
||||
}
|
||||
|
||||
[Command(1)]
|
||||
|
|
|
@ -61,7 +61,7 @@ namespace Ryujinx.HLE.HOS.Services.Sdb.Pl
|
|||
// GetSharedMemoryNativeHandle() -> handle<copy>
|
||||
public ResultCode GetSharedMemoryNativeHandle(ServiceCtx context)
|
||||
{
|
||||
context.Device.System.Font.EnsureInitialized(context.Device.System.ContentManager, false);
|
||||
context.Device.System.Font.EnsureInitialized(context.Device.System.ContentManager);
|
||||
|
||||
if (context.Process.HandleTable.GenerateHandle(context.Device.System.FontSharedMem, out int handle) != KernelResult.Success)
|
||||
{
|
||||
|
|
|
@ -4,6 +4,7 @@ using Ryujinx.Configuration;
|
|||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.Gpu;
|
||||
using Ryujinx.HLE.FileSystem;
|
||||
using Ryujinx.HLE.FileSystem.Content;
|
||||
using Ryujinx.HLE.HOS;
|
||||
using Ryujinx.HLE.HOS.Services;
|
||||
using Ryujinx.HLE.HOS.SystemState;
|
||||
|
@ -15,11 +16,11 @@ namespace Ryujinx.HLE
|
|||
{
|
||||
public class Switch : IDisposable
|
||||
{
|
||||
internal IAalOutput AudioOut { get; private set; }
|
||||
public IAalOutput AudioOut { get; private set; }
|
||||
|
||||
internal DeviceMemory Memory { get; private set; }
|
||||
|
||||
internal GpuContext Gpu { get; private set; }
|
||||
public GpuContext Gpu { get; private set; }
|
||||
|
||||
public VirtualFileSystem FileSystem { get; private set; }
|
||||
|
||||
|
@ -35,7 +36,7 @@ namespace Ryujinx.HLE
|
|||
|
||||
public event EventHandler Finish;
|
||||
|
||||
public Switch(IRenderer renderer, IAalOutput audioOut)
|
||||
public Switch(VirtualFileSystem fileSystem, ContentManager contentManager, IRenderer renderer, IAalOutput audioOut)
|
||||
{
|
||||
if (renderer == null)
|
||||
{
|
||||
|
@ -53,9 +54,9 @@ namespace Ryujinx.HLE
|
|||
|
||||
Gpu = new GpuContext(renderer);
|
||||
|
||||
FileSystem = new VirtualFileSystem();
|
||||
FileSystem = fileSystem;
|
||||
|
||||
System = new Horizon(this);
|
||||
System = new Horizon(this, contentManager);
|
||||
|
||||
Statistics = new PerformanceStatistics();
|
||||
|
||||
|
@ -78,15 +79,20 @@ namespace Ryujinx.HLE
|
|||
System.EnableMultiCoreScheduling();
|
||||
}
|
||||
|
||||
System.FsIntegrityCheckLevel = ConfigurationState.Instance.System.EnableFsIntegrityChecks
|
||||
? IntegrityCheckLevel.ErrorOnInvalid
|
||||
: IntegrityCheckLevel.None;
|
||||
System.FsIntegrityCheckLevel = GetIntigrityCheckLevel();
|
||||
|
||||
System.GlobalAccessLogMode = ConfigurationState.Instance.System.FsGlobalAccessLogMode;
|
||||
|
||||
ServiceConfiguration.IgnoreMissingServices = ConfigurationState.Instance.System.IgnoreMissingServices;
|
||||
}
|
||||
|
||||
public static IntegrityCheckLevel GetIntigrityCheckLevel()
|
||||
{
|
||||
return ConfigurationState.Instance.System.EnableFsIntegrityChecks
|
||||
? IntegrityCheckLevel.ErrorOnInvalid
|
||||
: IntegrityCheckLevel.None;
|
||||
}
|
||||
|
||||
public void LoadCart(string exeFsDir, string romFsFile = null)
|
||||
{
|
||||
System.LoadCart(exeFsDir, romFsFile);
|
||||
|
@ -129,7 +135,7 @@ namespace Ryujinx.HLE
|
|||
|
||||
internal void Unload()
|
||||
{
|
||||
FileSystem.Dispose();
|
||||
FileSystem.Unload();
|
||||
|
||||
Memory.Dispose();
|
||||
}
|
||||
|
@ -150,6 +156,7 @@ namespace Ryujinx.HLE
|
|||
{
|
||||
System.Dispose();
|
||||
VsyncEvent.Dispose();
|
||||
AudioOut.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue