Skip to content

Commit 7164a6f

Browse files
committed
RNG decompiled
1 parent cc0b7fb commit 7164a6f

File tree

9 files changed

+186
-37
lines changed

9 files changed

+186
-37
lines changed

config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
"name": "ctr-u.bin",
7373
"symbols":
7474
[
75-
"gcc-syms-rewrite.txt"
75+
"gcc-syms-rewrite.txt", "gcc-extern-rewrite.txt"
7676
],
7777
"build_id": 9999
7878
}

include/ctr/nd.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include <ctr/macros.h>
55
#include <ctr/math.h>
6+
#include <ctr/rng.h>
67

78
void ND_LOAD_XnfFile(char* filename, u32 address, char* dummy);
89
s32 ND_SquareRoot0_stub(s32 n);
@@ -19,4 +20,10 @@ void ND_MATH_VectorNormalize(SVec3* vector);
1920
void ND_MATH_CombineMatrixTransformation(Matrix* out, const Matrix* m, const Matrix* n);
2021
void ND_MATH_MatrixMultiplication(Matrix* out, const Matrix* m, const Matrix* n);
2122

23+
/* RNG */
24+
u32 ND_RNG_Rand();
25+
s32 ND_RNG_RandInt(u32 n);
26+
u16 ND_RNG_PseudoRand(u16 n);
27+
u32 ND_RNG_Random(RNGSeed* seed);
28+
2229
#endif

include/ctr/rng.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#ifndef RAND_H
2+
#define RAND_H
3+
4+
#include <ctr/macros.h>
5+
6+
typedef struct RNGSeed
7+
{
8+
u32 a;
9+
u32 b;
10+
} RNGSeed;
11+
12+
u32 RNG_Rand();
13+
s32 RNG_RandInt(u32 n);
14+
u16 RNG_PseudoRand(u16 n);
15+
u32 RNG_Random(RNGSeed* seed);
16+
17+
extern u32 e_seed; // 0x8008d424
18+
extern RNGSeed e_gameTrackerSeed; // 0x8009904c
19+
20+
#endif

include/ctr/test.h

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,16 @@
22
#define TEST_H
33

44
#include <ctr/macros.h>
5-
#include <ctr/math.h>
65
#include <ctr/redux.h>
6+
#include <ctr/math.h>
7+
#include <ctr/rng.h>
78

89
void LoadTestPatches();
910

11+
#define BACKUP_ADDR 0x80400000
12+
1013
#define TEST_MATH_IMPL
14+
#define TEST_RNG_IMPL
1115

1216
#ifdef TEST_MATH_IMPL
1317
void TEST_MATH_Sin(u32 angle, s32 res);
@@ -29,4 +33,20 @@ void LoadTestPatches();
2933
#define TEST_MATH_MatrixMultiplication(m, n, res)
3034
#endif
3135

36+
#ifdef TEST_RNG_IMPL
37+
void BACKUP_RNG_Rand();
38+
void TEST_RNG_Rand();
39+
void BACKUP_RNG_RandInt();
40+
void TEST_RNG_RandInt(u32 n, s32 ret);
41+
void TEST_RNG_PseudoRand(u16 n, u16 ret);
42+
void TEST_RNG_Random(RNGSeed* seed, const RNGSeed* ret);
43+
#else
44+
#define BACKUP_RNG_Rand()
45+
#define TEST_RNG_Rand()
46+
#define BACKUP_RNG_RandInt()
47+
#define TEST_RNG_RandInt(n, ret)
48+
#define TEST_RNG_PseudoRand(n, ret)
49+
#define TEST_RNG_Random(seed, ret)
50+
#endif
51+
3252
#endif

rewrite/buildList.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ common, exe, 0x8003c63c, 0x0, src/hooks/dll/hook.s
33
common, header, 0x8000B0B8, 0x0, src/hooks/dll/load_decomp.c
44

55
// decomp files
6-
common, DLL, 0x80200000, 0x0, src/math.c src/prim.c, DECOMP.BIN
6+
common, DLL, 0x80200000, 0x0, src/math.c src/rng.c src/prim.c, DECOMP.BIN
77
common, DLL, 0x80600000, 0x0, src/tests/test.c, TESTS.BIN

