mirror of
https://github.com/vale981/VoiDPlugins
synced 2025-03-04 16:51:38 -05:00
Optimize VMulti-based plugins
- Allocate to POH - Directly manipulate buffer through pointer access
This commit is contained in:
parent
aba845f297
commit
744fe3f780
14 changed files with 168 additions and 138 deletions
|
@ -1,3 +1,4 @@
|
|||
using System.Numerics;
|
||||
using OpenTabletDriver.Plugin.Platform.Display;
|
||||
using OpenTabletDriver.Plugin.Platform.Pointer;
|
||||
using VoiDPlugins.Library.VMulti;
|
||||
|
@ -5,11 +6,22 @@ using VoiDPlugins.Library.VMulti.Device;
|
|||
|
||||
namespace VoiDPlugins.OutputMode
|
||||
{
|
||||
public class VMultiAbsolutePointer : BasePointer<AbsoluteInputReport>, IAbsolutePointer
|
||||
public unsafe class VMultiAbsolutePointer : BasePointer<AbsoluteInputReport>, IAbsolutePointer
|
||||
{
|
||||
public VMultiAbsolutePointer(IVirtualScreen screen) : base(screen, 0x09, "VMultiAbs")
|
||||
public VMultiAbsolutePointer(IVirtualScreen screen) : base(screen, "VMultiAbs")
|
||||
{
|
||||
ButtonHandler.SetReport(Report);
|
||||
ButtonHandler.SetReport((VMultiReportHeader*)ReportPointer, ReportBuffer);
|
||||
}
|
||||
|
||||
protected override AbsoluteInputReport CreateReport()
|
||||
{
|
||||
return new AbsoluteInputReport(0x09);
|
||||
}
|
||||
|
||||
protected override void SetCoordinates(Vector2 pos)
|
||||
{
|
||||
ReportPointer->X = (ushort)pos.X;
|
||||
ReportPointer->Y = (ushort)pos.Y;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
using System.Numerics;
|
||||
using OpenTabletDriver.Plugin.Platform.Display;
|
||||
using OpenTabletDriver.Plugin.Platform.Pointer;
|
||||
using VoiDPlugins.Library.VMulti;
|
||||
|
@ -5,11 +6,28 @@ using VoiDPlugins.Library.VMulti.Device;
|
|||
|
||||
namespace VoiDPlugins.OutputMode
|
||||
{
|
||||
public class VMultiRelativePointer : BasePointer<RelativeInputReport>, IRelativePointer
|
||||
public unsafe class VMultiRelativePointer : BasePointer<RelativeInputReport>, IRelativePointer
|
||||
{
|
||||
public VMultiRelativePointer(IVirtualScreen screen) : base(screen, 0x04, "VMultiRel")
|
||||
public VMultiRelativePointer(IVirtualScreen screen) : base(screen, "VMultiRel")
|
||||
{
|
||||
ButtonHandler.SetReport(Report);
|
||||
ButtonHandler.SetReport((VMultiReportHeader*)ReportPointer, ReportBuffer);
|
||||
}
|
||||
|
||||
protected override RelativeInputReport CreateReport()
|
||||
{
|
||||
return new RelativeInputReport(0x04);
|
||||
}
|
||||
|
||||
public override void SetPosition(Vector2 pos)
|
||||
{
|
||||
SetCoordinates(pos);
|
||||
Device.Write(ReportBuffer);
|
||||
}
|
||||
|
||||
protected override void SetCoordinates(Vector2 pos)
|
||||
{
|
||||
ReportPointer->X = (byte)pos.X;
|
||||
ReportPointer->Y = (byte)pos.Y;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,9 +17,10 @@ namespace VoiDPlugins.OutputMode
|
|||
{ "Middle", 4 }
|
||||
};
|
||||
|
||||
public static string[] ValidButtons { get; } = Bindings.Keys.ToArray();
|
||||
|
||||
[Property("Button"), PropertyValidated(nameof(ValidButtons))]
|
||||
public string Button { get; set; }
|
||||
public static string[] ValidButtons => Bindings.Keys.ToArray();
|
||||
|
||||
public void Press(IDeviceReport report)
|
||||
{
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System.Numerics;
|
||||
using OpenTabletDriver.Plugin.Platform.Display;
|
||||
using OpenTabletDriver.Plugin.Platform.Pointer;
|
||||
using VoiDPlugins.Library.VMulti;
|
||||
|
@ -5,17 +6,28 @@ using VoiDPlugins.Library.VMulti.Device;
|
|||
|
||||
namespace VoiDPlugins.OutputMode
|
||||
{
|
||||
public class WinInkAbsolutePointer : BasePointer<DigitizerInputReport>, IVirtualTablet
|
||||
public unsafe class WinInkAbsolutePointer : BasePointer<DigitizerInputReport>, IVirtualTablet
|
||||
{
|
||||
public WinInkAbsolutePointer(IVirtualScreen screen) : base(screen, 0x05, "WindowsInk")
|
||||
public WinInkAbsolutePointer(IVirtualScreen screen) : base(screen, "WindowsInk")
|
||||
{
|
||||
WinInkButtonHandler.SetReport(Report);
|
||||
WinInkButtonHandler.SetReport(ReportPointer, ReportBuffer);
|
||||
WinInkButtonHandler.SetDevice(Device);
|
||||
}
|
||||
|
||||
public void SetPressure(float percentage)
|
||||
{
|
||||
Report.Pressure = (ushort)(percentage * 8191);
|
||||
ReportPointer->Pressure = (ushort)(percentage * 8191);
|
||||
}
|
||||
|
||||
protected override DigitizerInputReport CreateReport()
|
||||
{
|
||||
return new DigitizerInputReport(0x05);
|
||||
}
|
||||
|
||||
protected override void SetCoordinates(Vector2 pos)
|
||||
{
|
||||
ReportPointer->X = (ushort)pos.X;
|
||||
ReportPointer->Y = (ushort)pos.Y;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,14 +6,14 @@ using VoiDPlugins.Library.VMulti.Device;
|
|||
|
||||
namespace VoiDPlugins.OutputMode
|
||||
{
|
||||
public class WinInkRelativePointer : BasePointer<DigitizerInputReport>, IVirtualTablet
|
||||
public unsafe class WinInkRelativePointer : BasePointer<DigitizerInputReport>, IVirtualTablet
|
||||
{
|
||||
private Vector2 maxPoint;
|
||||
private Vector2 currentPoint;
|
||||
|
||||
public WinInkRelativePointer(IVirtualScreen screen) : base(screen, 0x05, "WindowsInk")
|
||||
public WinInkRelativePointer(IVirtualScreen screen) : base(screen, "WindowsInk")
|
||||
{
|
||||
WinInkButtonHandler.SetReport(Report);
|
||||
WinInkButtonHandler.SetReport(ReportPointer, ReportBuffer);
|
||||
WinInkButtonHandler.SetDevice(Device);
|
||||
maxPoint = new Vector2(VirtualScreen.Width, VirtualScreen.Height);
|
||||
currentPoint = maxPoint / 2;
|
||||
|
@ -21,7 +21,7 @@ namespace VoiDPlugins.OutputMode
|
|||
|
||||
public void SetPressure(float percentage)
|
||||
{
|
||||
Report.Pressure = (ushort)(percentage * 8191);
|
||||
ReportPointer->Pressure = (ushort)(percentage * 8191);
|
||||
}
|
||||
|
||||
public override void Translate(Vector2 delta)
|
||||
|
@ -29,5 +29,16 @@ namespace VoiDPlugins.OutputMode
|
|||
currentPoint = Vector2.Clamp(currentPoint + delta, Vector2.Zero, maxPoint);
|
||||
base.SetPosition(currentPoint);
|
||||
}
|
||||
|
||||
protected override DigitizerInputReport CreateReport()
|
||||
{
|
||||
return new DigitizerInputReport(0x05);
|
||||
}
|
||||
|
||||
protected override void SetCoordinates(Vector2 pos)
|
||||
{
|
||||
ReportPointer->X = (ushort)pos.X;
|
||||
ReportPointer->Y = (ushort)pos.Y;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@ using VoiDPlugins.Library.VMulti.Device;
|
|||
namespace VoiDPlugins.OutputMode
|
||||
{
|
||||
[PluginName("Windows Ink")]
|
||||
public class WinInkButtonHandler : ButtonHandler, IBinding
|
||||
public unsafe class WinInkButtonHandler : ButtonHandler, IBinding
|
||||
{
|
||||
public static string[] ValidButtons { get; } = new string[]
|
||||
{
|
||||
|
@ -32,7 +32,6 @@ namespace VoiDPlugins.OutputMode
|
|||
|
||||
private bool EraserState;
|
||||
private static HidStream Device;
|
||||
private static new DigitizerInputReport Report;
|
||||
|
||||
public void Press(IDeviceReport report)
|
||||
{
|
||||
|
@ -95,35 +94,35 @@ namespace VoiDPlugins.OutputMode
|
|||
|
||||
private void EraserStateTransition()
|
||||
{
|
||||
var buttons = Report.Buttons;
|
||||
var pressure = Report.Pressure;
|
||||
var Report = (DigitizerInputReport*)ReportPointer;
|
||||
var buttons = Report->Header.Buttons;
|
||||
var pressure = Report->Pressure;
|
||||
|
||||
// Send In-Range but no tips
|
||||
DisableBit((int)ButtonBits.Press);
|
||||
DisableBit((int)ButtonBits.Eraser);
|
||||
Report.Pressure = 0;
|
||||
Device.Write(Report.ToBytes());
|
||||
Report->Pressure = 0;
|
||||
Device.Write(ReportBuffer);
|
||||
|
||||
// Send Out-Of-Range
|
||||
Report.Buttons = 0;
|
||||
Device.Write(Report.ToBytes());
|
||||
Report->Header.Buttons = 0;
|
||||
Device.Write(ReportBuffer);
|
||||
|
||||
// Send In-Range but no tips
|
||||
EnableBit((int)ButtonBits.InRange);
|
||||
if (EraserState)
|
||||
EnableBit((int)ButtonBits.Invert);
|
||||
|
||||
Device.Write(Report.ToBytes());
|
||||
Device.Write(ReportBuffer);
|
||||
|
||||
// Send Proper Report
|
||||
Report.Buttons = buttons;
|
||||
Report.Pressure = pressure;
|
||||
Report->Header.Buttons = buttons;
|
||||
Report->Pressure = pressure;
|
||||
}
|
||||
|
||||
public static void SetReport(DigitizerInputReport Report)
|
||||
public static void SetReport(DigitizerInputReport* report, byte[] reportBuffer)
|
||||
{
|
||||
ButtonHandler.SetReport(Report);
|
||||
WinInkButtonHandler.Report = Report;
|
||||
ButtonHandler.SetReport((VMultiReportHeader*)report, reportBuffer);
|
||||
EnableBit((int)ButtonBits.InRange);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,29 +1,31 @@
|
|||
using System;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using HidSharp;
|
||||
using OpenTabletDriver.Plugin.Attributes;
|
||||
using OpenTabletDriver.Plugin.DependencyInjection;
|
||||
using OpenTabletDriver.Plugin.Platform.Display;
|
||||
using OpenTabletDriver.Plugin.Platform.Pointer;
|
||||
using VoiDPlugins.Library.VMulti.Device;
|
||||
|
||||
namespace VoiDPlugins.Library.VMulti
|
||||
{
|
||||
[PluginIgnore]
|
||||
public abstract class BasePointer<T> : IAbsolutePointer, IRelativePointer where T : Report, new()
|
||||
public abstract unsafe class BasePointer<T> : IAbsolutePointer, IRelativePointer where T : unmanaged
|
||||
{
|
||||
public T Report;
|
||||
protected readonly byte[] ReportBuffer;
|
||||
protected readonly T* ReportPointer;
|
||||
protected readonly HidStream Device;
|
||||
protected IVirtualScreen VirtualScreen;
|
||||
|
||||
private Vector2 ScreenToVMulti;
|
||||
private Vector2 error;
|
||||
|
||||
public BasePointer(IVirtualScreen screen, byte ReportID, string Name)
|
||||
public BasePointer(IVirtualScreen screen, string Name)
|
||||
{
|
||||
Report = new T
|
||||
{
|
||||
ReportID = ReportID
|
||||
};
|
||||
ReportBuffer = GC.AllocateArray<byte>(Unsafe.SizeOf<T>(), pinned: true);
|
||||
ReportPointer = (T*)Unsafe.AsPointer(ref ReportBuffer[0]);
|
||||
|
||||
T report = CreateReport();
|
||||
*ReportPointer = report;
|
||||
|
||||
VirtualScreen = screen;
|
||||
Device = VMultiDevice.Retrieve(Name);
|
||||
|
@ -36,10 +38,13 @@ namespace VoiDPlugins.Library.VMulti
|
|||
return pos / ScreenToVMulti;
|
||||
}
|
||||
|
||||
protected abstract T CreateReport();
|
||||
protected abstract void SetCoordinates(Vector2 pos);
|
||||
|
||||
public virtual void SetPosition(Vector2 pos)
|
||||
{
|
||||
Report.SetCoordinates(Convert(pos));
|
||||
Device.Write(Report.ToBytes());
|
||||
SetCoordinates(Convert(pos));
|
||||
Device.Write(ReportBuffer);
|
||||
}
|
||||
|
||||
public virtual void Translate(Vector2 delta)
|
||||
|
@ -47,8 +52,8 @@ namespace VoiDPlugins.Library.VMulti
|
|||
delta += error;
|
||||
error = new Vector2(delta.X % 1, delta.Y % 1);
|
||||
|
||||
Report.SetCoordinates(delta);
|
||||
Device.Write(Report.ToBytes());
|
||||
SetCoordinates(delta);
|
||||
Device.Write(ReportBuffer);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,23 +4,25 @@ using VoiDPlugins.Library.VMulti.Device;
|
|||
namespace VoiDPlugins.Library.VMulti
|
||||
{
|
||||
[PluginIgnore]
|
||||
public class ButtonHandler
|
||||
public unsafe class ButtonHandler
|
||||
{
|
||||
protected static Report Report;
|
||||
protected static byte[] ReportBuffer;
|
||||
protected static VMultiReportHeader* ReportPointer;
|
||||
|
||||
public static void SetReport(Report report)
|
||||
public static void SetReport(VMultiReportHeader* report, byte[] reportBuffer)
|
||||
{
|
||||
Report = report;
|
||||
ReportBuffer = reportBuffer;
|
||||
ReportPointer = report;
|
||||
}
|
||||
|
||||
public static void EnableBit(int bit)
|
||||
{
|
||||
Report.Buttons = (byte)(Report.Buttons | bit);
|
||||
ReportPointer->Buttons = (byte)(ReportPointer->Buttons | bit);
|
||||
}
|
||||
|
||||
public static void DisableBit(int bit)
|
||||
{
|
||||
Report.Buttons = (byte)(Report.Buttons & ~bit);
|
||||
ReportPointer->Buttons = (byte)(ReportPointer->Buttons & ~bit);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,35 +1,22 @@
|
|||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace VoiDPlugins.Library.VMulti.Device
|
||||
{
|
||||
public class AbsoluteInputReport : Report
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct AbsoluteInputReport
|
||||
{
|
||||
public AbsoluteInputReport(byte reportID)
|
||||
{
|
||||
Header = new VMultiReportHeader(Unsafe.SizeOf<AbsoluteInputReport>(), reportID);
|
||||
X = 0;
|
||||
Y = 0;
|
||||
Pressure = 0;
|
||||
}
|
||||
|
||||
public VMultiReportHeader Header;
|
||||
public ushort X; // X position of the mouse from 0 to 32767
|
||||
public ushort Y; // Y position of the mouse from 0 to 32767
|
||||
public ushort Pressure; // Pressure of the mouse? from 0 to 8191
|
||||
|
||||
public override byte[] ToBytes()
|
||||
{
|
||||
var bytes = new byte[Size];
|
||||
bytes[0] = VMultiID;
|
||||
bytes[1] = ReportLength;
|
||||
bytes[2] = ReportID;
|
||||
bytes[3] = Buttons;
|
||||
bytes[4] = (byte)(X & 0xFF);
|
||||
bytes[5] = (byte)((X & 0xFF00) >> 8);
|
||||
bytes[6] = (byte)(Y & 0xFF);
|
||||
bytes[7] = (byte)((Y & 0xFF00) >> 8);
|
||||
bytes[8] = (byte)(Pressure & 0xFF);
|
||||
bytes[9] = (byte)((Pressure & 0xFF00) >> 8);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public override void SetCoordinates(Vector2 coordinates)
|
||||
{
|
||||
X = (ushort)coordinates.X;
|
||||
Y = (ushort)coordinates.Y;
|
||||
}
|
||||
|
||||
public override byte Size => 10;
|
||||
}
|
||||
}
|
|
@ -1,38 +1,26 @@
|
|||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace VoiDPlugins.Library.VMulti.Device
|
||||
{
|
||||
public sealed class DigitizerInputReport : Report
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct DigitizerInputReport
|
||||
{
|
||||
public DigitizerInputReport(byte reportID)
|
||||
{
|
||||
Header = new VMultiReportHeader(Unsafe.SizeOf<DigitizerInputReport>(), reportID);
|
||||
X = 0;
|
||||
Y = 0;
|
||||
Pressure = 0;
|
||||
XTilt = 0;
|
||||
YTilt = 0;
|
||||
}
|
||||
|
||||
public VMultiReportHeader Header;
|
||||
public ushort X; // X position of the pen from 0 to 32767
|
||||
public ushort Y; // Y position of the pen from 0 to 32767
|
||||
public ushort Pressure; // Pressure level from 0 to 8191
|
||||
public byte XTilt; // X tilt of the pen from -127 to 127
|
||||
public byte YTilt; // Y tilt of the pen from -127 to 127
|
||||
|
||||
private byte[] bytes = new byte[12];
|
||||
|
||||
public override byte[] ToBytes()
|
||||
{
|
||||
Unsafe.WriteUnaligned(ref bytes[0], VMultiID);
|
||||
Unsafe.WriteUnaligned(ref bytes[1], ReportLength);
|
||||
Unsafe.WriteUnaligned(ref bytes[2], ReportID);
|
||||
Unsafe.WriteUnaligned(ref bytes[3], Buttons);
|
||||
Unsafe.WriteUnaligned(ref bytes[4], X);
|
||||
Unsafe.WriteUnaligned(ref bytes[6], Y);
|
||||
Unsafe.WriteUnaligned(ref bytes[8], Pressure);
|
||||
Unsafe.WriteUnaligned(ref bytes[10], XTilt);
|
||||
Unsafe.WriteUnaligned(ref bytes[11], YTilt);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public override void SetCoordinates(Vector2 coordinates)
|
||||
{
|
||||
X = (ushort)coordinates.X;
|
||||
Y = (ushort)coordinates.Y;
|
||||
}
|
||||
|
||||
public override byte Size => 12;
|
||||
}
|
||||
}
|
|
@ -1,32 +1,20 @@
|
|||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace VoiDPlugins.Library.VMulti.Device
|
||||
{
|
||||
public class RelativeInputReport : Report
|
||||
public struct RelativeInputReport
|
||||
{
|
||||
public RelativeInputReport(byte reportID)
|
||||
{
|
||||
Header = new VMultiReportHeader(Unsafe.SizeOf<RelativeInputReport>(), reportID);
|
||||
X = 0;
|
||||
Y = 0;
|
||||
WheelPos = 0;
|
||||
}
|
||||
|
||||
public VMultiReportHeader Header;
|
||||
public byte X; // X position of the mouse from -127 to 127
|
||||
public byte Y; // Y position of the mouse from -127 to 127
|
||||
public byte WheelPos; // Wheel position of the mouse from -127 to 127
|
||||
|
||||
public override byte[] ToBytes()
|
||||
{
|
||||
var bytes = new byte[Size];
|
||||
bytes[0] = VMultiID;
|
||||
bytes[1] = ReportLength;
|
||||
bytes[2] = ReportID;
|
||||
bytes[3] = Buttons;
|
||||
bytes[4] = X;
|
||||
bytes[5] = Y;
|
||||
bytes[6] = WheelPos;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public override void SetCoordinates(Vector2 coordinates)
|
||||
{
|
||||
X = (byte)coordinates.X;
|
||||
Y = (byte)coordinates.Y;
|
||||
}
|
||||
|
||||
public override byte Size => 7;
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
using System.Numerics;
|
||||
|
||||
namespace VoiDPlugins.Library.VMulti.Device
|
||||
{
|
||||
public abstract class Report
|
||||
{
|
||||
public byte VMultiID = 0x40;
|
||||
public byte ReportID;
|
||||
public byte Buttons;
|
||||
public byte ReportLength => (byte)(Size - 1);
|
||||
public abstract byte Size { get; }
|
||||
public abstract byte[] ToBytes();
|
||||
public abstract void SetCoordinates(Vector2 coordinates);
|
||||
}
|
||||
}
|
21
VoiDPlugins.Library/VMulti/Device/VMultiReportHeader.cs
Normal file
21
VoiDPlugins.Library/VMulti/Device/VMultiReportHeader.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace VoiDPlugins.Library.VMulti.Device
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct VMultiReportHeader
|
||||
{
|
||||
public VMultiReportHeader(int size, byte reportID)
|
||||
{
|
||||
VMultiID = 0x40;
|
||||
ReportLength = (byte)(size - 1);
|
||||
ReportID = reportID;
|
||||
Buttons = 0;
|
||||
}
|
||||
|
||||
public byte VMultiID;
|
||||
public byte ReportLength;
|
||||
public byte ReportID;
|
||||
public byte Buttons;
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net5</TargetFrameworks>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||
|
|
Loading…
Add table
Reference in a new issue