Game icons and names are now shown in the games list

This commit is contained in:
Xpl0itR 2019-06-21 18:21:15 +01:00
commit 9435231878
No known key found for this signature in database
GPG key ID: 91798184109676AD
9 changed files with 149 additions and 92 deletions

View file

@ -94,7 +94,7 @@ namespace Ryujinx.HLE.HOS
internal KEvent VsyncEvent { get; private set; } internal KEvent VsyncEvent { get; private set; }
internal Keyset KeySet { get; private set; } public Keyset KeySet { get; private set; }
private bool _hasStarted; private bool _hasStarted;
@ -455,8 +455,6 @@ namespace Ryujinx.HLE.HOS
TitleName = CurrentTitle = controlData.Descriptions[(int)State.DesiredTitleLanguage].Title; TitleName = CurrentTitle = controlData.Descriptions[(int)State.DesiredTitleLanguage].Title;
TitleID = metaData.Aci0.TitleId.ToString("x16"); TitleID = metaData.Aci0.TitleId.ToString("x16");
CurrentTitle = controlData.Descriptions[(int)State.DesiredTitleLanguage].Title;
if (string.IsNullOrWhiteSpace(CurrentTitle)) if (string.IsNullOrWhiteSpace(CurrentTitle))
{ {
TitleName = CurrentTitle = controlData.Descriptions.ToList().Find(x => !string.IsNullOrWhiteSpace(x.Title)).Title; TitleName = CurrentTitle = controlData.Descriptions.ToList().Find(x => !string.IsNullOrWhiteSpace(x.Title)).Title;

View file

@ -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;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
@ -22,8 +26,6 @@ namespace Ryujinx
{ {
public Gdk.Pixbuf Icon; public Gdk.Pixbuf Icon;
public string Game; public string Game;
public string Version;
public string DLC;
public string TP; public string TP;
public string LP; public string LP;
public string FileSize; public string FileSize;
@ -37,7 +39,6 @@ namespace Ryujinx
RyujinxNCAIcon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.GUI.assets.ryujinxNCAIcon.png", 75, 75); 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); 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); 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<string> Games = new List<string>(); List<string> Games = new List<string>();
@ -59,43 +60,99 @@ namespace Ryujinx
foreach (string GamePath in Games) foreach (string GamePath in Games)
{ {
double filesize = new FileInfo(GamePath).Length * 0.000000000931; double filesize = new FileInfo(GamePath).Length * 0.000000000931;
ApplicationData data = new ApplicationData()
using (FileStream file = new FileStream(GamePath, FileMode.Open, FileAccess.Read))
{ {
Icon = GetGameIcon(GamePath), Nca controlNca = null;
Game = (Path.GetExtension(GamePath) == ".nro") ? "Application" : "", PartitionFileSystem PFS = null;
Version = "", IFileSystem ControlFs = null;
DLC = (Path.GetExtension(GamePath) == ".nro") ? "N/A" : "", string TitleName = null;
TP = "", Gdk.Pixbuf GameIcon = null;
LP = "",
FileSize = (filesize < 1) ? (filesize * 1024).ToString("0.##") + "MB" : filesize.ToString("0.##") + "GB", if ((Path.GetExtension(GamePath) == ".nsp") || (Path.GetExtension(GamePath) == ".pfs0"))
Path = GamePath, {
}; PFS = new PartitionFileSystem(file.AsStorage());
ApplicationLibraryData.Add(data); }
else if (Path.GetExtension(GamePath) == ".xci")
{
Xci xci = new Xci(MainMenu.device.System.KeySet, file.AsStorage());
PFS = xci.OpenPartition(XciPartitionType.Secure);
}
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));
} }
} }
internal static Gdk.Pixbuf GetGameIcon(string filePath) foreach (DirectoryEntry fileEntry in PFS.EnumerateEntries("*.nca"))
{ {
using (FileStream Input = File.Open(filePath, FileMode.Open, FileAccess.Read)) Nca nca = new Nca(MainMenu.device.System.KeySet, PFS.OpenFile(fileEntry.FullPath, OpenMode.Read).AsStorage());
if (nca.Header.ContentType == ContentType.Control)
{ {
BinaryReader Reader = new BinaryReader(Input); controlNca = nca;
}
}
if ((Path.GetExtension(filePath) == ".nsp") || (Path.GetExtension(filePath) == ".pfs0")) { return RyujinxNSPIcon; } ControlFs = controlNca.OpenFileSystem(NcaSectionType.Data, MainMenu.device.System.FsIntegrityCheckLevel);
}
else if (Path.GetExtension(filePath) == ".xci") { return RyujinxXCIIcon; } if ((Path.GetExtension(GamePath) == ".nca") || (Path.GetExtension(GamePath) == ".nro") || (Path.GetExtension(GamePath) == ".nso")) { TitleName = Path.GetFileName(GamePath); }
else
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); 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(); int AssetOffset = Reader.ReadInt32();
byte[] Read(long Position, int Size) byte[] Read(long Position, int Size)
{ {
Input.Seek(Position, SeekOrigin.Begin); file.Seek(Position, SeekOrigin.Begin);
return Reader.ReadBytes(Size); return Reader.ReadBytes(Size);
} }
@ -108,12 +165,23 @@ namespace Ryujinx
byte[] IconData = Read(AssetOffset + IconOffset, (int)IconSize); byte[] IconData = Read(AssetOffset + IconOffset, (int)IconSize);
return new Gdk.Pixbuf(IconData, 75, 75); GameIcon = new Gdk.Pixbuf(IconData, 75, 75);
} }
else { return RyujinxNROIcon; } else { GameIcon = RyujinxNROIcon; }
} }
else { return RyujinxROMIcon; } 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);
}
} }
} }
} }

