game3 prints every string with the US cart's Latin font, and FrlgFont has
no glyph for a kana, so a Japanese translation of FireRed would print
blank. The US cart still carries its Japanese fonts, which its text
printer draws for a string in Japanese mode (pokefirered/src/text.c:141,
:227): pret builds them into the US ROM, with the normal font's width
table.
The font extractor now bakes both, the normal font from its eight-to-a-row
layout (DecompressGlyph_Normal, text.c:1452) with its widths and the small
one sixteen to a row (DecompressGlyph_Small, text.c:1372), as
chrome/fonts/japanese_{normal,small}_{fg,shadow}.rgba and
japanese_widths.lua. LeafGreen's addresses follow the same -0x24 shift as
the rest of text.o. Cache version 120 re-imports existing caches.
FrlgFont numbers a Japanese character by its byte in the Japanese block of
pokefirered/charmap.txt (kana 01-A0, the full-width space, !?。ー), plus
the symbols the font keeps at the Latin block's codes in their full-width
forms (digits, letters, 『』「」, 円, /, :), offset past the Latin
glyphs. A character with no Latin glyph draws from the Japanese sheet, at
the width the cart gives it (the table for the normal font, 8px for the
small one). Latin text is drawn as before.
The party, the PC boxes and the release animation drew an egg with the icon
of the species it will hatch into, so a Pichu egg showed as a Pichu. pret's
party menu picks the icon from GetMonData(MON_DATA_SPECIES_OR_EGG), which is
SPECIES_EGG for any egg (pokefirered/src/pokemon.c:3245, party_menu.c:2655).
Pokemon.speciesOrEgg does the same, and the icon call sites use it. The
species pass only extracted icons up to NUM_SPECIES - 1, so the egg extractor
now also bakes gMonIconTable[SPECIES_EGG] as pokemon/icons/412.rgba. Cache
version 114 re-imports existing caches so the icon appears.
Only src/import/gba/versions.lua conflicted, and not on the value: both
branches had independently taken CACHE_VERSION 111 for unrelated cache
layouts. dev's 111 is the hidden-item bitfield fix in
extract_map_events.lua (id % 256, qty % 128); this branch's 111 is the new
deoxys_rock_fragments field effect. Sharing one number would let a cache
stamped by dev be treated as fresh, silently dropping the meteorite
shatter artwork, so the Deoxys artwork moves to 112.
src/core/game3/field_view.lua auto-merged: dev's Doors.draw viewport
arguments and this branch's bg_flash veil do not overlap.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Two Birth Island visuals were broken; both are now verified on screen.
1. The meteorite never reddened as the triangle puzzle progressed.
OwSprites.recolour_sprite called Image:newImageData, which LOVE 11 does
not have, so the pcall always failed and setObjectPalette silently
returned false for all ten steps. Keep the ImageData the sheet was
decoded from in load_one and clone() it before mapPixel (which mutates
in place); the override copy keeps its imageData in step too.
2. The shatter happened, but the shards were invisible. The flash was a
whole-screen Renderer.screenVeil painted after the composite, and the
shards only live ~8 frames, so they were drawn underneath it. pret
(field_effect.c:3946) blends PALETTES_BG only -- BlendPalettes plus
BeginNormalPaletteFade -- so the OBJ shards, which share the
meteorite's palette tag 4371, keep their colours against a white map.
Replace startWhiteFlash with startBgFlash, drawn by FieldView.draw
between the last map layer and the actors. Also match pret's shake
cadence (flip every second frame) and its `++tTimer > 120` test.
Adds tests/drivers/game3_deoxys_visual.lua, which walks all eleven puzzle
positions, shatters the rock, and counts shard-coloured pixels in the
saved frames: 492 px at the shatter frame, 192 px a few frames later
(0 before this fix).
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Badge lines are end-battle texts (SaveEndBattleTextPointers), so they are
printed while the battle sound engine is still loaded. A text sound command
names an id rather than a sound, and that engine's SFX_Headers_2 gives those
ids different sounds: the id behind sound_get_item_1 / sound_level_up is
SFX_Level_Up there, and the id behind sound_get_key_item is SFX_Ball_Poof.
The port resolved the jingle by name, so it always played the overworld
reading (Get_Item1 / Get_Key_Item) -- the wrong jingle for receiving the
BOULDERBADGE, and the same collision for Cerulean, Saffron, Cinnabar and
Viridian in Red, Blue and Yellow alike.
Add victories.badgeSoundFor(), which answers with the jingle that is actually
audible for the badge hand-over:
Red/Blue Brock Level_Up, Misty Ball_Poof, Sabrina Ball_Poof,
Blaine Ball_Poof, Giovanni Level_Up
Yellow the same, except Misty: CeruleanGym.asm drops the command from
that line, so Yellow's Cascade Badge has no jingle
Vermilion, Celadon and Fuchsia carry no sound on their badge lines in any
version. The raw `badgeSound` field keeps the overworld-engine name, which is
what the TM texts (printed in the overworld) genuinely need.
Tests: pin the literal per-version jingle and its page for all five badge
leaders in tests/engine/gym_badge_jingle_page_bug1982.lua (53 checks), and
have the #1606 and driver suites assert through badgeSoundFor.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>