diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/irrlicht-1.8/examples/25.XmlHandling/main.cpp | 1010 |
1 files changed, 505 insertions, 505 deletions
diff --git a/libraries/irrlicht-1.8/examples/25.XmlHandling/main.cpp b/libraries/irrlicht-1.8/examples/25.XmlHandling/main.cpp index 3eb261d..3ae6316 100644 --- a/libraries/irrlicht-1.8/examples/25.XmlHandling/main.cpp +++ b/libraries/irrlicht-1.8/examples/25.XmlHandling/main.cpp | |||
@@ -1,505 +1,505 @@ | |||
1 | /** Example 025 Xml Handling | 1 | /** Example 025 Xml Handling |
2 | 2 | ||
3 | Demonstrates loading and saving of configurations via XML | 3 | Demonstrates loading and saving of configurations via XML |
4 | 4 | ||
5 | @author Y.M. Bosman \<yoran.bosman@gmail.com\> | 5 | @author Y.M. Bosman \<yoran.bosman@gmail.com\> |
6 | 6 | ||
7 | This demo features a fully usable system for configuration handling. The code | 7 | This demo features a fully usable system for configuration handling. The code |
8 | can easily be integrated into own apps. | 8 | can easily be integrated into own apps. |
9 | 9 | ||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <irrlicht.h> | 12 | #include <irrlicht.h> |
13 | 13 | ||
14 | using namespace irr; | 14 | using namespace irr; |
15 | using namespace core; | 15 | using namespace core; |
16 | using namespace scene; | 16 | using namespace scene; |
17 | using namespace video; | 17 | using namespace video; |
18 | using namespace io; | 18 | using namespace io; |
19 | using namespace gui; | 19 | using namespace gui; |
20 | 20 | ||
21 | #ifdef _IRR_WINDOWS_ | 21 | #ifdef _IRR_WINDOWS_ |
22 | #pragma comment(lib, "Irrlicht.lib") | 22 | #pragma comment(lib, "Irrlicht.lib") |
23 | #endif | 23 | #endif |
24 | 24 | ||
25 | 25 | ||
26 | /* SettingManager class. | 26 | /* SettingManager class. |
27 | 27 | ||
28 | This class loads and writes the settings and manages the options. | 28 | This class loads and writes the settings and manages the options. |
29 | 29 | ||
30 | The class makes use of irrMap which is a an associative arrays using a | 30 | The class makes use of irrMap which is a an associative arrays using a |
31 | red-black tree it allows easy mapping of a key to a value, along the way there | 31 | red-black tree it allows easy mapping of a key to a value, along the way there |
32 | is some information on how to use it. | 32 | is some information on how to use it. |
33 | */ | 33 | */ |
34 | 34 | ||
35 | class SettingManager | 35 | class SettingManager |
36 | { | 36 | { |
37 | public: | 37 | public: |
38 | 38 | ||
39 | // Construct setting managers and set default settings | 39 | // Construct setting managers and set default settings |
40 | SettingManager(const stringw& settings_file): SettingsFile(settings_file), NullDevice(0) | 40 | SettingManager(const stringw& settings_file): SettingsFile(settings_file), NullDevice(0) |
41 | { | 41 | { |
42 | // Irrlicht null device, we want to load settings before we actually created our device, therefore, nulldevice | 42 | // Irrlicht null device, we want to load settings before we actually created our device, therefore, nulldevice |
43 | NullDevice = irr::createDevice(irr::video::EDT_NULL); | 43 | NullDevice = irr::createDevice(irr::video::EDT_NULL); |
44 | 44 | ||
45 | //DriverOptions is an irrlicht map, | 45 | //DriverOptions is an irrlicht map, |
46 | //we can insert values in the map in two ways by calling insert(key,value) or by using the [key] operator | 46 | //we can insert values in the map in two ways by calling insert(key,value) or by using the [key] operator |
47 | //the [] operator overrides values if they already exist | 47 | //the [] operator overrides values if they already exist |
48 | DriverOptions.insert(L"Software", EDT_SOFTWARE); | 48 | DriverOptions.insert(L"Software", EDT_SOFTWARE); |
49 | DriverOptions.insert(L"OpenGL", EDT_OPENGL); | 49 | DriverOptions.insert(L"OpenGL", EDT_OPENGL); |
50 | DriverOptions.insert(L"Direct3D9", EDT_DIRECT3D9); | 50 | DriverOptions.insert(L"Direct3D9", EDT_DIRECT3D9); |
51 | 51 | ||
52 | //some resolution options | 52 | //some resolution options |
53 | ResolutionOptions.insert(L"640x480", dimension2du(640,480)); | 53 | ResolutionOptions.insert(L"640x480", dimension2du(640,480)); |
54 | ResolutionOptions.insert(L"800x600", dimension2du(800,600)); | 54 | ResolutionOptions.insert(L"800x600", dimension2du(800,600)); |
55 | ResolutionOptions.insert(L"1024x768", dimension2du(1024,768)); | 55 | ResolutionOptions.insert(L"1024x768", dimension2du(1024,768)); |
56 | 56 | ||
57 | //our preferred defaults | 57 | //our preferred defaults |
58 | SettingMap.insert(L"driver", L"Direct3D9"); | 58 | SettingMap.insert(L"driver", L"Direct3D9"); |
59 | SettingMap.insert(L"resolution", L"640x480"); | 59 | SettingMap.insert(L"resolution", L"640x480"); |
60 | SettingMap.insert(L"fullscreen", L"0"); //0 is false | 60 | SettingMap.insert(L"fullscreen", L"0"); //0 is false |
61 | } | 61 | } |
62 | 62 | ||
63 | // Destructor, you could store settings automatically on exit of your | 63 | // Destructor, you could store settings automatically on exit of your |
64 | // application if you wanted to in our case we simply drop the | 64 | // application if you wanted to in our case we simply drop the |
65 | // nulldevice | 65 | // nulldevice |
66 | ~SettingManager() | 66 | ~SettingManager() |
67 | { | 67 | { |
68 | if (NullDevice) | 68 | if (NullDevice) |
69 | { | 69 | { |
70 | NullDevice->closeDevice(); | 70 | NullDevice->closeDevice(); |
71 | NullDevice->drop(); | 71 | NullDevice->drop(); |
72 | } | 72 | } |
73 | }; | 73 | }; |
74 | 74 | ||
75 | /* | 75 | /* |
76 | Load xml from disk, overwrite default settings | 76 | Load xml from disk, overwrite default settings |
77 | The xml we are trying to load has the following structure | 77 | The xml we are trying to load has the following structure |
78 | settings nested in sections nested in the root node, like so | 78 | settings nested in sections nested in the root node, like so |
79 | <pre> | 79 | <pre> |
80 | <?xml version="1.0"?> | 80 | <?xml version="1.0"?> |
81 | <mygame> | 81 | <mygame> |
82 | <video> | 82 | <video> |
83 | <setting name="driver" value="Direct3D9" /> | 83 | <setting name="driver" value="Direct3D9" /> |
84 | <setting name="fullscreen" value="0" /> | 84 | <setting name="fullscreen" value="0" /> |
85 | <setting name="resolution" value="1024x768" /> | 85 | <setting name="resolution" value="1024x768" /> |
86 | </video> | 86 | </video> |
87 | </mygame> | 87 | </mygame> |
88 | </pre> | 88 | </pre> |
89 | */ | 89 | */ |
90 | bool load() | 90 | bool load() |
91 | { | 91 | { |
92 | //if not able to create device don't attempt to load | 92 | //if not able to create device don't attempt to load |
93 | if (!NullDevice) | 93 | if (!NullDevice) |
94 | return false; | 94 | return false; |
95 | 95 | ||
96 | irr::io::IXMLReader* xml = NullDevice->getFileSystem()->createXMLReader(SettingsFile); //create xml reader | 96 | irr::io::IXMLReader* xml = NullDevice->getFileSystem()->createXMLReader(SettingsFile); //create xml reader |
97 | if (!xml) | 97 | if (!xml) |
98 | return false; | 98 | return false; |
99 | 99 | ||
100 | const stringw settingTag(L"setting"); //we'll be looking for this tag in the xml | 100 | const stringw settingTag(L"setting"); //we'll be looking for this tag in the xml |
101 | stringw currentSection; //keep track of our current section | 101 | stringw currentSection; //keep track of our current section |
102 | const stringw videoTag(L"video"); //constant for videotag | 102 | const stringw videoTag(L"video"); //constant for videotag |
103 | 103 | ||
104 | //while there is more to read | 104 | //while there is more to read |
105 | while (xml->read()) | 105 | while (xml->read()) |
106 | { | 106 | { |
107 | //check the node type | 107 | //check the node type |
108 | switch (xml->getNodeType()) | 108 | switch (xml->getNodeType()) |
109 | { | 109 | { |
110 | //we found a new element | 110 | //we found a new element |
111 | case irr::io::EXN_ELEMENT: | 111 | case irr::io::EXN_ELEMENT: |
112 | { | 112 | { |
113 | //we currently are in the empty or mygame section and find the video tag so we set our current section to video | 113 | //we currently are in the empty or mygame section and find the video tag so we set our current section to video |
114 | if (currentSection.empty() && videoTag.equals_ignore_case(xml->getNodeName())) | 114 | if (currentSection.empty() && videoTag.equals_ignore_case(xml->getNodeName())) |
115 | { | 115 | { |
116 | currentSection = videoTag; | 116 | currentSection = videoTag; |
117 | } | 117 | } |
118 | //we are in the video section and we find a setting to parse | 118 | //we are in the video section and we find a setting to parse |
119 | else if (currentSection.equals_ignore_case(videoTag) && settingTag.equals_ignore_case(xml->getNodeName() )) | 119 | else if (currentSection.equals_ignore_case(videoTag) && settingTag.equals_ignore_case(xml->getNodeName() )) |
120 | { | 120 | { |
121 | //read in the key | 121 | //read in the key |
122 | stringw key = xml->getAttributeValueSafe(L"name"); | 122 | stringw key = xml->getAttributeValueSafe(L"name"); |
123 | //if there actually is a key to set | 123 | //if there actually is a key to set |
124 | if (!key.empty()) | 124 | if (!key.empty()) |
125 | { | 125 | { |
126 | //set the setting in the map to the value, | 126 | //set the setting in the map to the value, |
127 | //the [] operator overrides values if they already exist or inserts a new key value | 127 | //the [] operator overrides values if they already exist or inserts a new key value |
128 | //pair into the settings map if it was not defined yet | 128 | //pair into the settings map if it was not defined yet |
129 | SettingMap[key] = xml->getAttributeValueSafe(L"value"); | 129 | SettingMap[key] = xml->getAttributeValueSafe(L"value"); |
130 | } | 130 | } |
131 | } | 131 | } |
132 | 132 | ||
133 | //.. | 133 | //.. |
134 | // You can add your own sections and tags to read in here | 134 | // You can add your own sections and tags to read in here |
135 | //.. | 135 | //.. |
136 | } | 136 | } |
137 | break; | 137 | break; |
138 | 138 | ||
139 | //we found the end of an element | 139 | //we found the end of an element |
140 | case irr::io::EXN_ELEMENT_END: | 140 | case irr::io::EXN_ELEMENT_END: |
141 | //we were at the end of the video section so we reset our tag | 141 | //we were at the end of the video section so we reset our tag |
142 | currentSection=L""; | 142 | currentSection=L""; |
143 | break; | 143 | break; |
144 | } | 144 | } |
145 | } | 145 | } |
146 | 146 | ||
147 | // don't forget to delete the xml reader | 147 | // don't forget to delete the xml reader |
148 | xml->drop(); | 148 | xml->drop(); |
149 | 149 | ||
150 | return true; | 150 | return true; |
151 | } | 151 | } |
152 | 152 | ||
153 | // Save the xml to disk. We use the nulldevice. | 153 | // Save the xml to disk. We use the nulldevice. |
154 | bool save() | 154 | bool save() |
155 | { | 155 | { |
156 | 156 | ||
157 | //if not able to create device don't attempt to save | 157 | //if not able to create device don't attempt to save |
158 | if (!NullDevice) | 158 | if (!NullDevice) |
159 | return false; | 159 | return false; |
160 | 160 | ||
161 | //create xml writer | 161 | //create xml writer |
162 | irr::io::IXMLWriter* xwriter = NullDevice->getFileSystem()->createXMLWriter( SettingsFile ); | 162 | irr::io::IXMLWriter* xwriter = NullDevice->getFileSystem()->createXMLWriter( SettingsFile ); |
163 | if (!xwriter) | 163 | if (!xwriter) |
164 | return false; | 164 | return false; |
165 | 165 | ||
166 | //write out the obligatory xml header. Each xml-file needs to have exactly one of those. | 166 | //write out the obligatory xml header. Each xml-file needs to have exactly one of those. |
167 | xwriter->writeXMLHeader(); | 167 | xwriter->writeXMLHeader(); |
168 | 168 | ||
169 | //start element mygame, you replace the label "mygame" with anything you want | 169 | //start element mygame, you replace the label "mygame" with anything you want |
170 | xwriter->writeElement(L"mygame"); | 170 | xwriter->writeElement(L"mygame"); |
171 | xwriter->writeLineBreak(); //new line | 171 | xwriter->writeLineBreak(); //new line |
172 | 172 | ||
173 | //start section with video settings | 173 | //start section with video settings |
174 | xwriter->writeElement(L"video"); | 174 | xwriter->writeElement(L"video"); |
175 | xwriter->writeLineBreak(); //new line | 175 | xwriter->writeLineBreak(); //new line |
176 | 176 | ||
177 | // getIterator gets us a pointer to the first node of the settings map | 177 | // getIterator gets us a pointer to the first node of the settings map |
178 | // every iteration we increase the iterator which gives us the next map node | 178 | // every iteration we increase the iterator which gives us the next map node |
179 | // until we reach the end we write settings one by one by using the nodes key and value functions | 179 | // until we reach the end we write settings one by one by using the nodes key and value functions |
180 | map<stringw, stringw>::Iterator i = SettingMap.getIterator(); | 180 | map<stringw, stringw>::Iterator i = SettingMap.getIterator(); |
181 | for(; !i.atEnd(); i++) | 181 | for(; !i.atEnd(); i++) |
182 | { | 182 | { |
183 | //write element as <setting name="key" value="x" /> | 183 | //write element as <setting name="key" value="x" /> |
184 | //the second parameter indicates this is an empty element with no children, just attributes | 184 | //the second parameter indicates this is an empty element with no children, just attributes |
185 | xwriter->writeElement(L"setting",true, L"name", i->getKey().c_str(), L"value",i->getValue().c_str() ); | 185 | xwriter->writeElement(L"setting",true, L"name", i->getKey().c_str(), L"value",i->getValue().c_str() ); |
186 | xwriter->writeLineBreak(); | 186 | xwriter->writeLineBreak(); |
187 | } | 187 | } |
188 | xwriter->writeLineBreak(); | 188 | xwriter->writeLineBreak(); |
189 | 189 | ||
190 | //close video section | 190 | //close video section |
191 | xwriter->writeClosingTag(L"video"); | 191 | xwriter->writeClosingTag(L"video"); |
192 | xwriter->writeLineBreak(); | 192 | xwriter->writeLineBreak(); |
193 | 193 | ||
194 | //.. | 194 | //.. |
195 | // You can add writing sound settings, savegame information etc | 195 | // You can add writing sound settings, savegame information etc |
196 | //.. | 196 | //.. |
197 | 197 | ||
198 | //close mygame section | 198 | //close mygame section |
199 | xwriter->writeClosingTag(L"mygame"); | 199 | xwriter->writeClosingTag(L"mygame"); |
200 | 200 | ||
201 | //delete xml writer | 201 | //delete xml writer |
202 | xwriter->drop(); | 202 | xwriter->drop(); |
203 | 203 | ||
204 | return true; | 204 | return true; |
205 | } | 205 | } |
206 | 206 | ||
207 | // Set setting in our manager | 207 | // Set setting in our manager |
208 | void setSetting(const stringw& name, const stringw& value) | 208 | void setSetting(const stringw& name, const stringw& value) |
209 | { | 209 | { |
210 | SettingMap[name]=value; | 210 | SettingMap[name]=value; |
211 | } | 211 | } |
212 | 212 | ||
213 | // set setting overload to quickly assign integers to our setting map | 213 | // set setting overload to quickly assign integers to our setting map |
214 | void setSetting(const stringw& name, s32 value) | 214 | void setSetting(const stringw& name, s32 value) |
215 | { | 215 | { |
216 | SettingMap[name]=stringw(value); | 216 | SettingMap[name]=stringw(value); |
217 | } | 217 | } |
218 | 218 | ||
219 | // Get setting as string | 219 | // Get setting as string |
220 | stringw getSetting(const stringw& key) const | 220 | stringw getSetting(const stringw& key) const |
221 | { | 221 | { |
222 | //the find function or irrmap returns a pointer to a map Node | 222 | //the find function or irrmap returns a pointer to a map Node |
223 | //if the key can be found, otherwise it returns null | 223 | //if the key can be found, otherwise it returns null |
224 | //the map node has the function getValue and getKey, as we already know the key, we return node->getValue() | 224 | //the map node has the function getValue and getKey, as we already know the key, we return node->getValue() |
225 | map<stringw, stringw>::Node* n = SettingMap.find(key); | 225 | map<stringw, stringw>::Node* n = SettingMap.find(key); |
226 | if (n) | 226 | if (n) |
227 | return n->getValue(); | 227 | return n->getValue(); |
228 | else | 228 | else |
229 | return L""; | 229 | return L""; |
230 | } | 230 | } |
231 | 231 | ||
232 | // | 232 | // |
233 | bool getSettingAsBoolean(const stringw& key ) const | 233 | bool getSettingAsBoolean(const stringw& key ) const |
234 | { | 234 | { |
235 | stringw s = getSetting(key); | 235 | stringw s = getSetting(key); |
236 | if (s.empty()) | 236 | if (s.empty()) |
237 | return false; | 237 | return false; |
238 | return s.equals_ignore_case(L"1"); | 238 | return s.equals_ignore_case(L"1"); |
239 | } | 239 | } |
240 | 240 | ||
241 | // | 241 | // |
242 | s32 getSettingAsInteger(const stringw& key) const | 242 | s32 getSettingAsInteger(const stringw& key) const |
243 | { | 243 | { |
244 | //we implicitly cast to string instead of stringw because strtol10 does not accept wide strings | 244 | //we implicitly cast to string instead of stringw because strtol10 does not accept wide strings |
245 | const stringc s = getSetting(key); | 245 | const stringc s = getSetting(key); |
246 | if (s.empty()) | 246 | if (s.empty()) |
247 | return 0; | 247 | return 0; |
248 | 248 | ||
249 | return strtol10(s.c_str()); | 249 | return strtol10(s.c_str()); |
250 | } | 250 | } |
251 | 251 | ||
252 | public: | 252 | public: |
253 | map<stringw, s32> DriverOptions; //available options for driver config | 253 | map<stringw, s32> DriverOptions; //available options for driver config |
254 | map<stringw, dimension2du> ResolutionOptions; //available options for resolution config | 254 | map<stringw, dimension2du> ResolutionOptions; //available options for resolution config |
255 | private: | 255 | private: |
256 | SettingManager(const SettingManager& other); // defined but not implemented | 256 | SettingManager(const SettingManager& other); // defined but not implemented |
257 | SettingManager& operator=(const SettingManager& other); // defined but not implemented | 257 | SettingManager& operator=(const SettingManager& other); // defined but not implemented |
258 | 258 | ||
259 | map<stringw, stringw> SettingMap; //current config | 259 | map<stringw, stringw> SettingMap; //current config |
260 | 260 | ||
261 | stringw SettingsFile; // location of the xml, usually the | 261 | stringw SettingsFile; // location of the xml, usually the |
262 | irr::IrrlichtDevice* NullDevice; | 262 | irr::IrrlichtDevice* NullDevice; |
263 | }; | 263 | }; |
264 | 264 | ||
265 | /* | 265 | /* |
266 | Application context for global variables | 266 | Application context for global variables |
267 | */ | 267 | */ |
268 | struct SAppContext | 268 | struct SAppContext |
269 | { | 269 | { |
270 | SAppContext() | 270 | SAppContext() |
271 | : Device(0),Gui(0), Driver(0), Settings(0), ShouldQuit(false), | 271 | : Device(0),Gui(0), Driver(0), Settings(0), ShouldQuit(false), |
272 | ButtonSave(0), ButtonExit(0), ListboxDriver(0), | 272 | ButtonSave(0), ButtonExit(0), ListboxDriver(0), |
273 | ListboxResolution(0), CheckboxFullscreen(0) | 273 | ListboxResolution(0), CheckboxFullscreen(0) |
274 | { | 274 | { |
275 | } | 275 | } |
276 | 276 | ||
277 | ~SAppContext() | 277 | ~SAppContext() |
278 | { | 278 | { |
279 | if (Settings) | 279 | if (Settings) |
280 | delete Settings; | 280 | delete Settings; |
281 | 281 | ||
282 | if (Device) | 282 | if (Device) |
283 | { | 283 | { |
284 | Device->closeDevice(); | 284 | Device->closeDevice(); |
285 | Device->drop(); | 285 | Device->drop(); |
286 | } | 286 | } |
287 | } | 287 | } |
288 | 288 | ||
289 | IrrlichtDevice* Device; | 289 | IrrlichtDevice* Device; |
290 | IGUIEnvironment* Gui; | 290 | IGUIEnvironment* Gui; |
291 | IVideoDriver* Driver; | 291 | IVideoDriver* Driver; |
292 | SettingManager* Settings; | 292 | SettingManager* Settings; |
293 | bool ShouldQuit; | 293 | bool ShouldQuit; |
294 | 294 | ||
295 | //settings dialog | 295 | //settings dialog |
296 | IGUIButton* ButtonSave; | 296 | IGUIButton* ButtonSave; |
297 | IGUIButton* ButtonExit; | 297 | IGUIButton* ButtonExit; |
298 | IGUIListBox* ListboxDriver; | 298 | IGUIListBox* ListboxDriver; |
299 | IGUIListBox* ListboxResolution; | 299 | IGUIListBox* ListboxResolution; |
300 | IGUICheckBox* CheckboxFullscreen; | 300 | IGUICheckBox* CheckboxFullscreen; |
301 | }; | 301 | }; |
302 | 302 | ||
303 | /* | 303 | /* |
304 | A typical event receiver. | 304 | A typical event receiver. |
305 | */ | 305 | */ |
306 | class MyEventReceiver : public IEventReceiver | 306 | class MyEventReceiver : public IEventReceiver |
307 | { | 307 | { |
308 | public: | 308 | public: |
309 | MyEventReceiver(SAppContext & a) : App(a) { } | 309 | MyEventReceiver(SAppContext & a) : App(a) { } |
310 | 310 | ||
311 | virtual bool OnEvent(const SEvent& event) | 311 | virtual bool OnEvent(const SEvent& event) |
312 | { | 312 | { |
313 | if (event.EventType == EET_GUI_EVENT ) | 313 | if (event.EventType == EET_GUI_EVENT ) |
314 | { | 314 | { |
315 | switch ( event.GUIEvent.EventType ) | 315 | switch ( event.GUIEvent.EventType ) |
316 | { | 316 | { |
317 | //handle button click events | 317 | //handle button click events |
318 | case EGET_BUTTON_CLICKED: | 318 | case EGET_BUTTON_CLICKED: |
319 | { | 319 | { |
320 | //Our save button was called so we obtain the settings from our dialog and save them | 320 | //Our save button was called so we obtain the settings from our dialog and save them |
321 | if ( event.GUIEvent.Caller == App.ButtonSave ) | 321 | if ( event.GUIEvent.Caller == App.ButtonSave ) |
322 | { | 322 | { |
323 | //if there is a selection write it | 323 | //if there is a selection write it |
324 | if ( App.ListboxDriver->getSelected() != -1) | 324 | if ( App.ListboxDriver->getSelected() != -1) |
325 | App.Settings->setSetting(L"driver", App.ListboxDriver->getListItem(App.ListboxDriver->getSelected())); | 325 | App.Settings->setSetting(L"driver", App.ListboxDriver->getListItem(App.ListboxDriver->getSelected())); |
326 | 326 | ||
327 | //if there is a selection write it | 327 | //if there is a selection write it |
328 | if ( App.ListboxResolution->getSelected() != -1) | 328 | if ( App.ListboxResolution->getSelected() != -1) |
329 | App.Settings->setSetting(L"resolution", App.ListboxResolution->getListItem(App.ListboxResolution->getSelected())); | 329 | App.Settings->setSetting(L"resolution", App.ListboxResolution->getListItem(App.ListboxResolution->getSelected())); |
330 | 330 | ||
331 | App.Settings->setSetting(L"fullscreen", App.CheckboxFullscreen->isChecked()); | 331 | App.Settings->setSetting(L"fullscreen", App.CheckboxFullscreen->isChecked()); |
332 | 332 | ||
333 | 333 | ||
334 | if (App.Settings->save()) | 334 | if (App.Settings->save()) |
335 | { | 335 | { |
336 | App.Gui->addMessageBox(L"settings save",L"settings saved, please restart for settings to change effect","",true); | 336 | App.Gui->addMessageBox(L"settings save",L"settings saved, please restart for settings to change effect","",true); |
337 | } | 337 | } |
338 | } | 338 | } |
339 | // cancel/exit button clicked, tell the application to exit | 339 | // cancel/exit button clicked, tell the application to exit |
340 | else if ( event.GUIEvent.Caller == App.ButtonExit) | 340 | else if ( event.GUIEvent.Caller == App.ButtonExit) |
341 | { | 341 | { |
342 | App.ShouldQuit = true; | 342 | App.ShouldQuit = true; |
343 | } | 343 | } |
344 | } | 344 | } |
345 | break; | 345 | break; |
346 | } | 346 | } |
347 | } | 347 | } |
348 | 348 | ||
349 | return false; | 349 | return false; |
350 | } | 350 | } |
351 | 351 | ||
352 | private: | 352 | private: |
353 | SAppContext & App; | 353 | SAppContext & App; |
354 | }; | 354 | }; |
355 | 355 | ||
356 | 356 | ||
357 | /* | 357 | /* |
358 | Function to create a video settings dialog | 358 | Function to create a video settings dialog |
359 | This dialog shows the current settings from the configuration xml and allows them to be changed | 359 | This dialog shows the current settings from the configuration xml and allows them to be changed |
360 | */ | 360 | */ |
361 | void createSettingsDialog(SAppContext& app) | 361 | void createSettingsDialog(SAppContext& app) |
362 | { | 362 | { |
363 | // first get rid of alpha in gui | 363 | // first get rid of alpha in gui |
364 | for (irr::s32 i=0; i<irr::gui::EGDC_COUNT ; ++i) | 364 | for (irr::s32 i=0; i<irr::gui::EGDC_COUNT ; ++i) |
365 | { | 365 | { |
366 | irr::video::SColor col = app.Gui->getSkin()->getColor((irr::gui::EGUI_DEFAULT_COLOR)i); | 366 | irr::video::SColor col = app.Gui->getSkin()->getColor((irr::gui::EGUI_DEFAULT_COLOR)i); |
367 | col.setAlpha(255); | 367 | col.setAlpha(255); |
368 | app.Gui->getSkin()->setColor((irr::gui::EGUI_DEFAULT_COLOR)i, col); | 368 | app.Gui->getSkin()->setColor((irr::gui::EGUI_DEFAULT_COLOR)i, col); |
369 | } | 369 | } |
370 | 370 | ||
371 | //create video settings windows | 371 | //create video settings windows |
372 | gui::IGUIWindow* windowSettings = app.Gui->addWindow(rect<s32>(10,10,400,400),true,L"Videosettings"); | 372 | gui::IGUIWindow* windowSettings = app.Gui->addWindow(rect<s32>(10,10,400,400),true,L"Videosettings"); |
373 | app.Gui->addStaticText (L"Select your desired video settings", rect< s32 >(10,20, 200, 40), false, true, windowSettings); | 373 | app.Gui->addStaticText (L"Select your desired video settings", rect< s32 >(10,20, 200, 40), false, true, windowSettings); |
374 | 374 | ||
375 | // add listbox for driver choice | 375 | // add listbox for driver choice |
376 | app.Gui->addStaticText (L"Driver", rect< s32 >(10,50, 200, 60), false, true, windowSettings); | 376 | app.Gui->addStaticText (L"Driver", rect< s32 >(10,50, 200, 60), false, true, windowSettings); |
377 | app.ListboxDriver = app.Gui->addListBox(rect<s32>(10,60,220,120), windowSettings, 1,true); | 377 | app.ListboxDriver = app.Gui->addListBox(rect<s32>(10,60,220,120), windowSettings, 1,true); |
378 | 378 | ||
379 | //add all available options to the driver choice listbox | 379 | //add all available options to the driver choice listbox |
380 | map<stringw, s32>::Iterator i = app.Settings->DriverOptions.getIterator(); | 380 | map<stringw, s32>::Iterator i = app.Settings->DriverOptions.getIterator(); |
381 | for(; !i.atEnd(); i++) | 381 | for(; !i.atEnd(); i++) |
382 | app.ListboxDriver->addItem(i->getKey().c_str()); | 382 | app.ListboxDriver->addItem(i->getKey().c_str()); |
383 | 383 | ||
384 | //set currently selected driver | 384 | //set currently selected driver |
385 | app.ListboxDriver->setSelected(app.Settings->getSetting("driver").c_str()); | 385 | app.ListboxDriver->setSelected(app.Settings->getSetting("driver").c_str()); |
386 | 386 | ||
387 | // add listbox for resolution choice | 387 | // add listbox for resolution choice |
388 | app.Gui->addStaticText (L"Resolution", rect< s32 >(10,130, 200, 140), false, true, windowSettings); | 388 | app.Gui->addStaticText (L"Resolution", rect< s32 >(10,130, 200, 140), false, true, windowSettings); |
389 | app.ListboxResolution = app.Gui->addListBox(rect<s32>(10,140,220,200), windowSettings, 1,true); | 389 | app.ListboxResolution = app.Gui->addListBox(rect<s32>(10,140,220,200), windowSettings, 1,true); |
390 | 390 | ||
391 | //add all available options to the resolution listbox | 391 | //add all available options to the resolution listbox |
392 | map<stringw, dimension2du>::Iterator ri = app.Settings->ResolutionOptions.getIterator(); | 392 | map<stringw, dimension2du>::Iterator ri = app.Settings->ResolutionOptions.getIterator(); |
393 | for(; !ri.atEnd(); ri++) | 393 | for(; !ri.atEnd(); ri++) |
394 | app.ListboxResolution->addItem(ri->getKey().c_str()); | 394 | app.ListboxResolution->addItem(ri->getKey().c_str()); |
395 | 395 | ||
396 | //set currently selected resolution | 396 | //set currently selected resolution |
397 | app.ListboxResolution->setSelected(app.Settings->getSetting("resolution").c_str()); | 397 | app.ListboxResolution->setSelected(app.Settings->getSetting("resolution").c_str()); |
398 | 398 | ||
399 | //add checkbox to toggle fullscreen, initially set to loaded setting | 399 | //add checkbox to toggle fullscreen, initially set to loaded setting |
400 | app.CheckboxFullscreen = app.Gui->addCheckBox( | 400 | app.CheckboxFullscreen = app.Gui->addCheckBox( |
401 | app.Settings->getSettingAsBoolean("fullscreen"), | 401 | app.Settings->getSettingAsBoolean("fullscreen"), |
402 | rect<s32>(10,220,220,240), windowSettings, -1, | 402 | rect<s32>(10,220,220,240), windowSettings, -1, |
403 | L"Fullscreen"); | 403 | L"Fullscreen"); |
404 | 404 | ||
405 | //last but not least add save button | 405 | //last but not least add save button |
406 | app.ButtonSave = app.Gui->addButton( | 406 | app.ButtonSave = app.Gui->addButton( |
407 | rect<s32>(80,250,150,270), windowSettings, 2, | 407 | rect<s32>(80,250,150,270), windowSettings, 2, |
408 | L"Save video settings"); | 408 | L"Save video settings"); |
409 | 409 | ||
410 | //exit/cancel button | 410 | //exit/cancel button |
411 | app.ButtonExit = app.Gui->addButton( | 411 | app.ButtonExit = app.Gui->addButton( |
412 | rect<s32>(160,250,240,270), windowSettings, 2, | 412 | rect<s32>(160,250,240,270), windowSettings, 2, |
413 | L"Cancel and exit"); | 413 | L"Cancel and exit"); |
414 | } | 414 | } |
415 | 415 | ||
416 | /* | 416 | /* |
417 | The main function. Creates all objects and does the XML handling. | 417 | The main function. Creates all objects and does the XML handling. |
418 | */ | 418 | */ |
419 | int main() | 419 | int main() |
420 | { | 420 | { |
421 | //create new application context | 421 | //create new application context |
422 | SAppContext app; | 422 | SAppContext app; |
423 | 423 | ||
424 | //create device creation parameters that can get overwritten by our settings file | 424 | //create device creation parameters that can get overwritten by our settings file |
425 | SIrrlichtCreationParameters param; | 425 | SIrrlichtCreationParameters param; |
426 | param.DriverType = EDT_SOFTWARE; | 426 | param.DriverType = EDT_SOFTWARE; |
427 | param.WindowSize.set(640,480); | 427 | param.WindowSize.set(640,480); |
428 | 428 | ||
429 | // Try to load config. | 429 | // Try to load config. |
430 | // I leave it as an exercise of the reader to store the configuration in the local application data folder, | 430 | // I leave it as an exercise of the reader to store the configuration in the local application data folder, |
431 | // the only logical place to store config data for games. For all other operating systems I redirect to your manuals | 431 | // the only logical place to store config data for games. For all other operating systems I redirect to your manuals |
432 | app.Settings = new SettingManager("../../media/settings.xml"); | 432 | app.Settings = new SettingManager("../../media/settings.xml"); |
433 | if ( !app.Settings->load() ) | 433 | if ( !app.Settings->load() ) |
434 | { | 434 | { |
435 | // ... | 435 | // ... |
436 | // Here add your own exception handling, for now we continue because there are defaults set in SettingManager constructor | 436 | // Here add your own exception handling, for now we continue because there are defaults set in SettingManager constructor |
437 | // ... | 437 | // ... |
438 | } | 438 | } |
439 | else | 439 | else |
440 | { | 440 | { |
441 | //settings xml loaded from disk, | 441 | //settings xml loaded from disk, |
442 | 442 | ||
443 | //map driversetting to driver type and test if the setting is valid | 443 | //map driversetting to driver type and test if the setting is valid |
444 | //the DriverOptions map contains string representations mapped to to irrlicht E_DRIVER_TYPE enum | 444 | //the DriverOptions map contains string representations mapped to to irrlicht E_DRIVER_TYPE enum |
445 | //e.g "direct3d9" will become 4 | 445 | //e.g "direct3d9" will become 4 |
446 | //see DriverOptions in the settingmanager class for details | 446 | //see DriverOptions in the settingmanager class for details |
447 | map<stringw, s32>::Node* driver = app.Settings->DriverOptions.find( app.Settings->getSetting("driver") ); | 447 | map<stringw, s32>::Node* driver = app.Settings->DriverOptions.find( app.Settings->getSetting("driver") ); |
448 | 448 | ||
449 | if (driver) | 449 | if (driver) |
450 | { | 450 | { |
451 | if ( irr::IrrlichtDevice::isDriverSupported( static_cast<E_DRIVER_TYPE>( driver->getValue() ))) | 451 | if ( irr::IrrlichtDevice::isDriverSupported( static_cast<E_DRIVER_TYPE>( driver->getValue() ))) |
452 | { | 452 | { |
453 | // selected driver is supported, so we use it. | 453 | // selected driver is supported, so we use it. |
454 | param.DriverType = static_cast<E_DRIVER_TYPE>( driver->getValue()); | 454 | param.DriverType = static_cast<E_DRIVER_TYPE>( driver->getValue()); |
455 | } | 455 | } |
456 | } | 456 | } |
457 | 457 | ||
458 | //map resolution setting to dimension in a similar way as demonstrated above | 458 | //map resolution setting to dimension in a similar way as demonstrated above |
459 | map<stringw, dimension2du>::Node* res = app.Settings->ResolutionOptions.find( app.Settings->getSetting("resolution") ); | 459 | map<stringw, dimension2du>::Node* res = app.Settings->ResolutionOptions.find( app.Settings->getSetting("resolution") ); |
460 | if (res) | 460 | if (res) |
461 | { | 461 | { |
462 | param.WindowSize = res->getValue(); | 462 | param.WindowSize = res->getValue(); |
463 | } | 463 | } |
464 | 464 | ||
465 | //get fullscreen setting from config | 465 | //get fullscreen setting from config |
466 | param.Fullscreen = app.Settings->getSettingAsBoolean("fullscreen"); | 466 | param.Fullscreen = app.Settings->getSettingAsBoolean("fullscreen"); |
467 | } | 467 | } |
468 | 468 | ||
469 | //create the irrlicht device using the settings | 469 | //create the irrlicht device using the settings |
470 | app.Device = createDeviceEx(param); | 470 | app.Device = createDeviceEx(param); |
471 | if (app.Device == 0) | 471 | if (app.Device == 0) |
472 | { | 472 | { |
473 | // You can add your own exception handling on driver failure | 473 | // You can add your own exception handling on driver failure |
474 | exit(0); | 474 | exit(0); |
475 | } | 475 | } |
476 | 476 | ||
477 | app.Device->setWindowCaption(L"Xmlhandling - Irrlicht engine tutorial"); | 477 | app.Device->setWindowCaption(L"Xmlhandling - Irrlicht engine tutorial"); |
478 | app.Driver = app.Device->getVideoDriver(); | 478 | app.Driver = app.Device->getVideoDriver(); |
479 | app.Gui = app.Device->getGUIEnvironment(); | 479 | app.Gui = app.Device->getGUIEnvironment(); |
480 | 480 | ||
481 | createSettingsDialog(app); | 481 | createSettingsDialog(app); |
482 | 482 | ||
483 | //set event receiver so we can respond to gui events | 483 | //set event receiver so we can respond to gui events |
484 | MyEventReceiver receiver(app); | 484 | MyEventReceiver receiver(app); |
485 | app.Device->setEventReceiver(&receiver); | 485 | app.Device->setEventReceiver(&receiver); |
486 | 486 | ||
487 | //enter main loop | 487 | //enter main loop |
488 | while (!app.ShouldQuit && app.Device->run()) | 488 | while (!app.ShouldQuit && app.Device->run()) |
489 | { | 489 | { |
490 | if (app.Device->isWindowActive()) | 490 | if (app.Device->isWindowActive()) |
491 | { | 491 | { |
492 | app.Driver->beginScene(true, true, SColor(0,200,200,200)); | 492 | app.Driver->beginScene(true, true, SColor(0,200,200,200)); |
493 | app.Gui->drawAll(); | 493 | app.Gui->drawAll(); |
494 | app.Driver->endScene(); | 494 | app.Driver->endScene(); |
495 | } | 495 | } |
496 | app.Device->sleep(10); | 496 | app.Device->sleep(10); |
497 | } | 497 | } |
498 | 498 | ||
499 | //app destroys device in destructor | 499 | //app destroys device in destructor |
500 | 500 | ||
501 | return 0; | 501 | return 0; |
502 | } | 502 | } |
503 | 503 | ||
504 | /* | 504 | /* |
505 | **/ | 505 | **/ |