ScummVM API documentation
archive.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef DIRECTOR_ARCHIVE_H
23 #define DIRECTOR_ARCHIVE_H
24 
25 #include "common/hash-str.h"
26 #include "common/file.h"
27 
28 namespace Common {
29 class MacResManager;
30 class SeekableMemoryWriteStream;
31 class SeekableReadStreamEndian;
32 class SeekableReadStream;
33 class Path;
34 }
35 
36 namespace Director {
37 
38 class CastMember;
39 class Movie;
40 
41 // Completely ripped off of Mohawk's Archive code
42 
43 struct Resource {
44  uint32 index;
45  int32 offset;
46  uint32 size;
47  uint32 uncompSize;
48  uint32 compressionType;
49  uint32 castId;
50  uint32 libResourceId;
51  uint32 tag;
52  uint16 flags;
53  uint16 unk1;
54  uint32 nextFreeResourceID;
55  Common::String name;
56  Common::Array<Resource> children;
57  bool accessed;
58 
59  Resource() = default;
60  Resource(Resource *original) {
61  index = original->index;
62  offset = original->offset;
63  size = original->size;
64  uncompSize = original->uncompSize;
65  compressionType = original->compressionType;
66  castId = original->castId;
67  libResourceId = original->libResourceId;
68  tag = original->tag;
69  flags = original->flags;
70  unk1 = original->unk1;
71  nextFreeResourceID = original->nextFreeResourceID;
72  name = Common::String(original->name);
73  children = Common::Array<Resource>(original->children);
74  accessed = original->accessed;
75  }
76 };
77 
78 class Archive {
79 public:
80  Archive();
81  virtual ~Archive();
82 
83  virtual bool openFile(const Common::Path &path);
84  virtual bool openStream(Common::SeekableReadStream *stream, uint32 offset = 0) = 0;
85  virtual bool writeToFile(Common::String filename, Movie *movie) {
86  // Saving Director movies was introduced in Director 4
87  // However, from DirectorEngine::createArchive, it is evident that after Director 4 only RIFX Archives were written
88  error("Archive::writeToFile was called on a non-RIFX Archive, which is not allowed");
89  return false;
90  }
91  virtual void close();
92 
93  /* Loading Functions for Cast */
94  bool loadConfig(Cast *cast);
95 
96  Common::Path getPathName() const { return _pathName; }
97  Common::String getFileName() const;
98  void setPathName(const Common::Path &name) { _pathName = name; }
99  virtual uint32 getFileSize();
100 
101  bool isOpen() const { return _stream != 0; }
102 
103  bool hasResource(uint32 tag, int id) const;
104  bool hasResource(uint32 tag, const Common::String &resName) const;
105  virtual Common::SeekableReadStreamEndian *getResource(uint32 tag, uint16 id);
106  virtual Common::SeekableReadStreamEndian *getFirstResource(uint32 tag);
107  virtual Common::SeekableReadStreamEndian *getFirstResource(uint32 tag, uint32 parentId);
108  virtual Resource getResourceDetail(uint32 tag, uint16 id);
109  uint32 getOffset(uint32 tag, uint16 id) const;
110  uint getResourceSize(uint32 tag, uint16 id) const;
111  uint16 findResourceID(uint32 tag, const Common::String &resName, bool ignoreCase = false) const;
112  Common::String getName(uint32 tag, uint16 id) const;
113  Common::SeekableReadStreamEndian *getMovieResourceIfPresent(uint32 tag);
114 
115  Common::Array<uint32> getResourceTypeList() const;
116  Common::Array<uint16> getResourceIDList(uint32 type) const;
117  bool _isBigEndian;
118  static uint32 convertTagToUppercase(uint32 tag);
119 
120  virtual Common::String formatArchiveInfo();
121 
122  void listUnaccessedChunks();
123 
124 protected:
125  void dumpChunk(Resource &res, Common::DumpFile &out);
130  TypeMap _types;
131  MovieChunkMap _movieChunks;
132 
133  Common::Path _pathName;
134 };
135 
136 class MacArchive : public Archive {
137 public:
138  MacArchive();
139  ~MacArchive() override;
140 
141  uint32 getFileSize() override;
142  void close() override;
143  bool openFile(const Common::Path &path) override;
144  bool openStream(Common::SeekableReadStream *stream, uint32 startOffset = 0) override;
145  Common::SeekableReadStreamEndian *getResource(uint32 tag, uint16 id) override;
146  Common::String formatArchiveInfo() override;
147 
148 private:
149  Common::MacResManager *_resFork;
150 
151  void readTags();
152 };
153 
154 class RIFFArchive : public Archive {
155 public:
156  RIFFArchive() : Archive() { _startOffset = 0; }
157  ~RIFFArchive() override {}
158 
159  bool openStream(Common::SeekableReadStream *stream, uint32 startOffset = 0) override;
160  Common::SeekableReadStreamEndian *getResource(uint32 tag, uint16 id) override;
161  Common::String formatArchiveInfo() override;
162 
163  uint32 _startOffset;
164 };
165 
166 class RIFXArchive : public Archive {
167 public:
168  RIFXArchive();
169  ~RIFXArchive() override;
170 
171  bool openStream(Common::SeekableReadStream *stream, uint32 startOffset = 0) override;
172  bool writeToFile(Common::String filename, Movie *movie) override;
173 
174  Common::SeekableReadStreamEndian *getFirstResource(uint32 tag) override;
175  virtual Common::SeekableReadStreamEndian *getFirstResource(uint32 tag, bool fileEndianness);
176  Common::SeekableReadStreamEndian *getFirstResource(uint32 tag, uint32 parentId) override;
177  Common::SeekableReadStreamEndian *getResource(uint32 tag, uint16 id) override;
178  virtual Common::SeekableReadStreamEndian *getResource(uint32 tag, uint16 id, bool fileEndianness);
179  Resource getResourceDetail(uint32 tag, uint16 id) override;
180  Common::String formatArchiveInfo() override;
181 
182 private:
183  /* archive-save.cpp */
184  /* These functions are for writing movies */
185  bool writeMemoryMap(Common::SeekableWriteStream *writeStream, Common::Array<Resource *> resource); // Parallel to readMemoryMap
186  bool writeAfterBurnerMap(Common::SeekableWriteStream *writeStreaa); // Parallel to readAfterBurnerMap
187  bool writeKeyTable(Common::SeekableWriteStream *writeStream, uint32 offset); // Parallel to readKeyTable
188  bool writeCast(Common::SeekableWriteStream *writeStream, uint32 offset, uint32 castLib); // Parallel to readCast
189 
190  uint32 getArchiveSize(Common::Array<Resource *> resources);
191  uint32 getMmapSize();
192  uint32 getImapSize();
193  uint32 getCASResourceSize(uint32 castLib);
194  uint32 getKeyTableResourceSize();
195  Common::Array<Resource *> rebuildResources(Movie *movie);
196 
197  bool readMemoryMap(Common::SeekableReadStreamEndian &stream, uint32 moreOffset, Common::SeekableMemoryWriteStream *dumpStream, uint32 movieStartOffset);
198  bool readAfterburnerMap(Common::SeekableReadStreamEndian &stream, uint32 moreOffset);
199  void readCast(Common::SeekableReadStreamEndian &casStream, uint32 libResourceId);
200  void readKeyTable(Common::SeekableReadStreamEndian &keyStream);
201 
202  static const uint32 kNoParent = 0xFFFFFFFF;
203  uint32 findParentIndex(uint32 tag, uint16 index); // kNoParent when absent
204  CastMember *findResourceOwner(Movie *movie, uint32 tag, uint16 index); // nullptr when unresolvable
205 
206  /* Memory Map data to save the file */
207  uint32 _metaTag;
208  uint32 _mapversion;
209  uint32 _mmapHeaderSize;
210  uint32 _mmapEntrySize;
211  uint32 _totalCount;
212  uint32 _resCount;
213  uint32 _imapLength;
214  uint32 _version;
215  uint32 _size;
216 
217  /* Key Table data to save the file */
218  uint16 _keyTableEntrySize;
219  uint16 _keyTableEntrySize2;
220  uint32 _keyTableEntryCount;
221  uint32 _keyTableUsedCount;
222 
223  /* AfterBurner data to save the file */
224  uint32 _fverLength;
225  uint32 _afterBurnerVersion;
226  uint32 _fcdrLength;
227  Common::Array<bool> _fcdrZlibTypes;
228  uint32 _abmpLength;
229  uint32 _abmpEnd;
230  uint32 _abmpCompressionType;
231  uint32 _abmpUncompLength;
232  uint32 _abmpActualUncompLength;
233 
234 protected:
235  uint32 _rifxType;
236 
237  // Each resource is independent
238  Common::Array<Resource *> _resources;
240  uint32 _ilsBodyOffset;
243 
244  // In the RIFX container type, some resources are related of other resources in a child-parent relation
245  // If you want to check the relation between a 'BITD' resource and some other resource (e.g. 'CASt')
246  // Check if index of 'BITD' resource is present in _keyData['BITD'][index of 'CASt' resource]
248 };
249 
250 /*******************************************
251  *
252  * Projector Archive
253  *
254  *******************************************/
255 
257 public:
259  ~ProjectorArchive() override;
260 
261  bool hasFile(const Common::Path &path) const override;
262  int listMembers(Common::ArchiveMemberList &list) const override;
263  const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
264  Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
265  bool isLoaded() { return _isLoaded; }
266 private:
267  Common::SeekableReadStream *createBufferedReadStream();
268  bool loadArchive(Common::SeekableReadStream *stream);
269 
270  struct Entry {
271  uint32 offset;
272  uint32 size;
273  };
275  FileMap _files;
276  Common::Path _path;
277 
278  bool _isLoaded;
279 };
280 
281 void dumpFile(Common::String filename, uint32 id, uint32 tag, byte *dumpData, uint32 dumpSize);
282 
284 public:
285  SavedArchive(const Common::String &target);
286  bool hasFile(const Common::Path &path) const override;
287  int listMembers(Common::ArchiveMemberList &list) const override;
288  const Common::ArchiveMemberPtr getMember(const Common::Path &path) const override;
289  Common::SeekableReadStream *createReadStreamForMember(const Common::Path &path) const override;
290 
291  bool _addFile(const Common::String &path);
292 
293 private:
295  FileMap _files;
296  Common::String _target;
297 };
298 
299 }
300 #endif
Definition: archive.h:136
Definition: cast.h:88
Definition: macresman.h:126
Definition: str.h:59
Definition: archive.h:256
Definition: archive.h:166
Definition: list.h:44
Definition: path.h:52
Definition: movie.h:88
Definition: stream.h:745
Definition: file.h:145
Definition: archive.h:36
Definition: archive.h:141
Definition: archive.h:283
Definition: archive.h:78
Path
Definition: game.h:76
Definition: hashmap.h:85
Definition: algorithm.h:29
void NORETURN_PRE error(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
Definition: archive.h:43
Definition: stream.h:351
Definition: stream.h:944
Definition: archive.h:154
Definition: castmember.h:48
Definition: memstream.h:155