Skip to content

feat(target): add 8BitDo Ultimate 2 Wireless controller emulation#544

Open
honjow wants to merge 2 commits intoShadowBlip:mainfrom
honjow:8bitdo-u2
Open

feat(target): add 8BitDo Ultimate 2 Wireless controller emulation#544
honjow wants to merge 2 commits intoShadowBlip:mainfrom
honjow:8bitdo-u2

Conversation

@honjow
Copy link
Contributor

@honjow honjow commented Mar 5, 2026

Adds a 8bitdo-u2 target device that emulates the 8BitDo Ultimate 2 Wireless in DInput mode (VID=0x2DC8, PID=0x6012) via UHID.

Steam uses SDL_hidapi_8bitdo.c to identify and parse this device by VID/PID, reading the 34-byte input report at fixed offsets. The HID report structure and IMU coordinate mapping are derived from that source.

Supported features:

  • Buttons: face, shoulder, triggers, d-pad, L4/R4/PL/PR back buttons
  • Gyroscope and accelerometer (axes and signs verified on hardware)
  • Rumble via HID output report ID 0x05

To support rumble routing, this also adds OutputEvent::Rumble and a process_rumble handler in the evdev gamepad source that keeps a single persistent FF_RUMBLE effect alive and updates its magnitude in-place.

A udev rule is included to grant hidraw access so Steam can open the virtual device without root.

Tested on MSI Claw 8 and GPD Win5 .

image

honjow added 2 commits March 6, 2026 16:53
Emulates the 8BitDo Ultimate 2 Wireless controller (DInput mode,
VID=0x2DC8/PID=0x6012) as a UHID target device.

- HID report structure derived from SDL_hidapi_8bitdo.c
- Full button mapping including L4/R4/PL/PR back buttons
- Gyroscope and accelerometer with coordinate rotation matching SDL
- Rumble support via OutputEvent::Rumble routed through evdev FF
- Add generic OutputEvent::Rumble variant and process_rumble handler
  in evdev gamepad source for direct magnitude-based rumble control
Allow the current session user to read/write the UHID hidraw node
(VID=0x2DC8, PID=0x6012) so Steam can use the emulated device.
OutputEvent::DualSense(report) => report.use_rumble_not_haptics,
OutputEvent::SteamDeckHaptics(_) => true,
OutputEvent::SteamDeckRumble(_) => true,
OutputEvent::Rumble { .. } => true,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not familiar with this syntax, what does { .. } do?

DualSense(SetStatePackedOutputData),
SteamDeckHaptics(PackedHapticReport),
SteamDeckRumble(PackedRumbleReport),
Rumble {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason UinputOutputEvent wasn't usable here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants