diff --git a/DS4Windows/DS4Control/MouseCursor.cs b/DS4Windows/DS4Control/MouseCursor.cs index f54543ad7a..2ad11da9db 100644 --- a/DS4Windows/DS4Control/MouseCursor.cs +++ b/DS4Windows/DS4Control/MouseCursor.cs @@ -18,7 +18,20 @@ public enum Direction { Negative, Neutral, Positive } private Direction horizontalDirection = Direction.Neutral, verticalDirection = Direction.Neutral; private Direction hDirection = Direction.Neutral, vDirection = Direction.Neutral; + private double GYRO_MOUSE_COEFFICIENT = 0.0095; + private int GYRO_MOUSE_DEADZONE = 12; + private double GYRO_MOUSE_OFFSET = 0.1463; + private double GYRO_SMOOTH_MOUSE_OFFSET = 0.14698; + + private const int SMOOTH_BUFFER_LEN = 3; + private double[] xSmoothBuffer = new double[SMOOTH_BUFFER_LEN]; + private double[] ySmoothBuffer = new double[SMOOTH_BUFFER_LEN]; + private int smoothBufferTail = 0; + + double coefficient = 0.0; double verticalScale = 0.0; + bool gyroSmooth = false; + //double gyroSmoothWeight = 0.0; public virtual void sixaxisMoved(SixAxisEventArgs arg) { @@ -27,8 +40,20 @@ public virtual void sixaxisMoved(SixAxisEventArgs arg) deltaY = -arg.sixAxis.gyroYFull; //Console.WriteLine(arg.sixAxis.deltaX); - double coefficient = (Global.getGyroSensitivity(deviceNumber) * 0.01) * 0.0095; - double offset = 0.1463; + gyroSmooth = Global.getGyroSmoothing(deviceNumber); + double gyroSmoothWeight = 0.0; + + coefficient = (Global.getGyroSensitivity(deviceNumber) * 0.01) * GYRO_MOUSE_COEFFICIENT; + double offset = GYRO_MOUSE_OFFSET; + if (gyroSmooth) + { + gyroSmoothWeight = Global.getGyroSmoothingWeight(deviceNumber); + if (gyroSmoothWeight > 0.0) + { + offset = GYRO_SMOOTH_MOUSE_OFFSET; + } + } + double tempAngle = System.Math.Atan2(-deltaY, deltaX); double normX = System.Math.Abs(System.Math.Cos(tempAngle)); double normY = System.Math.Abs(System.Math.Sin(tempAngle)); @@ -45,7 +70,7 @@ public virtual void sixaxisMoved(SixAxisEventArgs arg) vRemainder = 0.0; } - int deadzone = 12; + int deadzone = GYRO_MOUSE_DEADZONE; //int deadzone = 0; int deadzoneX = (int)System.Math.Abs(normX * deadzone); int deadzoneY = (int)System.Math.Abs(normY * deadzone); @@ -73,12 +98,12 @@ public virtual void sixaxisMoved(SixAxisEventArgs arg) if (xMotion != 0.0) { xMotion += hRemainder; - xAction = (int)xMotion; - hRemainder = xMotion - xAction; + //xAction = (int)xMotion; + //hRemainder = xMotion - xAction; } else { - hRemainder = 0.0; + //hRemainder = 0.0; } //hRemainder -= (int)hRemainder; @@ -88,6 +113,51 @@ public virtual void sixaxisMoved(SixAxisEventArgs arg) if (yMotion != 0.0) { yMotion += vRemainder; + //yAction = (int)yMotion; + //vRemainder = yMotion - yAction; + } + else + { + //vRemainder = 0.0; + } + + if (gyroSmooth) + { + int iIndex = smoothBufferTail % SMOOTH_BUFFER_LEN; + xSmoothBuffer[iIndex] = xMotion; + ySmoothBuffer[iIndex] = yMotion; + smoothBufferTail = iIndex + 1; + + double currentWeight = 1.0; + double finalWeight = 0.0; + double x_out = 0.0, y_out = 0.0; + for (int i = 0; i < SMOOTH_BUFFER_LEN; i++) + { + int idx = System.Math.Abs(smoothBufferTail - i - 1) % SMOOTH_BUFFER_LEN; + x_out += xSmoothBuffer[idx] * currentWeight; + y_out += ySmoothBuffer[idx] * currentWeight; + finalWeight += currentWeight; + currentWeight *= gyroSmoothWeight; + } + + x_out /= finalWeight; + xMotion = x_out; + y_out /= finalWeight; + yMotion = y_out; + } + + if (xMotion != 0.0) + { + xAction = (int)xMotion; + hRemainder = xMotion - xAction; + } + else + { + hRemainder = 0.0; + } + + if (yMotion != 0.0) + { yAction = (int)yMotion; vRemainder = yMotion - yAction; } @@ -115,6 +185,10 @@ public virtual void sixaxisMoved(SixAxisEventArgs arg) public void mouseRemainderReset() { hRemainder = vRemainder = 0.0; + int iIndex = smoothBufferTail % SMOOTH_BUFFER_LEN; + xSmoothBuffer[iIndex] = 0.0; + ySmoothBuffer[iIndex] = 0.0; + smoothBufferTail = iIndex + 1; } public void touchesBegan(TouchpadEventArgs arg) diff --git a/DS4Windows/DS4Control/ScpUtil.cs b/DS4Windows/DS4Control/ScpUtil.cs index 36b5a57cd4..84b1764aeb 100644 --- a/DS4Windows/DS4Control/ScpUtil.cs +++ b/DS4Windows/DS4Control/ScpUtil.cs @@ -596,6 +596,18 @@ public static bool getGyroTriggerTurns(int index) return m_Config.gyroTriggerTurns[index]; } + public static bool[] GyroSmoothing => m_Config.gyroSmoothing; + public static bool getGyroSmoothing(int index) + { + return m_Config.gyroSmoothing[index]; + } + + public static double[] GyroSmoothingWeight => m_Config.gyroSmoothWeight; + public static double getGyroSmoothingWeight(int index) + { + return m_Config.gyroSmoothWeight[index]; + } + public static DS4Color[] MainColor => m_Config.m_Leds; public static DS4Color getMainColor(int index) { @@ -1240,6 +1252,8 @@ public class BackingStore public int[] gyroSensVerticalScale = { 100, 100, 100, 100, 100 }; public int[] gyroInvert = { 0, 0, 0, 0, 0 }; public bool[] gyroTriggerTurns = { true, true, true, true, true }; + public bool[] gyroSmoothing = { false, false, false, false, false }; + public double[] gyroSmoothWeight = { 0.5, 0.5, 0.5, 0.5, 0.5 }; public BackingStore() { @@ -1450,6 +1464,8 @@ public bool SaveProfile(int device, string propath) XmlNode xmlGyroSensVerticalScale = m_Xdoc.CreateNode(XmlNodeType.Element, "GyroSensVerticalScale", null); xmlGyroSensVerticalScale.InnerText = gyroSensVerticalScale[device].ToString(); Node.AppendChild(xmlGyroSensVerticalScale); XmlNode xmlGyroInvert = m_Xdoc.CreateNode(XmlNodeType.Element, "GyroInvert", null); xmlGyroInvert.InnerText = gyroInvert[device].ToString(); Node.AppendChild(xmlGyroInvert); XmlNode xmlGyroTriggerTurns = m_Xdoc.CreateNode(XmlNodeType.Element, "GyroTriggerTurns", null); xmlGyroTriggerTurns.InnerText = gyroTriggerTurns[device].ToString(); Node.AppendChild(xmlGyroTriggerTurns); + XmlNode xmlGyroSmoothWeight = m_Xdoc.CreateNode(XmlNodeType.Element, "GyroSmoothingWeight", null); xmlGyroSmoothWeight.InnerText = Convert.ToInt32(gyroSmoothWeight[device] * 100).ToString(); Node.AppendChild(xmlGyroSmoothWeight); + XmlNode xmlGyroSmoothing = m_Xdoc.CreateNode(XmlNodeType.Element, "GyroSmoothing", null); xmlGyroSmoothing.InnerText = gyroSmoothing[device].ToString(); Node.AppendChild(xmlGyroSmoothing); XmlNode xmlLSC = m_Xdoc.CreateNode(XmlNodeType.Element, "LSCurve", null); xmlLSC.InnerText = lsCurve[device].ToString(); Node.AppendChild(xmlLSC); XmlNode xmlRSC = m_Xdoc.CreateNode(XmlNodeType.Element, "RSCurve", null); xmlRSC.InnerText = rsCurve[device].ToString(); Node.AppendChild(xmlRSC); XmlNode xmlProfileActions = m_Xdoc.CreateNode(XmlNodeType.Element, "ProfileActions", null); xmlProfileActions.InnerText = string.Join("/", profileActions[device]); Node.AppendChild(xmlProfileActions); @@ -2368,6 +2384,12 @@ public bool LoadProfile(int device, bool launchprogram, ControlService control, try { Item = m_Xdoc.SelectSingleNode("/" + rootname + "/GyroTriggerTurns"); bool.TryParse(Item.InnerText, out gyroTriggerTurns[device]); } catch { gyroTriggerTurns[device] = true; missingSetting = true; } + try { Item = m_Xdoc.SelectSingleNode("/" + rootname + "/GyroSmoothing"); bool.TryParse(Item.InnerText, out gyroSmoothing[device]); } + catch { gyroSmoothing[device] = false; missingSetting = true; } + + try { Item = m_Xdoc.SelectSingleNode("/" + rootname + "/GyroSmoothingWeight"); int temp = 0; int.TryParse(Item.InnerText, out temp); gyroSmoothWeight[device] = Convert.ToDouble(temp * 0.01); } + catch { gyroSmoothWeight[device] = 0.5; missingSetting = true; } + try { Item = m_Xdoc.SelectSingleNode("/" + rootname + "/LSCurve"); int.TryParse(Item.InnerText, out lsCurve[device]); } catch { lsCurve[device] = 0; missingSetting = true; } @@ -3419,9 +3441,11 @@ private void ResetProfile(int device) gyroSensitivity[device] = 100; gyroSensVerticalScale[device] = 100; gyroInvert[device] = 0; + gyroTriggerTurns[device] = true; + gyroSmoothing[device] = false; + gyroSmoothWeight[device] = 0.5; lsOutCurveMode[device] = 0; rsOutCurveMode[device] = 0; - gyroTriggerTurns[device] = true; } } diff --git a/DS4Windows/DS4Forms/Options.Designer.cs b/DS4Windows/DS4Forms/Options.Designer.cs index 5b2ac69e16..92cbce2022 100644 --- a/DS4Windows/DS4Forms/Options.Designer.cs +++ b/DS4Windows/DS4Forms/Options.Designer.cs @@ -287,6 +287,7 @@ private void InitializeComponent() this.rBSAControls = new System.Windows.Forms.RadioButton(); this.rBSAMouse = new System.Windows.Forms.RadioButton(); this.pnlSAMouse = new System.Windows.Forms.Panel(); + this.label12 = new System.Windows.Forms.Label(); this.nUDGyroMouseVertScale = new System.Windows.Forms.NumericUpDown(); this.label11 = new System.Windows.Forms.Label(); this.gyroTriggerBehavior = new System.Windows.Forms.CheckBox(); @@ -331,8 +332,11 @@ private void InitializeComponent() this.shareToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.pSToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.alwaysOnToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.nUDGyroSmoothWeight = new System.Windows.Forms.NumericUpDown(); + this.lbSmoothWeight = new System.Windows.Forms.Label(); + this.cBGyroSmooth = new System.Windows.Forms.CheckBox(); this.advColorDialog = new DS4Windows.AdvancedColorDialog(); - this.label12 = new System.Windows.Forms.Label(); + this.lbGyroSmooth = new System.Windows.Forms.Label(); ((System.ComponentModel.ISupportInitialize)(this.nUDRainbow)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.tBBlueBar)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.tBGreenBar)).BeginInit(); @@ -416,6 +420,7 @@ private void InitializeComponent() ((System.ComponentModel.ISupportInitialize)(this.nUDSXS)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.nUDSZS)).BeginInit(); this.cMGyroTriggers.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.nUDGyroSmoothWeight)).BeginInit(); this.SuspendLayout(); // // lowColorChooserButton @@ -3017,6 +3022,10 @@ private void InitializeComponent() // // pnlSAMouse // + this.pnlSAMouse.Controls.Add(this.lbGyroSmooth); + this.pnlSAMouse.Controls.Add(this.cBGyroSmooth); + this.pnlSAMouse.Controls.Add(this.lbSmoothWeight); + this.pnlSAMouse.Controls.Add(this.nUDGyroSmoothWeight); this.pnlSAMouse.Controls.Add(this.label12); this.pnlSAMouse.Controls.Add(this.nUDGyroMouseVertScale); this.pnlSAMouse.Controls.Add(this.label11); @@ -3031,6 +3040,11 @@ private void InitializeComponent() resources.ApplyResources(this.pnlSAMouse, "pnlSAMouse"); this.pnlSAMouse.Name = "pnlSAMouse"; // + // label12 + // + resources.ApplyResources(this.label12, "label12"); + this.label12.Name = "label12"; + // // nUDGyroMouseVertScale // this.nUDGyroMouseVertScale.Increment = new decimal(new int[] { @@ -3518,10 +3532,39 @@ private void InitializeComponent() resources.ApplyResources(this.alwaysOnToolStripMenuItem, "alwaysOnToolStripMenuItem"); this.alwaysOnToolStripMenuItem.CheckedChanged += new System.EventHandler(this.SATrigger_CheckedChanged); // - // label12 + // nUDGyroSmoothWeight // - resources.ApplyResources(this.label12, "label12"); - this.label12.Name = "label12"; + this.nUDGyroSmoothWeight.DecimalPlaces = 3; + resources.ApplyResources(this.nUDGyroSmoothWeight, "nUDGyroSmoothWeight"); + this.nUDGyroSmoothWeight.Maximum = new decimal(new int[] { + 1, + 0, + 0, + 0}); + this.nUDGyroSmoothWeight.Name = "nUDGyroSmoothWeight"; + this.nUDGyroSmoothWeight.Value = new decimal(new int[] { + 5, + 0, + 0, + 65536}); + this.nUDGyroSmoothWeight.ValueChanged += new System.EventHandler(this.nUDGyroSmoothWeight_ValueChanged); + // + // lbSmoothWeight + // + resources.ApplyResources(this.lbSmoothWeight, "lbSmoothWeight"); + this.lbSmoothWeight.Name = "lbSmoothWeight"; + // + // cBGyroSmooth + // + resources.ApplyResources(this.cBGyroSmooth, "cBGyroSmooth"); + this.cBGyroSmooth.Name = "cBGyroSmooth"; + this.cBGyroSmooth.UseVisualStyleBackColor = true; + this.cBGyroSmooth.CheckedChanged += new System.EventHandler(this.cBGyroSmooth_CheckedChanged); + // + // lbGyroSmooth + // + resources.ApplyResources(this.lbGyroSmooth, "lbGyroSmooth"); + this.lbGyroSmooth.Name = "lbGyroSmooth"; // // Options // @@ -3635,6 +3678,7 @@ private void InitializeComponent() ((System.ComponentModel.ISupportInitialize)(this.nUDSXS)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.nUDSZS)).EndInit(); this.cMGyroTriggers.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.nUDGyroSmoothWeight)).EndInit(); this.ResumeLayout(false); } @@ -3946,5 +3990,9 @@ private void InitializeComponent() private System.Windows.Forms.NumericUpDown nUDGyroMouseVertScale; private System.Windows.Forms.Label label11; private System.Windows.Forms.Label label12; + private System.Windows.Forms.Label lbSmoothWeight; + private System.Windows.Forms.NumericUpDown nUDGyroSmoothWeight; + private System.Windows.Forms.CheckBox cBGyroSmooth; + private System.Windows.Forms.Label lbGyroSmooth; } } \ No newline at end of file diff --git a/DS4Windows/DS4Forms/Options.cs b/DS4Windows/DS4Forms/Options.cs index bc2d377107..3551b60dc6 100644 --- a/DS4Windows/DS4Forms/Options.cs +++ b/DS4Windows/DS4Forms/Options.cs @@ -581,6 +581,9 @@ public void Reload(int deviceNum, string name) cBGyroInvertY.Checked = invert == 1 || invert == 3; if (s.Count > 0) btnGyroTriggers.Text = string.Join(", ", s); + + cBGyroSmooth.Checked = nUDGyroSmoothWeight.Enabled = GyroSmoothing[device]; + nUDGyroSmoothWeight.Value = (decimal)(GyroSmoothingWeight[device]); } else { @@ -667,6 +670,8 @@ public void Reload(int deviceNum, string name) gyroTriggerBehavior.Checked = true; cBGyroInvertX.Checked = false; cBGyroInvertY.Checked = false; + cBGyroSmooth.Checked = false; + nUDGyroSmoothWeight.Value = 0.5m; Set(); } @@ -1324,6 +1329,8 @@ public void Set() GyroSensitivity[device] = (int)Math.Round(nUDGyroSensitivity.Value, 0); GyroTriggerTurns[device] = gyroTriggerBehavior.Checked; GyroSensVerticalScale[device] = (int)nUDGyroMouseVertScale.Value; + GyroSmoothing[device] = cBGyroSmooth.Checked; + GyroSmoothingWeight[device] = (double)nUDGyroSmoothWeight.Value; int invert = 0; if (cBGyroInvertX.Checked) @@ -2828,6 +2835,24 @@ private void nUDGyroMouseVertScale_ValueChanged(object sender, EventArgs e) } } + private void nUDGyroSmoothWeight_ValueChanged(object sender, EventArgs e) + { + if (!loading) + { + GyroSmoothingWeight[device] = (double)nUDGyroSmoothWeight.Value; + } + } + + private void cBGyroSmooth_CheckedChanged(object sender, EventArgs e) + { + bool value = cBGyroSmooth.Checked; + nUDGyroSmoothWeight.Enabled = value; + if (!loading) + { + GyroSmoothing[device] = value; + } + } + private void Options_Resize(object sender, EventArgs e) { fLPSettings.AutoScroll = false; diff --git a/DS4Windows/DS4Forms/Options.resx b/DS4Windows/DS4Forms/Options.resx index 6d01ea12f0..9d99e26270 100644 --- a/DS4Windows/DS4Forms/Options.resx +++ b/DS4Windows/DS4Forms/Options.resx @@ -4496,7 +4496,7 @@ with profile 6, 51 - 271, 139 + 271, 167 254 @@ -8947,9 +8947,123 @@ with profile 1 + + True + + + 8, 145 + + + 60, 13 + + + 269 + + + Smoothing: + + + lbGyroSmooth + + + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + pnlSAMouse + + + 0 + + + True + + + NoControl + + + 75, 145 + + + Yes + + + 15, 14 + + + 268 + + + cBGyroSmooth + + + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + pnlSAMouse + + + 1 + + + True + + + NoControl + + + 96, 145 + + + 83, 13 + + + 267 + + + Smooth Weight: + + + lbSmoothWeight + + + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + pnlSAMouse + + + 2 + + + False + + + 185, 141 + + + 55, 20 + + + 266 + + + nUDGyroSmoothWeight + + + System.Windows.Forms.NumericUpDown, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + pnlSAMouse + + + 3 + True + + NoControl + 151, 98 @@ -8972,7 +9086,7 @@ with profile pnlSAMouse - 0 + 4 96, 93 @@ -8993,11 +9107,14 @@ with profile pnlSAMouse - 1 + 5 True + + NoControl + 8, 95 @@ -9020,7 +9137,7 @@ with profile pnlSAMouse - 2 + 6 True @@ -9053,7 +9170,7 @@ with profile pnlSAMouse - 3 + 7 True @@ -9086,7 +9203,7 @@ with profile pnlSAMouse - 4 + 8 True @@ -9119,7 +9236,7 @@ with profile pnlSAMouse - 5 + 9 True @@ -9128,7 +9245,7 @@ with profile NoControl - 4, 120 + 8, 119 37, 13 @@ -9152,7 +9269,7 @@ with profile pnlSAMouse - 6 + 10 True @@ -9185,7 +9302,7 @@ with profile pnlSAMouse - 7 + 11 NoControl @@ -9215,10 +9332,10 @@ with profile pnlSAMouse - 8 + 12 - 96, 63 + 96, 67 49, 20 @@ -9236,7 +9353,7 @@ with profile pnlSAMouse - 9 + 13 True @@ -9245,7 +9362,7 @@ with profile NoControl - 6, 66 + 8, 69 82, 13 @@ -9269,7 +9386,7 @@ with profile pnlSAMouse - 10 + 14 6, 43 @@ -9278,7 +9395,7 @@ with profile 2, 2, 2, 2 - 263, 139 + 263, 170 259 @@ -9299,7 +9416,7 @@ with profile 3, 253 - 272, 196 + 272, 224 248 @@ -9982,6 +10099,9 @@ with profile 1010, 481 + + NoControl + 4, 4, 4, 4 @@ -10286,7 +10406,7 @@ with profile advColorDialog - DS4Windows.AdvancedColorDialog, DS4Windows, Version=1.4.80.0, Culture=neutral, PublicKeyToken=null + DS4Windows.AdvancedColorDialog, DS4Windows, Version=1.4.81.0, Culture=neutral, PublicKeyToken=null Options diff --git a/DS4Windows/DS4Library/DS4Device.cs b/DS4Windows/DS4Library/DS4Device.cs index f5398af842..63465c045f 100644 --- a/DS4Windows/DS4Library/DS4Device.cs +++ b/DS4Windows/DS4Library/DS4Device.cs @@ -671,23 +671,19 @@ private void performDs4Input() currerror = string.Empty; curTimeDouble = sw.Elapsed.TotalMilliseconds; curtime = sw.ElapsedMilliseconds; - lastTimeElapsed = curtime - oldtime; - lastTimeElapsedDouble = (curTimeDouble - oldTimeDouble); - //latencyList.Add(this.lastTimeElapsed); - latencyQueue.Enqueue(this.lastTimeElapsed); - tempLatencyCount++; - oldtime = curtime; - oldTimeDouble = curTimeDouble; - if (tempLatencyCount > 50) + if (tempLatencyCount >= 50) { - //latencyList.RemoveAt(0); latencyQueue.Dequeue(); tempLatencyCount--; } - //Latency = latencyList.Average(); - //latencyList.Average(); + lastTimeElapsed = curtime - oldtime; + lastTimeElapsedDouble = (curTimeDouble - oldTimeDouble); + latencyQueue.Enqueue(this.lastTimeElapsed); + tempLatencyCount++; + oldtime = curtime; + oldTimeDouble = curTimeDouble; Latency = latencyQueue.Average(); if (conType == ConnectionType.BT)