xoreos  0.0.5
witcher.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 "src/common/util.h"
26 #include "src/common/error.h"
27 #include "src/common/filelist.h"
28 #include "src/common/filepath.h"
29 #include "src/common/readstream.h"
30 #include "src/common/configman.h"
31 
32 #include "src/aurora/resman.h"
33 #include "src/aurora/language.h"
34 #include "src/aurora/talkman.h"
35 
37 
40 
41 #include "src/events/events.h"
42 
47 
52 
53 namespace Engines {
54 
55 namespace Witcher {
56 
58  _languageText(Aurora::kLanguageInvalid), _languageVoice(Aurora::kLanguageInvalid) {
59 
60  _console.reset(new Console(*this));
61 }
62 
64 }
65 
67  Aurora::Platform UNUSED(platform),
68  std::vector<Aurora::Language> &languagesText,
69  std::vector<Aurora::Language> &languagesVoice) const {
70  try {
71  Common::UString dataDir = Common::FilePath::findSubDirectory(target, "data", true);
72  if (dataDir.empty())
73  return true;
74 
75  Common::FileList files;
76  if (!files.addDirectory(dataDir))
77  return true;
78 
79  for (size_t i = 0; i < Aurora::kLanguageMAX; i++) {
80  const uint32 langID = LangMan.getLanguageID((Aurora::Language) i);
81 
82  const Common::UString voiceKey = Common::UString::format("lang_%d.key" , langID);
83  const Common::UString textKey = Common::UString::format("dialog_%d.tlk", langID);
84 
85  if (files.contains(voiceKey, true))
86  languagesVoice.push_back((Aurora::Language) i);
87  if (files.contains(textKey, true))
88  languagesText.push_back((Aurora::Language) i);
89  }
90 
91  } catch (...) {
92  }
93 
94  return true;
95 }
96 
97 bool WitcherEngine::getLanguage(Aurora::Language &languageText, Aurora::Language &languageVoice) const {
98  languageText = _languageText;
99  languageVoice = _languageVoice;
100 
101  return true;
102 }
103 
105  Aurora::Language languageText, languageVoice;
106  if (!evaluateLanguage(false, languageText, languageVoice))
107  return false;
108 
109  if ((_languageText == languageText) && (_languageVoice == languageVoice))
110  return true;
111 
112  try {
113 
114  loadLanguageFiles(languageText, languageVoice);
115 
116  if (_game)
117  _game->refreshLocalized();
118 
119  _languageText = languageText;
120  _languageVoice = languageVoice;
121 
122  } catch (...) {
123 
124  // Roll back
126  return false;
127 
128  }
129 
130  return true;
131 }
132 
134  assert(_game);
135 
136  return *_game;
137 }
138 
140  init();
141  if (EventMan.quitRequested())
142  return;
143 
144  CursorMan.hideCursor();
145  CursorMan.set();
146 
147  playIntroVideos();
148  if (EventMan.quitRequested())
149  return;
150 
151  CursorMan.showCursor();
152 
153  _game.reset(new Game(*this, *_console));
154  _game->run();
155 
156  deinit();
157 }
158 
160  LoadProgress progress(15);
161 
162  progress.step("Declare languages");
164 
166  status("Setting the language to %s text + %s voices",
167  LangMan.getLanguageName(_languageText).c_str(),
168  LangMan.getLanguageName(_languageVoice).c_str());
169  else
170  throw Common::Exception("Failed to detect this game's language");
171 
172  progress.step("Loading user game config");
173  initConfig();
174 
175  initResources(progress);
176  if (EventMan.quitRequested())
177  return;
178 
179  progress.step("Loading game cursors");
180  initCursors();
181  if (EventMan.quitRequested())
182  return;
183 
184  progress.step("Initializing internal game config");
185  initGameConfig();
186 
187  progress.step("Initializing Lua subsystem");
188  initLua();
189 
190  progress.step("Successfully initialized the engine");
191 }
192 
194  static const Aurora::LanguageManager::Declaration kLanguageDeclarations[] = {
208  };
209 
210  LangMan.addLanguages(kLanguageDeclarations, ARRAYSIZE(kLanguageDeclarations));
211 }
212 
214  progress.step("Setting base directory");
215  ResMan.registerDataBase(_target);
216 
217  progress.step("Adding extra archive directories");
218  indexMandatoryDirectory("system" , 0, 0, 2);
219  indexMandatoryDirectory("system/scripts", 0, 0, 3);
220  indexMandatoryDirectory("data" , 0, 0, 4);
221  indexMandatoryDirectory("data/modules" , 0, -1, 5);
222 
223  // Contains BIFs with voices for the two premium modules
224  indexOptionalDirectory("data/voices", 0, 0, 6);
225 
226  progress.step("Loading main KEY");
227  indexMandatoryArchive("main.key", 10);
228 
229  progress.step("Loading the localized base KEY");
230  indexMandatoryArchive("localized.key", 50);
231 
232  // Language files at 100-102
233 
234  progress.step("Indexing extra resources");
235  indexOptionalDirectory("data/movies" , 0, -1, 150);
236  indexOptionalDirectory("data/music" , 0, -1, 151);
237  indexOptionalDirectory("data/sounds" , 0, -1, 152);
238  indexOptionalDirectory("data/cutscenes", 0, -1, 153);
239  indexOptionalDirectory("data/dialogues", 0, -1, 154);
240  indexOptionalDirectory("data/fx" , 0, -1, 155);
241  indexOptionalDirectory("data/meshes" , 0, -1, 156);
242  indexOptionalDirectory("data/quests" , 0, -1, 157);
243  indexOptionalDirectory("data/scripts" , 0, -1, 158);
244  indexOptionalDirectory("data/templates", 0, -1, 159);
245  indexOptionalDirectory("data/textures" , 0, -1, 160);
246 
247  progress.step("Indexing Windows-specific resources");
248  indexMandatoryArchive("witcher.exe", 250);
249 
250  progress.step("Indexing override files");
251  indexOptionalDirectory("data/override", 0, 0, 500);
252 
254 
255  progress.step("Registering file formats");
258 }
259 
261  CursorMan.add("cursor0" , "default" , "up" );
262  CursorMan.add("cursor1" , "default" , "down");
263 
264  CursorMan.setDefault("default", "up");
265 }
266 
268 }
269 
271  ConfigMan.setString(Common::kConfigRealmGameTemp, "WITCHER_moduleDir",
272  Common::FilePath::findSubDirectory(_target, "data/modules", true));
273 }
274 
276  LuaScriptMan.init();
277 }
278 
280  TalkMan.removeTable(_languageTLK);
281 
282  std::list<Common::ChangeID>::iterator res;
283  for (res = _languageResources.begin(); res != _languageResources.end(); ++res)
284  deindexResources(*res);
285 
286  _languageResources.clear();
287 }
288 
290  Aurora::Language langText, Aurora::Language langVoice) {
291 
292  progress.step(Common::UString::format("Indexing language files (%s text + %s voices)",
293  LangMan.getLanguageName(langText).c_str(), LangMan.getLanguageName(langVoice).c_str()));
294 
295  loadLanguageFiles(langText, langVoice);
296 }
297 
300  LangMan.setCurrentLanguage(langText, langVoice);
301 
302  Common::UString archive;
303 
305  archive = Common::UString::format("lang_%d.key", LangMan.getLanguageID(langVoice));
306  indexMandatoryArchive(archive, 100, &_languageResources.back());
307 
308  // Voices for the first premium module (The Price of Neutrality)
310  archive = Common::UString::format("M1_%d.key", LangMan.getLanguageID(langVoice));
311  indexOptionalArchive(archive, 101, &_languageResources.back());
312 
313  // Voices for the second premium module (Side Effects)
315  archive = Common::UString::format("M2_%d.key", LangMan.getLanguageID(langVoice));
316  indexOptionalArchive(archive, 102, &_languageResources.back());
317 
318  archive = Common::UString::format("dialog_%d", LangMan.getLanguageID(langText));
319  TalkMan.addTable(archive, "", false, 0, &_languageTLK);
320 }
321 
323  _game.reset();
324 
325  LuaScriptMan.deinit();
327 }
328 
330  playVideo("publisher");
331  playVideo("developer");
332  playVideo("engine");
333  playVideo("intro");
334  playVideo("title");
335 }
336 
337 } // End of namespace Witcher
338 
339 } // End of namespace Engines
#define ResMan
Shortcut for accessing the sound manager.
Definition: resman.h:557
The Witcher model loader.
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
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
bool detectLanguages(Aurora::GameID game, const Common::UString &target, Aurora::Platform platform, std::vector< Aurora::Language > &languagesText, std::vector< Aurora::Language > &languagesVoice) const
Detect which languages this game instance supports.
Definition: witcher.cpp:66
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
Game & getGame()
Return the context running the actual game.
Definition: witcher.cpp:133
bool evaluateLanguage(bool find, Aurora::Language &language) const
Definition: engine.cpp:198
Common::ChangeID _languageTLK
Definition: witcher.h:72
bool changeLanguage()
Change the game&#39;s current language.
Definition: witcher.cpp:104
void run()
Run the game.
Definition: witcher.cpp:139
#define ARRAYSIZE(x)
Macro which determines the number of entries in a fixed size array.
Definition: util.h:131
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
std::list< Common::ChangeID > _languageResources
Definition: witcher.h:71
The Aurora font manager.
void initResources(LoadProgress &progress)
Definition: witcher.cpp:213
The Witcher (debug) console.
void deindexResources(Common::ChangeID &changeID)
Remove previously added resources from the ResourceManager.
Definition: resources.cpp:164
Basic exceptions to throw.
void indexMandatoryArchive(const Common::UString &file, uint32 priority, const std::vector< byte > &password, Common::ChangeID *changeID)
Definition: resources.cpp:36
static UString format(const char *s,...) GCC_PRINTF(1
Print formatted data into an UString object, similar to sprintf().
Definition: ustring.cpp:718
#define ConfigMan
Shortcut for accessing the config manager.
Definition: configman.h:176
#define UNUSED(x)
Definition: system.h:170
Utility templates and functions.
The global events manager.
Types and functions related to language.
bool empty() const
Is the string empty?
Definition: ustring.cpp:245
StackException Exception
Definition: error.h:59
#define CursorMan
Shortcut for accessing the cursor manager.
Definition: cursorman.h:129
bool getLanguage(Aurora::Language &languageText, Aurora::Language &languageVoice) const
Return the game&#39;s current language.
Definition: witcher.cpp:97
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
Common::UString _target
Definition: engine.h:85
void registerModelLoader(ModelLoader *loader)
Definition: model.cpp:37
Common::ScopedPtr< Game > _game
Definition: witcher.h:74
#define LangMan
Shortcut for accessing the language manager.
Definition: language.h:275
A class representing an undoable change.
Definition: changeid.h:35
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.
Lua script manager.
void status(const char *s,...)
Definition: util.cpp:52
bool addDirectory(const UString &directory, int recurseDepth=0)
Add a directory to the list.
Definition: filelist.cpp:102
void loadLanguageFiles(LoadProgress &progress, Aurora::Language langText, Aurora::Language langVoice)
Definition: witcher.cpp:289
Aurora::Language _languageVoice
Definition: witcher.h:69
Generic Aurora engines utility functions.
A list of files.
Engine class handling The Witcher.
Pseudo value for debug strings.
Definition: language.h:62
The context handling the gameplay in The Witcher.
#define LuaScriptMan
Shortcut for accessing the script engine.
Definition: scriptman.h:157
Aurora::Language _languageText
Definition: witcher.h:68
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
bool contains(const UString &str, bool caseInsensitive) const
Does the list contain at least one file ending with the given string?
Definition: filelist.cpp:185
Generic Aurora engines model functions.