diff --git a/.github/workflows/build-device-config.yml b/.github/workflows/build-device-config.yml index 94afa079..541be7b5 100644 --- a/.github/workflows/build-device-config.yml +++ b/.github/workflows/build-device-config.yml @@ -34,7 +34,7 @@ jobs: BIN_EXT: ${{ matrix.bin_ext }} strategy: fail-fast: false - matrix: + matrix: include: ${{ fromJson(needs.metadata.outputs.meta_json).build }} steps: diff --git a/HAL/pico/include/comms/NintendoSwitchBackend.hpp b/HAL/pico/include/comms/NintendoSwitchBackend.hpp index 0d16ac39..1f5c76f0 100644 --- a/HAL/pico/include/comms/NintendoSwitchBackend.hpp +++ b/HAL/pico/include/comms/NintendoSwitchBackend.hpp @@ -55,7 +55,7 @@ class NintendoSwitchBackend : public CommunicationBackend { protected: static const uint8_t _report_id = 0; - static uint8_t _descriptor[]; + static const uint8_t _descriptor[]; switch_gamepad_report_t _report; diff --git a/HAL/pico/src/comms/NintendoSwitchBackend.cpp b/HAL/pico/src/comms/NintendoSwitchBackend.cpp index c4aab389..d480424d 100644 --- a/HAL/pico/src/comms/NintendoSwitchBackend.cpp +++ b/HAL/pico/src/comms/NintendoSwitchBackend.cpp @@ -2,6 +2,7 @@ #include "core/CommunicationBackend.hpp" #include "core/state.hpp" +#include "util/analog_filters.hpp" #include #include @@ -61,7 +62,10 @@ // clang-format on -uint8_t NintendoSwitchBackend::_descriptor[] = { HID_REPORT_DESC() }; +const uint8_t NintendoSwitchBackend::_descriptor[] = { HID_REPORT_DESC() }; + +const uint8_t DEADZONE = 11; +const int RADIUS = 256; NintendoSwitchBackend::NintendoSwitchBackend( InputState &inputs, @@ -139,10 +143,10 @@ void NintendoSwitchBackend::SendReport() { _report.home = _outputs.home; // Analog outputs - _report.lx = (_outputs.leftStickX - 128) * 1.25 + 128; - _report.ly = 255 - ((_outputs.leftStickY - 128) * 1.25 + 128); - _report.rx = (_outputs.rightStickX - 128) * 1.25 + 128; - _report.ry = 255 - ((_outputs.rightStickY - 128) * 1.25 + 128); + _report.lx = apply_radius(apply_deadzone(_outputs.leftStickX, DEADZONE, true), RADIUS); + _report.ly = 255 - apply_radius(apply_deadzone(_outputs.leftStickY, DEADZONE, true), RADIUS); + _report.rx = apply_radius(apply_deadzone(_outputs.rightStickX, DEADZONE, true), RADIUS); + _report.ry = 255 - apply_radius(apply_deadzone(_outputs.rightStickY, DEADZONE, true), RADIUS); // D-pad Hat Switch _report.hat = diff --git a/include/util/analog_filters.hpp b/include/util/analog_filters.hpp new file mode 100644 index 00000000..55420a0e --- /dev/null +++ b/include/util/analog_filters.hpp @@ -0,0 +1,9 @@ +#ifndef _UTIL_ANALOG_FILTERS_HPP +#define _UTIL_ANALOG_FILTERS_HPP + +#include "stdlib.hpp" + +uint8_t apply_deadzone(uint8_t value, uint8_t deadzone, bool scale); +uint8_t apply_radius(uint8_t value, int radius); + +#endif \ No newline at end of file diff --git a/lib/TUCompositeHID/include/TUCompositeHID.hpp b/lib/TUCompositeHID/include/TUCompositeHID.hpp index dce350df..e644e48b 100644 --- a/lib/TUCompositeHID/include/TUCompositeHID.hpp +++ b/lib/TUCompositeHID/include/TUCompositeHID.hpp @@ -7,7 +7,7 @@ namespace TUCompositeHID { extern Adafruit_USBD_HID _usb_hid; - bool addDescriptor(uint8_t *descriptor, size_t descriptor_len); + bool addDescriptor(const uint8_t *descriptor, size_t descriptor_len); } #endif \ No newline at end of file diff --git a/lib/TUCompositeHID/include/TUGamepad.hpp b/lib/TUCompositeHID/include/TUGamepad.hpp index 2e4c33a2..447cd689 100644 --- a/lib/TUCompositeHID/include/TUGamepad.hpp +++ b/lib/TUCompositeHID/include/TUGamepad.hpp @@ -67,7 +67,7 @@ class TUGamepad { protected: static const uint8_t _report_id = 1; - static uint8_t _descriptor[]; + static const uint8_t _descriptor[]; gamepad_report_t _report; diff --git a/lib/TUCompositeHID/include/TUKeyboard.hpp b/lib/TUCompositeHID/include/TUKeyboard.hpp index 7e430586..c4b9fc5f 100644 --- a/lib/TUCompositeHID/include/TUKeyboard.hpp +++ b/lib/TUCompositeHID/include/TUKeyboard.hpp @@ -20,7 +20,7 @@ class TUKeyboard { private: static const uint8_t _report_id = 2; - static uint8_t _descriptor[]; + static const uint8_t _descriptor[]; hid_keyboard_report_t _report; }; diff --git a/lib/TUCompositeHID/src/TUCompositeHID.cpp b/lib/TUCompositeHID/src/TUCompositeHID.cpp index acaa6b8c..e3fac0e5 100644 --- a/lib/TUCompositeHID/src/TUCompositeHID.cpp +++ b/lib/TUCompositeHID/src/TUCompositeHID.cpp @@ -16,7 +16,7 @@ namespace TUCompositeHID { false ); - bool addDescriptor(uint8_t *descriptor, size_t descriptor_len) { + bool addDescriptor(const uint8_t *descriptor, size_t descriptor_len) { if (_current_descriptor_len + descriptor_len > HID_DESCRIPTOR_BUFSIZE) { return false; } diff --git a/lib/TUCompositeHID/src/TUGamepad.cpp b/lib/TUCompositeHID/src/TUGamepad.cpp index aaefa094..f8b05af9 100644 --- a/lib/TUCompositeHID/src/TUGamepad.cpp +++ b/lib/TUCompositeHID/src/TUGamepad.cpp @@ -71,7 +71,7 @@ SOFTWARE. // clang-format on -uint8_t TUGamepad::_descriptor[] = { HID_REPORT_DESC(HID_REPORT_ID(_report_id)) }; +const uint8_t TUGamepad::_descriptor[] = { HID_REPORT_DESC(HID_REPORT_ID(_report_id)) }; TUGamepad::TUGamepad() {} diff --git a/lib/TUCompositeHID/src/TUKeyboard.cpp b/lib/TUCompositeHID/src/TUKeyboard.cpp index d3ac6cbc..b93887db 100644 --- a/lib/TUCompositeHID/src/TUKeyboard.cpp +++ b/lib/TUCompositeHID/src/TUKeyboard.cpp @@ -3,7 +3,9 @@ #include #include -uint8_t TUKeyboard::_descriptor[] = { TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(_report_id)) }; +// clang-format off +const uint8_t TUKeyboard::_descriptor[] = { TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(_report_id)) }; +// clang-format on #define MODIFIER_MASK(mod_kc) (1 << (mod_kc & 0x0F)) diff --git a/src/util/analog_filters.cpp b/src/util/analog_filters.cpp new file mode 100644 index 00000000..74e619df --- /dev/null +++ b/src/util/analog_filters.cpp @@ -0,0 +1,29 @@ +#include "util/analog_filters.hpp" + +#include + +#define SIGNUM(x) ((x > 0) - (x < 0)) + +uint8_t apply_deadzone(uint8_t value, uint8_t deadzone, bool scale) { + int8_t value_signed = value - 128; + if (abs(value_signed) > deadzone) { + // If outside deadzone, must subtract deadzone from result so that axis values start from 1 + // instead of having lower values cut off. + int8_t post_deadzone = value_signed - deadzone * SIGNUM(value_signed); + // If a radius value is passed in, scale up the values linearly so that the same effective + // value is given on the rim. + if (scale) { + int8_t sign = SIGNUM(post_deadzone); + int8_t post_scaling = min(127, abs(post_deadzone) * 128.0 / (128 - deadzone)) * sign; + return post_scaling + 128; + } + return post_deadzone + 128; + } + return 128; +} + +uint8_t apply_radius(uint8_t value, int radius) { + int8_t value_signed = value - 128; + int8_t sign = SIGNUM(value_signed); + return min(127, (int)(abs(value_signed) * radius / 128.0)) * sign + 128; +} \ No newline at end of file