From 8f613397d6013578f9a1e9421edb952e1a3aa034 Mon Sep 17 00:00:00 2001 From: Andrew Kesterson Date: Sun, 24 May 2026 19:57:43 -0400 Subject: [PATCH] Loading sprites and tiles both work correctly with relative paths, now using akgl_path_relative* helpers --- include/akgl/SDL_GameControllerDB.h | 2 +- src/sprite.c | 7 +--- src/staticstring.c | 2 +- src/tilemap.c | 62 ++++++++++++++--------------- src/util.c | 16 ++++++++ 5 files changed, 51 insertions(+), 38 deletions(-) diff --git a/include/akgl/SDL_GameControllerDB.h b/include/akgl/SDL_GameControllerDB.h index fbfd383..f2ee080 100644 --- a/include/akgl/SDL_GameControllerDB.h +++ b/include/akgl/SDL_GameControllerDB.h @@ -1,7 +1,7 @@ #ifndef _SDL_GAMECONTROLLERDB_H_ #define _SDL_GAMECONTROLLERDB_H_ -// Taken from https://raw.githubusercontent.com/mdqinc/SDL_GameControllerDB/refs/heads/master/gamecontrollerdb.txt on Sun May 24 09:44:15 AM EDT 2026 +// Taken from https://raw.githubusercontent.com/mdqinc/SDL_GameControllerDB/refs/heads/master/gamecontrollerdb.txt on Sun May 24 07:53:58 PM EDT 2026 #define AKGL_SDL_GAMECONTROLLER_DB_LEN 2228 diff --git a/src/sprite.c b/src/sprite.c index aa66309..800eccb 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -12,6 +12,7 @@ #include #include #include +#include akerr_ErrorContext *akgl_sprite_sheet_coords_for_frame(akgl_Sprite *self, SDL_FRect *srccoords, uint8_t frameid) { @@ -48,11 +49,7 @@ static akerr_ErrorContext *akgl_sprite_load_json_spritesheet(json_t *json, akgl_ CATCH(errctx, akgl_string_initialize(tmpstr, NULL)); CATCH(errctx, akgl_get_json_object_value((json_t *)json, "spritesheet", &spritesheet_json)); CATCH(errctx, akgl_get_json_string_value((json_t *)spritesheet_json, "filename", &ss_filename)); - if ( ss_filename->data[0] != '/' ) { - SDL_snprintf((char *)&tmpstr->data, AKGL_MAX_STRING_LENGTH, "%s/%s", relative_path, ss_filename->data); - } else { - SDL_snprintf((char *)&tmpstr->data, AKGL_MAX_STRING_LENGTH, "%s", ss_filename->data); - } + CATCH(errctx, akgl_path_relative(relative_path, ss_filename->data, tmpstr)); *sheet = SDL_GetPointerProperty( AKGL_REGISTRY_SPRITESHEET, (char *)&tmpstr->data, diff --git a/src/staticstring.c b/src/staticstring.c index 5c85fe6..a91f59f 100644 --- a/src/staticstring.c +++ b/src/staticstring.c @@ -23,7 +23,7 @@ akerr_ErrorContext *akgl_string_copy(akgl_String *src, akgl_String *dst, int cou if ( count == 0 ) { count = AKGL_MAX_STRING_LENGTH; } - if ( (char *)dst->data != strncpy((char *)&src->data, (char *)&dst->data, count) ) { + if ( (char *)dst->data != strncpy((char *)&dst->data, (char *)&src->data, count) ) { FAIL_RETURN(e, errno, "strncpy"); } SUCCEED_RETURN(e); diff --git a/src/tilemap.c b/src/tilemap.c index 59a30d8..e98ef15 100644 --- a/src/tilemap.c +++ b/src/tilemap.c @@ -16,7 +16,7 @@ #include #include #include - +#include akerr_ErrorContext *akgl_get_json_tilemap_property(json_t *obj, char *key, char *type, json_t **dest) { @@ -103,43 +103,42 @@ akerr_ErrorContext *akgl_get_json_properties_number(json_t *obj, char *key, floa akerr_ErrorContext *akgl_tilemap_load_tilesets_each(json_t *tileset, akgl_Tilemap *dest, int tsidx, akgl_String *dirname) { - PREPARE_ERROR(errctx); + PREPARE_ERROR(e); akgl_String *tmpstr = NULL; + akgl_String *tmppath = NULL; + + PASS(e, akgl_get_json_integer_value((json_t *)tileset, "columns", &dest->tilesets[tsidx].columns)); + PASS(e, akgl_get_json_integer_value((json_t *)tileset, "firstgid", &dest->tilesets[tsidx].firstgid)); + PASS(e, akgl_get_json_integer_value((json_t *)tileset, "imageheight", &dest->tilesets[tsidx].imageheight)); + PASS(e, akgl_get_json_integer_value((json_t *)tileset, "imagewidth", &dest->tilesets[tsidx].imagewidth)); + PASS(e, akgl_get_json_integer_value((json_t *)tileset, "margin", &dest->tilesets[tsidx].margin)); + PASS(e, akgl_get_json_integer_value((json_t *)tileset, "spacing", &dest->tilesets[tsidx].spacing)); + PASS(e, akgl_get_json_integer_value((json_t *)tileset, "tilecount", &dest->tilesets[tsidx].tilecount)); + PASS(e, akgl_get_json_integer_value((json_t *)tileset, "tileheight", &dest->tilesets[tsidx].tileheight)); + PASS(e, akgl_get_json_integer_value((json_t *)tileset, "tilewidth", &dest->tilesets[tsidx].tilewidth)); + + PASS(e, akgl_get_json_string_value((json_t *)tileset, "name", &tmpstr)); + PASS(e, akgl_heap_next_string(&tmpstr)); + PASS(e, akgl_heap_next_string(&tmppath)); ATTEMPT { - CATCH(errctx, akgl_get_json_integer_value((json_t *)tileset, "columns", &dest->tilesets[tsidx].columns)); - CATCH(errctx, akgl_get_json_integer_value((json_t *)tileset, "firstgid", &dest->tilesets[tsidx].firstgid)); - CATCH(errctx, akgl_get_json_integer_value((json_t *)tileset, "imageheight", &dest->tilesets[tsidx].imageheight)); - CATCH(errctx, akgl_get_json_integer_value((json_t *)tileset, "imagewidth", &dest->tilesets[tsidx].imagewidth)); - CATCH(errctx, akgl_get_json_integer_value((json_t *)tileset, "margin", &dest->tilesets[tsidx].margin)); - CATCH(errctx, akgl_get_json_integer_value((json_t *)tileset, "spacing", &dest->tilesets[tsidx].spacing)); - CATCH(errctx, akgl_get_json_integer_value((json_t *)tileset, "tilecount", &dest->tilesets[tsidx].tilecount)); - CATCH(errctx, akgl_get_json_integer_value((json_t *)tileset, "tileheight", &dest->tilesets[tsidx].tileheight)); - CATCH(errctx, akgl_get_json_integer_value((json_t *)tileset, "tilewidth", &dest->tilesets[tsidx].tilewidth)); - - CATCH(errctx, akgl_get_json_string_value((json_t *)tileset, "name", &tmpstr)); strncpy((char *)&dest->tilesets[tsidx].name, (char *)&tmpstr->data, AKGL_TILEMAP_MAX_TILESET_NAME_SIZE ); - - CATCH(errctx, akgl_get_json_string_value((json_t *)tileset, "image", &tmpstr)); - - DISABLE_GCC_WARNING_FORMAT_TRUNCATION - snprintf((char *)&dest->tilesets[tsidx].imagefilename, - AKGL_TILEMAP_MAX_TILESET_FILENAME_SIZE, - "%s/%s", - dirname->data, - tmpstr->data - ); - RESTORE_GCC_WARNINGS - - dest->tilesets[tsidx].texture = IMG_LoadTexture(renderer, (char *)&dest->tilesets[tsidx].imagefilename); - FAIL_ZERO_BREAK(errctx, dest->tilesets[tsidx].texture, AKERR_NULLPOINTER, "Failed loading tileset image : %s", SDL_GetError()); - } CLEANUP { - } PROCESS(errctx) { - } FINISH(errctx, true); - SUCCEED_RETURN(errctx); + CATCH(e, akgl_get_json_string_value((json_t *)tileset, "image", &tmpstr)); + CATCH(e, akgl_path_relative((char *)&dirname->data, (char *)&tmpstr->data, tmppath)); + strncpy((char *)&dest->tilesets[tsidx].imagefilename, tmppath->data, AKGL_MAX_STRING_LENGTH); + } CLEANUP { + IGNORE(akgl_heap_release_string(tmpstr)); + IGNORE(akgl_heap_release_string(tmppath)); + } PROCESS(e) { + } FINISH(e, true); + + dest->tilesets[tsidx].texture = IMG_LoadTexture(renderer, (char *)&dest->tilesets[tsidx].imagefilename); + FAIL_ZERO_RETURN(e, dest->tilesets[tsidx].texture, AKERR_NULLPOINTER, "Failed loading tileset image : %s", SDL_GetError()); + + SUCCEED_RETURN(e); } akerr_ErrorContext *akgl_tilemap_compute_tileset_offsets(akgl_Tilemap *dest, int tilesetidx) @@ -457,6 +456,7 @@ akerr_ErrorContext *akgl_tilemap_load(char *fname, akgl_Tilemap *dest) //SDL_snprintf(tmpstr->data, AKGL_MAX_STRING_LENGTH, "%s%s", SDL_GetBasePath(), fname); CATCH(errctx, aksl_realpath(fname, (char *)&dirnamestr->data)); dirname((char *)&dirnamestr->data); + json = json_load_file(fname, 0, &error); FAIL_ZERO_BREAK( errctx, diff --git a/src/util.c b/src/util.c index 93763a6..7e7b674 100644 --- a/src/util.c +++ b/src/util.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -38,7 +39,9 @@ akerr_ErrorContext *akgl_path_relative_root(char *root, char *path, akgl_String if ( (rootlen + pathlen) >= AKGL_MAX_STRING_LENGTH ) { FAIL_RETURN(e, AKERR_OUTOFBOUNDS, "Total path length (%d) is greater than maximum akgl_String length (%d)", (rootlen + pathlen), AKGL_MAX_STRING_LENGTH); } + DISABLE_GCC_WARNING_FORMAT_TRUNCATION CATCH(e, aksl_sprintf(&count, (char *)&pathbuf->data, "%s/%s", root, path)); + RESTORE_GCC_WARNINGS CATCH(e, aksl_realpath((char *)&pathbuf->data, (char *)&strbuf->data)); CATCH(e, akgl_string_copy(strbuf, dst, 0)); } CLEANUP { @@ -77,6 +80,19 @@ akerr_ErrorContext *akgl_path_relative(char *root, char *path, akgl_String *dst) SUCCEED_RETURN(e); } +akerr_ErrorContext *akgl_path_relative_from(char *path, char *from, akgl_String **dst) +{ + akgl_String *dirnamestr; + PREPARE_ERROR(e); + FAIL_ZERO_RETURN(e, path, AKERR_NULLPOINTER, "path"); + FAIL_ZERO_RETURN(e, from, AKERR_NULLPOINTER, "from"); + PASS(e, akgl_heap_next_string(&dirnamestr)); + PASS(e, aksl_realpath(from, (char *)&dirnamestr->data)); + dirname((char *)&dirnamestr->data); + + SUCCEED_RETURN(e); +} + akerr_ErrorContext *akgl_rectangle_points(RectanglePoints *dest, SDL_FRect *rect) { PREPARE_ERROR(errctx);