commit c7a57149e4dd3faee96fa81f92e7d23a9a181630
parent c9251221fc319bf126f25bf9b706b943a76ad6a2
Author: amin <dev@aminmesbah.com>
Date:   Tue, 30 Apr 2019 04:01:58 +0000
Split some code out into new files
FossilOrigin-Name: afc6d004125b330cca89179671fd1990838767e358bff799b88783b57438d209
Diffstat:
| A | src/collision.c |  |  | 61 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 
| M | src/game.c |  |  | 219 | ++++--------------------------------------------------------------------------- | 
| M | src/game.h |  |  | 20 | +------------------- | 
| A | src/world.c |  |  | 138 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 
| A | src/world.h |  |  | 18 | ++++++++++++++++++ | 
5 files changed, 227 insertions(+), 229 deletions(-)
diff --git a/src/collision.c b/src/collision.c
@@ -0,0 +1,61 @@
+struct WallCollision
+{
+    bool collision_occurred;
+    f32 distance_scale_factor;
+};
+
+internal struct WallCollision get_wall_collision(v2 entity_p_initial, v2 entity_p_final, segment wall, v2 wall_normal)
+
+{
+    struct WallCollision result = {0};
+    result.collision_occurred = false;
+
+    assert(math_v2_le(wall.min, wall.max));
+
+    bool wall_is_horizontal = wall.min.y == wall.max.y;
+    bool wall_is_vertical = wall.min.x == wall.max.x;
+    assert(wall_is_horizontal || wall_is_vertical);
+
+    enum VectorAxis wall_axis = AXIS_X;
+    enum VectorAxis wall_normal_axis = AXIS_Y;
+    if (wall_is_vertical)
+    {
+        wall_axis = AXIS_Y;
+        wall_normal_axis = AXIS_X;
+    }
+
+    v2 player_delta = math_v2_s(entity_p_final, entity_p_initial);
+
+    // NOTE(amin): We needn't normalize player_delta here because its magnitude
+    // becomes irrelevant as the value of cos(theta) nears zero, and we are
+    // concerned only about the behavior near pi/2 and 3pi/2, where cos(theta)
+    // is zero. Therefore we simply treat player_delta as if it _were_
+    // normalized.
+    f32 cos_theta = math_v2_dot(player_delta, wall_normal);
+
+    bool theta_is_obtuse = cos_theta < 0.0f;
+    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];
+        v2 collision_point = math_v2_a(entity_p_initial, math_v2f_m(player_delta, segment_scale_factor));
+
+        if (math_in_interval_open(segment_scale_factor, 0.0f, 1.0f))
+        {
+            if (math_in_interval_open(
+                    collision_point.E[wall_axis],
+                    wall.min.E[wall_axis],
+                    wall.max.E[wall_axis]))
+            {
+                result.collision_occurred = true;
+                result.distance_scale_factor = math_max(0.0f, segment_scale_factor);
+            }
+        }
+    }
+
+    return result;
+}
diff --git a/src/game.c b/src/game.c
@@ -2,13 +2,8 @@
 #include "glad.c"
 #include "shader.c"
 #include "memory.c"
-
-#ifdef PLATFORM_HOTLOAD_GAME_CODE
-void game_load_opengl_symbols(void)
-{
-    gladLoadGL();
-}
-#endif
+#include "collision.c"
+#include "world.c"
 
 internal void game_init(struct GameMemory *game_memory, v2u framebuffer)
 {
@@ -30,10 +25,8 @@ internal void game_init(struct GameMemory *game_memory, v2u framebuffer)
         game_memory->buffer + sizeof(struct GameState),
         game_memory->buffer_size - sizeof(struct GameState));
 
-
     game_state->world = mem_st_alloc_struct(&game_state->world_allocator, struct World);
 
-
     struct Room knytt_hanging_fly_village = {
         .index = {0, 0},
         .tiles = {
@@ -134,207 +127,6 @@ internal void game_init(struct GameMemory *game_memory, v2u framebuffer)
     }
 }
 
