commit 359cee0b96a22775d22ca9c07c6c2a671c57bc94
parent d7eb12f2301685649964c47cb4a9025c5bc8506a
Author: amin <dev@aminmesbah.com>
Date: Mon, 10 Jun 2019 05:56:39 +0000
Compress and reduce game update code
FossilOrigin-Name: 5ad0c313ea09ed143d6627734825b1256d23050935c3d2726add39b4b12f31da
Diffstat:
M | src/am_math.h | | | 28 | ++++++++++++++++++++++++++++ |
M | src/game.c | | | 228 | +++++++++++++++++++++++-------------------------------------------------------- |
2 files changed, 93 insertions(+), 163 deletions(-)
diff --git a/src/am_math.h b/src/am_math.h
@@ -528,6 +528,8 @@ enum MathRectEdge
RECT_EDGE_TOP,
RECT_EDGE_LEFT,
RECT_EDGE_RIGHT,
+
+ NUM_RECT_EDGES,
};
internal inline segment math_rect_get_edge(rect r, enum MathRectEdge e)
@@ -552,6 +554,7 @@ internal inline segment math_rect_get_edge(rect r, enum MathRectEdge e)
case RECT_EDGE_RIGHT:
edge = (segment) {se, ne};
break;
+ case NUM_RECT_EDGES: // fallthrough
default:
assert(false);
break;
@@ -559,6 +562,31 @@ internal inline segment math_rect_get_edge(rect r, enum MathRectEdge e)
return edge;
}
+internal v2 math_rect_get_normal(enum MathRectEdge e)
+{
+ v2 normal = {0};
+ switch(e)
+ {
+ case RECT_EDGE_BOTTOM:
+ normal = (v2) {0.0f, -1.0f};
+ break;
+ case RECT_EDGE_TOP:
+ normal = (v2) {0.0f, 1.0f};
+ break;
+ case RECT_EDGE_LEFT:
+ normal = (v2) {-1.0f, 0.0f};
+ break;
+ case RECT_EDGE_RIGHT:
+ normal = (v2) {1.0f, 0.0f};
+ break;
+ case NUM_RECT_EDGES: // fallthrough
+ default:
+ assert(false);
+ break;
+ }
+ return normal;
+}
+
internal inline bool math_in_interval_open(f32 n, f32 min, f32 max)
{
assert(min <= max);
diff --git a/src/game.c b/src/game.c
@@ -149,10 +149,7 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
};
viewport.max = math_v2_a(viewport.min, viewport_size);
- }
-
- {
m4 view = math_m4_init_id();
// World origin is in the lower left
view = math_translate(view, (v3) {0.0f, framebuffer.height, 0.0f});
@@ -160,102 +157,17 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
view = math_translate(view, (v3) {viewport.min.x, viewport.min.y, 0.0f});
view = math_scale(view, (v3) {ppm, ppm, 1.0f});
game_state->renderer.view = view;
- }
- // Screen origin is in the upper left
- game_state->renderer.projection = math_projection_ortho(0.0f, framebuffer.width, framebuffer.height, 0.0f, -1.0f, 0.0f);
+ // Screen origin is in the upper left
+ game_state->renderer.projection = math_projection_ortho(0.0f, framebuffer.width, framebuffer.height, 0.0f, -1.0f, 0.0f);
+ }
v2i current_room_i = game_state->player.pos.room;
struct Room *current_room = world_room_get(game_state->world, current_room_i);
assert(current_room);
-
- // game_print_player_chunk
- {
- v2i c_i = world_room_get_chunk_index(current_room_i);
- struct WorldChunk *c = world_chunk_get(game_state->world, c_i);
- assert(c);
- printf("------------\n");
- printf("Current Player Room: ");
- math_print(current_room_i);
- printf("Current Actual Room: ");
- math_print(current_room->index);
- printf("Chunk Index: ");
- math_print(c->index);
- }
-
assert(math_v2i_eq(current_room_i, current_room->index));
- u32 *tiles = current_room->tiles;
-
- // game_render_tiles
- {
- for (size_t y = 0; y < ROOM_TILE_DIM_Y; y++)
- {
- for (size_t x = 0; x < ROOM_TILE_DIM_X; x++)
- {
- v2 tile_pos = {
- x,
- ROOM_TILE_DIM_Y - 1.0f - y,
- };
-
- m4 model = math_m4_init_id();
- // our square verts are anchored around the center point of the
- // square, so we want to offset by 0.5 to instead have our
- // anchor in the min corner
- model = math_translate(model, (v3) {TILE_SIZE * 0.5f, TILE_SIZE * 0.5f, 0.0f});
- model = math_translate(model, (v3) {tile_pos.x, tile_pos.y, 0.0f});
- model = math_scale(model, (v3) {TILE_SIZE, TILE_SIZE, 1.0f});
-
- v3 color;
-
- bool solid = tile_is_solid(tiles, tile_pos);
- if (solid)
- {
- color = (v3) {0.4f, 0.4f, 0.4f};
- }
- else
- {
- color = (v3) {0.3f, 0.3f, 0.3f};
- }
-
- {
- struct Entity player = game_state->player;
- f32 half_w = 0.5f * player.dimensions.width;
- f32 half_h = 0.5f * player.dimensions.height;
- rect player_aabb = {
- .min = {player.pos.local.x - half_w, player.pos.local.y - half_h},
- .max = {player.pos.local.x + half_w, player.pos.local.y + half_h},
- };
- rect tile_aabb = {
- .min = tile_pos,
- .max = {tile_pos.x + TILE_SIZE, tile_pos.y + TILE_SIZE},
- };
-
- bool player_is_in_tile = math_intersect_aabb_aabb(player_aabb, tile_aabb);
- if (player_is_in_tile)
- {
- color = (v3) {0.4f, 0.8f, 0.4f};
- }
- if (player_is_in_tile && solid)
- {
- color = (v3) {0.8f, 0.4f, 0.4f};
- assert(false);
- }
- }
-
- renderer_job_enqueue(
- &game_state->renderer,
- (struct RenderJob) {
- .ebo = game_state->renderer.quad_ebo,
- .color = color,
- .model = model,
- .layer = RENDER_LAYER_TILES,
- });
- }
- }
- }
-
// game_update_player
{
struct Entity *player = &game_state->player;
@@ -350,7 +262,7 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
});
// NOTE(amin): pointer alias
- u32 *tile_set = tiles;
+ u32 *tile_set = current_room->tiles;
bool tile_is_past_world_edge = false;
if (!math_v2i_eq(tile_pos.room, current_room_i))
{
@@ -374,82 +286,30 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
RENDER_COLLISION_DEBUG_QUAD(tile_aabb, ((v3) {0.8f, 0.4f, 0.4f}));
rect tile_player_sum = math_minkowski_sum_rect_rect(tile_aabb, player->dimensions);
- segment tile_sum_b = math_rect_get_edge(tile_player_sum, RECT_EDGE_BOTTOM);
- segment tile_sum_t = math_rect_get_edge(tile_player_sum, RECT_EDGE_TOP);
- segment tile_sum_l = math_rect_get_edge(tile_player_sum, RECT_EDGE_LEFT);
- segment tile_sum_r = math_rect_get_edge(tile_player_sum, RECT_EDGE_RIGHT);
-
- v2 norm_b = {0.0f, -1.0f};
- v2 norm_t = {0.0f, 1.0f};
- v2 norm_l = {-1.0f, 0.0f};
- v2 norm_r = {1.0f, 0.0f};
- if (!wall_is_internal(game_state->world, current_room_i, math_rect_get_edge(tile_aabb, RECT_EDGE_BOTTOM)))
+ for (enum MathRectEdge edge = 0; edge < NUM_RECT_EDGES; edge++)
{
- struct WallCollision bottom = get_wall_collision(player->pos.local, new_p, tile_sum_b, norm_b);
- if (bottom.collision_occurred)
- {
- if (smallest_distance_scale_factor > bottom.distance_scale_factor)
- {
- smallest_distance_scale_factor = bottom.distance_scale_factor;
- }
- wall_normal = norm_b;
- rect collision = {
- .min = tile_aabb.min,
- .max = {tile_aabb.max.x, tile_aabb.min.y + 0.2f},
- };
- RENDER_COLLISION_DEBUG_QUAD(collision, ((v3) {1.0f, 0.0f, 0.0f}));
- }
- }
- if (!wall_is_internal(game_state->world, current_room_i, math_rect_get_edge(tile_aabb, RECT_EDGE_TOP)))
- {
- struct WallCollision top = get_wall_collision(player->pos.local, new_p, tile_sum_t, norm_t);
- if (top.collision_occurred)
- {
- if (smallest_distance_scale_factor > top.distance_scale_factor)
- {
- smallest_distance_scale_factor = top.distance_scale_factor;
- }
- wall_normal = norm_t;
- rect collision = {
- .min = {tile_aabb.min.x, tile_aabb.max.y - 0.2f},
- .max = tile_aabb.max,
- };
- RENDER_COLLISION_DEBUG_QUAD(collision, ((v3) {0.0f, 1.0f, 0.0f}));
- }
- }
- if (!wall_is_internal(game_state->world, current_room_i, math_rect_get_edge(tile_aabb, RECT_EDGE_LEFT)))
- {
- struct WallCollision left = get_wall_collision(player->pos.local, new_p, tile_sum_l, norm_l);
- if (left.collision_occurred)
- {
- if (smallest_distance_scale_factor > left.distance_scale_factor)
- {
- smallest_distance_scale_factor = left.distance_scale_factor;
- }
- wall_normal = norm_l;
- rect collision = {
- .min = tile_aabb.min,
- .max = {tile_aabb.min.x + 0.2f, tile_aabb.max.y},
- };
- RENDER_COLLISION_DEBUG_QUAD(collision, ((v3) {0.0f, 0.0f, 1.0f}));
- }
- }
- if (!wall_is_internal(game_state->world, current_room_i, math_rect_get_edge(tile_aabb, RECT_EDGE_RIGHT)))
- {
- struct WallCollision right = get_wall_collision(player->pos.local, new_p, tile_sum_r, norm_r);
- if (right.collision_occurred)
+ segment player_sum_wall = math_rect_get_edge(tile_player_sum, edge);
+ v2 normal = math_rect_get_normal(edge);
+ segment tile_wall = math_rect_get_edge(tile_aabb, edge);
+
+ if (!wall_is_internal(game_state->world, current_room_i, tile_wall))
{
- if (smallest_distance_scale_factor > right.distance_scale_factor)
+ struct WallCollision c = get_wall_collision(player->pos.local, new_p, player_sum_wall, normal);
+ if (c.collision_occurred)
{
- smallest_distance_scale_factor = right.distance_scale_factor;
+ if (smallest_distance_scale_factor > c.distance_scale_factor)
+ {
+ smallest_distance_scale_factor = c.distance_scale_factor;
+ }
+ wall_normal = normal;
+ RENDER_COLLISION_DEBUG_QUAD(
+ ((rect) {
+ .min = tile_wall.min,
+ .max = math_v2_a(tile_wall.max, math_v2f_m(normal, -0.2f)),
+ }),
+ ((v3) {0.0f, 0.8f, 0.0f}));
}
- wall_normal = norm_r;
- rect collision = {
- .min = {tile_aabb.max.x - 0.2f, tile_aabb.min.y},
- .max = tile_aabb.max,
- };
- RENDER_COLLISION_DEBUG_QUAD(collision, ((v3) {1.0f, 0.0f, 1.0f}));
}
}
}
@@ -541,6 +401,48 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
});
}
+ // game_render_tiles
+ {
+ for (size_t y = 0; y < ROOM_TILE_DIM_Y; y++)
+ {
+ for (size_t x = 0; x < ROOM_TILE_DIM_X; x++)
+ {
+ v2 tile_pos = {
+ x,
+ ROOM_TILE_DIM_Y - 1.0f - y,
+ };
+
+ m4 model = math_m4_init_id();
+ // our square verts are anchored around the center point of the
+ // square, so we want to offset by 0.5 to instead have our
+ // anchor in the min corner
+ model = math_translate(model, (v3) {TILE_SIZE * 0.5f, TILE_SIZE * 0.5f, 0.0f});
+ model = math_translate(model, (v3) {tile_pos.x, tile_pos.y, 0.0f});
+ model = math_scale(model, (v3) {TILE_SIZE, TILE_SIZE, 1.0f});
+
+ v3 color;
+ bool solid = tile_is_solid(current_room->tiles, tile_pos);
+ if (solid)
+ {
+ color = (v3) {0.4f, 0.4f, 0.4f};
+ }
+ else
+ {
+ color = (v3) {0.3f, 0.3f, 0.3f};
+ }
+
+ renderer_job_enqueue(
+ &game_state->renderer,
+ (struct RenderJob) {
+ .ebo = game_state->renderer.quad_ebo,
+ .color = color,
+ .model = model,
+ .layer = RENDER_LAYER_TILES,
+ });
+ }
+ }
+ }
+
renderer_jobs_sort(&game_state->renderer, &game_state->world_allocator);
renderer_jobs_draw(&game_state->renderer);
}