From b34c9afde3360078bfc50f53b8a02e44b457503c Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sat, 11 Sep 2021 16:36:10 +1000 Subject: [PATCH] Decompile padsPrepare --- src/game/game_00c490.c | 2 +- src/game/game_012aa0.c | 286 ++++++++++++--------------------- src/game/game_013ee0.c | 4 +- src/game/pad.c | 12 +- src/include/bss.h | 2 +- src/include/game/game_012aa0.h | 2 +- src/include/game/game_013ee0.h | 2 +- src/include/types.h | 15 ++ 8 files changed, 127 insertions(+), 198 deletions(-) diff --git a/src/game/game_00c490.c b/src/game/game_00c490.c index 5d3191db4..f1fc56fb6 100644 --- a/src/game/game_00c490.c +++ b/src/game/game_00c490.c @@ -2894,7 +2894,7 @@ void setupParseObjects(s32 stagenum) if (stagenum < STAGE_TITLE) { if (g_StageSetup.padfiledata) { - func0f012aa0(); + padsPrepare(); } waypointsLoad(); diff --git a/src/game/game_012aa0.c b/src/game/game_012aa0.c index b6ab4fcc4..0832b6a82 100644 --- a/src/game/game_012aa0.c +++ b/src/game/game_012aa0.c @@ -12,189 +12,103 @@ #include "data.h" #include "types.h" -GLOBAL_ASM( -glabel func0f012aa0 -/* f012aa0: 27bdfed0 */ addiu $sp,$sp,-304 -/* f012aa4: afb5003c */ sw $s5,0x3c($sp) -/* f012aa8: 3c15800a */ lui $s5,%hi(g_StageSetup) -/* f012aac: 26b5d030 */ addiu $s5,$s5,%lo(g_StageSetup) -/* f012ab0: 8ea2001c */ lw $v0,0x1c($s5) -/* f012ab4: 3c04800a */ lui $a0,%hi(g_PadsFile) -/* f012ab8: 3c07800a */ lui $a3,%hi(g_PadOffsets) -/* f012abc: 24e72354 */ addiu $a3,$a3,%lo(g_PadOffsets) -/* f012ac0: 24842350 */ addiu $a0,$a0,%lo(g_PadsFile) -/* f012ac4: 244e0014 */ addiu $t6,$v0,0x14 -/* f012ac8: afbf004c */ sw $ra,0x4c($sp) -/* f012acc: afbe0048 */ sw $s8,0x48($sp) -/* f012ad0: afb70044 */ sw $s7,0x44($sp) -/* f012ad4: afb60040 */ sw $s6,0x40($sp) -/* f012ad8: afb40038 */ sw $s4,0x38($sp) -/* f012adc: afb30034 */ sw $s3,0x34($sp) -/* f012ae0: afb20030 */ sw $s2,0x30($sp) -/* f012ae4: afb1002c */ sw $s1,0x2c($sp) -/* f012ae8: afb00028 */ sw $s0,0x28($sp) -/* f012aec: f7b40020 */ sdc1 $f20,0x20($sp) -/* f012af0: acee0000 */ sw $t6,0x0($a3) -/* f012af4: ac820000 */ sw $v0,0x0($a0) -/* f012af8: 8c480000 */ lw $t0,0x0($v0) -/* f012afc: 00009025 */ or $s2,$zero,$zero -/* f012b00: 0000a025 */ or $s4,$zero,$zero -/* f012b04: 1900005e */ blez $t0,.L0f012c80 -/* f012b08: 00401825 */ or $v1,$v0,$zero -/* f012b0c: 3c013f80 */ lui $at,0x3f80 -/* f012b10: 4481a000 */ mtc1 $at,$f20 -/* f012b14: afa80120 */ sw $t0,0x120($sp) -/* f012b18: 241effff */ addiu $s8,$zero,-1 -/* f012b1c: 27b70064 */ addiu $s7,$sp,0x64 -/* f012b20: 27b60090 */ addiu $s6,$sp,0x90 -/* f012b24: 27b300c8 */ addiu $s3,$sp,0xc8 -.L0f012b28: -/* f012b28: 3c07800a */ lui $a3,%hi(g_PadOffsets) -/* f012b2c: 24e72354 */ addiu $a3,$a3,%lo(g_PadOffsets) -/* f012b30: 8cef0000 */ lw $t7,0x0($a3) -/* f012b34: 8eb9001c */ lw $t9,0x1c($s5) -/* f012b38: 02402025 */ or $a0,$s2,$zero -/* f012b3c: 01f4c021 */ addu $t8,$t7,$s4 -/* f012b40: 97020000 */ lhu $v0,0x0($t8) -/* f012b44: 24050022 */ addiu $a1,$zero,0x22 -/* f012b48: 02603025 */ or $a2,$s3,$zero -/* f012b4c: 0fc456ac */ jal padUnpack -/* f012b50: 03228821 */ addu $s1,$t9,$v0 -/* f012b54: 8e290000 */ lw $t1,0x0($s1) -/* f012b58: 00008025 */ or $s0,$zero,$zero -/* f012b5c: 02602025 */ or $a0,$s3,$zero -/* f012b60: 00095480 */ sll $t2,$t1,0x12 -/* f012b64: 000a5d83 */ sra $t3,$t2,0x16 -/* f012b68: 05610023 */ bgez $t3,.L0f012bf8 -/* f012b6c: 02c02825 */ or $a1,$s6,$zero -/* f012b70: 02e03025 */ or $a2,$s7,$zero -/* f012b74: 24070014 */ addiu $a3,$zero,0x14 -/* f012b78: 0fc58865 */ jal func0f162194 -/* f012b7c: afa00010 */ sw $zero,0x10($sp) -/* f012b80: 87ac0090 */ lh $t4,0x90($sp) -/* f012b84: 87ad0064 */ lh $t5,0x64($sp) -/* f012b88: 02602025 */ or $a0,$s3,$zero -/* f012b8c: 13cc0003 */ beq $s8,$t4,.L0f012b9c -/* f012b90: 00000000 */ nop -/* f012b94: 10000004 */ b .L0f012ba8 -/* f012b98: 02c08025 */ or $s0,$s6,$zero -.L0f012b9c: -/* f012b9c: 13cd0002 */ beq $s8,$t5,.L0f012ba8 -/* f012ba0: 00000000 */ nop -/* f012ba4: 02e08025 */ or $s0,$s7,$zero -.L0f012ba8: -/* f012ba8: 52000014 */ beqzl $s0,.L0f012bfc -/* f012bac: 8e2b0000 */ lw $t3,0x0($s1) -/* f012bb0: 0c00a900 */ jal func0002a400 -/* f012bb4: 02002825 */ or $a1,$s0,$zero -/* f012bb8: 58400009 */ blezl $v0,.L0f012be0 -/* f012bbc: 860e0000 */ lh $t6,0x0($s0) -/* f012bc0: 86290002 */ lh $t1,0x2($s1) -/* f012bc4: 0002c100 */ sll $t8,$v0,0x4 -/* f012bc8: 33193ff0 */ andi $t9,$t8,0x3ff0 -/* f012bcc: 312ac00f */ andi $t2,$t1,0xc00f -/* f012bd0: 032a5825 */ or $t3,$t9,$t2 -/* f012bd4: 10000008 */ b .L0f012bf8 -/* f012bd8: a62b0002 */ sh $t3,0x2($s1) -/* f012bdc: 860e0000 */ lh $t6,0x0($s0) -.L0f012be0: -/* f012be0: 86290002 */ lh $t1,0x2($s1) -/* f012be4: 000e7900 */ sll $t7,$t6,0x4 -/* f012be8: 31f83ff0 */ andi $t8,$t7,0x3ff0 -/* f012bec: 3139c00f */ andi $t9,$t1,0xc00f -/* f012bf0: 03195025 */ or $t2,$t8,$t9 -/* f012bf4: a62a0002 */ sh $t2,0x2($s1) -.L0f012bf8: -/* f012bf8: 8e2b0000 */ lw $t3,0x0($s1) -.L0f012bfc: -/* f012bfc: c7a400f8 */ lwc1 $f4,0xf8($sp) -/* f012c00: 000b6382 */ srl $t4,$t3,0xe -/* f012c04: 318d0200 */ andi $t5,$t4,0x200 -/* f012c08: 51a00016 */ beqzl $t5,.L0f012c64 -/* f012c0c: 8fae0120 */ lw $t6,0x120($sp) -/* f012c10: 46142182 */ mul.s $f6,$f4,$f20 -/* f012c14: c7a800fc */ lwc1 $f8,0xfc($sp) -/* f012c18: c7b00100 */ lwc1 $f16,0x100($sp) -/* f012c1c: c7a40104 */ lwc1 $f4,0x104($sp) -/* f012c20: 46144282 */ mul.s $f10,$f8,$f20 -/* f012c24: c7a80108 */ lwc1 $f8,0x108($sp) -/* f012c28: 02402025 */ or $a0,$s2,$zero -/* f012c2c: 46148482 */ mul.s $f18,$f16,$f20 -/* f012c30: e7a600f8 */ swc1 $f6,0xf8($sp) -/* f012c34: c7b0010c */ lwc1 $f16,0x10c($sp) -/* f012c38: 46142182 */ mul.s $f6,$f4,$f20 -/* f012c3c: e7aa00fc */ swc1 $f10,0xfc($sp) -/* f012c40: 02602825 */ or $a1,$s3,$zero -/* f012c44: 46144282 */ mul.s $f10,$f8,$f20 -/* f012c48: e7b20100 */ swc1 $f18,0x100($sp) -/* f012c4c: 46148482 */ mul.s $f18,$f16,$f20 -/* f012c50: e7a60104 */ swc1 $f6,0x104($sp) -/* f012c54: e7aa0108 */ swc1 $f10,0x108($sp) -/* f012c58: 0fc45864 */ jal padCopyBboxFromPad -/* f012c5c: e7b2010c */ swc1 $f18,0x10c($sp) -/* f012c60: 8fae0120 */ lw $t6,0x120($sp) -.L0f012c64: -/* f012c64: 26520001 */ addiu $s2,$s2,0x1 -/* f012c68: 26940002 */ addiu $s4,$s4,0x2 -/* f012c6c: 164effae */ bne $s2,$t6,.L0f012b28 -/* f012c70: 00000000 */ nop -/* f012c74: 3c03800a */ lui $v1,%hi(g_PadsFile) -/* f012c78: 8c632350 */ lw $v1,%lo(g_PadsFile)($v1) -/* f012c7c: 8ea2001c */ lw $v0,0x1c($s5) -.L0f012c80: -/* f012c80: 8c6f0008 */ lw $t7,0x8($v1) -/* f012c84: 004f4821 */ addu $t1,$v0,$t7 -/* f012c88: aea90000 */ sw $t1,0x0($s5) -/* f012c8c: 8c78000c */ lw $t8,0xc($v1) -/* f012c90: 0058c821 */ addu $t9,$v0,$t8 -/* f012c94: aeb90004 */ sw $t9,0x4($s5) -/* f012c98: 8c6a0010 */ lw $t2,0x10($v1) -/* f012c9c: 004a5821 */ addu $t3,$v0,$t2 -/* f012ca0: 11600003 */ beqz $t3,.L0f012cb0 -/* f012ca4: aeab0008 */ sw $t3,0x8($s5) -/* f012ca8: 0fc050ba */ jal coverLoad -/* f012cac: 00000000 */ nop -.L0f012cb0: -/* f012cb0: 8ea20000 */ lw $v0,0x0($s5) -/* f012cb4: 8c4d0000 */ lw $t5,0x0($v0) -/* f012cb8: 05a20009 */ bltzl $t5,.L0f012ce0 -/* f012cbc: 8ea20004 */ lw $v0,0x4($s5) -.L0f012cc0: -/* f012cc0: 8eae001c */ lw $t6,0x1c($s5) -/* f012cc4: 8c4f0004 */ lw $t7,0x4($v0) -/* f012cc8: 8c580010 */ lw $t8,0x10($v0) -/* f012ccc: 24420010 */ addiu $v0,$v0,0x10 -/* f012cd0: 01cf4821 */ addu $t1,$t6,$t7 -/* f012cd4: 0701fffa */ bgez $t8,.L0f012cc0 -/* f012cd8: ac49fff4 */ sw $t1,-0xc($v0) -/* f012cdc: 8ea20004 */ lw $v0,0x4($s5) -.L0f012ce0: -/* f012ce0: 8c430000 */ lw $v1,0x0($v0) -/* f012ce4: 5060000c */ beqzl $v1,.L0f012d18 -/* f012ce8: 8fbf004c */ lw $ra,0x4c($sp) -.L0f012cec: -/* f012cec: 8eb9001c */ lw $t9,0x1c($s5) -/* f012cf0: 8c4c0004 */ lw $t4,0x4($v0) -/* f012cf4: 2442000c */ addiu $v0,$v0,0xc -/* f012cf8: 03235021 */ addu $t2,$t9,$v1 -/* f012cfc: ac4afff4 */ sw $t2,-0xc($v0) -/* f012d00: 8eab001c */ lw $t3,0x1c($s5) -/* f012d04: 8c430000 */ lw $v1,0x0($v0) -/* f012d08: 016c6821 */ addu $t5,$t3,$t4 -/* f012d0c: 1460fff7 */ bnez $v1,.L0f012cec -/* f012d10: ac4dfff8 */ sw $t5,-0x8($v0) -/* f012d14: 8fbf004c */ lw $ra,0x4c($sp) -.L0f012d18: -/* f012d18: d7b40020 */ ldc1 $f20,0x20($sp) -/* f012d1c: 8fb00028 */ lw $s0,0x28($sp) -/* f012d20: 8fb1002c */ lw $s1,0x2c($sp) -/* f012d24: 8fb20030 */ lw $s2,0x30($sp) -/* f012d28: 8fb30034 */ lw $s3,0x34($sp) -/* f012d2c: 8fb40038 */ lw $s4,0x38($sp) -/* f012d30: 8fb5003c */ lw $s5,0x3c($sp) -/* f012d34: 8fb60040 */ lw $s6,0x40($sp) -/* f012d38: 8fb70044 */ lw $s7,0x44($sp) -/* f012d3c: 8fbe0048 */ lw $s8,0x48($sp) -/* f012d40: 03e00008 */ jr $ra -/* f012d44: 27bd0130 */ addiu $sp,$sp,0x130 -); +/** + * The function assumes that a pad file's data has been loaded from the ROM + * and is pointed to by g_StageSetup.padfiledata. These pads are in a packed + * format. During gameplay, the game uses padUnpack as needed to temporarily + * populate pad structs from this data. + * + * padsPrepare prepares the packed data by doing the following: + * - populates the room field (if -1) + * - multiplies each pad's bounding box by 1 (this is effectively a no op) + * - sets the g_StageSetup pad/waygroup/waypoint/cover pointers + * - promotes file offsets to RAM pointers + * - does similar things for cover by calling coverPrepare() + */ +void padsPrepare(void) +{ + struct packedpad *packedpad; + s16 *roomsptr; + s32 padnum; + s32 numpads; + s32 roomnum; + struct pad pad; + struct waypoint *waypoint; + struct waygroup *waygroup; + s16 sp90[24]; + s16 sp64[22]; + s32 offset; + + g_PadsFile = (struct padsfileheader *)g_StageSetup.padfiledata; + g_PadOffsets = (u16 *)(g_StageSetup.padfiledata + 0x14); + padnum = 0; + numpads = g_PadsFile->numpads; + + for (; padnum < numpads; padnum++) { + offset = g_PadOffsets[padnum]; + packedpad = (struct packedpad *) &g_StageSetup.padfiledata[offset]; + padUnpack(padnum, PADFIELD_POS | PADFIELD_BBOX, &pad); + + // If room is negative (ie. not specified) + if (packedpad->room < 0) { + roomsptr = NULL; + func0f162194(&pad.pos, sp90, sp64, 20, 0); + + if (sp90[0] != -1) { + roomsptr = sp90; + } else if (sp64[0] != -1) { + roomsptr = sp64; + } + + if (roomsptr != NULL) { + roomnum = func0002a400(&pad.pos, roomsptr); + + if (roomnum > 0) { + packedpad->room = roomnum; + } else { + packedpad->room = roomsptr[0]; + } + } + } + + // Scale the bbox by 1 and save it back into the packed pad data. + // Yeah, this is effectively doing nothing. + if ((*(u32 *) packedpad >> 14) & PADFLAG_HASBBOXDATA) { + f32 scale = 1; + + pad.bbox.xmin *= scale; + pad.bbox.xmax *= scale; + pad.bbox.ymin *= scale; + pad.bbox.ymax *= scale; + pad.bbox.zmin *= scale; + pad.bbox.zmax *= scale; + + padCopyBboxFromPad(padnum, &pad); + } + } + + g_StageSetup.waypoints = (struct waypoint *) ((u32)g_StageSetup.padfiledata + g_PadsFile->waypointsoffset); + g_StageSetup.waygroups = (struct waygroup *) ((u32)g_StageSetup.padfiledata + g_PadsFile->waygroupsoffset); + g_StageSetup.cover = (void *) ((s32)g_StageSetup.padfiledata + g_PadsFile->coversoffset); + + if (g_StageSetup.cover != NULL) { + coverPrepare(); + } + + // Promote offsets to pointers in waypoints + waypoint = g_StageSetup.waypoints; + + while (waypoint->padnum >= 0) { + waypoint->neighbours = (s32 *)((u32)g_StageSetup.padfiledata + (u32)waypoint->neighbours); + waypoint++; + } + + // Promote offsets to pointers in waygroups + waygroup = g_StageSetup.waygroups; + + while (waygroup->neighbours != NULL) { + waygroup->neighbours = (s32 *)((u32)g_StageSetup.padfiledata + (u32)waygroup->neighbours); + waygroup->waypoints = (s32 *)((u32)g_StageSetup.padfiledata + (u32)waygroup->waypoints); + waygroup++; + } +} diff --git a/src/game/game_013ee0.c b/src/game/game_013ee0.c index 82591c309..2ff3306d6 100644 --- a/src/game/game_013ee0.c +++ b/src/game/game_013ee0.c @@ -50,10 +50,10 @@ void coverAllocateSpecial(u16 *specialcovernums) } } -void coverLoad(void) +void coverPrepare(void) { s32 i; - s32 numcovers = g_PadsFile[1]; + s32 numcovers = g_PadsFile->numcovers; s16 *roomsptr; f32 scale = 1; struct coord aimpos; diff --git a/src/game/pad.c b/src/game/pad.c index 544dbb04a..8a29e4398 100644 --- a/src/game/pad.c +++ b/src/game/pad.c @@ -5,7 +5,7 @@ #include "data.h" #include "types.h" -s32 *g_PadsFile; +struct padsfileheader *g_PadsFile; u16 *g_PadOffsets; u32 var800a2358; u32 var800a235c; @@ -611,14 +611,14 @@ bool func0f1162c4(s32 padnum, s32 arg1) s32 coverGetCount(void) { - return g_PadsFile[1]; + return g_PadsFile->numcovers; } bool coverUnpack(s32 covernum, struct cover *cover) { struct coverdefinition *def; - if (covernum >= g_PadsFile[1] || covernum < 0 || !g_StageSetup.cover) { + if (covernum >= g_PadsFile->numcovers || covernum < 0 || !g_StageSetup.cover) { return false; } @@ -678,7 +678,7 @@ s32 func0f116450(s32 arg0, s32 arg1) bool coverIsInUse(s32 covernum) { // @bug: Second condition should be >= - if (covernum < 0 || covernum > g_PadsFile[1]) { + if (covernum < 0 || covernum > g_PadsFile->numcovers) { return false; } @@ -687,7 +687,7 @@ bool coverIsInUse(s32 covernum) void coverSetInUse(s32 covernum, bool enable) { - if (covernum >= 0 && covernum < g_PadsFile[1]) { + if (covernum >= 0 && covernum < g_PadsFile->numcovers) { if (enable) { g_CoverFlags[covernum] |= COVERFLAG_INUSE; } else { @@ -708,7 +708,7 @@ void coverUnsetFlag(s32 covernum, u32 flag) void coverSetFlag0001(s32 covernum, bool enable) { - if (covernum >= 0 && covernum < g_PadsFile[1]) { + if (covernum >= 0 && covernum < g_PadsFile->numcovers) { if (enable) { g_CoverFlags[covernum] |= COVERFLAG_0001; } else { diff --git a/src/include/bss.h b/src/include/bss.h index 0311f2b6a..935e11494 100644 --- a/src/include/bss.h +++ b/src/include/bss.h @@ -202,7 +202,7 @@ extern struct savefile_solo g_SoloSaveFile; extern struct savelocation_2d8 g_FilemgrLoadedMainFile; extern s8 g_SoloCompleted; extern u8 g_AltTitle; -extern s32 *g_PadsFile; +extern struct padsfileheader *g_PadsFile; extern u16 *g_PadOffsets; extern u16 *g_CoverFlags; extern s32 *g_CoverRooms; diff --git a/src/include/game/game_012aa0.h b/src/include/game/game_012aa0.h index b3031f1fe..176f7a579 100644 --- a/src/include/game/game_012aa0.h +++ b/src/include/game/game_012aa0.h @@ -4,6 +4,6 @@ #include "data.h" #include "types.h" -void func0f012aa0(void); +void padsPrepare(void); #endif diff --git a/src/include/game/game_013ee0.h b/src/include/game/game_013ee0.h index 3f332fdde..98dab20c0 100644 --- a/src/include/game/game_013ee0.h +++ b/src/include/game/game_013ee0.h @@ -6,6 +6,6 @@ void func0f013ee0(void); void coverAllocateSpecial(u16 *specialcovernums); -void coverLoad(void); +void coverPrepare(void); #endif diff --git a/src/include/types.h b/src/include/types.h index faf4a145a..f7c8e8563 100644 --- a/src/include/types.h +++ b/src/include/types.h @@ -423,6 +423,12 @@ struct prop { /*0x44*/ struct var800a41b0 *unk44; }; +struct packedpad { + s32 flags : 18; + s32 room : 10; + s32 liftnum : 4; +}; + struct pad { /*0x00*/ struct coord pos; /*0x0c*/ struct coord look; @@ -2948,6 +2954,15 @@ struct cover { /*0x0c*/ u16 flags; }; +struct padsfileheader { + s32 numpads; + s32 numcovers; + s32 waypointsoffset; + s32 waygroupsoffset; + s32 coversoffset; + s16 padoffsets[1]; +}; + struct stagesetup { /*0x00*/ struct waypoint *waypoints; /*0x04*/ struct waygroup *waygroups;