area.cpp: fix pointer dereference
[Tsunagari.git] / src / main.cpp
blob112827e8fb18946b2fdb1ccf5187b5859be4c5bf
1 /******************************
2 ** Tsunagari Tile Engine **
3 ** main.cpp **
4 ** Copyright 2011 OmegaSDG **
5 ******************************/
7 #include <stdarg.h>
8 #include <string>
10 #include <boost/shared_ptr.hpp>
11 #include <libxml/parser.h>
12 #include <libxml/tree.h>
14 #include "common.h"
15 #include "log.h"
16 #include "window.h"
18 #ifndef LIBXML_TREE_ENABLED
19 # error Tree must be enabled in libxml2
20 #endif
22 /**
23 * These probably won't be changed ever except maybe with a command line option.
25 #define CLIENT_CONF_FILE "./client.conf"
26 #define MESSAGE_MODE MM_DEBUG
28 /**
29 * Values needed prior to creating the GameWindow.
31 struct ClientValues {
32 std::string world;
33 coord_t windowsize;
34 bool fullscreen;
35 tern cache_enabled;
36 tern cache_ttl;
37 message_mode_t loglevel;
38 } CLIENT_CONFIG;
40 static void xmlErrorCb(void*, const char* msg, ...)
42 char buf[512];
43 va_list ap;
44 va_start(ap, msg);
45 sprintf(buf, msg, va_arg(ap, char*));
46 Log::err(CLIENT_CONF_FILE, buf);
47 va_end(ap);
50 /**
51 * Load the values we need to start initializing the game from a JSON file.
53 * We need to know what size window to create and which World to load. This
54 * information will be stored in a JSON file which we parse here.
56 * @param filename Name of the JSON-encoded file to load from.
57 * @param conf Values are stored here.
59 * @return True if successful
61 static bool parseClientConfig(const char* filename, ClientValues* conf)
63 xmlDoc* doc = NULL;
64 xmlNode* root = NULL;
66 doc = xmlReadFile(filename, NULL, XML_PARSE_NOBLANKS);
68 if (!doc) {
69 Log::err(filename, "Could not parse file");
70 return false;
73 boost::shared_ptr<void> alwaysFreeTheDoc(doc, xmlFreeDoc);
75 xmlValidCtxt ctxt;
76 ctxt.error = xmlErrorCb;
77 if (!xmlValidateDocument(&ctxt, doc)) {
78 Log::err(filename, "XML document does not follow DTD");
79 return false;
82 root = xmlDocGetRootElement(doc);
83 xmlNode* node = root->xmlChildrenNode; // <client>
84 xmlChar* str;
86 /* Extract from XML object:
87 * - name of World to load
88 * - width, height, fullscreen-ness of Window
90 node = node->xmlChildrenNode;
91 while (node != NULL) {
92 if (!xmlStrncmp(node->name, BAD_CAST("world"), 6)) {
93 conf->world = (char*)xmlNodeListGetString(doc,
94 node->xmlChildrenNode, 1);
96 else if (!xmlStrncmp(node->name, BAD_CAST("window"), 7)) {
97 str = xmlGetProp(node, BAD_CAST("x"));
98 conf->windowsize.x = atol((char*)str); // atol
100 str = xmlGetProp(node, BAD_CAST("y"));
101 conf->windowsize.y = atol((char*)str); // atol
103 str = xmlGetProp(node, BAD_CAST("fullscreen"));
104 conf->fullscreen = parseBool((char*)str);
106 else if (!xmlStrncmp(node->name, BAD_CAST("cache"), 6)) {
107 str = xmlGetProp(node, BAD_CAST("enabled"));
108 if (str == NULL)
109 conf->cache_enabled = T_None;
110 else
111 conf->cache_enabled = (tern)parseBool((char*)str);
112 str = xmlGetProp(node, BAD_CAST("ttl"));
113 if (str == NULL)
114 conf->cache_ttl = T_None;
115 else
116 conf->cache_ttl = (tern)parseBool((char*)str);
118 else if (!xmlStrncmp(node->name, BAD_CAST("logging"), 8)) {
119 str = xmlGetProp(node, BAD_CAST("level"));
120 if (!strcmp((char*)str, "error"))
121 conf->loglevel = MM_SILENT;
122 else if (!strcmp((char*)str, "devel"))
123 conf->loglevel = MM_DEVELOPER;
124 else if (!strcmp((char*)str, "debug"))
125 conf->loglevel = MM_DEBUG;
126 else
127 Log::err(filename, "Invalid logging level defined");
129 node = node->next;
132 return true;
136 * Load client config and instantiate window.
138 * The client config tells us our window parameters along with which World
139 * we're going to load. The GameWindow class then loads and plays the game.
141 int main()
143 Log::setMode(MESSAGE_MODE);
146 * This initializes the library and checks for potential ABI mismatches
147 * between the version it was compiled for and the actual shared
148 * library used.
150 LIBXML_TEST_VERSION
152 if (!parseClientConfig(CLIENT_CONF_FILE, &CLIENT_CONFIG))
153 return 1;
155 GameWindow window(CLIENT_CONFIG.windowsize.x,
156 CLIENT_CONFIG.windowsize.y,
157 CLIENT_CONFIG.fullscreen);
158 if (!window.init(CLIENT_CONFIG.world))
159 return 1;
160 window.show();
162 // Clean the XML library.
163 xmlCleanupParser();
165 return 0;