Files
LithosAnanake/docs/working/architecture/TURTLE-GRAPHICS-HOWTO-20260819.md
Robert Allan JamesandClaude Sonnet 5 413b5a9bbf Verify turtle.4th rendering live, revert overdue ART-STRESS-CAMPAIGN disable
Disabled capsules/artemis/init.4th block 4170's ART-STRESS-CAMPAIGN -- its
own comment already said to revert to disabled once the K-invariant/
heartbeat verification run (item 4.6, closed earlier this session) was
done. This was the actual ~25-30 minute wall blocking interactive REPL
access, unrelated to any DoE mechanism.

Verified capsules/turtle.4th and capsules/sdk.4th live in a gtk-display
QEMU session: a red hexagon (6 100 POLYGON) and a green self-intersecting
star (100 STAR) both render with correct geometry and color. Screenshot in
evidence/amd64/.

Two real obstacles found and worked around along the way: CS's full-
framebuffer PLOT loop is far slower under TCG than previously documented
(closer to 20+ minutes than "slow"), and the kernel's heartbeat CSV logging
draws to the same console surface PLOT writes pixels to, overwriting
drawings within a fraction of a second unless silenced first with the
existing HB-OFF word. Both HOWTOs updated to record this.

Re-verified full three-arch acceptance boot (POST, DoE, parity) with the
ART-STRESS-CAMPAIGN change: 1012/0/0 and matching dict_hash on all three,
identical to the pre-change baseline.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-19 07:57:43 -04:00

