aboutsummaryrefslogtreecommitdiff
path: root/engines/director
diff options
context:
space:
mode:
Diffstat (limited to 'engines/director')
-rw-r--r--engines/director/archive.cpp5
-rw-r--r--engines/director/cast.cpp30
-rw-r--r--engines/director/cast.h4
-rw-r--r--engines/director/frame.cpp67
-rw-r--r--engines/director/resource.cpp52
-rw-r--r--engines/director/score.cpp68
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.