2016-07-09 10:46:04 +00:00
|
|
|
#include "Dengine/Debug.h"
|
2016-07-16 13:27:52 +00:00
|
|
|
#include "Dengine/Platform.h"
|
2016-07-18 12:02:47 +00:00
|
|
|
#include "Dengine/AssetManager.h"
|
2016-07-09 10:46:04 +00:00
|
|
|
|
2016-07-18 12:02:47 +00:00
|
|
|
DebugState GLOBAL_debug;
|
2016-07-09 10:46:04 +00:00
|
|
|
|
|
|
|
void debug_init()
|
|
|
|
{
|
2016-07-18 12:02:47 +00:00
|
|
|
GLOBAL_debug.totalMemoryAllocated = 0;
|
|
|
|
GLOBAL_debug.callCount = PLATFORM_MEM_ALLOC(debugcallcount_num, i32);
|
2016-07-09 11:42:36 +00:00
|
|
|
|
2016-07-18 12:02:47 +00:00
|
|
|
GLOBAL_debug.numDebugStrings = 0;
|
|
|
|
GLOBAL_debug.stringUpdateTimer = 0.0f;
|
|
|
|
GLOBAL_debug.stringUpdateRate = 0.15f;
|
2016-07-09 10:46:04 +00:00
|
|
|
|
2016-07-18 12:02:47 +00:00
|
|
|
GLOBAL_debug.stringLineGap = -1;
|
2016-07-09 10:46:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void debug_pushString(char *formatString, void *data, char *dataType)
|
|
|
|
{
|
2016-07-18 12:02:47 +00:00
|
|
|
if (GLOBAL_debug.stringUpdateTimer <= 0)
|
2016-07-09 10:46:04 +00:00
|
|
|
{
|
2016-07-18 12:02:47 +00:00
|
|
|
i32 numDebugStrings = GLOBAL_debug.numDebugStrings;
|
2016-07-09 10:46:04 +00:00
|
|
|
if (common_strcmp(dataType, "v2") == 0)
|
|
|
|
{
|
|
|
|
v2 val = *(CAST(v2 *) data);
|
2016-07-18 12:02:47 +00:00
|
|
|
snprintf(GLOBAL_debug.debugStrings[numDebugStrings],
|
|
|
|
ARRAY_COUNT(GLOBAL_debug.debugStrings[0]),
|
2016-07-09 10:46:04 +00:00
|
|
|
formatString, val.x, val.y);
|
|
|
|
}
|
|
|
|
else if (common_strcmp(dataType, "i32") == 0)
|
|
|
|
{
|
|
|
|
i32 val = *(CAST(i32 *) data);
|
2016-07-18 12:02:47 +00:00
|
|
|
snprintf(GLOBAL_debug.debugStrings[numDebugStrings],
|
|
|
|
ARRAY_COUNT(GLOBAL_debug.debugStrings[0]),
|
2016-07-09 10:46:04 +00:00
|
|
|
formatString, val);
|
|
|
|
}
|
2016-07-15 16:34:44 +00:00
|
|
|
else if (common_strcmp(dataType, "f32") == 0)
|
|
|
|
{
|
|
|
|
f32 val = *(CAST(f32 *) data);
|
2016-07-18 12:02:47 +00:00
|
|
|
snprintf(GLOBAL_debug.debugStrings[numDebugStrings],
|
|
|
|
ARRAY_COUNT(GLOBAL_debug.debugStrings[0]),
|
2016-07-15 16:34:44 +00:00
|
|
|
formatString, val);
|
|
|
|
}
|
2016-07-18 10:16:29 +00:00
|
|
|
else if (common_strcmp(dataType, "char") == 0)
|
|
|
|
{
|
2016-07-19 05:19:08 +00:00
|
|
|
if (data)
|
|
|
|
{
|
|
|
|
char *val = CAST(char *) data;
|
2016-07-18 10:16:29 +00:00
|
|
|
|
2016-07-19 05:19:08 +00:00
|
|
|
snprintf(GLOBAL_debug.debugStrings[numDebugStrings],
|
|
|
|
ARRAY_COUNT(GLOBAL_debug.debugStrings[0]),
|
|
|
|
formatString, val);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
snprintf(GLOBAL_debug.debugStrings[numDebugStrings],
|
|
|
|
ARRAY_COUNT(GLOBAL_debug.debugStrings[0]),
|
|
|
|
formatString);
|
|
|
|
}
|
2016-07-18 10:16:29 +00:00
|
|
|
}
|
2016-07-19 05:19:08 +00:00
|
|
|
|
2016-07-09 10:46:04 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
ASSERT(INVALID_CODE_PATH);
|
|
|
|
}
|
2016-07-18 12:02:47 +00:00
|
|
|
GLOBAL_debug.numDebugStrings++;
|
2016-07-09 10:46:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void debug_stringUpdateAndRender(Renderer *renderer, Font *font, f32 dt)
|
|
|
|
{
|
2016-07-18 12:02:47 +00:00
|
|
|
if (GLOBAL_debug.stringLineGap == -1)
|
2016-07-09 10:46:04 +00:00
|
|
|
{
|
2016-07-18 12:02:47 +00:00
|
|
|
GLOBAL_debug.stringLineGap =
|
2016-07-09 10:46:04 +00:00
|
|
|
1.1f * asset_getVFontSpacing(font->metrics);
|
2016-07-18 12:02:47 +00:00
|
|
|
GLOBAL_debug.initialStringPos =
|
2016-07-09 10:46:04 +00:00
|
|
|
V2(0.0f,
|
2016-07-18 12:02:47 +00:00
|
|
|
(renderer->size.y - 1.8f * GLOBAL_debug.stringLineGap));
|
|
|
|
GLOBAL_debug.stringPos = GLOBAL_debug.initialStringPos;
|
2016-07-09 10:46:04 +00:00
|
|
|
}
|
|
|
|
|
2016-07-18 12:02:47 +00:00
|
|
|
for (i32 i = 0; i < GLOBAL_debug.numDebugStrings; i++)
|
2016-07-09 10:46:04 +00:00
|
|
|
{
|
|
|
|
f32 rotate = 0;
|
|
|
|
v4 color = V4(0, 0, 0, 1);
|
2016-07-18 12:02:47 +00:00
|
|
|
renderer_staticString(renderer, font, GLOBAL_debug.debugStrings[i],
|
|
|
|
GLOBAL_debug.stringPos, rotate, color);
|
|
|
|
GLOBAL_debug.stringPos.y -=
|
|
|
|
(0.9f * GLOBAL_debug.stringLineGap);
|
2016-07-09 10:46:04 +00:00
|
|
|
}
|
|
|
|
|
2016-07-18 12:02:47 +00:00
|
|
|
if (GLOBAL_debug.stringUpdateTimer <= 0)
|
2016-07-09 10:46:04 +00:00
|
|
|
{
|
2016-07-18 12:02:47 +00:00
|
|
|
GLOBAL_debug.stringUpdateTimer =
|
|
|
|
GLOBAL_debug.stringUpdateRate;
|
2016-07-09 10:46:04 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-07-18 12:02:47 +00:00
|
|
|
GLOBAL_debug.stringUpdateTimer -= dt;
|
|
|
|
if (GLOBAL_debug.stringUpdateTimer <= 0)
|
2016-07-09 10:46:04 +00:00
|
|
|
{
|
2016-07-18 12:02:47 +00:00
|
|
|
GLOBAL_debug.numDebugStrings = 0;
|
2016-07-09 10:46:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-18 12:02:47 +00:00
|
|
|
GLOBAL_debug.stringPos = GLOBAL_debug.initialStringPos;
|
2016-07-09 10:46:04 +00:00
|
|
|
}
|
2016-07-09 10:59:54 +00:00
|
|
|
|
2016-07-18 12:02:47 +00:00
|
|
|
void debug_drawUi(GameState *state, f32 dt)
|
|
|
|
{
|
|
|
|
AssetManager *assetManager = &state->assetManager;
|
|
|
|
Renderer *renderer = &state->renderer;
|
|
|
|
World *const world = &state->world[state->currWorldIndex];
|
|
|
|
Entity *hero = &world->entities[world->heroIndex];
|
|
|
|
Font *font = &assetManager->font;
|
|
|
|
|
|
|
|
// TODO(doyle): Dumb copy function from game so we don't expose api
|
|
|
|
v4 cameraBounds = math_getRect(world->cameraPos, renderer->size);
|
|
|
|
if (cameraBounds.x <= world->bounds.x)
|
|
|
|
{
|
|
|
|
cameraBounds.x = world->bounds.x;
|
|
|
|
cameraBounds.z = cameraBounds.x + renderer->size.w;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cameraBounds.y >= world->bounds.y) cameraBounds.y = world->bounds.y;
|
|
|
|
|
|
|
|
if (cameraBounds.z >= world->bounds.z)
|
|
|
|
{
|
|
|
|
cameraBounds.z = world->bounds.z;
|
|
|
|
cameraBounds.x = cameraBounds.z - renderer->size.w;
|
|
|
|
}
|
|
|
|
if (cameraBounds.w <= world->bounds.w) cameraBounds.w = world->bounds.w;
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
Texture *emptyTex = asset_getTexture(assetManager, texlist_empty);
|
|
|
|
v2 heroCenter = v2_add(hero->pos, v2_scale(hero->hitboxSize, 0.5f));
|
|
|
|
RenderTex renderTex = {emptyTex, V4(0, 1, 1, 0)};
|
|
|
|
renderer_rect(&state->renderer, cameraBounds, heroCenter,
|
|
|
|
V2(distance, 5.0f), 0, renderTex, V4(1, 0, 0, 0.25f));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (world->numEntitiesInBattle > 0)
|
|
|
|
{
|
|
|
|
v4 color = V4(1.0f, 0, 0, 1);
|
|
|
|
char *battleStr = "IN-BATTLE RANGE";
|
|
|
|
f32 strLenInPixels =
|
|
|
|
CAST(f32)(font->maxSize.w * common_strlen(battleStr));
|
|
|
|
v2 strPos = V2((renderer->size.w * 0.5f) - (strLenInPixels * 0.5f),
|
|
|
|
renderer->size.h - 300.0f);
|
|
|
|
renderer_staticString(&state->renderer, font, battleStr, strPos, 0,
|
|
|
|
color);
|
|
|
|
}
|
|
|
|
|
2016-07-19 05:19:08 +00:00
|
|
|
for (i32 i = 0; i < world->maxEntities; i++)
|
2016-07-18 12:02:47 +00:00
|
|
|
{
|
2016-07-19 05:19:08 +00:00
|
|
|
Entity *const entity = &world->entities[i];
|
2016-07-18 12:02:47 +00:00
|
|
|
/* Render debug markers on entities */
|
|
|
|
v4 color = V4(1, 1, 1, 1);
|
|
|
|
char *debugString = NULL;
|
|
|
|
switch (entity->type)
|
|
|
|
{
|
|
|
|
case entitytype_mob:
|
|
|
|
color = V4(1, 0, 0, 1);
|
|
|
|
debugString = "MOB";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case entitytype_hero:
|
|
|
|
color = V4(0, 0, 1.0f, 1);
|
|
|
|
debugString = "HERO";
|
|
|
|
break;
|
|
|
|
|
|
|
|
case entitytype_npc:
|
|
|
|
color = V4(0, 1.0f, 0, 1);
|
|
|
|
debugString = "NPC";
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (debugString)
|
|
|
|
{
|
|
|
|
v2 strPos = v2_add(entity->pos, entity->hitboxSize);
|
|
|
|
i32 indexOfLowerAInMetrics = 'a' - CAST(i32) font->codepointRange.x;
|
|
|
|
strPos.y += font->charMetrics[indexOfLowerAInMetrics].offset.y;
|
|
|
|
|
|
|
|
renderer_string(&state->renderer, cameraBounds, font, debugString,
|
|
|
|
strPos, 0, color);
|
|
|
|
|
|
|
|
f32 stringLineGap = 1.1f * asset_getVFontSpacing(font->metrics);
|
|
|
|
strPos.y -= GLOBAL_debug.stringLineGap;
|
|
|
|
|
|
|
|
char entityPosStr[128];
|
|
|
|
snprintf(entityPosStr, ARRAY_COUNT(entityPosStr), "%06.2f, %06.2f",
|
|
|
|
entity->pos.x, entity->pos.y);
|
|
|
|
renderer_string(&state->renderer, cameraBounds, font, entityPosStr,
|
|
|
|
strPos, 0, color);
|
|
|
|
|
|
|
|
strPos.y -= GLOBAL_debug.stringLineGap;
|
|
|
|
char entityIDStr[32];
|
2016-07-19 05:19:08 +00:00
|
|
|
snprintf(entityIDStr, ARRAY_COUNT(entityIDStr), "ID: %4d/%d", entity->id,
|
|
|
|
world->uniqueIdAccumulator-1);
|
2016-07-18 12:02:47 +00:00
|
|
|
renderer_string(&state->renderer, cameraBounds, font, entityIDStr,
|
|
|
|
strPos, 0, color);
|
|
|
|
|
|
|
|
if (entity->stats)
|
|
|
|
{
|
|
|
|
strPos.y -= GLOBAL_debug.stringLineGap;
|
|
|
|
char entityHealth[32];
|
|
|
|
snprintf(entityHealth, ARRAY_COUNT(entityHealth), "HP: %3.0f/%3.0f",
|
|
|
|
entity->stats->health, entity->stats->maxHealth);
|
|
|
|
renderer_string(&state->renderer, cameraBounds, font,
|
|
|
|
entityHealth, strPos, 0, color);
|
|
|
|
|
|
|
|
strPos.y -= GLOBAL_debug.stringLineGap;
|
|
|
|
char entityTimer[32];
|
|
|
|
snprintf(entityTimer, ARRAY_COUNT(entityTimer), "ATB: %3.0f/%3.0f",
|
|
|
|
entity->stats->actionTimer, entity->stats->actionRate);
|
|
|
|
renderer_string(&state->renderer, cameraBounds, font,
|
|
|
|
entityTimer, strPos, 0, color);
|
|
|
|
}
|
2016-07-19 05:19:08 +00:00
|
|
|
|
|
|
|
strPos.y -= GLOBAL_debug.stringLineGap;
|
|
|
|
char *entityStateStr = debug_entitystate_string(entity->state);
|
|
|
|
renderer_string(&state->renderer, cameraBounds, font,
|
|
|
|
entityStateStr, strPos, 0, color);
|
2016-07-18 12:02:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Render debug info stack */
|
2016-07-19 05:19:08 +00:00
|
|
|
DEBUG_PUSH_STRING("== Hero Properties == ");
|
|
|
|
DEBUG_PUSH_VAR("Hero Pos: %06.2f, %06.2f", hero->pos, "v2");
|
|
|
|
DEBUG_PUSH_VAR("Hero dPos: %06.2f, %06.2f", hero->dPos, "v2");
|
|
|
|
DEBUG_PUSH_VAR("Hero Busy Duration: %05.3f", hero->stats->busyDuration, "f32");
|
2016-07-18 12:02:47 +00:00
|
|
|
char *heroStateString = debug_entitystate_string(hero->state);
|
2016-07-19 05:19:08 +00:00
|
|
|
DEBUG_PUSH_VAR("Hero State: %s", *heroStateString, "char");
|
2016-07-18 12:02:47 +00:00
|
|
|
char *heroQueuedAttackStr =
|
|
|
|
debug_entityattack_string(hero->stats->queuedAttack);
|
2016-07-19 05:19:08 +00:00
|
|
|
DEBUG_PUSH_VAR("Hero QueuedAttack: %s", *heroQueuedAttackStr, "char");
|
2016-07-18 12:02:47 +00:00
|
|
|
|
2016-07-19 05:19:08 +00:00
|
|
|
DEBUG_PUSH_STRING("== State Properties == ");
|
|
|
|
DEBUG_PUSH_VAR("FreeEntityIndex: %d", world->freeEntityIndex, "i32");
|
|
|
|
DEBUG_PUSH_VAR("glDrawArray Calls: %d",
|
|
|
|
GLOBAL_debug.callCount[debugcallcount_drawArrays], "i32");
|
|
|
|
i32 debug_kbAllocated = GLOBAL_debug.totalMemoryAllocated / 1024;
|
|
|
|
DEBUG_PUSH_VAR("TotalMemoryAllocated: %dkb", debug_kbAllocated, "i32");
|
2016-07-18 12:02:47 +00:00
|
|
|
|
2016-07-19 05:19:08 +00:00
|
|
|
DEBUG_PUSH_STRING("== EntityIDs in Battle List == ");
|
|
|
|
DEBUG_PUSH_VAR("NumEntitiesInBattle: %d", world->numEntitiesInBattle,
|
|
|
|
"i32");
|
|
|
|
if (world->numEntitiesInBattle > 0)
|
|
|
|
{
|
|
|
|
for (i32 i = 0; i < world->maxEntities; i++)
|
|
|
|
{
|
|
|
|
if (world->entityIdInBattle[i])
|
|
|
|
DEBUG_PUSH_VAR("Entity ID: %d", i, "i32");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DEBUG_PUSH_STRING("-none-");
|
|
|
|
}
|
2016-07-18 12:02:47 +00:00
|
|
|
|
|
|
|
debug_stringUpdateAndRender(&state->renderer, font, dt);
|
|
|
|
debug_clearCallCounter();
|
|
|
|
}
|