From 5392f970f970ba0d5f4642b11935e61653086aae Mon Sep 17 00:00:00 2001 From: Aldrik Ramaekers Date: Mon, 11 May 2020 13:26:16 +0200 Subject: work --- src/assets.c | 93 +++++++++++++++++++++++++++++++- src/assets.h | 9 +++- src/linux/platform.c | 2 +- src/platform.h | 15 +++++- src/settings_config.c | 4 +- src/string_utils.c | 11 ++++ src/string_utils.h | 1 + src/timer.h | 2 +- src/ui.c | 2 +- src/windows/platform.c | 141 ++++++++++++++++++++++++++++++++----------------- 10 files changed, 222 insertions(+), 58 deletions(-) diff --git a/src/assets.c b/src/assets.c index acce310..3eddf02 100644 --- a/src/assets.c +++ b/src/assets.c @@ -35,13 +35,21 @@ inline static bool is_big_endian() void assets_do_post_process() { +#if 0 + static PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample = NULL; +#ifdef OS_WINDOWS + if (!glTexImage2DMultisample) + glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC)wglGetProcAddress("glTexImage2DMultisample"); +#endif +#endif + 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->type == ASSET_IMAGE || task->type == ASSET_BITMAP) { if (task->image->data && task->valid) { @@ -53,9 +61,16 @@ void assets_do_post_process() glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA8, task->image->width, task->image->height, 0, GL_RGBA, flag, task->image->data); + +#if 0 + if (glTexImage2DMultisample) + glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 16, GL_RGBA8, task->image->width, task->image->height, TRUE); +#endif + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); task->image->loaded = true; + glBindTexture(GL_TEXTURE_2D, 0); if (!task->image->keep_in_memory) stbi_image_free(task->image->data); @@ -93,6 +108,19 @@ void assets_do_post_process() mutex_unlock(&asset_mutex); } +bool assets_queue_worker_load_bitmap(image *image) +{ +#ifdef MODE_DEVELOPER + 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); +} + bool assets_queue_worker_load_image(image *image) { #ifdef MODE_DEVELOPER @@ -180,6 +208,11 @@ void *assets_queue_worker() bool result = assets_queue_worker_load_image(buf.image); buf.valid = result; } + if (buf.type == ASSET_BITMAP) + { + bool result = assets_queue_worker_load_bitmap(buf.image); + buf.valid = result; + } else if (buf.type == ASSET_FONT) { bool result = assets_queue_worker_load_font(buf.font); @@ -325,3 +358,61 @@ void assets_destroy() mutex_destroy(&asset_mutex); } + + +image *assets_load_bitmap(u8 *start_addr, s32 width, s32 height, s32 channels) +{ + // 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 = 0; + 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. + 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_BITMAP; + 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_bitmap(image *image_to_destroy) +{ + if (image_to_destroy->references == 1) + { + glBindTexture(GL_TEXTURE_2D, 0); + glDeleteTextures(1, &image_to_destroy->textureID); + + //array_remove(&global_asset_collection.images, image_at); + } + else + { + image_to_destroy->references--; + } +} diff --git a/src/assets.h b/src/assets.h index a2b02da..870ab97 100644 --- a/src/assets.h +++ b/src/assets.h @@ -12,12 +12,13 @@ typedef struct t_image { u8 *end_addr; bool loaded; bool keep_in_memory; + bool is_bitmap; s32 width; s32 height; s32 channels; void *data; s16 references; - GLuint textureID; + u32 textureID; } image; #define TEXT_CHARSET_START 0 @@ -33,7 +34,7 @@ typedef struct t_glyph s32 xoff; s32 yoff; void *bitmap; - GLuint textureID; + u32 textureID; } glyph; typedef struct t_font @@ -52,6 +53,7 @@ typedef struct t_font typedef enum t_asset_task_type { ASSET_IMAGE, + ASSET_BITMAP, ASSET_FONT, } asset_task_type; @@ -92,6 +94,9 @@ 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); +void assets_destroy_bitmap(image *image); + font *assets_load_font(u8 *start_addr, u8 *end_addr, s16 size); void assets_destroy_font(font *font); diff --git a/src/linux/platform.c b/src/linux/platform.c index 1b393d9..6083670 100644 --- a/src/linux/platform.c +++ b/src/linux/platform.c @@ -672,7 +672,7 @@ vec2 platform_get_window_size(platform_window *window) return res; } -platform_window platform_open_window(char *name, u16 width, u16 height, u16 max_w, u16 max_h, u16 min_w, u16 min_h) +platform_window platform_open_window_ex(char *name, u16 width, u16 height, u16 max_w, u16 max_h, u16 min_w, u16 min_h, s32 flags) { bool has_max_size = max_w || max_h; diff --git a/src/platform.h b/src/platform.h index b3d30e9..14118d2 100644 --- a/src/platform.h +++ b/src/platform.h @@ -160,11 +160,24 @@ typedef struct t_vec2 s32 y; } vec2; +// NOT IMPLEMENTED ON LINUX: USE FLAGS_NONE +typedef enum t_window_flags +{ + FLAGS_NONE = 0, + FLAGS_BORDERLESS = 1, + FLAGS_TOPMOST = 2, + FLAGS_GLOBAL_MOUSE = 4, + FLAGS_HIDDEN = 8, +} window_flags; +// NOT IMPLEMENTED ON LINUX: USE FLAGS_NONE + platform_window *main_window = 0; platform_window *settings_window = 0; bool platform_window_is_valid(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); + +#define platform_open_window(name, width, height, max_w, max_h, min_w, min_h) platform_open_window_ex(name,width,height,max_w,max_h,min_w,min_h, 0) +platform_window platform_open_window_ex(char *name, u16 width, u16 height, u16 max_w, u16 max_h, u16 min_w, u16 min_h, s32 flags); void platform_get_focus(platform_window *window); bool platform_set_clipboard(platform_window *window, char *buffer); bool platform_get_clipboard(platform_window *window, char *buffer); diff --git a/src/settings_config.c b/src/settings_config.c index d2bc018..0317ab7 100644 --- a/src/settings_config.c +++ b/src/settings_config.c @@ -199,7 +199,7 @@ void settings_config_set_number(settings_config *config, char *name, s64 value) if (setting) { char num_buf[20]; - snprintf(num_buf, 20, "%"PRId64"", value); + snprintf(num_buf, 20, "%I64d", value); s32 len = strlen(num_buf); mem_free(setting->value); @@ -217,7 +217,7 @@ void settings_config_set_number(settings_config *config, char *name, s64 value) // value char num_buf[20]; - snprintf(num_buf, 20, "%"PRId64"", value); + snprintf(num_buf, 20, "%I64d", value); len = strlen(num_buf); new_entry.value = mem_alloc(len+1); diff --git a/src/string_utils.c b/src/string_utils.c index 6709604..6bf1d01 100644 --- a/src/string_utils.c +++ b/src/string_utils.c @@ -224,6 +224,17 @@ inline bool string_equals(char *first, char *second) return (strcmp(first, second) == 0); } +s32 string_length(char *str) +{ + utf8_int32_t ch = 0; + s32 i = 0; + while((str = utf8codepoint(str, &ch)) && ch) + { + i++; + } + return i; +} + // replaces " with \" for file formats void string_appendf(char *buffer, char *text) { diff --git a/src/string_utils.h b/src/string_utils.h index 1c397f1..fa69bcb 100644 --- a/src/string_utils.h +++ b/src/string_utils.h @@ -64,6 +64,7 @@ bool string_match(char *first, char *second); bool string_contains_ex(char *big, char *small, array *text_matches, bool *cancel_search); void string_trim(char *string); bool string_equals(char *first, char *second); +s32 string_length(char *buffer); void string_append(char *buffer, char *text); bool string_is_asteriks(char *text); void string_copyn(char *buffer, char *text, s32 bufferlen); diff --git a/src/timer.h b/src/timer.h index 63afa30..4839b84 100644 --- a/src/timer.h +++ b/src/timer.h @@ -7,7 +7,7 @@ #ifndef INCLUDE_STOPWATCH #define INCLUDE_STOPWATCH -#ifdef MODE_DEVELOPER +#if defined(MODE_DEVELOPER) && !defined(MODE_TEST) 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; diff --git a/src/ui.c b/src/ui.c index ce99191..8869607 100644 --- a/src/ui.c +++ b/src/ui.c @@ -1777,7 +1777,7 @@ bool ui_push_button_image(button_state *state, char *title, image *img) result = true; } } - if (is_left_released(global_ui_context.mouse)) + else if (is_left_released(global_ui_context.mouse)) { state->state = 0; } diff --git a/src/windows/platform.c b/src/windows/platform.c index 4c24363..3290af8 100644 --- a/src/windows/platform.c +++ b/src/windows/platform.c @@ -4,10 +4,10 @@ * All rights reserved. */ -//#include #include #include #include +#include #include #include #include @@ -26,6 +26,7 @@ struct t_platform_window HDC hdc; HGLRC gl_context; WNDCLASS window_class; + s32 flags; s32 min_width; s32 min_height; @@ -372,11 +373,16 @@ LRESULT CALLBACK main_window_callback(HWND window, UINT message, WPARAM wparam, } else if (message == WM_KILLFOCUS) { - current_mouse_to_handle->x = MOUSE_OFFSCREEN; - current_mouse_to_handle->y = MOUSE_OFFSCREEN; + if (current_mouse_to_handle) + { + current_mouse_to_handle->x = MOUSE_OFFSCREEN; + current_mouse_to_handle->y = MOUSE_OFFSCREEN; + } current_window_to_handle->has_focus = false; - memset(current_keyboard_to_handle->keys, 0, MAX_KEYCODE); + + if (current_keyboard_to_handle) + memset(current_keyboard_to_handle->keys, 0, MAX_KEYCODE); } else if (message == WM_SETFOCUS) { @@ -524,7 +530,7 @@ void platform_get_focus(platform_window *window) SetFocus(window->window_handle); } -platform_window platform_open_window(char *name, u16 width, u16 height, u16 max_w, u16 max_h, u16 min_w, u16 min_h) +platform_window platform_open_window_ex(char *name, u16 width, u16 height, u16 max_w, u16 max_h, u16 min_w, u16 min_h, s32 flags) { debug_print_elapsed_title("window creation"); debug_print_elapsed_indent(); @@ -563,23 +569,46 @@ platform_window platform_open_window(char *name, u16 width, u16 height, u16 max_ debug_print_elapsed(startup_stamp, "register class"); int style = WS_VISIBLE|WS_SYSMENU|WS_CAPTION|WS_MINIMIZEBOX; + int ex_style = 0; if (min_w != max_w && min_h != max_h) style |= WS_SIZEBOX; else style |= WS_THICKFRAME; - window.window_handle = CreateWindow(window.window_class.lpszClassName, - name, - style, - CW_USEDEFAULT, - CW_USEDEFAULT, - width, - height, - 0, - 0, - instance, - 0); + if (flags & FLAGS_BORDERLESS) + { + style = WS_VISIBLE|WS_POPUP; + } + if (flags & FLAGS_TOPMOST) + { + ex_style = WS_EX_TOPMOST; + } + if (flags & FLAGS_HIDDEN) + { + style &= ~WS_VISIBLE; + } + + window.window_handle = CreateWindowEx(ex_style, + window.window_class.lpszClassName, + name, + style, + CW_USEDEFAULT, + CW_USEDEFAULT, + width, + height, + 0, + 0, + instance, + 0); + + if (flags & FLAGS_BORDERLESS) + { + ShowScrollBar(window.window_handle, SB_VERT, FALSE); + ShowScrollBar(window.window_handle, SB_HORZ, FALSE); + } + + window.flags = flags; debug_print_elapsed(startup_stamp, "create window"); @@ -594,6 +623,7 @@ platform_window platform_open_window(char *name, u16 width, u16 height, u16 max_ format.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER; format.cColorBits = 24; format.cAlphaBits = 8; + //format.cDepthBits = 16; format.iLayerType = PFD_MAIN_PLANE; // PFD_TYPE_RGBA s32 suggested_format_index = ChoosePixelFormat(window.hdc, &format); // SLOW AF?? @@ -620,32 +650,36 @@ platform_window platform_open_window(char *name, u16 width, u16 height, u16 max_ wglMakeCurrent(window.hdc, window.gl_context); ShowWindow(window.window_handle, cmd_show); - //BringWindowToTop(window.window_handle); + if (flags & FLAGS_HIDDEN) + ShowWindow(window.window_handle, SW_HIDE); + else + ShowWindow(window.window_handle, SW_SHOW); - //AllowSetForegroundWindow(ASFW_ANY); - //SetForegroundWindow(window.window_handle); - // blending - glEnable(GL_DEPTH_TEST); - //glDepthMask(true); - //glClearDepth(50); + ////// GL SETUP + glDepthMask(GL_TRUE); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glDepthFunc(GL_LEQUAL); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - // setup multisampling -#if 0 + glEnable(GL_DEPTH_TEST); + glAlphaFunc(GL_GREATER, 0.0f); glEnable(GL_ALPHA_TEST); glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE); glEnable(GL_SAMPLE_ALPHA_TO_ONE); glEnable(GL_MULTISAMPLE); - glHint(GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST); -#endif + glEnable(GL_TEXTURE_2D); + glEnable(GL_SCISSOR_TEST); + glEnable(GL_BLEND); + //glEnable(GL_FRAMEBUFFER_SRGB); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_MULTISAMPLE_ARB); window.is_open = true; + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); debug_print_elapsed(startup_stamp, "gl setup"); @@ -721,6 +755,7 @@ void platform_handle_events(platform_window *window, mouse_input *mouse, keyboar current_keyboard_to_handle = keyboard; current_mouse_to_handle = mouse; +#ifndef MODE_TEST mouse->left_state &= ~MOUSE_CLICK; mouse->right_state &= ~MOUSE_CLICK; mouse->left_state &= ~MOUSE_DOUBLE_CLICK; @@ -732,11 +767,13 @@ void platform_handle_events(platform_window *window, mouse_input *mouse, keyboar mouse->move_y = 0; mouse->scroll_state = 0; keyboard->text_changed = false; +#endif // mouse position (including outside of window) current_window_to_handle->has_focus = GetFocus() == current_window_to_handle->window_handle; - if (current_window_to_handle->has_focus) +#ifndef MODE_TEST + if (current_window_to_handle->has_focus || current_window_to_handle->flags & FLAGS_GLOBAL_MOUSE) { if((GetKeyState(VK_LBUTTON) & 0x100) == 0) { @@ -748,9 +785,15 @@ void platform_handle_events(platform_window *window, mouse_input *mouse, keyboar POINT p; GetCursorPos(&p); mouse->x = p.x - rec.left - GetSystemMetrics(SM_CYSIZEFRAME); - mouse->y = p.y - rec.top - GetSystemMetrics(SM_CYSIZE) - GetSystemMetrics(SM_CYFRAME); + + if (current_window_to_handle->flags & FLAGS_BORDERLESS) + mouse->y = p.y - rec.top; + else + mouse->y = p.y - rec.top - GetSystemMetrics(SM_CYSIZE) - GetSystemMetrics(SM_CYFRAME); + //printf("%d %d\n",GetSystemMetrics(SM_CYSIZE), GetSystemMetrics(SM_CYFRAME)); } +#endif MSG message; while(PeekMessageA(&message, window->window_handle, 0, 0, TRUE)) @@ -1315,15 +1358,15 @@ bool platform_send_http_request(char *url, char *params, char *response_buffer) char* szHeaders = "Content-Type: application/json"; char szReq[1024] = ""; - if(!HttpSendRequest(hHttpRequest, szHeaders, strlen(szHeaders), szReq, strlen(szReq))) { + if(!HttpSendRequest(hHttpRequest, szHeaders, strlen(szHeaders), szReq, strlen(szReq))) { goto failure; } - DWORD dwRead=0; - while(InternetReadFile(hHttpRequest, response_buffer, MAX_INPUT_LENGTH-1, &dwRead) && dwRead) { + DWORD dwRead=0; + while(InternetReadFile(hHttpRequest, response_buffer, MAX_INPUT_LENGTH-1, &dwRead) && dwRead) { response_buffer[dwRead] = 0; dwRead=0; - } + } goto done; @@ -1342,9 +1385,9 @@ bool platform_send_http_request(char *url, char *params, char *response_buffer) bool platform_get_mac_address(char *buffer, s32 buf_size) { PIP_ADAPTER_INFO pAdapterInfo; - PIP_ADAPTER_INFO pAdapter = NULL; - DWORD dwRetVal = 0; - UINT i; + PIP_ADAPTER_INFO pAdapter = NULL; + DWORD dwRetVal = 0; + UINT i; ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO); pAdapterInfo = mem_alloc(sizeof(IP_ADAPTER_INFO)); @@ -1352,21 +1395,21 @@ bool platform_get_mac_address(char *buffer, s32 buf_size) if (!pAdapterInfo) return false; if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) { - mem_free(pAdapterInfo); - pAdapterInfo = mem_alloc(ulOutBufLen); - if (!pAdapterInfo) return false; - } + mem_free(pAdapterInfo); + pAdapterInfo = mem_alloc(ulOutBufLen); + if (!pAdapterInfo) return false; + } if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) { pAdapter = pAdapterInfo; if (pAdapter) { for (i = 0; i < pAdapter->AddressLength; i++) { - if (i == (pAdapter->AddressLength - 1)) - buffer += sprintf(buffer, "%.2X", (int)pAdapter->Address[i]); - else - buffer += sprintf(buffer, "%.2X-", (int)pAdapter->Address[i]); - } + if (i == (pAdapter->AddressLength - 1)) + buffer += sprintf(buffer, "%.2X", (int)pAdapter->Address[i]); + else + buffer += sprintf(buffer, "%.2X-", (int)pAdapter->Address[i]); + } if (pAdapterInfo) mem_free(pAdapterInfo); return true; -- cgit v1.2.3-70-g09d2