From 91c06537ebc86d6aa7a30fe8486d8926170b7637 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 15 Nov 2023 00:06:28 +0300 Subject: [PATCH] Generator test mode setting --- src/coders/png.cpp | 42 +++++++++++++---------- src/engine.cpp | 6 ++-- src/files/WorldFiles.cpp | 9 +++-- src/files/WorldFiles.h | 3 +- src/settings.cpp | 61 --------------------------------- src/settings.h | 20 +++++++---- src/voxel_engine.cpp | 5 ++- src/voxels/Chunks.cpp | 3 +- src/voxels/ChunksController.cpp | 6 ++-- src/voxels/ChunksController.h | 2 +- src/world/Level.cpp | 5 ++- src/world/World.cpp | 6 ++-- src/world/World.h | 4 +-- 13 files changed, 67 insertions(+), 105 deletions(-) delete mode 100644 src/settings.cpp diff --git a/src/coders/png.cpp b/src/coders/png.cpp index d1be6da0..b3d0de00 100644 --- a/src/coders/png.cpp +++ b/src/coders/png.cpp @@ -1,12 +1,15 @@ #include "png.h" #include +#include #include #include "../graphics/ImageData.h" #include "../graphics/Texture.h" #include "../files/files.h" +using std::unique_ptr; + #ifndef _WIN32 #define LIBPNG #endif @@ -15,41 +18,45 @@ #include int _png_write(const char* filename, uint width, uint height, const ubyte* data, bool alpha) { - int code = 0; png_structp png_ptr = NULL; png_infop info_ptr = NULL; - png_bytep row = NULL; uint pixsize = alpha ? 4 : 3; // Open file for writing (binary mode) FILE* fp = fopen(filename, "wb"); if (fp == NULL) { fprintf(stderr, "Could not open file %s for writing\n", filename); - code = 1; - goto finalize; + fclose(fp); + return 1; } // Initialize write structure png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) { fprintf(stderr, "Could not allocate write struct\n"); - code = 1; - goto finalize; + fclose(fp); + png_destroy_write_struct(&png_ptr, (png_infopp)NULL); + return 1; } // Initialize info structure info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { fprintf(stderr, "Could not allocate info struct\n"); - code = 1; - goto finalize; + fclose(fp); + png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); + png_destroy_write_struct(&png_ptr, (png_infopp)NULL); + return 1; + } // Setup Exception handling if (setjmp(png_jmpbuf(png_ptr))) { fprintf(stderr, "Error during png creation\n"); - code = 1; - goto finalize; + fclose(fp); + png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); + png_destroy_write_struct(&png_ptr, (png_infopp)NULL); + return 1; } png_init_io(png_ptr, fp); @@ -65,7 +72,7 @@ int _png_write(const char* filename, uint width, uint height, const ubyte* data, png_write_info(png_ptr, info_ptr); - row = (png_bytep) malloc(pixsize * width * sizeof(png_byte)); + unique_ptr row(new png_byte[pixsize * width]); // Write image data for (uint y = 0; y < height; y++) { @@ -74,19 +81,16 @@ int _png_write(const char* filename, uint width, uint height, const ubyte* data, row[x * pixsize + i] = (png_byte)data[(y * width + x) * pixsize + i]; } } - png_write_row(png_ptr, row); + png_write_row(png_ptr, row.get()); } // End write png_write_end(png_ptr, NULL); - finalize: - if (fp != NULL) fclose(fp); - if (info_ptr != NULL) png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); - if (png_ptr != NULL) png_destroy_write_struct(&png_ptr, (png_infopp)NULL); - if (row != NULL) free(row); - - return code; + fclose(fp); + png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); + png_destroy_write_struct(&png_ptr, (png_infopp)NULL); + return 0; } ImageData* _png_load(const char* file){ diff --git a/src/engine.cpp b/src/engine.cpp index 8aaa2c5b..106b0703 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -54,7 +54,7 @@ Engine::Engine(const EngineSettings& settings_) { std::cout << "-- loading world" << std::endl; vec3 playerPosition = vec3(0, 64, 0); Camera* camera = new Camera(playerPosition, radians(90.0f)); - World* world = new World("world-1", "world/", 42); + World* world = new World("world-1", "world/", 42, settings); Player* player = new Player(playerPosition, 4.0f, camera); level = world->loadLevel(player, settings); @@ -116,7 +116,7 @@ void Engine::mainloop() { level->chunksController->update(settings.chunks.loadSpeed); float fovFactor = 18.0f / (float)settings.chunks.loadDistance; - worldRenderer.draw(camera, occlusion, fovFactor, settings.fogCurve); + worldRenderer.draw(camera, occlusion, fovFactor, settings.graphics.fogCurve); hud.draw(); if (level->player->debug) { hud.drawDebug( 1 / delta, occlusion); @@ -135,7 +135,7 @@ Engine::~Engine() { World* world = level->world; std::cout << "-- saving world" << std::endl; - world->write(level); + world->write(level, !settings.debug.generatorTestMode); delete level; delete world; diff --git a/src/files/WorldFiles.cpp b/src/files/WorldFiles.cpp index 8dd9b3fb..c3142792 100644 --- a/src/files/WorldFiles.cpp +++ b/src/files/WorldFiles.cpp @@ -56,7 +56,8 @@ float bytes2Float(ubyte* src, uint offset){ return *(float*)(&value); } -WorldFiles::WorldFiles(std::string directory, size_t mainBufferCapacity) : directory(directory){ +WorldFiles::WorldFiles(std::string directory, size_t mainBufferCapacity, bool generatorTestMode) + : directory(directory), generatorTestMode(generatorTestMode) { compressionBuffer = new ubyte[CHUNK_DATA_LEN * 2]; } @@ -161,6 +162,9 @@ ubyte* WorldFiles::getChunk(int x, int y){ } ubyte* WorldFiles::readChunkData(int x, int y, uint32_t& length){ + if (generatorTestMode) + return nullptr; + int regionX = floordiv(x, REGION_SIZE); int regionY = floordiv(y, REGION_SIZE); @@ -199,6 +203,8 @@ void WorldFiles::write(){ if (!std::filesystem::is_directory(directory)) { std::filesystem::create_directory(directory); } + if (generatorTestMode) + return; for (auto it = regions.begin(); it != regions.end(); it++){ if (it->second.chunksData == nullptr || !it->second.unsaved) continue; @@ -264,7 +270,6 @@ bool WorldFiles::readPlayer(Player* player) { return true; } - void WorldFiles::writeRegion(int x, int y, WorldRegion& entry){ ubyte** region = entry.chunksData; uint32_t* sizes = entry.compressedSizes; diff --git a/src/files/WorldFiles.h b/src/files/WorldFiles.h index bce29a74..312a73a3 100644 --- a/src/files/WorldFiles.h +++ b/src/files/WorldFiles.h @@ -31,8 +31,9 @@ public: std::unordered_map regions; std::string directory; ubyte* compressionBuffer; + bool generatorTestMode; - WorldFiles(std::string directory, size_t mainBufferCapacity); + WorldFiles(std::string directory, size_t mainBufferCapacity, bool generatorTestMode); ~WorldFiles(); void put(Chunk* chunk); diff --git a/src/settings.cpp b/src/settings.cpp deleted file mode 100644 index e9a4fb23..00000000 --- a/src/settings.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include "settings.h" - -#include -#include - -#include "files/files.h" -#include "coders/json.h" - -using std::string; -using std::unique_ptr; - -void load_settings(EngineSettings& settings, string filename) { - string source = files::read_string(filename); - unique_ptr obj(json::parse(filename, source)); - { - auto& display = settings.display; - obj->num("display-width", display.width); - obj->num("display-height", display.height); - obj->num("display-samples", display.samples); - obj->num("display-swap-interval", display.swapInterval); - } - - { - auto& chunks = settings.chunks; - obj->num("chunks-load-distance", chunks.loadDistance); - obj->num("chunks-load-speed", chunks.loadSpeed); - obj->num("chunks-padding", chunks.padding); - } - { - auto& camera = settings.camera; - obj->flag("camera-fov-effects", camera.fovEvents); - obj->flag("camera-shaking", camera.shaking); - } - obj->num("fog-curve", settings.fogCurve); -} - -void save_settings(EngineSettings& settings, string filename) { - json::JObject obj; - { - auto& display = settings.display; - obj.put("display-width", display.width); - obj.put("display-height", display.height); - obj.put("display-samples", display.samples); - obj.put("display-swap-interval", display.swapInterval); - } - - { - auto& chunks = settings.chunks; - obj.put("chunks-load-distance", chunks.loadDistance); - obj.put("chunks-load-speed", chunks.loadSpeed); - obj.put("chunks-padding", chunks.padding); - } - - { - auto& camera = settings.camera; - obj.put("camera-fov-effects", camera.fovEvents); - obj.put("camera-shaking", camera.shaking); - } - obj.put("fog-curve", settings.fogCurve); - files::write_string(filename, json::stringify(&obj, true, " ")); -} \ No newline at end of file diff --git a/src/settings.h b/src/settings.h index 2ebcf188..ef656ce9 100644 --- a/src/settings.h +++ b/src/settings.h @@ -34,17 +34,23 @@ struct CameraSettings { bool shaking = true; }; +struct GraphicsSettings { + /* Fog opacity is calculated as `pow(depth*k, fogCurve)` where k depends on chunksLoadDistance. + Use values in range [1.0 - 2.0] where 1.0 is linear, 2.0 is quadratic */ + float fogCurve = 1.6f; +}; + +struct DebugSettings { + /* Turns off chunks saving/loading */ + bool generatorTestMode = false; +}; + struct EngineSettings { DisplaySettings display; ChunksSettings chunks; CameraSettings camera; - - /* Fog opacity is calculated as `pow(depth*k, fogCurve)` where k depends on chunksLoadDistance. - Use values in range [1.0 - 2.0] where 1.0 is linear, 2.0 is quadratic - */ - float fogCurve = 1.6f; - - + GraphicsSettings graphics; + DebugSettings debug; }; #endif // SRC_SETTINGS_H_ \ No newline at end of file diff --git a/src/voxel_engine.cpp b/src/voxel_engine.cpp index ceed45b3..cc116389 100644 --- a/src/voxel_engine.cpp +++ b/src/voxel_engine.cpp @@ -31,7 +31,10 @@ toml::Wrapper create_wrapper(EngineSettings& settings) { camera.add("shaking", &settings.camera.shaking); toml::Section& graphics = wrapper.add("graphics"); - graphics.add("fog-curve", &settings.fogCurve); + graphics.add("fog-curve", &settings.graphics.fogCurve); + + toml::Section& debug = wrapper.add("debug"); + debug.add("generator-test-mode", &settings.debug.generatorTestMode); return wrapper; } diff --git a/src/voxels/Chunks.cpp b/src/voxels/Chunks.cpp index d703597c..f63dcd18 100644 --- a/src/voxels/Chunks.cpp +++ b/src/voxels/Chunks.cpp @@ -261,7 +261,8 @@ void Chunks::translate(int dx, int dz){ continue; if (nx < 0 || nz < 0 || nx >= w || nz >= d){ events->trigger(EVT_CHUNK_HIDDEN, chunk.get()); - worldFiles->put(chunk.get()); + if (worldFiles) + worldFiles->put(chunk.get()); chunksCount--; continue; } diff --git a/src/voxels/ChunksController.cpp b/src/voxels/ChunksController.cpp index 2fc2d976..f4bee47b 100644 --- a/src/voxels/ChunksController.cpp +++ b/src/voxels/ChunksController.cpp @@ -42,7 +42,7 @@ void ChunksController::update(int64_t maxDuration) { int64_t mcstotal = 0; for (uint i = 0; i < MAX_WORK_PER_FRAME; i++) { auto start = high_resolution_clock::now(); - if (loadVisible(level->world->wfile)) { + if (loadVisible()) { auto elapsed = high_resolution_clock::now() - start; int64_t mcs = duration_cast(elapsed).count(); avgDurationMcs = mcs * 0.2 + avgDurationMcs * 0.8; @@ -55,7 +55,7 @@ void ChunksController::update(int64_t maxDuration) { } } -bool ChunksController::loadVisible(WorldFiles* worldFiles){ +bool ChunksController::loadVisible(){ const int w = chunks->w; const int d = chunks->d; const int ox = chunks->ox; @@ -103,7 +103,7 @@ bool ChunksController::loadVisible(WorldFiles* worldFiles){ chunk = shared_ptr(new Chunk(nearX+ox, nearZ+oz)); level->chunksStorage->store(chunk); - ubyte* data = worldFiles->getChunk(chunk->x, chunk->z); + ubyte* data = level->world->wfile->getChunk(chunk->x, chunk->z); if (data) { chunk->decode(data); chunk->setLoaded(true); diff --git a/src/voxels/ChunksController.h b/src/voxels/ChunksController.h index f5616d99..1a2b0908 100644 --- a/src/voxels/ChunksController.h +++ b/src/voxels/ChunksController.h @@ -22,7 +22,7 @@ public: ~ChunksController(); void update(int64_t maxDuration); - bool loadVisible(WorldFiles* worldFiles); + bool loadVisible(); }; #endif /* VOXELS_CHUNKSCONTROLLER_H_ */ diff --git a/src/world/Level.cpp b/src/world/Level.cpp index 9c5a0ab3..fbc47b9f 100644 --- a/src/world/Level.cpp +++ b/src/world/Level.cpp @@ -20,7 +20,10 @@ Level::Level(World* world, Player* player, ChunksStorage* chunksStorage, LevelEv uint matrixSize = (settings.chunks.loadDistance+ settings.chunks.padding) * 2; - chunks = new Chunks(matrixSize, matrixSize, 0, 0, world->wfile, events); + chunks = new Chunks(matrixSize, matrixSize, + 0, 0, + world->wfile, + events); lighting = new Lighting(chunks); chunksController = new ChunksController(this, chunks, lighting, settings.chunks.padding); playerController = new PlayerController(this, settings); diff --git a/src/world/World.cpp b/src/world/World.cpp index 58d13062..493f2312 100644 --- a/src/world/World.cpp +++ b/src/world/World.cpp @@ -14,15 +14,15 @@ using std::shared_ptr; -World::World(std::string name, std::string directory, int seed) : name(name), seed(seed) { - wfile = new WorldFiles(directory, REGION_VOL * (CHUNK_DATA_LEN * 2 + 8)); +World::World(std::string name, std::string directory, int seed, EngineSettings& settings) : name(name), seed(seed) { + wfile = new WorldFiles(directory, REGION_VOL * (CHUNK_DATA_LEN * 2 + 8), settings.debug.generatorTestMode); } World::~World(){ delete wfile; } -void World::write(Level* level) { +void World::write(Level* level, bool writeChunks) { Chunks* chunks = level->chunks; for (size_t i = 0; i < chunks->volume; i++) { diff --git a/src/world/World.h b/src/world/World.h index 3ddcd007..4ffd8146 100644 --- a/src/world/World.h +++ b/src/world/World.h @@ -16,10 +16,10 @@ public: WorldFiles* wfile; int seed; - World(std::string name, std::string directory, int seed); + World(std::string name, std::string directory, int seed, EngineSettings& settings); ~World(); - void write(Level* level); + void write(Level* level, bool writeChunks); Level* loadLevel(Player* player, EngineSettings& settings); };