/** SGX

The   sss    gggg x   x   
     s      g      x x    Engine
      sss   g  gg   x
         s  g   g  x x          Copyright 1995-2008.
     ssss    gggg x   x         Steven Goodwin. All Rights Reserved.
    
This version has been released under the GNU Public License v2.0.

Please see the license files for details.

File: src/sgx/core/sgxlib/random.cpp

*/

#include "sgx/core/types/types.hpp"
#include "sgx/core/sgxlib/random.hpp"

/*
This file contains a pruned version of George Marsaglia's post 
from http://www.ciphersbyritter.com/NEWS4/RANDC.HTM 

Minor alterations have been made to fit in with the sgx naming scheme.
*/


/* Random seeds must be used to reset z,w,jsr,jco
*/
namespace {
	tUINT32 z=362436069, w=521288629, jsr=123456789, jcong=380116160;
}

#define znew  ((z=36969*(z&65535)+(z>>16))<<16)
#define wnew  ((w=18000*(w&65535)+(w>>16))&65535)
#define MWC   (znew+wnew)
#define SHR3  (jsr=(jsr=(jsr=jsr^(jsr<<17))^(jsr>>13))^(jsr<<5))
#define CONG  (jcong=69069*jcong+1234567)
#define KISS  ((MWC^CONG)+SHR3)
#define UNI   (KISS*2.328306e-10f)

/**
The four arguments values indicate the seeds which allow you to
replicate the stream of pseudo-random numbers. The defaults are
362436069, 521288629, 123456789, and 380116160, but need not be used.
*/
void 
sgxSetRandSeed(tUINT32 nz, tUINT32 nw, tUINT32 njsr, tUINT32 njcong)
{
	z = nz;
	w = nw;
	jsr = njsr;
	jcong = njcong;
}

/**
Returns a random number between 0 and 1.
*/
tREAL32 
sgxRand()
{
	return UNI;
}

/**
Returns a random number between 0 and @n.
*/
tUINT32 
sgxRand(int n)
{
	return tUINT32(UNI*n);
}

/**
Returns a random number between @from and @to inclusive.
*/
tUINT32 
sgxRand(const int from, const int to)
{
	return tUINT32(UNI*(to-from)) + from;
}

