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