112 lines
2.8 KiB
C
112 lines
2.8 KiB
C
#include "rng.h"
|
|
#include "sys.h"
|
|
#include "resource.h"
|
|
#include "arena.h"
|
|
|
|
GLOBAL struct {
|
|
struct arena arena;
|
|
u64 *noise;
|
|
u64 noise_count;
|
|
} G = ZI, DEBUG_ALIAS(G, G_rng);
|
|
|
|
/* ========================== *
|
|
* Generate random number file
|
|
* (unused function)
|
|
* ========================== */
|
|
|
|
#if 0
|
|
INTERNAL void gen_random_file(struct string path, u32 count)
|
|
{
|
|
{
|
|
/* Clear file */
|
|
struct sys_file f = sys_file_open_write(path);
|
|
sys_file_write(f, STRING(0, 0));
|
|
sys_file_close(f);
|
|
}
|
|
struct sys_file f = sys_file_open_append(path);
|
|
for (u32 i = 0; i < count; ++i) {
|
|
u64 rand = rng_rand_u64();
|
|
sys_file_write(f, STRING_FROM_STRUCT(&rand));
|
|
}
|
|
sys_file_close(f);
|
|
}
|
|
#endif
|
|
|
|
/* ========================== *
|
|
* Startup
|
|
* ========================== */
|
|
|
|
struct rng_startup_receipt rng_startup(struct resource_startup_receipt *resource_sr)
|
|
{
|
|
(UNUSED)resource_sr;
|
|
struct string noise_path = LIT("res/noise.dat");
|
|
if (resource_exists(noise_path)) {
|
|
struct resource r = resource_open(noise_path);
|
|
G.noise_count = r.data.len / sizeof(*G.noise);
|
|
G.arena = arena_alloc(sizeof(u64) * G.noise_count);
|
|
G.noise = arena_push_array(&G.arena, u64, G.noise_count);
|
|
MEMCPY(G.noise, r.data.text, r.data.len);
|
|
resource_close(r);
|
|
} else {
|
|
sys_panic(LIT("Failed to locate pre-computed noise resource"));
|
|
}
|
|
return (struct rng_startup_receipt) { 0 };
|
|
}
|
|
|
|
/* ========================== *
|
|
* Rand
|
|
* ========================== */
|
|
|
|
u32 rng_rand_u32(void)
|
|
{
|
|
u32 v = 0;
|
|
sys_rand(STRING_FROM_STRUCT(&v));
|
|
return v;
|
|
}
|
|
|
|
u64 rng_rand_u64(void)
|
|
{
|
|
u64 v = 0;
|
|
sys_rand(STRING_FROM_STRUCT(&v));
|
|
return v;
|
|
}
|
|
|
|
f32 rng_rand_f32(f32 range_start, f32 range_end)
|
|
{
|
|
return ((f32)rng_rand_u32() / (f32)U32_MAX) * (range_end - range_start) + range_start;
|
|
}
|
|
|
|
f64 rng_rand_f64(f64 range_start, f64 range_end)
|
|
{
|
|
return ((f64)rng_rand_u64() / (f64)U64_MAX) * (range_end - range_start) + range_start;
|
|
}
|
|
|
|
/* ========================== *
|
|
* Noise
|
|
* Functions that return a deterministic pre-computed random number based on the provided seed
|
|
*
|
|
* NOTE: Noise pattern repeats after period depending on how much noise data exists in noise.dat
|
|
* ========================== */
|
|
|
|
/* TODO: Use deterministic prng rather than embedded data */
|
|
|
|
u32 rng_noise_u32(u32 seed)
|
|
{
|
|
return (u32)G.noise[seed % G.noise_count];
|
|
}
|
|
|
|
u64 rng_noise_u64(u64 seed)
|
|
{
|
|
return G.noise[seed % G.noise_count];
|
|
}
|
|
|
|
f32 rng_noise_f32(u64 seed, f32 range_start, f32 range_end)
|
|
{
|
|
return ((f32)rng_noise_u32(seed) / (f32)U32_MAX) * (range_end - range_start) + range_start;
|
|
}
|
|
|
|
f32 rng_noise_f64(u64 seed, f64 range_start, f64 range_end)
|
|
{
|
|
return ((f64)rng_noise_u64(seed) / (f64)U64_MAX) * (range_end - range_start) + range_start;
|
|
}
|