1 /******************************
2 ** Tsunagari Tile Engine **
4 ** Copyright 2011 OmegaSDG **
5 ******************************/
10 #include <libxml/parser.h>
11 #include <libxml/tree.h>
17 #ifndef LIBXML_TREE_ENABLED
18 # error Tree must be enabled in libxml2
22 * These probably won't be changed ever except maybe with a command line option.
24 #define CLIENT_CONF_FILE "./client.conf"
25 #define MESSAGE_MODE MM_DEBUG
28 * Values needed prior to creating the GameWindow.
36 message_mode_t loglevel
;
39 static void xmlErrorCb(void*, const char* msg
, ...)
44 sprintf(buf
, msg
, va_arg(ap
, char*));
45 Log::err(CLIENT_CONF_FILE
, buf
);
50 * Load the values we need to start initializing the game from a JSON file.
52 * We need to know what size window to create and which World to load. This
53 * information will be stored in a JSON file which we parse here.
55 * @param filename Name of the JSON-encoded file to load from.
56 * @param conf Values are stored here.
58 * @return True if successful
60 static bool parseClientConfig(const char* filename
, ClientValues
* conf
)
65 doc
= xmlReadFile(filename
, NULL
, XML_PARSE_NOBLANKS
);
68 Log::err(filename
, "Could not parse file");
73 ctxt
.error
= xmlErrorCb
;
74 if (!xmlValidateDocument(&ctxt
, doc
)) {
75 Log::err(filename
, "XML document does not follow DTD");
79 root
= xmlDocGetRootElement(doc
);
80 xmlNode
* node
= root
->xmlChildrenNode
; // <client>
83 /* Extract from XML object:
84 * - name of World to load
85 * - width, height, fullscreen-ness of Window
87 node
= node
->xmlChildrenNode
;
88 while (node
!= NULL
) {
89 if (!xmlStrncmp(node
->name
, BAD_CAST("world"), 6)) {
90 conf
->world
= (char*)xmlNodeListGetString(doc
,
91 node
->xmlChildrenNode
, 1);
93 else if (!xmlStrncmp(node
->name
, BAD_CAST("window"), 7)) {
94 str
= xmlGetProp(node
, BAD_CAST("x"));
95 conf
->windowsize
.x
= atol((char*)str
); // atol
97 str
= xmlGetProp(node
, BAD_CAST("y"));
98 conf
->windowsize
.y
= atol((char*)str
); // atol
100 str
= xmlGetProp(node
, BAD_CAST("fullscreen"));
101 conf
->fullscreen
= parseBool((char*)str
);
103 else if (!xmlStrncmp(node
->name
, BAD_CAST("cache"), 6)) {
104 str
= xmlGetProp(node
, BAD_CAST("enabled"));
106 conf
->cache_enabled
= T_None
;
108 conf
->cache_enabled
= (tern
)parseBool((char*)str
);
109 str
= xmlGetProp(node
, BAD_CAST("ttl"));
111 conf
->cache_ttl
= T_None
;
113 conf
->cache_ttl
= (tern
)parseBool((char*)str
);
115 else if (!xmlStrncmp(node
->name
, BAD_CAST("logging"), 8)) {
116 str
= xmlGetProp(node
, BAD_CAST("level"));
117 if (!strcmp((char*)str
, "error"))
118 conf
->loglevel
= MM_SILENT
;
119 else if (!strcmp((char*)str
, "devel"))
120 conf
->loglevel
= MM_DEVELOPER
;
121 else if (!strcmp((char*)str
, "debug"))
122 conf
->loglevel
= MM_DEBUG
;
124 Log::err(filename
, "Invalid logging level defined");
133 * Load client config and instantiate window.
135 * The client config tells us our window parameters along with which World
136 * we're going to load. The GameWindow class then loads and plays the game.
140 Log::setMode(MESSAGE_MODE
);
143 * This initializes the library and checks for potential ABI mismatches
144 * between the version it was compiled for and the actual shared
149 if (!parseClientConfig(CLIENT_CONF_FILE
, &CLIENT_CONFIG
))
152 GameWindow
window(CLIENT_CONFIG
.windowsize
.x
,
153 CLIENT_CONFIG
.windowsize
.y
,
154 CLIENT_CONFIG
.fullscreen
);
155 if (!window
.init(CLIENT_CONFIG
.world
))
159 // Clean the XML library.