Added support for loading icon from .nro files and cleaned up the code a bit

This commit is contained in:
Xpl0itR 2019-06-04 20:50:47 +01:00
commit cf3a6cd993
No known key found for this signature in database
GPG key ID: 91798184109676AD
8 changed files with 130 additions and 53 deletions

View file

@ -1,5 +1,7 @@
using Gtk; using Gtk;
using System; using System;
using System.IO;
using System.Reflection;
namespace Ryujinx namespace Ryujinx
{ {
@ -7,27 +9,34 @@ namespace Ryujinx
{ {
public static void ControlSettingsMenu() public static void ControlSettingsMenu()
{ {
Window CSWin = new Window(WindowType.Toplevel); Window CSWin = new Window(WindowType.Toplevel);
CSWin.Title = "Control Settings"; CSWin.Title = "Control Settings";
CSWin.Icon = new Gdk.Pixbuf("./ryujinx.png"); CSWin.Resizable = false;
CSWin.SetDefaultSize(854, 360);
CSWin.Resizable = false;
CSWin.WindowPosition = WindowPosition.Center; CSWin.WindowPosition = WindowPosition.Center;
CSWin.SetDefaultSize(854, 360);
VBox box = new VBox(false, 2); VBox box = new VBox(false, 2);
//Load Icon
using (Stream iconstream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Ryujinx.ryujinxIcon.png"))
using (StreamReader reader = new StreamReader(iconstream))
{
Gdk.Pixbuf RyujinxIcon = new Gdk.Pixbuf(iconstream);
CSWin.Icon = RyujinxIcon;
}
//settings stuff will replace this block //settings stuff will replace this block
Label myLabel = new Label { Text = "General Settings" }; Label myLabel = new Label { Text = "Control Settings" };
box.PackStart(myLabel, true, true, 3); box.PackStart(myLabel, true, true, 3);
HBox ButtonBox = new HBox(true, 3); HBox ButtonBox = new HBox(true, 3);
Alignment BoxAlign = new Alignment(1, 0, 0, 0); Alignment BoxAlign = new Alignment(1, 0, 0, 0);
Button Save = new Button("Save"); Button Save = new Button("Save");
Save.Pressed += (o, args) => Save_Pressed(o, args, CSWin); Save.Pressed += (o, args) => Save_Pressed(o, args, CSWin);
ButtonBox.Add(Save); ButtonBox.Add(Save);
Button Cancel = new Button("Cancel"); Button Cancel = new Button("Cancel");
Cancel.Pressed += (o, args) => Cancel_Pressed(o, args, CSWin); Cancel.Pressed += (o, args) => Cancel_Pressed(o, args, CSWin);
ButtonBox.Add(Cancel); ButtonBox.Add(Cancel);

View file

@ -1,5 +1,7 @@
using Gtk; using Gtk;
using System; using System;
using System.IO;
using System.Reflection;
namespace Ryujinx namespace Ryujinx
{ {
@ -7,27 +9,34 @@ namespace Ryujinx
{ {
public static void GeneralSettingsMenu() public static void GeneralSettingsMenu()
{ {
Window GSWin = new Window(WindowType.Toplevel); Window GSWin = new Window(WindowType.Toplevel);
GSWin.Title = "General Settings"; GSWin.Title = "General Settings";
GSWin.Icon = new Gdk.Pixbuf("./ryujinx.png"); GSWin.Resizable = false;
GSWin.SetDefaultSize(854, 360);
GSWin.Resizable = false;
GSWin.WindowPosition = WindowPosition.Center; GSWin.WindowPosition = WindowPosition.Center;
GSWin.SetDefaultSize(854, 360);
VBox box = new VBox(false, 2); VBox box = new VBox(false, 2);
//Load Icon
using (Stream iconstream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Ryujinx.ryujinxIcon.png"))
using (StreamReader reader = new StreamReader(iconstream))
{
Gdk.Pixbuf RyujinxIcon = new Gdk.Pixbuf(iconstream);
GSWin.Icon = RyujinxIcon;
}
//settings stuff will replace this block //settings stuff will replace this block
Label myLabel = new Label { Text = "General Settings" }; Label myLabel = new Label { Text = "General Settings" };
box.PackStart(myLabel, true, true, 3); box.PackStart(myLabel, true, true, 3);
HBox ButtonBox = new HBox(true, 3); HBox ButtonBox = new HBox(true, 3);
Alignment BoxAlign = new Alignment(1, 0, 0, 0); Alignment BoxAlign = new Alignment(1, 0, 0, 0);
Button Save = new Button("Save"); Button Save = new Button("Save");
Save.Pressed += (o, args) => Save_Pressed(o, args, GSWin); Save.Pressed += (o, args) => Save_Pressed(o, args, GSWin);
ButtonBox.Add(Save); ButtonBox.Add(Save);
Button Cancel = new Button("Cancel"); Button Cancel = new Button("Cancel");
Cancel.Pressed += (o, args) => Cancel_Pressed(o, args, GSWin); Cancel.Pressed += (o, args) => Cancel_Pressed(o, args, GSWin);
ButtonBox.Add(Cancel); ButtonBox.Add(Cancel);

View file

@ -3,6 +3,8 @@ using GUI = Gtk.Builder.ObjectAttribute;
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using System; using System;
using System.IO; using System.IO;
using System.Reflection;
using System.Text;
namespace Ryujinx namespace Ryujinx
{ {
@ -12,7 +14,10 @@ namespace Ryujinx
internal ListStore TableStore { get; private set; } internal ListStore TableStore { get; private set; }
internal static Gdk.Pixbuf RyujinxIcon { get; private set; }
//UI Controls //UI Controls
[GUI] Window MainWin;
[GUI] MenuBar MenuBar; [GUI] MenuBar MenuBar;
[GUI] MenuItem LoadApplicationFile; [GUI] MenuItem LoadApplicationFile;
[GUI] MenuItem LoadApplicationFolder; [GUI] MenuItem LoadApplicationFolder;
@ -32,8 +37,8 @@ namespace Ryujinx
if (device.System.State.DiscordIntergrationEnabled == true) if (device.System.State.DiscordIntergrationEnabled == true)
{ {
Program.DiscordPresence.Details = "Main Menu"; Program.DiscordPresence.Details = "Main Menu";
Program.DiscordPresence.State = "Idling"; Program.DiscordPresence.State = "Idling";
Program.DiscordPresence.Timestamps = new DiscordRPC.Timestamps(DateTime.UtcNow); Program.DiscordPresence.Timestamps = new DiscordRPC.Timestamps(DateTime.UtcNow);
Program.DiscordClient.SetPresence(Program.DiscordPresence); Program.DiscordClient.SetPresence(Program.DiscordPresence);
@ -42,6 +47,14 @@ namespace Ryujinx
builder.Autoconnect(this); builder.Autoconnect(this);
ApplyTheme(); ApplyTheme();
//Load Icon
using (Stream iconstream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Ryujinx.ryujinxIcon.png"))
using (StreamReader reader = new StreamReader(iconstream))
{
RyujinxIcon = new Gdk.Pixbuf(iconstream);
MainWin.Icon = RyujinxIcon;
}
DeleteEvent += Window_Close; DeleteEvent += Window_Close;
//disable some buttons //disable some buttons
@ -58,13 +71,16 @@ namespace Ryujinx
GameTable.AppendColumn("Path", new CellRendererText(), "text" , 6); GameTable.AppendColumn("Path", new CellRendererText(), "text" , 6);
string dat = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "GameDirs.dat"); string dat = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "GameDirs.dat");
if (File.Exists(dat) == false) { File.Create(dat).Close(); } if (File.Exists(dat) == false) { File.Create(dat).Close(); }
string[] GameDirs = File.ReadAllLines(dat); string[] GameDirs = File.ReadAllLines(dat);
string[] Games = new string[] { }; string[] Games = new string[] { };
foreach (string GameDir in GameDirs) foreach (string GameDir in GameDirs)
{ {
if (Directory.Exists(GameDir) == false) { Logger.PrintError(LogClass.Application, "There is an invalid game directory in \"GameDirs.dat\""); return; } if (Directory.Exists(GameDir) == false) { Logger.PrintError(LogClass.Application, "There is an invalid game directory in \"GameDirs.dat\""); return; }
DirectoryInfo GameDirInfo = new DirectoryInfo(GameDir); DirectoryInfo GameDirInfo = new DirectoryInfo(GameDir);
foreach (var Game in GameDirInfo.GetFiles()) foreach (var Game in GameDirInfo.GetFiles())
{ {
@ -77,9 +93,11 @@ namespace Ryujinx
} }
TableStore = new ListStore(typeof(Gdk.Pixbuf), 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), typeof(string));
foreach (string GamePath in Games) foreach (string GamePath in Games)
{ {
TableStore.AppendValues(new Gdk.Pixbuf("./ryujinx.png", 50, 50), "", "", "", "", "", GamePath); Gdk.Pixbuf GameIcon = GetIconData(GamePath);
TableStore.AppendValues(GameIcon, "", "", "", "", "", GamePath);
} }
GameTable.Model = TableStore; GameTable.Model = TableStore;
@ -87,9 +105,9 @@ namespace Ryujinx
public static void ApplyTheme() public static void ApplyTheme()
{ {
var settings = Settings.Default; var settings = Settings.Default;
settings.XftRgba = "rgb"; settings.XftRgba = "rgb";
settings.XftHinting = 1; settings.XftHinting = 1;
settings.XftHintstyle = "hintfull"; settings.XftHintstyle = "hintfull";
CssProvider css_provider = new CssProvider(); CssProvider css_provider = new CssProvider();
@ -97,6 +115,44 @@ namespace Ryujinx
StyleContext.AddProviderForScreen(Gdk.Screen.Default, css_provider, 800); StyleContext.AddProviderForScreen(Gdk.Screen.Default, css_provider, 800);
} }
public static Gdk.Pixbuf GetIconData(string filePath)
{
using (FileStream Input = File.Open(filePath, FileMode.Open, FileAccess.Read))
{
BinaryReader Reader = new BinaryReader(Input);
if (System.IO.Path.GetExtension(filePath) == ".nro")
{
Input.Seek(24, SeekOrigin.Begin);
int AssetOffset = Reader.ReadInt32();
byte[] Read(long Position, int Size)
{
Input.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);
return new Gdk.Pixbuf(IconData, 50, 50);
}
else { return RyujinxIcon; }
}
else
{
return RyujinxIcon; //temp
}
}
}
//Events
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()));
@ -122,6 +178,7 @@ namespace Ryujinx
device.LoadProgram(path); device.LoadProgram(path);
break; break;
} }
Destroy(); Destroy();
Application.Quit(); Application.Quit();
} }
@ -129,7 +186,7 @@ namespace Ryujinx
private void Load_Application_File(object o, EventArgs args) private void Load_Application_File(object o, EventArgs args)
{ {
FileChooserDialog fc = new FileChooserDialog("Choose the file to open", this, FileChooserAction.Open, "Cancel", ResponseType.Cancel, "Open", ResponseType.Accept); FileChooserDialog fc = new FileChooserDialog("Choose the file to open", this, FileChooserAction.Open, "Cancel", ResponseType.Cancel, "Open", ResponseType.Accept);
fc.Filter = new FileFilter(); fc.Filter = new FileFilter();
fc.Filter.AddPattern("*.nsp"); fc.Filter.AddPattern("*.nsp");
fc.Filter.AddPattern("*.xci"); fc.Filter.AddPattern("*.xci");
fc.Filter.AddPattern("*.nca"); fc.Filter.AddPattern("*.nca");
@ -158,9 +215,11 @@ namespace Ryujinx
device.LoadProgram(fc.Filename); device.LoadProgram(fc.Filename);
break; break;
} }
Destroy(); Destroy();
Application.Quit(); Application.Quit();
} }
fc.Destroy(); fc.Destroy();
} }
@ -187,9 +246,11 @@ namespace Ryujinx
Logger.PrintInfo(LogClass.Application, "Loading as cart WITHOUT RomFS."); Logger.PrintInfo(LogClass.Application, "Loading as cart WITHOUT RomFS.");
device.LoadCart(fc.Filename); device.LoadCart(fc.Filename);
} }
Destroy(); Destroy();
Application.Quit(); Application.Quit();
} }
fc.Destroy(); fc.Destroy();
} }
@ -219,12 +280,12 @@ namespace Ryujinx
private void NFC_Pressed(object o, EventArgs args) private void NFC_Pressed(object o, EventArgs args)
{ {
FileChooserDialog fc = new FileChooserDialog("Choose the file to open", this, FileChooserAction.Open, "Cancel", ResponseType.Cancel, "Open", ResponseType.Accept); FileChooserDialog fc = new FileChooserDialog("Choose the file to open", this, FileChooserAction.Open, "Cancel", ResponseType.Cancel, "Open", ResponseType.Accept);
fc.Filter = new FileFilter(); fc.Filter = new FileFilter();
fc.Filter.AddPattern("*.bin"); fc.Filter.AddPattern("*.bin");
if (fc.Run() == (int)ResponseType.Accept) if (fc.Run() == (int)ResponseType.Accept)
{ {
Console.WriteLine(fc.Filename); Console.WriteLine(fc.Filename); //temp
} }
fc.Destroy(); fc.Destroy();
} }
@ -236,15 +297,15 @@ namespace Ryujinx
private void About_Pressed(object o, EventArgs args) private void About_Pressed(object o, EventArgs args)
{ {
AboutDialog about = new AboutDialog(); AboutDialog about = new AboutDialog();
about.ProgramName = "Ryujinx"; about.ProgramName = "Ryujinx";
about.Icon = new Gdk.Pixbuf("ryujinx.png"); about.Icon = RyujinxIcon;
about.Version = "Version x.x.x"; about.Version = "Version x.x.x";
about.Authors = new string[] { "gdkchan", "Ac_K", "LDj3SNuD", "emmauss", "MerryMage", "MS-DOS1999", "Thog", "jD", "BaronKiko", "Dr.Hacknik", "Lordmau5", "(and Xpl0itR did a bit of work too :D)" }; about.Authors = new string[] { "gdkchan", "Ac_K", "LDj3SNuD", "emmauss", "MerryMage", "MS-DOS1999", "Thog", "jD", "BaronKiko", "Dr.Hacknik", "Lordmau5", "(and Xpl0itR did a bit of work too :D)" };
about.Copyright = "Unlicense"; about.Copyright = "Unlicense";
about.Comments = "Ryujinx is an emulator for the Nintendo Switch"; about.Comments = "Ryujinx is an emulator for the Nintendo Switch";
about.Website = "https://github.com/Ryujinx/Ryujinx"; about.Website = "https://github.com/Ryujinx/Ryujinx";
about.Copyright = "Unlicense"; about.Copyright = "Unlicense";
about.WindowPosition = WindowPosition.Center; about.WindowPosition = WindowPosition.Center;
about.Run(); about.Run();
about.Destroy(); about.Destroy();

View file

@ -8,7 +8,6 @@
<property name="window_position">center</property> <property name="window_position">center</property>
<property name="default_width">1280</property> <property name="default_width">1280</property>
<property name="default_height">745</property> <property name="default_height">745</property>
<property name="icon">ryujinx.png</property>
<property name="gravity">center</property> <property name="gravity">center</property>
<child type="titlebar"> <child type="titlebar">
<placeholder/> <placeholder/>
@ -172,6 +171,7 @@
<object class="GtkTreeView" id="GameTable"> <object class="GtkTreeView" id="GameTable">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="headers_clickable">False</property>
<signal name="row-activated" handler="Row_Activated" swapped="no"/> <signal name="row-activated" handler="Row_Activated" swapped="no"/>
<child internal-child="selection"> <child internal-child="selection">
<object class="GtkTreeSelection"/> <object class="GtkTreeSelection"/>

View file

@ -36,16 +36,16 @@ namespace Ryujinx
Profile.Initialize(); Profile.Initialize();
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit; AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
if (device.System.State.DiscordIntegrationEnabled == true) if (device.System.State.DiscordIntegrationEnabled == true)
{ {
DiscordClient = new DiscordRpcClient("568815339807309834"); DiscordClient = new DiscordRpcClient("568815339807309834");
DiscordPresence = new RichPresence DiscordPresence = new RichPresence
{ {
Assets = new Assets Assets = new Assets
{ {
LargeImageKey = "ryujinx", LargeImageKey = "ryujinx",
LargeImageText = "Ryujinx is an emulator for the Nintendo Switch" LargeImageText = "Ryujinx is an emulator for the Nintendo Switch"
} }
}; };
@ -59,16 +59,16 @@ namespace Ryujinx
Gtk.Application.Init(); Gtk.Application.Init();
var resourceNames = Assembly.GetExecutingAssembly().GetManifestResourceNames(); var resourceNames = Assembly.GetExecutingAssembly().GetManifestResourceNames();
var app = new Gtk.Application("Ryujinx.Ryujinx", GLib.ApplicationFlags.None); var app = new Gtk.Application("Ryujinx.Ryujinx", GLib.ApplicationFlags.None);
var win = new MainMenu(device);
app.Register(GLib.Cancellable.Current); app.Register(GLib.Cancellable.Current);
var win = new MainMenu(device);
app.AddWindow(win); app.AddWindow(win);
win.Show(); win.Show();
Gtk.Application.Run(); Gtk.Application.Run();
} }
else else
{ {
if (Directory.Exists(args[0])) if (Directory.Exists(args[0]))
@ -127,12 +127,12 @@ namespace Ryujinx
DiscordPresence.Assets.LargeImageKey = device.System.TitleID; DiscordPresence.Assets.LargeImageKey = device.System.TitleID;
} }
DiscordPresence.Details = $"Playing {device.System.TitleName}"; DiscordPresence.Details = $"Playing {device.System.TitleName}";
DiscordPresence.State = string.IsNullOrWhiteSpace(device.System.TitleID) ? string.Empty : device.System.TitleID.ToUpper(); DiscordPresence.State = device.System.TitleID.ToUpper();
DiscordPresence.Assets.LargeImageText = device.System.TitleName; DiscordPresence.Assets.LargeImageText = device.System.TitleName;
DiscordPresence.Assets.SmallImageKey = "ryujinx"; DiscordPresence.Assets.SmallImageKey = "ryujinx";
DiscordPresence.Assets.SmallImageText = "Ryujinx is an emulator for the Nintendo Switch"; DiscordPresence.Assets.SmallImageText = "Ryujinx is an emulator for the Nintendo Switch";
DiscordPresence.Timestamps = new Timestamps(DateTime.UtcNow); DiscordPresence.Timestamps = new Timestamps(DateTime.UtcNow);
DiscordClient.SetPresence(DiscordPresence); DiscordClient.SetPresence(DiscordPresence);
} }

View file

@ -20,6 +20,7 @@
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="MainMenu.glade" /> <EmbeddedResource Include="MainMenu.glade" />
<EmbeddedResource Include="ryujinxIcon.png" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -44,9 +45,6 @@
<None Update="RPsupported.dat"> <None Update="RPsupported.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
<None Update="ryujinx.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Theme.css"> <None Update="Theme.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

BIN
Ryujinx/ryujinxIcon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB