Skip to content

denise: score sprite/playfield collision over all enabled planes#118

Merged
LinuxJedi merged 1 commit into
mainfrom
fix/collision-enabled-planes-beyond-bpu
Jul 5, 2026
Merged

denise: score sprite/playfield collision over all enabled planes#118
LinuxJedi merged 1 commit into
mainfrom
fix/collision-enabled-planes-beyond-bpu

Conversation

@LinuxJedi

Copy link
Copy Markdown
Owner

Problem

Denise's sprite/playfield collision comparator (clxcon_planes_match) only
walked bitplanes up to the current BPU count. Real Denise compares every
CLXCON-enabled plane regardless of how many planes the display is fetching:
a plane enabled beyond the BPU count reads back as 0 and still gates the
match. This mirrors vAmiga's checkS2PCollisions, which evaluates
(dBuffer & enbp) == (mvbp & enbp) across all six (CLXCON) or eight
(CLXCON2, AGA) planes.

With the default CLXCON reset value (all six planes enabled, all match bits
set), a low-plane-count playfield can never satisfy the compare on hardware,
so no collision is flagged. Copperline stopped at the fetched plane count and
so reported a spurious collision, corrupting the CLXDAT value software reads.

Fix

Drop the nplanes argument from collision_pixel / clxcon_planes_match
(render path) and live_playfield_collision_pixel /
live_clxcon_planes_match (live CLXDAT path) and always iterate the full
plane bank (6 for OCS/ECS, 8 for AGA via CLXCON2).

Validation

  • vAmigaTS: Denise/Sprites/collision/sprcoll1 and sprcoll1d drop from
    5.10% -> 0.12% differing pixels vs the vAmiga 4.4 reference. The other
    14 collision cases are unchanged (their residual is a different, unrelated
    class).
  • Byte-identity: phooey/tomato/roots-ecs/roots-aga/zool regression
    screenshots stay byte-identical at 4s and 8s (collision affects only CLXDAT
    reads, never the rendered framebuffer).
  • 1302 unit tests green, plus a new regression test
    (collision_match_gates_on_enabled_planes_beyond_the_bpu_count); clippy and
    fmt clean.

The seven existing live-CLXDAT unit tests set CLXCON to 0x0FC1 (match only
bitplane 1) so their one-plane playfields still collide under the corrected
all-planes compare, keeping their assertions intact.

The sprite/playfield collision comparator only walked bitplanes up to the
current BPU count. Denise compares every CLXCON-enabled plane regardless of
how many planes the display is actually fetching: a plane enabled beyond the
BPU count reads back as 0 and still gates the match, matching vAmiga's
checkS2PCollisions, which evaluates (dBuffer & enbp) == (mvbp & enbp) across
all six (CLXCON) or eight (CLXCON2, AGA) planes.

With the default CLXCON reset value (all six planes enabled, all match bits
set), a low-plane-count playfield can never satisfy the compare on hardware,
so no collision is flagged. Copperline previously stopped at the fetched
plane count and so reported a spurious collision.

Drop the nplanes argument from collision_pixel / clxcon_planes_match (render
path) and live_playfield_collision_pixel / live_clxcon_planes_match (live
CLXDAT path) and always iterate the full plane bank.

vAmigaTS Denise/Sprites/collision/sprcoll1 and sprcoll1d drop from 5.10% to
0.12% differing pixels against the vAmiga 4.4 reference; the other collision
cases are unchanged and the phooey/tomato/roots-ecs/roots-aga/zool regression
screenshots stay byte-identical (collision affects only CLXDAT reads, not the
rendered framebuffer).
@LinuxJedi LinuxJedi merged commit 594a2a5 into main Jul 5, 2026
8 checks passed
@LinuxJedi LinuxJedi deleted the fix/collision-enabled-planes-beyond-bpu branch July 5, 2026 08:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant