From 3a1fefc931cdc2b8cb661a5e43e3ca00a4b6b7dc Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 24 May 2016 17:00:46 +0100 Subject: [PATCH] Improve file io & gbglColour --- README.md | 4 +- gb.h | 725 +++++++++++++++++++++++------------------------------- gb_gl.h | 133 +++++++--- 3 files changed, 404 insertions(+), 458 deletions(-) diff --git a/README.md b/README.md index ecfa308..8506a02 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,9 @@ gb single-file public domain libraries for C & C++ library | latest version | category | description ----------------|----------------|----------|------------- -**gb.h** | 0.19 | misc | Helper library (Standard library _improvement_) +**gb.h** | 0.20 | misc | Helper library (Standard library _improvement_) **gb_math.h** | 0.06f | math | Vector math library geared towards game development -**gb_gl.h** | 0.04e | graphics | OpenGL Helper Library +**gb_gl.h** | 0.05 | graphics | OpenGL Helper Library **gb_string.h** | 0.95a | strings | A better string library (this is built into gb.h too with custom allocator support!) **gb_ini.h** | 0.93 | misc | Simple ini file loader library **gb_regex.h** | 0.01d | regex | Highly experimental regular expressions library diff --git a/gb.h b/gb.h index 5754a1a..1ce655a 100644 --- a/gb.h +++ b/gb.h @@ -1,4 +1,4 @@ -/* gb.h - v0.19 - Ginger Bill's C Helper Library - public domain +/* gb.h - v0.20 - Ginger Bill's C Helper Library - public domain - no warranty implied; use at your own risk This is a single header file with a bunch of useful stuff @@ -34,8 +34,10 @@ CREDITS TODOS - Remove CRT dependency for people who want that - But do I really? + - Or make it only depend on the really needed stuff? - Older compiler support? - How old do you wanna go? + - Only support C90+extension and C99 not pure C89. - File handling - All files to be UTF-8 (even on windows) - Better Virtual Memory handling @@ -44,7 +46,6 @@ TODOS - Better UTF support and conversion - Free List, best fit rather than first fit - More date & time functions - - Platform Layer? */ @@ -83,15 +84,13 @@ extern "C" { #endif #endif -#if defined(_WIN32) || defined(_WIN64) - #if defined(_WIN64) - #ifndef GB_ARCH_64_BIT - #define GB_ARCH_64_BIT 1 - #endif - #else - #ifndef GB_ARCH_32_BIT - #define GB_ARCH_32_BIT 1 - #endif +#if defined(_WIN64) + #ifndef GB_ARCH_64_BIT + #define GB_ARCH_64_BIT 1 + #endif +#elif defined(_WIN32) + #ifndef GB_ARCH_32_BIT + #define GB_ARCH_32_BIT 1 #endif #endif @@ -110,6 +109,7 @@ extern "C" { #ifndef GB_EDIAN_ORDER #define GB_EDIAN_ORDER + // TODO(bill): Is the a good way or is it better to test for certain compilers and macros? #define GB_IS_BIG_EDIAN (!*(u8*)&(u16){1}) #define GB_IS_LITTLE_EDIAN (!GB_IS_BIG_EDIAN) #endif @@ -286,6 +286,8 @@ GB_STATIC_ASSERT(sizeof(usize) == sizeof(isize)); typedef intptr_t intptr; #endif +GB_STATIC_ASSERT(sizeof(uintptr) == sizeof(intptr)); + typedef float f32; typedef double f64; @@ -360,11 +362,8 @@ typedef i32 b32; // NOTE(bill): Prefer this!!! #define F64_MIN 2.2250738585072014e-308 #define F64_MAX 1.7976931348623157e+308 - #endif - - #ifndef NULL #if defined(__cplusplus) #if __cplusplus >= 201103L @@ -377,7 +376,6 @@ typedef i32 b32; // NOTE(bill): Prefer this!!! #endif #endif - // TODO(bill): Is this enough to get inline working? #if !defined(__cplusplus) #if defined(_MSC_VER) && _MSC_VER <= 1800 @@ -389,7 +387,6 @@ typedef i32 b32; // NOTE(bill): Prefer this!!! #endif #endif - #if !defined(gb_restrict) #if defined(_MSC_VER) #define gb_restrict __restrict @@ -427,7 +424,6 @@ typedef i32 b32; // NOTE(bill): Prefer this!!! #define cast(Type) (Type) #endif - // NOTE(bill): Because a signed sizeof is more useful #ifndef gb_size_of #define gb_size_of(x) (isize)(sizeof(x)) @@ -605,7 +601,7 @@ extern "C++" { #ifndef GB_DEBUG_TRAP #if defined(_MSC_VER) #if _MSC_VER < 1300 - #define GB_DEBUG_TRAP() __asm int 3; // Trap to debugger! + #define GB_DEBUG_TRAP() __asm int 3 /* Trap to debugger! */ #else #define GB_DEBUG_TRAP() __debugbreak() #endif @@ -1218,16 +1214,16 @@ Advantages: * gb strings can be passed to C-style string functions without accessing a struct member of calling a function, i.e. - printf("%s\n", gb_str); + gb_printf("%s\n", gb_str); Many other libraries do either of these: - printf("%s\n", string->cstr); - printf("%s\n", get_cstring(string)); + gb_printf("%s\n", string->cstr); + gb_printf("%s\n", get_cstring(string)); * You can access each character just like a C-style string: - printf("%c %c\n", str[0], str[13]); + gb_printf("%c %c\n", str[0], str[13]); * gb strings are singularly allocated. The meta-data is next to the character array which is better for the cache. @@ -1242,34 +1238,31 @@ Disadvantages: */ #if 0 -#include -#include - #define GB_IMPLEMENTATION #include "gb.h" - int main(int argc, char **argv) { +int main(int argc, char **argv) { gbString str = gb_string_make("Hello"); gbString other_str = gb_string_make_length(", ", 2); str = gb_string_append(str, other_str); str = gb_string_appendc(str, "world!"); - printf("%s\n", str); // Hello, world! + gb_printf("%s\n", str); // Hello, world! - printf("str length = %d\n", gb_string_length(str)); + gb_printf("str length = %d\n", gb_string_length(str)); str = gb_string_set(str, "Potato soup"); - printf("%s\n", str); // Potato soup + gb_printf("%s\n", str); // Potato soup str = gb_string_set(str, "Hello"); other_str = gb_string_set(other_str, "Pizza"); if (gb_strings_are_equal(str, other_str)) - printf("Not called\n"); + gb_printf("Not called\n"); else - printf("Called\n"); + gb_printf("Called\n"); str = gb_string_set(str, "Ab.;!...AHello World ??"); str = gb_string_trim(str, "Ab.;!. ?"); - printf("%s\n", str); // "Hello World" + gb_printf("%s\n", str); // "Hello World" gb_string_free(str); gb_string_free(other_str); @@ -1548,7 +1541,7 @@ GB_EXTERN u64 gb_murmur64_seed(void const *data, isize len, u64 seed); // // PREFIX - a prefix for function prototypes e.g. extern, static, etc. // NAME - Name of the Hash Table -// N - the name will prefix function names +// FUNC - the name will prefix function names // VALUE - the type of the value to be stored // // NOTE(bill): This also allows for a multi-valued keys with the multi_* functions @@ -1563,21 +1556,21 @@ typedef struct gbHashTableFindResult { } gbHashTableFindResult; #define GB__INVALID_FIND_RESULT {-1, -1, -1} -#define GB_TABLE(PREFIX, NAME, N, VALUE) \ - GB_TABLE_DECLARE(PREFIX, NAME, N, VALUE) \ - GB_TABLE_DEFINE(NAME, N, VALUE) \ +#define GB_TABLE(PREFIX, NAME, FUNC, VALUE) \ + GB_TABLE_DECLARE(PREFIX, NAME, FUNC, VALUE) \ + GB_TABLE_DEFINE(NAME, FUNC, VALUE) \ #if defined(_MSC_VER) -#define GB_TABLE_DEFINE(NAME, N, VALUE) \ +#define GB_TABLE_DEFINE(NAME, FUNC, VALUE) \ __pragma(warning(push)); \ __pragma(warning(disable:4127)); \ - GB_TABLE_DEFINE_(NAME, N, VALUE); \ + GB_TABLE_DEFINE_(NAME, FUNC, VALUE); \ __pragma(warning(pop)); #else -#define GB_TABLE_DEFINE(NAME, N, VALUE) GB_TABLE_DEFINE_(NAME, N, VALUE) +#define GB_TABLE_DEFINE(NAME, FUNC, VALUE) GB_TABLE_DEFINE_(NAME, FUNC, VALUE) #endif -#define GB_TABLE_DECLARE(PREFIX, NAME, N, VALUE) \ +#define GB_TABLE_DECLARE(PREFIX, NAME, FUNC, VALUE) \ typedef struct GB_JOIN2(NAME, Entry) { \ u64 key; \ isize next; \ @@ -1589,38 +1582,38 @@ typedef struct NAME { \ gbArray(GB_JOIN2(NAME, Entry)) entries; \ } NAME; \ \ -PREFIX void GB_JOIN2(N,init) (NAME *h, gbAllocator a); \ -PREFIX void GB_JOIN2(N,free) (NAME *h); \ -PREFIX void GB_JOIN2(N,clear) (NAME *h); \ -PREFIX b32 GB_JOIN2(N,has) (NAME const *h, u64 key); \ -PREFIX VALUE GB_JOIN2(N,get) (NAME const *h, u64 key, VALUE default_value); \ -PREFIX void GB_JOIN2(N,set) (NAME *h, u64 key, VALUE value); \ -PREFIX void GB_JOIN2(N,remove) (NAME *h, u64 key); \ -PREFIX void GB_JOIN2(N,reserve)(NAME *h, isize capacity); \ +PREFIX void GB_JOIN2(FUNC,init) (NAME *h, gbAllocator a); \ +PREFIX void GB_JOIN2(FUNC,free) (NAME *h); \ +PREFIX void GB_JOIN2(FUNC,clear) (NAME *h); \ +PREFIX b32 GB_JOIN2(FUNC,has) (NAME const *h, u64 key); \ +PREFIX VALUE GB_JOIN2(FUNC,get) (NAME const *h, u64 key, VALUE default_value); \ +PREFIX void GB_JOIN2(FUNC,set) (NAME *h, u64 key, VALUE value); \ +PREFIX void GB_JOIN2(FUNC,remove) (NAME *h, u64 key); \ +PREFIX void GB_JOIN2(FUNC,reserve)(NAME *h, isize capacity); \ \ /* NOTE(bill): multi-valued keys functions */ \ -PREFIX void GB_JOIN2(N,multi_get) (NAME const *h, u64 key, VALUE *values, isize count); \ -PREFIX isize GB_JOIN2(N,multi_count) (NAME const *h, u64 key); \ -PREFIX void GB_JOIN2(N,multi_insert) (NAME *h, u64 key, isize value); \ -PREFIX void GB_JOIN2(N,multi_remove_entry)(NAME *h, GB_JOIN2(NAME, Entry) const *e); \ -PREFIX void GB_JOIN2(N,multi_remove_all) (NAME *h, u64 key); \ +PREFIX void GB_JOIN2(FUNC,multi_get) (NAME const *h, u64 key, VALUE *values, isize count); \ +PREFIX isize GB_JOIN2(FUNC,multi_count) (NAME const *h, u64 key); \ +PREFIX void GB_JOIN2(FUNC,multi_insert) (NAME *h, u64 key, isize value); \ +PREFIX void GB_JOIN2(FUNC,multi_remove_entry)(NAME *h, GB_JOIN2(NAME, Entry) const *e); \ +PREFIX void GB_JOIN2(FUNC,multi_remove_all) (NAME *h, u64 key); \ \ -PREFIX GB_JOIN2(NAME, Entry) const *GB_JOIN2(N,multi_find_first_entry)(NAME const *h, u64 key); \ -PREFIX GB_JOIN2(NAME, Entry) const *GB_JOIN2(N,multi_find_next_entry) (NAME const *h, GB_JOIN2(NAME, Entry) const *e); \ +PREFIX GB_JOIN2(NAME, Entry) const *GB_JOIN2(FUNC,multi_find_first_entry)(NAME const *h, u64 key); \ +PREFIX GB_JOIN2(NAME, Entry) const *GB_JOIN2(FUNC,multi_find_next_entry) (NAME const *h, GB_JOIN2(NAME, Entry) const *e); \ -#define GB_TABLE_DEFINE_(NAME, N, VALUE) \ -gb_inline void GB_JOIN2(N,init)(NAME *h, gbAllocator a) { \ +#define GB_TABLE_DEFINE_(NAME, FUNC, VALUE) \ +gb_inline void GB_JOIN2(FUNC,init)(NAME *h, gbAllocator a) { \ gb_array_init(h->hashes, a); \ gb_array_init(h->entries, a); \ } \ -gb_inline void GB_JOIN2(N,free)(NAME *h) { \ +gb_inline void GB_JOIN2(FUNC,free)(NAME *h) { \ gb_array_free(&h->hashes); \ gb_array_free(&h->entries); \ } \ -gbHashTableFindResult GB_JOIN2(N,_find_result_from_key)(NAME const *h, u64 key) { \ +gbHashTableFindResult GB_JOIN2(FUNC,_find_result_from_key)(NAME const *h, u64 key) { \ gbHashTableFindResult fr = GB__INVALID_FIND_RESULT; \ if (gb_array_count(h->hashes) == 0) \ return fr; \ @@ -1634,16 +1627,16 @@ gbHashTableFindResult GB_JOIN2(N,_find_result_from_key)(NAME const *h, u64 key) } \ return fr; \ } \ -gb_inline b32 GB_JOIN2(N,has)(NAME const *h, u64 key) { \ - return GB_JOIN2(N,_find_result_from_key)(h, key).entry_index >= 0; \ +gb_inline b32 GB_JOIN2(FUNC,has)(NAME const *h, u64 key) { \ + return GB_JOIN2(FUNC,_find_result_from_key)(h, key).entry_index >= 0; \ } \ -gb_inline VALUE GB_JOIN2(N,get)(NAME const *h, u64 key, VALUE default_value) { \ - isize index = GB_JOIN2(N,_find_result_from_key)(h, key).entry_index; \ +gb_inline VALUE GB_JOIN2(FUNC,get)(NAME const *h, u64 key, VALUE default_value) { \ + isize index = GB_JOIN2(FUNC,_find_result_from_key)(h, key).entry_index; \ if (index < 0) \ return default_value; \ return h->entries[index].value; \ } \ -gb_internal gb_inline isize GB_JOIN2(N,_add_entry)(NAME *h, u64 key) { \ +gb_internal gb_inline isize GB_JOIN2(FUNC,_add_entry)(NAME *h, u64 key) { \ isize i = gb_array_count(h->entries); \ GB_JOIN2(NAME,Entry) e = {0}; \ e.key = key; \ @@ -1651,50 +1644,50 @@ gb_internal gb_inline isize GB_JOIN2(N,_add_entry)(NAME *h, u64 key) { \ gb_array_append(h->entries, e); \ return i; \ } \ -gb_internal gb_inline isize GB_JOIN2(N,_is_full)(NAME *h) { \ +gb_internal gb_inline isize GB_JOIN2(FUNC,_is_full)(NAME *h) { \ f64 const MAXIMUM_LOAD_COEFFICIENT = 0.85; \ return gb_array_count(h->entries) >= MAXIMUM_LOAD_COEFFICIENT * gb_array_count(h->hashes); \ } \ -gb_internal gb_inline void GB_JOIN2(N,_table_grow)(NAME *h); \ -gb_inline void GB_JOIN2(N,multi_insert)(NAME *h, u64 key, VALUE value) { \ +gb_internal gb_inline void GB_JOIN2(FUNC,_table_grow)(NAME *h); \ +gb_inline void GB_JOIN2(FUNC,multi_insert)(NAME *h, u64 key, VALUE value) { \ gbHashTableFindResult fr; \ isize next; \ if (gb_array_count(h->hashes) == 0) \ - GB_JOIN2(N,_table_grow)(h); \ - fr = GB_JOIN2(N,_find_result_from_key)(h, key); \ - next = GB_JOIN2(N,_add_entry)(h, key); \ + GB_JOIN2(FUNC,_table_grow)(h); \ + fr = GB_JOIN2(FUNC,_find_result_from_key)(h, key); \ + next = GB_JOIN2(FUNC,_add_entry)(h, key); \ if (fr.data_prev < 0) \ h->hashes[fr.hash_index] = next; \ else \ h->entries[fr.data_prev].next = next; \ h->entries[next].next = fr.entry_index; \ h->entries[next].value = value; \ - if (GB_JOIN2(N,_is_full)(h)) \ - GB_JOIN2(N,_table_grow)(h); \ + if (GB_JOIN2(FUNC,_is_full)(h)) \ + GB_JOIN2(FUNC,_table_grow)(h); \ } \ -gb_inline void GB_JOIN2(N,multi_get)(NAME const *h, u64 key, VALUE *values, isize count) { \ +gb_inline void GB_JOIN2(FUNC,multi_get)(NAME const *h, u64 key, VALUE *values, isize count) { \ isize i = 0; \ - GB_JOIN2(NAME,Entry) const *e = GB_JOIN2(N,multi_find_first_entry)(h, key); \ + GB_JOIN2(NAME,Entry) const *e = GB_JOIN2(FUNC,multi_find_first_entry)(h, key); \ while (e && count --> 0) { \ values[i++] = e->value; \ - e = GB_JOIN2(N,multi_find_next_entry)(h, e); \ + e = GB_JOIN2(FUNC,multi_find_next_entry)(h, e); \ } \ } \ -gb_inline isize GB_JOIN2(N,multi_count)(NAME const *h, u64 key) { \ +gb_inline isize GB_JOIN2(FUNC,multi_count)(NAME const *h, u64 key) { \ isize count = 0; \ - GB_JOIN2(NAME,Entry) const *e = GB_JOIN2(N,multi_find_first_entry)(h, key); \ + GB_JOIN2(NAME,Entry) const *e = GB_JOIN2(FUNC,multi_find_first_entry)(h, key); \ while (e) { \ count++; \ - e = GB_JOIN2(N,multi_find_next_entry)(h, e); \ + e = GB_JOIN2(FUNC,multi_find_next_entry)(h, e); \ } \ return count; \ } \ -GB_JOIN2(NAME,Entry) const *GB_JOIN2(N,multi_find_first_entry)(NAME const *h, u64 key) { \ - isize index = GB_JOIN2(N,_find_result_from_key)(h, key).entry_index; \ +GB_JOIN2(NAME,Entry) const *GB_JOIN2(FUNC,multi_find_first_entry)(NAME const *h, u64 key) { \ + isize index = GB_JOIN2(FUNC,_find_result_from_key)(h, key).entry_index; \ if (index < 0) return NULL; \ return &h->entries[index]; \ } \ -GB_JOIN2(NAME,Entry) const *GB_JOIN2(N,multi_find_next_entry)(NAME const *h, GB_JOIN2(NAME,Entry) const *e) { \ +GB_JOIN2(NAME,Entry) const *GB_JOIN2(FUNC,multi_find_next_entry)(NAME const *h, GB_JOIN2(NAME,Entry) const *e) { \ if (e) { \ isize index = e->next; \ while (index >= 0) { \ @@ -1705,7 +1698,7 @@ GB_JOIN2(NAME,Entry) const *GB_JOIN2(N,multi_find_next_entry)(NAME const *h, GB_ } \ return NULL; \ } \ -void GB_JOIN2(N,_erase_find_result)(NAME *h, gbHashTableFindResult fr) { \ +void GB_JOIN2(FUNC,_erase_find_result)(NAME *h, gbHashTableFindResult fr) { \ if (fr.data_prev < 0) \ h->hashes[fr.hash_index] = h->entries[fr.entry_index].next; \ else \ @@ -1714,14 +1707,14 @@ void GB_JOIN2(N,_erase_find_result)(NAME *h, gbHashTableFindResult fr) { \ if (fr.entry_index != gb_array_count(h->entries)) { \ gbHashTableFindResult last; \ h->entries[fr.entry_index] = h->entries[gb_array_count(h->entries)]; \ - last = GB_JOIN2(N,_find_result_from_key)(h, h->entries[fr.entry_index].key); \ + last = GB_JOIN2(FUNC,_find_result_from_key)(h, h->entries[fr.entry_index].key); \ if (last.data_prev < 0) \ h->hashes[last.hash_index] = fr.entry_index; \ else \ h->entries[last.entry_index].next = fr.entry_index; \ } \ } \ -gb_inline void GB_JOIN2(N,multi_remove_entry)(NAME *h, GB_JOIN2(NAME,Entry) const *e) { \ +gb_inline void GB_JOIN2(FUNC,multi_remove_entry)(NAME *h, GB_JOIN2(NAME,Entry) const *e) { \ gbHashTableFindResult fr = GB__INVALID_FIND_RESULT; \ if (gb_array_count(h->hashes) && e) { \ fr.hash_index = e->key % gb_array_count(h->hashes); \ @@ -1734,63 +1727,63 @@ gb_inline void GB_JOIN2(N,multi_remove_entry)(NAME *h, GB_JOIN2(NAME,Entry) cons } \ } \ if (fr.entry_index >= 0) \ - GB_JOIN2(N,_erase_find_result)(h, fr); \ + GB_JOIN2(FUNC,_erase_find_result)(h, fr); \ } \ -gb_inline void GB_JOIN2(N,multi_remove_all)(NAME *h, u64 key) { \ - while (GB_JOIN2(N,has)(h, key)) \ - GB_JOIN2(N,remove)(h, key); \ +gb_inline void GB_JOIN2(FUNC,multi_remove_all)(NAME *h, u64 key) { \ + while (GB_JOIN2(FUNC,has)(h, key)) \ + GB_JOIN2(FUNC,remove)(h, key); \ } \ -void GB_JOIN2(N,_rehash)(NAME *h, isize new_capacity) { \ +void GB_JOIN2(FUNC,_rehash)(NAME *h, isize new_capacity) { \ NAME nh, empty; \ isize i; \ - GB_JOIN2(N,init)(&nh, gb_array_allocator(h->hashes)); \ + GB_JOIN2(FUNC,init)(&nh, gb_array_allocator(h->hashes)); \ gb_array_resize(nh.hashes, new_capacity); \ gb_array_reserve(nh.entries, gb_array_count(h->entries)); \ for (i = 0; i < new_capacity; i++) \ nh.hashes[i] = -1; \ for (i = 0; i < gb_array_count(h->entries); i++) { \ GB_JOIN2(NAME,Entry) *e = &h->entries[i]; \ - GB_JOIN2(N,multi_insert)(&nh, e->key, e->value); \ + GB_JOIN2(FUNC,multi_insert)(&nh, e->key, e->value); \ } \ - GB_JOIN2(N,init)(&empty, gb_array_allocator(h->hashes)); \ - GB_JOIN2(N,free)(h); \ + GB_JOIN2(FUNC,init)(&empty, gb_array_allocator(h->hashes)); \ + GB_JOIN2(FUNC,free)(h); \ gb_memcopy(&nh, &h, gb_size_of(NAME)); \ gb_memcopy(&empty, &nh, gb_size_of(NAME)); \ } \ -gb_internal gb_inline void GB_JOIN2(N,_table_grow)(NAME *h) { \ +gb_internal gb_inline void GB_JOIN2(FUNC,_table_grow)(NAME *h) { \ isize new_capacity = GB_ARRAY_GROW_FORMULA(gb_array_count(h->entries)); \ - GB_JOIN2(N,_rehash)(h, new_capacity); \ + GB_JOIN2(FUNC,_rehash)(h, new_capacity); \ } \ -isize GB_JOIN2(N,_find_or_make_entry)(NAME *h, u64 key) { \ +isize GB_JOIN2(FUNC,_find_or_make_entry)(NAME *h, u64 key) { \ isize index; \ - gbHashTableFindResult fr = GB_JOIN2(N,_find_result_from_key)(h, key); \ + gbHashTableFindResult fr = GB_JOIN2(FUNC,_find_result_from_key)(h, key); \ if (fr.entry_index >= 0) \ return fr.entry_index; \ - index = GB_JOIN2(N,_add_entry)(h, key); \ + index = GB_JOIN2(FUNC,_add_entry)(h, key); \ if (fr.data_prev < 0) \ h->hashes[fr.hash_index] = index; \ else \ h->entries[fr.data_prev].next = index; \ return index; \ } \ -gb_inline void GB_JOIN2(N,set)(NAME *h, u64 key, isize value) { \ +gb_inline void GB_JOIN2(FUNC,set)(NAME *h, u64 key, isize value) { \ isize i; \ if (gb_array_count(h->hashes) == 0) \ - GB_JOIN2(N,_table_grow)(h); \ - i = GB_JOIN2(N,_find_or_make_entry)(h, key); \ + GB_JOIN2(FUNC,_table_grow)(h); \ + i = GB_JOIN2(FUNC,_find_or_make_entry)(h, key); \ h->entries[i].value = value; \ - if (GB_JOIN2(N,_is_full)(h)) \ - GB_JOIN2(N,_table_grow)(h); \ + if (GB_JOIN2(FUNC,_is_full)(h)) \ + GB_JOIN2(FUNC,_table_grow)(h); \ } \ -gb_inline void GB_JOIN2(N,remove)(NAME *h, u64 key) { \ - gbHashTableFindResult fr = GB_JOIN2(N,_find_result_from_key)(h, key); \ +gb_inline void GB_JOIN2(FUNC,remove)(NAME *h, u64 key) { \ + gbHashTableFindResult fr = GB_JOIN2(FUNC,_find_result_from_key)(h, key); \ if (fr.entry_index >= 0) \ - GB_JOIN2(N,_erase_find_result)(h, fr); \ + GB_JOIN2(FUNC,_erase_find_result)(h, fr); \ } \ -gb_inline void GB_JOIN2(N,reserve)(NAME *h, isize capacity) { \ - GB_JOIN2(N,_rehash)(h, capacity); \ +gb_inline void GB_JOIN2(FUNC,reserve)(NAME *h, isize capacity) { \ + GB_JOIN2(FUNC,_rehash)(h, capacity); \ } \ -gb_inline void GB_JOIN2(N,clear)(NAME *h) { \ +gb_inline void GB_JOIN2(FUNC,clear)(NAME *h) { \ gb_array_clear(&h->hashes); \ gb_array_clear(&h->entries); \ } \ @@ -1884,10 +1877,10 @@ typedef enum gbFileStandardType { GB_DEF gbFile *const gb_file_get_standard(gbFileStandardType std); -GB_DEF gbFileError gb_file_create (gbFile *file, char const *filename, ...) GB_PRINTF_ARGS(2); -GB_DEF gbFileError gb_file_open (gbFile *file, char const *filename, ...) GB_PRINTF_ARGS(2); +GB_DEF gbFileError gb_file_create (gbFile *file, char const *filename); +GB_DEF gbFileError gb_file_open (gbFile *file, char const *filename); // TODO(bill): Get a better name for it -GB_DEF gbFileError gb_file_open_mode (gbFile *file, gbFileMode mode, char const *filename, ...) GB_PRINTF_ARGS(3); +GB_DEF gbFileError gb_file_open_mode (gbFile *file, gbFileMode mode, char const *filename); GB_DEF gbFileError gb_file_new (gbFile *file, gbFileDescriptor fd, gbFileOperations const *ops, char const *filename); GB_DEF b32 gb_file_read_at_check (gbFile *file, void *buffer, isize size, i64 offset, isize *bytes_read); GB_DEF b32 gb_file_write_at_check(gbFile *file, void const *buffer, isize size, i64 offset, isize *bytes_written); @@ -1915,13 +1908,13 @@ typedef struct gbFileContents { } gbFileContents; -GB_DEF gbFileContents gb_file_read_contents(gbAllocator a, b32 zero_terminate, char const *filepath, ...) GB_PRINTF_ARGS(3); +GB_DEF gbFileContents gb_file_read_contents(gbAllocator a, b32 zero_terminate, char const *filepath); GB_DEF void gb_file_free_contents(gbFileContents *fc); // TODO(bill): Should these have different na,es as they do not take in a gbFile * ??? GB_DEF b32 gb_file_exists (char const *filepath); -GB_DEF gbFileTime gb_file_last_write_time(char const *filepath, ...) GB_PRINTF_ARGS(1); +GB_DEF gbFileTime gb_file_last_write_time(char const *filepath); GB_DEF b32 gb_file_copy (char const *existing_filename, char const *new_filename, b32 fail_if_exists); GB_DEF b32 gb_file_move (char const *existing_filename, char const *new_filename); @@ -1971,7 +1964,7 @@ GB_DEF isize gb_snprintf_va(char *str, isize n, char const *fmt, va_list va); typedef void *gbDllHandle; typedef void (*gbDllProc)(void); -GB_DEF gbDllHandle gb_dll_load (char const *filepath, ...) GB_PRINTF_ARGS(1); +GB_DEF gbDllHandle gb_dll_load (char const *filepath); GB_DEF void gb_dll_unload (gbDllHandle dll); GB_DEF gbDllProc gb_dll_proc_address(gbDllHandle dll, char const *proc_name); @@ -2014,52 +2007,6 @@ GB_DEF u64 gb_endian_swap64(u64 i); -#if !defined(GB_NO_COLOUR_TYPE) - - -//////////////////////////////////////////////////////////////// -// -// Colour Type -// It's quite useful -// TODO(bill): Does this need to be in this library? -// Can I remove the anonymous struct extension? -// - -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable:4201) -#endif - -typedef union gbColour { - u32 rgba; // NOTE(bill): 0xaabbggrr in little endian - struct { u8 r, g, b, a; }; - u8 e[4]; -} gbColour; -GB_STATIC_ASSERT(gb_size_of(gbColour) == gb_size_of(u32)); - -#if defined(_MSC_VER) -#pragma warning(pop) -#endif - - -GB_DEF gbColour gb_colour(f32 r, f32 g, f32 b, f32 a); - -gb_global gbColour const GB_COLOUR_WHITE = {0xffffffff}; -gb_global gbColour const GB_COLOUR_GREY = {0xff808080}; -gb_global gbColour const GB_COLOUR_BLACK = {0xff000000}; - -gb_global gbColour const GB_COLOUR_RED = {0xff0000ff}; -gb_global gbColour const GB_COLOUR_ORANGE = {0xff0099ff}; -gb_global gbColour const GB_COLOUR_YELLOW = {0xff00ffff}; -gb_global gbColour const GB_COLOUR_GREEN = {0xff00ff00}; -gb_global gbColour const GB_COLOUR_CYAN = {0xffffff00}; -gb_global gbColour const GB_COLOUR_BLUE = {0xffff0000}; -gb_global gbColour const GB_COLOUR_VIOLET = {0xffff007f}; -gb_global gbColour const GB_COLOUR_MAGENTA = {0xffff00ff}; - -#endif // !defined(GB_NO_COLOUR_TYPE) - - //////////////////////////////////////////////////////////////// // @@ -2454,10 +2401,15 @@ GB_DEF GB_COMPARE_PROC(gb_video_mode_dsc_cmp); // NOTE(bill): Sort largest to sm #if defined(GB_IMPLEMENTATION) && !defined(GB_IMPLEMENTATION_DONE) #define GB_IMPLEMENTATION_DONE +#if defined(GB_SYSTEM_WINDOWS) + +#endif + #if defined(__cplusplus) extern "C" { #endif + #if defined(__GCC__) || defined(__GNUC__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wattributes" @@ -5290,189 +5242,186 @@ u64 gb_murmur64_seed(void const *data_, isize len, u64 seed) { // #if defined(GB_SYSTEM_WINDOWS) + gb_internal GB_FILE_SEEK_PROC(gb__win32_file_seek) { + LARGE_INTEGER li_offset; + li_offset.QuadPart = offset; + if (!SetFilePointerEx(fd.p, li_offset, &li_offset, whence)) { + return false; + } + if (new_offset) *new_offset = li_offset.QuadPart; + return true; + } -gb_internal GB_FILE_SEEK_PROC(gb__win32_file_seek) { - LARGE_INTEGER li_offset; - li_offset.QuadPart = offset; - if (!SetFilePointerEx(fd.p, li_offset, &li_offset, whence)) { + gb_internal GB_FILE_READ_AT_PROC(gb__win32_file_read) { + b32 result = false; + DWORD size_ = cast(DWORD)(size > I32_MAX ? I32_MAX : size); + DWORD bytes_read_; + gb__win32_file_seek(fd, offset, GB_SEEK_BEGIN, NULL); + if (ReadFile(fd.p, buffer, size_, &bytes_read_, NULL)) { + if (bytes_read) *bytes_read = bytes_read_; + result = true; + } + + return result; + } + + gb_internal GB_FILE_WRITE_AT_PROC(gb__win32_file_write) { + DWORD size_ = cast(DWORD)(size > I32_MAX ? I32_MAX : size); + DWORD bytes_written_; + gb__win32_file_seek(fd, offset, GB_SEEK_BEGIN, NULL); + if (WriteFile(fd.p, buffer, size_, &bytes_written_, NULL)) { + if (bytes_written) *bytes_written = bytes_written_; + return true; + } return false; } - if (new_offset) *new_offset = li_offset.QuadPart; - return true; -} - -gb_internal GB_FILE_READ_AT_PROC(gb__win32_file_read) { - b32 result = false; - DWORD size_ = cast(DWORD)(size > I32_MAX ? I32_MAX : size); - DWORD bytes_read_; - gb__win32_file_seek(fd, offset, GB_SEEK_BEGIN, NULL); - if (ReadFile(fd.p, buffer, size_, &bytes_read_, NULL)) { - if (bytes_read) *bytes_read = bytes_read_; - result = true; + gb_internal GB_FILE_CLOSE_PROC(gb__win32_file_close) { + CloseHandle(fd.p); } - return result; -} + gbFileOperations const GB_DEFAULT_FILE_OPERATIONS = { + gb__win32_file_read, + gb__win32_file_write, + gb__win32_file_seek, + gb__win32_file_close + }; -gb_internal GB_FILE_WRITE_AT_PROC(gb__win32_file_write) { - DWORD size_ = cast(DWORD)(size > I32_MAX ? I32_MAX : size); - DWORD bytes_written_; - gb__win32_file_seek(fd, offset, GB_SEEK_BEGIN, NULL); - if (WriteFile(fd.p, buffer, size_, &bytes_written_, NULL)) { - if (bytes_written) *bytes_written = bytes_written_; - return true; - } - return false; -} + gb_no_inline GB_FILE_OPEN_PROC(gb__win32_file_open) { + DWORD desired_access; + DWORD creation_disposition; + HANDLE handle; + char16 path[1024] = {0}; // TODO(bill): Is this really enough or should I heap allocate this if it's too large? - -gb_internal GB_FILE_CLOSE_PROC(gb__win32_file_close) { - CloseHandle(fd.p); -} - -gbFileOperations const GB_DEFAULT_FILE_OPERATIONS = { - gb__win32_file_read, - gb__win32_file_write, - gb__win32_file_seek, - gb__win32_file_close -}; - - - - -GB_FILE_OPEN_PROC(gb__win32_file_open) { - DWORD desired_access; - DWORD creation_disposition; - HANDLE handle; - - switch (mode & GB_FILE_MODES) { - case GB_FILE_READ: - desired_access = GENERIC_READ; - creation_disposition = OPEN_EXISTING; - break; - case GB_FILE_WRITE: - desired_access = GENERIC_WRITE; - creation_disposition = CREATE_ALWAYS; - break; - case GB_FILE_APPEND: - desired_access = GENERIC_WRITE; - creation_disposition = OPEN_ALWAYS; - break; - case GB_FILE_READ | GB_FILE_RW: - desired_access = GENERIC_READ | GENERIC_WRITE; - creation_disposition = OPEN_EXISTING; - break; - case GB_FILE_WRITE | GB_FILE_RW: - desired_access = GENERIC_READ | GENERIC_WRITE; - creation_disposition = CREATE_ALWAYS; - break; - case GB_FILE_APPEND | GB_FILE_RW: - desired_access = GENERIC_READ | GENERIC_WRITE; - creation_disposition = OPEN_ALWAYS; - break; - default: - GB_PANIC("Invalid file mode"); - return GB_FILE_ERR_INVALID; - } - - handle = CreateFileA(filename, desired_access, - FILE_SHARE_READ|FILE_SHARE_DELETE, NULL, - creation_disposition, FILE_ATTRIBUTE_NORMAL, NULL); - - // TODO(bill): More file errors - if (handle == INVALID_HANDLE_VALUE) { - return GB_FILE_ERR_INVALID; - } - - if (mode & GB_FILE_APPEND) { - LARGE_INTEGER offset = {0}; - if (!SetFilePointerEx(handle, offset, NULL, FILE_END)) { - CloseHandle(handle); + switch (mode & GB_FILE_MODES) { + case GB_FILE_READ: + desired_access = GENERIC_READ; + creation_disposition = OPEN_EXISTING; + break; + case GB_FILE_WRITE: + desired_access = GENERIC_WRITE; + creation_disposition = CREATE_ALWAYS; + break; + case GB_FILE_APPEND: + desired_access = GENERIC_WRITE; + creation_disposition = OPEN_ALWAYS; + break; + case GB_FILE_READ | GB_FILE_RW: + desired_access = GENERIC_READ | GENERIC_WRITE; + creation_disposition = OPEN_EXISTING; + break; + case GB_FILE_WRITE | GB_FILE_RW: + desired_access = GENERIC_READ | GENERIC_WRITE; + creation_disposition = CREATE_ALWAYS; + break; + case GB_FILE_APPEND | GB_FILE_RW: + desired_access = GENERIC_READ | GENERIC_WRITE; + creation_disposition = OPEN_ALWAYS; + break; + default: + GB_PANIC("Invalid file mode"); return GB_FILE_ERR_INVALID; } - } - fd->p = handle; - *ops = &GB_DEFAULT_FILE_OPERATIONS; - return GB_FILE_ERR_NONE; -} + handle = CreateFileW(cast(LPCWSTR)gb_utf8_to_ucs2(path, gb_count_of(path), filename), + desired_access, + FILE_SHARE_READ|FILE_SHARE_DELETE, NULL, + creation_disposition, FILE_ATTRIBUTE_NORMAL, NULL); + + if (handle == INVALID_HANDLE_VALUE) { + DWORD err = GetLastError(); + switch (err) { + case ERROR_FILE_NOT_FOUND: return GB_FILE_ERR_NOT_EXISTS; + case ERROR_FILE_EXISTS: return GB_FILE_ERR_EXISTS; + case ERROR_ALREADY_EXISTS: return GB_FILE_ERR_EXISTS; + case ERROR_ACCESS_DENIED: return GB_FILE_ERR_PERMISSION; + } + return GB_FILE_ERR_INVALID; + } + + if (mode & GB_FILE_APPEND) { + LARGE_INTEGER offset = {0}; + if (!SetFilePointerEx(handle, offset, NULL, FILE_END)) { + CloseHandle(handle); + return GB_FILE_ERR_INVALID; + } + } + + fd->p = handle; + *ops = &GB_DEFAULT_FILE_OPERATIONS; + return GB_FILE_ERR_NONE; + } #else // POSIX - - -gb_internal GB_FILE_SEEK_PROC(gb__posix_file_seek) { - i64 res = lseek64(fd.i, offset, whence); - if (res < 0) return false; - if (new_offset) *new_offset = res; - return true; -} - -gb_internal GB_FILE_READ_AT_PROC(gb__posix_file_read) { - isize res = pread(fd.i, buffer, size, offset); - if (res < 0) return false; - if (bytes_read) *bytes_read = res; - return true; -} - -gb_internal GB_FILE_WRITE_AT_PROC(gb__posix_file_write) { - isize res = pwrite(fd.i, buffer, size, offset); - if (res < 0) return false; - if (bytes_written) *bytes_written = res; - return true; -} - - -gb_internal GB_FILE_CLOSE_PROC(gb__posix_file_close) { - close(fd.i); -} - -gbFileOperations const GB_DEFAULT_FILE_OPERATIONS = { - gb__posix_file_read, - gb__posix_file_write, - gb__posix_file_seek, - gb__posix_file_close -}; - - - - -GB_FILE_OPEN_PROC(gb__posix_file_open) { - i32 os_mode; - switch (mode & GB_FILE_MODES) { - case GB_FILE_READ: - os_mode = O_RDONLY; - break; - case GB_FILE_WRITE: - os_mode = O_WRONLY | O_CREAT | O_TRUNC; - break; - case GB_FILE_APPEND: - os_mode = O_WRONLY | O_APPEND | O_CREAT; - break; - case GB_FILE_READ | GB_FILE_RW: - os_mode = O_RDWR; - break; - case GB_FILE_WRITE | GB_FILE_RW: - os_mode = O_RDWR | O_CREAT | O_TRUNC; - break; - case GB_FILE_APPEND | GB_FILE_RW: - os_mode = O_RDWR | O_APPEND | O_CREAT; - break; - default: - GB_PANIC("Invalid file mode"); - return GB_FILE_ERR_INVALID; + gb_internal GB_FILE_SEEK_PROC(gb__posix_file_seek) { + i64 res = lseek64(fd.i, offset, whence); + if (res < 0) return false; + if (new_offset) *new_offset = res; + return true; } - fd->i = open(filename, os_mode, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); - if (fd->i < 0) { - // TODO(bill): More file errors - return GB_FILE_ERR_INVALID; + gb_internal GB_FILE_READ_AT_PROC(gb__posix_file_read) { + isize res = pread(fd.i, buffer, size, offset); + if (res < 0) return false; + if (bytes_read) *bytes_read = res; + return true; } - *ops = &GB_DEFAULT_FILE_OPERATIONS; - return GB_FILE_ERR_NONE; -} + gb_internal GB_FILE_WRITE_AT_PROC(gb__posix_file_write) { + isize res = pwrite(fd.i, buffer, size, offset); + if (res < 0) return false; + if (bytes_written) *bytes_written = res; + return true; + } + + + gb_internal GB_FILE_CLOSE_PROC(gb__posix_file_close) { + close(fd.i); + } + + gbFileOperations const GB_DEFAULT_FILE_OPERATIONS = { + gb__posix_file_read, + gb__posix_file_write, + gb__posix_file_seek, + gb__posix_file_close + }; + + gb_no_inline GB_FILE_OPEN_PROC(gb__posix_file_open) { + i32 os_mode; + switch (mode & GB_FILE_MODES) { + case GB_FILE_READ: + os_mode = O_RDONLY; + break; + case GB_FILE_WRITE: + os_mode = O_WRONLY | O_CREAT | O_TRUNC; + break; + case GB_FILE_APPEND: + os_mode = O_WRONLY | O_APPEND | O_CREAT; + break; + case GB_FILE_READ | GB_FILE_RW: + os_mode = O_RDWR; + break; + case GB_FILE_WRITE | GB_FILE_RW: + os_mode = O_RDWR | O_CREAT | O_TRUNC; + break; + case GB_FILE_APPEND | GB_FILE_RW: + os_mode = O_RDWR | O_APPEND | O_CREAT; + break; + default: + GB_PANIC("Invalid file mode"); + return GB_FILE_ERR_INVALID; + } + + fd->i = open(filename, os_mode, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + if (fd->i < 0) { + // TODO(bill): More file errors + return GB_FILE_ERR_INVALID; + } + + *ops = &GB_DEFAULT_FILE_OPERATIONS; + return GB_FILE_ERR_NONE; + } #endif @@ -5484,24 +5433,22 @@ gbFileError gb_file_new(gbFile *f, gbFileDescriptor fd, gbFileOperations const * f->ops = ops; f->fd = fd; f->filename = gb_alloc_str(gb_heap_allocator(), filename); - f->last_write_time = gb_file_last_write_time("%s", f->filename); + f->last_write_time = gb_file_last_write_time(f->filename); return err; } -gbFileError gb_file_open_mode_va(gbFile *f, gbFileMode mode, char const *filename, va_list va) { - gb_local_persist char path[4096] = {0}; +gbFileError gb_file_open_mode(gbFile *f, gbFileMode mode, char const *filename) { gbFileError err; - gb_snprintf_va(path, gb_size_of(path), filename, va); #if defined(GB_SYSTEM_WINDOWS) - err = gb__win32_file_open(&f->fd, &f->ops, mode, path); + err = gb__win32_file_open(&f->fd, &f->ops, mode, filename); #else - err = gb__posix_file_open(&f->fd, &f->ops, mode, path); + err = gb__posix_file_open(&f->fd, &f->ops, mode, filename); #endif if (err == GB_FILE_ERR_NONE) - return gb_file_new(f, f->fd, f->ops, path); + return gb_file_new(f, f->fd, f->ops, filename); return err; } @@ -5571,32 +5518,13 @@ gb_inline b32 gb_file_read (gbFile *f, void *buffer, isize size) { return gb_inline b32 gb_file_write(gbFile *f, void const *buffer, isize size) { return gb_file_write_at(f, buffer, size, gb_file_tell(f)); } -gbFileError gb_file_create(gbFile *f, char const *filename, ...) { - gbFileError err; - va_list va; - va_start(va, filename); - err = gb_file_open_mode_va(f, GB_FILE_WRITE|GB_FILE_RW, filename, va); - va_end(va); - return err; +gbFileError gb_file_create(gbFile *f, char const *filename) { + return gb_file_open_mode(f, GB_FILE_WRITE|GB_FILE_RW, filename); } -gbFileError gb_file_open(gbFile *f, char const *filename, ...) { - gbFileError err; - va_list va; - va_start(va, filename); - err = gb_file_open_mode_va(f, GB_FILE_READ, filename, va); - va_end(va); - return err; -} - -gbFileError gb_file_open_mode(gbFile *f, gbFileMode mode, char const *filename, ...) { - gbFileError err; - va_list va; - va_start(va, filename); - err = gb_file_open_mode_va(f, mode, filename, va); - va_end(va); - return err; +gbFileError gb_file_open(gbFile *f, char const *filename) { + return gb_file_open_mode(f, GB_FILE_READ, filename); } @@ -5604,7 +5532,7 @@ char const *gb_file_name(gbFile *f) { return f->filename ? f->filename : ""; } gb_inline b32 gb_file_has_changed(gbFile *f) { b32 result = false; - gbFileTime last_write_time = gb_file_last_write_time("%s", f->filename); + gbFileTime last_write_time = gb_file_last_write_time(f->filename); if (f->last_write_time != last_write_time) { result = true; f->last_write_time = last_write_time; @@ -5686,7 +5614,7 @@ gb_inline gbFileError gb_file_truncate(gbFile *f, i64 size) { return err; } -b32 gb_file_exists(char const *name) { +gb_inline b32 gb_file_exists(char const *name) { return access(name, F_OK) != -1; } #endif @@ -5694,18 +5622,15 @@ b32 gb_file_exists(char const *name) { #if defined(GB_SYSTEM_WINDOWS) -gbFileTime gb_file_last_write_time(char const *filepath, ...) { - gb_local_persist char16 path[2048]; +gbFileTime gb_file_last_write_time(char const *filepath) { + char16 path[1024] = {0}; ULARGE_INTEGER li = {0}; FILETIME last_write_time = {0}; WIN32_FILE_ATTRIBUTE_DATA data = {0}; - va_list va; - va_start(va, filepath); - if (GetFileAttributesExW(cast(LPCWSTR)gb_utf8_to_ucs2(path, gb_count_of(path), gb_bprintf_va(filepath, va)), + if (GetFileAttributesExW(cast(LPCWSTR)gb_utf8_to_ucs2(path, gb_count_of(path), filepath), GetFileExInfoStandard, &data)) last_write_time = data.ftLastWriteTime; - va_end(va); li.LowPart = last_write_time.dwLowDateTime; li.HighPart = last_write_time.dwHighDateTime; @@ -5714,8 +5639,8 @@ gbFileTime gb_file_last_write_time(char const *filepath, ...) { gb_inline b32 gb_file_copy(char const *existing_filename, char const *new_filename, b32 fail_if_exists) { - gb_local_persist char16 old_f[2048]; - gb_local_persist char16 new_f[2048]; + char16 old_f[300] = {0}; + char16 new_f[300] = {0}; return CopyFileW(cast(LPCWSTR)gb_utf8_to_ucs2(old_f, gb_count_of(old_f), existing_filename), cast(LPCWSTR)gb_utf8_to_ucs2(new_f, gb_count_of(new_f), new_filename), @@ -5723,8 +5648,8 @@ gb_inline b32 gb_file_copy(char const *existing_filename, char const *new_filena } gb_inline b32 gb_file_move(char const *existing_filename, char const *new_filename) { - gb_local_persist char16 old_f[2048]; - gb_local_persist char16 new_f[2048]; + char16 old_f[300] = {0}; + char16 new_f[300] = {0}; return MoveFileW(cast(LPCWSTR)gb_utf8_to_ucs2(old_f, gb_count_of(old_f), existing_filename), cast(LPCWSTR)gb_utf8_to_ucs2(new_f, gb_count_of(new_f), new_filename)); @@ -5736,11 +5661,12 @@ gb_inline b32 gb_file_move(char const *existing_filename, char const *new_filena gbFileTime gb_file_last_write_time(char const *filepath, ...) { time_t result = 0; + char path[1024] = {0}; struct stat file_stat; va_list va; va_start(va, filepath); - if (stat(gb_bprintf_va(filepath, va), &file_stat)) { + if (stat(gb_snprintf_va(path, gb_count_of(path), filepath, va), &file_stat)) { result = file_stat.st_mtime; } @@ -5780,18 +5706,13 @@ gb_inline b32 gb_file_move(char const *existing_filename, char const *new_filena -gbFileContents gb_file_read_contents(gbAllocator a, b32 zero_terminate, char const *filepath, ...) { +gbFileContents gb_file_read_contents(gbAllocator a, b32 zero_terminate, char const *filepath) { gbFileContents result = {0}; gbFile file = {0}; - char *path; - va_list va; - va_start(va, filepath); - path = gb_bprintf_va(filepath, va); - va_end(va); result.allocator = a; - if (gb_file_open(&file, "%s", path) == GB_FILE_ERR_NONE) { + if (gb_file_open(&file, filepath) == GB_FILE_ERR_NONE) { isize file_size = cast(isize)gb_file_size(&file); if (file_size > 0) { result.data = gb_alloc(a, zero_terminate ? file_size+1 : file_size); @@ -6313,27 +6234,17 @@ gb_no_inline isize gb_snprintf_va(char *text, isize max_len, char const *fmt, va #if defined(GB_SYSTEM_WINDOWS) -gbDllHandle gb_dll_load(char const *filepath, ...) { - gb_local_persist char buffer[512]; - va_list va; - va_start(va, filepath); - gb_snprintf_va(buffer, gb_size_of(buffer), filepath, va); - va_end(va); - return cast(gbDllHandle)LoadLibraryA(buffer); +gbDllHandle gb_dll_load(char const *filepath) { + return cast(gbDllHandle)LoadLibraryA(filepath); } gb_inline void gb_dll_unload (gbDllHandle dll) { FreeLibrary(cast(HMODULE)dll); } gb_inline gbDllProc gb_dll_proc_address(gbDllHandle dll, char const *proc_name) { return cast(gbDllProc)GetProcAddress(cast(HMODULE)dll, proc_name); } #else // POSIX -gbDllHandle gb_dll_load(char const *filepath, ...) { - gb_local_persist char buffer[512]; - va_list va; - va_start(va, filepath); - gb_snprintf_va(buffer, gb_size_of(buffer), filepath, va); - va_end(va); +gbDllHandle gb_dll_load(char const *filepath) { // TODO(bill): Should this be RTLD_LOCAL? - return cast(gbDllHandle)dlopen(buffer, RTLD_LAZY|RTLD_GLOBAL); + return cast(gbDllHandle)dlopen(filepath, RTLD_LAZY|RTLD_GLOBAL); } gb_inline void gb_dll_unload (gbDllHandle dll) { dlclose(dll); } @@ -6604,25 +6515,6 @@ gb_inline u64 gb_endian_swap64(u64 i) { - -//////////////////////////////////////////////////////////////// -// -// Colour Type -// It's quite useful -// - -#if !defined(GB_NO_COLOUR_TYPE) -gb_inline gbColour gb_colour(f32 r, f32 g, f32 b, f32 a) { - gbColour result; - result.r = cast(u8)(gb_clamp01(r) * 255.0f); - result.g = cast(u8)(gb_clamp01(g) * 255.0f); - result.b = cast(u8)(gb_clamp01(b) * 255.0f); - result.a = cast(u8)(gb_clamp01(a) * 255.0f); - return result; -} -#endif - - //////////////////////////////////////////////////////////////// // // Platform @@ -7228,7 +7120,7 @@ gbWindow *gb_window_init(gbPlatform *platform, char const *title, gbVideoMode mo if (window->flags & GB_WINDOW_OPENGL) { PIXELFORMATDESCRIPTOR pfd = {gb_size_of(PIXELFORMATDESCRIPTOR)}; pfd.nVersion = 1; - pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; + pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 32; pfd.cAlphaBits = 8; @@ -7279,16 +7171,14 @@ void gb_window_set_position(gbWindow *w, i32 x, i32 y) { void gb_window_set_title(gbWindow *w, char const *title, ...) { char16 buffer[256] = {0}; - char *str; - LPCWSTR wstr; + char str[512] = {0}; va_list va; va_start(va, title); - str = gb_bprintf_va(title, va); + gb_snprintf_va(str, gb_size_of(str), title, va); va_end(va); - wstr = cast(LPCWSTR)gb_utf8_to_ucs2(buffer, gb_size_of(buffer), str); - if (wstr) - SetWindowTextW(cast(HWND)w->handle, wstr); + if (str[0] != '\0') + SetWindowTextW(cast(HWND)w->handle, cast(LPCWSTR)gb_utf8_to_ucs2(buffer, gb_size_of(buffer), str)); } void gb_window_toggle_fullscreen(gbWindow *w, b32 fullscreen_desktop) { @@ -7479,7 +7369,7 @@ GB_COMPARE_PROC(gb_video_mode_cmp) { } GB_COMPARE_PROC(gb_video_mode_dsc_cmp) { - return -gb_video_mode_cmp(a, b); + return gb_video_mode_cmp(b, a); } @@ -7503,6 +7393,7 @@ GB_COMPARE_PROC(gb_video_mode_dsc_cmp) { /* Version History: + 0.20 - Improve file io 0.19 - Clipboard Text 0.18a - Controller vibration 0.18 - Raw keyboard and mouse input for WIN32 diff --git a/gb_gl.h b/gb_gl.h index f858349..c97bc8c 100644 --- a/gb_gl.h +++ b/gb_gl.h @@ -1,4 +1,4 @@ -/* gb.h - v0.04e - OpenGL Helper Library - public domain +/* gb.h - v0.05 - OpenGL Helper Library - public domain - no warranty implied; use at your own risk This is a single header file with a bunch of useful stuff @@ -55,6 +55,7 @@ Conventions used: Version History: + 0.05 - gbglColour 0.04e - Change brace style because why not? 0.04d - Use new gb.h file handling system 0.04c - Use new gb.h file handling system @@ -131,6 +132,9 @@ CREDITS #endif #endif +#define gbgl_clamp(x, lower, upper) gbgl_min(gbgl_max((x), (lower)), (upper)) +#define gbgl_clamp01(x) gbgl_clamp(x, 0, 1) + #if defined(__cplusplus) extern "C" { @@ -155,6 +159,45 @@ extern "C" { +//////////////////////////////////////////////////////////////// +// +// Colour Type +// It's quite useful +// TODO(bill): Does this need to be in this library? +// Can I remove the anonymous struct extension? +// + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning(disable:4201) +#endif + +typedef union gbglColour { + u32 rgba; // NOTE(bill): 0xaabbggrr in little endian + struct { u8 r, g, b, a; }; + u8 e[4]; +} gbglColour; +GB_STATIC_ASSERT(gb_size_of(gbglColour) == gb_size_of(u32)); + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + + +GB_DEF gbglColour gbgl_colour(f32 r, f32 g, f32 b, f32 a); + +gb_global gbglColour const GBGL_COLOUR_WHITE = {0xffffffff}; +gb_global gbglColour const GBGL_COLOUR_GREY = {0xff808080}; +gb_global gbglColour const GBGL_COLOUR_BLACK = {0xff000000}; + +gb_global gbglColour const GBGL_COLOUR_RED = {0xff0000ff}; +gb_global gbglColour const GBGL_COLOUR_ORANGE = {0xff0099ff}; +gb_global gbglColour const GBGL_COLOUR_YELLOW = {0xff00ffff}; +gb_global gbglColour const GBGL_COLOUR_GREEN = {0xff00ff00}; +gb_global gbglColour const GBGL_COLOUR_CYAN = {0xffffff00}; +gb_global gbglColour const GBGL_COLOUR_BLUE = {0xffff0000}; +gb_global gbglColour const GBGL_COLOUR_VIOLET = {0xffff007f}; +gb_global gbglColour const GBGL_COLOUR_MAGENTA = {0xffff00ff}; //////////////////////////////////////////////////////////////// @@ -401,7 +444,7 @@ GBGL_DEF void gbgl_set_uniform_vec3 (gbglShader *s, char const *name, f32 c GBGL_DEF void gbgl_set_uniform_vec4 (gbglShader *s, char const *name, f32 const *v); GBGL_DEF void gbgl_set_uniform_mat4 (gbglShader *s, char const *name, f32 const *m); GBGL_DEF void gbgl_set_uniform_mat4_count(gbglShader *s, char const *name, f32 const *m, isize count); -GBGL_DEF void gbgl_set_uniform_colour (gbglShader *s, char const *name, gbColour col); +GBGL_DEF void gbgl_set_uniform_colour (gbglShader *s, char const *name, gbglColour col); //////////////////////////////////////////////////////////////// @@ -432,7 +475,7 @@ typedef struct gbglTexture { GBGL_DEF b32 gbgl_load_texture2d_from_file (gbglTexture *texture, b32 flip_vertically, char const *filename, ...); GBGL_DEF b32 gbgl_load_texture2d_from_memory(gbglTexture *texture, void const *data, i32 width, i32 height, i32 channel_count); -GBGL_DEF b32 gbgl_init_texture2d_coloured (gbglTexture *texture, gbColour colour); +GBGL_DEF b32 gbgl_init_texture2d_coloured (gbglTexture *texture, gbglColour colour); GBGL_DEF void gbgl_destroy_texture (gbglTexture *texture); GBGL_DEF void gbgl_bind_texture2d(gbglTexture const *texture, u32 position, u32 sampler); @@ -679,29 +722,29 @@ GBGL_DEF void gbgl_bs_begin(gbglBasicState *bs, i32 window_width, i32 window_hei GBGL_DEF void gbgl_bs_end(gbglBasicState *bs); GBGL_DEF void gbgl_bs_draw_textured_rect(gbglBasicState *bs, gbglTexture *tex, f32 x, f32 y, f32 w, f32 h, b32 v_up); -GBGL_DEF void gbgl_bs_draw_rect(gbglBasicState *bs, f32 x, f32 y, f32 w, f32 h, gbColour col); -GBGL_DEF void gbgl_bs_draw_rect_outline(gbglBasicState *bs, f32 x, f32 y, f32 w, f32 h, gbColour col, f32 thickness); +GBGL_DEF void gbgl_bs_draw_rect(gbglBasicState *bs, f32 x, f32 y, f32 w, f32 h, gbglColour col); +GBGL_DEF void gbgl_bs_draw_rect_outline(gbglBasicState *bs, f32 x, f32 y, f32 w, f32 h, gbglColour col, f32 thickness); GBGL_DEF void gbgl_bs_draw_quad(gbglBasicState *bs, f32 x0, f32 y0, f32 x1, f32 y1, f32 x2, f32 y2, f32 x3, f32 y3, - gbColour col); + gbglColour col); GBGL_DEF void gbgl_bs_draw_quad_outline(gbglBasicState *bs, f32 x0, f32 y0, f32 x1, f32 y1, f32 x2, f32 y2, f32 x3, f32 y3, - gbColour col, f32 thickness); + gbglColour col, f32 thickness); -GBGL_DEF void gbgl_bs_draw_line(gbglBasicState *bs, f32 x0, f32 y0, f32 x1, f32 y1, gbColour col, f32 thickness); +GBGL_DEF void gbgl_bs_draw_line(gbglBasicState *bs, f32 x0, f32 y0, f32 x1, f32 y1, gbglColour col, f32 thickness); -GBGL_DEF void gbgl_bs_draw_elliptical_arc(gbglBasicState *bs, f32 x, f32 y, f32 radius_a, f32 radius_b, f32 min_angle, f32 max_angle, gbColour col); +GBGL_DEF void gbgl_bs_draw_elliptical_arc(gbglBasicState *bs, f32 x, f32 y, f32 radius_a, f32 radius_b, f32 min_angle, f32 max_angle, gbglColour col); GBGL_DEF void gbgl_bs_draw_elliptical_arc_outline(gbglBasicState *bs, f32 x, f32 y, f32 radius_a, f32 radius_b, - f32 min_angle, f32 max_angle, gbColour col, f32 thickness); + f32 min_angle, f32 max_angle, gbglColour col, f32 thickness); -GBGL_DEF void gbgl_bs_draw_circle(gbglBasicState *bs, f32 x, f32 y, f32 radius, gbColour col); -GBGL_DEF void gbgl_bs_draw_circle_outline(gbglBasicState *bs, f32 x, f32 y, f32 radius, gbColour col, f32 thickness); +GBGL_DEF void gbgl_bs_draw_circle(gbglBasicState *bs, f32 x, f32 y, f32 radius, gbglColour col); +GBGL_DEF void gbgl_bs_draw_circle_outline(gbglBasicState *bs, f32 x, f32 y, f32 radius, gbglColour col, f32 thickness); // Corners Flags: @@ -710,17 +753,17 @@ GBGL_DEF void gbgl_bs_draw_circle_outline(gbglBasicState *bs, f32 x, f32 y, f32 // 4 - Top Right // 8 - Top Left // NOTE(bill): Apple, please don't sue me! -GBGL_DEF void gbgl_bs_draw_rounded_rect_corners(gbglBasicState *bs, f32 x, f32 y, f32 w, f32 h, f32 roundness, gbColour col, u32 corners); -GBGL_DEF void gbgl_bs_draw_rounded_rect(gbglBasicState *bs, f32 x, f32 y, f32 w, f32 h, f32 roundness, gbColour col); +GBGL_DEF void gbgl_bs_draw_rounded_rect_corners(gbglBasicState *bs, f32 x, f32 y, f32 w, f32 h, f32 roundness, gbglColour col, u32 corners); +GBGL_DEF void gbgl_bs_draw_rounded_rect(gbglBasicState *bs, f32 x, f32 y, f32 w, f32 h, f32 roundness, gbglColour col); -GBGL_DEF void gbgl_bs_draw_rounded_rect_corners_outline(gbglBasicState *bs, f32 x, f32 y, f32 w, f32 h, f32 roundness, gbColour col, f32 thickness, u32 corners); -GBGL_DEF void gbgl_bs_draw_rounded_rect_outline(gbglBasicState *bs, f32 x, f32 y, f32 w, f32 h, f32 roundness, gbColour col, f32 thickness); +GBGL_DEF void gbgl_bs_draw_rounded_rect_corners_outline(gbglBasicState *bs, f32 x, f32 y, f32 w, f32 h, f32 roundness, gbglColour col, f32 thickness, u32 corners); +GBGL_DEF void gbgl_bs_draw_rounded_rect_outline(gbglBasicState *bs, f32 x, f32 y, f32 w, f32 h, f32 roundness, gbglColour col, f32 thickness); #if !defined(GBGL_NO_FONTS) -GBGL_DEF isize gbgl_bs_draw_substring(gbglBasicState *bs, gbglFont *font, f32 x, f32 y, gbColour col, char const *str, isize len); -GBGL_DEF isize gbgl_bs_draw_string (gbglBasicState *bs, gbglFont *font, f32 x, f32 y, gbColour col, char const *fmt, ...); -GBGL_DEF isize gbgl_bs_draw_string_va(gbglBasicState *bs, gbglFont *font, f32 x, f32 y, gbColour col, char const *fmt, va_list va); +GBGL_DEF isize gbgl_bs_draw_substring(gbglBasicState *bs, gbglFont *font, f32 x, f32 y, gbglColour col, char const *str, isize len); +GBGL_DEF isize gbgl_bs_draw_string (gbglBasicState *bs, gbglFont *font, f32 x, f32 y, gbglColour col, char const *fmt, ...); +GBGL_DEF isize gbgl_bs_draw_string_va(gbglBasicState *bs, gbglFont *font, f32 x, f32 y, gbglColour col, char const *fmt, va_list va); #endif @@ -783,6 +826,15 @@ GBGL_DEF isize gbgl_bs_draw_string_va(gbglBasicState *bs, gbglFont *font, f32 x, #if defined(GBGL_IMPLEMENTATION) +gb_inline gbglColour gbgl_colour(f32 r, f32 g, f32 b, f32 a) { + gbglColour result; + result.r = cast(u8)(gbgl_clamp01(r) * 255.0f); + result.g = cast(u8)(gbgl_clamp01(g) * 255.0f); + result.b = cast(u8)(gbgl_clamp01(b) * 255.0f); + result.a = cast(u8)(gbgl_clamp01(a) * 255.0f); + return result; +} + u32 gbgl_make_sampler(u32 min_filter, u32 max_filter, u32 s_wrap, u32 t_wrap) { u32 samp; @@ -882,7 +934,10 @@ gb_inline void gbgl_unmap_ebo(void) { glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); } gbglShaderError gbgl__load_single_shader_from_file(gbglShader *shader, gbglShaderType type, char const *name) { gbglShaderError err = GBGL_SHADER_ERROR_NONE; - gbFileError ferr = gb_file_open(&shader->files[type], "%s%s", name, GBGL_SHADER_FILE_EXTENSIONS[type]); + gbFileError ferr; + gb_local_persist char filepath[1024]; + gb_snprintf(filepath, gb_count_of(filepath), "%s%s", name, GBGL_SHADER_FILE_EXTENSIONS[type]); + ferr = gb_file_open(&shader->files[type], filepath); if (ferr != GB_FILE_ERR_NONE) { err = GBGL_SHADER_ERROR_UNABLE_TO_READ_FILE; @@ -1142,7 +1197,7 @@ gb_inline void gbgl_set_uniform_mat4_count(gbglShader *s, char const *name, f32 } -gb_inline void gbgl_set_uniform_colour(gbglShader *s, char const *name, gbColour col) { +gb_inline void gbgl_set_uniform_colour(gbglShader *s, char const *name, gbglColour col) { f32 v[4]; v[0] = col.r / 255.0f; v[1] = col.g / 255.0f; @@ -1274,7 +1329,7 @@ b32 gbgl_load_texture2d_from_file(gbglTexture *texture, b32 flip_vertically, cha return result; } -gb_inline b32 gbgl_make_texture2d_coloured(gbglTexture *t, gbColour colour) { +gb_inline b32 gbgl_make_texture2d_coloured(gbglTexture *t, gbglColour colour) { return gbgl_load_texture2d_from_memory(t, &colour.rgba, 1, 1, 4); } @@ -2022,7 +2077,7 @@ void gbgl_bs_draw_textured_rect(gbglBasicState *bs, gbglTexture *tex, f32 x, f32 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, NULL); } -gb_inline void gbgl_bs_draw_rect(gbglBasicState *bs, f32 x, f32 y, f32 w, f32 h, gbColour col) { +gb_inline void gbgl_bs_draw_rect(gbglBasicState *bs, f32 x, f32 y, f32 w, f32 h, gbglColour col) { gbgl_bs_draw_quad(bs, x, y, x+w, y, @@ -2031,7 +2086,7 @@ gb_inline void gbgl_bs_draw_rect(gbglBasicState *bs, f32 x, f32 y, f32 w, f32 h, col); } -gb_inline void gbgl_bs_draw_rect_outline(gbglBasicState *bs, f32 x, f32 y, f32 w, f32 h, gbColour col, f32 thickness) { +gb_inline void gbgl_bs_draw_rect_outline(gbglBasicState *bs, f32 x, f32 y, f32 w, f32 h, gbglColour col, f32 thickness) { gbgl_bs_draw_quad_outline(bs, x, y, x+w, y, @@ -2042,7 +2097,7 @@ gb_inline void gbgl_bs_draw_rect_outline(gbglBasicState *bs, f32 x, f32 y, f32 w } -gb_internal void gbgl__bs_setup_ortho_colour_state(gbglBasicState *bs, isize vertex_count, gbColour col) { +gb_internal void gbgl__bs_setup_ortho_colour_state(gbglBasicState *bs, isize vertex_count, gbglColour col) { gbgl_use_shader(&bs->ortho_col_shader); gbgl_set_uniform_mat4(&bs->ortho_col_shader, "u_ortho_mat", bs->ortho_mat); @@ -2062,7 +2117,7 @@ gb_inline void gbgl_bs_draw_quad(gbglBasicState *bs, f32 x1, f32 y1, f32 x2, f32 y2, f32 x3, f32 y3, - gbColour col) { + gbglColour col) { bs->vertices[0].x = x0; bs->vertices[0].y = y0; @@ -2084,7 +2139,7 @@ gb_inline void gbgl_bs_draw_quad_outline(gbglBasicState *bs, f32 x1, f32 y1, f32 x2, f32 y2, f32 x3, f32 y3, - gbColour col, f32 thickness) { + gbglColour col, f32 thickness) { bs->vertices[0].x = x0; bs->vertices[0].y = y0; @@ -2102,7 +2157,7 @@ gb_inline void gbgl_bs_draw_quad_outline(gbglBasicState *bs, glDrawArrays(GL_LINE_LOOP, 0, 4); } -gb_inline void gbgl_bs_draw_line(gbglBasicState *bs, f32 x0, f32 y0, f32 x1, f32 y1, gbColour col, f32 thickness) { +gb_inline void gbgl_bs_draw_line(gbglBasicState *bs, f32 x0, f32 y0, f32 x1, f32 y1, gbglColour col, f32 thickness) { bs->vertices[0].x = x0; bs->vertices[0].y = y0; @@ -2115,7 +2170,7 @@ gb_inline void gbgl_bs_draw_line(gbglBasicState *bs, f32 x0, f32 y0, f32 x1, f32 } gb_inline void gbgl_bs_draw_elliptical_arc(gbglBasicState *bs, f32 x, f32 y, f32 radius_a, f32 radius_b, - f32 min_angle, f32 max_angle, gbColour col) { + f32 min_angle, f32 max_angle, gbglColour col) { isize i; bs->vertices[0].x = x; @@ -2135,7 +2190,7 @@ gb_inline void gbgl_bs_draw_elliptical_arc(gbglBasicState *bs, f32 x, f32 y, f32 } gb_inline void gbgl_bs_draw_elliptical_arc_outline(gbglBasicState *bs, f32 x, f32 y, f32 radius_a, f32 radius_b, - f32 min_angle, f32 max_angle, gbColour col, f32 thickness) { + f32 min_angle, f32 max_angle, gbglColour col, f32 thickness) { isize i; for (i = 0; i < 32; i++) { @@ -2154,15 +2209,15 @@ gb_inline void gbgl_bs_draw_elliptical_arc_outline(gbglBasicState *bs, f32 x, f3 -gb_inline void gbgl_bs_draw_circle(gbglBasicState *bs, f32 x, f32 y, f32 radius, gbColour col) { +gb_inline void gbgl_bs_draw_circle(gbglBasicState *bs, f32 x, f32 y, f32 radius, gbglColour col) { gbgl_bs_draw_elliptical_arc(bs, x, y, radius, radius, 0, GBGL_TAU, col); } -gb_inline void gbgl_bs_draw_circle_outline(gbglBasicState *bs, f32 x, f32 y, f32 radius, gbColour col, f32 thickness) { +gb_inline void gbgl_bs_draw_circle_outline(gbglBasicState *bs, f32 x, f32 y, f32 radius, gbglColour col, f32 thickness) { gbgl_bs_draw_elliptical_arc_outline(bs, x, y, radius, radius, 0, GBGL_TAU, col, thickness); } -void gbgl_bs_draw_rounded_rect_corners(gbglBasicState *bs, f32 x, f32 y, f32 w, f32 h, f32 roundness, gbColour col, u32 corners) { +void gbgl_bs_draw_rounded_rect_corners(gbglBasicState *bs, f32 x, f32 y, f32 w, f32 h, f32 roundness, gbglColour col, u32 corners) { if ((2.0f*roundness > gbgl_abs(w)) || (2.0f*roundness > gbgl_abs(h))) { roundness = 0.5f*gbgl_min(gbgl_abs(w), gbgl_abs(h)); @@ -2256,12 +2311,12 @@ void gbgl_bs_draw_rounded_rect_corners(gbglBasicState *bs, f32 x, f32 y, f32 w, } } -gb_inline void gbgl_bs_draw_rounded_rect(gbglBasicState *bs, f32 x, f32 y, f32 w, f32 h, f32 roundness, gbColour col) { +gb_inline void gbgl_bs_draw_rounded_rect(gbglBasicState *bs, f32 x, f32 y, f32 w, f32 h, f32 roundness, gbglColour col) { gbgl_bs_draw_rounded_rect_corners(bs, x, y, w, h, roundness, col, 1|2|4|8); } -void gbgl_bs_draw_rounded_rect_corners_outline(gbglBasicState *bs, f32 x, f32 y, f32 w, f32 h, f32 roundness, gbColour col, f32 thickness, u32 corners) { +void gbgl_bs_draw_rounded_rect_corners_outline(gbglBasicState *bs, f32 x, f32 y, f32 w, f32 h, f32 roundness, gbglColour col, f32 thickness, u32 corners) { if ((2.0f*roundness > gbgl_abs(w)) || (2.0f*roundness > gbgl_abs(h))) { roundness = 0.5f*gbgl_min(gbgl_abs(w), gbgl_abs(h)); @@ -2343,7 +2398,7 @@ void gbgl_bs_draw_rounded_rect_corners_outline(gbglBasicState *bs, f32 x, f32 y, } } -gb_inline void gbgl_bs_draw_rounded_rect_outline(gbglBasicState *bs, f32 x, f32 y, f32 w, f32 h, f32 roundness, gbColour col, f32 thickness) { +gb_inline void gbgl_bs_draw_rounded_rect_outline(gbglBasicState *bs, f32 x, f32 y, f32 w, f32 h, f32 roundness, gbglColour col, f32 thickness) { gbgl_bs_draw_rounded_rect_corners_outline(bs, x, y, w, h, roundness, col, thickness, 1|2|4|8); } @@ -2353,7 +2408,7 @@ gb_inline void gbgl_bs_draw_rounded_rect_outline(gbglBasicState *bs, f32 x, f32 #if !defined(GBGL_NO_FONTS) -isize gbgl_bs_draw_substring(gbglBasicState *bs, gbglFont *font, f32 x, f32 y, gbColour col, char const *str, isize len) { +isize gbgl_bs_draw_substring(gbglBasicState *bs, gbglFont *font, f32 x, f32 y, gbglColour col, char const *str, isize len) { isize char_count = gb_utf8_strnlen(str, len); isize line_count = 0; if (char_count > 0) { @@ -2507,7 +2562,7 @@ isize gbgl_bs_draw_substring(gbglBasicState *bs, gbglFont *font, f32 x, f32 y, g return line_count; } -isize gbgl_bs_draw_string(gbglBasicState *bs, gbglFont *font, f32 x, f32 y, gbColour col, char const *fmt, ...) { +isize gbgl_bs_draw_string(gbglBasicState *bs, gbglFont *font, f32 x, f32 y, gbglColour col, char const *fmt, ...) { isize len; va_list va; va_start(va, fmt); @@ -2516,7 +2571,7 @@ isize gbgl_bs_draw_string(gbglBasicState *bs, gbglFont *font, f32 x, f32 y, gbCo return len; } -gb_inline isize gbgl_bs_draw_string_va(gbglBasicState *bs, gbglFont *font, f32 x, f32 y, gbColour col, char const *fmt, va_list va) { +gb_inline isize gbgl_bs_draw_string_va(gbglBasicState *bs, gbglFont *font, f32 x, f32 y, gbglColour col, char const *fmt, va_list va) { isize len = gb_snprintf_va(bs->font_text_buffer, gb_size_of(bs->font_text_buffer), fmt, va); isize char_count = gb_utf8_strnlen(bs->font_text_buffer, len);