diff options
| author | emmauss <emmausssss@gmail.com> | 2018-09-19 15:09:49 +0300 |
|---|---|---|
| committer | Thomas Guillemard <thog@protonmail.com> | 2018-09-19 14:09:49 +0200 |
| commit | fae097408e5ef28848e97022766017e540b0da37 (patch) | |
| tree | e97dc440eead87671cd92cd95e07dcfd33ff3cbb /Ryujinx.HLE/HOS/Horizon.cs | |
| parent | b8133c19971c7a2026af803003fafedbdb70488e (diff) | |
Show Game Title on Titlebar (#408)
* support reading control data
* show game info on titlebar
* use first language is default is not available
* use seperate language enums for titles
* fix hex display
Diffstat (limited to 'Ryujinx.HLE/HOS/Horizon.cs')
| -rw-r--r-- | Ryujinx.HLE/HOS/Horizon.cs | 102 |
1 files changed, 86 insertions, 16 deletions
diff --git a/Ryujinx.HLE/HOS/Horizon.cs b/Ryujinx.HLE/HOS/Horizon.cs index c7a824c0..f8ec8914 100644 --- a/Ryujinx.HLE/HOS/Horizon.cs +++ b/Ryujinx.HLE/HOS/Horizon.cs @@ -47,6 +47,10 @@ namespace Ryujinx.HLE.HOS private bool HasStarted; + public Nacp ControlData { get; set; } + + public string CurrentTitle { get; private set; } + public Horizon(Switch Device) { this.Device = Device; @@ -137,6 +141,8 @@ namespace Ryujinx.HLE.HOS throw new NotImplementedException("32-bit titles are unsupported!"); } + CurrentTitle = MainProcess.MetaData.ACI0.TitleId.ToString("x16"); + LoadNso("rtld"); MainProcess.SetEmptyArgs(); @@ -154,27 +160,28 @@ namespace Ryujinx.HLE.HOS Xci Xci = new Xci(KeySet, File); - Nca Nca = GetXciMainNca(Xci); + (Nca MainNca, Nca ControlNca) = GetXciGameData(Xci); - if (Nca == null) + if (MainNca == null) { Device.Log.PrintError(LogClass.Loader, "Unable to load XCI"); return; } - LoadNca(Nca); + LoadNca(MainNca, ControlNca); } - private Nca GetXciMainNca(Xci Xci) + private (Nca Main, Nca Control) GetXciGameData(Xci Xci) { if (Xci.SecurePartition == null) { throw new InvalidDataException("Could not find XCI secure partition"); } - Nca MainNca = null; - Nca PatchNca = null; + Nca MainNca = null; + Nca PatchNca = null; + Nca ControlNca = null; foreach (PfsFileEntry FileEntry in Xci.SecurePartition.Files.Where(x => x.Name.EndsWith(".nca"))) { @@ -193,6 +200,10 @@ namespace Ryujinx.HLE.HOS PatchNca = Nca; } } + else if (Nca.Header.ContentType == ContentType.Control) + { + ControlNca = Nca; + } } if (MainNca == null) @@ -201,8 +212,24 @@ namespace Ryujinx.HLE.HOS } MainNca.SetBaseNca(PatchNca); + + if (ControlNca != null) + { + ReadControlData(ControlNca); + } - return MainNca; + return (MainNca, ControlNca); + } + + public void ReadControlData(Nca ControlNca) + { + Romfs ControlRomfs = new Romfs(ControlNca.OpenSection(0, false)); + + byte[] ControlFile = ControlRomfs.GetFile("/control.nacp"); + + BinaryReader Reader = new BinaryReader(new MemoryStream(ControlFile)); + + ControlData = new Nacp(Reader); } public void LoadNca(string NcaFile) @@ -211,7 +238,7 @@ namespace Ryujinx.HLE.HOS Nca Nca = new Nca(KeySet, File, true); - LoadNca(Nca); + LoadNca(Nca, null); } public void LoadNsp(string NspFile) @@ -231,25 +258,37 @@ namespace Ryujinx.HLE.HOS KeySet.TitleKeys[Ticket.RightsId] = Ticket.GetTitleKey(KeySet); } + Nca MainNca = null; + Nca ControlNca = null; + foreach (PfsFileEntry NcaFile in Nsp.Files.Where(x => x.Name.EndsWith(".nca"))) { Nca Nca = new Nca(KeySet, Nsp.OpenFile(NcaFile), true); if (Nca.Header.ContentType == ContentType.Program) { - LoadNca(Nca); - - return; + MainNca = Nca; } + else if (Nca.Header.ContentType == ContentType.Control) + { + ControlNca = Nca; + } + } + + if (MainNca != null) + { + LoadNca(MainNca, ControlNca); + + return; } Device.Log.PrintError(LogClass.Loader, "Could not find an Application NCA in the provided NSP file"); } - public void LoadNca(Nca Nca) + public void LoadNca(Nca MainNca, Nca ControlNca) { - NcaSection RomfsSection = Nca.Sections.FirstOrDefault(x => x?.Type == SectionType.Romfs); - NcaSection ExefsSection = Nca.Sections.FirstOrDefault(x => x?.IsExefs == true); + NcaSection RomfsSection = MainNca.Sections.FirstOrDefault(x => x?.Type == SectionType.Romfs); + NcaSection ExefsSection = MainNca.Sections.FirstOrDefault(x => x?.IsExefs == true); if (ExefsSection == null) { @@ -265,10 +304,12 @@ namespace Ryujinx.HLE.HOS return; } - Stream RomfsStream = Nca.OpenSection(RomfsSection.SectionNum, false); + Stream RomfsStream = MainNca.OpenSection(RomfsSection.SectionNum, false); + Device.FileSystem.SetRomFs(RomfsStream); - Stream ExefsStream = Nca.OpenSection(ExefsSection.SectionNum, false); + Stream ExefsStream = MainNca.OpenSection(ExefsSection.SectionNum, false); + Pfs Exefs = new Pfs(ExefsStream); Npdm MetaData = null; @@ -305,6 +346,35 @@ namespace Ryujinx.HLE.HOS } } + Nacp ReadControlData() + { + Romfs ControlRomfs = new Romfs(ControlNca.OpenSection(0, false)); + + byte[] ControlFile = ControlRomfs.GetFile("/control.nacp"); + + BinaryReader Reader = new BinaryReader(new MemoryStream(ControlFile)); + + Nacp ControlData = new Nacp(Reader); + + CurrentTitle = ControlData.Languages[(int)State.DesiredTitleLanguage].Title; + + if (string.IsNullOrWhiteSpace(CurrentTitle)) + { + CurrentTitle = ControlData.Languages.ToList().Find(x => !string.IsNullOrWhiteSpace(x.Title)).Title; + } + + return ControlData; + } + + if (ControlNca != null) + { + MainProcess.ControlData = ReadControlData(); + } + else + { + CurrentTitle = MainProcess.MetaData.ACI0.TitleId.ToString("x16"); + } + if (!MainProcess.MetaData.Is64Bits) { throw new NotImplementedException("32-bit titles are unsupported!"); |
