aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/mohawk/livingbooks.cpp165
-rw-r--r--engines/mohawk/livingbooks.h62
-rw-r--r--engines/mohawk/livingbooks_code.cpp4
-rw-r--r--engines/mohawk/livingbooks_code.h2
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 &section, 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 &section, const Common::String &key);
Common::String getStringFromConfig(const Common::String &section, const Common::String &key, Common::String &leftover);
int getIntFromConfig(const Common::String &section, const Common::String &key);
- Common::String getFileNameFromConfig(const Common::String &section, 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);