Skip to content
Draft
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
19 changes: 19 additions & 0 deletions include/ctr/jitpool.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#pragma once

#include <ctr/list.h>

typedef struct JitPool
{
LinkedList free;
LinkedList taken;

s32 maxItems;
u32 itemSize;
s32 poolSize;
void* ptrPoolData;
} JitPool;

void JitPool_Clear(JitPool* AP);
void JitPool_Init(JitPool* AP, s32 maxItems, s32 itemSize);
Item* JitPool_Add(JitPool* AP);
void JitPool_Remove(JitPool* AP, Item* item);
29 changes: 29 additions & 0 deletions include/ctr/list.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#pragma once

#include <ctr/macros.h>

typedef struct Item
{
struct Item* next;
struct Item* prev;
} Item;

typedef struct LinkedList
{
Item* first;
Item* last;
s32 count;
} LinkedList;

void LIST_Clear(LinkedList* list);
void LIST_AddFront(LinkedList* list, Item* item);
void LIST_AddBack(LinkedList* list, Item* item);
void* LIST_GetNextItem(Item* item);
void* LIST_GetFirstItem(LinkedList* list);
Item* LIST_RemoveMember(LinkedList* list, Item* item);
Item* LIST_RemoveFront(LinkedList* list);
Item* LIST_RemoveBack(LinkedList* list);
void LIST_Init(LinkedList* list, Item* item, s32 itemSize, s32 numItems);

//not a real ND function, just a helper macro. The value of an "Item" is the memory right after the Item struct.
#define LIST_GetItem(itemPtr) ((void*)(((Item*)itemPtr) + 1))
10 changes: 9 additions & 1 deletion include/ctr/nd.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,12 @@ void ND_COLL_CalculateTrianglePlane(const CollDCache* cache, CollVertex* v1, con
void ND_COLL_LoadVerticeData(CollDCache* cache);
s32 ND_COLL_BarycentricTest(TestVertex* t, const CollVertex* v1, const CollVertex* v2, const CollVertex* v3);
void ND_COLL_TestTriangle(CollDCache* cache, const CollVertex* v1, const CollVertex* v2, const CollVertex* v3);
void ND_COLL_TestLeaf_Quadblock(const Quadblock* quadblock, CollDCache* cache);
void ND_COLL_TestLeaf_Quadblock(const Quadblock* quadblock, CollDCache* cache);

/* MEMPACK */
void* ND_MEMPACK_AllocMem(s32 size);

/* MISC */
//TODO: ensure that the signedness of s32 for both of these are correct
void* memset(void* dest, u8 val, s32 len);
void* memcpy(void* dest, const void* src, s32 count);
71 changes: 66 additions & 5 deletions include/ctr/test.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@
#include <ctr/math.h>
#include <ctr/rng.h>
#include <ctr/coll.h>
#include <ctr/test_backup.h>

extern const char* s_nameTestedFunc;

void TEST_WRAPPER();
void LoadTestPatches();
void TEST_Init();
s32 TEST_Memcmp(const void* s1, const void* s2, u32 n);
u32 PatchFunction_Beg(u32* index, const char* funcName);
void PatchFunction_End(u32 index);
u32 PrintSVectorDiff(const SVec3* expected, const SVec3* ret);
Expand All @@ -24,11 +27,26 @@ force_inline void FlushCache()
((void (*)())0xa0)();
}

#define BACKUP_ADDR 0x80400000
#define TEST

#if defined(TEST)
#define DYNAMIC_ASSERT(expected, actual, msg) //TODO
#else
#define DYNAMIC_ASSERT(expected, actual, msg)
#endif

#if defined(TEST)
#define STATIC_ASSERT //TODO
#else
#define STATIC_ASSERT
#endif

#if defined(TEST)
#define TEST_MATH_IMPL
#define TEST_RNG_IMPL
#define TEST_COLL_IMPL
#define TEST_LIST_IMPL
#endif