rewrite/src/rng.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#include <ctr/rng.h>
2+
#include <ctr/math.h>
3+
#include <ctr/test.h>
4+
5+
#define RNG_MULT_FACTOR 0x6255
6+
#define RNG_INC_FACTOR 0x3619
7+
8+
/* Address: 0x8003ea28 */
9+
u32 RNG_Rand()
10+
{
11+
BACKUP_RNG_Rand();
12+
e_seed = (e_seed * RNG_MULT_FACTOR + RNG_INC_FACTOR) & 0xFFFF;
13+
TEST_RNG_Rand();
14+
return e_seed;
15+
}
16+
17+
/* Address: 0x8003ea6c */
18+
s32 RNG_RandInt(u32 n)
19+
{
20+
BACKUP_RNG_RandInt();
21+
const u32 rand = RNG_Random(&e_gameTrackerSeed);
22+
const s32 ret = ((s32) ((rand & 0xFFFF) * n)) >> 16;
23+
TEST_RNG_RandInt(n, ret);
24+
return ret;
25+
}
26+
27+
/* Address: 0x8003eaac */
28+
u16 RNG_PseudoRand(u16 n)
29+
{
30+
const u16 ret = n * RNG_MULT_FACTOR + RNG_INC_FACTOR;
31+
TEST_RNG_PseudoRand(n, ret);
32+
return ret;
33+
}
34+
35+
/* Address: 0x8006c684 */
36+
u32 RNG_Random(RNGSeed* seed)
37+
{
38+
#ifdef TEST_RNG_IMPL
39+
RNGSeed inputSeed = *seed;
40+
#endif
41+
const u32 x = seed->b >> 8;
42+
const u32 nextA = (seed->a >> 8) | (seed->b << 24);
43+
seed->b = (x | ((seed->a + x + (nextA >> 8)) << 24)) ^ 0xDEADC0ED;
44+
seed->a = nextA;
45+
TEST_RNG_Random(&inputSeed, seed);
46+
return seed->b;
47+
}

rewrite/src/tests/test.c

Lines changed: 83 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ FunctionPatch s_functions[] =
2626
TEST_FUNC(MATH_VectorNormalize),
2727
TEST_FUNC(MATH_CombineMatrixTransformation),
2828
TEST_FUNC(MATH_MatrixMultiplication),
29+
TEST_FUNC(RNG_Rand),
30+
TEST_FUNC(RNG_RandInt),
31+
TEST_FUNC(RNG_PseudoRand),
32+
TEST_FUNC(RNG_Random),
2933
};
3034

3135
void LoadTestPatches()
@@ -65,108 +69,162 @@ static u32 PatchFunction_End(u32 index)
6569
*(s_functions[index].address + 1) = s_functions[index].secondNewInst;
6670
}
6771

68-
static u32 PrintSVectorDiff(const char* name, const SVec3* expected, const SVec3* res)
72+
static u32 PrintSVectorDiff(const char* name, const SVec3* expected, const SVec3* ret)
6973
{
7074
u32 failed = 0;
7175
for (u32 i = 0; i < 3; i++)
7276
{
73-
if (expected->v[i] != res->v[i])
77+
if (expected->v[i] != ret->v[i])
7478
{
7579
failed = 1;
76-
ND_printf("[%s] Test Failed:\nv[%d] = %d, got %d\n", name, i, expected->v[i], res->v[i]);
80+
ND_printf("[%s] Test Failed:\nv[%d] = %d, got %d\n", name, i, expected->v[i], ret->v[i]);
7781
}
7882
}
7983
return failed;
8084
}
8185

