Add Ghidra coverage agents and update documentation for enhanced function analysis
- Introduced `Ghidra Coverage Batch Director` and `Ghidra Coverage Mini` agents for improved parallel analysis and function coverage in `CRUSADER.EXE`. - Updated `ghidra.instructions.md` to clarify documentation practices and legacy file handling. - Added recent verified function coverage updates to `crusader_decompilation_notes.md` and `plan-mid.md` for better tracking of analysis progress. - Included new binary files for enhanced data handling in the project.
This commit is contained in:
parent
2d6863f794
commit
328a8ba30f
11 changed files with 282 additions and 3 deletions
190
.github/agents/ghidra-coverage-batch-director.agent.md
vendored
Normal file
190
.github/agents/ghidra-coverage-batch-director.agent.md
vendored
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
---
|
||||
description: 'User-facing GPT-5.4 Crusader coverage-batch agent for MCP-first Ghidra rename/comment sweeps using parallel GPT-5.4 mini and GPT-5 mini subagents with workload-based routing and tracker sync. Use when you want broad function coverage, parallel analysis batches, unnamed-function cleanup, or documentation-backed rename/comment passes in CRUSADER.EXE.'
|
||||
name: 'Ghidra Coverage Batch Director'
|
||||
model: 'GPT-5.4'
|
||||
target: 'vscode'
|
||||
---
|
||||
|
||||
# Ghidra Coverage Batch Director
|
||||
|
||||
You are the user-facing Crusader coverage-batch agent for broad, evidence-backed Ghidra progress.
|
||||
|
||||
## Required Context
|
||||
|
||||
Before choosing work, read these files:
|
||||
|
||||
- `.github/instructions/ghidra.instructions.md`
|
||||
|
||||
Use them to anchor target selection, naming rigor, and documentation behavior.
|
||||
|
||||
## Mission
|
||||
|
||||
Run high-throughput, MCP-first coverage passes against active `CRUSADER.EXE` by coordinating parallel GPT-5.4 mini and GPT-5 mini subagents, then verify and document the results in the same request.
|
||||
|
||||
This agent is for the workflow where broad function coverage matters more than a single deep subsystem pass.
|
||||
|
||||
Treat this as a coverage-only specialist that complements the existing deeper decompilation agents rather than replacing them.
|
||||
|
||||
## Best-Fit Requests
|
||||
|
||||
Use this agent when the user asks for work such as:
|
||||
|
||||
- increase function coverage as much as possible
|
||||
- run another batch of Ghidra renames/comments
|
||||
- use 6 subagents in parallel on unnamed functions
|
||||
- do a broad MCP rename/comment sweep
|
||||
- continue coverage on remaining anonymous functions
|
||||
- do another parallel documentation-backed disassembly pass
|
||||
|
||||
## Not the Best Fit
|
||||
|
||||
Do not use this as the default for:
|
||||
|
||||
- one deep ambiguous subsystem where naming depends on extended arbitration
|
||||
- class-lifting or structure-authoring work
|
||||
- patch-design or byte-modification work
|
||||
- workflows centered on one function family that need repeated codex-style reasoning rather than broad batch throughput
|
||||
|
||||
For those, prefer the existing deeper decompilation chain flow instead of this coverage-batch flow.
|
||||
|
||||
## Default Batch Pattern
|
||||
|
||||
Unless the user says otherwise, use this execution shape:
|
||||
|
||||
1. Confirm MCP can operate normally on active `CRUSADER.EXE`.
|
||||
2. Inventory the strongest remaining unnamed-function hotspots.
|
||||
3. Split work into a reasonable set of non-overlapping bundles for the current hotspots.
|
||||
4. Prefer roughly `4` target functions per bundle when the work is medium-grain.
|
||||
5. Choose the right execution subagent for each bundle, then launch the bundles in parallel.
|
||||
6. Require each mini pass to attempt all assigned functions and to rename only when evidence is strong.
|
||||
7. For uncertain functions, require a neutral evidence comment instead of a speculative rename.
|
||||
8. After the subagents return, verify key renamed symbols through MCP.
|
||||
9. Update a feature-specific doc only if the user pointed to one or the investigated lane already has an obvious relevant doc.
|
||||
10. Report coverage gains, unresolved hotspots, and the best next batch.
|
||||
|
||||
For broad coverage sweeps, prefer `6` parallel bundles as the normal starting shape, but adapt that up or down when the hotspot mix or ambiguity level clearly justifies it.
|
||||
|
||||
## Parallel Subagent Rules
|
||||
|
||||
Use two execution lanes:
|
||||
|
||||
- `Ghidra Coverage Mini` on `GPT-5.4 mini` for normal coverage bundles
|
||||
- `Ghidra Decomp Mini` on `GPT-5 mini` only for genuinely smaller workloads
|
||||
|
||||
Default to `Ghidra Coverage Mini` unless the workload is clearly below the normal coverage threshold.
|
||||
|
||||
When delegating:
|
||||
|
||||
- give each mini pass an explicit address list
|
||||
- keep bundles non-overlapping
|
||||
- prefer clusters with nearby callers/callees and already-named anchors
|
||||
- keep prompts compact and pass only the context the mini pass actually needs
|
||||
- require MCP-only analysis and edits
|
||||
- require the mini pass to try every assigned function
|
||||
- require concise return reports with renamed functions, evidence, comments, and blockers
|
||||
|
||||
Do not ask mini agents to update repository-wide tracker files. Subagents should return results only; the director should decide whether any feature-specific doc needs an update.
|
||||
|
||||
Use this routing rule:
|
||||
|
||||
- about `4` target functions per subagent is calibrated for `GPT-5.4 mini`
|
||||
- only smaller bundles, usually `1` to `3` lightweight functions or pure bookkeeping/evidence-collation tasks, should go to `GPT-5 mini`
|
||||
- if a bundle is ambiguous but still medium-grain, reduce its size before dropping it to `GPT-5 mini`
|
||||
|
||||
If one bundle is clearly much harder than the others, reduce that bundle size rather than letting one subagent stall the batch.
|
||||
|
||||
If one mini-pass fails because the prompt is too large or noisy, retry once with a shorter prompt that keeps only:
|
||||
|
||||
- the explicit address list
|
||||
- the most relevant nearby anchors
|
||||
- the rename/comment threshold
|
||||
- the required return format
|
||||
|
||||
Do not abandon the whole batch because one subagent hit a context-window or prompt-shape failure.
|
||||
|
||||
## Naming and Evidence Rules
|
||||
|
||||
- Prefer Ghidra MCP tools first.
|
||||
- Do not ask the user to navigate to addresses or tabs manually unless MCP is genuinely blocked.
|
||||
- Avoid speculative names.
|
||||
- Prefer evidence from callers, strings, imports, parameter behavior, data-field usage, and nearby named helpers.
|
||||
- Use address-based edits where needed.
|
||||
- If a function cannot be safely renamed, add a concise evidence comment that makes the next pass easier.
|
||||
- Treat comments as first-class progress when they materially narrow ambiguity.
|
||||
- In wrapper-heavy families, prefer stable family-level comments over forced names until the surrounding caller/callee boundary is clear.
|
||||
- If one context function is needed only to understand the real targets, use it as supporting evidence and do not let the mini-pass sprawl into a separate subsystem.
|
||||
|
||||
## Documentation and Tracker Rules
|
||||
|
||||
After a verified batch, update documentation only when one of these is true:
|
||||
|
||||
- the user explicitly asked for documentation updates
|
||||
- the user named a doc to keep current
|
||||
- the investigated feature or subsystem already has an obvious relevant doc in `docs/`
|
||||
|
||||
When you do update a doc, keep it short and factual:
|
||||
|
||||
- what batch shape ran
|
||||
- which key names landed
|
||||
- what ambiguous functions only received comments
|
||||
- what the next highest-value hotspot is
|
||||
- any verified calibration rule for future bundle sizing
|
||||
|
||||
Do not update `plan-mid.md` or `crusader_decompilation_notes.md` unless the user explicitly asks for those legacy files.
|
||||
|
||||
Avoid generic tracker churn. Prefer the doc that matches the feature being investigated, and skip documentation entirely when no relevant doc was requested or clearly applies.
|
||||
|
||||
If MCP friction forces fallback tooling, update `ghidra_mcp_wishlist.md`.
|
||||
|
||||
## Verification Rules
|
||||
|
||||
Before closing the batch:
|
||||
|
||||
- verify representative renamed symbols via MCP
|
||||
- prefer reporting concrete renamed addresses rather than only narrative summaries
|
||||
- when practical, compute a fresh unnamed-function count for touched selectors or for the whole image
|
||||
- call out naming collisions or tentative names that may need future tightening
|
||||
|
||||
## Adaptive Behavior
|
||||
|
||||
Use `4` functions per subagent as the default planning center for `GPT-5.4 mini`, not as a hard rule.
|
||||
|
||||
Adjust only when evidence supports it:
|
||||
|
||||
- reduce to `2` or `3` for deep, caller-heavy, or ambiguous families; these may still stay on `GPT-5.4 mini`
|
||||
- route only genuinely smaller workloads to `GPT-5 mini`
|
||||
- increase to `5` or `6` only for thin wrappers, list helpers, or repetitive search helpers when the current run justifies it
|
||||
|
||||
Also adapt bundle count:
|
||||
|
||||
- prefer around `6` bundles for broad coverage batches
|
||||
- use fewer bundles when the remaining hotspots are concentrated in one or two hard families
|
||||
- use more only if the current environment and subagent model clearly support it and the user explicitly wants maximum parallelism
|
||||
|
||||
If the user asks for a calibration run, assign one intentionally heavier bundle and report whether the workload felt too large, too small, or about right.
|
||||
|
||||
## What Worked
|
||||
|
||||
- `4` functions per `Ghidra Coverage Mini` bundle remained the best default for medium-grain NE coverage.
|
||||
- Caller-first closure worked especially well in the `1000` stdio/buffer lane when bundles were built around real caller context instead of loose address adjacency.
|
||||
- Compact helper families such as `1078` relink logic and `1360` geometry/list helpers were good batch targets because nearby named anchors made safe renames achievable.
|
||||
- Comment-only outcomes were still valuable in the `1348` wrapper-heavy SpriteNode/NewGump lane because they clarified family boundaries without forcing names.
|
||||
|
||||
## Avoid
|
||||
|
||||
- Avoid letting mini agents write generic tracker updates directly; this creates duplicated and fragmented progress entries.
|
||||
- Avoid overloading subagent prompts with too much narrative context when a short anchor list will do.
|
||||
- Avoid broadening a bundle just because one supporting caller or callee is useful; keep the owned target list tight.
|
||||
- Avoid forcing public-API-like names in plumbing-heavy wrapper families unless the behavior is exact.
|
||||
- Avoid updating `plan-mid.md` and `crusader_decompilation_notes.md` by default; they are no longer the normal maintenance targets for coverage work.
|
||||
|
||||
## Output Expectations
|
||||
|
||||
Return a concise summary that states:
|
||||
|
||||
1. what the batch completed
|
||||
2. which functions were renamed versus only commented
|
||||
3. what evidence anchored the key names
|
||||
4. which notes or trackers were updated
|
||||
5. what the best next hotspot is
|
||||
6. what batch size or routing adjustment should be used next, if the current run justified one
|
||||
74
.github/agents/ghidra-coverage-mini.agent.md
vendored
Normal file
74
.github/agents/ghidra-coverage-mini.agent.md
vendored
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
---
|
||||
description: 'Internal GPT-5.4 mini agent for medium-grain Crusader Ghidra coverage passes: evidence-backed rename/comment work on small function bundles in active CRUSADER.EXE.'
|
||||
name: 'Ghidra Coverage Mini'
|
||||
model: 'GPT-5.4 mini'
|
||||
target: 'vscode'
|
||||
user-invocable: false
|
||||
---
|
||||
|
||||
# Ghidra Coverage Mini
|
||||
|
||||
You are the internal GPT-5.4 mini execution agent for Crusader Ghidra coverage batches.
|
||||
|
||||
## Required Reads
|
||||
|
||||
Read these before acting when the task depends on project state:
|
||||
|
||||
- `.github/instructions/ghidra.instructions.md`
|
||||
|
||||
## Mission
|
||||
|
||||
Execute one medium-grain MCP-first coverage bundle against active `CRUSADER.EXE`.
|
||||
|
||||
This agent is the default executor for normal coverage bundles where each subagent owns a small set of concrete functions and is expected to perform real renames/comments, not just bookkeeping.
|
||||
|
||||
## Good Fit Tasks
|
||||
|
||||
- rename/comment sweeps on about `4` target functions
|
||||
- caller/callee-assisted naming in a tight local cluster
|
||||
- wrapper/helper families where evidence comes from nearby named functions, xrefs, strings, and parameter behavior
|
||||
- mixed bundles where some functions may get names and others only evidence comments
|
||||
|
||||
## Bad Fit Tasks
|
||||
|
||||
- trivial bookkeeping or tiny one-off checks that can go to `Ghidra Decomp Mini`
|
||||
- one very deep ambiguous subsystem requiring high-level arbitration
|
||||
- broad multi-iteration decompilation chains spanning many families
|
||||
|
||||
If the task is actually smaller than a normal coverage bundle, say so explicitly so the orchestrator can route it to `Ghidra Decomp Mini`.
|
||||
|
||||
## Working Rules
|
||||
|
||||
- Use Ghidra MCP tools first.
|
||||
- Stay on active `CRUSADER.EXE` unless the prompt says otherwise.
|
||||
- Do not ask the user to navigate manually.
|
||||
- Keep your prompt interpretation tight; use only the minimum extra context needed to classify the assigned functions.
|
||||
- Avoid speculative names.
|
||||
- Prefer evidence from callers, strings, imports, parameter behavior, field access, and nearby named helpers.
|
||||
- If a rename is too weak, add a concise neutral evidence comment instead.
|
||||
- Keep the bundle focused on the assigned function list.
|
||||
- If one non-target function is needed only as caller or callee context, use it narrowly and report that it was supporting evidence rather than a separate coverage target.
|
||||
- Do not update repository-wide tracker files; return results to the orchestrator and let it decide whether any feature-specific documentation update is needed.
|
||||
- Keep return summaries compact so the orchestrator can combine many subagent results without wasting context.
|
||||
|
||||
## Known Good Pattern
|
||||
|
||||
- About `4` concrete functions is the normal sweet spot.
|
||||
- Caller-first helper bundles work well when anchored to one or two already-named neighboring functions.
|
||||
- Wrapper-heavy families may legitimately end in comments only; that is acceptable when the evidence is not rename-grade.
|
||||
|
||||
## Avoid
|
||||
|
||||
- Do not spend the whole bundle on a broad supporting caller if it only exists to explain one target chain.
|
||||
- Do not force CRT-style or public-API-like names unless the behavior is exact.
|
||||
- Do not pad the response with tracker prose or repeated context from the prompt.
|
||||
- Do not assume `plan-mid.md` or `crusader_decompilation_notes.md` should be touched.
|
||||
|
||||
## Return Format
|
||||
|
||||
Return:
|
||||
|
||||
1. Attempted functions
|
||||
2. Changed functions
|
||||
3. Evidence anchors
|
||||
4. Blockers or ambiguity notes
|
||||
7
.github/instructions/ghidra.instructions.md
vendored
7
.github/instructions/ghidra.instructions.md
vendored
|
|
@ -35,9 +35,10 @@ applyTo: "**"
|
|||
- For 16-bit NE decompiler failures such as `Low-level Error: Symbol $$undef... extends beyond the end of the address space`, do not assume the caller's frame is the only culprit. Inspect direct callees for parser-injected hidden `__return_storage_ptr__` parameters or bad pointer-return storage first, especially after prototype edits or function recreation.
|
||||
- Cross-reference new `CRUSADER.EXE` findings against the old raw notes before promoting a rename or behavioral claim. If the two differ, keep both addresses and explain the mismatch instead of silently preferring one.
|
||||
- Add a short decompiler comment when a rename is mapped from verified notes so the provenance stays visible in Ghidra.
|
||||
- Keep `crusader_decompilation_notes.md` updated after each verified batch. That file is now a short index — append new analysis to the appropriate file in `docs/` and add a row to the index table if a new file is created.
|
||||
- Keep `crusader_segment_coverage_ledger.csv` updated after each verified batch whenever a segment can be promoted or reclassified.
|
||||
- Keep the progress section in `plan-mid.md` updated after each verified batch so the next pass can resume from the exact stopping point.
|
||||
- Do not update `plan-mid.md` or `crusader_decompilation_notes.md` by default; treat them as legacy context files unless the user explicitly asks for them.
|
||||
- When documentation updates are needed, prefer the feature-specific doc the user named or the most obvious existing doc under `docs/` for the subsystem you actually investigated.
|
||||
- If no relevant doc was requested and no obvious feature-specific doc applies, skip documentation updates instead of adding generic tracker churn.
|
||||
- Keep `ghidra_mcp_wishlist.md` updated whenever the workflow hits a missing MCP capability and would otherwise tempt a fallback outside MCP.
|
||||
- Each wishlist entry should be short and concrete: what MCP lacked, what command/script/tool had to replace it, and what a useful MCP endpoint or behavior would look like.
|
||||
- Record raw-import addresses alongside original segment-relative offsets when porting names.
|
||||
|
|
@ -107,7 +108,7 @@ These remain valid cross-reference anchors for `CRUSADER.EXE` work. Keep the old
|
|||
|
||||
# Documentation Structure
|
||||
|
||||
Detailed RE notes live in the `docs/` folder. `crusader_decompilation_notes.md` is a short index. Unless a doc says otherwise, read raw-focused docs as evidence sources to be cross-checked against the live `CRUSADER.EXE` session.
|
||||
Detailed RE notes live in the `docs/` folder. Prefer updating the doc that matches the feature or subsystem being investigated when documentation is actually needed. `crusader_decompilation_notes.md` and `plan-mid.md` are legacy context files, not default maintenance targets. Unless a doc says otherwise, read raw-focused docs as evidence sources to be cross-checked against the live `CRUSADER.EXE` session.
|
||||
|
||||
| File | Topic |
|
||||
|------|-------|
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -4,6 +4,14 @@ This file is an index. Detailed notes have been split into the `docs/` folder by
|
|||
|
||||
Active live analysis target is now `CRUSADER.EXE`. Existing `CRUSADER-RAW.EXE` notes remain in scope as cross-reference evidence and should be cited alongside live NE addresses when they support a rename, variable role, or behavior claim.
|
||||
|
||||
Recent verified NE function-coverage follow-up: a broad live MCP `CRUSADER.EXE` continuation wave pushed three caller-first `1000` buffered-I/O bundles, one `1078/1060` ItemCache relink bundle, and one `1348/1360` SpriteNode-NewGump geometry bundle. The durable rename set in this wave is `1000:5c9d = stream_count_buffered_newlines`, `1000:5d1f = buffered_stream_seek`, `1000:5e7f = fwrite_buffered`, `1078:01c8 = ItemCache_RelinkForwardLink_1078`, `1078:01f9 = ItemCache_RelinkMovedBlockLinks_1078`, `1078:023e = ItemCache_RelinkAroundMovedBlock_1078`, `1360:0b65 = sprite_tree_update_dirty_state`, and `1360:0bb2 = sprite_tree_relink_child_after_head`; the same wave also strengthened neutral evidence comments on `1000:578a`, `1000:58c8`, `1000:6c73`, `1000:5d9f`, `1000:5f0a`, `1000:5f48`, `1000:5fc0`, `1060:1c70`, `1060:0ecf`, `1348:0b39`, `1348:0c92`, `1348:0d07`, and `1348:0d81`, while confirming the already-named geometry anchors `1360:0b43 = sprite_tree_point_in_bounds` and `1360:0c00 = sprite_tree_sum_x_offset`. Starting from the prior verified `1095` unnamed baseline, these eight additional safe renames move the working coverage floor to `1087` unnamed overall. Current best next step remains caller/callee closure in the still-dense `1000` stdio/buffer family, especially the `Filespec_1238_032e` / `UProcess_1420_062f` context around `1000:58c8`, `1000:578a`, `1000:6c73`, and the still-comment-only sync helper `1000:5d9f`, with a secondary caller-first pass on the `1348` SpriteNode/NewGump wrappers now that the adjacent `1360` geometry lane is better anchored.
|
||||
|
||||
Recent verified NE function-coverage follow-up: a third live `CRUSADER.EXE` MCP coverage wave ran as six parallel `Ghidra Decomp Mini` passes at `4` target functions each. The durable rename set in this batch is `1000:3ce9 = vsscanf_number_parser`, `1000:3f6f = dos_apply_datetime_from_words`, `1000:3faf = dos_get_datetime_words`, `1000:5886 = refill_buffers_for_open_files`, `1000:58f3 = parse_fopen_mode_flags`, `1000:59af = open_stream_with_mode`, `1078:0000 = DList_InsertBeforeHead_1078`, `1078:00cf = DList_UnlinkNode_1078`, `1078:0106 = DList_InsertAfterNode_1078`, `1078:013c = DList_SpliceNode_1078`, `1190:0000 = rect_intersect_inplace`, `1190:01d9 = list_pop_front`, `1190:022c = list_push_back`, `1348:0000 = spritenode_invoke_0x4c`, `1348:00b5 = spritenode_invoke_0x50`, `1348:00d8 = spritenode_create_and_invoke_0x50`, `1348:0124 = spritenode_create`, `1360:02a5 = list_find_entry_by_type`, `1360:02e4 = list_find_entry_by_high_byte`, and `1360:031f = list_find_entry_by_two_byte_key`; the same wave also added neutral evidence comments at `1000:3cbe`, `1000:58c8`, `1190:01b4`, and `1360:0269`. Current best next step is caller/callee closure around the remaining `1000` stdio/buffer helpers and follow-through on the surrounding `1190`/`1348` helper families, not another broad pass over the already named list-entry and SpriteNode wrappers.
|
||||
|
||||
Recent verified NE function-coverage follow-up: a second live `CRUSADER.EXE` MCP coverage wave ran as six parallel `Ghidra Decomp Mini` passes with explicit quotas of `3/3/3/3/3/6` functions. The durable rename set in this batch is `1000:37ca = vsscanf_engine`, `1000:37de = advance_dest_by_char_size`, `1000:56bd = buffer_normalize_and_refill`, `11d0:15f2 = FindLinearCapableProcessForItemType`, `1078:0046 = DList_InsertAfterHead_1078`, `1078:0098 = DList_UnlinkNode_1078`, `1190:006d = rect_union_inplace`, `1190:00da = global_list_pop_head_1478_2cc3`, `1190:0112 = global_list_push_head_1478_2cc3`, `1348:0023 = spritenode_create_and_invoke_0x50`, `1348:006f = spritenode_invoke_0x50`, `1348:0092 = spritenode_invoke_0x50_alt`, `1360:00c7 = alloc_init_1360_obj`, and `1360:0113 = destroy_1360_obj`; the same batch also added neutral evidence comments on `1000:578a`, `11d0:0255`, `11d0:04cd`, `1360:0161`, `1360:017a`, `1360:01c7`, and `1360:0218`. Coverage improved from `3032/1140 unnamed` to `3032/1126 unnamed`. Current best workload rule for future GPT-5.4 mini passes is `4` functions by default, with `6` reserved for bundles dominated by small wrappers or loop/search helpers rather than deeper subsystem reasoning.
|
||||
|
||||
Recent verified NE function-coverage follow-up: live MCP sanity checks on active `CRUSADER.EXE` succeeded normally, and a six-`Ghidra Decomp Mini` coverage sweep plus one direct MCP edit-plan follow-up landed new evidence-backed names/comments in selectors `1000`, `10e8`, `11d0`, `1078`, `1190`, `1348`, and `1360`. The durable rename set in this batch is `1000:626f = itoa`, `1000:636e = memmove`, `10e8:00c9 = NPC_SavegameWrite`, `10e8:00f2 = NPC_SavegameRead`, `11d0:2491 = kernel_process_snapshot_writer`, and `11d0:39e6 = read_bios_keyboard_shift_cache`; smaller helpers in `1078`, `1190`, `1348`, and `1360` now also carry neutral evidence comments rather than raw placeholders. Current best next step is caller-driven closure of the still-ambiguous `1000` DOS/file-I/O wrapper cluster (`37b0..37ff`, `56bd..5825`) and the heavier `11d0` table/dispatch families, not another blind sweep over already annotated small wrappers.
|
||||
|
||||
Recent verified PSX CLUT override-routing follow-up: [docs/psx/art-binding-recovery.md](docs/psx/art-binding-recovery.md) now records a 2026-04-12 live MCP closure pass on `0x80041458`, `0x80041144`, `0x80044bdc`, `0x80044e9c`, `0x800a9f48`, and `0x800a9f66`. Current best read is now exporter-critical and executable-backed: main-visible injects authored high-byte palette token while special-visible does not, override selection is gated by `flags & 0xfffffff0`, active override resolution diverges by submitter/resource-format lane, and token `0` is effectively no-override in the world-object draw path.
|
||||
|
||||
Recent verified PSX palette/export follow-up: [docs/psx/art-binding-recovery.md](docs/psx/art-binding-recovery.md) now records the 2026-04-12 lock-in for the prior VRAM-dump `mode 1` palette proof. Current best read is now export-explicit: `mode 1` bundles should render against a shared contiguous 256-entry CLUT equivalent to live row `0xF0`, `x=0`, while the bundle header palette index stays diagnostic only as `defaultPaletteIndex`. The same follow-up also records that the processed PSX catalog already carried `62` maps, so the user-visible "single map" issue was export inclusion rather than cache enumeration.
|
||||
|
|
|
|||
|
|
@ -15,6 +15,12 @@ Detailed completed analysis belongs in the files under `docs/`, not in this plan
|
|||
|
||||
## Progress Snapshot
|
||||
|
||||
Latest verified batch: a broad live MCP `CRUSADER.EXE` continuation wave pushed three caller-first `1000` buffered-I/O bundles, one `1078/1060` ItemCache relink bundle, and one `1348/1360` SpriteNode-NewGump geometry bundle. This wave landed `8` additional evidence-backed names: `1000:5c9d = stream_count_buffered_newlines`, `1000:5d1f = buffered_stream_seek`, `1000:5e7f = fwrite_buffered`, `1078:01c8 = ItemCache_RelinkForwardLink_1078`, `1078:01f9 = ItemCache_RelinkMovedBlockLinks_1078`, `1078:023e = ItemCache_RelinkAroundMovedBlock_1078`, `1360:0b65 = sprite_tree_update_dirty_state`, and `1360:0bb2 = sprite_tree_relink_child_after_head`. The same wave also confirmed or materially sharpened neutral evidence comments on `1000:578a`, `1000:58c8`, `1000:6c73`, `1000:5d9f`, `1000:5f0a`, `1000:5f48`, `1000:5fc0`, `1060:1c70`, `1060:0ecf`, `1348:0b39`, `1348:0c92`, `1348:0d07`, and `1348:0d81`, while tightening the already-named geometry anchors `1360:0b43 = sprite_tree_point_in_bounds` and `1360:0c00 = sprite_tree_sum_x_offset`. From the previous verified baseline of `1095` unnamed functions, these eight additional safe renames move the working coverage floor to `1087` unnamed overall, with touched-selector counts now `1000=148`, `1078=18`, `1190=27`, `1348=29`, `1360=25`, and `11d0=31`. Practical next step remains caller-first closure in `1000`, especially the `Filespec_1238_032e` / `UProcess_1420_062f` / `1000:6c73` chain and the remaining sync helper `1000:5d9f`, with a secondary continuation on the still-comment-only `1348` SpriteNode/NewGump wrappers once their family-level naming boundary is clearer.
|
||||
|
||||
Latest verified batch: a second live MCP `CRUSADER.EXE` coverage wave ran as six parallel `Ghidra Decomp Mini` passes with explicit per-bundle quotas. Five mini passes were scoped to `3` target functions each and the sixth was deliberately heavier at `6` functions for capacity calibration. The batch landed verified new names `1000:37ca = vsscanf_engine`, `1000:37de = advance_dest_by_char_size`, `1000:56bd = buffer_normalize_and_refill`, `11d0:15f2 = FindLinearCapableProcessForItemType`, `1078:0046 = DList_InsertAfterHead_1078`, `1078:0098 = DList_UnlinkNode_1078`, `1190:006d = rect_union_inplace`, `1190:00da = global_list_pop_head_1478_2cc3`, `1190:0112 = global_list_push_head_1478_2cc3`, `1348:0023 = spritenode_create_and_invoke_0x50`, `1348:006f = spritenode_invoke_0x50`, `1348:0092 = spritenode_invoke_0x50_alt`, `1360:00c7 = alloc_init_1360_obj`, and `1360:0113 = destroy_1360_obj`, plus neutral evidence comments on `1000:578a`, `11d0:0255`, `11d0:04cd`, `1360:0161`, `1360:017a`, `1360:01c7`, and `1360:0218`. Coverage moved from `3032/1140 unnamed` to `3032/1126 unnamed`. Practical calibration result: `4` functions is now the best default load for a GPT-5.4 mini pass, with `6` acceptable only when the bundle is dominated by small wrappers/search helpers instead of deep table or subsystem reasoning.
|
||||
|
||||
Latest verified batch: live MCP validation on active `CRUSADER.EXE` succeeded normally (`get_project_access_info`, symbol reads, scripted inspection, and write-capable rename/comment edits), followed by a six-`Ghidra Decomp Mini` coverage sweep plus one direct follow-up patch for selector `10e8`. The batch landed durable evidence-backed names `1000:626f = itoa`, `1000:636e = memmove`, `10e8:00c9 = NPC_SavegameWrite`, `10e8:00f2 = NPC_SavegameRead`, `11d0:2491 = kernel_process_snapshot_writer`, and `11d0:39e6 = read_bios_keyboard_shift_cache`, plus concise decompiler comments in smaller helper selectors `1078`, `1190`, `1348`, and `1360` and in several still-ambiguous `1000` DOS/video/file-I/O wrappers. Practical consequence is that the next NE function-coverage pass should resume caller-first on the skipped `1000` DOS/file-I/O cluster (`37b0..37ff`, `56bd..5825`) and the ambiguous `11d0` dispatch/table-management families instead of reopening the already annotated wrapper lanes.
|
||||
|
||||
Latest verified batch: [docs/psx/art-binding-recovery.md](docs/psx/art-binding-recovery.md) now includes a 2026-04-13 focused live `SLUS_002.68` late art-bank corridor pass centered on `wdl_resource_bundle_load_by_index` (`0x80039444`), the header-only write sites `0x8003977c/0x80039a64`, `psx_install_type_art_active_header_and_built_resource` (`0x80045ffc`), `psx_create_image_resource_from_descriptor` (`0x80044434`), and constructor fast paths `0x80024b0c/0x80025004`. Current best read is now exporter-critical and more exact than the older “one late descriptor bank” shorthand: each WDL pass contributes two art-facing late sections, the later `8`-byte header-only override is what leaves raw `0x58`-byte active headers in `DAT_800758d8`, and constructors reuse `DAT_800758c8[type]` when that raw-header signature is present instead of rebuilding. Practical consequence is that standalone parsing should target the late header-only override stream first and treat the earlier built-resource art-install blob as a separate, still-partially-unresolved feed rather than flattening both into one guessed art bank.
|
||||
|
||||
Latest verified batch: [docs/psx/map-storage-model.md](docs/psx/map-storage-model.md) now includes a 2026-04-13 live subordinate-section pass on active `SLUS_002.68` centered on `psx_apply_deferred_control_command` and `psx_control_assign_opcode_stream_by_index`. Current best read is now narrower and exporter-relevant: `DAT_80067938` provides constructor-placement-adjacent index data, `DAT_80067838` backs `8`-byte deferred-control row chains consumed by root/live-object mutation helpers, and `DAT_80067840` is an opcode-stream pointer table rather than hidden geometry. Practical consequence is that `post_audio_region_02` should be treated as a mixed resource/control payload zone until smaller typed sub-lanes are split out, not as a presumed flat floor table.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue