xoreos  0.0.5
game.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/error.h"
28 #include "src/common/filelist.h"
29 #include "src/common/filepath.h"
30 
31 #include "src/aurora/resman.h"
32 #include "src/aurora/talkman.h"
33 
34 #include "src/events/events.h"
35 
41 
43 
44 namespace Engines {
45 
46 namespace DragonAge2 {
47 
49  _engine(&engine), _console(&console) {
50 
51  _functions.reset(new Functions(*this));
52 }
53 
55 }
56 
58  assert(_campaigns);
59 
60  return *_campaigns;
61 }
62 
63 void Game::run() {
64  _campaigns.reset(new Campaigns(*_console, *this));
65 
66  while (!EventMan.quitRequested()) {
67  runCampaigns();
68  }
69 
70  _campaigns.reset();
71 }
72 
74  const Campaign *singlePlayer = _campaigns->findCampaign("campaign_base");
75  if (!singlePlayer)
76  throw Common::Exception("Can't find the default single player campaign");
77 
78  _campaigns->load(*singlePlayer);
79 
80  if (EventMan.quitRequested() || !_campaigns->isLoaded())
81  return;
82 
83  Creature *fakePC = new Creature;
84  fakePC->createFakePC();
85 
86  _campaigns->usePC(fakePC);
87  _campaigns->enter();
88 
89  EventMan.enableKeyRepeat(true);
90 
91  while (!EventMan.quitRequested() && _campaigns->isRunning()) {
92  Events::Event event;
93  while (EventMan.pollEvent(event))
94  _campaigns->addEvent(event);
95 
96  _campaigns->processEventQueue();
97  EventMan.delay(10);
98  }
99 
100  EventMan.enableKeyRepeat(false);
101  _campaigns->leave();
102  _campaigns->unload();
103 }
104 
105 void Game::loadResources(const Common::UString &dir, uint32 priority, ChangeList &res,
106  Aurora::Language language) {
107 
108  indexOptionalDirectory(dir + "/data" , 0, 0, priority + 10, res);
109  indexOptionalDirectory(dir + "/data/movies" , 0, 0, priority + 11, res);
110  indexOptionalDirectory(dir + "/data/talktables", 0, 0, priority + 12, res);
111  indexOptionalDirectory(dir + "/data/cursors" , 0, 0, priority + 13, res);
112  indexOptionalDirectory(dir + "/textures" , 0, -1, priority + 14, res);
113  indexOptionalDirectory(dir + "/audio" , 0, -1, priority + 15, res);
114  indexOptionalDirectory(dir + "/env" , 0, -1, priority + 16, res);
115  indexOptionalDirectory(dir + "/patch" , 0, 0, priority + 17, res);
116 
117  loadResourceDir(dir + "/data" , priority + 100, res);
118  loadResourceDir(dir + "/data/abilities", priority + 200, res);
119 
120  Common::FileList sounds(Common::FilePath::findSubDirectory(ResMan.getDataBase(), dir + "/audio/sound", true));
121  sounds.relativize(ResMan.getDataBase());
122 
123  for (Common::FileList::const_iterator f = sounds.begin(); f != sounds.end(); ++f)
124  indexOptionalArchive(*f, priority + 300, res);
125 
126  const Common::UString langString = DragonAge2Engine::getLanguageString(language);
127 
128  Common::FileList vos(Common::FilePath::findSubDirectory(ResMan.getDataBase(), dir + "/audio/vo/" + langString + "/vo", true));
129  vos.relativize(ResMan.getDataBase());
130 
131  for (Common::FileList::const_iterator f = vos.begin(); f != vos.end(); ++f)
132  indexOptionalArchive(*f, priority + 301, res);
133 
134  loadResourceDir(dir + "/patch", 0x40000000 | priority, res);
135 
136  indexOptionalDirectory(dir + "/override", 0, -1, 0x40000000 | (priority + 499), res);
137 }
138 
139 void Game::loadTexturePack(const Common::UString &dir, uint32 priority,
140  ChangeList &res, TextureQuality quality) {
141 
142  static const char * const kTextureQualityName[kTextureQualityMAX] = { "high", "medium" };
143 
144  if (((uint)quality) >= kTextureQualityMAX)
145  throw Common::Exception("Invalid texture quality level");
146 
147  loadResourceDir(dir + "/textures/" + kTextureQualityName[quality], priority + 300, res);
148 }
149 
150 void Game::loadResources(const Common::UString &dir, uint32 priority, ChangeList &res) {
152  _engine->getLanguage(language);
153 
154  loadResources(dir, priority, res, language);
155 }
156 
157 void Game::loadTalkTables(const Common::UString &dir, uint32 priority, ChangeList &res) {
159  _engine->getLanguage(language);
160 
161  loadTalkTables(dir, priority, res, language);
162 }
163 
164 void Game::loadTalkTables(const Common::UString &dir, uint32 priority, ChangeList &res,
165  Aurora::Language language) {
166 
167  if (EventMan.quitRequested())
168  return;
169 
170  const Common::UString tlkDir =
171  Common::FilePath::findSubDirectory(ResMan.getDataBase(), dir + "/data/talktables", true);
172 
173  Common::FileList files(tlkDir, 0);
174 
175  files.sort(true);
176  files.relativize(tlkDir);
177 
178  const Common::UString languageTLK = DragonAge2Engine::getLanguageString(language) + ".tlk";
179  const Common::UString languageTLKP = DragonAge2Engine::getLanguageString(language) + "_p.tlk";
180  for (Common::FileList::const_iterator f = files.begin(); f != files.end(); ++f) {
181  if (f->toLower().endsWith(languageTLK)) {
182  Common::UString tlk = *f;
183  tlk.truncate(tlk.size() - languageTLK.size());
184 
185  loadTalkTable(tlk, "", language, priority++, res);
186  } else if (f->toLower().endsWith(languageTLKP)) {
187  Common::UString tlk = *f;
188  tlk.truncate(tlk.size() - languageTLKP.size());
189 
190  loadTalkTable(tlk, "_p", language, priority++, res);
191  }
192  }
193 }
194 
195 void Game::loadTalkTable(const Common::UString &tlk, const Common::UString &suffix,
196  Aurora::Language language, uint32 priority, ChangeList &changes) {
197 
198  Common::UString tlkM = tlk + DragonAge2Engine::getLanguageString(language) + suffix;
199  Common::UString tlkF = tlk + DragonAge2Engine::getLanguageString(language) + suffix + "_f";
200 
201  changes.push_back(Common::ChangeID());
202  TalkMan.addTable(tlkM, tlkF, false, priority, &changes.back());
203 }
204 
205 void Game::loadResourceDir(const Common::UString &dir, uint32 priority, ChangeList &changes) {
206  if (EventMan.quitRequested())
207  return;
208 
209  Common::FileList files(Common::FilePath::findSubDirectory(ResMan.getDataBase(), dir, true), 0);
210 
211  files.sort(true);
212  files.relativize(ResMan.getDataBase());
213 
214  for (Common::FileList::const_iterator f = files.begin(); f != files.end(); ++f)
217  indexMandatoryArchive("/" + *f, priority++, changes);
218 }
219 
221  for (std::list<Common::ChangeID>::iterator t = changes.begin(); t != changes.end(); ++t)
222  TalkMan.removeTable(*t);
223 
224  changes.clear();
225 }
226 
227 } // End of namespace DragonAge2
228 
229 } // End of namespace Engines
Campaigns & getCampaigns()
Return the campaigns context.
Definition: game.cpp:57
#define ResMan
Shortcut for accessing the sound manager.
Definition: resman.h:557
Game(DragonAge2Engine &engine, ::Engines::Console &console)
Definition: game.cpp:48
static void loadResourceDir(const Common::UString &dir, uint32 priority, ChangeList &changes)
Definition: game.cpp:205
A creature in a Dragon Age II area.
#define TalkMan
Shortcut for accessing the talk manager.
Definition: talkman.h:111
static void unloadTalkTables(ChangeList &changes)
Unload this set of talk tables.
Definition: game.cpp:220
A class holding an UTF-8 string.
Definition: ustring.h:48
static UString getExtension(const UString &p)
Return a file name&#39;s extension.
Definition: filepath.cpp:93
static Common::UString getLanguageString(Aurora::Language language)
Return the string Dragon Age II uses to representing this language.
Definition: dragonage2.cpp:60
::Engines::Console * _console
Definition: game.h:87
bool indexOptionalArchive(const Common::UString &file, uint32 priority, const std::vector< byte > &password, Common::ChangeID *changeID)
Definition: resources.cpp:69
bool getLanguage(Aurora::Language &language) const
Return the game&#39;s current language.
Definition: dragonage2.cpp:122
Engine class handling Dragon Age II.
bool equalsIgnoreCase(const UString &str) const
Definition: ustring.cpp:218
void truncate(const iterator &it)
Definition: ustring.cpp:343
The context handling the gameplay in Dragon Age II.
std::list< UString >::const_iterator const_iterator
Definition: filelist.h:37
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 > ChangeList
Definition: resources.h:41
SDL_Event Event
Definition: types.h:42
Basic exceptions to throw.
void indexMandatoryArchive(const Common::UString &file, uint32 priority, const std::vector< byte > &password, Common::ChangeID *changeID)
Definition: resources.cpp:36
Common::ScopedPtr< Functions > _functions
Definition: game.h:85
static void loadTexturePack(const Common::UString &dir, uint32 priority, ChangeList &res, TextureQuality quality)
Definition: game.cpp:139
The global events manager.
DragonAge2Engine * _engine
Definition: game.h:82
StackException Exception
Definition: error.h:59
#define EventMan
Shortcut for accessing the events manager.
Definition: events.h:210
void relativize(const Common::UString &basePath)
Express all files in this archive as relative to the given base path.
Definition: filelist.cpp:81
The context holding a Dragon Age II campaign.
The context managing and running the Dragon Age II campaigns.
size_t size() const
Return the size of the string, in characters.
Definition: ustring.cpp:241
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
static void loadTalkTable(const Common::UString &tlk, const Common::UString &suffix, Aurora::Language language, uint32 priority, ChangeList &changes)
Definition: game.cpp:195
Common::ScopedPtr< Campaigns > _campaigns
Definition: game.h:84
const_iterator begin() const
Return a const_iterator pointing to the beginning of the list.
Definition: filelist.cpp:94
A list of files.
void sort(bool caseInsensitive)
Sort this list alphabetically.
Definition: filelist.cpp:74
void loadTalkTables(const Common::UString &dir, uint32 priority, ChangeList &res)
Load all talk tables in the current language found in this directory.
Definition: game.cpp:157
Dragon Age II engine functions.
void createFakePC()
Create a fake player character creature for testing purposes.
Definition: creature.cpp:119
The global resource manager for Aurora resources.
Utility class for manipulating file paths.
const_iterator end() const
Return a const_iterator pointing past the end of the list.
Definition: filelist.cpp:98
static UString findSubDirectory(const UString &directory, const UString &subDirectory, bool caseInsensitive=false)
Find a directory&#39;s subdirectory.
Definition: filepath.cpp:318
unsigned int uint
Definition: types.h:211
void loadResources(const Common::UString &dir, uint32 priority, ChangeList &res)
Load all game resource archives in the current language found in this directory.
Definition: game.cpp:150