#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Rumble {
frequency: f32,
amplitude: f32,
}
impl Rumble {
pub fn frequency(self) -> f32 {
self.frequency
}
pub fn amplitude(self) -> f32 {
self.amplitude
}
pub fn new(freq: f32, amp: f32) -> Self {
let freq = if freq < 0.0 {
0.0
} else if freq > 1252.0 {
1252.0
} else {
freq
};
let amp = if amp < 0.0 {
0.0
} else if amp > 1.799 {
1.799
} else {
amp
};
Self {
frequency: freq,
amplitude: amp,
}
}
pub fn is_safe(self) -> bool {
self.amplitude < 1.003
}
pub fn stop() -> Self {
Self {
frequency: 0.0,
amplitude: 0.0,
}
}
}
impl Into<[u8; 4]> for Rumble {
fn into(self) -> [u8; 4] {
let encoded_hex_freq = f32::round(f32::log2(self.frequency / 10.0) * 32.0) as u8;
let hf_freq: u16 = (encoded_hex_freq as u16).saturating_sub(0x60) * 4;
let lf_freq: u8 = encoded_hex_freq.saturating_sub(0x41) + 1;
let encoded_hex_amp = if self.amplitude > 0.23 {
f32::round(f32::log2(self.amplitude * 8.7) * 32.0) as u8
} else if self.amplitude > 0.12 {
f32::round(f32::log2(self.amplitude * 17.0) * 16.0) as u8
} else {
f32::round(((f32::log2(self.amplitude) * 32.0) - 96.0) / (4.0 - 2.0 * self.amplitude)) as u8
};
let hf_amp: u16 = {
let hf_amp: u16 = encoded_hex_amp as u16 * 2;
if hf_amp > 0x01FC {
0x01FC
} else { hf_amp }
}; let lf_amp: u8 = {
let lf_amp = encoded_hex_amp / 2 + 64;
if lf_amp > 0x7F {
0x7F
} else { lf_amp }
};
let mut buf = [0u8; 4];
buf[0] = (hf_freq & 0xFF) as u8;
buf[1] = (hf_amp + (hf_freq.wrapping_shr(8) & 0xFF)) as u8;
buf[2] = lf_freq.saturating_add(lf_amp.wrapping_shr(8));
buf[3] = lf_amp;
buf
}
}