Files
irrlichtandClaude Opus 5 5a055c048d Switch to 16-bit truecolor framebuffer and PNG assets
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>
2026-09-18 23:17:41 +02:00

43 lines
2.1 KiB
Markdown
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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?