diff options
Diffstat (limited to 'engines/director')
-rw-r--r-- | engines/director/archive.cpp | 5 | ||||
-rw-r--r-- | engines/director/cast.cpp | 30 | ||||
-rw-r--r-- | engines/director/cast.h | 4 | ||||
-rw-r--r-- | engines/director/frame.cpp | 67 | ||||
-rw-r--r-- | engines/director/resource.cpp | 52 | ||||
-rw-r--r-- | engines/director/score.cpp | 68 |
6 files changed, 159 insertions, 67 deletions
diff --git a/engines/director/archive.cpp b/engines/director/archive.cpp index 09be707129..31b421566c 100644 --- a/engines/director/archive.cpp +++ b/engines/director/archive.cpp @@ -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; } diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp index 0ee5a8f15c..564460b640 100644 --- a/engines/director/cast.cpp +++ b/engines/director/cast.cpp @@ -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(); diff --git a/engines/director/cast.h b/engines/director/cast.h index 7df9d94a59..96d7e82399 100644 --- a/engines/director/cast.h +++ b/engines/director/cast.h @@ -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; }; diff --git a/engines/director/frame.cpp b/engines/director/frame.cpp index cecc46dc65..1b3b59e1ef 100644 --- a/engines/director/frame.cpp +++ b/engines/director/frame.cpp @@ -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); diff --git a/engines/director/resource.cpp b/engines/director/resource.cpp index 5e1d79cf24..e748583146 100644 --- a/engines/director/resource.cpp +++ b/engines/director/resource.cpp @@ -77,25 +77,31 @@ void DirectorEngine::loadEXE(const Common::String movie) { _lingo->processEvent(kEventStart); - 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()); + 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()); + } } } @@ -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)) { diff --git a/engines/director/score.cpp b/engines/director/score.cpp index 64a44793a7..350fccb176 100644 --- a/engines/director/score.cpp +++ b/engines/director/score.cpp @@ -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. |