Implement battle time bar attacking within range

The main debug drawing elements have been moved to debug.c to avoid
cluttering up the main game file. The downside is that thus far the debug
values only track values post-update.

We have a notion of begin attack and end attack to allow code to drive the
animation system and apply effects after an attack animation has
completed.
This commit is contained in:
Doyle Thai 2016-07-18 22:02:47 +10:00
parent e00ef52f8a
commit fff9e6e5b2
5 changed files with 347 additions and 255 deletions

View File

@ -1,98 +1,236 @@
#include "Dengine/Debug.h"
#include "Dengine/Platform.h"
#include "Dengine/AssetManager.h"
DebugState GLOBAL_debugState;
DebugState GLOBAL_debug;
void debug_init()
{
GLOBAL_debugState.totalMemoryAllocated = 0;
GLOBAL_debugState.callCount = PLATFORM_MEM_ALLOC(debugcallcount_num, i32);
GLOBAL_debug.totalMemoryAllocated = 0;
GLOBAL_debug.callCount = PLATFORM_MEM_ALLOC(debugcallcount_num, i32);
GLOBAL_debugState.numDebugStrings = 0;
GLOBAL_debugState.stringUpdateTimer = 0.0f;
GLOBAL_debugState.stringUpdateRate = 0.15f;
GLOBAL_debug.numDebugStrings = 0;
GLOBAL_debug.stringUpdateTimer = 0.0f;
GLOBAL_debug.stringUpdateRate = 0.15f;
GLOBAL_debugState.stringLineGap = -1;
GLOBAL_debug.stringLineGap = -1;
}
void debug_pushString(char *formatString, void *data, char *dataType)
{
if (GLOBAL_debugState.stringUpdateTimer <= 0)
if (GLOBAL_debug.stringUpdateTimer <= 0)
{
i32 numDebugStrings = GLOBAL_debugState.numDebugStrings;
i32 numDebugStrings = GLOBAL_debug.numDebugStrings;
if (common_strcmp(dataType, "v2") == 0)
{
v2 val = *(CAST(v2 *) data);
snprintf(GLOBAL_debugState.debugStrings[numDebugStrings],
ARRAY_COUNT(GLOBAL_debugState.debugStrings[0]),
snprintf(GLOBAL_debug.debugStrings[numDebugStrings],
ARRAY_COUNT(GLOBAL_debug.debugStrings[0]),
formatString, val.x, val.y);
}
else if (common_strcmp(dataType, "i32") == 0)
{
i32 val = *(CAST(i32 *) data);
snprintf(GLOBAL_debugState.debugStrings[numDebugStrings],
ARRAY_COUNT(GLOBAL_debugState.debugStrings[0]),
snprintf(GLOBAL_debug.debugStrings[numDebugStrings],
ARRAY_COUNT(GLOBAL_debug.debugStrings[0]),
formatString, val);
}
else if (common_strcmp(dataType, "f32") == 0)
{
f32 val = *(CAST(f32 *) data);
snprintf(GLOBAL_debugState.debugStrings[numDebugStrings],
ARRAY_COUNT(GLOBAL_debugState.debugStrings[0]),
snprintf(GLOBAL_debug.debugStrings[numDebugStrings],
ARRAY_COUNT(GLOBAL_debug.debugStrings[0]),
formatString, val);
}
else if (common_strcmp(dataType, "char") == 0)
{
char *val = CAST(char *)data;
snprintf(GLOBAL_debugState.debugStrings[numDebugStrings],
ARRAY_COUNT(GLOBAL_debugState.debugStrings[0]),
snprintf(GLOBAL_debug.debugStrings[numDebugStrings],
ARRAY_COUNT(GLOBAL_debug.debugStrings[0]),
formatString, val);
}
else
{
ASSERT(INVALID_CODE_PATH);
}
GLOBAL_debugState.numDebugStrings++;
GLOBAL_debug.numDebugStrings++;
}
}
void debug_stringUpdateAndRender(Renderer *renderer, Font *font, f32 dt)
{
if (GLOBAL_debugState.stringLineGap == -1)
if (GLOBAL_debug.stringLineGap == -1)
{
GLOBAL_debugState.stringLineGap =
GLOBAL_debug.stringLineGap =
1.1f * asset_getVFontSpacing(font->metrics);
GLOBAL_debugState.initialStringPos =
GLOBAL_debug.initialStringPos =
V2(0.0f,
(renderer->size.y - 1.8f * GLOBAL_debugState.stringLineGap));
GLOBAL_debugState.stringPos = GLOBAL_debugState.initialStringPos;
(renderer->size.y - 1.8f * GLOBAL_debug.stringLineGap));
GLOBAL_debug.stringPos = GLOBAL_debug.initialStringPos;
}
for (i32 i = 0; i < GLOBAL_debugState.numDebugStrings; i++)
for (i32 i = 0; i < GLOBAL_debug.numDebugStrings; i++)
{
f32 rotate = 0;
v4 color = V4(0, 0, 0, 1);
renderer_staticString(renderer, font, GLOBAL_debugState.debugStrings[i],
GLOBAL_debugState.stringPos, rotate, color);
GLOBAL_debugState.stringPos.y -=
(0.9f * GLOBAL_debugState.stringLineGap);
renderer_staticString(renderer, font, GLOBAL_debug.debugStrings[i],
GLOBAL_debug.stringPos, rotate, color);
GLOBAL_debug.stringPos.y -=
(0.9f * GLOBAL_debug.stringLineGap);
}
if (GLOBAL_debugState.stringUpdateTimer <= 0)
if (GLOBAL_debug.stringUpdateTimer <= 0)
{
GLOBAL_debugState.stringUpdateTimer =
GLOBAL_debugState.stringUpdateRate;
GLOBAL_debug.stringUpdateTimer =
GLOBAL_debug.stringUpdateRate;
}
else
{
GLOBAL_debugState.stringUpdateTimer -= dt;
if (GLOBAL_debugState.stringUpdateTimer <= 0)
GLOBAL_debug.stringUpdateTimer -= dt;
if (GLOBAL_debug.stringUpdateTimer <= 0)
{
GLOBAL_debugState.numDebugStrings = 0;
GLOBAL_debug.numDebugStrings = 0;
}
}
GLOBAL_debugState.stringPos = GLOBAL_debugState.initialStringPos;
GLOBAL_debug.stringPos = GLOBAL_debug.initialStringPos;
}
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);
}
for (i32 entityId = 0; entityId < world->maxEntities; entityId++)
{
Entity *const entity = &world->entities[entityId];
/* 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];
snprintf(entityIDStr, ARRAY_COUNT(entityIDStr), "ID: %4d/%d", entityId,
world->maxEntities);
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);
}
}
}
/* Render debug info stack */
DEBUG_PUSH_STRING("Hero Pos: %06.2f, %06.2f", hero->pos, "v2");
DEBUG_PUSH_STRING("Hero dPos: %06.2f, %06.2f", hero->dPos, "v2");
DEBUG_PUSH_STRING("Hero Busy Duration: %05.3f", hero->stats->busyDuration, "f32");
char *heroStateString = debug_entitystate_string(hero->state);
DEBUG_PUSH_STRING("Hero State: %s", *heroStateString, "char");
char *heroQueuedAttackStr =
debug_entityattack_string(hero->stats->queuedAttack);
DEBUG_PUSH_STRING("Hero QueuedAttack: %s", *heroQueuedAttackStr, "char");
DEBUG_PUSH_STRING("FreeEntityIndex: %d", world->freeEntityIndex, "i32");
DEBUG_PUSH_STRING("glDrawArray Calls: %d",
GLOBAL_debug.callCount[debugcallcount_drawArrays],
"i32");
i32 debug_kbAllocated = GLOBAL_debug.totalMemoryAllocated / 1024;
DEBUG_PUSH_STRING("TotalMemoryAllocated: %dkb", debug_kbAllocated, "i32");
debug_stringUpdateAndRender(&state->renderer, font, dt);
debug_clearCallCounter();
}

View File

@ -10,7 +10,7 @@ void platform_memoryFree(void *data, i32 numBytes)
if (data) free(data);
#ifdef DENGINE_DEBUG
GLOBAL_debugState.totalMemoryAllocated -= numBytes;
GLOBAL_debug.totalMemoryAllocated -= numBytes;
#endif
}
@ -20,7 +20,7 @@ void *platform_memoryAlloc(i32 numBytes)
#ifdef DENGINE_DEBUG
if (result)
GLOBAL_debugState.totalMemoryAllocated += numBytes;
GLOBAL_debug.totalMemoryAllocated += numBytes;
#endif
return result;
}

