diff --git a/src/game/bg.c b/src/game/bg.c index afe52f60c..38e747f77 100644 --- a/src/game/bg.c +++ b/src/game/bg.c @@ -4793,7 +4793,7 @@ glabel var7f1b75d0 /* f15c2c0: 8eaf0000 */ lw $t7,0x0($s5) /* f15c2c4: e5f00028 */ swc1 $f16,0x28($t7) /* f15c2c8: 8eb90000 */ lw $t9,0x0($s5) -/* f15c2cc: 0fc4f0fd */ jal func0f13c3f4 +/* f15c2cc: 0fc4f0fd */ jal dyntexReset /* f15c2d0: e730002c */ swc1 $f16,0x2c($t9) /* f15c2d4: 03a08025 */ or $s0,$sp,$zero /* f15c2d8: 261000b3 */ addiu $s0,$s0,0xb3 @@ -5857,7 +5857,7 @@ glabel var7f1b75d0 /* f15c084: 8eaf0000 */ lw $t7,0x0($s5) /* f15c088: e5f00028 */ swc1 $f16,0x28($t7) /* f15c08c: 8eb90000 */ lw $t9,0x0($s5) -/* f15c090: 0fc4f071 */ jal func0f13c3f4 +/* f15c090: 0fc4f071 */ jal dyntexReset /* f15c094: e730002c */ swc1 $f16,0x2c($t9) /* f15c098: 03a08025 */ or $s0,$sp,$zero /* f15c09c: 261000b3 */ addiu $s0,$s0,0xb3 @@ -6919,7 +6919,7 @@ glabel var7f1b75d0 /* f156a18: 8eaf0000 */ lw $t7,0x0($s5) /* f156a1c: e5f00028 */ swc1 $f16,0x28($t7) /* f156a20: 8eb90000 */ lw $t9,0x0($s5) -/* f156a24: 0fc4dbbd */ jal func0f13c3f4 +/* f156a24: 0fc4dbbd */ jal dyntexReset /* f156a28: e730002c */ swc1 $f16,0x2c($t9) /* f156a2c: 03a08025 */ or $s0,$sp,$zero /* f156a30: 261000b3 */ addiu $s0,$s0,0xb3 @@ -7595,7 +7595,7 @@ glabel var7f1b75d0 // g_Rooms[0].bbmax[2] = 0; // // // 2cc -// func0f13c3f4(); +// dyntexReset(); // // header = (u8 *)ALIGN16((u32)headerbuffer); // bgLoadFile(header, g_BgSection3, 0x40); @@ -8422,7 +8422,7 @@ glabel roomLoad /* f15dd00: 8fa402f4 */ lw $a0,0x2f4($sp) /* f15dd04: 104001d3 */ beqz $v0,.L0f15e454 /* f15dd08: 0040a025 */ or $s4,$v0,$zero -/* f15dd0c: 0fc4f0dc */ jal func0f13c370 +/* f15dd0c: 0fc4f0dc */ jal dyntexSetCurrentRoom /* f15dd10: 87a402fa */ lh $a0,0x2fa($sp) /* f15dd14: 8fb002f8 */ lw $s0,0x2f8($sp) /* f15dd18: 3c11800a */ lui $s1,%hi(g_BgRooms) @@ -8451,7 +8451,7 @@ glabel roomLoad /* f15dd74: 03209025 */ or $s2,$t9,$zero /* f15dd78: 10200005 */ beqz $at,.L0f15dd90 /* f15dd7c: 00ac2823 */ subu $a1,$a1,$t4 -/* f15dd80: 0fc4f0dc */ jal func0f13c370 +/* f15dd80: 0fc4f0dc */ jal dyntexSetCurrentRoom /* f15dd84: 2404ffff */ addiu $a0,$zero,-1 /* f15dd88: 100001b3 */ b .L0f15e458 /* f15dd8c: 8fbf0034 */ lw $ra,0x34($sp) @@ -8469,7 +8469,7 @@ glabel roomLoad /* f15ddb8: 01cf082a */ slt $at,$t6,$t7 /* f15ddbc: 50200006 */ beqzl $at,.L0f15ddd8 /* f15ddc0: 8e380000 */ lw $t8,0x0($s1) -/* f15ddc4: 0fc4f0dc */ jal func0f13c370 +/* f15ddc4: 0fc4f0dc */ jal dyntexSetCurrentRoom /* f15ddc8: 2404ffff */ addiu $a0,$zero,-1 /* f15ddcc: 100001a2 */ b .L0f15e458 /* f15ddd0: 8fbf0034 */ lw $ra,0x34($sp) @@ -8923,7 +8923,7 @@ glabel roomLoad /* f15e440: 8fae0054 */ lw $t6,0x54($sp) /* f15e444: 8dad4928 */ lw $t5,%lo(g_Rooms)($t5) /* f15e448: 01aec021 */ addu $t8,$t5,$t6 -/* f15e44c: 0fc4f0dc */ jal func0f13c370 +/* f15e44c: 0fc4f0dc */ jal dyntexSetCurrentRoom /* f15e450: af000058 */ sw $zero,0x58($t8) .L0f15e454: /* f15e454: 8fbf0034 */ lw $ra,0x34($sp) @@ -8991,7 +8991,7 @@ glabel roomLoad /* f1584ac: 8fa402f4 */ lw $a0,0x2f4($sp) /* f1584b0: 104001ea */ beqz $v0,.NB0f158c5c /* f1584b4: 00409825 */ or $s3,$v0,$zero -/* f1584b8: 0fc4db9c */ jal func0f13c370 +/* f1584b8: 0fc4db9c */ jal dyntexSetCurrentRoom /* f1584bc: 87a402fa */ lh $a0,0x2fa($sp) /* f1584c0: 8fb002f8 */ lw $s0,0x2f8($sp) /* f1584c4: 3c11800b */ lui $s1,0x800b @@ -9020,7 +9020,7 @@ glabel roomLoad /* f158520: 03209025 */ or $s2,$t9,$zero /* f158524: 10200005 */ beqz $at,.NB0f15853c /* f158528: 00ac2823 */ subu $a1,$a1,$t4 -/* f15852c: 0fc4db9c */ jal func0f13c370 +/* f15852c: 0fc4db9c */ jal dyntexSetCurrentRoom /* f158530: 2404ffff */ addiu $a0,$zero,-1 /* f158534: 100001ca */ beqz $zero,.NB0f158c60 /* f158538: 8fbf002c */ lw $ra,0x2c($sp) @@ -9038,7 +9038,7 @@ glabel roomLoad /* f158564: 01cf082a */ slt $at,$t6,$t7 /* f158568: 50200006 */ beqzl $at,.NB0f158584 /* f15856c: 8e380000 */ lw $t8,0x0($s1) -/* f158570: 0fc4db9c */ jal func0f13c370 +/* f158570: 0fc4db9c */ jal dyntexSetCurrentRoom /* f158574: 2404ffff */ addiu $a0,$zero,-1 /* f158578: 100001b9 */ beqz $zero,.NB0f158c60 /* f15857c: 8fbf002c */ lw $ra,0x2c($sp) @@ -9512,7 +9512,7 @@ glabel roomLoad /* f158c38: 8fab0050 */ lw $t3,0x50($sp) /* f158c3c: 8f3990a8 */ lw $t9,-0x6f58($t9) /* f158c40: 032b6021 */ addu $t4,$t9,$t3 -/* f158c44: 0fc4db9c */ jal func0f13c370 +/* f158c44: 0fc4db9c */ jal dyntexSetCurrentRoom /* f158c48: ad800058 */ sw $zero,0x58($t4) /* f158c4c: 3c047f1b */ lui $a0,0x7f1b /* f158c50: 24841a60 */ addiu $a0,$a0,0x1a60 @@ -9582,14 +9582,14 @@ const char var7f1b1a60nb[] = "bg.c"; // allocation = memaAlloc(size); // // if (allocation != NULL) { -// func0f13c370(roomnum); +// dyntexSetCurrentRoom(roomnum); // // readlen = ((g_BgRooms[roomnum + 1].unk00 - g_BgRooms[roomnum].unk00) + 0xf) & ~0xf; // fileoffset = (g_BgPrimaryData + g_BgRooms[roomnum].unk00 - g_BgPrimaryData) + 0xf1000000; // fileoffset -= var8007fc54; // // if (size < readlen) { -// func0f13c370(-1); +// dyntexSetCurrentRoom(-1); // return; // } // @@ -9597,7 +9597,7 @@ const char var7f1b1a60nb[] = "bg.c"; // bgLoadFile(memaddr, fileoffset, readlen); // // if (rzipIs1173(memaddr) && size < readlen + 0x20) { -// func0f13c370(-1); +// dyntexSetCurrentRoom(-1); // return; // } // @@ -9750,7 +9750,7 @@ const char var7f1b1a60nb[] = "bg.c"; // g_Rooms[roomnum].flags |= ROOMFLAG_0200; // g_Rooms[roomnum].colours = NULL; // -// func0f13c370(-1); +// dyntexSetCurrentRoom(-1); // } // //#if VERSION < VERSION_NTSC_1_0 @@ -9922,8 +9922,8 @@ Gfx *room0f15e85c(Gfx *gdl, s32 roomnum, struct roomgfxdata18 *arg2, bool arg3) switch (arg2->type) { case 0: - if (g_Rooms[roomnum].flags & ROOMFLAG_0002) { - func0f13bc48(roomnum, arg2->vertices); + if (g_Rooms[roomnum].flags & ROOMFLAG_HASDYNTEX) { + dyntexTickRoom(roomnum, arg2->vertices); } gSPSegment(gdl++, 0xe, OS_PHYSICAL_TO_K0(arg2->vertices)); diff --git a/src/game/game_13b670.c b/src/game/game_13b670.c index b52931ea6..6d659d386 100644 --- a/src/game/game_13b670.c +++ b/src/game/game_13b670.c @@ -9,25 +9,72 @@ #include "data.h" #include "types.h" +/** + * dyntex - dynamic textures + * + * This file handles textures which animate automatically, such as water. + * + * The dyntex system maintains three conceptually nested arrays: rooms, types + * and vertices. + * + * Rooms are the first tier. Rooms will only exist in the array if they contain + * animated textures. Rooms contain types. + * + * Types are a type of animation. Linear is the most common, but there's also + * ocean waves, and some specific types such as Attack Ship triangular arrows. + * Types contain vertices. + * + * Vertices contain an offset to the graphics vertex, as well as a copy of its + * S and T values. + * + * The caller should call dyntexSetCurrentRoom and dyntexSetCurrentType, then + * add vertices with dyntexAddVertex. Lastly, dyntexTickRoom should be called + * on each tick for each nearby room. dyntexTickRoom can be called multiple + * times on the same frame (such as if there's two players), as dyntex will + * ensure it's only updated once per frame. + * + * Data is added to dyntex during gameplay as rooms are loaded. When a room is + * unloaded the data remains in the dyntex arrays. When a room is loaded again + * dyntex will not add it a second time. + */ + +struct dyntexroom { + u16 roomnum; + u16 typelistoffset; + u16 numtypes; + s32 updatedframe; +}; + +struct dyntextype { + u16 type : 7; + u16 initialised : 1; + u8 numvertices; + u16 vertexlistoffset; +}; + +struct dyntexvtx { + u16 offset; + s16 s; + s16 t; +}; + const char var7f1b5960[] = "modula"; const char var7f1b5968[] = "ripsize"; -s32 var800a4180; -s32 var800a4184; -s32 var800a4188; -struct var800a418c *var800a418c; -struct var800a4190 *var800a4190; -struct var800a4194 *var800a4194; -s32 var800a4198; -s32 var800a419c; +s32 g_DyntexVerticesMax; +s32 g_DyntexTypesMax; +s32 g_DyntexRoomsMax; +struct dyntexvtx *g_DyntexVertices; +struct dyntextype *g_DyntexTypes; +struct dyntexroom *g_DyntexRooms; -s32 var8007f6e0 = -1; -s32 var8007f6e4 = -1; -s32 var8007f6e8 = 0x00000000; -s32 var8007f6ec = 0x00000000; -s32 var8007f6f0 = 0x00000000; -s32 var8007f6f4 = 0x00000000; -s32 var8007f6f8 = 0x00000000; +s32 g_DyntexCurRoom = -1; +s32 g_DyntexCurType = -1; +bool g_DyntexRoomPopulated = false; +bool g_DyntexTypePopulated = false; +s32 g_DyntexRoomsCount = 0; +s32 g_DyntexTypesCount = 0; +s32 g_DyntexVerticesCount = 0; u32 var8007f6fc = 0x00000041; u32 var8007f700 = 0x00000016; u32 var8007f704 = 0x0000001d; @@ -42,12 +89,15 @@ u32 var8007f724 = 0x00000034; u32 var8007f728 = 0x000002f7; u32 var8007f72c = 0x00000012; u32 var8007f730 = 0x00000012; -u32 var8007f734 = 0x00000000; -u32 var8007f738 = 0x00000000; -u32 var8007f73c = 0x00000000; + +void dyntexUpdateLinear(struct gfxvtx *vertices, struct dyntextype *type); +void dyntexUpdateReset(struct gfxvtx *vertices, struct dyntextype *type); +void dyntexUpdateMonitor(struct gfxvtx *vertices, struct dyntextype *type); +void dyntexUpdateOcean(struct gfxvtx *vertices, struct dyntextype *type); +void dyntexUpdateArrows(struct gfxvtx *vertices, struct dyntextype *type); GLOBAL_ASM( -glabel func0f13b670 +glabel dyntexUpdateLinear /* f13b670: 3c018006 */ lui $at,%hi(var80061634) /* f13b674: c4241634 */ lwc1 $f4,%lo(var80061634)($at) /* f13b678: 3c014120 */ lui $at,0x4120 @@ -58,9 +108,9 @@ glabel func0f13b670 /* f13b68c: 27bdfff8 */ addiu $sp,$sp,-8 /* f13b690: afb00004 */ sw $s0,0x4($sp) /* f13b694: 90a90001 */ lbu $t1,0x1($a1) -/* f13b698: 3c08800a */ lui $t0,%hi(var800a418c) +/* f13b698: 3c08800a */ lui $t0,%hi(g_DyntexVertices) /* f13b69c: 00808025 */ or $s0,$a0,$zero -/* f13b6a0: 2508418c */ addiu $t0,$t0,%lo(var800a418c) +/* f13b6a0: 2508418c */ addiu $t0,$t0,%lo(g_DyntexVertices) /* f13b6a4: 460a4402 */ mul.s $f16,$f8,$f10 /* f13b6a8: 00001825 */ or $v1,$zero,$zero /* f13b6ac: 00003025 */ or $a2,$zero,$zero @@ -110,40 +160,19 @@ glabel func0f13b670 /* f13b750: 27bd0008 */ addiu $sp,$sp,0x8 ); -GLOBAL_ASM( -glabel func0f13b754 -/* f13b754: 90ae0001 */ lbu $t6,0x1($a1) -/* f13b758: 00803025 */ or $a2,$a0,$zero -/* f13b75c: 00002025 */ or $a0,$zero,$zero -/* f13b760: 19c00014 */ blez $t6,.L0f13b7b4 -/* f13b764: 00001025 */ or $v0,$zero,$zero -/* f13b768: 3c07800a */ lui $a3,%hi(var800a418c) -/* f13b76c: 24e7418c */ addiu $a3,$a3,%lo(var800a418c) -/* f13b770: 94b80002 */ lhu $t8,0x2($a1) -.L0f13b774: -/* f13b774: 8cef0000 */ lw $t7,0x0($a3) -/* f13b778: 24420001 */ addiu $v0,$v0,0x1 -/* f13b77c: 0018c880 */ sll $t9,$t8,0x2 -/* f13b780: 0338c823 */ subu $t9,$t9,$t8 -/* f13b784: 0019c840 */ sll $t9,$t9,0x1 -/* f13b788: 01f94021 */ addu $t0,$t7,$t9 -/* f13b78c: 01044821 */ addu $t1,$t0,$a0 -/* f13b790: 952a0000 */ lhu $t2,0x0($t1) -/* f13b794: 24840006 */ addiu $a0,$a0,0x6 -/* f13b798: 01461821 */ addu $v1,$t2,$a2 -/* f13b79c: a4600008 */ sh $zero,0x8($v1) -/* f13b7a0: a460000a */ sh $zero,0xa($v1) -/* f13b7a4: 90ab0001 */ lbu $t3,0x1($a1) -/* f13b7a8: 004b082a */ slt $at,$v0,$t3 -/* f13b7ac: 5420fff1 */ bnezl $at,.L0f13b774 -/* f13b7b0: 94b80002 */ lhu $t8,0x2($a1) -.L0f13b7b4: -/* f13b7b4: 03e00008 */ jr $ra -/* f13b7b8: 00000000 */ nop -); +void dyntexUpdateReset(struct gfxvtx *vertices, struct dyntextype *type) +{ + s32 i; + + for (i = 0; i < type->numvertices; i++) { + struct gfxvtx *vertex = (struct gfxvtx *)((s32)vertices + g_DyntexVertices[type->vertexlistoffset + i].offset); + vertex->unk08 = 0; + vertex->unk0a = 0; + } +} GLOBAL_ASM( -glabel func0f13b7bc +glabel dyntexUpdateMonitor /* f13b7bc: 3c018006 */ lui $at,%hi(var80061634) /* f13b7c0: c4241634 */ lwc1 $f4,%lo(var80061634)($at) /* f13b7c4: 3c014080 */ lui $at,0x4080 @@ -154,9 +183,9 @@ glabel func0f13b7bc /* f13b7d8: 27bdfff8 */ addiu $sp,$sp,-8 /* f13b7dc: afb00004 */ sw $s0,0x4($sp) /* f13b7e0: 90a90001 */ lbu $t1,0x1($a1) -/* f13b7e4: 3c08800a */ lui $t0,%hi(var800a418c) +/* f13b7e4: 3c08800a */ lui $t0,%hi(g_DyntexVertices) /* f13b7e8: 00808025 */ or $s0,$a0,$zero -/* f13b7ec: 2508418c */ addiu $t0,$t0,%lo(var800a418c) +/* f13b7ec: 2508418c */ addiu $t0,$t0,%lo(g_DyntexVertices) /* f13b7f0: 460a4402 */ mul.s $f16,$f8,$f10 /* f13b7f4: 00001825 */ or $v1,$zero,$zero /* f13b7f8: 00003025 */ or $a2,$zero,$zero @@ -207,7 +236,7 @@ glabel func0f13b7bc ); GLOBAL_ASM( -glabel func0f13b8a0 +glabel dyntexUpdateOcean .late_rodata glabel var7f1b5970 .word 0x40c907a9 @@ -245,8 +274,8 @@ glabel var7f1b5970 /* f13b918: 00008025 */ or $s0,$zero,$zero /* f13b91c: 19c00083 */ blez $t6,.L0f13bb2c /* f13b920: 3c017f1b */ lui $at,%hi(var7f1b5970) -/* f13b924: 3c11800a */ lui $s1,%hi(var800a418c) -/* f13b928: 2631418c */ addiu $s1,$s1,%lo(var800a418c) +/* f13b924: 3c11800a */ lui $s1,%hi(g_DyntexVertices) +/* f13b928: 2631418c */ addiu $s1,$s1,%lo(g_DyntexVertices) /* f13b92c: c4365970 */ lwc1 $f22,%lo(var7f1b5970)($at) /* f13b930: 96580002 */ lhu $t8,0x2($s2) .L0f13b934: @@ -400,7 +429,7 @@ glabel var7f1b5970 ); GLOBAL_ASM( -glabel func0f13bb5c +glabel dyntexUpdateArrows /* f13bb5c: 3c013f80 */ lui $at,0x3f80 /* f13bb60: 44812000 */ mtc1 $at,$f4 /* f13bb64: 3c018006 */ lui $at,%hi(var80061634) @@ -414,9 +443,9 @@ glabel func0f13bb5c /* f13bb84: 460a4402 */ mul.s $f16,$f8,$f10 /* f13bb88: afb00004 */ sw $s0,0x4($sp) /* f13bb8c: 90b90001 */ lbu $t9,0x1($a1) -/* f13bb90: 3c08800a */ lui $t0,%hi(var800a418c) +/* f13bb90: 3c08800a */ lui $t0,%hi(g_DyntexVertices) /* f13bb94: 00808025 */ or $s0,$a0,$zero -/* f13bb98: 2508418c */ addiu $t0,$t0,%lo(var800a418c) +/* f13bb98: 2508418c */ addiu $t0,$t0,%lo(g_DyntexVertices) /* f13bb9c: 00001825 */ or $v1,$zero,$zero /* f13bba0: 46128102 */ mul.s $f4,$f16,$f18 /* f13bba4: 00003025 */ or $a2,$zero,$zero @@ -465,13 +494,13 @@ glabel func0f13bb5c /* f13bc44: 27bd0008 */ addiu $sp,$sp,0x8 ); -void func0f13bc48(s32 roomnum, struct gfxvtx *vertices) +void dyntexTickRoom(s32 roomnum, struct gfxvtx *vertices) { s32 index = -1; s32 i; - for (i = 0; i < var8007f6f0; i++) { - if (var800a4194[i].roomnum == roomnum) { + for (i = 0; i < g_DyntexRoomsCount; i++) { + if (g_DyntexRooms[i].roomnum == roomnum) { index = i; break; } @@ -481,29 +510,29 @@ void func0f13bc48(s32 roomnum, struct gfxvtx *vertices) return; } - if (g_Vars.lvframenum == var800a4194[index].framenum) { + if (g_Vars.lvframenum == g_DyntexRooms[index].updatedframe) { return; } - for (i = 0; i < var800a4194[index].unk04; i++) { - struct var800a4190 *thing = &var800a4190[var800a4194[index].unk02 + i]; + for (i = 0; i < g_DyntexRooms[index].numtypes; i++) { + struct dyntextype *type = &g_DyntexTypes[g_DyntexRooms[index].typelistoffset + i]; s32 mins = 32767; s32 maxs = -32766; s32 mint = 32767; s32 maxt = -32766; - if (!thing->unk00_07) { + if (!type->initialised) { s32 adds = 0; s32 addt = 0; if (1); // @bug: Using i for both outer and inner loops - for (i = 0; i < thing->unk01; i++) { - struct gfxvtx *vertex = (struct gfxvtx *)((s32)vertices + var800a418c[thing->unk02 + i].offset); + for (i = 0; i < type->numvertices; i++) { + struct gfxvtx *vertex = (struct gfxvtx *)((s32)vertices + g_DyntexVertices[type->vertexlistoffset + i].offset); - var800a418c[thing->unk02 + i].s = vertex->unk08; - var800a418c[thing->unk02 + i].t = vertex->unk0a; + g_DyntexVertices[type->vertexlistoffset + i].s = vertex->unk08; + g_DyntexVertices[type->vertexlistoffset + i].t = vertex->unk0a; if (vertex->unk08 < mins) { mins = vertex->unk08; @@ -522,7 +551,7 @@ void func0f13bc48(s32 roomnum, struct gfxvtx *vertices) } } - thing->unk00_07 = true; + type->initialised = true; if (mins < -0x5d00) { adds = 0x2000; @@ -541,169 +570,194 @@ void func0f13bc48(s32 roomnum, struct gfxvtx *vertices) } if (adds || addt) { - for (i = 0; i < thing->unk01; i++) { - var800a418c[thing->unk02 + i].s += adds; - var800a418c[thing->unk02 + i].t += addt; + for (i = 0; i < type->numvertices; i++) { + g_DyntexVertices[type->vertexlistoffset + i].s += adds; + g_DyntexVertices[type->vertexlistoffset + i].t += addt; } } } - switch (var800a4190[var800a4194[index].unk02 + i].unk00_00) { - case 1: - func0f13b670(vertices, thing); + switch (g_DyntexTypes[g_DyntexRooms[index].typelistoffset + i].type) { + case DYNTEXTYPE_RIVER: + dyntexUpdateLinear(vertices, type); break; - case 4: - func0f13b7bc(vertices, thing); + case DYNTEXTYPE_MONITOR: + dyntexUpdateMonitor(vertices, type); break; - case 5: - func0f13b8a0(vertices, thing); + case DYNTEXTYPE_OCEAN: + dyntexUpdateOcean(vertices, type); break; - case 2: - func0f13bb5c(vertices, thing); + case DYNTEXTYPE_ARROWS: + dyntexUpdateArrows(vertices, type); break; - case 3: + case DYNTEXTYPE_TELEPORTAL: + // Deep Sea - teleports enabled and not SA disabled if (chrHasStageFlag(0, 0x00000100) && !chrHasStageFlag(0, 0x00010000)) { - func0f13b670(vertices, thing); + dyntexUpdateLinear(vertices, type); } break; - case 7: + case DYNTEXTYPE_POWERRING: if (chrHasStageFlag(0, 0x00010000)) { - func0f13b754(vertices, thing); + // Attack Ship engines are destroyed + dyntexUpdateReset(vertices, type); } else { - func0f13b670(vertices, thing); + // Attack Ship engines are healthy + dyntexUpdateLinear(vertices, type); } break; - case 6: + case DYNTEXTYPE_POWERJUICE: if (!chrHasStageFlag(0, 0x00010000)) { - func0f13b670(vertices, thing); + // Attack Ship engines are healthy + dyntexUpdateLinear(vertices, type); } break; } } - var800a4194[index].framenum = g_Vars.lvframenum; + g_DyntexRooms[index].updatedframe = g_Vars.lvframenum; } -void func0f13c07c(struct gfxvtx *vertex) +void dyntexAddVertex(struct gfxvtx *vertex) { - if (var8007f6e0 >= 0 && var8007f6f8 != var800a4180) { - if (var8007f6e8 == 0) { - if (var8007f6f4 >= var800a4184 || var8007f6f0 >= var800a4188) { - return; - } - - var800a4194[var8007f6f0].roomnum = var8007f6e0; - var800a4194[var8007f6f0].unk02 = var8007f6f4; - var800a4194[var8007f6f0].unk04 = 0; - var800a4194[var8007f6f0].framenum = 0; - - g_Rooms[var8007f6e0].flags |= ROOMFLAG_0002; - - var8007f6f0++; - var8007f6e8 = 1; - } - - if (var8007f6ec == 0) { - if (var8007f6f4 >= var800a4184) { - return; - } - - var800a4190[var8007f6f4].unk00_00 = var8007f6e4; - var800a4190[var8007f6f4].unk00_07 = 0; - var800a4190[var8007f6f4].unk01 = 0; - var800a4190[var8007f6f4].unk02 = var8007f6f8; - var8007f6f4++; - - var800a4194[var8007f6f0 - 1].unk04++; - var8007f6ec = 1; - } - - var800a418c[var8007f6f8].offset = (u16)vertex; - var8007f6f8++; - - var800a4190[var8007f6f4 - 1].unk01++; + if (g_DyntexCurRoom < 0) { + return; } + + if (g_DyntexVerticesCount == g_DyntexVerticesMax) { + return; + } + + if (!g_DyntexRoomPopulated) { + if (g_DyntexTypesCount >= g_DyntexTypesMax || g_DyntexRoomsCount >= g_DyntexRoomsMax) { + return; + } + + g_DyntexRooms[g_DyntexRoomsCount].roomnum = g_DyntexCurRoom; + g_DyntexRooms[g_DyntexRoomsCount].typelistoffset = g_DyntexTypesCount; + g_DyntexRooms[g_DyntexRoomsCount].numtypes = 0; + g_DyntexRooms[g_DyntexRoomsCount].updatedframe = 0; + + g_Rooms[g_DyntexCurRoom].flags |= ROOMFLAG_HASDYNTEX; + + g_DyntexRoomsCount++; + g_DyntexRoomPopulated = true; + } + + if (!g_DyntexTypePopulated) { + if (g_DyntexTypesCount >= g_DyntexTypesMax) { + return; + } + + g_DyntexTypes[g_DyntexTypesCount].type = g_DyntexCurType; + g_DyntexTypes[g_DyntexTypesCount].initialised = false; + g_DyntexTypes[g_DyntexTypesCount].numvertices = 0; + g_DyntexTypes[g_DyntexTypesCount].vertexlistoffset = g_DyntexVerticesCount; + g_DyntexTypesCount++; + + g_DyntexRooms[g_DyntexRoomsCount - 1].numtypes++; + g_DyntexTypePopulated = true; + } + + g_DyntexVertices[g_DyntexVerticesCount].offset = (u16)vertex; + g_DyntexVerticesCount++; + + g_DyntexTypes[g_DyntexTypesCount - 1].numvertices++; } -/** - * Related to moving textures. - * - * With this function nopped, Villa water does not animate. - */ -void func0f13c2e8(s16 arg0) +void dyntexSetCurrentType(s16 type) { - if (g_StageIndex != STAGEINDEX_AIRBASE - && (g_StageIndex != STAGEINDEX_INVESTIGATION || arg0 != 1) - && (g_StageIndex != STAGEINDEX_VILLA || arg0 != 1)) { - if (g_StageIndex != STAGEINDEX_ATTACKSHIP && (arg0 == 6 || arg0 == 7)) { - arg0 = 1; - } - - if (var8007f6e4 != arg0) { - var8007f6ec = 0; - } - - var8007f6e4 = arg0; + // Air Base - don't animate anything (exterior water) + if (g_StageIndex == STAGEINDEX_AIRBASE) { + return; } + + // Investigation - don't animate the puddle of water behind the glass + if (g_StageIndex == STAGEINDEX_INVESTIGATION && type == DYNTEXTYPE_RIVER) { + return; + } + + // Villa - don't animate shallow water + if (g_StageIndex == STAGEINDEX_VILLA && type == DYNTEXTYPE_RIVER) { + return; + } + + // Power juice and power rings exist on Deep Sea and Attack Ship. + // + // Deep Sea - in the SA megaweapon + // Attack Ship - in the engine's power node + // + // These both use a linear animation, but Attack Ship's are conditional on + // the ship's engines running. To avoid doing a stage check on every tick, + // Deep Sea's are retyped to the river type which uses an unconditional + // linear animation. Attack Ship's remains as is. + if (g_StageIndex != STAGEINDEX_ATTACKSHIP && (type == DYNTEXTYPE_POWERJUICE || type == DYNTEXTYPE_POWERRING)) { + type = DYNTEXTYPE_RIVER; + } + + if (type != g_DyntexCurType) { + g_DyntexTypePopulated = false; + } + + g_DyntexCurType = type; } -void func0f13c370(s16 roomnum) +void dyntexSetCurrentRoom(s16 roomnum) { s32 i; if (roomnum >= 0) { - for (i = 0; i < var8007f6f0; i++) { - if (var800a4194[i].roomnum == roomnum) { + for (i = 0; i < g_DyntexRoomsCount; i++) { + if (g_DyntexRooms[i].roomnum == roomnum) { return; } } } - if (var800a4194 != NULL) { - var8007f6e8 = 0; - var8007f6ec = 0; - var8007f6e0 = roomnum; - var8007f6e4 = -1; + if (g_DyntexRooms != NULL) { + g_DyntexRoomPopulated = false; + g_DyntexTypePopulated = false; + g_DyntexCurRoom = roomnum; + g_DyntexCurType = -1; } } -void func0f13c3f4(void) +void dyntexReset(void) { u32 size3; u32 size2; u32 size1; - var8007f6e0 = -1; - var8007f6e4 = -1; - var8007f6e8 = 0; - var8007f6f0 = 0; - var8007f6f4 = 0; - var8007f6f8 = 0; + g_DyntexCurRoom = -1; + g_DyntexCurType = -1; + g_DyntexRoomPopulated = false; + g_DyntexRoomsCount = 0; + g_DyntexTypesCount = 0; + g_DyntexVerticesCount = 0; - var800a4180 = 1200; - var800a4184 = 50; - var800a4188 = 50; + g_DyntexVerticesMax = 1200; + g_DyntexTypesMax = 50; + g_DyntexRoomsMax = 50; - size1 = ALIGN64(var800a4184 * sizeof(struct var800a4190)); - var800a4190 = mempAlloc(size1, MEMPOOL_STAGE); + size1 = ALIGN64(g_DyntexTypesMax * sizeof(struct dyntextype)); + g_DyntexTypes = mempAlloc(size1, MEMPOOL_STAGE); - size2 = ALIGN64(var800a4180 * sizeof(struct var800a418c)); - var800a418c = mempAlloc(size2, MEMPOOL_STAGE); + size2 = ALIGN64(g_DyntexVerticesMax * sizeof(struct dyntexvtx)); + g_DyntexVertices = mempAlloc(size2, MEMPOOL_STAGE); - size3 = ALIGN64(var800a4188 * sizeof(struct var800a4194)); - var800a4194 = mempAlloc(size3, MEMPOOL_STAGE); + size3 = ALIGN64(g_DyntexRoomsMax * sizeof(struct dyntexroom)); + g_DyntexRooms = mempAlloc(size3, MEMPOOL_STAGE); - if (var800a4180); - if (var800a4184); + if (g_DyntexVerticesMax); + if (g_DyntexTypesMax); if (size1); } -void func0f13c4e8(void) +void dyntex0f13c4e8(void) { // empty } -bool func0f13c4f0(void) +bool dyntexHasRoom(void) { - return var8007f6e0 >= 0; + return g_DyntexCurRoom >= 0; } diff --git a/src/game/tex.c b/src/game/tex.c index 5dd55deae..d18e2a3d6 100644 --- a/src/game/tex.c +++ b/src/game/tex.c @@ -831,7 +831,7 @@ glabel jtbl_var7f1b7c70 /* f175720: 00c0b025 */ or $s6,$a2,$zero /* f175724: 0fc5ce82 */ jal tex0f173a08 /* f175728: afb00128 */ sw $s0,0x128($sp) -/* f17572c: 0fc4f13c */ jal func0f13c4f0 +/* f17572c: 0fc4f13c */ jal dyntexHasRoom /* f175730: 00000000 */ nop /* f175734: 10400006 */ beqz $v0,.L0f175750 /* f175738: afa200e0 */ sw $v0,0xe0($sp) @@ -1043,26 +1043,26 @@ glabel jtbl_var7f1b7c70 /* f175a30: 00000000 */ nop /* f175a34: 56410005 */ bnel $s2,$at,.L0f175a4c /* f175a38: 24010a6a */ addiu $at,$zero,0xa6a -/* f175a3c: 0fc4f0ba */ jal func0f13c2e8 +/* f175a3c: 0fc4f0ba */ jal dyntexSetCurrentType /* f175a40: 24040001 */ addiu $a0,$zero,0x1 /* f175a44: 241e0001 */ addiu $s8,$zero,0x1 /* f175a48: 24010a6a */ addiu $at,$zero,0xa6a .L0f175a4c: /* f175a4c: 16410003 */ bne $s2,$at,.L0f175a5c /* f175a50: 24040006 */ addiu $a0,$zero,0x6 -/* f175a54: 0fc4f0ba */ jal func0f13c2e8 +/* f175a54: 0fc4f0ba */ jal dyntexSetCurrentType /* f175a58: 241e0001 */ addiu $s8,$zero,0x1 .L0f175a5c: /* f175a5c: 24010a69 */ addiu $at,$zero,0xa69 /* f175a60: 16410003 */ bne $s2,$at,.L0f175a70 /* f175a64: 24040007 */ addiu $a0,$zero,0x7 -/* f175a68: 0fc4f0ba */ jal func0f13c2e8 +/* f175a68: 0fc4f0ba */ jal dyntexSetCurrentType /* f175a6c: 241e0001 */ addiu $s8,$zero,0x1 .L0f175a70: /* f175a70: 240106e2 */ addiu $at,$zero,0x6e2 /* f175a74: 16410003 */ bne $s2,$at,.L0f175a84 /* f175a78: 24040003 */ addiu $a0,$zero,0x3 -/* f175a7c: 0fc4f0ba */ jal func0f13c2e8 +/* f175a7c: 0fc4f0ba */ jal dyntexSetCurrentType /* f175a80: 241e0001 */ addiu $s8,$zero,0x1 .L0f175a84: /* f175a84: 240101c7 */ addiu $at,$zero,0x1c7 @@ -1072,25 +1072,25 @@ glabel jtbl_var7f1b7c70 /* f175a94: 56410004 */ bnel $s2,$at,.L0f175aa8 /* f175a98: 2401029b */ addiu $at,$zero,0x29b .L0f175a9c: -/* f175a9c: 0fc4f0ba */ jal func0f13c2e8 +/* f175a9c: 0fc4f0ba */ jal dyntexSetCurrentType /* f175aa0: 241e0001 */ addiu $s8,$zero,0x1 /* f175aa4: 2401029b */ addiu $at,$zero,0x29b .L0f175aa8: /* f175aa8: 16410003 */ bne $s2,$at,.L0f175ab8 /* f175aac: 24040004 */ addiu $a0,$zero,0x4 -/* f175ab0: 0fc4f0ba */ jal func0f13c2e8 +/* f175ab0: 0fc4f0ba */ jal dyntexSetCurrentType /* f175ab4: 241e0001 */ addiu $s8,$zero,0x1 .L0f175ab8: /* f175ab8: 2401090f */ addiu $at,$zero,0x90f /* f175abc: 16410003 */ bne $s2,$at,.L0f175acc /* f175ac0: 24040005 */ addiu $a0,$zero,0x5 -/* f175ac4: 0fc4f0ba */ jal func0f13c2e8 +/* f175ac4: 0fc4f0ba */ jal dyntexSetCurrentType /* f175ac8: 241e0001 */ addiu $s8,$zero,0x1 .L0f175acc: /* f175acc: 24010a42 */ addiu $at,$zero,0xa42 /* f175ad0: 16410003 */ bne $s2,$at,.L0f175ae0 /* f175ad4: 24040002 */ addiu $a0,$zero,0x2 -/* f175ad8: 0fc4f0ba */ jal func0f13c2e8 +/* f175ad8: 0fc4f0ba */ jal dyntexSetCurrentType /* f175adc: 241e0001 */ addiu $s8,$zero,0x1 .L0f175ae0: /* f175ae0: 100000d7 */ b .L0f175e40 @@ -1119,7 +1119,7 @@ glabel jtbl_var7f1b7c70 /* f175b34: 920e0000 */ lbu $t6,0x0($s0) /* f175b38: 51c00005 */ beqzl $t6,.L0f175b50 /* f175b3c: 26310001 */ addiu $s1,$s1,0x1 -/* f175b40: 0fc4f01f */ jal func0f13c07c +/* f175b40: 0fc4f01f */ jal dyntexAddVertex /* f175b44: 8e440000 */ lw $a0,0x0($s2) /* f175b48: a2000000 */ sb $zero,0x0($s0) .L0f175b4c: @@ -1358,7 +1358,7 @@ glabel jtbl_var7f1b7c70 /* f175e88: 03ae2021 */ addu $a0,$sp,$t6 /* f175e8c: 51800005 */ beqzl $t4,.L0f175ea4 /* f175e90: 26100001 */ addiu $s0,$s0,0x1 -/* f175e94: 0fc4f01f */ jal func0f13c07c +/* f175e94: 0fc4f01f */ jal dyntexAddVertex /* f175e98: 8c8400a0 */ lw $a0,0xa0($a0) /* f175e9c: a2200000 */ sb $zero,0x0($s1) /* f175ea0: 26100001 */ addiu $s0,$s0,0x1 @@ -1431,7 +1431,7 @@ glabel jtbl_var7f1b7c70 // // tex0f173a08(); // -// spe0 = func0f13c4f0(); +// spe0 = dyntexHasRoom(); // // if (spe0) { // for (j = 0; j < 16; j++) { @@ -1521,43 +1521,58 @@ glabel jtbl_var7f1b7c70 // } // // if (spe0 != 0) { +// // Deep Sea - green river under floor // if (texturenum == TEXTURE_06CB) { -// func0f13c2e8(1); +// dyntexSetCurrentType(DYNTEXTYPE_RIVER); // animated = true; // } // +// // Deep Sea - juice that flows inside SA megaweapon +// // Attack Ship - juice that flows inside engine power node // if (texturenum == TEXTURE_0A6A) { -// func0f13c2e8(6); +// dyntexSetCurrentType(DYNTEXTYPE_POWERJUICE); // animated = true; // } // +// // Deep Sea - white rings around SA megaweapon node +// // Attack Ship - white rings around engine power node // if (texturenum == TEXTURE_0A69) { -// func0f13c2e8(7); +// dyntexSetCurrentType(DYNTEXTYPE_POWERRING); // animated = true; // } // +// // Deep Sea - teleport // if (texturenum == TEXTURE_06E2) { -// func0f13c2e8(3); +// dyntexSetCurrentType(DYNTEXTYPE_TELEPORTAL); // animated = true; // } // +// // 01c7 - Air Base - distant water +// // 01c7 - Investigation - puddle behind glass near shield +// // 0dae - Chicago - canal +// // 0dae - Villa - shallow water +// // 0dae - Sewers (MP) // if (texturenum == TEXTURE_01C7 || texturenum == TEXTURE_0DAE) { -// func0f13c2e8(1); +// dyntexSetCurrentType(DYNTEXTYPE_RIVER); // animated = true; // } // +// // Air Force One - Monitor // if (texturenum == TEXTURE_029B) { -// func0f13c2e8(4); +// dyntexSetCurrentType(DYNTEXTYPE_MONITOR); // animated = true; // } // +// // Villa - deep water +// // Complex - water // if (texturenum == TEXTURE_090F) { -// func0f13c2e8(5); +// dyntexSetCurrentType(DYNTEXTYPE_OCEAN); // animated = true; // } // +// // Attack Ship - triangular arrows // if (texturenum == TEXTURE_0A42) { -// func0f13c2e8(2); +// dyntexSetCurrentType(DYNTEXTYPE_ARROWS); // animated = true; // } // } @@ -1579,7 +1594,7 @@ glabel jtbl_var7f1b7c70 // // for (i = start; i < start + count; i++) { // if (animated && sp90[i]) { -// func0f13c07c(spA0[i]); +// dyntexAddVertex(spA0[i]); // sp90[i] = 0; // } // @@ -1701,7 +1716,7 @@ glabel jtbl_var7f1b7c70 // // for (i = 0; i < 16; i++) { // if (sp90[i]) { -// func0f13c07c(spA0[i]); +// dyntexAddVertex(spA0[i]); // sp90[i] = 0; // } // } diff --git a/src/include/constants.h b/src/include/constants.h index a99ff411a..ba7d84573 100644 --- a/src/include/constants.h +++ b/src/include/constants.h @@ -808,6 +808,14 @@ #define DROPTYPE_5 5 #define DROPTYPE_OWNERREAP 6 +#define DYNTEXTYPE_RIVER 1 +#define DYNTEXTYPE_ARROWS 2 +#define DYNTEXTYPE_TELEPORTAL 3 +#define DYNTEXTYPE_MONITOR 4 +#define DYNTEXTYPE_OCEAN 5 +#define DYNTEXTYPE_POWERJUICE 6 +#define DYNTEXTYPE_POWERRING 7 + // Might be the same flags as PROJECTILEFLAG #define EMBEDMENTFLAG_FREE 0x00000001 @@ -3461,7 +3469,7 @@ #define RENDERPASS_OPAQUE_POSTBG 2 #define ROOMFLAG_FORCEDISABLED 0x0001 -#define ROOMFLAG_0002 0x0002 +#define ROOMFLAG_HASDYNTEX 0x0002 #define ROOMFLAG_VISIBLEBYPLAYER 0x0004 #define ROOMFLAG_VISIBLEBYAIBOT 0x0008 #define ROOMFLAG_0010 0x0010 diff --git a/src/include/game/game_13b670.h b/src/include/game/game_13b670.h index 5f97044ba..c8b7c3710 100644 --- a/src/include/game/game_13b670.h +++ b/src/include/game/game_13b670.h @@ -4,16 +4,11 @@ #include "data.h" #include "types.h" -void func0f13b670(struct gfxvtx *vertices, struct var800a4190 *arg1); -void func0f13b754(struct gfxvtx *vertices, struct var800a4190 *arg1); -void func0f13b7bc(struct gfxvtx *vertices, struct var800a4190 *arg1); -void func0f13b8a0(struct gfxvtx *vertices, struct var800a4190 *arg1); -void func0f13bb5c(struct gfxvtx *vertices, struct var800a4190 *arg1); -void func0f13bc48(s32 roomnum, struct gfxvtx *vertices); -void func0f13c07c(struct gfxvtx *vertex); -void func0f13c2e8(s16 arg0); -void func0f13c370(s16 roomnum); -void func0f13c3f4(void); -bool func0f13c4f0(void); +void dyntexTickRoom(s32 roomnum, struct gfxvtx *vertices); +void dyntexAddVertex(struct gfxvtx *vertex); +void dyntexSetCurrentType(s16 type); +void dyntexSetCurrentRoom(s16 roomnum); +void dyntexReset(void); +bool dyntexHasRoom(void); #endif diff --git a/src/include/types.h b/src/include/types.h index 1ffaa67e3..e8e0a3195 100644 --- a/src/include/types.h +++ b/src/include/types.h @@ -6600,26 +6600,6 @@ struct texcacheitem { u8 heights[7]; }; -struct var800a418c { - u16 offset; - s16 s; - s16 t; -}; - -struct var800a4190 { - u16 unk00_00 : 7; - u16 unk00_07 : 1; - u8 unk01; - u16 unk02; -}; - -struct var800a4194 { - u16 roomnum; - u16 unk02; - u16 unk04; - s32 framenum; -}; - struct skything18 { /*0x00*/ f32 unk00; /*0x04*/ f32 unk04;