diff --git a/TODO.md b/TODO.md index abb8f78..2c54190 100644 --- a/TODO.md +++ b/TODO.md @@ -2629,8 +2629,21 @@ reduced against `build/basic`, the stdio build, unless it says otherwise. `tests/structure_verbs.c`, which today only exercises blocks whose bodies are plain statements. -3. **In the standalone SDL build, nothing the graphics verbs draw can ever be seen.** Not - "does not persist" — *never visible at all*, in any frame. +3. **In the standalone SDL build, nothing the graphics verbs draw can be seen unless the + program shrinks the text area first.** **Half done.** The tee sink now forwards + `WINDOW` (§6 item 31), so `sink_window()` is reachable and a program *can* take rows + back from the text layer -- which is the half that made this unanswerable. 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. + + Whether that default is right is a real question rather than a defect, and it is + entangled with what no `WINDOW` call fixes -- the frontend never clears and SDL + double-buffers, so a drawing has to be re-issued every frame, and it has to fit inside + one batch to survive a capture (item 5). Both are now documented in chapters 6, 13 and + 14. **Sprites remain the only thing visible for free**, so the trick the game uses is + still the right one for a game; it should not be the *only* way, and it no longer is. + + The original report, whose second bullet is fixed and whose first stands: ```basic GRAPHIC 1, 1 diff --git a/docs/17-tutorial-breakout.md b/docs/17-tutorial-breakout.md index 79b0dab..474b431 100644 --- a/docs/17-tutorial-breakout.md +++ b/docs/17-tutorial-breakout.md @@ -38,10 +38,11 @@ without your program doing anything: - the **sprites**, walked slot by slot after it. The drawing verbs are not one of them. `DRAW`, `BOX`, `CIRCLE` and `PAINT` go straight -into the renderer's back buffer, and the text layer paints over the whole window on its -way past — so in the standalone SDL build **nothing you draw with them is ever visible**. -That is recorded as a defect (`TODO.md` §9 item 3) rather than a design, but it is the -interpreter you have. +into the renderer's back buffer, and **the text layer owns every row of the window by +default** — so it paints over anything they drew on its way past. `WINDOW` shrinks the +text area and gives the rest of the window to the drawing verbs, but a drawing still has +to be re-issued every frame and has to fit in one batch to survive the capture; see +[Chapter 13](13-differences.md#graphics). So this game uses no drawing verb at all. Anything that has to move smoothly is a sprite; anything that can live on a 16-pixel grid is text. Ball and paddle move; bricks, score @@ -751,5 +752,6 @@ game against: differently from BASIC 7.0. - **[Chapter 14](14-architecture.md)** is the interpreter itself — the step loop, the pools and how to debug a program that stops for no visible reason. -- `TODO.md` §6 and §9 carry the defects this game found, each with a reduction that fits - on a screen and what a fix would touch. +- `TODO.md` §6 and §9 carry the thirteen defects these two games found, with the + reduction for each. Eleven have since been fixed and are struck; the entries are kept + because the reduction and the cause are worth more than the tidiness of deleting them. diff --git a/docs/18-tutorial-breakout-artwork.md b/docs/18-tutorial-breakout-artwork.md index 62e4ad1..1408b2e 100644 --- a/docs/18-tutorial-breakout-artwork.md +++ b/docs/18-tutorial-breakout-artwork.md @@ -100,15 +100,21 @@ broken while a gem is falling drops nothing. ## Step 3: Turn what you drew into a sprite In the standalone SDL build the text layer repaints every row of the window, opaque, -after your program's steps have run and before the frame is presented — so **anything -`DRAW`, `BOX` or `CIRCLE` puts on the screen is painted over before anybody sees it**. -Sprites are drawn after the text layer. A sprite is the only thing on the screen a -program can rely on being visible. (`TODO.md` §9 item 3; the figures in this chapter are -rendered by a tool that omits the text layer, which is why they can show a drawing at -all.) +after your program's steps have run and before the frame is presented — so by default +**anything `DRAW`, `BOX` or `CIRCLE` puts on the screen is painted over before anybody +sees it**. Sprites are drawn after the text layer, which makes a sprite the one thing a +program can rely on being visible without doing anything else about it. -That leaves exactly one way to put a picture up: **draw it, capture it with `SSHAPE`, -install the capture with `SPRSAV`.** +`WINDOW 0, 0, 49, 1` would hand the rest of the window to the drawing verbs. This program +does not, and would not want to: a drawing has to be re-issued every frame to survive +double buffering *and* fit inside one 256-line batch to survive the capture, which is +Step 4. A sprite has neither constraint — it is drawn from state the interpreter keeps. + +So: **draw it, capture it with `SSHAPE`, install the capture with `SPRSAV`.** Once it is +a sprite it stays on the screen for nothing. + +(The figures in this chapter are rendered by a tool that draws no text layer, which is +why they can show a bare drawing at all.) ```basic norun SSHAPE Z$, 0, 60, 800, 600 @@ -619,8 +625,12 @@ A silenced voice costs nothing to issue. One line beats eleven scattered through ## Five things in this dialect that do not do what they look like -Each of these cost an evening. All five are filed in `TODO.md` §9 with a reduction and -the file and line of the cause. +Each of these cost an evening, and each was filed in `TODO.md` §9 with a reduction and +the file and line of the cause. **Three of the five have since been fixed**, and are kept +here as the history of why this program is shaped the way it is — a listing whose +comments explain what it was avoiding is worth more than one quietly rewritten to pretend +the problem never existed. The two that remain are the first and the last, and the first +is the dangerous one. ### 1. The left operand decides integer or float arithmetic @@ -787,6 +797,11 @@ and two four-note stings; one gem at a time; sticky and multiball share one offs balls stuck to the paddle sit on top of each other; and no high score on disk, because there is no disk. +**Several of these budgets were tighter when this was written.** A scalar cost a pool +slot, a saved shape could not live in an array, and a loop inside a skipped block leaked +a scope — so a program had to spend variables to avoid all three. The listing has not +been rewritten to take the room back, because what it does instead is show its working. + ## Where to go next - **[Chapter 8](08-sprites.md)** is the sprite reference: every form of `SPRSAV`, the @@ -796,5 +811,6 @@ there is no disk. - **[Chapter 7](07-sound.md)** is `SOUND`, `PLAY`, `ENVELOPE` and `VOL`. - **[Chapter 14](14-architecture.md)** explains the step loop and the pools this chapter keeps running into, from the interpreter's side. -- `TODO.md` §9 is the eight defects this game found, each with a reduction, the cause and - what a fix would touch. +- `TODO.md` §9 is the eight defects this game found, each with a reduction and the cause. + Six are fixed and struck; the two that stand are the left-operand rule, which is a + decision rather than a defect, and the batch tear, which is the host's to own. diff --git a/examples/breakout/characters/README.md b/examples/breakout/characters/README.md index 42613e5..de35315 100644 --- a/examples/breakout/characters/README.md +++ b/examples/breakout/characters/README.md @@ -39,9 +39,10 @@ a completely different program. ## Known warts, this game's own - **The cell size is a constant.** `CW#` and `CH#` are 16, measured with the bundled - C64_Pro_Mono at 16 points in the 800×600 window; the grid is 50×37. BASIC cannot ask — - `WINDOW` knows, but the standalone frontend never offers it. Change the font or the - window size and those two numbers have to change with them. + C64_Pro_Mono at 16 points in the 800×600 window; the grid is 50×37. When this was + written BASIC had no way to ask. It has now — `RGR(3)`, `RGR(4)` and `RWINDOW`, added + because of this listing — and the listing has not been changed to use them, because + what it demonstrates is what a program does when the interpreter will not tell it. - **Every character the game draws also goes to stdout**, because the frontend tees the text sink to the terminal. It made the whole game auditable from a log file during development and it is pure noise the rest of the time. Redirect it. @@ -56,8 +57,13 @@ a completely different program. game is silent rather than dead. - **No high score on disk.** There is no disk in this interpreter. -The interpreter defects this game turned up are filed in `TODO.md` §6 item 30 and §9, each -with a reduction that fits on a screen. +The interpreter defects this game turned up are filed in `TODO.md` §6 and §9, each with a +reduction that fits on a screen. Most are now fixed — the value pool that killed the first +version after twenty-five seconds, the unreachable `WINDOW`, the character written past a +short row — and the entries are struck rather than deleted, because the reduction is worth +keeping. **The listing itself is unchanged**, and deliberately: it is what a program +written against those constraints looks like, and its comments explain what it was +working around. ## How this was checked diff --git a/examples/breakout/sprites/README.md b/examples/breakout/sprites/README.md index ea5ad38..e229f51 100644 --- a/examples/breakout/sprites/README.md +++ b/examples/breakout/sprites/README.md @@ -68,9 +68,9 @@ Crediting Kenney is not required by CC0. It is here because it should be. Named honestly rather than left to be discovered: - **No music under the game**, only event sounds and two four-note stings. There is room in - the third voice for it; there is not much room anywhere else. 121 of the interpreter's - 128 variables are spoken for, four more are the ones it makes itself, and the label table - is at 61 of 64. + the third voice for it; there was not much room anywhere else when it was written. 121 of + the interpreter's 128 variables are spoken for and the label table is at 61 of 64 — + several of them spent working around defects that have since been fixed. - **One gem at a time.** There is one sprite slot for it. A brick broken while a gem is falling drops nothing. - **Sticky and multiball share one offset.** Two balls stuck to the paddle at once sit on @@ -82,5 +82,13 @@ Named honestly rather than left to be discovered: - **No high score on disk.** There is no disk. The eight interpreter defects this game turned up are filed in `TODO.md` §9, each with a -reduction that fits on a screen, the file and line of the cause, and what a fix would -touch. +reduction that fits on a screen and the file and line of the cause. **Six are now fixed** +— the leaking `DEF` call, the skipped block that broke its caller's `RETURN`, the ignored +subscript on `SSHAPE`, `GRAPHIC CLR`, a negative `DATA` item, and half of the invisible +drawing. The two that stand are the left-operand arithmetic rule, which turned out to be a +decision rather than a defect and is now documented as one, and the 256-line batch tear, +which belongs to the host. + +**The listing is unchanged**, and deliberately: it is what a program written against those +constraints looks like, and its comments explain what it was working around. Six separate +scalars for six brick stamps is no longer necessary, and it is still what the file does.