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
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (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, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #include "illusions/gamarchive.h"
24
25 namespace Illusions {
26
GamArchive(const char * filename)27 GamArchive::GamArchive(const char *filename)
28 : _fd(0), _groupCount(0), _groups(0) {
29 _fd = new Common::File();
30 if (!_fd->open(filename))
31 error("GamArchive::GamArchive() Could not open %s", filename);
32 loadDictionary();
33 }
34
~GamArchive()35 GamArchive::~GamArchive() {
36 delete[] _groups;
37 delete _fd;
38 }
39
readResource(uint32 sceneId,uint32 resId,uint32 & dataSize)40 byte *GamArchive::readResource(uint32 sceneId, uint32 resId, uint32 &dataSize) {
41 const GamFileEntry *fileEntry = getGroupFileEntry(sceneId, resId);
42 _fd->seek(fileEntry->_fileOffset);
43 dataSize = fileEntry->_fileSize;
44 byte *data = (byte*)malloc(dataSize);
45 _fd->read(data, dataSize);
46 return data;
47 }
48
loadDictionary()49 void GamArchive::loadDictionary() {
50 _groupCount = _fd->readUint32LE();
51 _groups = new GamGroupEntry[_groupCount];
52 uint32 *groupOffsets = new uint32[_groupCount];
53
54 for (uint i = 0; i < _groupCount; ++i) {
55 _groups[i]._id = _fd->readUint32LE();
56 groupOffsets[i] = _fd->readUint32LE();
57 }
58
59 for (uint i = 0; i < _groupCount; ++i) {
60 _fd->seek(groupOffsets[i]);
61 uint32 fileCount = _fd->readUint32LE();
62 _groups[i]._fileCount = fileCount;
63 _groups[i]._files = new GamFileEntry[fileCount];
64
65 debug(8, "Group %08X, fileCount: %d", _groups[i]._id, _groups[i]._fileCount);
66
67 for (uint j = 0; j < fileCount; ++j) {
68 _groups[i]._files[j]._id = _fd->readUint32LE();
69 _groups[i]._files[j]._fileOffset = _fd->readUint32LE();
70 _groups[i]._files[j]._fileSize = _fd->readUint32LE();
71 debug(8, " %08X, %08X, %d", _groups[i]._files[j]._id, _groups[i]._files[j]._fileOffset, _groups[i]._files[j]._fileSize);
72 }
73 }
74
75 delete[] groupOffsets;
76 }
77
getGroupEntry(uint32 sceneId)78 const GamGroupEntry *GamArchive::getGroupEntry(uint32 sceneId) {
79 for (uint i = 0; i < _groupCount; ++i) {
80 if (_groups[i]._id == sceneId)
81 return &_groups[i];
82 }
83 return 0;
84 }
85
getFileEntry(const GamGroupEntry * groupEntry,uint32 resId)86 const GamFileEntry *GamArchive::getFileEntry(const GamGroupEntry *groupEntry, uint32 resId) {
87 for (uint i = 0; i < groupEntry->_fileCount; ++i) {
88 if (groupEntry->_files[i]._id == resId)
89 return &groupEntry->_files[i];
90 }
91 return 0;
92 }
93
getGroupFileEntry(uint32 sceneId,uint32 resId)94 const GamFileEntry *GamArchive::getGroupFileEntry(uint32 sceneId, uint32 resId) {
95 const GamGroupEntry *groupEntry = getGroupEntry(sceneId);
96 if (!groupEntry)
97 error("GamArchive::getFileEntry() Group %08X not found", sceneId);
98 const GamFileEntry *fileEntry = getFileEntry(groupEntry, resId);
99 if (!fileEntry)
100 error("GamArchive::getFileEntry() File %08X in group %08X not found", resId, sceneId);
101 return fileEntry;
102 }
103
104 } // End of namespace Illusions
105