Skip to content

Commit ea89da6

Browse files
committed
all math functions working
1 parent 2505aaa commit ea89da6

File tree

7 files changed

+167
-20
lines changed

7 files changed

+167
-20
lines changed

include/ctr/math.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ force_inline s32 clamp(s32 n, s32 lo, s32 hi)
120120

121121
s32 MATH_Sin(u32 angle);
122122
s32 MATH_Cos(u32 angle);
123-
s32 MATH_Sqrt(u32 n, u32 shift); // sqrt(n * 2^shift)
123+
u32 MATH_Sqrt(u32 n, u32 shift); // sqrt(n * 2^shift)
124124
void MATH_GetInverseMatrixTransformation(Matrix* out, const Matrix* matrix);
125125
s32 MATH_VectorLength(const SVec3* vector);
126126
void MATH_VectorNormalize(SVec3* vector);

include/ctr/nd.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ void ND_LOAD_InitCD();
1212
/* MATH */
1313
s32 ND_MATH_Sin(u32 angle);
1414
s32 ND_MATH_Cos(u32 angle);
15-
s32 ND_MATH_Sqrt(u32 n, u32 shift);
15+
u32 ND_MATH_Sqrt(u32 n, u32 shift);
1616
void ND_MATH_GetInverseMatrixTransformation(Matrix* out, const Matrix* matrix);
1717
s32 ND_MATH_VectorLength(const SVec3* vector);
1818
void ND_MATH_VectorNormalize(SVec3* vector);

include/ctr/redux.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#ifndef REDUX_H
2+
#define REDUX_H
3+
4+
#include <ctr/macros.h>
5+
6+
force_inline void pcsx_putc(int c) { *((volatile char* const)0x1f802080) = c; }
7+
force_inline void pcsx_debugbreak() { *((volatile char* const)0x1f802081) = 0; }
8+
force_inline void pcsx_execSlot(uint8_t slot) { *((volatile uint8_t* const)0x1f802081) = slot; }
9+
force_inline void pcsx_exit(int code) { *((volatile int16_t* const)0x1f802082) = code; }
10+
force_inline void pcsx_message(const char* msg) { *((volatile const char** const)0x1f802084) = msg; }
11+
force_inline void pcsx_checkKernel(int enable) { *((volatile char*)0x1f802088) = enable; }
12+
force_inline int pcsx_isCheckingKernel() { return *((volatile char* const)0x1f802088) != 0; }
13+
force_inline int pcsx_present() { return *((volatile uint32_t* const)0x1f802080) == 0x58534350; }
14+
15+
#endif

include/ctr/test.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,31 @@
22
#define TEST_H
33

44
#include <ctr/macros.h>
5+
#include <ctr/math.h>
6+
#include <ctr/redux.h>
57

68
void LoadTestPatches();
79

810
#define TEST_MATH_IMPL
911

1012
#ifdef TEST_MATH_IMPL
1113
void TEST_MATH_Sin(u32 angle, s32 res);
14+
void TEST_MATH_Cos(u32 angle, s32 res);
15+
void TEST_MATH_Sqrt(u32 n, u32 shift, u32 res);
16+
void TEST_MATH_GetInverseMatrixTransformation(const Matrix* matrix, const Matrix* res);
17+
void TEST_MATH_VectorLength(const SVec3* vector, s32 res);
18+
void TEST_MATH_VectorNormalize(SVec3* vector, const SVec3* res);
19+
void TEST_MATH_CombineMatrixTransformation(const Matrix* m, const Matrix* n, const Matrix* res);
20+
void TEST_MATH_MatrixMultiplication(const Matrix* m, const Matrix* n, const Matrix* res);
1221
#else
1322
#define TEST_MATH_Sin(angle, res)
23+
#define TEST_MATH_Cos(angle, res)
24+
#define TEST_MATH_Sqrt(n, shift, res)
25+
#define TEST_MATH_GetInverseMatrixTransformation(matrix, res)
26+
#define TEST_MATH_VectorLength(vector, res)
27+
#define TEST_MATH_VectorNormalize(vector, res)
28+
#define TEST_MATH_CombineMatrixTransformation(m, n, res)
29+
#define TEST_MATH_MatrixMultiplication(m, n, res)
1430
#endif
1531

1632
#endif

