feat: introduce ControllerState
+ add functionality for 2nd Z button (#29)
All checks were successful
Publish nightly release / build (push) Successful in 2m16s
All checks were successful
Publish nightly release / build (push) Successful in 2m16s
Reviewed-on: #29
This commit is contained in:
parent
9838c4ee64
commit
0a0754c248
8 changed files with 299 additions and 195 deletions
|
@ -19,7 +19,8 @@ use crate::{
|
||||||
helpers::{PackedFloat, ToPackedFloatArray, ToRegularArray, XyValuePair},
|
helpers::{PackedFloat, ToPackedFloatArray, ToRegularArray, XyValuePair},
|
||||||
hid::gcc::{GcButtons1, GcButtons2, GcState},
|
hid::gcc::{GcButtons1, GcButtons2, GcState},
|
||||||
input::{
|
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::{
|
stick::{
|
||||||
calc_stick_values, legalize_notches, AppliedCalibration, CleanedCalibrationPoints,
|
calc_stick_values, legalize_notches, AppliedCalibration, CleanedCalibrationPoints,
|
||||||
|
@ -37,7 +38,7 @@ use embassy_sync::{
|
||||||
};
|
};
|
||||||
use embassy_time::Timer;
|
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.
|
/// Whether we are currently calibrating the sticks. Updates are dispatched when the status changes.
|
||||||
/// Initial status is assumed to be false.
|
/// Initial status is assumed to be false.
|
||||||
|
@ -53,8 +54,10 @@ pub static SIGNAL_OVERRIDE_STICK_STATE: Signal<
|
||||||
> = Signal::new();
|
> = Signal::new();
|
||||||
|
|
||||||
/// Dispatched when we want to override the GCC state for a short amount of time.
|
/// Dispatched when we want to override the GCC state for a short amount of time.
|
||||||
pub static SIGNAL_OVERRIDE_GCC_STATE: Signal<CriticalSectionRawMutex, OverrideGcReportInstruction> =
|
pub static SIGNAL_OVERRIDE_CONTROLLER_STATE: Signal<
|
||||||
Signal::new();
|
CriticalSectionRawMutex,
|
||||||
|
OverrideGcReportInstruction,
|
||||||
|
> = Signal::new();
|
||||||
|
|
||||||
/// Dispatched when we want to enter config mode, sent from core1 so config mode
|
/// 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.
|
/// 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.
|
/// a certain mode.
|
||||||
#[derive(Default, Debug, Clone, Format)]
|
#[derive(Default, Debug, Clone, Format)]
|
||||||
pub struct OverrideGcReportInstruction {
|
pub struct OverrideGcReportInstruction {
|
||||||
pub report: GcState,
|
pub report: ControllerState,
|
||||||
pub duration_ms: u64,
|
pub duration_ms: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -684,7 +687,7 @@ trait ButtonPressProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: RawMutex, const I: usize, const J: usize, const K: usize> 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) {
|
async fn wait_for_button_press(&mut self, button_to_wait_for: &AwaitableButtons) {
|
||||||
loop {
|
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(
|
pub fn is_awaitable_button_pressed(
|
||||||
report: &GcState,
|
report: &ControllerState,
|
||||||
button_to_wait_for: &AwaitableButtons,
|
button_to_wait_for: &AwaitableButtons,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
match button_to_wait_for {
|
match button_to_wait_for {
|
||||||
AwaitableButtons::A => report.buttons_1.button_a,
|
AwaitableButtons::A => report.button_a,
|
||||||
AwaitableButtons::B => report.buttons_1.button_b,
|
AwaitableButtons::B => report.button_b,
|
||||||
AwaitableButtons::X => report.buttons_1.button_x,
|
AwaitableButtons::X => report.button_x,
|
||||||
AwaitableButtons::Y => report.buttons_1.button_y,
|
AwaitableButtons::Y => report.button_y,
|
||||||
AwaitableButtons::Up => report.buttons_1.dpad_up,
|
AwaitableButtons::Up => report.dpad_up,
|
||||||
AwaitableButtons::Down => report.buttons_1.dpad_down,
|
AwaitableButtons::Down => report.dpad_down,
|
||||||
AwaitableButtons::Left => report.buttons_1.dpad_left,
|
AwaitableButtons::Left => report.dpad_left,
|
||||||
AwaitableButtons::Right => report.buttons_1.dpad_right,
|
AwaitableButtons::Right => report.dpad_right,
|
||||||
AwaitableButtons::Start => report.buttons_2.button_start,
|
AwaitableButtons::Start => report.button_start,
|
||||||
AwaitableButtons::L => report.buttons_2.button_l || report.trigger_l > 10,
|
AwaitableButtons::L => report.trigger_l,
|
||||||
AwaitableButtons::R => report.buttons_2.button_r || report.trigger_r > 10,
|
AwaitableButtons::R => report.trigger_r,
|
||||||
AwaitableButtons::Z => report.buttons_2.button_z,
|
AwaitableButtons::Z => report.trigger_zr,
|
||||||
AwaitableButtons::Wildcard => true,
|
AwaitableButtons::Wildcard => true,
|
||||||
AwaitableButtons::Impossible => false,
|
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) {
|
pub async fn calibrate_stick(&mut self) {
|
||||||
info!("Beginning stick calibration for {}", self.which_stick);
|
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);
|
SIGNAL_IS_CALIBRATING.signal(true);
|
||||||
|
|
||||||
let mut done = false;
|
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) {
|
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;
|
Timer::after_millis(state.duration_ms).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1150,7 +1153,7 @@ async fn configuration_main_loop<
|
||||||
>(
|
>(
|
||||||
current_config: &ControllerConfig,
|
current_config: &ControllerConfig,
|
||||||
flash: &mut Flash<'static, FLASH, Async, FLASH_SIZE>,
|
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 {
|
) -> ControllerConfig {
|
||||||
let mut final_config = current_config.clone();
|
let mut final_config = current_config.clone();
|
||||||
let config_options = [
|
let config_options = [
|
||||||
|
@ -1226,7 +1229,8 @@ async fn configuration_main_loop<
|
||||||
stick_y: 127,
|
stick_y: 127,
|
||||||
cstick_x: 127,
|
cstick_x: 127,
|
||||||
cstick_y: 127,
|
cstick_y: 127,
|
||||||
},
|
}
|
||||||
|
.into(),
|
||||||
duration_ms: 1000,
|
duration_ms: 1000,
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
@ -1254,7 +1258,8 @@ async fn configuration_main_loop<
|
||||||
stick_y: 255,
|
stick_y: 255,
|
||||||
cstick_x: 127,
|
cstick_x: 127,
|
||||||
cstick_y: 127,
|
cstick_y: 127,
|
||||||
},
|
}
|
||||||
|
.into(),
|
||||||
duration_ms: 1000,
|
duration_ms: 1000,
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
@ -1283,7 +1288,8 @@ async fn configuration_main_loop<
|
||||||
stick_y: 127,
|
stick_y: 127,
|
||||||
cstick_x: 255,
|
cstick_x: 255,
|
||||||
cstick_y: 255,
|
cstick_y: 255,
|
||||||
},
|
}
|
||||||
|
.into(),
|
||||||
duration_ms: 1000,
|
duration_ms: 1000,
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
@ -1370,7 +1376,8 @@ async fn configuration_main_loop<
|
||||||
StickAxis::YAxis => *to_adjust,
|
StickAxis::YAxis => *to_adjust,
|
||||||
},
|
},
|
||||||
}) as u8,
|
}) as u8,
|
||||||
},
|
}
|
||||||
|
.into(),
|
||||||
duration_ms: 750,
|
duration_ms: 750,
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
@ -1456,7 +1463,8 @@ async fn configuration_main_loop<
|
||||||
StickAxis::YAxis => *to_adjust,
|
StickAxis::YAxis => *to_adjust,
|
||||||
},
|
},
|
||||||
}) as u8,
|
}) as u8,
|
||||||
},
|
}
|
||||||
|
.into(),
|
||||||
duration_ms: 750,
|
duration_ms: 750,
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
@ -1542,7 +1550,8 @@ async fn configuration_main_loop<
|
||||||
StickAxis::YAxis => *to_adjust,
|
StickAxis::YAxis => *to_adjust,
|
||||||
},
|
},
|
||||||
}) as u8,
|
}) as u8,
|
||||||
},
|
}
|
||||||
|
.into(),
|
||||||
duration_ms: 750,
|
duration_ms: 750,
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
@ -1597,7 +1606,8 @@ async fn configuration_main_loop<
|
||||||
Stick::ControlStick => 0,
|
Stick::ControlStick => 0,
|
||||||
Stick::CStick => *to_adjust,
|
Stick::CStick => *to_adjust,
|
||||||
}) as u8,
|
}) as u8,
|
||||||
},
|
}
|
||||||
|
.into(),
|
||||||
duration_ms: 750,
|
duration_ms: 750,
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
@ -1653,7 +1663,8 @@ async fn configuration_main_loop<
|
||||||
Stick::ControlStick => 0,
|
Stick::ControlStick => 0,
|
||||||
Stick::CStick => *to_adjust,
|
Stick::CStick => *to_adjust,
|
||||||
}) as u8,
|
}) as u8,
|
||||||
},
|
}
|
||||||
|
.into(),
|
||||||
duration_ms: 750,
|
duration_ms: 750,
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
@ -1694,7 +1705,8 @@ async fn configuration_main_loop<
|
||||||
stick_y: 127 + *to_adjust,
|
stick_y: 127 + *to_adjust,
|
||||||
cstick_x: 127,
|
cstick_x: 127,
|
||||||
cstick_y: 127,
|
cstick_y: 127,
|
||||||
},
|
}
|
||||||
|
.into(),
|
||||||
duration_ms: 750,
|
duration_ms: 750,
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
@ -1735,7 +1747,8 @@ async fn configuration_main_loop<
|
||||||
}) as u8,
|
}) as u8,
|
||||||
cstick_x: 127,
|
cstick_x: 127,
|
||||||
cstick_y: 127,
|
cstick_y: 127,
|
||||||
},
|
}
|
||||||
|
.into(),
|
||||||
duration_ms: 750,
|
duration_ms: 750,
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
@ -1763,7 +1776,8 @@ async fn configuration_main_loop<
|
||||||
stick_y: 127 + final_config.astick_config.y_waveshaping,
|
stick_y: 127 + final_config.astick_config.y_waveshaping,
|
||||||
cstick_x: 127 + final_config.cstick_config.x_waveshaping,
|
cstick_x: 127 + final_config.cstick_config.x_waveshaping,
|
||||||
cstick_y: 127 + final_config.cstick_config.y_waveshaping,
|
cstick_y: 127 + final_config.cstick_config.y_waveshaping,
|
||||||
},
|
}
|
||||||
|
.into(),
|
||||||
duration_ms: 1000,
|
duration_ms: 1000,
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
@ -1789,7 +1803,8 @@ async fn configuration_main_loop<
|
||||||
stick_y: 127 + final_config.astick_config.y_smoothing,
|
stick_y: 127 + final_config.astick_config.y_smoothing,
|
||||||
cstick_x: 127 + final_config.cstick_config.x_smoothing,
|
cstick_x: 127 + final_config.cstick_config.x_smoothing,
|
||||||
cstick_y: 127 + final_config.cstick_config.y_smoothing,
|
cstick_y: 127 + final_config.cstick_config.y_smoothing,
|
||||||
},
|
}
|
||||||
|
.into(),
|
||||||
duration_ms: 1000,
|
duration_ms: 1000,
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
@ -1815,7 +1830,8 @@ async fn configuration_main_loop<
|
||||||
stick_y: (127 + final_config.astick_config.y_snapback) as u8,
|
stick_y: (127 + final_config.astick_config.y_snapback) as u8,
|
||||||
cstick_x: (127 + final_config.cstick_config.x_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,
|
cstick_y: (127 + final_config.cstick_config.y_snapback) as u8,
|
||||||
},
|
}
|
||||||
|
.into(),
|
||||||
duration_ms: 1000,
|
duration_ms: 1000,
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
@ -1836,7 +1852,7 @@ async fn configuration_main_loop<
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
pub async fn config_task(mut flash: Flash<'static, FLASH, Async, FLASH_SIZE>) {
|
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.");
|
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,
|
stick_y: 127,
|
||||||
cstick_x: 127,
|
cstick_x: 127,
|
||||||
cstick_y: 127,
|
cstick_y: 127,
|
||||||
},
|
}
|
||||||
|
.into(),
|
||||||
duration_ms: 1000,
|
duration_ms: 1000,
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
@ -1902,7 +1919,7 @@ pub async fn config_task(mut flash: Flash<'static, FLASH, Async, FLASH_SIZE>) {
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
pub async fn enter_config_mode_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.");
|
info!("Enter config mode task is running.");
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,10 @@ use embassy_usb::{
|
||||||
control::OutResponse,
|
control::OutResponse,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::usb_comms::{HidReportBuilder, SIGNAL_RUMBLE};
|
use crate::{
|
||||||
|
input::ControllerState,
|
||||||
|
usb_comms::{HidReportBuilder, SIGNAL_RUMBLE},
|
||||||
|
};
|
||||||
use packed_struct::{derive::PackedStruct, PackedStruct};
|
use packed_struct::{derive::PackedStruct, PackedStruct};
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
|
@ -125,6 +128,36 @@ pub struct GcState {
|
||||||
pub trigger_r: u8,
|
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 {
|
impl Default for GcState {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -146,13 +179,15 @@ pub struct GcReportBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HidReportBuilder<37> for 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];
|
let mut buffer = [0u8; 37];
|
||||||
|
|
||||||
buffer[0] = 0x21;
|
buffer[0] = 0x21;
|
||||||
buffer[1] |= 0x14;
|
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 {
|
if !self.gc_first {
|
||||||
buffer[1] |= 0x04;
|
buffer[1] |= 0x04;
|
||||||
|
|
|
@ -18,9 +18,7 @@ use embassy_usb::{
|
||||||
use packed_struct::{derive::PackedStruct, PackedStruct};
|
use packed_struct::{derive::PackedStruct, PackedStruct};
|
||||||
use rand::RngCore;
|
use rand::RngCore;
|
||||||
|
|
||||||
use crate::usb_comms::HidReportBuilder;
|
use crate::{input::ControllerState, usb_comms::HidReportBuilder};
|
||||||
|
|
||||||
use super::gcc::GcState;
|
|
||||||
|
|
||||||
const SW_INFO_SET_MAC: u8 = 0x01;
|
const SW_INFO_SET_MAC: u8 = 0x01;
|
||||||
|
|
||||||
|
@ -486,36 +484,36 @@ impl Default for BatteryStatus {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&GcState> for ProconState {
|
impl From<&ControllerState> for ProconState {
|
||||||
fn from(value: &GcState) -> Self {
|
fn from(value: &ControllerState) -> Self {
|
||||||
Self {
|
Self {
|
||||||
buttons_left: ProconButtonsLeft {
|
buttons_left: ProconButtonsLeft {
|
||||||
dpad_down: value.buttons_1.dpad_down,
|
dpad_down: value.dpad_down,
|
||||||
dpad_right: value.buttons_1.dpad_right,
|
dpad_right: value.dpad_right,
|
||||||
dpad_up: value.buttons_1.dpad_up,
|
dpad_up: value.dpad_up,
|
||||||
dped_left: value.buttons_1.dpad_left,
|
dped_left: value.dpad_left,
|
||||||
trigger_l: value.buttons_2.button_l,
|
trigger_l: value.trigger_zl,
|
||||||
trigger_zl: value.buttons_2.button_l,
|
trigger_zl: value.trigger_l,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
buttons_right: ProconButtonsRight {
|
buttons_right: ProconButtonsRight {
|
||||||
button_a: value.buttons_1.button_a,
|
button_a: value.button_a,
|
||||||
button_b: value.buttons_1.button_b,
|
button_b: value.button_b,
|
||||||
button_x: value.buttons_1.button_x,
|
button_x: value.button_x,
|
||||||
button_y: value.buttons_1.button_y,
|
button_y: value.button_y,
|
||||||
trigger_r: value.buttons_2.button_z,
|
trigger_r: value.trigger_zr,
|
||||||
trigger_zr: value.buttons_2.button_r,
|
trigger_zr: value.trigger_r,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
buttons_shared: ProconButtonsShared {
|
buttons_shared: ProconButtonsShared {
|
||||||
button_plus: value.buttons_2.button_start && !value.buttons_2.button_z,
|
button_plus: value.button_start && !value.trigger_zr,
|
||||||
button_home: value.buttons_2.button_start && value.buttons_2.button_z,
|
button_home: value.button_start && value.trigger_zr,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
lstick_x: value.stick_x as u16 * 16,
|
lstick_x: value.stick_state.ax as u16 * 16,
|
||||||
lstick_y: value.stick_y,
|
lstick_y: value.stick_state.ay,
|
||||||
rstick_x: value.cstick_x as u16 * 16,
|
rstick_x: value.stick_state.cx as u16 * 16,
|
||||||
rstick_y: value.cstick_y,
|
rstick_y: value.stick_state.cy,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -694,7 +692,7 @@ impl ProconReportBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HidReportBuilder<64> for 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 {
|
let current_report_info = if self.switch_reporting_mode == RM_SEND_STATE {
|
||||||
SIGNAL_PROCON_REQUEST.try_take()
|
SIGNAL_PROCON_REQUEST.try_take()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -22,9 +22,9 @@ use embassy_usb::{
|
||||||
};
|
};
|
||||||
use packed_struct::{derive::PackedStruct, PackedStruct};
|
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
|
/// lol
|
||||||
pub const XINPUT_REPORT_DESCRIPTOR: &[u8] = &[];
|
pub const XINPUT_REPORT_DESCRIPTOR: &[u8] = &[];
|
||||||
|
@ -111,37 +111,37 @@ pub struct XInputReport {
|
||||||
pub reserved: [u8; 18],
|
pub reserved: [u8; 18],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&GcState> for XInputReport {
|
impl From<&ControllerState> for XInputReport {
|
||||||
fn from(value: &GcState) -> Self {
|
fn from(value: &ControllerState) -> Self {
|
||||||
Self {
|
Self {
|
||||||
report_id: 0,
|
report_id: 0,
|
||||||
report_size: 20,
|
report_size: 20,
|
||||||
buttons_1: XInputButtons1 {
|
buttons_1: XInputButtons1 {
|
||||||
dpad_up: value.buttons_1.dpad_up,
|
dpad_up: value.dpad_up,
|
||||||
dpad_down: value.buttons_1.dpad_down,
|
dpad_down: value.dpad_down,
|
||||||
dpad_right: value.buttons_1.dpad_right,
|
dpad_right: value.dpad_right,
|
||||||
dpad_left: value.buttons_1.dpad_left,
|
dpad_left: value.dpad_left,
|
||||||
button_menu: value.buttons_2.button_start,
|
button_menu: value.button_start,
|
||||||
button_back: false,
|
button_back: false,
|
||||||
button_stick_l: false,
|
button_stick_l: false,
|
||||||
button_stick_r: false,
|
button_stick_r: false,
|
||||||
},
|
},
|
||||||
buttons_2: XInputButtons2 {
|
buttons_2: XInputButtons2 {
|
||||||
blank_1: false,
|
blank_1: false,
|
||||||
bumper_l: false,
|
bumper_l: value.trigger_zl,
|
||||||
bumper_r: value.buttons_2.button_z,
|
bumper_r: value.trigger_zr,
|
||||||
button_a: value.buttons_1.button_a,
|
button_a: value.button_a,
|
||||||
button_b: value.buttons_1.button_b,
|
button_b: value.button_b,
|
||||||
button_x: value.buttons_1.button_x,
|
button_x: value.button_x,
|
||||||
button_y: value.buttons_1.button_y,
|
button_y: value.button_y,
|
||||||
button_guide: false,
|
button_guide: false,
|
||||||
},
|
},
|
||||||
analog_trigger_l: value.trigger_l,
|
analog_trigger_l: if value.trigger_l { 255 } else { 0 },
|
||||||
analog_trigger_r: value.trigger_r,
|
analog_trigger_r: if value.trigger_r { 255 } else { 0 },
|
||||||
stick_left_x: (value.stick_x as i16 - 127).clamp(-127, 127) * 257,
|
stick_left_x: (value.stick_state.ax as i16 - 127).clamp(-127, 127) * 257,
|
||||||
stick_left_y: (value.stick_y 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.cstick_x 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.cstick_y as i16 - 127).clamp(-127, 127) * 257,
|
stick_right_y: (value.stick_state.cy as i16 - 127).clamp(-127, 127) * 257,
|
||||||
reserved: [0u8; 18],
|
reserved: [0u8; 18],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -153,7 +153,7 @@ impl From<&GcState> for XInputReport {
|
||||||
pub struct XInputReportBuilder;
|
pub struct XInputReportBuilder;
|
||||||
|
|
||||||
impl HidReportBuilder<32> for 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)
|
XInputReport::from(state)
|
||||||
.pack()
|
.pack()
|
||||||
.expect("Failed to pack XInput State")
|
.expect("Failed to pack XInput State")
|
||||||
|
|
163
src/input.rs
163
src/input.rs
|
@ -17,8 +17,8 @@ use libm::{fmaxf, fminf};
|
||||||
use crate::{
|
use crate::{
|
||||||
config::{
|
config::{
|
||||||
ControllerConfig, ControllerMode, InputConsistencyMode, OverrideGcReportInstruction,
|
ControllerConfig, ControllerMode, InputConsistencyMode, OverrideGcReportInstruction,
|
||||||
OverrideStickState, SIGNAL_CONFIG_CHANGE, SIGNAL_IS_CALIBRATING, SIGNAL_OVERRIDE_GCC_STATE,
|
OverrideStickState, SIGNAL_CONFIG_CHANGE, SIGNAL_IS_CALIBRATING,
|
||||||
SIGNAL_OVERRIDE_STICK_STATE,
|
SIGNAL_OVERRIDE_CONTROLLER_STATE, SIGNAL_OVERRIDE_STICK_STATE,
|
||||||
},
|
},
|
||||||
filter::{run_waveshaping, FilterGains, KalmanState, WaveshapingValues, FILTER_GAINS},
|
filter::{run_waveshaping, FilterGains, KalmanState, WaveshapingValues, FILTER_GAINS},
|
||||||
helpers::XyValuePair,
|
helpers::XyValuePair,
|
||||||
|
@ -29,8 +29,13 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Used to send the button state to the usb task and the calibration task
|
/// 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> =
|
pub static CHANNEL_CONTROLLER_STATE: PubSubChannel<
|
||||||
PubSubChannel::new();
|
CriticalSectionRawMutex,
|
||||||
|
ControllerState,
|
||||||
|
1,
|
||||||
|
4,
|
||||||
|
1,
|
||||||
|
> = PubSubChannel::new();
|
||||||
|
|
||||||
/// Used to send the stick state from the stick task to the main input task
|
/// Used to send the stick state from the stick task to the main input task
|
||||||
static SIGNAL_STICK_STATE: Signal<CriticalSectionRawMutex, StickState> = Signal::new();
|
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;
|
const STICK_HYST_VAL: f32 = 0.3;
|
||||||
pub const FLOAT_ORIGIN: f32 = 127.5;
|
pub const FLOAT_ORIGIN: f32 = 127.5;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Format)]
|
#[derive(Clone, Copy, Debug, Format, PartialEq, Eq)]
|
||||||
pub struct StickState {
|
pub struct StickState {
|
||||||
pub ax: u8,
|
pub ax: u8,
|
||||||
pub ay: u8,
|
pub ay: u8,
|
||||||
|
@ -51,6 +56,17 @@ pub struct StickState {
|
||||||
pub cy: u8,
|
pub cy: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for StickState {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
ax: 127,
|
||||||
|
ay: 127,
|
||||||
|
cx: 127,
|
||||||
|
cy: 127,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
struct StickPositions {
|
struct StickPositions {
|
||||||
x: f32,
|
x: f32,
|
||||||
|
@ -69,6 +85,51 @@ struct RawStickValues {
|
||||||
c_unfiltered: XyValuePair<f32>,
|
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)]
|
#[derive(PartialEq, Eq, Debug, Clone, Format, Copy)]
|
||||||
pub enum Stick {
|
pub enum Stick {
|
||||||
ControlStick,
|
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.x = fminf(125., fmaxf(-125., remapped_c_unfiltered.x));
|
||||||
raw_stick_values.c_unfiltered.y = fminf(125., fmaxf(-125., remapped_c_unfiltered.y));
|
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;
|
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) {
|
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)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn update_button_states(
|
fn update_button_states(
|
||||||
gcc_state: &mut GcState,
|
controller_state: &mut ControllerState,
|
||||||
btn_a: &Input<'_>,
|
btn_a: &Input<'_>,
|
||||||
btn_b: &Input<'_>,
|
btn_b: &Input<'_>,
|
||||||
btn_x: &Input<'_>,
|
btn_x: &Input<'_>,
|
||||||
|
@ -353,42 +414,37 @@ fn update_button_states(
|
||||||
btn_start: &Input<'_>,
|
btn_start: &Input<'_>,
|
||||||
btn_l: &Input<'_>,
|
btn_l: &Input<'_>,
|
||||||
btn_r: &Input<'_>,
|
btn_r: &Input<'_>,
|
||||||
btn_z: &Input<'_>,
|
btn_zr: &Input<'_>,
|
||||||
|
btn_zl: &Input<'_>,
|
||||||
btn_dleft: &Input<'_>,
|
btn_dleft: &Input<'_>,
|
||||||
btn_dright: &Input<'_>,
|
btn_dright: &Input<'_>,
|
||||||
btn_dup: &Input<'_>,
|
btn_dup: &Input<'_>,
|
||||||
btn_ddown: &Input<'_>,
|
btn_ddown: &Input<'_>,
|
||||||
) {
|
) {
|
||||||
gcc_state.buttons_1.button_a = btn_a.is_low();
|
controller_state.button_a = btn_a.is_low();
|
||||||
gcc_state.buttons_1.button_b = btn_b.is_low();
|
controller_state.button_b = btn_b.is_low();
|
||||||
gcc_state.buttons_1.button_x = btn_x.is_low();
|
controller_state.button_x = btn_x.is_low();
|
||||||
gcc_state.buttons_1.button_y = btn_y.is_low();
|
controller_state.button_y = btn_y.is_low();
|
||||||
gcc_state.buttons_2.button_z = btn_z.is_low();
|
controller_state.trigger_zr = btn_zr.is_low();
|
||||||
gcc_state.buttons_2.button_start = btn_start.is_low();
|
controller_state.trigger_zl = btn_zl.is_low();
|
||||||
gcc_state.buttons_2.button_l = btn_l.is_low();
|
controller_state.button_start = btn_start.is_low();
|
||||||
gcc_state.buttons_2.button_r = btn_r.is_low();
|
controller_state.trigger_l = btn_l.is_low();
|
||||||
gcc_state.buttons_1.dpad_left = btn_dleft.is_low();
|
controller_state.trigger_r = btn_r.is_low();
|
||||||
gcc_state.buttons_1.dpad_right = btn_dright.is_low();
|
controller_state.dpad_left = btn_dleft.is_low();
|
||||||
gcc_state.buttons_1.dpad_up = btn_dup.is_low();
|
controller_state.dpad_right = btn_dright.is_low();
|
||||||
gcc_state.buttons_1.dpad_down = btn_ddown.is_low();
|
controller_state.dpad_up = btn_dup.is_low();
|
||||||
gcc_state.trigger_l = match gcc_state.buttons_2.button_l {
|
controller_state.dpad_down = btn_ddown.is_low();
|
||||||
true => 255,
|
|
||||||
false => 0,
|
|
||||||
};
|
|
||||||
gcc_state.trigger_r = match gcc_state.buttons_2.button_r {
|
|
||||||
true => 255,
|
|
||||||
false => 0,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
pub async fn input_integrity_benchmark() {
|
pub async fn input_integrity_benchmark() {
|
||||||
loop {
|
loop {
|
||||||
SIGNAL_OVERRIDE_GCC_STATE.signal(OverrideGcReportInstruction {
|
SIGNAL_OVERRIDE_CONTROLLER_STATE.signal(OverrideGcReportInstruction {
|
||||||
report: {
|
report: {
|
||||||
let mut report = GcState::default();
|
ControllerState {
|
||||||
report.buttons_1.dpad_up = true;
|
dpad_up: true,
|
||||||
report
|
..Default::default()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
duration_ms: 100,
|
duration_ms: 100,
|
||||||
});
|
});
|
||||||
|
@ -402,7 +458,8 @@ pub async fn input_integrity_benchmark() {
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
pub async fn update_button_state_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_a: Input<'static>,
|
||||||
btn_b: Input<'static>,
|
btn_b: Input<'static>,
|
||||||
btn_dright: Input<'static>,
|
btn_dright: Input<'static>,
|
||||||
|
@ -442,11 +499,11 @@ pub async fn update_button_state_task(
|
||||||
MUTEX_INPUT_CONSISTENCY_MODE.lock().await.unwrap()
|
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;
|
let mut override_stick_state: Option<OverrideStickState> = None;
|
||||||
|
|
||||||
|
@ -459,7 +516,7 @@ pub async fn update_button_state_task(
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
update_button_states(
|
update_button_states(
|
||||||
&mut gcc_state,
|
&mut controller_state,
|
||||||
&btn_a,
|
&btn_a,
|
||||||
&btn_b,
|
&btn_b,
|
||||||
&btn_x,
|
&btn_x,
|
||||||
|
@ -467,7 +524,8 @@ pub async fn update_button_state_task(
|
||||||
&btn_start,
|
&btn_start,
|
||||||
&btn_l,
|
&btn_l,
|
||||||
&btn_r,
|
&btn_r,
|
||||||
&btn_z,
|
&btn_zr,
|
||||||
|
&btn_zl,
|
||||||
&btn_dleft,
|
&btn_dleft,
|
||||||
&btn_dright,
|
&btn_dright,
|
||||||
&btn_dup,
|
&btn_dup,
|
||||||
|
@ -476,10 +534,7 @@ pub async fn update_button_state_task(
|
||||||
|
|
||||||
// not every loop pass is going to update the stick state
|
// not every loop pass is going to update the stick state
|
||||||
if let Some(stick_state) = SIGNAL_STICK_STATE.try_take() {
|
if let Some(stick_state) = SIGNAL_STICK_STATE.try_take() {
|
||||||
gcc_state.stick_x = stick_state.ax;
|
controller_state.stick_state = stick_state
|
||||||
gcc_state.stick_y = stick_state.ay;
|
|
||||||
gcc_state.cstick_x = stick_state.cx;
|
|
||||||
gcc_state.cstick_y = stick_state.cy;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(override_stick_state_opt) = SIGNAL_OVERRIDE_STICK_STATE.try_take() {
|
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)
|
// 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);
|
trace!("Overridden gcc state: {:?}", override_gcc_state.report);
|
||||||
let end_time = Instant::now() + Duration::from_millis(override_gcc_state.duration_ms);
|
let end_time = Instant::now() + Duration::from_millis(override_gcc_state.duration_ms);
|
||||||
while Instant::now() < end_time {
|
while Instant::now() < end_time {
|
||||||
|
@ -506,20 +561,20 @@ pub async fn update_button_state_task(
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(override_state) = &override_stick_state {
|
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 {
|
match override_state.which_stick {
|
||||||
Stick::ControlStick => {
|
Stick::ControlStick => {
|
||||||
overriden_gcc_state.stick_x = override_state.x;
|
overriden_gcc_state.stick_state.ax = override_state.x;
|
||||||
overriden_gcc_state.stick_y = override_state.y;
|
overriden_gcc_state.stick_state.ay = override_state.y;
|
||||||
}
|
}
|
||||||
Stick::CStick => {
|
Stick::CStick => {
|
||||||
overriden_gcc_state.cstick_x = override_state.x;
|
overriden_gcc_state.stick_state.cx = override_state.x;
|
||||||
overriden_gcc_state.cstick_y = override_state.y;
|
overriden_gcc_state.stick_state.cy = override_state.y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gcc_publisher.publish_immediate(overriden_gcc_state);
|
gcc_publisher.publish_immediate(overriden_gcc_state);
|
||||||
} else {
|
} else {
|
||||||
input_filter.apply_filter(&mut gcc_state);
|
input_filter.apply_filter(&mut controller_state);
|
||||||
if input_consistency_mode == InputConsistencyMode::SuperHack {
|
if input_consistency_mode == InputConsistencyMode::SuperHack {
|
||||||
// transmit state always for the first 5 seconds to give the console time to initialize the controller
|
// 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)
|
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;
|
initializing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if gcc_state != previous_state || initializing {
|
if controller_state != previous_state || initializing {
|
||||||
gcc_publisher.publish_immediate(gcc_state);
|
gcc_publisher.publish_immediate(controller_state);
|
||||||
previous_state = gcc_state;
|
previous_state = controller_state;
|
||||||
}
|
}
|
||||||
} else {
|
} 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;
|
last_loop_time = n;
|
||||||
};
|
};
|
||||||
|
|
||||||
SIGNAL_STICK_STATE.signal(current_stick_state.clone());
|
SIGNAL_STICK_STATE.signal(current_stick_state);
|
||||||
|
|
||||||
yield_now().await;
|
yield_now().await;
|
||||||
ticker.next().await;
|
ticker.next().await;
|
||||||
|
|
|
@ -2,7 +2,7 @@ use defmt::warn;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::{is_awaitable_button_pressed, AwaitableButtons},
|
config::{is_awaitable_button_pressed, AwaitableButtons},
|
||||||
hid::gcc::GcState,
|
input::ControllerState,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -14,7 +14,7 @@ use crate::{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pub trait InputFilter: Sized {
|
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.
|
/// Presses a single button if another button is pressed.
|
||||||
|
@ -26,46 +26,44 @@ pub struct SingleButtonMacroFilter {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InputFilter for SingleButtonMacroFilter {
|
impl InputFilter for SingleButtonMacroFilter {
|
||||||
fn apply_filter(&mut self, gcc_state: &mut GcState) {
|
fn apply_filter(&mut self, controller_state: &mut ControllerState) {
|
||||||
if is_awaitable_button_pressed(gcc_state, &self.btn_instigator) {
|
if is_awaitable_button_pressed(controller_state, &self.btn_instigator) {
|
||||||
match self.btn_to_press {
|
match self.btn_to_press {
|
||||||
AwaitableButtons::A => {
|
AwaitableButtons::A => {
|
||||||
gcc_state.buttons_1.button_a = true;
|
controller_state.button_a = true;
|
||||||
}
|
}
|
||||||
AwaitableButtons::B => {
|
AwaitableButtons::B => {
|
||||||
gcc_state.buttons_1.button_b = true;
|
controller_state.button_b = true;
|
||||||
}
|
}
|
||||||
AwaitableButtons::X => {
|
AwaitableButtons::X => {
|
||||||
gcc_state.buttons_1.button_x = true;
|
controller_state.button_x = true;
|
||||||
}
|
}
|
||||||
AwaitableButtons::Y => {
|
AwaitableButtons::Y => {
|
||||||
gcc_state.buttons_1.button_y = true;
|
controller_state.button_y = true;
|
||||||
}
|
}
|
||||||
AwaitableButtons::L => {
|
AwaitableButtons::L => {
|
||||||
gcc_state.trigger_l = 255;
|
controller_state.trigger_l = true;
|
||||||
gcc_state.buttons_2.button_l = true;
|
|
||||||
}
|
}
|
||||||
AwaitableButtons::R => {
|
AwaitableButtons::R => {
|
||||||
gcc_state.trigger_r = 255;
|
controller_state.trigger_r = true;
|
||||||
gcc_state.buttons_2.button_r = true;
|
|
||||||
}
|
}
|
||||||
AwaitableButtons::Z => {
|
AwaitableButtons::Z => {
|
||||||
gcc_state.buttons_2.button_z = true;
|
controller_state.trigger_zr = true;
|
||||||
}
|
}
|
||||||
AwaitableButtons::Start => {
|
AwaitableButtons::Start => {
|
||||||
gcc_state.buttons_2.button_start = true;
|
controller_state.button_start = true;
|
||||||
}
|
}
|
||||||
AwaitableButtons::Up => {
|
AwaitableButtons::Up => {
|
||||||
gcc_state.buttons_1.dpad_up = true;
|
controller_state.dpad_up = true;
|
||||||
}
|
}
|
||||||
AwaitableButtons::Down => {
|
AwaitableButtons::Down => {
|
||||||
gcc_state.buttons_1.dpad_down = true;
|
controller_state.dpad_down = true;
|
||||||
}
|
}
|
||||||
AwaitableButtons::Left => {
|
AwaitableButtons::Left => {
|
||||||
gcc_state.buttons_1.dpad_left = true;
|
controller_state.dpad_left = true;
|
||||||
}
|
}
|
||||||
AwaitableButtons::Right => {
|
AwaitableButtons::Right => {
|
||||||
gcc_state.buttons_1.dpad_right = true;
|
controller_state.dpad_right = true;
|
||||||
}
|
}
|
||||||
b => {
|
b => {
|
||||||
warn!(
|
warn!(
|
||||||
|
@ -83,22 +81,22 @@ impl InputFilter for SingleButtonMacroFilter {
|
||||||
pub struct CStickUpTiltFilter;
|
pub struct CStickUpTiltFilter;
|
||||||
|
|
||||||
impl InputFilter for CStickUpTiltFilter {
|
impl InputFilter for CStickUpTiltFilter {
|
||||||
fn apply_filter(&mut self, gcc_state: &mut GcState) {
|
fn apply_filter(&mut self, controller_state: &mut ControllerState) {
|
||||||
if gcc_state.cstick_y > 157 {
|
if controller_state.stick_state.cy > 157 {
|
||||||
if (137..=201).contains(&gcc_state.cstick_x) {
|
if (137..=201).contains(&controller_state.stick_state.cx) {
|
||||||
gcc_state.cstick_x = 201;
|
controller_state.stick_state.cx = 201;
|
||||||
gcc_state.cstick_y = 255;
|
controller_state.stick_state.cy = 255;
|
||||||
} else if (53..=117).contains(&gcc_state.cstick_x) {
|
} else if (53..=117).contains(&controller_state.stick_state.cx) {
|
||||||
gcc_state.cstick_x = 53;
|
controller_state.stick_state.cx = 53;
|
||||||
gcc_state.cstick_y = 255;
|
controller_state.stick_state.cy = 255;
|
||||||
}
|
}
|
||||||
} else if gcc_state.cstick_y < 97 {
|
} else if controller_state.stick_state.cy < 97 {
|
||||||
if (137..=221).contains(&gcc_state.cstick_x) {
|
if (137..=221).contains(&controller_state.stick_state.cx) {
|
||||||
gcc_state.cstick_x = 221;
|
controller_state.stick_state.cx = 221;
|
||||||
gcc_state.cstick_y = 0;
|
controller_state.stick_state.cy = 0;
|
||||||
} else if (53..=117).contains(&gcc_state.cstick_x) {
|
} else if (53..=117).contains(&controller_state.stick_state.cx) {
|
||||||
gcc_state.cstick_x = 33;
|
controller_state.stick_state.cx = 33;
|
||||||
gcc_state.cstick_y = 0;
|
controller_state.stick_state.cy = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,22 +108,22 @@ impl InputFilter for CStickUpTiltFilter {
|
||||||
pub struct CStickAngledFTiltFilter;
|
pub struct CStickAngledFTiltFilter;
|
||||||
|
|
||||||
impl InputFilter for CStickAngledFTiltFilter {
|
impl InputFilter for CStickAngledFTiltFilter {
|
||||||
fn apply_filter(&mut self, gcc_state: &mut GcState) {
|
fn apply_filter(&mut self, controller_state: &mut ControllerState) {
|
||||||
if gcc_state.cstick_y > 147 {
|
if controller_state.stick_state.cy > 147 {
|
||||||
if (147..=225).contains(&gcc_state.cstick_x) {
|
if (147..=225).contains(&controller_state.stick_state.cx) {
|
||||||
gcc_state.cstick_x = 205;
|
controller_state.stick_state.cx = 205;
|
||||||
gcc_state.cstick_y = 205;
|
controller_state.stick_state.cy = 205;
|
||||||
} else if (30..=107).contains(&gcc_state.cstick_x) {
|
} else if (30..=107).contains(&controller_state.stick_state.cx) {
|
||||||
gcc_state.cstick_x = 50;
|
controller_state.stick_state.cx = 50;
|
||||||
gcc_state.cstick_y = 205;
|
controller_state.stick_state.cy = 205;
|
||||||
}
|
}
|
||||||
} else if gcc_state.cstick_y < 107 {
|
} else if controller_state.stick_state.cy < 107 {
|
||||||
if (147..=225).contains(&gcc_state.cstick_x) {
|
if (147..=225).contains(&controller_state.stick_state.cx) {
|
||||||
gcc_state.cstick_x = 205;
|
controller_state.stick_state.cx = 205;
|
||||||
gcc_state.cstick_y = 50;
|
controller_state.stick_state.cy = 50;
|
||||||
} else if (30..=107).contains(&gcc_state.cstick_x) {
|
} else if (30..=107).contains(&controller_state.stick_state.cx) {
|
||||||
gcc_state.cstick_x = 50;
|
controller_state.stick_state.cx = 50;
|
||||||
gcc_state.cstick_y = 50;
|
controller_state.stick_state.cy = 50;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -136,5 +134,5 @@ impl InputFilter for CStickAngledFTiltFilter {
|
||||||
pub struct DummyFilter;
|
pub struct DummyFilter;
|
||||||
|
|
||||||
impl InputFilter for DummyFilter {
|
impl InputFilter for DummyFilter {
|
||||||
fn apply_filter(&mut self, _gcc_state: &mut GcState) {}
|
fn apply_filter(&mut self, _gcc_state: &mut ControllerState) {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,6 +89,7 @@ fn main() -> ! {
|
||||||
spawner
|
spawner
|
||||||
.spawn(update_button_state_task(
|
.spawn(update_button_state_task(
|
||||||
Input::new(AnyPin::from(p.PIN_20), gpio::Pull::Up),
|
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_17), gpio::Pull::Up),
|
||||||
Input::new(AnyPin::from(p.PIN_16), gpio::Pull::Up),
|
Input::new(AnyPin::from(p.PIN_16), gpio::Pull::Up),
|
||||||
Input::new(AnyPin::from(p.PIN_11), gpio::Pull::Up),
|
Input::new(AnyPin::from(p.PIN_11), gpio::Pull::Up),
|
||||||
|
|
|
@ -25,7 +25,7 @@ use libm::powf;
|
||||||
use crate::{
|
use crate::{
|
||||||
config::{ControllerMode, InputConsistencyMode},
|
config::{ControllerMode, InputConsistencyMode},
|
||||||
hid::{
|
hid::{
|
||||||
gcc::{GcReportBuilder, GcState, GccRequestHandler, GCC_REPORT_DESCRIPTOR},
|
gcc::{GcReportBuilder, GccRequestHandler, GCC_REPORT_DESCRIPTOR},
|
||||||
procon::{ProconReportBuilder, ProconRequestHandler, PROCON_REPORT_DESCRIPTOR},
|
procon::{ProconReportBuilder, ProconRequestHandler, PROCON_REPORT_DESCRIPTOR},
|
||||||
xinput::{
|
xinput::{
|
||||||
XInputReaderWriter, XInputReportBuilder, XInputRequestHandler, XInputState,
|
XInputReaderWriter, XInputReportBuilder, XInputRequestHandler, XInputState,
|
||||||
|
@ -33,7 +33,7 @@ use crate::{
|
||||||
},
|
},
|
||||||
HidReaderWriterSplit, UsbReader, UsbWriter,
|
HidReaderWriterSplit, UsbReader, UsbWriter,
|
||||||
},
|
},
|
||||||
input::CHANNEL_GCC_STATE,
|
input::{ControllerState, CHANNEL_CONTROLLER_STATE},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub static SIGNAL_RUMBLE: Signal<CriticalSectionRawMutex, bool> = Signal::new();
|
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}";
|
const DEVICE_INTERFACE_GUID: &str = "{ecceff35-146c-4ff3-acd9-8f992d09acdd}";
|
||||||
|
|
||||||
pub trait HidReportBuilder<const LEN: usize> {
|
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 {
|
struct UsbConfig {
|
||||||
|
@ -216,7 +216,7 @@ where
|
||||||
};
|
};
|
||||||
|
|
||||||
let in_fut = async move {
|
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 last_report_time = Instant::now();
|
||||||
let mut rate_limit_end_time = Instant::now();
|
let mut rate_limit_end_time = Instant::now();
|
||||||
|
|
Loading…
Reference in a new issue