-internal struct AbsolutePos pos_recanonicalize(struct AbsolutePos p)
-{
-    struct AbsolutePos p_final = p;
-    v2i room_index_delta = {0};
-
-    if (p.local.x < 0.0f)
-    {
-        room_index_delta.x -= 1;
-        p_final.local.x = math_wrap(p.local.x, 0.0f, ROOM_TILE_DIM_X);
-    }
-    else if (p.local.x > ROOM_TILE_DIM_X)
-    {
-        room_index_delta.x += 1;
-        p_final.local.x = math_wrap(p.local.x, 0.0f, ROOM_TILE_DIM_X);
-    }
-
-    if (p.local.y < 0.0f)
-    {
-        room_index_delta.y -= 1;
-        p_final.local.y = math_wrap(p.local.y, 0.0f, ROOM_TILE_DIM_Y);
-    }
-    else if (p.local.y > ROOM_TILE_DIM_Y)
-    {
-        room_index_delta.y += 1;
-        p_final.local.y = math_wrap(p.local.y, 0.0f, ROOM_TILE_DIM_Y);
-    }
-
-    p_final.room = math_v2i_a(p.room, room_index_delta);
-    return p_final;
-}
-
-struct RoomSearchResult
-{
-    bool room_found;
-    size_t room_array_index;
-};
-
-internal struct RoomSearchResult get_room_at_index(struct Room *rooms, u32 num_rooms, v2i room_i)
-{
-    struct RoomSearchResult result = {0};
-    for (size_t i = 0; i < num_rooms; i++)
-    {
-        struct Room *r = &rooms[i];
-        if (r->index.x == room_i.x && r->index.y == room_i.y)
-        {
-            result.room_found = true;
-            result.room_array_index = i;
-        }
-    }
-    return result;
-}
-
-struct WallCollision
-{
-    bool collision_occurred;
-    f32 distance_scale_factor;
-};
-
-internal struct WallCollision get_wall_collision(v2 entity_p_initial, v2 entity_p_final, segment wall, v2 wall_normal)
-
-{
-    struct WallCollision result = {0};
-    result.collision_occurred = false;
-
-    assert(math_v2_le(wall.min, wall.max));
-
-    bool wall_is_horizontal = wall.min.y == wall.max.y;
-    bool wall_is_vertical = wall.min.x == wall.max.x;
-    assert(wall_is_horizontal || wall_is_vertical);
-
-    enum VectorAxis wall_axis = AXIS_X;
-    enum VectorAxis wall_normal_axis = AXIS_Y;
-    if (wall_is_vertical)
-    {
-        wall_axis = AXIS_Y;
-        wall_normal_axis = AXIS_X;
-    }
-
-    v2 player_delta = math_v2_s(entity_p_final, entity_p_initial);
-
-    // NOTE(amin): We needn't normalize player_delta here because its magnitude
-    // becomes irrelevant as the value of cos(theta) nears zero, and we are
-    // concerned only about the behavior near pi/2 and 3pi/2, where cos(theta)
-    // is zero. Therefore we simply treat player_delta as if it _were_
-    // normalized.
-    f32 cos_theta = math_v2_dot(player_delta, wall_normal);
-
-    bool theta_is_obtuse = cos_theta < 0.0f;
-    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];
-        v2 collision_point = math_v2_a(entity_p_initial, math_v2f_m(player_delta, segment_scale_factor));
-
-        if (math_in_interval_open(segment_scale_factor, 0.0f, 1.0f))
-        {
-            if (math_in_interval_open(
-                    collision_point.E[wall_axis],
-                    wall.min.E[wall_axis],
-                    wall.max.E[wall_axis]))
-            {
-                result.collision_occurred = true;
-                result.distance_scale_factor = math_max(0.0f, segment_scale_factor);
-            }
-        }
-    }
-
-    return result;
-}
-
-internal u32 get_tile_value(u32 *tiles, v2 tile_pos)
-{
-    assert(tiles);
-
-    v2u tile_i_2d = {
-        tile_pos.x,
-        ROOM_TILE_DIM_Y - 1.0f - tile_pos.y,
-    };
-
-    assert(math_v2_lt(
-        (v2) {tile_i_2d.x, tile_i_2d.y},
-        (v2) {ROOM_TILE_DIM_X, ROOM_TILE_DIM_Y}));
-
-    assert(math_v2_ge(
-        (v2) {tile_i_2d.x, tile_i_2d.y},
-        (v2) {0}));
-
-    u32 tile_i_linearized = (ROOM_TILE_DIM_X * tile_i_2d.y) + tile_i_2d.x;
-    assert(tile_i_linearized < ROOM_TILE_COUNT);
-
-    u32 tile_value = tiles[tile_i_linearized];
-    return tile_value;
-}
-
-internal bool tile_is_solid(u32 *tiles, v2 tile_pos)
-{
-    assert(tiles);
-
-    bool is_solid = false;
-    u32 tile_value = get_tile_value(tiles, tile_pos);
-    is_solid = tile_value > 0;
-    return is_solid;
-}
-
-internal bool wall_is_screen_edge(u32 *tiles, segment wall)
-{
-    assert(tiles);
-
-    bool is_screen_edge = false;
-    bool wall_is_horizontal = wall.min.y == wall.max.y;
-    bool wall_is_vertical = wall.min.x == wall.max.x;
-
-    assert(wall_is_vertical || wall_is_horizontal);
-    assert(math_v2_ge(wall.min, (v2) {0}));
-    assert(math_v2_le(wall.max, (v2) {ROOM_TILE_DIM_X, ROOM_TILE_DIM_Y}));
-
-    if (wall_is_vertical)
-    {
-        is_screen_edge = wall.min.x == 0.0f || wall.min.x == ROOM_TILE_DIM_X;
-    }
-    else
-    {
-        is_screen_edge = wall.min.y == 0.0f || wall.min.y == ROOM_TILE_DIM_Y;
-    }
-
-    return is_screen_edge;
-}
-
-internal bool wall_is_internal(u32 *tiles, segment wall)
-{
-    assert(tiles);
-
-    bool is_internal = false;
-    bool wall_is_horizontal = wall.min.y == wall.max.y;
-    bool wall_is_vertical = wall.min.x == wall.max.x;
-
-    assert(wall_is_vertical || wall_is_horizontal);
-
-    v2 lesser_neighbor = {0};
-    v2 greater_neighbor = {0};
-
-    if (wall_is_vertical)
-    {
-        lesser_neighbor = (v2) {wall.min.x - TILE_SIZE, wall.min.y};
-        greater_neighbor = wall.min;
-        is_internal = tile_is_solid(tiles, lesser_neighbor) && tile_is_solid(tiles, greater_neighbor);
-    }
-    else
-    {
-        lesser_neighbor = (v2) {wall.min.x, wall.min.y - TILE_SIZE};
-        greater_neighbor = wall.min;
-        is_internal = tile_is_solid(tiles, lesser_neighbor) && tile_is_solid(tiles, greater_neighbor);
-    }
-
-    return is_internal;
-}
-
 // NOTE(amin): For now updating and rendering are interleaved. We simulate the
 // world at the same rate we render it. Our timestep is not fixed. We may want
 // to change this in the future.
