Add support for cache storage (#936)
* Update LibHac * Run EnsureApplicationCacheStorage when launching a game * Add new FS commands
This commit is contained in:
parent
dc97457bf0
commit
cecbd256a5
8 changed files with 63 additions and 10 deletions
|
@ -26,6 +26,7 @@ namespace Ryujinx.HLE.FileSystem
|
||||||
public FileSystemServer FsServer { get; private set; }
|
public FileSystemServer FsServer { get; private set; }
|
||||||
public FileSystemClient FsClient { get; private set; }
|
public FileSystemClient FsClient { get; private set; }
|
||||||
public EmulatedGameCard GameCard { get; private set; }
|
public EmulatedGameCard GameCard { get; private set; }
|
||||||
|
public EmulatedSdCard SdCard { get; private set; }
|
||||||
|
|
||||||
private VirtualFileSystem()
|
private VirtualFileSystem()
|
||||||
{
|
{
|
||||||
|
@ -208,6 +209,7 @@ namespace Ryujinx.HLE.FileSystem
|
||||||
DefaultFsServerObjects fsServerObjects = DefaultFsServerObjects.GetDefaultEmulatedCreators(serverBaseFs, KeySet);
|
DefaultFsServerObjects fsServerObjects = DefaultFsServerObjects.GetDefaultEmulatedCreators(serverBaseFs, KeySet);
|
||||||
|
|
||||||
GameCard = fsServerObjects.GameCard;
|
GameCard = fsServerObjects.GameCard;
|
||||||
|
SdCard = fsServerObjects.SdCard;
|
||||||
|
|
||||||
FileSystemServerConfig fsServerConfig = new FileSystemServerConfig
|
FileSystemServerConfig fsServerConfig = new FileSystemServerConfig
|
||||||
{
|
{
|
||||||
|
|
|
@ -519,7 +519,7 @@ namespace Ryujinx.HLE.HOS
|
||||||
{
|
{
|
||||||
Result result = codeFs.OpenFile(out IFile npdmFile, "/main.npdm", OpenMode.Read);
|
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!");
|
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.");
|
"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())
|
if (rc.IsFailure())
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,6 +12,17 @@ namespace Ryujinx.HLE.HOS.Services.Fs
|
||||||
_baseOperator = baseOperator;
|
_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)]
|
[Command(200)]
|
||||||
// IsGameCardInserted() -> b8 is_inserted
|
// IsGameCardInserted() -> b8 is_inserted
|
||||||
public ResultCode IsGameCardInserted(ServiceCtx context)
|
public ResultCode IsGameCardInserted(ServiceCtx context)
|
||||||
|
|
|
@ -448,6 +448,37 @@ namespace Ryujinx.HLE.HOS.Services.Fs
|
||||||
return (ResultCode)result.Value;
|
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)]
|
[Command(1005)]
|
||||||
// GetGlobalAccessLogMode() -> u32 logMode
|
// GetGlobalAccessLogMode() -> u32 logMode
|
||||||
public ResultCode GetGlobalAccessLogMode(ServiceCtx context)
|
public ResultCode GetGlobalAccessLogMode(ServiceCtx context)
|
||||||
|
|
|
@ -132,7 +132,7 @@ namespace Ryujinx.HLE.HOS.Services.Mii
|
||||||
|
|
||||||
if (result.IsFailure())
|
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
|
// TODO: We're currently always specifying the owner ID because FS doesn't have a way of
|
||||||
// knowing which process called it
|
// knowing which process called it
|
||||||
|
@ -212,7 +212,7 @@ namespace Ryujinx.HLE.HOS.Services.Mii
|
||||||
|
|
||||||
return (ResultCode)result.Value;
|
return (ResultCode)result.Value;
|
||||||
}
|
}
|
||||||
else if (result == ResultFs.PathNotFound)
|
else if (ResultFs.PathNotFound.Includes(result))
|
||||||
{
|
{
|
||||||
return (ResultCode)ForceSaveDatabase().Value;
|
return (ResultCode)ForceSaveDatabase().Value;
|
||||||
}
|
}
|
||||||
|
@ -224,7 +224,7 @@ namespace Ryujinx.HLE.HOS.Services.Mii
|
||||||
{
|
{
|
||||||
Result result = _filesystemClient.CreateFile(DatabasePath, Unsafe.SizeOf<NintendoFigurineDatabase>());
|
Result result = _filesystemClient.CreateFile(DatabasePath, Unsafe.SizeOf<NintendoFigurineDatabase>());
|
||||||
|
|
||||||
if (result.IsSuccess() || result == ResultFs.PathAlreadyExists)
|
if (result.IsSuccess() || ResultFs.PathAlreadyExists.Includes(result))
|
||||||
{
|
{
|
||||||
result = _filesystemClient.OpenFile(out FileHandle handle, DatabasePath, OpenMode.Write);
|
result = _filesystemClient.OpenFile(out FileHandle handle, DatabasePath, OpenMode.Write);
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Concentus" Version="1.1.7" />
|
<PackageReference Include="Concentus" Version="1.1.7" />
|
||||||
<PackageReference Include="LibHac" Version="0.8.2" />
|
<PackageReference Include="LibHac" Version="0.9.0" />
|
||||||
<PackageReference Include="MsgPack.Cli" Version="1.0.1" />
|
<PackageReference Include="MsgPack.Cli" Version="1.0.1" />
|
||||||
<PackageReference Include="TimeZoneConverter.Posix" Version="2.1.0" />
|
<PackageReference Include="TimeZoneConverter.Posix" Version="2.1.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -148,7 +148,7 @@ namespace Ryujinx.Ui
|
||||||
|
|
||||||
Result result = pfs.OpenFile(out IFile npdmFile, "/main.npdm", OpenMode.Read);
|
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());
|
Npdm npdm = new Npdm(npdmFile.AsStream());
|
||||||
|
|
||||||
|
@ -347,7 +347,7 @@ namespace Ryujinx.Ui
|
||||||
{
|
{
|
||||||
SaveDataFilter filter = new SaveDataFilter();
|
SaveDataFilter filter = new SaveDataFilter();
|
||||||
filter.SetUserId(new UserId(1, 0));
|
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);
|
Result result = virtualFileSystem.FsClient.FindSaveDataWithFilter(out SaveDataInfo saveDataInfo, SaveDataSpaceId.User, ref filter);
|
||||||
|
|
||||||
|
|
|
@ -75,11 +75,11 @@ namespace Ryujinx.Ui
|
||||||
|
|
||||||
SaveDataFilter filter = new SaveDataFilter();
|
SaveDataFilter filter = new SaveDataFilter();
|
||||||
filter.SetUserId(new UserId(1, 0));
|
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);
|
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
|
// 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)
|
using MessageDialog messageDialog = new MessageDialog(null, DialogFlags.Modal, MessageType.Question, ButtonsType.YesNo, null)
|
||||||
|
|
Reference in a new issue