blank
normal execution
-blank <n>
+blank [-n] <n>
terminate after <n> frames
blank -t <t>
blank <n> -t <t>
terminate after n frames, assume <t> milliseconds pass each frame
+blank -s <seed>
+ use <seed> (unsigned integer) as the world seed. default is 0
+
Controls
========
namespace blank {
-Application::Application()
+Application::Application(unsigned int seed)
: init_sdl()
, init_img()
, init_gl()
, init_glew()
, program()
, cam()
-, world()
+, world(seed)
, interface(world)
, test_controller(MakeTestEntity(world))
, running(false) {
class Application {
public:
- Application();
+ explicit Application(unsigned int seed);
Application(const Application &) = delete;
Application &operator =(const Application &) = delete;
-#include "app.hpp"
-
-#include <cctype>
-#include <cstdlib>
-#include <iostream>
+#include "runtime.hpp"
using namespace blank;
-
-namespace {
-
-enum Mode {
- NORMAL,
- FRAME_LIMIT,
- TIME_LIMIT,
- FIXED_FRAME_LIMIT,
-};
-
-}
-
-
int main(int argc, char *argv[]) {
-
- Mode mode = NORMAL;
- size_t n = 0, t = 0;
-
- bool error = false;
- for (int i = 1; i < argc; ++i) {
- if (argv[i] == nullptr || argv[i][0] == '\0') continue;
- if (argv[i][0] == '-') {
- if (argv[i][1] == 't' && argv[i][2] == '\0') {
- ++i;
- if (i >= argc) {
- std::cerr << "missing argument to -t" << std::endl;
- error = true;
- } else {
- t = std::strtoul(argv[i], nullptr, 10);
- }
- } else {
- std::cerr << "unable to interpret argument "
- << i << " (" << argv[i] << ")" << std::endl;
- error = true;
- }
- } else if (std::isdigit(*argv[i])) {
- n = std::strtoul(argv[i], nullptr, 10);
- } else {
- std::cerr << "unable to interpret argument "
- << i << " (" << argv[i] << ")" << std::endl;
- error = true;
- }
- }
-
- if (error) {
- return 1;
- }
-
- if (n > 0) {
- if (t > 0) {
- mode = FIXED_FRAME_LIMIT;
- } else {
- mode = FRAME_LIMIT;
- }
- } else if (t > 0) {
- mode = TIME_LIMIT;
- }
-
- Application app;
- switch (mode) {
- default:
- case NORMAL:
- app.Run();
- break;
- case FRAME_LIMIT:
- app.RunN(n);
- break;
- case TIME_LIMIT:
- app.RunT(t);
- break;
- case FIXED_FRAME_LIMIT:
- app.RunS(n, t);
- break;
- }
-
- return 0;
-
+ Runtime rt;
+ rt.ReadArgs(argc, argv);
+ return rt.Execute();
}
--- /dev/null
+#include "runtime.hpp"
+
+#include "app.hpp"
+
+#include <cctype>
+#include <cstdlib>
+#include <iostream>
+
+using namespace std;
+
+
+namespace blank {
+
+Runtime::Runtime()
+: name("blank")
+, mode(NORMAL)
+, n(0)
+, t(0)
+, seed(0) {
+
+}
+
+
+void Runtime::ReadArgs(int argc, const char *const *argv) {
+ if (argc <= 0) return;
+ name = argv[0];
+
+ bool options = true;
+ bool error = false;
+
+ for (int i = 1; i < argc; ++i) {
+ const char *arg = argv[i];
+ if (!arg || arg[0] == '\0') {
+ cerr << "warning: found empty argument at position " << i << endl;
+ continue;
+ }
+ if (options && arg[0] == '-') {
+ if (arg[1] == '\0') {
+ cerr << "warning: incomplete option list at position " << i << endl;
+ } else if (arg[1] == '-') {
+ if (arg[2] == '\0') {
+ // stopper
+ options = false;
+ } else {
+ // long option
+ cerr << "unknown option " << arg << endl;
+ error = true;
+ }
+ } else {
+ // short options
+ for (int j = 1; arg[j] != '\0'; ++j) {
+ switch (arg[j]) {
+ case 'n':
+ ++i;
+ if (i >= argc || argv[i] == nullptr || argv[i][0] == '\0') {
+ cerr << "missing argument to -n" << endl;
+ error = true;
+ } else {
+ n = strtoul(argv[i], nullptr, 10);
+ }
+ break;
+ case 's':
+ ++i;
+ if (i >= argc || argv[i] == nullptr || argv[i][0] == '\0') {
+ cerr << "missing argument to -s" << endl;
+ error = true;
+ } else {
+ seed = strtoul(argv[i], nullptr, 10);
+ }
+ break;
+ case 't':
+ ++i;
+ if (i >= argc || argv[i] == nullptr || argv[i][0] == '\0') {
+ cerr << "missing argument to -t" << endl;
+ error = true;
+ } else {
+ t = strtoul(argv[i], nullptr, 10);
+ }
+ break;
+ case '-':
+ // stopper
+ options = false;
+ break;
+ default:
+ cerr << "unknown option " << arg[j] << endl;
+ error = true;
+ break;
+ }
+ }
+ }
+ } else if (isdigit(arg[0])) {
+ // positional number interpreted as -n
+ n = strtoul(arg, nullptr, 10);
+ } else {
+ cerr << "unable to interpret argument "
+ << i << " (" << arg << ")" << endl;
+ error = true;
+ }
+ }
+
+ if (error) {
+ mode = ERROR;
+ return;
+ }
+
+ if (n > 0) {
+ if (t > 0) {
+ mode = FIXED_FRAME_LIMIT;
+ } else {
+ mode = FRAME_LIMIT;
+ }
+ } else if (t > 0) {
+ mode = TIME_LIMIT;
+ } else {
+ mode = NORMAL;
+ }
+}
+
+int Runtime::Execute() {
+ if (mode == ERROR) {
+ return 1;
+ }
+
+ Application app(seed);
+ switch (mode) {
+ default:
+ case NORMAL:
+ app.Run();
+ break;
+ case FRAME_LIMIT:
+ app.RunN(n);
+ break;
+ case TIME_LIMIT:
+ app.RunT(t);
+ break;
+ case FIXED_FRAME_LIMIT:
+ app.RunS(n, t);
+ break;
+ }
+ return 0;
+}
+
+}
--- /dev/null
+#ifndef BLANK_RUNTIME_HPP_
+#define BLANK_RUNTIME_HPP_
+
+#include <cstddef>
+
+
+namespace blank {
+
+class Runtime {
+
+public:
+ enum Mode {
+ NORMAL,
+ FRAME_LIMIT,
+ TIME_LIMIT,
+ FIXED_FRAME_LIMIT,
+ ERROR,
+ };
+
+ Runtime();
+
+ void ReadArgs(int argc, const char *const *argv);
+
+ int Execute();
+
+private:
+ const char *name;
+ Mode mode;
+ std::size_t n;
+ std::size_t t;
+ unsigned int seed;
+
+};
+
+}
+
+#endif
namespace blank {
-World::World()
+World::World(unsigned int seed)
: blockType()
, blockShape({{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f }})
, stairShape({{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f }}, { 0.0f, 0.0f })
, slabShape({{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.0f, 0.5f }})
-, generate(0)
+, generate(seed)
, chunks(blockType, generate)
, player() {
BlockType::Faces block_fill = { true, true, true, true, true, true };
class World {
public:
- World();
+ explicit World(unsigned int seed);
bool Intersection(
const Ray &,