Virtual Input over IP EmulatoR
A cross-platform virtual USB input framework for creating virtual USB input devices (game controllers, keyboards, mice and more) that are indistinguishable from real hardware to the operating system and applications.
VIIPER lets developers create and programmatically control virtual USB input devices (using USBIP under the hood), enabling seamless integration for gaming, automation, testing and remote control scenarios.
This repository is a fork of hbashton/VIIPER and serves as the embedded backend for the DualSense Client project, providing native virtual controller output including the ongoing DualSense audio, haptics, and microphone work. The DualSenseClient release channel aims for feature parity with the upstream fork. Unlike DS4Windows, DualSense Client embeds VIIPER directly as a library instead of running it as a separate app.
- Runs on Linux and Windows.
- Pure C API callable from any language with C FFI support.
- VIIPER abstracts away all USB / USBIP details.
- VIIPER is portable and runs entirely in userspace.
- Utilizes a generic USBIP kernel mode driver (built into Linux; on Windows usbip-win2 provides a signed kernel mode driver) New device types never require touching kernel code.
- After installing USBIP once, VIIPER can run without additional dependencies or system-wide installation.
libVIIPER is a single shared library (libVIIPER.dll on Windows, libVIIPER.so on Linux) that embeds the full
VIIPER USB/USBIP stack directly into your application.
- Pure C API callable from any language with C FFI support
- In-process and threadsafe: the USBIP server runs in a background thread inside your application
- Optional auto-attach to the local USBIP client on the same machine
- No separate server process or network protocol to implement
- See examples for C and C# in
examples/libVIIPER - See the libVIIPER documentation for details
- C# developers: the complete C# Bindings reference covers every function, struct, enum and callback with P/Invoke declarations
- Prefer a managed TCP client over P/Invoke? See Client Libraries for the generated C#, C++, Rust, TypeScript and Go clients
The features that hbashton/VIIPER added to the standalone app were ported to libVIIPER, so VIIPER can be embedded in an application as a library instead of requiring a separate app.
- Xbox 360 controller emulation; see Devices โบ Xbox 360 Controller
- HID Keyboard with N-key rollover and LED feedback; see Devices โบ Keyboard
- HID Mouse with 5 buttons and horizontal/vertical wheel; see Devices โบ Mouse
- PS4 controller emulation; see Devices โบ DualShock 4 Controller
- PS5 DualSense controller emulation (including Edge variant); see Devices โบ DualSense Controller
- Nintendo Switch 2 Pro Controller emulation; see Devices โบ Switch 2 Pro Controller
Physical controller
|
| HID input, audio, and feedback
v
Feeder application
|
| libVIIPER C API (in-process)
v
VIIPER userspace USB device
|
| USBIP
v
usbip-win2 virtual host controller
|
v
Windows, games, and audio services
VIIPER does not emulate a Bluetooth radio and does not make the virtual device appear wirelessly paired. The game sees a native-style USB controller. A separate app, such as DualSense Client or DS4Windows, is then responsible for translating and forwarding supported feedback between that virtual USB device and the physical USB or Bluetooth controller.
Download the latest libVIIPER release artifact (containing libVIIPER.dll/libVIIPER.so, libVIIPER.h and the
Windows import definition) from the latest DualSenseClient release.
libVIIPER itself is portable, but virtual devices on Windows still require the
usbip-win2 kernel driver.
Linux:
- Arch Linux:
- Install:
sudo pacman -S usbip - Docs: Arch Wiki: USBIP
- Install:
- Ubuntu / Debian:
- Install:
sudo apt install linux-tools-generic - Docs: Ubuntu USBIP Manual
- Install:
Windows:
- Windows 10 or Windows 11 x64
- usbip-win2 โ by far the most complete implementation of USBIP for Windows (comes with a SIGNED kernel mode driver)
Integrate libVIIPER directly into your application โ embed the full USBIP stack in-process and drive virtual devices through the pure C API. See Examples for examples in either C or C#.
The libVIIPER C API is declared in libVIIPER.h (generated at build time) and covers:
- Server lifecycle โ
NewUSBServer,CloseUSBServer - Bus management โ
CreateUSBBus,RemoveUSBBus - Device creation โ one
Create<Device>Deviceper emulatable device type, with ametaparameter to control identity (serial number, battery, colors, โฆ) - Input feeding โ
Set<Device>DeviceStateto push input (buttons, sticks, touch, IMU, โฆ) - Host feedback โ output callbacks for rumble, LEDs, adaptive triggers, and speaker/haptics PCM, plus microphone PCM input for the DualSense and DualShock 4
All functions return bool and are callable from any language with C FFI support. VIIPER takes care of all USBIP
protocol details, so you can focus on implementing the device logic only. On localhost, libVIIPER also automatically
attaches the USBIP client, so you don't have to worry about USBIP details at all.
See the libVIIPER documentation for the complete API reference, the
C# Bindings for the full C# P/Invoke reference, and
Client Libraries if you prefer driving a standalone
viiper server over TCP.
- Go 1.26 or newer
- USBIP installed
- (Optional) just
- Windows:
winget install --id Casey.Just --exact - Linux: use your package manager (
sudo pacman -S just,sudo apt install just, ...)
- Windows:
- Windows compiler (required for
build-libVIIPER):winget install -e --id MartinStorsjo.LLVM-MinGW.UCRT --accept-package-agreements --accept-source-agreements
git clone https://github.com/DualSenseClient/VIIPER.git
cd VIIPER
just build-libVIIPERThe output is written to dist/libVIIPER/ (libVIIPER.dll/libVIIPER.so plus the generated libVIIPER.h header).
Building libVIIPER requires CGO (CGO_ENABLED=1) and a C compiler (GCC / MSVC / Clang) in PATH.
For more build options:
just --list # Show all available targets
just test # Run tests
go test ./... # Run tests directlyContributions are welcome! Please open issues or pull requests on GitHub. See the issues page for bugs and feature requests.
USBIP is a protocol that allows USB devices to be shared over a network. VIIPER uses it because it's already built into Linux and available for Windows, making virtual device emulation possible without writing custom kernel drivers yourself.
libVIIPER is licensed under GPL-3.0. Linking against it (as a shared library) requires your application to be GPL-3.0 compatible.
Yes! VIIPER can create virtual input devices that appear as real hardware to games and applications. This works with Steam, native Windows games and any other application that supports the emulated device types.
Many controller emulation approaches require writing a custom kernel driver for every device type you want to support. VIIPER uses USBIP to handle the USB protocol layer, so device emulation code lives entirely in userspace.
USBIP itself does require a kernel driver. On Linux, the USBIP driver is built into the kernel. On Windows, usbip-win2 provides a signed kernel mode driver. That driver is generic and does not need to know anything about specific device types โ all device-type logic stays in userspace.
This makes VIIPER portable, easier to extend and simpler to bundle with applications. Adding a new device type never requires touching kernel code.
Yes! VIIPER's architecture is designed to be extensible. Check the xbox360 device implementation as a reference for creating new device types.
End-to-end input latency for virtual devices created with VIIPER is typically well below 1 millisecond on a modern desktop. To not stress the CPU excessively, reports get batched and sent every millisecond, so the best you will achieve is a 1000 Hz update rate โ more than enough, and more than what most real hardware devices provide. Note: Actual device polling rates may be lower depending on the device type and configuration.
Report backend issues at DualSenseClient/VIIPER Issues. Report controller mapping or DS4Windows UI issues at hbashton/DS4Windows Issues.
VIIPER - Virtual Input over IP EmulatoR
Copyright (C) 2025-2026 Peter Repukat
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
libVIIPER and the VIIPER core are licensed under GPL-3.0-or-later; see LICENSE.txt for the full text.
VIIPER was originally created by Peter Repukat and the Alia5/VIIPER contributors, and this fork builds on the fork created by Hunter Ashton and the hbashton/VIIPER contributors.
- ViGEmBus (retired, but still widely used) โ Windows kernel-mode driver emulating well-known USB game controllers. Shoutout and thank you to @nefarius for paving the way.
- Valve Software for creating the OG Steam Controller (2015) and Steam Input, which sent this project down the rabbit hole in the first place.
- USBIP โ without it, VIIPER would not be possible.
- SDL for their excellent work on input device handling, reducing reversing efforts to a minimum.
It also depends on controller/audio protocol research shared by SAxense, DualSense reverse-engineering projects, and the wider open-source community.