#ifdef TEST_MATH_IMPL
void TEST_MATH_Sin(u32 angle, s32 ret);
Expand All @@ -51,16 +69,30 @@ force_inline void FlushCache()
#endif

#ifdef TEST_RNG_IMPL
typedef struct BDATA_RNG_Rand
{
u32 e_seed; //backup of 0x8008d424
} BDATA_RNG_Rand;
void BACKUP_RNG_Rand();
void RESTORE_RNG_Rand(BDATA_RNG_Rand* restore);
void TEST_RNG_Rand();

typedef struct BDATA_RNG_RandInt
{
RNGSeed e_gameTracker_seed; //backup of e_gameTracker->seed
} BDATA_RNG_RandInt;
void BACKUP_RNG_RandInt();
void RESTORE_RNG_RandInt(BDATA_RNG_RandInt* restore);
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 RESTORE_RNG_Rand(restore)
#define TEST_RNG_Rand()
#define BACKUP_RNG_RandInt()
#define RESTORE_RNG_RandInt(restore)
#define TEST_RNG_RandInt(n, ret)
#define TEST_RNG_PseudoRand(n, ret)
#define TEST_RNG_Random(seed, ret)
Expand All @@ -70,11 +102,40 @@ force_inline void FlushCache()
void TEST_COLL_ProjectPointToEdge(const SVec3* v1, const SVec3* v2, const SVec3* point, const SVec3* ret);
void TEST_COLL_CalculateTrianglePlane(const CollDCache* cache, CollVertex* v1, const CollVertex* v2, const CollVertex* v3, const CollVertex* ret);
void TEST_COLL_LoadVerticeData(CollDCache* cache);
void TEST_COLL_LoadQuadblockData_LowLOD(CollDCache* cache, const Quadblock* quadblock, const CollDCache* ret);
void TEST_COLL_LoadQuadblockData_HighLOD(CollDCache* cache, const Quadblock* quadblock, const CollDCache* ret);

typedef struct BDATA_COLL_LoadQuadblockData_LowLOD
{
CollDCache cache; //backup of *cache
} BDATA_COLL_LoadQuadblockData_LowLOD;
void BACKUP_COLL_LoadQuadblockData_LowLOD(CollDCache* cache);
void RESTORE_COLL_LoadQuadblockData_LowLOD(BDATA_COLL_LoadQuadblockData_LowLOD* restore, CollDCache* cache);
void TEST_COLL_LoadQuadblockData_LowLOD(const Quadblock* quadblock, CollDCache* cache);

typedef struct BDATA_COLL_LoadQuadblockData_HighLOD
{
CollDCache cache; //backup of *cache
} BDATA_COLL_LoadQuadblockData_HighLOD;
void BACKUP_COLL_LoadQuadblockData_HighLOD(CollDCache* cache);
void RESTORE_COLL_LoadQuadblockData_HighLOD(BDATA_COLL_LoadQuadblockData_HighLOD* restore, CollDCache* cache);
void TEST_COLL_LoadQuadblockData_HighLOD(const Quadblock* quadblock, CollDCache* cache);

void TEST_COLL_BarycentricTest(TestVertex* t, const CollVertex* v1, const CollVertex* v2, const CollVertex* v3, const SVec3* pos, s32 ret);
void TEST_COLL_TestTriangle(CollDCache* cache, const CollVertex* v1, const CollVertex* v2, const CollVertex* v3, const CollDCache* ret);
void TEST_COLL_TestLeaf_Quadblock(const Quadblock* quadblock, CollDCache* cache, const CollDCache* ret);

typedef struct BDATA_COLL_TestTriangle
{
CollDCache cache; //backup of *cache
} BDATA_COLL_TestTriangle;
void BACKUP_COLL_TestTriangle(CollDCache* cache);
void RESTORE_COLL_TestTriangle(BDATA_COLL_TestTriangle* restore, CollDCache* cache);
void TEST_COLL_TestTriangle(const CollVertex* v1, const CollVertex* v2, const CollVertex* v3, CollDCache* cache);

