MACVENTURE: Add generic non-persistent container loading
This commit is contained in:
parent
9fc9e33981
commit
56e8ac873b
2 changed files with 60 additions and 64 deletions
|
@ -26,6 +26,7 @@
|
||||||
#include "macventure/macventure.h"
|
#include "macventure/macventure.h"
|
||||||
|
|
||||||
#include "common/file.h"
|
#include "common/file.h"
|
||||||
|
#include "common/bitstream.h"
|
||||||
|
|
||||||
namespace MacVenture {
|
namespace MacVenture {
|
||||||
|
|
||||||
|
@ -56,8 +57,8 @@ public:
|
||||||
_numObjs = dataLen / _lenObjs;
|
_numObjs = dataLen / _lenObjs;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ContainerHeader subHead = _header & 0x7fffffff;
|
_header &= 0x7fffffff;
|
||||||
_res->seek(subHead, SEEK_SET);
|
_res->seek(_header, SEEK_SET);
|
||||||
_numObjs = _res->readUint16BE();
|
_numObjs = _res->readUint16BE();
|
||||||
|
|
||||||
for (int i = 0; i < 15; ++i)
|
for (int i = 0; i < 15; ++i)
|
||||||
|
@ -66,71 +67,50 @@ public:
|
||||||
for (int i = 0; i < 16; ++i)
|
for (int i = 0; i < 16; ++i)
|
||||||
_lens[i] = _res->readByte();
|
_lens[i] = _res->readByte();
|
||||||
|
|
||||||
ItemGroup group;
|
// Read groups
|
||||||
for (int i = 0; i < _numObjs; ++i) {
|
uint numGroups = _numObjs / 64;
|
||||||
uint32 bits;
|
if ((_numObjs % 64) > 0)
|
||||||
if ((i & 0x37) == 0) { // It's the start of a group
|
numGroups++;
|
||||||
// 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
|
for (uint i = 0; i < numGroups; ++i) {
|
||||||
// Read the value in 32 bits
|
ItemGroup group;
|
||||||
uint32 v = (_res->readUint32BE() >> (16 - bits)) & 0xffff;
|
|
||||||
// Go back
|
// Place myself in the correct position to read group
|
||||||
_res->seek(-4, SEEK_CUR);
|
_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);
|
||||||
|
|
||||||
// Look in the Huffman table
|
b1 = _res->readByte();
|
||||||
int x;
|
b2 = _res->readByte();
|
||||||
for (x = 0; x<16; x++)
|
b3 = _res->readByte();
|
||||||
if (_huff[x] > v) break;
|
group.offset = (b1 << 16) + (b2 << 8) + (b3 << 0);
|
||||||
|
|
||||||
// Bits that we need to read from the length table
|
// Place the bit reader in the correct position
|
||||||
uint8 bitsToRead = _lens[x];
|
// group.bitOffset indicates the offset from the start of the subHeader
|
||||||
|
_res->seek(_header + (group.bitOffset >> 3), SEEK_SET);
|
||||||
|
|
||||||
bits += (bitsToRead & 0xf);
|
Common::BitStream32BEMSB bitStream(_res);
|
||||||
if (bits & 0x10) {
|
// Skip the last 3 bits that we couldn't skip with seek
|
||||||
bits &= 0xf;
|
bitStream.skip(group.bitOffset & 7);
|
||||||
_res->seek(2, SEEK_CUR);
|
for (uint j = 0; j < 64; ++j) {
|
||||||
}
|
uint32 length = 0;
|
||||||
|
uint32 mask = bitStream.peekBits(16);
|
||||||
// We already have in bits the first 4 bits (97)
|
// Look in the Huffman table
|
||||||
bitsToRead = bitsToRead >> 4;
|
int x;
|
||||||
|
for (x = 0; x<16; x++)
|
||||||
// The actual length of the object
|
if (_huff[x] > mask) break;
|
||||||
uint32 len = 0;
|
// OK UNTIL HERE
|
||||||
if (bitsToRead) {
|
// There may be a bug from this point forward, as the
|
||||||
// Peek 4 bytes
|
// lengths do not seem to coincide
|
||||||
len = _res->readUint32BE();
|
length = bitStream.getBits(_lens[x]);
|
||||||
_res->seek(-4, SEEK_CUR);
|
|
||||||
|
group.lengths[j] = length;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_groups.push_back(group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -169,6 +149,19 @@ public:
|
||||||
return item;
|
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:
|
protected:
|
||||||
|
|
||||||
uint _lenObjs;
|
uint _lenObjs;
|
||||||
|
@ -183,6 +176,9 @@ protected:
|
||||||
Common::File _file;
|
Common::File _file;
|
||||||
Common::SeekableReadStream *_res;
|
Common::SeekableReadStream *_res;
|
||||||
|
|
||||||
|
// To be moved
|
||||||
|
//byte _remainderOffset;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -19,7 +19,7 @@ World::World(MacVentureEngine *engine, Common::MacResManager *resMan) {
|
||||||
|
|
||||||
_saveGame = new SaveGame(_engine, saveGameRes);
|
_saveGame = new SaveGame(_engine, saveGameRes);
|
||||||
|
|
||||||
_objectConstants = new Container<uint16>("Shadowgate II/Shadow Object.TXT");
|
_objectConstants = new Container<uint16>("Shadowgate II/Shadow Graphic");
|
||||||
|
|
||||||
delete saveGameRes;
|
delete saveGameRes;
|
||||||
saveGameFile.close();
|
saveGameFile.close();
|
||||||
|
@ -47,7 +47,7 @@ bool World::loadStartGameFileName() {
|
||||||
res->read(fileName, length);
|
res->read(fileName, length);
|
||||||
fileName[length] = '\0';
|
fileName[length] = '\0';
|
||||||
_startGameFileName = Common::String(fileName, length);
|
_startGameFileName = Common::String(fileName, length);
|
||||||
_startGameFileName.replace(_startGameFileName.end(), _startGameFileName.end(), ".TXT");
|
_startGameFileName.replace(_startGameFileName.end(), _startGameFileName.end(), ".bin");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue