//////////////////////////////// //~ True randomness #if PlatformIsWindows #if 0 # define BCRYPT_RNG_ALG_HANDLE ((void *)0x00000081) u32 BCryptGenRandom(void *algorithm, u8 *buffer, u32 buffer_size, u32 flags); #endif void TrueRand(String buffer) { BCryptGenRandom(BCRYPT_RNG_ALG_HANDLE, (u8 *)buffer.text, buffer.len, 0); } #else # error TrueRand not implemented for this platform #endif //////////////////////////////// //~ Stateful randomness u64 RandU64FromState(RandState *state) { u64 seed = state->seed; if (seed == 0) { TrueRand(StringFromStruct(&seed)); state->seed = seed; } return seed ^ RandU64FromSeed(++state->counter); } f64 RandF64FromState(RandState *state, f64 range_start, f64 range_end) { return range_start + (range_end - range_start) * ((f64)(RandU64FromState(state) % RandMaxF64) / (f64)RandMaxF64); } //////////////////////////////// //~ Seeded randomness /* Based on Jon Maiga's "mx3" * https://jonkagstrom.com/mx3/mx3_rev2.html */ u64 RandU64FromSeed(u64 seed) { seed = (seed ^ (seed >> 32)) * 0xbea225f9eb34556d; seed = (seed ^ (seed >> 29)) * 0xbea225f9eb34556d; seed = (seed ^ (seed >> 32)) * 0xbea225f9eb34556d; seed = (seed ^ (seed >> 29)); return seed; } u64 RandU64FromSeeds(u64 seed_a, u64 seed_b) { return RandU64FromSeed((seed_a * 3) + seed_b); } f64 RandF64FromSeed(u64 seed, f64 range_start, f64 range_end) { return range_start + (range_end - range_start) * ((f64)(RandU64FromSeed(seed) % RandMaxF64) / (f64)RandMaxF64); }