Files
VVVVVV/desktop_version/src/Xoshiro.c
Misa 424c8c80be Add debug statements to print xoshiro RNG values
This is useful to investigate any TAS desync/reproducibility issues
relating to RNG, because even though I specifically separated the
Gravitron RNG away from other RNG and made it not dependent on the
system libc rand() function, there's still apparently some differences
in RNG execution between systems, resulting in TASVideos submission 7575
( https://tasvideos.org/7575S ) not syncing for everyone except the
author.

It seems that SDL_GetTicks(), which is used to seed the xoshiro RNG, is
not reliably consistent between systems, so in the future I will
probably replace it with a counter that is incremented each frame
starting from game startup, which is probably better.
2022-07-28 16:55:29 -07: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)
{
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);
vlog_debug("Xoshiro seeded with %u.", s);
}
float xoshiro_rand(void)
{
return ((float) xoshiro_next()) / ((float) UINT32_MAX);
}