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"
);