rewrite/src/math.c

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,18 @@ s32 MATH_Cos(u32 angle)
3333
cos = s_trigTable[ANG_MODULO_HALF_PI(angle)].sin;
3434
if (!IS_ANG_THIRD_OR_FOURTH_QUADRANT(angle)) { cos = -cos; }
3535
}
36+
TEST_MATH_Cos(angle, cos);
3637
return cos;
3738
}
3839

3940
/* Address: 0x8003d214 */
40-
s32 MATH_Sqrt(u32 n, u32 shift)
41+
u32 MATH_Sqrt(u32 n, u32 shift)
4142
{
4243
u32 root = 0;
4344
u32 remainder = 0;
45+
#ifdef TEST_MATH_IMPL
46+
const u32 input = n;
47+
#endif
4448
const u32 iterations = (shift / 2) + (sizeof(u32) * 8) / 2;
4549
for (u32 i = 0; i < iterations; i++)
4650
{
@@ -54,6 +58,7 @@ s32 MATH_Sqrt(u32 n, u32 shift)
5458
root += 1;
5559
}
5660
}
61+
TEST_MATH_Sqrt(input, shift, root);
5762
return root;
5863
}
5964

@@ -64,10 +69,11 @@ void MATH_GetInverseMatrixTransformation(Matrix* out, const Matrix* matrix)
6469
{
6570
for (u32 j = 0; j < 3; j++) { out->m[i][j] = matrix->m[j][i]; }
6671
}
67-
const SVec3 t = { .x = (s16) -matrix->t.x, .y = (s16) -matrix->t.y, .z = (s16) -matrix->t.z };
72+
const SVec3 t = { .x = (-matrix->t.x) & 0xFFFF, .y = (-matrix->t.y) & 0xFFFF, .z = (-matrix->t.z) & 0xFFFF };
6873
gte_SetRotMatrix(matrix->m);
6974
gte_loadVec(&t, GTE_VECTOR_0);
7075
gte_mulMatrixVec(out->t.v, GTE_MATRIX_ROT, GTE_VECTOR_0);
76+
TEST_MATH_GetInverseMatrixTransformation(matrix, out);
7177
}
7278

7379
/* Address: 0x8003d328 */
@@ -77,17 +83,23 @@ s32 MATH_VectorLength(const SVec3* vector)
7783
gte_loadVec(vector, GTE_VECTOR_0);
7884
s32 lengthSquared;
7985
gte_dotProduct(&lengthSquared, GTE_ROW_INDEX_0, GTE_MATRIX_ROT, GTE_VECTOR_0);
80-
return ND_SquareRoot0_stub(lengthSquared);
86+
const s32 len = ND_SquareRoot0_stub(lengthSquared);
87+
TEST_MATH_VectorLength(vector, len);
88+
return len;
8189
}
8290

8391
/* Address: 0x8003d378 */
8492
void MATH_VectorNormalize(SVec3* vector)
8593
{
94+
#ifdef TEST_MATH_IMPL
95+
SVec3 input = *vector;
96+
#endif
8697
s32 len = MATH_VectorLength(vector);
8798
if (len == 0) { return; }
8899
vector->x = FP_DIV(vector->x, len);
89100
vector->y = FP_DIV(vector->y, len);
90101
vector->z = FP_DIV(vector->z, len);
102+
TEST_MATH_VectorNormalize(&input, vector);
91103
}
92104

93105
/* Address: 0x8003d460 */
@@ -100,36 +112,45 @@ void MATH_CombineMatrixTransformation(Matrix* out, const Matrix* m, const Matrix
100112
M*N = [ RmRn (Rmtn + tm) ]
101113
[ 0 1 ]
102114
*/
115+
#ifdef TEST_MATH_IMPL
116+
Matrix inputM = *m;
117+
Matrix inputN = *n;
118+
#endif
103119
MATH_MatrixMultiplication(out, m, n);
104-
105120
Vec3 res[2];
106121
Vec3 upper = { .x = n->t.x >> 15, .y = n->t.y >> 15, .z = n->t.z >> 15 };
107122
Vec3 lower = { .x = n->t.x & 0x7fff, .y = n->t.y & 0x7fff, .z = n->t.z & 0x7fff };
108123
gte_loadVec(&upper, GTE_VECTOR_IR);
109-
_gte_mulMatrixVec(&res[0], GTE_MATRIX_ROT, GTE_VECTOR_IR, 0); // Special case, no shifting
124+
_gte_mulMatrixVec(res[0].v, GTE_MATRIX_ROT, GTE_VECTOR_IR, 0); // Special case, no shifting
110125
gte_loadVec(&lower, GTE_VECTOR_IR);
111-
gte_mulMatrixVec(&res[1], GTE_MATRIX_ROT, GTE_VECTOR_IR);
126+
gte_mulMatrixVec(res[1].v, GTE_MATRIX_ROT, GTE_VECTOR_IR);
112127
out->t.x = (res[0].x * 8) + res[1].x + m->t.x;
113128
out->t.y = (res[0].y * 8) + res[1].y + m->t.y;
114129
out->t.z = (res[0].z * 8) + res[1].z + m->t.z;
130+
TEST_MATH_CombineMatrixTransformation(&inputM, &inputN, out);
115131
}
116132

