diff --git a/src/code/random.cpp b/src/code/random.cpp index 72f58b7d9..af6cfb7bd 100644 --- a/src/code/random.cpp +++ b/src/code/random.cpp @@ -2,6 +2,8 @@ #include "global.h" #include "def/random.h" +#ifdef N64_VERSION + // The latest generated random number, used to generate the next number in the sequence. static u32 sRandInt = 1; @@ -20,6 +22,7 @@ u32 Rand_Next(void) { */ void Rand_Seed(u32 seed) { sRandInt = seed; + } /** @@ -43,35 +46,106 @@ f32 Rand_Centered(void) { return *((f32*)&sRandFloat) - 1.5f; } -/** - * Generates the next pseudo-random integer from the provided rndNum. - */ -u32 Rand_Next_Variable(u32* rndNum) { - return *rndNum = (*rndNum * 1664525) + 1013904223; +#else + +#define M 397 +#define MATRIX_A 0x9908b0df +#define UPPER_MASK 0x80000000 +#define LOWER_MASK 0x7fffffff + +#define TEMPERING_MASK_B 0x9d2c5680 +#define TEMPERING_MASK_C 0xefc60000 +#define TEMPERING_SHIFT_U(y) ((y) >> 11) +#define TEMPERING_SHIFT_S(y) ((y) << 7) +#define TEMPERING_SHIFT_T(y) ((y) << 15) +#define TEMPERING_SHIFT_L(y) ((y) >> 18) + +#define MTRAND_N 624 + + +unsigned short mtRand_xsubi[3]={723, 32761, 44444}; + +unsigned int mt[MTRAND_N]; +int mti; + + +void Rand_Seed(u32 Seed) +{ + mt[0]= Seed & 0xffffffff; + for ( mti = 1; mti < MTRAND_N; mti++ ) mt[mti] = (69069 * mt[mti - 1]) & 0xffffffff; + unsigned int s = 373737; + for ( mti = 1; mti < MTRAND_N; mti++ ) + { + mt[mti] ^= s; + s = s * 5531 + 81547; + s ^= (s >> 9) ^ (s << 19); + } } -/** - * Generates the next pseudo-random floating-point number between 0.0f and - * 1.0f from the provided rndNum. - */ -f32 Rand_ZeroOne_Variable(u32* rndNum) { - u32 next = (*rndNum * 1664525) + 1013904223; - // clang-format off - *rndNum = next; sRandFloat = (next >> 9) | 0x3F800000; - // clang-format on - return *((f32*)&sRandFloat) - 1.0f; +f32 Rand_ZeroOne(void) +{ + unsigned int y; + static const unsigned int mag01[2] = {0x0, MATRIX_A}; + if (mti >= MTRAND_N) + { + int kk; + for (kk=0;kk> 1) ^ mag01[y & 0x1]; + } + for (;kk> 1) ^ mag01[y & 0x1]; + } + y = (mt[MTRAND_N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); + mt[MTRAND_N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1]; + mti = 0; + } + y = mt[mti++]; + y ^= TEMPERING_SHIFT_U(y); + y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B; + y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C; + y ^= TEMPERING_SHIFT_L(y); + return ( (float)y * 2.3283064370807974e-10f ); } -/** - * Generates the next pseudo-random floating-point number between -0.5f and - * 0.5f from the provided rndNum. - */ -f32 Rand_Centered_Variable(u32* rndNum) { - u32 next = (*rndNum * 1664525) + 1013904223; - // clang-format off - *rndNum = next; sRandFloat = (next >> 9) | 0x3F800000; - // clang-format on - return *((f32*)&sRandFloat) - 1.5f; +f32 Rand_Centered(void) { + return Rand_ZeroOne() - 0.5f; } + + +u32 Rand_Next(void) +{ + unsigned int y; + static const unsigned long mag01[2] = { 0x0, MATRIX_A }; + if (mti >= MTRAND_N) + { + int kk; + for (kk=0;kk> 1) ^ mag01[y & 0x1]; + } + for (;kk> 1) ^ mag01[y & 0x1]; + } + y = (mt[MTRAND_N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); + mt[MTRAND_N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1]; + mti = 0; + } + y = mt[mti++]; + y ^= TEMPERING_SHIFT_U(y); + y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B; + y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C; + y ^= TEMPERING_SHIFT_L(y); + return y; +} + + +#endif \ No newline at end of file