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>
wire up Crystal PalMap tile attrs (bank 1, flips, BG_PRIO) through map bake,
attr grid, and BG-over-OAM blits instead of the gold/silver grassAtlasFor shortcut.
crystal-only: MapAttrGrid + TileAttrs, OAM bottom/top split for IN_GRASS,
keyed grass over feet strip via attrmap, drawBgPriorityOver for wAttrmap bit 7.
gold/silver left alone on the old path — all of this gated behind isCrystal().
fixes standing still in grass with tufts on torso / feet on top of grass (#2080).
RomExtractorGen2 pulls crystal PalMap attrs; SpriteRenderer splits standing
sheets on frameHeight; tests for tile attrs + feet strip regression.
the display sync stuff i added was probing whether vsync was actually working, but it was measuring the wrong thing. during the probe we software-cap at 60 for safety, and the probe was looking at the gap between frames... which includes the sleep 😅 ..... so it always looked like sync was fine even when the driver was ignoring it. on something like the ally x on windows thats a real problem. vsync says on, probe says gated, we lift the cap and snap logic to the panel hz, then youre basically uncapped. at 2–4x that turns into hitching, dropped frames, dropped input, that weird half second freeze. speed swapping wasnt desyncing the driver, it was just making the bad path hurt more.
the solution is just we time present() itself now, not the gap after it, this way the warmup sleep cant fake a pass. if sync is unclear or broken we just stay on a capped 60 and dont snap logic. Also fixed fixedstep so it snaps wall clock dt before applying speed, so in general the 2-4x speed swaps dont screw the pacing math anymore
- Introduced PresentSync module to manage display synchronization.
- Updated love.run() to handle display changes and resizing events with PresentSync.
- Enhanced FrameCap logic to accommodate PresentSync requirements.
- Modified VSync to report effective states and handle driver quirks.
- Updated options menus to reflect PresentSync availability and restrictions.
- Added tests to validate PresentSync functionality and its interaction with VSync settings.
should address issue #1910 and issue #1958