diff --git a/src/game/bondgun.c b/src/game/bondgun.c index 4e60f7c13..b304e9b70 100644 --- a/src/game/bondgun.c +++ b/src/game/bondgun.c @@ -11306,7 +11306,7 @@ glabel bgunTickIncLoad /* f09e950: ae0b0794 */ sw $t3,0x794($s0) /* f09e954: 8e4c1590 */ lw $t4,0x1590($s2) /* f09e958: 8e4615a8 */ lw $a2,0x15a8($s2) -/* f09e95c: 0fc28ba5 */ jal bgun0f0a2e94 +/* f09e95c: 0fc28ba5 */ jal bgunCreateModelCmdList /* f09e960: 8d850000 */ lw $a1,0x0($t4) /* f09e964: 8e4d15a8 */ lw $t5,0x15a8($s2) /* f09e968: 8e4f15ac */ lw $t7,0x15ac($s2) @@ -11321,7 +11321,7 @@ glabel bgunTickIncLoad /* f09e98c: 8e491594 */ lw $t1,0x1594($s2) /* f09e990: 8e4615a8 */ lw $a2,0x15a8($s2) /* f09e994: 26040534 */ addiu $a0,$s0,0x534 -/* f09e998: 0fc28ba5 */ jal bgun0f0a2e94 +/* f09e998: 0fc28ba5 */ jal bgunCreateModelCmdList /* f09e99c: 8d250000 */ lw $a1,0x0($t1) /* f09e9a0: 8e4a15a8 */ lw $t2,0x15a8($s2) /* f09e9a4: 8e4c15ac */ lw $t4,0x15ac($s2) @@ -11713,7 +11713,7 @@ glabel bgunTickIncLoad /* f09c7fc: ae0c0794 */ sw $t4,0x794($s0) /* f09c800: 8e4d1590 */ lw $t5,0x1590($s2) /* f09c804: 8e4615a8 */ lw $a2,0x15a8($s2) -/* f09c808: 0fc282e3 */ jal bgun0f0a2e94 +/* f09c808: 0fc282e3 */ jal bgunCreateModelCmdList /* f09c80c: 8da50000 */ lw $a1,0x0($t5) /* f09c810: 8e4e15a8 */ lw $t6,0x15a8($s2) /* f09c814: 8e5815ac */ lw $t8,0x15ac($s2) @@ -11728,7 +11728,7 @@ glabel bgunTickIncLoad /* f09c838: 8e4a1594 */ lw $t2,0x1594($s2) /* f09c83c: 8e4615a8 */ lw $a2,0x15a8($s2) /* f09c840: 26040534 */ addiu $a0,$s0,0x534 -/* f09c844: 0fc282e3 */ jal bgun0f0a2e94 +/* f09c844: 0fc282e3 */ jal bgunCreateModelCmdList /* f09c848: 8d450000 */ lw $a1,0x0($t2) /* f09c84c: 8e4b15a8 */ lw $t3,0x15a8($s2) /* f09c850: 8e4d15ac */ lw $t5,0x15ac($s2) @@ -11972,7 +11972,7 @@ glabel bgunTickIncLoad // // hand->unk0dcc = player->gunctrl.unk15a8; // -// value = bgun0f0a2e94(&hand->gunmodel, player->gunctrl.gunmodeldef->rootnode, player->gunctrl.unk15a8); +// value = bgunCreateModelCmdList(&hand->gunmodel, player->gunctrl.gunmodeldef->rootnode, player->gunctrl.unk15a8); // // sum += value; // player->gunctrl.unk15a8 += value; @@ -11981,7 +11981,7 @@ glabel bgunTickIncLoad // if (player->gunctrl.handmodeldef != 0) { // hand->unk0dd0 = player->gunctrl.unk15a8; // -// value = bgun0f0a2e94(&hand->handmodel, player->gunctrl.handmodeldef->rootnode, player->gunctrl.unk15a8); +// value = bgunCreateModelCmdList(&hand->handmodel, player->gunctrl.handmodeldef->rootnode, player->gunctrl.unk15a8); // // sum += value; // player->gunctrl.unk15a8 += value; @@ -14370,261 +14370,168 @@ void bgunLoseGun(struct prop *attackerprop) } } -// With this function stubbed, part of the CMP150 model does not render. -void bgun0f0a2da8(s32 *arg0) +/** + * Execute some sort of command list that was generated by the function below. + * + * With this function stubbed, part of the CMP150 model does not render. + */ +void bgunExecuteModelCmdList(s32 *ptr) { - s32 *ptr1; - s32 *ptr2; - s16 *ptr3; + union modelrwdata *rwdata; + struct modelnode *node; - if (arg0 != NULL) { - while (*arg0 != 6) { - switch (*arg0) { + if (ptr != NULL) { + while (*ptr != 6) { + switch (*ptr) { case 0: - ptr1 = (s32 *)arg0[1]; - ptr2 = (s32 *)arg0[2]; - ptr1[0] = 0; - ptr2[5] = arg0[3]; - arg0 += 4; + rwdata = (union modelrwdata *)ptr[1]; + node = (struct modelnode *)ptr[2]; + rwdata->distance.visible = false; + node->child = (struct modelnode *)ptr[3]; + ptr += 4; break; case 1: - ptr1 = (s32 *)arg0[1]; - ptr2 = (s32 *)arg0[2]; - ptr1[0] = 1; - ptr2[5] = arg0[3]; - arg0 += 4; + rwdata = (union modelrwdata *)ptr[1]; + node = (struct modelnode *)ptr[2]; + rwdata->toggle.visible = true; + node->child = (struct modelnode *)ptr[3]; + ptr += 4; break; case 2: - ptr1 = (s32 *)arg0[1]; - ptr1[0] = 0; - ptr1[1] = 0; - arg0 += 2; + rwdata = (union modelrwdata *)ptr[1]; + rwdata->headspot.modelfiledata = NULL; + rwdata->headspot.rwdatas = NULL; + ptr += 2; break; case 3: - ptr3 = (s16 *)arg0[1]; - ptr3[0] = 0; - arg0 += 2; + rwdata = (union modelrwdata *)ptr[1]; + rwdata->type0b.unk00 = 0; + ptr += 2; break; case 4: - ptr3 = (s16 *)arg0[1]; - ptr3[0] = 0; - arg0 += 2; + rwdata = (union modelrwdata *)ptr[1]; + rwdata->gunfire.visible = false; + ptr += 2; break; case 5: - ptr1 = (s32 *)arg0[1]; - ptr1[0] = arg0[2]; - ptr1[1] = arg0[3]; - ptr1[2] = arg0[4]; - arg0 += 5; + rwdata = (union modelrwdata *)ptr[1]; + rwdata->dl.vertices = (struct gfxvtx *)ptr[2]; + rwdata->dl.gdl = (Gfx *)ptr[3]; + rwdata->dl.colours = (struct colour *)ptr[4]; + ptr += 5; break; } } } } -GLOBAL_ASM( -glabel bgun0f0a2e94 -.late_rodata -glabel var7f1ac784 -.word bgun0f0a2e94+0x7c # f0a2f10 -glabel var7f1ac788 -.word bgun0f0a2e94+0x1dc # f0a3070 -glabel var7f1ac78c -.word bgun0f0a2e94+0x1dc # f0a3070 -glabel var7f1ac790 -.word bgun0f0a2e94+0x120 # f0a2fb4 -glabel var7f1ac794 -.word bgun0f0a2e94+0x148 # f0a2fdc -glabel var7f1ac798 -.word bgun0f0a2e94+0x1dc # f0a3070 -glabel var7f1ac79c -.word bgun0f0a2e94+0x1dc # f0a3070 -glabel var7f1ac7a0 -.word bgun0f0a2e94+0x1dc # f0a3070 -glabel var7f1ac7a4 -.word bgun0f0a2e94+0x1dc # f0a3070 -glabel var7f1ac7a8 -.word bgun0f0a2e94+0x1dc # f0a3070 -glabel var7f1ac7ac -.word bgun0f0a2e94+0xb8 # f0a2f4c -glabel var7f1ac7b0 -.word bgun0f0a2e94+0x1dc # f0a3070 -glabel var7f1ac7b4 -.word bgun0f0a2e94+0x1dc # f0a3070 -glabel var7f1ac7b8 -.word bgun0f0a2e94+0x1dc # f0a3070 -glabel var7f1ac7bc -.word bgun0f0a2e94+0x1dc # f0a3070 -glabel var7f1ac7c0 -.word bgun0f0a2e94+0xf4 # f0a2f88 -glabel var7f1ac7c4 -.word bgun0f0a2e94+0x170 # f0a3004 -.text -/* f0a2e94: 27bdffc0 */ addiu $sp,$sp,-64 -/* f0a2e98: afb60030 */ sw $s6,0x30($sp) -/* f0a2e9c: afb40028 */ sw $s4,0x28($sp) -/* f0a2ea0: afb30024 */ sw $s3,0x24($sp) -/* f0a2ea4: afb1001c */ sw $s1,0x1c($sp) -/* f0a2ea8: afb00018 */ sw $s0,0x18($sp) -/* f0a2eac: 00c08825 */ or $s1,$a2,$zero -/* f0a2eb0: 0080a025 */ or $s4,$a0,$zero -/* f0a2eb4: 00a0b025 */ or $s6,$a1,$zero -/* f0a2eb8: afbf003c */ sw $ra,0x3c($sp) -/* f0a2ebc: afbe0038 */ sw $s8,0x38($sp) -/* f0a2ec0: afb70034 */ sw $s7,0x34($sp) -/* f0a2ec4: afb5002c */ sw $s5,0x2c($sp) -/* f0a2ec8: afb20020 */ sw $s2,0x20($sp) -/* f0a2ecc: 00009825 */ or $s3,$zero,$zero -/* f0a2ed0: 10a0007d */ beqz $a1,.L0f0a30c8 -/* f0a2ed4: 00a08025 */ or $s0,$a1,$zero -/* f0a2ed8: 241e0005 */ addiu $s8,$zero,0x5 -/* f0a2edc: 2417000c */ addiu $s7,$zero,0xc -/* f0a2ee0: 24150001 */ addiu $s5,$zero,0x1 -/* f0a2ee4: 96020000 */ lhu $v0,0x0($s0) -.L0f0a2ee8: -/* f0a2ee8: 304e00ff */ andi $t6,$v0,0xff -/* f0a2eec: 25cffff8 */ addiu $t7,$t6,-8 -/* f0a2ef0: 2de10011 */ sltiu $at,$t7,0x11 -/* f0a2ef4: 1020005e */ beqz $at,.L0f0a3070 -/* f0a2ef8: 000f7880 */ sll $t7,$t7,0x2 -/* f0a2efc: 3c017f1b */ lui $at,%hi(var7f1ac784) -/* f0a2f00: 002f0821 */ addu $at,$at,$t7 -/* f0a2f04: 8c2fc784 */ lw $t7,%lo(var7f1ac784)($at) -/* f0a2f08: 01e00008 */ jr $t7 -/* f0a2f0c: 00000000 */ nop -/* f0a2f10: 8e120004 */ lw $s2,0x4($s0) -/* f0a2f14: 02802025 */ or $a0,$s4,$zero -/* f0a2f18: 0c006a87 */ jal modelGetNodeRwData -/* f0a2f1c: 02002825 */ or $a1,$s0,$zero -/* f0a2f20: ac400000 */ sw $zero,0x0($v0) -/* f0a2f24: 8e580008 */ lw $t8,0x8($s2) -/* f0a2f28: 26310010 */ addiu $s1,$s1,0x10 -/* f0a2f2c: 26730010 */ addiu $s3,$s3,0x10 -/* f0a2f30: ae180014 */ sw $t8,0x14($s0) -/* f0a2f34: ae20fff0 */ sw $zero,-0x10($s1) -/* f0a2f38: ae22fff4 */ sw $v0,-0xc($s1) -/* f0a2f3c: ae30fff8 */ sw $s0,-0x8($s1) -/* f0a2f40: 8e590008 */ lw $t9,0x8($s2) -/* f0a2f44: 1000004a */ b .L0f0a3070 -/* f0a2f48: ae39fffc */ sw $t9,-0x4($s1) -/* f0a2f4c: 8e120004 */ lw $s2,0x4($s0) -/* f0a2f50: 02802025 */ or $a0,$s4,$zero -/* f0a2f54: 0c006a87 */ jal modelGetNodeRwData -/* f0a2f58: 02002825 */ or $a1,$s0,$zero -/* f0a2f5c: ac550000 */ sw $s5,0x0($v0) -/* f0a2f60: 8e480000 */ lw $t0,0x0($s2) -/* f0a2f64: 26310010 */ addiu $s1,$s1,0x10 -/* f0a2f68: 26730010 */ addiu $s3,$s3,0x10 -/* f0a2f6c: ae080014 */ sw $t0,0x14($s0) -/* f0a2f70: ae35fff0 */ sw $s5,-0x10($s1) -/* f0a2f74: ae22fff4 */ sw $v0,-0xc($s1) -/* f0a2f78: ae30fff8 */ sw $s0,-0x8($s1) -/* f0a2f7c: 8e490000 */ lw $t1,0x0($s2) -/* f0a2f80: 1000003b */ b .L0f0a3070 -/* f0a2f84: ae29fffc */ sw $t1,-0x4($s1) -/* f0a2f88: 02802025 */ or $a0,$s4,$zero -/* f0a2f8c: 0c006a87 */ jal modelGetNodeRwData -/* f0a2f90: 02002825 */ or $a1,$s0,$zero -/* f0a2f94: ac400000 */ sw $zero,0x0($v0) -/* f0a2f98: ac400004 */ sw $zero,0x4($v0) -/* f0a2f9c: 240a0002 */ addiu $t2,$zero,0x2 -/* f0a2fa0: ae2a0000 */ sw $t2,0x0($s1) -/* f0a2fa4: ae220004 */ sw $v0,0x4($s1) -/* f0a2fa8: 26310008 */ addiu $s1,$s1,0x8 -/* f0a2fac: 10000030 */ b .L0f0a3070 -/* f0a2fb0: 26730008 */ addiu $s3,$s3,0x8 -/* f0a2fb4: 02802025 */ or $a0,$s4,$zero -/* f0a2fb8: 0c006a87 */ jal modelGetNodeRwData -/* f0a2fbc: 02002825 */ or $a1,$s0,$zero -/* f0a2fc0: a4400000 */ sh $zero,0x0($v0) -/* f0a2fc4: 240b0003 */ addiu $t3,$zero,0x3 -/* f0a2fc8: ae2b0000 */ sw $t3,0x0($s1) -/* f0a2fcc: ae220004 */ sw $v0,0x4($s1) -/* f0a2fd0: 26310008 */ addiu $s1,$s1,0x8 -/* f0a2fd4: 10000026 */ b .L0f0a3070 -/* f0a2fd8: 26730008 */ addiu $s3,$s3,0x8 -/* f0a2fdc: 02802025 */ or $a0,$s4,$zero -/* f0a2fe0: 0c006a87 */ jal modelGetNodeRwData -/* f0a2fe4: 02002825 */ or $a1,$s0,$zero -/* f0a2fe8: a4400000 */ sh $zero,0x0($v0) -/* f0a2fec: 240c0004 */ addiu $t4,$zero,0x4 -/* f0a2ff0: ae2c0000 */ sw $t4,0x0($s1) -/* f0a2ff4: ae220004 */ sw $v0,0x4($s1) -/* f0a2ff8: 26310008 */ addiu $s1,$s1,0x8 -/* f0a2ffc: 1000001c */ b .L0f0a3070 -/* f0a3000: 26730008 */ addiu $s3,$s3,0x8 -/* f0a3004: 8e120004 */ lw $s2,0x4($s0) -/* f0a3008: 02802025 */ or $a0,$s4,$zero -/* f0a300c: 0c006a87 */ jal modelGetNodeRwData -/* f0a3010: 02002825 */ or $a1,$s0,$zero -/* f0a3014: 8e4d000c */ lw $t5,0xc($s2) -/* f0a3018: 26310014 */ addiu $s1,$s1,0x14 -/* f0a301c: 26730014 */ addiu $s3,$s3,0x14 -/* f0a3020: ac4d0000 */ sw $t5,0x0($v0) -/* f0a3024: 8e4e0000 */ lw $t6,0x0($s2) -/* f0a3028: ac4e0004 */ sw $t6,0x4($v0) -/* f0a302c: 86580010 */ lh $t8,0x10($s2) -/* f0a3030: 8e4f000c */ lw $t7,0xc($s2) -/* f0a3034: 03170019 */ multu $t8,$s7 -/* f0a3038: 0000c812 */ mflo $t9 -/* f0a303c: 01f94021 */ addu $t0,$t7,$t9 -/* f0a3040: 25090007 */ addiu $t1,$t0,0x7 -/* f0a3044: 352a0007 */ ori $t2,$t1,0x7 -/* f0a3048: 394b0007 */ xori $t3,$t2,0x7 -/* f0a304c: ac4b0008 */ sw $t3,0x8($v0) -/* f0a3050: ae3effec */ sw $s8,-0x14($s1) -/* f0a3054: ae22fff0 */ sw $v0,-0x10($s1) -/* f0a3058: 8c4c0000 */ lw $t4,0x0($v0) -/* f0a305c: ae2cfff4 */ sw $t4,-0xc($s1) -/* f0a3060: 8c4d0004 */ lw $t5,0x4($v0) -/* f0a3064: ae2dfff8 */ sw $t5,-0x8($s1) -/* f0a3068: 8c4e0008 */ lw $t6,0x8($v0) -/* f0a306c: ae2efffc */ sw $t6,-0x4($s1) -.L0f0a3070: -/* f0a3070: 8e020014 */ lw $v0,0x14($s0) -/* f0a3074: 10400003 */ beqz $v0,.L0f0a3084 -/* f0a3078: 00000000 */ nop -/* f0a307c: 10000010 */ b .L0f0a30c0 -/* f0a3080: 00408025 */ or $s0,$v0,$zero -.L0f0a3084: -/* f0a3084: 1200000e */ beqz $s0,.L0f0a30c0 -/* f0a3088: 00000000 */ nop -/* f0a308c: 8ec30008 */ lw $v1,0x8($s6) -.L0f0a3090: -/* f0a3090: 56030004 */ bnel $s0,$v1,.L0f0a30a4 -/* f0a3094: 8e02000c */ lw $v0,0xc($s0) -/* f0a3098: 10000009 */ b .L0f0a30c0 -/* f0a309c: 00008025 */ or $s0,$zero,$zero -/* f0a30a0: 8e02000c */ lw $v0,0xc($s0) -.L0f0a30a4: -/* f0a30a4: 50400004 */ beqzl $v0,.L0f0a30b8 -/* f0a30a8: 8e100008 */ lw $s0,0x8($s0) -/* f0a30ac: 10000004 */ b .L0f0a30c0 -/* f0a30b0: 00408025 */ or $s0,$v0,$zero -/* f0a30b4: 8e100008 */ lw $s0,0x8($s0) -.L0f0a30b8: -/* f0a30b8: 1600fff5 */ bnez $s0,.L0f0a3090 -/* f0a30bc: 00000000 */ nop -.L0f0a30c0: -/* f0a30c0: 5600ff89 */ bnezl $s0,.L0f0a2ee8 -/* f0a30c4: 96020000 */ lhu $v0,0x0($s0) -.L0f0a30c8: -/* f0a30c8: 24180006 */ addiu $t8,$zero,0x6 -/* f0a30cc: ae380000 */ sw $t8,0x0($s1) -/* f0a30d0: 8fbf003c */ lw $ra,0x3c($sp) -/* f0a30d4: 26620004 */ addiu $v0,$s3,0x4 -/* f0a30d8: 8fb30024 */ lw $s3,0x24($sp) -/* f0a30dc: 8fbe0038 */ lw $s8,0x38($sp) -/* f0a30e0: 8fb70034 */ lw $s7,0x34($sp) -/* f0a30e4: 8fb60030 */ lw $s6,0x30($sp) -/* f0a30e8: 8fb5002c */ lw $s5,0x2c($sp) -/* f0a30ec: 8fb40028 */ lw $s4,0x28($sp) -/* f0a30f0: 8fb20020 */ lw $s2,0x20($sp) -/* f0a30f4: 8fb1001c */ lw $s1,0x1c($sp) -/* f0a30f8: 8fb00018 */ lw $s0,0x18($sp) -/* f0a30fc: 03e00008 */ jr $ra -/* f0a3100: 27bd0040 */ addiu $sp,$sp,0x40 -); +/** + * Generate some sort of command list to be executed by the function above. + * + * This appears to be a performance optimisation, so the tick code can quickly + * iterate the command list to update part visibility rather than iterate the + * full model tree. + */ +s32 bgunCreateModelCmdList(struct model *model, struct modelnode *nodearg, s32 *ptr) +{ + s32 len = 0; + struct modelnode *node = nodearg; + union modelrodata *rodata; + union modelrwdata *rwdata; + + while (node) { + u32 type = node->type; + + switch ((u8)type) { + case MODELNODETYPE_DISTANCE: + rodata = node->rodata; + rwdata = modelGetNodeRwData(model, node); + rwdata->distance.visible = false; + node->child = rodata->distance.target; + ptr[0] = 0; + ptr[1] = (s32)rwdata; + ptr[2] = (s32)node; + ptr[3] = (s32)rodata->distance.target; + ptr += 4; + len += 16; + break; + case MODELNODETYPE_TOGGLE: + rodata = node->rodata; + rwdata = modelGetNodeRwData(model, node); + rwdata->toggle.visible = true; + node->child = rodata->toggle.target; + ptr[0] = 1; + ptr[1] = (s32)rwdata; + ptr[2] = (s32)node; + ptr[3] = (s32)rodata->toggle.target; + ptr += 4; + len += 16; + break; + case MODELNODETYPE_HEADSPOT: + rwdata = modelGetNodeRwData(model, node); + rwdata->headspot.modelfiledata = NULL; + rwdata->headspot.rwdatas = NULL; + ptr[0] = 2; + ptr[1] = (s32)rwdata; + ptr += 2; + len += 8; + break; + case MODELNODETYPE_0B: + rwdata = modelGetNodeRwData(model, node); + rwdata->type0b.unk00 = 0; + ptr[0] = 3; + ptr[1] = (s32)rwdata; + ptr += 2; + len += 8; + break; + case MODELNODETYPE_GUNFIRE: + rwdata = modelGetNodeRwData(model, node); + rwdata->gunfire.visible = false; + ptr[0] = 4; + ptr[1] = (s32)rwdata; + ptr += 2; + len += 8; + break; + case MODELNODETYPE_DL: + rodata = node->rodata; + rwdata = modelGetNodeRwData(model, node); + rwdata->dl.vertices = rodata->dl.vertices; + rwdata->dl.gdl = rodata->dl.primary; + rwdata->dl.colours = (void *)ALIGN8((u32)&rodata->dl.vertices[rodata->dl.numvertices]); + ptr[0] = 5; + ptr[1] = (s32)rwdata; + ptr[2] = (s32)rwdata->dl.vertices; + ptr[3] = (s32)rwdata->dl.gdl; + ptr[4] = (s32)rwdata->dl.colours; + ptr += 5; + len += 20; + break; + } + + if (node->child) { + node = node->child; + } else { + while (node) { + if (node == nodearg->parent) { + node = NULL; + break; + } + + if (node->next) { + node = node->next; + break; + } + + node = node->parent; + } + } + } + + *ptr = 6; + len += 4; + + return len; +} void bgunStartDetonateAnimation(s32 playernum) { @@ -17907,10 +17814,10 @@ void bgun0f0a5550(s32 handnum) } } - bgun0f0a2da8(hand->unk0dcc); + bgunExecuteModelCmdList(hand->unk0dcc); if (player->gunctrl.handmodeldef != NULL) { - bgun0f0a2da8(hand->unk0dd0); + bgunExecuteModelCmdList(hand->unk0dd0); } bgun0f098030(hand, modeldef); diff --git a/src/include/game/bondgun.h b/src/include/game/bondgun.h index 6beecb3e4..a2ff7005e 100644 --- a/src/include/game/bondgun.h +++ b/src/include/game/bondgun.h @@ -118,8 +118,8 @@ bool bgun0f0a27c8(void); void bgunHandlePlayerDead(void); bool bgunIsMissionCritical(s32 weaponnum); void bgunLoseGun(struct prop *attacker); -void bgun0f0a2da8(s32 *arg0); -s32 bgun0f0a2e94(struct model *model, struct modelnode *node, s32 arg2); +void bgunExecuteModelCmdList(s32 *arg0); +s32 bgunCreateModelCmdList(struct model *model, struct modelnode *node, s32 *ptr); void bgunStartDetonateAnimation(s32 playernum); void bgunUpdateGangsta(struct hand *hand, s32 handnum, struct coord *arg2, struct weaponfunc *funcdef, Mtxf *arg4, Mtxf *arg5); void bgunUpdateSmoke(struct hand *hand, s32 handnum, s32 weaponnum, struct weaponfunc *funcdef);