typedef struct BDATA_COLL_TestLeaf_Quadblock
{
CollDCache cache; //backup of *cache
} BDATA_COLL_TestLeaf_Quadblock;
void BACKUP_COLL_TestLeaf_Quadblock(CollDCache* cache);
void RESTORE_COLL_TestLeaf_Quadblock(BDATA_COLL_TestLeaf_Quadblock* restore, CollDCache* cache);
void TEST_COLL_TestLeaf_Quadblock(const Quadblock* quadblock, CollDCache* cache);
#else
#define TEST_COLL_ProjectPointToEdge(out, v1, v2, point)
#define TEST_COLL_CalculateTrianglePlane(cache, v1, v2, v3, ret)
Expand Down
15 changes: 15 additions & 0 deletions include/ctr/test_backup.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once

#include <ctr/macros.h>

#define BACKUP_STACK_BASE_ADDR ((u32)0x80400000u)
#define BACKUP_STACK_HEAD_PTR ((volatile u32*)(BACKUP_STACK_BASE_ADDR + 0x0))
#define BACKUP_STACK_DATA_BEGIN ((u8*)(BACKUP_STACK_BASE_ADDR + 0x8))
#define BACKUP_STACK_DATA_END ((u8*)(0x80500000u))
#define BACKUP_ALIGN ((u32)4)

