diff --git a/.modules/Directory.Build.props b/.modules/Directory.Build.props
new file mode 100644
index 0000000..c1df222
--- /dev/null
+++ b/.modules/Directory.Build.props
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/.modules/Directory.Build.targets b/.modules/Directory.Build.targets
new file mode 100644
index 0000000..c1df222
--- /dev/null
+++ b/.modules/Directory.Build.targets
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/.modules/OpenTabletDriver b/.modules/OpenTabletDriver
index 267a322..78e9d03 160000
--- a/.modules/OpenTabletDriver
+++ b/.modules/OpenTabletDriver
@@ -1 +1 @@
-Subproject commit 267a32282ad5462a5be254e74f60edeba809831f
+Subproject commit 78e9d03766e61f986d3b510dfd3b23c74917d895
diff --git a/Binding/ScriptRunner/ScriptRunner.cs b/Binding/ScriptRunner/ScriptRunner.cs
index 13eda4d..412b956 100644
--- a/Binding/ScriptRunner/ScriptRunner.cs
+++ b/Binding/ScriptRunner/ScriptRunner.cs
@@ -1,6 +1,5 @@
-using System.Collections.Generic;
+using System;
using System.Diagnostics;
-using System.Linq;
using OpenTabletDriver.Plugin;
using OpenTabletDriver.Plugin.Attributes;
using OpenTabletDriver.Plugin.Tablet;
@@ -10,82 +9,8 @@ namespace VoiDPlugins.Binding.ScriptRunner
[PluginName("Script Runner")]
public class ScriptRunner : IStateBinding
{
- public static string[] ValidIndexes = Enumerable.Range(0, 10).Select(i => i.ToString()).ToArray();
-
- private List ScriptPathList = new List(10);
-
- [Property("Script Index"), PropertyValidated(nameof(ValidIndexes))]
- public string ScriptIndex { set; get; }
-
- [Property("Script Path 0")]
- public string ScriptPath0
- {
- get => ScriptPathList[0];
- set => ScriptPathList[0] = value;
- }
-
- [Property("Script Path 1")]
- public string ScriptPath1
- {
- get => ScriptPathList[1];
- set => ScriptPathList[1] = value;
- }
-
- [Property("Script Path 2")]
- public string ScriptPath2
- {
- get => ScriptPathList[2];
- set => ScriptPathList[2] = value;
- }
-
- [Property("Script Path 3")]
- public string ScriptPath3
- {
- get => ScriptPathList[3];
- set => ScriptPathList[3] = value;
- }
-
- [Property("Script Path 4")]
- public string ScriptPath4
- {
- get => ScriptPathList[4];
- set => ScriptPathList[4] = value;
- }
-
- [Property("Script Path 5")]
- public string ScriptPath5
- {
- get => ScriptPathList[5];
- set => ScriptPathList[5] = value;
- }
-
- [Property("Script Path 6")]
- public string ScriptPath6
- {
- get => ScriptPathList[6];
- set => ScriptPathList[6] = value;
- }
-
- [Property("Script Path 7")]
- public string ScriptPath7
- {
- get => ScriptPathList[7];
- set => ScriptPathList[7] = value;
- }
-
- [Property("Script Path 8")]
- public string ScriptPath8
- {
- get => ScriptPathList[8];
- set => ScriptPathList[8] = value;
- }
-
- [Property("Script Path 9")]
- public string ScriptPath9
- {
- get => ScriptPathList[9];
- set => ScriptPathList[9] = value;
- }
+ [Property("Run")]
+ public string? Script { get; set; }
public void Press(TabletReference tablet, IDeviceReport report)
{
@@ -93,14 +18,17 @@ namespace VoiDPlugins.Binding.ScriptRunner
{
var process = new Process
{
- StartInfo = new ProcessStartInfo(ScriptPathList[int.Parse(ScriptIndex)])
+ StartInfo = new ProcessStartInfo(Script!)
{
UseShellExecute = true
}
};
process.Start();
}
- catch { }
+ catch (Exception e)
+ {
+ Log.Exception(e);
+ }
}
public void Release(TabletReference tablet, IDeviceReport report)
diff --git a/Binding/ScriptRunner/ScriptRunner.csproj b/Binding/ScriptRunner/ScriptRunner.csproj
index ef87223..bef0383 100644
--- a/Binding/ScriptRunner/ScriptRunner.csproj
+++ b/Binding/ScriptRunner/ScriptRunner.csproj
@@ -1,17 +1,2 @@
-
-
- net5
-
-
-
- none
- false
- false
-
-
-
-
-
-
diff --git a/Directory.Build.props b/Directory.Build.props
new file mode 100644
index 0000000..5bd4b75
--- /dev/null
+++ b/Directory.Build.props
@@ -0,0 +1,12 @@
+
+
+ net6.0
+ true
+ enable
+ 0.3.0
+
+
+
+ embedded
+
+
\ No newline at end of file
diff --git a/Directory.Build.targets b/Directory.Build.targets
new file mode 100644
index 0000000..d6eb2cf
--- /dev/null
+++ b/Directory.Build.targets
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Filter/MeL/Core/MLCore.cs b/Filter/MeL/Core/MLCore.cs
index 2877ff4..cba45c1 100644
--- a/Filter/MeL/Core/MLCore.cs
+++ b/Filter/MeL/Core/MLCore.cs
@@ -1,3 +1,4 @@
+using System.Diagnostics;
using System.Linq;
using System.Numerics;
using MathNet.Numerics;
@@ -8,6 +9,28 @@ namespace VoiDPlugins.Filter.MeL.Core
{
internal partial class MLCore
{
+ private double[]? weights;
+ private Polynomial? xCoeff, yCoeff;
+ private RingBuffer? timeSeriesPoints;
+ private readonly Stopwatch watch = new();
+
+ public bool IsReady { private set; get; }
+
+ private int samples;
+ public int Samples
+ {
+ set
+ {
+ this.timeSeriesPoints = new RingBuffer(value);
+ this.samples = value;
+ }
+ get => this.samples;
+ }
+
+ public int Complexity { set; get; } = 2;
+ public float Weight { set => this.weights = CalcWeight(value).ToArray(); }
+ public double TimeNow { get => watch.Elapsed.TotalMilliseconds; }
+
public MLCore()
{
Weight = 1.4f;
@@ -49,29 +72,61 @@ namespace VoiDPlugins.Filter.MeL.Core
{
var predicted = new Vector2();
double predictAhead;
- predictAhead = TimeNow - this.timeSeriesPoints[0].Elapsed + offset;
+ predictAhead = TimeNow - this.timeSeriesPoints![0].Elapsed + offset;
- predicted.X = (float)this.xCoeff.Evaluate(predictAhead);
- predicted.Y = (float)this.yCoeff.Evaluate(predictAhead);
+ predicted.X = (float)this.xCoeff!.Evaluate(predictAhead);
+ predicted.Y = (float)this.yCoeff!.Evaluate(predictAhead);
return predicted;
}
- public bool IsReady { private set; get; }
-
- private int samples;
- public int Samples
+ private bool AddTimeSeriesPoint(Vector2 point, double elapsed)
{
- set
- {
- this.timeSeriesPoints = new RingBuffer(value);
- this.samples = value;
- }
- get => this.samples;
+ this.timeSeriesPoints!.Insert(new TimeSeriesPoint(point, elapsed));
+ return this.timeSeriesPoints.IsFilled;
}
- public int Complexity { set; get; } = 2;
- public float Weight { set => this.weights = CalcWeight(value).ToArray(); }
- public double TimeNow { get => watch.Elapsed.TotalMilliseconds; }
+ private double[] ConstructTimeDesignMatrix()
+ {
+ var baseTime = this.timeSeriesPoints![0].Elapsed;
+ var data = new double[Samples];
+ var index = 0;
+ foreach (var timePoint in this.timeSeriesPoints)
+ data[index++] = timePoint.Elapsed - baseTime;
+
+ return data;
+ }
+
+ private double[] ConstructTargetMatrix(Axis axis)
+ {
+ var points = new double[Samples];
+ var index = 0;
+
+ switch (axis)
+ {
+ case Axis.X:
+ foreach (var timePoint in timeSeriesPoints!)
+ points[index++] = timePoint.Point.X;
+ break;
+ case Axis.Y:
+ foreach (var timePoint in timeSeriesPoints!)
+ points[index++] = timePoint.Point.Y;
+ break;
+ }
+
+ return points;
+ }
+
+ private double[] CalcWeight(double ratio)
+ {
+ var weights = new double[Samples];
+ var weightsNormalized = new double[Samples];
+ double weight = 1;
+ for (int i = 0; i < Samples; i++)
+ weights[i] = weight *= ratio;
+ for (int i = 0; i < Samples; i++)
+ weightsNormalized[i] = weights[i] / weights[^1];
+ return weightsNormalized;
+ }
}
}
\ No newline at end of file
diff --git a/Filter/MeL/Core/MLCorePriv.cs b/Filter/MeL/Core/MLCorePriv.cs
deleted file mode 100644
index d76ba1f..0000000
--- a/Filter/MeL/Core/MLCorePriv.cs
+++ /dev/null
@@ -1,64 +0,0 @@
-using System.Diagnostics;
-using System.Numerics;
-using MathNet.Numerics;
-using VoiDPlugins.Library;
-
-namespace VoiDPlugins.Filter.MeL.Core
-{
- internal partial class MLCore
- {
- private double[] weights;
- private Polynomial xCoeff, yCoeff;
- private RingBuffer timeSeriesPoints;
- private readonly Stopwatch watch = new();
-
- private bool AddTimeSeriesPoint(Vector2 point, double elapsed)
- {
- this.timeSeriesPoints.Insert(new TimeSeriesPoint(point, elapsed));
- return this.timeSeriesPoints.IsFilled;
- }
-
- private double[] ConstructTimeDesignMatrix()
- {
- var baseTime = this.timeSeriesPoints[0].Elapsed;
- var data = new double[Samples];
- var index = 0;
- foreach (var timePoint in this.timeSeriesPoints)
- data[index++] = timePoint.Elapsed - baseTime;
-
- return data;
- }
-
- private double[] ConstructTargetMatrix(Axis axis)
- {
- var points = new double[Samples];
- var index = 0;
-
- switch (axis)
- {
- case Axis.X:
- foreach (var timePoint in timeSeriesPoints)
- points[index++] = timePoint.Point.X;
- break;
- case Axis.Y:
- foreach (var timePoint in timeSeriesPoints)
- points[index++] = timePoint.Point.Y;
- break;
- }
-
- return points;
- }
-
- private double[] CalcWeight(double ratio)
- {
- var weights = new double[Samples];
- var weightsNormalized = new double[Samples];
- double weight = 1;
- for (int i = 0; i < Samples; i++)
- weights[i] = weight *= ratio;
- for (int i = 0; i < Samples; i++)
- weightsNormalized[i] = weights[i] / weights[^1];
- return weightsNormalized;
- }
- }
-}
\ No newline at end of file
diff --git a/Filter/MeL/Filter/MeLFilter.cs b/Filter/MeL/Filter/MeLFilter.cs
index fd9bc94..53c015e 100644
--- a/Filter/MeL/Filter/MeLFilter.cs
+++ b/Filter/MeL/Filter/MeLFilter.cs
@@ -10,10 +10,10 @@ namespace VoiDPlugins.Filter.MeL
[PluginName("MeL Filter")]
public class MeLFilter : IPositionedPipelineElement
{
- private readonly MLCore Core = new MLCore();
+ private readonly MLCore Core = new();
private bool rateLimit;
- public event Action Emit;
+ public event Action? Emit;
public PipelinePosition Position => PipelinePosition.PostTransform;
diff --git a/Filter/MeL/MeL.csproj b/Filter/MeL/MeL.csproj
index a743c8f..bc942a5 100644
--- a/Filter/MeL/MeL.csproj
+++ b/Filter/MeL/MeL.csproj
@@ -1,19 +1,9 @@
-
- net5
-
-
-
- none
- false
- false
+ true
-
-
-
diff --git a/Filter/PrecisionControl/PrecisionControl.cs b/Filter/PrecisionControl/PrecisionControl.cs
index 64189ae..de80474 100644
--- a/Filter/PrecisionControl/PrecisionControl.cs
+++ b/Filter/PrecisionControl/PrecisionControl.cs
@@ -17,7 +17,7 @@ namespace VoiDPlugins.Filter
public static string[] ValidModes => new[] { "Toggle", "Hold" };
[Property("Mode"), PropertyValidated(nameof(ValidModes))]
- public string Mode { set; get; }
+ public string? Mode { set; get; }
public void Press(TabletReference tablet, IDeviceReport report)
{
@@ -39,7 +39,7 @@ namespace VoiDPlugins.Filter
[PluginName("Precision Control")]
public class PrecisionControl : IPositionedPipelineElement
{
- public event Action Emit;
+ public event Action? Emit;
[SliderProperty("Precision Multiplier", 0.0f, 10f, 0.3f), DefaultPropertyValue(0.3f)]
public float Scale { get; set; }
diff --git a/Filter/PrecisionControl/PrecisionControl.csproj b/Filter/PrecisionControl/PrecisionControl.csproj
index 36deb4c..bef0383 100644
--- a/Filter/PrecisionControl/PrecisionControl.csproj
+++ b/Filter/PrecisionControl/PrecisionControl.csproj
@@ -1,18 +1,2 @@
-
-
- net5
- true
-
-
-
- none
- false
- false
-
-
-
-
-
-
diff --git a/Filter/Reconstructor/Reconstructor.cs b/Filter/Reconstructor/Reconstructor.cs
index ad18aa5..c1e132b 100644
--- a/Filter/Reconstructor/Reconstructor.cs
+++ b/Filter/Reconstructor/Reconstructor.cs
@@ -25,7 +25,7 @@ namespace VoiDPlugins.Filter
get => weight;
}
- public event Action Emit;
+ public event Action? Emit;
public PipelinePosition Position => PipelinePosition.PreTransform;
diff --git a/Filter/Reconstructor/Reconstructor.csproj b/Filter/Reconstructor/Reconstructor.csproj
index 9019b32..25bef7b 100644
--- a/Filter/Reconstructor/Reconstructor.csproj
+++ b/Filter/Reconstructor/Reconstructor.csproj
@@ -1,18 +1,5 @@
-
- net5
+ true
-
-
- none
- false
- false
-
-
-
-
-
-
-
diff --git a/OutputMode/TouchEmu/NativeMethods.cs b/OutputMode/TouchEmu/NativeMethods.cs
index 6043a86..ac112c3 100644
--- a/OutputMode/TouchEmu/NativeMethods.cs
+++ b/OutputMode/TouchEmu/NativeMethods.cs
@@ -1,4 +1,5 @@
using System;
+using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
namespace VoiDPlugins.OutputMode
@@ -165,7 +166,7 @@ namespace VoiDPlugins.OutputMode
[DllImport("user32.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.Bool)]
- public static unsafe extern bool GetPointerDevices(out uint deviceCount, [In, Out, MarshalAs(UnmanagedType.LPArray)] POINTER_DEVICE_INFO[] pointerDevices);
+ public static unsafe extern bool GetPointerDevices(out uint deviceCount, [In, Out, MarshalAs(UnmanagedType.LPArray), AllowNull] POINTER_DEVICE_INFO[] pointerDevices);
[DllImport("user32.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr GetForegroundWindow();
diff --git a/OutputMode/TouchEmu/Touch.cs b/OutputMode/TouchEmu/Touch.cs
index 5609586..33edeee 100644
--- a/OutputMode/TouchEmu/Touch.cs
+++ b/OutputMode/TouchEmu/Touch.cs
@@ -6,7 +6,7 @@ namespace VoiDPlugins.OutputMode
public static class Touch
{
private static IntPtr _penHandle;
- private static POINTER_TYPE_INFO[] pointer;
+ private static POINTER_TYPE_INFO[]? pointer;
private static uint _pointerId;
private static IntPtr _sourceDevice;
@@ -79,7 +79,7 @@ namespace VoiDPlugins.OutputMode
public static void Inject()
{
- if (!NativeMethods.InjectSyntheticPointerInput(_penHandle, pointer, 1))
+ if (!NativeMethods.InjectSyntheticPointerInput(_penHandle, pointer!, 1))
{
throw new Exception($"Input injection failed. Reason: {Marshal.GetLastWin32Error()}");
}
@@ -87,38 +87,38 @@ namespace VoiDPlugins.OutputMode
public static void SetTarget()
{
- pointer[0].penInfo.pointerInfo.hwndTarget = NativeMethods.GetForegroundWindow();
+ pointer![0].penInfo.pointerInfo.hwndTarget = NativeMethods.GetForegroundWindow();
}
public static void SetPosition(POINT point)
{
- pointer[0].penInfo.pointerInfo.ptPixelLocation = point;
+ pointer![0].penInfo.pointerInfo.ptPixelLocation = point;
pointer[0].penInfo.pointerInfo.ptPixelLocationRaw = point;
}
public static void SetPressure(uint pressure)
{
- pointer[0].penInfo.pressure = pressure;
+ pointer![0].penInfo.pressure = pressure;
}
public static void SetPointerFlags(POINTER_FLAGS flags)
{
- pointer[0].penInfo.pointerInfo.pointerFlags |= flags;
+ pointer![0].penInfo.pointerInfo.pointerFlags |= flags;
}
public static void UnsetPointerFlags(POINTER_FLAGS flags)
{
- pointer[0].penInfo.pointerInfo.pointerFlags &= ~flags;
+ pointer![0].penInfo.pointerInfo.pointerFlags &= ~flags;
}
public static void ClearPointerFlags()
{
- pointer[0].penInfo.pointerInfo.pointerFlags = 0;
+ pointer![0].penInfo.pointerInfo.pointerFlags = 0;
}
public static void ClearPointerFlags(POINTER_FLAGS flags)
{
- pointer[0].penInfo.pointerInfo.pointerFlags = flags;
+ pointer![0].penInfo.pointerInfo.pointerFlags = flags;
}
}
}
diff --git a/OutputMode/TouchEmu/TouchEmu.csproj b/OutputMode/TouchEmu/TouchEmu.csproj
index 36deb4c..05d1625 100644
--- a/OutputMode/TouchEmu/TouchEmu.csproj
+++ b/OutputMode/TouchEmu/TouchEmu.csproj
@@ -1,18 +1,5 @@
-
- net5
- true
+ true
-
-
- none
- false
- false
-
-
-
-
-
-
diff --git a/OutputMode/TouchEmu/TouchPointerHandler.cs b/OutputMode/TouchEmu/TouchPointerHandler.cs
index ef97d0a..f6d17d1 100644
--- a/OutputMode/TouchEmu/TouchPointerHandler.cs
+++ b/OutputMode/TouchEmu/TouchPointerHandler.cs
@@ -3,7 +3,7 @@ using OpenTabletDriver.Plugin.Platform.Pointer;
namespace VoiDPlugins.OutputMode
{
- public class TouchPointerHandler : IAbsolutePointer, IVirtualTablet
+ public class TouchPointerHandler : IAbsolutePointer, IPressureHandler
{
private bool _inContact;
private bool _lastContact;
@@ -15,16 +15,6 @@ namespace VoiDPlugins.OutputMode
_lastContact = false;
}
- public void SetButtonState(uint button, bool active)
- {
- return;
- }
-
- public void SetEraser(bool isEraser)
- {
- return;
- }
-
public void SetPosition(Vector2 pos)
{
Touch.SetPosition(new POINT((int)pos.X, (int)pos.Y));
@@ -67,15 +57,5 @@ namespace VoiDPlugins.OutputMode
_inContact = false;
}
}
-
- public void SetProximity(bool proximity, uint distance)
- {
- return;
- }
-
- public void SetTilt(Vector2 tilt)
- {
- return;
- }
}
}
\ No newline at end of file
diff --git a/OutputMode/VMultiMode/Output/VMultiAbsoluteMode.cs b/OutputMode/VMultiMode/Output/VMultiAbsoluteMode.cs
index 8ccc6d1..04d1008 100644
--- a/OutputMode/VMultiMode/Output/VMultiAbsoluteMode.cs
+++ b/OutputMode/VMultiMode/Output/VMultiAbsoluteMode.cs
@@ -10,12 +10,24 @@ namespace VoiDPlugins.OutputMode
[PluginName("VMulti Absolute Mode")]
public class VMultiAbsoluteMode : AbsoluteOutputMode
{
+ private VMultiAbsolutePointer? _pointer;
+
[Resolved]
public IServiceProvider ServiceProvider
{
- set => Pointer = new VMultiAbsolutePointer((IVirtualScreen)value.GetService(typeof(IVirtualScreen)));
+ set => _pointer = new VMultiAbsolutePointer((IVirtualScreen)value.GetService(typeof(IVirtualScreen))!);
}
- public override IAbsolutePointer Pointer { get; set; }
+ [OnDependencyLoad]
+ public void Initialize()
+ {
+ _pointer!.Initialize(TabletReference);
+ }
+
+ public override IAbsolutePointer Pointer
+ {
+ get => _pointer!;
+ set { }
+ }
}
}
\ No newline at end of file
diff --git a/OutputMode/VMultiMode/Output/VMultiRelativeMode.cs b/OutputMode/VMultiMode/Output/VMultiRelativeMode.cs
index c230fab..9853fb0 100644
--- a/OutputMode/VMultiMode/Output/VMultiRelativeMode.cs
+++ b/OutputMode/VMultiMode/Output/VMultiRelativeMode.cs
@@ -1,8 +1,6 @@
-using System;
using OpenTabletDriver.Plugin.Attributes;
using OpenTabletDriver.Plugin.DependencyInjection;
using OpenTabletDriver.Plugin.Output;
-using OpenTabletDriver.Plugin.Platform.Display;
using OpenTabletDriver.Plugin.Platform.Pointer;
namespace VoiDPlugins.OutputMode
@@ -10,12 +8,19 @@ namespace VoiDPlugins.OutputMode
[PluginName("VMulti Relative Mode")]
public class VMultiRelativeMode : RelativeOutputMode
{
- [Resolved]
- public IServiceProvider ServiceProvider
+ private VMultiRelativePointer? _pointer;
+
+ [OnDependencyLoad]
+ public void Initialize()
{
- set => Pointer = new VMultiRelativePointer((IVirtualScreen)value.GetService(typeof(IVirtualScreen)));
+ _pointer = new VMultiRelativePointer();
+ _pointer!.Initialize(TabletReference);
}
- public override IRelativePointer Pointer { get; set; }
+ public override IRelativePointer Pointer
+ {
+ get => _pointer!;
+ set { }
+ }
}
}
\ No newline at end of file
diff --git a/OutputMode/VMultiMode/Pointer/VMultiAbsolutePointer.cs b/OutputMode/VMultiMode/Pointer/VMultiAbsolutePointer.cs
index 8c1371f..b7f6196 100644
--- a/OutputMode/VMultiMode/Pointer/VMultiAbsolutePointer.cs
+++ b/OutputMode/VMultiMode/Pointer/VMultiAbsolutePointer.cs
@@ -1,27 +1,43 @@
using System.Numerics;
using OpenTabletDriver.Plugin.Platform.Display;
using OpenTabletDriver.Plugin.Platform.Pointer;
+using OpenTabletDriver.Plugin.Tablet;
using VoiDPlugins.Library.VMulti;
using VoiDPlugins.Library.VMulti.Device;
namespace VoiDPlugins.OutputMode
{
- public unsafe class VMultiAbsolutePointer : BasePointer, IAbsolutePointer
+ public unsafe class VMultiAbsolutePointer : IAbsolutePointer, ISynchronousPointer
{
- public VMultiAbsolutePointer(IVirtualScreen screen) : base(screen, "VMultiAbs")
+ private AbsoluteInputReport* _rawPointer;
+ private VMultiInstance? _instance;
+ private Vector2 _conversionFactor;
+
+ public VMultiAbsolutePointer(IVirtualScreen virtualScreen)
{
- ButtonHandler.SetReport((VMultiReportHeader*)ReportPointer, ReportBuffer);
+ _conversionFactor = new Vector2(virtualScreen.Width, virtualScreen.Height) / (1 / 32767);
}
- protected override AbsoluteInputReport CreateReport()
+ public void Initialize(TabletReference tabletReference)
{
- return new AbsoluteInputReport(0x09);
+ _instance = VMultiInstanceManager.RetrieveVMultiInstance("VMultiAbs", tabletReference, () => new AbsoluteInputReport());
+ _rawPointer = _instance.Pointer;
}
- protected override void SetCoordinates(Vector2 pos)
+ public void SetPosition(Vector2 pos)
{
- ReportPointer->X = (ushort)pos.X;
- ReportPointer->Y = (ushort)pos.Y;
+ pos *= _conversionFactor;
+ _rawPointer->X = (ushort)pos.X;
+ _rawPointer->Y = (ushort)pos.Y;
+ }
+
+ public void Reset()
+ {
+ }
+
+ public void Flush()
+ {
+ _instance!.Write();
}
}
}
\ No newline at end of file
diff --git a/OutputMode/VMultiMode/Pointer/VMultiRelativePointer.cs b/OutputMode/VMultiMode/Pointer/VMultiRelativePointer.cs
index b742438..686a03b 100644
--- a/OutputMode/VMultiMode/Pointer/VMultiRelativePointer.cs
+++ b/OutputMode/VMultiMode/Pointer/VMultiRelativePointer.cs
@@ -1,33 +1,38 @@
using System.Numerics;
-using OpenTabletDriver.Plugin.Platform.Display;
using OpenTabletDriver.Plugin.Platform.Pointer;
+using OpenTabletDriver.Plugin.Tablet;
using VoiDPlugins.Library.VMulti;
using VoiDPlugins.Library.VMulti.Device;
namespace VoiDPlugins.OutputMode
{
- public unsafe class VMultiRelativePointer : BasePointer, IRelativePointer
+ public unsafe class VMultiRelativePointer : IRelativePointer, ISynchronousPointer
{
- public VMultiRelativePointer(IVirtualScreen screen) : base(screen, "VMultiRel")
+ private RelativeInputReport* _rawPointer;
+ private VMultiInstance? _instance;
+ private Vector2 _error;
+
+ public void Initialize(TabletReference tabletReference)
{
- ButtonHandler.SetReport((VMultiReportHeader*)ReportPointer, ReportBuffer);
+ _instance = VMultiInstanceManager.RetrieveVMultiInstance("VMultiRel", tabletReference, () => new RelativeInputReport());
+ _rawPointer = _instance.Pointer;
}
- protected override RelativeInputReport CreateReport()
+ public void SetPosition(Vector2 delta)
{
- return new RelativeInputReport(0x04);
+ delta += _error;
+ _error = new Vector2(delta.X % 1, delta.Y % 1);
+ _rawPointer->X = (byte)delta.X;
+ _rawPointer->Y = (byte)delta.Y;
}
- public override void SetPosition(Vector2 pos)
+ public void Reset()
{
- SetCoordinates(pos);
- Device.Write(ReportBuffer);
}
- protected override void SetCoordinates(Vector2 pos)
+ public void Flush()
{
- ReportPointer->X = (byte)pos.X;
- ReportPointer->Y = (byte)pos.Y;
+ _instance!.Write();
}
}
}
\ No newline at end of file
diff --git a/OutputMode/VMultiMode/VMultiButtonHandler.cs b/OutputMode/VMultiMode/VMultiButtonHandler.cs
index 7ce89cc..c48d8ab 100644
--- a/OutputMode/VMultiMode/VMultiButtonHandler.cs
+++ b/OutputMode/VMultiMode/VMultiButtonHandler.cs
@@ -8,8 +8,10 @@ using VoiDPlugins.Library.VMulti;
namespace VoiDPlugins.OutputMode
{
[PluginName("VMulti Mode")]
- public class VMultiButtonHandler : ButtonHandler, IStateBinding
+ public class VMultiButtonHandler : IStateBinding
{
+ private VMultiInstance? _instance;
+
public static Dictionary Bindings { get; } = new()
{
{ "Left", 1 },
@@ -20,16 +22,24 @@ namespace VoiDPlugins.OutputMode
public static string[] ValidButtons { get; } = Bindings.Keys.ToArray();
[Property("Button"), PropertyValidated(nameof(ValidButtons))]
- public string Button { get; set; }
+ public string? Button { get; set; }
+
+ [TabletReference]
+ public TabletReference Reference { set => Initialize(value); }
+
+ private void Initialize(TabletReference tabletReference)
+ {
+ _instance = VMultiInstanceManager.RetrieveVMultiInstance(tabletReference);
+ }
public void Press(TabletReference tablet, IDeviceReport report)
{
- EnableBit(Bindings[Button]);
+ _instance!.EnableButtonBit(Bindings[Button!]);
}
public void Release(TabletReference tablet, IDeviceReport report)
{
- DisableBit(Bindings[Button]);
+ _instance!.DisableButtonBit(Bindings[Button!]);
}
}
}
\ No newline at end of file
diff --git a/OutputMode/VMultiMode/VMultiMode.csproj b/OutputMode/VMultiMode/VMultiMode.csproj
index bd9d098..05d1625 100644
--- a/OutputMode/VMultiMode/VMultiMode.csproj
+++ b/OutputMode/VMultiMode/VMultiMode.csproj
@@ -1,19 +1,5 @@
-
- net5
- true
+ true
-
-
- none
- false
- false
-
-
-
-
-
-
-
diff --git a/OutputMode/WindowsInk/Output/WinInkAbsoluteMode.cs b/OutputMode/WindowsInk/Output/WinInkAbsoluteMode.cs
index f860304..67514ce 100644
--- a/OutputMode/WindowsInk/Output/WinInkAbsoluteMode.cs
+++ b/OutputMode/WindowsInk/Output/WinInkAbsoluteMode.cs
@@ -10,12 +10,24 @@ namespace VoiDPlugins.OutputMode
[PluginName("Windows Ink Absolute Mode")]
public class WinInkAbsoluteMode : AbsoluteOutputMode
{
+ private WinInkAbsolutePointer? _pointer;
+
[Resolved]
public IServiceProvider ServiceProvider
{
- set => Pointer = new WinInkAbsolutePointer((IVirtualScreen)value.GetService(typeof(IVirtualScreen)));
+ set => _pointer = new WinInkAbsolutePointer((IVirtualScreen)value.GetService(typeof(IVirtualScreen))!);
}
- public override IAbsolutePointer Pointer { get; set; }
+ [OnDependencyLoad]
+ public void Initialize()
+ {
+ _pointer!.Initialize(TabletReference);
+ }
+
+ public override IAbsolutePointer Pointer
+ {
+ get => _pointer!;
+ set { }
+ }
}
}
\ No newline at end of file
diff --git a/OutputMode/WindowsInk/Output/WinInkRelativeMode.cs b/OutputMode/WindowsInk/Output/WinInkRelativeMode.cs
index 9c89338..b7e3b54 100644
--- a/OutputMode/WindowsInk/Output/WinInkRelativeMode.cs
+++ b/OutputMode/WindowsInk/Output/WinInkRelativeMode.cs
@@ -10,12 +10,24 @@ namespace VoiDPlugins.OutputMode
[PluginName("Windows Ink Relative Mode")]
public class WinInkRelativeMode : RelativeOutputMode
{
+ private WinInkRelativePointer? _pointer;
+
[Resolved]
public IServiceProvider ServiceProvider
{
- set => Pointer = new WinInkRelativePointer((IVirtualScreen)value.GetService(typeof(IVirtualScreen)));
+ set => _pointer = new WinInkRelativePointer((IVirtualScreen)value.GetService(typeof(IVirtualScreen))!);
}
- public override IRelativePointer Pointer { get; set; }
+ [OnDependencyLoad]
+ public void Initialize()
+ {
+ _pointer!.Initialize(TabletReference);
+ }
+
+ public override IRelativePointer Pointer
+ {
+ get => _pointer!;
+ set { }
+ }
}
}
\ No newline at end of file
diff --git a/OutputMode/WindowsInk/Pointer/WinInkAbsolutePointer.cs b/OutputMode/WindowsInk/Pointer/WinInkAbsolutePointer.cs
index f9444b0..550a3e1 100644
--- a/OutputMode/WindowsInk/Pointer/WinInkAbsolutePointer.cs
+++ b/OutputMode/WindowsInk/Pointer/WinInkAbsolutePointer.cs
@@ -1,57 +1,23 @@
using System.Numerics;
using OpenTabletDriver.Plugin.Platform.Display;
using OpenTabletDriver.Plugin.Platform.Pointer;
-using VoiDPlugins.Library.VMulti;
-using VoiDPlugins.Library.VMulti.Device;
namespace VoiDPlugins.OutputMode
{
- public unsafe class WinInkAbsolutePointer : BasePointer, IVirtualTablet
+ public unsafe class WinInkAbsolutePointer : WinInkBasePointer, IAbsolutePointer
{
- public WinInkAbsolutePointer(IVirtualScreen screen) : base(screen, "WindowsInk")
+ private readonly Vector2 _conversionFactor;
+
+ public WinInkAbsolutePointer(IVirtualScreen screen)
{
- WinInkButtonHandler.SetReport(ReportPointer, ReportBuffer);
- WinInkButtonHandler.SetDevice(Device);
+ _conversionFactor = new Vector2(screen.Width, screen.Height) / (1 / 32767);
}
- public void SetButtonState(uint button, bool active)
+ public void SetPosition(Vector2 pos)
{
- throw new System.NotImplementedException();
- }
-
- public void SetEraser(bool isEraser)
- {
- if (!WinInkButtonHandler.IsManuallySet)
- {
- WinInkButtonHandler.EraserStateTransition(isEraser);
- }
- }
-
- public void SetPressure(float percentage)
- {
- ReportPointer->Pressure = (ushort)(percentage * 8191);
- }
-
- public void SetProximity(bool proximity, uint distance)
- {
- return;
- }
-
- public void SetTilt(Vector2 tilt)
- {
- ReportPointer->XTilt = (byte)tilt.X;
- ReportPointer->YTilt = (byte)tilt.Y;
- }
-
- protected override DigitizerInputReport CreateReport()
- {
- return new DigitizerInputReport(0x05);
- }
-
- protected override void SetCoordinates(Vector2 pos)
- {
- ReportPointer->X = (ushort)pos.X;
- ReportPointer->Y = (ushort)pos.Y;
+ pos *= _conversionFactor;
+ RawPointer->X = (ushort)pos.X;
+ RawPointer->Y = (ushort)pos.Y;
}
}
}
\ No newline at end of file
diff --git a/OutputMode/WindowsInk/Pointer/WinInkBasePointer.cs b/OutputMode/WindowsInk/Pointer/WinInkBasePointer.cs
new file mode 100644
index 0000000..0be8a6b
--- /dev/null
+++ b/OutputMode/WindowsInk/Pointer/WinInkBasePointer.cs
@@ -0,0 +1,57 @@
+using System.Numerics;
+using OpenTabletDriver.Plugin.Platform.Pointer;
+using OpenTabletDriver.Plugin.Tablet;
+using VoiDPlugins.Library.VMulti;
+using VoiDPlugins.Library.VMulti.Device;
+using static VoiDPlugins.OutputMode.WindowsInkConstants;
+
+namespace VoiDPlugins.OutputMode
+{
+ public unsafe abstract class WinInkBasePointer : IPressureHandler, ITiltHandler, IEraserHandler, ISynchronousPointer
+ {
+ protected DigitizerInputReport* RawPointer { get; private set; }
+ protected VMultiInstance? Instance { get; private set; }
+
+ public void Initialize(TabletReference tabletReference)
+ {
+ Instance = VMultiInstanceManager.RetrieveVMultiInstance("WindowsInk", tabletReference, () => new DigitizerInputReport());
+ Instance.InitializeData(POINTER, this);
+ Instance.InitializeData(ERASER_STATE, false);
+ Instance.InitializeData(MANUAL_ERASER, false);
+ RawPointer = Instance.Pointer;
+ }
+
+ public void SetEraser(bool isEraser)
+ {
+ if (!Instance!.GetData(MANUAL_ERASER))
+ {
+ WinInkButtonHandler.EraserStateTransition(Instance, ref GetEraser(), isEraser);
+ }
+ }
+
+ public void SetPressure(float percentage)
+ {
+ RawPointer->Pressure = (ushort)(percentage * 8191);
+ }
+
+ public void SetTilt(Vector2 tilt)
+ {
+ RawPointer->XTilt = (byte)tilt.X;
+ RawPointer->YTilt = (byte)tilt.Y;
+ }
+
+ public void Reset()
+ {
+ }
+
+ public void Flush()
+ {
+ Instance!.Write();
+ }
+
+ private ref bool GetEraser()
+ {
+ return ref Instance!.GetData(ERASER_STATE);
+ }
+ }
+}
\ No newline at end of file
diff --git a/OutputMode/WindowsInk/Pointer/WinInkRelativePointer.cs b/OutputMode/WindowsInk/Pointer/WinInkRelativePointer.cs
index 04e34fe..c45a1d1 100644
--- a/OutputMode/WindowsInk/Pointer/WinInkRelativePointer.cs
+++ b/OutputMode/WindowsInk/Pointer/WinInkRelativePointer.cs
@@ -1,68 +1,29 @@
using System.Numerics;
using OpenTabletDriver.Plugin.Platform.Display;
using OpenTabletDriver.Plugin.Platform.Pointer;
-using VoiDPlugins.Library.VMulti;
-using VoiDPlugins.Library.VMulti.Device;
namespace VoiDPlugins.OutputMode
{
- public unsafe class WinInkRelativePointer : BasePointer, IVirtualTablet
+ public unsafe class WinInkRelativePointer : WinInkBasePointer, IRelativePointer
{
- private Vector2 maxPoint;
- private Vector2 currentPoint;
+ private Vector2 _maxPoint;
+ private Vector2 _currentPoint;
+ private Vector2 _error;
- public WinInkRelativePointer(IVirtualScreen screen) : base(screen, "WindowsInk")
+ public WinInkRelativePointer(IVirtualScreen screen)
{
- WinInkButtonHandler.SetReport(ReportPointer, ReportBuffer);
- WinInkButtonHandler.SetDevice(Device);
- maxPoint = new Vector2(VirtualScreen.Width, VirtualScreen.Height);
- currentPoint = maxPoint / 2;
+ _maxPoint = new Vector2(screen.Width, screen.Height);
+ _currentPoint = _maxPoint / 2;
}
- public void SetButtonState(uint button, bool active)
+ public void SetPosition(Vector2 delta)
{
- return;
- }
+ delta += _error;
+ _error = new Vector2(delta.X % 1, delta.Y % 1);
- public void SetEraser(bool isEraser)
- {
- if (!WinInkButtonHandler.IsManuallySet)
- {
- WinInkButtonHandler.EraserStateTransition(isEraser);
- }
- }
-
- public void SetPressure(float percentage)
- {
- ReportPointer->Pressure = (ushort)(percentage * 8191);
- }
-
- public void SetProximity(bool proximity, uint distance)
- {
- return;
- }
-
- public void SetTilt(Vector2 tilt)
- {
- ReportPointer->XTilt = (byte)tilt.X;
- ReportPointer->YTilt = (byte)tilt.Y;
- }
-
- public override void Translate(Vector2 delta)
- {
- 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;
+ _currentPoint = Vector2.Clamp(_currentPoint + delta, Vector2.Zero, _maxPoint);
+ RawPointer->X = (ushort)_currentPoint.X;
+ RawPointer->Y = (ushort)_currentPoint.Y;
}
}
}
\ No newline at end of file
diff --git a/OutputMode/WindowsInk/WinInkButtonHandler.cs b/OutputMode/WindowsInk/WinInkButtonHandler.cs
index b57fde3..c4f2601 100644
--- a/OutputMode/WindowsInk/WinInkButtonHandler.cs
+++ b/OutputMode/WindowsInk/WinInkButtonHandler.cs
@@ -1,16 +1,18 @@
using System;
-using HidSharp;
using OpenTabletDriver.Plugin;
using OpenTabletDriver.Plugin.Attributes;
using OpenTabletDriver.Plugin.Tablet;
using VoiDPlugins.Library.VMulti;
using VoiDPlugins.Library.VMulti.Device;
+using static VoiDPlugins.OutputMode.WindowsInkConstants;
namespace VoiDPlugins.OutputMode
{
[PluginName("Windows Ink")]
- public unsafe class WinInkButtonHandler : ButtonHandler, IStateBinding
+ public unsafe class WinInkButtonHandler : IStateBinding
{
+ private VMultiInstance? _instance;
+
public static string[] ValidButtons { get; } = new string[]
{
"Pen Tip",
@@ -20,7 +22,7 @@ namespace VoiDPlugins.OutputMode
};
[Property("Button"), PropertyValidated(nameof(ValidButtons))]
- public string Button { get; set; }
+ public string? Button { get; set; }
[Flags]
private enum ButtonBits : byte
@@ -32,30 +34,37 @@ namespace VoiDPlugins.OutputMode
InRange = 16
}
- public static bool IsManuallySet { get; set; }
- private static bool EraserState;
- private static HidStream Device;
+ public bool IsManuallySet { get; set; }
+
+ [TabletReference]
+ public TabletReference Reference { set => Initialize(value); }
+
+ private void Initialize(TabletReference tabletReference)
+ {
+ _instance = VMultiInstanceManager.RetrieveVMultiInstance(tabletReference);
+ }
public void Press(TabletReference tablet, IDeviceReport report)
{
+ ref var eraserState = ref GetEraser();
switch (Button)
{
case "Pen Tip":
- EnableBit((int)(EraserState ? ButtonBits.Eraser : ButtonBits.Press));
+ _instance!.EnableButtonBit((int)(eraserState ? ButtonBits.Eraser : ButtonBits.Press));
break;
case "Pen Button":
- EnableBit((int)ButtonBits.Barrel);
+ _instance!.EnableButtonBit((int)ButtonBits.Barrel);
break;
case "Eraser (Toggle)":
IsManuallySet = true;
- EraserStateTransition(!EraserState);
+ EraserStateTransition(_instance!, ref eraserState, !eraserState);
break;
case "Eraser (Hold)":
IsManuallySet = true;
- EraserStateTransition(true);
+ EraserStateTransition(_instance!, ref eraserState, true);
break;
}
}
@@ -65,60 +74,54 @@ namespace VoiDPlugins.OutputMode
switch (Button)
{
case "Pen Tip":
- DisableBit((int)(ButtonBits.Press | ButtonBits.Eraser));
+ _instance!.DisableButtonBit((int)(ButtonBits.Press | ButtonBits.Eraser));
break;
case "Pen Button":
- DisableBit((int)ButtonBits.Barrel);
+ _instance!.DisableButtonBit((int)ButtonBits.Barrel);
break;
case "Eraser (Hold)":
- EraserStateTransition(false);
+ EraserStateTransition(_instance!, ref GetEraser(), false);
break;
}
}
- public static void EraserStateTransition(bool isEraser)
+ public static void EraserStateTransition(VMultiInstance instance, ref bool eraserState, bool isEraser)
{
- if (EraserState != isEraser)
+ if (eraserState != isEraser)
{
- EraserState = isEraser;
- var report = (DigitizerInputReport*)ReportPointer;
+ eraserState = isEraser;
+ var report = (DigitizerInputReport*)instance.Header;
var buttons = report->Header.Buttons;
var pressure = report->Pressure;
// Send In-Range but no tips
- DisableBit((int)(ButtonBits.Press | ButtonBits.Eraser));
+ instance.DisableButtonBit((int)(ButtonBits.Press | ButtonBits.Eraser));
report->Pressure = 0;
- Device.Write(ReportBuffer);
+ instance.Write();
// Send Out-Of-Range
report->Header.Buttons = 0;
- Device.Write(ReportBuffer);
+ instance.Write();
// Send In-Range but no tips
- EnableBit((int)ButtonBits.InRange);
- if (EraserState)
- EnableBit((int)ButtonBits.Invert);
+ instance.EnableButtonBit((int)ButtonBits.InRange);
+ if (eraserState)
+ instance.EnableButtonBit((int)ButtonBits.Invert);
- Device.Write(ReportBuffer);
+ instance.Write();
// Set Proper Report
- if (HasBit(buttons, (int)(ButtonBits.Press | ButtonBits.Eraser)))
- EnableBit((int)(EraserState ? ButtonBits.Eraser : ButtonBits.Press));
+ if (VMultiInstance.HasBit(buttons, (int)(ButtonBits.Press | ButtonBits.Eraser)))
+ instance.EnableButtonBit((int)(eraserState ? ButtonBits.Eraser : ButtonBits.Press));
report->Pressure = pressure;
}
}
- public static void SetReport(DigitizerInputReport* report, byte[] reportBuffer)
+ private ref bool GetEraser()
{
- SetReport((VMultiReportHeader*)report, reportBuffer);
- EnableBit((int)ButtonBits.InRange);
- }
-
- public static void SetDevice(HidStream device)
- {
- Device = device;
+ return ref _instance!.GetData(ERASER_STATE);
}
}
}
\ No newline at end of file
diff --git a/OutputMode/WindowsInk/WindowsInk.csproj b/OutputMode/WindowsInk/WindowsInk.csproj
index bd9d098..05d1625 100644
--- a/OutputMode/WindowsInk/WindowsInk.csproj
+++ b/OutputMode/WindowsInk/WindowsInk.csproj
@@ -1,19 +1,5 @@
-
- net5
- true
+ true
-
-
- none
- false
- false
-
-
-
-
-
-
-
diff --git a/OutputMode/WindowsInk/WindowsInkConstants.cs b/OutputMode/WindowsInk/WindowsInkConstants.cs
new file mode 100644
index 0000000..1b0380f
--- /dev/null
+++ b/OutputMode/WindowsInk/WindowsInkConstants.cs
@@ -0,0 +1,9 @@
+namespace VoiDPlugins.OutputMode
+{
+ public static class WindowsInkConstants
+ {
+ public const int POINTER = 0;
+ public const int ERASER_STATE = 1;
+ public const int MANUAL_ERASER = 2;
+ }
+}
\ No newline at end of file
diff --git a/VoiDPlugins.Library/VMulti/BasePointer.cs b/VoiDPlugins.Library/VMulti/BasePointer.cs
deleted file mode 100644
index 7b66ff7..0000000
--- a/VoiDPlugins.Library/VMulti/BasePointer.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-using System;
-using System.Numerics;
-using System.Runtime.CompilerServices;
-using HidSharp;
-using OpenTabletDriver.Plugin.Attributes;
-using OpenTabletDriver.Plugin.Platform.Display;
-using OpenTabletDriver.Plugin.Platform.Pointer;
-
-namespace VoiDPlugins.Library.VMulti
-{
- [PluginIgnore]
- public abstract unsafe class BasePointer : IAbsolutePointer, IRelativePointer where T : unmanaged
- {
- 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, string Name)
- {
- ReportBuffer = GC.AllocateArray(Unsafe.SizeOf(), pinned: true);
- ReportPointer = (T*)Unsafe.AsPointer(ref ReportBuffer[0]);
-
- T report = CreateReport();
- *ReportPointer = report;
-
- VirtualScreen = screen;
- Device = VMultiDevice.Retrieve(Name);
-
- ScreenToVMulti = new Vector2(VirtualScreen.Width, VirtualScreen.Height) / 32767;
- }
-
- protected Vector2 Convert(Vector2 pos)
- {
- return pos / ScreenToVMulti;
- }
-
- protected abstract T CreateReport();
- protected abstract void SetCoordinates(Vector2 pos);
-
- public virtual void SetPosition(Vector2 pos)
- {
- SetCoordinates(Convert(pos));
- Device.Write(ReportBuffer);
- }
-
- public virtual void Translate(Vector2 delta)
- {
- delta += error;
- error = new Vector2(delta.X % 1, delta.Y % 1);
-
- SetCoordinates(delta);
- Device.Write(ReportBuffer);
- }
- }
-}
\ No newline at end of file
diff --git a/VoiDPlugins.Library/VMulti/ButtonHandler.cs b/VoiDPlugins.Library/VMulti/ButtonHandler.cs
deleted file mode 100644
index 748e309..0000000
--- a/VoiDPlugins.Library/VMulti/ButtonHandler.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using OpenTabletDriver.Plugin.Attributes;
-using VoiDPlugins.Library.VMulti.Device;
-
-namespace VoiDPlugins.Library.VMulti
-{
- [PluginIgnore]
- public unsafe class ButtonHandler
- {
- protected static byte[] ReportBuffer;
- protected static VMultiReportHeader* ReportPointer;
-
- public static void SetReport(VMultiReportHeader* report, byte[] reportBuffer)
- {
- ReportBuffer = reportBuffer;
- ReportPointer = report;
- }
-
- public static void EnableBit(int bit)
- {
- ReportPointer->Buttons = (byte)(ReportPointer->Buttons | bit);
- }
-
- public static void DisableBit(int bit)
- {
- ReportPointer->Buttons = (byte)(ReportPointer->Buttons & ~bit);
- }
-
- public static bool HasBit(int bit)
- {
- return (ReportPointer->Buttons & bit) != 0;
- }
-
- public static bool HasBit(byte buttons, int bit)
- {
- return (buttons & bit) != 0;
- }
- }
-}
\ No newline at end of file
diff --git a/VoiDPlugins.Library/VMulti/Device/AbsoluteInputReport.cs b/VoiDPlugins.Library/VMulti/Device/AbsoluteInputReport.cs
index 016eefb..9ffc686 100644
--- a/VoiDPlugins.Library/VMulti/Device/AbsoluteInputReport.cs
+++ b/VoiDPlugins.Library/VMulti/Device/AbsoluteInputReport.cs
@@ -6,9 +6,9 @@ namespace VoiDPlugins.Library.VMulti.Device
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct AbsoluteInputReport
{
- public AbsoluteInputReport(byte reportID)
+ public AbsoluteInputReport()
{
- Header = new VMultiReportHeader(Unsafe.SizeOf(), reportID);
+ Header = new VMultiReportHeader(Unsafe.SizeOf(), 0x09);
X = 0;
Y = 0;
Pressure = 0;
diff --git a/VoiDPlugins.Library/VMulti/VMulti.csproj b/VoiDPlugins.Library/VMulti/VMulti.csproj
index 14f047c..8b2354d 100644
--- a/VoiDPlugins.Library/VMulti/VMulti.csproj
+++ b/VoiDPlugins.Library/VMulti/VMulti.csproj
@@ -1,19 +1,5 @@
-
-
- net5
- true
-
-
-
- none
- false
- false
-
-
-
-
\ No newline at end of file
diff --git a/VoiDPlugins.Library/VMulti/VMultiDevice.cs b/VoiDPlugins.Library/VMulti/VMultiDevice.cs
deleted file mode 100644
index 2e83b57..0000000
--- a/VoiDPlugins.Library/VMulti/VMultiDevice.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-using System;
-using HidSharp;
-using OpenTabletDriver.Plugin;
-
-namespace VoiDPlugins.Library.VMulti
-{
- public static class VMultiDevice
- {
- public static HidStream Retrieve(string Name)
- {
- HidStream VMultiDev = null;
- foreach (var device in DeviceList.Local.GetHidDevices(productID: 47820))
- {
- if (device.GetMaxOutputReportLength() == 65 && device.GetMaxInputReportLength() == 65)
- {
- if (device.TryOpen(out VMultiDev))
- break;
- }
- }
-
- if (VMultiDev == null)
- {
- Log.Write(Name, "Cannot find VirtualHID", LogLevel.Error);
- Log.Write(Name, "Install VMulti driver here: https://github.com/X9VoiD/vmulti-bin/releases/latest", LogLevel.Error);
- throw new Exception();
- }
-
- return VMultiDev;
- }
- }
-}
\ No newline at end of file
diff --git a/VoiDPlugins.Library/VMulti/VMultiInstance.cs b/VoiDPlugins.Library/VMulti/VMultiInstance.cs
new file mode 100644
index 0000000..a13042c
--- /dev/null
+++ b/VoiDPlugins.Library/VMulti/VMultiInstance.cs
@@ -0,0 +1,101 @@
+using System;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using HidSharp;
+using OpenTabletDriver.Plugin;
+using VoiDPlugins.Library.VMulti.Device;
+
+namespace VoiDPlugins.Library.VMulti
+{
+ public class VMultiInstance
+ {
+ private readonly object[] _data;
+ private readonly HidStream _device;
+ protected readonly byte[] Buffer;
+ public unsafe VMultiReportHeader* Header { get; }
+
+ internal unsafe VMultiInstance(string name, int size)
+ {
+ Buffer = GC.AllocateArray(size, true);
+ Header = (VMultiReportHeader*)Unsafe.AsPointer(ref Buffer[0]);
+ _device = Retrieve(name);
+ _data = GC.AllocateArray