1 /******************************
2 ** Tsunagari Tile Engine **
4 ** Copyright 2011 OmegaSDG **
5 ******************************/
10 #include <boost/shared_ptr.hpp>
11 #include <libxml/parser.h>
12 #include <libxml/tree.h>
18 #ifndef LIBXML_TREE_ENABLED
19 # error Tree must be enabled in libxml2
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
29 * Values needed prior to creating the GameWindow.
37 message_mode_t loglevel
;
40 static void xmlErrorCb(void*, const char* msg
, ...)
45 sprintf(buf
, msg
, va_arg(ap
, char*));
46 Log::err(CLIENT_CONF_FILE
, buf
);
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
)
66 doc
= xmlReadFile(filename
, NULL
, XML_PARSE_NOBLANKS
);
69 Log::err(filename
, "Could not parse file");
73 boost::shared_ptr
<void> alwaysFreeTheDoc(doc
, xmlFreeDoc
);
76 ctxt
.error
= xmlErrorCb
;
77 if (!xmlValidateDocument(&ctxt
, doc
)) {
78 Log::err(filename
, "XML document does not follow DTD");
82 root
= xmlDocGetRootElement(doc
);
83 xmlNode
* node
= root
->xmlChildrenNode
; // <client>
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"));
109 conf
->cache_enabled
= T_None
;
111 conf
->cache_enabled
= (tern
)parseBool((char*)str
);
112 str
= xmlGetProp(node
, BAD_CAST("ttl"));
114 conf
->cache_ttl
= T_None
;
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
;
127 Log::err(filename
, "Invalid logging level defined");
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.
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
152 if (!parseClientConfig(CLIENT_CONF_FILE
, &CLIENT_CONFIG
))
155 GameWindow
window(CLIENT_CONFIG
.windowsize
.x
,
156 CLIENT_CONFIG
.windowsize
.y
,
157 CLIENT_CONFIG
.fullscreen
);
158 if (!window
.init(CLIENT_CONFIG
.world
))
162 // Clean the XML library.