From 64e550d450f5ef8b7768d913554956dfa1f17fa6 Mon Sep 17 00:00:00 2001 From: Dominik Peters Date: Fri, 11 Jul 2025 21:19:55 +0200 Subject: [PATCH] match: func_80027568 (#674) * match: func_80027568 * fix: formatting, add Vec3f pointer cast * refac: make position in object transform union of vec3f and 3 floats --- README.md | 14 +++++----- include/structs.h | 11 ++++++-- src/collision.h | 2 +- src/object_functions.c | 63 ++++++++++++++++++++---------------------- src/objects.c | 2 +- src/particles.c | 4 +-- src/tracks.c | 40 ++++++++++++--------------- 7 files changed, 67 insertions(+), 69 deletions(-) diff --git a/README.md b/README.md index 836ae9ca..e1b09956 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 July 7, 2025, this is our current score: +As of July 10, 2025, this is our current score: -    Decomp progress: 96.67% +    Decomp progress: 96.77%     Documentation progress: 62.56% @@ -117,14 +117,14 @@ s32 is_drumstick_unlocked(void) { ``` -As of July 7, 2025, this is our current score: +As of July 10, 2025, this is our current score: ``` ====================================================================== ADVENTURE ONE (ASM -> C Decompilation) - --------------- 96.67% Complete (97.77% NON_MATCHING) ---------------- - # Decompiled functions: 1940 - # GLOBAL_ASM remaining: 12 - # NON_MATCHING functions: 6 + --------------- 96.77% Complete (97.77% NON_MATCHING) ---------------- + # Decompiled functions: 1941 + # GLOBAL_ASM remaining: 11 + # NON_MATCHING functions: 5 # NON_EQUIVALENT WIP functions: 6 ---------------------------- Game Status ----------------------------- Balloons: 46/47, Keys: 4/4, Trophies: 4/5 diff --git a/include/structs.h b/include/structs.h index d1407336..f55465df 100644 --- a/include/structs.h +++ b/include/structs.h @@ -1525,9 +1525,14 @@ typedef struct ObjectTransform { /* 0x0006 */ s16 spriteID; }; /* 0x0008 */ f32 scale; - /* 0x000C */ f32 x_position; - /* 0x0010 */ f32 y_position; - /* 0x0014 */ f32 z_position; + union { + /* 0x000C */ Vec3f position; + struct { + /* 0x000C */ f32 x_position; + /* 0x0010 */ f32 y_position; + /* 0x0014 */ f32 z_position; + }; + }; } ObjectTransform; /* Size: 0x0630 bytes */ diff --git a/src/collision.h b/src/collision.h index 683daa94..46c45414 100644 --- a/src/collision.h +++ b/src/collision.h @@ -8,7 +8,7 @@ enum CollisionModes { COLLISION_MODE_DEFAULT, COLLISION_MODE_1, COLLISION_MODE_NO_WALLS }; -void generate_collision_candidates(s32 numPoints, Vec3f *origins, Vec3f *targets, s32 vehicleID); +s32 generate_collision_candidates(s32 numPoints, Vec3f *origins, Vec3f *targets, s32 vehicleID); s32 compute_grid_overlap_mask(LevelModelSegmentBoundingBox *bbox, s32 x1, s32 z1, s32 x2, s32 z2); s32 resolve_collisions(Vec3f *origin, Vec3f *target, f32 *radius, s8 *surface, s32 numEntries, s32 *numCollisions); diff --git a/src/object_functions.c b/src/object_functions.c index 9fb60896..2bc79974 100644 --- a/src/object_functions.c +++ b/src/object_functions.c @@ -442,9 +442,9 @@ void obj_loop_laserbolt(Object *obj, s32 updateRate) { dir.z = obj->trans.z_position + (obj->z_velocity * updateRateF); radius = 9.0f; - generate_collision_candidates(1, (Vec3f *) &obj->trans.x_position, &dir, -1); + generate_collision_candidates(1, &obj->trans.position, &dir, -1); hasCollision = FALSE; - resolve_collisions((Vec3f *) &obj->trans.x_position, &dir, &radius, &surface, 1, &hasCollision); + resolve_collisions(&obj->trans.position, &dir, &radius, &surface, 1, &hasCollision); if (hasCollision) { obj->x_velocity = (dir.x - obj->trans.x_position) / updateRateF; obj->y_velocity = (dir.y - obj->trans.y_position) / updateRateF; @@ -709,7 +709,7 @@ void obj_loop_collectegg(Object *obj, s32 updateRate) { Object_CollectEgg *egg; Object *racerObj; Object_Racer *racer; - f32 targetPos[3]; + Vec3f targetPos; f32 radius; f32 updateRateF; s32 hasCollision; @@ -726,21 +726,20 @@ void obj_loop_collectegg(Object *obj, s32 updateRate) { break; case EGG_MOVING: obj->trans.flags &= ~OBJ_FLAGS_INVISIBLE; - targetPos[0] = obj->trans.x_position + (obj->x_velocity * updateRateF); - targetPos[1] = obj->trans.y_position + (obj->y_velocity * updateRateF); - targetPos[2] = obj->trans.z_position + (obj->z_velocity * updateRateF); + targetPos.f[0] = obj->trans.x_position + (obj->x_velocity * updateRateF); + targetPos.f[1] = obj->trans.y_position + (obj->y_velocity * updateRateF); + targetPos.f[2] = obj->trans.z_position + (obj->z_velocity * updateRateF); radius = 9.0f; - generate_collision_candidates(1, (Vec3f *) &obj->trans.x_position, (Vec3f *) targetPos, -1); + generate_collision_candidates(1, &obj->trans.position, &targetPos, -1); hasCollision = FALSE; surface = SURFACE_DEFAULT; - resolve_collisions((Vec3f *) &obj->trans.x_position, (Vec3f *) targetPos, &radius, &surface, 1, - &hasCollision); - obj->x_velocity = (targetPos[0] - obj->trans.x_position) / updateRateF; - obj->y_velocity = (targetPos[1] - obj->trans.y_position) / updateRateF; - obj->z_velocity = (targetPos[2] - obj->trans.z_position) / updateRateF; - obj->trans.x_position = targetPos[0]; - obj->trans.y_position = targetPos[1]; - obj->trans.z_position = targetPos[2]; + resolve_collisions(&obj->trans.position, &targetPos, &radius, &surface, 1, &hasCollision); + obj->x_velocity = (targetPos.f[0] - obj->trans.x_position) / updateRateF; + obj->y_velocity = (targetPos.f[1] - obj->trans.y_position) / updateRateF; + obj->z_velocity = (targetPos.f[2] - obj->trans.z_position) / updateRateF; + obj->trans.x_position = targetPos.f[0]; + obj->trans.y_position = targetPos.f[1]; + obj->trans.z_position = targetPos.f[2]; obj->y_velocity -= 0.5; obj->x_velocity *= 0.98; obj->z_velocity *= 0.98; @@ -4307,7 +4306,7 @@ void obj_init_banana(Object *obj, UNUSED LevelObjectEntry_Banana *entry) { void obj_loop_banana(Object *obj, s32 updateRate) { Object *racerObj; Object_Racer *racer; - f32 targetPos[3]; + Vec3f targetPos; f32 radius; f32 updateRateF; f32 velX; @@ -4342,20 +4341,19 @@ void obj_loop_banana(Object *obj, s32 updateRate) { banana->unk0 = 0; } if (properties->status == BANANA_DROPPED) { - targetPos[0] = obj->trans.x_position + (obj->x_velocity * updateRateF); - targetPos[1] = obj->trans.y_position + (obj->y_velocity * updateRateF); - targetPos[2] = obj->trans.z_position + (obj->z_velocity * updateRateF); + targetPos.f[0] = obj->trans.x_position + (obj->x_velocity * updateRateF); + targetPos.f[1] = obj->trans.y_position + (obj->y_velocity * updateRateF); + targetPos.f[2] = obj->trans.z_position + (obj->z_velocity * updateRateF); radius = 8.0f; - generate_collision_candidates(1, (Vec3f *) &obj->trans.x_position, (Vec3f *) targetPos, -1); + generate_collision_candidates(1, &obj->trans.position, &targetPos, -1); hasCollision = 0; - resolve_collisions((Vec3f *) &obj->trans.x_position, (Vec3f *) targetPos, &radius, &surface, 1, - &hasCollision); - obj->x_velocity = (targetPos[0] - obj->trans.x_position) / updateRateF; - obj->y_velocity = (targetPos[1] - obj->trans.y_position) / updateRateF; - obj->z_velocity = (targetPos[2] - obj->trans.z_position) / updateRateF; - obj->trans.x_position = targetPos[0]; - obj->trans.y_position = targetPos[1]; - obj->trans.z_position = targetPos[2]; + resolve_collisions(&obj->trans.position, &targetPos, &radius, &surface, 1, &hasCollision); + obj->x_velocity = (targetPos.f[0] - obj->trans.x_position) / updateRateF; + obj->y_velocity = (targetPos.f[1] - obj->trans.y_position) / updateRateF; + obj->z_velocity = (targetPos.f[2] - obj->trans.z_position) / updateRateF; + obj->trans.x_position = targetPos.f[0]; + obj->trans.y_position = targetPos.f[1]; + obj->trans.z_position = targetPos.f[2]; // Bananas dropped by planes will not have gravity. if (banana->droppedVehicleID != VEHICLE_PLANE) { obj->y_velocity -= 1.0; //!@Delta @@ -4853,10 +4851,10 @@ void weapon_projectile(Object *obj, s32 updateRate) { offset.z = obj->trans.z_position + (obj->z_velocity * updateRateF); if (weapon->weaponID != WEAPON_MAGNET_LEVEL_3) { radius = 16.0f; - generate_collision_candidates(1, (Vec3f *) &obj->trans.x_position, &offset, -1); + generate_collision_candidates(1, &obj->trans.position, &offset, -1); hasCollision = FALSE; surface = SURFACE_NONE; - resolve_collisions((Vec3f *) &obj->trans.x_position, &offset, &radius, &surface, 1, &hasCollision); + resolve_collisions(&obj->trans.position, &offset, &radius, &surface, 1, &hasCollision); if (hasCollision > 0) { if (get_collision_normal(&diffX, &diffY, &diffZ)) { obj->properties.projectile.timer = 0; @@ -5157,11 +5155,10 @@ void weapon_trap(Object *weaponObj, s32 updateRate) { intendedPos.y = weaponObj->trans.y_position + (weaponObj->y_velocity * updateRateF); intendedPos.z = weaponObj->trans.z_position + (weaponObj->z_velocity * updateRateF); radius = 9.0f; - generate_collision_candidates(1, (Vec3f *) &weaponObj->trans.x_position, (Vec3f *) &intendedPos.x, -1); + generate_collision_candidates(1, &weaponObj->trans.position, &intendedPos, -1); hasCollision = FALSE; surface = SURFACE_NONE; - resolve_collisions((Vec3f *) &weaponObj->trans.x_position, (Vec3f *) &intendedPos, &radius, &surface, 1, - &hasCollision); + resolve_collisions(&weaponObj->trans.position, &intendedPos, &radius, &surface, 1, &hasCollision); weaponObj->x_velocity = (intendedPos.x - weaponObj->trans.x_position) / updateRateF; weaponObj->y_velocity = (intendedPos.y - weaponObj->trans.y_position) / updateRateF; weaponObj->z_velocity = (intendedPos.z - weaponObj->trans.z_position) / updateRateF; diff --git a/src/objects.c b/src/objects.c index af69bd09..3de77615 100644 --- a/src/objects.c +++ b/src/objects.c @@ -3973,7 +3973,7 @@ void render_bubble_trap(ObjectTransform *trans, Sprite *gfxData, Object *obj, s3 Camera *cameraSegment; f32 dist; - vec3f_rotate(&trans->rotation, (Vec3f *) &obj->trans.x_position); + vec3f_rotate(&trans->rotation, &obj->trans.position); obj->trans.x_position += trans->x_position; obj->trans.y_position += trans->y_position; obj->trans.z_position += trans->z_position; diff --git a/src/particles.c b/src/particles.c index 4234e0c2..d55e538f 100644 --- a/src/particles.c +++ b/src/particles.c @@ -1190,7 +1190,7 @@ void setup_particle_position(Particle *particle, Object *obj, ParticleEmitter *e particle->trans.y_position = particle->localPos.y; particle->trans.z_position = particle->localPos.z; if (particle->movementType == PARTICLE_MOVEMENT_BASIC_PARENT) { - vec3f_rotate(&obj->trans.rotation, (Vec3f *) &particle->trans.x_position); + vec3f_rotate(&obj->trans.rotation, &particle->trans.position); } particle->trans.x_position += obj->trans.x_position; @@ -2283,7 +2283,7 @@ void move_particle_attached_to_parent(Particle *particle) { particle->trans.x_position = 0.0f; particle->trans.y_position = -particle->downOffset; particle->trans.z_position = 0.0f; - vec3f_rotate(&particle->trans.rotation, (Vec3f *) &particle->trans.x_position); + vec3f_rotate(&particle->trans.rotation, &particle->trans.position); particle->trans.x_position += particle->localPos.x; particle->trans.y_position += particle->localPos.y; particle->trans.z_position += particle->localPos.z; diff --git a/src/tracks.c b/src/tracks.c index 5dd026ee..16b57709 100644 --- a/src/tracks.c +++ b/src/tracks.c @@ -1075,8 +1075,6 @@ s32 void_generate_primitive(f32 *arg0, f32 *arg1, f32 arg2, f32 arg3) { return NULL; } -// https://decomp.me/scratch/7GUjD -#ifdef NON_MATCHING s32 func_80027568(void) { LevelModelSegment *segment; // spE4 s32 ret; @@ -1099,8 +1097,7 @@ s32 func_80027568(void) { f32 A, B, C, D; Object **racerObjects; // sp80 Object *racerObj; // sp7C - s32 index; - u16 index2; + f32 *planes; racerObjects = get_racer_objects(&numRacers); if (numRacers == 0) { @@ -1122,20 +1119,21 @@ s32 func_80027568(void) { if (racerObj == NULL) { return FALSE; } - generate_collision_candidates(1, (Vec3f *) &racerObj->trans.x_position, - (Vec3f *) &gSceneActiveCamera->trans.x_position, -1); + generate_collision_candidates(1, &racerObj->trans.position, &gSceneActiveCamera->trans.position, -1); ret = FALSE; for (var_t4 = 0; var_t4 < gNumCollisionCandidates && ret == FALSE; var_t4++) { - if (gCollisionCandidates[var_t4] > 0) { + flipSide = gCollisionCandidates[var_t4]; + if (flipSide > 0) { // this is segment Entry - segment = (LevelModelSegment *) (gCollisionCandidates[var_t4] | 0x80000000); + segment = (LevelModelSegment *) PHYS_TO_K0(flipSide); } else { - colNode = (CollisionNode *) gCollisionCandidates[var_t4]; - index = colNode->colPlaneIndex << 2; - A = segment->collisionPlanes[index + 0]; - B = segment->collisionPlanes[index + 1]; - C = segment->collisionPlanes[index + 2]; - D = segment->collisionPlanes[index + 3]; + colNode = (CollisionNode *) flipSide; + curViewport = colNode->colPlaneIndex << 2; + planes = &segment->collisionPlanes[curViewport]; + A = planes[0]; + B = planes[1]; + C = planes[2]; + D = planes[3]; camDist = A * gSceneActiveCamera->trans.x_position + B * gSceneActiveCamera->trans.y_position + C * gSceneActiveCamera->trans.z_position + D - 14.0; @@ -1164,11 +1162,12 @@ s32 func_80027568(void) { curViewport &= 0x7FFF; flipSide = TRUE; } - curViewport = 4 * curViewport; - A1 = segment->collisionPlanes[curViewport + 0]; - B1 = segment->collisionPlanes[curViewport + 1]; - C1 = segment->collisionPlanes[curViewport + 2]; - D1 = segment->collisionPlanes[curViewport + 3]; + curViewport = curViewport << 2; + planes = &segment->collisionPlanes[curViewport]; + A1 = planes[0]; + B1 = planes[1]; + C1 = planes[2]; + D1 = planes[3]; var_f18 = A1 * var_f20 + B1 * var_f22 + C1 * var_f24 + D1; if (flipSide) { var_f18 = -var_f18; @@ -1183,9 +1182,6 @@ s32 func_80027568(void) { } return ret; } -#else -#pragma GLOBAL_ASM("asm/nonmatchings/tracks/func_80027568.s") -#endif /** * Sets up the camera placement for the 4th viewport when using T.T Cam in 3 player.