diff --git a/TODO.md b/TODO.md index 00b3b9e..844a9f2 100644 --- a/TODO.md +++ b/TODO.md @@ -2244,35 +2244,35 @@ each is here so the reasoning does not have to be reconstructed. naive all-pairs sweep at 0.7% of a frame at 64 actors and 11% at 256, so the crossover is well above anything a Commodore-shaped sprite budget will reach. - Also still open at the seam: the contact is computed and discarded. §6 item 40 and the - BASIC surface built on it are what consume it. + What remains is only the pairing seam above. The contact itself is consumed: + `akbasic_collision_service()` pulls it per sprite and the `RCOLLISION` fields are what both + breakout games now bounce on. -39. **Convert the breakout listings and chapters 17 and 18 to the collision verbs.** This is the - payoff, and it is deliberately not part of the integration commit. +39. ~~**Convert the breakout listings and chapters 17 and 18 to the collision verbs.**~~ + **Done.** Both games and both tutorials now register their bricks with `SOLID`, arm + `COLLISION 2` and read the contact back with `RCOLLISION`. - Neither game calls `COLLISION` or `BUMP` even once today. Of roughly 230 lines of collision - code across the two, about 19 are sprite-against-sprite; the rest is a sprite against - numbers in a BASIC array or against bare constants, because bricks are text characters in - one game and stamped pixels inside one big sprite in the other. Static collision geometry is - what changes that — a brick becomes a collidable box without spending a sprite slot. + What went: `BALLBRICKS` (29 lines) and `TESTCELL` (28) in the artwork game, and `HITTEST` + (14) plus its pixel-to-cell arithmetic in the characters game — replaced by a handler that + asks which box was hit and which axis to reverse. The hand-written minimum-translation-axis + is `RCOLLISION(n, 7)`. `BUILDLIVE`/`BUILDROW`/`STAMPROW` went with the full-field redraw + they existed to make cheap, and the artwork game gave six orphaned declarations back with + them: the label table went from 61 of 64 to 57. - What goes, concretely: + Two things are worth keeping from doing it, because neither is obvious and both cost an + evening: - - `examples/breakout/sprites/breakout.bas` — `BALLBRICKS` (29 lines) and `TESTCELL` (28) - become a handler that reads which box was hit and which axis to reverse. The - hand-written minimum-translation-axis at `:661-666` is a contact field. `BUILDLIVE` and - `BUILDROW` stop maintaining a parallel `BRK#()` grid. - - `examples/breakout/characters/breakout.bas` — `HITTEST` (14 lines) and the pixel-to-cell - arithmetic go the same way, and `PADHIT`'s five-line overlap test becomes `BUMP`. + - **`BUMP`'s mask is by sprite number, not by anything the handler is about.** The artwork + game's balls are sprites 5, 6 and 7, so their bits are 16, 32 and 64. A handler that + tests 1, 2 and 4 runs, matches nothing and returns, with no error and nothing to see. + - **A bare `SOLID` must run *before* the level is laid out, not after.** Put after the fill + loop it retires all sixty rectangles that were just registered, and the only symptom is a + ball that passes through the wall. - **The documentation cost is the reason this is separate.** Chapter 17 Step 10 and chapter 18 - Steps 9 and 13 are built around that arithmetic, both chapters' examples are executed by - `docs_examples`, and both were rewritten and validated immediately before this work started. - Folding a listing rewrite into a library integration would make neither reviewable. - - Sequence it after §9 item 9 if that is ever fixed, since a game that no longer spends two - sprites on the screen has two more to spend on collidable things, and the two rewrites would - otherwise touch the same lines twice. + Chapter 18 also lost a rule it depended on and no longer stated: a `FOR` with equal bounds + does not run its body (§6 item 19), which is why every list in the chapter has its one-item + case written out beside the loop. It is now stated in Step 7 where it is first used, rather + than cross-referenced to a step that the rewrite deleted. 40. **`akbasic_runtime_call_function()`: call a BASIC function from C with bound values.** @@ -3151,7 +3151,8 @@ reduced against `build/basic`, the stdio build, unless it says otherwise. 9. ~~**A program that wants a picture on the screen has to spend a sprite slot on it, and `examples/breakout/sprites/breakout.bas` spends two of its eight on the screen itself.**~~ - **Done for the interpreter; the listing has not been converted yet -- that is §6 item 39.** + **Done.** The listing has been converted with it: no `SSHAPE` of the screen, no `PACE` + routine hunting for a batch boundary, and both slots free. The drawing verbs now render into a layer the frame composites under the text and the sprites (`akbasic_graphics_akgl_begin`/`_end`/`_render`, `src/graphics_akgl.c`), so a