it's now safe (i hope) to include Jambase.configure multiple times
[k8jam.git] / src / bjprng.c
blobcb2fede3cfbd6e96ad9d3115bf2aec313983ec4f
1 /* coded by Ketmar // Vampire Avalon (psyc://ketmar.no-ip.org/~Ketmar)
2 * Understanding is not required. Only obedience.
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include <fcntl.h>
18 #include <stdlib.h>
19 #include <time.h>
20 #include <unistd.h>
22 #include <sys/stat.h>
23 #include <sys/types.h>
25 #include "bjprng.h"
28 ////////////////////////////////////////////////////////////////////////////////
29 // by Bob Jenkins
30 // public domain
31 // http://burtleburtle.net/bob/rand/smallprng.html
33 ////////////////////////////////////////////////////////////////////////////////
34 #define BJPRNG_ROT(x,k) (((x)<<(k))|((x)>>(32-(k))))
37 ////////////////////////////////////////////////////////////////////////////////
38 uint32_t bjprngRand (BJRandCtx *x) {
39 uint32_t e;
40 /* original:
41 e = x->a-BJPRNG_ROT(x->b, 27);
42 x->a = x->b^BJPRNG_ROT(x->c, 17);
43 x->b = x->c+x->d;
44 x->c = x->d+e;
45 x->d = e+x->a;
47 /* better, but slower at least in idiotic m$vc */
48 e = x->a-BJPRNG_ROT(x->b, 23);
49 x->a = x->b^BJPRNG_ROT(x->c, 16);
50 x->b = x->c+BJPRNG_ROT(x->d, 11);
51 x->c = x->d+e;
52 x->d = e+x->a;
54 return x->d;
58 void bjprngInit (BJRandCtx *x, uint32_t seed) {
59 x->a = 0xf1ea5eed;
60 x->b = x->c = x->d = seed;
61 for (int i = 0; i < 20; ++i) bjprngRand(x);
65 static inline uint32_t hashint (uint32_t a) {
66 a -= (a<<6);
67 a ^= (a>>17);
68 a -= (a<<9);
69 a ^= (a<<4);
70 a -= (a<<3);
71 a ^= (a<<10);
72 a ^= (a>>15);
73 return a;
77 uint32_t bjprngGenRandSeed (void) {
78 #ifndef OS_NT
79 uint32_t res = (uint32_t)getpid()^(uint32_t)time(NULL);
80 int fd = open("/dev/urandom", O_RDONLY);
81 if (fd >= 0) {
82 read(fd, &res, sizeof(res));
83 close(fd);
85 #else
86 res = (uint32_t)GetTickCount()^(uint32_t)GetCurrentProcessId();
87 #endif
88 if ((res = hashint(res)) == 0) res = 45;
89 return res;