malloc/free errors wat

This commit is contained in:
2024-12-22 01:10:25 -05:00
parent 29cc3c341d
commit 9f57710c36
11 changed files with 289 additions and 177 deletions

View File

@@ -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)

152
src/heap.c Normal file
View File

@@ -0,0 +1,152 @@
#include <stdlib.h>
#include <aklabs/exclib.h>
#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);
}
}

31
src/heap.h Normal file
View File

@@ -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_

32
src/registry.c Normal file
View File

@@ -0,0 +1,32 @@
#include <aklabs/exclib.h>
#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");
}

16
src/registry.h Normal file
View File

@@ -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_

View File

@@ -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[])
{

View File

@@ -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);
}
}

View File

@@ -3,6 +3,7 @@
#include <box2d/box2d.h>
#include <SDL3/SDL_properties.h>
#include <SDL3/SDL.h>
#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_

12
src/string.c Normal file
View File

@@ -0,0 +1,12 @@
#include "string.h"
#include <aklabs/exclib.h>
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));
}
}

14
src/string.h Normal file
View File

@@ -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_

View File

@@ -2,12 +2,16 @@
#include <SDL3_image/SDL_image.h>
#include <SDL3_mixer/SDL_mixer.h>
#include <aklabs/exclib.h>
#include <string.h>
#include <jansson.h>
#include "tilemap.h"
#include "game.h"
#include "sprite.h"
#include <string.h>
#include <jansson.h>
#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)