mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-10-05 17:03:23 -04:00
4631 lines
135 KiB
C
4631 lines
135 KiB
C
#include "common.h"
|
||
|
||
#include "common.h"
|
||
|
||
extern void (*D_801A6B2C[])(void *);
|
||
extern void func_801A293C(void *a0);
|
||
extern void func_801A4268(s32 self);
|
||
extern void func_801A2EC8(void *a0);
|
||
extern s32 D_801F4360[];
|
||
|
||
void func_801A01D4(void *a0) {
|
||
D_801A6B2C[*(u16 *)((s32)a0 + 0x2)](a0);
|
||
if (*(u16 *)a0 != 0) {
|
||
func_801A293C(a0);
|
||
func_801A4268(a0);
|
||
func_801A2EC8(a0);
|
||
}
|
||
{
|
||
s32 i;
|
||
for (i = 0; i < 3; i++) {
|
||
D_801F4360[i] += 1;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/*
|
||
* func_801A026C (md_SC07_003, 0x801A026C, 154 ins) == MATCH, byte-exact.
|
||
*
|
||
* Overlay/actor init: gate on the game-state id, register the actor, seed its
|
||
* fields, spawn four sub-actors, then seed the SC07 minigame globals.
|
||
*
|
||
* LEVERS (each verified by removing it and re-scoring):
|
||
* 1. The 0x58 word is written with PLAIN LITERALS:
|
||
* (u32)D_801A6854 | 0x10000000 | 0x40000000
|
||
* fold's `associate` does NOT merge the two constants because the left
|
||
* operand is an ADDR_EXPR, not an INTEGER_CST, so split_tree finds no
|
||
* constant to pull and the two `or`s survive (accumulator $v0, temp $v1).
|
||
* Binding either constant to a local (src/800.c lever 2) is WRONG here: it
|
||
* hoists the lui above the address and swaps the or order (6 mismatched);
|
||
* `h |= C;` statement form puts the accumulator in $v1 (10 mismatched).
|
||
* 2. The D_801AE21C -> D_801F436C copy loop must use EXPLICIT BYTE OFFSETS
|
||
* (`*(s32 *)((u8 *)D_801AE21C + k)`), not `D_801AE21C[i]`. With array
|
||
* indexing loop.c strength-reduces both accesses into ADDRESS givs and
|
||
* hoists two la pairs into the preheader (cookbook s190-A); the target
|
||
* keeps integer givs and re-materialises %hi/%lo inside the loop, which is
|
||
* one instruction longer. This alone fixed the -1 LENGTH-DRIFT.
|
||
* 3. The copy loop's counter is the SAME C VARIABLE `i` as the rand() loop's
|
||
* counter. That pseudo is live across `jal rand`, so it is callee-saved,
|
||
* which is why the copy loop's counter sits in $s1 while its two offsets
|
||
* sit in caller-saved $a0/$v1 (cookbook s194-C read backwards). A fresh
|
||
* variable puts the counter in $v1 (3 mismatched registers).
|
||
* 4. Init order in the copy-loop preheader is source order: `i = 0; k = 0;
|
||
* j = 0; for (; i < 20; i++)`. Writing `k = 0; j = 0; for (i = 0; ...)`
|
||
* emits the three `move ...,zero` in the wrong order (3 mismatched).
|
||
* 5. `*(s32 *)(arg0 + 0x20)` is written RAW at all three uses. The store to
|
||
* 0x2C of that pointer kills cse's pointer-derived load, so the target
|
||
* reloads it; naming it in a local collapses two of the three intervals
|
||
* (cookbook s193-E).
|
||
* 6. The two s16 fill loops index a stride-8 record and let gcc eliminate the
|
||
* biv, which is what produces `slti $v1, 0x388` / `slti $v1, 0x460` on the
|
||
* byte-offset giv.
|
||
*
|
||
* SYMBOL AUDIT (law 1c, done after MATCH) - every symbol re-checked against the
|
||
* relocation lines of asm/md_SC07_003/nonmatchings/md_SC07_003/func_801A026C.s.
|
||
* The draft's symbol set and the .s's symbol set are identical (28 names), and
|
||
* each call site / load side / store side was walked individually:
|
||
* jal func_80029504 / func_8012CAE4($a0=arg0) / func_8012C354(arg0,&D_801A6874)
|
||
* / func_8001D0E8(*(arg0+0x20),0x7FFF,0x7FFF) / func_8012A828(arg0,&D_801F0008)
|
||
* / func_8012B2CC(arg0) / func_8012E8A8(arg0) / func_8012C588 x3 (0x34C,0x351,
|
||
* 0x3AB) / func_8012C658(0x34C,2,arg0) / rand / func_8001C97C(&D_801F436C)
|
||
* / func_801A2E20. &D_801A6854 -> 0x58, &D_801A68A8 -> 0x80 of *(arg0+0x20),
|
||
* D_801F4360 <- rand()&0x7FFF, D_801F1344/D_801F1A5C <- (s16)2,
|
||
* D_801AE21C -> D_801F436C, D_801AE228 -> D_801F43B4, D_801AE21C[0] ->
|
||
* D_801F43B8, 0 -> D_801F43BC/D_801F4358, 3 -> D_801F43C0.
|
||
*
|
||
* BANK NOTE (law 2): src/md_SC07_003/md_SC07_003.c declares NONE of these
|
||
* symbols (checked name by name) and has no prototype for func_801A026C, so
|
||
* every declaration below is free-standing and nothing had to be adopted.
|
||
* Spellings follow the card's decl_prior: modal fleet forms for func_8012CAE4
|
||
* (void*), func_8012A828 (s32,void*), func_8012E8A8 (u8*), func_8012C354 /
|
||
* func_8012C588 (s32,s32), func_8012C658 (s32,s32,s32), func_8012B2CC (s32);
|
||
* banked-DEFINITION forms for func_80029504 (s32(void)), func_8001D0E8
|
||
* (void(s32,s32,s32)) and func_8001C97C (void(s32*) - the def wins over the
|
||
* x41 fleet `s32` spelling). Data externs are in their rawest form (law 4);
|
||
* the only aggregate is the stride-8 record the two s16 fill loops walk.
|
||
*/
|
||
|
||
#include "common.h"
|
||
|
||
/* ---- callees (fleet-modal / banked-definition spellings; the destination TU
|
||
src/md_SC07_003/md_SC07_003.c declares none of these) ---- */
|
||
extern s32 rand(void);
|
||
extern s32 func_80029504(void);
|
||
extern void func_8012CAE4(void *);
|
||
extern s32 func_8012C354(s32, s32);
|
||
extern void func_8001D0E8(s32, s32, s32);
|
||
extern void func_8012A828(s32, void *);
|
||
extern void func_8012B2CC(s32);
|
||
extern void func_8012E8A8(u8 *);
|
||
extern s32 func_8012C588(s32, s32);
|
||
extern s32 func_8012C658(s32, s32, s32);
|
||
extern void func_8001C97C(s32 *);
|
||
extern void func_801A2E20(void);
|
||
|
||
/* ---- data ---- */
|
||
extern u8 D_801A6874[]; /* passed by address to func_8012C354 */
|
||
extern u8 D_801A6854[]; /* address OR'd with 0x50000000 into arg0+0x58 */
|
||
extern u8 D_801F0008[];
|
||
extern u8 D_801A68A8[];
|
||
|
||
extern s32 D_801F4360[]; /* 3 x s32, rand()&0x7FFF */
|
||
extern s32 D_801AE21C[]; /* s32 source table */
|
||
extern s32 D_801AE228[]; /* == &D_801AE21C[3] but its own symbol */
|
||
extern s32 D_801F436C[]; /* s32 destination table */
|
||
|
||
/* stride-8 records; only the s16 at +0 is touched here */
|
||
|
||
extern Rec8_801A026C D_801F1344[];
|
||
extern Rec8_801A026C D_801F1A5C[];
|
||
|
||
extern s32 D_801F4358;
|
||
extern s32 D_801F43B4;
|
||
extern s32 D_801F43B8;
|
||
extern s32 D_801F43BC;
|
||
extern u16 D_801F43C0;
|
||
|
||
void func_801A026C(s32 arg0)
|
||
{
|
||
s32 i;
|
||
s32 j;
|
||
s32 k;
|
||
|
||
if ((u32)func_80029504() >= 0x640) {
|
||
func_8012CAE4((void *)arg0);
|
||
return;
|
||
}
|
||
|
||
if (func_8012C354(arg0, (s32)D_801A6874) == 0) {
|
||
return;
|
||
}
|
||
|
||
func_8001D0E8(*(s32 *)(arg0 + 0x20), 0x7FFF, 0x7FFF);
|
||
|
||
*(s32 *)(arg0 + 0x58) = (s32)((u32)D_801A6854 | 0x10000000 | 0x40000000);
|
||
func_8012A828(arg0, (void *)D_801F0008);
|
||
|
||
*(s16 *)(arg0 + 0x02) = 1;
|
||
*(s32 *)(arg0 + 0x48) = 0x30000;
|
||
*(s32 *)(arg0 + 0x08) += 0xFD8A0000;
|
||
func_8012B2CC(arg0);
|
||
func_8012E8A8((u8 *)arg0);
|
||
|
||
*(s16 *)(arg0 + 0xAE) = -1;
|
||
*(s8 *)(arg0 + 0x75) = 2;
|
||
*(s16 *)(arg0 + 0x76) = *(u16 *)(*(s32 *)(arg0 + 0x78));
|
||
*(s32 *)(arg0 + 0xE4) = 0x50;
|
||
*(u16 *)(*(s32 *)(arg0 + 0x20) + 0x2C) |= 0x80;
|
||
*(s32 *)(*(s32 *)(arg0 + 0x20) + 0x80) = (s32)D_801A68A8;
|
||
|
||
*(s32 *)(arg0 + 0xCC) = func_8012C588(0x34C, arg0);
|
||
*(s32 *)(arg0 + 0xD0) = func_8012C588(0x351, arg0);
|
||
*(s32 *)(arg0 + 0xD4) = func_8012C658(0x34C, 2, arg0);
|
||
*(s32 *)(arg0 + 0xD8) = func_8012C588(0x3AB, arg0);
|
||
|
||
for (i = 0; i < 3; i++) {
|
||
D_801F4360[i] = rand() & 0x7FFF;
|
||
}
|
||
|
||
for (i = 62; i < 113; i++) {
|
||
D_801F1344[i].a = 2;
|
||
}
|
||
|
||
for (i = 52; i < 140; i++) {
|
||
D_801F1A5C[i].a = 2;
|
||
}
|
||
|
||
i = 0;
|
||
k = 0;
|
||
j = 0;
|
||
for (; i < 20; i++) {
|
||
if ((i != 0) && (i != 3)) {
|
||
*(s32 *)((u8 *)D_801F436C + j) = *(s32 *)((u8 *)D_801AE21C + k);
|
||
j += 4;
|
||
}
|
||
k += 4;
|
||
}
|
||
|
||
func_8001C97C(D_801F436C);
|
||
|
||
D_801F43BC = 0;
|
||
D_801F4358 = 0;
|
||
D_801F43C0 = 3;
|
||
D_801F43B4 = D_801AE228[0];
|
||
D_801F43B8 = D_801AE21C[0];
|
||
|
||
func_801A2E20();
|
||
}
|
||
|
||
|
||
extern s32 func_8016F1AC(void);
|
||
extern s32 func_80178B18(s32 a0, s32 a1);
|
||
|
||
extern s16 D_801A698C;
|
||
|
||
void func_801A04D4(s32 arg0) {
|
||
s32 s0 = arg0;
|
||
|
||
if (func_8016F1AC() == 0) {
|
||
func_80178B18((s32)s0, (s32)&D_801A698C);
|
||
*(s16 *)(s0 + 2) = 2;
|
||
*(s16 *)(s0 + 0x34) = 0;
|
||
*(s32 *)(s0 + 0x1C) = 0;
|
||
}
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
extern s32 func_801789AC(); // K&R: 0 of 1 args (P37 rung D t4_D58)
|
||
extern void func_80178D18();
|
||
extern void func_8017BF08(void *, void *, s32, s32);
|
||
extern void func_8012C218(void *);
|
||
extern s32 func_8012C194(void);
|
||
extern void func_800233CC(void *, u16);
|
||
extern void func_8001CD9C(s32, void *);
|
||
extern void func_8012A568(void *);
|
||
extern void func_8017F004(void);
|
||
|
||
extern s32 D_801F4358;
|
||
extern s32 D_801F4318;
|
||
extern s32 D_801F431C;
|
||
extern s32 D_801F4320;
|
||
extern s32 D_801F4324;
|
||
|
||
void func_801A0524(s32 a0) {
|
||
s32 s0;
|
||
s32 *p;
|
||
|
||
s0 = a0;
|
||
if (func_801789AC() == 1) {
|
||
func_80178D18(s0);
|
||
func_8017BF08((void *)(s0 + 0x76), (void *)*(s32 *)(s0 + 0x78), 0xA, 0x120);
|
||
*(s16 *)(s0 + 2) = 3;
|
||
func_8012C218(*(void **)(s0 + 0xD8));
|
||
*(s32 *)(s0 + 0xD8) = 0;
|
||
D_801F4358 = func_8012C194();
|
||
if (D_801F4358 != 0) {
|
||
p = &D_801F4318;
|
||
*p = 0;
|
||
D_801F431C = 0;
|
||
D_801F4320 = 0;
|
||
D_801F4324 = 0;
|
||
func_800233CC(p, 0x60);
|
||
func_8001CD9C(D_801F4358, p);
|
||
*(u16 *)(D_801F4358 + 0x2C) = 0xC010;
|
||
*(s32 *)(D_801F4358 + 4) |= 0x50000000;
|
||
}
|
||
func_8012A568(func_8017F004);
|
||
}
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
extern void func_8012A828(s32 a0, void *a1);
|
||
extern u8 D_801F0008[];
|
||
|
||
void func_801A060C(s32 arg0) {
|
||
*(s16 *)(arg0 + 0x02) = 4;
|
||
*(s32 *)(arg0 + 0x1C) = 0x40;
|
||
*(s32 *)(arg0 + 0xE4) = 0x50;
|
||
func_8012A828(arg0, D_801F0008);
|
||
}
|
||
|
||
|
||
extern s32 func_8012BEE8(s32 a0);
|
||
extern void func_8012BD14(s32);
|
||
|
||
void func_801A0648(s32 arg0) {
|
||
if (func_8012BEE8(arg0) != 0) {
|
||
*(s16 *)(arg0 + 2) = 7;
|
||
}
|
||
if (*(s32 *)(arg0 + 0x1C) < 0x20) {
|
||
if (((s32 (*)(s32))func_8012BD14)(arg0) <= 0x10000) {
|
||
*(s16 *)(arg0 + 2) = 0xF;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
extern void func_8012A828(s32 a0, void *a1);
|
||
extern u8 D_801F0008[];
|
||
|
||
void func_801A06AC(s32 arg0) {
|
||
*(s16 *)(arg0 + 0x02) = 6;
|
||
*(s32 *)(arg0 + 0x1C) = 0x14;
|
||
*(s32 *)(arg0 + 0xE4) = 0x50;
|
||
func_8012A828(arg0, D_801F0008);
|
||
}
|
||
|
||
|
||
extern s32 func_8012BEE8(s32 a0);
|
||
|
||
void func_801A06E8(s32 arg0) {
|
||
if (func_8012BEE8(arg0) != 0) {
|
||
*(s16 *)(arg0 + 2) = 7;
|
||
*(s32 *)(arg0 + 0xE0) &= ~0x40;
|
||
}
|
||
}
|
||
|
||
|
||
extern void func_8012A828(s32 a0, void *a1);
|
||
extern s32 func_8012C588(s32, s32);
|
||
extern s32 D_801F1FD8;
|
||
extern u16 D_801F43C0;
|
||
extern s32 D_801F436C[];
|
||
|
||
void func_801A072C(s32 arg0) {
|
||
*(s16 *)(arg0 + 0x2) = 8;
|
||
*(s32 *)(arg0 + 0x1C) = 0x80;
|
||
*(s32 *)(arg0 + 0xE4) = 0x50;
|
||
*(s32 *)(*(s32 *)(arg0 + 0x20) + 0x24) = (s32)D_801F436C;
|
||
func_8012A828(arg0, &D_801F1FD8);
|
||
D_801F43C0 = 0x11;
|
||
func_8012C588(0x3D0, arg0);
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
/*
|
||
* func_801A079C (md_SC07_003, 0x801A079C, 105 ins) == MATCH, byte-exact.
|
||
*
|
||
* SC07 actor tick: nudge the sprite's 0x12 field, kick the two 0x94-state
|
||
* cutscene hooks (0xF / 0x35), run the per-frame update, then pick the next
|
||
* state (offset 0x2) from the 0xE8 counter and the func_8012BD14 distance.
|
||
*
|
||
* LEVERS (each verified by flipping it back and re-scoring with match_one):
|
||
*
|
||
* 1. THE `0xF` STORE FOR `s1 <= 0x10000` IS AN **EARLY BLOCK**, NOT A TRAILING
|
||
* `else`. Written as `if (s1 > 0x10000) { ...body... } else { store 0xF; }`
|
||
* the else-block lands LAST, so it is the block that falls into the
|
||
* epilogue. gcc's cross_jump then merges every other `sh $v0,0x2($s0)`
|
||
* into it (cookbook §5a/§193-C: the SURVIVING copy is the later one, and
|
||
* `find_cross_jump` pairs a jump's block with `prev_real_insn(JUMP_LABEL)`
|
||
* — i.e. whatever falls through into the epilogue). Result: 100 ins, four
|
||
* stores lost, LENGTH-DRIFT −5 at closeness 56.
|
||
* With the early-return form the block that falls into the epilogue is
|
||
* `sw $v0,0x1C($s0)` instead, which matches NO `sh` block, so all five
|
||
* `sh $v0,0x2($s0)` survive — exactly the target. This one edit took the
|
||
* draft from 100/56 to 105/8. No §34 asm barrier is needed: choosing the
|
||
* fall-through block IS the barrier here.
|
||
*
|
||
* 2. BRANCH-SENSE / ARM ORDER is read off the target's `slt`+`beqz`/`bnez`
|
||
* pairs (§3-T4): `if (s1 <= 0x24000) {BDBC arm} else {0xC4000 arm}` and
|
||
* `if (s1 <= 0x64000) {store 0xF} else {store 0x80}`. Writing either the
|
||
* other way round emits the complementary branch and swaps the two blocks.
|
||
*
|
||
* 3. `unused[2]` IS LOAD-BEARING — DO NOT DELETE. The target's frame is 0x28
|
||
* with $s0/$s1/$ra at 0x18/0x1C/0x20; without an 8-byte aggregate local the
|
||
* frame is 0x20 (regs at 0x10/0x14/0x18) and eight instructions carry the
|
||
* wrong immediates. gcc-2.7.2 gives an aggregate a stack slot at expand
|
||
* time and never reclaims it, so an unreferenced 8-byte local costs zero
|
||
* instructions and buys the frame. (s16[4] and a 2xs32 struct match too —
|
||
* only the SIZE matters.)
|
||
*
|
||
* 4. `*(u16 *)(*(s32 *)(arg0 + 0x20) + 0x12) += func_8012BA10(arg0, 0x20);`
|
||
* is the TU's own house form (func_801A61C4) — the call is emitted first,
|
||
* then the pointer is reloaded, then `sh` rides the next jal's delay slot.
|
||
*
|
||
* 5. func_8012BD14 and func_8012CBA4 are declared `void` (the TU's canonical
|
||
* spelling, reconciled in S54) and their return values are read through the
|
||
* TU's `((s32 (*)(s32))f)(x)` fn-ptr cast — byte-neutral, see the note above
|
||
* func_801A1E30.
|
||
*
|
||
* SYMBOL AUDIT (law 1c, done after MATCH — match_one masks jal/HI16/LO16).
|
||
* Every name re-checked against the relocation lines of
|
||
* asm/md_SC07_003/nonmatchings/md_SC07_003/func_801A079C.s; the .s's symbol set
|
||
* and this draft's are identical (12 calls + 3 data):
|
||
* func_8012BA10(arg0,0x20) / func_8012B178(arg0,0xFFFB0000) /
|
||
* func_801A2658(arg0,&D_801A68BC) [state 0xF] and (arg0,&D_801A68C4) [0x35] /
|
||
* func_8013C9C4(D_80186F68) / func_8002D4C8(0xB53,0) / func_8012CBA4(arg0) /
|
||
* func_8012ADE4(arg0) / func_801A24E8(arg0) / rand /
|
||
* func_8012BD14(arg0) / func_8012BDBC(arg0,0x180) / func_8012BEE8(arg0).
|
||
* D_801A68C4 is its OWN relocation in this .s (it is &D_801A68BC[8], which
|
||
* func_801A23FC spells as `D_801A68BC + 8`) — law 1 says spell it as the .s
|
||
* does, so it gets its own extern here.
|
||
*
|
||
* BANK NOTE (law 2): src/md_SC07_003/md_SC07_003.c already declares eleven of
|
||
* these; every spelling below is copied verbatim from that file (rand:93,
|
||
* func_8012BEE8:282, func_8012BD14:410, func_8012BA10:412, func_8002D4C8:366,
|
||
* func_8012B178:1001, func_8012CBA4:1029, func_8012ADE4:1028, func_801A24E8:1032,
|
||
* func_8013C9C4:1340, func_801A2658:1341, D_801A68BC:1345, func_8012BDBC:4025).
|
||
* D_80186F68 and D_801A68C4 are absent from the TU, so they are free-standing;
|
||
* D_80186F68 follows the TU's own precedent for a func_8013C9C4 argument
|
||
* (`extern u16 D_80186F44[]` at line 1344) rather than the fleet's
|
||
* function-pointer-array spelling, which lives in other TUs only.
|
||
*/
|
||
|
||
extern s32 rand(void);
|
||
extern s32 func_8012BA10(s32 a0, s32 a1);
|
||
extern void func_8012B178(s32 a0, s32 a1);
|
||
extern void func_801A2658(s32 a0, s32 a1);
|
||
extern void func_8013C9C4(void *a0);
|
||
extern void func_8002D4C8(s32 a0, s32 a1);
|
||
extern void func_8012CBA4(s32 a0); /* canonical void; return read via fn-ptr cast */
|
||
extern void func_8012ADE4(u8 *a0);
|
||
extern void func_801A24E8(s32 a0);
|
||
extern void func_8012BD14(s32 a0); /* canonical void; return read via fn-ptr cast */
|
||
extern s32 func_8012BDBC(s32 a0, s32 a1);
|
||
extern s32 func_8012BEE8(s32 a0);
|
||
|
||
extern u8 D_80186F68[];
|
||
extern u8 D_801A68BC[];
|
||
extern u8 D_801A68C4[];
|
||
|
||
void func_801A079C(s32 arg0) {
|
||
s32 s1;
|
||
s32 unused[2]; /* LOAD-BEARING: buys the target's 0x28 frame (lever 3) */
|
||
s32 v1;
|
||
|
||
*(u16 *)(*(s32 *)(arg0 + 0x20) + 0x12) += func_8012BA10(arg0, 0x20);
|
||
func_8012B178(arg0, 0xFFFB0000);
|
||
|
||
v1 = *(s32 *)(arg0 + 0x94);
|
||
if (v1 == 0xF) {
|
||
func_801A2658(arg0, (s32)D_801A68BC);
|
||
func_8013C9C4(D_80186F68);
|
||
func_8002D4C8(0xB53, 0);
|
||
} else if (v1 == 0x35) {
|
||
func_801A2658(arg0, (s32)D_801A68C4);
|
||
func_8013C9C4(D_80186F68);
|
||
func_8002D4C8(0xB53, 0);
|
||
}
|
||
|
||
if ((((s32 (*)(s32))func_8012CBA4)(arg0) & 0x2000) == 0) {
|
||
func_8012ADE4((u8 *)arg0);
|
||
}
|
||
func_801A24E8(arg0);
|
||
|
||
if (*(s32 *)(arg0 + 0xE8) > 0xFFFF) {
|
||
if (rand() & 1) {
|
||
*(s16 *)(arg0 + 2) = 0xD;
|
||
} else {
|
||
*(s16 *)(arg0 + 2) = 0xB;
|
||
}
|
||
return;
|
||
}
|
||
|
||
s1 = ((s32 (*)(s32))func_8012BD14)(arg0);
|
||
if (s1 <= 0x10000) {
|
||
*(s16 *)(arg0 + 2) = 0xF;
|
||
return;
|
||
}
|
||
if (s1 <= 0x24000) {
|
||
if (func_8012BDBC(arg0, 0x180) != 0) {
|
||
*(s16 *)(arg0 + 2) = 0x11;
|
||
return;
|
||
}
|
||
} else if (s1 > 0xC4000 && *(s32 *)(arg0 + 0x94) == 0x4E) {
|
||
*(s16 *)(arg0 + 2) = 9;
|
||
return;
|
||
}
|
||
if (func_8012BEE8(arg0) != 0) {
|
||
if (s1 <= 0x64000) {
|
||
*(s16 *)(arg0 + 2) = 0xF;
|
||
} else {
|
||
*(s32 *)(arg0 + 0x1C) = 0x80;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
extern void func_801A28AC(s32 arg0);
|
||
extern void func_8012A828(s32 a0, void *a1);
|
||
extern s32 rand(void);
|
||
extern u16 D_801F1EC0[];
|
||
|
||
void func_801A0940(void *a0) {
|
||
s32 d;
|
||
|
||
func_801A28AC((s32)a0);
|
||
*(s16 *)((s32)a0 + 0x2) = 0xA;
|
||
*(s32 *)((s32)a0 + 0xE4) = 0x50;
|
||
*(u16 *)((s32)a0 + 0x34) = 0;
|
||
func_8012A828((s32)a0, D_801F1EC0);
|
||
d = rand();
|
||
*(s32 *)((s32)a0 + 0x1C) = d % 64 + 0x40;
|
||
*(s32 *)((s32)a0 + 0xE0) &= ~8;
|
||
}
|
||
|
||
|
||
INCLUDE_RODATA("asm/md_SC07_003/nonmatchings/md_SC07_003", D_801A00D8);
|
||
|
||
extern s32 func_8012BA10(s32 a0, s32 a1);
|
||
extern void func_8012B178(s32 a0, s32 a1);
|
||
extern void func_8012CBA4(s32 a0); /* canonical void; return read via fn-ptr cast */
|
||
extern void func_8012ADE4(u8 *a0);
|
||
extern void func_801A2658(s32 a0, s32 a1);
|
||
extern void func_8013C9C4(void *a0);
|
||
extern void func_8002D4C8(s32 a0, s32 a1);
|
||
extern s32 func_8012BEE8(s32 a0);
|
||
extern void func_8012BE54(s32 a0); /* canonical void; return read via fn-ptr cast */
|
||
extern s32 func_8012BDBC(s32 a0, s32 a1);
|
||
extern void func_8012A828(s32 a0, void *a1);
|
||
extern void func_801A27A4(void *a0, void *a1);
|
||
extern s32 func_801A19C8(s32 a0);
|
||
extern s32 func_80153BD8(s32 a0);
|
||
extern void func_801A1924(s32 a0);
|
||
extern void func_80153C44(s32 a0, s32 a1, s16 a2);
|
||
extern void func_801A24E8(s32 a0);
|
||
extern u8 D_801A68BC[];
|
||
extern u8 D_801A68C4[];
|
||
extern u8 D_80186F68[];
|
||
extern u8 D_801F1198[];
|
||
extern u8 D_801F1340[];
|
||
extern u8 D_801F1238[];
|
||
extern u16 D_800B99DA;
|
||
|
||
void func_801A09C8(s32 arg0) {
|
||
s32 pad[10];
|
||
s32 t;
|
||
s32 q;
|
||
|
||
switch (*(u16 *)(arg0 + 0x34)) {
|
||
case 0:
|
||
t = func_8012BA10(arg0, 0x10);
|
||
*(u16 *)(*(s32 *)(arg0 + 0x20) + 0x12) += t;
|
||
func_8012B178(arg0, -0xF0000);
|
||
if ((((s32 (*)(s32))func_8012CBA4)(arg0) & 0x2000) == 0) {
|
||
func_8012ADE4((u8 *)arg0);
|
||
}
|
||
q = *(s32 *)(arg0 + 0x94);
|
||
if (q == 9) {
|
||
func_801A2658(arg0, (s32)D_801A68BC);
|
||
func_8013C9C4(D_80186F68);
|
||
func_8002D4C8(0xB53, 0);
|
||
} else if (q == 0x1A) {
|
||
func_801A2658(arg0, (s32)D_801A68C4);
|
||
func_8013C9C4(D_80186F68);
|
||
func_8002D4C8(0xB53, 0);
|
||
}
|
||
if (func_8012BEE8(arg0) == 0) {
|
||
if (((s32 (*)(s32))func_8012BE54)(arg0) > 0x40000) {
|
||
break;
|
||
}
|
||
}
|
||
if (func_8012BDBC(arg0, 0x200) == 0) {
|
||
break;
|
||
}
|
||
*(u16 *)(arg0 + 0x34) = *(u16 *)(arg0 + 0x34) + 1;
|
||
func_8012A828(arg0, D_801F1198);
|
||
*(s32 *)(arg0 + 0x1C) = 0x30;
|
||
*(s32 *)(arg0 + 0x10) = *(s32 *)(arg0 + 0x10) * 2;
|
||
*(s32 *)(arg0 + 0x18) = *(s32 *)(arg0 + 0x18) * 2;
|
||
func_8002D4C8(0xB79, 0);
|
||
break;
|
||
|
||
case 1:
|
||
*(s32 *)(arg0 + 0x10) = *(s32 *)(arg0 + 0x10) * 15 / 16;
|
||
*(s32 *)(arg0 + 0x18) = *(s32 *)(arg0 + 0x18) * 15 / 16;
|
||
if (D_800B99DA % 3 == 0) {
|
||
func_801A27A4((void *)arg0, D_801A68BC);
|
||
func_801A27A4((void *)arg0, D_801A68BC + 8);
|
||
}
|
||
if ((((s32 (*)(s32))func_8012CBA4)(arg0) & 0x2000) == 0) {
|
||
func_8012ADE4((u8 *)arg0);
|
||
}
|
||
if (func_801A19C8(arg0) == 1) {
|
||
*(u16 *)(arg0 + 0x34) = *(u16 *)(arg0 + 0x34) + 1;
|
||
*(s32 *)(arg0 + 0xE0) |= 0x40;
|
||
break;
|
||
}
|
||
if (func_8012BEE8(arg0) == 0) {
|
||
break;
|
||
}
|
||
goto state5;
|
||
|
||
case 2:
|
||
if (func_80153BD8(arg0) != 0) {
|
||
*(s32 *)(arg0 + 0xE0) |= 8;
|
||
*(u16 *)(arg0 + 0x5C) &= ~0x800;
|
||
} else {
|
||
*(s32 *)(arg0 + 0xE0) &= ~0x40;
|
||
}
|
||
*(u16 *)(arg0 + 0x34) = *(u16 *)(arg0 + 0x34) + 1;
|
||
/* fallthrough */
|
||
case 3:
|
||
if (*(s32 *)(arg0 + 0xE0) & 8) {
|
||
func_801A1924(arg0);
|
||
}
|
||
if (*(s16 *)(arg0 + 0x98) != 0) {
|
||
break;
|
||
}
|
||
if (*(s32 *)(arg0 + 0xE0) & 8) {
|
||
func_8012A828(arg0, D_801F1340);
|
||
*(u16 *)(arg0 + 0x34) = 4;
|
||
break;
|
||
}
|
||
state5:
|
||
func_8012A828(arg0, D_801F1238);
|
||
*(u16 *)(arg0 + 0x34) = 5;
|
||
break;
|
||
|
||
case 4:
|
||
if (*(s32 *)(arg0 + 0x94) < 0x86) {
|
||
func_801A1924(arg0);
|
||
}
|
||
q = *(s32 *)(arg0 + 0x94);
|
||
if (q == 0x3E) {
|
||
func_8002D4C8(0xC18, 0);
|
||
q = *(s32 *)(arg0 + 0x94);
|
||
}
|
||
if (q == 0x86) {
|
||
func_80153C44(1, 0x50, *(s16 *)(*(s32 *)(arg0 + 0x20) + 0x12));
|
||
func_8002D4C8(0xC17, 0);
|
||
func_8002D4C8(0xC7B, 0);
|
||
}
|
||
/* fallthrough */
|
||
case 5:
|
||
if (*(s16 *)(arg0 + 0x98) == 0) {
|
||
*(s16 *)(arg0 + 2) = 3;
|
||
*(u16 *)(arg0 + 0x5C) |= 0x800;
|
||
*(s32 *)(arg0 + 0xE0) &= ~0x40;
|
||
}
|
||
break;
|
||
}
|
||
|
||
func_801A24E8(arg0);
|
||
}
|
||
|
||
|
||
extern void func_801A28AC(s32 arg0);
|
||
extern void func_8012A828(s32 a0, void *a1);
|
||
extern void func_80184C70(void);
|
||
extern void func_80184DB0(s32 a0, void *a1, s32 a2);
|
||
extern void func_8002D4C8(s32 a0, s32 a1);
|
||
extern u8 D_801A6544[];
|
||
extern s32 D_801A6B90;
|
||
|
||
void func_801A0DA4(void *a0) {
|
||
func_801A28AC((s32)a0);
|
||
*(s16 *)((s32)a0 + 2) = 0xC;
|
||
*(u16 *)((s32)a0 + 0x34) = 0;
|
||
*(s32 *)((s32)a0 + 0xE4) = 0x50;
|
||
func_8012A828((s32)a0, D_801A6544);
|
||
func_80184C70();
|
||
func_80184DB0(0, &D_801A6B90, -8);
|
||
*(s32 *)((s32)a0 + 0xE0) &= ~0x4;
|
||
func_8002D4C8(0xC35, 0);
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
/* 8-byte, 2-byte-aligned vector triple (the lwl/lwr/swl/swr block move at the tail
|
||
proves alignment 2 and size 8). Fields are u16 because every read site uses `lhu`;
|
||
the two negative literals are written through an s16 alias so the constant stays
|
||
signed (`addiu $v0,$zero,-0x180`) instead of becoming `ori 0xFE80`. */
|
||
|
||
extern u16 D_801F43C0;
|
||
extern u8 D_801A68D4[];
|
||
extern u16 D_80126B5E;
|
||
extern u16 D_80126B62;
|
||
extern u16 D_80126B66;
|
||
extern u16 D_801F4310[];
|
||
extern u16 D_801F4312;
|
||
extern u16 D_801F4314;
|
||
|
||
extern s32 rand(void);
|
||
extern void func_8002D4C8(s32 a0, s32 a1);
|
||
extern void func_8012F14C(s32 a0, s32 a1, s32 a2);
|
||
extern void func_8012F214(s32 a0, s32 a1, s32 a2);
|
||
extern s32 func_8012C51C(void *a0, s32 a1);
|
||
extern void func_8012BD14(s32 a0);
|
||
extern void func_8012EC04(s32 a0, s32 a1, s32 *a2);
|
||
extern s32 func_8012BA10(s32 a0, s32 a1);
|
||
extern void func_80184E20(void *a0);
|
||
extern void func_80184E98();
|
||
extern void func_8018503C(void);
|
||
extern s32 func_801A3054(s32 a0, s32 a1, s32 a2);
|
||
|
||
void func_801A0E28(s32 a0) {
|
||
s32 s1 = a0;
|
||
s32 sp10[8]; /* 0x10: 32-byte matrix */
|
||
Vec8_801A0E28 sp30; /* 0x30 */
|
||
u16 sp38[8]; /* 0x38: 16 bytes, fields at +2/+6/+10 */
|
||
struct {
|
||
u16 f0; /* 0x48 */
|
||
u16 f2;
|
||
u16 f4;
|
||
u16 f6;
|
||
u16 f8;
|
||
u16 fA;
|
||
u16 fC;
|
||
u16 fE;
|
||
s32 f10; /* 0x58 */
|
||
} sp48; /* 20 bytes -> 24 of frame (S54 law 24) */
|
||
s32 st;
|
||
|
||
if (*(s32 *)(s1 + 0x94) < 0x23) {
|
||
s32 r = func_8012BA10(s1, 8);
|
||
s32 p = *(s32 *)(s1 + 0x20);
|
||
s32 k = D_801F43C0;
|
||
|
||
*(s16 *)(p + 0x12) = *(u16 *)(p + 0x12) + r;
|
||
func_8012EC04(s1, k, sp10);
|
||
func_8012F14C((s32)sp10, (s32)D_801A68D4, (s32)&sp30);
|
||
sp38[1] = sp30.a;
|
||
sp38[3] = sp30.b;
|
||
sp38[5] = sp30.c;
|
||
func_80184E20(sp38);
|
||
if ((*(s32 *)(s1 + 0x94) & 1) == 0) {
|
||
func_80184E98(rand() & 0xFF0, 0x40);
|
||
}
|
||
func_8018503C();
|
||
}
|
||
|
||
st = *(s32 *)(s1 + 0x94);
|
||
if (st == 0x23) {
|
||
if (((s32 (*)(s32))func_8012BD14)(s1) > 0x23FFF) {
|
||
sp30.a = sp30.b = 0;
|
||
*(s16 *)&sp30.c = -0x180;
|
||
func_8012F214(s1, (s32)&sp30, (s32)&sp30);
|
||
if (func_801A3054(s1, (s32)&sp30, 0x200) != 0) {
|
||
D_801F4310[0] = D_80126B5E;
|
||
D_801F4312 = D_80126B62;
|
||
D_801F4314 = D_80126B66;
|
||
} else {
|
||
/* S54 law 22 (S193-C): the shared tail is written in BOTH arms so
|
||
cross_jump merges the scheduled common suffix, leaving each arm's
|
||
own `$a1` setup ($s0 copy vs a fresh addiu) above the merge point. */
|
||
sp30.a = sp30.b = 0;
|
||
*(s16 *)&sp30.c = -0x200;
|
||
func_8012F214(s1, (s32)&sp30, (s32)&sp30);
|
||
*(Vec8_801A0E28 *)D_801F4310 = sp30;
|
||
}
|
||
} else {
|
||
sp30.a = sp30.b = 0;
|
||
*(s16 *)&sp30.c = -0x200;
|
||
func_8012F214(s1, (s32)&sp30, (s32)&sp30);
|
||
*(Vec8_801A0E28 *)D_801F4310 = sp30;
|
||
}
|
||
st = *(s32 *)(s1 + 0x94);
|
||
}
|
||
|
||
if (st == 0x2F || st == 0x40 || st == 0x51) {
|
||
func_8012EC04(s1, D_801F43C0, sp10);
|
||
func_8012F14C((s32)sp10, (s32)D_801A68D4, (s32)&sp30);
|
||
sp48.f0 = sp30.a;
|
||
sp48.f2 = sp30.b;
|
||
sp48.f4 = sp30.c;
|
||
sp48.f6 = 0x378;
|
||
sp48.f8 = sp48.fA = 0;
|
||
sp48.fE = sp48.f10 = 0;
|
||
sp48.fC = 0x7FFF;
|
||
func_8012C51C(&sp48, s1);
|
||
sp48.f8 = 0x8000;
|
||
func_8012C51C(&sp48, s1);
|
||
*(s32 *)(s1 + 0xE0) |= 4;
|
||
func_8002D4C8(0xB54, 0);
|
||
}
|
||
|
||
if (*(s16 *)(s1 + 0x98) == 0) {
|
||
*(s16 *)(s1 + 2) = 0x13;
|
||
}
|
||
}
|
||
|
||
|
||
extern void func_801A28AC(s32 arg0);
|
||
extern void func_8012A828(s32 a0, void *a1);
|
||
extern void func_8012B23C(s32 a0);
|
||
extern void func_8017F184(void);
|
||
extern s32 func_8012C658(s32 a0, s32 a1, s32 a2);
|
||
extern u8 D_801F0478[];
|
||
|
||
void func_801A10B0(void *a0) {
|
||
func_801A28AC((s32)a0);
|
||
*(s16 *)((s32)a0 + 0x2) = 0xE;
|
||
*(u16 *)((s32)a0 + 0x34) = 0;
|
||
*(s32 *)((s32)a0 + 0xE4) = 0x50;
|
||
func_8012A828((s32)a0, D_801F0478);
|
||
func_8012B23C((s32)a0);
|
||
*(s32 *)((s32)a0 + 0x14) = 0xFFE00000;
|
||
func_8017F184();
|
||
func_8012C658(0x34C, 4, (s32)a0);
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
/*
|
||
* func_801A1120 (md_SC07_003, 0x801A1120, 160 ins) == MATCH, byte-exact.
|
||
*
|
||
* SC07 cutscene actor state machine, switch on the u16 at 0x34 (5 cases +
|
||
* jtbl_801A00F4). Case 2 FALLS THROUGH into case 3, and case 3's tail (the
|
||
* two func_8012F14C projections + the func_80135888 / func_8012F568 draw) is
|
||
* part of case 3 — NOT case 4. The previous attempt put that tail in case 4
|
||
* and split case 3, which is the whole of its 105-instruction residual.
|
||
*
|
||
* LEVERS (each verified by flipping it back and re-scoring with match_one):
|
||
*
|
||
* 1. CASE 0 AND CASE 1 SHARE THE `*(u16 *)(arg0+0x34) += 1` TAIL. Writing
|
||
* both as a plain `+= 1` lets gcc-2.7.2's cross_jump merge the scheduled
|
||
* common SUFFIX (`addiu $v0,$v0,1 / j / sh $v0,0x34($s1)`) into the single
|
||
* copy at .L801A11EC, which is why case 0 ends `lhu $v0,0x34 / j .L801A11EC
|
||
* / sh $zero,0x98` — the `sh $zero` rides the j's delay slot (§193-C:
|
||
* suffix-only merge, the surviving copy is the later block).
|
||
*
|
||
* 2. `d = D_800D3918;` AND `tbl = D_80126B78;` MUST BE EXPLICIT LOCALS.
|
||
* Spelling either symbol raw at its two use sites costs the target's whole
|
||
* saved-register set: cse is extended-basic-block-local, so the second
|
||
* `D_800D3918` (inside the func_80135888 arm) gets its own %hi/%lo and the
|
||
* address never becomes a call-crossing pseudo. Result: only $s0/$s1/$s2
|
||
* are saved, frame 0x38 instead of 0x40, LENGTH-DRIFT −2 at closeness 158.
|
||
* With both locals present the four call-crossing pseudos land exactly as
|
||
* the target allocates them — $s0 = &D_80126B78 then D_801152A8 (disjoint
|
||
* live ranges reuse the reg), $s1 = arg0, $s2 = &out, $s3 = D_800D3918
|
||
* (longest live range ⇒ lowest global.c priority ⇒ allocated last).
|
||
* `tbl` also converts the two rematerialised `lui/lw` pairs into one
|
||
* `lui/addiu` + two `lw 0($s0)` — count-neutral, register-decisive.
|
||
*
|
||
* 3. `tbl[0] + 0x34` (array-index read of the TU-canon `extern s32
|
||
* D_80126B78[]`) is what emits `lw $a0,0($s0) / addiu $a0,$a0,0x34` in the
|
||
* jal delay slot. The TU's other user (func_801A419C) needs the §37
|
||
* asm-label alias `aD_80126B78` instead because it has no local; here the
|
||
* local supplies the pointer, so the canon array spelling is correct.
|
||
*
|
||
* 4. func_8012CBCC and func_8012A8E8 are called through the TU's house
|
||
* fn-ptr cast (`((s32 (*)(s32))f)(x)`), because the TU canon / fleet canon
|
||
* spell them `void func_8012CBCC(s32)` and `void func_8012A8E8(void)`.
|
||
* Byte-neutral: gcc-2.7.2 folds the constant address back to a `jal`.
|
||
* func_8012A8E8 DOES take arg0 here — the target's `jal func_8012A8E8`
|
||
* delay slot holds a real `addu $a0,$s1,$zero` argument set-up, not a
|
||
* §263 invented-argument copy.
|
||
*
|
||
* 5. Case 1's 0xD0 chain is written RAW at all four dereferences
|
||
* (`*(u16 *)(*(s32 *)(*(s32 *)(arg0+0xD0)+0x20)+0x18)`), which is what
|
||
* reloads 0xD0($s1) and 0x20($v0) a second time for the 0x1A field;
|
||
* caching the pointer in a local (as sibling func_801A23FC does) collapses
|
||
* the reload. Case 3's +0x12C block is the same shape with the sign
|
||
* flipped.
|
||
*
|
||
* 6. buf then out in declaration order buys sp+0x18 / sp+0x20 (two 8-byte
|
||
* aggregates above the 6-word outgoing-argument area), giving the 0x40
|
||
* frame together with lever 2's four saved registers.
|
||
*
|
||
* SYMBOL AUDIT (law 1c, done after MATCH — match_one masks jal/HI16/LO16).
|
||
* The draft's relocation sequence was diffed against the relocation lines of
|
||
* asm/md_SC07_003/nonmatchings/md_SC07_003/func_801A1120.s and is identical,
|
||
* name for name and in order (26 entries beside the compiler-generated
|
||
* jtbl_801A00F4 pair):
|
||
* func_8012CBCC(arg0) [case 1] / func_8012BEE8(arg0) / func_8012A8E8(arg0) /
|
||
* func_8012CBCC(arg0) [case 3, &0x2000] / func_801830D8(arg0) /
|
||
* func_8013C9C4(D_80186F44) / func_801A2658(arg0,&D_801A68BC) and
|
||
* (arg0,&D_801A68BC+8) / func_8002D4C8(0xB52,0) /
|
||
* func_8012F14C(D_80126B78[0]+0x34, D_800D3918, &buf) and
|
||
* (D_80126B78[0]+0x34, D_801A68F4, &out) /
|
||
* func_80135888(*(arg0+0x20), *(arg0+0x58), &buf, &out) /
|
||
* func_8012B70C(D_800D3918, D_801152A8) /
|
||
* func_8012F568(1, 0x4002, <that>, 0x1E, &out, D_801152A8).
|
||
* D_801A68BC+8 is NOT its own relocation here (unlike D_801A68C4 in
|
||
* func_801A079C) — the .s spells it `addiu $a1, $s0, 0x8`, so it is written
|
||
* as `D_801A68BC + 8`, the same way sibling func_801A23FC spells it.
|
||
*
|
||
* BANK NOTE (law 2): every spelling below is copied verbatim from a
|
||
* declaration already in src/md_SC07_003/md_SC07_003.c — func_8012CBCC:1482,
|
||
* func_8013C9C4:1483, func_801A2658:1484, func_8002D4C8:1485, D_80186F44:1487,
|
||
* D_801A68BC:1488, func_8012BEE8:282, func_8012F14C:550, func_8012B70C:899,
|
||
* D_80126B78:895, func_80135888:3042, func_8012F568:3043, D_800D3918:3035,
|
||
* D_801A68F4:3036, D_801152A8:3037. Only func_8012A8E8 and func_801830D8 are
|
||
* absent from the TU; both take the card's fleet-modal spelling
|
||
* (`void func_8012A8E8(void)` n=1456, `void func_801830D8(void *)` n=3).
|
||
*/
|
||
|
||
extern void func_8012CBCC(s32 a0); /* TU canon: void; return read via fn-ptr cast */
|
||
extern void func_8013C9C4(void *a0);
|
||
extern void func_801A2658(s32 a0, s32 a1);
|
||
extern void func_8002D4C8(s32 a0, s32 a1);
|
||
extern s32 func_8012BEE8(s32 a0);
|
||
extern void func_8012A8E8(void); /* fleet canon: void(void); called with arg0 via cast */
|
||
extern void func_801830D8(void *a0);
|
||
extern void func_8012F14C(s32 a0, s32 a1, s32 a2);
|
||
extern s32 func_80135888(s32 a0, s32 a1, s32 a2, s32 a3);
|
||
extern s32 func_8012B70C(s16 *a0, s16 *a1);
|
||
extern void func_8012F568(s32 a0, s32 a1, s32 a2, s32 a3, s32 a4, s32 a5);
|
||
|
||
extern u16 D_80186F44[];
|
||
extern u8 D_801A68BC[];
|
||
extern u8 D_801A68F4[];
|
||
extern u8 D_800D3918[];
|
||
extern u8 D_801152A8[];
|
||
extern s32 D_80126B78[];
|
||
|
||
void func_801A1120(s32 arg0) {
|
||
s32 buf[2]; /* sp+0x18 */
|
||
s32 out[2]; /* sp+0x20 */
|
||
u8 *d;
|
||
s32 *tbl;
|
||
|
||
switch (*(u16 *)(arg0 + 0x34)) {
|
||
case 0:
|
||
if (*(s32 *)(arg0 + 0x94) == 0x26) {
|
||
*(s16 *)(arg0 + 0x98) = 0;
|
||
*(u16 *)(arg0 + 0x34) += 1;
|
||
}
|
||
break;
|
||
|
||
case 1:
|
||
func_8012CBCC(arg0);
|
||
if (*(s32 *)(arg0 + 0xD0) != 0) {
|
||
*(u16 *)(*(s32 *)(*(s32 *)(arg0 + 0xD0) + 0x20) + 0x18) -= 0x12C;
|
||
*(u16 *)(*(s32 *)(*(s32 *)(arg0 + 0xD0) + 0x20) + 0x1A) -= 0x12C;
|
||
}
|
||
if (*(s32 *)(arg0 + 0x14) >= 0) {
|
||
*(s32 *)(arg0 + 0x1C) = 8;
|
||
*(u16 *)(arg0 + 0x34) += 1;
|
||
}
|
||
break;
|
||
|
||
case 2:
|
||
if (func_8012BEE8(arg0) != 0) {
|
||
((void (*)(s32))func_8012A8E8)(arg0);
|
||
*(u16 *)(arg0 + 0x34) += 1;
|
||
}
|
||
/* fallthrough */
|
||
case 3:
|
||
if (*(s32 *)(arg0 + 0xD0) != 0) {
|
||
*(u16 *)(*(s32 *)(*(s32 *)(arg0 + 0xD0) + 0x20) + 0x18) += 0x12C;
|
||
*(u16 *)(*(s32 *)(*(s32 *)(arg0 + 0xD0) + 0x20) + 0x1A) += 0x12C;
|
||
}
|
||
if (((s32 (*)(s32))func_8012CBCC)(arg0) & 0x2000) {
|
||
func_801830D8((void *)arg0);
|
||
func_8013C9C4(D_80186F44);
|
||
func_801A2658(arg0, (s32)D_801A68BC);
|
||
func_801A2658(arg0, (s32)(D_801A68BC + 8));
|
||
func_8002D4C8(0xB52, 0);
|
||
*(u16 *)(arg0 + 0x34) += 1;
|
||
}
|
||
d = D_800D3918;
|
||
tbl = D_80126B78;
|
||
func_8012F14C(tbl[0] + 0x34, (s32)d, (s32)buf);
|
||
func_8012F14C(tbl[0] + 0x34, (s32)D_801A68F4, (s32)out);
|
||
if (func_80135888(*(s32 *)(arg0 + 0x20), *(s32 *)(arg0 + 0x58), (s32)buf, (s32)out) != 0) {
|
||
func_8012F568(1, 0x4002,
|
||
func_8012B70C((s16 *)d, (s16 *)D_801152A8),
|
||
0x1E, (s32)out, (s32)D_801152A8);
|
||
}
|
||
break;
|
||
|
||
case 4:
|
||
if (*(s16 *)(arg0 + 0x98) == 0) {
|
||
*(s16 *)(arg0 + 2) = 0x13;
|
||
*(s32 *)(arg0 + 0xE0) |= 0x10;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
|
||
extern void func_801A28AC(s32 arg0);
|
||
extern s32 func_8012BA10(s32 a0, s32 a1);
|
||
extern void func_8012A828(s32 a0, void *a1);
|
||
extern u8 D_801F1898[];
|
||
extern u8 D_801F1978[];
|
||
extern s16 D_801F435C;
|
||
extern void func_8002D4C8(s32 a0, s32 a1);
|
||
|
||
void func_801A13A0(s32 arg0) {
|
||
s32 s0 = arg0;
|
||
|
||
func_801A28AC(s0);
|
||
*(s16 *)(s0 + 2) = 0x10;
|
||
*(s16 *)(s0 + 0x34) = 0;
|
||
*(s32 *)(s0 + 0xE4) = 0x50;
|
||
if (func_8012BA10(s0, 1) < 0) {
|
||
func_8012A828(s0, D_801F1898);
|
||
D_801F435C = 1;
|
||
} else {
|
||
func_8012A828(s0, D_801F1978);
|
||
D_801F435C = -1;
|
||
}
|
||
*(s32 *)(s0 + 0xE0) |= 2;
|
||
func_8002D4C8(0xB56, 0);
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
extern s32 rand(void);
|
||
extern void func_800484EC(s32 a0, s32 a1, s32 a2);
|
||
extern s32 func_80132EF4(s32 a0, s32 a1);
|
||
extern s32 func_8012C51C(void *a0, s32 a1);
|
||
extern s16 D_801F435C;
|
||
|
||
/* PsyQ VECTOR (16 bytes: vx, vy, vz, pad) */
|
||
|
||
/* the 20-byte spawn descriptor handed to func_8012C51C */
|
||
|
||
void func_801A143C(s32 a0) {
|
||
Vec801A143C vin;
|
||
Vec801A143C vout;
|
||
Spawn801A143C stk;
|
||
s32 i;
|
||
s32 pick;
|
||
s32 obj;
|
||
register s32 t __asm__("$16"); // !FAKE: pin $16 — NEEDED DIFFERS (P36 rung B tus10)
|
||
s32 r;
|
||
|
||
if (*(s32 *)(a0 + 0x94) == 4) {
|
||
/* This is `x += D * -112` written as explicit shift-arithmetic ON PURPOSE.
|
||
Spelled `D_801F435C * -112`, expmed.c:2192 takes the negate_variant
|
||
(synth_mult on +112 -> `(D<<3) - D`, then a NEG) and combine folds the NEG
|
||
into the `+=`, giving `sll 3 / subu D8,D / sll 4 / SUBU` -- the target has
|
||
`sll 3 / subu D,D8 / sll 4 / ADDU`, i.e. the negative chain built directly. */
|
||
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) += (D_801F435C - D_801F435C * 8) * 16;
|
||
}
|
||
|
||
if ((u32)(*(s32 *)(a0 + 0x94) - 7) < 0x12) {
|
||
/* 240 == ((x << 4) - x) << 4 */
|
||
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) += D_801F435C * 240;
|
||
pick = rand() % 8;
|
||
|
||
vin.vy = 0;
|
||
vin.vz = 0x400000;
|
||
for (i = 0; i < 8; i++, vin.vz += 0x400000) {
|
||
obj = func_80132EF4(a0, 0x22);
|
||
if (obj == 0) {
|
||
continue;
|
||
}
|
||
/* The $16 pin on `t` is load-bearing (LENGTH-DRIFT +1 without it).
|
||
expand_divmod's internal `t1 = copy_to_mode_reg(op0)` (expmed.c:2986)
|
||
spans basic blocks, so global_alloc owns it and -- crossing 0 calls --
|
||
prefers a call-clobbered reg, taking $v0 and forcing the rand() result
|
||
into $v1 via an extra `move`, which also leaves the bgez delay slot a
|
||
nop. Pinning the result variable to $16 makes t1/quotient/t3/remainder
|
||
all land on $16, op0 stays in the raw return reg $v0, and the surviving
|
||
`t1 = op0` copy fills the delay slot exactly as the target does. */
|
||
t = (rand() % 64) << 16;
|
||
if ((rand() & 1) == 0) {
|
||
t = -t;
|
||
}
|
||
vin.vx = t;
|
||
func_800484EC(*(s32 *)(a0 + 0x20) + 0x34, (s32)&vin, (s32)&vout);
|
||
|
||
*(s32 *)(obj + 0x4) += vout.vx;
|
||
*(s32 *)(obj + 0x8) += vout.vy;
|
||
*(s32 *)(obj + 0xC) += vout.vz;
|
||
|
||
r = rand();
|
||
*(u16 *)(obj + 0x34) = (((r % 8192) + 0x5000) & ~0xF) | (rand() & 1);
|
||
*(u16 *)(*(s32 *)(obj + 0x20) + 0x2C) = 0xC004;
|
||
|
||
if (pick != i) {
|
||
continue;
|
||
}
|
||
|
||
stk.f0 = (*(s32 *)(a0 + 0x4) + vout.vx) >> 16;
|
||
stk.f2 = (*(s32 *)(a0 + 0x8) + vout.vy) >> 16;
|
||
stk.f4 = (*(s32 *)(a0 + 0xC) + vout.vz) >> 16;
|
||
stk.f6 = 0x376;
|
||
stk.f8 = 0;
|
||
stk.fA = 0;
|
||
stk.f10 = 0;
|
||
stk.fE = 0;
|
||
stk.fC = 0x7FFF;
|
||
func_8012C51C(&stk, a0);
|
||
}
|
||
}
|
||
|
||
if (*(s16 *)(a0 + 0x98) == 0) {
|
||
*(s16 *)(a0 + 0x2) = 3;
|
||
*(s32 *)(a0 + 0xE0) &= ~2;
|
||
}
|
||
}
|
||
|
||
|
||
extern void func_801A28AC(s32 arg0);
|
||
extern void func_8012A828(s32 a0, void *a1);
|
||
extern void func_8002D4C8(s32 a0, s32 a1);
|
||
extern u8 D_801F1198[];
|
||
|
||
void func_801A16BC(s32 arg0) {
|
||
s32 s0 = arg0;
|
||
|
||
func_801A28AC(s0);
|
||
*(s16 *)(s0 + 2) = 0x12;
|
||
*(s32 *)(s0 + 0xE4) = 0x50;
|
||
func_8012A828(s0, D_801F1198);
|
||
*(s16 *)(s0 + 0x34) = 0;
|
||
*(s32 *)(s0 + 0xE0) &= ~0x8;
|
||
func_8002D4C8(0xB79, 0);
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
extern s32 func_801A19C8(s32 a0);
|
||
extern s32 func_80153BD8(s32 a0);
|
||
extern void func_801A1924(s32 a0);
|
||
extern void func_8012A828(s32 a0, void *a1);
|
||
extern void func_8002D4C8(s32 a0, s32 a1);
|
||
extern void func_80153C44(s32 a0, s32 a1, s16 a2);
|
||
|
||
extern u8 D_801F1340[];
|
||
extern u8 D_801F1238[];
|
||
|
||
void func_801A1724(s32 arg0) {
|
||
s32 pad[10];
|
||
|
||
switch (*(u16 *)(arg0 + 0x34)) {
|
||
case 0:
|
||
if (func_801A19C8(arg0) == 1) {
|
||
*(u16 *)(arg0 + 0x34) += 1;
|
||
*(s32 *)(arg0 + 0xE0) |= 0x40;
|
||
} else if (*(s16 *)(arg0 + 0x98) == 0) {
|
||
func_8012A828(arg0, D_801F1238);
|
||
*(u16 *)(arg0 + 0x34) = 4;
|
||
}
|
||
break;
|
||
case 1:
|
||
if (func_80153BD8(arg0) != 0) {
|
||
*(s32 *)(arg0 + 0xE0) |= 8;
|
||
*(u16 *)(arg0 + 0x5C) &= ~0x800;
|
||
} else {
|
||
*(s32 *)(arg0 + 0xE0) &= ~0x40;
|
||
}
|
||
*(u16 *)(arg0 + 0x34) += 1;
|
||
case 2:
|
||
if ((*(s32 *)(arg0 + 0xE0) & 8) != 0) {
|
||
func_801A1924(arg0);
|
||
}
|
||
if (*(s16 *)(arg0 + 0x98) == 0) {
|
||
if ((*(s32 *)(arg0 + 0xE0) & 8) != 0) {
|
||
func_8012A828(arg0, D_801F1340);
|
||
*(u16 *)(arg0 + 0x34) = 3;
|
||
} else {
|
||
func_8012A828(arg0, D_801F1238);
|
||
*(u16 *)(arg0 + 0x34) = 4;
|
||
}
|
||
}
|
||
break;
|
||
case 3:
|
||
if (*(s32 *)(arg0 + 0x94) < 0x86) {
|
||
func_801A1924(arg0);
|
||
}
|
||
if (*(s32 *)(arg0 + 0x94) == 0x3E) {
|
||
func_8002D4C8(0xC18, 0);
|
||
}
|
||
if (*(s32 *)(arg0 + 0x94) == 0x86) {
|
||
func_80153C44(1, 0x50, *(s16 *)(*(s32 *)(arg0 + 0x20) + 0x12));
|
||
func_8002D4C8(0xC17, 0);
|
||
func_8002D4C8(0xC7B, 0);
|
||
}
|
||
case 4:
|
||
if (*(s16 *)(arg0 + 0x98) == 0) {
|
||
*(u16 *)(arg0 + 2) = 3;
|
||
*(u16 *)(arg0 + 0x5C) |= 0x800;
|
||
*(s32 *)(arg0 + 0xE0) &= ~0x40;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
|
||
extern u8 D_801A68FC[];
|
||
extern u16 D_80126B5E;
|
||
extern u16 D_80126B62;
|
||
extern u16 D_80126B66;
|
||
extern s32 D_80126B78[];
|
||
|
||
extern void func_8012EC04(s32 a0, s32 a1, s32 *a2);
|
||
extern void func_8012F14C(s32 a0, s32 a1, s32 a2);
|
||
extern s32 func_8012B70C(s16 *a0, s16 *a1);
|
||
|
||
void func_801A1924(s32 arg0) {
|
||
s32 sp10[8]; /* 0x10 */
|
||
Vec8_801A1924 sp30; /* 0x30 */
|
||
u16 sp38[4]; /* 0x38 */
|
||
|
||
func_8012EC04(arg0, 0x10, sp10);
|
||
func_8012F14C((s32)sp10, (s32)D_801A68FC, (s32)&sp30);
|
||
func_8012F14C((s32)sp10, (s32)(D_801A68FC + 8), (s32)sp38);
|
||
D_80126B5E = sp30.a;
|
||
D_80126B62 = sp30.b;
|
||
D_80126B66 = sp30.c;
|
||
*(s16 *)(*(s32 *)D_80126B78 + 0x12) = func_8012B70C((s16 *)sp38, (s16 *)&sp30);
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
/*
|
||
* func_801A19C8 (md_SC07_003, 0x801A19C8, 65 ins) == MATCH, byte-exact.
|
||
*
|
||
* "Can this actor be locked on?" Gate on the global u16 flag D_80126B94's
|
||
* 0x8000 bit; then for each of the two candidate ids in D_801A6B94[] build a
|
||
* screen-space test out of the 16-byte descriptor D_801A68FC[i] and ask
|
||
* func_80013478 for a distance. First candidate under 0x4001 wins: pop the
|
||
* indicator (func_8012F568), latch the actor in D_80127078, return 1.
|
||
*
|
||
* ---------------------------------------------------------------------------
|
||
* RESIDUAL CLASS SOLVED: GIV-fusion-over-reduction (combine_givs mult+symbol-base).
|
||
*
|
||
* The first-pass draft was NEAR/53 at 64 ins. Its loop strength-reduced the
|
||
* &D_801A68FC[i*0x10] address into an accumulating pointer ($sN += 16) where
|
||
* the target re-materialises sll/lui/addiu/addu every iteration. The whole
|
||
* residual is decided by loop.c arithmetic, and all three levers below are
|
||
* that one arithmetic statement:
|
||
*
|
||
* move_movables admits a movable iff threshold * savings * lifetime >= insn_count
|
||
* (loop.c:1631; threshold = (loop_has_call?1:2)*(1+n_non_fixed_regs) = 29,
|
||
* and threshold -= 3 after EVERY hoist, loop.c:1719/1904)
|
||
*
|
||
* The `la D_801A68FC` movable has savings 1 and lifetime 1, so its product is
|
||
* just the current threshold. If it is hoisted, the symbol lands in an
|
||
* invariant pseudo, `(plus (ashift i 4) (that pseudo))` becomes a giv with
|
||
* add_val = a register, combine_givs merges it with the bare i<<4 giv, the
|
||
* merged benefit clears 0, and it strength-reduces. Un-hoisted, the symbol
|
||
* pseudo is set INSIDE the loop, invariant_p says no, the plus is not a giv at
|
||
* all, and the lone i<<4 giv carries benefit 2 - add_cost*biv_count = 0 =>
|
||
* "not worth while" (loop.c:3823, cookbook s164-67's n=1 floor). So the whole
|
||
* job is to push the threshold under insn_count BEFORE that movable is reached.
|
||
*
|
||
* LEVER 1 - `D_801A6B94[i]`, NOT a walking `u16 *p`.
|
||
* A source pointer biv makes the D_801A6B94 base an insn-29 biv init and
|
||
* costs the loop one `addiu p,p,2`; insn_count stays 25 and the la is
|
||
* movable #1 at threshold 29 (29 >= 25 => hoisted). Array indexing turns
|
||
* it into an ADDRESS giv whose add_val is the SYMBOL_REF itself, so
|
||
* emit_iv_add_mult(symbol + 0*2) puts `la $s1,D_801A6B94` in the
|
||
* preheader's THIRD stratum (cookbook s190-A) - which is exactly where the
|
||
* target has it, AFTER the hoisted `addiu $s2,$sp,0x38` - and it raises
|
||
* insn_count 25 -> 27.
|
||
*
|
||
* LEVER 2 - `u16 *o = out;` as the FIRST statement of the loop body.
|
||
* Naming a stack address forces a pseudo that scan_loop can record
|
||
* (cookbook s164-35: written inline at a call site there is no insn to
|
||
* move). Body order is movable-list order, so this becomes movable #1 and
|
||
* spends the first `threshold -= 3` (29 -> 26). `buf` is deliberately
|
||
* left UNNAMED: the target recomputes `addiu $a2,$sp,0x18` twice inside
|
||
* the loop, so it must stay inline. With levers 1+2 the D_801A68FC la is
|
||
* movable #3 at threshold 23 < insn_count 27 and cc1 -dL prints
|
||
* "Insn 64: regno 87 (life 1), move-insn savings 1 not desirable".
|
||
*
|
||
* LEVER 3 - `s32 *m = &D_80126B58;` declared ABOVE the flag test.
|
||
* The target computes `lui/addiu $s4,D_80126B58` in the ENTRY block -
|
||
* before the `bnez` - and then spells the argument `addiu $a0,$s4,4`.
|
||
* loop.c can only hoist as far as the preheader (after the branch), so
|
||
* this cannot be invariant motion: it is source position. A pointer local
|
||
* initialised before the `if` leaves `(set p (symbol_ref))` in the entry
|
||
* block; cse cannot fold it into the loop because the loop body starts a
|
||
* fresh extended basic block, so `m + 1` survives as a register + 4.
|
||
* Writing `(s32)&D_80126B58 + 4` inline instead folds to one CONST and
|
||
* emits `lui/addiu` INSIDE the loop - that was the last 3 instructions
|
||
* (2 in-loop la, plus the missing sw/lw $s4 pair) of the -1/-3 drift.
|
||
*
|
||
* Declarations: none of these symbols is declared in md_SC07_003.c, and every
|
||
* spelling below matches the sibling drafts already staged for this TU
|
||
* (extern s32 D_80126B58; extern u8 D_801152A8[]; extern u16 D_801A6B94[]).
|
||
*/
|
||
|
||
extern u16 D_80126B94;
|
||
extern s32 D_80126B58;
|
||
extern u16 D_801A6B94[];
|
||
extern u8 D_801A68FC[];
|
||
extern u8 D_801152A8[];
|
||
extern s32 D_80127078;
|
||
|
||
extern void func_8012EC04(s32 param_1, s32 param_2, s32 *param_3);
|
||
extern void func_8012F14C(s32 a0, s32 a1, s32 a2);
|
||
extern s32 func_80013478(s32 a0, s32 a1);
|
||
extern void func_8012F568(s32 a0, s32 a1, s32 a2, s32 a3, s32 a4, s32 a5);
|
||
|
||
s32 func_801A19C8(s32 arg0) {
|
||
s32 buf[8]; /* 0x18(sp) - scratch handed to func_8012EC04/func_8012F14C */
|
||
u16 out[4]; /* 0x38(sp) - the projected point both later calls read */
|
||
s32 i;
|
||
s32 *m = &D_80126B58; /* LEVER 3: entry-block `la`, used as m+1 == +4 */
|
||
|
||
if (!(D_80126B94 & 0x8000)) {
|
||
return 0;
|
||
}
|
||
|
||
for (i = 0; i < 2; i++) {
|
||
u16 *o = out; /* LEVER 2: first movable, eats threshold 29 -> 26 */
|
||
func_8012EC04(arg0, D_801A6B94[i], buf); /* LEVER 1 */
|
||
func_8012F14C((s32)buf, (s32)&D_801A68FC[i * 0x10], (s32)o);
|
||
if (func_80013478((s32)(m + 1), (s32)o) < 0x4001) {
|
||
func_8012F568(1, 0x401C,
|
||
*(u16 *)(*(s32 *)(arg0 + 0x20) + 0x12) & 0xFFF, 0x50,
|
||
(s32)o, (s32)D_801152A8);
|
||
D_80127078 = arg0;
|
||
return 1;
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
|
||
extern void func_8012A828(s32 a0, void *a1);
|
||
extern s32 func_8012C658(s32 arg0, s32 arg1, s32 arg2);
|
||
extern u8 D_801A64C4[];
|
||
|
||
void func_801A1ACC(s32 arg0) {
|
||
*(s16 *)(arg0 + 0x02) = 0x14;
|
||
*(u16 *)(arg0 + 0x34) = 0;
|
||
*(s32 *)(arg0 + 0x1C) = 0;
|
||
*(s32 *)(arg0 + 0xE4) = 0x20;
|
||
func_8012A828(arg0, D_801A64C4);
|
||
*(s32 *)(arg0 + 0xD8) = func_8012C658(0x34C, 1, arg0);
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
/* func_801A1B28 — md_SC07_003 entity update (fresh mass-lane crack, no banked twin).
|
||
*
|
||
* arg0 is the standard 0x10C-ish entity record:
|
||
* +0x02 s16 state/anim id +0x1C s32 tick counter
|
||
* +0x20 s32 -> render object (its +0x34 is a MATRIX, its +0x2C a u16 gpu code)
|
||
* +0x34 u16 "done" counter +0x72 u16 flag word +0x76 s16 hp-ish
|
||
* +0x90 s32 script ptr +0x94 s32 script sub-state
|
||
* +0x98 s16 busy flag +0xD8 s32 -> u16-tagged record
|
||
* +0xE0 s32 flag word +0xE8/+0xEC s32
|
||
*
|
||
* Stack (frame 0x58 = 0x10 outgoing args + 0x38 locals + 0x10 saves):
|
||
* sp+0x10 MATRIX mtx (0x20) sp+0x30 SVECTOR sv (0x08) sp+0x38 VECTOR vec (0x10)
|
||
*/
|
||
|
||
/* 0x20 */
|
||
/* 0x08 */
|
||
/* 0x10 */
|
||
|
||
extern s32 func_8012E544(s32 a0);
|
||
extern s32 func_8017F2D8(void);
|
||
extern s32 func_80132EF4(s32 a0, s32 a1);
|
||
extern void func_8012EC04(s32 a0, s32 a1, s32 *a2);
|
||
extern void func_8012F14C(s32 a0, s32 a1, s32 a2);
|
||
extern s32 RotMatrixX(s32 a0, void *a1);
|
||
extern void func_800484EC(s32 a0, s32 a1, s32 a2);
|
||
extern void func_8002D4C8(s32 a0, s32 a1);
|
||
extern void func_8012A828(s32 a0, void *a1);
|
||
extern void func_8012C218(void *a0);
|
||
|
||
extern u8 D_801A63FC[];
|
||
extern u16 D_801F43C0;
|
||
extern u8 D_801A68DC[];
|
||
extern u8 D_801A6504[];
|
||
|
||
void func_801A1B28(s32 arg0) {
|
||
MTX_801A1B28 mtx;
|
||
SV_801A1B28 sv;
|
||
VEC_801A1B28 vec;
|
||
s32 obj;
|
||
s32 p;
|
||
|
||
if (*(s32 *)(arg0 + 0xE0) & 0x10) {
|
||
if (func_8012E544(0x352) == 0) {
|
||
func_8017F2D8();
|
||
*(s32 *)(arg0 + 0xE0) &= ~0x10;
|
||
}
|
||
}
|
||
|
||
if (*(s32 *)(arg0 + 0xE0) & 0x21) {
|
||
if (*(s16 *)(arg0 + 0x76) <= 0) {
|
||
*(s16 *)(arg0 + 0x2) = 0x17;
|
||
} else {
|
||
*(s16 *)(arg0 + 0x2) = 0x15;
|
||
}
|
||
return;
|
||
}
|
||
|
||
if (*(u16 *)(arg0 + 0x34) == 0) {
|
||
if (*(u16 *)(arg0 + 0x72) & 0x4000) {
|
||
*(s32 *)(arg0 + 0x1C) += 1;
|
||
}
|
||
if (*(s32 *)(arg0 + 0x90) == (s32)D_801A63FC && *(s32 *)(arg0 + 0x94) == 0) {
|
||
obj = func_80132EF4(arg0, 0x22);
|
||
if (obj != 0) {
|
||
func_8012EC04(arg0, D_801F43C0, (s32 *)&mtx);
|
||
func_8012F14C((s32)&mtx, (s32)D_801A68DC, (s32)&sv);
|
||
*(u16 *)(obj + 0x6) = sv.vx;
|
||
*(u16 *)(obj + 0xA) = sv.vy + 0x20;
|
||
*(u16 *)(obj + 0xE) = sv.vz;
|
||
*(s16 *)(obj + 0x34) = 0x6000;
|
||
*(u16 *)(*(s32 *)(obj + 0x20) + 0x2C) = 0xC010;
|
||
mtx = *(MTX_801A1B28 *)(*(s32 *)(arg0 + 0x20) + 0x34);
|
||
vec.vy = 0;
|
||
vec.vx = 0;
|
||
vec.vz = -0xC0000;
|
||
RotMatrixX(0x200, &mtx);
|
||
func_800484EC((s32)&mtx, (s32)&vec, obj + 0x10);
|
||
}
|
||
func_8002D4C8(0xB9C, 0);
|
||
}
|
||
if (*(s32 *)(arg0 + 0x1C) >= 4) {
|
||
func_8012A828(arg0, D_801A6504);
|
||
*(u16 *)(arg0 + 0x34) += 1;
|
||
}
|
||
} else {
|
||
if (*(s16 *)(arg0 + 0x98) == 0) {
|
||
*(s16 *)(arg0 + 0x2) = 3;
|
||
*(s32 *)(arg0 + 0xEC) = 0x10000;
|
||
*(s32 *)(arg0 + 0xE8) = 0;
|
||
*(s32 *)(arg0 + 0xE0) |= 0x100;
|
||
p = *(s32 *)(arg0 + 0xD8);
|
||
if (p != 0) {
|
||
if (*(u16 *)p != 0) {
|
||
func_8012C218((void *)p);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
extern void func_801A28AC(s32 arg0);
|
||
extern void func_8012A828(s32 a0, void *a1);
|
||
extern void func_8012B178(s32 a0, s32 a1);
|
||
|
||
extern u8 D_801F0798[];
|
||
extern u8 D_801F0840[];
|
||
|
||
void func_801A1D94(void *arg0) {
|
||
s32 s0 = (s32)arg0;
|
||
|
||
((void (*)(void *))func_801A28AC)(arg0);
|
||
if (*(u32 *)(s0 + 0xE0) & 1) {
|
||
func_8012A828(s0, D_801F0798);
|
||
*(u16 *)(s0 + 0x34) = 0;
|
||
} else {
|
||
func_8012A828(s0, D_801F0840);
|
||
*(u16 *)(s0 + 0x34) = 1;
|
||
func_8012B178(s0, 0x30000);
|
||
}
|
||
*(u16 *)(s0 + 2) = 0x16;
|
||
*(s32 *)(s0 + 0xE4) = 0x30;
|
||
*(s32 *)(s0 + 0xE0) = *(u32 *)(s0 + 0xE0) | 0x40;
|
||
*(s32 *)(s0 + 0x1C) = 0x10;
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
extern void func_8002D4C8(s32 a0, s32 a1);
|
||
extern void func_8012ADE4(u8 *a0);
|
||
extern void func_8012CBA4(s32 a0); /* canonical void; return read via fn-ptr cast */
|
||
extern s32 func_8012E544(s32 a0);
|
||
extern s32 func_8017F2D8(void);
|
||
extern void func_801A24E8(s32 a0);
|
||
|
||
void func_801A1E30(s32 a0) {
|
||
s32 v1;
|
||
|
||
if (*(u32 *)(a0 + 0xE0) & 0x10) {
|
||
if (func_8012E544(0x352) == 0) {
|
||
func_8017F2D8();
|
||
*(u32 *)(a0 + 0xE0) &= ~0x10;
|
||
}
|
||
}
|
||
|
||
if (*(u16 *)(a0 + 0x34) != 0) {
|
||
v1 = *(s32 *)(a0 + 0x94);
|
||
if ((u32)v1 < 0x33) {
|
||
if (v1 == 0x18) {
|
||
func_8002D4C8(0xC34, 0);
|
||
}
|
||
if ((((s32 (*)(s32))func_8012CBA4)(a0) & 0x2000) == 0) {
|
||
func_8012ADE4((u8 *)a0);
|
||
}
|
||
func_801A24E8(a0);
|
||
}
|
||
}
|
||
|
||
if (*(s16 *)(a0 + 0x98) == 0) {
|
||
if (*(u32 *)(a0 + 0xE0) & 0x20) {
|
||
*(u32 *)(a0 + 0xE8) = 0;
|
||
*(u32 *)(a0 + 0xEC) = 0x10000;
|
||
*(u32 *)(a0 + 0xE0) |= 0x100;
|
||
}
|
||
*(s16 *)(a0 + 2) = 5;
|
||
*(u32 *)(a0 + 0xE0) &= ~0x21;
|
||
}
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
extern void func_80016714(s8 *a0, s32 a1);
|
||
extern void func_8012B178(s32 a0, s32 a1);
|
||
extern void func_800D0C48(s32 a0);
|
||
extern s32 func_80178B18(s32 a0, s32 a1);
|
||
extern void func_8017C068(void);
|
||
extern void func_8002D4C8(s32 a0, s32 a1);
|
||
extern void func_8012A828(s32 a0, void *a1);
|
||
|
||
extern s16 D_801A6964;
|
||
extern s16 D_801A6966;
|
||
extern s16 D_801A6968;
|
||
extern s16 D_801A696C;
|
||
extern s16 D_801A6AE4;
|
||
extern u8 D_801F1A58[];
|
||
extern s32 D_801F4358;
|
||
|
||
void func_801A1F38(s32 arg0) {
|
||
s32 s0 = arg0;
|
||
|
||
D_801A6964 = 0;
|
||
D_801A6966 = -0x90;
|
||
D_801A6968 = 0;
|
||
|
||
D_801A696C = *(u16 *)(*(s32 *)(s0 + 0x20) + 0x12) & 0xFFF;
|
||
|
||
func_80178B18((s32)s0, (s32)&D_801A6AE4);
|
||
|
||
*(s16 *)(s0 + 0x2) = 0x18;
|
||
*(s16 *)(s0 + 0x34) = 0;
|
||
*(s16 *)(s0 + 0x98) = 0;
|
||
*(s32 *)(s0 + 0x1C) = 0;
|
||
*(s32 *)(s0 + 0xE4) = 0x10000;
|
||
func_8017C068();
|
||
|
||
func_8012A828((s32)s0, D_801F1A58);
|
||
func_8012B178((s32)s0, 0x30000);
|
||
func_800D0C48(1);
|
||
func_8002D4C8(0xC73, 0);
|
||
|
||
if (D_801F4358 != 0) {
|
||
func_80016714((s8 *)D_801F4358, 0x38);
|
||
D_801F4358 = 0;
|
||
}
|
||
}
|
||
|
||
|
||
/* func_801A2014 (md_SC07_003, 154 ins) -- MATCH, fresh crack from the .s.
|
||
*
|
||
* BANKING NOTES (the destination TU src/md_SC07_003/md_SC07_003.c is 100% INCLUDE_ASM,
|
||
* so it declares NOTHING; every spelling below is the fleet-modal one from the card's
|
||
* decl_prior EXCEPT where marked):
|
||
* - func_8012CBA4 RECONCILED (slate lane, S54): originally declared with the rival
|
||
* ('s32',('s32',)) spelling because this call site CONSUMES the return
|
||
* ("andi $v0,$v0,0x2000" right after the jal). That clashed with func_801A1E30 in the
|
||
* same TU, which uses the canonical ('void',('s32',)) def + the tree's fn-ptr-cast
|
||
* idiom. Adopted the canonical void extern here too and routed the return through
|
||
* ((s32 (*)(s32))func_8012CBA4)(...) at the call -- re-verified MATCH, byte-neutral.
|
||
* - func_80178970 / func_80178D18 / func_80181A00: declared with UNSPECIFIED parameter
|
||
* lists "()" on purpose. The first two are defined ('s32',()) / ('void',()) yet this
|
||
* site passes $a0; func_80181A00 is defined ('s32',('u8','u8','u8','u8')) yet this
|
||
* site passes NO arguments (the "jal func_80181A00" has a bare nop delay slot).
|
||
* Adopting either prototype makes this TU fail to compile -- keep "()" (STEP 0c: an
|
||
* unspecified list is compatible with any prototype in C89 and is never a conflict).
|
||
* - D_801A6BB8 / D_801A6BBE are the two splat symbols the target's own relocations name
|
||
* (the table is really one 8-byte-stride SVECTOR-ish array; splat split it at +6
|
||
* because both halves carry their own %hi).
|
||
* - RotTransSV uses the src/shared/engine_core.h spelling ('void',('s32','s32','void*')).
|
||
*/
|
||
#include "common.h"
|
||
|
||
/* --- PsyQ inline GTE macros (copied verbatim from the banked
|
||
* src/ov_SC06_008/ov_SC06_008_jr_8017C294.c spelling) ------------------ */
|
||
|
||
extern void RotTransSV(s32 a0, s32 a1, void *a2);
|
||
extern void func_8002D4C8(s32 a0, s32 a1);
|
||
extern void func_80029514(s32 a0);
|
||
extern s32 func_8004787C(s32 a0);
|
||
extern s32 func_80047948(s32 a0);
|
||
extern void func_8012CBA4(s32 a0); /* canonical void; return read via fn-ptr cast */
|
||
extern void func_8012ADE4(u8 *a0);
|
||
extern s32 func_8012C51C(void *a0, s32 a1);
|
||
extern s32 func_8012C588(s32 a0, s32 a1);
|
||
extern void func_8012EC04(s32 a0, s32 a1, s32 *a2);
|
||
extern s32 func_80132EF4(s32 a0, s32 a1);
|
||
extern s32 func_80178970();
|
||
extern void func_80178D18();
|
||
extern s32 func_80181A00();
|
||
extern void func_801A227C(void *arg0);
|
||
extern void func_801A24E8(s32 a0);
|
||
|
||
extern u8 D_801A6BB8[];
|
||
extern u16 D_801A6BBE[];
|
||
|
||
/* 0x14 bytes */
|
||
|
||
void func_801A2014(s32 p)
|
||
{
|
||
Prim801A2014 prim; /* sp+0x10 */
|
||
u16 sv[4]; /* sp+0x28 */
|
||
s32 m[8]; /* sp+0x30 */
|
||
s32 flag; /* sp+0x50 */
|
||
s32 i;
|
||
s32 off;
|
||
|
||
switch (*(u16 *)(p + 0x34)) {
|
||
case 0:
|
||
if ((u32)*(s32 *)(p + 0x94) < 0x33) {
|
||
if (((((s32 (*)(s32))func_8012CBA4)(p)) & 0x2000) == 0) {
|
||
func_8012ADE4((u8 *)p);
|
||
}
|
||
func_801A24E8(p);
|
||
}
|
||
if ((u32)(*(s32 *)(p + 0x94) - 0x32) < 0x3D) {
|
||
*(u16 *)(p + 0x50) += func_8004787C(*(s32 *)(p + 0x1C)) >> 9;
|
||
*(u16 *)(p + 0x54) += func_80047948(*(s32 *)(p + 0x1C)) >> 9;
|
||
*(s32 *)(p + 0x1C) += 0x400;
|
||
}
|
||
if (*(s32 *)(p + 0x94) == 0x6B) {
|
||
func_8002D4C8(0xC8C, 0);
|
||
}
|
||
break;
|
||
|
||
case 1:
|
||
func_8012EC04(p, 4, m);
|
||
gte_SetRotMatrix(m);
|
||
gte_SetTransMatrix(m);
|
||
for (i = 0; i < 16; i++) {
|
||
off = i * 8;
|
||
RotTransSV((s32)(D_801A6BB8 + off), (s32)sv, &flag);
|
||
prim.x = sv[0];
|
||
prim.y = sv[1];
|
||
prim.z = sv[2];
|
||
prim.f06 = 0x38A;
|
||
prim.f08 = i;
|
||
prim.f0A = 0;
|
||
/* §190-B / sched1 LUID tie-break: the 0x0E / 0x10 / 0x0C stores must be
|
||
* written in THIS order -- it is the only ordering of the nine field stores
|
||
* that reproduces the target's sched1+sched2 interleave (see notes). */
|
||
prim.f0E = *(u16 *)(*(s32 *)(p + 0x20) + 0x12) +
|
||
*(u16 *)((u8 *)D_801A6BBE + off);
|
||
prim.f10 = 0;
|
||
prim.f0C = 0x7FFF;
|
||
func_8012C51C(&prim, p);
|
||
}
|
||
func_8002D4C8(0xB9E, 0);
|
||
*(s16 *)(p + 0x34) = 3;
|
||
break;
|
||
|
||
case 2:
|
||
*(s32 *)(p + 0xD8) = func_8012C588(0x380, p);
|
||
func_80132EF4(p, 0x6E);
|
||
*(s16 *)(p + 0x34) = 3;
|
||
break;
|
||
}
|
||
|
||
if (func_80178970(p) == 1) {
|
||
func_80178D18(p);
|
||
func_801A227C(p);
|
||
func_80029514(0x640);
|
||
func_80181A00();
|
||
}
|
||
}
|
||
|
||
|
||
extern void func_8012C218(void *a0);
|
||
extern void func_80016450(s32 a0, s32 a1);
|
||
|
||
void func_801A227C(void *arg0) {
|
||
void *v0;
|
||
if (*(void **)((u8 *)arg0 + 0xCC) != NULL) {
|
||
func_8012C218(*(void **)((u8 *)arg0 + 0xCC));
|
||
}
|
||
if (*(void **)((u8 *)arg0 + 0xD0) != NULL) {
|
||
func_8012C218(*(void **)((u8 *)arg0 + 0xD0));
|
||
}
|
||
if (*(void **)((u8 *)arg0 + 0xD4) != NULL) {
|
||
func_8012C218(*(void **)((u8 *)arg0 + 0xD4));
|
||
}
|
||
v0 = *(void **)((u8 *)arg0 + 0xD8);
|
||
if (v0 != NULL) {
|
||
func_80016450(*(u8 *)((u8 *)v0 + 0xFC), 0);
|
||
func_8012C218(*(void **)((u8 *)arg0 + 0xD8));
|
||
}
|
||
func_8012C218(arg0);
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
extern void func_8002D4C8(s32 a0, s32 a1);
|
||
extern void func_8012AD80(s32 a0);
|
||
|
||
s32 func_801A2318(s32 arg0) {
|
||
s32 temp;
|
||
|
||
temp = *(s32 *)(arg0 + 0xD8);
|
||
((void (*)(s32))func_8012AD80)(temp);
|
||
|
||
if (--*(s32 *)(arg0 + 0xF8) == 0) {
|
||
*(s32 *)(temp + 0x14) = 0x60000;
|
||
func_8002D4C8(4, 0xC36);
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
|
||
|
||
|
||
extern void func_8012AD80(s32 a0);
|
||
s32 func_801A2384(s32 arg0) {
|
||
((void (*)(s32))func_8012AD80)(*(s32 *)(arg0 + 0xd8));
|
||
}
|
||
|
||
|
||
extern void func_8012A828(s32 a0, void *a1);
|
||
|
||
void func_801A23A8(void *arg0) {
|
||
func_8012A828((s32)arg0, *(void **)((s32)arg0 + 0xF8));
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
s32 func_801A23CC(s32 arg0) {
|
||
if (*(s16 *)(arg0 + 0x98) == 0 || (*(u16 *)(arg0 + 0x72) & 0x4000)) {
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
extern void func_8012CBCC(s32 a0);
|
||
extern void func_8013C9C4(void *a0);
|
||
extern void func_801A2658(s32 a0, s32 a1);
|
||
extern void func_8002D4C8(s32 a0, s32 a1);
|
||
|
||
extern u16 D_80186F44[];
|
||
extern u8 D_801A68BC[];
|
||
|
||
s32 func_801A23FC(s32 arg0) {
|
||
s32 s1;
|
||
s32 v;
|
||
s32 p;
|
||
|
||
s1 = 0;
|
||
v = *(s32 *)(arg0 + 0xD0);
|
||
if (v != 0) {
|
||
s1 = v;
|
||
*(u16 *)(*(s32 *)(s1 + 0x20) + 0x18) += 0x266;
|
||
*(u16 *)(*(s32 *)(s1 + 0x20) + 0x1A) += 0x266;
|
||
}
|
||
|
||
if (((s32 (*)(s32))func_8012CBCC)(arg0) & 0x2000) {
|
||
func_8013C9C4(D_80186F44);
|
||
func_801A2658(arg0, (s32)D_801A68BC);
|
||
func_801A2658(arg0, (s32)(D_801A68BC + 8));
|
||
if (s1 != 0) {
|
||
p = *(s32 *)(s1 + 0x20);
|
||
*(u16 *)(p + 0x1A) = 0x3000;
|
||
*(u16 *)(p + 0x18) = 0x3000;
|
||
}
|
||
*(s32 *)(arg0 + 0xE0) |= 4;
|
||
func_8002D4C8(0xB52, 0);
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
|
||
extern u8 D_801202A0[];
|
||
|
||
extern s32 func_8012BC60(void *a0, void *a1);
|
||
extern s32 func_8012B6D4(s16 *a0, s16 *a1);
|
||
extern void func_8012B0B4(u32 *a0, s32 a1, s32 a2);
|
||
extern s32 func_8012CEB0(s32 a0, s32 a1, s32 a2);
|
||
extern void func_8012ADE4(u8 *a0);
|
||
|
||
void func_801A24E8(s32 a0) {
|
||
u8 *p;
|
||
s16 *self4;
|
||
unsigned int *sc;
|
||
s32 i;
|
||
s32 ang;
|
||
s16 v10[4]; /* sp+0x10 */
|
||
s16 v18[4]; /* sp+0x18 */
|
||
s32 sp20[2]; /* sp+0x20 — func_8012B0B4 output */
|
||
|
||
p = D_801202A0;
|
||
i = 0;
|
||
self4 = (s16 *)(a0 + 4);
|
||
sc = (unsigned int *)sp20;
|
||
do {
|
||
switch (*(u16 *)p) {
|
||
case 0x4B:
|
||
if (func_8012BC60((void *)self4, (void *)(p + 4)) <= 0x30FFF) {
|
||
ang = func_8012B6D4(self4, (s16 *)(p + 4));
|
||
func_8012B0B4(sc, ang, 0x1C0);
|
||
v18[0] = *(u16 *)(p + 6);
|
||
v18[1] = *(u16 *)(p + 0xA);
|
||
v18[2] = *(u16 *)(p + 0xE);
|
||
v18[0] += sp20[0];
|
||
v18[1] = *(u16 *)(a0 + 0xA);
|
||
v18[2] += sp20[0] >> 16;
|
||
v10[0] = *(u16 *)(a0 + 0x3A);
|
||
v10[1] = *(u16 *)(a0 + 0x3E);
|
||
v10[2] = *(u16 *)(a0 + 0x42);
|
||
if ((func_8012CEB0((s32)v10, (s32)v18, 0) & 0x2000) == 0) {
|
||
func_8012ADE4((u8 *)a0);
|
||
return;
|
||
}
|
||
*(u16 *)(a0 + 6) = v18[0];
|
||
*(u16 *)(a0 + 0xA) = v18[1];
|
||
*(u16 *)(a0 + 0xE) = v18[2];
|
||
return;
|
||
}
|
||
break;
|
||
}
|
||
i++;
|
||
p += 0x10C;
|
||
} while (i < 0x60);
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
extern s32 D_801F1FD8;
|
||
|
||
extern void func_8012EC04(s32 a0, s32 a1, s32 *a2);
|
||
extern void func_8012F14C(s32 a0, s32 a1, s32 a2);
|
||
extern u8 *func_8012913C(s32 a0);
|
||
extern s32 func_80047948(s32 a0);
|
||
extern s32 func_8004787C(s32 a0);
|
||
extern s32 func_8012C51C(void *a0, s32 a1);
|
||
|
||
void func_801A2658(s32 arg0, s32 arg1) {
|
||
s32 buf[8];
|
||
s16 vec[3];
|
||
struct {
|
||
s16 f0, f1, f2, f3, f4, f5, f6, f7;
|
||
s32 f8;
|
||
} eff;
|
||
s32 i;
|
||
u8 *ent;
|
||
s32 delta;
|
||
|
||
delta = *(s16 *)(arg1 + 0x6);
|
||
if (*(s32 *)(arg0 + 0x90) == (s32)&D_801F1FD8) {
|
||
delta -= 1;
|
||
}
|
||
func_8012EC04(arg0, delta, buf);
|
||
func_8012F14C((s32)buf, arg1, (s32)vec);
|
||
|
||
for (i = 0; i < 0x1000; i += 0x100) {
|
||
ent = func_8012913C(0x22);
|
||
if (ent != 0) {
|
||
*(s16 *)(ent + 0x6) = vec[0];
|
||
*(s16 *)(ent + 0xA) = vec[1];
|
||
*(s16 *)(ent + 0xE) = vec[2];
|
||
*(s32 *)(ent + 0x10) = func_80047948(i) * 320;
|
||
*(s32 *)(ent + 0x18) = func_8004787C(i) * 320;
|
||
*(s16 *)(ent + 0x34) = 0x4000;
|
||
*(u16 *)(*(s32 *)(ent + 0x20) + 0x2C) = 0xC002;
|
||
}
|
||
}
|
||
|
||
eff.f3 = 0x376;
|
||
eff.f4 = 0;
|
||
eff.f5 = 0;
|
||
eff.f8 = 0;
|
||
eff.f7 = 0;
|
||
eff.f6 = 0x7FFF;
|
||
eff.f0 = vec[0];
|
||
eff.f1 = vec[1];
|
||
eff.f2 = vec[2];
|
||
|
||
for (i = 0; i < 8; i++) {
|
||
func_8012C51C(&eff, arg0);
|
||
}
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
extern void func_8012EC04(s32 param_1, s32 param_2, s32 *param_3);
|
||
extern void func_8012F14C(s32 a0, s32 a1, s32 a2);
|
||
extern u8 *func_8012913C(s32 a0);
|
||
extern s32 func_8012C51C(void *a0, s32 a1);
|
||
|
||
void func_801A27A4(void *a0, void *a1)
|
||
{
|
||
s32 buf1[8];
|
||
u16 pos[3];
|
||
u8 *ent;
|
||
s32 i;
|
||
|
||
struct {
|
||
u16 f0;
|
||
u16 f2;
|
||
u16 f4;
|
||
u16 f6;
|
||
u16 f8;
|
||
u16 fA;
|
||
u16 fC;
|
||
u16 fE;
|
||
s32 f10;
|
||
} tmp;
|
||
|
||
func_8012EC04((s32)a0, *(s16 *)((s32)a1 + 0x6), buf1);
|
||
func_8012F14C((s32)buf1, (s32)a1, (s32)pos);
|
||
|
||
ent = func_8012913C(0x22);
|
||
|
||
if (ent != NULL) {
|
||
*(u16 *)((s32)ent + 0x6) = pos[0];
|
||
*(u16 *)((s32)ent + 0xA) = pos[1];
|
||
*(u16 *)((s32)ent + 0xE) = pos[2];
|
||
*(s32 *)((s32)ent + 0x10) = -(*(s32 *)((s32)a0 + 0x10));
|
||
*(s32 *)((s32)ent + 0x18) = -(*(s32 *)((s32)a0 + 0x18));
|
||
*(u16 *)((s32)ent + 0x34) = 0x7001;
|
||
*(u16 *)((s32)(*(s32 *)((s32)ent + 0x20)) + 0x2C) = 0xC002;
|
||
}
|
||
|
||
tmp.f0 = pos[0];
|
||
tmp.f2 = pos[1];
|
||
tmp.f4 = pos[2];
|
||
tmp.f6 = 0x376;
|
||
tmp.f8 = 0;
|
||
tmp.fA = 0;
|
||
tmp.f10 = 0;
|
||
tmp.fE = 0;
|
||
tmp.fC = 0x7FFF;
|
||
|
||
for (i = 0; i < 2; i++) {
|
||
func_8012C51C(&tmp, (s32)a0);
|
||
}
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
extern s32 func_8012E544(s32 a0);
|
||
extern void func_8012C218(void *a0);
|
||
|
||
extern s32 D_801F1FD8;
|
||
extern u16 D_801F43C0;
|
||
extern s32 D_801AE21C[];
|
||
|
||
void func_801A28AC(s32 arg0)
|
||
{
|
||
s32 handle;
|
||
s32 obj;
|
||
|
||
if (*(s32 *)(arg0 + 0x90) == (s32)&D_801F1FD8) {
|
||
handle = func_8012E544(0x3D0);
|
||
if (handle != 0) {
|
||
func_8012C218((void *)handle);
|
||
}
|
||
obj = *(s32 *)(arg0 + 0x20);
|
||
{
|
||
s32 state;
|
||
|
||
state = 3;
|
||
D_801F43C0 = (u16)state;
|
||
}
|
||
do { *(s32 *)(obj + 0x24) = (s32)D_801AE21C; } while (0);
|
||
}
|
||
}
|
||
|
||
|
||
s32 func_801A2918(s32 arg0) {
|
||
s32 r;
|
||
s32 p;
|
||
r = 1;
|
||
p = *(s32 *)(arg0 + 0xD8);
|
||
if (p != 0) {
|
||
r = *(s32 *)(p + 0xE0) != 0;
|
||
}
|
||
return r;
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
extern s32 rand(void);
|
||
extern s32 func_8012E544(s32 a0);
|
||
extern void func_8012EC04(s32 a0, s32 a1, s32 *a2);
|
||
extern void func_8012F14C(s32 a0, s32 a1, s32 a2);
|
||
extern s32 func_8012C51C(void *a0, s32 a1);
|
||
extern s32 func_8005A600(s32 a0, s32 a1, s32 a2, s32 a3, s32 a4);
|
||
extern u16 D_801F43C0;
|
||
extern s32 D_801F4360[];
|
||
extern u8 D_801A6C50[];
|
||
extern u8 D_801A6C98[];
|
||
extern u8 D_800AF630[];
|
||
extern u8 D_800A6610[];
|
||
extern s16 D_800B9A02;
|
||
extern s32 D_800A5E60;
|
||
|
||
/* PsyQ inline GTE macros (house spelling) */
|
||
|
||
/* libgpu P_TAG: the 24-bit addr field reproduces setaddr()/getaddr() (boot.c house spelling) */
|
||
|
||
|
||
void func_801A293C(void *arg0)
|
||
{
|
||
s32 sp18[8]; /* 0x18 */
|
||
s32 sp38[8]; /* 0x38 */
|
||
u16 sp58[4]; /* 0x58 */
|
||
Prim293C prim; /* 0x60 */
|
||
s32 flag; /* 0x78 */
|
||
s32 otz1; /* 0x7C */
|
||
s32 otz2; /* 0x80 */
|
||
s32 dX[1]; /* 0x84 dead 4-byte slot (frame oracle: target 0xB8) */
|
||
s32 base; /* 0x88 spill */
|
||
s32 f5;
|
||
s32 w, m, s1, s3, s6, s7, s0, fp, i, p;
|
||
s32 s5v;
|
||
|
||
PTag293C *e;
|
||
|
||
w = (s32)arg0;
|
||
if (D_801F43C0 == 3) {
|
||
func_8012EC04(w, 3, sp18);
|
||
func_8012EC04(w, 0, sp38);
|
||
s1 = w;
|
||
s6 = D_801F43C0;
|
||
f5 = 0;
|
||
} else {
|
||
s1 = func_8012E544(0x3D0);
|
||
if (s1 == 0) {
|
||
return;
|
||
}
|
||
func_8012EC04(s1, 0, sp18);
|
||
func_8012EC04(s1, 1, sp38);
|
||
s6 = 0;
|
||
f5 = 1;
|
||
}
|
||
|
||
if (*(s32 *)(w + 0xE0) & 4) {
|
||
i = 0;
|
||
s3 = 0x38E38E39;
|
||
for (; i < 3; i++) {
|
||
if (D_801F4360[i] % *(s32 *)(w + 0xE4) == 0) {
|
||
if ((rand() & 1) == 0) {
|
||
s0 = (s32)(D_801A6C50 + (rand() % 9) * 8);
|
||
func_8012F14C((s32)sp18, s0, (s32)sp58);
|
||
prim.f0E = s6;
|
||
} else {
|
||
s0 = (s32)(D_801A6C98 + (rand() % 9) * 8);
|
||
func_8012F14C((s32)sp38, s0, (s32)sp58);
|
||
prim.f0E = f5;
|
||
}
|
||
prim.f00 = sp58[0];
|
||
prim.f02 = sp58[1];
|
||
prim.f04 = sp58[2];
|
||
prim.f06 = 0x399;
|
||
prim.f0A = 0;
|
||
prim.f08 = 0;
|
||
prim.f10 = s0;
|
||
prim.f0C = 0x7FFF;
|
||
func_8012C51C(&prim, s1);
|
||
}
|
||
}
|
||
}
|
||
|
||
i = 0;
|
||
s5v = (s32)sp58;
|
||
__asm__("addiu %0,%1,0x18" : "=r"(m) : "r"(D_800AF630)); // !FAKE: instruction addiu — NEEDED DIFFERS (P36 rung B tus10)
|
||
s7 = (s32)&flag;
|
||
fp = -0x1001;
|
||
base = (s32)D_800A6610 + (*(u16 *)&D_800B9A02 << 14);
|
||
|
||
for (i = 0; i < 9; i++) {
|
||
p = D_800A5E60;
|
||
D_800A5E60 = p + 0x14;
|
||
*(s8 *)(p + 3) = 4;
|
||
*(s32 *)(p + 4) = 0x808080;
|
||
*(s32 *)(p + 0xC) = 0x404040;
|
||
*(s8 *)(p + 7) = 0x52;
|
||
func_8012F14C((s32)sp18, (s32)(D_801A6C50 + i * 8), s5v);
|
||
gte_SetRotMatrix((void *)m);
|
||
gte_SetTransMatrix((void *)m);
|
||
gte_ldv0((void *)s5v);
|
||
gte_rtps();
|
||
gte_stsxy((void *)(p + 8));
|
||
gte_stflg((void *)s7);
|
||
gte_stszotz(&otz1);
|
||
if ((flag & fp) == 0) {
|
||
func_8012F14C((s32)sp38, (s32)(D_801A6C98 + i * 8), s5v);
|
||
gte_SetRotMatrix((void *)m);
|
||
gte_SetTransMatrix((void *)m);
|
||
gte_ldv0((void *)s5v);
|
||
gte_rtps();
|
||
gte_stsxy((void *)(p + 0x10));
|
||
gte_stflg((void *)s7);
|
||
gte_stszotz(&otz2);
|
||
if ((flag & fp) == 0) {
|
||
otz1 = (otz1 + otz2) >> 1;
|
||
otz1 = otz1 + 1;
|
||
if (otz1 >= 0x1000) {
|
||
otz1 = 0x1000;
|
||
}
|
||
s0 = D_800A5E60;
|
||
D_800A5E60 = s0 + 0xC;
|
||
func_8005A600(s0, 0, 0, 0x12A, 0);
|
||
e = (PTag293C *)(otz1 * 4 + base);
|
||
/* addPrim(e, p) */
|
||
((PTag293C *)p)->addr = e->addr;
|
||
e->addr = (u32)p;
|
||
/* addPrim(e, s0) */
|
||
((PTag293C *)s0)->addr = e->addr;
|
||
s0 = (s32)s0 & 0xFFFFFF;
|
||
*(s32 *)e = (*(s32 *)e & 0xFF000000) | s0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
extern u16 D_801A6914[]; /* source palette B (subtrahend) */
|
||
extern u16 D_801A6934[]; /* source palette A (minuend) */
|
||
|
||
/* stride-6 colour records; the three labels overlap (+0/+2/+4) but each
|
||
store must anchor its OWN symbol, hence three array decls */
|
||
|
||
extern Col6_801A2E20 D_801F43C4[];
|
||
extern Col6_801A2E20 D_801F43C6[];
|
||
extern Col6_801A2E20 D_801F43C8[];
|
||
|
||
void func_801A2E20(void)
|
||
{
|
||
u16 *a = D_801A6934;
|
||
u16 *b = D_801A6914;
|
||
s32 i;
|
||
|
||
for (i = 0; i < 16; i++) {
|
||
D_801F43C4[i].r = (*a & 0x1F) - (*b & 0x1F);
|
||
D_801F43C6[i].r = ((*a >> 5) & 0x1F) - ((*b >> 5) & 0x1F);
|
||
D_801F43C8[i].r = ((*a >> 10) & 0x1F) - ((*b >> 10) & 0x1F);
|
||
a++;
|
||
b++;
|
||
}
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
extern void func_800599B8(u16 *a0, u16 *a1);
|
||
extern u16 D_801A6914[];
|
||
extern u16 D_801A6CE0[];
|
||
extern u16 D_801F4424[];
|
||
|
||
|
||
|
||
extern Col6_801A2E20 D_801F43C4[];
|
||
extern Col6_801A2E20 D_801F43C6[];
|
||
extern Col6_801A2E20 D_801F43C8[];
|
||
|
||
void func_801A2EC8(void *a0)
|
||
{
|
||
u16 *dst = D_801F4424;
|
||
u16 *src = D_801A6914;
|
||
s32 i;
|
||
s32 j;
|
||
s32 fade;
|
||
|
||
if (!(*(s32 *)((s32)a0 + 0xE0) & 0x100)) {
|
||
fade = *(s32 *)((s32)a0 + 0xE8);
|
||
} else {
|
||
if (*(s32 *)((s32)a0 + 0xEC) <= 0) {
|
||
fade = 0;
|
||
*(s32 *)((s32)a0 + 0xEC) = 0x10000;
|
||
*(s32 *)((s32)a0 + 0xE0) &= ~0x100;
|
||
} else {
|
||
fade = (*(s32 *)((s32)a0 + 0xEC) -= 0x800);
|
||
}
|
||
}
|
||
|
||
i = 0;
|
||
j = 0;
|
||
do {
|
||
u16 w;
|
||
s32 t;
|
||
s32 r;
|
||
s32 g;
|
||
s32 b;
|
||
s32 c4 = *(s16 *)((u8 *)D_801F43C4 + j);
|
||
s32 c6 = *(s16 *)((u8 *)D_801F43C6 + j);
|
||
s32 c8;
|
||
|
||
i++;
|
||
c8 = *(s16 *)((u8 *)D_801F43C8 + j);
|
||
j += 6;
|
||
w = *src++;
|
||
|
||
r = (w & 0x1F) + ((c4 * fade) >> 16);
|
||
r &= 0x1F;
|
||
t = w << 16;
|
||
g = ((t >> 21) & 0x1F) + ((c6 * fade) >> 16);
|
||
g &= 0x1F;
|
||
b = ((t >> 26) & 0x1F) + ((c8 * fade) >> 16);
|
||
b &= 0x1F;
|
||
|
||
*dst++ = (u16)(r | ((b << 10) | (g << 5)));
|
||
} while (i < 16);
|
||
|
||
func_800599B8(D_801A6CE0, D_801F4424);
|
||
}
|
||
|
||
|
||
extern void func_8017F578(void);
|
||
void func_801A3014(void) {
|
||
func_8017F578();
|
||
}
|
||
|
||
|
||
extern void func_8017F004(void);
|
||
void func_801A3034(void) {
|
||
func_8017F004();
|
||
}
|
||
|
||
|
||
extern u16 D_80126B66;
|
||
extern u16 D_80126B5E;
|
||
extern s32 ratan2(s32 a0, s32 a1);
|
||
|
||
s32 func_801A3054(s32 s0, s32 a1, s32 s1) {
|
||
s32 v0;
|
||
s32 v1;
|
||
|
||
v0 = ratan2(*(s16 *)(a1 + 4) - *(s16 *)&D_80126B66,
|
||
*(s16 *)&D_80126B5E - *(s16 *)(a1 + 0));
|
||
v0 = ((v0 - 0x400) & 0xFFF) - *(s16 *)(*(s32 *)(s0 + 0x20) + 0x12);
|
||
v1 = v0 & 0xFFF;
|
||
if (v1 < 0x800) {
|
||
return v1 < (s16)s1;
|
||
}
|
||
return 0x1000 - v1 < (s16)s1;
|
||
}
|
||
|
||
|
||
extern void func_8018672C(int);
|
||
void func_801A30EC(void) {
|
||
func_8018672C(0x9);
|
||
}
|
||
|
||
|
||
extern void func_80186758(void);
|
||
void func_801A310C(void) {
|
||
func_80186758();
|
||
}
|
||
|
||
|
||
void func_801A312C(s32 a0) {
|
||
extern void func_8002D4C8(s32 a1, s32 a2);
|
||
|
||
if (*(s32 *)(a0 + 0x94) == 0xA) {
|
||
if ((*(s32 *)(a0 + 0x1C) & 1) == 0) {
|
||
func_8002D4C8(0xC31, 0);
|
||
} else {
|
||
func_8002D4C8(0xC32, 0);
|
||
}
|
||
*(s32 *)(a0 + 0x1C) = *(s32 *)(a0 + 0x1C) + 1;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
void func_801A3190(void *a0) {
|
||
|
||
extern void (*D_801A6D8C[])(void);
|
||
D_801A6D8C[*(u16 *)((s32)a0 + 0x2)]();
|
||
}
|
||
|
||
|
||
void func_801A31CC(void *arg0) {
|
||
s32 v0;
|
||
u8 *a1;
|
||
|
||
extern u8 D_801A6D58[];
|
||
extern s32 func_8012C1B8(void);
|
||
extern void func_8012CAE4(void *a0);
|
||
extern void func_8001C214(s32 a0, s32 a1);
|
||
|
||
*(s32 *)((u8 *)arg0 + 0x78) = (s32)D_801A6D58;
|
||
v0 = func_8012C1B8();
|
||
*(s32 *)((u8 *)arg0 + 0x20) = v0;
|
||
if (v0 == 0) {
|
||
func_8012CAE4(arg0);
|
||
return;
|
||
}
|
||
func_8001C214(v0, 0);
|
||
a1 = (u8 *)arg0 + 0xCC;
|
||
*(s32 *)((u8 *)arg0 + 0x58) = (s32)a1 | 0x50000000;
|
||
*(u8 *)((u8 *)arg0 + 0x75) = 2;
|
||
*(s32 *)((u8 *)arg0 + 0xF8) = *(s16 *)(*(s32 *)((u8 *)arg0 + 0x64) + 0x36);
|
||
switch (*(s16 *)((u8 *)arg0 + 0x70)) {
|
||
case 0: {
|
||
s32 link;
|
||
link = (s32)(a1 + 0x10);
|
||
*(s32 *)a1 = link;
|
||
a1 = (u8 *)link;
|
||
link = (s32)(a1 + 0x10);
|
||
*(s32 *)a1 = link;
|
||
__asm__ __volatile__("" : "=r"(link) : "0"(link)); // !FAKE: launder — NEEDED DIFFERS (P36 rung B tus10)
|
||
*(s32 *)link = 0;
|
||
*(u16 *)((u8 *)arg0 + 0x5C) = 0xC800;
|
||
*(s16 *)((u8 *)arg0 + 0xAE) = -1;
|
||
*(s16 *)((u8 *)arg0 + 0x2) = 1;
|
||
break;
|
||
}
|
||
case 1:
|
||
*(s16 *)((u8 *)arg0 + 0xAE) = -3;
|
||
*(u16 *)((u8 *)arg0 + 0x5C) = 0x8800;
|
||
*(s16 *)((u8 *)arg0 + 0x2) = 2;
|
||
break;
|
||
case 2:
|
||
*(u16 *)((u8 *)arg0 + 0x5C) = 0x8800;
|
||
*(s16 *)((u8 *)arg0 + 0xAE) = -0x10;
|
||
*(s16 *)((u8 *)arg0 + 0x2) = 3;
|
||
break;
|
||
case 3:
|
||
*(u16 *)((u8 *)arg0 + 0x5C) = 0xC000;
|
||
*(s16 *)((u8 *)arg0 + 0xAE) = -1;
|
||
*(s16 *)((u8 *)arg0 + 0x2) = 4;
|
||
break;
|
||
case 4:
|
||
*(u16 *)((u8 *)arg0 + 0x5C) = 0x800;
|
||
*(s16 *)((u8 *)arg0 + 0xAE) = -1;
|
||
*(s16 *)((u8 *)arg0 + 0x2) = 5;
|
||
*(s16 *)(a1 + 4) = -0x10;
|
||
*(s16 *)(a1 + 6) = 0x10;
|
||
*(s16 *)(a1 + 8) = -0x100;
|
||
*(s16 *)(a1 + 0xA) = 0;
|
||
*(s16 *)(a1 + 0xC) = -0x10;
|
||
*(s16 *)(a1 + 0xE) = 0x10;
|
||
break;
|
||
}
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
extern void func_8012C218(void *a0);
|
||
extern void func_801A38E4(void *a0, void *a1, s32 a2, s32 a3, s32 a4);
|
||
extern void func_801A3BCC(void *a0);
|
||
|
||
extern u16 D_801F43C0;
|
||
extern u8 D_801A6DA4[4];
|
||
|
||
void func_801A3334(void *a0) {
|
||
void *s1; /* the actor */
|
||
void *s2; /* linked actor @+0x64 */
|
||
void *s3; /* &s1->parts[0] (+0xCC), strides 0x10 */
|
||
s32 s4; /* part-id bias: -2 when D_801F43C0 == 0x11 */
|
||
s32 s5;
|
||
s32 i;
|
||
|
||
s1 = a0;
|
||
s3 = (u8 *)s1 + 0xCC;
|
||
s2 = *(void **)((u8 *)s1 + 0x64);
|
||
s4 = 0;
|
||
|
||
/* +0x00 is a u16 type tag; anything but 0x322 takes the generic path */
|
||
if (*(u16 *)s2 != 0x322) {
|
||
func_8012C218(a0);
|
||
return;
|
||
}
|
||
|
||
if (D_801F43C0 == 0x11) {
|
||
s4 = -2;
|
||
}
|
||
|
||
/* i = 0 must be the FIRST statement of the join block: reorg steals it into
|
||
the bne's delay slot, leaving `s5 = 1` at .L801A339C (§194 delay-slot steal). */
|
||
i = 0;
|
||
s5 = 1;
|
||
/* the s3 stride lives in the for-clause, AFTER i++ -- that ordering is what
|
||
puts the a3/lbu group ahead of `a1 = s3` in sched1's arg setup. */
|
||
for (; i < 3; i++, s3 = (u8 *)s3 + 0x10) {
|
||
func_801A38E4(s2, s3, D_801A6DA4[i] + s4, i, s5);
|
||
}
|
||
|
||
/* unaligned (align-1) 8-byte copy: (*(s1+0x20))[+0x10] = (*(s2+0x20))[+0x10] */
|
||
{
|
||
*(Vec8_md_SC07_003_801A3334 *)((u8 *)*(u32 *)((u8 *)s1 + 0x20) + 0x10) =
|
||
*(Vec8_md_SC07_003_801A3334 *)((u8 *)*(u32 *)((u8 *)s2 + 0x20) + 0x10);
|
||
}
|
||
|
||
*(s32 *)((u8 *)s1 + 0x4) = *(s32 *)((u8 *)s2 + 0x4);
|
||
*(s32 *)((u8 *)s1 + 0x8) = *(s32 *)((u8 *)s2 + 0x8);
|
||
*(s32 *)((u8 *)s1 + 0xC) = *(s32 *)((u8 *)s2 + 0xC);
|
||
|
||
if (*(s32 *)((u8 *)s2 + 0xE0) & 0x2) {
|
||
*(u16 *)((u8 *)s1 + 0x5C) = *(u16 *)((u8 *)s1 + 0x5C) & 0xF7FF;
|
||
func_801A3BCC(s1);
|
||
} else {
|
||
*(u16 *)((u8 *)s1 + 0x5C) = *(u16 *)((u8 *)s1 + 0x5C) | 0x0800;
|
||
}
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
/* Sibling shape: src/shared/engine_types.h:1337 `struct S80190C84` (0x14-byte
|
||
* spawn record: 8x s16 + trailing s32). Re-declared locally here since the
|
||
* include path for src/shared/ isn't reachable from this standalone draft. */
|
||
|
||
/* decl_prior (card func_801A3490): modal fleet spellings adopted verbatim. */
|
||
extern void func_8012E9C0(s32 a0);
|
||
extern void func_8002A520(s32 a0);
|
||
extern void func_8002A790(s32 a0);
|
||
extern void func_8002D4C8(s32 a0, s32 a1);
|
||
extern s32 func_8012C51C(void *a0, s32 a1);
|
||
extern void func_8012C218(void *a0);
|
||
|
||
/* No fleet data for these two (only referenced inside this TU, itself still
|
||
* unmatched) -- typed by access width per law 2's fallback. Kept s32 (not
|
||
* void*) so `p` never forms a pointer-typed value: a void* cast on the
|
||
* cross-branch-live `p` forces gcc-2.7.2 to materialize a SECOND pseudo
|
||
* (an extra callee-saved reg, observed as a stray `move $s2,$s0`). */
|
||
extern void func_801A38E4(void *a0, void *a1, s32 a2, s32 a3, s32 a4);
|
||
extern u16 D_801F43C0;
|
||
|
||
/* Sibling shape: an 8-byte, align-2 vector -- same idiom as func_80131340's
|
||
* `struct V8` (lwl/lwr + swl/swr unaligned block move, cookbook S48-C2). */
|
||
|
||
void func_801A3490(s32 p)
|
||
{
|
||
s32 linked;
|
||
s32 pCC;
|
||
|
||
pCC = p + 0xCC;
|
||
linked = *(s32 *)(p + 0x64);
|
||
|
||
if (*(u16 *)(p + 0x5C) & 1) {
|
||
s32 tbl;
|
||
s32 dec;
|
||
|
||
*(u16 *)(p + 0x60) = 0x280;
|
||
func_8012E9C0(p);
|
||
|
||
if (*(u16 *)(p + 0x5E) != 0x1D) {
|
||
if (*(u8 *)(p + 0xC8)) func_8002A520(p);
|
||
if (*(u8 *)(p + 0xC9)) func_8002A790(p);
|
||
}
|
||
|
||
tbl = *(s32 *)(p + 0x78);
|
||
dec = ((s32)*(s16 *)(p + 0x60) * (s32)*(s16 *)(tbl + 0x30)) >> 12;
|
||
if (dec <= 0) {
|
||
dec = 1;
|
||
}
|
||
|
||
{
|
||
s16 t = *(u16 *)(linked + 0x76) - dec;
|
||
*(s16 *)(linked + 0x76) = t;
|
||
if (t < 0) {
|
||
*(s16 *)(linked + 0x76) = 0;
|
||
}
|
||
}
|
||
|
||
*(s32 *)(linked + 0xE0) |= 0x20;
|
||
func_8002D4C8(0xB9F, 0);
|
||
|
||
{
|
||
struct S80190C84 sp;
|
||
sp.f0 = *(u16 *)(p + 0x7C);
|
||
sp.f2 = *(u16 *)(p + 0x7E);
|
||
sp.f4 = *(u16 *)(p + 0x80);
|
||
sp.f6 = 0x3D5;
|
||
sp.fA = 0;
|
||
sp.f8 = 0;
|
||
sp.f10 = 0;
|
||
sp.fE = 0;
|
||
sp.fC = 0x7FFF;
|
||
func_8012C51C(&sp, p);
|
||
}
|
||
|
||
func_8012C218((void *)p);
|
||
} else {
|
||
func_801A38E4((void *)linked, (void *)pCC, (s32)D_801F43C0, 3, 1);
|
||
|
||
*(V8_md_SC07_003 *)(*(s32 *)(p + 0x20) + 0x10) =
|
||
*(V8_md_SC07_003 *)(*(s32 *)(linked + 0x20) + 0x10);
|
||
|
||
*(s32 *)(p + 4) = *(s32 *)(linked + 4);
|
||
*(s32 *)(p + 8) = *(s32 *)(linked + 8);
|
||
*(s32 *)(p + 0xC) = *(s32 *)(linked + 0xC);
|
||
}
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
extern s32 func_8012BEE8(s32 a0);
|
||
extern void func_8002D4C8(s32 a0, s32 a1);
|
||
extern void func_801A43E8(void *a0);
|
||
extern void func_801A38E4(void *a0, void *a1, s32 a2, s32 a3, s32 a4);
|
||
extern u16 D_801F43C0;
|
||
|
||
/* Entity/effect-slot per-frame update. s1 = the linked slot *(s0+0x64).
|
||
*
|
||
* Clears the "just spawned" bit (0x5C bit0); if the entity has not already
|
||
* latched a state (0x1C == 0) and the linked slot is neither timed-out
|
||
* (*(s1+0xE8) <= 0xFFFF, signed) nor blocked ((*(s1+0xE0) & 0x140) == 0),
|
||
* runs the setup callback func_801A43E8, re-tags the linked slot
|
||
* (0x2 = 0x15, 0xE0 = (v|1) & ~2, 0x5C |= 0x800), latches this entity's own
|
||
* state (0x1C = 0x14) and fires two sound/queue events via func_8002D4C8.
|
||
* 0x5E is always cleared on the spawn frame.
|
||
*
|
||
* Then unconditionally forwards to func_801A38E4(slot, s0+0xCC, D_801F43C0,
|
||
* 5, 1), copies an 8-byte align-1 block (lwl/lwr/swl/swr — cookbook §160a
|
||
* Blk8) from *(s1+0x20)+0x10 to *(s0+0x20)+0x10, and mirrors the three s32
|
||
* fields 0x4/0x8/0xC from the slot onto this entity.
|
||
*
|
||
* S54 second pass: the first draft's only residual was a 7-instruction
|
||
* reorder around the 0xE0 / 0x5C read-modify-writes. It was NOT a hoist that
|
||
* needed a fence — it was §190-B. The first draft wrote the 0x5C update
|
||
* before the 0xE0 update; the target's interleave (lw 0xE0 and the -0x3
|
||
* constant floating above the 0x2 store, the 0xE0 store sinking below the
|
||
* 0x5C store, and -0x3 landing in $a2 rather than $v0) is exactly what sched1
|
||
* produces from the PLAIN natural order 0x2 -> 0xE0 -> 0x5C -> 0x1C. Swapping
|
||
* the two RMW statements back into that order matches byte-for-byte with no
|
||
* fence, no pin and no temp.
|
||
*/
|
||
void func_801A3638(void *a0) {
|
||
void *s0 = a0;
|
||
void *s1;
|
||
void *s2;
|
||
u16 flags;
|
||
|
||
s1 = *(void **)((u8 *)s0 + 0x64);
|
||
func_8012BEE8((s32)s0);
|
||
s2 = (u8 *)s0 + 0xCC;
|
||
|
||
flags = *(u16 *)((u8 *)s0 + 0x5C);
|
||
if (flags & 1) {
|
||
*(u16 *)((u8 *)s0 + 0x5C) = flags & 0xFFFE;
|
||
if (*(s32 *)((u8 *)s0 + 0x1C) == 0
|
||
&& *(s32 *)((u8 *)s1 + 0xE8) <= 0xFFFF
|
||
&& (*(s32 *)((u8 *)s1 + 0xE0) & 0x140) == 0) {
|
||
func_801A43E8(s0);
|
||
*(u16 *)((u8 *)s1 + 0x2) = 0x15;
|
||
*(s32 *)((u8 *)s1 + 0xE0) = (*(s32 *)((u8 *)s1 + 0xE0) | 1) & ~2;
|
||
*(u16 *)((u8 *)s1 + 0x5C) |= 0x800;
|
||
*(s32 *)((u8 *)s0 + 0x1C) = 0x14;
|
||
func_8002D4C8(4, 0xB79);
|
||
func_8002D4C8(4, 0xB56);
|
||
}
|
||
*(u16 *)((u8 *)s0 + 0x5E) = 0;
|
||
}
|
||
|
||
func_801A38E4(s1, s2, D_801F43C0, 5, 1);
|
||
|
||
{
|
||
void *dst = *(void **)((u8 *)s0 + 0x20);
|
||
void *src = *(void **)((u8 *)s1 + 0x20);
|
||
|
||
*(Blk8_md_SC07_003_801A3638 *)((u8 *)dst + 0x10) = *(Blk8_md_SC07_003_801A3638 *)((u8 *)src + 0x10);
|
||
}
|
||
|
||
*(s32 *)((u8 *)s0 + 0x4) = *(s32 *)((u8 *)s1 + 0x4);
|
||
*(s32 *)((u8 *)s0 + 0x8) = *(s32 *)((u8 *)s1 + 0x8);
|
||
*(s32 *)((u8 *)s0 + 0xC) = *(s32 *)((u8 *)s1 + 0xC);
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
extern void func_8012C218(void *a0);
|
||
extern void func_801A38E4(void *a0, void *a1, s32 a2, s32 a3, s32 a4);
|
||
extern s32 func_801A419C(s32 a0);
|
||
extern s32 func_80153BD8(s32 a0);
|
||
|
||
/* 8-byte, align-2 quad of s16 */
|
||
|
||
void func_801A3788(void *arg0) {
|
||
u16 s0;
|
||
s32 s1;
|
||
u16 v1;
|
||
s32 v1s;
|
||
s32 pad[8];
|
||
|
||
s1 = *(s32 *)(arg0 + 0x64);
|
||
|
||
if (*(s16 *)(s1 + 0x36) != *(s32 *)(arg0 + 0xF8)) {
|
||
func_8012C218((void *)arg0);
|
||
return;
|
||
}
|
||
|
||
func_801A38E4((void *)s1, (void *)(arg0 + 0xCC), 0x10, 6, 0);
|
||
|
||
*(V8x_801A3788 *)(*(s32 *)(arg0 + 0x20) + 0x10) = *(V8x_801A3788 *)(*(s32 *)(s1 + 0x20) + 0x10);
|
||
|
||
*(s32 *)(arg0 + 0x4) = *(s32 *)(s1 + 0x4);
|
||
*(s32 *)(arg0 + 0x8) = *(s32 *)(s1 + 0x8);
|
||
*(s32 *)(arg0 + 0xC) = *(s32 *)(s1 + 0xC);
|
||
|
||
v1 = *(u16 *)(arg0 + 0x34);
|
||
|
||
switch (v1) {
|
||
default:
|
||
v1s = v1;
|
||
if (v1s < 2) {
|
||
if (v1 != 0) {
|
||
break;
|
||
}
|
||
if (func_801A419C(arg0) == 1) {
|
||
(*(u16 *)(arg0 + 0x34))++;
|
||
}
|
||
}
|
||
break;
|
||
case 1:
|
||
if (func_80153BD8(arg0) != 0) {
|
||
*(s32 *)(s1 + 0xE0) |= 8;
|
||
}
|
||
(*(u16 *)(arg0 + 0x34))++;
|
||
break;
|
||
}
|
||
}
|
||
|
||
|
||
extern void func_8012C218(void *a0);
|
||
|
||
void func_801A38A8(s32 arg0) {
|
||
if (*(u32 *)(*(u32 *)(arg0 + 0x64) + 0xE0) & 0x10) {
|
||
func_8012C218((void *)arg0);
|
||
}
|
||
}
|
||
|
||
|
||
/*
|
||
* func_801A38E4 (md_SC07_003, 0x801A38E4, 186 ins) == MATCH, byte-exact.
|
||
*
|
||
* Rotates one of D_801A6CE8's 16-byte bounding-box records into view space and
|
||
* writes the six min/max halfwords at +4..+0xE of the caller's record. a4 == 0
|
||
* takes the three-axis path (each axis is fed through RotTransSV as a lone
|
||
* non-zero component); a4 != 0 rotates the two corner SVECTORs directly.
|
||
*
|
||
* Frame 0xC8: 0x10 MATRIX m, 0x30/0x38 sv0/sv1, 0x40/0x48 o0/o1, 0x50 flag,
|
||
* 0x58..0xB8 = 12 combine-orphaned sign-extend slots (§147-B as CORRECTED in
|
||
* P30 S43 — 2 per min/max block x 6 blocks, 8 bytes each). NO dead local is
|
||
* needed: writing the six blocks in the shape below produces the hole for free.
|
||
*
|
||
* LEVERS (each verified by reverting it and re-scoring with match_one):
|
||
* 1. NO `s16 *out` LOCAL — the six pairs index the parameter as
|
||
* `((s16 *)a1)[k]`. Binding a1 to a local makes `addu $s1,$a1,$zero` an
|
||
* ordinary body insn that sched1 sinks below the D_801A6CE8 address chain
|
||
* (target: sw $s1 / addu $s1 at idx 1-2, draft: idx 6-7). As a parameter
|
||
* copy it is an assign_parms insn and stays at the top. 7 -> 0.
|
||
* 2. The compare is spelled `o0.f > o1.f`, NOT `o1.f < o0.f`. Both fold to
|
||
* `slt $v0,$v0,$v1`, but the `>` form evaluates o0 first, so the target's
|
||
* `lh 0x40 ; lh 0x48 ; nop` load-delay nop appears (the `<` form fills that
|
||
* slot with the second load and loses 8 instructions across the 6 blocks).
|
||
* 3. Each SVECTOR is filled VALUE FIRST, then the two zeroed components in
|
||
* DESCENDING field order (vz before vy before vx). sched1 hoists the `lhu`
|
||
* and sinks its dependent `sh`, so the emitted order is
|
||
* lhu / zero / zero / value — source order any other way transposes the two
|
||
* `sh $zero` or floats one above the `lhu`.
|
||
* 4. Arm B's second corner needs `q = p; p += 4;` BEFORE the first call.
|
||
* `RotTransSV((s32)(p + 4), ...)` after it folds into `addiu $a0,$s2,8`
|
||
* (-1 instruction); the copy-then-bump form is what emits the target's
|
||
* `addu $a0,$s2,$zero` (branch delay slot) + `addiu $s2,$s2,8`.
|
||
*
|
||
* SYMBOL AUDIT (law 1c, after MATCH) — every symbol re-checked against the
|
||
* relocation lines of asm/md_SC07_003/nonmatchings/md_SC07_003/func_801A38E4.s:
|
||
* 1x jal func_8012EA90 (a0, a2, &m) · 8x jal RotTransSV (6 in arm A,
|
||
* 2 in arm B) · one %hi/%lo pair, D_801A6CE8. No other relocation exists
|
||
* in the target.
|
||
*
|
||
* BANK NOTE (law 2): src/md_SC07_003/md_SC07_003.c already prototypes
|
||
* `extern void func_801A38E4(void *a0, void *a1, s32 a2, s32 a3, s32 a4);`
|
||
* (4x, all above the INCLUDE_ASM) — the definition below is spelled to match it
|
||
* exactly, which is what the last gate rejected. `RotTransSV` and the two
|
||
* gte_Set*Matrix macros are copied VERBATIM from the same TU; D_801A6CE8 and
|
||
* func_8012EA90 are declared nowhere in it, so those two are free-standing
|
||
* (func_8012EA90 follows the fleet-modal `(void, (s32, s32, s32*))`).
|
||
*/
|
||
#include "common.h"
|
||
|
||
|
||
extern void func_8012EA90(s32 a0, s32 a1, s32 *a2);
|
||
extern void RotTransSV(s32 a0, s32 a1, void *a2);
|
||
extern u8 D_801A6CE8[];
|
||
|
||
|
||
void func_801A38E4(void *a0, void *a1, s32 a2, s32 a3, s32 a4)
|
||
{
|
||
s32 m[8];
|
||
SVec801A38E4 sv0;
|
||
SVec801A38E4 sv1;
|
||
SVec801A38E4 o0;
|
||
SVec801A38E4 o1;
|
||
s32 flag;
|
||
u16 *p;
|
||
u16 *q;
|
||
|
||
p = (u16 *)(D_801A6CE8 + (a3 << 4));
|
||
|
||
func_8012EA90((s32)a0, a2, m);
|
||
gte_SetRotMatrix(m);
|
||
gte_SetTransMatrix(m);
|
||
|
||
if (a4 == 0) {
|
||
sv0.vx = p[0];
|
||
sv0.vz = 0;
|
||
sv0.vy = 0;
|
||
sv1.vx = p[4];
|
||
sv1.vz = 0;
|
||
sv1.vy = 0;
|
||
RotTransSV((s32)&sv0, (s32)&o0, &flag);
|
||
RotTransSV((s32)&sv1, (s32)&o1, &flag);
|
||
if (o0.vx > o1.vx) {
|
||
((s16 *)a1)[3] = o0.vx;
|
||
((s16 *)a1)[2] = o1.vx;
|
||
} else {
|
||
((s16 *)a1)[3] = o1.vx;
|
||
((s16 *)a1)[2] = o0.vx;
|
||
}
|
||
|
||
sv0.vy = p[1];
|
||
sv0.vz = 0;
|
||
sv0.vx = 0;
|
||
sv1.vy = p[5];
|
||
sv1.vz = 0;
|
||
sv1.vx = 0;
|
||
RotTransSV((s32)&sv0, (s32)&o0, &flag);
|
||
RotTransSV((s32)&sv1, (s32)&o1, &flag);
|
||
if (o0.vy > o1.vy) {
|
||
((s16 *)a1)[5] = o0.vy;
|
||
((s16 *)a1)[4] = o1.vy;
|
||
} else {
|
||
((s16 *)a1)[5] = o1.vy;
|
||
((s16 *)a1)[4] = o0.vy;
|
||
}
|
||
|
||
sv0.vz = p[2];
|
||
sv0.vy = 0;
|
||
sv0.vx = 0;
|
||
sv1.vz = p[6];
|
||
sv1.vy = 0;
|
||
sv1.vx = 0;
|
||
RotTransSV((s32)&sv0, (s32)&o0, &flag);
|
||
RotTransSV((s32)&sv1, (s32)&o1, &flag);
|
||
if (o0.vz > o1.vz) {
|
||
((s16 *)a1)[7] = o0.vz;
|
||
((s16 *)a1)[6] = o1.vz;
|
||
} else {
|
||
((s16 *)a1)[7] = o1.vz;
|
||
((s16 *)a1)[6] = o0.vz;
|
||
}
|
||
} else {
|
||
q = p;
|
||
p += 4;
|
||
RotTransSV((s32)q, (s32)&o0, &flag);
|
||
RotTransSV((s32)p, (s32)&o1, &flag);
|
||
if (o0.vx > o1.vx) {
|
||
((s16 *)a1)[3] = o0.vx;
|
||
((s16 *)a1)[2] = o1.vx;
|
||
} else {
|
||
((s16 *)a1)[3] = o1.vx;
|
||
((s16 *)a1)[2] = o0.vx;
|
||
}
|
||
if (o0.vy > o1.vy) {
|
||
((s16 *)a1)[5] = o0.vy;
|
||
((s16 *)a1)[4] = o1.vy;
|
||
} else {
|
||
((s16 *)a1)[5] = o1.vy;
|
||
((s16 *)a1)[4] = o0.vy;
|
||
}
|
||
if (o0.vz > o1.vz) {
|
||
((s16 *)a1)[7] = o0.vz;
|
||
((s16 *)a1)[6] = o1.vz;
|
||
} else {
|
||
((s16 *)a1)[7] = o1.vz;
|
||
((s16 *)a1)[6] = o0.vz;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
void func_801A3BCC(void *a0)
|
||
{
|
||
__asm__ __volatile__( // !FAKE: asm-body .set — DEFERRED T7 (P36 rung B tus10)
|
||
".set\tnoreorder\n"
|
||
"addiu $29, $29, -312\n"
|
||
"sw $23, 300($29)\n"
|
||
"addu $23, $4, $0\n"
|
||
"sw $31, 308($29)\n"
|
||
"sw $30, 304($29)\n"
|
||
"sw $22, 296($29)\n"
|
||
"sw $21, 292($29)\n"
|
||
"sw $20, 288($29)\n"
|
||
"sw $19, 284($29)\n"
|
||
"sw $18, 280($29)\n"
|
||
"sw $17, 276($29)\n"
|
||
"sw $16, 272($29)\n"
|
||
"lw $16, 100($23)\n"
|
||
"nop\n"
|
||
"lw $2, 32($16)\n"
|
||
"nop\n"
|
||
"lhu $2, 16($2)\n"
|
||
"nop\n"
|
||
"sh $2, 40($29)\n"
|
||
"lw $2, 32($16)\n"
|
||
"nop\n"
|
||
"lhu $2, 18($2)\n"
|
||
"nop\n"
|
||
"sh $2, 42($29)\n"
|
||
"lw $2, 32($16)\n"
|
||
"lui $30, %hi(D_80126B58)\n"
|
||
"addiu $30, $30, %lo(D_80126B58)\n"
|
||
"lhu $2, 20($2)\n"
|
||
"addiu $5, $0, 10\n"
|
||
"sh $2, 44($29)\n"
|
||
"lw $2, 32($16)\n"
|
||
"addiu $6, $29, 80\n"
|
||
"lw $2, 72($2)\n"
|
||
"addu $21, $0, $0\n"
|
||
"sw $2, 68($29)\n"
|
||
"lw $2, 32($16)\n"
|
||
"addiu $19, $29, 48\n"
|
||
"lw $2, 76($2)\n"
|
||
"addiu $22, $29, 176\n"
|
||
"sw $2, 72($29)\n"
|
||
"lw $2, 32($16)\n"
|
||
"addiu $20, $29, 32\n"
|
||
"lw $2, 80($2)\n"
|
||
"addu $4, $16, $0\n"
|
||
"jal func_8012EA90\n"
|
||
"sw $2, 76($29)\n"
|
||
"addu $4, $16, $0\n"
|
||
"addiu $5, $0, 11\n"
|
||
"jal func_8012EA90\n"
|
||
"addiu $6, $29, 112\n"
|
||
"addu $4, $16, $0\n"
|
||
"addiu $5, $0, 12\n"
|
||
"jal func_8012EA90\n"
|
||
"addiu $6, $29, 144\n"
|
||
"addiu $4, $29, 40\n"
|
||
"9:\n"
|
||
"lui $3, %hi(D_801F435C)\n"
|
||
"lh $3, %lo(D_801F435C)($3)\n"
|
||
"addu $5, $19, $0\n"
|
||
"negu $3, $3\n"
|
||
"sll $2, $3, 3\n"
|
||
"addu $2, $2, $3\n"
|
||
"lhu $3, 42($29)\n"
|
||
"sll $2, $2, 1\n"
|
||
"addu $3, $3, $2\n"
|
||
"jal func_80049CAC\n"
|
||
"sh $3, 42($29)\n"
|
||
"lw $12, 0($19)\n"
|
||
"lw $13, 4($19)\n"
|
||
"ctc2 $12, $0\n"
|
||
"ctc2 $13, $1\n"
|
||
"lw $12, 8($19)\n"
|
||
"lw $13, 12($19)\n"
|
||
"lw $14, 16($19)\n"
|
||
"ctc2 $12, $2\n"
|
||
"ctc2 $13, $3\n"
|
||
"ctc2 $14, $4\n"
|
||
"addiu $2, $29, 80\n"
|
||
"lhu $12, 0($2)\n"
|
||
"lhu $13, 6($2)\n"
|
||
"lhu $14, 12($2)\n"
|
||
"mtc2 $12, $9\n"
|
||
"mtc2 $13, $10\n"
|
||
"mtc2 $14, $11\n"
|
||
"nop\n"
|
||
"nop\n"
|
||
"mvmva 1, 0, 3, 3, 0\n"
|
||
"mfc2 $12, $9\n"
|
||
"mfc2 $13, $10\n"
|
||
"mfc2 $14, $11\n"
|
||
"sh $12, 0($22)\n"
|
||
"sh $13, 6($22)\n"
|
||
"sh $14, 12($22)\n"
|
||
"addiu $2, $29, 82\n"
|
||
"lhu $12, 0($2)\n"
|
||
"lhu $13, 6($2)\n"
|
||
"lhu $14, 12($2)\n"
|
||
"mtc2 $12, $9\n"
|
||
"mtc2 $13, $10\n"
|
||
"mtc2 $14, $11\n"
|
||
"nop\n"
|
||
"nop\n"
|
||
"mvmva 1, 0, 3, 3, 0\n"
|
||
"addiu $2, $29, 178\n"
|
||
"mfc2 $12, $9\n"
|
||
"mfc2 $13, $10\n"
|
||
"mfc2 $14, $11\n"
|
||
"sh $12, 0($2)\n"
|
||
"sh $13, 6($2)\n"
|
||
"sh $14, 12($2)\n"
|
||
"addiu $2, $29, 84\n"
|
||
"lhu $12, 0($2)\n"
|
||
"lhu $13, 6($2)\n"
|
||
"lhu $14, 12($2)\n"
|
||
"mtc2 $12, $9\n"
|
||
"mtc2 $13, $10\n"
|
||
"mtc2 $14, $11\n"
|
||
"nop\n"
|
||
"nop\n"
|
||
"mvmva 1, 0, 3, 3, 0\n"
|
||
"addiu $2, $29, 180\n"
|
||
"mfc2 $12, $9\n"
|
||
"mfc2 $13, $10\n"
|
||
"mfc2 $14, $11\n"
|
||
"sh $12, 0($2)\n"
|
||
"sh $13, 6($2)\n"
|
||
"sh $14, 12($2)\n"
|
||
"lw $12, 20($19)\n"
|
||
"lw $13, 24($19)\n"
|
||
"ctc2 $12, $5\n"
|
||
"lw $14, 28($19)\n"
|
||
"ctc2 $13, $6\n"
|
||
"ctc2 $14, $7\n"
|
||
"addiu $2, $29, 100\n"
|
||
"lhu $13, 4($2)\n"
|
||
"lhu $12, 0($2)\n"
|
||
"sll $13, $13, 16\n"
|
||
"or $12, $12, $13\n"
|
||
"mtc2 $12, $0\n"
|
||
"lwc2 $1, 8($2)\n"
|
||
"nop\n"
|
||
"nop\n"
|
||
"mvmva 1, 0, 0, 0, 0\n"
|
||
"addiu $2, $29, 196\n"
|
||
"swc2 $25, 0($2)\n"
|
||
"swc2 $26, 4($2)\n"
|
||
"swc2 $27, 8($2)\n"
|
||
"lw $12, 0($19)\n"
|
||
"lw $13, 4($19)\n"
|
||
"ctc2 $12, $0\n"
|
||
"ctc2 $13, $1\n"
|
||
"lw $12, 8($19)\n"
|
||
"lw $13, 12($19)\n"
|
||
"lw $14, 16($19)\n"
|
||
"ctc2 $12, $2\n"
|
||
"ctc2 $13, $3\n"
|
||
"ctc2 $14, $4\n"
|
||
"addiu $2, $29, 112\n"
|
||
"lhu $12, 0($2)\n"
|
||
"lhu $13, 6($2)\n"
|
||
"lhu $14, 12($2)\n"
|
||
"mtc2 $12, $9\n"
|
||
"mtc2 $13, $10\n"
|
||
"mtc2 $14, $11\n"
|
||
"nop\n"
|
||
"nop\n"
|
||
"mvmva 1, 0, 3, 3, 0\n"
|
||
"addiu $2, $29, 208\n"
|
||
"mfc2 $12, $9\n"
|
||
"mfc2 $13, $10\n"
|
||
"mfc2 $14, $11\n"
|
||
"sh $12, 0($2)\n"
|
||
"sh $13, 6($2)\n"
|
||
"sh $14, 12($2)\n"
|
||
"addiu $2, $29, 114\n"
|
||
"lhu $12, 0($2)\n"
|
||
"lhu $13, 6($2)\n"
|
||
"lhu $14, 12($2)\n"
|
||
"mtc2 $12, $9\n"
|
||
"mtc2 $13, $10\n"
|
||
"mtc2 $14, $11\n"
|
||
"nop\n"
|
||
"nop\n"
|
||
"mvmva 1, 0, 3, 3, 0\n"
|
||
"addiu $2, $29, 210\n"
|
||
"mfc2 $12, $9\n"
|
||
"mfc2 $13, $10\n"
|
||
"mfc2 $14, $11\n"
|
||
"sh $12, 0($2)\n"
|
||
"sh $13, 6($2)\n"
|
||
"sh $14, 12($2)\n"
|
||
"addiu $2, $29, 116\n"
|
||
"lhu $12, 0($2)\n"
|
||
"lhu $13, 6($2)\n"
|
||
"lhu $14, 12($2)\n"
|
||
"mtc2 $12, $9\n"
|
||
"mtc2 $13, $10\n"
|
||
"mtc2 $14, $11\n"
|
||
"nop\n"
|
||
"nop\n"
|
||
"mvmva 1, 0, 3, 3, 0\n"
|
||
"addiu $2, $29, 212\n"
|
||
"mfc2 $12, $9\n"
|
||
"mfc2 $13, $10\n"
|
||
"mfc2 $14, $11\n"
|
||
"sh $12, 0($2)\n"
|
||
"sh $13, 6($2)\n"
|
||
"sh $14, 12($2)\n"
|
||
"lw $12, 20($19)\n"
|
||
"lw $13, 24($19)\n"
|
||
"ctc2 $12, $5\n"
|
||
"lw $14, 28($19)\n"
|
||
"ctc2 $13, $6\n"
|
||
"ctc2 $14, $7\n"
|
||
"addiu $2, $29, 132\n"
|
||
"lhu $13, 4($2)\n"
|
||
"lhu $12, 0($2)\n"
|
||
"sll $13, $13, 16\n"
|
||
"or $12, $12, $13\n"
|
||
"mtc2 $12, $0\n"
|
||
"lwc2 $1, 8($2)\n"
|
||
"nop\n"
|
||
"nop\n"
|
||
"mvmva 1, 0, 0, 0, 0\n"
|
||
"addiu $2, $29, 228\n"
|
||
"swc2 $25, 0($2)\n"
|
||
"swc2 $26, 4($2)\n"
|
||
"swc2 $27, 8($2)\n"
|
||
"lw $12, 0($19)\n"
|
||
"lw $13, 4($19)\n"
|
||
"ctc2 $12, $0\n"
|
||
"ctc2 $13, $1\n"
|
||
"lw $12, 8($19)\n"
|
||
"lw $13, 12($19)\n"
|
||
"lw $14, 16($19)\n"
|
||
"ctc2 $12, $2\n"
|
||
"ctc2 $13, $3\n"
|
||
"ctc2 $14, $4\n"
|
||
"addiu $2, $29, 144\n"
|
||
"lhu $12, 0($2)\n"
|
||
"lhu $13, 6($2)\n"
|
||
"lhu $14, 12($2)\n"
|
||
"mtc2 $12, $9\n"
|
||
"mtc2 $13, $10\n"
|
||
"mtc2 $14, $11\n"
|
||
"nop\n"
|
||
"nop\n"
|
||
"mvmva 1, 0, 3, 3, 0\n"
|
||
"addiu $2, $29, 240\n"
|
||
"mfc2 $12, $9\n"
|
||
"mfc2 $13, $10\n"
|
||
"mfc2 $14, $11\n"
|
||
"sh $12, 0($2)\n"
|
||
"sh $13, 6($2)\n"
|
||
"sh $14, 12($2)\n"
|
||
"addiu $2, $29, 146\n"
|
||
"lhu $12, 0($2)\n"
|
||
"lhu $13, 6($2)\n"
|
||
"lhu $14, 12($2)\n"
|
||
"mtc2 $12, $9\n"
|
||
"mtc2 $13, $10\n"
|
||
"mtc2 $14, $11\n"
|
||
"nop\n"
|
||
"nop\n"
|
||
"mvmva 1, 0, 3, 3, 0\n"
|
||
"addiu $2, $29, 242\n"
|
||
"mfc2 $12, $9\n"
|
||
"mfc2 $13, $10\n"
|
||
"mfc2 $14, $11\n"
|
||
"sh $12, 0($2)\n"
|
||
"sh $13, 6($2)\n"
|
||
"sh $14, 12($2)\n"
|
||
"addiu $2, $29, 148\n"
|
||
"lhu $12, 0($2)\n"
|
||
"lhu $13, 6($2)\n"
|
||
"lhu $14, 12($2)\n"
|
||
"mtc2 $12, $9\n"
|
||
"mtc2 $13, $10\n"
|
||
"mtc2 $14, $11\n"
|
||
"nop\n"
|
||
"nop\n"
|
||
"mvmva 1, 0, 3, 3, 0\n"
|
||
"addiu $2, $29, 244\n"
|
||
"mfc2 $12, $9\n"
|
||
"mfc2 $13, $10\n"
|
||
"mfc2 $14, $11\n"
|
||
"sh $12, 0($2)\n"
|
||
"sh $13, 6($2)\n"
|
||
"sh $14, 12($2)\n"
|
||
"lw $12, 20($19)\n"
|
||
"lw $13, 24($19)\n"
|
||
"ctc2 $12, $5\n"
|
||
"lw $14, 28($19)\n"
|
||
"ctc2 $13, $6\n"
|
||
"ctc2 $14, $7\n"
|
||
"addiu $2, $29, 164\n"
|
||
"lhu $13, 4($2)\n"
|
||
"lhu $12, 0($2)\n"
|
||
"sll $13, $13, 16\n"
|
||
"or $12, $12, $13\n"
|
||
"mtc2 $12, $0\n"
|
||
"lwc2 $1, 8($2)\n"
|
||
"nop\n"
|
||
"nop\n"
|
||
"mvmva 1, 0, 0, 0, 0\n"
|
||
"addiu $2, $29, 260\n"
|
||
"swc2 $25, 0($2)\n"
|
||
"swc2 $26, 4($2)\n"
|
||
"swc2 $27, 8($2)\n"
|
||
"lui $18, %hi(D_801A6DA8)\n"
|
||
"addiu $18, $18, %lo(D_801A6DA8)\n"
|
||
"addu $17, $0, $0\n"
|
||
"8:\n"
|
||
"lui $2, 21845\n"
|
||
"ori $2, $2, 21846\n"
|
||
"mult $17, $2\n"
|
||
"addu $5, $18, $0\n"
|
||
"addiu $6, $29, 24\n"
|
||
"sra $16, $17, 31\n"
|
||
"mfhi $8\n"
|
||
"subu $16, $8, $16\n"
|
||
"sll $16, $16, 5\n"
|
||
"addu $16, $22, $16\n"
|
||
"jal func_8012F14C\n"
|
||
"addu $4, $16, $0\n"
|
||
"addu $4, $16, $0\n"
|
||
"addiu $5, $18, 8\n"
|
||
"jal func_8012F14C\n"
|
||
"addu $6, $20, $0\n"
|
||
"addiu $6, $29, 24\n"
|
||
"lw $4, 32($30)\n"
|
||
"lw $5, 56($30)\n"
|
||
"jal func_80135888\n"
|
||
"addu $7, $20, $0\n"
|
||
"beqz $2, 7f\n"
|
||
"addiu $17, $17, 1\n"
|
||
"addiu $4, $0, 1\n"
|
||
"addiu $5, $0, 16411\n"
|
||
"addiu $7, $0, 128\n"
|
||
"lw $2, 32($23)\n"
|
||
"lui $3, %hi(D_801F435C)\n"
|
||
"lh $3, %lo(D_801F435C)($3)\n"
|
||
"lh $6, 18($2)\n"
|
||
"lui $2, %hi(D_801152A8)\n"
|
||
"addiu $2, $2, %lo(D_801152A8)\n"
|
||
"sll $3, $3, 10\n"
|
||
"sw $20, 16($29)\n"
|
||
"sw $2, 20($29)\n"
|
||
"subu $6, $6, $3\n"
|
||
"jal func_8012F568\n"
|
||
"andi $6, $6, 4095\n"
|
||
"j 6f\n"
|
||
"addiu $2, $0, 1\n"
|
||
"7:\n"
|
||
"slti $2, $17, 9\n"
|
||
"bnez $2, 8b\n"
|
||
"addiu $18, $18, 16\n"
|
||
"addiu $21, $21, 1\n"
|
||
"slti $2, $21, 8\n"
|
||
"bnez $2, 9b\n"
|
||
"addiu $4, $29, 40\n"
|
||
"addu $2, $0, $0\n"
|
||
"6:\n"
|
||
"lw $31, 308($29)\n"
|
||
"lw $30, 304($29)\n"
|
||
"lw $23, 300($29)\n"
|
||
"lw $22, 296($29)\n"
|
||
"lw $21, 292($29)\n"
|
||
"lw $20, 288($29)\n"
|
||
"lw $19, 284($29)\n"
|
||
"lw $18, 280($29)\n"
|
||
"lw $17, 276($29)\n"
|
||
"lw $16, 272($29)\n"
|
||
"addiu $29, $29, 312\n"
|
||
".set\treorder\n"
|
||
);
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
/* §37 asm-label alias: the TU canon (md_SC07_003.c:620) declares this symbol
|
||
`extern s32 D_80126B78[];`, but the target reads its VALUE twice
|
||
(lui/lw rematerialised per call site), which requires the pointer-variable
|
||
reading. Distinct C identifier + asm label = no conflicting-types clash,
|
||
emitted relocations still spell D_80126B78. */
|
||
extern s32 *aD_80126B78 __asm__("D_80126B78");
|
||
extern u8 D_800D3918[];
|
||
extern u8 D_801A68F4[];
|
||
extern u8 D_801152A8[];
|
||
extern s32 D_80127078;
|
||
|
||
extern void func_8012F14C(s32 a0, s32 a1, s32 a2);
|
||
extern void func_8012B2CC(s32 a0);
|
||
extern s32 func_80135888(s32 a0, s32 a1, s32 a2, s32 a3);
|
||
extern void func_8012F568(s32 a0, s32 a1, s32 a2, s32 a3, s32 a4, s32 a5);
|
||
|
||
s32 func_801A419C(s32 arg0) {
|
||
s32 buf[2]; /* 0x18(sp): projected point A */
|
||
s32 out[2]; /* 0x20(sp): projected point B */
|
||
|
||
func_8012F14C((s32)aD_80126B78 + 0x34, (s32)D_800D3918, (s32)buf);
|
||
func_8012F14C((s32)aD_80126B78 + 0x34, (s32)D_801A68F4, (s32)out);
|
||
func_8012B2CC(arg0);
|
||
if (func_80135888(*(s32 *)(arg0 + 0x20), *(s32 *)(arg0 + 0x58), (s32)buf, (s32)out) != 0) {
|
||
func_8012F568(1, 0x1C,
|
||
*(u16 *)(*(s32 *)(*(s32 *)(arg0 + 0x64) + 0x20) + 0x12) & 0xFFF,
|
||
0x1E, (s32)out, (s32)D_801152A8);
|
||
D_80127078 = arg0;
|
||
return 1;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
/* --- PsyQ inline GTE macros (TU house spelling, copied from func_801A2014) --- */
|
||
|
||
extern void RotTransSV(s32 a0, s32 a1, void *a2);
|
||
extern s32 func_8004787C(s32 a0);
|
||
extern s32 func_8012E544(s32 a0);
|
||
extern void func_8012EC04(s32 a0, s32 a1, s32 *a2);
|
||
|
||
|
||
void func_801A4268(s32 self)
|
||
{
|
||
|
||
extern u8 D_801A6E38[];
|
||
extern u16 D_800B99DA;
|
||
s32 m[8]; /* sp+0x10 */
|
||
s32 flag; /* sp+0x30 */
|
||
s32 handle;
|
||
s32 r;
|
||
s32 c;
|
||
s32 v;
|
||
s32 x;
|
||
s32 sx;
|
||
s32 sy;
|
||
s32 t0;
|
||
s32 t1;
|
||
s32 p;
|
||
|
||
if (D_801F4358 != 0) {
|
||
if (D_801F43C0 == 3) {
|
||
func_8012EC04(self, 3, m);
|
||
} else {
|
||
handle = func_8012E544(0x3D0);
|
||
if (handle == 0) {
|
||
return;
|
||
}
|
||
func_8012EC04(handle, 0, m);
|
||
}
|
||
gte_SetRotMatrix(m);
|
||
gte_SetTransMatrix(m);
|
||
RotTransSV((s32)D_801A6E38, (s32)(D_801F4358 + 8), &flag);
|
||
r = func_8004787C(((s32)D_800B99DA << 6) & 0x7C0);
|
||
c = *(s32 *)(self + 0xE0) & 0x100;
|
||
flag = r;
|
||
if (c == 0) {
|
||
v = *(s32 *)(self + 0xE8);
|
||
} else {
|
||
v = *(s32 *)(self + 0xEC);
|
||
}
|
||
x = ((v << 1) + v) << 5;
|
||
sx = (-x >> 16) + 0x60;
|
||
t0 = (s16)sx * flag;
|
||
sy = x >> 16;
|
||
t1 = sy * flag;
|
||
p = D_801F4358;
|
||
*(u16 *)(p + 0x1A) = ((flag << 10) >> 12) + 0x800;
|
||
*(u16 *)(p + 0x18) = ((flag << 10) >> 12) + 0x800;
|
||
*((s8 *)&D_801F4318 + 1) = 0;
|
||
*((s8 *)&D_801F4318 + 2) = (t0 >> 12) + sx;
|
||
*((s8 *)&D_801F4318 + 0) = (t1 >> 12) + sy;
|
||
}
|
||
}
|
||
|
||
|
||
extern void func_8002D4C8(s32 a0, s32 a1);
|
||
|
||
void func_801A43E8(void *a0) {
|
||
switch (*(u16 *)((s32)a0 + 0x5E)) {
|
||
case 1:
|
||
case 2:
|
||
case 3:
|
||
case 4:
|
||
case 5:
|
||
case 6:
|
||
case 7:
|
||
case 8:
|
||
case 35:
|
||
func_8002D4C8(0xC33, 0);
|
||
*(s32 *)(*(s32 *)((s32)a0 + 0x64) + 0xE8) += 0x2000;
|
||
break;
|
||
case 11:
|
||
case 12:
|
||
case 18:
|
||
case 19:
|
||
case 20:
|
||
case 21:
|
||
case 22:
|
||
case 23:
|
||
case 24:
|
||
case 25:
|
||
case 26:
|
||
func_8002D4C8(0xC33, 0);
|
||
*(s32 *)(*(s32 *)((s32)a0 + 0x64) + 0xE8) += 0x4000;
|
||
break;
|
||
case 36:
|
||
func_8002D4C8(0xC33, 0);
|
||
*(s32 *)(*(s32 *)((s32)a0 + 0x64) + 0xE8) += 0x4000;
|
||
break;
|
||
default:
|
||
*(s32 *)(*(s32 *)((s32)a0 + 0x64) + 0xE8) += 0x2000;
|
||
break;
|
||
}
|
||
if (*(s32 *)(*(s32 *)((s32)a0 + 0x64) + 0xE8) > 0x10000) {
|
||
*(s32 *)(*(s32 *)((s32)a0 + 0x64) + 0xE8) = 0x10000;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
void func_801A44C8(void *a0) {
|
||
|
||
extern void (*D_801A6F00[])(void);
|
||
D_801A6F00[*(u16 *)((s32)a0 + 0x2)]();
|
||
}
|
||
|
||
|
||
extern s32 func_8012C1B8(void);
|
||
extern void func_8012CAE4(void *a0);
|
||
extern void func_8001C214(s32 a0, s32 a1);
|
||
|
||
void func_801A4504(void *arg0) {
|
||
s32 v0 = func_8012C1B8();
|
||
*(s32 *)((u8 *)arg0 + 0x20) = v0;
|
||
if (v0 == 0) {
|
||
func_8012CAE4(arg0);
|
||
return;
|
||
}
|
||
func_8001C214(v0, 0);
|
||
*(u16 *)(*(s32 *)((u8 *)arg0 + 0x20) + 0x2C) |= 0x10;
|
||
{
|
||
s32 t = *(s32 *)((u8 *)arg0 + 0x20);
|
||
*(s16 *)(t + 0x1A) = 1;
|
||
*(s16 *)(t + 0x18) = 1;
|
||
}
|
||
{
|
||
u16 x = *(u16 *)(*(s32 *)((u8 *)arg0 + 0x64) + 0x36);
|
||
*(s16 *)((u8 *)arg0 + 0x2) = *(u16 *)((u8 *)arg0 + 0x2) + 1;
|
||
*(s16 *)((u8 *)arg0 + 0x10A) = x;
|
||
}
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
extern void func_8012C218(void *a0);
|
||
extern s32 func_80134510(s32 a0);
|
||
extern s32 ratan2(s32 a0, s32 a1);
|
||
extern void func_801A4680(void *a0);
|
||
|
||
extern u8 D_801152A8[];
|
||
extern s16 D_801152AA;
|
||
extern s16 D_801152AC;
|
||
|
||
void func_801A4590(s32 a0) {
|
||
s32 v0 = *(s32 *)(a0 + 0x64);
|
||
s16 sp[3];
|
||
|
||
if (*(s16 *)(v0 + 0x36) != *(s16 *)(a0 + 0x10A)) {
|
||
func_8012C218((void *)a0);
|
||
return;
|
||
}
|
||
|
||
sp[0] = *(u16 *)(v0 + 6);
|
||
sp[1] = *(u16 *)(v0 + 0xA) - 0x10;
|
||
sp[2] = *(u16 *)(v0 + 0xE);
|
||
if (func_80134510((s32)&sp[0]) == 0) {
|
||
return;
|
||
}
|
||
|
||
*(s16 *)(a0 + 6) = sp[0];
|
||
*(s16 *)(a0 + 0xA) = sp[1];
|
||
*(s16 *)(a0 + 0xE) = sp[2];
|
||
|
||
*(s16 *)(*(s32 *)(a0 + 0x20) + 0x10) = ratan2(D_801152AC, D_801152AA) + 0x400;
|
||
*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12) = ratan2(*(s16 *)D_801152A8, D_801152AA);
|
||
func_801A4680((void *)a0);
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
/* ---- local layout typedef (standalone match_one compilation) --------------
|
||
* SVec: {s16 vx,vy,vz,pad;} 8 bytes.
|
||
* Prim: v[4] @0x00 (0x20 bytes), 8 UV/coord shorts @0x20 (0x10 bytes),
|
||
* bcast(u32) @0x30, tag(s32) @0x34, code(u8) @0x38, padded to 0x40.
|
||
* frame: prim @ sp+0x10..sp+0x50 -> var_size 0x40, matches the 0x68
|
||
* frame with 6 callee-saves (s0-s4, ra).
|
||
* Same shape as func_80183F84 (ov_SC03_105) / func_8018DA64 (ov_SC04_011).
|
||
*/
|
||
|
||
extern void func_80016EF8(void *a0, void *a1);
|
||
|
||
void func_801A4680(void *a0) {
|
||
Prim_801A4680 prim;
|
||
s32 i, j;
|
||
|
||
prim.bcast = 0x808080;
|
||
prim.tag = 0x50000000;
|
||
prim.code = 0x8F;
|
||
|
||
prim.v[3].vy = -0x40;
|
||
prim.v[2].vy = -0x40;
|
||
prim.v[1].vy = -0x40;
|
||
prim.v[0].vy = -0x40;
|
||
|
||
prim.v[3].vz = 0;
|
||
prim.v[2].vz = 0;
|
||
prim.v[1].vz = 0;
|
||
prim.v[0].vz = 0;
|
||
|
||
prim.t3 = 0x80;
|
||
prim.t2 = 0x80;
|
||
prim.t1 = 0x80;
|
||
prim.t0 = 0x80;
|
||
|
||
for (i = 0; i < 8; i++) {
|
||
prim.v[3].vx = -0x40;
|
||
prim.v[2].vx = -0x40;
|
||
prim.v[1].vx = -0x40;
|
||
prim.v[0].vx = -0x40;
|
||
|
||
prim.u3 = 0xB80;
|
||
prim.u2 = 0xB80;
|
||
prim.u1 = 0xB80;
|
||
prim.u0 = 0xB80;
|
||
|
||
prim.v[2].vy += 0x10;
|
||
prim.v[3].vy += 0x10;
|
||
prim.t2 += 0xF;
|
||
prim.t3 += 0xF;
|
||
|
||
for (j = 0; j < 8; j++) {
|
||
prim.v[1].vx += 0x10;
|
||
prim.v[3].vx += 0x10;
|
||
prim.u1 += 0xF;
|
||
prim.u3 += 0xF;
|
||
|
||
func_80016EF8(&prim, (void *)(*(s32 *)((u8 *)a0 + 0x20) + 0x34));
|
||
|
||
prim.v[0].vx = prim.v[1].vx;
|
||
prim.v[2].vx = prim.v[3].vx;
|
||
prim.u0 = prim.u1;
|
||
prim.u2 = prim.u3;
|
||
}
|
||
|
||
prim.v[0].vy = prim.v[2].vy;
|
||
prim.v[1].vy = prim.v[3].vy;
|
||
prim.t0 = prim.t2;
|
||
prim.t1 = prim.t3;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
void func_801A4810(void *a0) {
|
||
|
||
extern void (*D_801A7308[])(void);
|
||
D_801A7308[*(u16 *)((s32)a0 + 0x2)]();
|
||
}
|
||
|
||
|
||
void func_801A484C(s32 a0, s32 a1) {
|
||
s32 ent = func_8012C658(0x378, a1 & 0xFFFF, a0);
|
||
if (ent != 0 && (a1 & 0xFFFF) < 7u) {
|
||
func_801A484C(ent, (a1 + 1) & 0xFFFF);
|
||
}
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
extern s32 func_8012C1B8(void);
|
||
extern void func_8012CAE4(void *a0);
|
||
extern void func_8001CA1C(s32 a0, s32 a1);
|
||
extern void func_8012A828(s32 a0, void *a1);
|
||
extern void func_8012B2CC(s32 a0);
|
||
extern void func_8012B260(u8 *a0);
|
||
extern s32 func_8012C658(s32 arg0, s32 arg1, s32 arg2);
|
||
extern s32 rand(void);
|
||
extern void func_801A484C(s32 a0, s32 a1);
|
||
|
||
extern u8 D_801A6F08[];
|
||
extern u8 D_801A7148[];
|
||
extern u16 D_801A7314[];
|
||
|
||
void func_801A48A8(void *arg0) {
|
||
s32 s0 = (s32)arg0;
|
||
s32 s1;
|
||
|
||
s1 = func_8012C1B8();
|
||
if (s1 == 0) {
|
||
func_8012CAE4((void *)s0);
|
||
return;
|
||
}
|
||
|
||
*(s32 *)(s0 + 0x20) = s1;
|
||
func_8001CA1C(s1, (s32)D_801A6F08);
|
||
do { func_8012A828(s0, (void *)D_801A7148); } while (0); // !FAKE: do-while — a LOOP-note scheduling barrier (sched.c:2058-2074; P36 R7)
|
||
|
||
{
|
||
u16 t70 = *(u16 *)(s0 + 0x70);
|
||
s16 val = 0x5000 - ((t70 & 0xF) << 11);
|
||
*(s16 *)(s1 + 0x1C) = val;
|
||
*(s16 *)(s1 + 0x1A) = val;
|
||
*(s16 *)(s1 + 0x18) = val;
|
||
}
|
||
*(s32 *)(s1 + 0x4) = *(s32 *)(s1 + 0x4) | 0x50000000;
|
||
*(s16 *)(s1 + 0x2C) = *(u16 *)(s1 + 0x2C) | 0x90;
|
||
|
||
*(s16 *)(s0 + 0x10A) = *(u16 *)(*(s32 *)(s0 + 0x64) + 0x36);
|
||
|
||
if ((*(u16 *)(s0 + 0x70) & 0xF) == 0) {
|
||
s32 p = *(s32 *)(*(s32 *)(s0 + 0x64) + 0x20);
|
||
u16 t = *(u16 *)(p + 0x12);
|
||
s16 sum;
|
||
s32 d;
|
||
s32 v0;
|
||
|
||
*(s16 *)(s1 + 0x14) = t;
|
||
sum = t + D_801A7314[*(u16 *)(s0 + 0x70) >> 15];
|
||
*(s16 *)(s1 + 0x14) = sum;
|
||
func_8012B2CC(s0);
|
||
|
||
d = rand();
|
||
s1 = s0 + 0xE4;
|
||
*(s32 *)(s0 + 0x94) = d % 0x10;
|
||
*(s32 *)(s0 + 0x1C) = 0xC;
|
||
*(s32 *)(*(s32 *)(s0 + 0x20) + 0x80) = s1;
|
||
*(s16 *)(s0 + 0xE8) = 0x80;
|
||
*(s16 *)(s0 + 0xE6) = 0x80;
|
||
*(s16 *)(s0 + 0xE4) = 0x80;
|
||
v0 = func_8012C658(0x378, 1, s0);
|
||
if (v0 != 0) {
|
||
func_801A484C(v0, 2);
|
||
}
|
||
*(s16 *)(s0 + 0x2) = *(u16 *)(s0 + 0x2) + 1;
|
||
return;
|
||
}
|
||
|
||
{
|
||
s32 p = *(s32 *)(*(s32 *)(s0 + 0x64) + 0x20);
|
||
s32 slot = *(s32 *)(s0 + 0x20);
|
||
s32 d;
|
||
*(s32 *)(slot + 0x80) = *(s32 *)(p + 0x80);
|
||
d = rand();
|
||
*(s32 *)(s0 + 0x94) = d % 0x10;
|
||
*(s16 *)(s0 + 0x2) = 2;
|
||
func_8012B260((u8 *)s0);
|
||
}
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
extern void func_801A4D58(s32 a0, s32 a1);
|
||
extern s32 func_801A4DFC(void *a0);
|
||
extern s32 func_8012BEE8(s32 a0);
|
||
extern s32 func_8012B744(void *a0, void *a1);
|
||
extern s32 func_8012B608(s32 a0, s32 a1, s32 a2);
|
||
extern void func_8012BE98(s32 a0, u16 *a1);
|
||
extern s32 func_8012B8A4(s16 *a0);
|
||
extern s32 func_80132EF4(s32 a0, s32 a1);
|
||
extern void func_8012CBCC(s32 a0);
|
||
extern void func_8012C218(void *a0);
|
||
|
||
extern u16 D_801F4310[];
|
||
|
||
void func_801A4A78(s32 arg0) {
|
||
s32 t;
|
||
s32 p;
|
||
s32 q;
|
||
|
||
switch (*(u16 *)(arg0 + 0x34)) {
|
||
case 0:
|
||
func_801A4D58(arg0, -0x100000);
|
||
if (func_8012BEE8(arg0) == 0) {
|
||
break;
|
||
}
|
||
*(s32 *)(arg0 + 0x1C) = 0xC;
|
||
*(u16 *)(arg0 + 0x34) = *(u16 *)(arg0 + 0x34) + 1;
|
||
break;
|
||
|
||
case 1:
|
||
t = func_8012B744((void *)(arg0 + 4), D_801F4310);
|
||
t = func_8012B608(*(s16 *)(*(s32 *)(arg0 + 0x20) + 0x14), t, 8);
|
||
*(u16 *)(*(s32 *)(arg0 + 0x20) + 0x14) += t;
|
||
func_801A4D58(arg0, -0x100000);
|
||
if (((s32 (*)(s32, u16 *))func_8012BE98)(arg0, D_801F4310) > 0x4000) {
|
||
if (func_8012BEE8(arg0) == 0) {
|
||
break;
|
||
}
|
||
}
|
||
*(s32 *)(arg0 + 0x1C) = 0x50;
|
||
*(u16 *)(arg0 + 0x34) = *(u16 *)(arg0 + 0x34) + 1;
|
||
break;
|
||
|
||
case 2:
|
||
t = func_8012B8A4((s16 *)arg0);
|
||
t = func_8012B608(*(s16 *)(*(s32 *)(arg0 + 0x20) + 0x14), t, 0x18);
|
||
*(u16 *)(*(s32 *)(arg0 + 0x20) + 0x14) += t;
|
||
func_801A4D58(arg0, -0x100000);
|
||
if (*(s32 *)(arg0 + 0x1C) == 0x10) {
|
||
*(u16 *)(*(s32 *)(arg0 + 0x20) + 0x2C) |= 0x80;
|
||
p = *(s32 *)(*(s32 *)(arg0 + 0x20) + 0x80);
|
||
*(s16 *)(p + 4) = 0x80;
|
||
*(s16 *)(p + 2) = 0x80;
|
||
*(s16 *)(p + 0) = 0x80;
|
||
*(u16 *)(arg0 + 0x34) = *(u16 *)(arg0 + 0x34) + 1;
|
||
}
|
||
/* fallthrough */
|
||
case 3:
|
||
if (*(s32 *)(arg0 + 0x1C) < 0x11) {
|
||
p = *(s32 *)(*(s32 *)(arg0 + 0x20) + 0x80);
|
||
*(u16 *)(p + 0) -= 8;
|
||
*(u16 *)(p + 2) -= 8;
|
||
*(u16 *)(p + 4) -= 8;
|
||
}
|
||
if (func_8012BEE8(arg0) != 0) {
|
||
func_8012C218((void *)arg0);
|
||
return;
|
||
}
|
||
break;
|
||
}
|
||
|
||
if (*(u16 *)(arg0 + 0x72) & 0x4000) {
|
||
q = func_80132EF4(arg0, 0x6F);
|
||
if (q != 0) {
|
||
*(s32 *)(q + 0x10) = -(*(s32 *)(arg0 + 0x10) * 2);
|
||
*(s32 *)(q + 0x14) = *(s32 *)(arg0 + 0x14);
|
||
*(s32 *)(q + 0x18) = -(*(s32 *)(arg0 + 0x18) * 2);
|
||
}
|
||
}
|
||
func_801A4DFC((void *)arg0);
|
||
if (((s32 (*)(s32))func_8012CBCC)(arg0) != 0) {
|
||
func_8012C218((void *)arg0);
|
||
}
|
||
}
|
||
|
||
|
||
extern void func_8012C218(void *a0);
|
||
extern void func_8012B260(u8 *a0);
|
||
|
||
void func_801A4CF4(s32 a0) {
|
||
s32 a1 = *(s32 *)(a0 + 0x64);
|
||
|
||
if (*(s16 *)(a1 + 0x36) != *(s16 *)(a0 + 0x10A)) {
|
||
func_8012C218((void *)a0);
|
||
return;
|
||
}
|
||
|
||
*(s32 *)(a0 + 0x4) = *(s32 *)(a1 + 0x38);
|
||
*(s32 *)(a0 + 0x8) = *(s32 *)(a1 + 0x3C);
|
||
*(s32 *)(a0 + 0xC) = *(s32 *)(a1 + 0x40);
|
||
func_8012B260((u8 *)a0);
|
||
}
|
||
|
||
|
||
|
||
extern void RotMatrixY(s32 a0, void *a1);
|
||
extern void func_800484EC(s32 a0, s32 a1, s32 a2);
|
||
|
||
void func_801A4D58(s32 a0, s32 a1)
|
||
{
|
||
extern u8 D_800AE620[];
|
||
|
||
Mtx32_801A4D58 m;
|
||
s32 vel[3];
|
||
|
||
m = *(Mtx32_801A4D58 *)&D_800AE620;
|
||
vel[1] = 0;
|
||
vel[0] = 0;
|
||
vel[2] = a1;
|
||
RotMatrixY(*(s16 *)(*(s32 *)((s32)a0 + 0x20) + 0x14), &m);
|
||
func_800484EC((s32)&m, (s32)&vel[0], a0 + 0x10);
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
/* func_801A4DFC (md_SC07_003, 95 ins).
|
||
*
|
||
* STEP-0 TWIN: ov_SC02_027:func_80180770 (87 ins, sim 0.5714) documents the
|
||
* same "mtx = D_800AE620;" 32-byte struct-copy idiom (8-word lw/lw/lw +
|
||
* sw/sw/sw grouping straight after the prologue). D_800AE620's global type
|
||
* (Mtx32 in src/gsgap3.c: { s16 m[3][3]; s32 t[3]; }, 0x20 bytes) is reused
|
||
* here under a local typedef name per law 8 (do not adopt the name alone
|
||
* without the same field layout guarantee across TUs).
|
||
*
|
||
* Callee signatures adopted verbatim from src/shared/engine_core.h's
|
||
* DEFINE_func_8012F14C / DEFINE_func_8012F568 / DEFINE_func_8012B8A4 macros
|
||
* (the actual banked definitions), and from the fleet-uniform
|
||
* `extern void RotMatrixY(s32 a0, void *a1);` spelling used across many TUs.
|
||
* func_80135888's 4-arg s32-returning shape matches its many banked
|
||
* definitions (e.g. src/ov_SC02_027/ov_SC02_027_jr_80135888.c).
|
||
*
|
||
* D_80126B58 is declared raw-scalar (`extern s32 D_80126B58;`, matching its
|
||
* fleet-wide spelling in e.g. src/ov_SC03_099/ov_SC03_099.c) and indexed at
|
||
* +0x20/+0x38 via byte-pointer casts at the use site (law 4). D_801A7318 is
|
||
* this overlay's own local data (asm/md_SC07_003/data/tail.data.s), a 5-
|
||
* entry array of 0x10-byte records each holding two 8-byte sub-fields; not
|
||
* declared elsewhere in the fleet under this name, so it is typed by the
|
||
* raw stride the asm walks (s32[4] per record; only base addresses are
|
||
* ever taken, never dereferenced structurally, so the element type does not
|
||
* affect codegen). D_801152A8 is declared `extern u8 D_801152A8[];` per its
|
||
* many fleet occurrences (e.g. src/ov_SC03_099/ov_SC03_099_jr_801588CC.c).
|
||
*/
|
||
|
||
|
||
extern Mtx32_801A4DFC D_800AE620;
|
||
extern void RotMatrixY(s32 a0, void *a1);
|
||
extern void func_8012F14C(s32 a0, s32 a1, s32 a2);
|
||
extern s32 func_80135888(s32 a0, s32 a1, s32 a2, s32 a3);
|
||
extern s32 func_8012B8A4(s16 *a0);
|
||
extern void func_8012F568(s32 a0, s32 a1, s32 a2, s32 a3, s32 a4, s32 a5);
|
||
extern s32 D_80126B58;
|
||
extern s32 D_801A7318[];
|
||
extern u8 D_801152A8[];
|
||
|
||
s32 func_801A4DFC(void *a0)
|
||
{
|
||
Mtx32_801A4DFC mtx;
|
||
s32 buf1[2];
|
||
s32 buf2[2];
|
||
u8 *p;
|
||
u8 *q;
|
||
u8 *b58;
|
||
u8 *base;
|
||
s32 i;
|
||
s32 v0;
|
||
|
||
mtx = D_800AE620;
|
||
|
||
RotMatrixY(*(s16 *)(*(s32 *)((s32)a0 + 0x20) + 0x14), &mtx);
|
||
|
||
b58 = (u8 *)&D_80126B58;
|
||
i = 0;
|
||
|
||
mtx.t[0] = *(s32 *)(*(s32 *)((s32)a0 + 0x20) + 0x48);
|
||
mtx.t[1] = *(s32 *)(*(s32 *)((s32)a0 + 0x20) + 0x4C);
|
||
|
||
base = (u8 *)D_801A7318;
|
||
q = base + 8;
|
||
|
||
mtx.t[2] = *(s32 *)(*(s32 *)((s32)a0 + 0x20) + 0x50);
|
||
|
||
p = base;
|
||
|
||
for (; i < 10; q += 0x10, i += 2, p += 0x10) {
|
||
func_8012F14C((s32)&mtx, (s32)p, (s32)buf1);
|
||
func_8012F14C((s32)&mtx, (s32)q, (s32)buf2);
|
||
v0 = func_80135888(*(s32 *)(b58 + 0x20),
|
||
*(s32 *)(b58 + 0x38),
|
||
(s32)buf1, (s32)buf2);
|
||
if (v0 != 0) {
|
||
v0 = func_8012B8A4((s16 *)a0);
|
||
func_8012F568(1, 0x4201, v0, 0x32, (s32)buf2, (s32)D_801152A8);
|
||
return 1;
|
||
}
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
|
||
|
||
void func_801A4F78(void *a0) {
|
||
|
||
extern void (*D_801A73B4[])(void);
|
||
D_801A73B4[*(u16 *)((s32)a0 + 0x2)]();
|
||
}
|
||
|
||
|
||
|
||
// @unstuck(P36): none — MATCH (42 ins), iteration 1, rtu_match clean.
|
||
// Saturating add of a 3-byte RGB triple by a signed delta.
|
||
// Idioms: (1) `s8` by-value param => entry `sll/sra 24` for the sign test only;
|
||
// combine folds the extension back out of `~a1`/`-a1`/`a0[i]+a1` because every
|
||
// consumer is 8-bit (andi 0xFF / sb), so $a1 is used RAW after the test.
|
||
// (2) branch sense read off the target `sltu` operand ORDER (§3-T4): positive arm
|
||
// `sltu lim,p[i]` => store when `p[i] <= lim`; negative arm `sltu p[i],lim`
|
||
// => store when `p[i] >= lim`.
|
||
// (3) the third `if` written out in BOTH arms; jump.c cross-jumps the identical
|
||
// tails into the shared `j .L8018C344` (§5a) — do not hoist it after the if/else.
|
||
void func_801A4FB4(u8 *a0, s8 a1) {
|
||
u8 lim;
|
||
|
||
if (a1 == 0) {
|
||
return;
|
||
}
|
||
if (a1 > 0) {
|
||
lim = ~a1;
|
||
if (a0[0] <= lim) {
|
||
a0[0] = a0[0] + a1;
|
||
}
|
||
if (a0[1] <= lim) {
|
||
a0[1] = a0[1] + a1;
|
||
}
|
||
if (a0[2] <= lim) {
|
||
a0[2] = a0[2] + a1;
|
||
}
|
||
} else {
|
||
lim = -a1;
|
||
if (a0[0] >= lim) {
|
||
a0[0] = a0[0] + a1;
|
||
}
|
||
if (a0[1] >= lim) {
|
||
a0[1] = a0[1] + a1;
|
||
}
|
||
if (a0[2] >= lim) {
|
||
a0[2] = a0[2] + a1;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
void func_801A505C(void *a0) {
|
||
|
||
extern void (*D_801A73BC[])(void);
|
||
D_801A73BC[*(u16 *)((s32)a0 + 0x2)]();
|
||
}
|
||
|
||
|
||
extern void func_8012AD44(s32 *a0, s16 a1);
|
||
|
||
void func_801A5098(s32 a0) {
|
||
s32 *v0;
|
||
|
||
v0 = *(s32 **)(((u8 *)a0) + 0x20);
|
||
*(s16 *)(((u8 *)v0) + 0x1C) = 0;
|
||
*(s16 *)(((u8 *)v0) + 0x1A) = 0;
|
||
*(s16 *)(((u8 *)v0) + 0x18) = 0;
|
||
func_8012AD44((s32 *)a0, 1);
|
||
func_8002D4C8(0xB58, 0);
|
||
}
|
||
|
||
|
||
|
||
extern void func_8012AD44(s32 *a0, s16 a1);
|
||
void func_801A50D4(void * arg0) {
|
||
*(s8 *)((char *)arg0 + 0xfc) = 0x8;
|
||
((void (*)(s32, s32))func_8012AD44)((int)arg0, 0x2);
|
||
}
|
||
|
||
|
||
|
||
|
||
void func_801A50FC(void *a0) {
|
||
|
||
extern void (*D_801A73C4[])(void);
|
||
D_801A73C4[*(u16 *)((s32)a0 + 0x2)]();
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
extern s32 func_8012C1B8(void);
|
||
extern void func_8012CAE4(void *a0);
|
||
extern void func_8001C214(s32 a0, s32 a1);
|
||
extern void func_8012B2CC(s32 a0);
|
||
extern s32 func_8012C194(void);
|
||
extern void func_800233CC(void *a0, u16 a1);
|
||
extern void func_8001CD9C(s32 a0, void *a1);
|
||
extern s32 rand(void);
|
||
|
||
extern u16 D_801A73D4[];
|
||
extern s32 D_801F4484;
|
||
extern s32 D_801F4488;
|
||
extern s32 D_801F448C;
|
||
extern s32 D_801F4490;
|
||
|
||
void func_801A5138(s32 a0) {
|
||
s32 s2;
|
||
s32 obj;
|
||
s32 o1;
|
||
s32 o2;
|
||
s32 base;
|
||
s32 off;
|
||
s32 v;
|
||
s32 s1;
|
||
s32 p64;
|
||
u16 tmp;
|
||
s32 *p;
|
||
|
||
s2 = a0;
|
||
obj = func_8012C1B8();
|
||
*(s32 *)(s2 + 0x20) = obj;
|
||
if (obj == 0) {
|
||
func_8012CAE4((void *)s2);
|
||
return;
|
||
}
|
||
|
||
func_8001C214(obj, 0);
|
||
|
||
o1 = *(s32 *)(s2 + 0x20);
|
||
*(u16 *)(o1 + 0x10) = D_801A73D4[*(s16 *)(s2 + 0x70)];
|
||
|
||
o2 = *(s32 *)(s2 + 0x20);
|
||
off = rand() % 0x100;
|
||
base = *(s16 *)(s2 + 0xFC);
|
||
if (rand() & 1) {
|
||
v = base + off;
|
||
} else {
|
||
v = base - off;
|
||
}
|
||
*(s16 *)(o2 + 0x12) = v;
|
||
|
||
func_8012B2CC(s2);
|
||
|
||
*(s16 *)(s2 + 0xFE) = (rand() % 0x20) + 0x20;
|
||
|
||
p64 = *(s32 *)(s2 + 0x64);
|
||
tmp = *(u16 *)(p64 + 0x36);
|
||
*(u16 *)(s2 + 0x2) = *(u16 *)(s2 + 0x2) + 1;
|
||
*(s16 *)(s2 + 0x10A) = tmp;
|
||
|
||
s1 = func_8012C194();
|
||
if (s1 == 0) {
|
||
return;
|
||
}
|
||
|
||
*(s32 *)(s2 + 0xCC) = s1;
|
||
p = &D_801F4484;
|
||
*p = 0xC0C0C0;
|
||
D_801F4488 = 0;
|
||
D_801F448C = 0;
|
||
D_801F4490 = 0;
|
||
func_800233CC((void *)p, 0x60);
|
||
func_8001CD9C(s1, (void *)p);
|
||
*(u16 *)(s1 + 0x2C) = 0xC010;
|
||
*(s32 *)(s1 + 0x4) = *(s32 *)(s1 + 0x4) | 0x50800000;
|
||
*(u16 *)(s1 + 0x8) = *(u16 *)(s2 + 0x6);
|
||
*(u16 *)(s1 + 0xA) = *(u16 *)(s2 + 0xA);
|
||
*(u16 *)(s1 + 0xC) = *(u16 *)(s2 + 0xE);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
extern void func_80016714(s8 *a0, s32 a1);
|
||
extern void func_8012C218(void *a0);
|
||
extern Mtx32_801A4DFC D_800AE620;
|
||
extern void RotMatrixY(s32 a0, void *a1);
|
||
extern void func_8012F14C(s32 a0, s32 a1, s32 a2);
|
||
extern void RotTransSV(s32 a0, s32 a1, void *a2);
|
||
extern u8 D_800AF648;
|
||
extern void func_800176F0(void *a0);
|
||
|
||
void func_801A52DC(s32 param_1)
|
||
{
|
||
Prim_801A52DC prim;
|
||
Mtx32_801A52DC m;
|
||
s32 otz[4];
|
||
s32 flag;
|
||
SVECTOR_801A52DC *p;
|
||
s32 i;
|
||
s32 a, b, t;
|
||
s16 h;
|
||
|
||
if (*(s16 *)(*(s32 *)(param_1 + 0x64) + 0x36) != *(s16 *)(param_1 + 0x10A)) {
|
||
if (*(s32 *)(param_1 + 0xCC) != 0) {
|
||
func_80016714((s8 *)(*(s32 *)(param_1 + 0xCC)), 0x38);
|
||
}
|
||
func_8012C218((void *)param_1);
|
||
return;
|
||
}
|
||
|
||
t = *(s32 *)(param_1 + 0xE0) - 0x80;
|
||
*(s32 *)(param_1 + 0xE0) = t;
|
||
if (t < -0x400) {
|
||
*(s32 *)(param_1 + 0xE0) = -0x400;
|
||
}
|
||
|
||
prim.v[0].vx = -0x10;
|
||
prim.v[1].vx = 0x10;
|
||
h = *(u16 *)(param_1 + 0xE0);
|
||
prim.v[3].vy = 0;
|
||
prim.v[2].vy = 0;
|
||
prim.v[3].vx = 0;
|
||
prim.v[2].vx = 0;
|
||
prim.v[1].vy = 0;
|
||
prim.v[0].vy = 0;
|
||
prim.v[1].vz = 0;
|
||
prim.v[0].vz = 0;
|
||
prim.v[3].vz = h;
|
||
prim.v[2].vz = h;
|
||
|
||
m = (*(Mtx32_801A52DC *)&D_800AE620);
|
||
RotMatrixY(*(s16 *)(param_1 + 0xFE), &m);
|
||
func_8012F14C((s32)&m, (s32)&prim.v[2], (s32)&prim.v[2]);
|
||
|
||
m = (*(Mtx32_801A52DC *)&D_800AE620);
|
||
RotMatrixY(-*(s16 *)(param_1 + 0xFE), &m);
|
||
func_8012F14C((s32)&m, (s32)&prim.v[3], (s32)&prim.v[3]);
|
||
|
||
gte_SetRotMatrix((void *)(*(s32 *)(param_1 + 0x20) + 0x34));
|
||
gte_SetTransMatrix((void *)(*(s32 *)(param_1 + 0x20) + 0x34));
|
||
|
||
RotTransSV((s32)&prim.v[0], (s32)&prim.v[0], &flag);
|
||
RotTransSV((s32)&prim.v[1], (s32)&prim.v[1], &flag);
|
||
RotTransSV((s32)&prim.v[2], (s32)&prim.v[2], &flag);
|
||
RotTransSV((s32)&prim.v[3], (s32)&prim.v[3], &flag);
|
||
|
||
gte_SetRotMatrix(&D_800AF648);
|
||
gte_SetTransMatrix(&D_800AF648);
|
||
|
||
for (i = 0, p = &prim.v[0]; i < 4; i++, p++) {
|
||
gte_ldv0(p);
|
||
gte_rtps();
|
||
gte_stsxy(p);
|
||
gte_stflg(&flag);
|
||
gte_stszotz(&otz[i]);
|
||
if (flag & ~0x1000) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
a = otz[2];
|
||
if (otz[3] < a) {
|
||
a = otz[3];
|
||
}
|
||
b = otz[0];
|
||
if (otz[1] < b) {
|
||
b = otz[1];
|
||
}
|
||
if (b > a) {
|
||
b = a;
|
||
}
|
||
prim.f0 = 0x808080;
|
||
prim.f1 = 0x808080;
|
||
prim.v[0].vz = b;
|
||
prim.f2 = 0;
|
||
prim.f3 = 0;
|
||
prim.f4 = 0x50000000;
|
||
func_800176F0(&prim);
|
||
}
|
||
|
||
|
||
|
||
|
||
void func_801A5638(void *a0) {
|
||
|
||
extern void (*D_801A73F4[])(void);
|
||
D_801A73F4[*(u16 *)((s32)a0 + 0x2)]();
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
/* func_801A5674 — per-frame tick for a 3-state "rising bar" effect entity.
|
||
*
|
||
* Frame map (0x68):
|
||
* sp+0x00..0x0F outgoing arg area
|
||
* sp+0x10..0x17 u16 out[4] (result of func_8012F14C)
|
||
* sp+0x18..0x37 s32 buf[8] (matrix scratch for func_8012EC04)
|
||
* sp+0x38..0x57 Prim801A5674 (2 SVECs + 2 packed colours + tag)
|
||
* sp+0x58 s0, sp+0x5C s1, sp+0x60 ra
|
||
*/
|
||
|
||
|
||
extern void func_8012C218(void *a0);
|
||
extern void func_8012EC04(s32 param_1, s32 param_2, s32 *param_3);
|
||
extern void func_8012F14C(s32 a0, s32 a1, s32 a2);
|
||
extern void func_8012CC40(s32 a0, s32 a1);
|
||
extern s32 func_80016A5C();
|
||
|
||
void func_801A5674(void *arg0) {
|
||
u16 out[4]; /* sp+0x10 */
|
||
s32 buf[8]; /* sp+0x18 */
|
||
Prim801A5674 prim; /* sp+0x38 */
|
||
s32 e;
|
||
u16 st;
|
||
s32 p;
|
||
|
||
e = (s32)arg0;
|
||
if (*(s16 *)(e + 0xA) >= 0x10) {
|
||
func_8012C218(arg0);
|
||
return;
|
||
}
|
||
|
||
switch (*(u16 *)(e + 0x34)) {
|
||
case 0:
|
||
p = *(s32 *)(e + 0x64);
|
||
if (*(s16 *)(e + 0x10A) == *(s16 *)(p + 0x36)) {
|
||
func_8012EC04(p, *(s16 *)(e + 0xFC), buf);
|
||
((void (*)(s32 *, s32, u16 *))func_8012F14C)(buf, *(s32 *)(e + 0xDC), out);
|
||
*(u16 *)(e + 0x6) = out[0];
|
||
*(u16 *)(e + 0xA) = out[1];
|
||
*(u16 *)(e + 0xE) = out[2];
|
||
}
|
||
*(s32 *)(e + 0xE4) += *(s32 *)(e + 0xE8);
|
||
if (*(s32 *)(e + 0xE4) >= *(s32 *)(e + 0xE0)) {
|
||
*(s32 *)(e + 0xE4) = *(s32 *)(e + 0xE0);
|
||
*(u16 *)(e + 0x34) += 1;
|
||
}
|
||
break;
|
||
case 1:
|
||
out[2] = 0;
|
||
out[0] = 0;
|
||
out[1] = *(s32 *)(e + 0xE4);
|
||
if (((s32 (*)(s32, u16 *))func_8012CC40)(e, out) & 0x2000) {
|
||
*(u16 *)(e + 0x34) += 1;
|
||
}
|
||
break;
|
||
case 2:
|
||
*(s32 *)(e + 0xEC) += 0x10;
|
||
if (*(s32 *)(e + 0xEC) >= *(s32 *)(e + 0xE4)) {
|
||
func_8012C218((void *)e);
|
||
return;
|
||
}
|
||
break;
|
||
}
|
||
|
||
prim.v[1].z = 0;
|
||
prim.v[1].x = 0;
|
||
prim.v[0].z = 0;
|
||
prim.v[0].x = 0;
|
||
prim.tag = 0x50000000;
|
||
st = *(u16 *)(e + 0x34);
|
||
prim.col[0] = 0x808080;
|
||
prim.col[1] = 0x101010;
|
||
if (st < 2) {
|
||
prim.v[0].y = *(s32 *)(e + 0xE4);
|
||
prim.v[1].y = 0;
|
||
} else {
|
||
prim.v[0].y = *(s32 *)(e + 0xE4);
|
||
prim.v[1].y = *(s32 *)(e + 0xEC);
|
||
}
|
||
func_80016A5C(&prim, *(s32 *)(e + 0x20) + 0x34);
|
||
}
|
||
|
||
|
||
|
||
|
||
void func_801A5860(void *a0) {
|
||
|
||
extern void (*D_801A73FC[])(void);
|
||
D_801A73FC[*(u16 *)((s32)a0 + 0x2)]();
|
||
}
|
||
|
||
|
||
|
||
|
||
void func_801A589C(void *a0) {
|
||
|
||
extern void (*D_801A7414[])(void);
|
||
D_801A7414[*(u16 *)((s32)a0 + 0x2)]();
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
|
||
extern void (*D_801A7434[])(void);
|
||
|
||
extern u16 D_801A7422;
|
||
extern u16 D_801A7424;
|
||
extern u16 D_801A7426;
|
||
extern u16 D_801A742E;
|
||
extern u16 D_801A7430;
|
||
extern u16 D_801A7432;
|
||
|
||
extern u8 D_800D3918[];
|
||
|
||
extern void func_8012EC04(s32 a0, s32 a1, s32 *a2);
|
||
extern void func_8012F14C(s32 a0, s32 a1, s32 a2);
|
||
extern void func_8012B2CC(s32 a0);
|
||
|
||
void func_801A58D8(void *a0) {
|
||
s32 p;
|
||
s32 v0;
|
||
s32 v1;
|
||
MATRIX_md_SC07_003 m1;
|
||
SVECTOR_800 svec_out;
|
||
|
||
D_801A7434[*(u16 *)((s32)a0 + 0x2)]();
|
||
|
||
if (*(u16 *)((s32)a0 + 0x0) != 0) {
|
||
p = *(s32 *)((s32)a0 + 0x64);
|
||
v0 = *(s32 *)(p + 0x20);
|
||
v1 = *(s32 *)(v0 + 0x20);
|
||
|
||
D_801A7422 = *(u16 *)(v1 + 0xD2);
|
||
D_801A7424 = *(u16 *)(v1 + 0xD4);
|
||
D_801A7426 = *(u16 *)(v1 + 0xD6);
|
||
D_801A742E = *(u16 *)(v1 + 0xDE);
|
||
D_801A7430 = *(u16 *)(v1 + 0xE0);
|
||
D_801A7432 = *(u16 *)(v1 + 0xE2);
|
||
|
||
func_8012EC04(p, 0x11, (s32 *)&m1);
|
||
func_8012F14C((s32)&m1, (s32)D_800D3918, (s32)&svec_out);
|
||
|
||
*(s16 *)((s32)a0 + 0x6) = svec_out.vx;
|
||
*(s16 *)((s32)a0 + 0xA) = svec_out.vy;
|
||
*(s16 *)((s32)a0 + 0xE) = svec_out.vz;
|
||
func_8012B2CC((s32)a0);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
void func_801A59D4(void *a0) {
|
||
|
||
extern void (*D_801A743C[])(void);
|
||
D_801A743C[*(u16 *)((s32)a0 + 0x2)]();
|
||
}
|
||
|
||
|
||
extern u8 D_801A7368[];
|
||
extern u8 D_801A7374[];
|
||
|
||
void func_801A5A10(s32 param_1)
|
||
{
|
||
s32 p;
|
||
|
||
*(u32 *)(*(s32 *)(param_1 + 0x20) + 0x20) = (u32)&D_801A7368;
|
||
|
||
*(u32 *)(*(s32 *)(param_1 + 0x20) + 4) |= 0x50000000;
|
||
|
||
*(u8 *)(*(s32 *)(param_1 + 0x20) + 0x27) = 0x5A;
|
||
|
||
p = *(s32 *)(param_1 + 0x20);
|
||
*(u16 *)(p + 0x1A) = 0x3000;
|
||
*(u16 *)(p + 0x18) = 0x3000;
|
||
|
||
func_80128EA8(*(u32 *)(param_1 + 0x20), param_1 + 0x24, (s32)&D_801A7374);
|
||
|
||
*(u16 *)(param_1 + 2) = *(u16 *)(param_1 + 2) + 1;
|
||
}
|
||
|
||
|
||
extern s32 func_80128ED8(s32 param_1, s32 *param_2);
|
||
extern void func_801292C8(u8 *a0);
|
||
extern void func_8012931C(void *);
|
||
|
||
void func_801A5A9C(s32 a0) {
|
||
s32 s0 = a0;
|
||
func_8012931C((void *)a0);
|
||
if (((s32 (*)(s32, void *))func_80128ED8)(*(s32 *)(s0 + 0x20), (void *)(s0 + 0x24)) != 0) {
|
||
((void (*)(s32))func_801292C8)(s0);
|
||
}
|
||
}
|
||
|
||
|
||
extern void func_8001CD50(s32 a0, s32 a1);
|
||
extern void func_800233CC(void *a0, u16 a1);
|
||
|
||
extern u8 D_801F4444[];
|
||
extern u8 D_801F4448[];
|
||
|
||
|
||
const Blk4_md_SC07_003 D_801A01CC = {{0x00, 0x00, 0x00, 0x00}};
|
||
const Blk4_md_SC07_003 D_801A01D0 = {{0xFF, 0x80, 0x00, 0x00}};
|
||
|
||
void func_801A5AE0(void *a0) {
|
||
void *s1 = D_801F4444;
|
||
|
||
func_8001CD50(*(s32 *)((s32)a0 + 0x20), (s32)s1);
|
||
|
||
*(u16 *)((s32)a0 + 0xA) -= 0x100;
|
||
*(s32 *)(*(s32 *)((s32)a0 + 0x20) + 0x4) |= 0x50000000;
|
||
*(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0x10) = 0x400;
|
||
|
||
*(u16 *)((s32)a0 + 0x2C) = 0x10;
|
||
func_800233CC(s1, 0x10);
|
||
|
||
*(Blk4_md_SC07_003 *)s1 = D_801A01CC;
|
||
*(Blk4_md_SC07_003 *)D_801F4448 = D_801A01D0;
|
||
|
||
*(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0x1E) = 0xC00;
|
||
*(u16 *)((s32)a0 + 0x2) += 1;
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
extern void func_801A4FB4(u8 *, s8);
|
||
extern void func_800233CC(void *, u16);
|
||
extern void func_801292C8(u8 *);
|
||
|
||
extern u8 D_801F4448[];
|
||
|
||
void func_801A5BBC(s32 arg0) {
|
||
s16 var;
|
||
|
||
var = *(s16 *)(arg0 + 0x2C);
|
||
if (var < 0x700) {
|
||
*(s16 *)(arg0 + 0x2C) = var + 0x30;
|
||
func_801A4FB4(D_801F4448, -4);
|
||
func_800233CC(D_801F4448 - 4, *(u16 *)(arg0 + 0x2C));
|
||
} else {
|
||
func_801292C8((u8 *)arg0);
|
||
}
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
extern s32 func_8012C1B8(void);
|
||
extern void func_8012CAE4(void *a0);
|
||
extern void func_8001C810(s32 a0, s32 a1);
|
||
extern void func_801A5098(s32 a0);
|
||
|
||
extern s32 D_801F28F8;
|
||
extern s32 D_801F30A8;
|
||
|
||
void func_801A5C34(s32 param_1)
|
||
{
|
||
s32 v0;
|
||
|
||
v0 = func_8012C1B8();
|
||
*(s32 *)(param_1 + 0x20) = v0;
|
||
if (v0 == 0) {
|
||
func_8012CAE4((void *)param_1);
|
||
return;
|
||
}
|
||
|
||
func_8001C810(v0, (s32)&D_801F28F8);
|
||
|
||
v0 = func_8012C1B8();
|
||
*(s32 *)(param_1 + 0xCC) = v0;
|
||
if (v0 == 0) {
|
||
func_8012CAE4((void *)param_1);
|
||
v0 = *(s32 *)(param_1 + 0x20);
|
||
*(s16 *)v0 = 0;
|
||
return;
|
||
}
|
||
|
||
func_8001C810(v0, (s32)&D_801F30A8);
|
||
|
||
*(u8 *)(param_1 + 0xC0) = 0;
|
||
*(u32 *)(*(s32 *)(param_1 + 0x20) + 4) |= 0x50000000;
|
||
*(u16 *)(*(s32 *)(param_1 + 0x20) + 0x2C) |= 0x90;
|
||
*(s32 *)(*(s32 *)(param_1 + 0x20) + 0x80) = param_1 + 0xFC;
|
||
|
||
*(u32 *)(*(s32 *)(param_1 + 0xCC) + 4) |= 0x50000000;
|
||
*(u16 *)(*(s32 *)(param_1 + 0xCC) + 0x2C) |= 0x90;
|
||
*(s32 *)(*(s32 *)(param_1 + 0xCC) + 0x80) = param_1 + 0xFC;
|
||
|
||
*(s16 *)(param_1 + 0xFC) = 0x100;
|
||
*(s16 *)(param_1 + 0xFE) = 0x100;
|
||
*(s16 *)(param_1 + 0x100) = 0x100;
|
||
*(s16 *)(param_1 + 0x102) = -2;
|
||
|
||
func_801A5098(param_1);
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
extern void func_801A50D4(void *arg0);
|
||
|
||
void func_801A5D4C(s32 param_1)
|
||
{
|
||
s32 a1;
|
||
u16 v0;
|
||
u16 v1;
|
||
|
||
a1 = *(s32 *)(param_1 + 0xCC);
|
||
v1 = *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x18);
|
||
if (v1 < 0x5000) {
|
||
s32 p20;
|
||
|
||
*(u16 *)(*(s32 *)(param_1 + 0x20) + 0x18) = v1 + 0x100;
|
||
|
||
p20 = *(s32 *)(param_1 + 0x20);
|
||
v1 = *(u16 *)(p20 + 0x18);
|
||
*(u16 *)(p20 + 0x1C) = v1;
|
||
*(u16 *)(p20 + 0x1A) = v1;
|
||
|
||
v0 = *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x12);
|
||
*(u16 *)(*(s32 *)(param_1 + 0x20) + 0x12) = v0 + 0x100;
|
||
|
||
*(u16 *)(a1 + 0x12) = *(u16 *)(a1 + 0x12) - 0x100;
|
||
|
||
*(u16 *)(a1 + 0x8) = *(u16 *)(param_1 + 0x6) + *(u16 *)(param_1 + 0x50);
|
||
*(u16 *)(a1 + 0xA) = *(u16 *)(param_1 + 0xA) + *(u16 *)(param_1 + 0x52);
|
||
*(u16 *)(a1 + 0xC) = *(u16 *)(param_1 + 0xE) + *(u16 *)(param_1 + 0x54);
|
||
|
||
*(u16 *)(a1 + 0x18) = *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x18);
|
||
*(u16 *)(a1 + 0x1A) = *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x1A);
|
||
*(u16 *)(a1 + 0x1C) = *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x1C);
|
||
} else {
|
||
func_801A50D4((void *)param_1);
|
||
}
|
||
}
|
||
|
||
|
||
extern s32 func_8012BEE8(s32 a0);
|
||
extern void func_80016450(s32 a0, s32 a1);
|
||
|
||
void func_801A5E44(s32 param_1)
|
||
{
|
||
s32 state = *(u16 *)(param_1 + 0x34);
|
||
|
||
switch (state) {
|
||
case 0:
|
||
{
|
||
u8 v0 = *(u8 *)(param_1 + 0xFC) + 0x10;
|
||
*(u8 *)(param_1 + 0xFC) = v0;
|
||
if (v0 >= 0xF1) {
|
||
*(u32 *)(*(s32 *)(param_1 + 0x20) + 4) |= 0x80000000;
|
||
*(u32 *)(*(s32 *)(param_1 + 0xCC) + 4) |= 0x80000000;
|
||
*(s32 *)(param_1 + 0x1C) = 8;
|
||
*(u16 *)(param_1 + 0x34) += 1;
|
||
}
|
||
break;
|
||
}
|
||
case 1:
|
||
if (func_8012BEE8(param_1) != 0) {
|
||
*(s32 *)(param_1 + 0xE0) = state;
|
||
}
|
||
break;
|
||
}
|
||
|
||
func_80016450(*(u8 *)(param_1 + 0xFC), 0);
|
||
}
|
||
|
||
|
||
void func_801A5F18(void *a0) {
|
||
u32 v;
|
||
u32 m;
|
||
v = *(u8 *)((s32)a0 + 0xFC);
|
||
v -= 3;
|
||
m = v & 0xFF;
|
||
*(u8 *)((s32)a0 + 0xFC) = v;
|
||
if (m >= 9) {
|
||
func_80016450(m, 0);
|
||
} else {
|
||
func_8012C218(a0);
|
||
}
|
||
}
|
||
|
||
|
||
extern s32 func_8012C1B8(void);
|
||
extern void func_8012CAE4(void *a0);
|
||
extern void func_8001C214(s32 a0, s32 a1);
|
||
extern s32 rand(void);
|
||
|
||
void func_801A5F6C(s32 a0) {
|
||
s32 v0;
|
||
s32 v1;
|
||
s32 p64;
|
||
u16 tmp;
|
||
|
||
v0 = func_8012C1B8();
|
||
*(s32 *)(a0 + 0x20) = v0;
|
||
if (v0 == 0) {
|
||
func_8012CAE4((void *)a0);
|
||
return;
|
||
}
|
||
func_8001C214(v0, 0);
|
||
|
||
*(s32 *)(a0 + 0xE0) = rand() % 64 + 0x20;
|
||
|
||
*(s32 *)(a0 + 0xE8) = rand() % 5 + 4;
|
||
*(s32 *)(a0 + 0x48) = 0xC000;
|
||
|
||
p64 = *(s32 *)(a0 + 0x64);
|
||
tmp = *(u16 *)(p64 + 0x36);
|
||
*(u16 *)(a0 + 0x2) = *(u16 *)(a0 + 0x2) + 1;
|
||
*(u16 *)(a0 + 0x10A) = tmp;
|
||
}
|
||
|
||
|
||
extern s32 func_8012C1B8(void);
|
||
extern void func_8012CAE4(void *a0);
|
||
extern void func_8001C214(s32 a0, s32 a1);
|
||
|
||
extern u8 D_801F3208[];
|
||
extern u8 D_801A7404[];
|
||
extern u16 D_80126B62;
|
||
extern u16 D_80126BE2;
|
||
extern u16 D_80126B5E;
|
||
extern u16 D_80126BE0;
|
||
extern u16 D_80126B66;
|
||
extern u16 D_80126BE4;
|
||
|
||
void func_801A6038(void *a0) {
|
||
s32 s0 = (s32)a0;
|
||
s32 v0;
|
||
|
||
v0 = func_8012C1B8();
|
||
*(s32 *)(s0 + 0x20) = v0;
|
||
|
||
if (v0 == 0) {
|
||
func_8012CAE4((void *)s0);
|
||
return;
|
||
}
|
||
|
||
do { func_8001C214(v0, (s32)D_801F3208); } while (0);
|
||
|
||
*(s32 *)(s0 + 0x58) = (s32)D_801A7404 | 0x40000000;
|
||
*(u16 *)(s0 + 0x5C) = 0xC00;
|
||
*(u16 *)(s0 + 0x6) = 0;
|
||
|
||
*(s16 *)&D_80126B62 = -0x120;
|
||
*(s16 *)&D_80126BE2 = -0x120;
|
||
*(s16 *)&D_80126B5E = 0;
|
||
*(s16 *)&D_80126BE0 = 0;
|
||
*(s16 *)(s0 + 0xE) = -0x462;
|
||
*(s16 *)&D_80126B66 = -0x462;
|
||
*(s16 *)&D_80126BE4 = -0x462;
|
||
*(s16 *)(s0 + 0xA) = -0x100;
|
||
*(s32 *)(s0 + 0x14) = 0xFFFA0000;
|
||
*(u8 *)(s0 + 0x75) = 2;
|
||
*(u16 *)(s0 + 0x2) = *(u16 *)(s0 + 0x2) + 1;
|
||
}
|
||
|
||
|
||
void func_801A6108(s32 arg0) {
|
||
if (*(u8 *)(arg0 + 0x74) != 0) {
|
||
func_8012E014(arg0);
|
||
}
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
extern s32 func_8012C1B8(void);
|
||
extern void func_8012CAE4(void *a0);
|
||
extern void func_8001C214(s32 a0, s32 a1);
|
||
|
||
extern s32 D_801F43B4;
|
||
extern u8 D_801A741C[];
|
||
|
||
void func_801A6138(void *arg0) {
|
||
s32 v0 = func_8012C1B8();
|
||
*(s32 *)((u8 *)arg0 + 0x20) = v0;
|
||
if (v0 == 0) {
|
||
func_8012CAE4(arg0);
|
||
return;
|
||
}
|
||
func_8001C214(v0, (s32)&D_801F43B4);
|
||
*(s32 *)(*(s32 *)((u8 *)arg0 + 0x20) + 0x20) = (s32)D_801A741C;
|
||
*(s16 *)(*(s32 *)((u8 *)arg0 + 0x20) + 0x12) =
|
||
*(u16 *)(*(s32 *)(*(s32 *)((u8 *)arg0 + 0x64) + 0x20) + 0x12);
|
||
*(s16 *)((u8 *)arg0 + 0x2) = *(u16 *)((u8 *)arg0 + 0x2) + 1;
|
||
}
|
||
|
||
|
||
extern s32 func_8012BDBC(s32 a0, s32 a1);
|
||
extern s32 func_8012BA10(s32 a0, s32 a1);
|
||
extern s32 func_8012B608(s32 a0, s32 a1, s32 a2);
|
||
|
||
void func_801A61C4(s32 arg0) {
|
||
if (func_8012BDBC(arg0, 0x280) != 0) {
|
||
*(u16 *)(*(s32 *)(arg0 + 0x20) + 0x12) += func_8012BA10(arg0, 8);
|
||
} else {
|
||
*(u16 *)(*(s32 *)(arg0 + 0x20) + 0x12) += func_8012B608(
|
||
*(s16 *)(*(s32 *)(arg0 + 0x20) + 0x12),
|
||
*(s16 *)(*(s32 *)(*(s32 *)(arg0 + 0x64) + 0x20) + 0x12),
|
||
8);
|
||
}
|
||
}
|
||
|
||
|
||
#include "common.h"
|
||
|
||
extern s32 func_8012C1B8(void);
|
||
extern void func_8012CAE4(void *a0);
|
||
extern void func_800233CC(void *a0, u16 a1);
|
||
extern s32 func_8001CA88(s32 a0, void *a1);
|
||
|
||
extern s32 D_801F44C4;
|
||
extern s32 D_801F44C8;
|
||
extern s32 D_801F44CC;
|
||
extern s32 D_801F44D0;
|
||
|
||
void func_801A623C(void *a0) {
|
||
s32 v0;
|
||
|
||
v0 = func_8012C1B8();
|
||
*(s32 *)((s32)a0 + 0x20) = v0;
|
||
if (v0 == 0) {
|
||
func_8012CAE4(a0);
|
||
return;
|
||
}
|
||
|
||
{
|
||
void *s0 = &D_801F44C4;
|
||
*(s32 *)s0 = 0x808080;
|
||
D_801F44C8 = 0;
|
||
D_801F44CC = 0;
|
||
D_801F44D0 = 0;
|
||
func_800233CC(s0, 0x60);
|
||
func_8001CA88(*(s32 *)((s32)a0 + 0x20), s0);
|
||
}
|
||
|
||
*(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0x2C) |= 0x10;
|
||
*(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0x18) =
|
||
*(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0x1A) =
|
||
*(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0x1C) = 1;
|
||
*(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0x1E) = 0xAAA;
|
||
*(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0x2E) = 0xC010;
|
||
|
||
*(s32 *)(*(s32 *)((s32)a0 + 0x20) + 0x4) |= 0x50000000;
|
||
|
||
*(u16 *)((s32)a0 + 0x2) += 1;
|
||
}
|
||
|
||
|
||
extern s32 D_801F44C4;
|
||
extern void func_8012C218(void *a0);
|
||
|
||
void func_801A6334(s32 arg0) {
|
||
s32 *p;
|
||
*(u16 *)(*(s32 *)(arg0 + 0x20) + 0x18) += 0xE00;
|
||
*(u16 *)(*(s32 *)(arg0 + 0x20) + 0x1A) += 0xE00;
|
||
p = &D_801F44C4;
|
||
*p += 0xFFFBFBFC;
|
||
if (*(s16 *)(*(s32 *)(arg0 + 0x20) + 0x18) >= 0x7001) {
|
||
func_8012C218((void *)arg0);
|
||
}
|
||
}
|
||
|