mirror of
https://github.com/izzy2lost/Diddy-Kong-Racing.git
synced 2026-06-19 01:16:26 -07:00
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:
@@ -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:
|
||||
|
||||
    Decomp progress: 78.93%
|
||||
    Decomp progress: 79.16%
|
||||
|
||||
    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
@@ -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
@@ -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
@@ -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 *) ¤tSegment->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
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user