void BACKUP_INIT(void);
void* BACKUP_PUSH(const void* src, u32 size);
void* BACKUP_PEEK(u32 depth, u32* out_size);
s32 BACKUP_POP(void); //add variable for "how many times to pop"
s32 BACKUP_POP_MULTIPLE(u32 count);
53 changes: 26 additions & 27 deletions rewrite/src/exe/coll.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,12 @@ static void _COLL_LoadQuadblockData_LowLOD(CollDCache* cache, const Quadblock* q

static void COLL_LoadQuadblockData_LowLOD(CollDCache* cache, const Quadblock* quadblock)
{
#ifdef TEST_COLL_IMPL
*(CollDCache*)(BACKUP_ADDR) = *cache;
#endif
BACKUP_COLL_LoadQuadblockData_LowLOD(cache); //global state before

_COLL_LoadQuadblockData_LowLOD(cache, quadblock);
TEST_COLL_LoadQuadblockData_LowLOD((CollDCache*)(BACKUP_ADDR), quadblock, cache);

BACKUP_COLL_LoadQuadblockData_LowLOD(cache); //global state after (result from decomp)
TEST_COLL_LoadQuadblockData_LowLOD(quadblock, cache);
}

/* Address: 0x8001f6f0 */
Expand Down Expand Up @@ -137,11 +138,12 @@ static void _COLL_LoadQuadblockData_HighLOD(CollDCache* cache, const Quadblock*

static void COLL_LoadQuadblockData_HighLOD(CollDCache* cache, const Quadblock* quadblock)
{
#ifdef TEST_COLL_IMPL
*(CollDCache*)(BACKUP_ADDR) = *cache;
#endif
BACKUP_COLL_LoadQuadblockData_HighLOD(cache); //global state before

_COLL_LoadQuadblockData_HighLOD(cache, quadblock);
TEST_COLL_LoadQuadblockData_HighLOD((CollDCache*)(BACKUP_ADDR), quadblock, cache);

BACKUP_COLL_LoadQuadblockData_HighLOD(cache); //global state after (result from decomp)
TEST_COLL_LoadQuadblockData_HighLOD(quadblock, cache);
}

/* Address: 0x8001f928 */
Expand Down Expand Up @@ -294,6 +296,9 @@ static void _COLL_TestTriangle(CollDCache* cache, const CollVertex* v1, const Co
}
if ((distTriNextPos >= cache->inputHitRadius) || ((!triggerScript) && (distTriNextPos > distTriCurrPos))) { return; }




u32 crossedPlane = false;
const SVec3 deltaPos = {
.x = cache->inputNextPos.x - cache->collInput.quadblock.driverPos.x,
Expand Down Expand Up @@ -382,12 +387,12 @@ static void _COLL_TestTriangle(CollDCache* cache, const CollVertex* v1, const Co

static void COLL_TestTriangle(CollDCache* cache, const CollVertex* v1, const CollVertex* v2, const CollVertex* v3)
{
#ifdef TEST_COLL_IMPL
const u32 backupAddr = BACKUP_ADDR + sizeof(CollDCache);
*(CollDCache*)(backupAddr) = *cache;
#endif
_COLL_TestTriangle(cache, v1, v2, v3);
TEST_COLL_TestTriangle((CollDCache*)(backupAddr), v1, v2, v3, cache);
BACKUP_COLL_TestTriangle(cache); //global state before

_COLL_TestTriangle(cache, v1, v2, v3);

BACKUP_COLL_TestTriangle(cache); //global state after (result from decomp)
TEST_COLL_TestTriangle(v1, v2, v3, cache);
}

/* Address: 0x80020064 */
Expand Down Expand Up @@ -450,19 +455,13 @@ static void _COLL_TestLeaf_Quadblock(const Quadblock* quadblock, CollDCache* cac

void COLL_TestLeaf_Quadblock(const Quadblock* quadblock, CollDCache* cache)
{
#ifdef TEST_COLL_IMPL
*(CollDCache*)(BACKUP_ADDR) = *cache;
#endif
_COLL_TestLeaf_Quadblock(quadblock, cache);
#ifdef TEST_COLL_IMPL
const u32 retAddr = BACKUP_ADDR + sizeof(CollDCache);
*(CollDCache*)(retAddr) = *cache;
*cache = *(CollDCache*)(BACKUP_ADDR);
#endif
TEST_COLL_TestLeaf_Quadblock(quadblock, cache, (CollDCache*)(retAddr));
#ifdef TEST_COLL_IMPL
*cache = *(CollDCache*)(retAddr);
#endif
BACKUP_COLL_TestLeaf_Quadblock(cache); //global state before

_COLL_TestLeaf_Quadblock(quadblock, cache);

BACKUP_COLL_TestLeaf_Quadblock(cache); //global state after (result from decomp)
TEST_COLL_TestLeaf_Quadblock(quadblock, cache);

/* This is a hand written assembly function that breaks the ABI,
and some callers expect the argument registers to be untouched */
__asm__ volatile("move $t9, %0" : : "r"((u32)quadblock));
Expand Down
43 changes: 43 additions & 0 deletions rewrite/src/exe/jitpool.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include <ctr/jitpool.h>
#include <ctr/nd.h>

void JitPool_Clear(JitPool* AP)
{
Item* item = (Item*)AP->ptrPoolData;
LIST_Clear(&AP->free);
LIST_Clear(&AP->taken);
for (s32 i = 0; i < AP->maxItems; i++)
{
LIST_AddFront(&AP->free, item);
//oddly, if AP->itemSize is not aligned to 4 bytes, this will align it DOWN to the nearest 4 byte boundary.
//will this cause clobbering?
item = (struct Item*)((u32)&item->next + (AP->itemSize & 0xfffffffc));
}
}

void JitPool_Init(JitPool* AP, s32 maxItems, s32 itemSize)
{
memset((void*)AP, '\0', sizeof(JitPool));
AP->maxItems = maxItems;
AP->itemSize = itemSize;
AP->poolSize = maxItems * itemSize;
void* poolData = ND_MEMPACK_AllocMem(maxItems * itemSize);
AP->ptrPoolData = poolData;
JitPool_Clear(AP);
}

Item* JitPool_Add(JitPool* AP)
{
Item* item = AP->free.first;
if (item != NULL) {
LIST_RemoveMember(&AP->free, item);
LIST_AddFront(&AP->taken, item);
}
return item;
}

void JitPool_Remove(JitPool* AP, Item* item)
{
LIST_RemoveMember(&AP->taken, item);
LIST_AddFront(&AP->free, item);
}
Loading