Merge pull request #933 from IceStormNG/asus-mouse-support

Added support for ASUS TUF Gaming M4 Wireless (P306_Wireless) Mouse
This commit is contained in:
Serge
2023-07-30 12:20:37 +02:00
committed by GitHub
7 changed files with 194 additions and 23 deletions

View File

@@ -376,9 +376,11 @@ namespace GHelper
sliderDPI.Max = mouse.MaxDPI();
sliderDPI.Min = mouse.MinDPI();
sliderDPI.Step = mouse.DPIIncrements();
numericUpDownCurrentDPI.Minimum = mouse.MinDPI();
numericUpDownCurrentDPI.Maximum = mouse.MaxDPI();
numericUpDownCurrentDPI.Increment = mouse.DPIIncrements();
if (!mouse.HasDPIColors())
@@ -391,9 +393,9 @@ namespace GHelper
buttonDPI4.Image = ControlHelper.TintImage(Properties.Resources.lighting_dot_24, Color.Green);
buttonDPI1.BorderColor = Color.Red;
buttonDPI1.BorderColor = Color.Purple;
buttonDPI1.BorderColor = Color.Blue;
buttonDPI1.BorderColor = Color.Green;
buttonDPI2.BorderColor = Color.Purple;
buttonDPI3.BorderColor = Color.Blue;
buttonDPI4.BorderColor = Color.Green;
}
if (mouse.CanSetPollingRate())
@@ -473,6 +475,8 @@ namespace GHelper
if (mouse.HasRGB())
{
sliderBrightness.Max = mouse.MaxBrightness();
foreach (LightingMode lm in Enum.GetValues(typeof(LightingMode)))
{
if (mouse.IsLightingModeSupported(lm))

View File

@@ -211,9 +211,14 @@ namespace GHelper.Peripherals.Mouse
}
}
public virtual int USBTimeout()
{
return 300;
}
public override void SetProvider()
{
_usbProvider = new WindowsUsbProvider(_vendorId, _productId, path);
_usbProvider = new WindowsUsbProvider(_vendorId, _productId, path, USBTimeout());
}
protected virtual void OnDisconnect()
@@ -235,6 +240,21 @@ namespace GHelper.Peripherals.Mouse
#endif
}
protected virtual bool IsMouseError(byte[] packet)
{
return packet[1] == 0xFF && packet[2] == 0xAA;
}
protected virtual long MeasuredIO(Action<byte[]> ioFunc, byte[] param)
{
var watch = System.Diagnostics.Stopwatch.StartNew();
ioFunc(param);
watch.Stop();
return watch.ElapsedMilliseconds;
}
[MethodImpl(MethodImplOptions.Synchronized)]
protected virtual byte[]? WriteForResponse(byte[] packet)
{
@@ -245,12 +265,31 @@ namespace GHelper.Peripherals.Mouse
if (IsPacketLoggerEnabled())
Logger.WriteLine(GetDisplayName() + ": Sending packet: " + ByteArrayToString(packet));
Write(packet);
long time = MeasuredIO(Write, packet);
Logger.WriteLine(GetDisplayName() + ": Write took " + time + "ms");
Read(response);
time = MeasuredIO(Read, response);
Logger.WriteLine(GetDisplayName() + ": Read took " + time + "ms");
if (IsPacketLoggerEnabled())
Logger.WriteLine(GetDisplayName() + ": Read packet: " + ByteArrayToString(response));
if (IsMouseError(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;
}
//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");
}
}
catch (IOException e)
{
@@ -258,12 +297,12 @@ namespace GHelper.Peripherals.Mouse
OnDisconnect();
return null;
}
catch (System.TimeoutException e)
catch (TimeoutException e)
{
Logger.WriteLine(GetDisplayName() + ": Timeout reading packet " + e.Message);
return null;
}
catch (System.ObjectDisposedException e)
catch (ObjectDisposedException)
{
Logger.WriteLine(GetDisplayName() + ": Channel closed ");
OnDisconnect();
@@ -295,9 +334,9 @@ namespace GHelper.Peripherals.Mouse
ReadProfile();
ReadDPI();
ReadLightingSetting();
ReadLiftOffDistance();
ReadPollingRate();
ReadLiftOffDistance();
ReadLightingSetting();
}
// ------------------------------------------------------------------------------
@@ -695,6 +734,11 @@ namespace GHelper.Peripherals.Mouse
return false;
}
public virtual int DPIIncrements()
{
return 50;
}
public virtual bool CanChangeDPIProfile()
{
return DPIProfileCount() > 1;
@@ -709,6 +753,11 @@ namespace GHelper.Peripherals.Mouse
return 100;
}
public virtual bool HasXYDPI()
{
return false;
}
protected virtual byte[] GetChangeDPIProfilePacket(int profile)
{
return new byte[] { 0x00, 0x51, 0x31, 0x0A, 0x00, (byte)profile };
@@ -720,7 +769,7 @@ namespace GHelper.Peripherals.Mouse
}
//profiles start to count at 1
public void SetDPIProfile(int profile)
public virtual void SetDPIProfile(int profile)
{
if (!CanChangeDPIProfile())
{
@@ -745,6 +794,11 @@ namespace GHelper.Peripherals.Mouse
protected virtual byte[] GetReadDPIPacket()
{
if (!HasXYDPI())
{
return new byte[] { 0x00, 0x12, 0x04, 0x00 };
}
return new byte[] { 0x00, 0x12, 0x04, 0x02 };
}
@@ -758,7 +812,7 @@ namespace GHelper.Peripherals.Mouse
{
return null;
}
ushort dpiEncoded = (ushort)((dpi.DPI - 50) / 50);
ushort dpiEncoded = (ushort)((dpi.DPI - DPIIncrements()) / DPIIncrements());
if (HasDPIColors())
{
@@ -773,7 +827,7 @@ namespace GHelper.Peripherals.Mouse
protected virtual void ParseDPI(byte[] packet)
{
if (packet[1] != 0x12 || packet[2] != 0x04 || packet[3] != 0x02)
if (packet[1] != 0x12 || packet[2] != 0x04 || (packet[3] != 0x02 && HasXYDPI()))
{
return;
}
@@ -785,12 +839,13 @@ namespace GHelper.Peripherals.Mouse
DpiSettings[i] = new AsusMouseDPI();
}
int offset = 5 + (i * 4);
int offset = HasXYDPI() ? (5 + (i * 4)) : (5 + (i * 2));
uint b1 = packet[offset];
uint b2 = packet[offset + 1];
DpiSettings[i].DPI = (uint)(b2 << 8 | b1) * 50 + 50;
DpiSettings[i].DPI = (uint)((b2 << 8 | b1) * DPIIncrements() + DPIIncrements());
}
}
@@ -931,6 +986,11 @@ namespace GHelper.Peripherals.Mouse
return false;
}
public virtual int MaxBrightness()
{
return 100;
}
//Override to remap lighting mode IDs.
//From OpenRGB code it looks like some mice have different orders of the modes or do not support some modes at all.
protected virtual byte IndexForLightingMode(LightingMode lightingMode)

