Fix Windows adapter enumeration and rumble

This commit is contained in:
Joey Yakimowich-Payne 2026-09-02 12:29:57 -06:00
commit db4a860cd6
10 changed files with 363 additions and 44 deletions

View file

@ -575,10 +575,18 @@ void test_independent_lifecycle() {
for (int slot = 0; slot < kSlotCount; ++slot) {
require(devices[slot].rumble_calls == 1 &&
devices[slot].last_low == 11 + slot &&
devices[slot].last_high == 21 + slot,
devices[slot].last_high == 21 + slot &&
devices[slot].last_rumble_duration_ms ==
kRumbleDurationMs,
"each slot rumble must reach only its indexed controller");
}
bluepad32_input_backend_queue_rumble(0, SwitchRumbleOutput{0, 0});
process_rumble_timer(&g_rumble_timer);
require(devices[0].rumble_calls == 2 &&
devices[0].last_rumble_duration_ms == 0,
"zero XInput magnitude must stop rumble immediately");
bluepad32_input_backend_queue_rumble(3, SwitchRumbleOutput{55, 66});
const uint32_t disconnected_generation =
g_slots[3].connection_generation;

View file

@ -10,9 +10,10 @@ def test_bluepad32_backend_lifecycle_native(tmp_path: Path) -> None:
compiler = shutil.which("c++") or shutil.which("g++")
assert compiler is not None, "a host C++ compiler is required"
executable = tmp_path / "bluepad32_backend_lifecycle_test"
subprocess.run(
[
for adapter_feasibility in (False, True):
suffix = "_adapter" if adapter_feasibility else ""
executable = tmp_path / f"bluepad32_backend_lifecycle_test{suffix}"
command = [
compiler,
"-std=c++17",
"-Wall",
@ -20,27 +21,31 @@ def test_bluepad32_backend_lifecycle_native(tmp_path: Path) -> None:
"-Werror",
"-pedantic",
"-DSWITCH_PICO_HID_INSTANCE_COUNT=4",
f"-I{root / 'tests' / 'bluepad32_native_stubs'}",
f"-I{root}",
str(root / "tests" / "bluepad32_backend_lifecycle_test.cpp"),
"-o",
str(executable),
],
check=True,
cwd=root,
)
]
if adapter_feasibility:
command.append("-DSWITCH_PICO_ADAPTER_FEASIBILITY=1")
command.extend(
[
f"-I{root / 'tests' / 'bluepad32_native_stubs'}",
f"-I{root}",
str(root / "tests" / "bluepad32_backend_lifecycle_test.cpp"),
"-o",
str(executable),
]
)
subprocess.run(command, check=True, cwd=root)
for scenario in (
"ready-forward",
"ready-reverse",
"rejections",
"lifecycle",
"pairing-policy",
"slot-lighting",
"abxy-hotkey",
"motion-hotkey",
"clear-pairings",
"flash-core-start",
"flash-core-failure",
):
subprocess.run([str(executable), scenario], check=True, cwd=root)
for scenario in (
"ready-forward",
"ready-reverse",
"rejections",
"lifecycle",
"pairing-policy",
"slot-lighting",
"abxy-hotkey",
"motion-hotkey",
"clear-pairings",
"flash-core-start",
"flash-core-failure",
):
subprocess.run([str(executable), scenario], check=True, cwd=root)

View file

@ -19,6 +19,7 @@ def test_bluepad32_imu_normalization_native(tmp_path: Path) -> None:
"-Wextra",
"-Werror",
"-pedantic",
f"-I{root / 'bluepad32_config'}",
f"-I{root / 'external' / 'bluepad32' / 'src' / 'components' / 'bluepad32' / 'include'}",
str(root / "tests" / "bluepad32_imu_normalization_test.cpp"),
"-o",

View file

@ -32,10 +32,27 @@ uint32_t read_le32(const uint8_t *data) {
void test_device_and_configuration_descriptors() {
using namespace XInputFeasibility;
expect(read_le16(&kSwitchProbeDeviceDescriptor[8]) ==
kSwitchProbeVendorId,
"Switch probe VID mismatch");
expect(read_le16(&kSwitchProbeDeviceDescriptor[10]) ==
kSwitchProbeProductId,
"Switch probe PID mismatch");
expect(read_le16(&kSwitchProbeDeviceDescriptor[12]) ==
kSwitchProbeDeviceRevision,
"Switch probe revision mismatch");
expect(kSwitchProbeDeviceRevision != 0x0210,
"Switch probe reuses the genuine controller cache identity");
expect(read_le16(&kDeviceDescriptor[8]) == kPrototypeVendorId,
"prototype VID mismatch");
expect(read_le16(&kDeviceDescriptor[10]) == kPrototypeProductId,
"prototype PID mismatch");
expect(read_le16(&kDeviceDescriptor[12]) ==
kPrototypeDeviceRevision,
"prototype revision mismatch");
expect(kDeviceDescriptor[4] == 0 && kDeviceDescriptor[5] == 0 &&
kDeviceDescriptor[6] == 0,
"multi-interface prototype is not a composite USB device");
expect(kPrototypeVendorId != 0x045e,
"prototype must not impersonate Microsoft's VID");
expect(read_le16(&kConfigurationDescriptor[2]) ==