match func_80060910 and func_80060AC8 (#589)

* match func_80060AC8

* reworked func_80060C58

* match func_80060910

* non equivalent func_8006017C

* format

* match calc_env_mapping_for_object
This commit is contained in:
Unnunu
2025-05-27 21:09:54 +03:00
committed by GitHub
parent b41c206cfd
commit b92148ab0b
7 changed files with 423 additions and 63 deletions
+8 -8
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 May 26, 2025, this is our current score:
As of May 27, 2025, this is our current score:
&emsp;&emsp;&emsp;&emsp;Decomp progress: 88.37%
&emsp;&emsp;&emsp;&emsp;Decomp progress: 88.58%
&emsp;&emsp;&emsp;&emsp;Documentation progress: 58.39%
<!-- README_SCORE_SUMMARY_END -->
@@ -117,20 +117,20 @@ s32 is_drumstick_unlocked(void) {
```
<!-- README_SCORE_BEGIN -->
As of May 26, 2025, this is our current score:
As of May 27, 2025, this is our current score:
```
===================================================================
ADVENTURE ONE (ASM -> C Decompilation)
-------------- 88.37% Complete (89.33% NON_MATCHING) --------------
# Decompiled functions: 1900
# GLOBAL_ASM remaining: 51
-------------- 88.58% Complete (89.54% NON_MATCHING) --------------
# Decompiled functions: 1903
# GLOBAL_ASM remaining: 48
# NON_MATCHING functions: 5
# NON_EQUIVALENT WIP functions: 15
# NON_EQUIVALENT WIP functions: 16
--------------------------- Game Status ---------------------------
Balloons: 41/47, Keys: 4/4, Trophies: 4/5
T.T. Amulets: 4/4, Wizpig Amulets: 4/4
-------------------------------------------------------------------
We are racing in Spaceport Alpha. (Lap 1/3)
We are racing in Spaceport Alpha. (Lap 2/3)
===================================================================
ADVENTURE TWO (Cleanup & Documentation)
------------------------- 58.39% Complete -------------------------
+14 -3
View File
@@ -639,12 +639,23 @@ typedef struct ObjectModel_44 {
/* 0x04 */ s32 unk4; // Number of frames in animation?
} ObjectModel_44;
typedef struct ObjectModel_C {
u16 unk0[4];
} ObjectModel_C;
typedef struct ObjectModel_10 {
f32 A;
f32 B;
f32 C;
f32 D;
} ObjectModel_10;
typedef struct ObjectModel {
/* 0x00 */ TextureInfo* textures;
/* 0x04 */ Vertex* vertices;
/* 0x08 */ Triangle* triangles;
/* 0x0C */ s32* unkC;
/* 0x10 */ s32* unk10;
/* 0x0C */ ObjectModel_C *unkC;
/* 0x10 */ ObjectModel_10 *unk10;
/* 0x14 */ s16 *unk14;
/* 0x18 */ s16 unk18;
/* 0x1A */ s16 unk1A;
@@ -662,7 +673,7 @@ typedef struct ObjectModel {
/* 0x34 */ u8 pad34[4];
/* 0x38 */ TriangleBatchInfo* batches;
/* 0x3C */ f32 unk3C;
/* 0x40 */ s32* unk40;
/* 0x40 */ Vec3s* unk40;
/* 0x44 */ ObjectModel_44* animations;
/* 0x48 */ s16 numberOfAnimations;
/* 0x4A */ s16 unk4A;
+3 -8
View File
@@ -214,14 +214,9 @@ GLOBAL_ASM("asm/math_util/rng.s")
#ifdef NON_EQUIVALENT
/* Official name: fastShortReflection */
void s16_matrix_rotate(s16 *arg0[4][4], s16 arg1[4][4]) {
s32 temp_t6;
temp_t6 = (s32) ((*arg0[0][0] * arg1[0][0]) + (*arg0[0][1] * arg1[0][1]) + (*arg0[0][2] * *arg0[0][2])) >> 12;
*arg0[1][0] = (s16) (((s32) (temp_t6 * arg1[0][0]) >> 13) - *arg0[0][0]);
*arg0[1][1] = (s16) (((s32) (temp_t6 * arg1[0][1]) >> 13) - *arg0[0][1]);
*arg0[1][2] =
(s16) (((s32) (temp_t6 * arg1[0][2]) >> 13) - *arg0[0][0]); // Did they mean to do `- *arg0[0][2]` here?
// name and code are incorrect
void s16_matrix_rotate(Vec3s *arg0, Vec3s *arg1) {
// TODO
}
#else
GLOBAL_ASM("asm/math_util/s16_matrix_rotate.s")
+1 -1
View File
@@ -42,7 +42,7 @@ void guMtxXFMF(float mf[4][4], float x, float y, float z, float *ox, float *oy,
void f32_matrix_dot(Matrix *mat1, Matrix *mat2, Matrix *output);
void f32_matrix_mult(Matrix *mat1, Matrix *mat2, Matrix *output);
void f32_matrix_to_s16_matrix(Matrix *input, MatrixS *output);
void s16_matrix_rotate(s16 *arg0[4][4], s16 arg1[4][4]);
void s16_matrix_rotate(Vec3s *arg0, Vec3s *arg1);
void s16_vec3_mult_by_s32_matrix(MatrixS input, Vec3s *output);
void object_transform_to_matrix(Matrix mtx, ObjectTransform *trans);
void f32_matrix_scale_y_axis(Matrix *input, f32 scale);
+283 -35
View File
@@ -376,51 +376,299 @@ void free_model_data(ObjectModel *mdl) {
mempool_free(mdl);
}
#pragma GLOBAL_ASM("asm/nonmatchings/object_models/func_8006017C.s")
#pragma GLOBAL_ASM("asm/nonmatchings/object_models/func_80060910.s")
#pragma GLOBAL_ASM("asm/nonmatchings/object_models/func_80060AC8.s")
#ifdef NON_EQUIVALENT
// url: https://decomp.me/scratch/VJ34p
void func_8006017C(ObjectModel *arg0) {
s32 facesOffset; // v1
s32 verticesOffset; // s5
s32 nextFacesOffset; // spF4
s32 s4;
s32 i; // spEC
s32 j; // s6
Vertex *v;
s32 v1, v2;
f32 x5, y5, z5; // f20, f24, f26
f32 x1, y1, z1; // spCC, spC8, spC4
f32 x2, y2, z2; // f14, f16, f18
f32 x3, y3, z3; // f22, spB0, f0
f32 nx, ny, nz; // spA8, spA4, spA0
f32 mag;
s32 s3;
s32 k;
s32 l;
s32 temp1, temp2, temp3;
s32 func_80060C58(Vertex *vertices, s32 arg1, s32 arg2, s32 arg3, s32 arg4) {
if (arg0->unkC != NULL) {
return;
}
s4 = 0;
for (i = 0; i < arg0->numberOfBatches; i++) {
facesOffset = arg0->batches[i].facesOffset;
nextFacesOffset = arg0->batches[i + 1].facesOffset;
if (arg0->batches[i].flags & 0x200) {
continue;
}
s4 += nextFacesOffset - facesOffset;
}
arg0->unkC = (ObjectModel_C *) mempool_alloc(s4 * sizeof(ObjectModel_C), COLOUR_TAG_RED);
if (v) {} // FAKE
if (arg0->unkC == NULL) {
return;
}
arg0->unk10 = (ObjectModel_10 *) mempool_alloc(s4 * 64, COLOUR_TAG_RED);
if (arg0->unk10 == NULL) {
mempool_free(arg0->unkC);
arg0->unkC = NULL;
return;
}
s4 = 0;
for (i = 0; i < arg0->numberOfBatches; i++) {
facesOffset = arg0->batches[i].facesOffset;
verticesOffset = arg0->batches[i].verticesOffset;
nextFacesOffset = arg0->batches[i + 1].facesOffset;
if (arg0->batches[i].flags & 0x200) {
nextFacesOffset = facesOffset - 1;
}
for (j = facesOffset; j < nextFacesOffset; j++) {
v = &arg0->vertices[arg0->triangles[j].vi0 + verticesOffset];
x1 = v->x;
y1 = v->y;
z1 = v->z;
v = &arg0->vertices[arg0->triangles[j].vi1 + verticesOffset];
x2 = v->x;
y2 = v->y;
z2 = v->z;
v = &arg0->vertices[arg0->triangles[j].vi2 + verticesOffset];
x3 = v->x;
y3 = v->y;
z3 = v->z;
nx = y1 * (z2 - z3) + y2 * (z3 - z1) + y3 * (z1 - z2);
ny = z1 * (x2 - x3) + z2 * (x3 - x1) + z3 * (x1 - x2);
nz = x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2);
mag = sqrtf(nx * nx + ny * ny + nz * nz);
if (mag > 0.0) {
nx /= mag;
ny /= mag;
nz /= mag;
}
arg0->unk10[s4].A = nx;
arg0->unk10[s4].B = ny;
arg0->unk10[s4].C = nz;
arg0->unk10[s4].D = -(x1 * nx + y1 * ny + z1 * nz);
arg0->unkC[s4].unk0[0] = s4;
arg0->unkC[s4].unk0[1] = s4;
arg0->unkC[s4].unk0[2] = s4;
arg0->unkC[s4].unk0[3] = s4;
s4++;
}
}
arg0->unk32 = s4;
func_80060910(arg0);
s3 = 0;
for (i = 0; i < arg0->numberOfBatches; i++) {
facesOffset = arg0->batches[i].facesOffset;
verticesOffset = arg0->batches[i].verticesOffset;
nextFacesOffset = arg0->batches[i + 1].facesOffset;
if (arg0->batches[i].flags & 0x200) {
nextFacesOffset = facesOffset - 1;
}
for (j = facesOffset; j < nextFacesOffset; j++) {
nx = arg0->unk10[arg0->unkC[s3].unk0[0]].A;
ny = arg0->unk10[arg0->unkC[s3].unk0[0]].B;
nz = arg0->unk10[arg0->unkC[s3].unk0[0]].C;
for (k = 0; k < 3; k++) {
l = k + 1;
if (l >= 3) {
l = 0;
}
v1 = arg0->triangles[j].verticesArray[1 + k];
v2 = arg0->triangles[j].verticesArray[1 + l];
x5 = nx + arg0->unk10[arg0->unkC[s3].unk0[l + 1]].A;
y5 = ny + arg0->unk10[arg0->unkC[s3].unk0[l + 1]].B;
z5 = nz + arg0->unk10[arg0->unkC[s3].unk0[l + 1]].C;
v = &arg0->vertices[v1 + verticesOffset];
x1 = v->x;
y1 = v->y;
z1 = v->z;
v = &arg0->vertices[v2 + verticesOffset];
x2 = v->x;
y2 = v->y;
z2 = v->z;
x3 = x5 * 10.0f + x1;
y3 = y5 * 10.0f + y1;
z3 = z5 * 10.0f + z1;
x5 = y1 * (z2 - z3) + y2 * (z3 - z1) + y3 * (z1 - z2);
y5 = z1 * (x2 - x3) + z2 * (x3 - x1) + z3 * (x1 - x2);
z5 = x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2);
mag = sqrtf(x5 * x5 + y5 * y5 + z5 * z5);
if (mag > 0.0) {
x5 /= mag;
y5 /= mag;
z5 /= mag;
}
arg0->unkC[s3].unk0[k + 1] = s4;
arg0->unk10[s4].A = x5;
arg0->unk10[s4].B = y5;
arg0->unk10[s4].C = z5;
arg0->unk10[s4].D = -(x1 * x5 + y1 * y5 + z1 * z5);
s4++;
}
s3++;
}
}
}
#else
#pragma GLOBAL_ASM("asm/nonmatchings/object_models/func_8006017C.s")
#endif
void func_80060910(ObjectModel *mdl) {
s32 count;
s32 i;
s32 vertOffset;
s32 triIndex;
s32 startTri;
s32 endTri;
s32 nextVertIndex;
s32 vertIndex;
s32 vertIndex0;
s32 vertIndex1;
s32 result;
s32 sp60;
s32 sp5C;
count = 0;
for (i = 0; i < mdl->numberOfBatches; i++) {
startTri = mdl->batches[i].facesOffset;
vertOffset = mdl->batches[i].verticesOffset;
endTri = mdl->batches[i + 1].facesOffset;
if (mdl->batches[i].flags & BATCH_FLAGS_UNK00000200) {
endTri = startTri - 1;
}
for (triIndex = startTri; triIndex < endTri; triIndex++, count++) {
mdl->unkC[count].unk0[0] = count;
for (vertIndex = 0; vertIndex < 3; vertIndex++) {
nextVertIndex = vertIndex + 1;
if (nextVertIndex >= 3) {
nextVertIndex = 0;
}
vertIndex0 = mdl->triangles[triIndex].verticesArray[vertIndex + 1] + vertOffset;
vertIndex1 = mdl->triangles[triIndex].verticesArray[nextVertIndex + 1] + vertOffset;
result = func_80060AC8(mdl, triIndex, vertIndex0, vertIndex1, &sp5C, &sp60);
if (result != -1) {
mdl->unkC[count].unk0[1 + vertIndex] = result;
} else {
mdl->unkC[count].unk0[1 + vertIndex] = count;
}
}
}
}
}
s32 func_80060AC8(ObjectModel *mdl, s32 arg1, s32 arg2, s32 arg3, s32 *outBatchIndex, s32 *outVertexIndex) {
s32 i;
s32 endTri;
s32 count;
Triangle *tri;
s16 vertOffset;
s16 startTri;
s32 triIndex;
s32 nextVertIndex;
s32 vertIndex;
s32 vertIndex0;
s32 vertIndex1;
count = 0;
for (i = 0; i < mdl->numberOfBatches; i++) {
startTri = mdl->batches[i].facesOffset;
vertOffset = mdl->batches[i].verticesOffset;
endTri = mdl->batches[i + 1].facesOffset;
if (mdl->batches[i].flags & BATCH_FLAGS_UNK00000200) {
endTri = startTri - 1;
}
for (triIndex = startTri; triIndex < endTri; triIndex++, count++) {
if (triIndex != arg1) {
for (vertIndex = 0; vertIndex < 3; vertIndex++) {
nextVertIndex = vertIndex + 1;
if (nextVertIndex >= 3) {
nextVertIndex = 0;
}
vertIndex0 = mdl->triangles[triIndex].verticesArray[vertIndex + 1] + vertOffset;
vertIndex1 = mdl->triangles[triIndex].verticesArray[nextVertIndex + 1] + vertOffset;
if (func_80060C58(mdl->vertices, arg2, arg3, vertIndex0, vertIndex1) != 0) {
*outVertexIndex = vertIndex;
*outBatchIndex = i;
return count;
}
}
}
}
}
return -1;
}
s32 func_80060C58(Vertex *vertices, s32 i1, s32 i2, s32 i3, s32 i4) {
Vertex *a;
Vertex *b;
Vertex *c;
Vertex *d;
if (((arg1 == arg3) && (arg2 == arg4)) || ((arg1 == arg4) && (arg2 == arg3))) {
#define NEARBY(a, b, x) (b->x - 4 < a->x && a->x < b->x + 4)
if (i1 == i3 && i2 == i4 || i1 == i4 && i2 == i3) {
return 1;
}
a = &vertices[arg1];
b = &vertices[arg2];
c = &vertices[arg3];
d = &vertices[arg4];
if (((c->x - 4) < a->x) && (a->x < (c->x + 4))) {
if (((c->y - 4) < a->y) && (a->y < (c->y + 4))) {
if (((c->z - 4) < a->z) && (a->z < (c->z + 4))) {
if (((d->x - 4) < b->x) && (b->x < (d->x + 4))) {
if (((d->y - 4) < b->y) && (b->y < (d->y + 4))) {
if (((d->z - 4) < b->z) && (b->z < (d->z + 4))) {
return 2;
}
}
}
goto end;
}
a = &vertices[i1];
b = &vertices[i2];
c = &vertices[i3];
d = &vertices[i4];
if (NEARBY(a, c, x) && NEARBY(a, c, y) && NEARBY(a, c, z)) {
if (NEARBY(b, d, x) && NEARBY(b, d, y) && NEARBY(b, d, z)) {
return 2;
}
} else if (NEARBY(a, d, x) && NEARBY(a, d, y) && NEARBY(a, d, z)) {
if (NEARBY(b, c, x) && NEARBY(b, c, y) && NEARBY(b, c, z)) {
return 2;
}
}
if (((d->x - 4) < a->x) && (a->x < (d->x + 4))) {
if (((d->y - 4) < a->y) && (a->y < (d->y + 4))) {
if (((d->z - 4) < a->z) && (a->z < (d->z + 4))) {
if (((c->x - 4) < b->x) && (b->x < (c->x + 4))) {
if (((c->y - 4) < b->y) && (b->y < (c->y + 4))) {
if (((c->z - 4) < b->z) && (b->z < (c->z + 4))) {
return 2;
}
}
}
}
}
}
end:
return 0;
#undef NEARBY
}
#pragma GLOBAL_ASM("asm/nonmatchings/object_models/func_80060EA8.s")
+1
View File
@@ -28,6 +28,7 @@ s32 func_80061A00(ObjectModel *model, s32 animTableIndex);
s32 check_nearby_vertices(Vertex *vertices, s32 arg1, s32 arg2, s32 arg3, s32 arg4);
Object_68 *model_init_type(ObjectModel *model, s32 flags);
Object_68 *object_model_init(s32 modelID, s32 flags);
s32 func_80060C58(Vertex *vertices, s32 arg1, s32 arg2, s32 arg3, s32 arg4);
void free_model_data(ObjectModel *mdl); // Non Matching
void func_80060910(ObjectModel *);
+113 -8
View File
@@ -37,6 +37,10 @@
#define AINODE_COUNT 128
#define CAMCONTROL_COUNT 20
#define SET_SHIFT_AND_MASK(varShift, varMask, x) \
varShift = x; \
varMask = 0xFFFF >> x;
/************ .data ************/
FadeTransition gTajChallengeTransition = FADE_TRANSITION(FADE_FULLSCREEN, FADE_FLAG_OUT, FADE_COLOR_BLACK, 30, 15);
@@ -311,10 +315,8 @@ ShadeProperties *gWorldShading; // Effectively unused.
s32 D_8011AF34;
s32 D_8011AF38[10];
s32 D_8011AF60[2];
s32 D_8011AF68[32];
VertexPosition gEnvmapPos;
s16 D_8011AFEE;
s32 D_8011AFF0;
TexCoords D_8011AF68[32];
Vec3s gEnvmapPos[2];
unk800179D0 *D_8011AFF4;
s32 gBoostVertCount;
s32 D_8011AFFC;
@@ -5965,9 +5967,9 @@ void update_envmap_position(f32 x, f32 y, f32 z) {
y *= normalizedLength;
z *= normalizedLength;
}
gEnvmapPos.x = x;
gEnvmapPos.y = y;
gEnvmapPos.z = z;
gEnvmapPos[0].x = x;
gEnvmapPos[0].y = y;
gEnvmapPos[0].z = z;
}
/**
@@ -6011,7 +6013,110 @@ void obj_shade_fancy(ObjectModel *model, Object *object, s32 arg2, f32 intensity
}
#pragma GLOBAL_ASM("asm/nonmatchings/objects/calc_dynamic_lighting_for_object_1.s")
#pragma GLOBAL_ASM("asm/nonmatchings/objects/calc_env_mapping_for_object.s")
void calc_env_mapping_for_object(ObjectModel *model, s16 zRot, s16 xRot, s16 yRot) {
MatrixS objRotMtxS32;
Matrix objRotMtxF32;
ObjectTransform objTrans;
s16 k;
s16 count;
Triangle *triangles;
Vec3s *model40Entries;
s32 sp70;
TextureHeader *tex;
s16 shiftS;
s16 maskS;
s16 shiftT;
s16 maskT;
s16 i;
s16 j;
s16 var_v0;
s16 var_v1;
count = 0;
triangles = model->triangles;
model40Entries = model->unk40;
objTrans.rotation.z_rotation = zRot;
objTrans.rotation.x_rotation = xRot;
objTrans.rotation.y_rotation = yRot;
objTrans.x_position = 0.0f;
objTrans.y_position = 0.0f;
objTrans.z_position = 0.0f;
objTrans.scale = 1.0f;
object_transform_to_matrix(objRotMtxF32, &objTrans);
f32_matrix_to_s32_matrix(&objRotMtxF32, &objRotMtxS32);
for (i = 0; i < model->numberOfBatches; i++) {
if (model->batches[i].flags & BATCH_FLAGS_ENVMAP) {
sp70 = ((model->batches[i].flags & BATCH_FLAGS_UNK00020000) | BATCH_FLAGS_ENVMAP) ^ BATCH_FLAGS_ENVMAP;
tex = model->textures[model->batches[i].textureIndex].texture;
k = 0;
switch (tex->width) {
case 0x80:
SET_SHIFT_AND_MASK(shiftS, maskS, 4);
break;
case 0x40:
SET_SHIFT_AND_MASK(shiftS, maskS, 5);
break;
case 0x20:
SET_SHIFT_AND_MASK(shiftS, maskS, 6);
break;
default:
SET_SHIFT_AND_MASK(shiftS, maskS, 7);
break;
}
switch (tex->height) {
case 0x80:
SET_SHIFT_AND_MASK(shiftT, maskT, 4);
break;
case 0x40:
SET_SHIFT_AND_MASK(shiftT, maskT, 5);
break;
case 0x20:
SET_SHIFT_AND_MASK(shiftT, maskT, 6);
break;
default:
SET_SHIFT_AND_MASK(shiftT, maskT, 7);
break;
}
for (j = model->batches[i].verticesOffset; j < model->batches[i + 1].verticesOffset; j++, k++) {
gEnvmapPos[1].x = model40Entries[count].x;
gEnvmapPos[1].y = model40Entries[count].y;
gEnvmapPos[1].z = model40Entries[count].z;
count++;
s16_vec3_mult_by_s32_matrix(objRotMtxS32, &gEnvmapPos[1]);
if (sp70 == 0) {
s16_matrix_rotate(&gEnvmapPos[0], &gEnvmapPos[1]);
}
var_v0 = gEnvmapPos[1].x;
var_v1 = gEnvmapPos[1].y;
if (var_v0 > 0) {
var_v0--;
}
if (var_v1 > 0) {
var_v1--;
}
var_v0 = (var_v0 << 2) + 0x8000;
var_v1 = (var_v1 << 2) + 0x8000;
D_8011AF68[k].u = (var_v0 >> shiftS) & maskS;
D_8011AF68[k].v = (var_v1 >> shiftT) & maskT;
}
for (j = model->batches[i].facesOffset; j < model->batches[i + 1].facesOffset; j++) {
triangles[j].uv0.u = D_8011AF68[triangles[j].vi0].u;
triangles[j].uv0.v = D_8011AF68[triangles[j].vi0].v;
triangles[j].uv1.u = D_8011AF68[triangles[j].vi1].u;
triangles[j].uv1.v = D_8011AF68[triangles[j].vi1].v;
triangles[j].uv2.u = D_8011AF68[triangles[j].vi2].u;
triangles[j].uv2.v = D_8011AF68[triangles[j].vi2].v;
}
} else if (model->batches[i].unk6 < 0xFF) {
count += model->batches[i + 1].verticesOffset - model->batches[i].verticesOffset;
}
}
}
/**
* Find the racer object representing the player and directly set position and angle to new values.