From 7a4abddbfa5a7f899199c1b831ef52d08d9c2c7d Mon Sep 17 00:00:00 2001 From: Drew T <50529377+Druthulu@users.noreply.github.com> Date: Tue, 4 Aug 2026 07:14:28 -0600 Subject: [PATCH] =?UTF-8?q?feat(phase-30=20S34):=20wave=202=20=E2=80=94=20?= =?UTF-8?q?10=20heads=20+=2018=20members;=20the=20search=20order=20had=20a?= =?UTF-8?q?=20cross-overlay=20hole?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fleet 96.24% fn-count / 93.9 -> 94.0% instr / 88.4% distinct. R22 clean-fleet: 140 passed, 0 failed of 140. dedup 1910/0. WAVE 2: 13 targets / 37,943 templatable ins. 19 agents, 4.5M tokens. Claimed 11 MATCH; the whole-binary gate banked 9, +1 on reconcile (func_8017E5D0 via the §37/§124 DEFINITION-side alias — the TU declares it `(void)`, the byte-true def takes a pointer). Reconcile lane now 19/20 lifetime. 18 members swept. THE FINDING (an agent caught a hole in our own procedure). §136c's search order — engine_core.h near-twin -> same-TU banked sibling -> the .s — is entirely SAME-TU or SHARED-HEADER scoped, so no step can reach a banked twin in a DIFFERENT overlay's TU. But the large template classes live cross-overlay by construction. func_80188C04 (328 ins) turned out byte-identical to an already-banked func_801833F0 in ov_SC02_028, and ONE command found it: `grep -rn "E100000A" src/` — a magic word lifted from the target .s. The body was then reused verbatim, only file-local suffixes renamed. Promoted to STEP 0 of §136c, ahead of engine_core.h. That compounds with the manifest finding this session: the family map's `exemplar` is an IN-FAMILY pointer, so a family whose twin is banked elsewhere looks un-cracked — and the pointer can itself name an ALREADY-BANKED instance, hiding the family from any ranking built on it. Derive open sites from corpus.stubs over the member list instead. Measured on this wave: ranking off the map's exemplar gave 16,696 templatable ins; deriving from corpus.stubs gave 41,023, including a 55-ins family open in 138 overlays and a 46-ins one in 133. HONEST ON THE SWEEP: those two big families templated 18/165. That is the known h_seq refusal ceiling, not a new wall. One agent reported "all 10 members distance 0" — that is NORMALIZED distance, not h_exact, which is why dedup_propagate correctly answered reach<2. Do not read a normalized-distance claim as an h_exact guarantee. LEDGERED (real residual, not paperwork): func_8017F7B4 — needed its sibling's type names AND a data asm-label alias for a u8-shaped symbol, and still refuses. Plus func_8017C294 (DIFF close=12: 4 register/schedule permutations + a frame where I can get the 0x138 size OR pEnd's slot at 0x108, not both) and func_801898E4. --- docs/backlog.md | 87 +++-- docs/cookbook-index.md | 14 +- docs/family-hseq.md | 90 +++--- docs/matching-cookbook.md | 19 ++ docs/progress.fleet.md | 62 ++-- src/ov_SC01_000/ov_SC01_000_jr_8012ACE0.c | 25 +- src/ov_SC01_000/ov_SC01_000_jr_801734BC.c | 43 ++- src/ov_SC02_011/ov_SC02_011_jr_8017AE2C.c | 211 +++++++++++- src/ov_SC02_026/ov_SC02_026_jr_8017C180.c | 22 +- src/ov_SC02_031/ov_SC02_031_jr_8017AE2C.c | 76 ++++- src/ov_SC03_001/ov_SC03_001_jr_8017AE2C.c | 96 +++++- src/ov_SC03_006/ov_SC03_006_jr_8017AE2C.c | 76 ++++- src/ov_SC03_024/ov_SC03_024_jr_8017DF84.c | 76 ++++- src/ov_SC03_028/ov_SC03_028_jr_8017AE2C.c | 76 ++++- src/ov_SC03_089/ov_SC03_089_jr_8017CA80.c | 378 +++++++++++++++++++++- src/ov_SC03_111/ov_SC03_111_jr_8017AE2C.c | 76 ++++- src/ov_SC03_113/ov_SC03_113_jr_8017C294.c | 76 ++++- src/ov_SC03_114/ov_SC03_114_jr_8017BEBC.c | 259 ++++++++++++++- src/ov_SC03_118/ov_SC03_118_jr_8017AE2C.c | 76 ++++- src/ov_SC03_119/ov_SC03_119_jr_8017AE2C.c | 76 ++++- src/ov_SC03_125/ov_SC03_125_jr_8017AE2C.c | 76 ++++- src/ov_SC04_011/ov_SC04_011_jr_8017D494.c | 225 ++++++++++++- src/ov_SC04_016/ov_SC04_016_jr_8017BEBC.c | 225 ++++++++++++- src/ov_SC04_020/ov_SC04_020_jr_8017AE2C.c | 76 ++++- src/ov_SC05_004/ov_SC05_004_jr_8017BEBC.c | 76 ++++- src/ov_SC05_018/ov_SC05_018_jr_8017AE2C.c | 76 ++++- src/ov_SC06_000/ov_SC06_000_jr_8017AE2C.c | 230 ++++++++++++- src/ov_SC06_006/ov_SC06_006_jr_8017BEBC.c | 225 ++++++++++++- src/ov_SC06_011/ov_SC06_011_jr_8017BEBC.c | 240 +++++++++++++- src/ov_SC06_018/ov_SC06_018_jr_8017C24C.c | 225 ++++++++++++- src/ov_SC06_032/ov_SC06_032_jr_8017C24C.c | 225 ++++++++++++- 31 files changed, 3658 insertions(+), 155 deletions(-) diff --git a/docs/backlog.md b/docs/backlog.md index 2a96dba7c..b1a0f8491 100644 --- a/docs/backlog.md +++ b/docs/backlog.md @@ -2,7 +2,7 @@ > Generated by `tools/backlog.py render` from `.run/backlog.jsonl`. These are functions the Phase-21 automation got **close** on but did NOT byte-match. The whole-binary byte-gate is the sole arbiter (G3/P9): **byte-matches bank and are NOT listed here** — only genuine near-misses/blockers are. Ranked by hand-session priority: **reach** (×N propagation leverage) → **closeness** (match_one mismatch count, lower = closer) → **size**. Each row's `best_draft` is the closest C the machine reached — resume from there. -**Open near-misses:** 863 · by status {'near': 825, 'failed': 38} · by class {'schedule': 4, 'plumbing': 6, 'struct': 11, 'regalloc-order': 9, None: 827, 'other': 1, 'WAVE': 3, 'STRUCT': 1, 'loose-typing': 1} +**Open near-misses:** 862 · by status {'near': 824, 'failed': 38} · by class {'schedule': 4, 'plumbing': 6, 'struct': 11, 'regalloc-order': 9, None: 826, 'other': 1, 'WAVE': 3, 'STRUCT': 1, 'loose-typing': 1} | # | addr | reach | class | nins | status | closeness | where it stuck | best draft | |--:|------|------:|-------|-----:|--------|----------:|----------------|------------| @@ -826,46 +826,45 @@ | 818 | func_80183BF8 | None | | None | near | 258 | residual: 258 mismatch | `.run/backlog_drafts/func_80183BF8.c` | | 819 | func_8017EB30 | None | | None | near | 278 | residual: 278 mismatch | `.run/backlog_drafts/func_8017EB30.c` | | 820 | func_801804A0 | None | | None | near | 280 | residual: 280 mismatch | `.run/backlog_drafts/func_801804A0.c` | -| 821 | func_80187EDC | None | | None | near | 296 | residual: 296 mismatch | `.run/backlog_drafts/func_80187EDC.c` | -| 822 | func_8017F554 | None | | None | near | 299 | residual: 299 mismatch | `.run/backlog_drafts/func_8017F554.c` | -| 823 | func_80181670 | None | | None | near | 311 | residual: 311 mismatch | `.run/backlog_drafts/func_80181670.c` | -| 824 | func_8017EA84 | None | | None | near | 578 | residual: 578 mismatch | `.run/backlog_drafts/func_8017EA84.c` | -| 825 | func_8018057C | None | | None | near | 897 | residual: 897 mismatch | `.run/backlog_drafts/func_8018057C.c` | -| 826 | func_80184A68 | 1 | regalloc-order | 33 | failed | | none — MATCH | `.run/backlog_drafts/func_80184A68.c` | -| 827 | func_80180B64 | 1 | struct | 75 | failed | | none — MATCH (75 ins, relocation-masked) | `.run/backlog_drafts/func_80180B64.c` | -| 828 | func_80183DE0 | 1 | regalloc-order | 91 | failed | | testing if(!=1) layout + counter-before-pointer init order | `.run/backlog_drafts/func_80183DE0.c` | -| 829 | func_80182C9C | 1 | schedule | 101 | failed | | none — MATCH (101 ins). Inner-switch break-to-shared-tail must be written as | `.run/backlog_drafts/func_80182C9C.c` | -| 830 | func_80183FB8 | 1 | loose-typing | 101 | failed | | none — MATCH (relocation-masked match_one, 101/101 ins) | `.run/backlog_drafts/func_80183FB8.c` | -| 831 | func_80185BA4 | 1 | WAVE | 177 | failed | | won't compile standalone (loose-typing / missing decl) | | -| 832 | func_8017D8DC | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017D8DC.c` | -| 833 | func_8017FFEC | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017FFEC.c` | -| 834 | func_8017DC18 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017DC18.c` | -| 835 | func_801853CC | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801853CC.c` | -| 836 | func_80181894 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80181894.c` | -| 837 | func_8018BFBC | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8018BFBC.c` | -| 838 | func_801807F4 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801807F4.c` | -| 839 | func_8017FFC8 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017FFC8.c` | -| 840 | func_8017E99C | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017E99C.c` | -| 841 | func_80180294 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80180294.c` | -| 842 | func_8017E76C | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017E76C.c` | -| 843 | func_8017F29C | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017F29C.c` | -| 844 | func_8017F00C | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017F00C.c` | -| 845 | func_801802B0 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801802B0.c` | -| 846 | func_8017DA1C | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017DA1C.c` | -| 847 | func_8017FFC4 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017FFC4.c` | -| 848 | func_8017E2F0 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017E2F0.c` | -| 849 | func_801841E4 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801841E4.c` | -| 850 | func_80181738 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80181738.c` | -| 851 | func_801873D8 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801873D8.c` | -| 852 | func_80185628 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80185628.c` | -| 853 | func_80181A78 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80181A78.c` | -| 854 | func_801805D4 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801805D4.c` | -| 855 | func_8017EA1C | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017EA1C.c` | -| 856 | func_8017F098 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017F098.c` | -| 857 | func_801822CC | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801822CC.c` | -| 858 | func_8017E3F4 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017E3F4.c` | -| 859 | func_800D1658 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_800D1658.c` | -| 860 | func_800D1984 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_800D1984.c` | -| 861 | func_800D24A0 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_800D24A0.c` | -| 862 | func_80144B9C | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80144B9C.c` | -| 863 | func_8013DD68 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8013DD68.c` | +| 821 | func_8017F554 | None | | None | near | 299 | residual: 299 mismatch | `.run/backlog_drafts/func_8017F554.c` | +| 822 | func_80181670 | None | | None | near | 311 | residual: 311 mismatch | `.run/backlog_drafts/func_80181670.c` | +| 823 | func_8017EA84 | None | | None | near | 578 | residual: 578 mismatch | `.run/backlog_drafts/func_8017EA84.c` | +| 824 | func_8018057C | None | | None | near | 897 | residual: 897 mismatch | `.run/backlog_drafts/func_8018057C.c` | +| 825 | func_80184A68 | 1 | regalloc-order | 33 | failed | | none — MATCH | `.run/backlog_drafts/func_80184A68.c` | +| 826 | func_80180B64 | 1 | struct | 75 | failed | | none — MATCH (75 ins, relocation-masked) | `.run/backlog_drafts/func_80180B64.c` | +| 827 | func_80183DE0 | 1 | regalloc-order | 91 | failed | | testing if(!=1) layout + counter-before-pointer init order | `.run/backlog_drafts/func_80183DE0.c` | +| 828 | func_80182C9C | 1 | schedule | 101 | failed | | none — MATCH (101 ins). Inner-switch break-to-shared-tail must be written as | `.run/backlog_drafts/func_80182C9C.c` | +| 829 | func_80183FB8 | 1 | loose-typing | 101 | failed | | none — MATCH (relocation-masked match_one, 101/101 ins) | `.run/backlog_drafts/func_80183FB8.c` | +| 830 | func_80185BA4 | 1 | WAVE | 177 | failed | | won't compile standalone (loose-typing / missing decl) | | +| 831 | func_8017D8DC | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017D8DC.c` | +| 832 | func_8017FFEC | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017FFEC.c` | +| 833 | func_8017DC18 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017DC18.c` | +| 834 | func_801853CC | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801853CC.c` | +| 835 | func_80181894 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80181894.c` | +| 836 | func_8018BFBC | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8018BFBC.c` | +| 837 | func_801807F4 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801807F4.c` | +| 838 | func_8017FFC8 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017FFC8.c` | +| 839 | func_8017E99C | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017E99C.c` | +| 840 | func_80180294 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80180294.c` | +| 841 | func_8017E76C | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017E76C.c` | +| 842 | func_8017F29C | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017F29C.c` | +| 843 | func_8017F00C | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017F00C.c` | +| 844 | func_801802B0 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801802B0.c` | +| 845 | func_8017DA1C | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017DA1C.c` | +| 846 | func_8017FFC4 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017FFC4.c` | +| 847 | func_8017E2F0 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017E2F0.c` | +| 848 | func_801841E4 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801841E4.c` | +| 849 | func_80181738 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80181738.c` | +| 850 | func_801873D8 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801873D8.c` | +| 851 | func_80185628 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80185628.c` | +| 852 | func_80181A78 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80181A78.c` | +| 853 | func_801805D4 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801805D4.c` | +| 854 | func_8017EA1C | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017EA1C.c` | +| 855 | func_8017F098 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017F098.c` | +| 856 | func_801822CC | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801822CC.c` | +| 857 | func_8017E3F4 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017E3F4.c` | +| 858 | func_800D1658 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_800D1658.c` | +| 859 | func_800D1984 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_800D1984.c` | +| 860 | func_800D24A0 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_800D24A0.c` | +| 861 | func_80144B9C | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80144B9C.c` | +| 862 | func_8013DD68 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8013DD68.c` | diff --git a/docs/cookbook-index.md b/docs/cookbook-index.md index c1c5c3393..131c99481 100644 --- a/docs/cookbook-index.md +++ b/docs/cookbook-index.md @@ -2,7 +2,7 @@ > **Generated by `tools/cookbook_index.py` — do not hand-edit** (R33). Regenerate after adding a cookbook section. > -> `docs/matching-cookbook.md` is ~716 KB / 389 sections. Grepping it blind is how three P30 wave-1 agents each "discovered" an idiom that was already written down. **Start here, then read the section.** A section appears under every symptom it addresses. +> `docs/matching-cookbook.md` is ~716 KB / 390 sections. Grepping it blind is how three P30 wave-1 agents each "discovered" an idiom that was already written down. **Start here, then read the section.** A section appears under every symptom it addresses. **How to use:** name what you SEE in the diff (a stolen delay slot, an extra `la`, a swapped register pair, a `conflicting types` error), find that symptom below, read those sections first. If nothing fits, THEN grind — and add a section when you win. @@ -225,7 +225,7 @@ - **§3-The** — declaration surface (integration, not codegen) L8931 - **§136f** — Two declaration sub-cases the reconcile lane surfaced (lane now 15/15 lifetime) L9176 - **§138** — The propagation lanes: a gate refusal is a DECLARATION, and which lever you owe depends on blast radius L9405 -- **Reconciling** — a gate-refused draft: which way you edit depends on WHERE the TU's decl is L9536 +- **Reconciling** — a gate-refused draft: which way you edit depends on WHERE the TU's decl is L9555 ### jump tables & switches (25) @@ -377,7 +377,7 @@ - **§114** — The THIRD decl axis: a CALLEE the draft declares differently from the target TU (Phase 29 T76/T77) L7801 - **§3-The** — integration idioms (these decide whether a byte-correct draft BANKS) L8797 - **§3-The** — declaration surface (integration, not codegen) L8931 -- **Reconciling** — a gate-refused draft: which way you edit depends on WHERE the TU's decl is L9536 +- **Reconciling** — a gate-refused draft: which way you edit depends on WHERE the TU's decl is L9555 ### build graph, splat & the harness (95) @@ -475,7 +475,7 @@ - **§137a** — A gate verdict has a TIMESTAMP; re-check it against the draft's mtime L9376 - **§138** — The propagation lanes: a gate refusal is a DECLARATION, and which lever you owe depends on blast radius L9405 - **§134** — again, in a second tool — and the waiter rule corrected L9516 -- **Reconciling** — a gate-refused draft: which way you edit depends on WHERE the TU's decl is L9536 +- **Reconciling** — a gate-refused draft: which way you edit depends on WHERE the TU's decl is L9555 ### process, measurement & doctrine (53) @@ -533,7 +533,7 @@ - **§136j** — The failure MIX flips with function size (measured across four bands, one session) L9292 - **Rank** — the lane by measured concentration, not by class count L9471 -### (unbucketed — title matched no symptom vocabulary) (109) +### (unbucketed — title matched no symptom vocabulary) (110) - **§3-How** — to use this L30 - **§1** — Idiom catalog (asm pattern → C that produces it) L39 @@ -644,6 +644,7 @@ - **§136i** — The drafter model LADDER: Haiku → **Sonnet** → Opus → Fable5 (Drew, 2026-08-03) L9260 - **§3-The** — triage, cheapest first L9411 - **THREE** — carry variants hide in one "CARRY-FIXABLE" bucket — and they need different fixes L9480 +- **STEP** — 0 of sibling-first: grep `src/` for a distinctive LITERAL from the `.s` L9536 ## All sections, in order @@ -1036,4 +1037,5 @@ - **Rank** — the lane by measured concentration, not by class count L9471 - **THREE** — carry variants hide in one "CARRY-FIXABLE" bucket — and they need different fixes L9480 - **§134** — again, in a second tool — and the waiter rule corrected L9516 -- **Reconciling** — a gate-refused draft: which way you edit depends on WHERE the TU's decl is L9536 +- **STEP** — 0 of sibling-first: grep `src/` for a distinctive LITERAL from the `.s` L9536 +- **Reconciling** — a gate-refused draft: which way you edit depends on WHERE the TU's decl is L9555 diff --git a/docs/family-hseq.md b/docs/family-hseq.md index d1cde2ec5..2cf8616f0 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:1386` · 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:1387` · 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.5% fn / 94.4% instr / 89.3% distinct-code matched. Unmatched: 12,264 instances / 736,631 ins (9,820 distinct classes). +**Fleet (overlays):** 96.5% fn / 94.4% instr / 89.4% distinct-code matched. Unmatched: 12,230 instances / 730,269 ins (9,790 distinct classes). -**Tail cross-check (Phase-25 close):** 8,013 tail fns / 392,543 ins → 434 h_seq families ≥2, **111 substantial (nins≥80) / 88,803 ins**. +**Tail cross-check (Phase-25 close):** 7,867 tail fns / 390,989 ins → 433 h_seq families ≥2, **110 substantial (nins≥80) / 87,350 ins**. -**Full frontier (all unmatched by h_seq):** 2044 target families (≥2 members or a matched sibling) + 3767 singletons (Step-D residue). Substantial: **381 families / 274,821 templatable ins**, 30 with a matched sibling (zero-crack). Substantial member classes: 1,625 PURE · 29 IMM · 6 STRUCT-excluded. +**Full frontier (all unmatched by h_seq):** 2041 target families (≥2 members or a matched sibling) + 3767 singletons (Step-D residue). Substantial: **378 families / 268,604 templatable ins**, 28 with a matched sibling (zero-crack). Substantial member classes: 1,595 PURE · 28 IMM · 6 STRUCT-excluded. ## Top substantial families (by templatable byte-weight) @@ -21,47 +21,47 @@ | 4 | 299 | 20 (20/0/0) | 20/20 | scattered | PURE | 0 | Y | 0x8017fee0 modal | 5,980 | | 5 | 246 | 16 (16/0/0) | 6/16 | cross-address | PURE | 0 | · | 0x8017c294 draft-ov077 | 3,936 | | 6 | 491 | 7 (7/0/0) | 6/7 | cross-address | PURE | 0 | Y | 0x801863cc modal | 3,437 | -| 7 | 328 | 10 (10/0/0) | 10/10 | scattered | PURE | 1 | · | 0x801833f0 matched | 3,280 | -| 8 | 770 | 4 (4/0/0) | 1/4 | per-location | PURE | 134 | · | 0x80144b9c matched-ov077 | 3,080 | -| 9 | 611 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | · | 0x80186e24 modal | 3,055 | +| 7 | 770 | 4 (4/0/0) | 1/4 | per-location | PURE | 134 | · | 0x80144b9c matched-ov077 | 3,080 | +| 8 | 611 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | · | 0x80186e24 modal | 3,055 | +| 9 | 328 | 9 (9/0/0) | 9/9 | scattered | PURE | 2 | · | 0x801833f0 matched | 2,952 | | 10 | 557 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | Y | 0x80186570 modal | 2,785 | | 11 | 551 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | Y | 0x80189540 modal | 2,755 | | 12 | 125 | 22 (22/0/0) | 22/22 | scattered | PURE | 0 | Y | 0x80185440 modal | 2,750 | -| 13 | 263 | 10 (10/0/0) | 10/10 | scattered | PURE | 1 | · | 0x80182fd4 matched | 2,630 | -| 14 | 513 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | Y | 0x801878e8 modal | 2,565 | -| 15 | 296 | 7 (7/0/0) | 7/7 | cross-address | PURE | 0 | · | 0x8017e2ec modal | 2,072 | -| 16 | 137 | 15 (15/0/0) | 15/15 | scattered | PURE | 0 | Y | 0x80183084 modal | 2,055 | -| 17 | 438 | 4 (4/0/0) | 1/4 | per-location | PURE | 134 | Y | 0x801380e0 matched-ov077 | 1,752 | -| 18 | 579 | 3 (3/0/0) | 2/3 | cross-address | PURE | 0 | Y | 0x8018103c draft-ov077 | 1,737 | -| 19 | 133 | 13 (13/0/0) | 10/13 | scattered | PURE | 1 | · | 0x8017d0bc matched | 1,729 | -| 20 | 288 | 6 (6/0/0) | 6/6 | cross-address | PURE | 0 | Y | 0x80184c74 modal | 1,728 | -| 21 | 281 | 6 (6/0/0) | 6/6 | cross-address | PURE | 0 | Y | 0x80186270 modal | 1,686 | -| 22 | 240 | 7 (7/0/0) | 6/7 | cross-address | PURE | 0 | Y | 0x801872b4 modal | 1,680 | -| 23 | 265 | 6 (0/6/0) | 6/6 | cross-address | IMM | 1 | · | 0x80183e04 matched | 1,590 | -| 24 | 143 | 11 (11/0/0) | 10/11 | scattered | PURE | 1 | · | 0x8017d77c matched | 1,573 | -| 25 | 251 | 6 (6/0/0) | 6/6 | cross-address | PURE | 0 | Y | 0x80186994 modal | 1,506 | -| 26 | 710 | 2 (2/0/0) | 2/2 | cross-address | PURE | 1 | Y | 0x80191c50 matched | 1,420 | -| 27 | 470 | 3 (3/0/0) | 3/3 | cross-address | PURE | 0 | Y | 0x80191320 modal | 1,410 | -| 28 | 279 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | Y | 0x8017f2d4 modal | 1,395 | -| 29 | 229 | 6 (6/0/0) | 2/6 | cross-address | PURE | 1 | · | 0x8017c290 matched | 1,374 | -| 30 | 673 | 2 (2/0/0) | 2/2 | cross-address | PURE | 1 | Y | 0x8019059c matched | 1,346 | -| 31 | 254 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | Y | 0x80188e1c modal | 1,270 | -| 32 | 198 | 6 (6/0/0) | 6/6 | cross-address | PURE | 1 | · | 0x80181ee0 matched | 1,188 | -| 33 | 198 | 6 (6/0/0) | 6/6 | cross-address | PURE | 0 | Y | 0x80185f58 modal | 1,188 | -| 34 | 385 | 3 (3/0/0) | 3/3 | cross-address | PURE | 0 | Y | 0x8018ff98 modal | 1,155 | -| 35 | 185 | 6 (6/0/0) | 6/6 | cross-address | PURE | 0 | Y | 0x80187aec modal | 1,110 | -| 36 | 184 | 6 (6/0/0) | 2/6 | cross-address | PURE | 1 | · | 0x8017d318 matched | 1,104 | -| 37 | 203 | 5 (0/5/0) | 4/5 | cross-address | IMM | 5 | · | 0x8017e804 matched | 1,015 | -| 38 | 324 | 3 (3/0/0) | 2/3 | cross-address | PURE | 0 | Y | 0x80183324 draft-ov077 | 972 | -| 39 | 121 | 8 (8/0/0) | 8/8 | cross-address | PURE | 9 | · | 0x8018b76c matched | 968 | -| 40 | 95 | 10 (10/0/0) | 9/10 | scattered | PURE | 0 | Y | 0x80185d70 modal | 950 | -| 41 | 231 | 4 (4/0/0) | 4/4 | cross-address | PURE | 0 | Y | 0x8017f83c modal | 924 | -| 42 | 184 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | · | 0x8017e3dc modal | 920 | -| 43 | 115 | 8 (8/0/0) | 6/8 | cross-address | PURE | 0 | · | 0x8018089c modal | 920 | -| 44 | 153 | 6 (6/0/0) | 6/6 | cross-address | PURE | 0 | · | 0x80181d94 modal | 918 | -| 45 | 152 | 6 (6/0/0) | 6/6 | cross-address | PURE | 0 | · | 0x8018200c modal | 912 | -| 46 | 180 | 5 (5/0/0) | 5/5 | cross-address | PURE | 0 | · | 0x80182a78 modal | 900 | -| 47 | 225 | 4 (4/0/0) | 4/4 | cross-address | PURE | 0 | · | 0x801803e0 modal | 900 | -| 48 | 150 | 6 (6/0/0) | 6/6 | cross-address | PURE | 0 | · | 0x8018829c modal | 900 | -| 49 | 175 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | · | 0x8017e6bc modal | 875 | -| 50 | 124 | 7 (7/0/0) | 7/7 | cross-address | PURE | 0 | · | 0x80181cf0 modal | 868 | +| 13 | 513 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | Y | 0x801878e8 modal | 2,565 | +| 14 | 263 | 9 (9/0/0) | 9/9 | scattered | PURE | 2 | · | 0x80182fd4 matched | 2,367 | +| 15 | 137 | 15 (15/0/0) | 15/15 | scattered | PURE | 0 | Y | 0x80183084 modal | 2,055 | +| 16 | 438 | 4 (4/0/0) | 1/4 | per-location | PURE | 134 | Y | 0x801380e0 matched-ov077 | 1,752 | +| 17 | 579 | 3 (3/0/0) | 2/3 | cross-address | PURE | 0 | Y | 0x8018103c draft-ov077 | 1,737 | +| 18 | 288 | 6 (6/0/0) | 6/6 | cross-address | PURE | 0 | Y | 0x80184c74 modal | 1,728 | +| 19 | 281 | 6 (6/0/0) | 6/6 | cross-address | PURE | 0 | Y | 0x80186270 modal | 1,686 | +| 20 | 240 | 7 (7/0/0) | 6/7 | cross-address | PURE | 0 | Y | 0x801872b4 modal | 1,680 | +| 21 | 251 | 6 (6/0/0) | 6/6 | cross-address | PURE | 0 | Y | 0x80186994 modal | 1,506 | +| 22 | 143 | 10 (10/0/0) | 9/10 | scattered | PURE | 2 | · | 0x8017df78 matched | 1,430 | +| 23 | 710 | 2 (2/0/0) | 2/2 | cross-address | PURE | 1 | Y | 0x80191c50 matched | 1,420 | +| 24 | 470 | 3 (3/0/0) | 3/3 | cross-address | PURE | 0 | Y | 0x80191320 modal | 1,410 | +| 25 | 279 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | Y | 0x8017f2d4 modal | 1,395 | +| 26 | 673 | 2 (2/0/0) | 2/2 | cross-address | PURE | 1 | Y | 0x8019059c matched | 1,346 | +| 27 | 265 | 5 (0/5/0) | 5/5 | cross-address | IMM | 2 | · | 0x80183e04 matched | 1,325 | +| 28 | 254 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | Y | 0x80188e1c modal | 1,270 | +| 29 | 198 | 6 (6/0/0) | 6/6 | cross-address | PURE | 0 | Y | 0x80185f58 modal | 1,188 | +| 30 | 385 | 3 (3/0/0) | 3/3 | cross-address | PURE | 0 | Y | 0x8018ff98 modal | 1,155 | +| 31 | 229 | 5 (5/0/0) | 1/5 | per-location | PURE | 2 | · | 0x8017e72c matched | 1,145 | +| 32 | 185 | 6 (6/0/0) | 6/6 | cross-address | PURE | 0 | Y | 0x80187aec modal | 1,110 | +| 33 | 184 | 6 (6/0/0) | 2/6 | cross-address | PURE | 1 | · | 0x8017d318 matched | 1,104 | +| 34 | 203 | 5 (0/5/0) | 4/5 | cross-address | IMM | 5 | · | 0x8017e804 matched | 1,015 | +| 35 | 324 | 3 (3/0/0) | 2/3 | cross-address | PURE | 0 | Y | 0x80183324 draft-ov077 | 972 | +| 36 | 121 | 8 (8/0/0) | 8/8 | cross-address | PURE | 9 | · | 0x8018b76c matched | 968 | +| 37 | 95 | 10 (10/0/0) | 9/10 | scattered | PURE | 0 | Y | 0x80185d70 modal | 950 | +| 38 | 231 | 4 (4/0/0) | 4/4 | cross-address | PURE | 0 | Y | 0x8017f83c modal | 924 | +| 39 | 184 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | · | 0x8017e3dc modal | 920 | +| 40 | 115 | 8 (8/0/0) | 6/8 | cross-address | PURE | 0 | · | 0x8018089c modal | 920 | +| 41 | 153 | 6 (6/0/0) | 6/6 | cross-address | PURE | 0 | · | 0x80181d94 modal | 918 | +| 42 | 152 | 6 (6/0/0) | 6/6 | cross-address | PURE | 0 | · | 0x8018200c modal | 912 | +| 43 | 180 | 5 (5/0/0) | 5/5 | cross-address | PURE | 0 | · | 0x80182a78 modal | 900 | +| 44 | 225 | 4 (4/0/0) | 4/4 | cross-address | PURE | 0 | · | 0x801803e0 modal | 900 | +| 45 | 150 | 6 (6/0/0) | 6/6 | cross-address | PURE | 0 | · | 0x8018829c modal | 900 | +| 46 | 175 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | · | 0x8017e6bc modal | 875 | +| 47 | 124 | 7 (7/0/0) | 7/7 | cross-address | PURE | 0 | · | 0x80181cf0 modal | 868 | +| 48 | 173 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | · | 0x8017dc48 modal | 865 | +| 49 | 214 | 4 (4/0/0) | 4/4 | cross-address | PURE | 0 | · | 0x8017f2e8 modal | 856 | +| 50 | 122 | 7 (7/0/0) | 7/7 | cross-address | PURE | 0 | · | 0x8017f100 modal | 854 | diff --git a/docs/matching-cookbook.md b/docs/matching-cookbook.md index 9a0a368cf..aa07c2f57 100644 --- a/docs/matching-cookbook.md +++ b/docs/matching-cookbook.md @@ -9533,6 +9533,25 @@ on **`tools/treelock.sh --status`**, which is a statement of intent spanning the wrap a campaign in `nohup … &` inside a backgrounded call: the harness then signals completion of the *wrapper* — a fleet check "finished" at 63/140. +### STEP 0 of sibling-first: grep `src/` for a distinctive LITERAL from the `.s` + +§136c's search order (engine_core.h near-twin -> same-TU banked sibling -> the `.s`) has a hole: both +of its first two steps are **same-TU or shared-header** scoped, so neither can reach a banked twin +that lives in a **different overlay's** TU — and the large template classes live cross-overlay by +construction. Measured: `func_80188C04` (328 ins) was byte-identical to an already-banked +`func_801833F0` in `ov_SC02_028`, and one command found it — + + grep -rn "E100000A" src/ # a magic word lifted straight out of the target .s + +— after which the body was reused verbatim with only the file-local type/macro suffixes renamed. +**Put this ahead of engine_core.h.** Pick a distinctive constant from the target: a magic word, an +unusual mask, an odd immediate. Corollary for the family map: it carries an in-family `exemplar` +pointer only, so a family whose twin is banked *elsewhere* looks un-cracked — and, separately, that +pointer can name an instance that is **already banked**, which hides the whole family from any +ranking built on it. **Derive open sites from `corpus.stubs` over the member list.** Measured on one +wave: ranking off the map's `exemplar` yielded 16,696 templatable ins; deriving from `corpus.stubs` +yielded **41,023** — including a 55-ins family open in 138 overlays and a 46-ins one open in 133. + ### Reconciling a gate-refused draft: which way you edit depends on WHERE the TU's decl is A draft that `match_one`-MATCHes but the whole-binary gate refuses is declaration plumbing (the diff --git a/docs/progress.fleet.md b/docs/progress.fleet.md index e88fd8e70..1d28cc77d 100644 --- a/docs/progress.fleet.md +++ b/docs/progress.fleet.md @@ -4,23 +4,23 @@ # cross-binary collapsible-byte leverage: docs/duplicates.cross.md. # THREE progress metrics (all matter — see the labels): -FLEET fn-count byte-ident: 340408 / 353721 = 96.24% (REAL+LINKED+empties; FUNCTION-count, ×134-inflated — one crack counts per overlay) -FLEET instr-weighted : 12344917 / 13141652 = 93.9% (shipped .text across main + resident + 138 overlays; the decomp.dev-DISPLAY number) -FLEET distinct-code(uniq): 4978834 / 5634875 = 88.4% (77631/87459 unique fns; the DISTINCT-RE number) +FLEET fn-count byte-ident: 340436 / 353721 = 96.24% (REAL+LINKED+empties; FUNCTION-count, ×134-inflated — one crack counts per overlay) +FLEET instr-weighted : 12350091 / 13141652 = 94.0% (shipped .text across main + resident + 138 overlays; the decomp.dev-DISPLAY number) +FLEET distinct-code(uniq): 4983476 / 5634875 = 88.4% (77655/87459 unique fns; the DISTINCT-RE number) MAIN game-code weighted : 436 / 60201 = 0.7% (INCLUDED in the fleet numbers above since 2026-07-22 — roadmap §1 metrics contract; LINKED-excluding Ghidra sig dated 2026-06-14; caveat is R34: no independent second oracle for a PS-X EXE, NOT drift) - (fleet EXCLUDING main, for continuity with pre-2026-07-22 readings: 12344481 / 13081451 = 94.4%) + (fleet EXCLUDING main, for continuity with pre-2026-07-22 readings: 12349655 / 13081451 = 94.4%) -FLEET REAL substantive : 338553 (of which dedup-shared 241142 via 1910 groups / 241216 instances) +FLEET REAL substantive : 338581 (of which dedup-shared 241142 via 1910 groups / 241216 instances) FLEET LINKED PsyQ objs : 959 FLEET NON_MATCHING : 7 (0 in any default build — G4) -FLEET INCLUDE_ASM stubs : 13306 +FLEET INCLUDE_ASM stubs : 13278 FLEET matchable : 353721 | binary | REAL | shared | LINKED | byte-ident | matchable | byte-ident % | |---|---:|---:|---:|---:|---:|---:| | main | 54 | 2 | 959 | 1055 | 2096 | 50.3% | | resident | 129 | 0 | 0 | 131 | 145 | 90.3% | -| ov_SC01_000 | 2382 | 1753 | 0 | 2382 | 2403 | 99.1% | +| ov_SC01_000 | 2384 | 1753 | 0 | 2384 | 2403 | 99.2% | | ov_SC01_001 | 2390 | 1754 | 0 | 2392 | 2466 | 97.0% | | ov_SC01_004 | 2384 | 1745 | 0 | 2385 | 2414 | 98.8% | | ov_SC01_005 | 2414 | 1768 | 0 | 2414 | 2503 | 96.4% | @@ -35,22 +35,22 @@ FLEET matchable : 353721 | ov_SC02_003 | 2507 | 1793 | 0 | 2507 | 2683 | 93.4% | | ov_SC02_004 | 2382 | 1749 | 0 | 2382 | 2401 | 99.2% | | ov_SC02_005 | 2530 | 1745 | 0 | 2540 | 2927 | 86.8% | -| ov_SC02_011 | 2614 | 1752 | 0 | 2625 | 2893 | 90.7% | +| ov_SC02_011 | 2616 | 1752 | 0 | 2627 | 2893 | 90.8% | | ov_SC02_015 | 2393 | 1751 | 0 | 2393 | 2414 | 99.1% | | ov_SC02_016 | 2474 | 1751 | 0 | 2477 | 2545 | 97.3% | | ov_SC02_017 | 2542 | 1751 | 0 | 2550 | 2732 | 93.3% | | ov_SC02_021 | 2398 | 1751 | 0 | 2398 | 2437 | 98.4% | -| ov_SC02_026 | 2489 | 1749 | 0 | 2495 | 2572 | 97.0% | +| ov_SC02_026 | 2490 | 1749 | 0 | 2496 | 2572 | 97.0% | | ov_SC02_027 | 2546 | 1749 | 0 | 2555 | 2692 | 94.9% | | ov_SC02_028 | 2552 | 1749 | 0 | 2562 | 2701 | 94.9% | -| ov_SC02_031 | 2485 | 1750 | 0 | 2490 | 2562 | 97.2% | +| ov_SC02_031 | 2486 | 1750 | 0 | 2491 | 2562 | 97.2% | | ov_SC02_035 | 2473 | 1749 | 0 | 2476 | 2520 | 98.3% | | ov_SC02_039 | 2387 | 1749 | 0 | 2387 | 2416 | 98.8% | | ov_SC02_041 | 2464 | 1749 | 0 | 2467 | 2561 | 96.3% | -| ov_SC03_001 | 2650 | 1750 | 0 | 2667 | 2869 | 93.0% | +| ov_SC03_001 | 2651 | 1750 | 0 | 2668 | 2869 | 93.0% | | ov_SC03_002 | 2526 | 1754 | 0 | 2541 | 2631 | 96.6% | | ov_SC03_003 | 2391 | 1749 | 0 | 2392 | 2423 | 98.7% | -| ov_SC03_006 | 2540 | 1755 | 0 | 2549 | 2767 | 92.1% | +| ov_SC03_006 | 2541 | 1755 | 0 | 2550 | 2767 | 92.2% | | ov_SC03_007 | 2454 | 1749 | 0 | 2458 | 2623 | 93.7% | | ov_SC03_010 | 2407 | 1749 | 0 | 2407 | 2471 | 97.4% | | ov_SC03_011 | 2409 | 1749 | 0 | 2415 | 2527 | 95.6% | @@ -59,12 +59,12 @@ FLEET matchable : 353721 | ov_SC03_014 | 2563 | 1777 | 0 | 2563 | 2685 | 95.5% | | ov_SC03_015 | 2562 | 1777 | 0 | 2562 | 2685 | 95.4% | | ov_SC03_023 | 2393 | 1749 | 0 | 2394 | 2435 | 98.3% | -| ov_SC03_024 | 2504 | 1754 | 0 | 2511 | 2641 | 95.1% | -| ov_SC03_028 | 2451 | 1749 | 0 | 2455 | 2664 | 92.2% | +| ov_SC03_024 | 2505 | 1754 | 0 | 2512 | 2641 | 95.1% | +| ov_SC03_028 | 2452 | 1749 | 0 | 2456 | 2664 | 92.2% | | ov_SC03_029 | 2493 | 1751 | 0 | 2503 | 2644 | 94.7% | | ov_SC03_030 | 2411 | 1754 | 0 | 2413 | 2495 | 96.7% | | ov_SC03_031 | 2440 | 1749 | 0 | 2443 | 2514 | 97.2% | -| ov_SC03_089 | 2499 | 1754 | 0 | 2506 | 2581 | 97.1% | +| ov_SC03_089 | 2501 | 1754 | 0 | 2508 | 2581 | 97.2% | | ov_SC03_090 | 2509 | 1754 | 0 | 2517 | 2625 | 95.9% | | ov_SC03_091 | 2523 | 1749 | 0 | 2531 | 2640 | 95.9% | | ov_SC03_092 | 2492 | 1754 | 0 | 2504 | 2587 | 96.8% | @@ -84,18 +84,18 @@ FLEET matchable : 353721 | ov_SC03_108 | 2390 | 1749 | 0 | 2390 | 2443 | 97.8% | | ov_SC03_109 | 2400 | 1749 | 0 | 2402 | 2424 | 99.1% | | ov_SC03_110 | 2432 | 1749 | 0 | 2432 | 2468 | 98.5% | -| ov_SC03_111 | 2462 | 1749 | 0 | 2465 | 2510 | 98.2% | +| ov_SC03_111 | 2463 | 1749 | 0 | 2466 | 2510 | 98.2% | | ov_SC03_112 | 2424 | 1751 | 0 | 2426 | 2526 | 96.0% | -| ov_SC03_113 | 2425 | 1751 | 0 | 2428 | 2468 | 98.4% | -| ov_SC03_114 | 2382 | 1749 | 0 | 2384 | 2415 | 98.7% | +| ov_SC03_113 | 2426 | 1751 | 0 | 2429 | 2468 | 98.4% | +| ov_SC03_114 | 2383 | 1749 | 0 | 2385 | 2415 | 98.8% | | ov_SC03_115 | 2423 | 1749 | 0 | 2425 | 2472 | 98.1% | | ov_SC03_116 | 2390 | 1749 | 0 | 2393 | 2438 | 98.2% | | ov_SC03_117 | 2458 | 1749 | 0 | 2464 | 2557 | 96.4% | -| ov_SC03_118 | 2530 | 1773 | 0 | 2531 | 2685 | 94.3% | -| ov_SC03_119 | 2526 | 1773 | 0 | 2527 | 2685 | 94.1% | +| ov_SC03_118 | 2531 | 1773 | 0 | 2532 | 2685 | 94.3% | +| ov_SC03_119 | 2527 | 1773 | 0 | 2528 | 2685 | 94.2% | | ov_SC03_121 | 2396 | 1749 | 0 | 2399 | 2459 | 97.6% | | ov_SC03_124 | 2560 | 1745 | 0 | 2580 | 2741 | 94.1% | -| ov_SC03_125 | 2513 | 1749 | 0 | 2525 | 2588 | 97.6% | +| ov_SC03_125 | 2514 | 1749 | 0 | 2526 | 2588 | 97.6% | | ov_SC03_126 | 2392 | 1751 | 0 | 2392 | 2423 | 98.7% | | ov_SC04_000 | 2465 | 1753 | 0 | 2474 | 2546 | 97.2% | | ov_SC04_002 | 2492 | 1749 | 0 | 2496 | 2636 | 94.7% | @@ -107,19 +107,19 @@ FLEET matchable : 353721 | ov_SC04_008 | 2393 | 1749 | 0 | 2393 | 2415 | 99.1% | | ov_SC04_009 | 2419 | 1749 | 0 | 2422 | 2441 | 99.2% | | ov_SC04_010 | 2395 | 1749 | 0 | 2396 | 2419 | 99.0% | -| ov_SC04_011 | 2507 | 1754 | 0 | 2513 | 2803 | 89.7% | +| ov_SC04_011 | 2508 | 1754 | 0 | 2514 | 2803 | 89.7% | | ov_SC04_012 | 2390 | 1749 | 0 | 2391 | 2420 | 98.8% | | ov_SC04_015 | 2518 | 1750 | 0 | 2529 | 2611 | 96.9% | -| ov_SC04_016 | 2393 | 1749 | 0 | 2395 | 2440 | 98.2% | +| ov_SC04_016 | 2394 | 1749 | 0 | 2396 | 2440 | 98.2% | | ov_SC04_018 | 2662 | 1785 | 0 | 2662 | 2857 | 93.2% | | ov_SC04_019 | 2654 | 1785 | 0 | 2654 | 2857 | 92.9% | -| ov_SC04_020 | 2500 | 1749 | 0 | 2512 | 2567 | 97.9% | +| ov_SC04_020 | 2501 | 1749 | 0 | 2513 | 2567 | 97.9% | | ov_SC04_021 | 2392 | 1751 | 0 | 2392 | 2423 | 98.7% | | ov_SC05_000 | 2399 | 1753 | 0 | 2402 | 2422 | 99.2% | | ov_SC05_001 | 2467 | 1749 | 0 | 2472 | 2574 | 96.0% | | ov_SC05_002 | 2423 | 1749 | 0 | 2426 | 2442 | 99.3% | | ov_SC05_003 | 2404 | 1749 | 0 | 2405 | 2481 | 96.9% | -| ov_SC05_004 | 2413 | 1749 | 0 | 2415 | 2464 | 98.0% | +| ov_SC05_004 | 2414 | 1749 | 0 | 2416 | 2464 | 98.1% | | ov_SC05_005 | 2429 | 1754 | 0 | 2430 | 2491 | 97.6% | | ov_SC05_006 | 2415 | 1749 | 0 | 2415 | 2430 | 99.4% | | ov_SC05_007 | 2422 | 1749 | 0 | 2427 | 2482 | 97.8% | @@ -128,18 +128,18 @@ FLEET matchable : 353721 | ov_SC05_010 | 2439 | 1749 | 0 | 2443 | 2588 | 94.4% | | ov_SC05_011 | 2389 | 1749 | 0 | 2390 | 2409 | 99.2% | | ov_SC05_017 | 2633 | 1746 | 0 | 2644 | 2842 | 93.0% | -| ov_SC05_018 | 2529 | 1749 | 0 | 2542 | 2673 | 95.1% | +| ov_SC05_018 | 2530 | 1749 | 0 | 2543 | 2673 | 95.1% | | ov_SC05_019 | 2392 | 1751 | 0 | 2392 | 2423 | 98.7% | -| ov_SC06_000 | 2518 | 1758 | 0 | 2521 | 2691 | 93.7% | -| ov_SC06_006 | 2415 | 1749 | 0 | 2416 | 2511 | 96.2% | +| ov_SC06_000 | 2519 | 1758 | 0 | 2522 | 2691 | 93.7% | +| ov_SC06_006 | 2416 | 1749 | 0 | 2417 | 2511 | 96.3% | | ov_SC06_008 | 2472 | 1751 | 0 | 2478 | 2542 | 97.5% | | ov_SC06_010 | 2446 | 1749 | 0 | 2451 | 2517 | 97.4% | -| ov_SC06_011 | 2407 | 1749 | 0 | 2411 | 2468 | 97.7% | +| ov_SC06_011 | 2408 | 1749 | 0 | 2412 | 2468 | 97.7% | | ov_SC06_013 | 2397 | 1749 | 0 | 2398 | 2425 | 98.9% | | ov_SC06_014 | 2408 | 1749 | 0 | 2410 | 2453 | 98.2% | | ov_SC06_015 | 2402 | 1749 | 0 | 2402 | 2421 | 99.2% | | ov_SC06_016 | 2444 | 1749 | 0 | 2446 | 2549 | 96.0% | -| ov_SC06_018 | 2476 | 1751 | 0 | 2483 | 2665 | 93.2% | +| ov_SC06_018 | 2477 | 1751 | 0 | 2484 | 2665 | 93.2% | | ov_SC06_020 | 2432 | 1751 | 0 | 2433 | 2518 | 96.6% | | ov_SC06_022 | 2462 | 1749 | 0 | 2470 | 2642 | 93.5% | | ov_SC06_024 | 2481 | 1749 | 0 | 2487 | 2667 | 93.3% | @@ -147,7 +147,7 @@ FLEET matchable : 353721 | ov_SC06_027 | 2384 | 1749 | 0 | 2385 | 2408 | 99.0% | | ov_SC06_029 | 2466 | 1749 | 0 | 2478 | 2662 | 93.1% | | ov_SC06_030 | 2405 | 1749 | 0 | 2405 | 2456 | 97.9% | -| ov_SC06_032 | 2468 | 1750 | 0 | 2475 | 2658 | 93.1% | +| ov_SC06_032 | 2469 | 1750 | 0 | 2476 | 2658 | 93.2% | | ov_SC06_033 | 2467 | 1750 | 0 | 2474 | 2631 | 94.0% | | ov_SC07_000 | 2425 | 1753 | 0 | 2427 | 2521 | 96.3% | | ov_SC07_001 | 2397 | 1749 | 0 | 2399 | 2454 | 97.8% | diff --git a/src/ov_SC01_000/ov_SC01_000_jr_8012ACE0.c b/src/ov_SC01_000/ov_SC01_000_jr_8012ACE0.c index c7ed774f1..d7582d1dd 100644 --- a/src/ov_SC01_000/ov_SC01_000_jr_8012ACE0.c +++ b/src/ov_SC01_000/ov_SC01_000_jr_8012ACE0.c @@ -2243,7 +2243,30 @@ void func_80131FDC(void *a0) { } -INCLUDE_ASM("asm/ov_SC01_000/nonmatchings/ov_SC01_000_jr_8012ACE0", func_80132018); +extern void func_8012C1B8(void); +extern void func_8012CAE4(void *a0); +extern void func_8001C214(int, int); +extern void (*D_8017F130[])(void); +extern s32 D_8017F134[]; + +void func_80132018(void *a0) +{ + s32 v0; + + v0 = ((int (*)(void))func_8012C1B8)(); + *(s32 *)((s32)a0 + 0x20) = v0; + if (v0 == 0) { + func_8012CAE4(a0); + } else { + func_8001C214(v0, 0); + *(s16 *)((s32)a0 + 0x5c) = 0x80; + *(u16 *)((s32)a0 + 0x2) += 1; + *(s32 *)((s32)a0 + 0x58) = (s32)&D_8017F134[(*(u16 *)((s32)a0 + 0x70) & 0xfff) * 5]; + *(s32 *)((s32)a0 + 0xdc) = (s32)D_8017F130[(*(u16 *)((s32)a0 + 0x70) & 0xfff) * 5]; + *(u16 *)((s32)a0 + 0xfc) = (*(u16 *)((s32)a0 + 0x70) >> 0xc) << 9; + } +} + DEFINE_func_801320D0() /* dedup: shared engine-core @0x801320D0 (src/shared) */ diff --git a/src/ov_SC01_000/ov_SC01_000_jr_801734BC.c b/src/ov_SC01_000/ov_SC01_000_jr_801734BC.c index 398e90288..5462d8218 100644 --- a/src/ov_SC01_000/ov_SC01_000_jr_801734BC.c +++ b/src/ov_SC01_000/ov_SC01_000_jr_801734BC.c @@ -2945,7 +2945,48 @@ s32 func_80175820(void) } -INCLUDE_ASM("asm/ov_SC01_000/nonmatchings/ov_SC01_000_jr_801734BC", func_801758FC); +/* func_801758FC — twin of the byte-matched func_80175820 / func_801759D8 in this same TU. + * Same three-part body (part1: mask-merge a word at ptr[N] with a masked read from + * D_8011F7A8+idx*4+B; part2: mask-merge *p2 (p2 = D_8011F7A8+idx*4+A) with the old ptr[N] value; + * part3: D_800AF634[idx].g0 accumulates ((D_8011F7A8+idx*4+B) - ((D_8011F7A8+idx*4+A) - 0x14)) >> 2), + * here with N=3 (offset 0xC), A=0x28 (D_8011F7D0), B=0x30 (D_8011F7D8). + * The two __asm__ memory fences keep the three parts from CSE-ing their base addresses together, + * matching func_80175820 / func_801759D8 exactly (same idiom, different slot/offsets). + */ + +typedef struct { u32 *f0; s32 pad[4]; } S_AE7BC_801758FC; /* size 0x14 */ +typedef struct { s32 g0; s32 pad[2]; } S_AF634_801758FC; /* size 0x0C */ + +s32 func_801758FC(void) +{ + extern s16 D_800B9A02; + extern S_AE7BC_801758FC D_800AE7BC[]; + extern S_AF634_801758FC D_800AF634[]; + extern u8 D_8011F7A8; + u8 *p = (u8 *)&D_8011F7A8; + u16 *q; + u32 *ptr; + u32 old; + u32 *p2; + + q = (u16 *)&(*(u16 *)&D_800B9A02); + + ptr = D_800AE7BC[*q].f0; + old = ptr[3]; + ptr[3] = (old & 0xff000000) | (*(u32 *)(p + *q * 4 + 0x30) & 0xffffff); + __asm__("" ::: "memory"); + + p2 = *(u32 **)(p + *q * 4 + 0x28); + *p2 = (*p2 & 0xff000000) | (old & 0xffffff); + __asm__("" ::: "memory"); + + { + s32 acc = D_800AF634[*q].g0; + s32 t = *(s32 *)(p + *q * 4 + 0x28) - 0x14; + D_800AF634[*q].g0 = acc + ((*(s32 *)(p + *q * 4 + 0x30) - t) >> 2); + } +} + 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 b2ee84f1d..aeac6fbd2 100644 --- a/src/ov_SC02_011/ov_SC02_011_jr_8017AE2C.c +++ b/src/ov_SC02_011/ov_SC02_011_jr_8017AE2C.c @@ -4824,7 +4824,79 @@ void func_8017DD34(s16 *a0) { } -INCLUDE_ASM("asm/ov_SC02_011/nonmatchings/ov_SC02_011_jr_8017AE2C", func_8017DE10); +/* func_8017DE10 -- ov_SC02_011 / ov_SC02_011_jr_8017AE2C [target: 133 ins] + * + * Structural twin of func_8017D0BC (ov_SC03_002/ov_SC03_002_jr_8017AE2C.c), + * banked [MATCH, 133 ins] this session -- same jr_8017AE2C shared layout, + * identical struct-offset chain (a0+0x6/0xA/0xE/0x10/0x12/0x16/0x18/0x1A) and + * identical call sequence (func_80133784 -> ratan2 x2 -> angle-wrap -> + * RotMatrixY -> ApplyMatrixSV -> func_8012CEB0). Reused verbatim per §136c + * sibling-first (declaration + expression forms are already byte-proven for + * this exact body). + * + * §136 L1/RC-5 note carried from the twin: `ang` (second ratan2 result) is a + * GLOBAL allocno spanning the +/-0x480 arms, while the `ang - base` compare + * temp is a LOCAL allocno in the same block; unpinned gcc hands the local + * temp $v0 and pushes `ang` to $v1 (REGALLOC-PERM). Pinning `ang` to $v0 + * fixes the swap, and reusing the now-dead `ang` as the a0[0x6] scratch + * (instead of a fresh local) avoids stealing back the $v0 slot. + */ + +typedef struct { s32 w[8]; } Mtx8_8017DE10; + +void func_8017DE10(s32 a0) { + extern void ApplyMatrixSV(void *a0, void *a1, void *a2); + extern s32 ratan2(s32 a0, s32 a1); + extern s16 D_801152B0; + extern s16 D_801152B4; + extern s32 func_80133784(s32 a0, void *a1, s32 a2); + extern s32 func_8012CEB0(s32 a0, s32 a1, s32 a2); + extern void RotMatrixY(s32 a0, void *a1); + extern Mtx8_8017DE10 D_800AE620; + + u8 in[8]; + u8 out[8]; + Mtx8_8017DE10 m; + s32 base; + register s32 ang __asm__("$2"); + s16 arg; + + *(s16 *)(in + 0) = *(u16 *)(a0 + 0x6) + *(u16 *)(a0 + 0x12); + *(s16 *)(in + 2) = *(u16 *)(a0 + 0xA) + 8; + *(s16 *)(in + 4) = *(u16 *)(a0 + 0xE) + *(u16 *)(a0 + 0x1A); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x6); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0xA) + 8; + *(s16 *)(out + 4) = *(u16 *)(a0 + 0xE); + if ((func_80133784(1, &in[0], (s32)&out[0]) & 0xC000) != 0) { + base = ratan2(D_801152B0, D_801152B4) & 0xFFF; + ang = ratan2(*(s32 *)(a0 + 0x10), *(s32 *)(a0 + 0x18)) & 0xFFF; + if ((s16)(ang - base) < 0) { + ang += 0x480; + } else { + ang -= 0x480; + } + arg = base - ang; + ang = *(u16 *)(a0 + 0x6); + *(s16 *)(in + 0) = ang; + *(s16 *)(in + 2) = *(u16 *)(a0 + 0xA); + *(s16 *)(in + 4) = *(u16 *)(a0 + 0xE); + m = D_800AE620; + RotMatrixY(arg, &m); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x12); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0x16); + *(s16 *)(out + 4) = *(u16 *)(a0 + 0x1A); + ApplyMatrixSV(&m, &out[0], &out[0]); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x6) + ((s16)*(u16 *)(out + 0) >> 1); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0xA) + ((s16)*(u16 *)(out + 2) >> 1); + *(s16 *)(out + 4) = *(u16 *)(a0 + 0xE) + ((s16)*(u16 *)(out + 4) >> 1); + if ((func_8012CEB0((s32)&in[0], (s32)&out[0], 0) & 0x2000) != 0) { + *(s16 *)(a0 + 0x6) = *(u16 *)(out + 0); + *(s16 *)(a0 + 0xA) = *(u16 *)(out + 2); + *(s16 *)(a0 + 0xE) = *(u16 *)(out + 4); + } + } +} + extern int func_80178970(void); @@ -5097,7 +5169,142 @@ void func_8017E5E8(void) { INCLUDE_ASM("asm/ov_SC02_011/nonmatchings/ov_SC02_011_jr_8017AE2C", func_8017E5F0); -INCLUDE_ASM("asm/ov_SC02_011/nonmatchings/ov_SC02_011_jr_8017AE2C", func_8017E72C); +/* func_8017E72C -- ov_SC02_011, TU ov_SC02_011_jr_8017AE2C.c + * + * §136c sibling-first: near-twin is the already-banked func_8017C290 in + * src/ov_SC03_014/ov_SC03_014_jr_8017AE2C.c (same "jr_8017AE2C" family). + * Reused verbatim from it: the MATRIX/SVECTOR/PW (packed align-1, 4 byte) + * type trio, the gte_ldv0/gte_rt/gte_stsv inline-asm macros, the whole + * statement shape and order, and the extern decls for func_80013F3C / + * RotMatrixZ / func_8004914C / func_800491AC / func_80017714 / rand. + * Only the data symbols differ (D_801EB4C8 in place of D_801EA8C0, etc.) -- + * none of them appear anywhere else in this TU, so fresh local types are + * declared here under a _8017E72C suffix. + */ + +typedef struct { s16 m[3][3]; s16 pad; s32 t[3]; } MATRIX_8017E72C; +typedef struct { u16 vx, vy, vz, pad; } SVECTOR_8017E72C; +struct PW8017E72C { 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_8017E72C D_801EB4C8[4]; +extern struct PW8017E72C D_801EB4E8; +extern struct PW8017E72C D_801EB4EC; +extern u8 D_801EB4F0, D_801EB4F1, D_801EB4F2, D_801EB4F4, D_801EB4F5, D_801EB4F6; +extern int D_801EB4F8; +extern struct PW8017E72C D_80194BA4[]; + +#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_8017E72C(int a, s16 *b, SVECTOR_8017E72C *c, SVECTOR_8017E72C *d, + SVECTOR_8017E72C *e, SVECTOR_8017E72C *f, s16 *g) +{ + MATRIX_8017E72C m; + SVECTOR_8017E72C *r0_00; + SVECTOR_8017E72C *pSVar6; + SVECTOR_8017E72C *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_801EB4C8[0]; + if (*(s16 *)(a + 0x12) == 0) { + D_801EB4F8 = 0x50000000; + D_801EB4E8 = D_80194BA4[*(s32 *)(a + 0x2C)]; + D_801EB4EC = D_80194BA4[*(s32 *)(a + 0x2C)]; + D_801EB4F0 = 0; + D_801EB4F1 = 0; + D_801EB4F2 = 0; + D_801EB4F4 = 0; + D_801EB4F5 = 0; + D_801EB4F6 = 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_SC02_011/nonmatchings/ov_SC02_011_jr_8017AE2C", func_8017EAC0); diff --git a/src/ov_SC02_026/ov_SC02_026_jr_8017C180.c b/src/ov_SC02_026/ov_SC02_026_jr_8017C180.c index 9c687a1ab..3fadc1626 100644 --- a/src/ov_SC02_026/ov_SC02_026_jr_8017C180.c +++ b/src/ov_SC02_026/ov_SC02_026_jr_8017C180.c @@ -6542,7 +6542,27 @@ void func_80185634(void *a0) { } -INCLUDE_ASM("asm/ov_SC02_026/nonmatchings/ov_SC02_026_jr_8017C180", func_801856E4); +#include "common.h" + +/* §37 data asm-label alias: D_800A5EA8/D_800A5EB0/struct B16_80185634 are already declared + * above the splice point (func_80185634's block, same TU). Redeclaring the struct TAG body + * verbatim would be a C89 duplicate-definition error there, so alias a private identifier + * onto the same linker symbol -- zero blast radius, identical %hi/%lo(D_800A5EA8) codegen. */ +struct B16_801856E4 { s32 w[4]; }; + +extern struct B16_801856E4 aD800A5EA8 __asm__("D_800A5EA8"); +extern struct B16_801856E4 D_801CCC30; +extern s32 D_800A5EB0; +extern s32 func_8004787C(s32 a0); +extern void func_80028620(s32 a0, void *a1); + +void func_801856E4(void *a0) { + aD800A5EA8 = D_801CCC30; + D_800A5EB0 = func_8004787C(*(s16 *)((s32)a0 + 0xFE)) * 6 / 4096 - 3; + *(u16 *)((s32)a0 + 0xFE) = (*(u16 *)((s32)a0 + 0xFE) + 0x71) & 0xFFF; + func_80028620(2, &aD800A5EA8); +} + #include "common.h" diff --git a/src/ov_SC02_031/ov_SC02_031_jr_8017AE2C.c b/src/ov_SC02_031/ov_SC02_031_jr_8017AE2C.c index 6026f16fc..36a8b8e12 100644 --- a/src/ov_SC02_031/ov_SC02_031_jr_8017AE2C.c +++ b/src/ov_SC02_031/ov_SC02_031_jr_8017AE2C.c @@ -5457,7 +5457,81 @@ void func_8017ED60(s16 *a0) { } -INCLUDE_ASM("asm/ov_SC02_031/nonmatchings/ov_SC02_031_jr_8017AE2C", func_8017EE3C); + + +/* func_8017EE3C -- ov_SC02_011 / ov_SC02_011_jr_8017AE2C [target: 133 ins] + * + * Structural twin of func_8017D0BC (ov_SC03_002/ov_SC03_002_jr_8017AE2C.c), + * banked [MATCH, 133 ins] this session -- same jr_8017AE2C shared layout, + * identical struct-offset chain (a0+0x6/0xA/0xE/0x10/0x12/0x16/0x18/0x1A) and + * identical call sequence (func_80133784 -> ratan2 x2 -> angle-wrap -> + * RotMatrixY -> ApplyMatrixSV -> func_8012CEB0). Reused verbatim per §136c + * sibling-first (declaration + expression forms are already byte-proven for + * this exact body). + * + * §136 L1/RC-5 note carried from the twin: `ang` (second ratan2 result) is a + * GLOBAL allocno spanning the +/-0x480 arms, while the `ang - base` compare + * temp is a LOCAL allocno in the same block; unpinned gcc hands the local + * temp $v0 and pushes `ang` to $v1 (REGALLOC-PERM). Pinning `ang` to $v0 + * fixes the swap, and reusing the now-dead `ang` as the a0[0x6] scratch + * (instead of a fresh local) avoids stealing back the $v0 slot. + */ + +typedef struct { s32 w[8]; } Mtx8_8017DE10_8017EE3C; + +void func_8017EE3C(s32 a0) { + extern void ApplyMatrixSV(void *a0, void *a1, void *a2); + extern s32 ratan2(s32 a0, s32 a1); + extern s16 D_801152B0; + extern s16 D_801152B4; + extern s32 func_80133784(s32 a0, void *a1, s32 a2); + extern s32 func_8012CEB0(s32 a0, s32 a1, s32 a2); + extern void RotMatrixY(s32 a0, void *a1); + extern Mtx8_8017DE10_8017EE3C D_800AE620; + + u8 in[8]; + u8 out[8]; + Mtx8_8017DE10_8017EE3C m; + s32 base; + register s32 ang __asm__("$2"); + s16 arg; + + *(s16 *)(in + 0) = *(u16 *)(a0 + 0x6) + *(u16 *)(a0 + 0x12); + *(s16 *)(in + 2) = *(u16 *)(a0 + 0xA) + 8; + *(s16 *)(in + 4) = *(u16 *)(a0 + 0xE) + *(u16 *)(a0 + 0x1A); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x6); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0xA) + 8; + *(s16 *)(out + 4) = *(u16 *)(a0 + 0xE); + if ((func_80133784(1, &in[0], (s32)&out[0]) & 0xC000) != 0) { + base = ratan2(D_801152B0, D_801152B4) & 0xFFF; + ang = ratan2(*(s32 *)(a0 + 0x10), *(s32 *)(a0 + 0x18)) & 0xFFF; + if ((s16)(ang - base) < 0) { + ang += 0x480; + } else { + ang -= 0x480; + } + arg = base - ang; + ang = *(u16 *)(a0 + 0x6); + *(s16 *)(in + 0) = ang; + *(s16 *)(in + 2) = *(u16 *)(a0 + 0xA); + *(s16 *)(in + 4) = *(u16 *)(a0 + 0xE); + m = D_800AE620; + RotMatrixY(arg, &m); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x12); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0x16); + *(s16 *)(out + 4) = *(u16 *)(a0 + 0x1A); + ApplyMatrixSV(&m, &out[0], &out[0]); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x6) + ((s16)*(u16 *)(out + 0) >> 1); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0xA) + ((s16)*(u16 *)(out + 2) >> 1); + *(s16 *)(out + 4) = *(u16 *)(a0 + 0xE) + ((s16)*(u16 *)(out + 4) >> 1); + if ((func_8012CEB0((s32)&in[0], (s32)&out[0], 0) & 0x2000) != 0) { + *(s16 *)(a0 + 0x6) = *(u16 *)(out + 0); + *(s16 *)(a0 + 0xA) = *(u16 *)(out + 2); + *(s16 *)(a0 + 0xE) = *(u16 *)(out + 4); + } + } +} + extern int func_80178970(void); 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 0c43f3cac..16b6c60b2 100644 --- a/src/ov_SC03_001/ov_SC03_001_jr_8017AE2C.c +++ b/src/ov_SC03_001/ov_SC03_001_jr_8017AE2C.c @@ -4275,7 +4275,101 @@ void func_8017DEE8(void *arg0) { } -INCLUDE_ASM("asm/ov_SC03_001/nonmatchings/ov_SC03_001_jr_8017AE2C", func_8017DF78); + + +extern u8 D_80078EB1; +extern u8 D_80078E78[]; +extern u8 D_800AF630[]; +extern Ent_8017D6EC_8017DEE8 D_801EE888[]; +extern s32 func_8004787C(s32 a0); +extern void func_8012AD44(s32 *a0, s16 a1); +extern void func_8017E1B4(void *a0); +extern void func_8017E2C0(void *arg0); + +void func_8017DF78(void *arg0) +{ + u8 *m; + u8 *e78; + s32 k; + + m = D_800AF630; + e78 = D_80078E78; + + if (D_80078EB1 >= 9) { + s32 count; + s32 i; + u8 *base; + + base = (u8 *)D_801EE888; + count = 0; + for (i = 0; i < 4; i++) { + if (*(s32 *)(base + i * 0x24 + 0x1C) == 0) { + count++; + } + } + if (count == 0) { + func_8012AD44((s32 *)arg0, 0); + return; + } + } + + for (k = 0; k < 4; k++) { + u8 *p = (u8 *)D_801EE888 + k * 0x24; + s32 c; + + if (*(s32 *)(p + 0x1C) != 0) { + continue; + } + + { + s16 val = *(s16 *)(p + 0xC); + if (val < 0x401) { + *(s16 *)(p + 0xC) = val + 0xB; + } else if (*(s32 *)(p + 0x18) != 0) { + *(s32 *)(p + 0x18) -= 1; + } else { + *(s16 *)(p + 0xC) = val + 0xB; + } + } + + if (*(s16 *)(p + 0xC) >= 0x801) { + *(s16 *)(p + 0xC) = 0; + } + + c = (func_8004787C(*(s16 *)(p + 0xC)) / 64) & 0xFF; + c = c | (c << 16 | c << 8); + *(s32 *)(p + 0x4) = c; + + c = (func_8004787C(*(s16 *)(p + 0xC)) / 256) & 0xFF; + c = c | (c << 16 | c << 8); + *(s32 *)(p + 0x8) = c; + + if ((*(u16 *)(m + 0xA3AA) & 1) == 0) { + s16 cnt = *(u16 *)(p + 0xE) + 1; + *(u16 *)(p + 0xE) = cnt; + if (cnt >= 0x40) { + *(u16 *)(p + 0xE) = 0; + } + } + + { + s32 val2 = *(s16 *)(p + 0xC); + if (val2 == 0) { + *(s32 *)(p + 0x1C) = 1; + } else if (val2 >= 0x556) { + if (*(s32 *)(p + 0x20) == 0) { + *(s32 *)(p + 0x20) = 1; + if (e78[0x39] < 9) { + func_8017E1B4(p); + } + } + } + } + + func_8017E2C0(p); + } +} + INCLUDE_ASM("asm/ov_SC03_001/nonmatchings/ov_SC03_001_jr_8017AE2C", func_8017E1B4); 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 24e79ec1c..2e7ea688e 100644 --- a/src/ov_SC03_006/ov_SC03_006_jr_8017AE2C.c +++ b/src/ov_SC03_006/ov_SC03_006_jr_8017AE2C.c @@ -5249,7 +5249,81 @@ void func_8017E634(s16 *a0) { } -INCLUDE_ASM("asm/ov_SC03_006/nonmatchings/ov_SC03_006_jr_8017AE2C", func_8017E710); + + +/* func_8017E710 -- ov_SC02_011 / ov_SC02_011_jr_8017AE2C [target: 133 ins] + * + * Structural twin of func_8017D0BC (ov_SC03_002/ov_SC03_002_jr_8017AE2C.c), + * banked [MATCH, 133 ins] this session -- same jr_8017AE2C shared layout, + * identical struct-offset chain (a0+0x6/0xA/0xE/0x10/0x12/0x16/0x18/0x1A) and + * identical call sequence (func_80133784 -> ratan2 x2 -> angle-wrap -> + * RotMatrixY -> ApplyMatrixSV -> func_8012CEB0). Reused verbatim per §136c + * sibling-first (declaration + expression forms are already byte-proven for + * this exact body). + * + * §136 L1/RC-5 note carried from the twin: `ang` (second ratan2 result) is a + * GLOBAL allocno spanning the +/-0x480 arms, while the `ang - base` compare + * temp is a LOCAL allocno in the same block; unpinned gcc hands the local + * temp $v0 and pushes `ang` to $v1 (REGALLOC-PERM). Pinning `ang` to $v0 + * fixes the swap, and reusing the now-dead `ang` as the a0[0x6] scratch + * (instead of a fresh local) avoids stealing back the $v0 slot. + */ + +typedef struct { s32 w[8]; } Mtx8_8017DE10_8017E710; + +void func_8017E710(s32 a0) { + extern void ApplyMatrixSV(void *a0, void *a1, void *a2); + extern s32 ratan2(s32 a0, s32 a1); + extern s16 D_801152B0; + extern s16 D_801152B4; + extern s32 func_80133784(s32 a0, void *a1, s32 a2); + extern s32 func_8012CEB0(s32 a0, s32 a1, s32 a2); + extern void RotMatrixY(s32 a0, void *a1); + extern Mtx8_8017DE10_8017E710 D_800AE620; + + u8 in[8]; + u8 out[8]; + Mtx8_8017DE10_8017E710 m; + s32 base; + register s32 ang __asm__("$2"); + s16 arg; + + *(s16 *)(in + 0) = *(u16 *)(a0 + 0x6) + *(u16 *)(a0 + 0x12); + *(s16 *)(in + 2) = *(u16 *)(a0 + 0xA) + 8; + *(s16 *)(in + 4) = *(u16 *)(a0 + 0xE) + *(u16 *)(a0 + 0x1A); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x6); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0xA) + 8; + *(s16 *)(out + 4) = *(u16 *)(a0 + 0xE); + if ((func_80133784(1, &in[0], (s32)&out[0]) & 0xC000) != 0) { + base = ratan2(D_801152B0, D_801152B4) & 0xFFF; + ang = ratan2(*(s32 *)(a0 + 0x10), *(s32 *)(a0 + 0x18)) & 0xFFF; + if ((s16)(ang - base) < 0) { + ang += 0x480; + } else { + ang -= 0x480; + } + arg = base - ang; + ang = *(u16 *)(a0 + 0x6); + *(s16 *)(in + 0) = ang; + *(s16 *)(in + 2) = *(u16 *)(a0 + 0xA); + *(s16 *)(in + 4) = *(u16 *)(a0 + 0xE); + m = D_800AE620; + RotMatrixY(arg, &m); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x12); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0x16); + *(s16 *)(out + 4) = *(u16 *)(a0 + 0x1A); + ApplyMatrixSV(&m, &out[0], &out[0]); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x6) + ((s16)*(u16 *)(out + 0) >> 1); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0xA) + ((s16)*(u16 *)(out + 2) >> 1); + *(s16 *)(out + 4) = *(u16 *)(a0 + 0xE) + ((s16)*(u16 *)(out + 4) >> 1); + if ((func_8012CEB0((s32)&in[0], (s32)&out[0], 0) & 0x2000) != 0) { + *(s16 *)(a0 + 0x6) = *(u16 *)(out + 0); + *(s16 *)(a0 + 0xA) = *(u16 *)(out + 2); + *(s16 *)(a0 + 0xE) = *(u16 *)(out + 4); + } + } +} + extern int func_80178970(void); diff --git a/src/ov_SC03_024/ov_SC03_024_jr_8017DF84.c b/src/ov_SC03_024/ov_SC03_024_jr_8017DF84.c index 960ac12f5..274109cd9 100644 --- a/src/ov_SC03_024/ov_SC03_024_jr_8017DF84.c +++ b/src/ov_SC03_024/ov_SC03_024_jr_8017DF84.c @@ -3855,7 +3855,81 @@ void func_8017FAEC(s16 *a0) { } -INCLUDE_ASM("asm/ov_SC03_024/nonmatchings/ov_SC03_024_jr_8017DF84", func_8017FBC8); + + +/* func_8017FBC8 -- ov_SC02_011 / ov_SC02_011_jr_8017AE2C [target: 133 ins] + * + * Structural twin of func_8017D0BC (ov_SC03_002/ov_SC03_002_jr_8017AE2C.c), + * banked [MATCH, 133 ins] this session -- same jr_8017AE2C shared layout, + * identical struct-offset chain (a0+0x6/0xA/0xE/0x10/0x12/0x16/0x18/0x1A) and + * identical call sequence (func_80133784 -> ratan2 x2 -> angle-wrap -> + * RotMatrixY -> ApplyMatrixSV -> func_8012CEB0). Reused verbatim per §136c + * sibling-first (declaration + expression forms are already byte-proven for + * this exact body). + * + * §136 L1/RC-5 note carried from the twin: `ang` (second ratan2 result) is a + * GLOBAL allocno spanning the +/-0x480 arms, while the `ang - base` compare + * temp is a LOCAL allocno in the same block; unpinned gcc hands the local + * temp $v0 and pushes `ang` to $v1 (REGALLOC-PERM). Pinning `ang` to $v0 + * fixes the swap, and reusing the now-dead `ang` as the a0[0x6] scratch + * (instead of a fresh local) avoids stealing back the $v0 slot. + */ + +typedef struct { s32 w[8]; } Mtx8_8017DE10_8017FBC8; + +void func_8017FBC8(s32 a0) { + extern void ApplyMatrixSV(void *a0, void *a1, void *a2); + extern s32 ratan2(s32 a0, s32 a1); + extern s16 D_801152B0; + extern s16 D_801152B4; + extern s32 func_80133784(s32 a0, void *a1, s32 a2); + extern s32 func_8012CEB0(s32 a0, s32 a1, s32 a2); + extern void RotMatrixY(s32 a0, void *a1); + extern Mtx8_8017DE10_8017FBC8 D_800AE620; + + u8 in[8]; + u8 out[8]; + Mtx8_8017DE10_8017FBC8 m; + s32 base; + register s32 ang __asm__("$2"); + s16 arg; + + *(s16 *)(in + 0) = *(u16 *)(a0 + 0x6) + *(u16 *)(a0 + 0x12); + *(s16 *)(in + 2) = *(u16 *)(a0 + 0xA) + 8; + *(s16 *)(in + 4) = *(u16 *)(a0 + 0xE) + *(u16 *)(a0 + 0x1A); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x6); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0xA) + 8; + *(s16 *)(out + 4) = *(u16 *)(a0 + 0xE); + if ((func_80133784(1, &in[0], (s32)&out[0]) & 0xC000) != 0) { + base = ratan2(D_801152B0, D_801152B4) & 0xFFF; + ang = ratan2(*(s32 *)(a0 + 0x10), *(s32 *)(a0 + 0x18)) & 0xFFF; + if ((s16)(ang - base) < 0) { + ang += 0x480; + } else { + ang -= 0x480; + } + arg = base - ang; + ang = *(u16 *)(a0 + 0x6); + *(s16 *)(in + 0) = ang; + *(s16 *)(in + 2) = *(u16 *)(a0 + 0xA); + *(s16 *)(in + 4) = *(u16 *)(a0 + 0xE); + m = D_800AE620; + RotMatrixY(arg, &m); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x12); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0x16); + *(s16 *)(out + 4) = *(u16 *)(a0 + 0x1A); + ApplyMatrixSV(&m, &out[0], &out[0]); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x6) + ((s16)*(u16 *)(out + 0) >> 1); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0xA) + ((s16)*(u16 *)(out + 2) >> 1); + *(s16 *)(out + 4) = *(u16 *)(a0 + 0xE) + ((s16)*(u16 *)(out + 4) >> 1); + if ((func_8012CEB0((s32)&in[0], (s32)&out[0], 0) & 0x2000) != 0) { + *(s16 *)(a0 + 0x6) = *(u16 *)(out + 0); + *(s16 *)(a0 + 0xA) = *(u16 *)(out + 2); + *(s16 *)(a0 + 0xE) = *(u16 *)(out + 4); + } + } +} + extern int func_80178970(void); 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 665f424fb..214b016f8 100644 --- a/src/ov_SC03_028/ov_SC03_028_jr_8017AE2C.c +++ b/src/ov_SC03_028/ov_SC03_028_jr_8017AE2C.c @@ -4341,7 +4341,81 @@ void func_8017D294(s16 *a0) { } -INCLUDE_ASM("asm/ov_SC03_028/nonmatchings/ov_SC03_028_jr_8017AE2C", func_8017D370); + + +/* func_8017D370 -- ov_SC02_011 / ov_SC02_011_jr_8017AE2C [target: 133 ins] + * + * Structural twin of func_8017D0BC (ov_SC03_002/ov_SC03_002_jr_8017AE2C.c), + * banked [MATCH, 133 ins] this session -- same jr_8017AE2C shared layout, + * identical struct-offset chain (a0+0x6/0xA/0xE/0x10/0x12/0x16/0x18/0x1A) and + * identical call sequence (func_80133784 -> ratan2 x2 -> angle-wrap -> + * RotMatrixY -> ApplyMatrixSV -> func_8012CEB0). Reused verbatim per §136c + * sibling-first (declaration + expression forms are already byte-proven for + * this exact body). + * + * §136 L1/RC-5 note carried from the twin: `ang` (second ratan2 result) is a + * GLOBAL allocno spanning the +/-0x480 arms, while the `ang - base` compare + * temp is a LOCAL allocno in the same block; unpinned gcc hands the local + * temp $v0 and pushes `ang` to $v1 (REGALLOC-PERM). Pinning `ang` to $v0 + * fixes the swap, and reusing the now-dead `ang` as the a0[0x6] scratch + * (instead of a fresh local) avoids stealing back the $v0 slot. + */ + +typedef struct { s32 w[8]; } Mtx8_8017DE10_8017D370; + +void func_8017D370(s32 a0) { + extern void ApplyMatrixSV(void *a0, void *a1, void *a2); + extern s32 ratan2(s32 a0, s32 a1); + extern s16 D_801152B0; + extern s16 D_801152B4; + extern s32 func_80133784(s32 a0, void *a1, s32 a2); + extern s32 func_8012CEB0(s32 a0, s32 a1, s32 a2); + extern void RotMatrixY(s32 a0, void *a1); + extern Mtx8_8017DE10_8017D370 D_800AE620; + + u8 in[8]; + u8 out[8]; + Mtx8_8017DE10_8017D370 m; + s32 base; + register s32 ang __asm__("$2"); + s16 arg; + + *(s16 *)(in + 0) = *(u16 *)(a0 + 0x6) + *(u16 *)(a0 + 0x12); + *(s16 *)(in + 2) = *(u16 *)(a0 + 0xA) + 8; + *(s16 *)(in + 4) = *(u16 *)(a0 + 0xE) + *(u16 *)(a0 + 0x1A); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x6); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0xA) + 8; + *(s16 *)(out + 4) = *(u16 *)(a0 + 0xE); + if ((func_80133784(1, &in[0], (s32)&out[0]) & 0xC000) != 0) { + base = ratan2(D_801152B0, D_801152B4) & 0xFFF; + ang = ratan2(*(s32 *)(a0 + 0x10), *(s32 *)(a0 + 0x18)) & 0xFFF; + if ((s16)(ang - base) < 0) { + ang += 0x480; + } else { + ang -= 0x480; + } + arg = base - ang; + ang = *(u16 *)(a0 + 0x6); + *(s16 *)(in + 0) = ang; + *(s16 *)(in + 2) = *(u16 *)(a0 + 0xA); + *(s16 *)(in + 4) = *(u16 *)(a0 + 0xE); + m = D_800AE620; + RotMatrixY(arg, &m); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x12); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0x16); + *(s16 *)(out + 4) = *(u16 *)(a0 + 0x1A); + ApplyMatrixSV(&m, &out[0], &out[0]); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x6) + ((s16)*(u16 *)(out + 0) >> 1); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0xA) + ((s16)*(u16 *)(out + 2) >> 1); + *(s16 *)(out + 4) = *(u16 *)(a0 + 0xE) + ((s16)*(u16 *)(out + 4) >> 1); + if ((func_8012CEB0((s32)&in[0], (s32)&out[0], 0) & 0x2000) != 0) { + *(s16 *)(a0 + 0x6) = *(u16 *)(out + 0); + *(s16 *)(a0 + 0xA) = *(u16 *)(out + 2); + *(s16 *)(a0 + 0xE) = *(u16 *)(out + 4); + } + } +} + extern int func_80178970(void); diff --git a/src/ov_SC03_089/ov_SC03_089_jr_8017CA80.c b/src/ov_SC03_089/ov_SC03_089_jr_8017CA80.c index 576a6764e..af5824cc5 100644 --- a/src/ov_SC03_089/ov_SC03_089_jr_8017CA80.c +++ b/src/ov_SC03_089/ov_SC03_089_jr_8017CA80.c @@ -7477,9 +7477,383 @@ INCLUDE_ASM("asm/ov_SC03_089/nonmatchings/ov_SC03_089_jr_8017CA80", func_801886B INCLUDE_ASM("asm/ov_SC03_089/nonmatchings/ov_SC03_089_jr_8017CA80", func_8018879C); -INCLUDE_ASM("asm/ov_SC03_089/nonmatchings/ov_SC03_089_jr_8017CA80", func_801887E8); +#include "common.h" + +/* func_801887E8 -- ov_SC03_089, TU src/ov_SC03_089/ov_SC03_089_jr_8017CA80.c + * + * This is the SAME routine (family of 10) as the already-BANKED + * func_80182FD4 in src/ov_SC02_028/ov_SC02_028_jr_8017D898.c -- identical + * shape confirmed instruction-for-instruction against the target .s: + * - offset 0x20: source point-offset table pointer (Src->pt[12], stride 4, + * u16 vx,vy each, table starts at +0x10 within the struct) + * - offset 0x2E/0x30/0x32: base position (u16 vx,vy,vz) + * - offset 0x34: dispatch func_8001E094()/func_8001E378(a0) + * - single-point gte_ldv0/rtps/stsxy(&buf[0]) + gte_stflg + gte_stszotz + * - flag & ~0x1000 early-out + * - offset 0x2C: w; z = otz+1, adjusted by (w&0xC000) 0x4000/0x8000/0xC000 + * cases, clamped >=0, early-out if z>=0x1000 + * - offset 0x1E bit 0x8000: two different traversal orders over pt[], + * both ending in a call taking (a0, a1, &buf[0], ot [+z]). + * Only the callee at the very end differs (func_80188C04 here vs + * func_801833F0 there) and the per-overlay local type names. + */ + +void func_801887E8(void *a0, void *a1) +{ + typedef struct { u16 vx, vy; } Pt2_801887E8; + typedef struct { u8 pad[0x10]; Pt2_801887E8 pt[12]; } Src_801887E8; + typedef struct { u16 vx, vy, vz, pad; } Vec8_801887E8; + + extern void func_8001E094(void); + extern void func_8001E378(void *a0); + extern void func_80188C04(void *a0, void *a1, u32 *a2, u32 *a3); + extern u8 D_800A6610[]; + extern short D_800B9A02; + + Vec8_801887E8 base; + Vec8_801887E8 v[3]; + u32 buf[19]; + long flag; + long otz; + long flag2; + + Src_801887E8 *s; + u32 *ot; + s32 z; + s32 i; + u16 w; + +#define gte_ldv0(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 )" \ + : \ + : "r"( r0 ) ) + +#define gte_ldv3(r0, r1, r2) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 );" \ + "lwc2 $2, 0( %1 );" \ + "lwc2 $3, 4( %1 );" \ + "lwc2 $4, 0( %2 );" \ + "lwc2 $5, 4( %2 )" \ + : \ + : "r"( r0 ), "r"( r1 ), "r"( r2 ) ) + +#define gte_rtps() __asm__ volatile ("nop;nop;rtps") +#define gte_rtpt() __asm__ volatile ("nop;nop;rtpt") + +#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_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" ) + + ot = (u32 *)&D_800A6610[(*(u16 *)&D_800B9A02) << 14]; + s = *(Src_801887E8 **)((s32)a0 + 0x20); + if (s == 0) { + return; + } + + if (*(s32 *)((s32)a0 + 0x34) != 0) { + func_8001E094(); + } else { + func_8001E378(a0); + } + + base.vx = *(u16 *)((s32)a0 + 0x2E); + base.vy = *(u16 *)((s32)a0 + 0x30); + base.vz = *(u16 *)((s32)a0 + 0x32); + + gte_ldv0(&base); + gte_rtps(); + gte_stsxy(&buf[0]); + gte_stflg(&flag); + gte_stszotz(&otz); + + if (flag & ~0x1000) { + return; + } + + w = *(u16 *)((s32)a0 + 0x2C); + z = otz + 1; + if ((w & 0xC000) != 0) { + if ((w & 0xC000) == 0xC000) { + z -= (w & 0xFFF); + if (z < 0) { + z = 0; + } + } else { + z += (w & 0xFFF); + } + } + if (z >= 0x1000) { + return; + } + + if (*(s16 *)((s32)a0 + 0x1E) & 0x8000) { + for (i = 0; i < 12; i += 6) { + v[0].vx = base.vx + s->pt[i].vx; + v[0].vy = base.vy + s->pt[i].vy; + v[0].vz = base.vz; + v[1].vx = base.vx + s->pt[i + 2].vx; + v[1].vy = base.vy + s->pt[i + 2].vy; + v[1].vz = base.vz; + v[2].vx = base.vx + s->pt[i + 4].vx; + v[2].vy = base.vy + s->pt[i + 4].vy; + v[2].vz = base.vz; + gte_ldv3(&v[0], &v[1], &v[2]); + gte_rtpt(); + gte_stsxy3(&buf[i + 1], &buf[i + 3], &buf[i + 5]); + } + for (i = 1; i < 12; i += 2) { + v[0].vx = base.vx + s->pt[i].vx; + v[0].vy = base.vy + s->pt[i].vy; + v[0].vz = base.vz; + gte_ldv0(&v[0]); + gte_rtps(); + gte_stsxy(&buf[i + 1]); + gte_stflg(&flag2); + gte_stszotz(&otz); + buf[13 + (i >> 1)] = otz + 1; + } + func_80188C04(a0, a1, &buf[0], ot); + } else { + for (i = 0; i < 12; i += 3) { + v[0].vx = base.vx + s->pt[i].vx; + v[0].vy = base.vy + s->pt[i].vy; + v[0].vz = base.vz; + v[1].vx = base.vx + s->pt[i + 1].vx; + v[1].vy = base.vy + s->pt[i + 1].vy; + v[1].vz = base.vz; + v[2].vx = base.vx + s->pt[i + 2].vx; + v[2].vy = base.vy + s->pt[i + 2].vy; + v[2].vz = base.vz; + gte_ldv3(&v[0], &v[1], &v[2]); + gte_rtpt(); + gte_stsxy3(&buf[i + 1], &buf[i + 2], &buf[i + 3]); + } + func_80188C04(a0, a1, &buf[0], ot + z); + } +} + + +/* func_80188C04 - ov_SC03_089 (328 ins, frame 0x38, leaf, 10-member family). + * + * §136c SIBLING-FIRST: this is a BYTE-IDENTICAL clone of the already-banked + * func_801833F0 in src/ov_SC02_028/ov_SC02_028_jr_8017D898.c:4441. + * diff of the two nonmatchings .s files (addresses/encodings stripped) is + * EMPTY - verified against asm/ov_SC03_090/.../func_8018B028.s, the same + * family template. So the banked body is reused VERBATIM, only the + * file-local type/macro suffixes renamed to _80188C04. + * + * DECLARATION SURFACE (whole-TU one-pass grep, D2): + * - src/ov_SC03_089/ov_SC03_089_jr_8017CA80.c has NO prototype and NO call + * for func_80188C04 (only the INCLUDE_ASM at :7482). `D_80188C04` hits + * elsewhere in src/ are a DIFFERENT symbol in other overlays. + * - `extern u8 *D_800A5E60;` is function-scope here, identical in shape to + * the TU's own function-scope decls at :2815 and :3431. + * - The TU expands ZERO DEFINE_func_*()/DEFINE_data_*() macros from + * engine_core.h (noted in-file at :5728), and engine_core.h contains no + * PTag_/Ft4_/Drm_/SR3_/ADDPRIM_ names at all - no type/macro collision, + * no repeated-typedef / repeated bare-struct-tag C89 error. + * + * The levers that make this body byte-true are documented in full on the + * banked twin (giv record order, the 1-unit allocno priority flip closed by + * the trailing zero-byte dead read on `vtx`, the two real dead computations, + * the volatile OT index that preserves the q biv, the uu/vv split copies). + * They are reproduced here unchanged; the trailing + * __asm__ __volatile__("" ::"r"(vtx)); + * placement is load-bearing - do not move it. + */ +#include "common.h" + +typedef struct { + u32 addr : 24; + u32 len : 8; +} PTag_80188C04; + +typedef struct { + PTag_80188C04 tag; + u8 r0, g0, b0, code; + u16 x0, y0; + u8 u0, v0; + u16 clut; + u16 x1, y1; + u8 u1, v1; + u16 tpage; + u16 x2, y2; + u8 u2, v2; + u16 pad2; + u16 x3, y3; + u8 u3, v3; + u16 pad3; +} Ft4_80188C04; + +typedef struct { + PTag_80188C04 tag; + u32 code0; +} Drm_80188C04; + +#define ADDPRIM_80188C04(o, p) \ + (((PTag_80188C04 *)(p))->addr = ((PTag_80188C04 *)(o))->addr, \ + ((PTag_80188C04 *)(o))->addr = (u32)(p)) + +/* lhu / sll 16 / sra 19 : signed 13-bit field held at bit 3 of a u16 */ +#define SR3_80188C04(a) (((s32)(*(u16 *)(a) << 16)) >> 19) + +void func_80188C04(void *ent, void *spr, u32 *q, u32 *ot) +{ + extern u8 *D_800A5E60; + register s32 zr __asm__("$0"); + + Ft4_80188C04 *poly; + Drm_80188C04 *dm; + s32 vtx; + u32 flags; + s32 tp, abr, code, shift; + u16 x; + u32 y; + s32 tpage, clut, cy; + s32 su, sv, uu, vv; + u16 fl; + s32 i, m; + u32 b; + + poly = (Ft4_80188C04 *)D_800A5E60; + fl = *(u16 *)((s32)ent + 0x1E) & 0x8000; + flags = *(u32 *)((s32)ent + 4); + tp = (flags >> 24) & 3; + shift = 2 - tp; + x = *(u16 *)((s32)ent + 0x28) + (*(s16 *)((s32)spr + 4) >> shift); + y = *(u16 *)((s32)ent + 0x2A) + *(u16 *)((s32)spr + 6); + vtx = *(s32 *)((s32)ent + 0x20); + D_800A5E60 += 0xF0; + if (flags & 0x40000000) { + code = 0x2E; + abr = (flags >> 28) & 3; + } else { + code = 0x2C; + abr = 1; + } + tpage = (tp << 7) | (abr << 5) | ((y & 0x100) >> 4) | ((x & 0x3C0) >> 6) | + ((y & 0x200) << 2); + b = *(u8 *)((s32)ent + 0x27); + cy = (b + 0x100) << 6; + if (b < 0xE0) { + clut = cy | 0x16; + } else { + clut = cy | 0x10; + } + { + s32 t = ((x - ((tpage & 0xF) << 6)) << shift) + + (*(u16 *)((s32)spr + 4) & ((1 << shift) - 1)); + su = t + zr; + __asm__ __volatile__("" ::"r"(t + *(u8 *)((s32)spr + 2) - 1)); + __asm__ __volatile__("" ::"r"(t)); + } + y = y & 0xFFFF; + if (tpage & 0x10) { + sv = y - 0x100; + } else { + sv = y + zr; + } + __asm__ __volatile__("" ::"r"(sv + *(u8 *)((s32)spr + 3) - 1)); + + i = 1; + uu = su; + vv = sv; + for (; i < 13; i += 2, poly++) { + s32 k = (i - 1) * 4; + __asm__ __volatile__("" ::"r"(i)); + poly->tag.len = 9; + poly->code = code; + poly->tpage = tpage; + poly->u2 = su; + poly->v2 = sv; + poly->u0 = SR3_80188C04(vtx + k + 0x10) + uu; + poly->v0 = SR3_80188C04(vtx + k + 0x12) + vv; + poly->u1 = SR3_80188C04(vtx + i * 4 + 0x10) + uu; + poly->v1 = SR3_80188C04(vtx + i * 4 + 0x12) + vv; + /* k2 is recorded as a giv HERE, AFTER the u1/v1 mem giv. */ + { + s32 k2 = (i + 1) * 4; + poly->u3 = SR3_80188C04(vtx + k2 + 0x10) + uu; + poly->v3 = SR3_80188C04(vtx + k2 + 0x12) + vv; + } + poly->clut = clut; + __asm__ __volatile__("" ::"r"(i), "r"(i)); + poly->r0 = *(u8 *)((s32)ent + 0x24); + poly->g0 = *(u8 *)((s32)ent + 0x25); + poly->b0 = *(u8 *)((s32)ent + 0x26); + poly->x0 = ((u16 *)q)[i * 2]; + poly->y0 = ((u16 *)q)[i * 2 + 1]; + poly->x1 = ((u16 *)q)[i * 2 + 2]; + poly->y1 = ((u16 *)q)[i * 2 + 3]; + poly->x2 = ((u16 *)q)[0]; + poly->y2 = ((u16 *)q)[1]; + poly->x3 = ((u16 *)q)[i * 2 + 4]; + poly->y3 = ((u16 *)q)[i * 2 + 5]; + if (fl != 0) { + ADDPRIM_80188C04(&ot[*(s32 *)((s32)q + 0x34 + (i >> 1) * 4)], poly); + } else { + ADDPRIM_80188C04(ot, poly); + } + } + poly[-1].x3 = ((u16 *)q)[2]; + poly[-1].y3 = ((u16 *)q)[3]; + poly[-1].u3 = su + SR3_80188C04(vtx + 0x10); + poly[-1].v3 = sv + SR3_80188C04(vtx + 0x12); + + if (flags & 0x40000000) { + dm = (Drm_80188C04 *)poly; + if (fl != 0) { + m = 0; + D_800A5E60 += 0x30; + do { + m++; + dm->tag.len = 1; + dm->code0 = (abr << 5) | 0xE100000A; + ADDPRIM_80188C04(&ot[*(volatile s32 *)((s32)q + 0x34)], dm); + q = (u32 *)((s32)q + 4); + dm++; + } while (m < 6); + } else { + dm->code0 = (abr << 5) | 0xE100000A; + D_800A5E60 += 8; + dm->tag.len = 1; + ADDPRIM_80188C04(ot, dm); + /* Zero-byte live-range stretch: puts vtx's allocno priority inside + * the only admissible window. Placement is load-bearing. */ + __asm__ __volatile__("" ::"r"(vtx)); + } + } +} -INCLUDE_ASM("asm/ov_SC03_089/nonmatchings/ov_SC03_089_jr_8017CA80", func_80188C04); void func_80189124(void) { } diff --git a/src/ov_SC03_111/ov_SC03_111_jr_8017AE2C.c b/src/ov_SC03_111/ov_SC03_111_jr_8017AE2C.c index 3aed9b4df..03524beb2 100644 --- a/src/ov_SC03_111/ov_SC03_111_jr_8017AE2C.c +++ b/src/ov_SC03_111/ov_SC03_111_jr_8017AE2C.c @@ -3857,7 +3857,81 @@ void func_8017C880(s16 *a0) { } -INCLUDE_ASM("asm/ov_SC03_111/nonmatchings/ov_SC03_111_jr_8017AE2C", func_8017C95C); + + +/* func_8017C95C -- ov_SC02_011 / ov_SC02_011_jr_8017AE2C [target: 133 ins] + * + * Structural twin of func_8017D0BC (ov_SC03_002/ov_SC03_002_jr_8017AE2C.c), + * banked [MATCH, 133 ins] this session -- same jr_8017AE2C shared layout, + * identical struct-offset chain (a0+0x6/0xA/0xE/0x10/0x12/0x16/0x18/0x1A) and + * identical call sequence (func_80133784 -> ratan2 x2 -> angle-wrap -> + * RotMatrixY -> ApplyMatrixSV -> func_8012CEB0). Reused verbatim per §136c + * sibling-first (declaration + expression forms are already byte-proven for + * this exact body). + * + * §136 L1/RC-5 note carried from the twin: `ang` (second ratan2 result) is a + * GLOBAL allocno spanning the +/-0x480 arms, while the `ang - base` compare + * temp is a LOCAL allocno in the same block; unpinned gcc hands the local + * temp $v0 and pushes `ang` to $v1 (REGALLOC-PERM). Pinning `ang` to $v0 + * fixes the swap, and reusing the now-dead `ang` as the a0[0x6] scratch + * (instead of a fresh local) avoids stealing back the $v0 slot. + */ + +typedef struct { s32 w[8]; } Mtx8_8017DE10_8017C95C; + +void func_8017C95C(s32 a0) { + extern void ApplyMatrixSV(void *a0, void *a1, void *a2); + extern s32 ratan2(s32 a0, s32 a1); + extern s16 D_801152B0; + extern s16 D_801152B4; + extern s32 func_80133784(s32 a0, void *a1, s32 a2); + extern s32 func_8012CEB0(s32 a0, s32 a1, s32 a2); + extern void RotMatrixY(s32 a0, void *a1); + extern Mtx8_8017DE10_8017C95C D_800AE620; + + u8 in[8]; + u8 out[8]; + Mtx8_8017DE10_8017C95C m; + s32 base; + register s32 ang __asm__("$2"); + s16 arg; + + *(s16 *)(in + 0) = *(u16 *)(a0 + 0x6) + *(u16 *)(a0 + 0x12); + *(s16 *)(in + 2) = *(u16 *)(a0 + 0xA) + 8; + *(s16 *)(in + 4) = *(u16 *)(a0 + 0xE) + *(u16 *)(a0 + 0x1A); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x6); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0xA) + 8; + *(s16 *)(out + 4) = *(u16 *)(a0 + 0xE); + if ((func_80133784(1, &in[0], (s32)&out[0]) & 0xC000) != 0) { + base = ratan2(D_801152B0, D_801152B4) & 0xFFF; + ang = ratan2(*(s32 *)(a0 + 0x10), *(s32 *)(a0 + 0x18)) & 0xFFF; + if ((s16)(ang - base) < 0) { + ang += 0x480; + } else { + ang -= 0x480; + } + arg = base - ang; + ang = *(u16 *)(a0 + 0x6); + *(s16 *)(in + 0) = ang; + *(s16 *)(in + 2) = *(u16 *)(a0 + 0xA); + *(s16 *)(in + 4) = *(u16 *)(a0 + 0xE); + m = D_800AE620; + RotMatrixY(arg, &m); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x12); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0x16); + *(s16 *)(out + 4) = *(u16 *)(a0 + 0x1A); + ApplyMatrixSV(&m, &out[0], &out[0]); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x6) + ((s16)*(u16 *)(out + 0) >> 1); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0xA) + ((s16)*(u16 *)(out + 2) >> 1); + *(s16 *)(out + 4) = *(u16 *)(a0 + 0xE) + ((s16)*(u16 *)(out + 4) >> 1); + if ((func_8012CEB0((s32)&in[0], (s32)&out[0], 0) & 0x2000) != 0) { + *(s16 *)(a0 + 0x6) = *(u16 *)(out + 0); + *(s16 *)(a0 + 0xA) = *(u16 *)(out + 2); + *(s16 *)(a0 + 0xE) = *(u16 *)(out + 4); + } + } +} + extern int func_80178970(void); 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 6dadf7aa7..0bacf4808 100644 --- a/src/ov_SC03_113/ov_SC03_113_jr_8017C294.c +++ b/src/ov_SC03_113/ov_SC03_113_jr_8017C294.c @@ -4140,7 +4140,81 @@ void func_8017E79C(s16 *a0) { } -INCLUDE_ASM("asm/ov_SC03_113/nonmatchings/ov_SC03_113_jr_8017C294", func_8017E878); + + +/* func_8017E878 -- ov_SC02_011 / ov_SC02_011_jr_8017AE2C [target: 133 ins] + * + * Structural twin of func_8017D0BC (ov_SC03_002/ov_SC03_002_jr_8017AE2C.c), + * banked [MATCH, 133 ins] this session -- same jr_8017AE2C shared layout, + * identical struct-offset chain (a0+0x6/0xA/0xE/0x10/0x12/0x16/0x18/0x1A) and + * identical call sequence (func_80133784 -> ratan2 x2 -> angle-wrap -> + * RotMatrixY -> ApplyMatrixSV -> func_8012CEB0). Reused verbatim per §136c + * sibling-first (declaration + expression forms are already byte-proven for + * this exact body). + * + * §136 L1/RC-5 note carried from the twin: `ang` (second ratan2 result) is a + * GLOBAL allocno spanning the +/-0x480 arms, while the `ang - base` compare + * temp is a LOCAL allocno in the same block; unpinned gcc hands the local + * temp $v0 and pushes `ang` to $v1 (REGALLOC-PERM). Pinning `ang` to $v0 + * fixes the swap, and reusing the now-dead `ang` as the a0[0x6] scratch + * (instead of a fresh local) avoids stealing back the $v0 slot. + */ + +typedef struct { s32 w[8]; } Mtx8_8017DE10_8017E878; + +void func_8017E878(s32 a0) { + extern void ApplyMatrixSV(void *a0, void *a1, void *a2); + extern s32 ratan2(s32 a0, s32 a1); + extern s16 D_801152B0; + extern s16 D_801152B4; + extern s32 func_80133784(s32 a0, void *a1, s32 a2); + extern s32 func_8012CEB0(s32 a0, s32 a1, s32 a2); + extern void RotMatrixY(s32 a0, void *a1); + extern Mtx8_8017DE10_8017E878 D_800AE620; + + u8 in[8]; + u8 out[8]; + Mtx8_8017DE10_8017E878 m; + s32 base; + register s32 ang __asm__("$2"); + s16 arg; + + *(s16 *)(in + 0) = *(u16 *)(a0 + 0x6) + *(u16 *)(a0 + 0x12); + *(s16 *)(in + 2) = *(u16 *)(a0 + 0xA) + 8; + *(s16 *)(in + 4) = *(u16 *)(a0 + 0xE) + *(u16 *)(a0 + 0x1A); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x6); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0xA) + 8; + *(s16 *)(out + 4) = *(u16 *)(a0 + 0xE); + if ((func_80133784(1, &in[0], (s32)&out[0]) & 0xC000) != 0) { + base = ratan2(D_801152B0, D_801152B4) & 0xFFF; + ang = ratan2(*(s32 *)(a0 + 0x10), *(s32 *)(a0 + 0x18)) & 0xFFF; + if ((s16)(ang - base) < 0) { + ang += 0x480; + } else { + ang -= 0x480; + } + arg = base - ang; + ang = *(u16 *)(a0 + 0x6); + *(s16 *)(in + 0) = ang; + *(s16 *)(in + 2) = *(u16 *)(a0 + 0xA); + *(s16 *)(in + 4) = *(u16 *)(a0 + 0xE); + m = D_800AE620; + RotMatrixY(arg, &m); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x12); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0x16); + *(s16 *)(out + 4) = *(u16 *)(a0 + 0x1A); + ApplyMatrixSV(&m, &out[0], &out[0]); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x6) + ((s16)*(u16 *)(out + 0) >> 1); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0xA) + ((s16)*(u16 *)(out + 2) >> 1); + *(s16 *)(out + 4) = *(u16 *)(a0 + 0xE) + ((s16)*(u16 *)(out + 4) >> 1); + if ((func_8012CEB0((s32)&in[0], (s32)&out[0], 0) & 0x2000) != 0) { + *(s16 *)(a0 + 0x6) = *(u16 *)(out + 0); + *(s16 *)(a0 + 0xA) = *(u16 *)(out + 2); + *(s16 *)(a0 + 0xE) = *(u16 *)(out + 4); + } + } +} + extern int func_80178970(void); 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 0b83b270c..6fc133cd0 100644 --- a/src/ov_SC03_114/ov_SC03_114_jr_8017BEBC.c +++ b/src/ov_SC03_114/ov_SC03_114_jr_8017BEBC.c @@ -3420,7 +3420,264 @@ void func_8017E170(void *a0) { INCLUDE_ASM("asm/ov_SC03_114/nonmatchings/ov_SC03_114_jr_8017BEBC", func_8017E270); -INCLUDE_ASM("asm/ov_SC03_114/nonmatchings/ov_SC03_114_jr_8017BEBC", func_8017E2EC); +/* func_8017E2EC — ov_SC03_114 (296 ins, match_one MATCH). + * + * Billboard sprite: RTPS the entity origin through the global matrix D_800AF648, + * cull on the GTE flag + OT index range, build a Z-rotated 2D basis with + * RotMatrixZ, RTPS the +0x20 corner offset, emit TWO POLY_F4 packets out of the + * D_800A5E60 bump allocator, addPrim() both into the OT slot, and (when + * flags & 0x40000000) append a third 8-byte DR_MODE (0xE1......) packet. + * + * LEVERS (each byte-checked against asm/.../func_8017E2EC.s) + * §135-4 MATRIX init is written in NATURAL row order (m00,m01,m02,m10,m11,...). + * The `lhu 0x18($s1)` loads are register-based and therefore ordered + * against EVERY $sp store (sched.md §14), so the 2nd load's source + * position is what fixes the whole 16-insn window; the two `sh` stores + * it feeds then sink on their own. Writing m11 last (to mimic the asm's + * store order) pins the 2nd load past all the stores = 15 mismatches. + * §135-4 `D_800A5E60 = p2;` must be written BEFORE the last `addPrim` half — + * the two stores are disambiguated (/s + symbol vs register base), so + * SOURCE order decides, and it is what puts `sw $v0,0($a2)` in the + * `beqz $t2` delay slot instead of a stolen `addiu $v0,$a1,0x38`. + * §137/S2 THE TAG TEMPS. Each `getaddr` read (`lw 0x0($a1)` / `0x18($a1)` / + * `0x30($a1)`) is a single-set pseudo => sched1's BIRTHING BOOST sinks + * it to just before its `and`, costing the 4th filler slot in the + * vertex-store window (nop at idx 221, +1 insn). Binding them to ONE + * reused local kills the boost (REG_N_SETS>1) and the loads take their + * target positions — but a 2-death local is REFUSED by local-alloc + * (local-alloc.c:472 needs reg_n_deaths==1), so it becomes a GLOBAL + * allocno and loses the low register ($a0 instead of $v1, and the `and` + * can no longer coalesce destructively). The two `register` pins + * restore exactly the target's dispositions; both are load-bearing + * (pin-trim: drop $a0 => 34 mismatches, drop $v1 => 6, drop both => 24). + * S2 `pkt` must be SINGLE-SET: the 2nd `D_800A5E60` read goes to its own + * local `pkb`, which boosts `lw $a1,D_800A5E60` and wins the pri-1 tie + * against `lhu 0x66($sp)` at idx 124. That tie is INVARIANT under every + * statement permutation (8 probed) — the lever is the boost, not LUID. + * §135-1 `idx` is u32 (unsigned compare `sltiu`); the sign test is the + * explicit `(s32)idx < 0` that emits `bgez`. + * T-form `otp = (u32 *)((idx << 2) + ot)` — index FIRST, giving + * `addu $a2,$v0,$s4`; `ot + (idx << 2)` emits the operands reversed. + * + * DECLARATIONS: the TU already defines gte_ldv0/gte_rtps/gte_stsxy/gte_stflg/ + * gte_stszotz at file scope (L2697-2806) — reproduced here VERBATIM so the + * redefinition is identical (C89 legal, no diagnostic). gte_SetRotMatrix, + * gte_SetTransMatrix, gte_stsz, RD16 and RW32 appear nowhere under src/. + * D_800B9A02 is spelled `short` exactly as the TU's file-scope L2468 and + * func_8017BEBC's L2822 do; D_800AF648, D_800A5E60, D_800A6610 and RotMatrixZ + * have no file-scope decl in this TU (engine_core.h carries D_800AF648 / + * D_800B9A02 only inside DEFINE_func macro BODIES, i.e. block scope), so each is + * block-scoped here to keep the blast radius on the rest of the TU at zero + * (§103/T51, the func_80185944 precedent). + */ + +#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" ) + +#define gte_ldv0(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 )" \ + : \ + : "r"( r0 ) ) + +#define gte_rtps() __asm__ volatile ("nop;nop;rtps") + +#define gte_stsxy(r0) __asm__ volatile ( \ + "swc2 $14, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#define gte_stsz(r0) __asm__ volatile ( \ + "swc2 $19, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) + +#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 RD16(p) (((struct { u16 v; } *)(p))->v) +#define RW32(p) (((struct { u32 v; } *)(p))->v) + +void func_8017E2EC(void *a0) +{ + extern u8 D_800AF648; + extern u8 *D_800A5E60; + extern u8 D_800A6610[]; + extern short D_800B9A02; + extern void RotMatrixZ(s32 a0, void *a1); + + u8 stk[0x60]; /* sp+0x10 .. sp+0x6F */ + u32 flags; + u32 idx; + u32 ot; + u32 t2; + u8 *pkt; + u8 *p1; + u8 *p2; + u8 *pkb; + s32 d; + u32 *otp; + register u32 tv __asm__("$3"); /* §137 pin — see header */ + register u32 tv2 __asm__("$4"); /* §137 pin — see header */ + + u8 *rotm; + + flags = *(u32 *)((s32)a0 + 4); + rotm = &D_800AF648; + + gte_SetRotMatrix(rotm); + gte_SetTransMatrix(rotm); + gte_ldv0((s32)a0 + 8); + gte_rtps(); + gte_stsxy(stk); + gte_stflg(stk + 0x48); + gte_stsz(stk + 0x4c); + gte_stszotz(stk + 0x50); + + if ((*(u32 *)(stk + 0x48) & 0xFFFFEFFF) == 0) { + idx = *(s32 *)(stk + 0x50) + 1; + ot = (u32)&D_800A6610[(*(u16 *)&D_800B9A02) << 14]; + { + u16 flags2 = *(u16 *)((s32)a0 + 0x2c); + if ((flags2 & 0xC000) != 0) { + if ((flags2 & 0xC000) == 0xC000) { + idx = idx - (flags2 & 0xFFF); + if ((s32)idx < 0) idx = 0; + } else { + idx = idx + (flags2 & 0xFFF); + } + } + } + + if (idx < 0x1000) { + d = (s32)&stk[0x08]; + + *(u16 *)(stk + 0x08) = *(u16 *)((s32)a0 + 0x18); + *(u16 *)(stk + 0x0a) = 0; + *(u16 *)(stk + 0x0c) = 0; + *(u16 *)(stk + 0x0e) = 0; + *(u16 *)(stk + 0x10) = *(u16 *)((s32)a0 + 0x18); + *(u16 *)(stk + 0x12) = 0; + *(u16 *)(stk + 0x14) = 0; + *(u16 *)(stk + 0x16) = 0; + *(u16 *)(stk + 0x18) = 0x1000; + *(u32 *)(stk + 0x24) = 0; + *(u32 *)(stk + 0x20) = 0; + *(u32 *)(stk + 0x1c) = 0; + + RotMatrixZ(*(s16 *)((s32)a0 + 0x14), (void *)d); + gte_SetRotMatrix((void *)d); + gte_SetTransMatrix((void *)d); + + *(u16 *)(stk + 0x28) = 0x20; + *(u16 *)(stk + 0x2a) = 0; + *(s16 *)(stk + 0x2c) = (s16)*(u32 *)(stk + 0x4c); + gte_ldv0(stk + 0x28); + gte_rtps(); + gte_stsxy(stk + 0x54); + + d = (u16)((s16)(RD16(stk + 0x54)) >> 3); + d |= (s32)((s16)(RD16(stk + 0x56)) >> 3) << 16; + + pkt = D_800A5E60; + p1 = pkt + 0x18; + *(u8 *)(pkt + 0x3) = 5; + *(u8 *)(pkt + 0x7) = 0x28; + *(u8 *)(p1 + 0x3) = 5; + t2 = flags & 0x40000000; + *(u8 *)(p1 + 0x7) = 0x28; + if (t2 != 0) { + *(u8 *)(pkt + 0x7) = *(u8 *)(pkt + 0x7) | 2; + *(u8 *)(p1 + 0x7) = *(u8 *)(p1 + 0x7) | 2; + } + *(u8 *)(pkt + 0x4) = *(u8 *)((s32)a0 + 0x24); + *(u8 *)(pkt + 0x5) = *(u8 *)((s32)a0 + 0x25); + *(u8 *)(pkt + 0x6) = *(u8 *)((s32)a0 + 0x26); + *(u8 *)(p1 + 0x4) = *(u8 *)((s32)a0 + 0x24); + *(u8 *)(p1 + 0x5) = *(u8 *)((s32)a0 + 0x25); + *(u8 *)(p1 + 0x6) = *(u8 *)((s32)a0 + 0x26); + + *(s16 *)(pkt + 0x8) = RD16(stk) + RD16(stk + 0x54); + *(s16 *)(pkt + 0xa) = RD16(stk + 0x02) + RD16(stk + 0x56); + *(s16 *)(pkt + 0xc) = RD16(stk) - (d >> 16); + *(s16 *)(pkt + 0xe) = RD16(stk + 0x02) + d; + *(s16 *)(pkt + 0x10) = RD16(stk) + (d >> 16); + *(s16 *)(pkt + 0x12) = RD16(stk + 0x02) - d; + *(s16 *)(pkt + 0x14) = RD16(stk) - RD16(stk + 0x54); + *(s16 *)(pkt + 0x16) = RD16(stk + 0x02) - RD16(stk + 0x56); + *(s16 *)(p1 + 0x8) = RD16(stk) - RD16(stk + 0x56); + *(s16 *)(p1 + 0xa) = RD16(stk + 0x02) + RD16(stk + 0x54); + *(s16 *)(p1 + 0xc) = RD16(stk) - d; + *(s16 *)(p1 + 0xe) = RD16(stk + 0x02) - (d >> 16); + *(s16 *)(p1 + 0x10) = RD16(stk) + d; + *(s16 *)(p1 + 0x12) = RD16(stk + 0x02) + (d >> 16); + *(s16 *)(p1 + 0x14) = RD16(stk) + RD16(stk + 0x56); + *(s16 *)(p1 + 0x16) = RD16(stk + 0x02) - RD16(stk + 0x54); + + /* addPrim(otp, pkt); addPrim(otp, p1); */ + otp = (u32 *)((idx << 2) + ot); + tv = RW32(pkt); + RW32(pkt) = (tv & 0xFF000000) | (RW32(otp) & 0xFFFFFF); + RW32(otp) = (RW32(otp) & 0xFF000000) | ((u32)pkt & 0xFFFFFF); + tv = RW32(p1); + RW32(p1) = (tv & 0xFF000000) | (RW32(otp) & 0xFFFFFF); + + pkb = D_800A5E60; + p2 = pkb + 0x30; + D_800A5E60 = p2; + RW32(otp) = (RW32(otp) & 0xFF000000) | ((u32)p1 & 0xFFFFFF); + + if (t2 != 0) { + D_800A5E60 = pkb + 0x38; + *(u8 *)(p2 + 3) = 1; + RW32(p2 + 4) = ((flags >> 23) & 0x60) | 0xE1000000; + tv2 = RW32(p2); + RW32(p2) = (tv2 & 0xFF000000) | (RW32(otp) & 0xFFFFFF); + RW32(otp) = (RW32(otp) & 0xFF000000) | ((u32)p2 & 0xFFFFFF); + } + } + } +} + // @class: loose-typing diff --git a/src/ov_SC03_118/ov_SC03_118_jr_8017AE2C.c b/src/ov_SC03_118/ov_SC03_118_jr_8017AE2C.c index 2b6f8caff..3e93f3bff 100644 --- a/src/ov_SC03_118/ov_SC03_118_jr_8017AE2C.c +++ b/src/ov_SC03_118/ov_SC03_118_jr_8017AE2C.c @@ -4291,7 +4291,81 @@ void func_8017E948(s16 *a0) { } -INCLUDE_ASM("asm/ov_SC03_118/nonmatchings/ov_SC03_118_jr_8017AE2C", func_8017EA24); + + +/* func_8017EA24 -- ov_SC02_011 / ov_SC02_011_jr_8017AE2C [target: 133 ins] + * + * Structural twin of func_8017D0BC (ov_SC03_002/ov_SC03_002_jr_8017AE2C.c), + * banked [MATCH, 133 ins] this session -- same jr_8017AE2C shared layout, + * identical struct-offset chain (a0+0x6/0xA/0xE/0x10/0x12/0x16/0x18/0x1A) and + * identical call sequence (func_80133784 -> ratan2 x2 -> angle-wrap -> + * RotMatrixY -> ApplyMatrixSV -> func_8012CEB0). Reused verbatim per §136c + * sibling-first (declaration + expression forms are already byte-proven for + * this exact body). + * + * §136 L1/RC-5 note carried from the twin: `ang` (second ratan2 result) is a + * GLOBAL allocno spanning the +/-0x480 arms, while the `ang - base` compare + * temp is a LOCAL allocno in the same block; unpinned gcc hands the local + * temp $v0 and pushes `ang` to $v1 (REGALLOC-PERM). Pinning `ang` to $v0 + * fixes the swap, and reusing the now-dead `ang` as the a0[0x6] scratch + * (instead of a fresh local) avoids stealing back the $v0 slot. + */ + +typedef struct { s32 w[8]; } Mtx8_8017DE10_8017EA24; + +void func_8017EA24(s32 a0) { + extern void ApplyMatrixSV(void *a0, void *a1, void *a2); + extern s32 ratan2(s32 a0, s32 a1); + extern s16 D_801152B0; + extern s16 D_801152B4; + extern s32 func_80133784(s32 a0, void *a1, s32 a2); + extern s32 func_8012CEB0(s32 a0, s32 a1, s32 a2); + extern void RotMatrixY(s32 a0, void *a1); + extern Mtx8_8017DE10_8017EA24 D_800AE620; + + u8 in[8]; + u8 out[8]; + Mtx8_8017DE10_8017EA24 m; + s32 base; + register s32 ang __asm__("$2"); + s16 arg; + + *(s16 *)(in + 0) = *(u16 *)(a0 + 0x6) + *(u16 *)(a0 + 0x12); + *(s16 *)(in + 2) = *(u16 *)(a0 + 0xA) + 8; + *(s16 *)(in + 4) = *(u16 *)(a0 + 0xE) + *(u16 *)(a0 + 0x1A); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x6); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0xA) + 8; + *(s16 *)(out + 4) = *(u16 *)(a0 + 0xE); + if ((func_80133784(1, &in[0], (s32)&out[0]) & 0xC000) != 0) { + base = ratan2(D_801152B0, D_801152B4) & 0xFFF; + ang = ratan2(*(s32 *)(a0 + 0x10), *(s32 *)(a0 + 0x18)) & 0xFFF; + if ((s16)(ang - base) < 0) { + ang += 0x480; + } else { + ang -= 0x480; + } + arg = base - ang; + ang = *(u16 *)(a0 + 0x6); + *(s16 *)(in + 0) = ang; + *(s16 *)(in + 2) = *(u16 *)(a0 + 0xA); + *(s16 *)(in + 4) = *(u16 *)(a0 + 0xE); + m = D_800AE620; + RotMatrixY(arg, &m); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x12); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0x16); + *(s16 *)(out + 4) = *(u16 *)(a0 + 0x1A); + ApplyMatrixSV(&m, &out[0], &out[0]); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x6) + ((s16)*(u16 *)(out + 0) >> 1); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0xA) + ((s16)*(u16 *)(out + 2) >> 1); + *(s16 *)(out + 4) = *(u16 *)(a0 + 0xE) + ((s16)*(u16 *)(out + 4) >> 1); + if ((func_8012CEB0((s32)&in[0], (s32)&out[0], 0) & 0x2000) != 0) { + *(s16 *)(a0 + 0x6) = *(u16 *)(out + 0); + *(s16 *)(a0 + 0xA) = *(u16 *)(out + 2); + *(s16 *)(a0 + 0xE) = *(u16 *)(out + 4); + } + } +} + extern int func_80178970(void); diff --git a/src/ov_SC03_119/ov_SC03_119_jr_8017AE2C.c b/src/ov_SC03_119/ov_SC03_119_jr_8017AE2C.c index 99a5d5340..c0bc5d2fe 100644 --- a/src/ov_SC03_119/ov_SC03_119_jr_8017AE2C.c +++ b/src/ov_SC03_119/ov_SC03_119_jr_8017AE2C.c @@ -4285,7 +4285,81 @@ void func_8017E948(s16 *a0) { } -INCLUDE_ASM("asm/ov_SC03_119/nonmatchings/ov_SC03_119_jr_8017AE2C", func_8017EA24); + + +/* func_8017EA24 -- ov_SC02_011 / ov_SC02_011_jr_8017AE2C [target: 133 ins] + * + * Structural twin of func_8017D0BC (ov_SC03_002/ov_SC03_002_jr_8017AE2C.c), + * banked [MATCH, 133 ins] this session -- same jr_8017AE2C shared layout, + * identical struct-offset chain (a0+0x6/0xA/0xE/0x10/0x12/0x16/0x18/0x1A) and + * identical call sequence (func_80133784 -> ratan2 x2 -> angle-wrap -> + * RotMatrixY -> ApplyMatrixSV -> func_8012CEB0). Reused verbatim per §136c + * sibling-first (declaration + expression forms are already byte-proven for + * this exact body). + * + * §136 L1/RC-5 note carried from the twin: `ang` (second ratan2 result) is a + * GLOBAL allocno spanning the +/-0x480 arms, while the `ang - base` compare + * temp is a LOCAL allocno in the same block; unpinned gcc hands the local + * temp $v0 and pushes `ang` to $v1 (REGALLOC-PERM). Pinning `ang` to $v0 + * fixes the swap, and reusing the now-dead `ang` as the a0[0x6] scratch + * (instead of a fresh local) avoids stealing back the $v0 slot. + */ + +typedef struct { s32 w[8]; } Mtx8_8017DE10_8017EA24; + +void func_8017EA24(s32 a0) { + extern void ApplyMatrixSV(void *a0, void *a1, void *a2); + extern s32 ratan2(s32 a0, s32 a1); + extern s16 D_801152B0; + extern s16 D_801152B4; + extern s32 func_80133784(s32 a0, void *a1, s32 a2); + extern s32 func_8012CEB0(s32 a0, s32 a1, s32 a2); + extern void RotMatrixY(s32 a0, void *a1); + extern Mtx8_8017DE10_8017EA24 D_800AE620; + + u8 in[8]; + u8 out[8]; + Mtx8_8017DE10_8017EA24 m; + s32 base; + register s32 ang __asm__("$2"); + s16 arg; + + *(s16 *)(in + 0) = *(u16 *)(a0 + 0x6) + *(u16 *)(a0 + 0x12); + *(s16 *)(in + 2) = *(u16 *)(a0 + 0xA) + 8; + *(s16 *)(in + 4) = *(u16 *)(a0 + 0xE) + *(u16 *)(a0 + 0x1A); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x6); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0xA) + 8; + *(s16 *)(out + 4) = *(u16 *)(a0 + 0xE); + if ((func_80133784(1, &in[0], (s32)&out[0]) & 0xC000) != 0) { + base = ratan2(D_801152B0, D_801152B4) & 0xFFF; + ang = ratan2(*(s32 *)(a0 + 0x10), *(s32 *)(a0 + 0x18)) & 0xFFF; + if ((s16)(ang - base) < 0) { + ang += 0x480; + } else { + ang -= 0x480; + } + arg = base - ang; + ang = *(u16 *)(a0 + 0x6); + *(s16 *)(in + 0) = ang; + *(s16 *)(in + 2) = *(u16 *)(a0 + 0xA); + *(s16 *)(in + 4) = *(u16 *)(a0 + 0xE); + m = D_800AE620; + RotMatrixY(arg, &m); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x12); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0x16); + *(s16 *)(out + 4) = *(u16 *)(a0 + 0x1A); + ApplyMatrixSV(&m, &out[0], &out[0]); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x6) + ((s16)*(u16 *)(out + 0) >> 1); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0xA) + ((s16)*(u16 *)(out + 2) >> 1); + *(s16 *)(out + 4) = *(u16 *)(a0 + 0xE) + ((s16)*(u16 *)(out + 4) >> 1); + if ((func_8012CEB0((s32)&in[0], (s32)&out[0], 0) & 0x2000) != 0) { + *(s16 *)(a0 + 0x6) = *(u16 *)(out + 0); + *(s16 *)(a0 + 0xA) = *(u16 *)(out + 2); + *(s16 *)(a0 + 0xE) = *(u16 *)(out + 4); + } + } +} + extern int func_80178970(void); diff --git a/src/ov_SC03_125/ov_SC03_125_jr_8017AE2C.c b/src/ov_SC03_125/ov_SC03_125_jr_8017AE2C.c index 8cc7b8a98..9938ce3d7 100644 --- a/src/ov_SC03_125/ov_SC03_125_jr_8017AE2C.c +++ b/src/ov_SC03_125/ov_SC03_125_jr_8017AE2C.c @@ -4245,7 +4245,81 @@ void func_8017CFE0(s16 *a0) { } -INCLUDE_ASM("asm/ov_SC03_125/nonmatchings/ov_SC03_125_jr_8017AE2C", func_8017D0BC); + + +/* func_8017D0BC -- ov_SC02_011 / ov_SC02_011_jr_8017AE2C [target: 133 ins] + * + * Structural twin of func_8017D0BC (ov_SC03_002/ov_SC03_002_jr_8017AE2C.c), + * banked [MATCH, 133 ins] this session -- same jr_8017AE2C shared layout, + * identical struct-offset chain (a0+0x6/0xA/0xE/0x10/0x12/0x16/0x18/0x1A) and + * identical call sequence (func_80133784 -> ratan2 x2 -> angle-wrap -> + * RotMatrixY -> ApplyMatrixSV -> func_8012CEB0). Reused verbatim per §136c + * sibling-first (declaration + expression forms are already byte-proven for + * this exact body). + * + * §136 L1/RC-5 note carried from the twin: `ang` (second ratan2 result) is a + * GLOBAL allocno spanning the +/-0x480 arms, while the `ang - base` compare + * temp is a LOCAL allocno in the same block; unpinned gcc hands the local + * temp $v0 and pushes `ang` to $v1 (REGALLOC-PERM). Pinning `ang` to $v0 + * fixes the swap, and reusing the now-dead `ang` as the a0[0x6] scratch + * (instead of a fresh local) avoids stealing back the $v0 slot. + */ + +typedef struct { s32 w[8]; } Mtx8_8017DE10_8017D0BC; + +void func_8017D0BC(s32 a0) { + extern void ApplyMatrixSV(void *a0, void *a1, void *a2); + extern s32 ratan2(s32 a0, s32 a1); + extern s16 D_801152B0; + extern s16 D_801152B4; + extern s32 func_80133784(s32 a0, void *a1, s32 a2); + extern s32 func_8012CEB0(s32 a0, s32 a1, s32 a2); + extern void RotMatrixY(s32 a0, void *a1); + extern Mtx8_8017DE10_8017D0BC D_800AE620; + + u8 in[8]; + u8 out[8]; + Mtx8_8017DE10_8017D0BC m; + s32 base; + register s32 ang __asm__("$2"); + s16 arg; + + *(s16 *)(in + 0) = *(u16 *)(a0 + 0x6) + *(u16 *)(a0 + 0x12); + *(s16 *)(in + 2) = *(u16 *)(a0 + 0xA) + 8; + *(s16 *)(in + 4) = *(u16 *)(a0 + 0xE) + *(u16 *)(a0 + 0x1A); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x6); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0xA) + 8; + *(s16 *)(out + 4) = *(u16 *)(a0 + 0xE); + if ((func_80133784(1, &in[0], (s32)&out[0]) & 0xC000) != 0) { + base = ratan2(D_801152B0, D_801152B4) & 0xFFF; + ang = ratan2(*(s32 *)(a0 + 0x10), *(s32 *)(a0 + 0x18)) & 0xFFF; + if ((s16)(ang - base) < 0) { + ang += 0x480; + } else { + ang -= 0x480; + } + arg = base - ang; + ang = *(u16 *)(a0 + 0x6); + *(s16 *)(in + 0) = ang; + *(s16 *)(in + 2) = *(u16 *)(a0 + 0xA); + *(s16 *)(in + 4) = *(u16 *)(a0 + 0xE); + m = D_800AE620; + RotMatrixY(arg, &m); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x12); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0x16); + *(s16 *)(out + 4) = *(u16 *)(a0 + 0x1A); + ApplyMatrixSV(&m, &out[0], &out[0]); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x6) + ((s16)*(u16 *)(out + 0) >> 1); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0xA) + ((s16)*(u16 *)(out + 2) >> 1); + *(s16 *)(out + 4) = *(u16 *)(a0 + 0xE) + ((s16)*(u16 *)(out + 4) >> 1); + if ((func_8012CEB0((s32)&in[0], (s32)&out[0], 0) & 0x2000) != 0) { + *(s16 *)(a0 + 0x6) = *(u16 *)(out + 0); + *(s16 *)(a0 + 0xA) = *(u16 *)(out + 2); + *(s16 *)(a0 + 0xE) = *(u16 *)(out + 4); + } + } +} + extern int func_80178970(void); 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 cda5d2a77..c82e7d3cb 100644 --- a/src/ov_SC04_011/ov_SC04_011_jr_8017D494.c +++ b/src/ov_SC04_011/ov_SC04_011_jr_8017D494.c @@ -6010,7 +6010,230 @@ void func_8018EEB0(void *a0) { INCLUDE_ASM("asm/ov_SC04_011/nonmatchings/ov_SC04_011_jr_8017D494", func_8018EFB0); -INCLUDE_ASM("asm/ov_SC04_011/nonmatchings/ov_SC04_011_jr_8017D494", func_8018F02C); +#define gte_ldv0(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 )" \ + : \ + : "r"( r0 ) ) +#define gte_rtps() __asm__ volatile ("nop;nop;rtps") +#define gte_stsxy(r0) __asm__ volatile ( \ + "swc2 $14, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) +#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_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" ) +#define gte_ldv0(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 )" \ + : \ + : "r"( r0 ) ) +#define gte_rtps() __asm__ volatile ("nop;nop;rtps") +#define gte_stsxy(r0) __asm__ volatile ( \ + "swc2 $14, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) +#define gte_stsz(r0) __asm__ volatile ( \ + "swc2 $19, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) +#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 RD16(p) (((struct { u16 v; } *)(p))->v) +#define RW32(p) (((struct { u32 v; } *)(p))->v) + +void func_8018F02C(void *a0) +{ + extern u8 D_800AF648; + extern u8 *D_800A5E60; + extern u8 D_800A6610[]; + extern void RotMatrixZ(s32 a0, void *a1); + + u8 stk[0x60]; /* sp+0x10 .. sp+0x6F */ + u32 flags; + u32 idx; + u32 ot; + u32 t2; + u8 *pkt; + u8 *p1; + u8 *p2; + u8 *pkb; + s32 d; + u32 *otp; + register u32 tv __asm__("$3"); /* §137 pin — see header */ + register u32 tv2 __asm__("$4"); /* §137 pin — see header */ + + u8 *rotm; + + flags = *(u32 *)((s32)a0 + 4); + rotm = &D_800AF648; + + gte_SetRotMatrix(rotm); + gte_SetTransMatrix(rotm); + gte_ldv0((s32)a0 + 8); + gte_rtps(); + gte_stsxy(stk); + gte_stflg(stk + 0x48); + gte_stsz(stk + 0x4c); + gte_stszotz(stk + 0x50); + + if ((*(u32 *)(stk + 0x48) & 0xFFFFEFFF) == 0) { + idx = *(s32 *)(stk + 0x50) + 1; + ot = (u32)&D_800A6610[(*(u16 *)&D_800B9A02) << 14]; + { + u16 flags2 = *(u16 *)((s32)a0 + 0x2c); + if ((flags2 & 0xC000) != 0) { + if ((flags2 & 0xC000) == 0xC000) { + idx = idx - (flags2 & 0xFFF); + if ((s32)idx < 0) idx = 0; + } else { + idx = idx + (flags2 & 0xFFF); + } + } + } + + if (idx < 0x1000) { + d = (s32)&stk[0x08]; + + *(u16 *)(stk + 0x08) = *(u16 *)((s32)a0 + 0x18); + *(u16 *)(stk + 0x0a) = 0; + *(u16 *)(stk + 0x0c) = 0; + *(u16 *)(stk + 0x0e) = 0; + *(u16 *)(stk + 0x10) = *(u16 *)((s32)a0 + 0x18); + *(u16 *)(stk + 0x12) = 0; + *(u16 *)(stk + 0x14) = 0; + *(u16 *)(stk + 0x16) = 0; + *(u16 *)(stk + 0x18) = 0x1000; + *(u32 *)(stk + 0x24) = 0; + *(u32 *)(stk + 0x20) = 0; + *(u32 *)(stk + 0x1c) = 0; + + RotMatrixZ(*(s16 *)((s32)a0 + 0x14), (void *)d); + gte_SetRotMatrix((void *)d); + gte_SetTransMatrix((void *)d); + + *(u16 *)(stk + 0x28) = 0x20; + *(u16 *)(stk + 0x2a) = 0; + *(s16 *)(stk + 0x2c) = (s16)*(u32 *)(stk + 0x4c); + gte_ldv0(stk + 0x28); + gte_rtps(); + gte_stsxy(stk + 0x54); + + d = (u16)((s16)(RD16(stk + 0x54)) >> 3); + d |= (s32)((s16)(RD16(stk + 0x56)) >> 3) << 16; + + pkt = D_800A5E60; + p1 = pkt + 0x18; + *(u8 *)(pkt + 0x3) = 5; + *(u8 *)(pkt + 0x7) = 0x28; + *(u8 *)(p1 + 0x3) = 5; + t2 = flags & 0x40000000; + *(u8 *)(p1 + 0x7) = 0x28; + if (t2 != 0) { + *(u8 *)(pkt + 0x7) = *(u8 *)(pkt + 0x7) | 2; + *(u8 *)(p1 + 0x7) = *(u8 *)(p1 + 0x7) | 2; + } + *(u8 *)(pkt + 0x4) = *(u8 *)((s32)a0 + 0x24); + *(u8 *)(pkt + 0x5) = *(u8 *)((s32)a0 + 0x25); + *(u8 *)(pkt + 0x6) = *(u8 *)((s32)a0 + 0x26); + *(u8 *)(p1 + 0x4) = *(u8 *)((s32)a0 + 0x24); + *(u8 *)(p1 + 0x5) = *(u8 *)((s32)a0 + 0x25); + *(u8 *)(p1 + 0x6) = *(u8 *)((s32)a0 + 0x26); + + *(s16 *)(pkt + 0x8) = RD16(stk) + RD16(stk + 0x54); + *(s16 *)(pkt + 0xa) = RD16(stk + 0x02) + RD16(stk + 0x56); + *(s16 *)(pkt + 0xc) = RD16(stk) - (d >> 16); + *(s16 *)(pkt + 0xe) = RD16(stk + 0x02) + d; + *(s16 *)(pkt + 0x10) = RD16(stk) + (d >> 16); + *(s16 *)(pkt + 0x12) = RD16(stk + 0x02) - d; + *(s16 *)(pkt + 0x14) = RD16(stk) - RD16(stk + 0x54); + *(s16 *)(pkt + 0x16) = RD16(stk + 0x02) - RD16(stk + 0x56); + *(s16 *)(p1 + 0x8) = RD16(stk) - RD16(stk + 0x56); + *(s16 *)(p1 + 0xa) = RD16(stk + 0x02) + RD16(stk + 0x54); + *(s16 *)(p1 + 0xc) = RD16(stk) - d; + *(s16 *)(p1 + 0xe) = RD16(stk + 0x02) - (d >> 16); + *(s16 *)(p1 + 0x10) = RD16(stk) + d; + *(s16 *)(p1 + 0x12) = RD16(stk + 0x02) + (d >> 16); + *(s16 *)(p1 + 0x14) = RD16(stk) + RD16(stk + 0x56); + *(s16 *)(p1 + 0x16) = RD16(stk + 0x02) - RD16(stk + 0x54); + + /* addPrim(otp, pkt); addPrim(otp, p1); */ + otp = (u32 *)((idx << 2) + ot); + tv = RW32(pkt); + RW32(pkt) = (tv & 0xFF000000) | (RW32(otp) & 0xFFFFFF); + RW32(otp) = (RW32(otp) & 0xFF000000) | ((u32)pkt & 0xFFFFFF); + tv = RW32(p1); + RW32(p1) = (tv & 0xFF000000) | (RW32(otp) & 0xFFFFFF); + + pkb = D_800A5E60; + p2 = pkb + 0x30; + D_800A5E60 = p2; + RW32(otp) = (RW32(otp) & 0xFF000000) | ((u32)p1 & 0xFFFFFF); + + if (t2 != 0) { + D_800A5E60 = pkb + 0x38; + *(u8 *)(p2 + 3) = 1; + RW32(p2 + 4) = ((flags >> 23) & 0x60) | 0xE1000000; + tv2 = RW32(p2); + RW32(p2) = (tv2 & 0xFF000000) | (RW32(otp) & 0xFFFFFF); + RW32(otp) = (RW32(otp) & 0xFF000000) | ((u32)p2 & 0xFFFFFF); + } + } + } +} + // @class: loose-typing 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 4f61a9857..359d5300c 100644 --- a/src/ov_SC04_016/ov_SC04_016_jr_8017BEBC.c +++ b/src/ov_SC04_016/ov_SC04_016_jr_8017BEBC.c @@ -3549,7 +3549,230 @@ void func_8017F72C(void *a0) { INCLUDE_ASM("asm/ov_SC04_016/nonmatchings/ov_SC04_016_jr_8017BEBC", func_8017F82C); -INCLUDE_ASM("asm/ov_SC04_016/nonmatchings/ov_SC04_016_jr_8017BEBC", func_8017F8A8); +#define gte_ldv0(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 )" \ + : \ + : "r"( r0 ) ) +#define gte_rtps() __asm__ volatile ("nop;nop;rtps") +#define gte_stsxy(r0) __asm__ volatile ( \ + "swc2 $14, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) +#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_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" ) +#define gte_ldv0(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 )" \ + : \ + : "r"( r0 ) ) +#define gte_rtps() __asm__ volatile ("nop;nop;rtps") +#define gte_stsxy(r0) __asm__ volatile ( \ + "swc2 $14, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) +#define gte_stsz(r0) __asm__ volatile ( \ + "swc2 $19, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) +#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 RD16(p) (((struct { u16 v; } *)(p))->v) +#define RW32(p) (((struct { u32 v; } *)(p))->v) + +void func_8017F8A8(void *a0) +{ + extern u8 D_800AF648; + extern u8 *D_800A5E60; + extern u8 D_800A6610[]; + extern void RotMatrixZ(s32 a0, void *a1); + + u8 stk[0x60]; /* sp+0x10 .. sp+0x6F */ + u32 flags; + u32 idx; + u32 ot; + u32 t2; + u8 *pkt; + u8 *p1; + u8 *p2; + u8 *pkb; + s32 d; + u32 *otp; + register u32 tv __asm__("$3"); /* §137 pin — see header */ + register u32 tv2 __asm__("$4"); /* §137 pin — see header */ + + u8 *rotm; + + flags = *(u32 *)((s32)a0 + 4); + rotm = &D_800AF648; + + gte_SetRotMatrix(rotm); + gte_SetTransMatrix(rotm); + gte_ldv0((s32)a0 + 8); + gte_rtps(); + gte_stsxy(stk); + gte_stflg(stk + 0x48); + gte_stsz(stk + 0x4c); + gte_stszotz(stk + 0x50); + + if ((*(u32 *)(stk + 0x48) & 0xFFFFEFFF) == 0) { + idx = *(s32 *)(stk + 0x50) + 1; + ot = (u32)&D_800A6610[(*(u16 *)&D_800B9A02) << 14]; + { + u16 flags2 = *(u16 *)((s32)a0 + 0x2c); + if ((flags2 & 0xC000) != 0) { + if ((flags2 & 0xC000) == 0xC000) { + idx = idx - (flags2 & 0xFFF); + if ((s32)idx < 0) idx = 0; + } else { + idx = idx + (flags2 & 0xFFF); + } + } + } + + if (idx < 0x1000) { + d = (s32)&stk[0x08]; + + *(u16 *)(stk + 0x08) = *(u16 *)((s32)a0 + 0x18); + *(u16 *)(stk + 0x0a) = 0; + *(u16 *)(stk + 0x0c) = 0; + *(u16 *)(stk + 0x0e) = 0; + *(u16 *)(stk + 0x10) = *(u16 *)((s32)a0 + 0x18); + *(u16 *)(stk + 0x12) = 0; + *(u16 *)(stk + 0x14) = 0; + *(u16 *)(stk + 0x16) = 0; + *(u16 *)(stk + 0x18) = 0x1000; + *(u32 *)(stk + 0x24) = 0; + *(u32 *)(stk + 0x20) = 0; + *(u32 *)(stk + 0x1c) = 0; + + RotMatrixZ(*(s16 *)((s32)a0 + 0x14), (void *)d); + gte_SetRotMatrix((void *)d); + gte_SetTransMatrix((void *)d); + + *(u16 *)(stk + 0x28) = 0x20; + *(u16 *)(stk + 0x2a) = 0; + *(s16 *)(stk + 0x2c) = (s16)*(u32 *)(stk + 0x4c); + gte_ldv0(stk + 0x28); + gte_rtps(); + gte_stsxy(stk + 0x54); + + d = (u16)((s16)(RD16(stk + 0x54)) >> 3); + d |= (s32)((s16)(RD16(stk + 0x56)) >> 3) << 16; + + pkt = D_800A5E60; + p1 = pkt + 0x18; + *(u8 *)(pkt + 0x3) = 5; + *(u8 *)(pkt + 0x7) = 0x28; + *(u8 *)(p1 + 0x3) = 5; + t2 = flags & 0x40000000; + *(u8 *)(p1 + 0x7) = 0x28; + if (t2 != 0) { + *(u8 *)(pkt + 0x7) = *(u8 *)(pkt + 0x7) | 2; + *(u8 *)(p1 + 0x7) = *(u8 *)(p1 + 0x7) | 2; + } + *(u8 *)(pkt + 0x4) = *(u8 *)((s32)a0 + 0x24); + *(u8 *)(pkt + 0x5) = *(u8 *)((s32)a0 + 0x25); + *(u8 *)(pkt + 0x6) = *(u8 *)((s32)a0 + 0x26); + *(u8 *)(p1 + 0x4) = *(u8 *)((s32)a0 + 0x24); + *(u8 *)(p1 + 0x5) = *(u8 *)((s32)a0 + 0x25); + *(u8 *)(p1 + 0x6) = *(u8 *)((s32)a0 + 0x26); + + *(s16 *)(pkt + 0x8) = RD16(stk) + RD16(stk + 0x54); + *(s16 *)(pkt + 0xa) = RD16(stk + 0x02) + RD16(stk + 0x56); + *(s16 *)(pkt + 0xc) = RD16(stk) - (d >> 16); + *(s16 *)(pkt + 0xe) = RD16(stk + 0x02) + d; + *(s16 *)(pkt + 0x10) = RD16(stk) + (d >> 16); + *(s16 *)(pkt + 0x12) = RD16(stk + 0x02) - d; + *(s16 *)(pkt + 0x14) = RD16(stk) - RD16(stk + 0x54); + *(s16 *)(pkt + 0x16) = RD16(stk + 0x02) - RD16(stk + 0x56); + *(s16 *)(p1 + 0x8) = RD16(stk) - RD16(stk + 0x56); + *(s16 *)(p1 + 0xa) = RD16(stk + 0x02) + RD16(stk + 0x54); + *(s16 *)(p1 + 0xc) = RD16(stk) - d; + *(s16 *)(p1 + 0xe) = RD16(stk + 0x02) - (d >> 16); + *(s16 *)(p1 + 0x10) = RD16(stk) + d; + *(s16 *)(p1 + 0x12) = RD16(stk + 0x02) + (d >> 16); + *(s16 *)(p1 + 0x14) = RD16(stk) + RD16(stk + 0x56); + *(s16 *)(p1 + 0x16) = RD16(stk + 0x02) - RD16(stk + 0x54); + + /* addPrim(otp, pkt); addPrim(otp, p1); */ + otp = (u32 *)((idx << 2) + ot); + tv = RW32(pkt); + RW32(pkt) = (tv & 0xFF000000) | (RW32(otp) & 0xFFFFFF); + RW32(otp) = (RW32(otp) & 0xFF000000) | ((u32)pkt & 0xFFFFFF); + tv = RW32(p1); + RW32(p1) = (tv & 0xFF000000) | (RW32(otp) & 0xFFFFFF); + + pkb = D_800A5E60; + p2 = pkb + 0x30; + D_800A5E60 = p2; + RW32(otp) = (RW32(otp) & 0xFF000000) | ((u32)p1 & 0xFFFFFF); + + if (t2 != 0) { + D_800A5E60 = pkb + 0x38; + *(u8 *)(p2 + 3) = 1; + RW32(p2 + 4) = ((flags >> 23) & 0x60) | 0xE1000000; + tv2 = RW32(p2); + RW32(p2) = (tv2 & 0xFF000000) | (RW32(otp) & 0xFFFFFF); + RW32(otp) = (RW32(otp) & 0xFF000000) | ((u32)p2 & 0xFFFFFF); + } + } + } +} + // @class: loose-typing diff --git a/src/ov_SC04_020/ov_SC04_020_jr_8017AE2C.c b/src/ov_SC04_020/ov_SC04_020_jr_8017AE2C.c index ca7373f28..c9108fa18 100644 --- a/src/ov_SC04_020/ov_SC04_020_jr_8017AE2C.c +++ b/src/ov_SC04_020/ov_SC04_020_jr_8017AE2C.c @@ -4245,7 +4245,81 @@ void func_8017CFE0(s16 *a0) { } -INCLUDE_ASM("asm/ov_SC04_020/nonmatchings/ov_SC04_020_jr_8017AE2C", func_8017D0BC); + + +/* func_8017D0BC -- ov_SC02_011 / ov_SC02_011_jr_8017AE2C [target: 133 ins] + * + * Structural twin of func_8017D0BC (ov_SC03_002/ov_SC03_002_jr_8017AE2C.c), + * banked [MATCH, 133 ins] this session -- same jr_8017AE2C shared layout, + * identical struct-offset chain (a0+0x6/0xA/0xE/0x10/0x12/0x16/0x18/0x1A) and + * identical call sequence (func_80133784 -> ratan2 x2 -> angle-wrap -> + * RotMatrixY -> ApplyMatrixSV -> func_8012CEB0). Reused verbatim per §136c + * sibling-first (declaration + expression forms are already byte-proven for + * this exact body). + * + * §136 L1/RC-5 note carried from the twin: `ang` (second ratan2 result) is a + * GLOBAL allocno spanning the +/-0x480 arms, while the `ang - base` compare + * temp is a LOCAL allocno in the same block; unpinned gcc hands the local + * temp $v0 and pushes `ang` to $v1 (REGALLOC-PERM). Pinning `ang` to $v0 + * fixes the swap, and reusing the now-dead `ang` as the a0[0x6] scratch + * (instead of a fresh local) avoids stealing back the $v0 slot. + */ + +typedef struct { s32 w[8]; } Mtx8_8017DE10_8017D0BC; + +void func_8017D0BC(s32 a0) { + extern void ApplyMatrixSV(void *a0, void *a1, void *a2); + extern s32 ratan2(s32 a0, s32 a1); + extern s16 D_801152B0; + extern s16 D_801152B4; + extern s32 func_80133784(s32 a0, void *a1, s32 a2); + extern s32 func_8012CEB0(s32 a0, s32 a1, s32 a2); + extern void RotMatrixY(s32 a0, void *a1); + extern Mtx8_8017DE10_8017D0BC D_800AE620; + + u8 in[8]; + u8 out[8]; + Mtx8_8017DE10_8017D0BC m; + s32 base; + register s32 ang __asm__("$2"); + s16 arg; + + *(s16 *)(in + 0) = *(u16 *)(a0 + 0x6) + *(u16 *)(a0 + 0x12); + *(s16 *)(in + 2) = *(u16 *)(a0 + 0xA) + 8; + *(s16 *)(in + 4) = *(u16 *)(a0 + 0xE) + *(u16 *)(a0 + 0x1A); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x6); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0xA) + 8; + *(s16 *)(out + 4) = *(u16 *)(a0 + 0xE); + if ((func_80133784(1, &in[0], (s32)&out[0]) & 0xC000) != 0) { + base = ratan2(D_801152B0, D_801152B4) & 0xFFF; + ang = ratan2(*(s32 *)(a0 + 0x10), *(s32 *)(a0 + 0x18)) & 0xFFF; + if ((s16)(ang - base) < 0) { + ang += 0x480; + } else { + ang -= 0x480; + } + arg = base - ang; + ang = *(u16 *)(a0 + 0x6); + *(s16 *)(in + 0) = ang; + *(s16 *)(in + 2) = *(u16 *)(a0 + 0xA); + *(s16 *)(in + 4) = *(u16 *)(a0 + 0xE); + m = D_800AE620; + RotMatrixY(arg, &m); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x12); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0x16); + *(s16 *)(out + 4) = *(u16 *)(a0 + 0x1A); + ApplyMatrixSV(&m, &out[0], &out[0]); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x6) + ((s16)*(u16 *)(out + 0) >> 1); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0xA) + ((s16)*(u16 *)(out + 2) >> 1); + *(s16 *)(out + 4) = *(u16 *)(a0 + 0xE) + ((s16)*(u16 *)(out + 4) >> 1); + if ((func_8012CEB0((s32)&in[0], (s32)&out[0], 0) & 0x2000) != 0) { + *(s16 *)(a0 + 0x6) = *(u16 *)(out + 0); + *(s16 *)(a0 + 0xA) = *(u16 *)(out + 2); + *(s16 *)(a0 + 0xE) = *(u16 *)(out + 4); + } + } +} + extern int func_80178970(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 6c2831658..c8ee0ddf6 100644 --- a/src/ov_SC05_004/ov_SC05_004_jr_8017BEBC.c +++ b/src/ov_SC05_004/ov_SC05_004_jr_8017BEBC.c @@ -3834,7 +3834,81 @@ void func_8017DA24(s16 *a0) { } -INCLUDE_ASM("asm/ov_SC05_004/nonmatchings/ov_SC05_004_jr_8017BEBC", func_8017DB00); + + +/* func_8017DB00 -- ov_SC02_011 / ov_SC02_011_jr_8017AE2C [target: 133 ins] + * + * Structural twin of func_8017D0BC (ov_SC03_002/ov_SC03_002_jr_8017AE2C.c), + * banked [MATCH, 133 ins] this session -- same jr_8017AE2C shared layout, + * identical struct-offset chain (a0+0x6/0xA/0xE/0x10/0x12/0x16/0x18/0x1A) and + * identical call sequence (func_80133784 -> ratan2 x2 -> angle-wrap -> + * RotMatrixY -> ApplyMatrixSV -> func_8012CEB0). Reused verbatim per §136c + * sibling-first (declaration + expression forms are already byte-proven for + * this exact body). + * + * §136 L1/RC-5 note carried from the twin: `ang` (second ratan2 result) is a + * GLOBAL allocno spanning the +/-0x480 arms, while the `ang - base` compare + * temp is a LOCAL allocno in the same block; unpinned gcc hands the local + * temp $v0 and pushes `ang` to $v1 (REGALLOC-PERM). Pinning `ang` to $v0 + * fixes the swap, and reusing the now-dead `ang` as the a0[0x6] scratch + * (instead of a fresh local) avoids stealing back the $v0 slot. + */ + +typedef struct { s32 w[8]; } Mtx8_8017DE10_8017DB00; + +void func_8017DB00(s32 a0) { + extern void ApplyMatrixSV(void *a0, void *a1, void *a2); + extern s32 ratan2(s32 a0, s32 a1); + extern s16 D_801152B0; + extern s16 D_801152B4; + extern s32 func_80133784(s32 a0, void *a1, s32 a2); + extern s32 func_8012CEB0(s32 a0, s32 a1, s32 a2); + extern void RotMatrixY(s32 a0, void *a1); + extern Mtx8_8017DE10_8017DB00 D_800AE620; + + u8 in[8]; + u8 out[8]; + Mtx8_8017DE10_8017DB00 m; + s32 base; + register s32 ang __asm__("$2"); + s16 arg; + + *(s16 *)(in + 0) = *(u16 *)(a0 + 0x6) + *(u16 *)(a0 + 0x12); + *(s16 *)(in + 2) = *(u16 *)(a0 + 0xA) + 8; + *(s16 *)(in + 4) = *(u16 *)(a0 + 0xE) + *(u16 *)(a0 + 0x1A); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x6); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0xA) + 8; + *(s16 *)(out + 4) = *(u16 *)(a0 + 0xE); + if ((func_80133784(1, &in[0], (s32)&out[0]) & 0xC000) != 0) { + base = ratan2(D_801152B0, D_801152B4) & 0xFFF; + ang = ratan2(*(s32 *)(a0 + 0x10), *(s32 *)(a0 + 0x18)) & 0xFFF; + if ((s16)(ang - base) < 0) { + ang += 0x480; + } else { + ang -= 0x480; + } + arg = base - ang; + ang = *(u16 *)(a0 + 0x6); + *(s16 *)(in + 0) = ang; + *(s16 *)(in + 2) = *(u16 *)(a0 + 0xA); + *(s16 *)(in + 4) = *(u16 *)(a0 + 0xE); + m = D_800AE620; + RotMatrixY(arg, &m); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x12); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0x16); + *(s16 *)(out + 4) = *(u16 *)(a0 + 0x1A); + ApplyMatrixSV(&m, &out[0], &out[0]); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x6) + ((s16)*(u16 *)(out + 0) >> 1); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0xA) + ((s16)*(u16 *)(out + 2) >> 1); + *(s16 *)(out + 4) = *(u16 *)(a0 + 0xE) + ((s16)*(u16 *)(out + 4) >> 1); + if ((func_8012CEB0((s32)&in[0], (s32)&out[0], 0) & 0x2000) != 0) { + *(s16 *)(a0 + 0x6) = *(u16 *)(out + 0); + *(s16 *)(a0 + 0xA) = *(u16 *)(out + 2); + *(s16 *)(a0 + 0xE) = *(u16 *)(out + 4); + } + } +} + extern int func_80178970(void); diff --git a/src/ov_SC05_018/ov_SC05_018_jr_8017AE2C.c b/src/ov_SC05_018/ov_SC05_018_jr_8017AE2C.c index d216cafd8..c83870bad 100644 --- a/src/ov_SC05_018/ov_SC05_018_jr_8017AE2C.c +++ b/src/ov_SC05_018/ov_SC05_018_jr_8017AE2C.c @@ -4245,7 +4245,81 @@ void func_8017CFE0(s16 *a0) { } -INCLUDE_ASM("asm/ov_SC05_018/nonmatchings/ov_SC05_018_jr_8017AE2C", func_8017D0BC); + + +/* func_8017D0BC -- ov_SC02_011 / ov_SC02_011_jr_8017AE2C [target: 133 ins] + * + * Structural twin of func_8017D0BC (ov_SC03_002/ov_SC03_002_jr_8017AE2C.c), + * banked [MATCH, 133 ins] this session -- same jr_8017AE2C shared layout, + * identical struct-offset chain (a0+0x6/0xA/0xE/0x10/0x12/0x16/0x18/0x1A) and + * identical call sequence (func_80133784 -> ratan2 x2 -> angle-wrap -> + * RotMatrixY -> ApplyMatrixSV -> func_8012CEB0). Reused verbatim per §136c + * sibling-first (declaration + expression forms are already byte-proven for + * this exact body). + * + * §136 L1/RC-5 note carried from the twin: `ang` (second ratan2 result) is a + * GLOBAL allocno spanning the +/-0x480 arms, while the `ang - base` compare + * temp is a LOCAL allocno in the same block; unpinned gcc hands the local + * temp $v0 and pushes `ang` to $v1 (REGALLOC-PERM). Pinning `ang` to $v0 + * fixes the swap, and reusing the now-dead `ang` as the a0[0x6] scratch + * (instead of a fresh local) avoids stealing back the $v0 slot. + */ + +typedef struct { s32 w[8]; } Mtx8_8017DE10_8017D0BC; + +void func_8017D0BC(s32 a0) { + extern void ApplyMatrixSV(void *a0, void *a1, void *a2); + extern s32 ratan2(s32 a0, s32 a1); + extern s16 D_801152B0; + extern s16 D_801152B4; + extern s32 func_80133784(s32 a0, void *a1, s32 a2); + extern s32 func_8012CEB0(s32 a0, s32 a1, s32 a2); + extern void RotMatrixY(s32 a0, void *a1); + extern Mtx8_8017DE10_8017D0BC D_800AE620; + + u8 in[8]; + u8 out[8]; + Mtx8_8017DE10_8017D0BC m; + s32 base; + register s32 ang __asm__("$2"); + s16 arg; + + *(s16 *)(in + 0) = *(u16 *)(a0 + 0x6) + *(u16 *)(a0 + 0x12); + *(s16 *)(in + 2) = *(u16 *)(a0 + 0xA) + 8; + *(s16 *)(in + 4) = *(u16 *)(a0 + 0xE) + *(u16 *)(a0 + 0x1A); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x6); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0xA) + 8; + *(s16 *)(out + 4) = *(u16 *)(a0 + 0xE); + if ((func_80133784(1, &in[0], (s32)&out[0]) & 0xC000) != 0) { + base = ratan2(D_801152B0, D_801152B4) & 0xFFF; + ang = ratan2(*(s32 *)(a0 + 0x10), *(s32 *)(a0 + 0x18)) & 0xFFF; + if ((s16)(ang - base) < 0) { + ang += 0x480; + } else { + ang -= 0x480; + } + arg = base - ang; + ang = *(u16 *)(a0 + 0x6); + *(s16 *)(in + 0) = ang; + *(s16 *)(in + 2) = *(u16 *)(a0 + 0xA); + *(s16 *)(in + 4) = *(u16 *)(a0 + 0xE); + m = D_800AE620; + RotMatrixY(arg, &m); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x12); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0x16); + *(s16 *)(out + 4) = *(u16 *)(a0 + 0x1A); + ApplyMatrixSV(&m, &out[0], &out[0]); + *(s16 *)(out + 0) = *(u16 *)(a0 + 0x6) + ((s16)*(u16 *)(out + 0) >> 1); + *(s16 *)(out + 2) = *(u16 *)(a0 + 0xA) + ((s16)*(u16 *)(out + 2) >> 1); + *(s16 *)(out + 4) = *(u16 *)(a0 + 0xE) + ((s16)*(u16 *)(out + 4) >> 1); + if ((func_8012CEB0((s32)&in[0], (s32)&out[0], 0) & 0x2000) != 0) { + *(s16 *)(a0 + 0x6) = *(u16 *)(out + 0); + *(s16 *)(a0 + 0xA) = *(u16 *)(out + 2); + *(s16 *)(a0 + 0xE) = *(u16 *)(out + 4); + } + } +} + extern int func_80178970(void); 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 e30f7a66f..a2920bc04 100644 --- a/src/ov_SC06_000/ov_SC06_000_jr_8017AE2C.c +++ b/src/ov_SC06_000/ov_SC06_000_jr_8017AE2C.c @@ -4046,7 +4046,6 @@ typedef struct { u32 xx, yy, zz; u32 nprim; u32 *prim; } Part35C; extern s32 func_800491EC(void); extern void func_800547D8(s32, Mtx35C *); extern void func_80052E38(Mtx35C *); -extern u8 D_800A6610[]; extern s16 D_800B9A02; #define gte_ldv0(r0) __asm__ volatile ( \ @@ -4141,6 +4140,10 @@ extern s16 D_800B9A02; void func_8017E35C(s32 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 u8 D_800A6610[]; /* [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. */ @@ -7322,7 +7325,230 @@ void func_801879B8(void *a0) { INCLUDE_ASM("asm/ov_SC06_000/nonmatchings/ov_SC06_000_jr_8017AE2C", func_80187AB8); -INCLUDE_ASM("asm/ov_SC06_000/nonmatchings/ov_SC06_000_jr_8017AE2C", func_80187B34); +#define gte_ldv0(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 )" \ + : \ + : "r"( r0 ) ) +#define gte_rtps() __asm__ volatile ("nop;nop;rtps") +#define gte_stsxy(r0) __asm__ volatile ( \ + "swc2 $14, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) +#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_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" ) +#define gte_ldv0(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 )" \ + : \ + : "r"( r0 ) ) +#define gte_rtps() __asm__ volatile ("nop;nop;rtps") +#define gte_stsxy(r0) __asm__ volatile ( \ + "swc2 $14, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) +#define gte_stsz(r0) __asm__ volatile ( \ + "swc2 $19, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) +#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 RD16(p) (((struct { u16 v; } *)(p))->v) +#define RW32(p) (((struct { u32 v; } *)(p))->v) + +void func_80187B34(void *a0) +{ + extern u8 D_800AF648; + extern u8 *D_800A5E60; + extern u8 D_800A6610[]; + extern void RotMatrixZ(s32 a0, void *a1); + + u8 stk[0x60]; /* sp+0x10 .. sp+0x6F */ + u32 flags; + u32 idx; + u32 ot; + u32 t2; + u8 *pkt; + u8 *p1; + u8 *p2; + u8 *pkb; + s32 d; + u32 *otp; + register u32 tv __asm__("$3"); /* §137 pin — see header */ + register u32 tv2 __asm__("$4"); /* §137 pin — see header */ + + u8 *rotm; + + flags = *(u32 *)((s32)a0 + 4); + rotm = &D_800AF648; + + gte_SetRotMatrix(rotm); + gte_SetTransMatrix(rotm); + gte_ldv0((s32)a0 + 8); + gte_rtps(); + gte_stsxy(stk); + gte_stflg(stk + 0x48); + gte_stsz(stk + 0x4c); + gte_stszotz(stk + 0x50); + + if ((*(u32 *)(stk + 0x48) & 0xFFFFEFFF) == 0) { + idx = *(s32 *)(stk + 0x50) + 1; + ot = (u32)&D_800A6610[(*(u16 *)&D_800B9A02) << 14]; + { + u16 flags2 = *(u16 *)((s32)a0 + 0x2c); + if ((flags2 & 0xC000) != 0) { + if ((flags2 & 0xC000) == 0xC000) { + idx = idx - (flags2 & 0xFFF); + if ((s32)idx < 0) idx = 0; + } else { + idx = idx + (flags2 & 0xFFF); + } + } + } + + if (idx < 0x1000) { + d = (s32)&stk[0x08]; + + *(u16 *)(stk + 0x08) = *(u16 *)((s32)a0 + 0x18); + *(u16 *)(stk + 0x0a) = 0; + *(u16 *)(stk + 0x0c) = 0; + *(u16 *)(stk + 0x0e) = 0; + *(u16 *)(stk + 0x10) = *(u16 *)((s32)a0 + 0x18); + *(u16 *)(stk + 0x12) = 0; + *(u16 *)(stk + 0x14) = 0; + *(u16 *)(stk + 0x16) = 0; + *(u16 *)(stk + 0x18) = 0x1000; + *(u32 *)(stk + 0x24) = 0; + *(u32 *)(stk + 0x20) = 0; + *(u32 *)(stk + 0x1c) = 0; + + RotMatrixZ(*(s16 *)((s32)a0 + 0x14), (void *)d); + gte_SetRotMatrix((void *)d); + gte_SetTransMatrix((void *)d); + + *(u16 *)(stk + 0x28) = 0x20; + *(u16 *)(stk + 0x2a) = 0; + *(s16 *)(stk + 0x2c) = (s16)*(u32 *)(stk + 0x4c); + gte_ldv0(stk + 0x28); + gte_rtps(); + gte_stsxy(stk + 0x54); + + d = (u16)((s16)(RD16(stk + 0x54)) >> 3); + d |= (s32)((s16)(RD16(stk + 0x56)) >> 3) << 16; + + pkt = D_800A5E60; + p1 = pkt + 0x18; + *(u8 *)(pkt + 0x3) = 5; + *(u8 *)(pkt + 0x7) = 0x28; + *(u8 *)(p1 + 0x3) = 5; + t2 = flags & 0x40000000; + *(u8 *)(p1 + 0x7) = 0x28; + if (t2 != 0) { + *(u8 *)(pkt + 0x7) = *(u8 *)(pkt + 0x7) | 2; + *(u8 *)(p1 + 0x7) = *(u8 *)(p1 + 0x7) | 2; + } + *(u8 *)(pkt + 0x4) = *(u8 *)((s32)a0 + 0x24); + *(u8 *)(pkt + 0x5) = *(u8 *)((s32)a0 + 0x25); + *(u8 *)(pkt + 0x6) = *(u8 *)((s32)a0 + 0x26); + *(u8 *)(p1 + 0x4) = *(u8 *)((s32)a0 + 0x24); + *(u8 *)(p1 + 0x5) = *(u8 *)((s32)a0 + 0x25); + *(u8 *)(p1 + 0x6) = *(u8 *)((s32)a0 + 0x26); + + *(s16 *)(pkt + 0x8) = RD16(stk) + RD16(stk + 0x54); + *(s16 *)(pkt + 0xa) = RD16(stk + 0x02) + RD16(stk + 0x56); + *(s16 *)(pkt + 0xc) = RD16(stk) - (d >> 16); + *(s16 *)(pkt + 0xe) = RD16(stk + 0x02) + d; + *(s16 *)(pkt + 0x10) = RD16(stk) + (d >> 16); + *(s16 *)(pkt + 0x12) = RD16(stk + 0x02) - d; + *(s16 *)(pkt + 0x14) = RD16(stk) - RD16(stk + 0x54); + *(s16 *)(pkt + 0x16) = RD16(stk + 0x02) - RD16(stk + 0x56); + *(s16 *)(p1 + 0x8) = RD16(stk) - RD16(stk + 0x56); + *(s16 *)(p1 + 0xa) = RD16(stk + 0x02) + RD16(stk + 0x54); + *(s16 *)(p1 + 0xc) = RD16(stk) - d; + *(s16 *)(p1 + 0xe) = RD16(stk + 0x02) - (d >> 16); + *(s16 *)(p1 + 0x10) = RD16(stk) + d; + *(s16 *)(p1 + 0x12) = RD16(stk + 0x02) + (d >> 16); + *(s16 *)(p1 + 0x14) = RD16(stk) + RD16(stk + 0x56); + *(s16 *)(p1 + 0x16) = RD16(stk + 0x02) - RD16(stk + 0x54); + + /* addPrim(otp, pkt); addPrim(otp, p1); */ + otp = (u32 *)((idx << 2) + ot); + tv = RW32(pkt); + RW32(pkt) = (tv & 0xFF000000) | (RW32(otp) & 0xFFFFFF); + RW32(otp) = (RW32(otp) & 0xFF000000) | ((u32)pkt & 0xFFFFFF); + tv = RW32(p1); + RW32(p1) = (tv & 0xFF000000) | (RW32(otp) & 0xFFFFFF); + + pkb = D_800A5E60; + p2 = pkb + 0x30; + D_800A5E60 = p2; + RW32(otp) = (RW32(otp) & 0xFF000000) | ((u32)p1 & 0xFFFFFF); + + if (t2 != 0) { + D_800A5E60 = pkb + 0x38; + *(u8 *)(p2 + 3) = 1; + RW32(p2 + 4) = ((flags >> 23) & 0x60) | 0xE1000000; + tv2 = RW32(p2); + RW32(p2) = (tv2 & 0xFF000000) | (RW32(otp) & 0xFFFFFF); + RW32(otp) = (RW32(otp) & 0xFF000000) | ((u32)p2 & 0xFFFFFF); + } + } + } +} + // @class: loose-typing 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 bb0d28c0d..d4c7d09a2 100644 --- a/src/ov_SC06_006/ov_SC06_006_jr_8017BEBC.c +++ b/src/ov_SC06_006/ov_SC06_006_jr_8017BEBC.c @@ -3875,7 +3875,230 @@ void func_801814DC(void *a0) { INCLUDE_ASM("asm/ov_SC06_006/nonmatchings/ov_SC06_006_jr_8017BEBC", func_801815DC); -INCLUDE_ASM("asm/ov_SC06_006/nonmatchings/ov_SC06_006_jr_8017BEBC", func_80181658); +#define gte_ldv0(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 )" \ + : \ + : "r"( r0 ) ) +#define gte_rtps() __asm__ volatile ("nop;nop;rtps") +#define gte_stsxy(r0) __asm__ volatile ( \ + "swc2 $14, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) +#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_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" ) +#define gte_ldv0(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 )" \ + : \ + : "r"( r0 ) ) +#define gte_rtps() __asm__ volatile ("nop;nop;rtps") +#define gte_stsxy(r0) __asm__ volatile ( \ + "swc2 $14, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) +#define gte_stsz(r0) __asm__ volatile ( \ + "swc2 $19, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) +#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 RD16(p) (((struct { u16 v; } *)(p))->v) +#define RW32(p) (((struct { u32 v; } *)(p))->v) + +void func_80181658(void *a0) +{ + extern u8 D_800AF648; + extern u8 *D_800A5E60; + extern u8 D_800A6610[]; + extern void RotMatrixZ(s32 a0, void *a1); + + u8 stk[0x60]; /* sp+0x10 .. sp+0x6F */ + u32 flags; + u32 idx; + u32 ot; + u32 t2; + u8 *pkt; + u8 *p1; + u8 *p2; + u8 *pkb; + s32 d; + u32 *otp; + register u32 tv __asm__("$3"); /* §137 pin — see header */ + register u32 tv2 __asm__("$4"); /* §137 pin — see header */ + + u8 *rotm; + + flags = *(u32 *)((s32)a0 + 4); + rotm = &D_800AF648; + + gte_SetRotMatrix(rotm); + gte_SetTransMatrix(rotm); + gte_ldv0((s32)a0 + 8); + gte_rtps(); + gte_stsxy(stk); + gte_stflg(stk + 0x48); + gte_stsz(stk + 0x4c); + gte_stszotz(stk + 0x50); + + if ((*(u32 *)(stk + 0x48) & 0xFFFFEFFF) == 0) { + idx = *(s32 *)(stk + 0x50) + 1; + ot = (u32)&D_800A6610[(*(u16 *)&D_800B9A02) << 14]; + { + u16 flags2 = *(u16 *)((s32)a0 + 0x2c); + if ((flags2 & 0xC000) != 0) { + if ((flags2 & 0xC000) == 0xC000) { + idx = idx - (flags2 & 0xFFF); + if ((s32)idx < 0) idx = 0; + } else { + idx = idx + (flags2 & 0xFFF); + } + } + } + + if (idx < 0x1000) { + d = (s32)&stk[0x08]; + + *(u16 *)(stk + 0x08) = *(u16 *)((s32)a0 + 0x18); + *(u16 *)(stk + 0x0a) = 0; + *(u16 *)(stk + 0x0c) = 0; + *(u16 *)(stk + 0x0e) = 0; + *(u16 *)(stk + 0x10) = *(u16 *)((s32)a0 + 0x18); + *(u16 *)(stk + 0x12) = 0; + *(u16 *)(stk + 0x14) = 0; + *(u16 *)(stk + 0x16) = 0; + *(u16 *)(stk + 0x18) = 0x1000; + *(u32 *)(stk + 0x24) = 0; + *(u32 *)(stk + 0x20) = 0; + *(u32 *)(stk + 0x1c) = 0; + + RotMatrixZ(*(s16 *)((s32)a0 + 0x14), (void *)d); + gte_SetRotMatrix((void *)d); + gte_SetTransMatrix((void *)d); + + *(u16 *)(stk + 0x28) = 0x20; + *(u16 *)(stk + 0x2a) = 0; + *(s16 *)(stk + 0x2c) = (s16)*(u32 *)(stk + 0x4c); + gte_ldv0(stk + 0x28); + gte_rtps(); + gte_stsxy(stk + 0x54); + + d = (u16)((s16)(RD16(stk + 0x54)) >> 3); + d |= (s32)((s16)(RD16(stk + 0x56)) >> 3) << 16; + + pkt = D_800A5E60; + p1 = pkt + 0x18; + *(u8 *)(pkt + 0x3) = 5; + *(u8 *)(pkt + 0x7) = 0x28; + *(u8 *)(p1 + 0x3) = 5; + t2 = flags & 0x40000000; + *(u8 *)(p1 + 0x7) = 0x28; + if (t2 != 0) { + *(u8 *)(pkt + 0x7) = *(u8 *)(pkt + 0x7) | 2; + *(u8 *)(p1 + 0x7) = *(u8 *)(p1 + 0x7) | 2; + } + *(u8 *)(pkt + 0x4) = *(u8 *)((s32)a0 + 0x24); + *(u8 *)(pkt + 0x5) = *(u8 *)((s32)a0 + 0x25); + *(u8 *)(pkt + 0x6) = *(u8 *)((s32)a0 + 0x26); + *(u8 *)(p1 + 0x4) = *(u8 *)((s32)a0 + 0x24); + *(u8 *)(p1 + 0x5) = *(u8 *)((s32)a0 + 0x25); + *(u8 *)(p1 + 0x6) = *(u8 *)((s32)a0 + 0x26); + + *(s16 *)(pkt + 0x8) = RD16(stk) + RD16(stk + 0x54); + *(s16 *)(pkt + 0xa) = RD16(stk + 0x02) + RD16(stk + 0x56); + *(s16 *)(pkt + 0xc) = RD16(stk) - (d >> 16); + *(s16 *)(pkt + 0xe) = RD16(stk + 0x02) + d; + *(s16 *)(pkt + 0x10) = RD16(stk) + (d >> 16); + *(s16 *)(pkt + 0x12) = RD16(stk + 0x02) - d; + *(s16 *)(pkt + 0x14) = RD16(stk) - RD16(stk + 0x54); + *(s16 *)(pkt + 0x16) = RD16(stk + 0x02) - RD16(stk + 0x56); + *(s16 *)(p1 + 0x8) = RD16(stk) - RD16(stk + 0x56); + *(s16 *)(p1 + 0xa) = RD16(stk + 0x02) + RD16(stk + 0x54); + *(s16 *)(p1 + 0xc) = RD16(stk) - d; + *(s16 *)(p1 + 0xe) = RD16(stk + 0x02) - (d >> 16); + *(s16 *)(p1 + 0x10) = RD16(stk) + d; + *(s16 *)(p1 + 0x12) = RD16(stk + 0x02) + (d >> 16); + *(s16 *)(p1 + 0x14) = RD16(stk) + RD16(stk + 0x56); + *(s16 *)(p1 + 0x16) = RD16(stk + 0x02) - RD16(stk + 0x54); + + /* addPrim(otp, pkt); addPrim(otp, p1); */ + otp = (u32 *)((idx << 2) + ot); + tv = RW32(pkt); + RW32(pkt) = (tv & 0xFF000000) | (RW32(otp) & 0xFFFFFF); + RW32(otp) = (RW32(otp) & 0xFF000000) | ((u32)pkt & 0xFFFFFF); + tv = RW32(p1); + RW32(p1) = (tv & 0xFF000000) | (RW32(otp) & 0xFFFFFF); + + pkb = D_800A5E60; + p2 = pkb + 0x30; + D_800A5E60 = p2; + RW32(otp) = (RW32(otp) & 0xFF000000) | ((u32)p1 & 0xFFFFFF); + + if (t2 != 0) { + D_800A5E60 = pkb + 0x38; + *(u8 *)(p2 + 3) = 1; + RW32(p2 + 4) = ((flags >> 23) & 0x60) | 0xE1000000; + tv2 = RW32(p2); + RW32(p2) = (tv2 & 0xFF000000) | (RW32(otp) & 0xFFFFFF); + RW32(otp) = (RW32(otp) & 0xFF000000) | ((u32)p2 & 0xFFFFFF); + } + } + } +} + // @class: loose-typing diff --git a/src/ov_SC06_011/ov_SC06_011_jr_8017BEBC.c b/src/ov_SC06_011/ov_SC06_011_jr_8017BEBC.c index 7e1ddfbf8..2bd3b93d1 100644 --- a/src/ov_SC06_011/ov_SC06_011_jr_8017BEBC.c +++ b/src/ov_SC06_011/ov_SC06_011_jr_8017BEBC.c @@ -3639,7 +3639,245 @@ s32 func_8017E5C8(void) { } -INCLUDE_ASM("asm/ov_SC06_011/nonmatchings/ov_SC06_011_jr_8017BEBC", func_8017E5D0); +/* func_8017E5D0 — draws a 4-segment perspective-scaled "trail/shadow" fan of + * gouraud-shaded quads (POLY_G4-shaped, stride 0x24) behind an object. + * + * Derivation notes (no banked sibling existed — first crack of a 6-member family): + * - GTE matrix load + RotTransSV + RotTransPers pipeline matches the byte-proven + * gte_SetRotMatrix/gte_SetTransMatrix macros (ov_SC03_099_jr_8017BEBC.c) and the + * engine_core.h RotTransPers canonical form. + * - D_800A651C OT-table lookup uses the canonical engine_core.h idiom: + * `*(s32*)((s8*)&D_800A651C + ((u16)D_800B9A02 * 0x14))` (DEFINE_func_8012D4B4 et al). + * - The per-prim struct (0x24-byte stride) decodes as a libgpu POLY_G4: tag(4, + * AddPrim-owned except the `len` top byte we set), 4x{rgb+code/pad(4), x,y(4)}. + * All 14 fields matched a `base = s0 - 0x22` model with s0 anchored at the LAST + * field (y3) — negative-offset addressing off that anchor pointer. + * - D_8019E198/199/19A/19B, D_8019E178/179/17A/17B, D_8019E188/189/18A/18B are each + * individually-addressed consecutive byte tables (cookbook idiom: multi-symbol + * byte array, same class as ov_SC03_101's D_8019E170..D_8019E178 chain) — accessed + * via `*(u8*)((s32)&D_8019Exxx + i)`, NOT array indexing. + * - RotTransSV / func_8004914C / func_800491AC are ALREADY file-scope declared + * above the splice point in this TU (void* params) — reused verbatim, not redeclared. + * + * CLOSING RESIDUAL (S34, gcc-2.7.2-map/sched.md §S2 — "CREATE the boost"): + * The 262/265 draft emitted `lhu $a2,0x54(sp)` BEFORE the `lui/lhu %hi/%lo(D_800B9A02)` + * pair; the target has the pair first. All four insns tie at pri 1, so the pick was + * decided by adjust_priority's BIRTHING BOOST (sched.c:2507 / birthing_insn_p:2469): + * a SET(REG,..) whose dest has REG_N_SETS==1 is raised to max_priority and, because + * schedule_block runs BACKWARD, is PICKED EARLY == PLACED LATE. `sy` had TWO sets + * (`sy = L.sy0` then `sy = sy + sc`) so its load was never boosted and could not sink + * past the D_800B9A02 pair. Giving the accumulate its own single-set local (`sye`) + * makes `sy = L.sy0` a single-set def -> boosted -> the whole 4-load group lands in + * the target order. (Splitting `sx` the same way OVER-shoots: it re-groups the + * 0x36/0x40 store cluster — 9 mismatches. ONLY `sy` is split. Byte-verified: the + * three tested variants scored sx-only 9, both 5, sy-only 0.) + */ + +extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3); +extern void *func_80010A08(s32 a0); +extern s32 GetTPage(s32 a0, s32 a1, s32 a2, s32 a3); +extern s32 func_8005A600(s32 a0, s32 a1, s32 a2, s32 a3, s32 a4); +extern s32 AddPrim(s32 a0, void *a1); + +extern u8 D_8019E164; +extern s32 D_8019E16C[]; + +extern u8 D_8019E178; +extern u8 D_8019E179; +extern u8 D_8019E17A; +extern u8 D_8019E17B; + +extern u8 D_8019E188; +extern u8 D_8019E189; +extern u8 D_8019E18A; +extern u8 D_8019E18B; + +extern u8 D_8019E198; +extern u8 D_8019E199; +extern u8 D_8019E19A; +extern u8 D_8019E19B; + +extern s32 D_800A651C; +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); + +#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" ) + +/* §37/§124 SELF-axis: the TU declares `extern void func_8017E5D0(void);` (L3765) but the + byte-true definition takes a pointer. Define under a private C name bound to the real + symbol so both live in one TU — zero blast radius on every caller. */ +extern void aF8017E5D0(void *a0) __asm__("func_8017E5D0"); +void aF8017E5D0(void *a0) +{ + extern u8 D_800AF648; + + s32 primPtrs[4]; /* sp+0x18 */ + s16 sv0[4]; /* sp+0x28 : RotTransSV out */ + s16 sxArr[8]; /* sp+0x30 */ + s16 syArr[8]; /* sp+0x40 */ + struct { + s32 flag; /* sp+0x50 */ + u16 sx0; /* sp+0x54 */ + u16 sy0; /* sp+0x56 */ + s32 p; /* sp+0x58 */ + } L; + + s32 m; + register s32 cnt __asm__("$8"); + s32 sc; + s32 sx, sy; + s32 sye; /* single-set split of sy (see header note: §S2 birthing boost) */ + s32 d; + register s32 ot __asm__("$9"); + s32 otAddr; + void *buf; + s32 tpage; + u8 *prim; + register s8 *fp __asm__("$16"); + s32 i; + + m = *(s32 *)((s32)a0 + 0x20) + 0x34; + gte_SetRotMatrix(m); + gte_SetTransMatrix(m); + + RotTransSV(&D_8019E164, sv0, &L.flag); + + func_8004914C(&D_800AF648); + func_800491AC(&D_800AF648); + + cnt = RotTransPers((s32)sv0, (s32)&L.sx0, &L.p, &L.flag); + if (cnt <= 0) { + return; + } + if (L.flag < 0) { + return; + } + cnt = cnt << 2; + + sc = ((D_80126950 + 0x1F4) * 3) << 4; + sc = sc / cnt; + + ot = *(s32 *)((s8 *)&D_800A651C + ((u16)D_800B9A02 * 0x14)); + sx = L.sx0; + sy = L.sy0; + + sxArr[2] = sx; + syArr[2] = sy; + + otAddr = ot + cnt; + + { + register s32 t __asm__("$2"); + + t = sx - sc; + sxArr[0] = t; + + d = (sc * 179) >> 8; + + t = sx - d; + sxArr[1] = t; + t = sx + d; + sxArr[3] = t; + sx = sx + sc; + + t = sy - sc; + syArr[0] = t; + t = sy - d; + sxArr[4] = sx; + syArr[1] = t; + syArr[3] = sy + d; + sye = sy + sc; + } + + syArr[4] = sye; + + buf = func_80010A08(0x9C); + + if (buf == 0) { + return; + } + + tpage = GetTPage(0, 1, 0, 0); + func_8005A600((s32)buf, 0, 0, (u16)tpage, 0); + + { + register s32 t0c __asm__("$2"); + t0c = (s32)((u8 *)buf + 0xC); + prim = (u8 *)t0c; + } + + primPtrs[1] = (s32)((u8 *)buf + 0x30); + primPtrs[2] = (s32)((u8 *)buf + 0x54); + primPtrs[0] = (s32)prim; + primPtrs[3] = (s32)((u8 *)buf + 0x78); + + { + register s32 *table __asm__("$21"); + register s8 *cbase __asm__("$18"); + table = D_8019E16C; + cbase = (s8 *)primPtrs; + fp = (s8 *)prim + 0x22; + + i = 0; + for (; i < 0x10; i += 4) { + *(s32 *)(fp - 0x1E) = table[*(u8 *)((s32)&D_8019E198 + i)]; + *(s32 *)(fp - 0x16) = table[*(u8 *)((s32)&D_8019E199 + i)]; + *(s32 *)(fp - 0xE) = table[*(u8 *)((s32)&D_8019E19A + i)]; + + { + s32 rgb3 = table[*(u8 *)((s32)&D_8019E19B + i)]; + *(u8 *)(fp - 0x1F) = 8; + *(u8 *)(fp - 0x1B) = 0x3A; + *(s32 *)(fp - 0x6) = rgb3; + } + + *(s16 *)(fp - 0x1A) = *(s16 *)(cbase + 0x18 + (*(u8 *)((s32)&D_8019E178 + i) << 1)); + *(s16 *)(fp - 0x12) = *(s16 *)(cbase + 0x18 + (*(u8 *)((s32)&D_8019E179 + i) << 1)); + *(s16 *)(fp - 0xA) = *(s16 *)(cbase + 0x18 + (*(u8 *)((s32)&D_8019E17A + i) << 1)); + *(s16 *)(fp - 0x2) = *(s16 *)(cbase + 0x18 + (*(u8 *)((s32)&D_8019E17B + i) << 1)); + + *(s16 *)(fp - 0x18) = *(s16 *)(cbase + 0x28 + (*(u8 *)((s32)&D_8019E188 + i) << 1)); + *(s16 *)(fp - 0x10) = *(s16 *)(cbase + 0x28 + (*(u8 *)((s32)&D_8019E189 + i) << 1)); + *(s16 *)(fp - 0x8) = *(s16 *)(cbase + 0x28 + (*(u8 *)((s32)&D_8019E18A + i) << 1)); + *(s16 *)(fp - 0x0) = *(s16 *)(cbase + 0x28 + (*(u8 *)((s32)&D_8019E18B + i) << 1)); + + AddPrim(otAddr, prim); + + prim += 0x24; + fp += 0x24; + } + } + + AddPrim(otAddr, buf); +} + extern u16 D_80126B62; extern u16 D_80126B66; 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 4171fb402..604a85bc0 100644 --- a/src/ov_SC06_018/ov_SC06_018_jr_8017C24C.c +++ b/src/ov_SC06_018/ov_SC06_018_jr_8017C24C.c @@ -7645,7 +7645,230 @@ INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C", func_8018CB8 INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C", func_8018CC88); -INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C", func_8018CD04); +#define gte_ldv0(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 )" \ + : \ + : "r"( r0 ) ) +#define gte_rtps() __asm__ volatile ("nop;nop;rtps") +#define gte_stsxy(r0) __asm__ volatile ( \ + "swc2 $14, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) +#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_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" ) +#define gte_ldv0(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 )" \ + : \ + : "r"( r0 ) ) +#define gte_rtps() __asm__ volatile ("nop;nop;rtps") +#define gte_stsxy(r0) __asm__ volatile ( \ + "swc2 $14, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) +#define gte_stsz(r0) __asm__ volatile ( \ + "swc2 $19, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) +#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 RD16(p) (((struct { u16 v; } *)(p))->v) +#define RW32(p) (((struct { u32 v; } *)(p))->v) + +void func_8018CD04(void *a0) +{ + extern u8 D_800AF648; + extern u8 *D_800A5E60; + extern u8 D_800A6610[]; + extern void RotMatrixZ(s32 a0, void *a1); + + u8 stk[0x60]; /* sp+0x10 .. sp+0x6F */ + u32 flags; + u32 idx; + u32 ot; + u32 t2; + u8 *pkt; + u8 *p1; + u8 *p2; + u8 *pkb; + s32 d; + u32 *otp; + register u32 tv __asm__("$3"); /* §137 pin — see header */ + register u32 tv2 __asm__("$4"); /* §137 pin — see header */ + + u8 *rotm; + + flags = *(u32 *)((s32)a0 + 4); + rotm = &D_800AF648; + + gte_SetRotMatrix(rotm); + gte_SetTransMatrix(rotm); + gte_ldv0((s32)a0 + 8); + gte_rtps(); + gte_stsxy(stk); + gte_stflg(stk + 0x48); + gte_stsz(stk + 0x4c); + gte_stszotz(stk + 0x50); + + if ((*(u32 *)(stk + 0x48) & 0xFFFFEFFF) == 0) { + idx = *(s32 *)(stk + 0x50) + 1; + ot = (u32)&D_800A6610[(*(u16 *)&D_800B9A02) << 14]; + { + u16 flags2 = *(u16 *)((s32)a0 + 0x2c); + if ((flags2 & 0xC000) != 0) { + if ((flags2 & 0xC000) == 0xC000) { + idx = idx - (flags2 & 0xFFF); + if ((s32)idx < 0) idx = 0; + } else { + idx = idx + (flags2 & 0xFFF); + } + } + } + + if (idx < 0x1000) { + d = (s32)&stk[0x08]; + + *(u16 *)(stk + 0x08) = *(u16 *)((s32)a0 + 0x18); + *(u16 *)(stk + 0x0a) = 0; + *(u16 *)(stk + 0x0c) = 0; + *(u16 *)(stk + 0x0e) = 0; + *(u16 *)(stk + 0x10) = *(u16 *)((s32)a0 + 0x18); + *(u16 *)(stk + 0x12) = 0; + *(u16 *)(stk + 0x14) = 0; + *(u16 *)(stk + 0x16) = 0; + *(u16 *)(stk + 0x18) = 0x1000; + *(u32 *)(stk + 0x24) = 0; + *(u32 *)(stk + 0x20) = 0; + *(u32 *)(stk + 0x1c) = 0; + + RotMatrixZ(*(s16 *)((s32)a0 + 0x14), (void *)d); + gte_SetRotMatrix((void *)d); + gte_SetTransMatrix((void *)d); + + *(u16 *)(stk + 0x28) = 0x20; + *(u16 *)(stk + 0x2a) = 0; + *(s16 *)(stk + 0x2c) = (s16)*(u32 *)(stk + 0x4c); + gte_ldv0(stk + 0x28); + gte_rtps(); + gte_stsxy(stk + 0x54); + + d = (u16)((s16)(RD16(stk + 0x54)) >> 3); + d |= (s32)((s16)(RD16(stk + 0x56)) >> 3) << 16; + + pkt = D_800A5E60; + p1 = pkt + 0x18; + *(u8 *)(pkt + 0x3) = 5; + *(u8 *)(pkt + 0x7) = 0x28; + *(u8 *)(p1 + 0x3) = 5; + t2 = flags & 0x40000000; + *(u8 *)(p1 + 0x7) = 0x28; + if (t2 != 0) { + *(u8 *)(pkt + 0x7) = *(u8 *)(pkt + 0x7) | 2; + *(u8 *)(p1 + 0x7) = *(u8 *)(p1 + 0x7) | 2; + } + *(u8 *)(pkt + 0x4) = *(u8 *)((s32)a0 + 0x24); + *(u8 *)(pkt + 0x5) = *(u8 *)((s32)a0 + 0x25); + *(u8 *)(pkt + 0x6) = *(u8 *)((s32)a0 + 0x26); + *(u8 *)(p1 + 0x4) = *(u8 *)((s32)a0 + 0x24); + *(u8 *)(p1 + 0x5) = *(u8 *)((s32)a0 + 0x25); + *(u8 *)(p1 + 0x6) = *(u8 *)((s32)a0 + 0x26); + + *(s16 *)(pkt + 0x8) = RD16(stk) + RD16(stk + 0x54); + *(s16 *)(pkt + 0xa) = RD16(stk + 0x02) + RD16(stk + 0x56); + *(s16 *)(pkt + 0xc) = RD16(stk) - (d >> 16); + *(s16 *)(pkt + 0xe) = RD16(stk + 0x02) + d; + *(s16 *)(pkt + 0x10) = RD16(stk) + (d >> 16); + *(s16 *)(pkt + 0x12) = RD16(stk + 0x02) - d; + *(s16 *)(pkt + 0x14) = RD16(stk) - RD16(stk + 0x54); + *(s16 *)(pkt + 0x16) = RD16(stk + 0x02) - RD16(stk + 0x56); + *(s16 *)(p1 + 0x8) = RD16(stk) - RD16(stk + 0x56); + *(s16 *)(p1 + 0xa) = RD16(stk + 0x02) + RD16(stk + 0x54); + *(s16 *)(p1 + 0xc) = RD16(stk) - d; + *(s16 *)(p1 + 0xe) = RD16(stk + 0x02) - (d >> 16); + *(s16 *)(p1 + 0x10) = RD16(stk) + d; + *(s16 *)(p1 + 0x12) = RD16(stk + 0x02) + (d >> 16); + *(s16 *)(p1 + 0x14) = RD16(stk) + RD16(stk + 0x56); + *(s16 *)(p1 + 0x16) = RD16(stk + 0x02) - RD16(stk + 0x54); + + /* addPrim(otp, pkt); addPrim(otp, p1); */ + otp = (u32 *)((idx << 2) + ot); + tv = RW32(pkt); + RW32(pkt) = (tv & 0xFF000000) | (RW32(otp) & 0xFFFFFF); + RW32(otp) = (RW32(otp) & 0xFF000000) | ((u32)pkt & 0xFFFFFF); + tv = RW32(p1); + RW32(p1) = (tv & 0xFF000000) | (RW32(otp) & 0xFFFFFF); + + pkb = D_800A5E60; + p2 = pkb + 0x30; + D_800A5E60 = p2; + RW32(otp) = (RW32(otp) & 0xFF000000) | ((u32)p1 & 0xFFFFFF); + + if (t2 != 0) { + D_800A5E60 = pkb + 0x38; + *(u8 *)(p2 + 3) = 1; + RW32(p2 + 4) = ((flags >> 23) & 0x60) | 0xE1000000; + tv2 = RW32(p2); + RW32(p2) = (tv2 & 0xFF000000) | (RW32(otp) & 0xFFFFFF); + RW32(otp) = (RW32(otp) & 0xFF000000) | ((u32)p2 & 0xFFFFFF); + } + } + } +} + // @class: loose-typing // @stuck: none — MATCH (99 ins). short* for param_2/param_3: gcc emits lh where sign is live (<<1 for signed div), lhu where truncated to short (arith result / direct copy) 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 682f98e2d..4d7c0327d 100644 --- a/src/ov_SC06_032/ov_SC06_032_jr_8017C24C.c +++ b/src/ov_SC06_032/ov_SC06_032_jr_8017C24C.c @@ -5800,7 +5800,230 @@ void func_80187D60(void *a0) { INCLUDE_ASM("asm/ov_SC06_032/nonmatchings/ov_SC06_032_jr_8017C24C", func_80187E60); -INCLUDE_ASM("asm/ov_SC06_032/nonmatchings/ov_SC06_032_jr_8017C24C", func_80187EDC); +#define gte_ldv0(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 )" \ + : \ + : "r"( r0 ) ) +#define gte_rtps() __asm__ volatile ("nop;nop;rtps") +#define gte_stsxy(r0) __asm__ volatile ( \ + "swc2 $14, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) +#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_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" ) +#define gte_ldv0(r0) __asm__ volatile ( \ + "lwc2 $0, 0( %0 );" \ + "lwc2 $1, 4( %0 )" \ + : \ + : "r"( r0 ) ) +#define gte_rtps() __asm__ volatile ("nop;nop;rtps") +#define gte_stsxy(r0) __asm__ volatile ( \ + "swc2 $14, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) +#define gte_stsz(r0) __asm__ volatile ( \ + "swc2 $19, 0( %0 )" \ + : \ + : "r"( r0 ) \ + : "memory" ) +#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 RD16(p) (((struct { u16 v; } *)(p))->v) +#define RW32(p) (((struct { u32 v; } *)(p))->v) + +void func_80187EDC(void *a0) +{ + extern u8 D_800AF648; + extern u8 *D_800A5E60; + extern u8 D_800A6610[]; + extern void RotMatrixZ(s32 a0, void *a1); + + u8 stk[0x60]; /* sp+0x10 .. sp+0x6F */ + u32 flags; + u32 idx; + u32 ot; + u32 t2; + u8 *pkt; + u8 *p1; + u8 *p2; + u8 *pkb; + s32 d; + u32 *otp; + register u32 tv __asm__("$3"); /* §137 pin — see header */ + register u32 tv2 __asm__("$4"); /* §137 pin — see header */ + + u8 *rotm; + + flags = *(u32 *)((s32)a0 + 4); + rotm = &D_800AF648; + + gte_SetRotMatrix(rotm); + gte_SetTransMatrix(rotm); + gte_ldv0((s32)a0 + 8); + gte_rtps(); + gte_stsxy(stk); + gte_stflg(stk + 0x48); + gte_stsz(stk + 0x4c); + gte_stszotz(stk + 0x50); + + if ((*(u32 *)(stk + 0x48) & 0xFFFFEFFF) == 0) { + idx = *(s32 *)(stk + 0x50) + 1; + ot = (u32)&D_800A6610[(*(u16 *)&D_800B9A02) << 14]; + { + u16 flags2 = *(u16 *)((s32)a0 + 0x2c); + if ((flags2 & 0xC000) != 0) { + if ((flags2 & 0xC000) == 0xC000) { + idx = idx - (flags2 & 0xFFF); + if ((s32)idx < 0) idx = 0; + } else { + idx = idx + (flags2 & 0xFFF); + } + } + } + + if (idx < 0x1000) { + d = (s32)&stk[0x08]; + + *(u16 *)(stk + 0x08) = *(u16 *)((s32)a0 + 0x18); + *(u16 *)(stk + 0x0a) = 0; + *(u16 *)(stk + 0x0c) = 0; + *(u16 *)(stk + 0x0e) = 0; + *(u16 *)(stk + 0x10) = *(u16 *)((s32)a0 + 0x18); + *(u16 *)(stk + 0x12) = 0; + *(u16 *)(stk + 0x14) = 0; + *(u16 *)(stk + 0x16) = 0; + *(u16 *)(stk + 0x18) = 0x1000; + *(u32 *)(stk + 0x24) = 0; + *(u32 *)(stk + 0x20) = 0; + *(u32 *)(stk + 0x1c) = 0; + + RotMatrixZ(*(s16 *)((s32)a0 + 0x14), (void *)d); + gte_SetRotMatrix((void *)d); + gte_SetTransMatrix((void *)d); + + *(u16 *)(stk + 0x28) = 0x20; + *(u16 *)(stk + 0x2a) = 0; + *(s16 *)(stk + 0x2c) = (s16)*(u32 *)(stk + 0x4c); + gte_ldv0(stk + 0x28); + gte_rtps(); + gte_stsxy(stk + 0x54); + + d = (u16)((s16)(RD16(stk + 0x54)) >> 3); + d |= (s32)((s16)(RD16(stk + 0x56)) >> 3) << 16; + + pkt = D_800A5E60; + p1 = pkt + 0x18; + *(u8 *)(pkt + 0x3) = 5; + *(u8 *)(pkt + 0x7) = 0x28; + *(u8 *)(p1 + 0x3) = 5; + t2 = flags & 0x40000000; + *(u8 *)(p1 + 0x7) = 0x28; + if (t2 != 0) { + *(u8 *)(pkt + 0x7) = *(u8 *)(pkt + 0x7) | 2; + *(u8 *)(p1 + 0x7) = *(u8 *)(p1 + 0x7) | 2; + } + *(u8 *)(pkt + 0x4) = *(u8 *)((s32)a0 + 0x24); + *(u8 *)(pkt + 0x5) = *(u8 *)((s32)a0 + 0x25); + *(u8 *)(pkt + 0x6) = *(u8 *)((s32)a0 + 0x26); + *(u8 *)(p1 + 0x4) = *(u8 *)((s32)a0 + 0x24); + *(u8 *)(p1 + 0x5) = *(u8 *)((s32)a0 + 0x25); + *(u8 *)(p1 + 0x6) = *(u8 *)((s32)a0 + 0x26); + + *(s16 *)(pkt + 0x8) = RD16(stk) + RD16(stk + 0x54); + *(s16 *)(pkt + 0xa) = RD16(stk + 0x02) + RD16(stk + 0x56); + *(s16 *)(pkt + 0xc) = RD16(stk) - (d >> 16); + *(s16 *)(pkt + 0xe) = RD16(stk + 0x02) + d; + *(s16 *)(pkt + 0x10) = RD16(stk) + (d >> 16); + *(s16 *)(pkt + 0x12) = RD16(stk + 0x02) - d; + *(s16 *)(pkt + 0x14) = RD16(stk) - RD16(stk + 0x54); + *(s16 *)(pkt + 0x16) = RD16(stk + 0x02) - RD16(stk + 0x56); + *(s16 *)(p1 + 0x8) = RD16(stk) - RD16(stk + 0x56); + *(s16 *)(p1 + 0xa) = RD16(stk + 0x02) + RD16(stk + 0x54); + *(s16 *)(p1 + 0xc) = RD16(stk) - d; + *(s16 *)(p1 + 0xe) = RD16(stk + 0x02) - (d >> 16); + *(s16 *)(p1 + 0x10) = RD16(stk) + d; + *(s16 *)(p1 + 0x12) = RD16(stk + 0x02) + (d >> 16); + *(s16 *)(p1 + 0x14) = RD16(stk) + RD16(stk + 0x56); + *(s16 *)(p1 + 0x16) = RD16(stk + 0x02) - RD16(stk + 0x54); + + /* addPrim(otp, pkt); addPrim(otp, p1); */ + otp = (u32 *)((idx << 2) + ot); + tv = RW32(pkt); + RW32(pkt) = (tv & 0xFF000000) | (RW32(otp) & 0xFFFFFF); + RW32(otp) = (RW32(otp) & 0xFF000000) | ((u32)pkt & 0xFFFFFF); + tv = RW32(p1); + RW32(p1) = (tv & 0xFF000000) | (RW32(otp) & 0xFFFFFF); + + pkb = D_800A5E60; + p2 = pkb + 0x30; + D_800A5E60 = p2; + RW32(otp) = (RW32(otp) & 0xFF000000) | ((u32)p1 & 0xFFFFFF); + + if (t2 != 0) { + D_800A5E60 = pkb + 0x38; + *(u8 *)(p2 + 3) = 1; + RW32(p2 + 4) = ((flags >> 23) & 0x60) | 0xE1000000; + tv2 = RW32(p2); + RW32(p2) = (tv2 & 0xFF000000) | (RW32(otp) & 0xFFFFFF); + RW32(otp) = (RW32(otp) & 0xFF000000) | ((u32)p2 & 0xFFFFFF); + } + } + } +} + // @class: loose-typing