Game icons and names are now shown in the games list
This commit is contained in:
parent
3fbaf43d4e
commit
9435231878
9 changed files with 149 additions and 92 deletions
|
@ -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;
|
||||
|
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 |
|
@ -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)
|
||||
|
|
|
@ -35,4 +35,5 @@
|
|||
0100e9f00b882000
|
||||
0100eab00605c000
|
||||
0100efd00a4fa000
|
||||
0100f6a00a684000
|
||||
0100f6a00a684000
|
||||
0100f9f00c696000
|
|
@ -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" />
|
||||
|
|
Loading…
Add table
Reference in a new issue