Update to LibHac 0.13.1 (#2475)
* Update to LibHac 0.13.1 * Recreate directories for indexed saves if they're missing on emulator start
This commit is contained in:
parent
3977d1f72b
commit
dadc0e59da
32 changed files with 1869 additions and 584 deletions
|
@ -1,7 +1,9 @@
|
|||
using LibHac;
|
||||
using LibHac.Common;
|
||||
using LibHac.Fs;
|
||||
using LibHac.Fs.Fsa;
|
||||
using LibHac.Fs.Shim;
|
||||
using LibHac.Ncm;
|
||||
using Ryujinx.HLE.HOS.Services.Mii.Types;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
|
@ -14,8 +16,6 @@ namespace Ryujinx.HLE.HOS.Services.Mii
|
|||
|
||||
private const ulong DatabaseTestSaveDataId = 0x8000000000000031;
|
||||
private const ulong DatabaseSaveDataId = 0x8000000000000030;
|
||||
private const ulong NsTitleId = 0x010000000000001F;
|
||||
private const ulong SdbTitleId = 0x0100000000000039;
|
||||
|
||||
private static U8String DatabasePath = new U8String("mii:/MiiDatabase.dat");
|
||||
private static U8String MountName = new U8String("mii");
|
||||
|
@ -23,7 +23,7 @@ namespace Ryujinx.HLE.HOS.Services.Mii
|
|||
private NintendoFigurineDatabase _database;
|
||||
private bool _isDirty;
|
||||
|
||||
private FileSystemClient _filesystemClient;
|
||||
private HorizonClient _horizonClient;
|
||||
|
||||
protected ulong UpdateCounter { get; private set; }
|
||||
|
||||
|
@ -94,74 +94,62 @@ namespace Ryujinx.HLE.HOS.Services.Mii
|
|||
return virtualIndex;
|
||||
}
|
||||
|
||||
public void InitializeDatabase(Switch device)
|
||||
public void InitializeDatabase(HorizonClient horizonClient)
|
||||
{
|
||||
_filesystemClient = device.FileSystem.FsClient;
|
||||
_horizonClient = horizonClient;
|
||||
|
||||
// Ensure we have valid data in the database
|
||||
_database.Format();
|
||||
|
||||
// TODO: Unmount is currently not implemented properly at dispose, implement that and decrement MountCounter.
|
||||
MountCounter = 0;
|
||||
|
||||
MountSave();
|
||||
}
|
||||
|
||||
private Result MountSave()
|
||||
{
|
||||
Result result = Result.Success;
|
||||
|
||||
if (MountCounter == 0)
|
||||
if (MountCounter != 0)
|
||||
{
|
||||
ulong targetSaveDataId;
|
||||
ulong targetTitleId;
|
||||
MountCounter++;
|
||||
return Result.Success;
|
||||
}
|
||||
|
||||
ulong saveDataId = IsTestModeEnabled ? DatabaseTestSaveDataId : DatabaseSaveDataId;
|
||||
|
||||
Result result = _horizonClient.Fs.MountSystemSaveData(MountName, SaveDataSpaceId.System, saveDataId);
|
||||
|
||||
if (result.IsFailure())
|
||||
{
|
||||
if (!ResultFs.TargetNotFound.Includes(result))
|
||||
return result;
|
||||
|
||||
if (IsTestModeEnabled)
|
||||
{
|
||||
targetSaveDataId = DatabaseTestSaveDataId;
|
||||
targetTitleId = SdbTitleId;
|
||||
result = _horizonClient.Fs.CreateSystemSaveData(saveDataId, 0x10000, 0x10000,
|
||||
SaveDataFlags.KeepAfterResettingSystemSaveDataWithoutUserSaveData);
|
||||
if (result.IsFailure()) return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
targetSaveDataId = DatabaseSaveDataId;
|
||||
|
||||
// Nintendo use NS TitleID when creating the production save even on sdb, let's follow that behaviour.
|
||||
targetTitleId = NsTitleId;
|
||||
result = _horizonClient.Fs.CreateSystemSaveData(saveDataId, SystemProgramId.Ns.Value, 0x10000,
|
||||
0x10000, SaveDataFlags.KeepAfterResettingSystemSaveDataWithoutUserSaveData);
|
||||
if (result.IsFailure()) return result;
|
||||
}
|
||||
|
||||
U8Span mountName = new U8Span(MountName);
|
||||
|
||||
result = _filesystemClient.MountSystemSaveData(mountName, SaveDataSpaceId.System, targetSaveDataId);
|
||||
|
||||
if (result.IsFailure())
|
||||
{
|
||||
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
|
||||
result = _filesystemClient.CreateSystemSaveData(targetSaveDataId, targetTitleId, 0x10000,
|
||||
0x10000, SaveDataFlags.KeepAfterResettingSystemSaveDataWithoutUserSaveData);
|
||||
if (result.IsFailure()) return result;
|
||||
|
||||
result = _filesystemClient.MountSystemSaveData(mountName, SaveDataSpaceId.System, targetSaveDataId);
|
||||
if (result.IsFailure()) return result;
|
||||
}
|
||||
}
|
||||
|
||||
if (result == Result.Success)
|
||||
{
|
||||
MountCounter++;
|
||||
}
|
||||
result = _horizonClient.Fs.MountSystemSaveData(MountName, SaveDataSpaceId.System, saveDataId);
|
||||
if (result.IsFailure()) return result;
|
||||
}
|
||||
|
||||
if (result == Result.Success)
|
||||
{
|
||||
MountCounter++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public ResultCode DeleteFile()
|
||||
{
|
||||
ResultCode result = (ResultCode)_filesystemClient.DeleteFile(DatabasePath).Value;
|
||||
ResultCode result = (ResultCode)_horizonClient.Fs.DeleteFile(DatabasePath).Value;
|
||||
|
||||
_filesystemClient.Commit(MountName);
|
||||
_horizonClient.Fs.Commit(MountName);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -179,17 +167,17 @@ namespace Ryujinx.HLE.HOS.Services.Mii
|
|||
|
||||
ResetDatabase();
|
||||
|
||||
Result result = _filesystemClient.OpenFile(out FileHandle handle, DatabasePath, OpenMode.Read);
|
||||
Result result = _horizonClient.Fs.OpenFile(out FileHandle handle, DatabasePath, OpenMode.Read);
|
||||
|
||||
if (result.IsSuccess())
|
||||
{
|
||||
result = _filesystemClient.GetFileSize(out long fileSize, handle);
|
||||
result = _horizonClient.Fs.GetFileSize(out long fileSize, handle);
|
||||
|
||||
if (result.IsSuccess())
|
||||
{
|
||||
if (fileSize == Unsafe.SizeOf<NintendoFigurineDatabase>())
|
||||
{
|
||||
result = _filesystemClient.ReadFile(handle, 0, _database.AsSpan());
|
||||
result = _horizonClient.Fs.ReadFile(handle, 0, _database.AsSpan());
|
||||
|
||||
if (result.IsSuccess())
|
||||
{
|
||||
|
@ -211,7 +199,7 @@ namespace Ryujinx.HLE.HOS.Services.Mii
|
|||
}
|
||||
}
|
||||
|
||||
_filesystemClient.CloseFile(handle);
|
||||
_horizonClient.Fs.CloseFile(handle);
|
||||
|
||||
return (ResultCode)result.Value;
|
||||
}
|
||||
|
@ -225,32 +213,32 @@ namespace Ryujinx.HLE.HOS.Services.Mii
|
|||
|
||||
private Result ForceSaveDatabase()
|
||||
{
|
||||
Result result = _filesystemClient.CreateFile(DatabasePath, Unsafe.SizeOf<NintendoFigurineDatabase>());
|
||||
Result result = _horizonClient.Fs.CreateFile(DatabasePath, Unsafe.SizeOf<NintendoFigurineDatabase>());
|
||||
|
||||
if (result.IsSuccess() || ResultFs.PathAlreadyExists.Includes(result))
|
||||
{
|
||||
result = _filesystemClient.OpenFile(out FileHandle handle, DatabasePath, OpenMode.Write);
|
||||
result = _horizonClient.Fs.OpenFile(out FileHandle handle, DatabasePath, OpenMode.Write);
|
||||
|
||||
if (result.IsSuccess())
|
||||
{
|
||||
result = _filesystemClient.GetFileSize(out long fileSize, handle);
|
||||
result = _horizonClient.Fs.GetFileSize(out long fileSize, handle);
|
||||
|
||||
if (result.IsSuccess())
|
||||
{
|
||||
// If the size doesn't match, recreate the file
|
||||
if (fileSize != Unsafe.SizeOf<NintendoFigurineDatabase>())
|
||||
{
|
||||
_filesystemClient.CloseFile(handle);
|
||||
_horizonClient.Fs.CloseFile(handle);
|
||||
|
||||
result = _filesystemClient.DeleteFile(DatabasePath);
|
||||
result = _horizonClient.Fs.DeleteFile(DatabasePath);
|
||||
|
||||
if (result.IsSuccess())
|
||||
{
|
||||
result = _filesystemClient.CreateFile(DatabasePath, Unsafe.SizeOf<NintendoFigurineDatabase>());
|
||||
result = _horizonClient.Fs.CreateFile(DatabasePath, Unsafe.SizeOf<NintendoFigurineDatabase>());
|
||||
|
||||
if (result.IsSuccess())
|
||||
{
|
||||
result = _filesystemClient.OpenFile(out handle, DatabasePath, OpenMode.Write);
|
||||
result = _horizonClient.Fs.OpenFile(out handle, DatabasePath, OpenMode.Write);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -260,10 +248,10 @@ namespace Ryujinx.HLE.HOS.Services.Mii
|
|||
}
|
||||
}
|
||||
|
||||
result = _filesystemClient.WriteFile(handle, 0, _database.AsReadOnlySpan(), WriteOption.Flush);
|
||||
result = _horizonClient.Fs.WriteFile(handle, 0, _database.AsReadOnlySpan(), WriteOption.Flush);
|
||||
}
|
||||
|
||||
_filesystemClient.CloseFile(handle);
|
||||
_horizonClient.Fs.CloseFile(handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -271,7 +259,7 @@ namespace Ryujinx.HLE.HOS.Services.Mii
|
|||
{
|
||||
_isDirty = false;
|
||||
|
||||
result = _filesystemClient.Commit(MountName);
|
||||
result = _horizonClient.Fs.Commit(MountName);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue