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