mirror of
https://github.com/imjasonh/nescript
synced 2026-07-18 06:36:57 +00:00
Sprite resolution, asset wiring, shift-assign, unreachable state warning
Sprite/asset pipeline: - Linker::link_with_assets() places sprite CHR data in ROM at correct tile - assets::resolve_sprites() walks Program for inline sprite bytes - CodeGen::with_sprites() maps sprite names to tile indices - gen_draw() uses correct tile index from sprite declarations - main.rs wires the full resolution pipeline Shift-assign operators (<<= and >>=): - AssignOp::ShiftLeftAssign and ShiftRightAssign variants - Parser handles in both statement and array index contexts - Codegen emits ASL A / LSR A - IR lowering maps to ShiftLeft/ShiftRight ops Unreachable state warning (W0104): - BFS from start state finds reachable states via transitions - States not reached produce W0104 warning Error polish helpers: - suggest_var_name() for "did you mean" suggestions - emit_undefined_var() for E0502 with typo hints - Used by analyzer for better diagnostics 242 tests pass, clippy clean. https://claude.ai/code/session_01W6eQFStA66EuMKHUFo2rx3
This commit is contained in:
parent
5d2d242520
commit
6430c3a935
13 changed files with 737 additions and 17 deletions
55
src/assets/resolve.rs
Normal file
55
src/assets/resolve.rs
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
use std::path::Path;
|
||||
|
||||
use crate::linker::SpriteData;
|
||||
use crate::parser::ast::{AssetSource, Program};
|
||||
|
||||
/// Resolve sprite declarations in a program into concrete CHR byte blobs and
|
||||
/// assign each one a tile index in CHR ROM.
|
||||
///
|
||||
/// Tile index 0 is reserved for the built-in default smiley sprite, so user
|
||||
/// sprites start at tile index 1. A single sprite declaration may occupy
|
||||
/// multiple consecutive tiles if its CHR data is larger than 16 bytes.
|
||||
///
|
||||
/// `source_dir` is used as the base for `@binary` / `@chr` relative paths.
|
||||
/// For now, only [`AssetSource::Inline`] sources produce sprite data; file-
|
||||
/// backed sources are parsed but skipped here (future work), which keeps
|
||||
/// existing tests that reference missing files compiling without I/O errors.
|
||||
pub fn resolve_sprites(program: &Program, source_dir: &Path) -> Result<Vec<SpriteData>, String> {
|
||||
let _ = source_dir; // reserved for future file-backed resolution
|
||||
let mut sprites = Vec::new();
|
||||
// Tile index 0 is the built-in smiley; user sprites start at 1.
|
||||
let mut next_tile: u8 = 1;
|
||||
|
||||
for sprite_decl in &program.sprites {
|
||||
let chr_bytes = match &sprite_decl.chr_source {
|
||||
AssetSource::Inline(bytes) => bytes.clone(),
|
||||
// Binary/Chr loading from files is future work; skip for now so
|
||||
// programs that reference (possibly-missing) external assets
|
||||
// still compile without I/O errors.
|
||||
AssetSource::Binary(_) | AssetSource::Chr(_) => continue,
|
||||
};
|
||||
|
||||
// Each NES 8x8 tile is 16 bytes of 2-bitplane CHR data. A single
|
||||
// sprite declaration can span multiple tiles when its CHR blob is
|
||||
// longer than 16 bytes.
|
||||
let tile_count = chr_bytes.len().div_ceil(16);
|
||||
if tile_count == 0 {
|
||||
continue;
|
||||
}
|
||||
if next_tile as usize + tile_count > 256 {
|
||||
return Err(format!(
|
||||
"sprite '{}' would exceed CHR ROM tile limit",
|
||||
sprite_decl.name
|
||||
));
|
||||
}
|
||||
|
||||
sprites.push(SpriteData {
|
||||
name: sprite_decl.name.clone(),
|
||||
tile_index: next_tile,
|
||||
chr_bytes,
|
||||
});
|
||||
next_tile += tile_count as u8;
|
||||
}
|
||||
|
||||
Ok(sprites)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue