MOHAWK: Move per-page data into LBPage.

This commit is contained in:
Alyssa Milburn 2011-04-09 21:01:27 +02:00
parent 8451252786
commit ae49865e9e
4 changed files with 162 additions and 71 deletions

View File

@ -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");
}

View File

@ -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

View File

@ -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())

View File

@ -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);