diff --git a/src/config.rs b/src/config.rs index 343e429..c290797 100644 --- a/src/config.rs +++ b/src/config.rs @@ -19,7 +19,8 @@ use crate::{ helpers::{PackedFloat, ToPackedFloatArray, ToRegularArray, XyValuePair}, hid::gcc::{GcButtons1, GcButtons2, GcState}, input::{ - read_ext_adc, Stick, StickAxis, FLOAT_ORIGIN, SPI_ACS_SHARED, SPI_CCS_SHARED, SPI_SHARED, + read_ext_adc, ControllerState, Stick, StickAxis, FLOAT_ORIGIN, SPI_ACS_SHARED, + SPI_CCS_SHARED, SPI_SHARED, }, stick::{ calc_stick_values, legalize_notches, AppliedCalibration, CleanedCalibrationPoints, @@ -37,7 +38,7 @@ use embassy_sync::{ }; use embassy_time::Timer; -use crate::input::CHANNEL_GCC_STATE; +use crate::input::CHANNEL_CONTROLLER_STATE; /// Whether we are currently calibrating the sticks. Updates are dispatched when the status changes. /// Initial status is assumed to be false. @@ -53,8 +54,10 @@ pub static SIGNAL_OVERRIDE_STICK_STATE: Signal< > = Signal::new(); /// Dispatched when we want to override the GCC state for a short amount of time. -pub static SIGNAL_OVERRIDE_GCC_STATE: Signal<CriticalSectionRawMutex, OverrideGcReportInstruction> = - Signal::new(); +pub static SIGNAL_OVERRIDE_CONTROLLER_STATE: Signal< + CriticalSectionRawMutex, + OverrideGcReportInstruction, +> = Signal::new(); /// Dispatched when we want to enter config mode, sent from core1 so config mode /// doesn't need to watch for the entire button combo every time. @@ -79,7 +82,7 @@ const MAX_ANALOG_SCALER: u8 = 125; /// a certain mode. #[derive(Default, Debug, Clone, Format)] pub struct OverrideGcReportInstruction { - pub report: GcState, + pub report: ControllerState, pub duration_ms: u64, } @@ -684,7 +687,7 @@ trait ButtonPressProvider { } impl<'a, T: RawMutex, const I: usize, const J: usize, const K: usize> ButtonPressProvider - for Subscriber<'a, T, GcState, I, J, K> + for Subscriber<'a, T, ControllerState, I, J, K> { async fn wait_for_button_press(&mut self, button_to_wait_for: &AwaitableButtons) { loop { @@ -784,25 +787,25 @@ impl<'a, T: RawMutex, const I: usize, const J: usize, const K: usize> ButtonPres } pub fn is_awaitable_button_pressed( - report: &GcState, + report: &ControllerState, 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, - AwaitableButtons::X => report.buttons_1.button_x, - AwaitableButtons::Y => report.buttons_1.button_y, - AwaitableButtons::Up => report.buttons_1.dpad_up, - AwaitableButtons::Down => report.buttons_1.dpad_down, - AwaitableButtons::Left => report.buttons_1.dpad_left, - AwaitableButtons::Right => report.buttons_1.dpad_right, - AwaitableButtons::Start => report.buttons_2.button_start, - AwaitableButtons::L => report.buttons_2.button_l || report.trigger_l > 10, - AwaitableButtons::R => report.buttons_2.button_r || report.trigger_r > 10, - AwaitableButtons::Z => report.buttons_2.button_z, + AwaitableButtons::A => report.button_a, + AwaitableButtons::B => report.button_b, + AwaitableButtons::X => report.button_x, + AwaitableButtons::Y => report.button_y, + AwaitableButtons::Up => report.dpad_up, + AwaitableButtons::Down => report.dpad_down, + AwaitableButtons::Left => report.dpad_left, + AwaitableButtons::Right => report.dpad_right, + AwaitableButtons::Start => report.button_start, + AwaitableButtons::L => report.trigger_l, + AwaitableButtons::R => report.trigger_r, + AwaitableButtons::Z => report.trigger_zr, AwaitableButtons::Wildcard => true, AwaitableButtons::Impossible => false, - AwaitableButtons::NotZ => !report.buttons_2.button_z, + AwaitableButtons::NotZ => !report.trigger_zr, } } @@ -1023,7 +1026,7 @@ impl<'a> StickCalibrationProcess<'a> { pub async fn calibrate_stick(&mut self) { info!("Beginning stick calibration for {}", self.which_stick); - let mut gcc_subscriber = CHANNEL_GCC_STATE.subscriber().unwrap(); + let mut gcc_subscriber = CHANNEL_CONTROLLER_STATE.subscriber().unwrap(); SIGNAL_IS_CALIBRATING.signal(true); let mut done = false; @@ -1137,7 +1140,7 @@ fn get_stick_display_coords(current_step: usize) -> (f32, f32) { } pub async fn override_gcc_state_and_wait(state: &OverrideGcReportInstruction) { - SIGNAL_OVERRIDE_GCC_STATE.signal(state.clone()); + SIGNAL_OVERRIDE_CONTROLLER_STATE.signal(state.clone()); Timer::after_millis(state.duration_ms).await; } @@ -1150,7 +1153,7 @@ async fn configuration_main_loop< >( current_config: &ControllerConfig, flash: &mut Flash<'static, FLASH, Async, FLASH_SIZE>, - gcc_subscriber: &mut Subscriber<'a, M, GcState, C, S, P>, + gcc_subscriber: &mut Subscriber<'a, M, ControllerState, C, S, P>, ) -> ControllerConfig { let mut final_config = current_config.clone(); let config_options = [ @@ -1226,7 +1229,8 @@ async fn configuration_main_loop< stick_y: 127, cstick_x: 127, cstick_y: 127, - }, + } + .into(), duration_ms: 1000, }) .await; @@ -1254,7 +1258,8 @@ async fn configuration_main_loop< stick_y: 255, cstick_x: 127, cstick_y: 127, - }, + } + .into(), duration_ms: 1000, }) .await; @@ -1283,7 +1288,8 @@ async fn configuration_main_loop< stick_y: 127, cstick_x: 255, cstick_y: 255, - }, + } + .into(), duration_ms: 1000, }) .await; @@ -1370,7 +1376,8 @@ async fn configuration_main_loop< StickAxis::YAxis => *to_adjust, }, }) as u8, - }, + } + .into(), duration_ms: 750, }) .await; @@ -1456,7 +1463,8 @@ async fn configuration_main_loop< StickAxis::YAxis => *to_adjust, }, }) as u8, - }, + } + .into(), duration_ms: 750, }) .await; @@ -1542,7 +1550,8 @@ async fn configuration_main_loop< StickAxis::YAxis => *to_adjust, }, }) as u8, - }, + } + .into(), duration_ms: 750, }) .await; @@ -1597,7 +1606,8 @@ async fn configuration_main_loop< Stick::ControlStick => 0, Stick::CStick => *to_adjust, }) as u8, - }, + } + .into(), duration_ms: 750, }) .await; @@ -1653,7 +1663,8 @@ async fn configuration_main_loop< Stick::ControlStick => 0, Stick::CStick => *to_adjust, }) as u8, - }, + } + .into(), duration_ms: 750, }) .await; @@ -1694,7 +1705,8 @@ async fn configuration_main_loop< stick_y: 127 + *to_adjust, cstick_x: 127, cstick_y: 127, - }, + } + .into(), duration_ms: 750, }) .await; @@ -1735,7 +1747,8 @@ async fn configuration_main_loop< }) as u8, cstick_x: 127, cstick_y: 127, - }, + } + .into(), duration_ms: 750, }) .await; @@ -1763,7 +1776,8 @@ async fn configuration_main_loop< stick_y: 127 + final_config.astick_config.y_waveshaping, cstick_x: 127 + final_config.cstick_config.x_waveshaping, cstick_y: 127 + final_config.cstick_config.y_waveshaping, - }, + } + .into(), duration_ms: 1000, }) .await; @@ -1789,7 +1803,8 @@ async fn configuration_main_loop< stick_y: 127 + final_config.astick_config.y_smoothing, cstick_x: 127 + final_config.cstick_config.x_smoothing, cstick_y: 127 + final_config.cstick_config.y_smoothing, - }, + } + .into(), duration_ms: 1000, }) .await; @@ -1815,7 +1830,8 @@ async fn configuration_main_loop< stick_y: (127 + final_config.astick_config.y_snapback) as u8, cstick_x: (127 + final_config.cstick_config.x_snapback) as u8, cstick_y: (127 + final_config.cstick_config.y_snapback) as u8, - }, + } + .into(), duration_ms: 1000, }) .await; @@ -1836,7 +1852,7 @@ async fn configuration_main_loop< #[embassy_executor::task] pub async fn config_task(mut flash: Flash<'static, FLASH, Async, FLASH_SIZE>) { - let mut gcc_subscriber = CHANNEL_GCC_STATE.subscriber().unwrap(); + let mut gcc_subscriber = CHANNEL_CONTROLLER_STATE.subscriber().unwrap(); info!("Config task is running."); @@ -1886,7 +1902,8 @@ pub async fn config_task(mut flash: Flash<'static, FLASH, Async, FLASH_SIZE>) { stick_y: 127, cstick_x: 127, cstick_y: 127, - }, + } + .into(), duration_ms: 1000, }) .await; @@ -1902,7 +1919,7 @@ pub async fn config_task(mut flash: Flash<'static, FLASH, Async, FLASH_SIZE>) { #[embassy_executor::task] pub async fn enter_config_mode_task() { - let mut gcc_subscriber = CHANNEL_GCC_STATE.subscriber().unwrap(); + let mut gcc_subscriber = CHANNEL_CONTROLLER_STATE.subscriber().unwrap(); info!("Enter config mode task is running."); diff --git a/src/hid/gcc.rs b/src/hid/gcc.rs index dddc8ef..c8cd030 100644 --- a/src/hid/gcc.rs +++ b/src/hid/gcc.rs @@ -4,7 +4,10 @@ use embassy_usb::{ control::OutResponse, }; -use crate::usb_comms::{HidReportBuilder, SIGNAL_RUMBLE}; +use crate::{ + input::ControllerState, + usb_comms::{HidReportBuilder, SIGNAL_RUMBLE}, +}; use packed_struct::{derive::PackedStruct, PackedStruct}; #[rustfmt::skip] @@ -125,6 +128,36 @@ pub struct GcState { pub trigger_r: u8, } +impl From<ControllerState> for GcState { + fn from(value: ControllerState) -> Self { + Self { + buttons_1: GcButtons1 { + button_a: value.button_a, + button_b: value.button_b, + button_x: value.button_x, + button_y: value.button_y, + dpad_left: value.dpad_left, + dpad_right: value.dpad_right, + dpad_down: value.dpad_down, + dpad_up: value.dpad_up, + }, + buttons_2: GcButtons2 { + button_start: value.button_start, + button_z: value.trigger_zr, + button_r: value.trigger_r, + button_l: value.trigger_l, + blank1: 0, + }, + stick_x: value.stick_state.ax, + stick_y: value.stick_state.ay, + cstick_x: value.stick_state.cx, + cstick_y: value.stick_state.cy, + trigger_l: if value.trigger_l { 255 } else { 0 }, + trigger_r: if value.trigger_r { 255 } else { 0 }, + } + } +} + impl Default for GcState { fn default() -> Self { Self { @@ -146,13 +179,15 @@ pub struct GcReportBuilder { } impl HidReportBuilder<37> for GcReportBuilder { - async fn get_hid_report(&mut self, state: &GcState) -> [u8; 37] { + async fn get_hid_report(&mut self, state: &ControllerState) -> [u8; 37] { let mut buffer = [0u8; 37]; buffer[0] = 0x21; buffer[1] |= 0x14; - let data = state.pack().expect("Failed to pack GC input data"); + let gcc_state: GcState = (*state).into(); + + let data = gcc_state.pack().expect("Failed to pack GC input data"); if !self.gc_first { buffer[1] |= 0x04; diff --git a/src/hid/procon.rs b/src/hid/procon.rs index 474cfdf..1ed2b5a 100644 --- a/src/hid/procon.rs +++ b/src/hid/procon.rs @@ -18,9 +18,7 @@ use embassy_usb::{ use packed_struct::{derive::PackedStruct, PackedStruct}; use rand::RngCore; -use crate::usb_comms::HidReportBuilder; - -use super::gcc::GcState; +use crate::{input::ControllerState, usb_comms::HidReportBuilder}; const SW_INFO_SET_MAC: u8 = 0x01; @@ -486,36 +484,36 @@ impl Default for BatteryStatus { } } -impl From<&GcState> for ProconState { - fn from(value: &GcState) -> Self { +impl From<&ControllerState> for ProconState { + fn from(value: &ControllerState) -> Self { Self { buttons_left: ProconButtonsLeft { - dpad_down: value.buttons_1.dpad_down, - dpad_right: value.buttons_1.dpad_right, - dpad_up: value.buttons_1.dpad_up, - dped_left: value.buttons_1.dpad_left, - trigger_l: value.buttons_2.button_l, - trigger_zl: value.buttons_2.button_l, + dpad_down: value.dpad_down, + dpad_right: value.dpad_right, + dpad_up: value.dpad_up, + dped_left: value.dpad_left, + trigger_l: value.trigger_zl, + trigger_zl: value.trigger_l, ..Default::default() }, buttons_right: ProconButtonsRight { - button_a: value.buttons_1.button_a, - button_b: value.buttons_1.button_b, - button_x: value.buttons_1.button_x, - button_y: value.buttons_1.button_y, - trigger_r: value.buttons_2.button_z, - trigger_zr: value.buttons_2.button_r, + button_a: value.button_a, + button_b: value.button_b, + button_x: value.button_x, + button_y: value.button_y, + trigger_r: value.trigger_zr, + trigger_zr: value.trigger_r, ..Default::default() }, buttons_shared: ProconButtonsShared { - button_plus: value.buttons_2.button_start && !value.buttons_2.button_z, - button_home: value.buttons_2.button_start && value.buttons_2.button_z, + button_plus: value.button_start && !value.trigger_zr, + button_home: value.button_start && value.trigger_zr, ..Default::default() }, - lstick_x: value.stick_x as u16 * 16, - lstick_y: value.stick_y, - rstick_x: value.cstick_x as u16 * 16, - rstick_y: value.cstick_y, + lstick_x: value.stick_state.ax as u16 * 16, + lstick_y: value.stick_state.ay, + rstick_x: value.stick_state.cx as u16 * 16, + rstick_y: value.stick_state.cy, } } } @@ -694,7 +692,7 @@ impl ProconReportBuilder { } impl HidReportBuilder<64> for ProconReportBuilder { - async fn get_hid_report(&mut self, state: &GcState) -> [u8; 64] { + async fn get_hid_report(&mut self, state: &ControllerState) -> [u8; 64] { let current_report_info = if self.switch_reporting_mode == RM_SEND_STATE { SIGNAL_PROCON_REQUEST.try_take() } else { diff --git a/src/hid/xinput.rs b/src/hid/xinput.rs index ddd8c20..23138f5 100644 --- a/src/hid/xinput.rs +++ b/src/hid/xinput.rs @@ -22,9 +22,9 @@ use embassy_usb::{ }; use packed_struct::{derive::PackedStruct, PackedStruct}; -use crate::usb_comms::HidReportBuilder; +use crate::{input::ControllerState, usb_comms::HidReportBuilder}; -use super::{gcc::GcState, HidReaderWriterSplit, UsbReader, UsbWriter}; +use super::{HidReaderWriterSplit, UsbReader, UsbWriter}; /// lol pub const XINPUT_REPORT_DESCRIPTOR: &[u8] = &[]; @@ -111,37 +111,37 @@ pub struct XInputReport { pub reserved: [u8; 18], } -impl From<&GcState> for XInputReport { - fn from(value: &GcState) -> Self { +impl From<&ControllerState> for XInputReport { + fn from(value: &ControllerState) -> Self { Self { report_id: 0, report_size: 20, buttons_1: XInputButtons1 { - dpad_up: value.buttons_1.dpad_up, - dpad_down: value.buttons_1.dpad_down, - dpad_right: value.buttons_1.dpad_right, - dpad_left: value.buttons_1.dpad_left, - button_menu: value.buttons_2.button_start, + dpad_up: value.dpad_up, + dpad_down: value.dpad_down, + dpad_right: value.dpad_right, + dpad_left: value.dpad_left, + button_menu: value.button_start, button_back: false, button_stick_l: false, button_stick_r: false, }, buttons_2: XInputButtons2 { blank_1: false, - bumper_l: false, - bumper_r: value.buttons_2.button_z, - button_a: value.buttons_1.button_a, - button_b: value.buttons_1.button_b, - button_x: value.buttons_1.button_x, - button_y: value.buttons_1.button_y, + bumper_l: value.trigger_zl, + bumper_r: value.trigger_zr, + button_a: value.button_a, + button_b: value.button_b, + button_x: value.button_x, + button_y: value.button_y, button_guide: false, }, - analog_trigger_l: value.trigger_l, - analog_trigger_r: value.trigger_r, - stick_left_x: (value.stick_x as i16 - 127).clamp(-127, 127) * 257, - stick_left_y: (value.stick_y as i16 - 127).clamp(-127, 127) * 257, - stick_right_x: (value.cstick_x as i16 - 127).clamp(-127, 127) * 257, - stick_right_y: (value.cstick_y as i16 - 127).clamp(-127, 127) * 257, + analog_trigger_l: if value.trigger_l { 255 } else { 0 }, + analog_trigger_r: if value.trigger_r { 255 } else { 0 }, + stick_left_x: (value.stick_state.ax as i16 - 127).clamp(-127, 127) * 257, + stick_left_y: (value.stick_state.ay as i16 - 127).clamp(-127, 127) * 257, + stick_right_x: (value.stick_state.cx as i16 - 127).clamp(-127, 127) * 257, + stick_right_y: (value.stick_state.cy as i16 - 127).clamp(-127, 127) * 257, reserved: [0u8; 18], } } @@ -153,7 +153,7 @@ impl From<&GcState> for XInputReport { pub struct XInputReportBuilder; impl HidReportBuilder<32> for XInputReportBuilder { - async fn get_hid_report(&mut self, state: &super::gcc::GcState) -> [u8; 32] { + async fn get_hid_report(&mut self, state: &ControllerState) -> [u8; 32] { XInputReport::from(state) .pack() .expect("Failed to pack XInput State") diff --git a/src/input.rs b/src/input.rs index 3738ae0..cd28a00 100644 --- a/src/input.rs +++ b/src/input.rs @@ -17,8 +17,8 @@ use libm::{fmaxf, fminf}; use crate::{ config::{ ControllerConfig, ControllerMode, InputConsistencyMode, OverrideGcReportInstruction, - OverrideStickState, SIGNAL_CONFIG_CHANGE, SIGNAL_IS_CALIBRATING, SIGNAL_OVERRIDE_GCC_STATE, - SIGNAL_OVERRIDE_STICK_STATE, + OverrideStickState, SIGNAL_CONFIG_CHANGE, SIGNAL_IS_CALIBRATING, + SIGNAL_OVERRIDE_CONTROLLER_STATE, SIGNAL_OVERRIDE_STICK_STATE, }, filter::{run_waveshaping, FilterGains, KalmanState, WaveshapingValues, FILTER_GAINS}, helpers::XyValuePair, @@ -29,8 +29,13 @@ use crate::{ }; /// Used to send the button state to the usb task and the calibration task -pub static CHANNEL_GCC_STATE: PubSubChannel<CriticalSectionRawMutex, GcState, 1, 4, 1> = - PubSubChannel::new(); +pub static CHANNEL_CONTROLLER_STATE: PubSubChannel< + CriticalSectionRawMutex, + ControllerState, + 1, + 4, + 1, +> = PubSubChannel::new(); /// Used to send the stick state from the stick task to the main input task static SIGNAL_STICK_STATE: Signal<CriticalSectionRawMutex, StickState> = Signal::new(); @@ -43,7 +48,7 @@ pub static SPI_CCS_SHARED: Mutex<ThreadModeRawMutex, Option<Output<'static>>> = const STICK_HYST_VAL: f32 = 0.3; pub const FLOAT_ORIGIN: f32 = 127.5; -#[derive(Clone, Debug, Default, Format)] +#[derive(Clone, Copy, Debug, Format, PartialEq, Eq)] pub struct StickState { pub ax: u8, pub ay: u8, @@ -51,6 +56,17 @@ pub struct StickState { pub cy: u8, } +impl Default for StickState { + fn default() -> Self { + Self { + ax: 127, + ay: 127, + cx: 127, + cy: 127, + } + } +} + #[derive(Clone, Debug, Default)] struct StickPositions { x: f32, @@ -69,6 +85,51 @@ struct RawStickValues { c_unfiltered: XyValuePair<f32>, } +#[derive(Clone, Copy, Debug, Default, Format, PartialEq, Eq)] +pub struct ControllerState { + pub button_a: bool, + pub button_b: bool, + pub button_x: bool, + pub button_y: bool, + pub trigger_zr: bool, + pub trigger_zl: bool, + pub trigger_l: bool, + pub trigger_r: bool, + pub button_start: bool, + pub dpad_up: bool, + pub dpad_down: bool, + pub dpad_left: bool, + pub dpad_right: bool, + pub stick_state: StickState, +} + +/// This is only implemented for backwards-compatibility purposes +impl From<GcState> for ControllerState { + fn from(value: GcState) -> Self { + Self { + button_a: value.buttons_1.button_a, + button_b: value.buttons_1.button_b, + button_x: value.buttons_1.button_x, + button_y: value.buttons_1.button_y, + trigger_zr: value.buttons_2.button_z, + trigger_zl: false, + trigger_l: value.trigger_l > 170, + trigger_r: value.trigger_r > 170, + button_start: value.buttons_2.button_start, + dpad_up: value.buttons_1.dpad_up, + dpad_down: value.buttons_1.dpad_down, + dpad_left: value.buttons_1.dpad_left, + dpad_right: value.buttons_1.dpad_right, + stick_state: StickState { + ax: value.stick_x, + ay: value.stick_y, + cx: value.stick_x, + cy: value.stick_y, + }, + } + } +} + #[derive(PartialEq, Eq, Debug, Clone, Format, Copy)] pub enum Stick { ControlStick, @@ -312,7 +373,7 @@ async fn update_stick_states( raw_stick_values.c_unfiltered.x = fminf(125., fmaxf(-125., remapped_c_unfiltered.x)); raw_stick_values.c_unfiltered.y = fminf(125., fmaxf(-125., remapped_c_unfiltered.y)); - let mut out_stick_state = current_stick_state.clone(); + let mut out_stick_state = *current_stick_state; let diff_x = (remapped.x + FLOAT_ORIGIN) - current_stick_state.ax as f32; if !(-STICK_HYST_VAL..=(1.0 + STICK_HYST_VAL)).contains(&diff_x) { @@ -345,7 +406,7 @@ async fn update_stick_states( #[allow(clippy::too_many_arguments)] fn update_button_states( - gcc_state: &mut GcState, + controller_state: &mut ControllerState, btn_a: &Input<'_>, btn_b: &Input<'_>, btn_x: &Input<'_>, @@ -353,42 +414,37 @@ fn update_button_states( btn_start: &Input<'_>, btn_l: &Input<'_>, btn_r: &Input<'_>, - btn_z: &Input<'_>, + btn_zr: &Input<'_>, + btn_zl: &Input<'_>, btn_dleft: &Input<'_>, btn_dright: &Input<'_>, btn_dup: &Input<'_>, btn_ddown: &Input<'_>, ) { - gcc_state.buttons_1.button_a = btn_a.is_low(); - gcc_state.buttons_1.button_b = btn_b.is_low(); - gcc_state.buttons_1.button_x = btn_x.is_low(); - gcc_state.buttons_1.button_y = btn_y.is_low(); - gcc_state.buttons_2.button_z = btn_z.is_low(); - gcc_state.buttons_2.button_start = btn_start.is_low(); - gcc_state.buttons_2.button_l = btn_l.is_low(); - gcc_state.buttons_2.button_r = btn_r.is_low(); - gcc_state.buttons_1.dpad_left = btn_dleft.is_low(); - gcc_state.buttons_1.dpad_right = btn_dright.is_low(); - gcc_state.buttons_1.dpad_up = btn_dup.is_low(); - gcc_state.buttons_1.dpad_down = btn_ddown.is_low(); - gcc_state.trigger_l = match gcc_state.buttons_2.button_l { - true => 255, - false => 0, - }; - gcc_state.trigger_r = match gcc_state.buttons_2.button_r { - true => 255, - false => 0, - }; + controller_state.button_a = btn_a.is_low(); + controller_state.button_b = btn_b.is_low(); + controller_state.button_x = btn_x.is_low(); + controller_state.button_y = btn_y.is_low(); + controller_state.trigger_zr = btn_zr.is_low(); + controller_state.trigger_zl = btn_zl.is_low(); + controller_state.button_start = btn_start.is_low(); + controller_state.trigger_l = btn_l.is_low(); + controller_state.trigger_r = btn_r.is_low(); + controller_state.dpad_left = btn_dleft.is_low(); + controller_state.dpad_right = btn_dright.is_low(); + controller_state.dpad_up = btn_dup.is_low(); + controller_state.dpad_down = btn_ddown.is_low(); } #[embassy_executor::task] pub async fn input_integrity_benchmark() { loop { - SIGNAL_OVERRIDE_GCC_STATE.signal(OverrideGcReportInstruction { + SIGNAL_OVERRIDE_CONTROLLER_STATE.signal(OverrideGcReportInstruction { report: { - let mut report = GcState::default(); - report.buttons_1.dpad_up = true; - report + ControllerState { + dpad_up: true, + ..Default::default() + } }, duration_ms: 100, }); @@ -402,7 +458,8 @@ pub async fn input_integrity_benchmark() { #[allow(clippy::too_many_arguments)] #[embassy_executor::task] pub async fn update_button_state_task( - btn_z: Input<'static>, + btn_zr: Input<'static>, + btn_zl: Input<'static>, btn_a: Input<'static>, btn_b: Input<'static>, btn_dright: Input<'static>, @@ -442,11 +499,11 @@ pub async fn update_button_state_task( MUTEX_INPUT_CONSISTENCY_MODE.lock().await.unwrap() }; - let mut previous_state = GcState::default(); + let mut previous_state = ControllerState::default(); - let mut gcc_state = GcState::default(); + let mut controller_state = ControllerState::default(); - let gcc_publisher = CHANNEL_GCC_STATE.publisher().unwrap(); + let gcc_publisher = CHANNEL_CONTROLLER_STATE.publisher().unwrap(); let mut override_stick_state: Option<OverrideStickState> = None; @@ -459,7 +516,7 @@ pub async fn update_button_state_task( loop { update_button_states( - &mut gcc_state, + &mut controller_state, &btn_a, &btn_b, &btn_x, @@ -467,7 +524,8 @@ pub async fn update_button_state_task( &btn_start, &btn_l, &btn_r, - &btn_z, + &btn_zr, + &btn_zl, &btn_dleft, &btn_dright, &btn_dup, @@ -476,10 +534,7 @@ pub async fn update_button_state_task( // not every loop pass is going to update the stick state if let Some(stick_state) = SIGNAL_STICK_STATE.try_take() { - gcc_state.stick_x = stick_state.ax; - gcc_state.stick_y = stick_state.ay; - gcc_state.cstick_x = stick_state.cx; - gcc_state.cstick_y = stick_state.cy; + controller_state.stick_state = stick_state } if let Some(override_stick_state_opt) = SIGNAL_OVERRIDE_STICK_STATE.try_take() { @@ -488,7 +543,7 @@ pub async fn update_button_state_task( } // check for a gcc state override (usually coming from the config task) - if let Some(override_gcc_state) = SIGNAL_OVERRIDE_GCC_STATE.try_take() { + if let Some(override_gcc_state) = SIGNAL_OVERRIDE_CONTROLLER_STATE.try_take() { trace!("Overridden gcc state: {:?}", override_gcc_state.report); let end_time = Instant::now() + Duration::from_millis(override_gcc_state.duration_ms); while Instant::now() < end_time { @@ -506,20 +561,20 @@ pub async fn update_button_state_task( }; if let Some(override_state) = &override_stick_state { - let mut overriden_gcc_state = gcc_state; + let mut overriden_gcc_state = controller_state; match override_state.which_stick { Stick::ControlStick => { - overriden_gcc_state.stick_x = override_state.x; - overriden_gcc_state.stick_y = override_state.y; + overriden_gcc_state.stick_state.ax = override_state.x; + overriden_gcc_state.stick_state.ay = override_state.y; } Stick::CStick => { - overriden_gcc_state.cstick_x = override_state.x; - overriden_gcc_state.cstick_y = override_state.y; + overriden_gcc_state.stick_state.cx = override_state.x; + overriden_gcc_state.stick_state.cy = override_state.y; } } gcc_publisher.publish_immediate(overriden_gcc_state); } else { - input_filter.apply_filter(&mut gcc_state); + input_filter.apply_filter(&mut controller_state); if input_consistency_mode == InputConsistencyMode::SuperHack { // transmit state always for the first 5 seconds to give the console time to initialize the controller if initializing && Instant::now().duration_since(init_time) > Duration::from_secs(5) @@ -527,12 +582,12 @@ pub async fn update_button_state_task( initializing = false; } - if gcc_state != previous_state || initializing { - gcc_publisher.publish_immediate(gcc_state); - previous_state = gcc_state; + if controller_state != previous_state || initializing { + gcc_publisher.publish_immediate(controller_state); + previous_state = controller_state; } } else { - gcc_publisher.publish_immediate(gcc_state); + gcc_publisher.publish_immediate(controller_state); } } @@ -621,7 +676,7 @@ pub async fn update_stick_states_task( last_loop_time = n; }; - SIGNAL_STICK_STATE.signal(current_stick_state.clone()); + SIGNAL_STICK_STATE.signal(current_stick_state); yield_now().await; ticker.next().await; diff --git a/src/input_filter.rs b/src/input_filter.rs index 3058a94..a3be235 100644 --- a/src/input_filter.rs +++ b/src/input_filter.rs @@ -2,7 +2,7 @@ use defmt::warn; use crate::{ config::{is_awaitable_button_pressed, AwaitableButtons}, - hid::gcc::GcState, + input::ControllerState, }; /** @@ -14,7 +14,7 @@ use crate::{ */ pub trait InputFilter: Sized { - fn apply_filter(&mut self, gcc_state: &mut GcState); + fn apply_filter(&mut self, controller_state: &mut ControllerState); } /// Presses a single button if another button is pressed. @@ -26,46 +26,44 @@ pub struct SingleButtonMacroFilter { } impl InputFilter for SingleButtonMacroFilter { - fn apply_filter(&mut self, gcc_state: &mut GcState) { - if is_awaitable_button_pressed(gcc_state, &self.btn_instigator) { + fn apply_filter(&mut self, controller_state: &mut ControllerState) { + if is_awaitable_button_pressed(controller_state, &self.btn_instigator) { match self.btn_to_press { AwaitableButtons::A => { - gcc_state.buttons_1.button_a = true; + controller_state.button_a = true; } AwaitableButtons::B => { - gcc_state.buttons_1.button_b = true; + controller_state.button_b = true; } AwaitableButtons::X => { - gcc_state.buttons_1.button_x = true; + controller_state.button_x = true; } AwaitableButtons::Y => { - gcc_state.buttons_1.button_y = true; + controller_state.button_y = true; } AwaitableButtons::L => { - gcc_state.trigger_l = 255; - gcc_state.buttons_2.button_l = true; + controller_state.trigger_l = true; } AwaitableButtons::R => { - gcc_state.trigger_r = 255; - gcc_state.buttons_2.button_r = true; + controller_state.trigger_r = true; } AwaitableButtons::Z => { - gcc_state.buttons_2.button_z = true; + controller_state.trigger_zr = true; } AwaitableButtons::Start => { - gcc_state.buttons_2.button_start = true; + controller_state.button_start = true; } AwaitableButtons::Up => { - gcc_state.buttons_1.dpad_up = true; + controller_state.dpad_up = true; } AwaitableButtons::Down => { - gcc_state.buttons_1.dpad_down = true; + controller_state.dpad_down = true; } AwaitableButtons::Left => { - gcc_state.buttons_1.dpad_left = true; + controller_state.dpad_left = true; } AwaitableButtons::Right => { - gcc_state.buttons_1.dpad_right = true; + controller_state.dpad_right = true; } b => { warn!( @@ -83,22 +81,22 @@ impl InputFilter for SingleButtonMacroFilter { pub struct CStickUpTiltFilter; impl InputFilter for CStickUpTiltFilter { - fn apply_filter(&mut self, gcc_state: &mut GcState) { - 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; + fn apply_filter(&mut self, controller_state: &mut ControllerState) { + if controller_state.stick_state.cy > 157 { + if (137..=201).contains(&controller_state.stick_state.cx) { + controller_state.stick_state.cx = 201; + controller_state.stick_state.cy = 255; + } else if (53..=117).contains(&controller_state.stick_state.cx) { + controller_state.stick_state.cx = 53; + controller_state.stick_state.cy = 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; + } else if controller_state.stick_state.cy < 97 { + if (137..=221).contains(&controller_state.stick_state.cx) { + controller_state.stick_state.cx = 221; + controller_state.stick_state.cy = 0; + } else if (53..=117).contains(&controller_state.stick_state.cx) { + controller_state.stick_state.cx = 33; + controller_state.stick_state.cy = 0; } } } @@ -110,22 +108,22 @@ impl InputFilter for CStickUpTiltFilter { pub struct CStickAngledFTiltFilter; impl InputFilter for CStickAngledFTiltFilter { - fn apply_filter(&mut self, gcc_state: &mut GcState) { - if gcc_state.cstick_y > 147 { - if (147..=225).contains(&gcc_state.cstick_x) { - gcc_state.cstick_x = 205; - gcc_state.cstick_y = 205; - } else if (30..=107).contains(&gcc_state.cstick_x) { - gcc_state.cstick_x = 50; - gcc_state.cstick_y = 205; + fn apply_filter(&mut self, controller_state: &mut ControllerState) { + if controller_state.stick_state.cy > 147 { + if (147..=225).contains(&controller_state.stick_state.cx) { + controller_state.stick_state.cx = 205; + controller_state.stick_state.cy = 205; + } else if (30..=107).contains(&controller_state.stick_state.cx) { + controller_state.stick_state.cx = 50; + controller_state.stick_state.cy = 205; } - } else if gcc_state.cstick_y < 107 { - if (147..=225).contains(&gcc_state.cstick_x) { - gcc_state.cstick_x = 205; - gcc_state.cstick_y = 50; - } else if (30..=107).contains(&gcc_state.cstick_x) { - gcc_state.cstick_x = 50; - gcc_state.cstick_y = 50; + } else if controller_state.stick_state.cy < 107 { + if (147..=225).contains(&controller_state.stick_state.cx) { + controller_state.stick_state.cx = 205; + controller_state.stick_state.cy = 50; + } else if (30..=107).contains(&controller_state.stick_state.cx) { + controller_state.stick_state.cx = 50; + controller_state.stick_state.cy = 50; } } } @@ -136,5 +134,5 @@ impl InputFilter for CStickAngledFTiltFilter { pub struct DummyFilter; impl InputFilter for DummyFilter { - fn apply_filter(&mut self, _gcc_state: &mut GcState) {} + fn apply_filter(&mut self, _gcc_state: &mut ControllerState) {} } diff --git a/src/main.rs b/src/main.rs index dc97008..6abcc03 100644 --- a/src/main.rs +++ b/src/main.rs @@ -89,6 +89,7 @@ fn main() -> ! { spawner .spawn(update_button_state_task( Input::new(AnyPin::from(p.PIN_20), gpio::Pull::Up), + Input::new(AnyPin::from(p.PIN_15), gpio::Pull::Up), Input::new(AnyPin::from(p.PIN_17), gpio::Pull::Up), Input::new(AnyPin::from(p.PIN_16), gpio::Pull::Up), Input::new(AnyPin::from(p.PIN_11), gpio::Pull::Up), diff --git a/src/usb_comms.rs b/src/usb_comms.rs index e89692d..7a76df1 100644 --- a/src/usb_comms.rs +++ b/src/usb_comms.rs @@ -25,7 +25,7 @@ use libm::powf; use crate::{ config::{ControllerMode, InputConsistencyMode}, hid::{ - gcc::{GcReportBuilder, GcState, GccRequestHandler, GCC_REPORT_DESCRIPTOR}, + gcc::{GcReportBuilder, GccRequestHandler, GCC_REPORT_DESCRIPTOR}, procon::{ProconReportBuilder, ProconRequestHandler, PROCON_REPORT_DESCRIPTOR}, xinput::{ XInputReaderWriter, XInputReportBuilder, XInputRequestHandler, XInputState, @@ -33,7 +33,7 @@ use crate::{ }, HidReaderWriterSplit, UsbReader, UsbWriter, }, - input::CHANNEL_GCC_STATE, + input::{ControllerState, CHANNEL_CONTROLLER_STATE}, }; pub static SIGNAL_RUMBLE: Signal<CriticalSectionRawMutex, bool> = Signal::new(); @@ -56,7 +56,7 @@ pub static MUTEX_CONTROLLER_MODE: Mutex<CriticalSectionRawMutex, Option<Controll const DEVICE_INTERFACE_GUID: &str = "{ecceff35-146c-4ff3-acd9-8f992d09acdd}"; pub trait HidReportBuilder<const LEN: usize> { - async fn get_hid_report(&mut self, state: &GcState) -> [u8; LEN]; + async fn get_hid_report(&mut self, state: &ControllerState) -> [u8; LEN]; } struct UsbConfig { @@ -216,7 +216,7 @@ where }; let in_fut = async move { - let mut gcc_subscriber = CHANNEL_GCC_STATE.subscriber().unwrap(); + let mut gcc_subscriber = CHANNEL_CONTROLLER_STATE.subscriber().unwrap(); let mut last_report_time = Instant::now(); let mut rate_limit_end_time = Instant::now();