82-
static u32 PrintMatrixDiff(const char* name, const Matrix* expected, const Matrix* res, u32 cmpTrans)
86+
static u32 PrintMatrixDiff(const char* name, const Matrix* expected, const Matrix* ret, u32 cmpTrans)
8387
{
8488
u32 failed = 0;
8589
for (u32 i = 0; i < 3; i++)
8690
{
8791
for (u32 j = 0; j < 3; j++)
8892
{
89-
if (expected->m[i][j] != res->m[i][j])
93+
if (expected->m[i][j] != ret->m[i][j])
9094
{
9195
failed = 1;
92-
ND_printf("[%s] Test Failed:\nm[%d][%d] = %d, got %d\n", name, i, j, expected->m[i][j], res->m[i][j]);
96+
ND_printf("[%s] Test Failed:\nm[%d][%d] = %d, got %d\n", name, i, j, expected->m[i][j], ret->m[i][j]);
9397
}
9498
}
95-
if ((cmpTrans) && (expected->t.v[i] != res->t.v[i]))
99+
if ((cmpTrans) && (expected->t.v[i] != ret->t.v[i]))
96100
{
97101
failed = 1;
98-
ND_printf("[%s] Test Failed:\nt[%d] = %d, got %d\n", name, i, expected->t.v[i], res->t.v[i]);
102+
ND_printf("[%s] Test Failed:\nt[%d] = %d, got %d\n", name, i, expected->t.v[i], ret->t.v[i]);
99103
}
100104
}
101105
return failed;
102106
}
103107

104108
#ifdef TEST_MATH_IMPL
105-
void TEST_MATH_Sin(u32 angle, s32 res)
109+
110+
void TEST_MATH_Sin(u32 angle, s32 ret)
106111
{
107112
const u32 index = PatchFunction_Beg((u32*)(&ND_MATH_Sin));
108113
const s32 expected = ND_MATH_Sin(angle);
109-
if (expected != res) { ND_printf("[MATH_Sin] Test Failed:\nInput: %d\nExpected: %d\nResult :%d\n", angle, expected, res); }
114+
if (expected != ret) { ND_printf("[MATH_Sin] Test Failed:\nInput: %d\nExpected: %d\nResult:%d\n", angle, expected, ret); }
110115
PatchFunction_End(index);
111116
}
112117

113-
void TEST_MATH_Cos(u32 angle, s32 res)
118+
void TEST_MATH_Cos(u32 angle, s32 ret)
114119
{
115120
const u32 index = PatchFunction_Beg((u32*)(&ND_MATH_Cos));
116121
const s32 expected = ND_MATH_Cos(angle);
117-
if (expected != res) { ND_printf("[MATH_Cos] Test Failed:\nInput: %d\nExpected: %d\nResult :%d\n", angle, expected, res); }
122+
if (expected != ret) { ND_printf("[MATH_Cos] Test Failed:\nInput: %d\nExpected: %d\nResult:%d\n", angle, expected, ret); }
118123
PatchFunction_End(index);
119124
}
120125

121-
void TEST_MATH_Sqrt(u32 n, u32 shift, u32 res)
126+
void TEST_MATH_Sqrt(u32 n, u32 shift, u32 ret)
122127
{
123128
const u32 index = PatchFunction_Beg((u32*)(&ND_MATH_Sqrt));
124129
const u32 expected = ND_MATH_Sqrt(n, shift);
125-
if (expected != res) { ND_printf("[MATH_Sqrt] Test Failed:\nInput: %d %d\nExpected: %d\nResult :%d\n", n, shift, expected, res); }
130+
if (expected != ret) { ND_printf("[MATH_Sqrt] Test Failed:\nInput: %d %d\nExpected: %d\nResult:%d\n", n, shift, expected, ret); }
126131
PatchFunction_End(index);
127132
}
128133

129-
void TEST_MATH_GetInverseMatrixTransformation(const Matrix* matrix, const Matrix* res)
134+
void TEST_MATH_GetInverseMatrixTransformation(const Matrix* matrix, const Matrix* ret)
130135
{
131136
Matrix out;
132137
const u32 index = PatchFunction_Beg((u32*)(&ND_MATH_GetInverseMatrixTransformation));
133138
ND_MATH_GetInverseMatrixTransformation(&out, matrix);
134-
PrintMatrixDiff("MATH_GetInverseMatrixTransformation", &out, res, true);
139+
PrintMatrixDiff("MATH_GetInverseMatrixTransformation", &out, ret, true);
135140
PatchFunction_End(index);
136141
}
137142

