Research
This commit is contained in:
parent
28cbbe3470
commit
a9153546ae
56 changed files with 6731 additions and 258 deletions
|
|
@ -62,6 +62,14 @@ Representative maps after the extended pass:
|
|||
|
||||
So the first practical conclusion is straightforward: the exporter was the main blocker for most maps, and a constrained donor heuristic can replace a large fraction of placeholders with real graphics without touching the viewer runtime.
|
||||
|
||||
## No-Placeholder Cohort Pass
|
||||
|
||||
- A second follow-up pass replaced synthetic fallback atlas generation with cohort-aware donor resolution keyed by authored family plus raw `u5` lane before the older coarse type default is consulted.
|
||||
- The exporter still prefers direct local `DAT_800758d8` payload matches first, but when a type bucket is mixed-role or otherwise unresolved it now resolves each cohort separately instead of collapsing the whole `map:type` bucket into one donor or one placeholder.
|
||||
- Focused validation on `map 104` now rebuilds as `1002` real-art items with `0` fallback items, `1` atlas, and `136` shape definitions. Scene `sourceCounts` are now `52` `section0_dispatch_roots-art` plus `950` `section0_constructor_placements-art`.
|
||||
- The scene JSON also now preserves `mappingSource` and optional `artCohort` on each `mapSource` row, so provisional cohort and emergency donor matches stay auditable after placeholders are removed.
|
||||
- This is still not the final executable-proof binding rule. The focused cache is now placeholder-free, but many rows still resolve through `cohort-*` or `emergency-global-donor:*` provenance and should be treated as provisional PSX art recovery rather than as final family/resource closure.
|
||||
|
||||
## Remaining Unresolved Mass
|
||||
|
||||
- The cache is still not fully closed. `25,038` fallback items remain across `62` maps.
|
||||
|
|
@ -70,12 +78,71 @@ So the first practical conclusion is straightforward: the exporter was the main
|
|||
- `0x0042` remains the single largest unresolved type even after the heuristic pass.
|
||||
- `map 104` is the most obvious current outlier: it still sits at `866` fallback items versus only `136` bundle-mapped items, so the next recovery pass should treat it as the best stress case rather than relying only on the now-mostly-readable early maps.
|
||||
|
||||
Those counts are now historical rather than current for the focused `map 104` export. They remain useful as the baseline that motivated the cohort pass, but the immediate blocker has shifted from “remove placeholders” to “replace provisional donor provenance with tighter executable-backed cohort/resource rules.”
|
||||
|
||||
## Practical Interpretation
|
||||
|
||||
- The donor heuristic is good enough to prove that many placeholders were caused by missing extraction-time inheritance logic.
|
||||
- It is not strong enough to count as the final executable-backed rule for the unresolved families.
|
||||
- The remaining gap still sits where the earlier Ghidra work already pointed: somewhere between the constructor-side art/resource creation lane and the live post-spawn state/resource/frame reselection path.
|
||||
|
||||
## Palette Lock-In Rule
|
||||
|
||||
- The PSX exporter must not treat `mode 1` bundle header palette index `+0x14` as the rendered 256-color selector.
|
||||
- The current dump-grounded rule is narrower and stronger: the known-good visible family decodes against one contiguous 256-entry lookup table equivalent to live VRAM row `0xF0`, `x=0`.
|
||||
- In extractor terms, that behaves like the first `16` adjacent `16-color` CLUTs flattened into one 256-entry palette. That is the rule now encoded in `map_renderer/src/lib/psx-cache.js` for `mode 1` bundles.
|
||||
- The old bundle-header palette index is still preserved in exported scene metadata as `defaultPaletteIndex`, but it is diagnostic provenance, not the primary rendered selector.
|
||||
- `mode 2` stays on the earlier per-bundle/per-usage palette-index path. This lock-in applies specifically to the current `mode 1` family proven by the VRAM dump.
|
||||
- If a future pass proves a wider runtime CLUT-row formula, update this note and the exporter together in one change. Do not silently reintroduce `mode 1 -> bundle header palette index` as a fallback rule.
|
||||
|
||||
## Static Export Follow-Up
|
||||
|
||||
- The processed PSX catalog already carried `62` maps during this pass, so the "single map" symptom was not a cache-build enumeration failure.
|
||||
- The immediate export-side blocker was config: `psx-remorse` was excluded from static export even though the prebuilt catalog/build-manager path already supports multi-map PSX scenes.
|
||||
- The renderer config now includes `psx-remorse` in static export so full PSX exports can surface the full processed map set instead of dropping the version entirely.
|
||||
|
||||
## Live MCP Follow-Up (2026-04-12): Wall-Family Split Failure Mode
|
||||
|
||||
- Scope for this focused pass: live `SLUS_002.68` around the wall-heavy generic family band (`0x003e..0x004f`) and exporter donor-heavy bundles (`0x0008b48c`, `0x00085c40`).
|
||||
- Constructor-side bind is now explicit and consistent across this family: both `psx_object_create_simple_record` (`0x800249f4`) and `psx_object_create_compound_record` (`0x80024eec`) read the per-type active art header from `DAT_800758d8[type]` before any lane-orientation updates.
|
||||
- That means cross-family visual collapse is unlikely to be caused by a missing pre-constructor resource-bank split in this band; divergence happens after bind.
|
||||
- Post-bind state/frame path is also explicit: `psx_object_select_state_script` (`0x800260e8`) installs selector state (`obj+0x9e` and script cursor `obj+0x90`), then `psx_object_advance_state_script` (`0x80025d68`) latches live frame token `obj+0x94` from the script stream.
|
||||
- Draw submission consumes that latched token, not raw authored selector: stage-1 geometry (`0x80040d44`) and stage-2 geometry (`0x80040f78`) both query frame geometry from `obj+0x94`, and submitters read the same token in `psx_draw_main_visible_object` (`0x80041458`) / `psx_draw_special_visible_queue` (`0x80041144`).
|
||||
- The stage-1/stage-2 route split matters materially: main-visible injects authored palette token only for type bands `>=0x003e`, while special-visible does not. If exporter cohorts collapse route outcome, families can appear as repeated art with wrong face/palette behavior.
|
||||
- Practical exporter implication: the strongest missing discriminator is runtime route+latch state (effective selector/latch outcome), not a new type-level resource bank key.
|
||||
|
||||
Conservative live-artifact updates applied in Ghidra for this pass:
|
||||
|
||||
- `0x80046038`: comment clarifying `DAT_800758d8[type]` install timing and post-bind divergence expectation.
|
||||
- `0x80026100`: comment clarifying pre-latch selector install and risk of authored-`u4`-only grouping.
|
||||
- `0x80041554`: comment clarifying main-visible-only authored palette-token lane for `>=0x003e`.
|
||||
- `0x80040f88`: comment clarifying stage-2 queue still consumes `obj+0x94` but has different route semantics.
|
||||
|
||||
## Live MCP Follow-Up (2026-04-12): CLUT Override Routing Closure
|
||||
|
||||
- Scope for this focused pass: world-object draw path and submitters at `0x80041458`, `0x80041144`, `0x80044bdc`, and `0x80044e9c`, with CLUT table symbols at `0x800a9f48` and `0x800a9f66`.
|
||||
- `0x800a9f48` remains `psx_clut_table_by_resource_bank` and is both load-populated (`level_palette_upload_cluts`) and draw-consumed.
|
||||
- `0x800a9f66` remains `psx_clut_override_table_by_palette_token` and is draw-consumed by both submitters.
|
||||
- Main-visible (`0x80041458`) injects authored high-byte palette token into submit flags for type bands `>=0x003e`; special-visible (`0x80041144`) does not inject authored token and only forwards `obj_flags & 0x0002`.
|
||||
- Submitter override gate is explicit in both submitters: override is used only when `(submit_flags & 0xfffffff0) != 0`.
|
||||
- For this world-object path, token `0` behaves as "no override": with only low flag bits present, submitters fall through to default bank CLUT lookup.
|
||||
- `psx_image_table_submit_frame` uses token as a key into `psx_clut_override_table_by_palette_token[token]` when override is active.
|
||||
- `psx_sprite_resource_submit_frame` has two override lanes based on resource format field (`resource+4`):
|
||||
- format `== 2`: token keys `psx_clut_override_table_by_palette_token[token]`.
|
||||
- format `!= 2`: token is used as a row key into `psx_clut_table_by_resource_bank` (`token << 4` halfword index).
|
||||
|
||||
Exporter-facing implication from executable evidence:
|
||||
|
||||
- The current flattening bug matches a real semantic split in executable code: authored token injection is lane-dependent (main-visible only) and CLUT resolution is submitter/resource-format dependent.
|
||||
- A single flattened token->CLUT mapping in exporter code will miscolor mixed cohorts where route lane or submitter/resource format differs.
|
||||
|
||||
Conservative live-artifact updates applied in Ghidra for this pass:
|
||||
|
||||
- `0x800415b0`: comment clarifying main-visible token injection source and band split.
|
||||
- `0x800412d0`: comment clarifying special-visible non-injection behavior.
|
||||
- `0x80044e10`: comment clarifying sprite submit override gate and token-0 fallthrough.
|
||||
- `0x80044eb8`: comment clarifying image-table override keying behavior.
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. Trace the remaining high-volume band `0x0055..0x0063` in Ghidra with the same question used for `0x0042`: why does `DAT_800758d8` stay zero-sized while visible art still exists at runtime?
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue