Files
libakgl/include/akgl/assets.h
Andrew Kesterson f0858b0d38 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:23:15 -04:00

45 lines
2.0 KiB
C

/**
* @file assets.h
* @brief Loads the game's startup assets into the global mixer and track table.
*/
#ifndef _ASSETS_H_
#define _ASSETS_H_
#include <akerror.h>
/**
* @brief Load a music file, bind it to the background-music track, and start it playing.
*
* Loads @p fname through `akgl_mixer`, creates a track for it, stores that track
* in `akgl_tracks[AKGL_GAME_AUDIO_TRACK_BGM]`, and starts playback. The loaded
* audio is also published as the global `bgm`. This is a *startup* helper: it
* assumes the mixer already exists, so `akgl_game_init` (or a bare
* `akgl_audio_init`) has to have run first, and it overwrites whatever the BGM
* track slot held without releasing it.
*
* Loading is deferred inside SDL_mixer (`MIX_LoadAudio(..., true)` predecodes),
* so a large file costs its decode time here rather than at first play.
*
* On any failure after the audio loads, the audio is destroyed again before the
* error is returned; the track, if one was created, is not.
*
* @param fname Path to a music file in any format SDL_mixer can open. Required.
* Used verbatim -- it is not resolved against `SDL_GetBasePath()`,
* so a relative path is relative to the process working directory.
* @return `NULL` on success, otherwise an error context owned by the caller.
* @throws AKERR_NULLPOINTER If @p fname is `NULL`, if SDL_mixer cannot load the
* file (missing, unreadable, or an unsupported format), or if it cannot
* allocate a track for it. The message carries `SDL_GetError()`.
* @throws AKGL_ERR_SDL If the loaded audio cannot be bound to the new track, or
* if playback fails to start.
*
* @note The infinite-loop request does not currently take effect:
* `MIX_PROP_PLAY_LOOPS_NUMBER` is set on property set 0, which is the
* "no properties" sentinel rather than a set this function owns, so the
* call is rejected and the music plays once.
*/
akerr_ErrorContext AKERR_NOIGNORE *akgl_load_start_bgm(char *fname);
#endif //_ASSETS_H_