Consume libakstdlib 0.2.0
Pass fixed buffer sizes to the bounded formatting and realpath wrappers. Route save-game records through exact-transfer helpers so the required fread/fwrite count parameter stays local to the complete-record contract. Co-Authored-By: Codex GPT-5 <noreply@openai.com>
This commit is contained in:
54
src/game.c
54
src/game.c
@@ -43,6 +43,20 @@ MIX_Mixer *akgl_mixer = NULL;
|
||||
MIX_Track *akgl_tracks[AKGL_GAME_AUDIO_MAX_TRACKS];
|
||||
akgl_Game game;
|
||||
|
||||
static akerr_ErrorContext *write_exact(const void *ptr, size_t size, size_t nmemb, FILE *fp)
|
||||
{
|
||||
size_t transferred;
|
||||
|
||||
return aksl_fwrite(ptr, size, nmemb, fp, &transferred);
|
||||
}
|
||||
|
||||
static akerr_ErrorContext *read_exact(void *ptr, size_t size, size_t nmemb, FILE *fp)
|
||||
{
|
||||
size_t transferred;
|
||||
|
||||
return aksl_fread(ptr, size, nmemb, fp, &transferred);
|
||||
}
|
||||
|
||||
void akgl_game_lowfps(void)
|
||||
{
|
||||
SDL_Log("Low FPS! %d", game.fps);
|
||||
@@ -188,9 +202,9 @@ void akgl_game_save_actorname_iterator(void *userdata, SDL_PropertiesID props, c
|
||||
PREPARE_ERROR(e);
|
||||
ATTEMPT {
|
||||
FAIL_ZERO_BREAK(e, fp, AKERR_NULLPOINTER, "NULL file pointer");
|
||||
CATCH(e, aksl_fwrite((char *)name, 1, AKGL_ACTOR_MAX_NAME_LENGTH, fp));
|
||||
CATCH(e, write_exact((char *)name, 1, AKGL_ACTOR_MAX_NAME_LENGTH, fp));
|
||||
actor = SDL_GetPointerProperty(props, name, NULL);
|
||||
CATCH(e, aksl_fwrite(&actor, 1, sizeof(akgl_Actor *), fp));
|
||||
CATCH(e, write_exact(&actor, 1, sizeof(akgl_Actor *), fp));
|
||||
} CLEANUP {
|
||||
} PROCESS(e) {
|
||||
} FINISH_NORETURN(e);
|
||||
@@ -210,8 +224,8 @@ void akgl_game_save_spritename_iterator(void *userdata, SDL_PropertiesID props,
|
||||
ATTEMPT {
|
||||
FAIL_ZERO_BREAK(e, fp, AKERR_NULLPOINTER, "NULL file pointer");
|
||||
sprite = SDL_GetPointerProperty(props, name, NULL);
|
||||
CATCH(e, aksl_fwrite((char *)name, 1, AKGL_SPRITE_MAX_NAME_LENGTH, fp));
|
||||
CATCH(e, aksl_fwrite(&sprite, 1, sizeof(akgl_Sprite *), fp));
|
||||
CATCH(e, write_exact((char *)name, 1, AKGL_SPRITE_MAX_NAME_LENGTH, fp));
|
||||
CATCH(e, write_exact(&sprite, 1, sizeof(akgl_Sprite *), fp));
|
||||
} CLEANUP {
|
||||
} PROCESS(e) {
|
||||
} FINISH_NORETURN(e);
|
||||
@@ -231,8 +245,8 @@ void akgl_game_save_spritesheetname_iterator(void *userdata, SDL_PropertiesID pr
|
||||
ATTEMPT {
|
||||
FAIL_ZERO_BREAK(e, fp, AKERR_NULLPOINTER, "NULL file pointer");
|
||||
spritesheet = SDL_GetPointerProperty(props, name, NULL);
|
||||
CATCH(e, aksl_fwrite((char *)name, 1, AKGL_SPRITE_SHEET_MAX_FILENAME_LENGTH, fp));
|
||||
CATCH(e, aksl_fwrite(&spritesheet, 1, sizeof(akgl_SpriteSheet *), fp));
|
||||
CATCH(e, write_exact((char *)name, 1, AKGL_SPRITE_SHEET_MAX_FILENAME_LENGTH, fp));
|
||||
CATCH(e, write_exact(&spritesheet, 1, sizeof(akgl_SpriteSheet *), fp));
|
||||
} CLEANUP {
|
||||
} PROCESS(e) {
|
||||
} FINISH_NORETURN(e);
|
||||
@@ -252,8 +266,8 @@ void akgl_game_save_charactername_iterator(void *userdata, SDL_PropertiesID prop
|
||||
ATTEMPT {
|
||||
FAIL_ZERO_BREAK(e, fp, AKERR_NULLPOINTER, "NULL file pointer");
|
||||
character = SDL_GetPointerProperty(props, name, NULL);
|
||||
CATCH(e, aksl_fwrite((char *)name, 1, AKGL_SPRITE_MAX_CHARACTER_NAME_LENGTH, fp));
|
||||
CATCH(e, aksl_fwrite(&character, 1, sizeof(akgl_Character *), fp));
|
||||
CATCH(e, write_exact((char *)name, 1, AKGL_SPRITE_MAX_CHARACTER_NAME_LENGTH, fp));
|
||||
CATCH(e, write_exact(&character, 1, sizeof(akgl_Character *), fp));
|
||||
} CLEANUP {
|
||||
} PROCESS(e) {
|
||||
} FINISH_NORETURN(e);
|
||||
@@ -286,29 +300,29 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_game_save_actors(FILE *fp)
|
||||
AKGL_REGISTRY_ACTOR,
|
||||
&akgl_game_save_actorname_iterator,
|
||||
(void *)fp);
|
||||
CATCH(e, aksl_fwrite((void *)&nullbuf, 1, AKGL_ACTOR_MAX_NAME_LENGTH, fp));
|
||||
CATCH(e, aksl_fwrite((void *)&nullbuf, 1, sizeof(akgl_Actor *), fp));
|
||||
CATCH(e, write_exact((void *)&nullbuf, 1, AKGL_ACTOR_MAX_NAME_LENGTH, fp));
|
||||
CATCH(e, write_exact((void *)&nullbuf, 1, sizeof(akgl_Actor *), fp));
|
||||
// write the sprite name pointer table
|
||||
SDL_EnumerateProperties(
|
||||
AKGL_REGISTRY_SPRITE,
|
||||
&akgl_game_save_spritename_iterator,
|
||||
(void *)fp);
|
||||
CATCH(e, aksl_fwrite((void *)&nullbuf, 1, AKGL_SPRITE_MAX_NAME_LENGTH, fp));
|
||||
CATCH(e, aksl_fwrite((void *)&nullbuf, 1, sizeof(akgl_Sprite *), fp));
|
||||
CATCH(e, write_exact((void *)&nullbuf, 1, AKGL_SPRITE_MAX_NAME_LENGTH, fp));
|
||||
CATCH(e, write_exact((void *)&nullbuf, 1, sizeof(akgl_Sprite *), fp));
|
||||
// write the spritesheet name pointer table
|
||||
SDL_EnumerateProperties(
|
||||
AKGL_REGISTRY_SPRITESHEET,
|
||||
&akgl_game_save_spritesheetname_iterator,
|
||||
(void *)fp);
|
||||
CATCH(e, aksl_fwrite((void *)&nullbuf, 1, AKGL_SPRITE_SHEET_MAX_FILENAME_LENGTH, fp));
|
||||
CATCH(e, aksl_fwrite((void *)&nullbuf, 1, sizeof(akgl_SpriteSheet *), fp));
|
||||
CATCH(e, write_exact((void *)&nullbuf, 1, AKGL_SPRITE_SHEET_MAX_FILENAME_LENGTH, fp));
|
||||
CATCH(e, write_exact((void *)&nullbuf, 1, sizeof(akgl_SpriteSheet *), fp));
|
||||
// write the character name pointer table
|
||||
SDL_EnumerateProperties(
|
||||
AKGL_REGISTRY_CHARACTER,
|
||||
&akgl_game_save_charactername_iterator,
|
||||
(void *)fp);
|
||||
CATCH(e, aksl_fwrite((void *)&nullbuf, 1, AKGL_SPRITE_MAX_CHARACTER_NAME_LENGTH, fp));
|
||||
CATCH(e, aksl_fwrite((void *)&nullbuf, 1, sizeof(akgl_Character *), fp));
|
||||
CATCH(e, write_exact((void *)&nullbuf, 1, AKGL_SPRITE_MAX_CHARACTER_NAME_LENGTH, fp));
|
||||
CATCH(e, write_exact((void *)&nullbuf, 1, sizeof(akgl_Character *), fp));
|
||||
} CLEANUP {
|
||||
} PROCESS(e) {
|
||||
} FINISH(e, true);
|
||||
@@ -323,7 +337,7 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_game_save(char *fpath)
|
||||
ATTEMPT {
|
||||
FAIL_ZERO_BREAK(e, fpath, AKERR_NULLPOINTER, "NULL file path");
|
||||
CATCH(e, aksl_fopen(fpath, "wb", &fp));
|
||||
CATCH(e, aksl_fwrite(&game, 1, sizeof(akgl_Game), fp));
|
||||
CATCH(e, write_exact(&game, 1, sizeof(akgl_Game), fp));
|
||||
CATCH(e, akgl_game_save_actors(fp));
|
||||
} CLEANUP {
|
||||
// CLEANUP must precede PROCESS: with the two transposed, the fclose
|
||||
@@ -363,8 +377,8 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_game_load_objectnamemap(FILE *fp, SDL_Pr
|
||||
// corrupt name table as a successful load.
|
||||
while ( done == false ) {
|
||||
ATTEMPT {
|
||||
CATCH(e, aksl_fread((void *)&objname, 1, namelength, fp));
|
||||
CATCH(e, aksl_fread((void *)&ptr, 1, ptrlength, fp));
|
||||
CATCH(e, read_exact((void *)&objname, 1, namelength, fp));
|
||||
CATCH(e, read_exact((void *)&ptr, 1, ptrlength, fp));
|
||||
// End of the map
|
||||
if ( ptr == 0x00 && objname[0] == 0x00 ) {
|
||||
done = true;
|
||||
@@ -456,7 +470,7 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_game_load(char *fpath)
|
||||
|
||||
ATTEMPT {
|
||||
CATCH(e, aksl_fopen(fpath, "rb", &fp));
|
||||
CATCH(e, aksl_fread((void *)&savegame, 1, sizeof(akgl_Game), fp));
|
||||
CATCH(e, read_exact((void *)&savegame, 1, sizeof(akgl_Game), fp));
|
||||
CATCH(e, akgl_game_load_versioncmp("library", (char *)&savegame.libversion, (char *)AKGL_VERSION));
|
||||
CATCH(e, akgl_game_load_versioncmp("game", (char *)&savegame.version, (char *)&game.version));
|
||||
FAIL_NONZERO_RETURN(
|
||||
|
||||
Reference in New Issue
Block a user