From aed495ae54ff405acada9c2e085f7c83d9bcc64a Mon Sep 17 00:00:00 2001 From: Naxdy Date: Wed, 3 Apr 2024 19:44:02 +0000 Subject: [PATCH] feat: implement input filters (#7) Reviewed-on: https://git.naxdy.org/NaxdyOrg/NaxGCC-FW/pulls/7 --- src/config.rs | 7 ++- src/input.rs | 5 ++ src/input_filter.rs | 109 ++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 1 + 4 files changed, 120 insertions(+), 2 deletions(-) create mode 100644 src/input_filter.rs diff --git a/src/config.rs b/src/config.rs index b1514b6..f087179 100644 --- a/src/config.rs +++ b/src/config.rs @@ -445,7 +445,7 @@ pub struct OverrideStickState { #[allow(dead_code)] #[derive(Clone, Copy, Debug, Format)] -enum AwaitableButtons { +pub enum AwaitableButtons { A, B, X, @@ -731,7 +731,10 @@ impl<'a, T: RawMutex, const I: usize, const J: usize, const K: usize> WaitForBut } } -fn is_awaitable_button_pressed(report: &GcReport, button_to_wait_for: &AwaitableButtons) -> bool { +pub fn is_awaitable_button_pressed( + report: &GcReport, + button_to_wait_for: &AwaitableButtons, +) -> bool { match button_to_wait_for { AwaitableButtons::A => report.buttons_1.button_a, AwaitableButtons::B => report.buttons_1.button_b, diff --git a/src/input.rs b/src/input.rs index 2e2a759..17e5e46 100644 --- a/src/input.rs +++ b/src/input.rs @@ -22,6 +22,7 @@ use crate::{ filter::{run_waveshaping, FilterGains, KalmanState, WaveshapingValues, FILTER_GAINS}, gcc_hid::GcReport, helpers::XyValuePair, + input_filter::{DummyFilter, InputFilter}, stick::{linearize, notch_remap, StickParams}, }; @@ -444,6 +445,9 @@ pub async fn update_button_state_task( let mut override_stick_state: Option = None; + // replace this with the input filter of your choice, if you so desire. + let mut input_filter = DummyFilter; + loop { update_button_states( &mut gcc_state, @@ -498,6 +502,7 @@ pub async fn update_button_state_task( } gcc_publisher.publish_immediate(overriden_gcc_state); } else { + input_filter.apply_filter(&mut gcc_state); gcc_publisher.publish_immediate(gcc_state); } diff --git a/src/input_filter.rs b/src/input_filter.rs new file mode 100644 index 0000000..3a8c93b --- /dev/null +++ b/src/input_filter.rs @@ -0,0 +1,109 @@ +use defmt::warn; + +use crate::{ + config::{is_awaitable_button_pressed, AwaitableButtons}, + gcc_hid::GcReport, +}; + +/** + * Houses functionality for modifying GCC state before it is sent to the console. + */ + +pub trait InputFilter: Sized { + fn apply_filter(&mut self, gcc_state: &mut GcReport); +} + +/// Presses a single button if another button is pressed. +pub struct SingleButtonMacroFilter { + /// The button that will trigger the macro. + pub btn_instigator: AwaitableButtons, + /// The button that will be pressed alongside the instigator. + pub btn_to_press: AwaitableButtons, +} + +impl InputFilter for SingleButtonMacroFilter { + fn apply_filter(&mut self, gcc_state: &mut GcReport) { + if is_awaitable_button_pressed(gcc_state, &self.btn_instigator) { + match self.btn_to_press { + AwaitableButtons::A => { + gcc_state.buttons_1.button_a = true; + } + AwaitableButtons::B => { + gcc_state.buttons_1.button_b = true; + } + AwaitableButtons::X => { + gcc_state.buttons_1.button_x = true; + } + AwaitableButtons::Y => { + gcc_state.buttons_1.button_y = true; + } + AwaitableButtons::L => { + gcc_state.trigger_l = 255; + gcc_state.buttons_2.button_l = true; + } + AwaitableButtons::R => { + gcc_state.trigger_r = 255; + gcc_state.buttons_2.button_r = true; + } + AwaitableButtons::Z => { + gcc_state.buttons_2.button_z = true; + } + AwaitableButtons::Start => { + gcc_state.buttons_2.button_start = true; + } + AwaitableButtons::Up => { + gcc_state.buttons_1.dpad_up = true; + } + AwaitableButtons::Down => { + gcc_state.buttons_1.dpad_down = true; + } + AwaitableButtons::Left => { + gcc_state.buttons_1.dpad_left = true; + } + AwaitableButtons::Right => { + gcc_state.buttons_1.dpad_right = true; + } + b => { + warn!( + "Awaitable button {} is not supported by SingleButtonMacroFilter", + b + ); + } + } + } + } +} + +/// Improves hitting turnaround up & down tilt at the cost +/// of making it harder to hit up/down angled forward tilt. +pub struct CStickUpTiltFilter; + +impl InputFilter for CStickUpTiltFilter { + fn apply_filter(&mut self, gcc_state: &mut GcReport) { + if gcc_state.cstick_y > 157 { + if (137..=201).contains(&gcc_state.cstick_x) { + gcc_state.cstick_x = 201; + gcc_state.cstick_y = 255; + } else if (53..=117).contains(&gcc_state.cstick_x) { + gcc_state.cstick_x = 53; + gcc_state.cstick_y = 255; + } + } else if gcc_state.cstick_y < 97 { + if (137..=221).contains(&gcc_state.cstick_x) { + gcc_state.cstick_x = 221; + gcc_state.cstick_y = 0; + } else if (53..=117).contains(&gcc_state.cstick_x) { + gcc_state.cstick_x = 33; + gcc_state.cstick_y = 0; + } + } + } +} + +/// Does nothing. +#[derive(Default)] +pub struct DummyFilter; + +impl InputFilter for DummyFilter { + fn apply_filter(&mut self, _gcc_state: &mut GcReport) {} +} diff --git a/src/main.rs b/src/main.rs index 9ccf733..719cf41 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,6 +9,7 @@ mod filter; mod gcc_hid; mod helpers; mod input; +mod input_filter; mod stick; use config::config_task;