diff --git a/Ryujinx.Profiler/Profile.cs b/Ryujinx.Profiler/Profile.cs
index 8f808c2868..25b10c498d 100644
--- a/Ryujinx.Profiler/Profile.cs
+++ b/Ryujinx.Profiler/Profile.cs
@@ -8,7 +8,7 @@ namespace Ryujinx.Profiler
private static InternalProfile ProfileInstance;
private static ProfilerSettings Settings;
- private static bool ProfilingEnabled()
+ public static bool ProfilingEnabled()
{
if (!Settings.Enabled)
return false;
diff --git a/Ryujinx.Profiler/Ryujinx.Profiler.csproj b/Ryujinx.Profiler/Ryujinx.Profiler.csproj
index 4833752b3a..3fc6117096 100644
--- a/Ryujinx.Profiler/Ryujinx.Profiler.csproj
+++ b/Ryujinx.Profiler/Ryujinx.Profiler.csproj
@@ -5,6 +5,10 @@
win10-x64;osx-x64;linux-x64
+
+
+
+
diff --git a/Ryujinx.Profiler/UI/ProfileWindow.cs b/Ryujinx.Profiler/UI/ProfileWindow.cs
new file mode 100644
index 0000000000..1912013c86
--- /dev/null
+++ b/Ryujinx.Profiler/UI/ProfileWindow.cs
@@ -0,0 +1,117 @@
+using OpenTK;
+using OpenTK.Graphics.OpenGL;
+using System;
+using System.ComponentModel;
+
+namespace Ryujinx
+{
+ public class ProfileWindow : GameWindow
+ {
+ private bool visible = true;
+ public bool visibleChanged;
+
+ public ProfileWindow()
+ : base(400, 720)
+ {
+ //Keyboard.KeyDown += Keyboard_KeyDown;
+ Location = new Point(DisplayDevice.Default.Width - 400, (DisplayDevice.Default.Height - 720) / 2);
+ Title = "Profiler";
+ }
+
+ #region Public Methods
+ public void ToggleVisible()
+ {
+ visible = !visible;
+ visibleChanged = true;
+ }
+ #endregion
+
+ #region OnLoad
+ ///
+ /// Setup OpenGL and load resources
+ ///
+ /// Not used.
+ protected override void OnLoad(EventArgs e)
+ {
+ GL.ClearColor(Color.MidnightBlue);
+ }
+ #endregion
+
+ #region OnResize
+ ///
+ /// Respond to resize events
+ ///
+ /// Contains information on the new GameWindow size.
+ /// There is no need to call the base implementation.
+ protected override void OnResize(EventArgs e)
+ {
+ GL.Viewport(0, 0, Width, Height);
+
+ GL.MatrixMode(MatrixMode.Projection);
+ GL.LoadIdentity();
+ GL.Ortho(0, Width, 0, Height, 0.0, 4.0);
+ }
+ #endregion
+
+ #region OnClose
+ ///
+ /// Intercept close event and hide instead
+ ///
+ protected override void OnClosing(CancelEventArgs e)
+ {
+ visible = false;
+ visibleChanged = true;
+ e.Cancel = true;
+ base.OnClosing(e);
+ }
+ #endregion
+
+ #region OnUpdateFrame
+ ///
+ /// Profile Update Loop
+ ///
+ /// Contains timing information.
+ /// There is no need to call the base implementation.
+ protected override void OnUpdateFrame(FrameEventArgs e)
+ {
+ // Nothing to do!
+ }
+ #endregion
+
+ #region OnRenderFrame
+ ///
+ /// Profile Render Loop
+ ///
+ /// Contains timing information.
+ /// There is no need to call the base implementation.
+ protected override void OnRenderFrame(FrameEventArgs e)
+ {
+ if (visibleChanged)
+ {
+ Visible = visible;
+ visibleChanged = false;
+ }
+
+ if (!visible)
+ {
+ return;
+ }
+
+ GL.Clear(ClearBufferMask.ColorBufferBit);
+
+ GL.Begin(BeginMode.Triangles);
+
+ GL.Color3(Color.MidnightBlue);
+ GL.Vertex2(0.0f, 0.0f);
+ GL.Color3(Color.SpringGreen);
+ GL.Vertex2(50.0f, 100.0f);
+ GL.Color3(Color.Ivory);
+ GL.Vertex2(100.0f, 0.0f);
+
+ GL.End();
+
+ this.SwapBuffers();
+ }
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/Ryujinx.Profiler/UI/ProfileWindowManager.cs b/Ryujinx.Profiler/UI/ProfileWindowManager.cs
new file mode 100644
index 0000000000..1273a5a37f
--- /dev/null
+++ b/Ryujinx.Profiler/UI/ProfileWindowManager.cs
@@ -0,0 +1,30 @@
+using System.Threading;
+
+namespace Ryujinx.Profiler.UI
+{
+ public class ProfileWindowManager
+ {
+ private ProfileWindow window;
+
+ public ProfileWindowManager()
+ {
+ if (Profile.ProfilingEnabled())
+ {
+ Thread profileThread = new Thread(() =>
+ {
+ window = new ProfileWindow();
+ window.Run(60, 60);
+ });
+ profileThread.Start();
+ }
+ }
+
+ public void ToggleVisible()
+ {
+ if (Profile.ProfilingEnabled())
+ {
+ window.ToggleVisible();
+ }
+ }
+ }
+}
diff --git a/Ryujinx/Config.cs b/Ryujinx/Config.cs
index 8807357cfa..629d65493a 100644
--- a/Ryujinx/Config.cs
+++ b/Ryujinx/Config.cs
@@ -11,6 +11,7 @@ using System.IO;
using System.Linq;
using System.Reflection;
using Ryujinx.Profiler;
+using Ryujinx.Ui;
namespace Ryujinx
{
@@ -18,6 +19,7 @@ namespace Ryujinx
{
public static NpadKeyboard NpadKeyboard { get; private set; }
public static NpadController NpadController { get; private set; }
+ public static NPadDebug NPadDebug { get; private set; }
public static void Read(Switch device)
{
@@ -159,6 +161,12 @@ namespace Ryujinx
ButtonR = ToId(parser.Value("Controls_Right_JoyConController_Button_R")),
ButtonZr = ToId(parser.Value("Controls_Right_JoyConController_Button_ZR"))
});
+
+ NPadDebug = new NPadDebug(
+ new NPadDebugButtons()
+ {
+ ToggleProfiler = Convert.ToInt16(parser.Value(("Controls_Debug_Toggle_Profiler"))),
+ });
}
private static ControllerInputId ToId(string key)
diff --git a/Ryujinx/Ryujinx.conf b/Ryujinx/Ryujinx.conf
index 9e755d6243..2e15aac4d9 100644
--- a/Ryujinx/Ryujinx.conf
+++ b/Ryujinx/Ryujinx.conf
@@ -107,4 +107,7 @@ Controls_Right_JoyConController_Button_R = RShoulder
Controls_Right_JoyConController_Button_ZR = RTrigger
Controls_Left_JoyConController_Stick = LJoystick
-Controls_Right_JoyConController_Stick = RJoystick
\ No newline at end of file
+Controls_Right_JoyConController_Stick = RJoystick
+
+#Debug Controls
+Controls_Debug_Toggle_Profiler = 10
diff --git a/Ryujinx/Ui/GLScreen.cs b/Ryujinx/Ui/GLScreen.cs
index 478c5887f2..23857d8a8b 100644
--- a/Ryujinx/Ui/GLScreen.cs
+++ b/Ryujinx/Ui/GLScreen.cs
@@ -4,6 +4,8 @@ using OpenTK.Input;
using Ryujinx.Graphics.Gal;
using Ryujinx.HLE;
using Ryujinx.HLE.Input;
+using Ryujinx.Profiler;
+using Ryujinx.Profiler.UI;
using System;
using System.Threading;
@@ -28,6 +30,8 @@ namespace Ryujinx
private Thread _renderThread;
+ private ProfileWindowManager _profileWindow;
+
private bool _resizeEvent;
private bool _titleEvent;
@@ -46,6 +50,9 @@ namespace Ryujinx
Location = new Point(
(DisplayDevice.Default.Width / 2) - (Width / 2),
(DisplayDevice.Default.Height / 2) - (Height / 2));
+
+ // Start profile window, it will handle itself from there
+ _profileWindow = new ProfileWindowManager();
}
private void RenderLoop()
@@ -142,6 +149,14 @@ namespace Ryujinx
{
KeyboardState keyboard = _keyboard.Value;
+ // Debug
+ if (Config.NPadDebug.TogglePressed(keyboard))
+ {
+ _profileWindow.ToggleVisible();
+ }
+ Config.NPadDebug.SetPrevKeyboardState(keyboard);
+
+ // Normal Input
currentButton = Config.NpadKeyboard.GetButtons(keyboard);
(leftJoystickDx, leftJoystickDy) = Config.NpadKeyboard.GetLeftStick(keyboard);
diff --git a/Ryujinx/Ui/NPadDebug.cs b/Ryujinx/Ui/NPadDebug.cs
new file mode 100644
index 0000000000..415e5035cd
--- /dev/null
+++ b/Ryujinx/Ui/NPadDebug.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using OpenTK.Input;
+
+namespace Ryujinx.Ui
+{
+ public struct NPadDebugButtons
+ {
+ public int ToggleProfiler;
+ }
+
+ public class NPadDebug
+ {
+ public NPadDebugButtons Buttons;
+ private KeyboardState prevKeyboard;
+
+ public NPadDebug(NPadDebugButtons buttons)
+ {
+ Buttons = buttons;
+ }
+
+ public bool TogglePressed(KeyboardState keyboard) => !keyboard[(Key) Buttons.ToggleProfiler] && prevKeyboard[(Key) Buttons.ToggleProfiler];
+
+ public void SetPrevKeyboardState(KeyboardState keyboard)
+ {
+ prevKeyboard = keyboard;
+ }
+ }
+}