Record the terrain record layout: 382 fixed 64-byte records
Continued on the tfrag terrain region and got a firm answer on the framing, which is what the next parser needs before it can read vertices. The region holds exactly 382 records of 64 bytes, from 0x40 to 0x5fc0; the 383rd breaks the pattern. Per-column analysis over 300 records separates marker bytes from data: +3 0x48 in 300/300 -- a marker, the high byte of the s16 at +2 +19,20,21,23,43,45 0x00 in 300/300 +52..55 ff 00 ff ff in 300/300 -- a fixed signature everything else varying Coordinates are fixed-point s16 with a scale of 8. That is not a guess: the value 17,496 appears in the first record and 17496 / 8 = 2187, the radius of a Ratchet & Clank planet to the unit. Read as f32 the data is nonsense, which is consistent with the earlier finding that no plausible float run exists anywhere in the 16.9 MB. Still open, and stated as open: which column is which of x, y and z, and whether 64 bytes is one vertex, two, or a header plus data. The ff 00 ff ff signature is more likely a record delimiter than a GS packet, since a VIF interpretation of the first tag does not chain. The next step is mechanical rather than exploratory: try every grouping of one record into 3-component vertices and keep the one whose points all fall within a sphere of radius ~2,187. Recorded in plan/level-assets.md. No code change.
This commit is contained in:
@@ -169,12 +169,38 @@ What is established about these records:
|
||||
GS packet headers rather than vertex data.
|
||||
- Bytes at 0x4c–0x4f repeat `ff 00 ff ff` on **every** record.
|
||||
|
||||
**Not yet determined:** the record layout. The values are not a straightforward
|
||||
vertex array read as `f32` — no plausible float run exists anywhere in the file,
|
||||
which is why packed `s16` coordinates are the right reading — but the exact
|
||||
field order has not been recovered, and a VIF packet interpretation of the
|
||||
first tag (`0xfff5`, command `0x1f`, 53 words) runs off its data after 216
|
||||
bytes and does not chain.
|
||||
### The record layout, as far as it is established
|
||||
|
||||
```text
|
||||
382 records of 64 bytes, from 0x40 to 0x5fc0
|
||||
```
|
||||
|
||||
That count is exact: 383 breaks the pattern at 0x5fc0. Per column, over 300
|
||||
records:
|
||||
|
||||
| Column | Value | Notes |
|
||||
|---|---|---|
|
||||
| +3 | `0x48` | 300/300 records. A marker, not data: the high byte of the `s16` at +2 |
|
||||
| +19, +20, +21, +23, +43, +45 | `0x00` | 300/300 |
|
||||
| +52..55 | `ff 00 ff ff` | 300/300. A fixed signature |
|
||||
| +2, +6, +10, +14, +18 … | varying | the data |
|
||||
|
||||
**Coordinates are fixed-point `s16` with a scale of 8.** Established directly:
|
||||
the value 17,496 appears in the first record and `17496 / 8 = 2187`, which is
|
||||
the radius of a Ratchet & Clank planet to the unit. Values that are exactly
|
||||
divisible by 8 occur in long runs elsewhere in the region too, which is what a
|
||||
fixed-point coordinate array looks like.
|
||||
|
||||
**Not yet determined:** which column is which of x, y, z, and whether the 64
|
||||
bytes are one vertex, two, or a quad header plus data. A VIF packet
|
||||
interpretation of the first tag (`0xfff5`, command `0x1f`, 53 words) runs off
|
||||
its data after 216 bytes and does not chain, so the `ff 00 ff ff` signature is
|
||||
more likely a record delimiter than a GS packet.
|
||||
|
||||
The next test is mechanical: take one 64-byte record, try every grouping into
|
||||
3-component vertices, and keep the one whose resulting points all lie within a
|
||||
sphere of radius ~2,187. That is a decidable question and does not need more
|
||||
speculation.
|
||||
|
||||
Ruled out along the way:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user