From af3d3e33e59652c21d936798df2f8223c1f87bc9 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Thu, 14 Jul 2022 21:26:10 +1000 Subject: [PATCH] Attempt to decompile bgCalculateHitInVtxBatch --- src/game/bg.c | 262 ++++++++++++++++++++++++++++++++++-- src/game/bgbss.c | 49 +------ src/game/explosions.c | 2 +- src/game/prop.c | 2 +- src/game/propobj.c | 2 +- src/game/splat.c | 2 +- src/include/bss.h | 3 +- src/include/game/bg.h | 4 +- src/include/lib/lib_2f490.h | 2 +- src/include/types.h | 12 +- 10 files changed, 264 insertions(+), 76 deletions(-) diff --git a/src/game/bg.c b/src/game/bg.c index 1774e85da..be733563f 100644 --- a/src/game/bg.c +++ b/src/game/bg.c @@ -10391,14 +10391,14 @@ glabel var7f1b75d8 /* f15f634: 032f7021 */ addu $t6,$t9,$t7 /* f15f638: 3078000f */ andi $t8,$v1,0xf /* f15f63c: 03001825 */ or $v1,$t8,$zero -/* f15f640: 3c02800a */ lui $v0,%hi(var800a647c) +/* f15f640: 3c02800a */ lui $v0,%hi(var800a6470+0xc) /* f15f644: 00007812 */ mflo $t7 /* f15f648: 01cf2023 */ subu $a0,$t6,$t7 /* f15f64c: 84980000 */ lh $t8,0x0($a0) /* f15f650: 24630000 */ addiu $v1,$v1,0x0 /* f15f654: 240f0001 */ addiu $t7,$zero,0x1 /* f15f658: 44982000 */ mtc1 $t8,$f4 -/* f15f65c: 2442647c */ addiu $v0,$v0,%lo(var800a647c) +/* f15f65c: 2442647c */ addiu $v0,$v0,%lo(var800a6470+0xc) /* f15f660: 2495000c */ addiu $s5,$a0,0xc /* f15f664: 468021a0 */ cvt.s.w $f6,$f4 /* f15f668: e5260000 */ swc1 $f6,0x0($t1) @@ -11797,7 +11797,7 @@ glabel func0f15ffdc ); GLOBAL_ASM( -glabel func0f160a38 +glabel bgCalculateHitInVtxBatch .late_rodata glabel var7f1b75dc .word 0x7f7fffff @@ -12405,6 +12405,231 @@ glabel var7f1b75dc /* f1612e0: 01a01025 */ or $v0,$t5,$zero ); +// Mismatch: Some significantly different codegen, probably related to how loops +// are iterated. Appears to be functionally correct. +//bool bgCalculateHitInVtxBatch(struct coord *arg0, struct coord *arg1, struct coord *arg2, struct vtxbatch *batch, s32 roomnum, struct hitthing *hitthing) +//{ +// s16 spf4; +// s32 spf0; +// Gfx *gdl; +// s32 ret; // e8 +// s32 spdc[3]; +// struct gfxvtx *vtx; +// s32 numvertices; +// f32 lowestsqdist; +// Gfx *tmpgdl; +// s32 texturenum; +// s32 i; +// s32 index; +// u32 stack; +// struct coord spb0; +// struct coord spa4; +// struct coord sp98; +// struct coord sp8c; +// +// Gfx *sp78; +// Gfx *iter; +// +// gdl = batch->gdl; +// +// vtx = room0f15dbb4(roomnum, gdl); +// iter = &gdl[batch->gbicmdindex]; +// numvertices = (((u32)iter->bytes[1] >> 4) & 0xf) + 1; +// vtx = (struct gfxvtx *)((s32)vtx + (iter->words.w1 & 0xffffff)); +// i = 0; +// +// while (numvertices > 0) { +// var800a6470[i].x = g_BgRooms[roomnum].pos.x + vtx->x; +// var800a6470[i].y = g_BgRooms[roomnum].pos.y + vtx->y; +// var800a6470[i].z = g_BgRooms[roomnum].pos.z + vtx->z; +// +// i++; +// vtx++; +// numvertices--; +// } +// +// lowestsqdist = MAXFLOAT; +// ret = false; +// +// iter++; +// +// while (iter->dma.cmd != G_VTX && iter->dma.cmd != G_ENDDL) { +// if (iter->dma.cmd != G_TRI1 && iter->dma.cmd != G_TRI4) { +// iter++; +// continue; +// } +// +// if (iter->dma.cmd == G_TRI1) { +// spf0 = 0; +// spf4 = 0; +// spdc[0] = iter->tri.tri.v[0] / 10; +// spdc[1] = iter->tri.tri.v[1] / 10; +// spdc[2] = iter->tri.tri.v[2] / 10; +// } else if (iter->dma.cmd == G_TRI4) { +// spf0 = 3; +// spf4 = 1; +// spdc[0] = iter->tri4.x1; +// spdc[1] = iter->tri4.y1; +// spdc[2] = iter->tri4.z1; +// } +// +// do { +// if (spdc[0] || spdc[1] || spdc[2]) { +// sp98.x = var800a6470[spdc[0]].x; +// +// if (var800a6470[spdc[1]].x < sp98.x) { +// sp98.x = var800a6470[spdc[1]].x; +// } +// +// if (var800a6470[spdc[2]].x < sp98.x) { +// sp98.x = var800a6470[spdc[2]].x; +// } +// +// if (!(arg0->x < sp98.x) || !(arg1->x < sp98.x)) { +// sp8c.x = var800a6470[spdc[0]].x; +// +// if (sp8c.x < var800a6470[spdc[1]].x) { +// sp8c.x = var800a6470[spdc[1]].x; +// } +// +// if (sp8c.x < var800a6470[spdc[2]].x) { +// sp8c.x = var800a6470[spdc[2]].x; +// } +// +// if (!(sp8c.x < arg0->x) || !(sp8c.x < arg1->x)) { +// sp98.z = var800a6470[spdc[0]].z; +// +// if (var800a6470[spdc[1]].z < sp98.z) { +// sp98.z = var800a6470[spdc[1]].z; +// } +// +// if (var800a6470[spdc[2]].z < sp98.z) { +// sp98.z = var800a6470[spdc[2]].z; +// } +// +// if (!(arg0->z < sp98.z) || !(arg1->z < sp98.z)) { +// sp8c.z = var800a6470[spdc[0]].z; +// +// if (sp8c.z < var800a6470[spdc[1]].z) { +// sp8c.z = var800a6470[spdc[1]].z; +// } +// +// if (sp8c.z < var800a6470[spdc[2]].z) { +// sp8c.z = var800a6470[spdc[2]].z; +// } +// +// if (!(sp8c.z < arg0->z) || !(sp8c.z < arg1->z)) { +// sp98.y = var800a6470[spdc[0]].y; +// +// if (var800a6470[spdc[1]].y < sp98.y) { +// sp98.y = var800a6470[spdc[1]].y; +// } +// +// if (var800a6470[spdc[2]].y < sp98.y) { +// sp98.y = var800a6470[spdc[2]].y; +// } +// +// if (!(arg0->y < sp98.y) || !(arg1->y < sp98.y)) { +// sp8c.y = var800a6470[spdc[0]].y; +// +// if (sp8c.y < var800a6470[spdc[1]].y) { +// sp8c.y = var800a6470[spdc[1]].y; +// } +// +// if (sp8c.y < var800a6470[spdc[2]].y) { +// sp8c.y = var800a6470[spdc[2]].y; +// } +// +// if (!(sp8c.y < arg0->y) || !(sp8c.y < arg1->y)) { +// if (bg0f15f2b0(arg0, arg2, &sp98, &sp8c)) { +// if (func0002f560(&var800a6470[spdc[0]], &var800a6470[spdc[1]], &var800a6470[spdc[2]], 0, arg0, arg1, arg2, &spb0, &spa4)) { +// f32 tmp; +// f32 sqdist; +// +// tmp = spb0.x - arg0->x; +// sqdist = tmp * tmp; +// tmp = spb0.y - arg0->y; +// sqdist += tmp * tmp; +// tmp = spb0.z - arg0->z; +// sqdist += tmp * tmp; +// +// if (sqdist < lowestsqdist) { +// ret = true; +// +// tmpgdl = iter; +// +// while (tmpgdl->bytes[0] != G_SETTIMG && tmpgdl > gdl) { +// tmpgdl--; +// } +// +// if (tmpgdl == gdl +// || (tmpgdl->words.w1 & 0x0f000000) == 0x0f000000 +// || (tmpgdl->words.w1 & 0x05000000) == 0x05000000) { +// texturenum = -1; +// } else { +// texturenum = *(s16 *)((tmpgdl->words.w1 - 8) | 0x80000000); +// } +// +// if (batch->type == VTXBATCHTYPE_XLU && g_Textures[texturenum].surfacetype == SURFACETYPE_DEFAULT) { +// ret = false; +// } +// +// if (ret) { +// lowestsqdist = sqdist; +// +// hitthing->unk00.x = spb0.x; +// hitthing->unk00.y = spb0.y; +// hitthing->unk00.z = spb0.z; +// hitthing->unk0c.x = spa4.x; +// hitthing->unk0c.y = spa4.y; +// hitthing->unk0c.z = spa4.z; +// hitthing->unk18 = &vtx[spdc[0]]; +// hitthing->unk1c = &vtx[spdc[1]]; +// hitthing->texturenum = texturenum; +// hitthing->unk24 = iter; +// hitthing->unk28 = spf4; +// hitthing->unk20 = &vtx[spdc[2]]; +// hitthing->unk2c = batch->type; +// } +// } +// } +// } +// } +// } +// } +// } +// } +// } +// +// spf0--; +// +// if (spf0 == 2) { +// spdc[0] = iter->tri4.x2; +// spdc[1] = iter->tri4.y2; +// spdc[2] = iter->tri4.z2; +// spf4 = 2; +// } else if (spf0 == 1) { +// spdc[0] = iter->tri4.x3; +// spdc[1] = iter->tri4.y3; +// spdc[2] = iter->tri4.z3; +// spf4 = 3; +// } else if (spf0 == 0) { +// spdc[0] = iter->tri4.x4; +// spdc[1] = iter->tri4.y4; +// spdc[2] = iter->tri4.z4; +// spf4 = 1; +// } +// } else { +// break; +// } +// } while (spf0 >= 0); +// +// iter++; +// } +// +// return ret; +//} + s32 bg0f1612e4(struct coord *bbmin, struct coord *bbmax, struct coord *arg2, struct coord *arg3, struct coord *arg4, struct coord *arg5) { s32 i; @@ -12468,7 +12693,18 @@ s32 bg0f1612e4(struct coord *bbmin, struct coord *bbmax, struct coord *arg2, str return 1; } -bool func0f161520(struct coord *arg0, struct coord *arg1, s32 roomnum, struct hitthing *hitthing) +/** + * Figure out which piece of BG geometry is hit in the given room based on a + * line intersection from frompos to topos. Populate the hitthing struct with + * the details. Props are not considered. Return true if a hit occurred. + * + * This is used not only for shots, but blood splatters and explosion scorch + * marks too. + * + * Room vertices are already grouped into batches, where each batch has a + * precomputed bounding box. + */ +bool bgCalculateHitInRoom(struct coord *frompos, struct coord *topos, s32 roomnum, struct hitthing *hitthing) { s32 i; s32 count; @@ -12489,13 +12725,13 @@ bool func0f161520(struct coord *arg0, struct coord *arg1, s32 roomnum, struct hi count = 0; - spb8.x = arg0->x; - spb8.y = arg0->y; - spb8.z = arg0->z; + spb8.x = frompos->x; + spb8.y = frompos->y; + spb8.z = frompos->z; - spac.x = arg1->x; - spac.y = arg1->y; - spac.z = arg1->z; + spac.x = topos->x; + spac.y = topos->y; + spac.z = topos->z; spa0.x = spac.x - spb8.x; spa0.y = spac.y - spb8.y; @@ -12560,7 +12796,7 @@ bool func0f161520(struct coord *arg0, struct coord *arg1, s32 roomnum, struct hi count = 0; for (j = 0; j < ARRAYCOUNT(var800a6538); j++) { - if (func0f160a38(&spb8, &spac, &spa0, &g_Rooms[roomnum].vtxbatches[var800a6538[j].vtxbatchindex], roomnum, hitthing)) { + if (bgCalculateHitInVtxBatch(&spb8, &spac, &spa0, &g_Rooms[roomnum].vtxbatches[var800a6538[j].vtxbatchindex], roomnum, hitthing)) { f0 = spb8.x - hitthing->unk00.x; f2 = f0 * f0; @@ -12609,7 +12845,7 @@ bool func0f161520(struct coord *arg0, struct coord *arg1, s32 roomnum, struct hi batch = g_Rooms[roomnum].vtxbatches; for (i = 0; i < count; i++) { - if (func0f160a38(&spb8, &spac, &spa0, &batch[var800a6538[i].vtxbatchindex], roomnum, hitthing)) { + if (bgCalculateHitInVtxBatch(&spb8, &spac, &spa0, &batch[var800a6538[i].vtxbatchindex], roomnum, hitthing)) { i++; if (i < count) { @@ -12624,7 +12860,7 @@ bool func0f161520(struct coord *arg0, struct coord *arg1, s32 roomnum, struct hi for (; i < count; i++) { if (var800a6538[i].unk04 <= spc8) { - if (func0f160a38(&spb8, &spac, &spa0, &batch[var800a6538[i].vtxbatchindex], roomnum, &sp60)) { + if (bgCalculateHitInVtxBatch(&spb8, &spac, &spa0, &batch[var800a6538[i].vtxbatchindex], roomnum, &sp60)) { f0 = spb8.f[0] - sp60.unk00.f[0]; f20 = f0 * f0; diff --git a/src/game/bgbss.c b/src/game/bgbss.c index beb2c146c..5beb09861 100644 --- a/src/game/bgbss.c +++ b/src/game/bgbss.c @@ -3,55 +3,8 @@ #include "data.h" #include "types.h" -u32 var800a6470; -u32 var800a6474; -u32 var800a6478; +struct coord var800a6470[16]; -u32 var800a647c; -u32 var800a6480; -u32 var800a6484; -u32 var800a6488; -u32 var800a648c; -u32 var800a6490; -u32 var800a6494; -u32 var800a6498; -u32 var800a649c; -u32 var800a64a0; -u32 var800a64a4; -u32 var800a64a8; -u32 var800a64ac; -u32 var800a64b0; -u32 var800a64b4; -u32 var800a64b8; -u32 var800a64bc; -u32 var800a64c0; -u32 var800a64c4; -u32 var800a64c8; -u32 var800a64cc; -u32 var800a64d0; -u32 var800a64d4; -u32 var800a64d8; -u32 var800a64dc; -u32 var800a64e0; -u32 var800a64e4; -u32 var800a64e8; -u32 var800a64ec; -u32 var800a64f0; -u32 var800a64f4; -u32 var800a64f8; -u32 var800a64fc; -u32 var800a6500; -u32 var800a6504; -u32 var800a6508; -u32 var800a650c; -u32 var800a6510; -u32 var800a6514; -u32 var800a6518; -u32 var800a651c; -u32 var800a6520; -u32 var800a6524; -u32 var800a6528; -u32 var800a652c; u32 var800a6530; u32 var800a6534; diff --git a/src/game/explosions.c b/src/game/explosions.c index eee34fdaf..6d10686db 100644 --- a/src/game/explosions.c +++ b/src/game/explosions.c @@ -1214,7 +1214,7 @@ u32 explosionTick(struct prop *prop) } if (g_Rooms[exp->room].gfxdata) { - if (g_Rooms[exp->room].gfxdata->unk0c && func0f161520(&prop->pos, &exp->unk3d0, exp->room, &hitthing)) { + if (g_Rooms[exp->room].gfxdata->unk0c && bgCalculateHitInRoom(&prop->pos, &exp->unk3d0, exp->room, &hitthing)) { xlu = hitthing.unk2c == 2; } diff --git a/src/game/prop.c b/src/game/prop.c index ee37ae581..436f00c11 100644 --- a/src/game/prop.c +++ b/src/game/prop.c @@ -690,7 +690,7 @@ struct prop *shotCalculateHits(s32 handnum, bool arg1, struct coord *arg2, struc roomsGetActive(roomsptr, 100); for (i = 0; rooms[i] != -1; i++) { - if (func0f161520(&shotdata.gunpos, &hitpos, rooms[i], &sp664)) { + if (bgCalculateHitInRoom(&shotdata.gunpos, &hitpos, rooms[i], &sp664)) { sp664.unk00.x *= 1; sp664.unk00.y *= 1; sp664.unk00.z *= 1; diff --git a/src/game/propobj.c b/src/game/propobj.c index 9c9bd6199..c95316965 100644 --- a/src/game/propobj.c +++ b/src/game/propobj.c @@ -6054,7 +6054,7 @@ bool func0f06cd00(struct defaultobj *obj, struct coord *pos, struct coord *arg2, s0 = false; if (roomIsLoaded(spcc[i])) { - if (func0f161520(&prop->pos, &sp1c4, spcc[i], &hitthing)) { + if (bgCalculateHitInRoom(&prop->pos, &sp1c4, spcc[i], &hitthing)) { hitthing.unk00.x *= scale; hitthing.unk00.y *= scale; hitthing.unk00.z *= scale; diff --git a/src/game/splat.c b/src/game/splat.c index 7cd17989e..cb5671e6a 100644 --- a/src/game/splat.c +++ b/src/game/splat.c @@ -277,7 +277,7 @@ bool splat0f149274(f32 arg0, struct prop *chrprop, struct shotdata *shotdata, f3 portal00018148(&stackshotdata.gunpos, &endpos, &gunrooms, &endrooms, rooms, ARRAYCOUNT(rooms) - 1); for (i = 0; rooms[i] != -1; i++) { - if (func0f161520(&stackshotdata.gunpos, &endpos, rooms[i], &hitthing) + if (bgCalculateHitInRoom(&stackshotdata.gunpos, &endpos, rooms[i], &hitthing) && ((stackshotdata.gunpos.x <= endpos.x && hitthing.unk00.x <= endpos.x && stackshotdata.gunpos.x <= hitthing.unk00.x) || (endpos.x <= stackshotdata.gunpos.x && endpos.x <= hitthing.unk00.x && hitthing.unk00.x <= stackshotdata.gunpos.x)) && ((stackshotdata.gunpos.y <= endpos.y && hitthing.unk00.y <= endpos.y && stackshotdata.gunpos.y <= hitthing.unk00.y) || (endpos.y <= stackshotdata.gunpos.y && endpos.y <= hitthing.unk00.y && hitthing.unk00.y <= stackshotdata.gunpos.y)) && ((stackshotdata.gunpos.z <= endpos.z && hitthing.unk00.z <= endpos.z && stackshotdata.gunpos.z <= hitthing.unk00.z) || (endpos.z <= stackshotdata.gunpos.z && endpos.z <= hitthing.unk00.z && hitthing.unk00.z <= stackshotdata.gunpos.z))) { diff --git a/src/include/bss.h b/src/include/bss.h index 7f2d469cd..3c511d9e1 100644 --- a/src/include/bss.h +++ b/src/include/bss.h @@ -220,8 +220,7 @@ extern struct var800a4ccc *var800a4ccc; extern u8 *g_BgLightsFileData; extern s16 *g_RoomPortals; extern struct var800a4cf0 var800a4cf0; -extern u32 var800a6470; -extern u32 var800a647c; +extern struct coord var800a6470[16]; extern struct var800a6538 var800a6538[16]; extern u32 g_BgRoomTestsDisabled; extern struct screenbox var800a65c0; diff --git a/src/include/game/bg.h b/src/include/game/bg.h index de5928c6c..ed6ed0b0d 100644 --- a/src/include/game/bg.h +++ b/src/include/game/bg.h @@ -68,9 +68,9 @@ bool func0f15f20c(struct coord *arg0, struct coord *arg1, s32 *arg2, s32 *arg3); bool bg0f15f2b0(struct coord *arg0, struct coord *arg1, struct coord *arg2, struct coord *arg3); bool func0f15f560(struct coord *arg0, struct coord *arg1, struct coord *arg2, Gfx *arg3, void *arg4, struct gfxvtx *vertices, struct hitthing *hitthing); bool func0f15ffdc(struct model *model, struct coord *arg1, struct coord *arg2, struct coord *arg3, Gfx *arg4, Gfx *arg5, struct gfxvtx *vertices, f32 *arg7, void *arg8); -bool func0f160a38(struct coord *arg0, struct coord *arg1, struct coord *arg2, struct vtxbatch *batches, s32 roomnum, struct hitthing *hitthing); +bool bgCalculateHitInVtxBatch(struct coord *arg0, struct coord *arg1, struct coord *arg2, struct vtxbatch *batches, s32 roomnum, struct hitthing *hitthing); s32 bg0f1612e4(struct coord *bbmin, struct coord *bbmax, struct coord *arg2, struct coord *arg3, struct coord *arg4, struct coord *arg5); -bool func0f161520(struct coord *arg0, struct coord *arg1, s32 roomnum, struct hitthing *hitthing); +bool bgCalculateHitInRoom(struct coord *frompos, struct coord *topos, s32 roomnum, struct hitthing *hitthing); bool roomIsLoaded(s32 room); bool roomContainsCoord(struct coord *pos, s16 roomnum); bool func0f161c08(struct coord *arg0, s16 roomnum); diff --git a/src/include/lib/lib_2f490.h b/src/include/lib/lib_2f490.h index 5d449ede2..fbf0081c8 100644 --- a/src/include/lib/lib_2f490.h +++ b/src/include/lib/lib_2f490.h @@ -5,6 +5,6 @@ #include "types.h" bool func0002f490(struct vec3s16 *arg0, struct vec3s16 *arg1, struct vec3s16 *arg2, s32 arg3, struct coord *arg4, struct coord *arg5, struct coord *arg6, s32 arg7, s32 arg8); -u32 func0002f560(void); +bool func0002f560(struct coord *arg0, struct coord *arg1, struct coord *arg2, s32 arg3, struct coord *arg4, struct coord *arg5, struct coord *arg6, struct coord *arg7, struct coord *arg8); #endif diff --git a/src/include/types.h b/src/include/types.h index 7c377e992..cf3215622 100644 --- a/src/include/types.h +++ b/src/include/types.h @@ -3564,8 +3564,8 @@ struct roomgfxdata { }; struct vtxbatch { - /*0x00*/ s16 gbicmdindex; - /*0x02*/ s16 type; + /*0x00*/ u16 gbicmdindex; + /*0x02*/ u16 type; /*0x04*/ Gfx *gdl; /*0x08*/ struct coord bbmin; /*0x14*/ struct coord bbmax; @@ -5985,10 +5985,10 @@ struct var8009ddec { struct hitthing { struct coord unk00; struct coord unk0c; - u32 unk18; - u32 unk1c; - u32 unk20; - u32 unk24; + void *unk18; + void *unk1c; + void *unk20; + Gfx *unk24; s16 unk28; s16 texturenum; s16 unk2c;