138-
void TEST_MATH_VectorLength(const SVec3* vector, s32 res)
143+
void TEST_MATH_VectorLength(const SVec3* vector, s32 ret)
139144
{
140145
const u32 index = PatchFunction_Beg((u32*)(&ND_MATH_VectorLength));
141146
const s32 expected = ND_MATH_VectorLength(vector);
142-
if (expected != res) { ND_printf("[MATH_VectorLength] Test Failed:\nInput: %d %d %d\nExpected: %d\nResult :%d\n", vector->x, vector->y, vector->z, expected, res); }
147+
if (expected != ret) { ND_printf("[MATH_VectorLength] Test Failed:\nInput: %d %d %d\nExpected: %d\nResult:%d\n", vector->x, vector->y, vector->z, expected, ret); }
143148
PatchFunction_End(index);
144149
}
145150

146-
void TEST_MATH_VectorNormalize(SVec3* vector, const SVec3* res)
151+
void TEST_MATH_VectorNormalize(SVec3* vector, const SVec3* ret)
147152
{
148153
const u32 index = PatchFunction_Beg((u32*)(&ND_MATH_VectorNormalize));
149154
ND_MATH_VectorNormalize(vector);
150-
PrintSVectorDiff("MATH_VectorNormalize", vector, res);
155+
PrintSVectorDiff("MATH_VectorNormalize", vector, ret);
151156
PatchFunction_End(index);
152157
}
153158

154-
void TEST_MATH_CombineMatrixTransformation(const Matrix* m, const Matrix* n, const Matrix* res)
159+
void TEST_MATH_CombineMatrixTransformation(const Matrix* m, const Matrix* n, const Matrix* ret)
155160
{
156161
Matrix expected;
157162
const u32 index = PatchFunction_Beg((u32*)(&ND_MATH_CombineMatrixTransformation));
158163
ND_MATH_CombineMatrixTransformation(&expected, m, n);
159-
PrintMatrixDiff("MATH_CombineMatrixTransformation", &expected, res, true);
164+
PrintMatrixDiff("MATH_CombineMatrixTransformation", &expected, ret, true);
160165
PatchFunction_End(index);
161166
}
162167

163-
void TEST_MATH_MatrixMultiplication(const Matrix* m, const Matrix* n, const Matrix* res)
168+
void TEST_MATH_MatrixMultiplication(const Matrix* m, const Matrix* n, const Matrix* ret)
164169
{
165170
Matrix expected;
166171
const u32 index = PatchFunction_Beg((u32*)(&ND_MATH_MatrixMultiplication));
167172
ND_MATH_MatrixMultiplication(&expected, m, n);
168-
PrintMatrixDiff("MATH_MatrixMultiplication", &expected, res, false);
173+
PrintMatrixDiff("MATH_MatrixMultiplication", &expected, ret, false);
174+
PatchFunction_End(index);
175+
}
176+
177+
#endif // TEST_MATH_IMPL
178+
179+
#ifdef TEST_RNG_IMPL
180+
181+
void BACKUP_RNG_Rand()
182+
{
183+
u32* seedAddr = (u32*) BACKUP_ADDR;
184+
*seedAddr = e_seed;
185+
}
186+
187+
void TEST_RNG_Rand()
188+
{
189+
const u32 index = PatchFunction_Beg((u32*)(&ND_RNG_Rand));
190+
const u32 ret = e_seed;
191+
e_seed = *(u32*) BACKUP_ADDR;
192+
ND_RNG_Rand();
193+
if (e_seed != ret) { ND_printf("[RNG_Rand] Test Failed:\nExpected: %d\nResult: %d\n", e_seed, ret); }
194+
PatchFunction_End(index);
195+
}
196+
197+
void BACKUP_RNG_RandInt()
198+
{
199+
RNGSeed* seedAddr = (RNGSeed*) BACKUP_ADDR;
200+
*seedAddr = e_gameTrackerSeed;
201+
}
202+
203+
void TEST_RNG_RandInt(u32 n, s32 ret)
204+
{
205+
const u32 index = PatchFunction_Beg((u32*)(&ND_RNG_RandInt));
206+
e_gameTrackerSeed = *(RNGSeed*) BACKUP_ADDR;
207+
const s32 expected = ND_RNG_RandInt(n);
208+
if (expected != ret) { ND_printf("[RNG_RandInt] Test Failed:\nExpected: %d\nResult: %d\n", expected, ret); }
209+
PatchFunction_End(index);
210+
}
211+
212+
void TEST_RNG_PseudoRand(u16 n, u16 ret)
213+
{
214+
const u32 index = PatchFunction_Beg((u32*)(&ND_RNG_PseudoRand));
215+
const u16 expected = ND_RNG_PseudoRand(n);
216+
if (expected != ret) { ND_printf("[RNG_PseudoRand] Test Failed:\nExpected: %d\nResult: %d\n", expected, ret); }
217+
PatchFunction_End(index);
218+
}
219+
220+
void TEST_RNG_Random(RNGSeed* seed, const RNGSeed* ret)
221+
{
222+
const u32 index = PatchFunction_Beg((u32*)(&ND_RNG_Random));
223+
const u32 expected = ND_RNG_Random(seed);
224+
if (seed->a != ret->a) { ND_printf("[RNG_Random] Test Failed:\nseed->a: %d\nret->a: %d\n", seed->a, ret->a); }
225+
if (seed->b != ret->b) { ND_printf("[RNG_Random] Test Failed:\nseed->b: %d\nret->b: %d\n", seed->b, ret->b); }
226+
if (expected != ret->b) { ND_printf("[RNG_Random] Test Failed:\nExpected: %d\nret: %d\n", expected, ret->b); }
169227
PatchFunction_End(index);
170228
}
171229