117133
/* Address: 0x8006c3b0 */
118134
void MATH_MatrixMultiplication(Matrix* out, const Matrix* m, const Matrix* n)
119135
{
136+
#ifdef TEST_MATH_IMPL
137+
Matrix inputM = *m;
138+
Matrix inputN = *n;
139+
#endif
120140
Vec3 res[3];
121-
const SVec3 v0 = { n->m[0][0], n->m[1][0], n->m[2][0] };
122-
const SVec3 v1 = { n->m[0][1], n->m[1][1], n->m[2][1] };
123-
const SVec3 v2 = { n->m[0][2], n->m[1][2], n->m[2][2] };
141+
const SVec3 v0 = { .x = n->m[0][0], .y = n->m[1][0], .z = n->m[2][0] };
142+
const SVec3 v1 = { .x = n->m[0][1], .y = n->m[1][1], .z = n->m[2][1] };
143+
const SVec3 v2 = { .x = n->m[0][2], .y = n->m[1][2], .z = n->m[2][2] };
124144
gte_SetRotMatrix(m->m);
125145
gte_loadVec(&v0, GTE_VECTOR_0);
126-
gte_mulMatrixVec(&res[0], GTE_MATRIX_ROT, GTE_VECTOR_0);
146+
gte_mulMatrixVec(res[0].v, GTE_MATRIX_ROT, GTE_VECTOR_0);
127147
gte_loadVec(&v1, GTE_VECTOR_1);
128-
gte_mulMatrixVec(&res[1], GTE_MATRIX_ROT, GTE_VECTOR_1);
129-
gte_loadVec(&v2, GTE_VECTOR_0);
130-
gte_mulMatrixVec(&res[2], GTE_MATRIX_ROT, GTE_VECTOR_2);
148+
gte_mulMatrixVec(res[1].v, GTE_MATRIX_ROT, GTE_VECTOR_1);
149+
gte_loadVec(&v2, GTE_VECTOR_2);
150+
gte_mulMatrixVec(res[2].v, GTE_MATRIX_ROT, GTE_VECTOR_2);
131151
out->m[0][0] = res[0].x; out->m[0][1] = res[1].x; out->m[0][2] = res[2].x;
132152
out->m[1][0] = res[0].y; out->m[1][1] = res[1].y; out->m[1][2] = res[2].y;
133153
out->m[2][0] = res[0].z; out->m[2][1] = res[1].z; out->m[2][2] = res[2].z;
134154
gte_SetRotMatrix(out->m);
155+
TEST_MATH_MatrixMultiplication(&inputM, &inputN, out);
135156
}

rewrite/src/tests/test.c

Lines changed: 99 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,108 @@ static u32 PatchFunction_End(u32 index)
6565
*(s_functions[index].address + 1) = s_functions[index].secondNewInst;
6666
}
6767

