Add ability to shoot and delete entities
This commit is contained in:
parent
6069ed8415
commit
42ba86f05a
Binary file not shown.
205
src/Asteroid.c
205
src/Asteroid.c
@ -183,6 +183,8 @@ v2 *createAsteroidVertexList(MemoryArena_ *arena, i32 iterations,
|
|||||||
result[i] = V2(((math_cosf(iterationAngle * i) + 1) * asteroidRadius),
|
result[i] = V2(((math_cosf(iterationAngle * i) + 1) * asteroidRadius),
|
||||||
((math_sinf(iterationAngle * i) + 1) * asteroidRadius));
|
((math_sinf(iterationAngle * i) + 1) * asteroidRadius));
|
||||||
|
|
||||||
|
ASSERT(result[i].x >= 0 && result[i].y >= 0);
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
f32 displacementDist = 0.50f * asteroidRadius;
|
f32 displacementDist = 0.50f * asteroidRadius;
|
||||||
i32 vertexDisplacement =
|
i32 vertexDisplacement =
|
||||||
@ -284,8 +286,9 @@ b32 checkEdgeProjectionOverlap(v2 *vertexList, i32 listSize,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
b32 moveEntity(GameState *state, Entity *entity, i32 entityIndex, v2 ddP,
|
INTERNAL b32 moveEntity(World *world, MemoryArena_ *transientArena,
|
||||||
f32 dt, f32 ddPSpeed)
|
Entity *entity, i32 entityIndex, v2 ddP, f32 dt,
|
||||||
|
f32 ddPSpeed)
|
||||||
{
|
{
|
||||||
ASSERT(ABS(ddP.x) <= 1.0f && ABS(ddP.y) <= 1.0f);
|
ASSERT(ABS(ddP.x) <= 1.0f && ABS(ddP.y) <= 1.0f);
|
||||||
/*
|
/*
|
||||||
@ -295,7 +298,7 @@ b32 moveEntity(GameState *state, Entity *entity, i32 entityIndex, v2 ddP,
|
|||||||
newPos = (a*t^2)/2 + oldVelocity*t + oldPos
|
newPos = (a*t^2)/2 + oldVelocity*t + oldPos
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ddP = v2_scale(ddP, state->pixelsPerMeter * ddPSpeed);
|
ddP = v2_scale(ddP, world->pixelsPerMeter * ddPSpeed);
|
||||||
v2 oldDp = entity->dP;
|
v2 oldDp = entity->dP;
|
||||||
v2 resistance = v2_scale(oldDp, 2.0f);
|
v2 resistance = v2_scale(oldDp, 2.0f);
|
||||||
ddP = v2_sub(ddP, resistance);
|
ddP = v2_sub(ddP, resistance);
|
||||||
@ -313,36 +316,37 @@ b32 moveEntity(GameState *state, Entity *entity, i32 entityIndex, v2 ddP,
|
|||||||
|
|
||||||
// TODO(doyle): Collision for rects, (need to create vertex list for it)
|
// TODO(doyle): Collision for rects, (need to create vertex list for it)
|
||||||
#if 1
|
#if 1
|
||||||
if (entity->renderMode == rendermode_polygon && entity->collides)
|
for (i32 i = entityIndex + 1; i < world->entityIndex; i++)
|
||||||
{
|
{
|
||||||
for (i32 i = entityIndex + 1; i < state->entityIndex; i++)
|
Entity *checkEntity = &world->entityList[i];
|
||||||
{
|
|
||||||
Entity *checkEntity = &state->entityList[i];
|
|
||||||
ASSERT(checkEntity->id != entity->id);
|
ASSERT(checkEntity->id != entity->id);
|
||||||
|
|
||||||
if (checkEntity->renderMode == rendermode_polygon &&
|
if (world->collisionTable[entity->type][checkEntity->type])
|
||||||
checkEntity->collides)
|
|
||||||
{
|
{
|
||||||
|
ASSERT(entity->vertexPoints);
|
||||||
|
ASSERT(checkEntity->vertexPoints);
|
||||||
|
|
||||||
/* Create entity edge lists */
|
/* Create entity edge lists */
|
||||||
v2 *entityVertexListOffsetToP =
|
v2 *entityVertexListOffsetToP = entity_generateUpdatedVertexList(
|
||||||
entity_createVertexList(&state->transientArena, entity);
|
transientArena, entity);
|
||||||
|
|
||||||
v2 *checkEntityVertexListOffsetToP = entity_createVertexList(
|
v2 *checkEntityVertexListOffsetToP =
|
||||||
&state->transientArena, checkEntity);
|
entity_generateUpdatedVertexList(transientArena,
|
||||||
|
checkEntity);
|
||||||
|
|
||||||
v2 *entityEdgeList = createNormalEdgeList(
|
v2 *entityEdgeList = createNormalEdgeList(transientArena,
|
||||||
&state->transientArena, entityVertexListOffsetToP,
|
entityVertexListOffsetToP,
|
||||||
entity->numVertexPoints);
|
entity->numVertexPoints);
|
||||||
|
|
||||||
v2 *checkEntityEdgeList = createNormalEdgeList(
|
v2 *checkEntityEdgeList = createNormalEdgeList(
|
||||||
&state->transientArena, checkEntityVertexListOffsetToP,
|
transientArena, checkEntityVertexListOffsetToP,
|
||||||
checkEntity->numVertexPoints);
|
checkEntity->numVertexPoints);
|
||||||
|
|
||||||
/* Combine both edge lists into one */
|
/* Combine both edge lists into one */
|
||||||
i32 totalNumEdges =
|
i32 totalNumEdges =
|
||||||
checkEntity->numVertexPoints + entity->numVertexPoints;
|
checkEntity->numVertexPoints + entity->numVertexPoints;
|
||||||
v2 *edgeList = memory_pushBytes(&state->transientArena,
|
v2 *edgeList =
|
||||||
totalNumEdges * sizeof(v2));
|
memory_pushBytes(transientArena, totalNumEdges * sizeof(v2));
|
||||||
for (i32 i = 0; i < entity->numVertexPoints; i++)
|
for (i32 i = 0; i < entity->numVertexPoints; i++)
|
||||||
{
|
{
|
||||||
edgeList[i] = entityEdgeList[i];
|
edgeList[i] = entityEdgeList[i];
|
||||||
@ -350,8 +354,7 @@ b32 moveEntity(GameState *state, Entity *entity, i32 entityIndex, v2 ddP,
|
|||||||
|
|
||||||
for (i32 i = 0; i < checkEntity->numVertexPoints; i++)
|
for (i32 i = 0; i < checkEntity->numVertexPoints; i++)
|
||||||
{
|
{
|
||||||
edgeList[i + entity->numVertexPoints] =
|
edgeList[i + entity->numVertexPoints] = checkEntityEdgeList[i];
|
||||||
checkEntityEdgeList[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkEdgeProjectionOverlap(
|
if (checkEdgeProjectionOverlap(
|
||||||
@ -363,11 +366,11 @@ b32 moveEntity(GameState *state, Entity *entity, i32 entityIndex, v2 ddP,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (willCollide) {
|
if (willCollide)
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@ -389,68 +392,106 @@ b32 moveEntity(GameState *state, Entity *entity, i32 entityIndex, v2 ddP,
|
|||||||
return willCollide;
|
return willCollide;
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERNAL void addAsteroid(GameState *state, v2 windowSize)
|
INTERNAL void addAsteroid(World *world, v2 windowSize)
|
||||||
{
|
{
|
||||||
Entity *asteroid = &state->entityList[state->entityIndex];
|
Entity *asteroid = &world->entityList[world->entityIndex++];
|
||||||
asteroid->id = state->entityIndex++;
|
asteroid->id = world->entityIdCounter++;
|
||||||
|
|
||||||
i32 randValue = rand();
|
i32 randValue = rand();
|
||||||
i32 randX = (randValue % (i32)windowSize.w);
|
i32 randX = (randValue % (i32)windowSize.w);
|
||||||
i32 randY = (randValue % (i32)windowSize.h);
|
i32 randY = (randValue % (i32)windowSize.h);
|
||||||
asteroid->pos = V2i(randX, randY);
|
asteroid->pos = V2i(randX, randY);
|
||||||
|
|
||||||
asteroid->size = V2(75.0f, 75.0f);
|
asteroid->size = V2(100.0f, 100.0f);
|
||||||
asteroid->hitbox = asteroid->size;
|
asteroid->hitbox = asteroid->size;
|
||||||
asteroid->offset = V2(asteroid->size.w * -0.5f, 0);
|
asteroid->offset = v2_scale(asteroid->size, -0.5f);
|
||||||
asteroid->scale = 1;
|
|
||||||
asteroid->rotation = 45;
|
|
||||||
asteroid->type = entitytype_asteroid;
|
asteroid->type = entitytype_asteroid;
|
||||||
asteroid->direction = direction_null;
|
asteroid->direction = direction_null;
|
||||||
asteroid->renderMode = rendermode_polygon;
|
asteroid->renderMode = rendermode_polygon;
|
||||||
|
|
||||||
asteroid->numVertexPoints = 10;
|
asteroid->numVertexPoints = 10;
|
||||||
asteroid->vertexPoints = createAsteroidVertexList(
|
asteroid->vertexPoints = createAsteroidVertexList(
|
||||||
&state->persistentArena, asteroid->numVertexPoints,
|
&world->entityArena, asteroid->numVertexPoints,
|
||||||
(i32)(asteroid->size.x * 0.5f));
|
(i32)(asteroid->size.w * 0.5f));
|
||||||
|
|
||||||
asteroid->tex = NULL;
|
asteroid->color = V4(0.0f, 0.5f, 0.5f, 1.0f);
|
||||||
asteroid->collides = TRUE;
|
}
|
||||||
|
|
||||||
|
INTERNAL void addBullet(World *world, Entity *shooter)
|
||||||
|
{
|
||||||
|
Entity *bullet = &world->entityList[world->entityIndex++];
|
||||||
|
bullet->id = world->entityIdCounter++;
|
||||||
|
|
||||||
|
bullet->offset = v2_scale(bullet->size, -0.5f);
|
||||||
|
bullet->pos = v2_add(shooter->pos, bullet->offset);
|
||||||
|
bullet->hitbox = bullet->size;
|
||||||
|
bullet->size = V2(2.0f, 20.0f);
|
||||||
|
bullet->rotation = shooter->rotation;
|
||||||
|
bullet->renderMode = rendermode_quad;
|
||||||
|
|
||||||
|
// TODO(doyle): Figure out how to free this memory on entity delete. A free list?
|
||||||
|
bullet->vertexPoints =
|
||||||
|
memory_pushBytes(&world->entityArena, sizeof(v2) * 4);
|
||||||
|
bullet->vertexPoints[0] = V2(0, bullet->size.h);
|
||||||
|
bullet->vertexPoints[1] = V2(0, 0);
|
||||||
|
bullet->vertexPoints[2] = V2(bullet->size.w, 0);
|
||||||
|
bullet->vertexPoints[3] = bullet->size;
|
||||||
|
|
||||||
|
bullet->numVertexPoints = 4;
|
||||||
|
|
||||||
|
bullet->type = entitytype_bullet;
|
||||||
|
bullet->color = V4(1.0f, 1.0f, 0, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
INTERNAL void setCollisionRule(World *world, enum EntityType a,
|
||||||
|
enum EntityType b, b32 rule)
|
||||||
|
{
|
||||||
|
ASSERT(a <= entitytype_count);
|
||||||
|
ASSERT(b <= entitytype_count);
|
||||||
|
world->collisionTable[a][b] = rule;
|
||||||
|
world->collisionTable[b][a] = rule;
|
||||||
}
|
}
|
||||||
|
|
||||||
void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
|
void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
|
||||||
v2 windowSize, f32 dt)
|
v2 windowSize, f32 dt)
|
||||||
{
|
{
|
||||||
|
MemoryIndex globalTransientArenaSize =
|
||||||
|
(MemoryIndex)((f32)memory->transientSize * 0.5f);
|
||||||
memory_arenaInit(&state->transientArena, memory->transient,
|
memory_arenaInit(&state->transientArena, memory->transient,
|
||||||
memory->transientSize);
|
globalTransientArenaSize);
|
||||||
|
|
||||||
|
World *world = &state->world;
|
||||||
if (!state->init)
|
if (!state->init)
|
||||||
{
|
{
|
||||||
srand((u32)time(NULL));
|
srand((u32)time(NULL));
|
||||||
memory_arenaInit(&state->persistentArena, memory->persistent,
|
|
||||||
memory->persistentSize);
|
|
||||||
initAssetManager(state);
|
initAssetManager(state);
|
||||||
initRenderer(state, windowSize);
|
initRenderer(state, windowSize);
|
||||||
|
|
||||||
state->pixelsPerMeter = 70.0f;
|
world->pixelsPerMeter = 70.0f;
|
||||||
|
|
||||||
|
MemoryIndex entityArenaSize =
|
||||||
|
(MemoryIndex)((f32)memory->transientSize * 0.5f);
|
||||||
|
|
||||||
|
u8 *arenaBase = state->transientArena.base + state->transientArena.size;
|
||||||
|
memory_arenaInit(&world->entityArena, arenaBase, entityArenaSize);
|
||||||
|
|
||||||
{ // Init asteroid entities
|
{ // Init asteroid entities
|
||||||
i32 numAsteroids = 15;
|
i32 numAsteroids = 15;
|
||||||
for (i32 i = 0; i < numAsteroids; i++)
|
for (i32 i = 0; i < numAsteroids; i++)
|
||||||
addAsteroid(state, windowSize);
|
addAsteroid(world, windowSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 1
|
|
||||||
{ // Init ship entity
|
{ // Init ship entity
|
||||||
Entity *ship = &state->entityList[state->entityIndex];
|
Entity *ship = &world->entityList[world->entityIndex++];
|
||||||
ship->id = state->entityIndex++;
|
ship->id = world->entityIdCounter++;
|
||||||
ship->pos = V2(100, 100);
|
ship->pos = V2(100, 100);
|
||||||
ship->size = V2(25.0f, 50.0f);
|
ship->size = V2(25.0f, 50.0f);
|
||||||
ship->hitbox = ship->size;
|
ship->hitbox = ship->size;
|
||||||
ship->offset = v2_scale(ship->size, 0.5f);
|
ship->offset = v2_scale(ship->size, -0.5f);
|
||||||
|
|
||||||
ship->numVertexPoints = 3;
|
ship->numVertexPoints = 3;
|
||||||
ship->vertexPoints = memory_pushBytes(
|
ship->vertexPoints = memory_pushBytes(
|
||||||
&state->persistentArena, sizeof(v2) * ship->numVertexPoints);
|
&world->entityArena, sizeof(v2) * ship->numVertexPoints);
|
||||||
|
|
||||||
v2 triangleBaseP = V2(0, 0);
|
v2 triangleBaseP = V2(0, 0);
|
||||||
v2 triangleTopP = V2(ship->size.w * 0.5f, ship->size.h);
|
v2 triangleTopP = V2(ship->size.w * 0.5f, ship->size.h);
|
||||||
@ -464,19 +505,21 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
|
|||||||
ship->type = entitytype_ship;
|
ship->type = entitytype_ship;
|
||||||
ship->direction = direction_null;
|
ship->direction = direction_null;
|
||||||
ship->renderMode = rendermode_polygon;
|
ship->renderMode = rendermode_polygon;
|
||||||
ship->tex = NULL;
|
ship->color = V4(1.0f, 0.5f, 0.5f, 1.0f);
|
||||||
ship->collides = TRUE;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
{ // Global Collision Rules
|
||||||
|
setCollisionRule(world, entitytype_ship, entitytype_asteroid, TRUE);
|
||||||
|
setCollisionRule(world, entitytype_bullet, entitytype_asteroid,
|
||||||
|
TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
world->camera.min = V2(0, 0);
|
||||||
|
world->camera.max = state->renderer.size;
|
||||||
|
world->worldSize = windowSize;
|
||||||
|
|
||||||
state->camera.min = V2(0, 0);
|
|
||||||
state->camera.max = state->renderer.size;
|
|
||||||
state->init = TRUE;
|
state->init = TRUE;
|
||||||
|
|
||||||
state->worldSize = windowSize;
|
|
||||||
|
|
||||||
debug_init(&state->persistentArena, windowSize,
|
debug_init(&state->persistentArena, windowSize,
|
||||||
state->assetManager.font);
|
state->assetManager.font);
|
||||||
}
|
}
|
||||||
@ -509,26 +552,26 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
|
|||||||
if (getKeyStatus(&state->input.keys[keycode_left_square_bracket],
|
if (getKeyStatus(&state->input.keys[keycode_left_square_bracket],
|
||||||
readkeytype_repeat, 0.2f, dt))
|
readkeytype_repeat, 0.2f, dt))
|
||||||
{
|
{
|
||||||
addAsteroid(state, windowSize);
|
addAsteroid(world, windowSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i32 i = 0; i < state->entityIndex; i++)
|
for (i32 i = 0; i < world->entityIndex; i++)
|
||||||
{
|
{
|
||||||
Entity *entity = &state->entityList[i];
|
Entity *entity = &world->entityList[i];
|
||||||
ASSERT(entity->type != entitytype_invalid);
|
ASSERT(entity->type != entitytype_invalid);
|
||||||
|
|
||||||
v2 pivotPoint = {0};
|
v2 pivotPoint = {0};
|
||||||
|
|
||||||
// Loop entity around world
|
// Loop entity around world
|
||||||
if (entity->pos.y >= state->worldSize.h)
|
if (entity->pos.y >= world->worldSize.h)
|
||||||
entity->pos.y = 0;
|
entity->pos.y = 0;
|
||||||
else if (entity->pos.y < 0)
|
else if (entity->pos.y < 0)
|
||||||
entity->pos.y = state->worldSize.h;
|
entity->pos.y = world->worldSize.h;
|
||||||
|
|
||||||
if (entity->pos.x >= state->worldSize.w)
|
if (entity->pos.x >= world->worldSize.w)
|
||||||
entity->pos.x = 0;
|
entity->pos.x = 0;
|
||||||
else if (entity->pos.x < 0)
|
else if (entity->pos.x < 0)
|
||||||
entity->pos.x = state->worldSize.w;
|
entity->pos.x = world->worldSize.w;
|
||||||
|
|
||||||
f32 ddPSpeedInMs = 0;
|
f32 ddPSpeedInMs = 0;
|
||||||
v2 ddP = {0};
|
v2 ddP = {0};
|
||||||
@ -560,6 +603,12 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
|
|||||||
entity->rotation -= (rotationsPerSecond) * dt;
|
entity->rotation -= (rotationsPerSecond) * dt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (getKeyStatus(&state->input.keys[keycode_space],
|
||||||
|
readkeytype_delayedRepeat, 0.0f, dt))
|
||||||
|
{
|
||||||
|
addBullet(world, entity);
|
||||||
|
}
|
||||||
|
|
||||||
if (ddP.x > 0.0f && ddP.y > 0.0f)
|
if (ddP.x > 0.0f && ddP.y > 0.0f)
|
||||||
{
|
{
|
||||||
// NOTE(doyle): Cheese it and pre-compute the vector for
|
// NOTE(doyle): Cheese it and pre-compute the vector for
|
||||||
@ -572,6 +621,11 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
|
|||||||
DEBUG_PUSH_VAR("Pos: %5.2f, %5.2f", entity->pos, "v2");
|
DEBUG_PUSH_VAR("Pos: %5.2f, %5.2f", entity->pos, "v2");
|
||||||
DEBUG_PUSH_VAR("Velocity: %5.2f, %5.2f", entity->dP, "v2");
|
DEBUG_PUSH_VAR("Velocity: %5.2f, %5.2f", entity->dP, "v2");
|
||||||
DEBUG_PUSH_VAR("Rotation: %5.2f", entity->rotation, "f32");
|
DEBUG_PUSH_VAR("Rotation: %5.2f", entity->rotation, "f32");
|
||||||
|
|
||||||
|
renderer_rect(&state->renderer, world->camera, entity->pos,
|
||||||
|
V2(5, 5), V2(0, 0),
|
||||||
|
DEGREES_TO_RADIANS(entity->rotation), NULL,
|
||||||
|
V4(1.0f, 1.0f, 1.0f, 1.0f), renderflag_no_texture);
|
||||||
}
|
}
|
||||||
else if (entity->type == entitytype_asteroid)
|
else if (entity->type == entitytype_asteroid)
|
||||||
{
|
{
|
||||||
@ -648,26 +702,43 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
|
|||||||
f32 dirOffset = ((randValue % 10) + 1) / 100.0f;
|
f32 dirOffset = ((randValue % 10) + 1) / 100.0f;
|
||||||
v2_scale(ddP, dirOffset);
|
v2_scale(ddP, dirOffset);
|
||||||
|
|
||||||
// NOTE(doyle): Make asteroids start and move at constant speed
|
// NOTE(doyle): Make asteroids start and move at constant speed by
|
||||||
|
// ensuring that dP is "refreshed" with non-decaying acceleration
|
||||||
ddPSpeedInMs = 1;
|
ddPSpeedInMs = 1;
|
||||||
entity->dP = v2_scale(ddP, state->pixelsPerMeter * ddPSpeedInMs);
|
entity->dP = v2_scale(ddP, world->pixelsPerMeter * ddPSpeedInMs);
|
||||||
entity->rotation += (60 * dt);
|
entity->rotation += (60 * dt);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
else if (entity->type == entitytype_bullet)
|
||||||
|
{
|
||||||
|
ddPSpeedInMs = 5;
|
||||||
|
Radians rotation = DEGREES_TO_RADIANS((entity->rotation + 90.0f));
|
||||||
|
ddP = V2(math_cosf(rotation), math_sinf(rotation));
|
||||||
|
entity->dP = v2_scale(ddP, world->pixelsPerMeter * ddPSpeedInMs);
|
||||||
|
}
|
||||||
|
|
||||||
b32 willCollide = moveEntity(state, entity, i, ddP, dt, ddPSpeedInMs);
|
b32 willCollide = moveEntity(world, &state->transientArena, entity, i,
|
||||||
v4 entityColor = V4(1.0f, 1.0f, 1.0f, 1.0f);
|
ddP, dt, ddPSpeedInMs);
|
||||||
#if 1
|
v4 collideColor = {0};
|
||||||
if (willCollide)
|
if (willCollide)
|
||||||
{
|
{
|
||||||
entityColor = V4(1.0f, 1.0f, 0, 1.0f);
|
collideColor = V4(1.0f, 0, 0, 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity->type == entitytype_bullet)
|
||||||
|
{
|
||||||
|
if (!math_pointInRect(world->camera, entity->pos))
|
||||||
|
{
|
||||||
|
world->entityList[i] = world->entityList[--world->entityIndex];
|
||||||
|
i--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
RenderFlags flags = renderflag_wireframe | renderflag_no_texture;
|
RenderFlags flags = renderflag_wireframe | renderflag_no_texture;
|
||||||
renderer_entity(&state->renderer, &state->transientArena, state->camera,
|
renderer_entity(&state->renderer, &state->transientArena, world->camera,
|
||||||
entity, V2(0, 0), 0,
|
entity, V2(0, 0), 0,
|
||||||
entityColor, flags);
|
collideColor, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
|
12
src/Debug.c
12
src/Debug.c
@ -273,20 +273,28 @@ void debug_drawUi(GameState *state, f32 dt)
|
|||||||
updateAndRenderDebugStack(&state->renderer, &state->transientArena, dt);
|
updateAndRenderDebugStack(&state->renderer, &state->transientArena, dt);
|
||||||
renderConsole(&state->renderer, &state->transientArena);
|
renderConsole(&state->renderer, &state->transientArena);
|
||||||
|
|
||||||
|
{ // Print Memory Arena Info
|
||||||
|
DEBUG_PUSH_STRING("== MEMORY ARENAS ==");
|
||||||
MemoryArena_ *transient = &state->transientArena;
|
MemoryArena_ *transient = &state->transientArena;
|
||||||
i32 transientSizeInKbs = transient->size / 1024;
|
i32 transientSizeInKbs = transient->size / 1024;
|
||||||
i32 transientUsedInKbs = transient->used / 1024;
|
i32 transientUsedInKbs = transient->used / 1024;
|
||||||
v2 transientUsage = V2i(transientUsedInKbs, transientSizeInKbs);
|
v2 transientUsage = V2i(transientUsedInKbs, transientSizeInKbs);
|
||||||
DEBUG_PUSH_VAR("Transient Size: %.0f", transient->size, "f32");
|
|
||||||
DEBUG_PUSH_VAR("Transient Usage: %.0f/%.0f", transientUsage, "v2");
|
DEBUG_PUSH_VAR("Transient Usage: %.0f/%.0f", transientUsage, "v2");
|
||||||
|
|
||||||
MemoryArena_ *persistent = &state->persistentArena;
|
MemoryArena_ *persistent = &state->persistentArena;
|
||||||
i32 persistentSizeInKbs = persistent->size / 1024;
|
i32 persistentSizeInKbs = persistent->size / 1024;
|
||||||
i32 persistentUsedInKbs = persistent->used / 1024;
|
i32 persistentUsedInKbs = persistent->used / 1024;
|
||||||
v2 persistentUsage = V2i(persistentUsedInKbs, persistentSizeInKbs);
|
v2 persistentUsage = V2i(persistentUsedInKbs, persistentSizeInKbs);
|
||||||
DEBUG_PUSH_VAR("Permanent Size: %.0f", persistent->size, "f32");
|
|
||||||
DEBUG_PUSH_VAR("Permanent Usage: %.0f/%.0f", persistentUsage, "v2");
|
DEBUG_PUSH_VAR("Permanent Usage: %.0f/%.0f", persistentUsage, "v2");
|
||||||
|
|
||||||
|
MemoryArena_ *entityArena = &state->world.entityArena;
|
||||||
|
i32 entitySizeInKbs = entityArena->size / 1024;
|
||||||
|
i32 entityUsedInKbs = entityArena->used / 1024;
|
||||||
|
v2 entityUsage = V2i(entityUsedInKbs, entitySizeInKbs);
|
||||||
|
DEBUG_PUSH_VAR("Entity Usage: %.0f/%.0f", entityUsage, "v2");
|
||||||
|
DEBUG_PUSH_STRING("== ==");
|
||||||
|
}
|
||||||
|
|
||||||
DEBUG_PUSH_VAR("Num Vertex: %d",
|
DEBUG_PUSH_VAR("Num Vertex: %d",
|
||||||
GLOBAL_debug.callCount[debugcount_numVertex], "i32");
|
GLOBAL_debug.callCount[debugcount_numVertex], "i32");
|
||||||
|
|
||||||
|
@ -89,8 +89,12 @@ 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");
|
||||||
}
|
}
|
||||||
|
|
||||||
v2 *entity_createVertexList(MemoryArena_ *transientArena, Entity *entity)
|
v2 *entity_generateUpdatedVertexList(MemoryArena_ *transientArena,
|
||||||
|
Entity *entity)
|
||||||
{
|
{
|
||||||
|
ASSERT(entity->vertexPoints);
|
||||||
|
ASSERT(entity->numVertexPoints >= 3);
|
||||||
|
|
||||||
v2 *result =
|
v2 *result =
|
||||||
memory_pushBytes(transientArena, entity->numVertexPoints * sizeof(v2));
|
memory_pushBytes(transientArena, entity->numVertexPoints * sizeof(v2));
|
||||||
|
|
||||||
@ -98,9 +102,10 @@ v2 *entity_createVertexList(MemoryArena_ *transientArena, Entity *entity)
|
|||||||
{
|
{
|
||||||
result[i] = v2_add(entity->vertexPoints[i], entity->offset);
|
result[i] = v2_add(entity->vertexPoints[i], entity->offset);
|
||||||
result[i] = v2_add(result[i], entity->pos);
|
result[i] = v2_add(result[i], entity->pos);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
math_applyRotationToVertexes(result[0], entity->offset,
|
math_applyRotationToVertexes(entity->pos, V2(0 ,0),
|
||||||
DEGREES_TO_RADIANS(entity->rotation), result,
|
DEGREES_TO_RADIANS(entity->rotation), result,
|
||||||
entity->numVertexPoints);
|
entity->numVertexPoints);
|
||||||
|
|
||||||
|
@ -574,11 +574,15 @@ void renderer_entity(Renderer *renderer, MemoryArena_ *transientArena,
|
|||||||
renderTex.texRect = texRect;
|
renderTex.texRect = texRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(doyle): Proper blending
|
||||||
|
v4 renderColor = color;
|
||||||
|
if (v4_equals(color, V4(0, 0, 0, 0))) renderColor = entity->color;
|
||||||
|
|
||||||
if (entity->renderMode == rendermode_quad)
|
if (entity->renderMode == rendermode_quad)
|
||||||
{
|
{
|
||||||
renderer_rect(renderer, camera, entity->pos, entity->size,
|
renderer_rect(renderer, camera, entity->pos, entity->size,
|
||||||
v2_add(entity->offset, pivotPoint), totalRotation,
|
v2_add(entity->offset, pivotPoint), totalRotation,
|
||||||
&renderTex, color, flags);
|
&renderTex, entity->color, flags);
|
||||||
}
|
}
|
||||||
else if (entity->renderMode == rendermode_polygon)
|
else if (entity->renderMode == rendermode_polygon)
|
||||||
{
|
{
|
||||||
@ -586,12 +590,12 @@ void renderer_entity(Renderer *renderer, MemoryArena_ *transientArena,
|
|||||||
ASSERT(entity->vertexPoints);
|
ASSERT(entity->vertexPoints);
|
||||||
|
|
||||||
v2 *offsetVertexPoints =
|
v2 *offsetVertexPoints =
|
||||||
entity_createVertexList(transientArena, entity);
|
entity_generateUpdatedVertexList(transientArena, entity);
|
||||||
|
|
||||||
renderer_polygon(renderer, camera, offsetVertexPoints,
|
renderer_polygon(renderer, camera, offsetVertexPoints,
|
||||||
entity->numVertexPoints,
|
entity->numVertexPoints,
|
||||||
v2_add(entity->offset, pivotPoint), totalRotation,
|
v2_add(entity->offset, pivotPoint), totalRotation,
|
||||||
&renderTex, color, flags);
|
&renderTex, renderColor, flags);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -172,8 +172,13 @@ 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 gameState = {0};
|
MemoryArena_ gameArena = {0};
|
||||||
glfwSetWindowUserPointer(window, CAST(void *)(&gameState));
|
memory_arenaInit(&gameArena, memory.persistent, memory.persistentSize);
|
||||||
|
|
||||||
|
GameState *gameState = MEMORY_PUSH_STRUCT(&gameArena, GameState);
|
||||||
|
gameState->persistentArena = gameArena;
|
||||||
|
|
||||||
|
glfwSetWindowUserPointer(window, CAST(void *)(gameState));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*******************
|
*******************
|
||||||
@ -203,7 +208,7 @@ i32 main(void)
|
|||||||
glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
|
glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
asteroid_gameUpdateAndRender(&gameState, &memory, windowSize,
|
asteroid_gameUpdateAndRender(gameState, &memory, windowSize,
|
||||||
secondsElapsed);
|
secondsElapsed);
|
||||||
GL_CHECK_ERROR();
|
GL_CHECK_ERROR();
|
||||||
|
|
||||||
@ -233,7 +238,7 @@ i32 main(void)
|
|||||||
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, gameState.entityIndex);
|
msPerFrame, framesPerSecond, gameState->world.entityIndex);
|
||||||
|
|
||||||
glfwSetWindowTitle(window, textBuffer);
|
glfwSetWindowTitle(window, textBuffer);
|
||||||
titleUpdateFrequencyInSeconds = 0.5f;
|
titleUpdateFrequencyInSeconds = 0.5f;
|
||||||
|
@ -8,23 +8,35 @@
|
|||||||
#include "Dengine/Platform.h"
|
#include "Dengine/Platform.h"
|
||||||
#include "Dengine/Renderer.h"
|
#include "Dengine/Renderer.h"
|
||||||
|
|
||||||
|
typedef struct World
|
||||||
|
{
|
||||||
|
MemoryArena_ entityArena;
|
||||||
|
|
||||||
|
v2 *entityVertexListCache[entitytype_count];
|
||||||
|
Entity entityList[1024];
|
||||||
|
i32 entityIndex;
|
||||||
|
|
||||||
|
u32 entityIdCounter;
|
||||||
|
|
||||||
|
f32 pixelsPerMeter;
|
||||||
|
v2 worldSize;
|
||||||
|
Rect camera;
|
||||||
|
|
||||||
|
// TODO(doyle): Ensure we change this if it gets too big
|
||||||
|
b32 collisionTable[entitytype_count][entitytype_count];
|
||||||
|
} World;
|
||||||
|
|
||||||
typedef struct GameState {
|
typedef struct GameState {
|
||||||
b32 init;
|
b32 init;
|
||||||
|
|
||||||
Entity entityList[1024];
|
World world;
|
||||||
i32 entityIndex;
|
|
||||||
f32 pixelsPerMeter;
|
|
||||||
|
|
||||||
v2 worldSize;
|
|
||||||
|
|
||||||
Rect camera;
|
|
||||||
|
|
||||||
AssetManager assetManager;
|
AssetManager assetManager;
|
||||||
KeyInput input;
|
KeyInput input;
|
||||||
|
|
||||||
MemoryArena_ transientArena;
|
MemoryArena_ transientArena;
|
||||||
MemoryArena_ persistentArena;
|
MemoryArena_ persistentArena;
|
||||||
|
|
||||||
|
|
||||||
Renderer renderer;
|
Renderer renderer;
|
||||||
} GameState;
|
} GameState;
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ enum EntityType
|
|||||||
entitytype_invalid,
|
entitytype_invalid,
|
||||||
entitytype_ship,
|
entitytype_ship,
|
||||||
entitytype_asteroid,
|
entitytype_asteroid,
|
||||||
|
entitytype_bullet,
|
||||||
entitytype_count,
|
entitytype_count,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -42,10 +43,7 @@ typedef struct EntityAnim
|
|||||||
|
|
||||||
typedef struct Entity
|
typedef struct Entity
|
||||||
{
|
{
|
||||||
i32 id;
|
u32 id;
|
||||||
|
|
||||||
i32 childIds[8];
|
|
||||||
i32 numChilds;
|
|
||||||
|
|
||||||
v2 pos;
|
v2 pos;
|
||||||
v2 dP;
|
v2 dP;
|
||||||
@ -53,11 +51,11 @@ typedef struct Entity
|
|||||||
v2 hitbox;
|
v2 hitbox;
|
||||||
v2 size;
|
v2 size;
|
||||||
|
|
||||||
// NOTE(doyle): Offset from origin point to the entity's considered "center"
|
/*
|
||||||
// point, all operations work from this point, i.e. rotation, movement,
|
NOTE(doyle): Offset is the vector to shift the polygons "origin" to the
|
||||||
// collision detection
|
world origin. In our case this should strictly be negative as we have
|
||||||
// If this is a polygon, the offset should be from the 1st vertex point
|
a requirement that all vertex points must be strictly positive.
|
||||||
// specified
|
*/
|
||||||
v2 offset;
|
v2 offset;
|
||||||
|
|
||||||
enum RenderMode renderMode;
|
enum RenderMode renderMode;
|
||||||
@ -70,17 +68,11 @@ typedef struct Entity
|
|||||||
enum EntityType type;
|
enum EntityType type;
|
||||||
enum Direction direction;
|
enum Direction direction;
|
||||||
|
|
||||||
|
v4 color;
|
||||||
Texture *tex;
|
Texture *tex;
|
||||||
b32 flipX;
|
b32 flipX;
|
||||||
b32 flipY;
|
b32 flipY;
|
||||||
|
|
||||||
// TODO(doyle): Two collision flags, we want certain entities to collide
|
|
||||||
// with certain types of entities only (i.e. projectile from hero to enemy,
|
|
||||||
// only collides with enemy). Having two flags is redundant, but! it does
|
|
||||||
// allow for early-exit in collision check if the entity doesn't collide at
|
|
||||||
// all
|
|
||||||
b32 collides;
|
|
||||||
|
|
||||||
EntityAnim animList[16];
|
EntityAnim animList[16];
|
||||||
i32 animListIndex;
|
i32 animListIndex;
|
||||||
|
|
||||||
@ -95,5 +87,6 @@ void entity_updateAnim(Entity *const entity, const f32 dt);
|
|||||||
void entity_addAnim(AssetManager *const assetManager, Entity *const entity,
|
void entity_addAnim(AssetManager *const assetManager, Entity *const entity,
|
||||||
const char *const animName);
|
const char *const animName);
|
||||||
|
|
||||||
v2 *entity_createVertexList(MemoryArena_ *transientArena, Entity *entity);
|
v2 *entity_generateUpdatedVertexList(MemoryArena_ *transientArena,
|
||||||
|
Entity *entity);
|
||||||
#endif
|
#endif
|
||||||
|
@ -410,5 +410,23 @@ INTERNAL inline void math_applyRotationToVertexes(v2 pos, v2 pivotPoint,
|
|||||||
vertexList[i] = newP;
|
vertexList[i] = newP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
INTERNAL inline f32 math_lerp(f32 a, f32 t, f32 b)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Linear blend between two values. We having a starting point "a", and
|
||||||
|
the distance to "b" is defined as (b - a). Then we can say
|
||||||
|
|
||||||
|
a + t(b - a)
|
||||||
|
|
||||||
|
As our linear blend fn. We start from "a" and choosing a t from 0->1
|
||||||
|
will vary the value of (b - a) towards b. If we expand this, this
|
||||||
|
becomes
|
||||||
|
|
||||||
|
a + (t * b) - (a * t) == (1 - t)a + t*b
|
||||||
|
*/
|
||||||
|
f32 result = ((1 - t) * a) + (t * b);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user