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;