diff --git a/src/main.cpp b/src/main.cpp index c5cfced..58c5b88 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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", ¤t_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", ¤t_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", ¤t_map); + char *map_path = SDL_strdup(current_map.save_path); + unload_map(¤t_map); + load_map(map_path, ¤t_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 },