feedback: plasma box, explicit fonts, and per-position text coalescing

Three endpoint gaps, found building the Descent 3 score overlay - the boxed
place|score field the original games drew over the callsign:

plasma box <x> <y> <w> <h> draws an outlined box with a blanked interior, the
overlay chrome, as one ESC P graphics write. The wire addresses whole bytes
horizontally, so the write covers the byte-aligned span containing the box and
clears span pixels outside it; documented, with 8-px alignment the advice.
Boxes queue FIFO with rows.

plasma text gains an explicit font: a third numeric token after the position,
with text still following, so `plasma text 2 2 7` still displays "7". Auto-fit
picks the font by LENGTH - short text always rendered large, and a "1" that
must fit a 12-px box simply could not be sent before. ResolvePosText
generalizes the legacy Score-font special case: 0 = auto, nonzero honored.

Text coalescing is now per position. The global rule - any queued text
superseded every other queued text - meant the documented two-field layout
(callsign top, score bottom) could not survive its own send burst: the second
field silently ate the first whenever both were queued. A newer text now
replaces only a queued text at the same (x,y).

15 new tests; 472 pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-08-02 11:45:59 -05:00
co-authored by Claude Opus 5
parent 23453667d2
commit 46e108de89
9 changed files with 315 additions and 26 deletions
+10 -2
View File
@@ -107,14 +107,22 @@ What the endpoint exposes (v1):
position; the font still auto-fits by length. Use this to keep two fields on
screen at once (e.g. callsign top line, score bottom line:
`plasma text 2 2 "VIPER 1-1"` + `plasma text 2 18 "SCORE 4200"`).
- **`plasma text <x> <y> <font> <text>`** — as above with an explicit font
(`2` small 5×7, `5` large 10×14, `0` auto). Auto picks the font by LENGTH,
so short positioned text always renders large; the explicit form is how a
short field ("1", "1000") fits inside a score box.
- **`plasma clear`** — blank the display.
- **`plasma row <y> <hex32>`** — one full 128-px bitmap row; see
[Bitmap graphics](#bitmap-graphics-esc-p).
- **`plasma box <x> <y> <w> <h>`** — outlined box, interior blanked: the
overlay chrome for a field drawn on top of other content (the original
games' rank|score box over the callsign). Byte-aligned horizontally — put
box edges on 8-px boundaries where neighbors matter.
Text is **Latin-1** (one byte per char) — don't send UTF-8.
Not exposed through the endpoint yet (small extensions when needed): explicit
font/attribute selection and box draw/fill.
Not exposed through the endpoint yet (small extensions when needed): text
attribute selection (intensity/underline/reverse/flash) and filled-only boxes.
### Bitmap graphics (`ESC P`)