VisualPinball.NativeInput
0.0.1
See the version list below for details.
dotnet add package VisualPinball.NativeInput --version 0.0.1
NuGet\Install-Package VisualPinball.NativeInput -Version 0.0.1
<PackageReference Include="VisualPinball.NativeInput" Version="0.0.1" />
<PackageVersion Include="VisualPinball.NativeInput" Version="0.0.1" />
<PackageReference Include="VisualPinball.NativeInput" />
paket add VisualPinball.NativeInput --version 0.0.1
#r "nuget: VisualPinball.NativeInput, 0.0.1"
#:package VisualPinball.NativeInput@0.0.1
#addin nuget:?package=VisualPinball.NativeInput&version=0.0.1
#tool nuget:?package=VisualPinball.NativeInput&version=0.0.1
VPE Native Input Polling
High-performance native input polling library for Visual Pinball Engine.
Purpose
Provides OS-level input polling to achieve sub-millisecond input latency by bypassing Unity's Input System buffer. The input polling runs on a dedicated thread at 500-2000 Hz and forwards events to the simulation thread via a callback.
Architecture
┌─────────────────────────────────────┐
│ OS Input Events (Keyboard/HID) │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ Native Input Polling Thread │
│ (500-2000 Hz) │
├─────────────────────────────────────┤
│ • GetAsyncKeyState (Windows) │
│ • X11 key polling (Linux) │
│ • CoreGraphics/AppKit (macOS) │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ Lock-Free SPSC Ring Buffer │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ Simulation Thread (1000 Hz) │
└─────────────────────────────────────┘
Building
Windows (Visual Studio 2022)
cd VisualPinball.NativeInput
mkdir build
cd build
cmake .. -G "Visual Studio 17 2022" -A x64
cmake --build . --config Release
Output: ../VisualPinball.Engine/VisualPinball.Unity/VisualPinball.Unity/Plugins/win-x64/VpeNativeInput.dll
Windows (MinGW)
cd VisualPinball.NativeInput
mkdir build
cd build
cmake .. -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release
cmake --build .
Linux
cd VisualPinball.NativeInput
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make
Requires: libx11-dev
macOS
cd VisualPinball.NativeInput
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make
Requires: AppKit and ApplicationServices frameworks (provided by macOS)
CI / NuGet
GitHub Actions builds win-x64, win-x86, linux-x64, osx-x64, and osx-arm64 binaries and packs them into a single NuGet package.
Publishing happens automatically for tags matching v*.
Usage from C#
using VisualPinball.Unity.Simulation;
// Initialize
NativeInputApi.VpeInputInit();
// Set bindings
var bindings = new[] {
new NativeInputApi.InputBinding {
Action = (int)NativeInputApi.InputAction.LeftFlipper,
BindingType = (int)NativeInputApi.BindingType.Keyboard,
KeyCode = (int)NativeInputApi.KeyCode.LShift
}
};
NativeInputApi.VpeInputSetBindings(bindings, bindings.Length);
// Start polling
NativeInputApi.VpeInputStartPolling(OnInputEvent, IntPtr.Zero, 500);
// Callback
[MonoPInvokeCallback(typeof(NativeInputApi.InputEventCallback))]
static void OnInputEvent(ref NativeInputApi.InputEvent evt, IntPtr userData) {
Console.WriteLine($"Input: {evt.Action} = {evt.Value} @ {evt.TimestampUsec}μs");
}
// Stop polling
NativeInputApi.VpeInputStopPolling();
// Shutdown
NativeInputApi.VpeInputShutdown();
Platform Status
| Platform | Status | API Used |
|---|---|---|
| Windows | ✅ Implemented | GetAsyncKeyState, QueryPerformanceCounter |
| Linux | ✅ Implemented | X11 keyboard state polling |
| macOS | ✅ Implemented | CoreGraphics keyboard state polling |
Performance
- Latency: <0.1ms from physical input to event callback
- CPU Usage: 5-10% of one core (mostly sleeping)
- Overhead: ~10-20ns per P/Invoke call
- Precision: Monotonic microsecond timestamps across platforms
Future Enhancements
- Gamepad support: XInput (Windows), SDL/libinput (Linux), GCController (macOS)
- Analog inputs: Plunger, steering, analog triggers
- Force feedback: Haptics for nudge, tilt, button feedback
- Hot-plugging: Detect device connect/disconnect
- Configuration: JSON-based key mapping files
- Profiles: Per-table input profiles
License
GPLv3+ (same as VPE)
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
This package has no dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.