From bfdea232cd321ad31d034c0ef5874f0e427ced9a Mon Sep 17 00:00:00 2001
From: shukenmg <18000205+shukenmg@users.noreply.github.com>
Date: Tue, 3 Nov 2020 16:19:59 +0800
Subject: [PATCH] Rumble data processing refactor (#591)
* Rumble reimplementation
* Remove white space
* More whitespace
* Remove Update
---
BetterJoyForCemu/App.config | 3 --
BetterJoyForCemu/Joycon.cs | 79 +++++++++++++-----------------------
BetterJoyForCemu/MainForm.cs | 6 ++-
BetterJoyForCemu/Program.cs | 2 +-
4 files changed, 34 insertions(+), 56 deletions(-)
diff --git a/BetterJoyForCemu/App.config b/BetterJoyForCemu/App.config
index aa0ad43..3d483d4 100644
--- a/BetterJoyForCemu/App.config
+++ b/BetterJoyForCemu/App.config
@@ -13,9 +13,6 @@
-
-
-
diff --git a/BetterJoyForCemu/Joycon.cs b/BetterJoyForCemu/Joycon.cs
index 15269ae..90b8fee 100644
--- a/BetterJoyForCemu/Joycon.cs
+++ b/BetterJoyForCemu/Joycon.cs
@@ -123,46 +123,21 @@ namespace BetterJoyForCemu {
private const uint report_len = 49;
private struct Rumble {
- private float h_f, l_f;
- public float amp;
- public bool controller_informed;
- public long end_rumble_time_milliseconds;
+ public Queue queue;
- public void set_vals(float low_freq, float high_freq, float amplitude, int rumble_duration_ms = 0) {
- h_f = high_freq;
- amp = amplitude;
- l_f = low_freq;
- if (rumble_duration_ms != 0) {
- end_rumble_time_milliseconds = DateTimeOffset.Now.ToUnixTimeMilliseconds() + rumble_duration_ms;
- } else {
- end_rumble_time_milliseconds = 0;
- }
-
- controller_informed = false;
+ public void set_vals(float low_freq, float high_freq, float amplitude) {
+ float[] rumbleQueue = new float[] {low_freq, high_freq, amplitude};
+ queue.Enqueue(rumbleQueue);
}
- public Rumble(float low_freq, float high_freq, float amplitude, int rumble_duration_ms = 0) {
- h_f = high_freq;
- amp = amplitude;
- l_f = low_freq;
- if (rumble_duration_ms != 0) {
- end_rumble_time_milliseconds = DateTimeOffset.Now.ToUnixTimeMilliseconds() + rumble_duration_ms;
- } else {
- end_rumble_time_milliseconds = 0;
- }
- controller_informed = false;
+ public Rumble(float[] rumble_info) {
+ queue = new Queue();
+ queue.Enqueue(rumble_info);
}
private float clamp(float x, float min, float max) {
if (x < min) return min;
if (x > max) return max;
return x;
}
- public void Update() {
- if (end_rumble_time_milliseconds != 0 && DateTimeOffset.Now.ToUnixTimeMilliseconds() > end_rumble_time_milliseconds) {
- controller_informed = false;
- end_rumble_time_milliseconds = 0;
- amp = 0;
- }
- }
private byte EncodeAmp(float amp) {
byte en_amp;
@@ -181,21 +156,22 @@ namespace BetterJoyForCemu {
public byte[] GetData() {
byte[] rumble_data = new byte[8];
+ float[] queued_data = queue.Dequeue();
- if (amp == 0.0f) {
+ if (queued_data[2] == 0.0f) {
rumble_data[0] = 0x0;
rumble_data[1] = 0x1;
rumble_data[2] = 0x40;
rumble_data[3] = 0x40;
} else {
- l_f = clamp(l_f, 40.875885f, 626.286133f);
- h_f = clamp(h_f, 81.75177f, 1252.572266f);
+ queued_data[0] = clamp(queued_data[0], 40.875885f, 626.286133f);
+ queued_data[1] = clamp(queued_data[1], 81.75177f, 1252.572266f);
- amp = clamp(amp, 0.0f, 1.0f);
+ queued_data[2] = clamp(queued_data[2], 0.0f, 1.0f);
- UInt16 hf = (UInt16)((Math.Round(32f * Math.Log(h_f * 0.1f, 2)) - 0x60) * 4);
- byte lf = (byte)(Math.Round(32f * Math.Log(l_f * 0.1f, 2)) - 0x40);
- byte hf_amp = EncodeAmp(amp);
+ UInt16 hf = (UInt16)((Math.Round(32f * Math.Log(queued_data[1] * 0.1f, 2)) - 0x60) * 4);
+ byte lf = (byte)(Math.Round(32f * Math.Log(queued_data[0] * 0.1f, 2)) - 0x40);
+ byte hf_amp = EncodeAmp(queued_data[2]);
UInt16 lf_amp = (UInt16)(Math.Round((double)hf_amp) * .5);
byte parity = (byte)(lf_amp % 2);
@@ -243,7 +219,6 @@ namespace BetterJoyForCemu {
ushort ds4_ts = 0;
ulong lag;
- int rumblePeriod = Int32.Parse(ConfigurationManager.AppSettings["RumblePeriod"]);
int lowFreq = Int32.Parse(ConfigurationManager.AppSettings["LowFreqRumble"]);
int highFreq = Int32.Parse(ConfigurationManager.AppSettings["HighFreqRumble"]);
@@ -267,7 +242,7 @@ namespace BetterJoyForCemu {
handle = handle_;
imu_enabled = imu;
do_localize = localize;
- rumble_obj = new Rumble(lowFreq, highFreq, 0, 0);
+ rumble_obj = new Rumble(new float[] {lowFreq, highFreq, 0});
for (int i = 0; i < buttons_down_timestamp.Length; i++)
buttons_down_timestamp[i] = -1;
filterweight = alpha;
@@ -302,17 +277,19 @@ namespace BetterJoyForCemu {
}
public void ReceiveRumble(Xbox360FeedbackReceivedEventArgs e) {
- SetRumble(lowFreq, highFreq, (float)Math.Max(e.LargeMotor, e.SmallMotor) / (float)255, rumblePeriod);
+ DebugPrint("Rumble data Recived: XInput", DebugType.RUMBLE);
+ SetRumble(lowFreq, highFreq, (float)Math.Max(e.LargeMotor, e.SmallMotor) / (float)255);
if (other != null && other != this)
- other.SetRumble(lowFreq, highFreq, (float)Math.Max(e.LargeMotor, e.SmallMotor) / (float)255, rumblePeriod);
+ other.SetRumble(lowFreq, highFreq, (float)Math.Max(e.LargeMotor, e.SmallMotor) / (float)255);
}
public void Ds4_FeedbackReceived(DualShock4FeedbackReceivedEventArgs e) {
- SetRumble(lowFreq, highFreq, (float)Math.Max(e.LargeMotor, e.SmallMotor) / (float)255, rumblePeriod);
+ DebugPrint("Rumble data Recived: DS4", DebugType.RUMBLE);
+ SetRumble(lowFreq, highFreq, (float)Math.Max(e.LargeMotor, e.SmallMotor) / (float)255);
if (other != null && other != this)
- other.SetRumble(lowFreq, highFreq, (float)Math.Max(e.LargeMotor, e.SmallMotor) / (float)255, rumblePeriod);
+ other.SetRumble(lowFreq, highFreq, (float)Math.Max(e.LargeMotor, e.SmallMotor) / (float)255);
}
public void DebugPrint(String s, DebugType d) {
@@ -787,10 +764,12 @@ namespace BetterJoyForCemu {
stop_polling = false;
int attempts = 0;
while (!stop_polling & state > state_.NO_JOYCONS) {
- rumble_obj.Update();
- if (!rumble_obj.controller_informed) {
+ if (rumble_obj.queue.Count > 0) {
SendRumble(rumble_obj.GetData());
- rumble_obj.controller_informed = true;
+ // Keep a queue of 15 items, discard oldest item if queue is full.
+ if (rumble_obj.queue.Count > 15) {
+ rumble_obj.queue.Dequeue();
+ }
}
int a = ReceiveRaw();
@@ -1057,9 +1036,9 @@ namespace BetterJoyForCemu {
return (byte)Math.Max(Byte.MinValue, Math.Min(Byte.MaxValue, 127 - stick_value * Byte.MaxValue));
}
- public void SetRumble(float low_freq, float high_freq, float amp, int rumble_duration_ms = 0) {
+ public void SetRumble(float low_freq, float high_freq, float amp) {
if (state <= Joycon.state_.ATTACHED) return;
- rumble_obj.set_vals(low_freq, high_freq, amp, rumble_duration_ms);
+ rumble_obj.set_vals(low_freq, high_freq, amp);
}
private void SendRumble(byte[] buf) {
diff --git a/BetterJoyForCemu/MainForm.cs b/BetterJoyForCemu/MainForm.cs
index c01932e..492e10a 100644
--- a/BetterJoyForCemu/MainForm.cs
+++ b/BetterJoyForCemu/MainForm.cs
@@ -172,7 +172,7 @@ namespace BetterJoyForCemu {
bool showAsXInput = Boolean.Parse(ConfigurationManager.AppSettings["ShowAsXInput"]);
bool showAsDS4 = Boolean.Parse(ConfigurationManager.AppSettings["ShowAsDS4"]);
- public void locBtnClick(object sender, EventArgs e) {
+ public async void locBtnClickAsync(object sender, EventArgs e) {
Button bb = sender as Button;
if (bb.Tag.GetType() == typeof(Button)) {
@@ -180,7 +180,9 @@ namespace BetterJoyForCemu {
if (button.Tag.GetType() == typeof(Joycon)) {
Joycon v = (Joycon)button.Tag;
- v.SetRumble(160.0f, 320.0f, 1.0f, 300);
+ v.SetRumble(160.0f, 320.0f, 1.0f);
+ await Task.Delay(300);
+ v.SetRumble(160.0f, 320.0f, 0);
}
}
}
diff --git a/BetterJoyForCemu/Program.cs b/BetterJoyForCemu/Program.cs
index 7d8dacf..22bb30e 100644
--- a/BetterJoyForCemu/Program.cs
+++ b/BetterJoyForCemu/Program.cs
@@ -229,7 +229,7 @@ namespace BetterJoyForCemu {
form.loc[ii].Invoke(new MethodInvoker(delegate {
form.loc[ii].Tag = v;
- form.loc[ii].Click += new EventHandler(form.locBtnClick);
+ form.loc[ii].Click += new EventHandler(form.locBtnClickAsync);
}));
break;