-
Notifications
You must be signed in to change notification settings - Fork 47
[RW] RNG namespace #227
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RW] RNG namespace #227
Changes from 8 commits
b04ae2c
a7584d4
2505aaa
ea89da6
cc0b7fb
7164a6f
3232fe7
b8ee711
eb6f882
c5ef533
ce7f7ce
8e4445d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| #ifndef RAND_H | ||
| #define RAND_H | ||
|
|
||
| #include <ctr/macros.h> | ||
|
|
||
| typedef struct RNGSeed | ||
| { | ||
| u32 a; | ||
| u32 b; | ||
| } RNGSeed; | ||
|
|
||
| u32 RNG_Rand(); | ||
| s32 RNG_RandInt(u32 n); | ||
| u16 RNG_PseudoRand(u16 n); | ||
| u32 RNG_Random(RNGSeed* seed); | ||
|
|
||
| extern u32 e_seed; // 0x8008d424 | ||
| extern RNGSeed e_gameTrackerSeed; // 0x8009904c | ||
|
|
||
| #endif | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| #include <ctr/rng.h> | ||
| #include <ctr/math.h> | ||
| #include <ctr/test.h> | ||
|
|
||
| #define RNG_MULT_FACTOR 0x6255 | ||
| #define RNG_INC_FACTOR 0x3619 | ||
|
|
||
| /* Address: 0x8003ea28 */ | ||
| u32 RNG_Rand() | ||
| { | ||
| BACKUP_RNG_Rand(); | ||
| e_seed = (e_seed * RNG_MULT_FACTOR + RNG_INC_FACTOR) & 0xFFFF; | ||
| TEST_RNG_Rand(); | ||
| return e_seed; | ||
| } | ||
|
|
||
| /* Address: 0x8003ea6c */ | ||
| s32 RNG_RandInt(u32 n) | ||
| { | ||
| BACKUP_RNG_RandInt(); | ||
| const u32 rand = RNG_Random(&e_gameTrackerSeed); | ||
| const s32 ret = ((s32) ((rand & 0xFFFF) * n)) >> 16; | ||
| TEST_RNG_RandInt(n, ret); | ||
| return ret; | ||
| } | ||
|
|
||
| /* Address: 0x8003eaac */ | ||
| u16 RNG_PseudoRand(u16 n) | ||
| { | ||
| const u16 ret = n * RNG_MULT_FACTOR + RNG_INC_FACTOR; | ||
| TEST_RNG_PseudoRand(n, ret); | ||
| return ret; | ||
| } | ||
|
|
||
| /* Address: 0x8006c684 */ | ||
| u32 RNG_Random(RNGSeed* seed) | ||
| { | ||
| #ifdef TEST_RNG_IMPL | ||
| RNGSeed inputSeed = *seed; | ||
| #endif | ||
| const u32 x = seed->b >> 8; | ||
| const u32 nextA = (seed->a >> 8) | (seed->b << 24); | ||
| seed->b = (x | ((seed->a + x + (nextA >> 8)) << 24)) ^ 0xDEADC0ED; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. iirc there was a deadcoed struct in sdata or something? Do we still use that?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We aren't using anything from the previous decomp
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm more interested in knowing where the functionality that that struct represented went.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's just parameters initialized with a seed, and bit shifted to give a pseudorandom number at the end. |
||
| seed->a = nextA; | ||
| TEST_RNG_Random(&inputSeed, seed); | ||
| return seed->b; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -26,6 +26,10 @@ FunctionPatch s_functions[] = | |
| TEST_FUNC(MATH_VectorNormalize), | ||
| TEST_FUNC(MATH_CombineMatrixTransformation), | ||
| TEST_FUNC(MATH_MatrixMultiplication), | ||
| TEST_FUNC(RNG_Rand), | ||
| TEST_FUNC(RNG_RandInt), | ||
| TEST_FUNC(RNG_PseudoRand), | ||
| TEST_FUNC(RNG_Random), | ||
| }; | ||
|
|
||
| void LoadTestPatches() | ||
|
|
@@ -65,108 +69,162 @@ static u32 PatchFunction_End(u32 index) | |
| *(s_functions[index].address + 1) = s_functions[index].secondNewInst; | ||
| } | ||
|
|
||
| static u32 PrintSVectorDiff(const char* name, const SVec3* expected, const SVec3* res) | ||
| static u32 PrintSVectorDiff(const char* name, const SVec3* expected, const SVec3* ret) | ||
| { | ||
| u32 failed = 0; | ||
| for (u32 i = 0; i < 3; i++) | ||
| { | ||
| if (expected->v[i] != res->v[i]) | ||
| if (expected->v[i] != ret->v[i]) | ||
| { | ||
| failed = 1; | ||
| ND_printf("[%s] Test Failed:\nv[%d] = %d, got %d\n", name, i, expected->v[i], res->v[i]); | ||
| ND_printf("[%s] Test Failed:\nv[%d] = %d, got %d\n", name, i, expected->v[i], ret->v[i]); | ||
| } | ||
| } | ||
| return failed; | ||
| } | ||
|
|
||
| static u32 PrintMatrixDiff(const char* name, const Matrix* expected, const Matrix* res, u32 cmpTrans) | ||
| static u32 PrintMatrixDiff(const char* name, const Matrix* expected, const Matrix* ret, u32 cmpTrans) | ||
| { | ||
| u32 failed = 0; | ||
| for (u32 i = 0; i < 3; i++) | ||
| { | ||
| for (u32 j = 0; j < 3; j++) | ||
| { | ||
| if (expected->m[i][j] != res->m[i][j]) | ||
| if (expected->m[i][j] != ret->m[i][j]) | ||
| { | ||
| failed = 1; | ||
| ND_printf("[%s] Test Failed:\nm[%d][%d] = %d, got %d\n", name, i, j, expected->m[i][j], res->m[i][j]); | ||
| ND_printf("[%s] Test Failed:\nm[%d][%d] = %d, got %d\n", name, i, j, expected->m[i][j], ret->m[i][j]); | ||
| } | ||
| } | ||
| if ((cmpTrans) && (expected->t.v[i] != res->t.v[i])) | ||
| if ((cmpTrans) && (expected->t.v[i] != ret->t.v[i])) | ||
| { | ||
| failed = 1; | ||
| ND_printf("[%s] Test Failed:\nt[%d] = %d, got %d\n", name, i, expected->t.v[i], res->t.v[i]); | ||
| ND_printf("[%s] Test Failed:\nt[%d] = %d, got %d\n", name, i, expected->t.v[i], ret->t.v[i]); | ||
| } | ||
| } | ||
| return failed; | ||
| } | ||
|
|
||
| #ifdef TEST_MATH_IMPL | ||
| void TEST_MATH_Sin(u32 angle, s32 res) | ||
|
|
||
| void TEST_MATH_Sin(u32 angle, s32 ret) | ||
| { | ||
| const u32 index = PatchFunction_Beg((u32*)(&ND_MATH_Sin)); | ||
| const s32 expected = ND_MATH_Sin(angle); | ||
| if (expected != res) { ND_printf("[MATH_Sin] Test Failed:\nInput: %d\nExpected: %d\nResult :%d\n", angle, expected, res); } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Expected:[space][number] vs Result:[number]
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it looks like result has two spaces on it now lol, probably doesn't matter though. |
||
| if (expected != ret) { ND_printf("[MATH_Sin] Test Failed:\nInput: %d\nExpected: %d\nResult:%d\n", angle, expected, ret); } | ||
| PatchFunction_End(index); | ||
| } | ||
|
|
||
| void TEST_MATH_Cos(u32 angle, s32 res) | ||
| void TEST_MATH_Cos(u32 angle, s32 ret) | ||
| { | ||
| const u32 index = PatchFunction_Beg((u32*)(&ND_MATH_Cos)); | ||
| const s32 expected = ND_MATH_Cos(angle); | ||
| if (expected != res) { ND_printf("[MATH_Cos] Test Failed:\nInput: %d\nExpected: %d\nResult :%d\n", angle, expected, res); } | ||
| if (expected != ret) { ND_printf("[MATH_Cos] Test Failed:\nInput: %d\nExpected: %d\nResult:%d\n", angle, expected, ret); } | ||
| PatchFunction_End(index); | ||
| } | ||
|
|
||
| void TEST_MATH_Sqrt(u32 n, u32 shift, u32 res) | ||
| void TEST_MATH_Sqrt(u32 n, u32 shift, u32 ret) | ||
| { | ||
| const u32 index = PatchFunction_Beg((u32*)(&ND_MATH_Sqrt)); | ||
| const u32 expected = ND_MATH_Sqrt(n, shift); | ||
| if (expected != res) { ND_printf("[MATH_Sqrt] Test Failed:\nInput: %d %d\nExpected: %d\nResult :%d\n", n, shift, expected, res); } | ||
| if (expected != ret) { ND_printf("[MATH_Sqrt] Test Failed:\nInput: %d %d\nExpected: %d\nResult:%d\n", n, shift, expected, ret); } | ||
| PatchFunction_End(index); | ||
| } | ||
|
|
||
| void TEST_MATH_GetInverseMatrixTransformation(const Matrix* matrix, const Matrix* res) | ||
| void TEST_MATH_GetInverseMatrixTransformation(const Matrix* matrix, const Matrix* ret) | ||
| { | ||
| Matrix out; | ||
| const u32 index = PatchFunction_Beg((u32*)(&ND_MATH_GetInverseMatrixTransformation)); | ||
| ND_MATH_GetInverseMatrixTransformation(&out, matrix); | ||
| PrintMatrixDiff("MATH_GetInverseMatrixTransformation", &out, res, true); | ||
| PrintMatrixDiff("MATH_GetInverseMatrixTransformation", &out, ret, true); | ||
| PatchFunction_End(index); | ||
| } | ||
|
|
||
| void TEST_MATH_VectorLength(const SVec3* vector, s32 res) | ||
| void TEST_MATH_VectorLength(const SVec3* vector, s32 ret) | ||
| { | ||
| const u32 index = PatchFunction_Beg((u32*)(&ND_MATH_VectorLength)); | ||
| const s32 expected = ND_MATH_VectorLength(vector); | ||
| 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); } | ||
| 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); } | ||
| PatchFunction_End(index); | ||
| } | ||
|
|
||
| void TEST_MATH_VectorNormalize(SVec3* vector, const SVec3* res) | ||
| void TEST_MATH_VectorNormalize(SVec3* vector, const SVec3* ret) | ||
| { | ||
| const u32 index = PatchFunction_Beg((u32*)(&ND_MATH_VectorNormalize)); | ||
| ND_MATH_VectorNormalize(vector); | ||
| PrintSVectorDiff("MATH_VectorNormalize", vector, res); | ||
| PrintSVectorDiff("MATH_VectorNormalize", vector, ret); | ||
| PatchFunction_End(index); | ||
| } | ||
|
|
||
| void TEST_MATH_CombineMatrixTransformation(const Matrix* m, const Matrix* n, const Matrix* res) | ||
| void TEST_MATH_CombineMatrixTransformation(const Matrix* m, const Matrix* n, const Matrix* ret) | ||
| { | ||
| Matrix expected; | ||
| const u32 index = PatchFunction_Beg((u32*)(&ND_MATH_CombineMatrixTransformation)); | ||
| ND_MATH_CombineMatrixTransformation(&expected, m, n); | ||
| PrintMatrixDiff("MATH_CombineMatrixTransformation", &expected, res, true); | ||
| PrintMatrixDiff("MATH_CombineMatrixTransformation", &expected, ret, true); | ||
| PatchFunction_End(index); | ||
| } | ||
|
|
||
| void TEST_MATH_MatrixMultiplication(const Matrix* m, const Matrix* n, const Matrix* res) | ||
| void TEST_MATH_MatrixMultiplication(const Matrix* m, const Matrix* n, const Matrix* ret) | ||
| { | ||
| Matrix expected; | ||
| const u32 index = PatchFunction_Beg((u32*)(&ND_MATH_MatrixMultiplication)); | ||
| ND_MATH_MatrixMultiplication(&expected, m, n); | ||
| PrintMatrixDiff("MATH_MatrixMultiplication", &expected, res, false); | ||
| PrintMatrixDiff("MATH_MatrixMultiplication", &expected, ret, false); | ||
| PatchFunction_End(index); | ||
| } | ||
|
|
||
| #endif // TEST_MATH_IMPL | ||
|
|
||
| #ifdef TEST_RNG_IMPL | ||
|
||
|
|
||
| void BACKUP_RNG_Rand() | ||
| { | ||
| u32* seedAddr = (u32*) BACKUP_ADDR; | ||
| *seedAddr = e_seed; | ||
| } | ||
|
|
||
| void TEST_RNG_Rand() | ||
| { | ||
| const u32 index = PatchFunction_Beg((u32*)(&ND_RNG_Rand)); | ||
| const u32 ret = e_seed; | ||
| e_seed = *(u32*) BACKUP_ADDR; | ||
| ND_RNG_Rand(); | ||
| if (e_seed != ret) { ND_printf("[RNG_Rand] Test Failed:\nExpected: %d\nResult: %d\n", e_seed, ret); } | ||
| PatchFunction_End(index); | ||
| } | ||
|
|
||
| void BACKUP_RNG_RandInt() | ||
| { | ||
| RNGSeed* seedAddr = (RNGSeed*) BACKUP_ADDR; | ||
| *seedAddr = e_gameTrackerSeed; | ||
| } | ||
|
|
||
| void TEST_RNG_RandInt(u32 n, s32 ret) | ||
| { | ||
| const u32 index = PatchFunction_Beg((u32*)(&ND_RNG_RandInt)); | ||
| e_gameTrackerSeed = *(RNGSeed*) BACKUP_ADDR; | ||
| const s32 expected = ND_RNG_RandInt(n); | ||
| if (expected != ret) { ND_printf("[RNG_RandInt] Test Failed:\nExpected: %d\nResult: %d\n", expected, ret); } | ||
| PatchFunction_End(index); | ||
| } | ||
|
|
||
| void TEST_RNG_PseudoRand(u16 n, u16 ret) | ||
| { | ||
| const u32 index = PatchFunction_Beg((u32*)(&ND_RNG_PseudoRand)); | ||
| const u16 expected = ND_RNG_PseudoRand(n); | ||
| if (expected != ret) { ND_printf("[RNG_PseudoRand] Test Failed:\nExpected: %d\nResult: %d\n", expected, ret); } | ||
| PatchFunction_End(index); | ||
| } | ||
|
|
||
| void TEST_RNG_Random(RNGSeed* seed, const RNGSeed* ret) | ||
| { | ||
| const u32 index = PatchFunction_Beg((u32*)(&ND_RNG_Random)); | ||
| const u32 expected = ND_RNG_Random(seed); | ||
| if (seed->a != ret->a) { ND_printf("[RNG_Random] Test Failed:\nseed->a: %d\nret->a: %d\n", seed->a, ret->a); } | ||
| if (seed->b != ret->b) { ND_printf("[RNG_Random] Test Failed:\nseed->b: %d\nret->b: %d\n", seed->b, ret->b); } | ||
| if (expected != ret->b) { ND_printf("[RNG_Random] Test Failed:\nExpected: %d\nret: %d\n", expected, ret->b); } | ||
| PatchFunction_End(index); | ||
| } | ||
|
|
||
| #endif // TEST_MATH_IMPL | ||
| #endif // TEST_RNG_IMPL | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| e_seed = 0x8008d424; | ||
| e_gameTrackerSeed = 0x8009904c; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
weren't you using pragma once in other files?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could switch to pragma once for every header