initial save path implementation

This commit is contained in:
emmaus 2018-08-23 19:12:22 +00:00
parent 3227218114
commit c35d9ba043
8 changed files with 174 additions and 11 deletions

View file

@ -0,0 +1,14 @@
using Ryujinx.HLE.HOS.SystemState;
namespace Ryujinx.HLE.FileSystem
{
struct Save
{
public long TitleId { get; set; }
public long SaveID { get; set; }
public UserId UserID { get; set; }
public SaveDataType SaveDataType { get; set; }
public SaveSpaceId SaveSpaceId { get; set; }
}
}

View file

@ -0,0 +1,12 @@
namespace Ryujinx.HLE.FileSystem
{
enum SaveDataType
{
SystemSaveData,
SaveData,
BcatDeliveryCacheStorage,
DeviceSaveData,
TemporaryStorage,
CacheStorage
}
}

View file

@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Ryujinx.HLE.HOS;
namespace Ryujinx.HLE.FileSystem
{
static class SaveHelper
{
public static string GetSavePath(Save SaveMetaData, ServiceCtx Context)
{
string BasePartitionPath = "nand";
long CurrentTitleId = SaveMetaData.TitleId;
switch (SaveMetaData.SaveSpaceId)
{
case SaveSpaceId.NandUser:
BasePartitionPath = Path.Combine(BasePartitionPath, "user");
break;
case SaveSpaceId.NandSystem:
BasePartitionPath = Path.Combine(BasePartitionPath, "system");
break;
case SaveSpaceId.SdCard:
BasePartitionPath = Path.Combine("sdmc", "Nintendo");
break;
}
BasePartitionPath = Path.Combine(BasePartitionPath, "save");
if (SaveMetaData.TitleId == 0 && SaveMetaData.SaveDataType == SaveDataType.SaveData)
{
CurrentTitleId = Context.Process.MetaData.ACI0.TitleId;
}
string SavePath = Path.Combine(BasePartitionPath,
SaveMetaData.SaveID.ToString("X16"),
SaveMetaData.UserID.ToString(),
SaveMetaData.SaveDataType == SaveDataType.SaveData ? CurrentTitleId.ToString("X16") : string.Empty);
return SavePath;
}
}
}

View file

@ -0,0 +1,10 @@
namespace Ryujinx.HLE.FileSystem
{
enum SaveSpaceId
{
NandSystem,
NandUser,
SdCard,
TemporaryStorage
}
}

View file

