acron.hud¶
Instrument widgets for game HUDs — the drawing RCSS cannot do.
RmlUi covers the document half of a HUD (panels, lists, gauges, text) and
acron.ui ships that machinery. It does not cover the other half:
a minimap, a compass tape, a dial, an oscilloscope trace. Web HUDs reach for
<canvas> there; RmlUi has no equivalent and its <img> reads files, not
live textures.
This module is that missing half, built out of what Acron already has —
aspect2d cards, a Texture, and (for Raster) the engine’s
acron.raster.RasterPainter:
PixelFrame— an authored pixel space onaspect2d, anchored to a window corner, so a HUD can be laid out in the same numbers its design was drawn in. (Every port so far hand-rolled this constant; acronvehicle’s HUD calls it_PX.)Painter— the drawing interface an instrument writes against: lines, rects, polygons, discs, arcs, text.Rasterimplements it on an RGBA pixel buffer uploaded to a card (the<canvas>this engine does not have; the pixels are painted in C++,acron.raster), andRecordPainterimplements it by writing the calls down — so an instrument’s layout can be pinned against its reference with no window, no GPU and no screenshot.LabelPool— pooled ``TextNode``s over a raster. A pixel buffer can draw everything an instrument needs except its type; Acron already has a text engine, so the two are used side by side rather than a font being rasterised by hand.MapView— a baked top-down map on a card, with the visible world rect driven by a texture transform rather than by re-blitting pixels: pan, zoom and (optionally) rotate cost nothing per frame. The mechanism behind both a north-up survey minimap and a heading-up combat radar.relative_bearing()/tape_offset()— the compass-tape mapping from a world bearing to a position along a strip.
Games supply policy: what to draw, in which colours, at what size.
Three engine facts shape the code (../RUNTIME.md rules 4 and 17):
Acron re-uploads a WHOLE texture when any of it changes. Instrument rasters are small (a 300-square minimap is 360 kB) so this is cheap, but it is why
Raster.upload()is explicit and skipped when nothing was drawn.Acron’s RAM images are BGRA and bottom-row-first. A raster is indexed
[y, x]with y growing DOWN the screen, the way every 2D drawing API is, and the flip happens once, on upload.The RmlUi backend does not render transformed subtrees, so anything that has to rotate or scale per frame belongs here rather than in a document.
|
Pooled ``TextNode``s over a raster, in the raster's own pixel frame. |
|
A baked top-down map, windowed by a texture transform. |
|
The drawing calls an instrument makes — raster pixels, y growing DOWN. |
|
An authored pixel space on |
|
An RGBA raster you draw into, on a card. |
|
A |
Global Functions
- hex_chip_png(cache_dir, name: str, rgba, px: int = 64, supersample: int = 4) str¶
A pointy-top hexagon chip PNG in
cache_dir, created on first ask.RCSS has no clip-path, so a shaped status chip has to be pixels; RmlUi loads images from files, so a cache directory stands in. Vertices (50%,0) (100%,25%) (100%,75%) (50%,100%) (0,75%) (0,25%), anti-aliased by
supersample``² coverage. Returns the file's absolute path, which is what an ``imgsrc wants.The colour is part of the FILENAME: a cache keyed by name alone keeps serving the old pixels after a palette edit (the documented cache-poisoning class), so the key covers everything that shapes the image.
- relative_bearing(bearing: float, heading: float) float¶
bearing - headingwrapped into [-180, 180) degrees.The signed short way round, which is what a compass tape needs and what a naive subtraction gets wrong exactly once per revolution. Dead astern lands on -180 rather than +180, matching the
((b - h + 540) % 360) - 180form the ports carry over from their sources.
- tape_offset(bearing: float, heading: float, span: float, width: float) float | None¶
Where
bearingfalls along a compass tape, orNoneif off it.The tape shows
spandegrees acrosswidthpixels; the answer is measured from the tape’s centre, positive to the right. Iterate ABSOLUTE bearings and ask this — stepping over offsets from the current heading instead means no tick ever lands on a multiple of 45 and the cardinal labels never appear.