From e7f67b450d8034b532101445035d3b199e702621 Mon Sep 17 00:00:00 2001 From: pryazha Date: Sun, 15 Jun 2025 15:28:45 +0500 Subject: windows? --- example/build.sh | 17 +- example/example | Bin 62744 -> 59280 bytes example/example.c | 388 +++++++++++++++------------------------ example/example.exe | Bin 0 -> 315771 bytes prb.h | 31 ++-- prb_arena.c | 48 ----- prb_arena.h | 52 +++++- prb_linux.h | 69 +++++++ prb_macros.h | 95 +++++----- prb_math.c | 510 --------------------------------------------------- prb_math.h | 515 ++++++++++++++++++++++++++++++++++++++++++++-------- prb_string.c | 170 ----------------- prb_string.h | 208 ++++++++++++++++++--- prb_sys.c | 52 ------ prb_sys.h | 13 +- prb_types.h | 117 ++++-------- prb_windows.h | 75 ++++++++ 17 files changed, 1078 insertions(+), 1282 deletions(-) create mode 100755 example/example.exe delete mode 100644 prb_arena.c create mode 100644 prb_linux.h delete mode 100644 prb_math.c delete mode 100644 prb_string.c delete mode 100644 prb_sys.c create mode 100644 prb_windows.h diff --git a/example/build.sh b/example/build.sh index 172aa69..de969e8 100755 --- a/example/build.sh +++ b/example/build.sh @@ -1,7 +1,14 @@ #!/bin/sh -CFLAGS='-g -Wall' -INCLUDE='-I..' -LIBS='-lm' +compiler='gcc' +if [ $# -eq 1 ] ; then + if [ $1 = 'windows' ] ; then + compiler='x86_64-w64-mingw32-gcc' + fi +fi +cflags='-g -Wall' +include='-I..' +libs='-lm' +path=`dirname $0` set -x -#tcc $CFLAGS $INCLUDE $LIBS -o example example.c && ./example -gcc $CFLAGS $INCLUDE $LIBS -o example example.c && ./example +cd $path +$compiler $cflags $include -o example example.c $libs diff --git a/example/example b/example/example index cefef94..cdaf21e 100755 Binary files a/example/example and b/example/example differ diff --git a/example/example.c b/example/example.c index dc76ffb..6b0085a 100644 --- a/example/example.c +++ b/example/example.c @@ -1,276 +1,172 @@ #include "prb.h" -typedef struct { - S32 first; - S32 second; - B32 flags; -} SomeStruct; - -typedef struct SLLNode { - S32 val; - struct SLLNode *next; -} SLLNode; - -typedef struct DLLNode { - S32 val; - struct DLLNode *next; - struct DLLNode *prev; -} DLLNode; - -int main(void) -{ - F32 verts[] = { - 1.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 1.0f - }; - - ASSERT(v3a(1.0f).y); - - printf("OFFSETOF(SomeStruct, flags): %ld\n\n", OFFSETOF(SomeStruct, flags)); - - F32 range_min = 0.0f, - range_max = 1.0f, - clamped_number = 1.5f, - another_clamped_number = -0.2f; - - printf("CLAMPBOT(%f, %f): %f\n", range_min, - another_clamped_number, CLAMPBOT(another_clamped_number, range_min)); - printf("CLAMPTOP(%f, %f): %f\n", range_max, - clamped_number, CLAMPTOP(clamped_number, range_max)); +#define MAX_NODES 10 - printf("CLAMP(%f, %f, %f): %f\n", range_min, clamped_number, range_max, - CLAMP(range_min, clamped_number, range_max)); - printf("CLAMP(%f, %f, %f): %f\n\n", range_min, another_clamped_number, range_max, - CLAMP(range_min, another_clamped_number, range_max)); - - F32 swap_test_first = 10.0f, - swap_test_second = 20.0f; +typedef struct { + i32 i32_element; + i16 i16_element; + u8 u8_element; +} type_t; - printf("Before SWAP: swap_test_first = %f, swap_test_second = %f\n", - swap_test_first, swap_test_second); - SWAP(F32, swap_test_first, swap_test_second); - printf("After SWAP: swap_test_first = %f, swap_test_second = %f\n\n", - swap_test_first, swap_test_second); +typedef struct stack_node_t { + i32 value; + struct stack_node_t *next; +} stack_node_t; - SomeStruct some_stuct = { 10, 20, 30 }; - printf("SomeStruct: first: %d, second: %d, flags: %d\n", - some_stuct.first, some_stuct.second, some_stuct.flags); - MEM0(&some_stuct, sizeof(SomeStruct)); - printf("After MEM0(&some_stuct, sizeof(SomeStruct)):\n"); - printf("some_stuct: first: %d, second: %d, flags: %d\n\n", - some_stuct.first, some_stuct.second, some_stuct.flags); +typedef struct { + stack_node_t *first; + stack_node_t *last; +} stack_t; - some_stuct = (SomeStruct){ 10, 20, 30 }; - printf("some_stuct: first: %d, second: %d, flags: %d\n", - some_stuct.first, some_stuct.second, some_stuct.flags); - MEM0STRUCT(&some_stuct); - printf("After MEM0STRUCT(&some_stuct):\n"); - printf("some_stuct: first: %d, second: %d, flags: %d\n\n", - some_stuct.first, some_stuct.second, some_stuct.flags); +typedef struct node_t { + i32 value; + struct node_t *next; + struct node_t *prev; +} node_t; - S32 dynamic_array_length = 10; - U64 dynamic_array_size = dynamic_array_length*sizeof(S32); - F32 *dynamic_array_first = malloc(dynamic_array_size); - F32 *dynamic_array_second = malloc(dynamic_array_size); +typedef struct { + node_t *first; + node_t *last; +} list_t; - printf("first dynamic array:\n"); - for (S32 i = 0; i < dynamic_array_length; ++i) { - F32 *element = dynamic_array_first+i; - *element = i+420; - printf("%f%c", *element, (i == dynamic_array_length-1) ? '\n' : ' '); - } - printf("second dynamic array:\n"); - for (S32 i = 0; i < dynamic_array_length; ++i) { - F32 *element = dynamic_array_second+i; - printf("%f%c", *element, (i == dynamic_array_length-1) ? '\n' : ' '); - } - MEMCPY(dynamic_array_second, dynamic_array_first, dynamic_array_size); - printf("After MEMCPY(dynamic_array_second, dynamic_array_first, dynamic_array_size):\n"); - printf("second dynamic array:\n"); - for (S32 i = 0; i < dynamic_array_length; ++i) { - F32 *element = dynamic_array_second+i; - printf("%f%c", *element, (i == dynamic_array_length-1) ? '\n' : ' '); +i32 main(void) +{ + // os + printf("os: "); + switch (OS) { + case OS_LINUX: + printf("linux\n"); + break; + case OS_WINDOWS: + printf("windows\n"); + break; + default: + printf("unsupported\n"); + return 1; } - S32 memory_match = MEMMATCH(dynamic_array_first, dynamic_array_second, dynamic_array_size); - printf("And MEMMATCH(dynamic_array_first, dynamic_array_second, dynamic_array_size): %d\n\n", memory_match); - free(dynamic_array_first); - free(dynamic_array_second); - printf("Linked Lists:\n"); - printf("Singly linked list: "); - S32 list_length = 5; - U64 list_size = list_length*sizeof(SLLNode); - SLLNode *sllist = malloc(list_size); - SLLNode *sllfirst = 0; - SLLNode *slllast = 0; - for (S32 i = 0; i < list_length; ++i) { - SLLNode *new = sllist+i; - new->val = i; - SLLPUSH(sllfirst, slllast, new); + arena_t path_arena = alloc_arena(MAX_PATH); + char *dir = sys_getbindir(&path_arena); + printf("bin directory \"%s\"\n", dir); + + // macros + u64 offset = offsetof(type_t, u8_element); + assert(offset == 6); + printf("offsetof(type_t, u8_element) = %lu\n", offset); + i32 clamped = clamp(0, -1, 1); + assert(clamped == 0); + printf("clamp(0, -1, 1) = %d\n", clamped); + clamped = clamp(0, 2, 1); + assert(clamped == 1); + printf("clamp(0, 2, 1) = %d\n", clamped); + + i32 nums[] = {0, 1, 2, 3}; + printf("mem0: ["); + for (i32 i = 0; i < array_count(nums); ++i) + printf("%x%s", nums[i], (i == array_count(nums)-1) ? "" : ", "); + memzero(nums, sizeof(nums)); + printf("] -> ["); + for (i32 i = 0; i < array_count(nums); ++i) { + assert(!nums[i]); + printf("%x%s", nums[i], (i == array_count(nums)-1) ? "" : ", "); } - for (SLLNode *node = sllfirst; node; node = node->next) - printf("%d%s", node->val, ((node->next) ? " -> " : "\n")); - SLLPOP(sllfirst, slllast); - printf("After SLLPOP(sllfirst, slllast): "); - for (SLLNode *node = sllfirst; node; node = node->next) - printf("%d%s", node->val, ((node->next) ? " -> " : "\n")); - free(sllist); + printf("]\n"); - printf("Doubly linked list: "); - list_length = 8; - list_size = list_length*sizeof(DLLNode); - DLLNode *dllist = malloc(list_size); - DLLNode *dllfirst = 0; - DLLNode *dlllast = 0; - for (S32 i = 0; i < list_length; ++i) { - DLLNode *new = dllist+i; - new->val = i; - DLLPUSHBACK(dllfirst, dlllast, new); - } - for (DLLNode *node = dllfirst; node; node = node->next) - printf("%d%s", node->val, ((node->next) ? " -> " : "\n")); - printf("Remove odd numbers: "); - for (DLLNode *node = dllfirst; node; node = node->next) - if (node->val % 2 == 1) - DLLREMOVE(dllfirst, dlllast, node); - for (DLLNode *node = dllfirst; node; node = node->next) - printf("%d%s", node->val, ((node->next) ? " -> " : "\n")); - free(dllist); printf("\n"); - printf("I'm pretty sure the vectors are fine.\nAt least for the last few months :)\n\n"); + printf("Singly linked list (stack for example):\n"); - printf("Matrices:\n"); - printf("Identity:\n"); - MAT4 m = MAT4_IDENTITY; - printmat4(m); - m = scalemat4(m, v3a(10.0f)); - m = translmat4(m, v3a(1.0f)); - m = translmat4(m, v3(0.0f, 68.0f, 0.0f)); - printmat4(m); - printf("Determinant: %f\n", detmat4(m)); - printf("Transpose:\n"); printmat4(transpmat4(m)); - printf("mat4rotate(MAT4_IDENTITY, v3(0.0f, 45.0f, 0.0f)):\n"); - printmat4(rotatemat4(MAT4_IDENTITY, v3(0.0f, 45.0f, 0.0f))); + stack_node_t stack_nodes[MAX_NODES]; + stack_t stack = {0}; + for (i32 i = 0; i < MAX_NODES; ++i) { + stack_node_t *node = stack_nodes+i; + node->value = i; + sllpush(stack.first, stack.last, node); + } - sys_printf("Example of using sys_printf without args\n"); - sys_printf("And with some of number : %x : <- like that or string : %s : for example\n", 69, "yeah"); + for (stack_node_t *node = stack.first; node; node = node->next) + printf("%d%s", node->value, ((node->next) ? " -> " : "\n")); - printf("Using Arenas:\n"); + sllpop(stack.first, stack.last); - Arena *a; - U8 *df, - *ds; - Arena *tmpa; + printf("After pop:\n"); + for (stack_node_t *node = stack.first; node; node = node->next) + printf("%d%s", node->value, ((node->next) ? " -> " : "\n")); - a = alloc_arena(10); - df = push_arena(a, 5); - memset(df, 5, 5); - ds = push_arena(a, 5); - memset(ds, 10, 5); - - tmpa = alloc_arena(0); - - flsprint(FLSLIT("|")); - for (S32 i = 0; i < 10; i++) - flsprint(flspushf(tmpa, "%x%s", df[i], ((i+1) % 5 == 0) ? "|" : " ")); - flsprint(FLSLIT("\n")); - - release_arena(tmpa); - release_arena(a); - - a = alloc_arena(0); - SLLNode *first = 0; - SLLNode *last = 0; - S32 node_count = 10; - for (S32 i = 0; i < node_count; ++i) { - SLLNode *new = push_arena(a, sizeof(SLLNode)); - new->val = i; - SLLPUSH(first, last, new); + node_t nodes[MAX_NODES]; + list_t list = {0}; + for (i32 i = 0; i < MAX_NODES; ++i) { + node_t *node = nodes+i; + node->value = i; + dllpushback(list.first, list.last, node); } - for (SLLNode *node = first; node; node = node->next) - printf("%d%s", node->val, ((node->next) ? " -> " : "\n")); - release_arena(a); - - a = alloc_arena(sizeof(verts)); - S32 verts_count = ARRCNT(verts); - F32 *dynamic_verts = push_arena(a, sizeof(verts)); - MEM0(dynamic_verts, verts_count*sizeof(F32)); - for (S32 i = 0; i < verts_count; ++i) { - F32 *vert = dynamic_verts+i; - printf("%f%c", *vert, (i == verts_count-1) ? '\n' : ' '); - } - release_arena(a); - printf("\n"); - - Arena *str_arena = alloc_arena(0); - printf("Strings:\n"); - char *cstr = "This is a C str\n"; - FLS str = flsfromcstr(cstr); - str = flschopstart(str, 10); - cstr = flstocstr(a, str); - printf("%s", cstr); - flsprint(str); - FLS choped_str = flschopend(str, 3); - flsprint(choped_str); + + printf("Doubly linked list:\n"); + for (node_t *node = list.first; node; node = node->next) + printf("%d%s", node->value, ((node->next) ? " -> " : "\n")); + + printf("Remove odd numbers:\n"); + for (node_t *node = list.first; node; node = node->next) + if (node->value % 2 == 1) + dllremove(list.first, list.last, node); + + for (node_t *node = list.first; node; node = node->next) + printf("%d%s", node->value, ((node->next) ? " -> " : "\n")); + printf("\n"); - FLSList *list = flslist(str_arena); - flslistpush(str_arena, list, str, 0); - flslistpush(str_arena, list, flsfromcstr("test"), 0); - flslistpush(str_arena, list, flsfromcstr("and this is also a test\n"), 0); - flslistpush(str_arena, list, flsfromcstr("Kinda works!"), 1); - printf("FLSList: "); - flslistprint(list); - release_arena(str_arena); - flslistprint(list); - str_arena = alloc_arena(KB(10)); - U32 memory_size = 512; - U32 count = memory_size/sizeof(S32); - S32 *some = push_arena(str_arena, memory_size); - printf("str_arena(size): %ld\nMemory:\n", str_arena->cap); - for (S32 i = 0; i < count; i++) { - S32 *e = some+i; - *e = 69; - printf("%d: %d%c", i, *e, ((i == count-1) ? '\n' : ' ')); - } - printf("Memory used: %lu\n", str_arena->used); - printf("Remaining memory: %lu\n", - str_arena->cap-str_arena->used); + printf("I'm pretty sure the vectors are fine\n"); + printf("At least for the last few months :)\n\n"); - pop_arena(str_arena, memory_size); + printf("Arenas:\n"); - printf("After arena pop\n"); - printf("Memory used: %lu\n", str_arena->used); - printf("Remaining memory: %lu\n", - str_arena->cap-str_arena->used); - printf("some ptr is %s\n", some ? "not null" : "null"); - printf("str_arena(size): %lu\nMemory:\n", str_arena->cap); - - FLS new_str = flspushf(str_arena, "Test of the formatted string: %d\n", 69); - flsprint(new_str); - - list = flslist(str_arena); - flslistpushf(str_arena, list, 0, "This is a list %d", 34); - flslistpushf(str_arena, list, 0, " of formatted strings: %d", 35); - flslistpushf(str_arena, list, 1, "And you can push to the start"); - /* TODO(pryazha): Think about simpler way of using string literals. - * Maybe you don't need to, I dunno */ - flslistpushf(str_arena, list, 1, "The most interesting part is that you can include the whole string like that: %*s\n", - FLSEXP(FLSLIT("Absolutely random string with absolutely random content (or not)."))); - flslistprint(list); + arena_t arena = alloc_arena(10); + u8 *first = push_arena(&arena, 5); + prb_memset(first, 5, 5); + u8 *second = push_arena(&arena, 5); + prb_memset(second, 10, 5); + printf("|"); + for (i32 i = 0; i < 10; i++) + printf("%x%s", first[i], ((i+1) % 5 == 0) ? "|" : " "); + printf("\n"); + release_arena(&arena); - release_arena(str_arena); + printf("Strings:\n"); - a = alloc_arena(MB(1)); - flsprint(FLSLIT("build.sh content:\n")); - FLS file_content = fls_read_entire_file(a, FLSLIT("build.sh")); - if (file_content.p) - flsprint(file_content); + arena_t str_arena = alloc_arena(0); + str8_list_t strlist = {0}; + str8_list_push(&str_arena, &strlist, 0, str8lit("first ")); + str8_list_push(&str_arena, &strlist, 0, str8lit("second ")); + str8_list_push(&str_arena, &strlist, 0, str8lit("third\n")); + str8_print(str8lit("strlist: ")); + str8_list_print(&strlist); + + str8_t fstr = str8_pushf(&str_arena, "Formatted string: %d\n", 69); + str8_print(fstr); + + memzero_struct(&strlist); + str8_list_pushf(&str_arena, &strlist, 0, "first %d -> ", 34); + str8_list_pushf(&str_arena, &strlist, 0, "second: %d -> ", 35); + str8_list_pushf(&str_arena, &strlist, 0, "sum: %d\n", 34+35); + str8_list_pushf(&str_arena, &strlist, 1, "%s", "To the front -> "); + + str8_print(str8lit("Formatted string list:\n")); + str8_list_print(&strlist); + + str8_t catstr = str8_list_join(&str_arena, &strlist); + str8_print(str8lit("Concatenated string list:\n")); + str8_print(catstr); + + release_arena(&str_arena); + + const char *filename = "build.sh"; + arena = alloc_arena(megabytes(1)); + u8 *content; + if (sys_read_file(&arena, &content, filename)) + printf("%s content:\n%s", filename, content); else - flsprint(FLSLIT("failed to read build.sh\n")); - release_arena(a); + printf("failed to read %s\n", filename); + release_arena(&arena); return(0); } diff --git a/example/example.exe b/example/example.exe new file mode 100755 index 0000000..ae02648 Binary files /dev/null and b/example/example.exe differ diff --git a/prb.h b/prb.h index f09df2d..fad7ff0 100644 --- a/prb.h +++ b/prb.h @@ -1,27 +1,30 @@ #ifndef PRB_H #define PRB_H -#include -#include -#include -#include #include +#include #include -#include +#include +#include -#include "prb_macros.h" #include "prb_types.h" - +#include "prb_macros.h" #include "prb_math.h" -#include "prb_math.c" - #include "prb_arena.h" -#include "prb_arena.c" - +#include "prb_sys.h" #include "prb_string.h" -#include "prb_string.c" -#include "prb_sys.h" -#include "prb_sys.c" +#define OS_NONE 0 +#define OS_WINDOWS 1 +#define OS_LINUX 2 + +#if defined(__linux) +#define OS OS_LINUX +#include "prb_linux.h" +#elif defined(__WIN64) +#define OS OS_WINDOWS +#include +#include "prb_windows.h" +#endif #endif /* PRB_H */ diff --git a/prb_arena.c b/prb_arena.c deleted file mode 100644 index 1938dec..0000000 --- a/prb_arena.c +++ /dev/null @@ -1,48 +0,0 @@ -Arena *alloc_arena(U64 cap) -{ - Arena *a; - - /* TODO(pryazha): Use OS specific memory allocator - * (like VirtualAlloc on Windows or mmap on Linux) - */ - a = malloc(sizeof(Arena)); - ASSERT(a); - - if (!cap) - cap = PRB_DEFAULT_ALLOC_SIZE; - - a->mem = malloc(cap); - ASSERT(a->mem); - a->cap = cap; - a->used = 0; - - return a; -} - -void release_arena(Arena *a) -{ - free(a->mem); - MEM0STRUCT(a); - free(a); -} - -void *push_arena(Arena *a, U64 size) -{ - ASSERT(a); - ASSERT(a->used+size <= a->cap); - - void *r; - - r = a->mem+a->used; - a->used += size; - - return r; -} - -void pop_arena(Arena *a, U64 size) -{ - ASSERT(a); - U64 clamped; - clamped = CLAMPTOP(size, a->used); - a->used = a->used-clamped; -} diff --git a/prb_arena.h b/prb_arena.h index 2d3453f..0a6de9b 100644 --- a/prb_arena.h +++ b/prb_arena.h @@ -1,6 +1,48 @@ -#define PRB_DEFAULT_ALLOC_SIZE KB(4) +#define DEFAULT_ARENA_SIZE kilobytes(4) -Arena *alloc_arena(U64 cap); -void release_arena(Arena *a); -void *push_arena(Arena *a, U64 size); -void pop_arena(Arena *a, U64 size); +arena_t alloc_arena(u64 capacity) +{ + void *sys_alloc(u64 length); + + /* TODO(pryazha): Find reasonable maximum capacity through testing */ + assert(capacity <= (u64)gigabytes(16)); + + if (!capacity) + capacity = DEFAULT_ARENA_SIZE; + + /* TODO(pryazha): Use OS specific memory allocator + * (like VirtualAlloc on Windows or mmap on Linux) + */ + void *memory = sys_alloc(capacity); + assert(memory); + + arena_t arena = {memory, capacity, 0}; + + return arena; +} + +void release_arena(arena_t *arena) +{ + void sys_free(void *memory, u64 length); + + assert(arena); + sys_free(arena->memory, arena->capacity); + arena->memory = 0; + arena->capacity = 0; + arena->used = 0; +} + +void *push_arena(arena_t *arena, u64 size) +{ + assert(arena); + assert(arena->used + size <= arena->capacity); + void *memory = arena->memory + arena->used; + arena->used += size; + return memory; +} + +void pop_arena(arena_t *arena, u64 size) +{ + assert(arena); + arena->used -= min(size, arena->used); +} diff --git a/prb_linux.h b/prb_linux.h new file mode 100644 index 0000000..3acc229 --- /dev/null +++ b/prb_linux.h @@ -0,0 +1,69 @@ +#include +#include +#include +#include + +void *sys_alloc(u64 length) +{ + assert(length); + void *result = mmap(0, length, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + return result; +} + +void sys_free(void *memory, u64 length) +{ + assert(memory); + assert(length); + munmap(memory, length); +} + +u64 sys_read_file(arena_t *arena, char **buffer, const char *filename) +{ + FILE *file = fopen(filename, "rb"); + if (!file) + return 0; + + if (fseek(file, 0, SEEK_END) == -1) + goto error; + long len = ftell(file); + if (!len || (len == -1)) + goto error; + if (fseek(file, 0, SEEK_SET) == -1) + goto error; + + *buffer = push_arena(arena, len + 1); + if (!fread(*buffer, 1, len, file)) { + pop_arena(arena, len + 1); + *buffer = 0; + goto error; + } + (*buffer)[len] = 0; + fclose(file); + + return len; +error: + fclose(file); + *buffer = 0; + return 0; +} + +char *sys_getbindir(arena_t *arena) +{ + char path[MAX_PATH]; + i64 len = readlink("/proc/self/exe", path, MAX_PATH - 1); + if (len <= 0) + return 0; + + path[len] = 0; + + char *dir = strrchr(path, '/'); + assert(dir); + assert(dir > path); + + len = dir - path; + dir = push_arena(arena, len + 1); + prb_memmove(dir, path, len); + dir[len] = 0; + + return dir; +} diff --git a/prb_macros.h b/prb_macros.h index 5a38ae4..8324919 100644 --- a/prb_macros.h +++ b/prb_macros.h @@ -1,55 +1,54 @@ -#ifndef PRB_MACROS_H -#define PRB_MACROS_H +/* +#ifndef assert +#define assert(expr) if (!(expr)) { *(int *)0 = 0; } +#endif +*/ +#include -#define ASSERT(E) if (!(E)) { *(int *)0 = 0; } +#define array_count(array) (sizeof(array)/sizeof(*(array))) -#define ARRCNT(A) (sizeof(A)/sizeof(*(A))) +#ifndef offsetof +#define offsetof(type, element) ((size_t)(&(((type *)0)->element))) +#endif -#define OFFSETOF(T, E) ((size_t)(&(((T *)(0))->E))) +#define min(a, b) (((a) < (b)) ? (a) : (b)) +#define max(a, b) (((a) > (b)) ? (a) : (b)) -#define MIN(A, B) (((A) < (B)) ? (A) : (B)) -#define MAX(A, B) (((A) > (B)) ? (A) : (B)) +#define clamp(a, x, b) \ + (((x) < (a)) ? (a) : \ + (((x) > (b)) ? (b) : (x))) -#define CLAMP(A, X, B) (((X) < (A)) ? (A) : \ - (((X) > (B)) ? (B) : (X))) -#define CLAMPTOP(A, B) MIN(A, B) -#define CLAMPBOT(A, B) MAX(A, B) - -#define SWAP(T, A, B) { T tmp = A; A = B; B = tmp; } +#define swap(type, a, b) { type tmp = (a); (a) = (b); (b) = tmp; } /* NOTE(pryazha): Memory */ -#define MEM0(P, N) memset((P), 0, (N)) -#define MEM0STRUCT(P) MEM0((P), sizeof(*(P))) - -#define MEMCPY(D, S, N) memmove((D), (S), (N)) - -#define MEMMATCH(A, B, N) (memcmp((A), (B), (N)) == 0) - -#define KB(N) N*1024 -#define MB(N) KB(N)*1024 -#define GB(N) MB(N)*1024 - -/* NOTE(pryazha): Singly-linked list */ -#define SLLPUSH(F, L, N) \ - ((F) == 0 ? \ - ((F) = (L) = (N), (N)->next = 0) : \ - ((L)->next = (N), (L) = (N), (N)->next = 0)) -#define SLLPOP(F, L) \ - ((F) == (L) ? \ - ((F) = (L) = 0) : \ - ((F) = (F)->next)) - -/* NOTE(pryazha): Doubly-linked list */ -#define DLLPUSHBACK_NP(F, L, N, next, prev) \ - ((F) == 0 ? \ - ((F) = (L) = (N), (N)->next = (N)->prev = 0) : \ - ((N)->prev = (L), (L)->next = (N), (L) = (N), (N)->next = 0)) -#define DLLPUSHBACK(F, L, N) DLLPUSHBACK_NP(F, L, N, next, prev) -#define DLLPUSHFRONT(F, L, N) DLLPUSHBACK_NP(L, F, N, prev, next) -#define DLLREMOVE(F, L, N) \ - ((F) == (N) ? \ - ((F) == (L) ? (F) = (L) = 0 : ((F) = (F)->next, (F)->prev = 0)) : \ - ((L) == (N) ? ((L) = (L)->prev, (L)->next = 0) : \ - ((N)->next->prev = (N)->prev, (N)->prev->next = (N)->next))) - -#endif /* PRB_MACROS_H */ +#define memzero(ptr, size) prb_memset((ptr), 0, (size)) +#define memzero_struct(ptr) memzero((ptr), sizeof(*(ptr))) + +#define kilobytes(n) n*1024 +#define megabytes(n) kilobytes(n)*1024 +#define gigabytes(n) megabytes(n)*1024 + +/* NOTE(pryazha): Singly linked list */ +#define sllpush(first, last, node) \ + ((first) == 0 ? \ + ((first) = (last) = (node), (node)->next = 0) : \ + ((last)->next = (node), (last) = (node), (node)->next = 0)) +#define sllpop(first, last) \ + ((first) == (last) ? \ + ((first) = (last) = 0) : \ + ((first) = (first)->next)) + +/* NOTE(pryazha): Doubly linked list */ +#define dllpushback_np(first, last, node, next, prev) \ + ((first) == 0 ? \ + ((first) = (last) = (node), (node)->next = (node)->prev = 0) : \ + ((node)->prev = (last), (last)->next = (node), (last) = (node), (node)->next = 0)) +#define dllpushback(first, last, node) dllpushback_np(first, last, node, next, prev) +#define dllpushfront(first, last, node) dllpushback_np(last, first, node, prev, next) + +#define dllremove(first, last, node) \ + ((first) == (node) ? \ + ((first) == (last) ? (first) = (last) = 0 : \ + ((first) = (first)->next, (first)->prev = 0)) : \ + ((last) == (node) ? ((last) = (last)->prev, (last)->next = 0) : \ + ((node)->next->prev = (node)->prev, (node)->prev->next = (node)->next))) diff --git a/prb_math.c b/prb_math.c deleted file mode 100644 index 2efb091..0000000 --- a/prb_math.c +++ /dev/null @@ -1,510 +0,0 @@ -F32 f32sin(F32 a) -{ - F32 r; - r = sinf(a); - return r; -} - -F32 f32cos(F32 a) -{ - F32 r; - r = cosf(a); - return r; -} - -F32 f32tan(F32 a) -{ - F32 r; - r = tanf(a); - return r; -} - -F32 f32sqrt(F32 a) -{ - F32 r; - r = sqrtf(a); - return r; -} - -/* NOTE(pryazha): Vectors */ -V2 v2(F32 x, F32 y) -{ - V2 r; - r.x = x; - r.y = y; - return r; -} - -V2 v2a(F32 x) -{ - V2 r; - r = v2(x, x); - return r; -} - -V2 invv2(V2 a) -{ - V2 r; - r = v2(-a.x, -a.y); - return r; -} - -V2 addv2(V2 a, V2 b) -{ - V2 r; - r = v2(a.x+b.x, a.y+b.y); - return r; -} - -V2 subv2(V2 a, V2 b) -{ - V2 r; - r = v2(a.x-b.x, a.y-b.y); - return r; -} - -V2 scalefv2(V2 a, F32 s) -{ - V2 r; - r = v2(a.x*s, a.y*s); - return r; -} - -V2 scalev2(V2 a, V2 s) -{ - V2 r; - r = v2(a.x*s.x, a.y*s.y); - return r; -} - -F32 dotv2(V2 a, V2 b) -{ - F32 r; - r = a.x*b.x+a.y*b.y; - return r; -} - -F32 len2v2(V2 a) -{ - F32 r; - r = dotv2(a, a); - return r; -} - -F32 lenv2(V2 a) -{ - F32 r; - r = f32sqrt(len2v2(a)); - return r; -} - -V2 normv2(V2 a) -{ - F32 len; - V2 r; - - r = V2_ZERO; - len = lenv2(a); - if (len) - r = v2(a.x/len, a.y/len); - - return r; -} - -void printv2(V2 a) -{ - fprintf(stdout, "{%f, %f}T\n", a.x, a.y); -} - -V3 v3(F32 x, F32 y, F32 z) -{ - V3 r; - r.x = x; - r.y = y; - r.z = z; - return r; -} - -V3 v3a(F32 x) -{ - V3 r; - r = v3(x, x, x); - return r; -} - -V3 v3fromv2(V2 a) -{ - V3 r; - r = v3(a.x, a.y, 0.0f); - return r; -} - -V3 v3fromv4(V4 a) -{ - V3 r; - r = v3(a.x, a.y, a.z); - return r; -} - -V3 invv3(V3 a) -{ - V3 r; - r = v3(-a.x, -a.y, -a.z); - return r; -} - -V3 addv3(V3 a, V3 b) -{ - V3 r; - r = v3(a.x+b.x, a.y+b.y, a.z+b.z); - return r; -} - -V3 subv3(V3 a, V3 b) -{ - V3 r; - r = v3(a.x-b.x, a.y-b.y, a.z-b.z); - return r; -} - -V3 scalefv3(V3 a, F32 s) -{ - V3 r; - r = v3(a.x*s, a.y*s, a.z*s); - return r; -} - -V3 scalev3(V3 a, V3 s) -{ - V3 r; - r = v3(a.x*s.x, a.y*s.y, a.z*s.z); - return r; -} - -F32 dotv3(V3 a, V3 b) -{ - F32 r; - r = a.x*b.x + a.y*b.y + a.z*b.z; - return r; -} - -V3 crossv3(V3 left, V3 right) -{ - V3 r; - r = v3((left.y*right.z-right.y*left.z), - (right.x*left.z-left.x*right.z), - (left.x*right.y-right.x*left.y)); - return r; -} - -F32 len2v3(V3 a) -{ - F32 r; - r = dotv3(a, a); - return r; -} - -F32 lenv3(V3 a) -{ - F32 r; - r = f32sqrt(len2v3(a)); - return r; -} - -V3 normv3(V3 a) -{ - F32 len; - V3 r; - - r = V3_ZERO; - len = lenv3(a); - if (len) - r = v3(a.x/len, a.y/len, a.z/len); - - return r; -} - -void printv3(V3 a) -{ - fprintf(stdout, "{%f, %f, %f}T\n", a.x, a.y, a.z); -} - -V4 v4(F32 x, F32 y, F32 z, F32 w) -{ - V4 r; - r.x = x; - r.y = y; - r.z = z; - r.w = w; - return r; -} - -V4 v4a(F32 x) -{ - V4 r; - r = v4(x, x, x, x); - return r; -} - -V4 v4fromv3(V3 a) -{ - V4 r; - r = v4(a.x, a.y, a.z, 0.0f); - return r; -} - -V4 invv4(V4 a) -{ - V4 r; - r = v4(-a.x, -a.y, -a.z, -a.w); - return r; -} - -V4 addv4(V4 a, V4 b) -{ - V4 r; - r = v4(a.x+b.x, a.y+b.y, a.z+b.z, a.w+b.w); - return r; -} - -V4 subv4(V4 a, V4 b) -{ - V4 r; - r = v4(a.x-b.x, a.y-b.y, a.z-b.z, a.w-b.w); - return r; -} - -V4 scalefv4(V4 a, F32 s) -{ - V4 r; - r = v4(a.x*s, a.y*s, a.z*s, a.w*s); - return r; -} - -V4 scalev4(V4 a, V4 s) -{ - V4 r; - r = v4(a.x*s.x, a.y*s.y, a.z*s.z, a.w*s.w); - return r; -} - -F32 dotv4(V4 a, V4 b) -{ - F32 r; - r = a.x*b.x+a.y*b.y+a.z*b.z+a.w*b.w; - return r; -} - -F32 len2v4(V4 a) -{ - F32 r; - r = dotv4(a, a); - return r; -} - -F32 lenv4(V4 a) -{ - F32 r; - r = f32sqrt(len2v4(a)); - return r; -} - -V4 normv4(V4 a) -{ - F32 len; - V4 r; - - r = V4_ZERO; - len = lenv4(a); - if (len) - r = v4(a.x/len, a.y/len, a.z/len, a.w/len); - - return r; -} - -void printv4(V4 a) -{ - fprintf(stdout, "{%f, %f, %f, %f}T\n", a.x, a.y, a.z, a.w); -} - -/* NOTE(pryazha): Matrices */ -F32 detmat4(MAT4 m) -{ - F32 r, m00minor, m01minor, m02minor, m03minor; - - F32 m00 = m.m0.x, m10 = m.m0.y, m20 = m.m0.z, m30 = m.m0.w; - F32 m01 = m.m1.x, m11 = m.m1.y, m21 = m.m1.z, m31 = m.m1.w; - F32 m02 = m.m2.x, m12 = m.m2.y, m22 = m.m2.z, m32 = m.m2.w; - F32 m03 = m.m3.x, m13 = m.m3.y, m23 = m.m3.z, m33 = m.m3.w; - - m00minor = ((m11*m22*m33)+(m12*m23*m31)+(m21*m32*m13)- - (m31*m22*m13)-(m21*m12*m33)-(m11*m32*m23)); - - m01minor = ((m10*m22*m33)+(m12*m23*m30)+(m20*m32*m13)- - (m13*m22*m30)-(m23*m32*m10)-(m12*m20*m33)); - - m02minor = ((m10*m21*m33)+(m20*m31*m13)+(m11*m23*m31)- - (m13*m21*m30)-(m23*m31*m10)-(m11*m20*m33)); - - m03minor = ((m10*m21*m32)+(m20*m31*m12)+(m11*m22*m30)- - (m12*m21*m30)-(m11*m20*m32)-(m22*m31*m10)); - - r = m00*m00minor + m01*m01minor - m02*m02minor + m03*m03minor; - - return r; -} - -MAT4 transpmat4(MAT4 m) -{ - MAT4 r; - - r = m; - - SWAP(F32, r.m0.y, r.m1.x); - SWAP(F32, r.m0.z, r.m2.x); - SWAP(F32, r.m0.w, r.m3.x); - - SWAP(F32, r.m1.z, r.m2.y); - SWAP(F32, r.m1.w, r.m3.y); - - SWAP(F32, r.m2.w, r.m3.z); - - return r; -} - -MAT4 mulmat4(MAT4 left, MAT4 right) -{ - F32 l00, l01, l02, l03; - F32 l10, l11, l12, l13; - F32 l20, l21, l22, l23; - F32 l30, l31, l32, l33; - - F32 r00, r01, r02, r03; - F32 r10, r11, r12, r13; - F32 r20, r21, r22, r23; - F32 r30, r31, r32, r33; - - MAT4 r; - - l00 = left.m0.x; l01 = left.m0.y; l02 = left.m0.z; l03 = left.m0.w; - l10 = left.m1.x; l11 = left.m1.y; l12 = left.m1.z; l13 = left.m1.w; - l20 = left.m2.x; l21 = left.m2.y; l22 = left.m2.z; l23 = left.m2.w; - l30 = left.m3.x; l31 = left.m3.y; l32 = left.m3.z; l33 = left.m3.w; - - r00 = right.m0.x; r01 = right.m0.y; r02 = right.m0.z; r03 = right.m0.w; - r10 = right.m1.x; r11 = right.m1.y; r12 = right.m1.z; r13 = right.m1.w; - r20 = right.m2.x; r21 = right.m2.y; r22 = right.m2.z; r23 = right.m2.w; - r30 = right.m3.x; r31 = right.m3.y; r32 = right.m3.z; r33 = right.m3.w; - - r.m0.x = l00*r00+l10*r01+l20*r02+l30*r03; - r.m0.y = l01*r00+l11*r01+l21*r02+l31*r03; - r.m0.z = l02*r00+l12*r01+l22*r02+l32*r03; - r.m0.w = l03*r00+l13*r01+l23*r02+l33*r03; - - r.m1.x = l00*r10+l10*r11+l20*r12+l30*r13; - r.m1.y = l01*r10+l11*r11+l21*r12+l31*r13; - r.m1.z = l02*r10+l12*r11+l22*r12+l32*r13; - r.m1.w = l03*r10+l13*r11+l23*r12+l33*r13; - - r.m2.x = l00*r20+l10*r21+l20*r22+l30*r23; - r.m2.y = l01*r20+l11*r21+l21*r22+l31*r23; - r.m2.z = l02*r20+l12*r21+l22*r22+l32*r23; - r.m2.w = l03*r20+l13*r21+l23*r22+l33*r23; - - r.m3.x = l00*r30+l10*r31+l20*r32+l30*r33; - r.m3.y = l01*r30+l11*r31+l21*r32+l31*r33; - r.m3.z = l02*r30+l12*r31+l22*r32+l32*r33; - r.m3.w = l03*r30+l13*r31+l23*r32+l33*r33; - - return r; -} - -MAT4 translmat4(MAT4 m, V3 v) -{ - MAT4 t, r; - - t = MAT4_IDENTITY; - t.m3.x = v.x; - t.m3.y = v.y; - t.m3.z = v.z; - r = mulmat4(t, m); - - return r; -} - -MAT4 scalemat4(MAT4 m, V3 v) -{ - MAT4 s, r; - - s = MAT4_IDENTITY; - s.m0.x = v.x; - s.m1.y = v.y; - s.m2.z = v.z; - r = mulmat4(s, m); - - return r; -} - -MAT4 rotateaxismat4(V3 x, V3 y, V3 z) -{ - MAT4 r; - - r = MAT4_IDENTITY; - r.m0 = v4(x.x, x.y, x.z, 0.0f); - r.m1 = v4(y.x, y.y, y.z, 0.0f); - r.m2 = v4(z.x, z.y, z.z, 0.0f); - - return r; -} - -/* - * NOTE(pryazha): Angles in degrees - * | 1 0 0 | | cy 0 sy | | cz -sz 0 | | cy*cz -cy*sz sy | - * | 0 cx -sx |*| 0 1 0 |*| sz cz 0 |=| sx*sy*cz+cx*sz -sx*sy*sz+cx*cz -sx*cy | - * | 0 sx cx | | -sy 0 cy | | 0 0 1 | | -cx*sy*cz+sx*sz cx*sy*sz+sx*cz cx*cy | - */ -MAT4 rotatemat4(MAT4 m, V3 angles) -{ - F32 angle, cx, sx, cy, sy, cz, sz; - MAT4 rotate, r; - V3 newx, newy, newz; - - angle = DEG2RAD*angles.x; - cx = f32cos(angle); - sx = f32sin(angle); - angle = DEG2RAD*angles.y; - cy = f32cos(angle); - sy = f32sin(angle); - angle = DEG2RAD*angles.z; - cz = f32cos(angle); - sz = f32sin(angle); - - newx = v3(cy*cz, sx*sy*cz+cx*sz, -cx*sy*cz+sx*sz); - newy = v3(-cy*sz, -sx*sy*sz+cx*cz, cx*sy*sz+sx*cz); - newz = v3(sy, -sx*cy, cx*cy); - rotate = rotateaxismat4(newx, newy, newz); - - r = mulmat4(rotate, m); - - return r; -} - -V4 mulmat4v4(MAT4 m, V4 v) -{ - V4 r; - - r = v4(m.m0.x*v.x+m.m1.x*v.y+m.m2.x*v.z+m.m3.x*v.w, - m.m0.y*v.x+m.m1.y*v.y+m.m2.y*v.z+m.m3.y*v.w, - m.m0.z*v.x+m.m1.z*v.y+m.m2.z*v.z+m.m3.z*v.w, - m.m0.w*v.x+m.m1.w*v.y+m.m2.w*v.z+m.m3.w*v.w); - - return r; -} - -void printmat4(MAT4 m) -{ - fprintf(stdout, "| %.4f %.4f %.4f %.4f |\n", m.m0.x, m.m1.x, m.m2.x, m.m3.x); - fprintf(stdout, "| %.4f %.4f %.4f %.4f |\n", m.m0.y, m.m1.y, m.m2.y, m.m3.y); - fprintf(stdout, "| %.4f %.4f %.4f %.4f |\n", m.m0.z, m.m1.z, m.m2.z, m.m3.z); - fprintf(stdout, "| %.4f %.4f %.4f %.4f |\n\n", m.m0.w, m.m1.w, m.m2.w, m.m3.w); -} diff --git a/prb_math.h b/prb_math.h index 52c6289..8f188f4 100644 --- a/prb_math.h +++ b/prb_math.h @@ -1,71 +1,444 @@ -#ifndef PRB_MATH_H -#define PRB_MATH_H - -/* NOTE(pryazha): Numeric */ -#define F32PI 3.14159265359f - -#define DEG2RAD F32PI/180.0f -#define RAD2DEG 182.0f/F32PI - -F32 f32sin(F32 a); -F32 f32cos(F32 a); -F32 f32tan(F32 a); -F32 f32sqrt(F32 a); - -/* NOTE(pryazha): Vectors */ -V2 v2(F32 x, F32 y); -V2 v2a(F32 x); -V2 invv2(V2 a); -V2 addv2(V2 a, V2 b); -V2 subv2(V2 a, V2 b); -V2 scalefv2(V2 a, F32 s); -V2 scalev2(V2 a, V2 s); -F32 dotv2(V2 a, V2 b); -F32 len2v2(V2 a); -F32 lenv2(V2 a); -V2 normv2(V2 a); -void printv2(V2 a); - -V3 v3(F32 x, F32 y, F32 z); -V3 v3a(F32 x); -V3 v3fromv2(V2 a); -V3 v3fromv4(V4 a); -V3 invv3(V3 a); -V3 addv3(V3 a, V3 b); -V3 subv3(V3 a, V3 b); -V3 scalefv3(V3 a, F32 s); -V3 scalev3(V3 a, V3 s); -F32 dotv3(V3 a, V3 b); -V3 crossv3(V3 l, V3 r); -F32 len2v3(V3 a); -F32 lenv3(V3 a); -V3 normv3(V3 a); -void printv3(V3 a); - -V4 v4(F32 x, F32 y, F32 z, F32 w); -V4 v4a(F32 x); -V4 v4fromv3(V3 a); -V4 invv4(V4 a); -V4 addv4(V4 a, V4 b); -V4 subv4(V4 a, V4 b); -V4 scalefv4(V4 a, F32 s); -V4 scalev4(V4 a, V4 s); -F32 dotv4(V4 a, V4 b); -F32 len2v4(V4 a); -F32 lenv4(V4 a); -V4 normv4(V4 a); -void printv4(V4 a); - -/* NOTE(pryazha): Matrices */ -F32 detmat4(MAT4 m); -MAT4 transpmat4(MAT4 m); -MAT4 mulmat4(MAT4 left, MAT4 right); -MAT4 translmat4(MAT4 m, V3 v); -MAT4 scalemat4(MAT4 m, V3 v); -MAT4 rotateaxismat4(V3 x, V3 y, V3 z); -/* NOTE(pryazha): Angles in degrees */ -MAT4 rotatemat4(MAT4 m, V3 angles); -V4 mulmat4v4(MAT4 m, V4 v); -void printmat4(MAT4 m); - -#endif /* PRB_MATH_H */ +#define V2_ZERO (v2){ 0.0f, 0.0f} +#define V2_ONE (v2){ 1.0f, 1.0f} +#define V2_RIGHT (v2){ 1.0f, 0.0f} +#define V2_UP (v2){ 0.0f, 1.0f} +#define V2_LEFT (v2){-1.0f, 0.0f} +#define V2_DOWN (v2){ 0.0f, -1.0f } + +#define V3_ZERO (v3){ 0.0f, 0.0f, 0.0f} +#define V3_ONE (v3){ 1.0f, 1.0f, 1.0f} +#define V3_RIGHT (v3){ 1.0f, 0.0f, 0.0f} +#define V3_UP (v3){ 0.0f, 1.0f, 0.0f} +#define V3_LEFT (v3){-1.0f, 0.0f, 0.0f} +#define V3_DOWN (v3){ 0.0f, -1.0f, 0.0f} +#define V3_FORWARD (v3){ 0.0f, 0.0f, 1.0f} +#define V3_BACKWARD (v3){ 0.0f, 0.0f, -1.0f} + +#define V4_ZERO (v4){0.0f, 0.0f, 0.0f, 0.0f} +#define V4_ONE (v4){1.0f, 1.0f, 1.0f, 1.0f} + +#define MAT4_IDENTITY (mat4){ \ + {1.0f, 0.0f, 0.0f, 0.0f}, \ + {0.0f, 1.0f, 0.0f, 0.0f}, \ + {0.0f, 0.0f, 1.0f, 0.0f}, \ + {0.0f, 0.0f, 0.0f, 1.0f}} + +#define F_PI 3.14159265359f + +#define deg2rad(angle) (F_PI/180.0f*(angle)) + +#define QUAT_IDENTITY (v4){0.0f, 0.0f, 0.0f, 1.0f} + +/* TODO(pryazha): Implement trigonometry functions */ +f32 fsin(f32 a) +{ + f32 result = sinf(a); + return result; +} + +f32 fcos(f32 a) +{ + f32 result = cosf(a); + return result; +} + +f32 ftan(f32 a) +{ + f32 result = tanf(a); + return result; +} + +f32 fsqrt(f32 a) +{ + f32 result = sqrtf(a); + return result; +} + +// vectors +v2 v2_fill(f32 x) +{ + v2 v = {x, x}; + return v; +} + +v2 v2_inv(v2 a) +{ + v2 v = {-a.x, -a.y}; + return v; +} + +v2 v2_add(v2 a, v2 b) +{ + v2 v = {a.x+b.x, a.y+b.y}; + return v; +} + +v2 v2_sub(v2 a, v2 b) +{ + v2 v = {a.x-b.x, a.y-b.y}; + return v; +} + +v2 v2_scalef(v2 a, f32 s) +{ + v2 v = {a.x*s, a.y*s}; + return v; +} + +v2 v2_scale(v2 a, v2 s) +{ + v2 v = {a.x*s.x, a.y*s.y}; + return v; +} + +f32 v2_dot(v2 a, v2 b) +{ + f32 v = a.x*b.x+a.y*b.y; + return v; +} + +f32 v2_len2(v2 a) +{ + f32 v = v2_dot(a, a); + return v; +} + +f32 v2_len(v2 a) +{ + f32 v = fsqrt(v2_len2(a)); + return v; +} + +v2 v2_norm(v2 a) +{ + v2 v = {0}; + f32 len = v2_len(a); + if (len) + v = (v2){a.x/len, a.y/len}; + return v; +} + +v3 v3_fill(f32 x) +{ + v3 v = {x, x, x}; + return v; +} + +v3 v3_from_v2(v2 a) +{ + v3 v = {a.x, a.y, 0.0f}; + return v; +} + +v3 v3_from_v4(v4 a) +{ + v3 v = {a.x, a.y, a.z}; + return v; +} + +v3 v3_inv(v3 a) +{ + v3 v = {-a.x, -a.y, -a.z}; + return v; +} + +v3 v3_add(v3 a, v3 b) +{ + v3 v = {a.x+b.x, a.y+b.y, a.z+b.z}; + return v; +} + +v3 v3_sub(v3 a, v3 b) +{ + v3 v = {a.x-b.x, a.y-b.y, a.z-b.z}; + return v; +} + +v3 v3_scalef(v3 a, f32 s) +{ + v3 v = {a.x*s, a.y*s, a.z*s}; + return v; +} + +v3 v3_scale(v3 a, v3 s) +{ + v3 v = {a.x*s.x, a.y*s.y, a.z*s.z}; + return v; +} + +f32 v3_dot(v3 a, v3 b) +{ + f32 v = a.x*b.x+a.y*b.y+a.z*b.z; + return v; +} + +v3 v3_cross(v3 l, v3 r) +{ + v3 v = {(l.y*r.z - r.y*l.z), (r.x*l.z - l.x*r.z), (l.x*r.y - r.x*l.y)}; + return v; +} + +f32 v3_len2(v3 a) +{ + f32 v = v3_dot(a, a); + return v; +} + +f32 v3_len(v3 a) +{ + f32 v = fsqrt(v3_len2(a)); + return v; +} + +v3 v3_norm(v3 a) +{ + v3 v = V3_ZERO; + f32 len = v3_len(a); + if (len) + v = (v3){a.x/len, a.y/len, a.z/len}; + return v; +} + +v4 v4_fill(f32 x) +{ + v4 v = {x, x, x, x}; + return v; +} + +v4 v4_from_v3(v3 a) +{ + v4 v = {a.x, a.y, a.z, 0.0f}; + return v; +} + +v4 v4_inv(v4 a) +{ + v4 v = {-a.x, -a.y, -a.z, -a.w}; + return v; +} + +v4 v4_add(v4 a, v4 b) +{ + v4 v = {a.x+b.x, a.y+b.y, a.z+b.z, a.w+b.w}; + return v; +} + +v4 v4_sub(v4 a, v4 b) +{ + v4 v = {a.x-b.x, a.y-b.y, a.z-b.z, a.w-b.w}; + return v; +} + +v4 v4_scalef(v4 a, f32 s) +{ + v4 v = {a.x*s, a.y*s, a.z*s, a.w*s}; + return v; +} + +v4 v4_scale(v4 a, v4 s) +{ + v4 v = {a.x*s.x, a.y*s.y, a.z*s.z, a.w*s.w}; + return v; +} + +f32 v4_dot(v4 a, v4 b) +{ + f32 v = a.x*b.x+a.y*b.y+a.z*b.z+a.w*b.w; + return v; +} + +f32 v4_len2(v4 a) +{ + f32 v = v4_dot(a, a); + return v; +} + +f32 v4_len(v4 a) +{ + f32 v = fsqrt(v4_len2(a)); + return v; +} + +v4 v4_norm(v4 a) +{ + v4 v = V4_ZERO; + f32 len = v4_len(a); + if (len) + v = (v4){a.x/len, a.y/len, a.z/len, a.w/len}; + return v; +} + +// matrices +f32 mat4_det(mat4 m) +{ + f32 m00 = m.c0.x, m10 = m.c0.y, m20 = m.c0.z, m30 = m.c0.w; + f32 m01 = m.c1.x, m11 = m.c1.y, m21 = m.c1.z, m31 = m.c1.w; + f32 m02 = m.c2.x, m12 = m.c2.y, m22 = m.c2.z, m32 = m.c2.w; + f32 m03 = m.c3.x, m13 = m.c3.y, m23 = m.c3.z, m33 = m.c3.w; + + f32 m00minor = ((m11*m22*m33)+(m12*m23*m31)+(m21*m32*m13)- + (m31*m22*m13)-(m21*m12*m33)-(m11*m32*m23)); + + f32 m01minor = ((m10*m22*m33)+(m12*m23*m30)+(m20*m32*m13)- + (m13*m22*m30)-(m23*m32*m10)-(m12*m20*m33)); + + f32 m02minor = ((m10*m21*m33)+(m20*m31*m13)+(m11*m23*m31)- + (m13*m21*m30)-(m23*m31*m10)-(m11*m20*m33)); + + f32 m03minor = ((m10*m21*m32)+(m20*m31*m12)+(m11*m22*m30)- + (m12*m21*m30)-(m11*m20*m32)-(m22*m31*m10)); + + f32 result = m00*m00minor+m01*m01minor-m02*m02minor+m03*m03minor; + + return result; +} + +mat4 mat4_transp(mat4 m) +{ + swap(f32, m.c0.y, m.c1.x); + swap(f32, m.c0.z, m.c2.x); + swap(f32, m.c0.w, m.c3.x); + + swap(f32, m.c1.z, m.c2.y); + swap(f32, m.c1.w, m.c3.y); + + swap(f32, m.c2.w, m.c3.z); + + return m; +} + +mat4 mat4_mul(mat4 left, mat4 right) +{ + f32 l00 = left.c0.x, l01 = left.c0.y, l02 = left.c0.z, l03 = left.c0.w; + f32 l10 = left.c1.x, l11 = left.c1.y, l12 = left.c1.z, l13 = left.c1.w; + f32 l20 = left.c2.x, l21 = left.c2.y, l22 = left.c2.z, l23 = left.c2.w; + f32 l30 = left.c3.x, l31 = left.c3.y, l32 = left.c3.z, l33 = left.c3.w; + + f32 r00 = right.c0.x, r01 = right.c0.y, r02 = right.c0.z, r03 = right.c0.w; + f32 r10 = right.c1.x, r11 = right.c1.y, r12 = right.c1.z, r13 = right.c1.w; + f32 r20 = right.c2.x, r21 = right.c2.y, r22 = right.c2.z, r23 = right.c2.w; + f32 r30 = right.c3.x, r31 = right.c3.y, r32 = right.c3.z, r33 = right.c3.w; + + mat4 result = { + { + l00*r00+l10*r01+l20*r02+l30*r03, + l01*r00+l11*r01+l21*r02+l31*r03, + l02*r00+l12*r01+l22*r02+l32*r03, + l03*r00+l13*r01+l23*r02+l33*r03 + }, + { + l00*r10+l10*r11+l20*r12+l30*r13, + l01*r10+l11*r11+l21*r12+l31*r13, + l02*r10+l12*r11+l22*r12+l32*r13, + l03*r10+l13*r11+l23*r12+l33*r13 + }, + { + l00*r20+l10*r21+l20*r22+l30*r23, + l01*r20+l11*r21+l21*r22+l31*r23, + l02*r20+l12*r21+l22*r22+l32*r23, + l03*r20+l13*r21+l23*r22+l33*r23 + }, + { + l00*r30+l10*r31+l20*r32+l30*r33, + l01*r30+l11*r31+l21*r32+l31*r33, + l02*r30+l12*r31+l22*r32+l32*r33, + l03*r30+l13*r31+l23*r32+l33*r33 + } + }; + + return result; +} + +mat4 mat4_make_transl(v3 v) +{ + mat4 translate = { + {1.0f, 0.0f, 0.0f, 0.0f}, + {0.0f, 1.0f, 0.0f, 0.0f}, + {0.0f, 0.0f, 1.0f, 0.0f}, + {v.x, v.y, v.z, 1.0f} + }; + return translate; +} + +mat4 mat4_make_scale(v3 v) +{ + mat4 scale = { + {v.x, 0.0f, 0.0f, 0.0f}, + {0.0f, v.y, 0.0f, 0.0f}, + {0.0f, 0.0f, v.z, 0.0f}, + {0.0f, 0.0f, 0.0f, 1.0f} + }; + return scale; +} + +mat4 mat4_make_rotate(v3 x, v3 y, v3 z) +{ + mat4 rotate = { + {x.x, x.y, x.z, 0.0f}, + {y.x, y.y, y.z, 0.0f}, + {z.x, z.y, z.z, 0.0f}, + {0.0f, 0.0f, 0.0f, 1.0f} + }; + return rotate; +} + +mat4 mat4_transl(mat4 m, v3 v) +{ + mat4 translate = mat4_make_transl(v); + mat4 result = mat4_mul(translate, m); + return result; +} + +mat4 mat4_scale(mat4 m, v3 v) +{ + mat4 scale = mat4_make_scale(v); + mat4 result = mat4_mul(scale, m); + return result; +} + +/* + * NOTE(pryazha): Angles in degrees + * | 1 0 0 | | cy 0 sy | | cz -sz 0 | | cy*cz -cy*sz sy | + * | 0 cx -sx |*| 0 1 0 |*| sz cz 0 |=| sx*sy*cz+cx*sz -sx*sy*sz+cx*cz -sx*cy | + * | 0 sx cx | | -sy 0 cy | | 0 0 1 | | -cx*sy*cz+sx*sz cx*sy*sz+sx*cz cx*cy | + */ +mat4 mat4_rotate(mat4 mat, v3 angles) +{ + f32 angle = deg2rad(angles.x); + f32 cx = fcos(angle); + f32 sx = fsin(angle); + angle = deg2rad(angles.y); + f32 cy = fcos(angle); + f32 sy = fsin(angle); + angle = deg2rad(angles.z); + f32 cz = fcos(angle); + f32 sz = fsin(angle); + + v3 x = {cy*cz, sx*sy*cz+cx*sz, -cx*sy*cz+sx*sz}; + v3 y = {-cy*sz, -sx*sy*sz+cx*cz, cx*sy*sz+sx*cz}; + v3 z = {sy, -sx*cy, cx*cy}; + mat4 rotate = mat4_make_rotate(x, y, z); + + mat4 result = mat4_mul(rotate, mat); + + return result; +} + +v4 mat4_v4_mul(mat4 m, v4 v) +{ + v4 result = { + m.c0.x*v.x+m.c1.x*v.y+m.c2.x*v.z+m.c3.x*v.w, + m.c0.y*v.x+m.c1.y*v.y+m.c2.y*v.z+m.c3.y*v.w, + m.c0.z*v.x+m.c1.z*v.y+m.c2.z*v.z+m.c3.z*v.w, + m.c0.w*v.x+m.c1.w*v.y+m.c2.w*v.z+m.c3.w*v.w + }; + return result; +} + +i32 in_rect(v2 pos, rect_t rect) +{ + i32 result = (pos.x > rect.start.x) && (pos.x < rect.end.x) && + (pos.y > rect.start.y) && (pos.y < rect.end.y); + return result; +} + diff --git a/prb_string.c b/prb_string.c deleted file mode 100644 index 06f4ed8..0000000 --- a/prb_string.c +++ /dev/null @@ -1,170 +0,0 @@ -/* NOTE(pryazha): Null-terminated strings */ - -/* TODO(pryazha): Move to another file specific to OS you're in */ -void sys_vprintf(const char *fmt, va_list args) -{ - vprintf(fmt, args); -} - -void sys_printf(const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - sys_vprintf(fmt, args); - va_end(args); -} - -/* NOTE(pryazha): Fixed-length strings */ - -FLS fls(U8 *p, U64 len) -{ - FLS r; - r.p = p; - r.len = len; - return r; -} - -FLS flsfromcstr(const char *cstr) -{ - U8 *p; - FLS r; - - p = (U8 *)cstr; - for (; *p; ++p); - r = flsrange((U8 *)cstr, p); - - return r; -} - -char *flstocstr(Arena *a, FLS s) -{ - U64 len; - char *cstr; - - len = s.len+1; - cstr = push_arena(a, len*sizeof(U8)); - MEMCPY(cstr, s.p, len*sizeof(U8)); - *(cstr+s.len) = 0; - - return cstr; -} - -FLS flsrange(U8 *st_arenat, U8 *end) -{ - FLS r; - r.p = st_arenat; - r.len = end-st_arenat; - return r; -} - -FLS flschopend(FLS s, U64 cnt) -{ - U64 len; - FLS r; - - len = s.len-CLAMPTOP(cnt, s.len); - r = fls(s.p, len); - - return r; -} - -FLS flschopstart(FLS s, U64 cnt) -{ - U64 clamped, len; - FLS r; - - clamped = CLAMPTOP(cnt, s.len); - len = s.len-CLAMPTOP(cnt, s.len); - r = fls(s.p+clamped, len); - - return r; -} - -FLS flspushfv(Arena *a, const char *fmt, va_list args) -{ - ASSERT(a); - - char tmp[1024]; - S32 n; - FLS r; - - n = vsnprintf(tmp, 1024, fmt, args); - - MEM0(&r, sizeof(FLS)); - - if (n > 0) { - r.p = push_arena(a, n); - MEMCPY(r.p, tmp, n); - r.len = n; - } - - return r; -} - -FLS flspushf(Arena *a, const char *fmt, ...) -{ - va_list args; - FLS r; - - va_start(args, fmt); - r = flspushfv(a, fmt, args); - va_end(args); - - return r; -} - -void flsprint(FLS s) -{ - ASSERT(s.p); - ASSERT(s.len); - - fwrite(s.p, sizeof(U8), s.len, stdout); -} - - -FLSList *flslist(Arena *a) -{ - FLSList *l; - - l = push_arena(a, sizeof(FLSList)); - MEM0(l, sizeof(FLSList)); - - return l; -} - -void flslistpush(Arena *a, FLSList *l, FLS s, B32 front) -{ - ASSERT(a); - ASSERT(l); - - FLSNode *n; - - n = push_arena(a, sizeof(FLSNode)); - n->str = s; - - if (front) - DLLPUSHFRONT(l->first, l->last, n); - else - DLLPUSHBACK(l->first, l->last, n); - l->len += s.len; - l->ncnt++; -} - -void flslistpushf(Arena *a, FLSList *l, B32 front, const char *fmt, ...) -{ - va_list args; - FLS str; - - va_start(args, fmt); - str = flspushfv(a, fmt, args); - va_end(args); - - flslistpush(a, l, str, front); -} - -void flslistprint(FLSList *l) -{ - FLSNode *n; - for (n = l->first; n; n = n->next) - flsprint(n->str); -} diff --git a/prb_string.h b/prb_string.h index 7df8246..344df11 100644 --- a/prb_string.h +++ b/prb_string.h @@ -1,40 +1,196 @@ -#ifndef PRB_STRING_H -#define PRB_STRING_H +void prb_memset(void *dest, i32 fill, u64 n) +{ + u8 *byte = dest; + while (n--) + *byte++ = fill; +} -/* NOTE(pryazha): I don't know wheter it's a good idea - * to keep regular and fixed-length strings together, but - * seems reasonable at the time. - */ +void prb_memmove(void *dest, const void *src, u64 size) +{ + u8 *byte_dest = dest; + const u8 *byte_src = src; + while (size--) + *byte_dest++ = *byte_src++; +} -/* NOTE(pryazha): Null-terminated strings */ +i32 prb_memeq(const void *p1, const void *p2, u64 size) +{ + const u8 *byte_p1 = p1; + const u8 *byte_p2 = p2; + while (size--) + if (*byte_p1++ != *byte_p2++) + return 0; + return 1; +} -void sys_vprintf(const char *fmt, va_list args); -void sys_printf(const char *fmt, ...); +i32 streq(const char *str1, const char *str2) +{ + if (!str1 || !str2) + return 0; + while (*str1++ == *str2++) + if (!*str1) + return 1; + return 0; +} -/* NOTE(pryazha): Fixed-length strings */ +// fixed length strings +#define str8lit(str) (str8_t){(u8 *)(str), sizeof(str) - 1} +#define str8exp(str) (i32)((str).len), ((str).ptr) -#define FLSLIT(s) fls((U8 *)(s), sizeof(s)-1) -#define FLSEXP(s) (int)((s).len), ((s).p) +#define MAX_FLS_BUFFER 1024 -FLS fls(U8 *p, U64 len); +typedef struct { + u8 *ptr; + u64 len; +} str8_t; -FLS flsfromcstr(const char *cstr); -char *flstocstr(Arena *a, FLS s); +typedef struct str8_node_t { + str8_t str; + struct str8_node_t *next; + struct str8_node_t *prev; +} str8_node_t; -FLS flsrange(U8 *start, U8 *end); -FLS flschopend(FLS s, U64 cnt); -FLS flschopstart(FLS s, U64 cnt); +typedef struct { + struct str8_node_t *first; + struct str8_node_t *last; + u64 len; + i32 cnt; +} str8_list_t; -FLS flspushfv(Arena *a, const char *fmt, va_list args); -FLS flspushf(Arena *a, const char *fmt, ...); +char *str8_to_cstr(arena_t *arena, str8_t str) +{ + u64 len = str.len + 1; + char *cstr = push_arena(arena, len); + prb_memmove(cstr, str.ptr, len); + cstr[str.len] = 0; + return cstr; +} -void flsprint(FLS s); +i32 str8eq(str8_t str1, str8_t str2) +{ + if (str1.len != str2.len) + return 0; + for (u64 i = 0; i < str1.len; ++i) + if (str1.ptr[i] != str2.ptr[i]) + return 0; + return 1; +} -FLSList *flslist(Arena *a); +u8 *str8ch(str8_t str, i32 c) +{ + for (u64 i = 0; i < str.len; ++i) + if (str.ptr[i] == c) + return str.ptr + i; + return 0; +} -void flslistpush(Arena *a, FLSList *l, FLS s, B32 front); -void flslistpushf(Arena *a, FLSList *l, B32 front, const char *fmt, ...); +u8 *str8rch(str8_t str, i32 c) +{ + for (u64 i = str.len - 1; i > 0; --i) + if (str.ptr[i] == c) + return str.ptr + i; + return 0; +} -void flslistprint(FLSList *l); +str8_t str8_range(u8 *start, u8 *end) +{ + assert(start); + assert(end); + assert(start < end); + str8_t result = {start, end - start}; + return result; +} -#endif /* PRB_STRING_H */ +str8_t str8_getdir(str8_t str) +{ + assert(str.len); + u8 *slash = str8rch(str, '/'); + if (!slash) + return str; + str8_t result = str8_range(str.ptr, slash); + return result; +} + +str8_t str8_pushfv(arena_t *arena, const char *format, va_list args) +{ + char tmp[MAX_FLS_BUFFER]; + i32 n = vsnprintf(tmp, MAX_FLS_BUFFER, format, args); + str8_t str = {0}; + if (n > 0) { + u8 *ptr = push_arena(arena, n); + prb_memmove(ptr, tmp, n); + str = (str8_t){ptr, n}; + str.ptr = ptr; + str.len = n; + } + return str; +} + +str8_t str8_pushf(arena_t *arena, const char *format, ...) +{ + va_list args; + va_start(args, format); + str8_t str = str8_pushfv(arena, format, args); + va_end(args); + return str; +} + +void str8_print(str8_t str) +{ + assert(str.ptr); + assert(str.len); + printf("%.*s", str8exp(str)); +} + +void str8_printf(const char *format, ...) +{ + + va_list args; + va_start(args, format); + arena_t temp = alloc_arena(MAX_FLS_BUFFER); + str8_t str = str8_pushfv(&temp, format, args); + va_end(args); + str8_print(str); + release_arena(&temp); +} + +void str8_list_push(arena_t *arena, str8_list_t *list, i32 front, str8_t str) +{ + str8_node_t *node = push_arena(arena, sizeof(str8_node_t)); + node->str = str; + if (front) + dllpushfront(list->first, list->last, node); + else + dllpushback(list->first, list->last, node); + list->len += str.len; + list->cnt++; +} + +void str8_list_pushf(arena_t *arena, str8_list_t *list, i32 front, const char *format, ...) +{ + va_list args; + va_start(args, format); + str8_t str = str8_pushfv(arena, format, args); + va_end(args); + str8_list_push(arena, list, front, str); +} + +/* TODO(pryazha): Check if that works :) */ +str8_t str8_list_join(arena_t *arena, str8_list_t *list) +{ + assert(arena); + assert(list); + str8_t str = {arena->memory + arena->used, 0}; + for (str8_node_t *node = list->first; node; node = node->next) { + u8 *ptr = push_arena(arena, node->str.len); + prb_memmove(ptr, node->str.ptr, node->str.len); + str.len += node->str.len; + } + return str; +} + +void str8_list_print(str8_list_t *list) +{ + for (str8_node_t *node = list->first; node; node = node->next) + str8_print(node->str); +} diff --git a/prb_sys.c b/prb_sys.c deleted file mode 100644 index 3747f18..0000000 --- a/prb_sys.c +++ /dev/null @@ -1,52 +0,0 @@ -/* TODO(pryazha): OS specific */ -FLS sys_read_entire_file_fls(Arena *a, const char *fname) -{ - FILE *f; - FLS r; - S32 len; - - MEM0STRUCT(&r); - - f = fopen(fname, "rb"); - if (!f) - return r; - - if (fseek(f, 0, SEEK_END) == -1) - goto error; - if ((len = ftell(f)) == -1) - goto error; - rewind(f); - - r.p = push_arena(a, len+1); - if (!fread(r.p, len, 1, f)) - goto error; - r.p[len] = 0; - r.len = len+1; - - fclose(f); - - return r; -error: - fclose(f); - return r; -} - -#define PRGE_MAX_PATH 256 - -char *sys_getbindir(Arena *a) -{ - U64 size; - char *path; - ssize_t len; - - size = PRGE_MAX_PATH*sizeof(char); - path = push_arena(a, size); - - len = readlink("/proc/self/exe", path, size-1); - if (len <= 0) - return path; - - path[len] = 0; - - return path; -} diff --git a/prb_sys.h b/prb_sys.h index 45a6d6d..7250758 100644 --- a/prb_sys.h +++ b/prb_sys.h @@ -1,7 +1,10 @@ -#ifndef PRB_OS_IO_H -#define PRB_OS_IO_H +#define MAX_PATH 512 -FLS sys_read_entire_file_fls(Arena *arena, const char *fname); -char *sys_getbindir(Arena *arena); +extern void *sys_alloc(u64 length); +extern void sys_free(void *memory, u64 length); -#endif /* PRB_OS_IO_H */ +// TODO(pryazha): Try using exit_failure, seems reasonable. I/O (file mainly) is a concern though +// extern void exit_failure(const char *format, ...); + +extern u64 sys_read_file(arena_t *arena, char **buffer, const char *filename); +extern char *sys_getbindir(arena_t *arena); diff --git a/prb_types.h b/prb_types.h index 8760513..bf6cd43 100644 --- a/prb_types.h +++ b/prb_types.h @@ -1,96 +1,49 @@ -#ifndef PRB_TYPES_H -#define PRB_TYPES_H +typedef int8_t i8; +typedef int16_t i16; +typedef int32_t i32; +typedef int64_t i64; -typedef int8_t S8; -typedef int16_t S16; -typedef int32_t S32; -typedef int64_t S64; +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; -typedef uint8_t U8; -typedef uint16_t U16; -typedef uint32_t U32; -typedef uint64_t U64; - -typedef S32 B32; - -typedef float F32; -typedef double F64; - -/* NOTE(pryazha): The library only use right-handed coordiante system (for now) */ - -#define V2_ZERO (V2){ 0.0f, 0.0f } -#define V2_ONE (V2){ 1.0f, 1.0f } -#define V2_RIGHT (V2){ 1.0f, 0.0f } -#define V2_UP (V2){ 0.0f, 1.0f } -#define V2_LEFT (V2){-1.0f, 0.0f } -#define V2_DOWN (V2){ 0.0f, -1.0f } +typedef float f32; +typedef double f64; typedef struct { - F32 x; - F32 y; -} V2; - -#define V3_ZERO (V3){ 0.0f, 0.0f, 0.0f } -#define V3_ONE (V3){ 1.0f, 1.0f, 1.0f } -#define V3_RIGHT (V3){ 1.0f, 0.0f, 0.0f } -#define V3_UP (V3){ 0.0f, 1.0f, 0.0f } -#define V3_LEFT (V3){-1.0f, 0.0f, 0.0f } -#define V3_DOWN (V3){ 0.0f, -1.0f, 0.0f } -#define V3_FORWARD (V3){ 0.0f, 0.0f, 1.0f } -#define V3_BACKWARD (V3){ 0.0f, 0.0f, -1.0f } + f32 x; + f32 y; +} v2; typedef struct { - F32 x; - F32 y; - F32 z; -} V3; - -#define V4_ZERO (V4){ 0.0f, 0.0f, 0.0f, 0.0f } -#define V4_ONE (V4){ 1.0f, 1.0f, 1.0f, 1.0f } + f32 x; + f32 y; + f32 z; +} v3; typedef struct { - F32 x; - F32 y; - F32 z; - F32 w; -} V4; - -#define MAT4_IDENTITY (MAT4) { \ - { 1.0f, 0.0f, 0.0f, 0.0f }, \ - { 0.0f, 1.0f, 0.0f, 0.0f }, \ - { 0.0f, 0.0f, 1.0f, 0.0f }, \ - { 0.0f, 0.0f, 0.0f, 1.0f } } + f32 x; + f32 y; + f32 z; + f32 w; +} v4; +// column-major typedef struct { - V4 m0; - V4 m1; - V4 m2; - V4 m3; -} MAT4; + v4 c0; + v4 c1; + v4 c2; + v4 c3; +} mat4; typedef struct { - U8 *mem; - U64 cap; - U64 used; -} Arena; - -/* NOTE(pryazha): Fixed-length string */ -typedef struct { - U8 *p; - U64 len; -} FLS; - -typedef struct FLSNode { - FLS str; - struct FLSNode *next; - struct FLSNode *prev; -} FLSNode; + v2 start; + v2 end; +} rect_t; typedef struct { - struct FLSNode *first; - struct FLSNode *last; - U64 len; - U32 ncnt; -} FLSList; - -#endif /* PRB_TYPES_H */ + void *memory; + u64 capacity; + u64 used; +} arena_t; diff --git a/prb_windows.h b/prb_windows.h new file mode 100644 index 0000000..aec7e9b --- /dev/null +++ b/prb_windows.h @@ -0,0 +1,75 @@ +void *sys_alloc(u64 length) +{ + assert(length); + void *result = VirtualAlloc(0, length, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE); + return result; +} + +void sys_free(void *memory, u64 length) +{ + assert(memory); + assert(length); + assert(VirtualFree(memory, 0, MEM_RELEASE)); +} + +u64 sys_read_file(arena_t *arena, char **buffer, const char *filename) +{ + *buffer = 0; + + HANDLE file = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, + 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); + if (file == INVALID_HANDLE_VALUE) { + printf("error: failed to open file \"%s\"\n", filename); + return 0; + } + + LARGE_INTEGER lisize; + if (!GetFileSizeEx(file, &lisize)) { + printf("error: failed to get size of the file \"%s\"", filename); + CloseHandle(file); + return 0; + } + + u64 size = lisize.QuadPart; + if (!size) { + printf("error: file \"%s\" is empty", filename); + CloseHandle(file); + return 0; + } + + *buffer = push_arena(arena, size + 1); + + DWORD bytes_read; + if (!ReadFile(file, *buffer, size, &bytes_read, 0)) { + CloseHandle(file); + pop_arena(arena, size); + printf("error: failed to read file \"%s\", bytes read: %lu\n", filename, bytes_read); + return 0; + } + CloseHandle(file); + + *(*buffer + size) = 0; + + return size + 1; +} + +char *sys_getbindir(arena_t *arena) +{ + char path[MAX_PATH]; + u32 len = GetModuleFileName(0, path, MAX_PATH); + if (!len) { + printf("error: failed to get file path\n"); + return 0; + } + + char *dir = strrchr(path, '\\'); + assert(dir); + assert(dir > path); + + len = dir - path; + dir = push_arena(arena, len + 1); + prb_memmove(dir, path, len); + dir[len] = 0; + + return dir; +} -- cgit v1.2.3-70-g09d2