1#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//-----------------------------------------------------------------------------
118