View file

@ -9,7 +9,7 @@
"logging_enable_fs_access_log": false, "logging_enable_fs_access_log": false,
"logging_filtered_classes": [ ], "logging_filtered_classes": [ ],
"enable_file_log": true, "enable_file_log": true,
"system_language": "BritishEnglish", "system_language": "AmericanEnglish",
"docked_mode": false, "docked_mode": false,
"enable_discord_integration": true, "enable_discord_integration": true,
"enable_vsync": true, "enable_vsync": true,

View file

@ -25,7 +25,7 @@ namespace Ryujinx
private static IAalOutput audioOut; private static IAalOutput audioOut;
private static HLE.Switch device { get; set; } internal static HLE.Switch device { get; set; }
private static Application gtkapp { get; set; } private static Application gtkapp { get; set; }
@ -105,15 +105,13 @@ namespace Ryujinx
NFC.Sensitive = false; NFC.Sensitive = false;
GameTable.AppendColumn("Icon", new CellRendererPixbuf(), "pixbuf", 0); GameTable.AppendColumn("Icon", new CellRendererPixbuf(), "pixbuf", 0);
//GameTable.AppendColumn("Game", new CellRendererText(), "text", 1); GameTable.AppendColumn("Game", new CellRendererText(), "text", 1);
//GameTable.AppendColumn("Version", new CellRendererText(), "text", 2); //GameTable.AppendColumn("Time Played", new CellRendererText(), "text", 2);
//GameTable.AppendColumn("DLC", new CellRendererText(), "text", 3); //GameTable.AppendColumn("Last Played", new CellRendererText(), "text", 3);
//GameTable.AppendColumn("Time Played", new CellRendererText(), "text", 4); GameTable.AppendColumn("File Size", new CellRendererText(), "text", 4);
//GameTable.AppendColumn("Last Played", new CellRendererText(), "text", 5); GameTable.AppendColumn("Path", new CellRendererText(), "text", 5);
GameTable.AppendColumn("File Size", new CellRendererText(), "text", 6);
GameTable.AppendColumn("Path", new CellRendererText(), "text", 7);
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; GameTable.Model = TableStore;
UpdateGameTable(); UpdateGameTable();
@ -127,13 +125,13 @@ namespace Ryujinx
foreach (ApplicationLibrary.ApplicationData AppData in ApplicationLibrary.ApplicationLibraryData) 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() public static void ApplyTheme()
{ {
var settings = Settings.Default; Settings settings = Settings.Default;
settings.XftRgba = "rgb"; settings.XftRgba = "rgb";
settings.XftDpi = 96; settings.XftDpi = 96;
settings.XftHinting = 1; settings.XftHinting = 1;
@ -232,7 +230,7 @@ namespace Ryujinx
private void Row_Activated(object obj, RowActivatedArgs args) private void Row_Activated(object obj, RowActivatedArgs args)
{ {
TableStore.GetIter(out TreeIter treeiter, new TreePath(args.Path.ToString())); 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); LoadApplication(path);
@ -349,7 +347,7 @@ namespace Ryujinx
private void Settings_Pressed(object o, EventArgs args) private void Settings_Pressed(object o, EventArgs args)
{ {
var SettingsWin = new SwitchSettings(device); SwitchSettings SettingsWin = new SwitchSettings(device);
gtkapp.Register(GLib.Cancellable.Current); gtkapp.Register(GLib.Cancellable.Current);
gtkapp.AddWindow(SettingsWin); gtkapp.AddWindow(SettingsWin);
SettingsWin.Show(); SettingsWin.Show();
@ -375,7 +373,7 @@ namespace Ryujinx
private void About_Pressed(object o, EventArgs args) private void About_Pressed(object o, EventArgs args)
{ {
var AboutWin = new AboutWindow(); AboutWindow AboutWin = new AboutWindow();
gtkapp.Register(GLib.Cancellable.Current); gtkapp.Register(GLib.Cancellable.Current);
gtkapp.AddWindow(AboutWin); gtkapp.AddWindow(AboutWin);
AboutWin.Show(); AboutWin.Show();

View file

@ -13,9 +13,9 @@ namespace Ryujinx
{ {
public class SwitchSettings : Window 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; } private static ListStore GameDirsBoxStore { get; set; }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

View file

@ -1,4 +1,5 @@
using Ryujinx.Common.Logging; using Gtk;
using Ryujinx.Common.Logging;
using Ryujinx.Profiler; using Ryujinx.Profiler;
using System; using System;
using System.IO; using System.IO;
@ -11,9 +12,8 @@ namespace Ryujinx
{ {
Console.Title = "Ryujinx Console"; Console.Title = "Ryujinx Console";
string parentDir = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory).ToString();
string systemPATH = Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.Machine); string systemPATH = Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.Machine);
Environment.SetEnvironmentVariable("Path", $"{Path.Combine(parentDir, "bin")};{systemPATH}"); Environment.SetEnvironmentVariable("Path", $"{Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin")};{systemPATH}");
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit; AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
@ -22,16 +22,16 @@ namespace Ryujinx
ApplicationLibrary.Init(); ApplicationLibrary.Init();
Gtk.Application.Init(); Application.Init();
var gtkapp = new Gtk.Application("Ryujinx.Ryujinx", GLib.ApplicationFlags.None); Application gtkapp = new Application("Ryujinx.Ryujinx", GLib.ApplicationFlags.None);
var win = new MainMenu(args, gtkapp); MainMenu win = new MainMenu(args, gtkapp);
gtkapp.Register(GLib.Cancellable.Current); gtkapp.Register(GLib.Cancellable.Current);
gtkapp.AddWindow(win); gtkapp.AddWindow(win);
win.Show(); win.Show();
Gtk.Application.Run(); Application.Run();
} }
private static void CurrentDomain_ProcessExit(object sender, EventArgs e) private static void CurrentDomain_ProcessExit(object sender, EventArgs e)

View file

@ -36,3 +36,4 @@
0100eab00605c000 0100eab00605c000
0100efd00a4fa000 0100efd00a4fa000
0100f6a00a684000 0100f6a00a684000
0100f9f00c696000

View file

@ -18,13 +18,6 @@
<Optimize>false</Optimize> <Optimize>false</Optimize>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<None Remove="GUI\assets\DiscordLogo.png" />
<None Remove="GUI\assets\GitHubLogo.png" />
<None Remove="GUI\assets\PatreonLogo.png" />
<None Remove="GUI\assets\TwitterLogo.png" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="GUI\AboutWindow.glade" /> <EmbeddedResource Include="GUI\AboutWindow.glade" />
<EmbeddedResource Include="GUI\assets\DiscordLogo.png" /> <EmbeddedResource Include="GUI\assets\DiscordLogo.png" />
@ -36,7 +29,6 @@
<EmbeddedResource Include="GUI\assets\ryujinxNROIcon.png" /> <EmbeddedResource Include="GUI\assets\ryujinxNROIcon.png" />
<EmbeddedResource Include="GUI\assets\ryujinxNSOIcon.png" /> <EmbeddedResource Include="GUI\assets\ryujinxNSOIcon.png" />
<EmbeddedResource Include="GUI\assets\ryujinxNSPIcon.png" /> <EmbeddedResource Include="GUI\assets\ryujinxNSPIcon.png" />
<EmbeddedResource Include="GUI\assets\ryujinxROMIcon.png" />
<EmbeddedResource Include="GUI\assets\ryujinxXCIIcon.png" /> <EmbeddedResource Include="GUI\assets\ryujinxXCIIcon.png" />
<EmbeddedResource Include="GUI\assets\TwitterLogo.png" /> <EmbeddedResource Include="GUI\assets\TwitterLogo.png" />
<EmbeddedResource Include="GUI\MainMenu.glade" /> <EmbeddedResource Include="GUI\MainMenu.glade" />