diff --git a/BetterJoyForCemu/BetterJoyForCemu.csproj b/BetterJoyForCemu/BetterJoyForCemu.csproj
index dd50a6a..c41e23a 100644
--- a/BetterJoyForCemu/BetterJoyForCemu.csproj
+++ b/BetterJoyForCemu/BetterJoyForCemu.csproj
@@ -190,7 +190,7 @@
- PreserveNewest
+ Always
diff --git a/BetterJoyForCemu/Config.cs b/BetterJoyForCemu/Config.cs
index 9ebe2e8..ecf962e 100644
--- a/BetterJoyForCemu/Config.cs
+++ b/BetterJoyForCemu/Config.cs
@@ -25,7 +25,7 @@ namespace BetterJoyForCemu {
}
public static void Init(List> caliData) {
- foreach (string s in new string[] { "ProgressiveScan", "StartInTray", "capture", "home", "sl_l", "sl_r", "sr_l", "sr_r", "reset_mouse" })
+ foreach (string s in new string[] { "ProgressiveScan", "StartInTray", "capture", "home", "sl_l", "sl_r", "sr_l", "sr_r", "reset_mouse", "active_gyro" })
variables[s] = GetDefaultValue(s);
if (File.Exists(PATH)) {
diff --git a/BetterJoyForCemu/Joycon.cs b/BetterJoyForCemu/Joycon.cs
index fc64621..e15be2f 100644
--- a/BetterJoyForCemu/Joycon.cs
+++ b/BetterJoyForCemu/Joycon.cs
@@ -518,11 +518,28 @@ namespace BetterJoyForCemu {
return ret;
}
- private void Simulate(string s) {
- if (s.StartsWith("key_"))
- WindowsInput.Simulate.Events().Click((WindowsInput.Events.KeyCode) Int32.Parse(s.Substring(4))).Invoke();
- else if (s.StartsWith("mse_"))
- WindowsInput.Simulate.Events().Click((WindowsInput.Events.ButtonCode) Int32.Parse(s.Substring(4))).Invoke();
+ private void Simulate(string s, bool click=true, bool up=false) {
+ if (s.StartsWith("key_")) {
+ if (click) {
+ WindowsInput.Simulate.Events().Click((WindowsInput.Events.KeyCode)Int32.Parse(s.Substring(4))).Invoke();
+ } else {
+ if (up) {
+ WindowsInput.Simulate.Events().Release((WindowsInput.Events.KeyCode)Int32.Parse(s.Substring(4))).Invoke();
+ } else {
+ WindowsInput.Simulate.Events().Hold((WindowsInput.Events.KeyCode)Int32.Parse(s.Substring(4))).Invoke();
+ }
+ }
+ } else if (s.StartsWith("mse_")) {
+ if (click) {
+ WindowsInput.Simulate.Events().Click((WindowsInput.Events.ButtonCode)Int32.Parse(s.Substring(4))).Invoke();
+ } else {
+ if (up) {
+ WindowsInput.Simulate.Events().Release((WindowsInput.Events.ButtonCode)Int32.Parse(s.Substring(4))).Invoke();
+ } else {
+ WindowsInput.Simulate.Events().Hold((WindowsInput.Events.ButtonCode)Int32.Parse(s.Substring(4))).Invoke();
+ }
+ }
+ }
}
string extraGyroFeature = ConfigurationManager.AppSettings["GyroToJoyOrMouse"];
@@ -533,13 +550,21 @@ namespace BetterJoyForCemu {
if (buttons_down[(int)Button.HOME])
Simulate(Config.Value("home"));
if (isLeft && buttons_down[(int)Button.SL])
- Simulate(Config.Value("sl_l"));
+ Simulate(Config.Value("sl_l"), false, false);
+ if (isLeft && buttons_up[(int)Button.SL])
+ Simulate(Config.Value("sl_l"), false, true);
if (isLeft && buttons_down[(int)Button.SR])
- Simulate(Config.Value("sr_l"));
+ Simulate(Config.Value("sr_l"), false, false);
+ if (isLeft && buttons_up[(int)Button.SR])
+ Simulate(Config.Value("sr_l"), false, true);
if (!isLeft && buttons_down[(int)Button.SL])
- Simulate(Config.Value("sl_r"));
+ Simulate(Config.Value("sl_r"), false, false);
+ if (!isLeft && buttons_up[(int)Button.SL])
+ Simulate(Config.Value("sl_r"), false, true);
if (!isLeft && buttons_down[(int)Button.SR])
- Simulate(Config.Value("sr_r"));
+ Simulate(Config.Value("sr_r"), false, false);
+ if (!isLeft && buttons_up[(int)Button.SR])
+ Simulate(Config.Value("sr_r"), false, true);
if (extraGyroFeature == "joy") {
// TODO
@@ -553,8 +578,10 @@ namespace BetterJoyForCemu {
WindowsInput.Simulate.Events().MoveBy(dx, dy).Invoke();
// reset mouse position to centre of primary monitor
- if (buttons_down[(int)Button.STICK] || buttons_down[(int)Button.STICK2])
- WindowsInput.Simulate.Events().MoveTo(Screen.PrimaryScreen.Bounds.Width / 2, Screen.PrimaryScreen.Bounds.Height / 2).Invoke();
+ string res_val = Config.Value("reset_mouse");
+ if (res_val.StartsWith("joy_"))
+ if (buttons_down[Int32.Parse(res_val.Substring(4))])
+ WindowsInput.Simulate.Events().MoveTo(Screen.PrimaryScreen.Bounds.Width / 2, Screen.PrimaryScreen.Bounds.Height / 2).Invoke();
}
}
diff --git a/BetterJoyForCemu/Program.cs b/BetterJoyForCemu/Program.cs
index ac31281..00b74c0 100644
--- a/BetterJoyForCemu/Program.cs
+++ b/BetterJoyForCemu/Program.cs
@@ -2,9 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
-using System.Threading.Tasks;
-using System.Numerics;
using System.Threading;
using System.Runtime.InteropServices;
using System.Timers;
@@ -14,7 +12,6 @@ using System.Diagnostics;
using static BetterJoyForCemu.HIDapi;
using Nefarius.ViGEm.Client;
-using Nefarius.ViGEm.Client.Targets;
using System.Net;
using System.Configuration;
using System.Net.Http;
@@ -356,6 +353,9 @@ namespace BetterJoyForCemu {
static public bool useHIDG = Boolean.Parse(ConfigurationManager.AppSettings["UseHIDG"]);
+ private static WindowsInput.Events.Sources.IKeyboardEventSource keyboard;
+ private static WindowsInput.Events.Sources.IMouseEventSource mouse;
+
public static void Start() {
pid = Process.GetCurrentProcess().Id.ToString(); // get current process id for HidCerberus.Srv
@@ -363,17 +363,17 @@ namespace BetterJoyForCemu {
try {
var HidCerberusService = new ServiceController("HidCerberus Service");
if (HidCerberusService.Status == ServiceControllerStatus.Stopped) {
- form.console.Text += "HidGuardian was stopped. Starting...\r\n";
+ form.console.AppendText("HidGuardian was stopped. Starting...\r\n");
try {
HidCerberusService.Start();
} catch (Exception e) {
- form.console.Text += "Unable to start HidGuardian - everything should work fine without it, but if you need it, run the app again as an admin.\r\n";
+ form.console.AppendText("Unable to start HidGuardian - everything should work fine without it, but if you need it, run the app again as an admin.\r\n");
useHIDG = false;
}
}
} catch (Exception e) {
- form.console.Text += "Unable to start HidGuardian - everything should work fine without it, but if you need it, install it properly as admin.\r\n";
+ form.console.AppendText("Unable to start HidGuardian - everything should work fine without it, but if you need it, install it properly as admin.\r\n");
useHIDG = false;
}
@@ -382,7 +382,7 @@ namespace BetterJoyForCemu {
try {
response = (HttpWebResponse)WebRequest.Create(@"http://localhost:26762/api/v1/hidguardian/whitelist/purge/").GetResponse(); // remove all programs allowed to see controller
} catch (Exception e) {
- form.console.Text += "Unable to purge whitelist.\r\n";
+ form.console.AppendText("Unable to purge whitelist.\r\n");
useHIDG = false;
}
}
@@ -390,14 +390,20 @@ namespace BetterJoyForCemu {
try {
response = (HttpWebResponse)WebRequest.Create(@"http://localhost:26762/api/v1/hidguardian/whitelist/add/" + pid).GetResponse(); // add BetterJoyForCemu to allowed processes
} catch (Exception e) {
- form.console.Text += "Unable to add program to whitelist.\r\n";
+ form.console.AppendText("Unable to add program to whitelist.\r\n");
useHIDG = false;
}
} else {
- form.console.Text += "HidGuardian is disabled.\r\n";
+ form.console.AppendText("HidGuardian is disabled.\r\n");
}
- emClient = new ViGEmClient(); // Manages emulated XInput
+ if (Boolean.Parse(ConfigurationManager.AppSettings["ShowAsXInput"])) {
+ try {
+ emClient = new ViGEmClient(); // Manages emulated XInput
+ } catch (Nefarius.ViGEm.Client.Exceptions.VigemBusNotFoundException) {
+ form.console.AppendText("Could not start VigemBus. Make sure drivers are installed correctly.\r\n");
+ }
+ }
foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces()) {
// Get local BT host MAC
@@ -421,7 +427,31 @@ namespace BetterJoyForCemu {
timer = new HighResTimer(pollsPerSecond, new HighResTimer.ActionDelegate(mgr.Update));
timer.Start();
- form.console.Text += "All systems go\r\n";
+ // Capture keyboard + mouse events for binding's sake
+ keyboard = WindowsInput.Capture.Global.KeyboardAsync();
+ keyboard.KeyEvent += Keyboard_KeyEvent;
+ mouse = WindowsInput.Capture.Global.MouseAsync();
+ mouse.MouseEvent += Mouse_MouseEvent;
+
+ form.console.AppendText("All systems go\r\n");
+ }
+
+ private static void Mouse_MouseEvent(object sender, WindowsInput.Events.Sources.EventSourceEventArgs e) {
+ if (e.Data.ButtonDown != null) {
+ string res_val = Config.Value("reset_mouse");
+ if (res_val.StartsWith("mse_"))
+ if ((int)e.Data.ButtonDown.Button == Int32.Parse(res_val.Substring(4)))
+ WindowsInput.Simulate.Events().MoveTo(Screen.PrimaryScreen.Bounds.Width / 2, Screen.PrimaryScreen.Bounds.Height / 2).Invoke();
+ }
+ }
+
+ private static void Keyboard_KeyEvent(object sender, WindowsInput.Events.Sources.EventSourceEventArgs e) {
+ if (e.Data.KeyDown != null) {
+ string res_val = Config.Value("reset_mouse");
+ if (res_val.StartsWith("key_"))
+ if ((int)e.Data.KeyDown.Key == Int32.Parse(res_val.Substring(4)))
+ WindowsInput.Simulate.Events().MoveTo(Screen.PrimaryScreen.Bounds.Width / 2, Screen.PrimaryScreen.Bounds.Height / 2).Invoke();
+ }
}
public static void Stop() {
@@ -429,7 +459,7 @@ namespace BetterJoyForCemu {
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";
+ form.console.AppendText("Unable to remove program from whitelist.\r\n");
}
}
@@ -439,6 +469,7 @@ namespace BetterJoyForCemu {
} catch { }
}
+ keyboard.Dispose(); mouse.Dispose();
server.Stop();
timer.Stop();
mgr.OnApplicationQuit();
diff --git a/BetterJoyForCemu/Reassign.Designer.cs b/BetterJoyForCemu/Reassign.Designer.cs
index b76b286..1ac2fc4 100644
--- a/BetterJoyForCemu/Reassign.Designer.cs
+++ b/BetterJoyForCemu/Reassign.Designer.cs
@@ -4,6 +4,7 @@ using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace BetterJoyForCemu {
+ // from https://stackoverflow.com/a/27173509
public class SplitButton : Button {
[DefaultValue(null), Browsable(true),
DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
@@ -47,7 +48,7 @@ namespace BetterJoyForCemu {
int lineX = ClientRectangle.Width - this.SplitWidth;
int lineYFrom = arrowY - 4;
int lineYTo = arrowY + 8;
- using (var separatorPen = new Pen(Brushes.DarkGray) { DashStyle = DashStyle.Dot }) {
+ using (var separatorPen = new Pen(Brushes.DarkGray) { DashStyle = System.Drawing.Drawing2D.DashStyle.Dot }) {
pevent.Graphics.DrawLine(separatorPen, lineX, lineYFrom, lineX, lineYTo);
}
}
@@ -80,23 +81,25 @@ namespace BetterJoyForCemu {
private void InitializeComponent() {
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Reassign));
- this.btn_capture = new SplitButton();
+ this.btn_capture = new BetterJoyForCemu.SplitButton();
this.lbl_capture = new System.Windows.Forms.Label();
this.lbl_home = new System.Windows.Forms.Label();
- this.btn_home = new SplitButton();
+ this.btn_home = new BetterJoyForCemu.SplitButton();
this.lbl_sl_l = new System.Windows.Forms.Label();
- this.btn_sl_l = new SplitButton();
+ this.btn_sl_l = new BetterJoyForCemu.SplitButton();
this.lbl_sr_l = new System.Windows.Forms.Label();
- this.btn_sr_l = new SplitButton();
+ this.btn_sr_l = new BetterJoyForCemu.SplitButton();
this.lbl_sl_r = new System.Windows.Forms.Label();
- this.btn_sl_r = new SplitButton();
+ this.btn_sl_r = new BetterJoyForCemu.SplitButton();
this.lbl_sr_r = new System.Windows.Forms.Label();
- this.btn_sr_r = new SplitButton();
- this.btn_close = new SplitButton();
- this.btn_apply = new SplitButton();
+ this.btn_sr_r = new BetterJoyForCemu.SplitButton();
+ this.btn_close = new BetterJoyForCemu.SplitButton();
+ this.btn_apply = new BetterJoyForCemu.SplitButton();
this.tip_reassign = new System.Windows.Forms.ToolTip(this.components);
this.lbl_reset_mouse = new System.Windows.Forms.Label();
- this.btn_reset_mouse = new SplitButton();
+ this.btn_reset_mouse = new BetterJoyForCemu.SplitButton();
+ this.lbl_activate_gyro = new System.Windows.Forms.Label();
+ this.btn_active_gyro = new SplitButton();
this.SuspendLayout();
//
// btn_capture
@@ -209,7 +212,7 @@ namespace BetterJoyForCemu {
//
// btn_close
//
- this.btn_close.Location = new System.Drawing.Point(15, 231);
+ this.btn_close.Location = new System.Drawing.Point(15, 257);
this.btn_close.Name = "btn_close";
this.btn_close.Size = new System.Drawing.Size(75, 23);
this.btn_close.TabIndex = 13;
@@ -219,7 +222,7 @@ namespace BetterJoyForCemu {
//
// btn_apply
//
- this.btn_apply.Location = new System.Drawing.Point(105, 231);
+ this.btn_apply.Location = new System.Drawing.Point(105, 257);
this.btn_apply.Name = "btn_apply";
this.btn_apply.Size = new System.Drawing.Size(75, 23);
this.btn_apply.TabIndex = 14;
@@ -245,11 +248,31 @@ namespace BetterJoyForCemu {
this.btn_reset_mouse.TabIndex = 15;
this.btn_reset_mouse.UseVisualStyleBackColor = true;
//
+ // lbl_activate_gyro
+ //
+ this.lbl_activate_gyro.AutoSize = true;
+ this.lbl_activate_gyro.Location = new System.Drawing.Point(14, 220);
+ this.lbl_activate_gyro.Name = "lbl_activate_gyro";
+ this.lbl_activate_gyro.Size = new System.Drawing.Size(71, 13);
+ this.lbl_activate_gyro.TabIndex = 17;
+ this.lbl_activate_gyro.Text = "Activate Gyro";
+ this.lbl_activate_gyro.TextAlign = System.Drawing.ContentAlignment.TopCenter;
+ //
+ // btn_active_gyro
+ //
+ this.btn_active_gyro.Location = new System.Drawing.Point(105, 215);
+ this.btn_active_gyro.Name = "btn_active_gyro";
+ this.btn_active_gyro.Size = new System.Drawing.Size(75, 23);
+ this.btn_active_gyro.TabIndex = 18;
+ this.btn_active_gyro.UseVisualStyleBackColor = true;
+ //
// Reassign
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(192, 266);
+ this.ClientSize = new System.Drawing.Size(192, 292);
+ this.Controls.Add(this.btn_active_gyro);
+ this.Controls.Add(this.lbl_activate_gyro);
this.Controls.Add(this.lbl_reset_mouse);
this.Controls.Add(this.btn_reset_mouse);
this.Controls.Add(this.btn_apply);
@@ -298,5 +321,7 @@ namespace BetterJoyForCemu {
private System.Windows.Forms.ToolTip tip_reassign;
private System.Windows.Forms.Label lbl_reset_mouse;
private SplitButton btn_reset_mouse;
+ private Label lbl_activate_gyro;
+ private SplitButton btn_active_gyro;
}
}
\ No newline at end of file
diff --git a/BetterJoyForCemu/Reassign.cs b/BetterJoyForCemu/Reassign.cs
index 7e6de89..122e3d8 100644
--- a/BetterJoyForCemu/Reassign.cs
+++ b/BetterJoyForCemu/Reassign.cs
@@ -29,7 +29,7 @@ namespace BetterJoyForCemu {
menu_joy_buttons.ItemClicked += Menu_joy_buttons_ItemClicked;
- foreach (SplitButton c in new SplitButton[] { btn_capture, btn_home, btn_sl_l, btn_sl_r, btn_sr_l, btn_sr_r, btn_reset_mouse }) {
+ foreach (SplitButton c in new SplitButton[] { btn_capture, btn_home, btn_sl_l, btn_sl_r, btn_sr_l, btn_sr_r, btn_reset_mouse , btn_active_gyro}) {
c.Tag = c.Name.Substring(4);
GetPrettyName(c);
@@ -78,6 +78,7 @@ namespace BetterJoyForCemu {
Config.SetValue((string)curAssignment.Tag, "mse_" + ((int)e.Data.ButtonDown.Button));
AsyncPrettyName(curAssignment);
curAssignment = null;
+ e.Next_Hook_Enabled = false;
}
}
@@ -86,6 +87,7 @@ namespace BetterJoyForCemu {
Config.SetValue((string)curAssignment.Tag, "key_" + ((int)e.Data.KeyDown.Key));
AsyncPrettyName(curAssignment);
curAssignment = null;
+ e.Next_Hook_Enabled = false;
}
}