-
Notifications
You must be signed in to change notification settings - Fork 46
[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
Merged
Merged
[RW] RNG namespace #227
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
b04ae2c
cos, sqrt and normalize decompiled
mateusfavarin a7584d4
finish MATH functions
mateusfavarin 2505aaa
no more hook files, add test files
mateusfavarin ea89da6
all math functions working
mateusfavarin cc0b7fb
passing 100% of tests
mateusfavarin 7164a6f
RNG decompiled
mateusfavarin 3232fe7
Merge branch 'main' into math_decomp
mateusfavarin b8ee711
naming convention
mateusfavarin eb6f882
code review
mateusfavarin c5ef533
add rewrite readme
mateusfavarin ce7f7ce
add codeflow script
mateusfavarin 8e4445d
code review 2
mateusfavarin File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -52,4 +52,6 @@ games/settings.json | |
| *.dll | ||
|
|
||
| # MyMods folder | ||
| mods/MyMods/* | ||
| mods/MyMods/* | ||
|
|
||
| log.txt | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| #pragma once | ||
|
|
||
| #include <ctr/macros.h> | ||
| #include <ctr/rng.h> | ||
|
|
||
| typedef struct GameTracker | ||
| { | ||
| u8 fill[0x252c]; | ||
| RNGSeed seed; | ||
| } GameTracker; | ||
|
|
||
| extern GameTracker* e_gameTracker; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| #pragma once | ||
|
|
||
| #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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,32 +1,55 @@ | ||
| #ifndef TEST_H | ||
| #define TEST_H | ||
| #pragma once | ||
|
|
||
| #include <ctr/macros.h> | ||
| #include <ctr/math.h> | ||
| #include <ctr/redux.h> | ||
| #include <ctr/nd.h> | ||
| #include <ctr/game_tracker.h> | ||
| #include <ctr/math.h> | ||
| #include <ctr/rng.h> | ||
|
|
||
| void LoadTestPatches(); | ||
| u32 PatchFunction_Beg(u32* index); | ||
| void PatchFunction_End(u32 index); | ||
| u32 PrintSVectorDiff(const char* name, const SVec3* expected, const SVec3* ret); | ||
| u32 PrintMatrixDiff(const char* name, const Matrix* expected, const Matrix* ret, u32 cmpTrans); | ||
|
|
||
| #define BACKUP_ADDR 0x80400000 | ||
|
|
||
| #define TEST_MATH_IMPL | ||
| #define TEST_RNG_IMPL | ||
|
|
||
| #ifdef TEST_MATH_IMPL | ||
| void TEST_MATH_Sin(u32 angle, s32 res); | ||
| void TEST_MATH_Cos(u32 angle, s32 res); | ||
| void TEST_MATH_Sqrt(u32 n, u32 shift, u32 res); | ||
| void TEST_MATH_GetInverseMatrixTransformation(const Matrix* matrix, const Matrix* res); | ||
| void TEST_MATH_VectorLength(const SVec3* vector, s32 res); | ||
| void TEST_MATH_VectorNormalize(SVec3* vector, const SVec3* res); | ||
| void TEST_MATH_CombineMatrixTransformation(const Matrix* m, const Matrix* n, const Matrix* res); | ||
| void TEST_MATH_MatrixMultiplication(const Matrix* m, const Matrix* n, const Matrix* res); | ||
| void TEST_MATH_Sin(u32 angle, s32 ret); | ||
| void TEST_MATH_Cos(u32 angle, s32 ret); | ||
| void TEST_MATH_Sqrt(u32 n, u32 shift, u32 ret); | ||
| void TEST_MATH_GetInverseMatrixTransformation(const Matrix* matrix, const Matrix* ret); | ||
| void TEST_MATH_VectorLength(const SVec3* vector, s32 ret); | ||
| void TEST_MATH_VectorNormalize(SVec3* vector, const SVec3* ret); | ||
| void TEST_MATH_CombineMatrixTransformation(const Matrix* m, const Matrix* n, const Matrix* ret); | ||
| void TEST_MATH_MatrixMultiplication(const Matrix* m, const Matrix* n, const Matrix* ret); | ||
| #else | ||
| #define TEST_MATH_Sin(angle, res) | ||
| #define TEST_MATH_Cos(angle, res) | ||
| #define TEST_MATH_Sqrt(n, shift, res) | ||
| #define TEST_MATH_GetInverseMatrixTransformation(matrix, res) | ||
| #define TEST_MATH_VectorLength(vector, res) | ||
| #define TEST_MATH_VectorNormalize(vector, res) | ||
| #define TEST_MATH_CombineMatrixTransformation(m, n, res) | ||
| #define TEST_MATH_MatrixMultiplication(m, n, res) | ||
| #define TEST_MATH_Sin(angle, ret) | ||
| #define TEST_MATH_Cos(angle, ret) | ||
| #define TEST_MATH_Sqrt(n, shift, ret) | ||
| #define TEST_MATH_GetInverseMatrixTransformation(matrix, ret) | ||
| #define TEST_MATH_VectorLength(vector, ret) | ||
| #define TEST_MATH_VectorNormalize(vector, ret) | ||
| #define TEST_MATH_CombineMatrixTransformation(m, n, ret) | ||
| #define TEST_MATH_MatrixMultiplication(m, n, ret) | ||
| #endif | ||
|
|
||
| #ifdef TEST_RNG_IMPL | ||
| void BACKUP_RNG_Rand(); | ||
| void TEST_RNG_Rand(); | ||
| void BACKUP_RNG_RandInt(); | ||
| void TEST_RNG_RandInt(u32 n, s32 ret); | ||
| void TEST_RNG_PseudoRand(u16 n, u16 ret); | ||
| void TEST_RNG_Random(RNGSeed* seed, const RNGSeed* ret); | ||
| #else | ||
| #define BACKUP_RNG_Rand() | ||
| #define TEST_RNG_Rand() | ||
| #define BACKUP_RNG_RandInt() | ||
| #define TEST_RNG_RandInt(n, ret) | ||
| #define TEST_RNG_PseudoRand(n, ret) | ||
| #define TEST_RNG_Random(seed, ret) | ||
| #endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| # Strategy | ||
| This folder is an ongoing decompilation project for the PSX game Crash Team Racing. This is a non byte matching decompilation, aiming for code quality while achieving the same functionality as the original game. This project adopts the [Ship of Theseus](https://en.wikipedia.org/wiki/Ship_of_Theseus) strategy. By taking advantage of [PCSX-Redux](https://github.com/grumpycoders/pcsx-redux/) 8MB memory expansion, we can re-write game functions and load them in memory, while the original game stays intact. Then, we can force the game to call each function we re-wrote, and compare the output of the decompiled function with the original game function. | ||
|
|
||
| # Folder Structure | ||
| `src/hooks/dll/`: boot loader for the decompile. | ||
|
|
||
| `src/exe/`: main executable decomp. | ||
|
|
||
| `src/tests/`: tests for each decompiled function. | ||
|
|
||
| `scripts/`: helpful misc scripts. | ||
|
|
||
| `../include/ctr/`: decompile headers. | ||
|
|
||
| `../symbols/gcc-syms-rewrite.txt`: original function addresses. | ||
|
|
||
| `../symbols/gcc-extern-rewrite.txt`: extern global variable addresses. | ||
|
|
||
| # Tests | ||
| Each decompiled function must have an entry in `s_functions` table at `src/tests/test.c`. During boot, this entry is used to patch each original function so that the decompile version can be called. At the end of each decompiled function, a call to a `TEST` function should be made, which restores the state before the decompiled function was called, then patches the game to call the original function, and then compared the output of the original function with the decompiled function. For simple test functions that don't use any global variables, see `src/tests/test_math.c` and `src/exe/math.c`. For functions that change global variables, a call to a `BACKUP` function should be made to store the state upon function call. For examples, see `str/tests/test_rng.c` and `src/exe/rng.c`. | ||
|
|
||
| Note: the original function name must have the same name of the decompiled function + `ND_` prefix. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| from symbols import Syms, RAM_BASE | ||
|
|
||
| class ASMInstruction: | ||
| def __init__(self, line: str, sym: Syms) -> None: | ||
| self.failed_decoding = False | ||
| try: | ||
| self.return_address = int("0x" + line[0][:8], 0) + 8 | ||
| except Exception: | ||
| self.failed_decoding = True | ||
| return | ||
| self.sym = sym | ||
| self.instruction = line[2] | ||
| self.destination = line[3] | ||
| switch = { | ||
| "jal" : self.case_jal, | ||
| "jalr" : self.case_jalr, | ||
| "jr" : self.case_jr | ||
| } | ||
| self.symbol = None | ||
| self.has_returned = False | ||
| self.returning = False | ||
| self.func_call = False | ||
| if self.instruction in switch: | ||
| switch[self.instruction]() | ||
| self.func_call = True | ||
|
|
||
| def case_jal(self): | ||
| self.destination = int(self.destination[:10], 0) | ||
| self.symbol = self.sym.get_symbol(self.destination) | ||
| if self.symbol is None: | ||
| name = str() | ||
| if self.destination < RAM_BASE: | ||
| name = "0" + hex(self.destination + RAM_BASE)[3:] | ||
| else: | ||
| name = hex(self.destination)[2:] | ||
| self.symbol = "FUN_" + name | ||
|
|
||
| def case_jalr(self): | ||
| self.destination = int("0x" + self.destination[4:12], 0) | ||
| self.symbol = self.sym.get_symbol(self.destination) | ||
| if self.symbol is None: | ||
| name = str() | ||
| if self.destination < RAM_BASE: | ||
| name = "0" + hex(self.destination + RAM_BASE)[3:] | ||
| else: | ||
| name = hex(self.destination)[2:] | ||
| self.symbol = "FUN_" + name | ||
|
|
||
| def case_jr(self): | ||
| self.destination = int("0x" + self.destination[4:12], 0) | ||
| self.returning = True | ||
|
|
||
| class ASMAnalyzer: | ||
| def __init__(self, sym: Syms, output: str, space_size: int) -> None: | ||
| self.sym = sym | ||
| self.output = output | ||
| self.space_size = space_size | ||
|
|
||
| def analyze_log(self, log: str, start_label: str) -> None: | ||
| output = open(self.output, "w") | ||
| buffer = start_label + "()\n" | ||
| curr_spacing = self.space_size | ||
| possible_func_calls = [] | ||
| with open(log, "r") as file: | ||
| for line in file: | ||
| line = line.split() | ||
| if len(line) < 4: | ||
| continue | ||
| instruction = ASMInstruction(line, self.sym) | ||
| if instruction.failed_decoding: | ||
| continue | ||
| if instruction.returning: | ||
| for i in range(len(possible_func_calls) - 1, -1, -1): | ||
| func_call = possible_func_calls[i][0] | ||
| if (not func_call.has_returned) and (func_call.return_address == instruction.destination): | ||
| possible_func_calls[i][0].has_returned = True | ||
| curr_spacing = possible_func_calls[i][1] | ||
| elif instruction.func_call: | ||
| possible_func_calls.append([instruction, curr_spacing]) | ||
| curr_spacing += self.space_size | ||
|
|
||
| for pfc in possible_func_calls: | ||
| func_call = pfc[0] | ||
| if func_call.has_returned: | ||
| spacing = pfc[1] | ||
| buffer += (" " * spacing) + func_call.symbol + "()\n" | ||
|
|
||
| output.write(buffer) | ||
| output.close() | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| from symbols import Syms | ||
| from asm import ASMAnalyzer | ||
|
|
||
| syms = Syms() | ||
| syms.add_symbols("../../../symbols/gcc-syms-rewrite.txt") | ||
|
|
||
| asm = ASMAnalyzer(syms, "output.txt", 2) | ||
| asm.analyze_log("log.txt", "main") |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
What's this do?
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.
analizes the log of instructions of one frame and displays the function calls