initial save path implementation
This commit is contained in:
parent
3227218114
commit
c35d9ba043
8 changed files with 174 additions and 11 deletions
14
Ryujinx.HLE/FileSystem/Save.cs
Normal file
14
Ryujinx.HLE/FileSystem/Save.cs
Normal 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; }
|
||||||
|
}
|
||||||
|
}
|
12
Ryujinx.HLE/FileSystem/SaveDataType.cs
Normal file
12
Ryujinx.HLE/FileSystem/SaveDataType.cs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
namespace Ryujinx.HLE.FileSystem
|
||||||
|
{
|
||||||
|
enum SaveDataType
|
||||||
|
{
|
||||||
|
SystemSaveData,
|
||||||
|
SaveData,
|
||||||
|
BcatDeliveryCacheStorage,
|
||||||
|
DeviceSaveData,
|
||||||
|
TemporaryStorage,
|
||||||
|
CacheStorage
|
||||||
|
}
|
||||||
|
}
|
44
Ryujinx.HLE/FileSystem/SaveHelper.cs
Normal file
44
Ryujinx.HLE/FileSystem/SaveHelper.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
10
Ryujinx.HLE/FileSystem/SaveSpaceId.cs
Normal file
10
Ryujinx.HLE/FileSystem/SaveSpaceId.cs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
namespace Ryujinx.HLE.FileSystem
|
||||||
|
{
|
||||||
|
enum SaveSpaceId
|
||||||
|
{
|
||||||
|
NandSystem,
|
||||||
|
NandUser,
|
||||||
|
SdCard,
|
||||||
|
TemporaryStorage
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,8 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using Ryujinx.HLE.HOS;
|
||||||
|
|
||||||
namespace Ryujinx.HLE
|
namespace Ryujinx.HLE.FileSystem
|
||||||
{
|
{
|
||||||
class VirtualFileSystem : IDisposable
|
class VirtualFileSystem : IDisposable
|
||||||
{
|
{
|
||||||
|
@ -50,7 +51,10 @@ namespace Ryujinx.HLE
|
||||||
|
|
||||||
public string GetSdCardPath() => MakeDirAndGetFullPath(SdCardPath);
|
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);
|
public string GetSystemPath() => MakeDirAndGetFullPath(SystemPath);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using Ryujinx.HLE.HOS.Ipc;
|
using Ryujinx.HLE.HOS.Ipc;
|
||||||
using Ryujinx.HLE.Logging;
|
using Ryujinx.HLE.Logging;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Ryujinx.HLE.FileSystem;
|
||||||
|
|
||||||
namespace Ryujinx.HLE.HOS.Services.FspSrv
|
namespace Ryujinx.HLE.HOS.Services.FspSrv
|
||||||
{
|
{
|
||||||
|
@ -14,13 +15,14 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
|
||||||
{
|
{
|
||||||
m_Commands = new Dictionary<int, ServiceProcessRequest>()
|
m_Commands = new Dictionary<int, ServiceProcessRequest>()
|
||||||
{
|
{
|
||||||
{ 1, SetCurrentProcess },
|
{ 1, SetCurrentProcess },
|
||||||
{ 18, OpenSdCardFileSystem },
|
{ 18, OpenSdCardFileSystem },
|
||||||
{ 22, CreateSaveDataFileSystem },
|
{ 22, CreateSaveDataFileSystem },
|
||||||
{ 51, OpenSaveDataFileSystem },
|
{ 51, OpenSaveDataFileSystem },
|
||||||
{ 200, OpenDataStorageByCurrentProcess },
|
{ 52, OpenSaveDataFileSystemBySystemSaveDataId },
|
||||||
{ 203, OpenPatchDataStorageByCurrentProcess },
|
{ 200, OpenDataStorageByCurrentProcess },
|
||||||
{ 1005, GetGlobalAccessLogMode }
|
{ 203, OpenPatchDataStorageByCurrentProcess },
|
||||||
|
{ 1005, GetGlobalAccessLogMode }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,14 +40,49 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
|
||||||
|
|
||||||
public long CreateSaveDataFileSystem(ServiceCtx Context)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long OpenSaveDataFileSystem(ServiceCtx Context)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -70,5 +107,32 @@ namespace Ryujinx.HLE.HOS.Services.FspSrv
|
||||||
|
|
||||||
return 0;
|
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)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -43,6 +43,20 @@ namespace Ryujinx.HLE.HOS.SystemState
|
||||||
this.Bytes = Bytes;
|
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)
|
public UserId(string UserIdHex)
|
||||||
{
|
{
|
||||||
if (UserIdHex == null || UserIdHex.Length != 32 || !UserIdHex.All("0123456789abcdefABCDEF".Contains))
|
if (UserIdHex == null || UserIdHex.Length != 32 || !UserIdHex.All("0123456789abcdefABCDEF".Contains))
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using Ryujinx.Audio;
|
using Ryujinx.Audio;
|
||||||
using Ryujinx.Graphics;
|
using Ryujinx.Graphics;
|
||||||
using Ryujinx.Graphics.Gal;
|
using Ryujinx.Graphics.Gal;
|
||||||
|
using Ryujinx.HLE.FileSystem;
|
||||||
using Ryujinx.HLE.HOS;
|
using Ryujinx.HLE.HOS;
|
||||||
using Ryujinx.HLE.Input;
|
using Ryujinx.HLE.Input;
|
||||||
using Ryujinx.HLE.Logging;
|
using Ryujinx.HLE.Logging;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue