mirror of
https://github.com/pmret/papermario.git
synced 2024-11-08 12:02:30 +01:00
Document PRNG Related Functions (#1060)
* document gfx_rand * document global LCG * rename func_80029994 * clarify rand_int_internal comment * gfx_rand -> gfx_rand_int * remove unneeded parens * gfx_rand_int -> effect_rand_int * gfx_prng_seed -> effect_prng_seed * fix local variable case
This commit is contained in:
parent
2e926567e3
commit
f770d12db4
@ -1455,7 +1455,7 @@ typedef struct GameStatus {
|
||||
/* 0x128 */ Vec3f playerGroundTraceNormal;
|
||||
/* 0x134 */ u16 frameCounter;
|
||||
/* 0x136 */ char unk_136[2];
|
||||
/* 0x138 */ s32 nextRNG;
|
||||
/* 0x138 */ u32 nextRNG;
|
||||
/* 0x13C */ s16 unk_13C;
|
||||
/* 0x13E */ char unk_13E[2];
|
||||
/* 0x140 */ ShopItemEntity* shopItemEntities;
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include "effects.h"
|
||||
|
||||
s32 func_E0200000(s32);
|
||||
s32 effect_rand_int(s32);
|
||||
s32 func_E0200044(s32, s32);
|
||||
|
||||
EffectInstance* shim_create_effect_instance(EffectBlueprint* effectBp);
|
||||
|
@ -11,7 +11,7 @@ extern PlayerStatus* gPlayerStatusPtr;
|
||||
extern CollisionStatus gCollisionStatus;
|
||||
extern GameStatus gGameStatus;
|
||||
extern GameStatus* gGameStatusPtr;
|
||||
extern s32 gRandSeed;
|
||||
extern u32 gRandSeed;
|
||||
extern ItemData gItemTable[365];
|
||||
extern UNK_FUN_PTR(gCurrentUpdateFunction);
|
||||
extern MoveData gMoveTable[185];
|
||||
|
14
src/325AD0.c
14
src/325AD0.c
@ -2,7 +2,7 @@
|
||||
#include "effects.h"
|
||||
#include "nu/nusys.h"
|
||||
|
||||
u32 D_E0200690 = 0x1E6D3457;
|
||||
u32 effect_prng_seed = 0x1E6D3457;
|
||||
|
||||
void* effectFuncs[] = {
|
||||
guRotateF, guTranslateF, guTranslate, guScaleF, guMtxCatF, guMtxF2L, guMtxL2F, queue_render_task,
|
||||
@ -33,12 +33,16 @@ s32 D_E0200734[128] = {
|
||||
};
|
||||
|
||||
// very simple 'random' number generator that mutates a single value in memory
|
||||
u32 func_E0200000(s32 max) {
|
||||
s32 temp_v0 = D_E0200690 * 4;
|
||||
// prng implementation is identical to that of guRandom
|
||||
u32 effect_rand_int(s32 max) {
|
||||
u32 seed = (effect_prng_seed << 2) + 2;
|
||||
|
||||
D_E0200690 = (u32)((temp_v0 + 2) * (temp_v0 + 3)) / 4;
|
||||
seed *= (seed + 1);
|
||||
seed = seed >> 2;
|
||||
|
||||
return D_E0200690 % (max + 1);
|
||||
effect_prng_seed = seed;
|
||||
|
||||
return effect_prng_seed % (max + 1);
|
||||
}
|
||||
|
||||
// very simple 'random' number generator using a LUT
|
||||
|
55
src/43F0.c
55
src/43F0.c
@ -25,7 +25,7 @@ u8 sIntegerDigits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
s32 gRandSeed = 1;
|
||||
u32 gRandSeed = 1;
|
||||
|
||||
f32 sAtanFactors[] = {
|
||||
1.0f, 1.273187f, 1.27303f, 1.272768f, 1.272402f, 1.271932f, 1.271358f, 1.270681f, 1.269902f, 1.269021f, 1.268038f,
|
||||
@ -487,53 +487,62 @@ void dma_write_block(Addr dramAddr, u32 devAddr, s32 size) {
|
||||
osRecvMesg(&osMesgQueue, &osMesg, 1);
|
||||
}
|
||||
|
||||
s32 advance_rng(void) {
|
||||
gRandSeed *= 0x5D588B65;
|
||||
gRandSeed++;
|
||||
// advance the global RNG via LCG algorithm and return a random integer [0,2^32)
|
||||
u32 advance_rng(void) {
|
||||
gRandSeed = gRandSeed * 0x5D588B65 + 1;
|
||||
|
||||
gGameStatusPtr->nextRNG = gRandSeed;
|
||||
|
||||
return gRandSeed;
|
||||
}
|
||||
|
||||
// return a random float [0,1)
|
||||
f32 rand_float(void) {
|
||||
u32 temp_v0 = advance_rng() & 0x7FFF;
|
||||
|
||||
return temp_v0 / 32768.0;
|
||||
return (advance_rng() & 0x7FFF) / 32768.0;
|
||||
}
|
||||
|
||||
s32 func_80029994(s32 arg0) {
|
||||
u32 div = -1;
|
||||
s32 plusOne = arg0 + 1;
|
||||
// return a random integer [0,max]
|
||||
s32 rand_int_internal(u32 max) {
|
||||
u32 partitionSize = 0xFFFFFFFF;
|
||||
u32 maxPlusOne = max + 1;
|
||||
u32 result;
|
||||
|
||||
div /= plusOne;
|
||||
if (div == 0) {
|
||||
div = 1;
|
||||
// split [0,2^32) into ``maxPlusOne`` equally sized partitions
|
||||
// [0, partitionSize), [partitionSize, 2*partitionSize), ... [maxPlusOne*partitionSize, 2^32)
|
||||
partitionSize /= maxPlusOne;
|
||||
if (partitionSize == 0) {
|
||||
partitionSize = 1;
|
||||
}
|
||||
|
||||
do {
|
||||
result = advance_rng() / div;
|
||||
} while (result >= plusOne);
|
||||
// numbers in the leftover [maxPlusOne*partitionSize, 2^32) are rejected as they would return maxPlusOne
|
||||
// this ensures the result is [0,max] whilst also ensuring each partition is the same size and equally probable
|
||||
do {
|
||||
// determine which partition the random number is in by dividing it by partitionSize
|
||||
result = advance_rng() / partitionSize;
|
||||
} while (result >= maxPlusOne);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
s32 rand_int(s32 arg0) {
|
||||
// return a random integer [0,|max|] with specific distributions for |max| = 1 and |max| = 100
|
||||
s32 rand_int(s32 max) {
|
||||
s32 ret = 0;
|
||||
|
||||
arg0 = abs(arg0);
|
||||
max = abs(max);
|
||||
|
||||
if (arg0 != 0) {
|
||||
switch (arg0) {
|
||||
if (max != 0) {
|
||||
switch (max) {
|
||||
case 1:
|
||||
ret = func_80029994(1000) > 500;
|
||||
// due to the off-by-one input of 1000 and the > operator being used,
|
||||
// there is a 501/1001 chance of returning 0 and a 500/1001 chance of returning 1
|
||||
// (assuming statistical randomness of rand_int_internal).
|
||||
ret = rand_int_internal(1000) > 500;
|
||||
break;
|
||||
default:
|
||||
ret = func_80029994(arg0);
|
||||
ret = rand_int_internal(max);
|
||||
break;
|
||||
case 100:
|
||||
ret = func_80029994(1009) / 10;
|
||||
ret = rand_int_internal(1009) / 10;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ void big_smoke_puff_main(f32 x, f32 y, f32 z) {
|
||||
|
||||
for (i = 0; i < effect->numParts; i++, data++) {
|
||||
data->unk_00 = 0;
|
||||
data->unk_02 = data->unk_04 = func_E0200000(6) + 0x10;
|
||||
data->unk_02 = data->unk_04 = effect_rand_int(6) + 0x10;
|
||||
data->unk_06 = 4;
|
||||
data->unk_08 = 0;
|
||||
data->x = x;
|
||||
|
@ -46,12 +46,12 @@ void big_snowflakes_main(s32 arg0, f32 arg1, f32 arg2, f32 arg3) {
|
||||
|
||||
data++;
|
||||
for (i = 1; i < numParts; i++, data++) {
|
||||
data->unk_04 = func_E0200000(10) - 5;
|
||||
data->unk_08 = func_E0200000(10) + 5;
|
||||
data->unk_04 = effect_rand_int(10) - 5;
|
||||
data->unk_08 = effect_rand_int(10) + 5;
|
||||
data->unk_0C = 10.0f;
|
||||
data->unk_18 = func_E0200000(360);
|
||||
data->unk_20 = func_E0200000(360);
|
||||
data->unk_1C = func_E0200000(100) / 10;
|
||||
data->unk_18 = effect_rand_int(360);
|
||||
data->unk_20 = effect_rand_int(360);
|
||||
data->unk_1C = effect_rand_int(100) / 10;
|
||||
data->unk_10 = 0;
|
||||
data->unk_14 = 2.0f;
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ void cloud_puff_main(f32 arg0, f32 arg1, f32 arg2, f32 arg3) {
|
||||
part->alpha = 255;
|
||||
part->unk_24 = (shim_rand_int(10) * 0.03) + 1.0;
|
||||
part->unk_28 = (shim_rand_int(10) * 0.03) + 1.7;
|
||||
part->unk_2C = func_E0200000(60);
|
||||
part->unk_2C = effect_rand_int(60);
|
||||
part->timeLeft = 30;
|
||||
part->unk_34 = 0.5f;
|
||||
part->unk_38 = -0.02f;
|
||||
|
@ -46,12 +46,12 @@ void cloud_trail_main(s32 arg0, f32 arg1, f32 arg2, f32 arg3) {
|
||||
part->alpha = -1;
|
||||
part->unk_28 = (shim_rand_int(10) * 0.03) + 1.4;
|
||||
part->unk_2C = (shim_rand_int(10) * 0.03) + 1.5;
|
||||
part->unk_30 = func_E0200000(60);
|
||||
part->unk_30 = effect_rand_int(60);
|
||||
part->unk_04 = arg0;
|
||||
part->lifetime = 15;
|
||||
part->unk_38 = 2.0f;
|
||||
part->unk_3C = -0.5f;
|
||||
part->unk_18 = func_E0200000(360);
|
||||
part->unk_18 = effect_rand_int(360);
|
||||
part->alpha = -1;
|
||||
}
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ EffectInstance* confetti_main(s32 arg0, f32 arg1, f32 arg2, f32 arg3, f32 arg4,
|
||||
temp_fp = shim_rand_int(360);
|
||||
|
||||
for (i = 0; i < np; i++, data++) {
|
||||
temp_f30 = sp28 * (func_E0200000(100) * 0.01f);
|
||||
temp_f30 = sp28 * (effect_rand_int(100) * 0.01f);
|
||||
switch (arg0) {
|
||||
case 0:
|
||||
case 4:
|
||||
|
@ -39,21 +39,21 @@ void drop_leaves_main(s32 arg0, f32 arg1, f32 arg2, f32 arg3, s32 arg4) {
|
||||
part++;
|
||||
for (i = 1; i < numParts; i++, part++) {
|
||||
if (arg0 == 0) {
|
||||
part->unk_04 = func_E0200000(50) - 25;
|
||||
part->unk_08 = func_E0200000(50) - 25;
|
||||
part->unk_04 = effect_rand_int(50) - 25;
|
||||
part->unk_08 = effect_rand_int(50) - 25;
|
||||
part->unk_0C = 0.0f;
|
||||
part->unk_18 = func_E0200000(360);
|
||||
part->unk_20 = func_E0200000(360);
|
||||
part->unk_1C = func_E0200000(100) / 10.0f;
|
||||
part->unk_18 = effect_rand_int(360);
|
||||
part->unk_20 = effect_rand_int(360);
|
||||
part->unk_1C = effect_rand_int(100) / 10.0f;
|
||||
part->unk_10 = 0;
|
||||
part->unk_14 = 0;
|
||||
} else {
|
||||
part->unk_04 = func_E0200000(10) - 5;
|
||||
part->unk_08 = func_E0200000(10) + 5;
|
||||
part->unk_04 = effect_rand_int(10) - 5;
|
||||
part->unk_08 = effect_rand_int(10) + 5;
|
||||
part->unk_0C = 10.0f;
|
||||
part->unk_18 = func_E0200000(360);
|
||||
part->unk_20 = func_E0200000(360);
|
||||
part->unk_1C = func_E0200000(100) / 10.0f;
|
||||
part->unk_18 = effect_rand_int(360);
|
||||
part->unk_20 = effect_rand_int(360);
|
||||
part->unk_1C = effect_rand_int(100) / 10.0f;
|
||||
part->unk_10 = 0;
|
||||
part->unk_14 = 2.0f;
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ void effect_3D_main(s32 arg0, f32 arg1, f32 arg2, f32 arg3, f32 arg4, f32 arg5,
|
||||
part->unk_44 = 0.5f;
|
||||
part->unk_48 = 4.0f;
|
||||
part->unk_50 = 20.0f;
|
||||
part->unk_4C = part->unk_54 = func_E0200000(360);
|
||||
part->unk_4C = part->unk_54 = effect_rand_int(360);
|
||||
part->unk_58 = 255;
|
||||
part->unk_64 = ((i - 1) / 5) * 2;
|
||||
part->unk_5C = 10;
|
||||
|
@ -87,9 +87,9 @@ EffectInstance* effect_46_main(s32 arg0, PlayerStatus* arg1, f32 arg2, s32 arg3)
|
||||
part->unk_08 = 0;
|
||||
part->unk_0C = arg1->colliderHeight * 0.5;
|
||||
part->unk_10 = 0;
|
||||
part->unk_38 = func_E0200000(1) * 8 - 4;
|
||||
part->unk_38 = effect_rand_int(1) * 8 - 4;
|
||||
part->unk_3C = 0;
|
||||
part->unk_40 = func_E0200000(1) * 8 - 4;
|
||||
part->unk_40 = effect_rand_int(1) * 8 - 4;
|
||||
part->unk_2C = i * 25;
|
||||
part->unk_30 = (i - 1) * 360 / (numParts - 1);
|
||||
part->unk_34 = 360 - i * 38;
|
||||
|
@ -63,9 +63,9 @@ EffectInstance* fire_flower_main(s32 arg0, f32 arg1, f32 arg2, f32 arg3, s32 arg
|
||||
part->pos.z = 0;
|
||||
part->unk_14 = 8.0f;
|
||||
part->unk_18 = 0;
|
||||
part->unk_1C = func_E0200000(20) - 8;
|
||||
part->unk_20 = (func_E0200000(10) - 5) * 0.05;
|
||||
part->unk_24 = func_E0200000(80) + 5;
|
||||
part->unk_1C = effect_rand_int(20) - 8;
|
||||
part->unk_20 = (effect_rand_int(10) - 5) * 0.05;
|
||||
part->unk_24 = effect_rand_int(80) + 5;
|
||||
part->unk_3C = 255;
|
||||
partData->z = i - 1;
|
||||
partData->x = 10;
|
||||
|
@ -58,7 +58,7 @@ void gather_energy_pink_main(s32 type, f32 posX, f32 posY, f32 posZ, f32 scale,
|
||||
|
||||
data->unk_1C = 10.0f;
|
||||
|
||||
data->unk_58 = func_E0200000(360);
|
||||
data->unk_58 = effect_rand_int(360);
|
||||
data->unk_5C = 4.0f;
|
||||
|
||||
data->unk_50 = 0;
|
||||
|
@ -14,12 +14,12 @@ Gfx* D_E008AA50[] = { D_09000D50_38DDC0, D_09000D50_38DDC0 };
|
||||
void func_E008A000(SnowfallFXData* data) {
|
||||
Camera* camera = &gCameras[gCurrentCameraID];
|
||||
|
||||
data->unk_08 = (camera->lookAt_eye.x + func_E0200000(2000)) - 1000.0f;
|
||||
data->unk_0C = (camera->lookAt_eye.y + func_E0200000(2000)) - 1000.0f;
|
||||
data->unk_10 = (camera->lookAt_eye.z + func_E0200000(2000)) - 1000.0f;
|
||||
data->unk_14 = (func_E0200000(20) - 10.0f) * 0.05;
|
||||
data->unk_18 = -1.2 - (func_E0200000(80) * 0.01);
|
||||
data->unk_1C = (func_E0200000(20) - 10.0f) * 0.05;
|
||||
data->unk_08 = (camera->lookAt_eye.x + effect_rand_int(2000)) - 1000.0f;
|
||||
data->unk_0C = (camera->lookAt_eye.y + effect_rand_int(2000)) - 1000.0f;
|
||||
data->unk_10 = (camera->lookAt_eye.z + effect_rand_int(2000)) - 1000.0f;
|
||||
data->unk_14 = (effect_rand_int(20) - 10.0f) * 0.05;
|
||||
data->unk_18 = -1.2 - (effect_rand_int(80) * 0.01);
|
||||
data->unk_1C = (effect_rand_int(20) - 10.0f) * 0.05;
|
||||
data->unk_28 = 255;
|
||||
}
|
||||
|
||||
|
@ -41,10 +41,10 @@ void windy_leaves_main(s32 type, f32 arg1, f32 arg2, f32 arg3) {
|
||||
|
||||
part++;
|
||||
for (i = 1; i < numParts; i++, part++) {
|
||||
s32 temp_s0_2 = func_E0200000(50);
|
||||
s32 temp_s1 = func_E0200000(20);
|
||||
s32 temp_s2 = func_E0200000(360);
|
||||
s32 temp_v0_2 = func_E0200000(100);
|
||||
s32 temp_s0_2 = effect_rand_int(50);
|
||||
s32 temp_s1 = effect_rand_int(20);
|
||||
s32 temp_s2 = effect_rand_int(360);
|
||||
s32 temp_v0_2 = effect_rand_int(100);
|
||||
part->unk_04.x = temp_s0_2 + 75;
|
||||
part->unk_04.y = temp_s1 + 70;
|
||||
part->unk_04.z = 0;
|
||||
|
@ -55,7 +55,7 @@ dma_write = 0x800297D4; // type:func rom:0x4BD4
|
||||
dma_write_block = 0x80029860; // type:func rom:0x4C60
|
||||
advance_rng = 0x80029900; // type:func rom:0x4D00
|
||||
rand_float = 0x80029934; // type:func rom:0x4D34
|
||||
func_80029994 = 0x80029994; // type:func rom:0x4D94
|
||||
rand_int_internal = 0x80029994; // type:func rom:0x4D94
|
||||
rand_int = 0x800299FC; // type:func rom:0x4DFC
|
||||
signF = 0x80029A7C; // type:func rom:0x4E7C
|
||||
round = 0x80029AC4; // type:func rom:0x4EC4
|
||||
@ -7953,7 +7953,7 @@ EVS_WorldItem_ShowUsedItem = 0x802C0410; // type:data rom:0x3255E0
|
||||
EVS_WorldItem_PlayEatingSounds = 0x802C04F4; // type:data rom:0x3256C4
|
||||
EVS_WorldItem_PlayDrinkingSounds = 0x802C0560; // type:data rom:0x325730
|
||||
EVS_World_UseItem = 0x802C05CC; // type:data rom:0x32579C
|
||||
func_E0200000 = 0xE0200000; // type:func rom:0x325AD0
|
||||
effect_rand_int = 0xE0200000; // type:func rom:0x325AD0
|
||||
func_E0200044 = 0xE0200044; // type:func rom:0x325B14
|
||||
func_E02000AC = 0xE02000AC; // type:func rom:0x325B7C
|
||||
shim_guRotateF = 0xE0200410; // type:func rom:0x325EE0
|
||||
@ -7996,7 +7996,7 @@ shim_draw_msg = 0xE0200650; // type:func rom:0x326120
|
||||
shim_get_msg_width = 0xE0200660; // type:func rom:0x326130
|
||||
shim_get_background_color_blend = 0xE0200670; // type:func rom:0x326140
|
||||
shim_sfx_play_sound_at_position = 0xE0200680; // type:func rom:0x326150
|
||||
D_E0200690 = 0xE0200690; // type:data rom:0x326160
|
||||
effect_prng_seed = 0xE0200690; // type:data rom:0x326160
|
||||
effectFuncs = 0xE0200694; // type:data rom:0x326164
|
||||
D_E0200734 = 0xE0200734; // type:data rom:0x326204
|
||||
D_09000000_326410 = 0x9000000; // type:data rom:0x326410
|
||||
|
Loading…
Reference in New Issue
Block a user