Switch developing game to asteroids, start project

Switch to something of smaller scope in aim to be able to finish a project from
start to finish. Also allow refreshed eyes to review the existing API and see
what can be improved on after taking a short break from the project.
This commit is contained in:
Doyle Thai 2016-11-09 22:36:41 +11:00
parent ed6b961b61
commit 4795fe1cb1
19 changed files with 358 additions and 3160 deletions

View File

@ -121,18 +121,17 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="src\AssetManager.c" /> <ClCompile Include="src\AssetManager.c" />
<ClCompile Include="src\Asteroid.c" />
<ClCompile Include="src\Audio.c" /> <ClCompile Include="src\Audio.c" />
<ClCompile Include="src\Common.c" /> <ClCompile Include="src\Common.c" />
<ClCompile Include="src\Debug.c" /> <ClCompile Include="src\Debug.c" />
<ClCompile Include="src\dengine.c" /> <ClCompile Include="src\dengine.c" />
<ClCompile Include="src\Entity.c" />
<ClCompile Include="src\MemoryArena.c" /> <ClCompile Include="src\MemoryArena.c" />
<ClCompile Include="src\Platform.c" /> <ClCompile Include="src\Platform.c" />
<ClCompile Include="src\Renderer.c" /> <ClCompile Include="src\Renderer.c" />
<ClCompile Include="src\Shader.c" /> <ClCompile Include="src\Shader.c" />
<ClCompile Include="src\String.c" /> <ClCompile Include="src\String.c" />
<ClCompile Include="src\UserInterface.c" /> <ClCompile Include="src\UserInterface.c" />
<ClCompile Include="src\WorldTraveller.c" />
<ClCompile Include="src\Texture.c" /> <ClCompile Include="src\Texture.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -143,14 +142,15 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="src\include\Dengine\Assets.h" /> <ClInclude Include="src\include\Dengine\Assets.h" />
<ClInclude Include="src\include\Dengine\Asteroid.h" />
<ClInclude Include="src\include\Dengine\Audio.h" /> <ClInclude Include="src\include\Dengine\Audio.h" />
<ClInclude Include="src\include\Dengine\Debug.h" /> <ClInclude Include="src\include\Dengine\Debug.h" />
<ClInclude Include="src\include\Dengine\Entity.h" />
<ClInclude Include="src\include\Dengine\MemoryArena.h" /> <ClInclude Include="src\include\Dengine\MemoryArena.h" />
<ClInclude Include="src\include\Dengine\Platform.h" /> <ClInclude Include="src\include\Dengine\Platform.h" />
<ClInclude Include="src\include\Dengine\AssetManager.h" /> <ClInclude Include="src\include\Dengine\AssetManager.h" />
<ClInclude Include="src\include\Dengine\Common.h" /> <ClInclude Include="src\include\Dengine\Common.h" />
<ClInclude Include="src\include\Breakout\Game.h" /> <ClInclude Include="src\include\Breakout\Game.h" />
<ClInclude Include="src\include\Dengine\Entity.h" />
<ClInclude Include="src\include\Dengine\Math.h" /> <ClInclude Include="src\include\Dengine\Math.h" />
<ClInclude Include="src\include\Dengine\OpenGL.h" /> <ClInclude Include="src\include\Dengine\OpenGL.h" />
<ClInclude Include="src\include\Dengine\Renderer.h" /> <ClInclude Include="src\include\Dengine\Renderer.h" />

View File

@ -15,9 +15,6 @@
</Filter> </Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="src\WorldTraveller.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\Texture.c"> <ClCompile Include="src\Texture.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
@ -42,9 +39,6 @@
<ClCompile Include="src\Audio.c"> <ClCompile Include="src\Audio.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\Entity.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\dengine.c"> <ClCompile Include="src\dengine.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
@ -57,6 +51,9 @@
<ClCompile Include="src\MemoryArena.c"> <ClCompile Include="src\MemoryArena.c">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\Asteroid.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="data\shaders\default.vert.glsl" /> <None Include="data\shaders\default.vert.glsl" />
@ -86,9 +83,6 @@
<ClInclude Include="src\include\Dengine\Renderer.h"> <ClInclude Include="src\include\Dengine\Renderer.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="src\include\Dengine\Entity.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\include\Dengine\Math.h"> <ClInclude Include="src\include\Dengine\Math.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
@ -116,5 +110,11 @@
<ClInclude Include="src\include\Dengine\String.h"> <ClInclude Include="src\include\Dengine\String.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="src\include\Dengine\Asteroid.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\include\Dengine\Entity.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>

241
src/Asteroid.c Normal file
View File