View File

@ -176,8 +176,9 @@ void worldTraveller_gameInit(GameState *state, v2 windowSize)
World *const world = &state->world[i];
world->maxEntities = 16384;
world->entities = PLATFORM_MEM_ALLOC(world->maxEntities, Entity);
world->texType = texlist_terrain;
world->entitiesInBattleIds = PLATFORM_MEM_ALLOC(world->maxEntities, i32);
world->numEntitiesInBattle = 0;
world->texType = texlist_terrain;
world->bounds =
math_getRect(V2(0, 0), v2_scale(worldDimensionInTiles,
CAST(f32) state->tileSize));
@ -387,30 +388,21 @@ INTERNAL void parseInput(GameState *state, const f32 dt)
ddPos = v2_scale(ddPos, 0.70710678118f);
}
// TODO(doyle): Revisit key input with state checking for last ended down
#if 0
if (state->keys[GLFW_KEY_SPACE] && !spaceBarWasDown)
{
if (!(hero->currAnimId == entityanimid_tackle &&
hero->currAnimCyclesCompleted == 0))
{
spaceBarWasDown = TRUE;
setActiveEntityAnim(hero, entityanimid_tackle);
if (hero->direction == direction_east)
{
ddPos.x = 1.0f;
hero->dPos.x += (1.0f * METERS_TO_PIXEL);
}
else
{
ddPos.x = -1.0f;
hero->dPos.x -= (1.0f * METERS_TO_PIXEL);
}
}
}
else if (!state->keys[GLFW_KEY_SPACE])
{
spaceBarWasDown = FALSE;
}
#endif
// NOTE(doyle): Clipping threshold for snapping velocity to 0
f32 epsilon = 0.5f;
@ -524,7 +516,7 @@ INTERNAL void updateEntityAnim(Entity *entity, f32 dt)
}
}
INTERNAL void beginAttack(GameState *state, Entity *attacker)
INTERNAL void beginAttack(Entity *attacker)
{
attacker->state = entitystate_attack;
switch (attacker->stats->queuedAttack)
@ -535,6 +527,12 @@ INTERNAL void beginAttack(GameState *state, Entity *attacker)
attacker->stats->busyDuration = busyDuration;
setActiveEntityAnim(attacker, entityanimid_tackle);
if (attacker->direction == direction_east)
attacker->dPos.x += (1.0f * METERS_TO_PIXEL);
else
attacker->dPos.x -= (1.0f * METERS_TO_PIXEL);
break;
default:
#ifdef DENGINE_DEBUG
@ -545,19 +543,36 @@ INTERNAL void beginAttack(GameState *state, Entity *attacker)
// TODO(doyle): Calculate the battle damage, transition back into battle pose ..
// etc
INTERNAL void endAttack(GameState *state, Entity *attacker)
INTERNAL void endAttack(World *world, Entity *attacker)
{
switch (attacker->stats->queuedAttack)
{
case entityattack_tackle:
if (attacker->direction == direction_east)
attacker->dPos.x -= (1.0f * METERS_TO_PIXEL);
else
attacker->dPos.x += (1.0f * METERS_TO_PIXEL);
break;
default:
#ifdef DENGINE_DEBUG
ASSERT(INVALID_CODE_PATH);
#endif
}
// TODO(doyle): Use attacker stats in battle equations
attacker->state = entitystate_battle;
attacker->stats->actionTimer = attacker->stats->actionRate;
attacker->stats->busyDuration = 0;
setActiveEntityAnim(attacker, entityanimid_battlePose);
Entity *defender =
&state->world->entities[attacker->stats->entityIdToAttack];
Entity *defender = &world->entities[attacker->stats->entityIdToAttack];
defender->stats->health--;
}
// TODO(doyle): Exposed because of debug .. rework debug system so it we don't
// need to expose any game API to it.
INTERNAL v4 createCameraBounds(World *world, v2 size)
{
v4 result = math_getRect(world->cameraPos, size);
@ -581,70 +596,105 @@ INTERNAL v4 createCameraBounds(World *world, v2 size)
return result;
}
INTERNAL void updateEntity(GameState *state, Entity *entity, f32 dt)
INTERNAL void updateEntityAndRender(Renderer *renderer, World *world, f32 dt)
{
World *const world = &state->world[state->currWorldIndex];
Entity *hero = &world->entities[world->heroIndex];
if (entity->state == entitystate_idle)
for (i32 entityId = 0; entityId < world->freeEntityIndex; entityId++)
{
Entity *const entity = &world->entities[entityId];
Entity *hero = &world->entities[world->heroIndex];
if (entity->type == entitytype_mob)
{
f32 distance = v2_magnitude(hero->pos, entity->pos);
// TODO(doyle): Currently calculated in pixels, how about meaningful
// game units?
f32 distance = v2_magnitude(hero->pos, entity->pos);
f32 battleThreshold = 500.0f;
if (distance <= battleThreshold)
{
entity->state = entitystate_battle;
}
else
{
entity->stats->actionTimer = entity->stats->actionRate;
entity->stats->queuedAttack = entityattack_invalid;
}
}
}
if ((entity->state == entitystate_battle ||
entity->state == entitystate_attack) &&
entity->type == entitytype_hero)
{
EntityStats *stats = entity->stats;
if (stats->health > 0)
{
if (entity->state == entitystate_battle)
{
if (stats->actionTimer > 0)
stats->actionTimer -= dt * stats->actionSpdMul;
if (stats->actionTimer < 0)
if (!world->entitiesInBattleIds[entityId])
{
stats->actionTimer = 0;
if (stats->queuedAttack == entityattack_invalid)
stats->queuedAttack = entityattack_tackle;
beginAttack(state, entity);
world->entitiesInBattleIds[entityId] = TRUE;
world->numEntitiesInBattle++;
}
}
else
{
stats->busyDuration -= dt;
if (stats->busyDuration <= 0)
endAttack(state, entity);
if (world->entitiesInBattleIds[entityId])
{
world->entitiesInBattleIds[entityId] = FALSE;
world->numEntitiesInBattle--;
}
entity->state = entitystate_idle;
entity->stats->actionTimer = entity->stats->actionRate;
entity->stats->queuedAttack = entityattack_invalid;
}
}
if ((entity->state == entitystate_battle ||
entity->state == entitystate_attack) &&
entity->type == entitytype_hero)
{
EntityStats *stats = entity->stats;
if (stats->health > 0)
{
if (entity->state == entitystate_battle)
{
if (stats->actionTimer > 0)
stats->actionTimer -= dt * stats->actionSpdMul;
if (stats->actionTimer < 0)
{
stats->actionTimer = 0;
if (stats->queuedAttack == entityattack_invalid)
stats->queuedAttack = entityattack_tackle;
beginAttack(entity);
}
}
else
{
stats->busyDuration -= dt;
if (stats->busyDuration <= 0)
endAttack(world, entity);
}
}
else
{
// TODO(doyle): Generalise for all entities
hero->stats->entityIdToAttack = -1;
hero->state = entitystate_idle;
entity->state = entitystate_dead;
}
}
if (world->numEntitiesInBattle > 0)
{
if (hero->state == entitystate_idle)
hero->state = entitystate_battle;
if (hero->stats->entityIdToAttack == -1)
hero->stats->entityIdToAttack = entityId;
}
else
{
// TODO(doyle): Generalise for all entities
if (hero->state == entitystate_battle)
{
hero->state = entitystate_idle;
setActiveEntityAnim(hero, entityanimid_idle);
}
hero->stats->entityIdToAttack = -1;
hero->state = entitystate_idle;
entity->state = entitystate_dead;
hero->stats->actionTimer = hero->stats->actionRate;
hero->stats->busyDuration = 0;
}
}
updateEntityAnim(entity, dt);
updateEntityAnim(entity, dt);
/* Calculate region to render */
v4 cameraBounds = createCameraBounds(world, renderer->size);
renderer_entity(renderer, cameraBounds, entity, 0, V4(1, 1, 1, 1));
}
}
void worldTraveller_gameUpdateAndRender(GameState *state, const f32 dt)
@ -657,124 +707,12 @@ void worldTraveller_gameUpdateAndRender(GameState *state, const f32 dt)
Renderer *renderer = &state->renderer;
World *const world = &state->world[state->currWorldIndex];
Entity *hero = &world->entities[world->heroIndex];
#ifdef DENGINE_DEBUG
Font *font = &assetManager->font;
#endif
/* Recalculate rendering bounds */
v4 cameraBounds = createCameraBounds(world, renderer->size);
/* Update and render entity loop */
ASSERT(world->freeEntityIndex < world->maxEntities);
for (i32 entityId = 0; entityId < world->freeEntityIndex; entityId++)
{
Entity *const entity = &world->entities[entityId];
updateEntity(state, entity, dt);
if (entity->state == entitystate_battle)
{
if (hero->state == entitystate_idle)
hero->state = entitystate_battle;
if (hero->stats->entityIdToAttack == -1)
hero->stats->entityIdToAttack = entityId;
#if 0
#ifdef DENGINE_DEBUG
Texture *emptyTex =
asset_getTexture(assetManager, texlist_empty);
v2 heroCenter = v2_add(hero->pos, v2_scale(hero->size, 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));
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);
#endif
#endif
}
f32 rotate = 0.0f;
renderer_entity(&state->renderer, cameraBounds, entity, rotate,
V4(1, 1, 1, 1));
#ifdef DENGINE_DEBUG
/* 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_debugState.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_debugState.stringLineGap;
char entityIDStr[32];
snprintf(entityIDStr, ARRAY_COUNT(entityIDStr), "ID: %4d/%d", entityId,
world->maxEntities);
renderer_string(&state->renderer, cameraBounds, font, entityIDStr,
strPos, 0, color);
if (entity->stats)
{
strPos.y -= GLOBAL_debugState.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_debugState.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);
}
}
#endif
}
updateEntityAndRender(renderer, world, dt);
/* Draw ui */
TexAtlas *heroAtlas = asset_getTextureAtlas(assetManager, texlist_hero);
v4 heroAvatarTexRect = heroAtlas->texRect[herorects_head];
v2 heroAvatarSize = math_getRectSize(heroAvatarTexRect);
@ -793,46 +731,6 @@ void worldTraveller_gameUpdateAndRender(GameState *state, const f32 dt)
V4(0, 0, 1, 1));
#ifdef DENGINE_DEBUG
/* Render debug info stack */
DEBUG_PUSH_STRING("Hero Pos: %06.2f, %06.2f", hero->pos, "v2");
DEBUG_PUSH_STRING("Hero dPos: %06.2f, %06.2f", hero->dPos, "v2");
DEBUG_PUSH_STRING("Hero Busy Duration: %05.3f", hero->stats->busyDuration, "f32");
char *stateString;
switch(hero->state)
{
case entitystate_idle:
stateString = "Idle";
break;
case entitystate_battle:
stateString = "Battle";
break;
case entitystate_attack:
stateString = "Attack";
break;
case entitystate_dead:
stateString = "Dead";
break;
case entitystate_count:
stateString = "Invalid (Count)";
break;
case entitystate_invalid:
stateString = "Invalid";
break;
default:
stateString = "Unknown";
}
DEBUG_PUSH_STRING("Hero State: %s", *stateString, "char");
DEBUG_PUSH_STRING("FreeEntityIndex: %d", world->freeEntityIndex, "i32");
DEBUG_PUSH_STRING("glDrawArray Calls: %d",
GLOBAL_debugState.callCount[debugcallcount_drawArrays],
"i32");
i32 debug_kbAllocated = GLOBAL_debugState.totalMemoryAllocated / 1024;
DEBUG_PUSH_STRING("TotalMemoryAllocated: %dkb", debug_kbAllocated, "i32");
debug_stringUpdateAndRender(&state->renderer, font, dt);
debug_clearCallCounter();
debug_drawUi(state, dt);
#endif
}

