engine errors thrown as Py error if in Py script
[Tsunagari.git] / src / client-conf.cpp
blob00bb6418e7d1d092881618106f0b8fbb7a7e7af0
1 /****************************
2 ** Tsunagari Tile Engine **
3 ** client-conf.cpp **
4 ** Copyright 2012 OmegaSDG **
5 ****************************/
7 #include <iostream>
8 #include <fstream>
10 #include <boost/config.hpp>
11 #include <boost/program_options.hpp>
12 #include <boost/program_options/detail/config_file.hpp>
13 #include <boost/program_options/parsers.hpp>
15 #include "client-conf.h"
16 #include "cmd.h"
17 #include "config.h"
18 #include "string.h"
20 Conf conf; // Project-wide global configuration.
22 Conf::Conf()
24 worldFilename = "";
25 windowSize.x = 0;
26 windowSize.y = 0;
27 persistInit = 0;
28 persistCons = 0;
31 //! Check for missing required configuration variables.
32 bool Conf::validate(const char* filename)
34 bool good_conf = true;
36 if (conf.worldFilename == "") {
37 Log::fatal(filename, "\"[engine] world\" option or equivalent command line option expected");
38 good_conf = false;
40 if (!conf.windowSize.x) {
41 Log::fatal(filename, "\"[window] width\" option or equivalent command line option expected");
42 good_conf = false;
44 if (!conf.windowSize.y) {
45 Log::fatal(filename, "\"[window] height\" option or equivalent command line option expected");
46 good_conf = false;
48 if (!conf.fullscreen_opt_set) {
49 Log::fatal(filename, "\"[window] fullscreen\" option or equivalent command line option expected");
50 good_conf = false;
52 if (good_conf)
53 return true;
54 else
55 return false;
58 /* Output compiled-in engine defaults. */
59 static void defaultsQuery()
61 std::cerr << "CLIENT_CONF_PATH: "
62 << CLIENT_CONF_PATH << std::endl;
63 std::cerr << "BASE_ZIP_PATH: "
64 << BASE_ZIP_PATH << std::endl;
65 std::cerr << "XML_DTD_PATH: "
66 << XML_DTD_PATH << std::endl;
67 std::cerr << "DEF_ENGINE_WORLD: "
68 << DEF_ENGINE_WORLD << std::endl;
69 std::cerr << "DEF_ENGINE_VERBOSITY: "
70 << DEF_ENGINE_VERBOSITY << std::endl;
71 std::cerr << "DEF_WINDOW_WIDTH: "
72 << DEF_WINDOW_WIDTH << std::endl;
73 std::cerr << "DEF_WINDOW_HEIGHT: "
74 << DEF_WINDOW_HEIGHT << std::endl;
75 std::cerr << "DEF_WINDOW_FULLSCREEN: "
76 << DEF_WINDOW_FULLSCREEN << std::endl;
77 std::cerr << "DEF_AUDIO_ENABLED: "
78 << DEF_AUDIO_ENABLED << std::endl;
79 std::cerr << "DEF_CACHE_ENABLED: "
80 << DEF_CACHE_ENABLED << std::endl;
81 std::cerr << "DEF_CACHE_TTL: "
82 << DEF_CACHE_TTL << std::endl;
83 std::cerr << "DEF_CACHE_SIZE: "
84 << DEF_CACHE_SIZE << std::endl;
87 /**
88 * Load the values we need to start initializing the game from an ini file.
90 * We need to know what size window to create and which World to load. This
91 * information will be stored in an ini file which we parse here.
93 * @param filename Name of the ini file to load from.
95 * @return false if error occured during processing
97 bool parseConfig(const char* filename)
99 namespace pod = boost::program_options::detail;
101 conf.cacheEnabled = DEF_CACHE_TTL && DEF_CACHE_SIZE;
103 std::ifstream config(filename);
104 if (!config) {
105 Log::fatal(filename, "could not parse config");
106 return false;
109 std::set<std::string> options;
110 std::map<std::string, std::string> parameters;
111 options.insert("*");
113 for (pod::config_file_iterator i(config, options), e ; i != e; ++i)
114 parameters[i->string_key] = i->value[0];
116 if (!parameters["engine.world"].empty())
117 conf.worldFilename = parameters["engine.world"];
119 if (!parameters["engine.datapath"].empty())
120 conf.dataPath = splitStr(parameters["engine.datapath"], ",");
122 if (!parameters["window.width"].empty())
123 conf.windowSize.x = atoi(parameters["window.width"].c_str());
125 if (!parameters["window.height"].empty())
126 conf.windowSize.y = atoi(parameters["window.height"].c_str());
128 if (!parameters["window.fullscreen"].empty()) {
129 conf.fullscreen_opt_set = true;
130 conf.fullscreen = parseBool(parameters["window.fullscreen"]);
133 if (parameters["audio.enabled"].size())
134 conf.audioEnabled = parseBool(parameters["audio.enabled"]);
135 else
136 conf.audioEnabled = true;
138 if (!parameters["cache.enabled"].empty()) {
139 if (parseBool(parameters["cache.enabled"]))
140 conf.cacheEnabled = true;
141 else
142 conf.cacheEnabled = false;
145 if (parameters["cache.ttl"].empty())
146 conf.cacheTTL = DEF_CACHE_TTL;
147 else {
148 if (atoi(parameters["cache.ttl"].c_str()) == 0)
149 conf.cacheEnabled = 0;
150 conf.cacheTTL = atoi(parameters["cache.ttl"].c_str());
153 if (parameters["cache.size"].empty())
154 conf.cacheSize = DEF_CACHE_SIZE;
155 else {
156 if (atoi(parameters["cache.size"].c_str()) == 0)
157 conf.cacheEnabled = 0;
158 conf.cacheSize = atoi(parameters["cache.size"].c_str());
161 std::string verbosity = parameters["engine.verbosity"];
162 conf.verbosity = V_NORMAL;
163 if (verbosity.empty())
165 else if (verbosity == "quiet")
166 conf.verbosity = V_QUIET;
167 else if (verbosity == "normal")
168 conf.verbosity = V_NORMAL;
169 else if (verbosity == "verbose")
170 conf.verbosity = V_VERBOSE;
171 else {
172 Log::err(filename, "unknown value for \"[engine] verbosity\", using default");
175 return true;
178 //! Parse and process command line options and arguments.
179 bool parseCommandLine(int argc, char* argv[])
181 CommandLineOptions cmd(argc, argv);
183 cmd.insert("-h", "--help", "", "Display this help message");
184 cmd.insert("-g", "--gameworld", "<world file>", "Game world to load");
185 cmd.insert("-c", "--config", "<config file>", "Client config file to use");
186 cmd.insert("-p", "--datapath", "<file,file,...>", "Prepend zips to data path");
187 cmd.insert("-q", "--quiet", "", "Display only fatal errors");
188 cmd.insert("", "--normal", "", "Display all errors");
189 cmd.insert("-v", "--verbose", "", "Display additional information");
190 cmd.insert("-t", "--cache-ttl", "<seconds>", "Cache time-to-live in seconds");
191 cmd.insert("-m", "--cache-size", "<megabytes>", "Cache size in megabytes");
192 cmd.insert("-s", "--size", "<WxH>", "Window dimensions");
193 cmd.insert("-f", "--fullscreen", "", "Run in fullscreen mode");
194 cmd.insert("-w", "--window", "", "Run in windowed mode");
195 cmd.insert("", "--no-audio", "", "Disable audio");
196 cmd.insert("", "--query", "", "Query compiled-in engine defaults");
197 cmd.insert("", "--version", "", "Print the engine version string");
199 if (!cmd.parse()) {
200 cmd.usage();
201 return false;
204 if (cmd.check("--help")) {
205 cmd.usage();
206 return false;
209 if (cmd.check("--version")) {
210 std::cout << TSUNAGARI_RELEASE_VERSION << std::endl;
211 return false;
214 if (cmd.check("--query")) {
215 defaultsQuery();
216 return false;
219 if (cmd.check("--config")) {
220 if (!parseConfig(cmd.get("--config").c_str()))
221 return false;
224 if (cmd.check("--datapath"))
225 conf.dataPath = splitStr(cmd.get("--datapath"), ",");
227 if (cmd.check("--gameworld"))
228 conf.worldFilename = cmd.get("--gameworld");
230 int verbcount = 0;
231 if (cmd.check("--quiet")) {
232 conf.verbosity = V_QUIET;
233 verbcount++;
235 if (cmd.check("--normal")) {
236 conf.verbosity = V_NORMAL;
237 verbcount++;
239 if (cmd.check("--verbose")) {
240 conf.verbosity = V_VERBOSE;
241 verbcount++;
243 if (verbcount > 1)
244 Log::err("cmdline", "multiple verbosity flags on cmdline, using most verbose");
246 if (cmd.check("--no-audio"))
247 conf.audioEnabled = false;
249 if (cmd.check("--cache-ttl")) {
250 conf.cacheTTL = atoi(cmd.get("--cache-ttl").c_str());
251 if (conf.cacheTTL == 0)
252 conf.cacheEnabled = false;
255 if (cmd.check("--cache-size")) {
256 conf.cacheSize = atoi(cmd.get("--cache-size").c_str());
257 if (conf.cacheSize == 0)
258 conf.cacheEnabled = false;
261 if (cmd.check("--size")) {
262 std::vector<std::string> dim = splitStr(cmd.get("--size"), "x");
263 if (dim.size() != 2) {
264 Log::fatal("cmdline", "invalid argument for -s/--size");
265 return false;
267 conf.windowSize.x = atoi(dim[0].c_str());
268 conf.windowSize.y = atoi(dim[1].c_str());
271 if (cmd.check("--fullscreen") && cmd.check("--window")) {
272 Log::fatal("cmdline", "-f/--fullscreen and -w/--window mutually exclusive");
273 return false;
276 if (cmd.check("--fullscreen")) {
277 conf.fullscreen = true;
278 conf.fullscreen_opt_set = true;
281 if (cmd.check("--window")) {
282 conf.fullscreen = false;
283 conf.fullscreen_opt_set = true;
286 return true;