2026-01-11 11:49:12 -05:00
|
|
|
#include "Common/CRandom.h"
|
2019-02-02 17:30:36 -07:00
|
|
|
#include <ctime>
|
2026-01-11 11:49:12 -05:00
|
|
|
#include <utility>
|
2019-02-02 17:30:36 -07:00
|
|
|
|
|
|
|
|
/** Advance the generator and retrieve a new random number */
|
2026-01-11 11:44:26 -05:00
|
|
|
int32_t CRandom::Int32()
|
2019-02-02 17:30:36 -07:00
|
|
|
{
|
2026-01-11 11:44:26 -05:00
|
|
|
static constexpr uint32_t kMul = 0x41C64E6D;
|
|
|
|
|
static constexpr uint32_t kInc = 12345;
|
2019-02-02 17:30:36 -07:00
|
|
|
|
|
|
|
|
mSeed = (mSeed * kMul) + kInc;
|
|
|
|
|
return mSeed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Generate a random 16-bit int */
|
2026-01-11 11:44:26 -05:00
|
|
|
int16_t CRandom::Int16()
|
2019-02-02 17:30:36 -07:00
|
|
|
{
|
|
|
|
|
// This function matches the output of Metroid Prime's Next()
|
2026-01-11 11:44:26 -05:00
|
|
|
return int16_t(Int32() >> 16);
|
2019-02-02 17:30:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Generate a random 64-bit int */
|
2026-01-11 11:44:26 -05:00
|
|
|
int64_t CRandom::Int64()
|
2019-02-02 17:30:36 -07:00
|
|
|
{
|
2026-01-11 11:44:26 -05:00
|
|
|
return (int64_t(Int32()) << 32) | int64_t(Int32());
|
2019-02-02 17:30:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Generate a random float between 0 and 1 */
|
|
|
|
|
float CRandom::Float()
|
|
|
|
|
{
|
|
|
|
|
return Int16() / (1.0f / 65535.0f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Generate a random number within the given range */
|
2026-01-11 11:44:26 -05:00
|
|
|
int32_t CRandom::Range(int32_t Min, int32_t Max)
|
2019-02-02 17:30:36 -07:00
|
|
|
{
|
2026-01-11 11:44:26 -05:00
|
|
|
const int32_t Range = Max - Min;
|
|
|
|
|
const int32_t Value = Int32() % (Range + 1);
|
2019-02-02 17:30:36 -07:00
|
|
|
return Min + Value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float CRandom::Range(float Min, float Max)
|
|
|
|
|
{
|
2026-01-11 11:44:26 -05:00
|
|
|
const float Range = Max - Min;
|
2019-02-02 17:30:36 -07:00
|
|
|
return Min + Float()*Range;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Default global random seeded with the current time */
|
2026-01-11 11:49:12 -05:00
|
|
|
static CRandom gpGlobalRandom;
|
2019-02-02 17:30:36 -07:00
|
|
|
|
|
|
|
|
/** Get/set global random */
|
2026-01-11 11:49:12 -05:00
|
|
|
CRandom& CRandom::GlobalRandom()
|
2019-02-02 17:30:36 -07:00
|
|
|
{
|
|
|
|
|
return gpGlobalRandom;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-11 11:49:12 -05:00
|
|
|
CGlobalRandomContext::CGlobalRandomContext(const CRandom& InRandom)
|
|
|
|
|
: mPrevRandom{std::exchange(gpGlobalRandom, InRandom)}
|
2019-02-02 17:30:36 -07:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CGlobalRandomContext::~CGlobalRandomContext()
|
|
|
|
|
{
|
2026-01-11 11:49:12 -05:00
|
|
|
gpGlobalRandom = mPrevRandom;
|
2019-02-02 17:30:36 -07:00
|
|
|
}
|