Implement GetApplicationControlData

This commit is contained in:
Thog 2019-02-11 23:52:33 +01:00
parent 540c2cad91
commit 701203bedd
No known key found for this signature in database
GPG key ID: 0CD291558FAFDBC6
3 changed files with 211 additions and 7 deletions

View file

@ -102,6 +102,8 @@ namespace Ryujinx.HLE.HOS
public Horizon(Switch device)
{
ControlData = new Nacp();
Device = device;
State = new SystemStateMgr();

View file

@ -1,6 +1,9 @@
using Ryujinx.Common.Logging;
using LibHac;
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Ipc;
using System;
using System.Collections.Generic;
using System.Text;
namespace Ryujinx.HLE.HOS.Services.Ns
{
@ -10,8 +13,6 @@ namespace Ryujinx.HLE.HOS.Services.Ns
public override IReadOnlyDictionary<int, ServiceProcessRequest> Commands => _commands;
private bool _isInitialized;
public IApplicationManagerInterface()
{
_commands = new Dictionary<int, ServiceProcessRequest>
@ -20,12 +21,213 @@ namespace Ryujinx.HLE.HOS.Services.Ns
};
}
// TODO: implement this at some point
public long GetApplicationControlData(ServiceCtx context)
{
Logger.PrintStub(LogClass.ServiceNs, "Stubbed.");
long position = context.Request.ReceiveBuff[0].Position;
return 0xDEAD;
Nacp nacp = context.Device.System.ControlData;
for (int i = 0; i < 0x10; i++)
{
NacpDescription description = nacp.Descriptions[i];
byte[] titleData = new byte[0x200];
byte[] developerData = new byte[0x100];
if (description !=null && description.Title != null)
{
byte[] titleDescriptionData = Encoding.ASCII.GetBytes(description.Title);
Buffer.BlockCopy(titleDescriptionData, 0, titleData, 0, titleDescriptionData.Length);
}
if (description != null && description.Developer != null)
{
byte[] developerDescriptionData = Encoding.ASCII.GetBytes(description.Developer);
Buffer.BlockCopy(developerDescriptionData, 0, developerData, 0, developerDescriptionData.Length);
}
context.Memory.WriteBytes(position, titleData);
context.Memory.WriteBytes(position + 0x200, developerData);
position += i * 0x300;
}
byte[] isbn = new byte[0x25];
if (nacp.Isbn != null)
{
byte[] isbnData = Encoding.ASCII.GetBytes(nacp.Isbn);
Buffer.BlockCopy(isbnData, 0, isbn, 0, isbnData.Length);
}
context.Memory.WriteBytes(position, isbn);
position += isbn.Length;
context.Memory.WriteByte(position, nacp.StartupUserAccount);
context.Memory.WriteByte(position + 1, nacp.TouchScreenUsageMode);
context.Memory.WriteByte(position + 2, nacp.AocRegistrationType);
position += 3;
context.Memory.WriteInt32(position, nacp.AttributeFlag);
position += 4;
context.Memory.WriteUInt32(position, nacp.SupportedLanguageFlag);
position += 4;
context.Memory.WriteUInt32(position, nacp.ParentalControlFlag);
position += 4;
context.Memory.WriteByte(position, nacp.Screenshot);
context.Memory.WriteByte(position + 1, nacp.VideoCapture);
context.Memory.WriteByte(position + 2, nacp.DataLossConfirmation);
context.Memory.WriteByte(position + 3, nacp.PlayLogPolicy);
position += 4;
context.Memory.WriteUInt64(position, nacp.PresenceGroupId);
position += 8;
for (int i = 0; i < nacp.RatingAge.Length; i++)
{
context.Memory.WriteSByte(position, nacp.RatingAge[i]);
position++;
}
byte[] displayVersion = new byte[0x10];
if (nacp.DisplayVersion != null)
{
byte[] displayVersionData = Encoding.ASCII.GetBytes(nacp.DisplayVersion);
Buffer.BlockCopy(displayVersionData, 0, displayVersion, 0, displayVersionData.Length);
}
context.Memory.WriteBytes(position, displayVersion);
position += displayVersion.Length;
context.Memory.WriteUInt64(position, nacp.AddOnContentBaseId);
position += 8;
context.Memory.WriteUInt64(position, nacp.SaveDataOwnerId);
position += 8;
context.Memory.WriteInt64(position, nacp.UserAccountSaveDataSize);
position += 8;
context.Memory.WriteInt64(position, nacp.UserAccountSaveDataJournalSize);
position += 8;
context.Memory.WriteInt64(position, nacp.DeviceSaveDataSize);
position += 8;
context.Memory.WriteInt64(position, nacp.DeviceSaveDataJournalSize);
position += 8;
context.Memory.WriteInt64(position, nacp.BcatDeliveryCacheStorageSize);
position += 8;
byte[] applicationErrorCodeCategory = new byte[0x8];
if (nacp.ApplicationErrorCodeCategory != null)
{
byte[] applicationErrorCodeCategoryData = Encoding.ASCII.GetBytes(nacp.ApplicationErrorCodeCategory);
Buffer.BlockCopy(applicationErrorCodeCategoryData, 0, applicationErrorCodeCategoryData, 0, applicationErrorCodeCategoryData.Length);
}
context.Memory.WriteBytes(position, applicationErrorCodeCategory);
position += applicationErrorCodeCategory.Length;
for (int i = 0; i < nacp.LocalCommunicationId.Length; i++)
{
context.Memory.WriteUInt64(position, nacp.LocalCommunicationId[i]);
position += 8;
}
context.Memory.WriteByte(position, nacp.LogoType);
context.Memory.WriteByte(position + 1, nacp.LogoHandling);
context.Memory.WriteByte(position + 2, nacp.RuntimeAddOnContentInstall);
byte[] reserved000 = new byte[0x3];
context.Memory.WriteBytes(position + 3, reserved000);
position += 3;
position += reserved000.Length;
context.Memory.WriteByte(position, nacp.CrashReport);
context.Memory.WriteByte(position + 1, nacp.Hdcp);
context.Memory.WriteUInt64(position + 2, nacp.SeedForPseudoDeviceId);
position += 10;
byte[] bcatPassphrase = new byte[65];
if (nacp.BcatPassphrase != null)
{
byte[] bcatPassphraseData = Encoding.ASCII.GetBytes(nacp.BcatPassphrase);
Buffer.BlockCopy(bcatPassphraseData, 0, bcatPassphrase, 0, bcatPassphraseData.Length);
}
context.Memory.WriteBytes(position, bcatPassphrase);
position += bcatPassphrase.Length;
context.Memory.WriteByte(position, nacp.Reserved01);
position++;
byte[] reserved02 = new byte[0x6];
context.Memory.WriteBytes(position, reserved02);
position += reserved02.Length;
context.Memory.WriteInt64(position, nacp.UserAccountSaveDataSizeMax);
position += 8;
context.Memory.WriteInt64(position, nacp.UserAccountSaveDataJournalSizeMax);
position += 8;
context.Memory.WriteInt64(position, nacp.DeviceSaveDataSizeMax);
position += 8;
context.Memory.WriteInt64(position, nacp.DeviceSaveDataJournalSizeMax);
position += 8;
context.Memory.WriteInt64(position, nacp.TemporaryStorageSize);
position += 8;
context.Memory.WriteInt64(position, nacp.CacheStorageSize);
position += 8;
context.Memory.WriteInt64(position, nacp.CacheStorageJournalSize);
position += 8;
context.Memory.WriteInt64(position, nacp.CacheStorageDataAndJournalSizeMax);
position += 8;
context.Memory.WriteInt16(position, nacp.CacheStorageIndex);
position += 2;
byte[] reserved03 = new byte[0x6];
context.Memory.WriteBytes(position, reserved03);
position += reserved03.Length;
for (int i = 0; i < 16; i++)
{
ulong value = 0;
if (nacp.PlayLogQueryableApplicationId.Count > i)
{
value = nacp.PlayLogQueryableApplicationId[i];
}
context.Memory.WriteUInt64(position, value);
position += 8;
}
context.Memory.WriteByte(position, nacp.PlayLogQueryCapability);
position++;
context.Memory.WriteByte(position, nacp.RepairFlag);
position++;
context.Memory.WriteByte(position, nacp.ProgramIndex);
position++;
return 0;
}
}
}

View file

@ -22,7 +22,7 @@ namespace Ryujinx.HLE.HOS.Services.Pm
// GetApplicationPid() -> u64
public long GetApplicationPid(ServiceCtx context)
{
// FIXME: This is wrong but needed to make hbmenu works
// FIXME: This is wrong but needed to make hb loader works
// TODO: Change this when we will have a way to process via a PM like interface.
long pid = context.Process.Pid;