A cross-platform input redirection client for Nintendo 3DS, rewritten in Rust.
Captures gamepad input (buttons, analog sticks) and touch screen events, then sends them over UDP to a 3DS running InputRedirection custom firmware.
- Full 3DS input support: buttons, circle pad, C-stick, touch screen, Home/Power
- Configurable button remapping (19 mappable buttons)
- Touch screen with mouse input and 2 preset shortcut buttons
- A/B and X/Y swap toggles
- Y-axis inversion for analog sticks
- Persistent TOML configuration
- Multi-gamepad support (all connected controllers merged)
- 20 Hz polling (50ms tick)
- A Nintendo 3DS with InputRedirection enabled
- A gamepad connected to your PC
Download the latest release from the Releases page.
| Platform | Archive |
|---|---|
| Linux x86_64 | input-redirection-client-linux-x86_64.tar.gz |
| macOS ARM64 | input-redirection-client-macos-arm64.tar.gz |
| Windows x86_64 | input-redirection-client-windows-x86_64.zip |
# Linux: install system dependencies first
sudo apt-get install libxkbcommon-dev libwayland-dev libfontconfig1-dev libudev-dev
# Build
cargo build --releaseThe binary will be at target/release/input-redirection-client-rs.
- Launch the application
- Enter your 3DS IP address in the Main tab
- Connect a gamepad — inputs are sent automatically
- Use the Touch Screen tab for touch input via mouse
- Use the Button Config tab to remap buttons and configure touch presets
Clean architecture with SOLID principles:
src/
├── main.rs # Entry point, dependency wiring
├── domain/ # Pure business logic (no external deps)
│ ├── models.rs # Data structures, enums, config
│ ├── input_mapper.rs # Button mapping, coordinate transforms
│ └── protocol.rs # 3DS HID frame encoding (20-byte UDP)
├── ports/ # Trait definitions (interfaces)
│ ├── gamepad_port.rs # GamepadPort trait
│ ├── network_port.rs # NetworkPort trait
│ └── settings_port.rs # SettingsPort trait
├── infrastructure/ # External I/O implementations
│ ├── gamepad_adapter.rs # gilrs wrapper
│ ├── network_sender.rs # UDP socket sender
│ └── settings_store.rs # TOML file persistence
├── application/ # Use case orchestration
│ ├── input_service.rs # Poll → map → encode → send
│ └── config_service.rs # Load/save settings
└── ui/
├── app.slint # Slint UI definition
└── bridge.rs # UI ↔ application bridge
Sends 20-byte little-endian UDP datagrams to port 4950:
| Offset | Field | Description |
|---|---|---|
| 0-3 | hidPad | Button bitmask (active-low, 12-bit) |
| 4-7 | touchScreenState | Touch coordinates + pressed flag |
| 8-11 | circlePadState | Left stick (12-bit X/Y) |
| 12-15 | cppState | Right stick with 45° rotation (8-bit) + ZL/ZR |
| 16-19 | interfaceButtons | Home, Power, Power Long |
Based on the original InputRedirectionClient-Qt by TuxSH.