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
parent 3fbaf43d4e
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 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;

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.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<string> Games = new List<string>();
@ -58,62 +59,129 @@ namespace Ryujinx
ApplicationLibraryData = new List<ApplicationData>();
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; }
}
}
}

View file

@ -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,

View file

@ -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();

View file

@ -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; }

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 System;
using System.IO;
@ -11,9 +12,8 @@ namespace Ryujinx
{
Console.Title = "Ryujinx Console";
string parentDir = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory).ToString();
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.ProcessExit += CurrentDomain_ProcessExit;
@ -22,16 +22,16 @@ namespace Ryujinx
ApplicationLibrary.Init();
Gtk.Application.Init();
Application.Init();
var gtkapp = new Gtk.Application("Ryujinx.Ryujinx", GLib.ApplicationFlags.None);
var win = new MainMenu(args, gtkapp);
Application gtkapp = new Application("Ryujinx.Ryujinx", GLib.ApplicationFlags.None);
MainMenu win = new MainMenu(args, gtkapp);
gtkapp.Register(GLib.Cancellable.Current);
gtkapp.AddWindow(win);
win.Show();
Gtk.Application.Run();
Application.Run();
}
private static void CurrentDomain_ProcessExit(object sender, EventArgs e)

View file

@ -35,4 +35,5 @@
0100e9f00b882000
0100eab00605c000
0100efd00a4fa000
0100f6a00a684000
0100f6a00a684000
0100f9f00c696000

View file

@ -18,13 +18,6 @@
<Optimize>false</Optimize>
</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>
<EmbeddedResource Include="GUI\AboutWindow.glade" />
<EmbeddedResource Include="GUI\assets\DiscordLogo.png" />
@ -36,7 +29,6 @@
<EmbeddedResource Include="GUI\assets\ryujinxNROIcon.png" />
<EmbeddedResource Include="GUI\assets\ryujinxNSOIcon.png" />
<EmbeddedResource Include="GUI\assets\ryujinxNSPIcon.png" />
<EmbeddedResource Include="GUI\assets\ryujinxROMIcon.png" />
<EmbeddedResource Include="GUI\assets\ryujinxXCIIcon.png" />
<EmbeddedResource Include="GUI\assets\TwitterLogo.png" />
<EmbeddedResource Include="GUI\MainMenu.glade" />