From 4ffc14f9b32863937b7520ad86efad71f2ece740 Mon Sep 17 00:00:00 2001 From: voidanix <51296985+voidanix@users.noreply.github.com> Date: Sun, 16 Apr 2023 13:43:11 +0200 Subject: [PATCH 1/3] tools: Replace rnd macros with STL alternatives --- src/shared/tools.cpp | 43 +++++++++++++++++-------------------------- src/shared/tools.h | 8 +++----- 2 files changed, 20 insertions(+), 31 deletions(-) diff --git a/src/shared/tools.cpp b/src/shared/tools.cpp index d52f8ed70..24984da2e 100644 --- a/src/shared/tools.cpp +++ b/src/shared/tools.cpp @@ -1,39 +1,30 @@ // implementation of generic tools +#include #include "cube.h" ////////////////////////// rnd numbers //////////////////////////////////////// -#define N (624) -#define M (397) -#define K (0x9908B0DFU) +// Seed stored statically to avoid excessive syscall overhead +static std::random_device rndseed; +static std::mt19937 rndalg(rndseed()); -static uint state[N]; -static int next = N; +// Generate a random number up to a certain value and do so starting from 0 +int rnd(int value) { + std::uniform_int_distribution<> rndint(0, value - 1); + return rndint(rndalg); +} -void seedMT(uint seed) -{ - state[0] = seed; - for(uint i = 1; i < N; i++) - state[i] = seed = 1812433253U * (seed ^ (seed >> 30)) + i; - next = 0; +float rndscale(int value) { + std::uniform_real_distribution<> rndreal(0, value - 1); + return rndreal(rndalg); } -uint randomMT() -{ - int cur = next; - if(++next >= N) - { - if(next > N) { seedMT(5489U + time(NULL)); cur = next++; } - else next = 0; - } - uint y = (state[cur] & 0x80000000U) | (state[next] & 0x7FFFFFFFU); - state[cur] = y = state[cur < N-M ? cur + M : cur + M-N] ^ (y >> 1) ^ (-int(y & 1U) & K); - y ^= (y >> 11); - y ^= (y << 7) & 0x9D2C5680U; - y ^= (y << 15) & 0xEFC60000U; - y ^= (y >> 18); - return y; +// Deterministic RNG: used to generate closer results by specifying the seed +int detrnd(int seed, int value) { + std::mt19937 algseed(seed); + std::uniform_int_distribution<> rnddet(0, value - 1); + return rnddet(algseed); } ///////////////////////// network /////////////////////// diff --git a/src/shared/tools.h b/src/shared/tools.h index 9d2d04ab8..2c1b8a63c 100644 --- a/src/shared/tools.h +++ b/src/shared/tools.h @@ -81,9 +81,6 @@ static inline int bitscan(uint mask) #endif #endif -#define rnd(x) ((int)(randomMT()&0x7FFFFFFF)%(x)) -#define rndscale(x) (float((randomMT()&0x7FFFFFFF)*double(x)/double(0x7FFFFFFF))) -#define detrnd(s, x) ((int)(((((uint)(s))*1103515245+12345)>>16)%(x))) #define isnumeric(c) (isdigit(c) || c == '+' || c == '-') #define loop(v,m) for(int v = 0; v < int(m); ++v) @@ -1685,8 +1682,9 @@ extern int listzipfiles(const char *dir, const char *ext, vector &files) extern void backup(const char *fname, const char *ext, int revision = 0, int start = 1, bool store = false, bool full = true); extern void endianswap(void *, int, int); -extern void seedMT(uint seed); -extern uint randomMT(); +extern int rnd(int); +extern float rndscale(int); +extern int detrnd(int, int); extern void putint(ucharbuf &p, int n); extern void putint(packetbuf &p, int n); extern void putint(vector &p, int n); From 372fe2a0137157ae9eb4480e7731caffcda957c6 Mon Sep 17 00:00:00 2001 From: voidanix <51296985+voidanix@users.noreply.github.com> Date: Sun, 16 Apr 2023 14:04:54 +0200 Subject: [PATCH 2/3] tools: Rename rndscale to rndfloat The reason behind such rename was because rndscale() is just rnd(), but it generates a floating point number instead: rename the function, as it is not necessarily related to scaling of any kind. --- src/engine/renderparticles.cpp | 6 +++--- src/shared/tools.cpp | 3 ++- src/shared/tools.h | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/engine/renderparticles.cpp b/src/engine/renderparticles.cpp index c62927f40..0a304146b 100644 --- a/src/engine/renderparticles.cpp +++ b/src/engine/renderparticles.cpp @@ -1552,8 +1552,8 @@ static inline vec offsetvec(vec o, int dir, int dist) } else if(dir < 27) // flat plane { - to[dir%3] = float(rndscale(2*radius)-radius); - to[(dir+1)%3] = float(rndscale(2*radius)-radius); + to[dir%3] = float(rndfloat(2*radius)-radius); + to[(dir+1)%3] = float(rndfloat(2*radius)-radius); to[(dir+2)%3] = 0.0; to.add(p); from = to; @@ -1599,7 +1599,7 @@ void regularflame(int type, const vec &p, float radius, float height, int color, float collidez = collide ? p.z - raycube(p, vec(0, 0, -1), collide >= 0 ? COLLIDERADIUS : max(p.z, 0.0f), RAY_CLIPMAT) + (collide >= 0 ? COLLIDEERROR : 0) : -1; loopi(density) { - vec q = vec(p).add(vec(rndscale(radius*2.f)-radius, rndscale(radius*2.f)-radius, 0)); + vec q = vec(p).add(vec(rndfloat(radius*2.f)-radius, rndfloat(radius*2.f)-radius, 0)); newparticle(q, v, rnd(max(int(fade*height), 1))+1, type, color, s, blend, grav, collide)->val = collidez; } } diff --git a/src/shared/tools.cpp b/src/shared/tools.cpp index 24984da2e..0782d1afa 100644 --- a/src/shared/tools.cpp +++ b/src/shared/tools.cpp @@ -15,7 +15,8 @@ int rnd(int value) { return rndint(rndalg); } -float rndscale(int value) { +// Like rnd(), but generate a floating point number instead +float rndfloat(int value) { std::uniform_real_distribution<> rndreal(0, value - 1); return rndreal(rndalg); } diff --git a/src/shared/tools.h b/src/shared/tools.h index 2c1b8a63c..2d1f6a008 100644 --- a/src/shared/tools.h +++ b/src/shared/tools.h @@ -1683,7 +1683,7 @@ extern void backup(const char *fname, const char *ext, int revision = 0, int sta extern void endianswap(void *, int, int); extern int rnd(int); -extern float rndscale(int); +extern float rndfloat(int); extern int detrnd(int, int); extern void putint(ucharbuf &p, int n); extern void putint(packetbuf &p, int n); From 87b1080d12e35fa920152ee6833a1c6b389a6990 Mon Sep 17 00:00:00 2001 From: voidanix <51296985+voidanix@users.noreply.github.com> Date: Sun, 16 Apr 2023 13:57:54 +0200 Subject: [PATCH 3/3] tools: Define tmprnd() for ad-hoc rng tmprnd() replaces the old randomMT() function, which gave a random unsigned int as a result. The algorithm itself has been replaced by STL's std::mt19937, but tmprnd() allows us to obtain an unsigned int like before. --- src/engine/master.cpp | 4 ++-- src/shared/tools.cpp | 3 +++ src/shared/tools.h | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/engine/master.cpp b/src/engine/master.cpp index a00fe407b..2784c6144 100644 --- a/src/engine/master.cpp +++ b/src/engine/master.cpp @@ -244,7 +244,7 @@ void reqauth(masterclient &c, uint id, char *name, char *hostname) a.reqtime = totalmillis; a.id = id; copystring(a.hostname, host); - uint seed[3] = { uint(starttime), uint(totalmillis), randomMT() }; + uint seed[3] = { uint(starttime), uint(totalmillis), tmprnd() }; static vector buf; buf.setsize(0); a.answer = genchallenge(u->pubkey, seed, sizeof(seed), buf); @@ -270,7 +270,7 @@ void reqserverauth(masterclient &c, char *name) c.serverauthreq.user = u; c.serverauthreq.reqtime = totalmillis; - uint seed[3] = { uint(starttime), uint(totalmillis), randomMT() }; + uint seed[3] = { uint(starttime), uint(totalmillis), tmprnd() }; static vector buf; buf.setsize(0); c.serverauthreq.answer = genchallenge(u->pubkey, seed, sizeof(seed), buf); diff --git a/src/shared/tools.cpp b/src/shared/tools.cpp index 0782d1afa..6d20027b1 100644 --- a/src/shared/tools.cpp +++ b/src/shared/tools.cpp @@ -28,6 +28,9 @@ int detrnd(int seed, int value) { return rnddet(algseed); } +// Generate a positive, ad-hoc random number +uint tmprnd() { return rndalg(); } + ///////////////////////// network /////////////////////// // all network traffic is in 32bit ints, which are then compressed using the following simple scheme (assumes that most values are small). diff --git a/src/shared/tools.h b/src/shared/tools.h index 2d1f6a008..de436ef10 100644 --- a/src/shared/tools.h +++ b/src/shared/tools.h @@ -1685,6 +1685,7 @@ extern void endianswap(void *, int, int); extern int rnd(int); extern float rndfloat(int); extern int detrnd(int, int); +extern uint tmprnd(); extern void putint(ucharbuf &p, int n); extern void putint(packetbuf &p, int n); extern void putint(vector &p, int n);