mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-09-26 13:33:34 -04:00
feat(phase-30 S43): FABLE5 CRACKS func_8017C6F4 pin-free — banked ×4 (~3,788 ins) [R22 PENDING]
⚠️ R22 CLEAN-FLEET VERIFY IS OWED, NOT DONE. All four gates below were INCREMENTAL builds
(§130: an incremental build can report BYTE-IDENTICAL for a change a clean build cannot link).
Committed now only to protect the work — a second Fable5 agent is reading asm/, so `make clean`
would destroy its inputs mid-run. The clean-fleet run follows the moment that agent finishes;
treat these four banks as UNCONFIRMED until then.
- THE CRACK (Drew approved the Fable5 escalation, R27): byte-exact, PIN-FREE, 947 ins. My §147-E
"qty_compare tie, unreachable from source" diagnosis was WRONG. The residual was VARIABLE
IDENTITY: (1) the X-pass and Y-pass min/max intermediates are DIFFERENT variables (8, not 4
reused); (2) mnc/mxc do not exist — the cell clamps reuse the prim-loop mn/mx (X) and mny/my (Y).
Ablations: split-only 63, reuse-only 624, conjunction MATCH. That is also why S42's "separate
X vs Y variables" probe was filed as a failure (it was half the fix), and why every allocator
lever was inert — pins, §148-C sliders, declaration order and 14 permuter restarts cannot reach
a draft with the wrong NUMBER OF PSEUDOS.
- VERIFIED INDEPENDENTLY BEFORE BELIEVING IT (R14): I re-ran match_one -> MATCH (947 ins), then
the whole-binary gate per binary.
- BANKED ×4 (every 948-ins sibling of this body), each byte-identical:
ov_SC03_126 c48a8bb8 · ov_SC03_003 898bf52a · ov_SC04_021 33614234 · ov_SC05_019 3f5b4f13.
family_remap produced all three siblings cleanly.
- §146 SEEN AGAIN: all three siblings first failed with `PLUMBING: parse error before 'MTX_C6F4'`
— _carry_macros carries #defines but NOT typedefs; prepending the 9 typedef lines fixed all
three. That label is legible ONLY because of this session's classifier fix; before it, it read
"CC1-FAIL: make: *** Error N" and cost a manual splice-and-rebuild each.
- cookbook §150 (decode register ownership from the MATCHING diff regions before touching the
allocator; per-instance register asymmetry ⇒ per-instance variables; the deleted-self-move tell
and the global.c:719-vs-:729 death-before-store exemption behind it). §147-E corrected: it named
the wrong allocator — these are global.c allocnos, not local qty_compare quantities.
This commit is contained in:
@@ -839,3 +839,4 @@
|
||||
{"ts": "2026-08-05 16:05:31", "addr": "0x8017C6F4", "name": "func_8017C6F4", "reach": 3, "klass": "regalloc: register rotation (mnc/xmx1/cell/prim); ILS took hand-63 -> 42, flat across 5 restarts", "nins": 947, "status": "near", "closeness": 42, "where_stuck": "ov_SC03_126; permuter ILS plateau (masked 44 over 6 warm restarts); residual still the register rotation, fewer instances", "best_draft": ".run/s43/func_8017C6F4.ils44.c", "binary": "ov_SC03_126", "source": "s43-permuter-ils", "residual": null, "passes_tried": null}
|
||||
{"ts": "2026-08-05 16:17:15", "addr": "0x8017C6F4", "name": "func_8017C6F4", "reach": 3, "klass": "regalloc: register rotation; hand 63 -> ILS 42 (pin-free seed) -> ILS 41 (pin-t5 seed); both basins plateau", "nins": 947, "status": "near", "closeness": 41, "where_stuck": "ov_SC03_126; BEST KNOWN. permuter ILS from the pin-t5 seed, masked 43, flat over 5 warm restarts", "best_draft": ".run/s43/func_8017C6F4.ils43-pin.c", "binary": "ov_SC03_126", "source": "s43-permuter-ils", "residual": null, "passes_tried": null}
|
||||
{"ts": "2026-08-05 16:38:43", "addr": "0x8017EF68", "name": "func_8017EF68", "reach": 1, "klass": "SCHEDULE-REORDER/2: sched2 INSN_LUID tie, lw $v0,0($s3) vs srl $a2,$a1,16 transposed; hand levers documented spent in the draft header; permuter ILS plateaus at 2 (6 cycles)", "nins": 969, "status": "near", "closeness": 2, "where_stuck": "ov_SC06_000 (the 970-ins variant; ov_SC03_007's is a DIFFERENT 12-ins body at the same addr)", "best_draft": ".run/drafts-p30beh/func_8017EF68.c", "binary": "ov_SC06_000", "source": "s43-rescan", "residual": null, "passes_tried": null}
|
||||
{"ts": "2026-08-05 17:07:03", "addr": "0x8017C6F4", "name": "func_8017C6F4", "reach": 4, "klass": "SOLVED: per-pass variables + prim-loop clamp reuse (cookbook \u00a7150); NOT an allocator tie", "nins": 947, "status": "matched", "closeness": 0, "where_stuck": "BANKED x4 (SC03_126/003, SC04_021, SC05_019) pending R22 clean-fleet", "best_draft": ".run/s43/fable/8017C6F4/v2_rtu.c", "binary": "ov_SC03_126", "source": "s43-fable", "residual": null, "passes_tried": null}
|
||||
|
||||
+8
-4
@@ -1293,7 +1293,7 @@ ov_SC03_003_ELF := $(ov_SC03_003_OUT).elf
|
||||
ov_SC03_003_MAPFILE := $(ov_SC03_003_OUT).map
|
||||
ov_SC03_003_LD_SCRIPT := $(ov_SC03_003_OUT).ld
|
||||
ov_SC03_003_SPLAT_YAML := config/splat.ov_SC03_003.yaml
|
||||
ov_SC03_003_JTBL_INTERLEAVE := --order tail.data.o,ov_SC03_003.o,ov_SC03_003_jr_8012ACE0.o,tail2.data.o,ov_SC03_003_jr_80135888.o,tail3.data.o,ov_SC03_003_jr_80135A4C.o,tail4.data.o,ov_SC03_003_jr_80135D20.o,tail5.data.o,ov_SC03_003_jr_801380E0.o,ov_SC03_003_o0c.o,tail6.data.o,ov_SC03_003_jr_8013F350.o,tail7.data.o,ov_SC03_003_jr_8013FFD8.o,tail8.data.o,ov_SC03_003_jr_80140608.o,tail9.data.o,ov_SC03_003_jr_8015444C.o,ov_SC03_003_jr_80154C24.o,ov_SC03_003_jr_801588CC.o,ov_SC03_003_jr_80159C84.o,tail10.data.o,ov_SC03_003_jr_8015A3C8.o,tail11.data.o,ov_SC03_003_jr_8015AE2C.o,tail12.data.o,ov_SC03_003_jr_8015C32C.o,tail13.data.o,ov_SC03_003_jr_8016AB6C.o,tail14.data.o,ov_SC03_003_jr_80171B4C.o,ov_SC03_003_jr_801734BC.o,tail15.data.o,ov_SC03_003_jr_801789AC.o,ov_SC03_003_jr_80178D40.o,tail16.data.o,ov_SC03_003_jr_8017A4AC.o,tail17.data.o,ov_SC03_003_jr_8017AE2C.o,tail18.data.o,ov_SC03_003_jr_8017D5C0.o,tail19.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
|
||||
ov_SC03_003_JTBL_INTERLEAVE := --order tail.data.o,ov_SC03_003.o,ov_SC03_003_jr_8012ACE0.o,tail2.data.o,ov_SC03_003_jr_80135888.o,tail3.data.o,ov_SC03_003_jr_80135A4C.o,tail4.data.o,ov_SC03_003_jr_80135D20.o,tail5.data.o,ov_SC03_003_jr_801380E0.o,ov_SC03_003_o0c.o,tail6.data.o,ov_SC03_003_jr_8013F350.o,tail7.data.o,ov_SC03_003_jr_8013FFD8.o,tail8.data.o,ov_SC03_003_jr_80140608.o,tail9.data.o,ov_SC03_003_jr_8015444C.o,ov_SC03_003_jr_80154C24.o,ov_SC03_003_jr_801588CC.o,ov_SC03_003_jr_80159C84.o,tail10.data.o,ov_SC03_003_jr_8015A3C8.o,tail11.data.o,ov_SC03_003_jr_8015AE2C.o,tail12.data.o,ov_SC03_003_jr_8015C32C.o,tail13.data.o,ov_SC03_003_jr_8016AB6C.o,tail14.data.o,ov_SC03_003_jr_80171B4C.o,ov_SC03_003_jr_801734BC.o,tail15.data.o,ov_SC03_003_jr_801789AC.o,ov_SC03_003_jr_80178D40.o,tail16.data.o,ov_SC03_003_jr_8017A4AC.o,tail17.data.o,ov_SC03_003_jr_8017AE2C.o,ov_SC03_003_jr_8017D5C0.o,tail18.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
|
||||
build/src/ov_SC03_003/ov_SC03_003.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x14
|
||||
build/src/ov_SC03_003/ov_SC03_003_jr_8012ACE0.o: JTBL_PADS := 0,0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0xcc,+0xe0
|
||||
build/src/ov_SC03_003/ov_SC03_003_jr_80135D20.o: JTBL_PADS := 0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x18
|
||||
@@ -1306,6 +1306,7 @@ build/src/ov_SC03_003/ov_SC03_003_jr_80159C84.o: JTBL_PADS := 0,4 # §8e pads (
|
||||
build/src/ov_SC03_003/ov_SC03_003_jr_8015AE2C.o: JTBL_PADS := 0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20
|
||||
build/src/ov_SC03_003/ov_SC03_003_jr_8016AB6C.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20
|
||||
build/src/ov_SC03_003/ov_SC03_003_jr_80178D40.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x178
|
||||
build/src/ov_SC03_003/ov_SC03_003_jr_8017AE2C.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x14
|
||||
build/src/ov_SC03_003/ov_SC03_003_o0c.o: JTBL_PADS := 0,4,4,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x38,+0xa8,+0x118
|
||||
ov_SC03_003_CHECK_SHA := config/check.ov_SC03_003.sha
|
||||
ov_SC03_003_SYMBOLS := config/symbols.ov_SC03_003.txt
|
||||
@@ -2920,7 +2921,7 @@ ov_SC03_126_ELF := $(ov_SC03_126_OUT).elf
|
||||
ov_SC03_126_MAPFILE := $(ov_SC03_126_OUT).map
|
||||
ov_SC03_126_LD_SCRIPT := $(ov_SC03_126_OUT).ld
|
||||
ov_SC03_126_SPLAT_YAML := config/splat.ov_SC03_126.yaml
|
||||
ov_SC03_126_JTBL_INTERLEAVE := --order tail.data.o,ov_SC03_126.o,ov_SC03_126_jr_8012ACE0.o,tail2.data.o,ov_SC03_126_jr_80135888.o,tail3.data.o,ov_SC03_126_jr_80135A4C.o,tail4.data.o,ov_SC03_126_jr_80135D20.o,tail5.data.o,ov_SC03_126_jr_801380E0.o,ov_SC03_126_o0c.o,tail6.data.o,ov_SC03_126_jr_8013F350.o,tail7.data.o,ov_SC03_126_jr_8013FFD8.o,tail8.data.o,ov_SC03_126_jr_80140608.o,tail9.data.o,ov_SC03_126_jr_8015444C.o,ov_SC03_126_jr_80154C24.o,ov_SC03_126_jr_801588CC.o,ov_SC03_126_jr_80159C84.o,tail10.data.o,ov_SC03_126_jr_8015A3C8.o,tail11.data.o,ov_SC03_126_jr_8015AE2C.o,tail12.data.o,ov_SC03_126_jr_8015C32C.o,tail13.data.o,ov_SC03_126_jr_8016AB6C.o,tail14.data.o,ov_SC03_126_jr_80171B4C.o,ov_SC03_126_jr_801734BC.o,tail15.data.o,ov_SC03_126_jr_801789AC.o,ov_SC03_126_jr_80178D40.o,tail16.data.o,ov_SC03_126_jr_8017A4AC.o,tail17.data.o,ov_SC03_126_jr_8017AE2C.o,tail18.data.o,ov_SC03_126_jr_8017D5C0.o,tail19.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
|
||||
ov_SC03_126_JTBL_INTERLEAVE := --order tail.data.o,ov_SC03_126.o,ov_SC03_126_jr_8012ACE0.o,tail2.data.o,ov_SC03_126_jr_80135888.o,tail3.data.o,ov_SC03_126_jr_80135A4C.o,tail4.data.o,ov_SC03_126_jr_80135D20.o,tail5.data.o,ov_SC03_126_jr_801380E0.o,ov_SC03_126_o0c.o,tail6.data.o,ov_SC03_126_jr_8013F350.o,tail7.data.o,ov_SC03_126_jr_8013FFD8.o,tail8.data.o,ov_SC03_126_jr_80140608.o,tail9.data.o,ov_SC03_126_jr_8015444C.o,ov_SC03_126_jr_80154C24.o,ov_SC03_126_jr_801588CC.o,ov_SC03_126_jr_80159C84.o,tail10.data.o,ov_SC03_126_jr_8015A3C8.o,tail11.data.o,ov_SC03_126_jr_8015AE2C.o,tail12.data.o,ov_SC03_126_jr_8015C32C.o,tail13.data.o,ov_SC03_126_jr_8016AB6C.o,tail14.data.o,ov_SC03_126_jr_80171B4C.o,ov_SC03_126_jr_801734BC.o,tail15.data.o,ov_SC03_126_jr_801789AC.o,ov_SC03_126_jr_80178D40.o,tail16.data.o,ov_SC03_126_jr_8017A4AC.o,tail17.data.o,ov_SC03_126_jr_8017AE2C.o,ov_SC03_126_jr_8017D5C0.o,tail18.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
|
||||
build/src/ov_SC03_126/ov_SC03_126.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x14
|
||||
build/src/ov_SC03_126/ov_SC03_126_jr_8012ACE0.o: JTBL_PADS := 0,0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0xcc,+0xe0
|
||||
build/src/ov_SC03_126/ov_SC03_126_jr_80135D20.o: JTBL_PADS := 0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x18
|
||||
@@ -2933,6 +2934,7 @@ build/src/ov_SC03_126/ov_SC03_126_jr_80159C84.o: JTBL_PADS := 0,4 # §8e pads (
|
||||
build/src/ov_SC03_126/ov_SC03_126_jr_8015AE2C.o: JTBL_PADS := 0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20
|
||||
build/src/ov_SC03_126/ov_SC03_126_jr_8016AB6C.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20
|
||||
build/src/ov_SC03_126/ov_SC03_126_jr_80178D40.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x178
|
||||
build/src/ov_SC03_126/ov_SC03_126_jr_8017AE2C.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x14
|
||||
build/src/ov_SC03_126/ov_SC03_126_o0c.o: JTBL_PADS := 0,4,4,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x38,+0xa8,+0x118
|
||||
ov_SC03_126_CHECK_SHA := config/check.ov_SC03_126.sha
|
||||
ov_SC03_126_SYMBOLS := config/symbols.ov_SC03_126.txt
|
||||
@@ -3449,7 +3451,7 @@ ov_SC04_021_ELF := $(ov_SC04_021_OUT).elf
|
||||
ov_SC04_021_MAPFILE := $(ov_SC04_021_OUT).map
|
||||
ov_SC04_021_LD_SCRIPT := $(ov_SC04_021_OUT).ld
|
||||
ov_SC04_021_SPLAT_YAML := config/splat.ov_SC04_021.yaml
|
||||
ov_SC04_021_JTBL_INTERLEAVE := --order tail.data.o,ov_SC04_021.o,ov_SC04_021_jr_8012ACE0.o,tail2.data.o,ov_SC04_021_jr_80135888.o,tail3.data.o,ov_SC04_021_jr_80135A4C.o,tail4.data.o,ov_SC04_021_jr_80135D20.o,tail5.data.o,ov_SC04_021_jr_801380E0.o,ov_SC04_021_o0c.o,tail6.data.o,ov_SC04_021_jr_8013F350.o,tail7.data.o,ov_SC04_021_jr_8013FFD8.o,tail8.data.o,ov_SC04_021_jr_80140608.o,tail9.data.o,ov_SC04_021_jr_8015444C.o,ov_SC04_021_jr_80154C24.o,ov_SC04_021_jr_801588CC.o,ov_SC04_021_jr_80159C84.o,tail10.data.o,ov_SC04_021_jr_8015A3C8.o,tail11.data.o,ov_SC04_021_jr_8015AE2C.o,tail12.data.o,ov_SC04_021_jr_8015C32C.o,tail13.data.o,ov_SC04_021_jr_8016AB6C.o,tail14.data.o,ov_SC04_021_jr_80171B4C.o,ov_SC04_021_jr_801734BC.o,tail15.data.o,ov_SC04_021_jr_801789AC.o,ov_SC04_021_jr_80178D40.o,tail16.data.o,ov_SC04_021_jr_8017A4AC.o,tail17.data.o,ov_SC04_021_jr_8017AE2C.o,tail18.data.o,ov_SC04_021_jr_8017D5C0.o,tail19.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
|
||||
ov_SC04_021_JTBL_INTERLEAVE := --order tail.data.o,ov_SC04_021.o,ov_SC04_021_jr_8012ACE0.o,tail2.data.o,ov_SC04_021_jr_80135888.o,tail3.data.o,ov_SC04_021_jr_80135A4C.o,tail4.data.o,ov_SC04_021_jr_80135D20.o,tail5.data.o,ov_SC04_021_jr_801380E0.o,ov_SC04_021_o0c.o,tail6.data.o,ov_SC04_021_jr_8013F350.o,tail7.data.o,ov_SC04_021_jr_8013FFD8.o,tail8.data.o,ov_SC04_021_jr_80140608.o,tail9.data.o,ov_SC04_021_jr_8015444C.o,ov_SC04_021_jr_80154C24.o,ov_SC04_021_jr_801588CC.o,ov_SC04_021_jr_80159C84.o,tail10.data.o,ov_SC04_021_jr_8015A3C8.o,tail11.data.o,ov_SC04_021_jr_8015AE2C.o,tail12.data.o,ov_SC04_021_jr_8015C32C.o,tail13.data.o,ov_SC04_021_jr_8016AB6C.o,tail14.data.o,ov_SC04_021_jr_80171B4C.o,ov_SC04_021_jr_801734BC.o,tail15.data.o,ov_SC04_021_jr_801789AC.o,ov_SC04_021_jr_80178D40.o,tail16.data.o,ov_SC04_021_jr_8017A4AC.o,tail17.data.o,ov_SC04_021_jr_8017AE2C.o,ov_SC04_021_jr_8017D5C0.o,tail18.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
|
||||
build/src/ov_SC04_021/ov_SC04_021.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x14
|
||||
build/src/ov_SC04_021/ov_SC04_021_jr_8012ACE0.o: JTBL_PADS := 0,0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0xcc,+0xe0
|
||||
build/src/ov_SC04_021/ov_SC04_021_jr_80135D20.o: JTBL_PADS := 0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x18
|
||||
@@ -3462,6 +3464,7 @@ build/src/ov_SC04_021/ov_SC04_021_jr_80159C84.o: JTBL_PADS := 0,4 # §8e pads (
|
||||
build/src/ov_SC04_021/ov_SC04_021_jr_8015AE2C.o: JTBL_PADS := 0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20
|
||||
build/src/ov_SC04_021/ov_SC04_021_jr_8016AB6C.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20
|
||||
build/src/ov_SC04_021/ov_SC04_021_jr_80178D40.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x178
|
||||
build/src/ov_SC04_021/ov_SC04_021_jr_8017AE2C.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x14
|
||||
build/src/ov_SC04_021/ov_SC04_021_o0c.o: JTBL_PADS := 0,4,4,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x38,+0xa8,+0x118
|
||||
ov_SC04_021_CHECK_SHA := config/check.ov_SC04_021.sha
|
||||
ov_SC04_021_SYMBOLS := config/symbols.ov_SC04_021.txt
|
||||
@@ -3942,7 +3945,7 @@ ov_SC05_019_ELF := $(ov_SC05_019_OUT).elf
|
||||
ov_SC05_019_MAPFILE := $(ov_SC05_019_OUT).map
|
||||
ov_SC05_019_LD_SCRIPT := $(ov_SC05_019_OUT).ld
|
||||
ov_SC05_019_SPLAT_YAML := config/splat.ov_SC05_019.yaml
|
||||
ov_SC05_019_JTBL_INTERLEAVE := --order tail.data.o,ov_SC05_019.o,ov_SC05_019_jr_8012ACE0.o,tail2.data.o,ov_SC05_019_jr_80135888.o,tail3.data.o,ov_SC05_019_jr_80135A4C.o,tail4.data.o,ov_SC05_019_jr_80135D20.o,tail5.data.o,ov_SC05_019_jr_801380E0.o,ov_SC05_019_o0c.o,tail6.data.o,ov_SC05_019_jr_8013F350.o,tail7.data.o,ov_SC05_019_jr_8013FFD8.o,tail8.data.o,ov_SC05_019_jr_80140608.o,tail9.data.o,ov_SC05_019_jr_8015444C.o,ov_SC05_019_jr_80154C24.o,ov_SC05_019_jr_801588CC.o,ov_SC05_019_jr_80159C84.o,tail10.data.o,ov_SC05_019_jr_8015A3C8.o,tail11.data.o,ov_SC05_019_jr_8015AE2C.o,tail12.data.o,ov_SC05_019_jr_8015C32C.o,tail13.data.o,ov_SC05_019_jr_8016AB6C.o,tail14.data.o,ov_SC05_019_jr_80171B4C.o,ov_SC05_019_jr_801734BC.o,tail15.data.o,ov_SC05_019_jr_801789AC.o,ov_SC05_019_jr_80178D40.o,tail16.data.o,ov_SC05_019_jr_8017A4AC.o,tail17.data.o,ov_SC05_019_jr_8017AE2C.o,tail18.data.o,ov_SC05_019_jr_8017D5C0.o,tail19.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
|
||||
ov_SC05_019_JTBL_INTERLEAVE := --order tail.data.o,ov_SC05_019.o,ov_SC05_019_jr_8012ACE0.o,tail2.data.o,ov_SC05_019_jr_80135888.o,tail3.data.o,ov_SC05_019_jr_80135A4C.o,tail4.data.o,ov_SC05_019_jr_80135D20.o,tail5.data.o,ov_SC05_019_jr_801380E0.o,ov_SC05_019_o0c.o,tail6.data.o,ov_SC05_019_jr_8013F350.o,tail7.data.o,ov_SC05_019_jr_8013FFD8.o,tail8.data.o,ov_SC05_019_jr_80140608.o,tail9.data.o,ov_SC05_019_jr_8015444C.o,ov_SC05_019_jr_80154C24.o,ov_SC05_019_jr_801588CC.o,ov_SC05_019_jr_80159C84.o,tail10.data.o,ov_SC05_019_jr_8015A3C8.o,tail11.data.o,ov_SC05_019_jr_8015AE2C.o,tail12.data.o,ov_SC05_019_jr_8015C32C.o,tail13.data.o,ov_SC05_019_jr_8016AB6C.o,tail14.data.o,ov_SC05_019_jr_80171B4C.o,ov_SC05_019_jr_801734BC.o,tail15.data.o,ov_SC05_019_jr_801789AC.o,ov_SC05_019_jr_80178D40.o,tail16.data.o,ov_SC05_019_jr_8017A4AC.o,tail17.data.o,ov_SC05_019_jr_8017AE2C.o,ov_SC05_019_jr_8017D5C0.o,tail18.data.o,trailing.o # Phase-26 §8 jtbl-rodata carve
|
||||
build/src/ov_SC05_019/ov_SC05_019.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x14
|
||||
build/src/ov_SC05_019/ov_SC05_019_jr_8012ACE0.o: JTBL_PADS := 0,0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0xcc,+0xe0
|
||||
build/src/ov_SC05_019/ov_SC05_019_jr_80135D20.o: JTBL_PADS := 0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x18
|
||||
@@ -3955,6 +3958,7 @@ build/src/ov_SC05_019/ov_SC05_019_jr_80159C84.o: JTBL_PADS := 0,4 # §8e pads (
|
||||
build/src/ov_SC05_019/ov_SC05_019_jr_8015AE2C.o: JTBL_PADS := 0,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20
|
||||
build/src/ov_SC05_019/ov_SC05_019_jr_8016AB6C.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x20
|
||||
build/src/ov_SC05_019/ov_SC05_019_jr_80178D40.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x178
|
||||
build/src/ov_SC05_019/ov_SC05_019_jr_8017AE2C.o: JTBL_PADS := 0,0 # §8e pads (jtbl_carve.py) tables=+0x0,+0x14
|
||||
build/src/ov_SC05_019/ov_SC05_019_o0c.o: JTBL_PADS := 0,4,4,4 # §8e pads (jtbl_carve.py) tables=+0x0,+0x38,+0xa8,+0x118
|
||||
ov_SC05_019_CHECK_SHA := config/check.ov_SC05_019.sha
|
||||
ov_SC05_019_SYMBOLS := config/symbols.ov_SC05_019.txt
|
||||
|
||||
@@ -162,9 +162,8 @@ segments:
|
||||
- [0x66488, .rodata, ov_SC03_003_jr_8017A4AC] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
|
||||
- [0x66514, data, tail17]
|
||||
- [0x66518, .rodata, ov_SC03_003_jr_8017AE2C] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
|
||||
- [0x6652c, data, tail18]
|
||||
- [0x6654c, .rodata, ov_SC03_003_jr_8017D5C0] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
|
||||
- [0x6656c, data, tail19]
|
||||
- [0x6656c, data, tail18]
|
||||
- [0x67A24, bin, trailing] # final 1 bytes (EOF not 4-aligned; spimdisasm drops a partial word)
|
||||
- [0x67A25] # EOF marker = the 0.4.dec byte length
|
||||
# @TRAILING@ (above) is replaced by tools/new_overlay.sh: for a non-4-aligned overlay it becomes
|
||||
|
||||
@@ -162,9 +162,8 @@ segments:
|
||||
- [0x6643c, .rodata, ov_SC03_126_jr_8017A4AC] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
|
||||
- [0x664c8, data, tail17]
|
||||
- [0x664cc, .rodata, ov_SC03_126_jr_8017AE2C] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
|
||||
- [0x664e0, data, tail18]
|
||||
- [0x66500, .rodata, ov_SC03_126_jr_8017D5C0] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
|
||||
- [0x66520, data, tail19]
|
||||
- [0x66520, data, tail18]
|
||||
- [0x679D4, bin, trailing] # final 1 bytes (EOF not 4-aligned; spimdisasm drops a partial word)
|
||||
- [0x679D5] # EOF marker = the 0.4.dec byte length
|
||||
# @TRAILING@ (above) is replaced by tools/new_overlay.sh: for a non-4-aligned overlay it becomes
|
||||
|
||||
@@ -162,9 +162,8 @@ segments:
|
||||
- [0x6643c, .rodata, ov_SC04_021_jr_8017A4AC] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
|
||||
- [0x664c8, data, tail17]
|
||||
- [0x664cc, .rodata, ov_SC04_021_jr_8017AE2C] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
|
||||
- [0x664e0, data, tail18]
|
||||
- [0x66500, .rodata, ov_SC04_021_jr_8017D5C0] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
|
||||
- [0x66520, data, tail19]
|
||||
- [0x66520, data, tail18]
|
||||
- [0x679D4, bin, trailing] # final 1 bytes (EOF not 4-aligned; spimdisasm drops a partial word)
|
||||
- [0x679D5] # EOF marker = the 0.4.dec byte length
|
||||
# @TRAILING@ (above) is replaced by tools/new_overlay.sh: for a non-4-aligned overlay it becomes
|
||||
|
||||
@@ -162,9 +162,8 @@ segments:
|
||||
- [0x6643c, .rodata, ov_SC05_019_jr_8017A4AC] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
|
||||
- [0x664c8, data, tail17]
|
||||
- [0x664cc, .rodata, ov_SC05_019_jr_8017AE2C] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
|
||||
- [0x664e0, data, tail18]
|
||||
- [0x66500, .rodata, ov_SC05_019_jr_8017D5C0] # Phase-26 §8 jtbl-rodata carve (jtbl_carve.py)
|
||||
- [0x66520, data, tail19]
|
||||
- [0x66520, data, tail18]
|
||||
- [0x679D4, bin, trailing] # final 1 bytes (EOF not 4-aligned; spimdisasm drops a partial word)
|
||||
- [0x679D5] # EOF marker = the 0.4.dec byte length
|
||||
# @TRAILING@ (above) is replaced by tools/new_overlay.sh: for a non-4-aligned overlay it becomes
|
||||
|
||||
+2
-2
@@ -2,12 +2,12 @@
|
||||
|
||||
> 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:** 837 · by status {'near': 797, 'failed': 40} · by class {'regalloc: qty_compare tie + stratum-3 frame slot (cookbook 147)': 1, 'regalloc: register rotation; hand 63 -> ILS 42 (pin-free seed) -> ILS 41 (pin-t5 seed); both basins plateau': 1, 'plumbing': 3, 'struct': 4, 'regalloc-order': 3, 'schedule': 2, 'loose-typing': 1, 'WAVE': 8, None: 804, 'SCHEDULE-REORDER/2: sched2 INSN_LUID tie, lw $v0,0($s3) vs srl $a2,$a1,16 transposed; hand levers documented spent in the draft header; permuter ILS plateaus at 2 (6 cycles)': 1, 'STRUCT': 9}
|
||||
**Open near-misses:** 837 · by status {'near': 796, 'matched': 1, 'failed': 40} · by class {'regalloc: qty_compare tie + stratum-3 frame slot (cookbook 147)': 1, 'SOLVED: per-pass variables + prim-loop clamp reuse (cookbook §150); NOT an allocator tie': 1, 'plumbing': 3, 'struct': 4, 'regalloc-order': 3, 'schedule': 2, 'loose-typing': 1, 'WAVE': 8, None: 804, 'SCHEDULE-REORDER/2: sched2 INSN_LUID tie, lw $v0,0($s3) vs srl $a2,$a1,16 transposed; hand levers documented spent in the draft header; permuter ILS plateaus at 2 (6 cycles)': 1, 'STRUCT': 9}
|
||||
|
||||
| # | addr | reach | class | nins | status | closeness | where it stuck | best draft |
|
||||
|--:|------|------:|-------|-----:|--------|----------:|----------------|------------|
|
||||
| 1 | func_8017C294 | 16 | regalloc: qty_compare tie + stratum-3 frame slot (cookbook 147) | 246 | near | 12 | ov_SC01_077 | `.run/s42/ov_SC01_077/func_8017C294.c` |
|
||||
| 2 | func_8017C6F4 | 3 | regalloc: register rotation; hand 63 -> ILS 42 (pin-free seed) -> ILS 41 (pin-t5 seed); both basins plateau | 947 | near | 41 | ov_SC03_126; BEST KNOWN. permuter ILS from the pin-t5 seed, masked 43, flat over 5 warm restarts | `.run/s43/func_8017C6F4.ils43-pin.c` |
|
||||
| 2 | func_8017C6F4 | 4 | SOLVED: per-pass variables + prim-loop clamp reuse (cookbook §150); NOT an allocator tie | 947 | matched | 0 | BANKED x4 (SC03_126/003, SC04_021, SC05_019) pending R22 clean-fleet | `.run/s43/fable/8017C6F4/v2_rtu.c` |
|
||||
| 3 | func_8017F714 | 1 | plumbing | 27 | near | 0 | none — MATCH (27/27 ins, match_one verified) | `.run/backlog_drafts/func_8017F714.c` |
|
||||
| 4 | func_8017E224 | 1 | struct | 29 | near | 0 | none — MATCH (unaligned 8-byte memcpy of global onto stack + cond byte incr) | `.run/backlog_drafts/func_8017E224.c` |
|
||||
| 5 | func_80184A68 | 1 | regalloc-order | 33 | near | 0 | none — MATCH | `.run/backlog_drafts/func_80184A68.c` |
|
||||
|
||||
@@ -10259,3 +10259,58 @@ it is scheduled — the probe here cost minutes and removed a phantom item from
|
||||
**Symptom lines for the index:** **"the permuter found no match in 0 seconds"** · **"a wall that only
|
||||
one tool reports"** · **"a backlog row that outranks a better result"** · **"CC1-FAIL: make: *** Error
|
||||
N"** · **"cheap fuel nobody has probed"**.
|
||||
|
||||
---
|
||||
|
||||
## §150 — A register ROTATION across symmetric blocks is VARIABLE-IDENTITY evidence, not an allocator tie (P30 S43, `func_8017C6F4`, 947 ins ×4)
|
||||
|
||||
The function that §147-E's signature fit perfectly — "structure exactly right, one register pair
|
||||
transposed, hand sweep and permuter plateau at the same number" — and the signature was **wrong about
|
||||
the cause**. Every lever aimed at the allocator was structurally inert because the draft had the wrong
|
||||
NUMBER OF PSEUDOS. Two coupled source-shape changes matched it pin-free.
|
||||
|
||||
### The fix
|
||||
1. **The X-pass and Y-pass min/max intermediates are DIFFERENT variables** — `xmn1/xmx1/xmn2/xmx2`
|
||||
*and* `ymn1/ymx1/ymn2/ymx2` (8, not 4 reused).
|
||||
2. **The cell-level clamp temps did not exist.** The original reuses the PRIM-LOOP variables:
|
||||
`mn/mx` for the cell X clamp, `mny/my` for the Y clamp.
|
||||
|
||||
**Neither half works alone** — split-only = 63 mismatched (which is exactly why a previous session's
|
||||
"separate X vs Y variables" probe was recorded as a failure), reuse-only = 624 + length drift, the
|
||||
conjunction = MATCH. **Ablate both ways before believing either half is wrong.**
|
||||
|
||||
### The method that found it (this is the transferable part)
|
||||
The diff's **matching** regions are a pseudo→register ownership map. Read the *mismatching* region's
|
||||
target registers against that map before touching the allocator:
|
||||
- **Different target registers for different instances of a symmetric block ⇒ per-instance
|
||||
variables.** gcc-2.7.2 does no live-range splitting: one pseudo holds one hard reg for life. So if
|
||||
the X pass uses `(a2,t1,a1,a3)` and the Y pass `(a3,t0,a1,a2)`, the original CANNOT have used one
|
||||
shared set — and no allocator steering on a shared-variable draft can ever reproduce it.
|
||||
- **Contested registers that coincide with a KNOWN variable's register ⇒ the region reuses that
|
||||
variable.** Here the four clamp registers were exactly the prim-loop `mn/mx/mny/my` registers,
|
||||
already byte-matched elsewhere in the function, with the right semantics per axis.
|
||||
- **A deleted self-move in ONE instance of a repeated block is a per-instance-variables tell.**
|
||||
`global_conflicts` processes `REG_DEAD` **before** `mark_reg_store` (`global.c:719` vs `:729`), so a
|
||||
copy whose source dies at that point records no conflict and the destination may be granted the
|
||||
source's register by ordinary first-fit — the copy then vanishes. A single shared pseudo can never
|
||||
be "same register as its source" in one pass and "different" in the other.
|
||||
|
||||
### Two corrections to the record
|
||||
- **§147-E named the wrong allocator.** The contested values here are multi-block and non-call-crossing
|
||||
⇒ **`global.c` allocnos**, not local `qty_compare` quantities. With the right variable identities,
|
||||
plain `allocno_compare` density order + first-fit reproduces every grant deterministically (full
|
||||
priority table in `.run/s43/fable/8017C6F4/NOTES.md`). Check WHICH allocator owns the value before
|
||||
citing a tie in it.
|
||||
- **§148's "residual is one register rotation, did not move under ~40 probes"** is explained: the
|
||||
probes were all allocator-shaped, and the defect was arithmetic — the wrong number of pseudos.
|
||||
Register pins, priority sliders (§148-C), declaration order and the permuter are all *inert* against
|
||||
a variable-identity error, which is why they agreed on a floor.
|
||||
|
||||
### Diagnostic order (adopt this)
|
||||
**Decode ownership → check pseudo COUNT and per-instance identity → only then reach for pins, sliders,
|
||||
statement order, or the permuter.** A rotation that survives every allocator lever is evidence about
|
||||
the VARIABLES, not about the allocator.
|
||||
|
||||
**Symptom lines for the index:** **"one register pair transposed"** · **"different registers in the X
|
||||
pass than the Y pass"** · **"a missing move / deleted copy in one of two symmetric blocks"** · **"every
|
||||
pin and slider is inert"** · **"hand sweep and permuter plateau at the same number"**.
|
||||
|
||||
@@ -2286,6 +2286,46 @@ read of the scheduler is exactly this class) — that needs Drew's go (R27).
|
||||
near-miss; `func_8017CE58`'s only draft is Ghidra-C and CC1-FAILs. **Re-derive every queue entry's size
|
||||
and home from the bytes before briefing an agent on it** — the list's annotations are unreliable.
|
||||
|
||||
### ▶ S43-6 — `func_8017C6F4` CRACKED by Fable5, pin-free, and banked ×4 (~3,788 ins) (2026-08-05)
|
||||
Drew approved the Fable5 escalation (R27). Two isolated agents, one per function, never batched.
|
||||
|
||||
**RESULT: byte-exact, pin-free, 947 ins — and my diagnosis was wrong.** I had this filed as §147-E, a
|
||||
`qty_compare` tie unreachable from source. It was **variable-identity evidence** all along:
|
||||
1. the X-pass and Y-pass min/max intermediates are **different variables** (8, not 4 reused);
|
||||
2. `mnc`/`mxc` **do not exist** — the cell clamps reuse the PRIM-LOOP `mn/mx` (X) and `mny/my` (Y).
|
||||
Ablations prove the conjunction is required: split-only **63**, reuse-only **624**, both = MATCH.
|
||||
That also explains why S42's "separate X vs Y variables" probe was recorded as a failure — it was
|
||||
half the fix. And why every allocator lever was inert (pins, §148-C sliders, declaration order, 14
|
||||
permuter restarts): **the draft had the wrong NUMBER OF PSEUDOS**, which no allocator steering reaches.
|
||||
|
||||
**Verified independently before believing it (R14):** `match_one` MATCH (947 ins) re-run by me, then
|
||||
the whole-binary gate.
|
||||
|
||||
**BANKED ×4 — every 948-ins sibling of this body:**
|
||||
| binary | SHA (byte-identical) |
|
||||
|---|---|
|
||||
| ov_SC03_126 | `c48a8bb894974dd3746a5833a20ee6da2feb831f` |
|
||||
| ov_SC03_003 | `898bf52a903dcb74ce11d2a8389c483ecc24e49e` |
|
||||
| ov_SC04_021 | `336142349b39ea4f5139b035fdb1ca8d8e7961c8` |
|
||||
| ov_SC05_019 | `3f5b4f132ed3ca63522d75c4021033b9d32b7a39` |
|
||||
`family_remap` produced all three siblings cleanly (SC03_003 remapped 4 per-overlay symbols; the other
|
||||
two needed none). **≈3,788 instructions.** ⚠️ These are INCREMENTAL-build gates — R22 clean-fleet is
|
||||
owed before the commit is trustworthy (§130: an incremental build can pass what a clean build cannot
|
||||
even link). Deferred only because the second Fable5 agent is reading `asm/` and `make clean` would
|
||||
destroy its inputs mid-run.
|
||||
|
||||
**The propagation gotcha (§146, seen again):** all three siblings first failed the gate with
|
||||
`PLUMBING: parse error before 'MTX_C6F4'` — `family_remap`'s `_carry_macros` carries `#define`s but
|
||||
**not typedefs**. Prepending the 9 typedef lines to each remapped draft fixed all three.
|
||||
**Worth noting: that label is legible only because of this session's classifier fix — before it, this
|
||||
would have read `CC1-FAIL: make: *** Error N` and cost three manual splice-and-rebuild diagnoses.**
|
||||
|
||||
**Idiom distilled → cookbook §150** (a register rotation across symmetric blocks is variable-identity
|
||||
evidence; decode ownership from the MATCHING diff regions first; per-instance register asymmetry ⇒
|
||||
per-instance variables; a deleted self-move in one of two symmetric blocks is the tell; and the
|
||||
`global.c:719`-vs-`:729` death-before-store exemption that produces it). §147-E corrected: it named
|
||||
the wrong allocator — these are `global.c` allocnos, not local `qty_compare` quantities.
|
||||
|
||||
### ▶ S11 — the propagation lag: EXTEND 0/36 -> 31/36, and every blocker was a DECLARATION (2026-08-03/04)
|
||||
Lane 2 of the S10 checkpoint ("26,006 ins, ~0 agent tokens, PARTLY BLOCKED"), taken first on the
|
||||
standing doctrine that the cheap deterministic lever is probed before the expensive agent one.
|
||||
|
||||
@@ -3402,4 +3402,469 @@ void func_8017C688(s32 a0, s32 a1) {
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_003/nonmatchings/ov_SC03_003_jr_8017AE2C", func_8017C6F4);
|
||||
typedef struct { u32 w0, w1, w2; } Prim126;
|
||||
typedef struct { u8 *vtx; u32 f4; u32 xx, yy, zz; Prim126 *prim, *end; } Cell126;
|
||||
typedef struct { s16 vx, vy; } DVEC2_C6F4;
|
||||
typedef struct { s16 vx, vy, vz, pad; } SVEC2_C6F4;
|
||||
typedef struct { s16 m[3][3]; s32 t[3]; } MTX_C6F4;
|
||||
typedef struct { u32 tag, rgbc; s16 x0, y0, x1, y1, x2, y2; } PF3_C6F4;
|
||||
typedef struct { u32 tag, rgbc; s16 x0, y0, x1, y1, x2, y2, x3, y3; } PF4_C6F4;
|
||||
typedef struct { u32 tag, rgbc; s16 x0, y0; u32 uvc0; s16 x1, y1; u32 uvp1; s16 x2, y2; u16 uv2, p2; } PFT3_C6F4;
|
||||
typedef struct { u32 tag, rgbc; s16 x0, y0; u32 uvc0; s16 x1, y1; u32 uvp1; s16 x2, y2; u16 uv2, p2; s16 x3, y3; u16 uv3, p3; } PFT4_C6F4;
|
||||
|
||||
#define gte_ldv0(r0) __asm__ volatile ( \
|
||||
"lwc2 $0, 0( %0 );" \
|
||||
"lwc2 $1, 4( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) )
|
||||
#define gte_ldv3(r0, r1, r2) __asm__ volatile ( \
|
||||
"lwc2 $0, 0( %0 );" \
|
||||
"lwc2 $1, 4( %0 );" \
|
||||
"lwc2 $2, 0( %1 );" \
|
||||
"lwc2 $3, 4( %1 );" \
|
||||
"lwc2 $4, 0( %2 );" \
|
||||
"lwc2 $5, 4( %2 )" \
|
||||
: \
|
||||
: "r"( r0 ), "r"( r1 ), "r"( r2 ) )
|
||||
#define gte_ldv3c(r0) __asm__ volatile ( \
|
||||
"lwc2 $0, 0( %0 );" \
|
||||
"lwc2 $1, 4( %0 );" \
|
||||
"lwc2 $2, 8( %0 );" \
|
||||
"lwc2 $3, 12( %0 );" \
|
||||
"lwc2 $4, 16( %0 );" \
|
||||
"lwc2 $5, 20( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) )
|
||||
#define gte_rtps() __asm__ volatile ("nop;nop;rtps")
|
||||
#define gte_rtpt() __asm__ volatile ("nop;nop;rtpt")
|
||||
#define gte_nclip() __asm__ volatile ("nop;nop;nclip")
|
||||
#define gte_avsz3() __asm__ volatile ("nop;nop;avsz3")
|
||||
#define gte_avsz4() __asm__ volatile ("nop;nop;avsz4")
|
||||
#define gte_stsxy(r0) __asm__ volatile ( \
|
||||
"swc2 $14, 0( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "memory" )
|
||||
#define gte_stsxy3(r0, r1, r2) __asm__ volatile ( \
|
||||
"swc2 $12, 0( %0 );" \
|
||||
"swc2 $13, 0( %1 );" \
|
||||
"swc2 $14, 0( %2 )" \
|
||||
: \
|
||||
: "r"( r0 ), "r"( r1 ), "r"( r2 ) \
|
||||
: "memory" )
|
||||
#define gte_stsxy3c(r0) __asm__ volatile ( \
|
||||
"swc2 $12, 0( %0 );" \
|
||||
"swc2 $13, 4( %0 );" \
|
||||
"swc2 $14, 8( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "memory" )
|
||||
#define gte_stsxy3_f3(r0) __asm__ volatile ( \
|
||||
"swc2 $12, 8( %0 );" \
|
||||
"swc2 $13, 12( %0 );" \
|
||||
"swc2 $14, 16( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "memory" )
|
||||
#define gte_stsz3(r0, r1, r2) __asm__ volatile ( \
|
||||
"swc2 $17, 0( %0 );" \
|
||||
"swc2 $18, 0( %1 );" \
|
||||
"swc2 $19, 0( %2 )" \
|
||||
: \
|
||||
: "r"( r0 ), "r"( r1 ), "r"( r2 ) \
|
||||
: "memory" )
|
||||
#define gte_stsz4(r0, r1, r2, r3) __asm__ volatile ( \
|
||||
"swc2 $16, 0( %0 );" \
|
||||
"swc2 $17, 0( %1 );" \
|
||||
"swc2 $18, 0( %2 );" \
|
||||
"swc2 $19, 0( %3 )" \
|
||||
: \
|
||||
: "r"( r0 ), "r"( r1 ), "r"( r2 ), "r"( r3 ) \
|
||||
: "memory" )
|
||||
#define gte_stflg(r0) __asm__ volatile ( \
|
||||
"cfc2 $12, $31;" \
|
||||
"nop;" \
|
||||
"sw $12, 0( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "$12", "memory" )
|
||||
#define gte_stopz(r0) __asm__ volatile ( \
|
||||
"swc2 $24, 0( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "memory" )
|
||||
|
||||
void func_8017C6F4(s32 arg0)
|
||||
{
|
||||
extern s32 func_800491EC(void);
|
||||
extern void func_800547D8(s32, MTX_C6F4 *);
|
||||
extern void func_80052E38(MTX_C6F4 *);
|
||||
extern void func_8017C014(void *, void *, s32);
|
||||
extern u8 D_8018FA10[];
|
||||
extern u8 *D_800A5E60;
|
||||
extern u8 D_800A6610[];
|
||||
extern short D_800B9A02;
|
||||
|
||||
s16 rect[4];
|
||||
DVEC2_C6F4 tmpxy[4];
|
||||
SVEC2_C6F4 box[8];
|
||||
SVEC2_C6F4 sxy[8];
|
||||
MTX_C6F4 mtx;
|
||||
struct { long flag, opz, sz0, sz1, sz2, sz3; } g;
|
||||
|
||||
s32 cx0, cx1, cy0, cy1, y, col;
|
||||
Cell126 **rowptr;
|
||||
Cell126 **p;
|
||||
Cell126 *cell;
|
||||
Prim126 *prim;
|
||||
Prim126 *end;
|
||||
u8 *pkt;
|
||||
u32 ot;
|
||||
u8 *vtx;
|
||||
u8 *va, *vb, *vc, *vd;
|
||||
u32 w, code;
|
||||
u32 wx, wy, wz;
|
||||
u32 xlo, xhi, ylo, yhi, zlo, zhi;
|
||||
s32 xa32, xb32, t32;
|
||||
s32 xmn1, xmx1, xmn2, xmx2;
|
||||
s32 ymn1, ymx1, ymn2, ymx2;
|
||||
s32 my, mny, mx, mn;
|
||||
|
||||
func_800491EC();
|
||||
func_800547D8(arg0 + 0x10, &mtx);
|
||||
func_80052E38(&mtx);
|
||||
func_8017C014(D_8018FA10, rect, *(s32 *)(arg0 + 0x60));
|
||||
|
||||
pkt = D_800A5E60;
|
||||
ot = (u32)&D_800A6610[(*(u16 *)&D_800B9A02) << 14];
|
||||
|
||||
cx0 = (rect[0] + 0x4000) / 512;
|
||||
cx1 = (rect[0] + rect[2] + 0x4000) / 512 + 2;
|
||||
cx0 = (cx0 < 0) ? 0 : ((cx0 > 0x3F) ? 0x3F : cx0);
|
||||
cx1 = (cx1 < 0) ? 0 : ((cx1 > 0x3F) ? 0x3F : cx1);
|
||||
cy0 = (rect[1] + 0x4000) / 512 - 1;
|
||||
cy1 = (rect[1] + rect[3] + 0x4000) / 512 + 2;
|
||||
cy0 = (cy0 < 0) ? 0 : ((cy0 > 0x3F) ? 0x3F : cy0);
|
||||
cy1 = (cy1 < 0) ? 0 : ((cy1 > 0x3F) ? 0x3F : cy1);
|
||||
|
||||
rowptr = (Cell126 **)(*(s32 *)(arg0 + 0xC)) + (cy0 * 64 + cx0);
|
||||
|
||||
for (y = cy0; y < cy1; y++, rowptr += 0x40) {
|
||||
for (col = cx0, p = rowptr; col < cx1; col++, p++) {
|
||||
cell = *p;
|
||||
if (cell == 0) continue;
|
||||
|
||||
wx = cell->xx;
|
||||
xlo = wx & 0xFFFF;
|
||||
xhi = wx >> 16;
|
||||
wy = cell->yy;
|
||||
ylo = wy & 0xFFFF;
|
||||
yhi = wy >> 16;
|
||||
wz = cell->zz;
|
||||
zlo = wz & 0xFFFF;
|
||||
zhi = wz >> 16;
|
||||
|
||||
box[0].vx = xlo; box[0].vy = ylo; box[0].vz = zlo;
|
||||
box[1].vx = xhi; box[1].vy = ylo; box[1].vz = zlo;
|
||||
box[2].vx = xlo; box[2].vy = ylo; box[2].vz = zhi;
|
||||
box[3].vx = xhi; box[3].vy = ylo; box[3].vz = zhi;
|
||||
box[4].vx = xlo; box[4].vy = yhi; box[4].vz = zlo;
|
||||
box[5].vx = xhi; box[5].vy = yhi; box[5].vz = zlo;
|
||||
box[6].vx = xlo; box[6].vy = yhi; box[6].vz = zhi;
|
||||
box[7].vx = xhi; box[7].vy = yhi; box[7].vz = zhi;
|
||||
|
||||
gte_ldv3c(&box[0]);
|
||||
gte_rtpt();
|
||||
gte_stsxy3(&sxy[0], &sxy[1], &sxy[2]);
|
||||
gte_ldv0(&box[3]);
|
||||
gte_rtps();
|
||||
gte_stsxy(&sxy[3]);
|
||||
gte_ldv3c(&box[4]);
|
||||
gte_rtpt();
|
||||
gte_stsxy3(&sxy[4], &sxy[5], &sxy[6]);
|
||||
gte_ldv0(&box[7]);
|
||||
gte_rtps();
|
||||
gte_stsxy(&sxy[7]);
|
||||
|
||||
xa32 = sxy[0].vx;
|
||||
xb32 = sxy[1].vx;
|
||||
if (xb32 < xa32) { xmx1 = xa32; xmn1 = xb32; } else { xmn1 = xa32; xmx1 = xb32; }
|
||||
t32 = sxy[2].vx;
|
||||
if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32;
|
||||
t32 = sxy[3].vx;
|
||||
if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32;
|
||||
xa32 = sxy[4].vx;
|
||||
xb32 = sxy[5].vx;
|
||||
if (xb32 < xa32) { xmx2 = xa32; xmn2 = xb32; } else { xmn2 = xa32; xmx2 = xb32; }
|
||||
t32 = sxy[6].vx;
|
||||
if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32;
|
||||
t32 = sxy[7].vx;
|
||||
if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32;
|
||||
mn = xmn1;
|
||||
if (xmn2 < mn) mn = xmn2;
|
||||
mx = xmx1;
|
||||
if (mx < xmx2) mx = xmx2;
|
||||
if (mx < -0xA0) continue;
|
||||
if (!(mn < 0xA1)) continue;
|
||||
|
||||
xa32 = sxy[0].vy;
|
||||
xb32 = sxy[1].vy;
|
||||
if (xb32 < xa32) { ymx1 = xa32; ymn1 = xb32; } else { ymn1 = xa32; ymx1 = xb32; }
|
||||
t32 = sxy[2].vy;
|
||||
if (ymx1 < t32) ymx1 = t32; else if (t32 < ymn1) ymn1 = t32;
|
||||
t32 = sxy[3].vy;
|
||||
if (ymx1 < t32) ymx1 = t32; else if (t32 < ymn1) ymn1 = t32;
|
||||
xa32 = sxy[4].vy;
|
||||
xb32 = sxy[5].vy;
|
||||
if (xb32 < xa32) { ymx2 = xa32; ymn2 = xb32; } else { ymn2 = xa32; ymx2 = xb32; }
|
||||
t32 = sxy[6].vy;
|
||||
if (ymx2 < t32) ymx2 = t32; else if (t32 < ymn2) ymn2 = t32;
|
||||
t32 = sxy[7].vy;
|
||||
if (ymx2 < t32) ymx2 = t32; else if (t32 < ymn2) ymn2 = t32;
|
||||
mny = ymn1;
|
||||
if (ymn2 < mny) mny = ymn2;
|
||||
my = ymx1;
|
||||
if (my < ymx2) my = ymx2;
|
||||
if (my < -0x78) continue;
|
||||
if (!(mny < 0x79)) continue;
|
||||
|
||||
prim = cell->prim;
|
||||
end = cell->end;
|
||||
vtx = cell->vtx;
|
||||
while (prim < end) {
|
||||
w = prim->w1;
|
||||
va = vtx + (w & 0xFFFF);
|
||||
vb = vtx + (w >> 16);
|
||||
w = prim->w2;
|
||||
vc = vtx + (w & 0xFFFF);
|
||||
w = w >> 16;
|
||||
gte_ldv3(va, vb, vc);
|
||||
gte_rtpt();
|
||||
gte_stflg(&g.flag);
|
||||
if (!(g.flag & 0x7F85E000)) {
|
||||
gte_nclip();
|
||||
code = w & 0xF;
|
||||
vd = vtx + ((w & 0xFFF0) >> 1);
|
||||
gte_stopz(&g.opz);
|
||||
if (g.opz > 0) {
|
||||
switch (code) {
|
||||
case 4:
|
||||
case 5:
|
||||
gte_stsxy3_f3(pkt);
|
||||
gte_stsz3(&g.sz0, &g.sz1, &g.sz2);
|
||||
if (((PFT3_C6F4 *)pkt)->x0 > ((PFT3_C6F4 *)pkt)->x1) {
|
||||
mx = ((PFT3_C6F4 *)pkt)->x0;
|
||||
mn = ((PFT3_C6F4 *)pkt)->x1;
|
||||
} else {
|
||||
mn = ((PFT3_C6F4 *)pkt)->x0;
|
||||
mx = ((PFT3_C6F4 *)pkt)->x1;
|
||||
}
|
||||
if (((PFT3_C6F4 *)pkt)->x2 > mx) mx = ((PFT3_C6F4 *)pkt)->x2;
|
||||
else if (((PFT3_C6F4 *)pkt)->x2 < mn) mn = ((PFT3_C6F4 *)pkt)->x2;
|
||||
if (mx >= -0xA0 && mn < 0xA1) {
|
||||
if (((PFT3_C6F4 *)pkt)->y0 > ((PFT3_C6F4 *)pkt)->y1) {
|
||||
my = ((PFT3_C6F4 *)pkt)->y0;
|
||||
mny = ((PFT3_C6F4 *)pkt)->y1;
|
||||
} else {
|
||||
mny = ((PFT3_C6F4 *)pkt)->y0;
|
||||
my = ((PFT3_C6F4 *)pkt)->y1;
|
||||
}
|
||||
if (((PFT3_C6F4 *)pkt)->y2 > my) my = ((PFT3_C6F4 *)pkt)->y2;
|
||||
else if (((PFT3_C6F4 *)pkt)->y2 < mny) mny = ((PFT3_C6F4 *)pkt)->y2;
|
||||
if (my >= -0x78 && mny < 0x79) {
|
||||
s32 za;
|
||||
u32 *otp;
|
||||
if (g.sz0 > g.sz1) {
|
||||
za = g.sz0;
|
||||
if (za < g.sz2) za = g.sz2;
|
||||
} else {
|
||||
za = g.sz1;
|
||||
if (za < g.sz2) za = g.sz2;
|
||||
}
|
||||
g.opz = za;
|
||||
if (code != 4) g.opz = za + 0x200;
|
||||
((PF3_C6F4 *)pkt)->rgbc = prim->w0;
|
||||
otp = (u32 *)(((g.opz >> 2) << 2) + ot);
|
||||
*(u32 *)pkt = (*otp & 0xFFFFFF) | 0x4000000;
|
||||
*otp = (*otp & 0xFF000000) | ((u32)pkt & 0xFFFFFF);
|
||||
pkt += 0x14;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
gte_stsxy3c(&tmpxy[0]);
|
||||
gte_stsz3(&g.sz0, &g.sz1, &g.sz2);
|
||||
if (tmpxy[0].vx > tmpxy[1].vx) {
|
||||
mx = tmpxy[0].vx;
|
||||
mn = tmpxy[1].vx;
|
||||
} else {
|
||||
mn = tmpxy[0].vx;
|
||||
mx = tmpxy[1].vx;
|
||||
}
|
||||
if (tmpxy[2].vx > mx) mx = tmpxy[2].vx;
|
||||
else if (tmpxy[2].vx < mn) mn = tmpxy[2].vx;
|
||||
if (mx >= -0xA0 && mn < 0xA1) {
|
||||
if (tmpxy[0].vy > tmpxy[1].vy) {
|
||||
my = tmpxy[0].vy;
|
||||
mny = tmpxy[1].vy;
|
||||
} else {
|
||||
mny = tmpxy[0].vy;
|
||||
my = tmpxy[1].vy;
|
||||
}
|
||||
if (tmpxy[2].vy > my) my = tmpxy[2].vy;
|
||||
else if (tmpxy[2].vy < mny) mny = tmpxy[2].vy;
|
||||
if (my >= -0x78 && mny < 0x79) {
|
||||
s32 za;
|
||||
u32 *otp;
|
||||
u32 *tp;
|
||||
gte_avsz3();
|
||||
if (g.sz0 > g.sz1) {
|
||||
za = g.sz0;
|
||||
if (za < g.sz2) za = g.sz2;
|
||||
} else {
|
||||
za = g.sz1;
|
||||
if (za < g.sz2) za = g.sz2;
|
||||
}
|
||||
g.opz = za;
|
||||
if (code != 6) g.opz = za + 0x200;
|
||||
*(u32 *)&((PFT3_C6F4 *)pkt)->x0 = *(u32 *)&tmpxy[0];
|
||||
*(u32 *)&((PFT3_C6F4 *)pkt)->x1 = *(u32 *)&tmpxy[1];
|
||||
*(u32 *)&((PFT3_C6F4 *)pkt)->x2 = *(u32 *)&tmpxy[2];
|
||||
tp = (u32 *)prim->w0;
|
||||
((PFT3_C6F4 *)pkt)->rgbc = tp[0];
|
||||
((PFT3_C6F4 *)pkt)->uvc0 = tp[1];
|
||||
((PFT3_C6F4 *)pkt)->uvp1 = tp[2];
|
||||
((PFT3_C6F4 *)pkt)->uv2 = tp[3];
|
||||
otp = (u32 *)(((g.opz >> 2) << 2) + ot);
|
||||
*(u32 *)pkt = (*otp & 0xFFFFFF) | 0x7000000;
|
||||
*otp = (*otp & 0xFF000000) | ((u32)pkt & 0xFFFFFF);
|
||||
pkt += 0x20;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
case 1:
|
||||
gte_stsxy3_f3(pkt);
|
||||
gte_ldv0(vd);
|
||||
gte_rtps();
|
||||
if (((PF4_C6F4 *)pkt)->x0 > ((PF4_C6F4 *)pkt)->x1) {
|
||||
mx = ((PF4_C6F4 *)pkt)->x0;
|
||||
mn = ((PF4_C6F4 *)pkt)->x1;
|
||||
} else {
|
||||
mn = ((PF4_C6F4 *)pkt)->x0;
|
||||
mx = ((PF4_C6F4 *)pkt)->x1;
|
||||
}
|
||||
if (((PF4_C6F4 *)pkt)->x2 > mx) mx = ((PF4_C6F4 *)pkt)->x2;
|
||||
else if (((PF4_C6F4 *)pkt)->x2 < mn) mn = ((PF4_C6F4 *)pkt)->x2;
|
||||
if (((PF4_C6F4 *)pkt)->y0 > ((PF4_C6F4 *)pkt)->y1) {
|
||||
my = ((PF4_C6F4 *)pkt)->y0;
|
||||
mny = ((PF4_C6F4 *)pkt)->y1;
|
||||
} else {
|
||||
mny = ((PF4_C6F4 *)pkt)->y0;
|
||||
my = ((PF4_C6F4 *)pkt)->y1;
|
||||
}
|
||||
if (((PF4_C6F4 *)pkt)->y2 > my) my = ((PF4_C6F4 *)pkt)->y2;
|
||||
else if (((PF4_C6F4 *)pkt)->y2 < mny) mny = ((PF4_C6F4 *)pkt)->y2;
|
||||
gte_stflg(&g.flag);
|
||||
if (!(g.flag & 0x7F85E000)) {
|
||||
gte_stsz4(&g.sz0, &g.sz1, &g.sz2, &g.sz3);
|
||||
gte_stsxy((long *)&((PF4_C6F4 *)pkt)->x3);
|
||||
if (((PF4_C6F4 *)pkt)->x3 < mn) mn = ((PF4_C6F4 *)pkt)->x3;
|
||||
else if (mx < ((PF4_C6F4 *)pkt)->x3) mx = ((PF4_C6F4 *)pkt)->x3;
|
||||
if (mx >= -0xA0 && mn < 0xA1) {
|
||||
if (((PF4_C6F4 *)pkt)->y3 < mny) mny = ((PF4_C6F4 *)pkt)->y3;
|
||||
else if (my < ((PF4_C6F4 *)pkt)->y3) my = ((PF4_C6F4 *)pkt)->y3;
|
||||
if (my >= -0x78 && mny < 0x79) {
|
||||
s32 za, zb;
|
||||
u32 *otp;
|
||||
zb = g.sz2;
|
||||
if (zb < g.sz3) zb = g.sz3;
|
||||
za = g.sz0;
|
||||
if (za < g.sz1) za = g.sz1;
|
||||
if (za < zb) za = zb;
|
||||
g.opz = za;
|
||||
if (code != 0) g.opz = za + 0x200;
|
||||
((PF4_C6F4 *)pkt)->rgbc = prim->w0;
|
||||
otp = (u32 *)(((g.opz >> 2) << 2) + ot);
|
||||
*(u32 *)pkt = (*otp & 0xFFFFFF) | 0x5000000;
|
||||
*otp = (*otp & 0xFF000000) | ((u32)pkt & 0xFFFFFF);
|
||||
pkt += 0x18;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
gte_stsxy3c(&tmpxy[0]);
|
||||
gte_ldv0(vd);
|
||||
gte_rtps();
|
||||
gte_stflg(&g.flag);
|
||||
if (!(g.flag & 0x7F85E000)) {
|
||||
gte_stsxy(&tmpxy[3]);
|
||||
gte_stsz4(&g.sz0, &g.sz1, &g.sz2, &g.sz3);
|
||||
if (tmpxy[0].vx > tmpxy[1].vx) {
|
||||
mx = tmpxy[0].vx;
|
||||
mn = tmpxy[1].vx;
|
||||
} else {
|
||||
mn = tmpxy[0].vx;
|
||||
mx = tmpxy[1].vx;
|
||||
}
|
||||
if (tmpxy[2].vx > mx) mx = tmpxy[2].vx;
|
||||
else if (tmpxy[2].vx < mn) mn = tmpxy[2].vx;
|
||||
if (tmpxy[3].vx > mx) mx = tmpxy[3].vx;
|
||||
else if (tmpxy[3].vx < mn) mn = tmpxy[3].vx;
|
||||
if (mx >= -0xA0 && mn < 0xA1) {
|
||||
if (tmpxy[0].vy > tmpxy[1].vy) {
|
||||
my = tmpxy[0].vy;
|
||||
mny = tmpxy[1].vy;
|
||||
} else {
|
||||
mny = tmpxy[0].vy;
|
||||
my = tmpxy[1].vy;
|
||||
}
|
||||
if (tmpxy[2].vy > my) my = tmpxy[2].vy;
|
||||
else if (tmpxy[2].vy < mny) mny = tmpxy[2].vy;
|
||||
if (tmpxy[3].vx > my) my = tmpxy[3].vx;
|
||||
else if (tmpxy[3].vx < mny) mny = tmpxy[3].vx;
|
||||
if (my >= -0x78 && mny < 0x79) {
|
||||
s32 za, zb;
|
||||
u32 *otp;
|
||||
u32 *tp;
|
||||
u32 uvw;
|
||||
gte_avsz4();
|
||||
zb = g.sz2;
|
||||
if (zb < g.sz3) zb = g.sz3;
|
||||
za = g.sz0;
|
||||
if (za < g.sz1) za = g.sz1;
|
||||
if (za < zb) za = zb;
|
||||
g.opz = za;
|
||||
if (code != 2) g.opz = za + 0x200;
|
||||
*(u32 *)&((PFT4_C6F4 *)pkt)->x0 = *(u32 *)&tmpxy[0];
|
||||
*(u32 *)&((PFT4_C6F4 *)pkt)->x1 = *(u32 *)&tmpxy[1];
|
||||
*(u32 *)&((PFT4_C6F4 *)pkt)->x2 = *(u32 *)&tmpxy[2];
|
||||
*(u32 *)&((PFT4_C6F4 *)pkt)->x3 = *(u32 *)&tmpxy[3];
|
||||
tp = (u32 *)prim->w0;
|
||||
((PFT4_C6F4 *)pkt)->rgbc = tp[0];
|
||||
((PFT4_C6F4 *)pkt)->uvc0 = tp[1];
|
||||
((PFT4_C6F4 *)pkt)->uvp1 = tp[2];
|
||||
uvw = tp[3];
|
||||
((PFT4_C6F4 *)pkt)->uv2 = uvw;
|
||||
((PFT4_C6F4 *)pkt)->uv3 = uvw >> 16;
|
||||
otp = (u32 *)(((g.opz >> 2) << 2) + ot);
|
||||
*(u32 *)pkt = (*otp & 0xFFFFFF) | 0x9000000;
|
||||
*otp = (*otp & 0xFF000000) | ((u32)pkt & 0xFFFFFF);
|
||||
pkt += 0x28;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
prim++;
|
||||
}
|
||||
}
|
||||
}
|
||||
D_800A5E60 = pkt;
|
||||
}
|
||||
|
||||
|
||||
@@ -3401,5 +3401,503 @@ void func_8017C688(s32 a0, s32 a1) {
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC03_126/nonmatchings/ov_SC03_126_jr_8017AE2C", func_8017C6F4);
|
||||
#include "common.h"
|
||||
|
||||
/* func_8017C6F4 — ov_SC03_126_jr_8017AE2C — MAP-TILE model renderer (947 ins).
|
||||
* Sibling of the matched func_8017BEBC (952 ins, §47) and func_8017CDF0.
|
||||
* Outer: screen rect -> 64x64 cell grid window -> per-cell bbox RTPT/RTPS cull.
|
||||
* Inner: per-prim RTPT -> flag/nclip/opz cull -> switch(w & 0xF):
|
||||
* 0,1=POLY_F4 / 2,3=POLY_FT4 / 4,5=POLY_F3 / 6,7=POLY_FT3 -> OT insert.
|
||||
* NOTE: the F3 arm bbox-tests the packet through PFT3_C6F4 offsets (8/0x10/0x18)
|
||||
* — a source-level copy/paste quirk of this variant, reproduced verbatim.
|
||||
*
|
||||
* MATCH (947 ins, pin-free) — s43 Fable crack. Two load-bearing source shapes
|
||||
* (byte-proven; see .run/s43/fable/8017C6F4/NOTES.md):
|
||||
* 1. X-pass and Y-pass bbox min/max intermediates are DISTINCT variables
|
||||
* (xmn1..xmx2 vs ymn1..ymx2) — the target allocates them differently.
|
||||
* 2. The cell-level clamps REUSE the prim-loop vars (mn/mx for X, mny/my
|
||||
* for Y); there are no separate mnc/mxc. This puts the clamps in
|
||||
* $t0/$a2/$a3/$a1 and makes the Y-pass `mny = ymn1` a deleted self-move.
|
||||
* Neither change matches alone (63 / 624 mismatches); prim lands $t5 and
|
||||
* cell $t3 naturally once the bbox block allocates right.
|
||||
*/
|
||||
|
||||
typedef struct { u32 w0, w1, w2; } Prim126;
|
||||
typedef struct { u8 *vtx; u32 f4; u32 xx, yy, zz; Prim126 *prim, *end; } Cell126;
|
||||
|
||||
typedef struct { s16 vx, vy; } DVEC2_C6F4;
|
||||
typedef struct { s16 vx, vy, vz, pad; } SVEC2_C6F4;
|
||||
typedef struct { s16 m[3][3]; s32 t[3]; } MTX_C6F4;
|
||||
typedef struct { u32 tag, rgbc; s16 x0, y0, x1, y1, x2, y2; } PF3_C6F4;
|
||||
typedef struct { u32 tag, rgbc; s16 x0, y0, x1, y1, x2, y2, x3, y3; } PF4_C6F4;
|
||||
typedef struct { u32 tag, rgbc; s16 x0, y0; u32 uvc0; s16 x1, y1; u32 uvp1; s16 x2, y2; u16 uv2, p2; } PFT3_C6F4;
|
||||
typedef struct { u32 tag, rgbc; s16 x0, y0; u32 uvc0; s16 x1, y1; u32 uvp1; s16 x2, y2; u16 uv2, p2; s16 x3, y3; u16 uv3, p3; } PFT4_C6F4;
|
||||
|
||||
#define gte_ldv0(r0) __asm__ volatile ( \
|
||||
"lwc2 $0, 0( %0 );" \
|
||||
"lwc2 $1, 4( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) )
|
||||
|
||||
#define gte_ldv3(r0, r1, r2) __asm__ volatile ( \
|
||||
"lwc2 $0, 0( %0 );" \
|
||||
"lwc2 $1, 4( %0 );" \
|
||||
"lwc2 $2, 0( %1 );" \
|
||||
"lwc2 $3, 4( %1 );" \
|
||||
"lwc2 $4, 0( %2 );" \
|
||||
"lwc2 $5, 4( %2 )" \
|
||||
: \
|
||||
: "r"( r0 ), "r"( r1 ), "r"( r2 ) )
|
||||
|
||||
#define gte_ldv3c(r0) __asm__ volatile ( \
|
||||
"lwc2 $0, 0( %0 );" \
|
||||
"lwc2 $1, 4( %0 );" \
|
||||
"lwc2 $2, 8( %0 );" \
|
||||
"lwc2 $3, 12( %0 );" \
|
||||
"lwc2 $4, 16( %0 );" \
|
||||
"lwc2 $5, 20( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) )
|
||||
|
||||
#define gte_rtps() __asm__ volatile ("nop;nop;rtps")
|
||||
#define gte_rtpt() __asm__ volatile ("nop;nop;rtpt")
|
||||
#define gte_nclip() __asm__ volatile ("nop;nop;nclip")
|
||||
#define gte_avsz3() __asm__ volatile ("nop;nop;avsz3")
|
||||
#define gte_avsz4() __asm__ volatile ("nop;nop;avsz4")
|
||||
|
||||
#define gte_stsxy(r0) __asm__ volatile ( \
|
||||
"swc2 $14, 0( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "memory" )
|
||||
|
||||
#define gte_stsxy3(r0, r1, r2) __asm__ volatile ( \
|
||||
"swc2 $12, 0( %0 );" \
|
||||
"swc2 $13, 0( %1 );" \
|
||||
"swc2 $14, 0( %2 )" \
|
||||
: \
|
||||
: "r"( r0 ), "r"( r1 ), "r"( r2 ) \
|
||||
: "memory" )
|
||||
|
||||
#define gte_stsxy3c(r0) __asm__ volatile ( \
|
||||
"swc2 $12, 0( %0 );" \
|
||||
"swc2 $13, 4( %0 );" \
|
||||
"swc2 $14, 8( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "memory" )
|
||||
|
||||
#define gte_stsxy3_f3(r0) __asm__ volatile ( \
|
||||
"swc2 $12, 8( %0 );" \
|
||||
"swc2 $13, 12( %0 );" \
|
||||
"swc2 $14, 16( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "memory" )
|
||||
|
||||
#define gte_stsz3(r0, r1, r2) __asm__ volatile ( \
|
||||
"swc2 $17, 0( %0 );" \
|
||||
"swc2 $18, 0( %1 );" \
|
||||
"swc2 $19, 0( %2 )" \
|
||||
: \
|
||||
: "r"( r0 ), "r"( r1 ), "r"( r2 ) \
|
||||
: "memory" )
|
||||
|
||||
#define gte_stsz4(r0, r1, r2, r3) __asm__ volatile ( \
|
||||
"swc2 $16, 0( %0 );" \
|
||||
"swc2 $17, 0( %1 );" \
|
||||
"swc2 $18, 0( %2 );" \
|
||||
"swc2 $19, 0( %3 )" \
|
||||
: \
|
||||
: "r"( r0 ), "r"( r1 ), "r"( r2 ), "r"( r3 ) \
|
||||
: "memory" )
|
||||
|
||||
#define gte_stflg(r0) __asm__ volatile ( \
|
||||
"cfc2 $12, $31;" \
|
||||
"nop;" \
|
||||
"sw $12, 0( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "$12", "memory" )
|
||||
|
||||
#define gte_stopz(r0) __asm__ volatile ( \
|
||||
"swc2 $24, 0( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "memory" )
|
||||
|
||||
void func_8017C6F4(s32 arg0)
|
||||
{
|
||||
extern s32 func_800491EC(void);
|
||||
extern void func_800547D8(s32, MTX_C6F4 *);
|
||||
extern void func_80052E38(MTX_C6F4 *);
|
||||
extern void func_8017C014(void *, void *, s32);
|
||||
extern u8 D_8018F9C0[];
|
||||
extern u8 *D_800A5E60;
|
||||
extern u8 D_800A6610[];
|
||||
extern short D_800B9A02;
|
||||
|
||||
s16 rect[4];
|
||||
DVEC2_C6F4 tmpxy[4];
|
||||
SVEC2_C6F4 box[8];
|
||||
SVEC2_C6F4 sxy[8];
|
||||
MTX_C6F4 mtx;
|
||||
struct { long flag, opz, sz0, sz1, sz2, sz3; } g;
|
||||
|
||||
s32 cx0, cx1, cy0, cy1, y, col;
|
||||
Cell126 **rowptr;
|
||||
Cell126 **p;
|
||||
Cell126 *cell;
|
||||
Prim126 *prim;
|
||||
Prim126 *end;
|
||||
u8 *pkt;
|
||||
u32 ot;
|
||||
u8 *vtx;
|
||||
u8 *va, *vb, *vc, *vd;
|
||||
u32 w, code;
|
||||
u32 wx, wy, wz;
|
||||
u32 xlo, xhi, ylo, yhi, zlo, zhi;
|
||||
s32 xa32, xb32, t32;
|
||||
s32 xmn1, xmx1, xmn2, xmx2;
|
||||
s32 ymn1, ymx1, ymn2, ymx2;
|
||||
s32 my, mny, mx, mn;
|
||||
|
||||
func_800491EC();
|
||||
func_800547D8(arg0 + 0x10, &mtx);
|
||||
func_80052E38(&mtx);
|
||||
func_8017C014(D_8018F9C0, rect, *(s32 *)(arg0 + 0x60));
|
||||
|
||||
pkt = D_800A5E60;
|
||||
ot = (u32)&D_800A6610[(*(u16 *)&D_800B9A02) << 14];
|
||||
|
||||
cx0 = (rect[0] + 0x4000) / 512;
|
||||
cx1 = (rect[0] + rect[2] + 0x4000) / 512 + 2;
|
||||
cx0 = (cx0 < 0) ? 0 : ((cx0 > 0x3F) ? 0x3F : cx0);
|
||||
cx1 = (cx1 < 0) ? 0 : ((cx1 > 0x3F) ? 0x3F : cx1);
|
||||
cy0 = (rect[1] + 0x4000) / 512 - 1;
|
||||
cy1 = (rect[1] + rect[3] + 0x4000) / 512 + 2;
|
||||
cy0 = (cy0 < 0) ? 0 : ((cy0 > 0x3F) ? 0x3F : cy0);
|
||||
cy1 = (cy1 < 0) ? 0 : ((cy1 > 0x3F) ? 0x3F : cy1);
|
||||
|
||||
rowptr = (Cell126 **)(*(s32 *)(arg0 + 0xC)) + (cy0 * 64 + cx0);
|
||||
|
||||
for (y = cy0; y < cy1; y++, rowptr += 0x40) {
|
||||
for (col = cx0, p = rowptr; col < cx1; col++, p++) {
|
||||
cell = *p;
|
||||
if (cell == 0) continue;
|
||||
|
||||
wx = cell->xx;
|
||||
xlo = wx & 0xFFFF;
|
||||
xhi = wx >> 16;
|
||||
wy = cell->yy;
|
||||
ylo = wy & 0xFFFF;
|
||||
yhi = wy >> 16;
|
||||
wz = cell->zz;
|
||||
zlo = wz & 0xFFFF;
|
||||
zhi = wz >> 16;
|
||||
|
||||
box[0].vx = xlo; box[0].vy = ylo; box[0].vz = zlo;
|
||||
box[1].vx = xhi; box[1].vy = ylo; box[1].vz = zlo;
|
||||
box[2].vx = xlo; box[2].vy = ylo; box[2].vz = zhi;
|
||||
box[3].vx = xhi; box[3].vy = ylo; box[3].vz = zhi;
|
||||
box[4].vx = xlo; box[4].vy = yhi; box[4].vz = zlo;
|
||||
box[5].vx = xhi; box[5].vy = yhi; box[5].vz = zlo;
|
||||
box[6].vx = xlo; box[6].vy = yhi; box[6].vz = zhi;
|
||||
box[7].vx = xhi; box[7].vy = yhi; box[7].vz = zhi;
|
||||
|
||||
gte_ldv3c(&box[0]);
|
||||
gte_rtpt();
|
||||
gte_stsxy3(&sxy[0], &sxy[1], &sxy[2]);
|
||||
gte_ldv0(&box[3]);
|
||||
gte_rtps();
|
||||
gte_stsxy(&sxy[3]);
|
||||
gte_ldv3c(&box[4]);
|
||||
gte_rtpt();
|
||||
gte_stsxy3(&sxy[4], &sxy[5], &sxy[6]);
|
||||
gte_ldv0(&box[7]);
|
||||
gte_rtps();
|
||||
gte_stsxy(&sxy[7]);
|
||||
|
||||
xa32 = sxy[0].vx;
|
||||
xb32 = sxy[1].vx;
|
||||
if (xb32 < xa32) { xmx1 = xa32; xmn1 = xb32; } else { xmn1 = xa32; xmx1 = xb32; }
|
||||
t32 = sxy[2].vx;
|
||||
if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32;
|
||||
t32 = sxy[3].vx;
|
||||
if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32;
|
||||
xa32 = sxy[4].vx;
|
||||
xb32 = sxy[5].vx;
|
||||
if (xb32 < xa32) { xmx2 = xa32; xmn2 = xb32; } else { xmn2 = xa32; xmx2 = xb32; }
|
||||
t32 = sxy[6].vx;
|
||||
if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32;
|
||||
t32 = sxy[7].vx;
|
||||
if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32;
|
||||
mn = xmn1;
|
||||
if (xmn2 < mn) mn = xmn2;
|
||||
mx = xmx1;
|
||||
if (mx < xmx2) mx = xmx2;
|
||||
if (mx < -0xA0) continue;
|
||||
if (!(mn < 0xA1)) continue;
|
||||
|
||||
xa32 = sxy[0].vy;
|
||||
xb32 = sxy[1].vy;
|
||||
if (xb32 < xa32) { ymx1 = xa32; ymn1 = xb32; } else { ymn1 = xa32; ymx1 = xb32; }
|
||||
t32 = sxy[2].vy;
|
||||
if (ymx1 < t32) ymx1 = t32; else if (t32 < ymn1) ymn1 = t32;
|
||||
t32 = sxy[3].vy;
|
||||
if (ymx1 < t32) ymx1 = t32; else if (t32 < ymn1) ymn1 = t32;
|
||||
xa32 = sxy[4].vy;
|
||||
xb32 = sxy[5].vy;
|
||||
if (xb32 < xa32) { ymx2 = xa32; ymn2 = xb32; } else { ymn2 = xa32; ymx2 = xb32; }
|
||||
t32 = sxy[6].vy;
|
||||
if (ymx2 < t32) ymx2 = t32; else if (t32 < ymn2) ymn2 = t32;
|
||||
t32 = sxy[7].vy;
|
||||
if (ymx2 < t32) ymx2 = t32; else if (t32 < ymn2) ymn2 = t32;
|
||||
mny = ymn1;
|
||||
if (ymn2 < mny) mny = ymn2;
|
||||
my = ymx1;
|
||||
if (my < ymx2) my = ymx2;
|
||||
if (my < -0x78) continue;
|
||||
if (!(mny < 0x79)) continue;
|
||||
|
||||
prim = cell->prim;
|
||||
end = cell->end;
|
||||
vtx = cell->vtx;
|
||||
while (prim < end) {
|
||||
w = prim->w1;
|
||||
va = vtx + (w & 0xFFFF);
|
||||
vb = vtx + (w >> 16);
|
||||
w = prim->w2;
|
||||
vc = vtx + (w & 0xFFFF);
|
||||
w = w >> 16;
|
||||
gte_ldv3(va, vb, vc);
|
||||
gte_rtpt();
|
||||
gte_stflg(&g.flag);
|
||||
if (!(g.flag & 0x7F85E000)) {
|
||||
gte_nclip();
|
||||
code = w & 0xF;
|
||||
vd = vtx + ((w & 0xFFF0) >> 1);
|
||||
gte_stopz(&g.opz);
|
||||
if (g.opz > 0) {
|
||||
switch (code) {
|
||||
case 4:
|
||||
case 5:
|
||||
gte_stsxy3_f3(pkt);
|
||||
gte_stsz3(&g.sz0, &g.sz1, &g.sz2);
|
||||
if (((PFT3_C6F4 *)pkt)->x0 > ((PFT3_C6F4 *)pkt)->x1) {
|
||||
mx = ((PFT3_C6F4 *)pkt)->x0;
|
||||
mn = ((PFT3_C6F4 *)pkt)->x1;
|
||||
} else {
|
||||
mn = ((PFT3_C6F4 *)pkt)->x0;
|
||||
mx = ((PFT3_C6F4 *)pkt)->x1;
|
||||
}
|
||||
if (((PFT3_C6F4 *)pkt)->x2 > mx) mx = ((PFT3_C6F4 *)pkt)->x2;
|
||||
else if (((PFT3_C6F4 *)pkt)->x2 < mn) mn = ((PFT3_C6F4 *)pkt)->x2;
|
||||
if (mx >= -0xA0 && mn < 0xA1) {
|
||||
if (((PFT3_C6F4 *)pkt)->y0 > ((PFT3_C6F4 *)pkt)->y1) {
|
||||
my = ((PFT3_C6F4 *)pkt)->y0;
|
||||
mny = ((PFT3_C6F4 *)pkt)->y1;
|
||||
} else {
|
||||
mny = ((PFT3_C6F4 *)pkt)->y0;
|
||||
my = ((PFT3_C6F4 *)pkt)->y1;
|
||||
}
|
||||
if (((PFT3_C6F4 *)pkt)->y2 > my) my = ((PFT3_C6F4 *)pkt)->y2;
|
||||
else if (((PFT3_C6F4 *)pkt)->y2 < mny) mny = ((PFT3_C6F4 *)pkt)->y2;
|
||||
if (my >= -0x78 && mny < 0x79) {
|
||||
s32 za;
|
||||
u32 *otp;
|
||||
if (g.sz0 > g.sz1) {
|
||||
za = g.sz0;
|
||||
if (za < g.sz2) za = g.sz2;
|
||||
} else {
|
||||
za = g.sz1;
|
||||
if (za < g.sz2) za = g.sz2;
|
||||
}
|
||||
g.opz = za;
|
||||
if (code != 4) g.opz = za + 0x200;
|
||||
((PF3_C6F4 *)pkt)->rgbc = prim->w0;
|
||||
otp = (u32 *)(((g.opz >> 2) << 2) + ot);
|
||||
*(u32 *)pkt = (*otp & 0xFFFFFF) | 0x4000000;
|
||||
*otp = (*otp & 0xFF000000) | ((u32)pkt & 0xFFFFFF);
|
||||
pkt += 0x14;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
gte_stsxy3c(&tmpxy[0]);
|
||||
gte_stsz3(&g.sz0, &g.sz1, &g.sz2);
|
||||
if (tmpxy[0].vx > tmpxy[1].vx) {
|
||||
mx = tmpxy[0].vx;
|
||||
mn = tmpxy[1].vx;
|
||||
} else {
|
||||
mn = tmpxy[0].vx;
|
||||
mx = tmpxy[1].vx;
|
||||
}
|
||||
if (tmpxy[2].vx > mx) mx = tmpxy[2].vx;
|
||||
else if (tmpxy[2].vx < mn) mn = tmpxy[2].vx;
|
||||
if (mx >= -0xA0 && mn < 0xA1) {
|
||||
if (tmpxy[0].vy > tmpxy[1].vy) {
|
||||
my = tmpxy[0].vy;
|
||||
mny = tmpxy[1].vy;
|
||||
} else {
|
||||
mny = tmpxy[0].vy;
|
||||
my = tmpxy[1].vy;
|
||||
}
|
||||
if (tmpxy[2].vy > my) my = tmpxy[2].vy;
|
||||
else if (tmpxy[2].vy < mny) mny = tmpxy[2].vy;
|
||||
if (my >= -0x78 && mny < 0x79) {
|
||||
s32 za;
|
||||
u32 *otp;
|
||||
u32 *tp;
|
||||
gte_avsz3();
|
||||
if (g.sz0 > g.sz1) {
|
||||
za = g.sz0;
|
||||
if (za < g.sz2) za = g.sz2;
|
||||
} else {
|
||||
za = g.sz1;
|
||||
if (za < g.sz2) za = g.sz2;
|
||||
}
|
||||
g.opz = za;
|
||||
if (code != 6) g.opz = za + 0x200;
|
||||
*(u32 *)&((PFT3_C6F4 *)pkt)->x0 = *(u32 *)&tmpxy[0];
|
||||
*(u32 *)&((PFT3_C6F4 *)pkt)->x1 = *(u32 *)&tmpxy[1];
|
||||
*(u32 *)&((PFT3_C6F4 *)pkt)->x2 = *(u32 *)&tmpxy[2];
|
||||
tp = (u32 *)prim->w0;
|
||||
((PFT3_C6F4 *)pkt)->rgbc = tp[0];
|
||||
((PFT3_C6F4 *)pkt)->uvc0 = tp[1];
|
||||
((PFT3_C6F4 *)pkt)->uvp1 = tp[2];
|
||||
((PFT3_C6F4 *)pkt)->uv2 = tp[3];
|
||||
otp = (u32 *)(((g.opz >> 2) << 2) + ot);
|
||||
*(u32 *)pkt = (*otp & 0xFFFFFF) | 0x7000000;
|
||||
*otp = (*otp & 0xFF000000) | ((u32)pkt & 0xFFFFFF);
|
||||
pkt += 0x20;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
case 1:
|
||||
gte_stsxy3_f3(pkt);
|
||||
gte_ldv0(vd);
|
||||
gte_rtps();
|
||||
if (((PF4_C6F4 *)pkt)->x0 > ((PF4_C6F4 *)pkt)->x1) {
|
||||
mx = ((PF4_C6F4 *)pkt)->x0;
|
||||
mn = ((PF4_C6F4 *)pkt)->x1;
|
||||
} else {
|
||||
mn = ((PF4_C6F4 *)pkt)->x0;
|
||||
mx = ((PF4_C6F4 *)pkt)->x1;
|
||||
}
|
||||
if (((PF4_C6F4 *)pkt)->x2 > mx) mx = ((PF4_C6F4 *)pkt)->x2;
|
||||
else if (((PF4_C6F4 *)pkt)->x2 < mn) mn = ((PF4_C6F4 *)pkt)->x2;
|
||||
if (((PF4_C6F4 *)pkt)->y0 > ((PF4_C6F4 *)pkt)->y1) {
|
||||
my = ((PF4_C6F4 *)pkt)->y0;
|
||||
mny = ((PF4_C6F4 *)pkt)->y1;
|
||||
} else {
|
||||
mny = ((PF4_C6F4 *)pkt)->y0;
|
||||
my = ((PF4_C6F4 *)pkt)->y1;
|
||||
}
|
||||
if (((PF4_C6F4 *)pkt)->y2 > my) my = ((PF4_C6F4 *)pkt)->y2;
|
||||
else if (((PF4_C6F4 *)pkt)->y2 < mny) mny = ((PF4_C6F4 *)pkt)->y2;
|
||||
gte_stflg(&g.flag);
|
||||
if (!(g.flag & 0x7F85E000)) {
|
||||
gte_stsz4(&g.sz0, &g.sz1, &g.sz2, &g.sz3);
|
||||
gte_stsxy((long *)&((PF4_C6F4 *)pkt)->x3);
|
||||
if (((PF4_C6F4 *)pkt)->x3 < mn) mn = ((PF4_C6F4 *)pkt)->x3;
|
||||
else if (mx < ((PF4_C6F4 *)pkt)->x3) mx = ((PF4_C6F4 *)pkt)->x3;
|
||||
if (mx >= -0xA0 && mn < 0xA1) {
|
||||
if (((PF4_C6F4 *)pkt)->y3 < mny) mny = ((PF4_C6F4 *)pkt)->y3;
|
||||
else if (my < ((PF4_C6F4 *)pkt)->y3) my = ((PF4_C6F4 *)pkt)->y3;
|
||||
if (my >= -0x78 && mny < 0x79) {
|
||||
s32 za, zb;
|
||||
u32 *otp;
|
||||
zb = g.sz2;
|
||||
if (zb < g.sz3) zb = g.sz3;
|
||||
za = g.sz0;
|
||||
if (za < g.sz1) za = g.sz1;
|
||||
if (za < zb) za = zb;
|
||||
g.opz = za;
|
||||
if (code != 0) g.opz = za + 0x200;
|
||||
((PF4_C6F4 *)pkt)->rgbc = prim->w0;
|
||||
otp = (u32 *)(((g.opz >> 2) << 2) + ot);
|
||||
*(u32 *)pkt = (*otp & 0xFFFFFF) | 0x5000000;
|
||||
*otp = (*otp & 0xFF000000) | ((u32)pkt & 0xFFFFFF);
|
||||
pkt += 0x18;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
gte_stsxy3c(&tmpxy[0]);
|
||||
gte_ldv0(vd);
|
||||
gte_rtps();
|
||||
gte_stflg(&g.flag);
|
||||
if (!(g.flag & 0x7F85E000)) {
|
||||
gte_stsxy(&tmpxy[3]);
|
||||
gte_stsz4(&g.sz0, &g.sz1, &g.sz2, &g.sz3);
|
||||
if (tmpxy[0].vx > tmpxy[1].vx) {
|
||||
mx = tmpxy[0].vx;
|
||||
mn = tmpxy[1].vx;
|
||||
} else {
|
||||
mn = tmpxy[0].vx;
|
||||
mx = tmpxy[1].vx;
|
||||
}
|
||||
if (tmpxy[2].vx > mx) mx = tmpxy[2].vx;
|
||||
else if (tmpxy[2].vx < mn) mn = tmpxy[2].vx;
|
||||
if (tmpxy[3].vx > mx) mx = tmpxy[3].vx;
|
||||
else if (tmpxy[3].vx < mn) mn = tmpxy[3].vx;
|
||||
if (mx >= -0xA0 && mn < 0xA1) {
|
||||
if (tmpxy[0].vy > tmpxy[1].vy) {
|
||||
my = tmpxy[0].vy;
|
||||
mny = tmpxy[1].vy;
|
||||
} else {
|
||||
mny = tmpxy[0].vy;
|
||||
my = tmpxy[1].vy;
|
||||
}
|
||||
if (tmpxy[2].vy > my) my = tmpxy[2].vy;
|
||||
else if (tmpxy[2].vy < mny) mny = tmpxy[2].vy;
|
||||
if (tmpxy[3].vx > my) my = tmpxy[3].vx;
|
||||
else if (tmpxy[3].vx < mny) mny = tmpxy[3].vx;
|
||||
if (my >= -0x78 && mny < 0x79) {
|
||||
s32 za, zb;
|
||||
u32 *otp;
|
||||
u32 *tp;
|
||||
u32 uvw;
|
||||
gte_avsz4();
|
||||
zb = g.sz2;
|
||||
if (zb < g.sz3) zb = g.sz3;
|
||||
za = g.sz0;
|
||||
if (za < g.sz1) za = g.sz1;
|
||||
if (za < zb) za = zb;
|
||||
g.opz = za;
|
||||
if (code != 2) g.opz = za + 0x200;
|
||||
*(u32 *)&((PFT4_C6F4 *)pkt)->x0 = *(u32 *)&tmpxy[0];
|
||||
*(u32 *)&((PFT4_C6F4 *)pkt)->x1 = *(u32 *)&tmpxy[1];
|
||||
*(u32 *)&((PFT4_C6F4 *)pkt)->x2 = *(u32 *)&tmpxy[2];
|
||||
*(u32 *)&((PFT4_C6F4 *)pkt)->x3 = *(u32 *)&tmpxy[3];
|
||||
tp = (u32 *)prim->w0;
|
||||
((PFT4_C6F4 *)pkt)->rgbc = tp[0];
|
||||
((PFT4_C6F4 *)pkt)->uvc0 = tp[1];
|
||||
((PFT4_C6F4 *)pkt)->uvp1 = tp[2];
|
||||
uvw = tp[3];
|
||||
((PFT4_C6F4 *)pkt)->uv2 = uvw;
|
||||
((PFT4_C6F4 *)pkt)->uv3 = uvw >> 16;
|
||||
otp = (u32 *)(((g.opz >> 2) << 2) + ot);
|
||||
*(u32 *)pkt = (*otp & 0xFFFFFF) | 0x9000000;
|
||||
*otp = (*otp & 0xFF000000) | ((u32)pkt & 0xFFFFFF);
|
||||
pkt += 0x28;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
prim++;
|
||||
}
|
||||
}
|
||||
}
|
||||
D_800A5E60 = pkt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3401,5 +3401,470 @@ void func_8017C688(s32 a0, s32 a1) {
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC04_021/nonmatchings/ov_SC04_021_jr_8017AE2C", func_8017C6F4);
|
||||
typedef struct { u32 w0, w1, w2; } Prim126;
|
||||
typedef struct { u8 *vtx; u32 f4; u32 xx, yy, zz; Prim126 *prim, *end; } Cell126;
|
||||
typedef struct { s16 vx, vy; } DVEC2_C6F4;
|
||||
typedef struct { s16 vx, vy, vz, pad; } SVEC2_C6F4;
|
||||
typedef struct { s16 m[3][3]; s32 t[3]; } MTX_C6F4;
|
||||
typedef struct { u32 tag, rgbc; s16 x0, y0, x1, y1, x2, y2; } PF3_C6F4;
|
||||
typedef struct { u32 tag, rgbc; s16 x0, y0, x1, y1, x2, y2, x3, y3; } PF4_C6F4;
|
||||
typedef struct { u32 tag, rgbc; s16 x0, y0; u32 uvc0; s16 x1, y1; u32 uvp1; s16 x2, y2; u16 uv2, p2; } PFT3_C6F4;
|
||||
typedef struct { u32 tag, rgbc; s16 x0, y0; u32 uvc0; s16 x1, y1; u32 uvp1; s16 x2, y2; u16 uv2, p2; s16 x3, y3; u16 uv3, p3; } PFT4_C6F4;
|
||||
|
||||
#define gte_ldv0(r0) __asm__ volatile ( \
|
||||
"lwc2 $0, 0( %0 );" \
|
||||
"lwc2 $1, 4( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) )
|
||||
#define gte_ldv3(r0, r1, r2) __asm__ volatile ( \
|
||||
"lwc2 $0, 0( %0 );" \
|
||||
"lwc2 $1, 4( %0 );" \
|
||||
"lwc2 $2, 0( %1 );" \
|
||||
"lwc2 $3, 4( %1 );" \
|
||||
"lwc2 $4, 0( %2 );" \
|
||||
"lwc2 $5, 4( %2 )" \
|
||||
: \
|
||||
: "r"( r0 ), "r"( r1 ), "r"( r2 ) )
|
||||
#define gte_ldv3c(r0) __asm__ volatile ( \
|
||||
"lwc2 $0, 0( %0 );" \
|
||||
"lwc2 $1, 4( %0 );" \
|
||||
"lwc2 $2, 8( %0 );" \
|
||||
"lwc2 $3, 12( %0 );" \
|
||||
"lwc2 $4, 16( %0 );" \
|
||||
"lwc2 $5, 20( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) )
|
||||
#define gte_rtps() __asm__ volatile ("nop;nop;rtps")
|
||||
#define gte_rtpt() __asm__ volatile ("nop;nop;rtpt")
|
||||
#define gte_nclip() __asm__ volatile ("nop;nop;nclip")
|
||||
#define gte_avsz3() __asm__ volatile ("nop;nop;avsz3")
|
||||
#define gte_avsz4() __asm__ volatile ("nop;nop;avsz4")
|
||||
#define gte_stsxy(r0) __asm__ volatile ( \
|
||||
"swc2 $14, 0( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "memory" )
|
||||
#define gte_stsxy3(r0, r1, r2) __asm__ volatile ( \
|
||||
"swc2 $12, 0( %0 );" \
|
||||
"swc2 $13, 0( %1 );" \
|
||||
"swc2 $14, 0( %2 )" \
|
||||
: \
|
||||
: "r"( r0 ), "r"( r1 ), "r"( r2 ) \
|
||||
: "memory" )
|
||||
#define gte_stsxy3c(r0) __asm__ volatile ( \
|
||||
"swc2 $12, 0( %0 );" \
|
||||
"swc2 $13, 4( %0 );" \
|
||||
"swc2 $14, 8( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "memory" )
|
||||
#define gte_stsxy3_f3(r0) __asm__ volatile ( \
|
||||
"swc2 $12, 8( %0 );" \
|
||||
"swc2 $13, 12( %0 );" \
|
||||
"swc2 $14, 16( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "memory" )
|
||||
#define gte_stsz3(r0, r1, r2) __asm__ volatile ( \
|
||||
"swc2 $17, 0( %0 );" \
|
||||
"swc2 $18, 0( %1 );" \
|
||||
"swc2 $19, 0( %2 )" \
|
||||
: \
|
||||
: "r"( r0 ), "r"( r1 ), "r"( r2 ) \
|
||||
: "memory" )
|
||||
#define gte_stsz4(r0, r1, r2, r3) __asm__ volatile ( \
|
||||
"swc2 $16, 0( %0 );" \
|
||||
"swc2 $17, 0( %1 );" \
|
||||
"swc2 $18, 0( %2 );" \
|
||||
"swc2 $19, 0( %3 )" \
|
||||
: \
|
||||
: "r"( r0 ), "r"( r1 ), "r"( r2 ), "r"( r3 ) \
|
||||
: "memory" )
|
||||
#define gte_stflg(r0) __asm__ volatile ( \
|
||||
"cfc2 $12, $31;" \
|
||||
"nop;" \
|
||||
"sw $12, 0( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "$12", "memory" )
|
||||
#define gte_stopz(r0) __asm__ volatile ( \
|
||||
"swc2 $24, 0( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "memory" )
|
||||
|
||||
void func_8017C6F4(s32 arg0)
|
||||
{
|
||||
extern s32 func_800491EC(void);
|
||||
extern void func_800547D8(s32, MTX_C6F4 *);
|
||||
extern void func_80052E38(MTX_C6F4 *);
|
||||
extern void func_8017C014(void *, void *, s32);
|
||||
extern u8 D_8018F9C0[];
|
||||
extern u8 *D_800A5E60;
|
||||
extern u8 D_800A6610[];
|
||||
extern short D_800B9A02;
|
||||
|
||||
s16 rect[4];
|
||||
DVEC2_C6F4 tmpxy[4];
|
||||
SVEC2_C6F4 box[8];
|
||||
SVEC2_C6F4 sxy[8];
|
||||
MTX_C6F4 mtx;
|
||||
struct { long flag, opz, sz0, sz1, sz2, sz3; } g;
|
||||
|
||||
s32 cx0, cx1, cy0, cy1, y, col;
|
||||
Cell126 **rowptr;
|
||||
Cell126 **p;
|
||||
Cell126 *cell;
|
||||
Prim126 *prim;
|
||||
Prim126 *end;
|
||||
u8 *pkt;
|
||||
u32 ot;
|
||||
u8 *vtx;
|
||||
u8 *va, *vb, *vc, *vd;
|
||||
u32 w, code;
|
||||
u32 wx, wy, wz;
|
||||
u32 xlo, xhi, ylo, yhi, zlo, zhi;
|
||||
s32 xa32, xb32, t32;
|
||||
s32 xmn1, xmx1, xmn2, xmx2;
|
||||
s32 ymn1, ymx1, ymn2, ymx2;
|
||||
s32 my, mny, mx, mn;
|
||||
|
||||
func_800491EC();
|
||||
func_800547D8(arg0 + 0x10, &mtx);
|
||||
func_80052E38(&mtx);
|
||||
func_8017C014(D_8018F9C0, rect, *(s32 *)(arg0 + 0x60));
|
||||
|
||||
pkt = D_800A5E60;
|
||||
ot = (u32)&D_800A6610[(*(u16 *)&D_800B9A02) << 14];
|
||||
|
||||
cx0 = (rect[0] + 0x4000) / 512;
|
||||
cx1 = (rect[0] + rect[2] + 0x4000) / 512 + 2;
|
||||
cx0 = (cx0 < 0) ? 0 : ((cx0 > 0x3F) ? 0x3F : cx0);
|
||||
cx1 = (cx1 < 0) ? 0 : ((cx1 > 0x3F) ? 0x3F : cx1);
|
||||
cy0 = (rect[1] + 0x4000) / 512 - 1;
|
||||
cy1 = (rect[1] + rect[3] + 0x4000) / 512 + 2;
|
||||
cy0 = (cy0 < 0) ? 0 : ((cy0 > 0x3F) ? 0x3F : cy0);
|
||||
cy1 = (cy1 < 0) ? 0 : ((cy1 > 0x3F) ? 0x3F : cy1);
|
||||
|
||||
rowptr = (Cell126 **)(*(s32 *)(arg0 + 0xC)) + (cy0 * 64 + cx0);
|
||||
|
||||
for (y = cy0; y < cy1; y++, rowptr += 0x40) {
|
||||
for (col = cx0, p = rowptr; col < cx1; col++, p++) {
|
||||
cell = *p;
|
||||
if (cell == 0) continue;
|
||||
|
||||
wx = cell->xx;
|
||||
xlo = wx & 0xFFFF;
|
||||
xhi = wx >> 16;
|
||||
wy = cell->yy;
|
||||
ylo = wy & 0xFFFF;
|
||||
yhi = wy >> 16;
|
||||
wz = cell->zz;
|
||||
zlo = wz & 0xFFFF;
|
||||
zhi = wz >> 16;
|
||||
|
||||
box[0].vx = xlo; box[0].vy = ylo; box[0].vz = zlo;
|
||||
box[1].vx = xhi; box[1].vy = ylo; box[1].vz = zlo;
|
||||
box[2].vx = xlo; box[2].vy = ylo; box[2].vz = zhi;
|
||||
box[3].vx = xhi; box[3].vy = ylo; box[3].vz = zhi;
|
||||
box[4].vx = xlo; box[4].vy = yhi; box[4].vz = zlo;
|
||||
box[5].vx = xhi; box[5].vy = yhi; box[5].vz = zlo;
|
||||
box[6].vx = xlo; box[6].vy = yhi; box[6].vz = zhi;
|
||||
box[7].vx = xhi; box[7].vy = yhi; box[7].vz = zhi;
|
||||
|
||||
gte_ldv3c(&box[0]);
|
||||
gte_rtpt();
|
||||
gte_stsxy3(&sxy[0], &sxy[1], &sxy[2]);
|
||||
gte_ldv0(&box[3]);
|
||||
gte_rtps();
|
||||
gte_stsxy(&sxy[3]);
|
||||
gte_ldv3c(&box[4]);
|
||||
gte_rtpt();
|
||||
gte_stsxy3(&sxy[4], &sxy[5], &sxy[6]);
|
||||
gte_ldv0(&box[7]);
|
||||
gte_rtps();
|
||||
gte_stsxy(&sxy[7]);
|
||||
|
||||
xa32 = sxy[0].vx;
|
||||
xb32 = sxy[1].vx;
|
||||
if (xb32 < xa32) { xmx1 = xa32; xmn1 = xb32; } else { xmn1 = xa32; xmx1 = xb32; }
|
||||
t32 = sxy[2].vx;
|
||||
if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32;
|
||||
t32 = sxy[3].vx;
|
||||
if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32;
|
||||
xa32 = sxy[4].vx;
|
||||
xb32 = sxy[5].vx;
|
||||
if (xb32 < xa32) { xmx2 = xa32; xmn2 = xb32; } else { xmn2 = xa32; xmx2 = xb32; }
|
||||
t32 = sxy[6].vx;
|
||||
if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32;
|
||||
t32 = sxy[7].vx;
|
||||
if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32;
|
||||
mn = xmn1;
|
||||
if (xmn2 < mn) mn = xmn2;
|
||||
mx = xmx1;
|
||||
if (mx < xmx2) mx = xmx2;
|
||||
if (mx < -0xA0) continue;
|
||||
if (!(mn < 0xA1)) continue;
|
||||
|
||||
xa32 = sxy[0].vy;
|
||||
xb32 = sxy[1].vy;
|
||||
if (xb32 < xa32) { ymx1 = xa32; ymn1 = xb32; } else { ymn1 = xa32; ymx1 = xb32; }
|
||||
t32 = sxy[2].vy;
|
||||
if (ymx1 < t32) ymx1 = t32; else if (t32 < ymn1) ymn1 = t32;
|
||||
t32 = sxy[3].vy;
|
||||
if (ymx1 < t32) ymx1 = t32; else if (t32 < ymn1) ymn1 = t32;
|
||||
xa32 = sxy[4].vy;
|
||||
xb32 = sxy[5].vy;
|
||||
if (xb32 < xa32) { ymx2 = xa32; ymn2 = xb32; } else { ymn2 = xa32; ymx2 = xb32; }
|
||||
t32 = sxy[6].vy;
|
||||
if (ymx2 < t32) ymx2 = t32; else if (t32 < ymn2) ymn2 = t32;
|
||||
t32 = sxy[7].vy;
|
||||
if (ymx2 < t32) ymx2 = t32; else if (t32 < ymn2) ymn2 = t32;
|
||||
mny = ymn1;
|
||||
if (ymn2 < mny) mny = ymn2;
|
||||
my = ymx1;
|
||||
if (my < ymx2) my = ymx2;
|
||||
if (my < -0x78) continue;
|
||||
if (!(mny < 0x79)) continue;
|
||||
|
||||
prim = cell->prim;
|
||||
end = cell->end;
|
||||
vtx = cell->vtx;
|
||||
while (prim < end) {
|
||||
w = prim->w1;
|
||||
va = vtx + (w & 0xFFFF);
|
||||
vb = vtx + (w >> 16);
|
||||
w = prim->w2;
|
||||
vc = vtx + (w & 0xFFFF);
|
||||
w = w >> 16;
|
||||
gte_ldv3(va, vb, vc);
|
||||
gte_rtpt();
|
||||
gte_stflg(&g.flag);
|
||||
if (!(g.flag & 0x7F85E000)) {
|
||||
gte_nclip();
|
||||
code = w & 0xF;
|
||||
vd = vtx + ((w & 0xFFF0) >> 1);
|
||||
gte_stopz(&g.opz);
|
||||
if (g.opz > 0) {
|
||||
switch (code) {
|
||||
case 4:
|
||||
case 5:
|
||||
gte_stsxy3_f3(pkt);
|
||||
gte_stsz3(&g.sz0, &g.sz1, &g.sz2);
|
||||
if (((PFT3_C6F4 *)pkt)->x0 > ((PFT3_C6F4 *)pkt)->x1) {
|
||||
mx = ((PFT3_C6F4 *)pkt)->x0;
|
||||
mn = ((PFT3_C6F4 *)pkt)->x1;
|
||||
} else {
|
||||
mn = ((PFT3_C6F4 *)pkt)->x0;
|
||||
mx = ((PFT3_C6F4 *)pkt)->x1;
|
||||
}
|
||||
if (((PFT3_C6F4 *)pkt)->x2 > mx) mx = ((PFT3_C6F4 *)pkt)->x2;
|
||||
else if (((PFT3_C6F4 *)pkt)->x2 < mn) mn = ((PFT3_C6F4 *)pkt)->x2;
|
||||
if (mx >= -0xA0 && mn < 0xA1) {
|
||||
if (((PFT3_C6F4 *)pkt)->y0 > ((PFT3_C6F4 *)pkt)->y1) {
|
||||
my = ((PFT3_C6F4 *)pkt)->y0;
|
||||
mny = ((PFT3_C6F4 *)pkt)->y1;
|
||||
} else {
|
||||
mny = ((PFT3_C6F4 *)pkt)->y0;
|
||||
my = ((PFT3_C6F4 *)pkt)->y1;
|
||||
}
|
||||
if (((PFT3_C6F4 *)pkt)->y2 > my) my = ((PFT3_C6F4 *)pkt)->y2;
|
||||
else if (((PFT3_C6F4 *)pkt)->y2 < mny) mny = ((PFT3_C6F4 *)pkt)->y2;
|
||||
if (my >= -0x78 && mny < 0x79) {
|
||||
s32 za;
|
||||
u32 *otp;
|
||||
if (g.sz0 > g.sz1) {
|
||||
za = g.sz0;
|
||||
if (za < g.sz2) za = g.sz2;
|
||||
} else {
|
||||
za = g.sz1;
|
||||
if (za < g.sz2) za = g.sz2;
|
||||
}
|
||||
g.opz = za;
|
||||
if (code != 4) g.opz = za + 0x200;
|
||||
((PF3_C6F4 *)pkt)->rgbc = prim->w0;
|
||||
otp = (u32 *)(((g.opz >> 2) << 2) + ot);
|
||||
*(u32 *)pkt = (*otp & 0xFFFFFF) | 0x4000000;
|
||||
*otp = (*otp & 0xFF000000) | ((u32)pkt & 0xFFFFFF);
|
||||
pkt += 0x14;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
gte_stsxy3c(&tmpxy[0]);
|
||||
gte_stsz3(&g.sz0, &g.sz1, &g.sz2);
|
||||
if (tmpxy[0].vx > tmpxy[1].vx) {
|
||||
mx = tmpxy[0].vx;
|
||||
mn = tmpxy[1].vx;
|
||||
} else {
|
||||
mn = tmpxy[0].vx;
|
||||
mx = tmpxy[1].vx;
|
||||
}
|
||||
if (tmpxy[2].vx > mx) mx = tmpxy[2].vx;
|
||||
else if (tmpxy[2].vx < mn) mn = tmpxy[2].vx;
|
||||
if (mx >= -0xA0 && mn < 0xA1) {
|
||||
if (tmpxy[0].vy > tmpxy[1].vy) {
|
||||
my = tmpxy[0].vy;
|
||||
mny = tmpxy[1].vy;
|
||||
} else {
|
||||
mny = tmpxy[0].vy;
|
||||
my = tmpxy[1].vy;
|
||||
}
|
||||
if (tmpxy[2].vy > my) my = tmpxy[2].vy;
|
||||
else if (tmpxy[2].vy < mny) mny = tmpxy[2].vy;
|
||||
if (my >= -0x78 && mny < 0x79) {
|
||||
s32 za;
|
||||
u32 *otp;
|
||||
u32 *tp;
|
||||
gte_avsz3();
|
||||
if (g.sz0 > g.sz1) {
|
||||
za = g.sz0;
|
||||
if (za < g.sz2) za = g.sz2;
|
||||
} else {
|
||||
za = g.sz1;
|
||||
if (za < g.sz2) za = g.sz2;
|
||||
}
|
||||
g.opz = za;
|
||||
if (code != 6) g.opz = za + 0x200;
|
||||
*(u32 *)&((PFT3_C6F4 *)pkt)->x0 = *(u32 *)&tmpxy[0];
|
||||
*(u32 *)&((PFT3_C6F4 *)pkt)->x1 = *(u32 *)&tmpxy[1];
|
||||
*(u32 *)&((PFT3_C6F4 *)pkt)->x2 = *(u32 *)&tmpxy[2];
|
||||
tp = (u32 *)prim->w0;
|
||||
((PFT3_C6F4 *)pkt)->rgbc = tp[0];
|
||||
((PFT3_C6F4 *)pkt)->uvc0 = tp[1];
|
||||
((PFT3_C6F4 *)pkt)->uvp1 = tp[2];
|
||||
((PFT3_C6F4 *)pkt)->uv2 = tp[3];
|
||||
otp = (u32 *)(((g.opz >> 2) << 2) + ot);
|
||||
*(u32 *)pkt = (*otp & 0xFFFFFF) | 0x7000000;
|
||||
*otp = (*otp & 0xFF000000) | ((u32)pkt & 0xFFFFFF);
|
||||
pkt += 0x20;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
case 1:
|
||||
gte_stsxy3_f3(pkt);
|
||||
gte_ldv0(vd);
|
||||
gte_rtps();
|
||||
if (((PF4_C6F4 *)pkt)->x0 > ((PF4_C6F4 *)pkt)->x1) {
|
||||
mx = ((PF4_C6F4 *)pkt)->x0;
|
||||
mn = ((PF4_C6F4 *)pkt)->x1;
|
||||
} else {
|
||||
mn = ((PF4_C6F4 *)pkt)->x0;
|
||||
mx = ((PF4_C6F4 *)pkt)->x1;
|
||||
}
|
||||
if (((PF4_C6F4 *)pkt)->x2 > mx) mx = ((PF4_C6F4 *)pkt)->x2;
|
||||
else if (((PF4_C6F4 *)pkt)->x2 < mn) mn = ((PF4_C6F4 *)pkt)->x2;
|
||||
if (((PF4_C6F4 *)pkt)->y0 > ((PF4_C6F4 *)pkt)->y1) {
|
||||
my = ((PF4_C6F4 *)pkt)->y0;
|
||||
mny = ((PF4_C6F4 *)pkt)->y1;
|
||||
} else {
|
||||
mny = ((PF4_C6F4 *)pkt)->y0;
|
||||
my = ((PF4_C6F4 *)pkt)->y1;
|
||||
}
|
||||
if (((PF4_C6F4 *)pkt)->y2 > my) my = ((PF4_C6F4 *)pkt)->y2;
|
||||
else if (((PF4_C6F4 *)pkt)->y2 < mny) mny = ((PF4_C6F4 *)pkt)->y2;
|
||||
gte_stflg(&g.flag);
|
||||
if (!(g.flag & 0x7F85E000)) {
|
||||
gte_stsz4(&g.sz0, &g.sz1, &g.sz2, &g.sz3);
|
||||
gte_stsxy((long *)&((PF4_C6F4 *)pkt)->x3);
|
||||
if (((PF4_C6F4 *)pkt)->x3 < mn) mn = ((PF4_C6F4 *)pkt)->x3;
|
||||
else if (mx < ((PF4_C6F4 *)pkt)->x3) mx = ((PF4_C6F4 *)pkt)->x3;
|
||||
if (mx >= -0xA0 && mn < 0xA1) {
|
||||
if (((PF4_C6F4 *)pkt)->y3 < mny) mny = ((PF4_C6F4 *)pkt)->y3;
|
||||
else if (my < ((PF4_C6F4 *)pkt)->y3) my = ((PF4_C6F4 *)pkt)->y3;
|
||||
if (my >= -0x78 && mny < 0x79) {
|
||||
s32 za, zb;
|
||||
u32 *otp;
|
||||
zb = g.sz2;
|
||||
if (zb < g.sz3) zb = g.sz3;
|
||||
za = g.sz0;
|
||||
if (za < g.sz1) za = g.sz1;
|
||||
if (za < zb) za = zb;
|
||||
g.opz = za;
|
||||
if (code != 0) g.opz = za + 0x200;
|
||||
((PF4_C6F4 *)pkt)->rgbc = prim->w0;
|
||||
otp = (u32 *)(((g.opz >> 2) << 2) + ot);
|
||||
*(u32 *)pkt = (*otp & 0xFFFFFF) | 0x5000000;
|
||||
*otp = (*otp & 0xFF000000) | ((u32)pkt & 0xFFFFFF);
|
||||
pkt += 0x18;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
gte_stsxy3c(&tmpxy[0]);
|
||||
gte_ldv0(vd);
|
||||
gte_rtps();
|
||||
gte_stflg(&g.flag);
|
||||
if (!(g.flag & 0x7F85E000)) {
|
||||
gte_stsxy(&tmpxy[3]);
|
||||
gte_stsz4(&g.sz0, &g.sz1, &g.sz2, &g.sz3);
|
||||
if (tmpxy[0].vx > tmpxy[1].vx) {
|
||||
mx = tmpxy[0].vx;
|
||||
mn = tmpxy[1].vx;
|
||||
} else {
|
||||
mn = tmpxy[0].vx;
|
||||
mx = tmpxy[1].vx;
|
||||
}
|
||||
if (tmpxy[2].vx > mx) mx = tmpxy[2].vx;
|
||||
else if (tmpxy[2].vx < mn) mn = tmpxy[2].vx;
|
||||
if (tmpxy[3].vx > mx) mx = tmpxy[3].vx;
|
||||
else if (tmpxy[3].vx < mn) mn = tmpxy[3].vx;
|
||||
if (mx >= -0xA0 && mn < 0xA1) {
|
||||
if (tmpxy[0].vy > tmpxy[1].vy) {
|
||||
my = tmpxy[0].vy;
|
||||
mny = tmpxy[1].vy;
|
||||
} else {
|
||||
mny = tmpxy[0].vy;
|
||||
my = tmpxy[1].vy;
|
||||
}
|
||||
if (tmpxy[2].vy > my) my = tmpxy[2].vy;
|
||||
else if (tmpxy[2].vy < mny) mny = tmpxy[2].vy;
|
||||
if (tmpxy[3].vx > my) my = tmpxy[3].vx;
|
||||
else if (tmpxy[3].vx < mny) mny = tmpxy[3].vx;
|
||||
if (my >= -0x78 && mny < 0x79) {
|
||||
s32 za, zb;
|
||||
u32 *otp;
|
||||
u32 *tp;
|
||||
u32 uvw;
|
||||
gte_avsz4();
|
||||
zb = g.sz2;
|
||||
if (zb < g.sz3) zb = g.sz3;
|
||||
za = g.sz0;
|
||||
if (za < g.sz1) za = g.sz1;
|
||||
if (za < zb) za = zb;
|
||||
g.opz = za;
|
||||
if (code != 2) g.opz = za + 0x200;
|
||||
*(u32 *)&((PFT4_C6F4 *)pkt)->x0 = *(u32 *)&tmpxy[0];
|
||||
*(u32 *)&((PFT4_C6F4 *)pkt)->x1 = *(u32 *)&tmpxy[1];
|
||||
*(u32 *)&((PFT4_C6F4 *)pkt)->x2 = *(u32 *)&tmpxy[2];
|
||||
*(u32 *)&((PFT4_C6F4 *)pkt)->x3 = *(u32 *)&tmpxy[3];
|
||||
tp = (u32 *)prim->w0;
|
||||
((PFT4_C6F4 *)pkt)->rgbc = tp[0];
|
||||
((PFT4_C6F4 *)pkt)->uvc0 = tp[1];
|
||||
((PFT4_C6F4 *)pkt)->uvp1 = tp[2];
|
||||
uvw = tp[3];
|
||||
((PFT4_C6F4 *)pkt)->uv2 = uvw;
|
||||
((PFT4_C6F4 *)pkt)->uv3 = uvw >> 16;
|
||||
otp = (u32 *)(((g.opz >> 2) << 2) + ot);
|
||||
*(u32 *)pkt = (*otp & 0xFFFFFF) | 0x9000000;
|
||||
*otp = (*otp & 0xFF000000) | ((u32)pkt & 0xFFFFFF);
|
||||
pkt += 0x28;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
prim++;
|
||||
}
|
||||
}
|
||||
}
|
||||
D_800A5E60 = pkt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3401,5 +3401,470 @@ void func_8017C688(s32 a0, s32 a1) {
|
||||
}
|
||||
|
||||
|
||||
INCLUDE_ASM("asm/ov_SC05_019/nonmatchings/ov_SC05_019_jr_8017AE2C", func_8017C6F4);
|
||||
typedef struct { u32 w0, w1, w2; } Prim126;
|
||||
typedef struct { u8 *vtx; u32 f4; u32 xx, yy, zz; Prim126 *prim, *end; } Cell126;
|
||||
typedef struct { s16 vx, vy; } DVEC2_C6F4;
|
||||
typedef struct { s16 vx, vy, vz, pad; } SVEC2_C6F4;
|
||||
typedef struct { s16 m[3][3]; s32 t[3]; } MTX_C6F4;
|
||||
typedef struct { u32 tag, rgbc; s16 x0, y0, x1, y1, x2, y2; } PF3_C6F4;
|
||||
typedef struct { u32 tag, rgbc; s16 x0, y0, x1, y1, x2, y2, x3, y3; } PF4_C6F4;
|
||||
typedef struct { u32 tag, rgbc; s16 x0, y0; u32 uvc0; s16 x1, y1; u32 uvp1; s16 x2, y2; u16 uv2, p2; } PFT3_C6F4;
|
||||
typedef struct { u32 tag, rgbc; s16 x0, y0; u32 uvc0; s16 x1, y1; u32 uvp1; s16 x2, y2; u16 uv2, p2; s16 x3, y3; u16 uv3, p3; } PFT4_C6F4;
|
||||
|
||||
#define gte_ldv0(r0) __asm__ volatile ( \
|
||||
"lwc2 $0, 0( %0 );" \
|
||||
"lwc2 $1, 4( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) )
|
||||
#define gte_ldv3(r0, r1, r2) __asm__ volatile ( \
|
||||
"lwc2 $0, 0( %0 );" \
|
||||
"lwc2 $1, 4( %0 );" \
|
||||
"lwc2 $2, 0( %1 );" \
|
||||
"lwc2 $3, 4( %1 );" \
|
||||
"lwc2 $4, 0( %2 );" \
|
||||
"lwc2 $5, 4( %2 )" \
|
||||
: \
|
||||
: "r"( r0 ), "r"( r1 ), "r"( r2 ) )
|
||||
#define gte_ldv3c(r0) __asm__ volatile ( \
|
||||
"lwc2 $0, 0( %0 );" \
|
||||
"lwc2 $1, 4( %0 );" \
|
||||
"lwc2 $2, 8( %0 );" \
|
||||
"lwc2 $3, 12( %0 );" \
|
||||
"lwc2 $4, 16( %0 );" \
|
||||
"lwc2 $5, 20( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) )
|
||||
#define gte_rtps() __asm__ volatile ("nop;nop;rtps")
|
||||
#define gte_rtpt() __asm__ volatile ("nop;nop;rtpt")
|
||||
#define gte_nclip() __asm__ volatile ("nop;nop;nclip")
|
||||
#define gte_avsz3() __asm__ volatile ("nop;nop;avsz3")
|
||||
#define gte_avsz4() __asm__ volatile ("nop;nop;avsz4")
|
||||
#define gte_stsxy(r0) __asm__ volatile ( \
|
||||
"swc2 $14, 0( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "memory" )
|
||||
#define gte_stsxy3(r0, r1, r2) __asm__ volatile ( \
|
||||
"swc2 $12, 0( %0 );" \
|
||||
"swc2 $13, 0( %1 );" \
|
||||
"swc2 $14, 0( %2 )" \
|
||||
: \
|
||||
: "r"( r0 ), "r"( r1 ), "r"( r2 ) \
|
||||
: "memory" )
|
||||
#define gte_stsxy3c(r0) __asm__ volatile ( \
|
||||
"swc2 $12, 0( %0 );" \
|
||||
"swc2 $13, 4( %0 );" \
|
||||
"swc2 $14, 8( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "memory" )
|
||||
#define gte_stsxy3_f3(r0) __asm__ volatile ( \
|
||||
"swc2 $12, 8( %0 );" \
|
||||
"swc2 $13, 12( %0 );" \
|
||||
"swc2 $14, 16( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "memory" )
|
||||
#define gte_stsz3(r0, r1, r2) __asm__ volatile ( \
|
||||
"swc2 $17, 0( %0 );" \
|
||||
"swc2 $18, 0( %1 );" \
|
||||
"swc2 $19, 0( %2 )" \
|
||||
: \
|
||||
: "r"( r0 ), "r"( r1 ), "r"( r2 ) \
|
||||
: "memory" )
|
||||
#define gte_stsz4(r0, r1, r2, r3) __asm__ volatile ( \
|
||||
"swc2 $16, 0( %0 );" \
|
||||
"swc2 $17, 0( %1 );" \
|
||||
"swc2 $18, 0( %2 );" \
|
||||
"swc2 $19, 0( %3 )" \
|
||||
: \
|
||||
: "r"( r0 ), "r"( r1 ), "r"( r2 ), "r"( r3 ) \
|
||||
: "memory" )
|
||||
#define gte_stflg(r0) __asm__ volatile ( \
|
||||
"cfc2 $12, $31;" \
|
||||
"nop;" \
|
||||
"sw $12, 0( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "$12", "memory" )
|
||||
#define gte_stopz(r0) __asm__ volatile ( \
|
||||
"swc2 $24, 0( %0 )" \
|
||||
: \
|
||||
: "r"( r0 ) \
|
||||
: "memory" )
|
||||
|
||||
void func_8017C6F4(s32 arg0)
|
||||
{
|
||||
extern s32 func_800491EC(void);
|
||||
extern void func_800547D8(s32, MTX_C6F4 *);
|
||||
extern void func_80052E38(MTX_C6F4 *);
|
||||
extern void func_8017C014(void *, void *, s32);
|
||||
extern u8 D_8018F9C0[];
|
||||
extern u8 *D_800A5E60;
|
||||
extern u8 D_800A6610[];
|
||||
extern short D_800B9A02;
|
||||
|
||||
s16 rect[4];
|
||||
DVEC2_C6F4 tmpxy[4];
|
||||
SVEC2_C6F4 box[8];
|
||||
SVEC2_C6F4 sxy[8];
|
||||
MTX_C6F4 mtx;
|
||||
struct { long flag, opz, sz0, sz1, sz2, sz3; } g;
|
||||
|
||||
s32 cx0, cx1, cy0, cy1, y, col;
|
||||
Cell126 **rowptr;
|
||||
Cell126 **p;
|
||||
Cell126 *cell;
|
||||
Prim126 *prim;
|
||||
Prim126 *end;
|
||||
u8 *pkt;
|
||||
u32 ot;
|
||||
u8 *vtx;
|
||||
u8 *va, *vb, *vc, *vd;
|
||||
u32 w, code;
|
||||
u32 wx, wy, wz;
|
||||
u32 xlo, xhi, ylo, yhi, zlo, zhi;
|
||||
s32 xa32, xb32, t32;
|
||||
s32 xmn1, xmx1, xmn2, xmx2;
|
||||
s32 ymn1, ymx1, ymn2, ymx2;
|
||||
s32 my, mny, mx, mn;
|
||||
|
||||
func_800491EC();
|
||||
func_800547D8(arg0 + 0x10, &mtx);
|
||||
func_80052E38(&mtx);
|
||||
func_8017C014(D_8018F9C0, rect, *(s32 *)(arg0 + 0x60));
|
||||
|
||||
pkt = D_800A5E60;
|
||||
ot = (u32)&D_800A6610[(*(u16 *)&D_800B9A02) << 14];
|
||||
|
||||
cx0 = (rect[0] + 0x4000) / 512;
|
||||
cx1 = (rect[0] + rect[2] + 0x4000) / 512 + 2;
|
||||
cx0 = (cx0 < 0) ? 0 : ((cx0 > 0x3F) ? 0x3F : cx0);
|
||||
cx1 = (cx1 < 0) ? 0 : ((cx1 > 0x3F) ? 0x3F : cx1);
|
||||
cy0 = (rect[1] + 0x4000) / 512 - 1;
|
||||
cy1 = (rect[1] + rect[3] + 0x4000) / 512 + 2;
|
||||
cy0 = (cy0 < 0) ? 0 : ((cy0 > 0x3F) ? 0x3F : cy0);
|
||||
cy1 = (cy1 < 0) ? 0 : ((cy1 > 0x3F) ? 0x3F : cy1);
|
||||
|
||||
rowptr = (Cell126 **)(*(s32 *)(arg0 + 0xC)) + (cy0 * 64 + cx0);
|
||||
|
||||
for (y = cy0; y < cy1; y++, rowptr += 0x40) {
|
||||
for (col = cx0, p = rowptr; col < cx1; col++, p++) {
|
||||
cell = *p;
|
||||
if (cell == 0) continue;
|
||||
|
||||
wx = cell->xx;
|
||||
xlo = wx & 0xFFFF;
|
||||
xhi = wx >> 16;
|
||||
wy = cell->yy;
|
||||
ylo = wy & 0xFFFF;
|
||||
yhi = wy >> 16;
|
||||
wz = cell->zz;
|
||||
zlo = wz & 0xFFFF;
|
||||
zhi = wz >> 16;
|
||||
|
||||
box[0].vx = xlo; box[0].vy = ylo; box[0].vz = zlo;
|
||||
box[1].vx = xhi; box[1].vy = ylo; box[1].vz = zlo;
|
||||
box[2].vx = xlo; box[2].vy = ylo; box[2].vz = zhi;
|
||||
box[3].vx = xhi; box[3].vy = ylo; box[3].vz = zhi;
|
||||
box[4].vx = xlo; box[4].vy = yhi; box[4].vz = zlo;
|
||||
box[5].vx = xhi; box[5].vy = yhi; box[5].vz = zlo;
|
||||
box[6].vx = xlo; box[6].vy = yhi; box[6].vz = zhi;
|
||||
box[7].vx = xhi; box[7].vy = yhi; box[7].vz = zhi;
|
||||
|
||||
gte_ldv3c(&box[0]);
|
||||
gte_rtpt();
|
||||
gte_stsxy3(&sxy[0], &sxy[1], &sxy[2]);
|
||||
gte_ldv0(&box[3]);
|
||||
gte_rtps();
|
||||
gte_stsxy(&sxy[3]);
|
||||
gte_ldv3c(&box[4]);
|
||||
gte_rtpt();
|
||||
gte_stsxy3(&sxy[4], &sxy[5], &sxy[6]);
|
||||
gte_ldv0(&box[7]);
|
||||
gte_rtps();
|
||||
gte_stsxy(&sxy[7]);
|
||||
|
||||
xa32 = sxy[0].vx;
|
||||
xb32 = sxy[1].vx;
|
||||
if (xb32 < xa32) { xmx1 = xa32; xmn1 = xb32; } else { xmn1 = xa32; xmx1 = xb32; }
|
||||
t32 = sxy[2].vx;
|
||||
if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32;
|
||||
t32 = sxy[3].vx;
|
||||
if (xmx1 < t32) xmx1 = t32; else if (t32 < xmn1) xmn1 = t32;
|
||||
xa32 = sxy[4].vx;
|
||||
xb32 = sxy[5].vx;
|
||||
if (xb32 < xa32) { xmx2 = xa32; xmn2 = xb32; } else { xmn2 = xa32; xmx2 = xb32; }
|
||||
t32 = sxy[6].vx;
|
||||
if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32;
|
||||
t32 = sxy[7].vx;
|
||||
if (xmx2 < t32) xmx2 = t32; else if (t32 < xmn2) xmn2 = t32;
|
||||
mn = xmn1;
|
||||
if (xmn2 < mn) mn = xmn2;
|
||||
mx = xmx1;
|
||||
if (mx < xmx2) mx = xmx2;
|
||||
if (mx < -0xA0) continue;
|
||||
if (!(mn < 0xA1)) continue;
|
||||
|
||||
xa32 = sxy[0].vy;
|
||||
xb32 = sxy[1].vy;
|
||||
if (xb32 < xa32) { ymx1 = xa32; ymn1 = xb32; } else { ymn1 = xa32; ymx1 = xb32; }
|
||||
t32 = sxy[2].vy;
|
||||
if (ymx1 < t32) ymx1 = t32; else if (t32 < ymn1) ymn1 = t32;
|
||||
t32 = sxy[3].vy;
|
||||
if (ymx1 < t32) ymx1 = t32; else if (t32 < ymn1) ymn1 = t32;
|
||||
xa32 = sxy[4].vy;
|
||||
xb32 = sxy[5].vy;
|
||||
if (xb32 < xa32) { ymx2 = xa32; ymn2 = xb32; } else { ymn2 = xa32; ymx2 = xb32; }
|
||||
t32 = sxy[6].vy;
|
||||
if (ymx2 < t32) ymx2 = t32; else if (t32 < ymn2) ymn2 = t32;
|
||||
t32 = sxy[7].vy;
|
||||
if (ymx2 < t32) ymx2 = t32; else if (t32 < ymn2) ymn2 = t32;
|
||||
mny = ymn1;
|
||||
if (ymn2 < mny) mny = ymn2;
|
||||
my = ymx1;
|
||||
if (my < ymx2) my = ymx2;
|
||||
if (my < -0x78) continue;
|
||||
if (!(mny < 0x79)) continue;
|
||||
|
||||
prim = cell->prim;
|
||||
end = cell->end;
|
||||
vtx = cell->vtx;
|
||||
while (prim < end) {
|
||||
w = prim->w1;
|
||||
va = vtx + (w & 0xFFFF);
|
||||
vb = vtx + (w >> 16);
|
||||
w = prim->w2;
|
||||
vc = vtx + (w & 0xFFFF);
|
||||
w = w >> 16;
|
||||
gte_ldv3(va, vb, vc);
|
||||
gte_rtpt();
|
||||
gte_stflg(&g.flag);
|
||||
if (!(g.flag & 0x7F85E000)) {
|
||||
gte_nclip();
|
||||
code = w & 0xF;
|
||||
vd = vtx + ((w & 0xFFF0) >> 1);
|
||||
gte_stopz(&g.opz);
|
||||
if (g.opz > 0) {
|
||||
switch (code) {
|
||||
case 4:
|
||||
case 5:
|
||||
gte_stsxy3_f3(pkt);
|
||||
gte_stsz3(&g.sz0, &g.sz1, &g.sz2);
|
||||
if (((PFT3_C6F4 *)pkt)->x0 > ((PFT3_C6F4 *)pkt)->x1) {
|
||||
mx = ((PFT3_C6F4 *)pkt)->x0;
|
||||
mn = ((PFT3_C6F4 *)pkt)->x1;
|
||||
} else {
|
||||
mn = ((PFT3_C6F4 *)pkt)->x0;
|
||||
mx = ((PFT3_C6F4 *)pkt)->x1;
|
||||
}
|
||||
if (((PFT3_C6F4 *)pkt)->x2 > mx) mx = ((PFT3_C6F4 *)pkt)->x2;
|
||||
else if (((PFT3_C6F4 *)pkt)->x2 < mn) mn = ((PFT3_C6F4 *)pkt)->x2;
|
||||
if (mx >= -0xA0 && mn < 0xA1) {
|
||||
if (((PFT3_C6F4 *)pkt)->y0 > ((PFT3_C6F4 *)pkt)->y1) {
|
||||
my = ((PFT3_C6F4 *)pkt)->y0;
|
||||
mny = ((PFT3_C6F4 *)pkt)->y1;
|
||||
} else {
|
||||
mny = ((PFT3_C6F4 *)pkt)->y0;
|
||||
my = ((PFT3_C6F4 *)pkt)->y1;
|
||||
}
|
||||
if (((PFT3_C6F4 *)pkt)->y2 > my) my = ((PFT3_C6F4 *)pkt)->y2;
|
||||
else if (((PFT3_C6F4 *)pkt)->y2 < mny) mny = ((PFT3_C6F4 *)pkt)->y2;
|
||||
if (my >= -0x78 && mny < 0x79) {
|
||||
s32 za;
|
||||
u32 *otp;
|
||||
if (g.sz0 > g.sz1) {
|
||||
za = g.sz0;
|
||||
if (za < g.sz2) za = g.sz2;
|
||||
} else {
|
||||
za = g.sz1;
|
||||
if (za < g.sz2) za = g.sz2;
|
||||
}
|
||||
g.opz = za;
|
||||
if (code != 4) g.opz = za + 0x200;
|
||||
((PF3_C6F4 *)pkt)->rgbc = prim->w0;
|
||||
otp = (u32 *)(((g.opz >> 2) << 2) + ot);
|
||||
*(u32 *)pkt = (*otp & 0xFFFFFF) | 0x4000000;
|
||||
*otp = (*otp & 0xFF000000) | ((u32)pkt & 0xFFFFFF);
|
||||
pkt += 0x14;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
gte_stsxy3c(&tmpxy[0]);
|
||||
gte_stsz3(&g.sz0, &g.sz1, &g.sz2);
|
||||
if (tmpxy[0].vx > tmpxy[1].vx) {
|
||||
mx = tmpxy[0].vx;
|
||||
mn = tmpxy[1].vx;
|
||||
} else {
|
||||
mn = tmpxy[0].vx;
|
||||
mx = tmpxy[1].vx;
|
||||
}
|
||||
if (tmpxy[2].vx > mx) mx = tmpxy[2].vx;
|
||||
else if (tmpxy[2].vx < mn) mn = tmpxy[2].vx;
|
||||
if (mx >= -0xA0 && mn < 0xA1) {
|
||||
if (tmpxy[0].vy > tmpxy[1].vy) {
|
||||
my = tmpxy[0].vy;
|
||||
mny = tmpxy[1].vy;
|
||||
} else {
|
||||
mny = tmpxy[0].vy;
|
||||
my = tmpxy[1].vy;
|
||||
}
|
||||
if (tmpxy[2].vy > my) my = tmpxy[2].vy;
|
||||
else if (tmpxy[2].vy < mny) mny = tmpxy[2].vy;
|
||||
if (my >= -0x78 && mny < 0x79) {
|
||||
s32 za;
|
||||
u32 *otp;
|
||||
u32 *tp;
|
||||
gte_avsz3();
|
||||
if (g.sz0 > g.sz1) {
|
||||
za = g.sz0;
|
||||
if (za < g.sz2) za = g.sz2;
|
||||
} else {
|
||||
za = g.sz1;
|
||||
if (za < g.sz2) za = g.sz2;
|
||||
}
|
||||
g.opz = za;
|
||||
if (code != 6) g.opz = za + 0x200;
|
||||
*(u32 *)&((PFT3_C6F4 *)pkt)->x0 = *(u32 *)&tmpxy[0];
|
||||
*(u32 *)&((PFT3_C6F4 *)pkt)->x1 = *(u32 *)&tmpxy[1];
|
||||
*(u32 *)&((PFT3_C6F4 *)pkt)->x2 = *(u32 *)&tmpxy[2];
|
||||
tp = (u32 *)prim->w0;
|
||||
((PFT3_C6F4 *)pkt)->rgbc = tp[0];
|
||||
((PFT3_C6F4 *)pkt)->uvc0 = tp[1];
|
||||
((PFT3_C6F4 *)pkt)->uvp1 = tp[2];
|
||||
((PFT3_C6F4 *)pkt)->uv2 = tp[3];
|
||||
otp = (u32 *)(((g.opz >> 2) << 2) + ot);
|
||||
*(u32 *)pkt = (*otp & 0xFFFFFF) | 0x7000000;
|
||||
*otp = (*otp & 0xFF000000) | ((u32)pkt & 0xFFFFFF);
|
||||
pkt += 0x20;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
case 1:
|
||||
gte_stsxy3_f3(pkt);
|
||||
gte_ldv0(vd);
|
||||
gte_rtps();
|
||||
if (((PF4_C6F4 *)pkt)->x0 > ((PF4_C6F4 *)pkt)->x1) {
|
||||
mx = ((PF4_C6F4 *)pkt)->x0;
|
||||
mn = ((PF4_C6F4 *)pkt)->x1;
|
||||
} else {
|
||||
mn = ((PF4_C6F4 *)pkt)->x0;
|
||||
mx = ((PF4_C6F4 *)pkt)->x1;
|
||||
}
|
||||
if (((PF4_C6F4 *)pkt)->x2 > mx) mx = ((PF4_C6F4 *)pkt)->x2;
|
||||
else if (((PF4_C6F4 *)pkt)->x2 < mn) mn = ((PF4_C6F4 *)pkt)->x2;
|
||||
if (((PF4_C6F4 *)pkt)->y0 > ((PF4_C6F4 *)pkt)->y1) {
|
||||
my = ((PF4_C6F4 *)pkt)->y0;
|
||||
mny = ((PF4_C6F4 *)pkt)->y1;
|
||||
} else {
|
||||
mny = ((PF4_C6F4 *)pkt)->y0;
|
||||
my = ((PF4_C6F4 *)pkt)->y1;
|
||||
}
|
||||
if (((PF4_C6F4 *)pkt)->y2 > my) my = ((PF4_C6F4 *)pkt)->y2;
|
||||
else if (((PF4_C6F4 *)pkt)->y2 < mny) mny = ((PF4_C6F4 *)pkt)->y2;
|
||||
gte_stflg(&g.flag);
|
||||
if (!(g.flag & 0x7F85E000)) {
|
||||
gte_stsz4(&g.sz0, &g.sz1, &g.sz2, &g.sz3);
|
||||
gte_stsxy((long *)&((PF4_C6F4 *)pkt)->x3);
|
||||
if (((PF4_C6F4 *)pkt)->x3 < mn) mn = ((PF4_C6F4 *)pkt)->x3;
|
||||
else if (mx < ((PF4_C6F4 *)pkt)->x3) mx = ((PF4_C6F4 *)pkt)->x3;
|
||||
if (mx >= -0xA0 && mn < 0xA1) {
|
||||
if (((PF4_C6F4 *)pkt)->y3 < mny) mny = ((PF4_C6F4 *)pkt)->y3;
|
||||
else if (my < ((PF4_C6F4 *)pkt)->y3) my = ((PF4_C6F4 *)pkt)->y3;
|
||||
if (my >= -0x78 && mny < 0x79) {
|
||||
s32 za, zb;
|
||||
u32 *otp;
|
||||
zb = g.sz2;
|
||||
if (zb < g.sz3) zb = g.sz3;
|
||||
za = g.sz0;
|
||||
if (za < g.sz1) za = g.sz1;
|
||||
if (za < zb) za = zb;
|
||||
g.opz = za;
|
||||
if (code != 0) g.opz = za + 0x200;
|
||||
((PF4_C6F4 *)pkt)->rgbc = prim->w0;
|
||||
otp = (u32 *)(((g.opz >> 2) << 2) + ot);
|
||||
*(u32 *)pkt = (*otp & 0xFFFFFF) | 0x5000000;
|
||||
*otp = (*otp & 0xFF000000) | ((u32)pkt & 0xFFFFFF);
|
||||
pkt += 0x18;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
gte_stsxy3c(&tmpxy[0]);
|
||||
gte_ldv0(vd);
|
||||
gte_rtps();
|
||||
gte_stflg(&g.flag);
|
||||
if (!(g.flag & 0x7F85E000)) {
|
||||
gte_stsxy(&tmpxy[3]);
|
||||
gte_stsz4(&g.sz0, &g.sz1, &g.sz2, &g.sz3);
|
||||
if (tmpxy[0].vx > tmpxy[1].vx) {
|
||||
mx = tmpxy[0].vx;
|
||||
mn = tmpxy[1].vx;
|
||||
} else {
|
||||
mn = tmpxy[0].vx;
|
||||
mx = tmpxy[1].vx;
|
||||
}
|
||||
if (tmpxy[2].vx > mx) mx = tmpxy[2].vx;
|
||||
else if (tmpxy[2].vx < mn) mn = tmpxy[2].vx;
|
||||
if (tmpxy[3].vx > mx) mx = tmpxy[3].vx;
|
||||
else if (tmpxy[3].vx < mn) mn = tmpxy[3].vx;
|
||||
if (mx >= -0xA0 && mn < 0xA1) {
|
||||
if (tmpxy[0].vy > tmpxy[1].vy) {
|
||||
my = tmpxy[0].vy;
|
||||
mny = tmpxy[1].vy;
|
||||
} else {
|
||||
mny = tmpxy[0].vy;
|
||||
my = tmpxy[1].vy;
|
||||
}
|
||||
if (tmpxy[2].vy > my) my = tmpxy[2].vy;
|
||||
else if (tmpxy[2].vy < mny) mny = tmpxy[2].vy;
|
||||
if (tmpxy[3].vx > my) my = tmpxy[3].vx;
|
||||
else if (tmpxy[3].vx < mny) mny = tmpxy[3].vx;
|
||||
if (my >= -0x78 && mny < 0x79) {
|
||||
s32 za, zb;
|
||||
u32 *otp;
|
||||
u32 *tp;
|
||||
u32 uvw;
|
||||
gte_avsz4();
|
||||
zb = g.sz2;
|
||||
if (zb < g.sz3) zb = g.sz3;
|
||||
za = g.sz0;
|
||||
if (za < g.sz1) za = g.sz1;
|
||||
if (za < zb) za = zb;
|
||||
g.opz = za;
|
||||
if (code != 2) g.opz = za + 0x200;
|
||||
*(u32 *)&((PFT4_C6F4 *)pkt)->x0 = *(u32 *)&tmpxy[0];
|
||||
*(u32 *)&((PFT4_C6F4 *)pkt)->x1 = *(u32 *)&tmpxy[1];
|
||||
*(u32 *)&((PFT4_C6F4 *)pkt)->x2 = *(u32 *)&tmpxy[2];
|
||||
*(u32 *)&((PFT4_C6F4 *)pkt)->x3 = *(u32 *)&tmpxy[3];
|
||||
tp = (u32 *)prim->w0;
|
||||
((PFT4_C6F4 *)pkt)->rgbc = tp[0];
|
||||
((PFT4_C6F4 *)pkt)->uvc0 = tp[1];
|
||||
((PFT4_C6F4 *)pkt)->uvp1 = tp[2];
|
||||
uvw = tp[3];
|
||||
((PFT4_C6F4 *)pkt)->uv2 = uvw;
|
||||
((PFT4_C6F4 *)pkt)->uv3 = uvw >> 16;
|
||||
otp = (u32 *)(((g.opz >> 2) << 2) + ot);
|
||||
*(u32 *)pkt = (*otp & 0xFFFFFF) | 0x9000000;
|
||||
*otp = (*otp & 0xFF000000) | ((u32)pkt & 0xFFFFFF);
|
||||
pkt += 0x28;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
prim++;
|
||||
}
|
||||
}
|
||||
}
|
||||
D_800A5E60 = pkt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user