diff options
author | Borja Lorente | 2016-06-15 00:21:57 +0200 |
---|---|---|
committer | Borja Lorente | 2016-08-14 18:24:58 +0200 |
commit | 56e8ac873b05f68fc9dfa1aa09f136974c71d353 (patch) | |
tree | d9f11438cd6b71bac7cc0fddfd9a208f88699232 | |
parent | 9fc9e3398186f1405ac36497f53fe9a95839c257 (diff) | |
download | scummvm-rg350-56e8ac873b05f68fc9dfa1aa09f136974c71d353.tar.gz scummvm-rg350-56e8ac873b05f68fc9dfa1aa09f136974c71d353.tar.bz2 scummvm-rg350-56e8ac873b05f68fc9dfa1aa09f136974c71d353.zip |
MACVENTURE: Add generic non-persistent container loading
-rw-r--r-- | engines/macventure/container.h | 128 | ||||
-rw-r--r-- | engines/macventure/world.cpp | 4 |
2 files changed, 64 insertions, 68 deletions
diff --git a/engines/macventure/container.h b/engines/macventure/container.h index fc350735d2..c2b558f6d3 100644 --- a/engines/macventure/container.h +++ b/engines/macventure/container.h @@ -26,6 +26,7 @@ #include "macventure/macventure.h" #include "common/file.h" +#include "common/bitstream.h" namespace MacVenture { @@ -56,8 +57,8 @@ public: _numObjs = dataLen / _lenObjs; } else { - ContainerHeader subHead = _header & 0x7fffffff; - _res->seek(subHead, SEEK_SET); + _header &= 0x7fffffff; + _res->seek(_header, SEEK_SET); _numObjs = _res->readUint16BE(); for (int i = 0; i < 15; ++i) @@ -66,71 +67,50 @@ public: for (int i = 0; i < 16; ++i) _lens[i] = _res->readByte(); - ItemGroup group; - for (int i = 0; i < _numObjs; ++i) { - uint32 bits; - if ((i & 0x37) == 0) { // It's the start of a group - // Place myself in the correct position to read group - _res->seek(subHead + (i >> 6) * 6 + 0x30, SEEK_SET); - _res->read(&bits, 3); - bits >>= 4; - _res->read(&group.offset, 3); // Read 3 bytes - group.offset >>= 4; - bits &= 7; - group.bitOffset = bits; - _res->seek(subHead + (bits >> 3), SEEK_SET); - } - - // Workaround to implement peek - // Read the value in 32 bits - uint32 v = (_res->readUint32BE() >> (16 - bits)) & 0xffff; - // Go back - _res->seek(-4, SEEK_CUR); - - // Look in the Huffman table - int x; - for (x = 0; x<16; x++) - if (_huff[x] > v) break; - - // Bits that we need to read from the length table - uint8 bitsToRead = _lens[x]; - - bits += (bitsToRead & 0xf); - if (bits & 0x10) { - bits &= 0xf; - _res->seek(2, SEEK_CUR); - } - - // We already have in bits the first 4 bits (97) - bitsToRead = bitsToRead >> 4; - - // The actual length of the object - uint32 len = 0; - if (bitsToRead) { - // Peek 4 bytes - len = _res->readUint32BE(); - _res->seek(-4, SEEK_CUR); - - bitsToRead--; - - if (bitsToRead == 0) len = 0; - else len >>= (32 - bitsToRead) - bits; - - len &= (1 << bitsToRead) - 1; - len |= 1 << bitsToRead; - - if (bits & 0x10) { - bits &= 0xf; - _res->seek(2, SEEK_CUR); - } - - } - - group.lengths[(i & 0x3f)] = len; - - if ((i & 0x37) == 0) { - _groups.push_back(group); + // Read groups + uint numGroups = _numObjs / 64; + if ((_numObjs % 64) > 0) + numGroups++; + + for (uint i = 0; i < numGroups; ++i) { + ItemGroup group; + + // Place myself in the correct position to read group + _res->seek(_header + (i * 6) + 0x30, SEEK_SET); + byte b1, b2, b3; + b1 = _res->readByte(); + b2 = _res->readByte(); + b3 = _res->readByte(); + group.bitOffset = (b1 << 16) + (b2 << 8) + (b3 << 0); + + b1 = _res->readByte(); + b2 = _res->readByte(); + b3 = _res->readByte(); + group.offset = (b1 << 16) + (b2 << 8) + (b3 << 0); + + // Place the bit reader in the correct position + // group.bitOffset indicates the offset from the start of the subHeader + _res->seek(_header + (group.bitOffset >> 3), SEEK_SET); + + Common::BitStream32BEMSB bitStream(_res); + // Skip the last 3 bits that we couldn't skip with seek + bitStream.skip(group.bitOffset & 7); + for (uint j = 0; j < 64; ++j) { + uint32 length = 0; + uint32 mask = bitStream.peekBits(16); + // Look in the Huffman table + int x; + for (x = 0; x<16; x++) + if (_huff[x] > mask) break; + // OK UNTIL HERE + // There may be a bug from this point forward, as the + // lengths do not seem to coincide + length = bitStream.getBits(_lens[x]); + + group.lengths[j] = length; } + + _groups.push_back(group); } } } @@ -169,6 +149,19 @@ public: return item; } + /* + void seekBits(uint32 bitNum) { + uint bytes = bits / 8; + _remainderOffset = bits % 8; + _res->seek(bytes, SEEK_SET); + } + + void readBits((void*)target, uint32 bitNum) { + // Skip the first _remainderOffset bits, read bitNum from that point + byte offset = 0xFF << _remainderOffset; + + }*/ + protected: uint _lenObjs; @@ -183,6 +176,9 @@ protected: Common::File _file; Common::SeekableReadStream *_res; + // To be moved + //byte _remainderOffset; + }; /* diff --git a/engines/macventure/world.cpp b/engines/macventure/world.cpp index 835d53ae10..dccf63ad2e 100644 --- a/engines/macventure/world.cpp +++ b/engines/macventure/world.cpp @@ -19,7 +19,7 @@ World::World(MacVentureEngine *engine, Common::MacResManager *resMan) { _saveGame = new SaveGame(_engine, saveGameRes); - _objectConstants = new Container<uint16>("Shadowgate II/Shadow Object.TXT"); + _objectConstants = new Container<uint16>("Shadowgate II/Shadow Graphic"); delete saveGameRes; saveGameFile.close(); @@ -47,7 +47,7 @@ bool World::loadStartGameFileName() { res->read(fileName, length); fileName[length] = '\0'; _startGameFileName = Common::String(fileName, length); - _startGameFileName.replace(_startGameFileName.end(), _startGameFileName.end(), ".TXT"); + _startGameFileName.replace(_startGameFileName.end(), _startGameFileName.end(), ".bin"); return true; } |