aboutsummaryrefslogtreecommitdiff
path: root/engines/dm/dungeonman.cpp
diff options
context:
space:
mode:
authorWinterGrascph2016-05-03 17:55:04 +0200
committerBendegúz Nagy2016-08-26 23:02:22 +0200
commitcdf377f7a7a43521403c38014bb1406b1ce15721 (patch)
tree7c45683f4025da5b095e259c0398098a0853c356 /engines/dm/dungeonman.cpp
parent055e789d0461f881b13cb4fe6e3331b1872eb633 (diff)
downloadscummvm-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.cpp62
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