From ebd3c08d9c656557bd9692f23926ca46e96d5738 Mon Sep 17 00:00:00 2001 From: Aldrik Ramaekers Date: Tue, 9 Jun 2020 21:13:51 +0200 Subject: bmp loading --- src/array.c | 4 + src/assets.c | 58 +++++++--- src/assets.h | 6 +- src/localization.c | 295 ++++++++++++++++++++++++------------------------- src/memory.h | 13 +++ src/windows/platform.c | 26 +++-- 6 files changed, 227 insertions(+), 175 deletions(-) diff --git a/src/array.c b/src/array.c index 7c0cbeb..4119f31 100644 --- a/src/array.c +++ b/src/array.c @@ -96,9 +96,13 @@ void array_reserve(array *array, u32 reserve_count) array->reserved_length += reserve_count; if (array->data) + { array->data = mem_realloc(array->data, (array->reserved_length*array->entry_size)); + } else + { array->data = mem_alloc(array->reserved_length*array->entry_size); + } } mutex_unlock(&array->mutex); } diff --git a/src/assets.c b/src/assets.c index 5b90ea3..a0808d0 100644 --- a/src/assets.c +++ b/src/assets.c @@ -60,8 +60,12 @@ bool assets_do_post_process() 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); + if (task->type == ASSET_IMAGE) + glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA8, task->image->width, + task->image->height, 0, GL_RGBA, flag, task->image->data); + else + glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA8, task->image->width, + task->image->height, 0, GL_BGRA, flag, task->image->data); #if 0 if (glTexImage2DMultisample) @@ -80,7 +84,7 @@ bool assets_do_post_process() task->image->loaded = true; glBindTexture(GL_TEXTURE_2D, 0); - if (!task->image->keep_in_memory) + if (!task->image->keep_in_memory && task->type == ASSET_IMAGE) stbi_image_free(task->image->data); } } @@ -126,11 +130,37 @@ bool assets_queue_worker_load_bitmap(image *image) u64 stamp = platform_get_time(TIME_FULL, TIME_US); #endif - image->data = image->start_addr; - - debug_print_elapsed(stamp, "loaded image in"); - - return !(image->data == 0); +#pragma pack(push, 1) + typedef struct { + unsigned short type; /* Magic identifier */ + unsigned int size; /* File size in bytes */ + unsigned int reserved; + unsigned int offset; /* Offset to image data, bytes */ + } HEADER; + typedef struct { + unsigned int size; /* Header size in bytes */ + int width,height; /* Width and height of image */ + unsigned short planes; /* Number of colour planes */ + unsigned short bits; /* Bits per pixel */ + unsigned int compression; /* Compression type */ + unsigned int imagesize; /* Image size in bytes */ + int xresolution,yresolution; /* Pixels per meter */ + unsigned int ncolours; /* Number of colours */ + unsigned int importantcolours; /* Important colours */ + } INFOHEADER; +#pragma pack(pop) + + HEADER* header = (HEADER*)image->start_addr; + INFOHEADER* info = (INFOHEADER*)(image->start_addr+sizeof(HEADER)); + + image->data = image->start_addr+header->offset; + image->width = info->width; + image->height = info->height; + image->channels = info->bits/8; + + debug_print_elapsed(stamp, "loaded bitmap in"); + + return image->data != 0; } bool assets_queue_worker_load_image(image *image) @@ -139,8 +169,6 @@ bool assets_queue_worker_load_image(image *image) 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, @@ -150,7 +178,7 @@ bool assets_queue_worker_load_image(image *image) debug_print_elapsed(stamp, "loaded image in"); - return !(image->data == 0); + return image->data != 0; } bool assets_queue_worker_load_font(font *font) @@ -373,8 +401,7 @@ void assets_destroy() mutex_destroy(&asset_mutex); } - -image *assets_load_bitmap(u8 *start_addr, s32 width, s32 height, s32 channels) +image *assets_load_bitmap(u8 *start_addr, u8 *end_addr) { // check if image is already loaded or loading for (int i = 0; i < global_asset_collection.images.length; i++) @@ -392,12 +419,9 @@ image *assets_load_bitmap(u8 *start_addr, s32 width, s32 height, s32 channels) image new_image; new_image.loaded = false; new_image.start_addr = start_addr; - new_image.end_addr = 0; + new_image.end_addr = end_addr; new_image.references = 1; new_image.keep_in_memory = false; - new_image.channels = channels; - new_image.width = width; - new_image.height = height; // NOTE(Aldrik): we should never realloc the image array because pointers will be // invalidated. diff --git a/src/assets.h b/src/assets.h index 30f0ebf..6f7e40f 100644 --- a/src/assets.h +++ b/src/assets.h @@ -94,10 +94,14 @@ void *assets_queue_worker(); image *assets_load_image(u8 *start_addr, u8 *end_addr, bool keep_in_memory); void assets_destroy_image(image *image); -image *assets_load_bitmap(u8 *start_addr, s32 width, s32 height, s32 channels); +image *assets_load_bitmap(u8 *start_addr, u8 *end_addr); void assets_destroy_bitmap(image *image); font *assets_load_font(u8 *start_addr, u8 *end_addr, s16 size); void assets_destroy_font(font *font); +#define load_image(_name, _inmem) assets_load_image(_binary____data_imgs_##_name##_start,_binary____data_imgs_##_name##_end, _inmem) +#define load_font(_name, _inmem) assets_load_font(_binary____data_fonts_##_name##_start,_binary____data_fonts_##_name##_end, _inmem) +#define load_bitmap(_name) assets_load_bitmap(_binary____data_imgs_##_name##_start,_binary____data_imgs_##_name##_end) + #endif \ No newline at end of file diff --git a/src/localization.c b/src/localization.c index 2ee39e3..6512d40 100644 --- a/src/localization.c +++ b/src/localization.c @@ -1,148 +1,147 @@ -/* -* BSD 2-Clause “Simplified” License -* Copyright (c) 2019, Aldrik Ramaekers, aldrik.ramaekers@protonmail.com -* All rights reserved. -*/ - -mo_file load_localization_file(u8 *start_addr, u8 *end_addr, u8 *img_start, u8 *img_end, - char *locale_id, char *locale_name) -{ - mo_file mo; - mo.translations = array_create(sizeof(mo_translation)); - - { - mo.header = *(mo_header*)start_addr; - mo.locale_id = mem_alloc(strlen(locale_id)+1); - string_copyn(mo.locale_id, locale_id, strlen(locale_id)+1); - - mo.locale_full = mem_alloc(strlen(locale_name)+1); - string_copyn(mo.locale_full, locale_name, strlen(locale_name)+1); - - mo.icon = assets_load_image(img_start, img_end, false); - - char *buffer = (char*)start_addr; - mo_entry *identifiers = (mo_entry*)(buffer + mo.header.identifier_table_offset); - mo_entry *translations = (mo_entry*)(buffer + mo.header.translation_table_offset); - - for (s32 i = 0; i < mo.header.number_of_strings; i++) - { - mo_entry *entry = &identifiers[i]; - mo_entry *trans = &translations[i]; - - mo_translation translation; - translation.identifier_len = entry->length; - translation.identifier = buffer+entry->offset; - translation.translation = buffer+trans->offset; - - array_push(&mo.translations, &translation); - //printf("%s=%s\n", translation.identifier, translation.translation); - } - } - - return mo; -} - -char* locale_get_name() -{ - if (!global_localization.active_localization) - { - return "[NO LOCALE]"; - } - - return global_localization.active_localization->locale_full; -} - -char* locale_get_id() -{ - if (!global_localization.active_localization) - { - return "[NO LOCALE]"; - } - - return global_localization.active_localization->locale_id; -} - -bool set_locale(char *country_id) -{ - if (country_id == 0 && global_localization.mo_files.length) - { - global_localization.active_localization = array_at(&global_localization.mo_files, 0); - return true; - } - - for (s32 i = 0; i < global_localization.mo_files.length; i++) - { - mo_file *file = array_at(&global_localization.mo_files, i); - if (strcmp(file->locale_id, country_id) == 0) - { - global_localization.active_localization = file; - return true; - } - } - - // if localization is not found, default to first in list (english), return false to report error - if (global_localization.mo_files.length) - global_localization.active_localization = array_at(&global_localization.mo_files, 0); - else - global_localization.active_localization = 0; - - return false; -} - -char* localize(const char *identifier) -{ - if (!global_localization.active_localization) - { - //printf("NO LOCALE SELECTED."); - return (char*)identifier; - } - - s32 len = strlen(identifier); - for (s32 i = 0; i < global_localization.active_localization->translations.length; i++) - { - mo_translation *trans = array_at(&global_localization.active_localization->translations, i); - - if (trans->identifier_len == len && strcmp(identifier, trans->identifier) == 0) - { - return trans->translation; - } - } - printf("MISSING TRANSLATION: [%s][%s]\n", identifier, global_localization.active_localization->locale_id); - return "MISSING"; -} - -void load_available_localizations() -{ - global_localization.mo_files = array_create(sizeof(mo_file)); - array_reserve(&global_localization.mo_files, 10); - - mo_file en = load_localization_file(_binary____data_translations_en_English_mo_start, - _binary____data_translations_en_English_mo_end, - _binary____data_imgs_en_png_start, - _binary____data_imgs_en_png_end, - "en", "English"); - - mo_file nl = load_localization_file(_binary____data_translations_nl_Dutch_mo_start, - _binary____data_translations_nl_Dutch_mo_end, - _binary____data_imgs_nl_png_start, - _binary____data_imgs_nl_png_end, - "nl", "Dutch"); - - array_push(&global_localization.mo_files, &en); - array_push(&global_localization.mo_files, &nl); -} - -void destroy_available_localizations() -{ - for (s32 i = 0; i < global_localization.mo_files.length; i++) - { - mo_file *file = array_at(&global_localization.mo_files, i); - array_destroy(&file->translations); - mem_free(file->locale_id); - mem_free(file->locale_full); - - if (file->icon) - assets_destroy_image(file->icon); - } - array_destroy(&global_localization.mo_files); -} +/* +* BSD 2-Clause “Simplified” License +* Copyright (c) 2019, Aldrik Ramaekers, aldrik.ramaekers@protonmail.com +* All rights reserved. +*/ + +mo_file load_localization_file(u8 *start_addr, u8 *end_addr, u8 *img_start, u8 *img_end, + char *locale_id, char *locale_name) +{ + mo_file mo; + mo.translations = array_create(sizeof(mo_translation)); + + { + mo.header = *(mo_header*)start_addr; + mo.locale_id = mem_alloc(strlen(locale_id)+1); + string_copyn(mo.locale_id, locale_id, strlen(locale_id)+1); + + mo.locale_full = mem_alloc(strlen(locale_name)+1); + string_copyn(mo.locale_full, locale_name, strlen(locale_name)+1); + + mo.icon = assets_load_bitmap(img_start, img_end); + + char *buffer = (char*)start_addr; + mo_entry *identifiers = (mo_entry*)(buffer + mo.header.identifier_table_offset); + mo_entry *translations = (mo_entry*)(buffer + mo.header.translation_table_offset); + + for (s32 i = 0; i < mo.header.number_of_strings; i++) + { + mo_entry *entry = &identifiers[i]; + mo_entry *trans = &translations[i]; + + mo_translation translation; + translation.identifier_len = entry->length; + translation.identifier = buffer+entry->offset; + translation.translation = buffer+trans->offset; + + array_push(&mo.translations, &translation); + } + } + + return mo; +} + +char* locale_get_name() +{ + if (!global_localization.active_localization) + { + return "[NO LOCALE]"; + } + + return global_localization.active_localization->locale_full; +} + +char* locale_get_id() +{ + if (!global_localization.active_localization) + { + return "[NO LOCALE]"; + } + + return global_localization.active_localization->locale_id; +} + +bool set_locale(char *country_id) +{ + if (country_id == 0 && global_localization.mo_files.length) + { + global_localization.active_localization = array_at(&global_localization.mo_files, 0); + return true; + } + + for (s32 i = 0; i < global_localization.mo_files.length; i++) + { + mo_file *file = array_at(&global_localization.mo_files, i); + if (strcmp(file->locale_id, country_id) == 0) + { + global_localization.active_localization = file; + return true; + } + } + + // if localization is not found, default to first in list (english), return false to report error + if (global_localization.mo_files.length) + global_localization.active_localization = array_at(&global_localization.mo_files, 0); + else + global_localization.active_localization = 0; + + return false; +} + +char* localize(const char *identifier) +{ + if (!global_localization.active_localization) + { + //printf("NO LOCALE SELECTED."); + return (char*)identifier; + } + + s32 len = strlen(identifier); + for (s32 i = 0; i < global_localization.active_localization->translations.length; i++) + { + mo_translation *trans = array_at(&global_localization.active_localization->translations, i); + + if (trans->identifier_len == len && strcmp(identifier, trans->identifier) == 0) + { + return trans->translation; + } + } + printf("MISSING TRANSLATION: [%s][%s]\n", identifier, global_localization.active_localization->locale_id); + return "MISSING"; +} + +void load_available_localizations() +{ + global_localization.mo_files = array_create(sizeof(mo_file)); + array_reserve(&global_localization.mo_files, 10); + + mo_file en = load_localization_file(_binary____data_translations_en_English_mo_start, + _binary____data_translations_en_English_mo_end, + _binary____data_imgs_en_bmp_start, + _binary____data_imgs_en_bmp_end, + "en", "English"); + + mo_file nl = load_localization_file(_binary____data_translations_nl_Dutch_mo_start, + _binary____data_translations_nl_Dutch_mo_end, + _binary____data_imgs_nl_bmp_start, + _binary____data_imgs_nl_bmp_end, + "nl", "Dutch"); + + array_push(&global_localization.mo_files, &en); + array_push(&global_localization.mo_files, &nl); +} + +void destroy_available_localizations() +{ + for (s32 i = 0; i < global_localization.mo_files.length; i++) + { + mo_file *file = array_at(&global_localization.mo_files, i); + array_destroy(&file->translations); + mem_free(file->locale_id); + mem_free(file->locale_full); + + if (file->icon) + assets_destroy_image(file->icon); + } + array_destroy(&global_localization.mo_files); +} diff --git a/src/memory.h b/src/memory.h index f63edef..1457f21 100644 --- a/src/memory.h +++ b/src/memory.h @@ -7,11 +7,24 @@ #ifndef INCLUDE_MEMORY #define INCLUDE_MEMORY +#ifdef MODE_DEVELOPER +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() {} + +#else + #define mem_alloc(size) malloc(size) #define mem_free(p) free(p) #define mem_realloc(p, size) realloc(p, size) #define memory_print_leaks() {} +#endif + #define STBI_MALLOC(sz) mem_alloc(sz) #define STBI_REALLOC(p, newsz) mem_realloc(p, newsz) #define STBI_FREE(p) mem_free(p) diff --git a/src/windows/platform.c b/src/windows/platform.c index 263f8d8..723cf5a 100644 --- a/src/windows/platform.c +++ b/src/windows/platform.c @@ -378,11 +378,19 @@ LRESULT CALLBACK main_window_callback(HWND window, UINT message, WPARAM wparam, keyboard_handle_input_string(current_window_to_handle, current_keyboard_to_handle, ch); } } - else if (message == WM_MOUSELEAVE) +#if 0 + else if (message == WM_PAINT) { - //current_mouse_to_handle->x = MOUSE_OFFSCREEN; - //current_mouse_to_handle->y = MOUSE_OFFSCREEN; + PAINTSTRUCT ps; + HDC hdc = BeginPaint(current_window_to_handle->window_handle, &ps); + + SetDCPenColor(hdc, RGB(255, 0, 0)); // red + Rectangle(hdc, 100, 100, 200, 300); + + EndPaint(current_window_to_handle->window_handle, &ps); + return 0; } +#endif else if (message == WM_KILLFOCUS) { if (current_mouse_to_handle && !(current_window_to_handle->flags & FLAGS_GLOBAL_MOUSE)) @@ -603,7 +611,7 @@ platform_window platform_open_window_ex(char *name, u16 width, u16 height, u16 m { debug_print_elapsed(startup_stamp, "register class"); - int style = WS_VISIBLE|WS_SYSMENU|WS_CAPTION|WS_MINIMIZEBOX; + int style = WS_SYSMENU|WS_CAPTION|WS_MINIMIZEBOX; int ex_style = 0; if (min_w != max_w && min_h != max_h) @@ -619,10 +627,6 @@ platform_window platform_open_window_ex(char *name, u16 width, u16 height, u16 m { ex_style = WS_EX_TOPMOST; } - if (flags & FLAGS_HIDDEN) - { - style &= ~WS_VISIBLE; - } if (flags & FLAGS_NO_TASKBAR) { ex_style |= WS_EX_TOOLWINDOW; @@ -737,7 +741,6 @@ platform_window platform_open_window_ex(char *name, u16 width, u16 height, u16 m else ShowWindow(window.window_handle, SW_SHOW); - ////// GL SETUP glDepthMask(GL_TRUE); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); @@ -1305,6 +1308,8 @@ void platform_init(int argc, char **argv) void platform_set_icon(platform_window *window, image *img) { + // 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; s32 data_len = img->width * img->height * 4; s32 total_len = data_len + 40 * 4; @@ -1326,6 +1331,7 @@ void platform_set_icon(platform_window *window, image *img) { s32 img_pixel = *(((s32*)img->data+(x+(y*img->width)))); +#if 0 // 0xAABBGGRR s32 a = (img_pixel>>24) & 0x000000FF; s32 b = (img_pixel>>16) & 0x000000FF; @@ -1334,6 +1340,8 @@ void platform_set_icon(platform_window *window, image *img) //s32 c = (r << 24) | (g << 16) | (b << 8) | (a << 0); s32 c = (a << 24) | (r << 16) | (g << 8) | (b << 0); +#endif + s32 c = img_pixel; memcpy(bmp+40+(index*4), &c, 4); ++index; -- cgit v1.2.3-70-g09d2