commit 487823facfe3c4477fc01b3951e369b3da1e6f12
parent e42269fa3745f6c6610263ee5bd8d58fcefd3ff0
Author: amin <dev@aminmesbah.com>
Date: Sat, 27 Apr 2019 02:21:04 +0000
Use AbsolutePos as player position
FossilOrigin-Name: 37236722038689f009aa238e57c579c9ced9398f701d1795bc53ecd6a7e8be0b
Diffstat:
M | src/game.c | | | 78 | +++++++++++++++++++++++++++++++++++++----------------------------------------- |
M | src/game.h | | | 20 | +++++++++++--------- |
2 files changed, 48 insertions(+), 50 deletions(-)
diff --git a/src/game.c b/src/game.c
@@ -2,8 +2,6 @@
#include "glad.c"
#include "shader.c"
-// One tile is one square meter
-#define TILE_SIZE 1.0f
// TODO: delete
#define NUM_ROOMS 2
@@ -18,13 +16,12 @@ internal void game_init(struct GameMemory *game_memory, v2u framebuffer)
{
struct GameState *game_state = game_memory->game_state;
- game_state->player_pos_absolute = (struct AbsolutePos) {
- .room_index = {0, 0},
- .room_offset = {12.5f, 5.0f},
- };
// init player
- game_state->player.pos = game_state->player_pos_absolute.room_offset;
+ game_state->player.pos = (struct AbsolutePos) {
+ .room = {0, 0},
+ .local = {12.5f, 5.0f},
+ };
// In Knytt, the player is 9 by 14 texels and a tile is 24 by 24 texels.
// These dimensions are relative to a square 'meter', one tile
@@ -97,29 +94,29 @@ internal struct AbsolutePos pos_recanonicalize(struct AbsolutePos p)
struct AbsolutePos p_final = p;
v2i room_index_delta = {0};
- if (p.room_offset.x < 0.0f)
+ if (p.local.x < 0.0f)
{
room_index_delta.x -= 1;
- p_final.room_offset.x = glmth_wrap(p.room_offset.x, 0.0f, ROOM_TILE_DIM_X);
+ p_final.local.x = glmth_wrap(p.local.x, 0.0f, ROOM_TILE_DIM_X);
}
- else if (p.room_offset.x > ROOM_TILE_DIM_X)
+ else if (p.local.x > ROOM_TILE_DIM_X)
{
room_index_delta.x += 1;
- p_final.room_offset.x = glmth_wrap(p.room_offset.x, 0.0f, ROOM_TILE_DIM_X);
+ p_final.local.x = glmth_wrap(p.local.x, 0.0f, ROOM_TILE_DIM_X);
}
- if (p.room_offset.y < 0.0f)
+ if (p.local.y < 0.0f)
{
room_index_delta.y -= 1;
- p_final.room_offset.y = glmth_wrap(p.room_offset.y, 0.0f, ROOM_TILE_DIM_Y);
+ p_final.local.y = glmth_wrap(p.local.y, 0.0f, ROOM_TILE_DIM_Y);
}
- else if (p.room_offset.y > ROOM_TILE_DIM_Y)
+ else if (p.local.y > ROOM_TILE_DIM_Y)
{
room_index_delta.y += 1;
- p_final.room_offset.y = glmth_wrap(p.room_offset.y, 0.0f, ROOM_TILE_DIM_Y);
+ p_final.local.y = glmth_wrap(p.local.y, 0.0f, ROOM_TILE_DIM_Y);
}
- p_final.room_index = glmth_v2i_a(p.room_index, room_index_delta);
+ p_final.room = glmth_v2i_a(p.room, room_index_delta);
return p_final;
}
@@ -183,6 +180,8 @@ internal struct WallCollision get_wall_collision(v2 entity_p_initial, v2 entity_
if (theta_is_obtuse)
{
f32 wall_position = wall.min.E[wall_normal_axis];
+
+ // Not to be confused with the anime about street racing
f32 initial_d = wall_position - entity_p_initial.E[wall_normal_axis];
f32 segment_scale_factor = initial_d / player_delta.E[wall_normal_axis];
@@ -222,7 +221,7 @@ internal u32 get_tile_value(u32 *tiles, v2 tile_pos)
(v2) {0}));
u32 tile_i_linearized = (ROOM_TILE_DIM_X * tile_i_2d.y) + tile_i_2d.x;
- assert(tile_i_linearized < ROOM_TILE_DIM_X * ROOM_TILE_DIM_Y);
+ assert(tile_i_linearized < ROOM_TILE_COUNT);
u32 tile_value = tiles[tile_i_linearized];
return tile_value;
@@ -382,7 +381,7 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
// TODO: This is, of course, just temporary. Delete it.
struct Room *rooms[NUM_ROOMS] = {&collision_test_zone, &knytt_hanging_fly_village};
- v2i current_room_i = game_state->player_pos_absolute.room_index;
+ v2i current_room_i = game_state->player.pos.room;
struct RoomSearchResult r = get_room_at_index(rooms, NUM_ROOMS, current_room_i);
assert(r.room_found);
struct Room *current_room = rooms[r.room_array_index];
@@ -427,8 +426,8 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
f32 half_w = 0.5f * player.dimensions.width;
f32 half_h = 0.5f * player.dimensions.height;
rect player_aabb = {
- .min = {player.pos.x - half_w, player.pos.y - half_h},
- .max = {player.pos.x + half_w, player.pos.y + half_h},
+ .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,
@@ -511,11 +510,11 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
{
#define RENDER_COLLISION_DEBUG_QUAD(r, c) render_debug_quad(game_state, (r), (c), &view, &projection);
v2 player_delta = glmth_v2f_m(player->velocity, dt);
- v2 new_p = glmth_v2_a(player->pos, player_delta);
+ v2 new_p = glmth_v2_a(player->pos.local, player_delta);
rect player_traversal_bb = {
- .min = {glmth_min(player->pos.x, new_p.x), glmth_min(player->pos.y, new_p.y)},
- .max = {glmth_max(player->pos.x, new_p.x), glmth_max(player->pos.y, new_p.y)},
+ .min = {glmth_min(player->pos.local.x, new_p.x), glmth_min(player->pos.local.y, new_p.y)},
+ .max = {glmth_max(player->pos.local.x, new_p.x), glmth_max(player->pos.local.y, new_p.y)},
};
rect player_traversal_occupancy_bb = glmth_minkowski_sum_rect_rect(player_traversal_bb, player->dimensions);
@@ -571,7 +570,7 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
if (!wall_is_screen_edge(tiles, glmth_rect_get_edge(tile_aabb, RECT_EDGE_BOTTOM)) && !wall_is_internal(tiles, glmth_rect_get_edge(tile_aabb, RECT_EDGE_BOTTOM)))
{
- struct WallCollision bottom = get_wall_collision(player->pos, new_p, tile_sum_b, norm_b);
+ 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)
@@ -588,7 +587,7 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
}
if (!wall_is_screen_edge(tiles, glmth_rect_get_edge(tile_aabb, RECT_EDGE_TOP)) && !wall_is_internal(tiles, glmth_rect_get_edge(tile_aabb, RECT_EDGE_TOP)))
{
- struct WallCollision top = get_wall_collision(player->pos, new_p, tile_sum_t, norm_t);
+ 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)
@@ -605,7 +604,7 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
}
if (!wall_is_screen_edge(tiles, glmth_rect_get_edge(tile_aabb, RECT_EDGE_LEFT)) && !wall_is_internal(tiles, glmth_rect_get_edge(tile_aabb, RECT_EDGE_LEFT)))
{
- struct WallCollision left = get_wall_collision(player->pos, new_p, tile_sum_l, norm_l);
+ 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)
@@ -622,7 +621,7 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
}
if (!wall_is_screen_edge(tiles, glmth_rect_get_edge(tile_aabb, RECT_EDGE_RIGHT)) && !wall_is_internal(tiles, glmth_rect_get_edge(tile_aabb, RECT_EDGE_RIGHT)))
{
- struct WallCollision right = get_wall_collision(player->pos, new_p, tile_sum_r, norm_r);
+ struct WallCollision right = get_wall_collision(player->pos.local, new_p, tile_sum_r, norm_r);
if (right.collision_occurred)
{
if (smallest_distance_scale_factor > right.distance_scale_factor)
@@ -642,23 +641,23 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
}
v2 delta_to_nearest_collision = glmth_v2f_m(player_delta, smallest_distance_scale_factor);
- v2 nearest_collision_p = glmth_v2_a(player->pos, delta_to_nearest_collision);
+ v2 nearest_collision_p = glmth_v2_a(player->pos.local, delta_to_nearest_collision);
f32 epsilon = 0.0001f;
rect local_inhabitable_region = {
.min = {
- glmth_min(player->pos.x, nearest_collision_p.x + epsilon),
- glmth_min(player->pos.y, nearest_collision_p.y + epsilon),
+ glmth_min(player->pos.local.x, nearest_collision_p.x + epsilon),
+ glmth_min(player->pos.local.y, nearest_collision_p.y + epsilon),
},
.max = {
- glmth_max(player->pos.x, nearest_collision_p.x - epsilon),
- glmth_max(player->pos.y, nearest_collision_p.y - epsilon),
+ glmth_max(player->pos.local.x, nearest_collision_p.x - epsilon),
+ glmth_max(player->pos.local.y, nearest_collision_p.y - epsilon),
},
};
- player->pos = nearest_collision_p;
- glmth_clamp(&player->pos.x, local_inhabitable_region.min.x, local_inhabitable_region.max.x);
- glmth_clamp(&player->pos.y, local_inhabitable_region.min.y, local_inhabitable_region.max.y);
+ player->pos.local = nearest_collision_p;
+ glmth_clamp(&player->pos.local.x, local_inhabitable_region.min.x, local_inhabitable_region.max.x);
+ glmth_clamp(&player->pos.local.y, local_inhabitable_region.min.y, local_inhabitable_region.max.y);
// NOTE(amin):
// n * dot(v, n)
@@ -672,16 +671,13 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
player->velocity = glmth_v2_s(player->velocity, colliding_velocity_component);
player_delta = glmth_v2f_m(player->velocity, dt);
- new_p = glmth_v2_a(player->pos, player_delta);
+ new_p = glmth_v2_a(player->pos.local, player_delta);
remaining_time_factor -= smallest_distance_scale_factor;
}
}
#undef RENDER_COLLISION_DEBUG_QUAD
- game_state->player_pos_absolute.room_offset = player->pos;
- struct AbsolutePos new_canonical_p = pos_recanonicalize(game_state->player_pos_absolute);
- game_state->player_pos_absolute = new_canonical_p;
- player->pos = game_state->player_pos_absolute.room_offset;
+ player->pos = pos_recanonicalize(player->pos);
}
// render player
@@ -690,7 +686,7 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
struct Entity player = game_state->player;
m4 model = glmth_m4_init_id();
- model = glmth_translate(model, (v3) {player.pos.x, player.pos.y, 0.0f});
+ model = glmth_translate(model, (v3) {player.pos.local.x, player.pos.local.y, 0.0f});
model = glmth_scale(model, (v3) {player.dimensions.x, player.dimensions.y, 1.0f});
v3 color = (v3) { 1.0f, 0.0f, 1.0f };
diff --git a/src/game.h b/src/game.h
@@ -12,8 +12,11 @@
#include "shader.h"
#include "platform.h"
+// One tile is one square meter
+#define TILE_SIZE 1.0f
#define ROOM_TILE_DIM_X 25
#define ROOM_TILE_DIM_Y 10
+#define ROOM_TILE_COUNT ROOM_TILE_DIM_X * ROOM_TILE_DIM_Y
#define ROOM_ASPECT_RATIO (f32)ROOM_TILE_DIM_X / (f32)ROOM_TILE_DIM_Y
struct RendererState
@@ -25,31 +28,30 @@ struct RendererState
struct Shader shader;
};
+struct AbsolutePos
+{
+ v2i room;
+ v2 local;
+};
+
struct Entity
{
+ struct AbsolutePos pos;
v2 acceleration;
v2 velocity;
- v2 pos;
v2 dimensions;
};
struct Room
{
v2i index;
- u32 tiles[ROOM_TILE_DIM_Y * ROOM_TILE_DIM_X];
-};
-
-struct AbsolutePos
-{
- v2i room_index;
- v2 room_offset;
+ u32 tiles[ROOM_TILE_COUNT];
};
struct GameState
{
struct RendererState renderer;
struct Entity player;
- struct AbsolutePos player_pos_absolute;
};
internal void game_init(struct GameMemory *game_memory, v2u framebuffer);