1
0
Fork 0
mirror of https://github.com/imjasonh/nescript synced 2026-07-08 00:45:38 +00:00

Add example builds to CI, document sprite name behavior

- CI: new "Build Examples" job compiles all .ne files and validates
  the output ROMs have correct iNES headers
- Examples: add notes explaining that sprite names (Smiley, Ball) are
  parsed but not yet resolved — all draws use the built-in CHR tile 0.
  Custom sprite declarations come in M3.
- Codegen: explicit `let _ = &draw.sprite_name` to document the
  intentional skip, with comment about M2/M3 scope

https://claude.ai/code/session_01W6eQFStA66EuMKHUFo2rx3
This commit is contained in:
Claude 2026-04-11 22:55:43 +00:00
parent a20ddcbbab
commit fd5a940c89
No known key found for this signature in database
5 changed files with 51 additions and 4 deletions

View file

@ -49,3 +49,31 @@ jobs:
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- run: cargo test --all-targets
examples:
name: Build Examples
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- run: cargo build --release
- name: Compile all .ne examples
run: |
for f in examples/*.ne; do
echo "==> Compiling $f"
cargo run --release -- build "$f"
done
- name: Verify ROMs are valid iNES
run: |
for f in examples/*.nes; do
echo "==> Checking $f"
# iNES magic: first 4 bytes must be "NES\x1a"
header=$(od -A n -t x1 -N 4 "$f" | tr -d ' ')
if [ "$header" != "4e45531a" ]; then
echo "FAIL: $f is not a valid iNES ROM (header: $header)"
exit 1
fi
size=$(stat -c%s "$f")
echo " OK: $size bytes"
done

View file

@ -35,10 +35,18 @@ Use the d-pad (arrow keys in most emulators) to move the sprite.
## What you'll see
The ROM displays a small smiley-face sprite (an 8x8 tile built into the
compiler's default CHR data). In `hello_sprite`, you control it with the d-pad.
The ROM displays a small 8x8 smiley-face sprite. This is a default tile built
into the compiler's CHR data. In `hello_sprite`, you control it with the d-pad.
In `bouncing_ball`, it moves on its own and bounces off the screen edges.
### About sprite names
In Milestone 1, the name in `draw Smiley at: (x, y)` is parsed but not
resolved to a specific tile — all draws use CHR tile 0 (the built-in smiley).
The `draw` syntax is forward-compatible: when `sprite` declarations and the
asset pipeline arrive in M3, names like `Smiley` will reference actual
sprite definitions with custom tile data from PNGs.
## Emulator controls
| NES Button | Typical Key |

View file

@ -2,6 +2,10 @@
//
// Build: cargo run -- build examples/bouncing_ball.ne
// Output: examples/bouncing_ball.nes
//
// Note: In M1 the sprite name in `draw` is parsed but not resolved.
// All sprites use tile 0 from the built-in CHR data (a smiley face).
// Custom sprite declarations come in M3.
game "Bouncing Ball" {
mapper: NROM

View file

@ -1,8 +1,12 @@
// Hello Sprite — the simplest NEScript program.
//
// Displays a smiley-face sprite on screen and moves it with the d-pad.
// Displays a sprite on screen and moves it with the d-pad.
// Build: cargo run -- build examples/hello_sprite.ne
// Output: examples/hello_sprite.nes (open in any NES emulator)
//
// Note: In M1 the sprite name in `draw` is parsed but not resolved.
// All sprites use tile 0 from the built-in CHR data (a smiley face).
// Sprite declarations with custom tile data come in M3.
game "Hello Sprite" {
mapper: NROM

View file

@ -540,7 +540,10 @@ impl CodeGen {
fn gen_draw(&mut self, draw: &DrawStmt) {
// OAM buffer is at $0200-$02FF
// Each sprite entry: Y, tile, attributes, X
// For M1: use OAM slot 0 (bytes $0200-$0203)
// For M1: sprite name (draw.sprite_name) is parsed but ignored —
// all draws use OAM slot 0 with tile index 0 (the built-in CHR tile).
// Sprite name resolution and multiple OAM slots come in M2/M3.
let _ = &draw.sprite_name;
// Y position (stored at $0200)
self.gen_expr(&draw.y);
self.emit(STA, AM::Absolute(0x0200));