load maps into a struct instead of a global to allow for multiple to be loaded at once
This commit is contained in:
+114
-97
@@ -155,10 +155,14 @@ struct Instance {
|
||||
|
||||
static Instance player_instance = { { 0.0f, 0.0f }, { 0, 0, 1, 0 }, { 1, 1, 0, 1 }};
|
||||
|
||||
static Sint32 map_width;
|
||||
static Sint32 map_height;
|
||||
struct Map {
|
||||
Sint32 width;
|
||||
Sint32 height;
|
||||
|
||||
static Uint32* map_tiles;
|
||||
Uint32 *tiles;
|
||||
};
|
||||
|
||||
static Map current_map;
|
||||
|
||||
struct Player {
|
||||
Sint32 pos_x;
|
||||
@@ -170,7 +174,7 @@ static Player player;
|
||||
struct PerFrame {
|
||||
Sint32 drag_start[2];
|
||||
Sint32 mouse[2];
|
||||
Uint32 map_width;
|
||||
Sint32 map_width;
|
||||
};
|
||||
|
||||
static PerFrame per_frame = {};
|
||||
@@ -213,64 +217,73 @@ static Sint32 selected_rotation = 0;
|
||||
static bool dragging_tile_change = false;
|
||||
static Sint32 drag_start_pos[2];
|
||||
|
||||
static void save_map() {
|
||||
log("Save file is under construction.");
|
||||
FILE* file = fopen("../assets/map/map.sv", "wb");
|
||||
|
||||
static bool save_map(const char *path, Map map) {
|
||||
SDL_IOStream *file = SDL_IOFromFile(path, "wb");
|
||||
if (!file) {
|
||||
log_error("Save file creation has failed.");
|
||||
return;
|
||||
log_error("Failed to open map file for writing.");
|
||||
return false;
|
||||
}
|
||||
defer(fclose(file));
|
||||
defer(SDL_CloseIO(file));
|
||||
|
||||
if (fwrite(&map_width, sizeof(Uint32), 1, file) != 1) {
|
||||
log_error("fwrite for map_width has failed.");
|
||||
return;
|
||||
if (!SDL_WriteS32LE(file, map.width)) {
|
||||
log_error("Failed to write width to map file.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fwrite(&map_height, sizeof(Uint32), 1, file) != 1) {
|
||||
log_error("fwrite for map_height has failed.");
|
||||
return;
|
||||
if (!SDL_WriteS32LE(file, map.height)) {
|
||||
log_error("Failed to write height to map file.");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < map_width * map_height; i++) {
|
||||
Uint32 type = tile_infos[map_tiles[i] & 0xffff].type;
|
||||
Uint32 orientation = (map_tiles[i] & 0x30000) >> 16;
|
||||
for (int i = 0; i < map.width * map.height; i++) {
|
||||
Uint32 type = tile_infos[map.tiles[i] & 0xffff].type;
|
||||
Uint32 orientation = map.tiles[i] & 0x30000;
|
||||
|
||||
Uint32 to_write = (orientation << 16) | type;
|
||||
if (fwrite(&to_write, sizeof(Uint32), 1, file) != 1) {
|
||||
log_error("fwrite for tile_type at tile number %d has failed.", i);
|
||||
return;
|
||||
Uint32 to_write = orientation | type;
|
||||
if (!SDL_WriteU32LE(file, to_write)) {
|
||||
log_error("Failed to write tile to map file.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
log("Saving map was successful.");
|
||||
if(!SDL_FlushIO(file)) {
|
||||
log_error("Failed to flush data to map file.");
|
||||
return false;
|
||||
};
|
||||
|
||||
log("Saved map file.");
|
||||
return true;
|
||||
}
|
||||
|
||||
static void load_map() {
|
||||
log("Load save file.");
|
||||
String file = load_entire_file("../assets/map/map.sv");
|
||||
if (!file.length) {
|
||||
log_error("Loading save file has failed.");
|
||||
return;
|
||||
static bool load_map(const char *path, Map *result) {
|
||||
SDL_IOStream *file = SDL_IOFromFile(path, "rb");
|
||||
if (!file) {
|
||||
log_error("Failed to open map file for reading.");
|
||||
return false;
|
||||
}
|
||||
defer(SDL_CloseIO(file));
|
||||
|
||||
if (!SDL_ReadS32LE(file, &result->width)) {
|
||||
log_error("Failed read width from map file.");
|
||||
return false;
|
||||
}
|
||||
|
||||
map_width = read<Uint32>(file);
|
||||
map_height = read<Uint32>(file);
|
||||
if (file.length != map_width * map_height * sizeof(Uint32)) {
|
||||
log_error("Incorrect file.length.");
|
||||
return;
|
||||
if (!SDL_ReadS32LE(file, &result->height)) {
|
||||
log_error("Failed read height from map file.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (map_tiles)
|
||||
free(map_tiles);
|
||||
result->tiles = (Uint32*)malloc(result->width * result->height * sizeof(Uint32));
|
||||
|
||||
map_tiles = (Uint32*)malloc(map_width * map_height * sizeof(Uint32));
|
||||
for (int i = 0; i < result->width * result->height; i++) {
|
||||
Uint32 tile = 0;
|
||||
if (!SDL_ReadU32LE(file, &tile)) {
|
||||
free(result->tiles);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < map_width * map_height; i++) {
|
||||
Uint32 to_read = read<Uint32>(file);
|
||||
Uint32 type = to_read & 0xffff;
|
||||
Uint32 orientation = (to_read & 0x30000) >> 16;
|
||||
Uint32 type = tile & 0xffff;
|
||||
Uint32 orientation = tile & 0x30000;
|
||||
|
||||
Uint32 kind = 0;
|
||||
for (int i = 0; i < SDL_arraysize(tile_infos); i++) {
|
||||
@@ -280,10 +293,11 @@ static void load_map() {
|
||||
}
|
||||
}
|
||||
|
||||
map_tiles[i] = (orientation << 16) | kind;
|
||||
result->tiles[i] = orientation | kind;
|
||||
}
|
||||
|
||||
log("Loading map was successful.");
|
||||
log("Loaded map file.");
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool update_buffer(SDL_GPUBuffer *buffer, Uint32 offset, Uint32 num_bytes, void *data) {
|
||||
@@ -368,25 +382,25 @@ static SDL_GPUBuffer *create_buffer(SDL_GPUBufferUsageFlags usage, Uint32 num_by
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static void change_map_size(char direction, int amount) {
|
||||
static void change_map_size(Map *map, char direction, int amount) {
|
||||
SDL_GPUBuffer *old_world_buffer = world_buffer;
|
||||
Uint32* old_map = map_tiles;
|
||||
auto old_map_width = map_width;
|
||||
auto old_map_height = map_height;
|
||||
Uint32* old_map = map->tiles;
|
||||
Sint32 old_map_width = map->width;
|
||||
Sint32 old_map_height = map->height;
|
||||
|
||||
Sint32 new_x_offset = 0;
|
||||
Sint32 new_y_offset = 0;
|
||||
Sint32 old_x_offset = 0;
|
||||
Sint32 old_y_offset = 0;
|
||||
|
||||
Sint32 to_fill_width = map_width;
|
||||
Sint32 to_fill_height = map_height;
|
||||
Sint32 to_fill_width = map->width;
|
||||
Sint32 to_fill_height = map->height;
|
||||
Sint32 to_fill_x_offset = 0;
|
||||
Sint32 to_fill_y_offset = 0;
|
||||
|
||||
if (direction == 'W') {
|
||||
player.pos_x = player.pos_x + amount;
|
||||
map_width += amount;
|
||||
map->width += amount;
|
||||
to_fill_width = amount;
|
||||
|
||||
if (amount < 0)
|
||||
@@ -397,7 +411,7 @@ static void change_map_size(char direction, int amount) {
|
||||
|
||||
if (direction == 'N') {
|
||||
player.pos_y = player.pos_y + amount;
|
||||
map_height += amount;
|
||||
map->height += amount;
|
||||
to_fill_height = amount;
|
||||
|
||||
if (amount < 0)
|
||||
@@ -407,35 +421,35 @@ static void change_map_size(char direction, int amount) {
|
||||
}
|
||||
|
||||
if (direction == 'E') {
|
||||
map_width += amount;
|
||||
map->width += amount;
|
||||
to_fill_width = amount;
|
||||
to_fill_x_offset = old_map_width;
|
||||
}
|
||||
|
||||
if (direction == 'S') {
|
||||
map_height += amount;
|
||||
map->height += amount;
|
||||
to_fill_height = amount;
|
||||
to_fill_y_offset = old_map_height;
|
||||
}
|
||||
|
||||
map_tiles = (Uint32*)malloc(map_width * map_height * sizeof(Uint32));
|
||||
map->tiles = (Uint32*)malloc(map->width * map->height * sizeof(Uint32));
|
||||
|
||||
for (int y = 0; y < min(old_map_height, map_height); y++) {
|
||||
for (int x = 0; x < min(old_map_width, map_width); x++) {
|
||||
map_tiles[(y + new_y_offset) * map_width + (x + new_x_offset)] = old_map[(y + old_y_offset) * old_map_width + (x + old_x_offset)];
|
||||
for (int y = 0; y < min(old_map_height, map->height); y++) {
|
||||
for (int x = 0; x < min(old_map_width, map->width); x++) {
|
||||
map->tiles[(y + new_y_offset) * map->width + (x + new_x_offset)] = old_map[(y + old_y_offset) * old_map_width + (x + old_x_offset)];
|
||||
}
|
||||
}
|
||||
|
||||
for (int y = 0; y < to_fill_height; y++) {
|
||||
for (int x = 0; x < to_fill_width; x++) {
|
||||
map_tiles[(y + to_fill_y_offset) * map_width + (x + to_fill_x_offset)] = 1;
|
||||
map->tiles[(y + to_fill_y_offset) * map->width + (x + to_fill_x_offset)] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
player.pos_x = clamp(0, player.pos_x, map_width - 1);
|
||||
player.pos_y = clamp(0, player.pos_y, map_height - 1);
|
||||
player.pos_x = clamp(0, player.pos_x, map->width - 1);
|
||||
player.pos_y = clamp(0, player.pos_y, map->height - 1);
|
||||
|
||||
world_buffer = create_buffer(SDL_GPU_BUFFERUSAGE_VERTEX, map_width * map_height * 4, map_tiles, "world_buffer");
|
||||
world_buffer = create_buffer(SDL_GPU_BUFFERUSAGE_VERTEX, map->width * map->height * 4, map->tiles, "world_buffer");
|
||||
if (!world_buffer) {
|
||||
log_error("Failed to create buffer. Exiting.");
|
||||
exit(1);
|
||||
@@ -1234,7 +1248,10 @@ bool imgui_time_picker(const char *label, int time[3]) {
|
||||
int main(int argc, char **argv) {
|
||||
setup_memory_functions();
|
||||
|
||||
load_map();
|
||||
if (!load_map("../assets/map/map.sv", ¤t_map)) {
|
||||
log_error("Failed to load initial map. Exiting.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef SDL_PLATFORM_LINUX
|
||||
if (!getenv("ENABLE_VULKAN_RENDERDOC_CAPTURE"))
|
||||
@@ -1332,7 +1349,7 @@ int main(int argc, char **argv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
world_buffer = create_buffer(SDL_GPU_BUFFERUSAGE_VERTEX, map_width * map_height * 4, map_tiles, "world_buffer");
|
||||
world_buffer = create_buffer(SDL_GPU_BUFFERUSAGE_VERTEX, current_map.width * current_map.height * 4, current_map.tiles, "world_buffer");
|
||||
if (!world_buffer) {
|
||||
log_error("Failed to create buffer. Exiting.");
|
||||
return 1;
|
||||
@@ -1641,27 +1658,27 @@ int main(int argc, char **argv) {
|
||||
SDL_Keymod modifiers = SDL_GetModState();
|
||||
|
||||
if (event.key.key == SDLK_UP || event.key.key == SDLK_W) {
|
||||
player.pos_y = clamp(0, player.pos_y + 1, map_height - 2);
|
||||
player.pos_y = clamp(0, player.pos_y + 1, current_map.height - 2);
|
||||
}
|
||||
|
||||
if (event.key.key == SDLK_LEFT || event.key.key == SDLK_A) {
|
||||
player.pos_x = clamp(0, player.pos_x - 1, map_width - 2);
|
||||
player.pos_x = clamp(0, player.pos_x - 1, current_map.width - 2);
|
||||
}
|
||||
|
||||
if (event.key.key == SDLK_DOWN || event.key.key == SDLK_S) {
|
||||
player.pos_y = clamp(0, player.pos_y - 1, map_height - 2);
|
||||
player.pos_y = clamp(0, player.pos_y - 1, current_map.height - 2);
|
||||
}
|
||||
|
||||
if (event.key.key == SDLK_RIGHT || event.key.key == SDLK_D) {
|
||||
player.pos_x = clamp(0, player.pos_x + 1, map_width - 2);
|
||||
player.pos_x = clamp(0, player.pos_x + 1, current_map.width - 2);
|
||||
}
|
||||
|
||||
if (event.key.key == SDLK_F1) {
|
||||
save_map();
|
||||
save_map("../assets/map/map.sv", current_map);
|
||||
}
|
||||
|
||||
if (event.key.key == SDLK_F4) {
|
||||
load_map();
|
||||
load_map("../assets/map/map.sv", ¤t_map);
|
||||
}
|
||||
|
||||
if (event.key.key == SDLK_R) {
|
||||
@@ -1684,7 +1701,7 @@ int main(int argc, char **argv) {
|
||||
Sint32 tile_x = roundf(floor_intersection.x);
|
||||
Sint32 tile_y = roundf(floor_intersection.y);
|
||||
|
||||
if(0 <= tile_x && tile_x < map_width && 0 <= tile_y && tile_y < map_height) {
|
||||
if(0 <= tile_x && tile_x < current_map.width && 0 <= tile_y && tile_y < current_map.height) {
|
||||
dragging_tile_change = true;
|
||||
|
||||
drag_start_pos[0] = tile_x;
|
||||
@@ -1694,30 +1711,30 @@ int main(int argc, char **argv) {
|
||||
SDL_Keymod modifiers = SDL_GetModState();
|
||||
if (modifiers & SDL_KMOD_SHIFT && tile_x <= -1) {
|
||||
if(modifiers & SDL_KMOD_CTRL)
|
||||
change_map_size('W', -1);
|
||||
change_map_size(¤t_map, 'W', -1);
|
||||
else
|
||||
change_map_size('W', 1);
|
||||
change_map_size(¤t_map, 'W', 1);
|
||||
}
|
||||
|
||||
if (modifiers & SDL_KMOD_SHIFT && tile_x == map_width) {
|
||||
if (modifiers & SDL_KMOD_SHIFT && tile_x == current_map.width) {
|
||||
if (modifiers & SDL_KMOD_CTRL)
|
||||
change_map_size('E', -1);
|
||||
change_map_size(¤t_map, 'E', -1);
|
||||
else
|
||||
change_map_size('E', 1);
|
||||
change_map_size(¤t_map, 'E', 1);
|
||||
}
|
||||
|
||||
if (modifiers & SDL_KMOD_SHIFT && tile_y <= -1) {
|
||||
if (modifiers & SDL_KMOD_CTRL)
|
||||
change_map_size('N', -1);
|
||||
change_map_size(¤t_map, 'N', -1);
|
||||
else
|
||||
change_map_size('N', 1);
|
||||
change_map_size(¤t_map, 'N', 1);
|
||||
}
|
||||
|
||||
if (modifiers & SDL_KMOD_SHIFT && tile_y == map_height) {
|
||||
if (modifiers & SDL_KMOD_SHIFT && tile_y == current_map.height) {
|
||||
if (modifiers & SDL_KMOD_CTRL)
|
||||
change_map_size('S', -1);
|
||||
change_map_size(¤t_map, 'S', -1);
|
||||
else
|
||||
change_map_size('S', 1);
|
||||
change_map_size(¤t_map, 'S', 1);
|
||||
}
|
||||
} break;
|
||||
|
||||
@@ -1728,8 +1745,8 @@ int main(int argc, char **argv) {
|
||||
if (selected_tile != -1 && dragging_tile_change) {
|
||||
V2 floor_intersection = get_floor_intersection_of_mouse(V2_(event.button.x, event.button.y));
|
||||
|
||||
Sint32 tile_x = clamp(0, (Sint32)roundf(floor_intersection.x), map_width - 1);
|
||||
Sint32 tile_y = clamp(0, (Sint32)roundf(floor_intersection.y), map_height - 1);
|
||||
Sint32 tile_x = clamp(0, (Sint32)roundf(floor_intersection.x), current_map.width - 1);
|
||||
Sint32 tile_y = clamp(0, (Sint32)roundf(floor_intersection.y), current_map.height - 1);
|
||||
|
||||
Sint32 start_x = min(tile_x, drag_start_pos[0]);
|
||||
Sint32 start_y = min(tile_y, drag_start_pos[1]);
|
||||
@@ -1741,14 +1758,14 @@ int main(int argc, char **argv) {
|
||||
for (Sint32 x = start_x; x <= end_x; x++) {
|
||||
if (selected_rotation == -1) {
|
||||
Sint32 rotation = SDL_rand(4);
|
||||
map_tiles[x + map_width * y] = ((rotation & 3) << 16) | selected_tile;
|
||||
current_map.tiles[x + current_map.width * y] = ((rotation & 3) << 16) | selected_tile;
|
||||
} else {
|
||||
map_tiles[x + map_width * y] = ((selected_rotation & 3) << 16) | selected_tile;
|
||||
current_map.tiles[x + current_map.width * y] = ((selected_rotation & 3) << 16) | selected_tile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
update_buffer(world_buffer, 0, map_width * map_height * sizeof(Uint32), map_tiles);
|
||||
update_buffer(world_buffer, 0, current_map.width * current_map.height * sizeof(Uint32), current_map.tiles);
|
||||
}
|
||||
|
||||
dragging_tile_change = false;
|
||||
@@ -1763,19 +1780,19 @@ int main(int argc, char **argv) {
|
||||
continue;
|
||||
|
||||
if (event.gbutton.button == SDL_GAMEPAD_BUTTON_DPAD_UP) {
|
||||
player.pos_y = clamp(0, player.pos_y + 1, map_height - 2);
|
||||
player.pos_y = clamp(0, player.pos_y + 1, current_map.height - 2);
|
||||
}
|
||||
|
||||
if (event.gbutton.button == SDL_GAMEPAD_BUTTON_DPAD_LEFT) {
|
||||
player.pos_x = clamp(0, player.pos_x - 1, map_width - 2);
|
||||
player.pos_x = clamp(0, player.pos_x - 1, current_map.width - 2);
|
||||
}
|
||||
|
||||
if (event.gbutton.button == SDL_GAMEPAD_BUTTON_DPAD_DOWN) {
|
||||
player.pos_y = clamp(0, player.pos_y - 1, map_height - 2);
|
||||
player.pos_y = clamp(0, player.pos_y - 1, current_map.height - 2);
|
||||
}
|
||||
|
||||
if (event.gbutton.button == SDL_GAMEPAD_BUTTON_DPAD_RIGHT) {
|
||||
player.pos_x = clamp(0, player.pos_x + 1, map_width - 2);
|
||||
player.pos_x = clamp(0, player.pos_x + 1, current_map.width - 2);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
@@ -1845,9 +1862,9 @@ int main(int argc, char **argv) {
|
||||
Sint32 tile_x = roundf(floor_intersection.x);
|
||||
Sint32 tile_y = roundf(floor_intersection.y);
|
||||
|
||||
per_frame.map_width = map_width;
|
||||
per_frame.mouse[0] = tile_x;
|
||||
per_frame.mouse[1] = tile_y;
|
||||
per_frame.map_width = current_map.width;
|
||||
per_frame.mouse[0] = tile_x;
|
||||
per_frame.mouse[1] = tile_y;
|
||||
|
||||
if (dragging_tile_change) {
|
||||
per_frame.drag_start[0] = drag_start_pos[0];
|
||||
@@ -1917,7 +1934,7 @@ int main(int argc, char **argv) {
|
||||
SDL_BindGPUVertexBuffers(render_pass, 0, vertex_buffers, SDL_arraysize(vertex_buffers));
|
||||
SDL_BindGPUVertexStorageBuffers(render_pass, 0, &tile_infos_buffer, 1);
|
||||
SDL_BindGPUFragmentSamplers(render_pass, 0, texture_bindings, SDL_arraysize(texture_bindings));
|
||||
SDL_DrawGPUIndexedPrimitives(render_pass, 6, map_height * map_width, 0, 0, 0);
|
||||
SDL_DrawGPUIndexedPrimitives(render_pass, 6, current_map.height * current_map.width, 0, 0, 0);
|
||||
}
|
||||
|
||||
{ // Draw Player
|
||||
@@ -1952,9 +1969,9 @@ int main(int argc, char **argv) {
|
||||
SDL_BindGPUIndexBuffer(render_pass, &index_buffer_binding, SDL_GPU_INDEXELEMENTSIZE_16BIT);
|
||||
SDL_BindGPUVertexBuffers(render_pass, 0, vertex_buffers, SDL_arraysize(vertex_buffers));
|
||||
SDL_PushGPUFragmentUniformData(command_buffer, 0, &tints, sizeof(tints));
|
||||
SDL_DrawGPUIndexedPrimitives(render_pass, SDL_arraysize(grid_indices), map_height * map_width, 0, 0, 0);
|
||||
SDL_DrawGPUIndexedPrimitives(render_pass, SDL_arraysize(grid_indices), current_map.height * current_map.width, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
SDL_EndGPURenderPass(render_pass);
|
||||
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user