Horizon.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. using Ryujinx.Core.Loaders.Executables;
  2. using Ryujinx.Core.OsHle.Handles;
  3. using Ryujinx.Core.OsHle.Utilities;
  4. using System;
  5. using System.Collections.Concurrent;
  6. using System.IO;
  7. namespace Ryujinx.Core.OsHle
  8. {
  9. public class Horizon
  10. {
  11. internal const int HidSize = 0x40000;
  12. internal const int FontSize = 0x50;
  13. internal int HidHandle { get; private set; }
  14. internal int FontHandle { get; private set; }
  15. internal IdPool IdGen { get; private set; }
  16. internal IdPool NvMapIds { get; private set; }
  17. internal IdPoolWithObj Handles { get; private set; }
  18. internal IdPoolWithObj Fds { get; private set; }
  19. internal IdPoolWithObj Displays { get; private set; }
  20. public ConcurrentDictionary<long, Mutex> Mutexes { get; private set; }
  21. public ConcurrentDictionary<long, CondVar> CondVars { get; private set; }
  22. private ConcurrentDictionary<int, Process> Processes;
  23. internal HSharedMem HidSharedMem;
  24. private Switch Ns;
  25. public Horizon(Switch Ns)
  26. {
  27. this.Ns = Ns;
  28. IdGen = new IdPool();
  29. NvMapIds = new IdPool();
  30. Handles = new IdPoolWithObj();
  31. Fds = new IdPoolWithObj();
  32. Displays = new IdPoolWithObj();
  33. Mutexes = new ConcurrentDictionary<long, Mutex>();
  34. CondVars = new ConcurrentDictionary<long, CondVar>();
  35. Processes = new ConcurrentDictionary<int, Process>();
  36. HidSharedMem = new HSharedMem();
  37. HidHandle = Handles.GenerateId(HidSharedMem);
  38. FontHandle = Handles.GenerateId(new HSharedMem());
  39. }
  40. public void LoadCart(string ExeFsDir, string RomFsFile = null)
  41. {
  42. if (RomFsFile != null)
  43. {
  44. Ns.VFs.LoadRomFs(RomFsFile);
  45. }
  46. int ProcessId = IdGen.GenerateId();
  47. Process MainProcess = new Process(Ns, ProcessId);
  48. void LoadNso(string FileName)
  49. {
  50. foreach (string File in Directory.GetFiles(ExeFsDir, FileName))
  51. {
  52. if (Path.GetExtension(File) != string.Empty)
  53. {
  54. continue;
  55. }
  56. Logging.Info($"Loading {Path.GetFileNameWithoutExtension(File)}...");
  57. using (FileStream Input = new FileStream(File, FileMode.Open))
  58. {
  59. Nso Program = new Nso(Input);
  60. MainProcess.LoadProgram(Program);
  61. }
  62. }
  63. }
  64. LoadNso("rtld");
  65. MainProcess.SetEmptyArgs();
  66. LoadNso("main");
  67. LoadNso("subsdk*");
  68. LoadNso("sdk");
  69. MainProcess.Run();
  70. Processes.TryAdd(ProcessId, MainProcess);
  71. }
  72. public void LoadProgram(string FileName)
  73. {
  74. bool IsNro = Path.GetExtension(FileName).ToLower() == ".nro";
  75. int ProcessId = IdGen.GenerateId();
  76. Process MainProcess = new Process(Ns, ProcessId);
  77. using (FileStream Input = new FileStream(FileName, FileMode.Open))
  78. {
  79. MainProcess.LoadProgram(IsNro
  80. ? (IExecutable)new Nro(Input)
  81. : (IExecutable)new Nso(Input));
  82. }
  83. MainProcess.SetEmptyArgs();
  84. MainProcess.Run(IsNro);
  85. Processes.TryAdd(ProcessId, MainProcess);
  86. }
  87. public void FinalizeAllProcesses()
  88. {
  89. foreach (Process Process in Processes.Values)
  90. {
  91. Process.StopAllThreads();
  92. Process.Dispose();
  93. }
  94. }
  95. internal bool ExitProcess(int ProcessId)
  96. {
  97. bool Success = Processes.TryRemove(ProcessId, out Process Process);
  98. if (Success)
  99. {
  100. Process.StopAllThreads();
  101. }
  102. if (Processes.Count == 0)
  103. {
  104. Ns.OnFinish(EventArgs.Empty);
  105. }
  106. return Success;
  107. }
  108. internal bool TryGetProcess(int ProcessId, out Process Process)
  109. {
  110. return Processes.TryGetValue(ProcessId, out Process);
  111. }
  112. internal void CloseHandle(int Handle)
  113. {
  114. object HndData = Handles.GetData<object>(Handle);
  115. if (HndData is HTransferMem TransferMem)
  116. {
  117. TransferMem.Memory.Manager.Reprotect(
  118. TransferMem.Position,
  119. TransferMem.Size,
  120. TransferMem.Perm);
  121. }
  122. Handles.Delete(Handle);
  123. }
  124. }
  125. }