xoreos  0.0.5
lytfile.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/readstream.h"
27 #include "src/common/util.h"
28 #include "src/common/error.h"
29 #include "src/common/strutil.h"
30 
31 #include "src/aurora/lytfile.h"
32 
33 namespace Aurora {
34 
36 }
37 
39 }
40 
42  _rooms.clear();
43  _artPlaceables.clear();
44  _doorHooks.clear();
46 }
47 
48 void LYTFile::assertTokenCount(const std::vector<Common::UString> &tokens, size_t n,
49  const Common::UString &name) {
50 
51  if (tokens.size() != n)
52  throw Common::Exception("LYTFile::load(): Invalid token \"%s\" (size %u)",
53  name.c_str(), (uint)tokens.size());
54 }
55 
57  clear();
58 
60  tokenizer.addSeparator(' ');
61  tokenizer.addChunkEnd('\n');
62  tokenizer.addIgnore('\r');
63 
64  while (!lyt.eos()) {
65  std::vector<Common::UString> strings;
66  tokenizer.getTokens(lyt, strings);
67 
68  if (strings.empty()) {
69  // Empty line?
70  } else if (*strings[0].begin() == '#') {
71  // Comment line
72  } else if (strings[0] == "filedependancy") {
73  // A clone2727 note: It's spelled "dependency", BioWare.
74  _fileDependency = strings[1];
75 
76  } else if (strings[0] == "roomcount") {
77  // Rooms
78 
79  assertTokenCount(strings, 2, "roomcount");
80 
81  int roomCount;
82  Common::parseString(strings[1], roomCount);
83  _rooms.resize(roomCount);
84 
85  for (int i = 0; i < roomCount; i++) {
86  tokenizer.nextChunk(lyt);
87  tokenizer.getTokens(lyt, strings);
88 
89  assertTokenCount(strings, 4, "room");
90 
91  _rooms[i].model = strings[0];
92  Common::parseString(strings[1], _rooms[i].x);
93  Common::parseString(strings[2], _rooms[i].y);
94  Common::parseString(strings[3], _rooms[i].z);
95  _rooms[i].canWalk = false;
96  }
97 
98  } else if (strings[0] == "trackcount") {
99  // TODO: Tracks?
100 
101  assertTokenCount(strings, 2, "trackcount");
102 
103  int trackCount;
104  Common::parseString(strings[1], trackCount);
105 
106  for (int i = 0; i < trackCount; i++)
107  tokenizer.nextChunk(lyt);
108 
109  } else if (strings[0] == "obstaclecount") {
110  // TODO: Obstacles?
111 
112  assertTokenCount(strings, 2, "obstaclecount");
113 
114  int obstacleCount;
115  Common::parseString(strings[1], obstacleCount);
116 
117  for (int i = 0; i < obstacleCount; i++)
118  tokenizer.nextChunk(lyt);
119 
120  } else if (strings[0] == "artplaceablecount") {
121  // Art placeables
122 
123  assertTokenCount(strings, 2, "artplaceablecount");
124 
125  int artPlaceablesCount;
126  Common::parseString(strings[1], artPlaceablesCount);
127  _artPlaceables.resize(artPlaceablesCount);
128 
129  for (int i = 0; i < artPlaceablesCount; i++) {
130  tokenizer.nextChunk(lyt);
131  tokenizer.getTokens(lyt, strings);
132 
133  assertTokenCount(strings, 4, "artplaceable");
134 
135  _artPlaceables[i].model = strings[0];
136  Common::parseString(strings[1], _artPlaceables[i].x);
137  Common::parseString(strings[2], _artPlaceables[i].y);
138  Common::parseString(strings[3], _artPlaceables[i].z);
139  }
140 
141  } else if (strings[0] == "walkmeshRooms") {
142  // Only relevant for Jade
143 
144  assertTokenCount(strings, 2, "walkmeshRooms");
145 
146  int walkmeshRoomCount;
147  Common::parseString(strings[1], walkmeshRoomCount);
148 
149  for (int i = 0; i < walkmeshRoomCount; i++) {
150  tokenizer.nextChunk(lyt);
151  tokenizer.getTokens(lyt, strings);
152 
153  assertTokenCount(strings, 1, "walkmesh room");
154 
155  for (size_t j = 0; j < _rooms.size(); j++) {
156  if (_rooms[j].model.equals(strings[0]))
157  _rooms[j].canWalk = true;
158  }
159  }
160 
161  } else if (strings[0] == "doorhookcount") {
162  // Door hooks
163 
164  assertTokenCount(strings, 2, "doorhookcount");
165 
166  int doorHookCount;
167  Common::parseString(strings[1], doorHookCount);
168  _doorHooks.resize(doorHookCount);
169 
170  for (int i = 0; i < doorHookCount; i++) {
171  tokenizer.nextChunk(lyt);
172  tokenizer.getTokens(lyt, strings);
173 
174  assertTokenCount(strings, 10, "doorHook");
175 
176  _doorHooks[i].room = strings[0];
177  _doorHooks[i].name = strings[1];
178 
179  Common::parseString(strings[2], _doorHooks[i].x);
180  Common::parseString(strings[3], _doorHooks[i].y);
181  Common::parseString(strings[4], _doorHooks[i].z);
182  Common::parseString(strings[5], _doorHooks[i].unk1);
183  Common::parseString(strings[6], _doorHooks[i].unk2);
184  Common::parseString(strings[7], _doorHooks[i].unk3);
185  Common::parseString(strings[8], _doorHooks[i].unk4);
186  Common::parseString(strings[9], _doorHooks[i].unk5);
187  }
188 
189  } else if (strings[0] == "beginlayout") {
190  // Ignore, we don't need it
191  } else if (strings[0] == "donelayout") {
192  // End parsing
193  break;
194  } else {
195  throw Common::Exception("LYTFile::load(): Unknown token %s", strings[0].c_str());
196  }
197 
198  tokenizer.nextChunk(lyt);
199  }
200 }
201 
203  return _rooms;
204 }
205 
207  return _artPlaceables;
208 }
209 
211  return _doorHooks;
212 }
213 
215  return _fileDependency;
216 }
217 
218 } // End of namespace Aurora
A class holding an UTF-8 string.
Definition: ustring.h:48
void clear()
Clear all information.
Definition: lytfile.cpp:41
virtual bool eos() const =0
Returns true if a read failed because the stream has been reached.
const DoorHookArray & getDoorHooks() const
Get all door hooks in this layout.
Definition: lytfile.cpp:210
Tokenizes a stream.
void addChunkEnd(uint32 c)
Add a character marking the end of a chunk.
Utility templates and functions for working with strings and streams.
Exception that provides a stack of explanations.
Definition: error.h:36
DoorHookArray _doorHooks
Definition: lytfile.h:109
Basic exceptions to throw.
void assertTokenCount(const std::vector< Common::UString > &tokens, size_t n, const Common::UString &name)
Definition: lytfile.cpp:48
const char * c_str() const
Return the (utf8 encoded) string data.
Definition: ustring.cpp:249
const RoomArray & getRooms() const
Get all rooms in this layout.
Definition: lytfile.cpp:202
Utility templates and functions.
std::vector< Room > RoomArray
Definition: lytfile.h:78
ArtPlaceableArray _artPlaceables
Definition: lytfile.h:108
std::vector< ArtPlaceable > ArtPlaceableArray
Definition: lytfile.h:79
StackException Exception
Definition: error.h:59
void addIgnore(uint32 c)
Add a character to ignore.
Basic reading stream interfaces.
RoomArray _rooms
Definition: lytfile.h:107
size_t getTokens(SeekableReadStream &stream, std::vector< UString > &list, size_t min=0, size_t max=SIZE_MAX, const UString &def="")
Parse tokens out of the stream.
Common::UString _fileDependency
Definition: lytfile.h:110
Parse tokens out of a stream.
void nextChunk(SeekableReadStream &stream)
Skip past end of chunk characters.
Ignore all repeated separators.
const ArtPlaceableArray & getArtPlaceables() const
Get art placeables in this layout.
Definition: lytfile.cpp:206
void addSeparator(uint32 c)
Add a character on where to split tokens.
void load(Common::SeekableReadStream &lyt)
Load a LYT file.
Definition: lytfile.cpp:56
void clear()
Clear the string&#39;s contents.
Definition: ustring.cpp:236
Common::UString getFileDependency() const
Get the file dependency in this layout.
Definition: lytfile.cpp:214
std::vector< DoorHook > DoorHookArray
Definition: lytfile.h:80
Interface for a seekable & readable data stream.
Definition: readstream.h:265
void parseString(const UString &str, T &value, bool allowEmpty)
Parse a string into any POD integer, float/double or bool type.
Definition: strutil.cpp:215
Handling BioWare&#39;s LYTs (Layout files).
unsigned int uint
Definition: types.h:211