Split input/save/load atlas and update references
This commit is contained in:
parent
b173c50c1a
commit
81316e6e49
13 changed files with 5301 additions and 4113 deletions
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Primary atlas sources:
|
||||
|
||||
- [input-save-load-and-simulation.md](/home/jan/projects/rrt/docs/control-loop-atlas/input-save-load-and-simulation.md)
|
||||
- [event-editors-companydetail-and-loadscreen.md](/home/jan/projects/rrt/docs/control-loop-atlas/event-editors-companydetail-and-loadscreen.md)
|
||||
|
||||
This view isolates the company-side shell panes, linked-transit company maintenance, city-connection
|
||||
news, and annual finance-policy thresholds.
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
Primary atlas sources:
|
||||
|
||||
- [input-save-load-and-simulation.md](/home/jan/projects/rrt/docs/control-loop-atlas/input-save-load-and-simulation.md)
|
||||
- [input-save-load-and-simulation.md#station-detail-overlay](/home/jan/projects/rrt/docs/control-loop-atlas/input-save-load-and-simulation.md#station-detail-overlay)
|
||||
- [station-detail-overlay.md](/home/jan/projects/rrt/docs/control-loop-atlas/station-detail-overlay.md)
|
||||
- [station-detail-overlay.md](/home/jan/projects/rrt/docs/control-loop-atlas/station-detail-overlay.md)
|
||||
|
||||
This view isolates the map-editor page families, candidate and site-service runtime chain, and the
|
||||
station-detail or station-list read-side consumers.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Primary atlas sources:
|
||||
|
||||
- [input-save-load-and-simulation.md](/home/jan/projects/rrt/docs/control-loop-atlas/input-save-load-and-simulation.md)
|
||||
- [station-detail-overlay.md](/home/jan/projects/rrt/docs/control-loop-atlas/station-detail-overlay.md)
|
||||
|
||||
This note isolates the lower route-entry, linked-site, route-link, and auxiliary tracker families
|
||||
that are easy to lose inside the broader runtime section.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Primary atlas sources:
|
||||
|
||||
- [input-save-load-and-simulation.md](/home/jan/projects/rrt/docs/control-loop-atlas/input-save-load-and-simulation.md)
|
||||
- [runtime-roots-camera-and-support-families.md](/home/jan/projects/rrt/docs/control-loop-atlas/runtime-roots-camera-and-support-families.md)
|
||||
|
||||
This view keeps together the runtime-side shell input path, world-view tool surfaces, world bring-up
|
||||
pipeline, and the large shell-window families that hang off the recurring frame owner.
|
||||
|
|
|
|||
|
|
@ -54,6 +54,13 @@ Detailed section:
|
|||
Detailed section:
|
||||
[input-save-load-and-simulation.md](/home/jan/projects/rrt/docs/control-loop-atlas/input-save-load-and-simulation.md)
|
||||
|
||||
Subsections:
|
||||
- [runtime-roots-camera-and-support-families.md](/home/jan/projects/rrt/docs/control-loop-atlas/runtime-roots-camera-and-support-families.md)
|
||||
- [post-load-generation-paintterrain-and-save-load-restore.md](/home/jan/projects/rrt/docs/control-loop-atlas/post-load-generation-paintterrain-and-save-load-restore.md)
|
||||
- [event-editors-companydetail-and-loadscreen.md](/home/jan/projects/rrt/docs/control-loop-atlas/event-editors-companydetail-and-loadscreen.md)
|
||||
- [editor-breadth.md](/home/jan/projects/rrt/docs/control-loop-atlas/editor-breadth.md)
|
||||
- [station-detail-overlay.md](/home/jan/projects/rrt/docs/control-loop-atlas/station-detail-overlay.md)
|
||||
|
||||
## Next Mapping Passes
|
||||
|
||||
Detailed section:
|
||||
|
|
|
|||
|
|
@ -15,4 +15,12 @@ section files when adding or reviewing grounded narrative content.
|
|||
- [map-and-scenario-content-load.md](/home/jan/projects/rrt/docs/control-loop-atlas/map-and-scenario-content-load.md)
|
||||
- [multiplayer-session-and-transport-flow.md](/home/jan/projects/rrt/docs/control-loop-atlas/multiplayer-session-and-transport-flow.md)
|
||||
- [input-save-load-and-simulation.md](/home/jan/projects/rrt/docs/control-loop-atlas/input-save-load-and-simulation.md)
|
||||
|
||||
Input/Save/Load subsections:
|
||||
|
||||
- [runtime-roots-camera-and-support-families.md](/home/jan/projects/rrt/docs/control-loop-atlas/runtime-roots-camera-and-support-families.md)
|
||||
- [post-load-generation-paintterrain-and-save-load-restore.md](/home/jan/projects/rrt/docs/control-loop-atlas/post-load-generation-paintterrain-and-save-load-restore.md)
|
||||
- [event-editors-companydetail-and-loadscreen.md](/home/jan/projects/rrt/docs/control-loop-atlas/event-editors-companydetail-and-loadscreen.md)
|
||||
- [editor-breadth.md](/home/jan/projects/rrt/docs/control-loop-atlas/editor-breadth.md)
|
||||
- [station-detail-overlay.md](/home/jan/projects/rrt/docs/control-loop-atlas/station-detail-overlay.md)
|
||||
- [next-mapping-passes.md](/home/jan/projects/rrt/docs/control-loop-atlas/next-mapping-passes.md)
|
||||
|
|
|
|||
912
docs/control-loop-atlas/editor-breadth.md
Normal file
912
docs/control-loop-atlas/editor-breadth.md
Normal file
|
|
@ -0,0 +1,912 @@
|
|||
# Input, Save/Load, and Simulation: Editor Breadth
|
||||
|
||||
### Editor Breadth
|
||||
|
||||
The broader map-editor page owner is now bounded through
|
||||
`map_editor_panel_select_active_section` `0x004ce070` and
|
||||
`map_editor_panel_dispatch_active_section_message` `0x004cf700`, which switch among the grounded
|
||||
setup pages, `Cities/Regions`, `Territories`, the `Players` and `Player Pool` setup slices, the
|
||||
now-grounded `Building Density` page, the locomotives-available and industry-availability pages,
|
||||
the economic and special-condition pages, the `Port/Warehouse Cargos` page, and the later report
|
||||
pages. The mid-editor ownership is materially clearer now too: the chairman-slot editor is the
|
||||
`Players` page, the available-chairman editor is the `Player Pool` page, and the former unnamed
|
||||
dual tri-state page now lines up with localized page text `997` `Building Density` plus help text
|
||||
`1017` and the direct field captions `1642` `Starting Building Density Level:` and `1644`
|
||||
`Building Density Growth:`. Both controls are now bounded as stored ordinal bytes `0/1/2` rather
|
||||
than loose labels: the first three-choice control is the map-wide starting-density selector, with
|
||||
its default middle state `1` matching the documented `100%` baseline from `1643`; the second is
|
||||
the paired overall growth selector whose effects later appear in the city-growth side of the
|
||||
simulation. `map_editor_city_region_panel_construct` and
|
||||
`map_editor_city_region_panel_handle_message` own the city-or-region editing lane with rename and
|
||||
copy-industry-data flows. That copy side is tighter now too: the handler first enters
|
||||
`0x00420e00`, which rebuilds the selected region's profile collection `[region+0x37f]`, clones
|
||||
the source region's live label-weight entries when a source region is present, and otherwise
|
||||
reseeds a fixed default weight set through repeated `0x004206b0` calls. The no-source companion
|
||||
`0x00420ed0` now makes that split explicit: it rebuilds the same subcollection and then picks one
|
||||
of two fixed default label-weight sets based on region class dword `[region+0x23e]`, using one
|
||||
all-`0.2f` family for nonzero-class regions and one class-`0` family that starts with `0.3f`
|
||||
before continuing with repeated `0.2f` entries. The lower mutator
|
||||
`0x004206b0` then linearly scans the selected region subcollection by profile label, creates a
|
||||
new profile only when the copied weight is positive, removes an existing profile when the copied
|
||||
weight is non-positive, updates `[entry+0x1e]` otherwise, and refreshes the region's derived
|
||||
availability-summary bytes `[region+0x2f6/+0x2fa/+0x2fe]` through `0x00420410`; `map_editor_territory_panel_construct` and
|
||||
the adjacent no-source companion `0x00420ed0` is tighter too: it rebuilds the same collection
|
||||
root `[region+0x37f]` but then seeds one of two fixed default profile-label sets directly through
|
||||
repeated `0x004206b0` calls, splitting by region class dword `[region+0x23e]`. Nonzero-class
|
||||
regions take one all-`0.2f` default set, while class-0 regions take a different set that starts
|
||||
with one `0.3f` weight before continuing with repeated `0.2f` entries. That makes `0x420ed0`
|
||||
the true class-split default-profile companion to the source-cloning helper at `0x420e00`,
|
||||
rather than just more of the same editor copy path. Two neighboring collection queries are tight
|
||||
enough now too. `0x00421d20` counts how many live regions have at least one profile row in
|
||||
`[region+0x37f]` whose label matches the candidate-name string for one caller-supplied candidate
|
||||
id; `0x00421e30` resolves the Nth such matching region. Both helpers reuse the same
|
||||
`0x0041fac0` ordinal label-and-weight copy helper we just grounded, only increment once per
|
||||
region, and skip nonzero-class regions whose companion count `[region+0x242]` is nonpositive.
|
||||
Those two queries are what the editor summary side at `0x004cdd56/0x004cdeab` uses before it
|
||||
formats per-region lists for one selected industry or profile name. The adjacent world-facing
|
||||
query strip is bounded too: `0x00422010` scans the live region collection for class-0 regions
|
||||
whose normalized coordinates fall inside one caller-supplied float rectangle, keeps the nearest
|
||||
region id `[region+0x23a]` by squared XY distance through `0x0051db80`, and returns `0` when no
|
||||
qualifying region is found; `0x004220b0` is the small wrapper above it that returns the matched
|
||||
region name `[region+0x356]` or the fallback localized scratch string at `0x0062ba90`.
|
||||
`map_editor_territory_panel_construct` and
|
||||
`map_editor_territory_panel_handle_message` own the territory rename and border-remap lane;
|
||||
`map_editor_locomotive_availability_panel_construct` plus
|
||||
`map_editor_locomotive_availability_panel_handle_message` now bound the locomotive policy page
|
||||
over `0x006ada84`; `map_editor_industry_availability_panel_construct` plus
|
||||
`map_editor_industry_availability_panel_handle_message` do the same for the industry candidate
|
||||
pool at `0x0062b268`; and `map_editor_port_warehouse_cargo_panel_construct` plus
|
||||
`map_editor_port_warehouse_cargo_panel_handle_message` now ground the recipe-book page that edits
|
||||
port or warehouse cargo policies through twelve per-book state blocks at
|
||||
`[0x006cec78+0x0fe7+index*0x4e1]`. Each book now has a shared maximum annual production float at
|
||||
`book+0x3ed` and five fixed cargo-line entries starting at `book+0x3f1` with stride `0x30`; each
|
||||
line is bounded as a mode dword, annual amount, a supplied-cargo token at `+0x08`, and a
|
||||
demanded-cargo token at `+0x1c`. The constructor and handler now make those fields materially
|
||||
tighter too: the row pair shown in `Supply Only` and `Production Demand->Supply` is the `+0x08`
|
||||
supplied-cargo selector, the row pair shown in `Demand Only` and `Production Demand->Supply` is
|
||||
the `+0x1c` demanded-cargo selector, and the single amount field at `+0x04` is labeled `Annual
|
||||
Demand:` only in mode `1` but `Annual Supply:` in modes `2/3`. The stronger new runtime-side
|
||||
result is now a full chain rather than only the importer:
|
||||
`scenario_state_rebuild_port_warehouse_cargo_recipe_runtime_tables` first imports those same five
|
||||
lines into one repeated array of identical `0xbc`-byte runtime descriptors with no row-index
|
||||
special casing, and the candidate-side rebuild pass at
|
||||
`structure_candidate_collection_rebuild_runtime_records_from_scenario_state` `0x00412d70` then
|
||||
projects those descriptors into the live structure collection at `0x0062ba8c` before
|
||||
`structure_candidate_rebuild_cargo_membership_and_scaled_rate_tables` `0x00411ee0` rebuilds the
|
||||
per-cargo runtime summary tables. The current local file-side result is now tighter too: the
|
||||
grounded recipe-book root at `0x0fe7` is preserved byte-for-byte across the checked map/save
|
||||
scenario pairs, so the loader can safely treat the twelve `0x4e1`-byte books as preserved
|
||||
scenario payload rather than a drifting save-only band. A conservative summary probe now only
|
||||
reports per-book head signatures, raw cap dwords at `+0x3ed`, and five raw line summaries rooted
|
||||
at `+0x3f1` so the file-side structure stays aligned with this grounded ownership. The
|
||||
player-facing line modes remain `Disabled`, `Demand Only`, `Supply Only`, and
|
||||
`Production Demand->Supply`, and the fourth mode is tighter now too: current wording around
|
||||
`1674`, `1675`, and `504` plus the downstream scaling path says it is the
|
||||
production-line mode governed by the shared annual production cap, where the entered annual amount
|
||||
stays on the supply side while the demanded side becomes the normalized input branch. The
|
||||
candidate-side accumulator pass reinforces that split by applying the shared production cap only
|
||||
to the supply-half runtime branch and bypassing that scaling on the normalized demand half. The
|
||||
lower gameplay side is tighter now too: `structure_candidate_query_cargo_runtime_summary_channels`
|
||||
`0x00412650` is the first grounded consumer beneath that rebuild chain, because it lazily rebuilds
|
||||
four per-cargo summary banks and returns one direct-supply channel, one cap-normalized supply
|
||||
channel, one demand or input channel, and one scaled production-output subrow channel for a
|
||||
requested cargo id. The internal indexing is tighter now too: the direct-supply lane indexes from
|
||||
`[desc+0x1c]`, the demand or input lane uses that same resolved cargo id in the no-subrow branch,
|
||||
and the scaled production-output lane indexes each subordinate row directly from
|
||||
`[desc+0x44+row*0x1c]`, with no post-resolution failure guard between the importer writes and the
|
||||
summary-bank updates. So the strongest current read is narrower than a full cargo-id decode: if
|
||||
the imported low-16 marker rows fail the exact matcher at `0x0041e9f0`, the resulting `0` ids
|
||||
will still hit the first summary-bank bucket inside `0x00412650`, but the semantic meaning of
|
||||
cargo id `0` itself remains ungrounded. The sibling helper
|
||||
`structure_candidate_supports_or_references_cargo_id`
|
||||
`0x004129d0` then uses those same banks plus the cached cargo-membership arrays to answer whether
|
||||
a live candidate materially references a cargo at all. One compare step tighter, the raw line
|
||||
lanes now split cleanly by scenario family while still preserving map->save identity inside each
|
||||
checked pair. `Alternate USA.gmp` and `Autosave.gms` match at the raw line-content level: books
|
||||
`0..4` keep mixed line areas, their `line02` slots carry the recurring nonzero mode words
|
||||
`0x00110000`, `0x000b0000`, `0x000b0000`, `0x00130000`, and `0x00180000`, and the same `line02`
|
||||
slots also carry one recurring supplied token `0x000040a0`; the neighboring `line00/line01`
|
||||
slots carry the same recurring demanded token lanes such as `0x00010000`, `0x72470000`,
|
||||
`0x6f430000`, `0x694c0000`, and `0x694d0000`. `Southern Pacific.gmp` and `p.gms` also match at
|
||||
the raw line-content level, but the same rooted line slots stay zero in the checked pair.
|
||||
`Spanish Mainline.gmp` and `g.gms` again match at the raw line-content level yet carry a distinct
|
||||
nonzero pattern: books `0..4` keep mixed line areas, line-level supplied tokens include
|
||||
`0x00170000`, `0x00150000`, `0x00004040`, and `0x00004000`, demanded tokens include
|
||||
`0x00010000`, `0x68430000`, and `0x6c410000`, and the later `line02` mode words stabilize at
|
||||
`0x00070000` then `0x00010000`. So the loader can now safely treat these raw line lanes as
|
||||
preserved scenario payload with family-specific signatures, even though the exact cargo-id and
|
||||
mode-enum semantics still need separate grounding. One inference is tighter now too: when those
|
||||
demanded-token words are zero in the low 16 bits and printable in the high 16 bits, the byte
|
||||
order reads as short two-letter stems such as `Gr`, `Co`, `Li`, `Mi`, `Ch`, and `Al`, which fit
|
||||
the current scenario cargo-name families `Grain`, `Corn`, `Livestock`, `Milk`, `Cheese`, and
|
||||
`Alcohol` from `RT3.lng`; the runtime probe now exposes those only as probable ASCII stems, not
|
||||
as fully grounded cargo-id decodes. The supplied-token side is now bounded as a separate layout
|
||||
family rather than forced into that same stem model: the `Alternate USA` family uses one stable
|
||||
low-16 marker `0x000040a0` only in `book00..04.line02`, the `Southern Pacific` family leaves the
|
||||
supplied lanes zero in the checked pair, and the `Spanish Mainline` family splits between two
|
||||
high-16 numeric tokens `0x00170000` and `0x00150000` in `book00/01.line01` plus the later low-16
|
||||
markers `0x00004040`, `0x00004000`, and `0x00004040` in `book02..04.line02`. The probe now
|
||||
exposes those conservatively as token-layout classes `high16-ascii-stem`, `high16-numeric`, and
|
||||
`low16-marker`, without claiming that the non-stem numeric or marker families are decoded yet.
|
||||
One more structural layer is stable enough to name conservatively: the checked nonzero recipe
|
||||
rows repeatedly fall into four line-signature classes. `Alternate USA` books `0..4` all expose
|
||||
one `demand-numeric-entry` at `line00` (`0x00010000`), one `demand-stem-entry` at `line01`
|
||||
(`Gr/Co/Li/Mi` stems), and one `supply-marker-entry` at `line02` (nonzero mode plus
|
||||
`0x000040a0`). `Spanish Mainline` books `2..4` expose that same three-line pattern with
|
||||
`Ch/Al` stems and the `0x00004040/0x00004000` marker family, while books `0/1` only expose the
|
||||
earlier `supply-numeric-entry` form at `line01`. So the loader can now distinguish recurring row
|
||||
roles such as demand-stem versus supply-marker without pretending the marker payloads themselves
|
||||
are decoded. The importer-side branch map is tighter now too because local `objdump` over
|
||||
`0x00435630` shows that only nonzero mode dwords materialize into `0xbc` runtime descriptors:
|
||||
mode `0` lines are skipped entirely, mode `1` enters the demand-only branch, mode `3` enters the
|
||||
dual demand-plus-supply branch, and every other nonzero mode falls into the supply-side branch.
|
||||
In the checked corpus that means the recurring `demand-numeric-entry` and `demand-stem-entry`
|
||||
rows in `Alternate USA` and `Spanish Mainline` are preserved scenario-side line records but do
|
||||
not become live runtime descriptors, while the later `supply-marker-entry` rows are the ones that
|
||||
actually reach the runtime import path. The runtime probe now exposes that directly as
|
||||
`imports_to_runtime_descriptor` plus one conservative `runtime_import_branch_kind`.
|
||||
The raw token windows beneath those branch labels are tighter now too. The checked mode-zero
|
||||
demand rows preserve string-bearing windows at `line+0x1c`, and the current probe shows those
|
||||
conservatively as prefixed ASCII previews such as `..Grain`, `..Corn`, `..Livestock`, and
|
||||
`..Milk`; local `objdump` over `0x0041e9f0` then shows the importer feeding the corresponding
|
||||
token buffer into an exact cargo-name matcher built over the live cargo collection at
|
||||
`0x0062ba8c`. By contrast, the imported `supply-marker-entry` rows feed nonprintable windows such
|
||||
as `.@...` from `line+0x08` through that same matcher, and the resolver path currently shows no
|
||||
special-case decoding for those marker forms. So the strongest static read is now: the stem-like
|
||||
demand rows preserve cargo-name text but are skipped because their mode is zero, while the
|
||||
nonzero imported marker rows are the live descriptor inputs yet likely fail exact cargo-name
|
||||
resolution unless another upstream transform exists.
|
||||
The wrapper layer above that query no longer looks like a hiding place for special treatment
|
||||
either. Local `objdump` now shows `0x00412960` simply summing the two supply-side floats returned
|
||||
by `0x00412650`, while `0x004129a0` returns the single scaled production-output lane directly;
|
||||
neither wrapper checks for cargo id `0` after the query returns. The broader world-side
|
||||
accumulator at `0x0041e7be` is tighter in the same way: it calls `0x00412650`, requires all four
|
||||
returned channels to be positive before continuing, and only then scales those four channel
|
||||
values by one linked-instance count from `0x00413940` into caller-owned accumulators. So the
|
||||
current strongest read remains structural rather than semantic: unresolved marker rows can still
|
||||
propagate through the first bank bucket, but the first place that meaning matters is a normal
|
||||
positivity-gated cargo-channel consumer, not a dedicated null-cargo branch.
|
||||
The caller side is narrower than before too. The steady-state site bitset owner
|
||||
`placed_structure_rebuild_candidate_cargo_service_bitsets` `0x0042c690` starts its inner cargo
|
||||
loop at id `1` and only walks upward through the current live cargo count, so it never
|
||||
intentionally queries cargo id `0`. The broader placed-structure sweep around `0x00452e60`
|
||||
tightens the same boundary from above: when the requested cargo id is nonzero it resolves the
|
||||
backing candidate and enters `structure_candidate_supports_or_references_cargo_id`, but when the
|
||||
requested id is exactly `0` it skips that cargo-reference helper entirely and falls through to a
|
||||
different linked-site or station-or-transit gate. Current local `objdump` now shows that bypass
|
||||
first requiring one subtype latch through the placed-structure vtable `+0x70`, then resolving the
|
||||
linked site id at `[site+0x2a8]` through the placed-structure collection `0x006cec20`, and then
|
||||
forwarding that linked peer into the narrower predicate at `0x0047fd50`. That narrower helper is
|
||||
tighter than before too: it resolves the linked peer's backing candidate through the peer site id
|
||||
at `[peer+0x04]`, reads candidate class byte `[candidate+0x8c]`, and returns true only for the
|
||||
first three class values `0/1/2` while rejecting `3/4` and anything above `4`. So current local
|
||||
callers treat cargo id `0` as a nonstandard request bound to one linked-site reachability or
|
||||
classification side path, not one ordinary cargo lane they routinely probe.
|
||||
The vtable-`+0x70` latch itself is bounded a bit better now too. It still lacks a direct field
|
||||
decode, but every local callsite we checked around `0x0040d230`, `0x0040dba0`, `0x0040dbf0`, and
|
||||
`0x0040f670` uses that slot only as the precondition for touching `[site+0x2a8]` and the
|
||||
neighboring linked-site helpers `0x0047dda0`, `0x0047fd50`, and `0x004138b0`. That makes the
|
||||
safest current read a linked-site-bearing or linked-site-capable latch, strongly aligned with the
|
||||
subtype-`1` construction lane that is the only grounded writer of `[site+0x2a8]`, rather than a
|
||||
broad cargo or route-style predicate.
|
||||
The neighboring maintenance pair tightens that linked-site read further. Local `objdump` now
|
||||
shows `0x0040dba0` and `0x0040dbf0` as complementary tiny helpers that each require the same
|
||||
vtable-`+0x70` latch, resolve optional linked peer id `[site+0x2a8]` through `0x006cec20`,
|
||||
forward that linked peer (or null) into `0x0047dda0`, and then mirror opposite values into local
|
||||
byte `[site+0x42]` (`0` for `0x0040dba0`, `1` for `0x0040dbf0`). The route-entry side beneath
|
||||
them is tighter too: `0x0047dda0` reads route-entry anchor id `[peer+0x08]`, resolves that anchor
|
||||
through `0x006cfca8`, and only dispatches one of two route-entry vtable calls when
|
||||
`0x0048a090(1)` reports that all three anchor-slot dwords `[entry+0x206]`, `[entry+0x20a]`, and
|
||||
`[entry+0x20e]` are still `-1`. So the strongest current read is no longer just "linked-site
|
||||
capable" in the abstract: this latch consistently fronts the local linked-peer class gate
|
||||
`0x0047fd50`, the paired `[site+0x42]` route-entry state toggles, and the later linked-peer
|
||||
collection sweep `0x004138b0`, which keeps the `cargo id 0` bypass path firmly on the
|
||||
linked-site route-anchor or classification side rather than on an ordinary cargo lane.
|
||||
One smaller ownership boundary is tighter too: byte `[site+0x42]` is not private scratch owned
|
||||
only by that pair. Local `objdump` shows tiny direct setters at `0x0040cbc0` and `0x0040cbd0`
|
||||
plus a raw getter at `0x0040cbf0`, so the `0x0040dba0/0x0040dbf0` pair is writing one shared
|
||||
placed-structure state byte rather than inventing a route-entry-only scratch lane. One caution
|
||||
is tighter now too: there are later mode-gated reads at other addresses that also touch a
|
||||
`+0x42` byte on their own object layouts, but current local evidence does not yet prove those are
|
||||
the same placed-structure owner family, so the safest current note keeps only the immediate
|
||||
`0x0040cbc0/0x0040cbd0/0x0040cbf0/0x0040dba0/0x0040dbf0` cluster grounded together.
|
||||
The vtable side sharpens that split too. A local `.rdata` scan shows `0x0040dba0` and
|
||||
`0x0040dbf0` each appearing exactly once, together with `0x0040cbf0`, in one method table rooted
|
||||
at `0x005c8c50`; the constructor chain is tighter now too, because `0x0040c950` installs that
|
||||
same table as one concrete placed-structure specialization above the common base table
|
||||
`0x005cb4c0`, while `0x0040c970` tears the same specialization back down to the base before the
|
||||
temporary object is freed. By contrast the raw set or get trio
|
||||
`0x0040cbc0/0x0040cbd0/0x0040cbf0` also appears in several sibling tables such as `0x005c9750`
|
||||
and `0x005dd1f0`. So the strongest current structural read is that byte `[site+0x42]` belongs
|
||||
to one broader placed-structure virtual interface, while the linked-peer route-entry toggles are
|
||||
one specialization-specific override pair inside that family rather than generic setters used by
|
||||
every sibling.
|
||||
One negative boundary is tighter now too: the
|
||||
raw token words in this recipe block do not look like the already grounded shell-side
|
||||
`AnyCargo/AnyFreight/AnyExpress` selector-table ids from `0x00621e04/0x00621e10`, so the current
|
||||
best read is that these on-disk line tokens are not just copied UI selector ordinals or the same
|
||||
small express-side id family in another wrapper. One broader collection pass also now ties
|
||||
the editor rule side back into runtime filtering:
|
||||
`structure_candidate_collection_refresh_cargo_economy_filter_flags` `0x0041eac0` rebuilds
|
||||
per-candidate flag `[candidate+0x56]` across the live structure collection, and current grounded
|
||||
callers show it rerunning directly off the runtime cargo-economy latch at `[0x006cec74+0x25f]`,
|
||||
which aligns this lane with the editor's `Disable Cargo Economy` special condition rather than
|
||||
leaving it as a purely editor-owned recipe page. The first common live gate beneath that filter is
|
||||
now bounded too: `structure_candidate_is_enabled_for_current_year` `0x0041e220` is the shared
|
||||
year-and-filter check used by the collection refresh and later candidate-selection branches, while
|
||||
`structure_candidate_rebuild_local_service_metrics` `0x0041e2b0` is a setup-side local service
|
||||
scorer that already consumes the same enabled candidate records through world-grid sampling. One
|
||||
steady-state world-side consumer is now grounded as well:
|
||||
`placed_structure_rebuild_candidate_cargo_service_bitsets` `0x0042c690` walks linked placed
|
||||
structures, filters live category-`2` candidates through
|
||||
`structure_candidate_is_enabled_for_current_year`, and compacts the direct and scaled supply-side
|
||||
channels from `0x00412960` and `0x004129a0` into per-cargo bitsets on the placed-structure record.
|
||||
The next site-side owner layer is tighter now too:
|
||||
`placed_structure_refresh_linked_candidate_flag4` `0x0042c8f0` refreshes the sibling state bit at
|
||||
`[site+0x0e6]`, `placed_structure_refresh_candidate_service_state` `0x0042cdf0` ties that flag
|
||||
refresh to the cargo-service bitset rebuild,
|
||||
`placed_structure_rebuild_candidate_local_service_tables` `0x0042ce00` then performs the heavier
|
||||
per-site candidate score rebuild over the aligned float and word tables at `[site+0x107]`,
|
||||
`[site+0x02]`, and `[site+0x6c]`, and `placed_structure_refresh_local_service_score_bundle`
|
||||
`0x0042d580` is now the local wrapper that chains that rebuild into the neighboring post-passes
|
||||
before the world-grid owner continues. Those post-passes are tighter too:
|
||||
`placed_structure_apply_route_linked_service_caps` `0x0042cc50` is the first route-backed cap pass
|
||||
over the rebuilt local tables,
|
||||
`placed_structure_redistribute_local_service_pressure_from_neighbors` `0x0042c1b0` is the
|
||||
neighboring-site redistribution pass, and `placed_structure_clamp_candidate_service_age_table`
|
||||
`0x0042cb30` is the final recent-service clamp over the primary per-candidate word table. Above
|
||||
that refresh lane, `placed_structure_query_candidate_local_service_metrics` `0x0047e240` is the
|
||||
first higher-level query, `placed_structure_count_candidates_with_local_service_metrics`
|
||||
`0x0047e330` counts how many candidates currently produce that query,
|
||||
`placed_structure_get_nth_candidate_id_with_local_service_metrics` `0x0047e620` is the ordinal
|
||||
selector over that same visible candidate family,
|
||||
`placed_structure_query_cached_express_service_class_score` `0x0047e390` caches one parallel class
|
||||
score for the express family now strongly aligned with `Passengers`, `Mail`, and `Troops`,
|
||||
`placed_structure_refresh_candidate_local_service_comparison_cache_against_peer_site`
|
||||
`0x0047eb90` rebuilds one peer-site comparison cache over the same local-service inputs, and
|
||||
`placed_structure_select_best_candidate_id_by_local_service_score` `0x0047f910` is the best-hit
|
||||
selector above the direct and directional local-service query pair. Those site-side scores now
|
||||
have grounded shell read-side consumers too:
|
||||
`shell_station_detail_format_freight_and_express_summary` `0x00506be0` formats the visible
|
||||
`Freight: %1` and `Express: %1` lines in `StationDetail.win`, and the same station-detail family
|
||||
now has a deeper candidate-service lane:
|
||||
`shell_station_detail_set_active_candidate_service_preview` `0x00504ae0` stores the active
|
||||
`(station id, candidate id)` pair for the world-side preview scan and now grounds the whole
|
||||
world-side arming strip through
|
||||
`world_store_preview_primary_id_0x2179_dispatch_mode3_collection_and_refresh_if_active`
|
||||
`0x00452f60`,
|
||||
`world_store_preview_scalar_0x217d_and_refresh_active_mode_if_nonzero` `0x00452d80`,
|
||||
`world_store_preview_linked_site_id_0x2181_rebind_mode3_and_refresh_if_active`
|
||||
`0x00452db0`, and
|
||||
`world_set_aux_preview_mode_0x2171_and_reseed_overlay_companion_grid` `0x00452ca0`,
|
||||
`shell_station_detail_clear_active_candidate_service_preview` `0x00504a90` tears that pair back
|
||||
down, `shell_station_detail_update_candidate_service_entry` `0x00504ba0` is the shell-side entry
|
||||
updater above that preview pair, `shell_station_detail_format_candidate_local_service_summary`
|
||||
`0x00504bea` uses `placed_structure_query_candidate_local_service_metrics` together with localized
|
||||
ids `681`, `682`, and `2813` to build the visible candidate service text,
|
||||
`shell_station_detail_build_to_from_haul_summary_widget` `0x00505150` now grounds the paired `To`
|
||||
and `From` hauled-traffic strip widgets, `shell_station_detail_present_to_from_haul_stats_popup`
|
||||
`0x00504770` owns their click-through annual and lifetime `hauled TO/FROM this station` popup,
|
||||
`shell_station_detail_refresh_nearby_structure_jump_rows` `0x00505470` owns the five-row
|
||||
nearby-structure jump lane, and `shell_station_detail_refresh_candidate_service_rows` `0x00505760`
|
||||
is now the larger row-list owner that enumerates active candidate-service entries and wires
|
||||
`shell_station_detail_update_candidate_service_entry` into the per-row click path. The broader
|
||||
owner above those lanes is tighter now too: `shell_station_detail_window_refresh_controls`
|
||||
`0x00506610` is the real `StationDetail.win` refresh pass, validating the current station from the
|
||||
detail manager, publishing the upper summary lane, splitting the `0xb3b7/0xb3b8` action strip by
|
||||
scenario latch `[0x006cec74+0x1db]`, routing that scenario branch through
|
||||
`shell_station_detail_present_scenario_station_connection_triplet_popup` `0x00504590`, routing
|
||||
class `3/4` sites into the alternate branch
|
||||
`shell_station_detail_refresh_class_3_or_4_train_service_matrix` `0x00504ec0`, and otherwise rebuilding the nearby-structure lane, the paired `To/From` widgets,
|
||||
and the candidate-service rows together. The broader message side is bounded now too:
|
||||
`shell_station_detail_window_handle_message` `0x00505e50` owns the wide `StationDetail.win`
|
||||
switch over message ids `0`, `0xca`, `0xcb`, and `0x3ea`, routes candidate-service rows
|
||||
`0xb4dc..0xb5a3` into preview arm or clear or a Ctrl-modified `Overview.win` handoff, routes
|
||||
nearby-structure rows `0xb40a..0xb413` into the detail transition and optional world-centering
|
||||
path, refreshes control `0xb3f8` on the `0x3ea` branch, and dispatches the lower
|
||||
`0xb3b5..0xb3bf` action band through the selected-station ownership and class-gated helper strip.
|
||||
The compact siblings under that pass are tighter now too:
|
||||
`shell_station_detail_clear_dynamic_rows_and_haul_widgets_if_dirty` `0x005042c0` is the dirty
|
||||
clear owner over the dynamic row bands and the paired haul widgets, `shell_station_detail_has_valid_selected_station`
|
||||
`0x00504370` is the bare selected-station validity probe, `shell_station_detail_selected_station_belongs_to_selected_company`
|
||||
`0x00504390` is the selected-company ownership gate, and
|
||||
`shell_station_detail_present_selected_station_not_controlled_notice` `0x005043f0` is the
|
||||
localized not-controlled popup beneath the same action family,
|
||||
`shell_station_detail_present_scenario_station_connection_triplet_popup` `0x00504590` is the
|
||||
scenario-latched station-to-station triplet popup that formats three per-destination scalar lanes
|
||||
with `%5.2f` or `N/C`, and
|
||||
`shell_station_detail_refresh_class_3_or_4_train_service_matrix` `0x00504ec0` is the alternate
|
||||
class-`3/4` branch that rebuilds the `Trains Serviced` / `Trains Maintained` matrix before
|
||||
reusing the shared haul-popup callback wiring,
|
||||
`shell_station_detail_refresh_class_gated_action_controls_0xb3bb_to_0xb3bf` `0x005044b0`
|
||||
refreshes the lower class-gated action strip rather than the older guessed `0xb3f8` lane. The
|
||||
adjacent lifecycle and navigation side is tighter now too:
|
||||
`shell_station_detail_window_destruct_release_preview_helpers_and_clear_singleton` `0x00505bf0`
|
||||
is the real `StationDetail.win` destructor, and
|
||||
`shell_station_detail_cycle_selected_station_by_direction_preserving_owner_and_station_site_class`
|
||||
`0x00505cb0` plus wrappers `0x00505e30` and `0x00505e40` now bound the next-or-previous station
|
||||
stepping path that keeps the selection inside the same owner and station-site class family before
|
||||
optionally recentering the world view. The broader shell command layer above that station-detail
|
||||
branch is tighter now too:
|
||||
`shell_command_step_active_window_subject_forward_or_publish_contextual_notice` `0x00440e00` and
|
||||
`shell_command_step_active_window_subject_backward_or_publish_contextual_notice` `0x00440f20`
|
||||
are the paired next-or-previous shell commands that first prefer `StationDetail.win`, then the
|
||||
live building-detail family, then `CompanyDetail.win`, and finally the sibling singleton at
|
||||
`0x006d3b20` before falling back to the localized notice pairs `0x017a/0x017b` and
|
||||
`0x017c/0x017d`. The adjacent direct subject-openers are tighter now too:
|
||||
`shell_open_or_focus_train_detail_for_current_or_first_owned_train` `0x00441040` reuses current
|
||||
detail subject `[detail+0x78]` or falls back to the first owned train for the selected chairman
|
||||
company before re-entering `shell_detail_panel_transition_manager` with mode `2`, while
|
||||
`shell_open_or_focus_station_detail_for_current_or_first_owned_linked_station` `0x004410d0`
|
||||
reuses `[detail+0x80]` or falls back to the first owned linked station before the same transition
|
||||
manager is re-entered with mode `5`. Two later registered command siblings are now bounded only
|
||||
structurally but still usefully: `0x00441160` requires active scenario plus live world root
|
||||
`0x0062c120` and dispatches either
|
||||
`world_enable_preview_mode_0x15_latch_and_enter_if_idle` `0x00453370` or
|
||||
`world_disable_preview_mode_0x15_latch_and_clear_if_active` `0x00453780` by the query at
|
||||
`world_query_preview_mode_0x15_latch_active` `0x00450150`,
|
||||
while `0x004411a0` requires active scenario plus live route-store root `0x006cfca8` and
|
||||
dispatches either `0x00491880` or `0x004932a0` by the boolean result of `0x004934a0(0)`.
|
||||
The next registered shell-command strip is bounded the same way now:
|
||||
`shell_command_toggle_shared_world_preview_global_0x62be84` `0x00441240` flips the shared
|
||||
preview-oriented global `0x0062be84`,
|
||||
`shell_command_open_detail_panel_mode_0x19_variant_0_via_game_uppermost_overlay` `0x00441260`
|
||||
and `...variant_1...` `0x004412a0` both route through
|
||||
`shell_open_detail_panel_mode_0x19_variant_and_refresh_game_uppermost_overlay` `0x00433da0`,
|
||||
which restyles `GameUppermost.win` controls `0x7923..0x7925`, mirrors the chosen variant across
|
||||
detail controls `0x07db..0x0837`, transitions the detail manager into mode `0x19`, and forwards
|
||||
the selected variant into
|
||||
`world_view_set_mode_0x19_variant_latch_seed_controller_blend_and_mark_dirty` `0x0043a0a0`, and
|
||||
`shell_command_enable_shell_state_band_0x1df_and_refresh_derived_year_thresholds` `0x004412e0`
|
||||
re-enters `scenario_state_rebuild_derived_year_threshold_band` `0x004351c0` and then rewrites the
|
||||
paired shell-state dwords at `[0x006cec74+0x1df/+0x1e3]` through `0x00482850`. Those three
|
||||
commands are still structurally named rather than semantically named, but the current static owner
|
||||
boundaries are now explicit. The same command band is tighter at both edges too: `0x004411e0`
|
||||
simply flips presenter dword `[0x006d4024+0x114276]` when the main shell presenter is live, and
|
||||
`0x00441200` is the adjacent active-scenario gate that injects shell message `0xcb` for control
|
||||
`0x9858` through
|
||||
`shell_dispatch_synthetic_12_dword_descriptor_from_five_scalars` `0x00538e00`. The later edge
|
||||
of the same shell strip is bounded too:
|
||||
`0x00441ac0` and `0x00441af0` are the two small active-scenario plus shell-idle wrappers over
|
||||
`shell_map_file_entry_coordinator` `0x00445ac0`, forwarding flag triplets `(0,0,0)` and
|
||||
`(0,1,0)` respectively, while `0x00441b20` is the neighboring live-world clamp that ensures
|
||||
`[world+0x168d]` never falls below `[world+0x1689]`. The next broader neighbor is now grounded
|
||||
too: `shell_command_toggle_editor_map_mode_with_one_shot_warning_modals` `0x00441b50` is the
|
||||
real editor-map-mode toggle owner above `0x00482e50`. It branches on current shell mode
|
||||
`[0x006cec74+0x68]`, uses one-shot latches `0x0062be88` and `0x0062be8c` to gate localized
|
||||
warnings `0x017e` and `0x0b24`, and on the non-editor side can instead raise warning `0x0b6e`
|
||||
when `0x004349a0` reports more than one active profile. After those gates it forwards target mode
|
||||
`([shell+0x68] == 0)` into
|
||||
`shell_set_editor_map_mode_and_refresh_detail_panel_world_and_graphics_side_effects` `0x00482e50`.
|
||||
The adjacent startup-year strip is grounded now too:
|
||||
`shell_command_raise_startup_selected_year_scalar_by_half_step_and_refresh_calendar` `0x00441cb0`
|
||||
and `shell_command_lower_startup_selected_year_scalar_by_half_step_and_refresh_calendar`
|
||||
`0x00441d20` are the paired registered commands beneath localized ids `0x0db5/0x0db6`. Both
|
||||
require active scenario state plus the same single-profile gate from `0x004349a0`, clear shell
|
||||
dwords `[0x006cec74+0x233]` and `[+0x124]`, then adjust startup scalar `[0x006cec78+0xbfa]` by
|
||||
`+0.5` or `-0.5` before re-entering
|
||||
`world_set_selected_year_and_refresh_calendar_presentation_state` `0x00409e80` with absolute
|
||||
counter `[0x006cec78+0x15]` and refreshing the live world view through `0x00439a80`. The exact
|
||||
player-facing command labels are still open, but the static owner boundary is now clear: these
|
||||
are not generic shell scalars, they are the paired half-step selected-year presentation commands.
|
||||
The adjacent progress-status side is tighter now too:
|
||||
`shell_build_percent_status_payload_clamped_0_to_100` `0x00441d90` is the shared save or load
|
||||
progress payload builder, and
|
||||
`shell_progress_callback_publish_incremental_percent_status_until_target` `0x00441e20` is the
|
||||
throttled callback installed at `0x00442960` through global `0x00d93988`. That callback advances
|
||||
the progress latches `0x0062bec8/0x0062becc/0x0062c118`, rebuilds the percent payload through
|
||||
`0x00441d90`, republishes it through `0x00538c70`, and services the shell frame through
|
||||
`0x00482160`. The surrounding `0x00445de0` callers keep that pair on the save or load progress
|
||||
side of the shell strip rather than as another input-command family. The adjacent companion-image
|
||||
file seam is bounded now too:
|
||||
`shell_map_bundle_load_companion_image_file_into_global_staging_buffer_and_sync_tags`
|
||||
`0x00441f70` and
|
||||
`shell_map_bundle_write_global_staging_buffer_to_companion_image_file_and_return_path`
|
||||
`0x004420f0` are the paired `_A.tga` / `_A.jpg` import and export helpers around the same
|
||||
tagged selector strip at `0x00441ec0`. Both derive an extensionless stem through
|
||||
`support_copy_string_stem_before_first_dot` `0x0051dde0`, choose the `_A.tga` versus `_A.jpg`
|
||||
suffix by selector byte `[record+0x09]`, and then shuttle the file bytes through the shared
|
||||
staging descriptor rooted at `0x0062bed4/0x0062bed8`. That keeps the family grounded on the same
|
||||
fallback descriptor later reused by
|
||||
`world_presentation_rebuild_four_overlay_surface_slots_from_source_or_fallback` `0x00535430`,
|
||||
instead of leaving it as an isolated save-side file copier. The neighboring exporter
|
||||
`shell_export_live_setup_preview_payload_record_and_normalize_pixel_block_0x100x0x100`
|
||||
`0x00442ba0` is bounded now too: it copies the live setup payload from `[this+0x66be]`,
|
||||
patches world dimensions and three shell bytes into offsets `+0x01..+0x0b`, and then
|
||||
normalizes the embedded `0x100 x 0x100` pixel block at `+0x03c2` through `0x0047a120`
|
||||
before the save-side callers forward that same record into `0x00441ec0` or the tagged
|
||||
slot-table serializer at `0x00446312`. The broader sibling
|
||||
`shell_build_temp_surface_from_payload_preview_pixels_and_query_named_resource_field_0x46`
|
||||
`0x00442740` is bounded now too: it copies the embedded preview pixels at `[record+0x03c2]`
|
||||
into a temporary `0x40000`-byte RGBA buffer, constructs one temporary `0xec`-byte surface-like
|
||||
owner through `0x0053b070 -> 0x00543980( pixels, 0x100, 0x100, 0 )`, forwards the caller path
|
||||
plus fixed selector `0x46` into `0x00542f50`, stores the returned dword into payload field
|
||||
`[record+0x18]`, and then releases the temporary owner again through `0x00542c90` and
|
||||
`0x0053b080`. That keeps the short save-side branch at `0x00445925` grounded as a one-shot
|
||||
preview-surface query helper rather than leaving another anonymous image-copy leaf between the
|
||||
tagged export path and the progress notice strip. The broader sibling
|
||||
`shell_map_bundle_rewrite_companion_payload_file_via_tmp_path_and_progress_callback`
|
||||
`0x004427c0` is now bounded as the temporary-path owner above that same tag strip: it derives
|
||||
`%1.tmp` from the source path, installs progress callback `0x00441e20` in `0x00d93988`,
|
||||
rewrites the middle payload band rooted at `+0x03ce` through `0x00553000`, writes the result
|
||||
back out through `0x005a276f`, updates payload dword `[record+0x18]`, and only then re-enters
|
||||
`0x00441ec0`.
|
||||
The sibling `shell_map_bundle_rewrite_companion_payload_file_from_record_offsets_and_sync_tags`
|
||||
`0x00442900` is bounded now too: it takes the live payload record in `EAX`, reads the full
|
||||
companion file named by the caller path, installs the same progress callback, rewrites the
|
||||
middle payload through `0x00553000` using stored offsets `[record+0x18/+0x1c]`, and then writes
|
||||
the output back in four spans: the leading `0x03ce` bytes, the transformed middle payload, the
|
||||
untouched interval `[record+0x18 .. record+0x1c)`, and the remaining tail. It then stores the
|
||||
caller path back into `[record+0x18]` and re-enters `0x00441ec0`. That closes the offset-driven
|
||||
save-side sibling reached from `0x004459dd` after `0x00441f70`, so the companion-payload strip
|
||||
is no longer split between one named temp-path owner and one anonymous offset-band rewrite body.
|
||||
The underlying temporary-surface seam beneath those save-side helpers is bounded now too.
|
||||
`surface_owner_allocate_first_free_row_slot_0xa0_and_seed_dimensions_and_type` `0x00541b10`
|
||||
scans the eight-entry row band `[this+0xa0..+0xbc]`, allocates one `0x32`-byte row, seeds width,
|
||||
height, and type, and returns the chosen slot index; `0x00541ba0` is the indexed release-side
|
||||
companion. `surface_owner_open_named_resource_and_dispatch_row_type_import` `0x00542f50` is the
|
||||
named-resource dispatcher used by `0x00442740`: it opens the caller-seeded resource path,
|
||||
forwards the result into `0x005428c0`, and then dispatches by imported row type
|
||||
`[row+0x18] = 2/3/4`. `surface_owner_commit_backing_rgba_buffer_recompute_size_and_republish`
|
||||
`0x005438d0` is the commit-side publish helper over the active RGBA backing buffer
|
||||
`[row+0x26]`, while `surface_owner_init_or_ensure_rgba_surface_from_pixels_dims_and_mode`
|
||||
`0x00543980` is the constructor or ensure owner that allocates one first-use slot through
|
||||
`0x00541b10(..., width, height, 3)` and then commits the caller pixels through `0x005438d0`.
|
||||
That keeps the save-side preview seam tied back to the same reusable surface-owner family already
|
||||
visible in the world-presentation and shell-overlay branches, instead of leaving the temporary
|
||||
preview query path grounded only at the leaf helper level.
|
||||
The lower surface-owner base is bounded now too. `surface_owner_base_init_and_register_on_global_list`
|
||||
`0x00540e30` seeds the fixed owner label, capability bytes, helper-object pair, row-slot bands,
|
||||
and global intrusive registration under `0x00ccbb2c`; `surface_owner_refresh_cached_byte_totals_and_release_all_row_buffers`
|
||||
`0x00540fc0` is the shared maintenance owner that recomputes cached byte totals `[this+0xcc/+0xd0]`
|
||||
across the eight row slots and also owns the full row-buffer release pass; and
|
||||
`surface_row_repack_rgba_or_rgb32_into_active_16bit_buffer_with_palette_mode_gate` `0x00541210`
|
||||
is the row-side repack body that converts the active backing pixels into the live 16-bit buffer
|
||||
`[row+0x2a]`, either through a palette-like accumulated-channel path or a direct nibble-packed
|
||||
conversion path depending on owner byte `[this+0x96]`. That closes the reusable surface family
|
||||
one layer deeper instead of stopping at the first slot allocator and commit helpers.
|
||||
The two remaining compact helpers in that same seam are bounded now too.
|
||||
`surface_owner_query_dimension_cap_from_mode_and_quality_band` `0x00541160` derives the active
|
||||
power-of-two size cap `0x100/0x200/0x400/0x800` from owner byte `[this+0x05]`, shell gate
|
||||
`[0x006d4024+0x11422f]`, and selector dword `[this+0xd8]`, while
|
||||
`surface_owner_probe_named_file_for_type2_header_signature` `0x005411c0` is the adjacent file
|
||||
probe that opens one named path, reads `0x12` header bytes, and accepts only the local type-`2`
|
||||
signature. The broader survivor above them is bounded now too:
|
||||
`surface_row_encode_active_pixels_and_write_tagged_records_to_open_stream` `0x005428c0`
|
||||
allocates temporary alpha and RGB planes from the active row, splits the current backing pixels,
|
||||
seeds the local codec object, and then writes the tagged record family `0xbaba/0xbabb/0xbabe`
|
||||
into the already-open stream, either directly or through the transformed payload path via
|
||||
`0x00553000`. That closes the immediate import-export seam under `0x00542f50`; the next open
|
||||
work in this branch is no longer a still-missing leaf, but the broader type-specific row owners.
|
||||
Those are bounded now too. `surface_row_import_tagged_baba_babb_babe_payload_to_rgba_buffer`
|
||||
`0x00541c30` is the type-`4` importer that validates the `0xbabe` lead tag plus the later
|
||||
`0xbaba/0xbabb` branches, reconstructs one RGBA row from the tagged payload bands, and then
|
||||
re-enters `0x00541210`. `surface_row_import_headered_rgb_or_paletted_payload_to_rgba_buffer`
|
||||
`0x00542030` is the type-`3` importer that validates the recovered width, height, and pixel-size
|
||||
header, allocates a full RGBA destination plus temporary staging, and decodes the supported
|
||||
`0x18`/`0x20` source families into RGBA rows. `surface_row_import_dds_dxt3_payload_and_optionally_materialize_buffer`
|
||||
`0x00542d50` is the type-`2` importer: it validates `DDS `, enforces the dimension cap from
|
||||
`0x00541160`, copies the block-compressed payload from offset `0x80`, stores format tag
|
||||
`DXT3`, and optionally materializes the live companion buffer through `0x005423d0`.
|
||||
That closes the current type-dispatch branch under `0x00542f50` without leaving its three row
|
||||
owners as anonymous stream bodies.
|
||||
The direct export-side sibling is bounded now too.
|
||||
`surface_owner_write_first_row_rgba_payload_with_0x12_byte_header_to_named_file` `0x00542b30`
|
||||
is the paired file-write alternative to `0x00542f50`: it opens one caller path in `wb` mode,
|
||||
builds the compact `0x12`-byte header with row type `2`, first-row width and height, fixed
|
||||
pixel-size byte `0x20`, and one optional `0x20` flag bit from the second caller argument, then
|
||||
optionally forces RGBA materialization through `0x00541970` and writes the first-row RGBA payload
|
||||
`[row+0x26]` plus that header to the open stream. The paired callers at `0x00520cda`,
|
||||
`0x00520f61`, and `0x00534dd6` all use it as the direct-file branch immediately before the same
|
||||
temporary-surface release through `0x00542c90 + 0x0053b080`, so the current export/import seam is
|
||||
no longer split between one named importer and one anonymous file-write sibling.
|
||||
The small dispatch sub-strip under that importer is bounded now too.
|
||||
`surface_owner_dispatch_row_import_by_embedded_type` `0x00542fb0` is the direct selector over
|
||||
embedded row type `[row+0x18]`, routing type `2/3/4` to `0x00542d50/0x00542030/0x00541c30`.
|
||||
The wrapper immediately above it,
|
||||
`surface_owner_allocate_temp_row_slot_dispatch_import_and_release_on_failure` `0x00543000`,
|
||||
clears selector field `[this+0x07]`, allocates one fresh row slot through `0x00541b10`,
|
||||
re-enters `0x00542fb0`, drops the slot again through `0x00541ba0` on the `1/2` failure paths,
|
||||
and then refreshes cached byte totals through `0x00540fc0`. That closes the type-dispatch seam
|
||||
between the file-open owner and the per-row import bodies instead of leaving one more anonymous
|
||||
slot wrapper in the middle.
|
||||
The lower lifecycle in that same surface-owner family is tighter now too.
|
||||
`surface_owner_query_or_materialize_rgba_buffer_from_active_16bit_row` `0x00541970` is the
|
||||
shared query-or-materialize helper for non-type-`2` rows: it optionally returns width and height,
|
||||
returns `[row+0x26]` when RGBA backing pixels already exist, and otherwise expands the live
|
||||
16-bit source buffer `[row+0x2a]` into nibble-doubled RGBA dwords before storing the new backing
|
||||
pointer back into `[row+0x26]`. The broader sibling
|
||||
`surface_owner_capability_gated_postprocess_non_type2_rows_into_live_16bit_buffers` `0x00542550`
|
||||
is the next owner above that helper: when shell capability byte `[0x006d4024+0x11422d]` is live
|
||||
and local latch `[this+0x95]` is still clear, it revisits the active row slots, skips type-`2`
|
||||
and already-processed rows, forces RGBA materialization through `0x00541970`, marks row byte
|
||||
`[row+0x21]`, seeds row state `[row+0x1c] = 0x3c`, discards the previous 16-bit output buffer,
|
||||
and rebuilds `[row+0x22/+0x2a]` from a float-heavy neighbor-difference transform over the RGBA
|
||||
source, halving `[row+0x04]` on the `0x20`-pixel-size branch. The release-side owner is bounded
|
||||
now too: `surface_owner_release_helpers_unlink_global_entry_and_drop_row_slots` `0x00542c90`
|
||||
releases optional helper roots `[this+0xdc/+0xe4]`, unlinks the owner from the global intrusive
|
||||
list rooted at `0x00ccbb2c`, conditionally refreshes the live shell presenter when `[this+0x93]`
|
||||
is set, and then drops both the selector-side handle and all row slots through
|
||||
`0x00541780` and `surface_owner_release_all_row_slots_0xa0` `0x00542870`. That closes the
|
||||
reusable surface-owner seam one level deeper instead of stopping at construction, import, and
|
||||
commit helpers.
|
||||
The remaining tiny surface-owner leaves in that strip are bounded now too.
|
||||
`surface_owner_query_first_row_width_or_one` `0x00541aa0` and
|
||||
`surface_owner_query_first_row_height_or_one` `0x00541ad0` are the fallback-safe first-row
|
||||
geometry getters used by later projection and world-presentation math paths, while
|
||||
`surface_owner_refresh_cached_shell_scalar_0xd4_and_return_bound_handle_0xc0` `0x00541bf0`
|
||||
simply refreshes cached scalar `[this+0xd4]` from the live shell presenter and returns
|
||||
`[this+0xc0]`. The last tiny release helper `surface_owner_release_selector_handle_0x07_if_present`
|
||||
`0x00541c10` does exactly what the current name says: when `[this+0x07]` is live it re-enters
|
||||
`0x00541780` and clears that handle back to zero.
|
||||
The later owner `shell_apply_scenario_name_specific_post_load_world_and_object_fixups`
|
||||
`0x00442c30` is bounded now too: `world_entry_transition_and_runtime_bringup` re-enters it at
|
||||
`0x00444b50` with the loaded scenario title, and it dispatches on many fixed `.rdata` names
|
||||
including `Go West!`, `Germany`, `France`, `State of Germany`, `New Beginnings`, `Dutchlantis`,
|
||||
`Britain`, `New Zealand`, `South East Australia`, `Tex-Mex`, `Germantown`, `The American`,
|
||||
`Central Pacific`, and `Orient Express`, with several branches further gated by setup payload
|
||||
byte `[this+0x66de]`. The matched branches then perform targeted live-world edits rather than a
|
||||
generic title-side publish: they patch object-state dwords and bytes inside collections rooted at
|
||||
`0x0062be18`, `0x0062bae0`, and `0x006ada80`, adjust selected float and scalar fields, copy
|
||||
paired ten-dword record blocks when specific name/class pairs match, flip secondary-raster bits
|
||||
through table `0x005ee508..0x005ee5cc`, retune a later collection at `0x0062b268`, and inject
|
||||
scenario-specific text lines into the shell-owned band `[this+0x4f30]` through repeated
|
||||
`0x0051e5d0`. That finally makes the broad post-load scenario-fixup seam explicit instead of
|
||||
leaving it as an unbounded string-switch body beneath world entry.
|
||||
One neighboring status helper is bounded now too:
|
||||
`shell_publish_progress_sample_notice_from_byte_delta_and_elapsed_ticks` `0x00442660` is the
|
||||
shared byte-delta and elapsed-time notice builder used by both the bundle-service strip and the
|
||||
save-side progress loop. It measures the current byte counter through `0x00530b70`, formats the
|
||||
rounded kilobyte delta and elapsed ticks through `%5d` and `% 4d`, packages them through
|
||||
`0x005193f0 -> 0x00518de0 -> 0x0051d680`, and then updates the running previous-counter latch
|
||||
`0x0062c11c`.
|
||||
That setter writes `[shell+0x68]`, then either rebuilds the editor-side shell surface through
|
||||
`0x004d4500` or refreshes the detail-panel and world side through `0x004d44a0`, `0x004dfda0`,
|
||||
and `0x0044fb70`, before both branches pulse graphics side effects through `0x00484d70(0x0d, 1)`.
|
||||
The adjacent display-settings strip is bounded now too:
|
||||
`shell_command_cycle_display_resolution_forward` `0x00483680` is the registered `+1` command
|
||||
wrapper into `shell_cycle_display_resolution_and_publish_status` `0x00483780`, while
|
||||
`0x00483990` and `0x004839a0` are the plain `+1` and `-1` wrappers into that same shared owner.
|
||||
The owner requires the live shell presenter `0x006d4024`, walks the supported resolution tables
|
||||
at `0x00620e64/0x00620e7c`, applies the chosen size through `0x005206b0`, publishes the updated
|
||||
size string through `0x0051b700`, `0x00518de0`, and `0x005386e0`, and then refreshes dependent
|
||||
presentation state through `0x004625b0`, `0x00484910(1)`, and `0x004821d0`. After that point the
|
||||
embedded world-view controller strip is tighter now too.
|
||||
`world_view_sample_local_clearance_ring_clamp_eye_height_and_optionally_republish_triplet`
|
||||
`0x00439820` samples a five-point local clearance ring around the current eye X/Z pair through
|
||||
`0x00534490`, keeps the highest sample, expands it through `0x0052d0c0` plus fixed margins, and
|
||||
republishes the eye triplet through `0x0052d1e0` when the current eye height needs to be lifted.
|
||||
The embedded controller base beneath that path is now first-class instead of only being referenced
|
||||
indirectly: `0x0052d140` stores the four blend scalars at `[+0x50..+0x5c]`, `0x0052d180` stores
|
||||
the focus triplet and raises dirty byte `[+0x64]` when it changes, `0x0052d1e0` stores the eye
|
||||
triplet and refreshes sampled vertical delta `[+0x66]`, `0x0052d230` extracts focus-to-eye
|
||||
distance plus heading/pitch-like angles, `0x0052d2b0` serializes the focus, eye, and orientation
|
||||
lanes into one camera-view snapshot record, `0x0052d400` is the inverse helper that rebuilds the
|
||||
focus triplet from eye, heading, pitch, and distance, `0x0052d450` rebuilds the eye triplet from
|
||||
focus, heading, pitch, and distance, `0x0052d640` clamps distance against sampled eye height,
|
||||
`0x0052d750` is the stream-load companion that rehydrates one stored camera-view snapshot back
|
||||
into the controller base, and `0x0052d570/0x0052d5a0/0x0052d6f0/0x0052d860` are the
|
||||
base-reset, default-seed, seed, and reset-plus-seed constructor owners. One level higher,
|
||||
the compact accessor and dirty-latch strip is bounded now too: `0x0052cd20/0x0052cd60` export the
|
||||
current eye triplet as packed or split outparams, `0x0052cd40/0x0052cd80` do the same for the
|
||||
focus triplet, `0x0052cda0/0x0052cdc0` are the matching load-store helpers for auxiliary triplet
|
||||
`[+0x2c..+0x34]`, `0x0052cde0/0x0052ce20` snapshot the current focus, heading, and distance bands
|
||||
into the two cached companion strips when their paired dirty latches are cleared, and
|
||||
`0x0052ce70` refreshes shell presenter scalar `[+0x6a]` while consuming the primary dirty latch
|
||||
back to zero; the next compact query strip is bounded now too: `0x0052cea0` exports heading and
|
||||
pitch lanes `[+0x10/+0x14]`, `0x0052cec0` samples owner height at current eye X/Z,
|
||||
`0x0052cf00` broadens that into a clamped XY-extent peak-height query, `0x0052d0c0` is the
|
||||
current-eye wrapper into that peak-height query, and `0x0052d0f0` is the normalized scalar-band
|
||||
containment predicate over `[+0x50..+0x5c]`. One level higher,
|
||||
`world_view_refresh_dependent_projection_visibility_and_presentation_scalars` `0x0043bde0`
|
||||
now bounds the larger refresh pass that derives visibility and presentation-side scalars from the
|
||||
current focus and eye triplets before later motion and input branches resume. The load-side owner
|
||||
one layer above that strip is bounded now too:
|
||||
`world_view_load_camera_snapshot_release_pending_helper_and_reseed_blend_scalars` `0x0043ac30`
|
||||
releases any pending helper handle, clears presenter ownership, resets the local controller strip,
|
||||
rehydrates one stored camera-view snapshot through `0x0052d750`, conditionally loads one
|
||||
extra-row band into `[this+0x10e]`, reseeds the four controller blend scalars through
|
||||
`0x0052d140(0, 0, 1.0, 0.7)`, and then normalizes heading before control returns to the broader
|
||||
world-view owner family. The adjacent low-side layout-state strip is bounded now too:
|
||||
`0x00544290/0x00544360` publish or reset the local descriptor blocks rooted at
|
||||
`[layout+0x352f]` and `[layout+0x34ef]`; the next setter strip `0x00544cb0..0x005450a0`
|
||||
publishes or clears bound-node property pairs `0x0d/0x0e`, packed property `0x3c`, grouped
|
||||
property `0x0b`, the broader capability and mode-gated slot strips
|
||||
`0x1d/0x13/0x14/0x12` and `0x15/0x1a/0x11/0x10`, plus the cached-byte-backed property `0x89`;
|
||||
and `0x005450c0/0x005450e0/0x00545130` export the cached local block `[layout+0x24f0]` and the
|
||||
negated local scalar triplet `[layout+0x2517/+0x251b/+0x251f]`, with the middle lane clamped up
|
||||
to `0.5f`. One level lower, `0x00545180` builds the generated default preset table rooted at
|
||||
`[layout+0x840]` as `0x90` fixed `0x33`-byte rows from an angular sweep, while
|
||||
`0x00545400/0x00545470/0x005454a0` are the adjacent indexed row setters and query helpers over
|
||||
that same table and `0x00545420/0x00545440` are the paired scalar-array siblings for
|
||||
`[layout+0x25f7/+0x25ff]`; the next local strip `0x005457c0/0x005458a0/0x005458d0` publishes
|
||||
one property-`0x8b` stack descriptor on the bound node and borrows or releases the current
|
||||
segment-record window handle `[layout+0x265b]` with global counter `0x00ccd824`; the immediate
|
||||
sibling wrappers `0x005459f0/0x00545a20/0x00545a40/0x00545a70/0x00545aa0/0x00545ac0/0x00545af0/0x00545b90/0x00545bb0/0x00545be0`
|
||||
repeat the same borrow-release pattern for the adjacent table handles `[layout+0x2643/+0x2647/+0x264b/+0x264f/+0x2653/+0x263f]`.
|
||||
The last clean local leaves after that are `0x00545ca0/0x00545d50/0x00545d60/0x00545db0/0x00545e00`,
|
||||
which cover the first-slot clear plus type-`1` span commit, the accumulated span counter query,
|
||||
the counter reset and optional bound-node reseed, the bound-node finalize-and-optional-clear
|
||||
helper, and the small bound-node signature classifier. One level up, the next owner body is
|
||||
bounded now too: `0x00545e30` queries one external/provider report and builds summary text in
|
||||
buffer `[layout+0x43c]`, falling back to localized id `0x73` when the provider lookup fails and
|
||||
otherwise appending the localized fragment strip `0x74..0x7d` plus the fixed format family
|
||||
`%1(16-bit HW) ` / `%1(8-bit HW) ` / `%1(8-bit) ` / `%1(16-bit) ` from the returned report. The
|
||||
adjacent reset-and-property strip is also tighter now: `0x005464d0` runs one repeated four-pass
|
||||
bound-node reset sequence, `0x00546540/0x00546560` force property `0x17` to `7` or `4`,
|
||||
`0x00546580/0x005465a0` clear or raise property `0xa8`, `0x005467a0/0x005467e0` are the paired
|
||||
one-bit gate writes for property `0x1c`, and `0x00546810/0x00546850/0x00546890` are the
|
||||
template-gated and clear-side mode writes for property `0x16` via local mode byte
|
||||
`[layout+0x254a]`. One level higher again, `0x0054a0c0` is now bounded as the broader setup-side
|
||||
owner above that strip: it binds one external source onto the bound presentation node, falls
|
||||
back to the midband release helper when that bind fails, conditionally reapplies the cached
|
||||
gamma-ramp scalar from `[[layout+0x83c]+0x2f]`, seeds optional handle `[layout+0x33ab]` through
|
||||
the small `0x00570fbd -> 0x00570f86` refcounted `0x14`-byte object helper pair, which now opens
|
||||
into a tighter row-container family: `0x0057091d` reserves one `0x40`-byte row block from the
|
||||
fixed template `0x0056cd2c`, with `0x005708ce/0x005708f2` as the aligned block alloc/free
|
||||
helpers, `0x00570908/0x005709da` as the destructor and release-side wrappers,
|
||||
`0x00570fa1` as the direct refcount-drop path, `0x0057098b` answering only `IUnknown` plus one
|
||||
custom IID, and `0x005709f6` as the first grow-and-duplicate-last-row owner. The next
|
||||
current-entry strip is also bounded now:
|
||||
`0x00570aac` seeds the current `0x40`-byte entry to an identity 4x4 matrix, `0x00570b0d`
|
||||
stores one caller matrix directly into that current slot, and `0x00570b2c/0x00570b76` are the
|
||||
two immediate left/right composition siblings over the same current matrix through
|
||||
`0x0056d3cd`. One level wider, the same family now has three helper-generated matrix-pair
|
||||
variants too: `0x00570bc0/0x00570c2f` build a temporary matrix through `0x0056df7d`,
|
||||
`0x00570c9e/0x00570d1a` do the same through `0x0056e1a8`, and `0x00570d96/0x00570e12` plus
|
||||
`0x00570e8e/0x00570f0a` do the same through `0x0056dc9a` and `0x0056dd2a`, with each pair
|
||||
preserving the same right- and left-side current-matrix composition split. The adjacent helper
|
||||
region is now bounded as one sibling COM-style object pair too: `0x0057aef3/0x0057aedb/0x00571016`
|
||||
are the init, refcount-drop, and release-side wrappers for vtable `0x005def30`, with
|
||||
`0x0057ad5a` as the direct addref helper,
|
||||
`0x0057ad20` as its destructor and `0x0057ae97` as its `IUnknown` plus custom-IID query gate,
|
||||
`0x0057ad67` as its resource-field bind plus attached-object and payload-copy owner,
|
||||
`0x0057add4/0x0057adfb` as the attached-object getter and fixed payload copy-out helpers, and
|
||||
`0x0057ae0f/0x0057ae1e/0x0057ae2d/0x0057ae53/0x0057ae79/0x0057ae88` as the direct pass-through
|
||||
wrappers over resource field `[+0x48]` and payload block `[+0x08]`,
|
||||
while `0x0057af0e/0x00571032` are the destructor and release-side wrapper for sibling vtable
|
||||
`0x005def5c`, with `0x0057af4e` as the matching addref helper, `0x0057af5b` as the target-attach
|
||||
plus cached-flag derivation owner, `0x0057afd0` as the target getter, and `0x0057aff6` as the
|
||||
one-shot target-handle release helper, `0x0057b021` as the paired two-handle clear path,
|
||||
`0x0057b065` as the matching `IUnknown` plus custom-IID query gate, `0x0057b0a9` as the
|
||||
refcount-drop helper, `0x0057b0c1` as the first broader target-handle and property-strip
|
||||
seeding owner, and `0x0057b4fd` as the next target-side transform-block builder over optional
|
||||
anchor pairs plus caller angle and scale. The resource-field branch under `0x0057ae0f..0x0057ae88`
|
||||
is now tighter too: `0x00580867` is the small constructor-style init for the `0xb0`-byte
|
||||
target-service object, clearing the embedded entry-band roots, ready byte, auxiliary handle
|
||||
fields, and cache link; `0x005808b2` is the matching full destructor, releasing the two
|
||||
target-bound service handles, both embedded eight-entry bands, attached object, target, the
|
||||
auxiliary handle family rooted at `[+0x6c/+0x98/+0x9c/+0xa8]`, and then unlinking the object
|
||||
from the global cache chain rooted at `0x00db89e4`; `0x005809ab` is the release-side wrapper for
|
||||
that destructor; `0x005809c7` seeds service handles `[+0x64]` and `[+0x68]`, invokes attached
|
||||
object `[+0x0c]` through slot `+0x10`, republishes those two handles through target slots `+0xdc`
|
||||
and `+0xd8`, and latches ready byte `[+0x60]`; `0x00580a54` is the paired clear-side sibling
|
||||
that releases handle `[+0x64]` through target slot `+0xd8`, notifies the attached object through
|
||||
slot `+0x1c`, and clears `[+0x60]`; `0x00580a84` is the broader release body over those target
|
||||
handles plus the two embedded eight-entry bands rooted at `[+0x10]` and `[+0x30]`;
|
||||
`0x00580aff` is the setup-side entry-band owner that chooses one of two fixed parameter triples
|
||||
from local mode byte `[+0x50]`, seeds scalars `[+0x54/+0x58/+0x5c]` through `0x00570669` and
|
||||
`0x00570691`, and dispatches live per-entry objects through slot `+0x3c`; `0x00580bb9` is the
|
||||
small auxiliary-handle release helper over the pointer band rooted at `[+0xa8]`; `0x00580bdc`
|
||||
is the direct refcount-drop path; `0x00580be8` is the constructor-side owner that stores target
|
||||
`[+0x04]`, derives mode byte `[+0x50]`, seeds the fixed scalar triple `[+0x54] = 0x15`,
|
||||
`[+0x58] = 0x40`, `[+0x5c] = 0x10`, builds the entry bands, and binds the auxiliary handle
|
||||
family rooted at `[+0x6c]`, `[+0x98]`, and `[+0x9c]`; and `0x00580d29` is the primary
|
||||
payload-dispatch and layout-style service owner below the `0x0057ae2d/0x0057ae53` wrappers,
|
||||
taking the target-service object, caller payload block, five caller arguments, and fixed
|
||||
mode-variant flag while using service handle `[+0x6c]` plus external callbacks
|
||||
`0x005c81e4/0x005c8248/0x005c824c`,
|
||||
and `0x0058123c` is the cache-or-create factory above that strip, walking the same global cache
|
||||
root `0x00db89e4` for a matching target, otherwise allocating one `0xb0`-byte object, running
|
||||
`0x00580867`, and finishing construction through `0x00580be8`. Immediately below that service
|
||||
factory the local container strip is now bounded too: `0x005812b1/0x005812c1/0x005812cf/
|
||||
0x0058133d/0x00581371` form the reset, release, push, pop, and status helpers for one growable
|
||||
dword-pointer vector, while `0x00581379/0x0058138c/0x005813bd/0x00581470/0x005814a4` do the same
|
||||
for the sibling growable string-pointer vector with accumulated byte count at `[+0x10]`, and
|
||||
`0x005814ac` is the first owner above that string-vector family, building one newline-joined
|
||||
text object from the stored strings. The adjacent object strip is now bounded too:
|
||||
`0x00581673/0x005815cf/0x005815dc/0x00581610` are the init, addref, refcount-drop, and release
|
||||
wrappers for vtable `0x005e0bd8`, `0x00581594` is the destructor, `0x005815a9` allocates the
|
||||
owned text buffer, `0x005815fc/0x00581606` are the direct getters for that buffer and its stored
|
||||
length, and `0x0058162c` is the matching `IUnknown` plus custom-IID query gate. The adjacent
|
||||
SIMD math strip is now bounded too: `0x00581690` applies the first two basis rows plus
|
||||
translation row `[+0x30]` to one XY pair and stores the full vec4 result, `0x005816d0` is the
|
||||
projective sibling that scales by a reciprocal derived from lane 3 and returns projected XY, and
|
||||
`0x00581730` is the translation-free low-64-bit sibling over just the first two basis rows,
|
||||
while `0x00581770/0x00581830/0x005818f0` are the corresponding 3D XYZ helpers for basis-only,
|
||||
basis-plus-translation, and projected basis-plus-translation output, `0x005819f0` is the direct
|
||||
4D vec4-by-4x4 basis application helper, `0x00581ab0` is the four-row batch sibling over a full
|
||||
4x4 source block, and `0x00581c00/0x00581cd0` are the shared normalize-or-zero helpers for vec3
|
||||
and vec4 input. One level wider, `0x00581db0` is now bounded as the shared 4x4 inversion helper
|
||||
with optional determinant outparam, `0x00582070` is the packed-output batch sibling to the
|
||||
earlier four-row 4D basis application helper, `0x005821d0` is a standalone 4D cross-product-like
|
||||
helper over three vec4 inputs, `0x00582280` is the unchecked vec4 normalization sibling, and
|
||||
`0x00582320/0x005823e0/0x00582470/0x00582520` are the first cubic-basis interpolation helpers
|
||||
in the same math strip for vec3, vec2, vec4, and the first alternate-basis vec3 case.
|
||||
The same family now extends cleanly through `0x005825e0` and `0x00582680` as the alternate-basis
|
||||
vec4 and vec2 siblings, then into `0x00582710/0x00582770/0x005827c0` as the two-scalar affine
|
||||
blend helpers computing `p0 + s*(p1-p0) + t*(p2-p0)` for vec3, vec4, and vec2 inputs.
|
||||
The next geometry leaves are bounded too: `0x00582820` is the plane-versus-segment intersection
|
||||
helper over one plane vec4 and two vec3 endpoints, `0x005828e0` is the standalone 4x4
|
||||
determinant helper beside the nearby inversion body, and `0x005829b0` builds one plane vec4
|
||||
from three vec3 points by cross product, normalization, and signed-distance writeout. The next
|
||||
quaternion strip is now bounded too: `0x00582c30` builds one 4x4 rotation matrix from a
|
||||
quaternion-like vec4, `0x00582d10` is the quaternion product helper, and `0x00582da0` is the
|
||||
unchecked quaternion-normalization sibling. The adjacent plane-and-quaternion leaves are tighter
|
||||
now too: `0x00582aa0` is the shared plane-driven projective 4x4 matrix builder over one plane
|
||||
vec4 and one second vec4 input, `0x00582e40` is the quaternion inverse helper that conjugates
|
||||
the spatial XYZ lanes and divides by squared length, `0x00582eb0` rebuilds one quaternion from a
|
||||
caller 3x3 rotation-matrix block, and `0x00582fd0` builds one quaternion from three caller Euler
|
||||
angles by halving them, routing the packed tuple through trig helper `0x0058aa70`, and then
|
||||
combining the resulting sine and cosine lanes. The next packed-row sibling strip is now bounded
|
||||
too: `0x005830a0` applies one compact 3x3 basis block to one vec3 input, `0x00583160` is the
|
||||
translation-bearing vec4 sibling, `0x00583220` is the packed projective vec3 sibling that scales
|
||||
by a reciprocal derived from lane 3, `0x00583320` is the packed 4x4 vec4 application helper,
|
||||
`0x005833e0` is its four-row batch sibling over a full caller 4x4 source block,
|
||||
`0x00583530/0x00583600` are the packed vec3 and vec4 normalize-or-zero siblings of
|
||||
`0x00581c00/0x00581cd0`, `0x005836e0` is the packed 4x4 inversion sibling with optional
|
||||
determinant outparam, `0x005839a0` is the packed-output batch sibling of `0x005833e0`, and
|
||||
`0x00583b00` is the packed-row sibling of the earlier 4D cross-product helper. The same packed
|
||||
analogue strip now extends further: `0x00583cc0` is the packed 4x4 determinant sibling,
|
||||
`0x00583d90` is the packed three-point plane builder, `0x00583e80` is the packed plane-driven
|
||||
projective 4x4 matrix builder, `0x00584010` is the packed quaternion-to-matrix sibling,
|
||||
`0x005840f0` rebuilds one quaternion from a packed 3x3 rotation-matrix block, and
|
||||
`0x00584210` is the packed Euler-angle-to-quaternion sibling using packed trig helper
|
||||
`0x0058ad50`. The lower trig seam is bounded now too: `0x00583bb0` and `0x00583c30` are the two
|
||||
single-angle packed axial rotation-matrix variants above the same trig layer, `0x0058ac60` is
|
||||
the interleaved packed sine/cosine helper they share, and `0x0058ad50` is the wider packed
|
||||
sin/cos vector generator used by the packed Euler-angle-to-quaternion helper. The MMX or 3DNow
|
||||
analogue seam is bounded now too: `0x005842e0` is the quaternion-product sibling,
|
||||
`0x00584379/0x005843d6` are the vec4 and vec3 normalize-or-zero siblings,
|
||||
`0x00584489` rebuilds one quaternion from a 3x3 rotation-matrix block,
|
||||
`0x005848ba` is the MMX or 3DNow Euler-angle-to-quaternion sibling using scalar trig helper
|
||||
`0x0058b660`, `0x0058497f` is the explicit axis-angle-to-quaternion sibling,
|
||||
`0x005849eb` is the core quaternion slerp helper, `0x00584b22` and `0x00584baf` are the next
|
||||
two nested-slerp multi-control helpers, `0x00584c41` is the quaternion inverse sibling,
|
||||
`0x00584ca5` extracts an axis-angle-style vec4 from one quaternion, and `0x00584d4c` is the
|
||||
scaled-axis-to-quaternion sibling. The next broader MMX owner is bounded now too: `0x00584df1`
|
||||
takes four caller key quaternions, aligns neighboring keys onto a common hemisphere, converts the
|
||||
two relative deltas around each interior key through the already-grounded inverse and
|
||||
axis-angle-style helpers, averages those tangent-like terms, exponentiates back into quaternions,
|
||||
and multiplies by the interior keys to write two inner spline-control quaternions. The immediate
|
||||
plane-and-matrix seam after that is tighter now too: `0x00585b4b` is the row-major MMX
|
||||
translation-matrix constructor, `0x00585b9b` is the MMX sibling to the shared plane-driven
|
||||
projective 4x4 matrix builder, `0x00585c86` is the paired plane-reflection matrix helper, and
|
||||
`0x0058a988` is the shared normalize-by-XYZ-length helper beneath those plane-driven bodies, while
|
||||
`0x0058a8ca` is the MMX origin-plane-versus-segment intersection sibling and `0x0058a9ec` is the
|
||||
MMX 4D vec4-by-4x4 basis application sibling. The immediate matrix seam after that is bounded
|
||||
too: `0x00585d62/0x00585dc5/0x00585e23` are the three single-angle MMX axial 4x4 rotation-matrix
|
||||
variants, `0x00585e7c` is the MMX diagonal scale-matrix constructor rather than a translation
|
||||
helper, `0x00585ec3` is the small 4x4 transpose or repack helper, `0x00585f32` is the MMX
|
||||
identity-matrix constructor, and `0x00585f6b/0x0058603d` are the two MMX quaternion-to-4x4
|
||||
rotation-matrix variants. The adjacent broader matrix owner beneath that constructor strip is
|
||||
bounded too: `0x0058584a` is the non-alias-staging MMX 4x4 multiply sibling that repacks one
|
||||
split-qword matrix to temporary contiguous rows before multiplying it through the second caller
|
||||
matrix, `0x00585a7c` is the scalar determinant helper for the upper 3x3 basis of the same
|
||||
split-layout 4x4 matrix family, `0x005860f2` is the broader affine-transform owner that builds
|
||||
one matrix from optional base translation, base rotation, pivoted post-rotation, and trailing
|
||||
translation-delta inputs, `0x0058728a` is the adjacent three-angle rotation-matrix builder that
|
||||
uses half-angle trig rather than the single-angle strip, `0x0058742f` is the uniform-scale
|
||||
sibling that adds one optional pivoted quaternion rotation and one trailing translation delta,
|
||||
`0x00587963` is the axis-angle rotation-matrix sibling over a normalized axis vec3 plus one
|
||||
caller angle, and `0x00587a7c` is the broader shared transform owner that supports one base
|
||||
translation, up to two optional pivoted quaternion rotations, and one trailing translation delta.
|
||||
One lower MMX sibling strip is bounded now too: `0x005895fa` is the
|
||||
3D basis-plus-translation-to-vec4 sibling of `0x00581830`, `0x0058966b` is the basis-only vec3
|
||||
sibling of `0x00581770`, `0x005896d2` is the vec3 normalize-or-zero sibling of `0x00581c00`, and
|
||||
`0x00589731` is the two-scalar affine vec3 blend sibling of `0x00582710`. The next MMX
|
||||
interpolation strip is bounded too: `0x005897a2` is the cubic-basis vec3 sibling of
|
||||
`0x00582320`, `0x00589876` is the alternate-basis vec3 sibling of `0x00582520`, `0x00589960` is
|
||||
the projective 3D basis-plus-translation sibling of `0x005818f0`, `0x005899eb` is the four-row
|
||||
4D basis application sibling of `0x00581ab0`, and `0x0058a1aa` is the cubic-basis vec2 sibling
|
||||
of `0x005823e0`. The remaining low-dimensional MMX strip is bounded now too: `0x0058a0b8` is the
|
||||
2D basis-plus-translation-to-vec4 sibling of `0x00581690`, `0x0058a10d` is the basis-only vec2
|
||||
sibling of `0x00581730`, `0x0058a146` is the projective 2D sibling of `0x005816d0`,
|
||||
`0x0058a242` is the affine vec2 blend sibling of `0x005827c0`, `0x0058a28b` is the vec2
|
||||
normalize-or-zero sibling, `0x0058a2ce` is the alternate-basis vec2 sibling of `0x00582680`,
|
||||
`0x0058a379` is the duplicate-layout 4D vec4-by-4x4 basis application sibling, `0x0058a3fb` is
|
||||
the four-lane normalize-or-zero sibling, `0x0058a45a` is the MMX 4D cross-product sibling of
|
||||
`0x005821d0`, `0x0058a58c` is the affine vec4 blend sibling, `0x0058a5fd` and `0x0058a6c5` are
|
||||
the cubic and alternate-basis vec4 siblings of `0x00582470` and `0x005825e0`, `0x0058a7a3`
|
||||
builds one plane vec4 from a normal vec3 plus point, and `0x0058a7e6` is the three-point plane
|
||||
builder sibling of `0x005829b0`. The broader MMX matrix seam just above those leaves is bounded
|
||||
now too: `0x00588eb2` is the alias-safe packed 4x4 multiply owner over two caller matrices,
|
||||
`0x00588bd0` and `0x005892aa` are the two broader MMX 4x4 inverse helpers with optional
|
||||
determinant output, `0x005895de` is the thin FEMMS wrapper over `0x005892aa`, `0x00589bb2` is
|
||||
the tiny thunk into the projective vec3 apply helper `0x00589960`,
|
||||
`0x00589bb7` selects identity or the ordered composition of up to three optional 4x4 inputs
|
||||
through `0x005899eb`, applies the resulting chain through `0x00589960`, and optionally remaps
|
||||
the normalized result into one caller integer viewport-style range block, `0x00589d3f` is the
|
||||
inverse-side sibling that composes the same optional chain, inverts it through `0x005892aa`,
|
||||
optionally maps one caller integer viewport-style coordinate triple back into normalized
|
||||
projective space, and then applies the inverse chain through `0x00589960`, and `0x00589f67` is
|
||||
the adjacent inverse-projective sibling that uses alternate inverse helper `0x00588bd0` before
|
||||
the same viewport-normalize and projective-apply tail. The scalar trig roots beneath the
|
||||
quaternion side are bounded now too: `0x0058af80` is the shared scalar `atan2`-style angle
|
||||
worker, `0x0058b080` is the shared scalar arccos-style angle worker, `0x0058b180` is the
|
||||
adjacent alternate arccos-style branch, `0x0058b280` and `0x0058b380` are the scalar natural-log
|
||||
and base-10-log helpers, `0x0058b3a0` is the scalar natural-exponential helper, `0x0058b480`,
|
||||
`0x0058b4a0`, `0x0058b4c0`, and `0x0058b500` are the scalar square-root, absolute-value,
|
||||
ceil-style, and floor-style helpers, `0x0058b540` and `0x0058b580` are the adjacent
|
||||
`frexp`-style split and `ldexp`-style scale helpers, `0x0058b5de` and `0x0058b600` are the
|
||||
compact `modf`-style split and `fmod`-style remainder helpers, `0x0058b660` returns one
|
||||
cosine/sine-style lane pair from one caller angle,
|
||||
`0x0058b780` is the paired scalar sine-lane helper used when callers only need that one branch
|
||||
duplicated, and `0x0058b9e0` is the broader scalar `pow(x, y)` owner that stitches the adjacent
|
||||
log and exponential strips back together. After that point the strip stops looking like separate
|
||||
command leaves and turns back into broader owner bodies. The next adjacent command leaves are
|
||||
bounded the same way:
|
||||
`shell_command_dispatch_scenario_followon_0x437d70_if_active` `0x00441340` is a guarded hop into
|
||||
the real cheat-code owner `shell_open_cheat_code_modal_and_dispatch_named_runtime_or_company_cheats`
|
||||
`0x00437d70`. That owner increments the shared shell counter at `[0x006d401c+0xc60]`, opens the
|
||||
localized cheat prompt `2922` `Do I detect a cheater in the house?\n\nEnter code (or <ESC> to
|
||||
cancel):`, and then scans the fixed 26-entry table at `0x005ee2c8`. The active selector strip is
|
||||
now grounded: winner/loss strings `3618/3619/3620/3622` route through `0x004367c0`, selector `1`
|
||||
jumps to the out-of-line reset branch at `0x004d676c` that clears the selected-company stat bands
|
||||
rooted at `[company+0x0cfb]`, `[company+0x0d7f]`, and `[company+0x1c47]`, selectors `2` and `3`
|
||||
post deltas into the selected company and selected chairman profile through `0x0042a080` and
|
||||
`0x00476050`, selector `4` resolves one locomotive by primary or alias stem through
|
||||
`0x00461c00` and applies it to every selected-company train through `0x004aefb0`, selector `5`
|
||||
forces territory-access byte `1` across the live territory table through `0x00424030`, selector
|
||||
`7` now reads more tightly as the train-crash branch because `0x004ad7a0(1)` is also the direct
|
||||
shell-command owner behind the `365` warning `There is no train available to crash!`, and
|
||||
selectors `6/8/9/10` toggle bytes `[state+0x4c8f/+0x4c8e/+0x4c8d/+0x4c8c]`. The same table also
|
||||
contains the later cheat labels
|
||||
`3634` `Orca` and the alias-only tail `Katie..Seymour`, but those rows currently sit above the
|
||||
visible jump-table bound `0x0a`, so the safest static read is that they are unreached or handled
|
||||
elsewhere rather than active cases in this owner. By contrast
|
||||
`shell_command_focus_subject_from_collection_0x62b244_via_selector_0x40b2d0` `0x00441360`
|
||||
requires the same single-profile gate, resolves one subject through `0x0040b2d0(0, 1)`, and then
|
||||
forwards that result into `shell_world_focus_selected_subject_kind_and_id` `0x00437a90`.
|
||||
The neighboring current-train command strip is bounded now too. Shared helper `0x00441790`
|
||||
resolves either the currently focused world-view train or one fallback train, but only keeps it
|
||||
when the owner company matches the current scenario-selected company. On top of that resolver,
|
||||
`0x00441810` is the direct `Current train crashes` command: it opens localized warning `365`
|
||||
when no owned train survives, otherwise it forwards the train into the crash owner
|
||||
`0x004ad7a0(1)`. `0x004418a0` is the paired `Current train breaks down` command with the same
|
||||
gate and warning `366`, but it forwards into the named breakdown owner `0x004ada00(1)`.
|
||||
`0x00441870` is the simpler `Current train whistles` command, which resolves the same owned train,
|
||||
finds the train-side visual owner through `0x004a77b0`, and writes request dword `1` into
|
||||
`[owner+0x33a]`. The immediately adjacent helper strip is bounded now too: `0x004a77d0` is a
|
||||
tiny two-float query over the same linked route object, defaulting both caller outputs to `10.0f`
|
||||
when `[train+0x41]` is empty and otherwise tail-calling the lower linked-route metric helper
|
||||
`0x0041add0`; and `0x004a7810` is the neighboring linked-route row-band refresh that walks
|
||||
`[route+0x316]` / `[route+0x31a]`, treats literal `steam` emitter definitions specially through
|
||||
`effect_name_matches_literal_steam` `0x004749a0`, and flips row byte `[row+0x1d8]` accordingly.
|
||||
The shell command strip on the other side is tighter too: `0x00441900`, `0x00441940`,
|
||||
`0x00441980`, `0x004419c0`, and `0x00441a00` are the five repeated `Overview.win` page toggles
|
||||
over detail-manager mode `9`, each closing the current page through
|
||||
`shell_detail_panel_transition_manager` `0x004ddbd0(-1, 0)` when that exact page is already
|
||||
active and otherwise requesting mode `9` with page ordinals `0..4`.
|
||||
`shell_station_list_format_freight_and_express_availability_summary` `0x00506e50` feeds the
|
||||
station-list summary `%1 has %2 freight loads and %3 express loads available for hauling...`, and
|
||||
the paired modifier helper `shell_station_list_handle_center_or_rename_action` `0x00506d50` owns
|
||||
the visible Shift-center and Ctrl-rename row actions. The list owner itself is tighter now too:
|
||||
`shell_station_list_window_refresh_rows_selection_and_status` `0x00506f30` is the real
|
||||
`StationList.win` row and status refresh pass, clearing and repopulating controls `0x61a9` and
|
||||
`0x61aa`, wiring the visible summary and modifier callbacks, mirroring the shared selected-station
|
||||
latch at `[0x006cec78+0x4cba]` when it still belongs to the current company, and updating the two
|
||||
status labels `0x61af` and `0x61b0`. The row-side callout lane is tighter too:
|
||||
`shell_station_list_row_callback_publish_station_callout_card` `0x00506ac0` is the actual
|
||||
row callback beneath both list controls, resolving the selected station, deriving one category
|
||||
header through `0x0053de00` and `0x00552560`, and then publishing the station-name plus freight
|
||||
and express callout card through repeated `shell_publish_text_callout_presentation` calls. The
|
||||
side-selector branch is tighter too:
|
||||
`shell_station_list_window_handle_message` no longer just re-enters the raw `StationPick.win`
|
||||
constructor. It flips the active side bit at `0x006d1710` and then re-enters the modal helper
|
||||
`shell_station_pick_window_open_modal_and_return_selected_station_id` `0x005078c0`, which
|
||||
allocates one helper window, runs `shell_station_pick_window_construct` `0x00507620`, brackets the
|
||||
modal show path, and returns the staged selected station id from `0x00622ae8`. Inside that helper
|
||||
family, `shell_station_pick_window_rewrite_list_and_scroll_messages_to_primary_select_event`
|
||||
`0x005075c0` now bounds the small message-normalization strip beneath controls `0x80e8..0x80ea`.
|
||||
The Shift-center side is tighter now too:
|
||||
the shared helper `0x00433900` takes one object pointer plus one small mode, derives one
|
||||
mode-specific `(distance,height)` preset from the target's virtual classification, and then
|
||||
re-enters `0x0043c9a0` to center the live world view on that object. The report side is clearer
|
||||
as well:
|
||||
`0x004d3060` is the dedicated `Stats - Trees` constructor over `map_editor_tree_stats_report`,
|
||||
`0x004d3080` is the actual `General Validation` constructor over
|
||||
`map_editor_general_validation_report`, and the same page table also now grounds `Stats - Cargo`,
|
||||
`Stats - City/Region`, `Stats - City Count`, `Event Variable Values`, and the neighboring
|
||||
event-validation page. The remaining open editor edge is therefore mostly the deeper gameplay
|
||||
meaning of those site-side service scores and flag bits, not page ownership.
|
||||
|
|
@ -0,0 +1,423 @@
|
|||
# Input, Save/Load, and Simulation: Event Editors, CompanyDetail, and LoadScreen
|
||||
|
||||
### Event Editors and Scenario Action Windows
|
||||
|
||||
The event side is tighter too:
|
||||
that `0x00433130` pass in turn materializes each live event record through
|
||||
`scenario_event_refresh_runtime_record_from_packed_state` `0x0042db20`. Current shell-side xrefs
|
||||
now tighten that event branch too: the first rebuilt linked row family under `0x0042db20` aligns
|
||||
with the standalone condition list later queried by `EventConditions.win`, while the second
|
||||
rebuilt family aligns with the four grouped effect lists later deep-copied through
|
||||
`scenario_event_clone_runtime_record_deep_copy` `0x0042e050` during event duplication and effect
|
||||
staging. The condition side is tighter now too: the tiny helper cluster
|
||||
`0x0042df30/0x0042df70/0x0042dfb0/0x0042dff0` is no longer just "some adjacent list scans".
|
||||
Current evidence bounds it as four predicates over the standalone `0x1e`-row condition list,
|
||||
testing class bits `0x01`, `0x02`, `0x04`, or any of those bits in the static table
|
||||
`0x005f3e04 + id*0x81`, with special fallback checks through event fields `[event+0x7f9]`,
|
||||
`[event+0x7fa]`, and `[event+0x7f0] == 0x63`. The shell side is tighter too: vtable slot
|
||||
`0x005d0cd8` now binds `shell_event_conditions_window_handle_message` `0x004d59e0`, and vtable
|
||||
slot `0x005d0cf8` binds `shell_event_effects_window_handle_message` `0x004d7060`. The effects
|
||||
side is tighter too: the lower helper trio is no longer anonymous. `0x004d5d00` now reads as the
|
||||
effect-type selector refresh under control family `0x4fb2`, `0x004d5f50` reads as the selected
|
||||
effect parameter-row repaint, `0x004d6090` is the heavier staged-effect editor refresh over the
|
||||
`0x4fc7/0x4fce/0x4ff6/0x4ff9/0x4ffc/0x5041/0x5044/0x5046/0x5047` bands, and `0x004d67f0`
|
||||
commits the current editor state back into the staged effect row at `[this+0x78]`. The verb side
|
||||
is tighter now too: `shell_open_event_conditions_modal_and_return_result` `0x004d9dc0` and
|
||||
`shell_open_event_effects_modal_and_return_result` `0x004d9e40` are the shared modal openers
|
||||
above the two editor windows; `0x004da640`, `0x004da700`, and `0x004d9ed0` now read as the add,
|
||||
edit, and remove verbs for standalone condition rows; `0x004da7c0`, `0x004da860`, and
|
||||
`0x004da920` are the matching add, edit, and remove verbs for grouped effect rows; and
|
||||
`0x004d8120` is now the heavier condition-row list panel refresh those condition-side verbs
|
||||
re-enter after mutation. The conditions-side refresh split is tighter too: `0x0042d700`
|
||||
aggregates standalone condition-list class or modifier flags, `0x0042d740` aggregates grouped
|
||||
effect-row type flags for one selected grouped list, `0x004d9970` owns the condition-class
|
||||
summary and grouped-row status bands, `0x004d77b0` owns the grouped summary-band affordance gate
|
||||
for `0x4fed..0x4ff0` when selector `0x5000` lands on `0x5002`, `0x004d9d10` owns the smaller
|
||||
grouped-effect territory-target affordance on control `0x500b`, `0x004d9f50` owns the selected-event mode
|
||||
strip and summary text panels, and `0x004d9390` is the mode-dependent detail-row switch beneath
|
||||
that strip. `0x004da0f0` is tighter too: selector `0x5001` now has the strongest current
|
||||
RT3.lng fit as the condition-side `Test against...` mode above `0x004d9970`, while selector
|
||||
`0x5002` has the strongest current fit as the grouped-effect-side `Apply effects...` mode.
|
||||
That `0x5002` branch now clearly builds control `0x5014` from RT3.lng `1160..1164` as `to the
|
||||
company/player/player (i.e. chairman)/territory for which the condition is TRUE` before
|
||||
enabling the adjacent `0x5005`, `0x500a`, and `0x5014..0x501c` family. The strongest current
|
||||
RT3.lng fit for the remaining visible target-scope strip is now `0x5015 = to the whole game`,
|
||||
`0x5016..0x5018 = to all/human/AI companies`, `0x5019 + 0x500b = to territories`, and
|
||||
`0x501a..0x501c = to all/human/AI players`; the grouped effect-row type mask matches that split
|
||||
directly through bits `0x08`, `0x01`, `0x04`, and `0x02`. The
|
||||
selected-event strip is tighter now too: `0x004db120` is the broader selected-event repaint and
|
||||
navigation refresh above those smaller helpers, `0x004db520` and `0x004db5e0` are the previous
|
||||
and next selected-event stepping verbs, `0x004db8b0` is the add-or-clone event modal helper,
|
||||
`0x004dba90` is the rename verb, `0x004d9360` is the delete verb, `0x004db6a0` is the live
|
||||
selected-event id setter behind control `0x4e84`, and `0x004db6f0` is the callback-binding plus
|
||||
pending-selection bootstrap path that seeds the strip during window bring-up. The larger
|
||||
dispatcher at `0x004dbb80` now makes the strip explicit: `0x4e85..0x4e8a` are previous, next,
|
||||
add blank, clone selected, rename, and delete event, while the later grouped band commits current
|
||||
summary state through `0x004d8d50` before changing grouped selector `[this+0x9c]` via `0x004dbf93`.
|
||||
The selection bootstrap side is tighter too: `0x004daf40` is now the placeholder reset helper for
|
||||
the selected-event summary controls `0x4eaf`, `0x4eac`, `0x4ed9`, `0x4edb`, and `0x4fdf..0x4fe2`.
|
||||
The grouped target-scope side is tighter too: `0x004d8ea0` now reads as the commit helper for current
|
||||
selected-event text panels before selection or grouped-action changes, `0x004d8d50` now records
|
||||
the hidden selector family `0x5006..0x500e -> 0..8`, and `0x004dab60` projects that ordinal
|
||||
one-to-one onto the visible grouped-effect target-scope display strip `0x5014..0x501c`. That
|
||||
split is firmer now: `0x5006..0x500e` are the canonical hidden selectors that get stored into
|
||||
`[event + group + 0x7fb]`, while `0x5014..0x501c` are the visible mirror rows republished from
|
||||
that same ordinal rather than a second independently named selector family. The grouped row and
|
||||
stored-summary refresh side is tighter too: `0x004d88f0` is now the selected grouped-effect
|
||||
row-list renderer for `0x4ed5`, formatting the grouped `0x28`-byte rows through RT3.lng
|
||||
`1154..1159`, and `0x004da9a0` is the current grouped-summary-state republisher that reloads
|
||||
`0x500a`, `0x500b`, and visible action selection `0x5014..0x501c` from `[event + group + ...]`
|
||||
before tailing back into `0x004da0f0`,
|
||||
`0x004dbfca` as the grouped target-scope mode selector that persists the chosen control id into
|
||||
`0x00622074`, with `0x5001/0x5002` now strongest-fit as `Test against...` and
|
||||
`Apply effects...`, `0x004dbeeb` as the pending shared summary-text triplet publish helper for
|
||||
`0x4eac/0x4ed9/0x4edb`,
|
||||
`0x004d91e0` as the selected-event summary-header and grouped-mode commit helper above
|
||||
`0x004d8d50`, and `0x004dbe7a` as the narrower `0x4ec6/0x4ec7` choice-event single-player-only
|
||||
warning modal branch rooted at RT3.lng `3887`. The remaining gaps on
|
||||
this lane are narrower again because the grouped-band `0x4dc09c` table now closes one earlier
|
||||
overclaim: controls `0x5001/0x5002` are the only `0x4fed..0x501c` entries that route into
|
||||
`0x004dbfca` on the `0xcf` side, while visible rows `0x5014..0x501c` only route to the smaller
|
||||
`0x004d9d10` affordance path and the rest of `0x4ff1..0x5013` are default no-ops. The open
|
||||
question is therefore no longer whether those visible target-scope rows are direct selector verbs;
|
||||
current evidence says they are not.
|
||||
The local slot records are rooted at
|
||||
`[world+0x69d8]`,
|
||||
`[slot+0x01]` polarity and the external role gate at `[world+0x0bc3+slot*9]` are now grounded, and
|
||||
`[slot+0x03]` now looks like the distinguished primary-human-seat marker because current grounded
|
||||
writes seed it only on slot zero and later logic moves it solely by whole-record compaction. The
|
||||
open question is no longer whether the seeded trio lands in the visible shell company roster;
|
||||
current evidence says it does, and ordinary `Start New Company` now looks like a fresh-company
|
||||
allocator through `start_new_company_dialog_commit_create_company` and
|
||||
`start_new_company_request_create_company`, not like the path that claims one of the seeded named
|
||||
railroads. The immediate post-roster station branch is now clearly separate: current grounded
|
||||
resource names and handlers put mode `8` on `StationDetail.win`, mode `5` on `StationList.win`,
|
||||
and the subordinate modal selector helper on `StationPick.win` through
|
||||
`shell_station_pick_window_open_modal_and_return_selected_station_id` above
|
||||
`shell_station_pick_window_construct`. The company-side ownership question has therefore moved
|
||||
down a layer rather than staying open. We now have a recovered `CompanyDetail.win`
|
||||
owner family through `shell_company_detail_window_refresh_controls`,
|
||||
`shell_company_detail_window_construct`, and `shell_company_detail_window_handle_message`; the
|
||||
same owner now has one broader bounded read-side lane too, because control `0x9470` uses
|
||||
`shell_company_detail_render_financial_history_panel` to draw the five-step Revenue or Expenses or
|
||||
Interest or Profit or Lifetime strip, sibling control `0x9471` reuses
|
||||
`shell_format_company_financial_summary_card` through
|
||||
`shell_company_detail_render_company_summary_card`, controls `0x947d` and `0x947e` now ground a
|
||||
bond maturity and repay panel through `shell_company_detail_render_bond_maturity_and_repay_panel`,
|
||||
control `0x9488` now grounds the debt or credit or rate summary block through
|
||||
`shell_company_detail_render_debt_credit_and_rate_summary_panel`, control `0x948a` now grounds the
|
||||
share-value and dividend-payout block through
|
||||
`shell_company_detail_render_share_value_and_dividend_summary_panel`, while the broader six-row
|
||||
per-share stock-data family is now bounded under `shell_format_company_stock_data_panel`, and the
|
||||
adjacent territory selector lane is bounded through
|
||||
`shell_company_detail_select_territory_access_row`,
|
||||
`shell_company_detail_render_territory_access_row`,
|
||||
`shell_company_detail_sync_selected_territory_from_picker`, and
|
||||
`shell_company_detail_refresh_selected_territory_access_summary`; the first finance-action layer
|
||||
beneath it is bounded through the bond, stock-issue, stock-buyback, and dividend-rate helpers; the
|
||||
territory-access side is bounded too through
|
||||
`shell_company_detail_refresh_selected_territory_access_summary`,
|
||||
`shell_company_detail_buy_territory_access_rights_flow`, and the underlying company access-rights
|
||||
helpers; and the full takeover and merger vote-result lane is now grounded through
|
||||
`shell_resolve_chairmanship_takeover_vote_and_commit_outcome`,
|
||||
`shell_present_chairmanship_takeover_vote_outcome_dialog`,
|
||||
`shell_resolve_merger_vote_and_commit_outcome`, and `shell_present_merger_vote_outcome_dialog`.
|
||||
The remaining company-side uncertainty is therefore narrower than before: the broader support and
|
||||
valuation side is now tighter too because
|
||||
`company_compute_cached_recent_per_share_performance_subscore`,
|
||||
`company_compute_five_year_weighted_shareholder_return`, and
|
||||
`company_compute_public_support_adjusted_share_price_scalar` bound the recent per-share
|
||||
performance and investor-support/share-price blend beneath those vote resolvers; the recent
|
||||
per-share feeder now has a grounded four-lane tail too, with current partial-year weight
|
||||
`(5 * [world+0x0f]) - 5`, prior full-year weights `48/36/24/12` on `0x1f/0x1e`, dividend
|
||||
non-decline pair weights `9/8/7/6` on `0x20`, lane weights `40/10/20/30`, the startup age ramp
|
||||
`0/0/0/100 -> 25/25/35/100 -> 50/50/65/100 -> 75/75/85/100 -> 100/100/100/100`, a strongest-lane
|
||||
`*1.25` boost, a weakest-lane `*0.8` reduction, and separate bounded-intermediate versus final
|
||||
difficulty applications under `0x005f33b8`; the next consumer `0x00424fd0` is also tighter now,
|
||||
with the young-company interpolation against `[company+0x57]`, caller pressure clamped to
|
||||
`[-0.2, 0.2]`, one `(shares / 20000)^0.33` share-count growth term, and the later threshold
|
||||
ladder `0.6 / 0.45 / 0.3 / 1.7 / 2.5 / 4.0 / 6.0` before the issue-`0x37` multiplier,
|
||||
`scenario_state_compute_issue_opinion_multiplier` now bounds the
|
||||
next layer of optional company, chairman, and territory-specific opinion overrides on the active
|
||||
scenario state, and the broader stat-reader family around
|
||||
`company_read_control_transfer_metric_slot` and
|
||||
`company_read_year_or_control_transfer_metric_value` is no longer just a merger-premium helper.
|
||||
Current grounded callers show the same metric family feeding the annual shareholder-revolt and
|
||||
creditor-liquidation lane surfaced by localized ids `300..304`, while the debt-side shell and
|
||||
bond lane now separately close `0x38` as `Credit Rating` and `0x39` as `Prime Rate`. That means
|
||||
the remaining gap is now mostly gone on the UI side too: issue `0x37` is already bounded to the
|
||||
same investor-confidence family as the equity-support and governance-pressure paths, and current
|
||||
grounded UI evidence still stops at the investor-attitude sentence family rather than one
|
||||
standalone caption. The calendar side is tighter now too:
|
||||
`[world+0x15]` is the absolute counter for the same mixed-radix `12 x 28 x 3 x 60`
|
||||
year-plus-subfield tuple packed by `0x0051d3c0` and unpacked by `0x0051d460`, not just a vague
|
||||
“calendar-like” blob. The `TrackLay.win` family now clearly owns `Lay single track.` `Lay double track.`
|
||||
and `Bulldoze` as its three primary modes, its bridge selector, its wrapped frequency preferences,
|
||||
and a strongly aligned pair of `Auto-Hide Trees During Track Lay` and `Auto-Show Grade During
|
||||
Track Lay` toggles; the `StationPlace.win` family now clearly owns its six top-level category
|
||||
buttons, the station-style scroller, and the station-rotation controls. The older `Building
|
||||
placement center` string 671 no longer looks like a live StationPlace control label in the current
|
||||
recovered flow, because the active constructor, preview, refresh, and dispatcher paths all use
|
||||
neighboring ids such as 669 and 2208 without a direct recovered lookup of 671. On save or load the
|
||||
broad serialize-versus-restore split is now grounded, the non-Quicksave `.gmp/.gmx/.gmc/.gms`
|
||||
families are separated, and the auxiliary `.gmt` path is at least bounded to the preview-surface
|
||||
side owner. The higher-value shell-facing gap has therefore shifted upward to the remaining
|
||||
semantics of the post-load generation phases, the later recurring structure-population cadence,
|
||||
the deeper vote-weight formulas inside takeover and merger resolution, and the still-open meaning
|
||||
of the packed simulation calendar tuple.
|
||||
|
||||
### CompanyDetail and Section Ownership
|
||||
|
||||
The shell detail family now has an explicit
|
||||
section-selector lane in addition to the read-side panels already mapped. Controls
|
||||
`0x9472..0x9475` directly select the four visible CompanyDetail sections through `0x006cfe60`,
|
||||
`0x9476..0x9479` are the companion visual controls for that same tab strip, and section `0` is now
|
||||
bounded more tightly as the chairman or governance slice around the portrait-backed chairman band
|
||||
on `0x9480` plus the dynamic overview widget `0x947f`. That widget is no longer just a vague
|
||||
status line: the section-0 refresh binds it through a dedicated stack-built dynamic text path,
|
||||
and the strongest current shared formatter candidate is
|
||||
`shell_format_company_governance_and_economy_status_panel` at `0x004e5cf0`, which first renders a
|
||||
five-line company-metric preamble through localized ids `1211..1215`: `Revenues` from slot
|
||||
`0x2c`, `Profits` from slot `0x2b`, `Load miles hauled` from slot `0x17`, `Revenue per load
|
||||
mile` from the derived `slot 0x2c / slot 0x17` branch, and `Average speed` from slot `0x26`
|
||||
rendered through `1216` `%1 m.p.h.`. It then splits the governance summary more concretely: no
|
||||
linked chairman emits `3045`, wholly owned companies emit `3046` for the scenario-selected
|
||||
chairman or `3047` for another linked chairman, and investor-owned companies emit the
|
||||
investor-attitude lines `3048/3049` with one adjective from the table at `0x00622170`. That
|
||||
branch is no longer using unnamed helpers either: `company_get_linked_chairman_profile_record`
|
||||
`0x00426ef0` resolves the linked chairman profile and `chairman_profile_owns_all_company_shares`
|
||||
`0x004768c0` is the full-ownership test behind the `3046/3047` split. The salary side is tighter
|
||||
too: the formatter computes one signed delta from `[company+0x14f]` and `[company+0x0d59]`, then
|
||||
chooses `3050..3052` for the scenario-selected chairman or `3053..3055` for another linked
|
||||
chairman depending on whether that delta is negative, positive, or zero. The bonus line is
|
||||
narrower still: it only appears when the display year matches `[company+0x34f]`, using amount
|
||||
`[company+0x353]` with `3056` or `3057`. It then appends the
|
||||
`1218` `Economy status - %1.` tail caption and stages the adjacent selected-company report or
|
||||
list help-title pairs `1219/1220` `Income Statement`, `1221/1222` `Balance Sheet`,
|
||||
`1223/1224` `Haulage Report`, `1225/1226` `Stock Report`, `1227/1228` `Train List`,
|
||||
`1229/1230` `Station List`, `1231/1232` `Industry List`, and `1233/1234` `Cargo List`.
|
||||
Current evidence still does not recover separate `CompanyDetail.win` action controls for that
|
||||
strip under `shell_company_detail_window_handle_message`, so it currently reads as staged
|
||||
overview text or help content rather than as a closed launcher family. The direct `0x947f`
|
||||
formatter call is still indirect, but the widget boundary is tighter too: the generic shell
|
||||
helpers `shell_control_refresh_matching_dynamic_text_payload` `0x00540a47` and
|
||||
`shell_control_release_dynamic_text_payload` `0x005639d2` now show that type `0x6f` controls
|
||||
free or swap one heap-backed text payload and then short-circuit as a special dynamic-text case,
|
||||
which strengthens the reading of `0x947f` as a display-only overview widget rather than a normal
|
||||
callback control. One adjacent boundary is tighter now too: the broader overview wrapper at
|
||||
`shell_render_company_overview_panel_header_and_optional_change_affordance` `0x004e5a80` owns
|
||||
the fallback no-company texts `1210`, `3043`, and `3888`, styles controls `0x3f06` and `0x3f07`,
|
||||
and on the narrower selected-company branch appends `3044` `Click to change company name and
|
||||
logo.` plus the neighboring `1941` `Change` affordance before falling through into the shared
|
||||
`0x004e5cf0` text body. That keeps the name/logo affordance outside the ordinary
|
||||
`CompanyDetail.win` action dispatcher and makes the `0x947f` alignment cleaner. The message-side
|
||||
action band is tighter too: `0x94b5` grounds
|
||||
territory-access purchase, `0x94b6` grounds bankruptcy, `0x94cf..0x94d2` ground bond issue, stock
|
||||
issue, stock buyback, and dividend-rate changes, `0x9493` routes into the destructive
|
||||
company-clear helper that deactivates the selected company and clears chairman/share links,
|
||||
`0x94d6` grounds bankruptcy, `0x94d7..0x94da` ground bond issue, stock issue, stock buyback, and
|
||||
dividend-rate changes, `0x94db` grounds merger, `0x94dc` grounds resignation, and `0x9538` grounds
|
||||
chairmanship takeover. The finance-side dialog family is tighter too: the bond-issue lane now has
|
||||
the dedicated modal renderer `shell_company_detail_render_issue_bond_offer_dialog` `0x004c3560`
|
||||
for underwriter terms `968..972`, the stock-issue lane has
|
||||
`shell_company_detail_render_issue_stock_offer_dialog` `0x004c3b50` for the staged offer lines
|
||||
`975..978`, and the buyback lane has
|
||||
`shell_company_detail_render_stock_buyback_offer_dialog` `0x004c4300` for broker lines
|
||||
`981..984`. The compact summary card on sibling control `0x9471` is tighter too:
|
||||
`shell_format_company_financial_summary_card` at `0x004bfb30` now clearly renders `Cash:`,
|
||||
`Revenue:`, and `Profits:` from company slots `0x0d`, `0x2c`, and `0x2b`, rather than one looser
|
||||
unnamed finance block. The dividend lane is now split the same way:
|
||||
`shell_company_detail_setup_dividend_rate_adjust_controls` `0x004c4c70` binds the paired adjust
|
||||
controls `0x99e8` and `0xc0f9`,
|
||||
`shell_company_detail_render_change_dividend_rate_dialog` `0x004c4e30` renders localized ids
|
||||
`988..990`, and
|
||||
`shell_company_detail_handle_change_dividend_rate_dialog_message` `0x004c5140` clamps the staged
|
||||
dividend rate against `company_compute_board_approved_dividend_rate_ceiling` `0x00426260` and
|
||||
raises localized id `991` when the board refuses a higher dividend, all before the existing
|
||||
company commit path. All four finance verbs now converge through the shared
|
||||
callback-driven modal opener `shell_open_custom_modal_dialog_with_callbacks` `0x004c98a0`, which
|
||||
is also reused by the multiplayer staged text-entry lane. The front controls in section `0` are
|
||||
tighter too: `0x948b` is a
|
||||
tutorial-guarded escape or back control that shows localized id `3724` `This option is disabled in
|
||||
the tutorial.` before falling back to the shell detail-manager escape path, `0x9491` and `0x9492`
|
||||
only restyle the paired visuals `0x948f` and `0x9490`, and `0x9494` opens localized id `3635`
|
||||
`Enter the amount that your company's cash should be` and writes the accepted value directly into
|
||||
the selected company cash pair. The neighboring debt section is tighter now too: controls
|
||||
`0x947d` and `0x947e` no longer read as one-off bond widgets, but as the owners of two repayable
|
||||
bond-slot row bands, `0x94e8..0x950f` and `0x9510..0x9537`. Those row controls now clearly
|
||||
converge on the same repayment path in the message dispatcher: they reject unaffordable repayment
|
||||
through localized id `2990`, open the early-repayment confirmation rooted at `2991`, and then
|
||||
either commit through `company_repay_bond_slot_and_compact_debt_table` `0x00423d70` or package
|
||||
the request through the multiplayer shell transport. The render-side owner is tighter too:
|
||||
`shell_company_detail_render_bond_maturity_and_repay_panel` formats `Due %1` and `Repay this
|
||||
bond.` for the selected debt slot while the tiny binder
|
||||
`shell_company_detail_bind_bond_row_band_for_active_panel` switches between the two row bands.
|
||||
Current `0xcb` dispatch does not treat `0x948f`, `0x9490`, `0x94d4`, or `0x94d5` as standalone
|
||||
action cases. The message-side jump table now makes that passive/action split explicit too: in the
|
||||
dispatch byte map rooted at `0x004c6640`, controls `0x94d6..0x94dc` map to cases `0x06..0x0c`,
|
||||
control `0x9538` maps to case `0x0d`, and the neighboring companion rows `0x94d4` and `0x94d5`
|
||||
stay on the default path. The refresh-side ownership is tighter too: the helper now explicitly
|
||||
loops over `0x94d4..0x9537` as the selected-company-owned band and over `0x9538..0x959b` as the
|
||||
linked-chairman-owned band, and those two loops do not use the same style polarity.
|
||||
`0x94d4..0x9537` take style `0x65` when the selected company matches the scenario-selected
|
||||
company and `0x87` when it differs, while `0x9538..0x959b` take style `0x87` when the selected
|
||||
company's linked chairman matches the scenario-selected chairman and `0x65` otherwise. The
|
||||
selected-company action side
|
||||
is tighter now too: scenario toggle `0x006cec78+0x4a8f` re-enables bankruptcy `0x94d6` together
|
||||
with passive companion row `0x94d4`, `+0x4a8b` re-enables issue bonds `0x94d7` together with
|
||||
passive companion row `0x94d5`, `+0x4a87` re-enables stock issue and stock buyback
|
||||
`0x94d8..0x94d9`, `+0x4a93` re-enables dividend `0x94da` together with the same passive
|
||||
companion row `0x94d5`, `+0x4adb` re-enables merger `0x94db`, `+0x4acb` re-enables resignation
|
||||
`0x94dc`, and `+0x4acf` re-enables chairmanship takeover `0x9538`. That makes `0x94d4/0x94d5`
|
||||
read more like passive companion or heading widgets than hidden verbs. The constructor boundary
|
||||
is tighter too: current `CompanyDetail.win` setup still only binds explicit callbacks for
|
||||
`0x9470`, `0x9471`, `0x947d`, `0x947e`, and `0x948c..0x948e`, not for the wider section-0 row
|
||||
bands. That keeps the remaining `0x94d4..0x959b` content looking more like resource-defined
|
||||
display rows that are gated and restyled by refresh than like individually code-rendered widgets.
|
||||
That leaves the main remaining CompanyDetail-specific shell edge at the exact `0x947f` formatter
|
||||
binding plus the still-unsplit render-side governance rows inside `0x94d4..0x959b`.
|
||||
### Adjacent LoadScreen.win Report Family
|
||||
|
||||
The neighboring shell lane around controls
|
||||
`0x3ef6..0x4073` is now separated from `CompanyDetail` instead of being treated as one more
|
||||
extension of the `0x947f` overview path. The real outer owner is
|
||||
`shell_load_screen_window_construct` `0x004ea620`, which binds `LoadScreen.win`, randomizes the
|
||||
`LoadScreen%d.imb` background family, stores the singleton at `0x006d10b0`, and seeds the first
|
||||
visible page-strip controls. Above the older page-specific work, the real message owner is now
|
||||
`shell_load_screen_window_handle_message` `0x004e3a80`: it owns page id `[this+0x78]`,
|
||||
page-local substate `[this+0x7c]`, page-kind `[this+0x80]`, current company `[this+0x88]`,
|
||||
current chairman profile `[this+0x8c]`, display year `[this+0x9c]`, and the page-local report
|
||||
row latch `[this+0x118]`, then fans back into the shared selector
|
||||
`shell_load_screen_select_page_subject_and_refresh` `0x004e2c10`, the company-step helper
|
||||
`0x004e3a00`, and narrower page branches such as `0x004e45d0`. The matching render-side owner is
|
||||
now bounded too: `shell_load_screen_render_active_page_panel` at `0x004ea060` formats the common
|
||||
heading and panel frame, then switches on page id `[this+0x78]` and hands control down into the
|
||||
active page body. That older branch is now demoted to what it actually is:
|
||||
`shell_load_screen_profile_stock_holdings_page_handle_message`, the page-specific handler beneath
|
||||
the stock-holdings slice. Inside that same family,
|
||||
`shell_load_screen_render_profile_stock_holdings_summary_panel` at `0x004e5300` grounds the
|
||||
selected-profile holdings page: it resolves the current chairman profile from `[this+0x8c]`,
|
||||
renders the top summary rows `1204` `Stock Value:`, `1205` `Total Assets:`, and
|
||||
`1206` `Stock Holdings:`, then walks the active company roster and formats one row per positive
|
||||
holding through `1201` `Click to view details on %1.`, `1207` `%1 Shares`, and `1208` `%1 Value`,
|
||||
falling back to `1209` `None` when no positive holdings survive. It also appends `3029`
|
||||
`Click to change player name and portrait.` plus the adjacent `1941` `Change` affordance only
|
||||
when the rendered profile matches the scenario-selected chairman. The earlier pages are tighter
|
||||
now too: `0x004e68e0` is the selected-company financial ranking page using the active company
|
||||
roster plus `1235..1245` for revenue, profit, cash, track mileage, and report affordances; and
|
||||
`0x004e6ef0` is the active-chairman wealth ranking page using the chairman profile collection
|
||||
plus `1237`, `1241`, `1246..1250` for cash, stock, total, and purchasing-power style comparisons.
|
||||
The later sibling renderers are broader than that one holdings page now too: `0x004e7670` is the
|
||||
selected-company train list page using `1235..1267`, `0x004e8270` is the selected-company
|
||||
building list page using `1268..1278`, `0x004e8bb0` is the selected-company station list page
|
||||
using `1279..1288`, and `0x004e9460` is the map-wide cargo list page using `1289..1298` over the
|
||||
live candidate collection rather than one company roster. The last broad early-page owner is
|
||||
tighter now too: `0x004e9b20` is the shared multi-year company report-table renderer for page
|
||||
`4` `Income Statement`, page `5` `Balance Sheet`, and page `6` `Haulage Report`, all driven from
|
||||
`0x004ea060` with one caller-supplied mode byte and yearly company rows built through
|
||||
`company_read_year_or_control_transfer_metric_value`. The row families are bounded too:
|
||||
income-statement rows `1301..1315`, balance-sheet rows `2816` and `1317..1322`, and
|
||||
haulage-report rows `1323..1335`. The only special rows inside that family are now tighter too:
|
||||
`0x00425880` and `0x004258c0` provide the negative-cash and positive-cash interest-rate inserts
|
||||
for the `%1/%2` placeholders in strings `2815` and `2816`, so they are no longer anonymous
|
||||
private math blobs. The adjacent early siblings are tighter now too: `0x004e5130` is the
|
||||
selected-company `Stock Data` page wrapper that falls back through `1299` and otherwise reuses
|
||||
`0x004c0160` to render the `Largest Shareholders`, `Shares`, and `Per Share Data` family;
|
||||
`0x004e6ef0` is the `Player List` page; `0x004e5300` is the `Player Detail` holdings page; and
|
||||
`0x004e51ea` is the `Game Status` briefing panel that pulls current scenario briefing text from
|
||||
the live scenario text store and appends the `1772/1773` `Briefing` affordance. The active-page
|
||||
renderer at `0x004ea060` is now tighter too because its 13-byte page descriptor table at
|
||||
`0x006220a0` has been decoded directly as `{ page kind, title string id, `0x3ef8` backlink
|
||||
page, selected-company-header flag }`. The currently grounded rendered title order is:
|
||||
`XXX`, `COMPANY OVERVIEW`, `COMPANY LIST`, `INCOME STATEMENT`, `BALANCE SHEET`,
|
||||
`HAULAGE REPORT`, `STOCK DATA`, `PLAYER LIST`, `PLAYER DETAIL`, `GAME STATUS`,
|
||||
`TRAIN LIST`, `TRAIN DETAIL`, `STATION LIST`, `STATION DETAIL`, `CARGO LIST`,
|
||||
and `INDUSTRY LIST`. Its live body bindings are now bounded too: page `0` falls back to
|
||||
`1203` `Unable to display page`, page `1` is the company overview wrapper, page `2` is the
|
||||
company list page, pages `3..5` are income statement, balance sheet, and haulage report, page
|
||||
`6` is stock data, page `7` is player list, page `8` is player detail, page `9` is game status,
|
||||
page `0x0a` is train list, page `0x0b` currently falls back to `1203`, page `0x0c` is station
|
||||
list, page `0x0d` currently falls back to `1203`, page `0x0e` is cargo list, and page `0x0f`
|
||||
is industry list. The row-click path is tighter now too: player-list rows re-enter page `8`
|
||||
directly, but train, station, and industry rows leave `LoadScreen.win` through the shell
|
||||
detail-panel manager at `0x004ddbd0` instead of switching to title-table pages `0x0b` or
|
||||
`0x0d`. Page `0` is tighter now too: its descriptor is kind `0`, title `1200` `XXX`, backlink
|
||||
`0`, and header flag `0`, and no current post-constructor selector path has been recovered for
|
||||
it. The descriptor side now also bounds the only known reverse route for the dormant detail
|
||||
titles: `0x3ef8` is the table-driven backlink affordance, so if page `0x0b` or `0x0d` were ever
|
||||
selected, the known reverse path would return to train-list page `0x0a` or station-list page
|
||||
`0x0c` respectively rather than through a separate detail-only owner.
|
||||
The launcher side is tighter too: current grounded `shell_open_or_focus_load_screen_page`
|
||||
callers cover pages `1`, `2`, `3`, `4`, `5`, `6`, `7`, `9`, `0x0a`, `0x0c`, `0x0e`, and `0x0f`,
|
||||
and no current recovered opener or row-click route selects `0x0b` or `0x0d`. So the
|
||||
`LoadScreen.win` family now has a much cleaner shape: one outer message owner
|
||||
`0x004e3a80`, one active-page render owner `0x004ea060`, and then the narrower page-specific
|
||||
handlers and renderers beneath them. The launcher side is tighter now too: `0x004e4ee0` is the
|
||||
shared open-or-focus ledger-page owner above this family. Outside sandbox it either re-enters
|
||||
`shell_load_screen_select_page_subject_and_refresh` on the live runtime at `0x006d10a8` or
|
||||
allocates that transient runtime, seeds it through `0x004e4b10`, and enters the visible modal
|
||||
loop; inside sandbox it raises localized id `3899` `The ledger is not available in sandbox mode.`
|
||||
instead.
|
||||
The direct shell-command strip above that opener is now explicit too: `0x00440700..0x0044086e`
|
||||
are just tiny `scenario-present -> open page` wrappers for pages `1`, `3`, `4`, `5`, `6`,
|
||||
`0x0a`, `0x0c`, `0x0f`, `0x0e`, `2`, `7`, and `9` respectively. So the recovered launcher range
|
||||
is no longer only “callers of `0x004e4ee0`” in the abstract; each of those small shell-command
|
||||
stubs now just forwards one fixed page id into the shared opener.
|
||||
instead. That narrows the remaining `LoadScreen.win` gap again: `TRAIN DETAIL` and
|
||||
`STATION DETAIL` now read as dormant title-table entries unless some still-unrecovered nonstandard
|
||||
selector reaches them. The live auto-load boundary is tighter now too: hook-driven
|
||||
`shell_transition_mode(4, 0)` now completes old-mode teardown, reconstructs and republishes
|
||||
`LoadScreen.win`, and returns cleanly, but the later post-transition service ticks still keep
|
||||
`[0x006cec78] = 0`, `[shell_state+0x0c]` on the same `LoadScreen.win` singleton, and
|
||||
`[LoadScreen.win+0x78] = 0` through at least counts `2..8`. So the next runtime edge is no
|
||||
longer the old mode-`4` teardown or publish band; it is the `LoadScreen.win` message owner
|
||||
`0x004e3a80` itself, because later service alone is not promoting the plain load screen into the
|
||||
separate startup-runtime object path. One later runtime probe did not actually reach that edge:
|
||||
the `0x004e3a80` hook installed, but the run never produced any ready-count, staging,
|
||||
transition, post-transition, or load-screen-message lines, only ordinary shell node-vcall
|
||||
traffic. So that result is now treated as a gate-or-cadence miss rather than as evidence against
|
||||
the `LoadScreen.win` message path itself. The newer shell-state service trace tightens it again:
|
||||
on a successful staged run the later service ticks do execute in `mode_id = 4`, but the
|
||||
`0x004e3a80` message hook still stays silent while the state remains frozen in the plain
|
||||
`LoadScreen.win` shape. So the next runtime boundary is now the shell-runtime prime call
|
||||
`0x00538b60` beneath `shell_state_service_active_mode_frame` `0x00482160`, not the message owner
|
||||
alone. The first direct `0x00538b60` probe run is not trustworthy yet, though: it stopped
|
||||
immediately after the first shell-state service-entry line, before any ready-count or
|
||||
runtime-prime entry logs. So that result is currently treated as probe validation work, not as a
|
||||
real boundary move inside RT3. The static service branch is conditional too: `0x00482160` only
|
||||
enters `0x00538b60` when `[shell_state+0xa0] == 0`, so silence from the runtime-prime hook does
|
||||
not yet prove the shell stops before that call unless the service-entry logs also show the `+0xa0`
|
||||
gate open. The newer run now closes that condition: `[shell_state+0xa0]` is `0`, and the
|
||||
`0x00538b60` runtime-prime hook enters and returns cleanly. The newer run closes the next owner
|
||||
too: `0x00520620` `shell_service_frame_cycle` also enters and returns cleanly on the same frozen
|
||||
mode-`4` path, and the logged fields match its generic branch rather than a startup-promotion
|
||||
lane (`[+0x1c] = 0`, `[+0x28] = 0`, `flag_56 = 0`, `[+0x58]` pulsed then cleared, and
|
||||
`0x006cec78` stayed `0`). The static body under the same owner is tighter now too: `0x00538b60`
|
||||
first re-enters `0x0054f6a0`, refreshes the primary timed-text lane from `[owner+0x1c]` through
|
||||
`0x005386e0` when that deadline has expired, walks the registered shell-window list from tail
|
||||
`[owner+0x04]` backward through `+0x54` while servicing each node through `0x0053fda0` and
|
||||
`0x0051f1d0`, and only then conditionally presents the secondary and primary text lanes through
|
||||
`0x005519f0`. So the next runtime boundary under the same shell-state service pass is now one
|
||||
level deeper: the per-object service walker `0x0053fda0` beneath `0x00538b60`. The newer run
|
||||
closes that owner too: it enters and returns cleanly while servicing the `LoadScreen.win` object
|
||||
itself, with `field_1d = 1`, `field_5c = 1`, and a stable child list under `[obj+0x70/+0x74]`,
|
||||
and its first child-service vcall target at slot `+0x18` stays `0x005595d0`. Since `0x006cec78`
|
||||
still stays `0` through those clean object-service passes, the next runtime boundary is now the
|
||||
child-service target `0x005595d0`, not the higher object walker. The newer child-service run
|
||||
narrows that again: the first sixteen `0x005595d0` calls are stable child lanes under the same
|
||||
`LoadScreen.win` parent, with `[child+0x86]` pointing back to the load-screen object,
|
||||
`field_b0 = 0`, and a split where earlier children carry `flag_68 = 0x03` and return `4` while
|
||||
later siblings carry `flag_68 = 0x00` and return `0`. The static body matches that read too:
|
||||
`0x005595d0` is gated by `0x00558670` and then spends most of its work in draw or overlay
|
||||
helpers `0x54f710`, `0x54f9f0`, `0x54fdd0`, `0x53de00`, and `0x552560`, so it now reads as
|
||||
another presentation-side service lane rather than the missing startup-runtime promotion. The
|
||||
widened allocator-window trace then reconciled the runtime with
|
||||
the static mode-`4` branch one step further: the first transition-window allocation is `0x7c`,
|
||||
which matches the static pre-construct `0x48302a -> 0x53b070` alloc exactly, and the later
|
||||
`0x111/0x84/0x3a/0x25...` allocations all occur before `LoadScreen.win` construct returns, so
|
||||
they now read as constructor-side child or control setup. That means the allocator probe did not
|
||||
disprove the still-silent startup-runtime slice; it simply exhausted its log budget inside the
|
||||
constructor before the post-construct block. The later reset-at-return run is now the decisive
|
||||
one: after `LoadScreen.win` construct returns there are still no further allocator hits before
|
||||
publish and transition return, which matches the corrected jump-table decode because mode `4`
|
||||
does not own the `0x46c40 -> 0x4336d0 -> 0x438890` startup-runtime path.
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,652 @@
|
|||
# Input, Save/Load, and Simulation: Post-load Generation, PaintTerrain, and Save/Load Restore
|
||||
|
||||
### Post-load Generation, PaintTerrain, and Save/Load Restore
|
||||
|
||||
The same brush strip is tighter now too:
|
||||
`0x004bc210` stores the selected ordinal and refreshes one scalar caption
|
||||
from table `0x00621e24`, `0x004bc260` exposes the cached world coordinate pair plus the
|
||||
currently selected scalar, and `0x004bc290` restyles the ordinal strip `0x0fa1..0x0fa7` plus
|
||||
the mapped mode strip `0x0faa..0x0faf` against the current mode dword `[0x006d0818+0x8c]`. The
|
||||
next unresolved layer is narrower and more semantic: the setup side now has one grounded
|
||||
owner, `world_run_post_load_generation_pipeline`, and its building-side branch is no longer just
|
||||
one opaque block. We now have a region family, a region-border overlay rebuild, a region-owned
|
||||
structure-demand and placement dispatcher, and a deeper per-region worker that computes category
|
||||
demand, subtracts existing coverage, and tries candidate placements. The category map is tighter
|
||||
too: category `0` falls back to `House`, category `2` is the year-gated weighted region-profile
|
||||
family that also feeds the localized `Industry Weightings` stats panel, and category `3` now
|
||||
reaches a separate pool-driven picker whose fallback label is `Commercial` but whose aligned
|
||||
player-facing stats bucket is `City Support`. The normalized region band is tighter too:
|
||||
`world_region_normalize_cached_structure_balance_scalars` `0x00422320` no longer just writes an
|
||||
anonymous cached preview band at `[region+0x2e2/+0x2e6/+0x2ea/+0x2ee]`. Current growth-report
|
||||
evidence now grounds `[region+0x2e2]` as the weighted-profit-margin scalar and `[region+0x2ee]`
|
||||
as the annual-density-adjust scalar later formatted as a percent in `Stats - City/Region`, with
|
||||
`[region+0x2e6/+0x2ea]` left as the intermediate normalized-delta and clamped companion slots
|
||||
beneath that final adjust term. The per-region prepass feeding that normalization is tighter too:
|
||||
`0x00420d40` clears `[region+0x306/+0x30a/+0x30e]`, walks the linked placed-structure chain from
|
||||
`[region+0x383]`, accumulates two local placed-structure metrics through `0x0040ca70` and
|
||||
`0x0040ca80`, and only for class-0 candidates also folds source field `[source+0x141]` through
|
||||
`0x0040cec0` into the third accumulator before tailing into the later scalar refresh. That tail
|
||||
helper `0x00420560` is tighter now too: on class-0 regions it revisits the same linked chain and
|
||||
folds a class-mix contribution into `[region+0x312]`, with one source-derived term for candidate
|
||||
class `0`, a separate branch keyed by `[candidate+0x78c]` and `[site+0x246]` for class `2`, one
|
||||
fixed increment for class `3`, and no current contribution from class `1`. One neighboring
|
||||
collection-side dispatcher is tighter now too: `0x00433b80` only runs when global mutation depth
|
||||
`0x0062be40` is back at zero and then conditionally fans into the optional refresh hooks
|
||||
`0x00481430`, `0x00413860`, `0x004b2a90`, and `0x004931e0`. The periodic boundary
|
||||
side is narrower now too. `0x00422100`, reached only from
|
||||
`simulation_service_periodic_boundary_work` `0x0040a590`, first requires several live world
|
||||
state gates to stay clear, derives one year-sensitive random threshold from selected-year fields
|
||||
plus world width, then scans the region collection for eligible class-0 regions whose transient
|
||||
dwords `[region+0x276]` and `[region+0x302]` are both clear and which fail the city-connection
|
||||
peer probe `0x00420030(1,1,0,0)`. When the gate passes it picks one random eligible region,
|
||||
derives one small severity bucket from `[region+0x25e]`, stores the scaled amount back into
|
||||
`[region+0x276]`, and appends one queued `0x20`-byte record through `0x004337c0` with literal
|
||||
kind `7`, the chosen region id, that amount, the fixed payload `0x005c87a8`, and sentinel dwords
|
||||
`-1/-1`. That append helper is now grounded directly too: `0x004337c0` allocates one zeroed
|
||||
linked `0x20`-byte node, copies one string or payload seed into `[node+0x04..]`, stores the six
|
||||
trailing caller dwords at `[node+0x08..+0x1c]`, and appends the finished node to the singly
|
||||
linked list rooted at `[state+0x66a6]`. The gameplay label for that queued-record family is still
|
||||
open, but the structural link from periodic region selection into the scenario-state queue is now
|
||||
direct instead of speculative. One neighboring narrow counter is bounded too: `0x00422850`
|
||||
counts class-0 regions that pass a second `0x00420030` peer-probe variant with fixed flags
|
||||
`(1,1,1)` plus one caller-supplied trailing dword, and current callers are the query/script
|
||||
dispatch at `0x0042f856` and the later region-stats formatter at
|
||||
`0x004d2088`. The
|
||||
remaining setup-side uncertainty has therefore narrowed
|
||||
again: the region seed and border-overlay pair clearly complete before the `Setting up Players and
|
||||
Companies...` banner is posted; `[0x006cec74+0x174]` now looks like the direct building-population
|
||||
gate; `[0x006cec74+0x178]` now looks like the direct seeding-burst gate and selected-year-adjust
|
||||
policy; and `[0x006cec74+0x68]` now aligns with editor-map mode because the same flag forces the
|
||||
`.gmp` family in the shell file coordinators while suppressing the later building and seeding
|
||||
branches and diverting the deeper region worker into alternate logic. One write side for that
|
||||
`[shell+0x178]` policy is now grounded too: inside `shell_dispatch_ui_command` `0x00464410`,
|
||||
command ids `0x9d26..0x9d28` store `command_id - 0x9d26` directly into `[0x006cec74+0x178]`,
|
||||
yielding live values `0`, `1`, and `2`. That means the later restore branch is no longer gated
|
||||
by an abstract hidden shell latch; at least one of its adjustment inputs is an explicit UI
|
||||
launch policy and current evidence still does not show that value being recovered from saved
|
||||
state. The `319` lane itself is no longer the
|
||||
open structural gap; it now clearly owns chairman-profile slot seeding, profile-record
|
||||
materialization, a shell editor surface over the same local record family, and a separate
|
||||
live-company presentation path through the company-list window. The later interior order of that
|
||||
same `319` lane is tighter now too: after the route-entry collection refresh on `0x006cfca8` it
|
||||
refreshes the auxiliary route-entry tracker collection `0x006cfcb4`, then runs
|
||||
`placed_structure_collection_refresh_local_runtime_records_and_position_scalars` `0x004133b0`,
|
||||
then a flagged world-grid cleanup sweep through the compact grid-flag query
|
||||
`0x00448af0` plus the neighboring local chunk-cell write helper `0x00533fe0`, and only after
|
||||
that the later route-entry post-pass at `0x00491c20`. The same `319` lane is tighter internally
|
||||
now too:
|
||||
before that later world and shell reactivation tail, `world_entry_transition_and_runtime_bringup`
|
||||
runs one distinct post-bundle status and runtime refresh phase that posts progress ids `0x196`
|
||||
and `0x197` through `0x005193f0/0x00540120` with paired `0x004834e0` follow-ons, refreshes the
|
||||
live event collection at `0x0062be18` through
|
||||
`scenario_event_collection_refresh_runtime_records_from_packed_state` `0x00433130`, rebuilds the
|
||||
scenario-side port-or-warehouse cargo recipe runtime tables through `0x00435630`, and then runs
|
||||
the named-candidate availability preseed through `0x00437743`. One later subphase is tighter now
|
||||
too: before the broad world-reactivation sweep it posts progress ids `0x32dc/0x3714/0x3715`,
|
||||
reloads one `0x108`-byte packed profile block through `0x00531150`, conditionally copies staged
|
||||
runtime-profile bytes back into `0x006cec7c` while latch `[profile+0x97]` is set, mirrors the
|
||||
grounded campaign-scenario bit `[profile+0xc5]` and sandbox bit `[profile+0x82]` into world
|
||||
bytes `[world+0x66de]` and `[world+0x66f2]`, and restores the selected year/profile lane through
|
||||
a tighter two-stage calendar path than before. Current local disassembly now shows the raw saved
|
||||
lane at `[profile+0x77]` first feeding helper `0x0051d3f0` with constant components
|
||||
`(month=1, day=1, subphase=0, tick=0)`, which writes the resulting Jan-1-style tuple dwords
|
||||
into `[world+0x05/+0x09]`. Only after that seed does the same lane enter one mode-sensitive
|
||||
adjustment branch: non-editor startup mode can decrement the lane by `1` or `3` depending on
|
||||
shell-state editor gate `[0x006cec74+0x68]`, shell-side selected-year-adjust policy
|
||||
`[0x006cec74+0x178]`, and the saved special-condition slot `[0x006cec78+0x4af7]`, and only that
|
||||
adjusted lane then feeds
|
||||
helper `0x0051d390` before `world_set_selected_year_and_refresh_calendar_presentation_state`
|
||||
`0x00409e80` stores the final absolute counter into `[world+0x15]` and refreshes
|
||||
`[world+0x0d/+0x11]`. That means the restore no longer reads as a direct
|
||||
`[profile+0x77] -> [world+0x15]` copy; the raw lane seeds the tuple immediately, but the final
|
||||
absolute-counter restore still depends on live shell/startup context. That dependency is tighter
|
||||
now too: current local evidence shows `[shell+0x178] == 1` decrementing the restored lane by
|
||||
`1`, `[shell+0x178] == 2` subtracting `3`, and otherwise a nonzero
|
||||
`[0x006cec78+0x4af7]` supplying the fallback `-1` branch. That field is no longer unresolved:
|
||||
current local disassembly now shows `0x00436d10` bulk-zeroing the dword table rooted at
|
||||
`[startup+0x4a7f]` through `rep stos`, which includes `+0x4af7`, while the editor-side special
|
||||
conditions owner at `0x004cb2b0/0x004cb8e0` counts and commits that same 49-entry table from the
|
||||
static rule descriptors at `0x005f3ab0`. The `.smp` save or restore family now grounds that live
|
||||
band directly too: `world_runtime_serialize_smp_bundle` `0x00446240` writes `49` dwords from
|
||||
`[world+0x4a7f..+0x4b3f]` plus one trailing scalar at `[world+0x4b43]`, and
|
||||
`world_load_saved_runtime_state_bundle` `0x00446d40` restores the same fixed `0xc8`-byte band
|
||||
symmetrically. Slot `30` in that table is localized pair `3722/3723`
|
||||
`Disable Cargo Economy`, so `+0x4af7` now reads as the live copy of that saved scenario rule,
|
||||
not a startup-runtime-only mystery latch. The neighboring fixed reads line up with the same rule
|
||||
cluster too: `+0x4aef` is slot `28` `Completely Disable Money-Related Things`, `+0x4af3` is slot
|
||||
`29` `Use Bio-Accelerator Cars`, `+0x4afb` is slot `31` `Use Wartime Cargos`, `+0x4aff` is slot
|
||||
`32` `Disable Train Crashes`, `+0x4b03` is slot `33` `Disable Train Crashes AND Breakdowns`, and
|
||||
`+0x4b07` is slot `34` `AI Ignore Territories At Startup`. So the remaining loader gap is
|
||||
narrower than before: the restore still depends on live shell policy `[shell+0x178]`, but the
|
||||
`+0x4af7` input itself is save-derived scenario rule data rather than something that requires
|
||||
runtime tracing to discover. Its read-side family is no longer isolated to the selected-year
|
||||
restore either: it also shapes the chunk size in
|
||||
`simulation_run_chunked_fast_forward_burst` `0x00437b20` and appears in candidate/local-service
|
||||
selection and station-detail-side scoring branches around `0x0047f910`, `0x00410d87`, and
|
||||
`0x005069c6`, which now makes this whole slot cluster look like broader runtime consumers of
|
||||
scenario special conditions rather than one startup-only mode enum. One file-side anchor is now
|
||||
tighter too: the checked classic and 1.05 `gmp/gms/gmx` corpus does expose the same aligned
|
||||
`0x0d64..0x0e2c` `50`-dword band as the grounded `.smp` runtime save or restore copy into
|
||||
`[world+0x4a7f..+0x4b43]`, but most checked file families only populate a sparse subset of that
|
||||
band. The first `36` dwords still behave like the older inferred fixed rule matrix with hidden
|
||||
slot `35` fixed to sentinel value `1`, while the trailing `13` unlabeled rule lanes plus one
|
||||
scalar vary much more selectively by file family. Current local corpus scans make that split
|
||||
concrete: the grounded 1.05 scenario-save family (`p.gms`, `q.gms`) stably lights lanes
|
||||
`35, 37, 39, 44, 45, 46, 47, 48`; the base 1.05 save family (`Autosave.gms`, `nom.gms`) only
|
||||
shares lane `35` stably and otherwise varies sparsely through `42`, `45`, and `47`; the checked
|
||||
grounded 1.05 maps, the lone 1.05 alt save, and the visible sandbox-family `.gmx` files keep
|
||||
only the sentinel lane `35` nonzero. So the current loader boundary is narrower than before: the
|
||||
`.smp` path still gives a grounded direct runtime-band restore, and checked `gmp/gms/gmx` files
|
||||
now show a partially populated projection of that same aligned band rather than a wholly separate
|
||||
fixed record family. The overlap against the later scalar window is now explicit too: trailing
|
||||
band indices `36..49` are byte-identical with post-window offsets `0x00..0x34`, so every nonzero
|
||||
lane in that prefix of the post-sentinel scalar window is also a nonzero lane in the aligned
|
||||
runtime-rule band. That means the real “other fields” boundary inside the post-sentinel window
|
||||
starts only at `0x0e2c`: `0x0df4..0x0e2c` is the aligned-band overlap prefix, while
|
||||
`0x0e2c..0x0f30` is the later tail that still looks like save-side scalar state. Local corpus
|
||||
scans now make that tail split more specific. The base 1.05 save family
|
||||
(`Autosave.gms`, `nom.gms`) shares a stable tail subset at relative offsets
|
||||
`0xb4`, `0xc0`, `0xe0`, `0xfc`, and `0x100`, with additional per-file lanes around them. The
|
||||
1.05 scenario-save family (`p.gms`, `q.gms`) has a much denser stable tail covering
|
||||
`0x08`, `0x0c`, `0x10`, `0x14`, `0x20`, `0x24`, `0x28`, `0x30`, `0x34`, `0x3c`, `0x5c`,
|
||||
`0x6c`, `0xa0`, `0xa8`, `0xbc`, `0xc0`, `0xc4`, `0xc8`, `0xcc`, `0xdc`, `0xe0`, `0xe4`,
|
||||
`0xe8`, `0xf4`, `0xf8`, and `0xfc`; those values still differ per save, but the occupancy is
|
||||
stable. The lone 1.05 alt save (`g.gms`) only lights `0x20`, `0x34`, `0xf0`, and `0xf4`.
|
||||
Grounded map families and classic saves keep the tail zeroed, while the only current map-side
|
||||
outlier remains `Tutorial_2.gmp` under the broad unknown map-family bucket. The immediately
|
||||
following fixed file window at `0x0df4..0x0f30` is now bounded separately as well: checked maps
|
||||
and classic saves leave that whole post-sentinel band zeroed,
|
||||
while checked 1.05 saves carry sparse nonzero dwords there, many of which decode cleanly as
|
||||
normal little-endian `f32` values. That makes the adjacent band look like a 1.05 save-only
|
||||
runtime band rather than scenario-static payload, even though its semantics are still open.
|
||||
One numeric alignment inside that band is now exact too: the tail start `0x0e2c` is the same
|
||||
relative distance from the aligned runtime-rule base `0x0d64` as live object offset `+0x4b47`
|
||||
is from grounded world-rule base `[world+0x4a7f]`, so the bounded tail window
|
||||
`0x0e2c..0x0f30` is offset-aligned with live bytes `[world+0x4b47..+0x4c4b]`. The first
|
||||
grounded live field at that boundary is no longer anonymous. `0x004367c0` sets one outcome mode
|
||||
in `[world+0x4a73]`, zeros `[world+0x4d]`, snapshots the selected-year lane to `[world+0x4c88]`,
|
||||
and then copies localized id `2923` `You lose.` or `2924` `You win, cheater...` into
|
||||
`[world+0x4b47]`; `0x00472dd0` formats localized id `3918` `%1 has won the game!` with one live
|
||||
profile name and writes that string into the same destination; and one compact runtime-effect
|
||||
branch inside `world_apply_compact_runtime_effect_record_to_resolved_targets` `0x00431b20` resets
|
||||
the same destination to the fixed placeholder token at `0x005c87a8`. That gives a grounded live
|
||||
interpretation for the start of the tail: `[world+0x4b47]` is the start of a victory or outcome
|
||||
status-text buffer, not a float lane. The same evidence also gives a useful caution: those live
|
||||
helpers copy up to `0x12c` bytes into `[world+0x4b47..+0x4c73]`, so the current bounded file-tail
|
||||
window `0x0e2c..0x0f30` cuts through the first `0x104` bytes of a grounded text field rather
|
||||
than ending on a clean live-field boundary. One small continuation probe now tightens that edge:
|
||||
the remaining file window `0x0f30..0x0f58` is exactly the last `0x28` bytes needed to reach the
|
||||
clean live-field boundary at `[world+0x4c73]`, and checked 1.05 saves still carry sparse nonzero
|
||||
bytes in that continuation window rather than a trailing text-looking suffix. Checked 1.05 save
|
||||
bytes in the aligned region therefore still do not resemble preserved text; they stay mostly zero
|
||||
at the beginning and many nonzero lanes decode as ordinary `f32` values. So the safest current
|
||||
note is: the tail is offset-aligned with the live object beyond `+0x4b43`, but it is not yet a
|
||||
validated byte-for-byte mirror of the live `[world+0x4b47]` status-text buffer, and the current
|
||||
nonzero save-side content continues right up to the first clean field edge at `0x0f58`. The next
|
||||
exact grounded fields after that edge are byte lanes, not restored dwords: `0x0f59` maps to
|
||||
`[world+0x4c74]` `Auto-Show Grade During Track Lay`, `0x0f5d` maps to `[world+0x4c78]`
|
||||
`Starting Building Density Level`, `0x0f61` maps to `[world+0x4c7c]` `Building Density Growth`,
|
||||
`0x0f65` maps to grounded dword `[world+0x4c80]` `leftover simulation time accumulator`, and
|
||||
`0x0f6d` maps to byte `[world+0x4c88]` `selected-year lane snapshot`. The first later grounded
|
||||
dword after that is `[world+0x4c8c]` at `0x0f71`. That means the simple 4-byte file-lane model
|
||||
stops matching grounded live field boundaries immediately after the text-buffer edge: the post-
|
||||
`0x0f58` file bytes are still offset-correlated to live state, but they are no longer naturally
|
||||
dword-aligned with the next grounded object fields. The new byte-neighborhood probe makes the
|
||||
mismatch more concrete. In checked 1.05 scenario saves, the exact grounded byte offsets
|
||||
themselves do not look like clean selector values: `p.gms` carries `0x33` at `0x0f5d` and `0x8c`
|
||||
at `0x0f6d`, while `q.gms` carries `0xcc` and `0xba` at those same offsets. The only clean
|
||||
float-looking starts in that neighborhood instead appear one byte earlier, at `0x0f5c` and
|
||||
`0x0f6c`: `p.gms` decodes those as roughly `7.6` and `6.0172`, while `q.gms` decodes them as
|
||||
roughly `23.6` and `44.6824`. That tightens the current read further: the checked save bytes
|
||||
remain offset-correlated to the live `[world+0x4c74..+0x4c8c]` neighborhood, but they are still
|
||||
not a validated byte-for-byte mirror of the exact live field layout. Local
|
||||
A second byte-oriented neighborhood immediately after that now has the same kind of split rather
|
||||
than a clean restored-field mirror. The earlier grounded anchors in that band all stay zero in
|
||||
the checked 1.05 saves: exact file offset `0x0f87` maps to selected-year bucket companion scalar
|
||||
`[world+0x4ca2]`, while `0x0f93` and `0x0f97` map to the two startup-dispatch reset-owned bands
|
||||
`[world+0x4cae]` and `[world+0x4cb2]`, and the local corpus leaves all three exact dword starts
|
||||
zeroed. The same is true for the later exact byte-owned policy lanes: file offsets `0x0f78`,
|
||||
`0x0f7c`, `0x0f7d`, and `0x0f7e` map cleanly to grounded byte fields `[world+0x4c93]` and
|
||||
`[world+0x4c97..+0x4c99]`: the linked-site removal follow-on gate plus the three editor
|
||||
locomotives-page policy bytes `All Steam Locos Avail.`, `All Diesel Locos Avail.`, and `All
|
||||
Electric Locos Avail.`. In the checked 1.05 save corpus those four exact byte lanes all stay
|
||||
`0`, which is at least structurally clean. The later grounded dword fields in the same
|
||||
neighborhood are less direct again. Exact file offset `0x0f9f` maps to `[world+0x4cba]` (the
|
||||
station-list selected-station mirror) and exact offset `0x0fa3` maps to cached
|
||||
available-locomotive rating `[world+0x4cbe]`, but the checked save bytes at those exact dword
|
||||
starts do not look like clean preserved ids or floats. The only stable float-looking starts sit
|
||||
three bytes earlier, at `0x0f9c` and `0x0fa0`: `p.gms` yields roughly `96.8754` and `186.4795`,
|
||||
`q.gms` yields `329.9467` and the same `0x0fa0`-side candidate shape, `g.gms` yields `7.0` and
|
||||
`95.8507`, and `Autosave.gms` only shows the later `0x0fa0` candidate at about `68.2629`. So
|
||||
this later band now has the same conservative read as the post-text one: the save bytes are
|
||||
still offset-correlated to grounded live fields, but the exact live byte or dword layout is not
|
||||
yet validated as a direct on-disk mirror.
|
||||
One more structural cut is now grounded beyond that neighborhood. The aligned scalar plateau
|
||||
`0x0fa7..0x0fe7` ends exactly at the later recipe-book root `[world+0x0fe7]` already grounded in
|
||||
the port-or-warehouse cargo editor and runtime rebuild path. We still do not have live semantic
|
||||
names for the plateau itself, but its aligned dword run now splits cleanly by save family. The
|
||||
base 1.05 saves (`Autosave.gms`, `nom.gms`) carry one stable signature with
|
||||
`0x0faf = 0x8000003f`, `0x0fb3 = 0x75c28f3f`, repeated `0x75c28f3c` lanes through `0x0fbf`, a
|
||||
sign-flipped lane `0x0fc3 = 0xa3d70a3c`, one tiny marker at `0x0fc7 = 0x0000003b`, and
|
||||
`0x0fcb = 0x00300000`. The scenario-save family (`p.gms`, `q.gms`) carries a different stable
|
||||
plateau over the same offsets, beginning `0x0faf = 0x4000003f`, `0x0fb3 = 0xe560423f`, then
|
||||
`0x03126f3b`, `0x1374bc3c`, and paired `0x23d70a3c` lanes at `0x0fbf/0x0fc3`, with
|
||||
`0x0fc7 = 0x0000003c`. The alt-save family (`g.gms`) follows the base signature through
|
||||
`0x0fc7`, then diverges sharply into the same `0xcdcdcd..` fill pattern already seen in its
|
||||
earlier header lanes. So the current best fit for `0x0fa7..0x0fe7` is a family-shaped aligned
|
||||
scalar plateau that belongs to save-side runtime state and terminates immediately before the
|
||||
grounded recipe-book block, not one more directly named live-field mirror. One conservative
|
||||
loader-side summary probe now starts exactly at that recipe root instead of extending the plateau
|
||||
model further. The fixed recipe-book block spans twelve books from `0x0fe7` with stride `0x4e1`,
|
||||
and the checked map/save pairs `Alternate USA.gmp -> Autosave.gms`, `Southern Pacific.gmp ->
|
||||
p.gms`, and `Spanish Mainline.gmp -> g.gms` preserve that rooted block byte-for-byte in the
|
||||
sampled local corpus. The current probe therefore treats it as preserved scenario payload rather
|
||||
than save-only runtime drift and only reports per-book signatures: a coarse head kind over the
|
||||
pre-line region, the raw `book+0x3ed` annual-production dword, and one raw summary for each of
|
||||
the five fixed `0x30`-byte cargo lines beginning at `book+0x3f1`: coarse line kind, raw mode
|
||||
dword, raw annual-amount dword, and the raw supplied/demanded cargo-token dwords at `+0x08` and
|
||||
`+0x1c`. That is enough to separate zero, `0xcd`-filled, and mixed books or lines without
|
||||
overstating line semantics beyond the grounded editor/runtime ownership already documented below.
|
||||
Local
|
||||
corpus clustering now makes the remaining split more specific. The base 1.05 save family
|
||||
(`Autosave.gms`, `nom.gms`) shares a narrow tail-heavy subset with stable relative offsets
|
||||
`0xec`, `0xf8`, `0x118`, `0x134`, and `0x138`, while still varying in value across files. The
|
||||
1.05 scenario-save family (`p.gms`, `q.gms`) shares a much broader stable set spanning almost the
|
||||
whole window from `0x04` through `0x134`, again with per-file scalar differences but consistent
|
||||
occupancy. Pairwise compare runs tighten that read further: `Autosave.gms` vs `nom.gms` does not
|
||||
preserve one common numeric tail signature even at the shared base-save offsets, and `p.gms` vs
|
||||
`q.gms` keeps the broad scenario-save occupancy pattern but still changes every shared value, with
|
||||
`q.gms` additionally lighting two extra lanes at `0x78` and `0x84`. So the current best fit is
|
||||
“family-shaped live scalar state” rather than family-default constants. The lone 1.05 alt-save
|
||||
sample (`g.gms`) only lights up four lanes at `0x58`, `0x6c`,
|
||||
`0x128`, and `0x12c`. The checked 1.05 maps and classic saves stay zero in that same bounded
|
||||
window, which strengthens the current read that this is runtime-save scalar state rather than
|
||||
generic map payload. One older unknown map-family outlier in the local corpus does still carry a
|
||||
populated window: `Tutorial_2.gmp` under the classic install tree. So the safest current note is
|
||||
“zero for grounded map families and classic save families, nonzero for observed 1.05 save
|
||||
families, with one older unknown-map exception.” Static consumer grounding is still sparse for
|
||||
that tail: direct object-offset hits currently only name the trailing scalar `[world+0x4b43]`
|
||||
through the editor panel and `.smp` save or restore family, while local opcode searches do not
|
||||
yet surface equally direct reads for the intervening `+0x4b0b..+0x4b3f` tail lanes. So the
|
||||
save-file family clustering is now strong, but those later tail scalars remain structurally
|
||||
bounded rather than semantically named. The
|
||||
same branch is no longer world-entry-only either: current local
|
||||
disassembly now shows the identical lane-adjust and
|
||||
`0x51d3f0 -> 0x51d390 -> 0x409e80` sequence in the post-fast-forward selected-year tail at
|
||||
`0x004370e0`, which lines up with the existing post-fast-forward callers already mapped under
|
||||
`0x00433bd0`, `0x00435603`, `0x0041e970`, and `0x00436af0`. That restore now
|
||||
also has some neighboring slot semantics bounded well enough to carry in the loader notes. Slot
|
||||
`31` `[0x006cec78+0x4afb]` is no longer best read as an unnamed runtime cargo-economy latch:
|
||||
local disassembly now ties it directly to the saved special-condition table entry `Use Wartime
|
||||
Cargos`, and the strongest current runtime owner is
|
||||
`structure_candidate_collection_refresh_cargo_economy_filter_flags` `0x0041eac0`. Inside that
|
||||
candidate-collection sweep the branch at `0x0041ed37` only activates when slot `31` is set and
|
||||
then treats the string family `Clothing`, `Cheese`, `Meat`, `Ammunition`, `Weapons`, and
|
||||
`Diesel` as one special cargo set before writing the live candidate filter byte `[entry+0x56]`.
|
||||
That makes the old read-side note around `0x00412560` tighter too: the neighboring descriptor
|
||||
gate is now best understood as using the live copy of the `Use Wartime Cargos` scenario rule,
|
||||
not an anonymous cargo-economy mode byte. Slot `34` `[0x006cec78+0x4b07]` is similarly bounded
|
||||
on the runtime side: the wrapper at `0x004013f0`, which sits immediately above the broader
|
||||
company-start or city-connection chooser `0x00404ce0`, snapshots region dword `[entry+0x2d]`
|
||||
across all `0x18` live region records in `0x006cfc9c`, zeros that field while the chooser runs,
|
||||
and then restores the original values on exit. That is a strong current fit for the editor rule
|
||||
`AI Ignore Territories At Startup`, even though the exact meaning of region field `+0x2d`
|
||||
remains open. Slot `29` `[0x006cec78+0x4af3]` is less semantically tidy but still worth carrying
|
||||
as a bounded consumer family: the branch at `0x0041d286` activates one later placed-structure or
|
||||
building-side scoring path only when that slot is nonzero and the linked candidate or era record
|
||||
at `[entry+0x41]` equals `5`, while two already-grounded world helpers
|
||||
`world_scan_secondary_grid_marked_cell_bounds` `0x0044ce60` and
|
||||
`world_service_secondary_grid_marked_cell_overlay_cache` `0x0044c670` also gate on the same
|
||||
slot. So the identity of slot `29` as saved rule data is grounded, but the downstream runtime
|
||||
semantics are still mixed enough that the loader should preserve the raw value without trying to
|
||||
rename its whole consumer family yet. The neighboring train-safety slots are now bounded enough
|
||||
to keep as a cautious runtime split too. Slot `33` `[0x006cec78+0x4b03]`
|
||||
`Disable Train Crashes AND Breakdowns` is the coarse gate in the currently recovered train-side
|
||||
deterioration family around `0x004af8a0`: the very first branch at `0x004af8ab` jumps straight
|
||||
to the function tail when the slot is set, bypassing the year-scaled threshold build, the later
|
||||
random or threshold comparison, and the two follow-on state transitions at `0x004ad7a0` and
|
||||
`0x004ada00`. Slot `32` `[0x006cec78+0x4aff]` `Disable Train Crashes` is narrower in the same
|
||||
family: after the threshold path has already run, the branch at `0x004af9c1` uses slot `32` to
|
||||
suppress only the lower failure-transition path and force the milder follow-on at `0x004ada00`.
|
||||
That same slot-`33` read also appears in the smaller train-side scalar query at `0x004ac460`,
|
||||
where setting it returns one fixed float immediately before the ordinary route-object-dependent
|
||||
calculation runs. So the current best loader-facing read is: slot `33` is the broad train
|
||||
deterioration bypass, slot `32` is the narrower crash-only branch inside that same family, but
|
||||
the exact player-facing names of the two unnamed train helpers still need one more naming pass.
|
||||
That restore now
|
||||
also has one concrete file-side correlation in the classic `.gms` family: local save inspection
|
||||
now consistently finds `0x32dc` at `0x76e8`, `0x3714` at `0x76ec`, and `0x3715` at `0x77f8` in
|
||||
`Autosave.gms`, `kk.gms`, and `hh.gms`, leaving one exact `0x108`-byte span from `0x76f0` to
|
||||
`0x77f8` between `0x3714` and `0x3715`. That span already carries staged-profile-looking payload
|
||||
text such as `British Isles.gmp`, so the current static-file evidence now supports the atlas-side
|
||||
`0x108` packed-profile note for the classic save family even though the exact field layout inside
|
||||
that block is still unresolved. The same classic corpus is tighter now too: inside that
|
||||
`0x108` span the map-path C string begins at relative offset `0x13`, the display-name C string
|
||||
begins at `0x46`, the block is otherwise almost entirely zeroed, and the three local samples are
|
||||
byte-identical except for the leading dword at `+0x00` (`3` in `Autosave.gms` and `hh.gms`,
|
||||
`5` in `kk.gms`). The currently atlas-tracked bytes `[profile+0x77]`, `[profile+0x82]`,
|
||||
`[profile+0x97]`, and `[profile+0xc5]` are all `0` in that classic sample set, so the current
|
||||
file-side evidence grounds the block boundaries and the embedded strings but does not yet show
|
||||
live examples of those branch-driving latches being set. One 1.05-era file-side analogue is now
|
||||
visible too, but only as an inference from repeated save structure rather than a disassembly-side
|
||||
field map: local `.gms` files in `rt3_105/Saved Games` carry one compact string-bearing block at
|
||||
`0x73c0` with the same broad shape as the classic profile slab, including a leading dword at
|
||||
`+0x00`, one map-path string at `+0x10`, one display-name string at `+0x43`, and a small
|
||||
nonzero tail around `+0x76..+0x88`. In that 1.05 corpus the analogue bytes at relative `+0x77`
|
||||
and `+0x82` are now nonzero in every checked sample (`Autosave.gms`/`nom.gms` show `0x07` and
|
||||
`0x4d`; `p.gms`/`q.gms` show `0x07` and `0x90`; `g.gms` shows `0x07` and `0xa3`), while
|
||||
relative `+0x97` and `+0xc5` remain `0`. The compared 1.05 save set is tighter now too:
|
||||
`Autosave.gms` and `nom.gms` cluster together on `Alternate USA.gmp` with `+0x82 = 0x4d`,
|
||||
`g.gms` carries `Spanish Mainline.gmp` with `+0x82 = 0xa3`, and `p.gms`/`q.gms` cluster on
|
||||
`Southern Pacific.gmp` with `+0x82 = 0x90`; across all five files the same inferred analogue
|
||||
lane at `+0x77` stays fixed at `0x07`, while the same map- or scenario-sensitive tail word at
|
||||
`+0x80` tracks those `0x4d/0xa3/0x90` byte lanes (`0x364d0000`, `0x29a30000`, `0x1b900000`).
|
||||
The leading dword at `+0x00` also splits the same corpus, with `Autosave.gms` alone at `3` and
|
||||
the other four checked 1.05 saves at `5`. That is enough to say the wider save corpus does
|
||||
contain nonzero candidates for two of the atlas-tracked profile lanes, and that one of them
|
||||
varies coherently with the loaded scenario family, but not yet enough to claim that the 1.05
|
||||
block reuses the exact same semantic field assignments as the classic one. The loader-side
|
||||
family split is tighter now too: `p.gms` and `q.gms` no longer live under a generic fallback;
|
||||
their save headers now classify as one explicit `rt3-105-scenario-save` branch with preamble
|
||||
words `0x00040001/0x00018000/0x00000746` and the early secondary window
|
||||
`0x00130000/0x86a00100/0x21000001/0xa0000100`, while `g.gms` now classifies as a second
|
||||
explicit `rt3-105-alt-save` branch with the different preamble lane
|
||||
`0x0001c001/.../0x00000754` and early window
|
||||
`0x00010000/0x49f00100/0x00000002/0xa0000000`. That branch now carries the same bootstrap,
|
||||
anchor-cycle, named 1.05 trailer, and narrow profile-block extraction path as the other 1.05
|
||||
saves. The bridge just below that trailer is now explicit too: the common 1.05 save branch
|
||||
carries selector/descriptor `0x7110 -> 0x7801` in `Autosave.gms` and `0x7110 -> 0x7401` in
|
||||
`nom.gms`, and both still reach the same first later candidate at
|
||||
`span_target + 0x189c`, well before the packed profile at `span_target + 0x3d48`; the
|
||||
`rt3-105-alt-save` branch instead carries `0x54cd -> 0x5901` and its first later candidate
|
||||
lands at `packed_profile + 0x104`, essentially on the profile tail; the scenario-save branch
|
||||
still diverges locally with `0x0001 -> 0x0186` and never enters that later `0x32c8`-spanned
|
||||
bridge at all. The common-branch bridge payload is narrower now too: both checked base saves
|
||||
expose the same 0x20-byte primary block at `0x4f14` followed by the same denser secondary block
|
||||
at `0x671c`, `0x1808` bytes later, and that secondary block now appears to run intact up to the
|
||||
packed-profile start at `0x73c0` for a total observed span of `0xca4` bytes. The trailing slice
|
||||
of that secondary block is now typed one level further: a small header at `secondary+0x354`
|
||||
carries the observed stride `0x22`, capacity `0x44`, and count `0x43`, followed by a fixed-width
|
||||
67-entry name table starting at `secondary+0x3b5` and running through names like
|
||||
`AluminumMill`, `AutoPlant`, `Bakery`, `Port00..11`, and `Warehouse00..11`, with a short footer
|
||||
(`dc3200001437000000`) after the last entry. The trailing per-entry word is now surfaced too:
|
||||
most entries carry `0x00000001`, while the currently observed zero-trailer subset is
|
||||
`Nuclear Power Plant`, `Recycling Plant`, and `Uranium Mine`. That footer is tighter now too:
|
||||
it parses directly as `0x32dc`, `0x3714`, and one trailing zero byte, so the shared
|
||||
map/save catalog currently ends on the same two grounded late-rehydrate progress ids that the
|
||||
classic staged-profile band already exposed. The strongest structural read is therefore that the
|
||||
entire `0x6a70..0x73c0` catalog region is shared verbatim between `Alternate USA.gmp` and the
|
||||
derived `Autosave.gms`, not rebuilt independently during save. Combined with the earlier
|
||||
grounded record-layout work under `0x00437743`, `0x00434ea0`, and `0x00434f20`, the current
|
||||
safest semantic read is that this shared catalog is the bundled source form of the scenario-side
|
||||
named candidate-availability table later mirrored into `[state+0x66b2]`, with each entry's
|
||||
trailing dword now reading as the same availability override bit later copied into
|
||||
`[candidate+0x7ac]`. The loader-side coverage is tighter now too: the same table parser now
|
||||
attaches both to the common-save bridge payload and directly to the fixed source range in
|
||||
`.gmp` files and the non-common `rt3-105-scenario-save` / `rt3-105-alt-save` branches. That
|
||||
makes the scenario variation explicit instead of anecdotal. `Alternate USA` keeps only three
|
||||
zero-availability names in this table (`Nuclear Power Plant`, `Recycling Plant`, `Uranium
|
||||
Mine`), `Southern Pacific` widens the zero set to twelve (`AutoPlant`, `Chemical Plant`,
|
||||
`Electric Plant`, `Farm Rubber`, `FarmRice`, `FarmSugar`, `Nuclear Power Plant`, `Plastics
|
||||
Factory`, `Recycling Plant`, `Tire Factory`, `Toy Factory`, `Uranium Mine`), and `Spanish
|
||||
Mainline` widens it again to forty-two, including `Bauxite Mine`, `Logging Camp`, `Oil Well`,
|
||||
`Port00`, and the `Warehouse00..11` run while also flipping `Recycling Plant` back to
|
||||
available. The header lanes just ahead of the table vary coherently with those scenario
|
||||
branches too: `Alternate USA` carries `header_word_0 = 0x10000000`, `Southern Pacific`
|
||||
carries `0x00000000`, and `Spanish Mainline` carries `0xcdcdcdcd`, while the structural
|
||||
fields from `header_word_2` onward remain stable (`0x332e`, `0x1`, `0x22`, `0x44`, `0x43`)
|
||||
and the 9-byte footer still decodes as `0x32dc`, `0x3714`, `0x00` in all three checked maps.
|
||||
A wider corpus scan over the visible `.gmp`/`.gms` files makes those two anonymous header
|
||||
lanes less mysterious too: the parser currently sees only three stable
|
||||
`(header_word_0, header_word_1)` pairs across 79 files with this table shape, namely
|
||||
`(0x00000000, 0x00000000)`, `(0x10000000, 0x00009000)`, and
|
||||
`(0xcdcdcdcd, 0xcdcdcdcd)`. The zero-availability count varies widely underneath the first and
|
||||
third pairs (`0..56` under the zero pair, `14..67` under the `0xcdcdcdcd` pair), so those two
|
||||
lanes no longer look like counts or direct availability payload; the safest current read is
|
||||
that they are coarse scenario-family or source-template markers above the stable
|
||||
`0x332e/0x22/0x44/0x43` table header, with `0xcdcdcdcd` still plausibly acting as one reused
|
||||
filler or sentinel lane rather than a meaningful numeric threshold. Current exported
|
||||
disassembly notes still do not ground one direct loader-side or editor-side consumer of
|
||||
`header_word_0` or `header_word_1` themselves, so that family-marker read remains an
|
||||
inference from corpus structure rather than a named field assignment.
|
||||
The new loader-side compare command makes the save-copy claim sharper too: for the checked
|
||||
pairs `Alternate USA.gmp -> Autosave.gms`, `Southern Pacific.gmp -> p.gms`, and
|
||||
`Spanish Mainline.gmp -> g.gms`, the parsed candidate-availability table contents now match
|
||||
exactly entry-for-entry, with the only reported differences being the outer container family
|
||||
(`map` vs `save`) and source-kind path (`map-fixed-catalog-range` vs the save-side branch).
|
||||
has the explicit companion `world_refresh_selected_year_bucket_scalar_band` `0x00433bd0`, which
|
||||
rebuilds the dependent selected-year bucket floats after the packed year changes; and then
|
||||
rehydrates the named locomotive availability collection at `[world+0x66b6]` through
|
||||
`locomotive_collection_refresh_runtime_availability_overrides_and_usage_state` `0x00461e00`.
|
||||
That locomotive-side restore is tighter now too: its tail explicitly re-enters
|
||||
`scenario_state_refresh_cached_available_locomotive_rating` `0x00436af0`, which rebuilds one
|
||||
cached available-locomotive rating at `[state+0x4cbe]` from the current year plus the strongest
|
||||
surviving available locomotive-side rating scalar `[loco+0x20]`, and the tiny query sibling
|
||||
`0x00434080` is now bounded as the shell-side clamped read helper over that same cached field,
|
||||
with the grounded shell-side reader later bucketing that value against `40/50/70/85/100`. The
|
||||
same rehydrate band also refreshes the live structure-candidate filter and year-visible counts
|
||||
through `structure_candidate_collection_refresh_filter_and_year_visible_counts` `0x0041e970`,
|
||||
rebuilding the paired per-slot bands at `[candidates+0x246]` and `[candidates+0x16e]` and the
|
||||
aggregate counts at `[candidates+0x31a]` and `[candidates+0x242]`; the same late checkpoint also
|
||||
re-enters `placed_structure_collection_seed_candidate_subtype2_runtime_latch` `0x00434d40`,
|
||||
which seeds runtime dword `[candidate+0x7b0]` across subtype-`2` candidate records before the
|
||||
later world-wide reactivation sweep. That checkpoint also now has an explicit shell-facing scalar
|
||||
publisher: `world_publish_shell_controller_progress_scalar_from_year_thresholds_or_selector_overrides`
|
||||
`0x004354a0` writes one clamped `0..255` value into the current shell presentation object,
|
||||
sourcing it either from the shell selector override pairs or from the scenario-side year-threshold
|
||||
band rooted at `[state+0x3a/+0x51/+0x55/+0x59/+0x5d/+0x61]`; and just ahead of the later
|
||||
scenario-side recipe rebuild, the same band also re-enters
|
||||
`scenario_state_ensure_derived_year_threshold_band` `0x00435603`, which only falls into its
|
||||
heavier rebuild body while `[state+0x3a] < 2` and otherwise leaves the derived year-threshold
|
||||
companion slots `[state+0x51/+0x55/+0x59/+0x5d/+0x61]` unchanged. The neighboring late status
|
||||
checkpoints around progress ids `0x196` and `0x197` also share one explicit stage gate now:
|
||||
`world_query_global_stage_counter_reached_late_reactivation_threshold` `0x00444dc5` compares the
|
||||
global counter `0x00620e94` against threshold `0x9901`, and the two current callers use a
|
||||
negative result to clear `[world+0x39]` before the broader world and shell reactivation sweep.
|
||||
The later reactivation tail is tighter now too: it includes the region-center world-grid flag
|
||||
reseed pass
|
||||
`0x0044c4b0`, which clears bit `0x10` across the live grid and then marks one representative
|
||||
center cell for each class-`0` region through `0x00455f60`; its immediate sibling `0x0044c450`
|
||||
then reruns `placed_structure_rebuild_candidate_cargo_service_bitsets` `0x0042c690` across every
|
||||
live grid cell. The small secondary-raster premark helper `0x0044c570` is bounded now too: it
|
||||
only admits cells whose current raster byte has no bits in mask `0x3e` and whose parallel class
|
||||
query `0x00534e10` is false, then rewrites that masked class field to `0x02` and widens the same
|
||||
cached bounds-and-count band `[world+0x21c6..+0x21d6]`. The next helper `0x0044ce60` scans the secondary raster at `[world+0x2135]`
|
||||
for cells with any bits in mask `0x3e`, caching min/max bounds plus a marked-cell count in
|
||||
`[world+0x21c6..+0x21d6]`; the larger sibling `0x0044c670` then consumes those cached bounds to
|
||||
normalize the same raster and rebuild one dependent overlay/cache surface before the later
|
||||
route-style rebuild, shell-window, and briefing branches. That overlay side is tighter now too:
|
||||
after `0x0044c670` resolves scaled surface dimensions through `0x00534c50`, it walks one local
|
||||
`3 x 32` sample lattice through the static offset tables at `0x00624b28/0x00624b48`, keeps only
|
||||
secondary-raster classes `4..0x0d`, folds several interpolated `0x0051db80` samples into one
|
||||
strongest local score, writes packed overlay pixels into the staged surface buffer, and only then
|
||||
publishes that staged overlay through `0x00534af0`. The lower helper layer under that overlay
|
||||
pass is tighter now too: `0x00534e10` is the reusable secondary-raster class-set
|
||||
predicate for classes `1/3/4/5`, `0x00534e50` is the smaller neighboring class-subset predicate
|
||||
for `1/4`, `0x00534ec0` covers `2/4/5`, `0x00534f00` covers `3/5`, `0x00534e90` is the
|
||||
marked-bit query over the same 3-byte cell family, and the nearby local counter `0x0044bdb0`
|
||||
is now bounded as the 8-neighbor count companion for that same `2/4/5` subset, walking the
|
||||
shared `0x00624b28/0x00624b48` offset tables and re-entering `0x00534ec0` on each bounded
|
||||
neighbor cell. The first caller cluster around `0x0044bf9d..0x0044c37b` therefore reads as a
|
||||
secondary-raster neighborhood service band rather than a generic map scan.
|
||||
`0x00533e70` and `0x00534160` are the coarser siblings over the overlay table at `[world+0x1685]`:
|
||||
the first clears coarse chunk objects across one clamped rectangle, while the second ensures one
|
||||
chunk object and seeds local marks through its deeper stamp helper. One level up, the neighboring
|
||||
rect owner `0x005374d0` now reads as the shared secondary-overlay refresh pass: it reruns the
|
||||
local sample and unsigned-word reducers `0x00536230/0x00536420`, rebuilds the signed vector byte
|
||||
planes through `0x00536710`, and then rebuilds the multiscale support surfaces through
|
||||
`0x00533890`, whose inner reducers now explicitly target the packed sample-triplet buffer plus
|
||||
the float and unsigned-word support planes rooted at the five-entry per-scale families
|
||||
`[world+0x15f1..+0x1601]`, `[world+0x1605..+0x1615]`, and `[world+0x1619..+0x1629]`. The setup
|
||||
side of that same family is tighter now too:
|
||||
`0x005375c0` is the shared ensure-and-seed owner that allocates the sample, sidecar, mask,
|
||||
raster, vector, and coarse-cell tables together; crucially, it seeds `[world+0x1655]` with byte
|
||||
`0x02` and `[world+0x1659]` with byte `0x01`, which closes the default-fill split. The local
|
||||
component-walk owner under the same neighborhood band is tighter now too: `0x0044c200`
|
||||
allocates a temporary `width*height` visit bitmap at `0x0062c128`, seeds one class-`2/4/5`
|
||||
starting cell, derives an initial direction index through the remap table `0x005ee5d4`, and then
|
||||
fans into the deeper recursive walker `0x0044be20`. That deeper walker widens dirty bounds
|
||||
`[world+0x21ad..+0x21b9]`, stamps one companion-word orientation lane through `0x005ee5cc`,
|
||||
reuses `0x00534ec0` plus `0x0044bdb0` to filter admissible neighbors, tracks temporary
|
||||
visitation in `0x0062c128`, and then applies the local byte-1 edge-bit `0x04/0x08` updates
|
||||
before returning. So the `0x0044bf9d..0x0044c422` cluster now reads as a real connected-component
|
||||
walk plus edge-flag refresh layer over the secondary raster rather than only a loose group of
|
||||
local neighbor counters. The adjacent mutation strip is tighter now too: `0x0044dcf0` refreshes
|
||||
companion-word bit `0x200` in one local rectangle by checking whether any neighbor belongs to
|
||||
class set `2/4/5`, while `0x0044df10` clears three local sidecar byte planes, demotes class `4`
|
||||
to `1` and class `5` to `3`, and then reruns that marked-bit refresh over the surrounding
|
||||
`+/-1` window. One level up, `0x0044e500` is the rect-wide owner that recomputes byte-1 edge
|
||||
bits `0x04/0x08` for class-`2/4/5` cells, dispatches `0x0044df10` on incompatible local
|
||||
patterns, and finally consumes the pending global seed pair at `[0x006d1304+0x78/+0x7c]`
|
||||
through `0x0044c200`. The shell-side owner of that pending pair is tighter now too:
|
||||
`[0x006d1304]` is the live `PaintTerrain.win` shell singleton while the callback-heavy side also
|
||||
keeps a second rooted pointer at `0x006d1334`; the tool constructor snapshots the broader
|
||||
terrain-paint state into both families while the world-side raster owner still only consumes
|
||||
`[0x006d1304+0x78/+0x7c]` as one pending component-seed pair. Its radial sibling `0x0044e7d0`
|
||||
is narrower:
|
||||
after validating world-space
|
||||
coordinates through `0x00414bd0`, it stamps class-`2` marks into the secondary raster by walking
|
||||
one clamped bounding box and admitting cells only when the radial falloff helper `0x0051db80`
|
||||
stays positive before re-entering `0x0044c570`. The two small support predicates under that same
|
||||
strip are now explicit too: `0x00414bd0` is the float grid-bounds gate, and `0x00449df0` is the
|
||||
integer rectangle clamp-and-validity helper shared by the local mutation owners. One level up,
|
||||
the broader rect-scoped owner is tighter now too:
|
||||
`world_rebuild_secondary_raster_derived_surface_and_companion_planes_in_rect` `0x0044e940`
|
||||
first reclamps the caller rectangle through `0x00449df0`, reruns the local edge-refresh owner
|
||||
`0x0044e500`, lazily ensures one presentation target through
|
||||
`0x0051f090/0x00534910/0x00534920/0x00534930`: the first helper resolves the shared
|
||||
world-presentation owner, `0x00534910/0x00534920` expose the current staging flag and buffer
|
||||
root, and `0x00534930` captures one normalized-bounds rect into that staging buffer before the
|
||||
later publish step `0x00534af0`. The same family then resolves scaled target dimensions through
|
||||
`0x00534c50` before allocating one temporary `width*height` mask. Its main scan then
|
||||
walks the live secondary raster `[world+0x165d]` through the same class predicates
|
||||
`0x00534e10/0x00534e50/0x00534f00/0x00534ec0`: class-`1/3/4/5` cells force `0xff` into the four
|
||||
sidecar byte planes `[world+0x1631..+0x163d]`, while the broader per-cell pass writes packed
|
||||
values into the ensured target through `0x00534730` and also updates nibble lanes at byte offsets
|
||||
`+0x2` and `+0x5` inside the same three-byte secondary-raster cell family. After the publish it
|
||||
notifies the shell owner at `0x0062be68`, re-enters `0x00449f80` and `0x004881b0`, frees the
|
||||
temporary mask, expands the caller rectangle by dirty bounds `[world+0x21ad..+0x21b9]` through
|
||||
`0x00536710`, and finally seeds companion byte `[world+0x162d]` with `0xc4` on cells selected
|
||||
from mask plane `[world+0x1655]`. So the `0x0044e500 -> 0x0044e940` band is now a real
|
||||
derived-surface and companion-plane rebuild family rather than only a loose collection of local
|
||||
raster mutations. The local
|
||||
evidence now also supports a stronger negative conclusion: unlike `[world+0x1655]`, that second
|
||||
mask plane is not part of the actively rebuilt runtime overlay path, and in the grounded local
|
||||
corpus it behaves only as a separately seeded, cleared, and persisted sibling plane. One level
|
||||
lower, the
|
||||
base-plane allocator `0x00532c80` now reads more cleanly too: it is the narrower owner that
|
||||
clears `[world+0x15e1]`, optionally applies the current grid dimensions, allocates the base
|
||||
float-summary plane `[world+0x1605]`, the four sidecar byte planes `[world+0x1631..+0x163d]`,
|
||||
both one-byte mask planes `[world+0x1655/+0x1659]`, and the packed secondary raster
|
||||
`[world+0x165d]`, then seeds those planes with the same `0x02/0x01/0x00` default split. The
|
||||
load-side owner for those same planes is tighter now too: the constructor thunk `0x0044e910`
|
||||
immediately feeds the heavier payload body `0x0044cfb0`, which reads the rooted chunk families
|
||||
`0x2ee2/0x2ee3/0x2ef4/0x2ef5/0x2ef6/0x2ee4/0x2ee5/0x2f43/0x2f44`, allocates the core world-grid
|
||||
and secondary-raster arrays `[world+0x2129..+0x2141]` plus the route-entry collection
|
||||
`0x006cfca8`, initializes every grid-cell record through `0x0042ae50`, and only then hands off
|
||||
into `world_compute_transport_and_pricing_grid` `0x0044fb70`, the neighboring presentation
|
||||
refresh `0x00449f20`, and the shell-mode pulse `0x00484d70`. So the `0x0044e910 -> 0x0044cfb0`
|
||||
load side is now bounded as the heavy world-grid and secondary-raster bundle-load body rather
|
||||
than just another anonymous constructor tail. One
|
||||
level higher again, the broader world-presentation reinitializer `0x00537e60` now sits above
|
||||
that base allocator and the larger support-family ensure path `0x005375c0`: it stores the live
|
||||
grid dimensions, hard-resets the whole overlay runtime family through `0x00532590`,
|
||||
and that reset strip is no longer opaque either: the immediately preceding local helpers
|
||||
`0x00532310..0x00532550` now bound one compact overlay-local state family under the same owner.
|
||||
`0x00532310/0x00532360/0x00532370/0x00532380` own the seven-dword companion block
|
||||
`[world+0x15b5..+0x15cd]` together with live flag byte `[world+0x15b4]`; `0x005323f0`,
|
||||
`0x00532460`, and `0x00532490` are the ensure, publish, and query strip for cached surface root
|
||||
`[world+0x478]` using saved dimensions `[world+0x159c/+0x15a0]`; `0x005324e0/0x00532500` are the
|
||||
live-flag setters for `[world+0x159b]`; `0x00532510` is the direct setter for mode byte
|
||||
`[world+0x159a]`; and `0x00532520/0x00532550` own the four-dword saved dimension quad
|
||||
`[world+0x15a4..+0x15b0]`. So the broader `0x00532590` reset really does sit at the base of a
|
||||
concrete local cached-surface and companion-block owner family, not just a pile of unrelated
|
||||
presentation fields. The reinitializer then
|
||||
reinitializes the secondary-overlay family for those dimensions, and then republishes the
|
||||
neighboring overlay constants and support owners used by both the world-side reattach branch and
|
||||
the `.smp` restore-side presentation rebuild path, including several owners that all funnel
|
||||
through the shared static-template slot allocator `0x00532ad0` over the local `0x100` pointer
|
||||
band at `[world+0x08]`. Those neighboring owners are tighter now too: `0x00535070` is the small
|
||||
primary overlay-surface-or-template setup owner; `0x00535100` is the heavier requested-dimension
|
||||
apply and four-slot overlay-surface rebuild owner used by the setup-side regenerate branch and
|
||||
the load-side bundle path; while `0x005356e0` and `0x00535890` seed two
|
||||
larger static-template slot bands rooted at `[world+0x1568/+0x156c/+0x1574/+0x1578]` and
|
||||
`[world+0x1560/+0x1564]` respectively; the remaining heavier sibling `0x00535430` now reads as a
|
||||
shared four-slot overlay-surface rebuild owner that resamples one source or fallback descriptor
|
||||
into a short local slot strip above `[world+0x155c]`. The immediate helper strip under that same
|
||||
family is tighter now too: `0x00534f60` is the small presentation-owner base init above
|
||||
`0x00532590`; `0x00534f80` releases one transient surface handle at `[world+0x478]` and clears
|
||||
byte `[world+0x159b]`; `0x00532760` releases the current overlay slot chosen by selector
|
||||
`[world+0x1558]`; `0x005327a0` clamps two requested surface dimensions down to supported
|
||||
power-of-two sizes while also enforcing shell display caps from `[0x006d4024+0x114243/+0x114247]`;
|
||||
`0x00532860` is the local twelve-slot stitching pass over the parallel bands rooted at
|
||||
`[world+0x08/+0x0c/+0x18]`, copying terminal rows and edge dwords between those sibling slot
|
||||
surfaces before finalizing the primary band through `0x00541c10`;
|
||||
`0x00532960` is the adjacent paired projection helper that maps two caller counters through the
|
||||
current `16x16` and `4x4` rounded grid quanta and writes the resulting coarse offsets back to two
|
||||
out-pointers;
|
||||
`0x005329e0` maps one `(x,y)` pair into a `1`-based coarse `4x4` overlay region id using the
|
||||
current rounded grid dimensions; `0x00532a30` is the direct getter for local dword `[world+0x1554]`,
|
||||
which still reads only as the live count or tag for this overlay slot band;
|
||||
`0x00532a40` and `0x00532aa0` are the time-selected query helpers over the first and second
|
||||
template-seeded slot bands rooted at `[world+0x1568/+0x156c]` and `[world+0x1560/+0x1564]`; and
|
||||
`0x00532a90` is the direct getter for trailing fallback slot `[world+0x1578]`. The next adjacent
|
||||
owner is tighter now too: `0x00532b30` is the shared release/reset path for the local overlay
|
||||
slot band at `[world+0x08]`, with a split release policy keyed by shell flag
|
||||
`[0x006d4024+0x11422e]` and a special forced-direct range for slot ids `1..0x10`, after which it
|
||||
clears band fields `[world+0x1554/+0x1568/+0x1570/+0x155c/+0x1560/+0x1564]`. The tail of that
|
||||
same reinitializer is tighter one level up too: `0x00527ce0` is the broader ensure owner that
|
||||
watches current grid extents plus world tag `[world+0x2121]`, re-enters `0x00532860` when those
|
||||
cached values change, rebuilds or releases local helper `[this+0x65]`, and then clears the two
|
||||
large global scratch planes rooted at `0x008f2520` and `0x00b33530`. The tail of that same
|
||||
reinitializer is
|
||||
tighter now too: after the larger support-family setup it seeds one seven-entry default overlay
|
||||
companion set through `0x005373b0`, whose inner allocator `0x00535950` populates the local
|
||||
`0x1b`-entry slot table from the static template rows `0x005dd300..0x005dd378`. The lifecycle
|
||||
side is tighter in the same way now: `0x00536044` is the shared teardown owner that frees those same
|
||||
three five-entry support families together with both mask planes, the packed secondary raster,
|
||||
the vector-byte planes, the local staging buffer, and the neighboring sidecar or coarse-cell
|
||||
tables. The remaining base-float lane is tighter too: the larger rebuild owner
|
||||
`0x00538360` now clearly writes one base float-summary field into `[world+0x1605]`, clears both
|
||||
one-byte mask planes, and then only repopulates the primary mask plane `[world+0x1655]` for the
|
||||
qualifying class-`1` interior cells before re-entering `0x00532d90` to normalize that base
|
||||
float-summary plane globally and `0x00532f60` to expand positive cells through one caller radius.
|
||||
That asymmetry is now enough to close the local semantic edge: `[world+0x1655]` is the actively
|
||||
rebuilt primary overlay mask, while `[world+0x1659]` is only the separately seeded and persisted
|
||||
secondary mask sibling with no comparably grounded distinct read-side consumer. The only grounded
|
||||
getter call to its root accessor `0x00533b60` is the shell staging branch at `0x00525bad`, and
|
||||
that branch immediately discards the returned pointer. The bundle side is now explicit too:
|
||||
`.smp` save-load treats the two mask planes as separate payloads with chunk ids `0x2cee` for
|
||||
`[world+0x1655]` and `0x2d51` for `[world+0x1659]`, while the neighboring `0x2d49/0x2d50`
|
||||
branches are the separate packed secondary-raster import lanes rather than alternate consumers
|
||||
of the second mask plane. So, in the mapped local code, `0x1659` is best treated as a persisted
|
||||
compatibility or seed-state sibling, not as a second actively consumed runtime overlay mask. The
|
||||
transport/pricing preview side is tighter now too: `0x00538060` sits directly beneath
|
||||
`0x0044faf0`, first seeds one preview handle through `0x00535430` using the short `C_`
|
||||
descriptor, temporarily overrides shell globals
|
||||
`[0x006d4024+0x11423b/+0x11423f/+0x114254/+0x114255]`, and then loads `%1.tga` through
|
||||
`0x0053c1c0 -> 0x00541970`. It clamps that sampled image into the `0x401 x 0x401` range,
|
||||
rewrites `[world+0x1605]` plus the mask/raster family `[world+0x1655/+0x1659/+0x165d]` from the
|
||||
sampled pixels, optionally re-enters `0x00532d90/0x00532f60`, republishes the seeded preview
|
||||
handle through `0x0053c000`, and then re-enters `0x005375c0(1, 0, 0)`. The small shell-global
|
||||
owner it also touches is tighter now too: `0x006d401c` is constructed by `0x00538640`,
|
||||
`0x005386e0` publishes the primary timed text lane, `0x005387a0` publishes the secondary fixed
|
||||
`10000` ms lane, `0x00538810` finds the first registered shell window containing one child
|
||||
control id by walking each window through `0x0053f830`, and `0x00538840/0x00538880/0x00538890`
|
||||
manage the owner's local `1000`-slot active-token table keyed by child control id. The adjacent
|
||||
list strip is tighter too: `0x00538990` is the registered-window virtual-slot-`0` gate that
|
||||
stops on the first zero return, `0x005389c0` is the shared unlink helper for the same doubly
|
||||
linked list rooted at `[owner+0x00/+0x04]`, `0x00538a60` is the zero-counter gate over
|
||||
`[owner+0xc60]`, `0x00538a70` is the matching full reset-and-release body used during bootstrap
|
||||
teardown, and `0x00538a10/0x00538a20/0x00538a30/0x00538a40` are the direct getter, setter,
|
||||
increment, and clamped decrement helpers for the owner's scalar lanes `[+0xc5c]` and `[+0xc60]`.
|
||||
The next shell-runtime strip is tighter now too: `0x005388d0` is the shared `12`-dword
|
||||
descriptor dispatcher with the optional override validator at `[owner+0xc75]` and the recursive
|
||||
`kind 6 -> 0xb7` rewrite; `0x00538c70` is the prioritized cached-text owner over
|
||||
`[owner+0xbd8/+0xbdc/+0xbe0/+0xbe4]` that emits descriptor kind `0xae` through `0x005388d0`;
|
||||
`shell_dispatch_synthetic_12_dword_descriptor_from_five_scalars` `0x00538e00` is the five-scalar
|
||||
descriptor-synthesis wrapper above that same dispatcher;
|
||||
`0x00538e50` is the sorted registered-window insert owner over node key `[node+0x21]`;
|
||||
`0x00538ec0` is the refresh sweep over the indexed helper collection rooted at `[owner+0xc69]`;
|
||||
and `0x00538f10` is the broader optional-window publish plus blocking descriptor loop used by
|
||||
modal launchers and some shell transition paths.
|
||||
2656
docs/control-loop-atlas/runtime-roots-camera-and-support-families.md
Normal file
2656
docs/control-loop-atlas/runtime-roots-camera-and-support-families.md
Normal file
File diff suppressed because it is too large
Load diff
148
docs/control-loop-atlas/station-detail-overlay.md
Normal file
148
docs/control-loop-atlas/station-detail-overlay.md
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
# Input, Save/Load, and Simulation: Station-detail Overlay
|
||||
|
||||
### Station-detail overlay
|
||||
|
||||
The shell-side candidate preview pair now has a grounded world consumer
|
||||
too. `world_render_station_candidate_service_map_overlay` at `0x0043f640` reads the active
|
||||
`(station id, candidate id)` pair from
|
||||
`world_store_station_detail_candidate_service_preview_pair_globals` `0x0043f620` and
|
||||
`world_clear_station_detail_candidate_service_preview_pair_globals` `0x0043f610`, scans the
|
||||
placed-structure collection, and then splits the legend by candidate mode. When the active candidate carries a
|
||||
nonzero route-style byte at `[candidate+0x46]`, the overlay uses the heavier helper
|
||||
`placed_structure_query_candidate_directional_route_overlay_summary` at `0x0047e690` in both
|
||||
directions between the preview station and each scanned site and formats the resulting directional
|
||||
rows as `3874` `Coming To %1` and `3875` `Going From %1`. When that byte is zero, the same overlay
|
||||
falls back to the direct local-service path through
|
||||
`placed_structure_query_candidate_local_service_metrics` and formats the two legend rows instead
|
||||
as `3876` `Current Supply @ < %1` and `3877` `Current Demand @ > %1`. Empty directional lanes
|
||||
collapse to `3878` `--None--`, and one title lane falls back to literal `All`. Current disassembly
|
||||
no longer supports treating `3872` `Already Connected by Another Company` or `3873` `Not
|
||||
Connected` as direct overlay-body emits.
|
||||
#### Corrected boundary
|
||||
|
||||
The neighboring connection-state note pair now appears
|
||||
to live in a city connection-bonus label formatter, not in `0x0043f640`. That formatter is now
|
||||
bounded as `city_site_format_connection_bonus_status_label` at `0x004207d0`: it directly chooses
|
||||
localized ids `3868` through `3873` after consulting the reusable city-peer scan
|
||||
`city_connection_bonus_exists_matching_peer_site` at `0x00420030`. Separately, `3879` `Out of
|
||||
Sync` is grounded under the multiplayer preview dataset path instead:
|
||||
`multiplayer_preview_dataset_service_launch_state_and_warn_out_of_sync` at `0x0046b780` checks
|
||||
global `0x006cd91c`, raises the `Out of Sync` shell status through `0x5386e0`, and then continues
|
||||
through the wider multiplayer preview launch-state service. So the station-detail overlay
|
||||
currently owns only the `Coming To`, `Going From`, `Current Supply`, `Current Demand`, `--None--`,
|
||||
and `All` legend lanes.
|
||||
#### Ownership side
|
||||
|
||||
One reusable site helper is grounded now too.
|
||||
`placed_structure_query_linked_company_id` at `0x0047efe0` resolves the current placed structure's
|
||||
linked instance through `0x0062b26c` and returns its company id from `[instance+0x276]`; the
|
||||
adjacent city bonus formatter at `0x004207d0` compares that id against the active company selector
|
||||
before choosing whether a scanned site should carry `3871` `Connected By Another Company` or
|
||||
`3872` `Already Connected by Another Company`. The larger caller boundary is no longer open
|
||||
either: the first bounded announcement owner above this formatter family is now
|
||||
`company_evaluate_and_publish_city_connection_bonus_news` at `0x00406050`, which re-enters the
|
||||
peer-route candidate builder at `0x004046a0` and later publishes one of the localized
|
||||
city-connection bonus news strings `2888`, `2890`, or `2921` through the shell news path.
|
||||
#### Peer-selector side
|
||||
|
||||
The city bonus formatter no longer depends only on
|
||||
boolean peer existence. The companion helper
|
||||
`city_connection_bonus_select_first_matching_peer_site` at `0x00420280` is now grounded as the
|
||||
first-match selector paired with `city_connection_bonus_exists_matching_peer_site`: it walks the
|
||||
same city-peer candidate set, applies the same site-class table plus the narrower
|
||||
station-or-transit and linked-instance class-byte flags, and returns one representative matching
|
||||
peer site id instead of a boolean. `city_site_format_connection_bonus_status_label` reuses that
|
||||
selector after the note checks so it can recover one linked company context from the selected
|
||||
peer. The remaining open edge here is therefore above this formatter family, not inside the
|
||||
peer-scan pair itself.
|
||||
#### Caller side
|
||||
|
||||
The reusable bridge between the status formatter and the
|
||||
company news lane is now bounded too. `city_connection_bonus_build_peer_route_candidate` at
|
||||
`0x004046a0` reuses `city_connection_bonus_select_first_matching_peer_site` with both selector
|
||||
flags forced on, samples the selected peer's derived coordinates through `0x0047df30` and
|
||||
`0x0047df50`, and then either tries the shared heavy builder
|
||||
`city_connection_try_build_route_with_optional_direct_site_placement` `0x00402cb0` or falls
|
||||
back to the smaller wrapper `city_connection_bonus_try_compact_route_builder_from_region_entry`
|
||||
`0x00404640` before handing the result back to the company-side announcement sweep at
|
||||
`0x00406050`. The score side of that announcement lane is tighter now as well:
|
||||
`city_compute_connection_bonus_candidate_weight` at `0x004010f0` provides the per-city opportunity
|
||||
weight, `company_query_min_linked_site_distance_to_xy` at `0x00405920` provides the nearest
|
||||
linked-site distance term, `company_count_linked_transit_sites` at `0x00426590` provides one of
|
||||
the company-side caps, `company_compute_connection_bonus_value_ladder` at `0x00425320` supplies
|
||||
the bounded company-side value scalar, and
|
||||
`company_compute_prime_rate_from_issue39_scenario_baseline` at `0x00424580` now bounds the
|
||||
shared prime-rate-side helper that this lane reuses beside the raw issue-`0x39` total,
|
||||
`scenario_state_sum_issue_opinion_terms_raw` at `0x00436710` now bounds the raw additive
|
||||
issue-total helper beneath that term, and `company_connection_bonus_lane_is_unlocked` at
|
||||
`0x00427590` is the small boolean gate above the ladder. Wider governance and CompanyDetail xrefs
|
||||
now tighten slot `0x2b` into the rolling net-profits lane reused by annual finance checks and a
|
||||
per-share/history formatter, while the report-history descriptor table now aligns raw slot `0x09`
|
||||
with the Income Statement fuel-cost lane surfaced by tooltip `1309`. The wider result now reads
|
||||
more like recent net profits minus recent fuel burden than a governance-pressure term. That now
|
||||
also sharpens the annual finance lane at `0x00401c50`: the first bankruptcy branch reads as
|
||||
sustained cash-and-debt stress over recent profits and fuel burden, the later fallback branch as
|
||||
a deeper `-300000` cash / three bad years cleanup trigger, and the later stock-issue branch reads
|
||||
as a price-to-book-versus-coupon approval ladder rather than a generic support vote. The tail is
|
||||
cleaner now too: it compares total retired versus newly issued principal to choose the `2882..2886`
|
||||
debt headline family, then publishes `2887` separately from the accumulated repurchased-share
|
||||
count. The sibling news owner above the same
|
||||
city-pair route family is bounded now too:
|
||||
`simulation_try_select_and_publish_company_start_or_city_connection_news` `0x00404ce0`
|
||||
filters and scores candidate city entries, re-enters the same shared heavy builder through
|
||||
`city_connection_try_build_route_between_region_entry_pair` `0x00404c60` for the dense pair
|
||||
sweep and the final retry, and then publishes `2889` `%1 has started a new company - the %2`
|
||||
or `2890` `%1 has connected %2 to %3.` through the shell news path. The remaining open edge on
|
||||
this branch is therefore narrower now: it is mostly whether `0x39` should be read as the
|
||||
narrower city-connection public-opinion lane or as part of a broader management-attitude family,
|
||||
not the ownership of the connection-bonus formatter, peer-route candidate path, or company news
|
||||
gate.
|
||||
#### Route-list side
|
||||
|
||||
The neighboring helper
|
||||
`placed_structure_append_unique_route_entry` at `0x0047f010` is now grounded as the
|
||||
append-if-missing builder for the six-byte route-entry list rooted at `[site+0x462]` and
|
||||
`[site+0x466]`. That matters here because the directional overlay query at `0x0047e690` consumes
|
||||
the same list, so the remaining uncertainty is no longer list ownership. It is down to the exact
|
||||
semantics of each entry's `u32` payload.
|
||||
#### Route-entry and Cache Side
|
||||
|
||||
The adjacent helper strip is tighter now too.
|
||||
`placed_structure_service_candidate_local_service_comparison_cache_decay_and_row_propagation`
|
||||
`0x0047df70` is the recurring age-and-propagation service pass over the paired comparison-cache
|
||||
float tables `[site+0x3e]` and `[site+0x112]` with age stamps at `[site+0x1e6]`; it zeroes stale
|
||||
entries older than `0x1d8800`, decays younger ones by the fixed `0x005ce900/0x005ce8f8` scales,
|
||||
and then propagates stronger marked row values back through the three five-float row bands rooted
|
||||
at `[site+0x24/+0x28/+0x2c]`. The wrapper
|
||||
`placed_structure_query_candidate_route_or_local_service_comparison_score` `0x0047e9a0` is now
|
||||
bounded too: it delegates to `placed_structure_query_candidate_directional_route_overlay_summary`
|
||||
`0x0047e690` when the requested candidate carries a grouped routing class, otherwise it uses the
|
||||
simpler local `[cell+0x103]` lane and the current sample list at `[site+0x34/+0x38]` before
|
||||
writing back into the same comparison-cache bands. The route-entry strip beneath the linked-peer
|
||||
family is no longer open either: `placed_structure_resolve_route_entry_anchor_record`
|
||||
`0x0047f310` is the direct resolver over `[site+0x08]`, and
|
||||
`placed_structure_route_anchor_matches_or_reaches_route_entry_id` `0x0047f250` is the boolean
|
||||
gate above it, first checking a direct match against `[site+0x08]` and then re-entering
|
||||
`0x0048e050(mode 2, fallback -1)` on the resolved route-entry record. The route-link companion
|
||||
`route_link_route_entry_reaches_peer_site_route_group` `0x0047f2d0` is tighter now too: it reads
|
||||
the peer site's route-entry anchor from `[peer+0x08]`, resolves the current link's own anchor,
|
||||
and re-enters `0x0048e3c0` to test whether the two anchors belong to the same reachable
|
||||
route-side family. One smaller linked-peer-side setter is grounded as well:
|
||||
`placed_structure_set_overlay_mark_byte_and_refresh_linked_peer_overlay_if_changed` `0x0047f290`
|
||||
updates byte `[site+0x5bc]` and then re-enters
|
||||
`placed_structure_refresh_linked_peer_overlay_when_linked_peer_flagged` `0x0040d2d0` when the
|
||||
byte changes.
|
||||
#### Terrain-class Side
|
||||
|
||||
The nearby linked-instance raster wrappers are no
|
||||
longer anonymous. `world_resolve_secondary_raster_class_record_at_float_xy` `0x0044e270` is the
|
||||
world-side float-XY lookup over `[world+0x2131]` plus class table `0x006cfc9c`;
|
||||
`placed_structure_query_linked_instance_secondary_raster_class_id` `0x0047f170` is the raw
|
||||
linked-instance wrapper that returns the shifted class id directly; and the paired
|
||||
record-returning wrappers `placed_structure_resolve_linked_instance_secondary_raster_class_record`
|
||||
`0x0047f0e0` and
|
||||
`placed_structure_resolve_linked_instance_secondary_raster_class_record_via_world_query`
|
||||
`0x0047f1f0` now bound the two record-returning lanes used by the later world-side and
|
||||
linked-peer filters. That means the remaining uncertainty in this neighborhood is no longer the
|
||||
route-entry or terrain-class helper ownership; it is the broader user-facing meaning of the later
|
||||
callers that consume those gates.
|
||||
Loading…
Add table
Add a link
Reference in a new issue