From 9f57710c36238f5500836f7247b7c23410bb2a9c Mon Sep 17 00:00:00 2001 From: Andrew Kesterson Date: Sun, 22 Dec 2024 01:10:25 -0500 Subject: [PATCH] malloc/free errors wat --- Makefile | 22 ++++++- src/heap.c | 152 ++++++++++++++++++++++++++++++++++++++++++++ src/heap.h | 31 +++++++++ src/registry.c | 32 ++++++++++ src/registry.h | 16 +++++ src/sdl3-gametest.c | 2 + src/sprite.c | 142 +---------------------------------------- src/sprite.h | 32 +--------- src/string.c | 12 ++++ src/string.h | 14 ++++ src/tilemap.c | 11 +++- 11 files changed, 289 insertions(+), 177 deletions(-) create mode 100644 src/heap.c create mode 100644 src/heap.h create mode 100644 src/registry.c create mode 100644 src/registry.h create mode 100644 src/string.c create mode 100644 src/string.h diff --git a/Makefile b/Makefile index 0520d91..1dffa2e 100644 --- a/Makefile +++ b/Makefile @@ -2,21 +2,37 @@ SDLFLAGS_CC:=$(shell PKG_CONFIG_PATH=~/local/lib/pkgconfig pkg-config sdl3 --cfl SDLFLAGS_LD:=$(shell PKG_CONFIG_PATH=~/local/lib/pkgconfig pkg-config sdl3 --libs) -lSDL3_image -lSDL3_mixer CC:=$(shell which gcc) LD:=$(shell which ld) +SRCFILES:=$(shell find src -type f -name '*.c') +OBJFILES:=$(patsubst %.c,%.o,$(SRCFILES)) +PREPFILES:=$(patsubst %.c,%.E,$(SRCFILES)) +ASMFILES:=$(patsubst %.c,%.S,$(SRCFILES)) + CFLAGS:=-ggdb -gstabs -OBJECTS:=src/util.o src/assets.o src/draw.o src/game.o src/physics.o src/json_helpers.o src/tilemap.o src/sprite.o src/sdl3-gametest.o DISTFILE:=dist/sdl3-gametest .PHONY: clean +.PHONY: preprocessor +.PHONY: assembler all: $(DISTFILE) +preprocessor: $(PREPFILES) + +assembler: $(ASMFILES) + clean: - rm -f src/*.o ${DISTFILE} + rm -f $(OBJFILES) $(PREPFILES) $(ASMFILES) ${DISTFILE} + +src/%.S: src/%.c + $(CC) -S -o $@ $(CFLAGS) $(SDLFLAGS_CC) $? + +src/%.E: src/%.c + $(CC) -E -o $@ $(CFLAGS) $(SDLFLAGS_CC) $? src/%.o: src/%.c $(CC) -c -o $@ $(CFLAGS) $(SDLFLAGS_CC) $? -$(DISTFILE): $(OBJECTS) +$(DISTFILE): $(OBJFILES) $(CC) -o $@ $^ -lexc -lbox2d -ljansson -lhashmap -lm $(SDLFLAGS_LD) diff --git a/src/heap.c b/src/heap.c new file mode 100644 index 0000000..a2203b6 --- /dev/null +++ b/src/heap.c @@ -0,0 +1,152 @@ +#include +#include + +#include "game.h" +#include "sprite.h" +#include "heap.h" +#include "registry.h" + +actor HEAP_ACTOR[MAX_HEAP_ACTOR]; +sprite HEAP_SPRITE[MAX_HEAP_SPRITE]; +spritesheet HEAP_SPRITESHEET[MAX_HEAP_SPRITESHEET]; +character HEAP_CHARACTER[MAX_HEAP_CHARACTER]; +string HEAP_STRING[MAX_HEAP_STRING]; + +void heap_init() +{ + int i = 0; + for ( i = 0; i < MAX_HEAP_ACTOR; i++) { + memset(&HEAP_ACTOR[i], 0x00, sizeof(actor)); + } + for ( i = 0; i < MAX_HEAP_SPRITE; i++) { + memset(&HEAP_SPRITE[i], 0x00, sizeof(sprite)); + } + for ( i = 0; i < MAX_HEAP_SPRITESHEET; i++) { + memset(&HEAP_SPRITESHEET[i], 0x00, sizeof(spritesheet)); + } + for ( i = 0; i < MAX_HEAP_CHARACTER; i++) { + memset(&HEAP_CHARACTER[i], 0x00, sizeof(character)); + } + for ( i = 0; i < MAX_HEAP_STRING; i++) { + memset(&HEAP_STRING[i], 0x00, sizeof(string)); + } +} + +actor *heap_next_actor() +{ + for (int i = 0; i < MAX_HEAP_ACTOR; i++ ) { + if ( HEAP_ACTOR[i].refcount != 0 ) { + continue; + } + return &HEAP_ACTOR[i]; + } + THROW(EXC_HEAPERROR, "Unable to find unused actor on the heap"); +} + +sprite *heap_next_sprite() +{ + for (int i = 0; i < MAX_HEAP_SPRITE; i++ ) { + if ( HEAP_SPRITE[i].refcount != 0 ) { + continue; + } + return &HEAP_SPRITE[i]; + } + THROW(EXC_HEAPERROR, "Unable to find unused sprite on the heap"); +} + +spritesheet *heap_next_spritesheet() +{ + for (int i = 0; i < MAX_HEAP_SPRITESHEET; i++ ) { + if ( HEAP_SPRITESHEET[i].refcount != 0 ) { + continue; + } + return &HEAP_SPRITESHEET[i]; + } + THROW(EXC_HEAPERROR, "Unable to find unused spritesheet on the heap"); +} + +character *heap_next_character() +{ + for (int i = 0; i < MAX_HEAP_CHARACTER; i++ ) { + if ( HEAP_CHARACTER[i].refcount != 0 ) { + continue; + } + return &HEAP_CHARACTER[i]; + } + THROW(EXC_HEAPERROR, "Unable to find unused character on the heap"); +} + +string *heap_next_string() +{ + for (int i = 0; i < MAX_HEAP_STRING; i++ ) { + if ( HEAP_STRING[i].refcount != 0 ) { + continue; + } + return &HEAP_STRING[i]; + } + THROW(EXC_HEAPERROR, "Unable to find unused string on the heap"); +} + +void heap_release_actor(actor *ptr) +{ + THROW_ZERO(ptr, EXC_NULLPOINTER, "NULL character reference"); + if ( ptr->refcount > 0 ) { + ptr->refcount -= 1; + } + if ( ptr->refcount == 0 ) { + heap_release_character(ptr->basechar); + SDL_ClearProperty(REGISTRY_ACTOR, (char *)&ptr->name); + } +} + +void heap_release_character(character *basechar) +{ + iterator opflags; + THROW_ZERO(basechar, EXC_NULLPOINTER, "NULL character reference"); + BITMASK_CLEAR(opflags.flags); + BITMASK_ADD(opflags.flags, ITERATOR_OP_RELEASE); + + if ( basechar->refcount > 0 ) { + basechar->refcount -= 1; + } + if ( basechar->refcount == 0 ) { + SDL_EnumerateProperties(basechar->state_sprites, &character_state_sprites_iterate, (void *)&opflags); + SDL_ClearProperty(REGISTRY_CHARACTER, (char *)&basechar->name); + } +} + +void heap_release_sprite(sprite *ptr) +{ + THROW_ZERO(ptr, EXC_NULLPOINTER, "Received NULL sprite reference"); + if ( ptr->refcount > 0 ) { + ptr->refcount -= 1; + } + if ( ptr->refcount == 0 ) { + heap_release_spritesheet(ptr->sheet); + SDL_ClearProperty(REGISTRY_SPRITE, (char *)&ptr->name); + } +} + +void heap_release_spritesheet(spritesheet *ptr) +{ + THROW_ZERO(ptr, EXC_NULLPOINTER, "Received NULL spritesheet reference"); + if ( ptr->refcount > 0 ) { + ptr->refcount -= 1; + } + if ( ptr->refcount == 0 ) { + // TODO : If we go threaded, make sure this is only happening on the main thread + SDL_DestroyTexture(ptr->texture); + SDL_ClearProperty(REGISTRY_CHARACTER, (char *)&ptr->name); + } +} + +void heap_release_string(string *ptr) +{ + THROW_ZERO(ptr, EXC_NULLPOINTER, "Received NULL spritesheet reference"); + if ( ptr->refcount > 0 ) { + ptr->refcount -= 1; + } + if ( ptr->refcount == 0 ) { + memset(ptr->data, 0x00, MAX_STRING_LENGTH); + } +} diff --git a/src/heap.h b/src/heap.h new file mode 100644 index 0000000..0f6700e --- /dev/null +++ b/src/heap.h @@ -0,0 +1,31 @@ +#ifndef _HEAP_H_ +#define _HEAP_H_ + +#include "sprite.h" +#include "string.h" + +#define MAX_HEAP_ACTOR 64 +#define MAX_HEAP_SPRITE (MAX_HEAP_ACTOR * 16) +#define MAX_HEAP_SPRITESHEET MAX_HEAP_SPRITE +#define MAX_HEAP_CHARACTER 256 +#define MAX_HEAP_STRING 256 + +extern actor HEAP_ACTOR[MAX_HEAP_ACTOR]; +extern sprite HEAP_SPRITE[MAX_HEAP_SPRITE]; +extern spritesheet HEAP_SPRITESHEET[MAX_HEAP_SPRITESHEET]; +extern character HEAP_CHARACTER[MAX_HEAP_CHARACTER]; +extern string HEAP_STRING[MAX_HEAP_STRING]; + +void heap_init(); +actor *heap_next_actor(); +sprite *heap_next_sprite(); +spritesheet *heap_next_spritesheet(); +character *heap_next_character(); +string *heap_next_string(); +void heap_release_actor(actor *ptr); +void heap_release_sprite(sprite *ptr); +void heap_release_spritesheet(spritesheet *ptr); +void heap_release_character(character *ptr); +void heap_release_string(string *ptr); + +#endif //_HEAP_H_ diff --git a/src/registry.c b/src/registry.c new file mode 100644 index 0000000..5b16104 --- /dev/null +++ b/src/registry.c @@ -0,0 +1,32 @@ +#include +#include "sprite.h" +#include "registry.h" + +SDL_PropertiesID REGISTRY_ACTOR; +SDL_PropertiesID REGISTRY_SPRITE; +SDL_PropertiesID REGISTRY_SPRITESHEET; +SDL_PropertiesID REGISTRY_CHARACTER; + +void registry_init_actor() +{ + REGISTRY_ACTOR = SDL_CreateProperties(); + THROW_ZERO(REGISTRY_ACTOR, EXC_NULLPOINTER, "Error initializing actor registry"); +} + +void registry_init_sprite() +{ + REGISTRY_SPRITE = SDL_CreateProperties(); + THROW_ZERO(REGISTRY_SPRITE, EXC_NULLPOINTER, "Error initializing sprite registry"); +} + +void registry_init_spritesheet() +{ + REGISTRY_SPRITESHEET = SDL_CreateProperties(); + THROW_ZERO(REGISTRY_SPRITESHEET, EXC_NULLPOINTER, "Error initializing spritesheet registry"); +} + +void registry_init_character() +{ + REGISTRY_CHARACTER = SDL_CreateProperties(); + THROW_ZERO(REGISTRY_CHARACTER, EXC_NULLPOINTER, "Error initializing character registry"); +} diff --git a/src/registry.h b/src/registry.h new file mode 100644 index 0000000..ec8f1e7 --- /dev/null +++ b/src/registry.h @@ -0,0 +1,16 @@ +#ifndef _REGISTRY_H_ +#define _REGISTRY_H_ + +extern SDL_PropertiesID REGISTRY_ACTOR; +extern SDL_PropertiesID REGISTRY_SPRITE; +extern SDL_PropertiesID REGISTRY_SPRITESHEET; +extern SDL_PropertiesID REGISTRY_CHARACTER; + +void registry_init_actor(); +void registry_iterate_actor(void *userdata, SDL_PropertiesID registry, const char *name); +void registry_init_sprite(); +void registry_init_spritesheet(); +void registry_init_character(); + + +#endif //_REGISTRY_H_ diff --git a/src/sdl3-gametest.c b/src/sdl3-gametest.c index 2eb4b0d..bda0818 100644 --- a/src/sdl3-gametest.c +++ b/src/sdl3-gametest.c @@ -13,6 +13,8 @@ #include "draw.h" #include "assets.h" #include "sprite.h" +#include "heap.h" +#include "registry.h" SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) { diff --git a/src/sprite.c b/src/sprite.c index 54018d8..16f6a47 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -8,101 +8,8 @@ #include "game.h" #include "sprite.h" #include "json_helpers.h" - -SDL_PropertiesID REGISTRY_ACTOR; -SDL_PropertiesID REGISTRY_SPRITE; -SDL_PropertiesID REGISTRY_SPRITESHEET; -SDL_PropertiesID REGISTRY_CHARACTER; - -actor HEAP_ACTOR[MAX_HEAP_ACTOR]; -sprite HEAP_SPRITE[MAX_HEAP_SPRITE]; -spritesheet HEAP_SPRITESHEET[MAX_HEAP_SPRITESHEET]; -character HEAP_CHARACTER[MAX_HEAP_CHARACTER]; - -void heap_init() -{ - int i = 0; - for ( i = 0; i < MAX_HEAP_ACTOR; i++) { - memset(&HEAP_ACTOR[i], 0x00, sizeof(actor)); - } - for ( i = 0; i < MAX_HEAP_SPRITE; i++) { - memset(&HEAP_SPRITE[i], 0x00, sizeof(sprite)); - } - for ( i = 0; i < MAX_HEAP_SPRITESHEET; i++) { - memset(&HEAP_SPRITESHEET[i], 0x00, sizeof(spritesheet)); - } - for ( i = 0; i < MAX_HEAP_CHARACTER; i++) { - memset(&HEAP_CHARACTER[i], 0x00, sizeof(character)); - } -} - -actor *heap_next_actor() -{ - for (int i = 0; i < MAX_HEAP_ACTOR; i++ ) { - if ( HEAP_ACTOR[i].refcount != 0 ) { - continue; - } - return &HEAP_ACTOR[i]; - } - THROW(EXC_HEAPERROR, "Unable to find unused actor on the heap"); -} - -sprite *heap_next_sprite() -{ - for (int i = 0; i < MAX_HEAP_SPRITE; i++ ) { - if ( HEAP_SPRITE[i].refcount != 0 ) { - continue; - } - return &HEAP_SPRITE[i]; - } - THROW(EXC_HEAPERROR, "Unable to find unused sprite on the heap"); -} - -spritesheet *heap_next_spritesheet() -{ - for (int i = 0; i < MAX_HEAP_SPRITESHEET; i++ ) { - if ( HEAP_SPRITESHEET[i].refcount != 0 ) { - continue; - } - return &HEAP_SPRITESHEET[i]; - } - THROW(EXC_HEAPERROR, "Unable to find unused spritesheet on the heap"); -} - -character *heap_next_character() -{ - for (int i = 0; i < MAX_HEAP_CHARACTER; i++ ) { - if ( HEAP_CHARACTER[i].refcount != 0 ) { - continue; - } - return &HEAP_CHARACTER[i]; - } - THROW(EXC_HEAPERROR, "Unable to find unused character on the heap"); -} - -void registry_init_actor() -{ - REGISTRY_ACTOR = SDL_CreateProperties(); - THROW_ZERO(REGISTRY_ACTOR, EXC_NULLPOINTER, "Error initializing actor registry"); -} - -void registry_init_sprite() -{ - REGISTRY_SPRITE = SDL_CreateProperties(); - THROW_ZERO(REGISTRY_SPRITE, EXC_NULLPOINTER, "Error initializing sprite registry"); -} - -void registry_init_spritesheet() -{ - REGISTRY_SPRITESHEET = SDL_CreateProperties(); - THROW_ZERO(REGISTRY_SPRITESHEET, EXC_NULLPOINTER, "Error initializing spritesheet registry"); -} - -void registry_init_character() -{ - REGISTRY_CHARACTER = SDL_CreateProperties(); - THROW_ZERO(REGISTRY_CHARACTER, EXC_NULLPOINTER, "Error initializing character registry"); -} +#include "heap.h" +#include "registry.h" void actor_initialize(actor *obj, char *name) { @@ -444,48 +351,3 @@ void character_state_sprites_iterate(void *userdata, SDL_PropertiesID registry, } } -void heap_release_actor(actor *ptr) -{ - THROW_ZERO(ptr, EXC_NULLPOINTER, "NULL character reference"); - ptr->refcount -= 1; - if ( ptr->refcount == 0 ) { - heap_release_character(ptr->basechar); - SDL_ClearProperty(REGISTRY_ACTOR, (char *)&ptr->name); - } -} - -void heap_release_character(character *basechar) -{ - iterator opflags; - THROW_ZERO(basechar, EXC_NULLPOINTER, "NULL character reference"); - BITMASK_CLEAR(opflags.flags); - BITMASK_ADD(opflags.flags, ITERATOR_OP_RELEASE); - - basechar->refcount -= 1; - if ( basechar->refcount == 0 ) { - SDL_EnumerateProperties(basechar->state_sprites, &character_state_sprites_iterate, (void *)&opflags); - SDL_ClearProperty(REGISTRY_CHARACTER, (char *)&basechar->name); - } -} - -void heap_release_sprite(sprite *ptr) -{ - THROW_ZERO(ptr, EXC_NULLPOINTER, "Received NULL sprite reference"); - ptr->refcount -= 1; - if ( ptr->refcount == 0 ) { - heap_release_spritesheet(ptr->sheet); - SDL_ClearProperty(REGISTRY_SPRITE, (char *)&ptr->name); - } -} - -void heap_release_spritesheet(spritesheet *ptr) -{ - THROW_ZERO(ptr, EXC_NULLPOINTER, "Received NULL spritesheet reference"); - ptr->refcount -= 1; - if ( ptr->refcount == 0 ) { - // TODO : If we go threaded, make sure this is only happening on the main thread - SDL_DestroyTexture(ptr->texture); - SDL_ClearProperty(REGISTRY_CHARACTER, (char *)&ptr->name); - } -} - diff --git a/src/sprite.h b/src/sprite.h index 701b601..27f28c7 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -3,6 +3,7 @@ #include #include +#include #define ACTOR_STATE_FACE_DOWN 1 // 1 #define ACTOR_STATE_FACE_LEFT 1 << 1 // 2 @@ -44,11 +45,6 @@ #define SPRITE_MAX_ACTOR_NAME_LENGTH 128 #define SPRITE_MAX_CHARACTER_NAME_LENGTH 128 -#define MAX_HEAP_ACTOR 64 -#define MAX_HEAP_SPRITE (MAX_HEAP_ACTOR * 16) -#define MAX_HEAP_SPRITESHEET MAX_HEAP_SPRITE -#define MAX_HEAP_CHARACTER 256 - typedef struct { int refcount; SDL_Texture *texture; @@ -93,16 +89,6 @@ typedef struct { int y; } actor; -extern SDL_PropertiesID REGISTRY_ACTOR; -extern SDL_PropertiesID REGISTRY_SPRITE; -extern SDL_PropertiesID REGISTRY_SPRITESHEET; -extern SDL_PropertiesID REGISTRY_CHARACTER; - -extern actor HEAP_ACTOR[MAX_HEAP_ACTOR]; -extern sprite HEAP_SPRITE[MAX_HEAP_SPRITE]; -extern spritesheet HEAP_SPRITESHEET[MAX_HEAP_SPRITESHEET]; -extern character HEAP_CHARACTER[MAX_HEAP_CHARACTER]; - void actor_initialize(actor *obj, char *name); void actor_set_character(actor *obj, char *basecharname); void actor_render(actor *obj, SDL_Renderer *renderer); @@ -120,20 +106,4 @@ void sprite_initialize(sprite *spr, char *name, spritesheet *sheet); void spritesheet_initialize(spritesheet *sheet, short sprite_w, short sprite_h, char *filename); void sprite_load_json(char *filename); -void registry_init_actor(); -void registry_iterate_actor(void *userdata, SDL_PropertiesID registry, const char *name); -void registry_init_sprite(); -void registry_init_spritesheet(); -void registry_init_character(); - -void heap_init(); -actor *heap_next_actor(); -sprite *heap_next_sprite(); -spritesheet *heap_next_spritesheet(); -character *heap_next_character(); -void heap_release_actor(actor *ptr); -void heap_release_sprite(sprite *ptr); -void heap_release_spritesheet(spritesheet *ptr); -void heap_release_character(character *ptr); - #endif //_SPRITE_H_ diff --git a/src/string.c b/src/string.c new file mode 100644 index 0000000..425018f --- /dev/null +++ b/src/string.c @@ -0,0 +1,12 @@ +#include "string.h" +#include + +void string_initialize(string *obj, char *init) +{ + THROW_ZERO(obj, EXC_NULLPOINTER, "Attempted to initialize NULL string reference"); + if ( init != NULL ) { + strncpy(obj->data, init, MAX_STRING_LENGTH); + } else { + memset(&obj->data, 0x00, sizeof(MAX_STRING_LENGTH)); + } +} diff --git a/src/string.h b/src/string.h new file mode 100644 index 0000000..7f2b696 --- /dev/null +++ b/src/string.h @@ -0,0 +1,14 @@ +#ifndef _STRING_H_ +#define _STRING_H_ + +#define MAX_STRING_LENGTH 256 + +typedef struct string +{ + int refcount; + char data[MAX_STRING_LENGTH]; +} string; + +void string_initialize(string *obj, char *init); + +#endif //_STRING_H_ diff --git a/src/tilemap.c b/src/tilemap.c index 4740927..1234389 100644 --- a/src/tilemap.c +++ b/src/tilemap.c @@ -2,12 +2,16 @@ #include #include #include +#include +#include + #include "tilemap.h" #include "game.h" #include "sprite.h" -#include -#include #include "json_helpers.h" +#include "heap.h" +#include "string.h" +#include "registry.h" static json_t *get_json_tilemap_property(json_t *obj, char *key, char *type) { @@ -239,6 +243,7 @@ static void tilemap_load_layers(tilemap *dest, json_t *root) layer = get_json_array_index_object(layers, i); if ( (get_json_integer_value(layer, "id") - 1) != i ) { // TileD's map layer IDs start at 1, not 0, and are sequential but not necessarily contiguous. We may have a gap in IDs. + json_decref(layer); continue; } @@ -259,9 +264,9 @@ static void tilemap_load_layers(tilemap *dest, json_t *root) } } FINALLY { json_decref(layer); - json_decref(layers); } ETRY; } + json_decref(layers); } void tilemap_load(char *fname, tilemap *dest)