@ -0,0 +1,241 @@
#include "Dengine/Asteroid.h"
#include "Dengine/Debug.h"
void initAssetManager(GameState *state)
{
AssetManager *assetManager = &state->assetManager;
MemoryArena_ *arena = &state->persistentArena;
i32 audioEntries = 32;
assetManager->audio.size = audioEntries;
assetManager->audio.entries =
memory_pushBytes(arena, audioEntries * sizeof(HashTableEntry));
i32 texAtlasEntries = 8;
assetManager->texAtlas.size = texAtlasEntries;
assetManager->texAtlas.entries =
memory_pushBytes(arena, texAtlasEntries * sizeof(HashTableEntry));
i32 texEntries = 32;
assetManager->textures.size = texEntries;
assetManager->textures.entries =
memory_pushBytes(arena, texEntries * sizeof(HashTableEntry));
i32 animEntries = 1024;
assetManager->anims.size = animEntries;
assetManager->anims.entries =
memory_pushBytes(arena, animEntries * sizeof(HashTableEntry));
/* Create empty 1x1 4bpp black texture */
u32 bitmap = (0xFF << 24) | (0xFF << 16) | (0xFF << 8) | (0xFF << 0);
Texture *tex = asset_getFreeTexSlot(assetManager, arena, "nullTex");
*tex = texture_gen(1, 1, 4, CAST(u8 *)(&bitmap));
/* Load shaders */
asset_loadShaderFiles(assetManager, arena, "data/shaders/sprite.vert.glsl",
"data/shaders/sprite.frag.glsl",
shaderlist_sprite);
i32 result =
asset_loadTTFont(assetManager, arena, "C:/Windows/Fonts/Arialbd.ttf");
if (result) {
ASSERT(TRUE);
}
}
void initRenderer(GameState *state, v2 windowSize) {
AssetManager *assetManager = &state->assetManager;
Renderer *renderer = &state->renderer;
renderer->size = windowSize;
// NOTE(doyle): Value to map a screen coordinate to NDC coordinate
renderer->vertexNdcFactor =
V2(1.0f / renderer->size.w, 1.0f / renderer->size.h);
renderer->shader = asset_getShader(assetManager, shaderlist_sprite);
shader_use(renderer->shader);
const mat4 projection =
mat4_ortho(0.0f, renderer->size.w, 0.0f, renderer->size.h, 0.0f, 1.0f);
shader_uniformSetMat4fv(renderer->shader, "projection", projection);
GL_CHECK_ERROR();
/* Create buffers */
glGenVertexArrays(1, &renderer->vao);
glGenBuffers(1, &renderer->vbo);
GL_CHECK_ERROR();
/* Bind buffers */
glBindBuffer(GL_ARRAY_BUFFER, renderer->vbo);
glBindVertexArray(renderer->vao);
/* Configure VAO */
u32 numVertexElements = 4;
u32 stride = sizeof(Vertex);
glVertexAttribPointer(0, numVertexElements, GL_FLOAT, GL_FALSE, stride,
(GLvoid *)0);
glEnableVertexAttribArray(0);
GL_CHECK_ERROR();
/* Unbind */
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
GL_CHECK_ERROR();
// TODO(doyle): Lazy allocate render group capacity
renderer->groupCapacity = 4096;
for (i32 i = 0; i < ARRAY_COUNT(renderer->groups); i++)
{
renderer->groups[i].vertexList = memory_pushBytes(
&state->persistentArena, renderer->groupCapacity * sizeof(Vertex));
}
}
enum ReadKeyType
{
readkeytype_oneShot,
readkeytype_delayedRepeat,
readkeytype_repeat,
readkeytype_count,
};
#define KEY_DELAY_NONE 0.0f
INTERNAL b32 getKeyStatus(KeyState *key, enum ReadKeyType readType,
f32 delayInterval, f32 dt)
{
if (!key->endedDown) return FALSE;
switch(readType)
{
case readkeytype_oneShot:
{
if (key->newHalfTransitionCount > key->oldHalfTransitionCount)
return TRUE;
break;
}
case readkeytype_repeat:
case readkeytype_delayedRepeat:
{
if (key->newHalfTransitionCount > key->oldHalfTransitionCount)
{
if (readType == readkeytype_delayedRepeat)
{
// TODO(doyle): Let user set arbitrary delay after initial input
key->delayInterval = 2 * delayInterval;
}
else
{
key->delayInterval = delayInterval;
}
return TRUE;
}
else if (key->delayInterval <= 0.0f)
{
key->delayInterval = delayInterval;
return TRUE;
}
else
{
key->delayInterval -= dt;
}
break;
}
default:
#ifdef DENGINE_DEBUG
DEBUG_LOG("getKeyStatus() error: Invalid ReadKeyType enum");
ASSERT(INVALID_CODE_PATH);
#endif
break;
}
return FALSE;
}
void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
v2 windowSize, f32 dt)
{
if (!state->init) {
memory_arenaInit(&state->persistentArena, memory->persistent,
memory->persistentSize);
memory_arenaInit(&state->transientArena, memory->transient,
memory->transientSize);
initAssetManager(state);
initRenderer(state, windowSize);
{ // Init ship entity
Entity *ship = &state->entityList[state->entityIndex++];
ship->id = 0;
ship->pos = V2(100.0f, 100.0f);
ship->hitbox = V2(100.0f, 100.0f);
ship->size = V2(100.0f, 100.0f);
ship->scale = 1;
ship->type = entitytype_ship;
ship->direction = direction_null;
ship->tex = asset_getTex(&state->assetManager, "nullTex");
ship->collides = FALSE;
}
state->camera.pos = V2(0, 0);
state->camera.size = state->renderer.size;
state->init = TRUE;
}
{
KeyState *keys = state->input.keys;
for (enum KeyCode code = 0; code < keycode_count; code++)
{
KeyState *keyState = &keys[code];
u32 halfTransitionCount = keyState->newHalfTransitionCount -
keyState->oldHalfTransitionCount;
if (halfTransitionCount > 0)
{
b32 transitionCountIsOdd = ((halfTransitionCount & 1) == 1);
if (transitionCountIsOdd)
{
if (keyState->endedDown) keyState->endedDown = FALSE;
else keyState->endedDown = TRUE;
}
keyState->oldHalfTransitionCount =
keyState->newHalfTransitionCount;
}
}
}
for (i32 i = 0; i < state->entityIndex; i++)
{
Entity *entity = &state->entityList[i];
ASSERT(entity->type != entitytype_invalid);
if (entity->type == entitytype_ship) {
{ // Parse input
if (getKeyStatus(&state->input.keys[keycode_up],
readkeytype_repeat, 0.0f, dt))
{
entity->pos.y += 10.0f;
}
if (getKeyStatus(&state->input.keys[keycode_down],
readkeytype_repeat, 0.0f, dt))
{
entity->pos.y -= 10.0f;
}
}
}
renderer_entity(&state->renderer, state->camera, entity, V2(0, 0), 0,
V4(1.0f, 1.0f, 1.0f, 1.0f));
}
renderer_renderGroups(&state->renderer);
}

View File

