ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

engines/myst3/archive.cpp

Go to the documentation of this file.
00001 /* ResidualVM - A 3D game interpreter
00002  *
00003  * ResidualVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the AUTHORS
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "engines/myst3/archive.h"
00024 #include "common/debug.h"
00025 #include "common/memstream.h"
00026 
00027 namespace Myst3 {
00028 
00029 void Archive::_decryptHeader(Common::SeekableReadStream &inStream, Common::WriteStream &outStream) {
00030     static const uint32 addKey = 0x3C6EF35F;
00031     static const uint32 multKey = 0x0019660D;
00032 
00033     inStream.seek(0);
00034     uint32 size = inStream.readUint32LE();
00035 
00036     bool encrypted = size > 1000000;
00037     
00038     inStream.seek(0);
00039 
00040     if (encrypted) {
00041         uint32 decryptedSize = size ^ addKey;
00042 
00043         uint32 currentKey = 0;
00044         for (uint i = 0; i < decryptedSize; i++) {
00045             currentKey += addKey;
00046             outStream.writeUint32LE(inStream.readUint32LE() ^ currentKey);
00047             currentKey *= multKey;
00048         }
00049     } else {
00050         for (uint i = 0; i < size; i++) {
00051             outStream.writeUint32LE(inStream.readUint32LE());
00052         }
00053     }
00054 }
00055 
00056 void Archive::_readDirectory() {
00057     Common::MemoryWriteStreamDynamic buf(DisposeAfterUse::YES);
00058     _decryptHeader(_file, buf);
00059 
00060     Common::MemoryReadStream directory(buf.getData(), buf.size());
00061     directory.skip(sizeof(uint32));
00062 
00063     while (directory.pos() + 4 < directory.size()) {
00064         DirectoryEntry entry(this);
00065         
00066         if (_multipleRoom)
00067             entry.readFromStream(directory, 0);
00068         else
00069             entry.readFromStream(directory, _roomName);
00070 
00071         _directory.push_back(entry);
00072     }
00073 }
00074 
00075 void Archive::dumpToFiles() {
00076     for (uint i = 0; i < _directory.size(); i++) {
00077         _directory[i].dumpToFiles(_file);
00078     }
00079 }
00080 
00081 Common::MemoryReadStream *Archive::dumpToMemory(uint32 offset, uint32 size) {
00082     _file.seek(offset);
00083     return static_cast<Common::MemoryReadStream *>(_file.readStream(size));
00084 }
00085 
00086 const DirectorySubEntry *Archive::getDescription(const Common::String &room, uint32 index, uint16 face,
00087                                                  DirectorySubEntry::ResourceType type) {
00088     for (uint i = 0; i < _directory.size(); i++) {
00089         if (_directory[i].getIndex() == index && _directory[i].getRoom() == room) {
00090             return _directory[i].getItemDescription(face, type);
00091         }
00092     }
00093 
00094     return 0;
00095 }
00096 
00097 DirectorySubEntryList Archive::listFilesMatching(const Common::String &room, uint32 index, uint16 face,
00098                                                  DirectorySubEntry::ResourceType type) {
00099     for (uint i = 0; i < _directory.size(); i++) {
00100         if (_directory[i].getIndex() == index && _directory[i].getRoom() == room) {
00101             return _directory[i].listItemsMatching(face, type);
00102         }
00103     }
00104 
00105     return DirectorySubEntryList();
00106 }
00107 
00108 bool Archive::open(const char *fileName, const char *room) {
00109     // Copy the room name if provided
00110     // If the room name is not provided, it is assumed that
00111     // we are opening a multi-room archive
00112     _multipleRoom = room == 0;
00113     if (!_multipleRoom)
00114         Common::strlcpy(_roomName, room, sizeof(_roomName));
00115 
00116     if (_file.open(fileName)) {
00117         _readDirectory();
00118         return true;
00119     }
00120     
00121     return false;
00122 }
00123 
00124 void Archive::close() {
00125     _directory.clear();
00126     _file.close();
00127 }
00128 
00129 Common::String Archive::getRoomName() const {
00130     if (_multipleRoom) {
00131         error("'%s' is a multi-room archive", _file.getName());
00132     }
00133 
00134     return _roomName;
00135 }
00136 } // End of namespace Myst3


Generated on Sat Feb 23 2019 05:00:57 for ResidualVM by doxygen 1.7.1
curved edge   curved edge