From 9435231878e697f50c903226d7b9d8bf8f8be793 Mon Sep 17 00:00:00 2001 From: Xpl0itR Date: Fri, 21 Jun 2019 18:21:15 +0100 Subject: [PATCH] Game icons and names are now shown in the games list --- Ryujinx.HLE/HOS/Horizon.cs | 4 +- Ryujinx/ApplicationLibrary.cs | 172 ++++++++++++++++++-------- Ryujinx/Config.json | 2 +- Ryujinx/GUI/MainMenu.cs | 34 +++-- Ryujinx/GUI/SwitchSettings.cs | 4 +- Ryujinx/GUI/assets/ryujinxROMIcon.png | Bin 20327 -> 0 bytes Ryujinx/Program.cs | 14 +-- Ryujinx/RPsupported.dat | 3 +- Ryujinx/Ryujinx.csproj | 8 -- 9 files changed, 149 insertions(+), 92 deletions(-) delete mode 100644 Ryujinx/GUI/assets/ryujinxROMIcon.png diff --git a/Ryujinx.HLE/HOS/Horizon.cs b/Ryujinx.HLE/HOS/Horizon.cs index 5873223ef6..d6922ceb51 100644 --- a/Ryujinx.HLE/HOS/Horizon.cs +++ b/Ryujinx.HLE/HOS/Horizon.cs @@ -94,7 +94,7 @@ namespace Ryujinx.HLE.HOS internal KEvent VsyncEvent { get; private set; } - internal Keyset KeySet { get; private set; } + public Keyset KeySet { get; private set; } private bool _hasStarted; @@ -455,8 +455,6 @@ namespace Ryujinx.HLE.HOS TitleName = CurrentTitle = controlData.Descriptions[(int)State.DesiredTitleLanguage].Title; TitleID = metaData.Aci0.TitleId.ToString("x16"); - CurrentTitle = controlData.Descriptions[(int)State.DesiredTitleLanguage].Title; - if (string.IsNullOrWhiteSpace(CurrentTitle)) { TitleName = CurrentTitle = controlData.Descriptions.ToList().Find(x => !string.IsNullOrWhiteSpace(x.Title)).Title; diff --git a/Ryujinx/ApplicationLibrary.cs b/Ryujinx/ApplicationLibrary.cs index 7e494c1e23..b2da9fb16e 100644 --- a/Ryujinx/ApplicationLibrary.cs +++ b/Ryujinx/ApplicationLibrary.cs @@ -1,7 +1,11 @@ -using Ryujinx.Common.Logging; +using LibHac; +using LibHac.Fs; +using LibHac.Fs.NcaUtils; +using Ryujinx.Common.Logging; using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Reflection; using System.Text; @@ -22,8 +26,6 @@ namespace Ryujinx { public Gdk.Pixbuf Icon; public string Game; - public string Version; - public string DLC; public string TP; public string LP; public string FileSize; @@ -37,7 +39,6 @@ namespace Ryujinx RyujinxNCAIcon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.GUI.assets.ryujinxNCAIcon.png", 75, 75); RyujinxNROIcon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.GUI.assets.ryujinxNROIcon.png", 75, 75); RyujinxNSOIcon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.GUI.assets.ryujinxNSOIcon.png", 75, 75); - RyujinxROMIcon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.GUI.assets.ryujinxROMIcon.png", 75, 75); List Games = new List(); @@ -58,62 +59,129 @@ namespace Ryujinx ApplicationLibraryData = new List(); foreach (string GamePath in Games) { - double filesize = new FileInfo(GamePath).Length * 0.000000000931; - ApplicationData data = new ApplicationData() + double filesize = new FileInfo(GamePath).Length * 0.000000000931; + + using (FileStream file = new FileStream(GamePath, FileMode.Open, FileAccess.Read)) { - Icon = GetGameIcon(GamePath), - Game = (Path.GetExtension(GamePath) == ".nro") ? "Application" : "", - Version = "", - DLC = (Path.GetExtension(GamePath) == ".nro") ? "N/A" : "", - TP = "", - LP = "", - FileSize = (filesize < 1) ? (filesize * 1024).ToString("0.##") + "MB" : filesize.ToString("0.##") + "GB", - Path = GamePath, - }; - ApplicationLibraryData.Add(data); - } - } + Nca controlNca = null; + PartitionFileSystem PFS = null; + IFileSystem ControlFs = null; + string TitleName = null; + Gdk.Pixbuf GameIcon = null; - internal static Gdk.Pixbuf GetGameIcon(string filePath) - { - using (FileStream Input = File.Open(filePath, FileMode.Open, FileAccess.Read)) - { - BinaryReader Reader = new BinaryReader(Input); - - if ((Path.GetExtension(filePath) == ".nsp") || (Path.GetExtension(filePath) == ".pfs0")) { return RyujinxNSPIcon; } - - else if (Path.GetExtension(filePath) == ".xci") { return RyujinxXCIIcon; } - - else if (Path.GetExtension(filePath) == ".nca") { return RyujinxNCAIcon; } - - else if (Path.GetExtension(filePath) == ".nso") { return RyujinxNSOIcon; } - - else if (Path.GetExtension(filePath) == ".nro") - { - Input.Seek(24, SeekOrigin.Begin); - int AssetOffset = Reader.ReadInt32(); - - byte[] Read(long Position, int Size) + if ((Path.GetExtension(GamePath) == ".nsp") || (Path.GetExtension(GamePath) == ".pfs0")) { - Input.Seek(Position, SeekOrigin.Begin); - return Reader.ReadBytes(Size); + PFS = new PartitionFileSystem(file.AsStorage()); } - if (Encoding.ASCII.GetString(Read(AssetOffset, 4)) == "ASET") + else if (Path.GetExtension(GamePath) == ".xci") { - byte[] IconSectionInfo = Read(AssetOffset + 8, 0x10); - - long IconOffset = BitConverter.ToInt64(IconSectionInfo, 0); - long IconSize = BitConverter.ToInt64(IconSectionInfo, 8); - - byte[] IconData = Read(AssetOffset + IconOffset, (int)IconSize); - - return new Gdk.Pixbuf(IconData, 75, 75); + Xci xci = new Xci(MainMenu.device.System.KeySet, file.AsStorage()); + PFS = xci.OpenPartition(XciPartitionType.Secure); } - else { return RyujinxNROIcon; } + + if (PFS != null) + { + foreach (DirectoryEntry ticketEntry in PFS.EnumerateEntries("*.tik")) + { + Ticket ticket = new Ticket(PFS.OpenFile(ticketEntry.FullPath, OpenMode.Read).AsStream()); + + if (!MainMenu.device.System.KeySet.TitleKeys.ContainsKey(ticket.RightsId)) + { + MainMenu.device.System.KeySet.TitleKeys.Add(ticket.RightsId, ticket.GetTitleKey(MainMenu.device.System.KeySet)); + } + } + + foreach (DirectoryEntry fileEntry in PFS.EnumerateEntries("*.nca")) + { + Nca nca = new Nca(MainMenu.device.System.KeySet, PFS.OpenFile(fileEntry.FullPath, OpenMode.Read).AsStorage()); + if (nca.Header.ContentType == ContentType.Control) + { + controlNca = nca; + } + } + + ControlFs = controlNca.OpenFileSystem(NcaSectionType.Data, MainMenu.device.System.FsIntegrityCheckLevel); + } + + if ((Path.GetExtension(GamePath) == ".nca") || (Path.GetExtension(GamePath) == ".nro") || (Path.GetExtension(GamePath) == ".nso")) { TitleName = Path.GetFileName(GamePath); } + else + { + IFile controlFile = ControlFs.OpenFile("/control.nacp", OpenMode.Read); + Nacp ControlData = new Nacp(controlFile.AsStream()); + + TitleName = ControlData.Descriptions[(int)MainMenu.device.System.State.DesiredTitleLanguage].Title; + if (string.IsNullOrWhiteSpace(TitleName)) + { + TitleName = ControlData.Descriptions.ToList().Find(x => !string.IsNullOrWhiteSpace(x.Title)).Title; + } + } + + if (Path.GetExtension(GamePath) == ".nca") { GameIcon = RyujinxNCAIcon; } + + else if ((Path.GetExtension(GamePath) == ".xci") || (Path.GetExtension(GamePath) == ".nsp") || (Path.GetExtension(GamePath) == ".pfs0")) + { + try + { + IFile logo = ControlFs.OpenFile($"/icon_{MainMenu.device.System.State.DesiredTitleLanguage}.dat", OpenMode.Read); + GameIcon = new Gdk.Pixbuf(logo.AsStream(), 75, 75); + } + catch(FileNotFoundException) + { + try + { + IFile logo = ControlFs.OpenFile($"/icon_AmericanEnglish.dat", OpenMode.Read); + GameIcon = new Gdk.Pixbuf(logo.AsStream(), 75, 75); + } + catch (FileNotFoundException) + { + if (Path.GetExtension(GamePath) == ".xci") { GameIcon = RyujinxXCIIcon; } + else { GameIcon = RyujinxNSPIcon; } + } + } + } + + else if (Path.GetExtension(GamePath) == ".nso") { GameIcon = RyujinxNSOIcon; } + + else if (Path.GetExtension(GamePath) == ".nro") + { + BinaryReader Reader = new BinaryReader(file); + + file.Seek(24, SeekOrigin.Begin); + int AssetOffset = Reader.ReadInt32(); + + byte[] Read(long Position, int Size) + { + file.Seek(Position, SeekOrigin.Begin); + return Reader.ReadBytes(Size); + } + + if (Encoding.ASCII.GetString(Read(AssetOffset, 4)) == "ASET") + { + byte[] IconSectionInfo = Read(AssetOffset + 8, 0x10); + + long IconOffset = BitConverter.ToInt64(IconSectionInfo, 0); + long IconSize = BitConverter.ToInt64(IconSectionInfo, 8); + + byte[] IconData = Read(AssetOffset + IconOffset, (int)IconSize); + + GameIcon = new Gdk.Pixbuf(IconData, 75, 75); + } + else { GameIcon = RyujinxNROIcon; } + } + + ApplicationData data = new ApplicationData() + { + Icon = GameIcon, + Game = TitleName, + TP = "", + LP = "", + FileSize = (filesize < 1) ? (filesize * 1024).ToString("0.##") + "MB" : filesize.ToString("0.##") + "GB", + Path = GamePath, + }; + + ApplicationLibraryData.Add(data); } - - else { return RyujinxROMIcon; } } } } diff --git a/Ryujinx/Config.json b/Ryujinx/Config.json index be81c3db45..f7ce6039c3 100644 --- a/Ryujinx/Config.json +++ b/Ryujinx/Config.json @@ -9,7 +9,7 @@ "logging_enable_fs_access_log": false, "logging_filtered_classes": [ ], "enable_file_log": true, - "system_language": "BritishEnglish", + "system_language": "AmericanEnglish", "docked_mode": false, "enable_discord_integration": true, "enable_vsync": true, diff --git a/Ryujinx/GUI/MainMenu.cs b/Ryujinx/GUI/MainMenu.cs index 420a36397f..01290ec766 100644 --- a/Ryujinx/GUI/MainMenu.cs +++ b/Ryujinx/GUI/MainMenu.cs @@ -25,7 +25,7 @@ namespace Ryujinx private static IAalOutput audioOut; - private static HLE.Switch device { get; set; } + internal static HLE.Switch device { get; set; } private static Application gtkapp { get; set; } @@ -61,16 +61,16 @@ namespace Ryujinx if (DiscordIntegrationEnabled) { - DiscordClient = new DiscordRpcClient("568815339807309834"); + DiscordClient = new DiscordRpcClient("568815339807309834"); DiscordPresence = new RichPresence { Assets = new Assets { - LargeImageKey = "ryujinx", + LargeImageKey = "ryujinx", LargeImageText = "Ryujinx is an emulator for the Nintendo Switch" }, - Details = "Main Menu", - State = "Idling", + Details = "Main Menu", + State = "Idling", Timestamps = new Timestamps(DateTime.UtcNow) }; @@ -105,15 +105,13 @@ namespace Ryujinx NFC.Sensitive = false; GameTable.AppendColumn("Icon", new CellRendererPixbuf(), "pixbuf", 0); - //GameTable.AppendColumn("Game", new CellRendererText(), "text", 1); - //GameTable.AppendColumn("Version", new CellRendererText(), "text", 2); - //GameTable.AppendColumn("DLC", new CellRendererText(), "text", 3); - //GameTable.AppendColumn("Time Played", new CellRendererText(), "text", 4); - //GameTable.AppendColumn("Last Played", new CellRendererText(), "text", 5); - GameTable.AppendColumn("File Size", new CellRendererText(), "text", 6); - GameTable.AppendColumn("Path", new CellRendererText(), "text", 7); + GameTable.AppendColumn("Game", new CellRendererText(), "text", 1); + //GameTable.AppendColumn("Time Played", new CellRendererText(), "text", 2); + //GameTable.AppendColumn("Last Played", new CellRendererText(), "text", 3); + GameTable.AppendColumn("File Size", new CellRendererText(), "text", 4); + GameTable.AppendColumn("Path", new CellRendererText(), "text", 5); - TableStore = new ListStore(typeof(Gdk.Pixbuf), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string)); + TableStore = new ListStore(typeof(Gdk.Pixbuf), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string)); GameTable.Model = TableStore; UpdateGameTable(); @@ -127,13 +125,13 @@ namespace Ryujinx foreach (ApplicationLibrary.ApplicationData AppData in ApplicationLibrary.ApplicationLibraryData) { - TableStore.AppendValues(AppData.Icon, AppData.Game, AppData.Version, AppData.DLC, AppData.TP, AppData.LP, AppData.FileSize, AppData.Path); + TableStore.AppendValues(AppData.Icon, AppData.Game, AppData.TP, AppData.LP, AppData.FileSize, AppData.Path); } } public static void ApplyTheme() { - var settings = Settings.Default; + Settings settings = Settings.Default; settings.XftRgba = "rgb"; settings.XftDpi = 96; settings.XftHinting = 1; @@ -232,7 +230,7 @@ namespace Ryujinx private void Row_Activated(object obj, RowActivatedArgs args) { TableStore.GetIter(out TreeIter treeiter, new TreePath(args.Path.ToString())); - string path = (string)TableStore.GetValue(treeiter, 7); + string path = (string)TableStore.GetValue(treeiter, 5); LoadApplication(path); @@ -349,7 +347,7 @@ namespace Ryujinx private void Settings_Pressed(object o, EventArgs args) { - var SettingsWin = new SwitchSettings(device); + SwitchSettings SettingsWin = new SwitchSettings(device); gtkapp.Register(GLib.Cancellable.Current); gtkapp.AddWindow(SettingsWin); SettingsWin.Show(); @@ -375,7 +373,7 @@ namespace Ryujinx private void About_Pressed(object o, EventArgs args) { - var AboutWin = new AboutWindow(); + AboutWindow AboutWin = new AboutWindow(); gtkapp.Register(GLib.Cancellable.Current); gtkapp.AddWindow(AboutWin); AboutWin.Show(); diff --git a/Ryujinx/GUI/SwitchSettings.cs b/Ryujinx/GUI/SwitchSettings.cs index 437ca35c09..ce2131390f 100644 --- a/Ryujinx/GUI/SwitchSettings.cs +++ b/Ryujinx/GUI/SwitchSettings.cs @@ -13,9 +13,9 @@ namespace Ryujinx { public class SwitchSettings : Window { - internal static Configuration SwitchConfig { get; private set; } + internal static Configuration SwitchConfig { get; set; } - private HLE.Switch device { get; set; } + internal HLE.Switch device { get; set; } private static ListStore GameDirsBoxStore { get; set; } diff --git a/Ryujinx/GUI/assets/ryujinxROMIcon.png b/Ryujinx/GUI/assets/ryujinxROMIcon.png deleted file mode 100644 index b2f8abf5322780c42b87468195602b89ae59f715..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20327 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 - - - - - - - @@ -36,7 +29,6 @@ -