From 72157e03eb09d4fb5d6d004efc2d13d3194e8c90 Mon Sep 17 00:00:00 2001 From: Thomas Guillemard Date: Fri, 25 Jan 2019 02:51:28 +0100 Subject: [PATCH] Add support of PFS0 as ExeFS (#564) Also add .pfs0 support --- Ryujinx.HLE/HOS/Horizon.cs | 57 +++++++++++++++++++++++++++++++++++++- Ryujinx/Program.cs | 1 + 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/Ryujinx.HLE/HOS/Horizon.cs b/Ryujinx.HLE/HOS/Horizon.cs index 6b5f5723c5..840624bed7 100644 --- a/Ryujinx.HLE/HOS/Horizon.cs +++ b/Ryujinx.HLE/HOS/Horizon.cs @@ -394,7 +394,62 @@ namespace Ryujinx.HLE.HOS return; } - Logger.PrintError(LogClass.Loader, "Could not find an Application NCA in the provided NSP file"); + // This is not a normal NSP, it's actually a ExeFS as a NSP + Npdm metaData = null; + + PfsFileEntry npdmFile = nsp.Files.FirstOrDefault(x => x.Name.Equals("main.npdm")); + + if (npdmFile != null) + { + Logger.PrintInfo(LogClass.Loader, $"Loading main.npdm..."); + + metaData = new Npdm(nsp.OpenFile(npdmFile).AsStream()); + } + else + { + Logger.PrintWarning(LogClass.Loader, $"NPDM file not found, using default values!"); + + metaData = GetDefaultNpdm(); + } + + List staticObjects = new List(); + + void LoadNso(string searchPattern) + { + PfsFileEntry entry = nsp.Files.FirstOrDefault(x => x.Name.Equals(searchPattern)); + + if (entry != null) + { + Logger.PrintInfo(LogClass.Loader, $"Loading {entry.Name}..."); + + NxStaticObject staticObject = new NxStaticObject(nsp.OpenFile(entry).AsStream()); + + staticObjects.Add(staticObject); + } + } + + if (!metaData.Is64Bits) + { + throw new NotImplementedException("32-bit titles are unsupported!"); + } + + CurrentTitle = metaData.Aci0.TitleId.ToString("x16"); + + LoadNso("rtld"); + LoadNso("main"); + LoadNso("subsdk*"); + LoadNso("sdk"); + + ContentManager.LoadEntries(); + + if (staticObjects.Count == 0) + { + Logger.PrintError(LogClass.Loader, "Could not find an Application NCA in the provided NSP file"); + } + else + { + ProgramLoader.LoadStaticObjects(this, metaData, staticObjects.ToArray()); + } } public void LoadNca(Nca mainNca, Nca controlNca) diff --git a/Ryujinx/Program.cs b/Ryujinx/Program.cs index f1d0a2ff9d..4dce13c7f7 100644 --- a/Ryujinx/Program.cs +++ b/Ryujinx/Program.cs @@ -61,6 +61,7 @@ namespace Ryujinx device.LoadNca(args[0]); break; case ".nsp": + case ".pfs0": Console.WriteLine("Loading as NSP."); device.LoadNsp(args[0]); break;