mirror of
https://github.com/imjasonh/nescript
synced 2026-07-08 08:55: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
1
tests/emulator/goldens/auto_chr_background.audio.hash
Normal file
1
tests/emulator/goldens/auto_chr_background.audio.hash
Normal file
|
|
@ -0,0 +1 @@
|
|||
a82b6ff5 132084
|
||||
BIN
tests/emulator/goldens/auto_chr_background.png
Normal file
BIN
tests/emulator/goldens/auto_chr_background.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 755 B |
|
|
@ -1154,7 +1154,7 @@ fn compile_banked(source: &str) -> Vec<u8> {
|
|||
let music = assets::resolve_music(&program).expect("music resolution should succeed");
|
||||
let palettes = assets::resolve_palettes(&program, Path::new("."))
|
||||
.expect("palette resolution should succeed");
|
||||
let backgrounds = assets::resolve_backgrounds(&program, Path::new("."))
|
||||
let backgrounds = assets::resolve_backgrounds(&program, Path::new("."), 0)
|
||||
.expect("background resolution should succeed");
|
||||
|
||||
let mut codegen = IrCodeGen::new(&analysis.var_allocations, &ir_program)
|
||||
|
|
@ -1932,7 +1932,7 @@ fn e2e_png_palette_source_compiles_and_splices_bytes_into_prg() {
|
|||
// relative PNG path lands on the fixture we just wrote.
|
||||
let palettes =
|
||||
assets::resolve_palettes(&program, &dir).expect("palette resolution should succeed");
|
||||
let backgrounds = assets::resolve_backgrounds(&program, &dir).expect("bg ok");
|
||||
let backgrounds = assets::resolve_backgrounds(&program, &dir, 0).expect("bg ok");
|
||||
assert_eq!(palettes.len(), 1);
|
||||
assert_eq!(palettes[0].name, "Main");
|
||||
// First two bytes should map via `nearest_nes_color` to black
|
||||
|
|
@ -2018,7 +2018,7 @@ fn compile_banked_with_opts(source: &str, optimize: bool) -> Vec<u8> {
|
|||
let music = assets::resolve_music(&program).expect("music resolution should succeed");
|
||||
let palettes = assets::resolve_palettes(&program, Path::new("."))
|
||||
.expect("palette resolution should succeed");
|
||||
let backgrounds = assets::resolve_backgrounds(&program, Path::new("."))
|
||||
let backgrounds = assets::resolve_backgrounds(&program, Path::new("."), 0)
|
||||
.expect("background resolution should succeed");
|
||||
|
||||
let mut codegen = IrCodeGen::new(&analysis.var_allocations, &ir_program)
|
||||
|
|
@ -2261,7 +2261,7 @@ fn source_map_survives_aggressive_peephole_folding() {
|
|||
let sfx = assets::resolve_sfx(&program).unwrap();
|
||||
let music = assets::resolve_music(&program).unwrap();
|
||||
let palettes = assets::resolve_palettes(&program, Path::new(".")).unwrap();
|
||||
let backgrounds = assets::resolve_backgrounds(&program, Path::new(".")).unwrap();
|
||||
let backgrounds = assets::resolve_backgrounds(&program, Path::new("."), 0).unwrap();
|
||||
|
||||
let mut codegen = IrCodeGen::new(&analysis.var_allocations, &ir_program)
|
||||
.with_sprites(&sprites)
|
||||
|
|
@ -2402,7 +2402,7 @@ fn debug_build_emits_bounds_check_halt_routine() {
|
|||
let music = assets::resolve_music(&program).unwrap();
|
||||
let palettes = assets::resolve_palettes(&program, Path::new("."))
|
||||
.expect("palette resolution should succeed");
|
||||
let backgrounds = assets::resolve_backgrounds(&program, Path::new("."))
|
||||
let backgrounds = assets::resolve_backgrounds(&program, Path::new("."), 0)
|
||||
.expect("background resolution should succeed");
|
||||
|
||||
let mut cg_debug = IrCodeGen::new(&analysis.var_allocations, &ir_program)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue