summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/assets.c30
-rw-r--r--src/assets.h5
-rw-r--r--src/linux/platform.c16
-rw-r--r--src/memory.h176
-rw-r--r--src/windows/platform.c14
5 files changed, 233 insertions, 8 deletions
diff --git a/src/assets.c b/src/assets.c
index e693d7f..e2452fb 100644
--- a/src/assets.c
+++ b/src/assets.c
@@ -33,8 +33,38 @@ inline static bool is_big_endian()
return !((*((uint8_t*)(&i))) == 0x67);
}
+void assets_stop_if_done()
+{
+ if (global_asset_collection.queue.queue.length == 0 && !global_asset_collection.done_loading_assets)
+ {
+ global_asset_collection.done_loading_assets = true;
+
+#ifdef MODE_TIMESTARTUP
+ abort();
+#endif
+
+#if defined(MODE_DEBUGMEM) && !defined(MODE_TEST)
+ printf("allocated at startup: %dkb\n", __total_allocated/1000);
+ printf("reallocated at startup: %dkb\n", __total_reallocated/1000);
+#endif
+
+#if defined(MODE_DEVELOPER) && !defined(MODE_TEST)
+ printf("frames drawn with missing assets: %d\n", __frames_drawn_with_missing_assets);
+#endif
+ }
+
+#ifdef MODE_DEVELOPER
+ if (global_asset_collection.queue.queue.length != 0 && !global_asset_collection.done_loading_assets)
+ {
+ __frames_drawn_with_missing_assets++;
+ }
+#endif
+}
+
bool assets_do_post_process()
{
+ assets_stop_if_done();
+
bool result = false;
mutex_lock(&asset_mutex);
diff --git a/src/assets.h b/src/assets.h
index 983ff41..1b0a6e7 100644
--- a/src/assets.h
+++ b/src/assets.h
@@ -19,6 +19,11 @@
#define ASSET_QUEUE_COUNT 20
#endif
+#ifdef MODE_DEVELOPER
+s32 __frames_drawn_with_missing_assets = 0;
+#endif
+
+
typedef struct t_image {
u8 *start_addr;
u8 *end_addr;
diff --git a/src/linux/platform.c b/src/linux/platform.c
index d654cac..5b94d92 100644
--- a/src/linux/platform.c
+++ b/src/linux/platform.c
@@ -58,6 +58,7 @@ struct t_platform_window
Atom _NET_WM_STATE;
// shared window properties
+ bool icon_loaded;
bool do_draw;
backbuffer backbuffer;
s32 width;
@@ -676,6 +677,15 @@ platform_window platform_open_window_ex(char *name, u16 width, u16 height, u16 m
bool has_max_size = max_w || max_h;
platform_window window;
+ window.width = width;
+ window.height = height;
+ window.min_width = min_w;
+ window.min_height = min_h;
+ window.max_width = max_w;
+ window.max_height = max_h;
+ window.backbuffer.buffer = 0;
+ window.gl_context = 0;
+ window.icon_loaded = false;
window.has_focus = true;
window.curr_cursor_type = CURSOR_DEFAULT;
window.next_cursor_type = CURSOR_DEFAULT;
@@ -1587,6 +1597,12 @@ inline void platform_run_command(char *command)
void platform_set_icon(platform_window *window, image *img)
{
+ if (!img->loaded) return;
+ if (!window->icon_loaded)
+ window->icon_loaded = true;
+ else
+ return;
+
s32 w = img->width;
s32 h = img->height;
diff --git a/src/memory.h b/src/memory.h
index 1457f21..0ebd070 100644
--- a/src/memory.h
+++ b/src/memory.h
@@ -7,14 +7,180 @@
#ifndef INCLUDE_MEMORY
#define INCLUDE_MEMORY
-#ifdef MODE_DEVELOPER
+#ifdef MODE_DEBUGMEM
+#include <stdio.h>
+#include <dbghelp.h>
+
+#define MEM_ENTRY_BUFFER_SIZE 50000
+
+typedef struct t_mem_entry
+{
+ bool valid;
+ void *p;
+ s32 size;
+ char *stacktrace;
+} __mem_entry;
+
+static __mem_entry *mem_entries;
+
static s32 __total_allocated = 0;
static s32 __total_reallocated = 0;
-#define mem_alloc(size) malloc(size); __total_allocated+=size
-#define mem_free(p) free(p)
-#define mem_realloc(p, size) realloc(p, size); __total_reallocated+=size
-#define memory_print_leaks() {}
+static void* __custom_alloc(s32 size)
+{
+ if (mem_entries == 0) {
+ mem_entries = malloc(sizeof(__mem_entry)*MEM_ENTRY_BUFFER_SIZE);
+ memset(mem_entries, 0, MEM_ENTRY_BUFFER_SIZE);
+ }
+
+ void* newp = malloc(size);
+
+ bool found = false;
+ for (s32 i = 0; i < MEM_ENTRY_BUFFER_SIZE; i++)
+ {
+ if (!mem_entries[i].valid)
+ {
+#ifdef OS_WIN
+ HANDLE process = GetCurrentProcess();
+ HANDLE thread = GetCurrentThread();
+
+ CONTEXT context;
+ memset(&context, 0, sizeof(CONTEXT));
+ context.ContextFlags = CONTEXT_FULL;
+ RtlCaptureContext(&context);
+
+ SymInitialize(process, NULL, TRUE);
+
+ DWORD image;
+ STACKFRAME64 stackframe;
+ ZeroMemory(&stackframe, sizeof(STACKFRAME64));
+
+#ifdef _M_IX86
+ image = IMAGE_FILE_MACHINE_I386;
+ stackframe.AddrPC.Offset = context.Eip;
+ stackframe.AddrPC.Mode = AddrModeFlat;
+ stackframe.AddrFrame.Offset = context.Ebp;
+ stackframe.AddrFrame.Mode = AddrModeFlat;
+ stackframe.AddrStack.Offset = context.Esp;
+ stackframe.AddrStack.Mode = AddrModeFlat;
+#elif _M_X64
+ image = IMAGE_FILE_MACHINE_AMD64;
+ stackframe.AddrPC.Offset = context.Rip;
+ stackframe.AddrPC.Mode = AddrModeFlat;
+ stackframe.AddrFrame.Offset = context.Rsp;
+ stackframe.AddrFrame.Mode = AddrModeFlat;
+ stackframe.AddrStack.Offset = context.Rsp;
+ stackframe.AddrStack.Mode = AddrModeFlat;
+#elif _M_IA64
+ image = IMAGE_FILE_MACHINE_IA64;
+ stackframe.AddrPC.Offset = context.StIIP;
+ stackframe.AddrPC.Mode = AddrModeFlat;
+ stackframe.AddrFrame.Offset = context.IntSp;
+ stackframe.AddrFrame.Mode = AddrModeFlat;
+ stackframe.AddrBStore.Offset = context.RsBSP;
+ stackframe.AddrBStore.Mode = AddrModeFlat;
+ stackframe.AddrStack.Offset = context.IntSp;
+ stackframe.AddrStack.Mode = AddrModeFlat;
+#endif
+
+ mem_entries[i].stacktrace = malloc(4000);
+ mem_entries[i].stacktrace[0] = 0;
+
+ for (size_t x = 0; i < 25; x++) {
+
+ BOOL result = StackWalk64(
+ image, process, thread,
+ &stackframe, &context, NULL,
+ SymFunctionTableAccess64, SymGetModuleBase64, NULL);
+
+ if (!result) { break; }
+
+ char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
+ PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer;
+ symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
+ symbol->MaxNameLen = MAX_SYM_NAME;
+
+ DWORD64 displacement = 0;
+ if (SymFromAddr(process, stackframe.AddrPC.Offset, &displacement, symbol)) {
+ char tmp[100];
+ snprintf(tmp, 100, "[%I64i] %s\n", x, symbol->Name);
+ strncat(mem_entries[i].stacktrace, tmp, 4000-1);
+ } else {
+ char tmp[100];
+ snprintf(tmp, 100, "[%I64i] ???\n", x);
+ strncat(mem_entries[i].stacktrace, tmp, 4000-1);
+ }
+
+ }
+
+ SymCleanup(process);
+
+#endif
+
+ mem_entries[i].valid = true;
+ mem_entries[i].p = newp;
+ mem_entries[i].size = size;
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) assert(0 && "memory entry buffer too small");
+
+ __total_allocated+=size;
+ return newp;
+}
+
+static void* __custom_realloc(void *p, s32 size)
+{
+ for (s32 i = 0; i < MEM_ENTRY_BUFFER_SIZE; i++)
+ {
+ if (mem_entries[i].valid && mem_entries[i].p == p)
+ {
+ __total_allocated-=mem_entries[i].size;
+ __total_allocated+=size;
+ mem_entries[i].size = size;
+ break;
+ }
+ }
+
+ __total_reallocated+=size;
+ return realloc(p, size);
+}
+
+static void __custom_free(void *p)
+{
+ for (s32 i = 0; i < MEM_ENTRY_BUFFER_SIZE; i++)
+ {
+ if (mem_entries[i].valid && mem_entries[i].p == p)
+ {
+ __total_allocated-=mem_entries[i].size;
+ mem_entries[i].valid = false;
+ break;
+ }
+ }
+
+ free(p);
+}
+
+static void __custom_print_leaks()
+{
+ printf("\n\n********LEAK LIST********\n");
+ for (s32 i = 0; i < MEM_ENTRY_BUFFER_SIZE; i++)
+ {
+ if (mem_entries[i].valid)
+ {
+ printf("%p: %d\n", mem_entries[i].p, mem_entries[i].size);
+ printf("%s\n", mem_entries[i].stacktrace);
+ }
+ }
+ getch();
+}
+
+#define mem_alloc(size) __custom_alloc(size)
+#define mem_free(p) __custom_free(p)
+#define mem_realloc(p, size) __custom_realloc(p, size);
+#define memory_print_leaks() __custom_print_leaks()
#else
diff --git a/src/windows/platform.c b/src/windows/platform.c
index a58a152..adbc053 100644
--- a/src/windows/platform.c
+++ b/src/windows/platform.c
@@ -27,6 +27,7 @@ struct t_platform_window
s32 max_height;
// shared window properties
+ bool icon_loaded;
bool do_draw;
backbuffer backbuffer;
s32 width;
@@ -673,6 +674,7 @@ platform_window platform_open_window_ex(char *name, u16 width, u16 height, u16 m
window.backbuffer.buffer = 0;
window.do_draw = true;
window.gl_context = 0;
+ window.icon_loaded = false;
current_window_to_handle = &window;
@@ -741,15 +743,15 @@ platform_window platform_open_window_ex(char *name, u16 width, u16 height, u16 m
platform_setup_backbuffer(&window);
debug_print_elapsed(startup_stamp, "backbuffer");
+ platform_setup_renderer();
+ debug_print_elapsed(startup_stamp, "renderer");
+
ShowWindow(window.window_handle, cmd_show);
if (flags & FLAGS_HIDDEN)
ShowWindow(window.window_handle, SW_HIDE);
else
ShowWindow(window.window_handle, SW_SHOW);
- platform_setup_renderer();
- debug_print_elapsed(startup_stamp, "renderer");
-
window.is_open = true;
TRACKMOUSEEVENT track;
@@ -1320,6 +1322,12 @@ void platform_init(int argc, char **argv)
void platform_set_icon(platform_window *window, image *img)
{
+ if (!img->loaded) return;
+ if (!window->icon_loaded)
+ window->icon_loaded = true;
+ else
+ return;
+
// NOTE only works with bmps currently; remove #if 0 to enable png again..
// we should probably change png color alignment so png and bmp data is the same in memory
BYTE *bmp;