| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 | //-----------------------------------------------------------------------------// Copyright (c) 2012 GarageGames, LLC//// Permission is hereby granted, free of charge, to any person obtaining a copy// of this software and associated documentation files (the "Software"), to// deal in the Software without restriction, including without limitation the// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or// sell copies of the Software, and to permit persons to whom the Software is// furnished to do so, subject to the following conditions://// The above copyright notice and this permission notice shall be included in// all copies or substantial portions of the Software.//// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS// IN THE SOFTWARE.//-----------------------------------------------------------------------------#include "platform/platform.h"#include "math/mRandom.h"#include "core/util/journal/journal.h"MRandomLCG gRandGen;U32 gRandGenSeed = 1376312589;void MRandomLCG::setGlobalRandSeed(U32 seed){	if (Journal::IsPlaying())		Journal::Read(&gRandGenSeed);	else	{		gRandGenSeed = seed;		if (Journal::IsRecording())			Journal::Write(gRandGenSeed);	}	//now actually set the seed	gRandGen.setSeed(gRandGenSeed);}static U32 msSeed = 1376312589;inline U32 generateSeed(){   // A very, VERY crude LCG but good enough to generate   // a nice range of seed values   msSeed = (msSeed * 0x015a4e35L) + 1;   msSeed = (msSeed>>16)&0x7fff;   return (msSeed);}//--------------------------------------void MRandomGenerator::setSeed(){   setSeed(generateSeed());}//--------------------------------------const S32 MRandomLCG::msQuotient  = S32_MAX / 16807L;const S32 MRandomLCG::msRemainder = S32_MAX % 16807L;//--------------------------------------MRandomLCG::MRandomLCG(){   setSeed(generateSeed());}MRandomLCG::MRandomLCG(S32 s){   setSeed(s);}//--------------------------------------void MRandomLCG::setSeed(S32 s){   mSeed = s;}//--------------------------------------U32 MRandomLCG::randI(){   if ( mSeed <= msQuotient )      mSeed = (mSeed * 16807) % S32_MAX;   else   {      S32 high_part = mSeed / msQuotient;      S32 low_part  = mSeed % msQuotient;      S32 test = (16807 * low_part) - (msRemainder * high_part);      if ( test > 0 )         mSeed = test;      else         mSeed = test + S32_MAX;   }   return mSeed;}//--------------------------------------MRandomR250::MRandomR250(){   setSeed(generateSeed());}MRandomR250::MRandomR250(S32 s){   setSeed(s);}//--------------------------------------void MRandomR250::setSeed(S32 s){   mSeed = s;   MRandomLCG lcg( s );   mIndex = 0;   S32 j;   for (j = 0; j < 250; j++)        // fill r250 buffer with bit values      mBuffer[j] = lcg.randI();   for (j = 0; j < 250; j++)        // set some MSBs to 1      if ( lcg.randI() > 0x40000000L )         mBuffer[j] |= 0x80000000L;   U32 msb  = 0x80000000;           // turn on diagonal bit   U32 mask = 0xffffffff;           // turn off the leftmost bits   for (j = 0; j < 32; j++)   {      S32 k = 7 * j + 3;            // select a word to operate on      mBuffer[k] &= mask;           // turn off bits left of the diagonal      mBuffer[k] |= msb;            // turn on the diagonal bit      mask >>= 1;      msb  >>= 1;   }}//--------------------------------------U32 MRandomR250::randI(){   S32 j;   // wrap pointer around   if ( mIndex >= 147 ) j = mIndex - 147;   else                 j = mIndex + 103;   U32 new_rand = mBuffer[ mIndex ] ^ mBuffer[ j ];   mBuffer[ mIndex ] = new_rand;   // increment pointer for next time   if ( mIndex >= 249 ) mIndex = 0;   else                 mIndex++;   return new_rand >> 1;}
 |