mirror of
https://github.com/jkocon/g-helper.git
synced 2026-02-23 13:00:52 +01:00
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:
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -45,6 +45,11 @@ namespace GHelper.Peripherals.Mouse.Models
|
||||
return 36_000;
|
||||
}
|
||||
|
||||
public override bool HasXYDPI()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool HasLiftOffSetting()
|
||||
{
|
||||
return true;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
80
app/Peripherals/Mouse/Models/TUFM4Wireless.cs
Normal file
80
app/Peripherals/Mouse/Models/TUFM4Wireless.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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 == "")
|
||||
|
||||
Reference in New Issue
Block a user