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

View File

@@ -30,7 +30,8 @@
#include <akgl/controller.h>
#include <akgl/error.h>
/*
* game.h purely for the `renderer` global and its `_akgl_renderer` storage.
* game.h purely for the `akgl_renderer` global and its `akgl_default_renderer`
* storage.
* akgl_text_rendertextat() takes no renderer argument and reads that global, so
* a host that never calls akgl_game_init() -- which is every host embedding this
* interpreter, since owning the game loop is exactly what goal 3 forbids -- has
@@ -72,13 +73,13 @@ akerr_ErrorContext *akbasic_frontend_akgl_init(akbasic_AkglFrontend *obj, const
FAIL_ZERO_RETURN(errctx, TTF_Init(), AKGL_ERR_SDL,
"Couldn't initialize SDL_ttf: %s", SDL_GetError());
obj->renderer = &_akgl_renderer;
renderer = obj->renderer;
obj->renderer = &akgl_default_renderer;
akgl_renderer = obj->renderer;
FAIL_ZERO_RETURN(errctx,
SDL_CreateWindowAndRenderer(title, w, h, 0,
&obj->window, &obj->renderer->sdl_renderer),
AKGL_ERR_SDL, "Couldn't create the window: %s", SDL_GetError());
window = obj->window;
akgl_window = obj->window;
/*
* Without this SDL sends no SDL_EVENT_TEXT_INPUT at all, every keystroke
@@ -95,14 +96,14 @@ akerr_ErrorContext *akbasic_frontend_akgl_init(akbasic_AkglFrontend *obj, const
SDL_GetError());
}
/*
* Bind the 2D methods onto the renderer we just made. akgl_render_init2d()
* Bind the 2D methods onto the renderer we just made. akgl_render_2d_init()
* would do this too, but it creates its own window from the game properties
* first, which is the akgl_game_init() path a host with its own window is
* not on. libakgl 0.3.0 split the vtable half out for exactly this caller --
* it was API-gap item 7, and until it landed these six pointers were
* assigned by hand here and in tests/akgl_backends.c.
*/
PASS(errctx, akgl_render_bind2d(obj->renderer));
PASS(errctx, akgl_render_2d_bind(obj->renderer));
/*
* The object pools and the name registries. Every akgl_*_initialize ends in
@@ -133,11 +134,11 @@ akerr_ErrorContext *akbasic_frontend_akgl_init(akbasic_AkglFrontend *obj, const
* anybody could act on. One screen's worth at the origin: BASIC has no verb
* that scrolls a view, so the world and the screen are the same thing here.
*/
camera = &_akgl_camera;
camera->x = 0.0f;
camera->y = 0.0f;
camera->w = (float)w;
camera->h = (float)h;
akgl_camera = &akgl_default_camera;
akgl_camera->x = 0.0f;
akgl_camera->y = 0.0f;
akgl_camera->w = (float)w;
akgl_camera->h = (float)h;
obj->font = TTF_OpenFont(fontpath, (float)fontsize);
FAIL_ZERO_RETURN(errctx, (obj->font != NULL), AKGL_ERR_SDL,
@@ -331,7 +332,7 @@ void akbasic_frontend_akgl_shutdown(akbasic_AkglFrontend *obj)
SDL_StopTextInput(obj->window);
SDL_DestroyWindow(obj->window);
obj->window = NULL;
window = NULL;
akgl_window = NULL;
}
TTF_Quit();
if ( obj->ownssdl ) {