Skip to content

Commit 46b3466

Browse files
committed
Fix various issues with NintendoSwitchBackend
NintendoSwitchBackend had several issues. Firstly, I messed up the descriptor, which was why this comms backend didn't work on PC. Secondly, because the Nintendo Switch apparently applies a deadzone and scaling to GameCube controller analog stick inputs, it was necessary to reverse engineer this scaling and replicate it in NintendoSwitchBackend so that we scale the inputs before sending them to the console, in the same way that the Switch would scale them after receiving them. Until now I have been using a naive multiplication which was not close enough to the actual formula to prevent input issues manifesting when using the Ultimate mode. Thanks to Zeronia, we have much more data now and I have been able to reverse engineer the scaling formula to get one that matches almost exactly. The only remaining considerations are that the GameCube controller C-Stick is apparently scaled differently to the left analog stick, and that I have only implemented a basic square deadzone rather than a circular deadzone. It is yet to be seen whether these things will cause any input inconsistencies in existing controller modes.
1 parent d3bc6bc commit 46b3466

File tree

11 files changed

+57
-13
lines changed

11 files changed

+57
-13
lines changed

.github/workflows/build-device-config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ jobs:
3434
BIN_EXT: ${{ matrix.bin_ext }}
3535
strategy:
3636
fail-fast: false
37-
matrix:
37+
matrix:
3838
include: ${{ fromJson(needs.metadata.outputs.meta_json).build }}
3939

4040
steps:

HAL/pico/include/comms/NintendoSwitchBackend.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class NintendoSwitchBackend : public CommunicationBackend {
5555

5656
protected:
5757
static const uint8_t _report_id = 0;
58-
static uint8_t _descriptor[];
58+
static const uint8_t _descriptor[];
5959

6060
switch_gamepad_report_t _report;
6161

HAL/pico/src/comms/NintendoSwitchBackend.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include "core/CommunicationBackend.hpp"
44
#include "core/state.hpp"
5+
#include "util/analog_filters.hpp"
56

67
#include <Adafruit_TinyUSB.h>
78
#include <TUCompositeHID.hpp>
@@ -61,7 +62,10 @@
6162

6263
// clang-format on
6364

64-
uint8_t NintendoSwitchBackend::_descriptor[] = { HID_REPORT_DESC() };
65+
const uint8_t NintendoSwitchBackend::_descriptor[] = { HID_REPORT_DESC() };
66+
67+
const uint8_t DEADZONE = 11;
68+
const int RADIUS = 256;
6569

6670
NintendoSwitchBackend::NintendoSwitchBackend(
6771
InputState &inputs,
@@ -139,10 +143,10 @@ void NintendoSwitchBackend::SendReport() {
139143
_report.home = _outputs.home;
140144

141145
// Analog outputs
142-
_report.lx = (_outputs.leftStickX - 128) * 1.25 + 128;
143-
_report.ly = 255 - ((_outputs.leftStickY - 128) * 1.25 + 128);
144-
_report.rx = (_outputs.rightStickX - 128) * 1.25 + 128;
145-
_report.ry = 255 - ((_outputs.rightStickY - 128) * 1.25 + 128);
146+
_report.lx = apply_radius(apply_deadzone(_outputs.leftStickX, DEADZONE, true), RADIUS);
147+
_report.ly = 255 - apply_radius(apply_deadzone(_outputs.leftStickY, DEADZONE, true), RADIUS);
148+
_report.rx = apply_radius(apply_deadzone(_outputs.rightStickX, DEADZONE, true), RADIUS);
149+
_report.ry = 255 - apply_radius(apply_deadzone(_outputs.rightStickY, DEADZONE, true), RADIUS);
146150

147151
// D-pad Hat Switch
148152
_report.hat =

include/util/analog_filters.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#ifndef _UTIL_ANALOG_FILTERS_HPP
2+
#define _UTIL_ANALOG_FILTERS_HPP
3+
4+
#include "stdlib.hpp"
5+
6+
uint8_t apply_deadzone(uint8_t value, uint8_t deadzone, bool scale);
7+
uint8_t apply_radius(uint8_t value, int radius);
8+
9+
#endif

lib/TUCompositeHID/include/TUCompositeHID.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
namespace TUCompositeHID {
88
extern Adafruit_USBD_HID _usb_hid;
99

10-
bool addDescriptor(uint8_t *descriptor, size_t descriptor_len);
10+
bool addDescriptor(const uint8_t *descriptor, size_t descriptor_len);
1111
}
1212

1313
#endif

lib/TUCompositeHID/include/TUGamepad.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ class TUGamepad {
6767

6868
protected:
6969
static const uint8_t _report_id = 1;
70-
static uint8_t _descriptor[];
70+
static const uint8_t _descriptor[];
7171

7272
gamepad_report_t _report;
7373

lib/TUCompositeHID/include/TUKeyboard.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class TUKeyboard {
2020

2121
private:
2222
static const uint8_t _report_id = 2;
23-
static uint8_t _descriptor[];
23+
static const uint8_t _descriptor[];
2424

2525
hid_keyboard_report_t _report;
2626
};

lib/TUCompositeHID/src/TUCompositeHID.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ namespace TUCompositeHID {
1616
false
1717
);
1818

19-
bool addDescriptor(uint8_t *descriptor, size_t descriptor_len) {
19+
bool addDescriptor(const uint8_t *descriptor, size_t descriptor_len) {
2020
if (_current_descriptor_len + descriptor_len > HID_DESCRIPTOR_BUFSIZE) {
2121
return false;
2222
}

lib/TUCompositeHID/src/TUGamepad.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ SOFTWARE.
7171

7272
// clang-format on
7373

74-
uint8_t TUGamepad::_descriptor[] = { HID_REPORT_DESC(HID_REPORT_ID(_report_id)) };
74+
const uint8_t TUGamepad::_descriptor[] = { HID_REPORT_DESC(HID_REPORT_ID(_report_id)) };
7575

7676
TUGamepad::TUGamepad() {}
7777

lib/TUCompositeHID/src/TUKeyboard.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
#include <Adafruit_TinyUSB.h>
44
#include <TUCompositeHID.hpp>
55

6-
uint8_t TUKeyboard::_descriptor[] = { TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(_report_id)) };
6+
// clang-format off
7+
const uint8_t TUKeyboard::_descriptor[] = { TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(_report_id)) };
8+
// clang-format on
79

810
#define MODIFIER_MASK(mod_kc) (1 << (mod_kc & 0x0F))
911

0 commit comments

Comments
 (0)