use core::sync::atomic::{AtomicU32, AtomicU8, Ordering};
unsafe extern "C" {
fn eadk_random() -> u32;
}
pub fn random_c() -> u32 {
unsafe { eadk_random() }
}
static FAST_RNG_STATE: AtomicU32 = AtomicU32::new(0x12345678);
static SEED_COUNTER: AtomicU8 = AtomicU8::new(0);
#[inline(always)]
pub fn random() -> u32 {
let mut counter = SEED_COUNTER.load(Ordering::Relaxed); let mut state = FAST_RNG_STATE.load(Ordering::Relaxed);
if counter == 0 {
let hardware_seed = random_c();
state ^= hardware_seed;
if state == 0 {
state = 0x12345678;
}
}
counter = counter.wrapping_add(1);
SEED_COUNTER.store(counter, Ordering::Relaxed);
state ^= state << 13;
state ^= state >> 17;
state ^= state << 5;
FAST_RNG_STATE.store(state, Ordering::Relaxed);
state
}
#[inline(always)]
pub fn random_f32() -> f32 {
let rand_bits = random();
let float_bits = 0x3F80_0000_u32 | (rand_bits >> 9);
f32::from_bits(float_bits) - 1.0
}
#[inline(always)]
pub fn random_f32_range(min: f32, max: f32) -> f32 {
debug_assert!(min <= max, "min must be less than or equal to max");
min + (max - min) * random_f32()
}
#[inline(always)]
pub fn randint(min: u32, max: u32) -> u32 {
debug_assert!(min <= max, "min must be less than or equal to max");
if min == 0 && max == u32::MAX {
return random();
}
let range = max - min;
let m = (random() as u64) * (range as u64);
min + (m >> 32) as u32
}
#[inline(always)]
pub fn randint_unbiased(min: u32, max: u32) -> u32 {
debug_assert!(min <= max, "min must be less than or equal to max");
if min == 0 && max == u32::MAX {
return random();
}
let range = max - min;
let mut m = (random() as u64) * (range as u64);
let mut l = m as u32;
if l < range {
let t = range.wrapping_neg() % range; while l < t {
m = (random() as u64) * (range as u64);
l = m as u32;
}
}
min + (m >> 32) as u32
}
#[inline(always)]
pub fn random_bool() -> bool {
(random() & 1) != 0
}
#[inline(always)]
pub fn random_bool_prob(probability: f32) -> bool {
debug_assert!((0.0..=1.0).contains(&probability), "probability must be between 0.0 and 1.0");
random_f32() < probability
}