Loading sprites and tiles both work correctly with relative paths, now using akgl_path_relative* helpers

This commit is contained in:
2026-05-24 19:57:43 -04:00
parent 980bbc56fb
commit 8f613397d6
5 changed files with 51 additions and 38 deletions

View File

@@ -1,7 +1,7 @@
#ifndef _SDL_GAMECONTROLLERDB_H_ #ifndef _SDL_GAMECONTROLLERDB_H_
#define _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 #define AKGL_SDL_GAMECONTROLLER_DB_LEN 2228

View File

@@ -12,6 +12,7 @@
#include <akgl/registry.h> #include <akgl/registry.h>
#include <akgl/staticstring.h> #include <akgl/staticstring.h>
#include <akgl/iterator.h> #include <akgl/iterator.h>
#include <akgl/util.h>
akerr_ErrorContext *akgl_sprite_sheet_coords_for_frame(akgl_Sprite *self, SDL_FRect *srccoords, uint8_t frameid) 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_string_initialize(tmpstr, NULL));
CATCH(errctx, akgl_get_json_object_value((json_t *)json, "spritesheet", &spritesheet_json)); 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)); CATCH(errctx, akgl_get_json_string_value((json_t *)spritesheet_json, "filename", &ss_filename));
if ( ss_filename->data[0] != '/' ) { CATCH(errctx, akgl_path_relative(relative_path, ss_filename->data, tmpstr));
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);
}
*sheet = SDL_GetPointerProperty( *sheet = SDL_GetPointerProperty(
AKGL_REGISTRY_SPRITESHEET, AKGL_REGISTRY_SPRITESHEET,
(char *)&tmpstr->data, (char *)&tmpstr->data,

View File

@@ -23,7 +23,7 @@ akerr_ErrorContext *akgl_string_copy(akgl_String *src, akgl_String *dst, int cou
if ( count == 0 ) { if ( count == 0 ) {
count = AKGL_MAX_STRING_LENGTH; 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"); FAIL_RETURN(e, errno, "strncpy");
} }
SUCCEED_RETURN(e); SUCCEED_RETURN(e);

View File

@@ -16,7 +16,7 @@
#include <akgl/registry.h> #include <akgl/registry.h>
#include <akgl/staticstring.h> #include <akgl/staticstring.h>
#include <akgl/game.h> #include <akgl/game.h>
#include <akgl/util.h>
akerr_ErrorContext *akgl_get_json_tilemap_property(json_t *obj, char *key, char *type, json_t **dest) 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) 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 *tmpstr = NULL;
ATTEMPT { akgl_String *tmppath = NULL;
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)); 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 {
strncpy((char *)&dest->tilesets[tsidx].name, strncpy((char *)&dest->tilesets[tsidx].name,
(char *)&tmpstr->data, (char *)&tmpstr->data,
AKGL_TILEMAP_MAX_TILESET_NAME_SIZE AKGL_TILEMAP_MAX_TILESET_NAME_SIZE
); );
CATCH(errctx, akgl_get_json_string_value((json_t *)tileset, "image", &tmpstr)); CATCH(e, akgl_get_json_string_value((json_t *)tileset, "image", &tmpstr));
CATCH(e, akgl_path_relative((char *)&dirname->data, (char *)&tmpstr->data, tmppath));
DISABLE_GCC_WARNING_FORMAT_TRUNCATION strncpy((char *)&dest->tilesets[tsidx].imagefilename, tmppath->data, AKGL_MAX_STRING_LENGTH);
snprintf((char *)&dest->tilesets[tsidx].imagefilename, } CLEANUP {
AKGL_TILEMAP_MAX_TILESET_FILENAME_SIZE, IGNORE(akgl_heap_release_string(tmpstr));
"%s/%s", IGNORE(akgl_heap_release_string(tmppath));
dirname->data, } PROCESS(e) {
tmpstr->data } FINISH(e, true);
);
RESTORE_GCC_WARNINGS
dest->tilesets[tsidx].texture = IMG_LoadTexture(renderer, (char *)&dest->tilesets[tsidx].imagefilename); 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()); FAIL_ZERO_RETURN(e, dest->tilesets[tsidx].texture, AKERR_NULLPOINTER, "Failed loading tileset image : %s", SDL_GetError());
} CLEANUP {
} PROCESS(errctx) {
} FINISH(errctx, true);
SUCCEED_RETURN(errctx); SUCCEED_RETURN(e);
} }
akerr_ErrorContext *akgl_tilemap_compute_tileset_offsets(akgl_Tilemap *dest, int tilesetidx) 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); //SDL_snprintf(tmpstr->data, AKGL_MAX_STRING_LENGTH, "%s%s", SDL_GetBasePath(), fname);
CATCH(errctx, aksl_realpath(fname, (char *)&dirnamestr->data)); CATCH(errctx, aksl_realpath(fname, (char *)&dirnamestr->data));
dirname((char *)&dirnamestr->data); dirname((char *)&dirnamestr->data);
json = json_load_file(fname, 0, &error); json = json_load_file(fname, 0, &error);
FAIL_ZERO_BREAK( FAIL_ZERO_BREAK(
errctx, errctx,

View File

@@ -1,6 +1,7 @@
#include <limits.h> #include <limits.h>
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
#include <libgen.h>
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <SDL3_image/SDL_image.h> #include <SDL3_image/SDL_image.h>
@@ -38,7 +39,9 @@ akerr_ErrorContext *akgl_path_relative_root(char *root, char *path, akgl_String
if ( (rootlen + pathlen) >= AKGL_MAX_STRING_LENGTH ) { 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); 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)); 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, aksl_realpath((char *)&pathbuf->data, (char *)&strbuf->data));
CATCH(e, akgl_string_copy(strbuf, dst, 0)); CATCH(e, akgl_string_copy(strbuf, dst, 0));
} CLEANUP { } CLEANUP {
@@ -77,6 +80,19 @@ akerr_ErrorContext *akgl_path_relative(char *root, char *path, akgl_String *dst)
SUCCEED_RETURN(e); 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) akerr_ErrorContext *akgl_rectangle_points(RectanglePoints *dest, SDL_FRect *rect)
{ {
PREPARE_ERROR(errctx); PREPARE_ERROR(errctx);