diff --git a/src/common/array.c b/src/common/array.c index 4f8269b..6b0a1f5 100755 --- a/src/common/array.c +++ b/src/common/array.c @@ -3,6 +3,7 @@ #include #include "array.h" +#include "memory_utils.h" struct Array { @@ -26,7 +27,7 @@ static struct Array* array_get_ptr(void* array_data) void* array_new_(size_t object_size, int capacity) { int initial_capacity = capacity == 0 ? ARRAY_MIN_CAPACITY : capacity; - struct Array* new_array = malloc(sizeof(*new_array) + (object_size * initial_capacity)); + struct Array* new_array = memory_allocate(sizeof(*new_array) + (object_size * initial_capacity)); new_array->object_size = object_size; new_array->length = capacity; new_array->capacity = initial_capacity; @@ -37,7 +38,7 @@ void* array_new_(size_t object_size, int capacity) void array_free(void* array) { struct Array* array_ptr = array_get_ptr(array); - free(array_ptr); + memory_free(array_ptr); } void* array_top(struct Array* array) @@ -52,7 +53,7 @@ void* array_grow_(void** array) if(++array_ptr->length > array_ptr->capacity) { array_ptr->capacity = array_ptr->capacity << 1; /* LShift by 1 means (number * number) */ - char* new_data = realloc(array_ptr, sizeof(*array_ptr) + (array_ptr->object_size * array_ptr->capacity)); + char* new_data = memory_reallocate(array_ptr, sizeof(*array_ptr) + (array_ptr->object_size * array_ptr->capacity)); if(new_data) { array_ptr = (struct Array*)new_data; @@ -76,7 +77,7 @@ int array_reset_(void** array, int length) int new_capacity = length < ARRAY_MIN_CAPACITY ? ARRAY_MIN_CAPACITY : length; int new_length = new_capacity; array_free(*array); - array_ptr = calloc(1, sizeof(*array_ptr) + (new_capacity * object_size)); + array_ptr = memory_allocate_and_clear(1, sizeof(*array_ptr) + (new_capacity * object_size)); if(array_ptr) { array_ptr->length = new_length; @@ -109,7 +110,7 @@ struct Array* array_reallocate(struct Array* array) if((array->length << 2) < array->capacity && array->capacity > ARRAY_MIN_CAPACITY) { array->capacity = array->capacity >> 1; - array = realloc(array, sizeof(*array) + (array->object_size * array->capacity)); + array = memory_reallocate(array, sizeof(*array) + (array->object_size * array->capacity)); /* TODO: Maybe error handling here? */ } return array; @@ -126,9 +127,7 @@ int array_remove_at_(void** array, int index) { char* current_location = array_ptr->data + (array_ptr->object_size * index); char* location_after_obj = current_location + array_ptr->object_size; - memmove(current_location, - location_after_obj, - array_ptr->object_size * (array_ptr->length - next_index)); + memmove(current_location, location_after_obj, array_ptr->object_size * (array_ptr->length - next_index)); array_ptr->length--; if(!(array_ptr = array_reallocate(array_ptr))) success = 0; @@ -182,8 +181,7 @@ void array_inc_cap_by_(void** array, int cap) if(cap > 0) { array_ptr->capacity += cap; - char* new_data = realloc(array_ptr, - sizeof(*array_ptr) + (array_ptr->object_size * array_ptr->capacity)); + char* new_data = memory_reallocate(array_ptr, sizeof(*array_ptr) + (array_ptr->object_size * array_ptr->capacity)); if(new_data) { array_ptr = (struct Array*)new_data; diff --git a/src/common/hashmap.c b/src/common/hashmap.c index a53c00d..6a4fdb1 100755 --- a/src/common/hashmap.c +++ b/src/common/hashmap.c @@ -2,6 +2,7 @@ #include "variant.h" #include "log.h" #include "string_utils.h" +#include "memory_utils.h" #include #include @@ -31,7 +32,7 @@ static struct Hashmap_Entry* hashmap_entry_new(struct Hashmap* hashmap, const ch if(strncmp(key, hashmap->buckets[index][i].key, MAX_HASH_KEY_LEN) == 0) { new_entry = &hashmap->buckets[index][i]; - if(new_entry->key) free(new_entry->key); + if(new_entry->key) memory_free(new_entry->key); break; } } @@ -53,7 +54,7 @@ unsigned int hashmap_generate_hash(const char* key) struct Hashmap* hashmap_create(void) { - struct Hashmap* hashmap = malloc(sizeof(*hashmap)); + struct Hashmap* hashmap = memory_allocate(sizeof(*hashmap)); if(!hashmap) return NULL; for(int i = 0; i < HASH_MAP_NUM_BUCKETS; i++) @@ -73,7 +74,7 @@ void hashmap_free(struct Hashmap* hashmap) struct Hashmap_Entry* entry = &hashmap->buckets[i][j]; if(entry->key) { - free(entry->key); + memory_free(entry->key); entry->key = NULL; } variant_free(&entry->value); @@ -81,7 +82,7 @@ void hashmap_free(struct Hashmap* hashmap) array_free(hashmap->buckets[i]); hashmap->buckets[i] = NULL; } - free(hashmap); + memory_free(hashmap); hashmap = NULL; } diff --git a/src/common/memory_utils.c b/src/common/memory_utils.c new file mode 100644 index 0000000..b754ce5 --- /dev/null +++ b/src/common/memory_utils.c @@ -0,0 +1,81 @@ +#include "memory_utils.h" +#include "log.h" + +#include + +static struct Memory memory = { .allocated = 0, .freed = 0 }; + +struct Memory_Allocation* memory_get_allocation_ptr(void* memory_block) +{ + return (struct Memory_Allocation*)((unsigned char*) memory_block - offsetof(struct Memory_Allocation, allocation)); +} + +void* memory_allocate(size_t size) +{ + struct Memory_Allocation* allocation = malloc(sizeof(*allocation) + size); + if(!allocation) + { + log_raw("MEMORY: Failed to allocate memory of size %d", size); + } + else + { + allocation->size = size; + //memory->allocated += size; + memory.allocated += size + sizeof(*allocation); + } + return allocation->allocation; +} + +void* memory_reallocate_(void** ptr, size_t size) +{ + if(ptr != NULL && *ptr == NULL) // Behave like malloc + { + return memory_allocate(size); + } + + struct Memory_Allocation* current_allocation = memory_get_allocation_ptr(*ptr); + void* reallocated_memory = realloc(current_allocation, sizeof(*current_allocation) + size); + if(!reallocated_memory) + { + log_raw("MEMORY: Failed to reallocated memory of size %d", size); + } + else + { + current_allocation = reallocated_memory; + memory.allocated += (size - current_allocation->size); + current_allocation->size = size; + } + + return current_allocation->allocation; + +} + +void* memory_allocate_and_clear(size_t count, size_t size) +{ + struct Memory_Allocation* allocation = calloc(count, sizeof(*allocation) + size); + if(!allocation) + { + log_raw("MEMORY: Failed to allocate memory of size %d", size); + } + else + { + allocation->size = size; + //memory->allocated += size; + memory.allocated += size + sizeof(*allocation); + } + return allocation->allocation; +} + +void memory_free(void* ptr) +{ + if(!ptr) return; + struct Memory_Allocation* allocation = memory_get_allocation_ptr(ptr); + //memory->allocated -= allocation->size; + memory.allocated -= allocation->size + sizeof(*allocation); + free(allocation); +} + +struct Memory* memory_get(void) +{ + return &memory; +} diff --git a/src/common/memory_utils.h b/src/common/memory_utils.h new file mode 100644 index 0000000..a2eefdb --- /dev/null +++ b/src/common/memory_utils.h @@ -0,0 +1,26 @@ +#ifndef MEMORY_UTILS_H +#define MEMORY_UTILS_H + +#include + +struct Memory +{ + size_t allocated; + size_t freed; +}; + +struct Memory_Allocation +{ + size_t size; + unsigned char allocation[]; +}; + +void* memory_allocate(size_t size); +void* memory_reallocate_(void** ptr, size_t size); +void* memory_allocate_and_clear(size_t count, size_t size); +void memory_free(void* ptr); +struct Memory* memory_get(void); + +#define memory_reallocate(ptr, size) memory_reallocate_(&ptr, size); + +#endif diff --git a/src/common/parser.c b/src/common/parser.c index 30574e4..e3b0573 100755 --- a/src/common/parser.c +++ b/src/common/parser.c @@ -4,6 +4,7 @@ #include "array.h" #include "log.h" #include "string_utils.h" +#include "memory_utils.h" #include #include @@ -80,7 +81,7 @@ struct Parser* parser_load_objects(FILE* file, const char* filename) return false; } - struct Parser* parser = malloc(sizeof(*parser)); + struct Parser* parser = memory_allocate(sizeof(*parser)); if(!parser) { log_error("parser:load_objects", "Out of memeory"); @@ -279,13 +280,13 @@ void parser_free(struct Parser *parser) object->type = PO_UNKNOWN; } array_free(parser->objects); - free(parser); + memory_free(parser); } struct Parser* parser_new(void) { struct Parser* parser = NULL; - parser = malloc(sizeof(*parser)); + parser = memory_allocate(sizeof(*parser)); if(!parser) { log_error("parser:new", "Out of memory"); @@ -296,7 +297,7 @@ struct Parser* parser_new(void) if(!parser->objects) { log_error("parser:new", "Could not create objects array for parser"); - free(parser); + memory_free(parser); return NULL; } diff --git a/src/common/string_utils.c b/src/common/string_utils.c index fdee76c..a18c1e4 100755 --- a/src/common/string_utils.c +++ b/src/common/string_utils.c @@ -3,6 +3,7 @@ #include #include +#include "memory_utils.h" #include "string_utils.h" #include "array.h" #include "log.h" @@ -25,7 +26,7 @@ char* str_new(const char* string, ...) } length++; - new_string = malloc(length); + new_string = memory_allocate(length); if(!new_string) { log_error("str_new", "Malloc failed, out of memory!"); @@ -38,7 +39,7 @@ char* str_new(const char* string, ...) if(length < 0) { log_error("str_new", "Writing to new string failed"); - free(new_string); + memory_free(new_string); return new_string; } va_end(list); @@ -50,7 +51,7 @@ char* str_concat(char* string, const char* str_to_concat) size_t length = strlen(str_to_concat); size_t length_orig = string ? strlen(string) : 0; - char* temp = realloc(string, length + length_orig + 1); /* +1 at the end to cope for null byte */ + char* temp = memory_reallocate(string, length + length_orig + 1); /* +1 at the end to cope for null byte */ if(temp) { string = temp; @@ -61,73 +62,73 @@ char* str_concat(char* string, const char* str_to_concat) char* str_replace(char* string, const char* pattern, const char* replacement) { - int* indices = array_new(int); - size_t string_len = strlen(string); + int* indices = array_new(int); + size_t string_len = strlen(string); - /* Calculate size of new string and allocate new memory */ - size_t pattern_len = strlen(pattern); - size_t replacement_len = strlen(replacement); + /* Calculate size of new string and allocate new memory */ + size_t pattern_len = strlen(pattern); + size_t replacement_len = strlen(replacement); - int done = 0; - char* remaining_string = string; - while(!done) - { - char* location = strstr(remaining_string, pattern); - if(location) + int done = 0; + char* remaining_string = string; + while(!done) { - int index = (int)(location - string); - array_push(indices, index, int); - remaining_string = location + pattern_len; /* Find the next occurance in the remaining string */ + char* location = strstr(remaining_string, pattern); + if(location) + { + int index = (int)(location - string); + array_push(indices, index, int); + remaining_string = location + pattern_len; /* Find the next occurance in the remaining string */ + } + else + { + done = 1; + } } - else + + int num_indices = array_len(indices); + if(num_indices > 0) { - done = 1; - } - } + size_t string_len_without_pattern = string_len - (pattern_len * num_indices); + size_t new_string_len = string_len_without_pattern + (replacement_len * num_indices); + char* new_string = memory_allocate(new_string_len); - int num_indices = array_len(indices); - if(num_indices > 0) - { - size_t string_len_without_pattern = string_len - (pattern_len * num_indices); - size_t new_string_len = string_len_without_pattern + (replacement_len * num_indices); - char* new_string = malloc(new_string_len); + if(new_string) + { + done = 0; + int count = 0; + int index = indices[count]; + int prev_index = 0; + while(!done) + { + char* source_beg = string + prev_index; + char* source_end = string + index; - if(new_string) - { - done = 0; - int count = 0; - int index = indices[count]; - int prev_index = 0; - while(!done) - { - char* source_beg = string + prev_index; - char* source_end = string + index; + strncat(new_string, source_beg, (source_end - source_beg)); + strcat(new_string, replacement); - strncat(new_string, source_beg, (source_end - source_beg)); - strcat(new_string, replacement); + count++; + prev_index = index + pattern_len; - count++; - prev_index = index + pattern_len; - - if(count == array_len(indices)) - { - done = 1; - source_beg = string + prev_index; - strcat(new_string, source_beg); + if(count == array_len(indices)) + { + done = 1; + source_beg = string + prev_index; + strcat(new_string, source_beg); + } + else + { + index = indices[count]; + } + } + memory_free(string); } - else - { - index = indices[count]; - } - } - free(string); - } - array_free(indices); - return new_string; - } - else - { - return NULL; - } + array_free(indices); + return new_string; + } + else + { + return NULL; + } } diff --git a/src/common/variant.c b/src/common/variant.c index 9213f2a..84605a1 100755 --- a/src/common/variant.c +++ b/src/common/variant.c @@ -1,6 +1,7 @@ #include "variant.h" #include "log.h" #include "string_utils.h" +#include "memory_utils.h" #include #include @@ -116,7 +117,7 @@ void variant_assign_quatf(struct Variant* variant, const float x, const float y, void variant_assign_mat4(struct Variant* variant, const mat4* source) { if(variant->type != VT_MAT4) variant_free(variant); - variant->val_mat4 = malloc(sizeof(mat4)); + variant->val_mat4 = memory_allocate(sizeof(mat4)); if(!variant->val_mat4) { log_error("variant_init_mat4", "Out of memory"); @@ -139,14 +140,14 @@ void variant_free(struct Variant* variant) case VT_MAT4: if(variant->val_mat4) { - free(variant->val_mat4); + memory_free(variant->val_mat4); variant->val_mat4 = NULL; } break; case VT_STR: if(variant->val_str) { - free(variant->val_str); + memory_free(variant->val_str); variant->val_str = NULL; } break; diff --git a/src/common/version.h b/src/common/version.h index ae5e7ac..0daa88e 100755 --- a/src/common/version.h +++ b/src/common/version.h @@ -4,7 +4,7 @@ /* Auto generated version file. DO NOT MODIFY */ #define SYMMETRY_VERSION_MAJOR 0 #define SYMMETRY_VERSION_MINOR 2 -#define SYMMETRY_VERSION_REVISION 364 +#define SYMMETRY_VERSION_REVISION 365 #define SYMMETRY_VERSION_BRANCH "dev" #endif \ No newline at end of file diff --git a/src/game/game.c b/src/game/game.c index 4313d00..45fbfa1 100755 --- a/src/game/game.c +++ b/src/game/game.c @@ -31,6 +31,7 @@ #include "../common/hashmap.h" #include "../common/variant.h" #include "../system/platform.h" +#include "../common/memory_utils.h" #include "debug_vars.h" #include "im_render.h" #include "event.h" @@ -61,7 +62,7 @@ static struct Game_State* game_state = NULL; bool game_init(struct Window* window, struct Hashmap* cvars) { - game_state = malloc(sizeof(*game_state)); + game_state = memory_allocate(sizeof(*game_state)); if(!game_state) { log_error("game:init", "Out of memory, failed to allocate game_state"); @@ -76,15 +77,15 @@ bool game_init(struct Window* window, struct Hashmap* cvars) game_state->update_scene = true; game_state->fixed_delta_time = 1.f / 60.f; game_state->game_mode = GAME_MODE_GAME; - game_state->renderer = calloc(1, sizeof(*game_state->renderer)); - game_state->scene = calloc(1, sizeof(*game_state->scene)); - game_state->console = calloc(1, sizeof(*game_state->console)); - game_state->editor = calloc(1, sizeof(*game_state->editor)); - game_state->gui_editor = calloc(1, sizeof(*game_state->gui_editor)); - game_state->gui_game = calloc(1, sizeof(*game_state->gui_game)); - game_state->event_manager = calloc(1, sizeof(*game_state->event_manager)); - game_state->sound = calloc(1, sizeof(*game_state->sound)); - game_state->debug_vars = calloc(1, sizeof(*game_state->debug_vars)); + game_state->renderer = memory_allocate_and_clear(1, sizeof(*game_state->renderer)); + game_state->scene = memory_allocate_and_clear(1, sizeof(*game_state->scene)); + game_state->console = memory_allocate_and_clear(1, sizeof(*game_state->console)); + game_state->editor = memory_allocate_and_clear(1, sizeof(*game_state->editor)); + game_state->gui_editor = memory_allocate_and_clear(1, sizeof(*game_state->gui_editor)); + game_state->gui_game = memory_allocate_and_clear(1, sizeof(*game_state->gui_game)); + game_state->event_manager = memory_allocate_and_clear(1, sizeof(*game_state->event_manager)); + game_state->sound = memory_allocate_and_clear(1, sizeof(*game_state->sound)); + game_state->debug_vars = memory_allocate_and_clear(1, sizeof(*game_state->debug_vars)); game_state->scene_func_table = hashmap_create(); log_message_callback_set(game_on_log_message); @@ -1991,18 +1992,18 @@ void game_cleanup(void) debug_vars_cleanup(game_state->debug_vars); event_manager_cleanup(game_state->event_manager); - free(game_state->editor); - free(game_state->console); - free(game_state->scene); - free(game_state->renderer); - free(game_state->event_manager); - free(game_state->gui_editor); - free(game_state->gui_game); - free(game_state->sound); - free(game_state->debug_vars); + memory_free(game_state->editor); + memory_free(game_state->console); + memory_free(game_state->scene); + memory_free(game_state->renderer); + memory_free(game_state->event_manager); + memory_free(game_state->gui_editor); + memory_free(game_state->gui_game); + memory_free(game_state->sound); + memory_free(game_state->debug_vars); hashmap_free(game_state->scene_func_table); } - free(game_state); + memory_free(game_state); game_state = NULL; } } diff --git a/src/game/geometry.c b/src/game/geometry.c index c850f93..cf10ee5 100755 --- a/src/game/geometry.c +++ b/src/game/geometry.c @@ -1,6 +1,7 @@ #include "geometry.h" #include "../common/array.h" #include "../common/string_utils.h" +#include "../common/memory_utils.h" #include "../common/log.h" #include "renderer.h" #include "transform.h" @@ -117,7 +118,7 @@ int geom_create_from_file(const char* name) char* full_path = str_new("models/%s", name); FILE* file = io_file_open(DIRT_INSTALL, full_path, "rb"); - free(full_path); + memory_free(full_path); if(file) { const uint32 INDEX_SIZE = sizeof(uint32); @@ -212,7 +213,7 @@ void geom_remove(int index) geometry->ref_count--; if(geometry->ref_count < 0) { - if(geometry->filename) free(geometry->filename); + if(geometry->filename) memory_free(geometry->filename); geometry->filename = NULL; glDeleteBuffers(1, &geometry->vertex_vbo); diff --git a/src/game/glad.c b/src/game/glad.c index 488bcce..a730547 100755 --- a/src/game/glad.c +++ b/src/game/glad.c @@ -23,6 +23,8 @@ #include #include +#include "../common/memory_utils.h" + struct gladGLversionStruct GLVersion; #if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0) @@ -48,7 +50,7 @@ static int get_exts(void) { num_exts_i = 0; glGetIntegerv(GL_NUM_EXTENSIONS, &num_exts_i); if (num_exts_i > 0) { - exts_i = (const char **)realloc((void *)exts_i, (size_t)num_exts_i * (sizeof *exts_i)); + exts_i = (const char **)memory_reallocate((void *)exts_i, (size_t)num_exts_i * (sizeof *exts_i)); } if (exts_i == NULL) { @@ -59,7 +61,7 @@ static int get_exts(void) { const char *gl_str_tmp = (const char*)glGetStringi(GL_EXTENSIONS, index); size_t len = strlen(gl_str_tmp); - char *local_str = (char*)malloc((len+1) * sizeof(char)); + char *local_str = (char*)memory_allocate((len+1) * sizeof(char)); if(local_str != NULL) { #if _MSC_VER >= 1400 strncpy_s(local_str, len+1, gl_str_tmp, len); @@ -78,9 +80,9 @@ static void free_exts(void) { if (exts_i != NULL) { int index; for(index = 0; index < num_exts_i; index++) { - free((char *)exts_i[index]); + memory_free((char *)exts_i[index]); } - free((void *)exts_i); + memory_free((void *)exts_i); exts_i = NULL; } } diff --git a/src/game/gui.c b/src/game/gui.c index 3ef5be0..4cc109e 100755 --- a/src/game/gui.c +++ b/src/game/gui.c @@ -9,6 +9,7 @@ #include "input.h" #include "renderer.h" #include "../common/string_utils.h" +#include "../common/memory_utils.h" #include "../system/platform.h" #include "../system/file_io.h" #include "event.h" @@ -25,14 +26,17 @@ struct Gui_Vertex #define MAX_GUI_VERTEX_MEMORY 512 * 1024 #define MAX_GUI_ELEMENT_MEMORY 128 * 1024 - -static void gui_on_clipbard_copy(nk_handle usr, const char *text, int len); -static void gui_on_clipbard_paste(nk_handle usr, struct nk_text_edit *edit); -static void gui_on_textinput(const struct Event* event); -static void gui_on_mousewheel(const struct Event* event); -static void gui_on_mousemotion(const struct Event* event); -static void gui_on_mousebutton(const struct Event* event); -static void gui_on_key(const struct Event* event); +#define GUI_BUFFER_SIZE_INITIAL (4 * 1024) + +static void gui_on_clipbard_copy(nk_handle usr, const char *text, int len); +static void gui_on_clipbard_paste(nk_handle usr, struct nk_text_edit *edit); +static void gui_on_textinput(const struct Event* event); +static void gui_on_mousewheel(const struct Event* event); +static void gui_on_mousemotion(const struct Event* event); +static void gui_on_mousebutton(const struct Event* event); +static void gui_on_key(const struct Event* event); +static void* gui_allocate_wrapper(nk_handle handle, void* old, nk_size size); +static void gui_free_wrapper(nk_handle handle, void* old); static void gui_upload_atlas(struct Gui* gui, const void *image, int width, int height); static void gui_font_set_default(struct Gui* gui); @@ -41,8 +45,12 @@ bool gui_init(struct Gui* gui) { bool success = false; - nk_init_default(&gui->context, 0); - nk_buffer_init_default(&gui->cmds); + //nk_init_default(&gui->context, 0); + //nk_buffer_init_default(&gui->commands); + nk_init(&gui->context, &(struct nk_allocator) {.userdata = NULL, .alloc = &gui_allocate_wrapper, .free = &gui_free_wrapper}, 0); + nk_buffer_init(&gui->commands, &(struct nk_allocator) {.userdata = NULL, .alloc = &gui_allocate_wrapper, .free = &gui_free_wrapper}, GUI_BUFFER_SIZE_INITIAL); + nk_font_atlas_init(&gui->atlas, &(struct nk_allocator) {.userdata = NULL, .alloc = &gui_allocate_wrapper, .free = &gui_free_wrapper}); + gui->context.clip.copy = gui_on_clipbard_copy; gui->context.clip.paste = gui_on_clipbard_paste; gui->context.clip.userdata = nk_handle_ptr(0); @@ -51,7 +59,7 @@ bool gui_init(struct Gui* gui) if(gui->shader < 0) { log_error("gui:init", "Failed to create shader for gui"); - free(gui); + memory_free(gui); return success; } gui->uniform_tex = shader_get_uniform_location(gui->shader, "sampler"); @@ -137,7 +145,7 @@ void gui_cleanup(struct Gui* gui) texture_remove(gui->font_tex); glDeleteBuffers(1, &gui->vbo); glDeleteBuffers(1, &gui->ebo); - nk_buffer_free(&gui->cmds); + nk_buffer_free(&gui->commands); } void gui_render(struct Gui* gui, enum nk_anti_aliasing AA) @@ -212,13 +220,13 @@ void gui_render(struct Gui* gui, enum nk_anti_aliasing AA) struct nk_buffer vbuf, ebuf; nk_buffer_init_fixed(&vbuf, vertices, (nk_size)MAX_GUI_VERTEX_MEMORY); nk_buffer_init_fixed(&ebuf, elements, (nk_size)MAX_GUI_ELEMENT_MEMORY); - nk_convert(&gui->context, &gui->cmds, &vbuf, &ebuf, &config); + nk_convert(&gui->context, &gui->commands, &vbuf, &ebuf, &config); } glUnmapBuffer(GL_ARRAY_BUFFER); glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); /* iterate over and execute each draw command */ - nk_draw_foreach(cmd, &gui->context, &gui->cmds) + nk_draw_foreach(cmd, &gui->context, &gui->commands) { if (!cmd->elem_count) continue; texture_bind(cmd->texture.id); @@ -247,7 +255,7 @@ void gui_on_clipbard_paste(nk_handle usr, struct nk_text_edit *edit) if(text) { nk_textedit_paste(edit, text, nk_strlen(text)); - free(text); + memory_free(text); } (void)usr; } @@ -257,12 +265,12 @@ void gui_on_clipbard_copy(nk_handle usr, const char *text, int len) char *str = 0; (void)usr; if (!len) return; - str = (char*)malloc((size_t)len+1); + str = (char*)memory_allocate((size_t)len+1); if (!str) return; memcpy(str, text, (size_t)len); str[len] = '\0'; platform_clipboard_text_set(str); - free(str); + memory_free(str); } void gui_on_key(const struct Event* event) @@ -408,7 +416,7 @@ void gui_font_set(struct Gui* gui, const char* font_name, float font_size) long size = 0; char* font_file_name = str_new("fonts/%s", font_name); char* font_data = io_file_read(DIRT_INSTALL, font_file_name, "rb", &size); - free(font_file_name); + memory_free(font_file_name); if(!font_data) { log_error("gui:init", "Could not load font %s, reverting to default", font_name); @@ -422,10 +430,11 @@ void gui_font_set(struct Gui* gui, const char* font_name, float font_size) texture_remove(gui->font_tex); gui->font_tex = -1; gui->current_font = NULL; + nk_font_atlas_init(&gui->atlas, &(struct nk_allocator) {.userdata = NULL, .alloc = &gui_allocate_wrapper, .free = &gui_free_wrapper}); } const void *image = NULL; int w = 0, h = 0; - nk_font_atlas_init_default(atlas); + //nk_font_atlas_init_default(atlas); nk_font_atlas_begin(atlas); struct nk_font *new_font = nk_font_atlas_add_from_memory(atlas, font_data, size, font_size, NULL); image = nk_font_atlas_bake(atlas, &w, &h, NK_FONT_ATLAS_RGBA32); @@ -442,7 +451,7 @@ void gui_font_set(struct Gui* gui, const char* font_name, float font_size) log_error("gui:init", "Could not add font %s, reverting to default", font_name); gui_font_set_default(gui); } - free(font_data); + memory_free(font_data); } } @@ -454,7 +463,7 @@ void gui_font_set_default(struct Gui* gui) texture_remove(gui->font_tex); } struct nk_font_atlas* atlas = &gui->atlas; - nk_font_atlas_init_default(atlas); + //nk_font_atlas_init_default(atlas); const void *image = NULL; int w = 0, h = 0; image = nk_font_atlas_bake(atlas, &w, &h, NK_FONT_ATLAS_RGBA32); @@ -606,3 +615,13 @@ void gui_theme_set(struct Gui* gui, enum Gui_Theme theme) nk_style_default(&gui->context); } } + +void* gui_allocate_wrapper(nk_handle handle, void* old, nk_size size) +{ + return memory_allocate(size); +} + +void gui_free_wrapper(nk_handle handle, void* old) +{ + memory_free(old); +} diff --git a/src/game/gui.h b/src/game/gui.h index 51e3fbc..8057424 100755 --- a/src/game/gui.h +++ b/src/game/gui.h @@ -2,7 +2,7 @@ #define GUI_H #define NK_INCLUDE_FIXED_TYPES -#define NK_INCLUDE_DEFAULT_ALLOCATOR +//#define NK_INCLUDE_DEFAULT_ALLOCATOR #define NK_INCLUDE_STANDARD_VARARGS #define NK_INCLUDE_STANDARD_IO #define NK_INCLUDE_FONT_BAKING @@ -17,15 +17,15 @@ struct Gui { - struct nk_buffer cmds; + struct nk_buffer commands; struct nk_draw_null_texture null; struct nk_context context; struct nk_font_atlas atlas; struct nk_font* current_font; GLuint vbo, vao, ebo; int shader; - GLuint vert_shdr; - GLuint frag_shdr; + GLuint vertex_shader; + GLuint fragment_shader; GLint attrib_pos; GLint attrib_uv; GLint attrib_col; diff --git a/src/game/gui_game.c b/src/game/gui_game.c index 5aa3a21..a2a268b 100644 --- a/src/game/gui_game.c +++ b/src/game/gui_game.c @@ -2,6 +2,7 @@ #include "game.h" #include "scene.h" #include "../common/log.h" +#include "../common/memory_utils.h" #include "../system/platform.h" #include "event.h" #include "input.h" @@ -20,7 +21,7 @@ static void gui_game_on_scene_cleared(struct Event* event); void gui_game_init(struct Game_Gui* game_gui) { - game_gui->gui = calloc(1, sizeof(*game_gui->gui)); + game_gui->gui = memory_allocate_and_clear(1, sizeof(*game_gui->gui)); gui_init(game_gui->gui); game_gui->show_next_level_dialog = false; game_gui->show_restart_level_dialog = false; @@ -54,7 +55,7 @@ void gui_game_cleanup(struct Game_Gui* game_gui) { texture_remove(game_gui->skin.skin_texture); gui_cleanup(game_gui->gui); - free(game_gui->gui); + memory_free(game_gui->gui); struct Event_Manager* event_manager = game_state_get()->event_manager; event_manager_unsubscribe(event_manager, EVT_PLAYER_DIED, &gui_game_on_player_death); diff --git a/src/game/input.c b/src/game/input.c index 86443e5..df5596d 100755 --- a/src/game/input.c +++ b/src/game/input.c @@ -6,6 +6,7 @@ #include "../common/log.h" #include "gui.h" #include "../common/string_utils.h" +#include "../common/memory_utils.h" #include "../common/hashmap.h" #include "../common/variant.h" #include "../common/parser.h" @@ -88,7 +89,7 @@ void input_cleanup(void) struct Variant* value = NULL; HASHMAP_FOREACH(key_bindings, key, value) { - free(value->val_voidptr); + memory_free(value->val_voidptr); } hashmap_free(key_bindings); @@ -339,7 +340,7 @@ bool input_map_create(const char* name, struct Key_Binding key_combination) input_map_remove(name); } - struct Key_Binding* new_keybinding = malloc(sizeof(*new_keybinding)); + struct Key_Binding* new_keybinding = memory_allocate(sizeof(*new_keybinding)); if(!new_keybinding) { log_error("input:map_create", "Out of memory"); @@ -382,7 +383,7 @@ bool input_map_remove(const char* name) if(hashmap_value_exists(key_bindings, name)) { struct Key_Binding* current_key = (struct Key_Binding*)hashmap_ptr_get(key_bindings, name); - free(current_key); + memory_free(current_key); hashmap_value_remove(key_bindings, name); } else diff --git a/src/game/renderer.c b/src/game/renderer.c index c1ea582..c6ab177 100755 --- a/src/game/renderer.c +++ b/src/game/renderer.c @@ -15,6 +15,7 @@ #include "game.h" #include "gui.h" #include "../common/hashmap.h" +#include "../common/memory_utils.h" #include "geometry.h" #include "material.h" #include "editor.h" @@ -61,7 +62,7 @@ void renderer_init(struct Renderer* renderer) renderer->settings.ambient_light = hashmap_vec3_get(cvars, "ambient_light"); renderer->debug_shader = shader_create("debug.vert", "debug.frag", NULL); - renderer->sprite_batch = malloc(sizeof(*renderer->sprite_batch)); + renderer->sprite_batch = memory_allocate(sizeof(*renderer->sprite_batch)); if(!renderer->sprite_batch) log_error("renderer:init", "Failed to allocated sprite batch"); @@ -314,7 +315,7 @@ void renderer_cleanup(struct Renderer* renderer) } im_cleanup(); sprite_batch_remove(renderer->sprite_batch); - free(renderer->sprite_batch); + memory_free(renderer->sprite_batch); } void renderer_on_framebuffer_size_changed(const struct Event* event) diff --git a/src/game/shader.c b/src/game/shader.c index fd00b61..d4ef028 100755 --- a/src/game/shader.c +++ b/src/game/shader.c @@ -2,6 +2,7 @@ #include "../common/array.h" #include "../common/num_types.h" #include "../common/string_utils.h" +#include "../common/memory_utils.h" #include "../common/log.h" #include "renderer.h" #include "texture.h" @@ -57,9 +58,9 @@ char* run_preprocessor(char* shader_text, const char* custom_defines) if(file_contents) { char* shader_text_new = str_new("%s\n%s", file_contents, shader_text); - free(shader_text); - free(file_contents); - free(path); + memory_free(shader_text); + memory_free(file_contents); + memory_free(path); shader_text = shader_text_new; } } @@ -71,13 +72,13 @@ char* run_preprocessor(char* shader_text, const char* custom_defines) if(custom_defines) { char* shader_text_with_custom_defines = str_new("%s\n%s", custom_defines, shader_text); - free(shader_text); + memory_free(shader_text); shader_text = shader_text_with_custom_defines; } // Insert #version line at the top char* shader_text_with_version = str_new("%s\n%s", GLSL_VERSION_STR, shader_text); - free(shader_text); + memory_free(shader_text); shader_text = shader_text_with_version; return shader_text; @@ -126,28 +127,28 @@ int shader_create(const char* vert_shader_name, const char* frag_shader_name, co { GLint log_size = 0; GL_CHECK(glGetShaderiv(vert_shader, GL_INFO_LOG_LENGTH, &log_size)); - char* message = (char *)malloc(sizeof(char) * log_size); + char* message = (char *)memory_allocate(sizeof(char) * log_size); GL_CHECK(glGetShaderInfoLog(vert_shader, log_size, NULL, message)); log_error("shader:create", "COMPILING VS %s : %s", vert_shader_name, message); debug_print_shader(vert_source); - free(message); + memory_free(message); } if(!is_frag_compiled) { GLint log_size = 0; GL_CHECK(glGetShaderiv(frag_shader, GL_INFO_LOG_LENGTH, &log_size)); - char* message = (char *)malloc(sizeof(char) * log_size); + char* message = (char *)memory_allocate(sizeof(char) * log_size); GL_CHECK(glGetShaderInfoLog(frag_shader, log_size, NULL, message)); log_error("shader:create", "COMPILING FS %s : %s", frag_shader_name, message); debug_print_shader(frag_source); - free(message); + memory_free(message); } - free(vert_source); - free(frag_source); + memory_free(vert_source); + memory_free(frag_source); if(!is_vert_compiled || !is_frag_compiled) { @@ -173,10 +174,10 @@ int shader_create(const char* vert_shader_name, const char* frag_shader_name, co { GLint log_size = 0; GL_CHECK(glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_size)); - char* message = (char *)malloc(sizeof(char) * log_size); + char* message = (char *)memory_allocate(sizeof(char) * log_size); GL_CHECK(glGetProgramInfoLog(program, log_size, NULL, message)); log_error("shader:create", "LINK SHADER : %s", message); - free(message); + memory_free(message); GL_CHECK(glDeleteProgram(program)); GL_CHECK(glDeleteShader(vert_shader)); @@ -208,8 +209,8 @@ int shader_create(const char* vert_shader_name, const char* frag_shader_name, co *new_shader = program; log_message("%s, %s compiled into shader program", vert_shader_name, frag_shader_name); - free(vs_path); - free(fs_path); + memory_free(vs_path); + memory_free(fs_path); return index; } diff --git a/src/game/texture.c b/src/game/texture.c index ebdc7fa..53f0ed7 100755 --- a/src/game/texture.c +++ b/src/game/texture.c @@ -1,6 +1,7 @@ #include "texture.h" #include "../common/array.h" #include "../common/string_utils.h" +#include "../common/memory_utils.h" #include "../common/log.h" #include "../common/num_types.h" #include "renderer.h" @@ -93,7 +94,7 @@ int texture_create_from_file(const char* filename, int texture_unit) { log_error("texture:create_from_file", "Error creating texture"); } - if(img_data) free(img_data); + if(img_data) memory_free(img_data); } fclose(file); } @@ -101,7 +102,7 @@ int texture_create_from_file(const char* filename, int texture_unit) { log_error("texture:create_from_file", "Could not open file %s", filename); } - free(full_path); + memory_free(full_path); return index; } @@ -116,7 +117,7 @@ void texture_remove(int index) if(texture->ref_count < 0) { glDeleteTextures(1, &texture->handle); - if(texture->name) free(texture->name); + if(texture->name) memory_free(texture->name); texture->name = NULL; texture->ref_count = -1; texture->texture_unit = -1; @@ -214,7 +215,7 @@ int load_img(FILE* file, GLubyte** image_data, int* width, int* height, int* fmt size_t bytes_per_pixel = header.bitsperpixel / 8; size_t image_size = (bytes_per_pixel * header.width * header.height); - *image_data = malloc(image_size); + *image_data = memory_allocate(image_size); if(!*image_data) { log_error("texture:load_img", "Out of memory"); @@ -237,7 +238,7 @@ int load_img(FILE* file, GLubyte** image_data, int* width, int* height, int* fmt if(fread(&pixel, 1, bytes_per_pixel, file) != bytes_per_pixel) { log_error("texture:load_img", "Unexpected end of file at pixel %d", i); - free(*image_data); + memory_free(*image_data); *image_data = NULL; return success; } @@ -258,7 +259,7 @@ int load_img(FILE* file, GLubyte** image_data, int* width, int* height, int* fmt if(fread(chunk, 1, chunk_size, file) != chunk_size) { log_error("texture:img_load", "Unexpected end of file at chunk %d", i); - free(*image_data); + memory_free(*image_data); *image_data = NULL; return success; } @@ -283,7 +284,7 @@ int load_img(FILE* file, GLubyte** image_data, int* width, int* height, int* fmt if(fread(&chunk[1], 1, bytes_per_pixel, file) != bytes_per_pixel) { log_error("texture:img_load", "Unexpected end of file at pixel %d", i); - free(*image_data); + memory_free(*image_data); *image_data = NULL; return success; } diff --git a/src/system/file_io.c b/src/system/file_io.c index f5b990a..52b972f 100755 --- a/src/system/file_io.c +++ b/src/system/file_io.c @@ -6,6 +6,7 @@ #include "file_io.h" #include "../common/log.h" #include "../common/string_utils.h" +#include "../common/memory_utils.h" static char* executable_directory = NULL; static char* install_directory = NULL; @@ -22,9 +23,9 @@ void io_file_init(const char* install_dir, const char* user_dir) void io_file_cleanup(void) { - if(install_directory) free(install_directory); - if(executable_directory) free(executable_directory); - if(user_directory) free(user_directory); + if(install_directory) memory_free(install_directory); + if(executable_directory) memory_free(executable_directory); + if(user_directory) memory_free(user_directory); install_directory = NULL; user_directory = NULL; } @@ -40,7 +41,7 @@ char* io_file_read(const int directory_type, const char* path, const char* mode, long length = (size_t)ftell(file); if(file_size) *file_size = length; rewind(file); - data = calloc(1, (sizeof(char) * length) + 1); + data = memory_allocate_and_clear(1, (sizeof(char) * length) + 1); if(data) { if(fread(data, length, 1, file) > 0) @@ -50,7 +51,7 @@ char* io_file_read(const int directory_type, const char* path, const char* mode, else { log_error("io:file_read", "fread failed"); - free(data); + memory_free(data); } } else @@ -86,7 +87,7 @@ FILE* io_file_open(const int directory_type, const char* path, const char* mode) perror(&err_str[0]); log_error("io:file_open", "Failed to open file '%s' (%s)", relative_path, err_str); } - free(relative_path); + memory_free(relative_path); return file; } @@ -115,7 +116,7 @@ bool io_file_copy(const int directory_type, const char* source, const char* dest } log_message("'%s' copied to '%s'", source, destination); - free(source_contents); + memory_free(source_contents); fclose(dest_file); return success; @@ -136,7 +137,7 @@ bool io_file_delete(const int directory_type, const char* filename) log_message("'%s' deleted", filename); } - free(relative_path); + memory_free(relative_path); return true; } diff --git a/src/system/main.c b/src/system/main.c index 9e0d396..df04b2b 100755 --- a/src/system/main.c +++ b/src/system/main.c @@ -8,6 +8,7 @@ #include "config_vars.h" #include "../common/hashmap.h" #include "../game/game.h" +#include "../common/memory_utils.h" struct Wndow; @@ -59,8 +60,8 @@ bool init(void) char* user_path = platform_user_directory_get("SS_Games", "Symmetry"); log_init("Log.txt", user_path); io_file_init(install_path, user_path); - free(install_path); - free(user_path); + memory_free(install_path); + memory_free(user_path); if(!config_vars_load(cvars, "config.symtres", DIRT_USER)) { log_error("main:init", "Could not load config, reverting to defaults"); diff --git a/src/system/platform.c b/src/system/platform.c index 522c9ba..6cda0a7 100755 --- a/src/system/platform.c +++ b/src/system/platform.c @@ -3,6 +3,7 @@ #include "config_vars.h" #include "../common/hashmap.h" #include "../common/string_utils.h" +#include "../common/memory_utils.h" #include @@ -23,7 +24,7 @@ struct Window* window_create(const char* title, int width, int height, int msaa, struct Window* new_window = NULL; if(!new_window) { - new_window = malloc(sizeof(*new_window)); + new_window = memory_allocate(sizeof(*new_window)); if(!new_window) { log_error("window_create", "Out of memory"); @@ -63,7 +64,7 @@ struct Window* window_create(const char* title, int width, int height, int msaa, if(!sdl_window) { log_error("window_create:SDL_CreateWindow", "Could not create window : %s", SDL_GetError()); - free(new_window); + memory_free(new_window); new_window = NULL; return new_window; } @@ -74,7 +75,7 @@ struct Window* window_create(const char* title, int width, int height, int msaa, { log_error("window_create:SDL_GL_CreateContext", "Failed to create GL context : %s", SDL_GetError()); window_destroy(new_window); - free(new_window); + memory_free(new_window); new_window = NULL; return new_window; } @@ -351,7 +352,7 @@ void* platform_load_library(const char *name) #endif void* lib_handle = SDL_LoadObject(lib_name); if(!lib_handle) log_error("platform:load_library", "Failed to load library '%s', SDL : (%s)", lib_name, SDL_GetError()); - free(install_dir); + memory_free(install_dir); return lib_handle; } diff --git a/src/system/sound.c b/src/system/sound.c index c627625..5aa2e8b 100755 --- a/src/system/sound.c +++ b/src/system/sound.c @@ -4,6 +4,7 @@ #include "../common/hashmap.h" #include "../common/variant.h" #include "../common/string_utils.h" +#include "../common/memory_utils.h" #include "../game/entity.h" #include "../game/transform.h" @@ -250,7 +251,7 @@ struct Sound_Source_Buffer* sound_source_buffer_create(struct Sound* sound, cons } source->type = ST_WAV; source->wav = wave; - free(memory); + memory_free(memory); } break; case ST_WAV_STREAM: @@ -265,7 +266,7 @@ struct Sound_Source_Buffer* sound_source_buffer_create(struct Sound* sound, cons } source->type = ST_WAV_STREAM; source->wavstream = wave_stream; - free(memory); + memory_free(memory); } break; default: log_error("sound:source_create", "Invalid source type %d", type); break; diff --git a/todo.txt b/todo.txt index 203c9bd..8e0c6ba 100644 --- a/todo.txt +++ b/todo.txt @@ -1,11 +1,9 @@ Todo: - Game End - Add functionality to editor that enables adding a default empty entity without having to load it from file - - Fix crash when default entity type is loaded from file - Don't save parent entity's transform when saving entity archetype. Only save the transformation values for children - Save case sensitive file names when scene entity entries - Disbale all player actions when scene cleared dialog or scene restart dialog are active - - Memory utils that provide allocation tracking - Remove excessive repitition in scene and editor code that handles multiple entity types - Allow switching to editor mode when game is in pause mode - Rendering Additions: @@ -435,4 +433,6 @@ Done: * Player weapon mesh and lighting * Added muzzle mesh to player * Add weapon flash, muzzle mesh to turrets - * Enemies getting hit by bullets \ No newline at end of file + * Enemies getting hit by bullets + * Fixed crash when default entity type is loaded from file + * Memory utils that provide allocation tracking \ No newline at end of file