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:
parent
ed6b961b61
commit
4795fe1cb1
@ -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" />
|
||||||
|
@ -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
241
src/Asteroid.c
Normal 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);
|
||||||
|
}
|
282
src/Debug.c
282
src/Debug.c
@ -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();
|
||||||
}
|
}
|
||||||
|
164
src/Entity.c
164
src/Entity.c
@ -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;
|
|
||||||
}
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
2477
src/WorldTraveller.c
2477
src/WorldTraveller.c
File diff suppressed because it is too large
Load Diff
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -94,7 +94,6 @@ typedef struct AudioVorbis
|
|||||||
* Texture Assets
|
* Texture Assets
|
||||||
*********************************
|
*********************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct SubTexture
|
typedef struct SubTexture
|
||||||
{
|
{
|
||||||
Rect rect;
|
Rect rect;
|
||||||
|
31
src/include/Dengine/Asteroid.h
Normal file
31
src/include/Dengine/Asteroid.h
Normal 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
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
|
Loading…
Reference in New Issue
Block a user