1
0
Fork 0
forked from NaxdyOrg/NaxGCC-FW
NaxGCC-FW/src/input_filter.rs

186 lines
5.9 KiB
Rust

use defmt::{warn, Format};
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) {}
}
#[derive(Debug, Format, Clone, Copy, PartialEq, Eq)]
enum NaxdyFilterMode {
Steve,
Snake,
Inactive,
}
pub struct NaxdyFilter {
mode: NaxdyFilterMode,
short_hop_filter: SingleButtonMacroFilter,
item_pickup_filter: SingleButtonMacroFilter,
cstick_up_tilt_filter: CStickUpTiltFilter,
}
impl NaxdyFilter {
#[allow(dead_code)]
pub fn new() -> Self {
Self {
mode: NaxdyFilterMode::Snake,
short_hop_filter: SingleButtonMacroFilter {
btn_instigator: AwaitableButtons::Y,
btn_to_press: AwaitableButtons::X,
},
item_pickup_filter: SingleButtonMacroFilter {
btn_instigator: AwaitableButtons::Y,
btn_to_press: AwaitableButtons::L,
},
cstick_up_tilt_filter: CStickUpTiltFilter,
}
}
}
impl InputFilter for NaxdyFilter {
fn apply_filter(&mut self, gcc_state: &mut GcReport) {
if gcc_state.buttons_1.button_a
&& gcc_state.buttons_1.button_b
&& gcc_state.buttons_1.dpad_right
&& self.mode != NaxdyFilterMode::Inactive
{
self.mode = NaxdyFilterMode::Snake
}
if gcc_state.buttons_1.button_a
&& gcc_state.buttons_1.button_b
&& gcc_state.buttons_1.dpad_left
&& self.mode != NaxdyFilterMode::Inactive
{
self.mode = NaxdyFilterMode::Steve;
}
if gcc_state.buttons_1.button_a
&& gcc_state.buttons_1.button_b
&& gcc_state.buttons_1.dpad_up
&& self.mode == NaxdyFilterMode::Inactive
{
self.mode = NaxdyFilterMode::Snake;
} else if gcc_state.buttons_1.button_a
&& gcc_state.buttons_1.button_b
&& gcc_state.buttons_1.dpad_down
&& self.mode != NaxdyFilterMode::Inactive
{
self.mode = NaxdyFilterMode::Inactive;
}
match self.mode {
NaxdyFilterMode::Steve => {
self.short_hop_filter.apply_filter(gcc_state);
}
NaxdyFilterMode::Snake => {
self.cstick_up_tilt_filter.apply_filter(gcc_state);
self.item_pickup_filter.apply_filter(gcc_state);
}
NaxdyFilterMode::Inactive => {}
}
}
}