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

directorysubentry.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 "engines/myst3/directorysubentry.h"
00025 
00026 #include "common/str.h"
00027 #include "common/debug.h"
00028 #include "common/file.h"
00029 #include "common/memstream.h"
00030 
00031 namespace Myst3 {
00032 
00033 DirectorySubEntry::DirectorySubEntry(Archive *archive) :
00034         _archive(archive) {
00035 }
00036 
00037 void DirectorySubEntry::readFromStream(Common::SeekableReadStream &inStream) {
00038     _offset = inStream.readUint32LE();
00039     _size = inStream.readUint32LE();
00040     _metadataSize = inStream.readUint16LE();
00041     _face = inStream.readByte();
00042     _type = static_cast<ResourceType>(inStream.readByte());
00043 
00044     if (_metadataSize == 2 && (_type == kSpotItem || _type == kLocalizedSpotItem)) {
00045         _spotItemData.u = inStream.readUint32LE();
00046         _spotItemData.v = inStream.readUint32LE();
00047     } else if (_metadataSize == 10 && (_type == kMovie || _type == kMultitrackMovie)) {
00048         _videoData.v1.setValue(0, inStream.readSint32LE() * 0.000001f);
00049         _videoData.v1.setValue(1, inStream.readSint32LE() * 0.000001f);
00050         _videoData.v1.setValue(2, inStream.readSint32LE() * 0.000001f);
00051 
00052         _videoData.v2.setValue(0, inStream.readSint32LE() * 0.000001f);
00053         _videoData.v2.setValue(1, inStream.readSint32LE() * 0.000001f);
00054         _videoData.v2.setValue(2, inStream.readSint32LE() * 0.000001f);
00055 
00056         _videoData.u = inStream.readSint32LE();
00057         _videoData.v = inStream.readSint32LE();
00058         _videoData.width = inStream.readSint32LE();
00059         _videoData.height = inStream.readSint32LE();
00060     } else if (_type == kNumMetadata || _type == kTextMetadata) {
00061         _miscData.resize(_metadataSize + 2);
00062         _miscData[0] = _offset;
00063         _miscData[1] = _size;
00064 
00065         for (uint i = 0; i < _metadataSize; i++)
00066             _miscData[i + 2] = inStream.readUint32LE();
00067     } else if (_metadataSize != 0) {
00068         warning("Metadata not read for type %d, size %d", _type, _metadataSize);
00069         inStream.skip(_metadataSize * sizeof(uint32));
00070     }
00071 }
00072 
00073 void DirectorySubEntry::dumpToFile(Common::SeekableReadStream &inStream, const char* room, uint32 index) {
00074     char fileName[255];
00075     
00076     switch (_type) {
00077         case kNumMetadata:
00078         case kTextMetadata:
00079             return; // These types are pure metadata and can't be extracted
00080         case kCubeFace:
00081         case kSpotItem:
00082         case kLocalizedSpotItem:
00083         case kFrame:
00084             sprintf(fileName, "dump/%s-%d-%d.jpg", room, index, _face);
00085             break;
00086         case kWaterEffectMask:
00087             sprintf(fileName, "dump/%s-%d-%d.mask", room, index, _face);
00088             break;
00089         case kMovie:
00090         case kStillMovie:
00091         case kDialogMovie:
00092         case kMultitrackMovie:
00093             sprintf(fileName, "dump/%s-%d.bik", room, index);
00094             break;
00095         default:
00096             sprintf(fileName, "dump/%s-%d-%d.%d", room, index, _face, _type);
00097             break;
00098     }
00099     
00100     
00101     debug("Extracted %s", fileName);
00102     
00103     Common::DumpFile outFile;
00104     if (!outFile.open(fileName))
00105         error("Unable to open file '%s' for writing", fileName);
00106     
00107     inStream.seek(_offset);
00108     
00109     uint8 *buf = new uint8[_size];
00110     
00111     inStream.read(buf, _size);
00112     outFile.write(buf, _size);
00113     
00114     delete[] buf;
00115     
00116     outFile.close();
00117 }
00118 
00119 Common::MemoryReadStream *DirectorySubEntry::getData() const {
00120     return _archive->dumpToMemory(_offset, _size);
00121 }
00122 
00123 uint32 DirectorySubEntry::getMiscData(uint index) const {
00124     return _miscData[index];
00125 }
00126 
00127 Common::String DirectorySubEntry::getTextData(uint index) const {
00128     uint8 key = 35;
00129     uint8 cnt = 0;
00130     uint8 decrypted[89];
00131     memset(decrypted, 0, sizeof(decrypted));
00132 
00133     uint8 *out = &decrypted[0];
00134     while (cnt / 4 < _miscData.size() && cnt < 89) {
00135         // XORed text stored in little endian 32 bit words
00136         *out++ = (_miscData[cnt / 4] >> (8 * (3 - (cnt % 4)))) ^ key++;
00137         cnt++;
00138     }
00139 
00140     // decrypted contains a null separated string array
00141     // extract the wanted one
00142     cnt = 0;
00143     int i = 0;
00144     Common::String text;
00145     while (cnt <= index && i < 89) {
00146         if (cnt == index)
00147             text += decrypted[i];
00148 
00149         if (!decrypted[i])
00150             cnt++;
00151 
00152         i++;
00153     }
00154 
00155     return text;
00156 }
00157 
00158 } // End of namespace Myst3


Generated on Sat Feb 16 2019 05:00:49 for ResidualVM by doxygen 1.7.1
curved edge   curved edge