@ -1,7 +1,8 @@
using System;
using System.IO;
using Ryujinx.HLE.HOS;
namespace Ryujinx.HLE
namespace Ryujinx.HLE.FileSystem
{
class VirtualFileSystem : IDisposable
{
@ -50,7 +51,10 @@ namespace Ryujinx.HLE
public string GetSdCardPath() => MakeDirAndGetFullPath(SdCardPath);
public string GetGameSavesPath() => MakeDirAndGetFullPath(NandPath);
public string GetNandPath() => MakeDirAndGetFullPath(NandPath);
public string GetGameSavesPath(Save SaveMetaData, ServiceCtx Context)
=> MakeDirAndGetFullPath(SaveHelper.GetSavePath(SaveMetaData, Context));
public string GetSystemPath() => MakeDirAndGetFullPath(SystemPath);

View file

@ -1,6 +1,7 @@
using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.Logging;
using System.Collections.Generic;
using Ryujinx.HLE.FileSystem;
namespace Ryujinx.HLE.HOS.Services.FspSrv
{
@ -14,13 +15,14 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
{
m_Commands = new Dictionary<int, ServiceProcessRequest>()
{
{ 1, SetCurrentProcess },
{ 18, OpenSdCardFileSystem },
{ 22, CreateSaveDataFileSystem },
{ 51, OpenSaveDataFileSystem },
{ 200, OpenDataStorageByCurrentProcess },
{ 203, OpenPatchDataStorageByCurrentProcess },
{ 1005, GetGlobalAccessLogMode }
{ 1, SetCurrentProcess },
{ 18, OpenSdCardFileSystem },
{ 22, CreateSaveDataFileSystem },
{ 51, OpenSaveDataFileSystem },
{ 52, OpenSaveDataFileSystemBySystemSaveDataId },
{ 200, OpenDataStorageByCurrentProcess },
{ 203, OpenPatchDataStorageByCurrentProcess },
{ 1005, GetGlobalAccessLogMode }
};
}
@ -38,14 +40,49 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
public long CreateSaveDataFileSystem(ServiceCtx Context)
{
Context.Device.Log.PrintStub(LogClass.ServiceFs, "Stubbed.");
long TitleId = Context.RequestData.ReadInt64();
long UserIdHigh = Context.RequestData.ReadInt64();
long UserIdLow = Context.RequestData.ReadInt64();
long SaveId = Context.RequestData.ReadInt64();
SaveDataType Type = (SaveDataType)Context.RequestData.ReadByte();
Save SaveInfo = new Save()
{
TitleId = TitleId,
UserID = new SystemState.UserId(UserIdLow, UserIdHigh),
SaveID = SaveId,
SaveDataType = Type
};
switch (SaveInfo.SaveDataType)
{
case SaveDataType.SaveData:
SaveInfo.SaveSpaceId = SaveSpaceId.NandUser;
break;
case SaveDataType.SystemSaveData:
SaveInfo.SaveSpaceId = SaveSpaceId.NandSystem;
break;
}
byte[] SaveCreateStruct = Context.RequestData.ReadBytes(0x40);
byte[] Input = Context.RequestData.ReadBytes(0x10);
Context.Device.FileSystem.GetGameSavesPath(SaveInfo, Context);
return 0;
}
public long OpenSaveDataFileSystem(ServiceCtx Context)
{
MakeObject(Context, new IFileSystem(Context.Device.FileSystem.GetGameSavesPath()));
LoadSaveDataFileSystem(Context);
return 0;
}
public long OpenSaveDataFileSystemBySystemSaveDataId(ServiceCtx Context)
{
LoadSaveDataFileSystem(Context);
return 0;
}
@ -70,5 +107,32 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
return 0;
}
public void LoadSaveDataFileSystem(ServiceCtx Context)
{
byte id = Context.RequestData.ReadByte();
SaveSpaceId SaveSpaceId = (SaveSpaceId)id;
int Unknown = Context.RequestData.ReadInt32();
long TitleId = Context.RequestData.ReadInt64();
byte[] UserId = Context.RequestData.ReadBytes(0x10);
long SaveId = Context.RequestData.ReadInt64();
byte type = Context.RequestData.ReadByte();
SaveDataType Type = (SaveDataType)type;
Save SaveInfo = new Save()
{
TitleId = TitleId,
UserID = new SystemState.UserId(UserId),
SaveID = SaveId,
SaveDataType = Type
};
SaveInfo.SaveSpaceId = SaveSpaceId;
MakeObject(Context, new IFileSystem(Context.Device.FileSystem.GetGameSavesPath(SaveInfo, Context)));
}
}
}

View file

@ -43,6 +43,20 @@ namespace Ryujinx.HLE.HOS.SystemState
this.Bytes = Bytes;
}
public UserId(byte[] UserIdBytes)
{
Bytes = UserIdBytes;
UserIdHex = string.Empty;
foreach (byte Byte in Bytes)
{
UserIdHex += Byte.ToString("X2");
}
this.Bytes = Bytes;
}
public UserId(string UserIdHex)
{
if (UserIdHex == null || UserIdHex.Length != 32 || !UserIdHex.All("0123456789abcdefABCDEF".Contains))

View file

@ -1,6 +1,7 @@
using Ryujinx.Audio;
using Ryujinx.Graphics;
using Ryujinx.Graphics.Gal;
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS;
using Ryujinx.HLE.Input;
using Ryujinx.HLE.Logging;