68+
static u32 PrintSVectorDiff(const char* name, const SVec3* expected, const SVec3* res)
69+
{
70+
u32 failed = 0;
71+
for (u32 i = 0; i < 3; i++)
72+
{
73+
if (expected->v[i] != res->v[i])
74+
{
75+
failed = 1;
76+
ND_printf("[%s] Test Failed:\nv[%d] = %d, got %d\n", name, i, expected->v[i], res->v[i]);
77+
}
78+
}
79+
return failed;
80+
}
81+
82+
static u32 PrintMatrixDiff(const char* name, const Matrix* expected, const Matrix* res, u32 cmpTrans)
83+
{
84+
u32 failed = 0;
85+
for (u32 i = 0; i < 3; i++)
86+
{
87+
for (u32 j = 0; j < 3; j++)
88+
{
89+
if (expected->m[i][j] != res->m[i][j])
90+
{
91+
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]);
93+
}
94+
}
95+
if ((cmpTrans) && (expected->t.v[i] != res->t.v[i]))
96+
{
97+
failed = 1;
98+
ND_printf("[%s] Test Failed:\nt[%d] = %d, got %d\n", name, i, expected->t.v[i], res->t.v[i]);
99+
}
100+
}
101+
return failed;
102+
}
103+
68104
#ifdef TEST_MATH_IMPL
69105
void TEST_MATH_Sin(u32 angle, s32 res)
70106
{
71-
u32 index = PatchFunction_Beg((u32*)(&ND_MATH_Sin));
72-
s32 expected = ND_MATH_Sin(angle);
73-
if (expected == res) { ND_printf("[MATH_Sin] Test Passed!\n"); }
74-
else { ND_printf("[MATH_Sin] Test Failed:\nExpected: %d\nResult :%d\n"); }
107+
const u32 index = PatchFunction_Beg((u32*)(&ND_MATH_Sin));
108+
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); }
75110
PatchFunction_End(index);
76111
}
112+
113+
void TEST_MATH_Cos(u32 angle, s32 res)
114+
{
115+
const u32 index = PatchFunction_Beg((u32*)(&ND_MATH_Cos));
116+
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); }
118+
PatchFunction_End(index);
119+
}
120+
121+
void TEST_MATH_Sqrt(u32 n, u32 shift, u32 res)
122+
{
123+
const u32 index = PatchFunction_Beg((u32*)(&ND_MATH_Sqrt));
124+
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); }
126+
PatchFunction_End(index);
127+
}
128+
129+
void TEST_MATH_GetInverseMatrixTransformation(const Matrix* matrix, const Matrix* res)
130+
{
131+
Matrix out;
132+
const u32 index = PatchFunction_Beg((u32*)(&ND_MATH_GetInverseMatrixTransformation));
133+
ND_MATH_GetInverseMatrixTransformation(&out, matrix);
134+
PrintMatrixDiff("MATH_GetInverseMatrixTransformation", &out, res, true);
135+
PatchFunction_End(index);
136+
}
137+
138+
void TEST_MATH_VectorLength(const SVec3* vector, s32 res)
139+
{
140+
const u32 index = PatchFunction_Beg((u32*)(&ND_MATH_VectorLength));
141+
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); }
143+
PatchFunction_End(index);
144+
}
145+
146+
void TEST_MATH_VectorNormalize(SVec3* vector, const SVec3* res)
147+
{
148+
const u32 index = PatchFunction_Beg((u32*)(&ND_MATH_VectorNormalize));
149+
ND_MATH_VectorNormalize(vector);
150+
PrintSVectorDiff("MATH_VectorNormalize", vector, res);
151+
PatchFunction_End(index);
152+
}
153+
154+
void TEST_MATH_CombineMatrixTransformation(const Matrix* m, const Matrix* n, const Matrix* res)
155+
{
156+
Matrix expected;
157+
const u32 index = PatchFunction_Beg((u32*)(&ND_MATH_CombineMatrixTransformation));
158+
ND_MATH_CombineMatrixTransformation(&expected, m, n);
159+
PrintMatrixDiff("MATH_CombineMatrixTransformation", &expected, res, true);
160+
PatchFunction_End(index);
161+
}
162+
163+
void TEST_MATH_MatrixMultiplication(const Matrix* m, const Matrix* n, const Matrix* res)
164+
{
165+
Matrix expected;
166+
const u32 index = PatchFunction_Beg((u32*)(&ND_MATH_MatrixMultiplication));
167+
ND_MATH_MatrixMultiplication(&expected, m, n);
168+
PrintMatrixDiff("MATH_MatrixMultiplication", &expected, res, false);
169+
PatchFunction_End(index);
170+
}
171+
77172
#endif // TEST_MATH_IMPL

symbols/gcc-syms-rewrite.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -950,7 +950,7 @@ ND_GetRCnt = 0x80077be4;
950950
ND_StartRCnt = 0x80077c1c;
951951
ND_StopRCnt = 0x80077c4c;
952952
ND_ResetRCnt = 0x80077c80;
953-
ND_memcpy = 0x80077cb8;
953+
memcpy = 0x80077cb8;
954954
ND_strlen = 0x80077cc8;
955955
ND_SetVideoMode = 0x80077cd8;
956956
ND_GetVideoMode = 0x80077cec;

0 commit comments

Comments
 (0)