Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 41 additions & 1 deletion include/ctr/coll.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,45 @@
#pragma once

#include <ctr/macros.h>
#include <ctr/math.h>
#include <ctr/lev.h>

void COLL_ProjectPointToEdge(SVec3* out, const SVec3* v1, const SVec3* v2, const SVec3* point);
typedef enum Axis
{
AXIS_Z = 1,
AXIS_X = 2,
AXIS_Y = 3,
} Axis;

typedef enum BarycentricTest
{
BARYCENTRIC_TEST_INVALID = -1,
BARYCENTRIC_TEST_SNAP_V1 = 0,
BARYCENTRIC_TEST_EDGE_V1_V2 = 1,
BARYCENTRIC_TEST_SNAP_V2 = 2,
BARYCENTRIC_TEST_EDGE_V2_V3 = 3,
BARYCENTRIC_TEST_SNAP_V3 = 4,
BARYCENTRIC_TEST_EDGE_V1_V3 = 5,
BARYCENTRIC_TEST_INSIDE_TRIANGLE = 6,
} BarycentricTest;

typedef struct CollVertex
{
SVec3 pos;
u16 normalDominantAxis;
Vertex* levVertex;
SVec3 triNormal;
u16 planeDist;
} CollVertex;

typedef struct TestVertex
{
SVec3 pos;
u16 normalDominantAxis;
SVec3 triNormal;
u16 planeDist;
SVec3 interpolationPoint;
} TestVertex;

void COLL_ProjectPointToEdge(SVec3* out, const SVec3* v1, const SVec3* v2, const SVec3* point);
s32 COLL_BarycentricTest(TestVertex* t, const CollVertex* v1, const CollVertex* v2, const CollVertex* v3);
24 changes: 24 additions & 0 deletions include/ctr/lev.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once

#include <ctr/macros.h>
#include <ctr/math.h>

typedef union Color
{
Copy link
Contributor

@TheUbMunster TheUbMunster Sep 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

??? why not just uint8_t?

struct
{
u8 r;
u8 g;
u8 b;
u8 a;
};
u32 color;
} Color;

typedef struct Vertex
{
SVec3 pos;
u16 flags;
Color colorHi;
Color colorLo;
} Vertex;
4 changes: 3 additions & 1 deletion include/ctr/macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,6 @@ typedef int8_t s8;
#define OFFSETOF(TYPE, ELEMENT) ((unsigned int)&(((TYPE *)0)->ELEMENT))

#define nullptr ((void *) 0)
#define force_inline static inline __attribute__((always_inline))
#define force_inline static inline __attribute__((always_inline))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is static necessary?


//#define FIX_CTR_BUGS
4 changes: 3 additions & 1 deletion include/ctr/nd.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <ctr/macros.h>
#include <ctr/math.h>
#include <ctr/rng.h>
#include <ctr/coll.h>

void ND_LOAD_XnfFile(char* filename, u32 address, char* dummy);
s32 ND_SquareRoot0_stub(s32 n);
Expand All @@ -27,4 +28,5 @@ u16 ND_RNG_PseudoRand(u16 n);
u32 ND_RNG_Random(RNGSeed* seed);

/* COLL */
void ND_COLL_ProjectPointToEdge(SVec3* out, const SVec3* v1, const SVec3* v2, const SVec3* point);
void ND_COLL_ProjectPointToEdge(SVec3* out, const SVec3* v1, const SVec3* v2, const SVec3* point);
s32 ND_COLL_BarycentricTest(TestVertex* t, const CollVertex* v1, const CollVertex* v2, const CollVertex* v3);
5 changes: 3 additions & 2 deletions include/ctr/profiler.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#pragma once

#define REWRITE_PROFILER
void LoadProfilerPatches();
//#define REWRITE_PROFILER

void LoadProfilerPatches();
15 changes: 12 additions & 3 deletions include/ctr/test.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,18 @@ 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);

force_inline void FlushCache()
{
register int n asm("t1") = 0x44;
__asm__ volatile("" : "=r"(n) : "r"(n));
((void (*)())0xa0)();
}

#define BACKUP_ADDR 0x80400000

//#define TEST_MATH_IMPL
//#define TEST_RNG_IMPL
//#define TEST_COLL_IMPL
#define TEST_MATH_IMPL
#define TEST_RNG_IMPL
#define TEST_COLL_IMPL

