1
0
mirror of https://github.com/TerryCavanagh/VVVVVV.git synced 2024-06-01 18:43:33 +02:00
VVVVVV/desktop_version/src/Xoshiro.c
Misa e6a3df6ca6 Move xoshiro_seed debug print to top
In its previous location, it would only print the value of `s` after it
had been mutated by `splitmix32` four times, and it doesn't get used
after that, so the print isn't very useful.

Mixing code and declarations here is fine because starting from a few
months ago, we compile with C99 and if we ever need to compile with C90
then it's trivial to add braces surrounding the declarations.
2022-11-14 13:14:25 -08:00

69 lines
1.2 KiB
C

#include <stdint.h>
#include "Vlogging.h"
/* Implements the xoshiro128+ PRNG. */
static uint32_t rotl(const uint32_t x, const int k)
{
return (x << k) | (x >> (32 - k));
}
static uint32_t s[4];
static uint32_t splitmix32(uint32_t* x)
{
uint32_t z = (*x += 0x9e3779b9UL);
z = (z ^ (z >> 15)) * 0xbf58476dUL;
z = (z ^ (z >> 13)) * 0x94d049bbUL;
return z ^ (z >> 16);
}
static void seed(
const uint32_t s0,
const uint32_t s1,
const uint32_t s2,
const uint32_t s3
) {
s[0] = s0;
s[1] = s1;
s[2] = s2;
s[3] = s3;
}
uint32_t xoshiro_next(void)
{
const uint32_t result = s[0] + s[3];
const uint32_t t = s[1] << 9;
s[2] ^= s[0];
s[3] ^= s[1];
s[1] ^= s[2];
s[0] ^= s[3];
s[2] ^= t;
s[3] = rotl(s[3], 11);
vlog_debug("Next xoshiro is %u.", result);
return result;
}
void xoshiro_seed(uint32_t s)
{
vlog_debug("Xoshiro seeded with %u.", s);
const uint32_t s0 = splitmix32(&s);
const uint32_t s1 = splitmix32(&s);
const uint32_t s2 = splitmix32(&s);
const uint32_t s3 = splitmix32(&s);
seed(s0, s1, s2, s3);
}
float xoshiro_rand(void)
{
return ((float) xoshiro_next()) / ((float) UINT32_MAX);
}