mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
VstdLib: properly implement CUniformRandomStream
The interface layout and implementation in the SDK was different than that of the engine. This has been changed to maintain ABI compatibility and to ensure the same values are generated.
This commit is contained in:
parent
28bed2517e
commit
f4d8acc918
@ -16,6 +16,7 @@
|
||||
#define IR 2836
|
||||
#define NDIV (1+(IM-1)/NTAB)
|
||||
#define MAX_RANDOM_RANGE 0x7FFFFFFFUL
|
||||
#define MAX_RANDOM_RANGE_SHORT 0x7FFFUL
|
||||
|
||||
// fran1 -- return a random floating-point number on the interval [0,1)
|
||||
//
|
||||
@ -43,27 +44,32 @@ void InstallUniformRandomStream(IUniformRandomStream* pStream)
|
||||
//-----------------------------------------------------------------------------
|
||||
// A couple of convenience functions to access the library's global uniform stream
|
||||
//-----------------------------------------------------------------------------
|
||||
void RandomSeed(int iSeed)
|
||||
void RandomSeed(const int iSeed)
|
||||
{
|
||||
s_pUniformStream->SetSeed(iSeed);
|
||||
}
|
||||
|
||||
float RandomFloat(float flMinVal, float flMaxVal)
|
||||
float RandomFloat(const float flMinVal, const float flMaxVal)
|
||||
{
|
||||
return s_pUniformStream->RandomFloat(flMinVal, flMaxVal);
|
||||
}
|
||||
|
||||
float RandomFloatExp(float flMinVal, float flMaxVal, float flExponent)
|
||||
float RandomFloatExp(const float flMinVal, const float flMaxVal, const float flExponent)
|
||||
{
|
||||
return s_pUniformStream->RandomFloatExp(flMinVal, flMaxVal, flExponent);
|
||||
}
|
||||
|
||||
int RandomInt(int iMinVal, int iMaxVal)
|
||||
int RandomInt(const int iMinVal, const int iMaxVal)
|
||||
{
|
||||
return s_pUniformStream->RandomInt(iMinVal, iMaxVal);
|
||||
}
|
||||
|
||||
float RandomGaussianFloat(float flMean, float flStdDev)
|
||||
int RandomShortMax()
|
||||
{
|
||||
return s_pUniformStream->RandomShortMax();
|
||||
}
|
||||
|
||||
float RandomGaussianFloat(const float flMean, const float flStdDev)
|
||||
{
|
||||
return s_GaussianStream.RandomFloat(flMean, flStdDev);
|
||||
}
|
||||
@ -79,61 +85,37 @@ CUniformRandomStream::CUniformRandomStream()
|
||||
SetSeed(0);
|
||||
}
|
||||
|
||||
void CUniformRandomStream::SetSeed(int iSeed)
|
||||
void CUniformRandomStream::SetSeed(const int iSeed)
|
||||
{
|
||||
std::lock_guard<std::mutex> l(m_mutex);
|
||||
AUTO_LOCK( m_mutex );
|
||||
m_idum = iSeed;
|
||||
}
|
||||
|
||||
m_idum = ((iSeed < 0) ? iSeed : -iSeed);
|
||||
m_iy = 0;
|
||||
int CUniformRandomStream::GetSeed() const
|
||||
{
|
||||
return m_idum;
|
||||
}
|
||||
|
||||
int CUniformRandomStream::GenerateRandomNumber()
|
||||
{
|
||||
std::lock_guard<std::mutex> l(m_mutex);
|
||||
int j;
|
||||
int k;
|
||||
AUTO_LOCK( m_mutex );
|
||||
|
||||
if (m_idum <= 0 || !m_iy)
|
||||
if (m_idum <= 0)
|
||||
{
|
||||
if (-(m_idum) < 1)
|
||||
m_idum = 1;
|
||||
else
|
||||
m_idum = -(m_idum);
|
||||
|
||||
for (j = NTAB + 7; j >= 0; j--)
|
||||
{
|
||||
k = (m_idum) / IQ;
|
||||
}
|
||||
const int k = (m_idum) / IQ;
|
||||
m_idum = IA * (m_idum - k * IQ) - IR * k;
|
||||
if (m_idum < 0)
|
||||
m_idum += IM;
|
||||
if (j < NTAB)
|
||||
m_iv[j] = m_idum;
|
||||
}
|
||||
m_iy = m_iv[0];
|
||||
}
|
||||
k = (m_idum) / IQ;
|
||||
m_idum = IA * (m_idum - k * IQ) - IR * k;
|
||||
if (m_idum < 0)
|
||||
m_idum += IM;
|
||||
j = m_iy / NDIV;
|
||||
|
||||
// We're seeing some strange memory corruption in the contents of s_pUniformStream.
|
||||
// Perhaps it's being caused by something writing past the end of this array?
|
||||
// Bounds-check in release to see if that's the case.
|
||||
if (j >= NTAB || j < 0)
|
||||
{
|
||||
//DebuggerBreakIfDebugging();
|
||||
//Warning(eDLL_T::COMMON, "CUniformRandomStream had an array overrun: tried to write to element %d of 0..31. Contact Tom or Elan.\n", j);
|
||||
j = (j % NTAB) & 0x7fffffff;
|
||||
return m_idum;
|
||||
}
|
||||
|
||||
m_iy = m_iv[j];
|
||||
m_iv[j] = m_idum;
|
||||
|
||||
return m_iy;
|
||||
}
|
||||
|
||||
float CUniformRandomStream::RandomFloat(float flLow, float flHigh)
|
||||
float CUniformRandomStream::RandomFloat(const float flLow, const float flHigh)
|
||||
{
|
||||
// float in [0,1)
|
||||
float fl = float(AM) * GenerateRandomNumber();
|
||||
@ -144,7 +126,7 @@ float CUniformRandomStream::RandomFloat(float flLow, float flHigh)
|
||||
return (fl * (flHigh - flLow)) + flLow; // float in [low,high)
|
||||
}
|
||||
|
||||
float CUniformRandomStream::RandomFloatExp(float flMinVal, float flMaxVal, float flExponent)
|
||||
float CUniformRandomStream::RandomFloatExp(const float flMinVal, const float flMaxVal, const float flExponent)
|
||||
{
|
||||
// float in [0,1)
|
||||
float fl = float(AM) * GenerateRandomNumber();
|
||||
@ -159,9 +141,10 @@ float CUniformRandomStream::RandomFloatExp(float flMinVal, float flMaxVal, float
|
||||
return (fl * (flMaxVal - flMinVal)) + flMinVal; // float in [low,high)
|
||||
}
|
||||
|
||||
int CUniformRandomStream::RandomInt(int iLow, int iHigh)
|
||||
int CUniformRandomStream::RandomInt(const int iLow, const int iHigh)
|
||||
{
|
||||
//ASSERT(lLow <= lHigh);
|
||||
Assert(lLow <= lHigh);
|
||||
|
||||
unsigned int maxAcceptable;
|
||||
unsigned int x = iHigh - iLow + 1;
|
||||
unsigned int n;
|
||||
@ -187,6 +170,11 @@ int CUniformRandomStream::RandomInt(int iLow, int iHigh)
|
||||
return iLow + (n % x);
|
||||
}
|
||||
|
||||
int CUniformRandomStream::RandomShortMax()
|
||||
{
|
||||
return RandomInt(0, MAX_RANDOM_RANGE_SHORT);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
|
@ -23,12 +23,16 @@ class IUniformRandomStream
|
||||
{
|
||||
public:
|
||||
// Sets the seed of the random number generator
|
||||
virtual void SetSeed(int iSeed) = 0;
|
||||
virtual void SetSeed(const int iSeed) = 0;
|
||||
virtual int GetSeed() const = 0;
|
||||
|
||||
// Generates random numbers
|
||||
virtual float RandomFloat(float flMinVal = 0.0f, float flMaxVal = 1.0f) = 0;
|
||||
virtual int RandomInt(int iMinVal, int iMaxVal) = 0;
|
||||
virtual float RandomFloatExp(float flMinVal = 0.0f, float flMaxVal = 1.0f, float flExponent = 1.0f) = 0;
|
||||
virtual float RandomFloat(const float flMinVal = 0.0f, const float flMaxVal = 1.0f) = 0;
|
||||
virtual int RandomInt(const int iMinVal, const int iMaxVal) = 0;
|
||||
virtual float RandomFloatExp(const float flMinVal = 0.0f, const float flMaxVal = 1.0f, const float flExponent = 1.0f) = 0;
|
||||
virtual int RandomShortMax() = 0;
|
||||
|
||||
virtual ~IUniformRandomStream() {};
|
||||
};
|
||||
|
||||
|
||||
@ -41,21 +45,22 @@ public:
|
||||
CUniformRandomStream();
|
||||
|
||||
// Sets the seed of the random number generator
|
||||
virtual void SetSeed(int iSeed);
|
||||
virtual void SetSeed(const int iSeed);
|
||||
virtual int GetSeed() const;
|
||||
|
||||
// Generates random numbers
|
||||
virtual float RandomFloat(float flMinVal = 0.0f, float flMaxVal = 1.0f);
|
||||
virtual int RandomInt(int iMinVal, int iMaxVal);
|
||||
virtual float RandomFloatExp(float flMinVal = 0.0f, float flMaxVal = 1.0f, float flExponent = 1.0f);
|
||||
virtual float RandomFloat(const float flMinVal = 0.0f, const float flMaxVal = 1.0f);
|
||||
virtual int RandomInt(const int iMinVal, const int iMaxVal);
|
||||
virtual float RandomFloatExp(const float flMinVal = 0.0f, const float flMaxVal = 1.0f, const float flExponent = 1.0f);
|
||||
virtual int RandomShortMax();
|
||||
|
||||
virtual ~CUniformRandomStream() {};
|
||||
|
||||
private:
|
||||
int GenerateRandomNumber();
|
||||
|
||||
int m_idum;
|
||||
int m_iy;
|
||||
int m_iv[NTAB];
|
||||
|
||||
std::mutex m_mutex;
|
||||
CThreadMutex m_mutex;
|
||||
};
|
||||
|
||||
|
||||
@ -87,11 +92,12 @@ private:
|
||||
//-----------------------------------------------------------------------------
|
||||
// A couple of convenience functions to access the library's global uniform stream
|
||||
//-----------------------------------------------------------------------------
|
||||
void RandomSeed(int iSeed);
|
||||
float RandomFloat(float flMinVal = 0.0f, float flMaxVal = 1.0f);
|
||||
float RandomFloatExp(float flMinVal = 0.0f, float flMaxVal = 1.0f, float flExponent = 1.0f);
|
||||
int RandomInt(int iMinVal, int iMaxVal);
|
||||
float RandomGaussianFloat(float flMean = 0.0f, float flStdDev = 1.0f);
|
||||
void RandomSeed(const int iSeed);
|
||||
float RandomFloat(const float flMinVal = 0.0f, const float flMaxVal = 1.0f);
|
||||
float RandomFloatExp(const float flMinVal = 0.0f, const float flMaxVal = 1.0f, const float flExponent = 1.0f);
|
||||
int RandomInt(const int iMinVal, const int iMaxVal);
|
||||
int RandomShortMax();
|
||||
float RandomGaussianFloat(const float flMean = 0.0f, const float flStdDev = 1.0f);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
Loading…
x
Reference in New Issue
Block a user