Porting Test Drive II from SNES to PC, Part 20: Closing the 1102..1117 late attract continuation
The previous checkpoint split the late attract continuation after frame 1093 into real behavior windows.
That was useful, but it still left one important question open:
was the 00:8029 tail still changing internally in ways that explained the renderer gap, or was it already one stable surface with one remaining bug?
This checkpoint answers that more cleanly.
What changed in the pipeline
Two small tooling changes mattered here:
- the visual-contract builders can now merge a normalized activity trace directly
- the compare rubric for these late windows is now a dedicated reusable builder instead of a pile of one-off commands
The new helper is:
tools/build_mesen_window_compare.py
That matters because the late attract lane can now line up three things in one pass:
- visible surface
- callback and activity shape
- renderer mismatch
The bounded run
I kept the run exactly on the 00:8029 continuation:
1102..1117
The promoted commands were:
python3 tools/build_mesen_visual_contract_range.py \
tools/out/design_mesen_range_1102_1109_v1 \
tools/out/visual_contract_range_1102_1109_activity \
--provenance-json rom_analysis/maps/tilemaps/mesen_range_1102_1109_provenance.jsonc \
--probe-json tools/out/activity_trace_1094_1117/td2_boot_probe.json \
--activity-trace-json tools/out/activity_trace_1094_1117/activity_trace.json \
--clean-out
python3 tools/build_mesen_visual_contract_range.py \
tools/out/design_mesen_range_1110_1117_v1 \
tools/out/visual_contract_range_1110_1117_activity \
--provenance-json rom_analysis/maps/tilemaps/mesen_range_1110_1117_provenance.jsonc \
--probe-json tools/out/activity_trace_1094_1117/td2_boot_probe.json \
--activity-trace-json tools/out/activity_trace_1094_1117/activity_trace.json \
--clean-out
python3 tools/build_mesen_window_compare.py \
tools/out/post_1093_compare_1102_1117/summary.json \
tools/out/mesen_range_1102_1109_v1 \
tools/out/mesen_range_1110_1117_v1 \
--activity-trace-json tools/out/activity_trace_1094_1117/activity_trace.json \
--markdown-out tools/out/post_1093_compare_1102_1117/summary.md
What the window looks like now
Across the whole 1102..1117 block, the visible presentation surface stays flat:
bgMode = 7- main screen layer:
bg1 - visible sprites:
61 - main callback:
00:8029
That is already useful.
The callback handoff at 1102 is real, but it is not a visible-surface handoff.
What still changes internally
The normalized activity trace still finds one internal boundary:
-
1102..1113: one per-frameOAMDMA -
1114..1117: noOAMDMA
But the rest of the shape stays flat:
- no direct
VRAM/CGRAMwrites - same
Mode 7event count - same
Mode 7write count
So the 1114 boundary is narrower than it first looked.
It is an OAM DMA shutdown, not a larger ownership or state fork.
What the compare summary proved
The export-surface explanation from the previous block survives intact:
-
main_visible.ppmis still the top224lines ofmain.ppm - not a different scene export
That holds for every frame 1102..1117.
The more interesting result is the renderer side.
Base render vs main_visible.ppm:
-
1102:838mismatched pixels -
1103:1061 -
1104:1798 -
1105..1117:2698
Visible-state render vs main_visible.ppm:
-
1102:6082 -
1103:5958 -
1104:6292 -
1105..1117:2698
That means the old visible-state substitution problem only survives for:
1102..1104
By 1105, the base and visible-state Mode 7 coefficients already agree.
And from there on, the remaining gap is just one stable plateau:
-
2698mismatched pixels
Why this checkpoint matters
This is the important change in reading:
before this checkpoint, the 00:8029 tail still looked like it might hide another ownership or upload transition.
After this checkpoint, the sharper reading is:
- the whole tail is one stable surface
- the
1114OAM DMAshutdown is real but not causal for the compare gap - the visible-state
Mode 7disagreement is already gone by1105 - the remaining problem is one stable renderer/composition plateau shared by
1105..1117
That is much better than "something still changes later."
Now the next step is narrower and more honest:
find the composition semantics behind that stable 2698-pixel plateau, instead of chasing more hidden uploads or callback forks.
Top comments (0)