From cecbd256a5b95cce815fcbbffc40b3898c319d9f Mon Sep 17 00:00:00 2001 From: Alex Barney Date: Tue, 3 Mar 2020 07:07:06 -0700 Subject: [PATCH] Add support for cache storage (#936) * Update LibHac * Run EnsureApplicationCacheStorage when launching a game * Add new FS commands --- Ryujinx.HLE/FileSystem/VirtualFileSystem.cs | 2 ++ Ryujinx.HLE/HOS/Horizon.cs | 13 ++++++-- .../HOS/Services/Fs/IDeviceOperator.cs | 11 +++++++ .../HOS/Services/Fs/IFileSystemProxy.cs | 31 +++++++++++++++++++ .../HOS/Services/Mii/MiiDatabaseManager.cs | 6 ++-- Ryujinx.HLE/Ryujinx.HLE.csproj | 2 +- Ryujinx/Ui/ApplicationLibrary.cs | 4 +-- Ryujinx/Ui/GameTableContextMenu.cs | 4 +-- 8 files changed, 63 insertions(+), 10 deletions(-) diff --git a/Ryujinx.HLE/FileSystem/VirtualFileSystem.cs b/Ryujinx.HLE/FileSystem/VirtualFileSystem.cs index 884f41973..e671b4515 100644 --- a/Ryujinx.HLE/FileSystem/VirtualFileSystem.cs +++ b/Ryujinx.HLE/FileSystem/VirtualFileSystem.cs @@ -26,6 +26,7 @@ namespace Ryujinx.HLE.FileSystem public FileSystemServer FsServer { get; private set; } public FileSystemClient FsClient { get; private set; } public EmulatedGameCard GameCard { get; private set; } + public EmulatedSdCard SdCard { get; private set; } private VirtualFileSystem() { @@ -208,6 +209,7 @@ namespace Ryujinx.HLE.FileSystem DefaultFsServerObjects fsServerObjects = DefaultFsServerObjects.GetDefaultEmulatedCreators(serverBaseFs, KeySet); GameCard = fsServerObjects.GameCard; + SdCard = fsServerObjects.SdCard; FileSystemServerConfig fsServerConfig = new FileSystemServerConfig { diff --git a/Ryujinx.HLE/HOS/Horizon.cs b/Ryujinx.HLE/HOS/Horizon.cs index b3e3ea013..e70a9e59e 100644 --- a/Ryujinx.HLE/HOS/Horizon.cs +++ b/Ryujinx.HLE/HOS/Horizon.cs @@ -519,7 +519,7 @@ namespace Ryujinx.HLE.HOS { Result result = codeFs.OpenFile(out IFile npdmFile, "/main.npdm", OpenMode.Read); - if (result == ResultFs.PathNotFound) + if (ResultFs.PathNotFound.Includes(result)) { Logger.PrintWarning(LogClass.Loader, "NPDM file not found, using default values!"); @@ -691,7 +691,16 @@ 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(Device.FileSystem.FsClient, out _, titleId, ref control, ref user); + FileSystemClient fs = Device.FileSystem.FsClient; + + Result rc = fs.EnsureApplicationCacheStorage(out _, titleId, ref ControlData.Value); + + if (rc.IsFailure()) + { + Logger.PrintError(LogClass.Application, $"Error calling EnsureApplicationCacheStorage. Result code {rc.ToStringWithName()}"); + } + + rc = EnsureApplicationSaveData(fs, out _, titleId, ref ControlData.Value, ref user); if (rc.IsFailure()) { diff --git a/Ryujinx.HLE/HOS/Services/Fs/IDeviceOperator.cs b/Ryujinx.HLE/HOS/Services/Fs/IDeviceOperator.cs index 426b50ed2..c9f2f74c4 100644 --- a/Ryujinx.HLE/HOS/Services/Fs/IDeviceOperator.cs +++ b/Ryujinx.HLE/HOS/Services/Fs/IDeviceOperator.cs @@ -12,6 +12,17 @@ namespace Ryujinx.HLE.HOS.Services.Fs _baseOperator = baseOperator; } + [Command(0)] + // IsSdCardInserted() -> b8 is_inserted + public ResultCode IsSdCardInserted(ServiceCtx context) + { + Result result = _baseOperator.IsSdCardInserted(out bool isInserted); + + context.ResponseData.Write(isInserted); + + return (ResultCode)result.Value; + } + [Command(200)] // IsGameCardInserted() -> b8 is_inserted public ResultCode IsGameCardInserted(ServiceCtx context) diff --git a/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs b/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs index 7c31814f3..43ae80aa0 100644 --- a/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs +++ b/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs @@ -448,6 +448,37 @@ namespace Ryujinx.HLE.HOS.Services.Fs return (ResultCode)result.Value; } + [Command(630)] + // SetSdCardAccessibility(u8) + public ResultCode SetSdCardAccessibility(ServiceCtx context) + { + bool isAccessible = context.RequestData.ReadBoolean(); + + return (ResultCode)_baseFileSystemProxy.SetSdCardAccessibility(isAccessible).Value; + } + + [Command(631)] + // IsSdCardAccessible() -> u8 + public ResultCode IsSdCardAccessible(ServiceCtx context) + { + Result result = _baseFileSystemProxy.IsSdCardAccessible(out bool isAccessible); + + context.ResponseData.Write(isAccessible); + + return (ResultCode)result.Value; + } + + [Command(1004)] + // SetGlobalAccessLogMode(u32 mode) + public ResultCode SetGlobalAccessLogMode(ServiceCtx context) + { + int mode = context.RequestData.ReadInt32(); + + context.Device.System.GlobalAccessLogMode = mode; + + return ResultCode.Success; + } + [Command(1005)] // GetGlobalAccessLogMode() -> u32 logMode public ResultCode GetGlobalAccessLogMode(ServiceCtx context) diff --git a/Ryujinx.HLE/HOS/Services/Mii/MiiDatabaseManager.cs b/Ryujinx.HLE/HOS/Services/Mii/MiiDatabaseManager.cs index 30bcab959..6ba1b2bf9 100644 --- a/Ryujinx.HLE/HOS/Services/Mii/MiiDatabaseManager.cs +++ b/Ryujinx.HLE/HOS/Services/Mii/MiiDatabaseManager.cs @@ -132,7 +132,7 @@ namespace Ryujinx.HLE.HOS.Services.Mii if (result.IsFailure()) { - if (ResultFs.TargetNotFound == result) + if (ResultFs.TargetNotFound.Includes(result)) { // TODO: We're currently always specifying the owner ID because FS doesn't have a way of // knowing which process called it @@ -212,7 +212,7 @@ namespace Ryujinx.HLE.HOS.Services.Mii return (ResultCode)result.Value; } - else if (result == ResultFs.PathNotFound) + else if (ResultFs.PathNotFound.Includes(result)) { return (ResultCode)ForceSaveDatabase().Value; } @@ -224,7 +224,7 @@ namespace Ryujinx.HLE.HOS.Services.Mii { Result result = _filesystemClient.CreateFile(DatabasePath, Unsafe.SizeOf()); - if (result.IsSuccess() || result == ResultFs.PathAlreadyExists) + if (result.IsSuccess() || ResultFs.PathAlreadyExists.Includes(result)) { result = _filesystemClient.OpenFile(out FileHandle handle, DatabasePath, OpenMode.Write); diff --git a/Ryujinx.HLE/Ryujinx.HLE.csproj b/Ryujinx.HLE/Ryujinx.HLE.csproj index e9540ab87..01c29fbab 100644 --- a/Ryujinx.HLE/Ryujinx.HLE.csproj +++ b/Ryujinx.HLE/Ryujinx.HLE.csproj @@ -52,7 +52,7 @@ - + diff --git a/Ryujinx/Ui/ApplicationLibrary.cs b/Ryujinx/Ui/ApplicationLibrary.cs index 3500da7df..6cf2a608c 100644 --- a/Ryujinx/Ui/ApplicationLibrary.cs +++ b/Ryujinx/Ui/ApplicationLibrary.cs @@ -148,7 +148,7 @@ namespace Ryujinx.Ui Result result = pfs.OpenFile(out IFile npdmFile, "/main.npdm", OpenMode.Read); - if (result != ResultFs.PathNotFound) + if (ResultFs.PathNotFound.Includes(result)) { Npdm npdm = new Npdm(npdmFile.AsStream()); @@ -347,7 +347,7 @@ namespace Ryujinx.Ui { SaveDataFilter filter = new SaveDataFilter(); filter.SetUserId(new UserId(1, 0)); - filter.SetTitleId(new TitleId(titleIdNum)); + filter.SetProgramId(new TitleId(titleIdNum)); Result result = virtualFileSystem.FsClient.FindSaveDataWithFilter(out SaveDataInfo saveDataInfo, SaveDataSpaceId.User, ref filter); diff --git a/Ryujinx/Ui/GameTableContextMenu.cs b/Ryujinx/Ui/GameTableContextMenu.cs index 3fbc985a6..6cddb9676 100644 --- a/Ryujinx/Ui/GameTableContextMenu.cs +++ b/Ryujinx/Ui/GameTableContextMenu.cs @@ -75,11 +75,11 @@ namespace Ryujinx.Ui SaveDataFilter filter = new SaveDataFilter(); filter.SetUserId(new UserId(1, 0)); - filter.SetTitleId(new TitleId(titleId)); + filter.SetProgramId(new TitleId(titleId)); Result result = _virtualFileSystem.FsClient.FindSaveDataWithFilter(out SaveDataInfo saveDataInfo, SaveDataSpaceId.User, ref filter); - if (result == ResultFs.TargetNotFound) + if (ResultFs.TargetNotFound.Includes(result)) { // Savedata was not found. Ask the user if they want to create it using MessageDialog messageDialog = new MessageDialog(null, DialogFlags.Modal, MessageType.Question, ButtonsType.YesNo, null)