use std::str::FromStr;
use crate::dsu::DSUFrame;
use crate::errors::DeviceError;
pub trait Device {
fn initialize(&self) -> Result<(), DeviceError>;
fn read_frame(&self) -> Result<DSUFrame, DeviceError>;
}
pub trait FrameDevice<F> {
fn to_dsu_frame(&self, frame: &F, gyro_disabled: bool) -> DSUFrame;
fn is_device_button_pressed(&self, button: &DeviceButton, frame: &F) -> bool;
}
#[derive(Debug, Clone)]
pub enum DeviceButton {
DpadLeft,
DpadDown,
DpadRight,
DpadUp,
Start,
Select,
Guide,
Quaternary,
A,
B,
X,
Y,
L1,
R1,
L2,
R2,
L3,
R3,
L4,
L5,
R4,
R5,
LeftStickTouch,
RightStickTouch,
LeftPadTouch,
RightPadTouch,
LeftGrip,
RightGrip,
Unknown,
}
impl FromStr for DeviceButton {
type Err = DeviceError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"dpad_left" => Ok(Self::DpadLeft),
"dpad_down" => Ok(Self::DpadDown),
"dpad_right" => Ok(Self::DpadRight),
"dpad_up" => Ok(Self::DpadUp),
"start" => Ok(Self::Start),
"select" => Ok(Self::Select),
"guide" => Ok(Self::Guide),
"quaternary" => Ok(Self::Quaternary),
"a" => Ok(Self::A),
"b" => Ok(Self::B),
"x" => Ok(Self::X),
"y" => Ok(Self::Y),
"l1" => Ok(Self::L1),
"r1" => Ok(Self::R1),
"l2" => Ok(Self::L2),
"r2" => Ok(Self::R2),
"l3" => Ok(Self::L3),
"r3" => Ok(Self::R3),
"l4" => Ok(Self::L4),
"l5" => Ok(Self::L5),
"r4" => Ok(Self::R4),
"r5" => Ok(Self::R5),
"left_stick_touch" => Ok(Self::LeftStickTouch),
"right_stick_touch" => Ok(Self::RightStickTouch),
"left_pad_touch" => Ok(Self::LeftPadTouch),
"right_pad_touch" => Ok(Self::RightPadTouch),
"left_grip" => Ok(Self::LeftGrip),
"right_grip" => Ok(Self::RightGrip),
_ => Err(DeviceError::InvalidDeviceButton(s.to_string())),
}
}
}
impl std::fmt::Display for DeviceButton {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::DpadLeft => write!(f, "dpad_left"),
Self::DpadDown => write!(f, "dpad_down"),
Self::DpadRight => write!(f, "dpad_right"),
Self::DpadUp => write!(f, "dpad_up"),
Self::Start => write!(f, "start"),
Self::Select => write!(f, "select"),
Self::Guide => write!(f, "guide"),
Self::Quaternary => write!(f, "quaternary"),
Self::A => write!(f, "a"),
Self::B => write!(f, "b"),
Self::X => write!(f, "x"),
Self::Y => write!(f, "y"),
Self::L1 => write!(f, "l1"),
Self::R1 => write!(f, "r1"),
Self::L2 => write!(f, "l2"),
Self::R2 => write!(f, "r2"),
Self::L3 => write!(f, "l3"),
Self::R3 => write!(f, "r3"),
Self::L4 => write!(f, "l4"),
Self::L5 => write!(f, "l5"),
Self::R4 => write!(f, "r4"),
Self::R5 => write!(f, "r5"),
Self::LeftStickTouch => write!(f, "left_stick_touch"),
Self::RightStickTouch => write!(f, "right_stick_touch"),
Self::LeftPadTouch => write!(f, "left_pad_touch"),
Self::RightPadTouch => write!(f, "right_pad_touch"),
Self::LeftGrip => write!(f, "left_grip"),
Self::RightGrip => write!(f, "right_grip"),
Self::Unknown => write!(f, "unknown"),
}
}
}
#[derive(Default, Debug, Clone)]
pub enum GyroActivationMode {
#[default]
Any,
All,
}
impl FromStr for GyroActivationMode {
type Err = DeviceError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"any" => Ok(Self::Any),
"all" => Ok(Self::All),
_ => Err(DeviceError::InvalidGyroActivationMode(s.to_string())),
}
}
}
impl std::fmt::Display for GyroActivationMode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Any => write!(f, "any"),
Self::All => write!(f, "all"),
}
}
}
#[derive(Debug, Clone)]
pub struct DeviceConfig {
pub no_enable_lizard_mode_on_close: bool,
pub gyro_activation_inputs: Vec<DeviceButton>,
pub gyro_activation_mode: GyroActivationMode,
pub gyro_deadzone: f32,
pub gyro_pitch_scale: f32,
pub gyro_yaw_scale: f32,
pub gyro_roll_scale: f32,
}
impl Default for DeviceConfig {
fn default() -> Self {
Self {
no_enable_lizard_mode_on_close: false,
gyro_activation_inputs: Vec::new(),
gyro_activation_mode: GyroActivationMode::default(),
gyro_deadzone: 0.0,
gyro_pitch_scale: 1.0,
gyro_yaw_scale: 1.0,
gyro_roll_scale: 1.0,
}
}
}