- Added added ability to drag when mapping left/right/mouse buttons

- Catching VigemBusNotFound exception
 - Added ability to set button for re-centering the gyro
This commit is contained in:
David Khachaturov 2020-04-07 14:52:04 +01:00
parent 12062d7a27
commit d8352d9b34
6 changed files with 124 additions and 39 deletions

View file

@ -190,7 +190,7 @@
<None Include="Properties\app.manifest" />
<Content Include="Icons\betterjoyforcemu_icon.ico" />
<Content Include="hidapi.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Icons\cross.png" />
<Content Include="Icons\jc_left_s.png" />

View file

@ -25,7 +25,7 @@ namespace BetterJoyForCemu {
}
public static void Init(List<KeyValuePair<string, float[]>> 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)) {

View file

@ -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();
}
}

View file

@ -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<WindowsInput.Events.Sources.MouseEvent> 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<WindowsInput.Events.Sources.KeyboardEvent> 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();

View file

@ -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;
}
}

View file

@ -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;
}
}