use std::f32::consts::PI;
use crate::{Radians, state::DualsenseAxisValue};
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
pub struct AxisValue(u8);
impl Default for AxisValue {
fn default() -> Self {
Self(127)
}
}
impl AxisValue {
pub fn as_ratio(&self) -> f32 {
((self.0 as f32) / (u8::MAX as f32)).clamp(0.0, 1.0)
}
}
impl From<DualsenseAxisValue> for AxisValue {
fn from(val: DualsenseAxisValue) -> Self {
AxisValue(val.into())
}
}
impl From<u8> for AxisValue {
fn from(val: u8) -> Self {
AxisValue(val)
}
}
impl From<Radians> for AxisValue {
fn from(val: Radians) -> Self {
let value = ((val.get_angle() / PI) + 0.5) * (u8::MAX as f32);
AxisValue(value as u8)
}
}
#[test]
fn axis_value_from_dualsense_value() {
let ds_values: [DualsenseAxisValue; 5] = [0, 100, 128, 200, 255].map(|v| v.into());
let expected_values: [AxisValue; 5] = [0, 100, 128, 200, 255].map(|v| v.into());
let got_values: [AxisValue; 5] = ds_values.map(|v| v.into());
assert_eq!(expected_values, got_values)
}
#[test]
fn axis_value_from_radians() {
let radians_values: [Radians; _] =
[0., PI, PI / 2., PI * 3. / 2., PI * 2., -PI / 2.].map(|v| v.into());
let expected_values: [AxisValue; _] = [127, 255, 255, 255, 255, 0].map(|v| v.into());
let got_values: [AxisValue; _] = radians_values.map(|v| v.into());
assert_eq!(expected_values, got_values)
}