big rewrite

This commit is contained in:
Xpl0itR 2019-06-09 02:52:44 +01:00
parent 38155b747a
commit 03274fea09
No known key found for this signature in database
GPG key ID: 91798184109676AD
4 changed files with 236 additions and 262 deletions

View file

@ -221,7 +221,7 @@ namespace Ryujinx
if (Instance.EnableFileLog)
{
Logger.AddTarget(new AsyncLogTargetWrapper(
new FileLogTarget(Path.Combine(Program.ApplicationDirectory, "Ryujinx.log")),
new FileLogTarget(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Ryujinx.log")),
1000,
AsyncLogTargetOverflowAction.Block
));
@ -253,7 +253,7 @@ namespace Ryujinx
}
}
Program.DiscordIntegrationEnabled = SwitchConfig.EnableDiscordIntegration;
MainMenu.DiscordIntegrationEnabled = SwitchConfig.EnableDiscordIntergration;
device.EnableDeviceVsync = SwitchConfig.EnableVsync;

View file

@ -9,7 +9,7 @@ namespace Ryujinx
{
public class GeneralSettings : Window
{
internal HLE.Switch device { get; private set; }
private HLE.Switch device { get; set; }
internal static Configuration SwitchConfig { get; private set; }

View file

@ -1,19 +1,35 @@
using Gtk;
using DiscordRPC;
using Gtk;
using GUI = Gtk.Builder.ObjectAttribute;
using Ryujinx.Audio;
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.Gal;
using Ryujinx.Graphics.Gal.OpenGL;
using Ryujinx.Profiler;
using System;
using System.IO;
using System.Linq;
using System.Reflection;
namespace Ryujinx
{
public class MainMenu : Window
{
internal HLE.Switch device { get; private set; }
public static bool DiscordIntegrationEnabled { get; set; }
internal Application gtkapp { get; private set; }
public static DiscordRpcClient DiscordClient;
internal ListStore TableStore { get; private set; }
public static RichPresence DiscordPresence;
private static IGalRenderer renderer;
private static IAalOutput audioOut;
private static HLE.Switch device { get; set; }
private static Application gtkapp { get; set; }
private static ListStore TableStore { get; set; }
//UI Controls
[GUI] Window MainWin;
@ -23,52 +39,88 @@ namespace Ryujinx
[GUI] ScrolledWindow GameTableWindow;
[GUI] GLArea GLScreen;
public MainMenu(HLE.Switch _device, Application _gtkapp) : this(new Builder("Ryujinx.GUI.MainMenu.glade"), _device, _gtkapp) { }
public MainMenu(string[] args, Application _gtkapp) : this(new Builder("Ryujinx.GUI.MainMenu.glade"), args, _gtkapp) { }
private MainMenu(Builder builder, HLE.Switch _device, Application _gtkapp) : base(builder.GetObject("MainWin").Handle)
private MainMenu(Builder builder, string[] args, Application _gtkapp) : base(builder.GetObject("MainWin").Handle)
{
device = _device;
renderer = new OglRenderer();
audioOut = InitializeAudioEngine();
device = new HLE.Switch(renderer, audioOut);
Configuration.Load(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.jsonc"));
Configuration.InitialConfigure(device);
gtkapp = _gtkapp;
if (Program.DiscordIntergrationEnabled)
{
Program.DiscordPresence.Details = "Main Menu";
Program.DiscordPresence.State = "Idling";
Program.DiscordPresence.Timestamps = new DiscordRPC.Timestamps(DateTime.UtcNow);
Program.DiscordClient.SetPresence(Program.DiscordPresence);
}
builder.Autoconnect(this);
MainWin.Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.GUI.assets.ryujinxIcon.png");
GameTableWindow.Show();
GLScreen.Hide();
ApplyTheme();
DeleteEvent += Window_Close;
//disable some buttons
NFC.Sensitive = false;
ControlSettingsMenu.Sensitive = false;
//Games grid thing
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("Path", new CellRendererText(), "text", 6);
TableStore = new ListStore(typeof(Gdk.Pixbuf), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string));
foreach (ApplicationLibrary.ApplicationData AppData in ApplicationLibrary.ApplicationLibraryData)
if (DiscordIntegrationEnabled)
{
TableStore.AppendValues(AppData.Icon, AppData.Game, AppData.Version, AppData.DLC, AppData.TP, AppData.LP, AppData.Path);
DiscordClient = new DiscordRpcClient("568815339807309834");
DiscordPresence = new RichPresence
{
Assets = new Assets
{
LargeImageKey = "ryujinx",
LargeImageText = "Ryujinx is an emulator for the Nintendo Switch"
},
Details = "Main Menu",
State = "Idling",
Timestamps = new Timestamps(DateTime.UtcNow)
};
DiscordClient.Initialize();
DiscordClient.SetPresence(DiscordPresence);
}
GameTable.Model = TableStore;
builder.Autoconnect(this);
MainWin.Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.GUI.assets.ryujinxIcon.png");
if (args.Length == 1)
{
GameTableWindow.Hide();
GLScreen.Show();
LoadApplication(args[0]);
using (GlScreen screen = new GlScreen(device, renderer))
{
screen.MainLoop();
Profile.FinishProfiling();
device.Dispose();
}
}
else
{
GameTableWindow.Show();
GLScreen.Hide();
NFC.Sensitive = false;
ControlSettingsMenu.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("Path", new CellRendererText(), "text", 6);
TableStore = new ListStore(typeof(Gdk.Pixbuf), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string));
foreach (ApplicationLibrary.ApplicationData AppData in ApplicationLibrary.ApplicationLibraryData)
{
TableStore.AppendValues(AppData.Icon, AppData.Game, AppData.Version, AppData.DLC, AppData.TP, AppData.LP, AppData.Path);
}
GameTable.Model = TableStore;
}
}
public static void ApplyTheme()
@ -93,38 +145,98 @@ namespace Ryujinx
StyleContext.AddProviderForScreen(Gdk.Screen.Default, css_provider, 800);
}
private static void LoadApplication(string path)
{
if (Directory.Exists(path))
{
string[] romFsFiles = Directory.GetFiles(path, "*.istorage");
if (romFsFiles.Length == 0)
{
romFsFiles = Directory.GetFiles(path, "*.romfs");
}
if (romFsFiles.Length > 0)
{
Logger.PrintInfo(LogClass.Application, "Loading as cart with RomFS.");
device.LoadCart(path, romFsFiles[0]);
}
else
{
Logger.PrintInfo(LogClass.Application, "Loading as cart WITHOUT RomFS.");
device.LoadCart(path);
}
}
else if (File.Exists(path))
{
switch (System.IO.Path.GetExtension(path).ToLowerInvariant())
{
case ".xci":
Logger.PrintInfo(LogClass.Application, "Loading as XCI.");
device.LoadXci(path);
break;
case ".nca":
Logger.PrintInfo(LogClass.Application, "Loading as NCA.");
device.LoadNca(path);
break;
case ".nsp":
case ".pfs0":
Logger.PrintInfo(LogClass.Application, "Loading as NSP.");
device.LoadNsp(path);
break;
default:
Logger.PrintInfo(LogClass.Application, "Loading as homebrew.");
device.LoadProgram(path);
break;
}
}
else
{
Logger.PrintWarning(LogClass.Application, "Please specify a valid XCI/NCA/NSP/PFS0/NRO file");
}
if (DiscordIntegrationEnabled)
{
if (File.ReadAllLines(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "RPsupported.dat")).Contains(device.System.TitleID))
{
DiscordPresence.Assets.LargeImageKey = device.System.TitleID;
}
DiscordPresence.Details = $"Playing {device.System.TitleName}";
DiscordPresence.State = device.System.TitleID.ToUpper();
DiscordPresence.Assets.LargeImageText = device.System.TitleName;
DiscordPresence.Assets.SmallImageKey = "ryujinx";
DiscordPresence.Assets.SmallImageText = "Ryujinx is an emulator for the Nintendo Switch";
DiscordPresence.Timestamps = new Timestamps(DateTime.UtcNow);
DiscordClient.SetPresence(DiscordPresence);
}
}
//Events
private void Row_Activated(object obj, RowActivatedArgs args)
{
TableStore.GetIter(out TreeIter treeiter, new TreePath(args.Path.ToString()));
string path = (string)TableStore.GetValue(treeiter, 6);
switch (System.IO.Path.GetExtension(path).ToLowerInvariant())
{
case ".xci":
Logger.PrintInfo(LogClass.Application, "Loading as XCI.");
device.LoadXci(path);
break;
case ".nca":
Logger.PrintInfo(LogClass.Application, "Loading as NCA.");
device.LoadNca(path);
break;
case ".nsp":
case ".pfs0":
Logger.PrintInfo(LogClass.Application, "Loading as NSP.");
device.LoadNsp(path);
break;
default:
Logger.PrintInfo(LogClass.Application, "Loading as homebrew.");
device.LoadProgram(path);
break;
}
LoadApplication(path);
GameTableWindow.Hide();
GLScreen.Show();
Destroy();
Application.Quit();
using (GlScreen screen = new GlScreen(device, renderer))
{
screen.MainLoop();
Profile.FinishProfiling();
device.Dispose();
}
audioOut.Dispose();
Logger.Shutdown();
}
private void Load_Application_File(object o, EventArgs args)
@ -139,32 +251,24 @@ namespace Ryujinx
if (fc.Run() == (int)ResponseType.Accept)
{
switch (System.IO.Path.GetExtension(fc.Filename).ToLowerInvariant())
{
case ".xci":
Logger.PrintInfo(LogClass.Application, "Loading as XCI.");
device.LoadXci(fc.Filename);
break;
case ".nca":
Logger.PrintInfo(LogClass.Application, "Loading as NCA.");
device.LoadNca(fc.Filename);
break;
case ".nsp":
case ".pfs0":
Logger.PrintInfo(LogClass.Application, "Loading as NSP.");
device.LoadNsp(fc.Filename);
break;
default:
Logger.PrintInfo(LogClass.Application, "Loading as homebrew.");
device.LoadProgram(fc.Filename);
break;
}
LoadApplication(fc.Filename);
GameTableWindow.Hide();
GLScreen.Show();
Destroy();
Application.Quit();
using (GlScreen screen = new GlScreen(device, renderer))
{
screen.MainLoop();
Profile.FinishProfiling();
device.Dispose();
}
audioOut.Dispose();
Logger.Shutdown();
}
fc.Destroy();
@ -176,29 +280,24 @@ namespace Ryujinx
if (fc.Run() == (int)ResponseType.Accept)
{
string[] romFsFiles = Directory.GetFiles(fc.Filename, "*.istorage");
if (romFsFiles.Length == 0)
{
romFsFiles = Directory.GetFiles(fc.Filename, "*.romfs");
}
if (romFsFiles.Length > 0)
{
Logger.PrintInfo(LogClass.Application, "Loading as cart with RomFS.");
device.LoadCart(fc.Filename, romFsFiles[0]);
}
else
{
Logger.PrintInfo(LogClass.Application, "Loading as cart WITHOUT RomFS.");
device.LoadCart(fc.Filename);
}
LoadApplication(fc.Filename);
GameTableWindow.Hide();
GLScreen.Show();
Destroy();
Application.Quit();
using (GlScreen screen = new GlScreen(device, renderer))
{
screen.MainLoop();
Profile.FinishProfiling();
device.Dispose();
}
audioOut.Dispose();
Logger.Shutdown();
}
fc.Destroy();
@ -206,11 +305,17 @@ namespace Ryujinx
private void Exit_Pressed(object o, EventArgs args)
{
audioOut.Dispose();
DiscordClient.Dispose();
Logger.Shutdown();
Environment.Exit(0);
}
private void Window_Close(object obj, DeleteEventArgs args)
{
audioOut.Dispose();
DiscordClient.Dispose();
Logger.Shutdown();
Environment.Exit(0);
}
@ -252,5 +357,25 @@ namespace Ryujinx
about.Run();
about.Destroy();
}
/// <summary>
/// Picks an <see cref="IAalOutput"/> audio output renderer supported on this machine
/// </summary>
/// <returns>An <see cref="IAalOutput"/> supported by this machine</returns>
private static IAalOutput InitializeAudioEngine()
{
if (SoundIoAudioOut.IsSupported)
{
return new SoundIoAudioOut();
}
else if (OpenALAudioOut.IsSupported)
{
return new OpenALAudioOut();
}
else
{
return new DummyAudioOut();
}
}
}
}

