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:
@@ -25,7 +25,7 @@
|
||||
#include <akgl/controller.h>
|
||||
#include <akgl/error.h>
|
||||
/*
|
||||
* game.h purely for the `renderer` global and its `_akgl_renderer` storage. The
|
||||
* game.h purely for the `akgl_renderer` global and its `akgl_default_renderer` storage. The
|
||||
* interpreter never calls akgl_game_init() -- it drives subsystems directly, and
|
||||
* owning the game loop is exactly what goal 3 forbids -- but the draw calls read
|
||||
* that global, so a test standing in for a host has to populate it the same way
|
||||
@@ -85,9 +85,9 @@ static akerr_ErrorContext AKERR_NOIGNORE *clear_target(void)
|
||||
{
|
||||
PREPARE_ERROR(errctx);
|
||||
|
||||
FAIL_ZERO_RETURN(errctx, SDL_SetRenderDrawColor(renderer->sdl_renderer, 0, 0, 0, 0xff),
|
||||
FAIL_ZERO_RETURN(errctx, SDL_SetRenderDrawColor(akgl_renderer->sdl_renderer, 0, 0, 0, 0xff),
|
||||
AKGL_ERR_SDL, "%s", SDL_GetError());
|
||||
FAIL_ZERO_RETURN(errctx, SDL_RenderClear(renderer->sdl_renderer),
|
||||
FAIL_ZERO_RETURN(errctx, SDL_RenderClear(akgl_renderer->sdl_renderer),
|
||||
AKGL_ERR_SDL, "%s", SDL_GetError());
|
||||
SUCCEED_RETURN(errctx);
|
||||
}
|
||||
@@ -104,8 +104,8 @@ static akerr_ErrorContext AKERR_NOIGNORE *start_runtime(const char *source)
|
||||
|
||||
PASS(errctx, akbasic_sink_init_stdio(&SINK, &SINKSTATE, OUT, NULL));
|
||||
PASS(errctx, akbasic_runtime_init(&RUNTIME, &SINK));
|
||||
PASS(errctx, akbasic_graphics_init_akgl(&GRAPHICS, &GRAPHICSSTATE, renderer));
|
||||
PASS(errctx, akbasic_sprite_init_akgl(&SPRITES, &SPRITESSTATE, renderer, &GRAPHICSSTATE));
|
||||
PASS(errctx, akbasic_graphics_init_akgl(&GRAPHICS, &GRAPHICSSTATE, akgl_renderer));
|
||||
PASS(errctx, akbasic_sprite_init_akgl(&SPRITES, &SPRITESSTATE, akgl_renderer, &GRAPHICSSTATE));
|
||||
PASS(errctx, akbasic_runtime_set_devices(&RUNTIME, &GRAPHICS, NULL, NULL, &SPRITES));
|
||||
PASS(errctx, akbasic_runtime_load(&RUNTIME, source));
|
||||
PASS(errctx, akbasic_runtime_start(&RUNTIME, AKBASIC_MODE_RUN));
|
||||
@@ -136,7 +136,7 @@ static akerr_ErrorContext AKERR_NOIGNORE *test_draw_reaches_pixels(void)
|
||||
PASS(errctx, start_runtime("10 COLOR 1, 3\n20 DRAW 1, 10, 20\n"));
|
||||
TEST_REQUIRE_STR(OUTPUT, "");
|
||||
|
||||
shot = SDL_RenderReadPixels(renderer->sdl_renderer, NULL);
|
||||
shot = SDL_RenderReadPixels(akgl_renderer->sdl_renderer, NULL);
|
||||
TEST_REQUIRE(shot != NULL, "could not read the render target back");
|
||||
/* Palette index 3 is red: 0x88, 0x39, 0x32 in src/graphics_tables.c. */
|
||||
TEST_REQUIRE(pixel_is(shot, 10, 20, 0x88, 0x39, 0x32),
|
||||
@@ -171,7 +171,7 @@ static akerr_ErrorContext AKERR_NOIGNORE *test_size_is_the_renderer(void)
|
||||
"20 DRAW 1, 1000, 1000\n"));
|
||||
TEST_REQUIRE_STR(OUTPUT, "");
|
||||
|
||||
shot = SDL_RenderReadPixels(renderer->sdl_renderer, NULL);
|
||||
shot = SDL_RenderReadPixels(akgl_renderer->sdl_renderer, NULL);
|
||||
TEST_REQUIRE(shot != NULL, "could not read the render target back");
|
||||
/*
|
||||
* The far corner of the user space lands on the far corner of the target.
|
||||
@@ -195,7 +195,7 @@ static akerr_ErrorContext AKERR_NOIGNORE *test_box_outlines(void)
|
||||
PASS(errctx, start_runtime("10 BOX 1, 10, 10, 40, 40\n"));
|
||||
TEST_REQUIRE_STR(OUTPUT, "");
|
||||
|
||||
shot = SDL_RenderReadPixels(renderer->sdl_renderer, NULL);
|
||||
shot = SDL_RenderReadPixels(akgl_renderer->sdl_renderer, NULL);
|
||||
TEST_REQUIRE(shot != NULL, "could not read the render target back");
|
||||
TEST_REQUIRE(pixel_is(shot, 10, 10, 0xff, 0xff, 0xff), "the box's corner should be lit");
|
||||
TEST_REQUIRE(pixel_is(shot, 25, 10, 0xff, 0xff, 0xff), "the box's top edge should be lit");
|
||||
@@ -223,7 +223,7 @@ static akerr_ErrorContext AKERR_NOIGNORE *test_paint_fills_region(void)
|
||||
"30 PAINT 2, 25, 25\n"));
|
||||
TEST_REQUIRE_STR(OUTPUT, "");
|
||||
|
||||
shot = SDL_RenderReadPixels(renderer->sdl_renderer, NULL);
|
||||
shot = SDL_RenderReadPixels(akgl_renderer->sdl_renderer, NULL);
|
||||
TEST_REQUIRE(shot != NULL, "could not read the render target back");
|
||||
/* Palette index 6 is green: 0x55, 0xa0, 0x49. */
|
||||
TEST_REQUIRE(pixel_is(shot, 25, 25, 0x55, 0xa0, 0x49),
|
||||
@@ -247,7 +247,7 @@ static akerr_ErrorContext AKERR_NOIGNORE *test_shape_roundtrip(void)
|
||||
"30 GSHAPE A$, 64, 64\n"));
|
||||
TEST_REQUIRE_STR(OUTPUT, "");
|
||||
|
||||
shot = SDL_RenderReadPixels(renderer->sdl_renderer, NULL);
|
||||
shot = SDL_RenderReadPixels(akgl_renderer->sdl_renderer, NULL);
|
||||
TEST_REQUIRE(shot != NULL, "could not read the render target back");
|
||||
/* The saved corner was at (4,4); pasted at (64,64) it lands at (68,68). */
|
||||
TEST_REQUIRE(pixel_is(shot, 68, 68, 0xff, 0xff, 0xff),
|
||||
@@ -273,7 +273,7 @@ static akerr_ErrorContext AKERR_NOIGNORE *test_sink_grid_and_wrap(void)
|
||||
PASS(errctx, akgl_text_measure(font, "A", &cellw, &cellh));
|
||||
TEST_REQUIRE(cellw > 0 && cellh > 0, "the fixture font should measure a real cell");
|
||||
|
||||
PASS(errctx, akbasic_sink_init_akgl(&AKGLSINK, &AKGLSINKSTATE, renderer, font,
|
||||
PASS(errctx, akbasic_sink_init_akgl(&AKGLSINK, &AKGLSINKSTATE, akgl_renderer, font,
|
||||
TARGET_SIZE, TARGET_SIZE));
|
||||
TEST_REQUIRE_INT(AKGLSINKSTATE.cellw, cellw);
|
||||
TEST_REQUIRE_INT(AKGLSINKSTATE.columns, TARGET_SIZE / cellw);
|
||||
@@ -297,7 +297,7 @@ static akerr_ErrorContext AKERR_NOIGNORE *test_sink_grid_and_wrap(void)
|
||||
* producing a zero-column grid, which would divide by zero on the first
|
||||
* wrap.
|
||||
*/
|
||||
TEST_REQUIRE_STATUS(akbasic_sink_init_akgl(&AKGLSINK, &AKGLSINKSTATE, renderer, font, 1, 1),
|
||||
TEST_REQUIRE_STATUS(akbasic_sink_init_akgl(&AKGLSINK, &AKGLSINKSTATE, akgl_renderer, font, 1, 1),
|
||||
AKBASIC_ERR_BOUNDS);
|
||||
TEST_REQUIRE_STATUS(akbasic_sink_init_akgl(&AKGLSINK, &AKGLSINKSTATE, NULL, font,
|
||||
TARGET_SIZE, TARGET_SIZE),
|
||||
@@ -315,7 +315,7 @@ static akerr_ErrorContext AKERR_NOIGNORE *test_sink_renders(void)
|
||||
bool lit = false;
|
||||
|
||||
PASS(errctx, clear_target());
|
||||
PASS(errctx, akbasic_sink_init_akgl(&AKGLSINK, &AKGLSINKSTATE, renderer, font,
|
||||
PASS(errctx, akbasic_sink_init_akgl(&AKGLSINK, &AKGLSINKSTATE, akgl_renderer, font,
|
||||
TARGET_SIZE, TARGET_SIZE));
|
||||
PASS(errctx, AKGLSINK.write(&AKGLSINK, "X"));
|
||||
PASS(errctx, akbasic_sink_akgl_render(&AKGLSINK));
|
||||
@@ -326,7 +326,7 @@ static akerr_ErrorContext AKERR_NOIGNORE *test_sink_renders(void)
|
||||
* is free to hint them differently. The seam being tested is that the text
|
||||
* reached the renderer at the cursor's cell at all.
|
||||
*/
|
||||
shot = SDL_RenderReadPixels(renderer->sdl_renderer, NULL);
|
||||
shot = SDL_RenderReadPixels(akgl_renderer->sdl_renderer, NULL);
|
||||
TEST_REQUIRE(shot != NULL, "could not read the render target back");
|
||||
for ( y = 0; y < AKGLSINKSTATE.cellh && !lit; y++ ) {
|
||||
for ( x = 0; x < AKGLSINKSTATE.cellw && !lit; x++ ) {
|
||||
@@ -402,7 +402,7 @@ static akerr_ErrorContext AKERR_NOIGNORE *test_sprite_from_file(void)
|
||||
TEST_REQUIRE_STR(OUTPUT, "");
|
||||
PASS(errctx, akbasic_sprite_akgl_render(&SPRITES));
|
||||
|
||||
shot = SDL_RenderReadPixels(renderer->sdl_renderer, NULL);
|
||||
shot = SDL_RenderReadPixels(akgl_renderer->sdl_renderer, NULL);
|
||||
TEST_REQUIRE(shot != NULL, "could not read the render target back");
|
||||
/*
|
||||
* Magenta, not white: SPRITE's colour argument modulates the texture and
|
||||
@@ -448,7 +448,7 @@ static akerr_ErrorContext AKERR_NOIGNORE *test_sprite_from_pattern(void)
|
||||
TEST_REQUIRE_STR(OUTPUT, "");
|
||||
PASS(errctx, akbasic_sprite_akgl_render(&SPRITES));
|
||||
|
||||
shot = SDL_RenderReadPixels(renderer->sdl_renderer, NULL);
|
||||
shot = SDL_RenderReadPixels(akgl_renderer->sdl_renderer, NULL);
|
||||
TEST_REQUIRE(shot != NULL, "could not read the render target back");
|
||||
/* Palette index 6 is green: 0x55, 0xa0, 0x49. */
|
||||
TEST_REQUIRE(pixel_is(shot, 20, 20, 0x55, 0xa0, 0x49),
|
||||
@@ -485,7 +485,7 @@ static akerr_ErrorContext AKERR_NOIGNORE *test_sprite_from_shape(void)
|
||||
TEST_REQUIRE_STR(OUTPUT, "");
|
||||
PASS(errctx, akbasic_sprite_akgl_render(&SPRITES));
|
||||
|
||||
shot = SDL_RenderReadPixels(renderer->sdl_renderer, NULL);
|
||||
shot = SDL_RenderReadPixels(akgl_renderer->sdl_renderer, NULL);
|
||||
TEST_REQUIRE(shot != NULL, "could not read the render target back");
|
||||
/*
|
||||
* Palette index 3 is red, which is what the BOX was outlined in. The corner
|
||||
@@ -512,7 +512,7 @@ int main(void)
|
||||
|
||||
ATTEMPT {
|
||||
CATCH(errctx, akgl_error_init());
|
||||
renderer = &_akgl_renderer;
|
||||
akgl_renderer = &akgl_default_renderer;
|
||||
|
||||
FAIL_ZERO_BREAK(errctx, SDL_Init(SDL_INIT_VIDEO), AKGL_ERR_SDL,
|
||||
"Couldn't initialize SDL: %s", SDL_GetError());
|
||||
@@ -521,17 +521,18 @@ int main(void)
|
||||
FAIL_ZERO_BREAK(errctx,
|
||||
SDL_CreateWindowAndRenderer("net/aklabs/akbasic/test_akgl_backends",
|
||||
TARGET_SIZE, TARGET_SIZE, 0,
|
||||
&window, &renderer->sdl_renderer),
|
||||
&akgl_window, &akgl_renderer->sdl_renderer),
|
||||
AKGL_ERR_SDL, "Couldn't create window/renderer: %s", SDL_GetError());
|
||||
/*
|
||||
* Bind the 2D methods. akgl_text_rendertextat() reaches through
|
||||
* renderer->draw_texture and an SDL_Renderer alone does not fill that in;
|
||||
* akgl_renderer->draw_texture and an SDL_Renderer alone does not fill that in;
|
||||
* deps/libakgl/tests/draw.c gets away without it because the draw
|
||||
* primitives take the SDL_Renderer directly. These six pointers were
|
||||
* assigned by hand here until libakgl 0.3.0 split akgl_render_bind2d out
|
||||
* of akgl_render_init2d -- API-gap item 7, filed from this file.
|
||||
* assigned by hand here until libakgl 0.3.0 split the bind half out of the
|
||||
* init half -- API-gap item 7, filed from this file. Both were renamed in
|
||||
* 0.5.0, from akgl_render_bind2d and akgl_render_init2d.
|
||||
*/
|
||||
CATCH(errctx, akgl_render_bind2d(renderer));
|
||||
CATCH(errctx, akgl_render_2d_bind(akgl_renderer));
|
||||
|
||||
/*
|
||||
* The three things akgl_game_init() would have done and this file, being
|
||||
@@ -541,11 +542,11 @@ int main(void)
|
||||
*/
|
||||
CATCH(errctx, akgl_heap_init());
|
||||
CATCH(errctx, akgl_registry_init());
|
||||
camera = &_akgl_camera;
|
||||
camera->x = 0.0f;
|
||||
camera->y = 0.0f;
|
||||
camera->w = (float)TARGET_SIZE;
|
||||
camera->h = (float)TARGET_SIZE;
|
||||
akgl_camera = &akgl_default_camera;
|
||||
akgl_camera->x = 0.0f;
|
||||
akgl_camera->y = 0.0f;
|
||||
akgl_camera->w = (float)TARGET_SIZE;
|
||||
akgl_camera->h = (float)TARGET_SIZE;
|
||||
|
||||
/*
|
||||
* libakgl's own monospaced fixture, borrowed rather than copied. Being
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#include <akgl/controller.h>
|
||||
#include <akgl/draw.h>
|
||||
#include <akgl/error.h>
|
||||
/* game.h for the `camera` global, which akgl_actor_render() reads. */
|
||||
/* game.h for the `akgl_camera` global, which akgl_actor_render() reads. */
|
||||
#include <akgl/game.h>
|
||||
#include <akgl/heap.h>
|
||||
#include <akgl/registry.h>
|
||||
@@ -875,9 +875,9 @@ static akerr_ErrorContext AKERR_NOIGNORE *test_host_can_draw_an_actor(void)
|
||||
|
||||
PASS(errctx, start_frontend(NULL));
|
||||
|
||||
TEST_REQUIRE(camera != NULL, "the frontend should have pointed the camera somewhere");
|
||||
TEST_REQUIRE_INT((int)camera->w, WINDOW_W);
|
||||
TEST_REQUIRE_INT((int)camera->h, WINDOW_H);
|
||||
TEST_REQUIRE(akgl_camera != NULL, "the frontend should have pointed the camera somewhere");
|
||||
TEST_REQUIRE_INT((int)akgl_camera->w, WINDOW_W);
|
||||
TEST_REQUIRE_INT((int)akgl_camera->h, WINDOW_H);
|
||||
TEST_REQUIRE(AKGL_REGISTRY_ACTOR != 0, "the frontend should have created the registries");
|
||||
|
||||
memset(sheetname, 0, sizeof(sheetname));
|
||||
|
||||
Reference in New Issue
Block a user