From 056f4d287bf0d58ce70a4a77dc85107db5420540 Mon Sep 17 00:00:00 2001 From: Yamagi Burmeister Date: Sat, 2 Jun 2012 10:56:40 +0200 Subject: [PATCH] Add rand.c, an implementation of G. Marsaglia KISS PRNG --- Makefile | 2 ++ src/common/header/common.h | 4 +++ src/common/rand.c | 69 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 src/common/rand.c diff --git a/Makefile b/Makefile index 923087d4..2226dea3 100644 --- a/Makefile +++ b/Makefile @@ -353,6 +353,7 @@ CLIENT_OBJS_ := \ src/common/misc.o \ src/common/netchan.o \ src/common/pmove.o \ + src/common/rand.o \ src/common/szone.o \ src/common/zone.o \ src/common/command/cmd_execution.o \ @@ -403,6 +404,7 @@ SERVER_OBJS_ := \ src/common/misc.o \ src/common/netchan.o \ src/common/pmove.o \ + src/common/rand.o \ src/common/szone.o \ src/common/zone.o \ src/common/command/cmd_execution.o \ diff --git a/src/common/header/common.h b/src/common/header/common.h index 24f3ad5e..88fba834 100644 --- a/src/common/header/common.h +++ b/src/common/header/common.h @@ -757,4 +757,8 @@ void SV_Init (void); void SV_Shutdown (char *finalmsg, qboolean reconnect); void SV_Frame (int msec); +/* Random number generator */ +int randk(void); +void randk_seed(void); + #endif diff --git a/src/common/rand.c b/src/common/rand.c new file mode 100644 index 00000000..6a60508f --- /dev/null +++ b/src/common/rand.c @@ -0,0 +1,69 @@ +/* + * KISS PRNG (c) 2011 Shinobu + * + * This file was optained from zuttobenkyou.wordpress.com + * and modified by the Yamagi Quake II developers. + * + * LICENSE: Public domain + * + * ======================================================================= + * + * KISS PRNG, as devised by Dr. George Marsaglia + * + * ======================================================================= + */ + +#include + +#define QSIZE 0x200000 +#define CNG (cng = 6906969069ULL * cng + 13579) +#define XS (xs ^= (xs << 13), xs ^= (xs >> 17), xs ^= (xs << 43)) +#define KISS (B64MWC() + CNG + XS) + +static uint64_t QARY[QSIZE]; +static int j; +static uint64_t carry; +static uint64_t xs; +static uint64_t cng; + +uint64_t +B64MWC(void) +{ + uint64_t t, x; + + j = (j + 1) & (QSIZE - 1); + x = QARY[j]; + t = (x << 28) + carry; + carry = (x >> 36) - (t < x); + return QARY[j] = t - x; +} + +/* + * Generate a pseudorandom + * signed integer. + */ +int +randk(void) +{ + return (int)KISS; +} + +void +randk_seed(void) +{ + uint64_t i; + + /* Seed QARY[] with CNG+XS: */ + for (i = 0; i < QSIZE; i++) + { + QARY[i] = CNG + XS; + } + + /* Run through several rounds + to warm up the state */ + for (i = 0; i < 256; i++) + { + randk(); + } +} +