1 /****************************
2 ** Tsunagari Tile Engine **
4 ** Copyright 2012 OmegaSDG **
5 ****************************/
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to
10 // deal in the Software without restriction, including without limitation the
11 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12 // sell copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
15 // The above copyright notice and this permission notice shall be included in
16 // all copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
30 #include <boost/config.hpp>
31 #include <boost/program_options.hpp>
32 #include <boost/program_options/detail/config_file.hpp>
33 #include <boost/program_options/parsers.hpp>
35 #include "client-conf.h"
36 #include "nbcl/nbcl.h"
39 Conf conf
; // Project-wide global configuration.
44 if (!strcmp(DEF_ENGINE_VERBOSITY
, "quiet"))
45 conf
.verbosity
= V_QUIET
;
46 else if (!strcmp(DEF_ENGINE_VERBOSITY
, "normal"))
47 conf
.verbosity
= V_NORMAL
;
48 else if (!strcmp(DEF_ENGINE_VERBOSITY
, "verbose"))
49 conf
.verbosity
= V_VERBOSE
;
50 if (!strcmp(DEF_ENGINE_HALTING
, "fatal"))
52 else if (!strcmp(DEF_ENGINE_HALTING
, "script"))
53 conf
.halting
= SCRIPT
;
54 else if (!strcmp(DEF_ENGINE_HALTING
, "error"))
56 windowSize
.x
= DEF_WINDOW_WIDTH
;
57 windowSize
.y
= DEF_WINDOW_HEIGHT
;
58 fullscreen
= DEF_WINDOW_FULLSCREEN
;
59 audioEnabled
= DEF_AUDIO_ENABLED
;
60 cacheEnabled
= DEF_CACHE_ENABLED
;
61 cacheTTL
= DEF_CACHE_TTL
;
62 cacheSize
= DEF_CACHE_SIZE
;
67 bool Conf::validate(const char* filename
)
69 if (conf
.worldFilename
== "") {
70 Log::fatal(filename
, "\"[engine] world\" option or equivalent command line option expected");
76 /* Output compiled-in engine defaults. */
77 static void defaultsQuery()
79 std::cerr
<< "CLIENT_CONF_PATH: "
80 << CLIENT_CONF_PATH
<< std::endl
;
81 std::cerr
<< "BASE_ZIP_PATH: "
82 << BASE_ZIP_PATH
<< std::endl
;
83 std::cerr
<< "XML_DTD_PATH: "
84 << XML_DTD_PATH
<< std::endl
;
85 std::cerr
<< "DEF_ENGINE_VERBOSITY: "
86 << DEF_ENGINE_VERBOSITY
<< std::endl
;
87 std::cerr
<< "DEF_ENGINE_HALTING: "
88 << DEF_ENGINE_HALTING
<< std::endl
;
89 std::cerr
<< "DEF_WINDOW_WIDTH: "
90 << DEF_WINDOW_WIDTH
<< std::endl
;
91 std::cerr
<< "DEF_WINDOW_HEIGHT: "
92 << DEF_WINDOW_HEIGHT
<< std::endl
;
93 std::cerr
<< "DEF_WINDOW_FULLSCREEN: "
94 << DEF_WINDOW_FULLSCREEN
<< std::endl
;
95 std::cerr
<< "DEF_AUDIO_ENABLED: "
96 << DEF_AUDIO_ENABLED
<< std::endl
;
97 std::cerr
<< "DEF_CACHE_ENABLED: "
98 << DEF_CACHE_ENABLED
<< std::endl
;
99 std::cerr
<< "DEF_CACHE_TTL: "
100 << DEF_CACHE_TTL
<< std::endl
;
101 std::cerr
<< "DEF_CACHE_SIZE: "
102 << DEF_CACHE_SIZE
<< std::endl
;
106 * Load the values we need to start initializing the game from an ini file.
108 * We need to know what size window to create and which World to load. This
109 * information will be stored in an ini file which we parse here.
111 * @param filename Name of the ini file to load from.
113 * @return false if error occured during processing
115 bool parseConfig(const char* filename
)
117 namespace pod
= boost::program_options::detail
;
119 conf
.cacheEnabled
= DEF_CACHE_TTL
&& DEF_CACHE_SIZE
;
121 std::ifstream
config(filename
);
123 Log::err(filename
, "could not parse config");
127 std::set
<std::string
> options
;
128 std::map
<std::string
, std::string
> parameters
;
131 for (pod::config_file_iterator
i(config
, options
), e
; i
!= e
; ++i
)
132 parameters
[i
->string_key
] = i
->value
[0];
134 if (!parameters
["engine.world"].empty())
135 conf
.worldFilename
= parameters
["engine.world"];
137 if (!parameters
["engine.datapath"].empty())
138 conf
.dataPath
= splitStr(parameters
["engine.datapath"], ",");
140 if (!parameters
["window.width"].empty())
141 conf
.windowSize
.x
= atoi(parameters
["window.width"].c_str());
143 if (!parameters
["window.height"].empty())
144 conf
.windowSize
.y
= atoi(parameters
["window.height"].c_str());
146 if (!parameters
["window.fullscreen"].empty())
147 conf
.fullscreen
= parseBool(parameters
["window.fullscreen"]);
149 if (parameters
["audio.enabled"].size())
150 conf
.audioEnabled
= parseBool(parameters
["audio.enabled"]);
152 conf
.audioEnabled
= true;
154 if (!parameters
["cache.enabled"].empty()) {
155 if (parseBool(parameters
["cache.enabled"]))
156 conf
.cacheEnabled
= true;
158 conf
.cacheEnabled
= false;
161 if (parameters
["cache.ttl"].empty())
162 conf
.cacheTTL
= DEF_CACHE_TTL
;
164 if (atoi(parameters
["cache.ttl"].c_str()) == 0)
165 conf
.cacheEnabled
= 0;
166 conf
.cacheTTL
= atoi(parameters
["cache.ttl"].c_str());
169 if (parameters
["cache.size"].empty())
170 conf
.cacheSize
= DEF_CACHE_SIZE
;
172 if (atoi(parameters
["cache.size"].c_str()) == 0)
173 conf
.cacheEnabled
= 0;
174 conf
.cacheSize
= atoi(parameters
["cache.size"].c_str());
177 std::string verbosity
= parameters
["engine.verbosity"];
178 if (verbosity
.empty())
180 else if (verbosity
== "quiet")
181 conf
.verbosity
= V_QUIET
;
182 else if (verbosity
== "normal")
183 conf
.verbosity
= V_NORMAL
;
184 else if (verbosity
== "verbose")
185 conf
.verbosity
= V_VERBOSE
;
187 Log::err(filename
, "unknown value for \"[engine] verbosity\", using default");
190 std::string halting
= parameters
["engine.halting"];
193 else if (halting
== "fatal")
194 conf
.halting
= FATAL
;
195 else if (halting
== "script")
196 conf
.halting
= SCRIPT
;
197 else if (halting
== "error")
198 conf
.halting
= ERROR
;
200 Log::err(filename
, "unknown value for \"[engine] halting\", using default");
206 //! Parse and process command line options and arguments.
207 bool parseCommandLine(int argc
, char* argv
[])
209 NBCL
cmd(argc
, argv
);
211 cmd
.setStrayArgsDesc("[WORLD FILE]");
213 cmd
.insert("-h", "--help", "", "Display this help message");
214 cmd
.insert("-c", "--config", "<config file>", "Client config file to use");
215 cmd
.insert("-p", "--datapath", "<file,file,...>", "Prepend zips to data path");
216 cmd
.insert("-q", "--quiet", "", "Display only fatal errors");
217 cmd
.insert("", "--normal", "", "Display all errors");
218 cmd
.insert("-v", "--verbose", "", "Display additional information");
219 cmd
.insert("-t", "--cache-ttl", "<seconds>", "Cache time-to-live in seconds");
220 cmd
.insert("-m", "--cache-size", "<megabytes>", "Cache size in megabytes");
221 cmd
.insert("-s", "--size", "<WxH>", "Window dimensions");
222 cmd
.insert("-f", "--fullscreen", "", "Run in fullscreen mode");
223 cmd
.insert("-w", "--window", "", "Run in windowed mode");
224 cmd
.insert("", "--fatal-halt", "", "Stop engine only on fatal errors");
225 cmd
.insert("", "--script-halt", "", "Stop engine on script errors");
226 cmd
.insert("", "--error-halt", "", "Stop engine on all errors");
227 cmd
.insert("", "--no-audio", "", "Disable audio");
228 cmd
.insert("", "--query", "", "Query compiled-in engine defaults");
229 cmd
.insert("", "--version", "", "Print the engine version string");
236 std::vector
<std::string
> strayArgs
= cmd
.getStrayArgsList();
237 if (strayArgs
.size() > 1) {
241 else if (strayArgs
.size() == 1)
242 conf
.worldFilename
= strayArgs
[0];
244 if (cmd
.check("--help")) {
249 if (cmd
.check("--version")) {
250 std::cout
<< TSUNAGARI_RELEASE_VERSION
<< std::endl
;
254 if (cmd
.check("--query")) {
259 if (cmd
.check("--config")) {
260 if (!parseConfig(cmd
.get("--config").c_str()))
264 if (cmd
.check("--datapath"))
265 conf
.dataPath
= splitStr(cmd
.get("--datapath"), ",");
268 if (cmd
.check("--quiet")) {
269 conf
.verbosity
= V_QUIET
;
272 if (cmd
.check("--normal")) {
273 conf
.verbosity
= V_NORMAL
;
276 if (cmd
.check("--verbose")) {
277 conf
.verbosity
= V_VERBOSE
;
281 Log::err("cmdline", "multiple verbosity flags on cmdline, using most verbose");
284 if (cmd
.check("--fatal-halt")) {
285 conf
.halting
= FATAL
;
288 if (cmd
.check("--script-halt")) {
289 conf
.halting
= SCRIPT
;
292 if (cmd
.check("--error-halt")) {
293 conf
.halting
= ERROR
;
297 Log::err("cmdline", "multiple halting flags on cmdline, using most stringent");
299 if (cmd
.check("--no-audio"))
300 conf
.audioEnabled
= false;
302 if (cmd
.check("--cache-ttl")) {
303 conf
.cacheTTL
= atoi(cmd
.get("--cache-ttl").c_str());
304 if (conf
.cacheTTL
== 0)
305 conf
.cacheEnabled
= false;
308 if (cmd
.check("--cache-size")) {
309 conf
.cacheSize
= atoi(cmd
.get("--cache-size").c_str());
310 if (conf
.cacheSize
== 0)
311 conf
.cacheEnabled
= false;
314 if (cmd
.check("--size")) {
315 std::vector
<std::string
> dim
= splitStr(cmd
.get("--size"), "x");
316 if (dim
.size() != 2) {
317 Log::fatal("cmdline", "invalid argument for -s/--size");
320 conf
.windowSize
.x
= atoi(dim
[0].c_str());
321 conf
.windowSize
.y
= atoi(dim
[1].c_str());
324 if (cmd
.check("--fullscreen") && cmd
.check("--window")) {
325 Log::fatal("cmdline", "-f/--fullscreen and -w/--window mutually exclusive");
329 if (cmd
.check("--fullscreen"))
330 conf
.fullscreen
= true;
332 if (cmd
.check("--window"))
333 conf
.fullscreen
= false;