Skip to content

Add Nintendo Switch 2 Pro controller support - #19

Merged
Alia5 merged 3 commits into
Alia5:mainfrom
Cookiekira:main
May 31, 2026
Merged

Add Nintendo Switch 2 Pro controller support#19
Alia5 merged 3 commits into
Alia5:mainfrom
Cookiekira:main

Conversation

@Cookiekira

@Cookiekira Cookiekira commented May 22, 2026

Copy link
Copy Markdown
Contributor

Description

Adds Nintendo Switch 2 Pro / NS2 Pro virtual USB HID device support to VIIPER.

This includes the NS2 Pro device implementation, input state and output feedback handling, USB/HID descriptors for host recognition, registry integration for the API device type ns2pro, a focused Go example, and device documentation.

Related Issue

N/A

Motivation and Context

This change lets VIIPER create a virtual Nintendo Switch 2 Pro Controller over USB so host-side software can interact with it through the existing VIIPER API and device streaming model.

How Has This Been Tested?

  • Unit tests
  • go test ./...
  • Targeted tests for device/ns2pro, internal/server/usb, device, and internal/server/api/handler

Type of Change

  • Bug fix (non-breaking change addressing an issue)
  • New feature (non-breaking change adding functionality)
  • Breaking change (fix or feature causing existing functionality to change)
  • Documentation update

Checklist

  • My code follows the code style of this project
  • I have updated the documentation accordingly
  • I have added tests to cover my changes
  • All new and existing tests passed

@Cookiekira Cookiekira changed the title Add NS2 Pro library support for Steam Input-compatible HID forwarding Add Nintendo Switch 2 Pro controller support May 22, 2026
@Cookiekira
Cookiekira marked this pull request as ready for review May 22, 2026 17:06
@Alia5

Alia5 commented May 25, 2026

Copy link
Copy Markdown
Owner

Thank you so much for your contribution.

I haven't looked in detail; however, the cgo-part in usb/server.go is rather problematic.
No cgo should be used outside of libVIIPER

@Alia5

Alia5 commented May 25, 2026

Copy link
Copy Markdown
Owner

Please also tell your LLM to clean up / rebase the commits.

Additionally, make sure the last line of a commit tthat should show up the changelog contains Changelog: feat|fix|misc.
See https://docs.gitlab.com/development/changelog/ for more info as we are doing something similar here.

Adds XYZ and exposes ABC

Please do 1 PR per atomic change; don't bundle multiple changes into a single PR.

Your second change is problematic anway, as I've commented before.
I'm also not sure if this is even needed, probably not.
What was your LLMs goal with this?

@Alia5

Alia5 commented May 26, 2026

Copy link
Copy Markdown
Owner

LMAO

@Cookiekira

Cookiekira commented May 26, 2026

Copy link
Copy Markdown
Contributor Author

It now only adds NS2 Pro virtual USB HID device support, plus the minimal generic USB descriptor support, tests, docs, and a Go example feature.

The USB descriptor/server changes are needed because the NS2 ProCon is not just a simple single-interface HID device.
It needs custom configuration descriptor fields instead of the server defaults. All works are based on https://github.com/ndeadly/switch2_controller_research.

I tried to keep this PR focused only on the virtual NS2 Pro USB HID device support.
My original goal was to expose this through libVIIPER via cgo so an external app could translate the NS2 Pro controller’s custom BLE protocol into a wired USB device shape that Steam Input already recognizes.

The implementation is a bit tricky because it needs some USB descriptor/server support for the NS2 Pro enumeration path. If you feel this is still too much for VIIPER or not suitable to merge, please feel free to close it. I appreciate the review either way.

Thank you for taking the time to look at this.

74234c80-4349-48da-b425-19c31c4eeb1a f1b1f0fd-a37a-4642-9d5a-0bba836d2b41

@Alia5

Alia5 commented May 27, 2026

Copy link
Copy Markdown
Owner

My original goal was to expose this through libVIIPER via cgo so an external app could translate the NS2 Pro controller’s custom BLE protocol into a wired USB device shape that Steam Input already recognizes.

That's a smart way to workaround this!
Should also be useful for my NSO GC Controller, then!

I don't think the cgo additions in the USBServer were at all necessary for that, though.
Either way overall I think this is a very welcome addition to VIIPER and I'll merge and look at what else and how it'd be best done very soon.

Thank you, again!

@Alia5

Alia5 commented May 27, 2026

Copy link
Copy Markdown
Owner

I additionally now noticed the presence of battery and charging state in the InputState struct.
This is probably fine for the merge, but in the long run, VIIPER should really support setting stuff like this via other means as well, as to keep the transmitted state just input-related.
Again, I'll take a deeper look soon

@codecov

codecov Bot commented May 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 75.21127% with 176 lines in your changes missing coverage. Please review.
✅ Project coverage is 43.30%. Comparing base (f4eda9b) to head (25be0ea).

Files with missing lines Patch % Lines
device/ns2pro/device.go 73.83% 32 Missing and 13 partials ⚠️
device/ns2pro/handler.go 50.00% 25 Missing and 12 partials ⚠️
device/ns2pro/commands.go 62.79% 29 Missing and 3 partials ⚠️
internal/server/usb/server.go 59.25% 17 Missing and 5 partials ⚠️
usb/usbdesc.go 77.31% 20 Missing and 2 partials ⚠️
device/ns2pro/inputstate.go 88.54% 7 Missing and 8 partials ⚠️
device/ns2pro/flash.go 81.25% 2 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #19      +/-   ##
==========================================
+ Coverage   36.68%   43.30%   +6.62%     
==========================================
  Files          72       78       +6     
  Lines        5139     5837     +698     
==========================================
+ Hits         1885     2528     +643     
+ Misses       3011     3003       -8     
- Partials      243      306      +63     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Alia5
Alia5 force-pushed the main branch 3 times, most recently from 1013721 to 717a95e Compare May 28, 2026 20:40
@Alia5
Alia5 merged commit 2906465 into Alia5:main May 31, 2026
10 of 14 checks passed
@Alia5

Alia5 commented May 31, 2026

Copy link
Copy Markdown
Owner

@Cookiekira

  • I've factored out the non-input (aka "meta") state from the Input-State (incl serial number override)
  • Added serial de-duplication (causes problems if more than 1 controller with the same serial is connected)
  • Added a wrapper for libVIIPER
  • Made sure TCP-Client libs work with this

Thanks again

My original goal was to expose this through libVIIPER via cgo so an external app could translate the NS2 Pro controller’s custom BLE protocol into a wired USB device shape that Steam Input already recognizes.

You should be good to Go! ;)

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