[Scummvm-git-logs] scummvm master -> fba1368267c470f66099bb833359b9d7fec6273e

stevenhoefel stevenhoefel at hotmail.com
Sat Mar 11 14:18:13 CET 2017


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
fba1368267 DIRECTOR: pre-load cast members.


Commit: fba1368267c470f66099bb833359b9d7fec6273e
    https://github.com/scummvm/scummvm/commit/fba1368267c470f66099bb833359b9d7fec6273e
Author: stevenhoefel (stevenhoefel at hotmail.com)
Date: 2017-03-12T00:18:03+11:00

Commit Message:
DIRECTOR: pre-load cast members.

Changed paths:
    engines/director/cast.h
    engines/director/director.cpp
    engines/director/director.h
    engines/director/events.cpp
    engines/director/frame.cpp
    engines/director/lingo/lingo-the.cpp
    engines/director/resource.cpp
    engines/director/score.cpp
    engines/director/score.h
    engines/director/sprite.cpp
    engines/director/sprite.h


diff --git a/engines/director/cast.h b/engines/director/cast.h
index 953c94c..f304456 100644
--- a/engines/director/cast.h
+++ b/engines/director/cast.h
@@ -26,6 +26,7 @@
 #include "common/rect.h"
 #include "common/substream.h"
 #include "director/archive.h"
