xoreos  0.0.5
nwn2.cpp
Go to the documentation of this file.
1 /* xoreos - A reimplementation of BioWare's Aurora engine
2  *
3  * xoreos is the legal property of its developers, whose names
4  * can be found in the AUTHORS file distributed with this source
5  * distribution.
6  *
7  * xoreos is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 3
10  * of the License, or (at your option) any later version.
11  *
12  * xoreos is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with xoreos. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
25 #include <cassert>
26 
27 #include "src/common/util.h"
28 #include "src/common/error.h"
29 #include "src/common/filepath.h"
30 #include "src/common/filelist.h"
31 #include "src/common/readstream.h"
32 #include "src/common/configman.h"
33 
34 #include "src/aurora/util.h"
35 #include "src/aurora/resman.h"
36 #include "src/aurora/language.h"
37 #include "src/aurora/talkman.h"
39 
42 
43 #include "src/events/events.h"
44 
49 
50 #include "src/engines/nwn2/nwn2.h"
53 #include "src/engines/nwn2/game.h"
54 
55 namespace Engines {
56 
57 namespace NWN2 {
58 
60  _hasXP1(false), _hasXP2(false), _hasXP3(false) {
61 
62  _console.reset(new Console(*this));
63 }
64 
66 }
67 
69  Aurora::Platform UNUSED(platform),
70  std::vector<Aurora::Language> &languages) const {
71  try {
72  Common::FileList files;
73  if (!files.addDirectory(target))
74  return true;
75 
76  Common::UString tlk = files.findFirst("dialog.tlk", true);
77  if (tlk.empty())
78  return true;
79 
81  if (languageID == Aurora::kLanguageInvalid)
82  return true;
83 
84  Aurora::Language language = LangMan.getLanguage(languageID);
85  if (language == Aurora::kLanguageInvalid)
86  return true;
87 
88  languages.push_back(language);
89 
90  } catch (...) {
91  }
92 
93  return true;
94 }
95 
97  language = _language;
98  return true;
99 }
100 
102  Aurora::Language language;
103  if (!evaluateLanguage(false, language) || (_language != language))
104  return false;
105 
106  return true;
107 }
108 
110  assert(_game);
111 
112  return *_game;
113 }
114 
116  init();
117  if (EventMan.quitRequested())
118  return;
119 
120  CursorMan.hideCursor();
121  CursorMan.set();
122 
123  playIntroVideos();
124  if (EventMan.quitRequested())
125  return;
126 
127  CursorMan.showCursor();
128 
129  _game.reset(new Game(*this, *_console));
130  _game->run();
131 
132  deinit();
133 }
134 
136  LoadProgress progress(21);
137 
138  progress.step("Declare languages");
140 
141  if (evaluateLanguage(true, _language))
142  status("Setting the language to %s", LangMan.getLanguageName(_language).c_str());
143  else
144  warning("Failed to detect this game's language");
145 
146  LangMan.setCurrentLanguage(_language);
147 
148  progress.step("Loading user game config");
149  initConfig();
150 
151  initResources(progress);
152  if (EventMan.quitRequested())
153  return;
154 
155  progress.step("Loading game cursors");
156  initCursors();
157  if (EventMan.quitRequested())
158  return;
159 
160  progress.step("Initializing internal game config");
161  initGameConfig();
162 
163  progress.step("Successfully initialized the engine");
164 }
165 
167  static const Aurora::LanguageManager::Declaration kLanguageDeclarations[] = {
178  };
179 
180  LangMan.addLanguages(kLanguageDeclarations, ARRAYSIZE(kLanguageDeclarations));
181 }
182 
184  // NWN2's new file types overlap with other engines in the 3000s block
185  ResMan.addTypeAlias((Aurora::FileType) 3000, Aurora::kFileTypeOSC);
186  ResMan.addTypeAlias((Aurora::FileType) 3001, Aurora::kFileTypeUSC);
187  ResMan.addTypeAlias((Aurora::FileType) 3002, Aurora::kFileTypeTRN);
188  ResMan.addTypeAlias((Aurora::FileType) 3003, Aurora::kFileTypeUTR);
189  ResMan.addTypeAlias((Aurora::FileType) 3004, Aurora::kFileTypeUEN);
190  ResMan.addTypeAlias((Aurora::FileType) 3005, Aurora::kFileTypeULT);
191  ResMan.addTypeAlias((Aurora::FileType) 3006, Aurora::kFileTypeSEF);
192  ResMan.addTypeAlias((Aurora::FileType) 3007, Aurora::kFileTypePFX);
193  ResMan.addTypeAlias((Aurora::FileType) 3008, Aurora::kFileTypeCAM);
194  ResMan.addTypeAlias((Aurora::FileType) 3009, Aurora::kFileTypeLFX);
195  ResMan.addTypeAlias((Aurora::FileType) 3010, Aurora::kFileTypeBFX);
196  ResMan.addTypeAlias((Aurora::FileType) 3011, Aurora::kFileTypeUPE);
197  ResMan.addTypeAlias((Aurora::FileType) 3012, Aurora::kFileTypeROS);
198  ResMan.addTypeAlias((Aurora::FileType) 3013, Aurora::kFileTypeRST);
199  ResMan.addTypeAlias((Aurora::FileType) 3014, Aurora::kFileTypeIFX);
200  ResMan.addTypeAlias((Aurora::FileType) 3015, Aurora::kFileTypePFB);
201  ResMan.addTypeAlias((Aurora::FileType) 3016, Aurora::kFileTypeZIP);
202  ResMan.addTypeAlias((Aurora::FileType) 3017, Aurora::kFileTypeWMP);
203  ResMan.addTypeAlias((Aurora::FileType) 3018, Aurora::kFileTypeBBX);
204  ResMan.addTypeAlias((Aurora::FileType) 3019, Aurora::kFileTypeTFX);
205  ResMan.addTypeAlias((Aurora::FileType) 3020, Aurora::kFileTypeWLK);
206  ResMan.addTypeAlias((Aurora::FileType) 3021, Aurora::kFileTypeXML);
207  ResMan.addTypeAlias((Aurora::FileType) 3022, Aurora::kFileTypeSCC);
208  ResMan.addTypeAlias((Aurora::FileType) 3033, Aurora::kFileTypePTX);
209  ResMan.addTypeAlias((Aurora::FileType) 3034, Aurora::kFileTypeLTX);
210  ResMan.addTypeAlias((Aurora::FileType) 3035, Aurora::kFileTypeTRX);
211 
212  progress.step("Setting base directory");
213  ResMan.registerDataBase(_target);
214 
215  progress.step("Adding extra archive directories");
216  indexMandatoryDirectory("data" , 0, 0, 2);
217  indexMandatoryDirectory("modules", 0, 0, 3);
218  indexMandatoryDirectory("hak" , 0, 0, 4);
219 
220  progress.step("Loading main resource files");
221 
222  indexMandatoryArchive("2da.zip" , 10);
223  indexMandatoryArchive("actors.zip" , 11);
224  indexMandatoryArchive("animtags.zip" , 12);
225  indexMandatoryArchive("convo.zip" , 13);
226  indexMandatoryArchive("ini.zip" , 14);
227  indexMandatoryArchive("lod-merged.zip" , 15);
228  indexMandatoryArchive("music.zip" , 16);
229  indexMandatoryArchive("nwn2_materials.zip", 17);
230  indexMandatoryArchive("nwn2_models.zip" , 18);
231  indexMandatoryArchive("nwn2_vfx.zip" , 19);
232  indexMandatoryArchive("prefabs.zip" , 20);
233  indexMandatoryArchive("scripts.zip" , 21);
234  indexMandatoryArchive("sounds.zip" , 22);
235  indexMandatoryArchive("soundsets.zip" , 23);
236  indexMandatoryArchive("speedtree.zip" , 24);
237  indexMandatoryArchive("templates.zip" , 25);
238  indexMandatoryArchive("vo.zip" , 26);
239  indexMandatoryArchive("walkmesh.zip" , 27);
240 
241  progress.step("Loading expansion 1 resource files");
242 
243  // Expansion 1: Mask of the Betrayer (MotB)
244  _hasXP1 = ResMan.hasArchive("2da_x1.zip");
245  indexOptionalArchive("2da_x1.zip" , 50);
246  indexOptionalArchive("actors_x1.zip" , 51);
247  indexOptionalArchive("animtags_x1.zip" , 52);
248  indexOptionalArchive("convo_x1.zip" , 53);
249  indexOptionalArchive("ini_x1.zip" , 54);
250  indexOptionalArchive("lod-merged_x1.zip" , 55);
251  indexOptionalArchive("music_x1.zip" , 56);
252  indexOptionalArchive("nwn2_materials_x1.zip", 57);
253  indexOptionalArchive("nwn2_models_x1.zip" , 58);
254  indexOptionalArchive("nwn2_vfx_x1.zip" , 59);
255  indexOptionalArchive("prefabs_x1.zip" , 60);
256  indexOptionalArchive("scripts_x1.zip" , 61);
257  indexOptionalArchive("soundsets_x1.zip" , 62);
258  indexOptionalArchive("sounds_x1.zip" , 63);
259  indexOptionalArchive("speedtree_x1.zip" , 64);
260  indexOptionalArchive("templates_x1.zip" , 65);
261  indexOptionalArchive("vo_x1.zip" , 66);
262  indexOptionalArchive("walkmesh_x1.zip" , 67);
263 
264  progress.step("Loading expansion 2 resource files");
265 
266  // Expansion 2: Storm of Zehir (SoZ)
267  _hasXP2 = ResMan.hasArchive("2da_x2.zip");
268  indexOptionalArchive("2da_x2.zip" , 100);
269  indexOptionalArchive("actors_x2.zip" , 101);
270  indexOptionalArchive("animtags_x2.zip" , 102);
271  indexOptionalArchive("lod-merged_x2.zip" , 103);
272  indexOptionalArchive("music_x2.zip" , 104);
273  indexOptionalArchive("nwn2_materials_x2.zip", 105);
274  indexOptionalArchive("nwn2_models_x2.zip" , 106);
275  indexOptionalArchive("nwn2_vfx_x2.zip" , 107);
276  indexOptionalArchive("prefabs_x2.zip" , 108);
277  indexOptionalArchive("scripts_x2.zip" , 109);
278  indexOptionalArchive("soundsets_x2.zip" , 110);
279  indexOptionalArchive("sounds_x2.zip" , 111);
280  indexOptionalArchive("speedtree_x2.zip" , 112);
281  indexOptionalArchive("templates_x2.zip" , 113);
282  indexOptionalArchive("vo_x2.zip" , 114);
283 
284  // Expansion 3: Mysteries of Westgate
285  _hasXP3 = ResMan.hasArchive("westgate.hak");
286 
287  progress.step("Loading patch resource files");
288 
289  indexOptionalArchive("actors_v103x1.zip" , 150);
290  indexOptionalArchive("actors_v106.zip" , 151);
291  indexOptionalArchive("lod-merged_v101.zip" , 152);
292  indexOptionalArchive("lod-merged_v107.zip" , 153);
293  indexOptionalArchive("lod-merged_v121.zip" , 154);
294  indexOptionalArchive("lod-merged_x1_v121.zip" , 155);
295  indexOptionalArchive("lod-merged_x2_v121.zip" , 156);
296  indexOptionalArchive("nwn2_materials_v103x1.zip" , 157);
297  indexOptionalArchive("nwn2_materials_v104.zip" , 158);
298  indexOptionalArchive("nwn2_materials_v106.zip" , 159);
299  indexOptionalArchive("nwn2_materials_v107.zip" , 160);
300  indexOptionalArchive("nwn2_materials_v110.zip" , 161);
301  indexOptionalArchive("nwn2_materials_v112.zip" , 162);
302  indexOptionalArchive("nwn2_materials_v121.zip" , 163);
303  indexOptionalArchive("nwn2_materials_x1_v113.zip", 164);
304  indexOptionalArchive("nwn2_materials_x1_v121.zip", 165);
305  indexOptionalArchive("nwn2_models_v103x1.zip" , 166);
306  indexOptionalArchive("nwn2_models_v104.zip" , 167);
307  indexOptionalArchive("nwn2_models_v105.zip" , 168);
308  indexOptionalArchive("nwn2_models_v106.zip" , 169);
309  indexOptionalArchive("nwn2_models_v107.zip" , 160);
310  indexOptionalArchive("nwn2_models_v112.zip" , 171);
311  indexOptionalArchive("nwn2_models_v121.zip" , 172);
312  indexOptionalArchive("nwn2_models_x1_v121.zip" , 173);
313  indexOptionalArchive("nwn2_models_x2_v121.zip" , 174);
314  indexOptionalArchive("templates_v112.zip" , 175);
315  indexOptionalArchive("templates_v122.zip" , 176);
316  indexOptionalArchive("templates_x1_v122.zip" , 177);
317  indexOptionalArchive("vo_103x1.zip" , 178);
318  indexOptionalArchive("vo_106.zip" , 179);
319 
320  progress.step("Indexing extra sound resources");
321  indexMandatoryDirectory("ambient" , 0, 0, 200);
322  indexOptionalDirectory ("ambient_x1", 0, 0, 201);
323  indexOptionalDirectory ("ambient_x2", 0, 0, 202);
324  progress.step("Indexing extra music resources");
325  indexMandatoryDirectory("music" , 0, 0, 203);
326  indexOptionalDirectory ("music_x1" , 0, 0, 204);
327  indexOptionalDirectory ("music_x2" , 0, 0, 205);
328  progress.step("Indexing extra movie resources");
329  indexMandatoryDirectory("movies" , 0, 0, 206);
330  progress.step("Indexing extra effects resources");
331  indexMandatoryDirectory("effects" , 0, 0, 207);
332  progress.step("Indexing extra character resources");
333  indexMandatoryDirectory("localvault", 0, 0, 208);
334  progress.step("Indexing extra UI resources");
335  indexMandatoryDirectory("ui" , 0, -1, 209);
336 
337  progress.step("Indexing Windows-specific resources");
338  indexMandatoryArchive("nwn2main.exe", 250);
339 
340  progress.step("Indexing override files");
341  indexOptionalDirectory("override", 0, 0, 500);
342 
343  progress.step("Loading main talk table");
344  TalkMan.addTable("dialog", "dialogf", false, 0);
345 
346  progress.step("Registering file formats");
349 }
350 
352  CursorMan.add("cursor0" , "default" , "up" );
353  CursorMan.add("cursor1" , "default" , "down");
354 
355  CursorMan.setDefault("default", "up");
356 }
357 
359  // Enable/Disable the Proof-of-Concept software tinting
360  ConfigMan.setBool(Common::kConfigRealmDefault, "tint", true);
361 }
362 
364  ConfigMan.setBool(Common::kConfigRealmGameTemp, "NWN2_hasXP1", _hasXP1);
365  ConfigMan.setBool(Common::kConfigRealmGameTemp, "NWN2_hasXP2", _hasXP2);
366  ConfigMan.setBool(Common::kConfigRealmGameTemp, "NWN2_hasXP3", _hasXP3);
367 
368  ConfigMan.setString(Common::kConfigRealmGameTemp, "NWN2_campaignDir",
369  Common::FilePath::findSubDirectory(_target, "campaigns", true));
370  ConfigMan.setString(Common::kConfigRealmGameTemp, "NWN2_moduleDir",
371  Common::FilePath::findSubDirectory(_target, "modules", true));
372  ConfigMan.setString(Common::kConfigRealmGameTemp, "NWN2_localPCDir",
373  Common::FilePath::findSubDirectory(_target, "localvault", true));
374  ConfigMan.setString(Common::kConfigRealmGameTemp, "NWN2_serverPCDir",
375  Common::FilePath::findSubDirectory(_target, "servervault", true));
376 }
377 
379  _game.reset();
380 }
381 
383  playVideo("atarilogo");
384  playVideo("oeilogo");
385  playVideo("wotclogo");
386  playVideo("nvidialogo");
387  playVideo("legal");
388  playVideo("intro");
389 }
390 
391 } // End of namespace NWN2
392 
393 } // End of namespace Engines
#define ResMan
Shortcut for accessing the sound manager.
Definition: resman.h:557
void playVideo(const Common::UString &video)
Play this video resource.
Definition: util.cpp:54
GameID
Definition: types.h:393
Generic Aurora engines resource utility functions.
The context handling the gameplay in Neverwinter Nights 2.
#define TalkMan
Shortcut for accessing the talk manager.
Definition: talkman.h:111
Neverwinter Nights 2 (debug) console.
A class holding an UTF-8 string.
Definition: ustring.h:48
Temporary game settings/properties.
Definition: configman.h:47
The global config manager.
TTF font, used by NWN2.
Definition: fontman.h:49
Common::ScopedPtr< Console > _console
Definition: engine.h:87
bool indexOptionalArchive(const Common::UString &file, uint32 priority, const std::vector< byte > &password, Common::ChangeID *changeID)
Definition: resources.cpp:69
bool evaluateLanguage(bool find, Aurora::Language &language) const
Definition: engine.cpp:198
Utility functions to handle files used in BioWare&#39;s Aurora engine.
Common::ScopedPtr< Game > _game
Definition: nwn2.h:70
#define ARRAYSIZE(x)
Macro which determines the number of entries in a fixed size array.
Definition: util.h:131
Particle effect.
Definition: types.h:230
Special effect file.
Definition: types.h:229
Language
Definition: language.h:46
Walk mesh.
Definition: types.h:227
bool indexOptionalDirectory(const Common::UString &dir, const char *glob, int depth, uint32 priority, Common::ChangeID *changeID)
Add a directory to the resource manager, if it exists.
Definition: resources.cpp:133
The Aurora font manager.
Face bone definitions, FaceFX Actor.
Definition: types.h:223
Prefab blueprint.
Definition: types.h:235
UString findFirst(const UString &str, bool caseInsensitive) const
Find the first file ending with the given string.
Definition: filelist.cpp:193
Basic exceptions to throw.
Extensible Markup Language.
Definition: types.h:226
void indexMandatoryArchive(const Common::UString &file, uint32 priority, const std::vector< byte > &password, Common::ChangeID *changeID)
Definition: resources.cpp:36
void initResources(LoadProgress &progress)
Definition: nwn2.cpp:183
#define ConfigMan
Shortcut for accessing the config manager.
Definition: configman.h:176
Campaign information.
Definition: types.h:169
#define UNUSED(x)
Definition: system.h:170
Windows codepage 950 (Traditional Chinese, similar to Big5).
Definition: encoding.h:56
Utility templates and functions.
void run()
Run the game.
Definition: nwn2.cpp:115
Tree template (user), GFF.
Definition: types.h:228
The global events manager.
bool detectLanguages(Aurora::GameID game, const Common::UString &target, Aurora::Platform platform, std::vector< Aurora::Language > &languages) const
Detect which languages this game instance supports.
Definition: nwn2.cpp:68
Types and functions related to language.
Light template (user), GFF.
Definition: types.h:238
Aurora::Language _language
Definition: nwn2.h:64
bool empty() const
Is the string empty?
Definition: ustring.cpp:245
Neverwinter Nights 2 model loader.
Handling BioWare&#39;s TLK talk tables.
void warning(const char *s,...)
Definition: util.cpp:33
#define CursorMan
Shortcut for accessing the cursor manager.
Definition: cursorman.h:129
World map, GFF.
Definition: types.h:243
Basic reading stream interfaces.
#define EventMan
Shortcut for accessing the events manager.
Definition: events.h:210
The Aurora cursor manager.
Displaying the progress in loading a game.
void indexMandatoryDirectory(const Common::UString &dir, const char *glob, int depth, uint32 priority, Common::ChangeID *changeID)
Add a directory to the resource manager, erroring out if it does not exist.
Definition: resources.cpp:112
Line effect.
Definition: types.h:233
Common::UString _target
Definition: engine.h:85
void registerModelLoader(ModelLoader *loader)
Definition: model.cpp:37
Application or game defaults.
Definition: configman.h:46
#define LangMan
Shortcut for accessing the language manager.
Definition: language.h:275
Windows codepage 932 (Japanese, extended Shift-JIS).
Definition: encoding.h:53
uint32_t uint32
Definition: types.h:204
The global talk manager for Aurora strings.
A list of files.
Definition: filelist.h:35
void step(const Common::UString &description)
Take a step in advancing the progress.
FileType
Various file types used by the Aurora engine and found in archives.
Definition: types.h:56
void status(const char *s,...)
Definition: util.cpp:52
Trail effect.
Definition: types.h:231
Windows codepage 1250 (Eastern European, Latin alphabet).
Definition: encoding.h:49
Game & getGame()
Return the context running the actual game.
Definition: nwn2.cpp:109
bool addDirectory(const UString &directory, int recurseDepth=0)
Add a directory to the list.
Definition: filelist.cpp:102
bool getLanguage(Aurora::Language &language) const
Return the game&#39;s current language.
Definition: nwn2.cpp:96
Generic Aurora engines utility functions.
A list of files.
Engine class handling Neverwinter Nights 2.
Windows codepage 1252 (Western European, Latin alphabet).
Definition: encoding.h:51
Billboard effect.
Definition: types.h:234
bool changeLanguage()
Change the game&#39;s current language.
Definition: nwn2.cpp:101
Windows codepage 949 (Korean, similar to EUC-KR).
Definition: encoding.h:55
uint32 getLanguageID() const
Return the language ID (ungendered) of the talk table.
Windows codepage 936 (Simplified Chinese, extended GB2312 with GBK codepoints).
Definition: encoding.h:54
Platform
Definition: types.h:429
The global resource manager for Aurora resources.
Utility class for manipulating file paths.
#define FontMan
Shortcut for accessing the font manager.
Definition: fontman.h:105
static UString findSubDirectory(const UString &directory, const UString &subDirectory, bool caseInsensitive=false)
Find a directory&#39;s subdirectory.
Definition: filepath.cpp:318
Generic Aurora engines model functions.