Files
LithosAnanake/docs/working/architecture/TURTLE-GRAPHICS-HOWTO-20260819.md
T
Robert Allan JamesandClaude Sonnet 5 e40134da0d Add capsules/turtle.4th, a limited LOGO-style turtle graphics demo capsule
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>
2026-08-19 01:50:54 -04:00

7.2 KiB
Raw Blame History

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:

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. 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 51005108, 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).
  • 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 ~2530 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.