-
Notifications
You must be signed in to change notification settings - Fork 2
Home
The universal controller remapping toolkit for Windows
PadForge transforms any controller, keyboard, or mouse into a virtual Xbox 360, DualShock 4, DirectInput, MIDI, or Keyboard+Mouse device that games and applications recognize as real hardware. With a 1000 Hz polling engine, interactive 3D visualization, and deep customization for dead zones, sensitivity curves, macros, and force feedback, PadForge gives you complete control over every input.

New in this release — Per-mapping axis-to-button dead zones let you control exactly how far an axis must travel before triggering a button press, with half-axis awareness for centered joystick axes. Audio bass rumble vibrates your controller to in-game explosions and music. The mapping grid includes a source input dropdown, and device mappings now persist when controllers are offline.
Everything you need to download, install, and launch PadForge for the first time.
| Page | Description | |
|---|---|---|
| ⬇ | Installation | Download the portable single-file EXE, verify system requirements (Windows 10/11 x64), install optional drivers (ViGEmBus, vJoy, HidHide, Windows MIDI Services), configure auto-elevation, and enable start-at-login. |
| ■ | Dashboard | Your command center — start and stop the input engine with a live polling-rate readout. Monitor per-slot virtual controller cards showing status, type, device name, and slot number. Add controllers, toggle the DSU motion server and web controller server, and check driver installation status at a glance. |
Create virtual controllers, explore them in 3D, and map every button and axis.
| Page | Description | |
|---|---|---|
| ➕ | Controller Slots | Create up to 16 virtual controller slots across 5 output types — Xbox 360, DualShock 4, DirectInput/vJoy, MIDI, and Keyboard+Mouse. Enable, disable, delete, and drag-reorder slots. Configure vJoy axes/buttons/POVs, MIDI channel/velocity/CC/notes, per-type driver requirements, and multi-slot device assignment. |
| ▶ | 3D and 2D Visualization | Rotate, zoom, and pan an interactive 3D controller model with live button highlighting and stick/trigger animation. Toggle between a flat 2D PNG overlay, a procedural DirectInput schematic (dynamic sticks/triggers/buttons/POVs), or a Keyboard+Mouse preview with full QWERTY keyboard and mouse graphic. Click any element to jump straight to its mapping. |
| ⇄ | Button and Axis Mappings | Map inputs through a grid showing output, source dropdown, live value, record button, invert/half-axis options, and per-mapping axis-to-button dead zone sliders. Record by pressing a button, moving an axis, or shifting the mouse. Run Map All, auto-map recognized gamepads, and Copy/Paste/Copy From with automatic cross-layout translation (Xbox, DS4, vJoy, MIDI, KB+M). Half-axis dead zone awareness for centered joystick axes mapped to buttons. |
Fine-tune stick response, trigger feel, and force feedback to match your play style.
| Page | Description | |
|---|---|---|
| ○ | Stick Dead Zones | Adjust per-axis dead zone and anti-dead zone sliders (X/Y independent, 0.1% precision) across 6 shapes — Scaled Radial, Radial, Axial, Hybrid, Sloped Scaled Axial, and Sloped Axial. Edit per-axis sensitivity curves with presets (Linear, Smooth, Aggressive, Instant, S-Curve, Delay, Custom) and draggable control points. Calibrate center offset, set per-direction max range (left/right/up/down independently), monitor the live circular preview, and configure up to 4 sticks for custom DirectInput devices. |
| ▮ | Trigger Dead Zones | Set floor and ceiling with a dual-handle range slider. Tune anti-dead zone and edit per-trigger sensitivity curves using the same presets as sticks. Watch the live value bar at 0.1% precision with raw digit input. Configure up to 8 triggers sharing 8 axes with sticks for custom DirectInput devices. Apply recommended settings for hair-trigger, racing, and default use cases. |
| ∿ | Force Feedback | Control overall gain and per-motor (left/right) strength, swap motors, and test rumble with live motor activity bars. Cascade haptic fallback through LeftRight, Sine, and Constant strategies. Route DirectInput FFB through vJoy PID descriptors with directional forces (polar-to-motor-split), condition effects (Spring, Damper, Friction, Inertia), and audio bass rumble via WASAPI loopback capture with configurable sensitivity, bass cutoff, and per-motor scaling. |
Power-user features — macros, per-game profiles, and raw device management.
| Page | Description | |
|---|---|---|
| ⚡ | Macros | Build macros with combo triggers (buttons + axes + POV directions, simultaneous activation) and 4 trigger modes — On Press, On Release, While Held, and Always. Set axis thresholds (1--100%), choose trigger source (Input Device or Output Controller), and define actions: button/key press/release, delay, axis set, system/app volume with limit, and mouse move/click/scroll with sensitivity. Repeat once, a fixed count, or until release. Consume trigger buttons, run continuous parallel actions, target up to 128 DirectInput buttons, and bind input device axes for volume/mouse control. |
| ⇆ | Profiles | Switch controller configurations automatically when a game takes focus (~30 Hz foreground window detection). Create, clone, edit, load, and delete profiles. Match executables via Browse dialog (case-insensitive, full-path match) with the Default profile as baseline. Inspect topology badges showing per-type controller counts. Each profile stores all slot settings, mappings, dead zones, force feedback, and macros. |
| ⌸ | Devices | Browse physical devices as cards with status dots (online/offline), VID/PID, type, capabilities, and slot badges. Examine GUID and HidHide instance path in the detail pane. Watch raw input in real time — progress-bar axes, circle-grid buttons, compass POV hats, gyro/accel values, keyboard layout, and mouse graphic. Hide input via HidHide (whole device) or input hooks (mapped keys/buttons only) with safety warnings. Force Raw Joystick Mode for devices with wrong SDL3 gamepad mappings. Drag and drop devices onto sidebar slots. |
Stream motion data to emulators or turn a phone into a wireless gamepad.
| Page | Description | |
|---|---|---|
| ➡ | DSU Motion Server | Stream gyro and accelerometer data to emulators over the DSU/Cemuhook protocol. Support DualSense, DualShock 4, Switch Pro, and Switch 2 Pro controllers. Enable the server on the Dashboard, follow step-by-step setup for Cemu, Dolphin, Ryujinx, and Yuzu, configure the port (default 26760), and work within the 4-slot protocol limit with automatic SDL-to-DSU axis mapping. |
| 🌐 | Web Controller | Turn any phone or tablet into a wireless gamepad. Launch the embedded HTTP/WebSocket server, open the URL in a touchscreen browser, and pick Xbox 360 or DualShock 4 layout. Touch buttons, analog sticks (nipplejs virtual joystick), 8-way D-pad, and triggers. Tap sticks for stick-click. Leverage WebSocket auto-reconnect, browser Vibration API rumble, Add to Home Screen for fullscreen, and network/firewall guidance. |
System settings, driver installation, precision details, and common fixes.
| Page | Description | |
|---|---|---|
| ⚙ | Settings | Choose from 10 languages with live switching. Set the theme (System/Light/Dark). Tune the input engine — auto-start, background polling, master hide toggle, polling interval (1--16 ms). Customize window behavior — minimize to tray, start minimized, start at login. Install or uninstall HidHide, ViGEmBus, vJoy, and Windows MIDI Services with 1 click. Manage the HidHide whitelist, configure MIDI slot settings (channel/velocity/CC count/note count/start numbers), and run file operations (save/reload/reset/open folder). |
| ⚒ | Driver Management | Install and manage 4 optional drivers: ViGEmBus (virtual Xbox 360 and DS4, MSI-based), vJoy (custom DirectInput joystick with configurable HID descriptors and FFB, requires auto-elevation), HidHide (selective device hiding with built-in blacklist/whitelist/cloaking — no external Configuration Client needed), and Windows MIDI Services (~210 MB GitHub download, virtual MIDI endpoints). Check driver status on the Dashboard, consult the troubleshooting table, and review uninstall guard conditions. |
| ⏱ | Input Precision | Poll at 1000 Hz using a 3-tier sleep strategy — HR waitable timer, multimedia timer, and Thread.Sleep+SpinWait — with wall-clock drift compensation and a zero-allocation hot path. Trace the full axis value pipeline from SDL3 16-bit input through unsigned conversion, double-precision dead zone processing, to vJoy 15-bit or ViGEm native output. Achieve bit-perfect passthrough at default settings. Covers dead zone math (x360ce-validated), continuous POV hat support (hundredths of degrees), and single-call batch output (UpdateVJD/SubmitReport). |
| ❓ | Troubleshooting | Fix common problems: no devices detected, virtual controller not appearing in games, double input, vJoy failures, rumble issues, audio bass rumble problems, DSU motion not working, settings not saving, high CPU usage, Steam controller conflicts, wrong button mappings (Force Raw Mode), mouse/keyboard input issues, macros not firing, mouse macro problems, Always-mode macros, web controller connection failures, no MIDI output, sensitivity curve issues, Keyboard+Mouse not working, and stick drift after calibration. Includes a quick-reference table. |
Whether you want to understand the architecture, contribute a feature, or build your own fork — these pages cover every layer of PadForge from the SDL3 input pipeline to the XAML view hierarchy.
| Page | Description | |
|---|---|---|
| 🏗 | Architecture Overview | Survey the 2-project .NET 10 solution — PadForge.App (WPF) and PadForge.Engine (library). Covers full project layout with every file and folder, Mermaid architecture diagram, SDL3-only input philosophy, MVVM via CommunityToolkit.Mvvm, 6-thread model (engine at ~1000 Hz, UI at 30 Hz, Raw Input, DSU receive, input hooks, web controller server), thread safety table, NuGet dependencies, 16-slot system, single-file publish build, and localization architecture (10 languages, live switching via weak-event INotifyPropertyChanged). |
| 🔀 | Input Pipeline | Trace the 6-step polling loop: Step 1 — SDL device enumeration with ViGEm/vJoy filtering and GUID migration. Step 2 — SDL state reading with gamepad vs. joystick API dispatch, FFB forwarding, and multi-slot vibration combining. Step 3 — mapping engine with descriptor-to-Gamepad conversion, dead zone processing, sensitivity curves, center offset, and axis inversion/half-axis. Step 4 — multi-device merge per slot (max-wins strategy). Step 4b — macro state machine with trigger evaluation, action execution, and volume/mouse continuous actions. Step 5 — virtual controller lifecycle for all 5 types, XInput slot mask detection, and vJoy device management. Step 6 — output state copy for UI display. Motion snapshot capture and DSU broadcast occur between Steps 2 and 3. |
| 📡 | SDL3 Integration | Expose the full P/Invoke layer (SDL3Minimal.cs) covering SDL3 vs. SDL2 API changes, bool/string/array marshaling, initialization flags, and critical hints (JOYSTICK_XINPUT enabled, RAWINPUT must not be set). Detail the device enumeration flow — Phase 1 open, Phase 1b/1c keyboard/mouse, Phase 2 disconnect detection — with counter-based ViGEm/vJoy filtering. Explain SdlDeviceWrapper open/close order, haptic strategy selection, and Force Raw Mode. Cover gamepad vs. joystick state reading (axis/button/POV layouts), sensor support (gyro/accel with DSU coordinate conversion), GUID construction, HID product string fallback, rumble with change detection, Raw Input for per-device keyboard/mouse, and the custom SDL3 fork for Switch 2 Pro Controller (WinUSB composite device, Steam conflict). |
| 🕹 | Virtual Controllers | Implement the IVirtualController interface and VirtualControllerType enum across 5 backends. Xbox360VirtualController — ViGEm-based, Gamepad-to-Xbox360 mapping, change detection, FeedbackReceived callback. DS4VirtualController — ViGEm-based, DS4 naming/D-Pad/Y-inversion/digital triggers, DualShock4DPadDirection. VJoyVirtualController — P/Invoke to vJoyInterface.dll, single UpdateVJD batch call, Y-axis HID inversion, SubmitRawState for custom configs, FFB architecture (FfbDeviceState/FfbEffectState/FfbConditionAxis, global FfbCallback routing by device ID, ApplyMotorOutput with condition effects), static device management, generation-based re-acquire. MidiVirtualController — Windows MIDI Services SDK, virtual endpoint creation, CC/Note change detection, auto-mapping. KeyboardMouseVirtualController — Win32 SendInput, KbmRawState with 256-bit key bitmask, mouse delta/scroll, change-detection key up/down. |
| 📝 | vJoy Deep Dive | Diagnose and fix the phantom controller bug (N nodes x N registry keys = N-squared controllers) with the single-node architecture. HID report descriptor format — fixed 97-byte layout with 16 axes, 4 continuous POVs, and 128 buttons using active/constant padding. Registry structure (DeviceNN descriptors, OEMForceFeedback keys for DirectInput FFB enumeration). FFB HID PID descriptor with report ID offset formula, 13 output reports, 4 feature reports, and 11 effect types including condition effects. FFB communication paths (HID vs. IOCTL). Device creation via SetupAPI PowerShell script (DIF_REGISTERDEVICE, critical DeviceName="HIDClass" requirement) and removal order (nodes before service). Generation-based re-acquire mechanism and runtime fixes (stale config leak, DLL namespace cache, config swap during reorder). |
| 💾 | Settings and Serialization | PadForge.xml file format rooted in SettingsFileData DTO, file discovery order, UserDevice (physical device record, 40+ fields), UserSetting (device-to-slot linkage via MapTo index), PadSetting (200+ mapping/dead zone/force feedback properties, string-based storage), AppSettingsData (engine, window, profile settings), MacroData/ActionData serialization, and ProfileData (per-profile PadSettings + macros). SettingsManager with static slot arrays, UserDevices/UserSettings collections, and CreateDefaultPadSetting auto-mapping. Load/save/apply pipeline, cross-layout MappingTranslation (positional equivalence across Xbox/DS4/vJoy/MIDI/KBM), and backward compatibility (array migration, missing fields). |
| 🔗 | Services Layer | Seven service classes bridge the engine and UI. InputService — engine lifecycle, 30 Hz DispatcherTimer for UI sync, macro snapshot push, audio bass detector, auto-save. SettingsService — XML load/save, PadSetting application to InputManager, slot creation/deletion/reorder. DeviceService — ObservableCollection sync from UserDevices, HidHide blacklist/whitelist, device assignment/unassignment, input hiding coordination. RecorderService — input recording state machine for button/axis/POV/mouse detection, Map All sequential flow, threshold-based axis detection. DsuMotionServer — UDP server lifecycle, subscription management. ForegroundMonitorService — GetForegroundWindow at 30 Hz, process name matching, profile switch triggering. WebControllerServer — HttpListener accept loop, WebSocket per-client I/O, static asset serving, WebControllerDevice creation. |
| 📊 | ViewModels | ViewModelBase built on CommunityToolkit.Mvvm ObservableObject with weak-event CultureChanged for live language switching. MainViewModel — navigation, sidebar items, profile list, engine status. DashboardViewModel — SlotSummary cards, engine toggle commands, DSU/web controller status. PadViewModel — per-slot mapping grid (MappingItem rows), StickConfigItem/TriggerConfigItem dead zone models, MacroItem state machine, VJoySlotConfig/MidiSlotConfig, output snapshots for all 5 controller types, recording flow. DevicesViewModel/DeviceRowViewModel — device cards, AxisDisplayItem/ButtonDisplayItem/PovDisplayItem for live visualization, slot toggle commands. SettingsViewModel — theme, polling, driver status, file operations. Supporting types — MappingItem source dropdown, MacroItem trigger/action/repeat models. |
| 🖼 | XAML Views | MainWindow shell — NavigationView sidebar with programmatic controller cards, visibility-swapped pages, drag reordering with adorners, cross-panel device drag-drop, Add Controller popup with per-type capacity checks, status bar, and driver overlay. DashboardPage — engine toggle, slot cards in WrapPanel, DSU/web controller/driver status. PadPage — custom RadioButton tab strip, 6 tab panels (Controller, Macros, Mappings, Sticks, Triggers, Force Feedback), view switching across 3D/2D/Schematic/KBM/MIDI preview, vJoy/MIDI config bars, multi-device selector, Copy From dialog. DevicesPage — card ListBox with accent selection bar, raw input visualization (axes/buttons/POV/gyro/keyboard/mouse), slot toggle buttons, input hiding toggles. SettingsPage — card-based sections, driver cards, HidHide whitelist. ProfilesPage — profile ListBox with topology badges. 14 value converters, theme switching, Segoe MDL2 icons, and code-behind patterns (Bind/Unbind, CompositionTarget.Rendering with dirty flag, flash animation). |
| 🎮 | 3D Model System | Render Xbox 360 and DualShock 4 controller models from Wavefront OBJ meshes via HelixToolkit.WPF (adapted from Handheld Companion, CC BY-NC-SA 4.0). ControllerModelBase abstract class with ButtonMap/ClickMap/DefaultMaterials/HighlightMaterials dictionaries, embedded resource loading (MSBuild digit-prefix suffix matching), and ButtonFileMap for OBJ-to-PadSetting name mapping. Xbox 360 model — colored face button overlays, guide ring/LED, 7-color palette. DS4 model — PlayStation symbol meshes, touchpad screen. ControllerModelView — HelixViewport3D with custom Preview-event rotation/zoom/pan (all built-in controls disabled), click-to-record via 3D ray-cast hit testing, stick ring quadrant detection (Sutherland-Hodgman clipping), hover highlighting, 400 ms flash animation with arrow and quadrant ring overlays, and gradient material blending for sticks/triggers. |
| 🗺 | 2D Overlay System | Render resolution-independent PNG overlays via Canvas inside Viewbox. Auto-generated ControllerOverlayLayout.cs (overlay_positions.py, SVG parsing + OpenCV template matching). ControllerModel2DView — base image + overlay images at Z-layers, trigger gas-tank fill (RectangleGeometry clip), stick translation transforms, quadrant hover/flash (CombinedGeometry clips), click-to-record with quadrant axis detection. ControllerSchematicView — procedural vJoy view with StickWidget/TriggerWidget/PovWidget/ButtonWidget structs, dynamic layout from VJoySlotConfig.ComputeAxisLayout, hover direction arrows, click-to-record targeting VJoyAxis/VJoyBtn/VJoyPov names. KBMPreviewView — QWERTY keyboard (KeyboardKeyItem.BuildLayout) + contoured mouse graphic (LMB/RMB/scroll/movement circle/X1/X2), per-VK-code highlighting, movement dot tracking. MidiPreviewView — CC vertical bar sliders + musically correct piano keyboard (white/black key layout), live CC value and note state rendering. |
| 📨 | DSU Protocol Implementation | MotionSnapshot struct carrying g-force acceleration and degrees/sec gyro with SDL-to-DSU axis mapping and sign inversions. DsuMotionServer — UDP socket on loopback, SIO_UDP_CONNRESET suppression, background receive thread. Packet format: 16-byte header (magic/version/CRC32/server ID), version request/response, controller info request/response (4-slot limit, fake MAC addresses), pad data request/subscription (per-slot and all-slot modes, 5-second expiry), pad data response (84-byte payload with zeroed button/stick/touch data, real motion timestamp, 6-axis accel/gyro floats). CRC32 implementation, subscription management with high-resolution timestamp pruning, and DsuDiag standalone diagnostic tool. |
| 🔧 | Driver Installation Internals | DriverInstaller static class with embedded resources (ViGEmBus EXE, HidHide EXE, vJoyDriver.zip). ViGEmBus — WiX bootstrapper extraction, MSI via msiexec with UAC, registry version detection. HidHide — same WiX/MSI pattern, product code extraction for uninstall. vJoy — single elevated PowerShell script: pre-install cleanup (critical node-before-service removal order), ZIP extraction to Program Files, pnputil driver store add, SetupAPI device node creation with inline C# P/Invoke. vJoy uninstall — batch script with exhaustive registry cleanup across all ControlSets. Windows MIDI Services — GitHub API release query, ~210 MB download, WiX Burn bootstrapper. HidHideController runtime IOCTL API — blacklist/whitelist/cloaking via \.\HidHide device, Multi-SZ buffer format, managed device tracking, DOS device path conversion. Uninstall guard conditions and elevation strategy. |
| 📦 | Engine Library | PadForge.Engine assembly — Gamepad struct (XInput layout, button flag constants), VJoyRawState (dynamic axes/buttons/POVs for custom DirectInput), MidiRawState (dynamic CC/note arrays), KbmRawState (256-bit key bitmask + mouse deltas + scroll + 5 mouse buttons, Combine method). VirtualControllerType enum and IVirtualController interface. CustomInputState (24 axes, 8 sliders, 4 POVs, 256 buttons, 3-axis gyro/accel). ISdlInputDevice (identity, capabilities, haptic, state reading, rumble). WebControllerDevice (browser gamepad, VID 0xBEEF/PID 0xCA7E). DeviceObjectItem and InputTypes (DeviceObjectTypeFlags, ObjectGuid constants matching DirectInput). ForceFeedbackState (change-detection rumble, haptic strategy dispatch, condition effects). Vibration (scalar motors + directional FFB + condition axis data). RumbleLogger, InputHookManager (WH_KEYBOARD_LL/WH_MOUSE_LL with volatile suppression sets), RawInputListener (HWND_MESSAGE thread, per-device keyboard/mouse state), SdlMouseWrapper (scroll wheel intensity tracking), and MappingTranslation (positional equivalence across 5 controller layouts). |
| 🛠 | Build and Publish | Prerequisites — .NET 10 SDK, Windows 10/11 x64. Build with dotnet publish -c Release (never dotnet build). Produces a single-file, self-contained, compressed ~85 MB EXE with embedded .NET runtime and debug symbols. Project configuration — WinExe, WPF+WinForms for NotifyIcon, WinForms implicit using removal. Version management via manual AssemblyInfo.cs. NuGet dependencies — ModernWpfUI, HelixToolkit, CommunityToolkit.Mvvm, ViGEm.Client, NAudio.Wasapi, Windows MIDI Services SDK from local source. Native DLLs — SDL3.dll and libusb-1.0.dll as Content with Link flattening. Embedded resources — driver installers, 3D OBJ meshes, 2D PNG overlays. Portable deployment with no installer. Release workflow — version update, build, deploy, test, commit, GitHub release via gh CLI. Diagnostic tools — DsuDiag, VJoyTest, FfbTest. Build troubleshooting table. |
Built with SDL3, ViGEmBus, vJoy, HelixToolkit, .NET 10 WPF, and Fluent Design.