DIRECTOR: Further work loading assets from D5 Movies.

This commit is contained in:
stevenhoefel 2017-04-06 14:55:15 +10:00
parent 514871316f
commit 90e97f7069
4 changed files with 82 additions and 54 deletions

View File

@ -26,7 +26,7 @@
namespace Director {
BitmapCast::BitmapCast(Common::ReadStreamEndian &stream, uint16 version) {
BitmapCast::BitmapCast(Common::ReadStreamEndian &stream, uint32 castTag, uint16 version) {
if (version < 4) {
flags = stream.readByte();
someFlaggyThing = stream.readUint16();
@ -71,35 +71,33 @@ BitmapCast::BitmapCast(Common::ReadStreamEndian &stream, uint16 version) {
uint32 unk2 = stream.readUint32();
uint32 unk3 = stream.readUint32();
uint32 unk4 = stream.readUint32();
uint32 unk5 = stream.readUint32();
uint32 unk6 = stream.readUint32();
uint32 unk7 = stream.readUint32();
uint16 count = stream.readUint16();
for (uint16 cc = 0; cc < count; cc++)
stream.readUint32();
stream.readUint32();
byte stringLength = stream.readByte();
char* string = new char[stringLength];
stream.read(string, stringLength);
stream.readUint16();
/*node.x1 = stream.readUint16();
if (node.x1 > 2048) node.x1 = -(0xffff - node.x1);
node.y1 = ReadWordAsInt(ref start, true);
if (node.y1 > 2048) node.y1 = -(0xffff - node.y1);
node.x2 = ReadWordAsInt(ref start, true);
node.y2 = ReadWordAsInt(ref start, true);*/
uint32 stringLength = stream.readUint32();
for (int s = 0; s < stringLength; s++)
stream.readByte();
uint16 width = stream.readUint16LE(); //maybe?
initialRect = Score::readRect(stream);
//node.h = (node.x2 - node.x1);
//node.w = (node.y2 - node.y1);
stream.readUint16();
stream.readUint16();
uint32 somethingElse = stream.readUint32();
boundingRect = Score::readRect(stream);
bitsPerPixel = stream.readUint16();
regX = 0;
regY = 0;
stream.readUint32();
}
modified = 0;
tag = castTag;
}
TextCast::TextCast(Common::ReadStreamEndian &stream, uint16 version) {
@ -238,7 +236,7 @@ ButtonCast::ButtonCast(Common::ReadStreamEndian &stream, uint16 version) : TextC
ScriptCast::ScriptCast(Common::ReadStreamEndian &stream, uint16 version) {
if (version < 4) {
error("Unhandled Script cast");
} else {
} else if (version == 4) {
stream.readByte();
stream.readByte();
@ -251,6 +249,18 @@ ScriptCast::ScriptCast(Common::ReadStreamEndian &stream, uint16 version) {
stream.readByte(); // There should be no more data
assert(stream.eos());
} else if (version > 4) {
stream.readByte();
stream.readByte();
initialRect = Score::readRect(stream);
boundingRect = Score::readRect(stream);
id = stream.readUint32();
debugC(4, kDebugLoading, "CASt: Script id: %d", id);
// WIP need to complete this!
}
modified = 0;
}

View File

@ -59,7 +59,7 @@ public:
class BitmapCast : public Cast {
public:
BitmapCast(Common::ReadStreamEndian &stream, uint16 version = 2);
BitmapCast(Common::ReadStreamEndian &stream, uint32 castTag, uint16 version = 2);
uint16 regX;
uint16 regY;
@ -68,6 +68,8 @@ public:
uint16 unk1, unk2;
uint16 bitsPerPixel;
uint32 tag;
};
enum ShapeType {

View File

@ -610,7 +610,7 @@ void Frame::renderSprites(Graphics::ManagedSurface &surface, bool renderTrail) {
int x = _sprites[i]->_startPoint.x - regX + rectLeft;
int y = _sprites[i]->_startPoint.y - regY + rectTop;
int height = _sprites[i]->_height;
int width = _sprites[i]->_width;
int width = _vm->getVersion() > 4 ? _sprites[i]->_bitmapCast->initialRect.width() : _sprites[i]->_width;
Common::Rect drawRect(x, y, x + width, y + height);
addDrawRect(i, drawRect);

View File

@ -135,6 +135,9 @@ void Score::loadArchive() {
if (_movieArchive->hasResource(MKTAG('V', 'W', 'C', 'F'), -1)) {
loadConfig(*_movieArchive->getResource(MKTAG('V', 'W', 'C', 'F'), 1024));
} else {
// TODO: Source this from somewhere!
_movieRect = Common::Rect(0, 0, 640, 480);
}
if (_movieArchive->hasResource(MKTAG('V', 'W', 'C', 'R'), -1)) {
@ -196,35 +199,43 @@ void Score::loadSpriteImages(bool isSharedCast) {
Common::HashMap<int, BitmapCast *>::iterator bc;
for (bc = _loadedBitmaps->begin(); bc != _loadedBitmaps->end(); ++bc) {
if (bc->_value) {
uint32 tag = bc->_value->tag;
uint16 imgId = bc->_key + 1024;
BitmapCast *bitmapCast = bc->_value;
if (_vm->getVersion() >= 4 && bitmapCast->children.size() > 0)
if (_vm->getVersion() >= 4 && bitmapCast->children.size() > 0) {
imgId = bitmapCast->children[0].index;
tag = bitmapCast->children[0].tag;
}
Image::ImageDecoder *img = NULL;
if (_movieArchive->hasResource(MKTAG('D', 'I', 'B', ' '), imgId)) {
img = new DIBDecoder();
img->loadStream(*_movieArchive->getResource(MKTAG('D', 'I', 'B', ' '), imgId));
bitmapCast->surface = img->getSurface();
}
if (isSharedCast && _vm->getSharedDIB() != NULL && _vm->getSharedDIB()->contains(imgId)) {
img = new DIBDecoder();
img->loadStream(*_vm->getSharedDIB()->getVal(imgId));
bitmapCast->surface = img->getSurface();
}
Common::SeekableReadStream *pic = NULL;
if (isSharedCast) {
debugC(4, kDebugImages, "Shared cast BMP: id: %d", imgId);
pic = _vm->getSharedBMP()->getVal(imgId);
if (pic != NULL)
pic->seek(0); // TODO: this actually gets re-read every loop... we need to rewind it!
} else if (_movieArchive->hasResource(MKTAG('B', 'I', 'T', 'D'), imgId)) {
pic = _movieArchive->getResource(MKTAG('B', 'I', 'T', 'D'), imgId);
switch (tag) {
case MKTAG('D', 'I', 'B', ' '):
if (_movieArchive->hasResource(MKTAG('D', 'I', 'B', ' '), imgId)) {
img = new DIBDecoder();
img->loadStream(*_movieArchive->getResource(MKTAG('D', 'I', 'B', ' '), imgId));
bitmapCast->surface = img->getSurface();
} else if (isSharedCast && _vm->getSharedDIB() != NULL && _vm->getSharedDIB()->contains(imgId)) {
img = new DIBDecoder();
img->loadStream(*_vm->getSharedDIB()->getVal(imgId));
bitmapCast->surface = img->getSurface();
}
break;
case MKTAG('B', 'I', 'T', 'D'):
if (isSharedCast) {
debugC(4, kDebugImages, "Shared cast BMP: id: %d", imgId);
pic = _vm->getSharedBMP()->getVal(imgId);
if (pic != NULL)
pic->seek(0); // TODO: this actually gets re-read every loop... we need to rewind it!
} else if (_movieArchive->hasResource(MKTAG('B', 'I', 'T', 'D'), imgId)) {
pic = _movieArchive->getResource(MKTAG('B', 'I', 'T', 'D'), imgId);
}
break;
default:
warning("Unknown Bitmap Cast Tag: [%d] %s", tag, tag2str(tag));
break;
}
int w = bitmapCast->initialRect.width(), h = bitmapCast->initialRect.height();
@ -242,9 +253,9 @@ void Score::loadSpriteImages(bool isSharedCast) {
img->loadStream(*pic);
bitmapCast->surface = img->getSurface();
} else {
warning("Image %d not found", imgId);
}
warning("Image %d not found", imgId);
}
}
}
@ -408,7 +419,7 @@ void Score::loadCastDataVWCR(Common::SeekableSubReadStreamEndian &stream) {
if (size == 0)
continue;
if (debugChannelSet(5, kDebugLoading))
if (debugChannelSet(5, kDebugLoading) && size < 2048)
stream.hexdump(size);
uint8 castType = stream.readByte();
@ -416,7 +427,8 @@ void Score::loadCastDataVWCR(Common::SeekableSubReadStreamEndian &stream) {
switch (castType) {
case kCastBitmap:
debugC(3, kDebugLoading, "CastTypes id: %d BitmapCast", id);
_loadedBitmaps->setVal(id, new BitmapCast(stream));
// TODO: Work out the proper tag!
_loadedBitmaps->setVal(id, new BitmapCast(stream, MKTAG('B', 'I', 'T', 'D')));
_castTypes[id] = kCastBitmap;
break;
case kCastText:
@ -498,14 +510,14 @@ void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id,
debugC(3, kDebugLoading, "CASt: id: %d", id);
if (debugChannelSet(5, kDebugLoading))
if (debugChannelSet(5, kDebugLoading) && stream.size() < 2048)
stream.hexdump(stream.size());
uint32 size1, size2, size3, castType;
byte unk1 = 0, unk2 = 0, unk3 = 0;
if (_vm->getVersion() <= 3) {
size1 = stream.readUint16() + 16;
size1 = stream.readUint16() + 16; // 16 is for bounding rects
size2 = stream.readUint32();
size3 = 0;
castType = stream.readByte();
@ -513,7 +525,7 @@ void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id,
unk2 = stream.readByte();
unk3 = stream.readByte();
} else if (_vm->getVersion() == 4) {
size1 = stream.readUint16() + 2 + 16;
size1 = stream.readUint16() + 2 + 16; // 16 is for bounding rects
size2 = stream.readUint32();
size3 = 0;
castType = stream.readByte();
@ -524,9 +536,11 @@ void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id,
size3 = stream.readUint32();
size2 = stream.readUint32();
size1 = stream.readUint32() - 4;
size1 = stream.readUint32();
// assert(size1 == 0x14);
// size1 = 0;
// don't read the strings later, the full cast data is needed to be parsed.
size1 = stream.size();
} else {
error("Score::loadCastData: unsupported Director version (%d)", _vm->getVersion());
}
@ -534,14 +548,14 @@ void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id,
debugC(3, kDebugLoading, "CASt: id: %d type: %x size1: %d size2: %d (%x) size3: %d unk1: %d unk2: %d unk3: %d",
id, castType, size1, size2, size2, size3, unk1, unk2, unk3);
byte *data = (byte *)calloc(size1, 1); // 16 is for bounding rects
byte *data = (byte *)calloc(size1, 1);
stream.read(data, size1);
Common::MemoryReadStreamEndian castStream(data, size1, stream.isBE());
switch (castType) {
case kCastBitmap:
_loadedBitmaps->setVal(id, new BitmapCast(castStream, _vm->getVersion()));
_loadedBitmaps->setVal(id, new BitmapCast(castStream, res->tag, _vm->getVersion()));
for (uint child = 0; child < res->children.size(); child++)
_loadedBitmaps->getVal(id)->children.push_back(res->children[child]);
_castTypes[id] = kCastBitmap;
@ -570,12 +584,14 @@ void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id,
break;
default:
warning("Score::loadCastData(): Unhandled cast type: %d [%s]", castType, tag2str(castType));
// also don't try and read the strings... we don't know what this item is.
size2 = 0;
break;
}
free(data);
if (size2) {
if (size2 && _vm->getVersion() < 5) {
uint32 entryType = 0;
Common::Array<Common::String> castStrings = loadStrings(stream, entryType, false);