DIRECTOR: Initial work for D5 RTE Cast Member loading.

This commit is contained in:
stevenhoefel 2017-09-14 13:08:57 +10:00
parent 49d2dd5bfb
commit b674c5712c
6 changed files with 158 additions and 66 deletions

View File

@ -420,7 +420,10 @@ bool RIFXArchive::openStream(Common::SeekableReadStream *stream, uint32 startOff
// or the children of
else if (tag == MKTAG('S', 'T', 'X', 'T') ||
tag == MKTAG('B', 'I', 'T', 'D') ||
tag == MKTAG('D', 'I', 'B', ' '))
tag == MKTAG('D', 'I', 'B', ' ') ||
tag == MKTAG('R', 'T', 'E', '0') ||
tag == MKTAG('R', 'T', 'E', '1') ||
tag == MKTAG('R', 'T', 'E', '2'))
_types[tag][i] = res;
}

View File

@ -173,8 +173,30 @@ TextCast::TextCast(Common::ReadStreamEndian &stream, uint16 version) {
fontSize = stream.readUint16();
textSlant = 0;
} else {
fontId = 1;
fontSize = 12;
stream.readUint32();
stream.readUint32();
stream.readUint32();
stream.readUint32();
uint16 skip = stream.readUint16();
for (int i = 0; i < skip; i++)
stream.readUint32();
stream.readUint32();
stream.readUint32();
stream.readUint32();
stream.readUint32();
stream.readUint32();
stream.readUint32();
initialRect = Score::readRect(stream);
boundingRect = Score::readRect(stream);
stream.readUint32();
stream.readUint16();
stream.readUint16();
}
modified = 0;
@ -193,6 +215,14 @@ void TextCast::importStxt(const Stxt *stxt) {
_ftext = stxt->_ftext;
}
void TextCast::importRTE(byte* text) {
//assert(rteList.size() == 3);
//child0 is probably font data.
//child1 is the raw text.
_ftext = Common::String((char*)text);
//child2 is positional?
}
ShapeCast::ShapeCast(Common::ReadStreamEndian &stream, uint16 version) {
if (version < 4) {
/*byte flags = */ stream.readByte();

View File

@ -45,7 +45,8 @@ enum CastType {
kCastShape = 8,
kCastMovie = 9,
kCastDigitalVideo = 10,
kCastLingoScript = 11
kCastLingoScript = 11,
kCastRTE = 12,
};
class Cast {
@ -142,6 +143,7 @@ public:
Common::String _ftext;
void importStxt(const Stxt *stxt);
void importRTE(byte* text);
CachedMacText *cachedMacText;
};

View File

@ -171,6 +171,10 @@ void Frame::readChannels(Common::ReadStreamEndian *stream) {
stream->read(unk, 16);
_actionId = stream->readUint16();
stream->read(unk, 5);
} else {
stream->read(unk, 16);
stream->read(unk, 16);
stream->read(unk, 10);
}
@ -193,34 +197,51 @@ void Frame::readChannels(Common::ReadStreamEndian *stream) {
for (int i = 0; i < CHANNEL_COUNT; i++) {
Sprite &sprite = *_sprites[i + 1];
sprite._scriptId = stream->readByte();
sprite._spriteType = stream->readByte();
sprite._enabled = sprite._spriteType != 0;
sprite._x2 = stream->readUint16();
if (_vm->getVersion() <= 4) {
sprite._scriptId = stream->readByte();
sprite._spriteType = stream->readByte();
sprite._enabled = sprite._spriteType != 0;
sprite._x2 = stream->readUint16();
sprite._flags = stream->readUint16();
sprite._ink = static_cast<InkType>(sprite._flags & 0x3f);
sprite._flags = stream->readUint16();
sprite._ink = static_cast<InkType>(sprite._flags & 0x3f);
if (sprite._flags & 0x40)
sprite._trails = 1;
else
sprite._trails = 0;
if (sprite._flags & 0x40)
sprite._trails = 1;
else
sprite._trails = 0;
sprite._lineSize = (sprite._flags >> 8) & 0x03;
sprite._lineSize = (sprite._flags >> 8) & 0x03;
sprite._castId = stream->readUint16();
sprite._startPoint.y = stream->readUint16();
sprite._startPoint.x = stream->readUint16();
sprite._height = stream->readUint16();
sprite._width = stream->readUint16();
sprite._castId = stream->readUint16();
sprite._startPoint.y = stream->readUint16();
sprite._startPoint.x = stream->readUint16();
sprite._height = stream->readUint16();
sprite._width = stream->readUint16();
if (_vm->getPlatform() == Common::kPlatformMacintosh && _vm->getVersion() >= 4) {
sprite._scriptId = stream->readUint16();
sprite._flags2 = stream->readByte(); // 0x40 editable, 0x80 moveable
sprite._unk2 = stream->readByte();
if (_vm->getPlatform() == Common::kPlatformMacintosh && _vm->getVersion() >= 4) {
sprite._scriptId = stream->readUint16();
sprite._flags2 = stream->readByte(); // 0x40 editable, 0x80 moveable
sprite._unk2 = stream->readByte();
if (_vm->getVersion() >= 5)
sprite._unk3 = stream->readUint32();
if (_vm->getVersion() >= 5)
sprite._unk3 = stream->readUint32();
}
} else {
stream->readUint16();
sprite._scriptId = stream->readByte();
sprite._spriteType = stream->readByte();
sprite._enabled = sprite._spriteType != 0;
sprite._castId = stream->readUint16();
stream->readUint32();
sprite._flags = stream->readUint16();
sprite._startPoint.y = stream->readUint16();
sprite._startPoint.x = stream->readUint16();
sprite._height = stream->readUint16();
sprite._width = stream->readUint16();
stream->readUint16();
stream->readUint16();
}
if (sprite._castId) {
@ -585,7 +606,7 @@ void Frame::renderSprites(Graphics::ManagedSurface &surface, bool renderTrail) {
// I don't like this implementation 100% as the 'cast' above might not actually hit a member and be null?
if (castType == kCastShape) {
renderShape(surface, i);
} else if (castType == kCastText) {
} else if (castType == kCastText || castType == kCastRTE) {
renderText(surface, i, NULL);
} else if (castType == kCastButton) {
renderButton(surface, i);

View File

@ -77,25 +77,31 @@ void DirectorEngine::loadEXE(const Common::String movie) {
_lingo->processEvent(kEventStart);
exeStream->seek(-4, SEEK_END);
exeStream->seek(exeStream->readUint32LE());
uint32 initialTag = exeStream->readUint32LE();
if (initialTag == MKTAG('R', 'I', 'F', 'X')) {
// we've encountered a movie saved from Director, not a projector.
loadEXERIFX(exeStream, 0);
} else {
exeStream->seek(-4, SEEK_END);
exeStream->seek(exeStream->readUint32LE());
switch (getVersion()) {
case 2:
case 3:
loadEXEv3(exeStream);
break;
case 4:
loadEXEv4(exeStream);
break;
case 5:
loadEXEv5(exeStream);
break;
case 7:
loadEXEv7(exeStream);
break;
default:
error("Unhandled Windows EXE version %d", getVersion());
switch (getVersion()) {
case 2:
case 3:
loadEXEv3(exeStream);
break;
case 4:
loadEXEv4(exeStream);
break;
case 5:
loadEXEv5(exeStream);
break;
case 7:
loadEXEv7(exeStream);
break;
default:
error("Unhandled Windows EXE version %d", getVersion());
}
}
}
@ -169,8 +175,10 @@ void DirectorEngine::loadEXEv4(Common::SeekableReadStream *stream) {
}
void DirectorEngine::loadEXEv5(Common::SeekableReadStream *stream) {
if (stream->readUint32LE() != MKTAG('P', 'J', '9', '5'))
error("Invalid projector tag found in v5 EXE");
uint32 ver = stream->readUint32LE();
if (ver != MKTAG('P', 'J', '9', '5'))
error("Invalid projector tag found in v5 EXE [%s]", tag2str(ver));
uint32 rifxOffset = stream->readUint32LE();
stream->readUint32LE(); // unknown
@ -248,13 +256,13 @@ void DirectorEngine::loadSharedCastsFrom(Common::String filename) {
_sharedSound = new Common::HashMap<int, Common::SeekableSubReadStreamEndian *>;
_sharedBMP = new Common::HashMap<int, Common::SeekableSubReadStreamEndian *>;
_sharedScore = new Score(this);
if (!shardcst->openFile(filename)) {
warning("No shared cast %s", filename.c_str());
return;
}
_sharedScore = new Score(this);
_sharedScore->setArchive(shardcst);
if (shardcst->hasResource(MKTAG('F', 'O', 'N', 'D'), -1)) {

View File

@ -321,6 +321,8 @@ void Score::loadPalette(Common::SeekableSubReadStreamEndian &stream) {
void Score::loadFrames(Common::SeekableSubReadStreamEndian &stream) {
debugC(1, kDebugLoading, "****** Loading frames");
//stream.hexdump(stream.size());
uint32 size = stream.readUint32();
size -= 4;
@ -337,25 +339,35 @@ void Score::loadFrames(Common::SeekableSubReadStreamEndian &stream) {
// Unknown, some bytes - constant (refer to contuinity).
} else if (_vm->getVersion() > 4) {
//what data is up the top of D5 VWSC?
stream.readUint32();
stream.readUint32();
uint32 blockSize = stream.readUint32() - 1;
stream.readUint32();
stream.readUint32();
stream.readUint32();
stream.readUint32();
for (uint32 skip = 0; skip < blockSize * 4; skip++)
stream.readByte();
//header number two... this is our actual score entry point.
uint32 unk1 = stream.readUint32();
uint32 unk2 = stream.readUint32();
stream.readUint32();
uint16 unk3 = stream.readUint16();
uint16 unk4 = stream.readUint16();
uint16 unk5 = stream.readUint16();
uint16 unk6 = stream.readUint16();
uint16 unk3, unk4, unk5, unk6;
if (unk2 > 0) {
uint32 blockSize = stream.readUint32() - 1;
stream.readUint32();
stream.readUint32();
stream.readUint32();
stream.readUint32();
for (uint32 skip = 0; skip < blockSize * 4; skip++)
stream.readByte();
//header number two... this is our actual score entry point.
unk1 = stream.readUint32();
unk2 = stream.readUint32();
stream.readUint32();
unk3 = stream.readUint16();
unk4 = stream.readUint16();
unk5 = stream.readUint16();
unk6 = stream.readUint16();
} else {
unk3 = stream.readUint16();
unk4 = stream.readUint16();
unk5 = stream.readUint16();
unk6 = stream.readUint16();
size -= 16;
}
warning("STUB: Score::loadFrames. unk1: %x unk2: %x unk3: %x unk4: %x unk5: %x unk6: %x", unk1, unk2, unk3, unk4, unk5, unk6);
}
@ -482,13 +494,13 @@ void Score::setSpriteCasts() {
for (uint16 j = 0; j < _frames[i]->_sprites.size(); j++) {
uint16 castId = _frames[i]->_sprites[j]->_castId;
if (_vm->getSharedScore()->_loadedBitmaps->contains(castId)) {
if (_vm->getSharedScore() != nullptr && _vm->getSharedScore()->_loadedBitmaps->contains(castId)) {
_frames[i]->_sprites[j]->_bitmapCast = _vm->getSharedScore()->_loadedBitmaps->getVal(castId);
} else if (_loadedBitmaps->contains(castId)) {
_frames[i]->_sprites[j]->_bitmapCast = _loadedBitmaps->getVal(castId);
}
if (_vm->getSharedScore()->_loadedButtons->contains(castId)) {
if (_vm->getSharedScore() != nullptr && _vm->getSharedScore()->_loadedButtons->contains(castId)) {
_frames[i]->_sprites[j]->_buttonCast = _vm->getSharedScore()->_loadedButtons->getVal(castId);
if (_frames[i]->_sprites[j]->_buttonCast->children.size() == 1) {
_frames[i]->_sprites[j]->_textCast =
@ -503,13 +515,13 @@ void Score::setSpriteCasts() {
//if (_loadedScripts->contains(castId))
// _frames[i]->_sprites[j]->_bitmapCast = _loadedBitmaps->getVal(castId);
if (_vm->getSharedScore()->_loadedText->contains(castId)) {
if (_vm->getSharedScore() != nullptr && _vm->getSharedScore()->_loadedText->contains(castId)) {
_frames[i]->_sprites[j]->_textCast = _vm->getSharedScore()->_loadedText->getVal(castId);
} else if (_loadedText->contains(castId)) {
_frames[i]->_sprites[j]->_textCast = _loadedText->getVal(castId);
}
if (_vm->getSharedScore()->_loadedShapes->contains(castId)) {
if (_vm->getSharedScore() != nullptr && _vm->getSharedScore()->_loadedShapes->contains(castId)) {
_frames[i]->_sprites[j]->_shapeCast = _vm->getSharedScore()->_loadedShapes->getVal(castId);
} else if (_loadedShapes->contains(castId)) {
_frames[i]->_sprites[j]->_shapeCast = _loadedShapes->getVal(castId);
@ -608,6 +620,22 @@ void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id,
_loadedScripts->setVal(id, new ScriptCast(castStream, _vm->getVersion()));
_castTypes[id] = kCastLingoScript;
break;
case kCastRTE:
//TODO: Actually load RTEs correctly, don't just make fake STXT.
_castTypes[id] = kCastRTE;
_loadedText->setVal(id, new TextCast(castStream, _vm->getVersion()));
for (uint child = 0; child < res->children.size(); child++) {
_loadedText->getVal(id)->children.push_back(res->children[child]);
if (child == 1) {
Common::SeekableReadStream *rte1 = _movieArchive->getResource(res->children[child].tag, res->children[child].index);
byte *buffer = new byte[rte1->size() + 2];
rte1->read(buffer, rte1->size());
buffer[rte1->size()] = '\n';
buffer[rte1->size() + 1] = '\0';
_loadedText->getVal(id)->importRTE(buffer);
}
}
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.