Fixed loading of tilesets and images from tilemaps to correctly use relative paths. FPS has dropped dramatically on tilemap rendering - impact as much as 75% - and I think it has something to do with the string limits that had to be increased to make this work. Probably has to do with SDL string property hashing in the registry methods related to tilesets.
This commit is contained in:
@@ -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 Thu May 21 09:41:48 PM EDT 2026
|
// Taken from https://raw.githubusercontent.com/mdqinc/SDL_GameControllerDB/refs/heads/master/gamecontrollerdb.txt on Sun May 24 09:44:15 AM EDT 2026
|
||||||
|
|
||||||
#define AKGL_SDL_GAMECONTROLLER_DB_LEN 2228
|
#define AKGL_SDL_GAMECONTROLLER_DB_LEN 2228
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,17 @@
|
|||||||
#ifndef _ERROR_H_
|
#ifndef _ERROR_H_
|
||||||
#define _ERROR_H_
|
#define _ERROR_H_
|
||||||
|
|
||||||
|
// This macro is used to silence warnings on string concatenation operations that may fail.
|
||||||
|
// e.g., combining two element of PATH_MAX into a string buffer of AKGL_STRING_MAX_LENGTH.
|
||||||
|
// We have to draw a line in the sand somewhere or we will just let our buffers grow forever
|
||||||
|
// to keep the compiler happy.
|
||||||
|
#define DISABLE_GCC_WARNING_FORMAT_TRUNCATION \
|
||||||
|
_Pragma("GCC diagnostic push") \
|
||||||
|
_Pragma("GCC diagnostic ignored \"-Wformat-truncation\"")
|
||||||
|
|
||||||
|
#define RESTORE_GCC_WARNINGS \
|
||||||
|
_Pragma("GCC diagnostic pop")
|
||||||
|
|
||||||
#define AKGL_ERR_SDL AKERR_LAST_ERRNO_VALUE + 1
|
#define AKGL_ERR_SDL AKERR_LAST_ERRNO_VALUE + 1
|
||||||
|
|
||||||
#endif // _ERROR_H_
|
#endif // _ERROR_H_
|
||||||
|
|||||||
@@ -3,8 +3,9 @@
|
|||||||
|
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include <akerror.h>
|
#include <akerror.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#define AKGL_MAX_STRING_LENGTH 256
|
#define AKGL_MAX_STRING_LENGTH PATH_MAX
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@@ -13,5 +14,5 @@ typedef struct
|
|||||||
} akgl_String;
|
} akgl_String;
|
||||||
|
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_string_initialize(akgl_String *obj, char *init);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_string_initialize(akgl_String *obj, char *init);
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_string_copy(akgl_String *src, akgl_String *dst, int count);
|
||||||
#endif //_STRING_H_
|
#endif //_STRING_H_
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#ifndef _TILEMAP_H_
|
#ifndef _TILEMAP_H_
|
||||||
#define _TILEMAP_H_
|
#define _TILEMAP_H_
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
#include "actor.h"
|
#include "actor.h"
|
||||||
#include "staticstring.h"
|
#include "staticstring.h"
|
||||||
#include <jansson.h>
|
#include <jansson.h>
|
||||||
@@ -11,7 +12,7 @@
|
|||||||
#define AKGL_TILEMAP_MAX_TILESETS 16
|
#define AKGL_TILEMAP_MAX_TILESETS 16
|
||||||
#define AKGL_TILEMAP_MAX_TILES_PER_IMAGE 65536
|
#define AKGL_TILEMAP_MAX_TILES_PER_IMAGE 65536
|
||||||
#define AKGL_TILEMAP_MAX_TILESET_NAME_SIZE 512
|
#define AKGL_TILEMAP_MAX_TILESET_NAME_SIZE 512
|
||||||
#define AKGL_TILEMAP_MAX_TILESET_FILENAME_SIZE 512
|
#define AKGL_TILEMAP_MAX_TILESET_FILENAME_SIZE PATH_MAX
|
||||||
#define AKGL_TILEMAP_MAX_OBJECT_NAME_SIZE 512
|
#define AKGL_TILEMAP_MAX_OBJECT_NAME_SIZE 512
|
||||||
#define AKGL_TILEMAP_MAX_OBJECTS_PER_LAYER 128
|
#define AKGL_TILEMAP_MAX_OBJECTS_PER_LAYER 128
|
||||||
|
|
||||||
@@ -112,11 +113,11 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_get_json_tilemap_property(json_t *obj, c
|
|||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_get_json_properties_string(json_t *obj, char *key, akgl_String **dest);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_get_json_properties_string(json_t *obj, char *key, akgl_String **dest);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_get_json_properties_integer(json_t *obj, char *key, int *dest);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_get_json_properties_integer(json_t *obj, char *key, int *dest);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_tilemap_compute_tileset_offsets(akgl_Tilemap *dest, int tilesetidx);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_tilemap_compute_tileset_offsets(akgl_Tilemap *dest, int tilesetidx);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_tilemap_load_layer_objects(akgl_Tilemap *dest, json_t *root, int layerid);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_tilemap_load_layer_objects(akgl_Tilemap *dest, json_t *root, int layerid, akgl_String *dirname);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_tilemap_load_layer_tile(akgl_Tilemap *dest, json_t *root, int layerid);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_tilemap_load_layer_tile(akgl_Tilemap *dest, json_t *root, int layerid, akgl_String *dirname);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_tilemap_load_layers(akgl_Tilemap *dest, json_t *root);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_tilemap_load_layers(akgl_Tilemap *dest, json_t *root, akgl_String *dirname);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_tilemap_load_tilesets_each(json_t *tileset, akgl_Tilemap *dest, int tsidx);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_tilemap_load_tilesets_each(json_t *tileset, akgl_Tilemap *dest, int tsidx, akgl_String *dirname);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_tilemap_load_tilesets(akgl_Tilemap *dest, json_t *root);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_tilemap_load_tilesets(akgl_Tilemap *dest, json_t *root, akgl_String *dirname);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_tilemap_release(akgl_Tilemap *dest);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_tilemap_release(akgl_Tilemap *dest);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_tilemap_scale_actor(akgl_Tilemap *map, akgl_Actor *actor);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_tilemap_scale_actor(akgl_Tilemap *map, akgl_Actor *actor);
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define _UTIL_H_
|
#define _UTIL_H_
|
||||||
|
|
||||||
#include <akerror.h>
|
#include <akerror.h>
|
||||||
|
#include <akgl/staticstring.h>
|
||||||
|
|
||||||
typedef struct point {
|
typedef struct point {
|
||||||
int x;
|
int x;
|
||||||
@@ -22,6 +23,8 @@ akerr_ErrorContext AKERR_NOIGNORE *akgl_rectangle_points(RectanglePoints *dest,
|
|||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_collide_point_rectangle(point *p, RectanglePoints *r, bool *collide);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_collide_point_rectangle(point *p, RectanglePoints *r, bool *collide);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_collide_rectangles(SDL_FRect *r1, SDL_FRect *r2, bool *collide);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_collide_rectangles(SDL_FRect *r1, SDL_FRect *r2, bool *collide);
|
||||||
|
|
||||||
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_path_relative(char *root, char *path, akgl_String *dst);
|
||||||
|
|
||||||
// These are REALLY slow routines that are only useful in testing harnesses
|
// These are REALLY slow routines that are only useful in testing harnesses
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_compare_sdl_surfaces(SDL_Surface *s1, SDL_Surface *s2);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_compare_sdl_surfaces(SDL_Surface *s1, SDL_Surface *s2);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *akgl_render_and_compare(SDL_Texture *t1, SDL_Texture *t2, int x, int y, int w, int h, char *writeout);
|
akerr_ErrorContext AKERR_NOIGNORE *akgl_render_and_compare(SDL_Texture *t1, SDL_Texture *t2, int x, int y, int w, int h, char *writeout);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include <akerror.h>
|
#include <akerror.h>
|
||||||
#include <akgl/staticstring.h>
|
#include <akgl/staticstring.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
akerr_ErrorContext *akgl_string_initialize(akgl_String *obj, char *init)
|
akerr_ErrorContext *akgl_string_initialize(akgl_String *obj, char *init)
|
||||||
{
|
{
|
||||||
@@ -13,3 +14,17 @@ akerr_ErrorContext *akgl_string_initialize(akgl_String *obj, char *init)
|
|||||||
obj->refcount = 1;
|
obj->refcount = 1;
|
||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
akerr_ErrorContext *akgl_string_copy(akgl_String *src, akgl_String *dst, int count)
|
||||||
|
{
|
||||||
|
PREPARE_ERROR(e);
|
||||||
|
FAIL_ZERO_RETURN(e, src, AKERR_NULLPOINTER, "NULL argument");
|
||||||
|
FAIL_ZERO_RETURN(e, dst, AKERR_NULLPOINTER, "NULL argument");
|
||||||
|
if ( count == 0 ) {
|
||||||
|
count = AKGL_MAX_STRING_LENGTH;
|
||||||
|
}
|
||||||
|
if ( (char *)dst->data != strncpy((char *)&src->data, (char *)&dst->data, count) ) {
|
||||||
|
FAIL_RETURN(e, errno, "strncpy");
|
||||||
|
}
|
||||||
|
SUCCEED_RETURN(e);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
|
#include <string.h>
|
||||||
|
#include <libgen.h>
|
||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
#include <SDL3_image/SDL_image.h>
|
#include <SDL3_image/SDL_image.h>
|
||||||
#include <SDL3_mixer/SDL_mixer.h>
|
#include <SDL3_mixer/SDL_mixer.h>
|
||||||
#include <string.h>
|
|
||||||
#include <jansson.h>
|
#include <jansson.h>
|
||||||
|
|
||||||
#include <akerror.h>
|
#include <akerror.h>
|
||||||
|
#include <akstdlib.h>
|
||||||
|
|
||||||
#include <akgl/tilemap.h>
|
#include <akgl/tilemap.h>
|
||||||
#include <akgl/actor.h>
|
#include <akgl/actor.h>
|
||||||
@@ -13,6 +17,7 @@
|
|||||||
#include <akgl/staticstring.h>
|
#include <akgl/staticstring.h>
|
||||||
#include <akgl/game.h>
|
#include <akgl/game.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)
|
||||||
{
|
{
|
||||||
PREPARE_ERROR(errctx);
|
PREPARE_ERROR(errctx);
|
||||||
@@ -96,7 +101,7 @@ akerr_ErrorContext *akgl_get_json_properties_number(json_t *obj, char *key, floa
|
|||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
akerr_ErrorContext *akgl_tilemap_load_tilesets_each(json_t *tileset, akgl_Tilemap *dest, int tsidx)
|
akerr_ErrorContext *akgl_tilemap_load_tilesets_each(json_t *tileset, akgl_Tilemap *dest, int tsidx, akgl_String *dirname)
|
||||||
{
|
{
|
||||||
PREPARE_ERROR(errctx);
|
PREPARE_ERROR(errctx);
|
||||||
akgl_String *tmpstr = NULL;
|
akgl_String *tmpstr = NULL;
|
||||||
@@ -119,12 +124,14 @@ akerr_ErrorContext *akgl_tilemap_load_tilesets_each(json_t *tileset, akgl_Tilema
|
|||||||
|
|
||||||
CATCH(errctx, akgl_get_json_string_value((json_t *)tileset, "image", &tmpstr));
|
CATCH(errctx, akgl_get_json_string_value((json_t *)tileset, "image", &tmpstr));
|
||||||
|
|
||||||
|
DISABLE_GCC_WARNING_FORMAT_TRUNCATION
|
||||||
snprintf((char *)&dest->tilesets[tsidx].imagefilename,
|
snprintf((char *)&dest->tilesets[tsidx].imagefilename,
|
||||||
AKGL_TILEMAP_MAX_TILESET_FILENAME_SIZE,
|
AKGL_TILEMAP_MAX_TILESET_FILENAME_SIZE,
|
||||||
"%s%s",
|
"%s/%s",
|
||||||
SDL_GetBasePath(),
|
dirname->data,
|
||||||
tmpstr->data
|
tmpstr->data
|
||||||
);
|
);
|
||||||
|
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_BREAK(errctx, dest->tilesets[tsidx].texture, AKERR_NULLPOINTER, "Failed loading tileset image : %s", SDL_GetError());
|
||||||
@@ -190,7 +197,7 @@ akerr_ErrorContext *akgl_tilemap_compute_tileset_offsets(akgl_Tilemap *dest, int
|
|||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
akerr_ErrorContext *akgl_tilemap_load_tilesets(akgl_Tilemap *dest, json_t *root)
|
akerr_ErrorContext *akgl_tilemap_load_tilesets(akgl_Tilemap *dest, json_t *root, akgl_String *dirname)
|
||||||
{
|
{
|
||||||
PREPARE_ERROR(errctx);
|
PREPARE_ERROR(errctx);
|
||||||
FAIL_ZERO_RETURN(errctx, dest, AKERR_NULLPOINTER, "Received NULL tilemap pointer");
|
FAIL_ZERO_RETURN(errctx, dest, AKERR_NULLPOINTER, "Received NULL tilemap pointer");
|
||||||
@@ -205,7 +212,7 @@ akerr_ErrorContext *akgl_tilemap_load_tilesets(akgl_Tilemap *dest, json_t *root)
|
|||||||
CATCH(errctx, akgl_get_json_array_value(root, "tilesets", &tilesets))
|
CATCH(errctx, akgl_get_json_array_value(root, "tilesets", &tilesets))
|
||||||
for (i = 0; i < json_array_size((json_t *)tilesets); i++) {
|
for (i = 0; i < json_array_size((json_t *)tilesets); i++) {
|
||||||
CATCH(errctx, akgl_get_json_array_index_object((json_t *)tilesets, i, &jstileset));
|
CATCH(errctx, akgl_get_json_array_index_object((json_t *)tilesets, i, &jstileset));
|
||||||
CATCH(errctx, akgl_tilemap_load_tilesets_each(jstileset, dest, i));
|
CATCH(errctx, akgl_tilemap_load_tilesets_each(jstileset, dest, i, dirname));
|
||||||
CATCH(errctx, akgl_tilemap_compute_tileset_offsets(dest, i));
|
CATCH(errctx, akgl_tilemap_compute_tileset_offsets(dest, i));
|
||||||
dest->numtilesets += 1;
|
dest->numtilesets += 1;
|
||||||
}
|
}
|
||||||
@@ -216,7 +223,7 @@ akerr_ErrorContext *akgl_tilemap_load_tilesets(akgl_Tilemap *dest, json_t *root)
|
|||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
akerr_ErrorContext *akgl_tilemap_load_layer_object_actor(akgl_TilemapObject *curobj, json_t *layerdatavalue, int layerid)
|
akerr_ErrorContext *akgl_tilemap_load_layer_object_actor(akgl_TilemapObject *curobj, json_t *layerdatavalue, int layerid, akgl_String *dirname)
|
||||||
{
|
{
|
||||||
PREPARE_ERROR(errctx);
|
PREPARE_ERROR(errctx);
|
||||||
akgl_String *tmpstr = NULL;
|
akgl_String *tmpstr = NULL;
|
||||||
@@ -260,7 +267,7 @@ akerr_ErrorContext *akgl_tilemap_load_layer_object_actor(akgl_TilemapObject *cur
|
|||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
akerr_ErrorContext *akgl_tilemap_load_layer_objects(akgl_Tilemap *dest, json_t *root, int layerid)
|
akerr_ErrorContext *akgl_tilemap_load_layer_objects(akgl_Tilemap *dest, json_t *root, int layerid, akgl_String *dirname)
|
||||||
{
|
{
|
||||||
PREPARE_ERROR(errctx);
|
PREPARE_ERROR(errctx);
|
||||||
json_t *layerdata = NULL;
|
json_t *layerdata = NULL;
|
||||||
@@ -290,7 +297,7 @@ akerr_ErrorContext *akgl_tilemap_load_layer_objects(akgl_Tilemap *dest, json_t *
|
|||||||
|
|
||||||
CATCH(errctx, akgl_get_json_string_value((json_t *)layerdatavalue, "type", &tmpstr));
|
CATCH(errctx, akgl_get_json_string_value((json_t *)layerdatavalue, "type", &tmpstr));
|
||||||
if ( strcmp(tmpstr->data, "actor") == 0 ) {
|
if ( strcmp(tmpstr->data, "actor") == 0 ) {
|
||||||
CATCH(errctx, akgl_tilemap_load_layer_object_actor(curobj, layerdatavalue, layerid));
|
CATCH(errctx, akgl_tilemap_load_layer_object_actor(curobj, layerdatavalue, layerid, dirname));
|
||||||
} else if ( strcmp(tmpstr->data, "perspective") == 0 ) {
|
} else if ( strcmp(tmpstr->data, "perspective") == 0 ) {
|
||||||
curobj->visible = false;
|
curobj->visible = false;
|
||||||
if ( strcmp((char *)curobj->name, "p_foreground") == 0 ) {
|
if ( strcmp((char *)curobj->name, "p_foreground") == 0 ) {
|
||||||
@@ -313,7 +320,7 @@ akerr_ErrorContext *akgl_tilemap_load_layer_objects(akgl_Tilemap *dest, json_t *
|
|||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
akerr_ErrorContext *akgl_tilemap_load_layer_tile(akgl_Tilemap *dest, json_t *root, int layerid)
|
akerr_ErrorContext *akgl_tilemap_load_layer_tile(akgl_Tilemap *dest, json_t *root, int layerid, akgl_String *dirname)
|
||||||
{
|
{
|
||||||
PREPARE_ERROR(errctx);
|
PREPARE_ERROR(errctx);
|
||||||
json_t *layerdata = NULL;
|
json_t *layerdata = NULL;
|
||||||
@@ -322,6 +329,7 @@ akerr_ErrorContext *akgl_tilemap_load_layer_tile(akgl_Tilemap *dest, json_t *roo
|
|||||||
|
|
||||||
FAIL_ZERO_RETURN(errctx, dest, AKERR_NULLPOINTER, "NULL destination tilemap reference");
|
FAIL_ZERO_RETURN(errctx, dest, AKERR_NULLPOINTER, "NULL destination tilemap reference");
|
||||||
FAIL_ZERO_RETURN(errctx, root, AKERR_NULLPOINTER, "NULL tilemap root reference");
|
FAIL_ZERO_RETURN(errctx, root, AKERR_NULLPOINTER, "NULL tilemap root reference");
|
||||||
|
FAIL_ZERO_RETURN(errctx, dirname, AKERR_NULLPOINTER, "dirname");
|
||||||
|
|
||||||
ATTEMPT {
|
ATTEMPT {
|
||||||
CATCH(errctx, akgl_get_json_integer_value(root, "height", &dest->layers[layerid].height));
|
CATCH(errctx, akgl_get_json_integer_value(root, "height", &dest->layers[layerid].height));
|
||||||
@@ -341,7 +349,7 @@ akerr_ErrorContext *akgl_tilemap_load_layer_tile(akgl_Tilemap *dest, json_t *roo
|
|||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
akerr_ErrorContext *akgl_tilemap_load_layer_image(akgl_Tilemap *dest, json_t *root, int layerid)
|
akerr_ErrorContext *akgl_tilemap_load_layer_image(akgl_Tilemap *dest, json_t *root, int layerid, akgl_String *dirname)
|
||||||
{
|
{
|
||||||
PREPARE_ERROR(errctx);
|
PREPARE_ERROR(errctx);
|
||||||
akgl_String *tmpstr;
|
akgl_String *tmpstr;
|
||||||
@@ -349,18 +357,21 @@ akerr_ErrorContext *akgl_tilemap_load_layer_image(akgl_Tilemap *dest, json_t *ro
|
|||||||
|
|
||||||
FAIL_ZERO_RETURN(errctx, dest, AKERR_NULLPOINTER, "NULL destination tilemap reference");
|
FAIL_ZERO_RETURN(errctx, dest, AKERR_NULLPOINTER, "NULL destination tilemap reference");
|
||||||
FAIL_ZERO_RETURN(errctx, root, AKERR_NULLPOINTER, "NULL tilemap root reference");
|
FAIL_ZERO_RETURN(errctx, root, AKERR_NULLPOINTER, "NULL tilemap root reference");
|
||||||
|
FAIL_ZERO_RETURN(errctx, dirname, AKERR_NULLPOINTER, "dirname");
|
||||||
|
|
||||||
ATTEMPT {
|
ATTEMPT {
|
||||||
CATCH(errctx, akgl_heap_next_string(&tmpstr));
|
CATCH(errctx, akgl_heap_next_string(&tmpstr));
|
||||||
CATCH(errctx, akgl_heap_next_string(&fpath));
|
CATCH(errctx, akgl_heap_next_string(&fpath));
|
||||||
CATCH(errctx, akgl_get_json_string_value(root, "image", &tmpstr));
|
CATCH(errctx, akgl_get_json_string_value(root, "image", &tmpstr));
|
||||||
|
|
||||||
|
DISABLE_GCC_WARNING_FORMAT_TRUNCATION
|
||||||
snprintf((char *)&fpath->data,
|
snprintf((char *)&fpath->data,
|
||||||
AKGL_TILEMAP_MAX_TILESET_FILENAME_SIZE,
|
AKGL_TILEMAP_MAX_TILESET_FILENAME_SIZE,
|
||||||
"%s%s",
|
"%s/%s",
|
||||||
SDL_GetBasePath(),
|
dirname->data,
|
||||||
tmpstr->data
|
tmpstr->data
|
||||||
);
|
);
|
||||||
|
RESTORE_GCC_WARNINGS
|
||||||
|
|
||||||
dest->layers[layerid].texture = IMG_LoadTexture(renderer, (char *)fpath->data);
|
dest->layers[layerid].texture = IMG_LoadTexture(renderer, (char *)fpath->data);
|
||||||
FAIL_ZERO_BREAK(errctx, dest->layers[layerid].texture, AKGL_ERR_SDL, "%s", SDL_GetError());
|
FAIL_ZERO_BREAK(errctx, dest->layers[layerid].texture, AKGL_ERR_SDL, "%s", SDL_GetError());
|
||||||
@@ -375,11 +386,12 @@ akerr_ErrorContext *akgl_tilemap_load_layer_image(akgl_Tilemap *dest, json_t *ro
|
|||||||
SUCCEED_RETURN(errctx);
|
SUCCEED_RETURN(errctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
akerr_ErrorContext *akgl_tilemap_load_layers(akgl_Tilemap *dest, json_t *root)
|
akerr_ErrorContext *akgl_tilemap_load_layers(akgl_Tilemap *dest, json_t *root, akgl_String *dirname)
|
||||||
{
|
{
|
||||||
PREPARE_ERROR(errctx);
|
PREPARE_ERROR(errctx);
|
||||||
FAIL_ZERO_RETURN(errctx, dest, AKERR_NULLPOINTER, "akgl_tilemap_load_layers received NULL tilemap pointer");
|
FAIL_ZERO_RETURN(errctx, dest, AKERR_NULLPOINTER, "akgl_tilemap_load_layers received NULL tilemap pointer");
|
||||||
FAIL_ZERO_RETURN(errctx, root, AKERR_NULLPOINTER, "akgl_tilemap_load_layers received NULL json object pointer");
|
FAIL_ZERO_RETURN(errctx, root, AKERR_NULLPOINTER, "akgl_tilemap_load_layers received NULL json object pointer");
|
||||||
|
FAIL_ZERO_RETURN(errctx, dirname, AKERR_NULLPOINTER, "dirname");
|
||||||
json_t *layers = NULL;
|
json_t *layers = NULL;
|
||||||
json_t *layer = NULL;
|
json_t *layer = NULL;
|
||||||
akgl_String *tmpstr = NULL;
|
akgl_String *tmpstr = NULL;
|
||||||
@@ -406,13 +418,13 @@ akerr_ErrorContext *akgl_tilemap_load_layers(akgl_Tilemap *dest, json_t *root)
|
|||||||
SDL_Log("Layer %d has type %s", layerid, tmpstr->data);
|
SDL_Log("Layer %d has type %s", layerid, tmpstr->data);
|
||||||
if ( strncmp((char *)tmpstr->data, "objectgroup", strlen((char *)tmpstr->data)) == 0 ) {
|
if ( strncmp((char *)tmpstr->data, "objectgroup", strlen((char *)tmpstr->data)) == 0 ) {
|
||||||
dest->layers[layerid].type = AKGL_TILEMAP_LAYER_TYPE_OBJECTS;
|
dest->layers[layerid].type = AKGL_TILEMAP_LAYER_TYPE_OBJECTS;
|
||||||
CATCH(errctx, akgl_tilemap_load_layer_objects((akgl_Tilemap *)dest, (json_t *)layer, layerid));
|
CATCH(errctx, akgl_tilemap_load_layer_objects((akgl_Tilemap *)dest, (json_t *)layer, layerid, dirname));
|
||||||
} else if ( strncmp((char *)tmpstr->data, "tilelayer", strlen((char *)tmpstr->data)) == 0 ) {
|
} else if ( strncmp((char *)tmpstr->data, "tilelayer", strlen((char *)tmpstr->data)) == 0 ) {
|
||||||
dest->layers[layerid].type = AKGL_TILEMAP_LAYER_TYPE_TILES;
|
dest->layers[layerid].type = AKGL_TILEMAP_LAYER_TYPE_TILES;
|
||||||
CATCH(errctx, akgl_tilemap_load_layer_tile((akgl_Tilemap *)dest, (json_t *)layer, layerid));
|
CATCH(errctx, akgl_tilemap_load_layer_tile((akgl_Tilemap *)dest, (json_t *)layer, layerid, dirname));
|
||||||
} else if ( strncmp((char *)tmpstr->data, "imagelayer", strlen((char *)tmpstr->data)) == 0 ) {
|
} else if ( strncmp((char *)tmpstr->data, "imagelayer", strlen((char *)tmpstr->data)) == 0 ) {
|
||||||
dest->layers[layerid].type = AKGL_TILEMAP_LAYER_TYPE_IMAGE;
|
dest->layers[layerid].type = AKGL_TILEMAP_LAYER_TYPE_IMAGE;
|
||||||
CATCH(errctx, akgl_tilemap_load_layer_image((akgl_Tilemap *)dest, (json_t *)layer, layerid));
|
CATCH(errctx, akgl_tilemap_load_layer_image((akgl_Tilemap *)dest, (json_t *)layer, layerid, dirname));
|
||||||
}
|
}
|
||||||
layer = NULL;
|
layer = NULL;
|
||||||
layerid += 1;
|
layerid += 1;
|
||||||
@@ -429,6 +441,7 @@ akerr_ErrorContext *akgl_tilemap_load(char *fname, akgl_Tilemap *dest)
|
|||||||
json_t *json = NULL;
|
json_t *json = NULL;
|
||||||
//akgl_String *tmpstr = NULL;
|
//akgl_String *tmpstr = NULL;
|
||||||
json_error_t error;
|
json_error_t error;
|
||||||
|
akgl_String *dirnamestr = NULL;
|
||||||
|
|
||||||
FAIL_ZERO_RETURN(errctx, fname, AKERR_NULLPOINTER, "load_tilemap received null filename");
|
FAIL_ZERO_RETURN(errctx, fname, AKERR_NULLPOINTER, "load_tilemap received null filename");
|
||||||
FAIL_ZERO_RETURN(errctx, dest, AKERR_NULLPOINTER, "load_tilemap received null tilemap");
|
FAIL_ZERO_RETURN(errctx, dest, AKERR_NULLPOINTER, "load_tilemap received null tilemap");
|
||||||
@@ -437,10 +450,13 @@ akerr_ErrorContext *akgl_tilemap_load(char *fname, akgl_Tilemap *dest)
|
|||||||
dest->p_foreground_scale = 1.0;
|
dest->p_foreground_scale = 1.0;
|
||||||
dest->p_vanishing_scale = 1.0;
|
dest->p_vanishing_scale = 1.0;
|
||||||
|
|
||||||
|
PASS(errctx, akgl_heap_next_string(&dirnamestr));
|
||||||
ATTEMPT {
|
ATTEMPT {
|
||||||
//CATCH(errctx, akgl_heap_next_string(&tmpstr));
|
//CATCH(errctx, akgl_heap_next_string(&tmpstr));
|
||||||
//CATCH(errctx, akgl_string_initialize(tmpstr, NULL));
|
//CATCH(errctx, akgl_string_initialize(tmpstr, NULL));
|
||||||
//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));
|
||||||
|
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,
|
||||||
@@ -461,8 +477,8 @@ akerr_ErrorContext *akgl_tilemap_load(char *fname, akgl_Tilemap *dest)
|
|||||||
FAIL_RETURN(errctx, AKERR_OUTOFBOUNDS, "Map exceeds the maximum size");
|
FAIL_RETURN(errctx, AKERR_OUTOFBOUNDS, "Map exceeds the maximum size");
|
||||||
}
|
}
|
||||||
|
|
||||||
CATCH(errctx, akgl_tilemap_load_layers((akgl_Tilemap *)dest, (json_t *)json));
|
CATCH(errctx, akgl_tilemap_load_layers((akgl_Tilemap *)dest, (json_t *)json, dirnamestr));
|
||||||
CATCH(errctx, akgl_tilemap_load_tilesets((akgl_Tilemap *)dest, (json_t *)json));
|
CATCH(errctx, akgl_tilemap_load_tilesets((akgl_Tilemap *)dest, (json_t *)json, dirnamestr));
|
||||||
|
|
||||||
if ( dest->p_foreground_y && dest->p_vanishing_y ) {
|
if ( dest->p_foreground_y && dest->p_vanishing_y ) {
|
||||||
// How much bigger is the foreground vs the vanishing point?
|
// How much bigger is the foreground vs the vanishing point?
|
||||||
|
|||||||
67
src/util.c
67
src/util.c
@@ -1,5 +1,6 @@
|
|||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
#include <SDL3_image/SDL_image.h>
|
#include <SDL3_image/SDL_image.h>
|
||||||
@@ -9,6 +10,72 @@
|
|||||||
#include <akgl/heap.h>
|
#include <akgl/heap.h>
|
||||||
#include <akgl/registry.h>
|
#include <akgl/registry.h>
|
||||||
#include <akgl/game.h>
|
#include <akgl/game.h>
|
||||||
|
#include <akgl/staticstring.h>
|
||||||
|
|
||||||
|
#include <akstdlib.h>
|
||||||
|
|
||||||
|
akerr_ErrorContext *akgl_path_relative_root(char *root, char *path, akgl_String *dst)
|
||||||
|
{
|
||||||
|
PREPARE_ERROR(e);
|
||||||
|
akgl_String *pathbuf;
|
||||||
|
akgl_String *strbuf;
|
||||||
|
char *result;
|
||||||
|
int rootlen;
|
||||||
|
int pathlen;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
FAIL_ZERO_RETURN(e, root, AKERR_NULLPOINTER, "NULL argument");
|
||||||
|
FAIL_ZERO_RETURN(e, path, AKERR_NULLPOINTER, "NULL argument");
|
||||||
|
FAIL_ZERO_RETURN(e, dst, AKERR_NULLPOINTER, "NULL argument");
|
||||||
|
|
||||||
|
PASS(e, akgl_heap_next_string(&strbuf));
|
||||||
|
PASS(e, akgl_heap_next_string(&pathbuf));
|
||||||
|
|
||||||
|
ATTEMPT {
|
||||||
|
// Is it relative to the root?
|
||||||
|
rootlen = strlen(root);
|
||||||
|
pathlen = strlen(path);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
CATCH(e, aksl_sprintf(&count, (char *)&pathbuf->data, "%s/%s", root, path));
|
||||||
|
CATCH(e, aksl_realpath((char *)&pathbuf->data, (char *)&strbuf->data));
|
||||||
|
CATCH(e, akgl_string_copy(strbuf, dst, 0));
|
||||||
|
} CLEANUP {
|
||||||
|
IGNORE(akgl_heap_release_string(strbuf));
|
||||||
|
IGNORE(akgl_heap_release_string(pathbuf));
|
||||||
|
} PROCESS(e) {
|
||||||
|
} FINISH(e, true);
|
||||||
|
SUCCEED_RETURN(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
akerr_ErrorContext *akgl_path_relative(char *root, char *path, akgl_String *dst)
|
||||||
|
{
|
||||||
|
PREPARE_ERROR(e);
|
||||||
|
akgl_String *strbuf;
|
||||||
|
char *result;
|
||||||
|
|
||||||
|
FAIL_ZERO_RETURN(e, root, AKERR_NULLPOINTER, "NULL argument");
|
||||||
|
FAIL_ZERO_RETURN(e, path, AKERR_NULLPOINTER, "NULL argument");
|
||||||
|
FAIL_ZERO_RETURN(e, dst, AKERR_NULLPOINTER, "NULL argument");
|
||||||
|
|
||||||
|
PASS(e, akgl_heap_next_string(&strbuf));
|
||||||
|
|
||||||
|
ATTEMPT {
|
||||||
|
// Is path relative to our current working directory?
|
||||||
|
CATCH(e, aksl_realpath(path, (char *)&strbuf->data));
|
||||||
|
// Yes it is. strbuf->data contains the absolute path.
|
||||||
|
CATCH(e, akgl_string_copy(strbuf, dst, 0));
|
||||||
|
} CLEANUP {
|
||||||
|
IGNORE(akgl_heap_release_string(strbuf));
|
||||||
|
} PROCESS(e) {
|
||||||
|
} HANDLE(e, ENOENT) {
|
||||||
|
// Path is not relative to our current working directory
|
||||||
|
// Noop - execution proceeds after the break
|
||||||
|
return akgl_path_relative_root(root, path, dst);
|
||||||
|
} FINISH(e, true);
|
||||||
|
SUCCEED_RETURN(e);
|
||||||
|
}
|
||||||
|
|
||||||
akerr_ErrorContext *akgl_rectangle_points(RectanglePoints *dest, SDL_FRect *rect)
|
akerr_ErrorContext *akgl_rectangle_points(RectanglePoints *dest, SDL_FRect *rect)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user