First entry in the "cookbook" track: a demo capsule plus HOWTO, per the sequencing laid out after the POST-coverage sweep. Built entirely in FORTH on top of existing primitives -- fabric.4th's LINE (raster Bresenham) and Q.SIN/Q.COS (Q48.16 trig), plus PLOT/FB-WIDTH/FB-HEIGHT -- no new C words. FORWARD/BACK/LEFT/RIGHT/PENUP/PENDOWN/HOME/SETXY/SETHEADING/SETCOLOR give the classic turtle model; POLYGON and STAR compose FORWARD+turn into simple demo shapes; TURTLE-DEMO is a one-call visual smoke test. Not wired into init.4th -- REPL-invoked only, matching the original idea's own scope. Verified: mkcapsule --lint clean, hosted-build logic trace shows zero VM errors and correct stack balance through the whole vocabulary, zero build warnings and capsule loads cleanly on all three kernel architectures. Visual pixel-level confirmation not yet done (needs an interactive gtk-display session or driving past the ~25-30 min DoE-before-REPL wall), documented as an open item in the HOWTO. HOWTO: docs/working/architecture/TURTLE-GRAPHICS-HOWTO-20260819.md Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
7.2 KiB
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.4thmust be loaded first — the turtle uses itsLINEword directly, and (transitively)Q.SIN/Q.COS/Q.FROM-INT/Q.TO-INT/Q.*/Q.+fromq48_words.c, which is always registered.- A real framebuffer.
PLOTis a no-op on hosted (make) builds, so the turtle is only visually meaningful under the kernel/QEMU build with thegtkdisplay (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:
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 VARIABLEs, 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
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.
THEADstores heading directly in Q48.16 radians (not degrees) soFORWARDcan hand it straight toQ.SIN/Q.COSwithout a conversion on every step.LEFT/RIGHT/SETHEADINGdo the degrees→radians conversion once, at the turn, via theDEG2RADconstant (1144, Q48.16 forπ/180 ≈ 0.0174533). - No manual angle wraparound.
q48_sin_approx/q48_cos_approx(src/math_portable.c) range-reduce internally viaq48_reduce_angle(), soTHEADcan accumulate indefinitely across many turns without the turtle needing to keep it inside[0, 2π)itself. - Coordinates are Cartesian, not raster.
TX/TYfollowfabric.4th's own convention (Y increases upward) — the Y-flip to raster space happens once, insideLINE's call toTO-RASTER/CART-Y. The turtle never touches raster coordinates directly. - z is always 0.
fabric.4th'sLINEtakes 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 passes0for both z arguments.
Verification performed
mkcapsule --lint capsules/— clean, no block-size or namespace violations (block range5100–5108, clear offabric.4th's highest block at5002).- Logic verified on the hosted build:
fabric.4th's core blocks (4900–4909) plusturtle.4thpiped directly into./build/amd64/standard/ starforth, exercisingHOME,SETCOLOR,POLYGON,STAR,FORWARD, and (transitively)LINE— zero VM errors, correct stack balance throughout (--log-debugtrace confirms everyFORWARDcall computesdx/dyviaQ.COS/Q.SINcorrectly and callsLINEwith the expected seven arguments). - Baked cleanly into
capsule_generated.c(capsule[35]) on a fullMakefile.starkernel ARCH=amd64build, 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). - Not yet visually confirmed pixel-by-pixel in a live framebuffer (that
requires an interactive
gtk-display QEMU session with a human at the keyboard, or driving the serial socket past the ~25–30 minute DoE campaign that runs automatically before the REPL is reachable — neither was practical to do unattended). The arithmetic and control flow are verified; the actual rendered image is not.