From f79a91fb78592e8a0cd48c0c44ec966e15853a7a Mon Sep 17 00:00:00 2001 From: IceStormNG Date: Fri, 18 Aug 2023 15:04:49 +0200 Subject: [PATCH 1/6] Make reportId a constructor variable as some mice might not require 0x00 as most do. --- app/Peripherals/Mouse/AsusMouse.cs | 51 +++++++++++++++++------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/app/Peripherals/Mouse/AsusMouse.cs b/app/Peripherals/Mouse/AsusMouse.cs index bfd4db26..493c98dd 100644 --- a/app/Peripherals/Mouse/AsusMouse.cs +++ b/app/Peripherals/Mouse/AsusMouse.cs @@ -149,6 +149,8 @@ namespace GHelper.Peripherals.Mouse private readonly string path; + protected byte reportId = 0x00; + public bool IsDeviceReady { get; protected set; } private void SetDeviceReady(bool ready) @@ -195,7 +197,12 @@ namespace GHelper.Peripherals.Mouse { LightingSetting = new LightingSetting[SupportedLightingZones().Length]; } + this.reportId = 0x00; + } + public AsusMouse(ushort vendorId, ushort productId, string path, bool wireless, byte reportId) : this(vendorId, productId, path, wireless) + { + this.reportId = reportId; } public override bool Equals(object? obj) @@ -410,7 +417,7 @@ namespace GHelper.Peripherals.Mouse protected virtual byte[] GetBatteryReportPacket() { - return new byte[] { 0x00, 0x12, 0x07 }; + return new byte[] { reportId, 0x12, 0x07 }; } protected virtual int ParseBattery(byte[] packet) @@ -452,7 +459,7 @@ namespace GHelper.Peripherals.Mouse } protected virtual byte[] GetUpdateEnergySettingsPacket(int lowBatteryWarning, PowerOffSetting powerOff) { - return new byte[] { 0x00, 0x51, 0x37, 0x00, 0x00, (byte)powerOff, 0x00, (byte)lowBatteryWarning }; + return new byte[] { reportId, 0x51, 0x37, 0x00, 0x00, (byte)powerOff, 0x00, (byte)lowBatteryWarning }; } public void SetEnergySettings(int lowBatteryWarning, PowerOffSetting powerOff) @@ -553,12 +560,12 @@ namespace GHelper.Peripherals.Mouse protected virtual byte[] GetReadProfilePacket() { - return new byte[] { 0x00, 0x12, 0x00 }; + return new byte[] { reportId, 0x12, 0x00 }; } protected virtual byte[] GetUpdateProfilePacket(int profile) { - return new byte[] { 0x00, 0x50, 0x02, (byte)profile }; + return new byte[] { reportId, 0x50, 0x02, (byte)profile }; } public void ReadProfile() @@ -667,20 +674,20 @@ namespace GHelper.Peripherals.Mouse protected virtual byte[] GetReadPollingRatePacket() { - return new byte[] { 0x00, 0x12, 0x04, 0x00 }; + return new byte[] { reportId, 0x12, 0x04, 0x00 }; } protected virtual byte[] GetUpdatePollingRatePacket(PollingRate pollingRate) { - return new byte[] { 0x00, 0x51, 0x31, 0x04, 0x00, (byte)pollingRate }; + return new byte[] { reportId, 0x51, 0x31, 0x04, 0x00, (byte)pollingRate }; } protected virtual byte[] GetUpdateAngleSnappingPacket(bool angleSnapping) { - return new byte[] { 0x00, 0x51, 0x31, 0x06, 0x00, (byte)(angleSnapping ? 0x01 : 0x00) }; + return new byte[] { reportId, 0x51, 0x31, 0x06, 0x00, (byte)(angleSnapping ? 0x01 : 0x00) }; } protected virtual byte[] GetUpdateAngleAdjustmentPacket(short angleAdjustment) { - return new byte[] { 0x00, 0x51, 0x31, 0x0B, 0x00, (byte)(angleAdjustment & 0xFF), (byte)((angleAdjustment >> 8) & 0xFF) }; + return new byte[] { reportId, 0x51, 0x31, 0x0B, 0x00, (byte)(angleAdjustment & 0xFF), (byte)((angleAdjustment >> 8) & 0xFF) }; } protected virtual PollingRate ParsePollingRate(byte[] packet) @@ -826,12 +833,12 @@ namespace GHelper.Peripherals.Mouse protected virtual byte[] GetChangeDPIProfilePacket(int profile) { - return new byte[] { 0x00, 0x51, 0x31, 0x0A, 0x00, (byte)profile }; + return new byte[] { reportId, 0x51, 0x31, 0x0A, 0x00, (byte)profile }; } protected virtual byte[] GetChangeDPIProfilePacket2(int profile) { - return new byte[] { 0x00, 0x51, 0x31, 0x09, 0x00, (byte)profile }; + return new byte[] { reportId, 0x51, 0x31, 0x09, 0x00, (byte)profile }; } //profiles start to count at 1 @@ -863,10 +870,10 @@ namespace GHelper.Peripherals.Mouse { if (!HasXYDPI()) { - return new byte[] { 0x00, 0x12, 0x04, 0x00 }; + return new byte[] { reportId, 0x12, 0x04, 0x00 }; } - return new byte[] { 0x00, 0x12, 0x04, 0x02 }; + return new byte[] { reportId, 0x12, 0x04, 0x02 }; } protected virtual byte[]? GetUpdateDPIPacket(AsusMouseDPI dpi, int profile) @@ -883,11 +890,11 @@ namespace GHelper.Peripherals.Mouse if (HasDPIColors()) { - return new byte[] { 0x00, 0x51, 0x31, (byte)(profile - 1), 0x00, (byte)(dpiEncoded & 0xFF), (byte)((dpiEncoded >> 8) & 0xFF), dpi.Color.R, dpi.Color.G, dpi.Color.B }; + return new byte[] { reportId, 0x51, 0x31, (byte)(profile - 1), 0x00, (byte)(dpiEncoded & 0xFF), (byte)((dpiEncoded >> 8) & 0xFF), dpi.Color.R, dpi.Color.G, dpi.Color.B }; } else { - return new byte[] { 0x00, 0x51, 0x31, (byte)(profile - 1), 0x00, (byte)(dpiEncoded & 0xFF), (byte)((dpiEncoded >> 8) & 0xFF) }; + return new byte[] { reportId, 0x51, 0x31, (byte)(profile - 1), 0x00, (byte)(dpiEncoded & 0xFF), (byte)((dpiEncoded >> 8) & 0xFF) }; } } @@ -918,7 +925,7 @@ namespace GHelper.Peripherals.Mouse protected virtual byte[] GetReadDPIColorsPacket() { - return new byte[] { 0x00, 0x12, 0x04, 0x03 }; + return new byte[] { reportId, 0x12, 0x04, 0x03 }; } protected virtual void ParseDPIColors(byte[] packet) @@ -996,13 +1003,13 @@ namespace GHelper.Peripherals.Mouse protected virtual byte[] GetReadLiftOffDistancePacket() { - return new byte[] { 0x00, 0x12, 0x06 }; + return new byte[] { reportId, 0x12, 0x06 }; } //This also resets the "calibration" to default. There is no seperate command to only set the lift off distance protected virtual byte[] GetUpdateLiftOffDistancePacket(LiftOffDistance liftOffDistance) { - return new byte[] { 0x00, 0x51, 0x35, 0xFF, 0x00, 0xFF, ((byte)liftOffDistance) }; + return new byte[] { reportId, 0x51, 0x35, 0xFF, 0x00, 0xFF, ((byte)liftOffDistance) }; } protected virtual LiftOffDistance ParseLiftOffDistance(byte[] packet) @@ -1071,13 +1078,13 @@ namespace GHelper.Peripherals.Mouse protected virtual byte[] GetReadDebouncePacket() { - return new byte[] { 0x00, 0x12, 0x04, 0x00 }; + return new byte[] { reportId, 0x12, 0x04, 0x00 }; } protected virtual byte[] GetUpdateDebouncePacket(DebounceTime debounce) { - return new byte[] { 0x00, 0x51, 0x31, 0x05, 0x00, ((byte)debounce) }; + return new byte[] { reportId, 0x51, 0x31, 0x05, 0x00, ((byte)debounce) }; } protected virtual DebounceTime ParseDebounce(byte[] packet) @@ -1261,7 +1268,7 @@ namespace GHelper.Peripherals.Mouse idx = IndexForZone(zone); } - return new byte[] { 0x00, 0x12, 0x03, (byte)idx }; + return new byte[] { reportId, 0x12, 0x03, (byte)idx }; } protected virtual byte[] GetUpdateLightingModePacket(LightingSetting lightingSetting, LightingZone zone) @@ -1279,7 +1286,7 @@ namespace GHelper.Peripherals.Mouse lightingSetting.LightingMode = LightingMode.ColorCycle; } - return new byte[] { 0x00, 0x51, 0x28, (byte)zone, 0x00, + return new byte[] { reportId, 0x51, 0x28, (byte)zone, 0x00, IndexForLightingMode(lightingSetting.LightingMode), (byte)lightingSetting.Brightness, lightingSetting.RGBColor.R, lightingSetting.RGBColor.G, lightingSetting.RGBColor.B, @@ -1375,7 +1382,7 @@ namespace GHelper.Peripherals.Mouse protected virtual byte[] GetSaveProfilePacket() { - return new byte[] { 0x00, 0x50, 0x03 }; + return new byte[] { reportId, 0x50, 0x03 }; } public void FlushSettings() From 18b54886ed54146c05d647cc039cea6651d6fa61 Mon Sep 17 00:00:00 2001 From: IceStormNG Date: Fri, 18 Aug 2023 15:05:55 +0200 Subject: [PATCH 2/6] Improved packet handling to deal better with empty packets and errors. --- app/Peripherals/Mouse/AsusMouse.cs | 113 ++++++++++++++++++----------- 1 file changed, 70 insertions(+), 43 deletions(-) diff --git a/app/Peripherals/Mouse/AsusMouse.cs b/app/Peripherals/Mouse/AsusMouse.cs index 493c98dd..8e1ddbbb 100644 --- a/app/Peripherals/Mouse/AsusMouse.cs +++ b/app/Peripherals/Mouse/AsusMouse.cs @@ -314,59 +314,86 @@ namespace GHelper.Peripherals.Mouse [MethodImpl(MethodImplOptions.Synchronized)] protected virtual byte[]? WriteForResponse(byte[] packet) { + Array.Resize(ref packet, ASUS_MOUSE_PACKET_SIZE); + + byte[] response = new byte[ASUS_MOUSE_PACKET_SIZE]; - try + int retries = 3; + + while (retries > 0) { - if (IsPacketLoggerEnabled()) - Logger.WriteLine(GetDisplayName() + ": Sending packet: " + ByteArrayToString(packet)); + response = new byte[ASUS_MOUSE_PACKET_SIZE]; - long time = MeasuredIO(Write, packet); - Logger.WriteLine(GetDisplayName() + ": Write took " + time + "ms"); - - time = MeasuredIO(Read, response); - Logger.WriteLine(GetDisplayName() + ": Read took " + time + "ms"); - - if (IsPacketLoggerEnabled()) - Logger.WriteLine(GetDisplayName() + ": Read packet: " + ByteArrayToString(response)); - - if (IsMouseError(response)) + try { - Logger.WriteLine(GetDisplayName() + ": Mouse returned error (FF AA). Packet probably not supported by mouse firmware."); - //Error. Mouse could not understand or process the sent packet - return response; - } + if (IsPacketLoggerEnabled()) + Logger.WriteLine(GetDisplayName() + ": Sending packet: " + ByteArrayToString(packet) + + " Try " + (retries - 2) + " of 3"); + + long time = MeasuredIO(Write, packet); + Logger.WriteLine(GetDisplayName() + ": Write took " + time + "ms"); - //Not the response we were looking for, continue reading - while (response[0] != packet[0] || response[1] != packet[1] || response[2] != packet[2]) - { - Logger.WriteLine(GetDisplayName() + ": Read wrong packet left in buffer: " + ByteArrayToString(response) + ". Retrying..."); - //Read again time = MeasuredIO(Read, response); Logger.WriteLine(GetDisplayName() + ": Read took " + time + "ms"); + + + if (IsMouseError(response)) + { + if (IsPacketLoggerEnabled()) + Logger.WriteLine(GetDisplayName() + ": Read packet: " + ByteArrayToString(response)); + + Logger.WriteLine(GetDisplayName() + ": Mouse returned error (FF AA). Packet probably not supported by mouse firmware."); + //Error. Mouse could not understand or process the sent packet + return response; + } + + if (response[1] == 0 && response[2] == 0 && response[3] == 0) + { + if (IsPacketLoggerEnabled()) + Logger.WriteLine(GetDisplayName() + ": Read packet: " + ByteArrayToString(response)); + Logger.WriteLine(GetDisplayName() + ": Received empty packet. Stopping here."); + //Empty packet + return null; + } + + //Not the response we were looking for, continue reading + while (response[0] != packet[0] || response[1] != packet[1] || response[2] != packet[2]) + { + if (IsPacketLoggerEnabled()) + Logger.WriteLine(GetDisplayName() + ": Read wrong packet left in buffer: " + ByteArrayToString(response) + ". Retrying..."); + //Read again + time = MeasuredIO(Read, response); + Logger.WriteLine(GetDisplayName() + ": Read took " + time + "ms"); + } + + if (IsPacketLoggerEnabled()) + Logger.WriteLine(GetDisplayName() + ": Read packet: " + ByteArrayToString(response)); + + + return response; + + } + catch (IOException e) + { + Logger.WriteLine(GetDisplayName() + ": Failed to read packet " + e.Message); + OnDisconnect(); + return null; + } + catch (TimeoutException e) + { + Logger.WriteLine(GetDisplayName() + ": Timeout reading packet " + e.Message + " Trying again."); + retries--; + continue; + } + catch (ObjectDisposedException) + { + Logger.WriteLine(GetDisplayName() + ": Channel closed "); + OnDisconnect(); + return null; } - } - catch (IOException e) - { - Logger.WriteLine(GetDisplayName() + ": Failed to read packet " + e.Message); - OnDisconnect(); - return null; - } - catch (TimeoutException e) - { - Logger.WriteLine(GetDisplayName() + ": Timeout reading packet " + e.Message); - return null; - } - catch (ObjectDisposedException) - { - Logger.WriteLine(GetDisplayName() + ": Channel closed "); - OnDisconnect(); - return null; - } - - - return response; + return null; } public abstract string GetDisplayName(); From 0ad058ec4a6d31faa70d69e18801817005e36812 Mon Sep 17 00:00:00 2001 From: IceStormNG Date: Fri, 18 Aug 2023 15:08:08 +0200 Subject: [PATCH 3/6] Added feature to read and edit Acceleration and Deceleration values. It seems like only the Harpe Ace really does something with it even though all AimPoint Mice respond to it and store the value. --- app/AsusMouseSettings.Designer.cs | 126 +++++++++++++++++++++++++++-- app/AsusMouseSettings.cs | 56 +++++++++++++ app/Peripherals/Mouse/AsusMouse.cs | 122 ++++++++++++++++++++++++++++ app/Properties/Strings.Designer.cs | 18 +++++ app/Properties/Strings.resx | 6 ++ 5 files changed, 323 insertions(+), 5 deletions(-) diff --git a/app/AsusMouseSettings.Designer.cs b/app/AsusMouseSettings.Designer.cs index d26fe3b4..e6a4f5a6 100644 --- a/app/AsusMouseSettings.Designer.cs +++ b/app/AsusMouseSettings.Designer.cs @@ -33,6 +33,14 @@ labelProfile = new Label(); panelPerformance = new Panel(); panelPerformanceOther = new Panel(); + panelDeceleration = new Panel(); + labelDeceleration = new Label(); + sliderDeceleration = new UI.Slider(); + labelDecelerationValue = new Label(); + panelAcceleration = new Panel(); + labelAcceleration = new Label(); + sliderAcceleration = new UI.Slider(); + labelAccelerationValue = new Label(); panelLiftOffDistance = new Panel(); labelLiftOffDistance = new Label(); comboBoxLiftOffDistance = new UI.RComboBox(); @@ -108,6 +116,8 @@ panelProfiles.SuspendLayout(); panelPerformance.SuspendLayout(); panelPerformanceOther.SuspendLayout(); + panelDeceleration.SuspendLayout(); + panelAcceleration.SuspendLayout(); panelLiftOffDistance.SuspendLayout(); panelDebounce.SuspendLayout(); panelAngleSnapping.SuspendLayout(); @@ -182,13 +192,15 @@ panelPerformance.Location = new Point(11, 68); panelPerformance.Name = "panelPerformance"; panelPerformance.Padding = new Padding(0, 11, 0, 25); - panelPerformance.Size = new Size(654, 461); + panelPerformance.Size = new Size(654, 555); panelPerformance.TabIndex = 1; // // panelPerformanceOther // panelPerformanceOther.AutoSize = true; panelPerformanceOther.AutoSizeMode = AutoSizeMode.GrowAndShrink; + panelPerformanceOther.Controls.Add(panelDeceleration); + panelPerformanceOther.Controls.Add(panelAcceleration); panelPerformanceOther.Controls.Add(panelLiftOffDistance); panelPerformanceOther.Controls.Add(panelDebounce); panelPerformanceOther.Controls.Add(panelAngleSnapping); @@ -197,9 +209,103 @@ panelPerformanceOther.Location = new Point(0, 240); panelPerformanceOther.Name = "panelPerformanceOther"; panelPerformanceOther.Padding = new Padding(0, 11, 0, 11); - panelPerformanceOther.Size = new Size(654, 196); + panelPerformanceOther.Size = new Size(654, 290); panelPerformanceOther.TabIndex = 49; // + // panelDeceleration + // + panelDeceleration.AutoSize = true; + panelDeceleration.AutoSizeMode = AutoSizeMode.GrowAndShrink; + panelDeceleration.Controls.Add(labelDeceleration); + panelDeceleration.Controls.Add(sliderDeceleration); + panelDeceleration.Controls.Add(labelDecelerationValue); + panelDeceleration.Dock = DockStyle.Top; + panelDeceleration.Location = new Point(0, 232); + panelDeceleration.Name = "panelDeceleration"; + panelDeceleration.Padding = new Padding(5); + panelDeceleration.Size = new Size(654, 47); + panelDeceleration.TabIndex = 58; + // + // labelDeceleration + // + labelDeceleration.Location = new Point(6, 7); + labelDeceleration.Margin = new Padding(6, 0, 6, 0); + labelDeceleration.Name = "labelDeceleration"; + labelDeceleration.Size = new Size(348, 33); + labelDeceleration.TabIndex = 52; + labelDeceleration.Text = "Deceleration"; + // + // sliderDeceleration + // + sliderDeceleration.AccessibleName = "DPI Slider"; + sliderDeceleration.Location = new Point(368, 9); + sliderDeceleration.Max = 9; + sliderDeceleration.Min = 0; + sliderDeceleration.Name = "sliderDeceleration"; + sliderDeceleration.Size = new Size(213, 30); + sliderDeceleration.Step = 1; + sliderDeceleration.TabIndex = 50; + sliderDeceleration.TabStop = false; + sliderDeceleration.Text = "sliderBattery"; + sliderDeceleration.Value = 0; + // + // labelDecelerationValue + // + labelDecelerationValue.Location = new Point(590, 9); + labelDecelerationValue.Margin = new Padding(6, 0, 6, 0); + labelDecelerationValue.Name = "labelDecelerationValue"; + labelDecelerationValue.Size = new Size(60, 30); + labelDecelerationValue.TabIndex = 51; + labelDecelerationValue.Text = "0"; + labelDecelerationValue.TextAlign = ContentAlignment.MiddleRight; + // + // panelAcceleration + // + panelAcceleration.AutoSize = true; + panelAcceleration.AutoSizeMode = AutoSizeMode.GrowAndShrink; + panelAcceleration.Controls.Add(labelAcceleration); + panelAcceleration.Controls.Add(sliderAcceleration); + panelAcceleration.Controls.Add(labelAccelerationValue); + panelAcceleration.Dock = DockStyle.Top; + panelAcceleration.Location = new Point(0, 185); + panelAcceleration.Name = "panelAcceleration"; + panelAcceleration.Padding = new Padding(5); + panelAcceleration.Size = new Size(654, 47); + panelAcceleration.TabIndex = 57; + // + // labelAcceleration + // + labelAcceleration.Location = new Point(6, 7); + labelAcceleration.Margin = new Padding(6, 0, 6, 0); + labelAcceleration.Name = "labelAcceleration"; + labelAcceleration.Size = new Size(348, 33); + labelAcceleration.TabIndex = 52; + labelAcceleration.Text = "Acceleration"; + // + // sliderAcceleration + // + sliderAcceleration.AccessibleName = "DPI Slider"; + sliderAcceleration.Location = new Point(368, 9); + sliderAcceleration.Max = 9; + sliderAcceleration.Min = 0; + sliderAcceleration.Name = "sliderAcceleration"; + sliderAcceleration.Size = new Size(213, 30); + sliderAcceleration.Step = 1; + sliderAcceleration.TabIndex = 50; + sliderAcceleration.TabStop = false; + sliderAcceleration.Text = "sliderBattery"; + sliderAcceleration.Value = 0; + // + // labelAccelerationValue + // + labelAccelerationValue.Location = new Point(590, 9); + labelAccelerationValue.Margin = new Padding(6, 0, 6, 0); + labelAccelerationValue.Name = "labelAccelerationValue"; + labelAccelerationValue.Size = new Size(60, 30); + labelAccelerationValue.TabIndex = 51; + labelAccelerationValue.Text = "0"; + labelAccelerationValue.TextAlign = ContentAlignment.MiddleRight; + // // panelLiftOffDistance // panelLiftOffDistance.AutoSize = true; @@ -656,7 +762,7 @@ panelLighting.Controls.Add(panelLightingContent); panelLighting.Controls.Add(panelLightingHeader); panelLighting.Dock = DockStyle.Top; - panelLighting.Location = new Point(11, 529); + panelLighting.Location = new Point(11, 623); panelLighting.Name = "panelLighting"; panelLighting.Padding = new Padding(0, 0, 0, 25); panelLighting.Size = new Size(654, 329); @@ -985,7 +1091,7 @@ panelEnergy.Controls.Add(labelAutoPowerOff); panelEnergy.Controls.Add(panelEnergyHeader); panelEnergy.Dock = DockStyle.Top; - panelEnergy.Location = new Point(11, 858); + panelEnergy.Location = new Point(11, 952); panelEnergy.Name = "panelEnergy"; panelEnergy.Padding = new Padding(0, 0, 0, 25); panelEnergy.Size = new Size(654, 143); @@ -1166,7 +1272,7 @@ panelBottomButtons.AutoSizeMode = AutoSizeMode.GrowAndShrink; panelBottomButtons.Controls.Add(buttonSync); panelBottomButtons.Dock = DockStyle.Top; - panelBottomButtons.Location = new Point(11, 1001); + panelBottomButtons.Location = new Point(11, 1095); panelBottomButtons.Name = "panelBottomButtons"; panelBottomButtons.Size = new Size(654, 67); panelBottomButtons.TabIndex = 47; @@ -1260,6 +1366,8 @@ panelPerformance.PerformLayout(); panelPerformanceOther.ResumeLayout(false); panelPerformanceOther.PerformLayout(); + panelDeceleration.ResumeLayout(false); + panelAcceleration.ResumeLayout(false); panelLiftOffDistance.ResumeLayout(false); panelDebounce.ResumeLayout(false); panelAngleSnapping.ResumeLayout(false); @@ -1379,5 +1487,13 @@ private Panel panelAngleSnapping; private Panel panelLiftOffDistance; private Panel panelDebounce; + private Panel panelDeceleration; + private Label labelDeceleration; + private UI.Slider sliderDeceleration; + private Label labelDecelerationValue; + private Panel panelAcceleration; + private Label labelAcceleration; + private UI.Slider sliderAcceleration; + private Label labelAccelerationValue; } } \ No newline at end of file diff --git a/app/AsusMouseSettings.cs b/app/AsusMouseSettings.cs index 3687b9be..62a9715b 100644 --- a/app/AsusMouseSettings.cs +++ b/app/AsusMouseSettings.cs @@ -46,6 +46,8 @@ namespace GHelper labelChargingState.Text = "(" + Properties.Strings.Charging + ")"; labelProfile.Text = Properties.Strings.Profile; labelButtonDebounce.Text = Properties.Strings.MouseButtonResponse; + labelAcceleration.Text = Properties.Strings.Acceleration; + labelDeceleration.Text = Properties.Strings.Deceleration; buttonLightingZoneLogo.Text = Properties.Strings.AuraZoneLogo; buttonLightingZoneScroll.Text = Properties.Strings.AuraZoneScroll; @@ -80,6 +82,12 @@ namespace GHelper sliderButtonDebounce.ValueChanged += SliderButtonDebounce_ValueChanged; sliderButtonDebounce.MouseUp += SliderButtonDebounce_MouseUp; + sliderAcceleration.MouseUp += SliderAcceleration_MouseUp; + sliderAcceleration.ValueChanged += SliderAcceleration_ValueChanged; + + sliderDeceleration.MouseUp += SliderDeceleration_MouseUp; + sliderDeceleration.ValueChanged += SliderDeceleration_ValueChanged; + buttonLightingColor.Click += ButtonLightingColor_Click; comboBoxLightingMode.DropDownClosed += ComboBoxLightingMode_DropDownClosed; sliderBrightness.MouseUp += SliderBrightness_MouseUp; @@ -103,6 +111,26 @@ namespace GHelper RefreshMouseData(); } + private void SliderAcceleration_MouseUp(object? sender, MouseEventArgs e) + { + mouse.SetAcceleration(sliderAcceleration.Value); + } + + private void SliderAcceleration_ValueChanged(object? sender, EventArgs e) + { + labelAccelerationValue.Text = sliderAcceleration.Value.ToString(); + } + + private void SliderDeceleration_MouseUp(object? sender, MouseEventArgs e) + { + mouse.SetDeceleration(sliderDeceleration.Value); + } + + private void SliderDeceleration_ValueChanged(object? sender, EventArgs e) + { + labelDecelerationValue.Text = sliderDeceleration.Value.ToString(); + } + private void SliderButtonDebounce_MouseUp(object? sender, MouseEventArgs e) { DebounceTime dbt = (DebounceTime)sliderButtonDebounce.Value; @@ -513,6 +541,24 @@ namespace GHelper panelAngleSnapping.Visible = false; } + if (mouse.HasAcceleration()) + { + sliderAcceleration.Max = mouse.MaxAcceleration(); + } + else + { + panelAcceleration.Visible = false; + } + + if (mouse.HasDeceleration()) + { + sliderDeceleration.Max = mouse.MaxDeceleration(); + } + else + { + panelDeceleration.Visible = false; + } + if (mouse.HasLiftOffSetting()) { comboBoxLiftOffDistance.Items.AddRange(new string[] { @@ -681,6 +727,16 @@ namespace GHelper { sliderButtonDebounce.Value = (int)mouse.Debounce; } + + if (mouse.HasAcceleration()) + { + sliderAcceleration.Value = mouse.Acceleration; + } + + if (mouse.HasDeceleration()) + { + sliderDeceleration.Value = mouse.Deceleration; + } } private void VisualizeBatteryState() diff --git a/app/Peripherals/Mouse/AsusMouse.cs b/app/Peripherals/Mouse/AsusMouse.cs index 8e1ddbbb..cd6eae26 100644 --- a/app/Peripherals/Mouse/AsusMouse.cs +++ b/app/Peripherals/Mouse/AsusMouse.cs @@ -182,6 +182,8 @@ namespace GHelper.Peripherals.Mouse public bool AngleSnapping { get; protected set; } public short AngleAdjustmentDegrees { get; protected set; } public DebounceTime Debounce { get; protected set; } + public int Acceleration { get; protected set; } + public int Deceleration { get; protected set; } public AsusMouse(ushort vendorId, ushort productId, string path, bool wireless) : base(vendorId, productId) @@ -420,6 +422,7 @@ namespace GHelper.Peripherals.Mouse ReadPollingRate(); ReadLiftOffDistance(); ReadDebounce(); + ReadAcceleration(); ReadLightingSetting(); } @@ -825,6 +828,125 @@ namespace GHelper.Peripherals.Mouse this.AngleAdjustmentDegrees = angleAdjustment; } + // ------------------------------------------------------------------------------ + // Acceleration/Deceleration + // ------------------------------------------------------------------------------ + public virtual bool HasAcceleration() + { + return false; + } + + public virtual bool HasDeceleration() + { + return false; + } + + public virtual int MaxAcceleration() + { + return 0; + } + public virtual int MaxDeceleration() + { + return 0; + } + + protected virtual byte[] GetChangeAccelerationPacket(int acceleration) + { + return new byte[] { reportId, 0x51, 0x31, 0x07, 0x00, (byte)acceleration }; + } + + protected virtual byte[] GetChangeDecelerationPacket(int deceleration) + { + return new byte[] { reportId, 0x51, 0x31, 0x08, 0x00, (byte)deceleration }; + } + + public virtual void SetAcceleration(int acceleration) + { + if (!HasAcceleration()) + { + return; + } + + if (acceleration > MaxAcceleration() || acceleration < 0) + { + Logger.WriteLine(GetDisplayName() + ": Acceleration " + acceleration + " is invalid."); + return; + } + + WriteForResponse(GetChangeAccelerationPacket(acceleration)); + FlushSettings(); + + Logger.WriteLine(GetDisplayName() + ": Acceleration set to " + acceleration); + this.Acceleration = acceleration; + } + + public virtual void SetDeceleration(int deceleration) + { + if (!HasDeceleration()) + { + return; + } + + if (deceleration > MaxDeceleration() || deceleration < 0) + { + Logger.WriteLine(GetDisplayName() + ": Deceleration " + deceleration + " is invalid."); + return; + } + + WriteForResponse(GetChangeDecelerationPacket(deceleration)); + FlushSettings(); + + Logger.WriteLine(GetDisplayName() + ": Deceleration set to " + deceleration); + this.Deceleration = deceleration; + } + + protected virtual byte[] GetReadAccelerationPacket() + { + return new byte[] { reportId, 0x12, 0x04, 0x01 }; + } + + protected virtual int ParseAcceleration(byte[] packet) + { + if (packet[1] != 0x12 || packet[2] != 0x04 || packet[3] != 0x01) + { + return 0; + } + + return packet[5]; + } + + protected virtual int ParseDeceleration(byte[] packet) + { + if (packet[1] != 0x12 || packet[2] != 0x04 || packet[3] != 0x01) + { + return 0; + } + + return packet[7]; + } + + public virtual void ReadAcceleration() + { + if (!HasAcceleration() && !HasDeceleration()) + { + return; + } + + byte[]? response = WriteForResponse(GetReadAccelerationPacket()); + if (response is null) return; + + if (HasAcceleration()) Acceleration = ParseAcceleration(response); + if (HasDeceleration()) Deceleration = ParseDeceleration(response); + + for (int i = 0; i < DPIProfileCount(); ++i) + { + Logger.WriteLine(GetDisplayName() + ": Read DPI Setting " + (i + 1) + ": " + DpiSettings[i].ToString()); + } + + } + + //TODO: Implement Acceleration Reading + // ------------------------------------------------------------------------------ // DPI // ------------------------------------------------------------------------------ diff --git a/app/Properties/Strings.Designer.cs b/app/Properties/Strings.Designer.cs index fc4656b1..a2a77ee5 100644 --- a/app/Properties/Strings.Designer.cs +++ b/app/Properties/Strings.Designer.cs @@ -60,6 +60,15 @@ namespace GHelper.Properties { } } + /// + /// Looks up a localized string similar to Acceleration. + /// + internal static string Acceleration { + get { + return ResourceManager.GetString("Acceleration", resourceCulture); + } + } + /// /// Looks up a localized string similar to Can't connect to ASUS ACPI. Application can't function without it. Try to install Asus System Control Interface. /// @@ -537,6 +546,15 @@ namespace GHelper.Properties { } } + /// + /// Looks up a localized string similar to Deceleration. + /// + internal static string Deceleration { + get { + return ResourceManager.GetString("Deceleration", resourceCulture); + } + } + /// /// Looks up a localized string similar to Default. /// diff --git a/app/Properties/Strings.resx b/app/Properties/Strings.resx index 4dcf8faf..5170a065 100644 --- a/app/Properties/Strings.resx +++ b/app/Properties/Strings.resx @@ -117,6 +117,9 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + Acceleration + Can't connect to ASUS ACPI. Application can't function without it. Try to install Asus System Control Interface @@ -276,6 +279,9 @@ Custom + + Deceleration + Default From 1d03eb064a52dd62b42bbd8293480bb7d9cc27f1 Mon Sep 17 00:00:00 2001 From: IceStormNG Date: Fri, 18 Aug 2023 15:08:40 +0200 Subject: [PATCH 4/6] Allow subclasses to read whether packet logger is enabled or not --- app/Peripherals/Mouse/AsusMouse.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Peripherals/Mouse/AsusMouse.cs b/app/Peripherals/Mouse/AsusMouse.cs index cd6eae26..d25fa232 100644 --- a/app/Peripherals/Mouse/AsusMouse.cs +++ b/app/Peripherals/Mouse/AsusMouse.cs @@ -288,7 +288,7 @@ namespace GHelper.Peripherals.Mouse } } - private static bool IsPacketLoggerEnabled() + protected static bool IsPacketLoggerEnabled() { #if DEBUG return true; From 18b664a123fdc8af85980e712e4f4ab66b8c83fc Mon Sep 17 00:00:00 2001 From: IceStormNG Date: Fri, 18 Aug 2023 15:09:12 +0200 Subject: [PATCH 5/6] Default Profile is 0, so use that if decoding fails to have a sane fallback. --- app/Peripherals/Mouse/AsusMouse.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Peripherals/Mouse/AsusMouse.cs b/app/Peripherals/Mouse/AsusMouse.cs index d25fa232..6c05ec66 100644 --- a/app/Peripherals/Mouse/AsusMouse.cs +++ b/app/Peripherals/Mouse/AsusMouse.cs @@ -575,7 +575,7 @@ namespace GHelper.Peripherals.Mouse return packet[11]; } Logger.WriteLine(GetDisplayName() + ": Failed to decode active profile"); - return 1; + return 0; } protected virtual int ParseDPIProfile(byte[] packet) From e4aa5f028311ce6e65bebf7a3df2ffe61f5e4c45 Mon Sep 17 00:00:00 2001 From: IceStormNG Date: Fri, 18 Aug 2023 15:17:03 +0200 Subject: [PATCH 6/6] Cleanup of left-overs that shouldn't be there --- app/Peripherals/Mouse/AsusMouse.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/app/Peripherals/Mouse/AsusMouse.cs b/app/Peripherals/Mouse/AsusMouse.cs index 6c05ec66..d2be78e5 100644 --- a/app/Peripherals/Mouse/AsusMouse.cs +++ b/app/Peripherals/Mouse/AsusMouse.cs @@ -935,18 +935,19 @@ namespace GHelper.Peripherals.Mouse byte[]? response = WriteForResponse(GetReadAccelerationPacket()); if (response is null) return; - if (HasAcceleration()) Acceleration = ParseAcceleration(response); - if (HasDeceleration()) Deceleration = ParseDeceleration(response); - - for (int i = 0; i < DPIProfileCount(); ++i) + if (HasAcceleration()) { - Logger.WriteLine(GetDisplayName() + ": Read DPI Setting " + (i + 1) + ": " + DpiSettings[i].ToString()); + Acceleration = ParseAcceleration(response); + Logger.WriteLine(GetDisplayName() + ": Read Acceleration: " + Acceleration); } + if (HasDeceleration()) + { + Deceleration = ParseDeceleration(response); + Logger.WriteLine(GetDisplayName() + ": Read Deceleration: " + Deceleration); + } } - //TODO: Implement Acceleration Reading - // ------------------------------------------------------------------------------ // DPI // ------------------------------------------------------------------------------