/ src / Ryujinx.HLE / Loaders / Processes / ProcessResult.cs
ProcessResult.cs
 1  using LibHac.Common;
 2  using LibHac.Loader;
 3  using LibHac.Ns;
 4  using Ryujinx.Common.Logging;
 5  using Ryujinx.Cpu;
 6  using Ryujinx.HLE.HOS.SystemState;
 7  using Ryujinx.HLE.Loaders.Processes.Extensions;
 8  using Ryujinx.Horizon.Common;
 9  using System;
10  
11  namespace Ryujinx.HLE.Loaders.Processes
12  {
13      public class ProcessResult
14      {
15          public static ProcessResult Failed => new(null, new BlitStruct<ApplicationControlProperty>(1), false, false, null, 0, 0, 0, TitleLanguage.AmericanEnglish);
16  
17          private readonly byte _mainThreadPriority;
18          private readonly uint _mainThreadStackSize;
19  
20          public readonly IDiskCacheLoadState DiskCacheLoadState;
21  
22          public readonly MetaLoader MetaLoader;
23          public readonly ApplicationControlProperty ApplicationControlProperties;
24  
25          public readonly ulong ProcessId;
26          public readonly string Name;
27          public readonly string DisplayVersion;
28          public readonly ulong ProgramId;
29          public readonly string ProgramIdText;
30          public readonly bool Is64Bit;
31          public readonly bool DiskCacheEnabled;
32          public readonly bool AllowCodeMemoryForJit;
33  
34          public ProcessResult(
35              MetaLoader metaLoader,
36              BlitStruct<ApplicationControlProperty> applicationControlProperties,
37              bool diskCacheEnabled,
38              bool allowCodeMemoryForJit,
39              IDiskCacheLoadState diskCacheLoadState,
40              ulong pid,
41              byte mainThreadPriority,
42              uint mainThreadStackSize,
43              TitleLanguage titleLanguage)
44          {
45              _mainThreadPriority = mainThreadPriority;
46              _mainThreadStackSize = mainThreadStackSize;
47  
48              DiskCacheLoadState = diskCacheLoadState;
49              ProcessId = pid;
50  
51              MetaLoader = metaLoader;
52              ApplicationControlProperties = applicationControlProperties.Value;
53  
54              if (metaLoader is not null)
55              {
56                  ulong programId = metaLoader.GetProgramId();
57  
58                  Name = ApplicationControlProperties.Title[(int)titleLanguage].NameString.ToString();
59  
60                  if (string.IsNullOrWhiteSpace(Name))
61                  {
62                      Name = Array.Find(ApplicationControlProperties.Title.ItemsRo.ToArray(), x => x.Name[0] != 0).NameString.ToString();
63                  }
64  
65                  DisplayVersion = ApplicationControlProperties.DisplayVersionString.ToString();
66                  ProgramId = programId;
67                  ProgramIdText = $"{programId:x16}";
68                  Is64Bit = metaLoader.IsProgram64Bit();
69              }
70  
71              DiskCacheEnabled = diskCacheEnabled;
72              AllowCodeMemoryForJit = allowCodeMemoryForJit;
73          }
74  
75          public bool Start(Switch device)
76          {
77              device.Configuration.ContentManager.LoadEntries(device);
78  
79              Result result = device.System.KernelContext.Processes[ProcessId].Start(_mainThreadPriority, _mainThreadStackSize);
80              if (result != Result.Success)
81              {
82                  Logger.Error?.Print(LogClass.Loader, $"Process start returned error \"{result}\".");
83  
84                  return false;
85              }
86  
87              // TODO: LibHac npdm currently doesn't support version field.
88              string version = ProgramId > 0x0100000000007FFF ? DisplayVersion : device.System.ContentManager.GetCurrentFirmwareVersion()?.VersionString ?? "?";
89  
90              Logger.Info?.Print(LogClass.Loader, $"Application Loaded: {Name} v{version} [{ProgramIdText}] [{(Is64Bit ? "64-bit" : "32-bit")}]");
91  
92              return true;
93          }
94      }
95  }