re: the definition constructor zero-fills -- defaults are derived after parsing

sub_8233FAF8 (0x8233faf8) writes vtable 0x820af844 -- the class dumped from a live
mission -- and every one of its 32 stores writes zero, out past +872. So defaults
are NOT constructor immediates, which was the hypothesis this tick set out to
test. Since a defaulted Size_Y nevertheless reads back non-zero at runtime (always
equal to Size_X), the value must be derived by a post-parse fixup -- the same
shape as the inheritance rule derived statically from sibling records.

Two candidate derivation sites (0x82217e18, 0x823081e8) are recorded as leads
only: the first is a conditional assignment rather than a copy, and offsets 48/52
are generic enough to belong to unrelated structures.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-12 21:49:48 +00:00
parent a3868fab5b
commit 71adafe7f7

View File

@@ -232,3 +232,27 @@ rather than one field per flight.
(The `vtables`, `classes` and `methods` tables are empty in this DB build, as
`CLAUDE.md` warns, so the class has to be reached through the call graph.)
## The constructor zero-fills, so the defaults are derived, not stored
Walking the call graph found the class: `sub_8233FAF8` (`0x8233faf8`) writes the
vtable **`0x820af844`** — the very objects dumped above — into `0(r30)` and then
initialises the instance. Every one of its 32 stores writes **zero**
(`stw r29, …` with `r29 = 0`), out to `+872` and beyond, interleaved with
string-member constructor calls.
That kills the natural next hypothesis: **the defaults are not immediates in the
constructor.** The object starts at zero, `Idxd_Parse` writes only the fields the
text contains, and yet a defaulted `Size_Y` reads back as a *non-zero* value at
runtime (200 for the Destroyer, 700 for the `f105` Cruiser — always `Size_X`).
So a defaulted value must be **derived after parsing**, which is exactly the shape
of the `Size_Y` inherits `Size_X` rule this project derived statically from sibling
records. Finding that fixup pass is what would yield the rest of the family.
Two candidate sites turned up by searching for a load of `+0x30` feeding a store
to `+0x34``0x82217e18` (in `sub_82217A90`) and `0x823081e8` — but neither is
confirmed: the first is a *conditional* assignment (it compares `+0x30` against a
register and picks between two values before storing to `+0x34`), not a plain
copy, and offsets 48/52 are generic enough that both could belong to unrelated
structures. Recorded as leads, not findings.