save the load path and gpu buffer in the map struct

This commit is contained in:
Sven Balzer 2025-03-25 19:33:13 +01:00
parent 0575989142
commit f7915b63c7

View File

@ -41,7 +41,6 @@ static SDL_GPUBuffer *index_buffer;
static SDL_GPUBuffer *grid_vertex_buffer;
static SDL_GPUBuffer *grid_index_buffer;
static SDL_GPUBuffer *player_instance_buffer;
static SDL_GPUBuffer *world_buffer;
static SDL_GPUBuffer *tile_infos_buffer;
static Sint32 window_width;
@ -160,6 +159,9 @@ struct Map {
Sint32 height;
Uint32 *tiles;
char *save_path;
SDL_GPUBuffer *gpu_buffer;
};
static Map current_map;
@ -217,89 +219,6 @@ static Sint32 selected_rotation = 0;
static bool dragging_tile_change = false;
static Sint32 drag_start_pos[2];
static bool save_map(const char *path, Map map) {
SDL_IOStream *file = SDL_IOFromFile(path, "wb");
if (!file) {
log_error("Failed to open map file for writing.");
return false;
}
defer(SDL_CloseIO(file));
if (!SDL_WriteS32LE(file, map.width)) {
log_error("Failed to write width to map file.");
return false;
}
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;
Uint32 to_write = orientation | type;
if (!SDL_WriteU32LE(file, to_write)) {
log_error("Failed to write tile to map file.");
return false;
}
}
if(!SDL_FlushIO(file)) {
log_error("Failed to flush data to map file.");
return false;
};
log("Saved map file.");
return true;
}
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;
}
if (!SDL_ReadS32LE(file, &result->height)) {
log_error("Failed read height from map file.");
return false;
}
result->tiles = (Uint32*)malloc(result->width * result->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;
}
Uint32 type = tile & 0xffff;
Uint32 orientation = tile & 0x30000;
Uint32 kind = 0;
for (int i = 0; i < SDL_arraysize(tile_infos); i++) {
if (tile_infos[i].type == type) {
kind = i;
break;
}
}
result->tiles[i] = orientation | kind;
}
log("Loaded map file.");
return true;
}
static bool update_buffer(SDL_GPUBuffer *buffer, Uint32 offset, Uint32 num_bytes, void *data) {
SDL_GPUTransferBufferCreateInfo transfer_buffer_info = {
.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD,
@ -382,11 +301,114 @@ static SDL_GPUBuffer *create_buffer(SDL_GPUBufferUsageFlags usage, Uint32 num_by
return buffer;
}
static bool save_map(Map map) {
SDL_IOStream *file = SDL_IOFromFile(map.save_path, "wb");
if (!file) {
log_error("Failed to open map file for writing.");
return false;
}
defer(SDL_CloseIO(file));
if (!SDL_WriteS32LE(file, map.width)) {
log_error("Failed to write width to map file.");
return false;
}
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;
Uint32 to_write = orientation | type;
if (!SDL_WriteU32LE(file, to_write)) {
log_error("Failed to write tile to map file.");
return false;
}
}
if(!SDL_FlushIO(file)) {
log_error("Failed to flush data to map file.");
return false;
};
log("Saved map file.");
return true;
}
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));
result->save_path = SDL_strdup(path);
if (!SDL_ReadS32LE(file, &result->width)) {
log_error("Failed read width from map file.");
return false;
}
if (!SDL_ReadS32LE(file, &result->height)) {
log_error("Failed read height from map file.");
return false;
}
result->tiles = (Uint32*)malloc(result->width * result->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;
}
Uint32 type = tile & 0xffff;
Uint32 orientation = tile & 0x30000;
Uint32 kind = 0;
for (int i = 0; i < SDL_arraysize(tile_infos); i++) {
if (tile_infos[i].type == type) {
kind = i;
break;
}
}
result->tiles[i] = orientation | kind;
}
char buffer_name[256] = "Map ";
SDL_strlcat(buffer_name, result->save_path, SDL_arraysize(buffer_name));
result->gpu_buffer = create_buffer(SDL_GPU_BUFFERUSAGE_VERTEX, result->width * result->height * 4, result->tiles, buffer_name);
if (!result->gpu_buffer) {
log_error("Failed to create buffer. Exiting.");
return 1;
}
log("Loaded map file.");
return true;
}
static void unload_map(Map *map) {
map->width = 0;
map->height = 0;
free(map->tiles);
SDL_free(map->save_path);
SDL_ReleaseGPUBuffer(device, map->gpu_buffer);
}
static void change_map_size(Map *map, char direction, int amount) {
SDL_GPUBuffer *old_world_buffer = world_buffer;
Uint32* old_map = map->tiles;
Sint32 old_map_width = map->width;
Sint32 old_map_height = map->height;
SDL_GPUBuffer *old_gpu_buffer = map->gpu_buffer;
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;
@ -449,14 +471,14 @@ static void change_map_size(Map *map, char direction, int amount) {
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");
if (!world_buffer) {
map->gpu_buffer = create_buffer(SDL_GPU_BUFFERUSAGE_VERTEX, map->width * map->height * 4, map->tiles, "world_buffer");
if (!map->gpu_buffer) {
log_error("Failed to create buffer. Exiting.");
exit(1);
}
free(old_map);
SDL_ReleaseGPUBuffer(device, old_world_buffer);
SDL_ReleaseGPUBuffer(device, old_gpu_buffer);
}
static SDL_GPUTexture *create_shader_texture(const char *name, const char *data, int width, int height, int channels) {
@ -1248,11 +1270,6 @@ bool imgui_time_picker(const char *label, int time[3]) {
int main(int argc, char **argv) {
setup_memory_functions();
if (!load_map("../assets/map/map.sv", &current_map)) {
log_error("Failed to load initial map. Exiting.");
return 1;
}
#ifdef SDL_PLATFORM_LINUX
if (!getenv("ENABLE_VULKAN_RENDERDOC_CAPTURE"))
SDL_SetHint(SDL_HINT_VIDEO_DRIVER, "wayland,x11");
@ -1292,6 +1309,11 @@ int main(int argc, char **argv) {
return 1;
}
if (!load_map("../assets/map/map.sv", &current_map)) {
log_error("Failed to load initial map. Exiting.");
return 1;
}
SDL_GPUTexture *player_texture = create_shader_texture("../assets/decorations/strawberry.png");
if (!player_texture) {
log_error("Failed to create shader texture. Exiting.");
@ -1349,12 +1371,6 @@ int main(int argc, char **argv) {
return 1;
}
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;
}
tile_infos_buffer = create_buffer(SDL_GPU_BUFFERUSAGE_GRAPHICS_STORAGE_READ, SDL_arraysize(cpu_tile_infos_buffer) * sizeof(*cpu_tile_infos_buffer), cpu_tile_infos_buffer, "tile_infos_buffer");
if (!tile_infos_buffer) {
log_error("Failed to create buffer. Exiting.");
@ -1674,11 +1690,14 @@ int main(int argc, char **argv) {
}
if (event.key.key == SDLK_F1) {
save_map("../assets/map/map.sv", current_map);
save_map(current_map);
}
if (event.key.key == SDLK_F4) {
load_map("../assets/map/map.sv", &current_map);
char *map_path = SDL_strdup(current_map.save_path);
unload_map(&current_map);
load_map(map_path, &current_map);
SDL_free(map_path);
}
if (event.key.key == SDLK_R) {
@ -1765,7 +1784,7 @@ int main(int argc, char **argv) {
}
}
update_buffer(world_buffer, 0, current_map.width * current_map.height * sizeof(Uint32), current_map.tiles);
update_buffer(current_map.gpu_buffer, 0, current_map.width * current_map.height * sizeof(Uint32), current_map.tiles);
}
dragging_tile_change = false;
@ -1923,7 +1942,7 @@ int main(int argc, char **argv) {
SDL_GPUBufferBinding index_buffer_binding = { .buffer = index_buffer, .offset = 0 };
SDL_GPUBufferBinding vertex_buffers[] = {
{ .buffer = vertex_buffer, .offset = 0 },
{ .buffer = world_buffer, .offset = 0 },
{ .buffer = current_map.gpu_buffer, .offset = 0 },
};
SDL_GPUTextureSamplerBinding texture_bindings[] = {
{ .texture = tile_textures_array, .sampler = pixel_sampler },