172-
#endif // TEST_MATH_IMPL
230+
#endif // TEST_RNG_IMPL

symbols/gcc-extern-rewrite.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
e_seed = 0x8008d424;
2+
e_gameTrackerSeed = 0x8009904c;

symbols/gcc-syms-rewrite.txt

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
ND_rdata = 0x80010000;
2-
ND_rdata_free = 0x800100cc;
31
ND_BOTS_SetGlobalNavData = 0x800123e0;
42
ND_BOTS_InitNavPath = 0x80012440;
53
ND_BOTS_EmptyFunc = 0x80012560;
@@ -475,9 +473,9 @@ ND_MEMPACK_PushState = 0x8003e978;
475473
ND_MEMPACK_ClearLowMem = 0x8003e9b8;
476474
ND_MEMPACK_PopState = 0x8003e9d0;
477475
ND_MEMPACK_PopToState = 0x8003ea08;
478-
ND_MixRNG_Scramble = 0x8003ea28;
479-
ND_MixRNG_Particles = 0x8003ea6c;
480-
ND_MixRNG_GetValue = 0x8003eaac;
476+
ND_RNG_Rand = 0x8003ea28;
477+
ND_RNG_RandInt = 0x8003ea6c;
478+
ND_RNG_PseudoRand = 0x8003eaac;
481479
ND_Particle_FuncPtr_PotionShatter = 0x8003eae0;
482480
ND_Particle_FuncPtr_SpitTire = 0x8003ec18;
483481
ND_Particle_FuncPtr_ExhaustUnderwater = 0x8003ee20;
@@ -823,7 +821,7 @@ ND_ConvertRotToMatrix_Transpose = 0x8006c378;
823821
ND_MATH_MatrixMultiplication = 0x8006c3b0;
824822
ND_TRIG_AngleSinCos_r16r17r18_duplicate = 0x8006c430;
825823
ND_SquareRoot0_stub = 0x8006c618;
826-
ND_RngDeadCoed = 0x8006c684;
824+
ND_RNG_Random = 0x8006c684;
827825
ND_ApplyMatrixLV_stub = 0x8006c6f0;
828826
ND_Draw_KartGhost = 0x8006c984;
829827
ND_Draw_KartBodyReflection = 0x8006c9c4;
@@ -1054,9 +1052,6 @@ ND__SpuDataCallback = 0x80080940;
10541052
ND_bzero = 0x80080970;
10551053
ND_WaitEvent = 0x80080980;
10561054
ND_FlushCache = 0x80080990;
1057-
ND_data = 0x800809a0;
1058-
ND_sdata_static = 0x8008cf6c;
1059-
ND_bss = 0x8008d668;
10601055
ND_OVR_Region1 = 0x8009f6fc;
10611056
ND_AA_EndEvent_DrawMenu = 0x8009f704;
10621057
ND_TT_EndEvent_DisplayTime = 0x8009f704;

0 commit comments

Comments
 (0)