util.h (7616B)
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 #define alignof _Alignof 17 18 #if COMPILER_CLANG || COMPILER_GCC 19 #define force_inline inline __attribute__((always_inline)) 20 #define unreachable() __builtin_unreachable() 21 #elif COMPILER_MSVC 22 #define force_inline __forceinline 23 #define unreachable() __assume(0) 24 #endif 25 26 #if COMPILER_MSVC || (COMPILER_CLANG && OS_WINDOWS) 27 #pragma section(".rdata$", read) 28 #define read_only __declspec(allocate(".rdata$")) 29 #elif COMPILER_CLANG 30 #define read_only __attribute__((section(".rodata"))) 31 #elif COMPILER_GCC 32 /* TODO(rnp): how do we do this with gcc, putting it in rodata causes warnings and writing to 33 * it doesn't cause a fault */ 34 #define read_only 35 #endif 36 37 /* TODO(rnp): msvc probably won't build this but there are other things preventing that as well */ 38 #define sqrt_f32(a) __builtin_sqrtf(a) 39 #define atan2_f32(y, x) __builtin_atan2f(y, x) 40 #define sin_f32(x) __builtin_sinf(x) 41 #define cos_f32(x) __builtin_cosf(x) 42 #define tan_f32(x) __builtin_tanf(x) 43 44 #if ARCH_ARM64 45 /* TODO? debuggers just loop here forever and need a manual PC increment (step over) */ 46 #define debugbreak() asm volatile ("brk 0xf000") 47 #elif ARCH_X64 48 #define debugbreak() asm volatile ("int3; nop") 49 #endif 50 51 #ifdef _DEBUG 52 #ifdef OS_WINDOWS 53 #define DEBUG_EXPORT __declspec(dllexport) 54 #else 55 #define DEBUG_EXPORT 56 #endif 57 #define DEBUG_DECL(a) a 58 #define assert(c) do { if (!(c)) debugbreak(); } while (0) 59 #else 60 #define DEBUG_EXPORT function 61 #define DEBUG_DECL(a) 62 #define assert(c) 63 #endif 64 65 #define InvalidCodePath assert(0) 66 #define InvalidDefaultCase default: assert(0); break 67 68 #define function static 69 #define global static 70 #define local_persist static 71 72 #define static_assert _Static_assert 73 74 /* NOTE: garbage to get the prepocessor to properly stringize the value of a macro */ 75 #define str_(...) #__VA_ARGS__ 76 #define str(...) str_(__VA_ARGS__) 77 78 #define countof(a) (sizeof(a) / sizeof(*a)) 79 #define ARRAY_COUNT(a) (sizeof(a) / sizeof(*a)) 80 #define ABS(x) ((x) < 0 ? (-x) : (x)) 81 #define BETWEEN(x, a, b) ((x) >= (a) && (x) <= (b)) 82 #define CLAMP(x, a, b) ((x) < (a) ? (a) : (x) > (b) ? (b) : (x)) 83 #define CLAMP01(x) CLAMP(x, 0, 1) 84 #define ISPOWEROF2(a) (((a) & ((a) - 1)) == 0) 85 #define MIN(a, b) ((a) < (b) ? (a) : (b)) 86 #define MAX(a, b) ((a) > (b) ? (a) : (b)) 87 #define ORONE(x) ((x)? (x) : 1) 88 #define SIGN(x) ((x) < 0? -1 : 1) 89 #define SWAP(a, b) {typeof(a) __tmp = (a); (a) = (b); (b) = __tmp;} 90 91 /* NOTE(rnp): no guarantees about actually getting an element */ 92 #define SLLPop(list) list; list = list ? list->next : 0 93 #define SLLPush(v, list) do { \ 94 (v)->next = (list); \ 95 (list) = v; \ 96 } while (0) 97 98 #define DLLPushDown(v, list) do { \ 99 (v)->next = (list); \ 100 if ((v)->next) (v)->next->prev = (v); \ 101 (list) = (v); \ 102 } while (0) 103 104 #define DLLRemove(v) do { \ 105 if ((v)->next) (v)->next->prev = (v)->prev; \ 106 if ((v)->prev) (v)->prev->next = (v)->next; \ 107 } while (0) 108 109 #define KB(a) ((u64)(a) << 10ULL) 110 #define MB(a) ((u64)(a) << 20ULL) 111 #define GB(a) ((u64)(a) << 30ULL) 112 113 #define I32_MAX (0x7FFFFFFFL) 114 #define U32_MAX (0xFFFFFFFFUL) 115 #define F32_INFINITY (__builtin_inff()) 116 117 #define PI (3.14159265358979323846) 118 119 #define INVALID_FILE (-1) 120 121 typedef char c8; 122 typedef uint8_t u8; 123 typedef int16_t s16; 124 typedef uint16_t u16; 125 typedef int32_t s32; 126 typedef uint32_t u32; 127 typedef int64_t s64; 128 typedef uint64_t u64; 129 typedef uint32_t b32; 130 typedef float f32; 131 typedef double f64; 132 typedef ptrdiff_t sz; 133 typedef size_t uz; 134 typedef ptrdiff_t sptr; 135 typedef size_t uptr; 136 137 typedef struct { u8 *beg, *end; } Arena; 138 139 typedef struct { sz len; u8 *data; } str8; 140 #define str8(s) (str8){.len = ARRAY_COUNT(s) - 1, .data = (u8 *)s} 141 142 typedef struct { sz len; u16 *data; } str16; 143 144 typedef struct { u32 cp, consumed; } UnicodeDecode; 145 146 typedef union { 147 struct { s32 x, y; }; 148 struct { s32 w, h; }; 149 s32 E[2]; 150 } sv2; 151 152 typedef union { 153 struct { s32 x, y, z; }; 154 struct { s32 w, h, d; }; 155 sv2 xy; 156 s32 E[3]; 157 } sv3; 158 159 typedef union { 160 struct { u32 x, y; }; 161 struct { u32 w, h; }; 162 u32 E[2]; 163 } uv2; 164 165 typedef union { 166 struct { u32 x, y, z; }; 167 struct { u32 w, h, d; }; 168 uv2 xy; 169 u32 E[3]; 170 } uv3; 171 172 typedef union { 173 struct { u32 x, y, z, w; }; 174 struct { uv3 xyz; u32 _w; }; 175 u32 E[4]; 176 } uv4; 177 178 typedef union { 179 struct { f32 x, y; }; 180 struct { f32 w, h; }; 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 typedef struct { v2 pos, size; } Rect; 210 #define INVERTED_INFINITY_RECT (Rect){.pos = {.x = -F32_INFINITY, .y = -F32_INFINITY}, \ 211 .size = {.x = -F32_INFINITY, .y = -F32_INFINITY}} 212 213 typedef struct { 214 u8 *data; 215 u32 widx; 216 u32 cap; 217 b32 errors; 218 } Stream; 219 220 typedef struct OS OS; 221 222 #define FILE_WATCH_CALLBACK_FN(name) b32 name(OS *os, str8 path, sptr user_data, Arena tmp) 223 typedef FILE_WATCH_CALLBACK_FN(file_watch_callback); 224 225 typedef struct { 226 sptr user_data; 227 u64 hash; 228 file_watch_callback *callback; 229 } FileWatch; 230 231 typedef struct { 232 u64 hash; 233 sptr handle; 234 str8 name; 235 236 FileWatch *data; 237 sz count; 238 sz capacity; 239 Arena buffer; 240 } FileWatchDirectory; 241 242 typedef struct { 243 FileWatchDirectory *data; 244 sz count; 245 sz capacity; 246 sptr handle; 247 } FileWatchContext; 248 249 #define OS_ALLOC_ARENA_FN(name) Arena name(sz capacity) 250 typedef OS_ALLOC_ARENA_FN(os_alloc_arena_fn); 251 252 #define OS_ADD_FILE_WATCH_FN(name) void name(OS *os, Arena *a, str8 path, \ 253 file_watch_callback *callback, sptr user_data) 254 typedef OS_ADD_FILE_WATCH_FN(os_add_file_watch_fn); 255 256 #define OS_READ_WHOLE_FILE_FN(name) str8 name(Arena *arena, char *file) 257 typedef OS_READ_WHOLE_FILE_FN(os_read_whole_file_fn); 258 259 #define OS_WRITE_NEW_FILE_FN(name) b32 name(char *fname, str8 raw) 260 typedef OS_WRITE_NEW_FILE_FN(os_write_new_file_fn); 261 262 #define OS_WRITE_FILE_FN(name) b32 name(sptr file, str8 raw) 263 typedef OS_WRITE_FILE_FN(os_write_file_fn); 264 265 struct OS { 266 FileWatchContext file_watch_context; 267 sptr context; 268 sptr error_handle; 269 }; 270 271 typedef struct { 272 u32 shader; 273 u32 vao; 274 u32 vbo; 275 } RenderContext; 276 277 typedef struct { 278 u32 fb; 279 u32 textures[2]; 280 sv2 size; 281 } RenderTarget; 282 283 typedef struct { 284 sptr elements_offset; 285 s32 elements; 286 u32 buffer; 287 u32 vao; 288 } RenderModel; 289 290 typedef struct { 291 Arena arena; 292 OS os; 293 294 RenderContext model_render_context; 295 RenderContext overlay_render_context; 296 297 RenderTarget multisample_target; 298 RenderTarget output_target; 299 RenderModel unit_cube; 300 301 sv2 window_size; 302 303 b32 demo_mode; 304 f32 cycle_t; 305 f32 camera_angle; 306 f32 camera_fov; 307 f32 camera_radius; 308 v3 camera_position; 309 310 u32 output_frames_count; 311 312 f32 last_time; 313 b32 do_update; 314 315 b32 should_exit; 316 317 Arena video_arena; 318 sz video_arena_offset; 319 320 void *window; 321 } ViewerContext; 322 323 #define LABEL_GL_OBJECT(type, id, s) {str8 _s = (s); glObjectLabel(type, id, _s.len, (c8 *)_s.data);} 324 325 #include "util.c" 326 327 #endif /* _UTIL_H_ */