mirror of
https://github.com/imjasonh/nescript
synced 2026-07-08 00:45:38 +00:00
assets: auto-generate CHR data from @nametable() PNG sources
`background Foo @nametable("file.png")` previously decoded the PNG
into a tile-index table and an attribute table but left CHR
generation to the user — they had to supply matching tiles via a
separate `sprite Tileset @chr(...)` declaration in the same
deduplication order, which was both error-prone and the main thing
keeping the shortcut form from being a one-liner.
The CHR pipeline now closes the gap. `png_to_nametable_with_chr`
returns a `PngNametable` carrying the tile-index table, the
attribute table, *and* a per-tile CHR blob encoded with the same
brightness-bucketing `png_to_chr` already uses for sprites. The
resolver passes `next_sprite_tile` (computed from the resolved
sprite list) so each background's CHR allocation slots in
immediately after the sprite range, and rewrites the nametable
indices to point at the actual physical tile numbers. The linker
copies each background's `chr_bytes` into CHR ROM at
`chr_base_tile * 16`, so the final image renders without any
user-supplied CHR.
`BackgroundData` carries `chr_bytes` and `chr_base_tile` so the
linker has everything it needs at a glance. Inline `tiles:` /
`attributes:` declarations leave them empty and behave exactly
like before — that path doesn't auto-generate CHR because the
user is implicitly opting into "I'll provide tiles myself" by
typing the indices out by hand.
The new `examples/auto_chr_background.ne` is a 256×240 grayscale
gradient committed alongside its `auto_chr_bg.png` source; the
emulator harness verifies the rendered output against a
committed golden so a regression in the dedupe/encode/linker
plumbing fails CI loudly. Existing example ROMs are byte-
identical because their backgrounds either have no PNG source or
already provided their own CHR.
https://claude.ai/code/session_01KEczoNUX3WmcFLfq6iAQxB
This commit is contained in:
parent
6b080316a4
commit
cc3f7eec7e
15 changed files with 337 additions and 54 deletions
48
examples/auto_chr_background.ne
Normal file
48
examples/auto_chr_background.ne
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
// Auto-CHR background — first NEScript example to use the
|
||||
// `@nametable("file.png")` shortcut without supplying any matching
|
||||
// CHR data. Previously the resolver decoded the PNG into a tile
|
||||
// index table but left CHR generation to the user; the new
|
||||
// `png_to_nametable_with_chr` helper also generates the per-tile
|
||||
// CHR bytes from the same brightness-bucketing code that
|
||||
// `png_to_chr` uses for sprite imports, then the asset resolver
|
||||
// allocates contiguous CHR-ROM tile indices starting after the
|
||||
// last sprite tile and rewrites the nametable to point at them.
|
||||
//
|
||||
// `auto_chr_bg.png` is a 256×240 grayscale gradient rendered to
|
||||
// roughly fifty distinct tiles — enough variety to exercise the
|
||||
// dedupe + CHR generation path but well within the 256-tile cap.
|
||||
//
|
||||
// Build: cargo run -- build examples/auto_chr_background.ne
|
||||
|
||||
game "Auto CHR Background" {
|
||||
mapper: NROM
|
||||
}
|
||||
|
||||
// Grayscale palette with every background sub-palette set to the
|
||||
// same three shades. The PNG-to-attribute helper buckets each
|
||||
// 16×16 quadrant by average brightness and assigns sub-palette
|
||||
// 0..3, so we need *every* bg sub-palette to carry the same
|
||||
// dk_gray / lt_gray / white triple — otherwise quadrants that
|
||||
// pick a non-zero palette would render as the universal colour.
|
||||
palette Main {
|
||||
universal: black
|
||||
bg0: [dk_gray, lt_gray, white]
|
||||
bg1: [dk_gray, lt_gray, white]
|
||||
bg2: [dk_gray, lt_gray, white]
|
||||
bg3: [dk_gray, lt_gray, white]
|
||||
sp0: [black, black, black]
|
||||
sp1: [black, black, black]
|
||||
sp2: [black, black, black]
|
||||
sp3: [black, black, black]
|
||||
}
|
||||
|
||||
// `@nametable` is the shortcut form: no `tiles:` / `attributes:`
|
||||
// body, and the resolver fills both — and now CHR data too — from
|
||||
// the PNG itself.
|
||||
background Stage @nametable("auto_chr_bg.png")
|
||||
|
||||
on frame {
|
||||
wait_frame
|
||||
}
|
||||
|
||||
start Main
|
||||
Loading…
Add table
Add a link
Reference in a new issue