Take libakgl 0.5.0 and rename every symbol it namespaced

0.5.0 gives every exported symbol the akgl_ prefix, which is the first libakgl
release to break this project's source rather than only its ABI. The soname goes
to libakgl.so.0.5 and include/akbasic/akgl.h asserts the floor.

What moved here: akgl_render_bind2d is akgl_render_2d_bind,
akgl_sprite_sheet_coords_for_frame is akgl_spritesheet_coords_for_frame, the
renderer, camera and window globals carry the prefix, and _akgl_renderer and
_akgl_camera are akgl_default_renderer and akgl_default_camera.

The renames were applied by site rather than by pattern, because renderer is also
a parameter name in src/sprite_akgl.c and a struct member throughout
src/frontend_akgl.c -- a substitution would have rewritten both without a word.
That is the same trap upstream describes hitting, and it is worth knowing that
the defect behind the rename was not cosmetic: an exported global called renderer
collided with a test's own variable, the executable's definition preempted the
library's, and every texture load in that suite failed while the suite passed.

0.5.0 also fixes libakgl defect 26, which was one of the two reasons
src/sprite_akgl.c installs its own renderfunc: akgl_actor_render took its
destination height from the sprite's width, drawing a 24x21 Commodore sprite as a
24x24 square. The renderfunc stays, because the other reason has not moved -- an
actor carries one scalar scale and SPRITE has separate x- and y-expand bits --
but the comments and TODO.md deviation 40 no longer claim a defect that is fixed.

Every documentation figure re-renders byte-identical under the new library, which
is what says the sprite and drawing paths did not move underneath them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-01 08:01:43 -04:00
parent 8077806598
commit 3415c9aec6
10 changed files with 128 additions and 96 deletions

24
TODO.md
View File

@@ -1291,11 +1291,23 @@ deviations from the reference's *program*: `main.go` and the SDL half of
40. **A sprite is a real `libakgl` actor, and it is drawn by a renderfunc of ours.** Each of the
eight becomes a `SpriteSheet` + `Sprite` + `Character` + `Actor` registered in
`AKGL_REGISTRY_ACTOR`, so an embedding game sees BASIC's sprites alongside its own (goal 3).
But `akgl_actor_render()` is not what draws them: it computes its destination *height* from
the sprite's **width**, which would draw a 24×21 Commodore sprite as a 24×24 square, and an
actor carries a single scalar `scale` that cannot express `SPRITE`'s separate x- and
y-expand bits. `src/sprite_akgl.c` installs its own `renderfunc`, which is libakgl's own
extension point for exactly this. Both defects are filed upstream.
But `akgl_actor_render()` is not what draws them. There were two reasons and **libakgl
0.5.0 fixed one**: the default used to compute its destination *height* from the sprite's
**width**, drawing a 24×21 Commodore sprite as a 24×24 square, and it now uses the height
— libakgl defect 26, filed from here and closed there.
**The reason that remains is the one that keeps this file.** An actor carries a single
scalar `scale` applied to both axes, which cannot express `SPRITE`'s separate x- and
y-expand bits, so `MOVSPR`'s twice-as-wide-same-height is unrepresentable. libakgl records
it as open and names this interpreter as the caller that needs it; the fix is a design
choice over there — `scale_x`/`scale_y` beside `scale`, or replacing `scale` and taking
the ABI break while the major is still 0 — rather than a patch. Until then
`src/sprite_akgl.c` installs its own `renderfunc`, which is libakgl's own extension point
for exactly this.
Worth keeping as a pattern: both defects were found by *using* the library for something
it had not been used for, and both were filed rather than worked around silently. One came
back fixed.
---
@@ -1708,7 +1720,7 @@ Dependency baseline:
|---|---|---|
| `deps/libakerror` | 2.0.1 | Private ownership-enforced status registry. akbasic reserves 512767 in `akbasic_error_register()`. Does not namespace its `coverage` target when embedded — worked around in our `CMakeLists.txt`. **2.0.0 is thread safe and an ABI break** (`libakerror.so.2`): `__akerr_last_ignored` is thread-local and `akerr_next_error()` returns an owned reference, neither of which fails to link when mismatched. **2.0.1 fixes an exit status that mattered more to this band than to any other** — see below. |
| `deps/libakstdlib` | 0.2.0 | soname `libakstdlib.so.0.2`. `AKSL_VERSION_CHECK()` asserted in `tests/version_check.c`. This release fixed all six confirmed defects the port was working around — see §1.9, where the bans are now lifted. |
| `deps/libakgl` | 0.4.0 | soname `libakgl.so.0.4`. Owns status codes 256260. Linked and tested under `-DAKBASIC_WITH_AKGL=ON`, which still defaults OFF so the core library and its whole suite build on a machine with no SDL. **0.3.0 closed every API gap this port had filed** — see §7 — so the four workarounds §3 used to list are gone. 0.4.0 is a leak-and-overread release that changed no public struct, but the soname carries `MAJOR.MINOR` while the major is 0, so rebuild rather than relink. |
| `deps/libakgl` | 0.5.0 | soname `libakgl.so.0.5`. Owns status codes 256260. Linked and tested under `-DAKBASIC_WITH_AKGL=ON`, which still defaults OFF so the core library and its whole suite build on a machine with no SDL. **0.3.0 closed every API gap this port had filed** — see §7 — so the four workarounds §3 used to list are gone. 0.4.0 was a leak-and-overread release that changed no public struct. **0.5.0 is the first that broke our source as well as our ABI**: it namespaced every exported symbol, so `akgl_render_bind2d` is `akgl_render_2d_bind`, `akgl_sprite_sheet_coords_for_frame` is `akgl_spritesheet_coords_for_frame`, the `renderer`/`camera`/`window` globals carry the prefix, and `_akgl_renderer`/`_akgl_camera` are `akgl_default_renderer`/`akgl_default_camera`. `include/akbasic/akgl.h` asserts the 0.5.0 floor. |
**An unhandled error in this band used to exit zero, and 512 is the worst possible base for
that.** `libakerror`'s default unhandled-error handler ended in `exit(errctx->status)`, and a