2023-03-31 21:16:46 +02:00
|
|
|
|
using LibHac.Loader;
|
|
|
|
|
using LibHac.Ns;
|
|
|
|
|
using Ryujinx.Common.Logging;
|
|
|
|
|
using Ryujinx.Cpu;
|
2023-04-05 03:34:21 +02:00
|
|
|
|
using Ryujinx.HLE.HOS.SystemState;
|
2023-03-31 21:16:46 +02:00
|
|
|
|
using Ryujinx.HLE.Loaders.Processes.Extensions;
|
|
|
|
|
using Ryujinx.Horizon.Common;
|
|
|
|
|
|
|
|
|
|
namespace Ryujinx.HLE.Loaders.Processes
|
|
|
|
|
{
|
|
|
|
|
public struct ProcessResult
|
|
|
|
|
{
|
2023-04-05 03:34:21 +02:00
|
|
|
|
public static ProcessResult Failed => new(null, new ApplicationControlProperty(), false, false, null, 0, 0, 0, TitleLanguage.AmericanEnglish);
|
2023-03-31 21:16:46 +02:00
|
|
|
|
|
|
|
|
|
private readonly byte _mainThreadPriority;
|
|
|
|
|
private readonly uint _mainThreadStackSize;
|
|
|
|
|
|
|
|
|
|
public readonly IDiskCacheLoadState DiskCacheLoadState;
|
|
|
|
|
|
|
|
|
|
public readonly MetaLoader MetaLoader;
|
|
|
|
|
public readonly ApplicationControlProperty ApplicationControlProperties;
|
|
|
|
|
|
|
|
|
|
public readonly ulong ProcessId;
|
|
|
|
|
public string Name;
|
|
|
|
|
public ulong ProgramId;
|
|
|
|
|
public readonly string ProgramIdText;
|
|
|
|
|
public readonly bool Is64Bit;
|
|
|
|
|
public readonly bool DiskCacheEnabled;
|
|
|
|
|
public readonly bool AllowCodeMemoryForJit;
|
|
|
|
|
|
|
|
|
|
public ProcessResult(
|
|
|
|
|
MetaLoader metaLoader,
|
|
|
|
|
ApplicationControlProperty applicationControlProperties,
|
|
|
|
|
bool diskCacheEnabled,
|
|
|
|
|
bool allowCodeMemoryForJit,
|
|
|
|
|
IDiskCacheLoadState diskCacheLoadState,
|
|
|
|
|
ulong pid,
|
|
|
|
|
byte mainThreadPriority,
|
2023-04-05 03:34:21 +02:00
|
|
|
|
uint mainThreadStackSize,
|
|
|
|
|
TitleLanguage titleLanguage)
|
2023-03-31 21:16:46 +02:00
|
|
|
|
{
|
|
|
|
|
_mainThreadPriority = mainThreadPriority;
|
|
|
|
|
_mainThreadStackSize = mainThreadStackSize;
|
|
|
|
|
|
|
|
|
|
DiskCacheLoadState = diskCacheLoadState;
|
|
|
|
|
ProcessId = pid;
|
|
|
|
|
|
|
|
|
|
MetaLoader = metaLoader;
|
|
|
|
|
ApplicationControlProperties = applicationControlProperties;
|
|
|
|
|
|
|
|
|
|
if (metaLoader is not null)
|
|
|
|
|
{
|
|
|
|
|
ulong programId = metaLoader.GetProgramId();
|
|
|
|
|
|
2023-04-05 03:34:21 +02:00
|
|
|
|
if (ApplicationControlProperties.Title.ItemsRo.Length > 0)
|
|
|
|
|
{
|
|
|
|
|
var langIndex = ApplicationControlProperties.Title.ItemsRo.Length > (int)titleLanguage ? (int)titleLanguage : 0;
|
|
|
|
|
|
|
|
|
|
Name = ApplicationControlProperties.Title[langIndex].NameString.ToString();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Name = metaLoader.GetProgramName();
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-31 21:16:46 +02:00
|
|
|
|
ProgramId = programId;
|
|
|
|
|
ProgramIdText = $"{programId:x16}";
|
|
|
|
|
Is64Bit = metaLoader.IsProgram64Bit();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DiskCacheEnabled = diskCacheEnabled;
|
|
|
|
|
AllowCodeMemoryForJit = allowCodeMemoryForJit;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool Start(Switch device)
|
|
|
|
|
{
|
|
|
|
|
device.Configuration.ContentManager.LoadEntries(device);
|
|
|
|
|
|
|
|
|
|
Result result = device.System.KernelContext.Processes[ProcessId].Start(_mainThreadPriority, _mainThreadStackSize);
|
|
|
|
|
if (result != Result.Success)
|
|
|
|
|
{
|
|
|
|
|
Logger.Error?.Print(LogClass.Loader, $"Process start returned error \"{result}\".");
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO: LibHac npdm currently doesn't support version field.
|
|
|
|
|
string version;
|
|
|
|
|
|
|
|
|
|
if (ProgramId > 0x0100000000007FFF)
|
|
|
|
|
{
|
|
|
|
|
version = ApplicationControlProperties.DisplayVersionString.ToString();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
version = device.System.ContentManager.GetCurrentFirmwareVersion().VersionString;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Logger.Info?.Print(LogClass.Loader, $"Application Loaded: {Name} v{version} [{ProgramIdText}] [{(Is64Bit ? "64-bit" : "32-bit")}]");
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|