blob: 292ca023e71dd455b09f3c1ceeaa2db826db9b1a (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
#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();
}
}
|