From cf10d284592391d8891482ddfa01eeb191f7123f Mon Sep 17 00:00:00 2001 From: Drew T <50529377+Druthulu@users.noreply.github.com> Date: Mon, 3 Aug 2026 19:06:02 -0600 Subject: [PATCH] =?UTF-8?q?feat(phase-30=20S9):=20x2-9=20calibration=20wav?= =?UTF-8?q?e=20=E2=80=94=2022/25=20banked=20+=2067=20members;=20the=20grin?= =?UTF-8?q?d=20rate=20is=20MEASURED?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - CALIBRATION (25 stratified targets: 12 head-by-weight + 13 sampled across the band, so the measurement captures the DECAY, not just the head): 28 agents -> 22 claimed -> gate BANKED 22/25 (88%) -> propagated 67 member-matches / 13 failed across 38 overlays. 89 instances. **22,937 templatable instructions banked in one wave.** HEAD 9/12 -> 19,492 of 28,584 templ ins BODY 13/13 -> 3,445 of 3,445 templ ins (the small ones are EASY; all 3 misses were 611-793 ins) - FIRST SONNET DATA (§136i ladder's new middle rung): **Sonnet 6/6 · Haiku 6/6 · Opus 10/13.** The two cheap tiers went 12/12 and Opus absorbed every hard failure — consistent with correct size-routing rather than luck. Small n; the controlled A/B stays parked (task #12). - THE PROJECTION for the >=95% instr bar (Drew's decision input): 411 of 1,872 families cover the 212,594-instruction gap = ~19 waves optimistic, 20-30 realistic. Mean templ ins/family decays 1,844 (top-25) -> 1,046 (top-100) -> 525 (top-400) -> 193 (band-wide), so early waves look like this one and later ones bank MORE functions for FEWER instructions. - DECISION (Drew): NO phase close — keep grinding. Campaign tracked as task #15. - Carried failures -> next lanes: func_8017D174 (793 ins, closeness 5 after ~90 variants; diagnosed a backward-scheduler priority race -> permuter, correctly NOT ledgered a wall), func_80186E24 (611 ins, 133 of 139 diffs pure register numbers -> a natural §137 test), func_8017E2EC. - §136c sibling-first paid again: func_8017DF84 (766 ins) MATCHED because a banked byte-matched twin existed in the same TU; its 697 index-diffs traced to ONE root cause (a bare 0xFFFFFF literal that loop.c hoisted to the OUTER preheader, stealing $s3) — closed by binding it to a local declared as the FIRST statement of the inner loop body. Verified via rtu_match (real-TU), not just match_one. --- .run/s8_lag.json | 3963 +++++++++++++++++++++ .run/s9_cal.js | 145 + .run/s9_cal.json | 1 + .run/s9_gate_derived.json | 31 + docs/family-hseq.md | 100 +- src/ov_SC01_074/ov_SC01_074_jr_8017BE9C.c | 29 +- src/ov_SC02_000/ov_SC02_000_jr_8017FCB0.c | 59 +- src/ov_SC02_003/ov_SC02_003_jr_8017FCB0.c | 60 +- src/ov_SC02_011/ov_SC02_011_jr_8017AE2C.c | 42 +- src/ov_SC03_001/ov_SC03_001_jr_8017AE2C.c | 51 +- src/ov_SC03_002/ov_SC03_002_jr_8017D604.c | 30 +- src/ov_SC03_006/ov_SC03_006_jr_8017AE2C.c | 43 +- src/ov_SC03_014/ov_SC03_014_jr_8017AE2C.c | 559 ++- src/ov_SC03_015/ov_SC03_015_jr_8017AE2C.c | 365 +- src/ov_SC03_028/ov_SC03_028_jr_8017AE2C.c | 171 +- src/ov_SC03_029/ov_SC03_029_jr_8017DC70.c | 43 +- src/ov_SC03_111/ov_SC03_111_jr_8017EC58.c | 549 ++- src/ov_SC03_112/ov_SC03_112_jr_8017C294.c | 184 +- src/ov_SC03_113/ov_SC03_113_jr_8017C294.c | 184 +- src/ov_SC03_114/ov_SC03_114_jr_8017BEBC.c | 36 +- src/ov_SC03_117/ov_SC03_117_jr_8017BEBC.c | 184 +- src/ov_SC03_118/ov_SC03_118_jr_8017FB84.c | 616 +++- src/ov_SC03_119/ov_SC03_119_jr_8017FB84.c | 549 ++- src/ov_SC03_125/ov_SC03_125_jr_8017D604.c | 30 +- src/ov_SC04_011/ov_SC04_011_jr_8017D494.c | 37 +- src/ov_SC04_016/ov_SC04_016_jr_8017BEBC.c | 70 +- src/ov_SC04_018/ov_SC04_018_jr_8017AE2C.c | 49 +- src/ov_SC04_019/ov_SC04_019_jr_8017AE2C.c | 51 +- src/ov_SC04_020/ov_SC04_020_jr_8017D604.c | 30 +- src/ov_SC05_003/ov_SC05_003_jr_8017BEBC.c | 51 +- src/ov_SC05_004/ov_SC05_004_jr_8017BEBC.c | 184 +- src/ov_SC05_005/ov_SC05_005_jr_8017D898.c | 50 +- src/ov_SC05_017/ov_SC05_017_jr_8017AE2C.c | 51 +- src/ov_SC05_018/ov_SC05_018_jr_8017D604.c | 30 +- src/ov_SC06_000/ov_SC06_000_jr_8017AE2C.c | 37 +- src/ov_SC06_006/ov_SC06_006_jr_8017BEBC.c | 37 +- src/ov_SC06_008/ov_SC06_008_jr_8017C294.c | 601 +++- src/ov_SC06_010/ov_SC06_010_jr_8017A4AC.c | 555 ++- src/ov_SC06_018/ov_SC06_018_jr_8017C24C.c | 914 ++++- src/ov_SC06_020/ov_SC06_020_jr_8017C24C.c | 293 +- src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c | 863 ++++- src/ov_SC06_024/ov_SC06_024_jr_8017BEBC.c | 864 ++++- src/ov_SC06_032/ov_SC06_032_jr_8017C24C.c | 951 ++++- src/ov_SC06_033/ov_SC06_033_jr_8017C24C.c | 843 ++++- src/ov_SC07_009/ov_SC07_009_jr_8017AE2C.c | 52 +- 45 files changed, 14488 insertions(+), 149 deletions(-) create mode 100644 .run/s8_lag.json create mode 100644 .run/s9_cal.js create mode 100644 .run/s9_cal.json create mode 100644 .run/s9_gate_derived.json diff --git a/.run/s8_lag.json b/.run/s8_lag.json new file mode 100644 index 000000000..eca154cd1 --- /dev/null +++ b/.run/s8_lag.json @@ -0,0 +1,3963 @@ +[ + { + "h": "813729d8b4654f4f00cd971bcc641863fb394c14", + "nins": 30, + "n_stub": 137, + "n_matched": 1, + "src_bin": "ov_SC07_006", + "src_addr": "0x80147364", + "src_name": "func_80147364", + "stubs": [ + { + "ov": "ov_SC03_090", + "addr": "0x80147364" + }, + { + "ov": "ov_SC06_000", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_006", + "addr": "0x80147364" + }, + { + "ov": "ov_SC06_033", + "addr": "0x80147364" + }, + { + "ov": "ov_SC02_031", + "addr": "0x80147364" + }, + { + "ov": "ov_SC07_002", + "addr": "0x80147364" + }, + { + "ov": "ov_SC05_006", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_002", + "addr": "0x80147364" + }, + { + "ov": "ov_SC06_027", + "addr": "0x80147364" + }, + { + "ov": "ov_SC04_019", + "addr": "0x80147364" + }, + { + "ov": "ov_SC04_008", + "addr": "0x80147364" + }, + { + "ov": "ov_SC06_006", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_112", + "addr": "0x80147364" + }, + { + "ov": "ov_SC06_015", + "addr": "0x80147364" + }, + { + "ov": "ov_SC06_030", + "addr": "0x80147364" + }, + { + "ov": "ov_SC02_016", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_110", + "addr": "0x80147364" + }, + { + "ov": "ov_SC05_017", + "addr": "0x80147364" + }, + { + "ov": "ov_SC06_032", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_029", + "addr": "0x80147364" + }, + { + "ov": "ov_SC04_002", + "addr": "0x80147364" + }, + { + "ov": "ov_SC01_074", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_089", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_105", + "addr": "0x80147364" + }, + { + "ov": "ov_SC07_000", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_121", + "addr": "0x80147364" + }, + { + "ov": "ov_SC04_018", + "addr": "0x80147364" + }, + { + "ov": "ov_SC06_008", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_124", + "addr": "0x80147364" + }, + { + "ov": "ov_SC07_009", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_010", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_097", + "addr": "0x80147364" + }, + { + "ov": "ov_SC02_041", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_031", + "addr": "0x80147364" + }, + { + "ov": "ov_SC04_021", + "addr": "0x80147364" + }, + { + "ov": "ov_SC02_021", + "addr": "0x80147364" + }, + { + "ov": "ov_SC07_011", + "addr": "0x80147364" + }, + { + "ov": "ov_SC04_020", + "addr": "0x80147364" + }, + { + "ov": "ov_SC07_008", + "addr": "0x80147364" + }, + { + "ov": "ov_SC06_020", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_119", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_024", + "addr": "0x80147364" + }, + { + "ov": "ov_SC04_003", + "addr": "0x80147364" + }, + { + "ov": "ov_SC02_026", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_118", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_099", + "addr": "0x80147364" + }, + { + "ov": "ov_SC06_013", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_104", + "addr": "0x80147364" + }, + { + "ov": "ov_SC02_005", + "addr": "0x80147364" + }, + { + "ov": "ov_SC05_003", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_012", + "addr": "0x80147364" + }, + { + "ov": "ov_SC07_007", + "addr": "0x80147364" + }, + { + "ov": "ov_SC01_005", + "addr": "0x80147364" + }, + { + "ov": "ov_SC02_017", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_102", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_014", + "addr": "0x80147364" + }, + { + "ov": "ov_SC04_006", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_093", + "addr": "0x80147364" + }, + { + "ov": "ov_SC04_012", + "addr": "0x80147364" + }, + { + "ov": "ov_SC01_080", + "addr": "0x80147364" + }, + { + "ov": "ov_SC02_011", + "addr": "0x80147364" + }, + { + "ov": "ov_SC06_011", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_111", + "addr": "0x80147364" + }, + { + "ov": "ov_SC05_018", + "addr": "0x80147364" + }, + { + "ov": "ov_SC06_024", + "addr": "0x80147364" + }, + { + "ov": "ov_SC06_014", + "addr": "0x80147364" + }, + { + "ov": "ov_SC05_007", + "addr": "0x80147364" + }, + { + "ov": "ov_SC02_028", + "addr": "0x80147364" + }, + { + "ov": "ov_SC02_000", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_109", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_030", + "addr": "0x80147364" + }, + { + "ov": "ov_SC06_029", + "addr": "0x80147364" + }, + { + "ov": "ov_SC05_001", + "addr": "0x80147364" + }, + { + "ov": "ov_SC01_008", + "addr": "0x80147364" + }, + { + "ov": "ov_SC07_001", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_028", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_013", + "addr": "0x80147364" + }, + { + "ov": "ov_SC05_004", + "addr": "0x80147364" + }, + { + "ov": "ov_SC01_077", + "addr": "0x80147364" + }, + { + "ov": "ov_SC05_008", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_015", + "addr": "0x80147364" + }, + { + "ov": "ov_SC06_010", + "addr": "0x80147364" + }, + { + "ov": "ov_SC04_000", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_126", + "addr": "0x80147364" + }, + { + "ov": "ov_SC01_004", + "addr": "0x80147364" + }, + { + "ov": "ov_SC04_011", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_117", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_116", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_125", + "addr": "0x80147364" + }, + { + "ov": "ov_SC02_035", + "addr": "0x80147364" + }, + { + "ov": "ov_SC04_016", + "addr": "0x80147364" + }, + { + "ov": "ov_SC02_027", + "addr": "0x80147364" + }, + { + "ov": "ov_SC02_004", + "addr": "0x80147364" + }, + { + "ov": "ov_SC04_004", + "addr": "0x80147364" + }, + { + "ov": "ov_SC02_003", + "addr": "0x80147364" + }, + { + "ov": "ov_SC05_019", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_098", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_094", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_101", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_007", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_003", + "addr": "0x80147364" + }, + { + "ov": "ov_SC04_015", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_108", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_095", + "addr": "0x80147364" + }, + { + "ov": "ov_SC06_016", + "addr": "0x80147364" + }, + { + "ov": "ov_SC01_084", + "addr": "0x80147364" + }, + { + "ov": "ov_SC05_011", + "addr": "0x80147364" + }, + { + "ov": "ov_SC01_000", + "addr": "0x80147364" + }, + { + "ov": "ov_SC04_005", + "addr": "0x80147364" + }, + { + "ov": "ov_SC04_007", + "addr": "0x80147364" + }, + { + "ov": "ov_SC02_039", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_092", + "addr": "0x80147364" + }, + { + "ov": "ov_SC01_001", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_011", + "addr": "0x80147364" + }, + { + "ov": "ov_SC06_025", + "addr": "0x80147364" + }, + { + "ov": "ov_SC05_000", + "addr": "0x80147364" + }, + { + "ov": "ov_SC05_010", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_103", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_091", + "addr": "0x80147364" + }, + { + "ov": "ov_SC05_009", + "addr": "0x80147364" + }, + { + "ov": "ov_SC02_015", + "addr": "0x80147364" + }, + { + "ov": "ov_SC01_006", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_023", + "addr": "0x80147364" + }, + { + "ov": "ov_SC07_010", + "addr": "0x80147364" + }, + { + "ov": "ov_SC05_005", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_114", + "addr": "0x80147364" + }, + { + "ov": "ov_SC04_010", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_001", + "addr": "0x80147364" + }, + { + "ov": "ov_SC05_002", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_096", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_115", + "addr": "0x80147364" + }, + { + "ov": "ov_SC06_018", + "addr": "0x80147364" + }, + { + "ov": "ov_SC06_022", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_100", + "addr": "0x80147364" + }, + { + "ov": "ov_SC03_113", + "addr": "0x80147364" + }, + { + "ov": "ov_SC01_009", + "addr": "0x80147364" + }, + { + "ov": "ov_SC04_009", + "addr": "0x80147364" + } + ] + }, + { + "h": "0bfaee44dc40e0a726c4b74c5efead7850714de0", + "nins": 29, + "n_stub": 137, + "n_matched": 1, + "src_bin": "ov_SC01_077", + "src_addr": "0x8012f274", + "src_name": "func_8012f274", + "stubs": [ + { + "ov": "ov_SC03_090", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC06_000", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_006", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC06_033", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC02_031", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC07_002", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC05_006", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_002", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC06_027", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC04_019", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC04_008", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC06_006", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_112", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC06_015", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC07_006", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC06_030", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC02_016", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_110", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC05_017", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC06_032", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_029", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC04_002", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC01_074", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_089", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_105", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC07_000", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_121", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC04_018", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC06_008", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_124", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC07_009", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_010", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_097", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC02_041", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_031", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC04_021", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC02_021", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC07_011", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC04_020", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC07_008", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC06_020", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_119", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_024", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC04_003", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC02_026", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_118", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_099", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC06_013", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_104", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC02_005", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC05_003", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_012", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC07_007", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC01_005", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC02_017", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_102", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_014", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC04_006", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_093", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC04_012", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC01_080", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC02_011", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC06_011", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_111", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC05_018", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC06_024", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC06_014", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC05_007", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC02_028", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC02_000", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_109", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_030", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC06_029", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC05_001", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC01_008", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC07_001", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_028", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_013", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC05_004", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC05_008", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_015", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC06_010", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC04_000", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_126", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC01_004", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC04_011", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_117", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_116", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_125", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC02_035", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC04_016", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC02_027", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC02_004", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC04_004", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC02_003", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC05_019", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_098", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_094", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_101", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_007", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_003", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC04_015", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_108", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_095", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC06_016", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC01_084", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC05_011", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC01_000", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC04_005", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC04_007", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC02_039", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_092", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC01_001", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_011", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC06_025", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC05_000", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC05_010", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_103", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_091", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC05_009", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC02_015", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC01_006", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_023", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC07_010", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC05_005", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_114", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC04_010", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_001", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC05_002", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_096", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_115", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC06_018", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC06_022", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_100", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC03_113", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC01_009", + "addr": "0x8012f274" + }, + { + "ov": "ov_SC04_009", + "addr": "0x8012f274" + } + ] + }, + { + "h": "1e79f41859edd25783d9505c9d1a94124adf4e9b", + "nins": 29, + "n_stub": 134, + "n_matched": 4, + "src_bin": "ov_SC07_006", + "src_addr": "0x8016ba68", + "src_name": "func_8016ba68", + "stubs": [ + { + "ov": "ov_SC03_090", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC06_000", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_006", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC06_033", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC02_031", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC07_002", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC05_006", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_002", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC06_027", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC04_019", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC04_008", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC06_006", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_112", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC06_015", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC06_030", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC02_016", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_110", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC05_017", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC06_032", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_029", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC04_002", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC01_074", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_089", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_105", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC07_000", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_121", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC04_018", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC06_008", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_124", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC07_009", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_010", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_097", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC02_041", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_031", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC04_021", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC02_021", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC04_020", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC07_008", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC06_020", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_119", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_024", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC04_003", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC02_026", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_118", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_099", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC06_013", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_104", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC02_005", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC05_003", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_012", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC01_005", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC02_017", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_102", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_014", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC04_006", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_093", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC04_012", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC01_080", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC02_011", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC06_011", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_111", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC05_018", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC06_024", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC06_014", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC05_007", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC02_028", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC02_000", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_109", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_030", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC06_029", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC05_001", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC01_008", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC07_001", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_028", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_013", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC05_004", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC01_077", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC05_008", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_015", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC06_010", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC04_000", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_126", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC01_004", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC04_011", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_117", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_116", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_125", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC02_035", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC04_016", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC02_027", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC02_004", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC04_004", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC02_003", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC05_019", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_098", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_094", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_101", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_007", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_003", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC04_015", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_108", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_095", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC06_016", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC01_084", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC05_011", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC01_000", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC04_005", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC04_007", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC02_039", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_092", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC01_001", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_011", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC06_025", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC05_000", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC05_010", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_103", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_091", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC05_009", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC02_015", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC01_006", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_023", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC05_005", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_114", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC04_010", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_001", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC05_002", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_096", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_115", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC06_018", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC06_022", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_100", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC03_113", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC01_009", + "addr": "0x8016ba68" + }, + { + "ov": "ov_SC04_009", + "addr": "0x8016ba68" + } + ] + }, + { + "h": "1bfd8874d4bd16914b5a68760b8039e83c8c59d8", + "nins": 24, + "n_stub": 137, + "n_matched": 1, + "src_bin": "ov_SC01_077", + "src_addr": "0x8012a598", + "src_name": "func_8012a598", + "stubs": [ + { + "ov": "ov_SC03_090", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC06_000", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_006", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC06_033", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC02_031", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC07_002", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC05_006", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_002", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC06_027", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC04_019", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC04_008", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC06_006", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_112", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC06_015", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC07_006", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC06_030", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC02_016", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_110", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC05_017", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC06_032", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_029", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC04_002", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC01_074", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_089", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_105", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC07_000", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_121", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC04_018", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC06_008", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_124", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC07_009", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_010", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_097", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC02_041", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_031", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC04_021", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC02_021", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC07_011", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC04_020", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC07_008", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC06_020", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_119", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_024", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC04_003", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC02_026", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_118", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_099", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC06_013", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_104", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC02_005", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC05_003", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_012", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC07_007", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC01_005", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC02_017", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_102", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_014", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC04_006", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_093", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC04_012", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC01_080", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC02_011", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC06_011", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_111", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC05_018", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC06_024", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC06_014", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC05_007", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC02_028", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC02_000", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_109", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_030", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC06_029", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC05_001", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC01_008", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC07_001", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_028", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_013", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC05_004", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC05_008", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_015", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC06_010", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC04_000", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_126", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC01_004", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC04_011", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_117", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_116", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_125", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC02_035", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC04_016", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC02_027", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC02_004", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC04_004", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC02_003", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC05_019", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_098", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_094", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_101", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_007", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_003", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC04_015", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_108", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_095", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC06_016", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC01_084", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC05_011", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC01_000", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC04_005", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC04_007", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC02_039", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_092", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC01_001", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_011", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC06_025", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC05_000", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC05_010", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_103", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_091", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC05_009", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC02_015", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC01_006", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_023", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC07_010", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC05_005", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_114", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC04_010", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_001", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC05_002", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_096", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_115", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC06_018", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC06_022", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_100", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC03_113", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC01_009", + "addr": "0x8012a598" + }, + { + "ov": "ov_SC04_009", + "addr": "0x8012a598" + } + ] + }, + { + "h": "f24b6aa1ffe15163148834f3cea54221d6b24f43", + "nins": 24, + "n_stub": 137, + "n_matched": 1, + "src_bin": "ov_SC01_077", + "src_addr": "0x801466f0", + "src_name": "func_801466f0", + "stubs": [ + { + "ov": "ov_SC03_090", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC06_000", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_006", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC06_033", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC02_031", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC07_002", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC05_006", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_002", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC06_027", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC04_019", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC04_008", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC06_006", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_112", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC06_015", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC07_006", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC06_030", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC02_016", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_110", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC05_017", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC06_032", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_029", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC04_002", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC01_074", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_089", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_105", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC07_000", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_121", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC04_018", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC06_008", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_124", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC07_009", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_010", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_097", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC02_041", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_031", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC04_021", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC02_021", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC07_011", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC04_020", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC07_008", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC06_020", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_119", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_024", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC04_003", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC02_026", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_118", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_099", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC06_013", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_104", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC02_005", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC05_003", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_012", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC07_007", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC01_005", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC02_017", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_102", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_014", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC04_006", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_093", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC04_012", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC01_080", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC02_011", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC06_011", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_111", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC05_018", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC06_024", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC06_014", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC05_007", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC02_028", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC02_000", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_109", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_030", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC06_029", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC05_001", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC01_008", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC07_001", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_028", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_013", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC05_004", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC05_008", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_015", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC06_010", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC04_000", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_126", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC01_004", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC04_011", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_117", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_116", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_125", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC02_035", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC04_016", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC02_027", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC02_004", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC04_004", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC02_003", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC05_019", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_098", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_094", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_101", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_007", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_003", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC04_015", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_108", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_095", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC06_016", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC01_084", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC05_011", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC01_000", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC04_005", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC04_007", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC02_039", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_092", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC01_001", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_011", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC06_025", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC05_000", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC05_010", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_103", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_091", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC05_009", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC02_015", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC01_006", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_023", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC07_010", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC05_005", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_114", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC04_010", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_001", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC05_002", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_096", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_115", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC06_018", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC06_022", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_100", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC03_113", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC01_009", + "addr": "0x801466f0" + }, + { + "ov": "ov_SC04_009", + "addr": "0x801466f0" + } + ] + }, + { + "h": "74186b97e5d9c09b5c0970ffd0cbfbf197bf5ffd", + "nins": 770, + "n_stub": 4, + "n_matched": 134, + "src_bin": "ov_SC03_090", + "src_addr": "0x80144b9c", + "src_name": "func_80144b9c", + "stubs": [ + { + "ov": "ov_SC07_006", + "addr": "0x80144b9c" + }, + { + "ov": "ov_SC07_011", + "addr": "0x80144b9c" + }, + { + "ov": "ov_SC07_007", + "addr": "0x80144b9c" + }, + { + "ov": "ov_SC07_010", + "addr": "0x80144b9c" + } + ] + }, + { + "h": "c378aa0123ea7e70aa008557dcbc7d2cecf92ffb", + "nins": 141, + "n_stub": 4, + "n_matched": 134, + "src_bin": "ov_SC03_090", + "src_addr": "0x8014f4c0", + "src_name": "func_8014f4c0", + "stubs": [ + { + "ov": "ov_SC07_006", + "addr": "0x8014f4c0" + }, + { + "ov": "ov_SC07_011", + "addr": "0x8014f4c0" + }, + { + "ov": "ov_SC07_007", + "addr": "0x8014f4c0" + }, + { + "ov": "ov_SC07_010", + "addr": "0x8014f4c0" + } + ] + }, + { + "h": "4f23330c1f0b97efc0d4e01fb4ba9d5dfb06c15c", + "nins": 133, + "n_stub": 3, + "n_matched": 1, + "src_bin": "ov_SC03_002", + "src_addr": "0x8017d0bc", + "src_name": "func_8017d0bc", + "stubs": [ + { + "ov": "ov_SC04_020", + "addr": "0x8017d0bc" + }, + { + "ov": "ov_SC05_018", + "addr": "0x8017d0bc" + }, + { + "ov": "ov_SC03_125", + "addr": "0x8017d0bc" + } + ] + }, + { + "h": "cc17e4fede5acacc97fed7d260125a83cd803738", + "nins": 80, + "n_stub": 4, + "n_matched": 134, + "src_bin": "ov_SC03_090", + "src_addr": "0x8016a08c", + "src_name": "func_8016a08c", + "stubs": [ + { + "ov": "ov_SC07_006", + "addr": "0x8016a08c" + }, + { + "ov": "ov_SC07_011", + "addr": "0x8016a08c" + }, + { + "ov": "ov_SC07_007", + "addr": "0x8016a08c" + }, + { + "ov": "ov_SC07_010", + "addr": "0x8016a08c" + } + ] + }, + { + "h": "921bf6d0d74bec524f3ea2a09ea24a8f11e1df24", + "nins": 24, + "n_stub": 13, + "n_matched": 1, + "src_bin": "ov_SC02_011", + "src_addr": "0x80190c84", + "src_name": "func_80190c84", + "stubs": [ + { + "ov": "ov_SC03_006", + "addr": "0x8018c090" + }, + { + "ov": "ov_SC03_112", + "addr": "0x8018567c" + }, + { + "ov": "ov_SC04_002", + "addr": "0x80188344" + }, + { + "ov": "ov_SC02_041", + "addr": "0x80184d20" + }, + { + "ov": "ov_SC05_003", + "addr": "0x801824b4" + }, + { + "ov": "ov_SC02_017", + "addr": "0x8018a428" + }, + { + "ov": "ov_SC04_006", + "addr": "0x8017fb28" + }, + { + "ov": "ov_SC05_007", + "addr": "0x801809b0" + }, + { + "ov": "ov_SC05_001", + "addr": "0x801851dc" + }, + { + "ov": "ov_SC04_000", + "addr": "0x80182290" + }, + { + "ov": "ov_SC04_004", + "addr": "0x80184614" + }, + { + "ov": "ov_SC03_007", + "addr": "0x8018732c" + }, + { + "ov": "ov_SC03_115", + "addr": "0x80180400" + } + ] + }, + { + "h": "cae222ea97b93e9f18a78c2377aff4a30a50abed", + "nins": 33, + "n_stub": 9, + "n_matched": 1, + "src_bin": "ov_SC04_018", + "src_addr": "0x801848dc", + "src_name": "func_801848dc", + "stubs": [ + { + "ov": "ov_SC03_002", + "addr": "0x80182e88" + }, + { + "ov": "ov_SC04_019", + "addr": "0x801848dc" + }, + { + "ov": "ov_SC05_017", + "addr": "0x801845dc" + }, + { + "ov": "ov_SC03_124", + "addr": "0x80184004" + }, + { + "ov": "ov_SC04_020", + "addr": "0x801810b8" + }, + { + "ov": "ov_SC05_018", + "addr": "0x801842c0" + }, + { + "ov": "ov_SC03_125", + "addr": "0x8018170c" + }, + { + "ov": "ov_SC04_015", + "addr": "0x80180c48" + }, + { + "ov": "ov_SC03_001", + "addr": "0x8018739c" + } + ] + }, + { + "h": "501b28459c94b05d99417b269fdcaca1d6548f55", + "nins": 24, + "n_stub": 9, + "n_matched": 1, + "src_bin": "ov_SC04_018", + "src_addr": "0x80185d10", + "src_name": "func_80185d10", + "stubs": [ + { + "ov": "ov_SC03_002", + "addr": "0x801842bc" + }, + { + "ov": "ov_SC04_019", + "addr": "0x80185d10" + }, + { + "ov": "ov_SC05_017", + "addr": "0x80185a10" + }, + { + "ov": "ov_SC03_124", + "addr": "0x80185438" + }, + { + "ov": "ov_SC04_020", + "addr": "0x801824ec" + }, + { + "ov": "ov_SC05_018", + "addr": "0x801856f4" + }, + { + "ov": "ov_SC03_125", + "addr": "0x80182b40" + }, + { + "ov": "ov_SC04_015", + "addr": "0x8018207c" + }, + { + "ov": "ov_SC03_001", + "addr": "0x801887d0" + } + ] + }, + { + "h": "af1aceb26914c3120879f5fcf397bb0155edc52d", + "nins": 52, + "n_stub": 4, + "n_matched": 134, + "src_bin": "ov_SC03_090", + "src_addr": "0x80162ff4", + "src_name": "func_80162ff4", + "stubs": [ + { + "ov": "ov_SC07_006", + "addr": "0x80162ff4" + }, + { + "ov": "ov_SC07_011", + "addr": "0x80162ff4" + }, + { + "ov": "ov_SC07_007", + "addr": "0x80162ff4" + }, + { + "ov": "ov_SC07_010", + "addr": "0x80162ff4" + } + ] + }, + { + "h": "b852714239b2a0f415f28968075a43834ec21274", + "nins": 52, + "n_stub": 4, + "n_matched": 134, + "src_bin": "ov_SC03_090", + "src_addr": "0x801630c4", + "src_name": "func_801630c4", + "stubs": [ + { + "ov": "ov_SC07_006", + "addr": "0x801630c4" + }, + { + "ov": "ov_SC07_011", + "addr": "0x801630c4" + }, + { + "ov": "ov_SC07_007", + "addr": "0x801630c4" + }, + { + "ov": "ov_SC07_010", + "addr": "0x801630c4" + } + ] + }, + { + "h": "d4c8dd1e1f541a2c58e5f52b08b8178d9f10be40", + "nins": 49, + "n_stub": 4, + "n_matched": 134, + "src_bin": "ov_SC03_090", + "src_addr": "0x8016a1cc", + "src_name": "func_8016a1cc", + "stubs": [ + { + "ov": "ov_SC07_006", + "addr": "0x8016a1cc" + }, + { + "ov": "ov_SC07_011", + "addr": "0x8016a1cc" + }, + { + "ov": "ov_SC07_007", + "addr": "0x8016a1cc" + }, + { + "ov": "ov_SC07_010", + "addr": "0x8016a1cc" + } + ] + }, + { + "h": "a99f39f3d5d59e1537f1b6ad8e841aab185e8e98", + "nins": 40, + "n_stub": 4, + "n_matched": 134, + "src_bin": "ov_SC03_090", + "src_addr": "0x80163194", + "src_name": "func_80163194", + "stubs": [ + { + "ov": "ov_SC07_006", + "addr": "0x80163194" + }, + { + "ov": "ov_SC07_011", + "addr": "0x80163194" + }, + { + "ov": "ov_SC07_007", + "addr": "0x80163194" + }, + { + "ov": "ov_SC07_010", + "addr": "0x80163194" + } + ] + }, + { + "h": "68a5f5ea3be61447e02cd37f4e55a06f1ba2ddec", + "nins": 143, + "n_stub": 1, + "n_matched": 1, + "src_bin": "ov_SC04_018", + "src_addr": "0x8017d77c", + "src_name": "func_8017d77c", + "stubs": [ + { + "ov": "ov_SC04_019", + "addr": "0x8017d77c" + } + ] + }, + { + "h": "7eaa565887f90feb2cb7dcaa718b3fee74608f17", + "nins": 33, + "n_stub": 4, + "n_matched": 134, + "src_bin": "ov_SC03_090", + "src_addr": "0x8016325c", + "src_name": "func_8016325c", + "stubs": [ + { + "ov": "ov_SC07_006", + "addr": "0x8016325c" + }, + { + "ov": "ov_SC07_011", + "addr": "0x8016325c" + }, + { + "ov": "ov_SC07_007", + "addr": "0x8016325c" + }, + { + "ov": "ov_SC07_010", + "addr": "0x8016325c" + } + ] + }, + { + "h": "5c389edd6f1adc9f5caaab5a7f28d3d0654f5445", + "nins": 114, + "n_stub": 1, + "n_matched": 1, + "src_bin": "ov_SC04_018", + "src_addr": "0x80184fa4", + "src_name": "func_80184fa4", + "stubs": [ + { + "ov": "ov_SC04_019", + "addr": "0x80184fa4" + } + ] + }, + { + "h": "1c5bc11f816e9ed71badae45bfb8bee66eef7a77", + "nins": 22, + "n_stub": 4, + "n_matched": 134, + "src_bin": "ov_SC03_090", + "src_addr": "0x8016bf50", + "src_name": "func_8016bf50", + "stubs": [ + { + "ov": "ov_SC07_006", + "addr": "0x8016bf50" + }, + { + "ov": "ov_SC07_011", + "addr": "0x8016bf50" + }, + { + "ov": "ov_SC07_007", + "addr": "0x8016bf50" + }, + { + "ov": "ov_SC07_010", + "addr": "0x8016bf50" + } + ] + }, + { + "h": "943e9c67c928b071dc67019db84a6cf8a629c162", + "nins": 80, + "n_stub": 1, + "n_matched": 1, + "src_bin": "ov_SC04_018", + "src_addr": "0x8017e26c", + "src_name": "func_8017e26c", + "stubs": [ + { + "ov": "ov_SC04_019", + "addr": "0x8017e26c" + } + ] + }, + { + "h": "f9e9ba7876c4640f6c72517e3c11e741d6f335b8", + "nins": 11, + "n_stub": 7, + "n_matched": 2, + "src_bin": "ov_SC02_005", + "src_addr": "0x801903dc", + "src_name": "func_801903dc", + "stubs": [ + { + "ov": "ov_SC07_002", + "addr": "0x8018672c" + }, + { + "ov": "ov_SC06_006", + "addr": "0x8018146c" + }, + { + "ov": "ov_SC03_105", + "addr": "0x801896ec" + }, + { + "ov": "ov_SC07_011", + "addr": "0x8017e5c4" + }, + { + "ov": "ov_SC06_029", + "addr": "0x8018b1e0" + }, + { + "ov": "ov_SC03_028", + "addr": "0x8018b234" + }, + { + "ov": "ov_SC05_010", + "addr": "0x80187b80" + } + ] + }, + { + "h": "f085c45fa0abb4467493fac3b7e16ef9f83be368", + "nins": 72, + "n_stub": 1, + "n_matched": 1, + "src_bin": "ov_SC04_018", + "src_addr": "0x8018613c", + "src_name": "func_8018613c", + "stubs": [ + { + "ov": "ov_SC04_019", + "addr": "0x8018613c" + } + ] + }, + { + "h": "7921cb4a22e0943444a312753fc16bed5f87f946", + "nins": 68, + "n_stub": 1, + "n_matched": 137, + "src_bin": "ov_SC03_090", + "src_addr": "0x80149954", + "src_name": "func_80149954", + "stubs": [ + { + "ov": "ov_SC07_006", + "addr": "0x80149954" + } + ] + }, + { + "h": "3c9a6d8e20bbd5ea59810eb0ed8057774aca74d2", + "nins": 10, + "n_stub": 6, + "n_matched": 1, + "src_bin": "ov_SC03_028", + "src_addr": "0x8017bee0", + "src_name": "func_8017bee0", + "stubs": [ + { + "ov": "ov_SC07_002", + "addr": "0x8017bee0" + }, + { + "ov": "ov_SC06_030", + "addr": "0x8017bee0" + }, + { + "ov": "ov_SC03_105", + "addr": "0x8017bee0" + }, + { + "ov": "ov_SC06_029", + "addr": "0x8017bee0" + }, + { + "ov": "ov_SC06_016", + "addr": "0x8017bee0" + }, + { + "ov": "ov_SC05_010", + "addr": "0x8017bee0" + } + ] + }, + { + "h": "8eaa5e59bf160652c661e17ec2f29582b2f72134", + "nins": 14, + "n_stub": 4, + "n_matched": 134, + "src_bin": "ov_SC03_090", + "src_addr": "0x8016f0ac", + "src_name": "func_8016f0ac", + "stubs": [ + { + "ov": "ov_SC07_006", + "addr": "0x8016f0ac" + }, + { + "ov": "ov_SC07_011", + "addr": "0x8016f0ac" + }, + { + "ov": "ov_SC07_007", + "addr": "0x8016f0ac" + }, + { + "ov": "ov_SC07_010", + "addr": "0x8016f0ac" + } + ] + }, + { + "h": "e15e89635674d75ee451bf958fc88db143f045ce", + "nins": 18, + "n_stub": 3, + "n_matched": 7, + "src_bin": "ov_SC04_019", + "src_addr": "0x80184cb8", + "src_name": "func_80184cb8", + "stubs": [ + { + "ov": "ov_SC03_002", + "addr": "0x80183264" + }, + { + "ov": "ov_SC03_124", + "addr": "0x801843e0" + }, + { + "ov": "ov_SC05_018", + "addr": "0x8018469c" + } + ] + }, + { + "h": "036f6784472c2e084e9f118acd6624880794c691", + "nins": 53, + "n_stub": 1, + "n_matched": 137, + "src_bin": "ov_SC03_090", + "src_addr": "0x80176144", + "src_name": "func_80176144", + "stubs": [ + { + "ov": "ov_SC07_006", + "addr": "0x80176144" + } + ] + }, + { + "h": "9402da97816880a36ad94d99b408f55b76f5a743", + "nins": 10, + "n_stub": 5, + "n_matched": 1, + "src_bin": "ov_SC03_015", + "src_addr": "0x8017bfa0", + "src_name": "func_8017bfa0", + "stubs": [ + { + "ov": "ov_SC06_000", + "addr": "0x8017bfa0" + }, + { + "ov": "ov_SC03_119", + "addr": "0x8017bfa0" + }, + { + "ov": "ov_SC03_024", + "addr": "0x8017bfa0" + }, + { + "ov": "ov_SC03_118", + "addr": "0x8017bfa0" + }, + { + "ov": "ov_SC03_014", + "addr": "0x8017bfa0" + } + ] + }, + { + "h": "1e4b7e74954abeff04f23546c53496534a80323f", + "nins": 12, + "n_stub": 4, + "n_matched": 6, + "src_bin": "ov_SC05_017", + "src_addr": "0x8018c390", + "src_name": "func_8018c390", + "stubs": [ + { + "ov": "ov_SC03_002", + "addr": "0x80185000" + }, + { + "ov": "ov_SC04_019", + "addr": "0x8018c93c" + }, + { + "ov": "ov_SC03_124", + "addr": "0x80181840" + }, + { + "ov": "ov_SC03_001", + "addr": "0x80186dac" + } + ] + }, + { + "h": "d46924f562575935824a936908bf7c33839c9f3d", + "nins": 8, + "n_stub": 5, + "n_matched": 8, + "src_bin": "ov_SC06_000", + "src_addr": "0x801828fc", + "src_name": "func_801828fc", + "stubs": [ + { + "ov": "ov_SC07_000", + "addr": "0x8017eec0" + }, + { + "ov": "ov_SC04_011", + "addr": "0x801873d8" + }, + { + "ov": "ov_SC03_117", + "addr": "0x8017e99c" + }, + { + "ov": "ov_SC03_092", + "addr": "0x8017f29c" + }, + { + "ov": "ov_SC06_022", + "addr": "0x801809d4" + } + ] + }, + { + "h": "5fd744e3b3557e0f8724f7ecd1d858ae6f6c783d", + "nins": 8, + "n_stub": 3, + "n_matched": 2, + "src_bin": "ov_SC06_029", + "src_addr": "0x8017e22c", + "src_name": "func_8017e22c", + "stubs": [ + { + "ov": "ov_SC06_027", + "addr": "0x8017cd9c" + }, + { + "ov": "ov_SC07_006", + "addr": "0x8017cd9c" + }, + { + "ov": "ov_SC07_000", + "addr": "0x8017d8c4" + } + ] + }, + { + "h": "37f67f3adb2e4e2b3392abbf4d460a287e3a0242", + "nins": 8, + "n_stub": 3, + "n_matched": 146, + "src_bin": "ov_SC03_090", + "src_addr": "0x80181064", + "src_name": "func_80181064", + "stubs": [ + { + "ov": "ov_SC03_097", + "addr": "0x8017eb98" + }, + { + "ov": "ov_SC03_097", + "addr": "0x8017ed58" + }, + { + "ov": "ov_SC03_119", + "addr": "0x8018188c" + } + ] + }, + { + "h": "c6c23e9bfdd04113a6b33171b3ed7266403a444c", + "nins": 22, + "n_stub": 1, + "n_matched": 1, + "src_bin": "ov_SC03_014", + "src_addr": "0x8018a808", + "src_name": "func_8018a808", + "stubs": [ + { + "ov": "ov_SC03_015", + "addr": "0x8018a808" + } + ] + }, + { + "h": "e48771d313459b926e2e0daee3f51f499e2c8b52", + "nins": 20, + "n_stub": 1, + "n_matched": 1, + "src_bin": "ov_SC04_018", + "src_addr": "0x8017d9b8", + "src_name": "func_8017d9b8", + "stubs": [ + { + "ov": "ov_SC04_019", + "addr": "0x8017d9b8" + } + ] + }, + { + "h": "3b4847517d5f0eb7020328ccfe75c14f3cf73c50", + "nins": 19, + "n_stub": 1, + "n_matched": 1, + "src_bin": "ov_SC04_018", + "src_addr": "0x8018625c", + "src_name": "func_8018625c", + "stubs": [ + { + "ov": "ov_SC04_019", + "addr": "0x8018625c" + } + ] + }, + { + "h": "5cdf578fa304ee37e3eb61e4a740519563bbc97d", + "nins": 17, + "n_stub": 1, + "n_matched": 8, + "src_bin": "ov_SC07_002", + "src_addr": "0x80186758", + "src_name": "func_80186758", + "stubs": [ + { + "ov": "ov_SC06_029", + "addr": "0x8018b20c" + } + ] + }, + { + "h": "fb0a4d4e82bde5a4bce5ce860081aab9edea2725", + "nins": 8, + "n_stub": 2, + "n_matched": 2, + "src_bin": "ov_SC03_104", + "src_addr": "0x80183c30", + "src_name": "func_80183c30", + "stubs": [ + { + "ov": "ov_SC03_097", + "addr": "0x80180294" + }, + { + "ov": "ov_SC03_101", + "addr": "0x801807f4" + } + ] + }, + { + "h": "71090d436f9f2f5f3b433a114ab1ae53509c6f8d", + "nins": 8, + "n_stub": 2, + "n_matched": 4, + "src_bin": "ov_SC06_000", + "src_addr": "0x8018467c", + "src_name": "func_8018467c", + "stubs": [ + { + "ov": "ov_SC03_119", + "addr": "0x80182550" + }, + { + "ov": "ov_SC03_015", + "addr": "0x80188d64" + } + ] + }, + { + "h": "30a60e301291fb6ce0442a1a70228ac77c8901e1", + "nins": 16, + "n_stub": 1, + "n_matched": 9, + "src_bin": "ov_SC03_002", + "src_addr": "0x80183070", + "src_name": "func_80183070", + "stubs": [ + { + "ov": "ov_SC05_018", + "addr": "0x801844a8" + } + ] + }, + { + "h": "930dd93cc9191ac7418bc2659eff24f50febbb59", + "nins": 15, + "n_stub": 1, + "n_matched": 1, + "src_bin": "ov_SC05_005", + "src_addr": "0x80180900", + "src_name": "func_80180900", + "stubs": [ + { + "ov": "ov_SC05_003", + "addr": "0x801807f8" + } + ] + }, + { + "h": "b991054fed76db618078a2fbf15aae982a8321b6", + "nins": 15, + "n_stub": 1, + "n_matched": 2, + "src_bin": "ov_SC03_014", + "src_addr": "0x8017bfc8", + "src_name": "func_8017bfc8", + "stubs": [ + { + "ov": "ov_SC03_015", + "addr": "0x8017bfc8" + } + ] + }, + { + "h": "3958d867cae66ae3d782a3e05126db735ac0c460", + "nins": 14, + "n_stub": 1, + "n_matched": 1, + "src_bin": "ov_SC03_029", + "src_addr": "0x801818b4", + "src_name": "func_801818b4", + "stubs": [ + { + "ov": "ov_SC02_011", + "addr": "0x80187800" + } + ] + }, + { + "h": "4fccf14e5b8054014b145c6a4c0ef44d7104231d", + "nins": 14, + "n_stub": 1, + "n_matched": 1, + "src_bin": "ov_SC04_007", + "src_addr": "0x80184394", + "src_name": "func_80184394", + "stubs": [ + { + "ov": "ov_SC04_005", + "addr": "0x801831f0" + } + ] + }, + { + "h": "d3861d4935f9ed4fadacf51461642780ebe28b3a", + "nins": 13, + "n_stub": 1, + "n_matched": 1, + "src_bin": "ov_SC04_019", + "src_addr": "0x8017e230", + "src_name": "func_8017e230", + "stubs": [ + { + "ov": "ov_SC04_018", + "addr": "0x8017e230" + } + ] + }, + { + "h": "0f3f34484ff38f8b177fd5808c3920da6b4ec31c", + "nins": 4, + "n_stub": 3, + "n_matched": 135, + "src_bin": "ov_SC03_090", + "src_addr": "0x8014cbe8", + "src_name": "func_8014cbe8", + "stubs": [ + { + "ov": "ov_SC07_006", + "addr": "0x8014cbe8" + }, + { + "ov": "ov_SC07_011", + "addr": "0x8014cbe8" + }, + { + "ov": "ov_SC07_007", + "addr": "0x8014cbe8" + } + ] + }, + { + "h": "8b9d73c69ced5e8519da1a77b6341b3d28da21ed", + "nins": 12, + "n_stub": 1, + "n_matched": 1, + "src_bin": "ov_SC03_118", + "src_addr": "0x801855f0", + "src_name": "func_801855f0", + "stubs": [ + { + "ov": "ov_SC03_119", + "addr": "0x801855f0" + } + ] + }, + { + "h": "97cafd5a05d97e9346c366def480439ebf3bf174", + "nins": 10, + "n_stub": 1, + "n_matched": 1, + "src_bin": "ov_SC03_015", + "src_addr": "0x80182bd4", + "src_name": "func_80182bd4", + "stubs": [ + { + "ov": "ov_SC03_014", + "addr": "0x80182bd4" + } + ] + }, + { + "h": "966e4d16d3dc015c2e028e4d4a3361fc0f5283c0", + "nins": 10, + "n_stub": 1, + "n_matched": 3, + "src_bin": "ov_SC03_097", + "src_addr": "0x8017f994", + "src_name": "func_8017f994", + "stubs": [ + { + "ov": "ov_SC03_093", + "addr": "0x8017f548" + } + ] + }, + { + "h": "8bc87e72d16f4a0755c469cfbc86997e3229270d", + "nins": 9, + "n_stub": 1, + "n_matched": 1, + "src_bin": "ov_SC05_005", + "src_addr": "0x80180f3c", + "src_name": "func_80180f3c", + "stubs": [ + { + "ov": "ov_SC05_003", + "addr": "0x80180e34" + } + ] + }, + { + "h": "a88cb6e7620d2650764619efb32d0dca9674be01", + "nins": 9, + "n_stub": 1, + "n_matched": 1, + "src_bin": "ov_SC03_015", + "src_addr": "0x80182bb0", + "src_name": "func_80182bb0", + "stubs": [ + { + "ov": "ov_SC03_014", + "addr": "0x80182bb0" + } + ] + }, + { + "h": "b3bec0e2c14444e681b0293612bcec0b58baf41b", + "nins": 9, + "n_stub": 1, + "n_matched": 9, + "src_bin": "ov_SC03_002", + "src_addr": "0x80183158", + "src_name": "func_80183158", + "stubs": [ + { + "ov": "ov_SC05_018", + "addr": "0x80184590" + } + ] + }, + { + "h": "7f3d0ea0cfdf9631f927117478171dbc48237299", + "nins": 8, + "n_stub": 1, + "n_matched": 1, + "src_bin": "ov_SC06_033", + "src_addr": "0x8017d3f0", + "src_name": "func_8017d3f0", + "stubs": [ + { + "ov": "ov_SC06_032", + "addr": "0x8017d12c" + } + ] + }, + { + "h": "79ff94814358ab5182cdf229e775dd0e78908a12", + "nins": 8, + "n_stub": 1, + "n_matched": 4, + "src_bin": "ov_SC06_020", + "src_addr": "0x8017d12c", + "src_name": "func_8017d12c", + "stubs": [ + { + "ov": "ov_SC06_008", + "addr": "0x8017d174" + } + ] + }, + { + "h": "0ac0e5e6754a22d27794d13f5be51a6314bccd3a", + "nins": 8, + "n_stub": 1, + "n_matched": 2, + "src_bin": "ov_SC03_124", + "src_addr": "0x8018a698", + "src_name": "func_8018a698", + "stubs": [ + { + "ov": "ov_SC03_119", + "addr": "0x80188f90" + } + ] + }, + { + "h": "53ccaf0755a5f6a2a9d32c667dcfcb0c2b19ea7b", + "nins": 8, + "n_stub": 1, + "n_matched": 2, + "src_bin": "ov_SC03_121", + "src_addr": "0x8017f978", + "src_name": "func_8017f978", + "stubs": [ + { + "ov": "ov_SC03_014", + "addr": "0x801880f8" + } + ] + }, + { + "h": "1fd8f71f4aed90d8d1a77a8fa9ebbb114bf90eeb", + "nins": 8, + "n_stub": 1, + "n_matched": 2, + "src_bin": "ov_SC06_000", + "src_addr": "0x801828dc", + "src_name": "func_801828dc", + "stubs": [ + { + "ov": "ov_SC03_092", + "addr": "0x8017f49c" + } + ] + }, + { + "h": "7a07049ae88adabeadebf21b4ecc73192cbaec07", + "nins": 8, + "n_stub": 1, + "n_matched": 8, + "src_bin": "ov_SC07_002", + "src_addr": "0x80181bd8", + "src_name": "func_80181bd8", + "stubs": [ + { + "ov": "ov_SC06_022", + "addr": "0x8017f9fc" + } + ] + }, + { + "h": "208db74d45603527e57fc42660cf875d62482105", + "nins": 2, + "n_stub": 1, + "n_matched": 2, + "src_bin": "ov_SC02_031", + "src_addr": "0x801829a0", + "src_name": "func_801829a0", + "stubs": [ + { + "ov": "ov_SC04_010", + "addr": "0x8017d6c4" + } + ] + } +] \ No newline at end of file diff --git a/.run/s9_cal.js b/.run/s9_cal.js new file mode 100644 index 000000000..b9a301f4e --- /dev/null +++ b/.run/s9_cal.js @@ -0,0 +1,145 @@ +export const meta = { + name: 'p30-s9-x29-calibration', + description: 'P30 wave 4b: draft the volume-lane B-shape families (10-19 members, <=60 ins)', + phases: [ + { title: 'Draft', detail: 'one agent per target, size-routed per the §136i ladder (haiku/sonnet/opus)' }, + { title: 'Escalate', detail: 'next rung up (haiku->sonnet, sonnet->opus) on any non-MATCH' }, + ], +} + +// args = { targets: [...compact records...], extra: "" } +// Accept a JSON string too — an invocation can deliver args stringified and pipeline() then dies. +const A = {targets: [{"fn": "func_8017D174", "ov": "ov_SC03_103", "sub": "asm/ov_SC03_103/nonmatchings/ov_SC03_103_jr_8017C294", "tu": "src/ov_SC03_103/ov_SC03_103_jr_8017C294.c", "n": 793, "m": 5, "ti": 3965, "stratum": "head", "model": "opus", "seed": 1}, {"fn": "func_8017DF84", "ov": "ov_SC03_014", "sub": "asm/ov_SC03_014/nonmatchings/ov_SC03_014_jr_8017AE2C", "tu": "src/ov_SC03_014/ov_SC03_014_jr_8017AE2C.c", "n": 766, "m": 5, "ti": 3830, "stratum": "head", "model": "opus", "seed": 1}, {"fn": "func_80186E24", "ov": "ov_SC04_018", "sub": "asm/ov_SC04_018/nonmatchings/ov_SC04_018_jr_8017AE2C", "tu": "src/ov_SC04_018/ov_SC04_018_jr_8017AE2C.c", "n": 611, "m": 5, "ti": 3055, "stratum": "head", "model": "opus", "seed": 1}, {"fn": "func_80186B78", "ov": "ov_SC03_118", "sub": "asm/ov_SC03_118/nonmatchings/ov_SC03_118_jr_8017FB84", "tu": "src/ov_SC03_118/ov_SC03_118_jr_8017FB84.c", "n": 386, "m": 7, "ti": 2702, "stratum": "head", "model": "opus", "seed": 0}, {"fn": "func_8018165C", "ov": "ov_SC06_008", "sub": "asm/ov_SC06_008/nonmatchings/ov_SC06_008_jr_8017C294", "tu": "src/ov_SC06_008/ov_SC06_008_jr_8017C294.c", "n": 305, "m": 7, "ti": 2135, "stratum": "head", "model": "opus", "seed": 1}, {"fn": "func_8017E2EC", "ov": "ov_SC03_114", "sub": "asm/ov_SC03_114/nonmatchings/ov_SC03_114_jr_8017BEBC", "tu": "src/ov_SC03_114/ov_SC03_114_jr_8017BEBC.c", "n": 296, "m": 7, "ti": 2072, "stratum": "head", "model": "opus", "seed": 1}, {"fn": "func_801823F0", "ov": "ov_SC06_008", "sub": "asm/ov_SC06_008/nonmatchings/ov_SC06_008_jr_8017C294", "tu": "src/ov_SC06_008/ov_SC06_008_jr_8017C294.c", "n": 274, "m": 7, "ti": 1918, "stratum": "head", "model": "opus", "seed": 1}, {"fn": "func_80182A48", "ov": "ov_SC06_008", "sub": "asm/ov_SC06_008/nonmatchings/ov_SC06_008_jr_8017C294", "tu": "src/ov_SC06_008/ov_SC06_008_jr_8017C294.c", "n": 273, "m": 7, "ti": 1911, "stratum": "head", "model": "opus", "seed": 1}, {"fn": "func_80183E04", "ov": "ov_SC03_028", "sub": "asm/ov_SC03_028/nonmatchings/ov_SC03_028_jr_8017AE2C", "tu": "src/ov_SC03_028/ov_SC03_028_jr_8017AE2C.c", "n": 265, "m": 7, "ti": 1855, "stratum": "head", "model": "opus", "seed": 1}, {"fn": "func_80180CA8", "ov": "ov_SC06_008", "sub": "asm/ov_SC06_008/nonmatchings/ov_SC06_008_jr_8017C294", "tu": "src/ov_SC06_008/ov_SC06_008_jr_8017C294.c", "n": 257, "m": 7, "ti": 1799, "stratum": "head", "model": "opus", "seed": 1}, {"fn": "func_801894F0", "ov": "ov_SC06_018", "sub": "asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C", "tu": "src/ov_SC06_018/ov_SC06_018_jr_8017C24C.c", "n": 281, "m": 6, "ti": 1686, "stratum": "head", "model": "opus", "seed": 1}, {"fn": "func_801886B0", "ov": "ov_SC06_018", "sub": "asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C", "tu": "src/ov_SC06_018/ov_SC06_018_jr_8017C24C.c", "n": 276, "m": 6, "ti": 1656, "stratum": "head", "model": "opus", "seed": 1}, {"fn": "func_8017C290", "ov": "ov_SC03_014", "sub": "asm/ov_SC03_014/nonmatchings/ov_SC03_014_jr_8017AE2C", "tu": "src/ov_SC03_014/ov_SC03_014_jr_8017AE2C.c", "n": 229, "m": 7, "ti": 1603, "stratum": "body", "model": "opus", "seed": 0}, {"fn": "func_8017E170", "ov": "ov_SC03_114", "sub": "asm/ov_SC03_114/nonmatchings/ov_SC03_114_jr_8017BEBC", "tu": "src/ov_SC03_114/ov_SC03_114_jr_8017BEBC.c", "n": 64, "m": 7, "ti": 448, "stratum": "body", "model": "sonnet", "seed": 1}, {"fn": "func_8017E3E0", "ov": "ov_SC01_074", "sub": "asm/ov_SC01_074/nonmatchings/ov_SC01_074_jr_8017BE9C", "tu": "src/ov_SC01_074/ov_SC01_074_jr_8017BE9C.c", "n": 58, "m": 5, "ti": 290, "stratum": "body", "model": "sonnet", "seed": 1}, {"fn": "func_8018E780", "ov": "ov_SC02_011", "sub": "asm/ov_SC02_011/nonmatchings/ov_SC02_011_jr_8017AE2C", "tu": "src/ov_SC02_011/ov_SC02_011_jr_8017AE2C.c", "n": 72, "m": 3, "ti": 216, "stratum": "body", "model": "sonnet", "seed": 1}, {"fn": "func_80181CDC", "ov": "ov_SC05_003", "sub": "asm/ov_SC05_003/nonmatchings/ov_SC05_003_jr_8017BEBC", "tu": "src/ov_SC05_003/ov_SC05_003_jr_8017BEBC.c", "n": 89, "m": 2, "ti": 178, "stratum": "body", "model": "sonnet", "seed": 1}, {"fn": "func_8018C518", "ov": "ov_SC04_018", "sub": "asm/ov_SC04_018/nonmatchings/ov_SC04_018_jr_8017AE2C", "tu": "src/ov_SC04_018/ov_SC04_018_jr_8017AE2C.c", "n": 37, "m": 4, "ti": 148, "stratum": "body", "model": "haiku", "seed": 0}, {"fn": "func_80182058", "ov": "ov_SC02_000", "sub": "asm/ov_SC02_000/nonmatchings/ov_SC02_000_jr_8017FCB0", "tu": "src/ov_SC02_000/ov_SC02_000_jr_8017FCB0.c", "n": 63, "m": 2, "ti": 126, "stratum": "body", "model": "sonnet", "seed": 1}, {"fn": "func_8018AF88", "ov": "ov_SC06_018", "sub": "asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C", "tu": "src/ov_SC06_018/ov_SC06_018_jr_8017C24C.c", "n": 54, "m": 2, "ti": 108, "stratum": "body", "model": "sonnet", "seed": 1}, {"fn": "func_801839C4", "ov": "ov_SC02_000", "sub": "asm/ov_SC02_000/nonmatchings/ov_SC02_000_jr_8017FCB0", "tu": "src/ov_SC02_000/ov_SC02_000_jr_8017FCB0.c", "n": 45, "m": 2, "ti": 90, "stratum": "body", "model": "haiku", "seed": 1}, {"fn": "func_801812F8", "ov": "ov_SC06_022", "sub": "asm/ov_SC06_022/nonmatchings/ov_SC06_022_jr_8017BEBC", "tu": "src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c", "n": 39, "m": 2, "ti": 78, "stratum": "body", "model": "haiku", "seed": 1}, {"fn": "func_8018BC40", "ov": "ov_SC06_018", "sub": "asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C", "tu": "src/ov_SC06_018/ov_SC06_018_jr_8017C24C.c", "n": 33, "m": 2, "ti": 66, "stratum": "body", "model": "haiku", "seed": 1}, {"fn": "func_8017D5EC", "ov": "ov_SC07_009", "sub": "asm/ov_SC07_009/nonmatchings/ov_SC07_009_jr_8017AE2C", "tu": "src/ov_SC07_009/ov_SC07_009_jr_8017AE2C.c", "n": 18, "m": 3, "ti": 54, "stratum": "body", "model": "haiku", "seed": 1}, {"fn": "func_8017EC90", "ov": "ov_SC04_016", "sub": "asm/ov_SC04_016/nonmatchings/ov_SC04_016_jr_8017BEBC", "tu": "src/ov_SC04_016/ov_SC04_016_jr_8017BEBC.c", "n": 20, "m": 2, "ti": 40, "stratum": "body", "model": "haiku", "seed": 1}], extra: "START HERE \u2014 SIBLING-FIRST IS THE FASTEST ROUTE (\u00a7136c, measured this session: it produced several\nFIRST-DRAFT matches). Before you derive anything from the .s:\n 1. grep src/shared/engine_core.h for a `DEFINE_func_*` macro body that is a NEAR-TWIN of your\n target (same struct-offset chain, same shape, differing only in constants/one call). This is a\n family wave \u2014 the twin usually EXISTS, because that is what a family is.\n 2. grep your own TU for an already-BANKED sibling (a real function definition, not an INCLUDE_ASM).\n 3. Reuse its EXPRESSION FORMS and its DECLARATION FORMS verbatim. They are already byte-proven to\n produce the gcc-2.7.2 schedule and register assignment you need.\nSearch order: engine_core.h near-twin -> same-TU banked sibling -> the .s -> the Ghidra seed LAST\n(the seed was byte-proven to be an ENTIRELY DIFFERENT body twice this session).\n\nTHE LOCAL-VARIABLE LEVER (\u00a7136 \u2014 highest-yield finding, 25 banks). gcc-2.7.2 allocates ONE PSEUDO\nPER C LOCAL, and local-alloc.c:472 REFUSES a local allocno whose REG_N_DEATHS > 1 \u2014 promoting it to\na GLOBAL allocno that loses the low register. The number and scope of your locals moves whole\nregister assignments. REACH FOR THIS BEFORE register __asm__ PINS.\n L1. Same $v0/$v1 pair swapped in ONE arm only => you reused ONE local across N arms. SPLIT it into\n per-arm block-scoped locals.\n L2. One extra `sw $sN` in the prologue, frame otherwise identical => SPLIT a compound initializer:\n `x = *(u8*)p << k;` makes TWO pseudos; `x = *(u8*)p; x = x << k;` reuses one.\n L3. An extra `addu $vX,$v0,$zero` after a `jal` AND a later copy of the same value => the source\n had TWO variables with the first PINNED (an unpinned pseudo coalesces the pair away).\n L4. LENGTH-DRIFT short by `addiu $sN,$sp,K` + a save/restore pair => write a POINTER local assigned\n before the loop and used only inside it.\n L5. Local stack slots are assigned in DECLARATION order ascending from 0x10, independent of use\n order. Frame-offset drift with correct code is a declaration-ORDER problem.\n\nTYPE-FORM RULES:\n T1. A real `mult $rX,$rY` with a small constant => the multiplier is a NON-CONST LOCAL, not a\n literal (a literal goes through synth_mult's sll/addu chain). `s32 r = K;` as its own statement.\n T2. `li $sN,0xfff0` + `addu` where the target has `addiu $vN,$vN,-0x10` => gcc narrowed to HImode.\n Hoist the call to its own statement; put the load+subtract in a BLOCK-SCOPED s32 temp.\n T3. `andi $vN,0xffff` after a `jal` the target lacks => the TU declares that callee u16/s16-\n returning. Do NOT change the decl \u2014 cast at the call (idiom 9 on the RETURN axis).\n T4. Unexplained `addu $vX,$aY,$zero` near a conditional branch (including in its DELAY SLOT,\n consumed only by the fall-through arm) + the feeding `lh` loads out of order => the value is an\n s16 LOCAL, not s32; LOAD_EXTEND_OP folded the widening extend into a plain move.\n T5. LENGTH-DRIFT +1 with a narrow load of the SAME stack slot => gcc narrowed a memory-operand\n `local >> 16`. Bind the local to an s32 temp used twice.\n T6. A symbol read once at a constant offset but built into $s1 by lui/addiu => cache it in a\n POINTER LOCAL. A direct D_xxx[k] folds %lo per use and shrinks the frame.\n T7. BRANCH POLARITY: if match_one prints BRANCH-POLARITY, invert the source condition \u2014 gcc-2.7.2\n flips the branch to place the longer block as the fall-through. (Closed 8 mismatches in one\n edit this wave; the index keys the literal string \"BRANCH-POLARITY\" straight to \u00a73-T4.)\n\nSCHEDULING:\n S1. The MEM_IN_STRUCT_P escape does NOT apply when the blocking store has a VARYING (register-base)\n address \u2014 true_dependence() only drops the edge for a CONSTANT-address store. Then the lever is\n SOURCE ORDER: assign the load to a temp ABOVE the stores. (But same-base `reg+const` addresses\n ARE disambiguated by memrefs_conflict_p, so those hoists are free.)\n S2. An unfilled load-delay nop where the target fills it with a trailing call's arg setup => hoist a\n LOAD: split `*p = *p + 1` into `v = *p + 1; ... *p = v;`.\n S3. NEVER pin an incoming PARAMETER \u2014 it turns the param's `move` into a schedulable body insn and\n reshuffles the whole prologue. Pin loop variables only.\n S4. If no C lever moves a 3-6 instruction schedule/regalloc residual, a \u00a721 ZERO-BYTE RE-TIE\n barrier can anchor it: `__asm__ __volatile__(\"\" : \"=r\"(v) : \"0\"(v));` between the loads and the\n use. Try the source-level levers first; this closed one case after six other variants failed.\n\nDECLARATION SURFACE (decides whether a byte-correct draft BANKS):\n D1. `conflicting types` for a D_ symbol you cannot find declared in the split .c => the decl lives\n inside a DEFINE_func_*() MACRO BODY in src/shared/engine_core.h. Reuse its canonical type.\n An 8-byte-stride table declared `s32 D_x[][2]` must be indexed [i][0]/[i][1].\n D2. cc1 reports only the FIRST conflict. EVERY reconciled draft this session had a SECOND hidden\n conflict, sometimes BELOW the splice point. grep the WHOLE TU in ONE pass for every symbol.\n D3. A DECLARATION CONFLICT ABORTS THE COMPILE, so it hides the byte question entirely. If you are\n handed a draft as \"byte-correct, only declaration-blocked\", RUN match_one ON IT FIRST \u2014 two of\n three such drafts this session also had a real codegen residual behind the conflict.\n D4. If you compile anything, use a PROCESS-UNIQUE scratch path. A shared one silently compiled\n another agent's file and returned a meaningless success this session.\n\n\nTHIS IS A x2-9 FAMILY (2-9 members), not a x100+ family. Two consequences:\n * \u00a7136c SIBLING-FIRST still applies but is LESS likely to hit \u2014 check whether a banked sibling or an\n engine_core.h DEFINE_func_* near-twin actually EXISTS before spending greps on it (\u00a7136e). If the\n whole family is in nonmatchings, go straight to the .s.\n * \u00a7136j: on this band expect a MIX \u2014 sub-120-ins targets tend to fail on DECLARATIONS, 120+ on real\n codegen. Do the whole-TU one-pass symbol grep (D2) regardless; it is the cheapest thing you can do.\n"} +const T = Array.isArray(A) ? A : A.targets +const EXTRA = (Array.isArray(A) ? '' : A.extra) || '' +if (!Array.isArray(T)) throw new Error('args.targets must be an array') + +const VERDICT = { + type: 'object', + additionalProperties: false, + required: ['fn', 'status', 'summary'], + properties: { + fn: { type: 'string' }, + status: { type: 'string', enum: ['MATCH', 'DIFF', 'BLOCKED'] }, + closeness: { type: 'number', description: 'mismatching instructions remaining; 0 for MATCH' }, + klass: { type: 'string', description: 'residual class if not MATCH' }, + summary: { type: 'string', description: 'what you did and what the residual is, <=4 sentences' }, + levers: { type: 'string', description: 'cookbook sections / idioms that CLOSED the residual' }, + index_hit: { type: 'boolean' }, + index_gap: { type: 'string' }, + }, +} + +function prompt(t, escalated) { + const asm = `${t.sub}/${t.fn}.s` + return `You are matching ONE PS1 function to byte-identical gcc-2.7.2 output for the Brave Fencer +Musashi decompilation. Your ONLY deliverable is a C file at \`.run/s9/${t.ov}/${t.fn}.c\`. + +TARGET + function ${t.fn} + binary ${t.ov} + target asm ${asm} <- THE GROUND TRUTH. Read this FIRST and in full. + TU it lands in ${t.tu} + asm-subdir ${t.sub} + size ${t.n} instructions + leverage family of ${t.m} members / ${t.ti} templatable instructions — a byte-match here + propagates ${t.m}x across the fleet. +${t.seed ? ` ghidra seed .run/ghidra_c/${t.fn}.c <- A HINT ONLY. It is sometimes an ENTIRELY + DIFFERENT body (byte-proven this phase). If it disagrees with the .s, THE .s WINS.` : ` ghidra seed (none cached — work from the .s)`} +${t.retry ? ` ** RETRY ** A previous wave recorded: "${t.retry}". That is a data point, not a + verdict. Re-derive from the .s; do not assume the earlier verdict was right.` : ''} + +HOW TO WORK (this order is the measured-fastest) +1. \`docs/cookbook-index.md\` is a SYMPTOM-KEYED index of 364 byte-verified idioms. Grep it for your + residual's symptom BEFORE deriving anything. Measured: index-first took a wave's bank rate from + 57% to 100%. Then read the section it names in \`docs/matching-cookbook.md\`. + \`docs/gcc-2.7.2-map/{sched,regalloc,loop,cse_expr}.md\` is the compiler-source-derived map for + scheduling / register-allocation residuals. +2. Read the target \`.s\` completely: frame size, callee-saved registers, jal targets, every + \`%hi/%lo\` symbol. +3. Read the TU (${t.tu}) for EVERY symbol your draft will name. cc1 reports only the FIRST conflict, + so a draft can look one edit from done and hold three more. grep the whole TU in ONE pass. + Match its existing declarations EXACTLY; push any type disagreement to a CAST AT THE USE SITE + rather than redeclaring the symbol. +4. Write the draft, then verify: + .venv/bin/python tools/match_one.py ${t.fn} --c .run/s9/${t.ov}/${t.fn}.c --asm-subdir ${t.sub} + Iterate until it prints MATCH; it names the exact mismatching instructions. + +IDIOMS THAT CLOSED RESIDUALS IN THE LAST WAVES (cookbook §135 — all byte-verified) + 1. UNSIGNED switch index => pure equality chain, NO range test. No \`slti\` bound check in the + target's switch means the index is u32, not s32. + 2. \`a0[0x46]\` (ARRAY_REF) sets MEM_IN_STRUCT_P and lets a load HOIST past a constant-address + store; \`*(s16 *)((s32)a0 + 0x8C)\` (INDIRECT_REF) keeps the dependence. Many 4-instruction + "scheduling residuals" are just this type-form choice. + 3. A constant store whose top bit is set in the STORED width needs an UNSIGNED destination: + \`*(u16 *)p = 0x8C00\` emits \`ori\`; through \`s16\` it folds negative and emits \`addiu\`. + 4. The list scheduler PRESERVES the relative order of disambiguable stores. A store written late + in source SINKS. If a store lands too late, move it EARLIER IN SOURCE (not a permuter job). + 5. A \`short\` loop counter blocks strength reduction; walking explicit pointers (\`p++\`) + reproduces the original biv/giv set. + 6. Frame size off by a constant => DEAD LOCALS. If ALL diffs are \`sp\`-relative immediates off by + one constant delta, add the padding declaration. + 7. An INTERIOR address has no symbol — a \`lui/addiu\` pair can build an offset INTO a symbol. + Find the containing symbol in the data \`.s\` and index into it; declaring the interior address + as its own extern link-fails. + 8. NEVER redeclare a C-library name (\`memcpy\` etc.). + 9. Loose typing is pervasive: if the TU declares \`void f(void)\` but the asm passes \`$a0\`, call + through a cast — \`((void(*)(s32))f)(a0)\` — do NOT change the declaration. +${EXTRA ? `\nPROMOTED FROM THE PREVIOUS BATCH (fresh, byte-verified this session)\n${EXTRA}\n` : ''} +HARD RULES + * Write ONLY \`.run/s9/${t.ov}/${t.fn}.c\`. NEVER edit \`src/\`, \`asm/\`, \`config/\`, \`include/\`, + the Makefile, or any tracked file. + * Do NOT run \`make\`, \`make build\`, \`make extract\`, or \`tools/harvest_verify.py\`. The + whole-binary gate is the orchestrator's job and the sole arbiter of a match. + * \`match_one\` MATCH is NECESSARY BUT NOT SUFFICIENT — it compiles standalone and cannot see the + TU's other declarations. Step 3 is what makes a MATCH actually BANK. + * Report honestly. A DIFF with a precise residual class routes the next attempt; a false MATCH + just gets caught by the byte-gate and wastes a cycle. + * ${escalated ? 'A cheaper rung of the model ladder already attempted this and did not reach MATCH. Read its draft at the path above, but re-derive from the .s rather than trusting it.' : 'Work economically — most functions this size close from the .s plus one or two index lookups.'} + +Return the structured verdict.` +} + +phase('Draft') + +const results = await pipeline( + T, + (t) => agent(prompt(t, false), { + label: `draft:${t.fn}(${t.n}i,x${t.m})`, + phase: 'Draft', + model: t.model, + schema: VERDICT, + }).then((v) => ({ t, v })), + + async ({ t, v }) => { + if (!v) return { t, v: { fn: t.fn, status: 'BLOCKED', summary: 'agent returned no verdict' }, tier: t.model } + if (v.status === 'MATCH' || t.model === 'opus') return { t, v, tier: t.model } + // §136i ladder: haiku -> SONNET -> opus. Never haiku -> opus directly. + const nextTier = t.model === 'haiku' ? 'sonnet' : 'opus' + const v2 = await agent(prompt(t, true), { + label: `escalate:${t.fn}`, + phase: 'Escalate', + model: nextTier, + schema: VERDICT, + }) + return { t, v: v2 && v2.status === 'MATCH' ? v2 : (v2 || v), tier: nextTier + '-escalated' } + }, +) + +const ok = results.filter(Boolean) +const matched = ok.filter((r) => r.v && r.v.status === 'MATCH') +log(`wave4b: ${matched.length}/${T.length} claim MATCH (the gate is the arbiter)`) + +return { + claimed_match: matched.map((r) => r.t.fn), + verdicts: ok.map((r) => ({ + fn: r.t.fn, ov: r.t.ov, nins: r.t.n, members: r.t.m, tier: r.tier, + status: r.v ? r.v.status : 'NONE', + closeness: r.v ? r.v.closeness : null, + klass: r.v ? r.v.klass : null, + levers: r.v ? r.v.levers : null, + index_hit: r.v ? r.v.index_hit : null, + index_gap: r.v ? r.v.index_gap : null, + summary: r.v ? r.v.summary : null, + })), +} diff --git a/.run/s9_cal.json b/.run/s9_cal.json new file mode 100644 index 000000000..75f753633 --- /dev/null +++ b/.run/s9_cal.json @@ -0,0 +1 @@ +[{"fn":"func_8017D174","ov":"ov_SC03_103","sub":"asm/ov_SC03_103/nonmatchings/ov_SC03_103_jr_8017C294","tu":"src/ov_SC03_103/ov_SC03_103_jr_8017C294.c","n":793,"m":5,"ti":3965,"stratum":"head","model":"opus","seed":1},{"fn":"func_8017DF84","ov":"ov_SC03_014","sub":"asm/ov_SC03_014/nonmatchings/ov_SC03_014_jr_8017AE2C","tu":"src/ov_SC03_014/ov_SC03_014_jr_8017AE2C.c","n":766,"m":5,"ti":3830,"stratum":"head","model":"opus","seed":1},{"fn":"func_80186E24","ov":"ov_SC04_018","sub":"asm/ov_SC04_018/nonmatchings/ov_SC04_018_jr_8017AE2C","tu":"src/ov_SC04_018/ov_SC04_018_jr_8017AE2C.c","n":611,"m":5,"ti":3055,"stratum":"head","model":"opus","seed":1},{"fn":"func_80186B78","ov":"ov_SC03_118","sub":"asm/ov_SC03_118/nonmatchings/ov_SC03_118_jr_8017FB84","tu":"src/ov_SC03_118/ov_SC03_118_jr_8017FB84.c","n":386,"m":7,"ti":2702,"stratum":"head","model":"opus","seed":0},{"fn":"func_8018165C","ov":"ov_SC06_008","sub":"asm/ov_SC06_008/nonmatchings/ov_SC06_008_jr_8017C294","tu":"src/ov_SC06_008/ov_SC06_008_jr_8017C294.c","n":305,"m":7,"ti":2135,"stratum":"head","model":"opus","seed":1},{"fn":"func_8017E2EC","ov":"ov_SC03_114","sub":"asm/ov_SC03_114/nonmatchings/ov_SC03_114_jr_8017BEBC","tu":"src/ov_SC03_114/ov_SC03_114_jr_8017BEBC.c","n":296,"m":7,"ti":2072,"stratum":"head","model":"opus","seed":1},{"fn":"func_801823F0","ov":"ov_SC06_008","sub":"asm/ov_SC06_008/nonmatchings/ov_SC06_008_jr_8017C294","tu":"src/ov_SC06_008/ov_SC06_008_jr_8017C294.c","n":274,"m":7,"ti":1918,"stratum":"head","model":"opus","seed":1},{"fn":"func_80182A48","ov":"ov_SC06_008","sub":"asm/ov_SC06_008/nonmatchings/ov_SC06_008_jr_8017C294","tu":"src/ov_SC06_008/ov_SC06_008_jr_8017C294.c","n":273,"m":7,"ti":1911,"stratum":"head","model":"opus","seed":1},{"fn":"func_80183E04","ov":"ov_SC03_028","sub":"asm/ov_SC03_028/nonmatchings/ov_SC03_028_jr_8017AE2C","tu":"src/ov_SC03_028/ov_SC03_028_jr_8017AE2C.c","n":265,"m":7,"ti":1855,"stratum":"head","model":"opus","seed":1},{"fn":"func_80180CA8","ov":"ov_SC06_008","sub":"asm/ov_SC06_008/nonmatchings/ov_SC06_008_jr_8017C294","tu":"src/ov_SC06_008/ov_SC06_008_jr_8017C294.c","n":257,"m":7,"ti":1799,"stratum":"head","model":"opus","seed":1},{"fn":"func_801894F0","ov":"ov_SC06_018","sub":"asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C","tu":"src/ov_SC06_018/ov_SC06_018_jr_8017C24C.c","n":281,"m":6,"ti":1686,"stratum":"head","model":"opus","seed":1},{"fn":"func_801886B0","ov":"ov_SC06_018","sub":"asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C","tu":"src/ov_SC06_018/ov_SC06_018_jr_8017C24C.c","n":276,"m":6,"ti":1656,"stratum":"head","model":"opus","seed":1},{"fn":"func_8017C290","ov":"ov_SC03_014","sub":"asm/ov_SC03_014/nonmatchings/ov_SC03_014_jr_8017AE2C","tu":"src/ov_SC03_014/ov_SC03_014_jr_8017AE2C.c","n":229,"m":7,"ti":1603,"stratum":"body","model":"opus","seed":0},{"fn":"func_8017E170","ov":"ov_SC03_114","sub":"asm/ov_SC03_114/nonmatchings/ov_SC03_114_jr_8017BEBC","tu":"src/ov_SC03_114/ov_SC03_114_jr_8017BEBC.c","n":64,"m":7,"ti":448,"stratum":"body","model":"sonnet","seed":1},{"fn":"func_8017E3E0","ov":"ov_SC01_074","sub":"asm/ov_SC01_074/nonmatchings/ov_SC01_074_jr_8017BE9C","tu":"src/ov_SC01_074/ov_SC01_074_jr_8017BE9C.c","n":58,"m":5,"ti":290,"stratum":"body","model":"sonnet","seed":1},{"fn":"func_8018E780","ov":"ov_SC02_011","sub":"asm/ov_SC02_011/nonmatchings/ov_SC02_011_jr_8017AE2C","tu":"src/ov_SC02_011/ov_SC02_011_jr_8017AE2C.c","n":72,"m":3,"ti":216,"stratum":"body","model":"sonnet","seed":1},{"fn":"func_80181CDC","ov":"ov_SC05_003","sub":"asm/ov_SC05_003/nonmatchings/ov_SC05_003_jr_8017BEBC","tu":"src/ov_SC05_003/ov_SC05_003_jr_8017BEBC.c","n":89,"m":2,"ti":178,"stratum":"body","model":"sonnet","seed":1},{"fn":"func_8018C518","ov":"ov_SC04_018","sub":"asm/ov_SC04_018/nonmatchings/ov_SC04_018_jr_8017AE2C","tu":"src/ov_SC04_018/ov_SC04_018_jr_8017AE2C.c","n":37,"m":4,"ti":148,"stratum":"body","model":"haiku","seed":0},{"fn":"func_80182058","ov":"ov_SC02_000","sub":"asm/ov_SC02_000/nonmatchings/ov_SC02_000_jr_8017FCB0","tu":"src/ov_SC02_000/ov_SC02_000_jr_8017FCB0.c","n":63,"m":2,"ti":126,"stratum":"body","model":"sonnet","seed":1},{"fn":"func_8018AF88","ov":"ov_SC06_018","sub":"asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C","tu":"src/ov_SC06_018/ov_SC06_018_jr_8017C24C.c","n":54,"m":2,"ti":108,"stratum":"body","model":"sonnet","seed":1},{"fn":"func_801839C4","ov":"ov_SC02_000","sub":"asm/ov_SC02_000/nonmatchings/ov_SC02_000_jr_8017FCB0","tu":"src/ov_SC02_000/ov_SC02_000_jr_8017FCB0.c","n":45,"m":2,"ti":90,"stratum":"body","model":"haiku","seed":1},{"fn":"func_801812F8","ov":"ov_SC06_022","sub":"asm/ov_SC06_022/nonmatchings/ov_SC06_022_jr_8017BEBC","tu":"src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c","n":39,"m":2,"ti":78,"stratum":"body","model":"haiku","seed":1},{"fn":"func_8018BC40","ov":"ov_SC06_018","sub":"asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C","tu":"src/ov_SC06_018/ov_SC06_018_jr_8017C24C.c","n":33,"m":2,"ti":66,"stratum":"body","model":"haiku","seed":1},{"fn":"func_8017D5EC","ov":"ov_SC07_009","sub":"asm/ov_SC07_009/nonmatchings/ov_SC07_009_jr_8017AE2C","tu":"src/ov_SC07_009/ov_SC07_009_jr_8017AE2C.c","n":18,"m":3,"ti":54,"stratum":"body","model":"haiku","seed":1},{"fn":"func_8017EC90","ov":"ov_SC04_016","sub":"asm/ov_SC04_016/nonmatchings/ov_SC04_016_jr_8017BEBC","tu":"src/ov_SC04_016/ov_SC04_016_jr_8017BEBC.c","n":20,"m":2,"ti":40,"stratum":"body","model":"haiku","seed":1}] \ No newline at end of file diff --git a/.run/s9_gate_derived.json b/.run/s9_gate_derived.json new file mode 100644 index 000000000..422770ade --- /dev/null +++ b/.run/s9_gate_derived.json @@ -0,0 +1,31 @@ +{ + "banked": [ + "func_8017E3E0", + "func_80182058", + "func_801839C4", + "func_8018E780", + "func_8017C290", + "func_8017DF84", + "func_80183E04", + "func_8017E170", + "func_80186B78", + "func_8017EC90", + "func_8018C518", + "func_80181CDC", + "func_80180CA8", + "func_8018165C", + "func_801823F0", + "func_80182A48", + "func_801886B0", + "func_801894F0", + "func_8018AF88", + "func_8018BC40", + "func_801812F8", + "func_8017D5EC" + ], + "failed": [ + "func_8017D174", + "func_8017E2EC", + "func_80186E24" + ] +} \ No newline at end of file diff --git a/docs/family-hseq.md b/docs/family-hseq.md index 20f40210a..213f043f9 100644 --- a/docs/family-hseq.md +++ b/docs/family-hseq.md @@ -2,13 +2,13 @@ > Generated by `tools/family_hseq.py` from the 138 overlay sigs + per-overlay src stubs. Ranked by TEMPLATABLE byte-weight (PURE+IMM members × nins × 4). The byte-gate is the arbiter. > -> **Scope: the 138 OVERLAYS only** (no main, no resident) · generated at HEAD `commit:1371` · stub set derived from `corpus.stubs` — the same oracle `progress.py` counts, so same-tree overlay totals agree by construction; compare digests only at the same HEAD. +> **Scope: the 138 OVERLAYS only** (no main, no resident) · generated at HEAD `commit:1373` · stub set derived from `corpus.stubs` — the same oracle `progress.py` counts, so same-tree overlay totals agree by construction; compare digests only at the same HEAD. -**Fleet (overlays):** 96.2% fn / 93.7% instr / 88.2% distinct-code matched. Unmatched: 13,297 instances / 826,188 ins (10,115 distinct classes). +**Fleet (overlays):** 96.2% fn / 93.8% instr / 88.5% distinct-code matched. Unmatched: 13,194 instances / 804,481 ins (10,019 distinct classes). -**Tail cross-check (Phase-25 close):** 8,079 tail fns / 403,668 ins → 442 h_seq families ≥2, **119 substantial (nins≥80) / 99,244 ins**. +**Tail cross-check (Phase-25 close):** 8,072 tail fns / 403,081 ins → 442 h_seq families ≥2, **119 substantial (nins≥80) / 98,674 ins**. -**Full frontier (all unmatched by h_seq):** 2103 target families (≥2 members or a matched sibling) + 3767 singletons (Step-D residue). Substantial: **420 families / 343,317 templatable ins**, 30 with a matched sibling (zero-crack). Substantial member classes: 1,918 PURE · 31 IMM · 6 STRUCT-excluded. +**Full frontier (all unmatched by h_seq):** 2098 target families (≥2 members or a matched sibling) + 3767 singletons (Step-D residue). Substantial: **415 families / 322,113 templatable ins**, 36 with a matched sibling (zero-crack). Substantial member classes: 1,826 PURE · 31 IMM · 6 STRUCT-excluded. ## Top substantial families (by templatable byte-weight) @@ -19,49 +19,49 @@ | 2 | 165 | 138 (138/0/0) | 1/138 | per-location | PURE | 0 | · | 0x80178004 draft-ov077 | 22,770 | | 3 | 947 | 16 (16/0/0) | 6/16 | cross-address | PURE | 0 | Y | 0x8017c974 draft-ov077 | 15,152 | | 4 | 299 | 20 (20/0/0) | 20/20 | scattered | PURE | 0 | Y | 0x8017fee0 modal | 5,980 | -| 5 | 227 | 25 (25/0/0) | 10/25 | scattered | PURE | 1 | · | 0x8017bfec matched | 5,675 | -| 6 | 793 | 5 (5/0/0) | 2/5 | cross-address | PURE | 0 | · | 0x8017d174 modal | 3,965 | -| 7 | 246 | 16 (16/0/0) | 6/16 | cross-address | PURE | 0 | · | 0x8017c294 draft-ov077 | 3,936 | -| 8 | 766 | 5 (5/0/0) | 3/5 | cross-address | PURE | 0 | · | 0x8017df84 modal | 3,830 | -| 9 | 491 | 7 (7/0/0) | 6/7 | cross-address | PURE | 0 | Y | 0x801863cc modal | 3,437 | -| 10 | 237 | 14 (14/0/0) | 14/14 | scattered | PURE | 1 | · | 0x801832a8 matched | 3,318 | -| 11 | 328 | 10 (10/0/0) | 10/10 | scattered | PURE | 1 | · | 0x801833f0 matched | 3,280 | -| 12 | 770 | 4 (4/0/0) | 1/4 | per-location | PURE | 134 | · | 0x80144b9c matched-ov077 | 3,080 | -| 13 | 611 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | · | 0x80186e24 modal | 3,055 | -| 14 | 293 | 10 (10/0/0) | 4/10 | cross-address | PURE | 1 | · | 0x8017c43c matched | 2,930 | -| 15 | 557 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | Y | 0x80186570 modal | 2,785 | -| 16 | 551 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | Y | 0x80189540 modal | 2,755 | -| 17 | 125 | 22 (22/0/0) | 22/22 | scattered | PURE | 0 | Y | 0x80185440 modal | 2,750 | -| 18 | 386 | 7 (7/0/0) | 6/7 | cross-address | PURE | 0 | · | 0x80186b78 modal | 2,702 | -| 19 | 263 | 10 (10/0/0) | 10/10 | scattered | PURE | 1 | · | 0x80182fd4 matched | 2,630 | -| 20 | 185 | 14 (14/0/0) | 13/14 | scattered | PURE | 1 | · | 0x8018b23c matched | 2,590 | -| 21 | 513 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | Y | 0x801878e8 modal | 2,565 | -| 22 | 177 | 14 (14/0/0) | 13/14 | scattered | PURE | 1 | · | 0x8018aa98 matched | 2,478 | -| 23 | 305 | 7 (7/0/0) | 7/7 | cross-address | PURE | 0 | · | 0x8018165c modal | 2,135 | -| 24 | 296 | 7 (7/0/0) | 7/7 | cross-address | PURE | 0 | · | 0x8017e2ec modal | 2,072 | -| 25 | 137 | 15 (15/0/0) | 15/15 | scattered | PURE | 0 | Y | 0x80183084 modal | 2,055 | -| 26 | 274 | 7 (7/0/0) | 7/7 | cross-address | PURE | 0 | · | 0x801823f0 modal | 1,918 | -| 27 | 273 | 7 (7/0/0) | 7/7 | cross-address | PURE | 0 | · | 0x80182a48 modal | 1,911 | -| 28 | 265 | 7 (1/6/0) | 7/7 | cross-address | IMM | 0 | · | 0x80183e04 modal | 1,855 | -| 29 | 203 | 9 (4/5/0) | 8/9 | cross-address | IMM | 1 | · | 0x8017efa8 matched | 1,827 | -| 30 | 257 | 7 (7/0/0) | 7/7 | cross-address | PURE | 0 | · | 0x80180ca8 modal | 1,799 | -| 31 | 438 | 4 (4/0/0) | 1/4 | per-location | PURE | 134 | Y | 0x801380e0 matched-ov077 | 1,752 | -| 32 | 579 | 3 (3/0/0) | 2/3 | cross-address | PURE | 0 | Y | 0x8018103c draft-ov077 | 1,737 | -| 33 | 133 | 13 (13/0/0) | 10/13 | scattered | PURE | 1 | · | 0x8017d0bc matched | 1,729 | -| 34 | 288 | 6 (6/0/0) | 6/6 | cross-address | PURE | 0 | Y | 0x80184c74 modal | 1,728 | -| 35 | 281 | 6 (6/0/0) | 6/6 | cross-address | PURE | 0 | Y | 0x80186270 modal | 1,686 | -| 36 | 281 | 6 (6/0/0) | 6/6 | cross-address | PURE | 0 | · | 0x801894f0 modal | 1,686 | -| 37 | 240 | 7 (7/0/0) | 6/7 | cross-address | PURE | 0 | Y | 0x801872b4 modal | 1,680 | -| 38 | 276 | 6 (6/0/0) | 6/6 | cross-address | PURE | 0 | · | 0x801886b0 modal | 1,656 | -| 39 | 229 | 7 (7/0/0) | 2/7 | cross-address | PURE | 0 | · | 0x8017c290 modal | 1,603 | -| 40 | 143 | 11 (11/0/0) | 10/11 | scattered | PURE | 1 | · | 0x8017d77c matched | 1,573 | -| 41 | 251 | 6 (6/0/0) | 6/6 | cross-address | PURE | 0 | Y | 0x80186994 modal | 1,506 | -| 42 | 250 | 6 (6/0/0) | 5/6 | cross-address | PURE | 0 | · | 0x8018a2e0 modal | 1,500 | -| 43 | 210 | 7 (7/0/0) | 2/7 | cross-address | PURE | 0 | · | 0x8017c8fc modal | 1,470 | -| 44 | 207 | 7 (7/0/0) | 7/7 | cross-address | PURE | 0 | · | 0x8017f2e8 modal | 1,449 | -| 45 | 710 | 2 (2/0/0) | 2/2 | cross-address | PURE | 1 | Y | 0x80191c50 matched | 1,420 | -| 46 | 470 | 3 (3/0/0) | 3/3 | cross-address | PURE | 0 | Y | 0x80191320 modal | 1,410 | -| 47 | 279 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | Y | 0x8017f2d4 modal | 1,395 | -| 48 | 198 | 7 (7/0/0) | 7/7 | cross-address | PURE | 0 | · | 0x80181ee0 modal | 1,386 | -| 49 | 693 | 2 (2/0/0) | 1/2 | per-location | PURE | 0 | · | 0x8017cdf0 modal | 1,386 | -| 50 | 230 | 6 (6/0/0) | 6/6 | cross-address | PURE | 0 | · | 0x80181688 modal | 1,380 | +| 5 | 793 | 5 (5/0/0) | 2/5 | cross-address | PURE | 0 | · | 0x8017d174 modal | 3,965 | +| 6 | 246 | 16 (16/0/0) | 6/16 | cross-address | PURE | 0 | · | 0x8017c294 draft-ov077 | 3,936 | +| 7 | 491 | 7 (7/0/0) | 6/7 | cross-address | PURE | 0 | Y | 0x801863cc modal | 3,437 | +| 8 | 328 | 10 (10/0/0) | 10/10 | scattered | PURE | 1 | · | 0x801833f0 matched | 3,280 | +| 9 | 770 | 4 (4/0/0) | 1/4 | per-location | PURE | 134 | · | 0x80144b9c matched-ov077 | 3,080 | +| 10 | 766 | 4 (4/0/0) | 3/4 | cross-address | PURE | 1 | · | 0x8017df84 matched | 3,064 | +| 11 | 611 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | · | 0x80186e24 modal | 3,055 | +| 12 | 557 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | Y | 0x80186570 modal | 2,785 | +| 13 | 551 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | Y | 0x80189540 modal | 2,755 | +| 14 | 125 | 22 (22/0/0) | 22/22 | scattered | PURE | 0 | Y | 0x80185440 modal | 2,750 | +| 15 | 263 | 10 (10/0/0) | 10/10 | scattered | PURE | 1 | · | 0x80182fd4 matched | 2,630 | +| 16 | 513 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | Y | 0x801878e8 modal | 2,565 | +| 17 | 386 | 6 (6/0/0) | 6/6 | cross-address | PURE | 1 | · | 0x80186b78 matched | 2,316 | +| 18 | 296 | 7 (7/0/0) | 7/7 | cross-address | PURE | 0 | · | 0x8017e2ec modal | 2,072 | +| 19 | 137 | 15 (15/0/0) | 15/15 | scattered | PURE | 0 | Y | 0x80183084 modal | 2,055 | +| 20 | 305 | 6 (6/0/0) | 6/6 | cross-address | PURE | 1 | · | 0x8018165c matched | 1,830 | +| 21 | 438 | 4 (4/0/0) | 1/4 | per-location | PURE | 134 | Y | 0x801380e0 matched-ov077 | 1,752 | +| 22 | 579 | 3 (3/0/0) | 2/3 | cross-address | PURE | 0 | Y | 0x8018103c draft-ov077 | 1,737 | +| 23 | 133 | 13 (13/0/0) | 10/13 | scattered | PURE | 1 | · | 0x8017d0bc matched | 1,729 | +| 24 | 288 | 6 (6/0/0) | 6/6 | cross-address | PURE | 0 | Y | 0x80184c74 modal | 1,728 | +| 25 | 281 | 6 (6/0/0) | 6/6 | cross-address | PURE | 0 | Y | 0x80186270 modal | 1,686 | +| 26 | 240 | 7 (7/0/0) | 6/7 | cross-address | PURE | 0 | Y | 0x801872b4 modal | 1,680 | +| 27 | 274 | 6 (6/0/0) | 6/6 | cross-address | PURE | 1 | · | 0x801823f0 matched | 1,644 | +| 28 | 273 | 6 (6/0/0) | 6/6 | cross-address | PURE | 1 | · | 0x80182a48 matched | 1,638 | +| 29 | 265 | 6 (0/6/0) | 6/6 | cross-address | IMM | 1 | · | 0x80183e04 matched | 1,590 | +| 30 | 143 | 11 (11/0/0) | 10/11 | scattered | PURE | 1 | · | 0x8017d77c matched | 1,573 | +| 31 | 257 | 6 (6/0/0) | 6/6 | cross-address | PURE | 1 | · | 0x80180ca8 matched | 1,542 | +| 32 | 251 | 6 (6/0/0) | 6/6 | cross-address | PURE | 0 | Y | 0x80186994 modal | 1,506 | +| 33 | 250 | 6 (6/0/0) | 5/6 | cross-address | PURE | 0 | · | 0x8018a2e0 modal | 1,500 | +| 34 | 210 | 7 (7/0/0) | 2/7 | cross-address | PURE | 0 | · | 0x8017c8fc modal | 1,470 | +| 35 | 207 | 7 (7/0/0) | 7/7 | cross-address | PURE | 0 | · | 0x8017f2e8 modal | 1,449 | +| 36 | 710 | 2 (2/0/0) | 2/2 | cross-address | PURE | 1 | Y | 0x80191c50 matched | 1,420 | +| 37 | 470 | 3 (3/0/0) | 3/3 | cross-address | PURE | 0 | Y | 0x80191320 modal | 1,410 | +| 38 | 281 | 5 (5/0/0) | 5/5 | cross-address | PURE | 1 | · | 0x801894f0 matched | 1,405 | +| 39 | 279 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | Y | 0x8017f2d4 modal | 1,395 | +| 40 | 198 | 7 (7/0/0) | 7/7 | cross-address | PURE | 0 | · | 0x80181ee0 modal | 1,386 | +| 41 | 693 | 2 (2/0/0) | 1/2 | per-location | PURE | 0 | · | 0x8017cdf0 modal | 1,386 | +| 42 | 230 | 6 (6/0/0) | 6/6 | cross-address | PURE | 0 | · | 0x80181688 modal | 1,380 | +| 43 | 276 | 5 (5/0/0) | 5/5 | cross-address | PURE | 1 | · | 0x801886b0 matched | 1,380 | +| 44 | 229 | 6 (6/0/0) | 2/6 | cross-address | PURE | 1 | · | 0x8017c290 matched | 1,374 | +| 45 | 673 | 2 (2/0/0) | 2/2 | cross-address | PURE | 1 | Y | 0x8019059c matched | 1,346 | +| 46 | 221 | 6 (6/0/0) | 6/6 | cross-address | PURE | 0 | · | 0x8017e9f4 modal | 1,326 | +| 47 | 184 | 7 (7/0/0) | 2/7 | cross-address | PURE | 0 | · | 0x8017d318 modal | 1,288 | +| 48 | 254 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | Y | 0x80188e1c modal | 1,270 | +| 49 | 150 | 8 (8/0/0) | 8/8 | cross-address | PURE | 0 | · | 0x801829bc modal | 1,200 | +| 50 | 397 | 3 (3/0/0) | 3/3 | cross-address | PURE | 0 | · | 0x8018f060 modal | 1,191 | diff --git a/src/ov_SC01_074/ov_SC01_074_jr_8017BE9C.c b/src/ov_SC01_074/ov_SC01_074_jr_8017BE9C.c index 7dc4ac6fd..e6dd907e6 100644 --- a/src/ov_SC01_074/ov_SC01_074_jr_8017BE9C.c +++ b/src/ov_SC01_074/ov_SC01_074_jr_8017BE9C.c @@ -3490,7 +3490,34 @@ INCLUDE_ASM("asm/ov_SC01_074/nonmatchings/ov_SC01_074_jr_8017BE9C", func_8017E07 INCLUDE_ASM("asm/ov_SC01_074/nonmatchings/ov_SC01_074_jr_8017BE9C", func_8017E158); -INCLUDE_ASM("asm/ov_SC01_074/nonmatchings/ov_SC01_074_jr_8017BE9C", func_8017E3E0); + + + + +void func_8017E3E0(void *a0, void *a1, void *a2, void *a3) +{ + extern void func_80016ED4(void *a0); + extern s32 D_80182244; + extern s32 D_80182248; + extern s32 D_8018224C; + extern s32 D_80182250; + + Prim_8016E7C8 prim; + + prim.v[0] = *(SVECTOR_8016E7C8 *)a0; + prim.v[1] = *(SVECTOR_8016E7C8 *)a1; + prim.v[2] = *(SVECTOR_8016E7C8 *)a2; + prim.v[3] = *(SVECTOR_8016E7C8 *)a3; + prim.f0 = D_80182244; + prim.f1 = D_80182248; + prim.f2 = D_8018224C; + prim.f3 = D_80182250; + prim.f4 = 0x808080; + prim.f5 = 0; + prim.f6 = 0x50; + func_80016ED4(&prim); +} + extern void (*D_80182254[])(void); diff --git a/src/ov_SC02_000/ov_SC02_000_jr_8017FCB0.c b/src/ov_SC02_000/ov_SC02_000_jr_8017FCB0.c index 8e396616f..f61a4288f 100644 --- a/src/ov_SC02_000/ov_SC02_000_jr_8017FCB0.c +++ b/src/ov_SC02_000/ov_SC02_000_jr_8017FCB0.c @@ -3141,7 +3141,39 @@ INCLUDE_ASM("asm/ov_SC02_000/nonmatchings/ov_SC02_000_jr_8017FCB0", func_80181DE INCLUDE_ASM("asm/ov_SC02_000/nonmatchings/ov_SC02_000_jr_8017FCB0", func_80181E70); -INCLUDE_ASM("asm/ov_SC02_000/nonmatchings/ov_SC02_000_jr_8017FCB0", func_80182058); +#include "common.h" + +extern s32 func_80013200(s32 *a0, s32 *a1); +extern s32 ratan2(s32 a0, s32 a1); +extern s16 D_800B9AB8[]; +extern s16 D_800B9ABA[]; + +void func_80182058(s32 param_1) { + s32 v1[3]; + s32 v2[3]; + s32 dist; + s32 angle; + s32 v0; + + v1[0] = *(s32 *)(param_1 + 0x48); + v1[1] = 0; + v1[2] = *(s32 *)(param_1 + 0x50); + v2[0] = *(s32 *)(param_1 + 0x3C); + v2[1] = 0; + v2[2] = *(s32 *)(param_1 + 0x44); + dist = func_80013200(v1, v2); + angle = ratan2(*(s32 *)(param_1 + 0x4C) - *(s32 *)(param_1 + 0x40), dist); + if (angle >= 0x801) { + angle = 0x1000 - angle; + } + v0 = angle * 360 / 1024 + 0xA0; + D_800B9ABA[0] = (s16)v0; + + angle = ratan2(v1[0] - v2[0], v1[2] - v2[2]); + v0 = angle * 640 / 4096 + 0x50; + D_800B9AB8[0] = (s16)v0; +} + extern void (*D_8018EAC4[])(void); @@ -3365,7 +3397,30 @@ INCLUDE_ASM("asm/ov_SC02_000/nonmatchings/ov_SC02_000_jr_8017FCB0", func_8018375 INCLUDE_ASM("asm/ov_SC02_000/nonmatchings/ov_SC02_000_jr_8017FCB0", func_80183814); -INCLUDE_ASM("asm/ov_SC02_000/nonmatchings/ov_SC02_000_jr_8017FCB0", func_801839C4); +void func_801839C4(void *a0) { + s32 bVar1; + + *(u32 *)((s32)a0 + 0x1F8) = *(u32 *)((s32)a0 + 0x1F8) & 0xFEFFFFFF; + *(u16 *)((s32)a0 + 0xAA) = *(u16 *)((s32)a0 + 0xAA) & 0xFF40; + bVar1 = *(u8 *)((s32)a0 + 0xA9); + *(u16 *)((s32)a0 + 0xAC) = *(u16 *)((s32)a0 + 0xAC) & 0xFF40; + + __asm__ __volatile__("" ::: "memory"); + + switch (bVar1) { + case 0x41: + *(u16 *)((s32)a0 + 0xAA) = *(u16 *)((s32)a0 + 0xAA) & 0xAFFF; + *(u16 *)((s32)a0 + 0xAC) = *(u16 *)((s32)a0 + 0xAC) & 0xAFFF; + *(u16 *)((s32)a0 + 0xAA) = *(u16 *)((s32)a0 + 0xAA) | 0x4000; + *(u16 *)((s32)a0 + 0xAC) = *(u16 *)((s32)a0 + 0xAC) | 0x4000; + break; + case 0x53: + case 0x73: + *(u16 *)((s32)a0 + 0xAE) = *(u8 *)((s32)a0 + 0xAE) | 0xFF00; + break; + } +} + DEFINE_func_80183A78() /* dedup: shared engine-core @0x80183A78 (src/shared) */ diff --git a/src/ov_SC02_003/ov_SC02_003_jr_8017FCB0.c b/src/ov_SC02_003/ov_SC02_003_jr_8017FCB0.c index 290cc1981..90c807324 100644 --- a/src/ov_SC02_003/ov_SC02_003_jr_8017FCB0.c +++ b/src/ov_SC02_003/ov_SC02_003_jr_8017FCB0.c @@ -3136,7 +3136,39 @@ INCLUDE_ASM("asm/ov_SC02_003/nonmatchings/ov_SC02_003_jr_8017FCB0", func_80181DE INCLUDE_ASM("asm/ov_SC02_003/nonmatchings/ov_SC02_003_jr_8017FCB0", func_80181E70); -INCLUDE_ASM("asm/ov_SC02_003/nonmatchings/ov_SC02_003_jr_8017FCB0", func_80182058); + +extern s32 func_80013200(s32 *a0, s32 *a1); +extern s32 ratan2(s32 a0, s32 a1); + +void func_80182058(s32 param_1) { + + extern s16 D_800B9AB8[]; + extern s16 D_800B9ABA[]; + s32 v1[3]; + s32 v2[3]; + s32 dist; + s32 angle; + s32 v0; + + v1[0] = *(s32 *)(param_1 + 0x48); + v1[1] = 0; + v1[2] = *(s32 *)(param_1 + 0x50); + v2[0] = *(s32 *)(param_1 + 0x3C); + v2[1] = 0; + v2[2] = *(s32 *)(param_1 + 0x44); + dist = func_80013200(v1, v2); + angle = ratan2(*(s32 *)(param_1 + 0x4C) - *(s32 *)(param_1 + 0x40), dist); + if (angle >= 0x801) { + angle = 0x1000 - angle; + } + v0 = angle * 360 / 1024 + 0xA0; + D_800B9ABA[0] = (s16)v0; + + angle = ratan2(v1[0] - v2[0], v1[2] - v2[2]); + v0 = angle * 640 / 4096 + 0x50; + D_800B9AB8[0] = (s16)v0; +} + extern void (*D_8018EAC4[])(void); @@ -3354,7 +3386,31 @@ INCLUDE_ASM("asm/ov_SC02_003/nonmatchings/ov_SC02_003_jr_8017FCB0", func_8018375 INCLUDE_ASM("asm/ov_SC02_003/nonmatchings/ov_SC02_003_jr_8017FCB0", func_80183814); -INCLUDE_ASM("asm/ov_SC02_003/nonmatchings/ov_SC02_003_jr_8017FCB0", func_801839C4); + +void func_801839C4(void *a0) { + s32 bVar1; + + *(u32 *)((s32)a0 + 0x1F8) = *(u32 *)((s32)a0 + 0x1F8) & 0xFEFFFFFF; + *(u16 *)((s32)a0 + 0xAA) = *(u16 *)((s32)a0 + 0xAA) & 0xFF40; + bVar1 = *(u8 *)((s32)a0 + 0xA9); + *(u16 *)((s32)a0 + 0xAC) = *(u16 *)((s32)a0 + 0xAC) & 0xFF40; + + __asm__ __volatile__("" ::: "memory"); + + switch (bVar1) { + case 0x41: + *(u16 *)((s32)a0 + 0xAA) = *(u16 *)((s32)a0 + 0xAA) & 0xAFFF; + *(u16 *)((s32)a0 + 0xAC) = *(u16 *)((s32)a0 + 0xAC) & 0xAFFF; + *(u16 *)((s32)a0 + 0xAA) = *(u16 *)((s32)a0 + 0xAA) | 0x4000; + *(u16 *)((s32)a0 + 0xAC) = *(u16 *)((s32)a0 + 0xAC) | 0x4000; + break; + case 0x53: + case 0x73: + *(u16 *)((s32)a0 + 0xAE) = *(u8 *)((s32)a0 + 0xAE) | 0xFF00; + break; + } +} + DEFINE_func_80183A78() /* dedup: shared engine-core @0x80183A78 (src/shared) */ diff --git a/src/ov_SC02_011/ov_SC02_011_jr_8017AE2C.c b/src/ov_SC02_011/ov_SC02_011_jr_8017AE2C.c index 6e6c96efb..28d86e574 100644 --- a/src/ov_SC02_011/ov_SC02_011_jr_8017AE2C.c +++ b/src/ov_SC02_011/ov_SC02_011_jr_8017AE2C.c @@ -8655,7 +8655,47 @@ INCLUDE_ASM("asm/ov_SC02_011/nonmatchings/ov_SC02_011_jr_8017AE2C", func_8018E5E INCLUDE_ASM("asm/ov_SC02_011/nonmatchings/ov_SC02_011_jr_8017AE2C", func_8018E678); -INCLUDE_ASM("asm/ov_SC02_011/nonmatchings/ov_SC02_011_jr_8017AE2C", func_8018E780); +extern s32 func_8012BEE8(s32 a0); +extern void func_8012C218(void *a0); +extern s32 func_8004787C(s32 a0); +extern s32 func_80047948(s32 a0); + +void func_8018E780(s32 param_1) +{ + s32 iVar3; + s32 uVar1; + s32 sVar2; + + if (*(u16 *)(param_1 + 0x34) == 0) { + if ((*(u16 *)(param_1 + 0x70) & 0xF) == 2) { + *(s16 *)(*(s32 *)(param_1 + 0x20) + 0x10) = + *(s16 *)(*(s32 *)(param_1 + 0x20) + 0x10) + -0x80; + if (*(s16 *)(*(s32 *)(param_1 + 0x20) + 0x10) < -0x400) { + *(s16 *)(*(s32 *)(param_1 + 0x20) + 0x10) = -0x400; + } + } + iVar3 = func_8012BEE8(param_1); + if (iVar3 != 0) { + *(s32 *)(param_1 + 0x1C) = 8; + *(u16 *)(param_1 + 0x34) = *(u16 *)(param_1 + 0x34) + 1; + *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x2C) = + *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x2C) | 0x10; + } + } else { + iVar3 = func_8012BEE8(param_1); + if (iVar3 != 0) { + ((void (*)(s32))func_8012C218)(param_1); + } else { + uVar1 = func_8004787C((*(s32 *)(param_1 + 0x1C) << 10) >> 3); + iVar3 = *(s32 *)(param_1 + 0x20); + *(s16 *)(iVar3 + 0x1C) = uVar1; + *(s16 *)(iVar3 + 0x18) = uVar1; + sVar2 = func_80047948((*(s32 *)(param_1 + 0x1C) << 10) >> 3); + *(s16 *)(*(s32 *)(param_1 + 0x20) + 0x1A) = sVar2 * 8 + 0x1000; + } + } +} + INCLUDE_ASM("asm/ov_SC02_011/nonmatchings/ov_SC02_011_jr_8017AE2C", func_8018E8A0); diff --git a/src/ov_SC03_001/ov_SC03_001_jr_8017AE2C.c b/src/ov_SC03_001/ov_SC03_001_jr_8017AE2C.c index c1eabfbc5..ed0527349 100644 --- a/src/ov_SC03_001/ov_SC03_001_jr_8017AE2C.c +++ b/src/ov_SC03_001/ov_SC03_001_jr_8017AE2C.c @@ -4729,7 +4729,56 @@ INCLUDE_ASM("asm/ov_SC03_001/nonmatchings/ov_SC03_001_jr_8017AE2C", func_8017EF3 INCLUDE_ASM("asm/ov_SC03_001/nonmatchings/ov_SC03_001_jr_8017AE2C", func_8017EFD4); -INCLUDE_ASM("asm/ov_SC03_001/nonmatchings/ov_SC03_001_jr_8017AE2C", func_8017F058); + +extern s32 func_80029504(void); +extern s32 func_801877C0(s32); +extern s32 func_80187904(void); +extern s32 func_8018766C(s32 arg0, s32 arg1); +extern void func_80187778(s32*, s32); + +void func_8017F058(void *a0) { + + extern short D_801913D4; + void *s0 = a0; + s32 v1 = func_80029504(); + s32 v0; + + if (v1 < 0xC8) { + v0 = ((s32 (*)(void))func_801877C0)(); + v1 = 3; + if (v0 == v1) { + return; + } + v0 = func_8018766C(0xA, 0x10); + if (v0 == 0) { + return; + } + v0 = 1; + } else if (v1 < 0x258) { + v0 = 1; + } else if (v1 < 0x384) { + v0 = func_8018766C(0xA, 0x10); + if (v0 == 0) { + return; + } + v0 = 1; + } else { + v0 = func_80187904(); + v1 = 1; + if (v0 == v1) { + return; + } + v0 = func_8018766C(0xA, 0x10); + if (v0 == 0) { + return; + } + v0 = 1; + } + + *(s16 *)((char *)s0 + 0x2) = 0x1; + ((void (*)(s32, s32))func_80187778)((s32)s0, (s32)&D_801913D4); +} + extern int func_80178970(void); diff --git a/src/ov_SC03_002/ov_SC03_002_jr_8017D604.c b/src/ov_SC03_002/ov_SC03_002_jr_8017D604.c index 2c0544180..5a797371e 100644 --- a/src/ov_SC03_002/ov_SC03_002_jr_8017D604.c +++ b/src/ov_SC03_002/ov_SC03_002_jr_8017D604.c @@ -3211,7 +3211,35 @@ INCLUDE_ASM("asm/ov_SC03_002/nonmatchings/ov_SC03_002_jr_8017D604", func_8017EBD INCLUDE_ASM("asm/ov_SC03_002/nonmatchings/ov_SC03_002_jr_8017D604", func_8017EC98); -INCLUDE_ASM("asm/ov_SC03_002/nonmatchings/ov_SC03_002_jr_8017D604", func_8017EF80); + + + + + +void func_8017EF80(void *a0, void *a1, void *a2, void *a3) +{ + extern void func_80016ED4(void *a0); + extern s32 D_8018931C; + extern s32 D_80189320; + extern s32 D_80189324; + extern s32 D_80189328; + + Prim_8016E7C8 prim; + + prim.v[0] = *(SVECTOR_8016E7C8 *)a0; + prim.v[1] = *(SVECTOR_8016E7C8 *)a1; + prim.v[2] = *(SVECTOR_8016E7C8 *)a2; + prim.v[3] = *(SVECTOR_8016E7C8 *)a3; + prim.f0 = D_8018931C; + prim.f1 = D_80189320; + prim.f2 = D_80189324; + prim.f3 = D_80189328; + prim.f4 = 0x808080; + prim.f5 = 0; + prim.f6 = 0x50; + func_80016ED4(&prim); +} + INCLUDE_ASM("asm/ov_SC03_002/nonmatchings/ov_SC03_002_jr_8017D604", func_8017F068); diff --git a/src/ov_SC03_006/ov_SC03_006_jr_8017AE2C.c b/src/ov_SC03_006/ov_SC03_006_jr_8017AE2C.c index b9d9405a2..24e79ec1c 100644 --- a/src/ov_SC03_006/ov_SC03_006_jr_8017AE2C.c +++ b/src/ov_SC03_006/ov_SC03_006_jr_8017AE2C.c @@ -7144,7 +7144,48 @@ INCLUDE_ASM("asm/ov_SC03_006/nonmatchings/ov_SC03_006_jr_8017AE2C", func_8018671 INCLUDE_ASM("asm/ov_SC03_006/nonmatchings/ov_SC03_006_jr_8017AE2C", func_801867A4); -INCLUDE_ASM("asm/ov_SC03_006/nonmatchings/ov_SC03_006_jr_8017AE2C", func_801868AC); + +extern s32 func_8012BEE8(s32 a0); +extern void func_8012C218(void *a0); +extern s32 func_8004787C(s32 a0); +extern s32 func_80047948(s32 a0); + +void func_801868AC(s32 param_1) +{ + s32 iVar3; + s32 uVar1; + s32 sVar2; + + if (*(u16 *)(param_1 + 0x34) == 0) { + if ((*(u16 *)(param_1 + 0x70) & 0xF) == 2) { + *(s16 *)(*(s32 *)(param_1 + 0x20) + 0x10) = + *(s16 *)(*(s32 *)(param_1 + 0x20) + 0x10) + -0x80; + if (*(s16 *)(*(s32 *)(param_1 + 0x20) + 0x10) < -0x400) { + *(s16 *)(*(s32 *)(param_1 + 0x20) + 0x10) = -0x400; + } + } + iVar3 = func_8012BEE8(param_1); + if (iVar3 != 0) { + *(s32 *)(param_1 + 0x1C) = 8; + *(u16 *)(param_1 + 0x34) = *(u16 *)(param_1 + 0x34) + 1; + *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x2C) = + *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x2C) | 0x10; + } + } else { + iVar3 = func_8012BEE8(param_1); + if (iVar3 != 0) { + ((void (*)(s32))func_8012C218)(param_1); + } else { + uVar1 = func_8004787C((*(s32 *)(param_1 + 0x1C) << 10) >> 3); + iVar3 = *(s32 *)(param_1 + 0x20); + *(s16 *)(iVar3 + 0x1C) = uVar1; + *(s16 *)(iVar3 + 0x18) = uVar1; + sVar2 = func_80047948((*(s32 *)(param_1 + 0x1C) << 10) >> 3); + *(s16 *)(*(s32 *)(param_1 + 0x20) + 0x1A) = sVar2 * 8 + 0x1000; + } + } +} + INCLUDE_ASM("asm/ov_SC03_006/nonmatchings/ov_SC03_006_jr_8017AE2C", func_801869CC); diff --git a/src/ov_SC03_014/ov_SC03_014_jr_8017AE2C.c b/src/ov_SC03_014/ov_SC03_014_jr_8017AE2C.c index 224e3cf60..5e5e55b99 100644 --- a/src/ov_SC03_014/ov_SC03_014_jr_8017AE2C.c +++ b/src/ov_SC03_014/ov_SC03_014_jr_8017AE2C.c @@ -3394,7 +3394,144 @@ DEFINE_func_8017C14C() /* dedup: shared engine-core @0x8017C14C (src/shared) */ INCLUDE_ASM("asm/ov_SC03_014/nonmatchings/ov_SC03_014_jr_8017AE2C", func_8017C154); -INCLUDE_ASM("asm/ov_SC03_014/nonmatchings/ov_SC03_014_jr_8017AE2C", func_8017C290); +// @class: regalloc-order +// @stuck: none — §136c SIBLING-FIRST. Near-twin = banked func_8017E830 in +// src/ov_SC06_008/ov_SC06_008_jr_8017C294.c (MATCH, 223 ins). Same GTE coord transform; +// this member drops the 8th param `h` and instead sources the two align-1 4-byte packed +// words from D_8018EF70[*(s32 *)(a + 0x2C)] INSIDE the `flags == 0` arm (source order: +// 0x50000000 word, copy, copy, six zero bytes — the list scheduler preserves the relative +// order of disambiguable constant-address stores, §sched). +// Reused verbatim from the twin: (1) `{int t = f->vy - 0x10; f->vy = t + (r & 0x1f);}` +// blocks the (r&0x1f)-16 reassoc that would materialize -0x10 via `li 0xfff0` (+1 ins); +// (2) the one-shot `r0_00 + 1` stsv arg is inlined so it stays a $v0 temp instead of +// stealing a saved reg from the reused pSVar6. + +/* MATRIX 0x20: 3x3 short rotation + pad, t[] at 0x14 */ +typedef struct { s16 m[3][3]; s16 pad; s32 t[3]; } MATRIX_8017C290; +/* 8, align 2 -> lwl/lwr/swl/swr struct copy */ +typedef struct { u16 vx, vy, vz, pad; } SVECTOR_8017C290; +/* 4, align 1 -> lwl/lwr/swl/swr */ +struct PW8017C290 { int w; } __attribute__((packed, aligned(1))); + +extern void func_80013F3C(s32 a0); +extern void RotMatrixZ(s32, void *); +extern void func_8004914C(void *a0); +extern void func_800491AC(void *a0); +extern int rand(void); +extern void func_80017714(void *); + +extern SVECTOR_8017C290 D_801EA8C0[4]; +extern struct PW8017C290 D_801EA8E0; +extern struct PW8017C290 D_801EA8E4; +extern u8 D_801EA8E8, D_801EA8E9, D_801EA8EA, D_801EA8EC, D_801EA8ED, D_801EA8EE; +extern int D_801EA8F0; +extern struct PW8017C290 D_8018EF70[]; + +#define gte_ldv0(r0) __asm__ __volatile__( \ + "lwc2 $0, 0(%0)\n" \ + "lwc2 $1, 4(%0)\n" \ + : : "r"(r0) : "memory") + +#define gte_rt() __asm__ __volatile__( \ + "nop\n" \ + "nop\n" \ + "mvmva 1, 0, 0, 0, 0\n" \ + : : : "memory") + +#define gte_stsv(r0) __asm__ __volatile__( \ + "mfc2 $12, $9\n" \ + "mfc2 $13, $10\n" \ + "mfc2 $14, $11\n" \ + "sh $12, 0(%0)\n" \ + "sh $13, 2(%0)\n" \ + "sh $14, 4(%0)\n" \ + : : "r"(r0) : "$12", "$13", "$14", "memory") + +void func_8017C290(int a, s16 *b, SVECTOR_8017C290 *c, SVECTOR_8017C290 *d, + SVECTOR_8017C290 *e, SVECTOR_8017C290 *f, s16 *g) +{ + MATRIX_8017C290 m; + SVECTOR_8017C290 *r0_00; + SVECTOR_8017C290 *pSVar6; + SVECTOR_8017C290 *r0; + int r; + int mask; + + func_80013F3C((s32)&m); + RotMatrixZ(g[0], &m); + m.t[0] = b[0]; + m.t[1] = b[1]; + m.t[2] = 0; + func_8004914C(&m); + func_800491AC(&m); + + r0_00 = &D_801EA8C0[0]; + if (*(s16 *)(a + 0x12) == 0) { + D_801EA8F0 = 0x50000000; + D_801EA8E0 = D_8018EF70[*(s32 *)(a + 0x2C)]; + D_801EA8E4 = D_8018EF70[*(s32 *)(a + 0x2C)]; + D_801EA8E8 = 0; + D_801EA8E9 = 0; + D_801EA8EA = 0; + D_801EA8EC = 0; + D_801EA8ED = 0; + D_801EA8EE = 0; + } + + f->vx = f->vx + c->vx; + f->vy = f->vy + c->vy; + r = rand(); + mask = f->pad & r; + if (*(u16 *)(a + 0x12) & 1) + f->vx = f->vx + mask; + else + f->vx = f->vx - mask; + r = rand(); + { int t = f->vy - 0x10; f->vy = t + (r & 0x1f); } + + gte_ldv0(c); + gte_rt(); + gte_stsv(r0_00); + + gte_ldv0(f); + gte_rt(); + gte_stsv(r0_00 + 1); + + gte_ldv0(d); + gte_rt(); + r0 = r0_00 + 2; + gte_stsv(r0); + + *d = *f; + r = rand(); + d->vx = d->vx - (f->pad & r); + + gte_ldv0(d); + gte_rt(); + pSVar6 = r0_00 + 3; + gte_stsv(pSVar6); + + r0_00->vz = ((u16 *)b)[2]; + func_80017714(r0_00); + + gte_ldv0(e); + gte_rt(); + gte_stsv(r0); + + *e = *f; + r = rand(); + e->vx = e->vx + (f->pad & r); + + gte_ldv0(e); + gte_rt(); + gte_stsv(pSVar6); + + r0_00->vz = ((u16 *)b)[2]; + func_80017714(r0_00); + + *c = *f; +} + INCLUDE_ASM("asm/ov_SC03_014/nonmatchings/ov_SC03_014_jr_8017AE2C", func_8017C624); @@ -3631,5 +3768,423 @@ INCLUDE_ASM("asm/ov_SC03_014/nonmatchings/ov_SC03_014_jr_8017AE2C", func_8017DE8 DEFINE_func_8017DF7C() /* dedup: shared engine-core @0x8017DF7C (src/shared) */ -INCLUDE_ASM("asm/ov_SC03_014/nonmatchings/ov_SC03_014_jr_8017AE2C", func_8017DF84); +// @class: none (target) +// @stuck: none — §136c SIBLING-FIRST. Near-twin = the BANKED func_8017FA5C in +// src/ov_SC03_014/ov_SC03_014_jr_8017EB7C.c (match_one MATCH, 728 ins), same TU family +// (TMD-style model renderer, same GTE macro bank, same bbox-cull skeleton, same OT tail). +// Deltas of THIS member vs that twin: +// - 4 params (obj, model, rot, zoff) instead of 3. +// - box[] vy uses `+ zoff` (as the twin used `+ xoff`), but the PER-VERTEX offset is a +// SWAY-TABLE lookup: `v[i].vy += D_8018F250[(v[i].vz + rot) & 0xFF] + zoff;` +// (u16 table -> `andi 0xFF; sll 1; addu $s6; lhu`, $s6 = the loop-hoisted table address). +// - rgbc gets `| 0x2000000` (GPU semi-transparency bit) in BOTH prim classes. +// - frame 0x1E0 (twin 0x1D0): exactly two extra reload spill slots (`ot` and `&g.sz0`), +// because $s6/$t9/$s0 are now taken by table/rot/zoff. +// VERIFIED: match_one MATCH 766/766 AND rtu_match (real TU, ov_SC03_014_jr_8017AE2C) MATCH. +// +// The four load-bearing levers, in the order they paid (767ins/697 -> 766/6 -> 0): +// L1 DECLARATION ORDER (§136-L5): reload's alter_reg walks pseudos ASCENDING, i.e. DECL order, +// so the spill slots 0x100=lim, 0x108=ot, 0x110=nparts, 0x118=part require `ot` DECLARED +// between `lim` and `nparts` (the twin declares it after `pkt`). Sets the 0x1E0 frame. +// L2 `rot = arg2;` BEFORE `zoff = arg3;` (both AFTER the 3 calls — the twin's L4 live-range +// split). The order decides which param gets the LOWER callee-saved reg: this way +// arg2->$s2 / arg3->$s3; swapped, they swap ($s3/$s2) and the prologue breaks. +// L3 *** THE MASK CONSTANT. 0xFFFFFF written as a bare literal in the OT tail is a loop +// invariant that loop.c hoists ALL THE WAY to the OUTER preheader, where it takes $s3 — +// which cascades into vtx->$t8, i->$s1, an unfilled load-delay nop, and 767 ins. The +// target keeps it in the INNER preheader ($s1). Fix: bind it to an explicit `u32 m24` +// and assign `m24 = 0xFFFFFF;` as the FIRST STATEMENT OF THE INNER LOOP BODY (ahead of +// `vp = &vdv;`). Placement is exact and all three positions are distinguishable: +// before the `for` -> emitted ahead of the loop GUARD (`beqz $s5`) = 6 mismatches +// after `vp=&vdv;` -> emitted after &vdv in the preheader = 4 mismatches +// FIRST in the body -> loop.c hoists it to the head of the INNER preheader = MATCH +// (Generalization of the twin's L5: a source local's DEF POSITION picks the hoist level.) +// L4 KEEP the §47 zero-byte `__asm__ volatile("")` between gte_ldv3c(&box[4]) and gte_rtpt() — +// same tie as the twin. Removing it flips $s7/$fp for &g.sz0/&g.sz1 (47 seq-diff lines). + +/* ---- ambient engine_types.h types. Guarded so this file compiles BOTH standalone + * (match_one isolation) and spliced into the real TU, which already provides them + * via ../shared/engine_core.h -> engine_types.h (cookbook §41 step 1). */ +#ifndef BFM_ENGINE_TYPES_H + + + + + + +#endif /* BFM_ENGINE_TYPES_H */ + +/* ---- GTE macro bank — verbatim from the matched sibling func_8017FA5C ---- */ +#define gte_ldv0(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 )" \ + : \ + : "r"( r0 ) ) + +#define gte_ldv3c(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 );" \ + "lwc2 $2, 8( %0 );" \ + "lwc2 $3, 12( %0 );" \ + "lwc2 $4, 16( %0 );" \ + "lwc2 $5, 20( %0 )" \ + : \ + : "r"( r0 ) ) + +#define gte_rtps() __asm__ volatile ("nop;nop;rtps") +#define gte_rtpt() __asm__ volatile ("nop;nop;rtpt") +#define gte_nclip() __asm__ volatile ("nop;nop;nclip") + +#define gte_stsxy(r0) __asm__ volatile ( \ + "swc2 $14, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stsxy3(r0, r1, r2) __asm__ volatile ( \ + "swc2 $12, 0( %0 );" \ + "swc2 $13, 0( %1 );" \ + "swc2 $14, 0( %2 )" \ + : \ + : "r"( r0 ), "r"( r1 ), "r"( r2 ) \ + : "memory" ) + +#define gte_stsxy3c(r0) __asm__ volatile ( \ + "swc2 $12, 0( %0 );" \ + "swc2 $13, 4( %0 );" \ + "swc2 $14, 8( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stsxy3_ft3(r0) __asm__ volatile ( \ + "swc2 $12, 8( %0 );" \ + "swc2 $13, 16( %0 );" \ + "swc2 $14, 24( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stsz3(r0, r1, r2) __asm__ volatile ( \ + "swc2 $17, 0( %0 );" \ + "swc2 $18, 0( %1 );" \ + "swc2 $19, 0( %2 )" \ + : \ + : "r"( r0 ), "r"( r1 ), "r"( r2 ) \ + : "memory" ) + +#define gte_stsz4(r0, r1, r2, r3) __asm__ volatile ( \ + "swc2 $16, 0( %0 );" \ + "swc2 $17, 0( %1 );" \ + "swc2 $18, 0( %2 );" \ + "swc2 $19, 0( %3 )" \ + : \ + : "r"( r0 ), "r"( r1 ), "r"( r2 ), "r"( r3 ) ) + +#define gte_stszotz(r0) __asm__ volatile ( \ + "mfc2 $12, $19;" \ + "nop;" \ + "sra $12, $12, 2;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) + +#define gte_stflg(r0) __asm__ volatile ( \ + "cfc2 $12, $31;" \ + "nop;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) + +#define gte_stopz(r0) __asm__ volatile ( \ + "swc2 $24, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + + +void func_8017DF84(s32 arg0, s32 arg1, s32 arg2, s32 arg3) +{ + typedef struct { u32 w0, w1, w2; } Prim; + /* vy UNSIGNED: the `+=` reads it with lhu, not lh. */ + typedef struct { s16 vx; u16 vy; s16 vz, pad; } SVec; + + extern s32 func_800491EC(void); + extern void func_800547D8(s32, MATRIX2 *); + extern void func_80052E38(MATRIX2 *); + extern u8 *D_800A5E60; + extern u8 D_800A6610[]; + extern short D_800B9A02; + extern u16 D_8018F250[]; + + DVECTOR2 tmpxy[4]; /* sp+0x10 */ + SVECTOR2 box[8]; /* sp+0x20 */ + SVECTOR2 sxy[8]; /* sp+0x60 */ + SVec v[3]; /* sp+0xA0 */ + SVec vdv; /* sp+0xB8 */ + MATRIX2 mtx; /* sp+0xC0 */ + struct { long otz, flag, opz, sz0, sz1, sz2, sz3; } g; /* sp+0xE0 */ + + s32 lim; /* spill 0x100 */ + u32 ot; /* spill 0x108 */ + s32 nparts; /* spill 0x110 */ + s32 j; + u32 nprim; + u32 i; + Part *part; /* spill 0x118 */ + SVec *vp; + Prim *prim; + u8 *pkt; + u8 *vtx; + u8 *va, *vb, *vc, *vd; + u32 w; + u32 m24; + s32 code; /* SIGNED: the switch tree uses slti, not sltiu */ + u32 wx, wy, wz; + s32 rot; + s32 zoff; + s32 xa32, xb32, t32; + s32 xmn1, xmx1, xmn2, xmx2; + s32 mnc, mxc; + s16 my, mny, mx, mn; + + if (*(s32 *)arg0 == 0) { + lim = func_800491EC() + *(s32 *)(arg0 + 0x64); + func_800547D8(arg0 + 0x10, &mtx); + func_80052E38(&mtx); + pkt = D_800A5E60; + + nparts = *(s32 *)(arg1 + 8); + ot = (u32)&D_800A6610[(*(u16 *)&D_800B9A02) << 14]; + rot = arg2; + zoff = arg3; + vtx = *(u8 **)(arg1 + 0x10); + part = (Part *)(arg1 + 0x14); + + for (j = 0; j < nparts; j++, part++) { + wx = part->xx; + mn = wx; + mx = wx >> 16; + wy = part->yy; + mny = wy + zoff; + my = (wy >> 16) + zoff; + wz = part->zz; + box[0].vx = mn; box[0].vy = mny; box[0].vz = wz; + box[1].vx = mx; box[1].vy = mny; box[1].vz = wz; + box[2].vx = mn; box[2].vy = mny; box[2].vz = wz >> 16; + box[3].vx = mx; box[3].vy = mny; box[3].vz = wz >> 16; + + gte_ldv3c(&box[0]); + gte_rtpt(); + gte_stsxy3(&sxy[0], &sxy[1], &sxy[2]); + gte_ldv0(&box[3]); + gte_rtps(); + + box[4].vx = mn; box[4].vy = my; box[4].vz = wz; + box[5].vx = mx; box[5].vy = my; box[5].vz = wz; + box[6].vx = mn; box[6].vy = my; box[6].vz = wz >> 16; + box[7].vx = mx; box[7].vy = my; box[7].vz = wz >> 16; + + gte_stsxy(&sxy[3]); + gte_ldv3c(&box[4]); + __asm__ volatile (""); /* §47 live-length slider (carried from the twin) */ + gte_rtpt(); + gte_stsxy3(&sxy[4], &sxy[5], &sxy[6]); + gte_ldv0(&box[7]); + gte_rtps(); + gte_stsxy(&sxy[7]); + gte_stszotz(&g.otz); + + if (lim >= g.otz) { + xa32 = sxy[0].vx; + xb32 = sxy[1].vx; + if (xb32 < xa32) { xmx1 = xa32; xmn1 = xb32; } else { xmn1 = xa32; xmx1 = xb32; } + t32 = sxy[2].vx; + if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32; + t32 = sxy[3].vx; + if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32; + xa32 = sxy[4].vx; + xb32 = sxy[5].vx; + if (xb32 < xa32) { xmx2 = xa32; xmn2 = xb32; } else { xmn2 = xa32; xmx2 = xb32; } + t32 = sxy[6].vx; + if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32; + t32 = sxy[7].vx; + if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32; + mnc = xmn1; + if (xmn2 < xmn1) mnc = xmn2; + mxc = xmx1; + if (mxc < xmx2) mxc = xmx2; + if ((s16)mxc >= -0xA0 && (s16)mnc < 0xA1) { + xa32 = sxy[0].vy; + xb32 = sxy[1].vy; + if (xb32 < xa32) { xmx1 = xa32; xmn1 = xb32; } else { xmn1 = xa32; xmx1 = xb32; } + t32 = sxy[2].vy; + if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32; + t32 = sxy[3].vy; + if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32; + xa32 = sxy[4].vy; + xb32 = sxy[5].vy; + if (xb32 < xa32) { xmx2 = xa32; xmn2 = xb32; } else { xmn2 = xa32; xmx2 = xb32; } + t32 = sxy[6].vy; + if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32; + t32 = sxy[7].vy; + if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32; + mnc = xmn1; + if (xmn2 < xmn1) mnc = xmn2; + mxc = xmx1; + if (mxc < xmx2) mxc = xmx2; + if ((s16)mxc >= -0x6E && (s16)mnc < 0x6F) { + prim = (Prim *)part->prim; + nprim = part->nprim; + for (i = 0; i < nprim; i++, prim++) { + m24 = 0xFFFFFF; + vp = &vdv; + w = prim->w1; + va = vtx + (w & 0xFFFF); + vb = vtx + (w >> 16); + w = prim->w2; + vc = vtx + (w & 0xFFFF); + v[0] = *(SVec *)va; + v[1] = *(SVec *)vb; + v[2] = *(SVec *)vc; + w = w >> 16; + v[0].vy += D_8018F250[(v[0].vz + rot) & 0xFF] + zoff; + v[1].vy += D_8018F250[(v[1].vz + rot) & 0xFF] + zoff; + v[2].vy += D_8018F250[(v[2].vz + rot) & 0xFF] + zoff; + gte_ldv3c(&v[0]); + gte_rtpt(); + gte_stflg(&g.flag); + if (!(g.flag & 0x7F85E000)) { + gte_nclip(); + code = w & 7; + vd = vtx + (w & 0xFFF8); + gte_stopz(&g.opz); + if (g.opz > 0) { + switch (code) { + case 6: + case 7: + gte_stsxy3_ft3(pkt); + gte_stsz3(&g.sz0, &g.sz1, &g.sz2); + if (((PolyFT3 *)pkt)->x0 > ((PolyFT3 *)pkt)->x1) { + mx = ((PolyFT3 *)pkt)->x0; + mn = ((PolyFT3 *)pkt)->x1; + } else { + mn = ((PolyFT3 *)pkt)->x0; + mx = ((PolyFT3 *)pkt)->x1; + } + if (((PolyFT3 *)pkt)->x2 > mx) mx = ((PolyFT3 *)pkt)->x2; + else if (((PolyFT3 *)pkt)->x2 < mn) mn = ((PolyFT3 *)pkt)->x2; + if (mx >= -0xA0 && mn < 0xA1) { + if (((PolyFT3 *)pkt)->y0 > ((PolyFT3 *)pkt)->y1) { + my = ((PolyFT3 *)pkt)->y0; + mny = ((PolyFT3 *)pkt)->y1; + } else { + mny = ((PolyFT3 *)pkt)->y0; + my = ((PolyFT3 *)pkt)->y1; + } + if (((PolyFT3 *)pkt)->y2 > my) my = ((PolyFT3 *)pkt)->y2; + else if (((PolyFT3 *)pkt)->y2 < mny) mny = ((PolyFT3 *)pkt)->y2; + if (my >= -0x6E && mny < 0x6F) { + s32 za; + u32 *otp; + u32 *tp; + if (g.sz0 > g.sz1) { + za = g.sz0; + if (za < g.sz2) za = g.sz2; + } else { + za = g.sz1; + if (za < g.sz2) za = g.sz2; + } + g.opz = za; + if (code == 7) g.opz = za + 0x200; + tp = (u32 *)prim->w0; + ((PolyFT3 *)pkt)->rgbc = tp[0] | 0x2000000; + ((PolyFT3 *)pkt)->uvc0 = tp[1]; + ((PolyFT3 *)pkt)->uvp1 = tp[2]; + ((PolyFT3 *)pkt)->uv2 = tp[3]; + otp = (u32 *)(((g.opz >> 2) << 2) + ot); + *(u32 *)pkt = (*otp & m24) | 0x7000000; + *otp = (*otp & 0xFF000000) | ((u32)pkt & m24); + pkt += 0x28; + } + } + break; + case 2: + case 3: + gte_stsxy3c(&tmpxy[0]); + vdv = *(SVec *)vd; + vdv.vy += D_8018F250[(vdv.vz + rot) & 0xFF] + zoff; + gte_ldv0(vp); + gte_rtps(); + if (tmpxy[0].vx > tmpxy[1].vx) { + mx = tmpxy[0].vx; + mn = tmpxy[1].vx; + } else { + mn = tmpxy[0].vx; + mx = tmpxy[1].vx; + } + if (tmpxy[2].vx > mx) mx = tmpxy[2].vx; + else if (tmpxy[2].vx < mn) mn = tmpxy[2].vx; + if (tmpxy[0].vy > tmpxy[1].vy) { + my = tmpxy[0].vy; + mny = tmpxy[1].vy; + } else { + mny = tmpxy[0].vy; + my = tmpxy[1].vy; + } + if (tmpxy[2].vy > my) my = tmpxy[2].vy; + else if (tmpxy[2].vy < mny) mny = tmpxy[2].vy; + gte_stflg(&g.flag); + if (!(g.flag & 0x7F85E000)) { + gte_stsz4(&g.sz0, &g.sz1, &g.sz2, &g.sz3); + gte_stsxy((long *)&((PolyFT4 *)pkt)->x3); + if (((PolyFT4 *)pkt)->x3 < mn) mn = ((PolyFT4 *)pkt)->x3; + else if (mx < ((PolyFT4 *)pkt)->x3) mx = ((PolyFT4 *)pkt)->x3; + if (mx >= -0xA0 && mn < 0xA1) { + if (((PolyFT4 *)pkt)->y3 < mny) mny = ((PolyFT4 *)pkt)->y3; + else if (my < ((PolyFT4 *)pkt)->y3) my = ((PolyFT4 *)pkt)->y3; + if (my >= -0x6E && mny < 0x6F) { + s32 za, zb; + u32 *otp; + u32 *tp; + u32 uvw; + zb = g.sz2; + if (zb < g.sz3) zb = g.sz3; + za = g.sz0; + if (za < g.sz1) za = g.sz1; + if (za < zb) za = zb; + g.opz = za; + if (code == 3) g.opz = za + 0x200; + *(u32 *)&((PolyFT4 *)pkt)->x0 = *(u32 *)&tmpxy[0]; + *(u32 *)&((PolyFT4 *)pkt)->x1 = *(u32 *)&tmpxy[1]; + *(u32 *)&((PolyFT4 *)pkt)->x2 = *(u32 *)&tmpxy[2]; + tp = (u32 *)prim->w0; + ((PolyFT4 *)pkt)->rgbc = tp[0] | 0x2000000; + ((PolyFT4 *)pkt)->uvc0 = tp[1]; + ((PolyFT4 *)pkt)->uvp1 = tp[2]; + uvw = tp[3]; + ((PolyFT4 *)pkt)->uv2 = uvw; + ((PolyFT4 *)pkt)->uv3 = uvw >> 16; + otp = (u32 *)(((g.opz >> 2) << 2) + ot); + *(u32 *)pkt = (*otp & m24) | 0x9000000; + *otp = (*otp & 0xFF000000) | ((u32)pkt & m24); + pkt += 0x28; + } + } + } + break; + } + } + } + } + } + } + } + } + D_800A5E60 = pkt; + } +} + diff --git a/src/ov_SC03_015/ov_SC03_015_jr_8017AE2C.c b/src/ov_SC03_015/ov_SC03_015_jr_8017AE2C.c index 6929f99ec..e03623170 100644 --- a/src/ov_SC03_015/ov_SC03_015_jr_8017AE2C.c +++ b/src/ov_SC03_015/ov_SC03_015_jr_8017AE2C.c @@ -3635,5 +3635,368 @@ INCLUDE_ASM("asm/ov_SC03_015/nonmatchings/ov_SC03_015_jr_8017AE2C", func_8017DE8 DEFINE_func_8017DF7C() /* dedup: shared engine-core @0x8017DF7C (src/shared) */ -INCLUDE_ASM("asm/ov_SC03_015/nonmatchings/ov_SC03_015_jr_8017AE2C", func_8017DF84); +#define gte_ldv0(r0) __asm__ __volatile__( \ + "lwc2 $0, 0(%0)\n" \ + "lwc2 $1, 4(%0)\n" \ + : : "r"(r0) : "memory") +#define gte_ldv0(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 )" \ + : \ + : "r"( r0 ) ) +#define gte_ldv3c(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 );" \ + "lwc2 $2, 8( %0 );" \ + "lwc2 $3, 12( %0 );" \ + "lwc2 $4, 16( %0 );" \ + "lwc2 $5, 20( %0 )" \ + : \ + : "r"( r0 ) ) +#define gte_rtps() __asm__ volatile ("nop;nop;rtps") +#define gte_rtpt() __asm__ volatile ("nop;nop;rtpt") +#define gte_nclip() __asm__ volatile ("nop;nop;nclip") +#define gte_stsxy(r0) __asm__ volatile ( \ + "swc2 $14, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) +#define gte_stsxy3(r0, r1, r2) __asm__ volatile ( \ + "swc2 $12, 0( %0 );" \ + "swc2 $13, 0( %1 );" \ + "swc2 $14, 0( %2 )" \ + : \ + : "r"( r0 ), "r"( r1 ), "r"( r2 ) \ + : "memory" ) +#define gte_stsxy3c(r0) __asm__ volatile ( \ + "swc2 $12, 0( %0 );" \ + "swc2 $13, 4( %0 );" \ + "swc2 $14, 8( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) +#define gte_stsxy3_ft3(r0) __asm__ volatile ( \ + "swc2 $12, 8( %0 );" \ + "swc2 $13, 16( %0 );" \ + "swc2 $14, 24( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) +#define gte_stsz3(r0, r1, r2) __asm__ volatile ( \ + "swc2 $17, 0( %0 );" \ + "swc2 $18, 0( %1 );" \ + "swc2 $19, 0( %2 )" \ + : \ + : "r"( r0 ), "r"( r1 ), "r"( r2 ) \ + : "memory" ) +#define gte_stsz4(r0, r1, r2, r3) __asm__ volatile ( \ + "swc2 $16, 0( %0 );" \ + "swc2 $17, 0( %1 );" \ + "swc2 $18, 0( %2 );" \ + "swc2 $19, 0( %3 )" \ + : \ + : "r"( r0 ), "r"( r1 ), "r"( r2 ), "r"( r3 ) ) +#define gte_stszotz(r0) __asm__ volatile ( \ + "mfc2 $12, $19;" \ + "nop;" \ + "sra $12, $12, 2;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) +#define gte_stflg(r0) __asm__ volatile ( \ + "cfc2 $12, $31;" \ + "nop;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) +#define gte_stopz(r0) __asm__ volatile ( \ + "swc2 $24, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + + +void func_8017DF84(s32 arg0, s32 arg1, s32 arg2, s32 arg3) +{ + typedef struct { u32 w0, w1, w2; } Prim_8017DF84; + /* vy UNSIGNED: the `+=` reads it with lhu, not lh. */ + typedef struct { s16 vx; u16 vy; s16 vz, pad; } SVec_8017DF84; + + extern s32 func_800491EC(void); + extern void func_800547D8(s32, MATRIX2 *); + extern void func_80052E38(MATRIX2 *); + extern u8 *D_800A5E60; + extern u8 D_800A6610[]; + extern u16 D_8018F250[]; + + DVECTOR2 tmpxy[4]; /* sp+0x10 */ + SVECTOR2 box[8]; /* sp+0x20 */ + SVECTOR2 sxy[8]; /* sp+0x60 */ + SVec_8017DF84 v[3]; /* sp+0xA0 */ + SVec_8017DF84 vdv; /* sp+0xB8 */ + MATRIX2 mtx; /* sp+0xC0 */ + struct { long otz, flag, opz, sz0, sz1, sz2, sz3; } g; /* sp+0xE0 */ + + s32 lim; /* spill 0x100 */ + u32 ot; /* spill 0x108 */ + s32 nparts; /* spill 0x110 */ + s32 j; + u32 nprim; + u32 i; + Part *part; /* spill 0x118 */ + SVec_8017DF84 *vp; + Prim_8017DF84 *prim; + u8 *pkt; + u8 *vtx; + u8 *va, *vb, *vc, *vd; + u32 w; + u32 m24; + s32 code; /* SIGNED: the switch tree uses slti, not sltiu */ + u32 wx, wy, wz; + s32 rot; + s32 zoff; + s32 xa32, xb32, t32; + s32 xmn1, xmx1, xmn2, xmx2; + s32 mnc, mxc; + s16 my, mny, mx, mn; + + if (*(s32 *)arg0 == 0) { + lim = func_800491EC() + *(s32 *)(arg0 + 0x64); + func_800547D8(arg0 + 0x10, &mtx); + func_80052E38(&mtx); + pkt = D_800A5E60; + + nparts = *(s32 *)(arg1 + 8); + ot = (u32)&D_800A6610[(*(u16 *)&D_800B9A02) << 14]; + rot = arg2; + zoff = arg3; + vtx = *(u8 **)(arg1 + 0x10); + part = (Part *)(arg1 + 0x14); + + for (j = 0; j < nparts; j++, part++) { + wx = part->xx; + mn = wx; + mx = wx >> 16; + wy = part->yy; + mny = wy + zoff; + my = (wy >> 16) + zoff; + wz = part->zz; + box[0].vx = mn; box[0].vy = mny; box[0].vz = wz; + box[1].vx = mx; box[1].vy = mny; box[1].vz = wz; + box[2].vx = mn; box[2].vy = mny; box[2].vz = wz >> 16; + box[3].vx = mx; box[3].vy = mny; box[3].vz = wz >> 16; + + gte_ldv3c(&box[0]); + gte_rtpt(); + gte_stsxy3(&sxy[0], &sxy[1], &sxy[2]); + gte_ldv0(&box[3]); + gte_rtps(); + + box[4].vx = mn; box[4].vy = my; box[4].vz = wz; + box[5].vx = mx; box[5].vy = my; box[5].vz = wz; + box[6].vx = mn; box[6].vy = my; box[6].vz = wz >> 16; + box[7].vx = mx; box[7].vy = my; box[7].vz = wz >> 16; + + gte_stsxy(&sxy[3]); + gte_ldv3c(&box[4]); + __asm__ volatile (""); /* §47 live-length slider (carried from the twin) */ + gte_rtpt(); + gte_stsxy3(&sxy[4], &sxy[5], &sxy[6]); + gte_ldv0(&box[7]); + gte_rtps(); + gte_stsxy(&sxy[7]); + gte_stszotz(&g.otz); + + if (lim >= g.otz) { + xa32 = sxy[0].vx; + xb32 = sxy[1].vx; + if (xb32 < xa32) { xmx1 = xa32; xmn1 = xb32; } else { xmn1 = xa32; xmx1 = xb32; } + t32 = sxy[2].vx; + if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32; + t32 = sxy[3].vx; + if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32; + xa32 = sxy[4].vx; + xb32 = sxy[5].vx; + if (xb32 < xa32) { xmx2 = xa32; xmn2 = xb32; } else { xmn2 = xa32; xmx2 = xb32; } + t32 = sxy[6].vx; + if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32; + t32 = sxy[7].vx; + if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32; + mnc = xmn1; + if (xmn2 < xmn1) mnc = xmn2; + mxc = xmx1; + if (mxc < xmx2) mxc = xmx2; + if ((s16)mxc >= -0xA0 && (s16)mnc < 0xA1) { + xa32 = sxy[0].vy; + xb32 = sxy[1].vy; + if (xb32 < xa32) { xmx1 = xa32; xmn1 = xb32; } else { xmn1 = xa32; xmx1 = xb32; } + t32 = sxy[2].vy; + if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32; + t32 = sxy[3].vy; + if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32; + xa32 = sxy[4].vy; + xb32 = sxy[5].vy; + if (xb32 < xa32) { xmx2 = xa32; xmn2 = xb32; } else { xmn2 = xa32; xmx2 = xb32; } + t32 = sxy[6].vy; + if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32; + t32 = sxy[7].vy; + if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32; + mnc = xmn1; + if (xmn2 < xmn1) mnc = xmn2; + mxc = xmx1; + if (mxc < xmx2) mxc = xmx2; + if ((s16)mxc >= -0x6E && (s16)mnc < 0x6F) { + prim = (Prim_8017DF84 *)part->prim; + nprim = part->nprim; + for (i = 0; i < nprim; i++, prim++) { + m24 = 0xFFFFFF; + vp = &vdv; + w = prim->w1; + va = vtx + (w & 0xFFFF); + vb = vtx + (w >> 16); + w = prim->w2; + vc = vtx + (w & 0xFFFF); + v[0] = *(SVec_8017DF84 *)va; + v[1] = *(SVec_8017DF84 *)vb; + v[2] = *(SVec_8017DF84 *)vc; + w = w >> 16; + v[0].vy += D_8018F250[(v[0].vz + rot) & 0xFF] + zoff; + v[1].vy += D_8018F250[(v[1].vz + rot) & 0xFF] + zoff; + v[2].vy += D_8018F250[(v[2].vz + rot) & 0xFF] + zoff; + gte_ldv3c(&v[0]); + gte_rtpt(); + gte_stflg(&g.flag); + if (!(g.flag & 0x7F85E000)) { + gte_nclip(); + code = w & 7; + vd = vtx + (w & 0xFFF8); + gte_stopz(&g.opz); + if (g.opz > 0) { + switch (code) { + case 6: + case 7: + gte_stsxy3_ft3(pkt); + gte_stsz3(&g.sz0, &g.sz1, &g.sz2); + if (((PolyFT3 *)pkt)->x0 > ((PolyFT3 *)pkt)->x1) { + mx = ((PolyFT3 *)pkt)->x0; + mn = ((PolyFT3 *)pkt)->x1; + } else { + mn = ((PolyFT3 *)pkt)->x0; + mx = ((PolyFT3 *)pkt)->x1; + } + if (((PolyFT3 *)pkt)->x2 > mx) mx = ((PolyFT3 *)pkt)->x2; + else if (((PolyFT3 *)pkt)->x2 < mn) mn = ((PolyFT3 *)pkt)->x2; + if (mx >= -0xA0 && mn < 0xA1) { + if (((PolyFT3 *)pkt)->y0 > ((PolyFT3 *)pkt)->y1) { + my = ((PolyFT3 *)pkt)->y0; + mny = ((PolyFT3 *)pkt)->y1; + } else { + mny = ((PolyFT3 *)pkt)->y0; + my = ((PolyFT3 *)pkt)->y1; + } + if (((PolyFT3 *)pkt)->y2 > my) my = ((PolyFT3 *)pkt)->y2; + else if (((PolyFT3 *)pkt)->y2 < mny) mny = ((PolyFT3 *)pkt)->y2; + if (my >= -0x6E && mny < 0x6F) { + s32 za; + u32 *otp; + u32 *tp; + if (g.sz0 > g.sz1) { + za = g.sz0; + if (za < g.sz2) za = g.sz2; + } else { + za = g.sz1; + if (za < g.sz2) za = g.sz2; + } + g.opz = za; + if (code == 7) g.opz = za + 0x200; + tp = (u32 *)prim->w0; + ((PolyFT3 *)pkt)->rgbc = tp[0] | 0x2000000; + ((PolyFT3 *)pkt)->uvc0 = tp[1]; + ((PolyFT3 *)pkt)->uvp1 = tp[2]; + ((PolyFT3 *)pkt)->uv2 = tp[3]; + otp = (u32 *)(((g.opz >> 2) << 2) + ot); + *(u32 *)pkt = (*otp & m24) | 0x7000000; + *otp = (*otp & 0xFF000000) | ((u32)pkt & m24); + pkt += 0x28; + } + } + break; + case 2: + case 3: + gte_stsxy3c(&tmpxy[0]); + vdv = *(SVec_8017DF84 *)vd; + vdv.vy += D_8018F250[(vdv.vz + rot) & 0xFF] + zoff; + gte_ldv0(vp); + gte_rtps(); + if (tmpxy[0].vx > tmpxy[1].vx) { + mx = tmpxy[0].vx; + mn = tmpxy[1].vx; + } else { + mn = tmpxy[0].vx; + mx = tmpxy[1].vx; + } + if (tmpxy[2].vx > mx) mx = tmpxy[2].vx; + else if (tmpxy[2].vx < mn) mn = tmpxy[2].vx; + if (tmpxy[0].vy > tmpxy[1].vy) { + my = tmpxy[0].vy; + mny = tmpxy[1].vy; + } else { + mny = tmpxy[0].vy; + my = tmpxy[1].vy; + } + if (tmpxy[2].vy > my) my = tmpxy[2].vy; + else if (tmpxy[2].vy < mny) mny = tmpxy[2].vy; + gte_stflg(&g.flag); + if (!(g.flag & 0x7F85E000)) { + gte_stsz4(&g.sz0, &g.sz1, &g.sz2, &g.sz3); + gte_stsxy((long *)&((PolyFT4 *)pkt)->x3); + if (((PolyFT4 *)pkt)->x3 < mn) mn = ((PolyFT4 *)pkt)->x3; + else if (mx < ((PolyFT4 *)pkt)->x3) mx = ((PolyFT4 *)pkt)->x3; + if (mx >= -0xA0 && mn < 0xA1) { + if (((PolyFT4 *)pkt)->y3 < mny) mny = ((PolyFT4 *)pkt)->y3; + else if (my < ((PolyFT4 *)pkt)->y3) my = ((PolyFT4 *)pkt)->y3; + if (my >= -0x6E && mny < 0x6F) { + s32 za, zb; + u32 *otp; + u32 *tp; + u32 uvw; + zb = g.sz2; + if (zb < g.sz3) zb = g.sz3; + za = g.sz0; + if (za < g.sz1) za = g.sz1; + if (za < zb) za = zb; + g.opz = za; + if (code == 3) g.opz = za + 0x200; + *(u32 *)&((PolyFT4 *)pkt)->x0 = *(u32 *)&tmpxy[0]; + *(u32 *)&((PolyFT4 *)pkt)->x1 = *(u32 *)&tmpxy[1]; + *(u32 *)&((PolyFT4 *)pkt)->x2 = *(u32 *)&tmpxy[2]; + tp = (u32 *)prim->w0; + ((PolyFT4 *)pkt)->rgbc = tp[0] | 0x2000000; + ((PolyFT4 *)pkt)->uvc0 = tp[1]; + ((PolyFT4 *)pkt)->uvp1 = tp[2]; + uvw = tp[3]; + ((PolyFT4 *)pkt)->uv2 = uvw; + ((PolyFT4 *)pkt)->uv3 = uvw >> 16; + otp = (u32 *)(((g.opz >> 2) << 2) + ot); + *(u32 *)pkt = (*otp & m24) | 0x9000000; + *otp = (*otp & 0xFF000000) | ((u32)pkt & m24); + pkt += 0x28; + } + } + } + break; + } + } + } + } + } + } + } + } + D_800A5E60 = pkt; + } +} + diff --git a/src/ov_SC03_028/ov_SC03_028_jr_8017AE2C.c b/src/ov_SC03_028/ov_SC03_028_jr_8017AE2C.c index 92bc1d63f..a76523956 100644 --- a/src/ov_SC03_028/ov_SC03_028_jr_8017AE2C.c +++ b/src/ov_SC03_028/ov_SC03_028_jr_8017AE2C.c @@ -4940,7 +4940,176 @@ void func_80183DC8(void *a0) { } -INCLUDE_ASM("asm/ov_SC03_028/nonmatchings/ov_SC03_028_jr_8017AE2C", func_80183E04); +#include "common.h" + +/* ---- decls already present at file scope in the TU (reused verbatim) ---- */ +extern s32 D_80126950; +extern s16 D_800B9A02; +extern void func_8004914C(void *a0); +extern void func_800491AC(void *a0); +extern void RotTransSV(void *a0, void *a1, void *a2); +extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3); + +/* ---- new decls (canonical forms from src/shared/engine_core.h) ---- */ +extern s32 D_800A651C; +extern u8 D_800AF648; +extern u8 D_8018F968[]; +extern u32 D_801902C8[]; +extern u8 D_801902D4[]; +extern u8 D_801902D5[]; +extern u8 D_801902D6[]; +extern u8 D_801902D7[]; +extern u8 D_801902E4[]; +extern u8 D_801902E5[]; +extern u8 D_801902E6[]; +extern u8 D_801902E7[]; +extern u8 D_801902F4[]; +extern u8 D_801902F5[]; +extern u8 D_801902F6[]; +extern u8 D_801902F7[]; +extern void *func_80010A08(s32); +extern s32 func_8005A600(s32, s32, s32, s32, s32); +extern s32 GetTPage(s32, s32, s32, s32); +extern s32 AddPrim(s32, void *); + +#define gte_SetRotMatrix(r0) __asm__ volatile ( \ + "lw $12, 0( %0 );" \ + "lw $13, 4( %0 );" \ + "ctc2 $12, $0;" \ + "ctc2 $13, $1;" \ + "lw $12, 8( %0 );" \ + "lw $13, 12( %0 );" \ + "lw $14, 16( %0 );" \ + "ctc2 $12, $2;" \ + "ctc2 $13, $3;" \ + "ctc2 $14, $4" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) +#define gte_SetTransMatrix(r0) __asm__ volatile ( \ + "lw $12, 20( %0 );" \ + "lw $13, 24( %0 );" \ + "ctc2 $12, $5;" \ + "lw $14, 28( %0 );" \ + "ctc2 $13, $6;" \ + "ctc2 $14, $7" \ + : \ + : "r"( r0 ) \ + : "$12", "$13", "$14" ) + + +/* Byte-verified levers (match_one MATCH, 265 ins): + * - L5/frame: locals start at sp+0x18 (5-arg out-arg area). tags/sv/xs/ys are arrays and take + * slots in DECLARATION order; flag/sxy/pz must be ONE struct — as separate address-taken + * scalars gcc packs them after the arrays with a 4-byte hole (flag landed at 0x58, not 0x50). + * - The 14 primitive stores are written off the SINGLE pointer biv `pp` (prim+0xC). loop.c + * combines their address givs into one register based at the LAST ref (pp+0x22 = prim+0x2E, + * $s0), and keeps `pp` itself ($s3) for AddPrim's value use. Adding a second explicit cursor + * (`q = prim+0x2E`) costs an EXTRA giv register and breaks the frame. + * - L3: `tags[0] = (s32)(prim + 0xC)` is written as its OWN expression (not `= (s32)pp`); CSE + * then emits `addiu $v0,$s4,0xC` + `addu $s3,$v0,$zero` — the copy the target has. + * - Loop counter is k = 0..3 with i = k*4 as a GIV, not a biv stepping 4. Both give the same + * `slti $s1,0x10` compare, but only the giv form puts the address-giv init BEFORE the index + * init in the preheader. `pp += 0x24` must come AFTER `k += 1` so pp's iv class is recorded + * last (loop_iv_list is prepend-ordered) and therefore emits its giv init FIRST. + * - tags[1..3] are genuinely DEAD stores in the original; they must be kept. + */ +void func_80183E04(void *a0) +{ + s32 tags[4]; /* sp+0x18 */ + s16 sv[4]; /* sp+0x28 */ + s16 xs[8]; /* sp+0x30 */ + s16 ys[8]; /* sp+0x40 */ + struct { + s32 flag; /* sp+0x50 */ + u16 sxy[2]; /* sp+0x54 */ + s32 pz; /* sp+0x58 */ + } o; + + s32 m; + void *pv; + s32 *pflag; + s32 ret; + s32 d; + s32 e; + s32 x; + s32 y; + s32 ot; + u8 *prim; + u8 *pp; + u8 *base; + u32 *pal; + s32 i; + s32 k; + + m = *(s32 *)((s32)a0 + 0x20) + 0x34; + gte_SetRotMatrix(m); + gte_SetTransMatrix(m); + + pv = (void *)sv; + pflag = &o.flag; + RotTransSV(D_8018F968, pv, pflag); + func_8004914C(&D_800AF648); + func_800491AC(&D_800AF648); + ret = RotTransPers((s32)pv, (s32)o.sxy, &o.pz, pflag); + if ((ret > 0) && (o.flag >= 0)) { + ret = ret * 4; + d = ((D_80126950 + 0x1F4) * 24) / ret; + x = o.sxy[0]; + y = o.sxy[1]; + ot = *(s32 *)((s8 *)&D_800A651C + ((u16)D_800B9A02 * 0x14)) + ret; + e = (d * 179) >> 8; + + xs[2] = x; + ys[2] = y; + xs[0] = x - d; + xs[1] = x - e; + xs[3] = x + e; + xs[4] = x + d; + ys[0] = y - d; + ys[1] = y - e; + ys[3] = y + e; + ys[4] = y + d; + + prim = (u8 *)func_80010A08(0x9C); + if (prim != 0) { + s32 tp; + tp = GetTPage(0, 1, 0, 0); + func_8005A600((s32)prim, 0, 0, (u16)tp, 0); + + tags[0] = (s32)(prim + 0xC); + pp = prim + 0xC; + pal = D_801902C8; + base = (u8 *)tags; + k = 0; + tags[1] = (s32)(prim + 0x30); + tags[2] = (s32)(prim + 0x54); + tags[3] = (s32)(prim + 0x78); + do { + i = k * 4; + *(u32 *)(pp + 0x04) = pal[D_801902F4[i]]; + *(u32 *)(pp + 0x0C) = pal[D_801902F5[i]]; + *(u32 *)(pp + 0x14) = pal[D_801902F6[i]]; + *(u32 *)(pp + 0x1C) = pal[D_801902F7[i]]; + *(u8 *)(pp + 0x03) = 8; + *(u8 *)(pp + 0x07) = 0x3A; + *(u16 *)(pp + 0x08) = *(u16 *)(base + 0x18 + D_801902D4[i] * 2); + *(u16 *)(pp + 0x10) = *(u16 *)(base + 0x18 + D_801902D5[i] * 2); + *(u16 *)(pp + 0x18) = *(u16 *)(base + 0x18 + D_801902D6[i] * 2); + *(u16 *)(pp + 0x20) = *(u16 *)(base + 0x18 + D_801902D7[i] * 2); + *(u16 *)(pp + 0x0A) = *(u16 *)(base + 0x28 + D_801902E4[i] * 2); + *(u16 *)(pp + 0x12) = *(u16 *)(base + 0x28 + D_801902E5[i] * 2); + *(u16 *)(pp + 0x1A) = *(u16 *)(base + 0x28 + D_801902E6[i] * 2); + *(u16 *)(pp + 0x22) = *(u16 *)(base + 0x28 + D_801902E7[i] * 2); + AddPrim(ot, pp); + k += 1; + pp += 0x24; + } while (k < 4); + AddPrim(ot, prim); + } + } +} + void func_80184228(void) { } diff --git a/src/ov_SC03_029/ov_SC03_029_jr_8017DC70.c b/src/ov_SC03_029/ov_SC03_029_jr_8017DC70.c index fab5c16aa..4052f0754 100644 --- a/src/ov_SC03_029/ov_SC03_029_jr_8017DC70.c +++ b/src/ov_SC03_029/ov_SC03_029_jr_8017DC70.c @@ -4174,7 +4174,48 @@ INCLUDE_ASM("asm/ov_SC03_029/nonmatchings/ov_SC03_029_jr_8017DC70", func_80184D3 INCLUDE_ASM("asm/ov_SC03_029/nonmatchings/ov_SC03_029_jr_8017DC70", func_80184DC8); -INCLUDE_ASM("asm/ov_SC03_029/nonmatchings/ov_SC03_029_jr_8017DC70", func_80184ED0); + +extern s32 func_8012BEE8(s32 a0); +extern void func_8012C218(void *a0); +extern s32 func_8004787C(s32 a0); +extern s32 func_80047948(s32 a0); + +void func_80184ED0(s32 param_1) +{ + s32 iVar3; + s32 uVar1; + s32 sVar2; + + if (*(u16 *)(param_1 + 0x34) == 0) { + if ((*(u16 *)(param_1 + 0x70) & 0xF) == 2) { + *(s16 *)(*(s32 *)(param_1 + 0x20) + 0x10) = + *(s16 *)(*(s32 *)(param_1 + 0x20) + 0x10) + -0x80; + if (*(s16 *)(*(s32 *)(param_1 + 0x20) + 0x10) < -0x400) { + *(s16 *)(*(s32 *)(param_1 + 0x20) + 0x10) = -0x400; + } + } + iVar3 = func_8012BEE8(param_1); + if (iVar3 != 0) { + *(s32 *)(param_1 + 0x1C) = 8; + *(u16 *)(param_1 + 0x34) = *(u16 *)(param_1 + 0x34) + 1; + *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x2C) = + *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x2C) | 0x10; + } + } else { + iVar3 = func_8012BEE8(param_1); + if (iVar3 != 0) { + ((void (*)(s32))func_8012C218)(param_1); + } else { + uVar1 = func_8004787C((*(s32 *)(param_1 + 0x1C) << 10) >> 3); + iVar3 = *(s32 *)(param_1 + 0x20); + *(s16 *)(iVar3 + 0x1C) = uVar1; + *(s16 *)(iVar3 + 0x18) = uVar1; + sVar2 = func_80047948((*(s32 *)(param_1 + 0x1C) << 10) >> 3); + *(s16 *)(*(s32 *)(param_1 + 0x20) + 0x1A) = sVar2 * 8 + 0x1000; + } + } +} + INCLUDE_ASM("asm/ov_SC03_029/nonmatchings/ov_SC03_029_jr_8017DC70", func_80184FF0); diff --git a/src/ov_SC03_111/ov_SC03_111_jr_8017EC58.c b/src/ov_SC03_111/ov_SC03_111_jr_8017EC58.c index bdcfbb38a..67f093b1e 100644 --- a/src/ov_SC03_111/ov_SC03_111_jr_8017EC58.c +++ b/src/ov_SC03_111/ov_SC03_111_jr_8017EC58.c @@ -3189,7 +3189,370 @@ void func_8017EC58(s32 arg0) } -INCLUDE_ASM("asm/ov_SC03_111/nonmatchings/ov_SC03_111_jr_8017EC58", func_8017FB38); +#define gte_ldv0(r0) __asm__ __volatile__( \ + "lwc2 $0, 0(%0)\n" \ + "lwc2 $1, 4(%0)\n" \ + : : "r"(r0) : "memory") +#define gte_ldv0(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 )" \ + : \ + : "r"( r0 ) ) +#define gte_ldv3c(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 );" \ + "lwc2 $2, 8( %0 );" \ + "lwc2 $3, 12( %0 );" \ + "lwc2 $4, 16( %0 );" \ + "lwc2 $5, 20( %0 )" \ + : \ + : "r"( r0 ) ) +#define gte_rtps() __asm__ volatile ("nop;nop;rtps") +#define gte_rtpt() __asm__ volatile ("nop;nop;rtpt") +#define gte_nclip() __asm__ volatile ("nop;nop;nclip") +#define gte_stsxy(r0) __asm__ volatile ( \ + "swc2 $14, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) +#define gte_stsxy3(r0, r1, r2) __asm__ volatile ( \ + "swc2 $12, 0( %0 );" \ + "swc2 $13, 0( %1 );" \ + "swc2 $14, 0( %2 )" \ + : \ + : "r"( r0 ), "r"( r1 ), "r"( r2 ) \ + : "memory" ) +#define gte_stsxy3c(r0) __asm__ volatile ( \ + "swc2 $12, 0( %0 );" \ + "swc2 $13, 4( %0 );" \ + "swc2 $14, 8( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) +#define gte_stsxy3_ft3(r0) __asm__ volatile ( \ + "swc2 $12, 8( %0 );" \ + "swc2 $13, 16( %0 );" \ + "swc2 $14, 24( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) +#define gte_stsz3(r0, r1, r2) __asm__ volatile ( \ + "swc2 $17, 0( %0 );" \ + "swc2 $18, 0( %1 );" \ + "swc2 $19, 0( %2 )" \ + : \ + : "r"( r0 ), "r"( r1 ), "r"( r2 ) \ + : "memory" ) +#define gte_stsz4(r0, r1, r2, r3) __asm__ volatile ( \ + "swc2 $16, 0( %0 );" \ + "swc2 $17, 0( %1 );" \ + "swc2 $18, 0( %2 );" \ + "swc2 $19, 0( %3 )" \ + : \ + : "r"( r0 ), "r"( r1 ), "r"( r2 ), "r"( r3 ) ) +#define gte_stszotz(r0) __asm__ volatile ( \ + "mfc2 $12, $19;" \ + "nop;" \ + "sra $12, $12, 2;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) +#define gte_stflg(r0) __asm__ volatile ( \ + "cfc2 $12, $31;" \ + "nop;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) +#define gte_stopz(r0) __asm__ volatile ( \ + "swc2 $24, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + + +void func_8017FB38(s32 arg0, s32 arg1, s32 arg2, s32 arg3) +{ + typedef struct { u32 w0, w1, w2; } Prim_8017FB38; + /* vy UNSIGNED: the `+=` reads it with lhu, not lh. */ + typedef struct { s16 vx; u16 vy; s16 vz, pad; } SVec_8017FB38; + + extern s32 func_800491EC(void); + extern void func_800547D8(s32, MATRIX2 *); + extern void func_80052E38(MATRIX2 *); + extern u8 *D_800A5E60; + extern u8 D_800A6610[]; + extern u16 D_801887C4[]; + + DVECTOR2 tmpxy[4]; /* sp+0x10 */ + SVECTOR2 box[8]; /* sp+0x20 */ + SVECTOR2 sxy[8]; /* sp+0x60 */ + SVec_8017FB38 v[3]; /* sp+0xA0 */ + SVec_8017FB38 vdv; /* sp+0xB8 */ + MATRIX2 mtx; /* sp+0xC0 */ + struct { long otz, flag, opz, sz0, sz1, sz2, sz3; } g; /* sp+0xE0 */ + + s32 lim; /* spill 0x100 */ + u32 ot; /* spill 0x108 */ + s32 nparts; /* spill 0x110 */ + s32 j; + u32 nprim; + u32 i; + Part *part; /* spill 0x118 */ + SVec_8017FB38 *vp; + Prim_8017FB38 *prim; + u8 *pkt; + u8 *vtx; + u8 *va, *vb, *vc, *vd; + u32 w; + u32 m24; + s32 code; /* SIGNED: the switch tree uses slti, not sltiu */ + u32 wx, wy, wz; + s32 rot; + s32 zoff; + s32 xa32, xb32, t32; + s32 xmn1, xmx1, xmn2, xmx2; + s32 mnc, mxc; + s16 my, mny, mx, mn; + + if (*(s32 *)arg0 == 0) { + lim = func_800491EC() + *(s32 *)(arg0 + 0x64); + func_800547D8(arg0 + 0x10, &mtx); + func_80052E38(&mtx); + pkt = D_800A5E60; + + nparts = *(s32 *)(arg1 + 8); + ot = (u32)&D_800A6610[(*(u16 *)&D_800B9A02) << 14]; + rot = arg2; + zoff = arg3; + vtx = *(u8 **)(arg1 + 0x10); + part = (Part *)(arg1 + 0x14); + + for (j = 0; j < nparts; j++, part++) { + wx = part->xx; + mn = wx; + mx = wx >> 16; + wy = part->yy; + mny = wy + zoff; + my = (wy >> 16) + zoff; + wz = part->zz; + box[0].vx = mn; box[0].vy = mny; box[0].vz = wz; + box[1].vx = mx; box[1].vy = mny; box[1].vz = wz; + box[2].vx = mn; box[2].vy = mny; box[2].vz = wz >> 16; + box[3].vx = mx; box[3].vy = mny; box[3].vz = wz >> 16; + + gte_ldv3c(&box[0]); + gte_rtpt(); + gte_stsxy3(&sxy[0], &sxy[1], &sxy[2]); + gte_ldv0(&box[3]); + gte_rtps(); + + box[4].vx = mn; box[4].vy = my; box[4].vz = wz; + box[5].vx = mx; box[5].vy = my; box[5].vz = wz; + box[6].vx = mn; box[6].vy = my; box[6].vz = wz >> 16; + box[7].vx = mx; box[7].vy = my; box[7].vz = wz >> 16; + + gte_stsxy(&sxy[3]); + gte_ldv3c(&box[4]); + __asm__ volatile (""); /* §47 live-length slider (carried from the twin) */ + gte_rtpt(); + gte_stsxy3(&sxy[4], &sxy[5], &sxy[6]); + gte_ldv0(&box[7]); + gte_rtps(); + gte_stsxy(&sxy[7]); + gte_stszotz(&g.otz); + + if (lim >= g.otz) { + xa32 = sxy[0].vx; + xb32 = sxy[1].vx; + if (xb32 < xa32) { xmx1 = xa32; xmn1 = xb32; } else { xmn1 = xa32; xmx1 = xb32; } + t32 = sxy[2].vx; + if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32; + t32 = sxy[3].vx; + if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32; + xa32 = sxy[4].vx; + xb32 = sxy[5].vx; + if (xb32 < xa32) { xmx2 = xa32; xmn2 = xb32; } else { xmn2 = xa32; xmx2 = xb32; } + t32 = sxy[6].vx; + if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32; + t32 = sxy[7].vx; + if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32; + mnc = xmn1; + if (xmn2 < xmn1) mnc = xmn2; + mxc = xmx1; + if (mxc < xmx2) mxc = xmx2; + if ((s16)mxc >= -0xA0 && (s16)mnc < 0xA1) { + xa32 = sxy[0].vy; + xb32 = sxy[1].vy; + if (xb32 < xa32) { xmx1 = xa32; xmn1 = xb32; } else { xmn1 = xa32; xmx1 = xb32; } + t32 = sxy[2].vy; + if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32; + t32 = sxy[3].vy; + if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32; + xa32 = sxy[4].vy; + xb32 = sxy[5].vy; + if (xb32 < xa32) { xmx2 = xa32; xmn2 = xb32; } else { xmn2 = xa32; xmx2 = xb32; } + t32 = sxy[6].vy; + if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32; + t32 = sxy[7].vy; + if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32; + mnc = xmn1; + if (xmn2 < xmn1) mnc = xmn2; + mxc = xmx1; + if (mxc < xmx2) mxc = xmx2; + if ((s16)mxc >= -0x6E && (s16)mnc < 0x6F) { + prim = (Prim_8017FB38 *)part->prim; + nprim = part->nprim; + for (i = 0; i < nprim; i++, prim++) { + m24 = 0xFFFFFF; + vp = &vdv; + w = prim->w1; + va = vtx + (w & 0xFFFF); + vb = vtx + (w >> 16); + w = prim->w2; + vc = vtx + (w & 0xFFFF); + v[0] = *(SVec_8017FB38 *)va; + v[1] = *(SVec_8017FB38 *)vb; + v[2] = *(SVec_8017FB38 *)vc; + w = w >> 16; + v[0].vy += D_801887C4[(v[0].vz + rot) & 0xFF] + zoff; + v[1].vy += D_801887C4[(v[1].vz + rot) & 0xFF] + zoff; + v[2].vy += D_801887C4[(v[2].vz + rot) & 0xFF] + zoff; + gte_ldv3c(&v[0]); + gte_rtpt(); + gte_stflg(&g.flag); + if (!(g.flag & 0x7F85E000)) { + gte_nclip(); + code = w & 7; + vd = vtx + (w & 0xFFF8); + gte_stopz(&g.opz); + if (g.opz > 0) { + switch (code) { + case 6: + case 7: + gte_stsxy3_ft3(pkt); + gte_stsz3(&g.sz0, &g.sz1, &g.sz2); + if (((PolyFT3 *)pkt)->x0 > ((PolyFT3 *)pkt)->x1) { + mx = ((PolyFT3 *)pkt)->x0; + mn = ((PolyFT3 *)pkt)->x1; + } else { + mn = ((PolyFT3 *)pkt)->x0; + mx = ((PolyFT3 *)pkt)->x1; + } + if (((PolyFT3 *)pkt)->x2 > mx) mx = ((PolyFT3 *)pkt)->x2; + else if (((PolyFT3 *)pkt)->x2 < mn) mn = ((PolyFT3 *)pkt)->x2; + if (mx >= -0xA0 && mn < 0xA1) { + if (((PolyFT3 *)pkt)->y0 > ((PolyFT3 *)pkt)->y1) { + my = ((PolyFT3 *)pkt)->y0; + mny = ((PolyFT3 *)pkt)->y1; + } else { + mny = ((PolyFT3 *)pkt)->y0; + my = ((PolyFT3 *)pkt)->y1; + } + if (((PolyFT3 *)pkt)->y2 > my) my = ((PolyFT3 *)pkt)->y2; + else if (((PolyFT3 *)pkt)->y2 < mny) mny = ((PolyFT3 *)pkt)->y2; + if (my >= -0x6E && mny < 0x6F) { + s32 za; + u32 *otp; + u32 *tp; + if (g.sz0 > g.sz1) { + za = g.sz0; + if (za < g.sz2) za = g.sz2; + } else { + za = g.sz1; + if (za < g.sz2) za = g.sz2; + } + g.opz = za; + if (code == 7) g.opz = za + 0x200; + tp = (u32 *)prim->w0; + ((PolyFT3 *)pkt)->rgbc = tp[0] | 0x2000000; + ((PolyFT3 *)pkt)->uvc0 = tp[1]; + ((PolyFT3 *)pkt)->uvp1 = tp[2]; + ((PolyFT3 *)pkt)->uv2 = tp[3]; + otp = (u32 *)(((g.opz >> 2) << 2) + ot); + *(u32 *)pkt = (*otp & m24) | 0x7000000; + *otp = (*otp & 0xFF000000) | ((u32)pkt & m24); + pkt += 0x28; + } + } + break; + case 2: + case 3: + gte_stsxy3c(&tmpxy[0]); + vdv = *(SVec_8017FB38 *)vd; + vdv.vy += D_801887C4[(vdv.vz + rot) & 0xFF] + zoff; + gte_ldv0(vp); + gte_rtps(); + if (tmpxy[0].vx > tmpxy[1].vx) { + mx = tmpxy[0].vx; + mn = tmpxy[1].vx; + } else { + mn = tmpxy[0].vx; + mx = tmpxy[1].vx; + } + if (tmpxy[2].vx > mx) mx = tmpxy[2].vx; + else if (tmpxy[2].vx < mn) mn = tmpxy[2].vx; + if (tmpxy[0].vy > tmpxy[1].vy) { + my = tmpxy[0].vy; + mny = tmpxy[1].vy; + } else { + mny = tmpxy[0].vy; + my = tmpxy[1].vy; + } + if (tmpxy[2].vy > my) my = tmpxy[2].vy; + else if (tmpxy[2].vy < mny) mny = tmpxy[2].vy; + gte_stflg(&g.flag); + if (!(g.flag & 0x7F85E000)) { + gte_stsz4(&g.sz0, &g.sz1, &g.sz2, &g.sz3); + gte_stsxy((long *)&((PolyFT4 *)pkt)->x3); + if (((PolyFT4 *)pkt)->x3 < mn) mn = ((PolyFT4 *)pkt)->x3; + else if (mx < ((PolyFT4 *)pkt)->x3) mx = ((PolyFT4 *)pkt)->x3; + if (mx >= -0xA0 && mn < 0xA1) { + if (((PolyFT4 *)pkt)->y3 < mny) mny = ((PolyFT4 *)pkt)->y3; + else if (my < ((PolyFT4 *)pkt)->y3) my = ((PolyFT4 *)pkt)->y3; + if (my >= -0x6E && mny < 0x6F) { + s32 za, zb; + u32 *otp; + u32 *tp; + u32 uvw; + zb = g.sz2; + if (zb < g.sz3) zb = g.sz3; + za = g.sz0; + if (za < g.sz1) za = g.sz1; + if (za < zb) za = zb; + g.opz = za; + if (code == 3) g.opz = za + 0x200; + *(u32 *)&((PolyFT4 *)pkt)->x0 = *(u32 *)&tmpxy[0]; + *(u32 *)&((PolyFT4 *)pkt)->x1 = *(u32 *)&tmpxy[1]; + *(u32 *)&((PolyFT4 *)pkt)->x2 = *(u32 *)&tmpxy[2]; + tp = (u32 *)prim->w0; + ((PolyFT4 *)pkt)->rgbc = tp[0] | 0x2000000; + ((PolyFT4 *)pkt)->uvc0 = tp[1]; + ((PolyFT4 *)pkt)->uvp1 = tp[2]; + uvw = tp[3]; + ((PolyFT4 *)pkt)->uv2 = uvw; + ((PolyFT4 *)pkt)->uv3 = uvw >> 16; + otp = (u32 *)(((g.opz >> 2) << 2) + ot); + *(u32 *)pkt = (*otp & m24) | 0x9000000; + *otp = (*otp & 0xFF000000) | ((u32)pkt & m24); + pkt += 0x28; + } + } + } + break; + } + } + } + } + } + } + } + } + D_800A5E60 = pkt; + } +} + extern void (*D_80188A14[])(void); @@ -3636,7 +3999,189 @@ s32 func_80181C38(u32 a0v) INCLUDE_ASM("asm/ov_SC03_111/nonmatchings/ov_SC03_111_jr_8017EC58", func_80181CE4); -INCLUDE_ASM("asm/ov_SC03_111/nonmatchings/ov_SC03_111_jr_8017EC58", func_80182490); +extern s32 func_8004787C(s32 a0); +extern s32 func_80047948(s32 a0); +extern void func_80049CAC(s32 a0, s32 a1); +extern void func_8012C218(void *a0); +extern s32 func_8012CEB0(s32 a0, s32 a1, s32 a2); +#define SRM_80186B78(r0) __asm__ __volatile__( \ + "lw $12, 0(%0)\n" \ + "lw $13, 4(%0)\n" \ + "ctc2 $12, $0\n" \ + "ctc2 $13, $1\n" \ + "lw $12, 8(%0)\n" \ + "lw $13, 12(%0)\n" \ + "lw $14, 16(%0)\n" \ + "ctc2 $12, $2\n" \ + "ctc2 $13, $3\n" \ + "ctc2 $14, $4\n" \ + : : "r"(r0) : "$12", "$13", "$14", "memory") +#define STM_80186B78(r0) __asm__ __volatile__( \ + "lw $12, 20(%0)\n" \ + "lw $13, 24(%0)\n" \ + "ctc2 $12, $5\n" \ + "lw $14, 28(%0)\n" \ + "ctc2 $13, $6\n" \ + "ctc2 $14, $7\n" \ + : : "r"(r0) : "$12", "$13", "$14", "memory") + +void func_80182490(s32 a0) +{ + u16 out[4]; /* sp+0x10 */ + s16 sv[4]; /* sp+0x18 */ + s16 pos[4]; /* sp+0x20 */ + s32 flag; /* sp+0x28 */ + s16 *p; + + if (*(s16 *)(*(s32 *)(a0 + 0x64) + 0x36) != *(s16 *)(a0 + 0xFE)) { + ((void (*)(void))func_8012C218)(); + return; + } + + if (*(s16 *)(a0 + 0x70) == 1 || *(s16 *)(a0 + 0x70) == 8) { + s32 ang; + s32 t; + ang = (*(u16 *)(a0 + 0xFC) + 0x40) & 0xFFF; + p = *(s16 **)(a0 + 0xCC); + *(s16 *)(a0 + 0xFC) = ang; + t = (func_8004787C(ang) >> 6) + 0xBF; + p[2] = t; + p[1] = t; + p[0] = t; + } + + if (*(s32 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 4) < 0) { + { register s32 *q __asm__("$3"); q = *(s32 **)(a0 + 0x20); + q[1] = q[1] | 0x80000000; } + } else { + __asm__ __volatile__(""); + *(s32 *)(*(s32 *)(a0 + 0x20) + 4) = + *(s32 *)(*(s32 *)(a0 + 0x20) + 4) & 0x7FFFFFFF; + } + + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x18) = + *(u16 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x18); + + if (*(s16 *)(*(s32 *)(a0 + 0x64) + 0x70) < 8) { + *(s16 *)(a0 + 0x108) = (*(u16 *)(a0 + 0x108) + 0x40) & 0xFFF; + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) & 0xFFF; + *(u16 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x12) = + *(u16 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x12) & 0xFFF; + + flag = *(s16 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x12) - + *(s16 *)(*(s32 *)(a0 + 0x20) + 0x12); + if (flag > 0x800) { + flag = flag - 0x1000; + } + if (flag < -0x800) { + flag = flag + 0x1000; + } + if (flag > 0x200) { + s32 t = *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) - 0x200; + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = t + flag; + } else if (flag < -0x200) { + s32 t = *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) + 0x200; + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = t + flag; + } else { + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) + (flag / 16); + } + + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) + + (func_8004787C(*(s16 *)(a0 + 0x108)) >> 6); + + func_80049CAC(*(s32 *)(a0 + 0x20) + 0x10, *(s32 *)(a0 + 0x20) + 0x34); + SRM_80186B78((s32 *)(*(s32 *)(a0 + 0x20) + 0x34)); + STM_80186B78((s32 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x34)); + + p = *(s16 **)(a0 + 0xD0); + sv[0] = 0; + sv[1] = 0; + sv[2] = (p[2] * *(s16 *)(*(s32 *)(a0 + 0x20) + 0x18)) >> 12; + RotTransSV(sv, out, &flag); + + *(s16 *)(a0 + 6) = out[0]; + *(s16 *)(a0 + 0xA) = out[1]; + *(s16 *)(a0 + 0xE) = out[2]; + out[1] = out[1] - 0x40; + + pos[0] = *(u16 *)(a0 + 6); + pos[1] = *(u16 *)(a0 + 0xA) + 0x10; + pos[2] = *(u16 *)(a0 + 0xE); + flag = func_8012CEB0((s32)out, (s32)pos, 1); + if (flag & 0x1000) { + return; + } + if (flag != 0) { + s32 d; + s32 t = pos[1] - 0x10; + d = *(s16 *)(a0 + 0xA) - t; + if (d < 5) { + return; + } + if (d > 0x40) { + d = 0x40; + } + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) + (d << 4); + + func_80049CAC(*(s32 *)(a0 + 0x20) + 0x10, *(s32 *)(a0 + 0x20) + 0x34); + SRM_80186B78((s32 *)(*(s32 *)(a0 + 0x20) + 0x34)); + STM_80186B78((s32 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x34)); + + p = *(s16 **)(a0 + 0xD0); + sv[0] = 0; + sv[1] = 0; + sv[2] = (p[2] * *(s16 *)(*(s32 *)(a0 + 0x20) + 0x18)) >> 12; + RotTransSV(sv, out, &flag); + + *(s16 *)(a0 + 6) = out[0]; + *(s16 *)(a0 + 0xA) = out[1]; + *(s16 *)(a0 + 0xE) = out[2]; + } else { + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) - 0x80; + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) & 0xFFF; + if ((u32)(*(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) - 0x801) < 0x3FF) { + *(s16 *)(*(s32 *)(a0 + 0x20) + 0x10) = 0xC00; + } + } + } else { + s32 ang; + s32 ang2; + + ang = (*(u16 *)(a0 + 0x102) + *(u16 *)(a0 + 0x106)) & 0xFFF; + *(s16 *)(a0 + 0x102) = ang; + *(s16 *)(*(s32 *)(a0 + 0x20) + 0x10) = func_80047948(ang) >> 6; + + ang2 = (*(u16 *)(a0 + 0x104) + *(u16 *)(a0 + 0x100)) & 0xFFF; + *(s16 *)(a0 + 0x104) = ang2; + *(s16 *)(*(s32 *)(a0 + 0x20) + 0x14) = func_80047948(ang2) >> 6; + + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) + 0xC00; + + func_80049CAC(*(s32 *)(a0 + 0x20) + 0x10, *(s32 *)(a0 + 0x20) + 0x34); + SRM_80186B78((s32 *)(*(s32 *)(a0 + 0x20) + 0x34)); + STM_80186B78((s32 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x34)); + + p = *(s16 **)(a0 + 0xD0); + sv[0] = 0; + sv[1] = 0; + sv[2] = (p[2] * *(s16 *)(*(s32 *)(a0 + 0x20) + 0x18)) >> 12; + RotTransSV(sv, out, &flag); + + *(s16 *)(a0 + 6) = out[0]; + *(s16 *)(a0 + 0xA) = out[1]; + *(s16 *)(a0 + 0xE) = out[2]; + } + { s32 pad[2]; } /* LEVER 1: frame pad. INNER-BLOCK + LAST is load-bearing -- + a function-scope decl takes 0x28 and evicts flag to 0x30 */ +} + INCLUDE_ASM("asm/ov_SC03_111/nonmatchings/ov_SC03_111_jr_8017EC58", func_80182A98); diff --git a/src/ov_SC03_112/ov_SC03_112_jr_8017C294.c b/src/ov_SC03_112/ov_SC03_112_jr_8017C294.c index ef607744c..6b84dde24 100644 --- a/src/ov_SC03_112/ov_SC03_112_jr_8017C294.c +++ b/src/ov_SC03_112/ov_SC03_112_jr_8017C294.c @@ -4188,7 +4188,189 @@ INCLUDE_ASM("asm/ov_SC03_112/nonmatchings/ov_SC03_112_jr_8017C294", func_80182B2 INCLUDE_ASM("asm/ov_SC03_112/nonmatchings/ov_SC03_112_jr_8017C294", func_80182BF8); -INCLUDE_ASM("asm/ov_SC03_112/nonmatchings/ov_SC03_112_jr_8017C294", func_801833A4); +extern s32 func_8004787C(s32 a0); +extern s32 func_80047948(s32 a0); +extern void func_80049CAC(s32 a0, s32 a1); +extern void func_8012C218(void *a0); +extern s32 func_8012CEB0(s32 a0, s32 a1, s32 a2); +#define SRM_80186B78(r0) __asm__ __volatile__( \ + "lw $12, 0(%0)\n" \ + "lw $13, 4(%0)\n" \ + "ctc2 $12, $0\n" \ + "ctc2 $13, $1\n" \ + "lw $12, 8(%0)\n" \ + "lw $13, 12(%0)\n" \ + "lw $14, 16(%0)\n" \ + "ctc2 $12, $2\n" \ + "ctc2 $13, $3\n" \ + "ctc2 $14, $4\n" \ + : : "r"(r0) : "$12", "$13", "$14", "memory") +#define STM_80186B78(r0) __asm__ __volatile__( \ + "lw $12, 20(%0)\n" \ + "lw $13, 24(%0)\n" \ + "ctc2 $12, $5\n" \ + "lw $14, 28(%0)\n" \ + "ctc2 $13, $6\n" \ + "ctc2 $14, $7\n" \ + : : "r"(r0) : "$12", "$13", "$14", "memory") + +void func_801833A4(s32 a0) +{ + u16 out[4]; /* sp+0x10 */ + s16 sv[4]; /* sp+0x18 */ + s16 pos[4]; /* sp+0x20 */ + s32 flag; /* sp+0x28 */ + s16 *p; + + if (*(s16 *)(*(s32 *)(a0 + 0x64) + 0x36) != *(s16 *)(a0 + 0xFE)) { + ((void (*)(void))func_8012C218)(); + return; + } + + if (*(s16 *)(a0 + 0x70) == 1 || *(s16 *)(a0 + 0x70) == 8) { + s32 ang; + s32 t; + ang = (*(u16 *)(a0 + 0xFC) + 0x40) & 0xFFF; + p = *(s16 **)(a0 + 0xCC); + *(s16 *)(a0 + 0xFC) = ang; + t = (func_8004787C(ang) >> 6) + 0xBF; + p[2] = t; + p[1] = t; + p[0] = t; + } + + if (*(s32 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 4) < 0) { + { register s32 *q __asm__("$3"); q = *(s32 **)(a0 + 0x20); + q[1] = q[1] | 0x80000000; } + } else { + __asm__ __volatile__(""); + *(s32 *)(*(s32 *)(a0 + 0x20) + 4) = + *(s32 *)(*(s32 *)(a0 + 0x20) + 4) & 0x7FFFFFFF; + } + + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x18) = + *(u16 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x18); + + if (*(s16 *)(*(s32 *)(a0 + 0x64) + 0x70) < 8) { + *(s16 *)(a0 + 0x108) = (*(u16 *)(a0 + 0x108) + 0x40) & 0xFFF; + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) & 0xFFF; + *(u16 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x12) = + *(u16 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x12) & 0xFFF; + + flag = *(s16 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x12) - + *(s16 *)(*(s32 *)(a0 + 0x20) + 0x12); + if (flag > 0x800) { + flag = flag - 0x1000; + } + if (flag < -0x800) { + flag = flag + 0x1000; + } + if (flag > 0x200) { + s32 t = *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) - 0x200; + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = t + flag; + } else if (flag < -0x200) { + s32 t = *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) + 0x200; + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = t + flag; + } else { + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) + (flag / 16); + } + + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) + + (func_8004787C(*(s16 *)(a0 + 0x108)) >> 6); + + func_80049CAC(*(s32 *)(a0 + 0x20) + 0x10, *(s32 *)(a0 + 0x20) + 0x34); + SRM_80186B78((s32 *)(*(s32 *)(a0 + 0x20) + 0x34)); + STM_80186B78((s32 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x34)); + + p = *(s16 **)(a0 + 0xD0); + sv[0] = 0; + sv[1] = 0; + sv[2] = (p[2] * *(s16 *)(*(s32 *)(a0 + 0x20) + 0x18)) >> 12; + RotTransSV(sv, out, &flag); + + *(s16 *)(a0 + 6) = out[0]; + *(s16 *)(a0 + 0xA) = out[1]; + *(s16 *)(a0 + 0xE) = out[2]; + out[1] = out[1] - 0x40; + + pos[0] = *(u16 *)(a0 + 6); + pos[1] = *(u16 *)(a0 + 0xA) + 0x10; + pos[2] = *(u16 *)(a0 + 0xE); + flag = func_8012CEB0((s32)out, (s32)pos, 1); + if (flag & 0x1000) { + return; + } + if (flag != 0) { + s32 d; + s32 t = pos[1] - 0x10; + d = *(s16 *)(a0 + 0xA) - t; + if (d < 5) { + return; + } + if (d > 0x40) { + d = 0x40; + } + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) + (d << 4); + + func_80049CAC(*(s32 *)(a0 + 0x20) + 0x10, *(s32 *)(a0 + 0x20) + 0x34); + SRM_80186B78((s32 *)(*(s32 *)(a0 + 0x20) + 0x34)); + STM_80186B78((s32 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x34)); + + p = *(s16 **)(a0 + 0xD0); + sv[0] = 0; + sv[1] = 0; + sv[2] = (p[2] * *(s16 *)(*(s32 *)(a0 + 0x20) + 0x18)) >> 12; + RotTransSV(sv, out, &flag); + + *(s16 *)(a0 + 6) = out[0]; + *(s16 *)(a0 + 0xA) = out[1]; + *(s16 *)(a0 + 0xE) = out[2]; + } else { + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) - 0x80; + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) & 0xFFF; + if ((u32)(*(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) - 0x801) < 0x3FF) { + *(s16 *)(*(s32 *)(a0 + 0x20) + 0x10) = 0xC00; + } + } + } else { + s32 ang; + s32 ang2; + + ang = (*(u16 *)(a0 + 0x102) + *(u16 *)(a0 + 0x106)) & 0xFFF; + *(s16 *)(a0 + 0x102) = ang; + *(s16 *)(*(s32 *)(a0 + 0x20) + 0x10) = func_80047948(ang) >> 6; + + ang2 = (*(u16 *)(a0 + 0x104) + *(u16 *)(a0 + 0x100)) & 0xFFF; + *(s16 *)(a0 + 0x104) = ang2; + *(s16 *)(*(s32 *)(a0 + 0x20) + 0x14) = func_80047948(ang2) >> 6; + + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) + 0xC00; + + func_80049CAC(*(s32 *)(a0 + 0x20) + 0x10, *(s32 *)(a0 + 0x20) + 0x34); + SRM_80186B78((s32 *)(*(s32 *)(a0 + 0x20) + 0x34)); + STM_80186B78((s32 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x34)); + + p = *(s16 **)(a0 + 0xD0); + sv[0] = 0; + sv[1] = 0; + sv[2] = (p[2] * *(s16 *)(*(s32 *)(a0 + 0x20) + 0x18)) >> 12; + RotTransSV(sv, out, &flag); + + *(s16 *)(a0 + 6) = out[0]; + *(s16 *)(a0 + 0xA) = out[1]; + *(s16 *)(a0 + 0xE) = out[2]; + } + { s32 pad[2]; } /* LEVER 1: frame pad. INNER-BLOCK + LAST is load-bearing -- + a function-scope decl takes 0x28 and evicts flag to 0x30 */ +} + INCLUDE_ASM("asm/ov_SC03_112/nonmatchings/ov_SC03_112_jr_8017C294", func_801839AC); diff --git a/src/ov_SC03_113/ov_SC03_113_jr_8017C294.c b/src/ov_SC03_113/ov_SC03_113_jr_8017C294.c index 83fe55e65..f3a5368d0 100644 --- a/src/ov_SC03_113/ov_SC03_113_jr_8017C294.c +++ b/src/ov_SC03_113/ov_SC03_113_jr_8017C294.c @@ -4658,7 +4658,189 @@ void func_80180910(void *a0) { INCLUDE_ASM("asm/ov_SC03_113/nonmatchings/ov_SC03_113_jr_8017C294", func_8018097C); -INCLUDE_ASM("asm/ov_SC03_113/nonmatchings/ov_SC03_113_jr_8017C294", func_80181128); +extern s32 func_8004787C(s32 a0); +extern s32 func_80047948(s32 a0); +extern void func_80049CAC(s32 a0, s32 a1); +extern void func_8012C218(void *a0); +extern s32 func_8012CEB0(s32 a0, s32 a1, s32 a2); +#define SRM_80186B78(r0) __asm__ __volatile__( \ + "lw $12, 0(%0)\n" \ + "lw $13, 4(%0)\n" \ + "ctc2 $12, $0\n" \ + "ctc2 $13, $1\n" \ + "lw $12, 8(%0)\n" \ + "lw $13, 12(%0)\n" \ + "lw $14, 16(%0)\n" \ + "ctc2 $12, $2\n" \ + "ctc2 $13, $3\n" \ + "ctc2 $14, $4\n" \ + : : "r"(r0) : "$12", "$13", "$14", "memory") +#define STM_80186B78(r0) __asm__ __volatile__( \ + "lw $12, 20(%0)\n" \ + "lw $13, 24(%0)\n" \ + "ctc2 $12, $5\n" \ + "lw $14, 28(%0)\n" \ + "ctc2 $13, $6\n" \ + "ctc2 $14, $7\n" \ + : : "r"(r0) : "$12", "$13", "$14", "memory") + +void func_80181128(s32 a0) +{ + u16 out[4]; /* sp+0x10 */ + s16 sv[4]; /* sp+0x18 */ + s16 pos[4]; /* sp+0x20 */ + s32 flag; /* sp+0x28 */ + s16 *p; + + if (*(s16 *)(*(s32 *)(a0 + 0x64) + 0x36) != *(s16 *)(a0 + 0xFE)) { + ((void (*)(void))func_8012C218)(); + return; + } + + if (*(s16 *)(a0 + 0x70) == 1 || *(s16 *)(a0 + 0x70) == 8) { + s32 ang; + s32 t; + ang = (*(u16 *)(a0 + 0xFC) + 0x40) & 0xFFF; + p = *(s16 **)(a0 + 0xCC); + *(s16 *)(a0 + 0xFC) = ang; + t = (func_8004787C(ang) >> 6) + 0xBF; + p[2] = t; + p[1] = t; + p[0] = t; + } + + if (*(s32 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 4) < 0) { + { register s32 *q __asm__("$3"); q = *(s32 **)(a0 + 0x20); + q[1] = q[1] | 0x80000000; } + } else { + __asm__ __volatile__(""); + *(s32 *)(*(s32 *)(a0 + 0x20) + 4) = + *(s32 *)(*(s32 *)(a0 + 0x20) + 4) & 0x7FFFFFFF; + } + + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x18) = + *(u16 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x18); + + if (*(s16 *)(*(s32 *)(a0 + 0x64) + 0x70) < 8) { + *(s16 *)(a0 + 0x108) = (*(u16 *)(a0 + 0x108) + 0x40) & 0xFFF; + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) & 0xFFF; + *(u16 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x12) = + *(u16 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x12) & 0xFFF; + + flag = *(s16 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x12) - + *(s16 *)(*(s32 *)(a0 + 0x20) + 0x12); + if (flag > 0x800) { + flag = flag - 0x1000; + } + if (flag < -0x800) { + flag = flag + 0x1000; + } + if (flag > 0x200) { + s32 t = *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) - 0x200; + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = t + flag; + } else if (flag < -0x200) { + s32 t = *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) + 0x200; + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = t + flag; + } else { + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) + (flag / 16); + } + + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) + + (func_8004787C(*(s16 *)(a0 + 0x108)) >> 6); + + func_80049CAC(*(s32 *)(a0 + 0x20) + 0x10, *(s32 *)(a0 + 0x20) + 0x34); + SRM_80186B78((s32 *)(*(s32 *)(a0 + 0x20) + 0x34)); + STM_80186B78((s32 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x34)); + + p = *(s16 **)(a0 + 0xD0); + sv[0] = 0; + sv[1] = 0; + sv[2] = (p[2] * *(s16 *)(*(s32 *)(a0 + 0x20) + 0x18)) >> 12; + RotTransSV(sv, out, &flag); + + *(s16 *)(a0 + 6) = out[0]; + *(s16 *)(a0 + 0xA) = out[1]; + *(s16 *)(a0 + 0xE) = out[2]; + out[1] = out[1] - 0x40; + + pos[0] = *(u16 *)(a0 + 6); + pos[1] = *(u16 *)(a0 + 0xA) + 0x10; + pos[2] = *(u16 *)(a0 + 0xE); + flag = func_8012CEB0((s32)out, (s32)pos, 1); + if (flag & 0x1000) { + return; + } + if (flag != 0) { + s32 d; + s32 t = pos[1] - 0x10; + d = *(s16 *)(a0 + 0xA) - t; + if (d < 5) { + return; + } + if (d > 0x40) { + d = 0x40; + } + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) + (d << 4); + + func_80049CAC(*(s32 *)(a0 + 0x20) + 0x10, *(s32 *)(a0 + 0x20) + 0x34); + SRM_80186B78((s32 *)(*(s32 *)(a0 + 0x20) + 0x34)); + STM_80186B78((s32 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x34)); + + p = *(s16 **)(a0 + 0xD0); + sv[0] = 0; + sv[1] = 0; + sv[2] = (p[2] * *(s16 *)(*(s32 *)(a0 + 0x20) + 0x18)) >> 12; + RotTransSV(sv, out, &flag); + + *(s16 *)(a0 + 6) = out[0]; + *(s16 *)(a0 + 0xA) = out[1]; + *(s16 *)(a0 + 0xE) = out[2]; + } else { + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) - 0x80; + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) & 0xFFF; + if ((u32)(*(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) - 0x801) < 0x3FF) { + *(s16 *)(*(s32 *)(a0 + 0x20) + 0x10) = 0xC00; + } + } + } else { + s32 ang; + s32 ang2; + + ang = (*(u16 *)(a0 + 0x102) + *(u16 *)(a0 + 0x106)) & 0xFFF; + *(s16 *)(a0 + 0x102) = ang; + *(s16 *)(*(s32 *)(a0 + 0x20) + 0x10) = func_80047948(ang) >> 6; + + ang2 = (*(u16 *)(a0 + 0x104) + *(u16 *)(a0 + 0x100)) & 0xFFF; + *(s16 *)(a0 + 0x104) = ang2; + *(s16 *)(*(s32 *)(a0 + 0x20) + 0x14) = func_80047948(ang2) >> 6; + + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) + 0xC00; + + func_80049CAC(*(s32 *)(a0 + 0x20) + 0x10, *(s32 *)(a0 + 0x20) + 0x34); + SRM_80186B78((s32 *)(*(s32 *)(a0 + 0x20) + 0x34)); + STM_80186B78((s32 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x34)); + + p = *(s16 **)(a0 + 0xD0); + sv[0] = 0; + sv[1] = 0; + sv[2] = (p[2] * *(s16 *)(*(s32 *)(a0 + 0x20) + 0x18)) >> 12; + RotTransSV(sv, out, &flag); + + *(s16 *)(a0 + 6) = out[0]; + *(s16 *)(a0 + 0xA) = out[1]; + *(s16 *)(a0 + 0xE) = out[2]; + } + { s32 pad[2]; } /* LEVER 1: frame pad. INNER-BLOCK + LAST is load-bearing -- + a function-scope decl takes 0x28 and evicts flag to 0x30 */ +} + INCLUDE_ASM("asm/ov_SC03_113/nonmatchings/ov_SC03_113_jr_8017C294", func_80181730); diff --git a/src/ov_SC03_114/ov_SC03_114_jr_8017BEBC.c b/src/ov_SC03_114/ov_SC03_114_jr_8017BEBC.c index b889be9cf..0b83b270c 100644 --- a/src/ov_SC03_114/ov_SC03_114_jr_8017BEBC.c +++ b/src/ov_SC03_114/ov_SC03_114_jr_8017BEBC.c @@ -3382,7 +3382,41 @@ INCLUDE_ASM("asm/ov_SC03_114/nonmatchings/ov_SC03_114_jr_8017BEBC", func_8017E01 INCLUDE_ASM("asm/ov_SC03_114/nonmatchings/ov_SC03_114_jr_8017BEBC", func_8017E070); -INCLUDE_ASM("asm/ov_SC03_114/nonmatchings/ov_SC03_114_jr_8017BEBC", func_8017E170); +extern void func_8017E270(void *a0); +extern void func_8017E2EC(void *a0); +extern void func_8012931C(struct vec *a0); +extern void func_801292C8(u8 *a0); + +void func_8017E170(void *a0) { + if (*(u16 *)((s32)a0 + 0x2) == 0) { + func_8017E270(a0); + return; + } + + if (*(s32 *)((s32)a0 + 0x1C) != 0) { + *(s32 *)((s32)a0 + 0x1C) -= 1; + func_8012931C((struct vec *)a0); + + if (*(s16 *)((s32)a0 + 0x32) == 0) { + u16 t = *(u16 *)((s32)a0 + 0xA) + 0x1000; + if (t >= 0x1001) { + func_801292C8((u8 *)a0); + return; + } + } + } else { + func_801292C8((u8 *)a0); + return; + } + + *(s32 *)((s32)a0 + 0x14) += *(s32 *)((s32)a0 + 0x34); + *(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0x14) += *(u16 *)((s32)a0 + 0x30); + *(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0x8) = *(u16 *)((s32)a0 + 0x6); + *(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0xA) = *(u16 *)((s32)a0 + 0xA); + *(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0xC) = *(u16 *)((s32)a0 + 0xE); + func_8017E2EC((void *)*(s32 *)((s32)a0 + 0x20)); +} + INCLUDE_ASM("asm/ov_SC03_114/nonmatchings/ov_SC03_114_jr_8017BEBC", func_8017E270); diff --git a/src/ov_SC03_117/ov_SC03_117_jr_8017BEBC.c b/src/ov_SC03_117/ov_SC03_117_jr_8017BEBC.c index 43c71914f..61af8c2f5 100644 --- a/src/ov_SC03_117/ov_SC03_117_jr_8017BEBC.c +++ b/src/ov_SC03_117/ov_SC03_117_jr_8017BEBC.c @@ -4576,7 +4576,189 @@ INCLUDE_ASM("asm/ov_SC03_117/nonmatchings/ov_SC03_117_jr_8017BEBC", func_80181A3 INCLUDE_ASM("asm/ov_SC03_117/nonmatchings/ov_SC03_117_jr_8017BEBC", func_80181C80); -INCLUDE_ASM("asm/ov_SC03_117/nonmatchings/ov_SC03_117_jr_8017BEBC", func_8018242C); +extern s32 func_8004787C(s32 a0); +extern s32 func_80047948(s32 a0); +extern void func_80049CAC(s32 a0, s32 a1); +extern void func_8012C218(void *a0); +extern s32 func_8012CEB0(s32 a0, s32 a1, s32 a2); +#define SRM_80186B78(r0) __asm__ __volatile__( \ + "lw $12, 0(%0)\n" \ + "lw $13, 4(%0)\n" \ + "ctc2 $12, $0\n" \ + "ctc2 $13, $1\n" \ + "lw $12, 8(%0)\n" \ + "lw $13, 12(%0)\n" \ + "lw $14, 16(%0)\n" \ + "ctc2 $12, $2\n" \ + "ctc2 $13, $3\n" \ + "ctc2 $14, $4\n" \ + : : "r"(r0) : "$12", "$13", "$14", "memory") +#define STM_80186B78(r0) __asm__ __volatile__( \ + "lw $12, 20(%0)\n" \ + "lw $13, 24(%0)\n" \ + "ctc2 $12, $5\n" \ + "lw $14, 28(%0)\n" \ + "ctc2 $13, $6\n" \ + "ctc2 $14, $7\n" \ + : : "r"(r0) : "$12", "$13", "$14", "memory") + +void func_8018242C(s32 a0) +{ + u16 out[4]; /* sp+0x10 */ + s16 sv[4]; /* sp+0x18 */ + s16 pos[4]; /* sp+0x20 */ + s32 flag; /* sp+0x28 */ + s16 *p; + + if (*(s16 *)(*(s32 *)(a0 + 0x64) + 0x36) != *(s16 *)(a0 + 0xFE)) { + ((void (*)(void))func_8012C218)(); + return; + } + + if (*(s16 *)(a0 + 0x70) == 1 || *(s16 *)(a0 + 0x70) == 8) { + s32 ang; + s32 t; + ang = (*(u16 *)(a0 + 0xFC) + 0x40) & 0xFFF; + p = *(s16 **)(a0 + 0xCC); + *(s16 *)(a0 + 0xFC) = ang; + t = (func_8004787C(ang) >> 6) + 0xBF; + p[2] = t; + p[1] = t; + p[0] = t; + } + + if (*(s32 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 4) < 0) { + { register s32 *q __asm__("$3"); q = *(s32 **)(a0 + 0x20); + q[1] = q[1] | 0x80000000; } + } else { + __asm__ __volatile__(""); + *(s32 *)(*(s32 *)(a0 + 0x20) + 4) = + *(s32 *)(*(s32 *)(a0 + 0x20) + 4) & 0x7FFFFFFF; + } + + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x18) = + *(u16 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x18); + + if (*(s16 *)(*(s32 *)(a0 + 0x64) + 0x70) < 8) { + *(s16 *)(a0 + 0x108) = (*(u16 *)(a0 + 0x108) + 0x40) & 0xFFF; + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) & 0xFFF; + *(u16 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x12) = + *(u16 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x12) & 0xFFF; + + flag = *(s16 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x12) - + *(s16 *)(*(s32 *)(a0 + 0x20) + 0x12); + if (flag > 0x800) { + flag = flag - 0x1000; + } + if (flag < -0x800) { + flag = flag + 0x1000; + } + if (flag > 0x200) { + s32 t = *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) - 0x200; + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = t + flag; + } else if (flag < -0x200) { + s32 t = *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) + 0x200; + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = t + flag; + } else { + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) + (flag / 16); + } + + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) + + (func_8004787C(*(s16 *)(a0 + 0x108)) >> 6); + + func_80049CAC(*(s32 *)(a0 + 0x20) + 0x10, *(s32 *)(a0 + 0x20) + 0x34); + SRM_80186B78((s32 *)(*(s32 *)(a0 + 0x20) + 0x34)); + STM_80186B78((s32 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x34)); + + p = *(s16 **)(a0 + 0xD0); + sv[0] = 0; + sv[1] = 0; + sv[2] = (p[2] * *(s16 *)(*(s32 *)(a0 + 0x20) + 0x18)) >> 12; + RotTransSV(sv, out, &flag); + + *(s16 *)(a0 + 6) = out[0]; + *(s16 *)(a0 + 0xA) = out[1]; + *(s16 *)(a0 + 0xE) = out[2]; + out[1] = out[1] - 0x40; + + pos[0] = *(u16 *)(a0 + 6); + pos[1] = *(u16 *)(a0 + 0xA) + 0x10; + pos[2] = *(u16 *)(a0 + 0xE); + flag = func_8012CEB0((s32)out, (s32)pos, 1); + if (flag & 0x1000) { + return; + } + if (flag != 0) { + s32 d; + s32 t = pos[1] - 0x10; + d = *(s16 *)(a0 + 0xA) - t; + if (d < 5) { + return; + } + if (d > 0x40) { + d = 0x40; + } + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) + (d << 4); + + func_80049CAC(*(s32 *)(a0 + 0x20) + 0x10, *(s32 *)(a0 + 0x20) + 0x34); + SRM_80186B78((s32 *)(*(s32 *)(a0 + 0x20) + 0x34)); + STM_80186B78((s32 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x34)); + + p = *(s16 **)(a0 + 0xD0); + sv[0] = 0; + sv[1] = 0; + sv[2] = (p[2] * *(s16 *)(*(s32 *)(a0 + 0x20) + 0x18)) >> 12; + RotTransSV(sv, out, &flag); + + *(s16 *)(a0 + 6) = out[0]; + *(s16 *)(a0 + 0xA) = out[1]; + *(s16 *)(a0 + 0xE) = out[2]; + } else { + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) - 0x80; + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) & 0xFFF; + if ((u32)(*(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) - 0x801) < 0x3FF) { + *(s16 *)(*(s32 *)(a0 + 0x20) + 0x10) = 0xC00; + } + } + } else { + s32 ang; + s32 ang2; + + ang = (*(u16 *)(a0 + 0x102) + *(u16 *)(a0 + 0x106)) & 0xFFF; + *(s16 *)(a0 + 0x102) = ang; + *(s16 *)(*(s32 *)(a0 + 0x20) + 0x10) = func_80047948(ang) >> 6; + + ang2 = (*(u16 *)(a0 + 0x104) + *(u16 *)(a0 + 0x100)) & 0xFFF; + *(s16 *)(a0 + 0x104) = ang2; + *(s16 *)(*(s32 *)(a0 + 0x20) + 0x14) = func_80047948(ang2) >> 6; + + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) + 0xC00; + + func_80049CAC(*(s32 *)(a0 + 0x20) + 0x10, *(s32 *)(a0 + 0x20) + 0x34); + SRM_80186B78((s32 *)(*(s32 *)(a0 + 0x20) + 0x34)); + STM_80186B78((s32 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x34)); + + p = *(s16 **)(a0 + 0xD0); + sv[0] = 0; + sv[1] = 0; + sv[2] = (p[2] * *(s16 *)(*(s32 *)(a0 + 0x20) + 0x18)) >> 12; + RotTransSV(sv, out, &flag); + + *(s16 *)(a0 + 6) = out[0]; + *(s16 *)(a0 + 0xA) = out[1]; + *(s16 *)(a0 + 0xE) = out[2]; + } + { s32 pad[2]; } /* LEVER 1: frame pad. INNER-BLOCK + LAST is load-bearing -- + a function-scope decl takes 0x28 and evicts flag to 0x30 */ +} + INCLUDE_ASM("asm/ov_SC03_117/nonmatchings/ov_SC03_117_jr_8017BEBC", func_80182A34); diff --git a/src/ov_SC03_118/ov_SC03_118_jr_8017FB84.c b/src/ov_SC03_118/ov_SC03_118_jr_8017FB84.c index 281a5c54f..84bd1238d 100644 --- a/src/ov_SC03_118/ov_SC03_118_jr_8017FB84.c +++ b/src/ov_SC03_118/ov_SC03_118_jr_8017FB84.c @@ -3210,7 +3210,370 @@ void func_8017FB84(s32 arg0) -INCLUDE_ASM("asm/ov_SC03_118/nonmatchings/ov_SC03_118_jr_8017FB84", func_80180A64); +#define gte_ldv0(r0) __asm__ __volatile__( \ + "lwc2 $0, 0(%0)\n" \ + "lwc2 $1, 4(%0)\n" \ + : : "r"(r0) : "memory") +#define gte_ldv0(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 )" \ + : \ + : "r"( r0 ) ) +#define gte_ldv3c(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 );" \ + "lwc2 $2, 8( %0 );" \ + "lwc2 $3, 12( %0 );" \ + "lwc2 $4, 16( %0 );" \ + "lwc2 $5, 20( %0 )" \ + : \ + : "r"( r0 ) ) +#define gte_rtps() __asm__ volatile ("nop;nop;rtps") +#define gte_rtpt() __asm__ volatile ("nop;nop;rtpt") +#define gte_nclip() __asm__ volatile ("nop;nop;nclip") +#define gte_stsxy(r0) __asm__ volatile ( \ + "swc2 $14, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) +#define gte_stsxy3(r0, r1, r2) __asm__ volatile ( \ + "swc2 $12, 0( %0 );" \ + "swc2 $13, 0( %1 );" \ + "swc2 $14, 0( %2 )" \ + : \ + : "r"( r0 ), "r"( r1 ), "r"( r2 ) \ + : "memory" ) +#define gte_stsxy3c(r0) __asm__ volatile ( \ + "swc2 $12, 0( %0 );" \ + "swc2 $13, 4( %0 );" \ + "swc2 $14, 8( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) +#define gte_stsxy3_ft3(r0) __asm__ volatile ( \ + "swc2 $12, 8( %0 );" \ + "swc2 $13, 16( %0 );" \ + "swc2 $14, 24( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) +#define gte_stsz3(r0, r1, r2) __asm__ volatile ( \ + "swc2 $17, 0( %0 );" \ + "swc2 $18, 0( %1 );" \ + "swc2 $19, 0( %2 )" \ + : \ + : "r"( r0 ), "r"( r1 ), "r"( r2 ) \ + : "memory" ) +#define gte_stsz4(r0, r1, r2, r3) __asm__ volatile ( \ + "swc2 $16, 0( %0 );" \ + "swc2 $17, 0( %1 );" \ + "swc2 $18, 0( %2 );" \ + "swc2 $19, 0( %3 )" \ + : \ + : "r"( r0 ), "r"( r1 ), "r"( r2 ), "r"( r3 ) ) +#define gte_stszotz(r0) __asm__ volatile ( \ + "mfc2 $12, $19;" \ + "nop;" \ + "sra $12, $12, 2;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) +#define gte_stflg(r0) __asm__ volatile ( \ + "cfc2 $12, $31;" \ + "nop;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) +#define gte_stopz(r0) __asm__ volatile ( \ + "swc2 $24, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + + +void func_80180A64(s32 arg0, s32 arg1, s32 arg2, s32 arg3) +{ + typedef struct { u32 w0, w1, w2; } Prim_80180A64; + /* vy UNSIGNED: the `+=` reads it with lhu, not lh. */ + typedef struct { s16 vx; u16 vy; s16 vz, pad; } SVec_80180A64; + + extern s32 func_800491EC(void); + extern void func_800547D8(s32, MATRIX2 *); + extern void func_80052E38(MATRIX2 *); + extern u8 *D_800A5E60; + extern u8 D_800A6610[]; + extern u16 D_8018DAB4[]; + + DVECTOR2 tmpxy[4]; /* sp+0x10 */ + SVECTOR2 box[8]; /* sp+0x20 */ + SVECTOR2 sxy[8]; /* sp+0x60 */ + SVec_80180A64 v[3]; /* sp+0xA0 */ + SVec_80180A64 vdv; /* sp+0xB8 */ + MATRIX2 mtx; /* sp+0xC0 */ + struct { long otz, flag, opz, sz0, sz1, sz2, sz3; } g; /* sp+0xE0 */ + + s32 lim; /* spill 0x100 */ + u32 ot; /* spill 0x108 */ + s32 nparts; /* spill 0x110 */ + s32 j; + u32 nprim; + u32 i; + Part *part; /* spill 0x118 */ + SVec_80180A64 *vp; + Prim_80180A64 *prim; + u8 *pkt; + u8 *vtx; + u8 *va, *vb, *vc, *vd; + u32 w; + u32 m24; + s32 code; /* SIGNED: the switch tree uses slti, not sltiu */ + u32 wx, wy, wz; + s32 rot; + s32 zoff; + s32 xa32, xb32, t32; + s32 xmn1, xmx1, xmn2, xmx2; + s32 mnc, mxc; + s16 my, mny, mx, mn; + + if (*(s32 *)arg0 == 0) { + lim = func_800491EC() + *(s32 *)(arg0 + 0x64); + func_800547D8(arg0 + 0x10, &mtx); + func_80052E38(&mtx); + pkt = D_800A5E60; + + nparts = *(s32 *)(arg1 + 8); + ot = (u32)&D_800A6610[(*(u16 *)&D_800B9A02) << 14]; + rot = arg2; + zoff = arg3; + vtx = *(u8 **)(arg1 + 0x10); + part = (Part *)(arg1 + 0x14); + + for (j = 0; j < nparts; j++, part++) { + wx = part->xx; + mn = wx; + mx = wx >> 16; + wy = part->yy; + mny = wy + zoff; + my = (wy >> 16) + zoff; + wz = part->zz; + box[0].vx = mn; box[0].vy = mny; box[0].vz = wz; + box[1].vx = mx; box[1].vy = mny; box[1].vz = wz; + box[2].vx = mn; box[2].vy = mny; box[2].vz = wz >> 16; + box[3].vx = mx; box[3].vy = mny; box[3].vz = wz >> 16; + + gte_ldv3c(&box[0]); + gte_rtpt(); + gte_stsxy3(&sxy[0], &sxy[1], &sxy[2]); + gte_ldv0(&box[3]); + gte_rtps(); + + box[4].vx = mn; box[4].vy = my; box[4].vz = wz; + box[5].vx = mx; box[5].vy = my; box[5].vz = wz; + box[6].vx = mn; box[6].vy = my; box[6].vz = wz >> 16; + box[7].vx = mx; box[7].vy = my; box[7].vz = wz >> 16; + + gte_stsxy(&sxy[3]); + gte_ldv3c(&box[4]); + __asm__ volatile (""); /* §47 live-length slider (carried from the twin) */ + gte_rtpt(); + gte_stsxy3(&sxy[4], &sxy[5], &sxy[6]); + gte_ldv0(&box[7]); + gte_rtps(); + gte_stsxy(&sxy[7]); + gte_stszotz(&g.otz); + + if (lim >= g.otz) { + xa32 = sxy[0].vx; + xb32 = sxy[1].vx; + if (xb32 < xa32) { xmx1 = xa32; xmn1 = xb32; } else { xmn1 = xa32; xmx1 = xb32; } + t32 = sxy[2].vx; + if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32; + t32 = sxy[3].vx; + if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32; + xa32 = sxy[4].vx; + xb32 = sxy[5].vx; + if (xb32 < xa32) { xmx2 = xa32; xmn2 = xb32; } else { xmn2 = xa32; xmx2 = xb32; } + t32 = sxy[6].vx; + if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32; + t32 = sxy[7].vx; + if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32; + mnc = xmn1; + if (xmn2 < xmn1) mnc = xmn2; + mxc = xmx1; + if (mxc < xmx2) mxc = xmx2; + if ((s16)mxc >= -0xA0 && (s16)mnc < 0xA1) { + xa32 = sxy[0].vy; + xb32 = sxy[1].vy; + if (xb32 < xa32) { xmx1 = xa32; xmn1 = xb32; } else { xmn1 = xa32; xmx1 = xb32; } + t32 = sxy[2].vy; + if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32; + t32 = sxy[3].vy; + if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32; + xa32 = sxy[4].vy; + xb32 = sxy[5].vy; + if (xb32 < xa32) { xmx2 = xa32; xmn2 = xb32; } else { xmn2 = xa32; xmx2 = xb32; } + t32 = sxy[6].vy; + if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32; + t32 = sxy[7].vy; + if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32; + mnc = xmn1; + if (xmn2 < xmn1) mnc = xmn2; + mxc = xmx1; + if (mxc < xmx2) mxc = xmx2; + if ((s16)mxc >= -0x6E && (s16)mnc < 0x6F) { + prim = (Prim_80180A64 *)part->prim; + nprim = part->nprim; + for (i = 0; i < nprim; i++, prim++) { + m24 = 0xFFFFFF; + vp = &vdv; + w = prim->w1; + va = vtx + (w & 0xFFFF); + vb = vtx + (w >> 16); + w = prim->w2; + vc = vtx + (w & 0xFFFF); + v[0] = *(SVec_80180A64 *)va; + v[1] = *(SVec_80180A64 *)vb; + v[2] = *(SVec_80180A64 *)vc; + w = w >> 16; + v[0].vy += D_8018DAB4[(v[0].vz + rot) & 0xFF] + zoff; + v[1].vy += D_8018DAB4[(v[1].vz + rot) & 0xFF] + zoff; + v[2].vy += D_8018DAB4[(v[2].vz + rot) & 0xFF] + zoff; + gte_ldv3c(&v[0]); + gte_rtpt(); + gte_stflg(&g.flag); + if (!(g.flag & 0x7F85E000)) { + gte_nclip(); + code = w & 7; + vd = vtx + (w & 0xFFF8); + gte_stopz(&g.opz); + if (g.opz > 0) { + switch (code) { + case 6: + case 7: + gte_stsxy3_ft3(pkt); + gte_stsz3(&g.sz0, &g.sz1, &g.sz2); + if (((PolyFT3 *)pkt)->x0 > ((PolyFT3 *)pkt)->x1) { + mx = ((PolyFT3 *)pkt)->x0; + mn = ((PolyFT3 *)pkt)->x1; + } else { + mn = ((PolyFT3 *)pkt)->x0; + mx = ((PolyFT3 *)pkt)->x1; + } + if (((PolyFT3 *)pkt)->x2 > mx) mx = ((PolyFT3 *)pkt)->x2; + else if (((PolyFT3 *)pkt)->x2 < mn) mn = ((PolyFT3 *)pkt)->x2; + if (mx >= -0xA0 && mn < 0xA1) { + if (((PolyFT3 *)pkt)->y0 > ((PolyFT3 *)pkt)->y1) { + my = ((PolyFT3 *)pkt)->y0; + mny = ((PolyFT3 *)pkt)->y1; + } else { + mny = ((PolyFT3 *)pkt)->y0; + my = ((PolyFT3 *)pkt)->y1; + } + if (((PolyFT3 *)pkt)->y2 > my) my = ((PolyFT3 *)pkt)->y2; + else if (((PolyFT3 *)pkt)->y2 < mny) mny = ((PolyFT3 *)pkt)->y2; + if (my >= -0x6E && mny < 0x6F) { + s32 za; + u32 *otp; + u32 *tp; + if (g.sz0 > g.sz1) { + za = g.sz0; + if (za < g.sz2) za = g.sz2; + } else { + za = g.sz1; + if (za < g.sz2) za = g.sz2; + } + g.opz = za; + if (code == 7) g.opz = za + 0x200; + tp = (u32 *)prim->w0; + ((PolyFT3 *)pkt)->rgbc = tp[0] | 0x2000000; + ((PolyFT3 *)pkt)->uvc0 = tp[1]; + ((PolyFT3 *)pkt)->uvp1 = tp[2]; + ((PolyFT3 *)pkt)->uv2 = tp[3]; + otp = (u32 *)(((g.opz >> 2) << 2) + ot); + *(u32 *)pkt = (*otp & m24) | 0x7000000; + *otp = (*otp & 0xFF000000) | ((u32)pkt & m24); + pkt += 0x28; + } + } + break; + case 2: + case 3: + gte_stsxy3c(&tmpxy[0]); + vdv = *(SVec_80180A64 *)vd; + vdv.vy += D_8018DAB4[(vdv.vz + rot) & 0xFF] + zoff; + gte_ldv0(vp); + gte_rtps(); + if (tmpxy[0].vx > tmpxy[1].vx) { + mx = tmpxy[0].vx; + mn = tmpxy[1].vx; + } else { + mn = tmpxy[0].vx; + mx = tmpxy[1].vx; + } + if (tmpxy[2].vx > mx) mx = tmpxy[2].vx; + else if (tmpxy[2].vx < mn) mn = tmpxy[2].vx; + if (tmpxy[0].vy > tmpxy[1].vy) { + my = tmpxy[0].vy; + mny = tmpxy[1].vy; + } else { + mny = tmpxy[0].vy; + my = tmpxy[1].vy; + } + if (tmpxy[2].vy > my) my = tmpxy[2].vy; + else if (tmpxy[2].vy < mny) mny = tmpxy[2].vy; + gte_stflg(&g.flag); + if (!(g.flag & 0x7F85E000)) { + gte_stsz4(&g.sz0, &g.sz1, &g.sz2, &g.sz3); + gte_stsxy((long *)&((PolyFT4 *)pkt)->x3); + if (((PolyFT4 *)pkt)->x3 < mn) mn = ((PolyFT4 *)pkt)->x3; + else if (mx < ((PolyFT4 *)pkt)->x3) mx = ((PolyFT4 *)pkt)->x3; + if (mx >= -0xA0 && mn < 0xA1) { + if (((PolyFT4 *)pkt)->y3 < mny) mny = ((PolyFT4 *)pkt)->y3; + else if (my < ((PolyFT4 *)pkt)->y3) my = ((PolyFT4 *)pkt)->y3; + if (my >= -0x6E && mny < 0x6F) { + s32 za, zb; + u32 *otp; + u32 *tp; + u32 uvw; + zb = g.sz2; + if (zb < g.sz3) zb = g.sz3; + za = g.sz0; + if (za < g.sz1) za = g.sz1; + if (za < zb) za = zb; + g.opz = za; + if (code == 3) g.opz = za + 0x200; + *(u32 *)&((PolyFT4 *)pkt)->x0 = *(u32 *)&tmpxy[0]; + *(u32 *)&((PolyFT4 *)pkt)->x1 = *(u32 *)&tmpxy[1]; + *(u32 *)&((PolyFT4 *)pkt)->x2 = *(u32 *)&tmpxy[2]; + tp = (u32 *)prim->w0; + ((PolyFT4 *)pkt)->rgbc = tp[0] | 0x2000000; + ((PolyFT4 *)pkt)->uvc0 = tp[1]; + ((PolyFT4 *)pkt)->uvp1 = tp[2]; + uvw = tp[3]; + ((PolyFT4 *)pkt)->uv2 = uvw; + ((PolyFT4 *)pkt)->uv3 = uvw >> 16; + otp = (u32 *)(((g.opz >> 2) << 2) + ot); + *(u32 *)pkt = (*otp & m24) | 0x9000000; + *otp = (*otp & 0xFF000000) | ((u32)pkt & m24); + pkt += 0x28; + } + } + } + break; + } + } + } + } + } + } + } + } + D_800A5E60 = pkt; + } +} + extern void (*D_8018DD98[])(void); @@ -4834,7 +5197,256 @@ void func_801860E8(s32 a0) { INCLUDE_ASM("asm/ov_SC03_118/nonmatchings/ov_SC03_118_jr_8017FB84", func_801863CC); -INCLUDE_ASM("asm/ov_SC03_118/nonmatchings/ov_SC03_118_jr_8017FB84", func_80186B78); +// @class: MATCH (386 ins, match_one byte-exact) +// @notes: 386-ins camera follow/aim update. Frame 0x50, $s0..$s3 + $ra saved. +// +// SIX LOAD-BEARING LEVERS (each MOVED the count; 183 -> 17 -> 7 -> 4 -> 0): +// +// 1. §136 L5 / idiom 6 — LOCAL SLOT ORDER + THE DEAD PAD. +// out[4]@0x10 (RotTransSV out, read lhu) sv[4]@0x18 (RotTransSV in) +// pos[4]@0x20 (func_8012CEB0 arg1) flag@0x28. +// `flag` is ONE addressable s32 reused as the yaw-delta temp, the +// RotTransSV out-param AND the func_8012CEB0 result — every stack ref in +// the .s is 0x28, so it cannot be split. vars must be 0x28 (s0@0x38), so +// 8 dead bytes are needed AFTER flag. +// *** The pad MUST be an INNER-BLOCK decl at the END of the body. *** +// An addressable SCALAR gets its stack slot lazily, when the C front end +// parses the first `&flag` (gcc 2.x generates RTL as it parses); a +// function-scope `s32 pad[2];` is expand_decl'd BEFORE any statement and +// therefore steals 0x28, pushing flag to 0x30 (cost: 15 mismatches). +// +// 2. §136 L1 (reuse, not split) — ONE pointer local `p` carries BOTH +// *(a0+0xCC) and the three *(a0+0xD0) reloads. Refs in 4 basic blocks => +// a GLOBAL allocno => $s1, which is the 4th callee-saved register and the +// whole reason the frame is 0x50. A separate `m` for the 0xD0 sites is a +// local allocno in $v1 and the function is 1 instruction short. +// +// 3. fold's `associate:` REASSOCIATES `(A - K) + B` into `A + (B - K)` and +// `A - (B - K)` into `(A + K) - B`. Both spellings appear here and both +// had to be split into a two-statement form with an explicit temp: +// `s32 t = *(u16*)(q+0x12) - 0x200; *(u16*)(q+0x12) = t + flag;` +// `s32 t = pos[1] - 0x10; d = *(s16*)(a0+0xA) - t;` +// Left folded, the first emits `li $a1,0xfe00` + `addu` where the target +// has `addiu $v1,$v1,-0x200` (idiom T2), and breaks the .L80186D68 +// cross-jump merge of the two clamp arms. +// +// 4. §5a/§34 ZERO-BYTE FENCE — `__asm__ __volatile__("")` as the FIRST +// statement of the `>= 0` (else / branch-target) arm. reorg.c +// `mostly_true_jump` predicts `bgez` TAKEN, so `fill_eager_delay_slots` +// fills the delay slot from the branch-TARGET thread and steals that arm's +// `lui $v1,0x7fff`, leaving a nop behind. `stop_search_p` bails on any asm +// insn, so the fence forces the fall-through thread instead — which yields +// the target's `lui $a0,(0x80000000>>16)` in the slot. Worth 3 mismatches. +// +// 5. REGALLOC-PERM $v0<->$v1 in the sign-set arm — the one place a source +// lever could not reach (all 8 spellings swept: ptr local, value temp, +// u32, `|=`, const-first, ~mask, swapped arms). Pinned the pointer to $3. +// It is a BLOCK-LOCAL pointer, not a parameter (S3), so it costs nothing. +// Levers 4 and 5 are BOTH required: either alone leaves 3 mismatches. +// +// 6. The two GTE control-register blocks are this TU's own +// gte_SetRotMatrix / gte_SetTransMatrix bodies verbatim. That #define +// lives BELOW the splice point (TU:5437/5451), so they are respelled here +// under private names to avoid a redefinition. +// +// DECLARATION SURFACE (D2 whole-TU one-pass grep, all above/below the splice): +// func_80047948 (TU:2204/4542/4642), func_8004787C (2205/4543/4643), +// func_80049CAC (2652), RotTransSV (2655) — copied VERBATIM. +// func_8012C218 (4926/5226/5265/5371, all BELOW the splice) — copied +// VERBATIM; the .s passes no argument, so it is called through a cast +// (idiom 9), exactly as the TU's banked func_801886xx sibling does. +// func_8012CEB0 — declared NOWHERE in this TU and in none of the 17 +// DEFINE_func_*() macros this TU expands (all checked), so the fleet- +// dominant `(s32,s32,s32)` spelling is free here. +// func_80186B78 itself has no prototype anywhere (only the INCLUDE_ASM at +// TU:4837), so no asm-label alias is needed. + +extern void func_8012C218(void *a0); +extern s32 func_80047948(s32 a0); +extern s32 func_8004787C(s32 a0); +extern void func_80049CAC(s32 a0, s32 a1); +extern void RotTransSV(void *a0, void *a1, void *a2); +extern s32 func_8012CEB0(s32 a0, s32 a1, s32 a2); + +#define SRM_80186B78(r0) __asm__ __volatile__( \ + "lw $12, 0(%0)\n" \ + "lw $13, 4(%0)\n" \ + "ctc2 $12, $0\n" \ + "ctc2 $13, $1\n" \ + "lw $12, 8(%0)\n" \ + "lw $13, 12(%0)\n" \ + "lw $14, 16(%0)\n" \ + "ctc2 $12, $2\n" \ + "ctc2 $13, $3\n" \ + "ctc2 $14, $4\n" \ + : : "r"(r0) : "$12", "$13", "$14", "memory") + +#define STM_80186B78(r0) __asm__ __volatile__( \ + "lw $12, 20(%0)\n" \ + "lw $13, 24(%0)\n" \ + "ctc2 $12, $5\n" \ + "lw $14, 28(%0)\n" \ + "ctc2 $13, $6\n" \ + "ctc2 $14, $7\n" \ + : : "r"(r0) : "$12", "$13", "$14", "memory") + +void func_80186B78(s32 a0) +{ + u16 out[4]; /* sp+0x10 */ + s16 sv[4]; /* sp+0x18 */ + s16 pos[4]; /* sp+0x20 */ + s32 flag; /* sp+0x28 */ + s16 *p; + + if (*(s16 *)(*(s32 *)(a0 + 0x64) + 0x36) != *(s16 *)(a0 + 0xFE)) { + ((void (*)(void))func_8012C218)(); + return; + } + + if (*(s16 *)(a0 + 0x70) == 1 || *(s16 *)(a0 + 0x70) == 8) { + s32 ang; + s32 t; + ang = (*(u16 *)(a0 + 0xFC) + 0x40) & 0xFFF; + p = *(s16 **)(a0 + 0xCC); + *(s16 *)(a0 + 0xFC) = ang; + t = (func_8004787C(ang) >> 6) + 0xBF; + p[2] = t; + p[1] = t; + p[0] = t; + } + + if (*(s32 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 4) < 0) { + { register s32 *q __asm__("$3"); q = *(s32 **)(a0 + 0x20); + q[1] = q[1] | 0x80000000; } + } else { + __asm__ __volatile__(""); + *(s32 *)(*(s32 *)(a0 + 0x20) + 4) = + *(s32 *)(*(s32 *)(a0 + 0x20) + 4) & 0x7FFFFFFF; + } + + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x18) = + *(u16 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x18); + + if (*(s16 *)(*(s32 *)(a0 + 0x64) + 0x70) < 8) { + *(s16 *)(a0 + 0x108) = (*(u16 *)(a0 + 0x108) + 0x40) & 0xFFF; + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) & 0xFFF; + *(u16 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x12) = + *(u16 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x12) & 0xFFF; + + flag = *(s16 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x12) - + *(s16 *)(*(s32 *)(a0 + 0x20) + 0x12); + if (flag > 0x800) { + flag = flag - 0x1000; + } + if (flag < -0x800) { + flag = flag + 0x1000; + } + if (flag > 0x200) { + s32 t = *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) - 0x200; + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = t + flag; + } else if (flag < -0x200) { + s32 t = *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) + 0x200; + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = t + flag; + } else { + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) + (flag / 16); + } + + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) + + (func_8004787C(*(s16 *)(a0 + 0x108)) >> 6); + + func_80049CAC(*(s32 *)(a0 + 0x20) + 0x10, *(s32 *)(a0 + 0x20) + 0x34); + SRM_80186B78((s32 *)(*(s32 *)(a0 + 0x20) + 0x34)); + STM_80186B78((s32 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x34)); + + p = *(s16 **)(a0 + 0xD0); + sv[0] = 0; + sv[1] = 0; + sv[2] = (p[2] * *(s16 *)(*(s32 *)(a0 + 0x20) + 0x18)) >> 12; + RotTransSV(sv, out, &flag); + + *(s16 *)(a0 + 6) = out[0]; + *(s16 *)(a0 + 0xA) = out[1]; + *(s16 *)(a0 + 0xE) = out[2]; + out[1] = out[1] - 0x40; + + pos[0] = *(u16 *)(a0 + 6); + pos[1] = *(u16 *)(a0 + 0xA) + 0x10; + pos[2] = *(u16 *)(a0 + 0xE); + flag = func_8012CEB0((s32)out, (s32)pos, 1); + if (flag & 0x1000) { + return; + } + if (flag != 0) { + s32 d; + s32 t = pos[1] - 0x10; + d = *(s16 *)(a0 + 0xA) - t; + if (d < 5) { + return; + } + if (d > 0x40) { + d = 0x40; + } + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) + (d << 4); + + func_80049CAC(*(s32 *)(a0 + 0x20) + 0x10, *(s32 *)(a0 + 0x20) + 0x34); + SRM_80186B78((s32 *)(*(s32 *)(a0 + 0x20) + 0x34)); + STM_80186B78((s32 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x34)); + + p = *(s16 **)(a0 + 0xD0); + sv[0] = 0; + sv[1] = 0; + sv[2] = (p[2] * *(s16 *)(*(s32 *)(a0 + 0x20) + 0x18)) >> 12; + RotTransSV(sv, out, &flag); + + *(s16 *)(a0 + 6) = out[0]; + *(s16 *)(a0 + 0xA) = out[1]; + *(s16 *)(a0 + 0xE) = out[2]; + } else { + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) - 0x80; + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) & 0xFFF; + if ((u32)(*(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) - 0x801) < 0x3FF) { + *(s16 *)(*(s32 *)(a0 + 0x20) + 0x10) = 0xC00; + } + } + } else { + s32 ang; + s32 ang2; + + ang = (*(u16 *)(a0 + 0x102) + *(u16 *)(a0 + 0x106)) & 0xFFF; + *(s16 *)(a0 + 0x102) = ang; + *(s16 *)(*(s32 *)(a0 + 0x20) + 0x10) = func_80047948(ang) >> 6; + + ang2 = (*(u16 *)(a0 + 0x104) + *(u16 *)(a0 + 0x100)) & 0xFFF; + *(s16 *)(a0 + 0x104) = ang2; + *(s16 *)(*(s32 *)(a0 + 0x20) + 0x14) = func_80047948(ang2) >> 6; + + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) + 0xC00; + + func_80049CAC(*(s32 *)(a0 + 0x20) + 0x10, *(s32 *)(a0 + 0x20) + 0x34); + SRM_80186B78((s32 *)(*(s32 *)(a0 + 0x20) + 0x34)); + STM_80186B78((s32 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x34)); + + p = *(s16 **)(a0 + 0xD0); + sv[0] = 0; + sv[1] = 0; + sv[2] = (p[2] * *(s16 *)(*(s32 *)(a0 + 0x20) + 0x18)) >> 12; + RotTransSV(sv, out, &flag); + + *(s16 *)(a0 + 6) = out[0]; + *(s16 *)(a0 + 0xA) = out[1]; + *(s16 *)(a0 + 0xE) = out[2]; + } + { s32 pad[2]; } /* LEVER 1: frame pad. INNER-BLOCK + LAST is load-bearing -- + a function-scope decl takes 0x28 and evicts flag to 0x30 */ +} + INCLUDE_ASM("asm/ov_SC03_118/nonmatchings/ov_SC03_118_jr_8017FB84", func_80187180); diff --git a/src/ov_SC03_119/ov_SC03_119_jr_8017FB84.c b/src/ov_SC03_119/ov_SC03_119_jr_8017FB84.c index 5d0e837d1..7515aad27 100644 --- a/src/ov_SC03_119/ov_SC03_119_jr_8017FB84.c +++ b/src/ov_SC03_119/ov_SC03_119_jr_8017FB84.c @@ -3194,7 +3194,370 @@ void func_8017FB84(s32 arg0) -INCLUDE_ASM("asm/ov_SC03_119/nonmatchings/ov_SC03_119_jr_8017FB84", func_80180A64); +#define gte_ldv0(r0) __asm__ __volatile__( \ + "lwc2 $0, 0(%0)\n" \ + "lwc2 $1, 4(%0)\n" \ + : : "r"(r0) : "memory") +#define gte_ldv0(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 )" \ + : \ + : "r"( r0 ) ) +#define gte_ldv3c(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 );" \ + "lwc2 $2, 8( %0 );" \ + "lwc2 $3, 12( %0 );" \ + "lwc2 $4, 16( %0 );" \ + "lwc2 $5, 20( %0 )" \ + : \ + : "r"( r0 ) ) +#define gte_rtps() __asm__ volatile ("nop;nop;rtps") +#define gte_rtpt() __asm__ volatile ("nop;nop;rtpt") +#define gte_nclip() __asm__ volatile ("nop;nop;nclip") +#define gte_stsxy(r0) __asm__ volatile ( \ + "swc2 $14, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) +#define gte_stsxy3(r0, r1, r2) __asm__ volatile ( \ + "swc2 $12, 0( %0 );" \ + "swc2 $13, 0( %1 );" \ + "swc2 $14, 0( %2 )" \ + : \ + : "r"( r0 ), "r"( r1 ), "r"( r2 ) \ + : "memory" ) +#define gte_stsxy3c(r0) __asm__ volatile ( \ + "swc2 $12, 0( %0 );" \ + "swc2 $13, 4( %0 );" \ + "swc2 $14, 8( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) +#define gte_stsxy3_ft3(r0) __asm__ volatile ( \ + "swc2 $12, 8( %0 );" \ + "swc2 $13, 16( %0 );" \ + "swc2 $14, 24( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) +#define gte_stsz3(r0, r1, r2) __asm__ volatile ( \ + "swc2 $17, 0( %0 );" \ + "swc2 $18, 0( %1 );" \ + "swc2 $19, 0( %2 )" \ + : \ + : "r"( r0 ), "r"( r1 ), "r"( r2 ) \ + : "memory" ) +#define gte_stsz4(r0, r1, r2, r3) __asm__ volatile ( \ + "swc2 $16, 0( %0 );" \ + "swc2 $17, 0( %1 );" \ + "swc2 $18, 0( %2 );" \ + "swc2 $19, 0( %3 )" \ + : \ + : "r"( r0 ), "r"( r1 ), "r"( r2 ), "r"( r3 ) ) +#define gte_stszotz(r0) __asm__ volatile ( \ + "mfc2 $12, $19;" \ + "nop;" \ + "sra $12, $12, 2;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) +#define gte_stflg(r0) __asm__ volatile ( \ + "cfc2 $12, $31;" \ + "nop;" \ + "sw $12, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "$12", "memory" ) +#define gte_stopz(r0) __asm__ volatile ( \ + "swc2 $24, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + + +void func_80180A64(s32 arg0, s32 arg1, s32 arg2, s32 arg3) +{ + typedef struct { u32 w0, w1, w2; } Prim_80180A64; + /* vy UNSIGNED: the `+=` reads it with lhu, not lh. */ + typedef struct { s16 vx; u16 vy; s16 vz, pad; } SVec_80180A64; + + extern s32 func_800491EC(void); + extern void func_800547D8(s32, MATRIX2 *); + extern void func_80052E38(MATRIX2 *); + extern u8 *D_800A5E60; + extern u8 D_800A6610[]; + extern u16 D_8018DAB4[]; + + DVECTOR2 tmpxy[4]; /* sp+0x10 */ + SVECTOR2 box[8]; /* sp+0x20 */ + SVECTOR2 sxy[8]; /* sp+0x60 */ + SVec_80180A64 v[3]; /* sp+0xA0 */ + SVec_80180A64 vdv; /* sp+0xB8 */ + MATRIX2 mtx; /* sp+0xC0 */ + struct { long otz, flag, opz, sz0, sz1, sz2, sz3; } g; /* sp+0xE0 */ + + s32 lim; /* spill 0x100 */ + u32 ot; /* spill 0x108 */ + s32 nparts; /* spill 0x110 */ + s32 j; + u32 nprim; + u32 i; + Part *part; /* spill 0x118 */ + SVec_80180A64 *vp; + Prim_80180A64 *prim; + u8 *pkt; + u8 *vtx; + u8 *va, *vb, *vc, *vd; + u32 w; + u32 m24; + s32 code; /* SIGNED: the switch tree uses slti, not sltiu */ + u32 wx, wy, wz; + s32 rot; + s32 zoff; + s32 xa32, xb32, t32; + s32 xmn1, xmx1, xmn2, xmx2; + s32 mnc, mxc; + s16 my, mny, mx, mn; + + if (*(s32 *)arg0 == 0) { + lim = func_800491EC() + *(s32 *)(arg0 + 0x64); + func_800547D8(arg0 + 0x10, &mtx); + func_80052E38(&mtx); + pkt = D_800A5E60; + + nparts = *(s32 *)(arg1 + 8); + ot = (u32)&D_800A6610[(*(u16 *)&D_800B9A02) << 14]; + rot = arg2; + zoff = arg3; + vtx = *(u8 **)(arg1 + 0x10); + part = (Part *)(arg1 + 0x14); + + for (j = 0; j < nparts; j++, part++) { + wx = part->xx; + mn = wx; + mx = wx >> 16; + wy = part->yy; + mny = wy + zoff; + my = (wy >> 16) + zoff; + wz = part->zz; + box[0].vx = mn; box[0].vy = mny; box[0].vz = wz; + box[1].vx = mx; box[1].vy = mny; box[1].vz = wz; + box[2].vx = mn; box[2].vy = mny; box[2].vz = wz >> 16; + box[3].vx = mx; box[3].vy = mny; box[3].vz = wz >> 16; + + gte_ldv3c(&box[0]); + gte_rtpt(); + gte_stsxy3(&sxy[0], &sxy[1], &sxy[2]); + gte_ldv0(&box[3]); + gte_rtps(); + + box[4].vx = mn; box[4].vy = my; box[4].vz = wz; + box[5].vx = mx; box[5].vy = my; box[5].vz = wz; + box[6].vx = mn; box[6].vy = my; box[6].vz = wz >> 16; + box[7].vx = mx; box[7].vy = my; box[7].vz = wz >> 16; + + gte_stsxy(&sxy[3]); + gte_ldv3c(&box[4]); + __asm__ volatile (""); /* §47 live-length slider (carried from the twin) */ + gte_rtpt(); + gte_stsxy3(&sxy[4], &sxy[5], &sxy[6]); + gte_ldv0(&box[7]); + gte_rtps(); + gte_stsxy(&sxy[7]); + gte_stszotz(&g.otz); + + if (lim >= g.otz) { + xa32 = sxy[0].vx; + xb32 = sxy[1].vx; + if (xb32 < xa32) { xmx1 = xa32; xmn1 = xb32; } else { xmn1 = xa32; xmx1 = xb32; } + t32 = sxy[2].vx; + if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32; + t32 = sxy[3].vx; + if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32; + xa32 = sxy[4].vx; + xb32 = sxy[5].vx; + if (xb32 < xa32) { xmx2 = xa32; xmn2 = xb32; } else { xmn2 = xa32; xmx2 = xb32; } + t32 = sxy[6].vx; + if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32; + t32 = sxy[7].vx; + if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32; + mnc = xmn1; + if (xmn2 < xmn1) mnc = xmn2; + mxc = xmx1; + if (mxc < xmx2) mxc = xmx2; + if ((s16)mxc >= -0xA0 && (s16)mnc < 0xA1) { + xa32 = sxy[0].vy; + xb32 = sxy[1].vy; + if (xb32 < xa32) { xmx1 = xa32; xmn1 = xb32; } else { xmn1 = xa32; xmx1 = xb32; } + t32 = sxy[2].vy; + if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32; + t32 = sxy[3].vy; + if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32; + xa32 = sxy[4].vy; + xb32 = sxy[5].vy; + if (xb32 < xa32) { xmx2 = xa32; xmn2 = xb32; } else { xmn2 = xa32; xmx2 = xb32; } + t32 = sxy[6].vy; + if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32; + t32 = sxy[7].vy; + if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32; + mnc = xmn1; + if (xmn2 < xmn1) mnc = xmn2; + mxc = xmx1; + if (mxc < xmx2) mxc = xmx2; + if ((s16)mxc >= -0x6E && (s16)mnc < 0x6F) { + prim = (Prim_80180A64 *)part->prim; + nprim = part->nprim; + for (i = 0; i < nprim; i++, prim++) { + m24 = 0xFFFFFF; + vp = &vdv; + w = prim->w1; + va = vtx + (w & 0xFFFF); + vb = vtx + (w >> 16); + w = prim->w2; + vc = vtx + (w & 0xFFFF); + v[0] = *(SVec_80180A64 *)va; + v[1] = *(SVec_80180A64 *)vb; + v[2] = *(SVec_80180A64 *)vc; + w = w >> 16; + v[0].vy += D_8018DAB4[(v[0].vz + rot) & 0xFF] + zoff; + v[1].vy += D_8018DAB4[(v[1].vz + rot) & 0xFF] + zoff; + v[2].vy += D_8018DAB4[(v[2].vz + rot) & 0xFF] + zoff; + gte_ldv3c(&v[0]); + gte_rtpt(); + gte_stflg(&g.flag); + if (!(g.flag & 0x7F85E000)) { + gte_nclip(); + code = w & 7; + vd = vtx + (w & 0xFFF8); + gte_stopz(&g.opz); + if (g.opz > 0) { + switch (code) { + case 6: + case 7: + gte_stsxy3_ft3(pkt); + gte_stsz3(&g.sz0, &g.sz1, &g.sz2); + if (((PolyFT3 *)pkt)->x0 > ((PolyFT3 *)pkt)->x1) { + mx = ((PolyFT3 *)pkt)->x0; + mn = ((PolyFT3 *)pkt)->x1; + } else { + mn = ((PolyFT3 *)pkt)->x0; + mx = ((PolyFT3 *)pkt)->x1; + } + if (((PolyFT3 *)pkt)->x2 > mx) mx = ((PolyFT3 *)pkt)->x2; + else if (((PolyFT3 *)pkt)->x2 < mn) mn = ((PolyFT3 *)pkt)->x2; + if (mx >= -0xA0 && mn < 0xA1) { + if (((PolyFT3 *)pkt)->y0 > ((PolyFT3 *)pkt)->y1) { + my = ((PolyFT3 *)pkt)->y0; + mny = ((PolyFT3 *)pkt)->y1; + } else { + mny = ((PolyFT3 *)pkt)->y0; + my = ((PolyFT3 *)pkt)->y1; + } + if (((PolyFT3 *)pkt)->y2 > my) my = ((PolyFT3 *)pkt)->y2; + else if (((PolyFT3 *)pkt)->y2 < mny) mny = ((PolyFT3 *)pkt)->y2; + if (my >= -0x6E && mny < 0x6F) { + s32 za; + u32 *otp; + u32 *tp; + if (g.sz0 > g.sz1) { + za = g.sz0; + if (za < g.sz2) za = g.sz2; + } else { + za = g.sz1; + if (za < g.sz2) za = g.sz2; + } + g.opz = za; + if (code == 7) g.opz = za + 0x200; + tp = (u32 *)prim->w0; + ((PolyFT3 *)pkt)->rgbc = tp[0] | 0x2000000; + ((PolyFT3 *)pkt)->uvc0 = tp[1]; + ((PolyFT3 *)pkt)->uvp1 = tp[2]; + ((PolyFT3 *)pkt)->uv2 = tp[3]; + otp = (u32 *)(((g.opz >> 2) << 2) + ot); + *(u32 *)pkt = (*otp & m24) | 0x7000000; + *otp = (*otp & 0xFF000000) | ((u32)pkt & m24); + pkt += 0x28; + } + } + break; + case 2: + case 3: + gte_stsxy3c(&tmpxy[0]); + vdv = *(SVec_80180A64 *)vd; + vdv.vy += D_8018DAB4[(vdv.vz + rot) & 0xFF] + zoff; + gte_ldv0(vp); + gte_rtps(); + if (tmpxy[0].vx > tmpxy[1].vx) { + mx = tmpxy[0].vx; + mn = tmpxy[1].vx; + } else { + mn = tmpxy[0].vx; + mx = tmpxy[1].vx; + } + if (tmpxy[2].vx > mx) mx = tmpxy[2].vx; + else if (tmpxy[2].vx < mn) mn = tmpxy[2].vx; + if (tmpxy[0].vy > tmpxy[1].vy) { + my = tmpxy[0].vy; + mny = tmpxy[1].vy; + } else { + mny = tmpxy[0].vy; + my = tmpxy[1].vy; + } + if (tmpxy[2].vy > my) my = tmpxy[2].vy; + else if (tmpxy[2].vy < mny) mny = tmpxy[2].vy; + gte_stflg(&g.flag); + if (!(g.flag & 0x7F85E000)) { + gte_stsz4(&g.sz0, &g.sz1, &g.sz2, &g.sz3); + gte_stsxy((long *)&((PolyFT4 *)pkt)->x3); + if (((PolyFT4 *)pkt)->x3 < mn) mn = ((PolyFT4 *)pkt)->x3; + else if (mx < ((PolyFT4 *)pkt)->x3) mx = ((PolyFT4 *)pkt)->x3; + if (mx >= -0xA0 && mn < 0xA1) { + if (((PolyFT4 *)pkt)->y3 < mny) mny = ((PolyFT4 *)pkt)->y3; + else if (my < ((PolyFT4 *)pkt)->y3) my = ((PolyFT4 *)pkt)->y3; + if (my >= -0x6E && mny < 0x6F) { + s32 za, zb; + u32 *otp; + u32 *tp; + u32 uvw; + zb = g.sz2; + if (zb < g.sz3) zb = g.sz3; + za = g.sz0; + if (za < g.sz1) za = g.sz1; + if (za < zb) za = zb; + g.opz = za; + if (code == 3) g.opz = za + 0x200; + *(u32 *)&((PolyFT4 *)pkt)->x0 = *(u32 *)&tmpxy[0]; + *(u32 *)&((PolyFT4 *)pkt)->x1 = *(u32 *)&tmpxy[1]; + *(u32 *)&((PolyFT4 *)pkt)->x2 = *(u32 *)&tmpxy[2]; + tp = (u32 *)prim->w0; + ((PolyFT4 *)pkt)->rgbc = tp[0] | 0x2000000; + ((PolyFT4 *)pkt)->uvc0 = tp[1]; + ((PolyFT4 *)pkt)->uvp1 = tp[2]; + uvw = tp[3]; + ((PolyFT4 *)pkt)->uv2 = uvw; + ((PolyFT4 *)pkt)->uv3 = uvw >> 16; + otp = (u32 *)(((g.opz >> 2) << 2) + ot); + *(u32 *)pkt = (*otp & m24) | 0x9000000; + *otp = (*otp & 0xFF000000) | ((u32)pkt & m24); + pkt += 0x28; + } + } + } + break; + } + } + } + } + } + } + } + } + D_800A5E60 = pkt; + } +} + extern void (*D_8018DD98[])(void); @@ -4804,7 +5167,189 @@ void func_801860E8(s32 a0) { INCLUDE_ASM("asm/ov_SC03_119/nonmatchings/ov_SC03_119_jr_8017FB84", func_801863CC); -INCLUDE_ASM("asm/ov_SC03_119/nonmatchings/ov_SC03_119_jr_8017FB84", func_80186B78); +extern s32 func_8004787C(s32 a0); +extern s32 func_80047948(s32 a0); +extern void func_80049CAC(s32 a0, s32 a1); +extern void func_8012C218(void *a0); +extern s32 func_8012CEB0(s32 a0, s32 a1, s32 a2); +#define SRM_80186B78(r0) __asm__ __volatile__( \ + "lw $12, 0(%0)\n" \ + "lw $13, 4(%0)\n" \ + "ctc2 $12, $0\n" \ + "ctc2 $13, $1\n" \ + "lw $12, 8(%0)\n" \ + "lw $13, 12(%0)\n" \ + "lw $14, 16(%0)\n" \ + "ctc2 $12, $2\n" \ + "ctc2 $13, $3\n" \ + "ctc2 $14, $4\n" \ + : : "r"(r0) : "$12", "$13", "$14", "memory") +#define STM_80186B78(r0) __asm__ __volatile__( \ + "lw $12, 20(%0)\n" \ + "lw $13, 24(%0)\n" \ + "ctc2 $12, $5\n" \ + "lw $14, 28(%0)\n" \ + "ctc2 $13, $6\n" \ + "ctc2 $14, $7\n" \ + : : "r"(r0) : "$12", "$13", "$14", "memory") + +void func_80186B78(s32 a0) +{ + u16 out[4]; /* sp+0x10 */ + s16 sv[4]; /* sp+0x18 */ + s16 pos[4]; /* sp+0x20 */ + s32 flag; /* sp+0x28 */ + s16 *p; + + if (*(s16 *)(*(s32 *)(a0 + 0x64) + 0x36) != *(s16 *)(a0 + 0xFE)) { + ((void (*)(void))func_8012C218)(); + return; + } + + if (*(s16 *)(a0 + 0x70) == 1 || *(s16 *)(a0 + 0x70) == 8) { + s32 ang; + s32 t; + ang = (*(u16 *)(a0 + 0xFC) + 0x40) & 0xFFF; + p = *(s16 **)(a0 + 0xCC); + *(s16 *)(a0 + 0xFC) = ang; + t = (func_8004787C(ang) >> 6) + 0xBF; + p[2] = t; + p[1] = t; + p[0] = t; + } + + if (*(s32 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 4) < 0) { + { register s32 *q __asm__("$3"); q = *(s32 **)(a0 + 0x20); + q[1] = q[1] | 0x80000000; } + } else { + __asm__ __volatile__(""); + *(s32 *)(*(s32 *)(a0 + 0x20) + 4) = + *(s32 *)(*(s32 *)(a0 + 0x20) + 4) & 0x7FFFFFFF; + } + + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x18) = + *(u16 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x18); + + if (*(s16 *)(*(s32 *)(a0 + 0x64) + 0x70) < 8) { + *(s16 *)(a0 + 0x108) = (*(u16 *)(a0 + 0x108) + 0x40) & 0xFFF; + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) & 0xFFF; + *(u16 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x12) = + *(u16 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x12) & 0xFFF; + + flag = *(s16 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x12) - + *(s16 *)(*(s32 *)(a0 + 0x20) + 0x12); + if (flag > 0x800) { + flag = flag - 0x1000; + } + if (flag < -0x800) { + flag = flag + 0x1000; + } + if (flag > 0x200) { + s32 t = *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) - 0x200; + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = t + flag; + } else if (flag < -0x200) { + s32 t = *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) + 0x200; + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = t + flag; + } else { + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) + (flag / 16); + } + + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) + + (func_8004787C(*(s16 *)(a0 + 0x108)) >> 6); + + func_80049CAC(*(s32 *)(a0 + 0x20) + 0x10, *(s32 *)(a0 + 0x20) + 0x34); + SRM_80186B78((s32 *)(*(s32 *)(a0 + 0x20) + 0x34)); + STM_80186B78((s32 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x34)); + + p = *(s16 **)(a0 + 0xD0); + sv[0] = 0; + sv[1] = 0; + sv[2] = (p[2] * *(s16 *)(*(s32 *)(a0 + 0x20) + 0x18)) >> 12; + RotTransSV(sv, out, &flag); + + *(s16 *)(a0 + 6) = out[0]; + *(s16 *)(a0 + 0xA) = out[1]; + *(s16 *)(a0 + 0xE) = out[2]; + out[1] = out[1] - 0x40; + + pos[0] = *(u16 *)(a0 + 6); + pos[1] = *(u16 *)(a0 + 0xA) + 0x10; + pos[2] = *(u16 *)(a0 + 0xE); + flag = func_8012CEB0((s32)out, (s32)pos, 1); + if (flag & 0x1000) { + return; + } + if (flag != 0) { + s32 d; + s32 t = pos[1] - 0x10; + d = *(s16 *)(a0 + 0xA) - t; + if (d < 5) { + return; + } + if (d > 0x40) { + d = 0x40; + } + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) + (d << 4); + + func_80049CAC(*(s32 *)(a0 + 0x20) + 0x10, *(s32 *)(a0 + 0x20) + 0x34); + SRM_80186B78((s32 *)(*(s32 *)(a0 + 0x20) + 0x34)); + STM_80186B78((s32 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x34)); + + p = *(s16 **)(a0 + 0xD0); + sv[0] = 0; + sv[1] = 0; + sv[2] = (p[2] * *(s16 *)(*(s32 *)(a0 + 0x20) + 0x18)) >> 12; + RotTransSV(sv, out, &flag); + + *(s16 *)(a0 + 6) = out[0]; + *(s16 *)(a0 + 0xA) = out[1]; + *(s16 *)(a0 + 0xE) = out[2]; + } else { + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) - 0x80; + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) & 0xFFF; + if ((u32)(*(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) - 0x801) < 0x3FF) { + *(s16 *)(*(s32 *)(a0 + 0x20) + 0x10) = 0xC00; + } + } + } else { + s32 ang; + s32 ang2; + + ang = (*(u16 *)(a0 + 0x102) + *(u16 *)(a0 + 0x106)) & 0xFFF; + *(s16 *)(a0 + 0x102) = ang; + *(s16 *)(*(s32 *)(a0 + 0x20) + 0x10) = func_80047948(ang) >> 6; + + ang2 = (*(u16 *)(a0 + 0x104) + *(u16 *)(a0 + 0x100)) & 0xFFF; + *(s16 *)(a0 + 0x104) = ang2; + *(s16 *)(*(s32 *)(a0 + 0x20) + 0x14) = func_80047948(ang2) >> 6; + + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) + 0xC00; + + func_80049CAC(*(s32 *)(a0 + 0x20) + 0x10, *(s32 *)(a0 + 0x20) + 0x34); + SRM_80186B78((s32 *)(*(s32 *)(a0 + 0x20) + 0x34)); + STM_80186B78((s32 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x34)); + + p = *(s16 **)(a0 + 0xD0); + sv[0] = 0; + sv[1] = 0; + sv[2] = (p[2] * *(s16 *)(*(s32 *)(a0 + 0x20) + 0x18)) >> 12; + RotTransSV(sv, out, &flag); + + *(s16 *)(a0 + 6) = out[0]; + *(s16 *)(a0 + 0xA) = out[1]; + *(s16 *)(a0 + 0xE) = out[2]; + } + { s32 pad[2]; } /* LEVER 1: frame pad. INNER-BLOCK + LAST is load-bearing -- + a function-scope decl takes 0x28 and evicts flag to 0x30 */ +} + INCLUDE_ASM("asm/ov_SC03_119/nonmatchings/ov_SC03_119_jr_8017FB84", func_80187180); diff --git a/src/ov_SC03_125/ov_SC03_125_jr_8017D604.c b/src/ov_SC03_125/ov_SC03_125_jr_8017D604.c index c5a04447c..65dbc319e 100644 --- a/src/ov_SC03_125/ov_SC03_125_jr_8017D604.c +++ b/src/ov_SC03_125/ov_SC03_125_jr_8017D604.c @@ -3606,7 +3606,35 @@ INCLUDE_ASM("asm/ov_SC03_125/nonmatchings/ov_SC03_125_jr_8017D604", func_8017FD9 INCLUDE_ASM("asm/ov_SC03_125/nonmatchings/ov_SC03_125_jr_8017D604", func_8017FE60); -INCLUDE_ASM("asm/ov_SC03_125/nonmatchings/ov_SC03_125_jr_8017D604", func_80180148); + + + + + +void func_80180148(void *a0, void *a1, void *a2, void *a3) +{ + extern void func_80016ED4(void *a0); + extern s32 D_80188128; + extern s32 D_8018812C; + extern s32 D_80188130; + extern s32 D_80188134; + + Prim_8016E7C8 prim; + + prim.v[0] = *(SVECTOR_8016E7C8 *)a0; + prim.v[1] = *(SVECTOR_8016E7C8 *)a1; + prim.v[2] = *(SVECTOR_8016E7C8 *)a2; + prim.v[3] = *(SVECTOR_8016E7C8 *)a3; + prim.f0 = D_80188128; + prim.f1 = D_8018812C; + prim.f2 = D_80188130; + prim.f3 = D_80188134; + prim.f4 = 0x808080; + prim.f5 = 0; + prim.f6 = 0x50; + func_80016ED4(&prim); +} + INCLUDE_ASM("asm/ov_SC03_125/nonmatchings/ov_SC03_125_jr_8017D604", func_80180230); diff --git a/src/ov_SC04_011/ov_SC04_011_jr_8017D494.c b/src/ov_SC04_011/ov_SC04_011_jr_8017D494.c index d43cc4db6..e7a6d77ca 100644 --- a/src/ov_SC04_011/ov_SC04_011_jr_8017D494.c +++ b/src/ov_SC04_011/ov_SC04_011_jr_8017D494.c @@ -5803,7 +5803,42 @@ void func_8018EBCC(s32 a0) { } -INCLUDE_ASM("asm/ov_SC04_011/nonmatchings/ov_SC04_011_jr_8017D494", func_8018EEB0); + +extern void func_8018EFB0(void *a0); +extern void func_8018F02C(void *a0); +extern void func_8012931C(struct vec *a0); +extern void func_801292C8(u8 *a0); + +void func_8018EEB0(void *a0) { + if (*(u16 *)((s32)a0 + 0x2) == 0) { + func_8018EFB0(a0); + return; + } + + if (*(s32 *)((s32)a0 + 0x1C) != 0) { + *(s32 *)((s32)a0 + 0x1C) -= 1; + func_8012931C((struct vec *)a0); + + if (*(s16 *)((s32)a0 + 0x32) == 0) { + u16 t = *(u16 *)((s32)a0 + 0xA) + 0x1000; + if (t >= 0x1001) { + func_801292C8((u8 *)a0); + return; + } + } + } else { + func_801292C8((u8 *)a0); + return; + } + + *(s32 *)((s32)a0 + 0x14) += *(s32 *)((s32)a0 + 0x34); + *(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0x14) += *(u16 *)((s32)a0 + 0x30); + *(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0x8) = *(u16 *)((s32)a0 + 0x6); + *(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0xA) = *(u16 *)((s32)a0 + 0xA); + *(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0xC) = *(u16 *)((s32)a0 + 0xE); + func_8018F02C((void *)*(s32 *)((s32)a0 + 0x20)); +} + INCLUDE_ASM("asm/ov_SC04_011/nonmatchings/ov_SC04_011_jr_8017D494", func_8018EFB0); diff --git a/src/ov_SC04_016/ov_SC04_016_jr_8017BEBC.c b/src/ov_SC04_016/ov_SC04_016_jr_8017BEBC.c index 021518339..4f61a9857 100644 --- a/src/ov_SC04_016/ov_SC04_016_jr_8017BEBC.c +++ b/src/ov_SC04_016/ov_SC04_016_jr_8017BEBC.c @@ -3415,11 +3415,40 @@ INCLUDE_ASM("asm/ov_SC04_016/nonmatchings/ov_SC04_016_jr_8017BEBC", func_8017EBF INCLUDE_ASM("asm/ov_SC04_016/nonmatchings/ov_SC04_016_jr_8017BEBC", func_8017EC48); -INCLUDE_ASM("asm/ov_SC04_016/nonmatchings/ov_SC04_016_jr_8017BEBC", func_8017EC90); +extern s32 func_8012A828(void *a0, void *a1); +extern s32 D_801849AC; +extern s32 D_8018430C; + +void func_8017EC90(void *arg0) { + /* [T51] scoped in from file scope: a file-scope decl of these symbols constrains every + LATER function in this TU, which blocks a byte-true decl of a different type. + Declaration-only move (cookbook §103); the whole-binary byte-gate is the arbiter. */ + extern s32 D_80184174; + s32 *s0 = M2C_FIELD(arg0, s32 *, 0xD0); + ((void (*)(s32, s32))func_8012A828)(s0, &D_80184174); + *(s32 *)((s32)s0 + 0xDC) = (s32)&D_801849AC; + *(s32 *)((s32)s0 + 0x1C) = 0; + *(s32 *)((s32)s0 + 0xEC) = (s32)&D_8018430C; +} + INCLUDE_ASM("asm/ov_SC04_016/nonmatchings/ov_SC04_016_jr_8017BEBC", func_8017ECE0); -INCLUDE_ASM("asm/ov_SC04_016/nonmatchings/ov_SC04_016_jr_8017BEBC", func_8017ED48); + +extern s32 func_8012A828(void *a0, void *a1); + +void func_8017ED48(void *arg0) { + + extern s32 D_80184174; + extern s32 D_801849CC; + extern s32 D_801840EC; + s32 *s0 = M2C_FIELD(arg0, s32 *, 0xD0); + ((void (*)(s32, s32))func_8012A828)(s0, &D_80184174); + *(s32 *)((s32)s0 + 0xDC) = (s32)&D_801849CC; + *(s32 *)((s32)s0 + 0x1C) = 0; + *(s32 *)((s32)s0 + 0xEC) = (s32)&D_801840EC; +} + extern s32 func_8012A828(void *a0, void *a1); @@ -3481,7 +3510,42 @@ INCLUDE_ASM("asm/ov_SC04_016/nonmatchings/ov_SC04_016_jr_8017BEBC", func_8017F5D INCLUDE_ASM("asm/ov_SC04_016/nonmatchings/ov_SC04_016_jr_8017BEBC", func_8017F62C); -INCLUDE_ASM("asm/ov_SC04_016/nonmatchings/ov_SC04_016_jr_8017BEBC", func_8017F72C); + +extern void func_8017F82C(void *a0); +extern void func_8017F8A8(void *a0); +extern void func_8012931C(struct vec *a0); +extern void func_801292C8(u8 *a0); + +void func_8017F72C(void *a0) { + if (*(u16 *)((s32)a0 + 0x2) == 0) { + func_8017F82C(a0); + return; + } + + if (*(s32 *)((s32)a0 + 0x1C) != 0) { + *(s32 *)((s32)a0 + 0x1C) -= 1; + func_8012931C((struct vec *)a0); + + if (*(s16 *)((s32)a0 + 0x32) == 0) { + u16 t = *(u16 *)((s32)a0 + 0xA) + 0x1000; + if (t >= 0x1001) { + func_801292C8((u8 *)a0); + return; + } + } + } else { + func_801292C8((u8 *)a0); + return; + } + + *(s32 *)((s32)a0 + 0x14) += *(s32 *)((s32)a0 + 0x34); + *(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0x14) += *(u16 *)((s32)a0 + 0x30); + *(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0x8) = *(u16 *)((s32)a0 + 0x6); + *(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0xA) = *(u16 *)((s32)a0 + 0xA); + *(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0xC) = *(u16 *)((s32)a0 + 0xE); + func_8017F8A8((void *)*(s32 *)((s32)a0 + 0x20)); +} + INCLUDE_ASM("asm/ov_SC04_016/nonmatchings/ov_SC04_016_jr_8017BEBC", func_8017F82C); diff --git a/src/ov_SC04_018/ov_SC04_018_jr_8017AE2C.c b/src/ov_SC04_018/ov_SC04_018_jr_8017AE2C.c index b276e71fc..e28a015f7 100644 --- a/src/ov_SC04_018/ov_SC04_018_jr_8017AE2C.c +++ b/src/ov_SC04_018/ov_SC04_018_jr_8017AE2C.c @@ -8868,7 +8868,54 @@ INCLUDE_ASM("asm/ov_SC04_018/nonmatchings/ov_SC04_018_jr_8017AE2C", func_8018C3F INCLUDE_ASM("asm/ov_SC04_018/nonmatchings/ov_SC04_018_jr_8017AE2C", func_8018C494); -INCLUDE_ASM("asm/ov_SC04_018/nonmatchings/ov_SC04_018_jr_8017AE2C", func_8018C518); +extern s32 func_80029504(void); +extern s32 func_80184D00(void); +extern s32 func_80184E44(void); +extern s32 func_80184BAC(s32 arg0, s32 arg1); +extern void func_80184CB8(s32*, s32); +extern short D_801E06A8; + +void func_8018C518(void *a0) { + void *s0 = a0; + s32 v1 = func_80029504(); + s32 v0; + + if (v1 < 0xC8) { + v0 = func_80184D00(); + v1 = 3; + if (v0 == v1) { + return; + } + v0 = func_80184BAC(0xA, 0x10); + if (v0 == 0) { + return; + } + v0 = 1; + } else if (v1 < 0x258) { + v0 = 1; + } else if (v1 < 0x384) { + v0 = func_80184BAC(0xA, 0x10); + if (v0 == 0) { + return; + } + v0 = 1; + } else { + v0 = func_80184E44(); + v1 = 1; + if (v0 == v1) { + return; + } + v0 = func_80184BAC(0xA, 0x10); + if (v0 == 0) { + return; + } + v0 = 1; + } + + *(s16 *)((char *)s0 + 0x2) = 0x1; + ((void (*)(s32, s32))func_80184CB8)((s32)s0, (s32)&D_801E06A8); +} + extern int func_80178970(void); diff --git a/src/ov_SC04_019/ov_SC04_019_jr_8017AE2C.c b/src/ov_SC04_019/ov_SC04_019_jr_8017AE2C.c index b36053a4a..7147624c0 100644 --- a/src/ov_SC04_019/ov_SC04_019_jr_8017AE2C.c +++ b/src/ov_SC04_019/ov_SC04_019_jr_8017AE2C.c @@ -8529,7 +8529,56 @@ INCLUDE_ASM("asm/ov_SC04_019/nonmatchings/ov_SC04_019_jr_8017AE2C", func_8018C3F INCLUDE_ASM("asm/ov_SC04_019/nonmatchings/ov_SC04_019_jr_8017AE2C", func_8018C494); -INCLUDE_ASM("asm/ov_SC04_019/nonmatchings/ov_SC04_019_jr_8017AE2C", func_8018C518); + +extern s32 func_80029504(void); +extern s32 func_80184D00(void); +extern s32 func_80184E44(void); +extern s32 func_80184BAC(s32 arg0, s32 arg1); +extern void func_80184CB8(s32*, s32); + +void func_8018C518(void *a0) { + + extern short D_801E06A8; + void *s0 = a0; + s32 v1 = func_80029504(); + s32 v0; + + if (v1 < 0xC8) { + v0 = func_80184D00(); + v1 = 3; + if (v0 == v1) { + return; + } + v0 = func_80184BAC(0xA, 0x10); + if (v0 == 0) { + return; + } + v0 = 1; + } else if (v1 < 0x258) { + v0 = 1; + } else if (v1 < 0x384) { + v0 = func_80184BAC(0xA, 0x10); + if (v0 == 0) { + return; + } + v0 = 1; + } else { + v0 = func_80184E44(); + v1 = 1; + if (v0 == v1) { + return; + } + v0 = func_80184BAC(0xA, 0x10); + if (v0 == 0) { + return; + } + v0 = 1; + } + + *(s16 *)((char *)s0 + 0x2) = 0x1; + ((void (*)(s32, s32))func_80184CB8)((s32)s0, (s32)&D_801E06A8); +} + extern int func_80178970(void); diff --git a/src/ov_SC04_020/ov_SC04_020_jr_8017D604.c b/src/ov_SC04_020/ov_SC04_020_jr_8017D604.c index a4ff9e52c..94b93a94d 100644 --- a/src/ov_SC04_020/ov_SC04_020_jr_8017D604.c +++ b/src/ov_SC04_020/ov_SC04_020_jr_8017D604.c @@ -3498,7 +3498,35 @@ INCLUDE_ASM("asm/ov_SC04_020/nonmatchings/ov_SC04_020_jr_8017D604", func_8017F63 INCLUDE_ASM("asm/ov_SC04_020/nonmatchings/ov_SC04_020_jr_8017D604", func_8017F704); -INCLUDE_ASM("asm/ov_SC04_020/nonmatchings/ov_SC04_020_jr_8017D604", func_8017F9EC); + + + + + +void func_8017F9EC(void *a0, void *a1, void *a2, void *a3) +{ + extern void func_80016ED4(void *a0); + extern s32 D_801874B4; + extern s32 D_801874B8; + extern s32 D_801874BC; + extern s32 D_801874C0; + + Prim_8016E7C8 prim; + + prim.v[0] = *(SVECTOR_8016E7C8 *)a0; + prim.v[1] = *(SVECTOR_8016E7C8 *)a1; + prim.v[2] = *(SVECTOR_8016E7C8 *)a2; + prim.v[3] = *(SVECTOR_8016E7C8 *)a3; + prim.f0 = D_801874B4; + prim.f1 = D_801874B8; + prim.f2 = D_801874BC; + prim.f3 = D_801874C0; + prim.f4 = 0x808080; + prim.f5 = 0; + prim.f6 = 0x50; + func_80016ED4(&prim); +} + INCLUDE_ASM("asm/ov_SC04_020/nonmatchings/ov_SC04_020_jr_8017D604", func_8017FAD4); diff --git a/src/ov_SC05_003/ov_SC05_003_jr_8017BEBC.c b/src/ov_SC05_003/ov_SC05_003_jr_8017BEBC.c index 08bcdedb8..660fb9b82 100644 --- a/src/ov_SC05_003/ov_SC05_003_jr_8017BEBC.c +++ b/src/ov_SC05_003/ov_SC05_003_jr_8017BEBC.c @@ -3794,7 +3794,56 @@ INCLUDE_ASM("asm/ov_SC05_003/nonmatchings/ov_SC05_003_jr_8017BEBC", func_80181AA INCLUDE_ASM("asm/ov_SC05_003/nonmatchings/ov_SC05_003_jr_8017BEBC", func_80181C00); -INCLUDE_ASM("asm/ov_SC05_003/nonmatchings/ov_SC05_003_jr_8017BEBC", func_80181CDC); +#include "common.h" + +typedef struct { s16 vx, vy, vz, pad; } SVec_80181CDC; + +extern void func_8012EFB8(s32 a0); +extern void func_8012BD14(s32 a0); +extern void func_8002D4C8(s32 a0, s32 a1); + +s32 func_80181CDC(s32 a0, s32 a1) { + register s32 zr __asm__("$0"); + SVec_80181CDC pos; + SVec_80181CDC out; + s32 val; + s32 lvl; + s32 t; + s32 x; + s32 n; + s32 y; + s32 arg; + + val = 0x7F; + arg = a1; + pos.vx = *(s16 *)(a0 + 0x6); + pos.vy = *(s16 *)(a0 + 0xA); + pos.vz = *(s16 *)(a0 + 0xE); + ((void (*)(void *, void *))func_8012EFB8)(&pos, &out); + lvl = 7; + + t = out.vx; + if (t < 0) { t = -t; } + if (t >= 0xC9) { return 0; } + + if (out.vy >= 0) { + if (out.vy >= 0xA1) { return 0; } + __asm__ __volatile__(""); + } else { + if (-out.vy >= 0xA1) { return 0; } + } + + val -= ((((s32 (*)(s32))func_8012BD14)(a0) - 0x1000) * 0x7F) / 0xFF000; + x = out.vx; + n = lvl + x / 0x19; + lvl = n + zr; + if ((s16)n < 0) { lvl = 0; } + else if ((s16)n > 0xF) { lvl = 0xF; } + y = (lvl << 8) | 0x3000; + func_8002D4C8(arg & 0xFFFF, (val | y) & 0xFFFF); + return 1; +} + extern void (*D_801A9F5C[])(void); diff --git a/src/ov_SC05_004/ov_SC05_004_jr_8017BEBC.c b/src/ov_SC05_004/ov_SC05_004_jr_8017BEBC.c index 9ce736af8..c7ce09bf5 100644 --- a/src/ov_SC05_004/ov_SC05_004_jr_8017BEBC.c +++ b/src/ov_SC05_004/ov_SC05_004_jr_8017BEBC.c @@ -4398,7 +4398,189 @@ INCLUDE_ASM("asm/ov_SC05_004/nonmatchings/ov_SC05_004_jr_8017BEBC", func_8017F18 INCLUDE_ASM("asm/ov_SC05_004/nonmatchings/ov_SC05_004_jr_8017BEBC", func_8017F210); -INCLUDE_ASM("asm/ov_SC05_004/nonmatchings/ov_SC05_004_jr_8017BEBC", func_8017F9BC); +extern s32 func_8004787C(s32 a0); +extern s32 func_80047948(s32 a0); +extern void func_80049CAC(s32 a0, s32 a1); +extern void func_8012C218(void *a0); +extern s32 func_8012CEB0(s32 a0, s32 a1, s32 a2); +#define SRM_80186B78(r0) __asm__ __volatile__( \ + "lw $12, 0(%0)\n" \ + "lw $13, 4(%0)\n" \ + "ctc2 $12, $0\n" \ + "ctc2 $13, $1\n" \ + "lw $12, 8(%0)\n" \ + "lw $13, 12(%0)\n" \ + "lw $14, 16(%0)\n" \ + "ctc2 $12, $2\n" \ + "ctc2 $13, $3\n" \ + "ctc2 $14, $4\n" \ + : : "r"(r0) : "$12", "$13", "$14", "memory") +#define STM_80186B78(r0) __asm__ __volatile__( \ + "lw $12, 20(%0)\n" \ + "lw $13, 24(%0)\n" \ + "ctc2 $12, $5\n" \ + "lw $14, 28(%0)\n" \ + "ctc2 $13, $6\n" \ + "ctc2 $14, $7\n" \ + : : "r"(r0) : "$12", "$13", "$14", "memory") + +void func_8017F9BC(s32 a0) +{ + u16 out[4]; /* sp+0x10 */ + s16 sv[4]; /* sp+0x18 */ + s16 pos[4]; /* sp+0x20 */ + s32 flag; /* sp+0x28 */ + s16 *p; + + if (*(s16 *)(*(s32 *)(a0 + 0x64) + 0x36) != *(s16 *)(a0 + 0xFE)) { + ((void (*)(void))func_8012C218)(); + return; + } + + if (*(s16 *)(a0 + 0x70) == 1 || *(s16 *)(a0 + 0x70) == 8) { + s32 ang; + s32 t; + ang = (*(u16 *)(a0 + 0xFC) + 0x40) & 0xFFF; + p = *(s16 **)(a0 + 0xCC); + *(s16 *)(a0 + 0xFC) = ang; + t = (func_8004787C(ang) >> 6) + 0xBF; + p[2] = t; + p[1] = t; + p[0] = t; + } + + if (*(s32 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 4) < 0) { + { register s32 *q __asm__("$3"); q = *(s32 **)(a0 + 0x20); + q[1] = q[1] | 0x80000000; } + } else { + __asm__ __volatile__(""); + *(s32 *)(*(s32 *)(a0 + 0x20) + 4) = + *(s32 *)(*(s32 *)(a0 + 0x20) + 4) & 0x7FFFFFFF; + } + + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x18) = + *(u16 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x18); + + if (*(s16 *)(*(s32 *)(a0 + 0x64) + 0x70) < 8) { + *(s16 *)(a0 + 0x108) = (*(u16 *)(a0 + 0x108) + 0x40) & 0xFFF; + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) & 0xFFF; + *(u16 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x12) = + *(u16 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x12) & 0xFFF; + + flag = *(s16 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x12) - + *(s16 *)(*(s32 *)(a0 + 0x20) + 0x12); + if (flag > 0x800) { + flag = flag - 0x1000; + } + if (flag < -0x800) { + flag = flag + 0x1000; + } + if (flag > 0x200) { + s32 t = *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) - 0x200; + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = t + flag; + } else if (flag < -0x200) { + s32 t = *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) + 0x200; + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = t + flag; + } else { + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) + (flag / 16); + } + + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) + + (func_8004787C(*(s16 *)(a0 + 0x108)) >> 6); + + func_80049CAC(*(s32 *)(a0 + 0x20) + 0x10, *(s32 *)(a0 + 0x20) + 0x34); + SRM_80186B78((s32 *)(*(s32 *)(a0 + 0x20) + 0x34)); + STM_80186B78((s32 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x34)); + + p = *(s16 **)(a0 + 0xD0); + sv[0] = 0; + sv[1] = 0; + sv[2] = (p[2] * *(s16 *)(*(s32 *)(a0 + 0x20) + 0x18)) >> 12; + RotTransSV(sv, out, &flag); + + *(s16 *)(a0 + 6) = out[0]; + *(s16 *)(a0 + 0xA) = out[1]; + *(s16 *)(a0 + 0xE) = out[2]; + out[1] = out[1] - 0x40; + + pos[0] = *(u16 *)(a0 + 6); + pos[1] = *(u16 *)(a0 + 0xA) + 0x10; + pos[2] = *(u16 *)(a0 + 0xE); + flag = func_8012CEB0((s32)out, (s32)pos, 1); + if (flag & 0x1000) { + return; + } + if (flag != 0) { + s32 d; + s32 t = pos[1] - 0x10; + d = *(s16 *)(a0 + 0xA) - t; + if (d < 5) { + return; + } + if (d > 0x40) { + d = 0x40; + } + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) + (d << 4); + + func_80049CAC(*(s32 *)(a0 + 0x20) + 0x10, *(s32 *)(a0 + 0x20) + 0x34); + SRM_80186B78((s32 *)(*(s32 *)(a0 + 0x20) + 0x34)); + STM_80186B78((s32 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x34)); + + p = *(s16 **)(a0 + 0xD0); + sv[0] = 0; + sv[1] = 0; + sv[2] = (p[2] * *(s16 *)(*(s32 *)(a0 + 0x20) + 0x18)) >> 12; + RotTransSV(sv, out, &flag); + + *(s16 *)(a0 + 6) = out[0]; + *(s16 *)(a0 + 0xA) = out[1]; + *(s16 *)(a0 + 0xE) = out[2]; + } else { + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) - 0x80; + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) & 0xFFF; + if ((u32)(*(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) - 0x801) < 0x3FF) { + *(s16 *)(*(s32 *)(a0 + 0x20) + 0x10) = 0xC00; + } + } + } else { + s32 ang; + s32 ang2; + + ang = (*(u16 *)(a0 + 0x102) + *(u16 *)(a0 + 0x106)) & 0xFFF; + *(s16 *)(a0 + 0x102) = ang; + *(s16 *)(*(s32 *)(a0 + 0x20) + 0x10) = func_80047948(ang) >> 6; + + ang2 = (*(u16 *)(a0 + 0x104) + *(u16 *)(a0 + 0x100)) & 0xFFF; + *(s16 *)(a0 + 0x104) = ang2; + *(s16 *)(*(s32 *)(a0 + 0x20) + 0x14) = func_80047948(ang2) >> 6; + + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) + 0xC00; + + func_80049CAC(*(s32 *)(a0 + 0x20) + 0x10, *(s32 *)(a0 + 0x20) + 0x34); + SRM_80186B78((s32 *)(*(s32 *)(a0 + 0x20) + 0x34)); + STM_80186B78((s32 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x34)); + + p = *(s16 **)(a0 + 0xD0); + sv[0] = 0; + sv[1] = 0; + sv[2] = (p[2] * *(s16 *)(*(s32 *)(a0 + 0x20) + 0x18)) >> 12; + RotTransSV(sv, out, &flag); + + *(s16 *)(a0 + 6) = out[0]; + *(s16 *)(a0 + 0xA) = out[1]; + *(s16 *)(a0 + 0xE) = out[2]; + } + { s32 pad[2]; } /* LEVER 1: frame pad. INNER-BLOCK + LAST is load-bearing -- + a function-scope decl takes 0x28 and evicts flag to 0x30 */ +} + INCLUDE_ASM("asm/ov_SC05_004/nonmatchings/ov_SC05_004_jr_8017BEBC", func_8017FFC4); diff --git a/src/ov_SC05_005/ov_SC05_005_jr_8017D898.c b/src/ov_SC05_005/ov_SC05_005_jr_8017D898.c index 672473c56..011be92da 100644 --- a/src/ov_SC05_005/ov_SC05_005_jr_8017D898.c +++ b/src/ov_SC05_005/ov_SC05_005_jr_8017D898.c @@ -3835,7 +3835,55 @@ INCLUDE_ASM("asm/ov_SC05_005/nonmatchings/ov_SC05_005_jr_8017D898", func_80181BB INCLUDE_ASM("asm/ov_SC05_005/nonmatchings/ov_SC05_005_jr_8017D898", func_80181D08); -INCLUDE_ASM("asm/ov_SC05_005/nonmatchings/ov_SC05_005_jr_8017D898", func_80181DE4); + +typedef struct { s16 vx, vy, vz, pad; } SVec_80181CDC_80181DE4; + +extern void func_8012EFB8(s32 a0); +extern void func_8012BD14(s32 a0); +extern void func_8002D4C8(s32 a0, s32 a1); + +s32 func_80181DE4(s32 a0, s32 a1) { + register s32 zr __asm__("$0"); + SVec_80181CDC_80181DE4 pos; + SVec_80181CDC_80181DE4 out; + s32 val; + s32 lvl; + s32 t; + s32 x; + s32 n; + s32 y; + s32 arg; + + val = 0x7F; + arg = a1; + pos.vx = *(s16 *)(a0 + 0x6); + pos.vy = *(s16 *)(a0 + 0xA); + pos.vz = *(s16 *)(a0 + 0xE); + ((void (*)(void *, void *))func_8012EFB8)(&pos, &out); + lvl = 7; + + t = out.vx; + if (t < 0) { t = -t; } + if (t >= 0xC9) { return 0; } + + if (out.vy >= 0) { + if (out.vy >= 0xA1) { return 0; } + __asm__ __volatile__(""); + } else { + if (-out.vy >= 0xA1) { return 0; } + } + + val -= ((((s32 (*)(s32))func_8012BD14)(a0) - 0x1000) * 0x7F) / 0xFF000; + x = out.vx; + n = lvl + x / 0x19; + lvl = n + zr; + if ((s16)n < 0) { lvl = 0; } + else if ((s16)n > 0xF) { lvl = 0xF; } + y = (lvl << 8) | 0x3000; + func_8002D4C8(arg & 0xFFFF, (val | y) & 0xFFFF); + return 1; +} + extern void (*D_801ABAB4[])(void); diff --git a/src/ov_SC05_017/ov_SC05_017_jr_8017AE2C.c b/src/ov_SC05_017/ov_SC05_017_jr_8017AE2C.c index c0cc03809..c358d15a2 100644 --- a/src/ov_SC05_017/ov_SC05_017_jr_8017AE2C.c +++ b/src/ov_SC05_017/ov_SC05_017_jr_8017AE2C.c @@ -8413,7 +8413,56 @@ INCLUDE_ASM("asm/ov_SC05_017/nonmatchings/ov_SC05_017_jr_8017AE2C", func_8018C0F INCLUDE_ASM("asm/ov_SC05_017/nonmatchings/ov_SC05_017_jr_8017AE2C", func_8018C194); -INCLUDE_ASM("asm/ov_SC05_017/nonmatchings/ov_SC05_017_jr_8017AE2C", func_8018C218); + +extern s32 func_80029504(void); +extern s32 func_80184A00(void); +extern s16 func_80184B44(void); +extern s32 func_801848AC(s32 arg0, s32 arg1); +extern void func_801849B8(s32*, s32); + +void func_8018C218(void *a0) { + + extern short D_801E6968; + void *s0 = a0; + s32 v1 = func_80029504(); + s32 v0; + + if (v1 < 0xC8) { + v0 = func_80184A00(); + v1 = 3; + if (v0 == v1) { + return; + } + v0 = func_801848AC(0xA, 0x10); + if (v0 == 0) { + return; + } + v0 = 1; + } else if (v1 < 0x258) { + v0 = 1; + } else if (v1 < 0x384) { + v0 = func_801848AC(0xA, 0x10); + if (v0 == 0) { + return; + } + v0 = 1; + } else { + v0 = ((s32 (*)(void))func_80184B44)(); + v1 = 1; + if (v0 == v1) { + return; + } + v0 = func_801848AC(0xA, 0x10); + if (v0 == 0) { + return; + } + v0 = 1; + } + + *(s16 *)((char *)s0 + 0x2) = 0x1; + ((void (*)(s32, s32))func_801849B8)((s32)s0, (s32)&D_801E6968); +} + extern int func_80178970(void); diff --git a/src/ov_SC05_018/ov_SC05_018_jr_8017D604.c b/src/ov_SC05_018/ov_SC05_018_jr_8017D604.c index 237d6c831..5ae200242 100644 --- a/src/ov_SC05_018/ov_SC05_018_jr_8017D604.c +++ b/src/ov_SC05_018/ov_SC05_018_jr_8017D604.c @@ -3903,7 +3903,35 @@ INCLUDE_ASM("asm/ov_SC05_018/nonmatchings/ov_SC05_018_jr_8017D604", func_8018284 INCLUDE_ASM("asm/ov_SC05_018/nonmatchings/ov_SC05_018_jr_8017D604", func_8018290C); -INCLUDE_ASM("asm/ov_SC05_018/nonmatchings/ov_SC05_018_jr_8017D604", func_80182BF4); + + + + + +void func_80182BF4(void *a0, void *a1, void *a2, void *a3) +{ + extern void func_80016ED4(void *a0); + extern s32 D_8018B0B4; + extern s32 D_8018B0B8; + extern s32 D_8018B0BC; + extern s32 D_8018B0C0; + + Prim_8016E7C8 prim; + + prim.v[0] = *(SVECTOR_8016E7C8 *)a0; + prim.v[1] = *(SVECTOR_8016E7C8 *)a1; + prim.v[2] = *(SVECTOR_8016E7C8 *)a2; + prim.v[3] = *(SVECTOR_8016E7C8 *)a3; + prim.f0 = D_8018B0B4; + prim.f1 = D_8018B0B8; + prim.f2 = D_8018B0BC; + prim.f3 = D_8018B0C0; + prim.f4 = 0x808080; + prim.f5 = 0; + prim.f6 = 0x50; + func_80016ED4(&prim); +} + INCLUDE_ASM("asm/ov_SC05_018/nonmatchings/ov_SC05_018_jr_8017D604", func_80182CDC); diff --git a/src/ov_SC06_000/ov_SC06_000_jr_8017AE2C.c b/src/ov_SC06_000/ov_SC06_000_jr_8017AE2C.c index da80f37d5..84b0cc450 100644 --- a/src/ov_SC06_000/ov_SC06_000_jr_8017AE2C.c +++ b/src/ov_SC06_000/ov_SC06_000_jr_8017AE2C.c @@ -7061,7 +7061,42 @@ void func_801879A8(s32 *a0, s8 a1, s8 a2, s8 a3) { } -INCLUDE_ASM("asm/ov_SC06_000/nonmatchings/ov_SC06_000_jr_8017AE2C", func_801879B8); + +extern void func_80187AB8(void *a0); +extern void func_80187B34(void *a0); +extern void func_8012931C(struct vec *a0); +extern void func_801292C8(u8 *a0); + +void func_801879B8(void *a0) { + if (*(u16 *)((s32)a0 + 0x2) == 0) { + func_80187AB8(a0); + return; + } + + if (*(s32 *)((s32)a0 + 0x1C) != 0) { + *(s32 *)((s32)a0 + 0x1C) -= 1; + func_8012931C((struct vec *)a0); + + if (*(s16 *)((s32)a0 + 0x32) == 0) { + u16 t = *(u16 *)((s32)a0 + 0xA) + 0x1000; + if (t >= 0x1001) { + func_801292C8((u8 *)a0); + return; + } + } + } else { + func_801292C8((u8 *)a0); + return; + } + + *(s32 *)((s32)a0 + 0x14) += *(s32 *)((s32)a0 + 0x34); + *(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0x14) += *(u16 *)((s32)a0 + 0x30); + *(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0x8) = *(u16 *)((s32)a0 + 0x6); + *(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0xA) = *(u16 *)((s32)a0 + 0xA); + *(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0xC) = *(u16 *)((s32)a0 + 0xE); + func_80187B34((void *)*(s32 *)((s32)a0 + 0x20)); +} + INCLUDE_ASM("asm/ov_SC06_000/nonmatchings/ov_SC06_000_jr_8017AE2C", func_80187AB8); diff --git a/src/ov_SC06_006/ov_SC06_006_jr_8017BEBC.c b/src/ov_SC06_006/ov_SC06_006_jr_8017BEBC.c index 4cd4d62a6..6c0f8aea9 100644 --- a/src/ov_SC06_006/ov_SC06_006_jr_8017BEBC.c +++ b/src/ov_SC06_006/ov_SC06_006_jr_8017BEBC.c @@ -3755,7 +3755,42 @@ void func_80181498(void) { } -INCLUDE_ASM("asm/ov_SC06_006/nonmatchings/ov_SC06_006_jr_8017BEBC", func_801814DC); + +extern void func_801815DC(void *a0); +extern void func_80181658(void *a0); +extern void func_8012931C(struct vec *a0); +extern void func_801292C8(u8 *a0); + +void func_801814DC(void *a0) { + if (*(u16 *)((s32)a0 + 0x2) == 0) { + func_801815DC(a0); + return; + } + + if (*(s32 *)((s32)a0 + 0x1C) != 0) { + *(s32 *)((s32)a0 + 0x1C) -= 1; + func_8012931C((struct vec *)a0); + + if (*(s16 *)((s32)a0 + 0x32) == 0) { + u16 t = *(u16 *)((s32)a0 + 0xA) + 0x1000; + if (t >= 0x1001) { + func_801292C8((u8 *)a0); + return; + } + } + } else { + func_801292C8((u8 *)a0); + return; + } + + *(s32 *)((s32)a0 + 0x14) += *(s32 *)((s32)a0 + 0x34); + *(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0x14) += *(u16 *)((s32)a0 + 0x30); + *(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0x8) = *(u16 *)((s32)a0 + 0x6); + *(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0xA) = *(u16 *)((s32)a0 + 0xA); + *(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0xC) = *(u16 *)((s32)a0 + 0xE); + func_80181658((void *)*(s32 *)((s32)a0 + 0x20)); +} + INCLUDE_ASM("asm/ov_SC06_006/nonmatchings/ov_SC06_006_jr_8017BEBC", func_801815DC); diff --git a/src/ov_SC06_008/ov_SC06_008_jr_8017C294.c b/src/ov_SC06_008/ov_SC06_008_jr_8017C294.c index 64833d896..a404aafc3 100644 --- a/src/ov_SC06_008/ov_SC06_008_jr_8017C294.c +++ b/src/ov_SC06_008/ov_SC06_008_jr_8017C294.c @@ -4040,7 +4040,160 @@ docopy: } -INCLUDE_ASM("asm/ov_SC06_008/nonmatchings/ov_SC06_008_jr_8017C294", func_80180CA8); +/* func_80180CA8 — ov_SC06_008 / ov_SC06_008_jr_8017C294 + * + * Two-arm actor tick keyed on the s16 countdown at actor+0xFC: + * arm A (counter == 0, the FALL-THROUGH / longer block): three func_8012C658 + * spawns with offset pokes, a sound cue, two child-actor state pokes, an + * 8-iteration 0x281 particle burst, then the RTP positional-sound block + * (the byte-proven RTP_SND shape from ov_SC03_099_jr_8017BEBC.c:5406). + * arm B (counter != 0): a func_8012913C(0x23) spawn scattered around the + * actor, VectorNormalSS toward D_801151D4->{0x5C,0x60,0x64}, sound 0xAF8. + * + * Declarations copied VERBATIM from the TU (one-pass grep, D2): + * D_801151D4 src/ov_SC06_008/ov_SC06_008_jr_8017C294.c:323 + * rand :956 + * VectorNormalSS :1849 + * func_8012C658 :2523 + * func_8012C588 :3767 + * func_8012C218 :3782 + * func_8002D4C8 :59 + * func_8004914C :2645 + * func_800491AC :2646 + * func_8012913C :4356 (non-prototype form, BELOW the splice point) + * func_8002AC00 :5447 (block-scope extern only) + * RotTransPers / D_800AF648 / func_8002A04C are not in this TU -> fleet-dominant forms. + */ + +extern s32 D_801151D4; +extern s32 rand(void); +extern s32 VectorNormalSS(void *a0, void *a1); +extern s32 func_8012C658(s32 arg0, s32 arg1, s32 arg2); +extern s32 func_8012C588(s32 a0, s32 a1); +extern void func_8012C218(void *a0); +extern void func_8002D4C8(s32 a0, s32 a1); +extern void func_8004914C(void *a0); +extern void func_800491AC(void *a0); +extern void func_8002A04C(s32 a0); +extern void func_8002AC00(s32 a0); +extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3); +extern u8 *func_8012913C(); + +void func_80180CA8(s32 a0) +{ + extern u8 D_800AF648; + + /* L5: slot offsets are exact only through ONE struct — plain array locals + get 8-byte-rounded slots and pushed z/flag to 0x28/0x2C (measured). */ + struct { + u16 nv[4]; /* sp+0x10 */ + s16 rv[4]; /* sp+0x18 */ + u16 sxy[2]; /* sp+0x20 */ + s32 z; /* sp+0x24 */ + s32 flag; /* sp+0x28 */ + } L; + + s32 g; + s32 s0; + s32 i; + + g = D_801151D4; + + if (*(s16 *)(a0 + 0xFC) == 0) { + s0 = func_8012C658(0x33, 3, a0); + if (s0 != 0) { + *(u16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(u16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) - 8; + *(u16 *)(s0 + 0x1A) = *(u16 *)(s0 + 0x1A) - 5; + } + s0 = func_8012C658(0x33, 3, a0); + if (s0 != 0) { + *(u16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(u16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) - 8; + *(u16 *)(s0 + 0x1A) = *(u16 *)(s0 + 0x1A) + 5; + } + s0 = func_8012C658(0x32, 2, a0); + if (s0 != 0) { + *(u16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(u16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) + 8; + } + func_8002AC00(0x22); + + s0 = *(s32 *)(a0 + 0xCC); + *(s16 *)(s0 + 0x2) = 2; + *(s16 *)(s0 + 0xFC) = 1; + s0 = *(s32 *)(a0 + 0xD0); + *(s16 *)(s0 + 0x2) = 2; + *(s16 *)(s0 + 0xFC) = 1; + + for (i = 0; i < 8; i++) { + s0 = func_8012C588(0x281, a0); + if (s0 != 0) { + *(s32 *)(s0 + 0x1C) = 2; + *(u16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x30; + *(s16 *)(s0 + 0x12) = (rand() & 0x1F) - 0x10; + *(s16 *)(s0 + 0x16) = -((rand() & 0xF) + 0x10); + *(s16 *)(s0 + 0x1A) = (rand() & 0x1F) - 0x10; + } + } + + L.rv[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48); + L.rv[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C); + L.rv[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50); + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); } + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); } + RotTransPers((s32)L.rv, (s32)L.sxy, &L.z, &L.flag); + if (L.flag >= 0 && (u32)((L.sxy[0] + 0xEF) & 0xFFFF) < 0x1DF + && (u32)((L.sxy[1] + 0xB3) & 0xFFFF) < 0x167) { + s32 x = (s16)L.sxy[0]; + s32 ax; + + ax = x; + if (x < 0) { + ax = -x; + } + ax = ((0xF0 - ax) * 0x7F) / 0xF0; + __asm__("" : "=r"(ax) : "0"(ax)); + x = (x + 0xF0) / 0x1E; + if (x == 0x10) { + x = 0xF; + } + x = x << 8; + { + s32 flg = 0x3000; + func_8002D4C8(0x961, ((ax | flg) | x) & 0xFFFF); + } + } + func_8002A04C(a0); + func_8012C218((void *)a0); + } else { + s0 = (s32)func_8012913C(0x23); + if (s0 != 0) { + *(s16 *)(s0 + 0x6) = *(u16 *)(a0 + 0x6) + (rand() & 0x7F) - 0x40; + *(s16 *)(s0 + 0xA) = *(u16 *)(a0 + 0xA) + (rand() & 0x7F) - 0xE0; + { + s32 r = rand(); + s32 t = *(u16 *)(a0 + 0xE); + *(s16 *)(s0 + 0x34) = 0x1800; + *(s32 *)(s0 + 0x18) = 0; + *(s32 *)(s0 + 0x14) = 0; + *(s32 *)(s0 + 0x10) = 0; + *(s16 *)(s0 + 0xE) = t + (r & 0x7F) - 0x40; + } + L.nv[0] = *(s32 *)(g + 0x5C) - *(u16 *)(s0 + 0x6); + L.nv[1] = *(s32 *)(g + 0x60) - *(u16 *)(s0 + 0xA); + L.nv[2] = *(s32 *)(g + 0x64) - *(u16 *)(s0 + 0xE); + VectorNormalSS(L.nv, L.nv); + *(s16 *)(s0 + 0x6) = *(u16 *)(s0 + 0x6) + ((s16)L.nv[0] >> 6); + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) + ((s16)L.nv[1] >> 6); + *(s16 *)(s0 + 0xE) = *(u16 *)(s0 + 0xE) + ((s16)L.nv[2] >> 6); + *(s16 *)(s0 + 0x34) = 0x3000; + func_8002D4C8(0xAF8, 0); + } + *(u16 *)(a0 + 0xFC) = *(u16 *)(a0 + 0xFC) - 1; + } +} + INCLUDE_ASM("asm/ov_SC06_008/nonmatchings/ov_SC06_008_jr_8017C294", func_801810AC); @@ -4119,7 +4272,172 @@ big: INCLUDE_ASM("asm/ov_SC06_008/nonmatchings/ov_SC06_008_jr_8017C294", func_801813D0); -INCLUDE_ASM("asm/ov_SC06_008/nonmatchings/ov_SC06_008_jr_8017C294", func_8018165C); +#include "common.h" + +/* func_8018165C — ov_SC06_008 jr_8017C294 (family of 7). MATCH 305/305. + * + * §136c sibling-first paid for the whole body: the RTP + positional-sound tail + * is the byte-proven RTP_SND block from + * src/ov_SC06_030/ov_SC06_030_jr_8017C8D0.c:3480 (func_8017E120) plus the + * panner from src/ov_SC03_103/ov_SC03_103_jr_8017C294.c:5378 (func_801819DC): + * - $a0-pinned scopes REMATERIALISE &D_800AF648 per call (else CSE hoists it + * into a callee-saved reg and shoves the actor out of $s0), + * - `u16 sxy[2]` + `(u32)((sxy[i] + K) & 0xFFFF) < N` range tests (u32 cast + * is what keeps the compare `sltiu` rather than `slt`), + * - `ax = x; if (x < 0) ax = -x;` — the branch must test x, NOT ax, so reorg + * can sink the copy into the bgez delay slot, + * - the zero-byte re-tie `__asm__("" : "=r"(v) : "0"(v))` after the vol + * divide: both divides share one HI/LO and priority is height-to-block-end, + * so without it the pan quotient (which feeds the `bne`) issues first, + * - the pan quotient REUSES `x`'s pseudo (target `subu $a2,$v0,$a0`), + * - 0x3000 in a local `flg` so fold cannot reassociate the `ori` onto the pan, + * and the OR stays inside the call ARGUMENT. + * §88a: both copies are written LONGHAND via the macro; gcc cross-jumps the + * common 4-insn suffix itself (target `.L80181A20`). + * + * Four deltas from the SC03_103 twin, each measured here: + * 1. NO hard-register pin on the abs result — instead `ax` and `vol` are ONE + * variable. The twin pins ax to $a1 and keeps vol separate; this target + * wants BOTH in $v1 (`addu $v1,$a2,$zero` … `subu $v1,$v0,$v1`), which one + * variable gives for free. Pinning it to $3 instead makes `ax` a hard reg, + * and then local-alloc's combine_regs ties the tail's `ori` dest to the + * dying $v1 (`ori $v1,$v1,0x3000`) — the target has `ori $a1,$v1,0x3000`. + * A plain pseudo is a GLOBAL allocno, which combine_regs will not tie. (21 + * -> 11 -> 8 mismatches across the two spellings.) + * 2. ONE local for the sprite angle AND the mod-16 index. Two locals put the + * index in $s1 (reusing the dead sprite pointer); one gives the target's + * $s2 (§136 L1 inverted — MERGING, not splitting). + * 3. ONE local `p` for the 0xCC/0xD0 child pointers, used in BOTH branches. + * In the else-branch it is a call argument, so regclass's arg-copy + * preference pulls the whole allocno to $a0 and frees $v0 for the constant + * 1 (`addiu $v0,$zero,1` / `lw $a0,0xCC($s0)`). Confined to the then-branch + * it wins $v0 on priority and the constant falls to $v1 (8 off). + * 4. STORE ORDER: `*(spr+0x14) = 0x40000` must be written AFTER the 0xE + * statement. Written before it, it lands ahead of the `jal func_80047948` + * and frees the next call's `addu $a0,$s2,$zero` early enough for reorg to + * eat the bgez delay slot (-1 ins). After it, the scheduler hoists the + * lui/sw pair inside .L80181724 by itself (idiom 4 / S1: same-base + * `reg+const` stores are disambiguated, so the hoist is free). + * Idiom 6: 8 bytes of dead aggregate precede L.v so the RTP block sits at + * sp+0x18 (vars 0x20 => frame 0x40). + * + * Decls: func_8002D4C8 / func_8004787C / func_80047948 / func_8004914C / + * func_800491AC / func_8012A828 / func_8012913C are copied VERBATIM from the TU + * (lines 59, 2205, 2204, 2645, 2646, 3781, 4356). RotTransPers, D_800AF648 and + * D_8019ED14 appear nowhere in the TU (fleet-dominant forms used); the three + * D_801A6xxx tables are declared BLOCK-scope exactly as func_80181220 does. + */ + +extern u8 *func_8012913C(); +extern s32 func_8004787C(s32 a0); +extern s32 func_80047948(s32 a0); +extern void func_8004914C(void *a0); +extern void func_800491AC(void *a0); +extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3); +extern void func_8002D4C8(s32 a0, s32 a1); +extern void func_8012A828(s32 a0, void *a1); + +#define RTP_SND(sndid) \ + L.v[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48); \ + L.v[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C); \ + L.v[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50); \ + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); } \ + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); } \ + RotTransPers((s32)L.v, (s32)L.sxy, &L.z, &L.flag); \ + if (L.flag >= 0 && (u32)((L.sxy[0] + 0xEF) & 0xFFFF) < 0x1DF \ + && (u32)((L.sxy[1] + 0xB3) & 0xFFFF) < 0x167) { \ + s32 x = (s16)L.sxy[0]; \ + s32 ax; \ + ax = x; \ + if (x < 0) { \ + ax = -x; \ + } \ + ax = ((0xF0 - ax) * 0x7F) / 0xF0; \ + __asm__("" : "=r"(ax) : "0"(ax)); \ + x = (x + 0xF0) / 0x1E; \ + if (x == 0x10) { \ + x = 0xF; \ + } \ + x = x << 8; \ + { \ + s32 flg = 0x3000; \ + func_8002D4C8(sndid, ((ax | flg) | x) & 0xFFFF); \ + } \ + } + +void func_8018165C(s32 a0) { + + extern u8 D_800AF648; + extern s32 D_8019ED14[]; + extern u8 D_801A61D4[]; + extern u8 D_801A625C[]; + extern u8 D_801A62E4[]; + struct { + s16 pad0[4]; /* sp+0x10 — dead, but sizes the frame (idiom 6) */ + s16 v[3]; /* sp+0x18 */ + s16 pad1; /* sp+0x1E */ + u16 sxy[2]; /* sp+0x20 */ + s32 z; /* sp+0x24 */ + s32 flag; /* sp+0x28 */ + } L; + s32 t; + s32 ang; + s32 idx; + s32 m; + s32 c; + s32 p; + + if (*(s16 *)(a0 + 0x98) == 0) { + s32 spr = (s32)func_8012913C(0x7F); + if (spr != 0) { + m = *(s16 *)(*(s32 *)(a0 + 0x20) + 0x12) + + (func_8004787C(*(s16 *)(a0 + 0x104)) >> 3); + *(s16 *)(spr + 0x6) = *(u16 *)(a0 + 0x6) - (func_8004787C(m) * 0x6C) / 0x1000; + *(s16 *)(spr + 0xA) = *(u16 *)(a0 + 0xA) - 0x34; + *(s16 *)(spr + 0xE) = *(u16 *)(a0 + 0xE) - (func_80047948(m) * 0x6C) / 0x1000; + *(s32 *)(spr + 0x14) = 0x40000; + *(s32 *)(spr + 0x10) = -(func_8004787C(m) * 0xC0); + *(s32 *)(spr + 0x18) = -(func_80047948(m) * 0xC0); + } + t = *(u16 *)(a0 + 0x104) + 0x100; + *(s16 *)(a0 + 0x104) = t; + ang = (s16)t; + idx = ang / 0x100; + m = (s16)(idx % 0x10); + if (ang == 0x100) { + RTP_SND(0x95F) + } else if (m == 0) { + RTP_SND(0x960) + } + *(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) = D_8019ED14[m]; + c = *(u16 *)(a0 + 0x100) - 1; + *(s16 *)(a0 + 0x100) = c; + if ((s16)c == 0) { + p = *(s32 *)(a0 + 0xCC); + *(s16 *)(a0 + 0x98) = 1; + if (p != 0) { + *(s16 *)(p + 0x98) = 1; + } + p = *(s32 *)(a0 + 0xD0); + if (p != 0) { + *(s16 *)(p + 0x98) = 1; + } + } + } else if ((*(u16 *)(a0 + 0x72) & 0x4000) != 0) { + *(s16 *)(a0 + 0x2) = 7; + *(s16 *)(a0 + 0x100) = 0x3C; + func_8012A828(a0, D_801A61D4); + p = *(s32 *)(a0 + 0xCC); + if (p != 0) { + func_8012A828(p, D_801A625C); + } + p = *(s32 *)(a0 + 0xD0); + if (p != 0) { + func_8012A828(p, D_801A62E4); + } + } +} + INCLUDE_ASM("asm/ov_SC06_008/nonmatchings/ov_SC06_008_jr_8017C294", func_80181B20); @@ -4209,7 +4527,146 @@ void func_801821F8(int param_1) } -INCLUDE_ASM("asm/ov_SC06_008/nonmatchings/ov_SC06_008_jr_8017C294", func_801823F0); +extern s32 D_801151D4; + +extern s32 func_8012C658(s32 arg0, s32 arg1, s32 arg2); +extern s32 func_8012C588(s32 a0, s32 a1); +extern void func_8012C218(void *a0); +extern u8 *func_8012913C(s32 a0); +extern s32 func_80047948(s32 a0); +extern s32 func_8004787C(s32 a0); +extern void func_8004914C(void *a0); +extern void func_800491AC(void *a0); +extern s32 VectorNormalSS(void *a0, void *a1); +extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3); +extern void func_8002D4C8(s32 a0, s32 a1); +extern s32 rand(void); + +void func_801823F0(s32 a0) { + + extern void func_8002AC00(s32 arg0); + extern void func_8002A04C(s32 arg0); + extern u8 D_800AF648; + + u16 v10[4]; /* sp+0x10 */ + s16 v18[4]; /* sp+0x18 */ + s32 sxy; /* sp+0x20 */ + s32 z; /* sp+0x24 */ + s32 flag; /* sp+0x28 */ + s32 base; + s32 iv; + s32 i; + s32 t; + s32 r; + + base = D_801151D4; + + if (*(s16 *)(a0 + 0xFC) >= 0x1F) { + iv = func_8012C658(0x33, 3, a0); + if (iv != 0) { + *(u16 *)(iv + 0x0A) = *(u16 *)(iv + 0x0A) - 0x20; + *(u16 *)(iv + 0x12) = *(u16 *)(iv + 0x12) - 8; + *(u16 *)(iv + 0x1A) = *(u16 *)(iv + 0x1A) - 5; + } + iv = func_8012C658(0x33, 3, a0); + if (iv != 0) { + *(u16 *)(iv + 0x0A) = *(u16 *)(iv + 0x0A) - 0x20; + *(u16 *)(iv + 0x12) = *(u16 *)(iv + 0x12) - 8; + *(u16 *)(iv + 0x1A) = *(u16 *)(iv + 0x1A) + 5; + } + iv = func_8012C658(0x32, 2, a0); + if (iv != 0) { + *(u16 *)(iv + 0x0A) = *(u16 *)(iv + 0x0A) - 0x20; + *(u16 *)(iv + 0x12) = *(u16 *)(iv + 0x12) + 8; + } + + func_8002AC00(0x22); + + iv = *(s32 *)(a0 + 0x64); + *(s16 *)(iv + 2) = 2; + iv = *(s32 *)(*(s32 *)(a0 + 0x64) + 0xD0); + *(s16 *)(iv + 2) = 4; + *(s32 *)(*(s32 *)(a0 + 0x64) + 0xCC) = 0; + + i = 0; + do { + iv = func_8012C588(0x281, a0); + if (iv != 0) { + *(s32 *)(iv + 0x1C) = 2; + *(s16 *)(iv + 0x12) = (rand() & 0x1F) - 0x10; + *(s16 *)(iv + 0x16) = -((rand() & 0x0F) + 0x10); + *(s16 *)(iv + 0x1A) = (rand() & 0x1F) - 0x10; + } + i++; + } while (i < 8); + + v18[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48); + v18[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C); + v18[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50); + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); } + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); } + RotTransPers((s32)v18, (s32)&sxy, &z, &flag); + if (flag >= 0 && (u32)((*(u16 *)&sxy + 0xEF) & 0xFFFF) < 0x1DF + && (u32)((*((u16 *)&sxy + 1) + 0xB3) & 0xFFFF) < 0x167) { + s32 sx; + s32 av; + + sx = (s16)*(u16 *)&sxy; + av = sx; + if (sx < 0) { + av = -sx; + } + /* one local for |x| AND the volume: gcc-2.7.2 keeps the single pseudo + in $v1 in place (subu $v1,$v0,$v1); a separate `vol` local steals $a1 + and the whole OR chain drifts (cookbook §136 L1). */ + av = ((0xF0 - av) * 0x7F) / 0xF0; + sx = (sx + 0xF0) / 0x1E; + if (sx == 0x10) { + sx = 0xF; + } + sx = sx << 8; + func_8002D4C8(0x961, (av | (0x3000 | sx)) & 0xFFFF); + } + + func_8002A04C(a0); + func_8012C218((void *)a0); + return; + } + + iv = (s32)func_8012913C(0x23); + if (iv != 0) { + r = rand(); + *(u16 *)(iv + 0x06) = *(u16 *)(a0 + 0x06) + (r & 0x7F) - 0x40; + r = rand(); + *(u16 *)(iv + 0x0A) = *(u16 *)(a0 + 0x0A) + (r & 0x7F) - 0x80; + r = rand(); + *(u16 *)(iv + 0x0E) = *(u16 *)(a0 + 0x0E) + (r & 0x7F) - 0x40; + + t = func_80047948((s32) * (s16 *)(*(s32 *)(a0 + 0x20) + 0x12)); + *(s32 *)(iv + 0x04) = *(s32 *)(iv + 0x04) + (t << 10); + + t = func_8004787C((s32) * (s16 *)(*(s32 *)(a0 + 0x20) + 0x12)); + *(u16 *)(iv + 0x34) = 0x1800; + *(s32 *)(iv + 0x18) = 0; + *(s32 *)(iv + 0x14) = 0; + *(s32 *)(iv + 0x10) = 0; + *(s32 *)(iv + 0x0C) = *(s32 *)(iv + 0x0C) - (t << 10); + + v10[0] = *(s32 *)(base + 0x5C) - *(u16 *)(iv + 0x06); + v10[1] = *(s32 *)(base + 0x60) - *(u16 *)(iv + 0x0A); + v10[2] = *(s32 *)(base + 0x64) - *(u16 *)(iv + 0x0E); + VectorNormalSS(v10, v10); + + *(u16 *)(iv + 0x06) = *(u16 *)(iv + 0x06) + ((s16)v10[0] >> 6); + *(u16 *)(iv + 0x0A) = *(u16 *)(iv + 0x0A) + ((s16)v10[1] >> 6); + *(u16 *)(iv + 0x0E) = *(u16 *)(iv + 0x0E) + ((s16)v10[2] >> 6); + *(u16 *)(iv + 0x34) = 0x3000; + func_8002D4C8(0xAF8, 0); + } + + *(u16 *)(a0 + 0xFC) = *(u16 *)(a0 + 0xFC) + 1; +} + // @class: struct @@ -4273,7 +4730,143 @@ void func_80182838(short *param_1) } -INCLUDE_ASM("asm/ov_SC06_008/nonmatchings/ov_SC06_008_jr_8017C294", func_80182A48); +#include "common.h" + +extern s32 D_801151D4; + +extern s32 func_8012C658(s32 arg0, s32 arg1, s32 arg2); +extern s32 func_8012C588(s32 a0, s32 a1); +extern void func_8012C218(void *a0); +extern u8 *func_8012913C(); +extern s32 rand(void); +extern s32 func_80047948(s32 a0); +extern s32 func_8004787C(s32 a0); +extern s32 VectorNormalSS(void *a0, void *a1); +extern void func_8004914C(void *a0); +extern void func_800491AC(void *a0); +extern void func_8002D4C8(s32 a0, s32 a1); +extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3); +extern void func_8002A04C(s32 a0); + + +void func_80182A48(s32 a0) { + + extern u8 D_800AF648; + extern void func_8002AC00(s32 arg0); + + struct { + u16 nv[4]; /* sp+0x10 */ + s16 v[4]; /* sp+0x18 */ + u16 sxy[2]; /* sp+0x20 */ + s32 z; /* sp+0x24 */ + s32 flag; /* sp+0x28 */ + } L; + s32 p; + s32 s0; + s32 i; + + p = D_801151D4; + + if (*(s16 *)(a0 + 0xFC) >= 0x1F) { + s0 = func_8012C658(0x33, 3, a0); + if (s0 != 0) { + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(s16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) - 8; + *(s16 *)(s0 + 0x1A) = *(u16 *)(s0 + 0x1A) - 5; + } + s0 = func_8012C658(0x33, 3, a0); + if (s0 != 0) { + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(s16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) - 8; + *(s16 *)(s0 + 0x1A) = *(u16 *)(s0 + 0x1A) + 5; + } + s0 = func_8012C658(0x32, 2, a0); + if (s0 != 0) { + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(s16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) + 8; + } + func_8002AC00(0x22); + s0 = *(s32 *)(a0 + 0x64); + *(s16 *)(s0 + 0x2) = 4; + s0 = *(s32 *)(*(s32 *)(a0 + 0x64) + 0xCC); + *(s16 *)(s0 + 0x2) = 4; + + for (i = 0; i < 8; i++) { + s0 = func_8012C588(0x281, a0); + if (s0 != 0) { + *(s32 *)(s0 + 0x1C) = 2; + *(s16 *)(s0 + 0x12) = (rand() & 0x1F) - 0x10; + *(s16 *)(s0 + 0x16) = -((rand() & 0xF) + 0x10); + *(s16 *)(s0 + 0x1A) = (rand() & 0x1F) - 0x10; + } + } + + L.v[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48); + L.v[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C); + L.v[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50); + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); } + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); } + RotTransPers((s32)L.v, (s32)L.sxy, &L.z, &L.flag); + if (L.flag >= 0 && (u32)((L.sxy[0] + 0xEF) & 0xFFFF) < 0x1DF + && (u32)((L.sxy[1] + 0xB3) & 0xFFFF) < 0x167) { + s32 x = (s16)L.sxy[0]; + s32 ax; + ax = x; + if (x < 0) { + ax = -x; + } + ax = ((0xF0 - ax) * 0x7F) / 0xF0; + __asm__("" : "=r"(ax) : "0"(ax)); + x = (x + 0xF0) / 0x1E; + if (x == 0x10) { + x = 0xF; + } + x = x << 8; + { + s32 flg = 0x3000; + func_8002D4C8(0x961, ((ax | flg) | x) & 0xFFFF); + } + } + + *(s32 *)(*(s32 *)(a0 + 0x64) + 0xD0) = 0; + func_8002A04C(a0); + func_8012C218((void *)a0); + return; + } + + s0 = (s32)func_8012913C(0x23); + if (s0 != 0) { + *(s16 *)(s0 + 0x6) = *(u16 *)(a0 + 0x6) + (rand() & 0x7F) - 0x40; + *(s16 *)(s0 + 0xA) = *(u16 *)(a0 + 0xA) + (rand() & 0x7F) - 0x80; + *(s16 *)(s0 + 0xE) = *(u16 *)(a0 + 0xE) + (rand() & 0x7F) - 0x40; + + *(s32 *)(s0 + 0x4) = + *(s32 *)(s0 + 0x4) - + func_80047948(*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12)) * 0x400; + { + s32 t = func_8004787C(*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12)) * 0x400; + *(s16 *)(s0 + 0x34) = 0x1800; + *(s32 *)(s0 + 0x18) = 0; + *(s32 *)(s0 + 0x14) = 0; + *(s32 *)(s0 + 0x10) = 0; + *(s32 *)(s0 + 0xC) = *(s32 *)(s0 + 0xC) + t; + } + + L.nv[0] = *(s32 *)(p + 0x5C) - *(u16 *)(s0 + 0x6); + L.nv[1] = *(s32 *)(p + 0x60) - *(u16 *)(s0 + 0xA); + L.nv[2] = *(s32 *)(p + 0x64) - *(u16 *)(s0 + 0xE); + VectorNormalSS(L.nv, L.nv); + + *(s16 *)(s0 + 0x6) = *(u16 *)(s0 + 0x6) + ((s16)L.nv[0] >> 6); + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) + ((s16)L.nv[1] >> 6); + *(s16 *)(s0 + 0xE) = *(u16 *)(s0 + 0xE) + ((s16)L.nv[2] >> 6); + *(s16 *)(s0 + 0x34) = 0x3000; + func_8002D4C8(0xAF8, 0); + } + + *(s16 *)(a0 + 0xFC) = *(u16 *)(a0 + 0xFC) + 1; +} + extern s32 rand(void); diff --git a/src/ov_SC06_010/ov_SC06_010_jr_8017A4AC.c b/src/ov_SC06_010/ov_SC06_010_jr_8017A4AC.c index 949caa85c..7210752c5 100644 --- a/src/ov_SC06_010/ov_SC06_010_jr_8017A4AC.c +++ b/src/ov_SC06_010/ov_SC06_010_jr_8017A4AC.c @@ -318,7 +318,6 @@ extern s32 func_80012B04(s32 a0, s32 a1, s32 a2); extern void func_801490F8(s32 a0, s32 a1); extern s32 func_801491C4(s32 a0); extern s32 func_80149184(s32 a0); -extern s32 D_801151D4; extern void func_80149204(s32 *a0); extern void func_80149210(s32 a0, s32 a1); extern s32 func_80149284(s32 *a0, s32 a1); @@ -3161,7 +3160,6 @@ void func_8017B7A8(void) -extern s32 D_801151D4; extern s16 D_801B2014; extern s16 D_801B2016; extern s16 D_801B2018; @@ -3170,6 +3168,10 @@ extern s16 D_801B201E; extern s16 D_801B2020; void func_8017B824(void) { + /* [T51] scoped in from file scope: a file-scope decl of these symbols constrains every + LATER function in this TU, which blocks a byte-true decl of a different type. + Declaration-only move (cookbook §103); the whole-binary byte-gate is the arbiter. */ + extern s32 D_801151D4; D_801B2014 = (s16) M2C_FIELD(D_801151D4, s32 *, 0x48); D_801B2016 = (s16) M2C_FIELD(D_801151D4, s32 *, 0x4C); D_801B2018 = (s16) M2C_FIELD(D_801151D4, s32 *, 0x50); @@ -5110,7 +5112,163 @@ docopy: } -INCLUDE_ASM("asm/ov_SC06_010/nonmatchings/ov_SC06_010_jr_8017A4AC", func_8018315C); + + +/* func_8018315C — ov_SC06_008 / ov_SC06_008_jr_8017C294 + * + * Two-arm actor tick keyed on the s16 countdown at actor+0xFC: + * arm A (counter == 0, the FALL-THROUGH / longer block): three func_8012C658 + * spawns with offset pokes, a sound cue, two child-actor state pokes, an + * 8-iteration 0x281 particle burst, then the RTP positional-sound block + * (the byte-proven RTP_SND shape from ov_SC03_099_jr_8017BEBC.c:5406). + * arm B (counter != 0): a func_8012913C(0x23) spawn scattered around the + * actor, VectorNormalSS toward D_801151D4->{0x5C,0x60,0x64}, sound 0xAF8. + * + * Declarations copied VERBATIM from the TU (one-pass grep, D2): + * D_801151D4 src/ov_SC06_008/ov_SC06_008_jr_8017C294.c:323 + * rand :956 + * VectorNormalSS :1849 + * func_8012C658 :2523 + * func_8012C588 :3767 + * func_8012C218 :3782 + * func_8002D4C8 :59 + * func_8004914C :2645 + * func_800491AC :2646 + * func_8012913C :4356 (non-prototype form, BELOW the splice point) + * func_8002AC00 :5447 (block-scope extern only) + * RotTransPers / D_800AF648 / func_8002A04C are not in this TU -> fleet-dominant forms. + */ + +extern s32 rand(void); +extern s32 VectorNormalSS(void *a0, void *a1); +extern s32 func_8012C658(s32 arg0, s32 arg1, s32 arg2); +extern s32 func_8012C588(s32 a0, s32 a1); +extern void func_8012C218(void *a0); +extern void func_8002D4C8(s32 a0, s32 a1); +extern void func_8004914C(void *a0); +extern void func_800491AC(void *a0); +extern void func_8002A04C(s32 a0); +extern void func_8002AC00(s32 a0); +extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3); +extern u8 *func_8012913C(); + +void func_8018315C(s32 a0) +{ + + extern s32 D_801151D4; + extern u8 D_800AF648; + + /* L5: slot offsets are exact only through ONE struct — plain array locals + get 8-byte-rounded slots and pushed z/flag to 0x28/0x2C (measured). */ + struct { + u16 nv[4]; /* sp+0x10 */ + s16 rv[4]; /* sp+0x18 */ + u16 sxy[2]; /* sp+0x20 */ + s32 z; /* sp+0x24 */ + s32 flag; /* sp+0x28 */ + } L; + + s32 g; + s32 s0; + s32 i; + + g = D_801151D4; + + if (*(s16 *)(a0 + 0xFC) == 0) { + s0 = func_8012C658(0x33, 3, a0); + if (s0 != 0) { + *(u16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(u16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) - 8; + *(u16 *)(s0 + 0x1A) = *(u16 *)(s0 + 0x1A) - 5; + } + s0 = func_8012C658(0x33, 3, a0); + if (s0 != 0) { + *(u16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(u16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) - 8; + *(u16 *)(s0 + 0x1A) = *(u16 *)(s0 + 0x1A) + 5; + } + s0 = func_8012C658(0x32, 2, a0); + if (s0 != 0) { + *(u16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(u16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) + 8; + } + func_8002AC00(0x22); + + s0 = *(s32 *)(a0 + 0xCC); + *(s16 *)(s0 + 0x2) = 2; + *(s16 *)(s0 + 0xFC) = 1; + s0 = *(s32 *)(a0 + 0xD0); + *(s16 *)(s0 + 0x2) = 2; + *(s16 *)(s0 + 0xFC) = 1; + + for (i = 0; i < 8; i++) { + s0 = func_8012C588(0x281, a0); + if (s0 != 0) { + *(s32 *)(s0 + 0x1C) = 2; + *(u16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x30; + *(s16 *)(s0 + 0x12) = (rand() & 0x1F) - 0x10; + *(s16 *)(s0 + 0x16) = -((rand() & 0xF) + 0x10); + *(s16 *)(s0 + 0x1A) = (rand() & 0x1F) - 0x10; + } + } + + L.rv[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48); + L.rv[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C); + L.rv[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50); + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); } + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); } + RotTransPers((s32)L.rv, (s32)L.sxy, &L.z, &L.flag); + if (L.flag >= 0 && (u32)((L.sxy[0] + 0xEF) & 0xFFFF) < 0x1DF + && (u32)((L.sxy[1] + 0xB3) & 0xFFFF) < 0x167) { + s32 x = (s16)L.sxy[0]; + s32 ax; + + ax = x; + if (x < 0) { + ax = -x; + } + ax = ((0xF0 - ax) * 0x7F) / 0xF0; + __asm__("" : "=r"(ax) : "0"(ax)); + x = (x + 0xF0) / 0x1E; + if (x == 0x10) { + x = 0xF; + } + x = x << 8; + { + s32 flg = 0x3000; + func_8002D4C8(0x961, ((ax | flg) | x) & 0xFFFF); + } + } + func_8002A04C(a0); + func_8012C218((void *)a0); + } else { + s0 = (s32)func_8012913C(0x23); + if (s0 != 0) { + *(s16 *)(s0 + 0x6) = *(u16 *)(a0 + 0x6) + (rand() & 0x7F) - 0x40; + *(s16 *)(s0 + 0xA) = *(u16 *)(a0 + 0xA) + (rand() & 0x7F) - 0xE0; + { + s32 r = rand(); + s32 t = *(u16 *)(a0 + 0xE); + *(s16 *)(s0 + 0x34) = 0x1800; + *(s32 *)(s0 + 0x18) = 0; + *(s32 *)(s0 + 0x14) = 0; + *(s32 *)(s0 + 0x10) = 0; + *(s16 *)(s0 + 0xE) = t + (r & 0x7F) - 0x40; + } + L.nv[0] = *(s32 *)(g + 0x5C) - *(u16 *)(s0 + 0x6); + L.nv[1] = *(s32 *)(g + 0x60) - *(u16 *)(s0 + 0xA); + L.nv[2] = *(s32 *)(g + 0x64) - *(u16 *)(s0 + 0xE); + VectorNormalSS(L.nv, L.nv); + *(s16 *)(s0 + 0x6) = *(u16 *)(s0 + 0x6) + ((s16)L.nv[0] >> 6); + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) + ((s16)L.nv[1] >> 6); + *(s16 *)(s0 + 0xE) = *(u16 *)(s0 + 0xE) + ((s16)L.nv[2] >> 6); + *(s16 *)(s0 + 0x34) = 0x3000; + func_8002D4C8(0xAF8, 0); + } + *(u16 *)(a0 + 0xFC) = *(u16 *)(a0 + 0xFC) - 1; + } +} + INCLUDE_ASM("asm/ov_SC06_010/nonmatchings/ov_SC06_010_jr_8017A4AC", func_80183560); @@ -5189,7 +5347,114 @@ big: INCLUDE_ASM("asm/ov_SC06_010/nonmatchings/ov_SC06_010_jr_8017A4AC", func_80183884); -INCLUDE_ASM("asm/ov_SC06_010/nonmatchings/ov_SC06_010_jr_8017A4AC", func_80183B10); +extern void func_8002D4C8(s32 a0, s32 a1); +extern s32 func_8004787C(s32 a0); +extern s32 func_80047948(s32 a0); +extern void func_8004914C(); +extern void func_800491AC(); +extern u8 *func_8012913C(s32 a0); +extern void func_8012A828(s32 a0, void * a1); +#define RTP_SND(sndid) \ + L.v[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48); \ + L.v[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C); \ + L.v[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50); \ + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); } \ + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); } \ + RotTransPers((s32)L.v, (s32)L.sxy, &L.z, &L.flag); \ + if (L.flag >= 0 && (u32)((L.sxy[0] + 0xEF) & 0xFFFF) < 0x1DF \ + && (u32)((L.sxy[1] + 0xB3) & 0xFFFF) < 0x167) { \ + s32 x = (s16)L.sxy[0]; \ + s32 ax; \ + ax = x; \ + if (x < 0) { \ + ax = -x; \ + } \ + ax = ((0xF0 - ax) * 0x7F) / 0xF0; \ + __asm__("" : "=r"(ax) : "0"(ax)); \ + x = (x + 0xF0) / 0x1E; \ + if (x == 0x10) { \ + x = 0xF; \ + } \ + x = x << 8; \ + { \ + s32 flg = 0x3000; \ + func_8002D4C8(sndid, ((ax | flg) | x) & 0xFFFF); \ + } \ + } + +void func_80183B10(s32 a0) { + + extern u8 D_800AF648; + extern s32 D_801A7008[]; + extern u8 D_801AE4C8[]; + extern u8 D_801AE550[]; + extern u8 D_801AE5D8[]; + struct { + s16 pad0[4]; /* sp+0x10 — dead, but sizes the frame (idiom 6) */ + s16 v[3]; /* sp+0x18 */ + s16 pad1; /* sp+0x1E */ + u16 sxy[2]; /* sp+0x20 */ + s32 z; /* sp+0x24 */ + s32 flag; /* sp+0x28 */ + } L; + s32 t; + s32 ang; + s32 idx; + s32 m; + s32 c; + s32 p; + + if (*(s16 *)(a0 + 0x98) == 0) { + s32 spr = (s32)func_8012913C(0x7F); + if (spr != 0) { + m = *(s16 *)(*(s32 *)(a0 + 0x20) + 0x12) + + (func_8004787C(*(s16 *)(a0 + 0x104)) >> 3); + *(s16 *)(spr + 0x6) = *(u16 *)(a0 + 0x6) - (func_8004787C(m) * 0x6C) / 0x1000; + *(s16 *)(spr + 0xA) = *(u16 *)(a0 + 0xA) - 0x34; + *(s16 *)(spr + 0xE) = *(u16 *)(a0 + 0xE) - (func_80047948(m) * 0x6C) / 0x1000; + *(s32 *)(spr + 0x14) = 0x40000; + *(s32 *)(spr + 0x10) = -(func_8004787C(m) * 0xC0); + *(s32 *)(spr + 0x18) = -(func_80047948(m) * 0xC0); + } + t = *(u16 *)(a0 + 0x104) + 0x100; + *(s16 *)(a0 + 0x104) = t; + ang = (s16)t; + idx = ang / 0x100; + m = (s16)(idx % 0x10); + if (ang == 0x100) { + RTP_SND(0x95F) + } else if (m == 0) { + RTP_SND(0x960) + } + *(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) = D_801A7008[m]; + c = *(u16 *)(a0 + 0x100) - 1; + *(s16 *)(a0 + 0x100) = c; + if ((s16)c == 0) { + p = *(s32 *)(a0 + 0xCC); + *(s16 *)(a0 + 0x98) = 1; + if (p != 0) { + *(s16 *)(p + 0x98) = 1; + } + p = *(s32 *)(a0 + 0xD0); + if (p != 0) { + *(s16 *)(p + 0x98) = 1; + } + } + } else if ((*(u16 *)(a0 + 0x72) & 0x4000) != 0) { + *(s16 *)(a0 + 0x2) = 7; + *(s16 *)(a0 + 0x100) = 0x3C; + func_8012A828(a0, D_801AE4C8); + p = *(s32 *)(a0 + 0xCC); + if (p != 0) { + func_8012A828(p, D_801AE550); + } + p = *(s32 *)(a0 + 0xD0); + if (p != 0) { + func_8012A828(p, D_801AE5D8); + } + } +} + INCLUDE_ASM("asm/ov_SC06_010/nonmatchings/ov_SC06_010_jr_8017A4AC", func_80183FD4); @@ -5279,7 +5544,149 @@ void func_801846AC(int param_1) } -INCLUDE_ASM("asm/ov_SC06_010/nonmatchings/ov_SC06_010_jr_8017A4AC", func_801848A4); + + + +extern s32 func_8012C658(s32 arg0, s32 arg1, s32 arg2); +extern s32 func_8012C588(s32 a0, s32 a1); +extern void func_8012C218(void *a0); +extern u8 *func_8012913C(s32 a0); +extern s32 func_80047948(s32 a0); +extern s32 func_8004787C(s32 a0); +extern void func_8004914C(void *a0); +extern void func_800491AC(void *a0); +extern s32 VectorNormalSS(void *a0, void *a1); +extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3); +extern void func_8002D4C8(s32 a0, s32 a1); +extern s32 rand(void); + +void func_801848A4(s32 a0) { + + extern s32 D_801151D4; + + extern void func_8002AC00(s32 arg0); + extern void func_8002A04C(s32 arg0); + extern u8 D_800AF648; + + u16 v10[4]; /* sp+0x10 */ + s16 v18[4]; /* sp+0x18 */ + s32 sxy; /* sp+0x20 */ + s32 z; /* sp+0x24 */ + s32 flag; /* sp+0x28 */ + s32 base; + s32 iv; + s32 i; + s32 t; + s32 r; + + base = D_801151D4; + + if (*(s16 *)(a0 + 0xFC) >= 0x1F) { + iv = func_8012C658(0x33, 3, a0); + if (iv != 0) { + *(u16 *)(iv + 0x0A) = *(u16 *)(iv + 0x0A) - 0x20; + *(u16 *)(iv + 0x12) = *(u16 *)(iv + 0x12) - 8; + *(u16 *)(iv + 0x1A) = *(u16 *)(iv + 0x1A) - 5; + } + iv = func_8012C658(0x33, 3, a0); + if (iv != 0) { + *(u16 *)(iv + 0x0A) = *(u16 *)(iv + 0x0A) - 0x20; + *(u16 *)(iv + 0x12) = *(u16 *)(iv + 0x12) - 8; + *(u16 *)(iv + 0x1A) = *(u16 *)(iv + 0x1A) + 5; + } + iv = func_8012C658(0x32, 2, a0); + if (iv != 0) { + *(u16 *)(iv + 0x0A) = *(u16 *)(iv + 0x0A) - 0x20; + *(u16 *)(iv + 0x12) = *(u16 *)(iv + 0x12) + 8; + } + + func_8002AC00(0x22); + + iv = *(s32 *)(a0 + 0x64); + *(s16 *)(iv + 2) = 2; + iv = *(s32 *)(*(s32 *)(a0 + 0x64) + 0xD0); + *(s16 *)(iv + 2) = 4; + *(s32 *)(*(s32 *)(a0 + 0x64) + 0xCC) = 0; + + i = 0; + do { + iv = func_8012C588(0x281, a0); + if (iv != 0) { + *(s32 *)(iv + 0x1C) = 2; + *(s16 *)(iv + 0x12) = (rand() & 0x1F) - 0x10; + *(s16 *)(iv + 0x16) = -((rand() & 0x0F) + 0x10); + *(s16 *)(iv + 0x1A) = (rand() & 0x1F) - 0x10; + } + i++; + } while (i < 8); + + v18[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48); + v18[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C); + v18[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50); + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); } + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); } + RotTransPers((s32)v18, (s32)&sxy, &z, &flag); + if (flag >= 0 && (u32)((*(u16 *)&sxy + 0xEF) & 0xFFFF) < 0x1DF + && (u32)((*((u16 *)&sxy + 1) + 0xB3) & 0xFFFF) < 0x167) { + s32 sx; + s32 av; + + sx = (s16)*(u16 *)&sxy; + av = sx; + if (sx < 0) { + av = -sx; + } + /* one local for |x| AND the volume: gcc-2.7.2 keeps the single pseudo + in $v1 in place (subu $v1,$v0,$v1); a separate `vol` local steals $a1 + and the whole OR chain drifts (cookbook §136 L1). */ + av = ((0xF0 - av) * 0x7F) / 0xF0; + sx = (sx + 0xF0) / 0x1E; + if (sx == 0x10) { + sx = 0xF; + } + sx = sx << 8; + func_8002D4C8(0x961, (av | (0x3000 | sx)) & 0xFFFF); + } + + func_8002A04C(a0); + func_8012C218((void *)a0); + return; + } + + iv = (s32)func_8012913C(0x23); + if (iv != 0) { + r = rand(); + *(u16 *)(iv + 0x06) = *(u16 *)(a0 + 0x06) + (r & 0x7F) - 0x40; + r = rand(); + *(u16 *)(iv + 0x0A) = *(u16 *)(a0 + 0x0A) + (r & 0x7F) - 0x80; + r = rand(); + *(u16 *)(iv + 0x0E) = *(u16 *)(a0 + 0x0E) + (r & 0x7F) - 0x40; + + t = func_80047948((s32) * (s16 *)(*(s32 *)(a0 + 0x20) + 0x12)); + *(s32 *)(iv + 0x04) = *(s32 *)(iv + 0x04) + (t << 10); + + t = func_8004787C((s32) * (s16 *)(*(s32 *)(a0 + 0x20) + 0x12)); + *(u16 *)(iv + 0x34) = 0x1800; + *(s32 *)(iv + 0x18) = 0; + *(s32 *)(iv + 0x14) = 0; + *(s32 *)(iv + 0x10) = 0; + *(s32 *)(iv + 0x0C) = *(s32 *)(iv + 0x0C) - (t << 10); + + v10[0] = *(s32 *)(base + 0x5C) - *(u16 *)(iv + 0x06); + v10[1] = *(s32 *)(base + 0x60) - *(u16 *)(iv + 0x0A); + v10[2] = *(s32 *)(base + 0x64) - *(u16 *)(iv + 0x0E); + VectorNormalSS(v10, v10); + + *(u16 *)(iv + 0x06) = *(u16 *)(iv + 0x06) + ((s16)v10[0] >> 6); + *(u16 *)(iv + 0x0A) = *(u16 *)(iv + 0x0A) + ((s16)v10[1] >> 6); + *(u16 *)(iv + 0x0E) = *(u16 *)(iv + 0x0E) + ((s16)v10[2] >> 6); + *(u16 *)(iv + 0x34) = 0x3000; + func_8002D4C8(0xAF8, 0); + } + + *(u16 *)(a0 + 0xFC) = *(u16 *)(a0 + 0xFC) + 1; +} + // @class: struct @@ -5343,7 +5750,143 @@ void func_80184CEC(short *param_1) } -INCLUDE_ASM("asm/ov_SC06_010/nonmatchings/ov_SC06_010_jr_8017A4AC", func_80184EFC); + + +extern s32 func_8012C658(s32 arg0, s32 arg1, s32 arg2); +extern s32 func_8012C588(s32 a0, s32 a1); +extern void func_8012C218(void *a0); +extern u8 *func_8012913C(); +extern s32 rand(void); +extern s32 func_80047948(s32 a0); +extern s32 func_8004787C(s32 a0); +extern s32 VectorNormalSS(void *a0, void *a1); +extern void func_8004914C(void *a0); +extern void func_800491AC(void *a0); +extern void func_8002D4C8(s32 a0, s32 a1); +extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3); +extern void func_8002A04C(s32 a0); + + +void func_80184EFC(s32 a0) { + + extern s32 D_801151D4; + + extern u8 D_800AF648; + extern void func_8002AC00(s32 arg0); + + struct { + u16 nv[4]; /* sp+0x10 */ + s16 v[4]; /* sp+0x18 */ + u16 sxy[2]; /* sp+0x20 */ + s32 z; /* sp+0x24 */ + s32 flag; /* sp+0x28 */ + } L; + s32 p; + s32 s0; + s32 i; + + p = D_801151D4; + + if (*(s16 *)(a0 + 0xFC) >= 0x1F) { + s0 = func_8012C658(0x33, 3, a0); + if (s0 != 0) { + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(s16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) - 8; + *(s16 *)(s0 + 0x1A) = *(u16 *)(s0 + 0x1A) - 5; + } + s0 = func_8012C658(0x33, 3, a0); + if (s0 != 0) { + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(s16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) - 8; + *(s16 *)(s0 + 0x1A) = *(u16 *)(s0 + 0x1A) + 5; + } + s0 = func_8012C658(0x32, 2, a0); + if (s0 != 0) { + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(s16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) + 8; + } + func_8002AC00(0x22); + s0 = *(s32 *)(a0 + 0x64); + *(s16 *)(s0 + 0x2) = 4; + s0 = *(s32 *)(*(s32 *)(a0 + 0x64) + 0xCC); + *(s16 *)(s0 + 0x2) = 4; + + for (i = 0; i < 8; i++) { + s0 = func_8012C588(0x281, a0); + if (s0 != 0) { + *(s32 *)(s0 + 0x1C) = 2; + *(s16 *)(s0 + 0x12) = (rand() & 0x1F) - 0x10; + *(s16 *)(s0 + 0x16) = -((rand() & 0xF) + 0x10); + *(s16 *)(s0 + 0x1A) = (rand() & 0x1F) - 0x10; + } + } + + L.v[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48); + L.v[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C); + L.v[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50); + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); } + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); } + RotTransPers((s32)L.v, (s32)L.sxy, &L.z, &L.flag); + if (L.flag >= 0 && (u32)((L.sxy[0] + 0xEF) & 0xFFFF) < 0x1DF + && (u32)((L.sxy[1] + 0xB3) & 0xFFFF) < 0x167) { + s32 x = (s16)L.sxy[0]; + s32 ax; + ax = x; + if (x < 0) { + ax = -x; + } + ax = ((0xF0 - ax) * 0x7F) / 0xF0; + __asm__("" : "=r"(ax) : "0"(ax)); + x = (x + 0xF0) / 0x1E; + if (x == 0x10) { + x = 0xF; + } + x = x << 8; + { + s32 flg = 0x3000; + func_8002D4C8(0x961, ((ax | flg) | x) & 0xFFFF); + } + } + + *(s32 *)(*(s32 *)(a0 + 0x64) + 0xD0) = 0; + func_8002A04C(a0); + func_8012C218((void *)a0); + return; + } + + s0 = (s32)func_8012913C(0x23); + if (s0 != 0) { + *(s16 *)(s0 + 0x6) = *(u16 *)(a0 + 0x6) + (rand() & 0x7F) - 0x40; + *(s16 *)(s0 + 0xA) = *(u16 *)(a0 + 0xA) + (rand() & 0x7F) - 0x80; + *(s16 *)(s0 + 0xE) = *(u16 *)(a0 + 0xE) + (rand() & 0x7F) - 0x40; + + *(s32 *)(s0 + 0x4) = + *(s32 *)(s0 + 0x4) - + func_80047948(*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12)) * 0x400; + { + s32 t = func_8004787C(*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12)) * 0x400; + *(s16 *)(s0 + 0x34) = 0x1800; + *(s32 *)(s0 + 0x18) = 0; + *(s32 *)(s0 + 0x14) = 0; + *(s32 *)(s0 + 0x10) = 0; + *(s32 *)(s0 + 0xC) = *(s32 *)(s0 + 0xC) + t; + } + + L.nv[0] = *(s32 *)(p + 0x5C) - *(u16 *)(s0 + 0x6); + L.nv[1] = *(s32 *)(p + 0x60) - *(u16 *)(s0 + 0xA); + L.nv[2] = *(s32 *)(p + 0x64) - *(u16 *)(s0 + 0xE); + VectorNormalSS(L.nv, L.nv); + + *(s16 *)(s0 + 0x6) = *(u16 *)(s0 + 0x6) + ((s16)L.nv[0] >> 6); + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) + ((s16)L.nv[1] >> 6); + *(s16 *)(s0 + 0xE) = *(u16 *)(s0 + 0xE) + ((s16)L.nv[2] >> 6); + *(s16 *)(s0 + 0x34) = 0x3000; + func_8002D4C8(0xAF8, 0); + } + + *(s16 *)(a0 + 0xFC) = *(u16 *)(a0 + 0xFC) + 1; +} + extern s32 rand(void); diff --git a/src/ov_SC06_018/ov_SC06_018_jr_8017C24C.c b/src/ov_SC06_018/ov_SC06_018_jr_8017C24C.c index 141f2fdc6..8c95e94bf 100644 --- a/src/ov_SC06_018/ov_SC06_018_jr_8017C24C.c +++ b/src/ov_SC06_018/ov_SC06_018_jr_8017C24C.c @@ -320,7 +320,6 @@ extern s32 func_80012B04(s32 a0, s32 a1, s32 a2); extern void func_801490F8(s32 a0, s32 a1); extern s32 func_801491C4(s32 a0); extern s32 func_80149184(s32 a0); -extern s32 D_801151D4; extern void func_80149204(s32 *a0); extern void func_80149210(s32 a0, s32 a1); extern s32 func_80149284(s32 *a0, s32 a1); @@ -4281,7 +4280,163 @@ docopy: } -INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C", func_80180AB4); + + +/* func_80180AB4 — ov_SC06_008 / ov_SC06_008_jr_8017C294 + * + * Two-arm actor tick keyed on the s16 countdown at actor+0xFC: + * arm A (counter == 0, the FALL-THROUGH / longer block): three func_8012C658 + * spawns with offset pokes, a sound cue, two child-actor state pokes, an + * 8-iteration 0x281 particle burst, then the RTP positional-sound block + * (the byte-proven RTP_SND shape from ov_SC03_099_jr_8017BEBC.c:5406). + * arm B (counter != 0): a func_8012913C(0x23) spawn scattered around the + * actor, VectorNormalSS toward D_801151D4->{0x5C,0x60,0x64}, sound 0xAF8. + * + * Declarations copied VERBATIM from the TU (one-pass grep, D2): + * D_801151D4 src/ov_SC06_008/ov_SC06_008_jr_8017C294.c:323 + * rand :956 + * VectorNormalSS :1849 + * func_8012C658 :2523 + * func_8012C588 :3767 + * func_8012C218 :3782 + * func_8002D4C8 :59 + * func_8004914C :2645 + * func_800491AC :2646 + * func_8012913C :4356 (non-prototype form, BELOW the splice point) + * func_8002AC00 :5447 (block-scope extern only) + * RotTransPers / D_800AF648 / func_8002A04C are not in this TU -> fleet-dominant forms. + */ + +extern s32 rand(void); +extern s32 VectorNormalSS(void *a0, void *a1); +extern s32 func_8012C658(s32 arg0, s32 arg1, s32 arg2); +extern s32 func_8012C588(s32 a0, s32 a1); +extern void func_8012C218(void *a0); +extern void func_8002D4C8(s32 a0, s32 a1); +extern void func_8004914C(void *a0); +extern void func_800491AC(void *a0); +extern void func_8002A04C(s32 a0); +extern void func_8002AC00(s32 a0); +extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3); +extern u8 *func_8012913C(); + +void func_80180AB4(s32 a0) +{ + + extern s32 D_801151D4; + extern u8 D_800AF648; + + /* L5: slot offsets are exact only through ONE struct — plain array locals + get 8-byte-rounded slots and pushed z/flag to 0x28/0x2C (measured). */ + struct { + u16 nv[4]; /* sp+0x10 */ + s16 rv[4]; /* sp+0x18 */ + u16 sxy[2]; /* sp+0x20 */ + s32 z; /* sp+0x24 */ + s32 flag; /* sp+0x28 */ + } L; + + s32 g; + s32 s0; + s32 i; + + g = D_801151D4; + + if (*(s16 *)(a0 + 0xFC) == 0) { + s0 = func_8012C658(0x33, 3, a0); + if (s0 != 0) { + *(u16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(u16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) - 8; + *(u16 *)(s0 + 0x1A) = *(u16 *)(s0 + 0x1A) - 5; + } + s0 = func_8012C658(0x33, 3, a0); + if (s0 != 0) { + *(u16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(u16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) - 8; + *(u16 *)(s0 + 0x1A) = *(u16 *)(s0 + 0x1A) + 5; + } + s0 = func_8012C658(0x32, 2, a0); + if (s0 != 0) { + *(u16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(u16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) + 8; + } + func_8002AC00(0x22); + + s0 = *(s32 *)(a0 + 0xCC); + *(s16 *)(s0 + 0x2) = 2; + *(s16 *)(s0 + 0xFC) = 1; + s0 = *(s32 *)(a0 + 0xD0); + *(s16 *)(s0 + 0x2) = 2; + *(s16 *)(s0 + 0xFC) = 1; + + for (i = 0; i < 8; i++) { + s0 = func_8012C588(0x281, a0); + if (s0 != 0) { + *(s32 *)(s0 + 0x1C) = 2; + *(u16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x30; + *(s16 *)(s0 + 0x12) = (rand() & 0x1F) - 0x10; + *(s16 *)(s0 + 0x16) = -((rand() & 0xF) + 0x10); + *(s16 *)(s0 + 0x1A) = (rand() & 0x1F) - 0x10; + } + } + + L.rv[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48); + L.rv[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C); + L.rv[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50); + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); } + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); } + RotTransPers((s32)L.rv, (s32)L.sxy, &L.z, &L.flag); + if (L.flag >= 0 && (u32)((L.sxy[0] + 0xEF) & 0xFFFF) < 0x1DF + && (u32)((L.sxy[1] + 0xB3) & 0xFFFF) < 0x167) { + s32 x = (s16)L.sxy[0]; + s32 ax; + + ax = x; + if (x < 0) { + ax = -x; + } + ax = ((0xF0 - ax) * 0x7F) / 0xF0; + __asm__("" : "=r"(ax) : "0"(ax)); + x = (x + 0xF0) / 0x1E; + if (x == 0x10) { + x = 0xF; + } + x = x << 8; + { + s32 flg = 0x3000; + func_8002D4C8(0x961, ((ax | flg) | x) & 0xFFFF); + } + } + func_8002A04C(a0); + func_8012C218((void *)a0); + } else { + s0 = (s32)func_8012913C(0x23); + if (s0 != 0) { + *(s16 *)(s0 + 0x6) = *(u16 *)(a0 + 0x6) + (rand() & 0x7F) - 0x40; + *(s16 *)(s0 + 0xA) = *(u16 *)(a0 + 0xA) + (rand() & 0x7F) - 0xE0; + { + s32 r = rand(); + s32 t = *(u16 *)(a0 + 0xE); + *(s16 *)(s0 + 0x34) = 0x1800; + *(s32 *)(s0 + 0x18) = 0; + *(s32 *)(s0 + 0x14) = 0; + *(s32 *)(s0 + 0x10) = 0; + *(s16 *)(s0 + 0xE) = t + (r & 0x7F) - 0x40; + } + L.nv[0] = *(s32 *)(g + 0x5C) - *(u16 *)(s0 + 0x6); + L.nv[1] = *(s32 *)(g + 0x60) - *(u16 *)(s0 + 0xA); + L.nv[2] = *(s32 *)(g + 0x64) - *(u16 *)(s0 + 0xE); + VectorNormalSS(L.nv, L.nv); + *(s16 *)(s0 + 0x6) = *(u16 *)(s0 + 0x6) + ((s16)L.nv[0] >> 6); + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) + ((s16)L.nv[1] >> 6); + *(s16 *)(s0 + 0xE) = *(u16 *)(s0 + 0xE) + ((s16)L.nv[2] >> 6); + *(s16 *)(s0 + 0x34) = 0x3000; + func_8002D4C8(0xAF8, 0); + } + *(u16 *)(a0 + 0xFC) = *(u16 *)(a0 + 0xFC) - 1; + } +} + INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C", func_80180EB8); @@ -4307,11 +4462,14 @@ extern u8 D_801AD394[]; extern u8 D_801B16DC[]; extern u8 D_801B498C[]; extern u8 D_801AD4B0[]; -extern u8 D_801B47F4[]; -extern u8 D_801B487C[]; -extern u8 D_801B4904[]; void func_8018102C(int param_1) { + /* [T51] scoped in from file scope: a file-scope decl of these symbols constrains every + LATER function in this TU, which blocks a byte-true decl of a different type. + Declaration-only move (cookbook §103); the whole-binary byte-gate is the arbiter. */ + extern u8 D_801B47F4[]; + extern u8 D_801B487C[]; + extern u8 D_801B4904[]; int iVar1; iVar1 = func_8012C354(param_1, D_801AD470); @@ -4358,7 +4516,114 @@ big: INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C", func_801811DC); -INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C", func_80181468); +extern void func_8002D4C8(s32 a0, s32 a1); +extern s32 func_8004787C(s32 a0); +extern s32 func_80047948(s32 a0); +extern void func_8004914C(); +extern void func_800491AC(); +extern u8 *func_8012913C(s32 a0); +extern void func_8012A828(s32 a0, void * a1); +#define RTP_SND(sndid) \ + L.v[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48); \ + L.v[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C); \ + L.v[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50); \ + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); } \ + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); } \ + RotTransPers((s32)L.v, (s32)L.sxy, &L.z, &L.flag); \ + if (L.flag >= 0 && (u32)((L.sxy[0] + 0xEF) & 0xFFFF) < 0x1DF \ + && (u32)((L.sxy[1] + 0xB3) & 0xFFFF) < 0x167) { \ + s32 x = (s16)L.sxy[0]; \ + s32 ax; \ + ax = x; \ + if (x < 0) { \ + ax = -x; \ + } \ + ax = ((0xF0 - ax) * 0x7F) / 0xF0; \ + __asm__("" : "=r"(ax) : "0"(ax)); \ + x = (x + 0xF0) / 0x1E; \ + if (x == 0x10) { \ + x = 0xF; \ + } \ + x = x << 8; \ + { \ + s32 flg = 0x3000; \ + func_8002D4C8(sndid, ((ax | flg) | x) & 0xFFFF); \ + } \ + } + +void func_80181468(s32 a0) { + + extern u8 D_800AF648; + extern s32 D_801AD334[]; + extern u8 D_801B47F4[]; + extern u8 D_801B487C[]; + extern u8 D_801B4904[]; + struct { + s16 pad0[4]; /* sp+0x10 — dead, but sizes the frame (idiom 6) */ + s16 v[3]; /* sp+0x18 */ + s16 pad1; /* sp+0x1E */ + u16 sxy[2]; /* sp+0x20 */ + s32 z; /* sp+0x24 */ + s32 flag; /* sp+0x28 */ + } L; + s32 t; + s32 ang; + s32 idx; + s32 m; + s32 c; + s32 p; + + if (*(s16 *)(a0 + 0x98) == 0) { + s32 spr = (s32)func_8012913C(0x7F); + if (spr != 0) { + m = *(s16 *)(*(s32 *)(a0 + 0x20) + 0x12) + + (func_8004787C(*(s16 *)(a0 + 0x104)) >> 3); + *(s16 *)(spr + 0x6) = *(u16 *)(a0 + 0x6) - (func_8004787C(m) * 0x6C) / 0x1000; + *(s16 *)(spr + 0xA) = *(u16 *)(a0 + 0xA) - 0x34; + *(s16 *)(spr + 0xE) = *(u16 *)(a0 + 0xE) - (func_80047948(m) * 0x6C) / 0x1000; + *(s32 *)(spr + 0x14) = 0x40000; + *(s32 *)(spr + 0x10) = -(func_8004787C(m) * 0xC0); + *(s32 *)(spr + 0x18) = -(func_80047948(m) * 0xC0); + } + t = *(u16 *)(a0 + 0x104) + 0x100; + *(s16 *)(a0 + 0x104) = t; + ang = (s16)t; + idx = ang / 0x100; + m = (s16)(idx % 0x10); + if (ang == 0x100) { + RTP_SND(0x95F) + } else if (m == 0) { + RTP_SND(0x960) + } + *(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) = D_801AD334[m]; + c = *(u16 *)(a0 + 0x100) - 1; + *(s16 *)(a0 + 0x100) = c; + if ((s16)c == 0) { + p = *(s32 *)(a0 + 0xCC); + *(s16 *)(a0 + 0x98) = 1; + if (p != 0) { + *(s16 *)(p + 0x98) = 1; + } + p = *(s32 *)(a0 + 0xD0); + if (p != 0) { + *(s16 *)(p + 0x98) = 1; + } + } + } else if ((*(u16 *)(a0 + 0x72) & 0x4000) != 0) { + *(s16 *)(a0 + 0x2) = 7; + *(s16 *)(a0 + 0x100) = 0x3C; + func_8012A828(a0, D_801B47F4); + p = *(s32 *)(a0 + 0xCC); + if (p != 0) { + func_8012A828(p, D_801B487C); + } + p = *(s32 *)(a0 + 0xD0); + if (p != 0) { + func_8012A828(p, D_801B4904); + } + } +} + INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C", func_8018192C); @@ -4446,7 +4711,149 @@ void func_80182004(int param_1) } -INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C", func_801821FC); + + + +extern s32 func_8012C658(s32 arg0, s32 arg1, s32 arg2); +extern s32 func_8012C588(s32 a0, s32 a1); +extern void func_8012C218(void *a0); +extern u8 *func_8012913C(s32 a0); +extern s32 func_80047948(s32 a0); +extern s32 func_8004787C(s32 a0); +extern void func_8004914C(void *a0); +extern void func_800491AC(void *a0); +extern s32 VectorNormalSS(void *a0, void *a1); +extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3); +extern void func_8002D4C8(s32 a0, s32 a1); +extern s32 rand(void); + +void func_801821FC(s32 a0) { + + extern s32 D_801151D4; + + extern void func_8002AC00(s32 arg0); + extern void func_8002A04C(s32 arg0); + extern u8 D_800AF648; + + u16 v10[4]; /* sp+0x10 */ + s16 v18[4]; /* sp+0x18 */ + s32 sxy; /* sp+0x20 */ + s32 z; /* sp+0x24 */ + s32 flag; /* sp+0x28 */ + s32 base; + s32 iv; + s32 i; + s32 t; + s32 r; + + base = D_801151D4; + + if (*(s16 *)(a0 + 0xFC) >= 0x1F) { + iv = func_8012C658(0x33, 3, a0); + if (iv != 0) { + *(u16 *)(iv + 0x0A) = *(u16 *)(iv + 0x0A) - 0x20; + *(u16 *)(iv + 0x12) = *(u16 *)(iv + 0x12) - 8; + *(u16 *)(iv + 0x1A) = *(u16 *)(iv + 0x1A) - 5; + } + iv = func_8012C658(0x33, 3, a0); + if (iv != 0) { + *(u16 *)(iv + 0x0A) = *(u16 *)(iv + 0x0A) - 0x20; + *(u16 *)(iv + 0x12) = *(u16 *)(iv + 0x12) - 8; + *(u16 *)(iv + 0x1A) = *(u16 *)(iv + 0x1A) + 5; + } + iv = func_8012C658(0x32, 2, a0); + if (iv != 0) { + *(u16 *)(iv + 0x0A) = *(u16 *)(iv + 0x0A) - 0x20; + *(u16 *)(iv + 0x12) = *(u16 *)(iv + 0x12) + 8; + } + + func_8002AC00(0x22); + + iv = *(s32 *)(a0 + 0x64); + *(s16 *)(iv + 2) = 2; + iv = *(s32 *)(*(s32 *)(a0 + 0x64) + 0xD0); + *(s16 *)(iv + 2) = 4; + *(s32 *)(*(s32 *)(a0 + 0x64) + 0xCC) = 0; + + i = 0; + do { + iv = func_8012C588(0x281, a0); + if (iv != 0) { + *(s32 *)(iv + 0x1C) = 2; + *(s16 *)(iv + 0x12) = (rand() & 0x1F) - 0x10; + *(s16 *)(iv + 0x16) = -((rand() & 0x0F) + 0x10); + *(s16 *)(iv + 0x1A) = (rand() & 0x1F) - 0x10; + } + i++; + } while (i < 8); + + v18[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48); + v18[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C); + v18[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50); + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); } + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); } + RotTransPers((s32)v18, (s32)&sxy, &z, &flag); + if (flag >= 0 && (u32)((*(u16 *)&sxy + 0xEF) & 0xFFFF) < 0x1DF + && (u32)((*((u16 *)&sxy + 1) + 0xB3) & 0xFFFF) < 0x167) { + s32 sx; + s32 av; + + sx = (s16)*(u16 *)&sxy; + av = sx; + if (sx < 0) { + av = -sx; + } + /* one local for |x| AND the volume: gcc-2.7.2 keeps the single pseudo + in $v1 in place (subu $v1,$v0,$v1); a separate `vol` local steals $a1 + and the whole OR chain drifts (cookbook §136 L1). */ + av = ((0xF0 - av) * 0x7F) / 0xF0; + sx = (sx + 0xF0) / 0x1E; + if (sx == 0x10) { + sx = 0xF; + } + sx = sx << 8; + func_8002D4C8(0x961, (av | (0x3000 | sx)) & 0xFFFF); + } + + func_8002A04C(a0); + func_8012C218((void *)a0); + return; + } + + iv = (s32)func_8012913C(0x23); + if (iv != 0) { + r = rand(); + *(u16 *)(iv + 0x06) = *(u16 *)(a0 + 0x06) + (r & 0x7F) - 0x40; + r = rand(); + *(u16 *)(iv + 0x0A) = *(u16 *)(a0 + 0x0A) + (r & 0x7F) - 0x80; + r = rand(); + *(u16 *)(iv + 0x0E) = *(u16 *)(a0 + 0x0E) + (r & 0x7F) - 0x40; + + t = func_80047948((s32) * (s16 *)(*(s32 *)(a0 + 0x20) + 0x12)); + *(s32 *)(iv + 0x04) = *(s32 *)(iv + 0x04) + (t << 10); + + t = func_8004787C((s32) * (s16 *)(*(s32 *)(a0 + 0x20) + 0x12)); + *(u16 *)(iv + 0x34) = 0x1800; + *(s32 *)(iv + 0x18) = 0; + *(s32 *)(iv + 0x14) = 0; + *(s32 *)(iv + 0x10) = 0; + *(s32 *)(iv + 0x0C) = *(s32 *)(iv + 0x0C) - (t << 10); + + v10[0] = *(s32 *)(base + 0x5C) - *(u16 *)(iv + 0x06); + v10[1] = *(s32 *)(base + 0x60) - *(u16 *)(iv + 0x0A); + v10[2] = *(s32 *)(base + 0x64) - *(u16 *)(iv + 0x0E); + VectorNormalSS(v10, v10); + + *(u16 *)(iv + 0x06) = *(u16 *)(iv + 0x06) + ((s16)v10[0] >> 6); + *(u16 *)(iv + 0x0A) = *(u16 *)(iv + 0x0A) + ((s16)v10[1] >> 6); + *(u16 *)(iv + 0x0E) = *(u16 *)(iv + 0x0E) + ((s16)v10[2] >> 6); + *(u16 *)(iv + 0x34) = 0x3000; + func_8002D4C8(0xAF8, 0); + } + + *(u16 *)(a0 + 0xFC) = *(u16 *)(a0 + 0xFC) + 1; +} + // @class: struct // @stuck: none — MATCH @@ -4508,7 +4915,143 @@ void func_80182644(short *param_1) } -INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C", func_80182854); + + +extern s32 func_8012C658(s32 arg0, s32 arg1, s32 arg2); +extern s32 func_8012C588(s32 a0, s32 a1); +extern void func_8012C218(void *a0); +extern u8 *func_8012913C(); +extern s32 rand(void); +extern s32 func_80047948(s32 a0); +extern s32 func_8004787C(s32 a0); +extern s32 VectorNormalSS(void *a0, void *a1); +extern void func_8004914C(void *a0); +extern void func_800491AC(void *a0); +extern void func_8002D4C8(s32 a0, s32 a1); +extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3); +extern void func_8002A04C(s32 a0); + + +void func_80182854(s32 a0) { + + extern s32 D_801151D4; + + extern u8 D_800AF648; + extern void func_8002AC00(s32 arg0); + + struct { + u16 nv[4]; /* sp+0x10 */ + s16 v[4]; /* sp+0x18 */ + u16 sxy[2]; /* sp+0x20 */ + s32 z; /* sp+0x24 */ + s32 flag; /* sp+0x28 */ + } L; + s32 p; + s32 s0; + s32 i; + + p = D_801151D4; + + if (*(s16 *)(a0 + 0xFC) >= 0x1F) { + s0 = func_8012C658(0x33, 3, a0); + if (s0 != 0) { + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(s16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) - 8; + *(s16 *)(s0 + 0x1A) = *(u16 *)(s0 + 0x1A) - 5; + } + s0 = func_8012C658(0x33, 3, a0); + if (s0 != 0) { + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(s16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) - 8; + *(s16 *)(s0 + 0x1A) = *(u16 *)(s0 + 0x1A) + 5; + } + s0 = func_8012C658(0x32, 2, a0); + if (s0 != 0) { + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(s16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) + 8; + } + func_8002AC00(0x22); + s0 = *(s32 *)(a0 + 0x64); + *(s16 *)(s0 + 0x2) = 4; + s0 = *(s32 *)(*(s32 *)(a0 + 0x64) + 0xCC); + *(s16 *)(s0 + 0x2) = 4; + + for (i = 0; i < 8; i++) { + s0 = func_8012C588(0x281, a0); + if (s0 != 0) { + *(s32 *)(s0 + 0x1C) = 2; + *(s16 *)(s0 + 0x12) = (rand() & 0x1F) - 0x10; + *(s16 *)(s0 + 0x16) = -((rand() & 0xF) + 0x10); + *(s16 *)(s0 + 0x1A) = (rand() & 0x1F) - 0x10; + } + } + + L.v[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48); + L.v[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C); + L.v[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50); + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); } + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); } + RotTransPers((s32)L.v, (s32)L.sxy, &L.z, &L.flag); + if (L.flag >= 0 && (u32)((L.sxy[0] + 0xEF) & 0xFFFF) < 0x1DF + && (u32)((L.sxy[1] + 0xB3) & 0xFFFF) < 0x167) { + s32 x = (s16)L.sxy[0]; + s32 ax; + ax = x; + if (x < 0) { + ax = -x; + } + ax = ((0xF0 - ax) * 0x7F) / 0xF0; + __asm__("" : "=r"(ax) : "0"(ax)); + x = (x + 0xF0) / 0x1E; + if (x == 0x10) { + x = 0xF; + } + x = x << 8; + { + s32 flg = 0x3000; + func_8002D4C8(0x961, ((ax | flg) | x) & 0xFFFF); + } + } + + *(s32 *)(*(s32 *)(a0 + 0x64) + 0xD0) = 0; + func_8002A04C(a0); + func_8012C218((void *)a0); + return; + } + + s0 = (s32)func_8012913C(0x23); + if (s0 != 0) { + *(s16 *)(s0 + 0x6) = *(u16 *)(a0 + 0x6) + (rand() & 0x7F) - 0x40; + *(s16 *)(s0 + 0xA) = *(u16 *)(a0 + 0xA) + (rand() & 0x7F) - 0x80; + *(s16 *)(s0 + 0xE) = *(u16 *)(a0 + 0xE) + (rand() & 0x7F) - 0x40; + + *(s32 *)(s0 + 0x4) = + *(s32 *)(s0 + 0x4) - + func_80047948(*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12)) * 0x400; + { + s32 t = func_8004787C(*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12)) * 0x400; + *(s16 *)(s0 + 0x34) = 0x1800; + *(s32 *)(s0 + 0x18) = 0; + *(s32 *)(s0 + 0x14) = 0; + *(s32 *)(s0 + 0x10) = 0; + *(s32 *)(s0 + 0xC) = *(s32 *)(s0 + 0xC) + t; + } + + L.nv[0] = *(s32 *)(p + 0x5C) - *(u16 *)(s0 + 0x6); + L.nv[1] = *(s32 *)(p + 0x60) - *(u16 *)(s0 + 0xA); + L.nv[2] = *(s32 *)(p + 0x64) - *(u16 *)(s0 + 0xE); + VectorNormalSS(L.nv, L.nv); + + *(s16 *)(s0 + 0x6) = *(u16 *)(s0 + 0x6) + ((s16)L.nv[0] >> 6); + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) + ((s16)L.nv[1] >> 6); + *(s16 *)(s0 + 0xE) = *(u16 *)(s0 + 0xE) + ((s16)L.nv[2] >> 6); + *(s16 *)(s0 + 0x34) = 0x3000; + func_8002D4C8(0xAF8, 0); + } + + *(s16 *)(a0 + 0xFC) = *(u16 *)(a0 + 0xFC) + 1; +} + // @class: other // @stuck: none — MATCH (132 ins). Blocker was gcc reassociating `mem - 0x20 + masked` @@ -5595,7 +6138,165 @@ INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C", func_8018855 INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C", func_8018868C); -INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C", func_801886B0); +// @class: struct +// @stuck: none — MATCH (276 ins, relocation-masked). Verified BOTH standalone (match_one) and +// spliced into src/ov_SC06_018/ov_SC06_018_jr_8017C24C.c (whole-TU cc1 -O2 clean, +// masked structured_diff 0/276). +// Keys: (1) the first func_8012C218 call gets a NOP delay slot because reload_cse_regs deletes the +// redundant `move a0,s1` -- $a0 still holds the incoming param on the fall-through path +// (no CODE_LABEL between the prologue and the jal). The second call site is behind a +// label, so the move survives. Source is the natural `func_8012C218((void *)param_1)` at +// BOTH sites -- do NOT write a zero-arg call (it also breaks in-TU: the composite type +// from the earlier file-scope `extern void func_8012C218(void *a0);` rejects 0 args). +// (2) case 0's guard is an `||` with an early return -- that is what puts `beqz -> fail` then +// `beq -> ok` (an `&&` would emit `bne -> fail`). +// (3) `register s32 sVar2 __asm__("$2")` holds the p+0x34 reload in cases 1/2 so the two arms +// cross-jump into the shared .L80188928 tail. +// (4) `__asm__ __volatile__("")` after the func_8012C658 arm forces the `lw v1,0x1C(s1)` +// reload before the cross-jumped `li v0,9` (§21 zero-byte re-tie). +// (5) `-((iVar3 << 0x10) / 0x22)` reproduces the 0x78787879/sra-4 magic-divide by 34 + negu. +// (6) `*p * 0xc` then `>>4` with the manual `if (x<0) x+=0xf` is the /16 rounding form. + +extern void func_8012C218(void *a0); +extern void func_80189380(s32, void*, void*, s32); +extern s32 func_80013328(s32 a0, s32 a1); +extern void func_8012B14C(s32 a0, s32 a1); +extern void func_8012CC64(s32 a0, s32 a1); /* fleet-canonical: void; $v0 used -> cast at use */ +extern s32 func_8012C658(s32, s32, s32); +extern s32 func_80143B6C(s32 a0, s32 a1); /* fleet-canonical */ +extern s32 func_8012BEE8(s32 a0); +extern void func_80016714(void*, s32); +extern void func_80189000(s32 a0, s32 a1); + +extern u8 D_801CD278; +extern u8 D_801B54EC; +extern u8 D_801B54F4; +extern u8 D_801B54E4; +extern u8 D_80126B5C; + +void func_801886B0(s32 param_1) { + u16 uVar1; + register s32 sVar2 __asm__("$2"); + s32 iVar3; + s32 iVar4; + s32 iVar5; + u32 uVar4; + s32 psVar5; + u16 buf[8]; + s32 vec[3]; + + if (0xf < *(s16 *)(param_1 + 0xA)) { + func_8012C218((void *)param_1); + return; + } + uVar1 = *(u16 *)(param_1 + 0x34); + switch (uVar1) { + case 0: + psVar5 = *(s32 *)(param_1 + 0x64); + if ((*(u16 *)psVar5 == 0) || + (*(s32 *)(psVar5 + 0x90) != (s32)&D_801CD278)) { + func_8012C218((void *)param_1); + return; + } + if (*(s32 *)(psVar5 + 0x94) < 0x11) { + ((void (*)(void *, void *, void *, s32))func_80189380)((void *)psVar5, (void *)&D_801B54EC, buf, 5); + *(s16 *)(param_1 + 6) = buf[0]; + *(s16 *)(param_1 + 0xA) = buf[1]; + *(s16 *)(param_1 + 0xE) = buf[2]; + return; + } + ((void (*)(void *, void *, void *, s32))func_80189380)((void *)psVar5, (void *)&D_801B54F4, buf, 4); + ((void (*)(void *, void *, void *, s32))func_80189380)((void *)psVar5, (void *)&D_801B54F4, &buf[4], 5); + *(s16 *)(param_1 + 6) = + (s16)((*(s16 *)&buf[0] + *(s16 *)&buf[4]) >> 1); + *(s16 *)(param_1 + 0xA) = + (s16)((*(s16 *)&buf[1] + *(s16 *)&buf[5]) >> 1); + *(s16 *)(param_1 + 0xE) = + (s16)((*(s16 *)&buf[2] + *(s16 *)&buf[6]) >> 1); + if (*(s32 *)(psVar5 + 0x94) != 0x19) { + return; + } + *(u16 *)(param_1 + 0x34) = *(u16 *)(param_1 + 0x34) + 1; + vec[0] = 0; + vec[1] = 0xfff40000; + iVar3 = func_80013328((s32)&D_80126B5C, param_1 + 4); + vec[2] = -((iVar3 << 0x10) / 0x22); + func_8012B14C(param_1, (s32)vec); + *(s32 *)(param_1 + 0x48) = 0xc000; + return; + case 1: + *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x10) + 0x80; + iVar3 = ((s32 (*)(s32, s32))func_8012CC64)(param_1, (s32)&D_801B54E4); + if (iVar3 == 0) { + return; + } + sVar2 = *(u16 *)(param_1 + 0x34); + *(s32 *)(param_1 + 0x1c) = 0; + *(u16 *)(param_1 + 0x34) = sVar2 + 1; + return; + case 2: + *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x10) + 0x40; + uVar4 = ((s32 (*)(s32, s32))func_8012CC64)(param_1, (s32)&D_801B54E4); + if ((uVar4 & 0x2000) == 0) { + return; + } + iVar4 = *(s32 *)(param_1 + 0x1c) + 1; + *(s32 *)(param_1 + 0x1c) = iVar4; + if (iVar4 >= 4) { + sVar2 = *(u16 *)(param_1 + 0x34); + *(s32 *)(param_1 + 0x1c) = 0x1e; + *(u16 *)(param_1 + 0x34) = sVar2 + 1; + return; + } + iVar3 = *(s32 *)(param_1 + 0x10) * 0xc; + if (iVar3 < 0) { + iVar3 = iVar3 + 0xf; + } + *(s32 *)(param_1 + 0x10) = iVar3 >> 4; + iVar5 = *(s32 *)(param_1 + 0x18) * 0xc; + if (iVar5 < 0) { + iVar5 = iVar5 + 0xf; + } + *(s32 *)(param_1 + 0x18) = iVar5 >> 4; + *(s32 *)(param_1 + 0x14) = -(0x80000 / *(s32 *)(param_1 + 0x1c)); + func_80143B6C(param_1, 1); + return; + case 3: + uVar4 = *(u32 *)(param_1 + 0x1c); + if ((uVar4 - 0xe < 0xb) && ((uVar4 & 1) == 0)) { + ((void (*)(s32, s32, s32))func_8012C658)(0x2a8, (s32)*(s16 *)(param_1 + 0x104), param_1); + *(u16 *)(param_1 + 0x104) = *(u16 *)(param_1 + 0x104) + 1; + __asm__ __volatile__(""); + uVar4 = *(u32 *)(param_1 + 0x1c); + } + if (uVar4 == 9) { + *(u32 *)(*(s32 *)(param_1 + 0xcc) + 4) = + *(u32 *)(*(s32 *)(param_1 + 0xcc) + 4) & 0x7fffffff; + *(s16 *)(*(s32 *)(param_1 + 0xcc) + 8) = *(u16 *)(param_1 + 6); + *(s16 *)(*(s32 *)(param_1 + 0xcc) + 0xa) = + *(u16 *)(param_1 + 0xa) - 0x24; + *(s16 *)(*(s32 *)(param_1 + 0xcc) + 0xc) = *(u16 *)(param_1 + 0xe); + } + if (*(s32 *)(param_1 + 0x1c) - 4U < 6) { + *(s16 *)(*(s32 *)(param_1 + 0xcc) + 0x18) = + *(u16 *)(*(s32 *)(param_1 + 0xcc) + 0x18) + 0x200; + *(s16 *)(*(s32 *)(param_1 + 0xcc) + 0x1a) = + *(u16 *)(*(s32 *)(param_1 + 0xcc) + 0x1a) + 0x200; + } + iVar3 = func_8012BEE8(param_1); + if (iVar3 != 1) { + return; + } + ((void (*)(s32, s32))func_80016714)(*(s32 *)(param_1 + 0xcc), 0x38); + *(s16 *)(param_1 + 2) = 9; + func_80189000(param_1, 0); + return; + } + return; +} + #include "common.h" @@ -5654,7 +6355,133 @@ void func_801894B4(void *a0) { } -INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C", func_801894F0); +extern s32 rand(void); +extern void func_8012C1B8(void); +extern void func_8012CAE4(s32 a0); +extern void func_8001C214(s32 a0, s32 a1); +extern void func_8012B2CC(s32 a0); +extern void func_8012B178(s32 a0, s32 a1); +extern u8 D_801B5588[]; + +void func_801894F0(s32 param_1) { + s32 unused[2]; /* dead 8-byte local — frame padding (cookbook idiom 6) */ + s32 obj; + s16 raw; + s32 r; + s32 sgn; + s32 v; + u8 *tbl; + s16 *p; + s32 q; + s32 w; + + obj = ((s32 (*)(void))func_8012C1B8)(); + if (obj == 0) { + func_8012CAE4(param_1); + return; + } + *(s32 *)(param_1 + 0x20) = obj; + func_8001C214(obj, 0); + + raw = rand(); + r = raw; + *(u16 *)(obj + 0x2C) = *(u16 *)(obj + 0x2C) | 0x10; + v = r % 384 + 0x400; + *(s16 *)(obj + 0x1C) = v; + *(s16 *)(obj + 0x1A) = v; + *(s16 *)(obj + 0x18) = v; + sgn = -1; + if (raw & 1) { + sgn = 1; + } + *(s16 *)(obj + 0x10) = sgn * (r % 128) - 0x300; + *(s16 *)(obj + 0x12) = r % 4096; + *(s32 *)(param_1 + 0x48) = 0xC000; + *(u16 *)(param_1 + 0xA) = *(u16 *)(param_1 + 0xA) - 0x19; + func_8012B2CC(param_1); + func_8012B178(param_1, -0xC0000 - ((r % 8) << 16)); + *(s32 *)(param_1 + 0x1C) = 0x3C; + *(s16 *)(param_1 + 0xFE) = rand() & 0xF0; + *(s16 *)(param_1 + 0x100) = rand() & 0x1F0; + *(s16 *)(param_1 + 0x102) = rand() & 0x30; + tbl = &D_801B5588[(*(u16 *)(param_1 + 0x70) & 0xF) * 4]; + + p = (s16 *)(param_1 + 0xDC); + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q - 0x18; + } else { + w = q - 0x18; + } + p[0] = w; + p[1] = 0; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q - 0x18; + } else { + w = q - 0x18; + } + p[2] = w; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q + 0x18; + } else { + w = q + 0x18; + } + p[4] = w; + p[5] = 0; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q - 0x18; + } else { + w = q - 0x18; + } + p[6] = w; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q - 0x18; + } else { + w = q - 0x18; + } + p[8] = w; + p[9] = 0; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q + 0x18; + } else { + w = q + 0x18; + } + p[10] = w; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q + 0x18; + } else { + w = q + 0x18; + } + p[12] = w; + p[13] = 0; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q + 0x18; + } else { + w = q + 0x18; + } + p[14] = w; + + *((u8 *)p + 0x20) = tbl[0]; + *((u8 *)p + 0x21) = tbl[1]; + *((u8 *)p + 0x22) = tbl[2]; + *(u16 *)(param_1 + 2) = *(u16 *)(param_1 + 2) + 1; +} + #include "common.h" @@ -5838,7 +6665,54 @@ INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C", func_8018AD7 INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C", func_8018AE64); -INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C", func_8018AF88); +// @class: struct +// @stuck: none — §136c SIBLING-FIRST. Near-twin (byte-identical template) = func_80186160 in +// src/ov_SC06_032/ov_SC06_032_jr_8017C24C.c (same jr_8017C24C base overlay TU, still +// nonmatching); the two differ only in the per-overlay D_ table symbol (D_801CD498 here vs +// D_801BEF4C there). RotMatrixY/func_8012AD44 canonical decl forms lifted from +// src/ov_SC06_008/ov_SC06_008_jr_8016AB6C.c ("extern void RotMatrixY(s32 a0, void *a1);") and +// src/shared/engine_core.h; the func_800484EC cast-through-fnptr call form is lifted from the +// banked func_80188B00 in this same TU. The D_800AE620 8-word struct copy (3+3+2 lw/sw +// grouping) is the established whole-struct `local = D_800AE620;` idiom already used for this +// exact symbol elsewhere (Blk20, renamed here to avoid clashing with the real typedef pulled +// in via engine_core.h when this splices into the TU). The address of the local matrix is +// cached in a POINTER LOCAL (T6) because it's used again across the intervening RotMatrixY +// call -- that's what forces it into a callee-saved reg ($s1) instead of being recomputed as +// `addiu $a0,$sp,0x10` at each use site. + +typedef struct { s32 w[8]; } Blk20_8018AF88; + +extern Blk20_8018AF88 D_800AE620; +extern s32 D_801CD498; + +extern s32 func_8012B8A4(s16 *a0); +extern void RotMatrixY(s32 a0, void *a1); +extern void func_800484EC(s32, s32, s32); +extern void func_8012AD44(s32 *a0, s16 a1); +extern s32 rand(void); + +void func_8018AF88(s32 param_1) +{ + Blk20_8018AF88 local_30; + Blk20_8018AF88 *m; + s32 iVar1; + s32 iVar2; + + local_30 = D_800AE620; + iVar1 = func_8012B8A4((s16 *)param_1); + m = &local_30; + RotMatrixY(iVar1, m); + ((void (*)(void *, void *, s32))func_800484EC)(m, &D_801CD498, param_1 + 0x10); + *(s32 *)(param_1 + 0x14) = 0xFFDC0000; + *(s32 *)(param_1 + 0xE0) = 0xFFDC0000; + *(s32 *)(param_1 + 0x1C) = 0x10; + iVar2 = rand(); + *(u16 *)(param_1 + 0x106) = iVar2 & 0x70; + iVar2 = rand(); + *(u16 *)(param_1 + 0x108) = iVar2 & 0x70; + func_8012AD44((s32 *)param_1, 1); +} + INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C", func_8018B060); @@ -5880,7 +6754,23 @@ INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C", func_8018BB1 INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C", func_8018BBB8); -INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C", func_8018BC40); +void func_8018BC40(s32 param_1) +{ + s32 result; + u16 val_e4; + + result = func_80132EF4(param_1, 0x23); + if (result != 0) { + *(u16 *)(result + 0x6) = *(u16 *)(param_1 + 0xE0); + *(u16 *)(result + 0xA) = *(u16 *)(param_1 + 0xE2); + val_e4 = *(u16 *)(param_1 + 0xE4); + *(u16 *)(result + 0x34) = 0x3001; + *(u16 *)(result + 0xE) = val_e4; + *(u16 *)(*(s32 *)(result + 0x20) + 0x2C) = 0xC008; + *(u32 *)(*(s32 *)(result + 0x20) + 0x4) |= 0x50000000; + } +} + INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C", func_8018BCC4); diff --git a/src/ov_SC06_020/ov_SC06_020_jr_8017C24C.c b/src/ov_SC06_020/ov_SC06_020_jr_8017C24C.c index 8fe62b06b..735829aff 100644 --- a/src/ov_SC06_020/ov_SC06_020_jr_8017C24C.c +++ b/src/ov_SC06_020/ov_SC06_020_jr_8017C24C.c @@ -4115,7 +4115,167 @@ INCLUDE_ASM("asm/ov_SC06_020/nonmatchings/ov_SC06_020_jr_8017C24C", func_801826C INCLUDE_ASM("asm/ov_SC06_020/nonmatchings/ov_SC06_020_jr_8017C24C", func_801827FC); -INCLUDE_ASM("asm/ov_SC06_020/nonmatchings/ov_SC06_020_jr_8017C24C", func_80182820); + +// @class: struct +// @stuck: none — MATCH (276 ins, relocation-masked). Verified BOTH standalone (match_one) and +// spliced into src/ov_SC06_018/ov_SC06_018_jr_8017C24C.c (whole-TU cc1 -O2 clean, +// masked structured_diff 0/276). +// Keys: (1) the first func_8012C218 call gets a NOP delay slot because reload_cse_regs deletes the +// redundant `move a0,s1` -- $a0 still holds the incoming param on the fall-through path +// (no CODE_LABEL between the prologue and the jal). The second call site is behind a +// label, so the move survives. Source is the natural `func_8012C218((void *)param_1)` at +// BOTH sites -- do NOT write a zero-arg call (it also breaks in-TU: the composite type +// from the earlier file-scope `extern void func_8012C218(void *a0);` rejects 0 args). +// (2) case 0's guard is an `||` with an early return -- that is what puts `beqz -> fail` then +// `beq -> ok` (an `&&` would emit `bne -> fail`). +// (3) `register s32 sVar2 __asm__("$2")` holds the p+0x34 reload in cases 1/2 so the two arms +// cross-jump into the shared .L80188928 tail. +// (4) `__asm__ __volatile__("")` after the func_8012C658 arm forces the `lw v1,0x1C(s1)` +// reload before the cross-jumped `li v0,9` (§21 zero-byte re-tie). +// (5) `-((iVar3 << 0x10) / 0x22)` reproduces the 0x78787879/sra-4 magic-divide by 34 + negu. +// (6) `*p * 0xc` then `>>4` with the manual `if (x<0) x+=0xf` is the /16 rounding form. + +extern void func_8012C218(void *a0); +extern void func_801834F0(s32, void*, void*, s32); +extern s32 func_80013328(s32 a0, s32 a1); +extern void func_8012B14C(s32 a0, s32 a1); +extern void func_8012CC64(s32 a0, s32 a1); /* fleet-canonical: void; $v0 used -> cast at use */ +extern s32 func_8012C658(s32, s32, s32); +extern s32 func_80143B6C(s32 a0, s32 a1); /* fleet-canonical */ +extern s32 func_8012BEE8(s32 a0); +extern void func_80016714(void*, s32); +extern void func_80183170(s32 a0, s32 a1); + + +void func_80182820(s32 param_1) { + + extern u8 D_801B6AA8; + extern u8 D_8019ED1C; + extern u8 D_8019ED24; + extern u8 D_8019ED14; + extern u8 D_80126B5C; + u16 uVar1; + register s32 sVar2 __asm__("$2"); + s32 iVar3; + s32 iVar4; + s32 iVar5; + u32 uVar4; + s32 psVar5; + u16 buf[8]; + s32 vec[3]; + + if (0xf < *(s16 *)(param_1 + 0xA)) { + func_8012C218((void *)param_1); + return; + } + uVar1 = *(u16 *)(param_1 + 0x34); + switch (uVar1) { + case 0: + psVar5 = *(s32 *)(param_1 + 0x64); + if ((*(u16 *)psVar5 == 0) || + (*(s32 *)(psVar5 + 0x90) != (s32)&D_801B6AA8)) { + func_8012C218((void *)param_1); + return; + } + if (*(s32 *)(psVar5 + 0x94) < 0x11) { + ((void (*)(void *, void *, void *, s32))func_801834F0)((void *)psVar5, (void *)&D_8019ED1C, buf, 5); + *(s16 *)(param_1 + 6) = buf[0]; + *(s16 *)(param_1 + 0xA) = buf[1]; + *(s16 *)(param_1 + 0xE) = buf[2]; + return; + } + ((void (*)(void *, void *, void *, s32))func_801834F0)((void *)psVar5, (void *)&D_8019ED24, buf, 4); + ((void (*)(void *, void *, void *, s32))func_801834F0)((void *)psVar5, (void *)&D_8019ED24, &buf[4], 5); + *(s16 *)(param_1 + 6) = + (s16)((*(s16 *)&buf[0] + *(s16 *)&buf[4]) >> 1); + *(s16 *)(param_1 + 0xA) = + (s16)((*(s16 *)&buf[1] + *(s16 *)&buf[5]) >> 1); + *(s16 *)(param_1 + 0xE) = + (s16)((*(s16 *)&buf[2] + *(s16 *)&buf[6]) >> 1); + if (*(s32 *)(psVar5 + 0x94) != 0x19) { + return; + } + *(u16 *)(param_1 + 0x34) = *(u16 *)(param_1 + 0x34) + 1; + vec[0] = 0; + vec[1] = 0xfff40000; + iVar3 = func_80013328((s32)&D_80126B5C, param_1 + 4); + vec[2] = -((iVar3 << 0x10) / 0x22); + func_8012B14C(param_1, (s32)vec); + *(s32 *)(param_1 + 0x48) = 0xc000; + return; + case 1: + *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x10) + 0x80; + iVar3 = ((s32 (*)(s32, s32))func_8012CC64)(param_1, (s32)&D_8019ED14); + if (iVar3 == 0) { + return; + } + sVar2 = *(u16 *)(param_1 + 0x34); + *(s32 *)(param_1 + 0x1c) = 0; + *(u16 *)(param_1 + 0x34) = sVar2 + 1; + return; + case 2: + *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x10) + 0x40; + uVar4 = ((s32 (*)(s32, s32))func_8012CC64)(param_1, (s32)&D_8019ED14); + if ((uVar4 & 0x2000) == 0) { + return; + } + iVar4 = *(s32 *)(param_1 + 0x1c) + 1; + *(s32 *)(param_1 + 0x1c) = iVar4; + if (iVar4 >= 4) { + sVar2 = *(u16 *)(param_1 + 0x34); + *(s32 *)(param_1 + 0x1c) = 0x1e; + *(u16 *)(param_1 + 0x34) = sVar2 + 1; + return; + } + iVar3 = *(s32 *)(param_1 + 0x10) * 0xc; + if (iVar3 < 0) { + iVar3 = iVar3 + 0xf; + } + *(s32 *)(param_1 + 0x10) = iVar3 >> 4; + iVar5 = *(s32 *)(param_1 + 0x18) * 0xc; + if (iVar5 < 0) { + iVar5 = iVar5 + 0xf; + } + *(s32 *)(param_1 + 0x18) = iVar5 >> 4; + *(s32 *)(param_1 + 0x14) = -(0x80000 / *(s32 *)(param_1 + 0x1c)); + func_80143B6C(param_1, 1); + return; + case 3: + uVar4 = *(u32 *)(param_1 + 0x1c); + if ((uVar4 - 0xe < 0xb) && ((uVar4 & 1) == 0)) { + ((void (*)(s32, s32, s32))func_8012C658)(0x2a8, (s32)*(s16 *)(param_1 + 0x104), param_1); + *(u16 *)(param_1 + 0x104) = *(u16 *)(param_1 + 0x104) + 1; + __asm__ __volatile__(""); + uVar4 = *(u32 *)(param_1 + 0x1c); + } + if (uVar4 == 9) { + *(u32 *)(*(s32 *)(param_1 + 0xcc) + 4) = + *(u32 *)(*(s32 *)(param_1 + 0xcc) + 4) & 0x7fffffff; + *(s16 *)(*(s32 *)(param_1 + 0xcc) + 8) = *(u16 *)(param_1 + 6); + *(s16 *)(*(s32 *)(param_1 + 0xcc) + 0xa) = + *(u16 *)(param_1 + 0xa) - 0x24; + *(s16 *)(*(s32 *)(param_1 + 0xcc) + 0xc) = *(u16 *)(param_1 + 0xe); + } + if (*(s32 *)(param_1 + 0x1c) - 4U < 6) { + *(s16 *)(*(s32 *)(param_1 + 0xcc) + 0x18) = + *(u16 *)(*(s32 *)(param_1 + 0xcc) + 0x18) + 0x200; + *(s16 *)(*(s32 *)(param_1 + 0xcc) + 0x1a) = + *(u16 *)(*(s32 *)(param_1 + 0xcc) + 0x1a) + 0x200; + } + iVar3 = func_8012BEE8(param_1); + if (iVar3 != 1) { + return; + } + ((void (*)(s32, s32))func_80016714)(*(s32 *)(param_1 + 0xcc), 0x38); + *(s16 *)(param_1 + 2) = 9; + func_80183170(param_1, 0); + return; + } + return; +} + extern void func_80049CAC(s32, s32); @@ -4173,7 +4333,136 @@ void func_80183624(void *a0) { } -INCLUDE_ASM("asm/ov_SC06_020/nonmatchings/ov_SC06_020_jr_8017C24C", func_80183660); + + +extern s32 rand(void); +extern void func_8012C1B8(void); +extern void func_8012CAE4(void*); +extern void func_8001C214(s32 a0, s32 a1); +extern void func_8012B2CC(s32 a0); +extern void func_8012B178(s32 a0, s32 a1); + +void func_80183660(s32 param_1) { + + extern u8 D_8019EDB8[]; + s32 unused[2]; /* dead 8-byte local — frame padding (cookbook idiom 6) */ + s32 obj; + s16 raw; + s32 r; + s32 sgn; + s32 v; + u8 *tbl; + s16 *p; + s32 q; + s32 w; + + obj = ((s32 (*)(void))func_8012C1B8)(); + if (obj == 0) { + ((void (*)(s32))func_8012CAE4)(param_1); + return; + } + *(s32 *)(param_1 + 0x20) = obj; + func_8001C214(obj, 0); + + raw = rand(); + r = raw; + *(u16 *)(obj + 0x2C) = *(u16 *)(obj + 0x2C) | 0x10; + v = r % 384 + 0x400; + *(s16 *)(obj + 0x1C) = v; + *(s16 *)(obj + 0x1A) = v; + *(s16 *)(obj + 0x18) = v; + sgn = -1; + if (raw & 1) { + sgn = 1; + } + *(s16 *)(obj + 0x10) = sgn * (r % 128) - 0x300; + *(s16 *)(obj + 0x12) = r % 4096; + *(s32 *)(param_1 + 0x48) = 0xC000; + *(u16 *)(param_1 + 0xA) = *(u16 *)(param_1 + 0xA) - 0x19; + func_8012B2CC(param_1); + func_8012B178(param_1, -0xC0000 - ((r % 8) << 16)); + *(s32 *)(param_1 + 0x1C) = 0x3C; + *(s16 *)(param_1 + 0xFE) = rand() & 0xF0; + *(s16 *)(param_1 + 0x100) = rand() & 0x1F0; + *(s16 *)(param_1 + 0x102) = rand() & 0x30; + tbl = &D_8019EDB8[(*(u16 *)(param_1 + 0x70) & 0xF) * 4]; + + p = (s16 *)(param_1 + 0xDC); + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q - 0x18; + } else { + w = q - 0x18; + } + p[0] = w; + p[1] = 0; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q - 0x18; + } else { + w = q - 0x18; + } + p[2] = w; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q + 0x18; + } else { + w = q + 0x18; + } + p[4] = w; + p[5] = 0; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q - 0x18; + } else { + w = q - 0x18; + } + p[6] = w; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q - 0x18; + } else { + w = q - 0x18; + } + p[8] = w; + p[9] = 0; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q + 0x18; + } else { + w = q + 0x18; + } + p[10] = w; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q + 0x18; + } else { + w = q + 0x18; + } + p[12] = w; + p[13] = 0; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q + 0x18; + } else { + w = q + 0x18; + } + p[14] = w; + + *((u8 *)p + 0x20) = tbl[0]; + *((u8 *)p + 0x21) = tbl[1]; + *((u8 *)p + 0x22) = tbl[2]; + *(u16 *)(param_1 + 2) = *(u16 *)(param_1 + 2) + 1; +} + extern s32 func_8012CBF4(s32 a0); diff --git a/src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c b/src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c index ebb408bb7..901e5005c 100644 --- a/src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c +++ b/src/ov_SC06_022/ov_SC06_022_jr_8017BEBC.c @@ -318,7 +318,6 @@ extern s32 func_80012B04(s32 a0, s32 a1, s32 a2); extern void func_801490F8(s32 a0, s32 a1); extern s32 func_801491C4(s32 a0); extern s32 func_80149184(s32 a0); -extern s32 D_801151D4; extern void func_80149204(s32 *a0); extern void func_80149210(s32 a0, s32 a1); extern s32 func_80149284(s32 *a0, s32 a1); @@ -3686,7 +3685,25 @@ void func_80181168(void *a0) { INCLUDE_ASM("asm/ov_SC06_022/nonmatchings/ov_SC06_022_jr_8017BEBC", func_801811A4); -INCLUDE_ASM("asm/ov_SC06_022/nonmatchings/ov_SC06_022_jr_8017BEBC", func_801812F8); +extern void func_8012B23C(); +extern s32 rand(void); +extern void func_8012AD44(s32 *a0, s16 a1); + +void func_801812F8(s32 a0) { + func_8012B23C(a0); + *(s32 *)(a0 + 0x10) = ((rand() & 0x7F) - 0x40) << 11; + *(s32 *)(a0 + 0x14) = -((rand() & 0x7F) << 13); + *(s32 *)(a0 + 0x18) = (rand() & 0x7F) << 13; + *(u16 *)(a0 + 0x106) = rand() & 0x1F0; + *(u16 *)(a0 + 0x108) = rand() & 0x1F0; + *(s16 *)(a0 + 0xE6) = 8; + { + s32 v = *(s16 *)(a0 + 0x70); + *(s16 *)(a0 + 0xE4) = v << 1; + } + ((void (*)(s32, s32))func_8012AD44)(a0, 1); +} + INCLUDE_ASM("asm/ov_SC06_022/nonmatchings/ov_SC06_022_jr_8017BEBC", func_80181394); @@ -4397,7 +4414,167 @@ INCLUDE_ASM("asm/ov_SC06_022/nonmatchings/ov_SC06_022_jr_8017BEBC", func_801865E INCLUDE_ASM("asm/ov_SC06_022/nonmatchings/ov_SC06_022_jr_8017BEBC", func_80186720); -INCLUDE_ASM("asm/ov_SC06_022/nonmatchings/ov_SC06_022_jr_8017BEBC", func_80186744); + +// @class: struct +// @stuck: none — MATCH (276 ins, relocation-masked). Verified BOTH standalone (match_one) and +// spliced into src/ov_SC06_018/ov_SC06_018_jr_8017C24C.c (whole-TU cc1 -O2 clean, +// masked structured_diff 0/276). +// Keys: (1) the first func_8012C218 call gets a NOP delay slot because reload_cse_regs deletes the +// redundant `move a0,s1` -- $a0 still holds the incoming param on the fall-through path +// (no CODE_LABEL between the prologue and the jal). The second call site is behind a +// label, so the move survives. Source is the natural `func_8012C218((void *)param_1)` at +// BOTH sites -- do NOT write a zero-arg call (it also breaks in-TU: the composite type +// from the earlier file-scope `extern void func_8012C218(void *a0);` rejects 0 args). +// (2) case 0's guard is an `||` with an early return -- that is what puts `beqz -> fail` then +// `beq -> ok` (an `&&` would emit `bne -> fail`). +// (3) `register s32 sVar2 __asm__("$2")` holds the p+0x34 reload in cases 1/2 so the two arms +// cross-jump into the shared .L80188928 tail. +// (4) `__asm__ __volatile__("")` after the func_8012C658 arm forces the `lw v1,0x1C(s1)` +// reload before the cross-jumped `li v0,9` (§21 zero-byte re-tie). +// (5) `-((iVar3 << 0x10) / 0x22)` reproduces the 0x78787879/sra-4 magic-divide by 34 + negu. +// (6) `*p * 0xc` then `>>4` with the manual `if (x<0) x+=0xf` is the /16 rounding form. + +extern void func_8012C218(void *a0); +extern void func_80187414(s32, void*, void*, s32); +extern s32 func_80013328(s32 a0, s32 a1); +extern void func_8012B14C(s32 a0, s32 a1); +extern void func_8012CC64(s32 a0, s32 a1); /* fleet-canonical: void; $v0 used -> cast at use */ +extern s32 func_8012C658(s32, s32, s32); +extern s32 func_80143B6C(s32 a0, s32 a1); /* fleet-canonical */ +extern s32 func_8012BEE8(s32 a0); +extern void func_80016714(void*, s32); +extern void func_80187094(s32 a0, s32 a1); + + +void func_80186744(s32 param_1) { + + extern u8 D_801D51D0; + extern u8 D_801BD444; + extern u8 D_801BD44C; + extern u8 D_801BD43C; + extern u8 D_80126B5C; + u16 uVar1; + register s32 sVar2 __asm__("$2"); + s32 iVar3; + s32 iVar4; + s32 iVar5; + u32 uVar4; + s32 psVar5; + u16 buf[8]; + s32 vec[3]; + + if (0xf < *(s16 *)(param_1 + 0xA)) { + func_8012C218((void *)param_1); + return; + } + uVar1 = *(u16 *)(param_1 + 0x34); + switch (uVar1) { + case 0: + psVar5 = *(s32 *)(param_1 + 0x64); + if ((*(u16 *)psVar5 == 0) || + (*(s32 *)(psVar5 + 0x90) != (s32)&D_801D51D0)) { + func_8012C218((void *)param_1); + return; + } + if (*(s32 *)(psVar5 + 0x94) < 0x11) { + ((void (*)(void *, void *, void *, s32))func_80187414)((void *)psVar5, (void *)&D_801BD444, buf, 5); + *(s16 *)(param_1 + 6) = buf[0]; + *(s16 *)(param_1 + 0xA) = buf[1]; + *(s16 *)(param_1 + 0xE) = buf[2]; + return; + } + ((void (*)(void *, void *, void *, s32))func_80187414)((void *)psVar5, (void *)&D_801BD44C, buf, 4); + ((void (*)(void *, void *, void *, s32))func_80187414)((void *)psVar5, (void *)&D_801BD44C, &buf[4], 5); + *(s16 *)(param_1 + 6) = + (s16)((*(s16 *)&buf[0] + *(s16 *)&buf[4]) >> 1); + *(s16 *)(param_1 + 0xA) = + (s16)((*(s16 *)&buf[1] + *(s16 *)&buf[5]) >> 1); + *(s16 *)(param_1 + 0xE) = + (s16)((*(s16 *)&buf[2] + *(s16 *)&buf[6]) >> 1); + if (*(s32 *)(psVar5 + 0x94) != 0x19) { + return; + } + *(u16 *)(param_1 + 0x34) = *(u16 *)(param_1 + 0x34) + 1; + vec[0] = 0; + vec[1] = 0xfff40000; + iVar3 = func_80013328((s32)&D_80126B5C, param_1 + 4); + vec[2] = -((iVar3 << 0x10) / 0x22); + func_8012B14C(param_1, (s32)vec); + *(s32 *)(param_1 + 0x48) = 0xc000; + return; + case 1: + *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x10) + 0x80; + iVar3 = ((s32 (*)(s32, s32))func_8012CC64)(param_1, (s32)&D_801BD43C); + if (iVar3 == 0) { + return; + } + sVar2 = *(u16 *)(param_1 + 0x34); + *(s32 *)(param_1 + 0x1c) = 0; + *(u16 *)(param_1 + 0x34) = sVar2 + 1; + return; + case 2: + *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x10) + 0x40; + uVar4 = ((s32 (*)(s32, s32))func_8012CC64)(param_1, (s32)&D_801BD43C); + if ((uVar4 & 0x2000) == 0) { + return; + } + iVar4 = *(s32 *)(param_1 + 0x1c) + 1; + *(s32 *)(param_1 + 0x1c) = iVar4; + if (iVar4 >= 4) { + sVar2 = *(u16 *)(param_1 + 0x34); + *(s32 *)(param_1 + 0x1c) = 0x1e; + *(u16 *)(param_1 + 0x34) = sVar2 + 1; + return; + } + iVar3 = *(s32 *)(param_1 + 0x10) * 0xc; + if (iVar3 < 0) { + iVar3 = iVar3 + 0xf; + } + *(s32 *)(param_1 + 0x10) = iVar3 >> 4; + iVar5 = *(s32 *)(param_1 + 0x18) * 0xc; + if (iVar5 < 0) { + iVar5 = iVar5 + 0xf; + } + *(s32 *)(param_1 + 0x18) = iVar5 >> 4; + *(s32 *)(param_1 + 0x14) = -(0x80000 / *(s32 *)(param_1 + 0x1c)); + func_80143B6C(param_1, 1); + return; + case 3: + uVar4 = *(u32 *)(param_1 + 0x1c); + if ((uVar4 - 0xe < 0xb) && ((uVar4 & 1) == 0)) { + ((void (*)(s32, s32, s32))func_8012C658)(0x2a8, (s32)*(s16 *)(param_1 + 0x104), param_1); + *(u16 *)(param_1 + 0x104) = *(u16 *)(param_1 + 0x104) + 1; + __asm__ __volatile__(""); + uVar4 = *(u32 *)(param_1 + 0x1c); + } + if (uVar4 == 9) { + *(u32 *)(*(s32 *)(param_1 + 0xcc) + 4) = + *(u32 *)(*(s32 *)(param_1 + 0xcc) + 4) & 0x7fffffff; + *(s16 *)(*(s32 *)(param_1 + 0xcc) + 8) = *(u16 *)(param_1 + 6); + *(s16 *)(*(s32 *)(param_1 + 0xcc) + 0xa) = + *(u16 *)(param_1 + 0xa) - 0x24; + *(s16 *)(*(s32 *)(param_1 + 0xcc) + 0xc) = *(u16 *)(param_1 + 0xe); + } + if (*(s32 *)(param_1 + 0x1c) - 4U < 6) { + *(s16 *)(*(s32 *)(param_1 + 0xcc) + 0x18) = + *(u16 *)(*(s32 *)(param_1 + 0xcc) + 0x18) + 0x200; + *(s16 *)(*(s32 *)(param_1 + 0xcc) + 0x1a) = + *(u16 *)(*(s32 *)(param_1 + 0xcc) + 0x1a) + 0x200; + } + iVar3 = func_8012BEE8(param_1); + if (iVar3 != 1) { + return; + } + ((void (*)(s32, s32))func_80016714)(*(s32 *)(param_1 + 0xcc), 0x38); + *(s16 *)(param_1 + 2) = 9; + func_80187094(param_1, 0); + return; + } + return; +} + extern void func_80049CAC(s32, s32); @@ -4455,7 +4632,136 @@ void func_80187548(void *a0) { } -INCLUDE_ASM("asm/ov_SC06_022/nonmatchings/ov_SC06_022_jr_8017BEBC", func_80187584); + + +extern s32 rand(void); +extern void func_8012C1B8(void); +extern void func_8012CAE4(void*); +extern void func_8001C214(s32 a0, s32 a1); +extern void func_8012B2CC(s32 a0); +extern void func_8012B178(s32 a0, s32 a1); + +void func_80187584(s32 param_1) { + + extern u8 D_801BD4E0[]; + s32 unused[2]; /* dead 8-byte local — frame padding (cookbook idiom 6) */ + s32 obj; + s16 raw; + s32 r; + s32 sgn; + s32 v; + u8 *tbl; + s16 *p; + s32 q; + s32 w; + + obj = ((s32 (*)(void))func_8012C1B8)(); + if (obj == 0) { + ((void (*)(s32))func_8012CAE4)(param_1); + return; + } + *(s32 *)(param_1 + 0x20) = obj; + func_8001C214(obj, 0); + + raw = rand(); + r = raw; + *(u16 *)(obj + 0x2C) = *(u16 *)(obj + 0x2C) | 0x10; + v = r % 384 + 0x400; + *(s16 *)(obj + 0x1C) = v; + *(s16 *)(obj + 0x1A) = v; + *(s16 *)(obj + 0x18) = v; + sgn = -1; + if (raw & 1) { + sgn = 1; + } + *(s16 *)(obj + 0x10) = sgn * (r % 128) - 0x300; + *(s16 *)(obj + 0x12) = r % 4096; + *(s32 *)(param_1 + 0x48) = 0xC000; + *(u16 *)(param_1 + 0xA) = *(u16 *)(param_1 + 0xA) - 0x19; + func_8012B2CC(param_1); + func_8012B178(param_1, -0xC0000 - ((r % 8) << 16)); + *(s32 *)(param_1 + 0x1C) = 0x3C; + *(s16 *)(param_1 + 0xFE) = rand() & 0xF0; + *(s16 *)(param_1 + 0x100) = rand() & 0x1F0; + *(s16 *)(param_1 + 0x102) = rand() & 0x30; + tbl = &D_801BD4E0[(*(u16 *)(param_1 + 0x70) & 0xF) * 4]; + + p = (s16 *)(param_1 + 0xDC); + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q - 0x18; + } else { + w = q - 0x18; + } + p[0] = w; + p[1] = 0; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q - 0x18; + } else { + w = q - 0x18; + } + p[2] = w; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q + 0x18; + } else { + w = q + 0x18; + } + p[4] = w; + p[5] = 0; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q - 0x18; + } else { + w = q - 0x18; + } + p[6] = w; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q - 0x18; + } else { + w = q - 0x18; + } + p[8] = w; + p[9] = 0; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q + 0x18; + } else { + w = q + 0x18; + } + p[10] = w; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q + 0x18; + } else { + w = q + 0x18; + } + p[12] = w; + p[13] = 0; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q + 0x18; + } else { + w = q + 0x18; + } + p[14] = w; + + *((u8 *)p + 0x20) = tbl[0]; + *((u8 *)p + 0x21) = tbl[1]; + *((u8 *)p + 0x22) = tbl[2]; + *(u16 *)(param_1 + 2) = *(u16 *)(param_1 + 2) + 1; +} + extern s32 func_8012CBF4(s32 a0); @@ -4848,7 +5154,163 @@ docopy: } -INCLUDE_ASM("asm/ov_SC06_022/nonmatchings/ov_SC06_022_jr_8017BEBC", func_80188964); + + +/* func_80188964 — ov_SC06_008 / ov_SC06_008_jr_8017C294 + * + * Two-arm actor tick keyed on the s16 countdown at actor+0xFC: + * arm A (counter == 0, the FALL-THROUGH / longer block): three func_8012C658 + * spawns with offset pokes, a sound cue, two child-actor state pokes, an + * 8-iteration 0x281 particle burst, then the RTP positional-sound block + * (the byte-proven RTP_SND shape from ov_SC03_099_jr_8017BEBC.c:5406). + * arm B (counter != 0): a func_8012913C(0x23) spawn scattered around the + * actor, VectorNormalSS toward D_801151D4->{0x5C,0x60,0x64}, sound 0xAF8. + * + * Declarations copied VERBATIM from the TU (one-pass grep, D2): + * D_801151D4 src/ov_SC06_008/ov_SC06_008_jr_8017C294.c:323 + * rand :956 + * VectorNormalSS :1849 + * func_8012C658 :2523 + * func_8012C588 :3767 + * func_8012C218 :3782 + * func_8002D4C8 :59 + * func_8004914C :2645 + * func_800491AC :2646 + * func_8012913C :4356 (non-prototype form, BELOW the splice point) + * func_8002AC00 :5447 (block-scope extern only) + * RotTransPers / D_800AF648 / func_8002A04C are not in this TU -> fleet-dominant forms. + */ + +extern s32 rand(void); +extern s32 VectorNormalSS(void *a0, void *a1); +extern s32 func_8012C658(s32 arg0, s32 arg1, s32 arg2); +extern s32 func_8012C588(s32 a0, s32 a1); +extern void func_8012C218(void *a0); +extern void func_8002D4C8(s32 a0, s32 a1); +extern void func_8004914C(void *a0); +extern void func_800491AC(void *a0); +extern void func_8002A04C(s32 a0); +extern void func_8002AC00(s32 a0); +extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3); +extern u8 *func_8012913C(); + +void func_80188964(s32 a0) +{ + + extern s32 D_801151D4; + extern u8 D_800AF648; + + /* L5: slot offsets are exact only through ONE struct — plain array locals + get 8-byte-rounded slots and pushed z/flag to 0x28/0x2C (measured). */ + struct { + u16 nv[4]; /* sp+0x10 */ + s16 rv[4]; /* sp+0x18 */ + u16 sxy[2]; /* sp+0x20 */ + s32 z; /* sp+0x24 */ + s32 flag; /* sp+0x28 */ + } L; + + s32 g; + s32 s0; + s32 i; + + g = D_801151D4; + + if (*(s16 *)(a0 + 0xFC) == 0) { + s0 = func_8012C658(0x33, 3, a0); + if (s0 != 0) { + *(u16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(u16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) - 8; + *(u16 *)(s0 + 0x1A) = *(u16 *)(s0 + 0x1A) - 5; + } + s0 = func_8012C658(0x33, 3, a0); + if (s0 != 0) { + *(u16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(u16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) - 8; + *(u16 *)(s0 + 0x1A) = *(u16 *)(s0 + 0x1A) + 5; + } + s0 = func_8012C658(0x32, 2, a0); + if (s0 != 0) { + *(u16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(u16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) + 8; + } + func_8002AC00(0x22); + + s0 = *(s32 *)(a0 + 0xCC); + *(s16 *)(s0 + 0x2) = 2; + *(s16 *)(s0 + 0xFC) = 1; + s0 = *(s32 *)(a0 + 0xD0); + *(s16 *)(s0 + 0x2) = 2; + *(s16 *)(s0 + 0xFC) = 1; + + for (i = 0; i < 8; i++) { + s0 = func_8012C588(0x281, a0); + if (s0 != 0) { + *(s32 *)(s0 + 0x1C) = 2; + *(u16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x30; + *(s16 *)(s0 + 0x12) = (rand() & 0x1F) - 0x10; + *(s16 *)(s0 + 0x16) = -((rand() & 0xF) + 0x10); + *(s16 *)(s0 + 0x1A) = (rand() & 0x1F) - 0x10; + } + } + + L.rv[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48); + L.rv[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C); + L.rv[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50); + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); } + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); } + RotTransPers((s32)L.rv, (s32)L.sxy, &L.z, &L.flag); + if (L.flag >= 0 && (u32)((L.sxy[0] + 0xEF) & 0xFFFF) < 0x1DF + && (u32)((L.sxy[1] + 0xB3) & 0xFFFF) < 0x167) { + s32 x = (s16)L.sxy[0]; + s32 ax; + + ax = x; + if (x < 0) { + ax = -x; + } + ax = ((0xF0 - ax) * 0x7F) / 0xF0; + __asm__("" : "=r"(ax) : "0"(ax)); + x = (x + 0xF0) / 0x1E; + if (x == 0x10) { + x = 0xF; + } + x = x << 8; + { + s32 flg = 0x3000; + func_8002D4C8(0x961, ((ax | flg) | x) & 0xFFFF); + } + } + func_8002A04C(a0); + func_8012C218((void *)a0); + } else { + s0 = (s32)func_8012913C(0x23); + if (s0 != 0) { + *(s16 *)(s0 + 0x6) = *(u16 *)(a0 + 0x6) + (rand() & 0x7F) - 0x40; + *(s16 *)(s0 + 0xA) = *(u16 *)(a0 + 0xA) + (rand() & 0x7F) - 0xE0; + { + s32 r = rand(); + s32 t = *(u16 *)(a0 + 0xE); + *(s16 *)(s0 + 0x34) = 0x1800; + *(s32 *)(s0 + 0x18) = 0; + *(s32 *)(s0 + 0x14) = 0; + *(s32 *)(s0 + 0x10) = 0; + *(s16 *)(s0 + 0xE) = t + (r & 0x7F) - 0x40; + } + L.nv[0] = *(s32 *)(g + 0x5C) - *(u16 *)(s0 + 0x6); + L.nv[1] = *(s32 *)(g + 0x60) - *(u16 *)(s0 + 0xA); + L.nv[2] = *(s32 *)(g + 0x64) - *(u16 *)(s0 + 0xE); + VectorNormalSS(L.nv, L.nv); + *(s16 *)(s0 + 0x6) = *(u16 *)(s0 + 0x6) + ((s16)L.nv[0] >> 6); + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) + ((s16)L.nv[1] >> 6); + *(s16 *)(s0 + 0xE) = *(u16 *)(s0 + 0xE) + ((s16)L.nv[2] >> 6); + *(s16 *)(s0 + 0x34) = 0x3000; + func_8002D4C8(0xAF8, 0); + } + *(u16 *)(a0 + 0xFC) = *(u16 *)(a0 + 0xFC) - 1; + } +} + INCLUDE_ASM("asm/ov_SC06_022/nonmatchings/ov_SC06_022_jr_8017BEBC", func_80188D68); @@ -4927,7 +5389,114 @@ big: INCLUDE_ASM("asm/ov_SC06_022/nonmatchings/ov_SC06_022_jr_8017BEBC", func_8018908C); -INCLUDE_ASM("asm/ov_SC06_022/nonmatchings/ov_SC06_022_jr_8017BEBC", func_80189318); +extern void func_8002D4C8(s32 a0, s32 a1); +extern s32 func_8004787C(s32 a0); +extern s32 func_80047948(s32 a0); +extern void func_8004914C(); +extern void func_800491AC(); +extern u8 *func_8012913C(s32 a0); +extern void func_8012A828(s32 a0, void * a1); +#define RTP_SND(sndid) \ + L.v[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48); \ + L.v[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C); \ + L.v[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50); \ + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); } \ + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); } \ + RotTransPers((s32)L.v, (s32)L.sxy, &L.z, &L.flag); \ + if (L.flag >= 0 && (u32)((L.sxy[0] + 0xEF) & 0xFFFF) < 0x1DF \ + && (u32)((L.sxy[1] + 0xB3) & 0xFFFF) < 0x167) { \ + s32 x = (s16)L.sxy[0]; \ + s32 ax; \ + ax = x; \ + if (x < 0) { \ + ax = -x; \ + } \ + ax = ((0xF0 - ax) * 0x7F) / 0xF0; \ + __asm__("" : "=r"(ax) : "0"(ax)); \ + x = (x + 0xF0) / 0x1E; \ + if (x == 0x10) { \ + x = 0xF; \ + } \ + x = x << 8; \ + { \ + s32 flg = 0x3000; \ + func_8002D4C8(sndid, ((ax | flg) | x) & 0xFFFF); \ + } \ + } + +void func_80189318(s32 a0) { + + extern u8 D_800AF648; + extern s32 D_801D591C[]; + extern u8 D_801DCDDC[]; + extern u8 D_801DCE64[]; + extern u8 D_801DCEEC[]; + struct { + s16 pad0[4]; /* sp+0x10 — dead, but sizes the frame (idiom 6) */ + s16 v[3]; /* sp+0x18 */ + s16 pad1; /* sp+0x1E */ + u16 sxy[2]; /* sp+0x20 */ + s32 z; /* sp+0x24 */ + s32 flag; /* sp+0x28 */ + } L; + s32 t; + s32 ang; + s32 idx; + s32 m; + s32 c; + s32 p; + + if (*(s16 *)(a0 + 0x98) == 0) { + s32 spr = (s32)func_8012913C(0x7F); + if (spr != 0) { + m = *(s16 *)(*(s32 *)(a0 + 0x20) + 0x12) + + (func_8004787C(*(s16 *)(a0 + 0x104)) >> 3); + *(s16 *)(spr + 0x6) = *(u16 *)(a0 + 0x6) - (func_8004787C(m) * 0x6C) / 0x1000; + *(s16 *)(spr + 0xA) = *(u16 *)(a0 + 0xA) - 0x34; + *(s16 *)(spr + 0xE) = *(u16 *)(a0 + 0xE) - (func_80047948(m) * 0x6C) / 0x1000; + *(s32 *)(spr + 0x14) = 0x40000; + *(s32 *)(spr + 0x10) = -(func_8004787C(m) * 0xC0); + *(s32 *)(spr + 0x18) = -(func_80047948(m) * 0xC0); + } + t = *(u16 *)(a0 + 0x104) + 0x100; + *(s16 *)(a0 + 0x104) = t; + ang = (s16)t; + idx = ang / 0x100; + m = (s16)(idx % 0x10); + if (ang == 0x100) { + RTP_SND(0x95F) + } else if (m == 0) { + RTP_SND(0x960) + } + *(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) = D_801D591C[m]; + c = *(u16 *)(a0 + 0x100) - 1; + *(s16 *)(a0 + 0x100) = c; + if ((s16)c == 0) { + p = *(s32 *)(a0 + 0xCC); + *(s16 *)(a0 + 0x98) = 1; + if (p != 0) { + *(s16 *)(p + 0x98) = 1; + } + p = *(s32 *)(a0 + 0xD0); + if (p != 0) { + *(s16 *)(p + 0x98) = 1; + } + } + } else if ((*(u16 *)(a0 + 0x72) & 0x4000) != 0) { + *(s16 *)(a0 + 0x2) = 7; + *(s16 *)(a0 + 0x100) = 0x3C; + func_8012A828(a0, D_801DCDDC); + p = *(s32 *)(a0 + 0xCC); + if (p != 0) { + func_8012A828(p, D_801DCE64); + } + p = *(s32 *)(a0 + 0xD0); + if (p != 0) { + func_8012A828(p, D_801DCEEC); + } + } +} + INCLUDE_ASM("asm/ov_SC06_022/nonmatchings/ov_SC06_022_jr_8017BEBC", func_801897DC); @@ -5017,7 +5586,149 @@ void func_80189EB4(int param_1) } -INCLUDE_ASM("asm/ov_SC06_022/nonmatchings/ov_SC06_022_jr_8017BEBC", func_8018A0AC); + + + +extern s32 func_8012C658(s32 arg0, s32 arg1, s32 arg2); +extern s32 func_8012C588(s32 a0, s32 a1); +extern void func_8012C218(void *a0); +extern u8 *func_8012913C(s32 a0); +extern s32 func_80047948(s32 a0); +extern s32 func_8004787C(s32 a0); +extern void func_8004914C(void *a0); +extern void func_800491AC(void *a0); +extern s32 VectorNormalSS(void *a0, void *a1); +extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3); +extern void func_8002D4C8(s32 a0, s32 a1); +extern s32 rand(void); + +void func_8018A0AC(s32 a0) { + + extern s32 D_801151D4; + + extern void func_8002AC00(s32 arg0); + extern void func_8002A04C(s32 arg0); + extern u8 D_800AF648; + + u16 v10[4]; /* sp+0x10 */ + s16 v18[4]; /* sp+0x18 */ + s32 sxy; /* sp+0x20 */ + s32 z; /* sp+0x24 */ + s32 flag; /* sp+0x28 */ + s32 base; + s32 iv; + s32 i; + s32 t; + s32 r; + + base = D_801151D4; + + if (*(s16 *)(a0 + 0xFC) >= 0x1F) { + iv = func_8012C658(0x33, 3, a0); + if (iv != 0) { + *(u16 *)(iv + 0x0A) = *(u16 *)(iv + 0x0A) - 0x20; + *(u16 *)(iv + 0x12) = *(u16 *)(iv + 0x12) - 8; + *(u16 *)(iv + 0x1A) = *(u16 *)(iv + 0x1A) - 5; + } + iv = func_8012C658(0x33, 3, a0); + if (iv != 0) { + *(u16 *)(iv + 0x0A) = *(u16 *)(iv + 0x0A) - 0x20; + *(u16 *)(iv + 0x12) = *(u16 *)(iv + 0x12) - 8; + *(u16 *)(iv + 0x1A) = *(u16 *)(iv + 0x1A) + 5; + } + iv = func_8012C658(0x32, 2, a0); + if (iv != 0) { + *(u16 *)(iv + 0x0A) = *(u16 *)(iv + 0x0A) - 0x20; + *(u16 *)(iv + 0x12) = *(u16 *)(iv + 0x12) + 8; + } + + func_8002AC00(0x22); + + iv = *(s32 *)(a0 + 0x64); + *(s16 *)(iv + 2) = 2; + iv = *(s32 *)(*(s32 *)(a0 + 0x64) + 0xD0); + *(s16 *)(iv + 2) = 4; + *(s32 *)(*(s32 *)(a0 + 0x64) + 0xCC) = 0; + + i = 0; + do { + iv = func_8012C588(0x281, a0); + if (iv != 0) { + *(s32 *)(iv + 0x1C) = 2; + *(s16 *)(iv + 0x12) = (rand() & 0x1F) - 0x10; + *(s16 *)(iv + 0x16) = -((rand() & 0x0F) + 0x10); + *(s16 *)(iv + 0x1A) = (rand() & 0x1F) - 0x10; + } + i++; + } while (i < 8); + + v18[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48); + v18[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C); + v18[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50); + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); } + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); } + RotTransPers((s32)v18, (s32)&sxy, &z, &flag); + if (flag >= 0 && (u32)((*(u16 *)&sxy + 0xEF) & 0xFFFF) < 0x1DF + && (u32)((*((u16 *)&sxy + 1) + 0xB3) & 0xFFFF) < 0x167) { + s32 sx; + s32 av; + + sx = (s16)*(u16 *)&sxy; + av = sx; + if (sx < 0) { + av = -sx; + } + /* one local for |x| AND the volume: gcc-2.7.2 keeps the single pseudo + in $v1 in place (subu $v1,$v0,$v1); a separate `vol` local steals $a1 + and the whole OR chain drifts (cookbook §136 L1). */ + av = ((0xF0 - av) * 0x7F) / 0xF0; + sx = (sx + 0xF0) / 0x1E; + if (sx == 0x10) { + sx = 0xF; + } + sx = sx << 8; + func_8002D4C8(0x961, (av | (0x3000 | sx)) & 0xFFFF); + } + + func_8002A04C(a0); + func_8012C218((void *)a0); + return; + } + + iv = (s32)func_8012913C(0x23); + if (iv != 0) { + r = rand(); + *(u16 *)(iv + 0x06) = *(u16 *)(a0 + 0x06) + (r & 0x7F) - 0x40; + r = rand(); + *(u16 *)(iv + 0x0A) = *(u16 *)(a0 + 0x0A) + (r & 0x7F) - 0x80; + r = rand(); + *(u16 *)(iv + 0x0E) = *(u16 *)(a0 + 0x0E) + (r & 0x7F) - 0x40; + + t = func_80047948((s32) * (s16 *)(*(s32 *)(a0 + 0x20) + 0x12)); + *(s32 *)(iv + 0x04) = *(s32 *)(iv + 0x04) + (t << 10); + + t = func_8004787C((s32) * (s16 *)(*(s32 *)(a0 + 0x20) + 0x12)); + *(u16 *)(iv + 0x34) = 0x1800; + *(s32 *)(iv + 0x18) = 0; + *(s32 *)(iv + 0x14) = 0; + *(s32 *)(iv + 0x10) = 0; + *(s32 *)(iv + 0x0C) = *(s32 *)(iv + 0x0C) - (t << 10); + + v10[0] = *(s32 *)(base + 0x5C) - *(u16 *)(iv + 0x06); + v10[1] = *(s32 *)(base + 0x60) - *(u16 *)(iv + 0x0A); + v10[2] = *(s32 *)(base + 0x64) - *(u16 *)(iv + 0x0E); + VectorNormalSS(v10, v10); + + *(u16 *)(iv + 0x06) = *(u16 *)(iv + 0x06) + ((s16)v10[0] >> 6); + *(u16 *)(iv + 0x0A) = *(u16 *)(iv + 0x0A) + ((s16)v10[1] >> 6); + *(u16 *)(iv + 0x0E) = *(u16 *)(iv + 0x0E) + ((s16)v10[2] >> 6); + *(u16 *)(iv + 0x34) = 0x3000; + func_8002D4C8(0xAF8, 0); + } + + *(u16 *)(a0 + 0xFC) = *(u16 *)(a0 + 0xFC) + 1; +} + // @class: struct @@ -5081,7 +5792,143 @@ void func_8018A4F4(short *param_1) } -INCLUDE_ASM("asm/ov_SC06_022/nonmatchings/ov_SC06_022_jr_8017BEBC", func_8018A704); + + +extern s32 func_8012C658(s32 arg0, s32 arg1, s32 arg2); +extern s32 func_8012C588(s32 a0, s32 a1); +extern void func_8012C218(void *a0); +extern u8 *func_8012913C(); +extern s32 rand(void); +extern s32 func_80047948(s32 a0); +extern s32 func_8004787C(s32 a0); +extern s32 VectorNormalSS(void *a0, void *a1); +extern void func_8004914C(void *a0); +extern void func_800491AC(void *a0); +extern void func_8002D4C8(s32 a0, s32 a1); +extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3); +extern void func_8002A04C(s32 a0); + + +void func_8018A704(s32 a0) { + + extern s32 D_801151D4; + + extern u8 D_800AF648; + extern void func_8002AC00(s32 arg0); + + struct { + u16 nv[4]; /* sp+0x10 */ + s16 v[4]; /* sp+0x18 */ + u16 sxy[2]; /* sp+0x20 */ + s32 z; /* sp+0x24 */ + s32 flag; /* sp+0x28 */ + } L; + s32 p; + s32 s0; + s32 i; + + p = D_801151D4; + + if (*(s16 *)(a0 + 0xFC) >= 0x1F) { + s0 = func_8012C658(0x33, 3, a0); + if (s0 != 0) { + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(s16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) - 8; + *(s16 *)(s0 + 0x1A) = *(u16 *)(s0 + 0x1A) - 5; + } + s0 = func_8012C658(0x33, 3, a0); + if (s0 != 0) { + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(s16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) - 8; + *(s16 *)(s0 + 0x1A) = *(u16 *)(s0 + 0x1A) + 5; + } + s0 = func_8012C658(0x32, 2, a0); + if (s0 != 0) { + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(s16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) + 8; + } + func_8002AC00(0x22); + s0 = *(s32 *)(a0 + 0x64); + *(s16 *)(s0 + 0x2) = 4; + s0 = *(s32 *)(*(s32 *)(a0 + 0x64) + 0xCC); + *(s16 *)(s0 + 0x2) = 4; + + for (i = 0; i < 8; i++) { + s0 = func_8012C588(0x281, a0); + if (s0 != 0) { + *(s32 *)(s0 + 0x1C) = 2; + *(s16 *)(s0 + 0x12) = (rand() & 0x1F) - 0x10; + *(s16 *)(s0 + 0x16) = -((rand() & 0xF) + 0x10); + *(s16 *)(s0 + 0x1A) = (rand() & 0x1F) - 0x10; + } + } + + L.v[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48); + L.v[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C); + L.v[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50); + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); } + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); } + RotTransPers((s32)L.v, (s32)L.sxy, &L.z, &L.flag); + if (L.flag >= 0 && (u32)((L.sxy[0] + 0xEF) & 0xFFFF) < 0x1DF + && (u32)((L.sxy[1] + 0xB3) & 0xFFFF) < 0x167) { + s32 x = (s16)L.sxy[0]; + s32 ax; + ax = x; + if (x < 0) { + ax = -x; + } + ax = ((0xF0 - ax) * 0x7F) / 0xF0; + __asm__("" : "=r"(ax) : "0"(ax)); + x = (x + 0xF0) / 0x1E; + if (x == 0x10) { + x = 0xF; + } + x = x << 8; + { + s32 flg = 0x3000; + func_8002D4C8(0x961, ((ax | flg) | x) & 0xFFFF); + } + } + + *(s32 *)(*(s32 *)(a0 + 0x64) + 0xD0) = 0; + func_8002A04C(a0); + func_8012C218((void *)a0); + return; + } + + s0 = (s32)func_8012913C(0x23); + if (s0 != 0) { + *(s16 *)(s0 + 0x6) = *(u16 *)(a0 + 0x6) + (rand() & 0x7F) - 0x40; + *(s16 *)(s0 + 0xA) = *(u16 *)(a0 + 0xA) + (rand() & 0x7F) - 0x80; + *(s16 *)(s0 + 0xE) = *(u16 *)(a0 + 0xE) + (rand() & 0x7F) - 0x40; + + *(s32 *)(s0 + 0x4) = + *(s32 *)(s0 + 0x4) - + func_80047948(*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12)) * 0x400; + { + s32 t = func_8004787C(*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12)) * 0x400; + *(s16 *)(s0 + 0x34) = 0x1800; + *(s32 *)(s0 + 0x18) = 0; + *(s32 *)(s0 + 0x14) = 0; + *(s32 *)(s0 + 0x10) = 0; + *(s32 *)(s0 + 0xC) = *(s32 *)(s0 + 0xC) + t; + } + + L.nv[0] = *(s32 *)(p + 0x5C) - *(u16 *)(s0 + 0x6); + L.nv[1] = *(s32 *)(p + 0x60) - *(u16 *)(s0 + 0xA); + L.nv[2] = *(s32 *)(p + 0x64) - *(u16 *)(s0 + 0xE); + VectorNormalSS(L.nv, L.nv); + + *(s16 *)(s0 + 0x6) = *(u16 *)(s0 + 0x6) + ((s16)L.nv[0] >> 6); + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) + ((s16)L.nv[1] >> 6); + *(s16 *)(s0 + 0xE) = *(u16 *)(s0 + 0xE) + ((s16)L.nv[2] >> 6); + *(s16 *)(s0 + 0x34) = 0x3000; + func_8002D4C8(0xAF8, 0); + } + + *(s16 *)(a0 + 0xFC) = *(u16 *)(a0 + 0xFC) + 1; +} + extern s32 rand(void); diff --git a/src/ov_SC06_024/ov_SC06_024_jr_8017BEBC.c b/src/ov_SC06_024/ov_SC06_024_jr_8017BEBC.c index 0bb26dd68..c6e58f320 100644 --- a/src/ov_SC06_024/ov_SC06_024_jr_8017BEBC.c +++ b/src/ov_SC06_024/ov_SC06_024_jr_8017BEBC.c @@ -318,7 +318,6 @@ extern s32 func_80012B04(s32 a0, s32 a1, s32 a2); extern void func_801490F8(s32 a0, s32 a1); extern s32 func_801491C4(s32 a0); extern s32 func_80149184(s32 a0); -extern s32 D_801151D4; extern void func_80149204(s32 *a0); extern void func_80149210(s32 a0, s32 a1); extern s32 func_80149284(s32 *a0, s32 a1); @@ -4226,7 +4225,26 @@ void func_80183640(void *a0) { INCLUDE_ASM("asm/ov_SC06_024/nonmatchings/ov_SC06_024_jr_8017BEBC", func_8018367C); -INCLUDE_ASM("asm/ov_SC06_024/nonmatchings/ov_SC06_024_jr_8017BEBC", func_801837D0); + +extern void func_8012B23C(); +extern s32 rand(void); +extern void func_8012AD44(s32 *a0, s16 a1); + +void func_801837D0(s32 a0) { + func_8012B23C(a0); + *(s32 *)(a0 + 0x10) = ((rand() & 0x7F) - 0x40) << 11; + *(s32 *)(a0 + 0x14) = -((rand() & 0x7F) << 13); + *(s32 *)(a0 + 0x18) = (rand() & 0x7F) << 13; + *(u16 *)(a0 + 0x106) = rand() & 0x1F0; + *(u16 *)(a0 + 0x108) = rand() & 0x1F0; + *(s16 *)(a0 + 0xE6) = 8; + { + s32 v = *(s16 *)(a0 + 0x70); + *(s16 *)(a0 + 0xE4) = v << 1; + } + ((void (*)(s32, s32))func_8012AD44)(a0, 1); +} + INCLUDE_ASM("asm/ov_SC06_024/nonmatchings/ov_SC06_024_jr_8017BEBC", func_8018386C); @@ -4930,7 +4948,167 @@ INCLUDE_ASM("asm/ov_SC06_024/nonmatchings/ov_SC06_024_jr_8017BEBC", func_80188AC INCLUDE_ASM("asm/ov_SC06_024/nonmatchings/ov_SC06_024_jr_8017BEBC", func_80188BF8); -INCLUDE_ASM("asm/ov_SC06_024/nonmatchings/ov_SC06_024_jr_8017BEBC", func_80188C1C); + +// @class: struct +// @stuck: none — MATCH (276 ins, relocation-masked). Verified BOTH standalone (match_one) and +// spliced into src/ov_SC06_018/ov_SC06_018_jr_8017C24C.c (whole-TU cc1 -O2 clean, +// masked structured_diff 0/276). +// Keys: (1) the first func_8012C218 call gets a NOP delay slot because reload_cse_regs deletes the +// redundant `move a0,s1` -- $a0 still holds the incoming param on the fall-through path +// (no CODE_LABEL between the prologue and the jal). The second call site is behind a +// label, so the move survives. Source is the natural `((void (*)(void *))func_8012C218)((void *)param_1)` at +// BOTH sites -- do NOT write a zero-arg call (it also breaks in-TU: the composite type +// from the earlier file-scope `extern void ((void (*)(void *))func_8012C218)(void *a0);` rejects 0 args). +// (2) case 0's guard is an `||` with an early return -- that is what puts `beqz -> fail` then +// `beq -> ok` (an `&&` would emit `bne -> fail`). +// (3) `register s32 sVar2 __asm__("$2")` holds the p+0x34 reload in cases 1/2 so the two arms +// cross-jump into the shared .L80188928 tail. +// (4) `__asm__ __volatile__("")` after the func_8012C658 arm forces the `lw v1,0x1C(s1)` +// reload before the cross-jumped `li v0,9` (§21 zero-byte re-tie). +// (5) `-((iVar3 << 0x10) / 0x22)` reproduces the 0x78787879/sra-4 magic-divide by 34 + negu. +// (6) `*p * 0xc` then `>>4` with the manual `if (x<0) x+=0xf` is the /16 rounding form. + +extern void func_8012C218(s32); +extern void func_801898EC(s32, void*, void*, s32); +extern s32 func_80013328(s32 a0, s32 a1); +extern void func_8012B14C(s32 a0, s32 a1); +extern void func_8012CC64(s32 a0, s32 a1); /* fleet-canonical: void; $v0 used -> cast at use */ +extern s32 func_8012C658(s32, s32, s32); +extern s32 func_80143B6C(s32 a0, s32 a1); /* fleet-canonical */ +extern s32 func_8012BEE8(s32 a0); +extern void func_80016714(void*, s32); +extern void func_8018956C(s32 a0, s32 a1); + + +void func_80188C1C(s32 param_1) { + + extern u8 D_801D4314; + extern u8 D_801BC588; + extern u8 D_801BC590; + extern u8 D_801BC580; + extern u8 D_80126B5C; + u16 uVar1; + register s32 sVar2 __asm__("$2"); + s32 iVar3; + s32 iVar4; + s32 iVar5; + u32 uVar4; + s32 psVar5; + u16 buf[8]; + s32 vec[3]; + + if (0xf < *(s16 *)(param_1 + 0xA)) { + ((void (*)(void *))func_8012C218)((void *)param_1); + return; + } + uVar1 = *(u16 *)(param_1 + 0x34); + switch (uVar1) { + case 0: + psVar5 = *(s32 *)(param_1 + 0x64); + if ((*(u16 *)psVar5 == 0) || + (*(s32 *)(psVar5 + 0x90) != (s32)&D_801D4314)) { + ((void (*)(void *))func_8012C218)((void *)param_1); + return; + } + if (*(s32 *)(psVar5 + 0x94) < 0x11) { + ((void (*)(void *, void *, void *, s32))func_801898EC)((void *)psVar5, (void *)&D_801BC588, buf, 5); + *(s16 *)(param_1 + 6) = buf[0]; + *(s16 *)(param_1 + 0xA) = buf[1]; + *(s16 *)(param_1 + 0xE) = buf[2]; + return; + } + ((void (*)(void *, void *, void *, s32))func_801898EC)((void *)psVar5, (void *)&D_801BC590, buf, 4); + ((void (*)(void *, void *, void *, s32))func_801898EC)((void *)psVar5, (void *)&D_801BC590, &buf[4], 5); + *(s16 *)(param_1 + 6) = + (s16)((*(s16 *)&buf[0] + *(s16 *)&buf[4]) >> 1); + *(s16 *)(param_1 + 0xA) = + (s16)((*(s16 *)&buf[1] + *(s16 *)&buf[5]) >> 1); + *(s16 *)(param_1 + 0xE) = + (s16)((*(s16 *)&buf[2] + *(s16 *)&buf[6]) >> 1); + if (*(s32 *)(psVar5 + 0x94) != 0x19) { + return; + } + *(u16 *)(param_1 + 0x34) = *(u16 *)(param_1 + 0x34) + 1; + vec[0] = 0; + vec[1] = 0xfff40000; + iVar3 = func_80013328((s32)&D_80126B5C, param_1 + 4); + vec[2] = -((iVar3 << 0x10) / 0x22); + func_8012B14C(param_1, (s32)vec); + *(s32 *)(param_1 + 0x48) = 0xc000; + return; + case 1: + *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x10) + 0x80; + iVar3 = ((s32 (*)(s32, s32))func_8012CC64)(param_1, (s32)&D_801BC580); + if (iVar3 == 0) { + return; + } + sVar2 = *(u16 *)(param_1 + 0x34); + *(s32 *)(param_1 + 0x1c) = 0; + *(u16 *)(param_1 + 0x34) = sVar2 + 1; + return; + case 2: + *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x10) + 0x40; + uVar4 = ((s32 (*)(s32, s32))func_8012CC64)(param_1, (s32)&D_801BC580); + if ((uVar4 & 0x2000) == 0) { + return; + } + iVar4 = *(s32 *)(param_1 + 0x1c) + 1; + *(s32 *)(param_1 + 0x1c) = iVar4; + if (iVar4 >= 4) { + sVar2 = *(u16 *)(param_1 + 0x34); + *(s32 *)(param_1 + 0x1c) = 0x1e; + *(u16 *)(param_1 + 0x34) = sVar2 + 1; + return; + } + iVar3 = *(s32 *)(param_1 + 0x10) * 0xc; + if (iVar3 < 0) { + iVar3 = iVar3 + 0xf; + } + *(s32 *)(param_1 + 0x10) = iVar3 >> 4; + iVar5 = *(s32 *)(param_1 + 0x18) * 0xc; + if (iVar5 < 0) { + iVar5 = iVar5 + 0xf; + } + *(s32 *)(param_1 + 0x18) = iVar5 >> 4; + *(s32 *)(param_1 + 0x14) = -(0x80000 / *(s32 *)(param_1 + 0x1c)); + func_80143B6C(param_1, 1); + return; + case 3: + uVar4 = *(u32 *)(param_1 + 0x1c); + if ((uVar4 - 0xe < 0xb) && ((uVar4 & 1) == 0)) { + ((void (*)(s32, s32, s32))func_8012C658)(0x2a8, (s32)*(s16 *)(param_1 + 0x104), param_1); + *(u16 *)(param_1 + 0x104) = *(u16 *)(param_1 + 0x104) + 1; + __asm__ __volatile__(""); + uVar4 = *(u32 *)(param_1 + 0x1c); + } + if (uVar4 == 9) { + *(u32 *)(*(s32 *)(param_1 + 0xcc) + 4) = + *(u32 *)(*(s32 *)(param_1 + 0xcc) + 4) & 0x7fffffff; + *(s16 *)(*(s32 *)(param_1 + 0xcc) + 8) = *(u16 *)(param_1 + 6); + *(s16 *)(*(s32 *)(param_1 + 0xcc) + 0xa) = + *(u16 *)(param_1 + 0xa) - 0x24; + *(s16 *)(*(s32 *)(param_1 + 0xcc) + 0xc) = *(u16 *)(param_1 + 0xe); + } + if (*(s32 *)(param_1 + 0x1c) - 4U < 6) { + *(s16 *)(*(s32 *)(param_1 + 0xcc) + 0x18) = + *(u16 *)(*(s32 *)(param_1 + 0xcc) + 0x18) + 0x200; + *(s16 *)(*(s32 *)(param_1 + 0xcc) + 0x1a) = + *(u16 *)(*(s32 *)(param_1 + 0xcc) + 0x1a) + 0x200; + } + iVar3 = func_8012BEE8(param_1); + if (iVar3 != 1) { + return; + } + ((void (*)(s32, s32))func_80016714)(*(s32 *)(param_1 + 0xcc), 0x38); + *(s16 *)(param_1 + 2) = 9; + func_8018956C(param_1, 0); + return; + } + return; +} + extern void func_80049CAC(s32, s32); @@ -4988,7 +5166,136 @@ void func_80189A20(void *a0) { } -INCLUDE_ASM("asm/ov_SC06_024/nonmatchings/ov_SC06_024_jr_8017BEBC", func_80189A5C); + + +extern s32 rand(void); +extern void func_8012C1B8(void); +extern void func_8012CAE4(s32 a0); +extern void func_8001C214(s32 a0, s32 a1); +extern void func_8012B2CC(s32 a0); +extern void func_8012B178(s32 a0, s32 a1); + +void func_80189A5C(s32 param_1) { + + extern u8 D_801BC624[]; + s32 unused[2]; /* dead 8-byte local — frame padding (cookbook idiom 6) */ + s32 obj; + s16 raw; + s32 r; + s32 sgn; + s32 v; + u8 *tbl; + s16 *p; + s32 q; + s32 w; + + obj = ((s32 (*)(void))func_8012C1B8)(); + if (obj == 0) { + func_8012CAE4(param_1); + return; + } + *(s32 *)(param_1 + 0x20) = obj; + func_8001C214(obj, 0); + + raw = rand(); + r = raw; + *(u16 *)(obj + 0x2C) = *(u16 *)(obj + 0x2C) | 0x10; + v = r % 384 + 0x400; + *(s16 *)(obj + 0x1C) = v; + *(s16 *)(obj + 0x1A) = v; + *(s16 *)(obj + 0x18) = v; + sgn = -1; + if (raw & 1) { + sgn = 1; + } + *(s16 *)(obj + 0x10) = sgn * (r % 128) - 0x300; + *(s16 *)(obj + 0x12) = r % 4096; + *(s32 *)(param_1 + 0x48) = 0xC000; + *(u16 *)(param_1 + 0xA) = *(u16 *)(param_1 + 0xA) - 0x19; + func_8012B2CC(param_1); + func_8012B178(param_1, -0xC0000 - ((r % 8) << 16)); + *(s32 *)(param_1 + 0x1C) = 0x3C; + *(s16 *)(param_1 + 0xFE) = rand() & 0xF0; + *(s16 *)(param_1 + 0x100) = rand() & 0x1F0; + *(s16 *)(param_1 + 0x102) = rand() & 0x30; + tbl = &D_801BC624[(*(u16 *)(param_1 + 0x70) & 0xF) * 4]; + + p = (s16 *)(param_1 + 0xDC); + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q - 0x18; + } else { + w = q - 0x18; + } + p[0] = w; + p[1] = 0; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q - 0x18; + } else { + w = q - 0x18; + } + p[2] = w; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q + 0x18; + } else { + w = q + 0x18; + } + p[4] = w; + p[5] = 0; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q - 0x18; + } else { + w = q - 0x18; + } + p[6] = w; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q - 0x18; + } else { + w = q - 0x18; + } + p[8] = w; + p[9] = 0; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q + 0x18; + } else { + w = q + 0x18; + } + p[10] = w; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q + 0x18; + } else { + w = q + 0x18; + } + p[12] = w; + p[13] = 0; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q + 0x18; + } else { + w = q + 0x18; + } + p[14] = w; + + *((u8 *)p + 0x20) = tbl[0]; + *((u8 *)p + 0x21) = tbl[1]; + *((u8 *)p + 0x22) = tbl[2]; + *(u16 *)(param_1 + 2) = *(u16 *)(param_1 + 2) + 1; +} + extern s32 func_8012CBF4(s32 a0); @@ -5378,7 +5685,163 @@ docopy: } -INCLUDE_ASM("asm/ov_SC06_024/nonmatchings/ov_SC06_024_jr_8017BEBC", func_8018AE3C); + + +/* func_8018AE3C — ov_SC06_008 / ov_SC06_008_jr_8017C294 + * + * Two-arm actor tick keyed on the s16 countdown at actor+0xFC: + * arm A (counter == 0, the FALL-THROUGH / longer block): three func_8012C658 + * spawns with offset pokes, a sound cue, two child-actor state pokes, an + * 8-iteration 0x281 particle burst, then the RTP positional-sound block + * (the byte-proven RTP_SND shape from ov_SC03_099_jr_8017BEBC.c:5406). + * arm B (counter != 0): a func_8012913C(0x23) spawn scattered around the + * actor, VectorNormalSS toward D_801151D4->{0x5C,0x60,0x64}, sound 0xAF8. + * + * Declarations copied VERBATIM from the TU (one-pass grep, D2): + * D_801151D4 src/ov_SC06_008/ov_SC06_008_jr_8017C294.c:323 + * rand :956 + * VectorNormalSS :1849 + * func_8012C658 :2523 + * func_8012C588 :3767 + * func_8012C218 :3782 + * func_8002D4C8 :59 + * func_8004914C :2645 + * func_800491AC :2646 + * func_8012913C :4356 (non-prototype form, BELOW the splice point) + * func_8002AC00 :5447 (block-scope extern only) + * RotTransPers / D_800AF648 / func_8002A04C are not in this TU -> fleet-dominant forms. + */ + +extern s32 rand(void); +extern s32 VectorNormalSS(void *a0, void *a1); +extern s32 func_8012C658(s32 arg0, s32 arg1, s32 arg2); +extern s32 func_8012C588(s32 a0, s32 a1); +extern void func_8012C218(s32); +extern void func_8002D4C8(s32 a0, s32 a1); +extern void func_8004914C(void *a0); +extern void func_800491AC(void *a0); +extern void func_8002A04C(s32 a0); +extern void func_8002AC00(s32 a0); +extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3); +extern u8 *func_8012913C(); + +void func_8018AE3C(s32 a0) +{ + + extern s32 D_801151D4; + extern u8 D_800AF648; + + /* L5: slot offsets are exact only through ONE struct — plain array locals + get 8-byte-rounded slots and pushed z/flag to 0x28/0x2C (measured). */ + struct { + u16 nv[4]; /* sp+0x10 */ + s16 rv[4]; /* sp+0x18 */ + u16 sxy[2]; /* sp+0x20 */ + s32 z; /* sp+0x24 */ + s32 flag; /* sp+0x28 */ + } L; + + s32 g; + s32 s0; + s32 i; + + g = D_801151D4; + + if (*(s16 *)(a0 + 0xFC) == 0) { + s0 = func_8012C658(0x33, 3, a0); + if (s0 != 0) { + *(u16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(u16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) - 8; + *(u16 *)(s0 + 0x1A) = *(u16 *)(s0 + 0x1A) - 5; + } + s0 = func_8012C658(0x33, 3, a0); + if (s0 != 0) { + *(u16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(u16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) - 8; + *(u16 *)(s0 + 0x1A) = *(u16 *)(s0 + 0x1A) + 5; + } + s0 = func_8012C658(0x32, 2, a0); + if (s0 != 0) { + *(u16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(u16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) + 8; + } + func_8002AC00(0x22); + + s0 = *(s32 *)(a0 + 0xCC); + *(s16 *)(s0 + 0x2) = 2; + *(s16 *)(s0 + 0xFC) = 1; + s0 = *(s32 *)(a0 + 0xD0); + *(s16 *)(s0 + 0x2) = 2; + *(s16 *)(s0 + 0xFC) = 1; + + for (i = 0; i < 8; i++) { + s0 = func_8012C588(0x281, a0); + if (s0 != 0) { + *(s32 *)(s0 + 0x1C) = 2; + *(u16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x30; + *(s16 *)(s0 + 0x12) = (rand() & 0x1F) - 0x10; + *(s16 *)(s0 + 0x16) = -((rand() & 0xF) + 0x10); + *(s16 *)(s0 + 0x1A) = (rand() & 0x1F) - 0x10; + } + } + + L.rv[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48); + L.rv[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C); + L.rv[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50); + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); } + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); } + RotTransPers((s32)L.rv, (s32)L.sxy, &L.z, &L.flag); + if (L.flag >= 0 && (u32)((L.sxy[0] + 0xEF) & 0xFFFF) < 0x1DF + && (u32)((L.sxy[1] + 0xB3) & 0xFFFF) < 0x167) { + s32 x = (s16)L.sxy[0]; + s32 ax; + + ax = x; + if (x < 0) { + ax = -x; + } + ax = ((0xF0 - ax) * 0x7F) / 0xF0; + __asm__("" : "=r"(ax) : "0"(ax)); + x = (x + 0xF0) / 0x1E; + if (x == 0x10) { + x = 0xF; + } + x = x << 8; + { + s32 flg = 0x3000; + func_8002D4C8(0x961, ((ax | flg) | x) & 0xFFFF); + } + } + func_8002A04C(a0); + ((void (*)(void *))func_8012C218)((void *)a0); + } else { + s0 = (s32)func_8012913C(0x23); + if (s0 != 0) { + *(s16 *)(s0 + 0x6) = *(u16 *)(a0 + 0x6) + (rand() & 0x7F) - 0x40; + *(s16 *)(s0 + 0xA) = *(u16 *)(a0 + 0xA) + (rand() & 0x7F) - 0xE0; + { + s32 r = rand(); + s32 t = *(u16 *)(a0 + 0xE); + *(s16 *)(s0 + 0x34) = 0x1800; + *(s32 *)(s0 + 0x18) = 0; + *(s32 *)(s0 + 0x14) = 0; + *(s32 *)(s0 + 0x10) = 0; + *(s16 *)(s0 + 0xE) = t + (r & 0x7F) - 0x40; + } + L.nv[0] = *(s32 *)(g + 0x5C) - *(u16 *)(s0 + 0x6); + L.nv[1] = *(s32 *)(g + 0x60) - *(u16 *)(s0 + 0xA); + L.nv[2] = *(s32 *)(g + 0x64) - *(u16 *)(s0 + 0xE); + VectorNormalSS(L.nv, L.nv); + *(s16 *)(s0 + 0x6) = *(u16 *)(s0 + 0x6) + ((s16)L.nv[0] >> 6); + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) + ((s16)L.nv[1] >> 6); + *(s16 *)(s0 + 0xE) = *(u16 *)(s0 + 0xE) + ((s16)L.nv[2] >> 6); + *(s16 *)(s0 + 0x34) = 0x3000; + func_8002D4C8(0xAF8, 0); + } + *(u16 *)(a0 + 0xFC) = *(u16 *)(a0 + 0xFC) - 1; + } +} + INCLUDE_ASM("asm/ov_SC06_024/nonmatchings/ov_SC06_024_jr_8017BEBC", func_8018B240); @@ -5457,7 +5920,114 @@ big: INCLUDE_ASM("asm/ov_SC06_024/nonmatchings/ov_SC06_024_jr_8017BEBC", func_8018B564); -INCLUDE_ASM("asm/ov_SC06_024/nonmatchings/ov_SC06_024_jr_8017BEBC", func_8018B7F0); +extern void func_8002D4C8(s32 a0, s32 a1); +extern s32 func_8004787C(s32 a0); +extern s32 func_80047948(s32 a0); +extern void func_8004914C(); +extern void func_800491AC(); +extern u8 *func_8012913C(s32 a0); +extern void func_8012A828(s32 a0, void * a1); +#define RTP_SND(sndid) \ + L.v[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48); \ + L.v[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C); \ + L.v[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50); \ + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); } \ + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); } \ + RotTransPers((s32)L.v, (s32)L.sxy, &L.z, &L.flag); \ + if (L.flag >= 0 && (u32)((L.sxy[0] + 0xEF) & 0xFFFF) < 0x1DF \ + && (u32)((L.sxy[1] + 0xB3) & 0xFFFF) < 0x167) { \ + s32 x = (s16)L.sxy[0]; \ + s32 ax; \ + ax = x; \ + if (x < 0) { \ + ax = -x; \ + } \ + ax = ((0xF0 - ax) * 0x7F) / 0xF0; \ + __asm__("" : "=r"(ax) : "0"(ax)); \ + x = (x + 0xF0) / 0x1E; \ + if (x == 0x10) { \ + x = 0xF; \ + } \ + x = x << 8; \ + { \ + s32 flg = 0x3000; \ + func_8002D4C8(sndid, ((ax | flg) | x) & 0xFFFF); \ + } \ + } + +void func_8018B7F0(s32 a0) { + + extern u8 D_800AF648; + extern s32 D_801D4A60[]; + extern u8 D_801DBF20[]; + extern u8 D_801DBFA8[]; + extern u8 D_801DC030[]; + struct { + s16 pad0[4]; /* sp+0x10 — dead, but sizes the frame (idiom 6) */ + s16 v[3]; /* sp+0x18 */ + s16 pad1; /* sp+0x1E */ + u16 sxy[2]; /* sp+0x20 */ + s32 z; /* sp+0x24 */ + s32 flag; /* sp+0x28 */ + } L; + s32 t; + s32 ang; + s32 idx; + s32 m; + s32 c; + s32 p; + + if (*(s16 *)(a0 + 0x98) == 0) { + s32 spr = (s32)func_8012913C(0x7F); + if (spr != 0) { + m = *(s16 *)(*(s32 *)(a0 + 0x20) + 0x12) + + (func_8004787C(*(s16 *)(a0 + 0x104)) >> 3); + *(s16 *)(spr + 0x6) = *(u16 *)(a0 + 0x6) - (func_8004787C(m) * 0x6C) / 0x1000; + *(s16 *)(spr + 0xA) = *(u16 *)(a0 + 0xA) - 0x34; + *(s16 *)(spr + 0xE) = *(u16 *)(a0 + 0xE) - (func_80047948(m) * 0x6C) / 0x1000; + *(s32 *)(spr + 0x14) = 0x40000; + *(s32 *)(spr + 0x10) = -(func_8004787C(m) * 0xC0); + *(s32 *)(spr + 0x18) = -(func_80047948(m) * 0xC0); + } + t = *(u16 *)(a0 + 0x104) + 0x100; + *(s16 *)(a0 + 0x104) = t; + ang = (s16)t; + idx = ang / 0x100; + m = (s16)(idx % 0x10); + if (ang == 0x100) { + RTP_SND(0x95F) + } else if (m == 0) { + RTP_SND(0x960) + } + *(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) = D_801D4A60[m]; + c = *(u16 *)(a0 + 0x100) - 1; + *(s16 *)(a0 + 0x100) = c; + if ((s16)c == 0) { + p = *(s32 *)(a0 + 0xCC); + *(s16 *)(a0 + 0x98) = 1; + if (p != 0) { + *(s16 *)(p + 0x98) = 1; + } + p = *(s32 *)(a0 + 0xD0); + if (p != 0) { + *(s16 *)(p + 0x98) = 1; + } + } + } else if ((*(u16 *)(a0 + 0x72) & 0x4000) != 0) { + *(s16 *)(a0 + 0x2) = 7; + *(s16 *)(a0 + 0x100) = 0x3C; + func_8012A828(a0, D_801DBF20); + p = *(s32 *)(a0 + 0xCC); + if (p != 0) { + func_8012A828(p, D_801DBFA8); + } + p = *(s32 *)(a0 + 0xD0); + if (p != 0) { + func_8012A828(p, D_801DC030); + } + } +} + INCLUDE_ASM("asm/ov_SC06_024/nonmatchings/ov_SC06_024_jr_8017BEBC", func_8018BCB4); @@ -5547,7 +6117,149 @@ void func_8018C38C(int param_1) } -INCLUDE_ASM("asm/ov_SC06_024/nonmatchings/ov_SC06_024_jr_8017BEBC", func_8018C584); + + + +extern s32 func_8012C658(s32 arg0, s32 arg1, s32 arg2); +extern s32 func_8012C588(s32 a0, s32 a1); +extern void func_8012C218(s32); +extern u8 *func_8012913C(s32 a0); +extern s32 func_80047948(s32 a0); +extern s32 func_8004787C(s32 a0); +extern void func_8004914C(void *a0); +extern void func_800491AC(void *a0); +extern s32 VectorNormalSS(void *a0, void *a1); +extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3); +extern void func_8002D4C8(s32 a0, s32 a1); +extern s32 rand(void); + +void func_8018C584(s32 a0) { + + extern s32 D_801151D4; + + extern void func_8002AC00(s32 arg0); + extern void func_8002A04C(s32 arg0); + extern u8 D_800AF648; + + u16 v10[4]; /* sp+0x10 */ + s16 v18[4]; /* sp+0x18 */ + s32 sxy; /* sp+0x20 */ + s32 z; /* sp+0x24 */ + s32 flag; /* sp+0x28 */ + s32 base; + s32 iv; + s32 i; + s32 t; + s32 r; + + base = D_801151D4; + + if (*(s16 *)(a0 + 0xFC) >= 0x1F) { + iv = func_8012C658(0x33, 3, a0); + if (iv != 0) { + *(u16 *)(iv + 0x0A) = *(u16 *)(iv + 0x0A) - 0x20; + *(u16 *)(iv + 0x12) = *(u16 *)(iv + 0x12) - 8; + *(u16 *)(iv + 0x1A) = *(u16 *)(iv + 0x1A) - 5; + } + iv = func_8012C658(0x33, 3, a0); + if (iv != 0) { + *(u16 *)(iv + 0x0A) = *(u16 *)(iv + 0x0A) - 0x20; + *(u16 *)(iv + 0x12) = *(u16 *)(iv + 0x12) - 8; + *(u16 *)(iv + 0x1A) = *(u16 *)(iv + 0x1A) + 5; + } + iv = func_8012C658(0x32, 2, a0); + if (iv != 0) { + *(u16 *)(iv + 0x0A) = *(u16 *)(iv + 0x0A) - 0x20; + *(u16 *)(iv + 0x12) = *(u16 *)(iv + 0x12) + 8; + } + + func_8002AC00(0x22); + + iv = *(s32 *)(a0 + 0x64); + *(s16 *)(iv + 2) = 2; + iv = *(s32 *)(*(s32 *)(a0 + 0x64) + 0xD0); + *(s16 *)(iv + 2) = 4; + *(s32 *)(*(s32 *)(a0 + 0x64) + 0xCC) = 0; + + i = 0; + do { + iv = func_8012C588(0x281, a0); + if (iv != 0) { + *(s32 *)(iv + 0x1C) = 2; + *(s16 *)(iv + 0x12) = (rand() & 0x1F) - 0x10; + *(s16 *)(iv + 0x16) = -((rand() & 0x0F) + 0x10); + *(s16 *)(iv + 0x1A) = (rand() & 0x1F) - 0x10; + } + i++; + } while (i < 8); + + v18[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48); + v18[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C); + v18[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50); + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); } + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); } + RotTransPers((s32)v18, (s32)&sxy, &z, &flag); + if (flag >= 0 && (u32)((*(u16 *)&sxy + 0xEF) & 0xFFFF) < 0x1DF + && (u32)((*((u16 *)&sxy + 1) + 0xB3) & 0xFFFF) < 0x167) { + s32 sx; + s32 av; + + sx = (s16)*(u16 *)&sxy; + av = sx; + if (sx < 0) { + av = -sx; + } + /* one local for |x| AND the volume: gcc-2.7.2 keeps the single pseudo + in $v1 in place (subu $v1,$v0,$v1); a separate `vol` local steals $a1 + and the whole OR chain drifts (cookbook §136 L1). */ + av = ((0xF0 - av) * 0x7F) / 0xF0; + sx = (sx + 0xF0) / 0x1E; + if (sx == 0x10) { + sx = 0xF; + } + sx = sx << 8; + func_8002D4C8(0x961, (av | (0x3000 | sx)) & 0xFFFF); + } + + func_8002A04C(a0); + ((void (*)(void *))func_8012C218)((void *)a0); + return; + } + + iv = (s32)func_8012913C(0x23); + if (iv != 0) { + r = rand(); + *(u16 *)(iv + 0x06) = *(u16 *)(a0 + 0x06) + (r & 0x7F) - 0x40; + r = rand(); + *(u16 *)(iv + 0x0A) = *(u16 *)(a0 + 0x0A) + (r & 0x7F) - 0x80; + r = rand(); + *(u16 *)(iv + 0x0E) = *(u16 *)(a0 + 0x0E) + (r & 0x7F) - 0x40; + + t = func_80047948((s32) * (s16 *)(*(s32 *)(a0 + 0x20) + 0x12)); + *(s32 *)(iv + 0x04) = *(s32 *)(iv + 0x04) + (t << 10); + + t = func_8004787C((s32) * (s16 *)(*(s32 *)(a0 + 0x20) + 0x12)); + *(u16 *)(iv + 0x34) = 0x1800; + *(s32 *)(iv + 0x18) = 0; + *(s32 *)(iv + 0x14) = 0; + *(s32 *)(iv + 0x10) = 0; + *(s32 *)(iv + 0x0C) = *(s32 *)(iv + 0x0C) - (t << 10); + + v10[0] = *(s32 *)(base + 0x5C) - *(u16 *)(iv + 0x06); + v10[1] = *(s32 *)(base + 0x60) - *(u16 *)(iv + 0x0A); + v10[2] = *(s32 *)(base + 0x64) - *(u16 *)(iv + 0x0E); + VectorNormalSS(v10, v10); + + *(u16 *)(iv + 0x06) = *(u16 *)(iv + 0x06) + ((s16)v10[0] >> 6); + *(u16 *)(iv + 0x0A) = *(u16 *)(iv + 0x0A) + ((s16)v10[1] >> 6); + *(u16 *)(iv + 0x0E) = *(u16 *)(iv + 0x0E) + ((s16)v10[2] >> 6); + *(u16 *)(iv + 0x34) = 0x3000; + func_8002D4C8(0xAF8, 0); + } + + *(u16 *)(a0 + 0xFC) = *(u16 *)(a0 + 0xFC) + 1; +} + // @class: struct @@ -5611,7 +6323,143 @@ void func_8018C9CC(short *param_1) } -INCLUDE_ASM("asm/ov_SC06_024/nonmatchings/ov_SC06_024_jr_8017BEBC", func_8018CBDC); + + +extern s32 func_8012C658(s32 arg0, s32 arg1, s32 arg2); +extern s32 func_8012C588(s32 a0, s32 a1); +extern void func_8012C218(s32); +extern u8 *func_8012913C(); +extern s32 rand(void); +extern s32 func_80047948(s32 a0); +extern s32 func_8004787C(s32 a0); +extern s32 VectorNormalSS(void *a0, void *a1); +extern void func_8004914C(void *a0); +extern void func_800491AC(void *a0); +extern void func_8002D4C8(s32 a0, s32 a1); +extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3); +extern void func_8002A04C(s32 a0); + + +void func_8018CBDC(s32 a0) { + + extern s32 D_801151D4; + + extern u8 D_800AF648; + extern void func_8002AC00(s32 arg0); + + struct { + u16 nv[4]; /* sp+0x10 */ + s16 v[4]; /* sp+0x18 */ + u16 sxy[2]; /* sp+0x20 */ + s32 z; /* sp+0x24 */ + s32 flag; /* sp+0x28 */ + } L; + s32 p; + s32 s0; + s32 i; + + p = D_801151D4; + + if (*(s16 *)(a0 + 0xFC) >= 0x1F) { + s0 = func_8012C658(0x33, 3, a0); + if (s0 != 0) { + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(s16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) - 8; + *(s16 *)(s0 + 0x1A) = *(u16 *)(s0 + 0x1A) - 5; + } + s0 = func_8012C658(0x33, 3, a0); + if (s0 != 0) { + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(s16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) - 8; + *(s16 *)(s0 + 0x1A) = *(u16 *)(s0 + 0x1A) + 5; + } + s0 = func_8012C658(0x32, 2, a0); + if (s0 != 0) { + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(s16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) + 8; + } + func_8002AC00(0x22); + s0 = *(s32 *)(a0 + 0x64); + *(s16 *)(s0 + 0x2) = 4; + s0 = *(s32 *)(*(s32 *)(a0 + 0x64) + 0xCC); + *(s16 *)(s0 + 0x2) = 4; + + for (i = 0; i < 8; i++) { + s0 = func_8012C588(0x281, a0); + if (s0 != 0) { + *(s32 *)(s0 + 0x1C) = 2; + *(s16 *)(s0 + 0x12) = (rand() & 0x1F) - 0x10; + *(s16 *)(s0 + 0x16) = -((rand() & 0xF) + 0x10); + *(s16 *)(s0 + 0x1A) = (rand() & 0x1F) - 0x10; + } + } + + L.v[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48); + L.v[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C); + L.v[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50); + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); } + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); } + RotTransPers((s32)L.v, (s32)L.sxy, &L.z, &L.flag); + if (L.flag >= 0 && (u32)((L.sxy[0] + 0xEF) & 0xFFFF) < 0x1DF + && (u32)((L.sxy[1] + 0xB3) & 0xFFFF) < 0x167) { + s32 x = (s16)L.sxy[0]; + s32 ax; + ax = x; + if (x < 0) { + ax = -x; + } + ax = ((0xF0 - ax) * 0x7F) / 0xF0; + __asm__("" : "=r"(ax) : "0"(ax)); + x = (x + 0xF0) / 0x1E; + if (x == 0x10) { + x = 0xF; + } + x = x << 8; + { + s32 flg = 0x3000; + func_8002D4C8(0x961, ((ax | flg) | x) & 0xFFFF); + } + } + + *(s32 *)(*(s32 *)(a0 + 0x64) + 0xD0) = 0; + func_8002A04C(a0); + ((void (*)(void *))func_8012C218)((void *)a0); + return; + } + + s0 = (s32)func_8012913C(0x23); + if (s0 != 0) { + *(s16 *)(s0 + 0x6) = *(u16 *)(a0 + 0x6) + (rand() & 0x7F) - 0x40; + *(s16 *)(s0 + 0xA) = *(u16 *)(a0 + 0xA) + (rand() & 0x7F) - 0x80; + *(s16 *)(s0 + 0xE) = *(u16 *)(a0 + 0xE) + (rand() & 0x7F) - 0x40; + + *(s32 *)(s0 + 0x4) = + *(s32 *)(s0 + 0x4) - + func_80047948(*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12)) * 0x400; + { + s32 t = func_8004787C(*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12)) * 0x400; + *(s16 *)(s0 + 0x34) = 0x1800; + *(s32 *)(s0 + 0x18) = 0; + *(s32 *)(s0 + 0x14) = 0; + *(s32 *)(s0 + 0x10) = 0; + *(s32 *)(s0 + 0xC) = *(s32 *)(s0 + 0xC) + t; + } + + L.nv[0] = *(s32 *)(p + 0x5C) - *(u16 *)(s0 + 0x6); + L.nv[1] = *(s32 *)(p + 0x60) - *(u16 *)(s0 + 0xA); + L.nv[2] = *(s32 *)(p + 0x64) - *(u16 *)(s0 + 0xE); + VectorNormalSS(L.nv, L.nv); + + *(s16 *)(s0 + 0x6) = *(u16 *)(s0 + 0x6) + ((s16)L.nv[0] >> 6); + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) + ((s16)L.nv[1] >> 6); + *(s16 *)(s0 + 0xE) = *(u16 *)(s0 + 0xE) + ((s16)L.nv[2] >> 6); + *(s16 *)(s0 + 0x34) = 0x3000; + func_8002D4C8(0xAF8, 0); + } + + *(s16 *)(a0 + 0xFC) = *(u16 *)(a0 + 0xFC) + 1; +} + extern s32 rand(void); diff --git a/src/ov_SC06_032/ov_SC06_032_jr_8017C24C.c b/src/ov_SC06_032/ov_SC06_032_jr_8017C24C.c index 9cee4db78..898cfc3d6 100644 --- a/src/ov_SC06_032/ov_SC06_032_jr_8017C24C.c +++ b/src/ov_SC06_032/ov_SC06_032_jr_8017C24C.c @@ -318,7 +318,6 @@ extern s32 func_80012B04(s32 a0, s32 a1, s32 a2); extern void func_801490F8(s32 a0, s32 a1); extern s32 func_801491C4(s32 a0); extern s32 func_80149184(s32 a0); -extern s32 D_801151D4; extern void func_80149204(s32 *a0); extern void func_80149210(s32 a0, s32 a1); extern s32 func_80149284(s32 *a0, s32 a1); @@ -4549,7 +4548,167 @@ INCLUDE_ASM("asm/ov_SC06_032/nonmatchings/ov_SC06_032_jr_8017C24C", func_801832F INCLUDE_ASM("asm/ov_SC06_032/nonmatchings/ov_SC06_032_jr_8017C24C", func_80183430); -INCLUDE_ASM("asm/ov_SC06_032/nonmatchings/ov_SC06_032_jr_8017C24C", func_80183454); + +// @class: struct +// @stuck: none — MATCH (276 ins, relocation-masked). Verified BOTH standalone (match_one) and +// spliced into src/ov_SC06_018/ov_SC06_018_jr_8017C24C.c (whole-TU cc1 -O2 clean, +// masked structured_diff 0/276). +// Keys: (1) the first func_8012C218 call gets a NOP delay slot because reload_cse_regs deletes the +// redundant `move a0,s1` -- $a0 still holds the incoming param on the fall-through path +// (no CODE_LABEL between the prologue and the jal). The second call site is behind a +// label, so the move survives. Source is the natural `func_8012C218((void *)param_1)` at +// BOTH sites -- do NOT write a zero-arg call (it also breaks in-TU: the composite type +// from the earlier file-scope `extern void func_8012C218(void *a0);` rejects 0 args). +// (2) case 0's guard is an `||` with an early return -- that is what puts `beqz -> fail` then +// `beq -> ok` (an `&&` would emit `bne -> fail`). +// (3) `register s32 sVar2 __asm__("$2")` holds the p+0x34 reload in cases 1/2 so the two arms +// cross-jump into the shared .L80188928 tail. +// (4) `__asm__ __volatile__("")` after the func_8012C658 arm forces the `lw v1,0x1C(s1)` +// reload before the cross-jumped `li v0,9` (§21 zero-byte re-tie). +// (5) `-((iVar3 << 0x10) / 0x22)` reproduces the 0x78787879/sra-4 magic-divide by 34 + negu. +// (6) `*p * 0xc` then `>>4` with the manual `if (x<0) x+=0xf` is the /16 rounding form. + +extern void func_8012C218(void *a0); +extern void func_80184124(s32, void*, void*, s32); +extern s32 func_80013328(s32 a0, s32 a1); +extern void func_8012B14C(s32 a0, s32 a1); +extern void func_8012CC64(s32 a0, s32 a1); /* fleet-canonical: void; $v0 used -> cast at use */ +extern s32 func_8012C658(s32, s32, s32); +extern s32 func_80143B6C(s32 a0, s32 a1); /* fleet-canonical */ +extern s32 func_8012BEE8(s32 a0); +extern void func_80016714(void*, s32); +extern void func_80183DA4(s32 a0, s32 a1); + + +void func_80183454(s32 param_1) { + + extern u8 D_801BE708; + extern u8 D_801A697C; + extern u8 D_801A6984; + extern u8 D_801A6974; + extern u8 D_80126B5C; + u16 uVar1; + register s32 sVar2 __asm__("$2"); + s32 iVar3; + s32 iVar4; + s32 iVar5; + u32 uVar4; + s32 psVar5; + u16 buf[8]; + s32 vec[3]; + + if (0xf < *(s16 *)(param_1 + 0xA)) { + func_8012C218((void *)param_1); + return; + } + uVar1 = *(u16 *)(param_1 + 0x34); + switch (uVar1) { + case 0: + psVar5 = *(s32 *)(param_1 + 0x64); + if ((*(u16 *)psVar5 == 0) || + (*(s32 *)(psVar5 + 0x90) != (s32)&D_801BE708)) { + func_8012C218((void *)param_1); + return; + } + if (*(s32 *)(psVar5 + 0x94) < 0x11) { + ((void (*)(void *, void *, void *, s32))func_80184124)((void *)psVar5, (void *)&D_801A697C, buf, 5); + *(s16 *)(param_1 + 6) = buf[0]; + *(s16 *)(param_1 + 0xA) = buf[1]; + *(s16 *)(param_1 + 0xE) = buf[2]; + return; + } + ((void (*)(void *, void *, void *, s32))func_80184124)((void *)psVar5, (void *)&D_801A6984, buf, 4); + ((void (*)(void *, void *, void *, s32))func_80184124)((void *)psVar5, (void *)&D_801A6984, &buf[4], 5); + *(s16 *)(param_1 + 6) = + (s16)((*(s16 *)&buf[0] + *(s16 *)&buf[4]) >> 1); + *(s16 *)(param_1 + 0xA) = + (s16)((*(s16 *)&buf[1] + *(s16 *)&buf[5]) >> 1); + *(s16 *)(param_1 + 0xE) = + (s16)((*(s16 *)&buf[2] + *(s16 *)&buf[6]) >> 1); + if (*(s32 *)(psVar5 + 0x94) != 0x19) { + return; + } + *(u16 *)(param_1 + 0x34) = *(u16 *)(param_1 + 0x34) + 1; + vec[0] = 0; + vec[1] = 0xfff40000; + iVar3 = func_80013328((s32)&D_80126B5C, param_1 + 4); + vec[2] = -((iVar3 << 0x10) / 0x22); + func_8012B14C(param_1, (s32)vec); + *(s32 *)(param_1 + 0x48) = 0xc000; + return; + case 1: + *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x10) + 0x80; + iVar3 = ((s32 (*)(s32, s32))func_8012CC64)(param_1, (s32)&D_801A6974); + if (iVar3 == 0) { + return; + } + sVar2 = *(u16 *)(param_1 + 0x34); + *(s32 *)(param_1 + 0x1c) = 0; + *(u16 *)(param_1 + 0x34) = sVar2 + 1; + return; + case 2: + *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x10) + 0x40; + uVar4 = ((s32 (*)(s32, s32))func_8012CC64)(param_1, (s32)&D_801A6974); + if ((uVar4 & 0x2000) == 0) { + return; + } + iVar4 = *(s32 *)(param_1 + 0x1c) + 1; + *(s32 *)(param_1 + 0x1c) = iVar4; + if (iVar4 >= 4) { + sVar2 = *(u16 *)(param_1 + 0x34); + *(s32 *)(param_1 + 0x1c) = 0x1e; + *(u16 *)(param_1 + 0x34) = sVar2 + 1; + return; + } + iVar3 = *(s32 *)(param_1 + 0x10) * 0xc; + if (iVar3 < 0) { + iVar3 = iVar3 + 0xf; + } + *(s32 *)(param_1 + 0x10) = iVar3 >> 4; + iVar5 = *(s32 *)(param_1 + 0x18) * 0xc; + if (iVar5 < 0) { + iVar5 = iVar5 + 0xf; + } + *(s32 *)(param_1 + 0x18) = iVar5 >> 4; + *(s32 *)(param_1 + 0x14) = -(0x80000 / *(s32 *)(param_1 + 0x1c)); + func_80143B6C(param_1, 1); + return; + case 3: + uVar4 = *(u32 *)(param_1 + 0x1c); + if ((uVar4 - 0xe < 0xb) && ((uVar4 & 1) == 0)) { + ((void (*)(s32, s32, s32))func_8012C658)(0x2a8, (s32)*(s16 *)(param_1 + 0x104), param_1); + *(u16 *)(param_1 + 0x104) = *(u16 *)(param_1 + 0x104) + 1; + __asm__ __volatile__(""); + uVar4 = *(u32 *)(param_1 + 0x1c); + } + if (uVar4 == 9) { + *(u32 *)(*(s32 *)(param_1 + 0xcc) + 4) = + *(u32 *)(*(s32 *)(param_1 + 0xcc) + 4) & 0x7fffffff; + *(s16 *)(*(s32 *)(param_1 + 0xcc) + 8) = *(u16 *)(param_1 + 6); + *(s16 *)(*(s32 *)(param_1 + 0xcc) + 0xa) = + *(u16 *)(param_1 + 0xa) - 0x24; + *(s16 *)(*(s32 *)(param_1 + 0xcc) + 0xc) = *(u16 *)(param_1 + 0xe); + } + if (*(s32 *)(param_1 + 0x1c) - 4U < 6) { + *(s16 *)(*(s32 *)(param_1 + 0xcc) + 0x18) = + *(u16 *)(*(s32 *)(param_1 + 0xcc) + 0x18) + 0x200; + *(s16 *)(*(s32 *)(param_1 + 0xcc) + 0x1a) = + *(u16 *)(*(s32 *)(param_1 + 0xcc) + 0x1a) + 0x200; + } + iVar3 = func_8012BEE8(param_1); + if (iVar3 != 1) { + return; + } + ((void (*)(s32, s32))func_80016714)(*(s32 *)(param_1 + 0xcc), 0x38); + *(s16 *)(param_1 + 2) = 9; + func_80183DA4(param_1, 0); + return; + } + return; +} + extern void func_80049CAC(s32, s32); @@ -4607,7 +4766,136 @@ void func_80184258(void *a0) { } -INCLUDE_ASM("asm/ov_SC06_032/nonmatchings/ov_SC06_032_jr_8017C24C", func_80184294); + + +extern s32 rand(void); +extern void func_8012C1B8(void); +extern void func_8012CAE4(s32 a0); +extern void func_8001C214(s32 a0, s32 a1); +extern void func_8012B2CC(s32 a0); +extern void func_8012B178(s32 a0, s32 a1); + +void func_80184294(s32 param_1) { + + extern u8 D_801A6A18[]; + s32 unused[2]; /* dead 8-byte local — frame padding (cookbook idiom 6) */ + s32 obj; + s16 raw; + s32 r; + s32 sgn; + s32 v; + u8 *tbl; + s16 *p; + s32 q; + s32 w; + + obj = ((s32 (*)(void))func_8012C1B8)(); + if (obj == 0) { + func_8012CAE4(param_1); + return; + } + *(s32 *)(param_1 + 0x20) = obj; + func_8001C214(obj, 0); + + raw = rand(); + r = raw; + *(u16 *)(obj + 0x2C) = *(u16 *)(obj + 0x2C) | 0x10; + v = r % 384 + 0x400; + *(s16 *)(obj + 0x1C) = v; + *(s16 *)(obj + 0x1A) = v; + *(s16 *)(obj + 0x18) = v; + sgn = -1; + if (raw & 1) { + sgn = 1; + } + *(s16 *)(obj + 0x10) = sgn * (r % 128) - 0x300; + *(s16 *)(obj + 0x12) = r % 4096; + *(s32 *)(param_1 + 0x48) = 0xC000; + *(u16 *)(param_1 + 0xA) = *(u16 *)(param_1 + 0xA) - 0x19; + func_8012B2CC(param_1); + func_8012B178(param_1, -0xC0000 - ((r % 8) << 16)); + *(s32 *)(param_1 + 0x1C) = 0x3C; + *(s16 *)(param_1 + 0xFE) = rand() & 0xF0; + *(s16 *)(param_1 + 0x100) = rand() & 0x1F0; + *(s16 *)(param_1 + 0x102) = rand() & 0x30; + tbl = &D_801A6A18[(*(u16 *)(param_1 + 0x70) & 0xF) * 4]; + + p = (s16 *)(param_1 + 0xDC); + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q - 0x18; + } else { + w = q - 0x18; + } + p[0] = w; + p[1] = 0; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q - 0x18; + } else { + w = q - 0x18; + } + p[2] = w; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q + 0x18; + } else { + w = q + 0x18; + } + p[4] = w; + p[5] = 0; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q - 0x18; + } else { + w = q - 0x18; + } + p[6] = w; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q - 0x18; + } else { + w = q - 0x18; + } + p[8] = w; + p[9] = 0; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q + 0x18; + } else { + w = q + 0x18; + } + p[10] = w; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q + 0x18; + } else { + w = q + 0x18; + } + p[12] = w; + p[13] = 0; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q + 0x18; + } else { + w = q + 0x18; + } + p[14] = w; + + *((u8 *)p + 0x20) = tbl[0]; + *((u8 *)p + 0x21) = tbl[1]; + *((u8 *)p + 0x22) = tbl[2]; + *(u16 *)(param_1 + 2) = *(u16 *)(param_1 + 2) + 1; +} + extern s32 func_8012CBF4(s32 a0); @@ -5008,7 +5296,56 @@ INCLUDE_ASM("asm/ov_SC06_032/nonmatchings/ov_SC06_032_jr_8017C24C", func_80185F4 INCLUDE_ASM("asm/ov_SC06_032/nonmatchings/ov_SC06_032_jr_8017C24C", func_8018603C); -INCLUDE_ASM("asm/ov_SC06_032/nonmatchings/ov_SC06_032_jr_8017C24C", func_80186160); + +// @class: struct +// @stuck: none — §136c SIBLING-FIRST. Near-twin (byte-identical template) = func_80186160 in +// src/ov_SC06_032/ov_SC06_032_jr_8017C24C.c (same jr_8017C24C base overlay TU, still +// nonmatching); the two differ only in the per-overlay D_ table symbol (D_801BEF4C here vs +// D_801BEF4C there). RotMatrixY/func_8012AD44 canonical decl forms lifted from +// src/ov_SC06_008/ov_SC06_008_jr_8016AB6C.c ("extern void RotMatrixY(s32 a0, void *a1);") and +// src/shared/engine_core.h; the func_800484EC cast-through-fnptr call form is lifted from the +// banked func_80188B00 in this same TU. The D_800AE620 8-word struct copy (3+3+2 lw/sw +// grouping) is the established whole-struct `local = D_800AE620;` idiom already used for this +// exact symbol elsewhere (Blk20, renamed here to avoid clashing with the real typedef pulled +// in via engine_core.h when this splices into the TU). The address of the local matrix is +// cached in a POINTER LOCAL (T6) because it's used again across the intervening RotMatrixY +// call -- that's what forces it into a callee-saved reg ($s1) instead of being recomputed as +// `addiu $a0,$sp,0x10` at each use site. + +typedef struct { s32 w[8]; } Blk20_8018AF88_80186160; + + +extern s32 func_8012B8A4(s16 *a0); +extern void RotMatrixY(s32 a0, void *a1); +extern void func_800484EC(s32, s32, s32); +extern void func_8012AD44(s32 *a0, s16 a1); +extern s32 rand(void); + +void func_80186160(s32 param_1) +{ + + extern Blk20_8018AF88_80186160 D_800AE620; + extern s32 D_801BEF4C; + Blk20_8018AF88_80186160 local_30; + Blk20_8018AF88_80186160 *m; + s32 iVar1; + s32 iVar2; + + local_30 = D_800AE620; + iVar1 = func_8012B8A4((s16 *)param_1); + m = &local_30; + RotMatrixY(iVar1, m); + ((void (*)(void *, void *, s32))func_800484EC)(m, &D_801BEF4C, param_1 + 0x10); + *(s32 *)(param_1 + 0x14) = 0xFFDC0000; + *(s32 *)(param_1 + 0xE0) = 0xFFDC0000; + *(s32 *)(param_1 + 0x1C) = 0x10; + iVar2 = rand(); + *(u16 *)(param_1 + 0x106) = iVar2 & 0x70; + iVar2 = rand(); + *(u16 *)(param_1 + 0x108) = iVar2 & 0x70; + func_8012AD44((s32 *)param_1, 1); +} + INCLUDE_ASM("asm/ov_SC06_032/nonmatchings/ov_SC06_032_jr_8017C24C", func_80186238); @@ -5051,7 +5388,25 @@ INCLUDE_ASM("asm/ov_SC06_032/nonmatchings/ov_SC06_032_jr_8017C24C", func_80186CF INCLUDE_ASM("asm/ov_SC06_032/nonmatchings/ov_SC06_032_jr_8017C24C", func_80186D90); -INCLUDE_ASM("asm/ov_SC06_032/nonmatchings/ov_SC06_032_jr_8017C24C", func_80186E18); +extern s32 func_80132EF4(s32 a0, s32 a1); + +void func_80186E18(s32 param_1) +{ + s32 result; + u16 val_e4; + + result = func_80132EF4(param_1, 0x23); + if (result != 0) { + *(u16 *)(result + 0x6) = *(u16 *)(param_1 + 0xE0); + *(u16 *)(result + 0xA) = *(u16 *)(param_1 + 0xE2); + val_e4 = *(u16 *)(param_1 + 0xE4); + *(u16 *)(result + 0x34) = 0x3001; + *(u16 *)(result + 0xE) = val_e4; + *(u16 *)(*(s32 *)(result + 0x20) + 0x2C) = 0xC008; + *(u32 *)(*(s32 *)(result + 0x20) + 0x4) |= 0x50000000; + } +} + INCLUDE_ASM("asm/ov_SC06_032/nonmatchings/ov_SC06_032_jr_8017C24C", func_80186E9C); @@ -5130,7 +5485,42 @@ INCLUDE_ASM("asm/ov_SC06_032/nonmatchings/ov_SC06_032_jr_8017C24C", func_80187C9 INCLUDE_ASM("asm/ov_SC06_032/nonmatchings/ov_SC06_032_jr_8017C24C", func_80187CEC); -INCLUDE_ASM("asm/ov_SC06_032/nonmatchings/ov_SC06_032_jr_8017C24C", func_80187D60); + +extern void func_80187E60(void *a0); +extern void func_80187EDC(void *a0); +extern void func_8012931C(s32); +extern void func_801292C8(s32); + +void func_80187D60(void *a0) { + if (*(u16 *)((s32)a0 + 0x2) == 0) { + func_80187E60(a0); + return; + } + + if (*(s32 *)((s32)a0 + 0x1C) != 0) { + *(s32 *)((s32)a0 + 0x1C) -= 1; + ((void (*)(struct vec *))func_8012931C)((struct vec *)a0); + + if (*(s16 *)((s32)a0 + 0x32) == 0) { + u16 t = *(u16 *)((s32)a0 + 0xA) + 0x1000; + if (t >= 0x1001) { + ((void (*)(u8 *))func_801292C8)((u8 *)a0); + return; + } + } + } else { + ((void (*)(u8 *))func_801292C8)((u8 *)a0); + return; + } + + *(s32 *)((s32)a0 + 0x14) += *(s32 *)((s32)a0 + 0x34); + *(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0x14) += *(u16 *)((s32)a0 + 0x30); + *(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0x8) = *(u16 *)((s32)a0 + 0x6); + *(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0xA) = *(u16 *)((s32)a0 + 0xA); + *(u16 *)(*(s32 *)((s32)a0 + 0x20) + 0xC) = *(u16 *)((s32)a0 + 0xE); + func_80187EDC((void *)*(s32 *)((s32)a0 + 0x20)); +} + INCLUDE_ASM("asm/ov_SC06_032/nonmatchings/ov_SC06_032_jr_8017C24C", func_80187E60); @@ -5231,7 +5621,163 @@ docopy: } -INCLUDE_ASM("asm/ov_SC06_032/nonmatchings/ov_SC06_032_jr_8017C24C", func_801887F4); + + +/* func_801887F4 — ov_SC06_008 / ov_SC06_008_jr_8017C294 + * + * Two-arm actor tick keyed on the s16 countdown at actor+0xFC: + * arm A (counter == 0, the FALL-THROUGH / longer block): three func_8012C658 + * spawns with offset pokes, a sound cue, two child-actor state pokes, an + * 8-iteration 0x281 particle burst, then the RTP positional-sound block + * (the byte-proven RTP_SND shape from ov_SC03_099_jr_8017BEBC.c:5406). + * arm B (counter != 0): a func_8012913C(0x23) spawn scattered around the + * actor, VectorNormalSS toward D_801151D4->{0x5C,0x60,0x64}, sound 0xAF8. + * + * Declarations copied VERBATIM from the TU (one-pass grep, D2): + * D_801151D4 src/ov_SC06_008/ov_SC06_008_jr_8017C294.c:323 + * rand :956 + * VectorNormalSS :1849 + * func_8012C658 :2523 + * func_8012C588 :3767 + * func_8012C218 :3782 + * func_8002D4C8 :59 + * func_8004914C :2645 + * func_800491AC :2646 + * func_8012913C :4356 (non-prototype form, BELOW the splice point) + * func_8002AC00 :5447 (block-scope extern only) + * RotTransPers / D_800AF648 / func_8002A04C are not in this TU -> fleet-dominant forms. + */ + +extern s32 rand(void); +extern s32 VectorNormalSS(void *a0, void *a1); +extern s32 func_8012C658(s32 arg0, s32 arg1, s32 arg2); +extern s32 func_8012C588(s32 a0, s32 a1); +extern void func_8012C218(void *a0); +extern void func_8002D4C8(s32 a0, s32 a1); +extern void func_8004914C(void *a0); +extern void func_800491AC(void *a0); +extern void func_8002A04C(s32 a0); +extern void func_8002AC00(s32 a0); +extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3); +extern u8 *func_8012913C(); + +void func_801887F4(s32 a0) +{ + + extern s32 D_801151D4; + extern u8 D_800AF648; + + /* L5: slot offsets are exact only through ONE struct — plain array locals + get 8-byte-rounded slots and pushed z/flag to 0x28/0x2C (measured). */ + struct { + u16 nv[4]; /* sp+0x10 */ + s16 rv[4]; /* sp+0x18 */ + u16 sxy[2]; /* sp+0x20 */ + s32 z; /* sp+0x24 */ + s32 flag; /* sp+0x28 */ + } L; + + s32 g; + s32 s0; + s32 i; + + g = D_801151D4; + + if (*(s16 *)(a0 + 0xFC) == 0) { + s0 = func_8012C658(0x33, 3, a0); + if (s0 != 0) { + *(u16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(u16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) - 8; + *(u16 *)(s0 + 0x1A) = *(u16 *)(s0 + 0x1A) - 5; + } + s0 = func_8012C658(0x33, 3, a0); + if (s0 != 0) { + *(u16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(u16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) - 8; + *(u16 *)(s0 + 0x1A) = *(u16 *)(s0 + 0x1A) + 5; + } + s0 = func_8012C658(0x32, 2, a0); + if (s0 != 0) { + *(u16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(u16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) + 8; + } + func_8002AC00(0x22); + + s0 = *(s32 *)(a0 + 0xCC); + *(s16 *)(s0 + 0x2) = 2; + *(s16 *)(s0 + 0xFC) = 1; + s0 = *(s32 *)(a0 + 0xD0); + *(s16 *)(s0 + 0x2) = 2; + *(s16 *)(s0 + 0xFC) = 1; + + for (i = 0; i < 8; i++) { + s0 = func_8012C588(0x281, a0); + if (s0 != 0) { + *(s32 *)(s0 + 0x1C) = 2; + *(u16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x30; + *(s16 *)(s0 + 0x12) = (rand() & 0x1F) - 0x10; + *(s16 *)(s0 + 0x16) = -((rand() & 0xF) + 0x10); + *(s16 *)(s0 + 0x1A) = (rand() & 0x1F) - 0x10; + } + } + + L.rv[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48); + L.rv[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C); + L.rv[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50); + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); } + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); } + RotTransPers((s32)L.rv, (s32)L.sxy, &L.z, &L.flag); + if (L.flag >= 0 && (u32)((L.sxy[0] + 0xEF) & 0xFFFF) < 0x1DF + && (u32)((L.sxy[1] + 0xB3) & 0xFFFF) < 0x167) { + s32 x = (s16)L.sxy[0]; + s32 ax; + + ax = x; + if (x < 0) { + ax = -x; + } + ax = ((0xF0 - ax) * 0x7F) / 0xF0; + __asm__("" : "=r"(ax) : "0"(ax)); + x = (x + 0xF0) / 0x1E; + if (x == 0x10) { + x = 0xF; + } + x = x << 8; + { + s32 flg = 0x3000; + func_8002D4C8(0x961, ((ax | flg) | x) & 0xFFFF); + } + } + func_8002A04C(a0); + func_8012C218((void *)a0); + } else { + s0 = (s32)func_8012913C(0x23); + if (s0 != 0) { + *(s16 *)(s0 + 0x6) = *(u16 *)(a0 + 0x6) + (rand() & 0x7F) - 0x40; + *(s16 *)(s0 + 0xA) = *(u16 *)(a0 + 0xA) + (rand() & 0x7F) - 0xE0; + { + s32 r = rand(); + s32 t = *(u16 *)(a0 + 0xE); + *(s16 *)(s0 + 0x34) = 0x1800; + *(s32 *)(s0 + 0x18) = 0; + *(s32 *)(s0 + 0x14) = 0; + *(s32 *)(s0 + 0x10) = 0; + *(s16 *)(s0 + 0xE) = t + (r & 0x7F) - 0x40; + } + L.nv[0] = *(s32 *)(g + 0x5C) - *(u16 *)(s0 + 0x6); + L.nv[1] = *(s32 *)(g + 0x60) - *(u16 *)(s0 + 0xA); + L.nv[2] = *(s32 *)(g + 0x64) - *(u16 *)(s0 + 0xE); + VectorNormalSS(L.nv, L.nv); + *(s16 *)(s0 + 0x6) = *(u16 *)(s0 + 0x6) + ((s16)L.nv[0] >> 6); + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) + ((s16)L.nv[1] >> 6); + *(s16 *)(s0 + 0xE) = *(u16 *)(s0 + 0xE) + ((s16)L.nv[2] >> 6); + *(s16 *)(s0 + 0x34) = 0x3000; + func_8002D4C8(0xAF8, 0); + } + *(u16 *)(a0 + 0xFC) = *(u16 *)(a0 + 0xFC) - 1; + } +} + INCLUDE_ASM("asm/ov_SC06_032/nonmatchings/ov_SC06_032_jr_8017C24C", func_80188BF8); @@ -5310,7 +5856,114 @@ big: INCLUDE_ASM("asm/ov_SC06_032/nonmatchings/ov_SC06_032_jr_8017C24C", func_80188F1C); -INCLUDE_ASM("asm/ov_SC06_032/nonmatchings/ov_SC06_032_jr_8017C24C", func_801891A8); +extern void func_8002D4C8(s32 a0, s32 a1); +extern s32 func_8004787C(s32 a0); +extern s32 func_80047948(s32 a0); +extern void func_8004914C(); +extern void func_800491AC(); +extern u8 *func_8012913C(s32 a0); +extern void func_8012A828(s32 a0, void * a1); +#define RTP_SND(sndid) \ + L.v[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48); \ + L.v[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C); \ + L.v[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50); \ + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); } \ + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); } \ + RotTransPers((s32)L.v, (s32)L.sxy, &L.z, &L.flag); \ + if (L.flag >= 0 && (u32)((L.sxy[0] + 0xEF) & 0xFFFF) < 0x1DF \ + && (u32)((L.sxy[1] + 0xB3) & 0xFFFF) < 0x167) { \ + s32 x = (s16)L.sxy[0]; \ + s32 ax; \ + ax = x; \ + if (x < 0) { \ + ax = -x; \ + } \ + ax = ((0xF0 - ax) * 0x7F) / 0xF0; \ + __asm__("" : "=r"(ax) : "0"(ax)); \ + x = (x + 0xF0) / 0x1E; \ + if (x == 0x10) { \ + x = 0xF; \ + } \ + x = x << 8; \ + { \ + s32 flg = 0x3000; \ + func_8002D4C8(sndid, ((ax | flg) | x) & 0xFFFF); \ + } \ + } + +void func_801891A8(s32 a0) { + + extern u8 D_800AF648; + extern s32 D_801C2B50[]; + extern u8 D_801CA010[]; + extern u8 D_801CA098[]; + extern u8 D_801CA120[]; + struct { + s16 pad0[4]; /* sp+0x10 — dead, but sizes the frame (idiom 6) */ + s16 v[3]; /* sp+0x18 */ + s16 pad1; /* sp+0x1E */ + u16 sxy[2]; /* sp+0x20 */ + s32 z; /* sp+0x24 */ + s32 flag; /* sp+0x28 */ + } L; + s32 t; + s32 ang; + s32 idx; + s32 m; + s32 c; + s32 p; + + if (*(s16 *)(a0 + 0x98) == 0) { + s32 spr = (s32)func_8012913C(0x7F); + if (spr != 0) { + m = *(s16 *)(*(s32 *)(a0 + 0x20) + 0x12) + + (func_8004787C(*(s16 *)(a0 + 0x104)) >> 3); + *(s16 *)(spr + 0x6) = *(u16 *)(a0 + 0x6) - (func_8004787C(m) * 0x6C) / 0x1000; + *(s16 *)(spr + 0xA) = *(u16 *)(a0 + 0xA) - 0x34; + *(s16 *)(spr + 0xE) = *(u16 *)(a0 + 0xE) - (func_80047948(m) * 0x6C) / 0x1000; + *(s32 *)(spr + 0x14) = 0x40000; + *(s32 *)(spr + 0x10) = -(func_8004787C(m) * 0xC0); + *(s32 *)(spr + 0x18) = -(func_80047948(m) * 0xC0); + } + t = *(u16 *)(a0 + 0x104) + 0x100; + *(s16 *)(a0 + 0x104) = t; + ang = (s16)t; + idx = ang / 0x100; + m = (s16)(idx % 0x10); + if (ang == 0x100) { + RTP_SND(0x95F) + } else if (m == 0) { + RTP_SND(0x960) + } + *(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) = D_801C2B50[m]; + c = *(u16 *)(a0 + 0x100) - 1; + *(s16 *)(a0 + 0x100) = c; + if ((s16)c == 0) { + p = *(s32 *)(a0 + 0xCC); + *(s16 *)(a0 + 0x98) = 1; + if (p != 0) { + *(s16 *)(p + 0x98) = 1; + } + p = *(s32 *)(a0 + 0xD0); + if (p != 0) { + *(s16 *)(p + 0x98) = 1; + } + } + } else if ((*(u16 *)(a0 + 0x72) & 0x4000) != 0) { + *(s16 *)(a0 + 0x2) = 7; + *(s16 *)(a0 + 0x100) = 0x3C; + func_8012A828(a0, D_801CA010); + p = *(s32 *)(a0 + 0xCC); + if (p != 0) { + func_8012A828(p, D_801CA098); + } + p = *(s32 *)(a0 + 0xD0); + if (p != 0) { + func_8012A828(p, D_801CA120); + } + } +} + INCLUDE_ASM("asm/ov_SC06_032/nonmatchings/ov_SC06_032_jr_8017C24C", func_8018966C); @@ -5400,7 +6053,149 @@ void func_80189D44(int param_1) } -INCLUDE_ASM("asm/ov_SC06_032/nonmatchings/ov_SC06_032_jr_8017C24C", func_80189F3C); + + + +extern s32 func_8012C658(s32 arg0, s32 arg1, s32 arg2); +extern s32 func_8012C588(s32 a0, s32 a1); +extern void func_8012C218(void *a0); +extern u8 *func_8012913C(s32 a0); +extern s32 func_80047948(s32 a0); +extern s32 func_8004787C(s32 a0); +extern void func_8004914C(void *a0); +extern void func_800491AC(void *a0); +extern s32 VectorNormalSS(void *a0, void *a1); +extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3); +extern void func_8002D4C8(s32 a0, s32 a1); +extern s32 rand(void); + +void func_80189F3C(s32 a0) { + + extern s32 D_801151D4; + + extern void func_8002AC00(s32 arg0); + extern void func_8002A04C(s32 arg0); + extern u8 D_800AF648; + + u16 v10[4]; /* sp+0x10 */ + s16 v18[4]; /* sp+0x18 */ + s32 sxy; /* sp+0x20 */ + s32 z; /* sp+0x24 */ + s32 flag; /* sp+0x28 */ + s32 base; + s32 iv; + s32 i; + s32 t; + s32 r; + + base = D_801151D4; + + if (*(s16 *)(a0 + 0xFC) >= 0x1F) { + iv = func_8012C658(0x33, 3, a0); + if (iv != 0) { + *(u16 *)(iv + 0x0A) = *(u16 *)(iv + 0x0A) - 0x20; + *(u16 *)(iv + 0x12) = *(u16 *)(iv + 0x12) - 8; + *(u16 *)(iv + 0x1A) = *(u16 *)(iv + 0x1A) - 5; + } + iv = func_8012C658(0x33, 3, a0); + if (iv != 0) { + *(u16 *)(iv + 0x0A) = *(u16 *)(iv + 0x0A) - 0x20; + *(u16 *)(iv + 0x12) = *(u16 *)(iv + 0x12) - 8; + *(u16 *)(iv + 0x1A) = *(u16 *)(iv + 0x1A) + 5; + } + iv = func_8012C658(0x32, 2, a0); + if (iv != 0) { + *(u16 *)(iv + 0x0A) = *(u16 *)(iv + 0x0A) - 0x20; + *(u16 *)(iv + 0x12) = *(u16 *)(iv + 0x12) + 8; + } + + func_8002AC00(0x22); + + iv = *(s32 *)(a0 + 0x64); + *(s16 *)(iv + 2) = 2; + iv = *(s32 *)(*(s32 *)(a0 + 0x64) + 0xD0); + *(s16 *)(iv + 2) = 4; + *(s32 *)(*(s32 *)(a0 + 0x64) + 0xCC) = 0; + + i = 0; + do { + iv = func_8012C588(0x281, a0); + if (iv != 0) { + *(s32 *)(iv + 0x1C) = 2; + *(s16 *)(iv + 0x12) = (rand() & 0x1F) - 0x10; + *(s16 *)(iv + 0x16) = -((rand() & 0x0F) + 0x10); + *(s16 *)(iv + 0x1A) = (rand() & 0x1F) - 0x10; + } + i++; + } while (i < 8); + + v18[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48); + v18[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C); + v18[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50); + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); } + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); } + RotTransPers((s32)v18, (s32)&sxy, &z, &flag); + if (flag >= 0 && (u32)((*(u16 *)&sxy + 0xEF) & 0xFFFF) < 0x1DF + && (u32)((*((u16 *)&sxy + 1) + 0xB3) & 0xFFFF) < 0x167) { + s32 sx; + s32 av; + + sx = (s16)*(u16 *)&sxy; + av = sx; + if (sx < 0) { + av = -sx; + } + /* one local for |x| AND the volume: gcc-2.7.2 keeps the single pseudo + in $v1 in place (subu $v1,$v0,$v1); a separate `vol` local steals $a1 + and the whole OR chain drifts (cookbook §136 L1). */ + av = ((0xF0 - av) * 0x7F) / 0xF0; + sx = (sx + 0xF0) / 0x1E; + if (sx == 0x10) { + sx = 0xF; + } + sx = sx << 8; + func_8002D4C8(0x961, (av | (0x3000 | sx)) & 0xFFFF); + } + + func_8002A04C(a0); + func_8012C218((void *)a0); + return; + } + + iv = (s32)func_8012913C(0x23); + if (iv != 0) { + r = rand(); + *(u16 *)(iv + 0x06) = *(u16 *)(a0 + 0x06) + (r & 0x7F) - 0x40; + r = rand(); + *(u16 *)(iv + 0x0A) = *(u16 *)(a0 + 0x0A) + (r & 0x7F) - 0x80; + r = rand(); + *(u16 *)(iv + 0x0E) = *(u16 *)(a0 + 0x0E) + (r & 0x7F) - 0x40; + + t = func_80047948((s32) * (s16 *)(*(s32 *)(a0 + 0x20) + 0x12)); + *(s32 *)(iv + 0x04) = *(s32 *)(iv + 0x04) + (t << 10); + + t = func_8004787C((s32) * (s16 *)(*(s32 *)(a0 + 0x20) + 0x12)); + *(u16 *)(iv + 0x34) = 0x1800; + *(s32 *)(iv + 0x18) = 0; + *(s32 *)(iv + 0x14) = 0; + *(s32 *)(iv + 0x10) = 0; + *(s32 *)(iv + 0x0C) = *(s32 *)(iv + 0x0C) - (t << 10); + + v10[0] = *(s32 *)(base + 0x5C) - *(u16 *)(iv + 0x06); + v10[1] = *(s32 *)(base + 0x60) - *(u16 *)(iv + 0x0A); + v10[2] = *(s32 *)(base + 0x64) - *(u16 *)(iv + 0x0E); + VectorNormalSS(v10, v10); + + *(u16 *)(iv + 0x06) = *(u16 *)(iv + 0x06) + ((s16)v10[0] >> 6); + *(u16 *)(iv + 0x0A) = *(u16 *)(iv + 0x0A) + ((s16)v10[1] >> 6); + *(u16 *)(iv + 0x0E) = *(u16 *)(iv + 0x0E) + ((s16)v10[2] >> 6); + *(u16 *)(iv + 0x34) = 0x3000; + func_8002D4C8(0xAF8, 0); + } + + *(u16 *)(a0 + 0xFC) = *(u16 *)(a0 + 0xFC) + 1; +} + // @class: struct @@ -5464,7 +6259,143 @@ void func_8018A384(short *param_1) } -INCLUDE_ASM("asm/ov_SC06_032/nonmatchings/ov_SC06_032_jr_8017C24C", func_8018A594); + + +extern s32 func_8012C658(s32 arg0, s32 arg1, s32 arg2); +extern s32 func_8012C588(s32 a0, s32 a1); +extern void func_8012C218(void *a0); +extern u8 *func_8012913C(); +extern s32 rand(void); +extern s32 func_80047948(s32 a0); +extern s32 func_8004787C(s32 a0); +extern s32 VectorNormalSS(void *a0, void *a1); +extern void func_8004914C(void *a0); +extern void func_800491AC(void *a0); +extern void func_8002D4C8(s32 a0, s32 a1); +extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3); +extern void func_8002A04C(s32 a0); + + +void func_8018A594(s32 a0) { + + extern s32 D_801151D4; + + extern u8 D_800AF648; + extern void func_8002AC00(s32 arg0); + + struct { + u16 nv[4]; /* sp+0x10 */ + s16 v[4]; /* sp+0x18 */ + u16 sxy[2]; /* sp+0x20 */ + s32 z; /* sp+0x24 */ + s32 flag; /* sp+0x28 */ + } L; + s32 p; + s32 s0; + s32 i; + + p = D_801151D4; + + if (*(s16 *)(a0 + 0xFC) >= 0x1F) { + s0 = func_8012C658(0x33, 3, a0); + if (s0 != 0) { + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(s16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) - 8; + *(s16 *)(s0 + 0x1A) = *(u16 *)(s0 + 0x1A) - 5; + } + s0 = func_8012C658(0x33, 3, a0); + if (s0 != 0) { + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(s16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) - 8; + *(s16 *)(s0 + 0x1A) = *(u16 *)(s0 + 0x1A) + 5; + } + s0 = func_8012C658(0x32, 2, a0); + if (s0 != 0) { + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(s16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) + 8; + } + func_8002AC00(0x22); + s0 = *(s32 *)(a0 + 0x64); + *(s16 *)(s0 + 0x2) = 4; + s0 = *(s32 *)(*(s32 *)(a0 + 0x64) + 0xCC); + *(s16 *)(s0 + 0x2) = 4; + + for (i = 0; i < 8; i++) { + s0 = func_8012C588(0x281, a0); + if (s0 != 0) { + *(s32 *)(s0 + 0x1C) = 2; + *(s16 *)(s0 + 0x12) = (rand() & 0x1F) - 0x10; + *(s16 *)(s0 + 0x16) = -((rand() & 0xF) + 0x10); + *(s16 *)(s0 + 0x1A) = (rand() & 0x1F) - 0x10; + } + } + + L.v[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48); + L.v[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C); + L.v[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50); + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); } + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); } + RotTransPers((s32)L.v, (s32)L.sxy, &L.z, &L.flag); + if (L.flag >= 0 && (u32)((L.sxy[0] + 0xEF) & 0xFFFF) < 0x1DF + && (u32)((L.sxy[1] + 0xB3) & 0xFFFF) < 0x167) { + s32 x = (s16)L.sxy[0]; + s32 ax; + ax = x; + if (x < 0) { + ax = -x; + } + ax = ((0xF0 - ax) * 0x7F) / 0xF0; + __asm__("" : "=r"(ax) : "0"(ax)); + x = (x + 0xF0) / 0x1E; + if (x == 0x10) { + x = 0xF; + } + x = x << 8; + { + s32 flg = 0x3000; + func_8002D4C8(0x961, ((ax | flg) | x) & 0xFFFF); + } + } + + *(s32 *)(*(s32 *)(a0 + 0x64) + 0xD0) = 0; + func_8002A04C(a0); + func_8012C218((void *)a0); + return; + } + + s0 = (s32)func_8012913C(0x23); + if (s0 != 0) { + *(s16 *)(s0 + 0x6) = *(u16 *)(a0 + 0x6) + (rand() & 0x7F) - 0x40; + *(s16 *)(s0 + 0xA) = *(u16 *)(a0 + 0xA) + (rand() & 0x7F) - 0x80; + *(s16 *)(s0 + 0xE) = *(u16 *)(a0 + 0xE) + (rand() & 0x7F) - 0x40; + + *(s32 *)(s0 + 0x4) = + *(s32 *)(s0 + 0x4) - + func_80047948(*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12)) * 0x400; + { + s32 t = func_8004787C(*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12)) * 0x400; + *(s16 *)(s0 + 0x34) = 0x1800; + *(s32 *)(s0 + 0x18) = 0; + *(s32 *)(s0 + 0x14) = 0; + *(s32 *)(s0 + 0x10) = 0; + *(s32 *)(s0 + 0xC) = *(s32 *)(s0 + 0xC) + t; + } + + L.nv[0] = *(s32 *)(p + 0x5C) - *(u16 *)(s0 + 0x6); + L.nv[1] = *(s32 *)(p + 0x60) - *(u16 *)(s0 + 0xA); + L.nv[2] = *(s32 *)(p + 0x64) - *(u16 *)(s0 + 0xE); + VectorNormalSS(L.nv, L.nv); + + *(s16 *)(s0 + 0x6) = *(u16 *)(s0 + 0x6) + ((s16)L.nv[0] >> 6); + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) + ((s16)L.nv[1] >> 6); + *(s16 *)(s0 + 0xE) = *(u16 *)(s0 + 0xE) + ((s16)L.nv[2] >> 6); + *(s16 *)(s0 + 0x34) = 0x3000; + func_8002D4C8(0xAF8, 0); + } + + *(s16 *)(a0 + 0xFC) = *(u16 *)(a0 + 0xFC) + 1; +} + extern s32 rand(void); diff --git a/src/ov_SC06_033/ov_SC06_033_jr_8017C24C.c b/src/ov_SC06_033/ov_SC06_033_jr_8017C24C.c index 31bea302f..b604fd595 100644 --- a/src/ov_SC06_033/ov_SC06_033_jr_8017C24C.c +++ b/src/ov_SC06_033/ov_SC06_033_jr_8017C24C.c @@ -318,7 +318,6 @@ extern s32 func_80012B04(s32 a0, s32 a1, s32 a2); extern void func_801490F8(s32 a0, s32 a1); extern s32 func_801491C4(s32 a0); extern s32 func_80149184(s32 a0); -extern s32 D_801151D4; extern void func_80149204(s32 *a0); extern void func_80149210(s32 a0, s32 a1); extern s32 func_80149284(s32 *a0, s32 a1); @@ -4132,7 +4131,163 @@ docopy: } -INCLUDE_ASM("asm/ov_SC06_033/nonmatchings/ov_SC06_033_jr_8017C24C", func_8017F53C); + + +/* func_8017F53C — ov_SC06_008 / ov_SC06_008_jr_8017C294 + * + * Two-arm actor tick keyed on the s16 countdown at actor+0xFC: + * arm A (counter == 0, the FALL-THROUGH / longer block): three func_8012C658 + * spawns with offset pokes, a sound cue, two child-actor state pokes, an + * 8-iteration 0x281 particle burst, then the RTP positional-sound block + * (the byte-proven RTP_SND shape from ov_SC03_099_jr_8017BEBC.c:5406). + * arm B (counter != 0): a func_8012913C(0x23) spawn scattered around the + * actor, VectorNormalSS toward D_801151D4->{0x5C,0x60,0x64}, sound 0xAF8. + * + * Declarations copied VERBATIM from the TU (one-pass grep, D2): + * D_801151D4 src/ov_SC06_008/ov_SC06_008_jr_8017C294.c:323 + * rand :956 + * VectorNormalSS :1849 + * func_8012C658 :2523 + * func_8012C588 :3767 + * func_8012C218 :3782 + * func_8002D4C8 :59 + * func_8004914C :2645 + * func_800491AC :2646 + * func_8012913C :4356 (non-prototype form, BELOW the splice point) + * func_8002AC00 :5447 (block-scope extern only) + * RotTransPers / D_800AF648 / func_8002A04C are not in this TU -> fleet-dominant forms. + */ + +extern s32 rand(void); +extern s32 VectorNormalSS(void *a0, void *a1); +extern s32 func_8012C658(s32 arg0, s32 arg1, s32 arg2); +extern s32 func_8012C588(s32 a0, s32 a1); +extern void func_8012C218(void *a0); +extern void func_8002D4C8(s32 a0, s32 a1); +extern void func_8004914C(void *a0); +extern void func_800491AC(void *a0); +extern void func_8002A04C(s32 a0); +extern void func_8002AC00(s32 a0); +extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3); +extern u8 *func_8012913C(); + +void func_8017F53C(s32 a0) +{ + + extern s32 D_801151D4; + extern u8 D_800AF648; + + /* L5: slot offsets are exact only through ONE struct — plain array locals + get 8-byte-rounded slots and pushed z/flag to 0x28/0x2C (measured). */ + struct { + u16 nv[4]; /* sp+0x10 */ + s16 rv[4]; /* sp+0x18 */ + u16 sxy[2]; /* sp+0x20 */ + s32 z; /* sp+0x24 */ + s32 flag; /* sp+0x28 */ + } L; + + s32 g; + s32 s0; + s32 i; + + g = D_801151D4; + + if (*(s16 *)(a0 + 0xFC) == 0) { + s0 = func_8012C658(0x33, 3, a0); + if (s0 != 0) { + *(u16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(u16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) - 8; + *(u16 *)(s0 + 0x1A) = *(u16 *)(s0 + 0x1A) - 5; + } + s0 = func_8012C658(0x33, 3, a0); + if (s0 != 0) { + *(u16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(u16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) - 8; + *(u16 *)(s0 + 0x1A) = *(u16 *)(s0 + 0x1A) + 5; + } + s0 = func_8012C658(0x32, 2, a0); + if (s0 != 0) { + *(u16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(u16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) + 8; + } + func_8002AC00(0x22); + + s0 = *(s32 *)(a0 + 0xCC); + *(s16 *)(s0 + 0x2) = 2; + *(s16 *)(s0 + 0xFC) = 1; + s0 = *(s32 *)(a0 + 0xD0); + *(s16 *)(s0 + 0x2) = 2; + *(s16 *)(s0 + 0xFC) = 1; + + for (i = 0; i < 8; i++) { + s0 = func_8012C588(0x281, a0); + if (s0 != 0) { + *(s32 *)(s0 + 0x1C) = 2; + *(u16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x30; + *(s16 *)(s0 + 0x12) = (rand() & 0x1F) - 0x10; + *(s16 *)(s0 + 0x16) = -((rand() & 0xF) + 0x10); + *(s16 *)(s0 + 0x1A) = (rand() & 0x1F) - 0x10; + } + } + + L.rv[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48); + L.rv[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C); + L.rv[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50); + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); } + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); } + RotTransPers((s32)L.rv, (s32)L.sxy, &L.z, &L.flag); + if (L.flag >= 0 && (u32)((L.sxy[0] + 0xEF) & 0xFFFF) < 0x1DF + && (u32)((L.sxy[1] + 0xB3) & 0xFFFF) < 0x167) { + s32 x = (s16)L.sxy[0]; + s32 ax; + + ax = x; + if (x < 0) { + ax = -x; + } + ax = ((0xF0 - ax) * 0x7F) / 0xF0; + __asm__("" : "=r"(ax) : "0"(ax)); + x = (x + 0xF0) / 0x1E; + if (x == 0x10) { + x = 0xF; + } + x = x << 8; + { + s32 flg = 0x3000; + func_8002D4C8(0x961, ((ax | flg) | x) & 0xFFFF); + } + } + func_8002A04C(a0); + func_8012C218((void *)a0); + } else { + s0 = (s32)func_8012913C(0x23); + if (s0 != 0) { + *(s16 *)(s0 + 0x6) = *(u16 *)(a0 + 0x6) + (rand() & 0x7F) - 0x40; + *(s16 *)(s0 + 0xA) = *(u16 *)(a0 + 0xA) + (rand() & 0x7F) - 0xE0; + { + s32 r = rand(); + s32 t = *(u16 *)(a0 + 0xE); + *(s16 *)(s0 + 0x34) = 0x1800; + *(s32 *)(s0 + 0x18) = 0; + *(s32 *)(s0 + 0x14) = 0; + *(s32 *)(s0 + 0x10) = 0; + *(s16 *)(s0 + 0xE) = t + (r & 0x7F) - 0x40; + } + L.nv[0] = *(s32 *)(g + 0x5C) - *(u16 *)(s0 + 0x6); + L.nv[1] = *(s32 *)(g + 0x60) - *(u16 *)(s0 + 0xA); + L.nv[2] = *(s32 *)(g + 0x64) - *(u16 *)(s0 + 0xE); + VectorNormalSS(L.nv, L.nv); + *(s16 *)(s0 + 0x6) = *(u16 *)(s0 + 0x6) + ((s16)L.nv[0] >> 6); + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) + ((s16)L.nv[1] >> 6); + *(s16 *)(s0 + 0xE) = *(u16 *)(s0 + 0xE) + ((s16)L.nv[2] >> 6); + *(s16 *)(s0 + 0x34) = 0x3000; + func_8002D4C8(0xAF8, 0); + } + *(u16 *)(a0 + 0xFC) = *(u16 *)(a0 + 0xFC) - 1; + } +} + INCLUDE_ASM("asm/ov_SC06_033/nonmatchings/ov_SC06_033_jr_8017C24C", func_8017F940); @@ -4211,7 +4366,114 @@ big: INCLUDE_ASM("asm/ov_SC06_033/nonmatchings/ov_SC06_033_jr_8017C24C", func_8017FC64); -INCLUDE_ASM("asm/ov_SC06_033/nonmatchings/ov_SC06_033_jr_8017C24C", func_8017FEF0); +extern void func_8002D4C8(s32 a0, s32 a1); +extern s32 func_8004787C(s32 a0); +extern s32 func_80047948(s32 a0); +extern void func_8004914C(); +extern void func_800491AC(); +extern u8 *func_8012913C(s32 a0); +extern void func_8012A828(s32 a0, void * a1); +#define RTP_SND(sndid) \ + L.v[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48); \ + L.v[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C); \ + L.v[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50); \ + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); } \ + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); } \ + RotTransPers((s32)L.v, (s32)L.sxy, &L.z, &L.flag); \ + if (L.flag >= 0 && (u32)((L.sxy[0] + 0xEF) & 0xFFFF) < 0x1DF \ + && (u32)((L.sxy[1] + 0xB3) & 0xFFFF) < 0x167) { \ + s32 x = (s16)L.sxy[0]; \ + s32 ax; \ + ax = x; \ + if (x < 0) { \ + ax = -x; \ + } \ + ax = ((0xF0 - ax) * 0x7F) / 0xF0; \ + __asm__("" : "=r"(ax) : "0"(ax)); \ + x = (x + 0xF0) / 0x1E; \ + if (x == 0x10) { \ + x = 0xF; \ + } \ + x = x << 8; \ + { \ + s32 flg = 0x3000; \ + func_8002D4C8(sndid, ((ax | flg) | x) & 0xFFFF); \ + } \ + } + +void func_8017FEF0(s32 a0) { + + extern u8 D_800AF648; + extern s32 D_801A7B58[]; + extern u8 D_801AF018[]; + extern u8 D_801AF0A0[]; + extern u8 D_801AF128[]; + struct { + s16 pad0[4]; /* sp+0x10 — dead, but sizes the frame (idiom 6) */ + s16 v[3]; /* sp+0x18 */ + s16 pad1; /* sp+0x1E */ + u16 sxy[2]; /* sp+0x20 */ + s32 z; /* sp+0x24 */ + s32 flag; /* sp+0x28 */ + } L; + s32 t; + s32 ang; + s32 idx; + s32 m; + s32 c; + s32 p; + + if (*(s16 *)(a0 + 0x98) == 0) { + s32 spr = (s32)func_8012913C(0x7F); + if (spr != 0) { + m = *(s16 *)(*(s32 *)(a0 + 0x20) + 0x12) + + (func_8004787C(*(s16 *)(a0 + 0x104)) >> 3); + *(s16 *)(spr + 0x6) = *(u16 *)(a0 + 0x6) - (func_8004787C(m) * 0x6C) / 0x1000; + *(s16 *)(spr + 0xA) = *(u16 *)(a0 + 0xA) - 0x34; + *(s16 *)(spr + 0xE) = *(u16 *)(a0 + 0xE) - (func_80047948(m) * 0x6C) / 0x1000; + *(s32 *)(spr + 0x14) = 0x40000; + *(s32 *)(spr + 0x10) = -(func_8004787C(m) * 0xC0); + *(s32 *)(spr + 0x18) = -(func_80047948(m) * 0xC0); + } + t = *(u16 *)(a0 + 0x104) + 0x100; + *(s16 *)(a0 + 0x104) = t; + ang = (s16)t; + idx = ang / 0x100; + m = (s16)(idx % 0x10); + if (ang == 0x100) { + RTP_SND(0x95F) + } else if (m == 0) { + RTP_SND(0x960) + } + *(s32 *)(*(s32 *)(a0 + 0x20) + 0x20) = D_801A7B58[m]; + c = *(u16 *)(a0 + 0x100) - 1; + *(s16 *)(a0 + 0x100) = c; + if ((s16)c == 0) { + p = *(s32 *)(a0 + 0xCC); + *(s16 *)(a0 + 0x98) = 1; + if (p != 0) { + *(s16 *)(p + 0x98) = 1; + } + p = *(s32 *)(a0 + 0xD0); + if (p != 0) { + *(s16 *)(p + 0x98) = 1; + } + } + } else if ((*(u16 *)(a0 + 0x72) & 0x4000) != 0) { + *(s16 *)(a0 + 0x2) = 7; + *(s16 *)(a0 + 0x100) = 0x3C; + func_8012A828(a0, D_801AF018); + p = *(s32 *)(a0 + 0xCC); + if (p != 0) { + func_8012A828(p, D_801AF0A0); + } + p = *(s32 *)(a0 + 0xD0); + if (p != 0) { + func_8012A828(p, D_801AF128); + } + } +} + INCLUDE_ASM("asm/ov_SC06_033/nonmatchings/ov_SC06_033_jr_8017C24C", func_801803B4); @@ -4302,7 +4564,149 @@ void func_80180A8C(int param_1) } -INCLUDE_ASM("asm/ov_SC06_033/nonmatchings/ov_SC06_033_jr_8017C24C", func_80180C84); + + + +extern s32 func_8012C658(s32 arg0, s32 arg1, s32 arg2); +extern s32 func_8012C588(s32 a0, s32 a1); +extern void func_8012C218(void *a0); +extern u8 *func_8012913C(s32 a0); +extern s32 func_80047948(s32 a0); +extern s32 func_8004787C(s32 a0); +extern void func_8004914C(void *a0); +extern void func_800491AC(void *a0); +extern s32 VectorNormalSS(void *a0, void *a1); +extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3); +extern void func_8002D4C8(s32 a0, s32 a1); +extern s32 rand(void); + +void func_80180C84(s32 a0) { + + extern s32 D_801151D4; + + extern void func_8002AC00(s32 arg0); + extern void func_8002A04C(s32 arg0); + extern u8 D_800AF648; + + u16 v10[4]; /* sp+0x10 */ + s16 v18[4]; /* sp+0x18 */ + s32 sxy; /* sp+0x20 */ + s32 z; /* sp+0x24 */ + s32 flag; /* sp+0x28 */ + s32 base; + s32 iv; + s32 i; + s32 t; + s32 r; + + base = D_801151D4; + + if (*(s16 *)(a0 + 0xFC) >= 0x1F) { + iv = func_8012C658(0x33, 3, a0); + if (iv != 0) { + *(u16 *)(iv + 0x0A) = *(u16 *)(iv + 0x0A) - 0x20; + *(u16 *)(iv + 0x12) = *(u16 *)(iv + 0x12) - 8; + *(u16 *)(iv + 0x1A) = *(u16 *)(iv + 0x1A) - 5; + } + iv = func_8012C658(0x33, 3, a0); + if (iv != 0) { + *(u16 *)(iv + 0x0A) = *(u16 *)(iv + 0x0A) - 0x20; + *(u16 *)(iv + 0x12) = *(u16 *)(iv + 0x12) - 8; + *(u16 *)(iv + 0x1A) = *(u16 *)(iv + 0x1A) + 5; + } + iv = func_8012C658(0x32, 2, a0); + if (iv != 0) { + *(u16 *)(iv + 0x0A) = *(u16 *)(iv + 0x0A) - 0x20; + *(u16 *)(iv + 0x12) = *(u16 *)(iv + 0x12) + 8; + } + + func_8002AC00(0x22); + + iv = *(s32 *)(a0 + 0x64); + *(s16 *)(iv + 2) = 2; + iv = *(s32 *)(*(s32 *)(a0 + 0x64) + 0xD0); + *(s16 *)(iv + 2) = 4; + *(s32 *)(*(s32 *)(a0 + 0x64) + 0xCC) = 0; + + i = 0; + do { + iv = func_8012C588(0x281, a0); + if (iv != 0) { + *(s32 *)(iv + 0x1C) = 2; + *(s16 *)(iv + 0x12) = (rand() & 0x1F) - 0x10; + *(s16 *)(iv + 0x16) = -((rand() & 0x0F) + 0x10); + *(s16 *)(iv + 0x1A) = (rand() & 0x1F) - 0x10; + } + i++; + } while (i < 8); + + v18[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48); + v18[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C); + v18[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50); + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); } + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); } + RotTransPers((s32)v18, (s32)&sxy, &z, &flag); + if (flag >= 0 && (u32)((*(u16 *)&sxy + 0xEF) & 0xFFFF) < 0x1DF + && (u32)((*((u16 *)&sxy + 1) + 0xB3) & 0xFFFF) < 0x167) { + s32 sx; + s32 av; + + sx = (s16)*(u16 *)&sxy; + av = sx; + if (sx < 0) { + av = -sx; + } + /* one local for |x| AND the volume: gcc-2.7.2 keeps the single pseudo + in $v1 in place (subu $v1,$v0,$v1); a separate `vol` local steals $a1 + and the whole OR chain drifts (cookbook §136 L1). */ + av = ((0xF0 - av) * 0x7F) / 0xF0; + sx = (sx + 0xF0) / 0x1E; + if (sx == 0x10) { + sx = 0xF; + } + sx = sx << 8; + func_8002D4C8(0x961, (av | (0x3000 | sx)) & 0xFFFF); + } + + func_8002A04C(a0); + func_8012C218((void *)a0); + return; + } + + iv = (s32)func_8012913C(0x23); + if (iv != 0) { + r = rand(); + *(u16 *)(iv + 0x06) = *(u16 *)(a0 + 0x06) + (r & 0x7F) - 0x40; + r = rand(); + *(u16 *)(iv + 0x0A) = *(u16 *)(a0 + 0x0A) + (r & 0x7F) - 0x80; + r = rand(); + *(u16 *)(iv + 0x0E) = *(u16 *)(a0 + 0x0E) + (r & 0x7F) - 0x40; + + t = func_80047948((s32) * (s16 *)(*(s32 *)(a0 + 0x20) + 0x12)); + *(s32 *)(iv + 0x04) = *(s32 *)(iv + 0x04) + (t << 10); + + t = func_8004787C((s32) * (s16 *)(*(s32 *)(a0 + 0x20) + 0x12)); + *(u16 *)(iv + 0x34) = 0x1800; + *(s32 *)(iv + 0x18) = 0; + *(s32 *)(iv + 0x14) = 0; + *(s32 *)(iv + 0x10) = 0; + *(s32 *)(iv + 0x0C) = *(s32 *)(iv + 0x0C) - (t << 10); + + v10[0] = *(s32 *)(base + 0x5C) - *(u16 *)(iv + 0x06); + v10[1] = *(s32 *)(base + 0x60) - *(u16 *)(iv + 0x0A); + v10[2] = *(s32 *)(base + 0x64) - *(u16 *)(iv + 0x0E); + VectorNormalSS(v10, v10); + + *(u16 *)(iv + 0x06) = *(u16 *)(iv + 0x06) + ((s16)v10[0] >> 6); + *(u16 *)(iv + 0x0A) = *(u16 *)(iv + 0x0A) + ((s16)v10[1] >> 6); + *(u16 *)(iv + 0x0E) = *(u16 *)(iv + 0x0E) + ((s16)v10[2] >> 6); + *(u16 *)(iv + 0x34) = 0x3000; + func_8002D4C8(0xAF8, 0); + } + + *(u16 *)(a0 + 0xFC) = *(u16 *)(a0 + 0xFC) + 1; +} + // @class: struct @@ -4366,7 +4770,143 @@ void func_801810CC(short *param_1) } -INCLUDE_ASM("asm/ov_SC06_033/nonmatchings/ov_SC06_033_jr_8017C24C", func_801812DC); + + +extern s32 func_8012C658(s32 arg0, s32 arg1, s32 arg2); +extern s32 func_8012C588(s32 a0, s32 a1); +extern void func_8012C218(void *a0); +extern u8 *func_8012913C(); +extern s32 rand(void); +extern s32 func_80047948(s32 a0); +extern s32 func_8004787C(s32 a0); +extern s32 VectorNormalSS(void *a0, void *a1); +extern void func_8004914C(void *a0); +extern void func_800491AC(void *a0); +extern void func_8002D4C8(s32 a0, s32 a1); +extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3); +extern void func_8002A04C(s32 a0); + + +void func_801812DC(s32 a0) { + + extern s32 D_801151D4; + + extern u8 D_800AF648; + extern void func_8002AC00(s32 arg0); + + struct { + u16 nv[4]; /* sp+0x10 */ + s16 v[4]; /* sp+0x18 */ + u16 sxy[2]; /* sp+0x20 */ + s32 z; /* sp+0x24 */ + s32 flag; /* sp+0x28 */ + } L; + s32 p; + s32 s0; + s32 i; + + p = D_801151D4; + + if (*(s16 *)(a0 + 0xFC) >= 0x1F) { + s0 = func_8012C658(0x33, 3, a0); + if (s0 != 0) { + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(s16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) - 8; + *(s16 *)(s0 + 0x1A) = *(u16 *)(s0 + 0x1A) - 5; + } + s0 = func_8012C658(0x33, 3, a0); + if (s0 != 0) { + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(s16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) - 8; + *(s16 *)(s0 + 0x1A) = *(u16 *)(s0 + 0x1A) + 5; + } + s0 = func_8012C658(0x32, 2, a0); + if (s0 != 0) { + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) - 0x20; + *(s16 *)(s0 + 0x12) = *(u16 *)(s0 + 0x12) + 8; + } + func_8002AC00(0x22); + s0 = *(s32 *)(a0 + 0x64); + *(s16 *)(s0 + 0x2) = 4; + s0 = *(s32 *)(*(s32 *)(a0 + 0x64) + 0xCC); + *(s16 *)(s0 + 0x2) = 4; + + for (i = 0; i < 8; i++) { + s0 = func_8012C588(0x281, a0); + if (s0 != 0) { + *(s32 *)(s0 + 0x1C) = 2; + *(s16 *)(s0 + 0x12) = (rand() & 0x1F) - 0x10; + *(s16 *)(s0 + 0x16) = -((rand() & 0xF) + 0x10); + *(s16 *)(s0 + 0x1A) = (rand() & 0x1F) - 0x10; + } + } + + L.v[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48); + L.v[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C); + L.v[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50); + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); } + { register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); } + RotTransPers((s32)L.v, (s32)L.sxy, &L.z, &L.flag); + if (L.flag >= 0 && (u32)((L.sxy[0] + 0xEF) & 0xFFFF) < 0x1DF + && (u32)((L.sxy[1] + 0xB3) & 0xFFFF) < 0x167) { + s32 x = (s16)L.sxy[0]; + s32 ax; + ax = x; + if (x < 0) { + ax = -x; + } + ax = ((0xF0 - ax) * 0x7F) / 0xF0; + __asm__("" : "=r"(ax) : "0"(ax)); + x = (x + 0xF0) / 0x1E; + if (x == 0x10) { + x = 0xF; + } + x = x << 8; + { + s32 flg = 0x3000; + func_8002D4C8(0x961, ((ax | flg) | x) & 0xFFFF); + } + } + + *(s32 *)(*(s32 *)(a0 + 0x64) + 0xD0) = 0; + func_8002A04C(a0); + func_8012C218((void *)a0); + return; + } + + s0 = (s32)func_8012913C(0x23); + if (s0 != 0) { + *(s16 *)(s0 + 0x6) = *(u16 *)(a0 + 0x6) + (rand() & 0x7F) - 0x40; + *(s16 *)(s0 + 0xA) = *(u16 *)(a0 + 0xA) + (rand() & 0x7F) - 0x80; + *(s16 *)(s0 + 0xE) = *(u16 *)(a0 + 0xE) + (rand() & 0x7F) - 0x40; + + *(s32 *)(s0 + 0x4) = + *(s32 *)(s0 + 0x4) - + func_80047948(*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12)) * 0x400; + { + s32 t = func_8004787C(*(s16 *)(*(s32 *)(a0 + 0x20) + 0x12)) * 0x400; + *(s16 *)(s0 + 0x34) = 0x1800; + *(s32 *)(s0 + 0x18) = 0; + *(s32 *)(s0 + 0x14) = 0; + *(s32 *)(s0 + 0x10) = 0; + *(s32 *)(s0 + 0xC) = *(s32 *)(s0 + 0xC) + t; + } + + L.nv[0] = *(s32 *)(p + 0x5C) - *(u16 *)(s0 + 0x6); + L.nv[1] = *(s32 *)(p + 0x60) - *(u16 *)(s0 + 0xA); + L.nv[2] = *(s32 *)(p + 0x64) - *(u16 *)(s0 + 0xE); + VectorNormalSS(L.nv, L.nv); + + *(s16 *)(s0 + 0x6) = *(u16 *)(s0 + 0x6) + ((s16)L.nv[0] >> 6); + *(s16 *)(s0 + 0xA) = *(u16 *)(s0 + 0xA) + ((s16)L.nv[1] >> 6); + *(s16 *)(s0 + 0xE) = *(u16 *)(s0 + 0xE) + ((s16)L.nv[2] >> 6); + *(s16 *)(s0 + 0x34) = 0x3000; + func_8002D4C8(0xAF8, 0); + } + + *(s16 *)(a0 + 0xFC) = *(u16 *)(a0 + 0xFC) + 1; +} + extern s32 rand(void); @@ -5367,7 +5907,167 @@ INCLUDE_ASM("asm/ov_SC06_033/nonmatchings/ov_SC06_033_jr_8017C24C", func_80186FD INCLUDE_ASM("asm/ov_SC06_033/nonmatchings/ov_SC06_033_jr_8017C24C", func_80187114); -INCLUDE_ASM("asm/ov_SC06_033/nonmatchings/ov_SC06_033_jr_8017C24C", func_80187138); + +// @class: struct +// @stuck: none — MATCH (276 ins, relocation-masked). Verified BOTH standalone (match_one) and +// spliced into src/ov_SC06_018/ov_SC06_018_jr_8017C24C.c (whole-TU cc1 -O2 clean, +// masked structured_diff 0/276). +// Keys: (1) the first func_8012C218 call gets a NOP delay slot because reload_cse_regs deletes the +// redundant `move a0,s1` -- $a0 still holds the incoming param on the fall-through path +// (no CODE_LABEL between the prologue and the jal). The second call site is behind a +// label, so the move survives. Source is the natural `func_8012C218((void *)param_1)` at +// BOTH sites -- do NOT write a zero-arg call (it also breaks in-TU: the composite type +// from the earlier file-scope `extern void func_8012C218(void *a0);` rejects 0 args). +// (2) case 0's guard is an `||` with an early return -- that is what puts `beqz -> fail` then +// `beq -> ok` (an `&&` would emit `bne -> fail`). +// (3) `register s32 sVar2 __asm__("$2")` holds the p+0x34 reload in cases 1/2 so the two arms +// cross-jump into the shared .L80188928 tail. +// (4) `__asm__ __volatile__("")` after the func_8012C658 arm forces the `lw v1,0x1C(s1)` +// reload before the cross-jumped `li v0,9` (§21 zero-byte re-tie). +// (5) `-((iVar3 << 0x10) / 0x22)` reproduces the 0x78787879/sra-4 magic-divide by 34 + negu. +// (6) `*p * 0xc` then `>>4` with the manual `if (x<0) x+=0xf` is the /16 rounding form. + +extern void func_8012C218(void *a0); +extern void func_80187E08(s32, void*, void*, s32); +extern s32 func_80013328(s32 a0, s32 a1); +extern void func_8012B14C(s32 a0, s32 a1); +extern void func_8012CC64(s32 a0, s32 a1); /* fleet-canonical: void; $v0 used -> cast at use */ +extern s32 func_8012C658(s32, s32, s32); +extern s32 func_80143B6C(s32 a0, s32 a1); /* fleet-canonical */ +extern s32 func_8012BEE8(s32 a0); +extern void func_80016714(void*, s32); +extern void func_80187A88(s32 a0, s32 a1); + + +void func_80187138(s32 param_1) { + + extern u8 D_801C7A9C; + extern u8 D_801AFD10; + extern u8 D_801AFD18; + extern u8 D_801AFD08; + extern u8 D_80126B5C; + u16 uVar1; + register s32 sVar2 __asm__("$2"); + s32 iVar3; + s32 iVar4; + s32 iVar5; + u32 uVar4; + s32 psVar5; + u16 buf[8]; + s32 vec[3]; + + if (0xf < *(s16 *)(param_1 + 0xA)) { + func_8012C218((void *)param_1); + return; + } + uVar1 = *(u16 *)(param_1 + 0x34); + switch (uVar1) { + case 0: + psVar5 = *(s32 *)(param_1 + 0x64); + if ((*(u16 *)psVar5 == 0) || + (*(s32 *)(psVar5 + 0x90) != (s32)&D_801C7A9C)) { + func_8012C218((void *)param_1); + return; + } + if (*(s32 *)(psVar5 + 0x94) < 0x11) { + ((void (*)(void *, void *, void *, s32))func_80187E08)((void *)psVar5, (void *)&D_801AFD10, buf, 5); + *(s16 *)(param_1 + 6) = buf[0]; + *(s16 *)(param_1 + 0xA) = buf[1]; + *(s16 *)(param_1 + 0xE) = buf[2]; + return; + } + ((void (*)(void *, void *, void *, s32))func_80187E08)((void *)psVar5, (void *)&D_801AFD18, buf, 4); + ((void (*)(void *, void *, void *, s32))func_80187E08)((void *)psVar5, (void *)&D_801AFD18, &buf[4], 5); + *(s16 *)(param_1 + 6) = + (s16)((*(s16 *)&buf[0] + *(s16 *)&buf[4]) >> 1); + *(s16 *)(param_1 + 0xA) = + (s16)((*(s16 *)&buf[1] + *(s16 *)&buf[5]) >> 1); + *(s16 *)(param_1 + 0xE) = + (s16)((*(s16 *)&buf[2] + *(s16 *)&buf[6]) >> 1); + if (*(s32 *)(psVar5 + 0x94) != 0x19) { + return; + } + *(u16 *)(param_1 + 0x34) = *(u16 *)(param_1 + 0x34) + 1; + vec[0] = 0; + vec[1] = 0xfff40000; + iVar3 = func_80013328((s32)&D_80126B5C, param_1 + 4); + vec[2] = -((iVar3 << 0x10) / 0x22); + func_8012B14C(param_1, (s32)vec); + *(s32 *)(param_1 + 0x48) = 0xc000; + return; + case 1: + *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x10) + 0x80; + iVar3 = ((s32 (*)(s32, s32))func_8012CC64)(param_1, (s32)&D_801AFD08); + if (iVar3 == 0) { + return; + } + sVar2 = *(u16 *)(param_1 + 0x34); + *(s32 *)(param_1 + 0x1c) = 0; + *(u16 *)(param_1 + 0x34) = sVar2 + 1; + return; + case 2: + *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x10) = + *(u16 *)(*(s32 *)(param_1 + 0x20) + 0x10) + 0x40; + uVar4 = ((s32 (*)(s32, s32))func_8012CC64)(param_1, (s32)&D_801AFD08); + if ((uVar4 & 0x2000) == 0) { + return; + } + iVar4 = *(s32 *)(param_1 + 0x1c) + 1; + *(s32 *)(param_1 + 0x1c) = iVar4; + if (iVar4 >= 4) { + sVar2 = *(u16 *)(param_1 + 0x34); + *(s32 *)(param_1 + 0x1c) = 0x1e; + *(u16 *)(param_1 + 0x34) = sVar2 + 1; + return; + } + iVar3 = *(s32 *)(param_1 + 0x10) * 0xc; + if (iVar3 < 0) { + iVar3 = iVar3 + 0xf; + } + *(s32 *)(param_1 + 0x10) = iVar3 >> 4; + iVar5 = *(s32 *)(param_1 + 0x18) * 0xc; + if (iVar5 < 0) { + iVar5 = iVar5 + 0xf; + } + *(s32 *)(param_1 + 0x18) = iVar5 >> 4; + *(s32 *)(param_1 + 0x14) = -(0x80000 / *(s32 *)(param_1 + 0x1c)); + func_80143B6C(param_1, 1); + return; + case 3: + uVar4 = *(u32 *)(param_1 + 0x1c); + if ((uVar4 - 0xe < 0xb) && ((uVar4 & 1) == 0)) { + ((void (*)(s32, s32, s32))func_8012C658)(0x2a8, (s32)*(s16 *)(param_1 + 0x104), param_1); + *(u16 *)(param_1 + 0x104) = *(u16 *)(param_1 + 0x104) + 1; + __asm__ __volatile__(""); + uVar4 = *(u32 *)(param_1 + 0x1c); + } + if (uVar4 == 9) { + *(u32 *)(*(s32 *)(param_1 + 0xcc) + 4) = + *(u32 *)(*(s32 *)(param_1 + 0xcc) + 4) & 0x7fffffff; + *(s16 *)(*(s32 *)(param_1 + 0xcc) + 8) = *(u16 *)(param_1 + 6); + *(s16 *)(*(s32 *)(param_1 + 0xcc) + 0xa) = + *(u16 *)(param_1 + 0xa) - 0x24; + *(s16 *)(*(s32 *)(param_1 + 0xcc) + 0xc) = *(u16 *)(param_1 + 0xe); + } + if (*(s32 *)(param_1 + 0x1c) - 4U < 6) { + *(s16 *)(*(s32 *)(param_1 + 0xcc) + 0x18) = + *(u16 *)(*(s32 *)(param_1 + 0xcc) + 0x18) + 0x200; + *(s16 *)(*(s32 *)(param_1 + 0xcc) + 0x1a) = + *(u16 *)(*(s32 *)(param_1 + 0xcc) + 0x1a) + 0x200; + } + iVar3 = func_8012BEE8(param_1); + if (iVar3 != 1) { + return; + } + ((void (*)(s32, s32))func_80016714)(*(s32 *)(param_1 + 0xcc), 0x38); + *(s16 *)(param_1 + 2) = 9; + func_80187A88(param_1, 0); + return; + } + return; +} + extern void func_80049CAC(s32, s32); @@ -5424,7 +6124,136 @@ void func_80187F3C(void *a0) { } -INCLUDE_ASM("asm/ov_SC06_033/nonmatchings/ov_SC06_033_jr_8017C24C", func_80187F78); + + +extern s32 rand(void); +extern void func_8012C1B8(void); +extern void func_8012CAE4(s32 a0); +extern void func_8001C214(s32 a0, s32 a1); +extern void func_8012B2CC(s32 a0); +extern void func_8012B178(s32 a0, s32 a1); + +void func_80187F78(s32 param_1) { + + extern u8 D_801AFDAC[]; + s32 unused[2]; /* dead 8-byte local — frame padding (cookbook idiom 6) */ + s32 obj; + s16 raw; + s32 r; + s32 sgn; + s32 v; + u8 *tbl; + s16 *p; + s32 q; + s32 w; + + obj = ((s32 (*)(void))func_8012C1B8)(); + if (obj == 0) { + func_8012CAE4(param_1); + return; + } + *(s32 *)(param_1 + 0x20) = obj; + func_8001C214(obj, 0); + + raw = rand(); + r = raw; + *(u16 *)(obj + 0x2C) = *(u16 *)(obj + 0x2C) | 0x10; + v = r % 384 + 0x400; + *(s16 *)(obj + 0x1C) = v; + *(s16 *)(obj + 0x1A) = v; + *(s16 *)(obj + 0x18) = v; + sgn = -1; + if (raw & 1) { + sgn = 1; + } + *(s16 *)(obj + 0x10) = sgn * (r % 128) - 0x300; + *(s16 *)(obj + 0x12) = r % 4096; + *(s32 *)(param_1 + 0x48) = 0xC000; + *(u16 *)(param_1 + 0xA) = *(u16 *)(param_1 + 0xA) - 0x19; + func_8012B2CC(param_1); + func_8012B178(param_1, -0xC0000 - ((r % 8) << 16)); + *(s32 *)(param_1 + 0x1C) = 0x3C; + *(s16 *)(param_1 + 0xFE) = rand() & 0xF0; + *(s16 *)(param_1 + 0x100) = rand() & 0x1F0; + *(s16 *)(param_1 + 0x102) = rand() & 0x30; + tbl = &D_801AFDAC[(*(u16 *)(param_1 + 0x70) & 0xF) * 4]; + + p = (s16 *)(param_1 + 0xDC); + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q - 0x18; + } else { + w = q - 0x18; + } + p[0] = w; + p[1] = 0; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q - 0x18; + } else { + w = q - 0x18; + } + p[2] = w; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q + 0x18; + } else { + w = q + 0x18; + } + p[4] = w; + p[5] = 0; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q - 0x18; + } else { + w = q - 0x18; + } + p[6] = w; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q - 0x18; + } else { + w = q - 0x18; + } + p[8] = w; + p[9] = 0; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q + 0x18; + } else { + w = q + 0x18; + } + p[10] = w; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q + 0x18; + } else { + w = q + 0x18; + } + p[12] = w; + p[13] = 0; + + q = rand() % 12; + if ((rand() & 1) == 0) { + w = -q + 0x18; + } else { + w = q + 0x18; + } + p[14] = w; + + *((u8 *)p + 0x20) = tbl[0]; + *((u8 *)p + 0x21) = tbl[1]; + *((u8 *)p + 0x22) = tbl[2]; + *(u16 *)(param_1 + 2) = *(u16 *)(param_1 + 2) + 1; +} + extern s32 func_8012CBF4(s32 a0); diff --git a/src/ov_SC07_009/ov_SC07_009_jr_8017AE2C.c b/src/ov_SC07_009/ov_SC07_009_jr_8017AE2C.c index a83d72d27..57e52832f 100644 --- a/src/ov_SC07_009/ov_SC07_009_jr_8017AE2C.c +++ b/src/ov_SC07_009/ov_SC07_009_jr_8017AE2C.c @@ -3993,7 +3993,21 @@ INCLUDE_ASM("asm/ov_SC07_009/nonmatchings/ov_SC07_009_jr_8017AE2C", func_8017D55 INCLUDE_ASM("asm/ov_SC07_009/nonmatchings/ov_SC07_009_jr_8017AE2C", func_8017D5A0); -INCLUDE_ASM("asm/ov_SC07_009/nonmatchings/ov_SC07_009_jr_8017AE2C", func_8017D5EC); +extern s32 func_8012BEE8(s32 a0); +extern void func_8017D980(s32 *a0); +extern s32 func_8012AD50(void *a0); +extern unsigned char D_801818C4; + +void func_8017D5EC(s32 a0) { + s32 result; + + result = func_8012BEE8(a0); + if (result != 0) { + func_8017D980((s32 *)&D_801818C4); + func_8012AD50((void *)a0); + } +} + INCLUDE_ASM("asm/ov_SC07_009/nonmatchings/ov_SC07_009_jr_8017AE2C", func_8017D634); @@ -4001,7 +4015,23 @@ INCLUDE_ASM("asm/ov_SC07_009/nonmatchings/ov_SC07_009_jr_8017AE2C", func_8017D68 INCLUDE_ASM("asm/ov_SC07_009/nonmatchings/ov_SC07_009_jr_8017AE2C", func_8017D6CC); -INCLUDE_ASM("asm/ov_SC07_009/nonmatchings/ov_SC07_009_jr_8017AE2C", func_8017D718); + +extern s32 func_8012BEE8(s32 a0); +extern void func_8017D980(s32 *a0); +extern s32 func_8012AD50(void *a0); + +void func_8017D718(s32 a0) { + + extern unsigned char D_8018190C; + s32 result; + + result = func_8012BEE8(a0); + if (result != 0) { + func_8017D980((s32 *)&D_8018190C); + func_8012AD50((void *)a0); + } +} + INCLUDE_ASM("asm/ov_SC07_009/nonmatchings/ov_SC07_009_jr_8017AE2C", func_8017D760); @@ -4009,7 +4039,23 @@ INCLUDE_ASM("asm/ov_SC07_009/nonmatchings/ov_SC07_009_jr_8017AE2C", func_8017D7A INCLUDE_ASM("asm/ov_SC07_009/nonmatchings/ov_SC07_009_jr_8017AE2C", func_8017D7F8); -INCLUDE_ASM("asm/ov_SC07_009/nonmatchings/ov_SC07_009_jr_8017AE2C", func_8017D844); + +extern s32 func_8012BEE8(s32 a0); +extern void func_8017D980(s32 *a0); +extern s32 func_8012AD50(void *a0); + +void func_8017D844(s32 a0) { + + extern unsigned char D_80181954; + s32 result; + + result = func_8012BEE8(a0); + if (result != 0) { + func_8017D980((s32 *)&D_80181954); + func_8012AD50((void *)a0); + } +} + INCLUDE_ASM("asm/ov_SC07_009/nonmatchings/ov_SC07_009_jr_8017AE2C", func_8017D88C);