mirror of https://github.com/bjornbytes/lovr.git
99 lines
2.8 KiB
C
99 lines
2.8 KiB
C
#include "api.h"
|
|
#include "math/randomGenerator.h"
|
|
#include "util.h"
|
|
#include <lua.h>
|
|
#include <lauxlib.h>
|
|
#include <math.h>
|
|
|
|
static double luax_checkrandomseedpart(lua_State* L, int index) {
|
|
double x = luaL_checknumber(L, index);
|
|
|
|
if (!isfinite(x)) {
|
|
luaL_argerror(L, index, "invalid random seed");
|
|
}
|
|
|
|
return x;
|
|
}
|
|
|
|
uint64_t luax_checkrandomseed(lua_State* L, int index) {
|
|
Seed seed;
|
|
|
|
if (lua_isnoneornil(L, index + 1)) {
|
|
seed.b64 = luax_checkrandomseedpart(L, index);
|
|
} else {
|
|
seed.b32.lo = luax_checkrandomseedpart(L, index);
|
|
seed.b32.hi = luax_checkrandomseedpart(L, index + 1);
|
|
}
|
|
|
|
return seed.b64;
|
|
}
|
|
|
|
int l_lovrRandomGeneratorGetSeed(lua_State* L) {
|
|
RandomGenerator* generator = luax_checktype(L, 1, RandomGenerator);
|
|
Seed seed = lovrRandomGeneratorGetSeed(generator);
|
|
lua_pushnumber(L, seed.b32.lo);
|
|
lua_pushnumber(L, seed.b32.hi);
|
|
return 2;
|
|
}
|
|
|
|
int l_lovrRandomGeneratorSetSeed(lua_State* L) {
|
|
RandomGenerator* generator = luax_checktype(L, 1, RandomGenerator);
|
|
Seed seed = { .b64 = luax_checkrandomseed(L, 2) };
|
|
lovrRandomGeneratorSetSeed(generator, seed);
|
|
return 0;
|
|
}
|
|
|
|
static int l_lovrRandomGeneratorGetState(lua_State* L) {
|
|
RandomGenerator* generator = luax_checktype(L, 1, RandomGenerator);
|
|
size_t length = 32;
|
|
char state[32];
|
|
lovrRandomGeneratorGetState(generator, state, length);
|
|
lua_pushstring(L, state);
|
|
return 1;
|
|
}
|
|
|
|
static int l_lovrRandomGeneratorSetState(lua_State* L) {
|
|
RandomGenerator* generator = luax_checktype(L, 1, RandomGenerator);
|
|
const char* state = luaL_checklstring(L, 2, NULL);
|
|
if (lovrRandomGeneratorSetState(generator, state)) {
|
|
return luaL_error(L, "invalid random state %s", state);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int l_lovrRandomGeneratorRandom(lua_State* L) {
|
|
RandomGenerator* generator = luax_checktype(L, 1, RandomGenerator);
|
|
double r = lovrRandomGeneratorRandom(generator);
|
|
|
|
if (lua_gettop(L) >= 3) {
|
|
double lower = luaL_checknumber(L, 2);
|
|
double upper = luaL_checknumber(L, 3);
|
|
lua_pushnumber(L, floor(r * (upper - lower + 1)) + lower);
|
|
} else if (lua_gettop(L) >= 2) {
|
|
double upper = luaL_checknumber(L, 2);
|
|
lua_pushnumber(L, floor(r * upper) + 1);
|
|
} else {
|
|
lua_pushnumber(L, r);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int l_lovrRandomGeneratorRandomNormal(lua_State* L) {
|
|
RandomGenerator* generator = luax_checktype(L, 1, RandomGenerator);
|
|
float sigma = luax_optfloat(L, 2, 1.f);
|
|
float mu = luax_optfloat(L, 3, 0.f);
|
|
lua_pushnumber(L, mu + lovrRandomGeneratorRandomNormal(generator) * sigma);
|
|
return 1;
|
|
}
|
|
|
|
const luaL_Reg lovrRandomGenerator[] = {
|
|
{ "getSeed", l_lovrRandomGeneratorGetSeed },
|
|
{ "setSeed", l_lovrRandomGeneratorSetSeed },
|
|
{ "getState", l_lovrRandomGeneratorGetState },
|
|
{ "setState", l_lovrRandomGeneratorSetState },
|
|
{ "random", l_lovrRandomGeneratorRandom },
|
|
{ "randomNormal", l_lovrRandomGeneratorRandomNormal },
|
|
{ NULL, NULL }
|
|
};
|