#[allow(dead_code)]
pub fn u8_mix(a: u8, b: u8, balance: u8) -> u8 {
((a as u16 * (255 - balance) as u16 + b as u16 * balance as u16) >> 8) as u8
}
#[allow(dead_code)]
pub fn u8_u8_mul_shift8(a: u8, b: u8) -> u8 {
((a as u16 * b as u16) >> 8) as u8
}
#[allow(dead_code)]
pub fn u8_u8_mul(a: u8, b: u8) -> u16 {
a as u16 * b as u16
}
#[derive(Debug, Clone, Copy)]
pub struct Random {
rng_state_: u16,
s_seeded_: bool, }
#[allow(dead_code)]
impl Random {
pub fn new() -> Self {
Self::default()
}
pub fn init(&mut self) {
if !self.s_seeded_ {
self.rng_state_ = 0xACE1; self.s_seeded_ = true;
}
}
pub fn seed(&mut self, seed: u16) {
self.rng_state_ = seed;
self.s_seeded_ = true;
}
pub fn update(&mut self) {
self.rng_state_ =
(self.rng_state_ >> 1) ^ (-((self.rng_state_ & 1) as i16) & 0xb400u16 as i16) as u16;
}
pub fn state(&self) -> u16 {
self.rng_state_
}
pub fn state_msb(&self) -> u8 {
(self.rng_state_ >> 8) as u8
}
pub fn get_byte(&mut self) -> u8 {
self.update();
self.state_msb()
}
pub fn get_control_byte(&mut self) -> u8 {
((self.state() >> 8) & 0xFF) as u8
}
pub fn get_word(&mut self) -> u16 {
self.update();
self.state()
}
}
impl Default for Random {
fn default() -> Self {
Self {
rng_state_: 0xACE1, s_seeded_: true,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_get_byte() {
let mut r = Random::new();
assert_eq!(226, r.get_byte());
assert_eq!(113, r.get_byte());
assert_eq!(56, r.get_byte());
r.init();
assert_eq!(28, r.get_byte());
assert_eq!(14, r.get_byte());
assert_eq!(179, r.get_byte());
assert_eq!(237, r.get_byte());
assert_eq!(237, r.get_control_byte());
}
}