forked from NaxdyOrg/NaxGCC-FW
186 lines
5.9 KiB
Rust
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 => {}
|
|
}
|
|
}
|
|
}
|