Bump libakgl to 42b60f7: every gap this port filed is now closed
All four capability gaps filed against libakgl have landed upstream, so nothing
in this repository is waiting on that library any more.
text measurement -> akgl_text_measure, akgl_text_measure_wrapped
immediate drawing -> akgl_draw_point/_line/_rect/_filled_rect/_circle/
_flood_fill/_copy_region/_paste_region
audio -> akgl_audio_init/_tone/_envelope/_waveform/_volume/
_stop/_voice_active/_mix
console input -> akgl_controller_poll_key, akgl_controller_flush_keys
The signatures came back close to what was filed, and two details are worth
recording for whoever writes src/sink_akgl.c next. The draw calls take an
akgl_RenderBackend * as their first argument rather than reaching for a global
renderer, which fits goal 3's rule that the interpreter draws through whatever
renderer the host already initialized. And the audio API is a synthesised-voice
one -- a tone on a numbered voice plus a separate ADSR envelope -- which is the
shape PLAY and ENVELOPE actually need, rather than the sample playback
SDL3_mixer would have offered.
Checked rather than assumed: libakgl's status band is still 256-260, so the
coordinated range map in CLAUDE.md is unaffected and akbasic's 512-767 does not
move.
Documentation that described these as open is corrected in the same commit --
section 7's gap list, section 3's "known gap" note, the priority list, the
dependency table, and the README's unimplemented-verbs section all said blocked
and no longer are. Section 3 also gains the thing that replaced the gap: the
character grid comes from akgl_text_measure(font, "A", &w, &h), the direct
equivalent of the font.SizeUTF8("A") at basicruntime.go:96, and
akgl_text_measure_wrapped takes the same wraplength argument
akgl_text_rendertextat does so the measurement and the draw cannot disagree
about where a line breaks.
One caveat recorded rather than papered over: -DAKBASIC_WITH_AKGL=ON has never
been configured in this repository, because until now there was nothing to build
against. The akbasic_akgl target is unproven and needs libakgl's own submodules
present. Expect to fix something there on the first attempt.
Default build unaffected: ctest 61/61, doxygen exits 0, no warnings.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
71
TODO.md
71
TODO.md
@@ -371,9 +371,18 @@ such ceiling because it called `make()`.
|
||||
|
||||
## 3. Remaining work: the akgl text sink
|
||||
|
||||
**`src/sink_akgl.c`.** Implement the §1.5 vtable against `akgl_text_loadfont` and
|
||||
`akgl_text_rendertextat`. Owns the cursor, the wrap, and the scroll — everything in
|
||||
`basicruntime_graphics.go` except `Write`/`Println`, which are now the sink interface itself.
|
||||
**Unblocked as of `libakgl` 42b60f7** — the text-measurement call this waited on now exists.
|
||||
|
||||
**`src/sink_akgl.c`.** Implement the §1.5 vtable against `akgl_text_loadfont`,
|
||||
`akgl_text_rendertextat` and `akgl_text_measure`. Owns the cursor, the wrap, and the scroll —
|
||||
everything in `basicruntime_graphics.go` except `Write`/`Println`, which are now the sink
|
||||
interface itself.
|
||||
|
||||
The character grid comes from `akgl_text_measure(font, "A", &w, &h)`, which is the direct
|
||||
equivalent of the `font.SizeUTF8("A")` at `basicruntime.go:96` that the reference derives
|
||||
`maxCharsW`/`maxCharsH` from. For wrapping, `akgl_text_measure_wrapped` takes the same
|
||||
`wraplength` argument `akgl_text_rendertextat` already does, so the measurement and the draw
|
||||
cannot disagree about where a line breaks.
|
||||
|
||||
**The interpreter does not own the window, the renderer, or the game loop.** The sink draws
|
||||
through whatever renderer the host already initialized. `akbasic_sink_init_akgl()` takes the
|
||||
@@ -389,13 +398,15 @@ guaranteed to be unnamed. It is idempotent, so calling it from both `akbasic_sin
|
||||
and a host that already did is harmless.
|
||||
`PASS` its result; a range collision is an initialization failure, not a warning.
|
||||
|
||||
**Known gap:** `libakgl` has no text-measurement call — the Go code needs
|
||||
`font.SizeUTF8("A")` (`basicruntime.go:96`) to compute `maxCharsW`/`maxCharsH`, and there is no
|
||||
`akgl_text_*` equivalent. **File it in `deps/libakgl/TODO.md`** before writing a workaround.
|
||||
See §7.
|
||||
**Still to check before starting:** `-DAKBASIC_WITH_AKGL=ON` has never been configured in this
|
||||
repository, because until now there was nothing to build against. It needs `libakgl`'s own
|
||||
submodules present (`git submodule update --init --recursive` pulls SDL and friends), and the
|
||||
`akbasic_akgl` target in `CMakeLists.txt` has therefore never been compiled. Expect to fix
|
||||
something there on the first attempt.
|
||||
|
||||
*Acceptance:* `tests/sink_akgl.c` against the offscreen renderer harness, or — if that harness
|
||||
does not exist yet — a known-failing test plus a `libakgl` TODO entry saying so.
|
||||
*Acceptance:* `tests/sink_akgl.c` against the offscreen renderer harness described in
|
||||
`deps/libakgl/TODO.md` under "Remaining work". If that harness still does not exist, a
|
||||
known-failing test plus a `libakgl` TODO entry saying so.
|
||||
|
||||
---
|
||||
|
||||
@@ -595,15 +606,29 @@ When phase 7 or phase 8 needs something `libakgl` does not have, **stop and file
|
||||
the `akgl_*` entry point should look like, and what tests would cover it. Growing `libakgl` to
|
||||
serve the interpreter is a wanted outcome, not a detour.
|
||||
|
||||
Known gaps, to be filed as they are reached:
|
||||
**All four gaps filed so far are now closed upstream**, at `libakgl` 42b60f7. Nothing here is
|
||||
blocked on `libakgl` any more; what remains is akbasic-side work.
|
||||
|
||||
1. **Text measurement.** No `akgl_text_*` call returns the pixel size of a string in a font.
|
||||
`PRINT` wrapping, the cursor, and `WIDTH` all need it. Blocks 7.1.
|
||||
2. **Immediate-mode drawing.** `src/draw.c` is at 0% coverage and there is no public API for
|
||||
lines, boxes, circles or flood fill. Blocks group G.
|
||||
3. **Audio.** There is no mixer-backed API at all. Blocks group I entirely.
|
||||
4. **Console input.** `GET`/`GETKEY` need a non-blocking keystroke read that does not require
|
||||
the interpreter to own the SDL event loop. Blocks part of group E.
|
||||
| Was blocking | Closed by |
|
||||
|---|---|
|
||||
| Text measurement (§3, the akgl sink) | `akgl_text_measure`, `akgl_text_measure_wrapped` |
|
||||
| Immediate-mode drawing (§4 group G) | `akgl_draw_point`/`_line`/`_rect`/`_filled_rect`/`_circle`/`_flood_fill`/`_copy_region`/`_paste_region` |
|
||||
| Audio (§4 group I) | `akgl_audio_init`/`_tone`/`_envelope`/`_waveform`/`_volume`/`_stop`/`_voice_active`/`_mix` |
|
||||
| Console input (§4 group E) | `akgl_controller_poll_key`, `akgl_controller_flush_keys` |
|
||||
|
||||
Two notes for whoever picks up §3 next. The draw calls take an `akgl_RenderBackend *` as their
|
||||
first argument rather than reaching for a global renderer, which fits the rule that the
|
||||
interpreter draws through whatever renderer the host already initialized. And the audio API is
|
||||
a synthesised-voice one — `akgl_audio_tone(voice, hz, ms)` with a separate ADSR envelope —
|
||||
which is the shape `PLAY` and `ENVELOPE` need, rather than the sample playback SDL3_mixer
|
||||
would have given.
|
||||
|
||||
Building against any of it needs `-DAKBASIC_WITH_AKGL=ON`, which pulls in `libakgl`'s own
|
||||
submodules (SDL and friends). Those are not initialized in a default clone; `git submodule
|
||||
update --init --recursive` gets them.
|
||||
|
||||
No gaps are currently outstanding. When the next one turns up, file it there rather than
|
||||
working around it here.
|
||||
|
||||
---
|
||||
|
||||
@@ -660,11 +685,13 @@ keeping:
|
||||
|
||||
What remains, in priority order:
|
||||
|
||||
1. **§3 — the akgl text sink.** Blocked on `libakgl` having no text-measurement call; that gap
|
||||
needs filing in `deps/libakgl/TODO.md` before any workaround is written.
|
||||
2. **§4 — the language completion work queue.** Groups A, B, D, F and J need nothing from
|
||||
`libakgl` and can start immediately. Multiple statements per line (the `COLON` token exists
|
||||
and nothing consumes it) should come first, because `DO`/`LOOP` reads badly without it.
|
||||
1. **§3 — the akgl text sink.** No longer blocked: `libakgl` 42b60f7 landed
|
||||
`akgl_text_measure`, so this is now ordinary work. Note that `-DAKBASIC_WITH_AKGL=ON` has
|
||||
never been configured here, so the `akbasic_akgl` target is unproven.
|
||||
2. **§4 — the language completion work queue.** Nothing in it is blocked on `libakgl` any more:
|
||||
groups G, I and part of E were, and `libakgl` 42b60f7 closed all three. Multiple statements
|
||||
per line (the `COLON` token exists and nothing consumes it) should still come first, because
|
||||
`DO`/`LOOP` reads badly without it.
|
||||
3. **§6 items 12–17** — the defects the port uncovered. Item 12 is the one that produces a
|
||||
*wrong answer* rather than a refused one, and should be fixed first.
|
||||
4. **Mutation survivors in `src/value.c`.** The harness is in place (`scripts/mutation_test.py`,
|
||||
|
||||
Reference in New Issue
Block a user