2026-07-30 01:10:31 -04:00
/**
* @ file renderer . h
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>
2026-07-31 11:02:20 -04:00
* @ brief The pluggable rendering backend : a record of function pointers plus an initializer .
*
* There is one backend shipped , the 2 D SDL one , and ` akgl_render_init2d ` is its
* initializer - - it creates the window and the ` SDL_Renderer ` and then fills in
* the six ` akgl_render_2d_ * ` entry points . A different renderer is a different
* initializer populating the same struct , not a branch inside these functions .
*
* Callers do not normally name the ` akgl_render_2d_ * ` functions directly ; they
* go through the pointers on the backend ( ` renderer - > frame_start ( renderer ) ` ) ,
* which is what makes the swap possible . The global ` renderer ` in game . h is the
* instance the rest of the library draws through .
*
* A frame is ` frame_start ` ( clear ) , any number of ` draw_ * ` calls , then
* ` frame_end ` ( present ) .
2026-07-30 01:10:31 -04:00
*/
2026-05-24 21:59:29 -04:00
# ifndef _RENDERER_H_
# define _RENDERER_H_
# include <SDL3/SDL.h>
# include <akerror.h>
2026-05-25 21:29:18 -04:00
# include <akgl/iterator.h>
2026-07-30 01:10:31 -04:00
/** @brief Defines a pluggable renderer backend and drawing callbacks. */
2026-05-24 21:59:29 -04:00
typedef struct akgl_RenderBackend {
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>
2026-07-31 11:02:20 -04:00
SDL_Renderer * sdl_renderer ; /**< The SDL renderer, created by the initializer. Owned by SDL, not freed here. */
akerr_ErrorContext AKERR_NOIGNORE * ( * shutdown ) ( struct akgl_RenderBackend * self ) ; /**< Tear the backend down. */
akerr_ErrorContext AKERR_NOIGNORE * ( * frame_start ) ( struct akgl_RenderBackend * self ) ; /**< Begin a frame: clear the target. */
akerr_ErrorContext AKERR_NOIGNORE * ( * frame_end ) ( struct akgl_RenderBackend * self ) ; /**< End a frame: present it. */
akerr_ErrorContext AKERR_NOIGNORE * ( * draw_texture ) ( struct akgl_RenderBackend * self , SDL_Texture * texture , SDL_FRect * src , SDL_FRect * dest , double angle , SDL_FPoint * center , SDL_FlipMode flip ) ; /**< Blit one texture. */
akerr_ErrorContext AKERR_NOIGNORE * ( * draw_mesh ) ( struct akgl_RenderBackend * self ) ; /**< Reserved for a 3D backend; the 2D one refuses. */
akerr_ErrorContext AKERR_NOIGNORE * ( * draw_world ) ( struct akgl_RenderBackend * self , akgl_Iterator * opflags ) ; /**< Draw the whole scene, layer by layer. */
2026-05-24 21:59:29 -04:00
} akgl_RenderBackend ;
2026-07-30 01:10:31 -04:00
/**
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>
2026-07-31 11:02:20 -04:00
* @ brief Tear the 2 D backend down .
*
* A no - op placeholder that always succeeds . The window and ` SDL_Renderer ` this
* backend created are still owned by SDL and are reclaimed by ` SDL_Quit ` , so
* there is nothing here to release yet ; the hook exists so a backend that * does *
* own resources has somewhere to free them .
*
* @ param self The backend to shut down . Ignored - - not even dereferenced , so
* ` NULL ` is currently harmless .
* @ return ` NULL ` always . It has no failure path today ; check it anyway , because
* a backend that acquires anything will grow one .
2026-07-30 01:10:31 -04:00
*/
2026-05-24 21:59:29 -04:00
akerr_ErrorContext AKERR_NOIGNORE * akgl_render_2d_shutdown ( akgl_RenderBackend * self ) ;
2026-07-30 01:10:31 -04:00
/**
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>
2026-07-31 11:02:20 -04:00
* @ brief Begin a frame : clear the render target to opaque black .
* @ param self The backend to draw through . Required , and dereferenced * before *
* it is checked - - a ` NULL ` @ p self is a crash , not an error .
2026-07-30 01:10:31 -04:00
* @ return ` NULL ` on success , otherwise an error context owned by the caller .
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>
2026-07-31 11:02:20 -04:00
* @ throws AKERR_NULLPOINTER If ` self - > sdl_renderer ` is ` NULL ` , which means the
* backend was never run through akgl_render_init2d .
2026-07-30 01:10:31 -04:00
*/
2026-05-24 21:59:29 -04:00
akerr_ErrorContext AKERR_NOIGNORE * akgl_render_2d_frame_start ( akgl_RenderBackend * self ) ;
2026-07-30 01:10:31 -04:00
/**
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>
2026-07-31 11:02:20 -04:00
* @ brief End a frame : present everything drawn since akgl_render_2d_frame_start .
* @ param self The backend to draw through . Required , and dereferenced * before *
* it is checked - - a ` NULL ` @ p self is a crash , not an error .
2026-07-30 01:10:31 -04:00
* @ return ` NULL ` on success , otherwise an error context owned by the caller .
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>
2026-07-31 11:02:20 -04:00
* @ throws AKERR_NULLPOINTER If ` self - > sdl_renderer ` is ` NULL ` , which means the
* backend was never run through akgl_render_init2d .
2026-07-30 01:10:31 -04:00
*/
2026-05-24 21:59:29 -04:00
akerr_ErrorContext AKERR_NOIGNORE * akgl_render_2d_frame_end ( akgl_RenderBackend * self ) ;
2026-07-30 01:10:31 -04:00
/**
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>
2026-07-31 11:02:20 -04:00
* @ brief Blit a texture , rotating it only when asked to .
*
* A rotation of exactly 0 takes the plain ` SDL_RenderTexture ` path , which is why
* @ p center and @ p flip are only consulted when @ p angle is non - zero .
*
* @ param self The backend to draw through . Required .
* @ param texture The texture to blit . Required .
* @ param src The rectangle of @ p texture to take , in pixels . Optional - -
* ` NULL ` means the whole texture .
* @ param dest Where to put it on the render target , in pixels . Optional - -
* ` NULL ` means stretch to fill the whole target . Not an output
* parameter despite the name .
* @ param angle Clockwise rotation in degrees . Exactly 0 skips rotation
* entirely , along with @ p center and @ p flip .
* @ param center Pivot for the rotation , relative to @ p dest . Required * when *
* @ p angle is non - zero , ignored otherwise . SDL ' s own " NULL means
* the centre of dest " convention is not available here.
* @ param flip Horizontal / vertical mirroring . Applied only on the rotated
* path ; ignored when @ p angle is 0.
2026-07-30 01:10:31 -04:00
* @ return ` NULL ` on success , otherwise an error context owned by the caller .
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>
2026-07-31 11:02:20 -04:00
* @ throws AKERR_NULLPOINTER If @ p self or @ p texture is ` NULL ` ; if @ p angle is
* non - zero and @ p center is ` NULL ` ; or if the SDL draw call itself
* fails , in which case the message carries ` SDL_GetError ( ) ` . That last
* case is a reused status rather than a pointer problem .
2026-07-30 01:10:31 -04:00
*/
2026-05-24 21:59:29 -04:00
akerr_ErrorContext AKERR_NOIGNORE * akgl_render_2d_draw_texture ( akgl_RenderBackend * self , SDL_Texture * texture , SDL_FRect * src , SDL_FRect * dest , double angle , SDL_FPoint * center , SDL_FlipMode flip ) ;
2026-07-30 01:10:31 -04:00
/**
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>
2026-07-31 11:02:20 -04:00
* @ brief Draw geometry . Not implemented by the 2 D backend .
*
* The hook exists so a 3 D backend has a slot to fill ; this one refuses every
* call . It is not a stub that quietly does nothing - - it fails loudly , so a
* caller that reaches it finds out at once .
*
* @ param self The backend . Ignored .
* @ return Never ` NULL ` .
* @ throws AKERR_API Always , with the message " Not implemented " .
2026-07-30 01:10:31 -04:00
*/
2026-05-24 21:59:29 -04:00
akerr_ErrorContext AKERR_NOIGNORE * akgl_render_2d_draw_mesh ( akgl_RenderBackend * self ) ;
2026-07-30 01:10:31 -04:00
/**
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>
2026-07-31 11:02:20 -04:00
* @ brief Draw the whole scene : every tilemap layer , and the actors standing on it .
*
* Walks layers from 0 to # AKGL_TILEMAP_MAX_LAYERS . For each , it draws that layer
* of the global ` gamemap ` through ` camera ` ( if the map has that many layers ) ,
* then sweeps the actor pool and calls ` renderfunc ` on every live actor whose
* ` layer ` matches . Sweeping in layer order is what puts actors in front of the
* scenery they stand on and behind the scenery they walk under .
*
* It reads the globals ` gamemap ` , ` camera ` , and ` HEAP_ACTOR ` directly rather
* than taking them as arguments , so there is exactly one world to draw .
*
* @ param self The backend to draw through . Required .
* @ param opflags Iterator flags . Optional - - ` NULL ` substitutes a zeroed set .
* Currently ignored either way : this function sweeps the actor
* pool itself instead of going through
* akgl_registry_iterate_actor , so no ` AKGL_ITERATOR_OP_ * ` bit
* reaches anything . The parameter is here for the backend
* signature and for the layer - mask support that has yet to be
* wired up .
2026-07-30 01:10:31 -04:00
* @ return ` NULL ` on success , otherwise an error context owned by the caller .
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>
2026-07-31 11:02:20 -04:00
* @ throws AKERR_NULLPOINTER If @ p self is ` NULL ` .
* @ throws AKERR_ * Whatever akgl_tilemap_draw or an actor ' s own ` renderfunc `
* raises ; the first failure aborts the frame and propagates unchanged .
*
* @ warning Neither the global ` gamemap ` nor a live actor ' s ` renderfunc ` is
* checked before use , so drawing before akgl_tilemap_load , or with a
* hand - built actor that was never run through akgl_actor_initialize ,
* is a crash rather than an error context .
2026-07-30 01:10:31 -04:00
*/
2026-05-25 21:29:18 -04:00
akerr_ErrorContext AKERR_NOIGNORE * akgl_render_2d_draw_world ( akgl_RenderBackend * self , akgl_Iterator * opflags ) ;
2026-05-24 21:59:29 -04:00
2026-07-30 01:10:31 -04:00
/**
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>
2026-07-31 11:02:20 -04:00
* @ brief Create the window and SDL renderer , and bind the 2 D backend ' s methods .
*
* Reads ` game . screenwidth ` and ` game . screenheight ` from the property registry
* ( both defaulting to the string " 0 " , which asks SDL for a zero - sized window ) ,
* creates the window and renderer with ` game . uri ` as the title , points ` camera `
* at the full screen rectangle , and installs the six ` akgl_render_2d_ * ` function
* pointers on @ p self .
*
* Because the dimensions come from the registry , akgl_registry_init_properties
* and the property writes have to happen first - - see the note on
* akgl_registry_init about the properties registry not being initialized for
* callers that skip akgl_game_init .
*
* @ param self The backend to initialize . Required . Its ` sdl_renderer ` and method
* pointers are overwritten ; anything it held before is not released .
2026-07-30 01:10:31 -04:00
* @ return ` NULL ` on success , otherwise an error context owned by the caller .
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>
2026-07-31 11:02:20 -04:00
* @ throws AKERR_NULLPOINTER If @ p self is ` NULL ` .
* @ throws AKERR_VALUE If ` game . screenwidth ` or ` game . screenheight ` is set to
* something that is not a base - 10 integer .
* @ throws ERANGE If either dimension does not fit in an ` int ` .
* @ throws AKGL_ERR_SDL If the window and renderer cannot be created . The message
* carries ` SDL_GetError ( ) ` .
* @ throws AKGL_ERR_HEAP If the string pool is exhausted while reading the two
* properties .
*
* @ note The two pooled strings holding the dimensions are only released on the
* success path , so each failed initialization leaks two string slots .
2026-07-30 01:10:31 -04:00
*/
2026-05-24 21:59:29 -04:00
akerr_ErrorContext AKERR_NOIGNORE * akgl_render_init2d ( akgl_RenderBackend * self ) ;
# endif // _RENDERER_H_