blob: 7e0df3fa45d95db9b2ef3661e6a68ab7f8516d10 [file] [log] [blame]
tanjent@gmail.comf3b78972012-03-01 03:38:55 +00001#pragma once
2
3#include "Types.h"
4
5//-----------------------------------------------------------------------------
6// Xorshift RNG based on code by George Marsaglia
7// http://en.wikipedia.org/wiki/Xorshift
8
9struct Rand
10{
11 uint32_t x;
12 uint32_t y;
13 uint32_t z;
14 uint32_t w;
15
16 Rand()
17 {
18 reseed(uint32_t(0));
19 }
20
21 Rand( uint32_t seed )
22 {
23 reseed(seed);
24 }
25
26 void reseed ( uint32_t seed )
27 {
28 x = 0x498b3bc5 ^ seed;
29 y = 0;
30 z = 0;
31 w = 0;
32
33 for(int i = 0; i < 10; i++) mix();
34 }
35
36 void reseed ( uint64_t seed )
37 {
38 x = 0x498b3bc5 ^ (uint32_t)(seed >> 0);
39 y = 0x5a05089a ^ (uint32_t)(seed >> 32);
40 z = 0;
41 w = 0;
42
43 for(int i = 0; i < 10; i++) mix();
44 }
45
46 //-----------------------------------------------------------------------------
47
48 void mix ( void )
49 {
50 uint32_t t = x ^ (x << 11);
51 x = y; y = z; z = w;
52 w = w ^ (w >> 19) ^ t ^ (t >> 8);
53 }
54
55 uint32_t rand_u32 ( void )
56 {
57 mix();
58
59 return x;
60 }
61
62 uint64_t rand_u64 ( void )
63 {
64 mix();
65
66 uint64_t a = x;
67 uint64_t b = y;
68
69 return (a << 32) | b;
70 }
71
72 void rand_p ( void * blob, int bytes )
73 {
74 uint32_t * blocks = reinterpret_cast<uint32_t*>(blob);
75
76 while(bytes >= 4)
77 {
78 blocks[0] = rand_u32();
79 blocks++;
80 bytes -= 4;
81 }
82
83 uint8_t * tail = reinterpret_cast<uint8_t*>(blocks);
84
85 for(int i = 0; i < bytes; i++)
86 {
87 tail[i] = (uint8_t)rand_u32();
88 }
89 }
90};
91
92//-----------------------------------------------------------------------------
93
94extern Rand g_rand1;
95
96inline uint32_t rand_u32 ( void ) { return g_rand1.rand_u32(); }
97inline uint64_t rand_u64 ( void ) { return g_rand1.rand_u64(); }
98
99inline void rand_p ( void * blob, int bytes )
100{
101 uint32_t * blocks = (uint32_t*)blob;
102
103 while(bytes >= 4)
104 {
105 *blocks++ = rand_u32();
106 bytes -= 4;
107 }
108
109 uint8_t * tail = (uint8_t*)blocks;
110
111 for(int i = 0; i < bytes; i++)
112 {
113 tail[i] = (uint8_t)rand_u32();
114 }
115}
116
117//-----------------------------------------------------------------------------