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>
43 lines
2.1 KiB
Markdown
Executable File
43 lines
2.1 KiB
Markdown
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
|
||
|
||
- `Image` struct: `width: u32`, `height: u32`, `pixels: Vec<u16>`, `opaque: Vec<bool>` — done.
|
||
- A simple `AssetStore` could be a `HashMap<&'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()` in `pixelhelper.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 `AssetStore` hold pre-split tilesets too, or just raw `Image` values?
|