Document what the functions actually do instead of that they can fail

The Doxygen comments were generated from the declarations, so 217 @throws
lines across 21 headers read "When the corresponding validation or operation
fails" and told a caller nothing beyond the status name. The @param lines were
the same shape: every output was "Output destination populated by the
function", every instance "Object to initialize, inspect, or modify".

Rewritten against the implementations, following the pattern libakstdlib
already uses:

- @throws names the condition. akgl_sprite_load_json separated AKERR_KEY
  (absent) from AKERR_TYPE (present, wrong type) from AKERR_OUTOFBOUNDS
  (filename too long, or array indexed past its end), and gained AKGL_ERR_SDL
  and AKGL_ERR_HEAP, which it raises and never declared.
- Parameters say whether they are required, what a NULL means, and what is
  written on a failure path. Where an argument is not checked, the doc says so:
  akgl_heap_next_actor's dest is a crash on NULL, not an error, and
  akgl_render_2d_frame_start dereferences self before testing it.
- The conventions move up to the file blocks so the per-function docs stay
  short. json_helpers.h states once that absence is an error here and that
  json_t * results are borrowed; heap.h explains the pool model and the
  acquire asymmetry; physics.h carries the thrust/environmental/velocity table.
- Struct fields, enum values, macros and exported globals are documented,
  including the dead ones - sprite_w/sprite_h, movetimer, p_scale and
  timer_gravity are read by nothing, and say so.

