The battle intro slide ran at 4px/frame over 40 frames -- twice the
original speed -- and drew the pics in their normal palette instead of
as black silhouettes.
SlidePlayerAndEnemySilhouettesOnScreen scrolls SCX from $90 to 0 at
2px/frame (~72 frames) under the %11100100 silhouette palette, only
running SET_PAL_BATTLE once the pics land. Match that: introSlide starts
at 80 with a 2px/frame offset (80 frames over the full 160px width), and
picImage bakes both pics through PAL_BLACK while introSlide > 0, exactly
like the evolution movie (#279).
parity_battle_intro_chrome waited a hardcoded 45 frames for the slide to
land; bumped to 85 to cover the slower slide.
Clarify that Mac+OpenMTP is contributor tooling (not the final product
contract), record Dusklight method references, and surface how/what we
tested so reviewers and the community can help finish the Switch port.
Co-authored-by: Cursor <cursoragent@cursor.com>
Ignore hidden ._*.gb in the ROM inbox like zips, keep mixed-rescan success notices while appending sibling errors, and cover FileData mount / PK rejection in unit tests.
Co-authored-by: Cursor <cursoragent@cursor.com>
Mac OpenMTP leaves ._*.zip sidecars that fail PhysFS mount and hide a good install; prefer FileData mount on Horizon and keep success notices when a sibling fails.
Co-authored-by: Cursor <cursoragent@cursor.com>
T24 closed: fused boot/import, Red+Blue Play after Blue mount fix,
and NRO-only replace keeps saves on OLED.
Co-authored-by: Cursor <cursoragent@cursor.com>
NX Play for Blue failed because mountVersion relied on absolute
PHYSFS_mount first. Prefer love.filesystem.mount of blue|yellow, overlay
generated trees by version prefix, and align CacheFs.prefix in bootGame.
Co-authored-by: Cursor <cursoragent@cursor.com>
PhysFS does not merge archive data/ with save-dir data/generated, so
fused NX Play crashed after import. Prepend-mount generated trees,
fall back to CacheFs.read in Data:load, keep multiline lua-error logs,
and skip Boot.run when network is unvalidated. T24 stays open.
Co-authored-by: Cursor <cursoragent@cursor.com>
Expose a generic seam so a mod can drive a second screen without the
engine owning any dual-screen layout policy:
- render.compose hook in Renderer:endFrame hands a mod the finished
world + UI canvases, their SGB zones, the frame metrics,
Renderer:blitCanvas (lifted from the internal blit closure) and the
SecondScreen bridge. Return true to take over the window; no wrap (or
calling next) runs the normal single-window composite byte-for-byte.
- SecondScreen.lua + the Android Presentation bridge (love_android_
secondary_* in common/android.cpp, GameActivity secondary display)
as the optional physical-second-display transport.
No battle-render changes: a mod lays out the two screens (including any
battle split) itself. Ships with a unit test, no-mod parity via
gate_hooks, and docs/modding.md (D14).
Under pipefail, unzip|grep -q exits 141 when grep closes early on a
match and aborts mac pack. List once to a file, then grep the listing.
Co-authored-by: Cursor <cursoragent@cursor.com>
OLED pass at 2699c9a: physical A confirms, B cancels; game.love
a208b21e… recorded. T19 suspend×10 still open.
Co-authored-by: Cursor <cursoragent@cursor.com>
SDL labels south as a and east as b; on Switch remap so physical A
confirms and physical B cancels in launcher and NamingScreen.
Co-authored-by: Cursor <cursoragent@cursor.com>
love-nx emits gamepad+raw on one press; NamingScreen saw a+b and always
erased. Skip raw when isGamepad(); align NX Y→a/X→b; prefer A if both.
Co-authored-by: Cursor <cursoragent@cursor.com>