diff --git a/docs/plan/pcsx2-verification.md b/docs/plan/pcsx2-verification.md index 0ae7454..811fe9b 100644 --- a/docs/plan/pcsx2-verification.md +++ b/docs/plan/pcsx2-verification.md @@ -864,6 +864,28 @@ half the vertices in this patch being mid-morph at the saved camera distance. ### How much of a patch actually changes, and where +The whole tfrags block was read from RAM -- 4,379,200 bytes at `0x848000` -- and +every one of the 833 patches compared against its disc copy, grouped by whether +it *can* morph at all. + + patches with NO morphing entries 334 differing bytes: max 10.59%, median 7.80% + patches WITH morphing entries 499 differing bytes: max 10.49%, median 8.12% + patches 100% identical to disc 0/334 and 0/499 + +**The two groups are indistinguishable.** Morphing is **not** what changes the +bytes. This is the disproof of the claim above that the 8.6% was "morphed +positions with topology and UVs left verbatim" -- if it were, the 334 patches with +no morphing entries would be untouched, and none of them is. + +Nor is it a relocation: the differing bytes fall in short structured runs +(257-263, 272-277, 305 on patch 0) whose `u32` deltas have no common value. + +The remaining explanation, consistent with everything measured, is that **the +loader regenerates each patch's VU packet stream for the LOD tier it selected** -- +which happens to every patch, morphing or not. That also settles the verification +route: this memory image shows the LOD-selected form, not the morph weight, so the +weight cannot be read out of it at any camera distance. + Patch 1 (13 morphing entries of 83) compared over 4 KiB, disc `0xdf60` against RAM `0x855f60`: diff --git a/docs/roadmap.md b/docs/roadmap.md index fcb8fe1..78f7f9c 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -253,11 +253,14 @@ Phase 1 hands over the extents; this phase works out what each one contains. is that both are **pointers**, not plain offsets. All **833** patches parse, carrying **43,613** vertex-info entries; **499 of 833** have at least one morphing entry. -- [~] Behind those pointers, **8.6% of bytes are rewritten** (354 of 4,096 on - patch 1), spread over 120 short runs across the whole window rather than - concentrated in a position array. Morphing on this hardware is VU1 GIF - packets, and the loader **regenerates the packet stream** rather than - patching position fields in place. +- [x] Behind those pointers, **every patch's bytes are rewritten** -- and it is + **not morphing**. Across all 833 patches: the 334 with **no** morphing + entries differ by a median **7.80%**, the 499 with morphing entries by + **8.12%**, and **0 of 833** are byte-identical to disc. Morphing does not + predict which bytes change. Nor is it a relocation: the differences fall in + short structured runs with no common `u32` addend. The loader regenerates + each patch's **VU packet stream for the LOD tier it selected**, which + happens to every patch regardless of morphing. - [ ] What tfrag is **not** yet verified is that the morph matches `resolve_vertex`'s formula. Reading a weight back out of RAM does **not** work -- the positions live inside regenerated VU packets, so there is no