Also fixes ten comments in error.h and audio.h that opened with /** rather
than /**<, so Doxygen attached them to the following entity and rendered the
text as part of the macro's value. Verified against the generated HTML.

Comments only - no declaration changed. Doxygen builds clean under
WARN_AS_ERROR, scripts/reindent.sh --check passes, 19/19 suites pass.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Andrew Kesterson <andrew@aklabs.net>
This commit is contained in:
2026-07-31 11:02:20 -04:00
parent 3a91b79709
commit b3450ac1da
28 changed files with 3090 additions and 1012 deletions

View File

@@ -37,57 +37,81 @@
#define AKGL_DRAW_MAX_FLOOD_SPANS 4096
/**
* @brief Draw background.
* @param w Destination width.
* @param h Destination height.
* @brief Paint an 8x8 grey checkerboard over a region, the way an image editor shows transparency.
*
* A diagnostic backdrop, not a general primitive -- `charviewer` uses it so a
* sprite's transparent pixels are visible rather than blending into black. It
* is the one function in this file that does not follow the file's conventions:
* it draws through the *global* `renderer` rather than a backend the caller
* passes in, it leaves the renderer's draw colour changed, and it reports
* nothing.
*
* @param w Width of the region to cover, in pixels, starting at x = 0.
* @param h Height of the region, starting at y = 0. Both round up to whole 8px
* cells, so a 12-pixel height paints 16.
*/
void akgl_draw_background(int w, int h);
/**
* @brief Plot a single pixel.
* @param self Backend or object instance to operate on.
* @param x Horizontal destination coordinate.
* @param y Vertical destination coordinate.
* @param color Color to draw with.
* @param self The backend to draw through. Required, along with its
* `sdl_renderer`.
* @param x Horizontal position in render-target pixels. Outside the target
* is clipped by SDL, not reported.
* @param y Vertical position.
* @param color Colour to plot in, including alpha. Blending follows the
* renderer's current blend mode, which this does not change.
* @return `NULL` on success, otherwise an error context owned by the caller.
* @throws AKERR_NULLPOINTER When the corresponding validation or operation fails.
* @throws AKGL_ERR_SDL When the corresponding validation or operation fails.
* @throws AKERR_NULLPOINTER If @p self or `self->sdl_renderer` is `NULL`.
* @throws AKGL_ERR_SDL If the draw colour cannot be read or set, or if the plot
* itself fails. The message carries `SDL_GetError()`.
*/
akerr_ErrorContext AKERR_NOIGNORE *akgl_draw_point(akgl_RenderBackend *self, float32_t x, float32_t y, SDL_Color color);
/**
* @brief Draw a line between two points.
* @param self Backend or object instance to operate on.
* @param x1 Horizontal coordinate of the first endpoint.
* @param y1 Vertical coordinate of the first endpoint.
* @param x2 Horizontal coordinate of the second endpoint.
* @param y2 Vertical coordinate of the second endpoint.
* @param color Color to draw with.
* @brief Draw a line between two points, endpoints included.
* @param self The backend to draw through. Required, along with its
* `sdl_renderer`.
* @param x1 Horizontal position of the first endpoint.
* @param y1 Vertical position of the first endpoint.
* @param x2 Horizontal position of the second endpoint.
* @param y2 Vertical position of the second endpoint. Coincident endpoints
* draw a single pixel rather than nothing.
* @param color Colour to draw in, including alpha.
* @return `NULL` on success, otherwise an error context owned by the caller.
* @throws AKERR_NULLPOINTER When the corresponding validation or operation fails.
* @throws AKGL_ERR_SDL When the corresponding validation or operation fails.
* @throws AKERR_NULLPOINTER If @p self or `self->sdl_renderer` is `NULL`.
* @throws AKGL_ERR_SDL If the draw colour cannot be read or set, or if the line
* cannot be drawn.
*/
akerr_ErrorContext AKERR_NOIGNORE *akgl_draw_line(akgl_RenderBackend *self, float32_t x1, float32_t y1, float32_t x2, float32_t y2, SDL_Color color);
/**
* @brief Draw the outline of a rectangle.
* @param self Backend or object instance to operate on.
* @param rect Rectangle to outline.
* @param color Color to draw with.
* @param self The backend to draw through. Required, along with its
* `sdl_renderer`.
* @param rect The rectangle, in render-target pixels. Required. A zero or
* negative width or height draws nothing and is not reported.
* @param color Colour to draw in, including alpha.
* @return `NULL` on success, otherwise an error context owned by the caller.
* @throws AKERR_NULLPOINTER When the corresponding validation or operation fails.
* @throws AKGL_ERR_SDL When the corresponding validation or operation fails.
* @throws AKERR_NULLPOINTER If @p self, `self->sdl_renderer`, or @p rect is
* `NULL`.
* @throws AKGL_ERR_SDL If the draw colour cannot be read or set, or if the
* outline cannot be drawn.
*/
akerr_ErrorContext AKERR_NOIGNORE *akgl_draw_rect(akgl_RenderBackend *self, SDL_FRect *rect, SDL_Color color);
/**
* @brief Fill a rectangle.
* @param self Backend or object instance to operate on.
* @param rect Rectangle to fill.
* @param color Color to draw with.
* @brief Fill a rectangle, outline included.
* @param self The backend to draw through. Required, along with its
* `sdl_renderer`.
* @param rect The rectangle, in render-target pixels. Required. A zero or
* negative width or height fills nothing and is not reported.
* @param color Colour to fill with, including alpha.
* @return `NULL` on success, otherwise an error context owned by the caller.
* @throws AKERR_NULLPOINTER When the corresponding validation or operation fails.
* @throws AKGL_ERR_SDL When the corresponding validation or operation fails.
* @throws AKERR_NULLPOINTER If @p self, `self->sdl_renderer`, or @p rect is
* `NULL`.
* @throws AKGL_ERR_SDL If the draw colour cannot be read or set, or if the fill
* cannot be drawn.
*/
akerr_ErrorContext AKERR_NOIGNORE *akgl_draw_filled_rect(akgl_RenderBackend *self, SDL_FRect *rect, SDL_Color color);
@@ -98,15 +122,22 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_draw_filled_rect(akgl_RenderBackend *sel
* algorithm -- integer arithmetic, eight-way symmetry, one pass per octant. A
* radius of zero draws the center pixel and nothing else.
*
* @param self Backend or object instance to operate on.
* @param x Horizontal coordinate of the center.
* @param y Vertical coordinate of the center.
* @param radius Circle radius in pixels.
* @param color Color to draw with.
* @param self The backend to draw through. Required, along with its
* `sdl_renderer`.
* @param x Horizontal position of the centre. Rounded to the nearest whole
* pixel -- the algorithm is integer-only.
* @param y Vertical position of the centre, rounded the same way.
* @param radius Radius in pixels, rounded to the nearest whole pixel. Must not
* be negative; 0 draws the centre pixel alone.
* @param color Colour to draw in, including alpha. The outline is one pixel
* wide and is not anti-aliased.
* @return `NULL` on success, otherwise an error context owned by the caller.
* @throws AKERR_NULLPOINTER When the corresponding validation or operation fails.
* @throws AKERR_OUTOFBOUNDS When the corresponding validation or operation fails.
* @throws AKGL_ERR_SDL When the corresponding validation or operation fails.
* @throws AKERR_NULLPOINTER If @p self or `self->sdl_renderer` is `NULL`.
* @throws AKERR_OUTOFBOUNDS If @p radius is negative. The message reports it.
* @throws AKGL_ERR_SDL If the draw colour cannot be read or set, or if any of
* the plotting passes fails. Failures inside the loop are recorded and
* reported once at the end rather than aborting mid-circle, so a partial
* arc may already be on the target.
*/
akerr_ErrorContext AKERR_NOIGNORE *akgl_draw_circle(akgl_RenderBackend *self, float32_t x, float32_t y, float32_t radius, SDL_Color color);
@@ -121,14 +152,30 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_draw_circle(akgl_RenderBackend *self, fl
* Filling a region that already holds @p color is a no-op rather than an error.
* A seed outside the render target reports AKERR_OUTOFBOUNDS.
*
* @param self Backend or object instance to operate on.
* @param x Horizontal coordinate of the seed pixel.
* @param y Vertical coordinate of the seed pixel.
* @param color Color to fill with.
* The region is four-connected -- it spreads up, down, left and right, not
* diagonally -- and its boundary is any pixel whose colour differs from the
* seed's, exactly. There is no tolerance, so an anti-aliased edge stops the fill
* at its first blended pixel and leaves a fringe.
*
* @param self The backend to draw through. Required, along with its
* `sdl_renderer`.
* @param x Horizontal position of the seed pixel, in render-target pixels.
* Must be inside the target.
* @param y Vertical position of the seed pixel.
* @param color Colour to fill with. Written over the region rather than blended,
* since the pixels going back are the ones just read out.
* @return `NULL` on success, otherwise an error context owned by the caller.
* @throws AKERR_NULLPOINTER When the corresponding validation or operation fails.
* @throws AKERR_OUTOFBOUNDS When the corresponding validation or operation fails.
* @throws AKGL_ERR_SDL When the corresponding validation or operation fails.
* @throws AKERR_NULLPOINTER If @p self or `self->sdl_renderer` is `NULL`.
* @throws AKERR_OUTOFBOUNDS If the seed is outside the render target -- the
* message reports both the seed and the target size -- or if the region
* needs more than #AKGL_DRAW_MAX_FLOOD_SPANS pending spans, in which
* case **it is left partially filled**.
* @throws AKGL_ERR_SDL If the render target cannot be read back, converted,
* uploaded, or blitted.
*
* @warning Not reentrant, and not safe from two threads: the span stack is a
* single file-scope array. Nothing that touches an `SDL_Renderer` is
* thread-safe either way.
*/
akerr_ErrorContext AKERR_NOIGNORE *akgl_draw_flood_fill(akgl_RenderBackend *self, int x, int y, SDL_Color color);
@@ -141,13 +188,23 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_draw_flood_fill(akgl_RenderBackend *self
* @p src's dimensions the pixels are copied into it instead, so a caller
* saving the same region repeatedly does not churn allocations.
*
* @param self Backend or object instance to operate on.
* @param src Rectangle of the render target to read.
* @param dest Output destination populated by the function.
* @param self The backend to read from. Required, along with its `sdl_renderer`.
* @param src Rectangle of the render target to read, in pixels. Required. It
* must fit *entirely* inside the target: SDL would otherwise clip
* the read and hand back a smaller surface than was asked for, which
* a caller pasting it back would not notice.
* @param dest Address of the destination surface. Required, and `*dest` must be
* initialized -- `NULL` to have one allocated (the caller then owns
* it and frees it with `SDL_DestroySurface`), or an existing surface
* of exactly @p src's dimensions to reuse.
* @return `NULL` on success, otherwise an error context owned by the caller.
* @throws AKERR_NULLPOINTER When the corresponding validation or operation fails.
* @throws AKERR_OUTOFBOUNDS When the corresponding validation or operation fails.
* @throws AKGL_ERR_SDL When the corresponding validation or operation fails.
* @throws AKERR_NULLPOINTER If @p self, `self->sdl_renderer`, @p src, or @p dest
* is `NULL`.
* @throws AKERR_OUTOFBOUNDS If @p src has no area, if it does not fit inside the
* render target, or if a supplied `*dest` is a different size from
* @p src. Each message reports both sets of dimensions.
* @throws AKGL_ERR_SDL If the target size cannot be queried, the pixels cannot
* be read, or the copy into a supplied `*dest` fails.
*/
akerr_ErrorContext AKERR_NOIGNORE *akgl_draw_copy_region(akgl_RenderBackend *self, SDL_Rect *src, SDL_Surface **dest);
@@ -158,13 +215,21 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_draw_copy_region(akgl_RenderBackend *sel
* produced. The surface is not consumed and may be pasted as many times as the
* caller likes.
*
* @param self Backend or object instance to operate on.
* @param src Surface to draw.
* @param x Horizontal destination coordinate.
* @param y Vertical destination coordinate.
* @param self The backend to draw through. Required, along with its
* `sdl_renderer`.
* @param src The surface to paste. Required. Drawn at its own size -- there is
* no scaling -- and *replacing* what is on the target rather than
* blending with it, which is GSHAPE's default behaviour and means a
* saved region's transparent pixels come back as transparent rather
* than letting the background show through.
* @param x Horizontal position of the paste's left edge.
* @param y Vertical position of its top edge. Parts falling outside the
* target are clipped by SDL, not reported.
* @return `NULL` on success, otherwise an error context owned by the caller.
* @throws AKERR_NULLPOINTER When the corresponding validation or operation fails.
* @throws AKGL_ERR_SDL When the corresponding validation or operation fails.
* @throws AKERR_NULLPOINTER If @p self, `self->sdl_renderer`, or @p src is
* `NULL`.
* @throws AKGL_ERR_SDL If the surface cannot be uploaded as a texture, its blend
* mode cannot be set, or the draw fails.
*/
akerr_ErrorContext AKERR_NOIGNORE *akgl_draw_paste_region(akgl_RenderBackend *self, SDL_Surface *src, float32_t x, float32_t y);