aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/director/archive.cpp49
-rw-r--r--engines/director/archive.h16
-rw-r--r--engines/director/cast.cpp20
-rw-r--r--engines/director/cast.h2
-rw-r--r--engines/director/director.h1
-rw-r--r--engines/director/resource.cpp2
-rw-r--r--engines/director/score.cpp53
-rw-r--r--engines/director/score.h3
8 files changed, 120 insertions, 26 deletions
diff --git a/engines/director/archive.cpp b/engines/director/archive.cpp
index 5b1a26ffd4..398b287b90 100644
--- a/engines/director/archive.cpp
+++ b/engines/director/archive.cpp
@@ -100,6 +100,18 @@ Common::SeekableSubReadStreamEndian *Archive::getResource(uint32 tag, uint16 id)
return new Common::SeekableSubReadStreamEndian(_stream, res.offset, res.offset + res.size, _isBigEndian, DisposeAfterUse::NO);
}
+Resource Archive::getResourceDetail(uint32 tag, uint16 id) {
+ if (!_types.contains(tag))
+ error("Archive does not contain '%s' %04x", tag2str(tag), id);
+
+ const ResourceMap &resMap = _types[tag];
+
+ if (!resMap.contains(id))
+ error("Archive does not contain '%s' %04x", tag2str(tag), id);
+
+ return resMap[id];
+}
+
uint32 Archive::getOffset(uint32 tag, uint16 id) const {
if (!_types.contains(tag))
error("Archive does not contain '%s' %04x", tag2str(tag), id);
@@ -365,6 +377,7 @@ bool RIFXArchive::openStream(Common::SeekableReadStream *stream, uint32 startOff
subStream.readUint32(); // unknown
Common::Array<Resource> resources;
+ resources.reserve(2048);
// Need to look for these two resources
const Resource *keyRes = 0;
@@ -395,6 +408,8 @@ bool RIFXArchive::openStream(Common::SeekableReadStream *stream, uint32 startOff
keyRes = &resources[resources.size() - 1];
else if (tag == MKTAG('C', 'A', 'S', '*'))
casRes = &resources[resources.size() - 1];
+ else
+ _types[tag][i] = res;
}
// We need to have found the 'File' resource already
@@ -409,6 +424,8 @@ bool RIFXArchive::openStream(Common::SeekableReadStream *stream, uint32 startOff
return false;
}
+ uint castTag = MKTAG('C', 'A', 'S', 't');
+
// Parse the CAS*, if present
if (casRes) {
Common::SeekableSubReadStreamEndian casStream(stream, casRes->offset + 8, casRes->offset + 8 + casRes->size, _isBigEndian, DisposeAfterUse::NO);
@@ -420,8 +437,10 @@ bool RIFXArchive::openStream(Common::SeekableReadStream *stream, uint32 startOff
for (uint i = 0; i < casSize; i++) {
uint32 index = casStream.readUint32();
- const Resource &res = resources[index];
- _types[MKTAG('C', 'A', 'S', 't')][i + 1] = res;
+ Resource &res = resources[index];
+ res.index = index;
+ res.castId = i + 1;
+ _types[castTag][res.castId] = res;
debugCN(2, kDebugLoading, "%d ", index);
}
@@ -444,10 +463,20 @@ bool RIFXArchive::openStream(Common::SeekableReadStream *stream, uint32 startOff
debugC(2, kDebugLoading, "KEY*: index: %d id: %d resTag: %s", index, id, tag2str(resTag));
- const Resource &res = resources[index];
+ Resource &res = resources[index];
debug(3, "Found RIFX resource: '%s' id: 0x%04x, %d @ 0x%08x (%d)", tag2str(resTag), id, res.size, res.offset, res.offset);
_types[resTag][id] = res;
- _types[resTag][1024 + i + 1] = res;
+ //_types[resTag][1024 + i + 1] = res;
+
+ if (id < 1024) {
+ for (uint cast = 0; cast < _types[castTag].size(); cast++) {
+ if (_types[castTag][cast].index == id) {
+ res.index = index;
+ _types[castTag][cast].children.push_back(res);
+ break;
+ }
+ }
+ }
}
_stream = stream;
@@ -471,5 +500,17 @@ Common::SeekableSubReadStreamEndian *RIFXArchive::getResource(uint32 tag, uint16
return new Common::SeekableSubReadStreamEndian(_stream, offset, offset + size, true, DisposeAfterUse::NO);
}
+Resource RIFXArchive::getResourceDetail(uint32 tag, uint16 id) {
+ if (!_types.contains(tag))
+ error("Archive does not contain '%s' %04x", tag2str(tag), id);
+
+ const ResourceMap &resMap = _types[tag];
+
+ if (!resMap.contains(id))
+ error("Archive does not contain '%s' %04x", tag2str(tag), id);
+
+ return resMap[id];
+}
+
} // End of namespace Director
diff --git a/engines/director/archive.h b/engines/director/archive.h
index 93f4ce7ee9..b77bace9ba 100644
--- a/engines/director/archive.h
+++ b/engines/director/archive.h
@@ -33,6 +33,15 @@ class MacResManager;
namespace Director {
// Completely ripped off of Mohawk's Archive code
+
+struct Resource {
+ uint32 index;
+ uint32 offset;
+ uint32 size;
+ uint32 castId;
+ Common::String name;
+ Common::Array<Resource> children;
+};
class Archive {
public:
@@ -50,6 +59,7 @@ public:
bool hasResource(uint32 tag, uint16 id) const;
bool hasResource(uint32 tag, const Common::String &resName) const;
virtual Common::SeekableSubReadStreamEndian *getResource(uint32 tag, uint16 id);
+ virtual Resource getResourceDetail(uint32 tag, uint16 id);
uint32 getOffset(uint32 tag, uint16 id) const;
uint16 findResourceID(uint32 tag, const Common::String &resName) const;
Common::String getName(uint32 tag, uint16 id) const;
@@ -61,11 +71,6 @@ public:
protected:
Common::SeekableReadStream *_stream;
- struct Resource {
- uint32 offset;
- uint32 size;
- Common::String name;
- };
typedef Common::HashMap<uint16, Resource> ResourceMap;
typedef Common::HashMap<uint32, ResourceMap> TypeMap;
TypeMap _types;
@@ -103,6 +108,7 @@ public:
bool openStream(Common::SeekableReadStream *stream, uint32 startOffset = 0);
Common::SeekableSubReadStreamEndian *getResource(uint32 tag, uint16 id);
+ Resource getResourceDetail(uint32 tag, uint16 id);
};
} // End of namespace Director
diff --git a/engines/director/cast.cpp b/engines/director/cast.cpp
index 892ac48f8c..81637b9684 100644
--- a/engines/director/cast.cpp
+++ b/engines/director/cast.cpp
@@ -41,6 +41,9 @@ BitmapCast::BitmapCast(Common::ReadStreamEndian &stream, uint16 version) {
unk2 = stream.readUint16();
}
} else {
+ stream.readByte();
+ stream.readByte();
+
initialRect = Score::readRect(stream);
boundingRect = Score::readRect(stream);
regX = stream.readUint16();
@@ -59,8 +62,10 @@ BitmapCast::BitmapCast(Common::ReadStreamEndian &stream, uint16 version) {
}
TextCast::TextCast(Common::ReadStreamEndian &stream, uint16 version) {
- if (version < 4) {
- flags1 = stream.readByte();
+ if (version < 5) {
+ if (version <= 3)
+ flags1 = stream.readByte();
+
borderSize = static_cast<SizeType>(stream.readByte());
gutterSize = static_cast<SizeType>(stream.readByte());
boxShadow = static_cast<SizeType>(stream.readByte());
@@ -109,6 +114,9 @@ ShapeCast::ShapeCast(Common::ReadStreamEndian &stream, uint16 version) {
lineThickness = stream.readByte();
lineDirection = stream.readByte();
} else {
+ stream.readByte();
+ stream.readByte();
+
initialRect = Score::readRect(stream);
boundingRect = Score::readRect(stream);
}
@@ -119,8 +127,13 @@ ButtonCast::ButtonCast(Common::ReadStreamEndian &stream, uint16 version) : TextC
if (version < 4) {
buttonType = static_cast<ButtonType>(stream.readUint16BE());
} else {
+ stream.readByte();
+ stream.readByte();
+
initialRect = Score::readRect(stream);
boundingRect = Score::readRect(stream);
+
+ buttonType = static_cast<ButtonType>(stream.readUint16BE());
}
modified = 0;
}
@@ -129,6 +142,9 @@ ScriptCast::ScriptCast(Common::ReadStreamEndian &stream, uint16 version) {
if (version < 4) {
error("Unhandled Script cast");
} else {
+ stream.readByte();
+ stream.readByte();
+
initialRect = Score::readRect(stream);
boundingRect = Score::readRect(stream);
diff --git a/engines/director/cast.h b/engines/director/cast.h
index 69edf8ce89..a739ccc25d 100644
--- a/engines/director/cast.h
+++ b/engines/director/cast.h
@@ -25,6 +25,7 @@
#include "common/rect.h"
#include "common/substream.h"
+#include "director/archive.h"
namespace Director {
@@ -46,6 +47,7 @@ struct Cast {
CastType type;
Common::Rect initialRect;
Common::Rect boundingRect;
+ Common::Array<Resource> children;
byte modified;
};
diff --git a/engines/director/director.h b/engines/director/director.h
index 7ec9608662..ead143758e 100644
--- a/engines/director/director.h
+++ b/engines/director/director.h
@@ -73,6 +73,7 @@ public:
Common::Language getLanguage() const;
Common::String getEXEName() const;
DirectorSound *getSoundManager() const { return _soundManager; }
+ Graphics::MacWindowManager *getMacWindowManager() const { return _wm; }
Archive *getMainArchive() const { return _mainArchive; }
Lingo *getLingo() const { return _lingo; }
Score *getCurrentScore() const { return _currentScore; }
diff --git a/engines/director/resource.cpp b/engines/director/resource.cpp
index 2f8ef3e432..711ce0474d 100644
--- a/engines/director/resource.cpp
+++ b/engines/director/resource.cpp
@@ -217,7 +217,7 @@ void DirectorEngine::loadSharedCastsFrom(Common::String filename) {
Common::Array<uint16> cast = shardcst->getResourceIDList(MKTAG('C','A','S','t'));
if (cast.size() > 0) {
for (Common::Array<uint16>::iterator iterator = cast.begin(); iterator != cast.end(); ++iterator)
- castScore->loadCastData(*shardcst->getResource(MKTAG('C','A','S','t'), *iterator), *iterator);
+ castScore->loadCastData(*shardcst->getResource(MKTAG('C','A','S','t'), *iterator), *iterator, NULL);
}
castScore->setSpriteCasts();
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 8a80e30765..b3aee97fd8 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -216,16 +216,19 @@ void Score::loadArchive() {
Common::Array<uint16> cast = _movieArchive->getResourceIDList(MKTAG('C','A','S','t'));
if (cast.size() > 0) {
- for (Common::Array<uint16>::iterator iterator = cast.begin(); iterator != cast.end(); ++iterator)
- loadCastData(*_movieArchive->getResource(MKTAG('C','A','S','t'), *iterator), *iterator);
+ for (Common::Array<uint16>::iterator iterator = cast.begin(); iterator != cast.end(); ++iterator) {
+ Common::SeekableSubReadStreamEndian *stream = _movieArchive->getResource(MKTAG('C', 'A', 'S', 't'), *iterator);
+ Resource res = _movieArchive->getResourceDetail(MKTAG('C', 'A', 'S', 't'), *iterator);
+ loadCastData(*stream, *iterator, &res);
+ }
}
setSpriteCasts();
- Common::Array<uint16> stxt = _movieArchive->getResourceIDList(MKTAG('S','T','X','T'));
- if (stxt.size() > 0) {
- loadScriptText(*_movieArchive->getResource(MKTAG('S','T','X','T'), *stxt.begin()));
- }
+ //Common::Array<uint16> stxt = _movieArchive->getResourceIDList(MKTAG('S','T','X','T'));
+ //if (stxt.size() > 0) {
+ // loadScriptText(*_movieArchive->getResource(MKTAG('S','T','X','T'), *stxt.begin()));
+ //}
}
Score::~Score() {
@@ -397,7 +400,7 @@ void Score::setSpriteCasts() {
}
}
-void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id) {
+void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id, Resource *res) {
// d4+ variant
if (stream.size() == 0)
return;
@@ -415,7 +418,7 @@ void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id)
uint32 size1, size2, size3, castType;
byte unk1 = 0, unk2 = 0, unk3 = 0;
- if (_vm->getVersion() < 5) {
+ if (_vm->getVersion() < 4) {
size1 = stream.readUint16();
size2 = stream.readUint32();
size3 = 0;
@@ -423,6 +426,12 @@ void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id)
unk1 = stream.readByte();
unk2 = stream.readByte();
unk3 = stream.readByte();
+ } else if (_vm->getVersion() < 5) {
+ size1 = stream.readUint16() + 2;
+ size2 = stream.readUint32();
+ size3 = 0;
+ castType = stream.readByte();
+ unk1 = stream.readByte();
} else {
// FIXME: only the cast type and the strings are good
castType = stream.readUint32();
@@ -436,7 +445,7 @@ 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 + 16, 1); // 16 is for bounding rects
stream.read(data, size1 + 16);
Common::MemoryReadStreamEndian castStream(data, size1 + 16, stream.isBE());
@@ -469,6 +478,9 @@ void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id)
_casts[id]->type = kCastButton;
break;
case kCastScript:
+ warning("CASt: Script");
+ Common::hexdump(data, size1 + 16);
+
_casts[id] = new ScriptCast(castStream, _vm->getVersion());
_casts[id]->type = kCastScript;
break;
@@ -477,6 +489,11 @@ void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id)
break;
}
+ if (res != NULL) {
+ for (uint child = 0; child < res->children.size(); child++)
+ _casts[id]->children.push_back(res->children[child]);
+ }
+
free(data);
if (size2) {
@@ -500,6 +517,11 @@ void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id)
ci->fileName = castStrings[3];
ci->type = castStrings[4];
+ if (!ci->script.empty()) {
+ //the script type here could be wrong!
+ _lingo->addCode(ci->script.c_str(), _casts[id]->type == kCastScript ? kFrameScript : kSpriteScript, id);
+ }
+
_castsInfo[id] = ci;
}
@@ -802,7 +824,7 @@ Common::Array<Common::String> Score::loadStrings(Common::SeekableSubReadStreamEn
byte *data = (byte *)malloc(entries[count - 1]);
stream.read(data, entries[count - 1]);
- for (uint i = 0; i < count - 1; i++) {
+ for (uint16 i = 0; i < count - 1; i++) {
Common::String entryString;
for (uint j = entries[i]; j < entries[i + 1]; j++)
@@ -821,6 +843,9 @@ Common::Array<Common::String> Score::loadStrings(Common::SeekableSubReadStreamEn
}
void Score::loadFontMap(Common::SeekableSubReadStreamEndian &stream) {
+ if (stream.size() == 0)
+ return;
+
uint16 count = stream.readUint16();
uint32 offset = (count * 2) + 2;
uint16 currentRawPosition = offset;
@@ -908,9 +933,11 @@ void Score::update() {
_currentFrame++;
Common::SortedArray<Label *>::iterator i;
- for (i = _labels->begin(); i != _labels->end(); ++i) {
- if ((*i)->number == _currentFrame) {
- _currentLabel = (*i)->name;
+ if (_labels != NULL) {
+ for (i = _labels->begin(); i != _labels->end(); ++i) {
+ if ((*i)->number == _currentFrame) {
+ _currentLabel = (*i)->name;
+ }
}
}
diff --git a/engines/director/score.h b/engines/director/score.h
index 49e4f357b0..b665842bb0 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -25,6 +25,7 @@
#include "common/substream.h"
#include "common/rect.h"
+#include "director/archive.h"
namespace Graphics {
class ManagedSurface;
@@ -67,7 +68,7 @@ public:
Archive *getArchive() const { return _movieArchive; };
void loadConfig(Common::SeekableSubReadStreamEndian &stream);
void loadCastDataVWCR(Common::SeekableSubReadStreamEndian &stream);
- void loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id);
+ void loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id, Resource *res);
void setCurrentFrame(uint16 frameId) { _currentFrame = frameId; }
int getCurrentFrame() { return _currentFrame; }
Common::String getMacName() const { return _macName; }