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