#ifdef TEST_MATH_IMPL
void TEST_MATH_Sin(u32 angle, s32 ret);
Expand Down Expand Up @@ -58,6 +65,8 @@ u32 PrintMatrixDiff(const char* name, const Matrix* expected, const Matrix* ret,

#ifdef TEST_COLL_IMPL
void TEST_COLL_ProjectPointToEdge(const SVec3* v1, const SVec3* v2, const SVec3* point, const SVec3* ret);
void TEST_COLL_BarycentricTest(TestVertex* t, const CollVertex* v1, const CollVertex* v2, const CollVertex* v3, const SVec3* pos, s32 ret);
#else
#define TEST_COLL_ProjectPointToEdge(out, v1, v2, point)
#define TEST_COLL_BarycentricTest(t, v1, v2, v3, pos, ret)
#endif
4 changes: 2 additions & 2 deletions rewrite/buildList.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ common, header, 0x8000B0B8, 0x0, src/hooks/dll/load_decomp.c

// decomp files
common, DLL, 0x80200000, 0x0, src/exe/*.c, DECOMP.BIN
common, DLL, 0x80600000, 0x0, src/tests/*.c, TESTS.BIN
common, DLL, 0x80600000, 0x0, src/tests/*.c src/tests/test_wrappers.s, TESTS.BIN

// profiler files
common, DLL, 0x80500000, 0x0, src/profiler/*.c, PROFILER.BIN
common, DLL, 0x80500000, 0x0, src/profiler/*.c, PROFILER.BIN
115 changes: 115 additions & 0 deletions rewrite/src/exe/coll.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,119 @@ void COLL_ProjectPointToEdge(SVec3* out, const SVec3* v1, const SVec3* v2, const
out->y = coords.y;
out->z = coords.z;
TEST_COLL_ProjectPointToEdge(v1, v2, point, out);
}

/* Address: 0x8001f928 */
static s32 _COLL_BarycentricTest(TestVertex* t, const CollVertex* v1, const CollVertex* v2, const CollVertex* v3)
{
Vec2 deltaT;
Vec2 deltaTri[2];
const SVec3* edgeV2;
const SVec3* edgeV3;
u32 firstAxis, secondAxis;

if (t->normalDominantAxis == AXIS_X)
{
firstAxis = 1; // y
secondAxis = 2; // z
}
else if (t->normalDominantAxis == AXIS_Y)
{
firstAxis = 2; // z
secondAxis = 0; // x
}
else
{
firstAxis = 0; // x
secondAxis = 1; // y
}

deltaTri[0].x = v2->pos.v[firstAxis] - v1->pos.v[firstAxis];
deltaTri[0].y = v3->pos.v[firstAxis] - v1->pos.v[firstAxis];
deltaT.x = t->interpolationPoint.v[firstAxis] - v1->pos.v[firstAxis];
edgeV2 = &v2->pos;
edgeV3 = &v3->pos;
if (abs(deltaTri[0].x) < abs(deltaTri[0].y))
{
edgeV2 = &v3->pos;
edgeV3 = &v2->pos;
s32 temp = deltaTri[0].x;
deltaTri[0].x = deltaTri[0].y;
deltaTri[0].y = temp;
}
deltaTri[1].x = edgeV2->v[secondAxis] - v1->pos.v[secondAxis];
deltaTri[1].y = edgeV3->v[secondAxis] - v1->pos.v[secondAxis];
deltaT.y = t->interpolationPoint.v[secondAxis] - v1->pos.v[secondAxis];

s32 beta = FP(-1);
s32 gamma = FP(-1);
if (deltaTri[0].x != 0)
{
s32 dem = ((deltaTri[1].y * deltaTri[0].x) - (deltaTri[0].y * deltaTri[1].x)) >> 6;
if (dem != 0)
{
beta = (((deltaT.y * deltaTri[0].x) - (deltaT.x * deltaTri[1].x)) << 6) / dem;
gamma = ((deltaT.x * FP_ONE) - (beta * deltaTri[0].y)) / deltaTri[0].x;
}
}
else
{
if ((deltaTri[0].y != 0) && (deltaTri[1].x != 0))
{
beta = FP_DIV(deltaT.y, deltaTri[0].y);
gamma = ((deltaT.y * FP_ONE) - (beta * deltaTri[1].y)) / deltaTri[1].x;
}
}

/* Naughty Dog bug: their hand written assembly code
forgets to check beta == -1, creating false collisions */
#ifdef FIX_CTR_BUGS
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

big appreciate

if ((beta == FP(-1)) || (gamma == FP(-1))) { return BARYCENTRIC_TEST_INVALID; }
#else
if (gamma == FP(-1)) { return BARYCENTRIC_TEST_INVALID; }
#endif

s32 alpha = beta + gamma + FP(-1);
if (gamma < 0)
{
if (beta < 0)
{
t->pos = v1->pos;
return BARYCENTRIC_TEST_SNAP_V1;
}
if (alpha < 0)
{
COLL_ProjectPointToEdge(&t->pos, &v1->pos, edgeV3, &t->interpolationPoint);
return BARYCENTRIC_TEST_EDGE_V1_V3;
}
t->pos = *edgeV3;
return BARYCENTRIC_TEST_SNAP_V3;
}
if (beta < 0)
{
if (alpha < 0)
{
COLL_ProjectPointToEdge(&t->pos, &v1->pos, edgeV2, &t->interpolationPoint);
return BARYCENTRIC_TEST_EDGE_V1_V2;
}
t->pos = *edgeV2;
return BARYCENTRIC_TEST_SNAP_V2;
}
if (alpha > 0)
{
COLL_ProjectPointToEdge(&t->pos, edgeV2, edgeV3, &t->interpolationPoint);
return BARYCENTRIC_TEST_EDGE_V2_V3;
}
t->pos = t->interpolationPoint;
return BARYCENTRIC_TEST_INSIDE_TRIANGLE;
}

s32 COLL_BarycentricTest(TestVertex* t, const CollVertex* v1, const CollVertex* v2, const CollVertex* v3)
{
#ifdef TEST_COLL_IMPL
TestVertex input = *t;
#endif
const s32 ret = _COLL_BarycentricTest(t, v1, v2, v3);
TEST_COLL_BarycentricTest(&input, v1, v2, v3, &t->pos, ret);
return ret;
}
7 changes: 5 additions & 2 deletions rewrite/src/profiler/benchmark.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// When running OG functions,
// dont forget to undefine these in ctr\test.h:
// TEST_MATH_IMPL, TEST_RNG_IMPL, TEST_COLL_IMPL
#ifdef REWRITE_PROFILER

void RunBenchmark()
{
Expand All @@ -30,5 +31,7 @@ void RunBenchmark()
{
ND_COLL_ProjectPointToEdge(&out, &v1, &v2, &point);
}

}

}