@ -1,10 +1,9 @@
#include "Dengine/Debug.h" #include "Dengine/Debug.h"
#include "Dengine/AssetManager.h" #include "Dengine/AssetManager.h"
#include "Dengine/Entity.h"
#include "Dengine/MemoryArena.h" #include "Dengine/MemoryArena.h"
#include "Dengine/Platform.h" #include "Dengine/Platform.h"
#include "Dengine/Renderer.h" #include "Dengine/Renderer.h"
#include "Dengine/WorldTraveller.h" #include "Dengine/Asteroid.h"
typedef struct DebugState typedef struct DebugState
{ {
@ -29,52 +28,6 @@ typedef struct DebugState
GLOBAL_VAR DebugState GLOBAL_debug; GLOBAL_VAR DebugState GLOBAL_debug;
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_count:
string = "EntityAttack_Count (Error!)";
break;
case entityattack_invalid:
string = "EntityAttack_Invalid";
break;
default:
string = "EntityAttack Unknown (NOT DEFINED)";
}
return string;
}
void debug_init(MemoryArena_ *arena, v2 windowSize, Font font) void debug_init(MemoryArena_ *arena, v2 windowSize, Font font)
{ {
GLOBAL_debug.font = font; GLOBAL_debug.font = font;
@ -317,238 +270,5 @@ INTERNAL void renderConsole(Renderer *renderer, MemoryArena_ *arena)
void debug_drawUi(GameState *state, f32 dt) 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[entity_getIndex(world, world->heroId)];
MemoryArena_ *transientArena = &state->transientArena;
// TODO(doyle): Dumb copy function from game so we don't expose api
Rect camera = {world->cameraPos, renderer->size};
// NOTE(doyle): Lock camera if it passes the bounds of the world
if (camera.pos.x <= world->bounds.x)
camera.pos.x = world->bounds.x;
// TODO(doyle): Allow Y panning when we need it
f32 cameraTopBoundInPixels = camera.pos.y + camera.size.h;
if (cameraTopBoundInPixels >= world->bounds.w)
camera.pos.y = (world->bounds.w - camera.size.h);
f32 cameraRightBoundInPixels = camera.pos.x + camera.size.w;
if (cameraRightBoundInPixels >= world->bounds.z)
camera.pos.x = (world->bounds.z - camera.size.w);
if (camera.pos.y <= world->bounds.y) camera.pos.y = world->bounds.y;
Font *font = &GLOBAL_debug.font;
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, transientArena, font, battleStr,
strPos, V2(0, 0), 0, color);
}
for (i32 i = 0; i < world->freeEntityIndex; i++)
{
Entity *const entity = &world->entities[i];
if (entity->state == entitystate_dead) continue;
/* 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->hitbox);
i32 indexOfLowerAInMetrics = 'a' - CAST(i32) font->codepointRange.x;
strPos.y += font->charMetrics[indexOfLowerAInMetrics].offset.y;
renderer_string(&state->renderer, transientArena, camera, font,
debugString, strPos, V2(0, 0), 0, color);
f32 stringLineGap = 1.1f * font->verticalSpacing;
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, transientArena, camera, font,
entityPosStr, strPos, V2(0, 0), 0, color);
strPos.y -= GLOBAL_debug.stringLineGap;
char entityIDStr[32];
snprintf(entityIDStr, ARRAY_COUNT(entityIDStr), "ID: %4d/%d", entity->id,
world->uniqueIdAccumulator-1);
renderer_string(&state->renderer, transientArena, camera, font,
entityIDStr, strPos, V2(0, 0), 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, transientArena, camera,
font, entityHealth, strPos, V2(0, 0), 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, transientArena, camera,
font, entityTimer, strPos, V2(0, 0), 0, color);
strPos.y -= GLOBAL_debug.stringLineGap;
char entityIdTarget[32];
snprintf(entityIdTarget, ARRAY_COUNT(entityIdTarget),
"Targetting ID: %d", entity->stats->entityIdToAttack);
renderer_string(&state->renderer, transientArena, camera,
font, entityIdTarget, strPos, V2(0, 0), 0, color);
}
strPos.y -= GLOBAL_debug.stringLineGap;
char *entityStateStr = debug_entitystate_string(entity->state);
renderer_string(&state->renderer, transientArena, camera, font,
entityStateStr, strPos, V2(0, 0), 0, color);
if (entity->audioRenderer)
{
strPos.y -= GLOBAL_debug.stringLineGap;
char entityAudioSourceIndex[32];
snprintf(entityAudioSourceIndex,
ARRAY_COUNT(entityAudioSourceIndex),
"AudioSource Index: %d",
entity->audioRenderer->sourceIndex);
renderer_string(&state->renderer, transientArena, camera,
font, entityAudioSourceIndex, strPos, V2(0, 0),
0, color);
}
}
}
/* Render debug info stack */
DEBUG_PUSH_STRING("== Controls ==");
DEBUG_PUSH_STRING(" [: Spawn a mob");
DEBUG_PUSH_STRING("<TAB>: Switch UI element");
DEBUG_PUSH_STRING("<ESC>: Close program");
DEBUG_PUSH_STRING("");
DEBUG_PUSH_STRING("== Config == ");
DEBUG_PUSH_VAR("Toggle World Audio: %d", state->config.playWorldAudio,
"i32");
DEBUG_PUSH_VAR("Toggle Debug Display: %d", state->config.showDebugDisplay,
"i32");
DEBUG_PUSH_STRING("");
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");
char *heroStateString = debug_entitystate_string(hero->state);
DEBUG_PUSH_VAR("Hero State: %s", *heroStateString, "char");
char *heroQueuedAttackStr =
debug_entityattack_string(hero->stats->queuedAttack);
DEBUG_PUSH_VAR("Hero QueuedAttack: %s", *heroQueuedAttackStr, "char");
DEBUG_PUSH_STRING("");
DEBUG_PUSH_STRING("== State Properties == ");
DEBUG_PUSH_VAR("FreeEntityIndex: %d", world->freeEntityIndex, "i32");
DEBUG_PUSH_VAR("GLDrawArray Calls: %d",
GLOBAL_debug.callCount[debugcount_drawArrays], "i32");
DEBUG_PUSH_VAR("PlatformMemAlloc Calls: %d",
GLOBAL_debug.callCount[debugcount_platformMemAlloc], "i32");
DEBUG_PUSH_VAR("PlatformMemFree Calls: %d",
GLOBAL_debug.callCount[debugcount_platformMemFree], "i32");
i32 vertexesUsed = GLOBAL_debug.callCount[debugcount_numVertex];
i32 vertexesAvail =
(ARRAY_COUNT(state->renderer.groups) * state->renderer.groupCapacity);
i32 vertexesLeft = vertexesAvail - vertexesUsed;
v2 vertexData = V2i(vertexesUsed, vertexesAvail);
DEBUG_PUSH_VAR("Vertexes Rendered: %1.0f/%1.0f", vertexData, "v2");
DEBUG_PUSH_VAR("Vertexes Left: %d", vertexesLeft, "i32");
i32 groupsUsed = GLOBAL_debug.callCount[debugcount_renderGroups];
i32 groupsAvail = ARRAY_COUNT(state->renderer.groups);
v2 groupData = V2i(groupsUsed, groupsAvail);
DEBUG_PUSH_VAR("Render Groups Used: %1.0f/%1.0f", groupData, "v2");
DEBUG_PUSH_VAR("Mouse Pos: %06.2f, %06.2f", state->input.mouseP, "v2");
/*
*****************
* MEMORY DISPLAY
*****************
*/
i32 debug_bAllocated = transientArena->used;
i32 debug_kbAllocated = debug_bAllocated / 1024;
i32 debug_mbAllocated = debug_kbAllocated / 1024;
DEBUG_PUSH_VAR("TransientArena Used: %db", debug_bAllocated, "i32");
DEBUG_PUSH_VAR("TransientArena Used: %dkb", debug_kbAllocated, "i32");
DEBUG_PUSH_VAR("TransientArena Used: %dmb", debug_mbAllocated, "i32");
DEBUG_PUSH_STRING("");
debug_bAllocated = state->arena_.used;
debug_kbAllocated = debug_bAllocated / 1024;
debug_mbAllocated = debug_kbAllocated / 1024;
DEBUG_PUSH_VAR("PersistentArena Used: %db", debug_bAllocated, "i32");
DEBUG_PUSH_VAR("PersistentArena Used: %dkb", debug_kbAllocated, "i32");
DEBUG_PUSH_VAR("PersistentArena Used: %dmb", debug_mbAllocated, "i32");
DEBUG_PUSH_STRING("");
AudioManager *audioManager = &state->audioManager;
DEBUG_PUSH_STRING("== Audio System ==");
for (i32 i = 0; i < ARRAY_COUNT(audioManager->sourceList); i++)
{
if (audioManager->sourceList[i].isFree) continue;
v3 tmp = V3i(i, audioManager->sourceList[i].id,
audioManager->sourceList[i].isFree);
DEBUG_PUSH_VAR("Source ID[%02.0f].id[%02.0f].isFree: %1.0f", tmp, "v3");
}
DEBUG_PUSH_STRING("");
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-");
}
updateAndRenderDebugStack(&state->renderer, transientArena, dt);
renderConsole(&state->renderer, transientArena);
debug_clearCounter(); debug_clearCounter();
} }