View File

@ -5,6 +5,9 @@
#include "Dengine/Common.h"
#include "Dengine/Math.h"
#include "Dengine/Renderer.h"
#include "Dengine/Entity.h"
#include "WorldTraveller/WorldTraveller.h"
#define INVALID_CODE_PATH TRUE
#define DEBUG_PUSH_STRING(formatString, data, type) \
@ -33,22 +36,73 @@ typedef struct DebugState
f32 stringLineGap;
} DebugState;
extern DebugState GLOBAL_debugState;
extern DebugState GLOBAL_debug;
inline void debug_callCountIncrement(i32 id)
{
ASSERT(id < debugcallcount_num);
GLOBAL_debugState.callCount[id]++;
GLOBAL_debug.callCount[id]++;
}
inline void debug_clearCallCounter()
{
for (i32 i = 0; i < debugcallcount_num; i++)
GLOBAL_debugState.callCount[i] = 0;
GLOBAL_debug.callCount[i] = 0;
}
inline char *debug_entitystate_string(i32 val)
{
char *string;
switch(val)
{
case entitystate_idle:
string = "EntityState_Idle";
break;
case entitystate_battle:
string = "EntityState_Battle";
break;
case entitystate_attack:
string = "EntityState_Attack";
break;
case entitystate_dead:
string = "EntityState_Dead";
break;
case entitystate_count:
string = "EntityState_Count (Error!)";
break;
case entitystate_invalid:
string = "EntityState_Invalid (Error!)";
break;
default:
string = "EntityState Unknown (NOT DEFINED)";
}
return string;
}
inline char *debug_entityattack_string(i32 val)
{
char *string;
switch(val)
{
case entityattack_tackle:
string = "EntityAttack_Tackle";
break;
case entityattack_count:
string = "EntityAttack_Count (Error!)";
break;
case entityattack_invalid:
string = "EntityAttack_Invalid";
break;
default:
string = "EntityAttack Unknown (NOT DEFINED)";
}
return string;
}
void debug_init();
void debug_pushString(char *formatString, void *data, char *dataType);
void debug_stringUpdateAndRender(Renderer *renderer, Font *font, f32 dt);
void debug_drawUi(GameState *state, f32 dt);
#endif

View File

@ -16,6 +16,8 @@ typedef struct World
{
Entity *entities;
i32 maxEntities;
b32 *entitiesInBattleIds;
i32 numEntitiesInBattle;
enum TexList texType;