Add a mappable shake input

- mappable "shake" input

Co-authored-by: Shuken <shukenmg@iuvenisstudios.ga>
This commit is contained in:
shukenmg 2020-09-22 21:47:26 +08:00 committed by GitHub
parent 43786c12d9
commit 36346c1896
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 322 additions and 236 deletions

View file

@ -25,6 +25,16 @@
<!--On is "true"; off is "false". Default: true -->
<add key="EnableRumble" value="true" />
<!--Enables a input when shaking a controller, only works with DS4 for now, replaces the touchpad input (Button 13 on DirectInput)-->
<!--On is "true"; off is "false". Default: false -->
<add key="EnableShakeInput" value="false" />
<!--How sensitve the shake detection should be. Default: 10-->
<add key="ShakeInputSensitivity" value="10" />
<!--How often should the shake input run in milliseconds. -->
<!--Don't set this lower than 15 -->
<!-- Default: 200 -->
<add key="ShakeInputDelay" value="200" />
<!--Swap A-B buttons; if on, this mimicks the (half of) Xbox layout by the button name, rather than by the physical layout.-->
<!--Also swaps buttons when using "Also use for buttons/axes"-->
<!--On is "true"; off is "false". Default: false -->

View file

@ -7,7 +7,7 @@ namespace BetterJoyForCemu {
const string PATH = "settings";
static Dictionary<string, string> variables = new Dictionary<string, string>();
const int settingsNum = 10; // currently - ProgressiveScan, StartInTray + special buttons
const int settingsNum = 11; // currently - ProgressiveScan, StartInTray + special buttons
public static string GetDefaultValue(string s) {
switch (s) {
@ -21,15 +21,36 @@ namespace BetterJoyForCemu {
return "0";
}
// Helper function to count how many lines are in a file
// https://www.dotnetperls.com/line-count
static long CountLinesInFile(string f) {
// Zero based count
long count = -1;
using (StreamReader r = new StreamReader(f)) {
string line;
while ((line = r.ReadLine()) != null) {
count++;
}
}
return count;
}
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", "active_gyro" })
foreach (string s in new string[] { "ProgressiveScan", "StartInTray", "capture", "home", "sl_l", "sl_r", "sr_l", "sr_r", "shake", "reset_mouse", "active_gyro" })
variables[s] = GetDefaultValue(s);
if (File.Exists(PATH)) {
int lineNO = 0;
// Reset settings file if old settings
if (CountLinesInFile(PATH) < settingsNum) {
File.Delete(PATH);
Init(caliData);
return;
}
using (StreamReader file = new StreamReader(PATH)) {
string line = String.Empty;
int lineNO = 0;
while ((line = file.ReadLine()) != null) {
string[] vs = line.Split();
try {
@ -52,14 +73,6 @@ namespace BetterJoyForCemu {
} catch { }
lineNO++;
}
}
// if old settings
if (lineNO < settingsNum) {
File.Delete(PATH);
Init(caliData);
}
} else {
using (StreamWriter file = new StreamWriter(PATH)) {

View file

@ -31,6 +31,7 @@ namespace BetterJoyForCemu {
THREADING,
IMU,
RUMBLE,
SHAKE,
};
public DebugType debug_type = DebugType.NONE;
public bool isLeft;
@ -574,6 +575,38 @@ namespace BetterJoyForCemu {
return ret;
}
private readonly Stopwatch shakeTimer = Stopwatch.StartNew(); //Setup a timer for measuring shake in milliseconds
private long shakedTime = 0;
private bool hasShaked;
void DetectShake() {
if (form.shakeInputEnabled) {
long currentShakeTime = shakeTimer.ElapsedMilliseconds;
// Shake detection logic
bool isShaking = GetAccel().LengthSquared() >= form.shakeSesitivity;
if (isShaking && currentShakeTime >= shakedTime + form.shakeDelay || isShaking && shakedTime == 0) {
shakedTime = currentShakeTime;
hasShaked = true;
// Mapped shake key down
Simulate(Config.Value("shake"), false, false);
DebugPrint("Shaked at time: " + shakedTime.ToString(), DebugType.SHAKE);
}
// If controller was shaked then release mapped key after a small delay to simulate a button press, then reset hasShaked
if (hasShaked && currentShakeTime >= shakedTime + 10) {
// Mapped shake key up
Simulate(Config.Value("shake"), false, true);
DebugPrint("Shake completed", DebugType.SHAKE);
hasShaked = false;
}
} else {
shakeTimer.Stop();
return;
}
}
bool dragToggle = Boolean.Parse(ConfigurationManager.AppSettings["DragToggle"]);
Dictionary<int, bool> mouse_toggle_btn = new Dictionary<int, bool>();
private void Simulate(string s, bool click = true, bool up = false) {
@ -655,6 +688,8 @@ namespace BetterJoyForCemu {
}
}
DetectShake();
if (buttons_down[(int)Button.CAPTURE])
Simulate(Config.Value("capture"));
if (buttons_down[(int)Button.HOME])

View file

@ -22,6 +22,9 @@ namespace BetterJoyForCemu {
private Timer countDown;
private int count;
public List<int> xG, yG, zG, xA, yA, zA;
public bool shakeInputEnabled = Boolean.Parse(ConfigurationManager.AppSettings["EnableShakeInput"]);
public float shakeSesitivity = float.Parse(ConfigurationManager.AppSettings["ShakeInputSensitivity"]);
public float shakeDelay = float.Parse(ConfigurationManager.AppSettings["ShakeInputDelay"]);
public MainForm() {
xG = new List<int>(); yG = new List<int>(); zG = new List<int>();

View file

@ -93,13 +93,15 @@ namespace BetterJoyForCemu {
this.btn_sl_r = new BetterJoyForCemu.SplitButton();
this.lbl_sr_r = new System.Windows.Forms.Label();
this.btn_sr_r = new BetterJoyForCemu.SplitButton();
this.btn_close = new Button();
this.btn_apply = new Button();
this.btn_close = new System.Windows.Forms.Button();
this.btn_apply = new System.Windows.Forms.Button();
this.tip_reassign = new System.Windows.Forms.ToolTip(this.components);
this.lbl_reset_mouse = new System.Windows.Forms.Label();
this.btn_reset_mouse = new BetterJoyForCemu.SplitButton();
this.lbl_activate_gyro = new System.Windows.Forms.Label();
this.btn_active_gyro = new SplitButton();
this.btn_active_gyro = new BetterJoyForCemu.SplitButton();
this.lbl_shake = new System.Windows.Forms.Label();
this.btn_shake = new BetterJoyForCemu.SplitButton();
this.SuspendLayout();
//
// btn_capture
@ -212,7 +214,7 @@ namespace BetterJoyForCemu {
//
// btn_close
//
this.btn_close.Location = new System.Drawing.Point(15, 257);
this.btn_close.Location = new System.Drawing.Point(15, 289);
this.btn_close.Name = "btn_close";
this.btn_close.Size = new System.Drawing.Size(75, 23);
this.btn_close.TabIndex = 13;
@ -222,7 +224,7 @@ namespace BetterJoyForCemu {
//
// btn_apply
//
this.btn_apply.Location = new System.Drawing.Point(105, 257);
this.btn_apply.Location = new System.Drawing.Point(105, 289);
this.btn_apply.Name = "btn_apply";
this.btn_apply.Size = new System.Drawing.Size(75, 23);
this.btn_apply.TabIndex = 14;
@ -233,7 +235,7 @@ namespace BetterJoyForCemu {
// lbl_reset_mouse
//
this.lbl_reset_mouse.AutoSize = true;
this.lbl_reset_mouse.Location = new System.Drawing.Point(15, 191);
this.lbl_reset_mouse.Location = new System.Drawing.Point(15, 223);
this.lbl_reset_mouse.Name = "lbl_reset_mouse";
this.lbl_reset_mouse.Size = new System.Drawing.Size(80, 13);
this.lbl_reset_mouse.TabIndex = 16;
@ -242,7 +244,7 @@ namespace BetterJoyForCemu {
//
// btn_reset_mouse
//
this.btn_reset_mouse.Location = new System.Drawing.Point(105, 186);
this.btn_reset_mouse.Location = new System.Drawing.Point(105, 218);
this.btn_reset_mouse.Name = "btn_reset_mouse";
this.btn_reset_mouse.Size = new System.Drawing.Size(75, 23);
this.btn_reset_mouse.TabIndex = 15;
@ -251,7 +253,7 @@ namespace BetterJoyForCemu {
// lbl_activate_gyro
//
this.lbl_activate_gyro.AutoSize = true;
this.lbl_activate_gyro.Location = new System.Drawing.Point(14, 220);
this.lbl_activate_gyro.Location = new System.Drawing.Point(14, 252);
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;
@ -260,17 +262,37 @@ namespace BetterJoyForCemu {
//
// btn_active_gyro
//
this.btn_active_gyro.Location = new System.Drawing.Point(105, 215);
this.btn_active_gyro.Location = new System.Drawing.Point(105, 247);
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;
//
// label1
//
this.lbl_shake.AutoSize = true;
this.lbl_shake.Location = new System.Drawing.Point(15, 191);
this.lbl_shake.Name = "lbl_shake";
this.lbl_shake.Size = new System.Drawing.Size(87, 13);
this.lbl_shake.TabIndex = 20;
this.lbl_shake.Text = "Shake Input";
this.lbl_shake.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// splitButton1
//
this.btn_shake.Location = new System.Drawing.Point(105, 186);
this.btn_shake.Name = "btn_shake";
this.btn_shake.Size = new System.Drawing.Size(75, 23);
this.btn_shake.TabIndex = 19;
this.btn_shake.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, 292);
this.ClientSize = new System.Drawing.Size(192, 338);
this.Controls.Add(this.lbl_shake);
this.Controls.Add(this.btn_shake);
this.Controls.Add(this.btn_active_gyro);
this.Controls.Add(this.lbl_activate_gyro);
this.Controls.Add(this.lbl_reset_mouse);
@ -323,5 +345,7 @@ namespace BetterJoyForCemu {
private SplitButton btn_reset_mouse;
private Label lbl_activate_gyro;
private SplitButton btn_active_gyro;
private Label lbl_shake;
private SplitButton btn_shake;
}
}

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, btn_active_gyro }) {
foreach (SplitButton c in new SplitButton[] { btn_capture, btn_home, btn_sl_l, btn_sl_r, btn_sr_l, btn_sr_r, btn_shake, btn_reset_mouse, btn_active_gyro }) {
c.Tag = c.Name.Substring(4);
GetPrettyName(c);

View file

@ -25,6 +25,7 @@ Go to the [Releases tab](https://github.com/Davidobot/BetterJoy/releases/)!
1. Read the READMEs (they're there for a reason!)
1. Run *Drivers/ViGEmBus_Setup_1.16.116.exe*
2. Run *BetterJoyForCemu.exe*
1. Run as Administrator if your keyboard/mouse button mappings don't work
3. Connect your controllers.
4. Start Cemu and ensure CemuHook has the controller selected.
1. If using Joycons, CemuHook will detect two controllers - each will give all buttons, but choosing one over the other just chooses preference for which hand to use for gyro controls.