158 lines
8.3 KiB
Markdown
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.
<!-- Living draft (docs/working/ tier). Source for a future docs/formal/cookbook
scrap once reviewed -- see docs/formal/CLAUDE.md's Scraps System. Not yet
promoted; do not cite. -->
# Turtle Graphics HOWTO — `capsules/turtle.4th`
**Status:** WORKING. First entry in the "cookbook" track Captain Bob asked
for on 2026-08-18 (memory: `project-stadium-logo-turtle-idea`, floated
2026-08-11) — a small, low-stakes demo capsule meant to make the CANVAS/
framebuffer substrate satisfying to drive interactively, not a production
subsystem. Second cookbook entry (DoE package/library HOWTO) is a separate,
later doc.
## What this is
A limited LOGO-style turtle graphics vocabulary: a cursor with a position
and heading that moves around the screen, drawing a trail when its "pen" is
down. Classic commands — `FORWARD`, `BACK`, `LEFT`, `RIGHT`, `PENUP`/
`PENDOWN` — composed entirely in FORTH on top of primitives that already
exist:
- `PLOT` / `FB-WIDTH` / `FB-HEIGHT` (`src/word_source/framebuffer_words.c`)
— raw hardware-boundary pixel write, kernel-only (no-op on hosted builds).
- `LINE` / `CIRC-PT` / `Q.SIN` / `Q.COS` (`capsules/fabric.4th`,
`src/word_source/q48_words.c`) — Cartesian line-drawing (Bresenham, in
raster space) and Q48.16 fixed-point trig, both already load-bearing for
the glyph-rendering pipeline.
No new C words were added for this — per this repo's standing rule ("compose
in FORTH first; new C primitives are justified only for raw hardware access,
atomics, syscalls, or freestanding kernel ops"), a turtle is pure policy on
top of primitives that already exist.
## Prerequisites
- `capsules/fabric.4th` must be loaded first — the turtle uses its `LINE`
word directly, and (transitively) `Q.SIN`/`Q.COS`/`Q.FROM-INT`/`Q.TO-INT`/
`Q.*`/`Q.+` from `q48_words.c`, which is always registered.
- A real framebuffer. `PLOT` is a no-op on hosted (`make`) builds, so the
turtle is only visually meaningful under the kernel/QEMU build with the
`gtk` display (`make -f Makefile.starkernel ARCH=<arch> qemu`). It loads
and runs its arithmetic identically on hosted builds — useful for logic
verification, not for seeing anything.
## Loading it
Not wired into `init.4th` — it is not part of the Mama VM's boot sequence,
by design (memory: "invoked from the REPL", not autoloaded). Load and run it
interactively:
```forth
S" turtle.4th" EXEC
TURTLE-DEMO
```
`TURTLE-DEMO` clears the screen, draws a cyan hexagon, then a magenta
five-pointed star from the same starting point — a one-call visual smoke
test.
## Vocabulary
| Word | Stack effect | Effect |
|------|---------------|--------|
| `HOME` | `( -- )` | Turtle to screen center, heading east (0°), pen down, color white. Does not clear the screen. |
| `CS` | `( -- )` | Clear the framebuffer to black. Plain nested `PLOT` loop (no fill primitive exists) — slow under TCG for a full screen; a one-shot clear, not a per-frame op. |
| `PENUP` / `PENDOWN` | `( -- )` | Whether `FORWARD`/`BACK` draw while moving. |
| `SETCOLOR` | `( color -- )` | 24-bit `0xRRGGBB`, same format `PLOT` takes directly. |
| `SETXY` | `( x y -- )` | Jump to `(x y)` without drawing, regardless of pen state. |
| `SETHEADING` | `( deg -- )` | Absolute heading in degrees, 0 = east, counterclockwise positive. |
| `FORWARD` | `( n -- )` | Move `n` pixels along the current heading, drawing a `LINE` from old to new position if the pen is down. |
| `BACK` | `( n -- )` | `FORWARD` in reverse (`NEGATE FORWARD`). |
| `LEFT` | `( deg -- )` | Turn `deg` degrees counterclockwise in place. |
| `RIGHT` | `( deg -- )` | Turn `deg` degrees clockwise in place (`NEGATE LEFT`). |
| `POLYGON` | `( sides len -- )` | Regular polygon, drawn from the turtle's current position/heading — call `HOME` first for a clean start. |
| `STAR` | `( len -- )` | Classic self-intersecting 5-pointed star (`FORWARD` + a 144° turn, five times — not `360/5=72°`, which draws a plain pentagon). |
| `TURTLE-DEMO` | `( -- )` | `CS`, a cyan hexagon, then a magenta star. |
Internal state (`TX`/`TY`/`THEAD`/`TPEN`/`TCOLOR` and the `FORWARD` scratch
pair `TNX`/`TNY`) is exposed as ordinary `VARIABLE`s, matching every other
piece of drawing-fabric state in `fabric.4th` — nothing here is hidden or
C-side.
## Worked example — a five-pointed star by hand
```forth
S" turtle.4th" EXEC
HOME
16711935 SETCOLOR ( magenta, 0xFF00FF )
100 STAR
```
Equivalent to running `TURTLE-DEMO`'s second half. `STAR` is not built from
`POLYGON` with a different turn angle — a mathematically regular pentagon
(`5 100 POLYGON`, turning `360/5 = 72°` per corner) is convex and does not
self-intersect; the classic five-pointed star shape requires overshooting
the turn to `144°` per corner instead, which is why `STAR` is its own word
rather than a `POLYGON` call with `n=5`.
## Design notes for anyone extending this
- **Heading storage.** `THEAD` stores heading directly in Q48.16 radians
(not degrees) so `FORWARD` can hand it straight to `Q.SIN`/`Q.COS` without
a conversion on every step. `LEFT`/`RIGHT`/`SETHEADING` do the
degrees→radians conversion once, at the turn, via the `DEG2RAD` constant
(`1144`, Q48.16 for `π/180 ≈ 0.0174533`).
- **No manual angle wraparound.** `q48_sin_approx`/`q48_cos_approx`
(`src/math_portable.c`) range-reduce internally via `q48_reduce_angle()`,
so `THEAD` can accumulate indefinitely across many turns without the
turtle needing to keep it inside `[0, 2π)` itself.
- **Coordinates are Cartesian, not raster.** `TX`/`TY` follow `fabric.4th`'s
own convention (Y increases upward) — the Y-flip to raster space happens
once, inside `LINE`'s call to `TO-RASTER`/`CART-Y`. The turtle never
touches raster coordinates directly.
- **z is always 0.** `fabric.4th`'s `LINE` takes 3D Cartesian points
(`x1 y1 z1 x2 y2 z2 color`) because it also serves the cavalier-projection
glyph/cube-drawing code; the turtle is flat, so it always passes `0` for
both z arguments.
## Verification performed
- `mkcapsule --lint capsules/` — clean, no block-size or namespace
violations (block range `5100``5108`, clear of `fabric.4th`'s highest
block at `5002`).
- Logic verified on the hosted build: `fabric.4th`'s core blocks (`4900`
`4909`) plus `turtle.4th` piped directly into `./build/amd64/standard/
starforth`, exercising `HOME`, `SETCOLOR`, `POLYGON`, `STAR`, `FORWARD`,
and (transitively) `LINE` — zero VM errors, correct stack balance
throughout (`--log-debug` trace confirms every `FORWARD` call computes
`dx`/`dy` via `Q.COS`/`Q.SIN` correctly and calls `LINE` with the expected
seven arguments).
- Baked cleanly into `capsule_generated.c` (capsule `[35]`) on a full
`Makefile.starkernel ARCH=amd64` build, zero warnings; boot verified
clean through POST and into the DoE campaign with the capsule present
(not autoloaded, so it cannot affect the boot path it isn't on).
- **Visually confirmed 2026-08-19**, live in a `gtk`-display QEMU session:
a red `6 100 POLYGON` (hexagon) and a green `100 STAR` both render with
correct geometry and color. Screenshot:
`evidence/amd64/qemu-screenshot-20260819-074637-turtle-polygon-star-
verified.png`. Two things had to be worked out first, worth recording
since they'll matter for any future interactive session:
- The `~2530` minute wall this doc used to describe turned out to
actually be `capsules/artemis/init.4th`'s `ART-STRESS-CAMPAIGN`
(auto-runs at Artemis's birth, unrelated to any DoE mechanism
documented in `DOE-LIBRARY-HOWTO-20260819.md`) — it carried a stale
`TEMP: ... revert once that run is done` comment for a verification
run that had already closed. Reverted to disabled, matching the
file's own note (FABRIC-2.md section K/L).
- The kernel's heartbeat CSV logging (`[HADES][DOE ]` rows) draws to
the *same* console surface `PLOT` draws pixels to, and scrolls
continuously — anything drawn gets visually overwritten within a
fraction of a second unless silenced first with `HB-OFF` (registered
in `src/starkernel/doe_log.c`; `HB-ON` re-enables it). Do this before
drawing anything you want to actually see.
- `TURTLE-DEMO`'s own `CS` call turned out to be dramatically slower
than "slow under TCG" suggested — closer to 20+ minutes than a minor
delay, for a full-framebuffer nested `PLOT` loop. For a quick visual
check, call `HOME`/`SETCOLOR`/`POLYGON`/`STAR` directly and skip `CS`.