View File

@ -1,12 +1,10 @@
#include "Dengine/Entity.h" #include "Dengine/Entity.h"
#include "Dengine/AssetManager.h" #include "Dengine/AssetManager.h"
#include "Dengine/Debug.h" #include "Dengine/Debug.h"
#include "Dengine/MemoryArena.h"
#include "Dengine/WorldTraveller.h"
SubTexture entity_getActiveSubTexture(Entity *const entity) SubTexture entity_getActiveSubTexture(Entity *const entity)
{ {
EntityAnim *entityAnim = &entity->animList[entity->currAnimId]; EntityAnim *entityAnim = &entity->animList[entity->animListIndex];
Animation *anim = entityAnim->anim; Animation *anim = entityAnim->anim;
char *frameName = anim->frameList[entityAnim->currFrame]; char *frameName = anim->frameList[entityAnim->currFrame];
@ -14,11 +12,10 @@ SubTexture entity_getActiveSubTexture(Entity *const entity)
return result; return result;
} }
void entity_setActiveAnim(EventQueue *eventQueue, Entity *const entity, void entity_setActiveAnim(Entity *const entity, const char *const animName)
const char *const animName)
{ {
/* Reset current anim data */ /* Reset current anim data */
EntityAnim *currEntityAnim = &entity->animList[entity->currAnimId]; EntityAnim *currEntityAnim = &entity->animList[entity->animListIndex];
currEntityAnim->currDuration = currEntityAnim->anim->frameDuration; currEntityAnim->currDuration = currEntityAnim->anim->frameDuration;
currEntityAnim->currFrame = 0; currEntityAnim->currFrame = 0;
currEntityAnim->timesCompleted = 0; currEntityAnim->timesCompleted = 0;
@ -32,14 +29,11 @@ void entity_setActiveAnim(EventQueue *eventQueue, Entity *const entity,
// TODO(doyle): Linear search, but not a problem if list is small // TODO(doyle): Linear search, but not a problem if list is small
if (common_strcmp(anim->key, animName) == 0) if (common_strcmp(anim->key, animName) == 0)
{ {
entity->currAnimId = i; entity->animListIndex = i;
EntityAnim *newEntityAnim = &entity->animList[i]; EntityAnim *newEntityAnim = &entity->animList[i];
newEntityAnim->currDuration = newEntityAnim->currDuration =
newEntityAnim->anim->frameDuration; newEntityAnim->anim->frameDuration;
newEntityAnim->currFrame = 0; newEntityAnim->currFrame = 0;
worldTraveller_registerEvent(eventQueue, eventtype_start_anim,
newEntityAnim);
return; return;
} }
} }
@ -48,13 +42,12 @@ void entity_setActiveAnim(EventQueue *eventQueue, Entity *const entity,
DEBUG_LOG("Entity does not have access to desired anim"); DEBUG_LOG("Entity does not have access to desired anim");
} }
void entity_updateAnim(EventQueue *eventQueue, Entity *const entity, void entity_updateAnim(Entity *const entity, const f32 dt)
const f32 dt)
{ {
if (!entity->tex) if (!entity->tex)
return; return;
EntityAnim *currEntityAnim = &entity->animList[entity->currAnimId]; EntityAnim *currEntityAnim = &entity->animList[entity->animListIndex];
Animation *anim = currEntityAnim->anim; Animation *anim = currEntityAnim->anim;
currEntityAnim->currDuration -= dt; currEntityAnim->currDuration -= dt;
@ -64,30 +57,15 @@ void entity_updateAnim(EventQueue *eventQueue, Entity *const entity,
currEntityAnim->currFrame = currEntityAnim->currFrame % anim->numFrames; currEntityAnim->currFrame = currEntityAnim->currFrame % anim->numFrames;
if (currEntityAnim->currFrame == 0) if (currEntityAnim->currFrame == 0)
{ {
worldTraveller_registerEvent(eventQueue, eventtype_end_anim,
currEntityAnim);
currEntityAnim->timesCompleted++; currEntityAnim->timesCompleted++;
} }
currEntityAnim->currDuration = anim->frameDuration; currEntityAnim->currDuration = anim->frameDuration;
} }
// NOTE(doyle): If humanoid entity, let animation dictate render size which char *frameName = anim->frameList[currEntityAnim->currFrame];
// may exceed the hitbox size of the entity SubTexture texRect = asset_getAtlasSubTex(anim->atlas, frameName);
switch (entity->type) entity->size = v2_scale(texRect.rect.size, entity->scale);
{
case entitytype_hero:
case entitytype_mob:
case entitytype_npc:
case entitytype_weapon:
case entitytype_projectile:
char *frameName = anim->frameList[currEntityAnim->currFrame];
SubTexture texRect =
asset_getAtlasSubTex(anim->atlas, frameName);
entity->size = v2_scale(texRect.rect.size, entity->scale);
default:
break;
}
} }
void entity_addAnim(AssetManager *const assetManager, Entity *const entity, void entity_addAnim(AssetManager *const assetManager, Entity *const entity,
@ -108,127 +86,3 @@ void entity_addAnim(AssetManager *const assetManager, Entity *const entity,
DEBUG_LOG("No more free entity animation slots"); DEBUG_LOG("No more free entity animation slots");
} }
Entity *const entity_add(MemoryArena_ *const arena, World *const world,
const v2 pos, const v2 size, const f32 scale,
const enum EntityType type,
const enum Direction direction, Texture *const tex,
const b32 collides)
{
#ifdef DENGINE_DEBUG
ASSERT(world);
ASSERT(world->freeEntityIndex < world->maxEntities);
ASSERT(type < entitytype_count);
#endif
Entity entity = {0};
entity.id = world->uniqueIdAccumulator++;
entity.pos = pos;
entity.size = size;
entity.hitbox = size;
entity.scale = scale;
entity.type = type;
entity.direction = direction;
entity.tex = tex;
entity.collides = collides;
switch (type)
{
case entitytype_hero:
entity.stats = MEMORY_PUSH_STRUCT(arena, EntityStats);
entity.stats->maxHealth = 100;
entity.stats->health = entity.stats->maxHealth;
entity.stats->actionRate = 100;
entity.stats->actionTimer = entity.stats->actionRate;
entity.stats->actionSpdMul = 100;
entity.stats->entityIdToAttack = -1;
entity.stats->queuedAttack = entityattack_invalid;
entity.state = entitystate_idle;
entity.collidesWith[entitytype_mob] = TRUE;
break;
case entitytype_mob:
{
entity.stats = MEMORY_PUSH_STRUCT(arena, EntityStats);
entity.stats->maxHealth = 100;
entity.stats->health = entity.stats->maxHealth;
entity.stats->actionRate = 80;
entity.stats->actionTimer = entity.stats->actionRate;
entity.stats->actionSpdMul = 100;
entity.stats->entityIdToAttack = -1;
entity.stats->queuedAttack = entityattack_invalid;
entity.state = entitystate_idle;
entity.collidesWith[entitytype_hero] = TRUE;
break;
}
case entitytype_projectile:
case entitytype_attackObject:
entity.stats = MEMORY_PUSH_STRUCT(arena, EntityStats);
entity.stats->maxHealth = 100;
entity.stats->health = entity.stats->maxHealth;
entity.stats->actionRate = 100;
entity.stats->actionTimer = entity.stats->actionRate;
entity.stats->actionSpdMul = 100;
entity.stats->entityIdToAttack = -1;
entity.stats->queuedAttack = entityattack_invalid;
entity.state = entitystate_idle;
break;
default:
break;
}
world->entities[world->freeEntityIndex++] = entity;
Entity *result = &world->entities[world->freeEntityIndex - 1];
return result;
}
void entity_clearData(MemoryArena_ *const arena, World *const world,
Entity *const entity)
{
// TODO(doyle): Mem free// memory leak!!
/*
if (entity->stats)
PLATFORM_MEM_FREE(arena, entity->stats, sizeof(EntityStats));
if (entity->audioRenderer)
PLATFORM_MEM_FREE(arena, entity->audioRenderer,
sizeof(AudioRenderer) * entity->numAudioRenderers);
*/
entity->type = entitytype_null;
}
i32 entity_getIndex(World *const world, const i32 entityId)
{
i32 first = 0;
i32 last = world->freeEntityIndex - 1;
while (first <= last)
{
i32 middle = (first + last) / 2;
if (world->entities[middle].id > entityId)
last = middle - 1;
else if (world->entities[middle].id < entityId)
first = middle + 1;
else
return middle;
}
#ifdef DENGINE_DEBUG
ASSERT(INVALID_CODE_PATH);
#endif
return -1;
}
Entity *entity_get(World *const world, const i32 entityId)
{
Entity *result = NULL;
i32 worldIndex = entity_getIndex(world, entityId);
if (worldIndex != -1) result = &world->entities[worldIndex];
return result;
}

View File

@ -6,7 +6,7 @@
#include "Dengine/Debug.h" #include "Dengine/Debug.h"
#include "Dengine/MemoryArena.h" #include "Dengine/MemoryArena.h"
void platform_memoryFree(MemoryArena_ *arena, void *data, i32 numBytes) void platform_memoryFree(MemoryArena_ *arena, void *data, size_t numBytes)
{ {
if (data) free(data); if (data) free(data);
@ -16,7 +16,7 @@ void platform_memoryFree(MemoryArena_ *arena, void *data, i32 numBytes)
#endif #endif
} }
void *platform_memoryAlloc(MemoryArena_ *arena, i32 numBytes) void *platform_memoryAlloc(MemoryArena_ *arena, size_t numBytes)
{ {
void *result = calloc(1, numBytes); void *result = calloc(1, numBytes);

View File

@ -381,23 +381,31 @@ void renderer_entity(Renderer *renderer, Rect camera, Entity *entity,
if (math_pointInRect(camera, leftAlignedP) || if (math_pointInRect(camera, leftAlignedP) ||
math_pointInRect(camera, rightAlignedP)) math_pointInRect(camera, rightAlignedP))
{ {
EntityAnim *entityAnim = &entity->animList[entity->currAnimId]; EntityAnim *entityAnim = &entity->animList[entity->animListIndex];
Animation *anim = entityAnim->anim;
char *frameName = anim->frameList[entityAnim->currFrame];
SubTexture animRect = asset_getAtlasSubTex(anim->atlas, frameName);
v4 animTexRect = {0}; v4 texRect = {0};
animTexRect.vec2[0] = animRect.rect.pos; if (entityAnim->anim)
animTexRect.vec2[1] = v2_add(animRect.rect.pos, animRect.rect.size); {
Animation *anim = entityAnim->anim;
char *frameName = anim->frameList[entityAnim->currFrame];
SubTexture subTex = asset_getAtlasSubTex(anim->atlas, frameName);
flipTexCoord(&animTexRect, entity->flipX, entity->flipY); texRect.vec2[0] = subTex.rect.pos;
texRect.vec2[1] = v2_add(subTex.rect.pos, subTex.rect.size);
flipTexCoord(&texRect, entity->flipX, entity->flipY);
}
else
{
texRect = V4(0.0f, 0.0f, (f32)entity->tex->width,
(f32)entity->tex->height);
}
if (entity->direction == direction_east) if (entity->direction == direction_east)
{ {
flipTexCoord(&animTexRect, TRUE, FALSE); flipTexCoord(&texRect, TRUE, FALSE);
} }
RenderTex renderTex = {entity->tex, animTexRect}; RenderTex renderTex = {entity->tex, texRect};
renderer_rect(renderer, camera, entity->pos, entity->size, pivotPoint, renderer_rect(renderer, camera, entity->pos, entity->size, pivotPoint,
entity->rotation + rotate, renderTex, color); entity->rotation + rotate, renderTex, color);
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,13 @@
@echo OFF @echo OFF
REM Build tags file
ctags -R
REM Check if build tool is on path
REM >nul, 2>nul will remove the output text from the where command
where cl.exe >nul 2>nul
if %errorlevel%==1 call msvc86.bat
REM Drop compilation files into build folder REM Drop compilation files into build folder
IF NOT EXIST ..\bin mkdir ..\bin IF NOT EXIST ..\bin mkdir ..\bin
pushd ..\bin pushd ..\bin

View File

@ -3,7 +3,8 @@
#include "Dengine/Debug.h" #include "Dengine/Debug.h"
#include "Dengine/Math.h" #include "Dengine/Math.h"
#include "Dengine/OpenGL.h" #include "Dengine/OpenGL.h"
#include "Dengine/WorldTraveller.h" #include "Dengine/MemoryArena.h"
#include "Dengine/Asteroid.h"
INTERNAL inline void processKey(KeyState *state, int action) INTERNAL inline void processKey(KeyState *state, int action)
{ {
@ -142,6 +143,7 @@ i32 main(void)
i32 frameBufferWidth, frameBufferHeight; i32 frameBufferWidth, frameBufferHeight;
glfwGetFramebufferSize(window, &frameBufferWidth, &frameBufferHeight); glfwGetFramebufferSize(window, &frameBufferWidth, &frameBufferHeight);
glViewport(0, 0, frameBufferWidth, frameBufferHeight); glViewport(0, 0, frameBufferWidth, frameBufferHeight);
v2 windowSize = V2i(frameBufferWidth, frameBufferHeight);
glfwSetKeyCallback(window, keyCallback); glfwSetKeyCallback(window, keyCallback);
glfwSetCursorPosCallback(window, mouseCallback); glfwSetCursorPosCallback(window, mouseCallback);
@ -161,9 +163,8 @@ i32 main(void)
******************* *******************
*/ */
Memory memory = {0}; Memory memory = {0};
MemoryIndex persistentSize = MEGABYTES(128);
size_t persistentSize = MEGABYTES(128); MemoryIndex transientSize = MEGABYTES(128);
size_t transientSize = MEGABYTES(128);
memory.persistentSize = persistentSize; memory.persistentSize = persistentSize;
memory.persistent = PLATFORM_MEM_ALLOC_(NULL, persistentSize, u8); memory.persistent = PLATFORM_MEM_ALLOC_(NULL, persistentSize, u8);
@ -171,15 +172,8 @@ i32 main(void)
memory.transientSize = transientSize; memory.transientSize = transientSize;
memory.transient = PLATFORM_MEM_ALLOC_(NULL, transientSize, u8); memory.transient = PLATFORM_MEM_ALLOC_(NULL, transientSize, u8);
GameState worldTraveller = {0}; GameState gameState = {0};
worldTraveller_gameInit(&worldTraveller, glfwSetWindowUserPointer(window, CAST(void *)(&gameState));
V2i(frameBufferWidth, frameBufferHeight), &memory);
#ifdef DENGINE_DEBUG
debug_init(&worldTraveller.arena_, V2i(windowWidth, windowHeight),
worldTraveller.assetManager.font);
#endif
glfwSetWindowUserPointer(window, CAST(void *)(&worldTraveller));
/* /*
******************* *******************
@ -206,10 +200,11 @@ i32 main(void)
glfwPollEvents(); glfwPollEvents();
/* Rendering commands here*/ /* Rendering commands here*/
glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
worldTraveller_gameUpdateAndRender(&worldTraveller, secondsElapsed); asteroid_gameUpdateAndRender(&gameState, &memory, windowSize,
secondsElapsed);
GL_CHECK_ERROR(); GL_CHECK_ERROR();
/* Swap the buffers */ /* Swap the buffers */
@ -235,14 +230,10 @@ i32 main(void)
f32 msPerFrame = secondsElapsed * 1000.0f; f32 msPerFrame = secondsElapsed * 1000.0f;
f32 framesPerSecond = 1.0f / secondsElapsed; f32 framesPerSecond = 1.0f / secondsElapsed;
i32 entityCount =
worldTraveller.world[worldTraveller.currWorldIndex]
.freeEntityIndex;
char textBuffer[256]; char textBuffer[256];
snprintf(textBuffer, ARRAY_COUNT(textBuffer), snprintf(textBuffer, ARRAY_COUNT(textBuffer),
"Dengine | %f ms/f | %f fps | Entity Count: %d", "Dengine | %f ms/f | %f fps | Entity Count: %d",
msPerFrame, framesPerSecond, entityCount); msPerFrame, framesPerSecond, 0);
glfwSetWindowTitle(window, textBuffer); glfwSetWindowTitle(window, textBuffer);
titleUpdateFrequencyInSeconds = 0.5f; titleUpdateFrequencyInSeconds = 0.5f;

View File

@ -94,7 +94,6 @@ typedef struct AudioVorbis
* Texture Assets * Texture Assets
********************************* *********************************
*/ */
typedef struct SubTexture typedef struct SubTexture
{ {
Rect rect; Rect rect;

View File

@ -0,0 +1,31 @@
#ifndef ASTEROID_H
#define ASTEROID_H
#include "Dengine/AssetManager.h"
#include "Dengine/Common.h"
#include "Dengine/Entity.h"
#include "Dengine/MemoryArena.h"
#include "Dengine/Platform.h"
#include "Dengine/Renderer.h"
typedef struct GameState {
b32 init;
Entity entityList[1024];
i32 entityIndex;
Rect camera;
AssetManager assetManager;
KeyInput input;
MemoryArena_ transientArena;
MemoryArena_ persistentArena;
Renderer renderer;
} GameState;
void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
v2 windowSize, f32 dt);
#endif

View File

@ -14,6 +14,8 @@ typedef i32 b32;
typedef float f32; typedef float f32;
typedef double f64; typedef double f64;
typedef size_t MemoryIndex;
#define TRUE 1 #define TRUE 1
#define FALSE 0 #define FALSE 0

View File

@ -1,17 +1,10 @@
#ifndef DENGINE_ENTITY_H #ifndef ENTITY_H
#define DENGINE_ENTITY_H #define ENTITY_H
#include "Dengine/Common.h"
#include "Dengine/Math.h"
#include "Dengine/Assets.h" #include "Dengine/Assets.h"
#include "Dengine/Common.h"
typedef struct AssetManager AssetManager;
typedef struct AudioRenderer AudioRenderer; typedef struct AudioRenderer AudioRenderer;
typedef struct MemoryArena MemoryArena_;
typedef struct World World;
typedef struct EventQueue EventQueue;
typedef struct Entity Entity;
enum Direction enum Direction
{ {
@ -19,63 +12,17 @@ enum Direction
direction_west, direction_west,
direction_south, direction_south,
direction_east, direction_east,
direction_num,
direction_null, direction_null,
direction_num,
}; };
enum EntityType enum EntityType
{ {
entitytype_null, entitytype_invalid,
entitytype_hero, entitytype_ship,
entitytype_weapon,
entitytype_projectile,
entitytype_attackObject,
entitytype_npc,
entitytype_mob,
entitytype_tile,
entitytype_soundscape,
entitytype_count, entitytype_count,
}; };
enum EntityState
{
entitystate_idle,
entitystate_battle,
entitystate_attack,
entitystate_dead,
entitystate_count,
entitystate_invalid,
};
enum EntityAttack
{
entityattack_claudeAttack,
entityattack_claudeAttackUp,
entityattack_claudeAttackDown,
entityattack_claudeDragonHowl,
entityattack_claudeEnergySword,
entityattack_claudeRipperBlast,
entityattack_claudeAirSlash,
entityattack_count,
entityattack_invalid,
};
typedef struct EntityStats
{
f32 maxHealth;
f32 health;
f32 actionRate;
f32 actionTimer;
f32 actionSpdMul;
f32 busyDuration;
i32 entityIdToAttack;
enum EntityAttack queuedAttack;
Entity *weapon;
} EntityStats;
typedef struct EntityAnim typedef struct EntityAnim
{ {
Animation *anim; Animation *anim;
@ -85,7 +32,7 @@ typedef struct EntityAnim
u32 timesCompleted; u32 timesCompleted;
} EntityAnim; } EntityAnim;
struct Entity typedef struct Entity
{ {
i32 id; i32 id;
@ -102,7 +49,6 @@ struct Entity
b32 invisible; b32 invisible;
enum EntityState state;
enum EntityType type; enum EntityType type;
enum Direction direction; enum Direction direction;
@ -116,32 +62,13 @@ struct Entity
// allow for early-exit in collision check if the entity doesn't collide at // allow for early-exit in collision check if the entity doesn't collide at
// all // all
b32 collides; b32 collides;
enum EntityType collidesWith[entitytype_count];
EntityAnim animList[16]; EntityAnim animList[16];
i32 currAnimId; i32 animListIndex;
EntityStats *stats;
// TODO(doyle): Audio mixing instead of multiple renderers // TODO(doyle): Audio mixing instead of multiple renderers
AudioRenderer *audioRenderer; AudioRenderer *audioRenderer;
i32 numAudioRenderers; i32 numAudioRenderers;
}; } Entity;
SubTexture entity_getActiveSubTexture(Entity *const entity);
void entity_setActiveAnim(EventQueue *eventQueue, Entity *const entity,
const char *const animName);
void entity_updateAnim(EventQueue *eventQueue, Entity *const entity,
const f32 dt);
void entity_addAnim(AssetManager *const assetManager, Entity *const entity,
const char *const animName);
Entity *const entity_add(MemoryArena_ *const arena, World *const world,
const v2 pos, const v2 size, const f32 scale,
const enum EntityType type,
const enum Direction direction, Texture *const tex,
const b32 collides);
void entity_clearData(MemoryArena_ *const arena, World *const world,
Entity *const entity);
Entity *entity_get(World *const world, const i32 entityId);
i32 entity_getIndex(World *const world, const i32 entityId);
#endif #endif

View File

@ -5,25 +5,25 @@
typedef struct MemoryArena typedef struct MemoryArena
{ {
size_t size; MemoryIndex size;
size_t used; MemoryIndex used;
u8 *base; u8 *base;
} MemoryArena_; } MemoryArena_;
typedef struct Memory typedef struct Memory
{ {
void *persistent; void *persistent;
size_t persistentSize; MemoryIndex persistentSize;
void *transient; void *transient;
size_t transientSize; MemoryIndex transientSize;
b32 init; b32 init;
} Memory; } Memory;
#define MEMORY_PUSH_STRUCT(arena, type) (type *)memory_pushBytes(arena, sizeof(type)) #define MEMORY_PUSH_STRUCT(arena, type) (type *)memory_pushBytes(arena, sizeof(type))
#define MEMORY_PUSH_ARRAY(arena, count, type) (type *)memory_pushBytes(arena, (count)*sizeof(type)) #define MEMORY_PUSH_ARRAY(arena, count, type) (type *)memory_pushBytes(arena, (count)*sizeof(type))
inline void *memory_pushBytes(MemoryArena_ *arena, size_t size) inline void *memory_pushBytes(MemoryArena_ *arena, MemoryIndex size)
{ {
ASSERT((arena->used + size) <= arena->size); ASSERT((arena->used + size) <= arena->size);
void *result = arena->base + arena->used; void *result = arena->base + arena->used;
@ -32,6 +32,6 @@ inline void *memory_pushBytes(MemoryArena_ *arena, size_t size)
return result; return result;
} }
void memory_arenaInit(MemoryArena_ *arena, void *base, size_t size); void memory_arenaInit(MemoryArena_ *arena, void *base, MemoryIndex size);
#endif #endif

View File

@ -140,14 +140,16 @@ typedef struct PlatformFileRead
} PlatformFileRead; } PlatformFileRead;
// TODO(doyle): Create own custom memory allocator // TODO(doyle): Create own custom memory allocator
#define PLATFORM_MEM_FREE_(arena, ptr, bytes) platform_memoryFree(arena, CAST(void *) ptr, bytes) #define PLATFORM_MEM_FREE_(arena, ptr, bytes) \
platform_memoryFree(arena, CAST(void *) ptr, bytes)
// TODO(doyle): numBytes in mem free is temporary until we create custom // TODO(doyle): numBytes in mem free is temporary until we create custom
// allocator since we haven't put in a system to track memory usage per // allocator since we haven't put in a system to track memory usage per
// allocation // allocation
void platform_memoryFree(MemoryArena_ *arena, void *data, i32 numBytes); void platform_memoryFree(MemoryArena_ *arena, void *data, MemoryIndex numBytes);
#define PLATFORM_MEM_ALLOC_(arena, num, type) CAST(type *) platform_memoryAlloc(arena, num * sizeof(type)) #define PLATFORM_MEM_ALLOC_(arena, num, type) \
void *platform_memoryAlloc(MemoryArena_ *arena, i32 numBytes); CAST(type *) platform_memoryAlloc(arena, num * sizeof(type))
void *platform_memoryAlloc(MemoryArena_ *arena, MemoryIndex numBytes);
void platform_closeFileRead(MemoryArena_ *arena, PlatformFileRead *file); void platform_closeFileRead(MemoryArena_ *arena, PlatformFileRead *file);
i32 platform_readFileToBuffer(MemoryArena_ *arena, const char *const filePath, i32 platform_readFileToBuffer(MemoryArena_ *arena, const char *const filePath,

View File

@ -6,8 +6,8 @@
/* Forward Declaration */ /* Forward Declaration */
typedef struct AssetManager AssetManager; typedef struct AssetManager AssetManager;
typedef struct Entity Entity;
typedef struct Font Font; typedef struct Font Font;
typedef struct Entity Entity;
typedef struct MemoryArena MemoryArena_; typedef struct MemoryArena MemoryArena_;
typedef struct Shader Shader; typedef struct Shader Shader;
typedef struct Texture Texture; typedef struct Texture Texture;

View File

@ -1,109 +0,0 @@
#ifndef WORLDTRAVELLER_GAME_H
#define WORLDTRAVELLER_GAME_H
#include "Dengine/AssetManager.h"
#include "Dengine/Audio.h"
#include "Dengine/Common.h"
#include "Dengine/Math.h"
#include "Dengine/MemoryArena.h"
#include "Dengine/Platform.h"
#include "Dengine/Renderer.h"
#include "Dengine/UserInterface.h"
#define NUM_KEYS 1024
#define METERS_TO_PIXEL 240
/* Forward declaration */
typedef struct Entity Entity;
enum EventType
{
eventtype_null = 0,
eventtype_start_attack,
eventtype_end_attack,
eventtype_start_anim,
eventtype_end_anim,
eventtype_entity_died,
eventtype_count,
};
typedef struct Event
{
enum EventType type;
void *data;
} Event;
typedef struct EventQueue
{
Event queue[1024];
i32 numEvents;
} EventQueue;
enum RectBaseline
{
rectbaseline_top,
rectbaseline_topLeft,
rectbaseline_topRight,
rectbaseline_bottom,
rectbaseline_bottomRight,
rectbaseline_bottomLeft,
rectbaseline_left,
rectbaseline_right,
rectbaseline_center,
rectbaseline_count,
};
typedef struct Config
{
b32 playWorldAudio;
b32 showStatMenu;
b32 showDebugDisplay;
} Config;
typedef struct World
{
Entity *entities;
i32 maxEntities;
b32 *entityIdInBattle;
i32 numEntitiesInBattle;
i32 cameraFollowingId;
v2 cameraPos; // In pixels
v4 bounds; // In pixels
i32 heroId;
i32 freeEntityIndex;
u32 uniqueIdAccumulator;
Entity *soundscape;
} World;
typedef struct GameState
{
Memory *memory;
MemoryArena_ arena_;
MemoryArena_ transientArena;
enum State state;
KeyInput input;
v2 mouse;
Renderer renderer;
World world[4];
i32 currWorldIndex;
i32 tileSize;
AssetManager assetManager;
AudioManager audioManager;
Config config;
UiState uiState;
EventQueue eventQueue;
} GameState;
void worldTraveller_gameInit(GameState *state, v2 windowSize, Memory *memory);
void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt);
void worldTraveller_registerEvent(EventQueue *eventQueue, enum EventType type,
void *data);
#endif