diff --git a/base_string.cpp b/base_string.cpp deleted file mode 100644 index 660c8d0..0000000 --- a/base_string.cpp +++ /dev/null @@ -1,454 +0,0 @@ - -function U8 -to_lower_case(U8 a) { - if (a >= 'A' && a <= 'Z') - a += 32; - return a; -} - -function U8 -to_upper_case(U8 a) { - if (a >= 'a' && a <= 'z') - a -= 32; - return a; -} - -function U8 -char_to_lower(U8 c){ - if(c >= 'A' && c <= 'Z') - c += 32; - return c; -} - -function U8 -char_to_upper(U8 c){ - if(c >= 'a' && c <= 'z') - c -= 32; - return c; -} - -function B32 -is_whitespace(U8 w) { - bool result = w == '\n' || w == ' ' || w == '\t' || w == '\v' || w == '\r'; - return result; -} - -function B32 -is_alphabetic(U8 a) { - if ((a >= 'a' && a <= 'z') || (a >= 'A' && a <= 'Z')) { - return true; - } - return false; -} - -function B32 -is_number(U8 a) { - B32 result = a >= '0' && a <= '9'; - return result; -} - -function B32 -is_alphanumeric(U8 a) { - B32 result = is_number(a) || is_alphabetic(a); - return result; -} - -function B32 -string_compare(String a, String b, B32 ignore_case = false) { - if (a.len != b.len) - return false; - for (S64 i = 0; i < a.len; i++) { - U8 A = a.str[i]; - U8 B = b.str[i]; - if (ignore_case) { - A = to_lower_case(A); - B = to_lower_case(B); - } - if (A != B) - return false; - } - return true; -} - -function B32 -operator==(String a, String b){ - return string_compare(a,b); -} - -function String -string_copy(Allocator *a, String string){ - U8 *copy = exp_alloc_array(a, U8, string.len+1); - memory_copy(copy, string.str, string.len); - copy[string.len] = 0; - return (String){copy, string.len}; -} - -function String -string_fmtv(Allocator *a, const char *str, va_list args1) { - va_list args2; - va_copy(args2, args1); - S64 len = stbsp_vsnprintf(0, 0, str, args2); - va_end(args2); - - char *result = exp_alloc_array(a, char, len + 1); - stbsp_vsnprintf(result, len + 1, str, args1); - - String res = {(U8 *)result, len}; - return res; -} - -#define STRING_FMT(alloc, str, result) \ -va_list args1; \ -va_start(args1, str); \ -String result = string_fmtv(alloc, str, args1); \ -va_end(args1) - -function String -string_fmt(Allocator *a, const char *str, ...) { - STRING_FMT(a, str, result); - return result; -} - -//----------------------------------------------------------------------------- -// String builder -//----------------------------------------------------------------------------- -struct String_Builder_Block{ - String_Builder_Block *next; - S64 cap; - S64 len; - U8 data[0]; -}; - -struct String_Builder{ - Allocator *allocator; - String_Builder_Block *first; - String_Builder_Block *last; - - void push_block(SizeU size){ - auto *block = (String_Builder_Block *)exp_alloc(allocator, sizeof(String_Builder_Block) + size); - memory_zero(block, sizeof(String_Builder_Block)+1); // Also clear first byte of character data - block->cap = size; - SLLQueuePush(first, last, block); - } - - void init(S64 size = 4096){ - assert(allocator); - push_block(size); - } - - void append_data(void *data, S64 size){ - if(first == 0){ - init(); - } - - S64 remaining_cap = last->cap - last->len; - if(size > remaining_cap){ - S64 new_block_size = max(last->cap*2, size*2); - push_block(new_block_size); - } - - U8 *write_address = last->data + last->len; - last->len += size; - memory_copy(write_address, data, size); - } -}; - -function String_Builder -string_builder_make(Allocator *a, S64 first_block_size = 4096){ - String_Builder sb = {a}; - sb.init(first_block_size); - return sb; -} - -function void -appendf(String_Builder *b, const char *str, ...){ - if(b->first == 0){ - b->init(); - } - va_list args, args2; - va_start(args, str); - retry:{ - String_Builder_Block *block = b->last; - int block_size = block->cap - block->len; - char *write_address = (char *)block->data + block->len; - - va_copy(args2, args); - int written = vsnprintf(write_address, block_size, str, args2); - va_end(args2); - - if(written > block_size){ - int new_block_size = max(4096, (written+1)*2); - b->push_block(new_block_size); - goto retry; - } - block->len += written; - } - va_end(args); -} - -enum String_Builder_Flag{ - String_Builder_Flag_None = 0, - String_Builder_Flag_AddSize = 0, -}; - -function String -string_flatten(String_Builder *b, String_Builder_Flag flags = String_Builder_Flag_None){ - // @Note(Krzosa): Only single block, no need to flatten, vsnprintf null terminates too - if(b->first == b->last){ - String result = {b->first->data, b->first->len}; - return result; - } - - // @Note(Krzosa): Compute size to allocate - S64 size = 1; - if(is_flag_set(flags, String_Builder_Flag_AddSize)) size += sizeof(SizeU); - IterList(b){ - size += it->len; - } - - String result = {}; - result.str = (U8 *)exp_alloc(b->allocator, size); - if(is_flag_set(flags, String_Builder_Flag_AddSize)) { - memory_copy(result.str + result.len, &size, sizeof(S64)); - result.len += sizeof(S64); - } - - // @Note(Krzosa): Copy the content of each block into the string - IterList(b){ - memory_copy(result.str + result.len, it->data, it->len); - result.len += it->len; - } - - result.str[result.len] = 0; - return result; -} - -function void -test_string_builder(){ - Scratch scratch; - String_Builder sb = string_builder_make(scratch, 4); - appendf(&sb, "Thing, %d", 242252); - String f = string_flatten(&sb); - assert(string_compare(f, "Thing, 242252"_s)); - appendf(&sb, "-%f %f %f", 23.0, 42.29, 2925.2); - f = string_flatten(&sb); -} - -//----------------------------------------------------------------------------- -// -//----------------------------------------------------------------------------- -function void -string_path_normalize(String s) { - for (S64 i = 0; i < s.len; i++) { - if (s.str[i] == '\\') - s.str[i] = '/'; - } -} - -function String -string_make(char *str, S64 len) { - String result; - result.str = (U8 *)str; - result.len = len; - return result; -} - -function String -string_make(U8 *str, S64 len) { - return string_make((char*)str, len); -} - -function String -string_chop(String string, S64 len) { - len = clamp_top(len, string.len); - String result = string_make(string.str, string.len - len); - return result; -} - -function String -string_skip(String string, S64 len) { - len = clamp_top(len, string.len); - S64 remain = string.len - len; - String result = string_make(string.str + len, remain); - return result; -} - -function String -string_get_postfix(String string, S64 len) { - len = clamp_top(len, string.len); - S64 remain_len = string.len - len; - String result = string_make(string.str + remain_len, len); - return result; -} - -function String -string_get_prefix(String string, S64 len) { - len = clamp_top(len, string.len); - String result = string_make(string.str, len); - return result; -} - -function String -string_slice(String string, S64 first_index, S64 one_past_last_index) { - assert_msg(first_index < one_past_last_index, "string_slice, first_index is bigger then one_past_last_index"); - assert_msg(string.len > 0, "Slicing string of length 0! Might be an error!"); - String result = string; - if (string.len > 0) { - if (one_past_last_index > first_index) { - first_index = clamp_top(first_index, string.len - 1); - one_past_last_index = clamp_top(one_past_last_index, string.len); - result.str += first_index; - result.len = one_past_last_index - first_index; - } - else { - result.len = 0; - } - } - return result; -} - -function String -string_trim(String string) { - if (string.len == 0) return string; - - - S64 whitespace_begin = 0; - for (; whitespace_begin < string.len; whitespace_begin++) { - if (!is_whitespace(string.str[whitespace_begin])) { - break; - } - } - - S64 whitespace_end = string.len; - for (; whitespace_end != whitespace_begin; whitespace_end--) { - if (!is_whitespace(string.str[whitespace_end - 1])) { - break; - } - } - - if (whitespace_begin == whitespace_end) { - string.len = 0; - } - else { - string = string_slice(string, whitespace_begin, whitespace_end); - } - - return string; -} - -function String -string_trim_end(String string) { - S64 whitespace_end = string.len; - for (; whitespace_end != 0; whitespace_end--) { - if (!is_whitespace(string.str[whitespace_end - 1])) { - break; - } - } - - String result = string_get_prefix(string, whitespace_end); - return result; -} - -function String -string_to_lower_case(Allocator *arena, String s) { - String copy = string_copy(arena, s); - for (U64 i = 0; i < copy.len; i++) { - copy.str[i] = to_lower_case(copy.str[i]); - } - return copy; -} - -function String -string_to_upper_case(Allocator *arena, String s) { - String copy = string_copy(arena, s); - for (U64 i = 0; i < copy.len; i++) { - copy.str[i] = to_upper_case(copy.str[i]); - } - return copy; -} - -typedef U64 MatchFlag; -enum { - MatchFlag_None=0, - MatchFlag_FindLast=1, - MatchFlag_IgnoreCase=2, -}; - -function B32 -string_find(String string, String find, MatchFlag flags, S64 *index_out) { - B32 result = false; - if (flags & MatchFlag_FindLast) { - for (S64 i = string.len; i != 0; i--) { - S64 index = i - 1; - String substring = string_slice(string, index, index + find.len); - if (string_compare(substring, find, flags & MatchFlag_IgnoreCase)) { - if (index_out) - *index_out = index; - result = true; - break; - } - } - } - else { - for (S64 i = 0; i < string.len; i++) { - String substring = string_slice(string, i, i + find.len); - if (string_compare(substring, find, flags & MatchFlag_IgnoreCase)) { - if (index_out) - *index_out = i; - result = true; - break; - } - } - } - - return result; -} - -function String -string_chop_last_slash(String s) { - String result = s; - string_find(s, "/"_s, MatchFlag_FindLast, &result.len); - return result; -} - -function String -string_chop_last_period(String s) { - String result = s; - string_find(s, "."_s, MatchFlag_FindLast, &result.len); - return result; -} - -function String -string_skip_to_last_slash(String s) { - S64 pos; - String result = s; - if (string_find(s, "/"_s, MatchFlag_FindLast, &pos)) { - result = string_skip(result, pos + 1); - } - return result; -} - -function String -string_skip_to_last_period(String s) { - S64 pos; - String result = s; - if (string_find(s, "."_s, MatchFlag_FindLast, &pos)) { - result = string_skip(result, pos + 1); - } - return result; -} - -#if 0 -function void -test_stb_sprintf(){ - char buff[1024]; - const char *asd = "adfag"; - int len = snprintf(buff, 1024, "Thing %s", asd); - assert(string_make(buff,len) == "Thing adfag"_s); - - String thing = "Thing12312412412412412"_s; - thing.len = 5; - len = snprintf(buff, 1024, "%Q %Q", thing, string_make(thing.str + 5, 5)); - __debugbreak(); -} -#endif \ No newline at end of file diff --git a/build.bat b/build.bat index 8ae189f..f3141cf 100644 --- a/build.bat +++ b/build.bat @@ -1,4 +1,4 @@ @echo off -clang main.cpp -Wall -Wno-unused-function -Wno-missing-braces -fno-exceptions -fdiagnostics-absolute-paths -g -I"C:/base" -I".." -o main.exe -Wl,user32.lib \ No newline at end of file +clang main.cpp -Wall -Wno-unused-function -Wno-missing-braces -fno-exceptions -fdiagnostics-absolute-paths -g -I".." -o main.exe -Wl,user32.lib \ No newline at end of file diff --git a/kpl_multimedia.cpp b/kpl_multimedia.cpp deleted file mode 100644 index 5e7b366..0000000 --- a/kpl_multimedia.cpp +++ /dev/null @@ -1,899 +0,0 @@ -#include -#include -#include -#include - -#pragma comment(linker, "/subsystem:windows") -#pragma comment(lib, "gdi32.lib") -#pragma comment(lib, "Shcore.lib") -#pragma comment(lib, "opengl32.lib") - -// Symbols taken from GLFW -// -// Executables (but not DLLs) exporting this symbol with this value will be -// automatically directed to the high-performance GPU on Nvidia Optimus systems -// with up-to-date drivers -// -__declspec(dllexport) DWORD NvOptimusEnablement = 1; - -// Executables (but not DLLs) exporting this symbol with this value will be -// automatically directed to the high-performance GPU on AMD PowerXpress systems -// with up-to-date drivers -// -__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; - - - -OS os; -#include "math.h" - -typedef HRESULT tSetProcessDpiAwareness(PROCESS_DPI_AWARENESS); -typedef MMRESULT TimeBeginPeriod(MMRESULT); -constexpr DWORD window_style_simplified = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU; -constexpr DWORD window_style_resizable = WS_OVERLAPPEDWINDOW; -constexpr DWORD window_style_borderless = WS_POPUP; - -struct Win32Bitmap { - Bitmap bitmap; - HDC dc; - HBITMAP dib; -}; - -struct Win32FontCtx { - HFONT font; - Win32Bitmap bitmap; - TEXTMETRIC text_metric; - Font result; -}; - -struct OS_Win32 { - HWND window; - HDC window_dc; - Win32Bitmap screen; - HINSTANCE instance; - int show_cmd; - char *cmd_line; - bool good_scheduling; - void *main_fiber; - void *msg_fiber; - U8 text_buff[32]; - Vec2I prev_window_size; - Vec2I prev_mouse_pos; -}; -static_assert(sizeof(OS_Win32) < 256, "Too big"); -#define w32(a) (*(OS_Win32 *)(a).platform) - -api Bitmap bitmap(U32 *pixels, Vec2I size, Vec2 align_in_pixels = {}) { - Bitmap result; - result.pixels = pixels; - result.size = size; - result.align = align_in_pixels; - return result; -} - -function Win32Bitmap win32_create_bitmap(Vec2I size) { - Win32Bitmap result; - result.bitmap.size = size; - if (result.bitmap.size.y < 0) - result.bitmap.size.y = -result.bitmap.size.y; - - HDC hdc = GetDC(0); - BITMAPINFO bminfo = {}; - bminfo.bmiHeader.biSize = sizeof(bminfo.bmiHeader); - bminfo.bmiHeader.biWidth = (LONG)size.x; - bminfo.bmiHeader.biHeight = (LONG)-size.y; - bminfo.bmiHeader.biPlanes = 1; - bminfo.bmiHeader.biBitCount = 32; - bminfo.bmiHeader.biCompression = BI_RGB; // AA RR GG BB - bminfo.bmiHeader.biXPelsPerMeter = 1; - bminfo.bmiHeader.biYPelsPerMeter = 1; - - void *mem = 0; - result.dib = CreateDIBSection(hdc, &bminfo, DIB_RGB_COLORS, (void **)&mem, 0, 0); - assert_msg(mem != 0, "Failed to create win32 bitmap"); - result.dc = CreateCompatibleDC(hdc); - result.bitmap.pixels = (U32 *)mem; - return result; -} - -function void win32_destroy_bitmap(Win32Bitmap *b) { - if (b->bitmap.pixels) { - b->bitmap.pixels = 0; - DeleteDC(b->dc); - DeleteObject(b->dib); - } -} - -function LRESULT -CALLBACK win32_window_proc(HWND window, UINT uMsg, WPARAM wParam, LPARAM lParam) { - EventKind kind = EventKind_None; - Key key = Key_None; - LRESULT result = 0; - switch (uMsg) { - case WM_CLOSE: - DestroyWindow(window); - os.quit = 1; - break; - case WM_DESTROY: - PostQuitMessage(0); - os.quit = 1; - break; - case WM_SYSKEYDOWN: - case WM_KEYDOWN: { - kind = EventKind_KeyDown; - switch (wParam) { - -#define X(button, win) \ -case win: \ -key = Key_##button; \ -break; - - KEY_MAPPING - } - } break; - case WM_SYSKEYUP: - case WM_KEYUP: { - kind = EventKind_KeyUp; - switch (wParam) { - KEY_MAPPING -#undef X - } - } break; - case WM_TIMER: { - SwitchToFiber(w32(os).main_fiber); - } break; - case WM_ENTERMENULOOP: - case WM_ENTERSIZEMOVE: { - SetTimer(w32(os).window, 0, 1, 0); - } break; - case WM_EXITMENULOOP: - case WM_EXITSIZEMOVE: { - KillTimer(w32(os).window, 0); - } break; - case WM_MOUSEMOVE: { - POINT p; - GetCursorPos(&p); - ScreenToClient(w32(os).window, &p); - os.mouse_pos = vec2i(p.x, p.y); - os.mouse_pos.y = os.window_size.y - os.mouse_pos.y; - kind = EventKind_MouseMove; - } break; - case WM_LBUTTONDOWN: { - kind = EventKind_KeyDown; - key = Key_MouseLeft; - } break; - case WM_LBUTTONUP: { - kind = EventKind_KeyUp; - key = Key_MouseLeft; - } break; - case WM_RBUTTONDOWN: { - kind = EventKind_KeyDown; - key = Key_MouseRight; - } break; - case WM_RBUTTONUP: { - kind = EventKind_KeyUp; - key = Key_MouseRight; - } break; - case WM_MBUTTONDOWN: { - kind = EventKind_KeyDown; - key = Key_MouseMiddle; - } break; - case WM_MBUTTONUP: { - kind = EventKind_KeyUp; - key = Key_MouseMiddle; - } break; - case WM_MOUSEWHEEL: { - if ((int)wParam > 0) - os.mouse_wheel = 1; - else - os.mouse_wheel = -1; - kind = EventKind_MouseWheel; - } break; - case WM_CHAR: { - // @Todo: Can this overflow? - //kind = EventKind_KeyboardText; - //U32 codepoint = '?'; - //utf16_to_utf32((U16 *)&wParam, &codepoint); - //os.text.len += utf32_to_utf8(codepoint, w32(os).text_buff + os.text.len); - } break; - default: - result = DefWindowProcW(window, uMsg, wParam, lParam); - break; - } - - if (kind) { - if (kind == EventKind_KeyDown) { - if (os.key[key].down == 0) - os.key[key].pressed = 1; - os.key[key].down = 1; - } else if (kind == EventKind_KeyUp) { - os.key[key].released = 1; - os.key[key].down = 0; - } - } - - return result; -} - -function void -CALLBACK _os_fiber_event_proc(void *data) { - unused(data); - for (;;) { - MSG msg; - while (PeekMessageW(&msg, w32(os).window, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - SwitchToFiber(w32(os).main_fiber); - } -} - -function Vec2I -get_window_size(HWND window) { - Vec2I result; - RECT window_rect; - GetClientRect(window, &window_rect); - result.x = window_rect.right - window_rect.left; - result.y = window_rect.bottom - window_rect.top; - return result; -} - -function Vec2I -get_window_size_with_border(HWND window) { - RECT ClientRect; - GetWindowRect(window, &ClientRect); - Vec2I draw_area; - draw_area.x = (ClientRect.right - ClientRect.left); - draw_area.y = (ClientRect.bottom - ClientRect.top); - return draw_area; -} - -function Vec2I -get_border_size(HWND window) { - Vec2I client = get_window_size(window); - Vec2I wind_size = get_window_size_with_border(window); - Vec2I result = vec2i(wind_size.x - client.x, wind_size.y - client.y); - return result; -} - -api void os_quit() { os.quit = 1; } -api void os_set_fps(F64 fps) { os.ms_per_frame = 1 / fps; } -api void os_set_ms_per_frame(F64 ms) { os.ms_per_frame = ms; } - -api void os_show_cursor(B32 status) { - ShowCursor(status); - os.cursor_visible = status; -} - -api void os_set_window_title(String title) { - Scratch scratch; - BOOL result = SetWindowTextA(w32(os).window, (char *)title.str); - assert_msg(result != 0, "Failed to set window title"); - os.window_title = title; -} - -api void os_set_window_size(S32 x, S32 y) { - Vec2I border = get_border_size(w32(os).window); - int actual_width = (int)(x + border.x); - int actual_height = (int)(y + border.y); - bool result = - SetWindowPos(w32(os).window, 0, 0, 0, actual_width, actual_height, SWP_NOMOVE | SWP_NOOWNERZORDER); - assert_msg(result, "SetWindowPos returned invalid value"); - os.window_size = get_window_size(w32(os).window); -} - -api void os_pull_state() { - os.window_was_resized = false; - os.window_size = get_window_size(w32(os).window); - if (os.window_size != w32(os).prev_window_size) { - os.window_was_resized = true; - w32(os).prev_window_size = os.window_size; - } - os.monitor_size = vec2i(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); - - // @Note: Client relative - POINT point = {0, 0}; - ClientToScreen(w32(os).window, &point); - os.window_pos.x = point.x; - os.window_pos.y = point.y; - - // @Note: Get DPI scale - UINT dpi = GetDpiForWindow(w32(os).window); - assert_msg(dpi != 0, "Failed to get dpi for window"); - os.dpi_scale = (F32)dpi / 96.f; - - // @Note: Reset text - os.text.len = 0; - // @Note: Reset keys - for (int i = 0; i < Key_Count; i++) { - os.key[i].released = 0; - os.key[i].pressed = 0; - } - os.mouse_wheel = 0; - SwitchToFiber(w32(os).msg_fiber); - if (!os.quit) { - os.delta_mouse_pos = w32(os).prev_mouse_pos - os.mouse_pos; - w32(os).prev_mouse_pos = os.mouse_pos; - - // @Note: Resize - if (os.render_backend == RenderBackend_Software) { - if (os.window_size != w32(os).screen.bitmap.size && os.window_size.x != 0 && os.window_size.y != 0) { - win32_destroy_bitmap(&w32(os).screen); - w32(os).screen = win32_create_bitmap(vec2i(os.window_size.x, -(os.window_size.y))); - os.screen = &w32(os).screen.bitmap; - } - } - } -} - -api void os_init_software_render() { os.render_backend = RenderBackend_Software; } - -api B32 os_init_opengl() { - PIXELFORMATDESCRIPTOR p = {}; - p.nSize = sizeof(p); - p.nVersion = 1; - p.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; - p.iPixelType = PFD_TYPE_RGBA; - p.cColorBits = 32; - p.cDepthBits = 24; - p.cStencilBits = 8; - p.iLayerType = PFD_MAIN_PLANE; - - S32 pixel_format = ChoosePixelFormat(w32(os).window_dc, &p); - if (pixel_format != 0) { - if (SetPixelFormat(w32(os).window_dc, pixel_format, &p)) { - HGLRC gl_ctx = wglCreateContext(w32(os).window_dc); - if (gl_ctx != NULL) { - if (wglMakeCurrent(w32(os).window_dc, gl_ctx)) { - // Success - } - else { - log_error("Failed on wglMakeCurrent!"); - return false; - } - } - else { - log_error("Failed on wglCreateContext!"); - return false; - } - } - else { - log_error("Failed on SetPixelFormat!"); - return false; - } - } - else { - log_error("Failed on ChoosePixelFormat!"); - return false; - } - - os.opengl.vendor = (char *)glGetString(GL_VENDOR); - os.opengl.renderer = (char *)glGetString(GL_RENDERER); - os.opengl.version = (char *)glGetString(GL_VERSION); - os.opengl.extensions = (char *)glGetString(GL_EXTENSIONS); - os.render_backend = RenderBackend_OpenGL1; - - return true; -} - -global S64 Global_counts_per_second; -api F64 os_time() { - if (Global_counts_per_second == 0) { - LARGE_INTEGER freq; - QueryPerformanceFrequency(&freq); - Global_counts_per_second = freq.QuadPart; - } - - LARGE_INTEGER time; - QueryPerformanceCounter(&time); - F64 result = (F64)time.QuadPart / (F64)Global_counts_per_second; - return result; -} - -api B32 os_init() { - HMODULE shcore = LoadLibraryA("Shcore.dll"); - if (shcore) { - tSetProcessDpiAwareness *set_dpi_awr = - (tSetProcessDpiAwareness *)GetProcAddress(shcore, "SetProcessDpiAwareness"); - if (set_dpi_awr) { - HRESULT hr = set_dpi_awr(PROCESS_PER_MONITOR_DPI_AWARE); - assert_msg(SUCCEEDED(hr), "Failed to set dpi awareness"); - } - } - - HMODULE winmm = LoadLibraryA("winmm.dll"); - if (winmm) { - TimeBeginPeriod *timeBeginPeriod = (TimeBeginPeriod *)GetProcAddress(winmm, "timeBeginPeriod"); - if (timeBeginPeriod) { - if (timeBeginPeriod(1) == TIMERR_NOERROR) { - w32(os).good_scheduling = true; - } - } - } - - DWORD window_style_chosen = window_style_resizable; - if (!os.window_resizable) - window_style_chosen = window_style_simplified; - - os.app_start_time = os_time(); - os.frame_start_time = os.app_start_time; - os.update_begin_cycles = __rdtsc(); - - WNDCLASSW wc = {}; // @Todo(Krzosa): UTF - wc.lpfnWndProc = win32_window_proc; - wc.hInstance = w32(os).instance; - // @Todo(Krzosa): UTF conversions - wc.lpszClassName = L"Have a good day"; // @Todo(Krzosa): Cant set window title - wc.hCursor = LoadCursor(0, IDC_ARROW); - wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW; - if (!RegisterClassW(&wc)) { // @Todo(Krzosa): UTF - log_error("Failed to create window class!"); - return false; - } - - RECT window_rect; - window_rect.left = (LONG)os.window_pos.x; - window_rect.top = (LONG)os.window_pos.y; - window_rect.right = (LONG)os.window_size.x + window_rect.left; - window_rect.bottom = (LONG)os.window_size.y + window_rect.top; - AdjustWindowRectEx(&window_rect, window_style_chosen, false, 0); - - // @Todo(Krzosa): UTF - w32(os).window = CreateWindowW(wc.lpszClassName, wc.lpszClassName, window_style_chosen, window_rect.left, window_rect.top, window_rect.right - window_rect.left,window_rect.bottom - window_rect.top, NULL, NULL, w32(os).instance, NULL); - if (w32(os).window == 0) { - log_error("Failed to create window!"); - return false; - } - - ShowWindow(w32(os).window, w32(os).show_cmd); - UpdateWindow(w32(os).window); - w32(os).window_dc = GetDC(w32(os).window); - - w32(os).main_fiber = ConvertThreadToFiber(0); - assert_msg(w32(os).main_fiber, "Failed to create main fiber"); - w32(os).msg_fiber = CreateFiber(0, _os_fiber_event_proc, 0); - assert_msg(w32(os).msg_fiber, "Failed to create message fiber"); - - if (os.cursor_visible == false) - os_show_cursor(false); - - switch (os.render_backend) { - case RenderBackend_Software: { - os_init_software_render(); - } break; - case RenderBackend_OpenGL1: { - os_init_opengl(); - } break; - default: assert_msg(0, "Invalid value for render backend"); - break; - } - - os_pull_state(); - os.initialized = true; - return true; -} - -api bool os_game_loop() { - assert_msg(os.initialized, "Platform is not initialized! Please call os_init"); - switch (os.render_backend) { - case RenderBackend_Software: { - if (os.screen) { // @Note: Draw screen - U32 *p = os.screen->pixels; - for (int y = 0; y < os.screen->y; y++) { - for (int x = 0; x < os.screen->x; x++) { - *p = ((*p & 0xff000000)) | ((*p & 0x00ff0000) >> 16) | ((*p & 0x0000ff00)) | - ((*p & 0x000000ff) << 16); - p += 1; - } - } - - HDC hdc = w32(os).window_dc; - SelectObject(w32(os).screen.dc, w32(os).screen.dib); - BitBlt(hdc, 0, 0, (LONG)os.screen->size.x, (LONG)os.screen->size.y, w32(os).screen.dc, 0, 0, SRCCOPY); - } - } break; - case RenderBackend_OpenGL1: { - SwapBuffers(w32(os).window_dc); - } break; - default: - assert_msg(0, "Please select a rendering backend!"); - break; - } - arena_clear(os.frame_arena); - os.update_time = os_time() - os.frame_start_time; - os.update_end_cycles = __rdtsc(); - F64 frame_time = os.update_time; - F64 ms_per_frame = os.ms_per_frame; - if (frame_time < ms_per_frame) { - if (w32(os).good_scheduling) { - // @Todo: I have no idea if letting over sleep is bad or not - // Busy waiting is chugging cpu alot more, not sure what to do - F64 time_to_sleep = (ms_per_frame - frame_time) * 1000; - if (time_to_sleep > 0) { - Sleep((DWORD)time_to_sleep); - } - } - - do { - frame_time = os_time() - os.frame_start_time; - } while (frame_time < ms_per_frame); - } - os.frame++; - os.delta_time = frame_time; - os.fps = 1 / os.delta_time; - os.time += os.delta_time; - os.frame_start_time = os_time(); - os.update_begin_cycles = __rdtsc(); - os_pull_state(); - return !os.quit; -} - -int main(int argc, char **argv); -int WINAPI WinMain(HINSTANCE instance, HINSTANCE, LPSTR cmd_line, int show_cmd) { - thread_ctx_init(); - w32(os).instance = instance; - w32(os).show_cmd = show_cmd; - w32(os).cmd_line = cmd_line; - - Arena frame_arena = {}; - arena_init(&frame_arena, "Frame arena"_s); - os.perm_arena = &pernament_arena; - os.frame_arena = &frame_arena; - - os.dpi_scale = 1; - os.text.str = w32(os).text_buff; - os.window_title = "Have a good day!"_s; - os.window_pos.x = 0; - os.window_pos.y = 50; - os.window_size.x = 1280; - os.window_size.y = 720; - os.ms_per_frame = 1.f / 60.f; - os.cursor_visible = true; - - if(AttachConsole(-1)) { - freopen("CONIN$", "r",stdin); - freopen("CONOUT$", "w",stdout); - freopen("CONOUT$", "w",stderr); - } - - return main(__argc, __argv); -} - -////////////// -// @Note: Font API -function FontGlyph extract_glyph(Allocator *arena, Win32FontCtx *ctx, wchar_t glyph) { - SIZE size; - GetTextExtentPoint32W(ctx->bitmap.dc, &glyph, 1, &size); - TextOutW(ctx->bitmap.dc, 0, 0, &glyph, 1); - - // @Note: Find bitmap edges - int minx = 100000; - int miny = 100000; - int maxx = -100000; - int maxy = -100000; - for (int y = 499; y >= 500 - size.cy; y--) { - for (int x = 0; x < size.cx; x++) { - if (ctx->bitmap.bitmap.pixels[x + y * (int)ctx->bitmap.bitmap.size.x] != 0) { - if (minx > x) - minx = x; - if (miny > y) - miny = y; - if (maxx < x) - maxx = x; - if (maxy < y) - maxy = y; - } - } - } - - assert(minx >= 0 && miny >= 0); - int bwidth = maxx - minx + 1; - int bheight = maxy - miny + 1; - U32 *cropped = - (U32 *)exp_alloc(arena, sizeof(U32) * (U32)(bwidth) * (U32)(bheight)); - for (int y = miny; y <= maxy; y++) { - for (int x = minx; x <= maxx; x++) { - U32 value = ctx->bitmap.bitmap.pixels[x + y * (int)ctx->bitmap.bitmap.size.x]; - U32 *dst = cropped + ((size_t)(x - minx) + (size_t)(y - miny) * bwidth); -#if 1 // Premultiplied alpha - F32 alpha = (F32)((value & 0x000000ff) >> 0); - F32 rgb = (F32)0xff*(alpha/255.f); - U8 val = (U8)(rgb + 0.5f); - *dst = (((U32)(alpha+0.5f) << 24) | val << 16 | val << 8 | val); -#else - U8 grey = (value & 0x000000ff); - *dst = (grey << 24 | 0xff << 16 | 0xff << 8 | 0xff); -#endif - } - } - exp_alloc(arena, sizeof(U32) * (U32)bwidth); - - // @Note: Calculate char metrics - int glyph_descent = (499 - size.cy) - miny; - - FontGlyph result; - INT width; - GetCharWidth32W(ctx->bitmap.dc, glyph, glyph, &width); - result.xadvance = (F32)width; - result.bitmap = bitmap(cropped, vec2i(bwidth, bheight), - vec2((F32)-minx, (F32)ctx->text_metric.tmDescent + (F32)glyph_descent)); - return result; -} - -function Win32FontCtx begin_font_extraction(char *filename, char *font_name, S64 height) { - assert_msg(height < 500, "Height of font over 500"); - Win32FontCtx ctx = {}; - if (filename) { - int fonts_added = AddFontResourceExA(filename, FR_PRIVATE, 0); - assert_msg(fonts_added != 0, "AddFontResourceEx added 0 fonts"); - } - - ctx.bitmap = win32_create_bitmap(vec2i(500, -500)); - ctx.font = - CreateFontA((S32)height, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, - CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH | FF_DONTCARE, font_name); - assert_msg(ctx.font != NULL, "CreateFont returned a 0 pointer"); - SelectObject(ctx.bitmap.dc, ctx.bitmap.dib); - SelectObject(ctx.bitmap.dc, ctx.font); - GetTextMetrics(ctx.bitmap.dc, &ctx.text_metric); - ctx.result.height = (F32)height; - ctx.result.descent = (F32)ctx.text_metric.tmDescent; - ctx.result.ascent = (F32)ctx.text_metric.tmAscent; - ctx.result.line_advance = (F32)(height + ctx.text_metric.tmExternalLeading); - SetBkColor(ctx.bitmap.dc, RGB(0, 0, 0)); - SetTextColor(ctx.bitmap.dc, RGB(255, 255, 255)); - return ctx; -} - -function Font end_font_extraction(Win32FontCtx *ctx) { - win32_destroy_bitmap(&ctx->bitmap); - DeleteObject(ctx->font); - return ctx->result; -} - -api Font os_load_font(Allocator *arena, S32 height, const char *font_name, const char *filename) { - FontGlyph *glyphs = exp_alloc_array(arena, FontGlyph, 96, AF_ZeroMemory); - Win32FontCtx font_ctx = begin_font_extraction((char *)filename, (char *)font_name, height); - for (U32 i = '!'; i <= '~'; i++) { - glyphs[i - '!'] = extract_glyph(arena, &font_ctx, (wchar_t)i); - } - Font font = end_font_extraction(&font_ctx); - font.glyphs = glyphs; - font.glyphs_len = '~' - '!'; - return font; -} - -function void set_window_style(HWND window, DWORD style) { - // @Todo: Need to readup on this - SetWindowLongPtrW(window, GWL_STYLE, style); - SetWindowPos(window, nullptr, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE); - ShowWindow(window, SW_SHOW); -} - -#undef w32 -/////////////////////////////////////// -// @Section Audio -#include -#include -#include -#include - -const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator); -const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator); -const IID IID_IAudioClient = __uuidof(IAudioClient); -const IID IID_IAudioRenderClient = __uuidof(IAudioRenderClient); - -// NOTE: typedefines for the functions which are goint to be loaded -typedef HRESULT CoCreateInstanceFunction(REFCLSID rclsid, LPUNKNOWN *pUnkOuter, DWORD dwClsContext, - REFIID riid, LPVOID *ppv); -typedef HRESULT CoInitializeExFunction(LPVOID pvReserved, DWORD dwCoInit); - -// NOTE: empty functions(stubs) which are used when library fails to load -HRESULT CoCreateInstanceStub(REFCLSID rclsid, LPUNKNOWN *pUnkOuter, DWORD dwClsContext, REFIID riid, - LPVOID *ppv) { - unused(rclsid); - unused(pUnkOuter); - unused(dwClsContext); - unused(riid); - unused(ppv); - return S_FALSE; -} - -HRESULT CoInitializeExStub(LPVOID pvReserved, DWORD dwCoInit) { - unused(pvReserved); - unused(dwCoInit); - return S_FALSE; -} - -// NOTE: pointers to the functions from the dll -CoCreateInstanceFunction *CoCreateInstanceFunctionPointer = CoCreateInstanceStub; -CoInitializeExFunction *CoInitializeExFunctionPointer = CoInitializeExStub; - -// NOTE: Number of REFERENCE_TIME units per second -// One unit is equal to 100 nano seconds -#define REF_TIMES_PER_SECOND 10000000 -#define REF_TIMES_PER_MSECOND 10000 -#define w32(a) (*(Audio_Win32 *)(a)->platform) - -struct Audio_Win32 { - IMMDevice *device; - IAudioClient *audio_client; - - IMMDeviceEnumerator *device_enum; - IAudioRenderClient *audio_render_client; - IAudioCaptureClient *audio_capture_client; -}; -static_assert(sizeof(Audio::platform) > sizeof(Audio_Win32), - "Audio::platform is too small to hold Audio_Win32 struct"); - -// Load COM Library functions dynamically, -// this way sound is not necessary to run the game -function B32 win32_load_com() { - B32 result = true; - HMODULE ole32Library = LoadLibraryA("ole32.dll"); - if (ole32Library) { - CoCreateInstanceFunctionPointer = - (CoCreateInstanceFunction *)GetProcAddress(ole32Library, "CoCreateInstance"); - if (!CoCreateInstanceFunctionPointer) { - CoCreateInstanceFunctionPointer = CoCreateInstanceStub; - log_error("CoCreateInstance failed to load"); - result = false; - } - CoInitializeExFunctionPointer = (CoInitializeExFunction *)GetProcAddress(ole32Library, "CoInitializeEx"); - if (!CoInitializeExFunctionPointer) { - CoInitializeExFunctionPointer = CoInitializeExStub; - log_error("CoInitializeEx failed to load"); - result = false; - } - } else { - CoCreateInstanceFunctionPointer = CoCreateInstanceStub; - CoInitializeExFunctionPointer = CoInitializeExStub; - log_error("Failed to load OLE32.dll"); - result = false; - } - return result; -} - -api void os_clean_audio(Audio *audio) { - if (w32(audio).audio_client) - w32(audio).audio_client->Stop(); - if (w32(audio).device_enum) - w32(audio).device_enum->Release(); - if (w32(audio).device) - w32(audio).device->Release(); - if (w32(audio).audio_client) - w32(audio).audio_client->Release(); - if (w32(audio).audio_render_client) - w32(audio).audio_render_client->Release(); - audio->initialized = false; -} - -function DWORD win32_audio_thread(void *parameter) { - Audio *audio = (Audio *)parameter; - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); - HANDLE buffer_ready_event = CreateEvent(0, 0, 0, 0); - if (!buffer_ready_event) { - return -1; - } - if (FAILED(w32(audio).audio_client->SetEventHandle(buffer_ready_event))) { - return -1; - } - U32 buffer_frame_count; - if (FAILED(w32(audio).audio_client->GetBufferSize(&buffer_frame_count))) { - return -1; - } - // U32 buffer_sample_count = buffer_frame_count * audio->number_of_channels; - if (FAILED(w32(audio).audio_client->Start())) { - w32(audio).audio_client->Stop(); - return -1; - } - for (;;) { - if (WaitForSingleObject(buffer_ready_event, INFINITE) != WAIT_OBJECT_0) { - w32(audio).audio_client->Stop(); - return -1; - } - U32 padding_frame_count; - if (FAILED(w32(audio).audio_client->GetCurrentPadding(&padding_frame_count))) { - w32(audio).audio_client->Stop(); - return -1; - } - U32 *samples; - U32 fill_frame_count = buffer_frame_count - padding_frame_count; - if (FAILED(w32(audio).audio_render_client->GetBuffer(fill_frame_count, (BYTE **)&samples))) { - w32(audio).audio_client->Stop(); - return -1; - } - audio->callback(audio, samples, fill_frame_count); - if (FAILED(w32(audio).audio_render_client->ReleaseBuffer(fill_frame_count, 0))) { - w32(audio).audio_client->Stop(); - return -1; - } - } - return 0; -} - -function AUDIO_CALLBACK(default_audio_callback) { - memory_zero(buffer, (U64)frames_to_fill * (U64)audio->samples_per_second); -} - -api B32 os_init_audio(Audio *audio) { - audio->bits_per_sample = 16; - if (audio->number_of_channels == 0) - audio->number_of_channels = 2; - if (audio->samples_per_second == 0) - audio->samples_per_second = 44100; - if (audio->callback == 0) - audio->callback = default_audio_callback; - - B32 success = win32_load_com(); - if (!success) { - return false; - } - if (FAILED(CoInitializeExFunctionPointer(0, COINITBASE_MULTITHREADED))) { - log_error("Failed to initialize COM, CoInitializeEx"); - return false; - } - if (FAILED(CoCreateInstanceFunctionPointer(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, - IID_IMMDeviceEnumerator, (LPVOID *)&w32(audio).device_enum))) { - log_error("Failed to initialize COM, CoCreateInstance"); - return false; - } - if (FAILED(w32(audio).device_enum->GetDefaultAudioEndpoint(eRender, eConsole, &w32(audio).device))) { - os_clean_audio(audio); - log_error("Failed to initialize WASAPI, GetDefaultAudioEndpoint"); - return false; - } - if (FAILED( - w32(audio).device->Activate(IID_IAudioClient, CLSCTX_ALL, 0, (void **)&w32(audio).audio_client))) { - os_clean_audio(audio); - log_error("Failed to initialize WASAPI, " - "w32(audio).device->Activate(IID_IAudioClient,"); - return false; - } - - WAVEFORMATEX waveFormat = {}; - waveFormat.wFormatTag = WAVE_FORMAT_PCM; - waveFormat.nChannels = audio->number_of_channels; - waveFormat.nSamplesPerSec = audio->samples_per_second; - waveFormat.wBitsPerSample = audio->bits_per_sample; - waveFormat.nBlockAlign = waveFormat.nChannels * waveFormat.wBitsPerSample / 8; - waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign; - REFERENCE_TIME requestedBufferDuration = REF_TIMES_PER_MSECOND * 40; - if (FAILED(w32(audio).audio_client->Initialize(AUDCLNT_SHAREMODE_SHARED, - AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_RATEADJUST | - AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM | AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY, - requestedBufferDuration, 0, &waveFormat, 0))) { - os_clean_audio(audio); - log_error("Failed to initialize WASAPI, w32(audio).audio_client->Initialize"); - return false; - } - if (FAILED(w32(audio).audio_client->GetService(IID_IAudioRenderClient, - (void **)&w32(audio).audio_render_client))) { - os_clean_audio(audio); - log_error("Failed to initialize WASAPI, " - "w32(audio).audio_client->GetService(IID_IAudioRenderClient"); - return false; - } - if (FAILED(w32(audio).audio_client->GetBufferSize(&audio->buffer_frame_count))) { - os_clean_audio(audio); - log_error("Failed to initialize WASAPI, w32(audio).audio_client->GetBufferSize"); - return false; - } - HANDLE thread_handle = CreateThread(0, 0, win32_audio_thread, audio, 0, 0); - if (!thread_handle) { - os_clean_audio(audio); - log_error("Failed to initialize WASAPI, CreateThread returned 0 in handle"); - return false; - } - if (thread_handle == INVALID_HANDLE_VALUE) { - os_clean_audio(audio); - log_error("Failed to initialize WASAPI, CreateThread for " - "audio failed with INVALID HANDLE VALUE"); - return false; - } - CloseHandle(thread_handle); - audio->initialized = true; -#undef w32 - return true; -} - diff --git a/kpl_multimedia.h b/kpl_multimedia.h deleted file mode 100644 index 8871774..0000000 --- a/kpl_multimedia.h +++ /dev/null @@ -1,230 +0,0 @@ -#pragma once - -struct Bitmap { - union { - U32 *pixels; - U64 id; - }; - union { - Vec2I size; - struct { - S32 x, y; - }; - }; - Vec2 align; -}; - -enum EventKind { - EventKind_None, - EventKind_KeyDown, - EventKind_KeyUp, - EventKind_MouseMove, - EventKind_MouseWheel, - EventKind_KeyboardText, -}; - -enum Key { - Key_None, - Key_Up, - Key_Down, - Key_Left, - Key_Right, - Key_Escape, - Key_F1, - Key_F2, - Key_F3, - Key_F4, - Key_F5, - Key_F6, - Key_F7, - Key_F8, - Key_F9, - Key_F10, - Key_F11, - Key_F12, - Key_MouseLeft, - Key_MouseRight, - Key_MouseMiddle, - Key_0 = '0', - Key_1, - Key_2, - Key_3, - Key_4, - Key_5, - Key_6, - Key_7, - Key_8, - Key_9 = '9', - Key_A = 'a', - Key_B, - Key_C, - Key_D, - Key_E, - Key_F, - Key_G, - Key_H, - Key_I, - Key_J, - Key_K, - Key_L, - Key_M, - Key_N, - Key_O, - Key_P, - Key_Q, - Key_R, - Key_S, - Key_T, - Key_U, - Key_V, - Key_W, - Key_X, - Key_Y, - Key_Z = 'z', - Key_Count = 256, -}; - -#define KEY_MAPPING \ -X(Up, VK_UP) \ -X(Down, VK_DOWN) \ -X(Left, VK_LEFT) \ -X(Right, VK_RIGHT) \ -X(Escape, VK_ESCAPE) \ -X(F1, VK_F1) \ -X(F2, VK_F2) \ -X(F3, VK_F3) \ -X(F4, VK_F4) \ -X(F5, VK_F5) \ -X(F6, VK_F6) \ -X(F7, VK_F7) \ -X(F8, VK_F8) \ -X(F9, VK_F9) \ -X(F10, VK_F10) \ -X(F11, VK_F11) \ -X(F12, VK_F12) \ -X(A, 65) \ -X(B, 66) \ -X(C, 67) \ -X(D, 68) \ -X(E, 69) \ -X(F, 70) \ -X(G, 71) \ -X(H, 72) \ -X(I, 73) \ -X(J, 74) \ -X(K, 75) \ -X(L, 76) \ -X(M, 77) \ -X(N, 78) \ -X(O, 79) \ -X(P, 80) \ -X(Q, 81) \ -X(R, 82) \ -X(S, 83) \ -X(T, 84) \ -X(U, 85) \ -X(V, 86) \ -X(W, 87) \ -X(X, 88) \ -X(Y, 89) \ -X(Z, 90) \ -X(0, 48) \ -X(1, 49) \ -X(2, 50) \ -X(3, 51) \ -X(4, 52) \ -X(5, 53) \ -X(6, 54) \ -X(7, 55) \ -X(8, 56) \ -X(9, 57) - -struct DigitalKey { - bool pressed; - bool down; - bool released; -}; - -enum RenderBackend { - RenderBackend_Software, - RenderBackend_OpenGL1, -}; - -struct OS { - bool quit; - bool initialized; - Arena *frame_arena; - Arena *perm_arena; - - F64 ms_per_frame; - bool window_resizable; - bool window_was_resized; - String window_title; - Vec2I window_size; - Vec2I window_pos; - RenderBackend render_backend; - - Bitmap *screen; - Vec2I monitor_size; - F32 dpi_scale; - - F64 fps; - F64 delta_time; - F64 time; - U64 frame; - F64 update_time; - U64 update_begin_cycles; - U64 update_end_cycles; - F64 frame_start_time; - F64 app_start_time; - - B32 cursor_visible; - DigitalKey key[Key_Count]; - F32 mouse_wheel; - Vec2I mouse_pos; - Vec2I delta_mouse_pos; - - String text; - - char platform[256]; - struct { - char *vendor; - char *version; - char *renderer; - char *extensions; - } opengl; -}; - -struct FontGlyph { - F32 xadvance; - U32 codepoint; - Bitmap bitmap; -}; - -struct Font { - F32 line_advance; - F32 ascent; - F32 descent; - F32 height; - FontGlyph *glyphs; - U32 glyphs_len; -}; - -struct Audio; -#define AUDIO_CALLBACK(name) void name(Audio *audio, U32* buffer, U32 frames_to_fill) -typedef AUDIO_CALLBACK(AudioCallback); - -struct Audio { - AudioCallback *callback; - B32 initialized; - U32 samples_per_second; - U32 number_of_channels; - - // NOTE: one frame is 2 samples (left, right) 32 bits if - // one sample is equal 16 bit - U32 buffer_frame_count; - U32 latency_frame_count; - S32 bits_per_sample; - - char platform[128]; -}; diff --git a/main.cpp b/main.cpp index 4d89cc0..3ab79a0 100644 --- a/main.cpp +++ b/main.cpp @@ -78,21 +78,24 @@ /// - [x] Simple scatter plot /// /// +/// ### Urgent: +/// +/// - [ ] Simplify the code, especially for the 2d routines +/// - [ ] Asset processor as second program +/// +/// #define PREMULTIPLIED_ALPHA_BLENDING 1 -#include "base.cpp" -#include "kpl_multimedia.h" -#include "kpl_multimedia.cpp" +#include "multimedia.cpp" #include "profile.cpp" -#include "math.h" -struct R_Vertex { +struct Vertex { Vec3 pos; Vec2 tex; Vec3 norm; }; -struct R_Render { +struct Render { Mat4 camera; Mat4 projection; Mat4 transform; @@ -109,6 +112,7 @@ struct R_Render { F32 *depth320; }; +#define STBI_ASSERT assert #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" #include "obj_parser.cpp" @@ -145,7 +149,7 @@ Vec4 premultiplied_alpha(Vec4 dst, Vec4 src) { } function -void r_draw_rect(Bitmap* dst, F32 X, F32 Y, F32 w, F32 h, Vec4 color) { +void draw_rect(Bitmap* dst, F32 X, F32 Y, F32 w, F32 h, Vec4 color) { int max_x = (int)(min(X + w, (F32)dst->x) + 0.5f); int max_y = (int)(min(Y + h, (F32)dst->y) + 0.5f); int min_x = (int)(max(0.f, X) + 0.5f); @@ -165,7 +169,7 @@ void r_draw_rect(Bitmap* dst, F32 X, F32 Y, F32 w, F32 h, Vec4 color) { } function -void r_draw_bitmap(Bitmap* dst, Bitmap* src, Vec2 pos, Vec2 size=vec2(F32MAX, F32MAX)) { +void draw_bitmap(Bitmap* dst, Bitmap* src, Vec2 pos, Vec2 size=vec2(F32MAX, F32MAX)) { S64 minx = (S64)(pos.x + 0.5); S64 miny = (S64)(pos.y + 0.5); @@ -247,7 +251,7 @@ void r_draw_bitmap(Bitmap* dst, Bitmap* src, Vec2 pos, Vec2 size=vec2(F32MAX, F3 } function -Vec4 r_base_string(Bitmap *dst, Font *font, String word, Vec2 pos, B32 draw) { +Vec4 base_string(Bitmap *dst, Font *font, String word, Vec2 pos, B32 draw) { Vec2 og_position = pos; F32 max_x = pos.x; for (U64 i = 0; i < word.len; i++) { @@ -262,7 +266,7 @@ Vec4 r_base_string(Bitmap *dst, Font *font, String word, Vec2 pos, B32 draw) { } else { FontGlyph* g = &font->glyphs[word.str[i] - '!']; - if(draw) r_draw_bitmap(dst, &g->bitmap, pos - g->bitmap.align); + if(draw) draw_bitmap(dst, &g->bitmap, pos - g->bitmap.align); pos.x += g->xadvance; if (pos.x > max_x) max_x = pos.x; } @@ -272,13 +276,13 @@ Vec4 r_base_string(Bitmap *dst, Font *font, String word, Vec2 pos, B32 draw) { } function -Vec4 r_draw_string(Bitmap *dst, Font *font, String word, Vec2 pos) { - return r_base_string(dst, font, word, pos, true); +Vec4 draw_string(Bitmap *dst, Font *font, String word, Vec2 pos) { + return base_string(dst, font, word, pos, true); } function -Vec4 r_get_string_rect(Font *font, String word, Vec2 pos) { - return r_base_string(0, font, word, pos, false); +Vec4 get_string_rect(Font *font, String word, Vec2 pos) { + return base_string(0, font, word, pos, false); } function @@ -493,7 +497,7 @@ void draw_triangle_bilinear(Bitmap* dst, F32 *depth_buffer, Bitmap *src, F32 lig } function -void r_scatter_plot(Bitmap *dst, F64 *data, S64 data_len) { +void scatter_plot(Bitmap *dst, F64 *data, S64 data_len) { F64 min = F32MAX; F64 max = F32MIN; F64 step = dst->x / (F64)data_len; @@ -508,13 +512,13 @@ void r_scatter_plot(Bitmap *dst, F64 *data, S64 data_len) { *p /= diff; F64 y = *p * dst->y; x += step; - r_draw_rect(dst, (F32)x-2, (F32)y-2, 4, 4, vec4(1,0,0,1)); + draw_rect(dst, (F32)x-2, (F32)y-2, 4, 4, vec4(1,0,0,1)); //dst->pixels[xi + yi * dst->x] = 0xffff0000; } } function -void r_draw_mesh(R_Render *r, String scene_name, Obj_Material *materials, Obj_Mesh *mesh, Vec3 *vertices, Vec2 *tex_coords, Vec3 *normals) { +void draw_mesh(Render *r, String scene_name, Obj_Material *materials, Obj_Mesh *mesh, Vec3 *vertices, Vec2 *tex_coords, Vec3 *normals) { for (int i = 0; i < mesh->indices.len; i++) { Obj_Index *index = mesh->indices.data + i; Bitmap *image = &r->img; @@ -527,7 +531,7 @@ void r_draw_mesh(R_Render *r, String scene_name, Obj_Material *materials, Obj_Me } } - R_Vertex vert[] = { + Vertex vert[] = { { vertices[index->vertex[0] - 1], tex_coords[index->tex[0] - 1], @@ -599,15 +603,15 @@ void r_draw_mesh(R_Render *r, String scene_name, Obj_Material *materials, Obj_Me Vec3 znear_normal = vec3(0, 0, 1); Vec3 znear_pos = vec3(0, 0, 1.f); - struct _R_Vertex { + struct _Vertex { Vec4 pos; Vec2 tex; Vec3 norm; } in[4]; S32 in_count = 0; - R_Vertex *prev = vert + 2; - R_Vertex *curr = vert; + Vertex *prev = vert + 2; + Vertex *curr = vert; F32 prev_dot = dot(znear_normal, prev->pos - znear_pos); F32 curr_dot = 0; for (int j = 0; j < 3; j++) { @@ -669,7 +673,7 @@ global F32 rotation = 0; global Obj f22; global Obj *sponza; global Obj *obj; -global R_Render r = {}; +global Render r = {}; global Scene scene = Scene_Sponza; function @@ -691,7 +695,13 @@ UI_SIGNAL_CALLBACK(scene_callback) { scene = (Scene)(((int)scene + 1) % Scene_Count); } +function void +windows_log(Log_Kind kind, String string, char *file, int line){ + OutputDebugStringA((char *)string.str); +} + int main(int argc, char **argv) { + thread_ctx.log_proc = windows_log; os.window_size.x = 320*2; os.window_size.y = 180*2; os.window_resizable = 1; @@ -703,7 +713,6 @@ int main(int argc, char **argv) { //sponza = &sponza_obj; //dump_obj_to_file(sponza); sponza = load_obj_dump(os.perm_arena, "sponza.bin"_s); - scene_callback(); int screen_x = 1280/2; @@ -715,24 +724,6 @@ int main(int argc, char **argv) { r.depth320 = (F32 *)arena_push_size(os.perm_arena, sizeof(F32) * screen_x * screen_y); r.img = load_image("assets/bricksx64.png"_s); - /* @Note: Transparent texture */ { -#if 0 - Vec4 testc = vec4(1, 1, 1, 0.5f); - testc.rgb *= testc.a; - U32 testc32 = vec4_to_u32abgr(testc); - U32 a[] = { d - testc32, testc32, testc32, testc32, - testc32, testc32, testc32, testc32, - testc32, testc32, testc32, testc32, - testc32, testc32, testc32, testc32, - }; - r.img.pixels = a; - r.img.x = 4; - r.img.y = 4; -#endif - } - - String frame_data = {}; UISetup setup[] = { @@ -795,7 +786,7 @@ int main(int argc, char **argv) { Vec3 *normals = (Vec3 *)obj->normals.data; Obj_Mesh *mesh = obj->mesh.data; Vec3* vertices = (Vec3 *)obj->vertices.data; - r_draw_mesh(&r, obj->name, obj->materials.data, mesh+i, vertices, tex_coords, normals); + draw_mesh(&r, obj->name, obj->materials.data, mesh+i, vertices, tex_coords, normals); } diff --git a/math.h b/math.h deleted file mode 100644 index b9d57fb..0000000 --- a/math.h +++ /dev/null @@ -1,1712 +0,0 @@ -#pragma once - -/////////////////////////////////////// -// @Section Math -#include -constexpr F32 PI32 = 3.14159265359f; - -api F32 power(S64 pow, F32 value) { - F32 result = value; - if (pow == 0) { - result = 1; - } else { - for (S64 i = 1; i < pow; i++) { - result *= result; - } - } - return result; -} - -api F32 to_radians(F32 degrees) { - F32 result = degrees * (PI32 / 180.f); - return result; -} - -api F32 to_degrees(F32 radians) { - F32 result = radians * (180.f / PI32); - return result; -} - -api F32 fraction(F32 value) { - F32 result = value - floorf(value); - return result; -} - -api F32 absolute(F32 value) { - if (value < 0) - value = -value; - return value; -} - -api S32 square(S32 val) { return val * val; } - -api S32 clamp01(S32 val) { - S32 result = clamp(0, val, 1); - return result; -} - -api S32 sign(S32 val) { - if (val > 0) - return 1; - else if (val < 0) - return -1; - return 0; -} - -api F32 square(F32 val) { return val * val; } - -api F32 clamp01(F32 val) { - F32 result = clamp(0.f, val, 1.f); - return result; -} - -api F32 sign(F32 val) { - if (val > 0) - return 1; - else if (val < 0) - return -1; - return 0; -} - -api F32 floor(F32 val) { return floorf(val); } - -api F32 ceil(F32 val) { return ceilf(val); } - -api F32 round(F32 val) { return roundf(val); } - -api F32 sine(F32 val) { return sinf(val); } - -api F32 sine01(F32 val) { - F32 result = sine(val); - result += 1; - result /= 2; - return result; -} - -api F32 cosine(F32 val) { return cosf(val); } - -api F32 square_root(F32 val) { return sqrtf(val); } - -api Vec2 vec2(F32 x, F32 y) { - Vec2 result; - result.x = x; - result.y = y; - return result; -} -api Vec2 vec2() { return vec2(0, 0); } -api Vec2 operator+(Vec2 a, Vec2 b) { - Vec2 result = vec2(a.x + b.x, a.y + b.y); - return result; -} -api Vec2 operator+(Vec2 a, F32 b) { - Vec2 result = vec2(a.x + b, a.y + b); - return result; -} -api Vec2 operator+(F32 a, Vec2 b) { - Vec2 result = vec2(a + b.x, a + b.y); - return result; -} -api Vec2 &operator+=(Vec2 &a, Vec2 b) { - a = a + b; - return a; -} -api Vec2 &operator+=(Vec2 &a, F32 b) { - a = a + b; - return a; -} -api Vec2 operator-(Vec2 a, Vec2 b) { - Vec2 result = vec2(a.x - b.x, a.y - b.y); - return result; -} -api Vec2 operator-(Vec2 a, F32 b) { - Vec2 result = vec2(a.x - b, a.y - b); - return result; -} -api Vec2 operator-(F32 a, Vec2 b) { - Vec2 result = vec2(a - b.x, a - b.y); - return result; -} -api Vec2 &operator-=(Vec2 &a, Vec2 b) { - a = a - b; - return a; -} -api Vec2 &operator-=(Vec2 &a, F32 b) { - a = a - b; - return a; -} -api Vec2 operator*(Vec2 a, Vec2 b) { - Vec2 result = vec2(a.x * b.x, a.y * b.y); - return result; -} -api Vec2 operator*(Vec2 a, F32 b) { - Vec2 result = vec2(a.x * b, a.y * b); - return result; -} -api Vec2 operator*(F32 a, Vec2 b) { - Vec2 result = vec2(a * b.x, a * b.y); - return result; -} -api Vec2 &operator*=(Vec2 &a, Vec2 b) { - a = a * b; - return a; -} -api Vec2 &operator*=(Vec2 &a, F32 b) { - a = a * b; - return a; -} -api Vec2 operator/(Vec2 a, Vec2 b) { - Vec2 result = vec2(a.x / b.x, a.y / b.y); - return result; -} -api Vec2 operator/(Vec2 a, F32 b) { - Vec2 result = vec2(a.x / b, a.y / b); - return result; -} -api Vec2 operator/(F32 a, Vec2 b) { - Vec2 result = vec2(a / b.x, a / b.y); - return result; -} -api Vec2 &operator/=(Vec2 &a, Vec2 b) { - a = a / b; - return a; -} -api Vec2 &operator/=(Vec2 &a, F32 b) { - a = a / b; - return a; -} -api B32 operator!=(Vec2 a, Vec2 b) { - B32 result = (a.x != b.x) || (a.y != b.y); - return result; -} -api B32 operator==(Vec2 a, Vec2 b) { - B32 result = (a.x == b.x) && (a.y == b.y); - return result; -} -api Vec2 operator-(Vec2 a) { - Vec2 result = vec2(-a.x, -a.y); - return result; -} -api Vec2 clamp(Vec2 min, Vec2 val, Vec2 max) { - Vec2 result = vec2(clamp(min.x, val.x, max.x), clamp(min.y, val.y, max.y)); - return result; -} -api Vec2 clamp(F32 min, Vec2 val, F32 max) { - Vec2 result = vec2(clamp(min, val.x, max), clamp(min, val.y, max)); - return result; -} -api Vec2 clamp01(Vec2 val) { - Vec2 result = vec2(clamp01(val.x), clamp01(val.y)); - return result; -} -api Vec2 ceil(Vec2 a) { - Vec2 result = vec2(ceil(a.x), ceil(a.y)); - return result; -} -api Vec2 floor(Vec2 a) { - Vec2 result = vec2(floor(a.x), floor(a.y)); - return result; -} -api Vec2 round(Vec2 a) { - Vec2 result = vec2(round(a.x), round(a.y)); - return result; -} -api Vec2 absolute(Vec2 a) { - Vec2 result = vec2(absolute(a.x), absolute(a.y)); - return result; -} -api Vec2 sign(Vec2 a) { - Vec2 result = vec2(sign(a.x), sign(a.y)); - return result; -} -api Vec2 fraction(Vec2 a) { - Vec2 result = vec2(fraction(a.x), fraction(a.y)); - return result; -} -api Vec2 square(Vec2 a) { - Vec2 result = vec2(square(a.x), square(a.y)); - return result; -} -api Vec2 square_root(Vec2 a) { - Vec2 result = vec2(square_root(a.x), square_root(a.y)); - return result; -} -api F32 dot(Vec2 a, Vec2 b) { - F32 result = a.x * b.x + a.y * b.y; - return result; -} -api F32 length_squared(Vec2 a) { - F32 result = dot(a, a); - return result; -} -api F32 length(Vec2 a) { - F32 result = square_root(length_squared(a)); - return result; -} -api Vec2 lerp(Vec2 from, Vec2 to, F32 t) { - Vec2 result = (1 - t) * from + to * t; - return result; -} -api Vec3 vec3(F32 x, F32 y, F32 z) { - Vec3 result; - result.x = x; - result.y = y; - result.z = z; - return result; -} -api Vec3 vec3() { return vec3(0, 0, 0); } -api Vec3 operator+(Vec3 a, Vec3 b) { - Vec3 result = vec3(a.x + b.x, a.y + b.y, a.z + b.z); - return result; -} -api Vec3 operator+(Vec3 a, F32 b) { - Vec3 result = vec3(a.x + b, a.y + b, a.z + b); - return result; -} -api Vec3 operator+(F32 a, Vec3 b) { - Vec3 result = vec3(a + b.x, a + b.y, a + b.z); - return result; -} -api Vec3 &operator+=(Vec3 &a, Vec3 b) { - a = a + b; - return a; -} -api Vec3 &operator+=(Vec3 &a, F32 b) { - a = a + b; - return a; -} -api Vec3 operator-(Vec3 a, Vec3 b) { - Vec3 result = vec3(a.x - b.x, a.y - b.y, a.z - b.z); - return result; -} -api Vec3 operator-(Vec3 a, F32 b) { - Vec3 result = vec3(a.x - b, a.y - b, a.z - b); - return result; -} -api Vec3 operator-(F32 a, Vec3 b) { - Vec3 result = vec3(a - b.x, a - b.y, a - b.z); - return result; -} -api Vec3 &operator-=(Vec3 &a, Vec3 b) { - a = a - b; - return a; -} -api Vec3 &operator-=(Vec3 &a, F32 b) { - a = a - b; - return a; -} -api Vec3 operator*(Vec3 a, Vec3 b) { - Vec3 result = vec3(a.x * b.x, a.y * b.y, a.z * b.z); - return result; -} -api Vec3 operator*(Vec3 a, F32 b) { - Vec3 result = vec3(a.x * b, a.y * b, a.z * b); - return result; -} -api Vec3 operator*(F32 a, Vec3 b) { - Vec3 result = vec3(a * b.x, a * b.y, a * b.z); - return result; -} -api Vec3 &operator*=(Vec3 &a, Vec3 b) { - a = a * b; - return a; -} -api Vec3 &operator*=(Vec3 &a, F32 b) { - a = a * b; - return a; -} -api Vec3 operator/(Vec3 a, Vec3 b) { - Vec3 result = vec3(a.x / b.x, a.y / b.y, a.z / b.z); - return result; -} -api Vec3 operator/(Vec3 a, F32 b) { - Vec3 result = vec3(a.x / b, a.y / b, a.z / b); - return result; -} -api Vec3 operator/(F32 a, Vec3 b) { - Vec3 result = vec3(a / b.x, a / b.y, a / b.z); - return result; -} -api Vec3 &operator/=(Vec3 &a, Vec3 b) { - a = a / b; - return a; -} -api Vec3 &operator/=(Vec3 &a, F32 b) { - a = a / b; - return a; -} -api B32 operator!=(Vec3 a, Vec3 b) { - B32 result = (a.x != b.x) || (a.y != b.y) || (a.z != b.z); - return result; -} -api B32 operator==(Vec3 a, Vec3 b) { - B32 result = (a.x == b.x) && (a.y == b.y) && (a.z == b.z); - return result; -} -api Vec3 operator-(Vec3 a) { - Vec3 result = vec3(-a.x, -a.y, -a.z); - return result; -} -api Vec3 clamp(Vec3 min, Vec3 val, Vec3 max) { - Vec3 result = vec3(clamp(min.x, val.x, max.x), clamp(min.y, val.y, max.y), clamp(min.z, val.z, max.z)); - return result; -} -api Vec3 clamp(F32 min, Vec3 val, F32 max) { - Vec3 result = vec3(clamp(min, val.x, max), clamp(min, val.y, max), clamp(min, val.z, max)); - return result; -} -api Vec3 clamp01(Vec3 val) { - Vec3 result = vec3(clamp01(val.x), clamp01(val.y), clamp01(val.z)); - return result; -} -api Vec3 ceil(Vec3 a) { - Vec3 result = vec3(ceil(a.x), ceil(a.y), ceil(a.z)); - return result; -} -api Vec3 floor(Vec3 a) { - Vec3 result = vec3(floor(a.x), floor(a.y), floor(a.z)); - return result; -} -api Vec3 round(Vec3 a) { - Vec3 result = vec3(round(a.x), round(a.y), round(a.z)); - return result; -} -api Vec3 absolute(Vec3 a) { - Vec3 result = vec3(absolute(a.x), absolute(a.y), absolute(a.z)); - return result; -} -api Vec3 sign(Vec3 a) { - Vec3 result = vec3(sign(a.x), sign(a.y), sign(a.z)); - return result; -} -api Vec3 fraction(Vec3 a) { - Vec3 result = vec3(fraction(a.x), fraction(a.y), fraction(a.z)); - return result; -} -api Vec3 square(Vec3 a) { - Vec3 result = vec3(square(a.x), square(a.y), square(a.z)); - return result; -} -api Vec3 square_root(Vec3 a) { - Vec3 result = vec3(square_root(a.x), square_root(a.y), square_root(a.z)); - return result; -} -api F32 dot(Vec3 a, Vec3 b) { - F32 result = a.x * b.x + a.y * b.y + a.z * b.z; - return result; -} -api F32 length_squared(Vec3 a) { - F32 result = dot(a, a); - return result; -} -api F32 length(Vec3 a) { - F32 result = square_root(length_squared(a)); - return result; -} -api Vec3 lerp(Vec3 from, Vec3 to, F32 t) { - Vec3 result = (1 - t) * from + to * t; - return result; -} -api Vec4 vec4(F32 x, F32 y, F32 z, F32 w) { - Vec4 result; - result.x = x; - result.y = y; - result.z = z; - result.w = w; - return result; -} -api Vec4 vec4() { return vec4(0, 0, 0, 0); } -api Vec4 operator+(Vec4 a, Vec4 b) { - Vec4 result = vec4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w); - return result; -} -api Vec4 operator+(Vec4 a, F32 b) { - Vec4 result = vec4(a.x + b, a.y + b, a.z + b, a.w + b); - return result; -} -api Vec4 operator+(F32 a, Vec4 b) { - Vec4 result = vec4(a + b.x, a + b.y, a + b.z, a + b.w); - return result; -} -api Vec4 &operator+=(Vec4 &a, Vec4 b) { - a = a + b; - return a; -} -api Vec4 &operator+=(Vec4 &a, F32 b) { - a = a + b; - return a; -} -api Vec4 operator-(Vec4 a, Vec4 b) { - Vec4 result = vec4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w); - return result; -} -api Vec4 operator-(Vec4 a, F32 b) { - Vec4 result = vec4(a.x - b, a.y - b, a.z - b, a.w - b); - return result; -} -api Vec4 operator-(F32 a, Vec4 b) { - Vec4 result = vec4(a - b.x, a - b.y, a - b.z, a - b.w); - return result; -} -api Vec4 &operator-=(Vec4 &a, Vec4 b) { - a = a - b; - return a; -} -api Vec4 &operator-=(Vec4 &a, F32 b) { - a = a - b; - return a; -} -api Vec4 operator*(Vec4 a, Vec4 b) { - Vec4 result = vec4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w); - return result; -} -api Vec4 operator*(Vec4 a, F32 b) { - Vec4 result = vec4(a.x * b, a.y * b, a.z * b, a.w * b); - return result; -} -api Vec4 operator*(F32 a, Vec4 b) { - Vec4 result = vec4(a * b.x, a * b.y, a * b.z, a * b.w); - return result; -} -api Vec4 &operator*=(Vec4 &a, Vec4 b) { - a = a * b; - return a; -} -api Vec4 &operator*=(Vec4 &a, F32 b) { - a = a * b; - return a; -} -api Vec4 operator/(Vec4 a, Vec4 b) { - Vec4 result = vec4(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w); - return result; -} -api Vec4 operator/(Vec4 a, F32 b) { - Vec4 result = vec4(a.x / b, a.y / b, a.z / b, a.w / b); - return result; -} -api Vec4 operator/(F32 a, Vec4 b) { - Vec4 result = vec4(a / b.x, a / b.y, a / b.z, a / b.w); - return result; -} -api Vec4 &operator/=(Vec4 &a, Vec4 b) { - a = a / b; - return a; -} -api Vec4 &operator/=(Vec4 &a, F32 b) { - a = a / b; - return a; -} -api B32 operator!=(Vec4 a, Vec4 b) { - B32 result = (a.x != b.x) || (a.y != b.y) || (a.z != b.z) || (a.w != b.w); - return result; -} -api B32 operator==(Vec4 a, Vec4 b) { - B32 result = (a.x == b.x) && (a.y == b.y) && (a.z == b.z) && (a.w == b.w); - return result; -} -api Vec4 operator-(Vec4 a) { - Vec4 result = vec4(-a.x, -a.y, -a.z, -a.w); - return result; -} -api Vec4 clamp(Vec4 min, Vec4 val, Vec4 max) { - Vec4 result = vec4(clamp(min.x, val.x, max.x), clamp(min.y, val.y, max.y), clamp(min.z, val.z, max.z), - clamp(min.w, val.w, max.w)); - return result; -} -api Vec4 clamp(F32 min, Vec4 val, F32 max) { - Vec4 result = - vec4(clamp(min, val.x, max), clamp(min, val.y, max), clamp(min, val.z, max), clamp(min, val.w, max)); - return result; -} -api Vec4 clamp01(Vec4 val) { - Vec4 result = vec4(clamp01(val.x), clamp01(val.y), clamp01(val.z), clamp01(val.w)); - return result; -} -api Vec4 ceil(Vec4 a) { - Vec4 result = vec4(ceil(a.x), ceil(a.y), ceil(a.z), ceil(a.w)); - return result; -} -api Vec4 floor(Vec4 a) { - Vec4 result = vec4(floor(a.x), floor(a.y), floor(a.z), floor(a.w)); - return result; -} -api Vec4 round(Vec4 a) { - Vec4 result = vec4(round(a.x), round(a.y), round(a.z), round(a.w)); - return result; -} -api Vec4 absolute(Vec4 a) { - Vec4 result = vec4(absolute(a.x), absolute(a.y), absolute(a.z), absolute(a.w)); - return result; -} -api Vec4 sign(Vec4 a) { - Vec4 result = vec4(sign(a.x), sign(a.y), sign(a.z), sign(a.w)); - return result; -} -api Vec4 fraction(Vec4 a) { - Vec4 result = vec4(fraction(a.x), fraction(a.y), fraction(a.z), fraction(a.w)); - return result; -} -api Vec4 square(Vec4 a) { - Vec4 result = vec4(square(a.x), square(a.y), square(a.z), square(a.w)); - return result; -} -api Vec4 square_root(Vec4 a) { - Vec4 result = vec4(square_root(a.x), square_root(a.y), square_root(a.z), square_root(a.w)); - return result; -} -api F32 dot(Vec4 a, Vec4 b) { - F32 result = a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; - return result; -} -api F32 length_squared(Vec4 a) { - F32 result = dot(a, a); - return result; -} -api F32 length(Vec4 a) { - F32 result = square_root(length_squared(a)); - return result; -} -api Vec4 lerp(Vec4 from, Vec4 to, F32 t) { - Vec4 result = (1 - t) * from + to * t; - return result; -} -api Vec2I vec2i(S32 x, S32 y) { - Vec2I result; - result.x = x; - result.y = y; - return result; -} -api Vec2I vec2i() { return vec2i(0, 0); } -api Vec2I operator+(Vec2I a, Vec2I b) { - Vec2I result = vec2i(a.x + b.x, a.y + b.y); - return result; -} -api Vec2I operator+(Vec2I a, S32 b) { - Vec2I result = vec2i(a.x + b, a.y + b); - return result; -} -api Vec2I operator+(S32 a, Vec2I b) { - Vec2I result = vec2i(a + b.x, a + b.y); - return result; -} -api Vec2I &operator+=(Vec2I &a, Vec2I b) { - a = a + b; - return a; -} -api Vec2I &operator+=(Vec2I &a, S32 b) { - a = a + b; - return a; -} -api Vec2I operator-(Vec2I a, Vec2I b) { - Vec2I result = vec2i(a.x - b.x, a.y - b.y); - return result; -} -api Vec2I operator-(Vec2I a, S32 b) { - Vec2I result = vec2i(a.x - b, a.y - b); - return result; -} -api Vec2I operator-(S32 a, Vec2I b) { - Vec2I result = vec2i(a - b.x, a - b.y); - return result; -} -api Vec2I &operator-=(Vec2I &a, Vec2I b) { - a = a - b; - return a; -} -api Vec2I &operator-=(Vec2I &a, S32 b) { - a = a - b; - return a; -} -api Vec2I operator*(Vec2I a, Vec2I b) { - Vec2I result = vec2i(a.x * b.x, a.y * b.y); - return result; -} -api Vec2I operator*(Vec2I a, S32 b) { - Vec2I result = vec2i(a.x * b, a.y * b); - return result; -} -api Vec2I operator*(S32 a, Vec2I b) { - Vec2I result = vec2i(a * b.x, a * b.y); - return result; -} -api Vec2I &operator*=(Vec2I &a, Vec2I b) { - a = a * b; - return a; -} -api Vec2I &operator*=(Vec2I &a, S32 b) { - a = a * b; - return a; -} -api Vec2I operator/(Vec2I a, Vec2I b) { - Vec2I result = vec2i(a.x / b.x, a.y / b.y); - return result; -} -api Vec2I operator/(Vec2I a, S32 b) { - Vec2I result = vec2i(a.x / b, a.y / b); - return result; -} -api Vec2I operator/(S32 a, Vec2I b) { - Vec2I result = vec2i(a / b.x, a / b.y); - return result; -} -api Vec2I &operator/=(Vec2I &a, Vec2I b) { - a = a / b; - return a; -} -api Vec2I &operator/=(Vec2I &a, S32 b) { - a = a / b; - return a; -} -api B32 operator!=(Vec2I a, Vec2I b) { - B32 result = (a.x != b.x) || (a.y != b.y); - return result; -} -api B32 operator==(Vec2I a, Vec2I b) { - B32 result = (a.x == b.x) && (a.y == b.y); - return result; -} -api Vec2I operator-(Vec2I a) { - Vec2I result = vec2i(-a.x, -a.y); - return result; -} -api Vec2I clamp(Vec2I min, Vec2I val, Vec2I max) { - Vec2I result = vec2i(clamp(min.x, val.x, max.x), clamp(min.y, val.y, max.y)); - return result; -} -api Vec2I clamp(S32 min, Vec2I val, S32 max) { - Vec2I result = vec2i(clamp(min, val.x, max), clamp(min, val.y, max)); - return result; -} -api Vec2I clamp01(Vec2I val) { - Vec2I result = vec2i(clamp01(val.x), clamp01(val.y)); - return result; -} -api Vec3I vec3i(S32 x, S32 y, S32 z) { - Vec3I result; - result.x = x; - result.y = y; - result.z = z; - return result; -} -api Vec3I vec3i() { return vec3i(0, 0, 0); } -api Vec3I operator+(Vec3I a, Vec3I b) { - Vec3I result = vec3i(a.x + b.x, a.y + b.y, a.z + b.z); - return result; -} -api Vec3I operator+(Vec3I a, S32 b) { - Vec3I result = vec3i(a.x + b, a.y + b, a.z + b); - return result; -} -api Vec3I operator+(S32 a, Vec3I b) { - Vec3I result = vec3i(a + b.x, a + b.y, a + b.z); - return result; -} -api Vec3I &operator+=(Vec3I &a, Vec3I b) { - a = a + b; - return a; -} -api Vec3I &operator+=(Vec3I &a, S32 b) { - a = a + b; - return a; -} -api Vec3I operator-(Vec3I a, Vec3I b) { - Vec3I result = vec3i(a.x - b.x, a.y - b.y, a.z - b.z); - return result; -} -api Vec3I operator-(Vec3I a, S32 b) { - Vec3I result = vec3i(a.x - b, a.y - b, a.z - b); - return result; -} -api Vec3I operator-(S32 a, Vec3I b) { - Vec3I result = vec3i(a - b.x, a - b.y, a - b.z); - return result; -} -api Vec3I &operator-=(Vec3I &a, Vec3I b) { - a = a - b; - return a; -} -api Vec3I &operator-=(Vec3I &a, S32 b) { - a = a - b; - return a; -} -api Vec3I operator*(Vec3I a, Vec3I b) { - Vec3I result = vec3i(a.x * b.x, a.y * b.y, a.z * b.z); - return result; -} -api Vec3I operator*(Vec3I a, S32 b) { - Vec3I result = vec3i(a.x * b, a.y * b, a.z * b); - return result; -} -api Vec3I operator*(S32 a, Vec3I b) { - Vec3I result = vec3i(a * b.x, a * b.y, a * b.z); - return result; -} -api Vec3I &operator*=(Vec3I &a, Vec3I b) { - a = a * b; - return a; -} -api Vec3I &operator*=(Vec3I &a, S32 b) { - a = a * b; - return a; -} -api Vec3I operator/(Vec3I a, Vec3I b) { - Vec3I result = vec3i(a.x / b.x, a.y / b.y, a.z / b.z); - return result; -} -api Vec3I operator/(Vec3I a, S32 b) { - Vec3I result = vec3i(a.x / b, a.y / b, a.z / b); - return result; -} -api Vec3I operator/(S32 a, Vec3I b) { - Vec3I result = vec3i(a / b.x, a / b.y, a / b.z); - return result; -} -api Vec3I &operator/=(Vec3I &a, Vec3I b) { - a = a / b; - return a; -} -api Vec3I &operator/=(Vec3I &a, S32 b) { - a = a / b; - return a; -} -api B32 operator!=(Vec3I a, Vec3I b) { - B32 result = (a.x != b.x) || (a.y != b.y) || (a.z != b.z); - return result; -} -api B32 operator==(Vec3I a, Vec3I b) { - B32 result = (a.x == b.x) && (a.y == b.y) && (a.z == b.z); - return result; -} -api Vec3I operator-(Vec3I a) { - Vec3I result = vec3i(-a.x, -a.y, -a.z); - return result; -} -api Vec3I clamp(Vec3I min, Vec3I val, Vec3I max) { - Vec3I result = vec3i(clamp(min.x, val.x, max.x), clamp(min.y, val.y, max.y), clamp(min.z, val.z, max.z)); - return result; -} -api Vec3I clamp(S32 min, Vec3I val, S32 max) { - Vec3I result = vec3i(clamp(min, val.x, max), clamp(min, val.y, max), clamp(min, val.z, max)); - return result; -} -api Vec3I clamp01(Vec3I val) { - Vec3I result = vec3i(clamp01(val.x), clamp01(val.y), clamp01(val.z)); - return result; -} -api Vec4I v4i(S32 x, S32 y, S32 z, S32 w) { - Vec4I result; - result.x = x; - result.y = y; - result.z = z; - result.w = w; - return result; -} -api Vec4I v4i() { return v4i(0, 0, 0, 0); } -api Vec4I operator+(Vec4I a, Vec4I b) { - Vec4I result = v4i(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w); - return result; -} -api Vec4I operator+(Vec4I a, S32 b) { - Vec4I result = v4i(a.x + b, a.y + b, a.z + b, a.w + b); - return result; -} -api Vec4I operator+(S32 a, Vec4I b) { - Vec4I result = v4i(a + b.x, a + b.y, a + b.z, a + b.w); - return result; -} -api Vec4I &operator+=(Vec4I &a, Vec4I b) { - a = a + b; - return a; -} -api Vec4I &operator+=(Vec4I &a, S32 b) { - a = a + b; - return a; -} -api Vec4I operator-(Vec4I a, Vec4I b) { - Vec4I result = v4i(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w); - return result; -} -api Vec4I operator-(Vec4I a, S32 b) { - Vec4I result = v4i(a.x - b, a.y - b, a.z - b, a.w - b); - return result; -} -api Vec4I operator-(S32 a, Vec4I b) { - Vec4I result = v4i(a - b.x, a - b.y, a - b.z, a - b.w); - return result; -} -api Vec4I &operator-=(Vec4I &a, Vec4I b) { - a = a - b; - return a; -} -api Vec4I &operator-=(Vec4I &a, S32 b) { - a = a - b; - return a; -} -api Vec4I operator*(Vec4I a, Vec4I b) { - Vec4I result = v4i(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w); - return result; -} -api Vec4I operator*(Vec4I a, S32 b) { - Vec4I result = v4i(a.x * b, a.y * b, a.z * b, a.w * b); - return result; -} -api Vec4I operator*(S32 a, Vec4I b) { - Vec4I result = v4i(a * b.x, a * b.y, a * b.z, a * b.w); - return result; -} -api Vec4I &operator*=(Vec4I &a, Vec4I b) { - a = a * b; - return a; -} -api Vec4I &operator*=(Vec4I &a, S32 b) { - a = a * b; - return a; -} -api Vec4I operator/(Vec4I a, Vec4I b) { - Vec4I result = v4i(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w); - return result; -} -api Vec4I operator/(Vec4I a, S32 b) { - Vec4I result = v4i(a.x / b, a.y / b, a.z / b, a.w / b); - return result; -} -api Vec4I operator/(S32 a, Vec4I b) { - Vec4I result = v4i(a / b.x, a / b.y, a / b.z, a / b.w); - return result; -} -api Vec4I &operator/=(Vec4I &a, Vec4I b) { - a = a / b; - return a; -} -api Vec4I &operator/=(Vec4I &a, S32 b) { - a = a / b; - return a; -} -api B32 operator!=(Vec4I a, Vec4I b) { - B32 result = (a.x != b.x) || (a.y != b.y) || (a.z != b.z) || (a.w != b.w); - return result; -} -api B32 operator==(Vec4I a, Vec4I b) { - B32 result = (a.x == b.x) && (a.y == b.y) && (a.z == b.z) && (a.w == b.w); - return result; -} -api Vec4I operator-(Vec4I a) { - Vec4I result = v4i(-a.x, -a.y, -a.z, -a.w); - return result; -} -api Vec4I clamp(Vec4I min, Vec4I val, Vec4I max) { - Vec4I result = v4i(clamp(min.x, val.x, max.x), clamp(min.y, val.y, max.y), clamp(min.z, val.z, max.z), - clamp(min.w, val.w, max.w)); - return result; -} -api Vec4I clamp(S32 min, Vec4I val, S32 max) { - Vec4I result = - v4i(clamp(min, val.x, max), clamp(min, val.y, max), clamp(min, val.z, max), clamp(min, val.w, max)); - return result; -} -api Vec4I clamp01(Vec4I val) { - Vec4I result = v4i(clamp01(val.x), clamp01(val.y), clamp01(val.z), clamp01(val.w)); - return result; -} -api Rect2 rect2(F32 min_x, F32 min_y, F32 max_x, F32 max_y) { - Rect2 result; - result.min_x = min_x; - result.min_y = min_y; - result.max_x = max_x; - result.max_y = max_y; - return result; -} -api Rect2 rect2() { return rect2(0, 0, 0, 0); } -api Rect2 operator+(Rect2 a, Rect2 b) { - Rect2 result = rect2(a.min_x + b.min_x, a.min_y + b.min_y, a.max_x + b.max_x, a.max_y + b.max_y); - return result; -} -api Rect2 operator+(Rect2 a, F32 b) { - Rect2 result = rect2(a.min_x + b, a.min_y + b, a.max_x + b, a.max_y + b); - return result; -} -api Rect2 operator+(F32 a, Rect2 b) { - Rect2 result = rect2(a + b.min_x, a + b.min_y, a + b.max_x, a + b.max_y); - return result; -} -api Rect2 &operator+=(Rect2 &a, Rect2 b) { - a = a + b; - return a; -} -api Rect2 &operator+=(Rect2 &a, F32 b) { - a = a + b; - return a; -} -api Rect2 operator-(Rect2 a, Rect2 b) { - Rect2 result = rect2(a.min_x - b.min_x, a.min_y - b.min_y, a.max_x - b.max_x, a.max_y - b.max_y); - return result; -} -api Rect2 operator-(Rect2 a, F32 b) { - Rect2 result = rect2(a.min_x - b, a.min_y - b, a.max_x - b, a.max_y - b); - return result; -} -api Rect2 operator-(F32 a, Rect2 b) { - Rect2 result = rect2(a - b.min_x, a - b.min_y, a - b.max_x, a - b.max_y); - return result; -} -api Rect2 &operator-=(Rect2 &a, Rect2 b) { - a = a - b; - return a; -} -api Rect2 &operator-=(Rect2 &a, F32 b) { - a = a - b; - return a; -} -api Rect2 operator*(Rect2 a, Rect2 b) { - Rect2 result = rect2(a.min_x * b.min_x, a.min_y * b.min_y, a.max_x * b.max_x, a.max_y * b.max_y); - return result; -} -api Rect2 operator*(Rect2 a, F32 b) { - Rect2 result = rect2(a.min_x * b, a.min_y * b, a.max_x * b, a.max_y * b); - return result; -} -api Rect2 operator*(F32 a, Rect2 b) { - Rect2 result = rect2(a * b.min_x, a * b.min_y, a * b.max_x, a * b.max_y); - return result; -} -api Rect2 &operator*=(Rect2 &a, Rect2 b) { - a = a * b; - return a; -} -api Rect2 &operator*=(Rect2 &a, F32 b) { - a = a * b; - return a; -} -api Rect2 operator/(Rect2 a, Rect2 b) { - Rect2 result = rect2(a.min_x / b.min_x, a.min_y / b.min_y, a.max_x / b.max_x, a.max_y / b.max_y); - return result; -} -api Rect2 operator/(Rect2 a, F32 b) { - Rect2 result = rect2(a.min_x / b, a.min_y / b, a.max_x / b, a.max_y / b); - return result; -} -api Rect2 operator/(F32 a, Rect2 b) { - Rect2 result = rect2(a / b.min_x, a / b.min_y, a / b.max_x, a / b.max_y); - return result; -} -api Rect2 &operator/=(Rect2 &a, Rect2 b) { - a = a / b; - return a; -} -api Rect2 &operator/=(Rect2 &a, F32 b) { - a = a / b; - return a; -} -api B32 operator!=(Rect2 a, Rect2 b) { - B32 result = (a.min_x != b.min_x) || (a.min_y != b.min_y) || (a.max_x != b.max_x) || (a.max_y != b.max_y); - return result; -} -api B32 operator==(Rect2 a, Rect2 b) { - B32 result = (a.min_x == b.min_x) && (a.min_y == b.min_y) && (a.max_x == b.max_x) && (a.max_y == b.max_y); - return result; -} -api Rect2 operator-(Rect2 a) { - Rect2 result = rect2(-a.min_x, -a.min_y, -a.max_x, -a.max_y); - return result; -} -api Rect2 clamp(Rect2 min, Rect2 val, Rect2 max) { - Rect2 result = rect2(clamp(min.min_x, val.min_x, max.min_x), clamp(min.min_y, val.min_y, max.min_y), - clamp(min.max_x, val.max_x, max.max_x), clamp(min.max_y, val.max_y, max.max_y)); - return result; -} -api Rect2 clamp(F32 min, Rect2 val, F32 max) { - Rect2 result = rect2(clamp(min, val.min_x, max), clamp(min, val.min_y, max), clamp(min, val.max_x, max), - clamp(min, val.max_y, max)); - return result; -} -api Rect2 clamp01(Rect2 val) { - Rect2 result = rect2(clamp01(val.min_x), clamp01(val.min_y), clamp01(val.max_x), clamp01(val.max_y)); - return result; -} -api Rect2I rect2i(S32 min_x, S32 min_y, S32 max_x, S32 max_y) { - Rect2I result; - result.min_x = min_x; - result.min_y = min_y; - result.max_x = max_x; - result.max_y = max_y; - return result; -} -api Rect2I rect2i() { return rect2i(0, 0, 0, 0); } -api Rect2I operator+(Rect2I a, Rect2I b) { - Rect2I result = rect2i(a.min_x + b.min_x, a.min_y + b.min_y, a.max_x + b.max_x, a.max_y + b.max_y); - return result; -} -api Rect2I operator+(Rect2I a, S32 b) { - Rect2I result = rect2i(a.min_x + b, a.min_y + b, a.max_x + b, a.max_y + b); - return result; -} -api Rect2I operator+(S32 a, Rect2I b) { - Rect2I result = rect2i(a + b.min_x, a + b.min_y, a + b.max_x, a + b.max_y); - return result; -} -api Rect2I &operator+=(Rect2I &a, Rect2I b) { - a = a + b; - return a; -} -api Rect2I &operator+=(Rect2I &a, S32 b) { - a = a + b; - return a; -} -api Rect2I operator-(Rect2I a, Rect2I b) { - Rect2I result = rect2i(a.min_x - b.min_x, a.min_y - b.min_y, a.max_x - b.max_x, a.max_y - b.max_y); - return result; -} -api Rect2I operator-(Rect2I a, S32 b) { - Rect2I result = rect2i(a.min_x - b, a.min_y - b, a.max_x - b, a.max_y - b); - return result; -} -api Rect2I operator-(S32 a, Rect2I b) { - Rect2I result = rect2i(a - b.min_x, a - b.min_y, a - b.max_x, a - b.max_y); - return result; -} -api Rect2I &operator-=(Rect2I &a, Rect2I b) { - a = a - b; - return a; -} -api Rect2I &operator-=(Rect2I &a, S32 b) { - a = a - b; - return a; -} -api Rect2I operator*(Rect2I a, Rect2I b) { - Rect2I result = rect2i(a.min_x * b.min_x, a.min_y * b.min_y, a.max_x * b.max_x, a.max_y * b.max_y); - return result; -} -api Rect2I operator*(Rect2I a, S32 b) { - Rect2I result = rect2i(a.min_x * b, a.min_y * b, a.max_x * b, a.max_y * b); - return result; -} -api Rect2I operator*(S32 a, Rect2I b) { - Rect2I result = rect2i(a * b.min_x, a * b.min_y, a * b.max_x, a * b.max_y); - return result; -} -api Rect2I &operator*=(Rect2I &a, Rect2I b) { - a = a * b; - return a; -} -api Rect2I &operator*=(Rect2I &a, S32 b) { - a = a * b; - return a; -} -api Rect2I operator/(Rect2I a, Rect2I b) { - Rect2I result = rect2i(a.min_x / b.min_x, a.min_y / b.min_y, a.max_x / b.max_x, a.max_y / b.max_y); - return result; -} -api Rect2I operator/(Rect2I a, S32 b) { - Rect2I result = rect2i(a.min_x / b, a.min_y / b, a.max_x / b, a.max_y / b); - return result; -} -api Rect2I operator/(S32 a, Rect2I b) { - Rect2I result = rect2i(a / b.min_x, a / b.min_y, a / b.max_x, a / b.max_y); - return result; -} -api Rect2I &operator/=(Rect2I &a, Rect2I b) { - a = a / b; - return a; -} -api Rect2I &operator/=(Rect2I &a, S32 b) { - a = a / b; - return a; -} -api B32 operator!=(Rect2I a, Rect2I b) { - B32 result = (a.min_x != b.min_x) || (a.min_y != b.min_y) || (a.max_x != b.max_x) || (a.max_y != b.max_y); - return result; -} -api B32 operator==(Rect2I a, Rect2I b) { - B32 result = (a.min_x == b.min_x) && (a.min_y == b.min_y) && (a.max_x == b.max_x) && (a.max_y == b.max_y); - return result; -} -api Rect2I operator-(Rect2I a) { - Rect2I result = rect2i(-a.min_x, -a.min_y, -a.max_x, -a.max_y); - return result; -} -api Rect2I clamp(Rect2I min, Rect2I val, Rect2I max) { - Rect2I result = rect2i(clamp(min.min_x, val.min_x, max.min_x), clamp(min.min_y, val.min_y, max.min_y), - clamp(min.max_x, val.max_x, max.max_x), clamp(min.max_y, val.max_y, max.max_y)); - return result; -} -api Rect2I clamp(S32 min, Rect2I val, S32 max) { - Rect2I result = rect2i(clamp(min, val.min_x, max), clamp(min, val.min_y, max), clamp(min, val.max_x, max), - clamp(min, val.max_y, max)); - return result; -} -api Rect2I clamp01(Rect2I val) { - Rect2I result = rect2i(clamp01(val.min_x), clamp01(val.min_y), clamp01(val.max_x), clamp01(val.max_y)); - return result; -} -api Vec2 cast_v2(Vec2I a) { - Vec2 result = vec2((F32)(a.x), (F32)(a.y)); - return result; -} -api Vec2I cast_v2i(Vec2 a) { - Vec2I result = vec2i((S32)(a.x), (S32)(a.y)); - return result; -} -api Vec2I round_cast_v2i(Vec2 a) { - Vec2I result = vec2i((S32)round(a.x), (S32)round(a.y)); - return result; -} -api Vec2I ceil_cast_v2i(Vec2 a) { - Vec2I result = vec2i((S32)ceil(a.x), (S32)ceil(a.y)); - return result; -} -api Vec2I floor_cast_v2i(Vec2 a) { - Vec2I result = vec2i((S32)floor(a.x), (S32)floor(a.y)); - return result; -} -api Vec3 cast_v3(Vec3I a) { - Vec3 result = vec3((F32)(a.x), (F32)(a.y), (F32)(a.z)); - return result; -} -api Vec3I cast_v3i(Vec3 a) { - Vec3I result = vec3i((S32)(a.x), (S32)(a.y), (S32)(a.z)); - return result; -} -api Vec3I round_cast_v3i(Vec3 a) { - Vec3I result = vec3i((S32)round(a.x), (S32)round(a.y), (S32)round(a.z)); - return result; -} -api Vec3I ceil_cast_v3i(Vec3 a) { - Vec3I result = vec3i((S32)ceil(a.x), (S32)ceil(a.y), (S32)ceil(a.z)); - return result; -} -api Vec3I floor_cast_v3i(Vec3 a) { - Vec3I result = vec3i((S32)floor(a.x), (S32)floor(a.y), (S32)floor(a.z)); - return result; -} -api Vec4 cast_v4(Vec4I a) { - Vec4 result = vec4((F32)(a.x), (F32)(a.y), (F32)(a.z), (F32)(a.w)); - return result; -} -api Vec4I cast_v4i(Vec4 a) { - Vec4I result = v4i((S32)(a.x), (S32)(a.y), (S32)(a.z), (S32)(a.w)); - return result; -} -api Vec4I round_cast_v4i(Vec4 a) { - Vec4I result = v4i((S32)round(a.x), (S32)round(a.y), (S32)round(a.z), (S32)round(a.w)); - return result; -} -api Vec4I ceil_cast_v4i(Vec4 a) { - Vec4I result = v4i((S32)ceil(a.x), (S32)ceil(a.y), (S32)ceil(a.z), (S32)ceil(a.w)); - return result; -} -api Vec4I floor_cast_v4i(Vec4 a) { - Vec4I result = v4i((S32)floor(a.x), (S32)floor(a.y), (S32)floor(a.z), (S32)floor(a.w)); - return result; -} -api Rect2 cast_rect2(Rect2I a) { - Rect2 result = rect2((F32)(a.min_x), (F32)(a.min_y), (F32)(a.max_x), (F32)(a.max_y)); - return result; -} -api Rect2I cast_rect2i(Rect2 a) { - Rect2I result = rect2i((S32)(a.min_x), (S32)(a.min_y), (S32)(a.max_x), (S32)(a.max_y)); - return result; -} -api Rect2I round_cast_rect2i(Rect2 a) { - Rect2I result = rect2i((S32)round(a.min_x), (S32)round(a.min_y), (S32)round(a.max_x), (S32)round(a.max_y)); - return result; -} -api Rect2I ceil_cast_rect2i(Rect2 a) { - Rect2I result = rect2i((S32)ceil(a.min_x), (S32)ceil(a.min_y), (S32)ceil(a.max_x), (S32)ceil(a.max_y)); - return result; -} -api Rect2I floor_cast_rect2i(Rect2 a) { - Rect2I result = rect2i((S32)floor(a.min_x), (S32)floor(a.min_y), (S32)floor(a.max_x), (S32)floor(a.max_y)); - return result; -} -api Rect2I rect2i(Vec2I a, Vec2I b) { - Rect2I result = rect2i(a.p[0], a.p[1], b.p[0], b.p[1]); - return result; -} -api Rect2I rect2i(S32 a, Vec3I b) { - Rect2I result = rect2i(a, b.p[0], b.p[1], b.p[2]); - return result; -} -api Rect2I rect2i(Vec3I a, S32 b) { - Rect2I result = rect2i(a.p[0], a.p[1], a.p[2], b); - return result; -} -api Rect2I rect2i(Vec2I a, S32 b, S32 c) { - Rect2I result = rect2i(a.p[0], a.p[1], b, c); - return result; -} -api Rect2I rect2i(S32 a, S32 b, Vec2I c) { - Rect2I result = rect2i(a, b, c.p[0], c.p[1]); - return result; -} -api Vec4I v4i(Vec2I a, Vec2I b) { - Vec4I result = v4i(a.p[0], a.p[1], b.p[0], b.p[1]); - return result; -} -api Vec4I v4i(S32 a, Vec3I b) { - Vec4I result = v4i(a, b.p[0], b.p[1], b.p[2]); - return result; -} -api Vec4I v4i(Vec3I a, S32 b) { - Vec4I result = v4i(a.p[0], a.p[1], a.p[2], b); - return result; -} -api Vec4I v4i(Vec2I a, S32 b, S32 c) { - Vec4I result = v4i(a.p[0], a.p[1], b, c); - return result; -} -api Vec4I v4i(S32 a, S32 b, Vec2I c) { - Vec4I result = v4i(a, b, c.p[0], c.p[1]); - return result; -} -api Rect2 rect2(Vec2 a, Vec2 b) { - Rect2 result = rect2(a.p[0], a.p[1], b.p[0], b.p[1]); - return result; -} -api Rect2 rect2(F32 a, Vec3 b) { - Rect2 result = rect2(a, b.p[0], b.p[1], b.p[2]); - return result; -} -api Rect2 rect2(Vec3 a, F32 b) { - Rect2 result = rect2(a.p[0], a.p[1], a.p[2], b); - return result; -} -api Rect2 rect2(Vec2 a, F32 b, F32 c) { - Rect2 result = rect2(a.p[0], a.p[1], b, c); - return result; -} -api Rect2 rect2(F32 a, F32 b, Vec2 c) { - Rect2 result = rect2(a, b, c.p[0], c.p[1]); - return result; -} -api Vec4 vec4(Vec2 a, Vec2 b) { - Vec4 result = vec4(a.p[0], a.p[1], b.p[0], b.p[1]); - return result; -} -api Vec4 vec4(F32 a, Vec3 b) { - Vec4 result = vec4(a, b.p[0], b.p[1], b.p[2]); - return result; -} -api Vec4 vec4(Vec3 a, F32 b) { - Vec4 result = vec4(a.p[0], a.p[1], a.p[2], b); - return result; -} -api Vec4 vec4(Vec2 a, F32 b, F32 c) { - Vec4 result = vec4(a.p[0], a.p[1], b, c); - return result; -} -api Vec4 vec4(F32 a, F32 b, Vec2 c) { - Vec4 result = vec4(a, b, c.p[0], c.p[1]); - return result; -} -api Rect2 rect2_min_size(Vec2 a, Vec2 b) { - Rect2 result = rect2(a.p[0], a.p[1], b.p[0], b.p[1]); - result.max += result.min; - return result; -} -api Rect2 rect2_min_size(F32 a, Vec3 b) { - Rect2 result = rect2(a, b.p[0], b.p[1], b.p[2]); - result.max += result.min; - return result; -} -api Rect2 rect2_min_size(Vec3 a, F32 b) { - Rect2 result = rect2(a.p[0], a.p[1], a.p[2], b); - result.max += result.min; - return result; -} -api Rect2 rect2_min_size(Vec2 a, F32 b, F32 c) { - Rect2 result = rect2(a.p[0], a.p[1], b, c); - result.max += result.min; - return result; -} -api Rect2 rect2_min_size(F32 a, F32 b, Vec2 c) { - Rect2 result = rect2(a, b, c.p[0], c.p[1]); - result.max += result.min; - return result; -} -api Rect2I rect2i_min_size(Vec2I a, Vec2I b) { - Rect2I result = rect2i(a.p[0], a.p[1], b.p[0], b.p[1]); - result.max += result.min; - return result; -} -api Rect2I rect2i_min_size(S32 a, Vec3I b) { - Rect2I result = rect2i(a, b.p[0], b.p[1], b.p[2]); - result.max += result.min; - return result; -} -api Rect2I rect2i_min_size(Vec3I a, S32 b) { - Rect2I result = rect2i(a.p[0], a.p[1], a.p[2], b); - result.max += result.min; - return result; -} -api Rect2I rect2i_min_size(Vec2I a, S32 b, S32 c) { - Rect2I result = rect2i(a.p[0], a.p[1], b, c); - result.max += result.min; - return result; -} -api Rect2I rect2i_min_size(S32 a, S32 b, Vec2I c) { - Rect2I result = rect2i(a, b, c.p[0], c.p[1]); - result.max += result.min; - return result; -} -api Rect2 rect2_center_half_dim(Vec2 a, Vec2 b) { - Rect2 result = rect2(a.p[0], a.p[1], b.p[0], b.p[1]); - Vec2 center = result.min; - result.min -= result.max; - result.max += center; - return result; -} -api Rect2 rect2_center_half_dim(F32 a, Vec3 b) { - Rect2 result = rect2(a, b.p[0], b.p[1], b.p[2]); - Vec2 center = result.min; - result.min -= result.max; - result.max += center; - return result; -} -api Rect2 rect2_center_half_dim(Vec3 a, F32 b) { - Rect2 result = rect2(a.p[0], a.p[1], a.p[2], b); - Vec2 center = result.min; - result.min -= result.max; - result.max += center; - return result; -} -api Rect2 rect2_center_half_dim(Vec2 a, F32 b, F32 c) { - Rect2 result = rect2(a.p[0], a.p[1], b, c); - Vec2 center = result.min; - result.min -= result.max; - result.max += center; - return result; -} -api Rect2 rect2_center_half_dim(F32 a, F32 b, Vec2 c) { - Rect2 result = rect2(a, b, c.p[0], c.p[1]); - Vec2 center = result.min; - result.min -= result.max; - result.max += center; - return result; -} -api Rect2I rect2i_center_half_dim(Vec2I a, Vec2I b) { - Rect2I result = rect2i(a.p[0], a.p[1], b.p[0], b.p[1]); - Vec2I center = result.min; - result.min -= result.max; - result.max += center; - return result; -} -api Rect2I rect2i_center_half_dim(S32 a, Vec3I b) { - Rect2I result = rect2i(a, b.p[0], b.p[1], b.p[2]); - Vec2I center = result.min; - result.min -= result.max; - result.max += center; - return result; -} -api Rect2I rect2i_center_half_dim(Vec3I a, S32 b) { - Rect2I result = rect2i(a.p[0], a.p[1], a.p[2], b); - Vec2I center = result.min; - result.min -= result.max; - result.max += center; - return result; -} -api Rect2I rect2i_center_half_dim(Vec2I a, S32 b, S32 c) { - Rect2I result = rect2i(a.p[0], a.p[1], b, c); - Vec2I center = result.min; - result.min -= result.max; - result.max += center; - return result; -} -api Rect2I rect2i_center_half_dim(S32 a, S32 b, Vec2I c) { - Rect2I result = rect2i(a, b, c.p[0], c.p[1]); - Vec2I center = result.min; - result.min -= result.max; - result.max += center; - return result; -} -api Rect2 rect2_min_size(F32 a, F32 b, F32 c, F32 d) { - Rect2 result = rect2(a, b, c, d); - result.max += result.min; - return result; -} -api Rect2I rect2i_min_size(S32 a, S32 b, S32 c, S32 d) { - Rect2I result = rect2i(a, b, c, d); - result.max += result.min; - return result; -} -api Rect2 rect2_center_half_dim(F32 a, F32 b, F32 c, F32 d) { - Rect2 result = rect2(a, b, c, d); - Vec2 center = result.min; - result.min -= result.max; - result.max += center; - return result; -} -api Rect2I rect2i_center_half_dim(S32 a, S32 b, S32 c, S32 d) { - Rect2I result = rect2i(a, b, c, d); - Vec2I center = result.min; - result.min -= result.max; - result.max += center; - return result; -} -api Vec3 vec3(F32 a, Vec2 b) { - Vec3 result = vec3(a, b.p[0], b.p[1]); - return result; -} -api Vec3 vec3(Vec2 a, F32 b) { - Vec3 result = vec3(a.p[0], a.p[1], b); - return result; -} -api Vec3I vec3i(S32 a, Vec2I b) { - Vec3I result = vec3i(a, b.p[0], b.p[1]); - return result; -} -api Vec3I vec3i(Vec2I a, S32 b) { - Vec3I result = vec3i(a.p[0], a.p[1], b); - return result; -} - -api Rect2I intersect(Rect2I a, Rect2I clip) { - Rect2I result; - result.min.x = max(a.min.x, clip.min.x); - result.min.y = max(a.min.y, clip.min.y); - result.max.x = min(a.max.x, clip.max.x); - result.max.y = min(a.max.y, clip.max.y); - return result; -} - -api B32 has_area(Rect2I a) { - B32 result = (a.max_x - a.min_x > 0) && (a.max_y - a.min_y > 0); - return result; -} - -api Rect2 intersect(Rect2 a, Rect2 clip) { - Rect2 result; - result.min.x = max(a.min.x, clip.min.x); - result.min.y = max(a.min.y, clip.min.y); - result.max.x = min(a.max.x, clip.max.x); - result.max.y = min(a.max.y, clip.max.y); - return result; -} - -api B32 has_area(Rect2 a) { - B32 result = (a.max_x - a.min_x > 0) && (a.max_y - a.min_y > 0); - return result; -} - -api Vec2 perp(Vec2 a) { - Vec2 result = vec2(-a.y, a.x); - return result; -} - -api Vec4 vec4argb(U32 v) { - U8 a = (v >> 24) & 0x000000ff; - U8 r = (v >> 16) & 0x000000ff; - U8 g = (v >> 8) & 0x000000ff; - U8 b = (v >> 0) & 0x000000ff; - Vec4 result = vec4((F32)r / 255.f, (F32)g / 255.f, (F32)b / 255.f, (F32)a / 255.f); - return result; -} - -api Vec4 vec4abgr(U32 c) { - float a = ((c & 0xff000000) >> 24) / 255.f; - float b = ((c & 0x00ff0000) >> 16) / 255.f; - float g = ((c & 0x0000ff00) >> 8) / 255.f; - float r = ((c & 0x000000ff) >> 0) / 255.f; - Vec4 result = vec4(r, g, b, a); - return result; -} - -api U32 vec4_to_u32argb(Vec4 c) { - U32 result = (U32)((U8)(c.a * 255.f) << 24u | (U8)(c.r * 255.f) << 16u | (U8)(c.g * 255.f) << 8u | - (U8)(c.b * 255.f) << 0u); - return result; -} - -api U32 vec4_to_u32abgr(Vec4 color) { - U8 red = (U8)(color.r * 255); - U8 green = (U8)(color.g * 255); - U8 blue = (U8)(color.b * 255); - U8 alpha = (U8)(color.a * 255); - U32 result = (U32)(alpha << 24 | blue << 16 | green << 8 | red << 0); - return result; -} - -api Mat4 operator*(Mat4 a, Mat4 b) { - Mat4 result; - for (int y = 0; y < 4; y++) { - for (int x = 0; x < 4; x++) { - result.p[y][x] = - a.p[y][0] * b.p[0][x] + a.p[y][1] * b.p[1][x] + a.p[y][2] * b.p[2][x] + a.p[y][3] * b.p[3][x]; - } - } - return result; -} - -api Vec4 operator*(Mat4 a, Vec4 b) { - Vec4 result; - for (int y = 0; y < 4; y++) { - result.p[y] = a.p[y][0] * b.p[0] + a.p[y][1] * b.p[1] + a.p[y][2] * b.p[2] + a.p[y][3] * b.p[3]; - } - return result; -} - -api Vec3 operator*(Mat4 a, Vec3 b) { - Vec4 result; - for (int y = 0; y < 4; y++) - result.p[y] = a.p[y][0] * b.p[0] + a.p[y][1] * b.p[1] + a.p[y][2] * b.p[2] + a.p[y][3] * 1; - return result.xyz; -} - -api Vec3 cross(Vec3 a, Vec3 b) { - Vec3 result; - result.x = a.y * b.z - a.z * b.y; - result.y = a.z * b.x - a.x * b.z; - result.z = a.x * b.y - a.y * b.x; - return result; -} - -api Vec2 normalize(Vec2 a) { - Vec2 result = {}; - F32 len = length(a); - if (len != 0.f) { - F32 inv_len = 1.0f / len; - result.x = a.x * inv_len; - result.y = a.y * inv_len; - } - return result; -} - -api Vec3 normalize(Vec3 a) { - Vec3 result = {}; - F32 len = length(a); - if (len != 0.f) { - F32 inv_len = 1.0f / len; - result.x = a.x * inv_len; - result.y = a.y * inv_len; - result.z = a.z * inv_len; - } - return result; -} - -api Vec4 normalize(Vec4 a) { - Vec4 result = {}; - F32 len = length(a); - if (len != 0.f) { - F32 inv_len = 1.0f / len; - result.x = a.x * inv_len; - result.y = a.y * inv_len; - result.z = a.z * inv_len; - result.w = a.w * inv_len; - } - return result; -} - -function -Mat4 mat4_identity() { - Mat4 result = {}; - result.p[0][0] = 1; - result.p[1][1] = 1; - result.p[2][2] = 1; - result.p[3][3] = 1; - return result; -} - -function -Mat4 mat4_scale(Vec3 a) { - Mat4 result = {}; - result.p[0][0] = a.x; - result.p[1][1] = a.y; - result.p[2][2] = a.z; - result.p[3][3] = 1; - return result; -} - -function -Mat4 mat4_translation(Vec3 a) { - return { - 1, 0, 0, a.x, - 0, 1, 0, a.y, - 0, 0, 1, a.z, - 0, 0, 0, 1 - }; -} - -function -Mat4 mat4_rotation_z(float rotation) { - float s = sinf(rotation); - float c = cosf(rotation); - Mat4 result = { - c, s, 0, 0, - -s, c, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1, - }; - return result; -} - -function -Mat4 mat4_rotation_y(float rotation) { - float s = sinf(rotation); - float c = cosf(rotation); - Mat4 result = { - c, 0, -s, 0, - 0, 1, 0, 0, - s, 0, c, 0, - 0, 0, 0, 1, - }; - return result; -} - -function -Mat4 mat4_rotation_x(float rotation) { - float s = sinf(rotation); - float c = cosf(rotation); - Mat4 result = { - 1, 0, 0, 0, - 0, c, s, 0, - 0, -s, c, 0, - 0, 0, 0, 1, - }; - return result; -} - -constexpr F32 deg2rad = (PI32 / 180.f); // @Usage: degree * deg2rad = radians; -constexpr F32 rad2deg = (180.f / PI32); -function -Mat4 mat4_perspective(float fov, float window_x, float window_y, float znear, float zfar) { - float aspect_ratio = window_y / window_x; - float f = (1.f / tanf((fov/2.f)*deg2rad)); - Mat4 result = { - aspect_ratio*f, 0, 0, 0, - 0, f, 0, 0, - 0, 0, (zfar)-(zfar-znear),(-zfar*znear)-(zfar - znear), - 0,0,1,0 - }; - return result; -} - -function Mat4 mat4_look_at(Vec3 pos, Vec3 target, Vec3 up) { - Vec3 z = normalize(target - pos); - Vec3 x = normalize(cross(up, z)); - Vec3 y = cross(z, x); - Mat4 result = { - x.x,x.y,x.z,-dot(x,pos), - y.x,y.y,y.z,-dot(y,pos), - z.x,z.y,z.z,-dot(z,pos), - 0,0,0, 1, - }; - return result; -} - -function -Mat4 mat4_transpose(Mat4 a) { - Mat4 result = a; - result.p[0][1] = result.p[1][0]; - result.p[0][2] = result.p[2][0]; - result.p[0][3] = result.p[3][0]; - result.p[2][1] = result.p[1][2]; - result.p[3][1] = result.p[1][3]; - result.p[3][2] = result.p[2][3]; - return result; -} - -function -Mat4 mat4_translate(Mat4 a, Vec3 translation) { - a.p[0][0] += translation.x; - a.p[0][1] += translation.y; - a.p[0][2] += translation.z; - return a; -} \ No newline at end of file diff --git a/obj_parser.cpp b/obj_parser.cpp index 6cfbe17..6cdb9b2 100644 --- a/obj_parser.cpp +++ b/obj_parser.cpp @@ -1,3 +1,7 @@ +/// +/// [ ] - Cache bitmaps +/// [ ] - Fix potential portability issues due to compiler struct alignment differences etc. +/// struct Obj_Index { int vertex[3]; @@ -159,9 +163,11 @@ parse_mtl(Obj* obj, String path_obj_folder, String mtl_file) { m->name_len = clamp_top(token.len, 64); memory_copy(m->name, token.s8.str, m->name_len); } + else if (string_compare(token.s8, "Ns"_s)) { m->shininess = expect_number(&data); } + else if (string_compare(token.s8, "Ka"_s)) { m->ambient_color.x = expect_number(&data); m->ambient_color.y = expect_number(&data); @@ -172,6 +178,7 @@ parse_mtl(Obj* obj, String path_obj_folder, String mtl_file) { m->diffuse_color.y = expect_number(&data); m->diffuse_color.z = expect_number(&data); } + else if (string_compare(token.s8, "Ks"_s)) { m->specular_color.x = expect_number(&data); m->specular_color.y = expect_number(&data); @@ -180,27 +187,32 @@ parse_mtl(Obj* obj, String path_obj_folder, String mtl_file) { else if (string_compare(token.s8, "Ni"_s)) { m->optical_density = expect_number(&data); } + else if (string_compare(token.s8, "d"_s)) { m->non_transparency = expect_number(&data); } else if (string_compare(token.s8, "illum"_s)) { m->illumination_model = (S32)expect_number(&data); } + else if (string_compare(token.s8, "map_Kd"_s)) { Obj_Token t = next_token(&data); String path = string_fmt(scratch, "%Q/%Q\0", path_obj_folder, t.s8); m->texture_diffuse = load_image(path); } + else if (string_compare(token.s8, "map_Ka"_s)) { Obj_Token t = next_token(&data); String path = string_fmt(scratch, "%Q/%Q\0", path_obj_folder, t.s8); m->texture_ambient = load_image(path); } + else if (string_compare(token.s8, "map_d"_s)) { Obj_Token t = next_token(&data); String path = string_fmt(scratch, "%Q/%Q\0", path_obj_folder, t.s8); m->texture_dissolve = load_image(path); } + else if (string_compare(token.s8, "map_Disp"_s)) { Obj_Token t = next_token(&data); String path = string_fmt(scratch, "%Q/%Q\0", path_obj_folder, t.s8); @@ -212,17 +224,18 @@ parse_mtl(Obj* obj, String path_obj_folder, String mtl_file) { function Obj parse(Allocator *allocator, char* data, String path_obj_folder) { + Set_Allocator(allocator); Scratch mtl_scratch; Obj result = {}; - result.vertices.init(allocator, 160000); - result.texture_coordinates.init(allocator, 160000); - result.normals.init(allocator, 160000); - result.mesh.init(allocator, 64); - result.materials.init(allocator, 64); + //result.vertices.init(allocator, 160000); + //result.texture_coordinates.init(allocator, 160000); + //result.normals.init(allocator, 160000); + //result.mesh.init(allocator, 64); + //result.materials.init(allocator, 64); int smoothing = 0; Obj_Mesh *mesh = result.mesh.push_empty_zero(); - mesh->indices.init(allocator); + //mesh->indices.init(allocator); int material_id = -1; S64 debug_i = 0; @@ -237,12 +250,14 @@ parse(Allocator *allocator, char* data, String path_obj_folder) { vertex->z = (float)expect_number(&data); debug_expect_raw(&data, Obj_Token_Type::whitespace); } + else if (string_compare(token.s8, "vt"_s)) { Vec2 *tex = result.texture_coordinates.push_empty_zero(); tex->x = (float)expect_number(&data); tex->y = (float)expect_number(&data); debug_expect_raw(&data, Obj_Token_Type::whitespace); } + else if (string_compare(token.s8, "vn"_s)) { Vec3 *norm = result.normals.push_empty_zero(); norm->x = (float)expect_number(&data); @@ -250,6 +265,7 @@ parse(Allocator *allocator, char* data, String path_obj_folder) { norm->z = (float)expect_number(&data); debug_expect_raw(&data, Obj_Token_Type::whitespace); } + else if (string_compare(token.s8, "mtllib"_s)) { Obj_Token t = next_token(&data); String path = string_fmt(mtl_scratch, "%Q/%Q", path_obj_folder, t.s8); @@ -258,6 +274,7 @@ parse(Allocator *allocator, char* data, String path_obj_folder) { parse_mtl(&result, path_obj_folder, mtl_file); } } + else if (string_compare(token.s8, "usemtl"_s)) { Obj_Token t = next_token(&data); assert(t.type == Obj_Token_Type::word); @@ -269,18 +286,19 @@ parse(Allocator *allocator, char* data, String path_obj_folder) { } } } + else if (string_compare(token.s8, "o"_s)) { Obj_Token t = next_token(&data); assert(t.type == Obj_Token_Type::word); if (mesh->indices.len != 0) { mesh = result.mesh.push_empty_zero(); - mesh->indices.init(allocator); } else { U64 len = clamp_top(t.len, 64); memory_copy(mesh->name, t.s, len); } } + else if (string_compare(token.s8, "s"_s)) { Obj_Token t = next_token(&data); if (t.type == Obj_Token_Type::number) { @@ -298,10 +316,12 @@ parse(Allocator *allocator, char* data, String path_obj_folder) { } } + else if (string_compare(token.s8, "g"_s)) { Obj_Token t = next_token(&data); assert(t.type == Obj_Token_Type::word); } + else if (string_compare(token.s8, "f"_s)) { Obj_Index *i = mesh->indices.push_empty_zero(); i->smoothing_group_id = smoothing; @@ -330,29 +350,6 @@ parse(Allocator *allocator, char* data, String path_obj_folder) { return result; } -function void -test_lex() { - const char* d = "v 0.885739 0.001910 -0.380334"; - char* dd = (char *)d; - assert(next_token(&dd).type == Obj_Token_Type::word); - Obj_Token t = next_token(&dd); assert(t.type == Obj_Token_Type::number && t.number > 0.8857); - t = next_token(&dd); assert(t.type == Obj_Token_Type::number && t.number > 0.0019); - t = next_token(&dd); assert(t.type == Obj_Token_Type::number && t.number < -0.38); - d = "# Blender v2.79 (sub 0) OBJ File: 'fighters_0.blend'\n" - "# www.blender.org\n" - "mtllib f-22.mtl\n" - "o F-22\n"; - dd = (char *)d; - t = next_token(&dd); assert(t.type == Obj_Token_Type::word && string_compare(t.s8, "mtllib"_s)); - t = next_token(&dd); assert(t.type == Obj_Token_Type::word && string_compare(t.s8, "f-22.mtl"_s)); - t = next_token(&dd); assert(t.type == Obj_Token_Type::word && string_compare(t.s8, "o"_s)); - t = next_token(&dd); assert(t.type == Obj_Token_Type::word && string_compare(t.s8, "F-22"_s)); -} - -void test() { - test_lex(); -} - function Obj load_obj(Allocator *arena, String file) { Scratch scratch; @@ -386,25 +383,17 @@ _os_write_file(String file, String data, B32 append = false) { creation_disposition = OPEN_ALWAYS; } - Scratch scratch; // @Todo(Krzosa): Unicode + // @Todo(Krzosa): Unicode HANDLE handle = CreateFileA((const char *)file.str, access, 0, NULL, creation_disposition, FILE_ATTRIBUTE_NORMAL, NULL); if (handle != INVALID_HANDLE_VALUE) { DWORD bytes_written = 0; // @Todo: can only read 32 byte size files? - assert_msg(data.len == (U32)data.len, - "Max data size os_write can handle is 32 bytes, data to write is " - "larger then 32 bytes!"); + assert_msg(data.len == (U32)data.len, "Max data size os_write can handle is 32 bytes, data to write is larger then 32 bytes!"); B32 error = WriteFile(handle, data.str, (U32)data.len, &bytes_written, NULL); - if (error == false) { - log_error("Failed to write to file: %Q", file); - } + if (error == false) log_error("Failed to write to file: %Q", file); else { - if (bytes_written != data.len) { - log_error("Failed to write to file: %Q, mismatch between length requested to write and length written", file); - } - else{ - result = true; - } + if (bytes_written != data.len) log_error("Failed to write to file: %Q, mismatch between length requested to write and length written", file); + else result = true; } CloseHandle(handle); } @@ -483,7 +472,7 @@ dump_obj_to_file(Obj *obj){ dump_bitmap_image(&sb, &it->texture_displacement); } - String result = string_flatten(&sb); + String result = string_flatten(arena, &sb); os_write_file("sponza.bin"_s, result); } diff --git a/ui.cpp b/ui.cpp index 0fe8b54..07c2d4b 100644 --- a/ui.cpp +++ b/ui.cpp @@ -62,7 +62,7 @@ function UIWidget *ui_new_widget(Allocator *arena, UIWidgetKind kind) { } function void ui_push_child(UIWidget *widget, UIWidget *child) { - //DLL_QUEUE_PUSH(widget->first_child, widget->last_child, child); + DLLQueuePush(widget->first_child, widget->last_child, child); } function UIWidget *ui_push_child(Arena *arena, UIWidget *widget, UIWidgetKind kind) { @@ -171,42 +171,42 @@ function void ui_end_frame(Bitmap *dst, UI *ui, Font *font) { rect = vec4(pos, w->size); ui_mouse_test(ui, w, rect); String string = string_fmt(scratch, "%d %d", w->ptr.image->x, w->ptr.image->y); - r_draw_string(dst, font, string, pos); - r_draw_bitmap(dst, w->ptr.image, pos, w->size); + draw_string(dst, font, string, pos); + draw_bitmap(dst, w->ptr.image, pos, w->size); if (ui->active == w) { F32 ratio = (F32)w->ptr.image->y / (F32)w->ptr.image->x; w->size.x -= os.delta_mouse_pos.x; w->size.y = w->size.x * ratio; } if (ui->hot == w) { - r_draw_rect(dst, rect.x, rect.y, rect.width, rect.height, vec4(1, 1, 1, 0.1f)); + draw_rect(dst, rect.x, rect.y, rect.width, rect.height, vec4(1, 1, 1, 0.1f)); } } break; case UIWidgetKind_Boolean: { pos.y -= font->height; Vec4 color = vec4(0, 0, 0, 1); String string = string_fmt(scratch, "%s %d", w->text, *w->ptr.b32); - rect = r_get_string_rect(font, string, pos); + rect = get_string_rect(font, string, pos); B32 clicked = ui_mouse_test(ui, w, rect); if (clicked) *w->ptr.b32 = !*w->ptr.b32; if (ui->hot == w) { color = vec4(0.4f, 0.4f, 0.4f, 1.f); } rect.y = rect.y-font->line_advance / 5; - r_draw_rect(dst, rect.x, rect.y, rect.width, rect.height, color); - rect = r_draw_string(dst, font, string, pos); + draw_rect(dst, rect.x, rect.y, rect.width, rect.height, color); + rect = draw_string(dst, font, string, pos); pos.y -= rect.height - font->height; } break; case UIWidgetKind_Label: { pos.y -= font->height; - rect = r_draw_string(dst, font, *w->ptr.label, pos); + rect = draw_string(dst, font, *w->ptr.label, pos); pos.y -= rect.height - font->height; } break; case UIWidgetKind_Option: { pos.y -= font->height; Vec4 color = vec4(0, 0, 0, 1); - String string = string_fmt(scratch, "%s %d", w->text, *w->ptr.option); - rect = r_get_string_rect(font, string, pos); + String string = string_fmt(scratch, "%Q %Q", w->text, *w->ptr.option); + rect = get_string_rect(font, string, pos); B32 clicked = ui_mouse_test(ui, w, rect); if (clicked) { *w->ptr.b32 = (*w->ptr.b32+1) % w->option_max; @@ -215,15 +215,15 @@ function void ui_end_frame(Bitmap *dst, UI *ui, Font *font) { color = vec4(0.4f, 0.4f, 0.4f, 1.f); } rect.y = rect.y-font->line_advance / 5; - r_draw_rect(dst, rect.x, rect.y, rect.width, rect.height, color); - rect = r_draw_string(dst, font, string, pos); + draw_rect(dst, rect.x, rect.y, rect.width, rect.height, color); + rect = draw_string(dst, font, string, pos); pos.y -= rect.height - font->height; } break; case UIWidgetKind_Signal: { pos.y -= font->height; Vec4 color = vec4(0, 0, 0, 1); - String string = string_fmt(scratch, "%s", w->text); - rect = r_get_string_rect(font, string, pos); + String string = string_fmt(scratch, "%Q", w->text); + rect = get_string_rect(font, string, pos); B32 clicked = ui_mouse_test(ui, w, rect); if (clicked) { w->ptr.signal_callback(); @@ -232,8 +232,8 @@ function void ui_end_frame(Bitmap *dst, UI *ui, Font *font) { color = vec4(0.4f, 0.4f, 0.4f, 1.f); } rect.y = rect.y-font->line_advance / 5; - r_draw_rect(dst, rect.x, rect.y, rect.width, rect.height, color); - rect = r_draw_string(dst, font, string, pos); + draw_rect(dst, rect.x, rect.y, rect.width, rect.height, color); + rect = draw_string(dst, font, string, pos); pos.y -= rect.height - font->height; } break; invalid_default_case;