aboutsummaryrefslogtreecommitdiff
path: root/engines/xeen/files.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/xeen/files.cpp')
-rw-r--r--engines/xeen/files.cpp54
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;
}