+#include "graphics/surface.h"
 
 namespace Director {
 
@@ -44,16 +45,20 @@ enum CastType {
 	kCastLingoScript = 11
 };
 
-struct Cast {
+class Cast {
+public:
 	CastType type;
 	Common::Rect initialRect;
 	Common::Rect boundingRect;
 	Common::Array<Resource> children;
 
+	const Graphics::Surface *surface;
+
 	byte modified;
 };
 
-struct BitmapCast : Cast {
+class BitmapCast : public Cast {
+public:
 	BitmapCast(Common::ReadStreamEndian &stream, uint16 version = 2);
 
 	uint16 regX;
@@ -72,7 +77,8 @@ enum ShapeType {
 	kShapeLine
 };
 
-struct ShapeCast : Cast {
+class ShapeCast : public Cast {
+public:
 	ShapeCast(Common::ReadStreamEndian &stream, uint16 version = 2);
 
 	ShapeType shapeType;
@@ -111,7 +117,8 @@ enum SizeType {
 	kSizeLargest
 };
 
-struct TextCast : Cast {
+class TextCast : public Cast {
+public:
 	TextCast(Common::ReadStreamEndian &stream, uint16 version = 2);
 
 	SizeType borderSize;
@@ -135,13 +142,15 @@ enum ButtonType {
 	kTypeRadio
 };
 
-struct ButtonCast : TextCast {
+class ButtonCast : public TextCast {
+public:
 	ButtonCast(Common::ReadStreamEndian &stream, uint16 version = 2);
 
 	ButtonType buttonType;
 };
 
-struct ScriptCast : Cast {
+class ScriptCast : public Cast {
+public:
 	ScriptCast(Common::ReadStreamEndian &stream, uint16 version = 2);
 
 	uint32 id;
diff --git a/engines/director/director.cpp b/engines/director/director.cpp
index c6459ea..1077b75 100644
--- a/engines/director/director.cpp
+++ b/engines/director/director.cpp
@@ -141,6 +141,8 @@ Common::Error DirectorEngine::run() {
 	//_mainArchive = new RIFFArchive();
 	//_mainArchive->openFile("bookshelf_example.mmm");
 
+	_currentScore = new Score(this);
+
 	if (getVersion() < 4) {
 		if (getPlatform() == Common::kPlatformWindows) {
 			_sharedCastFile = "SHARDCST.MMM";
@@ -155,7 +157,7 @@ Common::Error DirectorEngine::run() {
 
 	loadInitialMovie(getEXEName());
 
-	_currentScore = new Score(this, _mainArchive);
+	_currentScore->setArchive(_mainArchive);
 	debug(0, "Score name %s", _currentScore->getMacName().c_str());
 
 	bool loop = true;
@@ -196,7 +198,8 @@ Common::Error DirectorEngine::run() {
 				return Common::kNoError;
 			}
 
-			_currentScore = new Score(this, mov);
+			_currentScore = new Score(this);
+			_currentScore->setArchive(mov);
 			debug(0, "Switching to score '%s'", _currentScore->getMacName().c_str());
 
 			_nextMovie.movie.clear();
@@ -237,7 +240,8 @@ Common::HashMap<Common::String, Score *> *DirectorEngine::scanMovies(const Commo
 
 			warning("name: %s", i->getName().c_str());
 			arc->openFile(i->getName());
-			Score *sc = new Score(this, arc);
+			Score *sc = new Score(this);
+			sc->setArchive(arc);
 			nameMap->setVal(sc->getMacName(), sc);
 
 			debugC(2, kDebugLoading, "Movie name: \"%s\"", sc->getMacName().c_str());
@@ -247,11 +251,11 @@ Common::HashMap<Common::String, Score *> *DirectorEngine::scanMovies(const Commo
 	return nameMap;
 }
 
-Common::HashMap<int, Cast *> *DirectorEngine::getSharedCasts() {
+Common::HashMap<int, CastType> *DirectorEngine::getSharedCastTypes() {
 	if (_sharedScore)
-		return &_sharedScore->_casts;
+		return &_sharedScore->_castTypes;
 
-	return &_dummyCast;
+	return &_dummyCastType;
 }
 
 } // End of namespace Director
diff --git a/engines/director/director.h b/engines/director/director.h
index 2f0b652..1a98329 100644
--- a/engines/director/director.h
+++ b/engines/director/director.h
@@ -28,6 +28,7 @@
 
 #include "common/hashmap.h"
 #include "engines/engine.h"
+#include "director/cast.h"
 
 namespace Common {
 class MacResManager;
@@ -89,6 +90,7 @@ public:
 	Archive *getMainArchive() const { return _mainArchive; }
 	Lingo *getLingo() const { return _lingo; }
 	Score *getCurrentScore() const { return _currentScore; }
+	Score *getSharedScore() const { return _sharedScore; }
 	void setPalette(byte *palette, uint16 count);
 	bool hasFeature(EngineFeature f) const;
 	const byte *getPalette() const { return _currentPalette; }
@@ -107,7 +109,7 @@ public:
 	Common::HashMap<int, Common::SeekableSubReadStreamEndian *> *getSharedDIB() const { return _sharedDIB; }
 	Common::HashMap<int, Common::SeekableSubReadStreamEndian *> *getSharedBMP() const { return _sharedBMP; }
 	Common::HashMap<int, Common::SeekableSubReadStreamEndian *> *getSharedSTXT() const { return _sharedSTXT; }
-	Common::HashMap<int, Cast *> *getSharedCasts();
+	Common::HashMap<int, CastType> *getSharedCastTypes();
 
 	Common::HashMap<Common::String, Score *> *_movies;
 
@@ -159,7 +161,7 @@ private:
 	Graphics::MacPatterns _director3QuickDrawPatterns;
 
 	Common::String _sharedCastFile;
-	Common::HashMap<int, Cast *> _dummyCast;
+	Common::HashMap<int, CastType> _dummyCastType;
 
 private:
 	void testFontScaling();
diff --git a/engines/director/events.cpp b/engines/director/events.cpp
index a4e3f58..b010f74 100644
--- a/engines/director/events.cpp
+++ b/engines/director/events.cpp
@@ -88,6 +88,8 @@ void DirectorEngine::processEvents() {
 					else
 						_lingo->processEvent(kEventMouseUp, kFrameScript, sc->_frames[currentFrame]->_sprites[spriteId]->_scriptId);
 				}
+
+				sc->_currentMouseDownSpriteId = 0;
 			}
 
 			if (event.type == Common::EVENT_KEYDOWN) {
diff --git a/engines/director/frame.cpp b/engines/director/frame.cpp
index 7690a47..b629e43 100644
--- a/engines/director/frame.cpp
+++ b/engines/director/frame.cpp
@@ -563,18 +563,17 @@ void Frame::renderSprites(Graphics::ManagedSurface &surface, bool renderTrail) {
 					break;
 				}
 			} else {
-				if (!_vm->getCurrentScore()->_casts.contains(_sprites[i]->_castId)) {
-					if (!_vm->getSharedCasts()->contains(_sprites[i]->_castId)) {
+				if (!_vm->getCurrentScore()->_castTypes.contains(_sprites[i]->_castId)) {
+					if (!_vm->getSharedCastTypes()->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);
+						castType = _vm->getSharedCastTypes()->getVal(_sprites[i]->_castId);
 					}
 				} else {
-					cast = _vm->getCurrentScore()->_casts[_sprites[i]->_castId];
+					castType = _vm->getCurrentScore()->_castTypes[_sprites[i]->_castId];
 				}
-				castType = cast->type;
 			}
 
 			// this needs precedence to be hit first... D3 does something really tricky with cast IDs for shapes.
@@ -586,34 +585,15 @@ void Frame::renderSprites(Graphics::ManagedSurface &surface, bool renderTrail) {
 			} 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 (%s) not found", _sprites[i]->_castId, numToCastNum(_sprites[i]->_castId));
-					continue;
-				}
-
-				if (!img->getSurface()) {
-					warning("Frame::renderSprites: Could not load image %d (%s)", _sprites[i]->_castId, numToCastNum(_sprites[i]->_castId));
-					continue;
-				}
-
-				if (!_sprites[i]->_cast) {
+				if (!_sprites[i]->_bitmapCast) {
 					warning("No cast ID for sprite %d", i);
 					continue;
 				}
 
-				BitmapCast *bitmapCast = static_cast<BitmapCast *>(_sprites[i]->_cast);
-				// TODO: might want a quicker way to determine if cast is from Shared Cast.
-				if (_vm->getSharedBMP() != NULL && _vm->getSharedBMP()->contains(_sprites[i]->_castId + 1024)) {
-					debugC(2, kDebugImages, "Shared cast sprite BMP: id: %d", _sprites[i]->_castId + 1024);
-					bitmapCast = static_cast<BitmapCast *>(_vm->getSharedCasts()->getVal(_sprites[i]->_castId));
-				}
-
-				uint32 regX = bitmapCast->regX;
-				uint32 regY = bitmapCast->regY;
-				uint32 rectLeft = bitmapCast->initialRect.left;
-				uint32 rectTop = bitmapCast->initialRect.top;
+				uint32 regX = _sprites[i]->_bitmapCast->regX;
+				uint32 regY = _sprites[i]->_bitmapCast->regY;
+				uint32 rectLeft = _sprites[i]->_bitmapCast->initialRect.left;
+				uint32 rectTop = _sprites[i]->_bitmapCast->initialRect.top;
 
 				int x = _sprites[i]->_startPoint.x - regX + rectLeft;
 				int y = _sprites[i]->_startPoint.y - regY + rectTop;
@@ -621,9 +601,8 @@ void Frame::renderSprites(Graphics::ManagedSurface &surface, bool renderTrail) {
 				int width = _sprites[i]->_width;
 
 				Common::Rect drawRect(x, y, x + width, y + height);
-
 				addDrawRect(i, drawRect);
-				inkBasedBlit(surface, *img->getSurface(), i, drawRect);
+				inkBasedBlit(surface, *(_sprites[i]->_bitmapCast->surface), i, drawRect);
 			}
 		}
 	}
@@ -667,15 +646,15 @@ void Frame::renderShape(Graphics::ManagedSurface &surface, uint16 spriteId) {
 
 void Frame::renderButton(Graphics::ManagedSurface &surface, uint16 spriteId, uint16 textId) {
 	uint16 castId = _sprites[spriteId]->_castId;
-	ButtonCast *button = static_cast<ButtonCast *>(_vm->getCurrentScore()->_casts[castId]);
+	ButtonCast *button = _vm->getCurrentScore()->_loadedButtons->getVal(castId);
 
 	uint32 rectLeft = button->initialRect.left;
 	uint32 rectTop = button->initialRect.top;
 
 	int x = _sprites[spriteId]->_startPoint.x + rectLeft;
 	int y = _sprites[spriteId]->_startPoint.y + rectTop;
-	int height = button->initialRect.height(); // _sprites[spriteId]->_height;
-	int width = button->initialRect.width() + 3; // _sprites[spriteId]->_width;
+	int height = button->initialRect.height();
+	int width = button->initialRect.width() + 3;
 
 	Common::Rect textRect(0, 0, width, height);
 	// pass the rect of the button into the label.
@@ -706,73 +685,6 @@ void Frame::renderButton(Graphics::ManagedSurface &surface, uint16 spriteId, uin
 	}
 }
 
-Image::ImageDecoder *Frame::getImageFrom(uint16 spriteId) {
-	uint16 imgId = spriteId + 1024;
-
-	if (_vm->getVersion() >= 4 && _vm->getCurrentScore()->_casts[spriteId]->children.size() > 0)
-		imgId = _vm->getCurrentScore()->_casts[spriteId]->children[0].index;
-
-	Image::ImageDecoder *img = NULL;
-
-	if (_vm->getCurrentScore()->getArchive()->hasResource(MKTAG('D', 'I', 'B', ' '), imgId)) {
-		img = new DIBDecoder();
-		img->loadStream(*_vm->getCurrentScore()->getArchive()->getResource(MKTAG('D', 'I', 'B', ' '), imgId));
-		return img;
-	}
-
-	if (_vm->getSharedDIB() != NULL && _vm->getSharedDIB()->contains(imgId)) {
-		img = new DIBDecoder();
-		img->loadStream(*_vm->getSharedDIB()->getVal(imgId));
-		return img;
-	}
-
-	Common::SeekableReadStream *pic = NULL;
-	BitmapCast *bc = NULL;
-
-	if (_vm->getSharedBMP() != NULL && _vm->getSharedBMP()->contains(imgId)) {
-		debugC(4, kDebugImages, "Shared cast BMP: id: %d", imgId);
-		pic = _vm->getSharedBMP()->getVal(imgId);
-		pic->seek(0); // TODO: this actually gets re-read every loop... we need to rewind it!
-		bc = static_cast<BitmapCast *>(_vm->getSharedCasts()->getVal(spriteId));
-	} else 	if (_vm->getCurrentScore()->getArchive()->hasResource(MKTAG('B', 'I', 'T', 'D'), imgId)) {
-		pic = _vm->getCurrentScore()->getArchive()->getResource(MKTAG('B', 'I', 'T', 'D'), imgId);
-		bc = static_cast<BitmapCast *>(_vm->getCurrentScore()->_casts[spriteId]);
-	}
-
-	if (pic != NULL && bc != NULL) {
-		if (_vm->getVersion() < 4) {
-			int w = bc->initialRect.width(), h = bc->initialRect.height();
-
-			debugC(4, 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) {
-			bc = static_cast<BitmapCast *>(_vm->getCurrentScore()->_casts[spriteId]);
-			int w = bc->initialRect.width(), h = bc->initialRect.height();
-
-			debugC(4, 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, bc->bitsPerPixel);
-		} else {
-			img = new Image::BitmapDecoder();
-		}
-
-		if (debugChannelSet(8, kDebugLoading)) {
-			Common::SeekableReadStream *s = pic;
-			byte buf[1024];
-			int n = s->read(buf, 1024);
-			Common::hexdump(buf, n);
-			s->seek(0);
-		}
-
-		img->loadStream(*pic);
-		return img;
-	}
-
-	warning("Image %d not found", spriteId);
-	return img;
-}
-
 void Frame::inkBasedBlit(Graphics::ManagedSurface &targetSurface, const Graphics::Surface &spriteSurface, uint16 spriteId, Common::Rect drawRect) {
 	switch (_sprites[spriteId]->_ink) {
 	case kInkTypeCopy:
@@ -818,7 +730,7 @@ void Frame::renderText(Graphics::ManagedSurface &surface, uint16 spriteId, Commo
 		return;
 
 	uint16 castId = _sprites[spriteId]->_castId;
-	TextCast *textCast = static_cast<TextCast *>(_vm->getCurrentScore()->_casts[castId]);
+	TextCast *textCast = _vm->getCurrentScore()->_loadedText->getVal(castId);
 
 	uint32 unk1 = textStream->readUint32();
 	uint32 strLen = textStream->readUint32();
@@ -906,8 +818,8 @@ void Frame::renderText(Graphics::ManagedSurface &surface, uint16 spriteId, Commo
 
 	int x = _sprites[spriteId]->_startPoint.x; // +rectLeft;
 	int y = _sprites[spriteId]->_startPoint.y; // +rectTop;
-	int height = _sprites[spriteId]->_cast->initialRect.height(); //_sprites[spriteId]->_height;
-	int width = _sprites[spriteId]->_cast->initialRect.width(); //_sprites[spriteId]->_width;
+	int height = textCast->initialRect.height(); //_sprites[spriteId]->_height;
+	int width = textCast->initialRect.width(); //_sprites[spriteId]->_width;
 
 	if (_vm->getVersion() >= 4 && textSize != NULL)
 		width = textCast->initialRect.right;
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index 8f87443..68999f6 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -332,8 +332,8 @@ void Lingo::setTheSprite(Datum &id1, int field, Datum &d) {
 
 	switch (field) {
 	case kTheCastNum:
-		if (_vm->getCurrentScore()->_casts.contains(d.u.i)) {
-			sprite->_cast = _vm->getCurrentScore()->_casts[d.u.i];
+		if (_vm->getCurrentScore()->_castTypes.contains(d.u.i)) {
+			_vm->getCurrentScore()->loadCastInto(sprite, d.u.i);
 			sprite->_castId = d.u.i;
 		}
 		break;
@@ -638,9 +638,9 @@ Datum Lingo::getTheCast(Datum &id1, int field) {
 		return d;
 	}
 
-	Cast *cast;
+	CastType castType;
 	CastInfo *castInfo;
-	if (!_vm->getCurrentScore()->_casts.contains(id)) {
+	if (!_vm->getCurrentScore()->_castTypes.contains(id)) {
 		if (field == kTheLoaded) {
 			d.type = INT;
 			d.u.i = 0;
@@ -651,14 +651,14 @@ Datum Lingo::getTheCast(Datum &id1, int field) {
 		warning("The cast %d found", id);
 	}
 
-	cast = _vm->getCurrentScore()->_casts[id];
+	castType = _vm->getCurrentScore()->_castTypes[id];
 	castInfo = _vm->getCurrentScore()->_castsInfo[id];
 
 	d.type = INT;
 
 	switch (field) {
 	case kTheCastType:
-		d.u.i = cast->type;
+		d.u.i = castType;
 		break;
 	case kTheFileName:
 		d.toString();
@@ -673,32 +673,32 @@ Datum Lingo::getTheCast(Datum &id1, int field) {
 		d.u.s = &castInfo->script;
 		break;
 	case kTheWidth:
-		d.u.i = cast->initialRect.width();
+		d.u.i = _vm->getCurrentScore()->getCastMemberInitialRect(id).width();
 		break;
 	case kTheHeight:
-		d.u.i = cast->initialRect.height();
+		d.u.i = _vm->getCurrentScore()->getCastMemberInitialRect(id).height();
 		break;
 	case kTheBackColor:
 		{
-			if (cast->type != kCastShape) {
+			if (castType != kCastShape) {
 				warning("Field %d of cast %d not found", field, id);
 				d.type = VOID;
 				return d;
 			}
 
-			ShapeCast *shape = static_cast<ShapeCast *>(_vm->getCurrentScore()->_casts[id]);
+			ShapeCast *shape = _vm->getCurrentScore()->_loadedShapes->getVal(id);
 			d.u.i = shape->bgCol;
 		}
 		break;
 	case kTheForeColor:
 		{
-			if (cast->type != kCastShape) {
+			if (castType != kCastShape) {
 				warning("Field %d of cast %d not found", field, id);
 				d.type = VOID;
 				return d;
 			}
 
-			ShapeCast *shape = static_cast<ShapeCast *>(_vm->getCurrentScore()->_casts[id]);
+			ShapeCast *shape = _vm->getCurrentScore()->_loadedShapes->getVal(id);
 			d.u.i = shape->fgCol;
 		}
 		break;
@@ -729,18 +729,20 @@ void Lingo::setTheCast(Datum &id1, int field, Datum &d) {
 		return;
 	}
 
-	Cast *cast = _vm->getCurrentScore()->_casts[id];
+	CastType castType = _vm->getCurrentScore()->_castTypes[id];
 	CastInfo *castInfo = _vm->getCurrentScore()->_castsInfo[id];
 
-	if (!cast) {
+	if (!castInfo) {
 		warning("The cast %d found", id);
 		return;
 	}
 
 	switch (field) {
 	case kTheCastType:
-		cast->type = static_cast<CastType>(d.u.i);
-		cast->modified = 1;
+		// TODO: You can actually switch the cast type!?
+		warning("Tried to switch cast type of %d", id);
+		//cast->type = static_cast<CastType>(d.u.i);
+		//cast->modified = 1;
 		break;
 	case kTheFileName:
 		castInfo->fileName = *d.u.s;
@@ -752,30 +754,30 @@ void Lingo::setTheCast(Datum &id1, int field, Datum &d) {
 		castInfo->script = *d.u.s;
 		break;
 	case kTheWidth:
-		cast->initialRect.setWidth(d.u.i);
-		cast->modified = 1;
+		_vm->getCurrentScore()->getCastMemberInitialRect(id).setWidth(d.u.i);
+		_vm->getCurrentScore()->setCastMemberModified(id);
 		break;
 	case kTheHeight:
-		cast->initialRect.setHeight(d.u.i);
-		cast->modified = 1;
+		_vm->getCurrentScore()->getCastMemberInitialRect(id).setHeight(d.u.i);
+		_vm->getCurrentScore()->setCastMemberModified(id);
 		break;
 	case kTheBackColor:
 		{
-			if (cast->type != kCastShape) {
+			if (castType != kCastShape) {
 				warning("Field %d of cast %d not found", field, id);
 			}
-			ShapeCast *shape = static_cast<ShapeCast *>(_vm->getCurrentScore()->_casts[id]);
+			ShapeCast *shape = _vm->getCurrentScore()->_loadedShapes->getVal(id);
 			shape->bgCol = d.u.i;
 			shape->modified = 1;
 		}
 		break;
 	case kTheForeColor:
 		{
-			if (cast->type != kCastShape) {
+			if (castType != kCastShape) {
 				warning("Field %d of cast %d not found", field, id);
 				return;
 			}
-			ShapeCast *shape = static_cast<ShapeCast *>(_vm->getCurrentScore()->_casts[id]);
+			ShapeCast *shape = _vm->getCurrentScore()->_loadedShapes->getVal(id);
 			shape->fgCol = d.u.i;
 			shape->modified = 1;
 		}
diff --git a/engines/director/resource.cpp b/engines/director/resource.cpp
index 6dace8b..5a964c1 100644
--- a/engines/director/resource.cpp
+++ b/engines/director/resource.cpp
@@ -212,7 +212,9 @@ void DirectorEngine::loadSharedCastsFrom(Common::String filename) {
 	_sharedSTXT = new Common::HashMap<int, Common::SeekableSubReadStreamEndian *>;
 	_sharedSound = new Common::HashMap<int, Common::SeekableSubReadStreamEndian *>;
 	_sharedBMP = new Common::HashMap<int, Common::SeekableSubReadStreamEndian *>;
-	_sharedScore = new Score(this, shardcst);
+
+	_sharedScore = new Score(this);
+	_sharedScore->setArchive(shardcst);
 
 	if (shardcst->hasResource(MKTAG('F', 'O', 'N', 'D'), -1)) {
 		debug("Shared cast has fonts. Loading....");
@@ -276,6 +278,8 @@ void DirectorEngine::loadSharedCastsFrom(Common::String filename) {
 			_sharedSound->setVal(*iterator, shardcst->getResource(MKTAG('S','N','D',' '), *iterator));
 		}
 	}
+
+	_sharedScore->loadSpriteImages(true);
 }
 
 } // End of namespace Director
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index ea3ce9b..454831a 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -30,6 +30,7 @@
 #include "graphics/palette.h"
 #include "graphics/macgui/macfontmanager.h"
 #include "graphics/macgui/macwindowmanager.h"
+#include "image/bmp.h"
 
 #include "director/cast.h"
 #include "director/score.h"
@@ -59,11 +60,10 @@ const char *scriptType2str(ScriptType scr) {
 }
 
 
-Score::Score(DirectorEngine *vm, Archive *archive) {
+Score::Score(DirectorEngine *vm) {
 	_vm = vm;
 	_surface = new Graphics::ManagedSurface;
 	_trailSurface = new Graphics::ManagedSurface;
-	_movieArchive = archive;
 	_lingo = _vm->getLingo();
 	_soundManager = _vm->getSoundManager();
 	_currentMouseDownSpriteId = 0;
@@ -87,6 +87,15 @@ Score::Score(DirectorEngine *vm, Archive *archive) {
 	_stopPlay = false;
 	_stageColor = 0;
 
+	_loadedBitmaps = new Common::HashMap<int, BitmapCast *>();
+	_loadedText = new Common::HashMap<int, TextCast *>();
+	_loadedButtons = new Common::HashMap<int, ButtonCast *>();
+	_loadedShapes = new Common::HashMap<int, ShapeCast *>();
+	_loadedScripts = new Common::HashMap<int, ScriptCast *>();
+}
+
+void Score::setArchive(Archive *archive) {
+	_movieArchive = archive;
 	if (archive->hasResource(MKTAG('M', 'C', 'N', 'M'), 0)) {
 		_macName = archive->getName(MKTAG('M', 'C', 'N', 'M'), 0).c_str();
 	} else {
@@ -160,6 +169,7 @@ void Score::loadArchive() {
 	}
 
 	setSpriteCasts();
+	loadSpriteImages(false);
 
 	// Try to load movie script, it sits in resource A11
 	if (_vm->getVersion() <= 3) {
@@ -172,6 +182,62 @@ void Score::loadArchive() {
 	}
 }
 
+void Score::loadSpriteImages(bool isSharedCast) {
+	Common::HashMap<int, BitmapCast *>::iterator bc;
+	for (bc = _loadedBitmaps->begin(); bc != _loadedBitmaps->end(); ++bc) {
+		if (bc->_value) {
+			uint16 imgId = bc->_key + 1024;
+			BitmapCast *bitmapCast = bc->_value;
+
+			if (_vm->getVersion() >= 4 && bitmapCast->children.size() > 0)
+				imgId = bitmapCast->children[0].index;
+
+			Image::ImageDecoder *img = NULL;
+
+			if (_movieArchive->hasResource(MKTAG('D', 'I', 'B', ' '), imgId)) {
+				img = new DIBDecoder();
+				img->loadStream(*_movieArchive->getResource(MKTAG('D', 'I', 'B', ' '), imgId));
+				bitmapCast->surface = img->getSurface();
+			}
+
+			if (isSharedCast && _vm->getSharedDIB() != NULL && _vm->getSharedDIB()->contains(imgId)) {
+				img = new DIBDecoder();
+				img->loadStream(*_vm->getSharedDIB()->getVal(imgId));
+				bitmapCast->surface = img->getSurface();
+			}
+
+			Common::SeekableReadStream *pic = NULL;
+
+			if (isSharedCast) {
+				debugC(4, kDebugImages, "Shared cast BMP: id: %d", imgId);
+				pic = _vm->getSharedBMP()->getVal(imgId);
+				pic->seek(0); // TODO: this actually gets re-read every loop... we need to rewind it!
+			} else 	if (_movieArchive->hasResource(MKTAG('B', 'I', 'T', 'D'), imgId)) {
+				pic = _movieArchive->getResource(MKTAG('B', 'I', 'T', 'D'), imgId);
+			}
+
+			int w = bitmapCast->initialRect.width(), h = bitmapCast->initialRect.height();
+			debugC(4, kDebugImages, "id: %d, w: %d, h: %d, flags: %x, some: %x, unk1: %d, unk2: %d",
+				imgId, w, h, bitmapCast->flags, bitmapCast->someFlaggyThing, bitmapCast->unk1, bitmapCast->unk2);
+
+			if (pic != NULL && bitmapCast != NULL) {
+				if (_vm->getVersion() < 4) {
+					img = new BITDDecoder(w, h);
+				} else if (_vm->getVersion() < 6) {
+					img = new BITDDecoderV4(w, h, bitmapCast->bitsPerPixel);
+				} else {
+					img = new Image::BitmapDecoder();
+				}
+
+				img->loadStream(*pic);
+				bitmapCast->surface = img->getSurface();
+			}
+
+			warning("Image %d not found", imgId);
+		}
+	}
+}
+
 Score::~Score() {
 	if (_surface)
 		_surface->free();
@@ -309,20 +375,20 @@ void Score::loadCastDataVWCR(Common::SeekableSubReadStreamEndian &stream) {
 
 		switch (castType) {
 		case kCastBitmap:
-			_casts[id] = new BitmapCast(stream);
-			_casts[id]->type = kCastBitmap;
+			_loadedBitmaps->setVal(id, new BitmapCast(stream));
+			_castTypes[id] = kCastBitmap;
 			break;
 		case kCastText:
-			_casts[id] = new TextCast(stream);
-			_casts[id]->type = kCastText;
+			_loadedText->setVal(id, new TextCast(stream));
+			_castTypes[id] = kCastText;
 			break;
 		case kCastShape:
-			_casts[id] = new ShapeCast(stream);
-			_casts[id]->type = kCastShape;
+			_loadedShapes->setVal(id, new ShapeCast(stream));
+			_castTypes[id] = kCastShape;
 			break;
 		case kCastButton:
-			_casts[id] = new ButtonCast(stream);
-			_casts[id]->type = kCastButton;
+			_loadedButtons->setVal(id, new ButtonCast(stream));
+			_castTypes[id] = kCastButton;
 			break;
 		default:
 			warning("Score::loadCastDataVWCR(): Unhandled cast type: %d", castType);
@@ -336,10 +402,34 @@ void Score::setSpriteCasts() {
 	// Set cast pointers to sprites
 	for (uint16 i = 0; i < _frames.size(); i++) {
 		for (uint16 j = 0; j < _frames[i]->_sprites.size(); j++) {
-			byte castId = _frames[i]->_sprites[j]->_castId;
+			uint16 castId = _frames[i]->_sprites[j]->_castId;
+
+			if (_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)) {
+				_frames[i]->_sprites[j]->_buttonCast = _vm->getSharedScore()->_loadedButtons->getVal(castId);
+			} else if (_loadedButtons->contains(castId)) {
+				_frames[i]->_sprites[j]->_buttonCast = _loadedButtons->getVal(castId);
+			}
 
-			if (_casts.contains(castId))
-				_frames[i]->_sprites[j]->_cast = _casts.find(castId)->_value;
+			//if (_loadedScripts->contains(castId))
+			//	_frames[i]->_sprites[j]->_bitmapCast = _loadedBitmaps->getVal(castId);
+
+			if (_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)) {
+				_frames[i]->_sprites[j]->_shapeCast = _vm->getSharedScore()->_loadedShapes->getVal(castId);
+			} else if (_loadedShapes->contains(castId)) {
+				_frames[i]->_sprites[j]->_shapeCast = _loadedShapes->getVal(castId);
+			}
 		}
 	}
 }
@@ -398,35 +488,32 @@ void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id,
 
 	switch (castType) {
 	case kCastBitmap:
-		_casts[id] = new BitmapCast(castStream, _vm->getVersion());
-		_casts[id]->type = kCastBitmap;
+		_loadedBitmaps->setVal(id, new BitmapCast(castStream, _vm->getVersion()));
+		for (uint child = 0; child < res->children.size(); child++)
+			_loadedBitmaps->getVal(id)->children.push_back(res->children[child]);
+		_castTypes[id] = kCastBitmap;
 		break;
 	case kCastText:
-		_casts[id] = new TextCast(castStream, _vm->getVersion());
-		_casts[id]->type = kCastText;
+		_loadedText->setVal(id, new TextCast(castStream, _vm->getVersion()));
+		_castTypes[id] = kCastText;
 		break;
 	case kCastShape:
-		_casts[id] = new ShapeCast(castStream, _vm->getVersion());
-		_casts[id]->type = kCastShape;
+		_loadedShapes->setVal(id, new ShapeCast(castStream, _vm->getVersion()));
+		_castTypes[id] = kCastShape;
 		break;
 	case kCastButton:
-		_casts[id] = new ButtonCast(castStream, _vm->getVersion());
-		_casts[id]->type = kCastButton;
+		_loadedButtons->setVal(id, new ButtonCast(castStream, _vm->getVersion()));
+		_castTypes[id] = kCastButton;
 		break;
 	case kCastLingoScript:
-		_casts[id] = new ScriptCast(castStream, _vm->getVersion());
-		_casts[id]->type = kCastLingoScript;
+		_loadedScripts->setVal(id, new ScriptCast(castStream, _vm->getVersion()));
+		_castTypes[id] = kCastLingoScript;
 		break;
 	default:
 		warning("Score::loadCastData(): Unhandled cast type: %d", castType);
 		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) {
@@ -467,6 +554,53 @@ void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id,
 		warning("size3: %x", size3);
 }
 
+void Score::loadCastInto(Sprite *sprite, int castId) {
+	switch (_castTypes[castId]) {
+	case kCastBitmap:
+		sprite->_bitmapCast = _loadedBitmaps->getVal(castId);
+		break;
+	case kCastShape:
+		sprite->_shapeCast = _loadedShapes->getVal(castId);
+		break;
+	case kCastButton:
+		sprite->_buttonCast = _loadedButtons->getVal(castId);
+		break;
+	case kCastText:
+		sprite->_textCast = _loadedText->getVal(castId);
+		break;
+	}
+}
+
+Common::Rect Score::getCastMemberInitialRect(int castId) {
+	switch (_castTypes[castId]) {
+	case kCastBitmap:
+		return _loadedBitmaps->getVal(castId)->initialRect;
+	case kCastShape:
+		return _loadedShapes->getVal(castId)->initialRect;
+	case kCastButton:
+		return _loadedButtons->getVal(castId)->initialRect;
+	case kCastText:
+		return _loadedText->getVal(castId)->initialRect;
+	}
+}
+
+void Score::setCastMemberModified(int castId) {
+	switch (_castTypes[castId]) {
+	case kCastBitmap:
+		_loadedBitmaps->getVal(castId)->modified = 1;
+		break;
+	case kCastShape:
+		_loadedShapes->getVal(castId)->modified = 1;
+		break;
+	case kCastButton:
+		_loadedButtons->getVal(castId)->modified = 1;
+		break;
+	case kCastText:
+		_loadedText->getVal(castId)->modified = 1;
+		break;
+	}
+}
+
 void Score::loadLabels(Common::SeekableSubReadStreamEndian &stream) {
 	_labels = new Common::SortedArray<Label *>(compareLabels);
 	uint16 count = stream.readUint16() + 1;
diff --git a/engines/director/score.h b/engines/director/score.h
index 346a84c..83ffecd 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -26,6 +26,8 @@
 #include "common/substream.h"
 #include "common/rect.h"
 #include "director/archive.h"
+#include "director/cast.h"
+#include "director/images.h"
 
 namespace Graphics {
 	class ManagedSurface;
@@ -57,7 +59,7 @@ const char *scriptType2str(ScriptType scr);
 
 class Score {
 public:
-	Score(DirectorEngine *vm, Archive *);
+	Score(DirectorEngine *vm);
 	~Score();
 
 	static Common::Rect readRect(Common::ReadStreamEndian &stream);
@@ -68,6 +70,7 @@ public:
 	void gotoNext();
 	void gotoPrevious();
 	void startLoop();
+	void setArchive(Archive *archive);
 	Archive *getArchive() const { return _movieArchive; };
 	void loadConfig(Common::SeekableSubReadStreamEndian &stream);
 	void loadCastDataVWCR(Common::SeekableSubReadStreamEndian &stream);
@@ -78,8 +81,13 @@ public:
 	Common::String getMacName() const { return _macName; }
 	Sprite *getSpriteById(uint16 id);
 	void setSpriteCasts();
+	void loadSpriteImages(bool isSharedCast);
 	Graphics::ManagedSurface *getSurface() { return _surface; }
 
+	void loadCastInto(Sprite *sprite, int castId);
+	Common::Rect getCastMemberInitialRect(int castId);
+	void setCastMemberModified(int castId);
+
 	int getPreviousLabelNumber(int referenceFrame);
 	int getCurrentLabelNumber();
 	int getNextLabelNumber(int referenceFrame);
@@ -100,7 +108,7 @@ private:
 
 public:
 	Common::Array<Frame *> _frames;
-	Common::HashMap<int, Cast *> _casts;
+	Common::HashMap<int, CastType> _castTypes;
 	Common::HashMap<uint16, CastInfo *> _castsInfo;
 	Common::HashMap<Common::String, int> _castsNames;
 	Common::SortedArray<Label *> *_labels;
@@ -116,6 +124,13 @@ public:
 	bool _stopPlay;
 	uint32 _nextFrameTime;
 
+	Common::HashMap<int, ButtonCast *> *_loadedButtons;
+	Common::HashMap<int, TextCast *> *_loadedText;
+	//Common::HashMap<int, SoundCast *> _loadedSound;
+	Common::HashMap<int, BitmapCast *> *_loadedBitmaps;
+	Common::HashMap<int, ShapeCast *> *_loadedShapes;
+	Common::HashMap<int, ScriptCast *> *_loadedScripts;
+
 private:
 	uint16 _versionMinor;
 	uint16 _versionMajor;
diff --git a/engines/director/sprite.cpp b/engines/director/sprite.cpp
index 0199667..9d219d6 100644
--- a/engines/director/sprite.cpp
+++ b/engines/director/sprite.cpp
@@ -53,7 +53,11 @@ Sprite::Sprite() {
 	_stretch = 0;
 	_type = kInactiveSprite;
 
-	_cast = nullptr;
+	_bitmapCast = nullptr;
+	_textCast = nullptr;
+	_buttonCast = nullptr;
+	_shapeCast = nullptr;
+
 	_blend = 0;
 	_lineSize = 1;
 
@@ -90,7 +94,11 @@ Sprite::Sprite(const Sprite &sprite) {
 	_stretch = sprite._stretch;
 	_type = sprite._type;
 
-	_cast = sprite._cast;
+	_bitmapCast = sprite._bitmapCast;
+	_shapeCast = sprite._shapeCast;
+	_textCast = sprite._textCast;
+	_buttonCast = sprite._buttonCast;
+
 	_constraint = sprite._constraint;
 	_moveable = sprite._moveable;
 	_blend = sprite._blend;
@@ -107,7 +115,14 @@ Sprite::Sprite(const Sprite &sprite) {
 }
 
 Sprite::~Sprite() {
-	delete _cast;
+	if (_bitmapCast) 
+		delete _bitmapCast;
+	if (_shapeCast) 
+		delete _shapeCast;
+	if (_textCast) 
+		delete _textCast;
+	if (_buttonCast) 
+		delete _buttonCast;
 }
 
 } // End of namespace Director
diff --git a/engines/director/sprite.h b/engines/director/sprite.h
index c434188..de1965d 100644
--- a/engines/director/sprite.h
+++ b/engines/director/sprite.h
@@ -110,7 +110,14 @@ public:
 	byte _spriteType;
 	InkType _ink;
 	uint16 _trails;
-	Cast *_cast;
+
+	BitmapCast *_bitmapCast;
+	ShapeCast *_shapeCast;
+	//SoundCast *_soundCast;
+	TextCast *_textCast;
+	ButtonCast *_buttonCast;
+	//ScriptCast *_scriptCast;
+
 	uint16 _flags;
 	Common::Point _startPoint;
 	uint16 _width;





More information about the Scummvm-git-logs mailing list