aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Sandulenko2017-01-09 00:54:27 +0100
committerGitHub2017-01-09 00:54:27 +0100
commit2e64b2202da4833fd4c2d5040599a8a3b7460dc5 (patch)
tree66f2dee3ea886771e4159be756ee73b3381a4ae1
parent4dc6aa2d93a3e166891713549d73c4e40fe9f4f2 (diff)
parent41ee83e3f02144da364b98b8f5b974087e6dac89 (diff)
downloadscummvm-rg350-2e64b2202da4833fd4c2d5040599a8a3b7460dc5.tar.gz
scummvm-rg350-2e64b2202da4833fd4c2d5040599a8a3b7460dc5.tar.bz2
scummvm-rg350-2e64b2202da4833fd4c2d5040599a8a3b7460dc5.zip
Merge pull request #887 from stevenhoefel/master
DIRECTOR: Support for D4 cast and images
-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/frame.cpp360
-rw-r--r--engines/director/frame.h8
-rw-r--r--engines/director/images.cpp118
-rw-r--r--engines/director/images.h19
-rw-r--r--engines/director/lingo/lingo-builtins.cpp4
-rw-r--r--engines/director/lingo/lingo-funcs.cpp35
-rw-r--r--engines/director/lingo/lingo.h4
-rw-r--r--engines/director/resource.cpp2
-rw-r--r--engines/director/score.cpp53
-rw-r--r--engines/director/score.h3
-rw-r--r--engines/director/sound.cpp10
-rw-r--r--engines/director/sound.h4
-rw-r--r--engines/director/sprite.h3
-rw-r--r--graphics/macgui/macwindowmanager.cpp70
-rw-r--r--graphics/macgui/macwindowmanager.h4
20 files changed, 625 insertions, 160 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/frame.cpp b/engines/director/frame.cpp
index de0de6d4d0..7c52cf8ba7 100644
--- a/engines/director/frame.cpp
+++ b/engines/director/frame.cpp
@@ -114,54 +114,61 @@ void Frame::readChannel(Common::SeekableSubReadStreamEndian &stream, uint16 offs
}
void Frame::readChannels(Common::ReadStreamEndian *stream) {
- _actionId = stream->readByte();
- _soundType1 = stream->readByte(); // type: 0x17 for sounds (sound is cast id), 0x16 for MIDI (sound is cmd id)
- uint8 transFlags = stream->readByte(); // 0x80 is whole stage (vs changed area), rest is duration in 1/4ths of a second
-
- if (transFlags & 0x80)
- _transArea = 1;
- else
- _transArea = 0;
- _transDuration = transFlags & 0x7f;
-
- _transChunkSize = stream->readByte();
- _tempo = stream->readByte();
- _transType = static_cast<TransitionType>(stream->readByte());
- _sound1 = stream->readUint16();
- if (_vm->getPlatform() == Common::kPlatformMacintosh) {
- _sound2 = stream->readUint16();
- _soundType2 = stream->readByte();
- } else {
- byte unk[3];
- stream->read(unk, 3);
- warning("unk1: %x unk2: %x unk3: %x", unk[0], unk[1], unk[2]);
- }
- _skipFrameFlag = stream->readByte();
- _blend = stream->readByte();
+ byte unk[16];
- if (_vm->getPlatform() != Common::kPlatformMacintosh) {
- _sound2 = stream->readUint16();
- _soundType2 = stream->readByte();
- }
+ if (_vm->getVersion() < 4) {
+ _actionId = stream->readByte();
+ _soundType1 = stream->readByte(); // type: 0x17 for sounds (sound is cast id), 0x16 for MIDI (sound is cmd id)
+ uint8 transFlags = stream->readByte(); // 0x80 is whole stage (vs changed area), rest is duration in 1/4ths of a second
- uint16 palette = stream->readUint16();
+ if (transFlags & 0x80)
+ _transArea = 1;
+ else
+ _transArea = 0;
+ _transDuration = transFlags & 0x7f;
+
+ _transChunkSize = stream->readByte();
+ _tempo = stream->readByte();
+ _transType = static_cast<TransitionType>(stream->readByte());
+ _sound1 = stream->readUint16();
+ if (_vm->getPlatform() == Common::kPlatformMacintosh) {
+ _sound2 = stream->readUint16();
+ _soundType2 = stream->readByte();
+ } else {
+ stream->read(unk, 3);
+ warning("unk1: %x unk2: %x unk3: %x", unk[0], unk[1], unk[2]);
+ }
+ _skipFrameFlag = stream->readByte();
+ _blend = stream->readByte();
- if (palette) {
- warning("STUB: Palette info");
- }
+ if (_vm->getPlatform() != Common::kPlatformMacintosh) {
+ _sound2 = stream->readUint16();
+ _soundType2 = stream->readByte();
+ }
- debugC(kDebugLoading, 8, "%d %d %d %d %d %d %d %d %d %d %d", _actionId, _soundType1, _transDuration, _transChunkSize, _tempo, _transType, _sound1, _skipFrameFlag, _blend, _sound2, _soundType2);
+ uint16 palette = stream->readUint16();
- _palette = new PaletteInfo();
- _palette->firstColor = stream->readByte(); // for cycles. note: these start at 0x80 (for pal entry 0)!
- _palette->lastColor = stream->readByte();
- _palette->flags = stream->readByte();
- _palette->speed = stream->readByte();
- _palette->frameCount = stream->readUint16();
+ if (palette) {
+ warning("STUB: Palette info");
+ }
+
+ debugC(kDebugLoading, 8, "%d %d %d %d %d %d %d %d %d %d %d", _actionId, _soundType1, _transDuration, _transChunkSize, _tempo, _transType, _sound1, _skipFrameFlag, _blend, _sound2, _soundType2);
+
+ _palette = new PaletteInfo();
+ _palette->firstColor = stream->readByte(); // for cycles. note: these start at 0x80 (for pal entry 0)!
+ _palette->lastColor = stream->readByte();
+ _palette->flags = stream->readByte();
+ _palette->speed = stream->readByte();
+ _palette->frameCount = stream->readUint16();
+
+ _palette->cycleCount = stream->readUint16();
+ } else if (_vm->getVersion() < 5) {
+ stream->read(unk, 16);
+ _actionId = stream->readUint16();
+ stream->read(unk, 5);
+ }
- _palette->cycleCount = stream->readUint16();
- byte unk[11];
stream->read(unk, 6);
if (_vm->getPlatform() == Common::kPlatformMacintosh) {
@@ -181,8 +188,9 @@ void Frame::readChannels(Common::ReadStreamEndian *stream) {
for (int i = 0; i < CHANNEL_COUNT; i++) {
Sprite &sprite = *_sprites[i + 1];
- sprite._x1 = stream->readByte();
- sprite._enabled = (stream->readByte() != 0);
+ sprite._scriptId = stream->readByte();
+ sprite._spriteType = stream->readByte();
+ sprite._enabled = sprite._spriteType != 0;
sprite._x2 = stream->readUint16();
sprite._flags = stream->readUint16();
@@ -199,8 +207,6 @@ void Frame::readChannels(Common::ReadStreamEndian *stream) {
sprite._height = stream->readUint16();
sprite._width = stream->readUint16();
- debugC(kDebugLoading, 8, "%03d(%d)[%x,%x,%04x,%d/%d/%d/%d]", sprite._castId, sprite._enabled, sprite._x1, sprite._x2, sprite._flags, sprite._startPoint.x, sprite._startPoint.y, sprite._width, sprite._height);
-
if (_vm->getPlatform() == Common::kPlatformMacintosh && _vm->getVersion() >= 4) {
sprite._scriptId = stream->readUint16();
sprite._flags2 = stream->readByte(); // 0x40 editable, 0x80 moveable
@@ -209,6 +215,10 @@ void Frame::readChannels(Common::ReadStreamEndian *stream) {
if (_vm->getVersion() >= 5)
sprite._unk3 = stream->readUint32();
}
+
+ debugC(kDebugLoading, 8, "%03d(%d)[%x,%x,%04x,%d/%d/%d/%d] script:%d",
+ sprite._castId, sprite._enabled, sprite._x1, sprite._x2, sprite._flags,
+ sprite._startPoint.x, sprite._startPoint.y, sprite._width, sprite._height, sprite._scriptId);
}
}
@@ -360,6 +370,7 @@ void Frame::readSprite(Common::SeekableSubReadStreamEndian &stream, uint16 offse
}
void Frame::prepareFrame(Score *score) {
+ _drawRects.clear();
renderSprites(*score->_surface, false);
renderSprites(*score->_trailSurface, true);
@@ -529,82 +540,144 @@ void Frame::renderSprites(Graphics::ManagedSurface &surface, bool renderTrail) {
if ((_sprites[i]->_trails == 0 && renderTrail) || (_sprites[i]->_trails == 1 && !renderTrail))
continue;
+ CastType castType;
Cast *cast;
- if (!_vm->_currentScore->_casts.contains(_sprites[i]->_castId)) {
- if (!_vm->getSharedCasts()->contains(_sprites[i]->_castId)) {
- warning("Cast id %d not found", _sprites[i]->_castId);
- continue;
- } else {
- warning("Getting cast id %d from shared cast", _sprites[i]->_castId);
- cast = _vm->getSharedCasts()->getVal(_sprites[i]->_castId);
+ if (_vm->getVersion() < 4) {
+ switch (_sprites[i]->_spriteType) {
+ case 0x01:
+ case 0x0c: //this is actually a mouse-over shape? I don't think it's a real button.
+ castType = kCastBitmap;
+ break;
+ case 0x02:
+ castType = kCastShape;
+ break;
+ case 0x07:
+ castType = kCastText;
+ break;
}
} else {
- cast = _vm->_currentScore->_casts[_sprites[i]->_castId];
- }
-
- if (cast->type == kCastText) {
- renderText(surface, i);
- continue;
+ if (!_vm->_currentScore->_casts.contains(_sprites[i]->_castId)) {
+ if (!_vm->getSharedCasts()->contains(_sprites[i]->_castId)) {
+ warning("Cast id %d not found", _sprites[i]->_castId);
+ continue;
+ } else {
+ warning("Getting cast id %d from shared cast", _sprites[i]->_castId);
+ cast = _vm->getSharedCasts()->getVal(_sprites[i]->_castId);
+ }
+ } else {
+ cast = _vm->_currentScore->_casts[_sprites[i]->_castId];
+ }
+ castType = cast->type;
}
- Image::ImageDecoder *img = getImageFrom(_sprites[i]->_castId);
+ //this needs precedence to be hit first... D3 does something really tricky with cast IDs for shapes.
+ //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) {
+ renderText(surface, i, _vm->getVersion() < 4 ? _sprites[i]->_castId + 1024 : cast->children[0].index);
+ } else if (castType == kCastButton) {
+ renderButton(surface, i, _vm->getVersion() < 4 ? _sprites[i]->_castId + 1024 : cast->children[0].index);
+ } else {
+ Image::ImageDecoder *img = getImageFrom(_sprites[i]->_castId);
- if (!img) {
- warning("Image with id %d not found", _sprites[i]->_castId);
- continue;
- }
+ if (!img) {
+ warning("Image with id %d not found", _sprites[i]->_castId);
+ continue;
+ }
- if (!img->getSurface()) {
- warning("Frame::renderSprites: Could not load image %d", _sprites[i]->_castId);
- continue;
- }
+ if (!img->getSurface()) {
+ warning("Frame::renderSprites: Could not load image %d", _sprites[i]->_castId);
+ continue;
+ }
- assert(_sprites[i]->_cast);
-
- uint32 regX = static_cast<BitmapCast *>(_sprites[i]->_cast)->regX;
- uint32 regY = static_cast<BitmapCast *>(_sprites[i]->_cast)->regY;
- uint32 rectLeft = static_cast<BitmapCast *>(_sprites[i]->_cast)->initialRect.left;
- uint32 rectTop = static_cast<BitmapCast *>(_sprites[i]->_cast)->initialRect.top;
-
- 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;
-
- Common::Rect drawRect = Common::Rect(x, y, x + width, y + height);
- _drawRects.push_back(drawRect);
-
- switch (_sprites[i]->_ink) {
- case kInkTypeCopy:
- surface.blitFrom(*img->getSurface(), Common::Point(x, y));
- break;
- case kInkTypeTransparent:
- // FIXME: is it always white (last entry in pallette)?
- surface.transBlitFrom(*img->getSurface(), Common::Point(x, y), _vm->getPaletteColorCount() - 1);
- break;
- case kInkTypeBackgndTrans:
- drawBackgndTransSprite(surface, *img->getSurface(), drawRect);
- break;
- case kInkTypeMatte:
- drawMatteSprite(surface, *img->getSurface(), drawRect);
- break;
- case kInkTypeGhost:
- drawGhostSprite(surface, *img->getSurface(), drawRect);
- break;
- case kInkTypeReverse:
- drawReverseSprite(surface, *img->getSurface(), drawRect);
- break;
- default:
- warning("Unhandled ink type %d", _sprites[i]->_ink);
- surface.blitFrom(*img->getSurface(), Common::Point(x, y));
- break;
+ assert(_sprites[i]->_cast);
+
+ uint32 regX = static_cast<BitmapCast *>(_sprites[i]->_cast)->regX;
+ uint32 regY = static_cast<BitmapCast *>(_sprites[i]->_cast)->regY;
+ uint32 rectLeft = static_cast<BitmapCast *>(_sprites[i]->_cast)->initialRect.left;
+ uint32 rectTop = static_cast<BitmapCast *>(_sprites[i]->_cast)->initialRect.top;
+
+ 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;
+
+ Common::Rect drawRect = Common::Rect(x, y, x + width, y + height);
+ _drawRects[i] = drawRect;
+
+ switch (_sprites[i]->_ink) {
+ case kInkTypeCopy:
+ surface.blitFrom(*img->getSurface(), Common::Point(x, y));
+ break;
+ case kInkTypeTransparent:
+ // FIXME: is it always white (last entry in pallette)?
+ surface.transBlitFrom(*img->getSurface(), Common::Point(x, y), _vm->getPaletteColorCount() - 1);
+ break;
+ case kInkTypeBackgndTrans:
+ drawBackgndTransSprite(surface, *img->getSurface(), drawRect);
+ break;
+ case kInkTypeMatte:
+ drawMatteSprite(surface, *img->getSurface(), drawRect);
+ break;
+ case kInkTypeGhost:
+ drawGhostSprite(surface, *img->getSurface(), drawRect);
+ break;
+ case kInkTypeReverse:
+ drawReverseSprite(surface, *img->getSurface(), drawRect);
+ break;
+ default:
+ warning("Unhandled ink type %d", _sprites[i]->_ink);
+ surface.blitFrom(*img->getSurface(), Common::Point(x, y));
+ break;
+ }
}
}
}
}
-void Frame::renderButton(Graphics::ManagedSurface &surface, uint16 spriteId) {
- renderText(surface, spriteId);
+void Frame::renderShape(Graphics::ManagedSurface &surface, uint16 spriteID) {
+ Common::Rect r = Common::Rect(_sprites[spriteID]->_startPoint.x,
+ _sprites[spriteID]->_startPoint.y,
+ _sprites[spriteID]->_startPoint.x + _sprites[spriteID]->_width,
+ _sprites[spriteID]->_startPoint.y + _sprites[spriteID]->_height);
+
+ Graphics::Surface tmpSurface;
+ tmpSurface.create(r.width(), r.height(), Graphics::PixelFormat::createFormatCLUT8());
+
+ tmpSurface.fillRect(Common::Rect(r.width(), r.height()), 0);
+
+ switch (_sprites[spriteID]->_ink) {
+ case kInkTypeCopy:
+ surface.blitFrom(tmpSurface, Common::Point(_sprites[spriteID]->_startPoint.x, _sprites[spriteID]->_startPoint.y));
+ break;
+ case kInkTypeTransparent:
+ // FIXME: is it always white (last entry in pallette)?
+ surface.transBlitFrom(tmpSurface, Common::Point(_sprites[spriteID]->_startPoint.x, _sprites[spriteID]->_startPoint.y), _vm->getPaletteColorCount() - 1);
+ break;
+ case kInkTypeBackgndTrans:
+ drawBackgndTransSprite(surface, tmpSurface, r);
+ break;
+ case kInkTypeMatte:
+ drawMatteSprite(surface, tmpSurface, r);
+ break;
+ case kInkTypeGhost:
+ drawGhostSprite(surface, tmpSurface, r);
+ break;
+ case kInkTypeReverse:
+ drawReverseSprite(surface, tmpSurface, r);
+ break;
+ default:
+ warning("Unhandled ink type %d", _sprites[spriteID]->_ink);
+ surface.blitFrom(tmpSurface, Common::Point(_sprites[spriteID]->_startPoint.x, _sprites[spriteID]->_startPoint.y));
+ break;
+ }
+
+ _drawRects[spriteID] = r;
+}
+
+void Frame::renderButton(Graphics::ManagedSurface &surface, uint16 spriteId, uint16 textId) {
+ renderText(surface, spriteId, _vm->getMainArchive()->getResource(MKTAG('S', 'T', 'X', 'T'), textId), true);
uint16 castID = _sprites[spriteId]->_castId;
ButtonCast *button = static_cast<ButtonCast *>(_vm->_currentScore->_casts[castID]);
@@ -617,13 +690,19 @@ void Frame::renderButton(Graphics::ManagedSurface &surface, uint16 spriteId) {
int height = _sprites[spriteId]->_height;
int width = _sprites[spriteId]->_width;
+ Common::Rect _rect;
+
switch (button->buttonType) {
case kTypeCheckBox:
// Magic numbers: checkbox square need to move left about 5px from text and 12px side size (D4)
- surface.frameRect(Common::Rect(x - 17, y, x + 12, y + 12), 0);
+ _rect = Common::Rect(x - 17, y, x + 12, y + 12);
+ surface.frameRect(_rect, 0);
+ _drawRects[spriteId] = _rect;
break;
case kTypeButton:
- surface.frameRect(Common::Rect(x, y, x + width, y + height), 0);
+ _rect = Common::Rect(x, y, x + width, y + height);
+ surface.frameRect(_rect, 0);
+ _drawRects[spriteId] = _rect;
break;
case kTypeRadio:
warning("STUB: renderButton: kTypeRadio");
@@ -633,6 +712,10 @@ void Frame::renderButton(Graphics::ManagedSurface &surface, uint16 spriteId) {
Image::ImageDecoder *Frame::getImageFrom(uint16 spriteId) {
uint16 imgId = spriteId + 1024;
+
+ if (_vm->getVersion() >= 4 && _vm->_currentScore->_casts[spriteId]->children.size() > 0)
+ imgId = _vm->_currentScore->_casts[spriteId]->children[0].index;
+
Image::ImageDecoder *img = NULL;
if (_vm->_currentScore->getArchive()->hasResource(MKTAG('D', 'I', 'B', ' '), imgId)) {
@@ -650,13 +733,20 @@ Image::ImageDecoder *Frame::getImageFrom(uint16 spriteId) {
if (_vm->_currentScore->getArchive()->hasResource(MKTAG('B', 'I', 'T', 'D'), imgId)) {
Common::SeekableReadStream *pic = _vm->_currentScore->getArchive()->getResource(MKTAG('B', 'I', 'T', 'D'), imgId);
- if (_vm->getVersion() <= 4) {
+ if (_vm->getVersion() < 4) {
BitmapCast *bc = static_cast<BitmapCast *>(_vm->_currentScore->_casts[spriteId]);
int w = bc->initialRect.width(), h = bc->initialRect.height();
debugC(2, kDebugImages, "id: %d, w: %d, h: %d, flags: %x, some: %x, unk1: %d, unk2: %d",
imgId, w, h, bc->flags, bc->someFlaggyThing, bc->unk1, bc->unk2);
img = new BITDDecoder(w, h);
+ } else if (_vm->getVersion() < 6) {
+ BitmapCast *bc = static_cast<BitmapCast *>(_vm->_currentScore->_casts[spriteId]);
+ int w = bc->initialRect.width(), h = bc->initialRect.height();
+
+ debugC(2, kDebugImages, "id: %d, w: %d, h: %d, flags: %x, some: %x, unk1: %d, unk2: %d",
+ imgId, w, h, bc->flags, bc->someFlaggyThing, bc->unk1, bc->unk2);
+ img = new BITDDecoderV4(w, h);
} else {
img = new Image::BitmapDecoder();
}
@@ -666,6 +756,7 @@ Image::ImageDecoder *Frame::getImageFrom(uint16 spriteId) {
byte buf[1024];
int n = s->read(buf, 1024);
Common::hexdump(buf, n);
+ s->seek(0);
}
img->loadStream(*pic);
@@ -683,17 +774,26 @@ Image::ImageDecoder *Frame::getImageFrom(uint16 spriteId) {
}
-void Frame::renderText(Graphics::ManagedSurface &surface, uint16 spriteID) {
- uint16 castID = _sprites[spriteID]->_castId;
-
- TextCast *textCast = static_cast<TextCast *>(_vm->_currentScore->_casts[castID]);
- Common::SeekableSubReadStreamEndian *textStream;
+void Frame::renderText(Graphics::ManagedSurface &surface, uint16 spriteID, uint16 castID) {
+ Common::SeekableSubReadStreamEndian *textStream = NULL;
- if (_vm->_currentScore->_movieArchive->hasResource(MKTAG('S','T','X','T'), castID + 1024)) {
- textStream = _vm->_currentScore->_movieArchive->getResource(MKTAG('S','T','X','T'), castID + 1024);
- } else {
+ if (_vm->_currentScore->_movieArchive->hasResource(MKTAG('S', 'T', 'X', 'T'), castID)) {
+ textStream = _vm->_currentScore->_movieArchive->getResource(MKTAG('S', 'T', 'X', 'T'), castID);
+ } else if (_vm->getSharedSTXT() != nullptr) {
textStream = _vm->getSharedSTXT()->getVal(spriteID + 1024);
}
+
+ renderText(surface, spriteID, textStream, false);
+}
+
+void Frame::renderText(Graphics::ManagedSurface &surface, uint16 spriteID, Common::SeekableSubReadStreamEndian *textStream, bool isButtonLabel) {
+ if (textStream == NULL) return;
+
+ uint16 castID = _sprites[spriteID]->_castId;
+ TextCast *textCast = static_cast<TextCast *>(_vm->_currentScore->_casts[castID]);
+
+
+
uint32 unk1 = textStream->readUint32();
uint32 strLen = textStream->readUint32();
uint32 dataLen = textStream->readUint32();
@@ -711,11 +811,11 @@ void Frame::renderText(Graphics::ManagedSurface &surface, uint16 spriteID) {
if (strLen < 200)
debugC(3, kDebugText, "text: '%s'", text.c_str());
- uint32 rectLeft = static_cast<TextCast *>(_sprites[spriteID]->_cast)->initialRect.left;
- uint32 rectTop = static_cast<TextCast *>(_sprites[spriteID]->_cast)->initialRect.top;
+ uint32 rectLeft = textCast->initialRect.left;
+ uint32 rectTop = textCast->initialRect.top;
- int x = _sprites[spriteID]->_startPoint.x + rectLeft;
- int y = _sprites[spriteID]->_startPoint.y + rectTop;
+ int x = _sprites[spriteID]->_startPoint.x;// +rectLeft;
+ int y = _sprites[spriteID]->_startPoint.y;// +rectTop;
int height = _sprites[spriteID]->_height;
int width = _sprites[spriteID]->_width;
@@ -730,7 +830,11 @@ void Frame::renderText(Graphics::ManagedSurface &surface, uint16 spriteID) {
debugC(3, kDebugText, "renderText: x: %d y: %d w: %d h: %d font: '%s'", x, y, width, height, _vm->_wm->_fontMan->getFontName(macFont));
- font->drawString(&surface, text, x, y, width, 0);
+ //TODO: the colour is wrong here... need to determine the correct colour for all versions!
+ font->drawString(&surface, text, x, y, width, (_sprites[spriteID]->_ink == kInkTypeReverse ? 255 : 0), (Graphics::TextAlign)textCast->textAlign);
+
+ if (isButtonLabel)
+ return;
if (textCast->borderSize != kSizeNone) {
uint16 size = textCast->borderSize;
@@ -884,10 +988,10 @@ void Frame::drawMatteSprite(Graphics::ManagedSurface &target, const Graphics::Su
uint16 Frame::getSpriteIDFromPos(Common::Point pos) {
// Find first from top to bottom
- for (uint16 i = _drawRects.size() - 1; i > 0; i--) {
- if (_drawRects[i].contains(pos))
- return i;
- }
+ //TODO: THIS NEEDS TO BE REVERSED!
+ for (Common::HashMap<uint16, Common::Rect>::const_iterator dr = _drawRects.begin(); dr != _drawRects.end(); dr++)
+ if (dr->_value.contains(pos))
+ return dr->_key;
return 0;
}
diff --git a/engines/director/frame.h b/engines/director/frame.h
index ce82fa527c..29ae9dd596 100644
--- a/engines/director/frame.h
+++ b/engines/director/frame.h
@@ -119,8 +119,10 @@ private:
void playTransition(Score *score);
void playSoundChannel();
void renderSprites(Graphics::ManagedSurface &surface, bool renderTrail);
- void renderText(Graphics::ManagedSurface &surface, uint16 spriteId);
- void renderButton(Graphics::ManagedSurface &surface, uint16 spriteId);
+ void renderText(Graphics::ManagedSurface &surface, uint16 spriteId, uint16 castID);
+ void renderText(Graphics::ManagedSurface &surface, uint16 spriteID, Common::SeekableSubReadStreamEndian *textStream, bool isButtonLabel);
+ void renderShape(Graphics::ManagedSurface &surface, uint16 spriteID);
+ void renderButton(Graphics::ManagedSurface &surface, uint16 spriteId, uint16 textId);
void readPaletteInfo(Common::SeekableSubReadStreamEndian &stream);
void readSprite(Common::SeekableSubReadStreamEndian &stream, uint16 offset, uint16 size);
void readMainChannels(Common::SeekableSubReadStreamEndian &stream, uint16 offset, uint16 size);
@@ -148,7 +150,7 @@ public:
uint8 _skipFrameFlag;
uint8 _blend;
Common::Array<Sprite *> _sprites;
- Common::Array<Common::Rect > _drawRects;
+ Common::HashMap<uint16, Common::Rect> _drawRects;
DirectorEngine *_vm;
};
diff --git a/engines/director/images.cpp b/engines/director/images.cpp
index 0ec84af0d3..9b55402a18 100644
--- a/engines/director/images.cpp
+++ b/engines/director/images.cpp
@@ -201,4 +201,122 @@ bool BITDDecoder::loadStream(Common::SeekableReadStream &stream) {
return true;
}
+/****************************
+* BITD V4+
+****************************/
+
+BITDDecoderV4::BITDDecoderV4(int w, int h) {
+ _surface = new Graphics::Surface();
+
+ // We make the surface pitch a multiple of 16.
+ int pitch = w;
+ if (w % 16)
+ pitch += 16 - (w % 16);
+
+ // HACK: Create a padded surface by adjusting w after create()
+ _surface->create(pitch, h, Graphics::PixelFormat::createFormatCLUT8());
+ _surface->w = w;
+
+ _palette = new byte[256 * 3];
+
+ _palette[0] = _palette[1] = _palette[2] = 0;
+ _palette[255 * 3 + 0] = _palette[255 * 3 + 1] = _palette[255 * 3 + 2] = 0xff;
+
+ _paletteColorCount = 2;
+}
+
+BITDDecoderV4::~BITDDecoderV4() {
+ destroy();
+}
+
+void BITDDecoderV4::destroy() {
+ _surface = 0;
+
+ delete[] _palette;
+ _palette = 0;
+ _paletteColorCount = 0;
+}
+
+void BITDDecoderV4::loadPalette(Common::SeekableReadStream &stream) {
+ // no op
+}
+
+bool BITDDecoderV4::loadStream(Common::SeekableReadStream &stream) {
+ int x = 0, y = 0;
+
+ // If the stream has exactly the required number of bits for this image,
+ // we assume it is uncompressed.
+ if (stream.size() * 8 == _surface->pitch * _surface->h) {
+ debugC(3, kDebugImages, "Skipping compression");
+ for (y = 0; y < _surface->h; y++) {
+ for (x = 0; x < _surface->pitch; ) {
+ byte color = stream.readByte();
+ for (int c = 0; c < 8; c++)
+ *((byte *)_surface->getBasePtr(x++, y)) = (color & (1 << (7 - c))) ? 0 : 0xff;
+ }
+ }
+
+ return true;
+ }
+
+ Common::Array<int> pixels;
+ pixels.reserve(4096);
+
+ while (!stream.eos()) {
+ int data = stream.readByte();
+ int len = data + 1;
+ if ((data & 0x80) != 0) {
+ len = ((data ^ 0xFF) & 0xff) + 2;
+ data = stream.readByte();
+ for (int p = 0; p < len; p++) {
+ pixels.push_back(data);
+ //*((byte *)_surface->getBasePtr(x, y)) = data;
+ }
+ //data = stream.readByte();
+ } else {
+ for (int p = 0; p < len; p++) {
+ data = stream.readByte();
+ pixels.push_back(data);
+ }
+ }
+ //if (bpp == 32 && pixels.Count % (w * 3) == 0)
+ // source += 2;
+ }
+
+ if (pixels.size() > 0) {
+ //this needs to be calculated a lot earlier!
+ int bpp = pixels.size() / (_surface->w * _surface->h);
+ switch (bpp) {
+ case 1:
+ for (uint pix = 0; pix < pixels.size(); pix++) {
+ //this calculation is wrong.. need a demo with colours.
+ *((byte *)_surface->getBasePtr(x, y)) = 0xff - pixels[pix];
+ x++;
+ if (x == _surface->w) {
+ y++;
+ x = 0;
+ }
+ }
+ break;
+ /*
+ case 32:
+ SetPixel(x, y, Color.FromArgb(
+ pixels[((y * dxr.nodes[c].w) * 3) + x],
+ pixels[(((y * dxr.nodes[c].w) * 3) + (dxr.nodes[c].w)) + x],
+ pixels[(((y * dxr.nodes[c].w) * 3) + (2 * dxr.nodes[c].w)) + x]));
+ break;
+ case 16:
+ SetPixel(x, y, Color.FromArgb(
+ (pixels[((y * dxr.nodes[c].w) * 2) + x] & 0x7c) << 1,
+ (pixels[((y * dxr.nodes[c].w) * 2) + x] & 0x03) << 6 |
+ (pixels[((y * dxr.nodes[c].w) * 2) + (dxr.nodes[c].w) + x] & 0xe0) >> 2,
+ (pixels[((y * dxr.nodes[c].w) * 2) + (dxr.nodes[c].w) + x] & 0x1f) << 3));
+ break;
+ */
+ }
+ }
+
+ return true;
+}
+
} // End of namespace Director
diff --git a/engines/director/images.h b/engines/director/images.h
index 54e824588f..3be0e11a9e 100644
--- a/engines/director/images.h
+++ b/engines/director/images.h
@@ -81,6 +81,25 @@ private:
uint8 _paletteColorCount;
};
+class BITDDecoderV4 : public Image::ImageDecoder {
+public:
+ BITDDecoderV4(int w, int h);
+ virtual ~BITDDecoderV4();
+
+ // ImageDecoder API
+ void destroy();
+ virtual bool loadStream(Common::SeekableReadStream &stream);
+ virtual const Graphics::Surface *getSurface() const { return _surface; }
+ const byte *getPalette() const { return _palette; }
+ void loadPalette(Common::SeekableReadStream &stream);
+ uint16 getPaletteColorCount() const { return _paletteColorCount; }
+
+private:
+ Graphics::Surface *_surface;
+ byte *_palette;
+ uint8 _paletteColorCount;
+};
+
} // End of namespace Director
#endif
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 1d93b9ab44..a53601366d 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -615,7 +615,7 @@ void Lingo::b_alert(int nargs) {
void Lingo::b_cursor(int nargs) {
Datum d = g_lingo->pop();
d.toInt();
- warning("STUB: b_cursor(%d)", d.u.i);
+ g_lingo->func_cursor(d.u.i);
}
void Lingo::b_showGlobals(int nargs) {
@@ -767,7 +767,7 @@ void Lingo::b_point(int nargs) {
///////////////////
void Lingo::b_beep(int nargs) {
Datum d = g_lingo->pop();
- warning("STUB: b_beep(%d)", d.u.i);
+ g_lingo->func_beep(d.u.i);
}
void Lingo::b_mci(int nargs) {
diff --git a/engines/director/lingo/lingo-funcs.cpp b/engines/director/lingo/lingo-funcs.cpp
index e22044c1e9..6becd1410d 100644
--- a/engines/director/lingo/lingo-funcs.cpp
+++ b/engines/director/lingo/lingo-funcs.cpp
@@ -26,6 +26,7 @@
#include "common/util.h"
#include "director/lingo/lingo-gr.h"
#include "director/sound.h"
+#include "graphics/macgui/macwindowmanager.h"
namespace Director {
@@ -210,4 +211,38 @@ void Lingo::func_gotoprevious() {
_vm->_currentScore->gotoprevious();
}
+void Lingo::func_cursor(int c) {
+ if (_cursorOnStack) {
+ //pop cursor
+ _vm->getMacWindowManager()->popCursor();
+ }
+
+ //and then push cursor.
+ switch (c) {
+ case 0:
+ case -1:
+ _vm->getMacWindowManager()->pushArrowCursor();
+ break;
+ case 1:
+ _vm->getMacWindowManager()->pushBeamCursor();
+ break;
+ case 2:
+ _vm->getMacWindowManager()->pushCrossHairCursor();
+ break;
+ case 3:
+ _vm->getMacWindowManager()->pushCrossBarCursor();
+ break;
+ case 4:
+ _vm->getMacWindowManager()->pushWatchCursor();
+ break;
+ }
+
+ warning("STUB: func_cursor(%d)", c);
+}
+
+void Lingo::func_beep(int repeats) {
+ for (int r = 0; r <= repeats; r++)
+ _vm->getSoundManager()->systemBeep();
+}
+
}
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 5e7242abe6..67ab57ae22 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -401,10 +401,12 @@ public:
void func_mci(Common::String &s);
void func_mciwait(Common::String &s);
+ void func_beep(int repeats);
void func_goto(Datum &frame, Datum &movie);
void func_gotoloop();
void func_gotonext();
void func_gotoprevious();
+ void func_cursor(int c);
public:
void setTheEntity(int entity, Datum &id, int field, Datum &d);
@@ -440,6 +442,8 @@ public:
bool _exitRepeat;
+ bool _cursorOnStack;
+
private:
int parse(const char *code);
void parseMenu(const char *code);
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; }
diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index 1bd70d257d..0fc1a43666 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -34,6 +34,11 @@ DirectorSound::DirectorSound() {
_sound2 = new Audio::SoundHandle();
_scriptSound = new Audio::SoundHandle();
_mixer = g_system->getMixer();
+
+ _speaker = new Audio::PCSpeaker();
+ _pcSpeakerHandle = new Audio::SoundHandle();
+ _mixer->playStream(Audio::Mixer::kSFXSoundType,
+ _pcSpeakerHandle, _speaker, -1, 50, 0, DisposeAfterUse::NO, true);
}
DirectorSound::~DirectorSound() {
@@ -100,6 +105,11 @@ bool DirectorSound::isChannelActive(uint8 channelID) {
void DirectorSound::stopSound() {
_mixer->stopHandle(*_sound1);
_mixer->stopHandle(*_sound2);
+ _mixer->stopHandle(*_pcSpeakerHandle);
+}
+
+void DirectorSound::systemBeep() {
+ _speaker->play(Audio::PCSpeaker::kWaveFormSquare, 500, 150);
}
} // End of namespace Director
diff --git a/engines/director/sound.h b/engines/director/sound.h
index 0472da0ef7..6a770314a3 100644
--- a/engines/director/sound.h
+++ b/engines/director/sound.h
@@ -22,6 +22,7 @@
#include "audio/audiostream.h"
#include "audio/mixer.h"
+#include "audio/softsynth/pcspk.h"
#ifndef DIRECTOR_SOUND_H
#define DIRECTOR_SOUND_H
@@ -35,6 +36,8 @@ private:
Audio::SoundHandle *_sound2;
Audio::SoundHandle *_scriptSound;
Audio::Mixer *_mixer;
+ Audio::PCSpeaker *_speaker;
+ Audio::SoundHandle *_pcSpeakerHandle;
public:
DirectorSound();
@@ -43,6 +46,7 @@ public:
void playWAV(Common::String filename, uint8 channelID);
void playAIFF(Common::String filename, uint8 channelID);
void playMCI(Audio::AudioStream &stream, uint32 from, uint32 to);
+ void systemBeep();
bool isChannelActive(uint8 channelID);
void stopSound();
};
diff --git a/engines/director/sprite.h b/engines/director/sprite.h
index d248036693..d9b7729a87 100644
--- a/engines/director/sprite.h
+++ b/engines/director/sprite.h
@@ -106,7 +106,8 @@ public:
uint32 _unk3;
bool _enabled;
- byte _castId;
+ uint16 _castId;
+ byte _spriteType;
InkType _ink;
uint16 _trails;
Cast *_cast;
diff --git a/graphics/macgui/macwindowmanager.cpp b/graphics/macgui/macwindowmanager.cpp
index 42cab7cf8e..bad4ad3acc 100644
--- a/graphics/macgui/macwindowmanager.cpp
+++ b/graphics/macgui/macwindowmanager.cpp
@@ -88,6 +88,60 @@ static const byte macCursorBeam[] = {
3, 3, 0, 3, 0, 3, 3, 3, 3, 3, 3,
0, 0, 3, 3, 3, 0, 0, 3, 3, 3, 3,
};
+static const byte macCursorCrossHair[] = {
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+static const byte macCursorWatch[] = {
+ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0,
+ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0,
+ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0,
+ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0,
+ 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
+ 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1,
+ 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0,
+ 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0,
+ 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0,
+ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0,
+ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0,
+ 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0,
+};
+static const byte macCursorCrossBar[] = {
+ 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0,
+ 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0,
+ 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0,
+ 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0,
+ 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0,
+ 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1,
+ 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1,
+ 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1,
+ 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1,
+ 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0,
+ 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0,
+ 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0,
+ 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
MacWindowManager::MacWindowManager() {
_screen = 0;
@@ -327,6 +381,22 @@ void MacWindowManager::pushArrowCursor() {
CursorMan.pushCursor(macCursorArrow, 11, 16, 1, 1, 3);
}
+void MacWindowManager::pushBeamCursor() {
+ CursorMan.pushCursor(macCursorBeam, 11, 16, 1, 1, 3);
+}
+
+void MacWindowManager::pushCrossHairCursor() {
+ CursorMan.pushCursor(macCursorCrossHair, 11, 16, 1, 1, 3);
+}
+
+void MacWindowManager::pushCrossBarCursor() {
+ CursorMan.pushCursor(macCursorCrossBar, 11, 16, 1, 1, 3);
+}
+
+void MacWindowManager::pushWatchCursor() {
+ CursorMan.pushCursor(macCursorWatch, 11, 16, 1, 1, 3);
+}
+
void MacWindowManager::popCursor() {
CursorMan.popCursor();
}
diff --git a/graphics/macgui/macwindowmanager.h b/graphics/macgui/macwindowmanager.h
index 3449ab13c2..9f62403813 100644
--- a/graphics/macgui/macwindowmanager.h
+++ b/graphics/macgui/macwindowmanager.h
@@ -146,6 +146,10 @@ public:
void drawFilledRoundRect(ManagedSurface *surface, Common::Rect &rect, int arc, int color);
void pushArrowCursor();
+ void pushBeamCursor();
+ void pushCrossHairCursor();
+ void pushCrossBarCursor();
+ void pushWatchCursor();
void popCursor();
public: