Support Bluepad32 gamepads as native Joy-Con pair sources

This commit is contained in:
Joey Yakimowich-Payne 2026-09-12 23:03:15 -06:00
commit a17ca603aa
33 changed files with 2529 additions and 851 deletions

View file

@ -13,8 +13,8 @@
#include <inttypes.h>
extern "C" int probe_debug_printf(const char* format, ...);
#endif
#if SWITCH2_BRIDGE_DUALSENSE_INPUT
#include "dualsense_input.h"
#if SWITCH2_BRIDGE_FULL_INPUT
#include "native_gamepad_input.h"
#endif
#if SWITCH2_BRIDGE_WII_INPUT
#include <math.h>
@ -26,9 +26,9 @@ extern "C" int probe_debug_printf(const char* format, ...);
#if !SWITCH_PICO_SWITCH2_USB_BRIDGE || !SWITCH_PICO_BLUEPAD32
#error "The controller bridge requires Bluepad32"
#elif SWITCH2_BRIDGE_DUALSENSE_INPUT
#if !SWITCH_PICO_ENABLE_CLASSIC
#error "The DualSense bridge requires Classic Bluetooth"
#elif SWITCH2_BRIDGE_FULL_INPUT
#if SWITCH2_BRIDGE_DUALSENSE_INPUT && !SWITCH_PICO_ENABLE_CLASSIC
#error "The DualSense source requires Classic Bluetooth"
#endif
#elif !SWITCH_PICO_ENABLE_BLE || !SWITCH_PICO_SWITCH2_MOUSE_CAPTURE || \
!SWITCH_PICO_SWITCH2_MOUSE_CAPTURE_NATIVE
@ -36,7 +36,7 @@ extern "C" int probe_debug_printf(const char* format, ...);
#endif
namespace {
#if !SWITCH2_BRIDGE_DUALSENSE_INPUT
#if !SWITCH2_BRIDGE_FULL_INPUT
constexpr uint8_t kSourceAddress[] = {SWITCH2_BRIDGE_SOURCE_ADDRESS_BYTES};
static_assert(sizeof(kSourceAddress) == 6, "Select one physical Bluetooth address");
#if SWITCH2_PROBE_COMPOSITE || SWITCH2_PROBE_HUB
@ -56,7 +56,7 @@ bool g_start_attempted;
bool g_flash_ready;
#if SWITCH2_BRIDGE_WII_INPUT
probe_controller_input g_input;
#elif !SWITCH2_BRIDGE_DUALSENSE_INPUT
#elif !SWITCH2_BRIDGE_FULL_INPUT
probe_controller_input g_inputs[PROBE_CONTROLLER_COUNT];
uint32_t g_received_times[PROBE_CONTROLLER_COUNT];
#endif
@ -382,9 +382,9 @@ extern "C" void probe_controller_input_clock_init(void) {
extern "C" void probe_controller_input_init(void) {
if (g_initialized) return;
#if SWITCH2_BRIDGE_DUALSENSE_INPUT
#if SWITCH2_BRIDGE_FULL_INPUT
bluepad32_input_backend_init();
probe_dualsense_input_init();
probe_native_gamepad_input_init();
#elif SWITCH2_BRIDGE_WII_INPUT
bluepad32_input_backend_init();
bluepad32_input_backend_select_wii_source(kSourceAddress);
@ -484,17 +484,17 @@ extern "C" void probe_controller_input_set_native_features(uint8_t features) {
}
#endif
#if SWITCH2_BRIDGE_DUALSENSE_INPUT
#if SWITCH2_BRIDGE_FULL_INPUT
extern "C" void probe_controller_input_set_full_stick_calibration(
uint8_t instance, const uint8_t calibration[9]) {
probe_dualsense_input_set_stick_calibration(instance, calibration);
probe_native_gamepad_input_set_stick_calibration(instance, calibration);
}
#endif
extern "C" void probe_controller_input_set_native_stream(uint8_t instance, bool enabled) {
if (instance >= PROBE_CONTROLLER_COUNT) return;
#if SWITCH2_BRIDGE_DUALSENSE_INPUT
probe_dualsense_input_set_native_stream(instance, enabled && g_flash_ready);
#if SWITCH2_BRIDGE_FULL_INPUT
probe_native_gamepad_input_set_native_stream(instance, enabled && g_flash_ready);
#elif SWITCH2_BRIDGE_WII_INPUT
enabled = enabled && g_flash_ready;
if (g_native_stream != enabled || !enabled) discard_wii_output();
@ -508,8 +508,8 @@ extern "C" void probe_controller_input_set_native_stream(uint8_t instance, bool
extern "C" uint32_t probe_controller_input_peek_native_report(
uint8_t instance, uint32_t now_ms, uint8_t report[63]) {
if (instance >= PROBE_CONTROLLER_COUNT || !g_flash_ready) return 0;
#if SWITCH2_BRIDGE_DUALSENSE_INPUT
return probe_dualsense_input_peek_native_report(instance, now_ms, report);
#if SWITCH2_BRIDGE_FULL_INPUT
return probe_native_gamepad_input_peek_native_report(instance, now_ms, report);
#elif SWITCH2_BRIDGE_WII_INPUT
(void)now_ms;
return prepare_wii_report(report);
@ -520,8 +520,8 @@ extern "C" uint32_t probe_controller_input_peek_native_report(
extern "C" bool probe_controller_input_commit_native_report(uint8_t instance, uint32_t serial) {
if (instance >= PROBE_CONTROLLER_COUNT || !g_flash_ready) return false;
#if SWITCH2_BRIDGE_DUALSENSE_INPUT
return probe_dualsense_input_commit_native_report(instance, serial);
#if SWITCH2_BRIDGE_FULL_INPUT
return probe_native_gamepad_input_commit_native_report(instance, serial);
#elif SWITCH2_BRIDGE_WII_INPUT
if (!g_native_stream || !serial || serial != g_pending_serial ||
g_pending_generation != g_wii_generation || !g_wii_active) return false;
@ -543,8 +543,8 @@ extern "C" bool probe_controller_input_play_sample(uint8_t instance, uint8_t sam
if (token != nullptr) *token = 0;
return false;
}
#if SWITCH2_BRIDGE_DUALSENSE_INPUT
return bluepad32_input_backend_dualsense_sample_request(instance, sample_id, token);
#if SWITCH2_BRIDGE_FULL_INPUT
return bluepad32_input_backend_native_sample_request(instance, sample_id, token);
#elif SWITCH2_BRIDGE_WII_INPUT
return bluepad32_input_backend_wii_sample_request(sample_id, token);
#else
@ -555,9 +555,9 @@ extern "C" bool probe_controller_input_play_sample(uint8_t instance, uint8_t sam
extern "C" int probe_controller_input_sample_result(uint8_t instance, uint64_t token, uint32_t now_ms) {
if (instance >= PROBE_CONTROLLER_COUNT || !g_flash_ready) return -1;
#if SWITCH2_BRIDGE_DUALSENSE_INPUT
#if SWITCH2_BRIDGE_FULL_INPUT
(void)now_ms;
return bluepad32_input_backend_dualsense_sample_result(instance, token);
return bluepad32_input_backend_native_sample_result(instance, token);
#elif SWITCH2_BRIDGE_WII_INPUT
(void)now_ms;
return bluepad32_input_backend_wii_sample_result(token);
@ -568,8 +568,8 @@ extern "C" int probe_controller_input_sample_result(uint8_t instance, uint64_t t
extern "C" void probe_controller_input_cancel_sample(uint8_t instance) {
if (instance >= PROBE_CONTROLLER_COUNT) return;
#if SWITCH2_BRIDGE_DUALSENSE_INPUT
bluepad32_input_backend_dualsense_sample_cancel(instance);
#if SWITCH2_BRIDGE_FULL_INPUT
bluepad32_input_backend_native_sample_cancel(instance);
#elif SWITCH2_BRIDGE_WII_INPUT
bluepad32_input_backend_wii_sample_cancel();
#else
@ -584,8 +584,8 @@ extern "C" void probe_controller_input_poll(uint8_t instance, uint32_t now_ms,
*out = {};
return;
}
#if SWITCH2_BRIDGE_DUALSENSE_INPUT
probe_dualsense_input_poll(instance, now_ms, out);
#if SWITCH2_BRIDGE_FULL_INPUT
probe_native_gamepad_input_poll(instance, now_ms, out);
return;
#elif SWITCH2_BRIDGE_WII_INPUT
poll_wii_source(now_ms);
@ -618,7 +618,7 @@ extern "C" void probe_controller_input_poll(uint8_t instance, uint32_t now_ms,
g_input.mouse_surface = 0;
}
#endif
#if !SWITCH2_BRIDGE_DUALSENSE_INPUT
#if !SWITCH2_BRIDGE_FULL_INPUT
*out = g_input;
#endif
}