#include "core/Random.h" static const size_t M = 7; void coreInitRandom(CoreRandom* r, u32 seed) { for(size_t i = 0; i < CORE_ARRAY_LENGTH(r->data); i++) { r->data[i] = seed; seed = seed * 7 + 31; } } static void update(CoreRandom* r) { static const u32 map[2] = {0, 0x8EBFD028}; static const size_t LENGTH = CORE_ARRAY_LENGTH(r->data); for(size_t i = 0; i < LENGTH - M; i++) { r->data[i] = r->data[i + M] ^ (r->data[i] >> 1) ^ map[r->data[i] & 1]; } for(size_t i = LENGTH - M; i < LENGTH; i++) { r->data[i] = r->data[i + (M - LENGTH)] ^ (r->data[i] >> 1) ^ map[r->data[i] & 1]; } r->index = 0; } #define CORE_LIMIT(value, min, max) (min + value % (max - min)) static u32 next(CoreRandom* r) { if(r->index >= CORE_ARRAY_LENGTH(r->data)) { update(r); } u32 u = r->data[r->index++]; u ^= (u << 7) & 0x2B5B2500; u ^= (u << 15) & 0xDB8B0000; u ^= (u >> 16); return u; } u32 coreRandomU32(CoreRandom* r, u32 min, u32 exclusiveMax) { u32 u = next(r); return CORE_LIMIT(u, min, exclusiveMax); } i32 coreRandomI32(CoreRandom* r, i32 min, i32 exclusiveMax) { i32 i = (i32)(next(r) >> 1); return CORE_LIMIT(i, min, exclusiveMax); } size_t coreRandomSize(CoreRandom* r, size_t min, size_t exclusiveMax) { size_t s = next(r); return CORE_LIMIT(s, min, exclusiveMax); } bool coreRandomBool(CoreRandom* r) { return next(r) & 1; } float coreRandomFloat(CoreRandom* r) { u32 u = next(r); float f = (float)u / (float)0xFFFFFFF; return f >= 1.0f ? coreRandomFloat(r) : f; }