From 1eeb03e5bb1c7b29b2f6148b0bc51aa712863610 Mon Sep 17 00:00:00 2001 From: Dragorn421 Date: Fri, 30 Aug 2024 14:56:00 +0200 Subject: [PATCH] [ntsc-1.2] Match rand.c (#2097) * [ntsc-1.2] Match rand.c * Comment on N64 Rand_ZeroOne taking the low random bits Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> --------- Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> --- include/rand.h | 6 +++++- include/versions.h | 8 ++++++++ src/code/rand.c | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/include/rand.h b/include/rand.h index 508c9d6466..a1a6a7c165 100644 --- a/include/rand.h +++ b/include/rand.h @@ -2,14 +2,18 @@ #define RAND_H #include "ultra64.h" +#include "versions.h" u32 Rand_Next(void); void Rand_Seed(u32 seed); f32 Rand_ZeroOne(void); -f32 Rand_Centered(void); void Rand_Seed_Variable(u32* rndNum, u32 seed); u32 Rand_Next_Variable(u32* rndNum); f32 Rand_ZeroOne_Variable(u32* rndNum); + +#if RAND_VERSION == RAND_GC +f32 Rand_Centered(void); f32 Rand_Centered_Variable(u32* rndNum); +#endif #endif diff --git a/include/versions.h b/include/versions.h index a000cf0bcd..1112ac01f7 100644 --- a/include/versions.h +++ b/include/versions.h @@ -24,4 +24,12 @@ #define FAULT_VERSION FAULT_GC #endif +#define RAND_N64 1 // in OoT N64 +#define RAND_GC 2 // in OoT GC +#if PLATFORM_N64 +#define RAND_VERSION RAND_N64 +#else +#define RAND_VERSION RAND_GC +#endif + #endif diff --git a/src/code/rand.c b/src/code/rand.c index baf3965421..ce2beb9e30 100644 --- a/src/code/rand.c +++ b/src/code/rand.c @@ -42,6 +42,7 @@ * @note Original name: qrand.c */ #include "rand.h" +#include "versions.h" #define RAND_MULTIPLIER 1664525 #define RAND_INCREMENT 1013904223 @@ -53,12 +54,14 @@ */ static u32 sRandInt = 1; +#if RAND_VERSION == RAND_GC /** * Space to store a value to be re-interpreted as a float. * * @note Orignal name: __qrand_itemp */ static fu sRandFloat; +#endif /** * Gets the next integer in the sequence of pseudo-random numbers. @@ -66,7 +69,14 @@ static fu sRandFloat; * @note Original name: qrand */ u32 Rand_Next(void) { +#if RAND_VERSION == RAND_N64 + u32 next = sRandInt * RAND_MULTIPLIER + RAND_INCREMENT; + + sRandInt = next; + return next; +#else return sRandInt = sRandInt * RAND_MULTIPLIER + RAND_INCREMENT; +#endif } /** @@ -88,12 +98,24 @@ void Rand_Seed(u32 seed) { * @note Original name: fqrand */ f32 Rand_ZeroOne(void) { +#if RAND_VERSION == RAND_N64 + fu v; + f32 vf; + + // Note this samples the lower 23 bits, effectively reducing the LCG period from 2^32 to 2^23. + // This was fixed in Gamecube versions and Majora's Mask. + v.i = (Rand_Next() & 0x007FFFFF) | 0x3F800000; + vf = v.f - 1.0f; + return vf; +#else sRandInt = sRandInt * RAND_MULTIPLIER + RAND_INCREMENT; // Samples the upper 23 bits to avoid effectively reducing the LCG period. sRandFloat.i = (sRandInt >> 9) | 0x3F800000; return sRandFloat.f - 1.0f; +#endif } +#if RAND_VERSION == RAND_GC /** * Returns a pseudo-random floating-point number between -0.5f and 0.5f by the same manner in which Rand_ZeroOne * generates its result. @@ -107,6 +129,7 @@ f32 Rand_Centered(void) { sRandFloat.i = (sRandInt >> 9) | 0x3F800000; return sRandFloat.f - 1.5f; } +#endif //! All functions below are unused variants of the above four, that use a provided random number variable instead of the //! internal `sRandInt` @@ -141,12 +164,23 @@ u32 Rand_Next_Variable(u32* rndNum) { * @note Original name: fqrand_r */ f32 Rand_ZeroOne_Variable(u32* rndNum) { +#if RAND_VERSION == RAND_N64 + fu v; + f32 vf; + u32 next = Rand_Next_Variable(rndNum); + + v.i = (next & 0x007FFFFF) | 0x3F800000; + vf = v.f - 1.0f; + return vf; +#else u32 next = (*rndNum) * RAND_MULTIPLIER + RAND_INCREMENT; sRandFloat.i = ((*rndNum = next) >> 9) | 0x3F800000; return sRandFloat.f - 1.0f; +#endif } +#if RAND_VERSION == RAND_GC /** * Generates the next pseudo-random floating-point number between -0.5f and 0.5f from the provided rndNum. * @@ -160,3 +194,4 @@ f32 Rand_Centered_Variable(u32* rndNum) { sRandFloat.i = ((*rndNum = next) >> 9) | 0x3F800000; return sRandFloat.f - 1.5f; } +#endif