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