util.h (9395B)
1 /* See LICENSE for license details. */ 2 #ifndef _UTIL_H_ 3 #define _UTIL_H_ 4 5 #include <stddef.h> 6 #include <stdint.h> 7 8 #include "compiler.h" 9 10 #ifndef asm 11 #define asm __asm__ 12 #endif 13 14 #ifndef typeof 15 #define typeof __typeof__ 16 #endif 17 18 #ifdef _DEBUG 19 #if OS_WINDOWS 20 #define DEBUG_EXPORT __declspec(dllexport) 21 #ifdef _BEAMFORMER_DLL 22 #define DEBUG_IMPORT __declspec(dllimport) 23 #else 24 #define DEBUG_IMPORT __declspec(dllexport) 25 #endif 26 #else 27 #ifdef _BEAMFORMER_DLL 28 #define DEBUG_IMPORT extern 29 #else 30 #define DEBUG_IMPORT 31 #endif 32 #define DEBUG_EXPORT 33 #endif 34 #define DEBUG_DECL(a) a 35 #define assert(c) do { if (!(c)) debugbreak(); } while (0) 36 #else 37 #define DEBUG_IMPORT global 38 #define DEBUG_EXPORT function 39 #define DEBUG_DECL(a) 40 #define assert(c) 41 #endif 42 #define ASSERT assert 43 44 #define INVALID_CODE_PATH ASSERT(0) 45 #define INVALID_DEFAULT_CASE default: ASSERT(0); break 46 #define InvalidCodePath assert(0) 47 #define InvalidDefaultCase default: assert(0); break 48 49 #define arg_list(type, ...) (type []){__VA_ARGS__}, sizeof((type []){__VA_ARGS__}) / sizeof(type) 50 51 #define function static 52 #define global static 53 #define local_persist static 54 55 #define static_assert _Static_assert 56 57 /* NOTE: garbage to get the prepocessor to properly stringize the value of a macro */ 58 #define str_(...) #__VA_ARGS__ 59 #define str(...) str_(__VA_ARGS__) 60 61 #define countof(a) (sizeof(a) / sizeof(*a)) 62 #define ARRAY_COUNT(a) (sizeof(a) / sizeof(*a)) 63 #define ABS(x) ((x) < 0 ? (-x) : (x)) 64 #define BETWEEN(x, a, b) ((x) >= (a) && (x) <= (b)) 65 #define CLAMP(x, a, b) ((x) < (a) ? (a) : (x) > (b) ? (b) : (x)) 66 #define CLAMP01(x) CLAMP(x, 0, 1) 67 #define ISPOWEROF2(a) (((a) & ((a) - 1)) == 0) 68 #define MIN(a, b) ((a) < (b) ? (a) : (b)) 69 #define MAX(a, b) ((a) > (b) ? (a) : (b)) 70 #define ORONE(x) ((x)? (x) : 1) 71 #define SIGN(x) ((x) < 0? -1 : 1) 72 #define swap(a, b) do {typeof(a) __tmp = (a); (a) = (b); (b) = __tmp;} while(0) 73 74 #define f32_cmp(x, y) (ABS((x) - (y)) <= F32_EPSILON * MAX(1.0f, MAX(ABS(x), ABS(y)))) 75 76 #define EachElement(array, it) (u64 it = 0; it < countof(array); it += 1) 77 #define EachEnumValue(type, it) (type it = (type)0; it < type##_Count; it = (type)(it + 1)) 78 #define EachNonZeroEnumValue(type, it) (type it = (type)1; it < type##_Count; it = (type)(it + 1)) 79 80 /* NOTE(rnp): no guarantees about actually getting an element */ 81 #define SLLPop(list) list; list = list ? list->next : 0 82 #define SLLPush(v, list) do { \ 83 (v)->next = (list); \ 84 (list) = v; \ 85 } while (0) 86 87 #define DLLPushDown(v, list) do { \ 88 (v)->next = (list); \ 89 if ((v)->next) (v)->next->prev = (v); \ 90 (list) = (v); \ 91 } while (0) 92 93 #define DLLRemove(v) do { \ 94 if ((v)->next) (v)->next->prev = (v)->prev; \ 95 if ((v)->prev) (v)->prev->next = (v)->next; \ 96 } while (0) 97 98 #define KB(a) ((u64)(a) << 10ULL) 99 #define MB(a) ((u64)(a) << 20ULL) 100 #define GB(a) ((u64)(a) << 30ULL) 101 102 #define I32_MAX (0x7FFFFFFFL) 103 #define U32_MAX (0xFFFFFFFFUL) 104 #define F32_INFINITY (1e+300*1e+300) 105 #define F32_EPSILON (1e-6) 106 #ifndef PI 107 #define PI (3.14159265358979323846f) 108 #endif 109 110 typedef char c8; 111 typedef uint8_t u8; 112 typedef int16_t i16; 113 typedef uint16_t u16; 114 typedef int32_t i32; 115 typedef uint32_t u32; 116 typedef int64_t i64; 117 typedef uint64_t u64; 118 typedef uint32_t b32; 119 typedef float f32; 120 typedef double f64; 121 typedef ptrdiff_t iz; 122 typedef size_t uz; 123 typedef ptrdiff_t iptr; 124 typedef size_t uptr; 125 126 #include "intrinsics.c" 127 128 typedef struct { u8 *beg, *end; } Arena; 129 typedef struct { Arena *arena; u8 *old_beg; } TempArena; 130 131 typedef struct { iz len; u8 *data; } s8; 132 #define s8(s) (s8){.len = ARRAY_COUNT(s) - 1, .data = (u8 *)s} 133 #define s8_comp(s) {sizeof(s) - 1, (u8 *)s} 134 135 typedef struct { iz len; u16 *data; } s16; 136 137 typedef struct { u32 cp, consumed; } UnicodeDecode; 138 139 /* NOTE: raylib stubs */ 140 #ifndef RAYLIB_H 141 typedef struct { f32 x, y; } Vector2; 142 typedef struct { f32 x, y, w, h; } Rectangle; 143 #endif 144 145 typedef union { 146 struct { i32 x, y; }; 147 struct { i32 w, h; }; 148 i32 E[2]; 149 } iv2; 150 151 typedef union { 152 struct { i32 x, y, z; }; 153 struct { i32 w, h, d; }; 154 iv2 xy; 155 i32 E[3]; 156 } iv3; 157 158 typedef union { 159 struct { u32 x, y; }; 160 struct { u32 w, h; }; 161 u32 E[2]; 162 } uv2; 163 164 typedef union { 165 struct { u32 x, y, z; }; 166 struct { u32 w, h, d; }; 167 uv2 xy; 168 u32 E[3]; 169 } uv3; 170 171 typedef union { 172 struct { u32 x, y, z, w; }; 173 struct { uv3 xyz; u32 _w; }; 174 u32 E[4]; 175 } uv4; 176 177 typedef union { 178 struct { f32 x, y; }; 179 struct { f32 w, h; }; 180 Vector2 rl; 181 f32 E[2]; 182 } v2; 183 184 typedef union { 185 struct { f32 x, y, z; }; 186 struct { f32 w, h, d; }; 187 f32 E[3]; 188 } v3; 189 190 typedef union { 191 struct { f32 x, y, z, w; }; 192 struct { f32 r, g, b, a; }; 193 struct { v3 xyz; f32 _1; }; 194 struct { f32 _2; v3 yzw; }; 195 struct { v2 xy, zw; }; 196 f32 E[4]; 197 } v4; 198 199 #define XZ(v) (v2){.x = v.x, .y = v.z} 200 #define YZ(v) (v2){.x = v.y, .y = v.z} 201 #define XY(v) (v2){.x = v.x, .y = v.y} 202 203 typedef union { 204 struct { v4 x, y, z, w; }; 205 v4 c[4]; 206 f32 E[16]; 207 } m4; 208 209 /* TODO(rnp): delete raylib */ 210 typedef struct { 211 v3 origin; 212 v3 direction; 213 } ray; 214 215 typedef union { 216 struct { v2 pos, size; }; 217 Rectangle rl; 218 } Rect; 219 #define INVERTED_INFINITY_RECT (Rect){.pos = {.x = -F32_INFINITY, .y = -F32_INFINITY}, \ 220 .size = {.x = -F32_INFINITY, .y = -F32_INFINITY}} 221 222 typedef struct { 223 u8 *data; 224 u32 widx; 225 u32 cap; 226 b32 errors; 227 } Stream; 228 229 #define INVALID_FILE (-1) 230 231 typedef struct OS OS; 232 233 typedef struct { 234 Arena arena; 235 iptr handle; 236 iptr window_handle; 237 iptr gl_context; 238 iptr user_context; 239 i32 sync_variable; 240 b32 asleep; 241 } GLWorkerThreadContext; 242 243 #define FILE_WATCH_CALLBACK_FN(name) b32 name(OS *os, s8 path, iptr user_data, Arena arena) 244 typedef FILE_WATCH_CALLBACK_FN(file_watch_callback); 245 246 typedef struct { 247 iptr user_data; 248 u64 hash; 249 file_watch_callback *callback; 250 } FileWatch; 251 252 typedef struct { 253 u64 hash; 254 iptr handle; 255 s8 name; 256 257 FileWatch *data; 258 iz count; 259 iz capacity; 260 Arena buffer; 261 } FileWatchDirectory; 262 263 typedef struct { 264 FileWatchDirectory *data; 265 iz count; 266 iz capacity; 267 iptr handle; 268 } FileWatchContext; 269 270 typedef struct { 271 void *region; 272 iptr os_context; 273 } SharedMemoryRegion; 274 275 #define OS_ALLOC_ARENA_FN(name) Arena name(iz capacity) 276 typedef OS_ALLOC_ARENA_FN(os_alloc_arena_fn); 277 278 #define OS_ADD_FILE_WATCH_FN(name) void name(OS *os, Arena *a, s8 path, \ 279 file_watch_callback *callback, iptr user_data) 280 typedef OS_ADD_FILE_WATCH_FN(os_add_file_watch_fn); 281 282 #define OS_WAKE_WORKER_FN(name) void name(GLWorkerThreadContext *ctx) 283 typedef OS_WAKE_WORKER_FN(os_wake_worker_fn); 284 285 #define OS_READ_WHOLE_FILE_FN(name) s8 name(Arena *arena, char *file) 286 typedef OS_READ_WHOLE_FILE_FN(os_read_whole_file_fn); 287 288 #define OS_WAIT_ON_VALUE_FN(name) b32 name(i32 *value, i32 current, u32 timeout_ms) 289 typedef OS_WAIT_ON_VALUE_FN(os_wait_on_value_fn); 290 291 #define OS_WAKE_WAITERS_FN(name) void name(i32 *sync) 292 typedef OS_WAKE_WAITERS_FN(os_wake_waiters_fn); 293 294 #define OS_WRITE_NEW_FILE_FN(name) b32 name(char *fname, s8 raw) 295 typedef OS_WRITE_NEW_FILE_FN(os_write_new_file_fn); 296 297 #define OS_WRITE_FILE_FN(name) b32 name(iptr file, s8 raw) 298 typedef OS_WRITE_FILE_FN(os_write_file_fn); 299 300 #define OS_THREAD_ENTRY_POINT_FN(name) iptr name(iptr _ctx) 301 typedef OS_THREAD_ENTRY_POINT_FN(os_thread_entry_point_fn); 302 303 #define OS_SHARED_MEMORY_LOCK_REGION_FN(name) b32 name(SharedMemoryRegion *sm, i32 *locks, i32 lock_index, i32 timeout_ms) 304 typedef OS_SHARED_MEMORY_LOCK_REGION_FN(os_shared_memory_region_lock_fn); 305 306 #define OS_SHARED_MEMORY_UNLOCK_REGION_FN(name) void name(SharedMemoryRegion *sm, i32 *locks, i32 lock_index) 307 typedef OS_SHARED_MEMORY_UNLOCK_REGION_FN(os_shared_memory_region_unlock_fn); 308 309 #define OS_FNS \ 310 X(add_file_watch) \ 311 X(read_whole_file) \ 312 X(shared_memory_region_lock) \ 313 X(shared_memory_region_unlock) \ 314 X(wake_waiters) \ 315 X(write_new_file) \ 316 X(write_file) 317 318 #define RENDERDOC_GET_API_FN(name) b32 name(u32 version, void **out_api) 319 typedef RENDERDOC_GET_API_FN(renderdoc_get_api_fn); 320 321 #define RENDERDOC_START_FRAME_CAPTURE_FN(name) void name(iptr gl_context, iptr window_handle) 322 typedef RENDERDOC_START_FRAME_CAPTURE_FN(renderdoc_start_frame_capture_fn); 323 324 #define RENDERDOC_END_FRAME_CAPTURE_FN(name) b32 name(iptr gl_context, iptr window_handle) 325 typedef RENDERDOC_END_FRAME_CAPTURE_FN(renderdoc_end_frame_capture_fn); 326 327 typedef align_as(16) u8 RenderDocAPI[216]; 328 #define RENDERDOC_API_FN_ADDR(a, offset) (*(iptr *)((*a) + offset)) 329 #define RENDERDOC_START_FRAME_CAPTURE(a) (renderdoc_start_frame_capture_fn *)RENDERDOC_API_FN_ADDR(a, 152) 330 #define RENDERDOC_END_FRAME_CAPTURE(a) (renderdoc_end_frame_capture_fn *) RENDERDOC_API_FN_ADDR(a, 168) 331 332 struct OS { 333 #define X(name) os_ ## name ## _fn *name; 334 OS_FNS 335 #undef X 336 FileWatchContext file_watch_context; 337 iptr context; 338 iptr error_handle; 339 GLWorkerThreadContext compute_worker; 340 341 DEBUG_DECL(renderdoc_start_frame_capture_fn *start_frame_capture;) 342 DEBUG_DECL(renderdoc_end_frame_capture_fn *end_frame_capture;) 343 }; 344 345 #define LABEL_GL_OBJECT(type, id, s) {s8 _s = (s); glObjectLabel(type, id, _s.len, (c8 *)_s.data);} 346 347 #include "util.c" 348 #include "math.c" 349 350 #endif /* _UTIL_H_ */