diff --git a/gb.h b/gb.h index 55497cf..7be2452 100644 --- a/gb.h +++ b/gb.h @@ -1,4 +1,4 @@ -/* gb.h - v0.17 - Ginger Bill's C Helper Library - public domain +/* gb.h - v0.17a - 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 @@ -32,11 +32,12 @@ Conventions used: gbTypesAreLikeThis (None core types) gb_functions_and_variables_like_this - Prefer C90 Comments + Prefer C99 // Comments Never use _t suffix for types (I think they are stupid...) Version History: + 0.17a - Dropped C90 Support 0.17 - Instantiated Hash Table 0.16a - Minor code layout changes 0.16 - New file API and improved platform layer @@ -130,7 +131,7 @@ extern "C" { #endif -/* NOTE(bill): Redefine for DLL, etc. */ +// NOTE(bill): Redefine for DLL, etc. #ifndef GB_DEF #ifdef GB_STATIC #define GB_DEF static @@ -151,7 +152,7 @@ extern "C" { #endif #endif -/* TODO(bill): Check if this works on clang */ +// TODO(bill): Check if this works on clang #if defined(__GNUC__) #if defined(__x86_64__) || defined(__ppc64__) #ifndef GB_ARCH_64_BIT @@ -202,19 +203,18 @@ extern "C" { #ifndef GB_STATIC_ASSERT #define GB_STATIC_ASSERT3(cond, msg) typedef char static_assertion_##msg[(!!(cond))*2-1] - /* NOTE(bill): Token pasting madness!! */ + // NOTE(bill): Token pasting madness!! #define GB_STATIC_ASSERT2(cond, line) GB_STATIC_ASSERT3(cond, static_assertion_at_line_##line) #define GB_STATIC_ASSERT1(cond, line) GB_STATIC_ASSERT2(cond, line) #define GB_STATIC_ASSERT(cond) GB_STATIC_ASSERT1(cond, __LINE__) #endif - -/*************************************************************** - * - * Headers - * - */ +//////////////////////////////////////////////////////////////// +// +// Headers +// +// #if defined(_WIN32) && !defined(__MINGW32__) #ifndef _CRT_SECURE_NO_WARNINGS @@ -228,7 +228,7 @@ extern "C" { #endif -/* TODO(bill): How many of these headers do I really need? */ +// TODO(bill): How many of these headers do I really need? #include #include @@ -243,10 +243,10 @@ extern "C" { #undef WIN32_MEAN_AND_LEAN #undef VC_EXTRALEAN - #include /* NOTE(bill): _aligned_*() */ + #include // NOTE(bill): _aligned_*() #include #else - #include /* NOTE(bill): malloc */ + #include // NOTE(bill): malloc #include #include #include @@ -270,11 +270,11 @@ extern "C" { #endif -/*************************************************************** - * - * Base Types - * - */ +//////////////////////////////////////////////////////////////// +// +// Base Types +// +// #if defined(_MSC_VER) #if _MSC_VER < 1300 @@ -321,13 +321,13 @@ typedef ptrdiff_t isize; GB_STATIC_ASSERT(sizeof(usize) == sizeof(isize)); -/* NOTE(bill): (u)intptr is only here for semantic reasons really as this library will only support 32/64 bit OSes. */ -/* NOTE(bill): Are there any modern OSes (not 16 bit) where intptr != isize ? */ +// NOTE(bill): (u)intptr is only here for semantic reasons really as this library will only support 32/64 bit OSes. +// NOTE(bill): Are there any modern OSes (not 16 bit) where intptr != isize ? #if defined(_WIN64) typedef signed __int64 intptr; typedef unsigned __int64 uintptr; #elif defined(_WIN32) - /* NOTE(bill); To mark types changing their size, e.g. intptr */ + // NOTE(bill); To mark types changing their size, e.g. intptr #ifndef _W64 #if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 #define _W64 __w64 @@ -349,18 +349,17 @@ typedef double f64; GB_STATIC_ASSERT(sizeof(f32) == 4); GB_STATIC_ASSERT(sizeof(f64) == 8); -typedef char char8; /* NOTE(bill): Probably redundant but oh well! */ +typedef char char8; // NOTE(bill): Probably redundant but oh well! typedef u16 char16; typedef u32 char32; -/* NOTE(bill): I think C99 and C++ `bool` is stupid for numerous reasons but there are too many - * to write in this small comment. - */ +// NOTE(bill): I think C99 and C++ `bool` is stupid for numerous reasons but there are too many +// to write in this small comment. typedef i8 b8; typedef i16 b16; -typedef i32 b32; /* NOTE(bill): Prefer this!!! */ +typedef i32 b32; // NOTE(bill): Prefer this!!! -/* NOTE(bill): Get true and false */ +// NOTE(bill): Get true and false #if !defined(__cplusplus) #if (defined(_MSC_VER) && _MSC_VER <= 1800) || !defined(__STDC_VERSION__) #ifndef true @@ -374,7 +373,7 @@ typedef i32 b32; /* NOTE(bill): Prefer this!!! */ #endif #endif -/* NOTE(bill): These do are not prefixed with gb because the types are not. */ +// NOTE(bill): These do are not prefixed with gb because the types are not. #ifndef U8_MIN #define U8_MIN 0u #define U8_MAX 0xffu @@ -436,7 +435,7 @@ typedef i32 b32; /* NOTE(bill): Prefer this!!! */ #endif -/* TODO(bill): Is this enough to get inline working? */ +// TODO(bill): Is this enough to get inline working? #if !defined(__cplusplus) #if defined(_MSC_VER) && _MSC_VER <= 1800 #define inline __inline @@ -458,7 +457,7 @@ typedef i32 b32; /* NOTE(bill): Prefer this!!! */ #endif #endif -/* TODO(bill): Should force inline be a separate keyword and gb_inline be inline? */ +// TODO(bill): Should force inline be a separate keyword and gb_inline be inline? #if !defined(gb_inline) #if defined(_MSC_VER) #if _MSC_VER < 1300 @@ -479,14 +478,14 @@ typedef i32 b32; /* NOTE(bill): Prefer this!!! */ #endif #endif -/* NOTE(bill): Easy to grep */ -/* NOTE(bill): Not needed in macros */ +// NOTE(bill): Easy to grep +// NOTE(bill): Not needed in macros #ifndef cast #define cast(Type) (Type) #endif -/* NOTE(bill): Because a signed sizeof is more useful */ +// NOTE(bill): Because a signed sizeof is more useful #ifndef gb_size_of #define gb_size_of(x) (isize)(sizeof(x)) #endif @@ -505,7 +504,7 @@ typedef i32 b32; /* NOTE(bill): Prefer this!!! */ #define gb_align_of(Type) (isize)alignof(Type) #else extern "C++" { - /* NOTE(bill): Fucking Templates! */ + // NOTE(bill): Fucking Templates! template struct gbAlignment_Trick { char c; T member; }; #define gb_align_of(Type) gb_offset_of(gbAlignment_Trick, member) } @@ -517,16 +516,16 @@ extern "C++" { #endif #endif -/* NOTE(bill): I do wish I had a type_of that was portable */ +// NOTE(bill): I do wish I had a type_of that was portable #ifndef gb_swap #define gb_swap(Type, a, b) do { Type tmp = (a); (a) = (b); (b) = tmp; } while (0) #endif -/* NOTE(bill): Because static means 3/4 different things in C/C++. Great design (!) */ +// NOTE(bill): Because static means 3/4 different things in C/C++. Great design (!) #ifndef gb_global -#define gb_global static /* Global variables */ -#define gb_internal static /* Internal linkage */ -#define gb_local_persist static /* Local Persisting variables */ +#define gb_global static // Global variables +#define gb_internal static // Internal linkage +#define gb_local_persist static // Local Persisting variables #endif @@ -537,50 +536,46 @@ extern "C++" { - -/*************************************************************** - * - * Defer statement - * Akin to D's SCOPE_EXIT or - * similar to Go's defer but scope-based - * - * NOTE: C++11 (and above) only! - */ +//////////////////////////////////////////////////////////////// +// +// Defer statement +// Akin to D's SCOPE_EXIT or +// similar to Go's defer but scope-based +// +// NOTE: C++11 (and above) only! +// #if defined(__cplusplus) && __cplusplus >= 201103L #if 1 extern "C++" { #endif -namespace gb { + // NOTE(bill): Stupid fucking templates + template struct gbRemoveReference { typedef T Type; }; + template struct gbRemoveReference { typedef T Type; }; + template struct gbRemoveReference { typedef T Type; }; - /* NOTE(bill): Stupid fucking templates */ - template struct RemoveReference { typedef T Type; }; - template struct RemoveReference { typedef T Type; }; - template struct RemoveReference { typedef T Type; }; - - /* NOTE(bill): "Move" semantics - invented because the C++ committee are idiots (as a collective not as indiviuals (well a least some aren't)) */ - template inline T &&forward(typename RemoveReference::Type &t) { return static_cast(t); } - template inline T &&forward(typename RemoveReference::Type &&t) { return static_cast(t); } - template inline T &&move (T &&t) { return static_cast::Type &&>(t); } + /// NOTE(bill): "Move" semantics - invented because the C++ committee are idiots (as a collective not as indiviuals (well a least some aren't)) + template inline T &&gb_forward(typename gbRemoveReference::Type &t) { return static_cast(t); } + template inline T &&gb_forward(typename gbRemoveReference::Type &&t) { return static_cast(t); } + template inline T &&gb_move (T &&t) { return static_cast::Type &&>(t); } template - struct privDefer { + struct gbprivDefer { F f; - privDefer(F &&f) : f(forward(f)) {} - ~privDefer() { f(); } + gbprivDefer(F &&f) : f(gb_forward(f)) {} + ~gbprivDefer() { f(); } }; - template privDefer priv_defer_func(F &&f) { return privDefer(forward(f)); } + template gbprivDefer gb__defer_func(F &&f) { return gbprivDefer(gb_forward(f)); } #ifndef defer #define GB_DEFER_1(x, y) x##y #define GB_DEFER_2(x, y) GB_DEFER_1(x, y) #define GB_DEFER_3(x) GB_DEFER_2(x, __COUNTER__) - #define defer(code) auto GB_DEFER_3(_defer_) = gb::priv_defer_func([&](){code;}) + #define defer(code) auto GB_DEFER_3(_defer_) = gb__defer_func([&](){code;}) #endif -} /* namespace gb */ #if 1 } #endif -/* Example */ +// Example #if 0 gbMutex m; gb_mutex_init(&m); @@ -595,11 +590,11 @@ namespace gb { #endif -/*************************************************************** - * - * Macro Fun! - * - */ +//////////////////////////////////////////////////////////////// +// +// Macro Fun! +// +// #ifndef GB_JOIN_MACROS #define GB_JOIN_MACROS @@ -636,24 +631,24 @@ namespace gb { #endif -/* NOTE(bill): Some compilers support applying printf-style warnings to user functions. */ +// NOTE(bill): Some compilers support applying printf-style warnings to user functions. #if defined(__clang__) || defined(__GNUC__) #define GB_PRINTF_ARGS(FMT) __attribute__((format(printf, FMT, (FMT+1)))) #else #define GB_PRINTF_ARGS(FMT) #endif -/*************************************************************** - * - * Debug - * - */ +//////////////////////////////////////////////////////////////// +// +// Debug +// +// #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 @@ -663,9 +658,9 @@ namespace gb { #endif #ifndef GB_ASSERT_MSG -#define GB_ASSERT_MSG(cond, msg) do { \ +#define GB_ASSERT_MSG(cond, msg, ...) do { \ if (!(cond)) { \ - gb_assert_handler(#cond, __FILE__, cast(i64)__LINE__, msg); \ + gb_assert_handler(#cond, __FILE__, cast(i64)__LINE__, msg, ##__VA_ARGS__); \ GB_DEBUG_TRAP(); \ } \ } while (0) @@ -679,20 +674,20 @@ namespace gb { #define GB_ASSERT_NOT_NULL(ptr) GB_ASSERT_MSG((ptr) != NULL, #ptr " must not be NULL") #endif -/* NOTE(bill): Things that shouldn't happen with a message! */ +// NOTE(bill): Things that shouldn't happen with a message! #ifndef GB_PANIC #define GB_PANIC(msg) GB_ASSERT_MSG(0, msg) #endif -GB_DEF void gb_assert_handler(char const *condition, char const *file, i32 line, char const *msg); +GB_DEF void gb_assert_handler(char const *condition, char const *file, i32 line, char const *msg, ...); -/*************************************************************** - * - * Memory - * - */ +//////////////////////////////////////////////////////////////// +// +// Memory +// +// GB_DEF b32 gb_is_power_of_two(isize x); @@ -708,7 +703,7 @@ GB_DEF isize gb_pointer_diff (void const *begin, void const *end); GB_DEF void gb_zero_size(void *ptr, isize size); #ifndef gb_zero_item -#define gb_zero_item(t) gb_zero_size((t), gb_size_of(*(t))) /* NOTE(bill): Pass pointer of struct */ +#define gb_zero_item(t) gb_zero_size((t), gb_size_of(*(t))) // NOTE(bill): Pass pointer of struct #define gb_zero_array(a, count) gb_zero_size((a), gb_size_of(*(a))*count) #endif @@ -719,7 +714,7 @@ GB_DEF i32 gb_memcompare(void const *s1, void const *s2, isize size); GB_DEF void gb_memswap (void *i, void *j, isize size); -/* NOTE(bill): Very similar to doing `*cast(T *)(&u)` */ +// NOTE(bill): Very similar to doing `*cast(T *)(&u)` #ifndef GB_BIT_CAST #define GB_BIT_CAST(dest, source) do { \ GB_STATIC_ASSERT(gb_size_of(*(dest)) <= gb_size_of(source)); \ @@ -740,7 +735,7 @@ GB_DEF void gb_memswap (void *i, void *j, isize size); -/* Atomics */ +// Atomics #if defined(_MSC_VER) typedef struct gbAtomic32 { i32 volatile value; } gbAtomic32; typedef struct gbAtomic64 { i64 volatile value; } gbAtomic64; @@ -824,7 +819,7 @@ GB_DEF void gb_semaphore_post (gbSemaphore *s, i32 count); GB_DEF void gb_semaphore_wait (gbSemaphore *s); -/* Mutex */ +// Mutex typedef struct gbMutex { gbSemaphore semaphore; gbAtomic32 counter; @@ -838,9 +833,8 @@ GB_DEF void gb_mutex_lock (gbMutex *m); GB_DEF b32 gb_mutex_try_lock(gbMutex *m); GB_DEF void gb_mutex_unlock (gbMutex *m); -/* NOTE(bill): If you wanted a Scoped Mutex in C++, why not use the defer() construct? - * No need for a silly wrapper class and it's clear! - */ +// NOTE(bill): If you wanted a Scoped Mutex in C++, why not use the defer() construct? +// No need for a silly wrapper class and it's clear! #if 0 gbMutex m = {0}; gb_mutex_init(&m); @@ -848,11 +842,11 @@ gb_mutex_init(&m); gb_mutex_lock(&m); defer (gb_mutex_unlock(&m)); - /* Do whatever as the mutex is now scoped based! */ + // Do whatever as the mutex is now scoped based! } #endif -/* TODO(bill): Should I create a Condition Type? (gbCond vs gbCondition) */ +// TODO(bill): Should I create a Condition Type? (gbCond vs gbCondition) @@ -886,14 +880,15 @@ GB_DEF u32 gb_thread_current_id (void); GB_DEF void gb_thread_set_name (gbThread *t, char const *name); -/*************************************************************** - * - * Virtual Memory - * - * Still incomplete and needs working on a lot as it's shit! - */ +//////////////////////////////////////////////////////////////// +// +// Virtual Memory +// +// Still incomplete and needs working on a lot as it's shit! +// -/* TODO(bill): Track a lot more than just the pointer and size! */ + +// TODO(bill): Track a lot more than just the pointer and size! typedef struct gbVirtualMemory { void *data; @@ -908,11 +903,11 @@ GB_DEF b32 gb_vm_purge(gbVirtualMemory vm); -/*************************************************************** - * - * Custom Allocation - * - */ +//////////////////////////////////////////////////////////////// +// +// Custom Allocation +// +// typedef enum gbAllocationType { GB_ALLOCATION_ALLOC, @@ -921,7 +916,7 @@ typedef enum gbAllocationType { GB_ALLOCATION_RESIZE } gbAllocationType; -/* NOTE(bill): This is useful so you can define an allocator of the same type and parameters */ +// NOTE(bill): This is useful so you can define an allocator of the same type and parameters #define GB_ALLOCATOR_PROC(name) \ void *name(void *allocator_data, gbAllocationType type, \ isize size, isize alignment, \ @@ -944,7 +939,7 @@ GB_DEF void gb_free (gbAllocator a, void *ptr); GB_DEF void gb_free_all (gbAllocator a); GB_DEF void *gb_resize (gbAllocator a, void *ptr, isize old_size, isize new_size); GB_DEF void *gb_resize_align(gbAllocator a, void *ptr, isize old_size, isize new_size, isize alignment); -/* TODO(bill): For gb_resize, should the use need to pass the old_size or only the new_size? */ +// TODO(bill): For gb_resize, should the use need to pass the old_size or only the new_size? GB_DEF void *gb_alloc_copy (gbAllocator a, void const *src, isize size); GB_DEF void *gb_alloc_copy_align(gbAllocator a, void const *src, isize size, isize alignment); @@ -952,34 +947,32 @@ GB_DEF void *gb_alloc_copy_align(gbAllocator a, void const *src, isize size, isi GB_DEF char *gb_alloc_str(gbAllocator a, char const *str); -/* NOTE(bill): These are very useful and the type cast has saved me from numerous bugs */ +// NOTE(bill): These are very useful and the type cast has saved me from numerous bugs #ifndef gb_alloc_struct #define gb_alloc_struct(allocator, Type) (Type *)gb_alloc(allocator, gb_size_of(Type)) #define gb_alloc_array(allocator, Type, count) (Type *)gb_alloc(allocator, gb_size_of(Type) * (count)) #endif -/* NOTE(bill): Use this if you don't need a "fancy" resize allocation */ +// NOTE(bill): Use this if you don't need a "fancy" resize allocation GB_DEF void *gb_default_resize_align(gbAllocator a, void *ptr, isize old_size, isize new_size, isize alignment); -/* TODO(bill): Probably use a custom heap allocator system that doesn't depend on malloc/free - * Base it off TCMalloc or something else? Or something entirely custom? - */ +// TODO(bill): Probably use a custom heap allocator system that doesn't depend on malloc/free +// Base it off TCMalloc or something else? Or something entirely custom? GB_DEF gbAllocator gb_heap_allocator(void); GB_DEF GB_ALLOCATOR_PROC(gb_heap_allocator_proc); -/* NOTE(bill): Yep, I use my own allocator system! */ +// NOTE(bill): Yep, I use my own allocator system! #ifndef gb_malloc #define gb_malloc(sz) gb_alloc(gb_heap_allocator(), sz) #define gb_mfree(ptr) gb_free(gb_heap_allocator(), ptr) #endif -/* - * Arena Allocator - */ - +// +// Arena Allocator +// typedef struct gbArena { gbAllocator backing; void *physical_start; @@ -998,7 +991,7 @@ GB_DEF isize gb_arena_size_remaining(gbArena *arena, isize alignment); GB_DEF void gb_arena_check (gbArena *arena); -/* Allocation Types: alloc, free_all, resize */ +// Allocation Types: alloc, free_all, resize GB_DEF gbAllocator gb_arena_allocator(gbArena *arena); GB_DEF GB_ALLOCATOR_PROC(gb_arena_allocator_proc); @@ -1018,9 +1011,9 @@ GB_DEF void gb_temp_arena_memory_end (gbTempArenaMemory tmp_mem); -/* - * Pool Allocator - */ +// +// Pool Allocator +// typedef struct gbPool { @@ -1038,13 +1031,13 @@ GB_DEF void gb_pool_init (gbPool *pool, gbAllocator backing, isize num_bloc GB_DEF void gb_pool_init_align(gbPool *pool, gbAllocator backing, isize num_blocks, isize block_size, isize block_align); GB_DEF void gb_pool_free (gbPool *pool); -/* Allocation Types: alloc, free */ +// Allocation Types: alloc, free GB_DEF gbAllocator gb_pool_allocator(gbPool *pool); GB_DEF GB_ALLOCATOR_PROC(gb_pool_allocator_proc); -/* NOTE(bill): Used for allocators to keep track of sizes */ +// NOTE(bill): Used for allocators to keep track of sizes typedef struct gbAllocationHeader { isize size; } gbAllocationHeader; @@ -1052,7 +1045,7 @@ typedef struct gbAllocationHeader { GB_DEF gbAllocationHeader *gb_allocation_header (void *data); GB_DEF void gb_allocation_header_fill(gbAllocationHeader *header, void *data, isize size); -/* TODO(bill): Find better way of doing this without #if #elif etc. */ +// TODO(bill): Find better way of doing this without #if #elif etc. #if defined(GB_ARCH_32_BIT) #define GB_ISIZE_HIGH_BIT 0x80000000 #elif defined(GB_ARCH_64_BIT) @@ -1061,15 +1054,15 @@ GB_DEF void gb_allocation_header_fill(gbAllocationHeader *header, #error #endif -/* - * Free List Allocator - */ +// +// Free List Allocator +// -/* IMPORTANT TODO(bill): Thoroughly test the free list allocator! */ -/* NOTE(bill): This is a very shitty free list as it just picks the first free block not the best size - * as I am just being lazy. Also, I will probably remove it later; it's only here because why not?! - */ -/* NOTE(bill): I may also complete remove this if I completely implement a fixed heap allocator */ +// IMPORTANT TODO(bill): Thoroughly test the free list allocator! +// NOTE(bill): This is a very shitty free list as it just picks the first free block not the best size +// as I am just being lazy. Also, I will probably remove it later; it's only here because why not?! +// +// NOTE(bill): I may also complete remove this if I completely implement a fixed heap allocator typedef struct gbFreeListBlock { @@ -1090,15 +1083,15 @@ typedef struct gbFreeList { GB_DEF void gb_free_list_init (gbFreeList *fl, void *start, isize size); GB_DEF void gb_free_list_init_from_allocator(gbFreeList *fl, gbAllocator backing, isize size); -/* Allocation Types: alloc, free, free_all, resize */ +// Allocation Types: alloc, free, free_all, resize GB_DEF gbAllocator gb_free_list_allocator(gbFreeList *fl); GB_DEF GB_ALLOCATOR_PROC(gb_free_list_allocator_proc); -/* - * Scratch Memory Allocator - Ring Buffer Based Arena - */ +// +// Scratch Memory Allocator - Ring Buffer Based Arena +// typedef struct gbScratchMemory { void *physical_start; @@ -1110,31 +1103,30 @@ GB_DEF void gb_scratch_memory_init (gbScratchMemory *s, void *start, isize s GB_DEF b32 gb_scratch_memory_is_in_use(gbScratchMemory *s, void *ptr); -/* Allocation Types: alloc, free, free_all, resize */ +// Allocation Types: alloc, free, free_all, resize GB_DEF gbAllocator gb_scratch_allocator(gbScratchMemory *s); GB_DEF GB_ALLOCATOR_PROC(gb_scratch_allocator_proc); -/* TODO(bill): Stack allocator */ -/* TODO(bill): Fixed heap allocator */ -/* TODO(bill): General heap allocator. Maybe a TCMalloc like clone? */ +// TODO(bill): Stack allocator +// TODO(bill): Fixed heap allocator +// TODO(bill): General heap allocator. Maybe a TCMalloc like clone? -/*************************************************************** - * - * Sort & Search - * - */ +//////////////////////////////////////////////////////////////// +// +// Sort & Search +// +// #define GB_COMPARE_PROC(name) int name(void const *a, void const *b) typedef GB_COMPARE_PROC(gbCompareProc); #define GB_COMPARE_PROC_PTR(def) GB_COMPARE_PROC((*def)) -/* Producure pointers */ -/* NOTE(bill): The offset parameter specifies the offset in the structure - * e.g. gb_i32_cmp(gb_offset_of(Thing, value)) - * Use 0 if it's just the type instead. - */ +// Producure pointers +// NOTE(bill): The offset parameter specifies the offset in the structure +// e.g. gb_i32_cmp(gb_offset_of(Thing, value)) +// Use 0 if it's just the type instead. GB_DEF GB_COMPARE_PROC_PTR(gb_i16_cmp (isize offset)); GB_DEF GB_COMPARE_PROC_PTR(gb_i32_cmp (isize offset)); @@ -1145,12 +1137,12 @@ GB_DEF GB_COMPARE_PROC_PTR(gb_f32_cmp (isize offset)); GB_DEF GB_COMPARE_PROC_PTR(gb_f64_cmp (isize offset)); GB_DEF GB_COMPARE_PROC_PTR(gb_char_cmp (isize offset)); -/* TODO(bill): Better sorting algorithms */ -/* NOTE(bill): Uses quick sort for large arrays but insertion sort for small */ +// TODO(bill): Better sorting algorithms +// NOTE(bill): Uses quick sort for large arrays but insertion sort for small #define gb_sort_array(array, count, compare_proc) gb_sort(array, count, gb_size_of(*(array)), compare_proc) GB_DEF void gb_sort(void *base, isize count, isize size, gbCompareProc compare_proc); -/* NOTE(bill): the count of temp == count of items */ +// NOTE(bill): the count of temp == count of items #define gb_radix_sort(Type) gb_radix_sort_##Type #define GB_RADIX_SORT_PROC(Type) void gb_radix_sort(Type)(Type *gb_restrict items, Type *gb_restrict temp, isize count) @@ -1160,17 +1152,17 @@ GB_DEF GB_RADIX_SORT_PROC(u32); GB_DEF GB_RADIX_SORT_PROC(u64); -/* NOTE(bill): Returns index or -1 if not found */ +// NOTE(bill): Returns index or -1 if not found #define gb_binary_search_array(array, count, key, compare_proc) gb_binary_search(array, count, gb_size_of(*(array)), key, compare_proc) GB_DEF isize gb_binary_search(void const *base, isize count, isize size, void const *key, gbCompareProc compare_proc); -/*************************************************************** - * - * Char Functions - * - */ +//////////////////////////////////////////////////////////////// +// +// Char Functions +// +// GB_DEF char gb_char_to_lower (char c); GB_DEF char gb_char_to_upper (char c); @@ -1182,7 +1174,7 @@ GB_DEF b32 gb_char_is_alphanumeric(char c); GB_DEF i32 gb_digit_to_int (char c); GB_DEF i32 gb_hex_digit_to_int (char c); -/* NOTE(bill): ASCII only */ +// NOTE(bill): ASCII only GB_DEF void gb_str_to_lower(char *str); GB_DEF void gb_str_to_upper(char *str); @@ -1193,11 +1185,9 @@ GB_DEF i32 gb_strncmp(char const *s1, char const *s2, isize len); GB_DEF char *gb_strcpy (char *dest, char const *source); GB_DEF char *gb_strncpy(char *dest, char const *source, isize len); GB_DEF isize gb_strlcpy(char *dest, char const *source, isize len); -GB_DEF char *gb_strrev (char *str); +GB_DEF char *gb_strrev (char *str); // NOTE(bill): ASCII only - - -/* NOTE(bill): A less fucking crazy strtok! */ +// NOTE(bill): A less fucking crazy strtok! GB_DEF char const *gb_strtok(char *output, char const *src, char const *delimit); GB_DEF b32 gb_str_has_prefix(char const *str, char const *prefix); @@ -1210,36 +1200,37 @@ GB_DEF void gb_str_concat(char *dest, isize dest_len, char const *src_a, isize src_a_len, char const *src_b, isize src_b_len); -GB_DEF i64 gb_str_to_i64(char const *str, char **end_ptr, i32 base); /* TODO(bill): Support more than just decimal and hexadecimal */ +GB_DEF i64 gb_str_to_i64(char const *str, char **end_ptr, i32 base); // TODO(bill): Support more than just decimal and hexadecimal GB_DEF void gb_i64_to_str(i64 value, char *string, i32 base); GB_DEF void gb_u64_to_str(u64 value, char *string, i32 base); -/*************************************************************** - * - * UTF-8 Handling - * - * - */ +//////////////////////////////////////////////////////////////// +// +// UTF-8 Handling +// +// GB_DEF isize gb_utf8_strlen (char const *str); GB_DEF isize gb_utf8_strnlen(char const *str, isize max_len); -/* Windows doesn't handle 8 bit filenames well ('cause Micro$hit) */ -GB_DEF char16 *gb_utf8_to_ucs2(char16 *buffer, isize len, char const *str); -GB_DEF char * gb_ucs2_to_utf8(char *buffer, isize len, char16 const *str); +// NOTE(bill): Windows doesn't handle 8 bit filenames well ('cause Micro$hit) +GB_DEF char16 *gb_utf8_to_ucs2 (char16 *buffer, isize len, char const *str); +GB_DEF char * gb_ucs2_to_utf8 (char *buffer, isize len, char16 const *str); +GB_DEF char16 *gb_utf8_to_ucs2_buf(char const *str); // NOTE(bill): Uses locally persisting buffer +GB_DEF char * gb_ucs2_to_utf8_buf(char16 const *str); // NOTE(bill): Uses locally persisting buffer -/* NOTE(bill): Returns size of codepoint in bytes */ +// NOTE(bill): Returns size of codepoint in bytes GB_DEF isize gb_utf8_decode (char const *str, char32 *codepoint); GB_DEF isize gb_utf8_decode_len(char const *str, isize str_len, char32 *codepoint); -/*************************************************************** - * - * gbString - C Read-Only-Compatible - * - * - +//////////////////////////////////////////////////////////////// +// +// gbString - C Read-Only-Compatible +// +// +/* Reasoning: By default, strings in C are null terminated which means you have to count @@ -1293,7 +1284,7 @@ Disadvantages: This could be changed to gb_string_appendc(&str, "another string"); but I'm still not sure. * This is incompatible with "gb_string.h" strings - */ +*/ #if 0 #include @@ -1309,12 +1300,12 @@ int main(int argc, char **argv) str = gb_string_append(str, other_str); str = gb_string_appendc(str, "world!"); - printf("%s\n", str); /* Hello, world! */ + printf("%s\n", str); // Hello, world! printf("str length = %d\n", gb_string_length(str)); str = gb_string_set(str, "Potato soup"); - printf("%s\n", str); /* Potato soup */ + printf("%s\n", str); // Potato soup str = gb_string_set(str, "Hello"); other_str = gb_string_set(other_str, "Pizza"); @@ -1325,7 +1316,7 @@ int main(int argc, char **argv) str = gb_string_set(str, "Ab.;!...AHello World ??"); str = gb_string_trim(str, "Ab.;!. ?"); - printf("%s\n", str); /* "Hello World" */ + printf("%s\n", str); // "Hello World" gb_string_free(str); gb_string_free(other_str); @@ -1336,7 +1327,7 @@ int main(int argc, char **argv) typedef char *gbString; -/* NOTE(bill): If you only need a small string, just use a standard c string or change the size from isize to u16, etc. */ +// NOTE(bill): If you only need a small string, just use a standard c string or change the size from isize to u16, etc. typedef struct gbStringHeader { gbAllocator allocator; isize length; @@ -1361,19 +1352,18 @@ GB_DEF gbString gb_string_make_space_for (gbString str, isize add_len); GB_DEF isize gb_string_allocation_size(gbString const str); GB_DEF b32 gb_string_are_equal (gbString const lhs, gbString const rhs); GB_DEF gbString gb_string_trim (gbString str, char const *cut_set); -GB_DEF gbString gb_string_trim_space (gbString str); /* Whitespace ` \t\r\n\v\f` */ +GB_DEF gbString gb_string_trim_space (gbString str); // Whitespace ` \t\r\n\v\f` -/*************************************************************** - * - * Fixed Capacity Buffer (POD Types) - * - * - gbBuffer(Type) works like gbString or gbArray where the actual type is just a pointer to the first - element. - - */ +//////////////////////////////////////////////////////////////// +// +// Fixed Capacity Buffer (POD Types) +// +// +// gbBuffer(Type) works like gbString or gbArray where the actual type is just a pointer to the first +// element. +// typedef struct gbBufferHeader { isize count; @@ -1411,34 +1401,33 @@ typedef struct gbBufferHeader { -/*************************************************************** - * - * Dynamic Array (POD Types) - * - NOTE(bill): I know this is a macro hell but C is an old (and shit) language with no proper arrays - Also why the fuck not?! It fucking works! And it has custom allocation, which is already better than C++! +//////////////////////////////////////////////////////////////// +// +// Dynamic Array (POD Types) +// +// NOTE(bill): I know this is a macro hell but C is an old (and shit) language with no proper arrays +// Also why the fuck not?! It fucking works! And it has custom allocation, which is already better than C++! +// +// gbArray(Type) works like gbString or gbBuffer where the actual type is just a pointer to the first +// element. +// - gbArray(Type) works like gbString or gbBuffer where the actual type is just a pointer to the first - element. - */ +// Available Procedures for gbArray(Type) +// gb_array_init +// gb_array_free +// gb_array_set_capacity +// gb_array_grow +// gb_array_append +// gb_array_appendv +// gb_array_pop +// gb_array_clear +// gb_array_resize +// gb_array_reserve +// - -/* Available Procedures for gbArray(Type) - * gb_array_init - * gb_array_free - * gb_array_set_capacity - * gb_array_grow - * gb_array_append - * gb_array_appendv - * gb_array_pop - * gb_array_clear - * gb_array_resize - * gb_array_reserve - */ - -#if 0 /* Example */ +#if 0 // Example void foo(void) { isize i; @@ -1453,27 +1442,25 @@ void foo(void) gb_array_append(items, 9); gb_array_append(items, 16); - items[1] = 3; /* Manually set value */ - /* NOTE: No array bounds checking */ + items[1] = 3; // Manually set value + // NOTE: No array bounds checking for (i = 0; i < items.count; i++) gb_printf("%d\n", items[i]); - /* 1 - * 3 - * 9 - * 16 - */ + // 1 + // 3 + // 9 + // 16 gb_array_clear(items); gb_array_appendv(items, test_values, gb_count_of(test_values)); for (i = 0; i < items.count; i++) gb_printf("%d\n", items[i]); - /* 4 - * 2 - * 1 - * 7 - */ + // 4 + // 2 + // 1 + // 7 gb_array_free(items); } @@ -1485,7 +1472,7 @@ typedef struct gbArrayHeader { isize capacity; } gbArrayHeader; -/* NOTE(bill): This thing is magic! */ +// NOTE(bill): This thing is magic! #define gbArray(Type) Type * #ifndef GB_ARRAY_GROW_FORMULA @@ -1499,7 +1486,7 @@ GB_STATIC_ASSERT(GB_ARRAY_GROW_FORMULA(0) > 0); #define gb_array_count(x) (GB_ARRAY_HEADER(x)->count) #define gb_array_capacity(x) (GB_ARRAY_HEADER(x)->capacity) -/* TODO(bill): Have proper alignment! */ +// TODO(bill): Have proper alignment! #define gb_array_init_reserve(x, allocator_, cap) do { \ void **gb__array_ = cast(void **)&(x); \ gbArrayHeader *gb__ah = cast(gbArrayHeader *)gb_alloc(allocator_, gb_size_of(gbArrayHeader)+gb_size_of(*(x))*(cap)); \ @@ -1508,7 +1495,7 @@ GB_STATIC_ASSERT(GB_ARRAY_GROW_FORMULA(0) > 0); *gb__array_ = cast(void *)(gb__ah+1); \ } while (0) -/* NOTE(bill): Give it an initial default capacity */ +// NOTE(bill): Give it an initial default capacity #define gb_array_init(x, allocator) gb_array_init_reserve(x, allocator, GB_ARRAY_GROW_FORMULA(0)) #define gb_array_free(x) do { \ @@ -1523,11 +1510,11 @@ GB_STATIC_ASSERT(GB_ARRAY_GROW_FORMULA(0) > 0); } \ } while (0) -/* NOTE(bill): Do not use the thing below directly, use the macro */ +// NOTE(bill): Do not use the thing below directly, use the macro GB_DEF void *gb__array_set_capacity(void *array, isize capacity, isize element_size); -/* TODO(bill): Decide on a decent growing formula for gbArray */ +// TODO(bill): Decide on a decent growing formula for gbArray #define gb_array_grow(x, min_capacity) do { \ isize new_capacity = GB_ARRAY_GROW_FORMULA(gb_array_capacity(x)); \ if (new_capacity < (min_capacity)) \ @@ -1572,11 +1559,11 @@ GB_DEF void *gb__array_set_capacity(void *array, isize capacity, isize element_s -/*************************************************************** - * - * Hashing and Checksum Functions - * - */ +//////////////////////////////////////////////////////////////// +// +// Hashing and Checksum Functions +// +// GB_EXTERN u32 gb_adler32(void const *data, isize len); @@ -1588,8 +1575,8 @@ GB_EXTERN u64 gb_fnv64 (void const *data, isize len); GB_EXTERN u32 gb_fnv32a(void const *data, isize len); GB_EXTERN u64 gb_fnv64a(void const *data, isize len); -/* NOTE(bill): Default seed of 0x9747b28c */ -/* NOTE(bill): I prefer using murmur64 for most hashes */ +// NOTE(bill): Default seed of 0x9747b28c +// NOTE(bill): I prefer using murmur64 for most hashes GB_EXTERN u32 gb_murmur32(void const *data, isize len); GB_EXTERN u64 gb_murmur64(void const *data, isize len); @@ -1597,24 +1584,24 @@ GB_EXTERN u32 gb_murmur32_seed(void const *data, isize len, u32 seed); GB_EXTERN u64 gb_murmur64_seed(void const *data, isize len, u64 seed); -/*************************************************************** - * - * Instantiated Hash Table - * - * This is an attempt to implement a templated hash table - * NOTE(bill): The key is aways a u64 for simplicity and you will _probably_ _never_ need anything bigger. - * - * Hash table type and function declaration, call: GB_TABLE_DECLARE(PREFIX, NAME, N, VALUE) - * Hash table function definitions, call: GB_TABLE_DEFINE(NAME, N, VALUE) - * - * PREFIX - a prefix for function prototypes e.g. extern, static, etc. - * NAME - Name of the Hash Table - * N - 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 - * NOTE(bill): I really wish C had decent metaprogramming capabilities (and no I don't mean C++'s templates either) - */ +//////////////////////////////////////////////////////////////// +// +// Instantiated Hash Table +// +// This is an attempt to implement a templated hash table +// NOTE(bill): The key is aways a u64 for simplicity and you will _probably_ _never_ need anything bigger. +// +// Hash table type and function declaration, call: GB_TABLE_DECLARE(PREFIX, NAME, N, VALUE) +// Hash table function definitions, call: GB_TABLE_DEFINE(NAME, N, VALUE) +// +// PREFIX - a prefix for function prototypes e.g. extern, static, etc. +// NAME - Name of the Hash Table +// N - 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 +// NOTE(bill): I really wish C had decent metaprogramming capabilities (and no I don't mean C++'s templates either) +// typedef struct gbHashTableFindResult { @@ -1901,11 +1888,11 @@ GB_JOIN2(N,clear)(NAME *h) \ } \ -/*************************************************************** - * - * File Handling - * - */ + +//////////////////////////////////////////////////////////////// +// +// File Handling +// typedef u32 gbFileMode; @@ -1916,7 +1903,7 @@ typedef enum gbFileFlag { GB_FILE_RW = GB_BIT(3) } gbFileFlag; -/* TODO(bill): Is seek a silly idea? */ +// TODO(bill): Is seek a silly idea? typedef enum gbSeekWhence { GB_SEEK_BEGIN = 0, GB_SEEK_CURRENT = 1, @@ -1960,36 +1947,38 @@ struct gbFileOperations { extern gbFileOperations const GB_DEFAULT_FILE_OPERATIONS; -/* -typedef struct gbDirInfo { - u8 *buf; - isize buf_count; - isize buf_pos; -} gbDirInfo; -*/ + +// typedef struct gbDirInfo { +// u8 *buf; +// isize buf_count; +// isize buf_pos; +// } gbDirInfo; + typedef u64 gbFileTime; typedef struct gbFile { - gbFileDescriptor fd; gbFileOperations const *ops; + gbFileDescriptor fd; char const *filename; - /* gbDirInfo *dir_info; */ /* TODO(bill): Get directory info */ gbFileTime last_write_time; + // gbDirInfo *dir_info; // TODO(bill): Get directory info } gbFile; typedef enum gbFileStandardType { GB_FILE_STANDARD_INPUT, GB_FILE_STANDARD_OUTPUT, - GB_FILE_STANDARD_ERROR + GB_FILE_STANDARD_ERROR, + + GB_FILE_STANDARD_COUNT } gbFileStandardType; -GB_DEF gbFile gb_file_get_std(gbFileStandardType std); +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); -/* TODO(bill): Get a better name for it */ +// 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_new (gbFile *file, gbFileDescriptor fd, gbFileOperations const *ops, 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); GB_DEF b32 gb_file_read_at (gbFile *file, void *buffer, isize size, i64 offset); @@ -2002,11 +1991,10 @@ GB_DEF i64 gb_file_tell (gbFile *file); GB_DEF i64 gb_file_size (gbFile *file); GB_DEF char const *gb_file_name (gbFile *file); GB_DEF gbFileError gb_file_truncate (gbFile *file, i64 size); -GB_DEF b32 gb_file_has_changed (gbFile *file); /* NOTE(bill): Changed since lasted checked */ -/* TODO(bill): - gbFileError gb_file_temp(gbFile *file); - - */ +GB_DEF b32 gb_file_has_changed (gbFile *file); // NOTE(bill): Changed since lasted checked +// TODO(bill): +// gbFileError gb_file_temp(gbFile *file); +// typedef struct gbFileContents { gbAllocator allocator; @@ -2019,7 +2007,7 @@ GB_DEF gbFileContents gb_file_read_contents(gbAllocator a, b32 zero_terminate, c 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 * ??? */ +// 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 b32 gb_file_copy (char const *existing_filename, char const *new_filename, b32 fail_if_exists); @@ -2041,14 +2029,14 @@ GB_DEF char const *gb_path_base_name (char const *path); GB_DEF char const *gb_path_extension (char const *path); -/*************************************************************** - * - * Printing - * - */ +//////////////////////////////////////////////////////////////// +// +// Printing +// +// -/* TODO(bill): Allow printf-ing to a gbFile!!! */ +// TODO(bill): Allow printf-ing to a gbFile!!! GB_DEF isize gb_printf (char const *fmt, ...) GB_PRINTF_ARGS(1); GB_DEF isize gb_printf_va (char const *fmt, va_list va); @@ -2057,16 +2045,16 @@ GB_DEF isize gb_printf_err_va (char const *fmt, va_list va); GB_DEF isize gb_fprintf (gbFile *f, char const *fmt, ...) GB_PRINTF_ARGS(2); GB_DEF isize gb_fprintf_va (gbFile *f, char const *fmt, va_list va); -GB_DEF char *gb_bprintf (char const *fmt, ...) GB_PRINTF_ARGS(1); /* NOTE(bill): A locally persisting buffer is used internally */ -GB_DEF char *gb_bprintf_va (char const *fmt, va_list va); /* NOTE(bill): A locally persisting buffer is used internally */ +GB_DEF char *gb_bprintf (char const *fmt, ...) GB_PRINTF_ARGS(1); // NOTE(bill): A locally persisting buffer is used internally +GB_DEF char *gb_bprintf_va (char const *fmt, va_list va); // NOTE(bill): A locally persisting buffer is used internally GB_DEF isize gb_snprintf (char *str, isize n, char const *fmt, ...) GB_PRINTF_ARGS(3); GB_DEF isize gb_snprintf_va(char *str, isize n, char const *fmt, va_list va); -/*************************************************************** - * - * DLL Handling - * - */ +//////////////////////////////////////////////////////////////// +// +// DLL Handling +// +// typedef void *gbDllHandle; typedef void (*gbDllProc)(void); @@ -2076,24 +2064,23 @@ GB_DEF void gb_dll_unload (gbDllHandle dll); GB_DEF gbDllProc gb_dll_proc_address(gbDllHandle dll, char const *proc_name); -/*************************************************************** - * - * Time - * - */ +//////////////////////////////////////////////////////////////// +// +// Time +// +// GB_DEF u64 gb_rdtsc (void); -GB_DEF f64 gb_time_now (void); /* NOTE(bill): This is only for relative time e.g. game loops */ -GB_DEF u64 gb_utc_time_now(void); /* NOTE(bill): Number of microseconds since 1601-01-01 UTC */ +GB_DEF f64 gb_time_now (void); // NOTE(bill): This is only for relative time e.g. game loops +GB_DEF u64 gb_utc_time_now(void); // NOTE(bill): Number of microseconds since 1601-01-01 UTC GB_DEF void gb_sleep_ms (u32 ms); - -/*************************************************************** - * - * Miscellany - * - */ +//////////////////////////////////////////////////////////////// +// +// Miscellany +// +// typedef struct gbRandom { u64 seed[2]; @@ -2118,13 +2105,13 @@ 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? - */ +//////////////////////////////////////////////////////////////// +// +// 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) @@ -2132,7 +2119,7 @@ GB_DEF u64 gb_endian_swap64(u64 i); #endif typedef union gbColour { - u32 rgba; /* NOTE(bill): 0xaabbggrr */ + u32 rgba; // NOTE(bill): 0xaabbggrr in little endian struct { u8 r, g, b, a; }; u8 e[4]; } gbColour; @@ -2158,15 +2145,15 @@ 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) */ +#endif // !defined(GB_NO_COLOUR_TYPE) -/*************************************************************** - * - * Platform Stuff - * - */ +//////////////////////////////////////////////////////////////// +// +// Platform Stuff +// +// #if defined(GB_PLATFORM) @@ -2190,9 +2177,10 @@ typedef enum gbWindowFlag { GB_WINDOW_RESIZABLE = GB_BIT(6), GB_WINDOW_MINIMIZED = GB_BIT(7), GB_WINDOW_MAXIMIZED = GB_BIT(8), + GB_WINDOW_FULLSCREEN_DESKTOP = GB_WINDOW_FULLSCREEN | GB_WINDOW_BORDERLESS, - GB_WINDOW_FULLSCREEN_DESKTOP = GB_WINDOW_FULLSCREEN | GB_WINDOW_BORDERLESS - + GB_WINDOW_IS_CLOSED = GB_BIT(9), + GB_WINDOW_HAS_FOCUS = GB_BIT(10) } gbWindowFlag; #if defined(_MSC_VER) @@ -2210,15 +2198,13 @@ typedef struct gbWindow { i32 x, y; i32 width, height; - b32 is_closed; - b32 has_focus; + u32 flags; #if defined(GB_SYSTEM_WINDOWS) WINDOWPLACEMENT win32_placement; HDC win32_dc; #endif - u32 flags; union { struct { #if defined(GB_SYSTEM_WINDOWS) @@ -2246,9 +2232,9 @@ typedef struct gbWindow { typedef enum gbKeyType { - GB_KEY_UNKNOWN = 0, /* Unhandled key */ + GB_KEY_UNKNOWN = 0, // Unhandled key - /* NOTE(bill): Allow the basic printable keys to be aliased with their chars */ + // NOTE(bill): Allow the basic printable keys to be aliased with their chars GB_KEY_0 = '0', GB_KEY_1, GB_KEY_2, @@ -2300,61 +2286,61 @@ typedef enum gbKeyType { GB_KEY_MINUS = '-', GB_KEY_SPACE = ' ', - GB_KEY__PAD = 128, /* NOTE(bill): make sure ASCII is reserved */ + GB_KEY__PAD = 128, // NOTE(bill): make sure ASCII is reserved - GB_KEY_ESCAPE, /* Escape */ - GB_KEY_LCONTROL, /* Left Control */ - GB_KEY_LSHIFT, /* Left Shift */ - GB_KEY_LALT, /* Left Alt */ - GB_KEY_LSYSTEM, /* Left OS specific: window (Windows and Linux), apple (MacOS X), ... */ - GB_KEY_RCONTROL, /* Right Control */ - GB_KEY_RSHIFT, /* Right Shift */ - GB_KEY_RALT, /* Right Alt */ - GB_KEY_RSYSTEM, /* Right OS specific: window (Windows and Linux), apple (MacOS X), ... */ - GB_KEY_MENU, /* Menu */ - GB_KEY_RETURN, /* Return */ - GB_KEY_BACKSPACE, /* Backspace */ - GB_KEY_TAB, /* Tabulation */ - GB_KEY_PAGEUP, /* Page up */ - GB_KEY_PAGEDOWN, /* Page down */ - GB_KEY_END, /* End */ - GB_KEY_HOME, /* Home */ - GB_KEY_INSERT, /* Insert */ - GB_KEY_DELETE, /* Delete */ - GB_KEY_PLUS, /* + */ - GB_KEY_SUBTRACT, /* - */ - GB_KEY_MULTIPLY, /* * */ - GB_KEY_DIVIDE, /* / */ - GB_KEY_LEFT, /* Left arrow */ - GB_KEY_RIGHT, /* Right arrow */ - GB_KEY_UP, /* Up arrow */ - GB_KEY_DOWN, /* Down arrow */ - GB_KEY_NUMPAD0, /* Numpad 0 */ - GB_KEY_NUMPAD1, /* Numpad 1 */ - GB_KEY_NUMPAD2, /* Numpad 2 */ - GB_KEY_NUMPAD3, /* Numpad 3 */ - GB_KEY_NUMPAD4, /* Numpad 4 */ - GB_KEY_NUMPAD5, /* Numpad 5 */ - GB_KEY_NUMPAD6, /* Numpad 6 */ - GB_KEY_NUMPAD7, /* Numpad 7 */ - GB_KEY_NUMPAD8, /* Numpad 8 */ - GB_KEY_NUMPAD9, /* Numpad 9 */ - GB_KEY_F1, /* F1 */ - GB_KEY_F2, /* F2 */ - GB_KEY_F3, /* F3 */ - GB_KEY_F4, /* F4 */ - GB_KEY_F5, /* F5 */ - GB_KEY_F6, /* F6 */ - GB_KEY_F7, /* F7 */ - GB_KEY_F8, /* F8 */ - GB_KEY_F9, /* F8 */ - GB_KEY_F10, /* F10 */ - GB_KEY_F11, /* F11 */ - GB_KEY_F12, /* F12 */ - GB_KEY_F13, /* F13 */ - GB_KEY_F14, /* F14 */ - GB_KEY_F15, /* F15 */ - GB_KEY_PAUSE, /* Pause */ + GB_KEY_ESCAPE, // Escape + GB_KEY_LCONTROL, // Left Control + GB_KEY_LSHIFT, // Left Shift + GB_KEY_LALT, // Left Alt + GB_KEY_LSYSTEM, // Left OS specific: window (Windows and Linux), apple (MacOS X), ... + GB_KEY_RCONTROL, // Right Control + GB_KEY_RSHIFT, // Right Shift + GB_KEY_RALT, // Right Alt + GB_KEY_RSYSTEM, // Right OS specific: window (Windows and Linux), apple (MacOS X), ... + GB_KEY_MENU, // Menu + GB_KEY_RETURN, // Return + GB_KEY_BACKSPACE, // Backspace + GB_KEY_TAB, // Tabulation + GB_KEY_PAGEUP, // Page up + GB_KEY_PAGEDOWN, // Page down + GB_KEY_END, // End + GB_KEY_HOME, // Home + GB_KEY_INSERT, // Insert + GB_KEY_DELETE, // Delete + GB_KEY_PLUS, // + + GB_KEY_SUBTRACT, // - + GB_KEY_MULTIPLY, // * + GB_KEY_DIVIDE, // / + GB_KEY_LEFT, // Left arrow + GB_KEY_RIGHT, // Right arrow + GB_KEY_UP, // Up arrow + GB_KEY_DOWN, // Down arrow + GB_KEY_NUMPAD0, // Numpad 0 + GB_KEY_NUMPAD1, // Numpad 1 + GB_KEY_NUMPAD2, // Numpad 2 + GB_KEY_NUMPAD3, // Numpad 3 + GB_KEY_NUMPAD4, // Numpad 4 + GB_KEY_NUMPAD5, // Numpad 5 + GB_KEY_NUMPAD6, // Numpad 6 + GB_KEY_NUMPAD7, // Numpad 7 + GB_KEY_NUMPAD8, // Numpad 8 + GB_KEY_NUMPAD9, // Numpad 9 + GB_KEY_F1, // F1 + GB_KEY_F2, // F2 + GB_KEY_F3, // F3 + GB_KEY_F4, // F4 + GB_KEY_F5, // F5 + GB_KEY_F6, // F6 + GB_KEY_F7, // F7 + GB_KEY_F8, // F8 + GB_KEY_F9, // F8 + GB_KEY_F10, // F10 + GB_KEY_F11, // F11 + GB_KEY_F12, // F12 + GB_KEY_F13, // F13 + GB_KEY_F14, // F14 + GB_KEY_F15, // F15 + GB_KEY_PAUSE, // Pause GB_KEY_COUNT } gbKeyType; @@ -2435,7 +2421,7 @@ typedef GB_XINPUT_SET_STATE(gbXInputSetStateProc); typedef struct gbPlatform { gbWindow window; - gbKeyState keys[GB_KEY_COUNT]; /* NOTE(bill): test with flags */ + gbKeyState keys[GB_KEY_COUNT]; // NOTE(bill): test with flags struct { gbKeyState control; gbKeyState alt; @@ -2469,7 +2455,7 @@ GB_DEF void gb_platform_set_mouse_position(gbPlatform *p, gbWindow *rel_win, i32 GB_DEF gbGameController *gb_platform_get_controller(gbPlatform *p, isize index); -/* NOTE(bill): Title is UTF-8 */ +// NOTE(bill): Title is UTF-8 GB_DEF gbWindow *gb_window_init (gbPlatform *p, char const *title, gbVideoMode mode, u32 flags); GB_DEF void gb_window_destroy (gbWindow *w); GB_DEF void gb_window_set_position (gbWindow *w, i32 x, i32 y); @@ -2478,76 +2464,76 @@ GB_DEF void gb_window_toggle_fullscreen (gbWindow *w, b32 fullscreen_desk GB_DEF void gb_window_make_context_current(gbWindow *w); GB_DEF void gb_window_show (gbWindow *w); GB_DEF void gb_window_hide (gbWindow *w); +GB_DEF b32 gb_window_is_open (gbWindow const *w); -GB_DEF gbVideoMode gb_video_mode (i32 width, i32 height); -GB_DEF gbVideoMode gb_video_mode_bits (i32 width, i32 height, i32 bits_per_pixel); +GB_DEF gbVideoMode gb_video_mode (i32 width, i32 height, i32 bits_per_pixel); GB_DEF b32 gb_video_mode_is_valid (gbVideoMode mode); GB_DEF gbVideoMode gb_video_mode_get_desktop (void); -GB_DEF isize gb_video_mode_get_fullscreen_modes(gbVideoMode *modes, isize max_mode_count); /* NOTE(bill): returns mode count */ -GB_DEF GB_COMPARE_PROC(gb_video_mode_cmp); /* NOTE(bill): Sort smallest to largest (Ascending) */ -GB_DEF GB_COMPARE_PROC(gb_video_mode_dsc_cmp); /* NOTE(bill): Sort largest to smallest (Descending) */ +GB_DEF isize gb_video_mode_get_fullscreen_modes(gbVideoMode *modes, isize max_mode_count); // NOTE(bill): returns mode count +GB_DEF GB_COMPARE_PROC(gb_video_mode_cmp); // NOTE(bill): Sort smallest to largest (Ascending) +GB_DEF GB_COMPARE_PROC(gb_video_mode_dsc_cmp); // NOTE(bill): Sort largest to smallest (Descending) -#endif /* GB_PLATFORM */ +#endif // GB_PLATFORM #if defined(__cplusplus) } #endif -#endif /* GB_INCLUDE_GB_H */ +#endif // GB_INCLUDE_GB_H -/*************************************************************** - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * Implementation - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * It's turtles all the way down! - ***************************************************************/ +//////////////////////////////////////////////////////////////// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// Implementation +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// It's turtles all the way down! +//////////////////////////////////////////////////////////////// #if defined(GB_IMPLEMENTATION) && !defined(GB_IMPLEMENTATION_DONE) #define GB_IMPLEMENTATION_DONE @@ -2563,17 +2549,21 @@ extern "C" { #if defined(_MSC_VER) #pragma warning(push) -#pragma warning(disable:4127) /* Conditional expression is constant */ +#pragma warning(disable:4127) // Conditional expression is constant #endif void -gb_assert_handler(char const *condition, char const *file, i32 line, char const *msg) +gb_assert_handler(char const *condition, char const *file, i32 line, char const *msg, ...) { gb_printf_err("%s:%d: Assert Failure: ", file, line); if (condition) gb_printf_err( "`%s` ", condition); - if (msg) - gb_printf_err("%s", msg); + if (msg) { + va_list va; + va_start(va, msg); + gb_printf_err_va(msg, va); + va_end(va); + } gb_printf_err("\n"); } @@ -2621,9 +2611,9 @@ gb_memcopy(void *gb_restrict dest, void const *gb_restrict source, isize size) #elif (defined(__i386__) || defined(__x86_64___)) __asm__ __volatile__("rep movsb" : "+D"(cast(u8 *gb_restrict)dest), "+S"(cast(u8 *gb_restrict)source), "+c"(size) : : "memory"); #else - /* TODO(bill): Heavily optimize */ + // TODO(bill): Heavily optimize if ((cast(intptr)dest & 0x3) || (cast(intptr)source & 0x3)) { - /* NOTE(bill): Do an unaligned byte copy */ + // NOTE(bill): Do an unaligned byte copy u8 *gb_restrict dp8 = cast(u8 *)dest; u8 *sp8 = cast(u8 *)source; @@ -2652,7 +2642,7 @@ gb_memcopy(void *gb_restrict dest, void const *gb_restrict source, isize size) } } - /* TODO(bill): More betterer memcpys!!!! */ + // TODO(bill): More betterer memcpys!!!! #endif return dest; } @@ -2660,7 +2650,7 @@ gb_memcopy(void *gb_restrict dest, void const *gb_restrict source, isize size) gb_inline void * gb_memmove(void *dest, void const *source, isize size) { - /* TODO(bill): Heavily optimize */ + // TODO(bill): Heavily optimize u8 *dp8 = cast(u8 *)dest; u8 *sp8 = cast(u8 *)source; @@ -2679,15 +2669,15 @@ gb_memmove(void *dest, void const *source, isize size) gb_inline void * gb_memset(void *data, u8 c, isize size) { - /* TODO(bill): Heavily optimize */ + // TODO(bill): Heavily optimize isize left; u32 *dp32; u8 *dp8 = cast(u8 *)data; u32 c32 = (c | (c << 8) | (c << 16) | (c << 24)); - /* NOTE(bill): The destination pointer needs to be aligned on a 4-byte - * boundary to execute a 32-bit set. Set first bytes manually if needed - * until it is aligned. */ + // NOTE(bill): The destination pointer needs to be aligned on a 4-byte + // boundary to execute a 32-bit set. Set first bytes manually if needed + // until it is aligned. while (cast(intptr)dp8 & 0x3) { if (size--) *dp8++ = c; @@ -2714,7 +2704,7 @@ gb_memset(void *data, u8 c, isize size) gb_inline i32 gb_memcompare(void const *s1, void const *s2, isize size) { - /* TODO(bill): Heavily optimize */ + // TODO(bill): Heavily optimize u8 const *s1p8 = cast(u8 const *)s1; u8 const *s2p8 = cast(u8 const *)s2; @@ -2747,7 +2737,7 @@ gb_memswap(void *i, void *j, isize size) } else { char buffer[256]; - /* TODO(bill): Is the recursion ever a problem? */ + // TODO(bill): Is the recursion ever a problem? while (size > gb_size_of(buffer)) { gb_memswap(i, j, gb_size_of(buffer)); i = gb_pointer_add(i, gb_size_of(buffer)); @@ -2810,11 +2800,11 @@ gb_default_resize_align(gbAllocator a, void *old_memory, isize old_size, isize n -/*************************************************************** - * - * Concurrency - * - */ +//////////////////////////////////////////////////////////////// +// +// Concurrency +// +// #if defined(_MSC_VER) && !defined(__clang__) gb_inline i32 gb_atomic32_load (gbAtomic32 const volatile *a) { return a->value; } gb_inline void gb_atomic32_store(gbAtomic32 volatile *a, i32 value) { a->value = value; } @@ -2851,7 +2841,7 @@ gb_atomic64_load(gbAtomic64 const volatile *a) #if defined(GB_ARCH_64_BIT) return a->value; #else - /* NOTE(bill): The most compatible way to get an atomic 64-bit load on x86 is with cmpxchg8b */ + // NOTE(bill): The most compatible way to get an atomic 64-bit load on x86 is with cmpxchg8b i64 result; __asm { mov esi, a; @@ -2871,7 +2861,7 @@ gb_atomic64_store(gbAtomic64 volatile *a, i64 value) #if defined(GB_ARCH_64_BIT) a->value = value; #else - /* NOTE(bill): The most compatible way to get an atomic 64-bit store on x86 is with cmpxchg8b */ + // NOTE(bill): The most compatible way to get an atomic 64-bit store on x86 is with cmpxchg8b __asm { mov esi, a; mov ebx, dword ptr value; @@ -2955,7 +2945,7 @@ gb_atomic64_fetch_or(gbAtomic64 volatile *a, i64 operand) -#else /* GCC */ +#else // GCC gb_inline i32 gb_atomic32_load (gbAtomic32 const volatile *a) { return a->value; } @@ -2976,7 +2966,7 @@ gb_atomic32_compare_exchange(gbAtomic32 volatile *a, i32 expected, i32 desired) gb_inline i32 gb_atomic32_exchanged(gbAtomic32 volatile *a, i32 desired) { - /* NOTE(bill): No lock prefix is necessary for xchgl */ + // NOTE(bill): No lock prefix is necessary for xchgl i32 original; __asm__ volatile( "xchgl %0, %1" @@ -3347,8 +3337,8 @@ gb_atomic_ptr_spin_unlock(gbAtomicPtr volatile *a) #error #endif -/* NOTE(bill): THIS IS FUCKING AWESOME THAT THIS "MUTEX" IS FAST AND RECURSIVE TOO! */ -/* NOTE(bill): WHO THE FUCK NEEDS A NORMAL MUTEX NOW?!?!?!?! */ +// NOTE(bill): THIS IS FUCKING AWESOME THAT THIS "MUTEX" IS FAST AND RECURSIVE TOO! +// NOTE(bill): WHO THE FUCK NEEDS A NORMAL MUTEX NOW?!?!?!?! gb_inline void gb_mutex_init(gbMutex *m) { @@ -3521,7 +3511,7 @@ void gb_thread_set_name(gbThread *t, char const *name) { #if defined(_MSC_VER) - /* TODO(bill): Bloody Windows!!! */ + // TODO(bill): Bloody Windows!!! #pragma pack(push, 8) typedef struct { DWORD type; @@ -3542,13 +3532,13 @@ gb_thread_set_name(gbThread *t, char const *name) } #elif defined(GB_SYSTEM_WINDOWS) && !defined(_MSC_VER) - /* IMPORTANT TODO(bill): Set thread name for GCC/Clang on windows */ + // IMPORTANT TODO(bill): Set thread name for GCC/Clang on windows return; #elif defined(GB_SYSTEM_OSX) - /* TODO(bill): Test if this works */ + // TODO(bill): Test if this works pthread_setname_np(name); #else - /* TODO(bill): Test if this works */ + // TODO(bill): Test if this works pthread_setname_np(t->posix_handle, name); #endif } @@ -3571,14 +3561,14 @@ GB_ALLOCATOR_PROC(gb_heap_allocator_proc) gb_unused(allocator_data); gb_unused(options); gb_unused(old_size); -/* TODO(bill): Throughly test! */ +// TODO(bill): Throughly test! switch (type) { #if defined(_MSC_VER) case GB_ALLOCATION_ALLOC: return _aligned_malloc(size, alignment); case GB_ALLOCATION_FREE: _aligned_free(old_memory); break; case GB_ALLOCATION_RESIZE: return _aligned_realloc(old_memory, size, alignment); #else - /* TODO(bill): *nix version that's decent */ + // TODO(bill): *nix version that's decent case GB_ALLOCATION_ALLOC: { isize total_size = size + alignment + gb_size_of(gbAllocationHeader); void *ptr = malloc(total_size); @@ -3602,15 +3592,15 @@ GB_ALLOCATOR_PROC(gb_heap_allocator_proc) break; } - return NULL; /* NOTE(bill): Default return value */ + return NULL; // NOTE(bill): Default return value } -/*************************************************************** - * - * Virtual Memory - * - */ +//////////////////////////////////////////////////////////////// +// +// Virtual Memory +// +// gbVirtualMemory gb_virtual_memory(void *data, isize size) @@ -3661,7 +3651,7 @@ gb_inline b32 gb_vm_purge(gbVirtualMemory vm) { VirtualAlloc(vm.data, vm.size, MEM_RESET, PAGE_READWRITE); - /* NOTE(bill): Can this really fail? */ + // NOTE(bill): Can this really fail? return true; } #else @@ -3718,16 +3708,16 @@ gb_vm_purge(gbVirtualMemory vm) -/*************************************************************** - * - * Custom Allocation - * - */ +//////////////////////////////////////////////////////////////// +// +// Custom Allocation +// +// -/* - * Arena Allocator - */ +// +// Arena Allocator +// gb_inline void gb_arena_init_from_memory(gbArena *arena, void *start, isize size) @@ -3744,7 +3734,7 @@ gb_inline void gb_arena_init_from_allocator(gbArena *arena, gbAllocator backing, isize size) { arena->backing = backing; - arena->physical_start = gb_alloc(backing, size); /* NOTE(bill): Uses default alignment */ + arena->physical_start = gb_alloc(backing, size); // NOTE(bill): Uses default alignment arena->total_size = size; arena->total_allocated = 0; arena->temp_count = 0; @@ -3815,7 +3805,7 @@ GB_ALLOCATOR_PROC(gb_arena_allocator_proc) void *end = gb_pointer_add(arena->physical_start, arena->total_allocated); isize total_size = size + alignment; - /* NOTE(bill): Out of memory */ + // NOTE(bill): Out of memory if (arena->total_allocated + total_size > cast(isize)arena->total_size) return NULL; @@ -3825,8 +3815,8 @@ GB_ALLOCATOR_PROC(gb_arena_allocator_proc) } break; case GB_ALLOCATION_FREE: - /* NOTE(bill): Free all at once - * Use Temp_Arena_Memory if you want to free a block */ + // NOTE(bill): Free all at once + // Use Temp_Arena_Memory if you want to free a block break; case GB_ALLOCATION_FREE_ALL: @@ -3834,13 +3824,13 @@ GB_ALLOCATOR_PROC(gb_arena_allocator_proc) break; case GB_ALLOCATION_RESIZE: { - /* TODO(bill): Check if ptr is on top of stack and just extend */ + // TODO(bill): Check if ptr is on top of stack and just extend gbAllocator a = gb_arena_allocator(arena); return gb_default_resize_align(a, old_memory, old_size, size, alignment); } break; } - return NULL; /* NOTE(bill): Default return value */ + return NULL; // NOTE(bill): Default return value } @@ -3866,9 +3856,9 @@ gb_temp_arena_memory_end(gbTempArenaMemory tmp) -/* - * Pool Allocator - */ +// +// Pool Allocator +// gb_inline void @@ -3895,7 +3885,7 @@ gb_pool_init_align(gbPool *pool, gbAllocator backing, isize num_blocks, isize bl data = gb_alloc_align(backing, pool_size, block_align); - /* NOTE(bill): Init intrusive freelist */ + // NOTE(bill): Init intrusive freelist curr = data; for (block_index = 0; block_index < num_blocks-1; block_index++) { uintptr *next = cast(uintptr *)curr; @@ -3961,11 +3951,11 @@ GB_ALLOCATOR_PROC(gb_pool_allocator_proc) } break; case GB_ALLOCATION_FREE_ALL: - /* TODO(bill): */ + // TODO(bill): break; case GB_ALLOCATION_RESIZE: - /* NOTE(bill): Cannot resize */ + // NOTE(bill): Cannot resize GB_ASSERT(false); break; } @@ -3997,9 +3987,9 @@ gb_inline void gb_allocation_header_fill(gbAllocationHeader *header, void *data, -/* - * Free List Allocator - */ +// +// Free List Allocator +// gb_inline void gb_free_list_init(gbFreeList *fl, void *start, isize size) @@ -4065,7 +4055,7 @@ GB_ALLOCATOR_PROC(gb_free_list_allocator_proc) else fl->curr_block = curr_block->next; } else { - /* NOTE(bill): Create a new block for the remaining memory */ + // NOTE(bill): Create a new block for the remaining memory gbFreeListBlock *next_block; next_block = cast(gbFreeListBlock *)gb_pointer_add(curr_block, total_size); @@ -4081,7 +4071,7 @@ GB_ALLOCATOR_PROC(gb_free_list_allocator_proc) } - /* TODO(bill): Set Header Info */ + // TODO(bill): Set Header Info header = cast(gbAllocationHeader *)curr_block; ptr = gb_align_forward(header+1, alignment); gb_allocation_header_fill(header, ptr, size); @@ -4093,7 +4083,7 @@ GB_ALLOCATOR_PROC(gb_free_list_allocator_proc) return ptr; } - /* NOTE(bill): Ran out of free list memory! FUCK! */ + // NOTE(bill): Ran out of free list memory! FUCK! return NULL; } break; @@ -4199,7 +4189,7 @@ GB_ALLOCATOR_PROC(gb_scratch_allocator_proc) size = ((size + 3)/4)*4; ptr = gb_pointer_add(ptr, size); - /* NOTE(bill): Wrap around */ + // NOTE(bill): Wrap around if (ptr > end) { header->size = gb_pointer_diff(header, end) | GB_ISIZE_HIGH_BIT; ptr = s->physical_start; @@ -4221,7 +4211,7 @@ GB_ALLOCATOR_PROC(gb_scratch_allocator_proc) if (old_memory < s->physical_start || old_memory >= end) { GB_ASSERT(false); } else { - /* NOTE(bill): Mark as free */ + // NOTE(bill): Mark as free gbAllocationHeader *h = gb_allocation_header(old_memory); GB_ASSERT((h->size & GB_ISIZE_HIGH_BIT) == 0); h->size = h->size | GB_ISIZE_HIGH_BIT; @@ -4256,13 +4246,13 @@ GB_ALLOCATOR_PROC(gb_scratch_allocator_proc) -/*************************************************************** - * - * Sorting - * - */ +//////////////////////////////////////////////////////////////// +// +// Sorting +// +// -/* TODO(bill): Should I make all the macros local? */ +// TODO(bill): Should I make all the macros local? #define GB__COMPARE_PROC(Type) \ gb_global isize gb__##Type##_cmp_offset; \ @@ -4287,7 +4277,7 @@ GB__COMPARE_PROC(f32); GB__COMPARE_PROC(f64); GB__COMPARE_PROC(char); -/* NOTE(bill): str_cmp is special as it requires a funny type and funny comparison*/ +// NOTE(bill): str_cmp is special as it requires a funny type and funny comparison gb_global isize gb__str_cmp_offset; GB_COMPARE_PROC(gb__str_cmp) { @@ -4303,7 +4293,10 @@ GB_COMPARE_PROC_PTR(gb_str_cmp(isize offset)) #undef GB__COMPARE_PROC -/* TODO(bill): Make user definable? */ + + + +// TODO(bill): Make user definable? #define GB__SORT_STACK_SIZE 64 #define GB__SORT_INSERT_SORT_THRESHOLD 8 @@ -4330,13 +4323,13 @@ gb_sort(void *base_, isize count, isize size, gbCompareProc cmp) u8 *limit = base + count*size; isize threshold = GB__SORT_INSERT_SORT_THRESHOLD * size; - /* NOTE(bill): Prepare the stack */ + // NOTE(bill): Prepare the stack u8 *stack[GB__SORT_STACK_SIZE] = {0}; u8 **stack_ptr = stack; for (;;) { if ((limit-base) > threshold) { - /* NOTE(bill): Quick sort */ + // NOTE(bill): Quick sort i = base + size; j = limit - size; @@ -4367,7 +4360,7 @@ gb_sort(void *base_, isize count, isize size, gbCompareProc cmp) limit = j; } } else { - /* NOTE(bill): Insertion sort */ + // NOTE(bill): Insertion sort for (j = base, i = j+size; i < limit; j = i, i += size) { @@ -4379,7 +4372,7 @@ gb_sort(void *base_, isize count, isize size, gbCompareProc cmp) } if (stack_ptr == stack) - break; /* NOTE(bill): Sorting is done! */ + break; // NOTE(bill): Sorting is done! GB__SORT_POP(base, limit); } } @@ -4447,11 +4440,11 @@ gb_binary_search(void const *base, isize count, isize size, void const *key, gbC -/*************************************************************** - * - * Char things - * - */ +//////////////////////////////////////////////////////////////// +// +// Char things +// +// @@ -4524,7 +4517,6 @@ gb_digit_to_int(char c) return gb_char_is_digit(c) ? c - '0' : c - 'W'; } - gb_inline i32 gb_hex_digit_to_int(char c) { @@ -4997,7 +4989,7 @@ gb_string_make_space_for(gbString str, isize add_len) { isize available = gb_string_available_space(str); - /* Return if there is enough space left */ + // NOTE(bill): Return if there is enough space left if (available >= add_len) { return str; } else { @@ -5075,11 +5067,11 @@ gb_inline gbString gb_string_trim_space(gbString str) { return gb_string_trim(st -/*************************************************************** - * - * Windows UTF-8 Handling - * - */ +//////////////////////////////////////////////////////////////// +// +// Windows UTF-8 Handling +// +// char16 * @@ -5105,7 +5097,7 @@ gb_utf8_to_ucs2(char16 *buffer, isize len, char const *s) if (*str == 0xe0 && (str[1] < 0xa0 || str[1] > 0xbf)) return NULL; - if (*str == 0xed && str[1] > 0x9f) /* str[1] < 0x80 is checked below */ + if (*str == 0xed && str[1] > 0x9f) // str[1] < 0x80 is checked below return NULL; c = (*str++ & 0x0f) << 12; if ((*str & 0xc0) != 0x80) @@ -5119,7 +5111,7 @@ gb_utf8_to_ucs2(char16 *buffer, isize len, char const *s) return NULL; if (*str == 0xf0 && (str[1] < 0x90 || str[1] > 0xbf)) return NULL; - if (*str == 0xf4 && str[1] > 0x8f) /* str[1] < 0x80 is checked below */ + if (*str == 0xf4 && str[1] > 0x8f) // str[1] < 0x80 is checked below return NULL; c = (*str++ & 0x07) << 18; if ((*str & 0xc0) != 0x80) @@ -5131,7 +5123,7 @@ gb_utf8_to_ucs2(char16 *buffer, isize len, char const *s) if ((*str & 0xc0) != 0x80) return NULL; c += (*str++ & 0x3f); - /* UTF-8 encodings of values used in surrogate pairs are invalid */ + // UTF-8 encodings of values used in surrogate pairs are invalid if ((c & 0xfffff800) == 0xd800) return NULL; if (c >= 0x10000) { @@ -5190,6 +5182,22 @@ gb_ucs2_to_utf8(char *buffer, isize len, char16 const *str) return buffer; } +char16 * +gb_utf8_to_ucs2_buf(char const *str) // NOTE(bill): Uses locally persisting buffer +{ + gb_local_persist char16 buf[4096]; + return gb_utf8_to_ucs2(buf, gb_count_of(buf), str); +} + +char * +gb_ucs2_to_utf8_buf(char16 const *str) // NOTE(bill): Uses locally persisting buffer +{ + gb_local_persist char buf[4096]; + return gb_ucs2_to_utf8(buf, gb_count_of(buf), str); +} + + + #define GB__UTF_SIZE 4 #define GB__UTF_INVALID 0xfffd @@ -5260,11 +5268,11 @@ gb_utf8_decode_len(char const *s, isize str_len, char32 *c) -/*************************************************************** - * - * Array - * - */ +//////////////////////////////////////////////////////////////// +// +// gbArray +// +// gb_no_inline void * @@ -5300,11 +5308,11 @@ gb__array_set_capacity(void *array, isize capacity, isize element_size) } -/*************************************************************** - * - * Hashing functions - * - */ +//////////////////////////////////////////////////////////////// +// +// Hashing functions +// +// u32 gb_adler32(void const *data, isize len) @@ -5707,22 +5715,13 @@ gb_murmur64_seed(void const *data_, isize len, u64 seed) -/*************************************************************** - * - * Hash Table - * - */ - - - - -/*************************************************************** - * - * File Handling - * - */ +//////////////////////////////////////////////////////////////// +// +// File Handling +// +// #if defined(GB_SYSTEM_WINDOWS) @@ -5826,7 +5825,7 @@ GB_FILE_OPEN_PROC(gb__win32_file_open) FILE_SHARE_READ|FILE_SHARE_DELETE, NULL, creation_disposition, FILE_ATTRIBUTE_NORMAL, NULL); - /* TODO(bill): More file errors */ + // TODO(bill): More file errors if (handle == INVALID_HANDLE_VALUE) { return GB_FILE_ERR_INVALID; } @@ -5844,7 +5843,7 @@ GB_FILE_OPEN_PROC(gb__win32_file_open) return GB_FILE_ERR_NONE; } -#else /* POSIX */ +#else // POSIX gb_internal @@ -5921,7 +5920,7 @@ GB_FILE_OPEN_PROC(gb__posix_file_open) 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 */ + // TODO(bill): More file errors return GB_FILE_ERR_INVALID; } @@ -5934,7 +5933,7 @@ GB_FILE_OPEN_PROC(gb__posix_file_open) gbFileError -gb_file_new(gbFile *f, gbFileDescriptor fd, gbFileOperations const *ops, gbFileMode mode, char const *filename) +gb_file_new(gbFile *f, gbFileDescriptor fd, gbFileOperations const *ops, char const *filename) { gbFileError err = GB_FILE_ERR_NONE; @@ -5960,7 +5959,7 @@ gb_file_open_mode_va(gbFile *f, gbFileMode mode, char const *filename, va_list v err = gb__posix_file_open(&f->fd, &f->ops, mode, buffer); #endif if (!err) - return gb_file_new(f, f->fd, f->ops, mode, buffer); + return gb_file_new(f, f->fd, f->ops, buffer); return err; } @@ -6072,22 +6071,24 @@ gb_file_has_changed(gbFile *f) } +gb_global b32 gb__std_file_set = false; +gb_global gbFile gb__std_files[GB_FILE_STANDARD_COUNT] = {0}; #if defined(GB_SYSTEM_WINDOWS) -gb_inline gbFile -gb_file_get_std(gbFileStandardType std) +gb_inline gbFile *const +gb_file_get_standard(gbFileStandardType std) { - gbFile file = {0}; - file.ops = &GB_DEFAULT_FILE_OPERATIONS; - switch (std) { - case GB_FILE_STANDARD_INPUT: file.fd.p = GetStdHandle(STD_INPUT_HANDLE); break; - case GB_FILE_STANDARD_OUTPUT: file.fd.p = GetStdHandle(STD_OUTPUT_HANDLE); break; - case GB_FILE_STANDARD_ERROR: file.fd.p = GetStdHandle(STD_ERROR_HANDLE); break; - default: GB_PANIC("Invalid standard file"); break; + if (!gb__std_file_set) { + #define GB__SET_STD_FILE(type, v) gb__std_files[type].fd.p = v; gb__std_files[type].ops = &GB_DEFAULT_FILE_OPERATIONS + GB__SET_STD_FILE(GB_FILE_STANDARD_INPUT, GetStdHandle(STD_INPUT_HANDLE)); + GB__SET_STD_FILE(GB_FILE_STANDARD_OUTPUT, GetStdHandle(STD_OUTPUT_HANDLE)); + GB__SET_STD_FILE(GB_FILE_STANDARD_ERROR, GetStdHandle(STD_ERROR_HANDLE)); + #undef GB__SET_STD_FILE + gb__std_file_set = true; } - return file; + return &gb__std_files[std]; } gb_inline i64 @@ -6114,29 +6115,29 @@ gb_file_truncate(gbFile *f, i64 size) b32 gb_file_exists(char const *name) { - WIN32_FIND_DATA data; - HANDLE handle = FindFirstFile(name, &data); + WIN32_FIND_DATAW data; + HANDLE handle = FindFirstFileW(cast(LPCWSTR)gb_utf8_to_ucs2_buf(name), &data); b32 found = handle != INVALID_HANDLE_VALUE; if (found) FindClose(handle); return found; } -#else +#else // POSIX -gb_inline gbFile -gb_file_get_std(gbFileStandardType std) +gb_inline gbFile *const +gb_file_get_standard(gbFileStandardType std) { - gbFile file = {0}; - switch (std) { - case GB_FILE_STANDARD_INPUT: file.fd.i = 0; break; - case GB_FILE_STANDARD_OUTPUT: file.fd.i = 1; break; - case GB_FILE_STANDARD_ERROR: file.fd.i = 2; break; - default: GB_PANIC("Invalid standard file"); break; + if (!gb__std_file_set) { + #define GB__SET_STD_FILE(type, v) gb__std_files[type].fd.i = v; gb__std_files[type].ops = &GB_DEFAULT_FILE_OPERATIONS + GB__SET_STD_FILE(GB_FILE_STANDARD_INPUT, 0); + GB__SET_STD_FILE(GB_FILE_STANDARD_OUTPUT, 1); + GB__SET_STD_FILE(GB_FILE_STANDARD_ERROR, 2); + #undef GB__SET_STD_FILE + gb__std_file_set = true; } - return file; + return &gb__std_files[std]; } - gb_inline i64 gb_file_size(gbFile *f) { @@ -6170,16 +6171,16 @@ gb_file_exists(char const *name) gbFileTime gb_file_last_write_time(char const *filepath, ...) { + gb_local_persist char16 path[2048]; ULARGE_INTEGER li = {0}; FILETIME last_write_time = {0}; WIN32_FILE_ATTRIBUTE_DATA data = {0}; va_list va; va_start(va, filepath); - - if (GetFileAttributesExA(gb_bprintf_va(filepath, va), GetFileExInfoStandard, &data)) + if (GetFileAttributesExW(cast(LPCWSTR)gb_utf8_to_ucs2(path, gb_count_of(path), gb_bprintf_va(filepath, va)), + GetFileExInfoStandard, &data)) last_write_time = data.ftLastWriteTime; - va_end(va); li.LowPart = last_write_time.dwLowDateTime; @@ -6191,13 +6192,22 @@ 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) { - return CopyFileA(existing_filename, new_filename, fail_if_exists); + gb_local_persist char16 old_f[2048]; + gb_local_persist char16 new_f[2048]; + + 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), + fail_if_exists); } gb_inline b32 gb_file_move(char const *existing_filename, char const *new_filename) { - return MoveFileA(existing_filename, new_filename); + gb_local_persist char16 old_f[2048]; + gb_local_persist char16 new_f[2048]; + + 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)); } @@ -6348,11 +6358,11 @@ gb_path_extension(char const *path) } -/*************************************************************** - * - * Printing - * - */ +//////////////////////////////////////////////////////////////// +// +// Printing +// +// isize @@ -6416,15 +6426,13 @@ gb_snprintf(char *str, isize n, char const *fmt, ...) gb_inline isize gb_printf_va(char const *fmt, va_list va) { - gbFile f = gb_file_get_std(GB_FILE_STANDARD_OUTPUT); - return gb_fprintf_va(&f, fmt, va); + return gb_fprintf_va(gb_file_get_standard(GB_FILE_STANDARD_OUTPUT), fmt, va); } gb_inline isize gb_printf_err_va(char const *fmt, va_list va) { - gbFile f = gb_file_get_std(GB_FILE_STANDARD_ERROR); - return gb_fprintf_va(&f, fmt, va); + return gb_fprintf_va(gb_file_get_standard(GB_FILE_STANDARD_ERROR), fmt, va); } gb_inline isize @@ -6480,9 +6488,10 @@ typedef struct { gb_internal isize gb__print_string(char *text, isize max_len, gbprivFmtInfo *info, char const *str) { - /* TODO(bill): Get precision and width to work correctly. How does it actually work?! */ - /* TODO(bill): This looks very buggy indeed. */ + // TODO(bill): Get precision and width to work correctly. How does it actually work?! + // TODO(bill): This looks very buggy indeed. isize res = 0, len; + isize remaining = max_len; if (info && info->precision >= 0) len = gb_strnlen(str, info->precision); @@ -6494,22 +6503,24 @@ gb__print_string(char *text, isize max_len, gbprivFmtInfo *info, char const *str len = info->precision < len ? info->precision : len; res += gb_strlcpy(text, str, len); + res -= remaining; if (info->width > res) { isize padding = info->width - len; char pad = (info->flags & GB__FMT_ZERO) ? '0' : ' '; - while (padding --> 0) + while (padding --> 0 && remaining --> 0) *text++ = pad, res++; } } else { if (info && (info->width > res)) { isize padding = info->width - len; char pad = (info->flags & GB__FMT_ZERO) ? '0' : ' '; - while (padding --> 0) + while (padding --> 0 && remaining --> 0) *text++ = pad, res++; } res += gb_strlcpy(text, str, len); + remaining -= res; } @@ -6552,7 +6563,7 @@ gb__print_u64(char *text, isize max_len, gbprivFmtInfo *info, u64 value) gb_internal isize gb__print_f64(char *text, isize max_len, gbprivFmtInfo *info, f64 arg) { - /* TODO(bill): Handle exponent notation */ + // TODO(bill): Handle exponent notation isize width, len, remaining = max_len; char *text_begin = text; @@ -6656,34 +6667,17 @@ gb_snprintf_va(char *text, isize max_len, char const *fmt, va_list va) if (*fmt == '%') { do { switch (*fmt++) { - case '-': - info.flags |= GB__FMT_MINUS; - fmt++; - break; - case '+': - info.flags |= GB__FMT_PLUS; - fmt++; - break; - case '#': - info.flags |= GB__FMT_ALT; - fmt++; - break; - case ' ': - info.flags |= GB__FMT_SPACE; - fmt++; - break; - case '0': - info.flags |= GB__FMT_ZERO; - fmt++; - break; - default: - info.flags |= GB__FMT_DONE; - break; + case '-': info.flags |= GB__FMT_MINUS; fmt++; break; + case '+': info.flags |= GB__FMT_PLUS; fmt++; break; + case '#': info.flags |= GB__FMT_ALT; fmt++; break; + case ' ': info.flags |= GB__FMT_SPACE; fmt++; break; + case '0': info.flags |= GB__FMT_ZERO; fmt++; break; + default: info.flags |= GB__FMT_DONE; break; } } while (!(info.flags & GB__FMT_DONE)); } - /* NOTE(bill): Optional Width */ + // NOTE(bill): Optional Width if (*fmt == '*') { int width = va_arg(va, int); if (width < 0) { @@ -6697,9 +6691,9 @@ gb_snprintf_va(char *text, isize max_len, char const *fmt, va_list va) info.width = cast(i32)gb_str_to_i64(fmt, cast(char **)&fmt, 10); } - /* NOTE(bill): Optional Precision */ + // NOTE(bill): Optional Precision if (*fmt == '.') { - fmt++; + fmt++; if (*fmt == '*') { info.precision = va_arg(va, int); fmt++; @@ -6711,46 +6705,40 @@ gb_snprintf_va(char *text, isize max_len, char const *fmt, va_list va) switch (*fmt++) { case 'h': - if (*fmt == 'h') { - /* hh => char */ + if (*fmt == 'h') { // hh => char info.flags |= GB__FMT_CHAR; fmt++; - } else { - /* h => short */ + } else { // h => short info.flags |= GB__FMT_SHORT; } break; case 'l': - if (*fmt == 'l') { - /* ll => long long */ + if (*fmt == 'l') { // ll => long long info.flags |= GB__FMT_LLONG; fmt++; - } else { - /* l => long */ + } else { // l => long info.flags |= GB__FMT_LONG; } break; break; - case 'z': /* NOTE(bill): usize */ + case 'z': // NOTE(bill): usize info.flags |= GB__FMT_UNSIGNED; - /* FALLTHROUGH */ - case 't': /* NOTE(bill): isize */ + // fallthrough + case 't': // NOTE(bill): isize info.flags |= GB__FMT_SIZE; break; - default: - fmt--; - break; + default: fmt--; break; } switch (*fmt) { case 'u': info.flags |= GB__FMT_UNSIGNED; - /* FALLTHROUGH */ + // fallthrough case 'd': case 'i': info.base = 10; @@ -6779,7 +6767,7 @@ gb_snprintf_va(char *text, isize max_len, char const *fmt, va_list va) case 'a': case 'A': - /* TODO(bill): */ + // TODO(bill): break; case 'c': @@ -6795,14 +6783,11 @@ gb_snprintf_va(char *text, isize max_len, char const *fmt, va_list va) info.flags |= (GB__FMT_LOWER|GB__FMT_UNSIGNED|GB__FMT_ALT|GB__FMT_INTPTR); break; - default: - fmt--; - break; + default: fmt--; break; } fmt++; - if (info.base != 0) { if (info.flags & GB__FMT_UNSIGNED) { u64 value = 0; @@ -6861,11 +6846,11 @@ gb_snprintf_va(char *text, isize max_len, char const *fmt, va_list va) } -/*************************************************************** - * - * DLL Handling - * - */ +//////////////////////////////////////////////////////////////// +// +// DLL Handling +// +// #if defined(GB_SYSTEM_WINDOWS) @@ -6882,7 +6867,7 @@ gb_dll_load(char const *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 +#else // POSIX gbDllHandle gb_dll_load(char const *filepath, ...) @@ -6892,7 +6877,7 @@ gb_dll_load(char const *filepath, ...) va_start(va, filepath); gb_snprintf_va(buffer, gb_size_of(buffer), filepath, va); va_end(va); - /* TODO(bill): Should this be RTLD_LOCAL? */ + // TODO(bill): Should this be RTLD_LOCAL? return cast(gbDllHandle)dlopen(buffer, RTLD_LAZY|RTLD_GLOBAL); } @@ -6902,11 +6887,11 @@ gb_inline gbDllProc gb_dll_proc_address(gbDllHandle dll, char const *proc_name) #endif -/*************************************************************** - * - * Time - * - */ +//////////////////////////////////////////////////////////////// +// +// Time +// +// #if defined(_MSC_VER) && !defined(__clang__) gb_inline u64 gb_rdtsc(void) { return __rdtsc(); } @@ -7008,7 +6993,7 @@ gb_inline gbDllProc gb_dll_proc_address(gbDllHandle dll, char const *proc_name) struct timespec t; f64 result; - /* TODO(bill): THIS IS A HACK */ + // IMPORTANT TODO(bill): THIS IS A HACK clock_gettime(1 /*CLOCK_MONOTONIC*/, &t); result = t.tv_sec + 1.0e-9 * t.tv_nsec; return result; @@ -7019,7 +7004,7 @@ gb_inline gbDllProc gb_dll_proc_address(gbDllHandle dll, char const *proc_name) gb_utc_time_now(void) { struct timespec t; - /* TODO(bill): THIS IS A HACK */ + // IMPORTANT TODO(bill): THIS IS A HACK clock_gettime(0 /*CLOCK_REALTIME*/, &t); return cast(u64)t.tv_sec * 1000000ull + t.tv_nsec/1000 + 11644473600000000ull; } @@ -7036,16 +7021,16 @@ gb_inline gbDllProc gb_dll_proc_address(gbDllHandle dll, char const *proc_name) -/*************************************************************** - * - * Miscellany - * - */ +//////////////////////////////////////////////////////////////// +// +// Miscellany +// +// gb_internal gb_inline u64 gb__basic_hash(u64 x) { - /* NOTE(bill): Used in Murmur Hash */ + // NOTE(bill): Used in Murmur Hash x ^= x >> 33; x *= 0xff51afd7ed558ccdull; x ^= x >> 33; @@ -7095,7 +7080,7 @@ gb_random_range_i64(gbRandom *r, i64 lower_inc, i64 higher_inc) return i; } -/* NOTE(bill): Semi-cc'ed from gb_math to remove need for fmod */ +// NOTE(bill): Semi-cc'ed from gb_math to remove need for fmod and math.h f64 gb__copy_sign64(f64 x, f64 y) { @@ -7132,7 +7117,7 @@ gb_random_range_f64(gbRandom *r, f64 lower_inc, f64 higher_inc) u64 u = gb_random_next(r); f64 f = *cast(f64 *)&u; f64 diff = higher_inc-lower_inc+1.0; - f = gb__mod64(f, diff); /* TODO(bill): Replace fmod, maybe... */ + f = gb__mod64(f, diff); f += lower_inc; return f; } @@ -7159,6 +7144,7 @@ gb_inline void gb_set_env(char const *name, char const *value) { #if defined(GB_SYSTEM_WINDOWS) + // TODO(bill): Should this be a Wide version? SetEnvironmentVariableA(name, value); #else setenv(name, value, 1); @@ -7169,6 +7155,7 @@ gb_inline void gb_unset_env(char const *name) { #if defined(GB_SYSTEM_WINDOWS) + // TODO(bill): Should this be a Wide version? SetEnvironmentVariableA(name, NULL); #else unsetenv(name); @@ -7186,17 +7173,17 @@ gb_inline u32 gb_endian_swap32(u32 i) { return (i>>24) |(i<<24) | - ((i&0x00ff0000)>>8) | ((i&0x0000ff00)<<8); + ((i&0x00ff0000u)>>8) | ((i&0x0000ff00u)<<8); } gb_inline u64 gb_endian_swap64(u64 i) { - /* TODO(bill): Do I really need the cast here? */ + // TODO(bill): Do I really need the cast here? return (i>>56) | (i<<56) | - ((i&cast(u64)0x00ff000000000000)>>40) | ((i&cast(u64)0x000000000000ff00)<<40) | - ((i&cast(u64)0x0000ff0000000000)>>24) | ((i&cast(u64)0x0000000000ff0000)<<24) | - ((i&cast(u64)0x000000ff00000000)>>8) | ((i&cast(u64)0x00000000ff000000)<<8); + ((i&0x00ff000000000000ull)>>40) | ((i&0x000000000000ff00ull)<<40) | + ((i&0x0000ff0000000000ull)>>24) | ((i&0x0000000000ff0000ull)<<24) | + ((i&0x000000ff00000000ull)>>8) | ((i&0x00000000ff000000ull)<<8); } @@ -7205,11 +7192,11 @@ gb_endian_swap64(u64 i) -/*************************************************************** - * - * Colour Type - * It's quite useful - */ +//////////////////////////////////////////////////////////////// +// +// Colour Type +// It's quite useful +// #if !defined(GB_NO_COLOUR_TYPE) gb_inline gbColour @@ -7276,25 +7263,28 @@ gb__process_xinput_trigger_value(BYTE value) gb_internal void gb__window_resize_dib_section(gbWindow *window, i32 width, i32 height) { - if ((window->width != width) || - (window->height != height)) { - gbVideoMode mode = gb_video_mode_get_desktop(); + if (!(window->width == width && window->height == height)) { BITMAPINFO bmi = {0}; + + if (width == 0 || height == 0) + return; + window->width = width; window->height = height; - window->software.bits_per_pixel = mode.bits_per_pixel; + window->software.bits_per_pixel = gb_video_mode_get_desktop().bits_per_pixel; window->software.pitch = (window->software.bits_per_pixel * width / 8); bmi.bmiHeader.biSize = gb_size_of(bmi.bmiHeader); bmi.bmiHeader.biWidth = width; - bmi.bmiHeader.biHeight = -height; /* NOTE(bill): -ve is top-down, +ve is bottom-up */ + bmi.bmiHeader.biHeight = -height; // NOTE(bill): -ve is top-down, +ve is bottom-up bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = cast(WORD)window->software.bits_per_pixel; bmi.bmiHeader.biCompression = BI_RGB; window->software.win32_bmi = bmi; + if (window->software.memory) gb_vm_free(gb_virtual_memory(window->software.memory, window->software.memory_size)); @@ -7312,12 +7302,12 @@ gb_platform_init(gbPlatform *p) { gb_zero_item(p); - { /* Load XInput */ + { // Load XInput gbDllHandle xinput_library = gb_dll_load("xinput1_4.dll"); if (!xinput_library) xinput_library = gb_dll_load("xinput9_1_0.dll"); if (!xinput_library) xinput_library = gb_dll_load("xinput1_3.dll"); if (!xinput_library) { - /* TODO(bill): Diagnostic */ + // TODO(bill): Diagnostic gb_printf_err("XInput could not be loaded. Controllers will not work!\n"); } else { p->xinput.get_state = cast(gbXInputGetStateProc *) gb_dll_proc_address(xinput_library, "XInputGetState"); @@ -7328,7 +7318,7 @@ gb_platform_init(gbPlatform *p) } } - /* Init keys */ + // Init keys gb_zero_array(p->keys, gb_count_of(p->keys)); } @@ -7338,7 +7328,7 @@ gb_platform_update(gbPlatform *p) { isize i; - { /* NOTE(bill): Set window state */ + { // NOTE(bill): Set window state RECT window_rect; i32 x, y, w, h; @@ -7359,7 +7349,10 @@ gb_platform_update(gbPlatform *p) p->window.width = w; p->window.height = h; - p->window.has_focus = (GetFocus() == cast(HWND)p->window.handle); + if (GetFocus() == cast(HWND)p->window.handle) + p->window.flags |= GB_WINDOW_HAS_FOCUS; + else + p->window.flags &= ~GB_WINDOW_HAS_FOCUS; { b32 is_minimized = IsIconic(cast(HWND)p->window.handle) != 0; if (is_minimized) @@ -7369,9 +7362,8 @@ gb_platform_update(gbPlatform *p) } } - { /* NOTE(bill): Set mouse pos */ + { // NOTE(bill): Set mouse pos POINT mouse_pos; - GetCursorPos(&mouse_pos); ScreenToClient(cast(HWND)p->window.handle, &mouse_pos); @@ -7381,7 +7373,7 @@ gb_platform_update(gbPlatform *p) p->mouse.y = mouse_pos.y; } - { /* NOTE(bill): Set mouse buttons */ + { // NOTE(bill): Set mouse buttons DWORD win_button_id[GB_MOUSE_BUTTON_COUNT] = { VK_LBUTTON, VK_MBUTTON, @@ -7390,11 +7382,11 @@ gb_platform_update(gbPlatform *p) VK_XBUTTON2, }; for (i = 0; i < GB_MOUSE_BUTTON_COUNT; i++) - p->mouse.buttons[i] = GetAsyncKeyState(win_button_id[i]) < 0; + p->mouse.buttons[i] = GetKeyState(win_button_id[i]) < 0; } - /* NOTE(bill): Set Key states */ - if (p->window.has_focus) { + // NOTE(bill): Set Key states + if (p->window.flags & GB_WINDOW_HAS_FOCUS) { #define GB_KEY_STATE_SET(platform, test, state) \ if (test) p->keys[platform] |= state; \ else p->keys[platform] &= ~state @@ -7525,7 +7517,7 @@ gb_platform_update(gbPlatform *p) p->key_modifiers.shift = p->keys[GB_KEY_LSHIFT] | p->keys[GB_KEY_RSHIFT]; } - { /* NOTE(bill): Set Controller states */ + { // NOTE(bill): Set Controller states DWORD max_controller_count = XUSER_MAX_COUNT; if (max_controller_count > gb_count_of(p->game_controllers)) max_controller_count = gb_count_of(p->game_controllers); @@ -7537,18 +7529,17 @@ gb_platform_update(gbPlatform *p) XINPUT_STATE controller_state = {0}; if (p->xinput.get_state(cast(DWORD)i, &controller_state) != ERROR_SUCCESS) { - /* NOTE(bill): The controller is not available */ + // NOTE(bill): The controller is not available controller->is_connected = false; } else { - /* NOTE(bill): This controller is plugged in */ - /* TODO(bill): See if ControllerState.dwPacketNumber increments too rapidly */ + // NOTE(bill): This controller is plugged in + // TODO(bill): See if ControllerState.dwPacketNumber increments too rapidly XINPUT_GAMEPAD *pad = &controller_state.Gamepad; controller->is_connected = true; - /* TODO(bill): This is a square deadzone, check XInput to - * verify that the deadzone is "round" and do round deadzone processing. - */ + // TODO(bill): This is a square deadzone, check XInput to + // verify that the deadzone is "round" and do round deadzone processing. controller->axes[GB_CONTROLLER_AXIS_LEFT_X] = gb__process_xinput_stick_value(pad->sThumbLX, XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE); controller->axes[GB_CONTROLLER_AXIS_LEFT_Y] = gb__process_xinput_stick_value(pad->sThumbLY, XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE); controller->axes[GB_CONTROLLER_AXIS_RIGHT_Y] = gb__process_xinput_stick_value(pad->sThumbRX, XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE); @@ -7563,7 +7554,7 @@ gb_platform_update(gbPlatform *p) controller->is_analog = true; } - /* NOTE(bill): I know, I just wanted macros */ + // NOTE(bill): I know, I just wanted macros #define GB__PROCESS_PAD_BUTTON(stick_axis, sign, xinput_button) do { \ if (pad->wButtons & xinput_button) { \ controller->axes[stick_axis] = sign 1.0f; \ @@ -7600,7 +7591,7 @@ gb_platform_update(gbPlatform *p) } } - { /* NOTE(bill): Process pending messages */ + { // NOTE(bill): Process pending messages MSG message; for (;;) { BOOL is_okay = PeekMessage(&message, 0, 0, 0, PM_REMOVE); @@ -7688,12 +7679,12 @@ gb__win32_main_window_callback(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam) LRESULT result = 0; gbWindow *window = cast(gbWindow *)GetWindowLongPtr(wnd, GWLP_USERDATA); - /* TODO(bill): Do more in here? */ + // TODO(bill): Do more in here? switch (msg) { case WM_CLOSE: case WM_DESTROY: - window->is_closed = true; + window->flags |= GB_WINDOW_IS_CLOSED; break; default: @@ -7705,7 +7696,7 @@ gb__win32_main_window_callback(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam) } -/* TODO(bill): Make this return errors rathern than silly message boxes */ +// TODO(bill): Make this return errors rathern than silly message boxes gbWindow * gb_window_init(gbPlatform *p, char const *title, gbVideoMode mode, u32 flags) { @@ -7713,17 +7704,17 @@ gb_window_init(gbPlatform *p, char const *title, gbVideoMode mode, u32 flags) WNDCLASSEXW wc = {gb_size_of(WNDCLASSEXW)}; DWORD ex_style, style; RECT wr; - char16 title_buffer[256] = {0}; /* TODO(bill): gb_local_persist this? */ + char16 title_buffer[256] = {0}; // TODO(bill): gb_local_persist this? gb_zero_item(window); - wc.style = CS_HREDRAW | CS_VREDRAW; /* | CS_OWNDC */ + wc.style = CS_HREDRAW | CS_VREDRAW; // | CS_OWNDC wc.lpfnWndProc = gb__win32_main_window_callback; wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = cast(HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; - wc.lpszClassName = L"gb-win32-wndclass"; /* TODO(bill): Is this enough? */ + wc.lpszClassName = L"gb-win32-wndclass"; // TODO(bill): Is this enough? wc.hInstance = GetModuleHandle(NULL); wc.hIconSm = LoadIcon(NULL, IDI_WINLOGO); @@ -7732,7 +7723,7 @@ gb_window_init(gbPlatform *p, char const *title, gbVideoMode mode, u32 flags) return NULL; } - if (flags & GB_WINDOW_FULLSCREEN) { + if ((flags & GB_WINDOW_FULLSCREEN) && !(flags & GB_WINDOW_BORDERLESS)) { DEVMODEW screen_settings = {gb_size_of(DEVMODEW)}; GB_ASSERT(gb_video_mode_is_valid(mode)); screen_settings.dmPelsWidth = mode.width; @@ -7767,7 +7758,7 @@ gb_window_init(gbPlatform *p, char const *title, gbVideoMode mode, u32 flags) if (flags & GB_WINDOW_MINIMIZED) style |= WS_MINIMIZE; - /* NOTE(bill): Completely ignore the give mode and just change it */ + // NOTE(bill): Completely ignore the give mode and just change it if (flags & GB_WINDOW_FULLSCREEN_DESKTOP) mode = gb_video_mode_get_desktop(); @@ -7933,14 +7924,7 @@ gb_window_hide(gbWindow *w) gb_inline gbVideoMode -gb_video_mode(i32 width, i32 height) -{ - /* NOTE(bill): Oh do I wish C has default arguments for procs :( */ - return gb_video_mode_bits(width, height, 8); -} - -gb_inline gbVideoMode -gb_video_mode_bits(i32 width, i32 height, i32 bits_per_pixel) +gb_video_mode(i32 width, i32 height, i32 bits_per_pixel) { gbVideoMode m; m.width = width; @@ -7949,14 +7933,12 @@ gb_video_mode_bits(i32 width, i32 height, i32 bits_per_pixel) return m; } - - gb_inline gbVideoMode gb_video_mode_get_desktop(void) { DEVMODE win32_mode = {gb_size_of(win32_mode)}; EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &win32_mode); - return gb_video_mode_bits(win32_mode.dmPelsWidth, win32_mode.dmPelsHeight, win32_mode.dmBitsPerPel); + return gb_video_mode(win32_mode.dmPelsWidth, win32_mode.dmPelsHeight, win32_mode.dmBitsPerPel); } isize @@ -7967,7 +7949,7 @@ gb_video_mode_get_fullscreen_modes(gbVideoMode *modes, isize max_mode_count) for (count = 0; count < max_mode_count && count < EnumDisplaySettings(NULL, count, &win32_mode); count++) { - modes[count] = gb_video_mode_bits(win32_mode.dmPelsWidth, win32_mode.dmPelsHeight, win32_mode.dmBitsPerPel); + modes[count] = gb_video_mode(win32_mode.dmPelsWidth, win32_mode.dmPelsHeight, win32_mode.dmBitsPerPel); } gb_sort_array(modes, count, gb_video_mode_dsc_cmp); @@ -7976,6 +7958,14 @@ gb_video_mode_get_fullscreen_modes(gbVideoMode *modes, isize max_mode_count) #endif + +b32 +gb_window_is_open(gbWindow const *w) +{ + return (w->flags & GB_WINDOW_IS_CLOSED) == 0; +} + + gb_inline b32 gb_video_mode_is_valid(gbVideoMode mode) { @@ -8003,7 +7993,7 @@ GB_COMPARE_PROC(gb_video_mode_dsc_cmp) return -gb_video_mode_cmp(a, b); } -#endif /* GB_PLATFORM */ +#endif // GB_PLATFORM @@ -8020,4 +8010,4 @@ GB_COMPARE_PROC(gb_video_mode_dsc_cmp) } #endif -#endif /* GB_IMPLEMENTATION */ +#endif // GB_IMPLEMENTATION