Skip to content

Add metacursor sample with controller input#88

Merged
jonathanpeppers merged 2 commits intomainfrom
metacursor
Feb 15, 2026
Merged

Add metacursor sample with controller input#88
jonathanpeppers merged 2 commits intomainfrom
metacursor

Conversation

@jonathanpeppers
Copy link
Owner

Implements the metacursor.c 8bitworkshop sample.

Features demonstrated

  • \pad_poll(0)\ and \pad_poll(1)\ for two-player controller input
  • \PAD.LEFT/RIGHT/UP/DOWN\ bitflag checking with &\ operator
  • 8 actors with metasprite rendering via \oam_meta_spr\
  • Runtime array element stores (\�ctor_dx[0] = 254\ for d-pad velocity)

Transpiler fix

\HandleStelemI1\ stack depth tracking now accounts for \Mul/\Div\ opcodes (pop 2, push 1). Previously these fell through to the default case with no stack effect, causing the backward IL walk to identify the wrong local as the array target when expressions like \�ctor_x[i] = (byte)(i * 32)\ were used.

Simplifications vs original C

  • 8 actors instead of 16 (zero-page memory limits)
  • Single metasprite for all actors (no animation frame cycling, which requires unsupported array-of-pointers)
  • No boundary checks (actors wrap around screen edges)
  • Inlined \setup_graphics()\ into main body

All 170 tests pass.

Copilot AI review requested due to automatic review settings February 14, 2026 23:21
Copy link

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.

Pull request overview

This PR implements the metacursor sample from 8bitworkshop, demonstrating two-player controller input using pad_poll() to control metasprite cursors with the d-pad. The implementation also includes a critical transpiler fix for array element stores with multiplication/division in the value expression.

Changes:

  • Fixed HandleStelemI1 stack depth tracking to properly account for Mul/Div IL opcodes (pop 2, push 1), enabling correct identification of array targets in expressions like actor_x[i] = (byte)(i * 32)
  • Added metacursor sample with 8 actors controlled via pad_poll(0) and pad_poll(1) for two-player input, demonstrating runtime array operations combined with arithmetic
  • Updated documentation to mark metacursor as implemented and adjust summary counts

Reviewed changes

Copilot reviewed 8 out of 11 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/dotnes.tasks/Utilities/IL2NESWriter.cs Fixed stack tracking in HandleStelemI1 to include Mul and Div opcodes alongside existing binary operators
src/dotnes.tests/TranspilerTests.cs Added test cases for metacursor sample (debug and release builds)
src/dotnes.tests/TranspilerTests.Write.metacursor.verified.bin Verified binary output for metacursor ROM
src/dotnes.tests/Data/metacursor.debug.dll Debug build DLL for metacursor test
src/dotnes.tests/Data/metacursor.release.dll Release build DLL for metacursor test
samples/samples.sln Added metacursor project to solution with all build configurations
samples/metacursor/metacursor.csproj Project configuration for metacursor sample
samples/metacursor/Program.cs Sample implementation with controller input and array operations
samples/metacursor/chr_generic.s CHR ROM graphics data (standard tileset)
samples/metacursor/metacursor.c Original C reference implementation
docs/8bitworkshop-samples.md Updated status from "Moderate" to "Implemented" and adjusted counts

Implements the metacursor.c 8bitworkshop sample demonstrating:
- pad_poll(0) and pad_poll(1) for two-player controller input
- PAD.LEFT/RIGHT/UP/DOWN bitflag checking
- 8 actors with metasprite rendering via oam_meta_spr
- Runtime array element stores (actor_dx[0] = 254 for d-pad velocity)

Transpiler fixes:
1. HandleStelemI1 stack depth tracking now accounts for Mul/Div opcodes
   (pop 2, push 1). Previously these fell through to the default case,
   causing the backward IL walk to identify the wrong local as the
   array target.
2. NTADR_A/B/C/D handlers no longer double-pop args from the Stack.
   The handler pops 2 args for compile-time address computation, but
   the generic post-Call loop was also popping N args, consuming the
   byte array negative marker needed by pal_all to load the PALETTE
   address. This caused gray/colorless output.
3. HandleStelemI1 now supports constant-index stores to runtime arrays
   (e.g. actor_dx[0] = 254). Previously, constant-index stelem was
   treated as a no-op (for ROM array initialization), but runtime
   arrays need actual LDA/STA code. Without this fix, d-pad velocity
   stores were silently dropped, causing random movement and crashes.

Simplifications vs original C:
- 8 actors instead of 16 (zero-page memory limits)
- Single metasprite for all actors (no animation frame cycling)
- No boundary checks (actors wrap around screen edges)
- Inlined setup_graphics() into main body

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… pad reload

- HandleStelemI1: Add value expression support for Mul (power-of-2 shifts),
  Mul+Add, and simple constant patterns. Previously, the init loop
  actor_x[i] = (byte)(i * 32) and actor_dx[i] = 0 generated no value
  loads (A was never set before STA array,X).

- pad_poll: Replace fixed tempVar () with dynamically allocated
  address from local space. The hardcoded address collided with runtime
  arrays (actor_x[2] in metacursor). Now allocates on first pad_poll
  call at local + LocalCount.

- pad_poll: Remove exclusion from _runtimeValueInA, allowing stloc to
  correctly store the return value via STA. Add _runtimeValueInA = false
  in Pop handler for samples that discard the return value.

- AND handler: Continue using _padReloadAddress for pad value reloads
  (renamed from tempVar). Guard conditions unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers jonathanpeppers merged commit 193b602 into main Feb 15, 2026
1 check passed
@jonathanpeppers jonathanpeppers deleted the metacursor branch February 15, 2026 03:21
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