Transcribe the 256-byte MobyInstance; oClass closes the instance-to-routine loop
The decomp carries an authentic MobyInstance layout of 0x100 bytes with every
field named. It is now in gc_formats::moby with a 67-entry offset map, attributed
as a transcription rather than presented as our own finding.
Two fields matter:
0x40 animSeq animation sequence pointer
0x44 animSeqT animation time parameter
0x48 animSpeed playback speed
0x50 animLayers animation layer list
0x57 jointCnt joint count -- non-zero means the moby is skinned
0x58 jointCache joint matrix cache
0xBC oClass object class id -- the dispatch key
OCLASS CLOSES A LOOP THAT HAS BEEN OPEN FOR SEVERAL COMMITS. It is the field the
runtime uses to reach the lvl.vtbl handler tables, so an instance and its routine
are now linked by a named offset, rather than by an assumption about which axis
the two tables share. That assumption -- the positional correspondence -- is still
refuted, and still does not need to be true.
jointCnt and jointCache settle something from earlier in this log BY CONTRADICTION
rather than confirmation. A tie vertex's i16[3] was tested as a skin/joint index
and disproved: vertices sharing it were 0.95x FARTHER apart than vertices differing
in it. That stands and is unaffected -- this is the moby struct, and a moby is a
different object from a tie. Recording the distinction rather than letting "joints"
appear in two places look like a confirmation of the earlier hypothesis.
WHAT THIS DOES NOT DO IS FIND moby_anim. It names the instance-side state, so the
asset to locate is whatever those pointers reference, and we still do not know
where that is. The item's unblock condition is now sharper -- it needs the data
behind those pointers, not the struct.
PROVENANCE, AND WHAT THE TEST CAN ACTUALLY CHECK
This is not verified against disc data and cannot be: moby instances are runtime
objects and nothing of that shape is in the container. The test asserts what can be
asserted without the bytes -- offsets ascend, do not overlap, the last field lands
exactly on 0x100, and o_class sits at 0xBC immediately before triggers.
Worth keeping distinct from the collision finding. That project's FUNCTION ADDRESSES
did not transfer: they landed in NOBITS memory. A struct's field order is a
different kind of claim from an address in a program's layout, so one failing does
not impeach the other -- but the distinction is real, and PROVENANCE.md now records
which is which rather than citing the project as a single authority.
268 tests.
This commit is contained in:
@@ -3269,3 +3269,49 @@ Asserted in `dispatch_tables_contain_far_fewer_behaviours_than_records`, which
|
||||
also fails if a table ever reports more behaviours than records -- an
|
||||
impossibility worth pinning because it is the shape the counts would take if the
|
||||
record widths were wrong.
|
||||
|
||||
|
||||
## The moby instance, 256 bytes, named
|
||||
|
||||
The decomp carries an authentic `MobyInstance` layout of 0x100 bytes with every
|
||||
field named, and it is now transcribed into `gc_formats::moby::MobyInstance`
|
||||
with a 67-entry offset map. Two fields matter for the open items:
|
||||
|
||||
0x40 animSeq animation sequence pointer
|
||||
0x44 animSeqT animation time parameter
|
||||
0x48 animSpeed playback speed
|
||||
0x50 animLayers animation layer list
|
||||
0x57 jointCnt joint count -- non-zero means the moby is skinned
|
||||
0x58 jointCache joint matrix cache
|
||||
0xBC oClass object class id -- the dispatch key
|
||||
|
||||
`oClass` closes a loop that was open for several commits. It is the field the
|
||||
runtime uses to reach the `lvl.vtbl` handler tables, so an instance and its
|
||||
routine are now linked by a named offset rather than by an assumption about which
|
||||
axis the two tables share.
|
||||
|
||||
`jointCnt` and `jointCache` also settle something from earlier in this log by
|
||||
contradiction rather than confirmation. A tie vertex's `i16[3]` was tested as a
|
||||
skin/joint index and **disproved** -- vertices sharing it were 0.95x *farther*
|
||||
apart than vertices differing in it. That result stands and is unaffected: this is
|
||||
the *moby* struct, and a moby is a different object from a tie.
|
||||
|
||||
What this does **not** do is find `moby_anim`. It names the instance-side state --
|
||||
a sequence pointer, a layer list, a joint cache -- which means the asset to locate
|
||||
is whatever those point at, and we still do not know where that is. The item's
|
||||
unblock condition is now sharper: it needs the data those pointers reference, not
|
||||
the struct.
|
||||
|
||||
### Provenance and what the test can check
|
||||
|
||||
The layout is transcribed, not derived here, and it is not verified against disc
|
||||
data because it cannot be: moby instances are runtime objects and nothing of that
|
||||
shape is in the container. What the test asserts is what can be asserted without
|
||||
the bytes -- that the offsets ascend, do not overlap, and land the last field
|
||||
exactly on 0x100, and that `o_class` sits at 0xBC immediately before `triggers`.
|
||||
|
||||
Worth keeping distinct from the collision finding: that project's **function
|
||||
addresses** did not transfer, landing in NOBITS memory. A struct's field order is a
|
||||
different kind of claim from an address in a program's layout, so the failure of
|
||||
one does not impeach the other -- but the distinction is real, and `PROVENANCE.md`
|
||||
now says which is which.
|
||||
|
||||
Reference in New Issue
Block a user