From fff9e6e5b233d5a215d1accecc612109cd198ce8 Mon Sep 17 00:00:00 2001 From: Doyle Thai Date: Mon, 18 Jul 2016 22:02:47 +1000 Subject: [PATCH] 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. --- src/Debug.c | 208 ++++++++++--- src/Platform.c | 4 +- src/WorldTraveller.c | 328 +++++++------------- src/include/Dengine/Debug.h | 60 +++- src/include/WorldTraveller/WorldTraveller.h | 2 + 5 files changed, 347 insertions(+), 255 deletions(-) diff --git a/src/Debug.c b/src/Debug.c index 584a5be..5678b03 100644 --- a/src/Debug.c +++ b/src/Debug.c @@ -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(); +} diff --git a/src/Platform.c b/src/Platform.c index acad980..5a2cbac 100644 --- a/src/Platform.c +++ b/src/Platform.c @@ -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; } diff --git a/src/WorldTraveller.c b/src/WorldTraveller.c index edb6195..a19d0df 100644 --- a/src/WorldTraveller.c +++ b/src/WorldTraveller.c @@ -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 } diff --git a/src/include/Dengine/Debug.h b/src/include/Dengine/Debug.h index b0f3714..0793acc 100644 --- a/src/include/Dengine/Debug.h +++ b/src/include/Dengine/Debug.h @@ -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 diff --git a/src/include/WorldTraveller/WorldTraveller.h b/src/include/WorldTraveller/WorldTraveller.h index 44cd3d9..4537f56 100644 --- a/src/include/WorldTraveller/WorldTraveller.h +++ b/src/include/WorldTraveller/WorldTraveller.h @@ -16,6 +16,8 @@ typedef struct World { Entity *entities; i32 maxEntities; + b32 *entitiesInBattleIds; + i32 numEntitiesInBattle; enum TexList texType;