option.c: fixed warnings
[k8jam.git] / src / bjprng.c
blob9a63202b288ca1dbfd9bdd9c074cd2e4caf1194b
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, version 3 of the License ONLY.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #include <fcntl.h>
17 #include <stdlib.h>
18 #include <time.h>
19 #include <unistd.h>
21 #include <sys/stat.h>
22 #include <sys/types.h>
24 #include "bjprng.h"
27 static inline uint32_t hashint (uint32_t a) {
28 a -= (a<<6);
29 a ^= (a>>17);
30 a -= (a<<9);
31 a ^= (a<<4);
32 a -= (a<<3);
33 a ^= (a<<10);
34 a ^= (a>>15);
35 return a;
39 void bjprngRandomize (BJRandCtx *rng) {
40 #ifndef OS_NT
41 uint32_t res0, res1;
42 int fd = open("/dev/urandom", O_RDONLY);
43 if (fd >= 0) {
44 read(fd, &res0, sizeof(res0));
45 read(fd, &res1, sizeof(res1));
46 close(fd);
47 } else {
48 res0 = hashint((uint32_t)getpid()^(uint32_t)time(NULL));
49 res1 = hashint((uint32_t)getpid())^hashint((uint32_t)time(NULL));
51 #else
52 uint32_t res0 = hashint((uint32_t)GetTickCount()^(uint32_t)GetCurrentProcessId());
53 uint32_t res1 = hashint((uint32_t)GetTickCount())^hashint((uint32_t)GetCurrentProcessId());
54 #endif
55 rng->state = (((uint64_t)res0)<<32)|res1;
56 rng->inc = 1;
57 for (res0 = 16; res0 > 0; --res0) bjprngRand(rng);
61 // *Really* minimal PCG32 code / (c) 2014 M.E. O'Neill / pcg-random.org
62 // Licensed under Apache License 2.0 (NO WARRANTY, etc. see website)
63 uint32_t bjprngRand (BJRandCtx *rng) {
64 uint64_t oldstate = rng->state;
65 // advance internal state
66 rng->state = oldstate*6364136223846793005ULL+(rng->inc|1);
67 // calculate output function (XSH RR), uses old state for max ILP
68 uint32_t xorshifted = ((oldstate>>18u)^oldstate)>>27u;
69 uint32_t rot = oldstate>>59u;
70 return (xorshifted>>rot)|(xorshifted<<((-rot)&31));