#endif // REWRITE_PROFILER
28 changes: 16 additions & 12 deletions rewrite/src/profiler/profiler.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include <ctr/profiler.h>
#include <ctr/nd.h>

#ifdef REWRITE_PROFILER

// No Vehicle.h
struct MetaPhys
{
Expand Down Expand Up @@ -51,7 +53,7 @@ int Debug_GetPreciseTime()
int sysClock =
ND_GetRCnt(0xf2000001) +
sdata->rcntTotalUnits;

return sysClock;
}

Expand All @@ -65,42 +67,44 @@ void Hook_DrawOTag(int a)
if (timeRed == 0)
{
timeStart = Debug_GetPreciseTime();

void RunBenchmark();
RunBenchmark();

timeEnd = Debug_GetPreciseTime();


timeRed = timeEnd - timeStart;
}

struct GameTracker* gGT = sdata->gGT;

if((gGT->gameMode1 & (LOADING|1)) == 0)
{
// reset depth to CLOSEST
gGT->pushBuffer_UI.ptrOT =
gGT->otSwapchainDB[gGT->swapchainIndex];


#ifndef REBUILD_PC
char* string = (char*)0x1f800000;
#else
char string[128];
#endif

ND_sprintf(string, "RED %d", timeRed);
ND_DecalFont_DrawLine(string, 0x14, 0x5C, FONT_SMALL, 0);
}

ND_DrawOTag(a);
}

#define JMP(dest) (((unsigned long)dest & 0x3FFFFFF) >> 2 | 0x8000000)
#define JAL(dest) (((unsigned long)dest & 0x3FFFFFF) >> 2 | 0xC000000)

void LoadProfilerPatches()
{
{
*(int*)0x800379b0 = JAL(Hook_DrawOTag);
}
}

#endif // REWRITE_PROFILER
Loading