blob: e5a78fb274d323b99573ab0cfb87922305fa17d5 [file] [log] [blame]
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +00001#pragma once
2
3#include "Types.h"
4
5//-----------------------------------------------------------------------------
tanjent@gmail.comad4b3632010-11-05 01:20:58 +00006// Xorshift RNG based on code by George Marsaglia
7// http://en.wikipedia.org/wiki/Xorshift
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +00008
9struct Rand
10{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000011 uint32_t x;
12 uint32_t y;
13 uint32_t z;
14 uint32_t w;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000015
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000016 Rand()
17 {
18 reseed(uint32_t(0));
19 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000020
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000021 Rand( uint32_t seed )
22 {
23 reseed(seed);
24 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000025
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000026 void reseed ( uint32_t seed )
27 {
28 x = 0x498b3bc5 ^ seed;
29 y = 0;
30 z = 0;
31 w = 0;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000032
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000033 for(int i = 0; i < 10; i++) mix();
34 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000035
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000036 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;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000042
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000043 for(int i = 0; i < 10; i++) mix();
44 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000045
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000046 //-----------------------------------------------------------------------------
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000047
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000048 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 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000054
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000055 uint32_t rand_u32 ( void )
56 {
57 mix();
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000058
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000059 return x;
60 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000061
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000062 uint64_t rand_u64 ( void )
63 {
64 mix();
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000065
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000066 uint64_t a = x;
67 uint64_t b = y;
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000068
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000069 return (a << 32) | b;
70 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000071
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000072 void rand_p ( void * blob, int bytes )
73 {
aappleby@google.coma27c2812011-04-13 23:23:14 +000074 uint32_t * blocks = reinterpret_cast<uint32_t*>(blob);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000075
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000076 while(bytes >= 4)
77 {
aappleby@google.coma27c2812011-04-13 23:23:14 +000078 blocks[0] = rand_u32();
79 blocks++;
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000080 bytes -= 4;
81 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000082
aappleby@google.coma27c2812011-04-13 23:23:14 +000083 uint8_t * tail = reinterpret_cast<uint8_t*>(blocks);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000084
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000085 for(int i = 0; i < bytes; i++)
86 {
87 tail[i] = (uint8_t)rand_u32();
88 }
89 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000090};
91
92//-----------------------------------------------------------------------------
93
94extern Rand g_rand1;
95
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000096inline uint32_t rand_u32 ( void ) { return g_rand1.rand_u32(); }
97inline uint64_t rand_u64 ( void ) { return g_rand1.rand_u64(); }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000098
99inline void rand_p ( void * blob, int bytes )
100{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000101 uint32_t * blocks = (uint32_t*)blob;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000102
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000103 while(bytes >= 4)
104 {
105 *blocks++ = rand_u32();
106 bytes -= 4;
107 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000108
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000109 uint8_t * tail = (uint8_t*)blocks;
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000110
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000111 for(int i = 0; i < bytes; i++)
112 {
113 tail[i] = (uint8_t)rand_u32();
114 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000115}
116
117//-----------------------------------------------------------------------------