diff options
author | WinterGrascph | 2016-05-03 17:55:04 +0200 |
---|---|---|
committer | Bendegúz Nagy | 2016-08-26 23:02:22 +0200 |
commit | cdf377f7a7a43521403c38014bb1406b1ce15721 (patch) | |
tree | 7c45683f4025da5b095e259c0398098a0853c356 /engines/dm/dungeonman.cpp | |
parent | 055e789d0461f881b13cb4fe6e3331b1872eb633 (diff) | |
download | scummvm-rg350-cdf377f7a7a43521403c38014bb1406b1ce15721.tar.gz scummvm-rg350-cdf377f7a7a43521403c38014bb1406b1ce15721.tar.bz2 scummvm-rg350-cdf377f7a7a43521403c38014bb1406b1ce15721.zip |
DM: Add support for Dungeon.dat uncompression
Add DungeonMan class with support for loading and uncompressing
Dungeon.dat file into memory
Diffstat (limited to 'engines/dm/dungeonman.cpp')
-rw-r--r-- | engines/dm/dungeonman.cpp | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/engines/dm/dungeonman.cpp b/engines/dm/dungeonman.cpp new file mode 100644 index 0000000000..6ddf966eb9 --- /dev/null +++ b/engines/dm/dungeonman.cpp @@ -0,0 +1,62 @@ +#include "dungeonman.h" +#include "common/file.h" + + +namespace DM { +DungeonMan::DungeonMan(DMEngine *dmEngine) : _vm(dmEngine), _dungeonDataSize(0), _dungeonData(NULL) {} +DungeonMan::~DungeonMan() { delete[] _dungeonData; } +void DungeonMan::loadDungeonFile() { + Common::File f; + f.open("Dungeon.dat"); + if (f.readUint16BE() == 0x8104) { + _dungeonDataSize = f.readUint32BE(); + _dungeonData = new byte[_dungeonDataSize]; + f.readUint16BE(); + byte common[4]; + for (uint16 i = 0; i < 4; ++i) + common[i] = f.readByte(); + byte lessCommon[16]; + for (uint16 i = 0; i < 16; ++i) + lessCommon[i] = f.readByte(); + + // start unpacking + uint32 uncompIndex = 0; + uint8 bitsUsedInWord = 0; + uint16 wordBuff = f.readUint16BE(); + uint8 bitsLeftInByte = 8; + byte byteBuff = f.readByte(); + while (uncompIndex < _dungeonDataSize) { + while (bitsUsedInWord != 0) { + uint8 shiftVal; + if (f.eos()) { + shiftVal = bitsUsedInWord; + wordBuff <<= shiftVal; + } else { + shiftVal = MIN(bitsLeftInByte, bitsUsedInWord); + wordBuff <<= shiftVal; + wordBuff |= (byteBuff >> (8 - shiftVal)); + byteBuff <<= shiftVal; + bitsLeftInByte -= shiftVal; + if (!bitsLeftInByte) { + byteBuff = f.readByte(); + bitsLeftInByte = 8; + } + } + bitsUsedInWord -= shiftVal; + } + if (((wordBuff >> 15) & 1) == 0) { + _dungeonData[uncompIndex++] = common[(wordBuff >> 13) & 3]; + bitsUsedInWord += 3; + } else if (((wordBuff >> 14) & 3) == 2) { + _dungeonData[uncompIndex++] = lessCommon[(wordBuff >> 10) & 15]; + bitsUsedInWord += 6; + } else if (((wordBuff >> 14) & 3) == 3) { + _dungeonData[uncompIndex++] = (wordBuff >> 6) & 255; + bitsUsedInWord += 10; + } + } + } + f.close(); +} + +}
\ No newline at end of file |