]> git.localhorst.tv Git - blank.git/blob - src/app/runtime.cpp
eaeea8dd85c5c8940074fb4792e50e58271ec3e8
[blank.git] / src / app / runtime.cpp
1 #include "Application.hpp"
2 #include "Environment.hpp"
3 #include "PreloadState.hpp"
4 #include "Runtime.hpp"
5 #include "WorldState.hpp"
6
7 #include "init.hpp"
8
9 #include <cctype>
10 #include <cstdlib>
11 #include <iostream>
12 #include <SDL.h>
13
14 using namespace std;
15
16
17 namespace {
18
19 string get_asset_path() {
20         char *base = SDL_GetBasePath();
21         string assets(base);
22         assets += "assets/";
23         SDL_free(base);
24         return assets;
25 }
26
27 }
28
29 namespace blank {
30
31 Environment::Environment(Window &win)
32 : audio()
33 , viewport()
34 , window(win)
35 , assets(get_asset_path())
36 , counter() {
37
38 }
39
40
41 Runtime::Runtime() noexcept
42 : name("blank")
43 , mode(NORMAL)
44 , n(0)
45 , t(0)
46 , config() {
47
48 }
49
50
51 void Runtime::ReadArgs(int argc, const char *const *argv) {
52         if (argc <= 0) return;
53         name = argv[0];
54
55         bool options = true;
56         bool error = false;
57
58         for (int i = 1; i < argc; ++i) {
59                 const char *arg = argv[i];
60                 if (!arg || arg[0] == '\0') {
61                         cerr << "warning: found empty argument at position " << i << endl;
62                         continue;
63                 }
64                 if (options && arg[0] == '-') {
65                         if (arg[1] == '\0') {
66                                 cerr << "warning: incomplete option list at position " << i << endl;
67                         } else if (arg[1] == '-') {
68                                 if (arg[2] == '\0') {
69                                         // stopper
70                                         options = false;
71                                 } else {
72                                         // long option
73                                         if (strcmp(arg + 2, "no-vsync") == 0) {
74                                                 config.vsync = false;
75                                         } else if (strcmp(arg + 2, "no-keyboard") == 0) {
76                                                 config.interface.keyboard_disabled = true;
77                                         } else if (strcmp(arg + 2, "no-mouse") == 0) {
78                                                 config.interface.mouse_disabled = true;
79                                         } else if (strcmp(arg + 2, "no-hud") == 0) {
80                                                 config.interface.visual_disabled = true;
81                                         } else if (strcmp(arg + 2, "no-audio") == 0) {
82                                                 config.interface.audio_disabled = true;
83                                         } else {
84                                                 cerr << "unknown option " << arg << endl;
85                                                 error = true;
86                                         }
87                                 }
88                         } else {
89                                 // short options
90                                 for (int j = 1; arg[j] != '\0'; ++j) {
91                                         switch (arg[j]) {
92                                                 case 'd':
93                                                         config.doublebuf = false;
94                                                         break;
95                                                 case 'm':
96                                                         ++i;
97                                                         if (i >= argc || argv[i] == nullptr || argv[i][0] == '\0') {
98                                                                 cerr << "missing argument to -m" << endl;
99                                                                 error = true;
100                                                         } else {
101                                                                 config.multisampling = strtoul(argv[i], nullptr, 10);
102                                                         }
103                                                         break;
104                                                 case 'n':
105                                                         ++i;
106                                                         if (i >= argc || argv[i] == nullptr || argv[i][0] == '\0') {
107                                                                 cerr << "missing argument to -n" << endl;
108                                                                 error = true;
109                                                         } else {
110                                                                 n = strtoul(argv[i], nullptr, 10);
111                                                         }
112                                                         break;
113                                                 case 's':
114                                                         ++i;
115                                                         if (i >= argc || argv[i] == nullptr || argv[i][0] == '\0') {
116                                                                 cerr << "missing argument to -s" << endl;
117                                                                 error = true;
118                                                         } else {
119                                                                 config.world.gen.solid_seed = strtoul(argv[i], nullptr, 10);
120                                                                 config.world.gen.type_seed = config.world.gen.solid_seed;
121                                                         }
122                                                         break;
123                                                 case 't':
124                                                         ++i;
125                                                         if (i >= argc || argv[i] == nullptr || argv[i][0] == '\0') {
126                                                                 cerr << "missing argument to -t" << endl;
127                                                                 error = true;
128                                                         } else {
129                                                                 t = strtoul(argv[i], nullptr, 10);
130                                                         }
131                                                         break;
132                                                 case '-':
133                                                         // stopper
134                                                         options = false;
135                                                         break;
136                                                 default:
137                                                         cerr << "unknown option " << arg[j] << endl;
138                                                         error = true;
139                                                         break;
140                                         }
141                                 }
142                         }
143                 } else {
144                         cerr << "unable to interpret argument "
145                                 << i << " (" << arg << ")" << endl;
146                         error = true;
147                 }
148         }
149
150         if (error) {
151                 mode = ERROR;
152                 return;
153         }
154
155         if (n > 0) {
156                 if (t > 0) {
157                         mode = FIXED_FRAME_LIMIT;
158                 } else {
159                         mode = FRAME_LIMIT;
160                 }
161         } else if (t > 0) {
162                 mode = TIME_LIMIT;
163         } else {
164                 mode = NORMAL;
165         }
166 }
167
168 int Runtime::Execute() {
169         if (mode == ERROR) {
170                 return 1;
171         }
172
173         Init init(config.doublebuf, config.multisampling);
174
175         Environment env(init.window);
176         env.viewport.VSync(config.vsync);
177
178         Application app(env);
179
180         WorldState world_state(env, config.interface, config.world);
181         app.PushState(&world_state);
182
183         PreloadState preloader(env, world_state.GetWorld().Loader());
184         app.PushState(&preloader);
185
186         switch (mode) {
187                 default:
188                 case NORMAL:
189                         app.Run();
190                         break;
191                 case FRAME_LIMIT:
192                         app.RunN(n);
193                         break;
194                 case TIME_LIMIT:
195                         app.RunT(t);
196                         break;
197                 case FIXED_FRAME_LIMIT:
198                         app.RunS(n, t);
199                         break;
200         }
201
202         return 0;
203 }
204
205 }