xoreos  0.0.5
kotor2.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/ustring.h"
29 #include "src/common/filelist.h"
30 #include "src/common/filepath.h"
31 #include "src/common/configman.h"
32 
33 #include "src/aurora/resman.h"
34 #include "src/aurora/language.h"
35 #include "src/aurora/talkman.h"
37 
38 #include "src/events/events.h"
39 
42 
47 
52 
53 namespace Engines {
54 
55 namespace KotOR2 {
56 
58  _console.reset(new Console(*this));
59 }
60 
62 }
63 
65  Aurora::Platform platform,
66  std::vector<Aurora::Language> &languages) const {
67  try {
68  Common::UString baseDir = target;
69  if (platform == Aurora::kPlatformLinux)
70  baseDir += "/steamassets";
71  else if (platform == Aurora::kPlatformMacOSX)
72  baseDir += "/GameData";
73 
74  Common::FileList files;
75  if (!files.addDirectory(baseDir))
76  return true;
77 
78  Common::UString tlk = files.findFirst("dialog.tlk", true);
79  if (tlk.empty())
80  return true;
81 
83  if (languageID == Aurora::kLanguageInvalid)
84  return true;
85 
86  Aurora::Language language = LangMan.getLanguage(languageID);
87  if (language == Aurora::kLanguageInvalid)
88  return true;
89 
90  languages.push_back(language);
91 
92  } catch (...) {
93  }
94 
95  return true;
96 }
97 
99  language = _language;
100  return true;
101 }
102 
104  Aurora::Language language;
105  if (!evaluateLanguage(false, language) || (_language != language))
106  return false;
107 
108  return true;
109 }
110 
112  assert(_game);
113 
114  return *_game;
115 }
116 
118  init();
119  if (EventMan.quitRequested())
120  return;
121 
122  CursorMan.hideCursor();
123  CursorMan.set();
124 
125  playIntroVideos();
126  if (EventMan.quitRequested())
127  return;
128 
129  CursorMan.showCursor();
130 
131  _game.reset(new Game(*this, *_console, _platform));
132  _game->run();
133 
134  deinit();
135 }
136 
138  LoadProgress progress(17);
139 
140  progress.step("Declare languages");
142 
143  if (evaluateLanguage(true, _language))
144  status("Setting the language to %s", LangMan.getLanguageName(_language).c_str());
145  else
146  warning("Failed to detect this game's language");
147 
148  LangMan.setCurrentLanguage(_language);
149 
150  progress.step("Loading user game config");
151  initConfig();
152  checkConfig();
153 
154  if (EventMan.quitRequested())
155  return;
156 
157  initResources(progress);
158 
159  if (EventMan.quitRequested())
160  return;
161 
162  progress.step("Loading game cursors");
163  initCursors();
164 
165  if (EventMan.quitRequested())
166  return;
167 
168  progress.step("Initializing internal game config");
169  initGameConfig();
170 
171  progress.step("Successfully initialized the engine");
172 }
173 
175  static const Aurora::LanguageManager::Declaration kLanguageDeclarations[] = {
186  };
187 
188  LangMan.addLanguages(kLanguageDeclarations, ARRAYSIZE(kLanguageDeclarations));
189 }
190 
192  // In the Xbox version of KotOR2, TXB textures are actually TPCs
195 
196  progress.step("Setting base directory");
197 
198  Common::UString baseDir = _target;
200  baseDir += "/steamassets";
202  baseDir += "/GameData";
203 
204  ResMan.registerDataBase(baseDir);
205 
206  progress.step("Adding extra archive directories");
207  const Common::UString dataDir = (_platform == Aurora::kPlatformXbox) ? "dataxbox" : "data";
208  const Common::UString rimsDir = (_platform == Aurora::kPlatformXbox) ? "rimsxbox" : "rims";
209 
210  indexMandatoryDirectory( dataDir , 0, 0, 2);
211  indexMandatoryDirectory("lips" , 0, 0, 3);
212  indexMandatoryDirectory("modules", 0, 0, 4);
213 
214  indexOptionalDirectory(rimsDir, 0, 0, 5);
215 
217  indexMandatoryDirectory("texturepacks", 0, 0, 6);
218 
220  indexMandatoryDirectory("supermodels" , 0, 0, 7);
221 
222  progress.step("Loading main KEY");
223  indexMandatoryArchive("chitin.key", 10);
224 
225  progress.step("Loading high-res texture packs");
227  indexMandatoryArchive("swpc_tex_gui.erf", 50);
228 
229  progress.step("Indexing extra sound resources");
230  indexMandatoryDirectory("streamsounds", 0, -1, 100);
231  progress.step("Indexing extra voice resources");
232  indexMandatoryDirectory("streamvoice" , 0, -1, 101);
233  progress.step("Indexing extra music resources");
234  indexMandatoryDirectory("streammusic" , 0, -1, 102);
235  progress.step("Indexing extra movie resources");
236  indexMandatoryDirectory("movies" , 0, -1, 103);
237 
238  progress.step("Indexing platform-specific resources");
241  indexMandatoryArchive("swkotor2.exe", 104);
242  } else if (_platform == Aurora::kPlatformLinux) {
243  indexMandatoryDirectory("../resources/cursors/", 0, 0, 104);
244  } else if (_platform == Aurora::kPlatformMacOSX) {
245  indexMandatoryDirectory("../Resources/Cursors/", 0, 0, 104);
246  }
247 
248  // Texture packs at 400, in module.cpp
249 
250  progress.step("Indexing override files");
251  indexOptionalDirectory("override", 0, 0, 500);
252 
253  if (EventMan.quitRequested())
254  return;
255 
256  progress.step("Loading main talk table");
257  TalkMan.addTable("dialog", "dialogf", false, 0);
258 
259  progress.step("Registering file formats");
262 }
263 
265  std::vector<Common::UString> cursorRemap;
266 
267  cursorRemap.push_back("gui_mp_defaultu");
268  cursorRemap.push_back("gui_mp_defaultd");
269  cursorRemap.push_back("gui_mp_walku");
270  cursorRemap.push_back("gui_mp_walkd");
271  cursorRemap.push_back("gui_mp_invalidu");
272  cursorRemap.push_back("gui_mp_invalidd");
273  cursorRemap.push_back("gui_mp_bashu");
274  cursorRemap.push_back("gui_mp_bashd");
275  cursorRemap.push_back("gui_mp_bashup");
276  cursorRemap.push_back("gui_mp_bashdp");
277  cursorRemap.push_back("gui_mp_talku");
278  cursorRemap.push_back("gui_mp_talkd");
279  cursorRemap.push_back("gui_mp_notalku");
280  cursorRemap.push_back("gui_mp_notalkd");
281  cursorRemap.push_back("gui_mp_followu");
282  cursorRemap.push_back("gui_mp_followd");
283  cursorRemap.push_back("gui_mp_examineu");
284  cursorRemap.push_back("gui_mp_examined");
285  cursorRemap.push_back("gui_mp_noexamu");
286  cursorRemap.push_back("gui_mp_noexamd");
287  cursorRemap.push_back("gui_mp_transu");
288  cursorRemap.push_back("gui_mp_transd");
289  cursorRemap.push_back("gui_mp_dooru");
290  cursorRemap.push_back("gui_mp_doord");
291  cursorRemap.push_back("gui_mp_useu");
292  cursorRemap.push_back("gui_mp_used");
293  cursorRemap.push_back("gui_mp_useup");
294  cursorRemap.push_back("gui_mp_usedp");
295  cursorRemap.push_back("gui_mp_magicu");
296  cursorRemap.push_back("gui_mp_magicd");
297  cursorRemap.push_back("gui_mp_nomagicu");
298  cursorRemap.push_back("gui_mp_nomagicd");
299  cursorRemap.push_back("gui_mp_dismineu");
300  cursorRemap.push_back("gui_mp_dismined");
301  cursorRemap.push_back("gui_mp_dismineup");
302  cursorRemap.push_back("gui_mp_disminedp");
303  cursorRemap.push_back("gui_mp_recmineu");
304  cursorRemap.push_back("gui_mp_recmined");
305  cursorRemap.push_back("gui_mp_recmineup");
306  cursorRemap.push_back("gui_mp_recminedp");
307  cursorRemap.push_back("gui_mp_locku");
308  cursorRemap.push_back("gui_mp_lockd");
309  cursorRemap.push_back("gui_mp_doorup");
310  cursorRemap.push_back("gui_mp_doordp");
311  cursorRemap.push_back("gui_mp_selectu");
312  cursorRemap.push_back("gui_mp_selectd");
313  cursorRemap.push_back("gui_mp_createu");
314  cursorRemap.push_back("gui_mp_created");
315  cursorRemap.push_back("gui_mp_nocreatu");
316  cursorRemap.push_back("gui_mp_nocreatd");
317  cursorRemap.push_back("gui_mp_killu");
318  cursorRemap.push_back("gui_mp_killd");
319  cursorRemap.push_back("gui_mp_nokillu");
320  cursorRemap.push_back("gui_mp_nokilld");
321  cursorRemap.push_back("gui_mp_healu");
322  cursorRemap.push_back("gui_mp_heald");
323  cursorRemap.push_back("gui_mp_nohealu");
324  cursorRemap.push_back("gui_mp_noheald");
325  cursorRemap.push_back("gui_mp_arrun00");
326  cursorRemap.push_back("gui_mp_arrun01");
327  cursorRemap.push_back("gui_mp_arrun02");
328  cursorRemap.push_back("gui_mp_arrun03");
329  cursorRemap.push_back("gui_mp_arrun04");
330  cursorRemap.push_back("gui_mp_arrun05");
331  cursorRemap.push_back("gui_mp_arrun06");
332  cursorRemap.push_back("gui_mp_arrun07");
333  cursorRemap.push_back("gui_mp_arrun08");
334  cursorRemap.push_back("gui_mp_arrun09");
335  cursorRemap.push_back("gui_mp_arrun10");
336  cursorRemap.push_back("gui_mp_arrun11");
337  cursorRemap.push_back("gui_mp_arrun12");
338  cursorRemap.push_back("gui_mp_arrun13");
339  cursorRemap.push_back("gui_mp_arrun14");
340  cursorRemap.push_back("gui_mp_arrun15");
341  cursorRemap.push_back("gui_mp_arwalk00");
342  cursorRemap.push_back("gui_mp_arwalk01");
343  cursorRemap.push_back("gui_mp_arwalk02");
344  cursorRemap.push_back("gui_mp_arwalk03");
345  cursorRemap.push_back("gui_mp_arwalk04");
346  cursorRemap.push_back("gui_mp_arwalk05");
347  cursorRemap.push_back("gui_mp_arwalk06");
348  cursorRemap.push_back("gui_mp_arwalk07");
349  cursorRemap.push_back("gui_mp_arwalk08");
350  cursorRemap.push_back("gui_mp_arwalk09");
351  cursorRemap.push_back("gui_mp_arwalk10");
352  cursorRemap.push_back("gui_mp_arwalk11");
353  cursorRemap.push_back("gui_mp_arwalk12");
354  cursorRemap.push_back("gui_mp_arwalk13");
355  cursorRemap.push_back("gui_mp_arwalk14");
356  cursorRemap.push_back("gui_mp_arwalk15");
357  cursorRemap.push_back("gui_mp_pickupu");
358  cursorRemap.push_back("gui_mp_pickupd");
359 
360  ResMan.setCursorRemap(cursorRemap);
361 }
362 
365  return;
366 
367  CursorMan.add("gui_mp_defaultd" , "default" , "down");
368  CursorMan.add("gui_mp_defaultu" , "default" , "up" );
369 
370  CursorMan.add("gui_mp_bashd" , "bash" , "down");
371  CursorMan.add("gui_mp_bashu" , "bash" , "up" );
372  CursorMan.add("gui_mp_bashdp" , "bash+" , "down");
373  CursorMan.add("gui_mp_bashup" , "bash+" , "up" );
374  CursorMan.add("gui_mp_dismined" , "dismine" , "down");
375  CursorMan.add("gui_mp_dismineu" , "dismine" , "up" );
376  CursorMan.add("gui_mp_disminedp", "dismine+" , "down");
377  CursorMan.add("gui_mp_dismineup", "dismine+" , "up" );
378  CursorMan.add("gui_mp_doord" , "door" , "down");
379  CursorMan.add("gui_mp_dooru" , "door" , "up" );
380  CursorMan.add("gui_mp_doordp" , "door+" , "down");
381  CursorMan.add("gui_mp_doorup" , "door+" , "up" );
382  CursorMan.add("gui_mp_invalidd" , "invalid" , "down");
383  CursorMan.add("gui_mp_invalidu" , "invalid" , "up" );
384  CursorMan.add("gui_mp_killd" , "kill" , "down");
385  CursorMan.add("gui_mp_killu" , "kill" , "up" );
386  CursorMan.add("gui_mp_recmined" , "recmine" , "down");
387  CursorMan.add("gui_mp_recmineu" , "recmine" , "up" );
388  CursorMan.add("gui_mp_recminedp", "recmine+" , "down");
389  CursorMan.add("gui_mp_recmineup", "recmine+" , "up" );
390  CursorMan.add("gui_mp_selectd" , "select" , "down");
391  CursorMan.add("gui_mp_selectu" , "select" , "up" );
392  CursorMan.add("gui_mp_talkd" , "talk" , "down");
393  CursorMan.add("gui_mp_talku" , "talk" , "up" );
394  CursorMan.add("gui_mp_used" , "use" , "down");
395  CursorMan.add("gui_mp_useu" , "use" , "up" );
396  CursorMan.add("gui_mp_usedp" , "use+" , "down");
397  CursorMan.add("gui_mp_useup" , "use+" , "up" );
398 
399  CursorMan.setDefault("default", "up");
400 }
401 
403  ConfigMan.setInt(Common::kConfigRealmDefault, "texturepack", 2);
404 }
405 
407  ConfigMan.setString(Common::kConfigRealmGameTemp, "KOTOR2_moduleDir",
408  Common::FilePath::findSubDirectory(ResMan.getDataBase(), "modules", true));
409 }
410 
412  checkConfigInt("texturepack", 0, 2);
413 }
414 
417 
418  _game.reset();
419 }
420 
422  playVideo("leclogo");
423  playVideo("obsidianent");
424  playVideo("aspyr");
425  playVideo("legal");
426 }
427 
428 } // End of namespace KotOR2
429 
430 } // End of namespace Engines
#define ResMan
Shortcut for accessing the sound manager.
Definition: resman.h:557
Aurora::Platform _platform
Definition: engine.h:84
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.
#define TalkMan
Shortcut for accessing the talk manager.
Definition: talkman.h:111
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: kotor2.cpp:64
A class holding an UTF-8 string.
Definition: ustring.h:48
Temporary game settings/properties.
Definition: configman.h:47
The context handling the gameplay in Star Wars: Knights of the Old Republic II - The Sith Lords...
The global config manager.
void initResources(LoadProgress &progress)
Definition: kotor2.cpp:191
Common::ScopedPtr< Console > _console
Definition: engine.h:87
bool evaluateLanguage(bool find, Aurora::Language &language) const
Definition: engine.cpp:198
#define ARRAYSIZE(x)
Macro which determines the number of entries in a fixed size array.
Definition: util.h:131
Texture.
Definition: types.h:182
Language
Definition: language.h:46
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.
UString findFirst(const UString &str, bool caseInsensitive) const
Find the first file ending with the given string.
Definition: filelist.cpp:193
void indexMandatoryArchive(const Common::UString &file, uint32 priority, const std::vector< byte > &password, Common::ChangeID *changeID)
Definition: resources.cpp:36
Game & getGame()
Return the context running the actual game.
Definition: kotor2.cpp:111
#define ConfigMan
Shortcut for accessing the config manager.
Definition: configman.h:176
#define UNUSED(x)
Definition: system.h:170
Windows codepage 950 (Traditional Chinese, similar to Big5).
Definition: encoding.h:56
Utility templates and functions.
Microsoft Xbox.
Definition: types.h:433
void unregisterModelLoader()
Definition: model.cpp:41
The global events manager.
Types and functions related to language.
Star Wars: Knights of the Old Republic II - The Sith Lords (debug) console.
bool empty() const
Is the string empty?
Definition: ustring.cpp:245
bool changeLanguage()
Change the game&#39;s current language.
Definition: kotor2.cpp:103
Aurora::Language _language
Definition: kotor2.h:63
Texture.
Definition: types.h:183
bool getLanguage(Aurora::Language &language) const
Return the game&#39;s current language.
Definition: kotor2.cpp:98
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
#define EventMan
Shortcut for accessing the events manager.
Definition: events.h:210
The Aurora cursor manager.
Displaying the progress in loading a game.
Textured font, used by NWN and KotOR/KotOR2.
Definition: fontman.h:47
Unicode string handling.
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
GNU/Linux.
Definition: types.h:432
Star Wars: Knights of the Old Republic II - The Sith Lords model loader.
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
Common::ScopedPtr< Game > _game
Definition: kotor2.h:65
void step(const Common::UString &description)
Take a step in advancing the progress.
Microsoft Windows.
Definition: types.h:430
void status(const char *s,...)
Definition: util.cpp:52
void checkConfigInt(const Common::UString &key, int min, int max)
Make sure that an int config value is in the right range.
Definition: util.cpp:116
Windows codepage 1250 (Eastern European, Latin alphabet).
Definition: encoding.h:49
bool addDirectory(const UString &directory, int recurseDepth=0)
Add a directory to the list.
Definition: filelist.cpp:102
Generic Aurora engines utility functions.
A list of files.
Windows codepage 1252 (Western European, Latin alphabet).
Definition: encoding.h:51
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
Engine class handling Star Wars: Knights of the Old Republic II - The Sith Lords. ...
Platform
Definition: types.h:429
void run()
Run the game.
Definition: kotor2.cpp:117
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.