Home | History | Annotate | Download | only in src
      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 
      9 struct 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 
     94 extern Rand g_rand1;
     95 
     96 inline uint32_t rand_u32 ( void ) { return g_rand1.rand_u32(); }
     97 inline uint64_t rand_u64 ( void ) { return g_rand1.rand_u64(); }
     98 
     99 inline 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