Match func_80026430 and fix UB in func_80026070 (#516)

* Score and formatting

* Fix UB for func_80026070, and get func_80026430 to NON_EQ

* func_80026430 near match

* documenting

* Single diff for func_80026430

* Match func_80026430

* Update score and merge master

* Rework func_80026430 to have an AVOID_UB.
This commit is contained in:
Ryan Myers
2025-04-16 15:27:28 -04:00
committed by GitHub
parent a2636b9708
commit a298ec5b5f
5 changed files with 165 additions and 41 deletions
+10 -10
View File
@@ -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.
<!-- README_SCORE_SUMMARY_BEGIN -->
As of April 14, 2025, this is our current score:
As of April 16, 2025, this is our current score:
&emsp;&emsp;&emsp;&emsp;Decomp progress: 78.93%
&emsp;&emsp;&emsp;&emsp;Decomp progress: 79.16%
&emsp;&emsp;&emsp;&emsp;Documentation progress: 50.05%
<!-- README_SCORE_SUMMARY_END -->
@@ -117,25 +117,25 @@ s32 is_drumstick_unlocked(void) {
```
<!-- README_SCORE_BEGIN -->
As of April 14, 2025, this is our current score:
As of April 16, 2025, this is our current score:
```
===================================================================
ADVENTURE ONE (ASM -> C Decompilation)
-------------- 78.93% Complete (81.50% NON_MATCHING) --------------
# Decompiled functions: 1851
# GLOBAL_ASM remaining: 100
# NON_MATCHING functions: 12
# NON_EQUIVALENT WIP functions: 29
-------------- 79.16% Complete (81.99% NON_MATCHING) --------------
# Decompiled functions: 1852
# GLOBAL_ASM remaining: 98
# NON_MATCHING functions: 13
# NON_EQUIVALENT WIP functions: 28
--------------------------- Game Status ---------------------------
Balloons: 38/47, Keys: 4/4, Trophies: 3/5
T.T. Amulets: 4/4, Wizpig Amulets: 3/4
-------------------------------------------------------------------
We are collecting silver coins in Haunted Woods. (0/8 silver coins)
We are collecting silver coins in Haunted Woods. (2/8 silver coins)
===================================================================
ADVENTURE TWO (Cleanup & Documentation)
------------------------- 50.05% Complete -------------------------
# Documented functions: 1090
# Undocumented remaining: 564
# Undocumented remaining: 563
--------------------------- Game Status ---------------------------
Balloons: 25/47, Keys: 3/4, Trophies: 2/5
T.T. Amulets: 2/4, Wizpig Amulets: 2/4
+8 -1
View File
@@ -666,6 +666,13 @@ typedef struct ObjectModel {
/* 0x54 */ u8 pad[0x2C];
} ObjectModel;
typedef struct CollisionNode {
u16 triangleIndex; // This triangle index
u16 closestTri01; // The closest triangle index to the line made from indices 0 & 1.
u16 closestTri12; // The closest triangle index to the line made from indices 1 & 2.
u16 closestTri20; // The closest triangle index to the line made from indices 2 & 0.
} CollisionNode;
/* Size: 0x44 bytes */
typedef struct LevelModelSegment {
/* 0x00 */ Vertex *vertices;
@@ -673,7 +680,7 @@ typedef struct LevelModelSegment {
/* 0x08 */ s32 unk8;
/* 0x0C */ TriangleBatchInfo *batches;
/* 0x10 */ s16 *unk10;
/* 0x14 */ u16 *unk14;
/* 0x14 */ CollisionNode *unk14;
/* 0x18 */ f32 *unk18;
/* 0x1C */ s16 numberOfVertices;
/* 0x1E */ s16 numberOfTriangles;
+2 -4
View File
@@ -5611,11 +5611,9 @@ void pakmenu_render(UNUSED s32 updateRate) {
set_current_text_colour(6, 255, 255, 255, 0, 255);
set_current_text_background_colour(6, 0, 0, 0, 0);
render_dialogue_text(6, POS_CENTRED, 2 - PAKMENU_JP_OFFSET, gMenuText[ASSET_MENU_TEXT_CONTPAK1 + gMenuOption],
1,
HORZ_ALIGN_CENTER); // CONTROLLER PAK 1 / 2 / 3 / 4
1, HORZ_ALIGN_CENTER); // CONTROLLER PAK 1 / 2 / 3 / 4
render_dialogue_text(6, POS_CENTRED, 16 - PAKMENU_JP_OFFSET, gMenuText[ASSET_MENU_TEXT_FREEPAGESX],
sCurrentControllerPakFreePages,
HORZ_ALIGN_CENTER); // FREE PAGES: ~
sCurrentControllerPakFreePages, HORZ_ALIGN_CENTER); // FREE PAGES: ~
render_dialogue_box(&sMenuCurrDisplayList, NULL, NULL, 6);
yPos += 34; // To 82
+139 -19
View File
@@ -643,16 +643,15 @@ void func_8002581C(u8 *segmentIds, s32 numberOfSegments, s32 viewportIndex) {
void func_80026070(LevelModelSegmentBoundingBox *arg0, f32 arg1, f32 arg2, f32 arg3) {
f32 sp80[4];
f32 sp70[4];
s16 temp2;
s32 pad;
f32 sp60[2];
s16 index;
s16 nextIndex;
f32 sp60[4];
f32 temp;
f32 sp54[2];
f32 sp4C[2];
f32 temp;
s16 index;
s16 nextIndex;
s16 sp40[4];
s16 var_t0;
s16 temp2;
sp80[0] = arg0->x1;
sp70[0] = arg0->z1;
@@ -701,10 +700,8 @@ void func_80026070(LevelModelSegmentBoundingBox *arg0, f32 arg1, f32 arg2, f32 a
// Returns must be on the same line.
// clang-format off
if (-300.0 > sp60[1]) { return;
}
if (sp60[0] > 300.0) { return;
}
if (-300.0 > sp60[1]) { return; }
if (sp60[0] > 300.0) { return; }
// clang-format on
if (sp60[0] < -300.0) {
@@ -718,7 +715,132 @@ void func_80026070(LevelModelSegmentBoundingBox *arg0, f32 arg1, f32 arg2, f32 a
}
}
#pragma GLOBAL_ASM("asm/nonmatchings/tracks/func_80026430.s")
void func_80026430(LevelModelSegment *segment, f32 arg1, f32 arg2, f32 arg3) {
s16 i;
s16 index;
s16 verticesOffset;
s16 nextFaceOffset;
s16 nextIndex;
s16 currFaceOffset;
s16 j;
Vertex *vert;
s8 spF8[3];
f32 temp;
s16 var_s0;
s16 var_t0;
#ifdef AVOID_UB
f32 spE8[3]; // This really should be size of 3, but something is keeping it from matching that way.
#else
f32 spE8[2];
#endif
f32 spDC[3];
f32 spD0[3];
f32 spC4[3];
f32 spB8[3];
f32 spB0[2];
f32 spA8[2];
f32 spA0[2];
if (D_8011D49E >= D_8011D4BA) {
return;
}
for (i = 0; i < segment->numberOfBatches; i++) {
currFaceOffset = segment->batches[i].facesOffset;
verticesOffset = segment->batches[i].verticesOffset;
nextFaceOffset = segment->batches[i + 1].facesOffset;
if (segment->batches[i].flags & (BATCH_FLAGS_HIDDEN | BATCH_FLAGS_UNK00000200)) {
currFaceOffset = nextFaceOffset;
}
for (j = currFaceOffset; j < nextFaceOffset; j++) {
if ((segment->triangles[j].flags & BACKFACE_DRAW)) {
continue;
}
var_t0 = 0;
for (index = 0; index < 3; index++) {
vert = &(segment->triangles[j].verticesArray[index + 1] + verticesOffset)[segment->vertices];
spE8[index] = vert->x;
spDC[index] = vert->y;
spD0[index] = vert->z;
spC4[index] = (arg1 * spE8[index]) + (arg2 * spD0[index]) + arg3;
spF8[index] = (spC4[index] <= 0.0);
var_t0 += (spF8[index] <= 0.0);
}
if ((var_t0 == 1) || (var_t0 == 2)) {
for (var_s0 = 0, index = 0; index < 3; index++) {
nextIndex = index + 1;
if (nextIndex >= 3) {
nextIndex = 0;
}
if ((spF8[nextIndex] != spF8[index]) != 0) {
temp = spC4[index] / (spC4[index] - spC4[nextIndex]);
spB0[var_s0] = spE8[index] + ((spE8[nextIndex] - spE8[index]) * temp);
spB8[var_s0] = spDC[index] + ((spDC[nextIndex] - spDC[index]) * temp);
spA0[var_s0] = spB8[var_s0];
spA8[var_s0] = spD0[index] + ((spD0[nextIndex] - spD0[index]) * temp);
var_s0++;
}
}
var_s0 = 0;
spF8[0] = 0;
spF8[1] = 0;
spC4[0] = (D_8011D4A0 * spB0[0]) + (D_8011D4A4 * spA8[0]) + D_8011D4A8;
spC4[1] = (D_8011D4A0 * spB0[1]) + (D_8011D4A4 * spA8[1]) + D_8011D4A8;
if (spC4[0] < -300.0) {
spF8[0] = 1;
}
if (spC4[0] > 300.0) {
spF8[0] |= 2;
}
if (spC4[1] < -300.0) {
spF8[1] = 1;
}
if (spC4[1] > 300.0) {
spF8[1] |= 2;
}
// clang-format off
if ((spF8[0] | spF8[1]) == 0) { var_s0 = 1; }
// clang-format on
else if ((spF8[1] != spF8[0]) != 0) {
index = 0;
if (spC4[1] < spC4[0]) {
index = 1;
}
nextIndex = 1 - index;
if (spF8[index] == 1) {
temp = ((-spC4[index] - 300.0) / (spC4[nextIndex] - spC4[index]));
spB8[index] = spB8[index] + ((spB8[nextIndex] - spB8[index]) * temp);
spC4[index] = -300.0f;
}
if (spF8[nextIndex] == 2) {
temp = ((spC4[nextIndex] - 300.0) / (spC4[nextIndex] - spC4[index]));
spB8[nextIndex] = spB8[nextIndex] + ((spB8[index] - spB8[nextIndex]) * temp);
spC4[nextIndex] = 300.0f;
}
var_s0 = 1;
}
if (var_s0 != 0) {
var_t0 = (segment->unk14[j].triangleIndex << 2);
temp = (spB0[0] + D_8011D4A0) * segment->unk18[var_t0];
temp += spB8[0] * segment->unk18[var_t0 + 1];
temp += (spA8[0] + D_8011D4A4) * segment->unk18[var_t0 + 2];
temp += segment->unk18[var_t0 + 3];
var_s0 = (temp > 0.0) << 2;
if (segment->unk18[var_t0 + 1] < 0.0f) {
var_s0 |= 1;
}
if (spC4[0] == spC4[1]) {
var_s0 |= 8;
}
func_80026C14(spC4[0], spB8[0], var_s0);
func_80026C14(spC4[1], spB8[1], var_s0);
}
}
}
}
}
void func_80026C14(s16 arg0, s16 arg1, s32 arg2) {
s16 i;
@@ -754,7 +876,7 @@ void func_80026C14(s16 arg0, s16 arg1, s32 arg2) {
}
void func_80026E54(s16 arg0, s8 *arg1, f32 arg2, f32 arg3) {
s32 pad[7];
UNUSED s32 pad[7];
unk8011D478 *next;
unk8011D478 *curr;
s16 temp3;
@@ -770,7 +892,7 @@ void func_80026E54(s16 arg0, s8 *arg1, f32 arg2, f32 arg3) {
s8 temp;
s8 temp0;
s8 temp1;
f32 temp2;
UNUSED f32 temp2;
f32 sp94[10];
f32 sp6C[10];
s8 sp60[10];
@@ -831,7 +953,7 @@ s32 func_80027184(f32 *arg0, f32 *arg1, f32 arg2, f32 arg3) {
Vertex *verts;
Triangle *tris;
s32 two;
s32 test;
UNUSED s32 test;
s32 vertZ1;
s32 vertX2;
s32 vertZ2;
@@ -2209,7 +2331,6 @@ s32 func_8002BAB0(s32 levelSegmentIndex, f32 xIn, f32 zIn, f32 *yOut) {
TriangleBatchInfo *currentBatch;
f32 *temp_v1_4;
Vec4f tempVec4f;
u16 *new_var;
u16 temp;
if (levelSegmentIndex < 0 || levelSegmentIndex >= gCurrentLevelModel->numberOfSegments) {
@@ -2274,8 +2395,7 @@ s32 func_8002BAB0(s32 levelSegmentIndex, f32 xIn, f32 zIn, f32 *yOut) {
temp_ra_3 = ((((XInInt - vert1X) * (vert3Z - vert1Z)) - ((vert3X - vert1X) * (ZInInt - vert1Z))) >= 0);
var_v0 = faceNum; // fake?
if (temp_ra_1 == temp_ra_2 && temp_ra_2 != temp_ra_3) {
new_var = currentSegment->unk14;
temp = new_var[faceNum * 4];
temp = currentSegment->unk14[faceNum].triangleIndex;
temp_v1_4 = (f32 *) &currentSegment->unk18[temp * 4];
tempVec4f.x = temp_v1_4[0];
tempVec4f.y = temp_v1_4[1];
@@ -2364,7 +2484,7 @@ void func_8002C0C4(s32 modelId) {
LOCAL_OFFSET_TO_RAM_ADDRESS(Vertex *, gCurrentLevelModel->segments[k].vertices);
LOCAL_OFFSET_TO_RAM_ADDRESS(Triangle *, gCurrentLevelModel->segments[k].triangles);
LOCAL_OFFSET_TO_RAM_ADDRESS(TriangleBatchInfo *, gCurrentLevelModel->segments[k].batches);
LOCAL_OFFSET_TO_RAM_ADDRESS(u16 *, gCurrentLevelModel->segments[k].unk14);
LOCAL_OFFSET_TO_RAM_ADDRESS(CollisionNode *, gCurrentLevelModel->segments[k].unk14);
}
for (k = 0; k < gCurrentLevelModel->numberOfTextures; k++) {
gCurrentLevelModel->textures[k].texture =
@@ -2873,7 +2993,7 @@ void shadow_generate(Object *obj, s32 isWater) {
s32 yPos;
f32 xPos;
f32 zPos;
s32 *new_var;
UNUSED s32 *pad;
s32 cheats;
s32 inSegs[28];
s32 i;
+6 -7
View File
@@ -284,7 +284,7 @@ void func_800B82B4(LevelModel *arg0, LevelHeader *arg1, s32 arg2) {
D_8012A01C = 10000.0f;
D_8012A020 = -10000.0f;
for (var_s7 = 0; var_s7 < D_80129FC8.unk20; var_s7++) {
D_800E3040[var_s7] = (sins_f(var_s6) * D_80129FC8.unkC) + (sins_f(var_fp) * D_80129FC8.unk18);
D_800E3040[var_s7] = (sins_f(var_s6) * D_80129FC8.unkC) + (sins_f(var_fp) * D_80129FC8.unk18);
if (D_80129FC8.unk28 != 0) {
D_800E3040[var_s7] *= 2.0f;
}
@@ -297,7 +297,6 @@ void func_800B82B4(LevelModel *arg0, LevelHeader *arg1, s32 arg2) {
var_s6 += sp54;
var_fp += sp4C;
}
;
save_rng_seed();
set_rng_seed(0x57415646);
@@ -352,7 +351,7 @@ void func_800B82B4(LevelModel *arg0, LevelHeader *arg1, s32 arg2) {
D_800E3080[var_a0][var_s5].unk2 = (var_s0 + D_80129FC8.unk0) + 1;
D_800E3080[var_a0][var_s5].unk3 = var_s0 + 1;
var_s5++;
D_800E3080[var_a0][var_s5].unk0 = 0x40;
D_800E3080[var_a0][var_s5].unk0 = 0x40;
D_800E3080[var_a0][var_s5].unk1 = var_s0 + 1;
D_800E3080[var_a0][var_s5].unk2 = (var_s0 + D_80129FC8.unk0) + 1;
D_800E3080[var_a0][var_s5].unk3 = (var_s0 + D_80129FC8.unk0) + 2;
@@ -371,7 +370,7 @@ void func_800B82B4(LevelModel *arg0, LevelHeader *arg1, s32 arg2) {
for (i = 0; i < ARRAY_COUNT(D_800E3070); i++) {
// @note this should probably be the following for loop (or something like it, anyway)
// but the change of var_s3 does not work
// for (j = 0; j < 4; j++) {
// if (j == 0) {
// var_s3 = 0;
@@ -402,7 +401,7 @@ void func_800B82B4(LevelModel *arg0, LevelHeader *arg1, s32 arg2) {
temp_vtx->g = temp_vtx_2->g;
temp_vtx->b = temp_vtx_2->b;
temp_vtx->a = temp_vtx_2->a;
temp_vtx_3 = &D_800E3070[i][var_t0];
temp_vtx = &D_8012A028[i][1];
temp_vtx->x = temp_vtx_3->x;
@@ -414,7 +413,7 @@ void func_800B82B4(LevelModel *arg0, LevelHeader *arg1, s32 arg2) {
temp_vtx->a = temp_vtx_3->a;
var_t2 = var_t0 + 1;
var_v1 = (var_t0 + 1) * var_t0 ;
var_v1 = (var_t0 + 1) * var_t0;
temp_vtx_4 = &D_800E3070[i][var_v1];
temp_vtx = &D_8012A028[i][2];
temp_vtx->x = temp_vtx_4->x;
@@ -425,7 +424,7 @@ void func_800B82B4(LevelModel *arg0, LevelHeader *arg1, s32 arg2) {
temp_vtx->b = temp_vtx_4->b;
temp_vtx->a = temp_vtx_4->a;
var_v1 = (var_t0 + 1) * var_t0 ;
var_v1 = (var_t0 + 1) * var_t0;
temp_vtx_5 = &(&D_800E3070[i][var_v1])[var_t0];
temp_vtx = &D_8012A028[i][3];
temp_vtx->x = temp_vtx_5->x;