veloren_world/util/
seed_expan.rs

1/// The zerocopy crate exists and can replace this function.
2/// We should evaluate using it when we have multiple usage spots for it.
3/// For now we have this safe alternative.
4fn cast_u32x8_u8x32(a: [u32; 8]) -> [u8; 32] {
5    let mut r = [0; 32];
6    for i in 0..8 {
7        let a = a[i].to_ne_bytes();
8        for j in 0..4 {
9            r[i * 4 + j] = a[j];
10        }
11    }
12    r
13}
14
15/// Simple non-cryptographic diffusion function.
16#[inline(always)]
17pub fn diffuse(mut a: u32) -> u32 {
18    a ^= a.rotate_right(23);
19    a.wrapping_mul(2654435761)
20}
21
22/// Diffuse but takes multiple values as input.
23#[inline(always)]
24pub fn diffuse_mult(v: &[u32]) -> u32 {
25    let mut state = (1 << 31) - 1;
26    for e in v {
27        state = diffuse(state ^ e);
28    }
29    state
30}
31
32/// Expand a 32 bit seed into a 32 byte RNG state.
33pub fn rng_state(mut x: u32) -> [u8; 32] {
34    let mut r: [u32; 8] = [0; 8];
35    for s in &mut r {
36        x = diffuse(x);
37        *s = x;
38    }
39    cast_u32x8_u8x32(r)
40}