aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/adl/adl.cpp39
-rw-r--r--engines/adl/adl.h8
-rw-r--r--engines/adl/adl_v2.cpp116
-rw-r--r--engines/adl/adl_v2.h7
-rw-r--r--engines/adl/hires1.cpp33
-rw-r--r--engines/adl/hires1.h3
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<Item>::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<byte>::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<byte>::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<byte> 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<Item>::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<Item>::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<byte>::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<Item>::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<byte>::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<Item>::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<DataBlockPtr> _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<Item>::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<byte>::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_v1 *>(_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();