@@ -750,3 +542,10 @@ internal void render_debug_quad(struct GameState *game_state, rect r, v3 color, 
 
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, initial_ebo);
 }
+
+#ifdef PLATFORM_HOTLOAD_GAME_CODE
+void game_load_opengl_symbols(void)
+{
+    gladLoadGL();
+}
+#endif
diff --git a/src/game.h b/src/game.h
@@ -12,14 +12,11 @@
 #include "am_math.h"
 #include "shader.h"
 #include "memory.h"
+#include "world.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
 {
@@ -44,21 +41,6 @@ struct Entity
     v2 dimensions;
 };
 
-struct Room
-{
-    v2i index;
-    u32 tiles[ROOM_TILE_COUNT];
-};
-
-// TODO: delete
-#define MAX_ROOMS 120
-
-struct World
-{
-    struct Room rooms[MAX_ROOMS];
-    u32 num_rooms;
-};
-
 struct GameState
 {
     struct RendererState renderer;
diff --git a/src/world.c b/src/world.c
@@ -0,0 +1,138 @@
+internal struct AbsolutePos pos_recanonicalize(struct AbsolutePos p)
+{
+    struct AbsolutePos p_final = p;
+    v2i room_index_delta = {0};
+
+    if (p.local.x < 0.0f)
+    {
+        room_index_delta.x -= 1;
+        p_final.local.x = math_wrap(p.local.x, 0.0f, ROOM_TILE_DIM_X);
+    }
+    else if (p.local.x > ROOM_TILE_DIM_X)
+    {
+        room_index_delta.x += 1;
+        p_final.local.x = math_wrap(p.local.x, 0.0f, ROOM_TILE_DIM_X);
+    }
+
+    if (p.local.y < 0.0f)
+    {
+        room_index_delta.y -= 1;
+        p_final.local.y = math_wrap(p.local.y, 0.0f, ROOM_TILE_DIM_Y);
+    }
+    else if (p.local.y > ROOM_TILE_DIM_Y)
+    {
+        room_index_delta.y += 1;
+        p_final.local.y = math_wrap(p.local.y, 0.0f, ROOM_TILE_DIM_Y);
+    }
+
+    p_final.room = math_v2i_a(p.room, room_index_delta);
+    return p_final;
+}
+
+struct RoomSearchResult
+{
+    bool room_found;
+    size_t room_array_index;
+};
+
+internal struct RoomSearchResult get_room_at_index(struct Room *rooms, u32 num_rooms, v2i room_i)
+{
+    struct RoomSearchResult result = {0};
+    for (size_t i = 0; i < num_rooms; i++)
+    {
+        struct Room *r = &rooms[i];
+        if (r->index.x == room_i.x && r->index.y == room_i.y)
+        {
+            result.room_found = true;
+            result.room_array_index = i;
+        }
+    }
+    return result;
+}
+
+internal u32 get_tile_value(u32 *tiles, v2 tile_pos)
+{
+    assert(tiles);
+
+    v2u tile_i_2d = {
+        tile_pos.x,
+        ROOM_TILE_DIM_Y - 1.0f - tile_pos.y,
+    };
+
+    assert(math_v2_lt(
+        (v2) {tile_i_2d.x, tile_i_2d.y},
+        (v2) {ROOM_TILE_DIM_X, ROOM_TILE_DIM_Y}));
+
+    assert(math_v2_ge(
+        (v2) {tile_i_2d.x, tile_i_2d.y},
+        (v2) {0}));
+
+    u32 tile_i_linearized = (ROOM_TILE_DIM_X * tile_i_2d.y) + tile_i_2d.x;
+    assert(tile_i_linearized < ROOM_TILE_COUNT);
+
+    u32 tile_value = tiles[tile_i_linearized];
+    return tile_value;
+}
+
+internal bool tile_is_solid(u32 *tiles, v2 tile_pos)
+{
+    assert(tiles);
+
+    bool is_solid = false;
+    u32 tile_value = get_tile_value(tiles, tile_pos);
+    is_solid = tile_value > 0;
+    return is_solid;
+}
+
+internal bool wall_is_screen_edge(u32 *tiles, segment wall)
+{
+    assert(tiles);
+
+    bool is_screen_edge = false;
+    bool wall_is_horizontal = wall.min.y == wall.max.y;
+    bool wall_is_vertical = wall.min.x == wall.max.x;
+
+    assert(wall_is_vertical || wall_is_horizontal);
+    assert(math_v2_ge(wall.min, (v2) {0}));
+    assert(math_v2_le(wall.max, (v2) {ROOM_TILE_DIM_X, ROOM_TILE_DIM_Y}));
+
+    if (wall_is_vertical)
+    {
+        is_screen_edge = wall.min.x == 0.0f || wall.min.x == ROOM_TILE_DIM_X;
+    }
+    else
+    {
+        is_screen_edge = wall.min.y == 0.0f || wall.min.y == ROOM_TILE_DIM_Y;
+    }
+
+    return is_screen_edge;
+}
+
+internal bool wall_is_internal(u32 *tiles, segment wall)
+{
+    assert(tiles);
+
+    bool is_internal = false;
+    bool wall_is_horizontal = wall.min.y == wall.max.y;
+    bool wall_is_vertical = wall.min.x == wall.max.x;
+
+    assert(wall_is_vertical || wall_is_horizontal);
+
+    v2 lesser_neighbor = {0};
+    v2 greater_neighbor = {0};
+
+    if (wall_is_vertical)
+    {
+        lesser_neighbor = (v2) {wall.min.x - TILE_SIZE, wall.min.y};
+        greater_neighbor = wall.min;
+        is_internal = tile_is_solid(tiles, lesser_neighbor) && tile_is_solid(tiles, greater_neighbor);
+    }
+    else
+    {
+        lesser_neighbor = (v2) {wall.min.x, wall.min.y - TILE_SIZE};
+        greater_neighbor = wall.min;
+        is_internal = tile_is_solid(tiles, lesser_neighbor) && tile_is_solid(tiles, greater_neighbor);
+    }
+
+    return is_internal;
+}
diff --git a/src/world.h b/src/world.h
@@ -0,0 +1,18 @@
+// TODO: delete
+#define MAX_ROOMS 120
+#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 Room
+{
+    v2i index;
+    u32 tiles[ROOM_TILE_COUNT];
+};
+
+struct World
+{
+    struct Room rooms[MAX_ROOMS];
+    u32 num_rooms;
+};