1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2024-11-14 21:40:03 +00:00

[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>
This commit is contained in:
Dragorn421 2024-08-30 14:56:00 +02:00 committed by GitHub
parent dc964931c2
commit 1eeb03e5bb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 48 additions and 1 deletions

View file

@ -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

View file

@ -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

View file

@ -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