From bc0fc246f047415837d7c7bccf82918303fcccaf Mon Sep 17 00:00:00 2001 From: Walter van Niftrik Date: Sun, 3 Apr 2016 19:26:34 +0200 Subject: ADL: Implement hires2 screen update routine --- engines/adl/adl.cpp | 39 +---------------- engines/adl/adl.h | 8 ++-- engines/adl/adl_v2.cpp | 116 +++++++++++++++++++++++++++++++++++++++++++++---- engines/adl/adl_v2.h | 7 ++- engines/adl/hires1.cpp | 33 +++++++++++++- engines/adl/hires1.h | 3 +- 6 files changed, 152 insertions(+), 54 deletions(-) diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp index c0592588c8..50e7af4fb6 100644 --- a/engines/adl/adl.cpp +++ b/engines/adl/adl.cpp @@ -379,10 +379,6 @@ void AdlEngine::setupOpcodeTables() { Opcode(o1_setRoomPic); } -bool AdlEngine::matchesCurrentPic(byte pic) const { - return pic == getCurRoom().curPicture; -} - byte AdlEngine::roomArg(byte room) const { return room; } @@ -399,36 +395,6 @@ void AdlEngine::drawPic(byte pic, Common::Point pos) const { _graphics->drawPic(*_pictures[pic]->createReadStream(), pos); } -void AdlEngine::drawItems() const { - Common::List::const_iterator item; - - uint dropped = 0; - - for (item = _state.items.begin(); item != _state.items.end(); ++item) { - // Skip items not in this room - if (item->room != _state.room) - continue; - - if (item->state == IDI_ITEM_DROPPED) { - // Draw dropped item if in normal view - if (getCurRoom().picture == getCurRoom().curPicture) { - drawItem(*item, _itemOffsets[dropped]); - ++dropped; - } - } else { - // Draw fixed item if current view is in the pic list - Common::Array::const_iterator pic; - - for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) { - if (matchesCurrentPic(*pic)) { - drawItem(*item, item->position); - break; - } - } - } - } -} - void AdlEngine::bell(uint count) const { _speaker->bell(count); } @@ -508,7 +474,7 @@ void AdlEngine::takeItem(byte noun) { Common::Array::const_iterator pic; for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) { - if (matchesCurrentPic(*pic)) { + if (*pic == getCurRoom().curPicture) { item->room = IDI_ANY; item->state = IDI_ITEM_DROPPED; return; @@ -566,9 +532,6 @@ Common::Error AdlEngine::run() { // restoring in-game brings us to the same game state. // (Also see comment below.) if (!_isRestoring) { - clearScreen(); - // FIXME: Should only be called when room changes - loadRoom(_state.room); showRoom(); _canSaveNow = _canRestoreNow = true; diff --git a/engines/adl/adl.h b/engines/adl/adl.h index d81afe2743..1b6d02b895 100644 --- a/engines/adl/adl.h +++ b/engines/adl/adl.h @@ -150,6 +150,7 @@ struct Item { int state; byte description; Common::Array roomPictures; + bool isOnScreen; }; struct Time { @@ -238,7 +239,6 @@ protected: virtual bool isInputValid(const Commands &commands, byte verb, byte noun, bool &is_any); virtual void setupOpcodeTables(); - virtual bool matchesCurrentPic(byte pic) const; virtual byte roomArg(byte room) const; virtual void advanceClock() { } @@ -276,7 +276,6 @@ protected: // Graphics void clearScreen() const; void drawPic(byte pic, Common::Point pos = Common::Point()) const; - void drawItems() const; // Sound void bell(uint count = 1) const; @@ -290,7 +289,7 @@ protected: Item &getItem(uint i); byte getVar(uint i) const; void setVar(uint i, byte value); - void takeItem(byte noun); + virtual void takeItem(byte noun); void dropItem(byte noun); bool matchCommand(ScriptEnv &env) const; void doActions(ScriptEnv &env); @@ -359,7 +358,8 @@ private: virtual void runIntro() const { } virtual void init() = 0; virtual void initState() = 0; - virtual void drawItem(const Item &item, const Common::Point &pos) const = 0; + virtual void drawItems() = 0; + virtual void drawItem(Item &item, const Common::Point &pos) = 0; virtual void loadRoom(byte roomNr) = 0; virtual void showRoom() = 0; diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp index 8b7a623654..fd316c052a 100644 --- a/engines/adl/adl_v2.cpp +++ b/engines/adl/adl_v2.cpp @@ -37,7 +37,11 @@ AdlEngine_v2::~AdlEngine_v2() { AdlEngine_v2::AdlEngine_v2(OSystem *syst, const AdlGameDescription *gd) : AdlEngine(syst, gd), _linesPrinted(0), - _disk(nullptr) { + _disk(nullptr), + _itemRemoved(false), + _roomOnScreen(0), + _picOnScreen(0), + _itemsOnScreen(0) { _random = new Common::RandomSource("adl"); } @@ -110,10 +114,6 @@ void AdlEngine_v2::setupOpcodeTables() { Opcode(o2_initDisk); } -bool AdlEngine_v2::matchesCurrentPic(byte pic) const { - return pic == getCurRoom().curPicture || pic == IDI_ANY; -} - byte AdlEngine_v2::roomArg(byte room) const { if (room == IDI_CUR_ROOM) return _state.room; @@ -195,7 +195,8 @@ void AdlEngine_v2::printString(const Common::String &str) { _display->updateTextScreen(); } -void AdlEngine_v2::drawItem(const Item &item, const Common::Point &pos) const { +void AdlEngine_v2::drawItem(Item &item, const Common::Point &pos) { + item.isOnScreen = true; StreamPtr stream(_itemPics[item.picture - 1]->createReadStream()); stream->readByte(); // Skip clear opcode _graphics->drawPic(*stream, pos); @@ -228,13 +229,103 @@ void AdlEngine_v2::loadRoom(byte roomNr) { } void AdlEngine_v2::showRoom() { - drawPic(getCurRoom().curPicture, Common::Point()); - drawItems(); + bool redrawPic = false; + + if (_state.room != _roomOnScreen) { + loadRoom(_state.room); + clearScreen(); + + if (!_state.isDark) + redrawPic = true; + } else { + if (getCurRoom().curPicture != _picOnScreen || _itemRemoved) + redrawPic = true; + } + + if (redrawPic) { + _roomOnScreen = _state.room; + _picOnScreen = getCurRoom().curPicture; + + drawPic(getCurRoom().curPicture); + _itemRemoved = false; + _itemsOnScreen = 0; + + Common::List::iterator item; + for (item = _state.items.begin(); item != _state.items.end(); ++item) + item->isOnScreen = false; + } + + if (!_state.isDark) + drawItems(); + _display->updateHiResScreen(); printString(_roomData.description); + + // FIXME: move to main loop? _linesPrinted = 0; } +void AdlEngine_v2::takeItem(byte noun) { + Common::List::iterator item; + + for (item = _state.items.begin(); item != _state.items.end(); ++item) { + if (item->noun != noun || item->room != _state.room) + continue; + + if (item->state == IDI_ITEM_DOESNT_MOVE) { + printMessage(_messageIds.itemDoesntMove); + return; + } + + if (item->state == IDI_ITEM_DROPPED) { + item->room = IDI_ANY; + _itemRemoved = true; + return; + } + + Common::Array::const_iterator pic; + for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) { + if (*pic == getCurRoom().curPicture || *pic == IDI_ANY) { + item->room = IDI_ANY; + _itemRemoved = true; + item->state = IDI_ITEM_DROPPED; + return; + } + } + } + + printMessage(_messageIds.itemNotHere); +} + +void AdlEngine_v2::drawItems() { + Common::List::iterator item; + + for (item = _state.items.begin(); item != _state.items.end(); ++item) { + // Skip items not in this room + if (item->room != _state.room) + continue; + + if (item->isOnScreen) + continue; + + if (item->state == IDI_ITEM_DROPPED) { + // Draw dropped item if in normal view + if (getCurRoom().picture == getCurRoom().curPicture) + drawItem(*item, _itemOffsets[_itemsOnScreen++]); + } else { + // Draw fixed item if current view is in the pic list + Common::Array::const_iterator pic; + + for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) { + if (*pic == getCurRoom().curPicture || *pic == IDI_ANY) { + drawItem(*item, item->position); + break; + } + } + } + } +} + DataBlockPtr AdlEngine_v2::readDataBlockPtr(Common::ReadStream &f) const { byte track = f.readByte(); byte sector = f.readByte(); @@ -304,6 +395,9 @@ int AdlEngine_v2::o2_moveItem(ScriptEnv &e) { Item &item = getItem(e.arg(1)); + if (item.room == _roomOnScreen) + _picOnScreen = 0; + // Set items that move from inventory to a room to state "dropped" if (item.room == IDI_ANY && room != IDI_VOID_ROOM) item.state = IDI_ITEM_DROPPED; @@ -316,6 +410,10 @@ int AdlEngine_v2::o2_moveAllItems(ScriptEnv &e) { OP_DEBUG_2("\tMOVE_ALL_ITEMS(%d %d)", roomStr(e.arg(1)).c_str(), roomStr(e.arg(2)).c_str()); byte room1 = roomArg(e.arg(1)); + + if (room1 == _state.room) + _picOnScreen = 0; + byte room2 = roomArg(e.arg(2)); Common::List::iterator item; @@ -358,6 +456,8 @@ int AdlEngine_v2::o2_restore(ScriptEnv &e) { _display->printString(_strings_v2.restoreReplace); inputString(); + _picOnScreen = 0; + _roomOnScreen = 0; return 0; } diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h index c8dc189ecd..46a8813cda 100644 --- a/engines/adl/adl_v2.h +++ b/engines/adl/adl_v2.h @@ -43,13 +43,14 @@ protected: // AdlEngine virtual void setupOpcodeTables(); - bool matchesCurrentPic(byte pic) const; byte roomArg(byte room) const; void advanceClock(); void printString(const Common::String &str); - void drawItem(const Item &item, const Common::Point &pos) const; + void drawItems(); + void drawItem(Item &item, const Common::Point &pos); void loadRoom(byte roomNr); void showRoom(); + void takeItem(byte noun); DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const; @@ -78,6 +79,8 @@ protected: uint _linesPrinted; DiskImage *_disk; Common::Array _itemPics; + bool _itemRemoved; + byte _roomOnScreen, _picOnScreen, _itemsOnScreen; private: int askForSlot(const Common::String &question); diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp index 1d7e50e123..cca2fe42e5 100644 --- a/engines/adl/hires1.cpp +++ b/engines/adl/hires1.cpp @@ -289,7 +289,35 @@ void HiRes1Engine::printMessage(uint idx) { printString(msg); } -void HiRes1Engine::drawItem(const Item &item, const Common::Point &pos) const { +void HiRes1Engine::drawItems() { + Common::List::iterator item; + + uint dropped = 0; + + for (item = _state.items.begin(); item != _state.items.end(); ++item) { + // Skip items not in this room + if (item->room != _state.room) + continue; + + if (item->state == IDI_ITEM_DROPPED) { + // Draw dropped item if in normal view + if (getCurRoom().picture == getCurRoom().curPicture) + drawItem(*item, _itemOffsets[dropped++]); + } else { + // Draw fixed item if current view is in the pic list + Common::Array::const_iterator pic; + + for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) { + if (*pic == getCurRoom().curPicture) { + drawItem(*item, item->position); + break; + } + } + } + } +} + +void HiRes1Engine::drawItem(Item &item, const Common::Point &pos) { if (item.isLineArt) { StreamPtr stream(_corners[item.picture - 1]->createReadStream()); static_cast(_graphics)->drawCorners(*stream, pos); @@ -302,6 +330,9 @@ void HiRes1Engine::loadRoom(byte roomNr) { } void HiRes1Engine::showRoom() { + clearScreen(); + loadRoom(_state.room); + if (!_state.isDark) { drawPic(getCurRoom().curPicture); drawItems(); diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h index 251d0797c8..8dc7081b23 100644 --- a/engines/adl/hires1.h +++ b/engines/adl/hires1.h @@ -106,7 +106,8 @@ private: void restartGame(); void printString(const Common::String &str); void printMessage(uint idx); - void drawItem(const Item &item, const Common::Point &pos) const; + void drawItems(); + void drawItem(Item &item, const Common::Point &pos); void loadRoom(byte roomNr); void showRoom(); -- cgit v1.2.3