From e579f4a94e6c89f2a16eba619dfd503e4d4606e6 Mon Sep 17 00:00:00 2001 From: David Khachaturov Date: Thu, 2 Apr 2020 10:23:48 +0100 Subject: [PATCH] - Added option to use gyro input as mouse - Changed default of UseHIDG to false - Improved start-up and shut-down time - Added option to disable motion server --- BetterJoyForCemu/App.config | 16 ++++++++++--- BetterJoyForCemu/Joycon.cs | 45 ++++++++++++++++++++++++++++++++++- BetterJoyForCemu/Program.cs | 20 +++++++--------- BetterJoyForCemu/UpdServer.cs | 9 +++++-- 4 files changed, 72 insertions(+), 18 deletions(-) diff --git a/BetterJoyForCemu/App.config b/BetterJoyForCemu/App.config index d21effa..1b7b8d9 100644 --- a/BetterJoyForCemu/App.config +++ b/BetterJoyForCemu/App.config @@ -10,6 +10,8 @@ + + @@ -34,8 +36,8 @@ - - + + @@ -45,11 +47,19 @@ - + + + + + + + + + \ No newline at end of file diff --git a/BetterJoyForCemu/Joycon.cs b/BetterJoyForCemu/Joycon.cs index 36bd04c..6f2037a 100644 --- a/BetterJoyForCemu/Joycon.cs +++ b/BetterJoyForCemu/Joycon.cs @@ -11,8 +11,28 @@ using System.Threading.Tasks; using Nefarius.ViGEm.Client; using Nefarius.ViGEm.Client.Targets; using Nefarius.ViGEm.Client.Targets.Xbox360; +using System.Runtime.InteropServices; +using System.Windows.Forms; namespace BetterJoyForCemu { + // For mouse movement + public class Win32 { + [DllImport("User32.Dll")] + public static extern long SetCursorPos(int x, int y); + + [DllImport("User32.dll")] + public static extern bool GetCursorPos(out POINT lpPoint); + + [DllImport("User32.Dll")] + public static extern bool ClientToScreen(IntPtr hWnd, ref POINT point); + + [StructLayout(LayoutKind.Sequential)] + public struct POINT { + public int x; + public int y; + } + } + public class Joycon { float timing = 120.0f; @@ -445,6 +465,9 @@ namespace BetterJoyForCemu { state = state_.NOT_ATTACHED; } + string extraGyroFeature = ConfigurationManager.AppSettings["GyroToJoyOrMouse"]; + int GyroMouseSensitivity = Int32.Parse(ConfigurationManager.AppSettings["GyroMouseSensitivity"]); + // TODO: Improve this loop, make USB not laggy private byte ts_en; private int ReceiveRaw() { if (handle == IntPtr.Zero) return -2; @@ -476,6 +499,25 @@ namespace BetterJoyForCemu { xin.SendReport(report); } + if (extraGyroFeature == "joy") { + // TODO + } else if (extraGyroFeature == "mouse") { + Win32.POINT p; + Win32.GetCursorPos(out p); + + float dt = 0.015f; // 15ms + + // gyro data is in degrees/s + int dx = (int)(GyroMouseSensitivity * (gyr_g.Z * dt) * (Math.Abs(gyr_g.Z) < 1 ? 0 : 1)); + int dy = (int)-(GyroMouseSensitivity * (gyr_g.Y * dt) * (Math.Abs(gyr_g.Y) < 1 ? 0 : 1)); + + Win32.SetCursorPos(p.x + dx, p.y + dy); + + // reset mouse position to centre of primary monitor + if (buttons[(int) Button.STICK] || buttons[(int) Button.STICK2]) + Win32.SetCursorPos(Screen.PrimaryScreen.Bounds.Width / 2, Screen.PrimaryScreen.Bounds.Height / 2); + } + if (ts_en == raw_buf[1] && !isSnes) { form.AppendTextBox("Duplicate timestamp enqueued.\r\n"); DebugPrint(string.Format("Duplicate timestamp enqueued. TS: {0:X2}", ts_en), DebugType.THREADING); @@ -486,6 +528,7 @@ namespace BetterJoyForCemu { return ret; } + // TODO: Fix? private Thread PollThreadObj; // pro times out over time randomly if it was USB and then bluetooth?? private void Poll() { int attempts = 0; @@ -709,6 +752,7 @@ namespace BetterJoyForCemu { return 0; } + // Get Gyro/Accel data private void ExtractIMUValues(byte[] report_buf, int n = 0) { if (!isSnes) { gyr_r[0] = (Int16)(report_buf[19 + n * 12] | ((report_buf[20 + n * 12] << 8) & 0xff00)); @@ -718,7 +762,6 @@ namespace BetterJoyForCemu { acc_r[1] = (Int16)(report_buf[15 + n * 12] | ((report_buf[16 + n * 12] << 8) & 0xff00)); acc_r[2] = (Int16)(report_buf[17 + n * 12] | ((report_buf[18 + n * 12] << 8) & 0xff00)); - if (form.nonOriginal) { for (int i = 0; i < 3; ++i) { switch (i) { diff --git a/BetterJoyForCemu/Program.cs b/BetterJoyForCemu/Program.cs index b6be75e..3558899 100644 --- a/BetterJoyForCemu/Program.cs +++ b/BetterJoyForCemu/Program.cs @@ -53,7 +53,7 @@ namespace BetterJoyForCemu { } public void Start() { - controllerCheck = new System.Timers.Timer(2000); // check every 2 seconds + controllerCheck = new System.Timers.Timer(5000); // check for new controllers every 5 seconds controllerCheck.Elapsed += CheckForNewControllersTime; controllerCheck.Start(); } @@ -159,10 +159,6 @@ namespace BetterJoyForCemu { } catch { form.AppendTextBox("Unable to add controller to block-list.\r\n"); } - } else { // Remove affected devices from list - try { - HttpWebResponse r1 = (HttpWebResponse)WebRequest.Create(@"http://localhost:26762/api/v1/hidguardian/affected/purge/").GetResponse(); - } catch { } } // -------------------- // @@ -426,13 +422,15 @@ namespace BetterJoyForCemu { } public static void Stop() { - try { - HttpWebResponse response = (HttpWebResponse)WebRequest.Create(@"http://localhost:26762/api/v1/hidguardian/whitelist/remove/" + pid).GetResponse(); - } catch (Exception e) { - form.console.Text += "Unable to remove program from whitelist.\r\n"; + if (Program.useHIDG) { + try { + HttpWebResponse response = (HttpWebResponse)WebRequest.Create(@"http://localhost:26762/api/v1/hidguardian/whitelist/remove/" + pid).GetResponse(); + } catch (Exception e) { + form.console.Text += "Unable to remove program from whitelist.\r\n"; + } } - if (Boolean.Parse(ConfigurationManager.AppSettings["PurgeAffectedDevices"])) { + if (Boolean.Parse(ConfigurationManager.AppSettings["PurgeAffectedDevices"]) && Program.useHIDG) { try { HttpWebResponse r1 = (HttpWebResponse)WebRequest.Create(@"http://localhost:26762/api/v1/hidguardian/affected/purge/").GetResponse(); } catch { } @@ -441,8 +439,6 @@ namespace BetterJoyForCemu { server.Stop(); timer.Stop(); mgr.OnApplicationQuit(); - - form.console.Text += ""; } static void Main(string[] args) { diff --git a/BetterJoyForCemu/UpdServer.cs b/BetterJoyForCemu/UpdServer.cs index 7a66c20..11383f9 100644 --- a/BetterJoyForCemu/UpdServer.cs +++ b/BetterJoyForCemu/UpdServer.cs @@ -282,6 +282,11 @@ namespace BetterJoyForCemu { } public void Start(IPAddress ip, int port = 26760) { + if (!Boolean.Parse(ConfigurationManager.AppSettings["MotionServer"])) { + form.console.AppendText("Motion server is OFF.\r\n"); + return; + } + if (running) { if (udpSock != null) { udpSock.Close(); @@ -295,7 +300,7 @@ namespace BetterJoyForCemu { udpSock.Close(); udpSock = null; - form.console.Text += "Could not start server. Make sure that only one instance of the program is running at a time and no other CemuHook applications are running.\r\n"; + form.console.AppendText("Could not start server. Make sure that only one instance of the program is running at a time and no other CemuHook applications are running.\r\n"); return; } @@ -304,7 +309,7 @@ namespace BetterJoyForCemu { serverId = BitConverter.ToUInt32(randomBuf, 0); running = true; - form.console.Text += String.Format("Starting server on {0}:{1}\r\n", ip.ToString(), port); + form.console.AppendText(String.Format("Starting server on {0}:{1}\r\n", ip.ToString(), port)); StartReceive(); }