View File

@@ -45,6 +45,11 @@ namespace GHelper.Peripherals.Mouse.Models
return 36_000;
}
public override bool HasXYDPI()
{
return true;
}
public override bool HasLiftOffSetting()
{
return true;

View File

@@ -1,12 +1,12 @@
namespace GHelper.Peripherals.Mouse.Models
{
public class GladiusIII : AsusMouse
public class GladiusIIIAimpoint : AsusMouse
{
public GladiusIII() : base(0x0B05, 0x1A70, "mi_00", true)
public GladiusIIIAimpoint() : base(0x0B05, 0x1A70, "mi_00", true)
{
}
protected GladiusIII(ushort vendorId, bool wireless) : base(0x0B05, vendorId, "mi_00", wireless)
protected GladiusIIIAimpoint(ushort vendorId, bool wireless) : base(0x0B05, vendorId, "mi_00", wireless)
{
}
@@ -40,6 +40,11 @@
return 36_000;
}
public override bool HasXYDPI()
{
return true;
}
public override bool HasLiftOffSetting()
{
return true;
@@ -76,9 +81,9 @@
}
}
public class GladiusIIIWired : GladiusIII
public class GladiusIIIAimpointWired : GladiusIIIAimpoint
{
public GladiusIIIWired() : base(0x1A72, false)
public GladiusIIIAimpointWired() : base(0x1A72, false)
{
}

View File

@@ -0,0 +1,80 @@
namespace GHelper.Peripherals.Mouse.Models
{
//P306_Wireless
public class TUFM4Wirelss : AsusMouse
{
public TUFM4Wirelss() : base(0x0B05, 0x19F4, "mi_00", true)
{
}
public override int DPIProfileCount()
{
return 4;
}
public override string GetDisplayName()
{
return "TUF GAMING M4 (Wireless)";
}
public override PollingRate[] SupportedPollingrates()
{
return new PollingRate[] {
PollingRate.PR125Hz,
PollingRate.PR250Hz,
PollingRate.PR500Hz,
PollingRate.PR1000Hz
};
}
public override int ProfileCount()
{
return 3;
}
public override int MaxDPI()
{
return 12_000;
}
public override bool HasLiftOffSetting()
{
return false;
}
public override bool HasAutoPowerOff()
{
return true;
}
public override bool HasAngleSnapping()
{
return true;
}
public override bool HasAngleTuning()
{
return false;
}
public override bool HasLowBatteryWarning()
{
return true;
}
public override bool HasDPIColors()
{
return false;
}
public override int DPIIncrements()
{
return 100;
}
public override bool CanChangeDPIProfile()
{
return true;
}
}
}

View File

@@ -20,6 +20,8 @@ namespace GHelper.Peripherals
}
private static long lastRefresh;
public static bool IsMouseConnected()
{
lock (_LOCK)
@@ -51,6 +53,15 @@ namespace GHelper.Peripherals
public static void RefreshBatteryForAllDevices()
{
RefreshBatteryForAllDevices(false);
}
public static void RefreshBatteryForAllDevices(bool force)
{
//Polling the battery every 20s should be enough
if (!force && Math.Abs(DateTimeOffset.Now.ToUnixTimeMilliseconds() - lastRefresh) < 20_000) return;
lastRefresh = DateTimeOffset.Now.ToUnixTimeMilliseconds();
List<IPeripheral> l = AllPeripherals();
foreach (IPeripheral m in l)
@@ -174,8 +185,9 @@ namespace GHelper.Peripherals
//Add one line for every supported mouse class here to support them.
DetectMouse(new ChakramX());
DetectMouse(new ChakramXWired());
DetectMouse(new GladiusIII());
DetectMouse(new GladiusIIIWired());
DetectMouse(new GladiusIIIAimpoint());
DetectMouse(new GladiusIIIAimpointWired());
DetectMouse(new TUFM4Wirelss());
}
public static void DetectMouse(AsusMouse am)

View File

@@ -236,11 +236,16 @@ namespace GHelper
{
screenControl.InitScreen();
gpuControl.InitXGM();
Task.Run((Action)PeripheralsProvider.RefreshBatteryForAllDevices);
Task.Run((Action)RefreshPeripheralsBattery);
updateControl.CheckForUpdates();
}
}
private void RefreshPeripheralsBattery()
{
PeripheralsProvider.RefreshBatteryForAllDevices(true);
}
private void ButtonUpdates_Click(object? sender, EventArgs e)
{
if (updates == null || updates.Text == "")