summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/assets.c643
-rw-r--r--src/assets.h194
-rw-r--r--src/linux/platform.c1
-rw-r--r--src/render.c3
-rw-r--r--src/timer.c12
-rw-r--r--src/timer.h25
-rw-r--r--src/windows/platform.c49
7 files changed, 491 insertions, 436 deletions
diff --git a/src/assets.c b/src/assets.c
index d5f1540..acce310 100644
--- a/src/assets.c
+++ b/src/assets.c
@@ -1,316 +1,327 @@
-/*
-* BSD 2-Clause “Simplified” License
-* Copyright (c) 2019, Aldrik Ramaekers, aldrik.ramaekers@protonmail.com
-* All rights reserved.
-*/
-
-void assets_create()
-{
- assets asset_collection;
- asset_collection.images = array_create(sizeof(image));
- asset_collection.fonts = array_create(sizeof(font));
-
- array_reserve(&asset_collection.images, ASSET_IMAGE_COUNT);
- array_reserve(&asset_collection.fonts, ASSET_FONT_COUNT);
-
- asset_collection.queue.queue = array_create(sizeof(asset_task));
- asset_collection.post_process_queue = array_create(sizeof(asset_task));
-
- array_reserve(&asset_collection.queue.queue, ASSET_QUEUE_COUNT);
- array_reserve(&asset_collection.post_process_queue, ASSET_QUEUE_COUNT);
-
- asset_mutex = mutex_create();
- asset_collection.valid = true;
- asset_collection.done_loading_assets = false;
-
- global_asset_collection = asset_collection;
-}
-
-inline static bool is_big_endian()
-{
- volatile uint32_t i=0x01234567;
- // return 1 for big endian, 0 for little endian.
- return !((*((uint8_t*)(&i))) == 0x67);
-}
-
-void assets_do_post_process()
-{
- mutex_lock(&asset_mutex);
-
- for (int i = 0; i < global_asset_collection.post_process_queue.length; i++)
- {
- asset_task *task = array_at(&global_asset_collection.post_process_queue, i);
-
- if (task->type == ASSET_IMAGE)
- {
- if (task->image->data && task->valid)
- {
- glGenTextures(1, &task->image->textureID);
- glBindTexture(GL_TEXTURE_2D, task->image->textureID);
-
- s32 flag = is_big_endian() ? GL_UNSIGNED_INT_8_8_8_8 :
- GL_UNSIGNED_INT_8_8_8_8_REV;
-
- glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA8, task->image->width,
- task->image->height, 0, GL_RGBA, flag, task->image->data);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- task->image->loaded = true;
-
- if (!task->image->keep_in_memory)
- stbi_image_free(task->image->data);
- }
- }
- else if (task->type == ASSET_FONT)
- {
- if (task->valid)
- {
- for (s32 i = TEXT_CHARSET_START; i < TEXT_CHARSET_END; i++)
- {
- glyph *g = &task->font->glyphs[i];
-
- glGenTextures(1, &g->textureID);
- glBindTexture(GL_TEXTURE_2D, g->textureID);
-
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
- glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glTexImage2D( GL_TEXTURE_2D, 0, GL_ALPHA, g->width,g->height,
- 0, GL_ALPHA, GL_UNSIGNED_BYTE, g->bitmap );
-
- mem_free(g->bitmap);
- }
-
- task->font->loaded = true;
- }
- }
-
- array_remove_at(&global_asset_collection.post_process_queue, i);
- }
-
- mutex_unlock(&asset_mutex);
-}
-
-bool assets_queue_worker_load_image(image *image)
-{
- set_active_directory(binary_path);
-
- image->data = stbi_load_from_memory(image->start_addr,
- image->end_addr - image->start_addr,
- &image->width,
- &image->height,
- &image->channels,
- STBI_rgb_alpha);
-
- return !(image->data == 0);
-}
-
-bool assets_queue_worker_load_font(font *font)
-{
- unsigned char *ttf_buffer = (unsigned char*)font->start_addr;
-
- stbtt_fontinfo info;
- if (!stbtt_InitFont(&info, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer,0)))
- {
- return false;
- }
- float scale = stbtt_ScaleForPixelHeight(&info, font->size);
-
- for (s32 i = TEXT_CHARSET_START; i < TEXT_CHARSET_END; i++)
- {
- s32 w, h, xoff, yoff;
-
- glyph new_glyph;
- new_glyph.bitmap = stbtt_GetCodepointBitmap(&info, 0, scale, i, &w, &h, &xoff, &yoff);
- new_glyph.width = w;
- new_glyph.height = h;
- new_glyph.xoff = xoff;
- new_glyph.yoff = yoff;
-
- stbtt_GetCodepointHMetrics(&info, i, &new_glyph.advance, &new_glyph.lsb);
- new_glyph.advance *= scale;
- new_glyph.lsb *= scale;
-
- if (i == 'M') font->px_h = -yoff;
-
- font->glyphs[i-TEXT_CHARSET_START] = new_glyph;
- }
-
- font->info = info;
- font->scale = scale;
-
- return true;
-}
-
-void *assets_queue_worker()
-{
- while (global_asset_collection.valid && !global_asset_collection.done_loading_assets)
- {
- if (mutex_trylock(&asset_mutex))
- {
- int queue_length = global_asset_collection.queue.queue.length;
- if (!queue_length)
- {
- mutex_unlock(&asset_mutex);
- continue;
- }
-
- asset_task *task = array_at(&global_asset_collection.queue.queue, 0);
- asset_task buf = *task;
- array_remove_at(&global_asset_collection.queue.queue, 0);
- mutex_unlock(&asset_mutex);
-
- // load here
- if (buf.type == ASSET_IMAGE)
- {
- bool result = assets_queue_worker_load_image(buf.image);
- buf.valid = result;
- }
- else if (buf.type == ASSET_FONT)
- {
- bool result = assets_queue_worker_load_font(buf.font);
- buf.valid = result;
- }
-
- mutex_lock(&asset_mutex);
-
- assert(global_asset_collection.post_process_queue.reserved_length >
- global_asset_collection.post_process_queue.length);
-
- array_push(&global_asset_collection.post_process_queue, &buf);
- mutex_unlock(&asset_mutex);
- }
-
- // 3 ms
- thread_sleep(3000);
- }
-
- return 0;
-}
-
-image *assets_load_image(u8 *start_addr, u8 *end_addr, bool keep_in_memory)
-{
- // check if image is already loaded or loading
- for (int i = 0; i < global_asset_collection.images.length; i++)
- {
- image *img_at = array_at(&global_asset_collection.images, i);
-
- if (start_addr == img_at->start_addr)
- {
- // image is already loaded/loading
- img_at->references++;
- return img_at;
- }
- }
-
- image new_image;
- new_image.loaded = false;
- new_image.start_addr = start_addr;
- new_image.end_addr = end_addr;
- new_image.references = 1;
- new_image.keep_in_memory = keep_in_memory;
-
- // NOTE(Aldrik): we should never realloc the image array because pointers will be
- // invalidated.
- assert(global_asset_collection.images.reserved_length > global_asset_collection.images.length);
-
- int index = array_push(&global_asset_collection.images, &new_image);
-
- asset_task task;
- task.type = ASSET_IMAGE;
- task.image = array_at(&global_asset_collection.images, index);
-
- mutex_lock(&asset_mutex);
- array_push(&global_asset_collection.queue.queue, &task);
- mutex_unlock(&asset_mutex);
-
- return task.image;
-}
-
-void assets_destroy_image(image *image_to_destroy)
-{
- if (image_to_destroy->references == 1)
- {
- glBindTexture(GL_TEXTURE_2D, 0);
- glDeleteTextures(1, &image_to_destroy->textureID);
-
- if (image_to_destroy->keep_in_memory)
- stbi_image_free(image_to_destroy->data);
-
- //array_remove(&global_asset_collection.images, image_at);
- }
- else
- {
- image_to_destroy->references--;
- }
-}
-
-font *assets_load_font(u8 *start_addr, u8 *end_addr, s16 size)
-{
- //assert(!(size % 4));
- for (int i = 0; i < global_asset_collection.fonts.length; i++)
- {
- font *font_at = array_at(&global_asset_collection.fonts, i);
-
- if (start_addr == font_at->start_addr && font_at->size == size)
- {
- // font is already loaded/loading
- font_at->references++;
- return font_at;
- }
- }
-
- font new_font;
- new_font.loaded = false;
- new_font.start_addr = start_addr;
- new_font.end_addr = end_addr;
- new_font.size = size;
- new_font.references = 1;
-
- // NOTE(Aldrik): we should never realloc the font array because pointers will be
- // invalidated.
- assert(global_asset_collection.fonts.reserved_length > global_asset_collection.fonts.length);
-
- int index = array_push(&global_asset_collection.fonts, &new_font);
-
- asset_task task;
- task.type = ASSET_FONT;
- task.font = array_at(&global_asset_collection.fonts, index);
-
- mutex_lock(&asset_mutex);
- array_push(&global_asset_collection.queue.queue, &task);
- mutex_unlock(&asset_mutex);
-
- return task.font;
-}
-
-void assets_destroy_font(font *font_to_destroy)
-{
- if (font_to_destroy->references == 1)
- {
- //glBindTexture(GL_TEXTURE_2D, 0);
- //glDeleteTextures(1, font_to_destroy->textureIDs);
- }
- else
- {
- font_to_destroy->references--;
- }
-}
-
-void assets_destroy()
-{
- global_asset_collection.valid = false;
- global_asset_collection.done_loading_assets = false;
-
- array_destroy(&global_asset_collection.images);
- array_destroy(&global_asset_collection.fonts);
-
- array_destroy(&global_asset_collection.queue.queue);
- array_destroy(&global_asset_collection.post_process_queue);
-
- mem_free(binary_path);
-
- mutex_destroy(&asset_mutex);
-}
+/*
+* BSD 2-Clause “Simplified” License
+* Copyright (c) 2019, Aldrik Ramaekers, aldrik.ramaekers@protonmail.com
+* All rights reserved.
+*/
+
+void assets_create()
+{
+ assets asset_collection;
+ asset_collection.images = array_create(sizeof(image));
+ asset_collection.fonts = array_create(sizeof(font));
+
+ array_reserve(&asset_collection.images, ASSET_IMAGE_COUNT);
+ array_reserve(&asset_collection.fonts, ASSET_FONT_COUNT);
+
+ asset_collection.queue.queue = array_create(sizeof(asset_task));
+ asset_collection.post_process_queue = array_create(sizeof(asset_task));
+
+ array_reserve(&asset_collection.queue.queue, ASSET_QUEUE_COUNT);
+ array_reserve(&asset_collection.post_process_queue, ASSET_QUEUE_COUNT);
+
+ asset_mutex = mutex_create();
+ asset_collection.valid = true;
+ asset_collection.done_loading_assets = false;
+
+ global_asset_collection = asset_collection;
+}
+
+inline static bool is_big_endian()
+{
+ volatile uint32_t i=0x01234567;
+ // return 1 for big endian, 0 for little endian.
+ return !((*((uint8_t*)(&i))) == 0x67);
+}
+
+void assets_do_post_process()
+{
+ mutex_lock(&asset_mutex);
+
+ for (int i = 0; i < global_asset_collection.post_process_queue.length; i++)
+ {
+ asset_task *task = array_at(&global_asset_collection.post_process_queue, i);
+
+ if (task->type == ASSET_IMAGE)
+ {
+ if (task->image->data && task->valid)
+ {
+ glGenTextures(1, &task->image->textureID);
+ glBindTexture(GL_TEXTURE_2D, task->image->textureID);
+
+ s32 flag = is_big_endian() ? GL_UNSIGNED_INT_8_8_8_8 :
+ GL_UNSIGNED_INT_8_8_8_8_REV;
+
+ glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA8, task->image->width,
+ task->image->height, 0, GL_RGBA, flag, task->image->data);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ task->image->loaded = true;
+
+ if (!task->image->keep_in_memory)
+ stbi_image_free(task->image->data);
+ }
+ }
+ else if (task->type == ASSET_FONT)
+ {
+ if (task->valid)
+ {
+ for (s32 i = TEXT_CHARSET_START; i < TEXT_CHARSET_END; i++)
+ {
+ glyph *g = &task->font->glyphs[i];
+
+ glGenTextures(1, &g->textureID);
+ glBindTexture(GL_TEXTURE_2D, g->textureID);
+
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_ALPHA, g->width,g->height,
+ 0, GL_ALPHA, GL_UNSIGNED_BYTE, g->bitmap );
+
+ mem_free(g->bitmap);
+ }
+
+ task->font->loaded = true;
+ }
+ }
+
+ array_remove_at(&global_asset_collection.post_process_queue, i);
+ }
+
+ mutex_unlock(&asset_mutex);
+}
+
+bool assets_queue_worker_load_image(image *image)
+{
+#ifdef MODE_DEVELOPER
+ u64 stamp = platform_get_time(TIME_FULL, TIME_US);
+#endif
+
+ set_active_directory(binary_path);
+
+ image->data = stbi_load_from_memory(image->start_addr,
+ image->end_addr - image->start_addr,
+ &image->width,
+ &image->height,
+ &image->channels,
+ STBI_rgb_alpha);
+
+ debug_print_elapsed(stamp, "loaded image in");
+
+ return !(image->data == 0);
+}
+
+bool assets_queue_worker_load_font(font *font)
+{
+#ifdef MODE_DEVELOPER
+ u64 stamp = platform_get_time(TIME_FULL, TIME_US);
+#endif
+
+ unsigned char *ttf_buffer = (unsigned char*)font->start_addr;
+
+ stbtt_fontinfo info;
+ if (!stbtt_InitFont(&info, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer,0)))
+ {
+ return false;
+ }
+ float scale = stbtt_ScaleForPixelHeight(&info, font->size);
+
+ for (s32 i = TEXT_CHARSET_START; i < TEXT_CHARSET_END; i++)
+ {
+ s32 w, h, xoff, yoff;
+
+ glyph new_glyph;
+ new_glyph.bitmap = stbtt_GetCodepointBitmap(&info, 0, scale, i, &w, &h, &xoff, &yoff);
+ new_glyph.width = w;
+ new_glyph.height = h;
+ new_glyph.xoff = xoff;
+ new_glyph.yoff = yoff;
+
+ stbtt_GetCodepointHMetrics(&info, i, &new_glyph.advance, &new_glyph.lsb);
+ new_glyph.advance *= scale;
+ new_glyph.lsb *= scale;
+
+ if (i == 'M') font->px_h = -yoff;
+
+ font->glyphs[i-TEXT_CHARSET_START] = new_glyph;
+ }
+
+ font->info = info;
+ font->scale = scale;
+
+ debug_print_elapsed(stamp, "loaded font in");
+
+ return true;
+}
+
+void *assets_queue_worker()
+{
+ while (global_asset_collection.valid && !global_asset_collection.done_loading_assets)
+ {
+ if (mutex_trylock(&asset_mutex))
+ {
+ int queue_length = global_asset_collection.queue.queue.length;
+ if (!queue_length)
+ {
+ mutex_unlock(&asset_mutex);
+ continue;
+ }
+
+ asset_task *task = array_at(&global_asset_collection.queue.queue, 0);
+ asset_task buf = *task;
+ array_remove_at(&global_asset_collection.queue.queue, 0);
+ mutex_unlock(&asset_mutex);
+
+ // load here
+ if (buf.type == ASSET_IMAGE)
+ {
+ bool result = assets_queue_worker_load_image(buf.image);
+ buf.valid = result;
+ }
+ else if (buf.type == ASSET_FONT)
+ {
+ bool result = assets_queue_worker_load_font(buf.font);
+ buf.valid = result;
+ }
+
+ mutex_lock(&asset_mutex);
+
+ assert(global_asset_collection.post_process_queue.reserved_length >
+ global_asset_collection.post_process_queue.length);
+
+ array_push(&global_asset_collection.post_process_queue, &buf);
+ mutex_unlock(&asset_mutex);
+ }
+
+ thread_sleep(1000);
+ }
+
+ return 0;
+}
+
+image *assets_load_image(u8 *start_addr, u8 *end_addr, bool keep_in_memory)
+{
+ // check if image is already loaded or loading
+ for (int i = 0; i < global_asset_collection.images.length; i++)
+ {
+ image *img_at = array_at(&global_asset_collection.images, i);
+
+ if (start_addr == img_at->start_addr)
+ {
+ // image is already loaded/loading
+ img_at->references++;
+ return img_at;
+ }
+ }
+
+ image new_image;
+ new_image.loaded = false;
+ new_image.start_addr = start_addr;
+ new_image.end_addr = end_addr;
+ new_image.references = 1;
+ new_image.keep_in_memory = keep_in_memory;
+
+ // NOTE(Aldrik): we should never realloc the image array because pointers will be
+ // invalidated.
+ assert(global_asset_collection.images.reserved_length > global_asset_collection.images.length);
+
+ int index = array_push(&global_asset_collection.images, &new_image);
+
+ asset_task task;
+ task.type = ASSET_IMAGE;
+ task.image = array_at(&global_asset_collection.images, index);
+
+ mutex_lock(&asset_mutex);
+ array_push(&global_asset_collection.queue.queue, &task);
+ mutex_unlock(&asset_mutex);
+
+ return task.image;
+}
+
+void assets_destroy_image(image *image_to_destroy)
+{
+ if (image_to_destroy->references == 1)
+ {
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glDeleteTextures(1, &image_to_destroy->textureID);
+
+ if (image_to_destroy->keep_in_memory)
+ stbi_image_free(image_to_destroy->data);
+
+ //array_remove(&global_asset_collection.images, image_at);
+ }
+ else
+ {
+ image_to_destroy->references--;
+ }
+}
+
+font *assets_load_font(u8 *start_addr, u8 *end_addr, s16 size)
+{
+ //assert(!(size % 4));
+ for (int i = 0; i < global_asset_collection.fonts.length; i++)
+ {
+ font *font_at = array_at(&global_asset_collection.fonts, i);
+
+ if (start_addr == font_at->start_addr && font_at->size == size)
+ {
+ // font is already loaded/loading
+ font_at->references++;
+ return font_at;
+ }
+ }
+
+ font new_font;
+ new_font.loaded = false;
+ new_font.start_addr = start_addr;
+ new_font.end_addr = end_addr;
+ new_font.size = size;
+ new_font.references = 1;
+
+ // NOTE(Aldrik): we should never realloc the font array because pointers will be
+ // invalidated.
+ assert(global_asset_collection.fonts.reserved_length > global_asset_collection.fonts.length);
+
+ int index = array_push(&global_asset_collection.fonts, &new_font);
+
+ asset_task task;
+ task.type = ASSET_FONT;
+ task.font = array_at(&global_asset_collection.fonts, index);
+
+ mutex_lock(&asset_mutex);
+ array_push(&global_asset_collection.queue.queue, &task);
+ mutex_unlock(&asset_mutex);
+
+ return task.font;
+}
+
+void assets_destroy_font(font *font_to_destroy)
+{
+ if (font_to_destroy->references == 1)
+ {
+ //glBindTexture(GL_TEXTURE_2D, 0);
+ //glDeleteTextures(1, font_to_destroy->textureIDs);
+ }
+ else
+ {
+ font_to_destroy->references--;
+ }
+}
+
+void assets_destroy()
+{
+ global_asset_collection.valid = false;
+ global_asset_collection.done_loading_assets = false;
+
+ array_destroy(&global_asset_collection.images);
+ array_destroy(&global_asset_collection.fonts);
+
+ array_destroy(&global_asset_collection.queue.queue);
+ array_destroy(&global_asset_collection.post_process_queue);
+
+ mem_free(binary_path);
+
+ mutex_destroy(&asset_mutex);
+}
diff --git a/src/assets.h b/src/assets.h
index a9816b5..a2b02da 100644
--- a/src/assets.h
+++ b/src/assets.h
@@ -1,98 +1,98 @@
-/*
-* BSD 2-Clause “Simplified” License
-* Copyright (c) 2019, Aldrik Ramaekers, aldrik.ramaekers@protonmail.com
-* All rights reserved.
-*/
-
-#ifndef INCLUDE_ASSETS
-#define INCLUDE_ASSETS
-
-typedef struct t_image {
- u8 *start_addr;
- u8 *end_addr;
- bool loaded;
- bool keep_in_memory;
- s32 width;
- s32 height;
- s32 channels;
- void *data;
- s16 references;
- GLuint textureID;
-} image;
-
-#define TEXT_CHARSET_START 0
-#define TEXT_CHARSET_END 2000
-#define TOTAL_GLYPHS TEXT_CHARSET_END-TEXT_CHARSET_START
-
-typedef struct t_glyph
-{
- s32 width;
- s32 height;
- s32 advance;
- s32 lsb;
- s32 xoff;
- s32 yoff;
- void *bitmap;
- GLuint textureID;
-} glyph;
-
-typedef struct t_font
-{
- u8 *start_addr;
- u8 *end_addr;
- bool loaded;
- s16 references;
- s16 size;
- s32 px_h;
- float32 scale;
- stbtt_fontinfo info;
- glyph glyphs[TOTAL_GLYPHS];
-} font;
-
-typedef enum t_asset_task_type
-{
- ASSET_IMAGE,
- ASSET_FONT,
-} asset_task_type;
-
-typedef struct t_asset_task
-{
- s8 type;
- bool valid;
- union {
- image *image;
- font *font;
- };
-} asset_task;
-
-typedef struct t_asset_queue {
- array queue;
-} asset_queue;
-
-typedef struct t_assets {
- array images;
- array fonts;
- asset_queue queue;
- array post_process_queue;
- bool valid;
- bool done_loading_assets;
-} assets;
-
-char *binary_path;
-
-mutex asset_mutex;
-assets global_asset_collection;
-
-void assets_create();
-void assets_destroy();
-
-void assets_do_post_process();
-void *assets_queue_worker();
-
-image *assets_load_image(u8 *start_addr, u8 *end_addr, bool keep_in_memory);
-void assets_destroy_image(image *image);
-
-font *assets_load_font(u8 *start_addr, u8 *end_addr, s16 size);
-void assets_destroy_font(font *font);
-
+/*
+* BSD 2-Clause “Simplified” License
+* Copyright (c) 2019, Aldrik Ramaekers, aldrik.ramaekers@protonmail.com
+* All rights reserved.
+*/
+
+#ifndef INCLUDE_ASSETS
+#define INCLUDE_ASSETS
+
+typedef struct t_image {
+ u8 *start_addr;
+ u8 *end_addr;
+ bool loaded;
+ bool keep_in_memory;
+ s32 width;
+ s32 height;
+ s32 channels;
+ void *data;
+ s16 references;
+ GLuint textureID;
+} image;
+
+#define TEXT_CHARSET_START 0
+#define TEXT_CHARSET_END 2000
+#define TOTAL_GLYPHS TEXT_CHARSET_END-TEXT_CHARSET_START
+
+typedef struct t_glyph
+{
+ s32 width;
+ s32 height;
+ s32 advance;
+ s32 lsb;
+ s32 xoff;
+ s32 yoff;
+ void *bitmap;
+ GLuint textureID;
+} glyph;
+
+typedef struct t_font
+{
+ u8 *start_addr;
+ u8 *end_addr;
+ bool loaded;
+ s16 references;
+ s16 size;
+ s32 px_h;
+ float32 scale;
+ stbtt_fontinfo info;
+ glyph glyphs[TOTAL_GLYPHS];
+} font;
+
+typedef enum t_asset_task_type
+{
+ ASSET_IMAGE,
+ ASSET_FONT,
+} asset_task_type;
+
+typedef struct t_asset_task
+{
+ s8 type;
+ bool valid;
+ union {
+ image *image;
+ font *font;
+ };
+} asset_task;
+
+typedef struct t_asset_queue {
+ array queue;
+} asset_queue;
+
+typedef struct t_assets {
+ array images;
+ array fonts;
+ asset_queue queue;
+ array post_process_queue;
+ bool valid;
+ bool done_loading_assets;
+} assets;
+
+char *binary_path;
+
+mutex asset_mutex;
+assets global_asset_collection;
+
+void assets_create();
+void assets_destroy();
+
+void assets_do_post_process();
+void *assets_queue_worker();
+
+image *assets_load_image(u8 *start_addr, u8 *end_addr, bool keep_in_memory);
+void assets_destroy_image(image *image);
+
+font *assets_load_font(u8 *start_addr, u8 *end_addr, s16 size);
+void assets_destroy_font(font *font);
+
#endif \ No newline at end of file
diff --git a/src/linux/platform.c b/src/linux/platform.c
index daa0120..1b393d9 100644
--- a/src/linux/platform.c
+++ b/src/linux/platform.c
@@ -268,6 +268,7 @@ s32 platform_get_file_size(char *path)
int length = ftell(file);
fseek(file, 0, SEEK_SET);
+ fclose(file);
return length;
}
diff --git a/src/render.c b/src/render.c
index f095967..b19abcd 100644
--- a/src/render.c
+++ b/src/render.c
@@ -256,7 +256,8 @@ s32 render_text(font *font, s32 x, s32 y, char *text, color tint)
{
ch = 0x3f;
}
- if (ch == '\n') ch = 0xB6;
+ if (ch == 10) ch = 0xB6;
+ if (ch == 13) continue;
glyph g = font->glyphs[ch];
diff --git a/src/timer.c b/src/timer.c
new file mode 100644
index 0000000..41904b0
--- /dev/null
+++ b/src/timer.c
@@ -0,0 +1,12 @@
+/*
+* BSD 2-Clause “Simplified” License
+* Copyright (c) 2019, Aldrik Ramaekers, aldrik.ramaekers@protonmail.com
+* All rights reserved.
+*/
+
+float32 timer_elapsed_ms(u64 start)
+{
+ u64 diff = platform_get_time(TIME_FULL, TIME_US) - start;
+ float diff_ms = diff / 1000.0f;
+ return diff_ms;
+}
diff --git a/src/timer.h b/src/timer.h
new file mode 100644
index 0000000..63afa30
--- /dev/null
+++ b/src/timer.h
@@ -0,0 +1,25 @@
+/*
+* BSD 2-Clause “Simplified” License
+* Copyright (c) 2019, Aldrik Ramaekers, aldrik.ramaekers@protonmail.com
+* All rights reserved.
+*/
+
+#ifndef INCLUDE_STOPWATCH
+#define INCLUDE_STOPWATCH
+
+#ifdef MODE_DEVELOPER
+s32 _indent_c = 0;
+#define debug_print_elapsed_title(_title) printf("%.*s", _indent_c+1, "|---------------------"); printf("%s\n", _title)
+#define debug_print_elapsed_indent() _indent_c+=2;
+#define debug_print_elapsed_undent() _indent_c-=2;
+#define debug_print_elapsed(_stamp,_title) printf("|%*s%s: %.2fms\n", _indent_c, "", _title, timer_elapsed_ms(_stamp));_stamp = platform_get_time(TIME_FULL, TIME_US);
+#else
+#define debug_print_elapsed_title(_title) do { } while(0);
+#define debug_print_elapsed_indent() do { } while(0);
+#define debug_print_elapsed_undent() do { } while(0);
+#define debug_print_elapsed(_stamp,_title) do { } while(0);
+#endif
+
+float32 timer_elapsed_ms(u64 start);
+
+#endif \ No newline at end of file
diff --git a/src/windows/platform.c b/src/windows/platform.c
index 70a1b7d..4c24363 100644
--- a/src/windows/platform.c
+++ b/src/windows/platform.c
@@ -526,6 +526,13 @@ void platform_get_focus(platform_window *window)
platform_window platform_open_window(char *name, u16 width, u16 height, u16 max_w, u16 max_h, u16 min_w, u16 min_h)
{
+ debug_print_elapsed_title("window creation");
+ debug_print_elapsed_indent();
+
+#ifdef MODE_DEVELOPER
+ u64 startup_stamp = platform_get_time(TIME_FULL, TIME_US);
+#endif
+
platform_window window;
window.has_focus = true;
window.window_handle = 0;
@@ -549,8 +556,12 @@ platform_window platform_open_window(char *name, u16 width, u16 height, u16 max_
window.window_class.hIcon = LoadIcon(NULL, IDI_WINLOGO);
//window.window_class.hCursor = LoadCursor(NULL, IDC_ARROW);
+ debug_print_elapsed(startup_stamp, "setup");
+
if (RegisterClass(&window.window_class))
{
+ debug_print_elapsed(startup_stamp, "register class");
+
int style = WS_VISIBLE|WS_SYSMENU|WS_CAPTION|WS_MINIMIZEBOX;
if (min_w != max_w && min_h != max_h)
@@ -570,6 +581,8 @@ platform_window platform_open_window(char *name, u16 width, u16 height, u16 max_
instance,
0);
+ debug_print_elapsed(startup_stamp, "create window");
+
if (window.window_handle)
{
window.hdc = GetDC(window.window_handle);
@@ -582,14 +595,18 @@ platform_window platform_open_window(char *name, u16 width, u16 height, u16 max_
format.cColorBits = 24;
format.cAlphaBits = 8;
format.iLayerType = PFD_MAIN_PLANE; // PFD_TYPE_RGBA
- s32 suggested_format_index = ChoosePixelFormat(window.hdc, &format);
+ s32 suggested_format_index = ChoosePixelFormat(window.hdc, &format); // SLOW AF??
PIXELFORMATDESCRIPTOR actual_format;
DescribePixelFormat(window.hdc, suggested_format_index, sizeof(actual_format), &actual_format);
SetPixelFormat(window.hdc, suggested_format_index, &actual_format);
+ debug_print_elapsed(startup_stamp, "pixel format");
+
window.gl_context = wglCreateContext(window.hdc);
+ debug_print_elapsed(startup_stamp, "gl context");
+
static HGLRC share_list = 0;
if (share_list == 0)
{
@@ -605,8 +622,8 @@ platform_window platform_open_window(char *name, u16 width, u16 height, u16 max_
ShowWindow(window.window_handle, cmd_show);
//BringWindowToTop(window.window_handle);
- AllowSetForegroundWindow(ASFW_ANY);
- SetForegroundWindow(window.window_handle);
+ //AllowSetForegroundWindow(ASFW_ANY);
+ //SetForegroundWindow(window.window_handle);
// blending
glEnable(GL_DEPTH_TEST);
@@ -626,34 +643,19 @@ platform_window platform_open_window(char *name, u16 width, u16 height, u16 max_
glHint(GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST);
#endif
- // https://stackoverflow.com/questions/5627229/sub-pixel-drawing-with-opengl
- //glHint(GL_POINT_SMOOTH, GL_NICEST);
- //glHint(GL_LINE_SMOOTH, GL_NICEST);
- //glHint(GL_POLYGON_SMOOTH, GL_NICEST);
-
- //glEnable(GL_SMOOTH);
- //glEnable(GL_POINT_SMOOTH);
- //glEnable(GL_LINE_SMOOTH);
- //glEnable(GL_POLYGON_SMOOTH);
- //////////////////
-
window.is_open = true;
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, width, height, 0, -1, 1);
-
- //GLint m_viewport[4];
- //glGetIntegerv( GL_VIEWPORT, m_viewport );
- //printf("%d %d %d %d\n", m_viewport[0], m_viewport[1], m_viewport[2], m_viewport[3]);
-
glMatrixMode(GL_MODELVIEW);
+ debug_print_elapsed(startup_stamp, "gl setup");
+
TRACKMOUSEEVENT track;
track.cbSize = sizeof(track);
track.dwFlags = TME_LEAVE;
track.hwndTrack = window.window_handle;
TrackMouseEvent(&track);
+
+ debug_print_elapsed(startup_stamp, "track mouse");
}
else
{
@@ -669,6 +671,8 @@ platform_window platform_open_window(char *name, u16 width, u16 height, u16 max_
platform_get_focus(&window);
+ debug_print_elapsed_undent();
+
return window;
}
@@ -789,6 +793,7 @@ s32 platform_get_file_size(char *path)
int length = ftell(file);
fseek(file, 0, SEEK_SET);
+ fclose(file);
return length;
}