The text layer owns the whole window by default, so a drawing is invisible until a program calls WINDOW #23

Open
opened 2026-08-02 19:04:28 -04:00 by tachikoma · 3 comments
Collaborator

Source: TODO.md §9 items 3 and 9 (at 9151438)

Half of this is fixed and the remaining half is a real question rather than a defect.

What was fixed: the tee sink now forwards WINDOW, so a program can take rows back from the text
layer; and the drawing verbs now render into a layer the frame composites under the text and the
sprites, so a drawing survives the frame it was made in. Both Breakout listings gave back the two
sprite slots they were spending on the screen itself.

What stands is the default. The text area is the whole window, so a program that does not call
WINDOW still cannot see a drawing:

GRAPHIC 1, 1
COLOR 1, 3
BOX 1, 100, 300, 700, 500
PRINT "THE TEXT SHOWS AND THE BOX DOES NOT"
LABEL SPIN
GOTO SPIN

akbasic_sink_akgl_render() fills every row of the text area, opaque, every frame, and the
area is the whole window (state->rows = h / cellh). The comment explaining why it must repaint
rather than track dirty rows is sound; what it does not account for is that the rows it owns are
all of them.

The consequence is that chapter 6 cannot be run in the interpreter it documents. Its figures
are right because tools/screenshot.c deliberately omits the text layer -- so the harness that
proves the chapter is exactly the harness that hides this
, and docs_screenshots passes and
always would.

Deciding it means deciding what a frame owns: whether a fresh runtime's text area should be the
whole window, some fraction of it, or whether GRAPHIC should imply a split.

Files: src/sink_akgl.c:505,564, src/frontend_akgl.c, docs/06-graphics.md


Filed by Tachikoma (Claude Code, Opus 5, 1M context)

**Source:** TODO.md §9 items 3 and 9 (at 9151438) **Half of this is fixed and the remaining half is a real question rather than a defect.** What was fixed: the tee sink now forwards `WINDOW`, so a program *can* take rows back from the text layer; and the drawing verbs now render into a layer the frame composites under the text and the sprites, so a drawing survives the frame it was made in. Both Breakout listings gave back the two sprite slots they were spending on the screen itself. **What stands is the default.** The text area is the whole window, so a program that does not call `WINDOW` still cannot see a drawing: ```basic GRAPHIC 1, 1 COLOR 1, 3 BOX 1, 100, 300, 700, 500 PRINT "THE TEXT SHOWS AND THE BOX DOES NOT" LABEL SPIN GOTO SPIN ``` `akbasic_sink_akgl_render()` fills **every row of the text area, opaque, every frame**, and the area is the whole window (`state->rows = h / cellh`). The comment explaining why it must repaint rather than track dirty rows is sound; **what it does not account for is that the rows it owns are all of them.** **The consequence is that chapter 6 cannot be run in the interpreter it documents.** Its figures are right because `tools/screenshot.c` deliberately omits the text layer -- **so the harness that proves the chapter is exactly the harness that hides this**, and `docs_screenshots` passes and always would. Deciding it means deciding what a frame owns: whether a fresh runtime's text area should be the whole window, some fraction of it, or whether `GRAPHIC` should imply a split. **Files:** `src/sink_akgl.c:505,564`, `src/frontend_akgl.c`, `docs/06-graphics.md` --- Filed by Tachikoma (Claude Code, Opus 5, 1M context)
tachikoma added this to the 1.0.0 milestone 2026-08-02 19:04:28 -04:00
tachikoma added the design-decisionblast-radius:mediumstatus::grooming labels 2026-08-02 19:04:28 -04:00
Owner

@tachikoma

Deciding it means deciding what a frame owns: whether a fresh runtime's text area should be the whole window, some fraction of it, or whether GRAPHIC should imply a split.

What was the behavior of Commodore BASIC 7.0? That should be the guiding principle here, and we should avoid deviating from it without a good reason.

@tachikoma > Deciding it means deciding what a frame owns: whether a fresh runtime's text area should be the whole window, some fraction of it, or whether GRAPHIC should imply a split. What was the behavior of Commodore BASIC 7.0? That should be the guiding principle here, and we should avoid deviating from it without a good reason.
Owner

@tachikoma ^ respond

@tachikoma ^ respond
Author
Collaborator

Confirmed. BASIC 7.0 GRAPHIC 1,1 selects the standard full bitmap display. The normal text screen remains updated, but it is hidden; ordinary PRINT is therefore not visible. That matches the current default rather than identifying a defect.

The C128’s explicit mixed-mode facility is GRAPHIC 2 (standard bitmap split screen, with the optional third argument selecting the split line). The reference program draws in the bitmap portion and uses PRINT in the text portion; text placed on a full bitmap uses CHAR, not PRINT. Therefore GRAPHIC should not implicitly create a split or window. Examples intended to show a full graphic need bitmap text (or no text); examples needing PRINT need an explicit split/window.

Source: Commodore 128 Programmer’s Reference Guide, “GRAPHIC,” p. 119.

Confirmed. BASIC 7.0 `GRAPHIC 1,1` selects the standard full bitmap display. The normal text screen remains updated, but it is hidden; ordinary `PRINT` is therefore not visible. That matches the current default rather than identifying a defect. The C128’s explicit mixed-mode facility is `GRAPHIC 2` (standard bitmap split screen, with the optional third argument selecting the split line). The reference program draws in the bitmap portion and uses `PRINT` in the text portion; text placed on a full bitmap uses `CHAR`, not `PRINT`. Therefore `GRAPHIC` should not implicitly create a split or window. Examples intended to show a full graphic need bitmap text (or no text); examples needing `PRINT` need an explicit split/window. Source: [Commodore 128 Programmer’s Reference Guide, “GRAPHIC,” p. 119](https://cx16.dk/c128-kernal-routines/Commodore128ProgrammersReferenceGuide.pdf).
Sign in to join this conversation.