scummvm/engines/dm/dungeonman.cpp

62 lines
1.7 KiB
C++
Raw Normal View History

#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();
}
}