From fba1368267c470f66099bb833359b9d7fec6273e Mon Sep 17 00:00:00 2001 From: stevenhoefel Date: Sun, 12 Mar 2017 00:18:03 +1100 Subject: DIRECTOR: pre-load cast members. --- engines/director/cast.h | 21 ++-- engines/director/director.cpp | 16 +-- engines/director/director.h | 6 +- engines/director/events.cpp | 2 + engines/director/frame.cpp | 120 +++------------------- engines/director/lingo/lingo-the.cpp | 50 ++++----- engines/director/resource.cpp | 6 +- engines/director/score.cpp | 190 +++++++++++++++++++++++++++++------ engines/director/score.h | 19 +++- engines/director/sprite.cpp | 21 +++- engines/director/sprite.h | 9 +- 11 files changed, 283 insertions(+), 177 deletions(-) (limited to 'engines/director') diff --git a/engines/director/cast.h b/engines/director/cast.h index 953c94c4c6..f304456e12 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 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 c6459ead46..1077b75475 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 *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 *DirectorEngine::scanMovies(const Commo return nameMap; } -Common::HashMap *DirectorEngine::getSharedCasts() { +Common::HashMap *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 2f0b65288f..1a98329219 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 *getSharedDIB() const { return _sharedDIB; } Common::HashMap *getSharedBMP() const { return _sharedBMP; } Common::HashMap *getSharedSTXT() const { return _sharedSTXT; } - Common::HashMap *getSharedCasts(); + Common::HashMap *getSharedCastTypes(); Common::HashMap *_movies; @@ -159,7 +161,7 @@ private: Graphics::MacPatterns _director3QuickDrawPatterns; Common::String _sharedCastFile; - Common::HashMap _dummyCast; + Common::HashMap _dummyCastType; private: void testFontScaling(); diff --git a/engines/director/events.cpp b/engines/director/events.cpp index a4e3f58a59..b010f74a6a 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 7690a47893..b629e43705 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(_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(_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(_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(_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(_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(_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(_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 8f874435f7..68999f66ef 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(_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(_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(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(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(_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(_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 6dace8bcb2..5a964c1687 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; _sharedSound = new Common::HashMap; _sharedBMP = new Common::HashMap; - _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 ea3ce9be8c..454831a528 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(); + _loadedText = new Common::HashMap(); + _loadedButtons = new Common::HashMap(); + _loadedShapes = new Common::HashMap(); + _loadedScripts = new Common::HashMap(); +} + +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::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