From: Daniel Karbach Date: Sun, 9 Aug 2015 18:16:16 +0000 (+0200) Subject: save and load world seed X-Git-Url: https://git.localhorst.tv/?a=commitdiff_plain;h=39df551265bff648c1ac166043bb4b046122cc8d;p=blank.git save and load world seed first four bytes of persistence, yay ^^ --- diff --git a/Makefile b/Makefile index 5989839..9b261db 100644 --- a/Makefile +++ b/Makefile @@ -85,6 +85,7 @@ clean: distclean: clean rm -f $(BIN) cachegrind.out.* callgrind.out.* + rm -Rf build saves .PHONY: all release debug profile tests run gdb cachegrind callgrind test clean distclean diff --git a/running b/running index d3a632e..26a0f9e 100644 --- a/running +++ b/running @@ -56,8 +56,14 @@ World -s use (unsigned integer) as the world seed + only used for newly created worlds default is 0 +--world-name + use given name for the world save + no checks are being done right now, so make sure it can be + used as a directory name + Controls ======== diff --git a/src/app/Runtime.hpp b/src/app/Runtime.hpp index ac508b9..81c015c 100644 --- a/src/app/Runtime.hpp +++ b/src/app/Runtime.hpp @@ -34,6 +34,7 @@ public: std::string asset_path; std::string save_path; + std::string world_name = "default"; Interface::Config interface = Interface::Config(); World::Config world = World::Config(); diff --git a/src/app/runtime.cpp b/src/app/runtime.cpp index 5dce721..30b15ae 100644 --- a/src/app/runtime.cpp +++ b/src/app/runtime.cpp @@ -5,6 +5,7 @@ #include "WorldState.hpp" #include "init.hpp" +#include "../world/WorldSave.hpp" #include #include @@ -112,6 +113,14 @@ void Runtime::ReadArgs(int argc, const char *const *argv) { } else { config.save_path = argv[i]; } + } else if (strcmp(param, "world-name") == 0) { + ++i; + if (i >= argc || argv[i] == nullptr || argv[i][0] == '\0') { + cerr << "missing argument to --world-name" << endl; + error = true; + } else { + config.world_name = argv[i]; + } } else { cerr << "unknown option " << arg << endl; error = true; @@ -148,8 +157,7 @@ void Runtime::ReadArgs(int argc, const char *const *argv) { cerr << "missing argument to -s" << endl; error = true; } else { - config.world.gen.solid_seed = strtoul(argv[i], nullptr, 10); - config.world.gen.type_seed = config.world.gen.solid_seed; + config.world.gen.seed = strtoul(argv[i], nullptr, 10); } break; case 't': @@ -224,6 +232,13 @@ int Runtime::Execute() { Environment env(init.window, config.asset_path); env.viewport.VSync(config.vsync); + WorldSave save(config.save_path + config.world_name + '/'); + if (save.Exists()) { + save.Read(config.world); + } else { + save.Create(config.world); + } + Application app(env); WorldState world_state(env, config.interface, config.world); diff --git a/src/world/Generator.cpp b/src/world/Generator.cpp index c49dce1..3962252 100644 --- a/src/world/Generator.cpp +++ b/src/world/Generator.cpp @@ -9,8 +9,8 @@ namespace blank { Generator::Generator(const Config &config) noexcept -: solidNoise(config.solid_seed) -, typeNoise(config.type_seed) +: solidNoise(config.seed) +, typeNoise(config.seed) , stretch(1.0f/config.stretch) , solid_threshold(config.solid_threshold) , space(0) diff --git a/src/world/Generator.hpp b/src/world/Generator.hpp index a2ae18a..b3cb61f 100644 --- a/src/world/Generator.hpp +++ b/src/world/Generator.hpp @@ -16,8 +16,7 @@ class Generator { public: struct Config { - unsigned int solid_seed = 0; - unsigned int type_seed = 0; + unsigned int seed = 0; float stretch = 64.0f; float solid_threshold = 0.5f; }; diff --git a/src/world/WorldSave.cpp b/src/world/WorldSave.cpp new file mode 100644 index 0000000..2bfa818 --- /dev/null +++ b/src/world/WorldSave.cpp @@ -0,0 +1,84 @@ +#include "WorldSave.hpp" + +#include "../app/io.hpp" + +#include +#include +#include +#include + +using namespace std; + + +namespace blank { + +WorldSave::WorldSave(const string &path) +: root_path(path) +, conf_path(path + "world.conf") { + +} + + +bool WorldSave::Exists() const noexcept { + return is_dir(root_path) && is_file(conf_path); +} + + +void WorldSave::Create(const World::Config &conf) const { + cout << "creating world save" << endl; + + if (!make_dirs(root_path)) { + throw runtime_error("failed to create world save directory"); + } + + ofstream out(conf_path); + out << "seed = " << conf.gen.seed << endl; + out.close(); + + if (!out) { + throw runtime_error("failed to write world config"); + } +} + +void WorldSave::Read(World::Config &conf) const { + cout << "reading world save" << endl; + + ifstream in(conf_path); + if (!in) { + throw runtime_error("failed to open world config"); + } + + constexpr char spaces[] = "\n\r\t "; + + string line; + while (getline(in, line)) { + if (line.empty() || line[0] == '#') continue; + auto equals_pos = line.find_first_of('='); + + auto name_begin = line.find_first_not_of(spaces, 0, sizeof(spaces)); + auto name_end = equals_pos - 1; + while (name_end > name_begin && isspace(line[name_end])) { + --name_end; + } + + auto value_begin = line.find_first_not_of(spaces, equals_pos + 1, sizeof(spaces)); + auto value_end = line.length() - 1; + while (value_end > value_begin && isspace(line[value_end])) { + --value_end; + } + + string name(line, name_begin, name_end - name_begin + 1); + string value(line, value_begin, value_end - value_begin + 1); + + if (name == "seed") { + conf.gen.seed = stoul(value); + } else { + throw runtime_error("unknown world option: " + name); + } + } + if (in.bad()) { + throw runtime_error("IO error reading world config"); + } +} + +} diff --git a/src/world/WorldSave.hpp b/src/world/WorldSave.hpp new file mode 100644 index 0000000..7e40fc8 --- /dev/null +++ b/src/world/WorldSave.hpp @@ -0,0 +1,30 @@ +#ifndef BLANK_WORLD_WORLDSAVE_HPP_ +#define BLANK_WORLD_WORLDSAVE_HPP_ + +#include "World.hpp" + +#include + + +namespace blank { + +class WorldSave { + +public: + explicit WorldSave(const std::string &path); + +public: + bool Exists() const noexcept; + + void Create(const World::Config &) const; + void Read(World::Config &) const; + +private: + std::string root_path; + std::string conf_path; + +}; + +} + +#endif