From 45208555b8eff2c38fdfb4ce192d1de838c1d5b7 Mon Sep 17 00:00:00 2001 From: Dominik Peters Date: Thu, 1 May 2025 16:35:49 +0200 Subject: [PATCH] match: func_800BCC70 (#539) * match: func_800BCC70 * refac: replace magic value with constant --- README.md | 52 ++++----- include/structs.h | 28 +++-- src/waves.c | 262 +++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 304 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index b65cea23..ab54c68b 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,9 @@ This repo contains a work-in-progress decompilation of Diddy Kong Racing for the All versions are supported, and the US 1.0 version (SHA1 = 0cb115d8716dbbc2922fda38e533b9fe63bb9670) of the game is the default if not specified. -As of April 29, 2025, this is our current score: +As of May 1, 2025, this is our current score: -    Decomp progress: 81.51% +    Decomp progress: 81.98%     Documentation progress: 53.79% @@ -117,30 +117,30 @@ s32 is_drumstick_unlocked(void) { ``` -As of April 29, 2025, this is our current score: +As of May 1, 2025, this is our current score: ``` - ======================================================== - ADVENTURE ONE (ASM -> C Decompilation) - -------- 81.51% Complete (84.33% NON_MATCHING) --------- - # Decompiled functions: 1866 - # GLOBAL_ASM remaining: 85 - # NON_MATCHING functions: 13 - # NON_EQUIVALENT WIP functions: 27 - --------------------- Game Status ---------------------- - Balloons: 39/47, Keys: 4/4, Trophies: 3/5 - T.T. Amulets: 4/4, Wizpig Amulets: 3/4 - -------------------------------------------------------- - We are racing in the rematch against Smokey. (Lap 3/3) - ======================================================== - ADVENTURE TWO (Cleanup & Documentation) - ------------------- 53.79% Complete -------------------- - # Documented functions: 1138 - # Undocumented remaining: 516 - --------------------- Game Status ---------------------- - Balloons: 26/47, Keys: 3/4, Trophies: 2/5 - T.T. Amulets: 2/4, Wizpig Amulets: 2/4 - -------------------------------------------------------- - We are battling in Darkwater Beach. (2 opponents remain) - ======================================================== + ===================================================================== + ADVENTURE ONE (ASM -> C Decompilation) + --------------- 81.98% Complete (84.79% NON_MATCHING) --------------- + # Decompiled functions: 1867 + # GLOBAL_ASM remaining: 84 + # NON_MATCHING functions: 13 + # NON_EQUIVALENT WIP functions: 27 + ---------------------------- Game Status ---------------------------- + Balloons: 39/47, Keys: 4/4, Trophies: 3/5 + T.T. Amulets: 4/4, Wizpig Amulets: 4/4 + --------------------------------------------------------------------- + We are participating in the Trophy Race of Dragon Forest. (Round One) + ===================================================================== + ADVENTURE TWO (Cleanup & Documentation) + -------------------------- 53.79% Complete -------------------------- + # Documented functions: 1138 + # Undocumented remaining: 516 + ---------------------------- Game Status ---------------------------- + Balloons: 26/47, Keys: 3/4, Trophies: 2/5 + T.T. Amulets: 2/4, Wizpig Amulets: 2/4 + --------------------------------------------------------------------- + We are battling in Darkwater Beach. (2 opponents remain) + ===================================================================== ``` diff --git a/include/structs.h b/include/structs.h index c0b3ae2b..4fa7ee67 100644 --- a/include/structs.h +++ b/include/structs.h @@ -10,6 +10,18 @@ #include "gbi.h" #include "PR/libaudio.h" +typedef struct Vec4f { + union { + struct { + f32 x; + f32 y; + f32 z; + f32 w; + }; + f32 f[4]; + }; +} Vec4f; + // Stolen from PD // This hacky structure allows coords to be accessed using // coord->x, coord->y and coord->z, but also as @@ -77,17 +89,15 @@ typedef struct Vec3i { }; } Vec3i; -typedef struct Vec4f { +typedef struct Vec2i { union { - struct { - f32 x; - f32 y; - f32 z; - f32 w; - }; - f32 f[4]; + struct { + s32 x; + s32 y; + }; + s32 i[2]; }; -} Vec4f; +} Vec2i; /* Size: 0x24 / 36 bytes */ typedef struct SoundMask { diff --git a/src/waves.c b/src/waves.c index 0d1e4822..b2f8a00a 100644 --- a/src/waves.c +++ b/src/waves.c @@ -1351,7 +1351,7 @@ void func_800BBF78(LevelModel *model) { if (D_800E30D4 != NULL) { mempool_free(D_800E30D4); } - D_800E30D4 = mempool_alloc_safe(D_8012A0D8 * D_8012A0DC * 4, 0xFFFFFF); + D_800E30D4 = mempool_alloc_safe(D_8012A0D8 * D_8012A0DC * 4, COLOUR_TAG_CYAN); if (D_800E30D8 != NULL) { mempool_free(D_800E30D8); @@ -1360,7 +1360,7 @@ void func_800BBF78(LevelModel *model) { // clang-format off D_800E30D8 = mempool_alloc_safe( (model->numberOfSegments * sizeof(LevelModel_Alternate)) + (D_800E318C * 8) + 0x880, - 0xFFFFFF + COLOUR_TAG_CYAN ); // clang-format on @@ -1517,7 +1517,263 @@ void func_800BC6C8(void) { } } -#pragma GLOBAL_ASM("asm/nonmatchings/waves/func_800BCC70.s") +void func_800BCC70(LevelModel *arg0) { + s32 sp18C; + u32 pad_sp188; + s32 sp184; + s32 var_t2; + s32 var_t4; + s32 var_t8; + f32 var_f20; + f32 var_f22; + f32 var_f24; + f32 var_f26; + f32 var_f28; + s32 var_v0; + s32 sp140[8]; + s32 var_v1; + s32 var_a1; + s32 var_a2; + s32 var_a3; + s32 var_s2; + s32 var_s4; + s32 var_s5; + f32 spAC[30]; + f32 *spA8; + Vec2i *spA4; + u8 *spA0; + + var_s4 = D_80129FC8.unk0; + if (D_80129FC8.unk28 != 0) { + var_s4 *= 2; + } + D_800E317C = (var_s4 + 1) * (var_s4 + 1); + if (D_800E3178 != NULL) { + mempool_free(D_800E3178); + } + D_800E3178 = mempool_alloc_safe(arg0->numberOfSegments * D_800E317C, COLOUR_TAG_CYAN); + spA0 = mempool_alloc_safe(arg0->numberOfSegments * 4, COLOUR_TAG_CYAN); + spA4 = mempool_alloc_safe((D_8012A0D8 * D_8012A0DC) * 8, COLOUR_TAG_CYAN); + spA8 = mempool_alloc_safe((var_s4 * 4) + 4, COLOUR_TAG_CYAN); + + // temp assignment required for match + pad_sp188 = -1; + for (var_a3 = 0; var_a3 < (D_8012A0D8 * D_8012A0DC); var_a3++) { + spA4[var_a3].i[0] = -1; + spA4[var_a3].i[1] = pad_sp188; + } + + for (var_t2 = 0; var_t2 <= var_s4; var_t2++) { + spA8[var_t2] = (((var_s4 - (var_t2 << 1)) / (f32) var_s4) * 8.0f); + } + + var_f26 = D_8012A0A0 / var_s4; + var_f28 = D_8012A0A4 / var_s4; + for (sp18C = 0, var_s5 = 0; sp18C < arg0->numberOfSegments; sp18C++) { + if (D_8012A0E8[D_800E30D8[sp18C].unkB] & (1 << D_800E30D8[sp18C].unkA)) { + spA4[(D_800E30D8[sp18C].unkB * D_8012A0D8) + D_800E30D8[sp18C].unkA].i[0] = sp18C; + spA4[(D_800E30D8[sp18C].unkB * D_8012A0D8) + D_800E30D8[sp18C].unkA].i[1] = var_s5; + var_f20 = D_800E30D8[sp18C].unk6; + var_f24 = D_800E30D8[sp18C].unk8; + for (sp184 = 0; sp184 <= var_s4; sp184++) { + var_f22 = D_800E30D8[sp18C].unk4; + for (var_t2 = 0; var_t2 <= var_s4; var_t2++) { + // var_v0 stores the length of spAC + var_v0 = func_8002BAB0(sp18C, spA8[var_t2] + var_f22, spA8[sp184] + var_f24, spAC); + if (var_v0 == 0) { + var_a2 = 0xFF; + } else { + var_v1 = 0; + while (var_v1 < var_v0 - 1 && var_f20 <= spAC[var_v1]) { + var_v1++; + } + if (var_f20 < spAC[var_v1]) { + var_a2 = 0; + } else if (var_f20 == spAC[var_v1]) { + var_a2 = 0xFF; + } else { + var_a2 = (var_f20 - spAC[var_v1]) * D_80129FC8.unk48; + if (var_a2 > 0x1FF) { + var_a2 = 0x1FF; + } + var_a2 >>= 1; + } + } + D_800E3178[var_s5++] = var_a2; + var_f22 += var_f26; + } + var_f24 += var_f28; + } + } else { + // clang-format off + // @note \ required here + for (var_t2 = 0; var_t2 < D_800E317C; var_t2++) { \ + D_800E3178[var_s5++] = 0xFF; + } + // clang-format on + } + } + + for (sp184 = 0; sp184 < D_8012A0DC; sp184++) { + for (var_t2 = 0; var_t2 < D_8012A0D8; var_t2++) { + var_t4 = spA4[(sp184 * D_8012A0D8) + var_t2].i[1]; + if (var_t4 != -1) { + if (sp184 < (D_8012A0DC - 1)) { + var_v0 = spA4[((sp184 + 1) * D_8012A0D8) + var_t2].i[1]; + if (var_v0 != -1) { + var_a1 = ((var_s4 + 1) * var_s4) + var_t4 + 1; + var_v1 = var_v0 + 1; + for (var_a3 = 0; var_a3 < var_s4 - 1; var_a3++) { + var_a2 = (D_800E3178[var_a1] + D_800E3178[var_v1]) >> 1; + D_800E3178[var_a1] = var_a2; + D_800E3178[var_v1] = var_a2; + var_v1++; + var_a1++; + } + } + } + if (var_t2 < (D_8012A0D8 - 1)) { + var_v0 = spA4[(sp184 * D_8012A0D8) + var_t2 + 1].i[1]; + if (var_v0 != -1) { + var_a1 = (var_s4 * 2) + var_t4 + 1; + var_v1 = var_v0 + var_s4 + 1; + for (var_a3 = 0; var_a3 < var_s4 - 1; var_a3++) { + var_a2 = (D_800E3178[var_a1] + D_800E3178[var_v1]) >> 1; + D_800E3178[var_a1] = var_a2; + if (!var_v1) {} + D_800E3178[var_v1] = var_a2; + var_v1 += var_s4; + var_v1++; + var_a1 += var_s4; + var_a1++; + } + } + } + } + } + } + + for (var_t4 = 0, sp18C = 0; sp18C < arg0->numberOfSegments; sp18C++, var_t4 += D_800E317C) { + spA0[(sp18C * 4) + 0] = D_800E3178[var_t4]; + spA0[(sp18C * 4) + 1] = D_800E3178[var_t4 + (var_s4)]; + spA0[(sp18C * 4) + 2] = D_800E3178[var_t4 + ((var_s4 + 1) * var_s4)]; + spA0[(sp18C * 4) + 3] = D_800E3178[var_t4 + ((var_s4 + 1) * (var_s4 + 1)) - 1]; + } + + for (var_t4 = 0, sp18C = 0; sp18C < arg0->numberOfSegments; sp18C++, var_t4 += D_800E317C) { + var_s5 = (D_800E30D8[sp18C].unkB * D_8012A0D8) + D_800E30D8[sp18C].unkA; + if (spA4[var_s5].i[0] != -1) { + for (var_a3 = 0; var_a3 < ARRAY_COUNT(sp140); var_a3++) { + sp140[var_a3] = -1; + } + + if (D_800E30D8[sp18C].unkB > 0) { + if (D_800E30D8[sp18C].unkA > 0) { + sp140[0] = spA4[var_s5 - D_8012A0D8 - 1].i[0]; + } + sp140[1] = spA4[var_s5 - D_8012A0D8].i[0]; + if (D_800E30D8[sp18C].unkA < D_8012A0D8 - 1) { + sp140[2] = spA4[var_s5 - D_8012A0D8 + 1].i[0]; + } + } + + if (D_800E30D8[sp18C].unkA > 0) { + sp140[3] = spA4[var_s5 - 1].i[0]; + } + + if (D_800E30D8[sp18C].unkA < (D_8012A0D8 - 1)) { + sp140[4] = spA4[var_s5 + 1].i[0]; + } + + if (D_800E30D8[sp18C].unkB < (D_8012A0DC - 1)) { + if (D_800E30D8[sp18C].unkA > 0) { + sp140[5] = spA4[var_s5 + D_8012A0D8 - 1].i[0]; + } + sp140[6] = spA4[var_s5 + D_8012A0D8].i[0]; + if (D_800E30D8[sp18C].unkA < D_8012A0D8 - 1) { + sp140[7] = spA4[var_s5 + D_8012A0D8 + 1].i[0]; + } + } + + var_a3 = 1; + var_a2 = spA0[sp18C * 4]; + if (sp140[0] != -1) { + var_a3++; + var_a2 += spA0[(sp140[0] * 4) + 3]; + } + + if (sp140[1] != -1) { + var_a3++; + var_a2 += spA0[(sp140[1] * 4) + 2]; + } + + if (sp140[3] != -1) { + var_a3++; + var_a2 += spA0[(sp140[3] * 4) + 1]; + } + D_800E3178[var_t4] = var_a2 / var_a3; + + var_a2 = spA0[(sp18C * 4) + 1]; + var_a3 = 1; + if (sp140[1] != -1) { + var_a3++; + var_a2 += spA0[(sp140[1] * 4) + 3]; + } + + if (sp140[2] != -1) { + var_a3++; + var_a2 += spA0[(sp140[2] * 4) + 2]; + } + + if (sp140[4] != -1) { + var_a3++; + var_a2 += spA0[sp140[4] * 4]; + } + D_800E3178[var_t4 + var_s4] = var_a2 / var_a3; + + var_a2 = spA0[(sp18C * 4) + 2]; + var_a3 = 1; + if (sp140[3] != -1) { + var_a3++; + var_a2 += spA0[(sp140[3] * 4) + 3]; + } + + if (sp140[5] != -1) { + var_a3++; + var_a2 += spA0[(sp140[5] * 4) + 1]; + } + + if (sp140[6] != -1) { + var_a3++; + var_a2 += spA0[sp140[6] * 4]; + } + D_800E3178[var_t4 + ((var_s4 + 1) * var_s4)] = var_a2 / var_a3; + + var_a2 = spA0[(sp18C * 4) + 3]; + var_a3 = 1; + if (sp140[4] != -1) { + var_a3++; + var_a2 += spA0[(sp140[4] * 4) + 2]; + } + + if (sp140[6] != -1) { + var_a3++; + var_a2 += spA0[(sp140[6] * 4) + 1]; + } + + if (sp140[7] != -1) { + var_a3++; + var_a2 += spA0[sp140[7] * 4]; + } + + D_800E3178[var_t4 + ((var_s4 + 1) * (var_s4 + 1)) - 1] = var_a2 / var_a3; + } + } + + mempool_free(spA8); + mempool_free(spA4); + mempool_free(spA0); +} #ifdef NON_EQUIVALENT typedef struct unkArg1 {