Code style fixes and nits on the HLE project (#355)
* Some style fixes and nits on ITimeZoneService * Remove some unneeded usings * Remove the Ryujinx.HLE.OsHle.Handles namespace * Remove hbmenu automatic load on process exit * Rename Ns to Device, rename Os to System, rename SystemState to State * Move Exceptions and Utilities out of OsHle * Rename OsHle to HOS * Rename OsHle folder to HOS * IManagerDisplayService and ISystemDisplayService style fixes * BsdError shouldn't be public * Add a empty new line before using static * Remove unused file * Some style fixes on NPDM * Exit gracefully when the application is closed * Code style fixes on IGeneralService * Add 0x prefix on values printed as hex * Small improvements on finalization code * Move ProcessId and ThreadId out of AThreadState * Rename VFs to FileSystem * FsAccessHeader shouldn't be public. Also fix file names casing * More case changes on NPDM * Remove unused files * Move using to the correct place on NPDM * Use properties on KernelAccessControlMmio * Address PR feedback
This commit is contained in:
parent
182d716867
commit
521751795a
258 changed files with 1574 additions and 1546 deletions
227
Ryujinx.HLE/HOS/Horizon.cs
Normal file
227
Ryujinx.HLE/HOS/Horizon.cs
Normal file
|
@ -0,0 +1,227 @@
|
|||
using Ryujinx.HLE.HOS.Font;
|
||||
using Ryujinx.HLE.HOS.Kernel;
|
||||
using Ryujinx.HLE.HOS.SystemState;
|
||||
using Ryujinx.HLE.Loaders.Executables;
|
||||
using Ryujinx.HLE.Loaders.Npdm;
|
||||
using Ryujinx.HLE.Logging;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
|
||||
namespace Ryujinx.HLE.HOS
|
||||
{
|
||||
public class Horizon : IDisposable
|
||||
{
|
||||
internal const int HidSize = 0x40000;
|
||||
internal const int FontSize = 0x1100000;
|
||||
|
||||
private Switch Device;
|
||||
|
||||
private KProcessScheduler Scheduler;
|
||||
|
||||
private ConcurrentDictionary<int, Process> Processes;
|
||||
|
||||
public SystemStateMgr State { get; private set; }
|
||||
|
||||
internal KSharedMemory HidSharedMem { get; private set; }
|
||||
internal KSharedMemory FontSharedMem { get; private set; }
|
||||
|
||||
internal SharedFontManager Font { get; private set; }
|
||||
|
||||
internal KEvent VsyncEvent { get; private set; }
|
||||
|
||||
public Horizon(Switch Device)
|
||||
{
|
||||
this.Device = Device;
|
||||
|
||||
Scheduler = new KProcessScheduler(Device.Log);
|
||||
|
||||
Processes = new ConcurrentDictionary<int, Process>();
|
||||
|
||||
State = new SystemStateMgr();
|
||||
|
||||
if (!Device.Memory.Allocator.TryAllocate(HidSize, out long HidPA) ||
|
||||
!Device.Memory.Allocator.TryAllocate(FontSize, out long FontPA))
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
HidSharedMem = new KSharedMemory(HidPA, HidSize);
|
||||
FontSharedMem = new KSharedMemory(FontPA, FontSize);
|
||||
|
||||
Font = new SharedFontManager(Device, FontSharedMem.PA);
|
||||
|
||||
VsyncEvent = new KEvent();
|
||||
}
|
||||
|
||||
public void LoadCart(string ExeFsDir, string RomFsFile = null)
|
||||
{
|
||||
if (RomFsFile != null)
|
||||
{
|
||||
Device.FileSystem.LoadRomFs(RomFsFile);
|
||||
}
|
||||
|
||||
string NpdmFileName = Path.Combine(ExeFsDir, "main.npdm");
|
||||
|
||||
Npdm MetaData = null;
|
||||
|
||||
if (File.Exists(NpdmFileName))
|
||||
{
|
||||
Device.Log.PrintInfo(LogClass.Loader, $"Loading main.npdm...");
|
||||
|
||||
using (FileStream Input = new FileStream(NpdmFileName, FileMode.Open))
|
||||
{
|
||||
MetaData = new Npdm(Input);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Device.Log.PrintWarning(LogClass.Loader, $"NPDM file not found, using default values!");
|
||||
}
|
||||
|
||||
Process MainProcess = MakeProcess(MetaData);
|
||||
|
||||
void LoadNso(string FileName)
|
||||
{
|
||||
foreach (string File in Directory.GetFiles(ExeFsDir, FileName))
|
||||
{
|
||||
if (Path.GetExtension(File) != string.Empty)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Device.Log.PrintInfo(LogClass.Loader, $"Loading {Path.GetFileNameWithoutExtension(File)}...");
|
||||
|
||||
using (FileStream Input = new FileStream(File, FileMode.Open))
|
||||
{
|
||||
string Name = Path.GetFileNameWithoutExtension(File);
|
||||
|
||||
Nso Program = new Nso(Input, Name);
|
||||
|
||||
MainProcess.LoadProgram(Program);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!MainProcess.MetaData.Is64Bits)
|
||||
{
|
||||
throw new NotImplementedException("32-bit titles are unsupported!");
|
||||
}
|
||||
|
||||
LoadNso("rtld");
|
||||
|
||||
MainProcess.SetEmptyArgs();
|
||||
|
||||
LoadNso("main");
|
||||
LoadNso("subsdk*");
|
||||
LoadNso("sdk");
|
||||
|
||||
MainProcess.Run();
|
||||
}
|
||||
|
||||
public void LoadProgram(string FilePath)
|
||||
{
|
||||
bool IsNro = Path.GetExtension(FilePath).ToLower() == ".nro";
|
||||
|
||||
string Name = Path.GetFileNameWithoutExtension(FilePath);
|
||||
string SwitchFilePath = Device.FileSystem.SystemPathToSwitchPath(FilePath);
|
||||
|
||||
if (IsNro && (SwitchFilePath == null || !SwitchFilePath.StartsWith("sdmc:/")))
|
||||
{
|
||||
string SwitchPath = $"sdmc:/switch/{Name}{Homebrew.TemporaryNroSuffix}";
|
||||
string TempPath = Device.FileSystem.SwitchPathToSystemPath(SwitchPath);
|
||||
|
||||
string SwitchDir = Path.GetDirectoryName(TempPath);
|
||||
|
||||
if (!Directory.Exists(SwitchDir))
|
||||
{
|
||||
Directory.CreateDirectory(SwitchDir);
|
||||
}
|
||||
|
||||
File.Copy(FilePath, TempPath, true);
|
||||
|
||||
FilePath = TempPath;
|
||||
}
|
||||
|
||||
Process MainProcess = MakeProcess();
|
||||
|
||||
using (FileStream Input = new FileStream(FilePath, FileMode.Open))
|
||||
{
|
||||
MainProcess.LoadProgram(IsNro
|
||||
? (IExecutable)new Nro(Input, FilePath)
|
||||
: (IExecutable)new Nso(Input, FilePath));
|
||||
}
|
||||
|
||||
MainProcess.SetEmptyArgs();
|
||||
MainProcess.Run(IsNro);
|
||||
}
|
||||
|
||||
public void SignalVsync() => VsyncEvent.WaitEvent.Set();
|
||||
|
||||
private Process MakeProcess(Npdm MetaData = null)
|
||||
{
|
||||
Process Process;
|
||||
|
||||
lock (Processes)
|
||||
{
|
||||
int ProcessId = 0;
|
||||
|
||||
while (Processes.ContainsKey(ProcessId))
|
||||
{
|
||||
ProcessId++;
|
||||
}
|
||||
|
||||
Process = new Process(Device, Scheduler, ProcessId, MetaData);
|
||||
|
||||
Processes.TryAdd(ProcessId, Process);
|
||||
}
|
||||
|
||||
InitializeProcess(Process);
|
||||
|
||||
return Process;
|
||||
}
|
||||
|
||||
private void InitializeProcess(Process Process)
|
||||
{
|
||||
Process.AppletState.SetFocus(true);
|
||||
}
|
||||
|
||||
internal void ExitProcess(int ProcessId)
|
||||
{
|
||||
if (Processes.TryRemove(ProcessId, out Process Process))
|
||||
{
|
||||
Process.Dispose();
|
||||
|
||||
if (Processes.Count == 0)
|
||||
{
|
||||
Unload();
|
||||
|
||||
Device.Unload();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Unload()
|
||||
{
|
||||
VsyncEvent.Dispose();
|
||||
|
||||
Scheduler.Dispose();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool Disposing)
|
||||
{
|
||||
if (Disposing)
|
||||
{
|
||||
foreach (Process Process in Processes.Values)
|
||||
{
|
||||
Process.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue