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