#if DEBUG static int32 *debugnull = NULL; #define Assert(Expression) if(!(Expression)) {*debugnull = 21;} enum valtype { d_float, d_uint, d_int }; union debugval { real32 f; uint32 u; int32 i; }; // things that get cleared every frame with the UI struct debug_temp { valtype DebugPropertyType[16]; debugval Val[16]; char *String[16]; uint32 WatchedProperties; }; struct project_debug { debug_temp Temp; bool32 ToggleWindow; uint64 PixelCountTransparent; uint64 PixelCountRendered; uint64 PixelCountChecked; // NOTE(fox): Pixel count isn't thread safe; don't use with multithreading! uint64 LayerCycleCount[64]; }; static project_debug Debug; static void DebugWatchVar(char *Name, void *Address, valtype Type) { uint32 i = Debug.Temp.WatchedProperties; Debug.Temp.String[i] = Name; if (Type == d_float) Debug.Temp.Val[i].f = *(real32 *)Address; if (Type == d_uint) Debug.Temp.Val[i].u = *(uint32 *)Address; if (Type == d_int) Debug.Temp.Val[i].i = *(int32 *)Address; Debug.Temp.DebugPropertyType[i] = Type; Debug.Temp.WatchedProperties++; } static void DebugPrintMemoryUsage(memory Memory) { for (int i = 0; i < 8; i++) { memory_table Table = Memory.Slot[i]; printf("%s: %li bytes, %li kb\n", Table.Name, Table.CurrentPosition, Table.CurrentPosition / 1024); } } #else #define Assert(Expression) enum valtype { }; union debugval { }; struct debug_temp { }; struct project_debug { }; static void DebugWatchVar(char *Name, void *Address, valtype Type) { } static void DebugPrintMemoryUsage(memory Memory) { } #endif #ifdef PERF struct perf_stats { uint64 PixelCountTransparent; uint64 PixelCountRendered; uint64 PixelCountChecked; }; static uint64 Test; #endif