Most map sections never showed a Location Preview because the preview artwork and the region-map GUIDE text were hand-authored placeholders: only a handful of sections had art and none of it came from the ROM. Read the real tables out of the dump instead. Extraction (new): - src/import/gba/region_map_tables.lua locates and validates sMapPreviewScreenData. The pinned offset from versions.lua is tried first and a bounded +/-0x8000 scan is only a guard. Validation is structural (mapsec in 88..196, type 0/1, three in-range ROM pointers, and the shipped invariant that the palette block is the first 0x40 bytes of the tile block) so all 28 entries must hold. - src/import/gba/map_preview_extract.lua bakes 21 deduplicated 240x160 RGBA artworks (28 entries reuse art: Pattern Bush and the six Tanoby chambers), 109 mapsec names verified against sRegionMapSectionIdToName, and the 19 sDungeonInfo entries. Palette banks 13/14; bank-0 tilemap refs only occur in off-screen padding columns. - src/import/gba/bg_bake.lua holds the shared 4bpp BG baking helpers; berry_pouch_extract.lua is refactored onto them (-94 lines). Runtime: - src/ui/game3/map_preview_screen.lua ports Task_RunMapPreviewScreenForest: 120-frame first-visit hold, 40-frame revisit, 48-frame fade-out, artwork and name window composited into one canvas so they fade together. Only MPS_TYPE_FOREST (8 sections) takes over the screen; the 20 MPS_TYPE_CAVE sections only change the warp fade colour, matching pret. - src/core/game3/map.lua gives a changed section with a forest preview precedence over the map name popup (overworld.c state 12). - src/core/game3/warp.lua routes every fade through warpFadeModes, applying WarpFadeOutScreen/WarpFadeInScreen: a section change into a cave-preview map forces FADE_TO_BLACK, otherwise MapTransitionIsEnter/ IsExit decide white vs black on MAP_TYPE_UNDERGROUND. - setworldmapflag feeds the transient visit flag; the HUD ticks and dismisses the screen; the dataset installs the cache on hydrate. - region_map.lua's GUIDE panel uses the retail geometry, tint ramp and delayed text, and ROM names/dungeon text overlay the hand-authored fallbacks via ensureGenerated(). Two retail quirks are tolerated: MPS_ROCKET_WAREHOUSE and Berry Forest share flagId 2231 (as do the six Tanoby chambers), and the Tanoby mapsec is spelled MAPSEC_DILFORD_CHAMBER. CACHE_VERSION 99 -> 100. Verified: tests/game3_map_preview_extract_test.lua (new; ROM-gated, all 28 entries, 8 forest / 20 cave, 21 artworks, 109 names, 19 dungeons, the shared flag, Pattern Bush art reuse), tests/game3_town_map_test.lua, tests/run_engine.lua 587/587, scripts/test.sh --quick all tiers, luacheck src 0 warnings / 0 errors. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
5.1 KiB
Location Previews
Entering a FireRed map section that owns a preview now shows the retail full-screen artwork and location-name window during the warp transition, and the Town Map GUIDE panel shows the retail artwork and flavour text instead of the hand-authored placeholders. Before this, only a handful of sections had art, and none of it came from the ROM.
What the ROM provides
src/import/gba/map_preview_extract.lua reads two tables straight from the
user's dump and bakes them into the cache:
| Table | Source | Contents |
|---|---|---|
sMapPreviewScreenData |
src/map_preview_screen.c |
28 entries: mapsec, type, flagId, tilesptr, tilemapptr, palptr |
sMapsecName_* |
src/region_map.c |
109 display names for mapsec 88..196 |
sDungeonInfo |
src/region_map.c |
19 dungeon GUIDE entries: name + pre-wrapped flavour text |
src/import/gba/region_map_tables.lua locates sMapPreviewScreenData by
validating the pinned offset from versions.lua and only then falling back to a
bounded ±0x8000 scan. Validation is structural, not a magic byte match: every
one of the 28 entries must have a mapsec in range, a type of 0 or 1, three
in-range ROM pointers, and satisfy the shipped invariant that the palette block
is physically the first 0x40 bytes of the tile block.
Artwork is deduplicated by its tiles:tilemap:palette key, so 28 entries bake
21 images. Pattern Bush and the six Tanoby chambers reuse another section's art,
exactly as the retail table does. Each image is 240×160 RGBA at 4bpp using
palette banks 13 and 14.
src/import/gba/bg_bake.lua holds the shared 4bpp BG baking helpers
(bgr555ToRgb8, decodeTile4bpp, loadPalBanks, bakeBgRgba); the Berry Pouch
extractor was refactored onto them.
Cache files
<root>/map_preview/manifest.lua entries, by_mapsec index, name-window colours
<root>/map_preview/<mapsec>.rgba 240x160 RGBA artwork, deduplicated
<root>/region_map/names.lua mapsec 88..196 display names
<root>/region_map/dungeon_info.lua sDungeonInfo name + flavour text
versions.lua CACHE_VERSION is bumped when any of these change shape.
Two ROM quirks the importer tolerates
MPS_ROCKET_WAREHOUSE(mapsec 178) and Berry Forest (mapsec 176) shareflagId = 2231, so the first one the player visits marks both as seen. The six Tanoby chambers likewise share one flag. This is retail behaviour.- The Tanoby chamber mapsec is spelled
MAPSEC_DILFORD_CHAMBER(notDILFORD) in the name table.
Runtime behaviour
src/ui/game3/map_preview_screen.lua ports Task_RunMapPreviewScreenForest.
Only MPS_TYPE_FOREST sections (8 of them) take over the screen; the other 20
are MPS_TYPE_CAVE and only change the warp fade colour. The artwork and the
name window are composited into one canvas so they fade out together, matching
the retail BG0/BLDALPHA blend.
- Hold: 120 frames on a first visit, 40 on a revisit. Caves key off their own
world-map flag; forests key off the transient
sHasVisitedMapBeforeglobal thatScrCmd_setworldmapflagrefreshes (MapPreviewScreen.setVisitedFlagcaptures the pre-visit state). - Fade-out: 48 frames.
Wiring:
src/core/game3/map.lua— a changed section with a forest preview wins over the map-name popup (mirrorsoverworld.cstate 12). Suppressed for seamless warps.src/core/game3/gfx.lua— a running preview suppressesMapNamePopup.src/core/game3/warp.lua—warpFadeModesappliesWarpFadeOutScreen/WarpFadeInScreen: a section change into a cave-preview map forcesFADE_TO_BLACK, otherwiseMapTransitionIsEnter/IsExitdecide white-vs-black usingMAP_TYPE_UNDERGROUND.src/core/game3/scripting/ops_a.lua—setworldmapflagfeeds the visit flag.src/ui/game3/hud.lua— ticks and dismisses the screen on menu open.src/core/game3/dataset.lua— installs the cache during hydrate.src/ui/game3/region_map.lua— GUIDE panel geometry, tint ramp and delayed text now follow the retail timings; ROM names and dungeon text overlay the hand-authoredmap_sections_extract.SECTIONS/region_map_extractfallbacks viaensureGenerated().
Verification
Run from the project root:
luajit tests/game3_map_preview_extract_test.lua
luajit tests/game3_town_map_test.lua
luajit tests/run_engine.lua
luacheck src -q --codes --only 0 1 511
tests/game3_map_preview_extract_test.lua covers the pinned offsets, the
BGR555→RGB8 conversion, the manifest/screen logic against a synthetic cache
(so it runs without a ROM), and — when a FireRed dump is present at the repo
root — the full extraction: 28 entries, 8 forest / 20 cave, 21 deduplicated
240×160×4 artworks, 109 verified mapsec names, 19 dungeon entries, the shared
2231 flag, and Pattern Bush reusing Viridian Forest's artwork.
The tests/game3_* suites are run manually; they are not wired into a CI
workflow. Extraction was additionally checked against a real FireRed 1.0 dump
(all 28 entries and 109 names decode, sMapsecName_* pointers match
sRegionMapSectionIdToName). Timing was reasoned against pret source; no
in-game visual capture has been performed.