View file

@ -1,26 +1,12 @@
using DiscordRPC;
using Ryujinx.Audio;
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.Gal;
using Ryujinx.Graphics.Gal.OpenGL;
using Ryujinx.HLE;
using Ryujinx.Common.Logging;
using Ryujinx.Profiler;
using System;
using System.IO;
using System.Linq;
namespace Ryujinx
{
class Program
{
public static DiscordRpcClient DiscordClient;
public static RichPresence DiscordPresence;
public static bool DiscordIntegrationEnabled { get; set; }
public static string ApplicationDirectory => AppDomain.CurrentDomain.BaseDirectory;
static void Main(string[] args)
{
Console.Title = "Ryujinx Console";
@ -29,141 +15,26 @@ namespace Ryujinx
string systemPATH = Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.Machine);
Environment.SetEnvironmentVariable("Path", $"{Path.Combine(parentDir, "bin")};{systemPATH}");
IGalRenderer renderer = new OglRenderer();
IAalOutput audioOut = InitializeAudioEngine();
Switch device = new Switch(renderer, audioOut);
Configuration.Load(Path.Combine(ApplicationDirectory, "Config.jsonc"));
Configuration.InitialConfigure(device);
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
Profile.Initialize();
ApplicationLibrary.Init();
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
var gtkapp = new Gtk.Application("Ryujinx.Ryujinx", GLib.ApplicationFlags.None);
var win = new MainMenu(args, gtkapp);
if (DiscordIntegrationEnabled)
{
DiscordClient = new DiscordRpcClient("568815339807309834");
DiscordPresence = new RichPresence
{
Assets = new Assets
{
LargeImageKey = "ryujinx",
LargeImageText = "Ryujinx is an emulator for the Nintendo Switch"
}
};
gtkapp.Register(GLib.Cancellable.Current);
gtkapp.AddWindow(win);
win.Show();
DiscordClient.Initialize();
DiscordClient.SetPresence(DiscordPresence);
}
if (args.Length == 0)
{
Gtk.Application.Init();
var gtkapp = new Gtk.Application("Ryujinx.Ryujinx", GLib.ApplicationFlags.None);
var win = new MainMenu(device, gtkapp);
gtkapp.Register(GLib.Cancellable.Current);
gtkapp.AddWindow(win);
win.Show();
Gtk.Application.Run();
}
else
{
if (Directory.Exists(args[0]))
{
string[] romFsFiles = Directory.GetFiles(args[0], "*.istorage");
if (romFsFiles.Length == 0)
{
romFsFiles = Directory.GetFiles(args[0], "*.romfs");
}
if (romFsFiles.Length > 0)
{
Logger.PrintInfo(LogClass.Application, "Loading as cart with RomFS.");
device.LoadCart(args[0], romFsFiles[0]);
}
else
{
Logger.PrintInfo(LogClass.Application, "Loading as cart WITHOUT RomFS.");
device.LoadCart(args[0]);
}
}
else if (File.Exists(args[0]))
{
switch (Path.GetExtension(args[0]).ToLowerInvariant())
{
case ".xci":
Logger.PrintInfo(LogClass.Application, "Loading as XCI.");
device.LoadXci(args[0]);
break;
case ".nca":
Logger.PrintInfo(LogClass.Application, "Loading as NCA.");
device.LoadNca(args[0]);
break;
case ".nsp":
case ".pfs0":
Logger.PrintInfo(LogClass.Application, "Loading as NSP.");
device.LoadNsp(args[0]);
break;
default:
Logger.PrintInfo(LogClass.Application, "Loading as homebrew.");
device.LoadProgram(args[0]);
break;
}
}
else
{
Logger.PrintWarning(LogClass.Application, "Please specify a valid XCI/NCA/NSP/PFS0/NRO file");
}
}
if (DiscordIntegrationEnabled)
{
if (File.ReadAllLines(Path.Combine(ApplicationDirectory, "RPsupported.dat")).Contains(device.System.TitleID))
{
DiscordPresence.Assets.LargeImageKey = device.System.TitleID;
}
DiscordPresence.Details = $"Playing {device.System.TitleName}";
DiscordPresence.State = device.System.TitleID.ToUpper();
DiscordPresence.Assets.LargeImageText = device.System.TitleName;
DiscordPresence.Assets.SmallImageKey = "ryujinx";
DiscordPresence.Assets.SmallImageText = "Ryujinx is an emulator for the Nintendo Switch";
DiscordPresence.Timestamps = new Timestamps(DateTime.UtcNow);
DiscordClient.SetPresence(DiscordPresence);
}
using (GlScreen screen = new GlScreen(device, renderer))
{
screen.MainLoop();
Profile.FinishProfiling();
device.Dispose();
}
audioOut.Dispose();
Logger.Shutdown();
DiscordClient.Dispose();
Gtk.Application.Run();
}
private static void CurrentDomain_ProcessExit(object sender, EventArgs e)
{
Logger.Shutdown();
DiscordClient.Dispose();
}
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
@ -175,28 +46,6 @@ namespace Ryujinx
if (e.IsTerminating)
{
Logger.Shutdown();
DiscordClient.Dispose();
}
}
/// <summary>
/// Picks an <see cref="IAalOutput"/> audio output renderer supported on this machine
/// </summary>
/// <returns>An <see cref="IAalOutput"/> supported by this machine</returns>
private static IAalOutput InitializeAudioEngine()
{
if (SoundIoAudioOut.IsSupported)
{
return new SoundIoAudioOut();
}
else if (OpenALAudioOut.IsSupported)
{
return new OpenALAudioOut();
}
else
{
return new DummyAudioOut();
}
}
}