commit c9251221fc319bf126f25bf9b706b943a76ad6a2
parent dd1e59ec2efc9f5403dacbc0891276461618de6b
Author: amin <dev@aminmesbah.com>
Date:   Tue, 30 Apr 2019 03:49:51 +0000
Add a stack allocator and store rooms on the heap
FossilOrigin-Name: a13f61e35a13d77932938f63607a60c2b8168a677557da6c1a7cf104bd1452a8
Diffstat:
6 files changed, 124 insertions(+), 48 deletions(-)
diff --git a/src/am_math.h b/src/am_math.h
@@ -570,6 +570,12 @@ internal inline bool math_v2_ge(v2 v, v2 compare)
     return is_ge;
 }
 
+internal inline bool math_is_pow_2(u64 n)
+{
+    bool is_pow_2 = (n & (n - 1)) == 0;
+    return is_pow_2;
+}
+
 internal inline void math_v2_print(v2 v)
 {
     printf("( %f, %f )\n", v.x, v.y);
diff --git a/src/game.c b/src/game.c
@@ -1,9 +1,7 @@
 #include "game.h"
 #include "glad.c"
 #include "shader.c"
-
-// TODO: delete
-#define NUM_ROOMS 2
+#include "memory.c"
 
 #ifdef PLATFORM_HOTLOAD_GAME_CODE
 void game_load_opengl_symbols(void)
@@ -27,6 +25,53 @@ internal void game_init(struct GameMemory *game_memory, v2u framebuffer)
     // These dimensions are relative to a square 'meter', one tile
     game_state->player.dimensions = (v2) {0.375f, 0.583f};
 
+    mem_st_init(
+        &game_state->world_allocator,
+        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 = {
+            1, 1, 1, 1, 1,  1, 1, 0, 1, 1,  1, 1, 1, 1, 1,  1, 1, 1, 0, 1,  1, 1, 1, 1, 1,
+            1, 1, 1, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 1, 1,  1, 1, 1, 0, 1,  1, 1, 1, 1, 1,
+            1, 1, 1, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 1, 1,  1, 1, 1, 0, 1,  1, 1, 1, 1, 1,
+            1, 1, 1, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 1, 1,  1, 1, 1, 0, 1,  1, 1, 1, 1, 1,
+            0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 1,  1, 1, 0, 0, 0,
+
+            0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 1,  1, 1, 0, 0, 0,
+            0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 1,  1, 1, 0, 0, 0,
+            0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 0,
+            1, 1, 1, 1, 1,  1, 1, 1, 1, 1,  1, 1, 1, 1, 1,  1, 1, 1, 1, 1,  1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1,  1, 1, 1, 1, 1,  1, 1, 1, 1, 1,  1, 1, 1, 1, 1,  1, 1, 1, 1, 1,
+        },
+    };
+
+    struct Room collision_test_zone = {
+        .index = {0, 1},
+        .tiles = {
+            0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 0,
+            0, 1, 1, 1, 1,  1, 1, 1, 1, 1,  1, 1, 1, 1, 1,  1, 1, 1, 1, 1,  1, 1, 1, 1, 0,
+            0, 1, 0, 0, 1,  0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  1, 0, 0, 1, 0,
+            0, 1, 0, 1, 1,  0, 0, 1, 0, 0,  0, 1, 0, 1, 0,  0, 0, 1, 0, 0,  1, 1, 0, 1, 0,
+            0, 1, 0, 1, 1,  0, 0, 0, 0, 0,  1, 0, 0, 0, 1,  0, 0, 0, 0, 0,  1, 1, 0, 1, 0,
+
+            0, 1, 0, 1, 1,  0, 0, 0, 0, 0,  1, 0, 0, 0, 1,  0, 0, 0, 0, 0,  1, 1, 0, 1, 0,
+            0, 1, 0, 1, 1,  0, 0, 1, 0, 0,  0, 1, 1, 1, 0,  0, 0, 1, 0, 0,  1, 1, 0, 1, 0,
+            0, 1, 0, 1, 1,  0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  1, 1, 0, 1, 0,
+            0, 1, 0, 1, 1,  1, 1, 1, 1, 1,  1, 1, 0, 1, 1,  1, 1, 1, 1, 1,  1, 1, 0, 1, 0,
+            0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 0,
+        },
+    };
+
+    game_state->world->rooms[0] = collision_test_zone;
+    game_state->world->rooms[1] = knytt_hanging_fly_village;
+    game_state->world->num_rooms = 2;
+
     // set up and load tiles
     {
         GLfloat quad_vertices[] = {
@@ -126,12 +171,12 @@ struct RoomSearchResult
     size_t room_array_index;
 };
 
-internal struct RoomSearchResult get_room_at_index(struct Room *rooms[NUM_ROOMS], u32 num_rooms, v2i room_i)
+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];
+        struct Room *r = &rooms[i];
         if (r->index.x == room_i.x && r->index.y == room_i.y)
         {
             result.room_found = true;
@@ -345,49 +390,11 @@ void game_update_and_render(struct GameMemory *game_memory, struct GameInput *ga
     // Screen origin is in the upper left
     m4 projection = math_projection_ortho(0.0f, framebuffer.width, framebuffer.height, 0.0f, -1.0f, 0.0f);
 
-    struct Room knytt_hanging_fly_village = {
-        .index = {0, 0},
-        .tiles = {
-            1, 1, 1, 1, 1,  1, 1, 0, 1, 1,  1, 1, 1, 1, 1,  1, 1, 1, 0, 1,  1, 1, 1, 1, 1,
-            1, 1, 1, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 1, 1,  1, 1, 1, 0, 1,  1, 1, 1, 1, 1,
-            1, 1, 1, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 1, 1,  1, 1, 1, 0, 1,  1, 1, 1, 1, 1,
-            1, 1, 1, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 1, 1,  1, 1, 1, 0, 1,  1, 1, 1, 1, 1,
-            0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 1,  1, 1, 0, 0, 0,
-
-            0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 1,  1, 1, 0, 0, 0,
-            0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 1,  1, 1, 0, 0, 0,
-            0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 0,
-            1, 1, 1, 1, 1,  1, 1, 1, 1, 1,  1, 1, 1, 1, 1,  1, 1, 1, 1, 1,  1, 1, 1, 1, 1,
-            1, 1, 1, 1, 1,  1, 1, 1, 1, 1,  1, 1, 1, 1, 1,  1, 1, 1, 1, 1,  1, 1, 1, 1, 1,
-        },
-    };
-
-    struct Room collision_test_zone = {
-        .index = {0, 1},
-        .tiles = {
-            0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 0,
-            0, 1, 1, 1, 1,  1, 1, 1, 1, 1,  1, 1, 1, 1, 1,  1, 1, 1, 1, 1,  1, 1, 1, 1, 0,
-            0, 1, 0, 0, 1,  0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  1, 0, 0, 1, 0,
-            0, 1, 0, 1, 1,  0, 0, 1, 0, 0,  0, 1, 0, 1, 0,  0, 0, 1, 0, 0,  1, 1, 0, 1, 0,
-            0, 1, 0, 1, 1,  0, 0, 0, 0, 0,  1, 0, 0, 0, 1,  0, 0, 0, 0, 0,  1, 1, 0, 1, 0,
-
-            0, 1, 0, 1, 1,  0, 0, 0, 0, 0,  1, 0, 0, 0, 1,  0, 0, 0, 0, 0,  1, 1, 0, 1, 0,
-            0, 1, 0, 1, 1,  0, 0, 1, 0, 0,  0, 1, 1, 1, 0,  0, 0, 1, 0, 0,  1, 1, 0, 1, 0,
-            0, 1, 0, 1, 1,  0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  1, 1, 0, 1, 0,
-            0, 1, 0, 1, 1,  1, 1, 1, 1, 1,  1, 1, 0, 1, 1,  1, 1, 1, 1, 1,  1, 1, 0, 1, 0,
-            0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 0,  0, 0, 0, 0, 0,
-        },
-    };
-
-    // 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.room;
-    struct RoomSearchResult r = get_room_at_index(rooms, NUM_ROOMS, current_room_i);
+    struct RoomSearchResult r = get_room_at_index(game_state->world->rooms, game_state->world->num_rooms, current_room_i);
     assert(r.room_found);
-    struct Room *current_room = rooms[r.room_array_index];
-    assert(current_room);
-    u32 *tiles = current_room->tiles;
+    struct Room current_room = game_state->world->rooms[r.room_array_index];
+    u32 *tiles = current_room.tiles;
 
     // render tiles
     {
diff --git a/src/game.h b/src/game.h
@@ -1,5 +1,6 @@
 #include <assert.h>
 #include <math.h>
+#include <stdalign.h>
 #include <stdbool.h>
 #include <stdint.h>
 #include <stdio.h>
@@ -10,6 +11,7 @@
 #include "types.h"
 #include "am_math.h"
 #include "shader.h"
+#include "memory.h"
 #include "platform.h"
 
 // One tile is one square meter
@@ -48,11 +50,21 @@ struct Room
     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;
     struct Entity player;
-    struct Room *rooms;
+    struct StackAllocator world_allocator;
+    struct World *world;
 };
 
 internal void game_init(struct GameMemory *game_memory, v2u framebuffer);
diff --git a/src/memory.c b/src/memory.c
@@ -0,0 +1,45 @@
+#define mem_st_alloc_struct(allocator, type) mem_st_alloc((allocator), sizeof(type), alignof(type))
+
+// TODO: test that alignment is working properly
+internal inline uintptr_t mem_align_address(uintptr_t address, size_t alignment)
+{
+    assert(math_is_pow_2(alignment));
+    // This works since we've asserted alignment is a power of 2
+    size_t mask = alignment - 1;
+    uintptr_t result = (address + mask) & ~mask;
+    return result;
+}
+
+internal void mem_st_init(struct StackAllocator *allocator, void *backing_buffer, size_t backing_buffer_bytes)
+{
+   allocator->size = backing_buffer_bytes;
+   allocator->base = backing_buffer;
+   allocator->used = 0;
+}
+
+internal void* mem_st_alloc(struct StackAllocator *allocator, size_t bytes, size_t alignment)
+{
+    size_t worst_case_bytes = bytes + alignment - 1;
+    assert(allocator->used + worst_case_bytes <= allocator->size);
+
+    allocator->used += worst_case_bytes;
+    uintptr_t current_head = (uintptr_t)allocator->base + allocator->used;
+    void *address = (void *)mem_align_address(current_head, alignment);
+    return address;
+}
+
+internal size_t mem_st_get_marker(struct StackAllocator *allocator)
+{
+    size_t marker = allocator->used;
+    return marker;
+}
+
+internal void mem_st_free_to_marker(struct StackAllocator *allocator, size_t marker)
+{
+    allocator->used = marker;
+}
+
+internal void mem_st_free_all(struct StackAllocator *allocator)
+{
+    allocator->used = 0;
+}
diff --git a/src/memory.h b/src/memory.h
@@ -0,0 +1,6 @@
+struct StackAllocator
+{
+    u8 *base;
+    size_t size;
+    size_t used;
+};
diff --git a/src/platform_linux.c b/src/platform_linux.c
@@ -280,7 +280,7 @@ internal struct GameCode load_game_code(char *source_lib_path)
             // In this case, we are protected by POSIX, which specifies that
             // function and data pointers must be the same size. We will only ever
             // be using dlsym on POSIX-compliant platforms.
-            _Static_assert(
+            static_assert(
                 sizeof(void *) == sizeof(void(*)()),
                 "Object pointer must be the same size as function pointer"
             );