#pragma once #include #include #include #include #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #include #define ASSERT(cond) if (!(cond)) { fprintf(stderr, "%s:%d (%s): Assertion failed: %s\n", __FILE__, __LINE__, __func__, #cond); __builtin_trap(); } #define NOT_IMPLEMENTED() ASSERT(0 && "Not implemented") #define NOT_REACHABLE() ASSERT(0 && "Not reachable") #define INCOMPLETE(cond) if (!(cond)) { fprintf(stderr, "%s:%d (%s): Incomplete: %s\n", __FILE__, __LINE__, __func__, #cond); __builtin_trap(); } #define BP() asm("int3;nop;") #define IS_POWER_OF_TWO(x) (((x) & ((x) - 1)) == 0) #define container_of(ptr, type, member) (type *)((char *)(ptr) - offsetof(type, member)) typedef uint64_t u64; typedef uint32_t u32; typedef uint16_t u16; typedef uint8_t u8; typedef int64_t i64; typedef int32_t i32; typedef int16_t i16; typedef int8_t i8; typedef size_t usize; typedef ptrdiff_t isize; typedef float f32; typedef double f64; #define log(level, fmt, ...) fprintf(stderr, "[" level "] %s:%d (%s): " fmt "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__) #define LOG_LEVEL_TRACE 6 #define LOG_LEVEL_DEBUG 5 #define LOG_LEVEL_VERBOSE 4 #define LOG_LEVEL_INFO 3 #define LOG_LEVEL_WARNING 2 #define LOG_LEVEL_ERROR 1 #define LOG_LEVEL_FATAL 0 #define LOG_LEVEL LOG_LEVEL_DEBUG #if (LOG_LEVEL >= LOG_LEVEL_TRACE) #define logt(fmt, ...) log("TRACE", fmt, ##__VA_ARGS__) #else #define logt(fmt, ...) #endif #if (LOG_LEVEL >= LOG_LEVEL_DEBUG) #define logd(fmt, ...) log("\033[1;34mDEBUG\033[0m", fmt, ##__VA_ARGS__) #else #define logd(fmt, ...) #endif #if (LOG_LEVEL >= LOG_LEVEL_VERBOSE) #define logv(fmt, ...) log("\033[1;32mVERBOSE\033[0m", fmt, ##__VA_ARGS__) #else #define logv(fmt, ...) #endif #if (LOG_LEVEL >= LOG_LEVEL_INFO) #define logi(fmt, ...) log("\033[1;32mINFO\033[0m", fmt, ##__VA_ARGS__) #else #define logi(fmt, ...) #endif #if (LOG_LEVEL >= LOG_LEVEL_WARNING) #define logw(fmt, ...) log("\033[1;33mWARNING\033[0m", fmt, ##__VA_ARGS__) #else #define logw(fmt, ...) #endif #if (LOG_LEVEL >= LOG_LEVEL_ERROR) #define loge(fmt, ...) log("\033[1;31mERROR\033[0m", fmt, ##__VA_ARGS__) #else #define loge(fmt, ...) #endif #if (LOG_LEVEL >= LOG_LEVEL_FATAL) #define logf(fmt, ...) do { log("\033[1;31mFATAL\033[0m", fmt, ##__VA_ARGS__); __builtin_trap(); } while (0) #else #define logf(fmt, ...) #endif #define Kilobytes(x) ((u64) (x) << 10) #define Megabytes(x) ((u64) (x) << 20) #define Gigabytes(x) ((u64) (x) << 30) #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define CLAMP(x, lo, hi) ((x) < (lo) ? (lo) : (x) > (hi) ? (hi) : (x)) typedef union Vec2 { struct { f32 x, y; }; struct { f32 u, v; }; } Vec2; typedef union Vec2i { struct { i32 x, y; }; struct { i32 u, v; }; } Vec2i ; typedef struct Mat4 { float e[4][4]; } Mat4; static inline Vec2 vec2_add(Vec2 a, Vec2 b) { Vec2 result = { .x = a.x + b.x, .y = a.y + b.y, }; return result; } static inline Vec2 vec2_sub(Vec2 a, Vec2 b) { Vec2 result = { .x = a.x - b.x, .y = a.y - b.y, }; return result; } static inline Vec2 vec2(f32 x, f32 y) { Vec2 result = { x, y }; return result; } static inline f32 vec2_dot(Vec2 a, Vec2 b) { return a.x * b.x + a.y * b.y; } static inline f32 vec2_norm2(Vec2 v) { return vec2_dot(v, v); } static inline f32 vec2_norm(Vec2 v) { return sqrtf(vec2_norm2(v)); } static inline f32 vec2_dist(Vec2 a, Vec2 b) { return vec2_norm(vec2_sub(a, b)); } typedef struct Rect2i { int x, y, w, h; } Rect2i; typedef struct Rect2f { f32 x, y, w, h; } Rect2f; static inline Rect2f rect2f(f32 x, f32 y, f32 w, f32 h) { Rect2f result = { x, y, w, h }; return result; }