From c9029b18fd494fdb5d4cc372db2a3f67be94333f Mon Sep 17 00:00:00 2001 From: Drew T <50529377+Druthulu@users.noreply.github.com> Date: Sun, 30 Aug 2026 21:27:06 -0600 Subject: [PATCH] =?UTF-8?q?feat(decomp):=20main=20batch-gate=20batch=201?= =?UTF-8?q?=20=E2=80=94=20143dbb89=20byte-identical?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/800.c | 276 ++++++++++++++++++++++++++++++++++++++++++++++++++- src/800c.c | 113 ++++++++++++++++++++- src/800c3.c | 78 ++++++++++++++- src/sgap_4.c | 60 ++++++++++- src/sgap_6.c | 153 +++++++++++++++++++++++++++- 5 files changed, 672 insertions(+), 8 deletions(-) diff --git a/src/800.c b/src/800.c index 27ad65b32..0e7627738 100644 --- a/src/800.c +++ b/src/800.c @@ -9937,7 +9937,86 @@ void func_8001F97C(void *a0) *(u16 *)((u8 *)a0 + 0x2C) |= 1; } -INCLUDE_ASM("asm/nonmatchings/800", func_8001F9F8); +extern u8 D_800AF8D8[]; +extern u8 D_800AFB6C[]; +extern u8 D_800AFBF0[]; +extern u8 D_800B0430[]; +extern u8 D_800B0C70[]; +extern u8 D_800B3DF0[]; +extern u8 D_800B9A11; +extern void func_8001FB8C(s32* a0, s32* a1); + +void func_8001F9F8(void) { + u8* p; + u8 bits; + s32 x; + + bits = D_800B9A11; + { + s32 i; + i = 0; + p = D_800AF8D8; + x = 0; + for (; i < 4; i++) { + func_8001FB8C(p, &x); + p += 0x84; + } + } + if (!(bits & 2)) { + s32 i; + i = 0; + p = D_800AF8D8 + 0x210; + for (; i < 1; i++) { + func_8001FB8C(p, &x); + p += 0x84; + } + } + if (!(bits & 8)) { + s32 i; + i = 0; + p = D_800AFB6C; + for (; i < 1; i++) { + func_8001FB8C(p, &x); + p += 0x84; + } + } + if (!(bits & 0x10)) { + s32 i; + i = 0; + p = D_800AFBF0; + for (; i < 0x10; i++) { + func_8001FB8C(p, &x); + p += 0x84; + } + } + if (!(bits & 0x20)) { + s32 i; + i = 0; + p = D_800B0430; + for (; i < 0x10; i++) { + func_8001FB8C(p, &x); + p += 0x84; + } + } + if (!(bits & 0x40)) { + s32 i; + i = 0; + p = D_800B0C70; + for (; i < 0x60; i++) { + func_8001FB8C(p, &x); + p += 0x84; + } + } + if (!(bits & 0x80)) { + s32 i; + i = 0; + p = D_800B3DF0; + for (; i < 0x3A; i++) { + func_8001FB8C(p, &x); + p += 0x84; + } + } +} extern void (*D_80063500[])(); @@ -20507,7 +20586,71 @@ s32 func_80034CF0(u8 *p) { return ret; } -INCLUDE_ASM("asm/nonmatchings/800", func_80034DFC); +extern u8 D_8006AEF5; +extern s32 D_8006AEF8; +extern s32 D_8006AEFC; +extern u8 D_80076118[]; + +void func_80034DFC(short arg0) { + u8 *cur; + u8 *src; + u8 saved; + s32 i; + s32 next; + s32 nn; + + if (arg0 == 0) { + return; + } + i = (short)(arg0 - 1); + cur = D_80076118 + i * 0x30; + saved = D_8006AEF5; + D_8006AEF5 = 1; + if (cur[0] != 0) { + cur[0] = 0; + cur[1] = 1; + if (i != D_8006AEF8 && cur[7] != 0) { + next = i + 1; + goto check; + for (;;) { + src = D_80076118 + next * 0x30; + cur[0] = src[0]; + cur[1] = src[1]; + cur[2] = src[2]; + cur[3] = src[3]; + cur[4] = src[4]; + cur[5] = src[5]; + cur[6] = src[6]; + cur[7] = src[7]; + *(s32 *)(cur + 0x08) = *(s32 *)(src + 0x08); + *(s32 *)(cur + 0x0C) = *(s32 *)(src + 0x0C); + *(s32 *)(cur + 0x10) = *(s32 *)(src + 0x10); + *(s32 *)(cur + 0x14) = *(s32 *)(src + 0x14); + *(s32 *)(cur + 0x18) = *(s32 *)(src + 0x18); + *(s32 *)(cur + 0x1C) = *(s32 *)(src + 0x1C); + *(s32 *)(cur + 0x20) = *(s32 *)(src + 0x20); + *(s32 *)(cur + 0x24) = *(s32 *)(src + 0x24); + nn = next + 1; + *(s32 *)(cur + 0x28) = *(s32 *)(src + 0x28); + *(s32 *)(cur + 0x2C) = *(s32 *)(src + 0x2C); + ((void (*)(s32, s32)) *(s32 *)(src + 0x28))(nn, i + 1); + i = next; + cur = src; + next = nn; + check: + if (next >= 4) { + next = 0; + } + if (next == D_8006AEFC) { + break; + } + } + D_8006AEFC = i; + D_80076118[i * 0x30] = 0; + } + } + D_8006AEF5 = saved; +} extern u8 D_8006AEF5; @@ -20924,7 +21067,116 @@ int StreamLoadStateMachine(int param_1, void *param_2, int param_3) { /* param_ INCLUDE_ASM("asm/nonmatchings/800", StreamLoadStateMachine); #endif -INCLUDE_ASM("asm/nonmatchings/800", func_80036AF8); + +extern s32 D_8006A69C; +extern u8 D_8006A6A0; +extern s32 D_8006A6A4; +extern s32 D_8006AEE8; +extern s32 D_80078F10; +extern u8 D_800A46BA; +extern u8 D_800A4F1A; +extern s32 func_80034CF0(u8 *); +extern void func_80034DFC(short); +extern void func_80035270(void); +extern void func_800359B0(void); +extern void func_80036D24(void); +extern void func_80036FB0(s32, s32); + +typedef struct { + s32 f00; + s32 f04; + s32 f08; + s32 f0c; + s32 f10; + s32 f14; + s32 f18; + s32 f1c; + s32 f20; + s32 f24; + s32 f28; + s32 f2c; +} CdReq; + +void func_80036AF8(CdlLOC *loc, s32 flags) { + register s32 zr __asm__("$0"); + CdReq req; + s32 mode; + s32 n; + s32 idx; + s32 lo; + s16 h; + s32 drv; + s32 hi; + u8 b; + s32 i; + s32 ret; + u8 *rec; + u8 *rec2; + u8 *tbl; + s32 hoff; + + mode = flags + zr; + if (!(flags & 0x4000)) { + return; + } + + n = flags & 0xF; + idx = n + zr; + lo = (s32)(flags << 16) >> 20; + drv = ((s32)(flags << 16) >> 25) & 0x1F; + hi = drv + zr; + h = lo & 0x1F; + if (lo & 1) { + if (*(u8 *)((u8 *)&D_8006A6A0 + drv * 0x48) != 0) { + idx = n + 4; + } else { + idx = n + 8; + } + } + + h = h >> 1; + rec = (u8 *)*(s32 *)((u8 *)&D_8006A69C + hi * 0x48); + rec2 = rec + (h << 6); + b = *(u8 *)(rec2 + (idx << 2) + 1); + if ((b & 0xF0) == 0) { + return; + } + + if (D_8006AEE8 != 0) { + if ((b & 0xF) == 0) { + return; + } + if ((b & 0xF) == 1) { + for (i = 0; i < D_8006AEE8; i++) { + func_80034DFC(*(short *)(&D_80078F10 + i)); + (&D_80078F10)[i] = 0; + } + D_8006AEE8 = 0; + } + } + + req.f08 = (s32)func_80035270; + D_800A46BA = 0; + if (h != 0) { + ret = CdPosToInt(loc); + hoff = hi * 0x48; + tbl = (u8 *)&D_8006A6A4; + req.f0c = ret + *(s32 *)(tbl + hoff + h * 4); + } else { + req.f0c = CdPosToInt(loc); + } + req.f10 = (s16)mode; + req.f1c = (s32)func_80036D24; + req.f24 = (s32)func_800359B0; + req.f20 = 0; + req.f28 = (s32)func_80036FB0; + ret = func_80034CF0((u8 *)&req); + if (ret != 0) { + (&D_80078F10)[D_8006AEE8] = ret; + D_8006AEE8 = D_8006AEE8 + 1; + } + D_800A4F1A = 1; +} extern s32 D_8006AEE8; extern s32 D_80078F10; @@ -21978,7 +22230,23 @@ s32 func_80038A00(void) { INCLUDE_ASM("asm/nonmatchings/800", func_80038A58); -INCLUDE_ASM("asm/nonmatchings/800", func_80038FC4); +s32 func_80038FC4(u8 **a0) { + s32 result = 0; + u8 b; + + do { + u8 *p = *a0; + b = *p++; + *a0 = p; + result += b & 0x7F; + if (!(b & 0x80)) { + break; + } + result <<= 7; + } while (1); + + return result; +} INCLUDE_ASM("asm/nonmatchings/800", func_80038FFC); diff --git a/src/800c.c b/src/800c.c index 426a98589..5b44d035e 100644 --- a/src/800c.c +++ b/src/800c.c @@ -1577,7 +1577,118 @@ __asm__( ".end\tSYS_OBJ_1578\n" ); -INCLUDE_ASM("asm/nonmatchings/800c", func_8005A870); +/* + * func_8005A870 -- like func_80059FC0/SYS_OBJ_E34 and func_80059234/SYS_OBJ_16C in this + * same TU, this function's LAST basic block falls straight through (no "jr $ra", no + * epilogue) into SYS_OBJ_1790, a separately-banked file-scope asm fragment that owns + * this same 0x40-byte / s0,s1,ra frame and its own eventual epilogue (via SYS_OBJ_18AC). + * One path additionally takes a bare `beqz`/`bnez` transfer straight into SYS_OBJ_18AC / + * SYS_OBJ_1790 respectively. gcc-2.7.2 has no sibcall optimization and unconditionally + * appends its own "jr $ra" epilogue to any ordinary C function body -- so this can only be + * expressed as FILE-SCOPE inline asm (no enclosing C function), transcribed 1:1 from the + * target .s (asm/nonmatchings/800c/func_8005A870.s), with every symbol spelled exactly as + * the target's own relocation lines name it. + */ +__asm__( + ".text\n" + ".align\t2\n" + ".globl\tfunc_8005A870\n" + ".ent\tfunc_8005A870\n" + "func_8005A870:\n" + ".frame\t$sp,64,$31\n" + ".mask\t0x80030000,-8\n" + ".fmask\t0x00000000,0\n" + ".set\tnoreorder\n" + "addiu $sp, $sp, -64\n" + "sw $s0, 48($sp)\n" + "addu $s0, $a1, $zero\n" + "sw $s1, 52($sp)\n" + "addu $s1, $a0, $zero\n" + "sw $ra, 56($sp)\n" + "lh $a0, 0($s0)\n" + "lh $a1, 2($s0)\n" + "jal func_8005AB58\n" + " nop\n" + "sw $v0, 4($s1)\n" + "lhu $a0, 4($s0)\n" + "lhu $v0, 0($s0)\n" + "lhu $a1, 2($s0)\n" + "addu $a0, $a0, $v0\n" + "addiu $a0, $a0, -1\n" + "sll $a0, $a0, 16\n" + "lhu $v0, 6($s0)\n" + "sra $a0, $a0, 16\n" + "addu $a1, $a1, $v0\n" + "addiu $a1, $a1, -1\n" + "sll $a1, $a1, 16\n" + "jal func_8005AC24\n" + " sra $a1, $a1, 16\n" + "sw $v0, 8($s1)\n" + "lh $a0, 8($s0)\n" + "lh $a1, 10($s0)\n" + "jal func_8005ACF0\n" + " nop\n" + "sw $v0, 12($s1)\n" + "lbu $a0, 23($s0)\n" + "lbu $a1, 22($s0)\n" + "lhu $a2, 20($s0)\n" + "jal func_8005AB00\n" + " nop\n" + "addiu $a0, $s0, 12\n" + "jal func_8005AD34\n" + " sw $v0, 16($s1)\n" + "sw $v0, 20($s1)\n" + "lui $v0, 0xe600\n" + "sw $v0, 24($s1)\n" + "lbu $v0, 24($s0)\n" + "nop\n" + "beqz $v0, SYS_OBJ_18AC\n" + " addiu $t0, $zero, 7\n" + "lhu $v0, 0($s0)\n" + "nop\n" + "sh $v0, 16($sp)\n" + "lhu $v0, 2($s0)\n" + "nop\n" + "sh $v0, 18($sp)\n" + "lhu $a0, 4($s0)\n" + "nop\n" + "sh $a0, 20($sp)\n" + "lhu $v0, 6($s0)\n" + "nop\n" + "sh $v0, 22($sp)\n" + "sll $v0, $a0, 16\n" + "sra $a1, $v0, 16\n" + "bltz $a1, .L8005A988\n" + " addu $v0, $zero, $zero\n" + "lui $v0, %hi(D_8007278C)\n" + "lh $v0, %lo(D_8007278C)($v0)\n" + "nop\n" + "addu $v1, $v0, $zero\n" + "addiu $v0, $v0, -1\n" + "slt $v0, $v0, $a1\n" + "bnez $v0, .L8005A988\n" + " addiu $v0, $v1, -1\n" + "addu $v0, $a0, $zero\n" + ".L8005A988:\n" + "lh $a1, 22($sp)\n" + "sh $v0, 20($sp)\n" + "bltz $a1, .L8005A9C0\n" + " addu $a0, $a1, $zero\n" + "lui $v0, %hi(D_8007278E)\n" + "lh $v0, %lo(D_8007278E)($v0)\n" + "nop\n" + "addu $v1, $v0, $zero\n" + "addiu $v0, $v0, -1\n" + "slt $v0, $v0, $a1\n" + "bnez $v0, SYS_OBJ_1790\n" + " addiu $v0, $v1, -1\n" + "j SYS_OBJ_1790\n" + " addu $v0, $a0, $zero\n" + ".L8005A9C0:\n" + "addu $v0, $zero, $zero\n" + ".set\treorder\n" + ".end\tfunc_8005A870\n" +); /* SYS_OBJ_1790 (0x8005A9C4, 0x11C, 71 insns) -- REPLACES the * INCLUDE_ASM("asm/nonmatchings/800c", SYS_OBJ_1790) entry at this exact spot diff --git a/src/800c3.c b/src/800c3.c index c8a352fc5..1f0592993 100644 --- a/src/800c3.c +++ b/src/800c3.c @@ -1329,7 +1329,83 @@ __asm__( ".set\treorder\n" ".end\tfunc_8005EAE8\n"); -INCLUDE_ASM("asm/nonmatchings/800c3", func_8005EB28); +/* + * func_8005EB28 -- the target's epilogue restores TWO callee-saved registers + * ($ra and $s0) yet still ends in a bare `jr $ra` / `addiu $sp,$sp,0x18` + * delay-slot pair. Per cookbook §188 (gcc-2.7.2 mips.c:5081/5174/5204, + * mips_epilogue_delay_slots): cc1 offers the epilogue a delay slot ONLY when + * mask == RA_MASK && fmask == 0 (i.e. only $ra saved) -- with $s0 also saved, + * that branch is structurally unreachable, so NO C source can make cc1 emit + * this tail under the project's pinned `as -O1` (confirmed here with + * tools/oracle_reorder.py: bypass+`as -O2` on the ordinary-C draft gives 0 + * diffs, i.e. the C was already right and only the assembler's schedule pass + * was missing). This is the §265 "no -O2 C can ever match" class, form 1: + * the whole body is transcribed verbatim as a raw __asm__ block so gcc passes + * it through untouched. See src/md_MAIN_003/md_MAIN_003.c:524 (func_800D0440) + * for the precedent this follows. + */ +__asm__(".text\n.align 2\n.globl func_8005EB28\n.ent\tfunc_8005EB28\n" +"func_8005EB28:\n.frame $sp,24,$31\n.mask 0x80010000,-4\n.fmask 0,0\n" +".set\tnoreorder\n" +"lui $v1, %hi(D_8007299C)\n" +"lw $v1, %lo(D_8007299C)($v1)\n" +"lui $v0, %hi(D_800729AC)\n" +"lw $v0, %lo(D_800729AC)($v0)\n" +"addiu $sp, $sp, -24\n" +"sw $s0, 16($sp)\n" +"addu $s0, $a0, $zero\n" +"bne $v1, $v0, .L8005EB88\n" +" sw $ra, 20($sp)\n" +"lui $v0, %hi(D_80072998)\n" +"lw $v0, %lo(D_80072998)($v0)\n" +"nop\n" +"beqz $v0, .L8005EB88\n" +" nop\n" +"lui $v0, %hi(D_8007298C)\n" +"lw $v0, %lo(D_8007298C)($v0)\n" +"nop\n" +"jalr $v0\n" +" nop\n" +"lui $v0, %hi(D_80072988)\n" +"lw $v0, %lo(D_80072988)($v0)\n" +"nop\n" +"jalr $v0\n" +" nop\n" +".L8005EB88:\n" +"lui $v0, %hi(D_800729DC)\n" +"lw $v0, %lo(D_800729DC)($v0)\n" +"nop\n" +"beqz $v0, .L8005EBCC\n" +" nop\n" +"lw $a0, 12($s0)\n" +"lui $v0, %hi(D_80072974)\n" +"lw $v0, %lo(D_80072974)($v0)\n" +"nop\n" +"jalr $v0\n" +" nop\n" +"lw $a0, 12($s0)\n" +"lui $v0, %hi(D_80072974)\n" +"lw $v0, %lo(D_80072974)($v0)\n" +"nop\n" +"jalr $v0\n" +" addiu $a0, $a0, 240\n" +".L8005EBCC:\n" +"lbu $v0, 54($s0)\n" +"nop\n" +"bnez $v0, .L8005EBE4\n" +" addu $a0, $s0, $zero\n" +"j .L8005EBE8\n" +" addiu $a1, $zero, 66\n" +".L8005EBE4:\n" +"lbu $a1, 54($s0)\n" +".L8005EBE8:\n" +"jal func_8005DE78\n" +" nop\n" +"lw $ra, 20($sp)\n" +"lw $s0, 16($sp)\n" +"jr $ra\n" +" addiu $sp, $sp, 24\n" +".set\treorder\n.end\tfunc_8005EB28\n"); INCLUDE_ASM("asm/nonmatchings/800c3", func_8005EC00); diff --git a/src/sgap_4.c b/src/sgap_4.c index 11ee52637..6722094cb 100644 --- a/src/sgap_4.c +++ b/src/sgap_4.c @@ -2,4 +2,62 @@ INCLUDE_ASM("asm/nonmatchings/sgap_4", func_8003DC90); -INCLUDE_ASM("asm/nonmatchings/sgap_4", func_8003DF8C); + +extern s32 D_800C73D8[]; +extern void func_80040DE8(s16, u16, u16, s16); +extern s32 func_80041354(s16, u16 *, u16 *); + +void func_8003DF8C(s32 arg0, s32 arg1) +{ + register s32 zr __asm__("$0"); + u16 w; + u16 h; + s32 p; + s32 n; + s32 i; + s32 j; + + i = arg0 + zr; + j = arg1 + zr; + p = D_800C73D8[(s16)arg0] + (s16)arg1 * 0xB0; + n = *(s32 *)(p + 0xA0) - 1; + *(s32 *)(p + 0xA0) = n; + if (n < 0) { + *(s32 *)((s16)arg1 * 0xB0 + D_800C73D8[(s16)arg0] + 0x98) &= ~0x20; + goto tail; + } + if (*(s16 *)(p + 0x4C) > 0) { + if (n % *(s16 *)(p + 0x4C) != 0) { + goto tail; + } + *(s16 *)(p + 0x4A) -= 1; + if (*(s16 *)(p + 0x4A) > 0) { + func_80041354(arg0 | (arg1 << 8), &w, &h); + if (w - *(s16 *)(p + 0x4A) > 0 && h - *(s16 *)(p + 0x4A) > 0 && w != 1) { + func_80040DE8(arg0 | (arg1 << 8), w - 1, h - 1, 1); + } else { + func_80040DE8(i | (j << 8), 1, 1, 1); + } + } else { + *(s32 *)((s16)arg1 * 0xB0 + D_800C73D8[(s16)arg0] + 0x98) &= ~0x20; + } + } else { + *(s16 *)(p + 0x4A) += *(s16 *)(p + 0x4C); + if (*(s16 *)(p + 0x4A) > 0) { + func_80041354(arg0 | (arg1 << 8), &w, &h); + if (*(s16 *)(p + 0x48) >= (*(s32 *)(p + 0x9C) - *(s32 *)(p + 0xA0)) * -*(s16 *)(p + 0x4C) + && -*(s16 *)(p + 0x4C) < w) { + func_80040DE8(arg0 | (arg1 << 8), w + *(s16 *)(p + 0x4C), h + *(s16 *)(p + 0x4C), 1); + } else { + func_80040DE8(i | (j << 8), 1, 1, 1); + } + } else { + *(s32 *)((s16)arg1 * 0xB0 + D_800C73D8[(s16)arg0] + 0x98) &= ~0x20; + } + } + if (*(s32 *)(p + 0xA0) == 0 || *(s16 *)(p + 0x4A) == 0) { + *(s32 *)(D_800C73D8[(s16)i] + (s16)j * 0xB0 + 0x98) &= ~0x20; + } +tail: + func_80041354(i | (j << 8), (u16 *)(p + 0x5C), (u16 *)(p + 0x5E)); +} diff --git a/src/sgap_6.c b/src/sgap_6.c index 0cddefc3d..3e3ede67c 100644 --- a/src/sgap_6.c +++ b/src/sgap_6.c @@ -5,4 +5,155 @@ void func_8003FA54(void) { D_800A5F60 = 0; } -INCLUDE_ASM("asm/nonmatchings/sgap_6", func_8003FA64); +extern s32 D_800BA1B0; +extern u8 D_800AE614; +extern u32 D_800C7EC0[16]; +extern u16 D_8007958E; +extern u8 D_800BA100; +extern u8 D_800795A3; +extern u16 D_800C7F04; +extern u16 D_800C7F06; +extern s16 D_800795A4; +extern s16 D_800795B0; +extern u8 D_800A4620; +extern u16 D_80078D8C; +extern u16 D_80078D8E; +extern u16 D_80078D90; +extern u16 D_80078D92; +extern u16 D_800B9B58; +extern u16 D_800B9B5C; +extern u16 D_800B9B5E; +extern void (*D_800BA0D0)(s32); +extern void (*D_800AE828)(s32); +extern u16* D_8006B8FC; +extern void func_8003FE18(s32, u32); + +void func_8003FA64(void) { + s32 pad[2]; /* frame pad: target vars=16 (cookbook §226 / §162i1 dead-local lever) */ + s32 i = 0; + s32 n; + u32 mask; + u32 off; + u8* fp; + u16* pa2; + u16* pa3; + u16* pt0; + u16* pt1; + u16* pend; + u16* pb; + u16 r1, r2, r3, r4, r5, r6; + u16* dp; + + D_800BA1B0 = (D_800BA1B0 + 1) & 0xF; + D_800C7EC0[D_800BA1B0] = 0; + n = D_800AE614; + if (n > 0) { + u32* mp = &D_800C7EC0[D_800BA1B0]; + u32 one = 1; + s32 count = D_800AE614; + u16* vp = D_8006B8FC; + u32 off0 = 0; + do { + u16 val = *(u16*)((char*)vp + 0xC); + *(u16*)((char*)&D_8007958E + off0) = val; + if (val == 0) { + *mp |= one << i; + } + vp += 8; + off0 += 0x34; + i++; + } while (i < count); + } + + i = 0; + if (D_800BA100 == 0) { + mask = -1; + do { + mask &= D_800C7EC0[i]; + i++; + } while (i < 0xF); + for (i = 0; i < (s32)D_800AE614; i++) { + u32 one = 1; + u32 two = 2; + off = i * 0x34; + if ((mask & (one << i)) != 0) { + if (*(u8*)((char*)&D_800795A3 + off) == two) { + func_8003FE18(0, 0xFFFFFF); + } + *(u8*)((char*)&D_800795A3 + off) = 0; + } + } + i = 0; + } + + D_80078D8C &= ~D_800C7F04; + D_80078D8E &= ~D_800C7F06; + + off = 0; + do { + if (*(s16*)((char*)&D_800795A4 + off) != 0) { + D_800BA0D0(i); + } + if (*(s16*)((char*)&D_800795B0 + off) != 0) { + D_800AE828(i); + } + i++; + off += 0x34; + } while (i < 0x18); + + fp = &D_800A4620; + pb = &D_800B9B58; + pt1 = pb + 5; + pt0 = pb + 4; + { + u32 off4 = 0; + pa3 = pb + 1; + pa2 = pb; + pend = &D_800A4620 + 24; + do { + if ((*fp & 1) != 0) { + u16* d1 = (u16*)(off4 + (u32)D_8006B8FC); + *d1 = *pa2; + *(u16*)((char*)d1 + 2) = *pa3; + } + if ((*fp & 4) != 0) { + u16* d2 = (u16*)(off4 + (u32)D_8006B8FC); + *(u16*)((char*)d2 + 4) = *(u16*)((char*)&D_800B9B5C + off4); + } + if ((*fp & 8) != 0) { + u16* d3 = (u16*)(off4 + (u32)D_8006B8FC); + *(u16*)((char*)d3 + 6) = *(u16*)((char*)&D_800B9B5E + off4); + } + if ((*fp & 0x10) != 0) { + u16* d4 = (u16*)(off4 + (u32)D_8006B8FC); + *(u16*)((char*)d4 + 8) = *pt0; + *(u16*)((char*)d4 + 0xA) = *pt1; + } + *fp = 0; + fp++; + pt1 += 8; + pt0 += 8; + off4 += 0x10; + pa3 += 8; + pa2 += 8; + } while ((s32)fp < (s32)pend); + } + + dp = D_8006B8FC; + r1 = D_800C7F04; + r2 = D_800C7F06; + r3 = D_80078D8C; + r4 = D_80078D8E; + r5 = D_80078D90; + r6 = D_80078D92; + D_800C7F04 = 0; + D_800C7F06 = 0; + D_80078D8C = 0; + D_80078D8E = 0; + *(u16*)((char*)dp + 0x18C) = r1; + *(u16*)((char*)dp + 0x18E) = r2; + *(u16*)((char*)dp + 0x188) = r3; + *(u16*)((char*)dp + 0x18A) = r4; + *(u16*)((char*)dp + 0x198) = r5; + *(u16*)((char*)dp + 0x19A) = r6; +}