diff options
Diffstat (limited to 'engines/director/score.cpp')
-rw-r--r-- | engines/director/score.cpp | 190 |
1 files changed, 162 insertions, 28 deletions
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<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; |