From 2bff09bb74e1606ffd7d7ac8c46ab02ac298995a Mon Sep 17 00:00:00 2001 From: Ethan Lafrenais Date: Fri, 8 Nov 2024 18:20:54 -0500 Subject: [PATCH] Some segment_5660 decomp (#94) * Unrelated typos :( * Match a bunch of segment_5660 funcs * Little more segment_5660 progress * Match a few more functions * Fix bad math.h merge * More stuff from stash --- include/sys/math.h | 4 + src/segment_5660.c | 393 ++++++++++++++++++++++++++++++++-- symbol_addrs.txt | 2 + tools/dino/dll_imports_tab.py | 2 +- tools/dino/dll_tab.py | 2 +- undefined_funcs.txt | 2 + 6 files changed, 390 insertions(+), 15 deletions(-) diff --git a/include/sys/math.h b/include/sys/math.h index d6c23be..04aedc1 100644 --- a/include/sys/math.h +++ b/include/sys/math.h @@ -15,6 +15,10 @@ typedef struct { f32 x, y, z; } Vec3f; +typedef struct { + f32 x, y, z, w; +} Vec4f; + typedef struct { s32 x, y, z; } Vec3s32; diff --git a/src/segment_5660.c b/src/segment_5660.c index d4c7ddf..46af75d 100644 --- a/src/segment_5660.c +++ b/src/segment_5660.c @@ -1,30 +1,272 @@ +// curves.c? + #include "common.h" -#pragma GLOBAL_ASM("asm/nonmatchings/segment_5660/func_80004A60.s") +typedef f32 (*unk_curve_func)(Vec4f*, f32, f32*); // TODO: first arg is actually f32[4] +typedef void (*unk_curve_func_2)(f32*, f32*); +typedef struct { + /* 0000 */ f32 unk0x0; + /* 0004 */ f32 unk0x4; + /* 0008 */ f32 unk0x8; + /* 000C */ f32 unk0xC; + /* 0010 */ s32 unk0x10; + /* 0014 */ f32 unk0x14; + /* 0018 */ f32 unk0x18[19]; // unsure of length + /* 0064 */ f32 unk0x64; + /* 0068 */ f32 unk0x68; + /* 006C */ f32 unk0x6C; + /* 0070 */ f32 unk0x70; + /* 0074 */ f32 unk0x74; + /* 0078 */ f32 unk0x78; + /* 007C */ f32 unk0x7C; + /* 0080 */ s32 unk0x80; + /* 0084 */ f32 *unk0x84; + /* 0088 */ f32 *unk0x88; + /* 008C */ f32 *unk0x8C; + /* 0090 */ s32 unk0x90; + /* 0094 */ unk_curve_func unk0x94; + /* 0098 */ s32 unk0x98; +} UnkCurvesStruct; + +extern s32 D_8008C7D0; + +extern f32 D_800984FC; // 1.0f / 60.0f +extern f32 D_80098500; // 1.0f / 60.0f +extern f32 D_80098504; // 1.0f / 60.0f + +extern f32 D_800A7C30[4]; +extern f32 D_800A7C40; + +void func_80004B78(Vec4f *a0, Vec4f *a1); +void func_80004CE8(Vec4f *in, Vec4f *out); +void func_80004DFC(Vec4f *in, Vec4f *out); +void func_800065C0(UnkCurvesStruct *, s32); + +// // // bezier? + +f32 func_80004A60(Vec4f *a0, f32 a1, f32 *a2) { + Vec4f v; + + v.x = a0->w + (((3.0f * a0->y) - a0->x) + (-3.0f * a0->z)); + v.y = (3.0f * a0->z) + ((3.0f * a0->x) + (-6.0f * a0->y)); + v.z = (3.0f * a0->z) + (-3.0f * a0->x); + v.w = a0->z + (a0->x + (4.0f * a0->y)); + + v = v; // from permuter + + if (a2 != NULL) { + *a2 = ((v.z * 1.0f) + ((((3.0f * v.x) * a1) + (v.y + v.y)) * a1)) * D_800984FC; + } + + return ((v.w * 1.0f) + ((((v.x * a1) + v.y) * a1) + v.z) * a1) * D_80098500; +} + +#if 1 #pragma GLOBAL_ASM("asm/nonmatchings/segment_5660/func_80004B78.s") +#else +// Functionally equivalent +void func_80004B78(Vec4f *a0, Vec4f *a1) { + f32 temp = D_80098504; -#pragma GLOBAL_ASM("asm/nonmatchings/segment_5660/func_80004C5C.s") + a1->x = a0->w + (((3.0f * a0->y) - a0->x) + (-3.0f * a0->z)); + a1->y = (3.0f * a0->z) + ((3.0f * a0->x) + (-6.0f * a0->y)); + a1->z = (3.0f * a0->z) + (-3.0f * a0->x); + a1->w = a0->z + (a0->x + (4.0f * a0->y)); + + a1->x *= temp; + a1->y *= temp; + a1->z *= temp; + a1->w *= temp; +} +#endif -#pragma GLOBAL_ASM("asm/nonmatchings/segment_5660/func_80004CE8.s") +f32 func_80004C5C(Vec4f *a0, f32 a1, f32 *a2) { + Vec4f v; -#pragma GLOBAL_ASM("asm/nonmatchings/segment_5660/func_80004D70.s") + func_80004CE8(a0, &v); -#pragma GLOBAL_ASM("asm/nonmatchings/segment_5660/func_80004DFC.s") + if (a2 != NULL) { + *a2 = (v.z * 1.0f) + (((3.0f * v.x * a1) + (v.y + v.y)) * a1); + } -#pragma GLOBAL_ASM("asm/nonmatchings/segment_5660/func_80004E90.s") + return (v.w * 1.0f) + ((((v.x * a1 + v.y) * a1) + v.z) * a1); +} -#pragma GLOBAL_ASM("asm/nonmatchings/segment_5660/func_80004F90.s") +void func_80004CE8(Vec4f *in, Vec4f *out) { + out->x = in->w + ((in->x + in->x) + (-2.0f * in->y) + in->z); + out->y = -in->w + ((-3.0f * in->x) + (3.0f * in->y) + (-2.0f * in->z)); + out->z = in->z; + out->w = in->x; +} -#pragma GLOBAL_ASM("asm/nonmatchings/segment_5660/func_80005060.s") +// // // hermite? -#pragma GLOBAL_ASM("asm/nonmatchings/segment_5660/func_80005084.s") +f32 func_80004D70(Vec4f *a0, f32 a1, f32 *a2) { + Vec4f v; -#pragma GLOBAL_ASM("asm/nonmatchings/segment_5660/func_80005094.s") + func_80004DFC(a0, &v); -#pragma GLOBAL_ASM("asm/nonmatchings/segment_5660/func_8000523C.s") + if (a2 != NULL) { + *a2 = (v.z * 1.0f) + (((3.0f * v.x * a1) + (v.y + v.y)) * a1); + } -#pragma GLOBAL_ASM("asm/nonmatchings/segment_5660/func_8000535C.s") + return (v.w * 1.0f) + ((((v.x * a1 + v.y) * a1) + v.z) * a1); +} + +void func_80004DFC(Vec4f *in, Vec4f *out) { + out->x = in->w + (((3.0f * in->y) - in->x) + (-3.0f * in->z)); + out->y = (3.0f * in->z) + ((3.0f * in->x) + (-6.0f * in->y)); + out->z = (3.0f * in->y) + (-3.0f * in->x); + out->w = in->x; +} + +f32 func_80004E90(Vec4f *a0, f32 a1, f32 *a2) { + Vec4f v; + f32 temp; + + v.x = a0->w + (((3.0f * a0->y) - a0->x) + (-3.0f * a0->z)); + v.y = -a0->w + (((a0->x + a0->x) + (-5.0f * a0->y)) + (4.0f * a0->z)); + v.z = a0->z - a0->x; + temp = a0->y; + v.w = temp + temp; + + v = v; // from permuter + + if (a2 != NULL) { + *a2 = (v.z * 1.0f) + ((((3.0f * v.x) * a1) + (v.y + v.y)) * a1); + } + + return ((v.w * 1.0f) + (((((v.x * a1) + v.y) * a1) + v.z) * a1)) * 0.5f; +} + +void func_80004F90(Vec4f *a0, Vec4f *a1) { + f32 temp; + a1->x = a0->w + (((3.0f * a0->y) - a0->x) + (-3.0f * a0->z)); + a1->y = -a0->w + (((a0->x + a0->x) + (-5.0f * a0->y)) + (4.0f * a0->z)); + a1->z = a0->z - a0->x; + temp = a0->y; + a1->w = temp + temp; + + a1->x *= 0.5f; + a1->y *= 0.5f; + a1->z *= 0.5f; + a1->w *= 0.5f; +} + +// // // + +f32 linear_interp(f32 values[2], f32 time, void *a2) { + return values[0] + (values[1] - values[0]) * time; +} + +void func_80005084(void *a0, void *a1) { + +} + +void func_80005094(UnkCurvesStruct *arg0) { + if (arg0->unk0x90) { + + } + if ((arg0->unk0x94 == &func_80004D70) || (arg0->unk0x94 == &func_80004C5C)) { + + } + + arg0->unk0x10 = 0; + arg0->unk0xC = 0.0f; + + while (arg0->unk0x10 < (arg0->unk0x90 - 3)) { + func_800065C0(arg0, 5); + + arg0->unk0xC += arg0->unk0x14; + + if ((arg0->unk0x94 == &func_80004D70) || (arg0->unk0x94 == &func_80004C5C)) { + arg0->unk0x10 += 4; + } else { + arg0->unk0x10 += 1; + } + } + + if (arg0->unk0x80 != 0) { + arg0->unk0x10 = arg0->unk0x90 - 4; + } else { + arg0->unk0x10 = 0; + } + + func_800065C0(arg0, 0x14); + + if (arg0->unk0x80 != 0) { + arg0->unk0x0 = 1.0f; + arg0->unk0x4 = arg0->unk0x64; + arg0->unk0x8 = arg0->unk0xC; + } else { + arg0->unk0x0 = 0.0f; + arg0->unk0x4 = 0.0f; + arg0->unk0x8 = 0.0f; + } + + if (arg0->unk0x84 != NULL) { + arg0->unk0x68 = arg0->unk0x94(arg0->unk0x84, arg0->unk0x0, &arg0->unk0x74); + } + if (arg0->unk0x88 != NULL) { + arg0->unk0x6C = arg0->unk0x94(arg0->unk0x88, arg0->unk0x0, &arg0->unk0x78); + } + if (arg0->unk0x8C != NULL) { + arg0->unk0x70 = arg0->unk0x94(arg0->unk0x8C, arg0->unk0x0, &arg0->unk0x7C); + } +} + +void func_8000523C(UnkCurvesStruct *arg0) { + if (arg0->unk0x90) { + + } + if ((arg0->unk0x94 == &func_80004D70) || (arg0->unk0x94 == &func_80004C5C)) { + + } + + arg0->unk0x10 = 0; + arg0->unk0xC = 0.0f; + + while (arg0->unk0x10 < (arg0->unk0x90 - 3)) { + func_800065C0(arg0, 5); + + arg0->unk0xC += arg0->unk0x14; + + if ((arg0->unk0x94 == &func_80004D70) || (arg0->unk0x94 == &func_80004C5C)) { + arg0->unk0x10 += 4; + } else { + arg0->unk0x10 += 1; + } + } + + if (arg0->unk0x80 != 0) { + arg0->unk0x10 = arg0->unk0x90 - 4; + } else { + arg0->unk0x10 = 0; + } + + func_800065C0(arg0, 0x14); + + if (arg0->unk0x80 != 0) { + arg0->unk0x8 = arg0->unk0xC - arg0->unk0x4; + } else { + arg0->unk0x8 = arg0->unk0x4; + } +} + +void func_8000535C(UnkCurvesStruct *arg0) { + if (arg0->unk0x80 != 0) { + arg0->unk0x0 = 1.0f; + arg0->unk0x4 = arg0->unk0x64; + arg0->unk0x8 = arg0->unk0xC; + arg0->unk0x10 = arg0->unk0x90 - 4; + } else { + arg0->unk0x0 = 0.0f; + arg0->unk0x4 = 0.0f; + arg0->unk0x8 = 0.0f; + arg0->unk0x10 = 0; + } +} #pragma GLOBAL_ASM("asm/nonmatchings/segment_5660/func_800053B0.s") @@ -32,13 +274,138 @@ #pragma GLOBAL_ASM("asm/nonmatchings/segment_5660/func_80005E60.s") -#pragma GLOBAL_ASM("asm/nonmatchings/segment_5660/func_800065C0.s") +void func_800065C0(UnkCurvesStruct *arg0, s32 arg1) { + f32 *phi_s4; + f32 *phi_s5; + f32 *phi_s6; + f32 xCoords[21]; + f32 yCoords[21]; + f32 zCoords[21]; + f32 xDist; + f32 yDist; + f32 zDist; + s32 i; + + phi_s4 = 0; + phi_s5 = 0; + phi_s6 = 0; + + if (arg0->unk0x84 != 0) { + phi_s4 = &arg0->unk0x84[arg0->unk0x10]; + } + if (arg0->unk0x88 != 0) { + phi_s5 = &arg0->unk0x88[arg0->unk0x10]; + } + if (arg0->unk0x8C != 0) { + phi_s6 = &arg0->unk0x8C[arg0->unk0x10]; + } + + if (arg0->unk0x98 != 0) { + func_8000598C(phi_s4, phi_s5, phi_s6, &xCoords, &yCoords, &zCoords, arg1, arg0->unk0x98); + } else { + + } + + arg0->unk0x14 = 0.0f; + + for (i = 0; i < arg1; ++i) { + // Find distance between current and next coord + if (phi_s4 != 0) { + xDist = xCoords[i + 1] - xCoords[i]; + } else { + xDist = 0.0f; + } + + if (phi_s5 != 0) { + yDist = yCoords[i + 1] - yCoords[i]; + } else { + yDist = 0.0f; + } + + if (phi_s6 != 0) { + zDist = zCoords[i + 1] - zCoords[i]; + } else { + zDist = 0.0f; + } + + // Compute distance between current and next coord + arg0->unk0x18[i] = sqrtf((xDist * xDist) + (yDist * yDist) + (zDist * zDist)); + // Sum distances + arg0->unk0x14 += arg0->unk0x18[i]; + } +} #pragma GLOBAL_ASM("asm/nonmatchings/segment_5660/func_80006784.s") #pragma GLOBAL_ASM("asm/nonmatchings/segment_5660/func_80006908.s") +#if 1 #pragma GLOBAL_ASM("asm/nonmatchings/segment_5660/func_80006B28.s") +#else +typedef struct { + /* 0x0 */ Vec4f unk0x0; + /* 0x10 */ Vec4f unk0x10; + /* 0x20 */ f32 unk0x20; +} UnkCurveStruct1; + +typedef struct { + /* 0x0 */ f32 unk0x0; + /* 0x4 */ f32 unk0x4; +} UnkCurveStruct2; + +void func_80006B28(UnkCurveStruct2 *arg0, s32 arg1, UnkCurveStruct1 *arg2) { + Vec4f sp88; + Vec4f sp78; + Vec4f sp68; + UnkCurveStruct2 *phi_v0; + f32 *phi_a0; + f32 *phi_v1; + s32 i; + s32 end; + + end = arg1 - 1; + i = 0; + if (end > 0) { + phi_v0 = arg0[i - 1]; + phi_a0 = &sp88; + phi_v1 = &sp78; + + do { + if ((i - 1) < 0) { + *phi_a0 = (phi_v0->unk8 - phi_v0->unk10) + phi_v0->unk8; // v[i].z - v[i+1].x + v[i].z + *phi_v1 = (phi_v0->unkC - phi_v0->unk14) + phi_v0->unkC; // v[i].w - v[i+1].y + v[i].z + } else if ((i - 1) >= arg1) { + *phi_a0 = (phi_v0->unk-8 - phi_v0->unk-10) + phi_v0->unk-8; // v[i-1].z - v[i-1].x + v[i-1].z + *phi_v1 = (phi_v0->unk-4 - phi_v0->unk-C) + phi_v0->unk-4; // v[i-1].w - v[i-1].y + v[i-1].w + } else { + *phi_a0 = phi_v0->unk0; // v[i].x + *phi_v1 = phi_v0->unk4; // v[i].y + } + phi_a0 += 4; + phi_v1 = phi_v1 + 4; + if (phi_v1 != &sp88) { + continue; + } + + func_80004B78(&sp88, &sp68); + arg2[i].unk0x0.x = sp68.x; + arg2[i].unk0x0.y = sp68.y; + arg2[i].unk0x0.z = sp68.z; + arg2[i].unk0x0.w = sp68.w; + func_80004B78(&sp78, &sp68); + arg2[i].unk0x10.x = sp68.x; + arg2[i].unk0x10.y = sp68.y; + arg2[i].unk0x10.z = sp68.z; + arg2[i].unk0x10.w = sp68.w; + arg2[i].unk0x20 = func_80004A60(&sp78, 0, 0); + + i = i + 1; + } while (i != end); + } + arg2[0].unk0x20 = 0.0f; + arg2[arg1 - 1].unk0x20 = 1.0f; +} +#endif #pragma GLOBAL_ASM("asm/nonmatchings/segment_5660/func_80006CFC.s") diff --git a/symbol_addrs.txt b/symbol_addrs.txt index 958ade7..ceef5a1 100644 --- a/symbol_addrs.txt +++ b/symbol_addrs.txt @@ -1304,3 +1304,5 @@ generic_stack_is_full = 0x8000B29C; // type:func generic_stack_is_empty = 0x8000B2B8; // type:func fit_aabb_around_cubes = 0x80053438; // type:func + +linear_interp = 0x80005060; // type:func diff --git a/tools/dino/dll_imports_tab.py b/tools/dino/dll_imports_tab.py index 74be4be..2760b9b 100644 --- a/tools/dino/dll_imports_tab.py +++ b/tools/dino/dll_imports_tab.py @@ -5,7 +5,7 @@ class DLLImportsTab: def __init__(self, imports: "list[int]") -> None: self.imports = imports """A mapping of import index to base executable pointer. Each pointer - refers to non-DLL VRAM (e.g. >=0x80000000)""" + refers to non-DLL VRAM (i.e. >=0x80000000)""" @staticmethod def parse(data: bytearray) -> "DLLImportsTab": diff --git a/tools/dino/dll_tab.py b/tools/dino/dll_tab.py index 71ab6e6..db7dbf0 100644 --- a/tools/dino/dll_tab.py +++ b/tools/dino/dll_tab.py @@ -32,7 +32,7 @@ class DLLTab: # for the second to last entry. start_offset, bss_size, end_offset = struct.unpack_from(">III", data, offset) - # DLLS.tab ends with 16 bytes of 0xF + # DLLS.tab ends with 8 bytes of 0xFF if end_offset == 0xFFFF_FFFF: break diff --git a/undefined_funcs.txt b/undefined_funcs.txt index b0634bc..3f2bde3 100644 --- a/undefined_funcs.txt +++ b/undefined_funcs.txt @@ -14,3 +14,5 @@ func_80080E00 = 0x80080E00; func_80089718 = 0x80089718; func_8008972C = 0x8008972C; func_8003cd7c = 0x8003cd7c; +func_800065C0 = 0x800065C0; +func_8000598C = 0x8000598C;