diff options
-rw-r--r-- | engines/mohawk/livingbooks.cpp | 165 | ||||
-rw-r--r-- | engines/mohawk/livingbooks.h | 62 | ||||
-rw-r--r-- | engines/mohawk/livingbooks_code.cpp | 4 | ||||
-rw-r--r-- | engines/mohawk/livingbooks_code.h | 2 |
4 files changed, 162 insertions, 71 deletions
diff --git a/engines/mohawk/livingbooks.cpp b/engines/mohawk/livingbooks.cpp index 6ecf9f9a48..556210cb43 100644 --- a/engines/mohawk/livingbooks.cpp +++ b/engines/mohawk/livingbooks.cpp @@ -72,6 +72,48 @@ Common::Rect MohawkEngine_LivingBooks::readRect(Common::SeekableSubReadStreamEnd return rect; } +LBPage::LBPage(MohawkEngine_LivingBooks *vm) : _vm(vm) { + _code = NULL; + _mhk = NULL; + + _baseId = 0; + _cascade = false; +} + +void LBPage::open(MohawkArchive *mhk, uint16 baseId) { + _mhk = mhk; + _baseId = baseId; + + _vm->addArchive(_mhk); + if (_vm->hasResource(ID_BCOD, baseId)) + _code = new LBCode(_vm, baseId); + + loadBITL(baseId); + for (uint i = 0; i < _items.size(); i++) + _vm->addItem(_items[i]); + + for (uint32 i = 0; i < _items.size(); i++) + _items[i]->init(); +} + +void LBPage::itemDestroyed(LBItem *item) { + for (uint i = 0; i < _items.size(); i++) + if (item == _items[i]) { + _items.remove_at(i); + return; + } + error("itemDestroyed didn't find item"); +} + +LBPage::~LBPage() { + delete _code; + _vm->removeItems(_items); + for (uint i = 0; i < _items.size(); i++) + delete _items[i]; + _vm->removeArchive(_mhk); + delete _mhk; +} + MohawkEngine_LivingBooks::MohawkEngine_LivingBooks(OSystem *syst, const MohawkGameDescription *gamedesc) : MohawkEngine(syst, gamedesc) { _needsUpdate = false; _needsRedraw = false; @@ -82,11 +124,11 @@ MohawkEngine_LivingBooks::MohawkEngine_LivingBooks(OSystem *syst, const MohawkGa _alreadyShowedIntro = false; - _code = NULL; - _rnd = new Common::RandomSource(); g_eventRec.registerRandomSource(*_rnd, "livingbooks"); + _page = NULL; + const Common::FSNode gameDataDir(ConfMan.get("path")); // Rugrats SearchMan.addSubDirectoryMatching(gameDataDir, "program"); @@ -281,16 +323,9 @@ void MohawkEngine_LivingBooks::destroyPage() { _eventQueue.clear(); - delete _code; - _code = NULL; - - for (uint32 i = 0; i < _items.size(); i++) - delete _items[i]; - _items.clear(); - - for (uint32 i = 0; i < _mhk.size(); i++) - delete _mhk[i]; - _mhk.clear(); + delete _page; + assert(_items.empty()); + _page = NULL; _notifyEvents.clear(); @@ -342,7 +377,8 @@ bool MohawkEngine_LivingBooks::loadPage(LBMode mode, uint page, uint subpage) { MohawkArchive *pageArchive = createMohawkArchive(); if (!filename.empty() && pageArchive->open(filename)) { - _mhk.push_back(pageArchive); + _page = new LBPage(this); + _page->open(pageArchive, 1000); } else { delete pageArchive; debug(2, "Could not find page %d.%d for '%s'", page, subpage, name.c_str()); @@ -360,7 +396,7 @@ bool MohawkEngine_LivingBooks::loadPage(LBMode mode, uint page, uint subpage) { } } - debug(1, "Stack Version: %d", getResourceVersion()); + debug(1, "Page Version: %d", _page->getResourceVersion()); _curMode = mode; _curPage = page; @@ -370,13 +406,6 @@ bool MohawkEngine_LivingBooks::loadPage(LBMode mode, uint page, uint subpage) { _gfx->setPalette(1000); - if (hasResource(ID_BCOD, 1000)) - _code = new LBCode(this); - - loadBITL(1000); - for (uint32 i = 0; i < _items.size(); i++) - _items[i]->init(); - _phase = 0; _introDone = false; @@ -523,6 +552,7 @@ void MohawkEngine_LivingBooks::updatePage() { _items.remove_at(i); i--; delete delayedEvent.item; + _page->itemDestroyed(delayedEvent.item); if (_focus == delayedEvent.item) _focus = NULL; break; @@ -550,6 +580,39 @@ void MohawkEngine_LivingBooks::updatePage() { } } +void MohawkEngine_LivingBooks::addArchive(MohawkArchive *archive) { + _mhk.push_back(archive); +} + +void MohawkEngine_LivingBooks::removeArchive(MohawkArchive *archive) { + for (uint i = 0; i < _mhk.size(); i++) { + if (archive != _mhk[i]) + continue; + _mhk.remove_at(i); + return; + } + + error("removeArchive didn't find archive"); +} + +void MohawkEngine_LivingBooks::addItem(LBItem *item) { + _items.push_back(item); +} + +void MohawkEngine_LivingBooks::removeItems(const Common::Array<LBItem *> &items) { + for (uint i = 0; i < items.size(); i++) { + bool found = false; + for (uint16 j = 0; j < _items.size(); j++) { + if (items[i] != _items[j]) + continue; + found = true; + _items.remove_at(j); + break; + } + assert(found); + } +} + LBItem *MohawkEngine_LivingBooks::getItemById(uint16 id) { for (uint16 i = 0; i < _items.size(); i++) if (_items[i]->getId() == id) @@ -632,9 +695,9 @@ void MohawkEngine_LivingBooks::lockSound(LBItem *owner, bool lock) { } } -// Only 1 VSRN resource per stack, Id 1000 -uint16 MohawkEngine_LivingBooks::getResourceVersion() { - Common::SeekableReadStream *versionStream = getResource(ID_VRSN, 1000); +// Only 1 VSRN resource per page +uint16 LBPage::getResourceVersion() { + Common::SeekableReadStream *versionStream = _vm->getResource(ID_VRSN, _baseId); // FIXME: some V2 games have very strange version entries if (versionStream->size() != 2) @@ -646,43 +709,43 @@ uint16 MohawkEngine_LivingBooks::getResourceVersion() { return version; } -void MohawkEngine_LivingBooks::loadBITL(uint16 resourceId) { - Common::SeekableSubReadStreamEndian *bitlStream = wrapStreamEndian(ID_BITL, resourceId); +void LBPage::loadBITL(uint16 resourceId) { + Common::SeekableSubReadStreamEndian *bitlStream = _vm->wrapStreamEndian(ID_BITL, resourceId); while (true) { - Common::Rect rect = readRect(bitlStream); + Common::Rect rect = _vm->readRect(bitlStream); uint16 type = bitlStream->readUint16(); LBItem *res; switch (type) { case kLBPictureItem: - res = new LBPictureItem(this, rect); + res = new LBPictureItem(_vm, this, rect); break; case kLBAnimationItem: - res = new LBAnimationItem(this, rect); + res = new LBAnimationItem(_vm, this, rect); break; case kLBPaletteItem: - res = new LBPaletteItem(this, rect); + res = new LBPaletteItem(_vm, this, rect); break; case kLBGroupItem: - res = new LBGroupItem(this, rect); + res = new LBGroupItem(_vm, this, rect); break; case kLBSoundItem: - res = new LBSoundItem(this, rect); + res = new LBSoundItem(_vm, this, rect); break; case kLBLiveTextItem: - res = new LBLiveTextItem(this, rect); + res = new LBLiveTextItem(_vm, this, rect); break; case kLBMovieItem: - res = new LBMovieItem(this, rect); + res = new LBMovieItem(_vm, this, rect); break; case kLBMiniGameItem: - res = new LBMiniGameItem(this, rect); + res = new LBMiniGameItem(_vm, this, rect); break; default: warning("Unknown item type %04x", type); case 3: // often used for buttons - res = new LBItem(this, rect); + res = new LBItem(_vm, this, rect); break; } @@ -1810,7 +1873,7 @@ LBScriptEntry::~LBScriptEntry() { delete subentries[i]; } -LBItem::LBItem(MohawkEngine_LivingBooks *vm, Common::Rect rect) : _vm(vm), _rect(rect) { +LBItem::LBItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : _vm(vm), _page(page), _rect(rect) { _phase = 0; _loopMode = 0; @@ -2198,9 +2261,9 @@ void LBItem::readData(uint16 type, uint16 size, Common::SeekableSubReadStreamEnd { assert(size == 4); uint offset = stream->readUint32(); - if (!_vm->_code) + if (!_page->_code) error("no BCOD?"); - _vm->_code->runCode(this, offset); + _page->_code->runCode(this, offset); } break; @@ -2667,9 +2730,9 @@ int LBItem::runScriptEntry(LBScriptEntry *entry) { break; case kLBOpSendExpression: - if (!_vm->_code) + if (!_page->_code) error("no BCOD?"); - _vm->_code->runCode(this, entry->offset); + _page->_code->runCode(this, entry->offset); break; case kLBOpRunSubentries: @@ -2702,10 +2765,10 @@ int LBItem::runScriptEntry(LBScriptEntry *entry) { case kLBOpJumpUnlessExpression: case kLBOpBreakExpression: case kLBOpJumpToExpression: - if (!_vm->_code) + if (!_page->_code) error("no BCOD?"); { - LBValue r = _vm->_code->runCode(this, entry->offset); + LBValue r = _page->_code->runCode(this, entry->offset); // FIXME return r.integer; } @@ -2981,7 +3044,7 @@ bool LBItem::checkCondition(const Common::String &condition) { return false; // unreachable } -LBSoundItem::LBSoundItem(MohawkEngine_LivingBooks *vm, Common::Rect rect) : LBItem(vm, rect) { +LBSoundItem::LBSoundItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) { debug(3, "new LBSoundItem"); _running = false; } @@ -3027,7 +3090,7 @@ void LBSoundItem::stop() { LBItem::stop(); } -LBGroupItem::LBGroupItem(MohawkEngine_LivingBooks *vm, Common::Rect rect) : LBItem(vm, rect) { +LBGroupItem::LBGroupItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) { debug(3, "new LBGroupItem"); _starting = false; } @@ -3142,7 +3205,7 @@ void LBGroupItem::stop() { } } -LBPaletteItem::LBPaletteItem(MohawkEngine_LivingBooks *vm, Common::Rect rect) : LBItem(vm, rect) { +LBPaletteItem::LBPaletteItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) { debug(3, "new LBPaletteItem"); _fadeInStart = 0; @@ -3227,7 +3290,7 @@ void LBPaletteItem::update() { LBItem::update(); } -LBLiveTextItem::LBLiveTextItem(MohawkEngine_LivingBooks *vm, Common::Rect rect) : LBItem(vm, rect) { +LBLiveTextItem::LBLiveTextItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) { _currentPhrase = 0xFFFF; _currentWord = 0xFFFF; debug(3, "new LBLiveTextItem"); @@ -3474,7 +3537,7 @@ void LBLiveTextItem::notify(uint16 data, uint16 from) { LBItem::notify(data, from); } -LBPictureItem::LBPictureItem(MohawkEngine_LivingBooks *vm, Common::Rect rect) : LBItem(vm, rect) { +LBPictureItem::LBPictureItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) { debug(3, "new LBPictureItem"); } @@ -3517,7 +3580,7 @@ void LBPictureItem::draw() { _vm->_gfx->copyAnimImageToScreen(_resourceId, _rect.left, _rect.top); } -LBAnimationItem::LBAnimationItem(MohawkEngine_LivingBooks *vm, Common::Rect rect) : LBItem(vm, rect) { +LBAnimationItem::LBAnimationItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) { _anim = NULL; _running = false; debug(3, "new LBAnimationItem"); @@ -3616,7 +3679,7 @@ void LBAnimationItem::draw() { _anim->draw(); } -LBMovieItem::LBMovieItem(MohawkEngine_LivingBooks *vm, Common::Rect rect) : LBItem(vm, rect) { +LBMovieItem::LBMovieItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) { debug(3, "new LBMovieItem"); } @@ -3645,7 +3708,7 @@ bool LBMovieItem::togglePlaying(bool playing, bool restart) { return LBItem::togglePlaying(playing, restart); } -LBMiniGameItem::LBMiniGameItem(MohawkEngine_LivingBooks *vm, Common::Rect rect) : LBItem(vm, rect) { +LBMiniGameItem::LBMiniGameItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) { debug(3, "new LBMiniGameItem"); } diff --git a/engines/mohawk/livingbooks.h b/engines/mohawk/livingbooks.h index 90540d2c9d..ddca81c64f 100644 --- a/engines/mohawk/livingbooks.h +++ b/engines/mohawk/livingbooks.h @@ -237,6 +237,7 @@ enum { }; class MohawkEngine_LivingBooks; +class LBPage; class LBGraphics; class LBAnimation; @@ -357,7 +358,7 @@ class LBItem { friend class LBCode; public: - LBItem(MohawkEngine_LivingBooks *vm, Common::Rect rect); + LBItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect); virtual ~LBItem(); void readFrom(Common::SeekableSubReadStreamEndian *stream); @@ -392,6 +393,7 @@ public: protected: MohawkEngine_LivingBooks *_vm; + LBPage *_page; void setNextTime(uint16 min, uint16 max); void setNextTime(uint16 min, uint16 max, uint32 start); @@ -427,7 +429,7 @@ protected: class LBSoundItem : public LBItem { public: - LBSoundItem(MohawkEngine_LivingBooks *_vm, Common::Rect rect); + LBSoundItem(MohawkEngine_LivingBooks *_vm, LBPage *page, Common::Rect rect); ~LBSoundItem(); void update(); @@ -445,7 +447,7 @@ struct GroupEntry { class LBGroupItem : public LBItem { public: - LBGroupItem(MohawkEngine_LivingBooks *_vm, Common::Rect rect); + LBGroupItem(MohawkEngine_LivingBooks *_vm, LBPage *page, Common::Rect rect); void readData(uint16 type, uint16 size, Common::SeekableSubReadStreamEndian *stream); @@ -469,7 +471,7 @@ protected: class LBPaletteItem : public LBItem { public: - LBPaletteItem(MohawkEngine_LivingBooks *_vm, Common::Rect rect); + LBPaletteItem(MohawkEngine_LivingBooks *_vm, LBPage *page, Common::Rect rect); ~LBPaletteItem(); void readData(uint16 type, uint16 size, Common::SeekableSubReadStreamEndian *stream); @@ -496,7 +498,7 @@ struct LiveTextPhrase { class LBLiveTextItem : public LBItem { public: - LBLiveTextItem(MohawkEngine_LivingBooks *_vm, Common::Rect rect); + LBLiveTextItem(MohawkEngine_LivingBooks *_vm, LBPage *page, Common::Rect rect); void readData(uint16 type, uint16 size, Common::SeekableSubReadStreamEndian *stream); @@ -525,7 +527,7 @@ protected: class LBPictureItem : public LBItem { public: - LBPictureItem(MohawkEngine_LivingBooks *_vm, Common::Rect rect); + LBPictureItem(MohawkEngine_LivingBooks *_vm, LBPage *page, Common::Rect rect); void readData(uint16 type, uint16 size, Common::SeekableSubReadStreamEndian *stream); @@ -536,7 +538,7 @@ public: class LBAnimationItem : public LBItem { public: - LBAnimationItem(MohawkEngine_LivingBooks *_vm, Common::Rect rect); + LBAnimationItem(MohawkEngine_LivingBooks *_vm, LBPage *page, Common::Rect rect); ~LBAnimationItem(); void setEnabled(bool enabled); @@ -557,7 +559,7 @@ protected: class LBMovieItem : public LBItem { public: - LBMovieItem(MohawkEngine_LivingBooks *_vm, Common::Rect rect); + LBMovieItem(MohawkEngine_LivingBooks *_vm, LBPage *page, Common::Rect rect); ~LBMovieItem(); void update(); @@ -566,7 +568,7 @@ public: class LBMiniGameItem : public LBItem { public: - LBMiniGameItem(MohawkEngine_LivingBooks *_vm, Common::Rect rect); + LBMiniGameItem(MohawkEngine_LivingBooks *_vm, LBPage *page, Common::Rect rect); ~LBMiniGameItem(); bool togglePlaying(bool playing, bool restart); @@ -596,6 +598,30 @@ struct DelayedEvent { DelayedEventType type; }; +class LBPage { +public: + LBPage(MohawkEngine_LivingBooks *vm); + ~LBPage(); + + void open(MohawkArchive *mhk, uint16 baseId); + uint16 getResourceVersion(); + + void itemDestroyed(LBItem *item); + + LBCode *_code; + +protected: + MohawkEngine_LivingBooks *_vm; + + MohawkArchive *_mhk; + Common::Array<LBItem *> _items; + + uint16 _baseId; + bool _cascade; + + void loadBITL(uint16 resourceId); +}; + class MohawkEngine_LivingBooks : public MohawkEngine { protected: Common::Error run(); @@ -616,6 +642,11 @@ public: Common::Rect readRect(Common::SeekableSubReadStreamEndian *stream); GUI::Debugger *getDebugger() { return _console; } + void addArchive(MohawkArchive *archive); + void removeArchive(MohawkArchive *Archive); + void addItem(LBItem *item); + void removeItems(const Common::Array<LBItem *> &items); + LBItem *getItemById(uint16 id); LBItem *getItemByName(Common::String name); @@ -636,11 +667,13 @@ public: void prevPage(); void nextPage(); - LBCode *_code; - // TODO: make private Common::HashMap<Common::String, LBValue> _variables; + // helper functions, also used by LBProxyItem + Common::String getFileNameFromConfig(const Common::String §ion, const Common::String &key, Common::String &leftover); + MohawkArchive *createMohawkArchive() const; + private: LivingBooksConsole *_console; Common::ConfigFile _bookInfoFile; @@ -654,6 +687,7 @@ private: LBMode _curMode; uint16 _curPage, _curSubPage; uint16 _phase; + LBPage *_page; Common::Array<LBItem *> _items; Common::Queue<DelayedEvent> _eventQueue; LBItem *_focus; @@ -666,8 +700,6 @@ private: uint16 _soundLockOwner; uint16 _maxSoundPriority; - uint16 getResourceVersion(); - void loadBITL(uint16 resourceId); void loadSHP(uint16 resourceId); bool tryDefaultPage(); @@ -701,10 +733,6 @@ private: Common::String getStringFromConfig(const Common::String §ion, const Common::String &key); Common::String getStringFromConfig(const Common::String §ion, const Common::String &key, Common::String &leftover); int getIntFromConfig(const Common::String §ion, const Common::String &key); - Common::String getFileNameFromConfig(const Common::String §ion, const Common::String &key, Common::String &leftover); - - // Platform/Version functions - MohawkArchive *createMohawkArchive() const; }; } // End of namespace Mohawk diff --git a/engines/mohawk/livingbooks_code.cpp b/engines/mohawk/livingbooks_code.cpp index 48c48ba917..86adfd6b46 100644 --- a/engines/mohawk/livingbooks_code.cpp +++ b/engines/mohawk/livingbooks_code.cpp @@ -122,8 +122,8 @@ Common::Rect LBValue::toRect() const { } } -LBCode::LBCode(MohawkEngine_LivingBooks *vm) : _vm(vm) { - Common::SeekableSubReadStreamEndian *bcodStream = _vm->wrapStreamEndian(ID_BCOD, 1000); +LBCode::LBCode(MohawkEngine_LivingBooks *vm, uint16 baseId) : _vm(vm) { + Common::SeekableSubReadStreamEndian *bcodStream = _vm->wrapStreamEndian(ID_BCOD, baseId); uint32 totalSize = bcodStream->readUint32(); if (totalSize != (uint32)bcodStream->size()) diff --git a/engines/mohawk/livingbooks_code.h b/engines/mohawk/livingbooks_code.h index bd9a56547b..cd9ac1004a 100644 --- a/engines/mohawk/livingbooks_code.h +++ b/engines/mohawk/livingbooks_code.h @@ -180,7 +180,7 @@ enum { class LBCode { public: - LBCode(MohawkEngine_LivingBooks *vm); + LBCode(MohawkEngine_LivingBooks *vm, uint16 baseId); ~LBCode(); LBValue runCode(LBItem *src, uint32 offset); |