Skip to content

Add rect_overlap and sprite_overlap collision detection helpers#439

Open
jonathanpeppers wants to merge 2 commits intomainfrom
add-rect-overlap
Open

Add rect_overlap and sprite_overlap collision detection helpers#439
jonathanpeppers wants to merge 2 commits intomainfrom
add-rect-overlap

Conversation

@jonathanpeppers
Copy link
Copy Markdown
Owner

Add two new NESLib collision detection APIs as described in #421:

  • rect_overlap(x1, y1, w1, h1, x2, y2, w2, h2) — Full AABB rectangle overlap test. Returns true if two axis-aligned rectangles overlap. Uses unsigned byte arithmetic, suitable for NES screen coordinates.

  • sprite_overlap(x1, y1, x2, y2, threshold) — Distance-based collision for same-size sprites. Returns true if the unsigned absolute difference on both axes is less than the threshold.

Both are implemented as 6502 subroutines that read arguments directly from the cc65 parameter stack via indirect indexed addressing, avoiding expensive per-arg popa calls. They depend on addysp for stack cleanup.

Changes

  • src/neslib/NESLib.cs — Added method stubs with XML docs
  • src/dotnes.tasks/ObjectModel/BuiltInSubroutines.cs — 6502 assembly implementations
  • src/dotnes.tasks/ObjectModel/Program6502.cs — Registered in ForEachOptionalBuiltIn with addysp dependency
  • samples/climber/Program.cs — Replaced manual byte-distance collision with sprite_overlap
  • samples/pong/Program.cs — Replaced nested paddle collision checks with rect_overlap
  • Updated test DLLs and verified snapshots

Before/After (climber)

// Before: ~7 lines of manual collision
byte dx = (byte)(actor_x[0] - actor_x[ci]);
if (dx >= 248) dx = (byte)(0 - dx);
byte dyl = (byte)(actor_yy_lo[0] - actor_yy_lo[ci]);
if (dyl >= 248) dyl = (byte)(0 - dyl);
if (dx < 8 && dyl < 8) { collided = 1; }

// After: 1 line
if (sprite_overlap(actor_x[0], actor_yy_lo[0], actor_x[ci], actor_yy_lo[ci], 8))
{ collided = 1; }

Before/After (pong)

// Before: 16 lines of nested ifs per paddle
if (ball_x < 24) {
    if (ball_right == 0) {
        if (ball_y >= p1_y) {
            byte p1_end = (byte)(p1_y + 24);
            if (ball_y < p1_end) { ... }
        }
    }
}

// After: 1 line per paddle
if (ball_right == 0 && rect_overlap(ball_x, ball_y, 8, 8, 16, p1_y, 8, 24))
{ ... }

Closes #421

Copilot AI review requested due to automatic review settings April 3, 2026 03:45
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Add two new NESLib collision detection APIs:
- rect_overlap(x1, y1, w1, h1, x2, y2, w2, h2) for AABB rectangle overlap
- sprite_overlap(x1, y1, x2, y2, threshold) for distance-based same-size sprite collision

Both return bool (0/1 in A register) and are implemented as 6502 subroutines
that read arguments directly from the cc65 parameter stack for efficiency.

Updated samples:
- climber: replaced manual byte-distance collision with sprite_overlap
- pong: replaced nested paddle collision checks with rect_overlap

Closes #421

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

The transpiler's HandleLdelemU1 saves prior values to a single TEMP
register, not the cc65 parameter stack. When multiple array accesses
are chained as function arguments, values get overwritten. Fix by
storing array element values in local variables before the call,
which uses WriteLdloc's pusha emission path instead.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

Add rect_overlap collision detection helper

2 participants