diff --git a/.gitignore b/.gitignore index 82d9719b5..f0c58d2fb 100644 --- a/.gitignore +++ b/.gitignore @@ -121,6 +121,7 @@ ClientBin/ *.publishsettings packages/* *.config +*.glide~ # RIA/Silverlight projects Generated_Code/ diff --git a/Ryujinx.Audio/IAalOutput.cs b/Ryujinx.Audio/IAalOutput.cs index f9978ee4d..c53da64b6 100644 --- a/Ryujinx.Audio/IAalOutput.cs +++ b/Ryujinx.Audio/IAalOutput.cs @@ -20,5 +20,7 @@ namespace Ryujinx.Audio void Stop(int Track); PlaybackState GetState(int Track); + + void Close(); } } \ No newline at end of file diff --git a/Ryujinx.Audio/OpenAL/OpenALAudioOut.cs b/Ryujinx.Audio/OpenAL/OpenALAudioOut.cs index f574b46f3..41fa2e5ff 100644 --- a/Ryujinx.Audio/OpenAL/OpenALAudioOut.cs +++ b/Ryujinx.Audio/OpenAL/OpenALAudioOut.cs @@ -360,6 +360,10 @@ namespace Ryujinx.Audio.OpenAL return PlaybackState.Stopped; } - + public void Close() + { + KeepPolling = false; + Context.Dispose(); + } } } \ No newline at end of file diff --git a/Ryujinx.Core/Hid/JoyCon.cs b/Ryujinx.Core/Hid/JoyCon.cs index 1aef82fe0..f83c02b83 100644 --- a/Ryujinx.Core/Hid/JoyCon.cs +++ b/Ryujinx.Core/Hid/JoyCon.cs @@ -1,4 +1,7 @@ -//TODO: This is only used by Config, it doesn't belong to Core. +using System.ComponentModel; +using Newtonsoft.Json; +using OpenTK.Input; + namespace Ryujinx.Core.Input { public struct JoyConLeft diff --git a/Ryujinx.Core/Logging/Logger.cs b/Ryujinx.Core/Logging/Logger.cs index 972d716cc..905ddf343 100644 --- a/Ryujinx.Core/Logging/Logger.cs +++ b/Ryujinx.Core/Logging/Logger.cs @@ -43,6 +43,16 @@ namespace Ryujinx.Core.Logging EnabledClasses[(int)Class] = Enabled; } + public bool IsEnabled(LogLevel Level) + { + return EnabledLevels[(int)Level]; + } + + public bool IsEnabled(LogClass Class) + { + return EnabledClasses[(int)Class]; + } + internal void PrintDebug(LogClass Class, string Message, [CallerMemberName] string Caller = "") { Print(LogLevel.Debug, Class, GetFormattedMessage(Class, Message, Caller)); diff --git a/Ryujinx.Core/OsHle/Horizon.cs b/Ryujinx.Core/OsHle/Horizon.cs index 3b31bfc6d..a84476c6e 100644 --- a/Ryujinx.Core/OsHle/Horizon.cs +++ b/Ryujinx.Core/OsHle/Horizon.cs @@ -167,6 +167,19 @@ namespace Ryujinx.Core.OsHle } } + public void ShutDown() + { + foreach(var Process in Processes) + { + Process.Value.StopAllThreadsAsync(); + Process.Value.Dispose(); + } + Processes.Clear(); + Ns.OnFinish(EventArgs.Empty); + Ns.Gpu.Close(); + Ns.AudioOut.Close(); + } + internal bool TryGetProcess(int ProcessId, out Process Process) { return Processes.TryGetValue(ProcessId, out Process); diff --git a/Ryujinx.Core/Ryujinx.Core.csproj b/Ryujinx.Core/Ryujinx.Core.csproj index b9374af1d..f34e352d6 100644 --- a/Ryujinx.Core/Ryujinx.Core.csproj +++ b/Ryujinx.Core/Ryujinx.Core.csproj @@ -12,6 +12,10 @@ true + + + + diff --git a/Ryujinx.Graphics/Gpu/NsGpu.cs b/Ryujinx.Graphics/Gpu/NsGpu.cs index e10889821..d14c5cf18 100644 --- a/Ryujinx.Graphics/Gpu/NsGpu.cs +++ b/Ryujinx.Graphics/Gpu/NsGpu.cs @@ -70,5 +70,10 @@ namespace Ryujinx.Graphics.Gpu Thread.Yield(); } } + + public void Close() + { + KeepRunning = false; + } } } \ No newline at end of file diff --git a/Ryujinx.UI/Configuration.cs b/Ryujinx.UI/Configuration.cs new file mode 100644 index 000000000..2a73d308a --- /dev/null +++ b/Ryujinx.UI/Configuration.cs @@ -0,0 +1,25 @@ +using Ryujinx.Core.Input; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using Newtonsoft.Json; +using Ryujinx.Core.Logging; + +namespace Ryujinx.UI +{ + public class Configuration + { + public bool EnableMemoryChecks { get; set; } + public bool LoggingEnableInfo { get; set; } + public bool LoggingEnableDebug { get; set; } + public bool LoggingEnableWarn { get; set; } + public bool LoggingEnableError { get; set; } + public bool LoggingEnableStub { get; set; } + + public string LoggingFilteredClasses { get; set; } + + public JoyCon EmulatedJoyCon { get; set; } + } +} \ No newline at end of file diff --git a/Ryujinx.UI/Dependencies/libbz2-1.dll b/Ryujinx.UI/Dependencies/libbz2-1.dll new file mode 100644 index 000000000..553478e6a Binary files /dev/null and b/Ryujinx.UI/Dependencies/libbz2-1.dll differ diff --git a/Ryujinx.UI/Dependencies/libcairo-2.dll b/Ryujinx.UI/Dependencies/libcairo-2.dll new file mode 100644 index 000000000..0ac754f91 Binary files /dev/null and b/Ryujinx.UI/Dependencies/libcairo-2.dll differ diff --git a/Ryujinx.UI/Dependencies/libepoxy-0.dll b/Ryujinx.UI/Dependencies/libepoxy-0.dll new file mode 100644 index 000000000..9f986a8f0 Binary files /dev/null and b/Ryujinx.UI/Dependencies/libepoxy-0.dll differ diff --git a/Ryujinx.UI/Dependencies/libexpat-1.dll b/Ryujinx.UI/Dependencies/libexpat-1.dll new file mode 100644 index 000000000..5e8565643 Binary files /dev/null and b/Ryujinx.UI/Dependencies/libexpat-1.dll differ diff --git a/Ryujinx.UI/Dependencies/libffi-6.dll b/Ryujinx.UI/Dependencies/libffi-6.dll new file mode 100644 index 000000000..6e154b845 Binary files /dev/null and b/Ryujinx.UI/Dependencies/libffi-6.dll differ diff --git a/Ryujinx.UI/Dependencies/libfontconfig-1.dll b/Ryujinx.UI/Dependencies/libfontconfig-1.dll new file mode 100644 index 000000000..eb5eda2ae Binary files /dev/null and b/Ryujinx.UI/Dependencies/libfontconfig-1.dll differ diff --git a/Ryujinx.UI/Dependencies/libfreetype-6.dll b/Ryujinx.UI/Dependencies/libfreetype-6.dll new file mode 100644 index 000000000..ee4afdc9c Binary files /dev/null and b/Ryujinx.UI/Dependencies/libfreetype-6.dll differ diff --git a/Ryujinx.UI/Dependencies/libgcc_s_seh-1.dll b/Ryujinx.UI/Dependencies/libgcc_s_seh-1.dll new file mode 100644 index 000000000..6d84b21cb Binary files /dev/null and b/Ryujinx.UI/Dependencies/libgcc_s_seh-1.dll differ diff --git a/Ryujinx.UI/Dependencies/libgdk-3-0.dll b/Ryujinx.UI/Dependencies/libgdk-3-0.dll new file mode 100644 index 000000000..1b1d7cb14 Binary files /dev/null and b/Ryujinx.UI/Dependencies/libgdk-3-0.dll differ diff --git a/Ryujinx.UI/Dependencies/libgdk_pixbuf-2.0-0.dll b/Ryujinx.UI/Dependencies/libgdk_pixbuf-2.0-0.dll new file mode 100644 index 000000000..a80ff4a84 Binary files /dev/null and b/Ryujinx.UI/Dependencies/libgdk_pixbuf-2.0-0.dll differ diff --git a/Ryujinx.UI/Dependencies/libglib-2.0-0.dll b/Ryujinx.UI/Dependencies/libglib-2.0-0.dll new file mode 100644 index 000000000..a30b5a031 Binary files /dev/null and b/Ryujinx.UI/Dependencies/libglib-2.0-0.dll differ diff --git a/Ryujinx.UI/Dependencies/libgobject-2.0-0.dll b/Ryujinx.UI/Dependencies/libgobject-2.0-0.dll new file mode 100644 index 000000000..a4c1bcb62 Binary files /dev/null and b/Ryujinx.UI/Dependencies/libgobject-2.0-0.dll differ diff --git a/Ryujinx.UI/Dependencies/libgraphite2.dll b/Ryujinx.UI/Dependencies/libgraphite2.dll new file mode 100644 index 000000000..9f58ee3ed Binary files /dev/null and b/Ryujinx.UI/Dependencies/libgraphite2.dll differ diff --git a/Ryujinx.UI/Dependencies/libgthread-2.0-0.dll b/Ryujinx.UI/Dependencies/libgthread-2.0-0.dll new file mode 100644 index 000000000..9f42d679a Binary files /dev/null and b/Ryujinx.UI/Dependencies/libgthread-2.0-0.dll differ diff --git a/Ryujinx.UI/Dependencies/libgtk-3-0.dll b/Ryujinx.UI/Dependencies/libgtk-3-0.dll new file mode 100644 index 000000000..04af8c788 Binary files /dev/null and b/Ryujinx.UI/Dependencies/libgtk-3-0.dll differ diff --git a/Ryujinx.UI/Dependencies/libharfbuzz-0.dll b/Ryujinx.UI/Dependencies/libharfbuzz-0.dll new file mode 100644 index 000000000..d77f2b641 Binary files /dev/null and b/Ryujinx.UI/Dependencies/libharfbuzz-0.dll differ diff --git a/Ryujinx.UI/Dependencies/libiconv-2.dll b/Ryujinx.UI/Dependencies/libiconv-2.dll new file mode 100644 index 000000000..4d54efb1d Binary files /dev/null and b/Ryujinx.UI/Dependencies/libiconv-2.dll differ diff --git a/Ryujinx.UI/Dependencies/libintl-8.dll b/Ryujinx.UI/Dependencies/libintl-8.dll new file mode 100644 index 000000000..a0f926785 Binary files /dev/null and b/Ryujinx.UI/Dependencies/libintl-8.dll differ diff --git a/Ryujinx.UI/Dependencies/libpango-1.0-0.dll b/Ryujinx.UI/Dependencies/libpango-1.0-0.dll new file mode 100644 index 000000000..eeeff50a3 Binary files /dev/null and b/Ryujinx.UI/Dependencies/libpango-1.0-0.dll differ diff --git a/Ryujinx.UI/Dependencies/libpangocairo-1.0-0.dll b/Ryujinx.UI/Dependencies/libpangocairo-1.0-0.dll new file mode 100644 index 000000000..410e23ae4 Binary files /dev/null and b/Ryujinx.UI/Dependencies/libpangocairo-1.0-0.dll differ diff --git a/Ryujinx.UI/Dependencies/libpangoft2-1.0-0.dll b/Ryujinx.UI/Dependencies/libpangoft2-1.0-0.dll new file mode 100644 index 000000000..5e4e80f28 Binary files /dev/null and b/Ryujinx.UI/Dependencies/libpangoft2-1.0-0.dll differ diff --git a/Ryujinx.UI/Dependencies/libpangowin32-1.0-0.dll b/Ryujinx.UI/Dependencies/libpangowin32-1.0-0.dll new file mode 100644 index 000000000..dab1e8d45 Binary files /dev/null and b/Ryujinx.UI/Dependencies/libpangowin32-1.0-0.dll differ diff --git a/Ryujinx.UI/Dependencies/libpcre32-0.dll b/Ryujinx.UI/Dependencies/libpcre32-0.dll new file mode 100644 index 000000000..85839b26a Binary files /dev/null and b/Ryujinx.UI/Dependencies/libpcre32-0.dll differ diff --git a/Ryujinx.UI/Dependencies/libpixman-1-0.dll b/Ryujinx.UI/Dependencies/libpixman-1-0.dll new file mode 100644 index 000000000..74a712c5e Binary files /dev/null and b/Ryujinx.UI/Dependencies/libpixman-1-0.dll differ diff --git a/Ryujinx.UI/Dependencies/libpng16-16.dll b/Ryujinx.UI/Dependencies/libpng16-16.dll new file mode 100644 index 000000000..d71c4700e Binary files /dev/null and b/Ryujinx.UI/Dependencies/libpng16-16.dll differ diff --git a/Ryujinx.UI/Dependencies/libstdc++-6.dll b/Ryujinx.UI/Dependencies/libstdc++-6.dll new file mode 100644 index 000000000..d1753d36e Binary files /dev/null and b/Ryujinx.UI/Dependencies/libstdc++-6.dll differ diff --git a/Ryujinx.UI/Dependencies/libwinpthread-1.dll b/Ryujinx.UI/Dependencies/libwinpthread-1.dll new file mode 100644 index 000000000..dd1eb67e0 Binary files /dev/null and b/Ryujinx.UI/Dependencies/libwinpthread-1.dll differ diff --git a/Ryujinx.UI/EmulationController.cs b/Ryujinx.UI/EmulationController.cs new file mode 100644 index 000000000..23be2d2e6 --- /dev/null +++ b/Ryujinx.UI/EmulationController.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Ryujinx.Graphics.Gal; + +namespace Ryujinx.Core +{ + public class EmutionController + { + private Thread EmulationThread; + private Switch Ns; + private IGalRenderer Renderer; + private bool IsPaused = false; + + public EmutionController(Switch Ns, IGalRenderer Renderer) + { + this.Ns = Ns; + this.Renderer = Renderer; + } + + public void Start() + { + EmulationThread = new Thread(new ThreadStart(() => + { + using (GLScreen Screen = new GLScreen(Ns, Renderer)) + { + Ns.Finish += (Sender, Args) => + { + Screen?.Exit(); + }; + + Screen.Closed += (Sender, Args) => + { + Stop(); + }; + + Screen.Run(60.0); + } + })); + + EmulationThread.Start(); + } + + public void Stop() + { + IsPaused = false; + Ns.Os.ShutDown(); + } + + public async void Pause() + { + IsPaused = true; + lock (Ns) + { + while (IsPaused) + { + Thread.Sleep(1000); + } + } + + } + + public void Continue() + { + IsPaused = false; + } + } +} diff --git a/Ryujinx.UI/MainWindow.cs b/Ryujinx.UI/MainWindow.cs new file mode 100644 index 000000000..d54e19be0 --- /dev/null +++ b/Ryujinx.UI/MainWindow.cs @@ -0,0 +1,237 @@ +using System; +using System.Threading.Tasks; +using Gtk; +using GUI = Gtk.Builder.ObjectAttribute; +using Ryujinx.Audio; +using Ryujinx.Audio.OpenAL; +using Ryujinx.Core; +using System.Threading; +using Ryujinx.Graphics.Gal; +using Ryujinx.Graphics.Gal.OpenGL; +using System.IO; +using System.Reflection; +using Ryujinx.Core.Logging; + +namespace Ryujinx.UI +{ + class MainWindow : Window + { + //UI Controls + [GUI] MenuItem LoadFileMenuItem; + [GUI] MenuItem LoadFolderMenuItem; + [GUI] MenuItem ExitMenuItem; + [GUI] MenuItem OptionMenuItem; + [GUI] MenuItem ShowDebugMenuItem; + [GUI] MenuItem ContinueMenuItem; + [GUI] MenuItem PauseMenuItem; + [GUI] MenuItem StopMenuItem; + [GUI] MenuItem AboutMenuItem; + + bool DebugWindowActive = false; + + Core.Switch Ns; + + IAalOutput AudioOut = new OpenALAudioOut(); + + IGalRenderer Renderer; + + EmutionController EmulationController; + + public MainWindow() : this(new Builder("MainWindow.glade")) { } + + private MainWindow(Builder builder) : base(builder.GetObject("MainWindow").Handle) + { + builder.Autoconnect(this); + + //Load Icon + using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Ryujinx.UI.ryujinxicon.png")) + using (StreamReader reader = new StreamReader(stream)) + { + Icon = new Gdk.Pixbuf(stream); + } + + InitializeSwitch(); + + //Register Events + DeleteEvent += Window_DeleteEvent; + LoadFileMenuItem.Activated += LoadFileMenuItem_Activated; + LoadFolderMenuItem.Activated += LoadFolderMenuItem_Activated; + ExitMenuItem.Activated += ExitMenuItem_Activated; + OptionMenuItem.Activated += OptionMenuItem_Activated; + ShowDebugMenuItem.Activated += ShowDebugMenuItem_Activated; + ContinueMenuItem.Activated += ContinueMenuItem_Activated; + PauseMenuItem.Activated += PauseMenuItem_Activated; + StopMenuItem.Activated += StopMenuItem_Activated; + AboutMenuItem.Activated += AboutMenuItem_Activated; + + PauseMenuItem.Sensitive = false; + ContinueMenuItem.Sensitive = false; + StopMenuItem.Sensitive = false; + + //Initialize Ryujinx + Console.Title = "Ryujinx Console"; + } + + private void AboutMenuItem_Activated(object sender, EventArgs e) + { + AboutDialog AboutDialog = new AboutDialog + { + Title = "Ryujinx", + Logo = Icon, + Comments = "This is a free switch emulator", + Copyright = "2018 - Ryujinx Team" + }; + + AboutDialog.Run(); + AboutDialog.Destroy(); + } + + private void LoadFolderMenuItem_Activated(object sender, EventArgs e) + { + FileChooserDialog ContentLoader = new FileChooserDialog("Open Game Folder", this, FileChooserAction.SelectFolder, + "Cancel", Gtk.ResponseType.Cancel, + "Open", Gtk.ResponseType.Accept + ); + if (ContentLoader.Run() == (int)Gtk.ResponseType.Accept) + { + if (Directory.Exists(ContentLoader.Filename)) + { + InitializeSwitch(); + + string FolderName = ContentLoader.Filename; + + ContentLoader.Destroy(); + + string[] RomFsFiles = Directory.GetFiles(FolderName, "*.istorage"); + + if (RomFsFiles.Length == 0) + { + RomFsFiles = Directory.GetFiles(FolderName, "*.romfs"); + } + + if (RomFsFiles.Length > 0) + { + Console.WriteLine("Loading as cart with RomFS."); + + Ns.LoadCart(FolderName, RomFsFiles[0]); + } + else + { + Console.WriteLine("Loading as cart WITHOUT RomFS."); + + Ns.LoadCart(FolderName); + } + + Start(); + } + } + else + ContentLoader.Destroy(); + } + + void InitializeSwitch() + { + Renderer = new OpenGLRenderer(); + + IAalOutput AudioOut = new OpenALAudioOut(); + + Ns = new Core.Switch(Renderer, AudioOut); + + Settings.Read(Ns.Log); + } + + private void StopMenuItem_Activated(object sender, EventArgs e) + { + EmulationController?.Stop(); + PauseMenuItem.Sensitive = false; + ContinueMenuItem.Sensitive = false; + StopMenuItem.Sensitive = false; + EmulationController = null; + } + + private void PauseMenuItem_Activated(object sender, EventArgs e) + { + new Thread(()=>EmulationController?.Pause()).Start(); + PauseMenuItem.Sensitive = false; + ContinueMenuItem.Sensitive = true; + StopMenuItem.Sensitive = true; + } + + private void ContinueMenuItem_Activated(object sender, EventArgs e) + { + EmulationController?.Continue(); + PauseMenuItem.Sensitive = true; + ContinueMenuItem.Sensitive = false; + StopMenuItem.Sensitive = true; + } + + private void ShowDebugMenuItem_Activated(object sender, EventArgs e) + { + UI.Debugging.Debugger debugger = new UI.Debugging.Debugger(); + debugger.DeleteEvent += Debugger_DeleteEvent; + DebugWindowActive = true; + debugger.Show(); + } + + private void Debugger_DeleteEvent(object o, DeleteEventArgs args) + { + DebugWindowActive = false; + } + + private void OptionMenuItem_Activated(object sender, EventArgs e) + { + UI.ConfigurationWindow configurationWindow = new UI.ConfigurationWindow(Ns.Log); + + if (configurationWindow.Run() == (int)ResponseType.Accept) + { + Settings.Write(Ns.Log); + } + else + Settings.Read(Ns.Log); + + configurationWindow.Destroy(); + } + + private void ExitMenuItem_Activated(object sender, EventArgs e) + { + Environment.Exit(0); + } + + private void LoadFileMenuItem_Activated(object sender, EventArgs e) + { + FileChooserDialog ContentLoader = new FileChooserDialog("Open Package", this, FileChooserAction.Open, + "Cancel", Gtk.ResponseType.Cancel, + "Open", Gtk.ResponseType.Accept + ); + if (ContentLoader.Run() == (int)Gtk.ResponseType.Accept) + { + if (File.Exists(ContentLoader.Filename)) + { + InitializeSwitch(); + + Ns.LoadProgram(ContentLoader.Filename); + + ContentLoader.Destroy(); + Start(); + } + } + else + ContentLoader.Destroy(); + } + + private void Window_DeleteEvent(object sender, DeleteEventArgs a) + { + EmulationController?.Stop(); + Environment.Exit(0); + } + + void Start() + { + EmulationController = new EmutionController(Ns, Renderer); + EmulationController.Start(); + PauseMenuItem.Sensitive = true; + ContinueMenuItem.Sensitive = false; + StopMenuItem.Sensitive = true; + } + } +} diff --git a/Ryujinx.UI/Program.cs b/Ryujinx.UI/Program.cs new file mode 100644 index 000000000..e7fc9b5b8 --- /dev/null +++ b/Ryujinx.UI/Program.cs @@ -0,0 +1,35 @@ +using Gtk; +using System; +using System.Reflection; +using System.Linq; +using Ryujinx.Core; +using Ryujinx.Core.Logging; + +namespace Ryujinx.UI +{ + class Program + { + [STAThread] + public static void Main(string[] args) + { + Application.Init(); + + Console.Title = "Ryujinx Console"; + + if (Environment.OSVersion.Platform == PlatformID.Win32NT) + AppDomain.CurrentDomain.AppendPrivatePath(@"Dependencies\"); + + Console.SetOut(UI.Debugging.LogPage.LogWriter); + + var resourceNames = Assembly.GetExecutingAssembly().GetManifestResourceNames(); + var app = new Application("org.Ryujinx.UI.Ryujinx.UI", GLib.ApplicationFlags.None); + app.Register(GLib.Cancellable.Current); + + var win = new MainWindow(); + app.AddWindow(win); + + win.Show(); + Application.Run(); + } + } +} diff --git a/Ryujinx.UI/Ryujinx.UI.csproj b/Ryujinx.UI/Ryujinx.UI.csproj new file mode 100644 index 000000000..2eb768c9b --- /dev/null +++ b/Ryujinx.UI/Ryujinx.UI.csproj @@ -0,0 +1,131 @@ + + + + WinExe + netcoreapp2.0 + + + + + + %(Filename)%(Extension) + + + + + + + + + + + + Never + + + + + + + + + + + + + + + + + + + + %(Filename)%(Extension) + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + diff --git a/Ryujinx.UI/Settings.cs b/Ryujinx.UI/Settings.cs new file mode 100644 index 000000000..86d78ea50 --- /dev/null +++ b/Ryujinx.UI/Settings.cs @@ -0,0 +1,164 @@ +using System; +using System.Reflection; +using System.IO; +using System.Collections.Generic; +using System.Text; +using Ryujinx.Core; +using Ryujinx.Core.Input; +using Newtonsoft.Json; +using Ryujinx.Core.Logging; + +namespace Ryujinx.UI +{ + public static class Settings + { + private static string ConfigPath; + + static Settings() + { + var IniFolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); + ConfigPath = Path.Combine(IniFolder, "RyujinxUI.json"); + } + + public static void Read(Logger Log) + { + JsonParser JsonParser = new JsonParser(ConfigPath); + var Configuration = JsonParser.Load(); + + Config.FakeJoyCon = Configuration.EmulatedJoyCon; + + AOptimizations.DisableMemoryChecks = !Configuration.EnableMemoryChecks; + + Log.SetEnable(LogLevel.Info, Configuration.LoggingEnableInfo); + Log.SetEnable(LogLevel.Debug, Configuration.LoggingEnableDebug); + Log.SetEnable(LogLevel.Error, Configuration.LoggingEnableError); + Log.SetEnable(LogLevel.Warning, Configuration.LoggingEnableWarn); + Log.SetEnable(LogLevel.Stub, Configuration.LoggingEnableStub); + + Configuration.LoggingFilteredClasses = Configuration.LoggingFilteredClasses != null ? + Configuration.LoggingFilteredClasses : string.Empty; + string[] FilteredLogClasses = Configuration.LoggingFilteredClasses.Split('\n'); + + //When the classes are specified on the list, we only + //enable the classes that are on the list. + //So, first disable everything, then enable + //the classes that the user added to the list. + if (FilteredLogClasses.Length > 0) + { + foreach (LogClass Class in Enum.GetValues(typeof(LogClass))) + { + Log.SetEnable(Class, false); + } + } + + foreach (string LogClass in FilteredLogClasses) + { + if (!string.IsNullOrEmpty(LogClass.Trim())) + { + foreach (LogClass Class in Enum.GetValues(typeof(LogClass))) + { + if (Class.ToString().ToLower().Contains(LogClass.Trim().ToLower())) + { + Log.SetEnable(Class, true); + } + } + } + } + } + + public static void Write(Logger Logger) + { + Configuration Configuration = new Configuration + { + EmulatedJoyCon = Config.FakeJoyCon, + EnableMemoryChecks = !AOptimizations.DisableMemoryChecks, + LoggingEnableDebug = (bool)Logger?.IsEnabled(LogLevel.Debug), + LoggingEnableInfo = (bool)Logger?.IsEnabled(LogLevel.Info), + LoggingEnableWarn = (bool)Logger?.IsEnabled(LogLevel.Warning), + LoggingEnableError = (bool)Logger?.IsEnabled(LogLevel.Error), + LoggingEnableStub = (bool)Logger?.IsEnabled(LogLevel.Stub) + }; + + lock (ConfigPath) + { + JsonParser JsonParser = new JsonParser(ConfigPath); + JsonParser.Save(Configuration); + } + } + + public static void LoadDefault() + { + Configuration configuration = new Configuration(); + Config.FakeJoyCon = new JoyCon(); + var Joycon = configuration.EmulatedJoyCon; + + Joycon.Left.StickUp = (int)OpenTK.Input.Key.W; + Joycon.Left.StickDown = (int)OpenTK.Input.Key.S; + Joycon.Left.StickLeft = (int)OpenTK.Input.Key.A; + Joycon.Left.StickRight = (int)OpenTK.Input.Key.D; + Joycon.Left.StickButton = (int)OpenTK.Input.Key.F; + Joycon.Left.DPadUp = (int)OpenTK.Input.Key.Up; + Joycon.Left.DPadDown = (int)OpenTK.Input.Key.Down; + Joycon.Left.DPadLeft = (int)OpenTK.Input.Key.Left; + Joycon.Left.DPadRight = (int)OpenTK.Input.Key.Right; + Joycon.Left.ButtonMinus = (int)OpenTK.Input.Key.Minus; + Joycon.Left.ButtonL = (int)OpenTK.Input.Key.E; + Joycon.Left.ButtonZL = (int)OpenTK.Input.Key.Q; + Joycon.Right.StickUp = (int)OpenTK.Input.Key.I; + Joycon.Right.StickDown = (int)OpenTK.Input.Key.K; + Joycon.Right.StickLeft = (int)OpenTK.Input.Key.J; + Joycon.Right.StickRight = (int)OpenTK.Input.Key.L; + Joycon.Right.StickButton = (int)OpenTK.Input.Key.H; + Joycon.Right.ButtonA = (int)OpenTK.Input.Key.Z; + Joycon.Right.ButtonB = (int)OpenTK.Input.Key.X; + Joycon.Right.ButtonX = (int)OpenTK.Input.Key.C; + Joycon.Right.ButtonY = (int)OpenTK.Input.Key.V; + Joycon.Right.ButtonPlus = (int)OpenTK.Input.Key.Plus; + Joycon.Right.ButtonR = (int)OpenTK.Input.Key.U; + Joycon.Right.ButtonZR = (int)OpenTK.Input.Key.O; + + Config.FakeJoyCon = Joycon; + + Write(null); + } + } + + public class JsonParser + { + private string ConfigPath; + + public JsonParser(string Path) + { + ConfigPath = Path; + if (!File.Exists(ConfigPath)) + { + File.CreateText(ConfigPath).Close(); + Settings.LoadDefault(); + } + } + + private string Serialize(T obj) + { + return JsonConvert.SerializeObject(obj, typeof(T),Formatting.Indented ,null); + } + + private T Deserialize(string serialized_string) + { + return (T)JsonConvert.DeserializeObject(serialized_string); + } + + public void Save(Configuration Configuration) + { + string SerializeText = Serialize(Configuration); + File.WriteAllText(ConfigPath, SerializeText); + } + + public Configuration Load() + { + if (!File.Exists(ConfigPath)) + File.Create(ConfigPath).Close(); + string Config = File.ReadAllText(ConfigPath); + return Deserialize(Config); + } + } +} diff --git a/Ryujinx.UI/UI/ConfigurationWindow.cs b/Ryujinx.UI/UI/ConfigurationWindow.cs new file mode 100644 index 000000000..a57ede900 --- /dev/null +++ b/Ryujinx.UI/UI/ConfigurationWindow.cs @@ -0,0 +1,56 @@ +using Gtk; +using System; +using System.Reflection; +using Ryujinx.Core.Logging; +using GUI = Gtk.Builder.ObjectAttribute; + +namespace Ryujinx.UI.UI +{ + public class ConfigurationWindow : Dialog + { + Logger Log; + [GUI] Notebook OptionNotebook; + [GUI] Button OptionAcceptButton; + [GUI] Button OptionCancelButton; + + public ConfigurationWindow(Logger Log) : this(new Builder("ConfigurationWindow.glade")) + { + this.Log = Log; + } + + private ConfigurationWindow(Builder builder) : base(builder.GetObject("ConfigurationWindow").Handle) + { + builder.Autoconnect(this); + + //Saves current configuration + Settings.Write(Log); + + //Loads Parser + var iniFolder = System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); + var iniPath = System.IO.Path.Combine(iniFolder, "Ryujinx.conf"); + + //Add pages + Label GeneralLabel = new Label("General"); + GeneralPage GeneralPage = new GeneralPage(); + OptionNotebook.AppendPage(GeneralPage.GetWidget(), GeneralLabel); + Label InputLabel = new Label("Input"); + InputPage InputPage = new InputPage(); + OptionNotebook.AppendPage(InputPage.GetWidget(), InputLabel); + + //Register Events + OptionAcceptButton.Clicked += OptionAcceptButton_Clicked; + OptionCancelButton.Clicked += OptionCancelButton_Clicked; + + } + + private void OptionCancelButton_Clicked(object sender, EventArgs e) + { + this.Respond(ResponseType.Cancel); + } + + private void OptionAcceptButton_Clicked(object sender, EventArgs e) + { + this.Respond(ResponseType.Accept); + } + } +} diff --git a/Ryujinx.UI/UI/ConfigurationWindow.glade b/Ryujinx.UI/UI/ConfigurationWindow.glade new file mode 100644 index 000000000..9e3538e19 --- /dev/null +++ b/Ryujinx.UI/UI/ConfigurationWindow.glade @@ -0,0 +1,72 @@ + + + + + + -1 + -1 + False + Configuration + dialog + + + False + vertical + 2 + + + False + end + + + OK + True + True + True + + + True + True + 0 + + + + + Cancel + True + True + True + + + True + True + 1 + + + + + False + False + 0 + + + + + -1 + -1 + True + True + + + True + True + 1 + + + + + + + + + diff --git a/Ryujinx.UI/UI/Debugging/Debugger.cs b/Ryujinx.UI/UI/Debugging/Debugger.cs new file mode 100644 index 000000000..00d24d700 --- /dev/null +++ b/Ryujinx.UI/UI/Debugging/Debugger.cs @@ -0,0 +1,25 @@ +using Gtk; +using System; +using System.Reflection; +using GUI = Gtk.Builder.ObjectAttribute; + + +namespace Ryujinx.UI.UI.Debugging +{ + public class Debugger : Gtk.Window + { + [GUI] Notebook DebuggerNotebook; + + public Debugger() : this(new Builder("Debugger.glade")) { } + + public Debugger(Builder builder) : base(builder.GetObject("Debugger").Handle) + { + builder.Autoconnect(this); + + //Add Pages + Label LogLabel = new Label("Log"); + LogPage LogPage = new LogPage(); + DebuggerNotebook.AppendPage(LogPage.Widget, LogLabel); + } + } +} diff --git a/Ryujinx.UI/UI/Debugging/Debugger.glade b/Ryujinx.UI/UI/Debugging/Debugger.glade new file mode 100644 index 000000000..e5283c9f5 --- /dev/null +++ b/Ryujinx.UI/UI/Debugging/Debugger.glade @@ -0,0 +1,19 @@ + + + + + + False + Debugger + + + 500 + True + True + + + + + + + diff --git a/Ryujinx.UI/UI/Debugging/LogPage.cs b/Ryujinx.UI/UI/Debugging/LogPage.cs new file mode 100644 index 000000000..4856c0fcd --- /dev/null +++ b/Ryujinx.UI/UI/Debugging/LogPage.cs @@ -0,0 +1,200 @@ +using Gtk; +using System; +using System.IO; +using System.Reflection; +using System.Text; +using Ryujinx.Core.Logging; +using GUI = Gtk.Builder.ObjectAttribute; +namespace Ryujinx.UI.UI.Debugging +{ + public class LogPage : Box + { + Logger Log; + + public static LogWriter LogWriter = new LogWriter(); + + Builder builder = new Builder("LogPage.glade"); + + Box LogBox; + + //UI elements + [GUI] Button SaveButton; + [GUI] TextView LogTextView; + [GUI] TextView LogClassesBox; + [GUI] CheckButton InfoLogEnable; + [GUI] CheckButton DebugLogEnable; + [GUI] CheckButton ErrorLogEnable; + [GUI] CheckButton StubLogEnable; + [GUI] CheckButton WarnLogEnable; + + public LogPage() : base(Orientation.Horizontal, 0) + { + //Load styles + CssProvider provider = new CssProvider(); + using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Ryujinx.UI.UI.style.css")) + using (StreamReader reader = new StreamReader(stream)) + { + provider.LoadFromData(reader.ReadToEnd()); + } + + builder.Autoconnect(this); + + LogBox = (Box)builder.GetObject("MainBox"); + + //Style the log text box + LogTextView.StyleContext.AddProvider(provider,1000); + + //Register Events + InfoLogEnable.Toggled += InfoLogEnable_Toggled; + DebugLogEnable.Toggled += DebugLogEnable_Toggled; + ErrorLogEnable.Toggled += ErrorLogEnable_Toggled; + WarnLogEnable.Toggled += WarnLogEnable_Toggled; + StubLogEnable.Toggled += StubLogEnable_Toggled; + SaveButton.Clicked += SaveButton_Clicked; + LogClassesBox.Buffer.InsertText += Buffer_InsertText; + + //Set values + LogTextView.Buffer = LogWriter.LogBuffer; + } + + private void SaveButton_Clicked(object sender, EventArgs e) + { + if (Log != null) + Settings.Write(Log); + } + + public void UpdateSettings(Logger Log) + { + this.Log = Log; + + InfoLogEnable.Active = Log.IsEnabled(LogLevel.Info); + DebugLogEnable.Active = Log.IsEnabled(LogLevel.Debug); + ErrorLogEnable.Active = Log.IsEnabled(LogLevel.Error); + WarnLogEnable.Active = Log.IsEnabled(LogLevel.Warning); + StubLogEnable.Active = Log.IsEnabled(LogLevel.Stub); + + string EnabledClasses = string.Empty; + foreach(var logClass in Enum.GetNames(typeof(LogClass))) + { + if (Log.IsEnabled(Enum.Parse(logClass))) + EnabledClasses += logClass + Environment.NewLine; + } + + LogClassesBox.Buffer.Text = EnabledClasses; + } + + private void Buffer_InsertText(object o, InsertTextArgs args) + { + string[] FilteredLogClasses = LogClassesBox.Buffer.Text.Split('\n'); + + if (FilteredLogClasses.Length > 0) + { + foreach (LogClass Class in Enum.GetValues(typeof(LogClass))) + { + Log.SetEnable(Class, false); + } + } + + foreach (string LogClass in FilteredLogClasses) + { + if (!string.IsNullOrEmpty(LogClass.Trim())) + { + foreach (LogClass Class in Enum.GetValues(typeof(LogClass))) + { + if (Class.ToString().ToLower().Contains(LogClass.Trim().ToLower())) + { + Log.SetEnable(Class, true); + } + } + } + } + } + + private void StubLogEnable_Toggled(object sender, EventArgs e) + { + if (sender is CheckButton LogCheckButton) + { + Log.SetEnable(LogLevel.Stub,LogCheckButton.Active); + } + } + + private void WarnLogEnable_Toggled(object sender, EventArgs e) + { + if (sender is CheckButton LogCheckButton) + { + Log.SetEnable(LogLevel.Warning, LogCheckButton.Active); + } + } + + private void ErrorLogEnable_Toggled(object sender, EventArgs e) + { + if (sender is CheckButton LogCheckButton) + { + Log.SetEnable(LogLevel.Error, LogCheckButton.Active); + } + } + + private void DebugLogEnable_Toggled(object sender, EventArgs e) + { + if (sender is CheckButton LogCheckButton) + { + Log.SetEnable(LogLevel.Debug, LogCheckButton.Active); + } + } + + private void InfoLogEnable_Toggled(object sender, EventArgs e) + { + if (sender is CheckButton LogCheckButton) + { + Log.SetEnable(LogLevel.Info, LogCheckButton.Active); + } + } + + public Widget Widget + { + get => LogBox; + } + } + + public class LogWriter : TextWriter + { + public override Encoding Encoding => Encoding.UTF8; + public TextBuffer LogBuffer { get; private set; } + private TextIter EndIter; + + public LogWriter() + { + LogBuffer = new TextBuffer(null); + EndIter = LogBuffer.EndIter; + + //Add color tags + LogBuffer.TagTable.Add(new TextTag("Red") { Foreground = "red" }); + LogBuffer.TagTable.Add(new TextTag("Gray") { Foreground = "grey" }); + LogBuffer.TagTable.Add(new TextTag("Yellow") { Foreground = "yellow" }); + LogBuffer.TagTable.Add(new TextTag("Magenta") { Foreground = "magenta" }); + LogBuffer.TagTable.Add(new TextTag("White") { Foreground = "white" }); + LogBuffer.TagTable.Add(new TextTag("DarkYellow") { Foreground = "orange" }); + LogBuffer.TagTable.Add(new TextTag("DarkGray") { Foreground = "darkgray" }); + } + + public override void Write(string value) + { + string consoleColor = Console.ForegroundColor.ToString(); + Gtk.Application.Invoke(delegate + { + LogBuffer.InsertWithTagsByName(ref EndIter, value, consoleColor); + }); + } + + public override void WriteLine(string value) + { + string consoleColor = Console.ForegroundColor.ToString(); + Gtk.Application.Invoke(delegate + { + LogBuffer.InsertWithTagsByName(ref EndIter, value + Environment.NewLine, consoleColor); + }); + } + + + } +} diff --git a/Ryujinx.UI/UI/Debugging/LogPage.glade b/Ryujinx.UI/UI/Debugging/LogPage.glade new file mode 100644 index 000000000..395756b46 --- /dev/null +++ b/Ryujinx.UI/UI/Debugging/LogPage.glade @@ -0,0 +1,254 @@ + + + + + + True + False + + + 400 + True + True + 5 + 5 + 10 + 10 + in + True + True + + + 400 + True + True + False + word + + + + + + True + True + 0 + + + + + 200 + True + False + 5 + 5 + 5 + vertical + + + True + False + 5 + 10 + 0 + none + + + True + False + 12 + + + True + False + 20 + 5 + vertical + + + Info + True + True + False + True + + + False + True + 0 + + + + + Debug + True + True + False + True + + + False + True + 1 + + + + + Error + True + True + False + True + + + False + True + 2 + + + + + Trace + True + True + False + True + + + False + True + 3 + + + + + Fatal + True + True + False + True + + + False + True + 4 + + + + + Stub + True + True + False + True + + + False + True + 5 + + + + + Warn + True + True + False + True + + + False + True + 6 + + + + + + + + + True + False + Log Levels + + + + + False + True + 0 + + + + + True + False + 5 + 10 + True + 0 + none + + + True + False + 12 + + + True + True + 5 + 5 + in + + + 200 + 300 + True + True + + + + + + + + + True + False + Log Classes + + + + + True + True + 1 + + + + + button + True + True + True + 10 + 10 + + + False + True + 3 + + + + + True + True + 1 + + + + diff --git a/Ryujinx.UI/UI/GeneralPage.cs b/Ryujinx.UI/UI/GeneralPage.cs new file mode 100644 index 000000000..5c02e0275 --- /dev/null +++ b/Ryujinx.UI/UI/GeneralPage.cs @@ -0,0 +1,36 @@ +using Gtk; +using System; +using GUI = Gtk.Builder.ObjectAttribute; + +namespace Ryujinx.UI.UI +{ + public class GeneralPage : Alignment + { + Alignment Alignment; + + [GUI] CheckButton MemoryChecksToggle; + + Builder builder = new Builder("GeneralPage.glade"); + + public GeneralPage(): base(0.5f, 0.5f, 1, 1) + { + builder.Autoconnect(this); + + Alignment = (Alignment)builder.GetObject("GeneralLayout"); + + MemoryChecksToggle.Toggled += MemoryChecksToggle_Toggled; + + MemoryChecksToggle.Active = !AOptimizations.DisableMemoryChecks; + } + + private void MemoryChecksToggle_Toggled(object sender, EventArgs e) + { + AOptimizations.DisableMemoryChecks = !MemoryChecksToggle.Active; + } + + public Widget GetWidget() + { + return Alignment; + } + } +} diff --git a/Ryujinx.UI/UI/GeneralPage.glade b/Ryujinx.UI/UI/GeneralPage.glade new file mode 100644 index 000000000..3c1069e98 --- /dev/null +++ b/Ryujinx.UI/UI/GeneralPage.glade @@ -0,0 +1,68 @@ + + + + + + True + False + 10 + + + True + False + 10 + 10 + 10 + vertical + + + True + False + 0 + none + + + True + False + 12 + + + True + False + vertical + + + Enable Memory Checks + True + True + False + True + + + False + True + 0 + + + + + + + + + True + False + CPU + + + + + False + True + 0 + + + + + + diff --git a/Ryujinx.UI/UI/InputPage.cs b/Ryujinx.UI/UI/InputPage.cs new file mode 100644 index 000000000..6aadcb211 --- /dev/null +++ b/Ryujinx.UI/UI/InputPage.cs @@ -0,0 +1,495 @@ +using Gtk; +using Ryujinx.Core; +using System; +using System.Threading.Tasks; +using System.Globalization; +using GUI = Gtk.Builder.ObjectAttribute; + +namespace Ryujinx.UI.UI +{ + public class InputPage : Notebook + { + Notebook Notebook; + //Buttons + [GUI] Button LeftAnalogUp; + [GUI] Button LeftAnalogDown; + [GUI] Button LeftAnalogLeft; + [GUI] Button LeftAnalogRight; + [GUI] Button LeftAnalogStick; + [GUI] Button RightAnalogUp; + [GUI] Button RightAnalogDown; + [GUI] Button RightAnalogLeft; + [GUI] Button RightAnalogRight; + [GUI] Button RightAnalogStick; + [GUI] Button DPadUp; + [GUI] Button DPadDown; + [GUI] Button DPadLeft; + [GUI] Button DPadRight; + [GUI] Button ButtonA; + [GUI] Button ButtonB; + [GUI] Button ButtonX; + [GUI] Button ButtonY; + [GUI] Button ButtonL; + [GUI] Button ButtonR; + [GUI] Button ButtonZL; + [GUI] Button ButtonZR; + [GUI] Button ButtonMinus; + [GUI] Button ButtonPlus; + + Gdk.Key CurrentKeyPressed; + bool IsPressed; + bool CancelCurrentEvent; + + Builder builder = new Builder("InputPage.glade"); + + public InputPage() + { + builder.Autoconnect(this); + + Notebook = (Notebook)builder.GetObject("InputNotebook"); + + //Register Events + LeftAnalogUp.Clicked += LeftAnalogUp_Clicked; + LeftAnalogDown.Clicked += LeftAnalogDown_Clicked; + LeftAnalogLeft.Clicked += LeftAnalogLeft_Clicked; + LeftAnalogRight.Clicked += LeftAnalogRight_Clicked; + LeftAnalogStick.Clicked += LeftAnalogStick_Clicked; + + RightAnalogUp.Clicked += RightAnalogUp_Clicked; + RightAnalogDown.Clicked += RightAnalogDown_Clicked; + RightAnalogLeft.Clicked += RightAnalogLeft_Clicked; + RightAnalogRight.Clicked += RightAnalogRight_Clicked; + RightAnalogStick.Clicked += RightAnalogStick_Clicked; + + DPadUp.Clicked += DPadUp_Clicked; + DPadDown.Clicked += DPadDown_Clicked; + DPadLeft.Clicked += DPadLeft_Clicked; + DPadRight.Clicked += DPadRight_Clicked; + + ButtonA.Clicked += ButtonA_Clicked; + ButtonB.Clicked += ButtonB_Clicked; + ButtonX.Clicked += ButtonX_Clicked; + ButtonY.Clicked += ButtonY_Clicked; + ButtonZL.Clicked += ButtonZL_Clicked; + ButtonZR.Clicked += ButtonZR_Clicked; + ButtonMinus.Clicked += ButtonMinus_Clicked; + ButtonPlus.Clicked += ButtonPlus_Clicked; + + // Load Values + LeftAnalogUp.Label = ((OpenTK.Input.Key)Config.FakeJoyCon.Left.StickUp).ToString(); + LeftAnalogDown.Label = ((OpenTK.Input.Key)Config.FakeJoyCon.Left.StickDown).ToString(); + LeftAnalogLeft.Label = ((OpenTK.Input.Key)Config.FakeJoyCon.Left.StickLeft).ToString(); + LeftAnalogRight.Label = ((OpenTK.Input.Key)Config.FakeJoyCon.Left.StickRight).ToString(); + LeftAnalogStick.Label = ((OpenTK.Input.Key)Config.FakeJoyCon.Left.StickButton).ToString(); + + RightAnalogUp.Label = ((OpenTK.Input.Key)Config.FakeJoyCon.Right.StickUp).ToString(); + RightAnalogDown.Label = ((OpenTK.Input.Key)Config.FakeJoyCon.Right.StickDown).ToString(); + RightAnalogLeft.Label = ((OpenTK.Input.Key)Config.FakeJoyCon.Right.StickLeft).ToString(); + RightAnalogRight.Label = ((OpenTK.Input.Key)Config.FakeJoyCon.Right.StickRight).ToString(); + RightAnalogStick.Label = ((OpenTK.Input.Key)Config.FakeJoyCon.Right.StickButton).ToString(); + + DPadUp.Label = ((OpenTK.Input.Key)Config.FakeJoyCon.Left.DPadUp).ToString(); + DPadDown.Label = ((OpenTK.Input.Key)Config.FakeJoyCon.Left.DPadDown).ToString(); + DPadLeft.Label = ((OpenTK.Input.Key)Config.FakeJoyCon.Left.DPadLeft).ToString(); + DPadRight.Label = ((OpenTK.Input.Key)Config.FakeJoyCon.Left.DPadRight).ToString(); + + ButtonA.Label = ((OpenTK.Input.Key)Config.FakeJoyCon.Right.ButtonA).ToString(); + ButtonB.Label = ((OpenTK.Input.Key)Config.FakeJoyCon.Right.ButtonB).ToString(); + ButtonX.Label = ((OpenTK.Input.Key)Config.FakeJoyCon.Right.ButtonX).ToString(); + ButtonY.Label = ((OpenTK.Input.Key)Config.FakeJoyCon.Right.ButtonY).ToString(); + ButtonL.Label = ((OpenTK.Input.Key)Config.FakeJoyCon.Left.ButtonL).ToString(); + ButtonR.Label = ((OpenTK.Input.Key)Config.FakeJoyCon.Right.ButtonR).ToString(); + ButtonZL.Label = ((OpenTK.Input.Key)Config.FakeJoyCon.Left.ButtonZL).ToString(); + ButtonZR.Label = ((OpenTK.Input.Key)Config.FakeJoyCon.Right.ButtonZR).ToString(); + ButtonMinus.Label = ((OpenTK.Input.Key)Config.FakeJoyCon.Left.ButtonMinus).ToString(); + ButtonPlus.Label = ((OpenTK.Input.Key)Config.FakeJoyCon.Right.ButtonPlus).ToString(); + } + + private async void ButtonPlus_Clicked(object sender, EventArgs e) + { + if (sender is Button ClickedButton) + { + OpenTK.Input.Key key = await GetKeyPress(ClickedButton); + if (key != default(OpenTK.Input.Key)) + { + var joycon = Config.FakeJoyCon; + joycon.Right.ButtonPlus = (int)key; + Config.FakeJoyCon = joycon; + } + } + } + + private async void ButtonMinus_Clicked(object sender, EventArgs e) + { + if (sender is Button ClickedButton) + { + OpenTK.Input.Key key = await GetKeyPress(ClickedButton); + if (key != default(OpenTK.Input.Key)) + { + var joycon = Config.FakeJoyCon; + joycon.Left.ButtonMinus = (int)key; + Config.FakeJoyCon = joycon; + } + } + } + + private async void ButtonZR_Clicked(object sender, EventArgs e) + { + if (sender is Button ClickedButton) + { + OpenTK.Input.Key key = await GetKeyPress(ClickedButton); + if (key != default(OpenTK.Input.Key)) + { + var joycon = Config.FakeJoyCon; + joycon.Right.ButtonZR = (int)key; + Config.FakeJoyCon = joycon; + } + } + } + + private async void ButtonZL_Clicked(object sender, EventArgs e) + { + if (sender is Button ClickedButton) + { + OpenTK.Input.Key key = await GetKeyPress(ClickedButton); + if (key != default(OpenTK.Input.Key)) + { + var joycon = Config.FakeJoyCon; + joycon.Left.ButtonZL = (int)key; + Config.FakeJoyCon = joycon; + } + } + } + + private async void ButtonY_Clicked(object sender, EventArgs e) + { + if (sender is Button ClickedButton) + { + OpenTK.Input.Key key = await GetKeyPress(ClickedButton); + if (key != default(OpenTK.Input.Key)) + { + var joycon = Config.FakeJoyCon; + joycon.Right.ButtonY = (int)key; + Config.FakeJoyCon = joycon; + } + } + } + + private async void ButtonX_Clicked(object sender, EventArgs e) + { + if (sender is Button ClickedButton) + { + OpenTK.Input.Key key = await GetKeyPress(ClickedButton); + if (key != default(OpenTK.Input.Key)) + { + var joycon = Config.FakeJoyCon; + joycon.Right.ButtonX = (int)key; + Config.FakeJoyCon = joycon; + } + } + } + + private async void ButtonB_Clicked(object sender, EventArgs e) + { + if (sender is Button ClickedButton) + { + OpenTK.Input.Key key = await GetKeyPress(ClickedButton); + if (key != default(OpenTK.Input.Key)) + { + var joycon = Config.FakeJoyCon; + joycon.Right.ButtonB = (int)key; + Config.FakeJoyCon = joycon; + } + } + } + + private async void ButtonA_Clicked(object sender, EventArgs e) + { + if (sender is Button ClickedButton) + { + OpenTK.Input.Key key = await GetKeyPress(ClickedButton); + if (key != default(OpenTK.Input.Key)) + { + var joycon = Config.FakeJoyCon; + joycon.Right.ButtonA = (int)key; + Config.FakeJoyCon = joycon; + } + } + } + + private async void DPadRight_Clicked(object sender, EventArgs e) + { + if (sender is Button ClickedButton) + { + OpenTK.Input.Key key = await GetKeyPress(ClickedButton); + if (key != default(OpenTK.Input.Key)) + { + var joycon = Config.FakeJoyCon; + joycon.Left.DPadRight = (int)key; + Config.FakeJoyCon = joycon; + } + } + } + + private async void DPadLeft_Clicked(object sender, EventArgs e) + { + if (sender is Button ClickedButton) + { + OpenTK.Input.Key key = await GetKeyPress(ClickedButton); + if (key != default(OpenTK.Input.Key)) + { + var joycon = Config.FakeJoyCon; + joycon.Left.DPadLeft = (int)key; + Config.FakeJoyCon = joycon; + } + } + } + + private async void DPadDown_Clicked(object sender, EventArgs e) + { + if (sender is Button ClickedButton) + { + OpenTK.Input.Key key = await GetKeyPress(ClickedButton); + if (key != default(OpenTK.Input.Key)) + { + var joycon = Config.FakeJoyCon; + joycon.Left.DPadDown = (int)key; + Config.FakeJoyCon = joycon; + } + } + } + + private async void DPadUp_Clicked(object sender, EventArgs e) + { + if (sender is Button ClickedButton) + { + OpenTK.Input.Key key = await GetKeyPress(ClickedButton); + if (key != default(OpenTK.Input.Key)) + { + var joycon = Config.FakeJoyCon; + joycon.Left.DPadUp = (int)key; + Config.FakeJoyCon = joycon; + } + } + } + + private async void RightAnalogStick_Clicked(object sender, EventArgs e) + { + if (sender is Button ClickedButton) + { + OpenTK.Input.Key key = await GetKeyPress(ClickedButton); + if (key != default(OpenTK.Input.Key)) + { + var joycon = Config.FakeJoyCon; + joycon.Right.StickButton = (int)key; + Config.FakeJoyCon = joycon; + } + } + } + + private async void RightAnalogRight_Clicked(object sender, EventArgs e) + { + if (sender is Button ClickedButton) + { + OpenTK.Input.Key key = await GetKeyPress(ClickedButton); + if (key != default(OpenTK.Input.Key)) + { + var joycon = Config.FakeJoyCon; + joycon.Right.StickRight = (int)key; + Config.FakeJoyCon = joycon; + } + } + } + + private async void RightAnalogLeft_Clicked(object sender, EventArgs e) + { + if (sender is Button ClickedButton) + { + OpenTK.Input.Key key = await GetKeyPress(ClickedButton); + if (key != default(OpenTK.Input.Key)) + { + var joycon = Config.FakeJoyCon; + joycon.Right.StickLeft = (int)key; + Config.FakeJoyCon = joycon; + } + } + } + + private async void RightAnalogDown_Clicked(object sender, EventArgs e) + { + if (sender is Button ClickedButton) + { + OpenTK.Input.Key key = await GetKeyPress(ClickedButton); + if (key != default(OpenTK.Input.Key)) + { + var joycon = Config.FakeJoyCon; + joycon.Right.StickDown = (int)key; + Config.FakeJoyCon = joycon; + } + } + } + + private async void RightAnalogUp_Clicked(object sender, EventArgs e) + { + if (sender is Button ClickedButton) + { + OpenTK.Input.Key key = await GetKeyPress(ClickedButton); + if (key != default(OpenTK.Input.Key)) + { + var joycon = Config.FakeJoyCon; + joycon.Right.StickUp = (int)key; + Config.FakeJoyCon = joycon; + } + } + } + + private async void LeftAnalogStick_Clicked(object sender, EventArgs e) + { + if (sender is Button ClickedButton) + { + OpenTK.Input.Key key = await GetKeyPress(ClickedButton); + if (key != default(OpenTK.Input.Key)) + { + var joycon = Config.FakeJoyCon; + joycon.Left.StickButton = (int)key; + Config.FakeJoyCon = joycon; + } + } + } + + private async void LeftAnalogRight_Clicked(object sender, EventArgs e) + { + if (sender is Button ClickedButton) + { + OpenTK.Input.Key key = await GetKeyPress(ClickedButton); + if (key != default(OpenTK.Input.Key)) + { + var joycon = Config.FakeJoyCon; + joycon.Left.StickRight = (int)key; + Config.FakeJoyCon = joycon; + } + } + } + + private async void LeftAnalogLeft_Clicked(object sender, EventArgs e) + { + if (sender is Button ClickedButton) + { + OpenTK.Input.Key key = await GetKeyPress(ClickedButton); + if (key != default(OpenTK.Input.Key)) + { + var joycon = Config.FakeJoyCon; + joycon.Left.StickLeft = (int)key; + Config.FakeJoyCon = joycon; + } + } + } + + private async void LeftAnalogDown_Clicked(object sender, EventArgs e) + { + if (sender is Button ClickedButton) + { + OpenTK.Input.Key key = await GetKeyPress(ClickedButton); + if (key != default(OpenTK.Input.Key)) + { + var joycon = Config.FakeJoyCon; + joycon.Left.StickDown = (int)key; + Config.FakeJoyCon = joycon; + } + } + } + + private async void LeftAnalogUp_Clicked(object sender, EventArgs e) + { + if (sender is Button ClickedButton) + { + OpenTK.Input.Key key = await GetKeyPress(ClickedButton); + if (key != default(OpenTK.Input.Key)) + { + var joycon = Config.FakeJoyCon; + joycon.Left.StickUp = (int)key; + Config.FakeJoyCon = joycon; + } + } + } + + private void InputPage_KeyPressEvent(object o, KeyPressEventArgs args) + { + CurrentKeyPressed = args.Event.Key; + IsPressed = true; + } + + public async Task GetKeyPress(Button ClickedButton) + { + string oldLabel = ClickedButton.Label; + try + { + ClickedButton.IsFocus = true; + ClickedButton.Label = "Enter Key"; + ClickedButton.KeyPressEvent += InputPage_KeyPressEvent; + ClickedButton.FocusOutEvent += ClickedButton_FocusOutEvent; + + + ClickedButton.KeyPressEvent -= InputPage_KeyPressEvent; + while (!IsPressed) + { + if (CancelCurrentEvent) + return default(OpenTK.Input.Key); + await Task.Delay(1); + } + + IsPressed = false; + string KeyCode = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(CurrentKeyPressed.ToString()); + + //Convert certain GTK Keys to OpenTK + switch (CurrentKeyPressed) + { + case Gdk.Key.Shift_L: + KeyCode = "LShift"; + break; + case Gdk.Key.Shift_R: + KeyCode = "RShift"; + break; + case Gdk.Key.Alt_L: + KeyCode = "LAlt"; + break; + case Gdk.Key.Alt_R: + KeyCode = "RAlt"; + break; + case Gdk.Key.Control_L: + KeyCode = "LControl"; + break; + case Gdk.Key.Control_R: + KeyCode = "RControl"; + break; + case Gdk.Key.dead_tilde: + KeyCode = "Tilde"; + break; + } + + return (OpenTK.Input.Key)Enum.Parse(typeof(OpenTK.Input.Key), KeyCode, true); + } + finally + { + CancelCurrentEvent = false; + Gtk.Application.Invoke(delegate + { + ClickedButton.FocusOutEvent -= ClickedButton_FocusOutEvent; + ClickedButton.KeyPressEvent -= InputPage_KeyPressEvent; + ClickedButton.Label = ClickedButton.Label.Equals("Enter Key") ? oldLabel : ClickedButton.Label; + }); + } + } + + private void ClickedButton_FocusOutEvent(object o, FocusOutEventArgs args) + { + CancelCurrentEvent = true; + IsPressed = false; + } + + public Widget GetWidget() + { + return Notebook; + } + } +} diff --git a/Ryujinx.UI/UI/InputPage.glade b/Ryujinx.UI/UI/InputPage.glade new file mode 100644 index 000000000..a7f833ce1 --- /dev/null +++ b/Ryujinx.UI/UI/InputPage.glade @@ -0,0 +1,1234 @@ + + + + + + -1 + -1 + True + True + + + True + False + 5 + 10 + 5 + 10 + True + + + -1 + -1 + True + False + 5 + 0 + none + + + -1 + -1 + True + False + 12 + + + True + False + vertical + + + -1 + -1 + True + False + 0 + none + + + True + False + 12 + + + True + False + vertical + + + True + False + True + + + True + False + 0 + none + + + True + False + 12 + + + Controls_Left_FakeJoycon_Stick_Up + True + True + True + + + + + + + True + False + Up + + + + + 0 + 0 + + + + + True + False + 0 + none + + + True + False + 12 + + + Controls_Left_FakeJoycon_Stick_Down + True + True + True + + + + + + + True + False + Down + + + + + 1 + 0 + + + + + True + False + 0 + none + + + True + False + 12 + + + Controls_Left_FakeJoycon_Stick_Left + True + True + True + + + + + + + True + False + Left + + + + + 0 + 1 + + + + + True + False + 0 + none + + + True + False + 12 + + + Controls_Left_FakeJoycon_Stick_Right + True + True + True + + + + + + + True + False + Right + + + + + 1 + 1 + + + + + False + True + 0 + + + + + True + False + center + center + 0 + none + + + True + False + 12 + + + 100 + True + True + True + + + + + + + True + False + L-Stick + + + + + False + True + 1 + + + + + + + + + True + False + Left + + + + + False + True + 0 + + + + + -1 + -1 + True + False + 0 + none + + + True + False + 12 + + + True + False + vertical + + + True + False + True + + + True + False + 0 + none + + + True + False + 12 + + + Controls_Right_FakeJoycon_Stick_Up + True + True + True + + + + + + + True + False + Up + + + + + 0 + 0 + + + + + True + False + 0 + none + + + True + False + 12 + + + Controls_Right_FakeJoycon_Stick_Down + True + True + True + + + + + + + True + False + Down + + + + + 1 + 0 + + + + + True + False + 0 + none + + + True + False + 12 + + + Controls_Right_FakeJoycon_Stick_Left + True + True + True + + + + + + + True + False + Left + + + + + 0 + 1 + + + + + True + False + 0 + none + + + True + False + 12 + + + Controls_Right_FakeJoycon_Stick_Right + True + True + True + + + + + + + True + False + Right + + + + + 1 + 1 + + + + + False + True + 0 + + + + + True + False + center + center + 0 + none + + + True + False + 12 + + + Controls_Right_FakeJoycon_Stick_Stick + 100 + True + True + True + center + center + + + + + + + True + False + R-Stick + + + + + False + True + 1 + + + + + + + + + True + False + Right + + + + + False + True + 1 + + + + + True + False + 0 + none + + + True + False + 12 + + + True + False + vertical + + + True + False + True + True + + + True + False + 0 + none + + + True + False + 12 + + + Controls_Left_FakeJoycon_DPad_Up + 100 + True + True + True + + + + + + + True + False + Up + + + + + 0 + 0 + + + + + True + False + 0 + none + + + True + False + 12 + + + Controls_Left_FakeJoycon_DPad_Left + 100 + True + True + True + + + + + + + True + False + Down + + + + + 1 + 0 + + + + + True + False + 0 + none + + + True + False + 12 + + + Controls_Left_FakeJoycon_DPad_Left + 100 + True + True + True + + + + + + + True + False + Left + + + + + 0 + 1 + + + + + True + False + 0 + none + + + True + False + 12 + + + Controls_Left_FakeJoycon_DPad_Right + 100 + True + True + True + + + + + + + True + False + Right + + + + + 1 + 1 + + + + + False + True + 0 + + + + + + + + + True + False + D-Pad + + + + + False + True + 2 + + + + + + + + + True + False + Analogs + + + + + True + True + 0 + + + + + -1 + -1 + True + False + 0 + none + + + -1 + -1 + True + False + 12 + + + True + False + 10 + vertical + True + + + True + False + 0 + none + + + True + False + 12 + + + True + False + vertical + + + True + False + True + True + + + True + False + 0 + none + + + True + False + 12 + + + Controls_Left_FakeJoycon_Button_A + 100 + True + True + True + + + + + + + True + False + A + + + + + 0 + 0 + + + + + True + False + 0 + none + + + True + False + 12 + + + Controls_Left_FakeJoycon_Button_B + 100 + True + True + True + + + + + + + True + False + B + + + + + 1 + 0 + + + + + True + False + 0 + none + + + True + False + 12 + + + Controls_Left_FakeJoycon_Button_X + 100 + True + True + True + + + + + + + True + False + X + + + + + 0 + 1 + + + + + True + False + 0 + none + + + True + False + 12 + + + Controls_Left_FakeJoycon_Button_Y + 100 + True + True + True + + + + + + + True + False + Y + + + + + 1 + 1 + + + + + False + True + 0 + + + + + + + + + True + False + Face Buttons + + + + + False + True + 0 + + + + + True + False + 0 + none + + + True + False + 12 + + + True + False + vertical + + + True + False + True + True + + + True + False + 0 + none + + + True + False + 12 + + + Controls_Left_FakeJoycon_Button_L + 100 + True + True + True + + + + + + + True + False + L + + + + + 0 + 0 + + + + + True + False + 0 + none + + + True + False + 12 + + + Controls_Left_FakeJoycon_Button_R + 100 + True + True + True + + + + + + + True + False + R + + + + + 1 + 0 + + + + + True + False + 0 + none + + + True + False + 12 + + + Controls_Left_FakeJoycon_Button_ZL + 100 + True + True + True + + + + + + + True + False + ZL + + + + + 0 + 1 + + + + + True + False + 0 + none + + + True + False + 12 + + + Controls_Left_FakeJoycon_Button_ZR + 100 + True + True + True + + + + + + + True + False + ZR + + + + + 1 + 1 + + + + + False + True + 0 + + + + + + + + + True + False + Triggers + + + + + False + True + 1 + + + + + True + False + 0 + none + + + True + False + 12 + + + True + False + vertical + + + True + False + True + True + + + True + False + 0 + none + + + True + False + 12 + + + Controls_Left_FakeJoycon_Button_Minus + 100 + True + True + True + + + + + + + True + False + - + + + + + 0 + 0 + + + + + True + False + 0 + none + + + True + False + 12 + + + Controls_Left_FakeJoycon_Button_Plus + 100 + True + True + True + + + + + + + True + False + + + + + + + 1 + 0 + + + + + False + True + 0 + + + + + + + + + True + False + Extra + + + + + False + True + 2 + + + + + + + + + True + False + Buttons + + + + + True + True + 1 + + + + + + + True + False + JoyCons + + + False + + + + diff --git a/Ryujinx.UI/UI/MainWindow.glade b/Ryujinx.UI/UI/MainWindow.glade new file mode 100644 index 000000000..e6d7a0782 --- /dev/null +++ b/Ryujinx.UI/UI/MainWindow.glade @@ -0,0 +1,196 @@ + + + + + + True + False + gtk-about + + + True + False + gtk-file + + + True + False + gtk-open + + + 1027 + 640 + False + RyujinxUI + True + + + True + False + vertical + + + True + False + start + + + True + False + Game + + + True + False + + + Load Package + True + False + FileImage + False + True + + + + + Load Game Folder + True + False + FolderImage + False + + + + + True + False + + + + + gtk-close + True + False + True + True + True + + + + + + + + + True + False + Emulation + True + + + True + False + + + True + False + Continue + True + + + + + True + False + Pause + True + + + + + True + False + Stop + True + + + + + True + False + + + + + True + False + Configuration + True + + + + + + + + + True + False + View + True + + + True + False + + + True + False + Show Debug Window + True + + + + + + + + + True + False + Help + + + True + False + + + About Ryujinx + True + False + AboutImage + False + + + + + + + + + False + True + 0 + + + + + + + + + + + + diff --git a/Ryujinx.UI/UI/MiscPage.glade b/Ryujinx.UI/UI/MiscPage.glade new file mode 100644 index 000000000..2c048f05a --- /dev/null +++ b/Ryujinx.UI/UI/MiscPage.glade @@ -0,0 +1,50 @@ + + + + + + True + True + + + + + + True + False + page 1 + + + False + + + + + + + + True + False + page 2 + + + 1 + False + + + + + + + + True + False + page 3 + + + 2 + False + + + + diff --git a/Ryujinx.UI/UI/style.css b/Ryujinx.UI/UI/style.css new file mode 100644 index 000000000..fef8f8c67 --- /dev/null +++ b/Ryujinx.UI/UI/style.css @@ -0,0 +1,5 @@ +* +{ + background-color:black; + color:blue; +} \ No newline at end of file diff --git a/Ryujinx.UI/ryujinxicon.png b/Ryujinx.UI/ryujinxicon.png new file mode 100644 index 000000000..33b46db75 Binary files /dev/null and b/Ryujinx.UI/ryujinxicon.png differ diff --git a/Ryujinx.sln b/Ryujinx.sln index 036421f90..dafba2a15 100644 --- a/Ryujinx.sln +++ b/Ryujinx.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26730.8 +VisualStudioVersion = 15.0.27130.2036 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx", "Ryujinx\Ryujinx.csproj", "{074045D4-3ED2-4711-9169-E385F2BFB5A0}" EndProject @@ -15,6 +15,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics", "Ryujinx EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio", "Ryujinx.Audio\Ryujinx.Audio.csproj", "{5C1D818E-682A-46A5-9D54-30006E26C270}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.UI", "Ryujinx.UI\Ryujinx.UI.csproj", "{367E79AF-9A28-4E34-8589-A0F2CF32E2BF}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -45,6 +47,10 @@ Global {5C1D818E-682A-46A5-9D54-30006E26C270}.Debug|Any CPU.Build.0 = Debug|Any CPU {5C1D818E-682A-46A5-9D54-30006E26C270}.Release|Any CPU.ActiveCfg = Release|Any CPU {5C1D818E-682A-46A5-9D54-30006E26C270}.Release|Any CPU.Build.0 = Release|Any CPU + {367E79AF-9A28-4E34-8589-A0F2CF32E2BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {367E79AF-9A28-4E34-8589-A0F2CF32E2BF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {367E79AF-9A28-4E34-8589-A0F2CF32E2BF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {367E79AF-9A28-4E34-8589-A0F2CF32E2BF}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Ryujinx/Config.cs b/Ryujinx/Config.cs index 86b74c966..00aeac4ce 100644 --- a/Ryujinx/Config.cs +++ b/Ryujinx/Config.cs @@ -22,11 +22,11 @@ namespace Ryujinx AOptimizations.DisableMemoryChecks = !Convert.ToBoolean(Parser.Value("Enable_Memory_Checks")); - Log.SetEnable(LogLevel.Debug, Convert.ToBoolean(Parser.Value("Logging_Enable_Debug"))); - Log.SetEnable(LogLevel.Stub, Convert.ToBoolean(Parser.Value("Logging_Enable_Stub"))); - Log.SetEnable(LogLevel.Info, Convert.ToBoolean(Parser.Value("Logging_Enable_Info"))); + Log.SetEnable(LogLevel.Debug, Convert.ToBoolean(Parser.Value("Logging_Enable_Debug"))); + Log.SetEnable(LogLevel.Stub, Convert.ToBoolean(Parser.Value("Logging_Enable_Stub"))); + Log.SetEnable(LogLevel.Info, Convert.ToBoolean(Parser.Value("Logging_Enable_Info"))); Log.SetEnable(LogLevel.Warning, Convert.ToBoolean(Parser.Value("Logging_Enable_Warn"))); - Log.SetEnable(LogLevel.Error, Convert.ToBoolean(Parser.Value("Logging_Enable_Error"))); + Log.SetEnable(LogLevel.Error, Convert.ToBoolean(Parser.Value("Logging_Enable_Error"))); string[] FilteredLogClasses = Parser.Value("Logging_Filtered_Classes").Split(',', StringSplitOptions.RemoveEmptyEntries); @@ -60,34 +60,34 @@ namespace Ryujinx { Left = new JoyConLeft { - StickUp = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_Stick_Up")), - StickDown = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_Stick_Down")), - StickLeft = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_Stick_Left")), - StickRight = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_Stick_Right")), + StickUp = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_Stick_Up")), + StickDown = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_Stick_Down")), + StickLeft = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_Stick_Left")), + StickRight = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_Stick_Right")), StickButton = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_Stick_Button")), - DPadUp = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_DPad_Up")), - DPadDown = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_DPad_Down")), - DPadLeft = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_DPad_Left")), - DPadRight = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_DPad_Right")), + DPadUp = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_DPad_Up")), + DPadDown = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_DPad_Down")), + DPadLeft = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_DPad_Left")), + DPadRight = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_DPad_Right")), ButtonMinus = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_Button_Minus")), - ButtonL = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_Button_L")), - ButtonZL = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_Button_ZL")) + ButtonL = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_Button_L")), + ButtonZL = Convert.ToInt16(Parser.Value("Controls_Left_FakeJoycon_Button_ZL")) }, Right = new JoyConRight { - StickUp = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Stick_Up")), - StickDown = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Stick_Down")), - StickLeft = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Stick_Left")), - StickRight = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Stick_Right")), + StickUp = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Stick_Up")), + StickDown = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Stick_Down")), + StickLeft = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Stick_Left")), + StickRight = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Stick_Right")), StickButton = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Stick_Button")), - ButtonA = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Button_A")), - ButtonB = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Button_B")), - ButtonX = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Button_X")), - ButtonY = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Button_Y")), - ButtonPlus = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Button_Plus")), - ButtonR = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Button_R")), - ButtonZR = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Button_ZR")) + ButtonA = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Button_A")), + ButtonB = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Button_B")), + ButtonX = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Button_X")), + ButtonY = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Button_Y")), + ButtonPlus = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Button_Plus")), + ButtonR = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Button_R")), + ButtonZR = Convert.ToInt16(Parser.Value("Controls_Right_FakeJoycon_Button_ZR")) } }; } diff --git a/Ryujinx/Ui/GLScreen.cs b/Ryujinx/Ui/GLScreen.cs index 6b6ae6a01..12b5c18b0 100644 --- a/Ryujinx/Ui/GLScreen.cs +++ b/Ryujinx/Ui/GLScreen.cs @@ -10,10 +10,10 @@ namespace Ryujinx { public class GLScreen : GameWindow { - private const int TouchScreenWidth = 1280; + private const int TouchScreenWidth = 1280; private const int TouchScreenHeight = 720; - private const float TouchScreenRatioX = (float)TouchScreenWidth / TouchScreenHeight; + private const float TouchScreenRatioX = (float)TouchScreenWidth / TouchScreenHeight; private const float TouchScreenRatioY = (float)TouchScreenHeight / TouchScreenWidth; private Switch Ns; @@ -26,11 +26,11 @@ namespace Ryujinx DisplayDevice.Default, 3, 3, GraphicsContextFlags.ForwardCompatible) { - this.Ns = Ns; + this.Ns = Ns; this.Renderer = Renderer; Location = new Point( - (DisplayDevice.Default.Width / 2) - (Width / 2), + (DisplayDevice.Default.Width / 2) - (Width / 2), (DisplayDevice.Default.Height / 2) - (Height / 2)); } @@ -55,36 +55,36 @@ namespace Ryujinx int RightJoystickDY = 0; //RightJoystick - if (Keyboard[(Key)Config.FakeJoyCon.Left.StickUp]) LeftJoystickDY = short.MaxValue; - if (Keyboard[(Key)Config.FakeJoyCon.Left.StickDown]) LeftJoystickDY = -short.MaxValue; - if (Keyboard[(Key)Config.FakeJoyCon.Left.StickLeft]) LeftJoystickDX = -short.MaxValue; + if (Keyboard[(Key)Config.FakeJoyCon.Left.StickUp]) LeftJoystickDY = short.MaxValue; + if (Keyboard[(Key)Config.FakeJoyCon.Left.StickDown]) LeftJoystickDY = -short.MaxValue; + if (Keyboard[(Key)Config.FakeJoyCon.Left.StickLeft]) LeftJoystickDX = -short.MaxValue; if (Keyboard[(Key)Config.FakeJoyCon.Left.StickRight]) LeftJoystickDX = short.MaxValue; //LeftButtons if (Keyboard[(Key)Config.FakeJoyCon.Left.StickButton]) CurrentButton |= HidControllerButtons.KEY_LSTICK; - if (Keyboard[(Key)Config.FakeJoyCon.Left.DPadUp]) CurrentButton |= HidControllerButtons.KEY_DUP; - if (Keyboard[(Key)Config.FakeJoyCon.Left.DPadDown]) CurrentButton |= HidControllerButtons.KEY_DDOWN; - if (Keyboard[(Key)Config.FakeJoyCon.Left.DPadLeft]) CurrentButton |= HidControllerButtons.KEY_DLEFT; - if (Keyboard[(Key)Config.FakeJoyCon.Left.DPadRight]) CurrentButton |= HidControllerButtons.KEY_DRIGHT; + if (Keyboard[(Key)Config.FakeJoyCon.Left.DPadUp]) CurrentButton |= HidControllerButtons.KEY_DUP; + if (Keyboard[(Key)Config.FakeJoyCon.Left.DPadDown]) CurrentButton |= HidControllerButtons.KEY_DDOWN; + if (Keyboard[(Key)Config.FakeJoyCon.Left.DPadLeft]) CurrentButton |= HidControllerButtons.KEY_DLEFT; + if (Keyboard[(Key)Config.FakeJoyCon.Left.DPadRight]) CurrentButton |= HidControllerButtons.KEY_DRIGHT; if (Keyboard[(Key)Config.FakeJoyCon.Left.ButtonMinus]) CurrentButton |= HidControllerButtons.KEY_MINUS; - if (Keyboard[(Key)Config.FakeJoyCon.Left.ButtonL]) CurrentButton |= HidControllerButtons.KEY_L; - if (Keyboard[(Key)Config.FakeJoyCon.Left.ButtonZL]) CurrentButton |= HidControllerButtons.KEY_ZL; + if (Keyboard[(Key)Config.FakeJoyCon.Left.ButtonL]) CurrentButton |= HidControllerButtons.KEY_L; + if (Keyboard[(Key)Config.FakeJoyCon.Left.ButtonZL]) CurrentButton |= HidControllerButtons.KEY_ZL; //RightJoystick - if (Keyboard[(Key)Config.FakeJoyCon.Right.StickUp]) RightJoystickDY = short.MaxValue; - if (Keyboard[(Key)Config.FakeJoyCon.Right.StickDown]) RightJoystickDY = -short.MaxValue; - if (Keyboard[(Key)Config.FakeJoyCon.Right.StickLeft]) RightJoystickDX = -short.MaxValue; + if (Keyboard[(Key)Config.FakeJoyCon.Right.StickUp]) RightJoystickDY = short.MaxValue; + if (Keyboard[(Key)Config.FakeJoyCon.Right.StickDown]) RightJoystickDY = -short.MaxValue; + if (Keyboard[(Key)Config.FakeJoyCon.Right.StickLeft]) RightJoystickDX = -short.MaxValue; if (Keyboard[(Key)Config.FakeJoyCon.Right.StickRight]) RightJoystickDX = short.MaxValue; //RightButtons if (Keyboard[(Key)Config.FakeJoyCon.Right.StickButton]) CurrentButton |= HidControllerButtons.KEY_RSTICK; - if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonA]) CurrentButton |= HidControllerButtons.KEY_A; - if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonB]) CurrentButton |= HidControllerButtons.KEY_B; - if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonX]) CurrentButton |= HidControllerButtons.KEY_X; - if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonY]) CurrentButton |= HidControllerButtons.KEY_Y; - if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonPlus]) CurrentButton |= HidControllerButtons.KEY_PLUS; - if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonR]) CurrentButton |= HidControllerButtons.KEY_R; - if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonZR]) CurrentButton |= HidControllerButtons.KEY_ZR; + if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonA]) CurrentButton |= HidControllerButtons.KEY_A; + if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonB]) CurrentButton |= HidControllerButtons.KEY_B; + if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonX]) CurrentButton |= HidControllerButtons.KEY_X; + if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonY]) CurrentButton |= HidControllerButtons.KEY_Y; + if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonPlus]) CurrentButton |= HidControllerButtons.KEY_PLUS; + if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonR]) CurrentButton |= HidControllerButtons.KEY_R; + if (Keyboard[(Key)Config.FakeJoyCon.Right.ButtonZR]) CurrentButton |= HidControllerButtons.KEY_ZR; LeftJoystick = new HidJoystickPosition { @@ -104,7 +104,7 @@ namespace Ryujinx //OpenTK always captures mouse events, even if out of focus, so check if window is focused. if (Focused && Mouse?.GetState().LeftButton == ButtonState.Pressed) { - int ScrnWidth = Width; + int ScrnWidth = Width; int ScrnHeight = Height; if (Width > Height * TouchScreenRatioX) @@ -116,7 +116,7 @@ namespace Ryujinx ScrnHeight = (int)(Width * TouchScreenRatioY); } - int StartX = (Width - ScrnWidth) >> 1; + int StartX = (Width - ScrnWidth) >> 1; int StartY = (Height - ScrnHeight) >> 1; int EndX = StartX + ScrnWidth; @@ -124,13 +124,13 @@ namespace Ryujinx if (Mouse.X >= StartX && Mouse.Y >= StartY && - Mouse.X < EndX && - Mouse.Y < EndY) + Mouse.X < EndX && + Mouse.Y < EndY) { int ScrnMouseX = Mouse.X - StartX; int ScrnMouseY = Mouse.Y - StartY; - int MX = (int)(((float)ScrnMouseX / ScrnWidth) * TouchScreenWidth); + int MX = (int)(((float)ScrnMouseX / ScrnWidth) * TouchScreenWidth); int MY = (int)(((float)ScrnMouseY / ScrnHeight) * TouchScreenHeight); HidTouchPoint CurrentPoint = new HidTouchPoint @@ -141,7 +141,7 @@ namespace Ryujinx //Placeholder values till more data is acquired DiameterX = 10, DiameterY = 10, - Angle = 90 + Angle = 90 }; HasTouch = true;