#include "ExMath.h"

#include <stdint.h>

static uint64_t rngstate, rnginc;

void Math_SeedRNG(unsigned long v)
{
	rngstate = 0;
	rnginc = ((v & 15) << 1) | 1;
	(void)Math_Random();
	rngstate += v;
	(void)Math_Random();
}

// https://www.pcg-random.org/download.html
unsigned Math_Random(void)
{
	uint32_t xorshifted, rot;
	uint64_t oldstate = rngstate;
	
	// Advance internal state
	rngstate = oldstate * 6364136223846793005ULL + (rnginc | 1);
	
	// Calculate output function (XSH RR), uses old state for max ILP
	xorshifted = ((oldstate >> 18u) ^ oldstate) >> 27u;
	rot = oldstate >> 59u;
	return (xorshifted >> rot) | (xorshifted << ((-(*(int32_t*)&rot)) & 31));
}

float Math_RandomFloat(void)
{
	return (float)(Math_Random() / (float)UINT32_MAX);
}
