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:
Thog 2020-01-21 23:23:11 +01:00 committed by Ac_K
parent b4b2b8b162
commit d6b9babe1d
16 changed files with 284 additions and 215 deletions

View file

@ -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();