bcat:u: Implement EnumerateDeliveryCacheDirectory

Basic implementation `EnumerateDeliveryCacheDirectory` call to `IDeliveryCacheStorageService` according to RE.  (close #622)
I've added some comments in the whole service for when we'll implement a real bcat implementation.
For now, all games who use it isn't playable because of GPU.
This commit is contained in:
Ac_K 2019-09-09 00:25:29 +02:00
parent 1ff89d6482
commit 3f483d53d4
4 changed files with 98 additions and 6 deletions

View file

@ -1,7 +1,9 @@
using Ryujinx.HLE.HOS.Services.Arp;
namespace Ryujinx.HLE.HOS.Services.Bcat
{
class IBcatService : IpcService
{
public IBcatService() { }
public IBcatService(ApplicationLaunchProperty applicationLaunchProperty) { }
}
}

View file

@ -1,7 +1,48 @@
using Ryujinx.HLE.HOS.Services.Arp;
using System;
using System.Collections.Generic;
using System.Text;
namespace Ryujinx.HLE.HOS.Services.Bcat
{
class IDeliveryCacheStorageService : IpcService
{
public IDeliveryCacheStorageService() { }
private const int DeliveryCacheDirectoriesLimit = 100;
private const int DeliveryCacheDirectoryNameLength = 32;
private List<string> _deliveryCacheDirectories = new List<string>();
public IDeliveryCacheStorageService(ServiceCtx context, ApplicationLaunchProperty applicationLaunchProperty)
{
// TODO: Read directories.meta file from the save data (loaded in IServiceCreator) in _deliveryCacheDirectories.
}
[Command(10)]
// EnumerateDeliveryCacheDirectory() -> (u32, buffer<nn::bcat::DirectoryName, 6>)
public ResultCode EnumerateDeliveryCacheDirectory(ServiceCtx context)
{
long outputPosition = context.Request.ReceiveBuff[0].Position;
long outputSize = context.Request.ReceiveBuff[0].Size;
for (int index = 0; index < _deliveryCacheDirectories.Count; index++)
{
if (index == DeliveryCacheDirectoriesLimit - 1)
{
break;
}
byte[] directoryNameBuffer = Encoding.ASCII.GetBytes(_deliveryCacheDirectories[index]);
Array.Resize(ref directoryNameBuffer, DeliveryCacheDirectoryNameLength);
directoryNameBuffer[DeliveryCacheDirectoryNameLength - 1] = 0x00;
context.Memory.WriteBytes(outputPosition + index * DeliveryCacheDirectoryNameLength, directoryNameBuffer);
}
context.ResponseData.Write(_deliveryCacheDirectories.Count);
return ResultCode.Success;
}
}
}

View file

@ -1,3 +1,8 @@
using Ryujinx.HLE.FileSystem;
using Ryujinx.HLE.HOS.Services.Arp;
using Ryujinx.HLE.Utilities;
using System;
namespace Ryujinx.HLE.HOS.Services.Bcat
{
[Service("bcat:a")]
@ -12,9 +17,24 @@ namespace Ryujinx.HLE.HOS.Services.Bcat
// CreateBcatService(u64, pid) -> object<nn::bcat::detail::ipc::IBcatService>
public ResultCode CreateBcatService(ServiceCtx context)
{
long id = context.RequestData.ReadInt64();
// TODO: Call arp:r GetApplicationLaunchProperty with the pid to get the TitleId.
// Add an instance of nn::bcat::detail::service::core::PassphraseManager.
// Add an instance of nn::bcat::detail::service::ServiceMemoryManager.
// Add an instance of nn::bcat::detail::service::core::TaskManager who load "bcat-sys:/" system save data and open "dc/task.bin".
// If the file don't exist, create a new one (size of 0x800) and write 2 empty struct with a size of 0x400.
MakeObject(context, new IBcatService());
ApplicationLaunchProperty applicationLaunchProperty = new ApplicationLaunchProperty
{
TitleId = BitConverter.ToInt64(StringUtils.HexToBytes(context.Device.System.TitleID), 0),
Version = 0x00,
BaseGameStorageId = (byte)StorageId.NandSystem,
UpdateGameStorageId = (byte)StorageId.None
};
MakeObject(context, new IBcatService(applicationLaunchProperty));
// NOTE: If the IBcatService is null this error is returned, Doesn't occur in our case.
// return ResultCode.NullObject;
return ResultCode.Success;
}
@ -23,9 +43,24 @@ namespace Ryujinx.HLE.HOS.Services.Bcat
// CreateDeliveryCacheStorageService(u64, pid) -> object<nn::bcat::detail::ipc::IDeliveryCacheStorageService>
public ResultCode CreateDeliveryCacheStorageService(ServiceCtx context)
{
long id = context.RequestData.ReadInt64();
// TODO: Call arp:r GetApplicationLaunchProperty with the pid to get the TitleId.
// Add an instance of nn::bcat::detail::service::core::ApplicationStorageManager who load "bcat-dc-X:/" system save data,
// return ResultCode.NullSaveData if failed.
// Where X depend of the ApplicationLaunchProperty stored in an array (range 0-3).
// Add an instance of nn::bcat::detail::service::ServiceMemoryManager.
MakeObject(context, new IDeliveryCacheStorageService());
ApplicationLaunchProperty applicationLaunchProperty = new ApplicationLaunchProperty
{
TitleId = BitConverter.ToInt64(StringUtils.HexToBytes(context.Device.System.TitleID), 0),
Version = 0x00,
BaseGameStorageId = (byte)StorageId.NandSystem,
UpdateGameStorageId = (byte)StorageId.None
};
MakeObject(context, new IDeliveryCacheStorageService(context, applicationLaunchProperty));
// NOTE: If the IDeliveryCacheStorageService is null this error is returned, Doesn't occur in our case.
// return ResultCode.NullObject;
return ResultCode.Success;
}

View file

@ -0,0 +1,14 @@
namespace Ryujinx.HLE.HOS.Services.Bcat
{
enum ResultCode
{
ModuleId = 122,
ErrorCodeShift = 9,
Success = 0,
NullArgument = (2 << ErrorCodeShift) | ModuleId,
NullSaveData = (31 << ErrorCodeShift) | ModuleId,
NullObject = (91 << ErrorCodeShift) | ModuleId
}
}