diff options
Diffstat (limited to 'engines/xeen/files.cpp')
-rw-r--r-- | engines/xeen/files.cpp | 54 |
1 files changed, 36 insertions, 18 deletions
diff --git a/engines/xeen/files.cpp b/engines/xeen/files.cpp index 912c9533d8..86fb3fc3e3 100644 --- a/engines/xeen/files.cpp +++ b/engines/xeen/files.cpp @@ -66,42 +66,35 @@ void BaseCCArchive::loadIndex(Common::SeekableReadStream &stream) { // Decrypt the index int seed = 0xac; for (int i = 0; i < count * 8; ++i, seed += 0x67) { - rawIndex[i] = (byte)(((rawIndex[i] << 2 | rawIndex[i] >> 6) + seed) & 0xff); + rawIndex[i] = (byte)((((rawIndex[i] << 2) | (rawIndex[i] >> 6)) + seed) & 0xff); } // Extract the index data into entry structures - _index.reserve(count); + _index.resize(count); const byte *entryP = &rawIndex[0]; - for (int i = 0; i < count; ++i, entryP += 8) { + for (int idx = 0; idx < count; ++idx, entryP += 8) { CCEntry entry; entry._id = READ_LE_UINT16(entryP); entry._offset = READ_LE_UINT32(entryP + 2) & 0xffffff; entry._size = READ_LE_UINT16(entryP + 5); assert(!entryP[7]); - _index.push_back(entry); + _index[idx] = entry; } delete[] rawIndex; } void BaseCCArchive::saveIndex(Common::WriteStream &stream) { - // First caclculate file offsets for each resource, since replaced resources - // will shift file offsets for even the succeeding unchanged resources - for (uint idx = 1, pos = _index[0]._offset + _index[0]._size; idx < _index.size(); ++idx) { - _index[idx]._offset = pos; - pos += _index[idx]._size; - } - // Fill up the data for the index entries into a raw data block - byte data[8]; byte *rawIndex = new byte[_index.size() * 8]; + byte b; byte *entryP = rawIndex; for (uint i = 0; i < _index.size(); ++i, entryP += 8) { CCEntry &entry = _index[i]; WRITE_LE_UINT16(&entryP[0], entry._id); - WRITE_LE_UINT32(&entryP[2], entry._offset); + WRITE_LE_UINT32(&entryP[2], entry._writeOffset); WRITE_LE_UINT16(&entryP[5], entry._size); entryP[7] = 0; } @@ -109,8 +102,11 @@ void BaseCCArchive::saveIndex(Common::WriteStream &stream) { // Encrypt the index int seed = 0xac; for (uint i = 0; i < _index.size() * 8; ++i, seed += 0x67) { - byte b = (seed - rawIndex[i]) && 0xff; - rawIndex[i] = ((b >> 2) & 0x3f) | ((b & 3) << 6); + b = (rawIndex[i] - seed) & 0xff; + b = (byte)((b >> 2) | (b << 6)); + + assert(rawIndex[i] == (byte)((((b << 2) | (b >> 6)) + seed) & 0xff)); + rawIndex[i] = b; } // Write out the number of entries and the encrypted index data @@ -253,6 +249,14 @@ void FileManager::setGameCc(int ccMode) { _isDarkCc = ccMode != 0; } +void FileManager::load(Common::SeekableReadStream &stream) { + setGameCc(stream.readByte()); +} + +void FileManager::save(Common::WriteStream &s) { + s.writeByte(_isDarkCc ? 1 : 0); +} + /*------------------------------------------------------------------------*/ CCArchive *File::_xeenCc; @@ -297,7 +301,7 @@ bool File::open(const Common::String &filename, int ccMode) { int oldMode = files._isDarkCc ? 1 : 0; files.setGameCc(ccMode); - File::open(filename); + File::open(filename, *_currentArchive); files.setGameCc(oldMode); return true; @@ -482,13 +486,26 @@ void SaveArchive::save(Common::WriteStream &s) { OutFile chr("maze.chr", this); XeenSerializer sChr(nullptr, &chr); _party->_roster.synchronize(sChr); + chr.finalize(); OutFile pty("maze.pty", this); Common::Serializer sPty(nullptr, &pty); _party->synchronize(sPty); + pty.finalize(); + + // First caclculate new offsets and total filesize + _dataSize = _index.size() * 8 + 2; + for (uint idx = 0; idx < _index.size(); ++idx) { + _index[idx]._writeOffset = (idx == 0) ? _dataSize : + _index[idx - 1]._writeOffset + _index[idx - 1]._size; + _dataSize += _index[idx]._size; + } + + s.writeUint32LE(_dataSize); // Save out the index - saveIndex(s); + SubWriteStream dataStream(&s); + saveIndex(dataStream); // Save out each resource in turn for (uint idx = 0; idx < _index.size(); ++idx) { @@ -498,7 +515,8 @@ void SaveArchive::save(Common::WriteStream &s) { entry->read(data, entry->size()); // Write it out to the savegame - s.write(data, entry->size()); + assert(dataStream.pos() == _index[idx]._writeOffset); + dataStream.write(data, entry->size()); delete[] data; delete entry; } |