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
-s <seed>
use <seed> (unsigned integer) as the world seed
+ only used for newly created worlds
default is 0
+--world-name <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
========
std::string asset_path;
std::string save_path;
+ std::string world_name = "default";
Interface::Config interface = Interface::Config();
World::Config world = World::Config();
#include "WorldState.hpp"
#include "init.hpp"
+#include "../world/WorldSave.hpp"
#include <cctype>
#include <cstdlib>
} 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;
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':
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);
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)
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;
};
--- /dev/null
+#include "WorldSave.hpp"
+
+#include "../app/io.hpp"
+
+#include <cctype>
+#include <fstream>
+#include <iostream>
+#include <stdexcept>
+
+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");
+ }
+}
+
+}
--- /dev/null
+#ifndef BLANK_WORLD_WORLDSAVE_HPP_
+#define BLANK_WORLD_WORLDSAVE_HPP_
+
+#include "World.hpp"
+
+#include <string>
+
+
+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