pbio moves to git.bnd.wtf/irrlicht/pbio.git branch truecolor16: the framebuffer is now RGB565 u16, no palette. Assets are loaded from PNG via the png crate and quantized to RGB565 on load; transparency comes from the alpha channel as a per-tile opacity mask, so any color (black included) can be opaque. The TGA loader and the palette-order fragility are gone. overworld.png is the unmodified Mini-Medieval Overworld sheet (same 24-column layout as the old TGA, so map tile ids are unchanged); entities.png holds the player sprite extracted from the old entities.tga. Adds an ignored snapshot test that renders the first frame headlessly to a PNG for eyeballing the renderer without a window. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2.1 KiB
Executable File
Asset Loader
Current state
PNG loading is implemented in game/src/assets.rs. Image::from_png(path) decodes via the
png crate (any color type, expanded to 8-bit RGBA) and quantizes on load to the
framebuffer's RGB565 format with pbio::rgb565; alpha ≥ 128 counts as opaque. The result
is an Image { width, height, pixels: Vec<u16>, opaque: Vec<bool> }. Artists work in
truecolor; there is no palette an asset could be "in the wrong order" for. game.rs uses it
directly: Image::from_png("assets/tilesets/overworld.png").
Image also provides to_tileset() -> Vec<Tile>, which splits the image into 8×8 tiles
row-major. A Tile is 64 RGB565 pixels plus a u64 opacity bitmask. Every tile is
emitted; tile ID is the flat row-major index into the Vec, so tiles are never skipped or
reordered. overworld.png is the unmodified Mini-Medieval Overworld.png sheet (24
columns), so Tiled tile ids line up with the Vec index.
History: the first iteration used 8-bit indexed TGAs on a palette framebuffer (RGB332,
pbio master branch). The colormap-ordering fragility and the index-0-is-transparent
convention are gone with the switch to pbio's truecolor16 branch.
AssetStore (a named registry) is not yet implemented. Assets are currently loaded
inline in Game::start().
Goal
Add an AssetStore so that game code can ask for an asset by name rather than loading
files directly at the call site.
Design notes
Imagestruct:width: u32,height: u32,pixels: Vec<u16>,opaque: Vec<bool>— done.- A simple
AssetStorecould be aHashMap<&'static str, Image>loaded at startup. - No streaming needed — the whole game is small enough to load everything upfront in
start(). - Transparency is the tile's mask bit, checked by
blit_tile()inpixelhelper.rs. Any color — black included — can be an opaque pixel. - Pixel assets are stored as flat
Vec<u16>of RGB565 values, row-major, width × height. - Future: consider embedding assets with
include_bytes!to produce a single binary.
Open questions
- Should
AssetStorehold pre-split tilesets too, or just rawImagevalues?