mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-09-28 23:00:29 -04:00
feat(phase-30 S40): propagate the 19 wave exemplars — 61/87 members banked (+7,087 ins), R22 140/140
Propagation behind every crack, same session (the multiplier the waves exist for). 19 newly-banked exemplars from waves 1+2, all in the family_sweep lane (0 has_mid_jr): 87 candidate members / 10,212 ins -> 61 BANKED / 26 failed across 39 overlays The 26 that did not bank are the known plumbing shapes, not codegen: 20 CC1-FAIL + 5 callee `conflicting types` (func_8017EFA0 x3, func_8012B23C x2) -- the same classes the S40 recovery ladder already has levers for (§17a-1 no-proto + call-site cast; recover_giant block-scoping). Left open deliberately rather than force-banked (P9); they are the cheapest fuel on the board next session. TOOLING GAP RECORDED: the sweep's classifier writes "CC1-FAIL: make: *** Error 33" WITHOUT the actual cc1 message, so 20 of 26 failures carry no actionable reason. Diagnosing one currently requires manually splicing the draft into its TU and rebuilding (done twice this session). The classifier should capture cc1 stderr the way harvest_verify already does -- worth fixing before the next big sweep, or every CC1-FAIL costs a manual reproduction. VERIFIED: make clean && make extract-all && make check-all -> 140 passed, 0 failed of 140. Fleet 12425854 -> 12432941 instr (+7,087); distinct +6,145 / +51 uniq; fn-count +61. instr-weighted back to 94.5% ON THE HONEST (post-main-regen) denominator of 13,160,961. audit-digest OK. 0 NON_MATCHING (G4).
This commit is contained in:
@@ -497,7 +497,6 @@
|
||||
{"ts": "2026-07-14 22:58:06", "addr": null, "name": "func_8017DA9C", "reach": null, "klass": null, "nins": null, "status": "near", "closeness": 83, "where_stuck": "residual: 83 mismatch", "best_draft": ".run/backlog_drafts/func_8017DA9C.c", "binary": "ov_SC01_008", "source": "worker", "residual": null, "passes_tried": null}
|
||||
{"ts": "2026-07-14 22:58:06", "addr": null, "name": "func_8017DD18", "reach": null, "klass": null, "nins": null, "status": "near", "closeness": 21, "where_stuck": "residual: 21 mismatch", "best_draft": ".run/backlog_drafts/func_8017DD18.c", "binary": "ov_SC01_008", "source": "worker", "residual": null, "passes_tried": null}
|
||||
{"ts": "2026-07-14 22:58:32", "addr": null, "name": "func_8017D610", "reach": null, "klass": null, "nins": null, "status": "near", "closeness": 64, "where_stuck": "residual: 64 mismatch", "best_draft": ".run/backlog_drafts/func_8017D610.c", "binary": "ov_SC02_035", "source": "worker", "residual": null, "passes_tried": null}
|
||||
{"ts": "2026-07-14 22:58:32", "addr": null, "name": "func_8017F96C", "reach": null, "klass": null, "nins": null, "status": "near", "closeness": 106, "where_stuck": "residual: 106 mismatch", "best_draft": ".run/backlog_drafts/func_8017F96C.c", "binary": "ov_SC02_035", "source": "worker", "residual": null, "passes_tried": null}
|
||||
{"ts": "2026-07-14 22:59:00", "addr": null, "name": "func_80181A94", "reach": null, "klass": null, "nins": null, "status": "near", "closeness": 15, "where_stuck": "residual: 15 mismatch", "best_draft": ".run/backlog_drafts/func_80181A94.c", "binary": "ov_SC02_000", "source": "worker", "residual": null, "passes_tried": null}
|
||||
{"ts": "2026-07-14 22:59:00", "addr": null, "name": "func_80182E08", "reach": null, "klass": null, "nins": null, "status": "near", "closeness": 30, "where_stuck": "residual: 30 mismatch", "best_draft": ".run/backlog_drafts/func_80182E08.c", "binary": "ov_SC02_000", "source": "worker", "residual": null, "passes_tried": null}
|
||||
{"ts": "2026-07-14 22:59:00", "addr": null, "name": "func_80183018", "reach": null, "klass": null, "nins": null, "status": "near", "closeness": 32, "where_stuck": "residual: 32 mismatch", "best_draft": ".run/backlog_drafts/func_80183018.c", "binary": "ov_SC02_000", "source": "worker", "residual": null, "passes_tried": null}
|
||||
@@ -763,7 +762,6 @@
|
||||
{"ts": "2026-07-14 23:40:24", "addr": null, "name": "func_80183598", "reach": null, "klass": null, "nins": null, "status": "near", "closeness": 42, "where_stuck": "residual: 42 mismatch", "best_draft": ".run/backlog_drafts/func_80183598.c", "binary": "ov_SC06_024", "source": "worker", "residual": null, "passes_tried": null}
|
||||
{"ts": "2026-07-14 23:40:24", "addr": null, "name": "func_80183C58", "reach": null, "klass": null, "nins": null, "status": "near", "closeness": 17, "where_stuck": "residual: 17 mismatch", "best_draft": ".run/backlog_drafts/func_80183C58.c", "binary": "ov_SC06_024", "source": "worker", "residual": null, "passes_tried": null}
|
||||
{"ts": "2026-07-14 23:40:24", "addr": null, "name": "func_8018474C", "reach": null, "klass": null, "nins": null, "status": "near", "closeness": 76, "where_stuck": "residual: 76 mismatch", "best_draft": ".run/backlog_drafts/func_8018474C.c", "binary": "ov_SC06_024", "source": "worker", "residual": null, "passes_tried": null}
|
||||
{"ts": "2026-07-14 23:40:24", "addr": null, "name": "func_8018788C", "reach": null, "klass": null, "nins": null, "status": "near", "closeness": 113, "where_stuck": "residual: 113 mismatch", "best_draft": ".run/backlog_drafts/func_8018788C.c", "binary": "ov_SC06_024", "source": "worker", "residual": null, "passes_tried": null}
|
||||
{"ts": "2026-07-14 23:40:48", "addr": null, "name": "func_80182BC8", "reach": null, "klass": null, "nins": null, "status": "near", "closeness": 107, "where_stuck": "residual: 107 mismatch", "best_draft": ".run/backlog_drafts/func_80182BC8.c", "binary": "ov_SC06_029", "source": "worker", "residual": null, "passes_tried": null}
|
||||
{"ts": "2026-07-14 23:40:49", "addr": null, "name": "func_80183D84", "reach": null, "klass": null, "nins": null, "status": "near", "closeness": 192, "where_stuck": "residual: 192 mismatch", "best_draft": ".run/backlog_drafts/func_80183D84.c", "binary": "ov_SC06_029", "source": "worker", "residual": null, "passes_tried": null}
|
||||
{"ts": "2026-07-14 23:40:49", "addr": null, "name": "func_80186044", "reach": null, "klass": null, "nins": null, "status": "near", "closeness": 41, "where_stuck": "residual: 41 mismatch", "best_draft": ".run/backlog_drafts/func_80186044.c", "binary": "ov_SC06_029", "source": "worker", "residual": null, "passes_tried": null}
|
||||
|
||||
+90
-92
@@ -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:** 847 · by status {'near': 804, 'failed': 43} · by class {'regalloc-order': 8, 'struct': 6, 'plumbing': 3, 'schedule': 2, 'WAVE': 9, None: 808, 'other': 1, 'STRUCT': 10}
|
||||
**Open near-misses:** 845 · by status {'near': 802, 'failed': 43} · by class {'regalloc-order': 8, 'struct': 6, 'plumbing': 3, 'schedule': 2, 'WAVE': 9, None: 806, 'other': 1, 'STRUCT': 10}
|
||||
|
||||
| # | addr | reach | class | nins | status | closeness | where it stuck | best draft |
|
||||
|--:|------|------:|-------|-----:|--------|----------:|----------------|------------|
|
||||
@@ -762,94 +762,92 @@
|
||||
| 754 | func_8017D808 | None | | None | near | 102 | residual: 102 mismatch | `.run/backlog_drafts/func_8017D808.c` |
|
||||
| 755 | func_80182D10 | None | | None | near | 102 | residual: 102 mismatch | `.run/backlog_drafts/func_80182D10.c` |
|
||||
| 756 | func_8017DC40 | None | | None | near | 104 | residual: 104 mismatch | `.run/backlog_drafts/func_8017DC40.c` |
|
||||
| 757 | func_8017F96C | None | | None | near | 106 | residual: 106 mismatch | `.run/backlog_drafts/func_8017F96C.c` |
|
||||
| 758 | func_8017EFEC | None | | None | near | 107 | residual: 107 mismatch | `.run/backlog_drafts/func_8017EFEC.c` |
|
||||
| 759 | func_80182BC8 | None | | None | near | 107 | residual: 107 mismatch | `.run/backlog_drafts/func_80182BC8.c` |
|
||||
| 760 | func_8017F69C | None | | None | near | 107 | residual: 107 mismatch | `.run/backlog_drafts/func_8017F69C.c` |
|
||||
| 761 | func_80184828 | None | | None | near | 109 | residual: 109 mismatch | `.run/backlog_drafts/func_80184828.c` |
|
||||
| 762 | func_8017F3E4 | None | | None | near | 110 | residual: 110 mismatch | `.run/backlog_drafts/func_8017F3E4.c` |
|
||||
| 763 | func_80181948 | 1 | STRUCT | 132 | near | 111 | STRUCT: 111 mismatch | `.run/backlog_drafts/func_80181948.c` |
|
||||
| 764 | func_8017DAF4 | None | | None | near | 111 | residual: 111 mismatch | `.run/backlog_drafts/func_8017DAF4.c` |
|
||||
| 765 | func_8017FE9C | None | | None | near | 111 | residual: 111 mismatch | `.run/backlog_drafts/func_8017FE9C.c` |
|
||||
| 766 | func_8017F768 | None | | None | near | 112 | residual: 112 mismatch | `.run/backlog_drafts/func_8017F768.c` |
|
||||
| 767 | func_8017F3B8 | None | | None | near | 112 | residual: 112 mismatch | `.run/backlog_drafts/func_8017F3B8.c` |
|
||||
| 768 | func_8017D508 | None | | None | near | 113 | residual: 113 mismatch | `.run/backlog_drafts/func_8017D508.c` |
|
||||
| 769 | func_8018788C | None | | None | near | 113 | residual: 113 mismatch | `.run/backlog_drafts/func_8018788C.c` |
|
||||
| 770 | func_80180C90 | 1 | STRUCT | 160 | near | 116 | STRUCT: 116 mismatch | `.run/backlog_drafts/func_80180C90.c` |
|
||||
| 771 | func_80181858 | None | | None | near | 117 | residual: 117 mismatch | `.run/backlog_drafts/func_80181858.c` |
|
||||
| 772 | func_8017E8F8 | None | | None | near | 120 | residual: 120 mismatch | `.run/backlog_drafts/func_8017E8F8.c` |
|
||||
| 773 | func_80184358 | None | | None | near | 121 | residual: 121 mismatch | `.run/backlog_drafts/func_80184358.c` |
|
||||
| 774 | func_8017F074 | None | | None | near | 121 | residual: 121 mismatch | `.run/backlog_drafts/func_8017F074.c` |
|
||||
| 775 | func_8017D890 | None | | None | near | 124 | residual: 124 mismatch | `.run/backlog_drafts/func_8017D890.c` |
|
||||
| 776 | func_8017DECC | None | | None | near | 125 | residual: 125 mismatch | `.run/backlog_drafts/func_8017DECC.c` |
|
||||
| 777 | func_80185020 | None | | None | near | 125 | residual: 125 mismatch | `.run/backlog_drafts/func_80185020.c` |
|
||||
| 778 | func_801892CC | None | | None | near | 127 | residual: 127 mismatch | `.run/backlog_drafts/func_801892CC.c` |
|
||||
| 779 | func_8017EB00 | None | | None | near | 127 | residual: 127 mismatch | `.run/backlog_drafts/func_8017EB00.c` |
|
||||
| 780 | func_80185E68 | 1 | STRUCT | 132 | near | 131 | STRUCT: 131 mismatch | `.run/backlog_drafts/func_80185E68.c` |
|
||||
| 781 | func_8017E378 | None | | None | near | 134 | residual: 134 mismatch | `.run/backlog_drafts/func_8017E378.c` |
|
||||
| 782 | func_80186530 | None | | None | near | 139 | residual: 139 mismatch | `.run/backlog_drafts/func_80186530.c` |
|
||||
| 783 | func_80186078 | 1 | WAVE | 174 | near | 141 | WAVE: 141 mismatch | `.run/backlog_drafts/func_80186078.c` |
|
||||
| 784 | func_80184F08 | None | regalloc-order | None | near | 141 | none — MATCH (145/145 ins, match_one confirmed) | `.run/backlog_drafts/func_80184F08.c` |
|
||||
| 785 | func_80185668 | None | | None | near | 142 | residual: 142 mismatch | `.run/backlog_drafts/func_80185668.c` |
|
||||
| 786 | func_8017DB0C | None | | None | near | 142 | residual: 142 mismatch | `.run/backlog_drafts/func_8017DB0C.c` |
|
||||
| 787 | func_80181984 | None | | None | near | 153 | residual: 153 mismatch | `.run/backlog_drafts/func_80181984.c` |
|
||||
| 788 | func_8017E6EC | None | | None | near | 172 | residual: 172 mismatch | `.run/backlog_drafts/func_8017E6EC.c` |
|
||||
| 789 | func_80181BE4 | 1 | STRUCT | 201 | near | 173 | STRUCT: 173 mismatch | `.run/backlog_drafts/func_80181BE4.c` |
|
||||
| 790 | func_80184210 | None | | None | near | 176 | residual: 176 mismatch | `.run/backlog_drafts/func_80184210.c` |
|
||||
| 791 | func_80180568 | None | | None | near | 185 | residual: 185 mismatch | `.run/backlog_drafts/func_80180568.c` |
|
||||
| 792 | func_801809C4 | None | | None | near | 190 | residual: 190 mismatch | `.run/backlog_drafts/func_801809C4.c` |
|
||||
| 793 | func_80183D84 | None | | None | near | 192 | residual: 192 mismatch | `.run/backlog_drafts/func_80183D84.c` |
|
||||
| 794 | func_80183FEC | None | | None | near | 198 | residual: 198 mismatch | `.run/backlog_drafts/func_80183FEC.c` |
|
||||
| 795 | func_801823B8 | None | | None | near | 204 | residual: 204 mismatch | `.run/backlog_drafts/func_801823B8.c` |
|
||||
| 796 | func_801826C4 | None | | None | near | 207 | residual: 207 mismatch | `.run/backlog_drafts/func_801826C4.c` |
|
||||
| 797 | func_8018C3F8 | None | | None | near | 236 | residual: 236 mismatch | `.run/backlog_drafts/func_8018C3F8.c` |
|
||||
| 798 | func_8017FD14 | 1 | STRUCT | 249 | near | 240 | STRUCT: 240 mismatch | `.run/backlog_drafts/func_8017FD14.c` |
|
||||
| 799 | func_8017E7D4 | None | | None | near | 241 | residual: 241 mismatch | `.run/backlog_drafts/func_8017E7D4.c` |
|
||||
| 800 | func_80183BF8 | None | | None | near | 258 | residual: 258 mismatch | `.run/backlog_drafts/func_80183BF8.c` |
|
||||
| 801 | func_8017EB30 | None | | None | near | 278 | residual: 278 mismatch | `.run/backlog_drafts/func_8017EB30.c` |
|
||||
| 802 | func_801804A0 | None | | None | near | 280 | residual: 280 mismatch | `.run/backlog_drafts/func_801804A0.c` |
|
||||
| 803 | func_80181670 | None | | None | near | 311 | residual: 311 mismatch | `.run/backlog_drafts/func_80181670.c` |
|
||||
| 804 | func_8018057C | None | | None | near | 897 | residual: 897 mismatch | `.run/backlog_drafts/func_8018057C.c` |
|
||||
| 805 | func_80128CFC | 1 | WAVE | 25 | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80128CFC.c` |
|
||||
| 806 | func_80184A68 | 1 | regalloc-order | 33 | failed | | none — MATCH | `.run/backlog_drafts/func_80184A68.c` |
|
||||
| 807 | func_80180B64 | 1 | struct | 75 | failed | | none — MATCH (75 ins, relocation-masked) | `.run/backlog_drafts/func_80180B64.c` |
|
||||
| 808 | func_80183DE0 | 1 | regalloc-order | 91 | failed | | testing if(!=1) layout + counter-before-pointer init order | `.run/backlog_drafts/func_80183DE0.c` |
|
||||
| 809 | func_80185BA4 | 1 | WAVE | 177 | failed | | won't compile standalone (loose-typing / missing decl) | |
|
||||
| 810 | func_80183324 | 1 | STRUCT | 324 | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80183324.c` |
|
||||
| 811 | func_8017D8DC | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017D8DC.c` |
|
||||
| 812 | func_8017FFEC | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017FFEC.c` |
|
||||
| 813 | func_8017DC18 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017DC18.c` |
|
||||
| 814 | func_801853CC | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801853CC.c` |
|
||||
| 815 | func_80181894 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80181894.c` |
|
||||
| 816 | func_8018BFBC | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8018BFBC.c` |
|
||||
| 817 | func_801807F4 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801807F4.c` |
|
||||
| 818 | func_8017FFC8 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017FFC8.c` |
|
||||
| 819 | func_8017E99C | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017E99C.c` |
|
||||
| 820 | func_80180294 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80180294.c` |
|
||||
| 821 | func_8017E76C | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017E76C.c` |
|
||||
| 822 | func_8017F29C | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017F29C.c` |
|
||||
| 823 | func_8017F00C | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017F00C.c` |
|
||||
| 824 | func_801802B0 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801802B0.c` |
|
||||
| 825 | func_8017DA1C | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017DA1C.c` |
|
||||
| 826 | func_8017FFC4 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017FFC4.c` |
|
||||
| 827 | func_8017E2F0 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017E2F0.c` |
|
||||
| 828 | func_801841E4 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801841E4.c` |
|
||||
| 829 | func_80181738 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80181738.c` |
|
||||
| 830 | func_801873D8 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801873D8.c` |
|
||||
| 831 | func_80185628 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80185628.c` |
|
||||
| 832 | func_80181A78 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80181A78.c` |
|
||||
| 833 | func_801805D4 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801805D4.c` |
|
||||
| 834 | func_8017EA1C | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017EA1C.c` |
|
||||
| 835 | func_8017F098 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017F098.c` |
|
||||
| 836 | func_801822CC | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801822CC.c` |
|
||||
| 837 | func_8017E3F4 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017E3F4.c` |
|
||||
| 838 | func_800D1658 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_800D1658.c` |
|
||||
| 839 | func_800D1984 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_800D1984.c` |
|
||||
| 840 | func_800D24A0 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_800D24A0.c` |
|
||||
| 841 | func_8013DD68 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8013DD68.c` |
|
||||
| 842 | func_80132018 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80132018.c` |
|
||||
| 843 | func_80181164 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80181164.c` |
|
||||
| 844 | func_8012D664 | None | schedule | None | failed | | none — MATCH | `.run/backlog_drafts/func_8012D664.c` |
|
||||
| 845 | func_80136C90 | None | struct | None | failed | | none — MATCH (28 ins). 10-byte 1-aligned struct copy (S10{char s[10]}) from global D_801A5A7C into a stack buffer, then ((void(*)(int, void *, int, int, int, int))func_8001534C)(0,&buf,0x78,0x10,0,0). gcc emits the block move as 2 unaligned words (lwl/lwr+swl/swr) + 2 bytes (lb/sb). | `.run/backlog_drafts/func_80136C90.c` |
|
||||
| 846 | func_80145CEC | None | struct | None | failed | | 2 residuals — (1) target RELOADS global ptr ((s32 *)&D_80126B78) before each of its 5 field accesses (f28/f18/f1a/f1c/f2c); gcc-2.7.2 CSEs the single pointer load in every clean-C form I tried (int-cast, (s8*)/(s32) M2C_FIELD, struct*), keeping ONE load. volatile forces reloads but hoists them + leaves delay-slot nops the target fills (target is NOT volatile). (2) frame 0x20 not 0x18: target reserves an unused 8-byte stack local @0x10 (address-taken local — reproduced, but every code-free escape optimizes away and a visible escape corrupts the ((int (*)(void))func_80145EE8)(0) arg). Structure/order/values/callees all match; only the alias-driven reload chain + the phantom frame local remain. Family exemplar (~130 overlays). | `.run/backlog_drafts/func_80145CEC.c` |
|
||||
| 847 | func_8016BCC0 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8016BCC0.c` |
|
||||
| 757 | func_8017EFEC | None | | None | near | 107 | residual: 107 mismatch | `.run/backlog_drafts/func_8017EFEC.c` |
|
||||
| 758 | func_80182BC8 | None | | None | near | 107 | residual: 107 mismatch | `.run/backlog_drafts/func_80182BC8.c` |
|
||||
| 759 | func_8017F69C | None | | None | near | 107 | residual: 107 mismatch | `.run/backlog_drafts/func_8017F69C.c` |
|
||||
| 760 | func_80184828 | None | | None | near | 109 | residual: 109 mismatch | `.run/backlog_drafts/func_80184828.c` |
|
||||
| 761 | func_8017F3E4 | None | | None | near | 110 | residual: 110 mismatch | `.run/backlog_drafts/func_8017F3E4.c` |
|
||||
| 762 | func_80181948 | 1 | STRUCT | 132 | near | 111 | STRUCT: 111 mismatch | `.run/backlog_drafts/func_80181948.c` |
|
||||
| 763 | func_8017DAF4 | None | | None | near | 111 | residual: 111 mismatch | `.run/backlog_drafts/func_8017DAF4.c` |
|
||||
| 764 | func_8017FE9C | None | | None | near | 111 | residual: 111 mismatch | `.run/backlog_drafts/func_8017FE9C.c` |
|
||||
| 765 | func_8017F768 | None | | None | near | 112 | residual: 112 mismatch | `.run/backlog_drafts/func_8017F768.c` |
|
||||
| 766 | func_8017F3B8 | None | | None | near | 112 | residual: 112 mismatch | `.run/backlog_drafts/func_8017F3B8.c` |
|
||||
| 767 | func_8017D508 | None | | None | near | 113 | residual: 113 mismatch | `.run/backlog_drafts/func_8017D508.c` |
|
||||
| 768 | func_80180C90 | 1 | STRUCT | 160 | near | 116 | STRUCT: 116 mismatch | `.run/backlog_drafts/func_80180C90.c` |
|
||||
| 769 | func_80181858 | None | | None | near | 117 | residual: 117 mismatch | `.run/backlog_drafts/func_80181858.c` |
|
||||
| 770 | func_8017E8F8 | None | | None | near | 120 | residual: 120 mismatch | `.run/backlog_drafts/func_8017E8F8.c` |
|
||||
| 771 | func_80184358 | None | | None | near | 121 | residual: 121 mismatch | `.run/backlog_drafts/func_80184358.c` |
|
||||
| 772 | func_8017F074 | None | | None | near | 121 | residual: 121 mismatch | `.run/backlog_drafts/func_8017F074.c` |
|
||||
| 773 | func_8017D890 | None | | None | near | 124 | residual: 124 mismatch | `.run/backlog_drafts/func_8017D890.c` |
|
||||
| 774 | func_8017DECC | None | | None | near | 125 | residual: 125 mismatch | `.run/backlog_drafts/func_8017DECC.c` |
|
||||
| 775 | func_80185020 | None | | None | near | 125 | residual: 125 mismatch | `.run/backlog_drafts/func_80185020.c` |
|
||||
| 776 | func_801892CC | None | | None | near | 127 | residual: 127 mismatch | `.run/backlog_drafts/func_801892CC.c` |
|
||||
| 777 | func_8017EB00 | None | | None | near | 127 | residual: 127 mismatch | `.run/backlog_drafts/func_8017EB00.c` |
|
||||
| 778 | func_80185E68 | 1 | STRUCT | 132 | near | 131 | STRUCT: 131 mismatch | `.run/backlog_drafts/func_80185E68.c` |
|
||||
| 779 | func_8017E378 | None | | None | near | 134 | residual: 134 mismatch | `.run/backlog_drafts/func_8017E378.c` |
|
||||
| 780 | func_80186530 | None | | None | near | 139 | residual: 139 mismatch | `.run/backlog_drafts/func_80186530.c` |
|
||||
| 781 | func_80186078 | 1 | WAVE | 174 | near | 141 | WAVE: 141 mismatch | `.run/backlog_drafts/func_80186078.c` |
|
||||
| 782 | func_80184F08 | None | regalloc-order | None | near | 141 | none — MATCH (145/145 ins, match_one confirmed) | `.run/backlog_drafts/func_80184F08.c` |
|
||||
| 783 | func_80185668 | None | | None | near | 142 | residual: 142 mismatch | `.run/backlog_drafts/func_80185668.c` |
|
||||
| 784 | func_8017DB0C | None | | None | near | 142 | residual: 142 mismatch | `.run/backlog_drafts/func_8017DB0C.c` |
|
||||
| 785 | func_80181984 | None | | None | near | 153 | residual: 153 mismatch | `.run/backlog_drafts/func_80181984.c` |
|
||||
| 786 | func_8017E6EC | None | | None | near | 172 | residual: 172 mismatch | `.run/backlog_drafts/func_8017E6EC.c` |
|
||||
| 787 | func_80181BE4 | 1 | STRUCT | 201 | near | 173 | STRUCT: 173 mismatch | `.run/backlog_drafts/func_80181BE4.c` |
|
||||
| 788 | func_80184210 | None | | None | near | 176 | residual: 176 mismatch | `.run/backlog_drafts/func_80184210.c` |
|
||||
| 789 | func_80180568 | None | | None | near | 185 | residual: 185 mismatch | `.run/backlog_drafts/func_80180568.c` |
|
||||
| 790 | func_801809C4 | None | | None | near | 190 | residual: 190 mismatch | `.run/backlog_drafts/func_801809C4.c` |
|
||||
| 791 | func_80183D84 | None | | None | near | 192 | residual: 192 mismatch | `.run/backlog_drafts/func_80183D84.c` |
|
||||
| 792 | func_80183FEC | None | | None | near | 198 | residual: 198 mismatch | `.run/backlog_drafts/func_80183FEC.c` |
|
||||
| 793 | func_801823B8 | None | | None | near | 204 | residual: 204 mismatch | `.run/backlog_drafts/func_801823B8.c` |
|
||||
| 794 | func_801826C4 | None | | None | near | 207 | residual: 207 mismatch | `.run/backlog_drafts/func_801826C4.c` |
|
||||
| 795 | func_8018C3F8 | None | | None | near | 236 | residual: 236 mismatch | `.run/backlog_drafts/func_8018C3F8.c` |
|
||||
| 796 | func_8017FD14 | 1 | STRUCT | 249 | near | 240 | STRUCT: 240 mismatch | `.run/backlog_drafts/func_8017FD14.c` |
|
||||
| 797 | func_8017E7D4 | None | | None | near | 241 | residual: 241 mismatch | `.run/backlog_drafts/func_8017E7D4.c` |
|
||||
| 798 | func_80183BF8 | None | | None | near | 258 | residual: 258 mismatch | `.run/backlog_drafts/func_80183BF8.c` |
|
||||
| 799 | func_8017EB30 | None | | None | near | 278 | residual: 278 mismatch | `.run/backlog_drafts/func_8017EB30.c` |
|
||||
| 800 | func_801804A0 | None | | None | near | 280 | residual: 280 mismatch | `.run/backlog_drafts/func_801804A0.c` |
|
||||
| 801 | func_80181670 | None | | None | near | 311 | residual: 311 mismatch | `.run/backlog_drafts/func_80181670.c` |
|
||||
| 802 | func_8018057C | None | | None | near | 897 | residual: 897 mismatch | `.run/backlog_drafts/func_8018057C.c` |
|
||||
| 803 | func_80128CFC | 1 | WAVE | 25 | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80128CFC.c` |
|
||||
| 804 | func_80184A68 | 1 | regalloc-order | 33 | failed | | none — MATCH | `.run/backlog_drafts/func_80184A68.c` |
|
||||
| 805 | func_80180B64 | 1 | struct | 75 | failed | | none — MATCH (75 ins, relocation-masked) | `.run/backlog_drafts/func_80180B64.c` |
|
||||
| 806 | func_80183DE0 | 1 | regalloc-order | 91 | failed | | testing if(!=1) layout + counter-before-pointer init order | `.run/backlog_drafts/func_80183DE0.c` |
|
||||
| 807 | func_80185BA4 | 1 | WAVE | 177 | failed | | won't compile standalone (loose-typing / missing decl) | |
|
||||
| 808 | func_80183324 | 1 | STRUCT | 324 | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80183324.c` |
|
||||
| 809 | func_8017D8DC | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017D8DC.c` |
|
||||
| 810 | func_8017FFEC | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017FFEC.c` |
|
||||
| 811 | func_8017DC18 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017DC18.c` |
|
||||
| 812 | func_801853CC | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801853CC.c` |
|
||||
| 813 | func_80181894 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80181894.c` |
|
||||
| 814 | func_8018BFBC | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8018BFBC.c` |
|
||||
| 815 | func_801807F4 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801807F4.c` |
|
||||
| 816 | func_8017FFC8 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017FFC8.c` |
|
||||
| 817 | func_8017E99C | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017E99C.c` |
|
||||
| 818 | func_80180294 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80180294.c` |
|
||||
| 819 | func_8017E76C | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017E76C.c` |
|
||||
| 820 | func_8017F29C | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017F29C.c` |
|
||||
| 821 | func_8017F00C | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017F00C.c` |
|
||||
| 822 | func_801802B0 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801802B0.c` |
|
||||
| 823 | func_8017DA1C | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017DA1C.c` |
|
||||
| 824 | func_8017FFC4 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017FFC4.c` |
|
||||
| 825 | func_8017E2F0 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017E2F0.c` |
|
||||
| 826 | func_801841E4 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801841E4.c` |
|
||||
| 827 | func_80181738 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80181738.c` |
|
||||
| 828 | func_801873D8 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801873D8.c` |
|
||||
| 829 | func_80185628 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80185628.c` |
|
||||
| 830 | func_80181A78 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80181A78.c` |
|
||||
| 831 | func_801805D4 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801805D4.c` |
|
||||
| 832 | func_8017EA1C | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017EA1C.c` |
|
||||
| 833 | func_8017F098 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017F098.c` |
|
||||
| 834 | func_801822CC | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_801822CC.c` |
|
||||
| 835 | func_8017E3F4 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8017E3F4.c` |
|
||||
| 836 | func_800D1658 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_800D1658.c` |
|
||||
| 837 | func_800D1984 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_800D1984.c` |
|
||||
| 838 | func_800D24A0 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_800D24A0.c` |
|
||||
| 839 | func_8013DD68 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8013DD68.c` |
|
||||
| 840 | func_80132018 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80132018.c` |
|
||||
| 841 | func_80181164 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_80181164.c` |
|
||||
| 842 | func_8012D664 | None | schedule | None | failed | | none — MATCH | `.run/backlog_drafts/func_8012D664.c` |
|
||||
| 843 | func_80136C90 | None | struct | None | failed | | none — MATCH (28 ins). 10-byte 1-aligned struct copy (S10{char s[10]}) from global D_801A5A7C into a stack buffer, then ((void(*)(int, void *, int, int, int, int))func_8001534C)(0,&buf,0x78,0x10,0,0). gcc emits the block move as 2 unaligned words (lwl/lwr+swl/swr) + 2 bytes (lb/sb). | `.run/backlog_drafts/func_80136C90.c` |
|
||||
| 844 | func_80145CEC | None | struct | None | failed | | 2 residuals — (1) target RELOADS global ptr ((s32 *)&D_80126B78) before each of its 5 field accesses (f28/f18/f1a/f1c/f2c); gcc-2.7.2 CSEs the single pointer load in every clean-C form I tried (int-cast, (s8*)/(s32) M2C_FIELD, struct*), keeping ONE load. volatile forces reloads but hoists them + leaves delay-slot nops the target fills (target is NOT volatile). (2) frame 0x20 not 0x18: target reserves an unused 8-byte stack local @0x10 (address-taken local — reproduced, but every code-free escape optimizes away and a visible escape corrupts the ((int (*)(void))func_80145EE8)(0) arg). Structure/order/values/callees all match; only the alias-driven reload chain + the phantom frame local remain. Family exemplar (~130 overlays). | `.run/backlog_drafts/func_80145CEC.c` |
|
||||
| 845 | func_8016BCC0 | None | | None | failed | | won't compile standalone (loose-typing / missing decl) | `.run/backlog_drafts/func_8016BCC0.c` |
|
||||
|
||||
+23
-23
@@ -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:1461` · 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:1464` · 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.8% fn / 95.0% instr / 90.2% distinct-code matched. Unmatched: 11,274 instances / 659,985 ins (9,467 distinct classes).
|
||||
**Fleet (overlays):** 96.8% fn / 95.0% instr / 90.3% distinct-code matched. Unmatched: 11,231 instances / 654,506 ins (9,424 distinct classes).
|
||||
|
||||
**Tail cross-check (Phase-25 close):** 7,355 tail fns / 370,451 ins → 417 h_seq families ≥2, **99 substantial (nins≥80) / 66,568 ins**.
|
||||
**Tail cross-check (Phase-25 close):** 7,341 tail fns / 370,259 ins → 417 h_seq families ≥2, **99 substantial (nins≥80) / 66,568 ins**.
|
||||
|
||||
**Full frontier (all unmatched by h_seq):** 1979 target families (≥2 members or a matched sibling) + 3766 singletons (Step-D residue). Substantial: **345 families / 219,759 templatable ins**, 28 with a matched sibling (zero-crack). Substantial member classes: 1,385 PURE · 23 IMM · 6 STRUCT-excluded.
|
||||
**Full frontier (all unmatched by h_seq):** 1974 target families (≥2 members or a matched sibling) + 3766 singletons (Step-D residue). Substantial: **340 families / 214,280 templatable ins**, 42 with a matched sibling (zero-crack). Substantial member classes: 1,342 PURE · 23 IMM · 6 STRUCT-excluded.
|
||||
|
||||
|
||||
## Top substantial families (by templatable byte-weight)
|
||||
@@ -46,22 +46,22 @@
|
||||
| 29 | 255 | 3 (3/0/0) | 3/3 | cross-address | PURE | 0 | · | 0x8018e9bc modal | 765 |
|
||||
| 30 | 254 | 3 (3/0/0) | 3/3 | cross-address | PURE | 0 | · | 0x80192768 modal | 762 |
|
||||
| 31 | 188 | 4 (4/0/0) | 1/4 | per-location | PURE | 134 | Y | 0x8016ab6c matched-ov077 | 752 |
|
||||
| 32 | 107 | 7 (7/0/0) | 7/7 | cross-address | PURE | 0 | · | 0x8017ef54 modal | 749 |
|
||||
| 33 | 187 | 4 (4/0/0) | 1/4 | per-location | PURE | 134 | · | 0x8013dd68 matched-ov077 | 748 |
|
||||
| 34 | 248 | 3 (3/0/0) | 3/3 | cross-address | PURE | 0 | · | 0x8018e5dc modal | 744 |
|
||||
| 35 | 186 | 4 (4/0/0) | 4/1 | cross-address | PURE | 0 | · | 0x801802ec modal | 744 |
|
||||
| 36 | 147 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | Y | 0x8017ed5c modal | 735 |
|
||||
| 37 | 181 | 4 (4/0/0) | 4/4 | cross-address | PURE | 0 | · | 0x8017d7c0 modal | 724 |
|
||||
| 38 | 144 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | · | 0x80188778 modal | 720 |
|
||||
| 39 | 710 | 1 (1/0/0) | 1/1 | per-location | PURE | 2 | Y | 0x80191c50 matched | 710 |
|
||||
| 40 | 171 | 4 (4/0/0) | 4/4 | cross-address | PURE | 0 | · | 0x80183fe0 modal | 684 |
|
||||
| 41 | 341 | 2 (2/0/0) | 1/2 | per-location | PURE | 0 | · | 0x80184bd8 modal | 682 |
|
||||
| 42 | 85 | 8 (8/0/0) | 8/8 | cross-address | PURE | 1 | · | 0x801822e0 matched | 680 |
|
||||
| 43 | 85 | 8 (8/0/0) | 8/8 | cross-address | PURE | 0 | · | 0x80182b90 modal | 680 |
|
||||
| 44 | 113 | 6 (6/0/0) | 6/6 | cross-address | PURE | 0 | · | 0x80187320 modal | 678 |
|
||||
| 45 | 226 | 3 (3/0/0) | 3/3 | cross-address | PURE | 0 | · | 0x80192f64 modal | 678 |
|
||||
| 46 | 134 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | Y | 0x8017eb44 modal | 670 |
|
||||
| 47 | 133 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | · | 0x80189ea0 modal | 665 |
|
||||
| 48 | 110 | 6 (6/0/0) | 6/6 | cross-address | PURE | 0 | · | 0x80188b9c modal | 660 |
|
||||
| 49 | 93 | 7 (7/0/0) | 2/7 | cross-address | PURE | 0 | · | 0x8017c6a0 modal | 651 |
|
||||
| 50 | 93 | 7 (7/0/0) | 7/7 | cross-address | PURE | 0 | · | 0x8017fb10 modal | 651 |
|
||||
| 32 | 187 | 4 (4/0/0) | 1/4 | per-location | PURE | 134 | · | 0x8013dd68 matched-ov077 | 748 |
|
||||
| 33 | 147 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | Y | 0x8017ed5c modal | 735 |
|
||||
| 34 | 181 | 4 (4/0/0) | 4/4 | cross-address | PURE | 0 | · | 0x8017d7c0 modal | 724 |
|
||||
| 35 | 710 | 1 (1/0/0) | 1/1 | per-location | PURE | 2 | Y | 0x80191c50 matched | 710 |
|
||||
| 36 | 341 | 2 (2/0/0) | 1/2 | per-location | PURE | 0 | · | 0x80184bd8 modal | 682 |
|
||||
| 37 | 134 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | Y | 0x8017eb44 modal | 670 |
|
||||
| 38 | 93 | 7 (7/0/0) | 2/7 | cross-address | PURE | 0 | · | 0x8017c6a0 modal | 651 |
|
||||
| 39 | 108 | 6 (6/0/0) | 6/6 | cross-address | PURE | 0 | Y | 0x8017eeec modal | 648 |
|
||||
| 40 | 107 | 6 (6/0/0) | 6/6 | cross-address | PURE | 1 | · | 0x8017ef54 matched | 642 |
|
||||
| 41 | 320 | 2 (2/0/0) | 1/2 | per-location | PURE | 0 | · | 0x80181b00 modal | 640 |
|
||||
| 42 | 317 | 2 (2/0/0) | 2/1 | cross-address | PURE | 0 | · | 0x8017fdf8 modal | 634 |
|
||||
| 43 | 211 | 3 (3/0/0) | 3/3 | cross-address | PURE | 0 | · | 0x8018e8a0 modal | 633 |
|
||||
| 44 | 207 | 3 (3/0/0) | 3/3 | cross-address | PURE | 2 | · | 0x801880ec matched | 621 |
|
||||
| 45 | 124 | 5 (5/0/0) | 4/5 | cross-address | PURE | 0 | · | 0x8017defc modal | 620 |
|
||||
| 46 | 154 | 4 (4/0/0) | 4/4 | cross-address | PURE | 0 | Y | 0x801844c8 modal | 616 |
|
||||
| 47 | 203 | 3 (0/3/0) | 2/3 | cross-address | IMM | 7 | · | 0x8017e804 matched | 609 |
|
||||
| 48 | 304 | 2 (2/0/0) | 1/2 | per-location | PURE | 0 | · | 0x80185ef8 modal | 608 |
|
||||
| 49 | 101 | 6 (3/3/0) | 6/3 | cross-address | IMM | 0 | · | 0x8018de60 modal | 606 |
|
||||
| 50 | 201 | 3 (3/0/0) | 2/3 | cross-address | PURE | 0 | Y | 0x80181be4 draft-ov077 | 603 |
|
||||
|
||||
+40
-40
@@ -4,16 +4,16 @@
|
||||
# cross-binary collapsible-byte leverage: docs/duplicates.cross.md.
|
||||
|
||||
# THREE progress metrics (all matter — see the labels):
|
||||
FLEET fn-count byte-ident: 341431 / 353717 = 96.53% (REAL+LINKED+empties; FUNCTION-count, ×134-inflated — one crack counts per overlay)
|
||||
FLEET instr-weighted : 12425854 / 13160961 = 94.4% (shipped .text across main + resident + 138 overlays; the decomp.dev-DISPLAY number)
|
||||
FLEET distinct-code(uniq): 5035626 / 5654184 = 89.1% (78021/87459 unique fns; the DISTINCT-RE number)
|
||||
FLEET fn-count byte-ident: 341492 / 353717 = 96.54% (REAL+LINKED+empties; FUNCTION-count, ×134-inflated — one crack counts per overlay)
|
||||
FLEET instr-weighted : 12432941 / 13160961 = 94.5% (shipped .text across main + resident + 138 overlays; the decomp.dev-DISPLAY number)
|
||||
FLEET distinct-code(uniq): 5041771 / 5654184 = 89.2% (78072/87459 unique fns; the DISTINCT-RE number)
|
||||
MAIN game-code weighted : 436 / 79510 = 0.5% (INCLUDED in the fleet numbers above since 2026-07-22 — roadmap §1 metrics contract; LINKED-excluding Ghidra sig dated 2026-08-05; 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: 12425418 / 13081451 = 95.0%)
|
||||
(fleet EXCLUDING main, for continuity with pre-2026-07-22 readings: 12432505 / 13081451 = 95.0%)
|
||||
|
||||
FLEET REAL substantive : 339576 (of which dedup-shared 241439 via 1919 groups / 241513 instances)
|
||||
FLEET REAL substantive : 339637 (of which dedup-shared 241439 via 1919 groups / 241513 instances)
|
||||
FLEET LINKED PsyQ objs : 959
|
||||
FLEET NON_MATCHING : 7 (0 in any default build — G4)
|
||||
FLEET INCLUDE_ASM stubs : 12279
|
||||
FLEET INCLUDE_ASM stubs : 12218
|
||||
FLEET matchable : 353717
|
||||
|
||||
| binary | REAL | shared | LINKED | byte-ident | matchable | byte-ident % |
|
||||
@@ -37,14 +37,14 @@ FLEET matchable : 353717
|
||||
| ov_SC02_005 | 2536 | 1747 | 0 | 2546 | 2927 | 87.0% |
|
||||
| ov_SC02_011 | 2624 | 1754 | 0 | 2635 | 2893 | 91.1% |
|
||||
| ov_SC02_015 | 2397 | 1753 | 0 | 2397 | 2414 | 99.3% |
|
||||
| ov_SC02_016 | 2479 | 1754 | 0 | 2482 | 2545 | 97.5% |
|
||||
| ov_SC02_016 | 2480 | 1754 | 0 | 2483 | 2545 | 97.6% |
|
||||
| ov_SC02_017 | 2548 | 1754 | 0 | 2556 | 2732 | 93.6% |
|
||||
| ov_SC02_021 | 2402 | 1753 | 0 | 2402 | 2437 | 98.6% |
|
||||
| ov_SC02_026 | 2500 | 1751 | 0 | 2506 | 2572 | 97.4% |
|
||||
| ov_SC02_027 | 2556 | 1751 | 0 | 2565 | 2692 | 95.3% |
|
||||
| ov_SC02_028 | 2561 | 1751 | 0 | 2571 | 2701 | 95.2% |
|
||||
| ov_SC02_031 | 2491 | 1752 | 0 | 2496 | 2562 | 97.4% |
|
||||
| ov_SC02_035 | 2483 | 1751 | 0 | 2486 | 2520 | 98.7% |
|
||||
| ov_SC02_035 | 2485 | 1751 | 0 | 2488 | 2520 | 98.7% |
|
||||
| ov_SC02_039 | 2392 | 1751 | 0 | 2392 | 2416 | 99.0% |
|
||||
| ov_SC02_041 | 2473 | 1751 | 0 | 2476 | 2561 | 96.7% |
|
||||
| ov_SC03_001 | 2667 | 1752 | 0 | 2684 | 2869 | 93.6% |
|
||||
@@ -65,24 +65,24 @@ FLEET matchable : 353717
|
||||
| ov_SC03_030 | 2415 | 1756 | 0 | 2417 | 2495 | 96.9% |
|
||||
| ov_SC03_031 | 2444 | 1751 | 0 | 2447 | 2514 | 97.3% |
|
||||
| ov_SC03_089 | 2510 | 1756 | 0 | 2517 | 2581 | 97.5% |
|
||||
| ov_SC03_090 | 2523 | 1756 | 0 | 2531 | 2625 | 96.4% |
|
||||
| ov_SC03_091 | 2537 | 1751 | 0 | 2545 | 2640 | 96.4% |
|
||||
| ov_SC03_092 | 2502 | 1756 | 0 | 2514 | 2587 | 97.2% |
|
||||
| ov_SC03_090 | 2525 | 1756 | 0 | 2533 | 2625 | 96.5% |
|
||||
| ov_SC03_091 | 2539 | 1751 | 0 | 2547 | 2640 | 96.5% |
|
||||
| ov_SC03_092 | 2503 | 1756 | 0 | 2515 | 2587 | 97.2% |
|
||||
| ov_SC03_093 | 2513 | 1751 | 0 | 2517 | 2563 | 98.2% |
|
||||
| ov_SC03_094 | 2500 | 1751 | 0 | 2506 | 2577 | 97.2% |
|
||||
| ov_SC03_094 | 2502 | 1751 | 0 | 2508 | 2577 | 97.3% |
|
||||
| ov_SC03_095 | 2429 | 1751 | 0 | 2432 | 2474 | 98.3% |
|
||||
| ov_SC03_096 | 2426 | 1751 | 0 | 2429 | 2465 | 98.5% |
|
||||
| ov_SC03_097 | 2523 | 1751 | 0 | 2530 | 2603 | 97.2% |
|
||||
| ov_SC03_098 | 2505 | 1751 | 0 | 2508 | 2541 | 98.7% |
|
||||
| ov_SC03_098 | 2507 | 1751 | 0 | 2510 | 2541 | 98.8% |
|
||||
| ov_SC03_099 | 2483 | 1751 | 0 | 2486 | 2504 | 99.3% |
|
||||
| ov_SC03_100 | 2518 | 1751 | 0 | 2522 | 2539 | 99.3% |
|
||||
| ov_SC03_101 | 2480 | 1756 | 0 | 2484 | 2528 | 98.3% |
|
||||
| ov_SC03_102 | 2467 | 1751 | 0 | 2470 | 2492 | 99.1% |
|
||||
| ov_SC03_103 | 2491 | 1753 | 0 | 2494 | 2510 | 99.4% |
|
||||
| ov_SC03_104 | 2538 | 1756 | 0 | 2545 | 2616 | 97.3% |
|
||||
| ov_SC03_105 | 2445 | 1752 | 0 | 2452 | 2597 | 94.4% |
|
||||
| ov_SC03_105 | 2446 | 1752 | 0 | 2453 | 2597 | 94.5% |
|
||||
| ov_SC03_108 | 2397 | 1751 | 0 | 2397 | 2443 | 98.1% |
|
||||
| ov_SC03_109 | 2404 | 1751 | 0 | 2406 | 2424 | 99.3% |
|
||||
| ov_SC03_109 | 2405 | 1751 | 0 | 2407 | 2424 | 99.3% |
|
||||
| ov_SC03_110 | 2438 | 1751 | 0 | 2438 | 2468 | 98.8% |
|
||||
| ov_SC03_111 | 2469 | 1751 | 0 | 2472 | 2510 | 98.5% |
|
||||
| ov_SC03_112 | 2434 | 1753 | 0 | 2436 | 2526 | 96.4% |
|
||||
@@ -94,65 +94,65 @@ FLEET matchable : 353717
|
||||
| ov_SC03_118 | 2540 | 1776 | 0 | 2541 | 2685 | 94.6% |
|
||||
| ov_SC03_119 | 2537 | 1776 | 0 | 2538 | 2685 | 94.5% |
|
||||
| ov_SC03_121 | 2400 | 1751 | 0 | 2403 | 2459 | 97.7% |
|
||||
| ov_SC03_124 | 2572 | 1747 | 0 | 2592 | 2741 | 94.6% |
|
||||
| ov_SC03_124 | 2574 | 1747 | 0 | 2594 | 2741 | 94.6% |
|
||||
| ov_SC03_125 | 2525 | 1751 | 0 | 2537 | 2588 | 98.0% |
|
||||
| ov_SC03_126 | 2396 | 1753 | 0 | 2396 | 2423 | 98.9% |
|
||||
| ov_SC04_000 | 2470 | 1755 | 0 | 2479 | 2546 | 97.4% |
|
||||
| ov_SC04_002 | 2499 | 1751 | 0 | 2503 | 2636 | 95.0% |
|
||||
| ov_SC04_000 | 2471 | 1755 | 0 | 2480 | 2546 | 97.4% |
|
||||
| ov_SC04_002 | 2501 | 1751 | 0 | 2505 | 2636 | 95.0% |
|
||||
| ov_SC04_003 | 2435 | 1751 | 0 | 2439 | 2502 | 97.5% |
|
||||
| ov_SC04_004 | 2467 | 1751 | 0 | 2469 | 2558 | 96.5% |
|
||||
| ov_SC04_005 | 2494 | 1751 | 0 | 2500 | 2612 | 95.7% |
|
||||
| ov_SC04_005 | 2496 | 1751 | 0 | 2502 | 2612 | 95.8% |
|
||||
| ov_SC04_006 | 2427 | 1751 | 0 | 2429 | 2454 | 99.0% |
|
||||
| ov_SC04_007 | 2488 | 1751 | 0 | 2492 | 2569 | 97.0% |
|
||||
| ov_SC04_007 | 2490 | 1751 | 0 | 2494 | 2569 | 97.1% |
|
||||
| ov_SC04_008 | 2397 | 1751 | 0 | 2397 | 2415 | 99.3% |
|
||||
| ov_SC04_009 | 2423 | 1751 | 0 | 2426 | 2441 | 99.4% |
|
||||
| ov_SC04_009 | 2424 | 1751 | 0 | 2427 | 2441 | 99.4% |
|
||||
| ov_SC04_010 | 2399 | 1751 | 0 | 2400 | 2419 | 99.2% |
|
||||
| ov_SC04_011 | 2512 | 1756 | 0 | 2518 | 2803 | 89.8% |
|
||||
| ov_SC04_011 | 2513 | 1756 | 0 | 2519 | 2803 | 89.9% |
|
||||
| ov_SC04_012 | 2394 | 1751 | 0 | 2395 | 2420 | 99.0% |
|
||||
| ov_SC04_015 | 2529 | 1752 | 0 | 2540 | 2611 | 97.3% |
|
||||
| ov_SC04_015 | 2530 | 1752 | 0 | 2541 | 2611 | 97.3% |
|
||||
| ov_SC04_016 | 2398 | 1751 | 0 | 2400 | 2440 | 98.4% |
|
||||
| ov_SC04_018 | 2668 | 1788 | 0 | 2668 | 2857 | 93.4% |
|
||||
| ov_SC04_019 | 2668 | 1788 | 0 | 2668 | 2857 | 93.4% |
|
||||
| ov_SC04_018 | 2670 | 1788 | 0 | 2670 | 2857 | 93.5% |
|
||||
| ov_SC04_019 | 2670 | 1788 | 0 | 2670 | 2857 | 93.5% |
|
||||
| ov_SC04_020 | 2511 | 1751 | 0 | 2523 | 2567 | 98.3% |
|
||||
| ov_SC04_021 | 2396 | 1753 | 0 | 2396 | 2423 | 98.9% |
|
||||
| ov_SC05_000 | 2403 | 1755 | 0 | 2406 | 2422 | 99.3% |
|
||||
| ov_SC05_001 | 2475 | 1751 | 0 | 2480 | 2574 | 96.3% |
|
||||
| ov_SC05_002 | 2427 | 1751 | 0 | 2430 | 2442 | 99.5% |
|
||||
| ov_SC05_003 | 2409 | 1751 | 0 | 2410 | 2481 | 97.1% |
|
||||
| ov_SC05_003 | 2410 | 1751 | 0 | 2411 | 2481 | 97.2% |
|
||||
| ov_SC05_004 | 2420 | 1751 | 0 | 2422 | 2464 | 98.3% |
|
||||
| ov_SC05_005 | 2434 | 1756 | 0 | 2435 | 2491 | 97.8% |
|
||||
| ov_SC05_005 | 2435 | 1756 | 0 | 2436 | 2491 | 97.8% |
|
||||
| ov_SC05_006 | 2419 | 1751 | 0 | 2419 | 2430 | 99.5% |
|
||||
| ov_SC05_007 | 2428 | 1751 | 0 | 2433 | 2482 | 98.0% |
|
||||
| ov_SC05_008 | 2439 | 1751 | 0 | 2441 | 2543 | 96.0% |
|
||||
| ov_SC05_009 | 2405 | 1751 | 0 | 2409 | 2438 | 98.8% |
|
||||
| ov_SC05_010 | 2445 | 1752 | 0 | 2449 | 2588 | 94.6% |
|
||||
| ov_SC05_009 | 2406 | 1751 | 0 | 2410 | 2438 | 98.9% |
|
||||
| ov_SC05_010 | 2446 | 1752 | 0 | 2450 | 2588 | 94.7% |
|
||||
| ov_SC05_011 | 2393 | 1751 | 0 | 2394 | 2409 | 99.4% |
|
||||
| ov_SC05_017 | 2644 | 1748 | 0 | 2655 | 2842 | 93.4% |
|
||||
| ov_SC05_017 | 2646 | 1748 | 0 | 2657 | 2842 | 93.5% |
|
||||
| ov_SC05_018 | 2543 | 1751 | 0 | 2556 | 2673 | 95.6% |
|
||||
| ov_SC05_019 | 2396 | 1753 | 0 | 2396 | 2423 | 98.9% |
|
||||
| ov_SC06_000 | 2525 | 1760 | 0 | 2528 | 2691 | 93.9% |
|
||||
| ov_SC06_006 | 2420 | 1751 | 0 | 2421 | 2511 | 96.4% |
|
||||
| ov_SC06_008 | 2484 | 1753 | 0 | 2490 | 2542 | 98.0% |
|
||||
| ov_SC06_010 | 2454 | 1751 | 0 | 2459 | 2517 | 97.7% |
|
||||
| ov_SC06_008 | 2485 | 1753 | 0 | 2491 | 2542 | 98.0% |
|
||||
| ov_SC06_010 | 2457 | 1751 | 0 | 2462 | 2517 | 97.8% |
|
||||
| ov_SC06_011 | 2412 | 1751 | 0 | 2416 | 2468 | 97.9% |
|
||||
| ov_SC06_013 | 2402 | 1751 | 0 | 2403 | 2425 | 99.1% |
|
||||
| ov_SC06_014 | 2413 | 1751 | 0 | 2415 | 2453 | 98.5% |
|
||||
| ov_SC06_015 | 2407 | 1751 | 0 | 2407 | 2421 | 99.4% |
|
||||
| ov_SC06_016 | 2449 | 1752 | 0 | 2451 | 2549 | 96.2% |
|
||||
| ov_SC06_018 | 2495 | 1753 | 0 | 2502 | 2665 | 93.9% |
|
||||
| ov_SC06_020 | 2442 | 1753 | 0 | 2443 | 2518 | 97.0% |
|
||||
| ov_SC06_022 | 2474 | 1751 | 0 | 2482 | 2642 | 93.9% |
|
||||
| ov_SC06_024 | 2494 | 1751 | 0 | 2500 | 2667 | 93.7% |
|
||||
| ov_SC06_018 | 2497 | 1753 | 0 | 2504 | 2665 | 94.0% |
|
||||
| ov_SC06_020 | 2443 | 1753 | 0 | 2444 | 2518 | 97.1% |
|
||||
| ov_SC06_022 | 2478 | 1751 | 0 | 2486 | 2642 | 94.1% |
|
||||
| ov_SC06_024 | 2498 | 1751 | 0 | 2504 | 2667 | 93.9% |
|
||||
| ov_SC06_025 | 2449 | 1751 | 0 | 2454 | 2572 | 95.4% |
|
||||
| ov_SC06_027 | 2388 | 1751 | 0 | 2389 | 2408 | 99.2% |
|
||||
| ov_SC06_029 | 2473 | 1752 | 0 | 2485 | 2662 | 93.4% |
|
||||
| ov_SC06_029 | 2474 | 1752 | 0 | 2486 | 2662 | 93.4% |
|
||||
| ov_SC06_030 | 2410 | 1752 | 0 | 2410 | 2456 | 98.1% |
|
||||
| ov_SC06_032 | 2484 | 1752 | 0 | 2491 | 2658 | 93.7% |
|
||||
| ov_SC06_033 | 2479 | 1752 | 0 | 2486 | 2631 | 94.5% |
|
||||
| ov_SC06_033 | 2484 | 1752 | 0 | 2491 | 2631 | 94.7% |
|
||||
| ov_SC07_000 | 2429 | 1755 | 0 | 2431 | 2521 | 96.4% |
|
||||
| ov_SC07_001 | 2401 | 1751 | 0 | 2403 | 2454 | 97.9% |
|
||||
| ov_SC07_002 | 2456 | 1752 | 0 | 2460 | 2579 | 95.4% |
|
||||
| ov_SC07_006 | 2318 | 1575 | 0 | 2398 | 2455 | 97.7% |
|
||||
| ov_SC07_002 | 2457 | 1752 | 0 | 2461 | 2579 | 95.4% |
|
||||
| ov_SC07_006 | 2321 | 1575 | 0 | 2401 | 2455 | 97.8% |
|
||||
| ov_SC07_007 | 2334 | 1607 | 0 | 2418 | 2612 | 92.6% |
|
||||
| ov_SC07_008 | 2382 | 1751 | 0 | 2382 | 2386 | 99.8% |
|
||||
| ov_SC07_009 | 2394 | 1751 | 0 | 2396 | 2430 | 98.6% |
|
||||
|
||||
@@ -4265,7 +4265,51 @@ void func_80182E34(void *a0) {
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC02_016/nonmatchings/ov_SC02_016_jr_8017DC70", func_80182E70);
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC02_016/nonmatchings/ov_SC02_016_jr_8017DC70", func_80182FE8);
|
||||
|
||||
extern s32 func_80012C6C(s32 a0, s32 a1, s32 a2);
|
||||
extern s32 func_80012ABC(s32 a0, s32 a1, s32 a2);
|
||||
extern void func_80049CAC(s32 a0, s32 a1);
|
||||
extern void func_8012F14C(s32);
|
||||
|
||||
|
||||
void func_80182FE8(s32 param_1) {
|
||||
|
||||
extern s16 D_80126940;
|
||||
extern s16 D_80126942;
|
||||
extern s16 D_80126944;
|
||||
MATRIX m1;
|
||||
SVECTOR svec_in;
|
||||
SVECTOR svec_out;
|
||||
s16 *p;
|
||||
|
||||
*(s32 *)(param_1 + 0x8) = (s16)func_80012C6C((s32)*(s16 *)(param_1 + 0x8), (s32)*(s16 *)(param_1 + 0xC), 4);
|
||||
*(s32 *)(param_1 + 0x10) = (s16)func_80012C6C((s32)*(s16 *)(param_1 + 0x10), (s32)*(s16 *)(param_1 + 0x14), 4);
|
||||
*(s16 *)(param_1 + 0x18) = func_80012ABC((s32)*(s16 *)(param_1 + 0x18), (s32)*(s16 *)(param_1 + 0x20), 4);
|
||||
*(s16 *)(param_1 + 0x1A) = func_80012ABC((s32)*(s16 *)(param_1 + 0x1A), (s32)*(s16 *)(param_1 + 0x22), 4);
|
||||
*(s16 *)(param_1 + 0x1C) = func_80012ABC((s32)*(s16 *)(param_1 + 0x1C), (s32)*(s16 *)(param_1 + 0x24), 4);
|
||||
*(s16 *)(param_1 + 0x28) = func_80012C6C((s32)*(s16 *)(param_1 + 0x28), (s32)*(s16 *)(param_1 + 0x2E), 0x10);
|
||||
*(s16 *)(param_1 + 0x2A) = func_80012C6C((s32)*(s16 *)(param_1 + 0x2A), (s32)*(s16 *)(param_1 + 0x30), 0x10);
|
||||
*(s16 *)(param_1 + 0x2C) = func_80012C6C((s32)*(s16 *)(param_1 + 0x2C), (s32)*(s16 *)(param_1 + 0x32), 0x10);
|
||||
|
||||
p = &D_80126940;
|
||||
*(s32 *)(param_1 + 0x48) = (s32)*(s16 *)(param_1 + 0x28) + (s32)*p;
|
||||
*(s32 *)(param_1 + 0x4C) = (s32)*(s16 *)(param_1 + 0x2A) + (s32)D_80126942;
|
||||
*(s32 *)(param_1 + 0x50) = (s32)*(s16 *)(param_1 + 0x2C) + (s32)D_80126944;
|
||||
func_80049CAC(param_1 + 0x18, (s32)&m1);
|
||||
|
||||
m1.t[0] = *(s16 *)(param_1 + 0x28) + *p;
|
||||
m1.t[1] = *(s16 *)(param_1 + 0x2A) + D_80126942;
|
||||
m1.t[2] = *(s16 *)(param_1 + 0x2C) + D_80126944;
|
||||
svec_in.vx = 0;
|
||||
svec_in.vy = 0;
|
||||
svec_in.vz = *(s32 *)(param_1 + 0x10);
|
||||
((void (*)(s32, s32, s32))func_8012F14C)((s32)&m1, (s32)&svec_in, (s32)&svec_out);
|
||||
|
||||
*(s32 *)(param_1 + 0x3C) = (s32)svec_out.vx;
|
||||
*(s32 *)(param_1 + 0x40) = (s32)svec_out.vy;
|
||||
*(s32 *)(param_1 + 0x44) = (s32)svec_out.vz;
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern void (*D_801A41D8[])(void);
|
||||
|
||||
@@ -4683,7 +4683,84 @@ INCLUDE_ASM("asm/ov_SC02_035/nonmatchings/ov_SC02_035_jr_8017BEBC", func_8017F8A
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC02_035/nonmatchings/ov_SC02_035_jr_8017BEBC", func_8017F918);
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC02_035/nonmatchings/ov_SC02_035_jr_8017BEBC", func_8017F96C);
|
||||
|
||||
extern void func_8012BE54(s32 a0);
|
||||
extern void func_8012CBCC(s32 a0);
|
||||
extern void func_8012E88C(s32);
|
||||
extern void func_8012B21C(void *a0);
|
||||
extern s32 func_8004787C(s32 a0);
|
||||
extern void func_8002D4C8(s32 a0, s32 a1);
|
||||
|
||||
void func_8017F96C(s32 a0) {
|
||||
register s32 state __asm__("$16"); /* $s0 */
|
||||
register s32 ent __asm__("$17"); /* $s1 */
|
||||
s32 sub;
|
||||
s32 t;
|
||||
s32 v;
|
||||
s32 cnt;
|
||||
|
||||
ent = a0;
|
||||
__asm__ volatile("" ::: "$4");
|
||||
state = *(u16 *)(ent + 0x34);
|
||||
|
||||
switch (state) {
|
||||
case 0:
|
||||
if (0x10000 < ((s32 (*)(s32))func_8012BE54)(ent)) {
|
||||
return;
|
||||
}
|
||||
*(u16 *)(ent + 0x34) = *(u16 *)(ent + 0x34) + 1;
|
||||
((void (*)(u8 *))func_8012E88C)((u8 *)ent);
|
||||
func_8012B21C((void *)ent);
|
||||
return;
|
||||
case 1:
|
||||
if ((((s32 (*)(s32))func_8012CBCC)(ent) & 0x2000) == 0) {
|
||||
return;
|
||||
}
|
||||
*(s32 *)(ent + 0x1C) = state;
|
||||
*(u16 *)(ent + 0x34) = *(u16 *)(ent + 0x34) + 1;
|
||||
func_8002D4C8(0x703, 0);
|
||||
/* fallthrough */
|
||||
case 2:
|
||||
sub = *(s32 *)(ent + 0x20);
|
||||
t = func_8004787C(*(s32 *)(ent + 0x1C) << 7);
|
||||
v = (t * 0x1c00 >> 12) + 0x400;
|
||||
*(s16 *)(sub + 0x1C) = v;
|
||||
*(s16 *)(sub + 0x18) = v;
|
||||
{
|
||||
s32 w = 0x3000 - (t * 0x2800 >> 12);
|
||||
*(s16 *)(sub + 0x1A) = w;
|
||||
}
|
||||
cnt = *(s32 *)(ent + 0x1C) + 1;
|
||||
*(s32 *)(ent + 0x1C) = cnt;
|
||||
if (cnt < 9) {
|
||||
return;
|
||||
}
|
||||
*(s32 *)(ent + 0x1C) = 1;
|
||||
*(u16 *)(ent + 0x34) = *(u16 *)(ent + 0x34) + 1;
|
||||
return;
|
||||
case 3:
|
||||
sub = *(s32 *)(ent + 0x20);
|
||||
t = func_8004787C(*(s32 *)(ent + 0x1C) << 7);
|
||||
{
|
||||
register s32 lo __asm__("$3");
|
||||
lo = (t << 12) >> 12;
|
||||
v = 0x2000 - lo;
|
||||
}
|
||||
*(s16 *)(sub + 0x1C) = v;
|
||||
*(s16 *)(sub + 0x18) = v;
|
||||
{
|
||||
s32 w = ((t * 0x800) >> 12) + 0x800;
|
||||
*(s16 *)(sub + 0x1A) = w;
|
||||
}
|
||||
cnt = *(s32 *)(ent + 0x1C) + 1;
|
||||
*(s32 *)(ent + 0x1C) = cnt;
|
||||
if (8 < cnt) {
|
||||
*(u16 *)(ent + 2) = 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC02_035/nonmatchings/ov_SC02_035_jr_8017BEBC", func_8017FB1C);
|
||||
|
||||
@@ -4963,7 +5040,50 @@ INCLUDE_ASM("asm/ov_SC02_035/nonmatchings/ov_SC02_035_jr_8017BEBC", func_801808F
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC02_035/nonmatchings/ov_SC02_035_jr_8017BEBC", func_80180948);
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC02_035/nonmatchings/ov_SC02_035_jr_8017BEBC", func_801809E4);
|
||||
|
||||
extern void func_8012931C(struct vec *a0);
|
||||
extern s32 func_8012CEB0(s32 a0, s32 a1, s32 a2);
|
||||
|
||||
/* a0 = actor/entity base (struct vec-compatible; s16 fields at +6/+A/+E, s32 flag/vel at +0x14),
|
||||
* a1 = s16[3] offset vector, a2 = mode passed through to func_8012CEB0.
|
||||
* Same family as func_8012CC88 (src/ov_SC02_027/ov_SC02_027_jr_8012ACE0.c etc) but the
|
||||
* position-integration step is a real call to func_8012931C instead of being inlined. */
|
||||
s32 func_801809E4(s32 a0, s32 a1, s32 a2) {
|
||||
SV3_8012CC88 sp10;
|
||||
SV3_8012CC88 sp18;
|
||||
s32 v0;
|
||||
|
||||
sp10.vx = *(u16*)(a0 + 0x06);
|
||||
sp10.vy = *(u16*)(a0 + 0x0A);
|
||||
sp10.vz = *(u16*)(a0 + 0x0E);
|
||||
sp10.vx += *(u16*)(a1 + 0);
|
||||
sp10.vy += *(u16*)(a1 + 2);
|
||||
sp10.vz += *(u16*)(a1 + 4);
|
||||
|
||||
func_8012931C((struct vec *)a0);
|
||||
|
||||
sp18.vx = *(u16*)(a0 + 0x06);
|
||||
sp18.vy = *(u16*)(a0 + 0x0A);
|
||||
sp18.vz = *(u16*)(a0 + 0x0E);
|
||||
sp18.vx += *(u16*)(a1 + 0);
|
||||
sp18.vy += *(u16*)(a1 + 2);
|
||||
sp18.vz += *(u16*)(a1 + 4);
|
||||
|
||||
v0 = func_8012CEB0((s32)&sp10, (s32)&sp18, a2);
|
||||
|
||||
sp18.vx -= *(u16*)(a1 + 0);
|
||||
sp18.vy -= *(u16*)(a1 + 2);
|
||||
sp18.vz -= *(u16*)(a1 + 4);
|
||||
*(s16*)(a0 + 0x06) = sp18.vx;
|
||||
*(s16*)(a0 + 0x0A) = sp18.vy;
|
||||
*(s16*)(a0 + 0x0E) = sp18.vz;
|
||||
|
||||
if (v0 & 0x6000) {
|
||||
*(s32*)(a0 + 0x14) = 0;
|
||||
}
|
||||
return v0;
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC02_035/nonmatchings/ov_SC02_035_jr_8017BEBC", func_80180B38);
|
||||
|
||||
|
||||
@@ -6158,7 +6158,84 @@ INCLUDE_ASM("asm/ov_SC03_090/nonmatchings/ov_SC03_090_jr_8017CA80", func_80185FA
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_090/nonmatchings/ov_SC03_090_jr_8017CA80", func_80186020);
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_090/nonmatchings/ov_SC03_090_jr_8017CA80", func_80186074);
|
||||
|
||||
extern void func_8012BE54(s32 a0);
|
||||
extern void func_8012CBCC(s32 a0);
|
||||
extern void func_8012E88C(u8 *a0);
|
||||
extern void func_8012B21C(void *a0);
|
||||
extern s32 func_8004787C(s32 a0);
|
||||
extern void func_8002D4C8(s32 a0, s32 a1);
|
||||
|
||||
void func_80186074(s32 a0) {
|
||||
register s32 state __asm__("$16"); /* $s0 */
|
||||
register s32 ent __asm__("$17"); /* $s1 */
|
||||
s32 sub;
|
||||
s32 t;
|
||||
s32 v;
|
||||
s32 cnt;
|
||||
|
||||
ent = a0;
|
||||
__asm__ volatile("" ::: "$4");
|
||||
state = *(u16 *)(ent + 0x34);
|
||||
|
||||
switch (state) {
|
||||
case 0:
|
||||
if (0x10000 < ((s32 (*)(s32))func_8012BE54)(ent)) {
|
||||
return;
|
||||
}
|
||||
*(u16 *)(ent + 0x34) = *(u16 *)(ent + 0x34) + 1;
|
||||
func_8012E88C((u8 *)ent);
|
||||
func_8012B21C((void *)ent);
|
||||
return;
|
||||
case 1:
|
||||
if ((((s32 (*)(s32))func_8012CBCC)(ent) & 0x2000) == 0) {
|
||||
return;
|
||||
}
|
||||
*(s32 *)(ent + 0x1C) = state;
|
||||
*(u16 *)(ent + 0x34) = *(u16 *)(ent + 0x34) + 1;
|
||||
func_8002D4C8(0x703, 0);
|
||||
/* fallthrough */
|
||||
case 2:
|
||||
sub = *(s32 *)(ent + 0x20);
|
||||
t = func_8004787C(*(s32 *)(ent + 0x1C) << 7);
|
||||
v = (t * 0x1c00 >> 12) + 0x400;
|
||||
*(s16 *)(sub + 0x1C) = v;
|
||||
*(s16 *)(sub + 0x18) = v;
|
||||
{
|
||||
s32 w = 0x3000 - (t * 0x2800 >> 12);
|
||||
*(s16 *)(sub + 0x1A) = w;
|
||||
}
|
||||
cnt = *(s32 *)(ent + 0x1C) + 1;
|
||||
*(s32 *)(ent + 0x1C) = cnt;
|
||||
if (cnt < 9) {
|
||||
return;
|
||||
}
|
||||
*(s32 *)(ent + 0x1C) = 1;
|
||||
*(u16 *)(ent + 0x34) = *(u16 *)(ent + 0x34) + 1;
|
||||
return;
|
||||
case 3:
|
||||
sub = *(s32 *)(ent + 0x20);
|
||||
t = func_8004787C(*(s32 *)(ent + 0x1C) << 7);
|
||||
{
|
||||
register s32 lo __asm__("$3");
|
||||
lo = (t << 12) >> 12;
|
||||
v = 0x2000 - lo;
|
||||
}
|
||||
*(s16 *)(sub + 0x1C) = v;
|
||||
*(s16 *)(sub + 0x18) = v;
|
||||
{
|
||||
s32 w = ((t * 0x800) >> 12) + 0x800;
|
||||
*(s16 *)(sub + 0x1A) = w;
|
||||
}
|
||||
cnt = *(s32 *)(ent + 0x1C) + 1;
|
||||
*(s32 *)(ent + 0x1C) = cnt;
|
||||
if (8 < cnt) {
|
||||
*(u16 *)(ent + 2) = 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_090/nonmatchings/ov_SC03_090_jr_8017CA80", func_80186224);
|
||||
|
||||
@@ -6436,7 +6513,50 @@ INCLUDE_ASM("asm/ov_SC03_090/nonmatchings/ov_SC03_090_jr_8017CA80", func_80186FF
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_090/nonmatchings/ov_SC03_090_jr_8017CA80", func_80187050);
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_090/nonmatchings/ov_SC03_090_jr_8017CA80", func_801870EC);
|
||||
|
||||
extern void func_8012931C(struct vec *a0);
|
||||
extern s32 func_8012CEB0(s32 a0, s32 a1, s32 a2);
|
||||
|
||||
/* a0 = actor/entity base (struct vec-compatible; s16 fields at +6/+A/+E, s32 flag/vel at +0x14),
|
||||
* a1 = s16[3] offset vector, a2 = mode passed through to func_8012CEB0.
|
||||
* Same family as func_8012CC88 (src/ov_SC02_027/ov_SC02_027_jr_8012ACE0.c etc) but the
|
||||
* position-integration step is a real call to func_8012931C instead of being inlined. */
|
||||
s32 func_801870EC(s32 a0, s32 a1, s32 a2) {
|
||||
SV3_8012CC88 sp10;
|
||||
SV3_8012CC88 sp18;
|
||||
s32 v0;
|
||||
|
||||
sp10.vx = *(u16*)(a0 + 0x06);
|
||||
sp10.vy = *(u16*)(a0 + 0x0A);
|
||||
sp10.vz = *(u16*)(a0 + 0x0E);
|
||||
sp10.vx += *(u16*)(a1 + 0);
|
||||
sp10.vy += *(u16*)(a1 + 2);
|
||||
sp10.vz += *(u16*)(a1 + 4);
|
||||
|
||||
func_8012931C((struct vec *)a0);
|
||||
|
||||
sp18.vx = *(u16*)(a0 + 0x06);
|
||||
sp18.vy = *(u16*)(a0 + 0x0A);
|
||||
sp18.vz = *(u16*)(a0 + 0x0E);
|
||||
sp18.vx += *(u16*)(a1 + 0);
|
||||
sp18.vy += *(u16*)(a1 + 2);
|
||||
sp18.vz += *(u16*)(a1 + 4);
|
||||
|
||||
v0 = func_8012CEB0((s32)&sp10, (s32)&sp18, a2);
|
||||
|
||||
sp18.vx -= *(u16*)(a1 + 0);
|
||||
sp18.vy -= *(u16*)(a1 + 2);
|
||||
sp18.vz -= *(u16*)(a1 + 4);
|
||||
*(s16*)(a0 + 0x06) = sp18.vx;
|
||||
*(s16*)(a0 + 0x0A) = sp18.vy;
|
||||
*(s16*)(a0 + 0x0E) = sp18.vz;
|
||||
|
||||
if (v0 & 0x6000) {
|
||||
*(s32*)(a0 + 0x14) = 0;
|
||||
}
|
||||
return v0;
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_090/nonmatchings/ov_SC03_090_jr_8017CA80", func_80187240);
|
||||
|
||||
|
||||
@@ -4669,7 +4669,84 @@ INCLUDE_ASM("asm/ov_SC03_091/nonmatchings/ov_SC03_091_jr_80182268", func_80186E5
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_091/nonmatchings/ov_SC03_091_jr_80182268", func_80186EC8);
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_091/nonmatchings/ov_SC03_091_jr_80182268", func_80186F1C);
|
||||
|
||||
extern void func_8012BE54(s32 a0);
|
||||
extern void func_8012CBCC(s32 a0);
|
||||
extern void func_8012E88C(u8 *a0);
|
||||
extern void func_8012B21C(void *a0);
|
||||
extern s32 func_8004787C(s32 a0);
|
||||
extern void func_8002D4C8(s32 a0, s32 a1);
|
||||
|
||||
void func_80186F1C(s32 a0) {
|
||||
register s32 state __asm__("$16"); /* $s0 */
|
||||
register s32 ent __asm__("$17"); /* $s1 */
|
||||
s32 sub;
|
||||
s32 t;
|
||||
s32 v;
|
||||
s32 cnt;
|
||||
|
||||
ent = a0;
|
||||
__asm__ volatile("" ::: "$4");
|
||||
state = *(u16 *)(ent + 0x34);
|
||||
|
||||
switch (state) {
|
||||
case 0:
|
||||
if (0x10000 < ((s32 (*)(s32))func_8012BE54)(ent)) {
|
||||
return;
|
||||
}
|
||||
*(u16 *)(ent + 0x34) = *(u16 *)(ent + 0x34) + 1;
|
||||
func_8012E88C((u8 *)ent);
|
||||
func_8012B21C((void *)ent);
|
||||
return;
|
||||
case 1:
|
||||
if ((((s32 (*)(s32))func_8012CBCC)(ent) & 0x2000) == 0) {
|
||||
return;
|
||||
}
|
||||
*(s32 *)(ent + 0x1C) = state;
|
||||
*(u16 *)(ent + 0x34) = *(u16 *)(ent + 0x34) + 1;
|
||||
func_8002D4C8(0x703, 0);
|
||||
/* fallthrough */
|
||||
case 2:
|
||||
sub = *(s32 *)(ent + 0x20);
|
||||
t = func_8004787C(*(s32 *)(ent + 0x1C) << 7);
|
||||
v = (t * 0x1c00 >> 12) + 0x400;
|
||||
*(s16 *)(sub + 0x1C) = v;
|
||||
*(s16 *)(sub + 0x18) = v;
|
||||
{
|
||||
s32 w = 0x3000 - (t * 0x2800 >> 12);
|
||||
*(s16 *)(sub + 0x1A) = w;
|
||||
}
|
||||
cnt = *(s32 *)(ent + 0x1C) + 1;
|
||||
*(s32 *)(ent + 0x1C) = cnt;
|
||||
if (cnt < 9) {
|
||||
return;
|
||||
}
|
||||
*(s32 *)(ent + 0x1C) = 1;
|
||||
*(u16 *)(ent + 0x34) = *(u16 *)(ent + 0x34) + 1;
|
||||
return;
|
||||
case 3:
|
||||
sub = *(s32 *)(ent + 0x20);
|
||||
t = func_8004787C(*(s32 *)(ent + 0x1C) << 7);
|
||||
{
|
||||
register s32 lo __asm__("$3");
|
||||
lo = (t << 12) >> 12;
|
||||
v = 0x2000 - lo;
|
||||
}
|
||||
*(s16 *)(sub + 0x1C) = v;
|
||||
*(s16 *)(sub + 0x18) = v;
|
||||
{
|
||||
s32 w = ((t * 0x800) >> 12) + 0x800;
|
||||
*(s16 *)(sub + 0x1A) = w;
|
||||
}
|
||||
cnt = *(s32 *)(ent + 0x1C) + 1;
|
||||
*(s32 *)(ent + 0x1C) = cnt;
|
||||
if (8 < cnt) {
|
||||
*(u16 *)(ent + 2) = 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_091/nonmatchings/ov_SC03_091_jr_80182268", func_801870CC);
|
||||
|
||||
@@ -4947,7 +5024,50 @@ INCLUDE_ASM("asm/ov_SC03_091/nonmatchings/ov_SC03_091_jr_80182268", func_80187EA
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_091/nonmatchings/ov_SC03_091_jr_80182268", func_80187EF8);
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_091/nonmatchings/ov_SC03_091_jr_80182268", func_80187F94);
|
||||
|
||||
extern void func_8012931C(struct vec *a0);
|
||||
extern s32 func_8012CEB0(s32 a0, s32 a1, s32 a2);
|
||||
|
||||
/* a0 = actor/entity base (struct vec-compatible; s16 fields at +6/+A/+E, s32 flag/vel at +0x14),
|
||||
* a1 = s16[3] offset vector, a2 = mode passed through to func_8012CEB0.
|
||||
* Same family as func_8012CC88 (src/ov_SC02_027/ov_SC02_027_jr_8012ACE0.c etc) but the
|
||||
* position-integration step is a real call to func_8012931C instead of being inlined. */
|
||||
s32 func_80187F94(s32 a0, s32 a1, s32 a2) {
|
||||
SV3_8012CC88 sp10;
|
||||
SV3_8012CC88 sp18;
|
||||
s32 v0;
|
||||
|
||||
sp10.vx = *(u16*)(a0 + 0x06);
|
||||
sp10.vy = *(u16*)(a0 + 0x0A);
|
||||
sp10.vz = *(u16*)(a0 + 0x0E);
|
||||
sp10.vx += *(u16*)(a1 + 0);
|
||||
sp10.vy += *(u16*)(a1 + 2);
|
||||
sp10.vz += *(u16*)(a1 + 4);
|
||||
|
||||
func_8012931C((struct vec *)a0);
|
||||
|
||||
sp18.vx = *(u16*)(a0 + 0x06);
|
||||
sp18.vy = *(u16*)(a0 + 0x0A);
|
||||
sp18.vz = *(u16*)(a0 + 0x0E);
|
||||
sp18.vx += *(u16*)(a1 + 0);
|
||||
sp18.vy += *(u16*)(a1 + 2);
|
||||
sp18.vz += *(u16*)(a1 + 4);
|
||||
|
||||
v0 = func_8012CEB0((s32)&sp10, (s32)&sp18, a2);
|
||||
|
||||
sp18.vx -= *(u16*)(a1 + 0);
|
||||
sp18.vy -= *(u16*)(a1 + 2);
|
||||
sp18.vz -= *(u16*)(a1 + 4);
|
||||
*(s16*)(a0 + 0x06) = sp18.vx;
|
||||
*(s16*)(a0 + 0x0A) = sp18.vy;
|
||||
*(s16*)(a0 + 0x0E) = sp18.vz;
|
||||
|
||||
if (v0 & 0x6000) {
|
||||
*(s32*)(a0 + 0x14) = 0;
|
||||
}
|
||||
return v0;
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_091/nonmatchings/ov_SC03_091_jr_80182268", func_801880E8);
|
||||
|
||||
|
||||
@@ -4030,7 +4030,6 @@ void func_80183764(void *a0) {
|
||||
}
|
||||
|
||||
|
||||
extern s32 *D_80126B78;
|
||||
extern u8 D_801B0200[];
|
||||
extern s32 func_8012BDBC(s32 a0, s32 a1);
|
||||
extern s32 func_80135888(s32 a0, s32 a1, s32 a2, s32 a3);
|
||||
@@ -4066,6 +4065,10 @@ s32 aF8018A224() __asm__("func_801837D4");
|
||||
s32 aF8018A224(param_1)
|
||||
void *param_1;
|
||||
{
|
||||
/* [T51] scoped in from file scope: a file-scope decl of these symbols constrains every
|
||||
LATER function in this TU, which blocks a byte-true decl of a different type.
|
||||
Declaration-only move (cookbook §103); the whole-binary byte-gate is the arbiter. */
|
||||
extern s32 *D_80126B78;
|
||||
s32 *m;
|
||||
s32 obj;
|
||||
s32 sv0[2];
|
||||
@@ -4211,7 +4214,101 @@ extern void func_800296F8(void *a0);
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_092/nonmatchings/ov_SC03_092_jr_80181694", func_80183C04);
|
||||
extern s32 func_8012BDBC(s32 a0, s32 a1);
|
||||
extern s32 func_80135888(s32 a0, s32 a1, s32 a2, s32 a3);
|
||||
extern void func_80172710(void);
|
||||
extern s32 func_80178BF8();
|
||||
#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_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" )
|
||||
|
||||
/* §71 sibling: identical shape to func_8018F390 (same TU, this file, D_80126B78/RotTransSV/
|
||||
* func_80135888/func_8012BDBC/func_80178BF8/func_80172710 idiom) already MATCHED -- only the
|
||||
* per-overlay data symbol (D_801B0358 vs D_801E33F0) differs. §37 asm-label alias avoids the
|
||||
* `conflicting types` clash with the fleet's `extern void func_80183C04(void);` used elsewhere
|
||||
* in this TU as a state-handler function pointer. */
|
||||
|
||||
s32 aF801904E0() __asm__("func_80183C04");
|
||||
|
||||
s32 aF801904E0(param_1)
|
||||
void *param_1;
|
||||
{
|
||||
|
||||
extern s32 *D_80126B78;
|
||||
extern u8 D_801B0358[];
|
||||
MATRIX m;
|
||||
s32 obj;
|
||||
s32 sv0[2];
|
||||
s32 sv1[2];
|
||||
s32 flag;
|
||||
|
||||
obj = *(s32 *)((s32)param_1 + 0x64);
|
||||
m = *(MATRIX *)((u8 *)D_80126B78 + 0x34);
|
||||
|
||||
gte_SetRotMatrix(&m);
|
||||
gte_SetTransMatrix(&m);
|
||||
|
||||
RotTransSV(D_801B0358, sv0, &flag);
|
||||
RotTransSV(D_801B0358 + 8, sv1, &flag);
|
||||
|
||||
if (func_80135888(*(s32 *)(*(s32 *)((s32)param_1 + 0x64) + 0x20),
|
||||
*(s32 *)(*(s32 *)((s32)param_1 + 0x64) + 0x58),
|
||||
(s32)sv0, (s32)sv1) == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (func_8012BDBC(obj, 0x300) == 0) {
|
||||
return 0;
|
||||
}
|
||||
*(s16 *)(obj + 0x2) = 3;
|
||||
func_80178BF8();
|
||||
return (s32)func_80172710;
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern s32 func_8012C194(void);
|
||||
|
||||
@@ -4837,7 +4837,84 @@ INCLUDE_ASM("asm/ov_SC03_094/nonmatchings/ov_SC03_094_jr_8017BEBC", func_80180C2
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_094/nonmatchings/ov_SC03_094_jr_8017BEBC", func_80180CA0);
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_094/nonmatchings/ov_SC03_094_jr_8017BEBC", func_80180CF4);
|
||||
|
||||
extern void func_8012BE54(s32 a0);
|
||||
extern void func_8012CBCC(s32 a0);
|
||||
extern void func_8012E88C(s32);
|
||||
extern void func_8012B21C(void *a0);
|
||||
extern s32 func_8004787C(s32 a0);
|
||||
extern void func_8002D4C8(s32 a0, s32 a1);
|
||||
|
||||
void func_80180CF4(s32 a0) {
|
||||
register s32 state __asm__("$16"); /* $s0 */
|
||||
register s32 ent __asm__("$17"); /* $s1 */
|
||||
s32 sub;
|
||||
s32 t;
|
||||
s32 v;
|
||||
s32 cnt;
|
||||
|
||||
ent = a0;
|
||||
__asm__ volatile("" ::: "$4");
|
||||
state = *(u16 *)(ent + 0x34);
|
||||
|
||||
switch (state) {
|
||||
case 0:
|
||||
if (0x10000 < ((s32 (*)(s32))func_8012BE54)(ent)) {
|
||||
return;
|
||||
}
|
||||
*(u16 *)(ent + 0x34) = *(u16 *)(ent + 0x34) + 1;
|
||||
((void (*)(u8 *))func_8012E88C)((u8 *)ent);
|
||||
func_8012B21C((void *)ent);
|
||||
return;
|
||||
case 1:
|
||||
if ((((s32 (*)(s32))func_8012CBCC)(ent) & 0x2000) == 0) {
|
||||
return;
|
||||
}
|
||||
*(s32 *)(ent + 0x1C) = state;
|
||||
*(u16 *)(ent + 0x34) = *(u16 *)(ent + 0x34) + 1;
|
||||
func_8002D4C8(0x703, 0);
|
||||
/* fallthrough */
|
||||
case 2:
|
||||
sub = *(s32 *)(ent + 0x20);
|
||||
t = func_8004787C(*(s32 *)(ent + 0x1C) << 7);
|
||||
v = (t * 0x1c00 >> 12) + 0x400;
|
||||
*(s16 *)(sub + 0x1C) = v;
|
||||
*(s16 *)(sub + 0x18) = v;
|
||||
{
|
||||
s32 w = 0x3000 - (t * 0x2800 >> 12);
|
||||
*(s16 *)(sub + 0x1A) = w;
|
||||
}
|
||||
cnt = *(s32 *)(ent + 0x1C) + 1;
|
||||
*(s32 *)(ent + 0x1C) = cnt;
|
||||
if (cnt < 9) {
|
||||
return;
|
||||
}
|
||||
*(s32 *)(ent + 0x1C) = 1;
|
||||
*(u16 *)(ent + 0x34) = *(u16 *)(ent + 0x34) + 1;
|
||||
return;
|
||||
case 3:
|
||||
sub = *(s32 *)(ent + 0x20);
|
||||
t = func_8004787C(*(s32 *)(ent + 0x1C) << 7);
|
||||
{
|
||||
register s32 lo __asm__("$3");
|
||||
lo = (t << 12) >> 12;
|
||||
v = 0x2000 - lo;
|
||||
}
|
||||
*(s16 *)(sub + 0x1C) = v;
|
||||
*(s16 *)(sub + 0x18) = v;
|
||||
{
|
||||
s32 w = ((t * 0x800) >> 12) + 0x800;
|
||||
*(s16 *)(sub + 0x1A) = w;
|
||||
}
|
||||
cnt = *(s32 *)(ent + 0x1C) + 1;
|
||||
*(s32 *)(ent + 0x1C) = cnt;
|
||||
if (8 < cnt) {
|
||||
*(u16 *)(ent + 2) = 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_094/nonmatchings/ov_SC03_094_jr_8017BEBC", func_80180EA4);
|
||||
|
||||
@@ -5116,7 +5193,50 @@ INCLUDE_ASM("asm/ov_SC03_094/nonmatchings/ov_SC03_094_jr_8017BEBC", func_80181C7
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_094/nonmatchings/ov_SC03_094_jr_8017BEBC", func_80181CD0);
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_094/nonmatchings/ov_SC03_094_jr_8017BEBC", func_80181D6C);
|
||||
|
||||
extern void func_8012931C(struct vec *a0);
|
||||
extern s32 func_8012CEB0(s32 a0, s32 a1, s32 a2);
|
||||
|
||||
/* a0 = actor/entity base (struct vec-compatible; s16 fields at +6/+A/+E, s32 flag/vel at +0x14),
|
||||
* a1 = s16[3] offset vector, a2 = mode passed through to func_8012CEB0.
|
||||
* Same family as func_8012CC88 (src/ov_SC02_027/ov_SC02_027_jr_8012ACE0.c etc) but the
|
||||
* position-integration step is a real call to func_8012931C instead of being inlined. */
|
||||
s32 func_80181D6C(s32 a0, s32 a1, s32 a2) {
|
||||
SV3_8012CC88 sp10;
|
||||
SV3_8012CC88 sp18;
|
||||
s32 v0;
|
||||
|
||||
sp10.vx = *(u16*)(a0 + 0x06);
|
||||
sp10.vy = *(u16*)(a0 + 0x0A);
|
||||
sp10.vz = *(u16*)(a0 + 0x0E);
|
||||
sp10.vx += *(u16*)(a1 + 0);
|
||||
sp10.vy += *(u16*)(a1 + 2);
|
||||
sp10.vz += *(u16*)(a1 + 4);
|
||||
|
||||
func_8012931C((struct vec *)a0);
|
||||
|
||||
sp18.vx = *(u16*)(a0 + 0x06);
|
||||
sp18.vy = *(u16*)(a0 + 0x0A);
|
||||
sp18.vz = *(u16*)(a0 + 0x0E);
|
||||
sp18.vx += *(u16*)(a1 + 0);
|
||||
sp18.vy += *(u16*)(a1 + 2);
|
||||
sp18.vz += *(u16*)(a1 + 4);
|
||||
|
||||
v0 = func_8012CEB0((s32)&sp10, (s32)&sp18, a2);
|
||||
|
||||
sp18.vx -= *(u16*)(a1 + 0);
|
||||
sp18.vy -= *(u16*)(a1 + 2);
|
||||
sp18.vz -= *(u16*)(a1 + 4);
|
||||
*(s16*)(a0 + 0x06) = sp18.vx;
|
||||
*(s16*)(a0 + 0x0A) = sp18.vy;
|
||||
*(s16*)(a0 + 0x0E) = sp18.vz;
|
||||
|
||||
if (v0 & 0x6000) {
|
||||
*(s32*)(a0 + 0x14) = 0;
|
||||
}
|
||||
return v0;
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_094/nonmatchings/ov_SC03_094_jr_8017BEBC", func_80181EC0);
|
||||
|
||||
|
||||
@@ -4773,7 +4773,84 @@ INCLUDE_ASM("asm/ov_SC03_098/nonmatchings/ov_SC03_098_jr_8017D898", func_8018143
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_098/nonmatchings/ov_SC03_098_jr_8017D898", func_801814A8);
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_098/nonmatchings/ov_SC03_098_jr_8017D898", func_801814FC);
|
||||
|
||||
extern void func_8012BE54(s32 a0);
|
||||
extern void func_8012CBCC(s32 a0);
|
||||
extern void func_8012E88C(u8 *a0);
|
||||
extern void func_8012B21C(void *a0);
|
||||
extern s32 func_8004787C(s32 a0);
|
||||
extern void func_8002D4C8(s32 a0, s32 a1);
|
||||
|
||||
void func_801814FC(s32 a0) {
|
||||
register s32 state __asm__("$16"); /* $s0 */
|
||||
register s32 ent __asm__("$17"); /* $s1 */
|
||||
s32 sub;
|
||||
s32 t;
|
||||
s32 v;
|
||||
s32 cnt;
|
||||
|
||||
ent = a0;
|
||||
__asm__ volatile("" ::: "$4");
|
||||
state = *(u16 *)(ent + 0x34);
|
||||
|
||||
switch (state) {
|
||||
case 0:
|
||||
if (0x10000 < ((s32 (*)(s32))func_8012BE54)(ent)) {
|
||||
return;
|
||||
}
|
||||
*(u16 *)(ent + 0x34) = *(u16 *)(ent + 0x34) + 1;
|
||||
func_8012E88C((u8 *)ent);
|
||||
func_8012B21C((void *)ent);
|
||||
return;
|
||||
case 1:
|
||||
if ((((s32 (*)(s32))func_8012CBCC)(ent) & 0x2000) == 0) {
|
||||
return;
|
||||
}
|
||||
*(s32 *)(ent + 0x1C) = state;
|
||||
*(u16 *)(ent + 0x34) = *(u16 *)(ent + 0x34) + 1;
|
||||
func_8002D4C8(0x703, 0);
|
||||
/* fallthrough */
|
||||
case 2:
|
||||
sub = *(s32 *)(ent + 0x20);
|
||||
t = func_8004787C(*(s32 *)(ent + 0x1C) << 7);
|
||||
v = (t * 0x1c00 >> 12) + 0x400;
|
||||
*(s16 *)(sub + 0x1C) = v;
|
||||
*(s16 *)(sub + 0x18) = v;
|
||||
{
|
||||
s32 w = 0x3000 - (t * 0x2800 >> 12);
|
||||
*(s16 *)(sub + 0x1A) = w;
|
||||
}
|
||||
cnt = *(s32 *)(ent + 0x1C) + 1;
|
||||
*(s32 *)(ent + 0x1C) = cnt;
|
||||
if (cnt < 9) {
|
||||
return;
|
||||
}
|
||||
*(s32 *)(ent + 0x1C) = 1;
|
||||
*(u16 *)(ent + 0x34) = *(u16 *)(ent + 0x34) + 1;
|
||||
return;
|
||||
case 3:
|
||||
sub = *(s32 *)(ent + 0x20);
|
||||
t = func_8004787C(*(s32 *)(ent + 0x1C) << 7);
|
||||
{
|
||||
register s32 lo __asm__("$3");
|
||||
lo = (t << 12) >> 12;
|
||||
v = 0x2000 - lo;
|
||||
}
|
||||
*(s16 *)(sub + 0x1C) = v;
|
||||
*(s16 *)(sub + 0x18) = v;
|
||||
{
|
||||
s32 w = ((t * 0x800) >> 12) + 0x800;
|
||||
*(s16 *)(sub + 0x1A) = w;
|
||||
}
|
||||
cnt = *(s32 *)(ent + 0x1C) + 1;
|
||||
*(s32 *)(ent + 0x1C) = cnt;
|
||||
if (8 < cnt) {
|
||||
*(u16 *)(ent + 2) = 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_098/nonmatchings/ov_SC03_098_jr_8017D898", func_801816AC);
|
||||
|
||||
@@ -5051,7 +5128,50 @@ INCLUDE_ASM("asm/ov_SC03_098/nonmatchings/ov_SC03_098_jr_8017D898", func_8018248
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_098/nonmatchings/ov_SC03_098_jr_8017D898", func_801824D8);
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_098/nonmatchings/ov_SC03_098_jr_8017D898", func_80182574);
|
||||
|
||||
extern void func_8012931C(struct vec *a0);
|
||||
extern s32 func_8012CEB0(s32 a0, s32 a1, s32 a2);
|
||||
|
||||
/* a0 = actor/entity base (struct vec-compatible; s16 fields at +6/+A/+E, s32 flag/vel at +0x14),
|
||||
* a1 = s16[3] offset vector, a2 = mode passed through to func_8012CEB0.
|
||||
* Same family as func_8012CC88 (src/ov_SC02_027/ov_SC02_027_jr_8012ACE0.c etc) but the
|
||||
* position-integration step is a real call to func_8012931C instead of being inlined. */
|
||||
s32 func_80182574(s32 a0, s32 a1, s32 a2) {
|
||||
SV3_8012CC88 sp10;
|
||||
SV3_8012CC88 sp18;
|
||||
s32 v0;
|
||||
|
||||
sp10.vx = *(u16*)(a0 + 0x06);
|
||||
sp10.vy = *(u16*)(a0 + 0x0A);
|
||||
sp10.vz = *(u16*)(a0 + 0x0E);
|
||||
sp10.vx += *(u16*)(a1 + 0);
|
||||
sp10.vy += *(u16*)(a1 + 2);
|
||||
sp10.vz += *(u16*)(a1 + 4);
|
||||
|
||||
func_8012931C((struct vec *)a0);
|
||||
|
||||
sp18.vx = *(u16*)(a0 + 0x06);
|
||||
sp18.vy = *(u16*)(a0 + 0x0A);
|
||||
sp18.vz = *(u16*)(a0 + 0x0E);
|
||||
sp18.vx += *(u16*)(a1 + 0);
|
||||
sp18.vy += *(u16*)(a1 + 2);
|
||||
sp18.vz += *(u16*)(a1 + 4);
|
||||
|
||||
v0 = func_8012CEB0((s32)&sp10, (s32)&sp18, a2);
|
||||
|
||||
sp18.vx -= *(u16*)(a1 + 0);
|
||||
sp18.vy -= *(u16*)(a1 + 2);
|
||||
sp18.vz -= *(u16*)(a1 + 4);
|
||||
*(s16*)(a0 + 0x06) = sp18.vx;
|
||||
*(s16*)(a0 + 0x0A) = sp18.vy;
|
||||
*(s16*)(a0 + 0x0E) = sp18.vz;
|
||||
|
||||
if (v0 & 0x6000) {
|
||||
*(s32*)(a0 + 0x14) = 0;
|
||||
}
|
||||
return v0;
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_098/nonmatchings/ov_SC03_098_jr_8017D898", func_801826C8);
|
||||
|
||||
|
||||
@@ -3182,7 +3182,67 @@ void func_8017D7B0(void *a0) {
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_105/nonmatchings/ov_SC03_105_jr_8017C8D0", func_8017D7EC);
|
||||
|
||||
|
||||
extern s32 rand(void);
|
||||
|
||||
typedef struct {
|
||||
u16 f0;
|
||||
u16 f2;
|
||||
u16 f4;
|
||||
u16 f6;
|
||||
u16 f8;
|
||||
u16 fA;
|
||||
s32 fC;
|
||||
s32 f10;
|
||||
s32 f14;
|
||||
s32 f18;
|
||||
} SubRec_801EB5C8_8017D7EC; /* 0x1C */
|
||||
|
||||
typedef struct {
|
||||
u16 g0;
|
||||
u16 g2;
|
||||
s32 g4;
|
||||
s32 g8;
|
||||
s32 gC;
|
||||
SubRec_801EB5C8_8017D7EC subs[16];
|
||||
} GroupRec_801EB5C8_8017D7EC; /* 0x1D0 */
|
||||
|
||||
|
||||
void func_8017D7EC(s32 param_1)
|
||||
{
|
||||
|
||||
extern GroupRec_801EB5C8_8017D7EC D_801B9708[8];
|
||||
s32 i, j;
|
||||
GroupRec_801EB5C8_8017D7EC *grp;
|
||||
SubRec_801EB5C8_8017D7EC *sub;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
grp = &D_801B9708[i];
|
||||
grp->g0 = 0;
|
||||
grp->g2 = i << 9;
|
||||
grp->gC = (rand() & 0xF) << 16;
|
||||
grp->g4 = ((rand() & 0xF) << 15) + 0x10000;
|
||||
grp->g8 = ((rand() & 0xF) << 12) + 0x8000;
|
||||
|
||||
for (j = 0; j < 16; j++) {
|
||||
sub = &grp->subs[j];
|
||||
sub->f0 = 0;
|
||||
sub->f2 = (rand() & 3) + 4;
|
||||
sub->f8 = (j << 8) + (rand() & 0xF) * 56;
|
||||
sub->fA = (rand() & 0xF) << 8;
|
||||
sub->f14 = (rand() & 0xF) << 13;
|
||||
sub->fC = ((rand() & 0xF) << 14) + 0x10000;
|
||||
sub->f10 = ((rand() & 0xF) << 12) + 0x8000;
|
||||
sub->f4 = 0x200;
|
||||
sub->f6 = (rand() & 0xF) << 4;
|
||||
sub->f18 = ((rand() & 3) << 5) + 0x40;
|
||||
}
|
||||
}
|
||||
|
||||
*(u16 *)(param_1 + 2) = *(u16 *)(param_1 + 2) + 1;
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_105/nonmatchings/ov_SC03_105_jr_8017C8D0", func_8017D994);
|
||||
|
||||
|
||||
@@ -76,7 +76,6 @@ extern s32 func_80146128(void);
|
||||
extern void func_80146360(void);
|
||||
extern void func_801463A0();
|
||||
extern void func_8014607C(void);
|
||||
extern s32 *D_80126B78;
|
||||
extern u8 D_80078EC1;
|
||||
extern s32 D_80078EC8;
|
||||
extern s32 D_80126B9C;
|
||||
@@ -3638,7 +3637,101 @@ extern void func_800296F8(void);
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_109/nonmatchings/ov_SC03_109_jr_8017C180", func_8017E1AC);
|
||||
extern s32 func_8012BDBC(s32 a0, s32 a1);
|
||||
extern s32 func_80135888(s32 a0, s32 a1, s32 a2, s32 a3);
|
||||
extern void func_80172710(void);
|
||||
extern s32 func_80178BF8();
|
||||
#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_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" )
|
||||
|
||||
/* §71 sibling: identical shape to func_8018F390 (same TU, this file, D_80126B78/RotTransSV/
|
||||
* func_80135888/func_8012BDBC/func_80178BF8/func_80172710 idiom) already MATCHED -- only the
|
||||
* per-overlay data symbol (D_80197290 vs D_801E33F0) differs. §37 asm-label alias avoids the
|
||||
* `conflicting types` clash with the fleet's `extern void func_8017E1AC(void);` used elsewhere
|
||||
* in this TU as a state-handler function pointer. */
|
||||
|
||||
s32 aF801904E0() __asm__("func_8017E1AC");
|
||||
|
||||
s32 aF801904E0(param_1)
|
||||
void *param_1;
|
||||
{
|
||||
|
||||
extern s32 *D_80126B78;
|
||||
extern u8 D_80197290[];
|
||||
MATRIX m;
|
||||
s32 obj;
|
||||
s32 sv0[2];
|
||||
s32 sv1[2];
|
||||
s32 flag;
|
||||
|
||||
obj = *(s32 *)((s32)param_1 + 0x64);
|
||||
m = *(MATRIX *)((u8 *)D_80126B78 + 0x34);
|
||||
|
||||
gte_SetRotMatrix(&m);
|
||||
gte_SetTransMatrix(&m);
|
||||
|
||||
RotTransSV(D_80197290, sv0, &flag);
|
||||
RotTransSV(D_80197290 + 8, sv1, &flag);
|
||||
|
||||
if (func_80135888(*(s32 *)(*(s32 *)((s32)param_1 + 0x64) + 0x20),
|
||||
*(s32 *)(*(s32 *)((s32)param_1 + 0x64) + 0x58),
|
||||
(s32)sv0, (s32)sv1) == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (func_8012BDBC(obj, 0x300) == 0) {
|
||||
return 0;
|
||||
}
|
||||
*(s16 *)(obj + 0x2) = 3;
|
||||
func_80178BF8();
|
||||
return (s32)func_80172710;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -5594,7 +5594,99 @@ void func_80182C04(void *a0) {
|
||||
void func_80182C40(void) {
|
||||
}
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_124/nonmatchings/ov_SC03_124_jr_8017AE2C", func_80182C48);
|
||||
|
||||
extern s32 func_8012BEE8(s32 a0);
|
||||
extern s32 rand(void);
|
||||
|
||||
void func_80182C48(s32 param_1) {
|
||||
s32 uVar1;
|
||||
s32 iVar2;
|
||||
register s32 iVar3 __asm__("$3");
|
||||
register s32 iVar4 __asm__("$16");
|
||||
u32 uVar3;
|
||||
|
||||
uVar1 = *(u16 *)(param_1 + 0x34);
|
||||
if (uVar1 == 1) {
|
||||
goto case1;
|
||||
}
|
||||
if (uVar1 < 2) {
|
||||
if (uVar1 == 0) {
|
||||
goto case0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (uVar1 == 2) {
|
||||
goto case2;
|
||||
}
|
||||
if (uVar1 != 3) {
|
||||
return;
|
||||
}
|
||||
goto case3;
|
||||
|
||||
case0:
|
||||
iVar2 = func_8012BEE8(param_1);
|
||||
if (iVar2 == 0) {
|
||||
return;
|
||||
}
|
||||
*(s32 *)(param_1 + 0x1c) = 0x40;
|
||||
*(u16 *)(param_1 + 0x34) = *(u16 *)(param_1 + 0x34) + 1;
|
||||
uVar3 = rand();
|
||||
iVar4 = uVar3 & 0x3fff;
|
||||
iVar4 = iVar4 + 0x7800;
|
||||
uVar3 = rand();
|
||||
if ((uVar3 & 1) == 0) {
|
||||
iVar4 = -iVar4;
|
||||
}
|
||||
*(s32 *)(param_1 + 0xe0) = iVar4;
|
||||
*(s32 *)(param_1 + 0xe4) = 0;
|
||||
return;
|
||||
|
||||
case1:
|
||||
iVar3 = *(s32 *)(param_1 + 0xe4);
|
||||
iVar3 = iVar3 + *(s32 *)(param_1 + 0xe0);
|
||||
*(s32 *)(param_1 + 0xdc) = *(s32 *)(param_1 + 0xdc) + iVar3;
|
||||
*(s32 *)(param_1 + 0xe4) = iVar3;
|
||||
*(u16 *)(*(s32 *)(param_1 + 0x20) + 0x12) = *(u16 *)(param_1 + 0xde);
|
||||
iVar2 = func_8012BEE8(param_1);
|
||||
if (iVar2 == 0) {
|
||||
return;
|
||||
}
|
||||
*(u16 *)(param_1 + 0x34) = *(u16 *)(param_1 + 0x34) + 1;
|
||||
uVar3 = rand();
|
||||
uVar3 = uVar3 & 0x3f;
|
||||
goto tail;
|
||||
|
||||
case2:
|
||||
*(s32 *)(param_1 + 0xdc) = *(s32 *)(param_1 + 0xdc) + *(s32 *)(param_1 + 0xe4);
|
||||
*(u16 *)(*(s32 *)(param_1 + 0x20) + 0x12) = *(u16 *)(param_1 + 0xde);
|
||||
iVar2 = func_8012BEE8(param_1);
|
||||
if (iVar2 == 0) {
|
||||
return;
|
||||
}
|
||||
*(s32 *)(param_1 + 0x1c) = 0x40;
|
||||
*(u16 *)(param_1 + 0x34) = *(u16 *)(param_1 + 0x34) + 1;
|
||||
*(s32 *)(param_1 + 0xe0) = -*(s32 *)(param_1 + 0xe0);
|
||||
return;
|
||||
|
||||
case3:
|
||||
__asm__ __volatile__("" ::: "memory");
|
||||
iVar3 = *(s32 *)(param_1 + 0xe4);
|
||||
iVar3 = iVar3 + *(s32 *)(param_1 + 0xe0);
|
||||
*(s32 *)(param_1 + 0xdc) = *(s32 *)(param_1 + 0xdc) + iVar3;
|
||||
*(s32 *)(param_1 + 0xe4) = iVar3;
|
||||
*(u16 *)(*(s32 *)(param_1 + 0x20) + 0x12) = *(u16 *)(param_1 + 0xde);
|
||||
iVar2 = func_8012BEE8(param_1);
|
||||
if (iVar2 == 0) {
|
||||
return;
|
||||
}
|
||||
*(u16 *)(param_1 + 0x34) = 0;
|
||||
uVar3 = rand();
|
||||
uVar3 = uVar3 & 0xff;
|
||||
|
||||
tail:
|
||||
*(u32 *)(param_1 + 0x1c) = uVar3 + 0x40;
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern void (*D_801906E0[])(void);
|
||||
|
||||
@@ -2984,22 +2984,16 @@ extern void func_80185BD4(void);
|
||||
|
||||
extern s16 D_800B9A02;
|
||||
extern u8 D_801151C8[];
|
||||
extern s32 D_801151D0;
|
||||
extern s16 D_80115126;
|
||||
extern u16 D_80115112;
|
||||
extern u16 D_8011511A;
|
||||
extern u8 D_80115138[];
|
||||
extern u8 D_80115148[];
|
||||
extern s32 D_80115130;
|
||||
extern u8 D_800B9A15;
|
||||
|
||||
extern s16 D_801E2360;
|
||||
extern u16 D_801E2364;
|
||||
extern s16 D_801E2368;
|
||||
extern s32 D_801E2358;
|
||||
extern s32 D_801E235C;
|
||||
extern s16 D_801E23E8;
|
||||
extern s16 D_801E23EC;
|
||||
extern s16 D_801E23F0;
|
||||
extern s16 D_801E23F4;
|
||||
extern s16 D_801E23F8;
|
||||
@@ -3034,6 +3028,18 @@ extern s32 func_80188C68(s32 a0, s16 a1);
|
||||
extern s16 func_8018957C(s32 a0);
|
||||
|
||||
void func_80187010(void) {
|
||||
/* [T51] scoped in from file scope: a file-scope decl of these symbols constrains every
|
||||
LATER function in this TU, which blocks a byte-true decl of a different type.
|
||||
Declaration-only move (cookbook §103); the whole-binary byte-gate is the arbiter. */
|
||||
extern u16 D_801E2364;
|
||||
extern s16 D_801E2368;
|
||||
/* [T51] scoped in from file scope: a file-scope decl of these symbols constrains every
|
||||
LATER function in this TU, which blocks a byte-true decl of a different type.
|
||||
Declaration-only move (cookbook §103); the whole-binary byte-gate is the arbiter. */
|
||||
extern s32 D_801151D0;
|
||||
extern s16 D_801E23EC;
|
||||
extern s16 D_80115126;
|
||||
extern u16 D_8011511A;
|
||||
s32 s0;
|
||||
s32 pad[2];
|
||||
(void)&pad;
|
||||
@@ -3644,7 +3650,125 @@ INCLUDE_ASM("asm/ov_SC03_124/nonmatchings/ov_SC03_124_jr_80187010", func_8018953
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_124/nonmatchings/ov_SC03_124_jr_80187010", func_8018957C);
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_124/nonmatchings/ov_SC03_124_jr_80187010", func_801895C8);
|
||||
|
||||
/* func_801895C8 — ov_SC03_001 (133 ins), exemplar of a 5-member open-only
|
||||
* h_norm cluster. Builds the full-screen fade overlay: a DR_MODE-style 8-byte
|
||||
* GP0 packet (0xE1000015), a 320x240 semi-transparent gouraud quad (POLY_G4,
|
||||
* code 0x3A), and a second 8-byte GP0 packet (0xE1000240), each linked into the
|
||||
* current OT with the psyq `addPrim` idiom. The type shapes and the
|
||||
* `((PTag *)x)->addr = ((PTag *)ot)->addr; ((PTag *)ot)->addr = (u32)x;` pair
|
||||
* are copied VERBATIM from the already-matched neighbour func_8018BCD4 in this
|
||||
* same TU (§71) — Env_* / PTag_* there are the fleet-canonical shapes.
|
||||
*
|
||||
* Levers that were load-bearing (all byte-tested; the draft is PIN-FREE):
|
||||
* §20 &D_801151D0 / &D_800B9A02 taken into pointer LOCALS -> each address is
|
||||
* force_reg'd once (lui+addiu -> $t2 / $a3) instead of a %lo per use.
|
||||
* §36 the 24-bit BITFIELD store, not a hand-written mask, is what emits
|
||||
* 0x00FFFFFF (lui+ori) ahead of 0xFF000000 (lui) while the body ANDs the
|
||||
* destination first — expmed's store_fixed_bit_field signature.
|
||||
* §37 asm-label aliases for D_801E2364/D_801E2368: the TU canon is u16/s16
|
||||
* but the target does a bare `lbu %lo(sym)`, and a plain block-scope
|
||||
* `extern u8` would be a conflicting redeclaration.
|
||||
* --- `volatile` on the OT index read keeps all SIX *pbh loads alive; a plain
|
||||
* read cse-folds them and the function loses ~25 instructions.
|
||||
* S1 the whole body is ONE branch-free basic block and every store ties at
|
||||
* the same priority, so forward asm order == source statement order —
|
||||
* the POLY_G4 block below is a literal transcription of the target.
|
||||
* S2 `p` is destructively updated (multi-set -> no birthing boost) so its
|
||||
* `addiu +8` floats up into the preceding load-delay gap, while `r` is a
|
||||
* FRESH single-set local (boosted) so its `addiu +0x24` sinks to sit
|
||||
* immediately before `sb 3($a0)`. Both placements are the target's.
|
||||
* --- the bare `p = r;` before r's uses is a COMBINE BARRIER: without a SET
|
||||
* of `p` between `r = p + 9` and r's first use, `can_combine_p` lets
|
||||
* combine substitute `r` -> `p + 0x24` into every MEM offset and the
|
||||
* `addiu` disappears entirely (and, at the tail, `p += 2` folds to
|
||||
* `addiu $t3,$t3,0x2C` off the stale base instead of `addiu $t3,$a0,8`).
|
||||
* It also fixes the register rotation for free — verified that adding or
|
||||
* removing `register __asm__` pins on p/r/pbh is a byte no-op.
|
||||
*/
|
||||
|
||||
/* ---- TU-visible spellings (file scope of ov_SC03_001_jr_8018A3A8.c) ---- */
|
||||
|
||||
void func_801895C8(void) {
|
||||
|
||||
extern s32 D_801151D0;
|
||||
extern u16 D_801E2364;
|
||||
extern s16 D_801E2368;
|
||||
/* §100/§120: draft-local, uniquely-named types — they live in the BODY so
|
||||
* they cannot collide with the TU's own Env_8018BCD4 / PTag_8018BCD4. */
|
||||
typedef struct { u32 addr : 24; u32 len : 8; } PTag_8018C960_801895C8;
|
||||
typedef struct { u32 *ot; u32 pad[4]; } Env_8018C960_801895C8; /* 0x14 stride */
|
||||
typedef struct {
|
||||
u32 tag; /* 0x00 */
|
||||
u8 r0, g0, b0, code; /* 0x04..0x07 */
|
||||
s16 x0, y0; /* 0x08, 0x0A */
|
||||
u8 r1, g1, b1, p1; /* 0x0C..0x0F */
|
||||
s16 x1, y1; /* 0x10, 0x12 */
|
||||
u8 r2, g2, b2, p2; /* 0x14..0x17 */
|
||||
s16 x2, y2; /* 0x18, 0x1A */
|
||||
u8 r3, g3, b3, p3; /* 0x1C..0x1F */
|
||||
s16 x3, y3; /* 0x20, 0x22 */
|
||||
} PG4_8018C960_801895C8; /* -> 0x24 */
|
||||
|
||||
extern Env_8018C960_801895C8 D_800AE7BC[];
|
||||
extern u8 aD801EF1EC __asm__("D_801E2364");
|
||||
extern u8 aD801EF1F0 __asm__("D_801E2368");
|
||||
|
||||
u32 **pp;
|
||||
volatile u16 *pbh;
|
||||
u32 *p;
|
||||
u32 *r;
|
||||
u8 c1, c2;
|
||||
|
||||
pp = (u32 **)&D_801151D0;
|
||||
pbh = (volatile u16 *)&D_800B9A02;
|
||||
|
||||
p = *pp;
|
||||
((PTag_8018C960_801895C8 *)p)->len = 1;
|
||||
p[1] = 0xE1000015;
|
||||
((PTag_8018C960_801895C8 *)p)->addr = ((PTag_8018C960_801895C8 *)D_800AE7BC[*pbh].ot)->addr;
|
||||
((PTag_8018C960_801895C8 *)D_800AE7BC[*pbh].ot)->addr = (u32)p;
|
||||
|
||||
p += 2;
|
||||
((PG4_8018C960_801895C8 *)p)->tag = 0x08000000;
|
||||
((PG4_8018C960_801895C8 *)p)->code = 0x3A;
|
||||
((PG4_8018C960_801895C8 *)p)->x2 = -160;
|
||||
((PG4_8018C960_801895C8 *)p)->x0 = -160;
|
||||
((PG4_8018C960_801895C8 *)p)->x3 = 160;
|
||||
((PG4_8018C960_801895C8 *)p)->x1 = 160;
|
||||
c1 = aD801EF1EC;
|
||||
((PG4_8018C960_801895C8 *)p)->b1 = c1;
|
||||
((PG4_8018C960_801895C8 *)p)->b0 = c1;
|
||||
((PG4_8018C960_801895C8 *)p)->g1 = c1;
|
||||
((PG4_8018C960_801895C8 *)p)->g0 = c1;
|
||||
((PG4_8018C960_801895C8 *)p)->r1 = c1;
|
||||
((PG4_8018C960_801895C8 *)p)->r0 = c1;
|
||||
c2 = aD801EF1F0;
|
||||
((PG4_8018C960_801895C8 *)p)->y1 = -120;
|
||||
((PG4_8018C960_801895C8 *)p)->b3 = c2;
|
||||
((PG4_8018C960_801895C8 *)p)->b2 = c2;
|
||||
((PG4_8018C960_801895C8 *)p)->g3 = c2;
|
||||
((PG4_8018C960_801895C8 *)p)->g2 = c2;
|
||||
((PG4_8018C960_801895C8 *)p)->r3 = c2;
|
||||
((PG4_8018C960_801895C8 *)p)->r2 = c2;
|
||||
((PG4_8018C960_801895C8 *)p)->y0 = -120;
|
||||
((PG4_8018C960_801895C8 *)p)->y3 = 120;
|
||||
((PG4_8018C960_801895C8 *)p)->y2 = 120;
|
||||
|
||||
((PTag_8018C960_801895C8 *)p)->addr = ((PTag_8018C960_801895C8 *)D_800AE7BC[*pbh].ot)->addr;
|
||||
((PTag_8018C960_801895C8 *)D_800AE7BC[*pbh].ot)->addr = (u32)p;
|
||||
|
||||
r = p + 9; /* 0x24 */
|
||||
p = r; /* COMBINE BARRIER — see header */
|
||||
((PTag_8018C960_801895C8 *)r)->len = 1;
|
||||
r[1] = 0xE1000240;
|
||||
((PTag_8018C960_801895C8 *)r)->addr = ((PTag_8018C960_801895C8 *)D_800AE7BC[*pbh].ot)->addr;
|
||||
((PTag_8018C960_801895C8 *)D_800AE7BC[*pbh].ot)->addr = (u32)r;
|
||||
|
||||
p += 2;
|
||||
*pp = p;
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern void (*D_801D52BC[])(void);
|
||||
|
||||
@@ -5342,7 +5342,6 @@ void func_80180E54(void *a0) {
|
||||
}
|
||||
|
||||
|
||||
extern s32 *D_80126B78;
|
||||
extern u8 D_8019D340[];
|
||||
extern s32 func_8012BDBC(s32 a0, s32 a1);
|
||||
extern s32 func_80135888(s32 a0, s32 a1, s32 a2, s32 a3);
|
||||
@@ -5378,6 +5377,10 @@ s32 aF8018A224() __asm__("func_80180EC4");
|
||||
s32 aF8018A224(param_1)
|
||||
void *param_1;
|
||||
{
|
||||
/* [T51] scoped in from file scope: a file-scope decl of these symbols constrains every
|
||||
LATER function in this TU, which blocks a byte-true decl of a different type.
|
||||
Declaration-only move (cookbook §103); the whole-binary byte-gate is the arbiter. */
|
||||
extern s32 *D_80126B78;
|
||||
s32 *m;
|
||||
s32 obj;
|
||||
s32 sv0[2];
|
||||
@@ -5894,7 +5897,101 @@ extern void func_800296F8(void *a0);
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC04_000/nonmatchings/ov_SC04_000_jr_8017BEBC", func_801830E4);
|
||||
extern s32 func_8012BDBC(s32 a0, s32 a1);
|
||||
extern s32 func_80135888(s32 a0, s32 a1, s32 a2, s32 a3);
|
||||
extern void func_80172710(void);
|
||||
extern s32 func_80178BF8();
|
||||
#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_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" )
|
||||
|
||||
/* §71 sibling: identical shape to func_8018F390 (same TU, this file, D_80126B78/RotTransSV/
|
||||
* func_80135888/func_8012BDBC/func_80178BF8/func_80172710 idiom) already MATCHED -- only the
|
||||
* per-overlay data symbol (D_801A7028 vs D_801E33F0) differs. §37 asm-label alias avoids the
|
||||
* `conflicting types` clash with the fleet's `extern void func_801830E4(void);` used elsewhere
|
||||
* in this TU as a state-handler function pointer. */
|
||||
|
||||
s32 aF801904E0() __asm__("func_801830E4");
|
||||
|
||||
s32 aF801904E0(param_1)
|
||||
void *param_1;
|
||||
{
|
||||
|
||||
extern s32 *D_80126B78;
|
||||
extern u8 D_801A7028[];
|
||||
MATRIX m;
|
||||
s32 obj;
|
||||
s32 sv0[2];
|
||||
s32 sv1[2];
|
||||
s32 flag;
|
||||
|
||||
obj = *(s32 *)((s32)param_1 + 0x64);
|
||||
m = *(MATRIX *)((u8 *)D_80126B78 + 0x34);
|
||||
|
||||
gte_SetRotMatrix(&m);
|
||||
gte_SetTransMatrix(&m);
|
||||
|
||||
RotTransSV(D_801A7028, sv0, &flag);
|
||||
RotTransSV(D_801A7028 + 8, sv1, &flag);
|
||||
|
||||
if (func_80135888(*(s32 *)(*(s32 *)((s32)param_1 + 0x64) + 0x20),
|
||||
*(s32 *)(*(s32 *)((s32)param_1 + 0x64) + 0x58),
|
||||
(s32)sv0, (s32)sv1) == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (func_8012BDBC(obj, 0x300) == 0) {
|
||||
return 0;
|
||||
}
|
||||
*(s16 *)(obj + 0x2) = 3;
|
||||
func_80178BF8();
|
||||
return (s32)func_80172710;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -6688,9 +6688,195 @@ INCLUDE_ASM("asm/ov_SC04_002/nonmatchings/ov_SC04_002_jr_8017BEBC", func_8018717
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC04_002/nonmatchings/ov_SC04_002_jr_8017BEBC", func_801871EC);
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC04_002/nonmatchings/ov_SC04_002_jr_8017BEBC", func_8018739C);
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC04_002/nonmatchings/ov_SC04_002_jr_8017BEBC", func_80187604);
|
||||
/* --- types: ALREADY PRESENT in src/shared/engine_types.h (pulled into the real TU
|
||||
* via engine_core.h). Delete these four typedefs when banking into
|
||||
* src/ov_SC02_041/ov_SC02_041_jr_8017BEBC.c — they exist verbatim at
|
||||
* engine_types.h:1168 (MATRIX), :1726 (CV_801837B0), :3787..:3793 (SV/PKT).
|
||||
* The immediate neighbour func_801837B0 (line 5484, MATCHed) uses PKT_801837B0
|
||||
* with the identical v[4]/rgb[4]/code layout and the same `pkt.code = 0x50000000`. */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void func_8018739C(s32 a0, void *a1, s32 a2)
|
||||
{
|
||||
extern u16 D_800B99DA;
|
||||
extern u8 D_801B4F84[];
|
||||
extern u8 D_801B4F98[];
|
||||
extern s32 func_80017758(void *a0, void *a1); /* canon, TU line 1761 */
|
||||
extern void func_801878B0(s32 a0, void *a1, s32 a2, MATRIX *a3);
|
||||
MATRIX m; /* sp+0x10 */
|
||||
PKT_801837B0 pkt; /* sp+0x30 */
|
||||
u8 *p;
|
||||
s32 i;
|
||||
|
||||
func_801878B0(a0, a1, a2, &m);
|
||||
|
||||
if (D_800B99DA & 1) {
|
||||
pkt.rgb[1].b = 0x58;
|
||||
} else {
|
||||
pkt.rgb[1].b = 0x48;
|
||||
}
|
||||
|
||||
p = D_801B4F84;
|
||||
pkt.rgb[0].r = pkt.rgb[0].g = pkt.rgb[0].b = 0;
|
||||
pkt.rgb[2].r = pkt.rgb[2].g = pkt.rgb[2].b = 0;
|
||||
pkt.rgb[3].r = pkt.rgb[3].g = pkt.rgb[3].b = 0;
|
||||
pkt.code = 0x50000000;
|
||||
pkt.v[0].vz = pkt.v[2].vz = pkt.v[3].vz = 0;
|
||||
pkt.v[1].vx = pkt.v[1].vy = pkt.v[1].vz = 0;
|
||||
pkt.rgb[1].r = pkt.rgb[1].g = pkt.rgb[1].b >> 2;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
pkt.v[0].vx = (s8)*p++;
|
||||
pkt.v[0].vy = (s8)*p++;
|
||||
pkt.v[2].vx = (s8)*p++;
|
||||
pkt.v[2].vy = (s8)*p++;
|
||||
pkt.v[3].vx = (s8)*p++;
|
||||
pkt.v[3].vy = (s8)*p--;
|
||||
func_80017758(&pkt.v[0], &m);
|
||||
}
|
||||
|
||||
p = D_801B4F98;
|
||||
pkt.v[1].vz = -0x12;
|
||||
pkt.v[0].vy = pkt.v[2].vy = pkt.v[3].vy = 0;
|
||||
pkt.v[1].vx = pkt.v[1].vy = 0;
|
||||
pkt.rgb[1].b <<= 1;
|
||||
pkt.rgb[1].r = pkt.rgb[1].g <<= 1;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
pkt.v[0].vx = (s8)*p++;
|
||||
pkt.v[0].vz = (s8)*p++;
|
||||
pkt.v[2].vx = (s8)*p++;
|
||||
pkt.v[2].vz = (s8)*p++;
|
||||
pkt.v[3].vx = (s8)*p++;
|
||||
pkt.v[3].vz = (s8)*p--;
|
||||
if (i == 2) {
|
||||
pkt.rgb[3].b = pkt.rgb[1].b;
|
||||
pkt.rgb[3].r = pkt.rgb[3].g = pkt.rgb[1].r;
|
||||
} else if (i == 3) {
|
||||
pkt.rgb[3].r = pkt.rgb[3].g = pkt.rgb[3].b = 0;
|
||||
pkt.rgb[0].b = pkt.rgb[1].b;
|
||||
pkt.rgb[0].r = pkt.rgb[0].g = pkt.rgb[1].r;
|
||||
}
|
||||
func_80017758(&pkt.v[0], &m);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* func_80187604 (ov_SC02_041_jr_8017BEBC, 171 ins) — byte-matched.
|
||||
*
|
||||
* Builds a GTE 4-vertex/4-colour packet on the stack and pushes it three times
|
||||
* through func_80017758 (the shared "transform + link prim" helper, see the
|
||||
* sibling func_80182BDC in ov_SC03_099_jr_8017BEBC.c, which uses the identical
|
||||
* 0x00 verts / 0x20 colours / 0x30 code layout).
|
||||
*
|
||||
* Layout notes that had to be right for the frame to come out as 0x78:
|
||||
* - mtx[0x20] is declared FIRST so it takes the low local slot (sp+0x10) and
|
||||
* the packet takes sp+0x30 (MIPS frame grows UP; slots go in decl order).
|
||||
* - locals total 0x54 -> MIPS_STACK_ALIGN 0x58, +0x10 outgoing args +12 saved
|
||||
* regs = 0x74 -> 0x78.
|
||||
*
|
||||
* Two idioms this needed (both byte-verified here):
|
||||
* 1. The colour/vertex zero-fills are CHAINED assignments; `a = b = c = 0`
|
||||
* emits the stores RIGHT-TO-LEFT, which is what produces the descending
|
||||
* 0x52/0x51/0x50 and 0x4C/0x44/0x34 store orders.
|
||||
* 2. The brightness must be stored into the packet IN EACH ARM (cross-jump
|
||||
* then merges the three `sb`s into one at the join). Hoisting it into an
|
||||
* `s32 br` local instead lets cse/combine forward the stored value into
|
||||
* the `>> 2`, which DELETES the `lbu 0x54(sp)` reload (-1 instruction).
|
||||
* 3. The inner test is written `!(flags & 2) -> 0x80` so gcc's
|
||||
* jump-if-false lands `bnez` (with 0xC0 stolen into the delay slot from
|
||||
* the branch target), not `beqz` with 0x80.
|
||||
*/
|
||||
|
||||
void func_80187604(s32 a0, s32 a1, s32 a2)
|
||||
{
|
||||
typedef struct {
|
||||
s16 vx, vy, vz, pad;
|
||||
} SV_80183FE0_80187604;
|
||||
|
||||
typedef struct {
|
||||
SV_80183FE0_80187604 v[4]; /* 0x00 */
|
||||
u8 c[4][4]; /* 0x20 */
|
||||
u32 code; /* 0x30 */
|
||||
} Prim_80183FE0_80187604; /* 0x34 */
|
||||
|
||||
extern void func_801878B0(s32 a0, s32 a1, s32 a2, void *a3);
|
||||
extern s32 func_80017758(void *a0, void *a1);
|
||||
extern u16 D_800B99DA;
|
||||
extern u8 D_8018B4D8[];
|
||||
extern u8 D_8018B4EC[];
|
||||
|
||||
u8 mtx[0x20];
|
||||
Prim_80183FE0_80187604 p;
|
||||
u8 *q;
|
||||
s32 i;
|
||||
|
||||
func_801878B0(a0, a1, a2, mtx);
|
||||
|
||||
p.v[0].vz = p.v[2].vz = p.v[3].vz = 0;
|
||||
p.v[1].vx = p.v[1].vy = p.v[1].vz = 0;
|
||||
if (D_800B99DA & 1) {
|
||||
p.c[1][0] = 0xA0;
|
||||
} else if (!(D_800B99DA & 2)) {
|
||||
p.c[1][0] = 0x80;
|
||||
} else {
|
||||
p.c[1][0] = 0xC0;
|
||||
}
|
||||
p.c[0][0] = p.c[0][1] = p.c[0][2] = 0;
|
||||
p.c[2][0] = p.c[2][1] = p.c[2][2] = 0;
|
||||
p.c[3][0] = p.c[3][1] = p.c[3][2] = 0;
|
||||
p.code = 0x50000000;
|
||||
p.c[1][1] = p.c[1][2] = p.c[1][0] >> 2;
|
||||
|
||||
q = D_8018B4D8;
|
||||
for (i = 0; i < 4; i++) {
|
||||
p.v[0].vx = (s8)*q++;
|
||||
p.v[0].vy = (s8)*q++;
|
||||
p.v[2].vx = (s8)*q++;
|
||||
p.v[2].vy = (s8)*q++;
|
||||
p.v[3].vx = (s8)*q++;
|
||||
p.v[3].vy = (s8)*q--;
|
||||
func_80017758(&p, mtx);
|
||||
}
|
||||
|
||||
p.v[0].vy = p.v[2].vy = p.v[3].vy = 0;
|
||||
p.v[1].vx = p.v[1].vy = 0;
|
||||
p.v[1].vz = -0x20;
|
||||
q = D_8018B4EC;
|
||||
for (i = 0; i < 4; i++) {
|
||||
p.v[0].vx = (s8)*q++;
|
||||
p.v[0].vz = (s8)*q++;
|
||||
p.v[2].vx = (s8)*q++;
|
||||
p.v[2].vz = (s8)*q++;
|
||||
p.v[3].vx = (s8)*q++;
|
||||
p.v[3].vz = (s8)*q--;
|
||||
func_80017758(&p, mtx);
|
||||
if (i == 1) {
|
||||
p.v[1].vz = 0x20;
|
||||
q += 2;
|
||||
}
|
||||
}
|
||||
q += 2;
|
||||
|
||||
p.v[0].vx = 0;
|
||||
p.v[0].vz = -0x20;
|
||||
p.c[0][0] = p.c[1][0];
|
||||
p.c[0][1] = p.c[0][2] = p.c[1][1];
|
||||
for (i = 0; i < 2; i++) {
|
||||
p.v[2].vx = (s8)*q++;
|
||||
p.v[2].vz = (s8)*q++;
|
||||
p.v[3].vx = (s8)*q++;
|
||||
p.v[3].vz = (s8)*q++;
|
||||
func_80017758(&p, mtx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC04_002/nonmatchings/ov_SC04_002_jr_8017BEBC", func_801878B0);
|
||||
|
||||
|
||||
@@ -6844,9 +6844,195 @@ INCLUDE_ASM("asm/ov_SC04_005/nonmatchings/ov_SC04_005_jr_8017BEBC", func_8018654
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC04_005/nonmatchings/ov_SC04_005_jr_8017BEBC", func_801865BC);
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC04_005/nonmatchings/ov_SC04_005_jr_8017BEBC", func_8018676C);
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC04_005/nonmatchings/ov_SC04_005_jr_8017BEBC", func_801869D4);
|
||||
/* --- types: ALREADY PRESENT in src/shared/engine_types.h (pulled into the real TU
|
||||
* via engine_core.h). Delete these four typedefs when banking into
|
||||
* src/ov_SC02_041/ov_SC02_041_jr_8017BEBC.c — they exist verbatim at
|
||||
* engine_types.h:1168 (MATRIX), :1726 (CV_801837B0), :3787..:3793 (SV/PKT).
|
||||
* The immediate neighbour func_801837B0 (line 5484, MATCHed) uses PKT_801837B0
|
||||
* with the identical v[4]/rgb[4]/code layout and the same `pkt.code = 0x50000000`. */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void func_8018676C(s32 a0, void *a1, s32 a2)
|
||||
{
|
||||
extern u16 D_800B99DA;
|
||||
extern u8 D_801B5A10[];
|
||||
extern u8 D_801B5A24[];
|
||||
extern s32 func_80017758(void *a0, void *a1); /* canon, TU line 1761 */
|
||||
extern void func_80186C80(s32 a0, void *a1, s32 a2, MATRIX *a3);
|
||||
MATRIX m; /* sp+0x10 */
|
||||
PKT_801837B0 pkt; /* sp+0x30 */
|
||||
u8 *p;
|
||||
s32 i;
|
||||
|
||||
func_80186C80(a0, a1, a2, &m);
|
||||
|
||||
if (D_800B99DA & 1) {
|
||||
pkt.rgb[1].b = 0x58;
|
||||
} else {
|
||||
pkt.rgb[1].b = 0x48;
|
||||
}
|
||||
|
||||
p = D_801B5A10;
|
||||
pkt.rgb[0].r = pkt.rgb[0].g = pkt.rgb[0].b = 0;
|
||||
pkt.rgb[2].r = pkt.rgb[2].g = pkt.rgb[2].b = 0;
|
||||
pkt.rgb[3].r = pkt.rgb[3].g = pkt.rgb[3].b = 0;
|
||||
pkt.code = 0x50000000;
|
||||
pkt.v[0].vz = pkt.v[2].vz = pkt.v[3].vz = 0;
|
||||
pkt.v[1].vx = pkt.v[1].vy = pkt.v[1].vz = 0;
|
||||
pkt.rgb[1].r = pkt.rgb[1].g = pkt.rgb[1].b >> 2;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
pkt.v[0].vx = (s8)*p++;
|
||||
pkt.v[0].vy = (s8)*p++;
|
||||
pkt.v[2].vx = (s8)*p++;
|
||||
pkt.v[2].vy = (s8)*p++;
|
||||
pkt.v[3].vx = (s8)*p++;
|
||||
pkt.v[3].vy = (s8)*p--;
|
||||
func_80017758(&pkt.v[0], &m);
|
||||
}
|
||||
|
||||
p = D_801B5A24;
|
||||
pkt.v[1].vz = -0x12;
|
||||
pkt.v[0].vy = pkt.v[2].vy = pkt.v[3].vy = 0;
|
||||
pkt.v[1].vx = pkt.v[1].vy = 0;
|
||||
pkt.rgb[1].b <<= 1;
|
||||
pkt.rgb[1].r = pkt.rgb[1].g <<= 1;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
pkt.v[0].vx = (s8)*p++;
|
||||
pkt.v[0].vz = (s8)*p++;
|
||||
pkt.v[2].vx = (s8)*p++;
|
||||
pkt.v[2].vz = (s8)*p++;
|
||||
pkt.v[3].vx = (s8)*p++;
|
||||
pkt.v[3].vz = (s8)*p--;
|
||||
if (i == 2) {
|
||||
pkt.rgb[3].b = pkt.rgb[1].b;
|
||||
pkt.rgb[3].r = pkt.rgb[3].g = pkt.rgb[1].r;
|
||||
} else if (i == 3) {
|
||||
pkt.rgb[3].r = pkt.rgb[3].g = pkt.rgb[3].b = 0;
|
||||
pkt.rgb[0].b = pkt.rgb[1].b;
|
||||
pkt.rgb[0].r = pkt.rgb[0].g = pkt.rgb[1].r;
|
||||
}
|
||||
func_80017758(&pkt.v[0], &m);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* func_801869D4 (ov_SC02_041_jr_8017BEBC, 171 ins) — byte-matched.
|
||||
*
|
||||
* Builds a GTE 4-vertex/4-colour packet on the stack and pushes it three times
|
||||
* through func_80017758 (the shared "transform + link prim" helper, see the
|
||||
* sibling func_80182BDC in ov_SC03_099_jr_8017BEBC.c, which uses the identical
|
||||
* 0x00 verts / 0x20 colours / 0x30 code layout).
|
||||
*
|
||||
* Layout notes that had to be right for the frame to come out as 0x78:
|
||||
* - mtx[0x20] is declared FIRST so it takes the low local slot (sp+0x10) and
|
||||
* the packet takes sp+0x30 (MIPS frame grows UP; slots go in decl order).
|
||||
* - locals total 0x54 -> MIPS_STACK_ALIGN 0x58, +0x10 outgoing args +12 saved
|
||||
* regs = 0x74 -> 0x78.
|
||||
*
|
||||
* Two idioms this needed (both byte-verified here):
|
||||
* 1. The colour/vertex zero-fills are CHAINED assignments; `a = b = c = 0`
|
||||
* emits the stores RIGHT-TO-LEFT, which is what produces the descending
|
||||
* 0x52/0x51/0x50 and 0x4C/0x44/0x34 store orders.
|
||||
* 2. The brightness must be stored into the packet IN EACH ARM (cross-jump
|
||||
* then merges the three `sb`s into one at the join). Hoisting it into an
|
||||
* `s32 br` local instead lets cse/combine forward the stored value into
|
||||
* the `>> 2`, which DELETES the `lbu 0x54(sp)` reload (-1 instruction).
|
||||
* 3. The inner test is written `!(flags & 2) -> 0x80` so gcc's
|
||||
* jump-if-false lands `bnez` (with 0xC0 stolen into the delay slot from
|
||||
* the branch target), not `beqz` with 0x80.
|
||||
*/
|
||||
|
||||
void func_801869D4(s32 a0, s32 a1, s32 a2)
|
||||
{
|
||||
typedef struct {
|
||||
s16 vx, vy, vz, pad;
|
||||
} SV_80183FE0_801869D4;
|
||||
|
||||
typedef struct {
|
||||
SV_80183FE0_801869D4 v[4]; /* 0x00 */
|
||||
u8 c[4][4]; /* 0x20 */
|
||||
u32 code; /* 0x30 */
|
||||
} Prim_80183FE0_801869D4; /* 0x34 */
|
||||
|
||||
extern void func_80186C80(s32 a0, s32 a1, s32 a2, void *a3);
|
||||
extern s32 func_80017758(void *a0, void *a1);
|
||||
extern u16 D_800B99DA;
|
||||
extern u8 D_8018ABDC[];
|
||||
extern u8 D_8018ABF0[];
|
||||
|
||||
u8 mtx[0x20];
|
||||
Prim_80183FE0_801869D4 p;
|
||||
u8 *q;
|
||||
s32 i;
|
||||
|
||||
func_80186C80(a0, a1, a2, mtx);
|
||||
|
||||
p.v[0].vz = p.v[2].vz = p.v[3].vz = 0;
|
||||
p.v[1].vx = p.v[1].vy = p.v[1].vz = 0;
|
||||
if (D_800B99DA & 1) {
|
||||
p.c[1][0] = 0xA0;
|
||||
} else if (!(D_800B99DA & 2)) {
|
||||
p.c[1][0] = 0x80;
|
||||
} else {
|
||||
p.c[1][0] = 0xC0;
|
||||
}
|
||||
p.c[0][0] = p.c[0][1] = p.c[0][2] = 0;
|
||||
p.c[2][0] = p.c[2][1] = p.c[2][2] = 0;
|
||||
p.c[3][0] = p.c[3][1] = p.c[3][2] = 0;
|
||||
p.code = 0x50000000;
|
||||
p.c[1][1] = p.c[1][2] = p.c[1][0] >> 2;
|
||||
|
||||
q = D_8018ABDC;
|
||||
for (i = 0; i < 4; i++) {
|
||||
p.v[0].vx = (s8)*q++;
|
||||
p.v[0].vy = (s8)*q++;
|
||||
p.v[2].vx = (s8)*q++;
|
||||
p.v[2].vy = (s8)*q++;
|
||||
p.v[3].vx = (s8)*q++;
|
||||
p.v[3].vy = (s8)*q--;
|
||||
func_80017758(&p, mtx);
|
||||
}
|
||||
|
||||
p.v[0].vy = p.v[2].vy = p.v[3].vy = 0;
|
||||
p.v[1].vx = p.v[1].vy = 0;
|
||||
p.v[1].vz = -0x20;
|
||||
q = D_8018ABF0;
|
||||
for (i = 0; i < 4; i++) {
|
||||
p.v[0].vx = (s8)*q++;
|
||||
p.v[0].vz = (s8)*q++;
|
||||
p.v[2].vx = (s8)*q++;
|
||||
p.v[2].vz = (s8)*q++;
|
||||
p.v[3].vx = (s8)*q++;
|
||||
p.v[3].vz = (s8)*q--;
|
||||
func_80017758(&p, mtx);
|
||||
if (i == 1) {
|
||||
p.v[1].vz = 0x20;
|
||||
q += 2;
|
||||
}
|
||||
}
|
||||
q += 2;
|
||||
|
||||
p.v[0].vx = 0;
|
||||
p.v[0].vz = -0x20;
|
||||
p.c[0][0] = p.c[1][0];
|
||||
p.c[0][1] = p.c[0][2] = p.c[1][1];
|
||||
for (i = 0; i < 2; i++) {
|
||||
p.v[2].vx = (s8)*q++;
|
||||
p.v[2].vz = (s8)*q++;
|
||||
p.v[3].vx = (s8)*q++;
|
||||
p.v[3].vz = (s8)*q++;
|
||||
func_80017758(&p, mtx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC04_005/nonmatchings/ov_SC04_005_jr_8017BEBC", func_80186C80);
|
||||
|
||||
|
||||
@@ -5676,9 +5676,195 @@ INCLUDE_ASM("asm/ov_SC04_007/nonmatchings/ov_SC04_007_jr_8017BEBC", func_80182BB
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC04_007/nonmatchings/ov_SC04_007_jr_8017BEBC", func_80182C28);
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC04_007/nonmatchings/ov_SC04_007_jr_8017BEBC", func_80182DD8);
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC04_007/nonmatchings/ov_SC04_007_jr_8017BEBC", func_80183040);
|
||||
/* --- types: ALREADY PRESENT in src/shared/engine_types.h (pulled into the real TU
|
||||
* via engine_core.h). Delete these four typedefs when banking into
|
||||
* src/ov_SC02_041/ov_SC02_041_jr_8017BEBC.c — they exist verbatim at
|
||||
* engine_types.h:1168 (MATRIX), :1726 (CV_801837B0), :3787..:3793 (SV/PKT).
|
||||
* The immediate neighbour func_801837B0 (line 5484, MATCHed) uses PKT_801837B0
|
||||
* with the identical v[4]/rgb[4]/code layout and the same `pkt.code = 0x50000000`. */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void func_80182DD8(s32 a0, void *a1, s32 a2)
|
||||
{
|
||||
extern u16 D_800B99DA;
|
||||
extern u8 D_801980B8[];
|
||||
extern u8 D_801980CC[];
|
||||
extern s32 func_80017758(void *a0, void *a1); /* canon, TU line 1761 */
|
||||
extern void func_801832EC(s32 a0, void *a1, s32 a2, MATRIX *a3);
|
||||
MATRIX m; /* sp+0x10 */
|
||||
PKT_801837B0 pkt; /* sp+0x30 */
|
||||
u8 *p;
|
||||
s32 i;
|
||||
|
||||
func_801832EC(a0, a1, a2, &m);
|
||||
|
||||
if (D_800B99DA & 1) {
|
||||
pkt.rgb[1].b = 0x58;
|
||||
} else {
|
||||
pkt.rgb[1].b = 0x48;
|
||||
}
|
||||
|
||||
p = D_801980B8;
|
||||
pkt.rgb[0].r = pkt.rgb[0].g = pkt.rgb[0].b = 0;
|
||||
pkt.rgb[2].r = pkt.rgb[2].g = pkt.rgb[2].b = 0;
|
||||
pkt.rgb[3].r = pkt.rgb[3].g = pkt.rgb[3].b = 0;
|
||||
pkt.code = 0x50000000;
|
||||
pkt.v[0].vz = pkt.v[2].vz = pkt.v[3].vz = 0;
|
||||
pkt.v[1].vx = pkt.v[1].vy = pkt.v[1].vz = 0;
|
||||
pkt.rgb[1].r = pkt.rgb[1].g = pkt.rgb[1].b >> 2;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
pkt.v[0].vx = (s8)*p++;
|
||||
pkt.v[0].vy = (s8)*p++;
|
||||
pkt.v[2].vx = (s8)*p++;
|
||||
pkt.v[2].vy = (s8)*p++;
|
||||
pkt.v[3].vx = (s8)*p++;
|
||||
pkt.v[3].vy = (s8)*p--;
|
||||
func_80017758(&pkt.v[0], &m);
|
||||
}
|
||||
|
||||
p = D_801980CC;
|
||||
pkt.v[1].vz = -0x12;
|
||||
pkt.v[0].vy = pkt.v[2].vy = pkt.v[3].vy = 0;
|
||||
pkt.v[1].vx = pkt.v[1].vy = 0;
|
||||
pkt.rgb[1].b <<= 1;
|
||||
pkt.rgb[1].r = pkt.rgb[1].g <<= 1;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
pkt.v[0].vx = (s8)*p++;
|
||||
pkt.v[0].vz = (s8)*p++;
|
||||
pkt.v[2].vx = (s8)*p++;
|
||||
pkt.v[2].vz = (s8)*p++;
|
||||
pkt.v[3].vx = (s8)*p++;
|
||||
pkt.v[3].vz = (s8)*p--;
|
||||
if (i == 2) {
|
||||
pkt.rgb[3].b = pkt.rgb[1].b;
|
||||
pkt.rgb[3].r = pkt.rgb[3].g = pkt.rgb[1].r;
|
||||
} else if (i == 3) {
|
||||
pkt.rgb[3].r = pkt.rgb[3].g = pkt.rgb[3].b = 0;
|
||||
pkt.rgb[0].b = pkt.rgb[1].b;
|
||||
pkt.rgb[0].r = pkt.rgb[0].g = pkt.rgb[1].r;
|
||||
}
|
||||
func_80017758(&pkt.v[0], &m);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* func_80183040 (ov_SC02_041_jr_8017BEBC, 171 ins) — byte-matched.
|
||||
*
|
||||
* Builds a GTE 4-vertex/4-colour packet on the stack and pushes it three times
|
||||
* through func_80017758 (the shared "transform + link prim" helper, see the
|
||||
* sibling func_80182BDC in ov_SC03_099_jr_8017BEBC.c, which uses the identical
|
||||
* 0x00 verts / 0x20 colours / 0x30 code layout).
|
||||
*
|
||||
* Layout notes that had to be right for the frame to come out as 0x78:
|
||||
* - mtx[0x20] is declared FIRST so it takes the low local slot (sp+0x10) and
|
||||
* the packet takes sp+0x30 (MIPS frame grows UP; slots go in decl order).
|
||||
* - locals total 0x54 -> MIPS_STACK_ALIGN 0x58, +0x10 outgoing args +12 saved
|
||||
* regs = 0x74 -> 0x78.
|
||||
*
|
||||
* Two idioms this needed (both byte-verified here):
|
||||
* 1. The colour/vertex zero-fills are CHAINED assignments; `a = b = c = 0`
|
||||
* emits the stores RIGHT-TO-LEFT, which is what produces the descending
|
||||
* 0x52/0x51/0x50 and 0x4C/0x44/0x34 store orders.
|
||||
* 2. The brightness must be stored into the packet IN EACH ARM (cross-jump
|
||||
* then merges the three `sb`s into one at the join). Hoisting it into an
|
||||
* `s32 br` local instead lets cse/combine forward the stored value into
|
||||
* the `>> 2`, which DELETES the `lbu 0x54(sp)` reload (-1 instruction).
|
||||
* 3. The inner test is written `!(flags & 2) -> 0x80` so gcc's
|
||||
* jump-if-false lands `bnez` (with 0xC0 stolen into the delay slot from
|
||||
* the branch target), not `beqz` with 0x80.
|
||||
*/
|
||||
|
||||
void func_80183040(s32 a0, s32 a1, s32 a2)
|
||||
{
|
||||
typedef struct {
|
||||
s16 vx, vy, vz, pad;
|
||||
} SV_80183FE0_80183040;
|
||||
|
||||
typedef struct {
|
||||
SV_80183FE0_80183040 v[4]; /* 0x00 */
|
||||
u8 c[4][4]; /* 0x20 */
|
||||
u32 code; /* 0x30 */
|
||||
} Prim_80183FE0_80183040; /* 0x34 */
|
||||
|
||||
extern void func_801832EC(s32 a0, s32 a1, s32 a2, void *a3);
|
||||
extern s32 func_80017758(void *a0, void *a1);
|
||||
extern u16 D_800B99DA;
|
||||
extern u8 D_80188C74[];
|
||||
extern u8 D_80188C88[];
|
||||
|
||||
u8 mtx[0x20];
|
||||
Prim_80183FE0_80183040 p;
|
||||
u8 *q;
|
||||
s32 i;
|
||||
|
||||
func_801832EC(a0, a1, a2, mtx);
|
||||
|
||||
p.v[0].vz = p.v[2].vz = p.v[3].vz = 0;
|
||||
p.v[1].vx = p.v[1].vy = p.v[1].vz = 0;
|
||||
if (D_800B99DA & 1) {
|
||||
p.c[1][0] = 0xA0;
|
||||
} else if (!(D_800B99DA & 2)) {
|
||||
p.c[1][0] = 0x80;
|
||||
} else {
|
||||
p.c[1][0] = 0xC0;
|
||||
}
|
||||
p.c[0][0] = p.c[0][1] = p.c[0][2] = 0;
|
||||
p.c[2][0] = p.c[2][1] = p.c[2][2] = 0;
|
||||
p.c[3][0] = p.c[3][1] = p.c[3][2] = 0;
|
||||
p.code = 0x50000000;
|
||||
p.c[1][1] = p.c[1][2] = p.c[1][0] >> 2;
|
||||
|
||||
q = D_80188C74;
|
||||
for (i = 0; i < 4; i++) {
|
||||
p.v[0].vx = (s8)*q++;
|
||||
p.v[0].vy = (s8)*q++;
|
||||
p.v[2].vx = (s8)*q++;
|
||||
p.v[2].vy = (s8)*q++;
|
||||
p.v[3].vx = (s8)*q++;
|
||||
p.v[3].vy = (s8)*q--;
|
||||
func_80017758(&p, mtx);
|
||||
}
|
||||
|
||||
p.v[0].vy = p.v[2].vy = p.v[3].vy = 0;
|
||||
p.v[1].vx = p.v[1].vy = 0;
|
||||
p.v[1].vz = -0x20;
|
||||
q = D_80188C88;
|
||||
for (i = 0; i < 4; i++) {
|
||||
p.v[0].vx = (s8)*q++;
|
||||
p.v[0].vz = (s8)*q++;
|
||||
p.v[2].vx = (s8)*q++;
|
||||
p.v[2].vz = (s8)*q++;
|
||||
p.v[3].vx = (s8)*q++;
|
||||
p.v[3].vz = (s8)*q--;
|
||||
func_80017758(&p, mtx);
|
||||
if (i == 1) {
|
||||
p.v[1].vz = 0x20;
|
||||
q += 2;
|
||||
}
|
||||
}
|
||||
q += 2;
|
||||
|
||||
p.v[0].vx = 0;
|
||||
p.v[0].vz = -0x20;
|
||||
p.c[0][0] = p.c[1][0];
|
||||
p.c[0][1] = p.c[0][2] = p.c[1][1];
|
||||
for (i = 0; i < 2; i++) {
|
||||
p.v[2].vx = (s8)*q++;
|
||||
p.v[2].vz = (s8)*q++;
|
||||
p.v[3].vx = (s8)*q++;
|
||||
p.v[3].vz = (s8)*q++;
|
||||
func_80017758(&p, mtx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC04_007/nonmatchings/ov_SC04_007_jr_8017BEBC", func_801832EC);
|
||||
|
||||
|
||||
@@ -4076,7 +4076,6 @@ void func_8017E4B0(void *a0) {
|
||||
}
|
||||
|
||||
|
||||
extern s32 *D_80126B78;
|
||||
extern u8 D_80194EE8[];
|
||||
extern s32 func_8012BDBC(s32 a0, s32 a1);
|
||||
extern s32 func_80135888(s32 a0, s32 a1, s32 a2, s32 a3);
|
||||
@@ -4112,6 +4111,10 @@ s32 aF8018A224() __asm__("func_8017E520");
|
||||
s32 aF8018A224(param_1)
|
||||
void *param_1;
|
||||
{
|
||||
/* [T51] scoped in from file scope: a file-scope decl of these symbols constrains every
|
||||
LATER function in this TU, which blocks a byte-true decl of a different type.
|
||||
Declaration-only move (cookbook §103); the whole-binary byte-gate is the arbiter. */
|
||||
extern s32 *D_80126B78;
|
||||
s32 *m;
|
||||
s32 obj;
|
||||
s32 sv0[2];
|
||||
@@ -4257,7 +4260,101 @@ extern void func_800296F8(void);
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC04_009/nonmatchings/ov_SC04_009_jr_8017BEBC", func_8017E950);
|
||||
extern s32 func_8012BDBC(s32 a0, s32 a1);
|
||||
extern s32 func_80135888(s32 a0, s32 a1, s32 a2, s32 a3);
|
||||
extern void func_80172710(void);
|
||||
extern s32 func_80178BF8();
|
||||
#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_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" )
|
||||
|
||||
/* §71 sibling: identical shape to func_8018F390 (same TU, this file, D_80126B78/RotTransSV/
|
||||
* func_80135888/func_8012BDBC/func_80178BF8/func_80172710 idiom) already MATCHED -- only the
|
||||
* per-overlay data symbol (D_80195040 vs D_801E33F0) differs. §37 asm-label alias avoids the
|
||||
* `conflicting types` clash with the fleet's `extern void func_8017E950(void);` used elsewhere
|
||||
* in this TU as a state-handler function pointer. */
|
||||
|
||||
s32 aF801904E0() __asm__("func_8017E950");
|
||||
|
||||
s32 aF801904E0(param_1)
|
||||
void *param_1;
|
||||
{
|
||||
|
||||
extern s32 *D_80126B78;
|
||||
extern u8 D_80195040[];
|
||||
MATRIX m;
|
||||
s32 obj;
|
||||
s32 sv0[2];
|
||||
s32 sv1[2];
|
||||
s32 flag;
|
||||
|
||||
obj = *(s32 *)((s32)param_1 + 0x64);
|
||||
m = *(MATRIX *)((u8 *)D_80126B78 + 0x34);
|
||||
|
||||
gte_SetRotMatrix(&m);
|
||||
gte_SetTransMatrix(&m);
|
||||
|
||||
RotTransSV(D_80195040, sv0, &flag);
|
||||
RotTransSV(D_80195040 + 8, sv1, &flag);
|
||||
|
||||
if (func_80135888(*(s32 *)(*(s32 *)((s32)param_1 + 0x64) + 0x20),
|
||||
*(s32 *)(*(s32 *)((s32)param_1 + 0x64) + 0x58),
|
||||
(s32)sv0, (s32)sv1) == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (func_8012BDBC(obj, 0x300) == 0) {
|
||||
return 0;
|
||||
}
|
||||
*(s16 *)(obj + 0x2) = 3;
|
||||
func_80178BF8();
|
||||
return (s32)func_80172710;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -3177,7 +3177,67 @@ void func_8017E374(void *a0) {
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC04_011/nonmatchings/ov_SC04_011_jr_8017D494", func_8017E3B0);
|
||||
|
||||
|
||||
extern s32 rand(void);
|
||||
|
||||
typedef struct {
|
||||
u16 f0;
|
||||
u16 f2;
|
||||
u16 f4;
|
||||
u16 f6;
|
||||
u16 f8;
|
||||
u16 fA;
|
||||
s32 fC;
|
||||
s32 f10;
|
||||
s32 f14;
|
||||
s32 f18;
|
||||
} SubRec_801EB5C8_8017E3B0; /* 0x1C */
|
||||
|
||||
typedef struct {
|
||||
u16 g0;
|
||||
u16 g2;
|
||||
s32 g4;
|
||||
s32 g8;
|
||||
s32 gC;
|
||||
SubRec_801EB5C8_8017E3B0 subs[16];
|
||||
} GroupRec_801EB5C8_8017E3B0; /* 0x1D0 */
|
||||
|
||||
|
||||
void func_8017E3B0(s32 param_1)
|
||||
{
|
||||
|
||||
extern GroupRec_801EB5C8_8017E3B0 D_801EEDC8[8];
|
||||
s32 i, j;
|
||||
GroupRec_801EB5C8_8017E3B0 *grp;
|
||||
SubRec_801EB5C8_8017E3B0 *sub;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
grp = &D_801EEDC8[i];
|
||||
grp->g0 = 0;
|
||||
grp->g2 = i << 9;
|
||||
grp->gC = (rand() & 0xF) << 16;
|
||||
grp->g4 = ((rand() & 0xF) << 15) + 0x10000;
|
||||
grp->g8 = ((rand() & 0xF) << 12) + 0x8000;
|
||||
|
||||
for (j = 0; j < 16; j++) {
|
||||
sub = &grp->subs[j];
|
||||
sub->f0 = 0;
|
||||
sub->f2 = (rand() & 3) + 4;
|
||||
sub->f8 = (j << 8) + (rand() & 0xF) * 56;
|
||||
sub->fA = (rand() & 0xF) << 8;
|
||||
sub->f14 = (rand() & 0xF) << 13;
|
||||
sub->fC = ((rand() & 0xF) << 14) + 0x10000;
|
||||
sub->f10 = ((rand() & 0xF) << 12) + 0x8000;
|
||||
sub->f4 = 0x200;
|
||||
sub->f6 = (rand() & 0xF) << 4;
|
||||
sub->f18 = ((rand() & 3) << 5) + 0x40;
|
||||
}
|
||||
}
|
||||
|
||||
*(u16 *)(param_1 + 2) = *(u16 *)(param_1 + 2) + 1;
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC04_011/nonmatchings/ov_SC04_011_jr_8017D494", func_8017E558);
|
||||
|
||||
|
||||
@@ -7096,7 +7096,99 @@ void func_80183598(void *a0) {
|
||||
void func_801835D4(void) {
|
||||
}
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC04_015/nonmatchings/ov_SC04_015_jr_8017AE2C", func_801835DC);
|
||||
|
||||
extern s32 func_8012BEE8(s32 a0);
|
||||
extern s32 rand(void);
|
||||
|
||||
void func_801835DC(s32 param_1) {
|
||||
s32 uVar1;
|
||||
s32 iVar2;
|
||||
register s32 iVar3 __asm__("$3");
|
||||
register s32 iVar4 __asm__("$16");
|
||||
u32 uVar3;
|
||||
|
||||
uVar1 = *(u16 *)(param_1 + 0x34);
|
||||
if (uVar1 == 1) {
|
||||
goto case1;
|
||||
}
|
||||
if (uVar1 < 2) {
|
||||
if (uVar1 == 0) {
|
||||
goto case0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (uVar1 == 2) {
|
||||
goto case2;
|
||||
}
|
||||
if (uVar1 != 3) {
|
||||
return;
|
||||
}
|
||||
goto case3;
|
||||
|
||||
case0:
|
||||
iVar2 = func_8012BEE8(param_1);
|
||||
if (iVar2 == 0) {
|
||||
return;
|
||||
}
|
||||
*(s32 *)(param_1 + 0x1c) = 0x40;
|
||||
*(u16 *)(param_1 + 0x34) = *(u16 *)(param_1 + 0x34) + 1;
|
||||
uVar3 = rand();
|
||||
iVar4 = uVar3 & 0x3fff;
|
||||
iVar4 = iVar4 + 0x7800;
|
||||
uVar3 = rand();
|
||||
if ((uVar3 & 1) == 0) {
|
||||
iVar4 = -iVar4;
|
||||
}
|
||||
*(s32 *)(param_1 + 0xe0) = iVar4;
|
||||
*(s32 *)(param_1 + 0xe4) = 0;
|
||||
return;
|
||||
|
||||
case1:
|
||||
iVar3 = *(s32 *)(param_1 + 0xe4);
|
||||
iVar3 = iVar3 + *(s32 *)(param_1 + 0xe0);
|
||||
*(s32 *)(param_1 + 0xdc) = *(s32 *)(param_1 + 0xdc) + iVar3;
|
||||
*(s32 *)(param_1 + 0xe4) = iVar3;
|
||||
*(u16 *)(*(s32 *)(param_1 + 0x20) + 0x12) = *(u16 *)(param_1 + 0xde);
|
||||
iVar2 = func_8012BEE8(param_1);
|
||||
if (iVar2 == 0) {
|
||||
return;
|
||||
}
|
||||
*(u16 *)(param_1 + 0x34) = *(u16 *)(param_1 + 0x34) + 1;
|
||||
uVar3 = rand();
|
||||
uVar3 = uVar3 & 0x3f;
|
||||
goto tail;
|
||||
|
||||
case2:
|
||||
*(s32 *)(param_1 + 0xdc) = *(s32 *)(param_1 + 0xdc) + *(s32 *)(param_1 + 0xe4);
|
||||
*(u16 *)(*(s32 *)(param_1 + 0x20) + 0x12) = *(u16 *)(param_1 + 0xde);
|
||||
iVar2 = func_8012BEE8(param_1);
|
||||
if (iVar2 == 0) {
|
||||
return;
|
||||
}
|
||||
*(s32 *)(param_1 + 0x1c) = 0x40;
|
||||
*(u16 *)(param_1 + 0x34) = *(u16 *)(param_1 + 0x34) + 1;
|
||||
*(s32 *)(param_1 + 0xe0) = -*(s32 *)(param_1 + 0xe0);
|
||||
return;
|
||||
|
||||
case3:
|
||||
__asm__ __volatile__("" ::: "memory");
|
||||
iVar3 = *(s32 *)(param_1 + 0xe4);
|
||||
iVar3 = iVar3 + *(s32 *)(param_1 + 0xe0);
|
||||
*(s32 *)(param_1 + 0xdc) = *(s32 *)(param_1 + 0xdc) + iVar3;
|
||||
*(s32 *)(param_1 + 0xe4) = iVar3;
|
||||
*(u16 *)(*(s32 *)(param_1 + 0x20) + 0x12) = *(u16 *)(param_1 + 0xde);
|
||||
iVar2 = func_8012BEE8(param_1);
|
||||
if (iVar2 == 0) {
|
||||
return;
|
||||
}
|
||||
*(u16 *)(param_1 + 0x34) = 0;
|
||||
uVar3 = rand();
|
||||
uVar3 = uVar3 & 0xff;
|
||||
|
||||
tail:
|
||||
*(u32 *)(param_1 + 0x1c) = uVar3 + 0x40;
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern void (*D_801C44E4[])(void);
|
||||
|
||||
@@ -3064,22 +3064,16 @@ extern void func_801864AC(void);
|
||||
|
||||
extern s16 D_800B9A02;
|
||||
extern u8 D_801151C8[];
|
||||
extern s32 D_801151D0;
|
||||
extern s16 D_80115126;
|
||||
extern u16 D_80115112;
|
||||
extern u16 D_8011511A;
|
||||
extern u8 D_80115138[];
|
||||
extern u8 D_80115148[];
|
||||
extern s32 D_80115130;
|
||||
extern u8 D_800B9A15;
|
||||
|
||||
extern s16 D_801E7708;
|
||||
extern u16 D_801E770C;
|
||||
extern s16 D_801E7710;
|
||||
extern s32 D_801E7700;
|
||||
extern s32 D_801E7704;
|
||||
extern s16 D_801E7790;
|
||||
extern s16 D_801E7794;
|
||||
extern s16 D_801E7798;
|
||||
extern s16 D_801E779C;
|
||||
extern s16 D_801E77A0;
|
||||
@@ -3114,6 +3108,18 @@ extern s32 func_80189540(s32 a0, s16 a1);
|
||||
extern s16 func_80189E54(s32 a0);
|
||||
|
||||
void func_801878E8(void) {
|
||||
/* [T51] scoped in from file scope: a file-scope decl of these symbols constrains every
|
||||
LATER function in this TU, which blocks a byte-true decl of a different type.
|
||||
Declaration-only move (cookbook §103); the whole-binary byte-gate is the arbiter. */
|
||||
extern u16 D_801E770C;
|
||||
extern s16 D_801E7710;
|
||||
/* [T51] scoped in from file scope: a file-scope decl of these symbols constrains every
|
||||
LATER function in this TU, which blocks a byte-true decl of a different type.
|
||||
Declaration-only move (cookbook §103); the whole-binary byte-gate is the arbiter. */
|
||||
extern s32 D_801151D0;
|
||||
extern s16 D_801E7794;
|
||||
extern s16 D_80115126;
|
||||
extern u16 D_8011511A;
|
||||
s32 s0;
|
||||
s32 pad[2];
|
||||
(void)&pad;
|
||||
@@ -3322,9 +3328,7 @@ void func_801878E8(void) {
|
||||
extern s32 D_80126B58;
|
||||
extern s16 D_800B9A02;
|
||||
extern u8 D_801151C8[];
|
||||
extern s32 D_801151D0;
|
||||
extern s16 D_801E7708;
|
||||
extern u16 D_8011511A;
|
||||
extern s16 func_8014168C(s16 a0);
|
||||
extern s16 D_801B9414[];
|
||||
extern void func_8014BB24(s32 a0, s32 a1, s32 a2);
|
||||
@@ -3333,8 +3337,6 @@ extern void func_8014B2A8(void);
|
||||
extern void func_801EA0E4(s32 a0);
|
||||
extern void func_8014BD24(s32 a0, s32 a1);
|
||||
extern void func_80189EA0(void);
|
||||
extern u16 D_801E770C;
|
||||
extern s16 D_801E7710;
|
||||
extern s32 func_801621CC(s32 arg0);
|
||||
extern void func_801622C4(void);
|
||||
extern void func_80139954(void);
|
||||
@@ -3355,6 +3357,16 @@ extern void func_8002D4C8(s32 a0, s32 a1);
|
||||
|
||||
void func_801880EC(void)
|
||||
{
|
||||
/* [T51] scoped in from file scope: a file-scope decl of these symbols constrains every
|
||||
LATER function in this TU, which blocks a byte-true decl of a different type.
|
||||
Declaration-only move (cookbook §103); the whole-binary byte-gate is the arbiter. */
|
||||
extern u16 D_801E770C;
|
||||
extern s16 D_801E7710;
|
||||
/* [T51] scoped in from file scope: a file-scope decl of these symbols constrains every
|
||||
LATER function in this TU, which blocks a byte-true decl of a different type.
|
||||
Declaration-only move (cookbook §103); the whole-binary byte-gate is the arbiter. */
|
||||
extern s32 D_801151D0;
|
||||
extern u16 D_8011511A;
|
||||
register s16 s0 __asm__("$16");
|
||||
register s32 s1 __asm__("$17");
|
||||
register s32 s2 __asm__("$18");
|
||||
@@ -3707,7 +3719,125 @@ INCLUDE_ASM("asm/ov_SC04_018/nonmatchings/ov_SC04_018_jr_801878E8", func_80189E1
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC04_018/nonmatchings/ov_SC04_018_jr_801878E8", func_80189E54);
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC04_018/nonmatchings/ov_SC04_018_jr_801878E8", func_80189EA0);
|
||||
|
||||
/* func_80189EA0 — ov_SC03_001 (133 ins), exemplar of a 5-member open-only
|
||||
* h_norm cluster. Builds the full-screen fade overlay: a DR_MODE-style 8-byte
|
||||
* GP0 packet (0xE1000015), a 320x240 semi-transparent gouraud quad (POLY_G4,
|
||||
* code 0x3A), and a second 8-byte GP0 packet (0xE1000240), each linked into the
|
||||
* current OT with the psyq `addPrim` idiom. The type shapes and the
|
||||
* `((PTag *)x)->addr = ((PTag *)ot)->addr; ((PTag *)ot)->addr = (u32)x;` pair
|
||||
* are copied VERBATIM from the already-matched neighbour func_8018BCD4 in this
|
||||
* same TU (§71) — Env_* / PTag_* there are the fleet-canonical shapes.
|
||||
*
|
||||
* Levers that were load-bearing (all byte-tested; the draft is PIN-FREE):
|
||||
* §20 &D_801151D0 / &D_800B9A02 taken into pointer LOCALS -> each address is
|
||||
* force_reg'd once (lui+addiu -> $t2 / $a3) instead of a %lo per use.
|
||||
* §36 the 24-bit BITFIELD store, not a hand-written mask, is what emits
|
||||
* 0x00FFFFFF (lui+ori) ahead of 0xFF000000 (lui) while the body ANDs the
|
||||
* destination first — expmed's store_fixed_bit_field signature.
|
||||
* §37 asm-label aliases for D_801E770C/D_801E7710: the TU canon is u16/s16
|
||||
* but the target does a bare `lbu %lo(sym)`, and a plain block-scope
|
||||
* `extern u8` would be a conflicting redeclaration.
|
||||
* --- `volatile` on the OT index read keeps all SIX *pbh loads alive; a plain
|
||||
* read cse-folds them and the function loses ~25 instructions.
|
||||
* S1 the whole body is ONE branch-free basic block and every store ties at
|
||||
* the same priority, so forward asm order == source statement order —
|
||||
* the POLY_G4 block below is a literal transcription of the target.
|
||||
* S2 `p` is destructively updated (multi-set -> no birthing boost) so its
|
||||
* `addiu +8` floats up into the preceding load-delay gap, while `r` is a
|
||||
* FRESH single-set local (boosted) so its `addiu +0x24` sinks to sit
|
||||
* immediately before `sb 3($a0)`. Both placements are the target's.
|
||||
* --- the bare `p = r;` before r's uses is a COMBINE BARRIER: without a SET
|
||||
* of `p` between `r = p + 9` and r's first use, `can_combine_p` lets
|
||||
* combine substitute `r` -> `p + 0x24` into every MEM offset and the
|
||||
* `addiu` disappears entirely (and, at the tail, `p += 2` folds to
|
||||
* `addiu $t3,$t3,0x2C` off the stale base instead of `addiu $t3,$a0,8`).
|
||||
* It also fixes the register rotation for free — verified that adding or
|
||||
* removing `register __asm__` pins on p/r/pbh is a byte no-op.
|
||||
*/
|
||||
|
||||
/* ---- TU-visible spellings (file scope of ov_SC03_001_jr_8018A3A8.c) ---- */
|
||||
|
||||
void func_80189EA0(void) {
|
||||
|
||||
extern s32 D_801151D0;
|
||||
extern u16 D_801E770C;
|
||||
extern s16 D_801E7710;
|
||||
/* §100/§120: draft-local, uniquely-named types — they live in the BODY so
|
||||
* they cannot collide with the TU's own Env_8018BCD4 / PTag_8018BCD4. */
|
||||
typedef struct { u32 addr : 24; u32 len : 8; } PTag_8018C960_80189EA0;
|
||||
typedef struct { u32 *ot; u32 pad[4]; } Env_8018C960_80189EA0; /* 0x14 stride */
|
||||
typedef struct {
|
||||
u32 tag; /* 0x00 */
|
||||
u8 r0, g0, b0, code; /* 0x04..0x07 */
|
||||
s16 x0, y0; /* 0x08, 0x0A */
|
||||
u8 r1, g1, b1, p1; /* 0x0C..0x0F */
|
||||
s16 x1, y1; /* 0x10, 0x12 */
|
||||
u8 r2, g2, b2, p2; /* 0x14..0x17 */
|
||||
s16 x2, y2; /* 0x18, 0x1A */
|
||||
u8 r3, g3, b3, p3; /* 0x1C..0x1F */
|
||||
s16 x3, y3; /* 0x20, 0x22 */
|
||||
} PG4_8018C960_80189EA0; /* -> 0x24 */
|
||||
|
||||
extern Env_8018C960_80189EA0 D_800AE7BC[];
|
||||
extern u8 aD801EF1EC __asm__("D_801E770C");
|
||||
extern u8 aD801EF1F0 __asm__("D_801E7710");
|
||||
|
||||
u32 **pp;
|
||||
volatile u16 *pbh;
|
||||
u32 *p;
|
||||
u32 *r;
|
||||
u8 c1, c2;
|
||||
|
||||
pp = (u32 **)&D_801151D0;
|
||||
pbh = (volatile u16 *)&D_800B9A02;
|
||||
|
||||
p = *pp;
|
||||
((PTag_8018C960_80189EA0 *)p)->len = 1;
|
||||
p[1] = 0xE1000015;
|
||||
((PTag_8018C960_80189EA0 *)p)->addr = ((PTag_8018C960_80189EA0 *)D_800AE7BC[*pbh].ot)->addr;
|
||||
((PTag_8018C960_80189EA0 *)D_800AE7BC[*pbh].ot)->addr = (u32)p;
|
||||
|
||||
p += 2;
|
||||
((PG4_8018C960_80189EA0 *)p)->tag = 0x08000000;
|
||||
((PG4_8018C960_80189EA0 *)p)->code = 0x3A;
|
||||
((PG4_8018C960_80189EA0 *)p)->x2 = -160;
|
||||
((PG4_8018C960_80189EA0 *)p)->x0 = -160;
|
||||
((PG4_8018C960_80189EA0 *)p)->x3 = 160;
|
||||
((PG4_8018C960_80189EA0 *)p)->x1 = 160;
|
||||
c1 = aD801EF1EC;
|
||||
((PG4_8018C960_80189EA0 *)p)->b1 = c1;
|
||||
((PG4_8018C960_80189EA0 *)p)->b0 = c1;
|
||||
((PG4_8018C960_80189EA0 *)p)->g1 = c1;
|
||||
((PG4_8018C960_80189EA0 *)p)->g0 = c1;
|
||||
((PG4_8018C960_80189EA0 *)p)->r1 = c1;
|
||||
((PG4_8018C960_80189EA0 *)p)->r0 = c1;
|
||||
c2 = aD801EF1F0;
|
||||
((PG4_8018C960_80189EA0 *)p)->y1 = -120;
|
||||
((PG4_8018C960_80189EA0 *)p)->b3 = c2;
|
||||
((PG4_8018C960_80189EA0 *)p)->b2 = c2;
|
||||
((PG4_8018C960_80189EA0 *)p)->g3 = c2;
|
||||
((PG4_8018C960_80189EA0 *)p)->g2 = c2;
|
||||
((PG4_8018C960_80189EA0 *)p)->r3 = c2;
|
||||
((PG4_8018C960_80189EA0 *)p)->r2 = c2;
|
||||
((PG4_8018C960_80189EA0 *)p)->y0 = -120;
|
||||
((PG4_8018C960_80189EA0 *)p)->y3 = 120;
|
||||
((PG4_8018C960_80189EA0 *)p)->y2 = 120;
|
||||
|
||||
((PTag_8018C960_80189EA0 *)p)->addr = ((PTag_8018C960_80189EA0 *)D_800AE7BC[*pbh].ot)->addr;
|
||||
((PTag_8018C960_80189EA0 *)D_800AE7BC[*pbh].ot)->addr = (u32)p;
|
||||
|
||||
r = p + 9; /* 0x24 */
|
||||
p = r; /* COMBINE BARRIER — see header */
|
||||
((PTag_8018C960_80189EA0 *)r)->len = 1;
|
||||
r[1] = 0xE1000240;
|
||||
((PTag_8018C960_80189EA0 *)r)->addr = ((PTag_8018C960_80189EA0 *)D_800AE7BC[*pbh].ot)->addr;
|
||||
((PTag_8018C960_80189EA0 *)D_800AE7BC[*pbh].ot)->addr = (u32)r;
|
||||
|
||||
p += 2;
|
||||
*pp = p;
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC04_018/nonmatchings/ov_SC04_018_jr_801878E8", func_8018A0B4);
|
||||
|
||||
@@ -3918,7 +4048,99 @@ void func_8018A94C(void *a0) {
|
||||
|
||||
DEFINE_func_8018A988() /* dedup: shared engine-core @0x8018A988 (src/shared) */
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC04_018/nonmatchings/ov_SC04_018_jr_801878E8", func_8018A990);
|
||||
|
||||
extern s32 func_8012BEE8(s32 a0);
|
||||
extern s32 rand(void);
|
||||
|
||||
void func_8018A990(s32 param_1) {
|
||||
s32 uVar1;
|
||||
s32 iVar2;
|
||||
register s32 iVar3 __asm__("$3");
|
||||
register s32 iVar4 __asm__("$16");
|
||||
u32 uVar3;
|
||||
|
||||
uVar1 = *(u16 *)(param_1 + 0x34);
|
||||
if (uVar1 == 1) {
|
||||
goto case1;
|
||||
}
|
||||
if (uVar1 < 2) {
|
||||
if (uVar1 == 0) {
|
||||
goto case0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (uVar1 == 2) {
|
||||
goto case2;
|
||||
}
|
||||
if (uVar1 != 3) {
|
||||
return;
|
||||
}
|
||||
goto case3;
|
||||
|
||||
case0:
|
||||
iVar2 = func_8012BEE8(param_1);
|
||||
if (iVar2 == 0) {
|
||||
return;
|
||||
}
|
||||
*(s32 *)(param_1 + 0x1c) = 0x40;
|
||||
*(u16 *)(param_1 + 0x34) = *(u16 *)(param_1 + 0x34) + 1;
|
||||
uVar3 = rand();
|
||||
iVar4 = uVar3 & 0x3fff;
|
||||
iVar4 = iVar4 + 0x7800;
|
||||
uVar3 = rand();
|
||||
if ((uVar3 & 1) == 0) {
|
||||
iVar4 = -iVar4;
|
||||
}
|
||||
*(s32 *)(param_1 + 0xe0) = iVar4;
|
||||
*(s32 *)(param_1 + 0xe4) = 0;
|
||||
return;
|
||||
|
||||
case1:
|
||||
iVar3 = *(s32 *)(param_1 + 0xe4);
|
||||
iVar3 = iVar3 + *(s32 *)(param_1 + 0xe0);
|
||||
*(s32 *)(param_1 + 0xdc) = *(s32 *)(param_1 + 0xdc) + iVar3;
|
||||
*(s32 *)(param_1 + 0xe4) = iVar3;
|
||||
*(u16 *)(*(s32 *)(param_1 + 0x20) + 0x12) = *(u16 *)(param_1 + 0xde);
|
||||
iVar2 = func_8012BEE8(param_1);
|
||||
if (iVar2 == 0) {
|
||||
return;
|
||||
}
|
||||
*(u16 *)(param_1 + 0x34) = *(u16 *)(param_1 + 0x34) + 1;
|
||||
uVar3 = rand();
|
||||
uVar3 = uVar3 & 0x3f;
|
||||
goto tail;
|
||||
|
||||
case2:
|
||||
*(s32 *)(param_1 + 0xdc) = *(s32 *)(param_1 + 0xdc) + *(s32 *)(param_1 + 0xe4);
|
||||
*(u16 *)(*(s32 *)(param_1 + 0x20) + 0x12) = *(u16 *)(param_1 + 0xde);
|
||||
iVar2 = func_8012BEE8(param_1);
|
||||
if (iVar2 == 0) {
|
||||
return;
|
||||
}
|
||||
*(s32 *)(param_1 + 0x1c) = 0x40;
|
||||
*(u16 *)(param_1 + 0x34) = *(u16 *)(param_1 + 0x34) + 1;
|
||||
*(s32 *)(param_1 + 0xe0) = -*(s32 *)(param_1 + 0xe0);
|
||||
return;
|
||||
|
||||
case3:
|
||||
__asm__ __volatile__("" ::: "memory");
|
||||
iVar3 = *(s32 *)(param_1 + 0xe4);
|
||||
iVar3 = iVar3 + *(s32 *)(param_1 + 0xe0);
|
||||
*(s32 *)(param_1 + 0xdc) = *(s32 *)(param_1 + 0xdc) + iVar3;
|
||||
*(s32 *)(param_1 + 0xe4) = iVar3;
|
||||
*(u16 *)(*(s32 *)(param_1 + 0x20) + 0x12) = *(u16 *)(param_1 + 0xde);
|
||||
iVar2 = func_8012BEE8(param_1);
|
||||
if (iVar2 == 0) {
|
||||
return;
|
||||
}
|
||||
*(u16 *)(param_1 + 0x34) = 0;
|
||||
uVar3 = rand();
|
||||
uVar3 = uVar3 & 0xff;
|
||||
|
||||
tail:
|
||||
*(u32 *)(param_1 + 0x1c) = uVar3 + 0x40;
|
||||
}
|
||||
|
||||
|
||||
DEFINE_func_8018AB3C() /* dedup: shared engine-core @0x8018AB3C (src/shared) */
|
||||
|
||||
|
||||
@@ -3009,22 +3009,16 @@ extern void func_801864AC(void);
|
||||
|
||||
extern s16 D_800B9A02;
|
||||
extern u8 D_801151C8[];
|
||||
extern s32 D_801151D0;
|
||||
extern s16 D_80115126;
|
||||
extern u16 D_80115112;
|
||||
extern u16 D_8011511A;
|
||||
extern u8 D_80115138[];
|
||||
extern u8 D_80115148[];
|
||||
extern s32 D_80115130;
|
||||
extern u8 D_800B9A15;
|
||||
|
||||
extern s16 D_801E7708;
|
||||
extern u16 D_801E770C;
|
||||
extern s16 D_801E7710;
|
||||
extern s32 D_801E7700;
|
||||
extern s32 D_801E7704;
|
||||
extern s16 D_801E7790;
|
||||
extern s16 D_801E7794;
|
||||
extern s16 D_801E7798;
|
||||
extern s16 D_801E779C;
|
||||
extern s16 D_801E77A0;
|
||||
@@ -3059,6 +3053,18 @@ extern s32 func_80189540(s32 a0, s16 a1);
|
||||
extern s16 func_80189E54(s32 a0);
|
||||
|
||||
void func_801878E8(void) {
|
||||
/* [T51] scoped in from file scope: a file-scope decl of these symbols constrains every
|
||||
LATER function in this TU, which blocks a byte-true decl of a different type.
|
||||
Declaration-only move (cookbook §103); the whole-binary byte-gate is the arbiter. */
|
||||
extern u16 D_801E770C;
|
||||
extern s16 D_801E7710;
|
||||
/* [T51] scoped in from file scope: a file-scope decl of these symbols constrains every
|
||||
LATER function in this TU, which blocks a byte-true decl of a different type.
|
||||
Declaration-only move (cookbook §103); the whole-binary byte-gate is the arbiter. */
|
||||
extern s32 D_801151D0;
|
||||
extern s16 D_801E7794;
|
||||
extern s16 D_80115126;
|
||||
extern u16 D_8011511A;
|
||||
s32 s0;
|
||||
s32 pad[2];
|
||||
(void)&pad;
|
||||
@@ -3654,7 +3660,125 @@ INCLUDE_ASM("asm/ov_SC04_019/nonmatchings/ov_SC04_019_jr_801878E8", func_80189E1
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC04_019/nonmatchings/ov_SC04_019_jr_801878E8", func_80189E54);
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC04_019/nonmatchings/ov_SC04_019_jr_801878E8", func_80189EA0);
|
||||
|
||||
/* func_80189EA0 — ov_SC03_001 (133 ins), exemplar of a 5-member open-only
|
||||
* h_norm cluster. Builds the full-screen fade overlay: a DR_MODE-style 8-byte
|
||||
* GP0 packet (0xE1000015), a 320x240 semi-transparent gouraud quad (POLY_G4,
|
||||
* code 0x3A), and a second 8-byte GP0 packet (0xE1000240), each linked into the
|
||||
* current OT with the psyq `addPrim` idiom. The type shapes and the
|
||||
* `((PTag *)x)->addr = ((PTag *)ot)->addr; ((PTag *)ot)->addr = (u32)x;` pair
|
||||
* are copied VERBATIM from the already-matched neighbour func_8018BCD4 in this
|
||||
* same TU (§71) — Env_* / PTag_* there are the fleet-canonical shapes.
|
||||
*
|
||||
* Levers that were load-bearing (all byte-tested; the draft is PIN-FREE):
|
||||
* §20 &D_801151D0 / &D_800B9A02 taken into pointer LOCALS -> each address is
|
||||
* force_reg'd once (lui+addiu -> $t2 / $a3) instead of a %lo per use.
|
||||
* §36 the 24-bit BITFIELD store, not a hand-written mask, is what emits
|
||||
* 0x00FFFFFF (lui+ori) ahead of 0xFF000000 (lui) while the body ANDs the
|
||||
* destination first — expmed's store_fixed_bit_field signature.
|
||||
* §37 asm-label aliases for D_801E770C/D_801E7710: the TU canon is u16/s16
|
||||
* but the target does a bare `lbu %lo(sym)`, and a plain block-scope
|
||||
* `extern u8` would be a conflicting redeclaration.
|
||||
* --- `volatile` on the OT index read keeps all SIX *pbh loads alive; a plain
|
||||
* read cse-folds them and the function loses ~25 instructions.
|
||||
* S1 the whole body is ONE branch-free basic block and every store ties at
|
||||
* the same priority, so forward asm order == source statement order —
|
||||
* the POLY_G4 block below is a literal transcription of the target.
|
||||
* S2 `p` is destructively updated (multi-set -> no birthing boost) so its
|
||||
* `addiu +8` floats up into the preceding load-delay gap, while `r` is a
|
||||
* FRESH single-set local (boosted) so its `addiu +0x24` sinks to sit
|
||||
* immediately before `sb 3($a0)`. Both placements are the target's.
|
||||
* --- the bare `p = r;` before r's uses is a COMBINE BARRIER: without a SET
|
||||
* of `p` between `r = p + 9` and r's first use, `can_combine_p` lets
|
||||
* combine substitute `r` -> `p + 0x24` into every MEM offset and the
|
||||
* `addiu` disappears entirely (and, at the tail, `p += 2` folds to
|
||||
* `addiu $t3,$t3,0x2C` off the stale base instead of `addiu $t3,$a0,8`).
|
||||
* It also fixes the register rotation for free — verified that adding or
|
||||
* removing `register __asm__` pins on p/r/pbh is a byte no-op.
|
||||
*/
|
||||
|
||||
/* ---- TU-visible spellings (file scope of ov_SC03_001_jr_8018A3A8.c) ---- */
|
||||
|
||||
void func_80189EA0(void) {
|
||||
|
||||
extern s32 D_801151D0;
|
||||
extern u16 D_801E770C;
|
||||
extern s16 D_801E7710;
|
||||
/* §100/§120: draft-local, uniquely-named types — they live in the BODY so
|
||||
* they cannot collide with the TU's own Env_8018BCD4 / PTag_8018BCD4. */
|
||||
typedef struct { u32 addr : 24; u32 len : 8; } PTag_8018C960_80189EA0;
|
||||
typedef struct { u32 *ot; u32 pad[4]; } Env_8018C960_80189EA0; /* 0x14 stride */
|
||||
typedef struct {
|
||||
u32 tag; /* 0x00 */
|
||||
u8 r0, g0, b0, code; /* 0x04..0x07 */
|
||||
s16 x0, y0; /* 0x08, 0x0A */
|
||||
u8 r1, g1, b1, p1; /* 0x0C..0x0F */
|
||||
s16 x1, y1; /* 0x10, 0x12 */
|
||||
u8 r2, g2, b2, p2; /* 0x14..0x17 */
|
||||
s16 x2, y2; /* 0x18, 0x1A */
|
||||
u8 r3, g3, b3, p3; /* 0x1C..0x1F */
|
||||
s16 x3, y3; /* 0x20, 0x22 */
|
||||
} PG4_8018C960_80189EA0; /* -> 0x24 */
|
||||
|
||||
extern Env_8018C960_80189EA0 D_800AE7BC[];
|
||||
extern u8 aD801EF1EC __asm__("D_801E770C");
|
||||
extern u8 aD801EF1F0 __asm__("D_801E7710");
|
||||
|
||||
u32 **pp;
|
||||
volatile u16 *pbh;
|
||||
u32 *p;
|
||||
u32 *r;
|
||||
u8 c1, c2;
|
||||
|
||||
pp = (u32 **)&D_801151D0;
|
||||
pbh = (volatile u16 *)&D_800B9A02;
|
||||
|
||||
p = *pp;
|
||||
((PTag_8018C960_80189EA0 *)p)->len = 1;
|
||||
p[1] = 0xE1000015;
|
||||
((PTag_8018C960_80189EA0 *)p)->addr = ((PTag_8018C960_80189EA0 *)D_800AE7BC[*pbh].ot)->addr;
|
||||
((PTag_8018C960_80189EA0 *)D_800AE7BC[*pbh].ot)->addr = (u32)p;
|
||||
|
||||
p += 2;
|
||||
((PG4_8018C960_80189EA0 *)p)->tag = 0x08000000;
|
||||
((PG4_8018C960_80189EA0 *)p)->code = 0x3A;
|
||||
((PG4_8018C960_80189EA0 *)p)->x2 = -160;
|
||||
((PG4_8018C960_80189EA0 *)p)->x0 = -160;
|
||||
((PG4_8018C960_80189EA0 *)p)->x3 = 160;
|
||||
((PG4_8018C960_80189EA0 *)p)->x1 = 160;
|
||||
c1 = aD801EF1EC;
|
||||
((PG4_8018C960_80189EA0 *)p)->b1 = c1;
|
||||
((PG4_8018C960_80189EA0 *)p)->b0 = c1;
|
||||
((PG4_8018C960_80189EA0 *)p)->g1 = c1;
|
||||
((PG4_8018C960_80189EA0 *)p)->g0 = c1;
|
||||
((PG4_8018C960_80189EA0 *)p)->r1 = c1;
|
||||
((PG4_8018C960_80189EA0 *)p)->r0 = c1;
|
||||
c2 = aD801EF1F0;
|
||||
((PG4_8018C960_80189EA0 *)p)->y1 = -120;
|
||||
((PG4_8018C960_80189EA0 *)p)->b3 = c2;
|
||||
((PG4_8018C960_80189EA0 *)p)->b2 = c2;
|
||||
((PG4_8018C960_80189EA0 *)p)->g3 = c2;
|
||||
((PG4_8018C960_80189EA0 *)p)->g2 = c2;
|
||||
((PG4_8018C960_80189EA0 *)p)->r3 = c2;
|
||||
((PG4_8018C960_80189EA0 *)p)->r2 = c2;
|
||||
((PG4_8018C960_80189EA0 *)p)->y0 = -120;
|
||||
((PG4_8018C960_80189EA0 *)p)->y3 = 120;
|
||||
((PG4_8018C960_80189EA0 *)p)->y2 = 120;
|
||||
|
||||
((PTag_8018C960_80189EA0 *)p)->addr = ((PTag_8018C960_80189EA0 *)D_800AE7BC[*pbh].ot)->addr;
|
||||
((PTag_8018C960_80189EA0 *)D_800AE7BC[*pbh].ot)->addr = (u32)p;
|
||||
|
||||
r = p + 9; /* 0x24 */
|
||||
p = r; /* COMBINE BARRIER — see header */
|
||||
((PTag_8018C960_80189EA0 *)r)->len = 1;
|
||||
r[1] = 0xE1000240;
|
||||
((PTag_8018C960_80189EA0 *)r)->addr = ((PTag_8018C960_80189EA0 *)D_800AE7BC[*pbh].ot)->addr;
|
||||
((PTag_8018C960_80189EA0 *)D_800AE7BC[*pbh].ot)->addr = (u32)r;
|
||||
|
||||
p += 2;
|
||||
*pp = p;
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC04_019/nonmatchings/ov_SC04_019_jr_801878E8", func_8018A0B4);
|
||||
|
||||
@@ -3864,7 +3988,99 @@ void func_8018A94C(void *a0) {
|
||||
|
||||
DEFINE_func_8018A988() /* dedup: shared engine-core @0x8018A988 (src/shared) */
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC04_019/nonmatchings/ov_SC04_019_jr_801878E8", func_8018A990);
|
||||
|
||||
extern s32 func_8012BEE8(s32 a0);
|
||||
extern s32 rand(void);
|
||||
|
||||
void func_8018A990(s32 param_1) {
|
||||
s32 uVar1;
|
||||
s32 iVar2;
|
||||
register s32 iVar3 __asm__("$3");
|
||||
register s32 iVar4 __asm__("$16");
|
||||
u32 uVar3;
|
||||
|
||||
uVar1 = *(u16 *)(param_1 + 0x34);
|
||||
if (uVar1 == 1) {
|
||||
goto case1;
|
||||
}
|
||||
if (uVar1 < 2) {
|
||||
if (uVar1 == 0) {
|
||||
goto case0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (uVar1 == 2) {
|
||||
goto case2;
|
||||
}
|
||||
if (uVar1 != 3) {
|
||||
return;
|
||||
}
|
||||
goto case3;
|
||||
|
||||
case0:
|
||||
iVar2 = func_8012BEE8(param_1);
|
||||
if (iVar2 == 0) {
|
||||
return;
|
||||
}
|
||||
*(s32 *)(param_1 + 0x1c) = 0x40;
|
||||
*(u16 *)(param_1 + 0x34) = *(u16 *)(param_1 + 0x34) + 1;
|
||||
uVar3 = rand();
|
||||
iVar4 = uVar3 & 0x3fff;
|
||||
iVar4 = iVar4 + 0x7800;
|
||||
uVar3 = rand();
|
||||
if ((uVar3 & 1) == 0) {
|
||||
iVar4 = -iVar4;
|
||||
}
|
||||
*(s32 *)(param_1 + 0xe0) = iVar4;
|
||||
*(s32 *)(param_1 + 0xe4) = 0;
|
||||
return;
|
||||
|
||||
case1:
|
||||
iVar3 = *(s32 *)(param_1 + 0xe4);
|
||||
iVar3 = iVar3 + *(s32 *)(param_1 + 0xe0);
|
||||
*(s32 *)(param_1 + 0xdc) = *(s32 *)(param_1 + 0xdc) + iVar3;
|
||||
*(s32 *)(param_1 + 0xe4) = iVar3;
|
||||
*(u16 *)(*(s32 *)(param_1 + 0x20) + 0x12) = *(u16 *)(param_1 + 0xde);
|
||||
iVar2 = func_8012BEE8(param_1);
|
||||
if (iVar2 == 0) {
|
||||
return;
|
||||
}
|
||||
*(u16 *)(param_1 + 0x34) = *(u16 *)(param_1 + 0x34) + 1;
|
||||
uVar3 = rand();
|
||||
uVar3 = uVar3 & 0x3f;
|
||||
goto tail;
|
||||
|
||||
case2:
|
||||
*(s32 *)(param_1 + 0xdc) = *(s32 *)(param_1 + 0xdc) + *(s32 *)(param_1 + 0xe4);
|
||||
*(u16 *)(*(s32 *)(param_1 + 0x20) + 0x12) = *(u16 *)(param_1 + 0xde);
|
||||
iVar2 = func_8012BEE8(param_1);
|
||||
if (iVar2 == 0) {
|
||||
return;
|
||||
}
|
||||
*(s32 *)(param_1 + 0x1c) = 0x40;
|
||||
*(u16 *)(param_1 + 0x34) = *(u16 *)(param_1 + 0x34) + 1;
|
||||
*(s32 *)(param_1 + 0xe0) = -*(s32 *)(param_1 + 0xe0);
|
||||
return;
|
||||
|
||||
case3:
|
||||
__asm__ __volatile__("" ::: "memory");
|
||||
iVar3 = *(s32 *)(param_1 + 0xe4);
|
||||
iVar3 = iVar3 + *(s32 *)(param_1 + 0xe0);
|
||||
*(s32 *)(param_1 + 0xdc) = *(s32 *)(param_1 + 0xdc) + iVar3;
|
||||
*(s32 *)(param_1 + 0xe4) = iVar3;
|
||||
*(u16 *)(*(s32 *)(param_1 + 0x20) + 0x12) = *(u16 *)(param_1 + 0xde);
|
||||
iVar2 = func_8012BEE8(param_1);
|
||||
if (iVar2 == 0) {
|
||||
return;
|
||||
}
|
||||
*(u16 *)(param_1 + 0x34) = 0;
|
||||
uVar3 = rand();
|
||||
uVar3 = uVar3 & 0xff;
|
||||
|
||||
tail:
|
||||
*(u32 *)(param_1 + 0x1c) = uVar3 + 0x40;
|
||||
}
|
||||
|
||||
|
||||
DEFINE_func_8018AB3C() /* dedup: shared engine-core @0x8018AB3C (src/shared) */
|
||||
|
||||
|
||||
@@ -4226,7 +4226,50 @@ INCLUDE_ASM("asm/ov_SC05_003/nonmatchings/ov_SC05_003_jr_8017BEBC", func_801818B
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC05_003/nonmatchings/ov_SC05_003_jr_8017BEBC", func_80181A08);
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC05_003/nonmatchings/ov_SC05_003_jr_8017BEBC", func_80181AAC);
|
||||
|
||||
extern void func_8012931C(struct vec *a0);
|
||||
extern s32 func_8012CEB0(s32 a0, s32 a1, s32 a2);
|
||||
|
||||
/* a0 = actor/entity base (struct vec-compatible; s16 fields at +6/+A/+E, s32 flag/vel at +0x14),
|
||||
* a1 = s16[3] offset vector, a2 = mode passed through to func_8012CEB0.
|
||||
* Same family as func_8012CC88 (src/ov_SC02_027/ov_SC02_027_jr_8012ACE0.c etc) but the
|
||||
* position-integration step is a real call to func_8012931C instead of being inlined. */
|
||||
s32 func_80181AAC(s32 a0, s32 a1, s32 a2) {
|
||||
SV3_8012CC88 sp10;
|
||||
SV3_8012CC88 sp18;
|
||||
s32 v0;
|
||||
|
||||
sp10.vx = *(u16*)(a0 + 0x06);
|
||||
sp10.vy = *(u16*)(a0 + 0x0A);
|
||||
sp10.vz = *(u16*)(a0 + 0x0E);
|
||||
sp10.vx += *(u16*)(a1 + 0);
|
||||
sp10.vy += *(u16*)(a1 + 2);
|
||||
sp10.vz += *(u16*)(a1 + 4);
|
||||
|
||||
func_8012931C((struct vec *)a0);
|
||||
|
||||
sp18.vx = *(u16*)(a0 + 0x06);
|
||||
sp18.vy = *(u16*)(a0 + 0x0A);
|
||||
sp18.vz = *(u16*)(a0 + 0x0E);
|
||||
sp18.vx += *(u16*)(a1 + 0);
|
||||
sp18.vy += *(u16*)(a1 + 2);
|
||||
sp18.vz += *(u16*)(a1 + 4);
|
||||
|
||||
v0 = func_8012CEB0((s32)&sp10, (s32)&sp18, a2);
|
||||
|
||||
sp18.vx -= *(u16*)(a1 + 0);
|
||||
sp18.vy -= *(u16*)(a1 + 2);
|
||||
sp18.vz -= *(u16*)(a1 + 4);
|
||||
*(s16*)(a0 + 0x06) = sp18.vx;
|
||||
*(s16*)(a0 + 0x0A) = sp18.vy;
|
||||
*(s16*)(a0 + 0x0E) = sp18.vz;
|
||||
|
||||
if (v0 & 0x6000) {
|
||||
*(s32*)(a0 + 0x14) = 0;
|
||||
}
|
||||
return v0;
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC05_003/nonmatchings/ov_SC05_003_jr_8017BEBC", func_80181C00);
|
||||
|
||||
|
||||
@@ -3866,7 +3866,50 @@ INCLUDE_ASM("asm/ov_SC05_005/nonmatchings/ov_SC05_005_jr_8017D898", func_801819C
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC05_005/nonmatchings/ov_SC05_005_jr_8017D898", func_80181B10);
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC05_005/nonmatchings/ov_SC05_005_jr_8017D898", func_80181BB4);
|
||||
|
||||
extern void func_8012931C(struct vec *a0);
|
||||
extern s32 func_8012CEB0(s32 a0, s32 a1, s32 a2);
|
||||
|
||||
/* a0 = actor/entity base (struct vec-compatible; s16 fields at +6/+A/+E, s32 flag/vel at +0x14),
|
||||
* a1 = s16[3] offset vector, a2 = mode passed through to func_8012CEB0.
|
||||
* Same family as func_8012CC88 (src/ov_SC02_027/ov_SC02_027_jr_8012ACE0.c etc) but the
|
||||
* position-integration step is a real call to func_8012931C instead of being inlined. */
|
||||
s32 func_80181BB4(s32 a0, s32 a1, s32 a2) {
|
||||
SV3_8012CC88 sp10;
|
||||
SV3_8012CC88 sp18;
|
||||
s32 v0;
|
||||
|
||||
sp10.vx = *(u16*)(a0 + 0x06);
|
||||
sp10.vy = *(u16*)(a0 + 0x0A);
|
||||
sp10.vz = *(u16*)(a0 + 0x0E);
|
||||
sp10.vx += *(u16*)(a1 + 0);
|
||||
sp10.vy += *(u16*)(a1 + 2);
|
||||
sp10.vz += *(u16*)(a1 + 4);
|
||||
|
||||
func_8012931C((struct vec *)a0);
|
||||
|
||||
sp18.vx = *(u16*)(a0 + 0x06);
|
||||
sp18.vy = *(u16*)(a0 + 0x0A);
|
||||
sp18.vz = *(u16*)(a0 + 0x0E);
|
||||
sp18.vx += *(u16*)(a1 + 0);
|
||||
sp18.vy += *(u16*)(a1 + 2);
|
||||
sp18.vz += *(u16*)(a1 + 4);
|
||||
|
||||
v0 = func_8012CEB0((s32)&sp10, (s32)&sp18, a2);
|
||||
|
||||
sp18.vx -= *(u16*)(a1 + 0);
|
||||
sp18.vy -= *(u16*)(a1 + 2);
|
||||
sp18.vz -= *(u16*)(a1 + 4);
|
||||
*(s16*)(a0 + 0x06) = sp18.vx;
|
||||
*(s16*)(a0 + 0x0A) = sp18.vy;
|
||||
*(s16*)(a0 + 0x0E) = sp18.vz;
|
||||
|
||||
if (v0 & 0x6000) {
|
||||
*(s32*)(a0 + 0x14) = 0;
|
||||
}
|
||||
return v0;
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC05_005/nonmatchings/ov_SC05_005_jr_8017D898", func_80181D08);
|
||||
|
||||
|
||||
@@ -76,7 +76,6 @@ extern s32 func_80146128(void);
|
||||
extern void func_80146360(void);
|
||||
extern void func_801463A0();
|
||||
extern void func_8014607C(void);
|
||||
extern s32 *D_80126B78;
|
||||
extern u8 D_80078EC1;
|
||||
extern s32 D_80078EC8;
|
||||
extern s32 D_80126B9C;
|
||||
@@ -3681,7 +3680,101 @@ extern void func_800296F8(void);
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC05_009/nonmatchings/ov_SC05_009_jr_8017BEBC", func_8017E894);
|
||||
extern s32 func_8012BDBC(s32 a0, s32 a1);
|
||||
extern s32 func_80135888(s32 a0, s32 a1, s32 a2, s32 a3);
|
||||
extern void func_80172710(void);
|
||||
extern s32 func_80178BF8();
|
||||
#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_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" )
|
||||
|
||||
/* §71 sibling: identical shape to func_8018F390 (same TU, this file, D_80126B78/RotTransSV/
|
||||
* func_80135888/func_8012BDBC/func_80178BF8/func_80172710 idiom) already MATCHED -- only the
|
||||
* per-overlay data symbol (D_801939E0 vs D_801E33F0) differs. §37 asm-label alias avoids the
|
||||
* `conflicting types` clash with the fleet's `extern void func_8017E894(void);` used elsewhere
|
||||
* in this TU as a state-handler function pointer. */
|
||||
|
||||
s32 aF801904E0() __asm__("func_8017E894");
|
||||
|
||||
s32 aF801904E0(param_1)
|
||||
void *param_1;
|
||||
{
|
||||
|
||||
extern s32 *D_80126B78;
|
||||
extern u8 D_801939E0[];
|
||||
MATRIX m;
|
||||
s32 obj;
|
||||
s32 sv0[2];
|
||||
s32 sv1[2];
|
||||
s32 flag;
|
||||
|
||||
obj = *(s32 *)((s32)param_1 + 0x64);
|
||||
m = *(MATRIX *)((u8 *)D_80126B78 + 0x34);
|
||||
|
||||
gte_SetRotMatrix(&m);
|
||||
gte_SetTransMatrix(&m);
|
||||
|
||||
RotTransSV(D_801939E0, sv0, &flag);
|
||||
RotTransSV(D_801939E0 + 8, sv1, &flag);
|
||||
|
||||
if (func_80135888(*(s32 *)(*(s32 *)((s32)param_1 + 0x64) + 0x20),
|
||||
*(s32 *)(*(s32 *)((s32)param_1 + 0x64) + 0x58),
|
||||
(s32)sv0, (s32)sv1) == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (func_8012BDBC(obj, 0x300) == 0) {
|
||||
return 0;
|
||||
}
|
||||
*(s16 *)(obj + 0x2) = 3;
|
||||
func_80178BF8();
|
||||
return (s32)func_80172710;
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC05_009/nonmatchings/ov_SC05_009_jr_8017BEBC", func_8017E9E8);
|
||||
|
||||
|
||||
@@ -3413,7 +3413,67 @@ void func_8017DFF0(void *a0) {
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC05_010/nonmatchings/ov_SC05_010_jr_8017C8D0", func_8017E02C);
|
||||
|
||||
|
||||
extern s32 rand(void);
|
||||
|
||||
typedef struct {
|
||||
u16 f0;
|
||||
u16 f2;
|
||||
u16 f4;
|
||||
u16 f6;
|
||||
u16 f8;
|
||||
u16 fA;
|
||||
s32 fC;
|
||||
s32 f10;
|
||||
s32 f14;
|
||||
s32 f18;
|
||||
} SubRec_801EB5C8_8017E02C; /* 0x1C */
|
||||
|
||||
typedef struct {
|
||||
u16 g0;
|
||||
u16 g2;
|
||||
s32 g4;
|
||||
s32 g8;
|
||||
s32 gC;
|
||||
SubRec_801EB5C8_8017E02C subs[16];
|
||||
} GroupRec_801EB5C8_8017E02C; /* 0x1D0 */
|
||||
|
||||
|
||||
void func_8017E02C(s32 param_1)
|
||||
{
|
||||
|
||||
extern GroupRec_801EB5C8_8017E02C D_801C6FA8[8];
|
||||
s32 i, j;
|
||||
GroupRec_801EB5C8_8017E02C *grp;
|
||||
SubRec_801EB5C8_8017E02C *sub;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
grp = &D_801C6FA8[i];
|
||||
grp->g0 = 0;
|
||||
grp->g2 = i << 9;
|
||||
grp->gC = (rand() & 0xF) << 16;
|
||||
grp->g4 = ((rand() & 0xF) << 15) + 0x10000;
|
||||
grp->g8 = ((rand() & 0xF) << 12) + 0x8000;
|
||||
|
||||
for (j = 0; j < 16; j++) {
|
||||
sub = &grp->subs[j];
|
||||
sub->f0 = 0;
|
||||
sub->f2 = (rand() & 3) + 4;
|
||||
sub->f8 = (j << 8) + (rand() & 0xF) * 56;
|
||||
sub->fA = (rand() & 0xF) << 8;
|
||||
sub->f14 = (rand() & 0xF) << 13;
|
||||
sub->fC = ((rand() & 0xF) << 14) + 0x10000;
|
||||
sub->f10 = ((rand() & 0xF) << 12) + 0x8000;
|
||||
sub->f4 = 0x200;
|
||||
sub->f6 = (rand() & 0xF) << 4;
|
||||
sub->f18 = ((rand() & 3) << 5) + 0x40;
|
||||
}
|
||||
}
|
||||
|
||||
*(u16 *)(param_1 + 2) = *(u16 *)(param_1 + 2) + 1;
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC05_010/nonmatchings/ov_SC05_010_jr_8017C8D0", func_8017E1D4);
|
||||
|
||||
|
||||
@@ -2982,22 +2982,16 @@ extern void func_801861AC(void);
|
||||
|
||||
extern s16 D_800B9A02;
|
||||
extern u8 D_801151C8[];
|
||||
extern s32 D_801151D0;
|
||||
extern s16 D_80115126;
|
||||
extern u16 D_80115112;
|
||||
extern u16 D_8011511A;
|
||||
extern u8 D_80115138[];
|
||||
extern u8 D_80115148[];
|
||||
extern s32 D_80115130;
|
||||
extern u8 D_800B9A15;
|
||||
|
||||
extern s16 D_801ED568;
|
||||
extern u16 D_801ED56C;
|
||||
extern s16 D_801ED570;
|
||||
extern s32 D_801ED560;
|
||||
extern s32 D_801ED564;
|
||||
extern s16 D_801ED5F0;
|
||||
extern s16 D_801ED5F4;
|
||||
extern s16 D_801ED5F8;
|
||||
extern s16 D_801ED5FC;
|
||||
extern s16 D_801ED600;
|
||||
@@ -3032,6 +3026,18 @@ extern s32 func_80189240(s32 a0, s16 a1);
|
||||
extern s16 func_80189B54(s32 a0);
|
||||
|
||||
void func_801875E8(void) {
|
||||
/* [T51] scoped in from file scope: a file-scope decl of these symbols constrains every
|
||||
LATER function in this TU, which blocks a byte-true decl of a different type.
|
||||
Declaration-only move (cookbook §103); the whole-binary byte-gate is the arbiter. */
|
||||
extern u16 D_801ED56C;
|
||||
extern s16 D_801ED570;
|
||||
/* [T51] scoped in from file scope: a file-scope decl of these symbols constrains every
|
||||
LATER function in this TU, which blocks a byte-true decl of a different type.
|
||||
Declaration-only move (cookbook §103); the whole-binary byte-gate is the arbiter. */
|
||||
extern s32 D_801151D0;
|
||||
extern s16 D_801ED5F4;
|
||||
extern s16 D_80115126;
|
||||
extern u16 D_8011511A;
|
||||
s32 s0;
|
||||
s32 pad[2];
|
||||
(void)&pad;
|
||||
@@ -3499,7 +3505,125 @@ INCLUDE_ASM("asm/ov_SC05_017/nonmatchings/ov_SC05_017_jr_801875E8", func_80189B1
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC05_017/nonmatchings/ov_SC05_017_jr_801875E8", func_80189B54);
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC05_017/nonmatchings/ov_SC05_017_jr_801875E8", func_80189BA0);
|
||||
|
||||
/* func_80189BA0 — ov_SC03_001 (133 ins), exemplar of a 5-member open-only
|
||||
* h_norm cluster. Builds the full-screen fade overlay: a DR_MODE-style 8-byte
|
||||
* GP0 packet (0xE1000015), a 320x240 semi-transparent gouraud quad (POLY_G4,
|
||||
* code 0x3A), and a second 8-byte GP0 packet (0xE1000240), each linked into the
|
||||
* current OT with the psyq `addPrim` idiom. The type shapes and the
|
||||
* `((PTag *)x)->addr = ((PTag *)ot)->addr; ((PTag *)ot)->addr = (u32)x;` pair
|
||||
* are copied VERBATIM from the already-matched neighbour func_8018BCD4 in this
|
||||
* same TU (§71) — Env_* / PTag_* there are the fleet-canonical shapes.
|
||||
*
|
||||
* Levers that were load-bearing (all byte-tested; the draft is PIN-FREE):
|
||||
* §20 &D_801151D0 / &D_800B9A02 taken into pointer LOCALS -> each address is
|
||||
* force_reg'd once (lui+addiu -> $t2 / $a3) instead of a %lo per use.
|
||||
* §36 the 24-bit BITFIELD store, not a hand-written mask, is what emits
|
||||
* 0x00FFFFFF (lui+ori) ahead of 0xFF000000 (lui) while the body ANDs the
|
||||
* destination first — expmed's store_fixed_bit_field signature.
|
||||
* §37 asm-label aliases for D_801ED56C/D_801ED570: the TU canon is u16/s16
|
||||
* but the target does a bare `lbu %lo(sym)`, and a plain block-scope
|
||||
* `extern u8` would be a conflicting redeclaration.
|
||||
* --- `volatile` on the OT index read keeps all SIX *pbh loads alive; a plain
|
||||
* read cse-folds them and the function loses ~25 instructions.
|
||||
* S1 the whole body is ONE branch-free basic block and every store ties at
|
||||
* the same priority, so forward asm order == source statement order —
|
||||
* the POLY_G4 block below is a literal transcription of the target.
|
||||
* S2 `p` is destructively updated (multi-set -> no birthing boost) so its
|
||||
* `addiu +8` floats up into the preceding load-delay gap, while `r` is a
|
||||
* FRESH single-set local (boosted) so its `addiu +0x24` sinks to sit
|
||||
* immediately before `sb 3($a0)`. Both placements are the target's.
|
||||
* --- the bare `p = r;` before r's uses is a COMBINE BARRIER: without a SET
|
||||
* of `p` between `r = p + 9` and r's first use, `can_combine_p` lets
|
||||
* combine substitute `r` -> `p + 0x24` into every MEM offset and the
|
||||
* `addiu` disappears entirely (and, at the tail, `p += 2` folds to
|
||||
* `addiu $t3,$t3,0x2C` off the stale base instead of `addiu $t3,$a0,8`).
|
||||
* It also fixes the register rotation for free — verified that adding or
|
||||
* removing `register __asm__` pins on p/r/pbh is a byte no-op.
|
||||
*/
|
||||
|
||||
/* ---- TU-visible spellings (file scope of ov_SC03_001_jr_8018A3A8.c) ---- */
|
||||
|
||||
void func_80189BA0(void) {
|
||||
|
||||
extern s32 D_801151D0;
|
||||
extern u16 D_801ED56C;
|
||||
extern s16 D_801ED570;
|
||||
/* §100/§120: draft-local, uniquely-named types — they live in the BODY so
|
||||
* they cannot collide with the TU's own Env_8018BCD4 / PTag_8018BCD4. */
|
||||
typedef struct { u32 addr : 24; u32 len : 8; } PTag_8018C960_80189BA0;
|
||||
typedef struct { u32 *ot; u32 pad[4]; } Env_8018C960_80189BA0; /* 0x14 stride */
|
||||
typedef struct {
|
||||
u32 tag; /* 0x00 */
|
||||
u8 r0, g0, b0, code; /* 0x04..0x07 */
|
||||
s16 x0, y0; /* 0x08, 0x0A */
|
||||
u8 r1, g1, b1, p1; /* 0x0C..0x0F */
|
||||
s16 x1, y1; /* 0x10, 0x12 */
|
||||
u8 r2, g2, b2, p2; /* 0x14..0x17 */
|
||||
s16 x2, y2; /* 0x18, 0x1A */
|
||||
u8 r3, g3, b3, p3; /* 0x1C..0x1F */
|
||||
s16 x3, y3; /* 0x20, 0x22 */
|
||||
} PG4_8018C960_80189BA0; /* -> 0x24 */
|
||||
|
||||
extern Env_8018C960_80189BA0 D_800AE7BC[];
|
||||
extern u8 aD801EF1EC __asm__("D_801ED56C");
|
||||
extern u8 aD801EF1F0 __asm__("D_801ED570");
|
||||
|
||||
u32 **pp;
|
||||
volatile u16 *pbh;
|
||||
u32 *p;
|
||||
u32 *r;
|
||||
u8 c1, c2;
|
||||
|
||||
pp = (u32 **)&D_801151D0;
|
||||
pbh = (volatile u16 *)&D_800B9A02;
|
||||
|
||||
p = *pp;
|
||||
((PTag_8018C960_80189BA0 *)p)->len = 1;
|
||||
p[1] = 0xE1000015;
|
||||
((PTag_8018C960_80189BA0 *)p)->addr = ((PTag_8018C960_80189BA0 *)D_800AE7BC[*pbh].ot)->addr;
|
||||
((PTag_8018C960_80189BA0 *)D_800AE7BC[*pbh].ot)->addr = (u32)p;
|
||||
|
||||
p += 2;
|
||||
((PG4_8018C960_80189BA0 *)p)->tag = 0x08000000;
|
||||
((PG4_8018C960_80189BA0 *)p)->code = 0x3A;
|
||||
((PG4_8018C960_80189BA0 *)p)->x2 = -160;
|
||||
((PG4_8018C960_80189BA0 *)p)->x0 = -160;
|
||||
((PG4_8018C960_80189BA0 *)p)->x3 = 160;
|
||||
((PG4_8018C960_80189BA0 *)p)->x1 = 160;
|
||||
c1 = aD801EF1EC;
|
||||
((PG4_8018C960_80189BA0 *)p)->b1 = c1;
|
||||
((PG4_8018C960_80189BA0 *)p)->b0 = c1;
|
||||
((PG4_8018C960_80189BA0 *)p)->g1 = c1;
|
||||
((PG4_8018C960_80189BA0 *)p)->g0 = c1;
|
||||
((PG4_8018C960_80189BA0 *)p)->r1 = c1;
|
||||
((PG4_8018C960_80189BA0 *)p)->r0 = c1;
|
||||
c2 = aD801EF1F0;
|
||||
((PG4_8018C960_80189BA0 *)p)->y1 = -120;
|
||||
((PG4_8018C960_80189BA0 *)p)->b3 = c2;
|
||||
((PG4_8018C960_80189BA0 *)p)->b2 = c2;
|
||||
((PG4_8018C960_80189BA0 *)p)->g3 = c2;
|
||||
((PG4_8018C960_80189BA0 *)p)->g2 = c2;
|
||||
((PG4_8018C960_80189BA0 *)p)->r3 = c2;
|
||||
((PG4_8018C960_80189BA0 *)p)->r2 = c2;
|
||||
((PG4_8018C960_80189BA0 *)p)->y0 = -120;
|
||||
((PG4_8018C960_80189BA0 *)p)->y3 = 120;
|
||||
((PG4_8018C960_80189BA0 *)p)->y2 = 120;
|
||||
|
||||
((PTag_8018C960_80189BA0 *)p)->addr = ((PTag_8018C960_80189BA0 *)D_800AE7BC[*pbh].ot)->addr;
|
||||
((PTag_8018C960_80189BA0 *)D_800AE7BC[*pbh].ot)->addr = (u32)p;
|
||||
|
||||
r = p + 9; /* 0x24 */
|
||||
p = r; /* COMBINE BARRIER — see header */
|
||||
((PTag_8018C960_80189BA0 *)r)->len = 1;
|
||||
r[1] = 0xE1000240;
|
||||
((PTag_8018C960_80189BA0 *)r)->addr = ((PTag_8018C960_80189BA0 *)D_800AE7BC[*pbh].ot)->addr;
|
||||
((PTag_8018C960_80189BA0 *)D_800AE7BC[*pbh].ot)->addr = (u32)r;
|
||||
|
||||
p += 2;
|
||||
*pp = p;
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC05_017/nonmatchings/ov_SC05_017_jr_801875E8", func_80189DB4);
|
||||
|
||||
@@ -3722,7 +3846,99 @@ void func_8018A64C(void *a0) {
|
||||
void func_8018A688(void) {
|
||||
}
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC05_017/nonmatchings/ov_SC05_017_jr_801875E8", func_8018A690);
|
||||
|
||||
extern s32 func_8012BEE8(s32 a0);
|
||||
extern s32 rand(void);
|
||||
|
||||
void func_8018A690(s32 param_1) {
|
||||
s32 uVar1;
|
||||
s32 iVar2;
|
||||
register s32 iVar3 __asm__("$3");
|
||||
register s32 iVar4 __asm__("$16");
|
||||
u32 uVar3;
|
||||
|
||||
uVar1 = *(u16 *)(param_1 + 0x34);
|
||||
if (uVar1 == 1) {
|
||||
goto case1;
|
||||
}
|
||||
if (uVar1 < 2) {
|
||||
if (uVar1 == 0) {
|
||||
goto case0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (uVar1 == 2) {
|
||||
goto case2;
|
||||
}
|
||||
if (uVar1 != 3) {
|
||||
return;
|
||||
}
|
||||
goto case3;
|
||||
|
||||
case0:
|
||||
iVar2 = func_8012BEE8(param_1);
|
||||
if (iVar2 == 0) {
|
||||
return;
|
||||
}
|
||||
*(s32 *)(param_1 + 0x1c) = 0x40;
|
||||
*(u16 *)(param_1 + 0x34) = *(u16 *)(param_1 + 0x34) + 1;
|
||||
uVar3 = rand();
|
||||
iVar4 = uVar3 & 0x3fff;
|
||||
iVar4 = iVar4 + 0x7800;
|
||||
uVar3 = rand();
|
||||
if ((uVar3 & 1) == 0) {
|
||||
iVar4 = -iVar4;
|
||||
}
|
||||
*(s32 *)(param_1 + 0xe0) = iVar4;
|
||||
*(s32 *)(param_1 + 0xe4) = 0;
|
||||
return;
|
||||
|
||||
case1:
|
||||
iVar3 = *(s32 *)(param_1 + 0xe4);
|
||||
iVar3 = iVar3 + *(s32 *)(param_1 + 0xe0);
|
||||
*(s32 *)(param_1 + 0xdc) = *(s32 *)(param_1 + 0xdc) + iVar3;
|
||||
*(s32 *)(param_1 + 0xe4) = iVar3;
|
||||
*(u16 *)(*(s32 *)(param_1 + 0x20) + 0x12) = *(u16 *)(param_1 + 0xde);
|
||||
iVar2 = func_8012BEE8(param_1);
|
||||
if (iVar2 == 0) {
|
||||
return;
|
||||
}
|
||||
*(u16 *)(param_1 + 0x34) = *(u16 *)(param_1 + 0x34) + 1;
|
||||
uVar3 = rand();
|
||||
uVar3 = uVar3 & 0x3f;
|
||||
goto tail;
|
||||
|
||||
case2:
|
||||
*(s32 *)(param_1 + 0xdc) = *(s32 *)(param_1 + 0xdc) + *(s32 *)(param_1 + 0xe4);
|
||||
*(u16 *)(*(s32 *)(param_1 + 0x20) + 0x12) = *(u16 *)(param_1 + 0xde);
|
||||
iVar2 = func_8012BEE8(param_1);
|
||||
if (iVar2 == 0) {
|
||||
return;
|
||||
}
|
||||
*(s32 *)(param_1 + 0x1c) = 0x40;
|
||||
*(u16 *)(param_1 + 0x34) = *(u16 *)(param_1 + 0x34) + 1;
|
||||
*(s32 *)(param_1 + 0xe0) = -*(s32 *)(param_1 + 0xe0);
|
||||
return;
|
||||
|
||||
case3:
|
||||
__asm__ __volatile__("" ::: "memory");
|
||||
iVar3 = *(s32 *)(param_1 + 0xe4);
|
||||
iVar3 = iVar3 + *(s32 *)(param_1 + 0xe0);
|
||||
*(s32 *)(param_1 + 0xdc) = *(s32 *)(param_1 + 0xdc) + iVar3;
|
||||
*(s32 *)(param_1 + 0xe4) = iVar3;
|
||||
*(u16 *)(*(s32 *)(param_1 + 0x20) + 0x12) = *(u16 *)(param_1 + 0xde);
|
||||
iVar2 = func_8012BEE8(param_1);
|
||||
if (iVar2 == 0) {
|
||||
return;
|
||||
}
|
||||
*(u16 *)(param_1 + 0x34) = 0;
|
||||
uVar3 = rand();
|
||||
uVar3 = uVar3 & 0xff;
|
||||
|
||||
tail:
|
||||
*(u32 *)(param_1 + 0x1c) = uVar3 + 0x40;
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern void (*D_801E6814[])(void);
|
||||
|
||||
@@ -7113,7 +7113,101 @@ extern void func_800296F8(void);
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC06_008/nonmatchings/ov_SC06_008_jr_8017C294", func_80184E94);
|
||||
extern s32 func_8012BDBC(s32 a0, s32 a1);
|
||||
extern s32 func_80135888(s32 a0, s32 a1, s32 a2, s32 a3);
|
||||
extern void func_80172710(void);
|
||||
extern s32 func_80178BF8();
|
||||
#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_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" )
|
||||
|
||||
/* §71 sibling: identical shape to func_8018F390 (same TU, this file, D_80126B78/RotTransSV/
|
||||
* func_80135888/func_8012BDBC/func_80178BF8/func_80172710 idiom) already MATCHED -- only the
|
||||
* per-overlay data symbol (D_801A6BCC vs D_801E33F0) differs. §37 asm-label alias avoids the
|
||||
* `conflicting types` clash with the fleet's `extern void func_80184E94(void);` used elsewhere
|
||||
* in this TU as a state-handler function pointer. */
|
||||
|
||||
s32 aF801904E0() __asm__("func_80184E94");
|
||||
|
||||
s32 aF801904E0(param_1)
|
||||
void *param_1;
|
||||
{
|
||||
|
||||
extern s32 *D_80126B78;
|
||||
extern u8 D_801A6BCC[];
|
||||
MATRIX m;
|
||||
s32 obj;
|
||||
s32 sv0[2];
|
||||
s32 sv1[2];
|
||||
s32 flag;
|
||||
|
||||
obj = *(s32 *)((s32)param_1 + 0x64);
|
||||
m = *(MATRIX *)((u8 *)D_80126B78 + 0x34);
|
||||
|
||||
gte_SetRotMatrix(&m);
|
||||
gte_SetTransMatrix(&m);
|
||||
|
||||
RotTransSV(D_801A6BCC, sv0, &flag);
|
||||
RotTransSV(D_801A6BCC + 8, sv1, &flag);
|
||||
|
||||
if (func_80135888(*(s32 *)(*(s32 *)((s32)param_1 + 0x64) + 0x20),
|
||||
*(s32 *)(*(s32 *)((s32)param_1 + 0x64) + 0x58),
|
||||
(s32)sv0, (s32)sv1) == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (func_8012BDBC(obj, 0x300) == 0) {
|
||||
return 0;
|
||||
}
|
||||
*(s16 *)(obj + 0x2) = 3;
|
||||
func_80178BF8();
|
||||
return (s32)func_80172710;
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern void (*D_801A75D0[])(void);
|
||||
|
||||
@@ -4784,7 +4784,152 @@ void aF8017ED80(void *param_1) {
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC06_010/nonmatchings/ov_SC06_010_jr_8017A4AC", func_80181408);
|
||||
|
||||
/* func_80181408 -- ov_SC06_008, TU ov_SC06_008_jr_8017C294.c (open-only h_norm
|
||||
* cluster exemplar, 7 members).
|
||||
*
|
||||
* a0+0x0 : u16 active flag; 0 => early return.
|
||||
* a0+0x84 : s16 sound cooldown timer.
|
||||
* cooldown != 0 -> just decrement it.
|
||||
* cooldown == 0 -> try to play a positional sound (RotTransPers screen
|
||||
* projection of the parent's position, range-gated on
|
||||
* screen X/Y, volume from the classic div-by-0xF0 /
|
||||
* div-by-0x1E magic-constant idiom -- byte-proven sibling
|
||||
* form is func_80181CF0 in this same TU, sndid 0x849 here
|
||||
* vs 0x961 there), then unconditionally reset the timer
|
||||
* to 0xA regardless of whether the sound actually played.
|
||||
* a0+0xFC / 0xFE : running hit-combo accumulators, bumped by +/-0x280 every
|
||||
* call (unconditional tail).
|
||||
* Tail always calls ((void (*)(void *))func_80181234)(a0) (the TU's canonical decl for this
|
||||
* symbol is void(void) -- S35 self-axis -- so this draft binds its own
|
||||
* private extern with the asm's real void(void*) shape).
|
||||
*
|
||||
* Control flow is EXPLICIT goto/label, mirroring source-order block
|
||||
* placement (gcc-2.7.2 lays out basic blocks in literal source order, not by
|
||||
* fallthrough preference -- see the func_80181CF0 comment, same TU): the
|
||||
* cooldown!=0 decrement is the SHORT block and sits out-of-line (jumped to),
|
||||
* the cooldown==0 RTP+sound block is the LONG block and sits inline
|
||||
* (fallthrough), matching the target's physical layout exactly.
|
||||
*
|
||||
* MATCH levers (byte-proven, 2026-08-05):
|
||||
* 1. Naive `if(old!=0){cool=old-1;}else{...}` folds trivially: reorg.c's
|
||||
* delay-slot filler steals the single-insn decrement into the `bnez`'s
|
||||
* own delay slot and retargets the branch straight to the join label
|
||||
* (2 ins short of target). The target instead keeps a genuine copy
|
||||
* (`addu $v1,$v0,zero`) in the delay slot and a SEPARATE `addiu $v0,$v1,-1`
|
||||
* at the decrement site. Reproduced by pinning a second variable
|
||||
* `register s32 v1 __asm__("$3")`, assigned UNCONDITIONALLY right after
|
||||
* the load (`v1 = old;`) -- the scheduler places that copy in the
|
||||
* branch's delay slot on its own, and the decrement (`cool = v1 - 1`)
|
||||
* can no longer be folded away. `cool` is separately pinned to
|
||||
* `__asm__("$2")` so its other def sites (the three `cool = 0xA` early
|
||||
* exits) don't drift onto $3 by coalescing with v1.
|
||||
* 2. The tail's `sh $v0,0x84($s0)` / `addu $a0,$s0,zero` order (store off
|
||||
* the callee-saved pointer BEFORE reloading it into the call-argument
|
||||
* register) needed a `__asm__ __volatile__("":::"memory")` fence right
|
||||
* after the store -- without it, sched1 hoists the independent a0-reload
|
||||
* ahead of the store even when the reload is written later in source.
|
||||
* 3. Frame is -0x38, 8 bytes (2 words) larger than the natural -0x30 the
|
||||
* locals alone produce; `pad2[2]` (dead, address never read) inside `L`
|
||||
* reserves them, mirroring func_80181CF0's own "dead aggregate sizes the
|
||||
* frame" idiom.
|
||||
*/
|
||||
|
||||
|
||||
/* §37/§124 def-side asm-label alias (P30 S1d class lever): the TU declares
|
||||
* `extern void func_80181408(void);` (L4082, L4091) for callers that invoke it with NO args,
|
||||
* while the byte-true definition takes an s32 in $a0 -> `conflicting types`. Neither side can
|
||||
* move (a no-prototype escape is illegal once a param promotes), so the DEFINITION gets a
|
||||
* private C identifier and binds the emitted symbol with a GNU asm label. Zero blast radius:
|
||||
* the TU's declaration never meets the definition, and the emitted symbol is unchanged. */
|
||||
void aF8017EF54(s32 a0) __asm__("func_80181408");
|
||||
|
||||
void aF8017EF54(s32 a0)
|
||||
{
|
||||
extern void func_8004914C(void *a0);
|
||||
extern void func_800491AC(void *a0);
|
||||
extern void func_8002D4C8(s32 a0, s32 a1);
|
||||
extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3);
|
||||
extern u8 D_800AF648;
|
||||
extern void func_80181234(void);
|
||||
struct {
|
||||
s16 v[3]; /* sp+0x10 */
|
||||
s16 pad1; /* sp+0x16 */
|
||||
u16 sxy[2]; /* sp+0x18 */
|
||||
s32 z; /* sp+0x1C */
|
||||
s32 flag; /* sp+0x20 */
|
||||
s32 pad2[2]; /* sp+0x24 -- dead, sizes the frame */
|
||||
} L;
|
||||
|
||||
register s32 v1 __asm__("$3");
|
||||
register s32 cool __asm__("$2");
|
||||
s32 old;
|
||||
|
||||
if (*(u16 *)(a0 + 0x0) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
old = *(s16 *)(a0 + 0x84);
|
||||
v1 = old;
|
||||
if (old != 0) {
|
||||
goto L_dec;
|
||||
}
|
||||
|
||||
L.v[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48);
|
||||
L.v[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C);
|
||||
L.v[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50);
|
||||
{ register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); }
|
||||
{ register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); }
|
||||
RotTransPers((s32)L.v, (s32)L.sxy, &L.z, &L.flag);
|
||||
|
||||
if (L.flag < 0) {
|
||||
cool = 0xA;
|
||||
goto L_join;
|
||||
}
|
||||
if ((u32)((L.sxy[0] + 0xEF) & 0xFFFF) >= 0x1DF) {
|
||||
cool = 0xA;
|
||||
goto L_join;
|
||||
}
|
||||
if ((u32)((L.sxy[1] + 0xB3) & 0xFFFF) >= 0x167) {
|
||||
goto L_snd_skip;
|
||||
}
|
||||
|
||||
{
|
||||
s32 sx = (s16)L.sxy[0];
|
||||
s32 av;
|
||||
|
||||
av = sx;
|
||||
if (sx < 0) {
|
||||
av = -sx;
|
||||
}
|
||||
av = ((0xF0 - av) * 0x7F) / 0xF0;
|
||||
sx = (sx + 0xF0) / 0x1E;
|
||||
if (sx == 0x10) {
|
||||
sx = 0xF;
|
||||
}
|
||||
sx = sx << 8;
|
||||
func_8002D4C8(0x849, (av | (0x3000 | sx)) & 0xFFFF);
|
||||
}
|
||||
|
||||
L_snd_skip:
|
||||
cool = 0xA;
|
||||
goto L_join;
|
||||
|
||||
L_dec:
|
||||
cool = v1 - 1;
|
||||
|
||||
L_join:
|
||||
*(s16 *)(a0 + 0x84) = cool;
|
||||
__asm__ __volatile__("" ::: "memory");
|
||||
|
||||
{
|
||||
s32 p = a0;
|
||||
*(u16 *)(p + 0xFC) = *(u16 *)(p + 0xFC) + 0x280;
|
||||
*(u16 *)(p + 0xFE) = *(u16 *)(p + 0xFE) - 0x280;
|
||||
((void (*)(void *))func_80181234)((void *)p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern s32 rand(void);
|
||||
@@ -5124,7 +5269,97 @@ void func_80181F88(void *a0) {
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC06_010/nonmatchings/ov_SC06_010_jr_8017A4AC", func_80181FC4);
|
||||
|
||||
/* SV4 is the TU-canonical name (src/shared/engine_types.h) for func_8012F214's
|
||||
* in/out struct (see ov_SC06_008_jr_8017AE2C.c:3135, "SV4 svec" comment: func_8012F214 out).
|
||||
* Isolated match_one has no include path to that header, so it is typedef'd
|
||||
* locally here for the standalone compile only. */
|
||||
|
||||
|
||||
/* func_80181FC4 - ov_SC06_008 / ov_SC06_008_jr_8017C294 (93 ins)
|
||||
*
|
||||
* One-time init (guarded by state flag at +0x34): mirror the +0x64 sub-object's
|
||||
* +0x20/+0x12 field into our own +0x20 sub-object, kick off two "core" calls,
|
||||
* pick an entry from the 2-element 12-byte table D_801A4C64 (indexed by the
|
||||
* s16 at +0x70), then call func_8012F214 with a zeroed input SV4 and read the
|
||||
* first 3 fields of the output SV4 back into +6/+0xA/+0xE. Sets the countdown
|
||||
* at +0x1c to 0x5a and marks the state flag +0x34 = 1.
|
||||
*
|
||||
* Always-executed tail: bump the +0x20 sub-object's +0x10/+0x12/+0x14 fields
|
||||
* (reloading the +0x20 pointer fresh for each field -- no CSE across the
|
||||
* intervening stores, straight literal translation), mirror +0x14 into +0xDC,
|
||||
* call func_8012CBCC(a0) and test its return (canonical fleet decl is
|
||||
* void func_8012CBCC(s32 a0); the return value is read via a function-
|
||||
* pointer cast at the use site, per the established TU idiom -- see
|
||||
* ov_SC03_099_jr_8017BEBC.c:5630 comment block). If (ret & 0x6000), decrement
|
||||
* the +0xac counter (signed s16 compare-to-zero on the POST-decrement value --
|
||||
* gcc-2.7.2's sll-by-16/bnez idiom for a s16 local) and negate +0xDC into
|
||||
* +0x14; on the counter hitting zero, call func_8012C218. Finally decrement
|
||||
* the +0x1c countdown and call func_8012C218 again when IT hits zero.
|
||||
*/
|
||||
|
||||
extern void func_8012B2CC(s32 a0);
|
||||
extern void func_8012B23C(s32 a0);
|
||||
extern void func_8012B14C(s32 a0, s32 a1);
|
||||
extern void func_8012F214(s32 a0, s32 a1, s32 a2);
|
||||
extern void func_8012CBCC(s32 a0);
|
||||
extern void func_8012C218(void *a0);
|
||||
|
||||
|
||||
void func_80181FC4(s32 a0)
|
||||
{
|
||||
|
||||
extern s32 D_801A4C64;
|
||||
SV4 in;
|
||||
SV4 out;
|
||||
s16 v1;
|
||||
u16 uStack_c;
|
||||
|
||||
if (*(u16 *)(a0 + 0x34) == 0) {
|
||||
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) =
|
||||
*(u16 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x12);
|
||||
func_8012B2CC(a0);
|
||||
func_8012B23C(a0);
|
||||
func_8012B14C(a0, *(s16 *)(a0 + 0x70) * 12 + (s32)&D_801A4C64);
|
||||
|
||||
in.a = 0;
|
||||
in.b = 0;
|
||||
in.c = 0x10;
|
||||
func_8012F214(a0, (s32)&in, (s32)&out);
|
||||
*(u16 *)(a0 + 6) = out.a;
|
||||
*(u16 *)(a0 + 0xa) = out.b;
|
||||
uStack_c = out.c;
|
||||
*(s32 *)(a0 + 0x1c) = 0x5a;
|
||||
*(u16 *)(a0 + 0x34) = 1;
|
||||
*(u16 *)(a0 + 0xe) = uStack_c;
|
||||
}
|
||||
|
||||
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) += -0x80;
|
||||
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) += 4;
|
||||
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x14) += *(u16 *)(a0 + 0xfc);
|
||||
|
||||
*(s32 *)(a0 + 0xdc) = *(s32 *)(a0 + 0x14);
|
||||
if ((((s32 (*)(s32))func_8012CBCC)(a0)) & 0x6000) {
|
||||
register s32 negdc __asm__("$2");
|
||||
negdc = -*(s32 *)(a0 + 0xdc);
|
||||
v1 = *(u16 *)(a0 + 0xac);
|
||||
v1 -= 1;
|
||||
*(s16 *)(a0 + 0xac) = v1;
|
||||
*(s32 *)(a0 + 0x14) = negdc;
|
||||
if (v1 == 0) {
|
||||
func_8012C218((void *)a0);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
s32 iVar3 = *(s32 *)(a0 + 0x1c) - 1;
|
||||
*(s32 *)(a0 + 0x1c) = iVar3;
|
||||
if (iVar3 == 0) {
|
||||
func_8012C218((void *)a0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern void (*D_801A4C7C[])(void);
|
||||
@@ -5633,7 +5868,86 @@ void func_8018315C(s32 a0)
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC06_010/nonmatchings/ov_SC06_010_jr_8017A4AC", func_80183560);
|
||||
|
||||
|
||||
// TARGET: func_80183560 (ov_SC06_008, TU ov_SC06_008_jr_8017C294.c, 93 ins)
|
||||
//
|
||||
// Template: func_801821F8 in this SAME TU (src/ov_SC06_008/ov_SC06_008_jr_8017C294.c,
|
||||
// around line 5283) is an already-MATCHED sibling (126 ins) with a documented byte-exact
|
||||
// idiom set (its comment, verbatim):
|
||||
// @class: plumbing
|
||||
// @stuck: none — MATCH (126 ins). Keys: (1) cVar1 as `int` (not unsigned char) so the
|
||||
// lbu-loaded byte stays full-width and gcc omits the per-compare `andi 0xff`; (2) uninitialized
|
||||
// `int unaff_s1` -> $s1 (live-from-entry across func_8002D4C8); (3) func_8016AA50 takes TWO args
|
||||
// (param_1, unaff_s1) — a1=unaff_s1 arg-setup is reused by the preceding subtraction and a0=s0
|
||||
// hoists into the branch delay slot; (4) 0x76 read UNSIGNED (lhu) in the subtract, SIGNED (lh) in
|
||||
// the `< 1` test.
|
||||
//
|
||||
// func_80183560 is the SAME body with the leading "if (*(short*)(param_1+0xfc)==0) {...}" block
|
||||
// (the 0x64-indirected 3x int-copy + 3x u16-copy prologue) removed, and the "already fired" gate
|
||||
// field is 0xe2 instead of 0x102. Confirmed against the target .s: no reference anywhere to 0xfc,
|
||||
// 0x64, or 0x102/0x20 offsets; the gate compare is `lh $v1, 0xE2($s0)` / `sh $v1(=0xA), 0xE2($s0)`.
|
||||
|
||||
extern void func_8002D4C8(int, int);
|
||||
extern void func_8016AA50(int, int);
|
||||
extern s32 func_8016B428(s32);
|
||||
extern void func_80019064(void *);
|
||||
extern void func_8002A520(int);
|
||||
extern void func_8002A790(int);
|
||||
extern void func_80131E00(int, int);
|
||||
|
||||
void func_80183560(int param_1)
|
||||
{
|
||||
extern unsigned char D_801A7124[];
|
||||
int cVar1;
|
||||
int unaff_s1;
|
||||
|
||||
cVar1 = *(unsigned char *)(param_1 + 0x5e);
|
||||
*(char *)(param_1 + 0xc1) = 0;
|
||||
*(short *)(param_1 + 0x5e) = 0;
|
||||
*(unsigned short *)(param_1 + 0x5c) = *(unsigned short *)(param_1 + 0x5c) & 0xfffe;
|
||||
if (*(short *)(param_1 + 0xe2) == 0) {
|
||||
*(short *)(param_1 + 0xe2) = 10;
|
||||
*(unsigned short *)(param_1 + 0x5c) = *(unsigned short *)(param_1 + 0x5c) | 0x4000;
|
||||
func_8002D4C8(0x9b7, 0);
|
||||
if (*(short *)(param_1 + 0x60) != 0) {
|
||||
if (cVar1 == 0x1d) {
|
||||
*(short *)(param_1 + 0x82) = 0;
|
||||
*(short *)(param_1 + 0x7c) = *(unsigned short *)(param_1 + 6);
|
||||
*(short *)(param_1 + 0x7e) = *(unsigned short *)(param_1 + 0xa);
|
||||
*(short *)(param_1 + 0x80) = *(unsigned short *)(param_1 + 0xe);
|
||||
}
|
||||
if (*(int *)(param_1 + 0x78) != 0) {
|
||||
unaff_s1 = (int)*(short *)(param_1 + 0x60) *
|
||||
(int)*(short *)(*(int *)(param_1 + 0x78) + 0x30) >> 0xc;
|
||||
if (unaff_s1 < 1) {
|
||||
unaff_s1 = 1;
|
||||
}
|
||||
}
|
||||
*(unsigned short *)(param_1 + 0x76) =
|
||||
*(unsigned short *)(param_1 + 0x76) - unaff_s1;
|
||||
func_8016AA50(param_1, unaff_s1);
|
||||
if ((*(unsigned short *)(param_1 + 0x82) & 1) != 0) {
|
||||
((void (*)(int))func_8016B428)(param_1);
|
||||
func_80019064(D_801A7124);
|
||||
}
|
||||
}
|
||||
if (cVar1 != 0x1d) {
|
||||
if (*(unsigned char *)(param_1 + 0xc8) != 0) {
|
||||
func_8002A520(param_1);
|
||||
}
|
||||
if (*(unsigned char *)(param_1 + 0xc9) != 0) {
|
||||
func_8002A790(param_1);
|
||||
}
|
||||
}
|
||||
if (*(short *)(param_1 + 0x76) < 1) {
|
||||
*(short *)(param_1 + 0x5c) = 0;
|
||||
func_80131E00(param_1, 6);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// @class: schedule
|
||||
|
||||
@@ -3996,7 +3996,152 @@ void aF8017ED80(void *param_1) {
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C", func_8017ED60);
|
||||
|
||||
/* func_8017ED60 -- ov_SC06_008, TU ov_SC06_008_jr_8017C294.c (open-only h_norm
|
||||
* cluster exemplar, 7 members).
|
||||
*
|
||||
* a0+0x0 : u16 active flag; 0 => early return.
|
||||
* a0+0x84 : s16 sound cooldown timer.
|
||||
* cooldown != 0 -> just decrement it.
|
||||
* cooldown == 0 -> try to play a positional sound (RotTransPers screen
|
||||
* projection of the parent's position, range-gated on
|
||||
* screen X/Y, volume from the classic div-by-0xF0 /
|
||||
* div-by-0x1E magic-constant idiom -- byte-proven sibling
|
||||
* form is func_80181CF0 in this same TU, sndid 0x849 here
|
||||
* vs 0x961 there), then unconditionally reset the timer
|
||||
* to 0xA regardless of whether the sound actually played.
|
||||
* a0+0xFC / 0xFE : running hit-combo accumulators, bumped by +/-0x280 every
|
||||
* call (unconditional tail).
|
||||
* Tail always calls ((void (*)(void *))func_8017EB8C)(a0) (the TU's canonical decl for this
|
||||
* symbol is void(void) -- S35 self-axis -- so this draft binds its own
|
||||
* private extern with the asm's real void(void*) shape).
|
||||
*
|
||||
* Control flow is EXPLICIT goto/label, mirroring source-order block
|
||||
* placement (gcc-2.7.2 lays out basic blocks in literal source order, not by
|
||||
* fallthrough preference -- see the func_80181CF0 comment, same TU): the
|
||||
* cooldown!=0 decrement is the SHORT block and sits out-of-line (jumped to),
|
||||
* the cooldown==0 RTP+sound block is the LONG block and sits inline
|
||||
* (fallthrough), matching the target's physical layout exactly.
|
||||
*
|
||||
* MATCH levers (byte-proven, 2026-08-05):
|
||||
* 1. Naive `if(old!=0){cool=old-1;}else{...}` folds trivially: reorg.c's
|
||||
* delay-slot filler steals the single-insn decrement into the `bnez`'s
|
||||
* own delay slot and retargets the branch straight to the join label
|
||||
* (2 ins short of target). The target instead keeps a genuine copy
|
||||
* (`addu $v1,$v0,zero`) in the delay slot and a SEPARATE `addiu $v0,$v1,-1`
|
||||
* at the decrement site. Reproduced by pinning a second variable
|
||||
* `register s32 v1 __asm__("$3")`, assigned UNCONDITIONALLY right after
|
||||
* the load (`v1 = old;`) -- the scheduler places that copy in the
|
||||
* branch's delay slot on its own, and the decrement (`cool = v1 - 1`)
|
||||
* can no longer be folded away. `cool` is separately pinned to
|
||||
* `__asm__("$2")` so its other def sites (the three `cool = 0xA` early
|
||||
* exits) don't drift onto $3 by coalescing with v1.
|
||||
* 2. The tail's `sh $v0,0x84($s0)` / `addu $a0,$s0,zero` order (store off
|
||||
* the callee-saved pointer BEFORE reloading it into the call-argument
|
||||
* register) needed a `__asm__ __volatile__("":::"memory")` fence right
|
||||
* after the store -- without it, sched1 hoists the independent a0-reload
|
||||
* ahead of the store even when the reload is written later in source.
|
||||
* 3. Frame is -0x38, 8 bytes (2 words) larger than the natural -0x30 the
|
||||
* locals alone produce; `pad2[2]` (dead, address never read) inside `L`
|
||||
* reserves them, mirroring func_80181CF0's own "dead aggregate sizes the
|
||||
* frame" idiom.
|
||||
*/
|
||||
|
||||
|
||||
/* §37/§124 def-side asm-label alias (P30 S1d class lever): the TU declares
|
||||
* `extern void func_8017ED60(void);` (L4082, L4091) for callers that invoke it with NO args,
|
||||
* while the byte-true definition takes an s32 in $a0 -> `conflicting types`. Neither side can
|
||||
* move (a no-prototype escape is illegal once a param promotes), so the DEFINITION gets a
|
||||
* private C identifier and binds the emitted symbol with a GNU asm label. Zero blast radius:
|
||||
* the TU's declaration never meets the definition, and the emitted symbol is unchanged. */
|
||||
void aF8017EF54(s32 a0) __asm__("func_8017ED60");
|
||||
|
||||
void aF8017EF54(s32 a0)
|
||||
{
|
||||
extern void func_8004914C(void *a0);
|
||||
extern void func_800491AC(void *a0);
|
||||
extern void func_8002D4C8(s32 a0, s32 a1);
|
||||
extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3);
|
||||
extern u8 D_800AF648;
|
||||
extern void func_8017EB8C(s32);
|
||||
struct {
|
||||
s16 v[3]; /* sp+0x10 */
|
||||
s16 pad1; /* sp+0x16 */
|
||||
u16 sxy[2]; /* sp+0x18 */
|
||||
s32 z; /* sp+0x1C */
|
||||
s32 flag; /* sp+0x20 */
|
||||
s32 pad2[2]; /* sp+0x24 -- dead, sizes the frame */
|
||||
} L;
|
||||
|
||||
register s32 v1 __asm__("$3");
|
||||
register s32 cool __asm__("$2");
|
||||
s32 old;
|
||||
|
||||
if (*(u16 *)(a0 + 0x0) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
old = *(s16 *)(a0 + 0x84);
|
||||
v1 = old;
|
||||
if (old != 0) {
|
||||
goto L_dec;
|
||||
}
|
||||
|
||||
L.v[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48);
|
||||
L.v[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C);
|
||||
L.v[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50);
|
||||
{ register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); }
|
||||
{ register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); }
|
||||
RotTransPers((s32)L.v, (s32)L.sxy, &L.z, &L.flag);
|
||||
|
||||
if (L.flag < 0) {
|
||||
cool = 0xA;
|
||||
goto L_join;
|
||||
}
|
||||
if ((u32)((L.sxy[0] + 0xEF) & 0xFFFF) >= 0x1DF) {
|
||||
cool = 0xA;
|
||||
goto L_join;
|
||||
}
|
||||
if ((u32)((L.sxy[1] + 0xB3) & 0xFFFF) >= 0x167) {
|
||||
goto L_snd_skip;
|
||||
}
|
||||
|
||||
{
|
||||
s32 sx = (s16)L.sxy[0];
|
||||
s32 av;
|
||||
|
||||
av = sx;
|
||||
if (sx < 0) {
|
||||
av = -sx;
|
||||
}
|
||||
av = ((0xF0 - av) * 0x7F) / 0xF0;
|
||||
sx = (sx + 0xF0) / 0x1E;
|
||||
if (sx == 0x10) {
|
||||
sx = 0xF;
|
||||
}
|
||||
sx = sx << 8;
|
||||
func_8002D4C8(0x849, (av | (0x3000 | sx)) & 0xFFFF);
|
||||
}
|
||||
|
||||
L_snd_skip:
|
||||
cool = 0xA;
|
||||
goto L_join;
|
||||
|
||||
L_dec:
|
||||
cool = v1 - 1;
|
||||
|
||||
L_join:
|
||||
*(s16 *)(a0 + 0x84) = cool;
|
||||
__asm__ __volatile__("" ::: "memory");
|
||||
|
||||
{
|
||||
s32 p = a0;
|
||||
*(u16 *)(p + 0xFC) = *(u16 *)(p + 0xFC) + 0x280;
|
||||
*(u16 *)(p + 0xFE) = *(u16 *)(p + 0xFE) - 0x280;
|
||||
((void (*)(void *))func_8017EB8C)((void *)p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern s32 rand(void);
|
||||
@@ -4845,7 +4990,86 @@ void func_80180AB4(s32 a0)
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC06_018/nonmatchings/ov_SC06_018_jr_8017C24C", func_80180EB8);
|
||||
|
||||
|
||||
// TARGET: func_80180EB8 (ov_SC06_008, TU ov_SC06_008_jr_8017C294.c, 93 ins)
|
||||
//
|
||||
// Template: func_801821F8 in this SAME TU (src/ov_SC06_008/ov_SC06_008_jr_8017C294.c,
|
||||
// around line 5283) is an already-MATCHED sibling (126 ins) with a documented byte-exact
|
||||
// idiom set (its comment, verbatim):
|
||||
// @class: plumbing
|
||||
// @stuck: none — MATCH (126 ins). Keys: (1) cVar1 as `int` (not unsigned char) so the
|
||||
// lbu-loaded byte stays full-width and gcc omits the per-compare `andi 0xff`; (2) uninitialized
|
||||
// `int unaff_s1` -> $s1 (live-from-entry across func_8002D4C8); (3) func_8016AA50 takes TWO args
|
||||
// (param_1, unaff_s1) — a1=unaff_s1 arg-setup is reused by the preceding subtraction and a0=s0
|
||||
// hoists into the branch delay slot; (4) 0x76 read UNSIGNED (lhu) in the subtract, SIGNED (lh) in
|
||||
// the `< 1` test.
|
||||
//
|
||||
// func_80180EB8 is the SAME body with the leading "if (*(short*)(param_1+0xfc)==0) {...}" block
|
||||
// (the 0x64-indirected 3x int-copy + 3x u16-copy prologue) removed, and the "already fired" gate
|
||||
// field is 0xe2 instead of 0x102. Confirmed against the target .s: no reference anywhere to 0xfc,
|
||||
// 0x64, or 0x102/0x20 offsets; the gate compare is `lh $v1, 0xE2($s0)` / `sh $v1(=0xA), 0xE2($s0)`.
|
||||
|
||||
extern void func_8002D4C8(int, int);
|
||||
extern void func_8016AA50(int, int);
|
||||
extern s32 func_8016B428(s32);
|
||||
extern void func_80019064(void *);
|
||||
extern void func_8002A520(int);
|
||||
extern void func_8002A790(int);
|
||||
extern void func_80131E00(int, int);
|
||||
|
||||
void func_80180EB8(int param_1)
|
||||
{
|
||||
extern unsigned char D_801AD450[];
|
||||
int cVar1;
|
||||
int unaff_s1;
|
||||
|
||||
cVar1 = *(unsigned char *)(param_1 + 0x5e);
|
||||
*(char *)(param_1 + 0xc1) = 0;
|
||||
*(short *)(param_1 + 0x5e) = 0;
|
||||
*(unsigned short *)(param_1 + 0x5c) = *(unsigned short *)(param_1 + 0x5c) & 0xfffe;
|
||||
if (*(short *)(param_1 + 0xe2) == 0) {
|
||||
*(short *)(param_1 + 0xe2) = 10;
|
||||
*(unsigned short *)(param_1 + 0x5c) = *(unsigned short *)(param_1 + 0x5c) | 0x4000;
|
||||
func_8002D4C8(0x9b7, 0);
|
||||
if (*(short *)(param_1 + 0x60) != 0) {
|
||||
if (cVar1 == 0x1d) {
|
||||
*(short *)(param_1 + 0x82) = 0;
|
||||
*(short *)(param_1 + 0x7c) = *(unsigned short *)(param_1 + 6);
|
||||
*(short *)(param_1 + 0x7e) = *(unsigned short *)(param_1 + 0xa);
|
||||
*(short *)(param_1 + 0x80) = *(unsigned short *)(param_1 + 0xe);
|
||||
}
|
||||
if (*(int *)(param_1 + 0x78) != 0) {
|
||||
unaff_s1 = (int)*(short *)(param_1 + 0x60) *
|
||||
(int)*(short *)(*(int *)(param_1 + 0x78) + 0x30) >> 0xc;
|
||||
if (unaff_s1 < 1) {
|
||||
unaff_s1 = 1;
|
||||
}
|
||||
}
|
||||
*(unsigned short *)(param_1 + 0x76) =
|
||||
*(unsigned short *)(param_1 + 0x76) - unaff_s1;
|
||||
func_8016AA50(param_1, unaff_s1);
|
||||
if ((*(unsigned short *)(param_1 + 0x82) & 1) != 0) {
|
||||
((void (*)(int))func_8016B428)(param_1);
|
||||
func_80019064(D_801AD450);
|
||||
}
|
||||
}
|
||||
if (cVar1 != 0x1d) {
|
||||
if (*(unsigned char *)(param_1 + 0xc8) != 0) {
|
||||
func_8002A520(param_1);
|
||||
}
|
||||
if (*(unsigned char *)(param_1 + 0xc9) != 0) {
|
||||
func_8002A790(param_1);
|
||||
}
|
||||
}
|
||||
if (*(short *)(param_1 + 0x76) < 1) {
|
||||
*(short *)(param_1 + 0x5c) = 0;
|
||||
func_80131E00(param_1, 6);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// @class: schedule
|
||||
// @stuck: none — MATCH; success-block placed last via `goto big` (bnez forward into epilogue), single cae4 merge kept
|
||||
|
||||
@@ -2995,7 +2995,134 @@ store:
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC06_020/nonmatchings/ov_SC06_020_jr_80180B04", func_80181490);
|
||||
|
||||
/* func_80181490 — walk the 0x60-entry / 0x10C-stride entity table D_801202A0 and
|
||||
* react to the first neighbour of class 0x27A (get pushed away from it) or 0x2F4
|
||||
* (get clamped down onto it).
|
||||
*
|
||||
* §71 sibling-first: the callee signatures below are copied VERBATIM from this TU's
|
||||
* own already-matched neighbours — func_8012B0B4 (TU L6971/7855/8177), func_8012B6D4
|
||||
* (TU L6419), func_8012CEB0 (TU L7226, the func_80187844 block), func_8012C098
|
||||
* (TU L5379) — and D_801202A0 is the TU's file-scope `extern u8 D_801202A0[];` (L384).
|
||||
* func_8012BC60 / func_8012ADE4 are not declared in this TU; the forms below are the
|
||||
* fleet-majority shapes (func_8012ADE4 verbatim; func_8012BC60 with `void *` instead of
|
||||
* `struct Vec *` so the draft does not depend on engine_types.h being in scope).
|
||||
*
|
||||
* FIVE load-bearing constructs (do NOT "clean up"):
|
||||
*
|
||||
* 1. NO SECOND WALKED POINTER. All of +0x6/+0xA/+0xE are written as `*(T *)(p + k)`
|
||||
* off the single biv `p`. combine_givs then merges the three DEST_ADDR givs onto
|
||||
* ONE anchor = the LAST-emitted one (+0xE, from the case-0x2F4 `lh`), giving the
|
||||
* target's `$s3 = $s2 + 0xE` with -0x8/-0x4/0x0 displacements.
|
||||
* An explicit `q = p + 0xE` with `*(u16 *)q` looks equivalent and is NOT:
|
||||
* gcc-2.7.2 excludes a bare `*q` (mult 1, add 0) from givs (find_mem_givs:4198),
|
||||
* so q stays a live biv AND the remaining two accesses combine onto their own
|
||||
* anchor +0xA => THREE IVs, the wrong anchor, and the $s6 hoist lost to pressure
|
||||
* (measured: 111 ins, 87 mismatched). gcc-2.7.2-map/loop.md §L1 rules 4 & 6.
|
||||
*
|
||||
* 2. `switch`, not `if/else if`. The two-case switch is what emits the target's
|
||||
* compare CHAIN with BOTH arms out of line (`beq`/`beq`/`j default`, 6 slots).
|
||||
* An `if (id == 0x27A) ... else if (id == 0x2F4)` inverts the first test and lets
|
||||
* the 0x27A arm fall through — 2 instructions short.
|
||||
*
|
||||
* 3. do-while with `i++` BEFORE `p += 0x10C`. strength_reduce inserts the reduced
|
||||
* giv's `addiu` immediately before ITS biv's increment, so the source order
|
||||
* i-then-p is what produces `addiu $s4,$s4,1` / `addiu $s3,$s3,0x10C` /
|
||||
* (delay) `addiu $s2,$s2,0x10C`. A `for (i = 0; i < 0x60; i++)` with `p += 0x10C`
|
||||
* last puts the giv add first and swaps the pair.
|
||||
*
|
||||
* 4. `self4` and `sc` are REAL pre-loop locals, in that order. Both are loop
|
||||
* invariants; written inline as `(s16 *)(a0 + 4)` / `(unsigned int *)sp20` at the
|
||||
* call, combine folds the address straight into the argument move
|
||||
* (`addiu $a0,$sp,0x20`) and the target's `$s6 = $sp + 0x20` hoist never happens.
|
||||
* Assigning them in a *different basic block* from their uses is what keeps the
|
||||
* pseudos alive; the declaration ORDER (p, i, self4, sc) is what gives
|
||||
* $s2/$s4/$s5/$s6 in the target's prologue emission order.
|
||||
*
|
||||
* 5. `s16 y` (a SHORT local), and `s32 sp20[2]` (an EIGHT-byte scratch).
|
||||
* - The short local is why `y` gets a second pseudo: gcc-2.7.2 emits
|
||||
* `(set (reg:HI B) (subreg:HI (reg:SI A)))` for the HImode assignment, i.e. the
|
||||
* target's `addu $a1,$a0,$zero` in the branch delay slot, with the two `- 0x60`
|
||||
* recomputed from A ($a0, the compare) and B ($a1, the stored value).
|
||||
* An `s32 y` coalesces the pair away and loses that instruction.
|
||||
* - The short local also costs a DEAD 4-byte reload home at the top of the frame
|
||||
* (`(use (mem:SI (plus $sp 48)))` in the greg dump, no insn references it).
|
||||
* That is exactly why the func_8012B0B4 buffer is 8 bytes, not 16: 0x10 + 8
|
||||
* (v10) + 8 (v18) + 8 (sp20) + 4 (dead) rounds to 0x30 = the target's first
|
||||
* saved-register slot. 8 bytes also matches the fleet's canonical shape for a
|
||||
* func_8012B0B4 output buffer (`unsigned int buf[2]`).
|
||||
*/
|
||||
|
||||
|
||||
extern s32 func_8012BC60(void *a0, void *a1);
|
||||
extern s32 func_8012B6D4(s16 *a0, s16 *a1);
|
||||
extern void func_8012B0B4(unsigned int *p, int a1, int a2);
|
||||
extern s32 func_8012CEB0(void *a0, void *a1, s32 a2);
|
||||
extern void func_8012ADE4(u8 *a0);
|
||||
extern void func_8012C098(void *param_1);
|
||||
|
||||
void func_80181490(s32 a0) {
|
||||
|
||||
extern u8 D_801202A0[];
|
||||
u8 *p;
|
||||
s16 *self4;
|
||||
unsigned int *sc;
|
||||
s32 i;
|
||||
s16 y;
|
||||
s32 z;
|
||||
s32 ang;
|
||||
s16 v10[4]; /* sp+0x10 */
|
||||
s16 v18[4]; /* sp+0x18 */
|
||||
s32 sp20[2]; /* sp+0x20 — func_8012B0B4 output */
|
||||
|
||||
p = D_801202A0;
|
||||
i = 0;
|
||||
self4 = (s16 *)(a0 + 4);
|
||||
sc = (unsigned int *)sp20;
|
||||
do {
|
||||
if ((u8 *)a0 != p) {
|
||||
switch (*(u16 *)p) {
|
||||
case 0x27A:
|
||||
if (func_8012BC60((void *)self4, (void *)(p + 4)) < 0x6400) {
|
||||
ang = func_8012B6D4(self4, (s16 *)(p + 4));
|
||||
func_8012B0B4(sc, ang, 0xA1);
|
||||
v18[0] = *(u16 *)(p + 6);
|
||||
v18[1] = *(u16 *)(p + 0xA);
|
||||
v18[2] = *(u16 *)(p + 0xE);
|
||||
v18[0] += sp20[0];
|
||||
v18[2] += sp20[0] >> 16;
|
||||
v18[1] = *(u16 *)(a0 + 0xA);
|
||||
v10[0] = *(u16 *)(a0 + 0x3A);
|
||||
v10[1] = *(u16 *)(a0 + 0x3E);
|
||||
v10[2] = *(u16 *)(a0 + 0x42);
|
||||
if ((func_8012CEB0(v10, v18, 0) & 0x2000) == 0) {
|
||||
func_8012ADE4((u8 *)a0);
|
||||
return;
|
||||
}
|
||||
*(u16 *)(a0 + 6) = v18[0];
|
||||
*(u16 *)(a0 + 0xA) = v18[1];
|
||||
*(u16 *)(a0 + 0xE) = v18[2];
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0x2F4:
|
||||
y = *(s16 *)(p + 0xE);
|
||||
z = *(s16 *)(a0 + 0xE);
|
||||
if (y + 0x10 < z) {
|
||||
func_8012C098((void *)a0);
|
||||
return;
|
||||
}
|
||||
if (y - 0x60 < z) {
|
||||
*(s16 *)(a0 + 0xE) = y - 0x60;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
p += 0x10C;
|
||||
} while (i < 0x60);
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC06_020/nonmatchings/ov_SC06_020_jr_80180B04", func_80181654);
|
||||
|
||||
|
||||
@@ -4408,7 +4408,134 @@ store:
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC06_022/nonmatchings/ov_SC06_022_jr_8017BEBC", func_801853B4);
|
||||
|
||||
/* func_801853B4 — walk the 0x60-entry / 0x10C-stride entity table D_801202A0 and
|
||||
* react to the first neighbour of class 0x27A (get pushed away from it) or 0x2F4
|
||||
* (get clamped down onto it).
|
||||
*
|
||||
* §71 sibling-first: the callee signatures below are copied VERBATIM from this TU's
|
||||
* own already-matched neighbours — func_8012B0B4 (TU L6971/7855/8177), func_8012B6D4
|
||||
* (TU L6419), func_8012CEB0 (TU L7226, the func_80187844 block), func_8012C098
|
||||
* (TU L5379) — and D_801202A0 is the TU's file-scope `extern u8 D_801202A0[];` (L384).
|
||||
* func_8012BC60 / func_8012ADE4 are not declared in this TU; the forms below are the
|
||||
* fleet-majority shapes (func_8012ADE4 verbatim; func_8012BC60 with `void *` instead of
|
||||
* `struct Vec *` so the draft does not depend on engine_types.h being in scope).
|
||||
*
|
||||
* FIVE load-bearing constructs (do NOT "clean up"):
|
||||
*
|
||||
* 1. NO SECOND WALKED POINTER. All of +0x6/+0xA/+0xE are written as `*(T *)(p + k)`
|
||||
* off the single biv `p`. combine_givs then merges the three DEST_ADDR givs onto
|
||||
* ONE anchor = the LAST-emitted one (+0xE, from the case-0x2F4 `lh`), giving the
|
||||
* target's `$s3 = $s2 + 0xE` with -0x8/-0x4/0x0 displacements.
|
||||
* An explicit `q = p + 0xE` with `*(u16 *)q` looks equivalent and is NOT:
|
||||
* gcc-2.7.2 excludes a bare `*q` (mult 1, add 0) from givs (find_mem_givs:4198),
|
||||
* so q stays a live biv AND the remaining two accesses combine onto their own
|
||||
* anchor +0xA => THREE IVs, the wrong anchor, and the $s6 hoist lost to pressure
|
||||
* (measured: 111 ins, 87 mismatched). gcc-2.7.2-map/loop.md §L1 rules 4 & 6.
|
||||
*
|
||||
* 2. `switch`, not `if/else if`. The two-case switch is what emits the target's
|
||||
* compare CHAIN with BOTH arms out of line (`beq`/`beq`/`j default`, 6 slots).
|
||||
* An `if (id == 0x27A) ... else if (id == 0x2F4)` inverts the first test and lets
|
||||
* the 0x27A arm fall through — 2 instructions short.
|
||||
*
|
||||
* 3. do-while with `i++` BEFORE `p += 0x10C`. strength_reduce inserts the reduced
|
||||
* giv's `addiu` immediately before ITS biv's increment, so the source order
|
||||
* i-then-p is what produces `addiu $s4,$s4,1` / `addiu $s3,$s3,0x10C` /
|
||||
* (delay) `addiu $s2,$s2,0x10C`. A `for (i = 0; i < 0x60; i++)` with `p += 0x10C`
|
||||
* last puts the giv add first and swaps the pair.
|
||||
*
|
||||
* 4. `self4` and `sc` are REAL pre-loop locals, in that order. Both are loop
|
||||
* invariants; written inline as `(s16 *)(a0 + 4)` / `(unsigned int *)sp20` at the
|
||||
* call, combine folds the address straight into the argument move
|
||||
* (`addiu $a0,$sp,0x20`) and the target's `$s6 = $sp + 0x20` hoist never happens.
|
||||
* Assigning them in a *different basic block* from their uses is what keeps the
|
||||
* pseudos alive; the declaration ORDER (p, i, self4, sc) is what gives
|
||||
* $s2/$s4/$s5/$s6 in the target's prologue emission order.
|
||||
*
|
||||
* 5. `s16 y` (a SHORT local), and `s32 sp20[2]` (an EIGHT-byte scratch).
|
||||
* - The short local is why `y` gets a second pseudo: gcc-2.7.2 emits
|
||||
* `(set (reg:HI B) (subreg:HI (reg:SI A)))` for the HImode assignment, i.e. the
|
||||
* target's `addu $a1,$a0,$zero` in the branch delay slot, with the two `- 0x60`
|
||||
* recomputed from A ($a0, the compare) and B ($a1, the stored value).
|
||||
* An `s32 y` coalesces the pair away and loses that instruction.
|
||||
* - The short local also costs a DEAD 4-byte reload home at the top of the frame
|
||||
* (`(use (mem:SI (plus $sp 48)))` in the greg dump, no insn references it).
|
||||
* That is exactly why the func_8012B0B4 buffer is 8 bytes, not 16: 0x10 + 8
|
||||
* (v10) + 8 (v18) + 8 (sp20) + 4 (dead) rounds to 0x30 = the target's first
|
||||
* saved-register slot. 8 bytes also matches the fleet's canonical shape for a
|
||||
* func_8012B0B4 output buffer (`unsigned int buf[2]`).
|
||||
*/
|
||||
|
||||
|
||||
extern s32 func_8012BC60(void *a0, void *a1);
|
||||
extern s32 func_8012B6D4(s16 *a0, s16 *a1);
|
||||
extern void func_8012B0B4(unsigned int *p, int a1, int a2);
|
||||
extern s32 func_8012CEB0(void *a0, void *a1, s32 a2);
|
||||
extern void func_8012ADE4(u8 *a0);
|
||||
extern void func_8012C098(void *param_1);
|
||||
|
||||
void func_801853B4(s32 a0) {
|
||||
|
||||
extern u8 D_801202A0[];
|
||||
u8 *p;
|
||||
s16 *self4;
|
||||
unsigned int *sc;
|
||||
s32 i;
|
||||
s16 y;
|
||||
s32 z;
|
||||
s32 ang;
|
||||
s16 v10[4]; /* sp+0x10 */
|
||||
s16 v18[4]; /* sp+0x18 */
|
||||
s32 sp20[2]; /* sp+0x20 — func_8012B0B4 output */
|
||||
|
||||
p = D_801202A0;
|
||||
i = 0;
|
||||
self4 = (s16 *)(a0 + 4);
|
||||
sc = (unsigned int *)sp20;
|
||||
do {
|
||||
if ((u8 *)a0 != p) {
|
||||
switch (*(u16 *)p) {
|
||||
case 0x27A:
|
||||
if (func_8012BC60((void *)self4, (void *)(p + 4)) < 0x6400) {
|
||||
ang = func_8012B6D4(self4, (s16 *)(p + 4));
|
||||
func_8012B0B4(sc, ang, 0xA1);
|
||||
v18[0] = *(u16 *)(p + 6);
|
||||
v18[1] = *(u16 *)(p + 0xA);
|
||||
v18[2] = *(u16 *)(p + 0xE);
|
||||
v18[0] += sp20[0];
|
||||
v18[2] += sp20[0] >> 16;
|
||||
v18[1] = *(u16 *)(a0 + 0xA);
|
||||
v10[0] = *(u16 *)(a0 + 0x3A);
|
||||
v10[1] = *(u16 *)(a0 + 0x3E);
|
||||
v10[2] = *(u16 *)(a0 + 0x42);
|
||||
if ((func_8012CEB0(v10, v18, 0) & 0x2000) == 0) {
|
||||
func_8012ADE4((u8 *)a0);
|
||||
return;
|
||||
}
|
||||
*(u16 *)(a0 + 6) = v18[0];
|
||||
*(u16 *)(a0 + 0xA) = v18[1];
|
||||
*(u16 *)(a0 + 0xE) = v18[2];
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0x2F4:
|
||||
y = *(s16 *)(p + 0xE);
|
||||
z = *(s16 *)(a0 + 0xE);
|
||||
if (y + 0x10 < z) {
|
||||
func_8012C098((void *)a0);
|
||||
return;
|
||||
}
|
||||
if (y - 0x60 < z) {
|
||||
*(s16 *)(a0 + 0xE) = y - 0x60;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
p += 0x10C;
|
||||
} while (i < 0x60);
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC06_022/nonmatchings/ov_SC06_022_jr_8017BEBC", func_80185578);
|
||||
|
||||
@@ -5927,7 +6054,86 @@ void func_80188964(s32 a0)
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC06_022/nonmatchings/ov_SC06_022_jr_8017BEBC", func_80188D68);
|
||||
|
||||
|
||||
// TARGET: func_80188D68 (ov_SC06_008, TU ov_SC06_008_jr_8017C294.c, 93 ins)
|
||||
//
|
||||
// Template: func_801821F8 in this SAME TU (src/ov_SC06_008/ov_SC06_008_jr_8017C294.c,
|
||||
// around line 5283) is an already-MATCHED sibling (126 ins) with a documented byte-exact
|
||||
// idiom set (its comment, verbatim):
|
||||
// @class: plumbing
|
||||
// @stuck: none — MATCH (126 ins). Keys: (1) cVar1 as `int` (not unsigned char) so the
|
||||
// lbu-loaded byte stays full-width and gcc omits the per-compare `andi 0xff`; (2) uninitialized
|
||||
// `int unaff_s1` -> $s1 (live-from-entry across func_8002D4C8); (3) func_8016AA50 takes TWO args
|
||||
// (param_1, unaff_s1) — a1=unaff_s1 arg-setup is reused by the preceding subtraction and a0=s0
|
||||
// hoists into the branch delay slot; (4) 0x76 read UNSIGNED (lhu) in the subtract, SIGNED (lh) in
|
||||
// the `< 1` test.
|
||||
//
|
||||
// func_80188D68 is the SAME body with the leading "if (*(short*)(param_1+0xfc)==0) {...}" block
|
||||
// (the 0x64-indirected 3x int-copy + 3x u16-copy prologue) removed, and the "already fired" gate
|
||||
// field is 0xe2 instead of 0x102. Confirmed against the target .s: no reference anywhere to 0xfc,
|
||||
// 0x64, or 0x102/0x20 offsets; the gate compare is `lh $v1, 0xE2($s0)` / `sh $v1(=0xA), 0xE2($s0)`.
|
||||
|
||||
extern void func_8002D4C8(int, int);
|
||||
extern void func_8016AA50(int, int);
|
||||
extern s32 func_8016B428(s32);
|
||||
extern void func_80019064(void *);
|
||||
extern void func_8002A520(int);
|
||||
extern void func_8002A790(int);
|
||||
extern void func_80131E00(int, int);
|
||||
|
||||
void func_80188D68(int param_1)
|
||||
{
|
||||
extern unsigned char D_801D5A38[];
|
||||
int cVar1;
|
||||
int unaff_s1;
|
||||
|
||||
cVar1 = *(unsigned char *)(param_1 + 0x5e);
|
||||
*(char *)(param_1 + 0xc1) = 0;
|
||||
*(short *)(param_1 + 0x5e) = 0;
|
||||
*(unsigned short *)(param_1 + 0x5c) = *(unsigned short *)(param_1 + 0x5c) & 0xfffe;
|
||||
if (*(short *)(param_1 + 0xe2) == 0) {
|
||||
*(short *)(param_1 + 0xe2) = 10;
|
||||
*(unsigned short *)(param_1 + 0x5c) = *(unsigned short *)(param_1 + 0x5c) | 0x4000;
|
||||
func_8002D4C8(0x9b7, 0);
|
||||
if (*(short *)(param_1 + 0x60) != 0) {
|
||||
if (cVar1 == 0x1d) {
|
||||
*(short *)(param_1 + 0x82) = 0;
|
||||
*(short *)(param_1 + 0x7c) = *(unsigned short *)(param_1 + 6);
|
||||
*(short *)(param_1 + 0x7e) = *(unsigned short *)(param_1 + 0xa);
|
||||
*(short *)(param_1 + 0x80) = *(unsigned short *)(param_1 + 0xe);
|
||||
}
|
||||
if (*(int *)(param_1 + 0x78) != 0) {
|
||||
unaff_s1 = (int)*(short *)(param_1 + 0x60) *
|
||||
(int)*(short *)(*(int *)(param_1 + 0x78) + 0x30) >> 0xc;
|
||||
if (unaff_s1 < 1) {
|
||||
unaff_s1 = 1;
|
||||
}
|
||||
}
|
||||
*(unsigned short *)(param_1 + 0x76) =
|
||||
*(unsigned short *)(param_1 + 0x76) - unaff_s1;
|
||||
func_8016AA50(param_1, unaff_s1);
|
||||
if ((*(unsigned short *)(param_1 + 0x82) & 1) != 0) {
|
||||
((void (*)(int))func_8016B428)(param_1);
|
||||
func_80019064(D_801D5A38);
|
||||
}
|
||||
}
|
||||
if (cVar1 != 0x1d) {
|
||||
if (*(unsigned char *)(param_1 + 0xc8) != 0) {
|
||||
func_8002A520(param_1);
|
||||
}
|
||||
if (*(unsigned char *)(param_1 + 0xc9) != 0) {
|
||||
func_8002A790(param_1);
|
||||
}
|
||||
}
|
||||
if (*(short *)(param_1 + 0x76) < 1) {
|
||||
*(short *)(param_1 + 0x5c) = 0;
|
||||
func_80131E00(param_1, 6);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// @class: schedule
|
||||
@@ -7396,7 +7602,152 @@ void aF8017ED80(void *param_1) {
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC06_022/nonmatchings/ov_SC06_022_jr_8017BEBC", func_8018BBBC);
|
||||
|
||||
/* func_8018BBBC -- ov_SC06_008, TU ov_SC06_008_jr_8017C294.c (open-only h_norm
|
||||
* cluster exemplar, 7 members).
|
||||
*
|
||||
* a0+0x0 : u16 active flag; 0 => early return.
|
||||
* a0+0x84 : s16 sound cooldown timer.
|
||||
* cooldown != 0 -> just decrement it.
|
||||
* cooldown == 0 -> try to play a positional sound (RotTransPers screen
|
||||
* projection of the parent's position, range-gated on
|
||||
* screen X/Y, volume from the classic div-by-0xF0 /
|
||||
* div-by-0x1E magic-constant idiom -- byte-proven sibling
|
||||
* form is func_80181CF0 in this same TU, sndid 0x849 here
|
||||
* vs 0x961 there), then unconditionally reset the timer
|
||||
* to 0xA regardless of whether the sound actually played.
|
||||
* a0+0xFC / 0xFE : running hit-combo accumulators, bumped by +/-0x280 every
|
||||
* call (unconditional tail).
|
||||
* Tail always calls ((void (*)(void *))func_8018B9E8)(a0) (the TU's canonical decl for this
|
||||
* symbol is void(void) -- S35 self-axis -- so this draft binds its own
|
||||
* private extern with the asm's real void(void*) shape).
|
||||
*
|
||||
* Control flow is EXPLICIT goto/label, mirroring source-order block
|
||||
* placement (gcc-2.7.2 lays out basic blocks in literal source order, not by
|
||||
* fallthrough preference -- see the func_80181CF0 comment, same TU): the
|
||||
* cooldown!=0 decrement is the SHORT block and sits out-of-line (jumped to),
|
||||
* the cooldown==0 RTP+sound block is the LONG block and sits inline
|
||||
* (fallthrough), matching the target's physical layout exactly.
|
||||
*
|
||||
* MATCH levers (byte-proven, 2026-08-05):
|
||||
* 1. Naive `if(old!=0){cool=old-1;}else{...}` folds trivially: reorg.c's
|
||||
* delay-slot filler steals the single-insn decrement into the `bnez`'s
|
||||
* own delay slot and retargets the branch straight to the join label
|
||||
* (2 ins short of target). The target instead keeps a genuine copy
|
||||
* (`addu $v1,$v0,zero`) in the delay slot and a SEPARATE `addiu $v0,$v1,-1`
|
||||
* at the decrement site. Reproduced by pinning a second variable
|
||||
* `register s32 v1 __asm__("$3")`, assigned UNCONDITIONALLY right after
|
||||
* the load (`v1 = old;`) -- the scheduler places that copy in the
|
||||
* branch's delay slot on its own, and the decrement (`cool = v1 - 1`)
|
||||
* can no longer be folded away. `cool` is separately pinned to
|
||||
* `__asm__("$2")` so its other def sites (the three `cool = 0xA` early
|
||||
* exits) don't drift onto $3 by coalescing with v1.
|
||||
* 2. The tail's `sh $v0,0x84($s0)` / `addu $a0,$s0,zero` order (store off
|
||||
* the callee-saved pointer BEFORE reloading it into the call-argument
|
||||
* register) needed a `__asm__ __volatile__("":::"memory")` fence right
|
||||
* after the store -- without it, sched1 hoists the independent a0-reload
|
||||
* ahead of the store even when the reload is written later in source.
|
||||
* 3. Frame is -0x38, 8 bytes (2 words) larger than the natural -0x30 the
|
||||
* locals alone produce; `pad2[2]` (dead, address never read) inside `L`
|
||||
* reserves them, mirroring func_80181CF0's own "dead aggregate sizes the
|
||||
* frame" idiom.
|
||||
*/
|
||||
|
||||
|
||||
/* §37/§124 def-side asm-label alias (P30 S1d class lever): the TU declares
|
||||
* `extern void func_8018BBBC(void);` (L4082, L4091) for callers that invoke it with NO args,
|
||||
* while the byte-true definition takes an s32 in $a0 -> `conflicting types`. Neither side can
|
||||
* move (a no-prototype escape is illegal once a param promotes), so the DEFINITION gets a
|
||||
* private C identifier and binds the emitted symbol with a GNU asm label. Zero blast radius:
|
||||
* the TU's declaration never meets the definition, and the emitted symbol is unchanged. */
|
||||
void aF8017EF54(s32 a0) __asm__("func_8018BBBC");
|
||||
|
||||
void aF8017EF54(s32 a0)
|
||||
{
|
||||
extern void func_8004914C(void *a0);
|
||||
extern void func_800491AC(void *a0);
|
||||
extern void func_8002D4C8(s32 a0, s32 a1);
|
||||
extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3);
|
||||
extern u8 D_800AF648;
|
||||
extern void func_8018B9E8(void);
|
||||
struct {
|
||||
s16 v[3]; /* sp+0x10 */
|
||||
s16 pad1; /* sp+0x16 */
|
||||
u16 sxy[2]; /* sp+0x18 */
|
||||
s32 z; /* sp+0x1C */
|
||||
s32 flag; /* sp+0x20 */
|
||||
s32 pad2[2]; /* sp+0x24 -- dead, sizes the frame */
|
||||
} L;
|
||||
|
||||
register s32 v1 __asm__("$3");
|
||||
register s32 cool __asm__("$2");
|
||||
s32 old;
|
||||
|
||||
if (*(u16 *)(a0 + 0x0) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
old = *(s16 *)(a0 + 0x84);
|
||||
v1 = old;
|
||||
if (old != 0) {
|
||||
goto L_dec;
|
||||
}
|
||||
|
||||
L.v[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48);
|
||||
L.v[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C);
|
||||
L.v[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50);
|
||||
{ register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); }
|
||||
{ register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); }
|
||||
RotTransPers((s32)L.v, (s32)L.sxy, &L.z, &L.flag);
|
||||
|
||||
if (L.flag < 0) {
|
||||
cool = 0xA;
|
||||
goto L_join;
|
||||
}
|
||||
if ((u32)((L.sxy[0] + 0xEF) & 0xFFFF) >= 0x1DF) {
|
||||
cool = 0xA;
|
||||
goto L_join;
|
||||
}
|
||||
if ((u32)((L.sxy[1] + 0xB3) & 0xFFFF) >= 0x167) {
|
||||
goto L_snd_skip;
|
||||
}
|
||||
|
||||
{
|
||||
s32 sx = (s16)L.sxy[0];
|
||||
s32 av;
|
||||
|
||||
av = sx;
|
||||
if (sx < 0) {
|
||||
av = -sx;
|
||||
}
|
||||
av = ((0xF0 - av) * 0x7F) / 0xF0;
|
||||
sx = (sx + 0xF0) / 0x1E;
|
||||
if (sx == 0x10) {
|
||||
sx = 0xF;
|
||||
}
|
||||
sx = sx << 8;
|
||||
func_8002D4C8(0x849, (av | (0x3000 | sx)) & 0xFFFF);
|
||||
}
|
||||
|
||||
L_snd_skip:
|
||||
cool = 0xA;
|
||||
goto L_join;
|
||||
|
||||
L_dec:
|
||||
cool = v1 - 1;
|
||||
|
||||
L_join:
|
||||
*(s16 *)(a0 + 0x84) = cool;
|
||||
__asm__ __volatile__("" ::: "memory");
|
||||
|
||||
{
|
||||
s32 p = a0;
|
||||
*(u16 *)(p + 0xFC) = *(u16 *)(p + 0xFC) + 0x280;
|
||||
*(u16 *)(p + 0xFE) = *(u16 *)(p + 0xFE) - 0x280;
|
||||
((void (*)(void *))func_8018B9E8)((void *)p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern s32 rand(void);
|
||||
@@ -7736,7 +8087,97 @@ void func_8018C73C(void *a0) {
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC06_022/nonmatchings/ov_SC06_022_jr_8017BEBC", func_8018C778);
|
||||
|
||||
/* SV4 is the TU-canonical name (src/shared/engine_types.h) for func_8012F214's
|
||||
* in/out struct (see ov_SC06_008_jr_8017AE2C.c:3135, "SV4 svec" comment: func_8012F214 out).
|
||||
* Isolated match_one has no include path to that header, so it is typedef'd
|
||||
* locally here for the standalone compile only. */
|
||||
|
||||
|
||||
/* func_8018C778 - ov_SC06_008 / ov_SC06_008_jr_8017C294 (93 ins)
|
||||
*
|
||||
* One-time init (guarded by state flag at +0x34): mirror the +0x64 sub-object's
|
||||
* +0x20/+0x12 field into our own +0x20 sub-object, kick off two "core" calls,
|
||||
* pick an entry from the 2-element 12-byte table D_801DD6BC (indexed by the
|
||||
* s16 at +0x70), then call func_8012F214 with a zeroed input SV4 and read the
|
||||
* first 3 fields of the output SV4 back into +6/+0xA/+0xE. Sets the countdown
|
||||
* at +0x1c to 0x5a and marks the state flag +0x34 = 1.
|
||||
*
|
||||
* Always-executed tail: bump the +0x20 sub-object's +0x10/+0x12/+0x14 fields
|
||||
* (reloading the +0x20 pointer fresh for each field -- no CSE across the
|
||||
* intervening stores, straight literal translation), mirror +0x14 into +0xDC,
|
||||
* call func_8012CBCC(a0) and test its return (canonical fleet decl is
|
||||
* void func_8012CBCC(s32 a0); the return value is read via a function-
|
||||
* pointer cast at the use site, per the established TU idiom -- see
|
||||
* ov_SC03_099_jr_8017BEBC.c:5630 comment block). If (ret & 0x6000), decrement
|
||||
* the +0xac counter (signed s16 compare-to-zero on the POST-decrement value --
|
||||
* gcc-2.7.2's sll-by-16/bnez idiom for a s16 local) and negate +0xDC into
|
||||
* +0x14; on the counter hitting zero, call func_8012C218. Finally decrement
|
||||
* the +0x1c countdown and call func_8012C218 again when IT hits zero.
|
||||
*/
|
||||
|
||||
extern void func_8012B2CC(s32 a0);
|
||||
extern void func_8012B23C(s32 a0);
|
||||
extern void func_8012B14C(s32 a0, s32 a1);
|
||||
extern void func_8012F214(s32 a0, s32 a1, s32 a2);
|
||||
extern void func_8012CBCC(s32 a0);
|
||||
extern void func_8012C218(void *a0);
|
||||
|
||||
|
||||
void func_8018C778(s32 a0)
|
||||
{
|
||||
|
||||
extern s32 D_801DD6BC;
|
||||
SV4 in;
|
||||
SV4 out;
|
||||
s16 v1;
|
||||
u16 uStack_c;
|
||||
|
||||
if (*(u16 *)(a0 + 0x34) == 0) {
|
||||
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) =
|
||||
*(u16 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x12);
|
||||
func_8012B2CC(a0);
|
||||
func_8012B23C(a0);
|
||||
func_8012B14C(a0, *(s16 *)(a0 + 0x70) * 12 + (s32)&D_801DD6BC);
|
||||
|
||||
in.a = 0;
|
||||
in.b = 0;
|
||||
in.c = 0x10;
|
||||
func_8012F214(a0, (s32)&in, (s32)&out);
|
||||
*(u16 *)(a0 + 6) = out.a;
|
||||
*(u16 *)(a0 + 0xa) = out.b;
|
||||
uStack_c = out.c;
|
||||
*(s32 *)(a0 + 0x1c) = 0x5a;
|
||||
*(u16 *)(a0 + 0x34) = 1;
|
||||
*(u16 *)(a0 + 0xe) = uStack_c;
|
||||
}
|
||||
|
||||
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) += -0x80;
|
||||
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) += 4;
|
||||
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x14) += *(u16 *)(a0 + 0xfc);
|
||||
|
||||
*(s32 *)(a0 + 0xdc) = *(s32 *)(a0 + 0x14);
|
||||
if ((((s32 (*)(s32))func_8012CBCC)(a0)) & 0x6000) {
|
||||
register s32 negdc __asm__("$2");
|
||||
negdc = -*(s32 *)(a0 + 0xdc);
|
||||
v1 = *(u16 *)(a0 + 0xac);
|
||||
v1 -= 1;
|
||||
*(s16 *)(a0 + 0xac) = v1;
|
||||
*(s32 *)(a0 + 0x14) = negdc;
|
||||
if (v1 == 0) {
|
||||
func_8012C218((void *)a0);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
s32 iVar3 = *(s32 *)(a0 + 0x1c) - 1;
|
||||
*(s32 *)(a0 + 0x1c) = iVar3;
|
||||
if (iVar3 == 0) {
|
||||
func_8012C218((void *)a0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern void (*D_801DD6D4[])(void);
|
||||
|
||||
@@ -5055,7 +5055,134 @@ store:
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC06_024/nonmatchings/ov_SC06_024_jr_8017BEBC", func_8018788C);
|
||||
|
||||
/* func_8018788C — walk the 0x60-entry / 0x10C-stride entity table D_801202A0 and
|
||||
* react to the first neighbour of class 0x27A (get pushed away from it) or 0x2F4
|
||||
* (get clamped down onto it).
|
||||
*
|
||||
* §71 sibling-first: the callee signatures below are copied VERBATIM from this TU's
|
||||
* own already-matched neighbours — func_8012B0B4 (TU L6971/7855/8177), func_8012B6D4
|
||||
* (TU L6419), func_8012CEB0 (TU L7226, the func_80187844 block), func_8012C098
|
||||
* (TU L5379) — and D_801202A0 is the TU's file-scope `extern u8 D_801202A0[];` (L384).
|
||||
* func_8012BC60 / func_8012ADE4 are not declared in this TU; the forms below are the
|
||||
* fleet-majority shapes (func_8012ADE4 verbatim; func_8012BC60 with `void *` instead of
|
||||
* `struct Vec *` so the draft does not depend on engine_types.h being in scope).
|
||||
*
|
||||
* FIVE load-bearing constructs (do NOT "clean up"):
|
||||
*
|
||||
* 1. NO SECOND WALKED POINTER. All of +0x6/+0xA/+0xE are written as `*(T *)(p + k)`
|
||||
* off the single biv `p`. combine_givs then merges the three DEST_ADDR givs onto
|
||||
* ONE anchor = the LAST-emitted one (+0xE, from the case-0x2F4 `lh`), giving the
|
||||
* target's `$s3 = $s2 + 0xE` with -0x8/-0x4/0x0 displacements.
|
||||
* An explicit `q = p + 0xE` with `*(u16 *)q` looks equivalent and is NOT:
|
||||
* gcc-2.7.2 excludes a bare `*q` (mult 1, add 0) from givs (find_mem_givs:4198),
|
||||
* so q stays a live biv AND the remaining two accesses combine onto their own
|
||||
* anchor +0xA => THREE IVs, the wrong anchor, and the $s6 hoist lost to pressure
|
||||
* (measured: 111 ins, 87 mismatched). gcc-2.7.2-map/loop.md §L1 rules 4 & 6.
|
||||
*
|
||||
* 2. `switch`, not `if/else if`. The two-case switch is what emits the target's
|
||||
* compare CHAIN with BOTH arms out of line (`beq`/`beq`/`j default`, 6 slots).
|
||||
* An `if (id == 0x27A) ... else if (id == 0x2F4)` inverts the first test and lets
|
||||
* the 0x27A arm fall through — 2 instructions short.
|
||||
*
|
||||
* 3. do-while with `i++` BEFORE `p += 0x10C`. strength_reduce inserts the reduced
|
||||
* giv's `addiu` immediately before ITS biv's increment, so the source order
|
||||
* i-then-p is what produces `addiu $s4,$s4,1` / `addiu $s3,$s3,0x10C` /
|
||||
* (delay) `addiu $s2,$s2,0x10C`. A `for (i = 0; i < 0x60; i++)` with `p += 0x10C`
|
||||
* last puts the giv add first and swaps the pair.
|
||||
*
|
||||
* 4. `self4` and `sc` are REAL pre-loop locals, in that order. Both are loop
|
||||
* invariants; written inline as `(s16 *)(a0 + 4)` / `(unsigned int *)sp20` at the
|
||||
* call, combine folds the address straight into the argument move
|
||||
* (`addiu $a0,$sp,0x20`) and the target's `$s6 = $sp + 0x20` hoist never happens.
|
||||
* Assigning them in a *different basic block* from their uses is what keeps the
|
||||
* pseudos alive; the declaration ORDER (p, i, self4, sc) is what gives
|
||||
* $s2/$s4/$s5/$s6 in the target's prologue emission order.
|
||||
*
|
||||
* 5. `s16 y` (a SHORT local), and `s32 sp20[2]` (an EIGHT-byte scratch).
|
||||
* - The short local is why `y` gets a second pseudo: gcc-2.7.2 emits
|
||||
* `(set (reg:HI B) (subreg:HI (reg:SI A)))` for the HImode assignment, i.e. the
|
||||
* target's `addu $a1,$a0,$zero` in the branch delay slot, with the two `- 0x60`
|
||||
* recomputed from A ($a0, the compare) and B ($a1, the stored value).
|
||||
* An `s32 y` coalesces the pair away and loses that instruction.
|
||||
* - The short local also costs a DEAD 4-byte reload home at the top of the frame
|
||||
* (`(use (mem:SI (plus $sp 48)))` in the greg dump, no insn references it).
|
||||
* That is exactly why the func_8012B0B4 buffer is 8 bytes, not 16: 0x10 + 8
|
||||
* (v10) + 8 (v18) + 8 (sp20) + 4 (dead) rounds to 0x30 = the target's first
|
||||
* saved-register slot. 8 bytes also matches the fleet's canonical shape for a
|
||||
* func_8012B0B4 output buffer (`unsigned int buf[2]`).
|
||||
*/
|
||||
|
||||
|
||||
extern s32 func_8012BC60(void *a0, void *a1);
|
||||
extern s32 func_8012B6D4(s16 *a0, s16 *a1);
|
||||
extern void func_8012B0B4(unsigned int *p, int a1, int a2);
|
||||
extern s32 func_8012CEB0(void *a0, void *a1, s32 a2);
|
||||
extern void func_8012ADE4(u8 *a0);
|
||||
extern void func_8012C098(void *param_1);
|
||||
|
||||
void func_8018788C(s32 a0) {
|
||||
|
||||
extern u8 D_801202A0[];
|
||||
u8 *p;
|
||||
s16 *self4;
|
||||
unsigned int *sc;
|
||||
s32 i;
|
||||
s16 y;
|
||||
s32 z;
|
||||
s32 ang;
|
||||
s16 v10[4]; /* sp+0x10 */
|
||||
s16 v18[4]; /* sp+0x18 */
|
||||
s32 sp20[2]; /* sp+0x20 — func_8012B0B4 output */
|
||||
|
||||
p = D_801202A0;
|
||||
i = 0;
|
||||
self4 = (s16 *)(a0 + 4);
|
||||
sc = (unsigned int *)sp20;
|
||||
do {
|
||||
if ((u8 *)a0 != p) {
|
||||
switch (*(u16 *)p) {
|
||||
case 0x27A:
|
||||
if (func_8012BC60((void *)self4, (void *)(p + 4)) < 0x6400) {
|
||||
ang = func_8012B6D4(self4, (s16 *)(p + 4));
|
||||
func_8012B0B4(sc, ang, 0xA1);
|
||||
v18[0] = *(u16 *)(p + 6);
|
||||
v18[1] = *(u16 *)(p + 0xA);
|
||||
v18[2] = *(u16 *)(p + 0xE);
|
||||
v18[0] += sp20[0];
|
||||
v18[2] += sp20[0] >> 16;
|
||||
v18[1] = *(u16 *)(a0 + 0xA);
|
||||
v10[0] = *(u16 *)(a0 + 0x3A);
|
||||
v10[1] = *(u16 *)(a0 + 0x3E);
|
||||
v10[2] = *(u16 *)(a0 + 0x42);
|
||||
if ((func_8012CEB0(v10, v18, 0) & 0x2000) == 0) {
|
||||
func_8012ADE4((u8 *)a0);
|
||||
return;
|
||||
}
|
||||
*(u16 *)(a0 + 6) = v18[0];
|
||||
*(u16 *)(a0 + 0xA) = v18[1];
|
||||
*(u16 *)(a0 + 0xE) = v18[2];
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0x2F4:
|
||||
y = *(s16 *)(p + 0xE);
|
||||
z = *(s16 *)(a0 + 0xE);
|
||||
if (y + 0x10 < z) {
|
||||
func_8012C098((void *)a0);
|
||||
return;
|
||||
}
|
||||
if (y - 0x60 < z) {
|
||||
*(s16 *)(a0 + 0xE) = y - 0x60;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
p += 0x10C;
|
||||
} while (i < 0x60);
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC06_024/nonmatchings/ov_SC06_024_jr_8017BEBC", func_80187A50);
|
||||
|
||||
@@ -6572,7 +6699,86 @@ void func_8018AE3C(s32 a0)
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC06_024/nonmatchings/ov_SC06_024_jr_8017BEBC", func_8018B240);
|
||||
|
||||
|
||||
// TARGET: func_8018B240 (ov_SC06_008, TU ov_SC06_008_jr_8017C294.c, 93 ins)
|
||||
//
|
||||
// Template: func_801821F8 in this SAME TU (src/ov_SC06_008/ov_SC06_008_jr_8017C294.c,
|
||||
// around line 5283) is an already-MATCHED sibling (126 ins) with a documented byte-exact
|
||||
// idiom set (its comment, verbatim):
|
||||
// @class: plumbing
|
||||
// @stuck: none — MATCH (126 ins). Keys: (1) cVar1 as `int` (not unsigned char) so the
|
||||
// lbu-loaded byte stays full-width and gcc omits the per-compare `andi 0xff`; (2) uninitialized
|
||||
// `int unaff_s1` -> $s1 (live-from-entry across func_8002D4C8); (3) func_8016AA50 takes TWO args
|
||||
// (param_1, unaff_s1) — a1=unaff_s1 arg-setup is reused by the preceding subtraction and a0=s0
|
||||
// hoists into the branch delay slot; (4) 0x76 read UNSIGNED (lhu) in the subtract, SIGNED (lh) in
|
||||
// the `< 1` test.
|
||||
//
|
||||
// func_8018B240 is the SAME body with the leading "if (*(short*)(param_1+0xfc)==0) {...}" block
|
||||
// (the 0x64-indirected 3x int-copy + 3x u16-copy prologue) removed, and the "already fired" gate
|
||||
// field is 0xe2 instead of 0x102. Confirmed against the target .s: no reference anywhere to 0xfc,
|
||||
// 0x64, or 0x102/0x20 offsets; the gate compare is `lh $v1, 0xE2($s0)` / `sh $v1(=0xA), 0xE2($s0)`.
|
||||
|
||||
extern void func_8002D4C8(int, int);
|
||||
extern void func_8016AA50(int, int);
|
||||
extern s32 func_8016B428(s32);
|
||||
extern void func_80019064(void *);
|
||||
extern void func_8002A520(int);
|
||||
extern void func_8002A790(int);
|
||||
extern void func_80131E00(int, int);
|
||||
|
||||
void func_8018B240(int param_1)
|
||||
{
|
||||
extern unsigned char D_801D4B7C[];
|
||||
int cVar1;
|
||||
int unaff_s1;
|
||||
|
||||
cVar1 = *(unsigned char *)(param_1 + 0x5e);
|
||||
*(char *)(param_1 + 0xc1) = 0;
|
||||
*(short *)(param_1 + 0x5e) = 0;
|
||||
*(unsigned short *)(param_1 + 0x5c) = *(unsigned short *)(param_1 + 0x5c) & 0xfffe;
|
||||
if (*(short *)(param_1 + 0xe2) == 0) {
|
||||
*(short *)(param_1 + 0xe2) = 10;
|
||||
*(unsigned short *)(param_1 + 0x5c) = *(unsigned short *)(param_1 + 0x5c) | 0x4000;
|
||||
func_8002D4C8(0x9b7, 0);
|
||||
if (*(short *)(param_1 + 0x60) != 0) {
|
||||
if (cVar1 == 0x1d) {
|
||||
*(short *)(param_1 + 0x82) = 0;
|
||||
*(short *)(param_1 + 0x7c) = *(unsigned short *)(param_1 + 6);
|
||||
*(short *)(param_1 + 0x7e) = *(unsigned short *)(param_1 + 0xa);
|
||||
*(short *)(param_1 + 0x80) = *(unsigned short *)(param_1 + 0xe);
|
||||
}
|
||||
if (*(int *)(param_1 + 0x78) != 0) {
|
||||
unaff_s1 = (int)*(short *)(param_1 + 0x60) *
|
||||
(int)*(short *)(*(int *)(param_1 + 0x78) + 0x30) >> 0xc;
|
||||
if (unaff_s1 < 1) {
|
||||
unaff_s1 = 1;
|
||||
}
|
||||
}
|
||||
*(unsigned short *)(param_1 + 0x76) =
|
||||
*(unsigned short *)(param_1 + 0x76) - unaff_s1;
|
||||
func_8016AA50(param_1, unaff_s1);
|
||||
if ((*(unsigned short *)(param_1 + 0x82) & 1) != 0) {
|
||||
((void (*)(int))func_8016B428)(param_1);
|
||||
func_80019064(D_801D4B7C);
|
||||
}
|
||||
}
|
||||
if (cVar1 != 0x1d) {
|
||||
if (*(unsigned char *)(param_1 + 0xc8) != 0) {
|
||||
func_8002A520(param_1);
|
||||
}
|
||||
if (*(unsigned char *)(param_1 + 0xc9) != 0) {
|
||||
func_8002A790(param_1);
|
||||
}
|
||||
}
|
||||
if (*(short *)(param_1 + 0x76) < 1) {
|
||||
*(short *)(param_1 + 0x5c) = 0;
|
||||
func_80131E00(param_1, 6);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// @class: schedule
|
||||
@@ -8038,7 +8244,152 @@ void aF8017ED80(void *param_1) {
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC06_024/nonmatchings/ov_SC06_024_jr_8017BEBC", func_8018E094);
|
||||
|
||||
/* func_8018E094 -- ov_SC06_008, TU ov_SC06_008_jr_8017C294.c (open-only h_norm
|
||||
* cluster exemplar, 7 members).
|
||||
*
|
||||
* a0+0x0 : u16 active flag; 0 => early return.
|
||||
* a0+0x84 : s16 sound cooldown timer.
|
||||
* cooldown != 0 -> just decrement it.
|
||||
* cooldown == 0 -> try to play a positional sound (RotTransPers screen
|
||||
* projection of the parent's position, range-gated on
|
||||
* screen X/Y, volume from the classic div-by-0xF0 /
|
||||
* div-by-0x1E magic-constant idiom -- byte-proven sibling
|
||||
* form is func_80181CF0 in this same TU, sndid 0x849 here
|
||||
* vs 0x961 there), then unconditionally reset the timer
|
||||
* to 0xA regardless of whether the sound actually played.
|
||||
* a0+0xFC / 0xFE : running hit-combo accumulators, bumped by +/-0x280 every
|
||||
* call (unconditional tail).
|
||||
* Tail always calls ((void (*)(void *))func_8018DEC0)(a0) (the TU's canonical decl for this
|
||||
* symbol is void(void) -- S35 self-axis -- so this draft binds its own
|
||||
* private extern with the asm's real void(void*) shape).
|
||||
*
|
||||
* Control flow is EXPLICIT goto/label, mirroring source-order block
|
||||
* placement (gcc-2.7.2 lays out basic blocks in literal source order, not by
|
||||
* fallthrough preference -- see the func_80181CF0 comment, same TU): the
|
||||
* cooldown!=0 decrement is the SHORT block and sits out-of-line (jumped to),
|
||||
* the cooldown==0 RTP+sound block is the LONG block and sits inline
|
||||
* (fallthrough), matching the target's physical layout exactly.
|
||||
*
|
||||
* MATCH levers (byte-proven, 2026-08-05):
|
||||
* 1. Naive `if(old!=0){cool=old-1;}else{...}` folds trivially: reorg.c's
|
||||
* delay-slot filler steals the single-insn decrement into the `bnez`'s
|
||||
* own delay slot and retargets the branch straight to the join label
|
||||
* (2 ins short of target). The target instead keeps a genuine copy
|
||||
* (`addu $v1,$v0,zero`) in the delay slot and a SEPARATE `addiu $v0,$v1,-1`
|
||||
* at the decrement site. Reproduced by pinning a second variable
|
||||
* `register s32 v1 __asm__("$3")`, assigned UNCONDITIONALLY right after
|
||||
* the load (`v1 = old;`) -- the scheduler places that copy in the
|
||||
* branch's delay slot on its own, and the decrement (`cool = v1 - 1`)
|
||||
* can no longer be folded away. `cool` is separately pinned to
|
||||
* `__asm__("$2")` so its other def sites (the three `cool = 0xA` early
|
||||
* exits) don't drift onto $3 by coalescing with v1.
|
||||
* 2. The tail's `sh $v0,0x84($s0)` / `addu $a0,$s0,zero` order (store off
|
||||
* the callee-saved pointer BEFORE reloading it into the call-argument
|
||||
* register) needed a `__asm__ __volatile__("":::"memory")` fence right
|
||||
* after the store -- without it, sched1 hoists the independent a0-reload
|
||||
* ahead of the store even when the reload is written later in source.
|
||||
* 3. Frame is -0x38, 8 bytes (2 words) larger than the natural -0x30 the
|
||||
* locals alone produce; `pad2[2]` (dead, address never read) inside `L`
|
||||
* reserves them, mirroring func_80181CF0's own "dead aggregate sizes the
|
||||
* frame" idiom.
|
||||
*/
|
||||
|
||||
|
||||
/* §37/§124 def-side asm-label alias (P30 S1d class lever): the TU declares
|
||||
* `extern void func_8018E094(void);` (L4082, L4091) for callers that invoke it with NO args,
|
||||
* while the byte-true definition takes an s32 in $a0 -> `conflicting types`. Neither side can
|
||||
* move (a no-prototype escape is illegal once a param promotes), so the DEFINITION gets a
|
||||
* private C identifier and binds the emitted symbol with a GNU asm label. Zero blast radius:
|
||||
* the TU's declaration never meets the definition, and the emitted symbol is unchanged. */
|
||||
void aF8017EF54(s32 a0) __asm__("func_8018E094");
|
||||
|
||||
void aF8017EF54(s32 a0)
|
||||
{
|
||||
extern void func_8004914C(void *a0);
|
||||
extern void func_800491AC(void *a0);
|
||||
extern void func_8002D4C8(s32 a0, s32 a1);
|
||||
extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3);
|
||||
extern u8 D_800AF648;
|
||||
extern void func_8018DEC0(void);
|
||||
struct {
|
||||
s16 v[3]; /* sp+0x10 */
|
||||
s16 pad1; /* sp+0x16 */
|
||||
u16 sxy[2]; /* sp+0x18 */
|
||||
s32 z; /* sp+0x1C */
|
||||
s32 flag; /* sp+0x20 */
|
||||
s32 pad2[2]; /* sp+0x24 -- dead, sizes the frame */
|
||||
} L;
|
||||
|
||||
register s32 v1 __asm__("$3");
|
||||
register s32 cool __asm__("$2");
|
||||
s32 old;
|
||||
|
||||
if (*(u16 *)(a0 + 0x0) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
old = *(s16 *)(a0 + 0x84);
|
||||
v1 = old;
|
||||
if (old != 0) {
|
||||
goto L_dec;
|
||||
}
|
||||
|
||||
L.v[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48);
|
||||
L.v[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C);
|
||||
L.v[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50);
|
||||
{ register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); }
|
||||
{ register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); }
|
||||
RotTransPers((s32)L.v, (s32)L.sxy, &L.z, &L.flag);
|
||||
|
||||
if (L.flag < 0) {
|
||||
cool = 0xA;
|
||||
goto L_join;
|
||||
}
|
||||
if ((u32)((L.sxy[0] + 0xEF) & 0xFFFF) >= 0x1DF) {
|
||||
cool = 0xA;
|
||||
goto L_join;
|
||||
}
|
||||
if ((u32)((L.sxy[1] + 0xB3) & 0xFFFF) >= 0x167) {
|
||||
goto L_snd_skip;
|
||||
}
|
||||
|
||||
{
|
||||
s32 sx = (s16)L.sxy[0];
|
||||
s32 av;
|
||||
|
||||
av = sx;
|
||||
if (sx < 0) {
|
||||
av = -sx;
|
||||
}
|
||||
av = ((0xF0 - av) * 0x7F) / 0xF0;
|
||||
sx = (sx + 0xF0) / 0x1E;
|
||||
if (sx == 0x10) {
|
||||
sx = 0xF;
|
||||
}
|
||||
sx = sx << 8;
|
||||
func_8002D4C8(0x849, (av | (0x3000 | sx)) & 0xFFFF);
|
||||
}
|
||||
|
||||
L_snd_skip:
|
||||
cool = 0xA;
|
||||
goto L_join;
|
||||
|
||||
L_dec:
|
||||
cool = v1 - 1;
|
||||
|
||||
L_join:
|
||||
*(s16 *)(a0 + 0x84) = cool;
|
||||
__asm__ __volatile__("" ::: "memory");
|
||||
|
||||
{
|
||||
s32 p = a0;
|
||||
*(u16 *)(p + 0xFC) = *(u16 *)(p + 0xFC) + 0x280;
|
||||
*(u16 *)(p + 0xFE) = *(u16 *)(p + 0xFE) - 0x280;
|
||||
((void (*)(void *))func_8018DEC0)((void *)p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern s32 rand(void);
|
||||
@@ -8378,7 +8729,97 @@ void func_8018EC14(void *a0) {
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC06_024/nonmatchings/ov_SC06_024_jr_8017BEBC", func_8018EC50);
|
||||
|
||||
/* SV4 is the TU-canonical name (src/shared/engine_types.h) for func_8012F214's
|
||||
* in/out struct (see ov_SC06_008_jr_8017AE2C.c:3135, "SV4 svec" comment: func_8012F214 out).
|
||||
* Isolated match_one has no include path to that header, so it is typedef'd
|
||||
* locally here for the standalone compile only. */
|
||||
|
||||
|
||||
/* func_8018EC50 - ov_SC06_008 / ov_SC06_008_jr_8017C294 (93 ins)
|
||||
*
|
||||
* One-time init (guarded by state flag at +0x34): mirror the +0x64 sub-object's
|
||||
* +0x20/+0x12 field into our own +0x20 sub-object, kick off two "core" calls,
|
||||
* pick an entry from the 2-element 12-byte table D_801DC800 (indexed by the
|
||||
* s16 at +0x70), then call func_8012F214 with a zeroed input SV4 and read the
|
||||
* first 3 fields of the output SV4 back into +6/+0xA/+0xE. Sets the countdown
|
||||
* at +0x1c to 0x5a and marks the state flag +0x34 = 1.
|
||||
*
|
||||
* Always-executed tail: bump the +0x20 sub-object's +0x10/+0x12/+0x14 fields
|
||||
* (reloading the +0x20 pointer fresh for each field -- no CSE across the
|
||||
* intervening stores, straight literal translation), mirror +0x14 into +0xDC,
|
||||
* call func_8012CBCC(a0) and test its return (canonical fleet decl is
|
||||
* void func_8012CBCC(s32 a0); the return value is read via a function-
|
||||
* pointer cast at the use site, per the established TU idiom -- see
|
||||
* ov_SC03_099_jr_8017BEBC.c:5630 comment block). If (ret & 0x6000), decrement
|
||||
* the +0xac counter (signed s16 compare-to-zero on the POST-decrement value --
|
||||
* gcc-2.7.2's sll-by-16/bnez idiom for a s16 local) and negate +0xDC into
|
||||
* +0x14; on the counter hitting zero, call func_8012C218. Finally decrement
|
||||
* the +0x1c countdown and call func_8012C218 again when IT hits zero.
|
||||
*/
|
||||
|
||||
extern void func_8012B2CC(s32 a0);
|
||||
extern void func_8012B23C(s32 a0);
|
||||
extern void func_8012B14C(s32 a0, s32 a1);
|
||||
extern void func_8012F214(s32 a0, s32 a1, s32 a2);
|
||||
extern void func_8012CBCC(s32 a0);
|
||||
extern void func_8012C218(s32);
|
||||
|
||||
|
||||
void func_8018EC50(s32 a0)
|
||||
{
|
||||
|
||||
extern s32 D_801DC800;
|
||||
SV4 in;
|
||||
SV4 out;
|
||||
s16 v1;
|
||||
u16 uStack_c;
|
||||
|
||||
if (*(u16 *)(a0 + 0x34) == 0) {
|
||||
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) =
|
||||
*(u16 *)(*(s32 *)(*(s32 *)(a0 + 0x64) + 0x20) + 0x12);
|
||||
func_8012B2CC(a0);
|
||||
func_8012B23C(a0);
|
||||
func_8012B14C(a0, *(s16 *)(a0 + 0x70) * 12 + (s32)&D_801DC800);
|
||||
|
||||
in.a = 0;
|
||||
in.b = 0;
|
||||
in.c = 0x10;
|
||||
func_8012F214(a0, (s32)&in, (s32)&out);
|
||||
*(u16 *)(a0 + 6) = out.a;
|
||||
*(u16 *)(a0 + 0xa) = out.b;
|
||||
uStack_c = out.c;
|
||||
*(s32 *)(a0 + 0x1c) = 0x5a;
|
||||
*(u16 *)(a0 + 0x34) = 1;
|
||||
*(u16 *)(a0 + 0xe) = uStack_c;
|
||||
}
|
||||
|
||||
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x10) += -0x80;
|
||||
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x12) += 4;
|
||||
*(u16 *)(*(s32 *)(a0 + 0x20) + 0x14) += *(u16 *)(a0 + 0xfc);
|
||||
|
||||
*(s32 *)(a0 + 0xdc) = *(s32 *)(a0 + 0x14);
|
||||
if ((((s32 (*)(s32))func_8012CBCC)(a0)) & 0x6000) {
|
||||
register s32 negdc __asm__("$2");
|
||||
negdc = -*(s32 *)(a0 + 0xdc);
|
||||
v1 = *(u16 *)(a0 + 0xac);
|
||||
v1 -= 1;
|
||||
*(s16 *)(a0 + 0xac) = v1;
|
||||
*(s32 *)(a0 + 0x14) = negdc;
|
||||
if (v1 == 0) {
|
||||
((void (*)(void *))func_8012C218)((void *)a0);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
s32 iVar3 = *(s32 *)(a0 + 0x1c) - 1;
|
||||
*(s32 *)(a0 + 0x1c) = iVar3;
|
||||
if (iVar3 == 0) {
|
||||
((void (*)(void *))func_8012C218)((void *)a0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern void (*D_801DC818[])(void);
|
||||
|
||||
@@ -3419,7 +3419,67 @@ void func_8017DBFC(void *a0) {
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC06_029/nonmatchings/ov_SC06_029_jr_8017C954", func_8017DC38);
|
||||
|
||||
|
||||
extern s32 rand(void);
|
||||
|
||||
typedef struct {
|
||||
u16 f0;
|
||||
u16 f2;
|
||||
u16 f4;
|
||||
u16 f6;
|
||||
u16 f8;
|
||||
u16 fA;
|
||||
s32 fC;
|
||||
s32 f10;
|
||||
s32 f14;
|
||||
s32 f18;
|
||||
} SubRec_801EB5C8_8017DC38; /* 0x1C */
|
||||
|
||||
typedef struct {
|
||||
u16 g0;
|
||||
u16 g2;
|
||||
s32 g4;
|
||||
s32 g8;
|
||||
s32 gC;
|
||||
SubRec_801EB5C8_8017DC38 subs[16];
|
||||
} GroupRec_801EB5C8_8017DC38; /* 0x1D0 */
|
||||
|
||||
|
||||
void func_8017DC38(s32 param_1)
|
||||
{
|
||||
|
||||
extern GroupRec_801EB5C8_8017DC38 D_801DCCA8[8];
|
||||
s32 i, j;
|
||||
GroupRec_801EB5C8_8017DC38 *grp;
|
||||
SubRec_801EB5C8_8017DC38 *sub;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
grp = &D_801DCCA8[i];
|
||||
grp->g0 = 0;
|
||||
grp->g2 = i << 9;
|
||||
grp->gC = (rand() & 0xF) << 16;
|
||||
grp->g4 = ((rand() & 0xF) << 15) + 0x10000;
|
||||
grp->g8 = ((rand() & 0xF) << 12) + 0x8000;
|
||||
|
||||
for (j = 0; j < 16; j++) {
|
||||
sub = &grp->subs[j];
|
||||
sub->f0 = 0;
|
||||
sub->f2 = (rand() & 3) + 4;
|
||||
sub->f8 = (j << 8) + (rand() & 0xF) * 56;
|
||||
sub->fA = (rand() & 0xF) << 8;
|
||||
sub->f14 = (rand() & 0xF) << 13;
|
||||
sub->fC = ((rand() & 0xF) << 14) + 0x10000;
|
||||
sub->f10 = ((rand() & 0xF) << 12) + 0x8000;
|
||||
sub->f4 = 0x200;
|
||||
sub->f6 = (rand() & 0xF) << 4;
|
||||
sub->f18 = ((rand() & 3) << 5) + 0x40;
|
||||
}
|
||||
}
|
||||
|
||||
*(u16 *)(param_1 + 2) = *(u16 *)(param_1 + 2) + 1;
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC06_029/nonmatchings/ov_SC06_029_jr_8017C954", func_8017DDE0);
|
||||
|
||||
|
||||
@@ -4287,7 +4287,86 @@ void func_8017F53C(s32 a0)
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC06_033/nonmatchings/ov_SC06_033_jr_8017C24C", func_8017F940);
|
||||
|
||||
|
||||
// TARGET: func_8017F940 (ov_SC06_008, TU ov_SC06_008_jr_8017C294.c, 93 ins)
|
||||
//
|
||||
// Template: func_801821F8 in this SAME TU (src/ov_SC06_008/ov_SC06_008_jr_8017C294.c,
|
||||
// around line 5283) is an already-MATCHED sibling (126 ins) with a documented byte-exact
|
||||
// idiom set (its comment, verbatim):
|
||||
// @class: plumbing
|
||||
// @stuck: none — MATCH (126 ins). Keys: (1) cVar1 as `int` (not unsigned char) so the
|
||||
// lbu-loaded byte stays full-width and gcc omits the per-compare `andi 0xff`; (2) uninitialized
|
||||
// `int unaff_s1` -> $s1 (live-from-entry across func_8002D4C8); (3) func_8016AA50 takes TWO args
|
||||
// (param_1, unaff_s1) — a1=unaff_s1 arg-setup is reused by the preceding subtraction and a0=s0
|
||||
// hoists into the branch delay slot; (4) 0x76 read UNSIGNED (lhu) in the subtract, SIGNED (lh) in
|
||||
// the `< 1` test.
|
||||
//
|
||||
// func_8017F940 is the SAME body with the leading "if (*(short*)(param_1+0xfc)==0) {...}" block
|
||||
// (the 0x64-indirected 3x int-copy + 3x u16-copy prologue) removed, and the "already fired" gate
|
||||
// field is 0xe2 instead of 0x102. Confirmed against the target .s: no reference anywhere to 0xfc,
|
||||
// 0x64, or 0x102/0x20 offsets; the gate compare is `lh $v1, 0xE2($s0)` / `sh $v1(=0xA), 0xE2($s0)`.
|
||||
|
||||
extern void func_8002D4C8(int, int);
|
||||
extern void func_8016AA50(int, int);
|
||||
extern s32 func_8016B428(s32);
|
||||
extern void func_80019064(void *);
|
||||
extern void func_8002A520(int);
|
||||
extern void func_8002A790(int);
|
||||
extern void func_80131E00(int, int);
|
||||
|
||||
void func_8017F940(int param_1)
|
||||
{
|
||||
extern unsigned char D_801A7C74[];
|
||||
int cVar1;
|
||||
int unaff_s1;
|
||||
|
||||
cVar1 = *(unsigned char *)(param_1 + 0x5e);
|
||||
*(char *)(param_1 + 0xc1) = 0;
|
||||
*(short *)(param_1 + 0x5e) = 0;
|
||||
*(unsigned short *)(param_1 + 0x5c) = *(unsigned short *)(param_1 + 0x5c) & 0xfffe;
|
||||
if (*(short *)(param_1 + 0xe2) == 0) {
|
||||
*(short *)(param_1 + 0xe2) = 10;
|
||||
*(unsigned short *)(param_1 + 0x5c) = *(unsigned short *)(param_1 + 0x5c) | 0x4000;
|
||||
func_8002D4C8(0x9b7, 0);
|
||||
if (*(short *)(param_1 + 0x60) != 0) {
|
||||
if (cVar1 == 0x1d) {
|
||||
*(short *)(param_1 + 0x82) = 0;
|
||||
*(short *)(param_1 + 0x7c) = *(unsigned short *)(param_1 + 6);
|
||||
*(short *)(param_1 + 0x7e) = *(unsigned short *)(param_1 + 0xa);
|
||||
*(short *)(param_1 + 0x80) = *(unsigned short *)(param_1 + 0xe);
|
||||
}
|
||||
if (*(int *)(param_1 + 0x78) != 0) {
|
||||
unaff_s1 = (int)*(short *)(param_1 + 0x60) *
|
||||
(int)*(short *)(*(int *)(param_1 + 0x78) + 0x30) >> 0xc;
|
||||
if (unaff_s1 < 1) {
|
||||
unaff_s1 = 1;
|
||||
}
|
||||
}
|
||||
*(unsigned short *)(param_1 + 0x76) =
|
||||
*(unsigned short *)(param_1 + 0x76) - unaff_s1;
|
||||
func_8016AA50(param_1, unaff_s1);
|
||||
if ((*(unsigned short *)(param_1 + 0x82) & 1) != 0) {
|
||||
((void (*)(int))func_8016B428)(param_1);
|
||||
func_80019064(D_801A7C74);
|
||||
}
|
||||
}
|
||||
if (cVar1 != 0x1d) {
|
||||
if (*(unsigned char *)(param_1 + 0xc8) != 0) {
|
||||
func_8002A520(param_1);
|
||||
}
|
||||
if (*(unsigned char *)(param_1 + 0xc9) != 0) {
|
||||
func_8002A790(param_1);
|
||||
}
|
||||
}
|
||||
if (*(short *)(param_1 + 0x76) < 1) {
|
||||
*(short *)(param_1 + 0x5c) = 0;
|
||||
func_80131E00(param_1, 6);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// @class: schedule
|
||||
@@ -6346,7 +6425,134 @@ store:
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC06_033/nonmatchings/ov_SC06_033_jr_8017C24C", func_80185DA8);
|
||||
|
||||
/* func_80185DA8 — walk the 0x60-entry / 0x10C-stride entity table D_801202A0 and
|
||||
* react to the first neighbour of class 0x27A (get pushed away from it) or 0x2F4
|
||||
* (get clamped down onto it).
|
||||
*
|
||||
* §71 sibling-first: the callee signatures below are copied VERBATIM from this TU's
|
||||
* own already-matched neighbours — func_8012B0B4 (TU L6971/7855/8177), func_8012B6D4
|
||||
* (TU L6419), func_8012CEB0 (TU L7226, the func_80187844 block), func_8012C098
|
||||
* (TU L5379) — and D_801202A0 is the TU's file-scope `extern u8 D_801202A0[];` (L384).
|
||||
* func_8012BC60 / func_8012ADE4 are not declared in this TU; the forms below are the
|
||||
* fleet-majority shapes (func_8012ADE4 verbatim; func_8012BC60 with `void *` instead of
|
||||
* `struct Vec *` so the draft does not depend on engine_types.h being in scope).
|
||||
*
|
||||
* FIVE load-bearing constructs (do NOT "clean up"):
|
||||
*
|
||||
* 1. NO SECOND WALKED POINTER. All of +0x6/+0xA/+0xE are written as `*(T *)(p + k)`
|
||||
* off the single biv `p`. combine_givs then merges the three DEST_ADDR givs onto
|
||||
* ONE anchor = the LAST-emitted one (+0xE, from the case-0x2F4 `lh`), giving the
|
||||
* target's `$s3 = $s2 + 0xE` with -0x8/-0x4/0x0 displacements.
|
||||
* An explicit `q = p + 0xE` with `*(u16 *)q` looks equivalent and is NOT:
|
||||
* gcc-2.7.2 excludes a bare `*q` (mult 1, add 0) from givs (find_mem_givs:4198),
|
||||
* so q stays a live biv AND the remaining two accesses combine onto their own
|
||||
* anchor +0xA => THREE IVs, the wrong anchor, and the $s6 hoist lost to pressure
|
||||
* (measured: 111 ins, 87 mismatched). gcc-2.7.2-map/loop.md §L1 rules 4 & 6.
|
||||
*
|
||||
* 2. `switch`, not `if/else if`. The two-case switch is what emits the target's
|
||||
* compare CHAIN with BOTH arms out of line (`beq`/`beq`/`j default`, 6 slots).
|
||||
* An `if (id == 0x27A) ... else if (id == 0x2F4)` inverts the first test and lets
|
||||
* the 0x27A arm fall through — 2 instructions short.
|
||||
*
|
||||
* 3. do-while with `i++` BEFORE `p += 0x10C`. strength_reduce inserts the reduced
|
||||
* giv's `addiu` immediately before ITS biv's increment, so the source order
|
||||
* i-then-p is what produces `addiu $s4,$s4,1` / `addiu $s3,$s3,0x10C` /
|
||||
* (delay) `addiu $s2,$s2,0x10C`. A `for (i = 0; i < 0x60; i++)` with `p += 0x10C`
|
||||
* last puts the giv add first and swaps the pair.
|
||||
*
|
||||
* 4. `self4` and `sc` are REAL pre-loop locals, in that order. Both are loop
|
||||
* invariants; written inline as `(s16 *)(a0 + 4)` / `(unsigned int *)sp20` at the
|
||||
* call, combine folds the address straight into the argument move
|
||||
* (`addiu $a0,$sp,0x20`) and the target's `$s6 = $sp + 0x20` hoist never happens.
|
||||
* Assigning them in a *different basic block* from their uses is what keeps the
|
||||
* pseudos alive; the declaration ORDER (p, i, self4, sc) is what gives
|
||||
* $s2/$s4/$s5/$s6 in the target's prologue emission order.
|
||||
*
|
||||
* 5. `s16 y` (a SHORT local), and `s32 sp20[2]` (an EIGHT-byte scratch).
|
||||
* - The short local is why `y` gets a second pseudo: gcc-2.7.2 emits
|
||||
* `(set (reg:HI B) (subreg:HI (reg:SI A)))` for the HImode assignment, i.e. the
|
||||
* target's `addu $a1,$a0,$zero` in the branch delay slot, with the two `- 0x60`
|
||||
* recomputed from A ($a0, the compare) and B ($a1, the stored value).
|
||||
* An `s32 y` coalesces the pair away and loses that instruction.
|
||||
* - The short local also costs a DEAD 4-byte reload home at the top of the frame
|
||||
* (`(use (mem:SI (plus $sp 48)))` in the greg dump, no insn references it).
|
||||
* That is exactly why the func_8012B0B4 buffer is 8 bytes, not 16: 0x10 + 8
|
||||
* (v10) + 8 (v18) + 8 (sp20) + 4 (dead) rounds to 0x30 = the target's first
|
||||
* saved-register slot. 8 bytes also matches the fleet's canonical shape for a
|
||||
* func_8012B0B4 output buffer (`unsigned int buf[2]`).
|
||||
*/
|
||||
|
||||
|
||||
extern s32 func_8012BC60(void *a0, void *a1);
|
||||
extern s32 func_8012B6D4(s16 *a0, s16 *a1);
|
||||
extern void func_8012B0B4(unsigned int *p, int a1, int a2);
|
||||
extern s32 func_8012CEB0(void *a0, void *a1, s32 a2);
|
||||
extern void func_8012ADE4(u8 *a0);
|
||||
extern void func_8012C098(void *param_1);
|
||||
|
||||
void func_80185DA8(s32 a0) {
|
||||
|
||||
extern u8 D_801202A0[];
|
||||
u8 *p;
|
||||
s16 *self4;
|
||||
unsigned int *sc;
|
||||
s32 i;
|
||||
s16 y;
|
||||
s32 z;
|
||||
s32 ang;
|
||||
s16 v10[4]; /* sp+0x10 */
|
||||
s16 v18[4]; /* sp+0x18 */
|
||||
s32 sp20[2]; /* sp+0x20 — func_8012B0B4 output */
|
||||
|
||||
p = D_801202A0;
|
||||
i = 0;
|
||||
self4 = (s16 *)(a0 + 4);
|
||||
sc = (unsigned int *)sp20;
|
||||
do {
|
||||
if ((u8 *)a0 != p) {
|
||||
switch (*(u16 *)p) {
|
||||
case 0x27A:
|
||||
if (func_8012BC60((void *)self4, (void *)(p + 4)) < 0x6400) {
|
||||
ang = func_8012B6D4(self4, (s16 *)(p + 4));
|
||||
func_8012B0B4(sc, ang, 0xA1);
|
||||
v18[0] = *(u16 *)(p + 6);
|
||||
v18[1] = *(u16 *)(p + 0xA);
|
||||
v18[2] = *(u16 *)(p + 0xE);
|
||||
v18[0] += sp20[0];
|
||||
v18[2] += sp20[0] >> 16;
|
||||
v18[1] = *(u16 *)(a0 + 0xA);
|
||||
v10[0] = *(u16 *)(a0 + 0x3A);
|
||||
v10[1] = *(u16 *)(a0 + 0x3E);
|
||||
v10[2] = *(u16 *)(a0 + 0x42);
|
||||
if ((func_8012CEB0(v10, v18, 0) & 0x2000) == 0) {
|
||||
func_8012ADE4((u8 *)a0);
|
||||
return;
|
||||
}
|
||||
*(u16 *)(a0 + 6) = v18[0];
|
||||
*(u16 *)(a0 + 0xA) = v18[1];
|
||||
*(u16 *)(a0 + 0xE) = v18[2];
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0x2F4:
|
||||
y = *(s16 *)(p + 0xE);
|
||||
z = *(s16 *)(a0 + 0xE);
|
||||
if (y + 0x10 < z) {
|
||||
func_8012C098((void *)a0);
|
||||
return;
|
||||
}
|
||||
if (y - 0x60 < z) {
|
||||
*(s16 *)(a0 + 0xE) = y - 0x60;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
p += 0x10C;
|
||||
} while (i < 0x60);
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC06_033/nonmatchings/ov_SC06_033_jr_8017C24C", func_80185F6C);
|
||||
|
||||
@@ -8033,7 +8239,189 @@ void func_80189EC4(void *arg) {
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC06_033/nonmatchings/ov_SC06_033_jr_8017C24C", func_8018A318);
|
||||
|
||||
/* func_8018A318 — ov_SC06_018 / ov_SC06_018_jr_8017C24C
|
||||
*
|
||||
* Direct structural sibling of func_8018E188 (SAME TU, banked MATCH,
|
||||
* src/ov_SC06_018/ov_SC06_018_jr_8017C24C.c:9077) and of func_8018D5C0
|
||||
* (src/ov_SC06_032/ov_SC06_032_jr_8017C24C.c:8530). Shares VERBATIM:
|
||||
* - the 0x60 gate + 0x1D snapshot block,
|
||||
* - the 0x78/0x60 decrement block (AND form — see E188's @stuck note),
|
||||
* - the 0x82&1 finisher, the C8/C9 pokes,
|
||||
* - the two 8-iteration spawn loops (0x281 / 0x23),
|
||||
* - the 0x76<0 else arm (0x8800 / 0x60 / 0xC1 / 0xC2).
|
||||
* It ADDS three leading func_8012C658 triple-spawns and replaces E188's
|
||||
* CC/D0/D4 particle-reseed with the byte-proven RTP_SND block already
|
||||
* matched in this TU at :4292 (func_8017F5xx) — same &D_800AF648 $a0-pin
|
||||
* idiom, different constants (0x9F/0x13F, 0x77/0xEF, /0xA0, no panning).
|
||||
*
|
||||
* Regalloc target (identical to E188): p pinned $s1, e/spawn-ptr coalesce
|
||||
* on $s0, loop counter $s2, the hoisted constant 2 on $s3.
|
||||
*
|
||||
* @class: regalloc-order
|
||||
* @stuck: none — MATCH (248 ins), iteration 2.
|
||||
* ONLY residual on iteration 1 was REGALLOC-PERM/$v1>$a0: the 2nd and 3rd
|
||||
* func_8012C658 results landed in $v1 where the target has $a0 (block 1 was
|
||||
* already right). LEVER: the three spawn pointers are ONE function-scope
|
||||
* variable `t`, not three block-scope `s32 t`. Block 1 CSEs the shared -4
|
||||
* constant into $v1, which forces its pointer to $a0; making `t` a single
|
||||
* multi-block (global) allocno propagates that $a0 to blocks 2 and 3. With
|
||||
* three separate block-local pseudos each block re-runs local-alloc
|
||||
* independently and takes $v1 (lower in REG_ALLOC_ORDER). This is the §76
|
||||
* "variable reuse selects the allocno CLASS" law applied to a pointer whose
|
||||
* live ranges are disjoint — reuse is what makes it global, and global is
|
||||
* what makes the first block's forced choice bind the later ones.
|
||||
*/
|
||||
|
||||
extern s32 rand(void);
|
||||
extern void func_8016AA50(s32, s32);
|
||||
extern s32 func_8016B428(s32);
|
||||
extern void func_80019064(void *);
|
||||
extern void func_8002A520(int);
|
||||
extern void func_8002A790(int);
|
||||
extern void func_8002D4C8(s32, s32);
|
||||
extern s32 func_8012C658(s32, s32, s32);
|
||||
extern s32 func_8012C588(s32, s32);
|
||||
extern u8 *func_8012913C(s32);
|
||||
extern void func_8012C218(void *);
|
||||
extern void func_8004914C(void *a0);
|
||||
extern void func_800491AC(void *a0);
|
||||
extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3);
|
||||
|
||||
void func_8018A318(void *arg) {
|
||||
|
||||
extern u8 D_801C835C;
|
||||
|
||||
extern u8 D_800AF648;
|
||||
|
||||
/* L5: slot offsets are exact only through ONE struct (see the TU's other
|
||||
RTP_SND site) — rv at sp+0x10, sxy at sp+0x18, z sp+0x1C, flag sp+0x20. */
|
||||
struct {
|
||||
s16 rv[4]; /* sp+0x10 */
|
||||
u16 sxy[2]; /* sp+0x18 */
|
||||
s32 z; /* sp+0x1C */
|
||||
s32 flag; /* sp+0x20 */
|
||||
} L;
|
||||
|
||||
register u8 *p __asm__("$17"); /* $s1 */
|
||||
s32 e;
|
||||
s32 i;
|
||||
s32 iv;
|
||||
s32 t;
|
||||
|
||||
p = (u8 *)arg;
|
||||
e = *(u8 *)(p + 0x5E);
|
||||
|
||||
if (*(s16 *)(p + 0x60) != 0) {
|
||||
if (e == 0x1D) {
|
||||
*(u16 *)(p + 0x82) = 0;
|
||||
*(u16 *)(p + 0x7C) = *(u16 *)(p + 0x06);
|
||||
*(u16 *)(p + 0x7E) = *(u16 *)(p + 0x0A);
|
||||
*(u16 *)(p + 0x80) = *(u16 *)(p + 0x0E);
|
||||
}
|
||||
{
|
||||
s32 dec;
|
||||
s32 q = *(s32 *)(p + 0x78);
|
||||
if (q != 0 && *(s16 *)(p + 0x60) != 0) {
|
||||
dec = ((s32)*(s16 *)(p + 0x60) * (s32)*(s16 *)(q + 0x30)) >> 12;
|
||||
if (dec < 1) dec = 1;
|
||||
} else {
|
||||
dec = *(s16 *)(p + 0x60);
|
||||
}
|
||||
*(u16 *)(p + 0x76) = *(u16 *)(p + 0x76) - dec;
|
||||
((void (*)(void *, s32))func_8016AA50)(p, dec);
|
||||
}
|
||||
if (*(u16 *)(p + 0x82) & 1) {
|
||||
((void (*)(void *))func_8016B428)(p);
|
||||
func_80019064(&D_801C835C);
|
||||
}
|
||||
}
|
||||
|
||||
if (e != 0x1D) {
|
||||
if (*(u8 *)(p + 0xC8)) func_8002A520(p);
|
||||
if (*(u8 *)(p + 0xC9)) func_8002A790(p);
|
||||
}
|
||||
|
||||
if (*(s16 *)(p + 0x76) < 0) {
|
||||
t = func_8012C658(0x33, 3, (s32)p);
|
||||
if (t != 0) {
|
||||
*(s16 *)(t + 0x12) = -4;
|
||||
*(s16 *)(t + 0x16) = -0x10;
|
||||
*(s16 *)(t + 0x1A) = -4;
|
||||
}
|
||||
t = func_8012C658(0x33, 2, (s32)p);
|
||||
if (t != 0) {
|
||||
*(s16 *)(t + 0x12) = -4;
|
||||
*(s16 *)(t + 0x16) = -0x10;
|
||||
*(u16 *)(t + 0x1A) = 0;
|
||||
}
|
||||
t = func_8012C658(0x32, 2, (s32)p);
|
||||
if (t != 0) {
|
||||
*(s16 *)(t + 0x12) = -4;
|
||||
*(s16 *)(t + 0x16) = -0x10;
|
||||
*(u16 *)(t + 0x1A) = 4;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
do {
|
||||
iv = ((s32 (*)(s32, void *))func_8012C588)(0x281, p);
|
||||
if (iv != 0) {
|
||||
*(s32 *)(iv + 0x1C) = 2;
|
||||
*(u16 *)(iv + 0x12) = (rand() & 0x1F) - 0x10;
|
||||
*(u16 *)(iv + 0x16) = -((rand() & 0x0F) + 0x10);
|
||||
*(u16 *)(iv + 0x1A) = (rand() & 0x1F) - 0x10;
|
||||
}
|
||||
i++;
|
||||
} while (i < 8);
|
||||
i = 0;
|
||||
do {
|
||||
iv = (s32)func_8012913C(0x23);
|
||||
if (iv != 0) {
|
||||
s32 r;
|
||||
s32 sv;
|
||||
r = rand();
|
||||
*(u16 *)(iv + 0x06) = *(u16 *)(p + 0x06) + (r & 0x3F) - 0x20;
|
||||
r = rand();
|
||||
*(u16 *)(iv + 0x0A) = *(u16 *)(p + 0x0A) - (r & 0x3F) - 0x20;
|
||||
r = rand();
|
||||
sv = *(u16 *)(p + 0x0E);
|
||||
*(s32 *)(iv + 0x18) = 0;
|
||||
*(s32 *)(iv + 0x14) = 0;
|
||||
*(s32 *)(iv + 0x10) = 0;
|
||||
*(u16 *)(iv + 0x0E) = sv + (r & 0x3F) - 0x20;
|
||||
r = rand();
|
||||
*(u16 *)(iv + 0x34) = (r & 0x17FF) + 0x1800;
|
||||
}
|
||||
i++;
|
||||
} while (i < 8);
|
||||
|
||||
L.rv[0] = *(s32 *)(*(s32 *)(p + 0x20) + 0x48);
|
||||
L.rv[1] = *(s32 *)(*(s32 *)(p + 0x20) + 0x4C);
|
||||
L.rv[2] = *(s32 *)(*(s32 *)(p + 0x20) + 0x50);
|
||||
{ register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); }
|
||||
{ register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); }
|
||||
RotTransPers((s32)L.rv, (s32)L.sxy, &L.z, &L.flag);
|
||||
if (L.flag >= 0 && (u32)((L.sxy[0] + 0x9F) & 0xFFFF) < 0x13F
|
||||
&& (u32)((L.sxy[1] + 0x77) & 0xFFFF) < 0xEF) {
|
||||
s32 x = (s16)L.sxy[0];
|
||||
s32 ax;
|
||||
|
||||
ax = x;
|
||||
if (x < 0) {
|
||||
ax = -x;
|
||||
}
|
||||
ax = ((0xA0 - ax) * 0x7F) / 0xA0;
|
||||
func_8002D4C8(0xB32, (ax | 0x1000) & 0xFFFF);
|
||||
}
|
||||
func_8012C218((void *)p);
|
||||
} else {
|
||||
*(u16 *)(p + 0x5C) = 0x8800;
|
||||
*(u16 *)(p + 0x60) = 0;
|
||||
*(u8 *)(p + 0xC1) = 0;
|
||||
*(u8 *)(p + 0xC2) = 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC06_033/nonmatchings/ov_SC06_033_jr_8017C24C", func_8018A6F8);
|
||||
|
||||
@@ -8244,7 +8632,166 @@ INCLUDE_ASM("asm/ov_SC06_033/nonmatchings/ov_SC06_033_jr_8017C24C", func_8018E4A
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC06_033/nonmatchings/ov_SC06_033_jr_8017C24C", func_8018E89C);
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC06_033/nonmatchings/ov_SC06_033_jr_8017C24C", func_8018ECA0);
|
||||
|
||||
/* func_8018ECA0 — ov_SC06_018 / ov_SC06_018_jr_80191C50 (226 ins)
|
||||
*
|
||||
* A "sweeping beam" tick for the 0x318 boss-effect entity family — the same
|
||||
* entity class its already-MATCHED TU neighbour func_80191C50 drives
|
||||
* (src/ov_SC06_018/ov_SC06_018_jr_80191C50.c:2860).
|
||||
*
|
||||
* - 3-way state machine on +0x34:
|
||||
* 0 = spawn the child (func_8012C658(0x318, 8, arg0)) -> +0xCC,
|
||||
* 1 = sweep -Z until 0x8C-z >= 0xFC, then state 2,
|
||||
* 2 = sweep +Z until z-0x8C >= 0xFC, then state 1.
|
||||
* - then, if the child (+0xCC) exists: two func_8018AD9C draws (colours
|
||||
* 0x81818 / 0x204040), and TWO substep-interpolated hit sweeps that walk
|
||||
* the beam origin backwards by `d` once per substep:
|
||||
* (a) over the 0x60-entry entity table D_801202A0 (stride 0x10C),
|
||||
* hit-testing each live entity with func_80135260 and, on a hit,
|
||||
* stamping state 0x1D / timer 0xA / flag 1 / +0x62 = yaw-0x800;
|
||||
* (b) against the player with func_8012DF34, stamping D_80126B98.
|
||||
*
|
||||
* @class: none — MATCH (226 ins), iteration 3.
|
||||
*
|
||||
* @lever (NEW, generalizable — loop.c `combine_givs` ANCHOR RULE):
|
||||
* Iterations 1-2 were LENGTH-DRIFT +5 / +2 with an EXTRA induction register.
|
||||
* All of the entity-record accesses (+0x20 +0x58 +0x5C +0x5E +0x60 +0x62
|
||||
* +0xAE) are DEST_ADDR givs on the table pointer, and gcc-2.7.2 allocates
|
||||
* ONE new pseudo for the combined group. Which offset the group is
|
||||
* ANCHORED at is not free: `record_giv` PREPENDS to `bl->giv`, and
|
||||
* `combine_givs` walks that list from the head taking the first absorber —
|
||||
* so the anchor is the **LAST address giv discovered in source order**.
|
||||
* The target anchors at +0x5E (base $s3, giv $s0, offsets -0x3E..+0x50);
|
||||
* my draft anchored at +0x62 because `*(u16*)(e+0x62) = ...` was the last
|
||||
* store in the hit block, which forced a THIRD induction register (+$s7,
|
||||
* +2 prologue/epilogue insns, +1 giv-init, +1 latch increment, +1 nop).
|
||||
* FIX: reorder the hit block so the **+0x5E store is last** — pure source
|
||||
* ordering, zero semantic change, and the scheduler still emits +0x62 last
|
||||
* in the asm because it depends on a lw->lhu chain.
|
||||
*
|
||||
* @lever (§76 allocno CLASS): the spawn result, the +0xCC child pointer and
|
||||
* the D_801202A0 table walker are ONE variable `e`. Split into separate
|
||||
* variables the first two are local, call-crossing-free allocnos and land
|
||||
* in $a0 (first free in REG_ALLOC_ORDER); merged, the live range spans the
|
||||
* func_80135260 loop, so calls_crossed > 0 forces a callee-saved reg and
|
||||
* the whole chain coalesces onto $s3 — which is also what frees the
|
||||
* `bnez $s3` delay slot for `addu $a0, $s2, $zero`.
|
||||
*
|
||||
* @lever (store order): `sp10.vy = sp18.vy = v` (not `sp18.vy = sp10.vy = v`)
|
||||
* — `a = b = v` stores b first, and the target emits sh 0x1A before 0x12.
|
||||
*/
|
||||
|
||||
extern s32 func_8012C658(s32 a0, s32 a1, s32 a2);
|
||||
extern void func_8012B2CC(s32 a0);
|
||||
extern void func_8018AD9C(s32 param_1, u32 param_2, u16 *param_3, u32 param_4);
|
||||
extern s32 func_8004787C(s32 a0);
|
||||
extern s32 func_80135260(s32 arg0, s32 arg1, s16 *arg2, s16 *arg3);
|
||||
extern s32 func_8012DF34(s32 a0, s32 a1, s32 a2);
|
||||
|
||||
typedef struct {
|
||||
s16 vx, vy, vz, pad;
|
||||
} SV_80192F64_8018ECA0;
|
||||
|
||||
void func_8018ECA0(s32 arg0) {
|
||||
|
||||
extern u8 D_801202A0[];
|
||||
extern u16 D_80126B98[];
|
||||
s32 e;
|
||||
s16 t;
|
||||
s32 i;
|
||||
s32 n;
|
||||
s32 d;
|
||||
SV_80192F64_8018ECA0 sp10;
|
||||
SV_80192F64_8018ECA0 sp18;
|
||||
SV_80192F64_8018ECA0 sp20;
|
||||
u16 sp28[2];
|
||||
|
||||
switch (*(u16 *)(arg0 + 0x34)) {
|
||||
case 0:
|
||||
e = func_8012C658(0x318, 8, arg0);
|
||||
if (e != 0) {
|
||||
*(u16 *)(arg0 + 0x34) = (*(u16 *)(arg0 + 0xFC) & 1) + 1;
|
||||
*(u16 *)(*(s32 *)(e + 0x20) + 0x12) = *(u16 *)(*(s32 *)(arg0 + 0x20) + 0x12) + 0x800;
|
||||
*(s32 *)(e + 4) = *(s32 *)(e + 4) - *(s32 *)(arg0 + 0xDC);
|
||||
*(s32 *)(arg0 + 0xCC) = e;
|
||||
*(u16 *)(e + 0xFC) = *(u16 *)(arg0 + 0x36);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
t = *(u16 *)(arg0 + 0xE) - 4;
|
||||
*(u16 *)(arg0 + 0xE) = t;
|
||||
if (*(s16 *)(arg0 + 0x8C) - t >= *(s16 *)(arg0 + 0xFC)) {
|
||||
*(u16 *)(arg0 + 0x34) = 2;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
t = *(u16 *)(arg0 + 0xE) + 4;
|
||||
*(u16 *)(arg0 + 0xE) = t;
|
||||
if (t - *(s16 *)(arg0 + 0x8C) >= *(s16 *)(arg0 + 0xFC)) {
|
||||
*(u16 *)(arg0 + 0x34) = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
e = *(s32 *)(arg0 + 0xCC);
|
||||
if (e == 0) {
|
||||
*(u16 *)(arg0 + 2) = *(u16 *)(arg0 + 2) + 1;
|
||||
return;
|
||||
}
|
||||
*(s32 *)(e + 0xC) = *(s32 *)(arg0 + 0xC);
|
||||
sp28[0] = 0;
|
||||
sp28[1] = *(u16 *)(arg0 + 0xDE);
|
||||
func_8012B2CC(arg0);
|
||||
func_8018AD9C(arg0, 0, sp28, 0x81818);
|
||||
func_8018AD9C(arg0, 1, sp28, 0x204040);
|
||||
|
||||
sp10.vx = *(u16 *)(arg0 + 6);
|
||||
sp10.vy = sp18.vy = *(u16 *)(arg0 + 0xA);
|
||||
sp10.vz = sp18.vz = *(u16 *)(arg0 + 0xE);
|
||||
e = (s32)D_801202A0;
|
||||
i = 0;
|
||||
d = func_8004787C(*(s16 *)(*(s32 *)(arg0 + 0x20) + 0x12)) >> 4;
|
||||
do {
|
||||
if (*(u16 *)e != 0 && *(u16 *)e != 0x25D && *(u16 *)e != 0x318 &&
|
||||
(*(u16 *)(e + 0x5C) & 0x8000) != 0 && *(u16 *)(e + 0x5E) != 0x1D &&
|
||||
(*(u16 *)(e + 0xAE) & 1) == 0) {
|
||||
n = ((s16) * (u16 *)(arg0 + 0xDE) >> 8) + 1;
|
||||
sp18.vx = sp10.vx;
|
||||
sp20.vy = sp18.vy;
|
||||
sp20.vz = sp18.vz;
|
||||
do {
|
||||
sp20.vx = sp18.vx - d;
|
||||
if (func_80135260(*(s32 *)(e + 0x20), *(s32 *)(e + 0x58), &sp18.vx, &sp20.vx) == 1) {
|
||||
*(u16 *)(e + 0x60) = 0xA;
|
||||
*(u16 *)(e + 0x5C) = *(u16 *)(e + 0x5C) | 1;
|
||||
*(u16 *)(e + 0x62) = *(u16 *)(*(s32 *)(e + 0x20) + 0x12) - 0x800;
|
||||
*(u16 *)(e + 0x5E) = 0x1D;
|
||||
n = 1;
|
||||
}
|
||||
n--;
|
||||
sp18.vx = sp18.vx - d;
|
||||
} while (n != 0);
|
||||
}
|
||||
e += 0x10C;
|
||||
i++;
|
||||
} while (i < 0x60);
|
||||
|
||||
n = ((s16) * (u16 *)(arg0 + 0xDE) >> 8) + 1;
|
||||
sp18.vx = sp10.vx;
|
||||
sp20.vy = sp18.vy;
|
||||
sp20.vz = sp18.vz;
|
||||
do {
|
||||
sp20.vx = sp18.vx - d;
|
||||
if (func_8012DF34(arg0, (s32)&sp18.vx, (s32)&sp20.vx) == 1) {
|
||||
D_80126B98[0] = 0x96;
|
||||
D_80126B98[-1] = 0x4018;
|
||||
n = 1;
|
||||
}
|
||||
n--;
|
||||
sp18.vx = sp18.vx - d;
|
||||
} while (n != 0);
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC06_033/nonmatchings/ov_SC06_033_jr_8017C24C", func_8018F028);
|
||||
|
||||
@@ -8320,7 +8867,152 @@ void aF8017ED80(void *param_1) {
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC06_033/nonmatchings/ov_SC06_033_jr_8017C24C", func_8018F6EC);
|
||||
|
||||
/* func_8018F6EC -- ov_SC06_008, TU ov_SC06_008_jr_8017C294.c (open-only h_norm
|
||||
* cluster exemplar, 7 members).
|
||||
*
|
||||
* a0+0x0 : u16 active flag; 0 => early return.
|
||||
* a0+0x84 : s16 sound cooldown timer.
|
||||
* cooldown != 0 -> just decrement it.
|
||||
* cooldown == 0 -> try to play a positional sound (RotTransPers screen
|
||||
* projection of the parent's position, range-gated on
|
||||
* screen X/Y, volume from the classic div-by-0xF0 /
|
||||
* div-by-0x1E magic-constant idiom -- byte-proven sibling
|
||||
* form is func_80181CF0 in this same TU, sndid 0x849 here
|
||||
* vs 0x961 there), then unconditionally reset the timer
|
||||
* to 0xA regardless of whether the sound actually played.
|
||||
* a0+0xFC / 0xFE : running hit-combo accumulators, bumped by +/-0x280 every
|
||||
* call (unconditional tail).
|
||||
* Tail always calls ((void (*)(void *))func_8018F518)(a0) (the TU's canonical decl for this
|
||||
* symbol is void(void) -- S35 self-axis -- so this draft binds its own
|
||||
* private extern with the asm's real void(void*) shape).
|
||||
*
|
||||
* Control flow is EXPLICIT goto/label, mirroring source-order block
|
||||
* placement (gcc-2.7.2 lays out basic blocks in literal source order, not by
|
||||
* fallthrough preference -- see the func_80181CF0 comment, same TU): the
|
||||
* cooldown!=0 decrement is the SHORT block and sits out-of-line (jumped to),
|
||||
* the cooldown==0 RTP+sound block is the LONG block and sits inline
|
||||
* (fallthrough), matching the target's physical layout exactly.
|
||||
*
|
||||
* MATCH levers (byte-proven, 2026-08-05):
|
||||
* 1. Naive `if(old!=0){cool=old-1;}else{...}` folds trivially: reorg.c's
|
||||
* delay-slot filler steals the single-insn decrement into the `bnez`'s
|
||||
* own delay slot and retargets the branch straight to the join label
|
||||
* (2 ins short of target). The target instead keeps a genuine copy
|
||||
* (`addu $v1,$v0,zero`) in the delay slot and a SEPARATE `addiu $v0,$v1,-1`
|
||||
* at the decrement site. Reproduced by pinning a second variable
|
||||
* `register s32 v1 __asm__("$3")`, assigned UNCONDITIONALLY right after
|
||||
* the load (`v1 = old;`) -- the scheduler places that copy in the
|
||||
* branch's delay slot on its own, and the decrement (`cool = v1 - 1`)
|
||||
* can no longer be folded away. `cool` is separately pinned to
|
||||
* `__asm__("$2")` so its other def sites (the three `cool = 0xA` early
|
||||
* exits) don't drift onto $3 by coalescing with v1.
|
||||
* 2. The tail's `sh $v0,0x84($s0)` / `addu $a0,$s0,zero` order (store off
|
||||
* the callee-saved pointer BEFORE reloading it into the call-argument
|
||||
* register) needed a `__asm__ __volatile__("":::"memory")` fence right
|
||||
* after the store -- without it, sched1 hoists the independent a0-reload
|
||||
* ahead of the store even when the reload is written later in source.
|
||||
* 3. Frame is -0x38, 8 bytes (2 words) larger than the natural -0x30 the
|
||||
* locals alone produce; `pad2[2]` (dead, address never read) inside `L`
|
||||
* reserves them, mirroring func_80181CF0's own "dead aggregate sizes the
|
||||
* frame" idiom.
|
||||
*/
|
||||
|
||||
|
||||
/* §37/§124 def-side asm-label alias (P30 S1d class lever): the TU declares
|
||||
* `extern void func_8018F6EC(void);` (L4082, L4091) for callers that invoke it with NO args,
|
||||
* while the byte-true definition takes an s32 in $a0 -> `conflicting types`. Neither side can
|
||||
* move (a no-prototype escape is illegal once a param promotes), so the DEFINITION gets a
|
||||
* private C identifier and binds the emitted symbol with a GNU asm label. Zero blast radius:
|
||||
* the TU's declaration never meets the definition, and the emitted symbol is unchanged. */
|
||||
void aF8017EF54(s32 a0) __asm__("func_8018F6EC");
|
||||
|
||||
void aF8017EF54(s32 a0)
|
||||
{
|
||||
extern void func_8004914C(void *a0);
|
||||
extern void func_800491AC(void *a0);
|
||||
extern void func_8002D4C8(s32 a0, s32 a1);
|
||||
extern s32 RotTransPers(s32 a0, s32 a1, s32 *a2, s32 *a3);
|
||||
extern u8 D_800AF648;
|
||||
extern void func_8018F518(void);
|
||||
struct {
|
||||
s16 v[3]; /* sp+0x10 */
|
||||
s16 pad1; /* sp+0x16 */
|
||||
u16 sxy[2]; /* sp+0x18 */
|
||||
s32 z; /* sp+0x1C */
|
||||
s32 flag; /* sp+0x20 */
|
||||
s32 pad2[2]; /* sp+0x24 -- dead, sizes the frame */
|
||||
} L;
|
||||
|
||||
register s32 v1 __asm__("$3");
|
||||
register s32 cool __asm__("$2");
|
||||
s32 old;
|
||||
|
||||
if (*(u16 *)(a0 + 0x0) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
old = *(s16 *)(a0 + 0x84);
|
||||
v1 = old;
|
||||
if (old != 0) {
|
||||
goto L_dec;
|
||||
}
|
||||
|
||||
L.v[0] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x48);
|
||||
L.v[1] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x4C);
|
||||
L.v[2] = *(s32 *)(*(s32 *)(a0 + 0x20) + 0x50);
|
||||
{ register void *r4 __asm__("$4"); r4 = &D_800AF648; func_8004914C(r4); }
|
||||
{ register void *r4 __asm__("$4"); r4 = &D_800AF648; func_800491AC(r4); }
|
||||
RotTransPers((s32)L.v, (s32)L.sxy, &L.z, &L.flag);
|
||||
|
||||
if (L.flag < 0) {
|
||||
cool = 0xA;
|
||||
goto L_join;
|
||||
}
|
||||
if ((u32)((L.sxy[0] + 0xEF) & 0xFFFF) >= 0x1DF) {
|
||||
cool = 0xA;
|
||||
goto L_join;
|
||||
}
|
||||
if ((u32)((L.sxy[1] + 0xB3) & 0xFFFF) >= 0x167) {
|
||||
goto L_snd_skip;
|
||||
}
|
||||
|
||||
{
|
||||
s32 sx = (s16)L.sxy[0];
|
||||
s32 av;
|
||||
|
||||
av = sx;
|
||||
if (sx < 0) {
|
||||
av = -sx;
|
||||
}
|
||||
av = ((0xF0 - av) * 0x7F) / 0xF0;
|
||||
sx = (sx + 0xF0) / 0x1E;
|
||||
if (sx == 0x10) {
|
||||
sx = 0xF;
|
||||
}
|
||||
sx = sx << 8;
|
||||
func_8002D4C8(0x849, (av | (0x3000 | sx)) & 0xFFFF);
|
||||
}
|
||||
|
||||
L_snd_skip:
|
||||
cool = 0xA;
|
||||
goto L_join;
|
||||
|
||||
L_dec:
|
||||
cool = v1 - 1;
|
||||
|
||||
L_join:
|
||||
*(s16 *)(a0 + 0x84) = cool;
|
||||
__asm__ __volatile__("" ::: "memory");
|
||||
|
||||
{
|
||||
s32 p = a0;
|
||||
*(u16 *)(p + 0xFC) = *(u16 *)(p + 0xFC) + 0x280;
|
||||
*(u16 *)(p + 0xFE) = *(u16 *)(p + 0xFE) - 0x280;
|
||||
((void (*)(void *))func_8018F518)((void *)p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern s32 rand(void);
|
||||
|
||||
@@ -3203,7 +3203,67 @@ void func_8017E604(void *a0) {
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC07_002/nonmatchings/ov_SC07_002_jr_8017C8D0", func_8017E640);
|
||||
|
||||
|
||||
extern s32 rand(void);
|
||||
|
||||
typedef struct {
|
||||
u16 f0;
|
||||
u16 f2;
|
||||
u16 f4;
|
||||
u16 f6;
|
||||
u16 f8;
|
||||
u16 fA;
|
||||
s32 fC;
|
||||
s32 f10;
|
||||
s32 f14;
|
||||
s32 f18;
|
||||
} SubRec_801EB5C8_8017E640; /* 0x1C */
|
||||
|
||||
typedef struct {
|
||||
u16 g0;
|
||||
u16 g2;
|
||||
s32 g4;
|
||||
s32 g8;
|
||||
s32 gC;
|
||||
SubRec_801EB5C8_8017E640 subs[16];
|
||||
} GroupRec_801EB5C8_8017E640; /* 0x1D0 */
|
||||
|
||||
|
||||
void func_8017E640(s32 param_1)
|
||||
{
|
||||
|
||||
extern GroupRec_801EB5C8_8017E640 D_8019E1B8[8];
|
||||
s32 i, j;
|
||||
GroupRec_801EB5C8_8017E640 *grp;
|
||||
SubRec_801EB5C8_8017E640 *sub;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
grp = &D_8019E1B8[i];
|
||||
grp->g0 = 0;
|
||||
grp->g2 = i << 9;
|
||||
grp->gC = (rand() & 0xF) << 16;
|
||||
grp->g4 = ((rand() & 0xF) << 15) + 0x10000;
|
||||
grp->g8 = ((rand() & 0xF) << 12) + 0x8000;
|
||||
|
||||
for (j = 0; j < 16; j++) {
|
||||
sub = &grp->subs[j];
|
||||
sub->f0 = 0;
|
||||
sub->f2 = (rand() & 3) + 4;
|
||||
sub->f8 = (j << 8) + (rand() & 0xF) * 56;
|
||||
sub->fA = (rand() & 0xF) << 8;
|
||||
sub->f14 = (rand() & 0xF) << 13;
|
||||
sub->fC = ((rand() & 0xF) << 14) + 0x10000;
|
||||
sub->f10 = ((rand() & 0xF) << 12) + 0x8000;
|
||||
sub->f4 = 0x200;
|
||||
sub->f6 = (rand() & 0xF) << 4;
|
||||
sub->f18 = ((rand() & 3) << 5) + 0x40;
|
||||
}
|
||||
}
|
||||
|
||||
*(u16 *)(param_1 + 2) = *(u16 *)(param_1 + 2) + 1;
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC07_002/nonmatchings/ov_SC07_002_jr_8017C8D0", func_8017E7E8);
|
||||
|
||||
|
||||
@@ -3966,12 +3966,6 @@ extern Morph_8017DC1C *D_801BF530;
|
||||
extern Morph_8017DC1C *D_801BF534;
|
||||
extern Morph_8017DC1C *D_801BF538;
|
||||
extern Morph_8017DC1C *D_801BF650;
|
||||
extern Morph_8017DC1C *D_801BF65C;
|
||||
extern Morph_8017DC1C *D_801BF660;
|
||||
extern Morph_8017DC1C *D_801BF684;
|
||||
extern Morph_8017DC1C *D_801BF6A4;
|
||||
extern Morph_8017DC1C *D_801BF6A8;
|
||||
extern Morph_8017DC1C *D_801BF6AC;
|
||||
|
||||
extern SVECTOR2 *D_801C1E14;
|
||||
extern SVECTOR2 *D_801C1E18;
|
||||
@@ -3979,11 +3973,6 @@ extern SVECTOR2 *D_801C1E1C;
|
||||
extern SVECTOR2 *D_801C1E20;
|
||||
extern SVECTOR2 *D_801C1E24;
|
||||
extern SVECTOR2 *D_801C1E28;
|
||||
extern SVECTOR2 *D_801C1E2C;
|
||||
extern SVECTOR2 *D_801C1E30;
|
||||
extern SVECTOR2 *D_801C1E34;
|
||||
extern SVECTOR2 *D_801C1E38;
|
||||
extern SVECTOR2 *D_801C1E3C;
|
||||
extern SVECTOR2 *D_801C1E40;
|
||||
extern SVECTOR2 *D_801C1E44;
|
||||
extern SVECTOR2 *D_801C1E48;
|
||||
@@ -3994,24 +3983,11 @@ extern SVECTOR2 *D_801C1E58;
|
||||
extern SVECTOR2 *D_801C1E60;
|
||||
extern SVECTOR2 *D_801C1E64;
|
||||
extern SVECTOR2 *D_801C1E68;
|
||||
extern SVECTOR2 *D_801C1E6C;
|
||||
extern SVECTOR2 *D_801C1E70;
|
||||
extern SVECTOR2 *D_801C1E74;
|
||||
extern SVECTOR2 *D_801C1E78;
|
||||
extern SVECTOR2 *D_801C1E7C;
|
||||
extern SVECTOR2 *D_801C1E80;
|
||||
extern SVECTOR2 *D_801C1E84;
|
||||
extern SVECTOR2 *D_801C1E88;
|
||||
extern SVECTOR2 *D_801C1E8C;
|
||||
extern SVECTOR2 *D_801C1E90;
|
||||
extern SVECTOR2 *D_801C1E94;
|
||||
extern SVECTOR2 *D_801C1E98;
|
||||
extern SVECTOR2 *D_801C1E9C;
|
||||
extern SVECTOR2 *D_801C1EA0;
|
||||
extern SVECTOR2 *D_801C1EA4;
|
||||
extern SVECTOR2 *D_801C1EA8;
|
||||
extern SVECTOR2 *D_801C1EAC;
|
||||
extern SVECTOR2 *D_801C1EB0;
|
||||
|
||||
|
||||
/* MUST be `inline` — see L1. 25 expansions == 1518 ins, 0 jal, frame 25*24=0x258. */
|
||||
@@ -4042,6 +4018,39 @@ static inline void morph_lerp(Morph_8017DC1C *o, SVECTOR2 *b, SVECTOR2 *a, s32 t
|
||||
|
||||
void func_8017DC1C(s32 t)
|
||||
{
|
||||
/* [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 SVECTOR2 *D_801C1E6C;
|
||||
extern SVECTOR2 *D_801C1E70;
|
||||
extern SVECTOR2 *D_801C1E74;
|
||||
extern SVECTOR2 *D_801C1E78;
|
||||
extern SVECTOR2 *D_801C1E7C;
|
||||
extern SVECTOR2 *D_801C1EB0;
|
||||
extern Morph_8017DC1C *D_801BF6A4;
|
||||
extern Morph_8017DC1C *D_801BF6A8;
|
||||
extern Morph_8017DC1C *D_801BF6AC;
|
||||
/* [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 SVECTOR2 *D_801C1E2C;
|
||||
extern SVECTOR2 *D_801C1E30;
|
||||
extern SVECTOR2 *D_801C1EAC;
|
||||
extern SVECTOR2 *D_801C1E38;
|
||||
extern SVECTOR2 *D_801C1E3C;
|
||||
extern SVECTOR2 *D_801C1E34;
|
||||
extern Morph_8017DC1C *D_801BF65C;
|
||||
extern Morph_8017DC1C *D_801BF660;
|
||||
extern Morph_8017DC1C *D_801BF684;
|
||||
/* [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 SVECTOR2 *D_801C1E80;
|
||||
extern SVECTOR2 *D_801C1E84;
|
||||
extern SVECTOR2 *D_801C1E88;
|
||||
extern SVECTOR2 *D_801C1E90;
|
||||
extern SVECTOR2 *D_801C1E94;
|
||||
extern SVECTOR2 *D_801C1E98;
|
||||
morph_lerp(D_801BF4F4, D_801C1E14, D_801C1E18, t);
|
||||
morph_lerp(D_801BF4F8, D_801C1E1C, D_801C1E1C, t);
|
||||
morph_lerp(D_801BF4FC, D_801C1E20, D_801C1E20, t);
|
||||
@@ -4106,7 +4115,32 @@ INCLUDE_ASM("asm/ov_SC07_006/nonmatchings/ov_SC07_006_jr_8017BEBC", func_80180CF
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC07_006/nonmatchings/ov_SC07_006_jr_8017BEBC", func_80181148);
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC07_006/nonmatchings/ov_SC07_006_jr_8017BEBC", func_8018163C);
|
||||
|
||||
/* func_8018163C — banked from the S40 wave-1 draft.
|
||||
* The draft carried the TYPES, the six SVECTOR2 externs and `static inline morph_lerp` so that
|
||||
* match_one could compile it standalone (-Iinclude only, the §77 probe rule). The REAL TU
|
||||
* (ov_SC07_006_jr_8017BEBC.c) already defines all of them — morph_lerp at :4018 — so keeping
|
||||
* them produced `redefinition of morph_lerp`. Per the draft's own banking note, only the three
|
||||
* NEW externs and the body belong here. §77: a probe layer is scaffolding, not part of the bank. */
|
||||
|
||||
|
||||
void func_8018163C(s32 t)
|
||||
{
|
||||
|
||||
extern SVECTOR2 *D_801C1E80;
|
||||
extern SVECTOR2 *D_801C1E84;
|
||||
extern SVECTOR2 *D_801C1E88;
|
||||
extern SVECTOR2 *D_801C1E90;
|
||||
extern SVECTOR2 *D_801C1E94;
|
||||
extern SVECTOR2 *D_801C1E98;
|
||||
extern Morph_8017DC1C *D_801BF5B4;
|
||||
extern Morph_8017DC1C *D_801BF5B8;
|
||||
extern Morph_8017DC1C *D_801BF5BC;
|
||||
morph_lerp(D_801BF5B4, D_801C1E80, D_801C1E90, t);
|
||||
morph_lerp(D_801BF5B8, D_801C1E84, D_801C1E94, t);
|
||||
morph_lerp(D_801BF5BC, D_801C1E88, D_801C1E98, t);
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC07_006/nonmatchings/ov_SC07_006_jr_8017BEBC", func_80181924);
|
||||
|
||||
@@ -4120,11 +4154,61 @@ INCLUDE_ASM("asm/ov_SC07_006/nonmatchings/ov_SC07_006_jr_8017BEBC", func_8018215
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC07_006/nonmatchings/ov_SC07_006_jr_8017BEBC", func_80182268);
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC07_006/nonmatchings/ov_SC07_006_jr_8017BEBC", func_801823F8);
|
||||
|
||||
/* func_801823F8 — banked from the S40 wave-1 draft.
|
||||
* The draft carried the TYPES, the six SVECTOR2 externs and `static inline morph_lerp` so that
|
||||
* match_one could compile it standalone (-Iinclude only, the §77 probe rule). The REAL TU
|
||||
* (ov_SC07_006_jr_8017BEBC.c) already defines all of them — morph_lerp at :4018 — so keeping
|
||||
* them produced `redefinition of morph_lerp`. Per the draft's own banking note, only the three
|
||||
* NEW externs and the body belong here. §77: a probe layer is scaffolding, not part of the bank. */
|
||||
|
||||
|
||||
void func_801823F8(s32 t)
|
||||
{
|
||||
|
||||
extern SVECTOR2 *D_801C1E2C;
|
||||
extern SVECTOR2 *D_801C1E30;
|
||||
extern SVECTOR2 *D_801C1EAC;
|
||||
extern SVECTOR2 *D_801C1E38;
|
||||
extern SVECTOR2 *D_801C1E3C;
|
||||
extern SVECTOR2 *D_801C1E34;
|
||||
extern Morph_8017DC1C *D_801BF65C;
|
||||
extern Morph_8017DC1C *D_801BF660;
|
||||
extern Morph_8017DC1C *D_801BF684;
|
||||
morph_lerp(D_801BF65C, D_801C1E2C, D_801C1E38, t);
|
||||
morph_lerp(D_801BF660, D_801C1E30, D_801C1E3C, t);
|
||||
morph_lerp(D_801BF684, D_801C1EAC, D_801C1E34, t);
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC07_006/nonmatchings/ov_SC07_006_jr_8017BEBC", func_801826E0);
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC07_006/nonmatchings/ov_SC07_006_jr_8017BEBC", func_801828A4);
|
||||
|
||||
/* func_801828A4 — banked from the S40 wave-1 draft.
|
||||
* The draft carried the TYPES, the six SVECTOR2 externs and `static inline morph_lerp` so that
|
||||
* match_one could compile it standalone (-Iinclude only, the §77 probe rule). The REAL TU
|
||||
* (ov_SC07_006_jr_8017BEBC.c) already defines all of them — morph_lerp at :4018 — so keeping
|
||||
* them produced `redefinition of morph_lerp`. Per the draft's own banking note, only the three
|
||||
* NEW externs and the body belong here. §77: a probe layer is scaffolding, not part of the bank. */
|
||||
|
||||
|
||||
void func_801828A4(s32 t)
|
||||
{
|
||||
|
||||
extern SVECTOR2 *D_801C1E6C;
|
||||
extern SVECTOR2 *D_801C1E70;
|
||||
extern SVECTOR2 *D_801C1E74;
|
||||
extern SVECTOR2 *D_801C1E78;
|
||||
extern SVECTOR2 *D_801C1E7C;
|
||||
extern SVECTOR2 *D_801C1EB0;
|
||||
extern Morph_8017DC1C *D_801BF6A4;
|
||||
extern Morph_8017DC1C *D_801BF6A8;
|
||||
extern Morph_8017DC1C *D_801BF6AC;
|
||||
morph_lerp(D_801BF6A4, D_801C1E6C, D_801C1E78, t);
|
||||
morph_lerp(D_801BF6A8, D_801C1E70, D_801C1E7C, t);
|
||||
morph_lerp(D_801BF6AC, D_801C1E74, D_801C1EB0, t);
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC07_006/nonmatchings/ov_SC07_006_jr_8017BEBC", func_80182B8C);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user