aboutsummaryrefslogtreecommitdiff
path: root/engines/adl
diff options
context:
space:
mode:
Diffstat (limited to 'engines/adl')
-rw-r--r--engines/adl/adl.cpp9
-rw-r--r--engines/adl/adl.h3
-rw-r--r--engines/adl/adl_v2.cpp28
-rw-r--r--engines/adl/adl_v2.h5
-rw-r--r--engines/adl/adl_v3.cpp217
-rw-r--r--engines/adl/adl_v3.h29
-rw-r--r--engines/adl/adl_v4.cpp271
-rw-r--r--engines/adl/adl_v4.h73
-rw-r--r--engines/adl/detection.cpp64
-rw-r--r--engines/adl/detection.h1
-rw-r--r--engines/adl/disk.cpp184
-rw-r--r--engines/adl/disk.h52
-rw-r--r--engines/adl/display.cpp27
-rw-r--r--engines/adl/display.h1
-rw-r--r--engines/adl/hires0.cpp168
-rw-r--r--engines/adl/hires0.h59
-rw-r--r--engines/adl/hires1.cpp1
-rw-r--r--engines/adl/hires2.cpp10
-rw-r--r--engines/adl/hires4.cpp50
-rw-r--r--engines/adl/hires4.h45
-rw-r--r--engines/adl/hires6.cpp8
-rw-r--r--engines/adl/hires6.h8
-rw-r--r--engines/adl/module.mk3
23 files changed, 912 insertions, 404 deletions
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index b6af54962e..19595606e1 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -520,6 +520,8 @@ void AdlEngine::dropItem(byte noun) {
}
Common::Error AdlEngine::run() {
+ initGraphics(DISPLAY_WIDTH * 2, DISPLAY_HEIGHT * 2, true);
+
_console = new Console(this);
_speaker = new Speaker();
_display = new Display();
@@ -659,6 +661,11 @@ Common::Error AdlEngine::loadGameState(int slot) {
_state.rooms[i].isFirstTime = inFile->readByte();
}
+ // NOTE: _state.curPicture is part of the save state in the original engine. We
+ // reconstruct it instead. This is believed to be safe for at least hires 0-2, but
+ // this may need to be re-evaluated for later games.
+ _state.curPicture = _state.rooms[_state.room].curPicture;
+
size = inFile->readUint32BE();
if (size != _state.items.size())
error("Item count mismatch (expected %i; found %i)", _state.items.size(), size);
@@ -949,7 +956,7 @@ int AdlEngine::o1_isVarEQ(ScriptEnv &e) {
int AdlEngine::o1_isCurPicEQ(ScriptEnv &e) {
OP_DEBUG_1("\t&& GET_CURPIC() == %d", e.arg(1));
- if (getCurRoom().curPicture == e.arg(1))
+ if (_state.curPicture == e.arg(1))
return 1;
return -1;
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index c9d77fcc62..89cdabe384 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -165,11 +165,12 @@ struct State {
Common::Array<byte> vars;
byte room;
+ byte curPicture;
uint16 moves;
bool isDark;
Time time;
- State() : room(1), moves(1), isDark(false) { }
+ State() : room(1), curPicture(0), moves(1), isDark(false) { }
};
typedef Common::List<Command> Commands;
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 4fdf796701..e18f3339f8 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -79,9 +79,9 @@ void AdlEngine_v2::setupOpcodeTables() {
Opcode(o1_listInv);
Opcode(o2_moveItem);
Opcode(o1_setRoom);
- Opcode(o1_setCurPic);
+ Opcode(o2_setCurPic);
// 0x08
- Opcode(o1_setPic);
+ Opcode(o2_setPic);
Opcode(o1_printMsg);
Opcode(o1_setLight);
Opcode(o1_setDark);
@@ -250,6 +250,8 @@ void AdlEngine_v2::loadRoom(byte roomNr) {
void AdlEngine_v2::showRoom() {
bool redrawPic = false;
+ _state.curPicture = getCurRoom().curPicture;
+
if (_state.room != _roomOnScreen) {
loadRoom(_state.room);
clearScreen();
@@ -257,15 +259,15 @@ void AdlEngine_v2::showRoom() {
if (!_state.isDark)
redrawPic = true;
} else {
- if (getCurRoom().curPicture != _picOnScreen || _itemRemoved)
+ if (_state.curPicture != _picOnScreen || _itemRemoved)
redrawPic = true;
}
if (redrawPic) {
_roomOnScreen = _state.room;
- _picOnScreen = getCurRoom().curPicture;
+ _picOnScreen = _state.curPicture;
- drawPic(getCurRoom().curPicture);
+ drawPic(_state.curPicture);
_itemRemoved = false;
_itemsOnScreen = 0;
@@ -336,7 +338,7 @@ void AdlEngine_v2::drawItems() {
Common::Array<byte>::const_iterator pic;
for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
- if (*pic == getCurRoom().curPicture || *pic == IDI_ANY) {
+ if (*pic == _state.curPicture || *pic == IDI_ANY) {
drawItem(*item, item->position);
break;
}
@@ -425,6 +427,20 @@ int AdlEngine_v2::o2_moveItem(ScriptEnv &e) {
return 2;
}
+int AdlEngine_v2::o2_setCurPic(ScriptEnv &e) {
+ OP_DEBUG_1("\tSET_CURPIC(%d)", e.arg(1));
+
+ getCurRoom().curPicture = _state.curPicture = e.arg(1);
+ return 1;
+}
+
+int AdlEngine_v2::o2_setPic(ScriptEnv &e) {
+ OP_DEBUG_1("\tSET_PIC(%d)", e.arg(1));
+
+ getCurRoom().picture = getCurRoom().curPicture = _state.curPicture = e.arg(1);
+ return 1;
+}
+
int AdlEngine_v2::o2_moveAllItems(ScriptEnv &e) {
OP_DEBUG_2("\tMOVE_ALL_ITEMS(%s, %s)", itemRoomStr(e.arg(1)).c_str(), itemRoomStr(e.arg(2)).c_str());
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index f18972b74b..327b36e913 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -25,9 +25,6 @@
#include "adl/adl.h"
-// Note: this version of ADL redraws only when necessary, but
-// this is not currently implemented.
-
namespace Common {
class RandomSource;
}
@@ -64,6 +61,8 @@ protected:
int o2_isCarryingSomething(ScriptEnv &e);
int o2_moveItem(ScriptEnv &e);
+ int o2_setCurPic(ScriptEnv &e);
+ int o2_setPic(ScriptEnv &e);
int o2_moveAllItems(ScriptEnv &e);
int o2_save(ScriptEnv &e);
int o2_restore(ScriptEnv &e);
diff --git a/engines/adl/adl_v3.cpp b/engines/adl/adl_v3.cpp
index 623db661bc..6b93acde61 100644
--- a/engines/adl/adl_v3.cpp
+++ b/engines/adl/adl_v3.cpp
@@ -20,162 +20,26 @@
*
*/
-#include "common/random.h"
-#include "common/error.h"
-
#include "adl/adl_v3.h"
-#include "adl/display.h"
-#include "adl/graphics.h"
namespace Adl {
AdlEngine_v3::AdlEngine_v3(OSystem *syst, const AdlGameDescription *gd) :
- AdlEngine_v2(syst, gd),
- _curDisk(0) {
-}
-
-Common::String AdlEngine_v3::loadMessage(uint idx) const {
- Common::String str = AdlEngine_v2::loadMessage(idx);
-
- for (uint i = 0; i < str.size(); ++i) {
- const char *xorStr = "AVISDURGAN";
- str.setChar(str[i] ^ xorStr[i % strlen(xorStr)], i);
- }
-
- return str;
+ AdlEngine_v2(syst, gd) {
}
Common::String AdlEngine_v3::getItemDescription(const Item &item) const {
- return _itemDesc[item.id - 1];
-}
-
-void AdlEngine_v3::applyDiskOffset(byte &track, byte &sector) const {
- sector += _diskOffsets[_curDisk].sector;
- if (sector >= 16) {
- sector -= 16;
- ++track;
- }
-
- track += _diskOffsets[_curDisk].track;
-}
-
-DataBlockPtr AdlEngine_v3::readDataBlockPtr(Common::ReadStream &f) const {
- byte track = f.readByte();
- byte sector = f.readByte();
- byte offset = f.readByte();
- byte size = f.readByte();
-
- if (f.eos() || f.err())
- error("Error reading DataBlockPtr");
-
- if (track == 0 && sector == 0 && offset == 0 && size == 0)
- return DataBlockPtr();
-
- applyDiskOffset(track, sector);
-
- return _disk->getDataBlock(track, sector, offset, size);
+ return _itemDesc[item.description - 1];
}
typedef Common::Functor1Mem<ScriptEnv &, int, AdlEngine_v3> OpcodeV3;
-#define SetOpcodeTable(x) table = &x;
-#define Opcode(x) table->push_back(new OpcodeV3(this, &AdlEngine_v3::x))
-#define OpcodeUnImpl() table->push_back(new OpcodeV3(this, 0))
void AdlEngine_v3::setupOpcodeTables() {
- Common::Array<const Opcode *> *table = 0;
-
- SetOpcodeTable(_condOpcodes);
- // 0x00
- OpcodeUnImpl();
- Opcode(o2_isFirstTime);
- Opcode(o2_isRandomGT);
- Opcode(o3_isItemInRoom);
- // 0x04
- Opcode(o3_isNounNotInRoom);
- Opcode(o1_isMovesGT);
- Opcode(o1_isVarEQ);
- Opcode(o2_isCarryingSomething);
- // 0x08
- Opcode(o3_isVarGT);
- Opcode(o1_isCurPicEQ);
- Opcode(o3_skipOneCommand);
-
- SetOpcodeTable(_actOpcodes);
- // 0x00
- OpcodeUnImpl();
- Opcode(o1_varAdd);
- Opcode(o1_varSub);
- Opcode(o1_varSet);
- // 0x04
- Opcode(o1_listInv);
- Opcode(o3_moveItem);
- Opcode(o1_setRoom);
- Opcode(o1_setCurPic);
- // 0x08
- Opcode(o1_setPic);
- Opcode(o1_printMsg);
- Opcode(o3_dummy);
- Opcode(o3_setTextMode);
- // 0x0c
- Opcode(o2_moveAllItems);
- Opcode(o1_quit);
- Opcode(o3_dummy);
- Opcode(o2_save);
- // 0x10
- Opcode(o2_restore);
- Opcode(o1_restart);
- Opcode(o3_setDisk);
- Opcode(o3_dummy);
- // 0x14
- Opcode(o1_resetPic);
- Opcode(o1_goDirection<IDI_DIR_NORTH>);
- Opcode(o1_goDirection<IDI_DIR_SOUTH>);
- Opcode(o1_goDirection<IDI_DIR_EAST>);
- // 0x18
- Opcode(o1_goDirection<IDI_DIR_WEST>);
- Opcode(o1_goDirection<IDI_DIR_UP>);
- Opcode(o1_goDirection<IDI_DIR_DOWN>);
- Opcode(o1_takeItem);
- // 0x1c
- Opcode(o1_dropItem);
- Opcode(o1_setRoomPic);
- Opcode(o3_sound);
- OpcodeUnImpl();
- // 0x20
- Opcode(o2_initDisk);
-}
-
-int AdlEngine_v3::o3_isVarGT(ScriptEnv &e) {
- OP_DEBUG_2("\t&& VARS[%d] > %d", e.arg(1), e.arg(2));
-
- if (getVar(e.arg(1)) > e.arg(2))
- return 2;
-
- return -1;
-}
-
-int AdlEngine_v3::o3_skipOneCommand(ScriptEnv &e) {
- OP_DEBUG_0("\t&& SKIP_ONE_COMMAND()");
-
- _skipOneCommand = true;
- setVar(2, 0);
-
- return -1;
-}
-
-// FIXME: Rename "isLineArt" and look at code duplication
-int AdlEngine_v3::o3_isItemInRoom(ScriptEnv &e) {
- OP_DEBUG_2("\t&& GET_ITEM_ROOM(%s) == %s", itemStr(e.arg(1)).c_str(), itemRoomStr(e.arg(2)).c_str());
-
- const Item &item = getItem(e.arg(1));
-
- if (e.arg(2) != IDI_ANY && item.isLineArt != _curDisk)
- return -1;
-
- if (item.room == roomArg(e.arg(2)))
- return 2;
-
- return -1;
+ AdlEngine_v2::setupOpcodeTables();
+ delete _condOpcodes[0x04];
+ _condOpcodes[0x04] = new OpcodeV3(this, &AdlEngine_v3::o3_isNounNotInRoom);
+ delete _actOpcodes[0x04];
+ _actOpcodes[0x04] = new OpcodeV3(this, &AdlEngine_v3::o3_listInv);
}
int AdlEngine_v3::o3_isNounNotInRoom(ScriptEnv &e) {
@@ -183,75 +47,28 @@ int AdlEngine_v3::o3_isNounNotInRoom(ScriptEnv &e) {
Common::List<Item>::const_iterator item;
- setVar(24, 0);
+ bool isAnItem = false;
- for (item = _state.items.begin(); item != _state.items.end(); ++item)
+ for (item = _state.items.begin(); item != _state.items.end(); ++item) {
if (item->noun == e.getNoun()) {
- setVar(24, 1);
+ isAnItem = true;
if (item->room == roomArg(e.arg(1)))
return -1;
}
-
- return 1;
-}
-
-int AdlEngine_v3::o3_moveItem(ScriptEnv &e) {
- OP_DEBUG_2("\tSET_ITEM_ROOM(%s, %s)", itemStr(e.arg(1)).c_str(), itemRoomStr(e.arg(2)).c_str());
-
- byte room = roomArg(e.arg(2));
-
- 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;
-
- item.room = room;
- item.isLineArt = _curDisk;
- return 2;
-}
-
-int AdlEngine_v3::o3_dummy(ScriptEnv &e) {
- OP_DEBUG_0("\tDUMMY()");
-
- return 0;
-}
-
-int AdlEngine_v3::o3_setTextMode(ScriptEnv &e) {
- OP_DEBUG_1("\tSET_TEXT_MODE(%d)", e.arg(1));
-
- // TODO
- // 1: 4-line mode
- // 2: 24-line mode
-
- switch (e.arg(1)) {
- case 3:
- // We re-use the restarting flag here, to simulate a long jump
- _isRestarting = true;
- return -1;
}
- return 1;
+ return (isAnItem ? 1 : -1);
}
-int AdlEngine_v3::o3_setDisk(ScriptEnv &e) {
- OP_DEBUG_2("\tSET_DISK(%d, %d)", e.arg(1), e.arg(2));
-
- // TODO
- // Arg 1: disk
- // Arg 2: room
-
- return 2;
-}
+int AdlEngine_v3::o3_listInv(ScriptEnv &e) {
+ OP_DEBUG_0("\tLIST_INVENTORY()");
-int AdlEngine_v3::o3_sound(ScriptEnv &e) {
- OP_DEBUG_0("\tSOUND()");
+ Common::List<Item>::const_iterator item;
- // TODO
+ for (item = _state.items.begin(); item != _state.items.end(); ++item)
+ if (item->room == IDI_ANY)
+ printString(_itemDesc[item->description - 1]);
return 0;
}
diff --git a/engines/adl/adl_v3.h b/engines/adl/adl_v3.h
index 61dd5852e7..759b17cc6f 100644
--- a/engines/adl/adl_v3.h
+++ b/engines/adl/adl_v3.h
@@ -25,18 +25,6 @@
#include "adl/adl_v2.h"
-// Note: this version of ADL redraws only when necessary, but
-// this is not currently implemented.
-
-namespace Common {
-class RandomSource;
-}
-
-struct DiskOffset {
- byte track;
- byte sector;
-};
-
namespace Adl {
class AdlEngine_v3 : public AdlEngine_v2 {
@@ -48,27 +36,12 @@ protected:
// AdlEngine
virtual void setupOpcodeTables();
- virtual Common::String loadMessage(uint idx) const;
Common::String getItemDescription(const Item &item) const;
- // AdlEngine_v2
- virtual DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const;
-
- void applyDiskOffset(byte &track, byte &sector) const;
-
- int o3_isVarGT(ScriptEnv &e);
- int o3_isItemInRoom(ScriptEnv &e);
int o3_isNounNotInRoom(ScriptEnv &e);
- int o3_skipOneCommand(ScriptEnv &e);
- int o3_moveItem(ScriptEnv &e);
- int o3_dummy(ScriptEnv &e);
- int o3_setTextMode(ScriptEnv &e);
- int o3_setDisk(ScriptEnv &e);
- int o3_sound(ScriptEnv &e);
+ int o3_listInv(ScriptEnv &e);
Common::Array<Common::String> _itemDesc;
- byte _curDisk;
- Common::Array<DiskOffset> _diskOffsets;
};
} // End of namespace Adl
diff --git a/engines/adl/adl_v4.cpp b/engines/adl/adl_v4.cpp
new file mode 100644
index 0000000000..602ee25683
--- /dev/null
+++ b/engines/adl/adl_v4.cpp
@@ -0,0 +1,271 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/random.h"
+#include "common/error.h"
+
+#include "adl/adl_v4.h"
+#include "adl/display.h"
+#include "adl/graphics.h"
+
+namespace Adl {
+
+AdlEngine_v4::AdlEngine_v4(OSystem *syst, const AdlGameDescription *gd) :
+ AdlEngine_v3(syst, gd),
+ _curDisk(0) {
+}
+
+Common::String AdlEngine_v4::loadMessage(uint idx) const {
+ Common::String str = AdlEngine_v2::loadMessage(idx);
+
+ for (uint i = 0; i < str.size(); ++i) {
+ const char *xorStr = "AVISDURGAN";
+ str.setChar(str[i] ^ xorStr[i % strlen(xorStr)], i);
+ }
+
+ return str;
+}
+
+Common::String AdlEngine_v4::getItemDescription(const Item &item) const {
+ return _itemDesc[item.id - 1];
+}
+
+void AdlEngine_v4::applyDiskOffset(byte &track, byte &sector) const {
+ sector += _diskOffsets[_curDisk].sector;
+ if (sector >= 16) {
+ sector -= 16;
+ ++track;
+ }
+
+ track += _diskOffsets[_curDisk].track;
+}
+
+DataBlockPtr AdlEngine_v4::readDataBlockPtr(Common::ReadStream &f) const {
+ byte track = f.readByte();
+ byte sector = f.readByte();
+ byte offset = f.readByte();
+ byte size = f.readByte();
+
+ if (f.eos() || f.err())
+ error("Error reading DataBlockPtr");
+
+ if (track == 0 && sector == 0 && offset == 0 && size == 0)
+ return DataBlockPtr();
+
+ applyDiskOffset(track, sector);
+
+ return _disk->getDataBlock(track, sector, offset, size);
+}
+
+typedef Common::Functor1Mem<ScriptEnv &, int, AdlEngine_v4> OpcodeV4;
+#define SetOpcodeTable(x) table = &x;
+#define Opcode(x) table->push_back(new OpcodeV4(this, &AdlEngine_v4::x))
+#define OpcodeUnImpl() table->push_back(new OpcodeV4(this, 0))
+
+void AdlEngine_v4::setupOpcodeTables() {
+ Common::Array<const Opcode *> *table = 0;
+
+ SetOpcodeTable(_condOpcodes);
+ // 0x00
+ OpcodeUnImpl();
+ Opcode(o2_isFirstTime);
+ Opcode(o2_isRandomGT);
+ Opcode(o4_isItemInRoom);
+ // 0x04
+ Opcode(o4_isNounNotInRoom);
+ Opcode(o1_isMovesGT);
+ Opcode(o1_isVarEQ);
+ Opcode(o2_isCarryingSomething);
+ // 0x08
+ Opcode(o4_isVarGT);
+ Opcode(o1_isCurPicEQ);
+ Opcode(o4_skipOneCommand);
+
+ SetOpcodeTable(_actOpcodes);
+ // 0x00
+ OpcodeUnImpl();
+ Opcode(o1_varAdd);
+ Opcode(o1_varSub);
+ Opcode(o1_varSet);
+ // 0x04
+ Opcode(o4_listInv);
+ Opcode(o4_moveItem);
+ Opcode(o1_setRoom);
+ Opcode(o2_setCurPic);
+ // 0x08
+ Opcode(o2_setPic);
+ Opcode(o1_printMsg);
+ Opcode(o4_dummy);
+ Opcode(o4_setTextMode);
+ // 0x0c
+ Opcode(o2_moveAllItems);
+ Opcode(o1_quit);
+ Opcode(o4_dummy);
+ Opcode(o2_save);
+ // 0x10
+ Opcode(o2_restore);
+ Opcode(o1_restart);
+ Opcode(o4_setDisk);
+ Opcode(o4_dummy);
+ // 0x14
+ Opcode(o1_resetPic);
+ Opcode(o1_goDirection<IDI_DIR_NORTH>);
+ Opcode(o1_goDirection<IDI_DIR_SOUTH>);
+ Opcode(o1_goDirection<IDI_DIR_EAST>);
+ // 0x18
+ Opcode(o1_goDirection<IDI_DIR_WEST>);
+ Opcode(o1_goDirection<IDI_DIR_UP>);
+ Opcode(o1_goDirection<IDI_DIR_DOWN>);
+ Opcode(o1_takeItem);
+ // 0x1c
+ Opcode(o1_dropItem);
+ Opcode(o1_setRoomPic);
+ Opcode(o4_sound);
+ OpcodeUnImpl();
+ // 0x20
+ Opcode(o2_initDisk);
+}
+
+int AdlEngine_v4::o4_isVarGT(ScriptEnv &e) {
+ OP_DEBUG_2("\t&& VARS[%d] > %d", e.arg(1), e.arg(2));
+
+ if (getVar(e.arg(1)) > e.arg(2))
+ return 2;
+
+ return -1;
+}
+
+int AdlEngine_v4::o4_skipOneCommand(ScriptEnv &e) {
+ OP_DEBUG_0("\t&& SKIP_ONE_COMMAND()");
+
+ _skipOneCommand = true;
+ setVar(2, 0);
+
+ return -1;
+}
+
+// FIXME: Rename "isLineArt" and look at code duplication
+int AdlEngine_v4::o4_isItemInRoom(ScriptEnv &e) {
+ OP_DEBUG_2("\t&& GET_ITEM_ROOM(%s) == %s", itemStr(e.arg(1)).c_str(), itemRoomStr(e.arg(2)).c_str());
+
+ const Item &item = getItem(e.arg(1));
+
+ if (e.arg(2) != IDI_ANY && item.isLineArt != _curDisk)
+ return -1;
+
+ if (item.room == roomArg(e.arg(2)))
+ return 2;
+
+ return -1;
+}
+
+int AdlEngine_v4::o4_isNounNotInRoom(ScriptEnv &e) {
+ OP_DEBUG_1("\t&& NO_SUCH_ITEMS_IN_ROOM(%s)", itemRoomStr(e.arg(1)).c_str());
+
+ Common::List<Item>::const_iterator item;
+
+ setVar(24, 0);
+
+ for (item = _state.items.begin(); item != _state.items.end(); ++item)
+ if (item->noun == e.getNoun()) {
+ setVar(24, 1);
+
+ if (item->room == roomArg(e.arg(1)))
+ return -1;
+ }
+
+ return 1;
+}
+
+int AdlEngine_v4::o4_listInv(ScriptEnv &e) {
+ OP_DEBUG_0("\tLIST_INVENTORY()");
+
+ Common::List<Item>::const_iterator item;
+
+ for (item = _state.items.begin(); item != _state.items.end(); ++item)
+ if (item->room == IDI_ANY)
+ printString(_itemDesc[item->id - 1]);
+
+ return 0;
+}
+
+int AdlEngine_v4::o4_moveItem(ScriptEnv &e) {
+ OP_DEBUG_2("\tSET_ITEM_ROOM(%s, %s)", itemStr(e.arg(1)).c_str(), itemRoomStr(e.arg(2)).c_str());
+
+ byte room = roomArg(e.arg(2));
+
+ 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;
+
+ item.room = room;
+ item.isLineArt = _curDisk;
+ return 2;
+}
+
+int AdlEngine_v4::o4_dummy(ScriptEnv &e) {
+ OP_DEBUG_0("\tDUMMY()");
+
+ return 0;
+}
+
+int AdlEngine_v4::o4_setTextMode(ScriptEnv &e) {
+ OP_DEBUG_1("\tSET_TEXT_MODE(%d)", e.arg(1));
+
+ // TODO
+ // 1: 4-line mode
+ // 2: 24-line mode
+
+ switch (e.arg(1)) {
+ case 3:
+ // We re-use the restarting flag here, to simulate a long jump
+ _isRestarting = true;
+ return -1;
+ }
+
+ return 1;
+}
+
+int AdlEngine_v4::o4_setDisk(ScriptEnv &e) {
+ OP_DEBUG_2("\tSET_DISK(%d, %d)", e.arg(1), e.arg(2));
+
+ // TODO
+ // Arg 1: disk
+ // Arg 2: room
+
+ return 2;
+}
+
+int AdlEngine_v4::o4_sound(ScriptEnv &e) {
+ OP_DEBUG_0("\tSOUND()");
+
+ // TODO
+
+ return 0;
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/adl_v4.h b/engines/adl/adl_v4.h
new file mode 100644
index 0000000000..dc9a27501e
--- /dev/null
+++ b/engines/adl/adl_v4.h
@@ -0,0 +1,73 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ADL_ADL_V4_H
+#define ADL_ADL_V4_H
+
+#include "adl/adl_v3.h"
+
+namespace Common {
+class RandomSource;
+}
+
+struct DiskOffset {
+ byte track;
+ byte sector;
+};
+
+namespace Adl {
+
+class AdlEngine_v4 : public AdlEngine_v3 {
+public:
+ virtual ~AdlEngine_v4() { }
+
+protected:
+ AdlEngine_v4(OSystem *syst, const AdlGameDescription *gd);
+
+ // AdlEngine
+ virtual void setupOpcodeTables();
+ virtual Common::String loadMessage(uint idx) const;
+ Common::String getItemDescription(const Item &item) const;
+
+ // AdlEngine_v2
+ virtual DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const;
+
+ void applyDiskOffset(byte &track, byte &sector) const;
+
+ int o4_isVarGT(ScriptEnv &e);
+ int o4_isItemInRoom(ScriptEnv &e);
+ int o4_isNounNotInRoom(ScriptEnv &e);
+ int o4_skipOneCommand(ScriptEnv &e);
+ int o4_listInv(ScriptEnv &e);
+ int o4_moveItem(ScriptEnv &e);
+ int o4_dummy(ScriptEnv &e);
+ int o4_setTextMode(ScriptEnv &e);
+ int o4_setDisk(ScriptEnv &e);
+ int o4_sound(ScriptEnv &e);
+
+ byte _curDisk;
+ Common::Array<DiskOffset> _diskOffsets;
+};
+
+} // End of namespace Adl
+
+#endif
diff --git a/engines/adl/detection.cpp b/engines/adl/detection.cpp
index 12405e7c5e..be9165b127 100644
--- a/engines/adl/detection.cpp
+++ b/engines/adl/detection.cpp
@@ -32,13 +32,15 @@
namespace Adl {
-#define GAMEOPTION_COLOR GUIO_GAMEOPTIONS1
-#define GAMEOPTION_SCANLINES GUIO_GAMEOPTIONS2
-#define GAMEOPTION_MONO GUIO_GAMEOPTIONS3
+// Mystery House was designed for monochrome display, so we default to
+// monochrome mode there. All the other games default to color mode.
+#define GAMEOPTION_COLOR_DEFAULT_OFF GUIO_GAMEOPTIONS1
+#define GAMEOPTION_SCANLINES GUIO_GAMEOPTIONS2
+#define GAMEOPTION_COLOR_DEFAULT_ON GUIO_GAMEOPTIONS3
static const ADExtraGuiOptionsMap optionsList[] = {
{
- GAMEOPTION_COLOR,
+ GAMEOPTION_COLOR_DEFAULT_OFF,
{
_s("Color mode"),
_s("Use color graphics"),
@@ -48,7 +50,7 @@ static const ADExtraGuiOptionsMap optionsList[] = {
},
{
- GAMEOPTION_MONO,
+ GAMEOPTION_COLOR_DEFAULT_ON,
{
_s("Color mode"),
_s("Use color graphics"),
@@ -74,6 +76,7 @@ static const PlainGameDescriptor adlGames[] = {
{ "hires0", "Hi-Res Adventure #0: Mission Asteroid" },
{ "hires1", "Hi-Res Adventure #1: Mystery House" },
{ "hires2", "Hi-Res Adventure #2: Wizard and the Princess" },
+ { "hires4", "Hi-Res Adventure #4: Ulysses and the Golden Fleece" },
{ "hires6", "Hi-Res Adventure #6: The Dark Crystal" },
{ 0, 0 }
};
@@ -89,9 +92,9 @@ static const AdlGameDescription gameDescriptions[] = {
AD_LISTEND
},
Common::EN_ANY,
- Common::kPlatformApple2GS, // FIXME
- ADGF_UNSTABLE,
- GUIO2(GAMEOPTION_COLOR, GAMEOPTION_SCANLINES)
+ Common::kPlatformApple2,
+ ADGF_TESTING,
+ GUIO2(GAMEOPTION_COLOR_DEFAULT_OFF, GAMEOPTION_SCANLINES)
},
GAME_TYPE_HIRES1
},
@@ -103,9 +106,9 @@ static const AdlGameDescription gameDescriptions[] = {
AD_LISTEND
},
Common::EN_ANY,
- Common::kPlatformApple2GS, // FIXME
- ADGF_UNSTABLE,
- GUIO2(GAMEOPTION_COLOR, GAMEOPTION_SCANLINES)
+ Common::kPlatformApple2,
+ ADGF_TESTING,
+ GUIO2(GAMEOPTION_COLOR_DEFAULT_OFF, GAMEOPTION_SCANLINES)
},
GAME_TYPE_HIRES1
},
@@ -117,9 +120,9 @@ static const AdlGameDescription gameDescriptions[] = {
AD_LISTEND
},
Common::EN_ANY,
- Common::kPlatformApple2GS, // FIXME
- ADGF_UNSTABLE,
- GUIO2(GAMEOPTION_MONO, GAMEOPTION_SCANLINES)
+ Common::kPlatformApple2,
+ ADGF_TESTING,
+ GUIO2(GAMEOPTION_COLOR_DEFAULT_ON, GAMEOPTION_SCANLINES)
},
GAME_TYPE_HIRES2
},
@@ -131,12 +134,27 @@ static const AdlGameDescription gameDescriptions[] = {
AD_LISTEND
},
Common::EN_ANY,
- Common::kPlatformApple2GS, // FIXME
- ADGF_UNSTABLE,
- GUIO2(GAMEOPTION_MONO, GAMEOPTION_SCANLINES)
+ Common::kPlatformApple2,
+ ADGF_TESTING,
+ GUIO2(GAMEOPTION_COLOR_DEFAULT_ON, GAMEOPTION_SCANLINES)
},
GAME_TYPE_HIRES0
},
+ { // Hi-Res Adventure #4: Ulysses and the Golden Fleece - Atari 8-bit - Re-release
+ {
+ "hires4", 0,
+ {
+ { "ULYS1A.XFD", 0, "26365d2b06509fd21e7a7919e33f7199", 92160 },
+ // FIXME: Add sides 1B and 2C
+ AD_LISTEND
+ },
+ Common::EN_ANY,
+ Common::kPlatformAtariST, // FIXME
+ ADGF_UNSTABLE,
+ GUIO2(GAMEOPTION_COLOR_DEFAULT_ON, GAMEOPTION_SCANLINES)
+ },
+ GAME_TYPE_HIRES4
+ },
{ // Hi-Res Adventure #6: The Dark Crystal - Apple II - Roberta Williams Anthology
{
"hires6", 0,
@@ -148,9 +166,9 @@ static const AdlGameDescription gameDescriptions[] = {
AD_LISTEND
},
Common::EN_ANY,
- Common::kPlatformApple2GS, // FIXME
+ Common::kPlatformApple2,
ADGF_UNSTABLE,
- GUIO2(GAMEOPTION_MONO, GAMEOPTION_SCANLINES)
+ GUIO2(GAMEOPTION_COLOR_DEFAULT_ON, GAMEOPTION_SCANLINES)
},
GAME_TYPE_HIRES6
},
@@ -294,6 +312,8 @@ void AdlMetaEngine::removeSaveState(const char *target, int slot) const {
Engine *HiRes1Engine_create(OSystem *syst, const AdlGameDescription *gd);
Engine *HiRes2Engine_create(OSystem *syst, const AdlGameDescription *gd);
+Engine *HiRes0Engine_create(OSystem *syst, const AdlGameDescription *gd);
+Engine *HiRes4Engine_create(OSystem *syst, const AdlGameDescription *gd);
Engine *HiRes6Engine_create(OSystem *syst, const AdlGameDescription *gd);
bool AdlMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const {
@@ -309,6 +329,12 @@ bool AdlMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameD
case GAME_TYPE_HIRES2:
*engine = HiRes2Engine_create(syst, adlGd);
break;
+ case GAME_TYPE_HIRES0:
+ *engine = HiRes0Engine_create(syst, adlGd);
+ break;
+ case GAME_TYPE_HIRES4:
+ *engine = HiRes4Engine_create(syst, adlGd);
+ break;
case GAME_TYPE_HIRES6:
*engine = HiRes6Engine_create(syst, adlGd);
break;
diff --git a/engines/adl/detection.h b/engines/adl/detection.h
index 533466c094..b4dc3c430f 100644
--- a/engines/adl/detection.h
+++ b/engines/adl/detection.h
@@ -35,6 +35,7 @@ enum GameType {
GAME_TYPE_HIRES0,
GAME_TYPE_HIRES1,
GAME_TYPE_HIRES2,
+ GAME_TYPE_HIRES4,
GAME_TYPE_HIRES6
};
diff --git a/engines/adl/disk.cpp b/engines/adl/disk.cpp
index 214f76aeae..49e01f9d0f 100644
--- a/engines/adl/disk.cpp
+++ b/engines/adl/disk.cpp
@@ -28,98 +28,63 @@
namespace Adl {
-const DataBlockPtr DiskImage_DSK::getDataBlock(uint track, uint sector, uint offset, uint size) const {
- return Common::SharedPtr<DiskImage::DataBlock>(new DiskImage::DataBlock(this, track, sector, offset, size));
-}
-
-Common::SeekableReadStream *DiskImage_DSK::createReadStream(uint track, uint sector, uint offset, uint size) const {
- _f->seek((track * _sectorsPerTrack + sector) * _bytesPerSector + offset);
- Common::SeekableReadStream *stream = _f->readStream(size * _bytesPerSector + _bytesPerSector - offset);
-
- if (_f->eos() || _f->err())
- error("Error reading disk image");
-
- return stream;
-}
-
-bool DiskImage_DSK::open(const Common::String &filename) {
- assert(!_f->isOpen());
-
- if (!_f->open(filename))
- return false;
-
- uint filesize = _f->size();
- switch (filesize) {
- case 143360:
- _tracks = 35;
- _sectorsPerTrack = 16;
- _bytesPerSector = 256;
- break;
- default:
- warning("Unrecognized disk image '%s' of size %d bytes", filename.c_str(), filesize);
- return false;
+#define TRACKS 35
+// The Apple II uses either 13- or 16-sector disks. We currently pad out
+// 13-sector disks, so we set SECTORS_PER_TRACK to 16 here.
+#define SECTORS_PER_TRACK 16
+#define BYTES_PER_SECTOR 256
+#define RAW_IMAGE_SIZE(S) (TRACKS * (S) * BYTES_PER_SECTOR)
+#define NIB_IMAGE_SIZE (RAW_IMAGE_SIZE(13) * 2)
+
+static Common::SeekableReadStream *readImage_DSK(const Common::String &filename) {
+ Common::File *f = new Common::File;
+
+ if (!f->open(filename)) {
+ delete f;
+ return nullptr;
}
- return true;
-}
-
-const DataBlockPtr DiskImage_NIB::getDataBlock(uint track, uint sector, uint offset, uint size) const {
- return Common::SharedPtr<DiskImage::DataBlock>(new DiskImage::DataBlock(this, track, sector, offset, size));
-}
-
-Common::SeekableReadStream *DiskImage_NIB::createReadStream(uint track, uint sector, uint offset, uint size) const {
- _memStream->seek((track * _sectorsPerTrack + sector) * _bytesPerSector + offset);
- Common::SeekableReadStream *stream = _memStream->readStream(size * _bytesPerSector + _bytesPerSector - offset);
-
- if (_memStream->eos() || _memStream->err())
- error("Error reading NIB image");
+ if (f->size() != RAW_IMAGE_SIZE(16))
+ error("Unrecognized DSK image '%s' of size %d bytes", filename.c_str(), f->size());
- return stream;
+ return f;
}
// 4-and-4 encoding (odd-even)
-static uint8 read44(Common::SeekableReadStream *f) {
+static uint8 read44(Common::SeekableReadStream &f) {
// 1s in the other fields, so we can just AND
- uint8 ret = f->readByte();
- return ((ret << 1) | 1) & f->readByte();
+ uint8 ret = f.readByte();
+ return ((ret << 1) | 1) & f.readByte();
}
-bool DiskImage_NIB::open(const Common::String &filename) {
- assert(!_f->isOpen());
+static Common::SeekableReadStream *readImage_NIB(const Common::String &filename) {
+ Common::File f;
- if (!_f->open(filename))
- return false;
+ if (!f.open(filename))
+ return nullptr;
- uint filesize = _f->size();
- switch (filesize) {
- case 232960:
- _tracks = 35;
- _sectorsPerTrack = 16; // we always pad it out
- _bytesPerSector = 256;
- break;
- default:
- error("Unrecognized NIB image '%s' of size %d bytes", filename.c_str(), filesize);
- }
+ if (f.size() != NIB_IMAGE_SIZE)
+ error("Unrecognized NIB image '%s' of size %d bytes", filename.c_str(), f.size());
// starting at 0xaa, 32 is invalid (see below)
const byte c_5and3_lookup[] = { 32, 0, 32, 1, 2, 3, 32, 32, 32, 32, 32, 4, 5, 6, 32, 32, 7, 8, 32, 9, 10, 11, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 12, 13, 32, 32, 14, 15, 32, 16, 17, 18, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 19, 20, 32, 21, 22, 23, 32, 32, 32, 32, 32, 24, 25, 26, 32, 32, 27, 28, 32, 29, 30, 31 };
// starting at 0x96, 64 is invalid (see below)
const byte c_6and2_lookup[] = { 0, 1, 64, 64, 2, 3, 64, 4, 5, 6, 64, 64, 64, 64, 64, 64, 7, 8, 64, 64, 64, 9, 10, 11, 12, 13, 64, 64, 14, 15, 16, 17, 18, 19, 64, 20, 21, 22, 23, 24, 25, 26, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 27, 64, 28, 29, 30, 64, 64, 64, 31, 64, 64, 32, 33, 64, 34, 35, 36, 37, 38, 39, 40, 64, 64, 64, 64, 64, 41, 42, 43, 64, 44, 45, 46, 47, 48, 49, 50, 64, 64, 51, 52, 53, 54, 55, 56, 64, 57, 58, 59, 60, 61, 62, 63 };
- uint32 diskSize = _tracks * _sectorsPerTrack * _bytesPerSector;
- byte *diskImage = (byte *)calloc(diskSize, 1);
- _memStream = new Common::MemoryReadStream(diskImage, diskSize, DisposeAfterUse::YES);
+ // we always pad it out
+ const uint sectorsPerTrack = 16;
+ byte *diskImage = (byte *)calloc(RAW_IMAGE_SIZE(sectorsPerTrack), 1);
bool sawAddress = false;
uint8 volNo, track, sector;
bool newStyle;
- while (_f->pos() < _f->size()) {
+ while (f.pos() < f.size()) {
// Read until we find two sync bytes.
- if (_f->readByte() != 0xd5 || _f->readByte() != 0xaa)
+ if (f.readByte() != 0xd5 || f.readByte() != 0xaa)
continue;
- byte prologue = _f->readByte();
+ byte prologue = f.readByte();
if (sawAddress && (prologue == 0xb5 || prologue == 0x96)) {
warning("NIB: data for %02x/%02x/%02x missing", volNo, track, sector);
@@ -140,21 +105,13 @@ bool DiskImage_NIB::open(const Common::String &filename) {
}
}
- volNo = read44(_f);
- track = read44(_f);
- sector = read44(_f);
- uint8 checksum = read44(_f);
+ volNo = read44(f);
+ track = read44(f);
+ sector = read44(f);
+ uint8 checksum = read44(f);
if ((volNo ^ track ^ sector) != checksum)
error("invalid NIB checksum");
- // FIXME: This is a hires0/hires2-specific hack.
- if (volNo == 0xfe) {
- if (track == 1)
- track = 2;
- else if (track == 2)
- track = 1;
- }
-
// Epilogue is de/aa plus a gap, but we don't care.
continue;
}
@@ -163,17 +120,17 @@ bool DiskImage_NIB::open(const Common::String &filename) {
// We should always find the data field after an address field.
// TODO: we ignore volNo?
- byte *output = diskImage + (track * _sectorsPerTrack + sector) * _bytesPerSector;
+ byte *output = diskImage + (track * sectorsPerTrack + sector) * BYTES_PER_SECTOR;
if (newStyle) {
// We hardcode the DOS 3.3 mapping here. TODO: Do we also need raw/prodos?
int raw2dos[16] = { 0, 7, 14, 6, 13, 5, 12, 4, 11, 3, 10, 2, 9, 1, 8, 15 };
sector = raw2dos[sector];
- output = diskImage + (track * _sectorsPerTrack + sector) * _bytesPerSector;
+ output = diskImage + (track * sectorsPerTrack + sector) * BYTES_PER_SECTOR;
// 6-and-2 uses 342 on-disk bytes
byte inbuffer[342];
- _f->read(inbuffer, 342);
+ f.read(inbuffer, 342);
byte oldVal = 0;
for (uint n = 0; n < 342; ++n) {
@@ -188,7 +145,7 @@ bool DiskImage_NIB::open(const Common::String &filename) {
inbuffer[n] = oldVal;
}
- byte checksum = _f->readByte();
+ byte checksum = f.readByte();
if (checksum < 0x96 || oldVal != c_6and2_lookup[checksum - 0x96])
warning("NIB: checksum mismatch @ (%x, %x)", track, sector);
@@ -208,7 +165,7 @@ bool DiskImage_NIB::open(const Common::String &filename) {
} else {
// 5-and-3 uses 410 on-disk bytes, decoding to just over 256 bytes
byte inbuffer[410];
- _f->read(inbuffer, 410);
+ f.read(inbuffer, 410);
bool truncated = false;
byte oldVal = 0;
@@ -218,16 +175,16 @@ bool DiskImage_NIB::open(const Common::String &filename) {
if (inbuffer[n] == 0xd5) {
// Early end of block.
truncated = true;
- _f->seek(-(410 - n), SEEK_CUR);
- warning("NIB: early end of block @ 0x%x (%x, %x)", _f->pos(), track, sector);
+ f.seek(-(410 - n), SEEK_CUR);
+ warning("NIB: early end of block @ 0x%x (%x, %x)", f.pos(), track, sector);
break;
}
byte val = c_5and3_lookup[inbuffer[n] - 0xaa];
if (val == 0x20) {
// Badly-encoded nibbles, stop trying to decode here.
truncated = true;
- warning("NIB: bad nibble %02x @ 0x%x (%x, %x)", inbuffer[n], _f->pos(), track, sector);
- _f->seek(-(410 - n), SEEK_CUR);
+ warning("NIB: bad nibble %02x @ 0x%x (%x, %x)", inbuffer[n], f.pos(), track, sector);
+ f.seek(-(410 - n), SEEK_CUR);
break;
}
// undo checksum
@@ -235,7 +192,7 @@ bool DiskImage_NIB::open(const Common::String &filename) {
inbuffer[n] = oldVal;
}
if (!truncated) {
- byte checksum = _f->readByte();
+ byte checksum = f.readByte();
if (checksum < 0xaa || oldVal != c_5and3_lookup[checksum - 0xaa])
warning("NIB: checksum mismatch @ (%x, %x)", track, sector);
}
@@ -259,7 +216,52 @@ bool DiskImage_NIB::open(const Common::String &filename) {
}
}
- return true;
+ return new Common::MemoryReadStream(diskImage, RAW_IMAGE_SIZE(sectorsPerTrack), DisposeAfterUse::YES);
+}
+
+bool DiskImage::open(const Common::String &filename) {
+ Common::String lcName(filename);
+ lcName.toLowercase();
+
+ if (lcName.hasSuffix(".dsk"))
+ _stream = readImage_DSK(filename);
+ else if (lcName.hasSuffix(".nib"))
+ _stream = readImage_NIB(filename);
+
+ return _stream != nullptr;
+}
+
+const DataBlockPtr DiskImage::getDataBlock(uint track, uint sector, uint offset, uint size) const {
+ return DataBlockPtr(new DiskImage::DataBlock(this, track, sector, offset, size, _mode13));
+}
+
+Common::SeekableReadStream *DiskImage::createReadStream(uint track, uint sector, uint offset, uint size, uint sectorsPerTrackToRead) const {
+ const uint bytesToRead = size * BYTES_PER_SECTOR + BYTES_PER_SECTOR - offset;
+ byte *const data = (byte *)malloc(bytesToRead);
+ uint dataOffset = 0;
+
+ if (sector > sectorsPerTrackToRead - 1)
+ error("Sector %i is out of bounds for %i-sector reading", sector, sectorsPerTrackToRead);
+
+ while (dataOffset < bytesToRead) {
+ uint bytesRemInTrack = (sectorsPerTrackToRead - 1 - sector) * BYTES_PER_SECTOR + BYTES_PER_SECTOR - offset;
+ _stream->seek((track * SECTORS_PER_TRACK + sector) * BYTES_PER_SECTOR + offset);
+
+ if (bytesToRead - dataOffset < bytesRemInTrack)
+ bytesRemInTrack = bytesToRead - dataOffset;
+
+ if (_stream->read(data + dataOffset, bytesRemInTrack) < bytesRemInTrack)
+ error("Error reading disk image");
+
+ ++track;
+
+ sector = 0;
+ offset = 0;
+
+ dataOffset += bytesRemInTrack;
+ }
+
+ return new Common::MemoryReadStream(data, bytesToRead, DisposeAfterUse::YES);
}
const DataBlockPtr Files_Plain::getDataBlock(const Common::String &filename, uint offset) const {
@@ -449,7 +451,7 @@ Common::SeekableReadStream *Files_DOS33::createReadStream(const Common::String &
}
bool Files_DOS33::open(const Common::String &filename) {
- _disk = new DiskImage_DSK();
+ _disk = new DiskImage();
if (!_disk->open(filename))
return false;
diff --git a/engines/adl/disk.h b/engines/adl/disk.h
index 43b9e387ba..1041f0cebd 100644
--- a/engines/adl/disk.h
+++ b/engines/adl/disk.h
@@ -73,41 +73,41 @@ protected:
class DiskImage {
public:
DiskImage() :
- _tracks(0),
- _sectorsPerTrack(0),
- _bytesPerSector(0) {
- _f = new Common::File();
- }
+ _stream(nullptr),
+ _mode13(false) { }
- virtual ~DiskImage() {
- delete _f;
+ ~DiskImage() {
+ delete _stream;
}
- virtual bool open(const Common::String &filename) = 0;
- virtual const DataBlockPtr getDataBlock(uint track, uint sector, uint offset = 0, uint size = 0) const = 0;
- virtual Common::SeekableReadStream *createReadStream(uint track, uint sector, uint offset = 0, uint size = 0) const = 0;
+ bool open(const Common::String &filename);
+ const DataBlockPtr getDataBlock(uint track, uint sector, uint offset = 0, uint size = 0) const;
+ Common::SeekableReadStream *createReadStream(uint track, uint sector, uint offset = 0, uint size = 0, uint sectorsPerTrackToRead = 16) const;
+ void setMode13(bool enable) { _mode13 = enable; }
protected:
class DataBlock : public Adl::DataBlock {
public:
- DataBlock(const DiskImage *disk, uint track, uint sector, uint offset, uint size) :
+ DataBlock(const DiskImage *disk, uint track, uint sector, uint offset, uint size, bool mode13) :
_track(track),
_sector(sector),
_offset(offset),
_size(size),
+ _mode13(mode13),
_disk(disk) { }
Common::SeekableReadStream *createReadStream() const {
- return _disk->createReadStream(_track, _sector, _offset, _size);
+ return _disk->createReadStream(_track, _sector, _offset, _size, (_mode13 ? 13 : 16));
}
private:
uint _track, _sector, _offset, _size;
+ bool _mode13;
const DiskImage *_disk;
};
- Common::File *_f;
- uint _tracks, _sectorsPerTrack, _bytesPerSector;
+ Common::SeekableReadStream *_stream;
+ bool _mode13; // Older 13-sector format
};
// Data in plain files
@@ -117,30 +117,6 @@ public:
Common::SeekableReadStream *createReadStream(const Common::String &filename, uint offset = 0) const;
};
-// .DSK disk image - 35 tracks, 16 sectors per track, 256 bytes per sector
-class DiskImage_DSK : public DiskImage {
-public:
- bool open(const Common::String &filename);
- const DataBlockPtr getDataBlock(uint track, uint sector, uint offset = 0, uint size = 0) const;
- Common::SeekableReadStream *createReadStream(uint track, uint sector, uint offset = 0, uint size = 0) const;
-};
-
-// .NIB disk image
-class DiskImage_NIB : public DiskImage {
-public:
- DiskImage_NIB() : _memStream(nullptr) { }
- virtual ~DiskImage_NIB() {
- delete _memStream;
- }
-
- bool open(const Common::String &filename);
- const DataBlockPtr getDataBlock(uint track, uint sector, uint offset = 0, uint size = 0) const;
- Common::SeekableReadStream *createReadStream(uint track, uint sector, uint offset = 0, uint size = 0) const;
-
-private:
- Common::SeekableReadStream *_memStream;
-};
-
// Data in files contained in Apple DOS 3.3 disk image
class Files_DOS33 : public Files {
public:
diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp
index b7f6eb9923..2cf50f72fc 100644
--- a/engines/adl/display.cpp
+++ b/engines/adl/display.cpp
@@ -55,6 +55,9 @@ static const byte colorPalette[COLOR_PALETTE_ENTRIES * 3] = {
0xf2, 0x5e, 0x00
};
+// Opacity of the optional scanlines (percentage)
+#define SCANLINE_OPACITY 75
+
// Corresponding color in second palette
#define PAL2(X) ((X) | 0x04)
@@ -109,8 +112,6 @@ Display::Display() :
_cursorPos(0),
_showCursor(false) {
- initGraphics(DISPLAY_WIDTH * 2, DISPLAY_HEIGHT * 2, true);
-
_monochrome = !ConfMan.getBool("color");
_scanlines = ConfMan.getBool("scanlines");
@@ -135,6 +136,8 @@ Display::Display() :
_textBufSurface->create(DISPLAY_WIDTH * 2, DISPLAY_HEIGHT * 2, Graphics::PixelFormat::createFormatCLUT8());
createFont();
+
+ _startMillis = g_system->getMillis();
}
Display::~Display() {
@@ -334,14 +337,16 @@ void Display::writeFrameBuffer(const Common::Point &p, byte color, byte mask) {
}
void Display::showScanlines(bool enable) {
- byte pal[COLOR_PALETTE_ENTRIES * 3] = { };
+ byte pal[COLOR_PALETTE_ENTRIES * 3];
- if (enable)
- g_system->getPaletteManager()->setPalette(pal, COLOR_PALETTE_ENTRIES, COLOR_PALETTE_ENTRIES);
- else {
- g_system->getPaletteManager()->grabPalette(pal, 0, COLOR_PALETTE_ENTRIES);
- g_system->getPaletteManager()->setPalette(pal, COLOR_PALETTE_ENTRIES, COLOR_PALETTE_ENTRIES);
+ g_system->getPaletteManager()->grabPalette(pal, 0, COLOR_PALETTE_ENTRIES);
+
+ if (enable) {
+ for (uint i = 0; i < ARRAYSIZE(pal); ++i)
+ pal[i] = pal[i] * (100 - SCANLINE_OPACITY) / 100;
}
+
+ g_system->getPaletteManager()->setPalette(pal, COLOR_PALETTE_ENTRIES, COLOR_PALETTE_ENTRIES);
}
static byte processColorBits(uint16 &bits, bool &odd, bool secondPal) {
@@ -489,7 +494,11 @@ void Display::updateTextSurface() {
r.translate(((c & 0x3f) % 16) * 7 * 2, (c & 0x3f) / 16 * 8 * 2);
if (!(c & 0x80)) {
- if (!(c & 0x40) || ((g_system->getMillis() / 270) & 1))
+ // Blink text. We subtract _startMillis to make this compatible
+ // with the event recorder, which returns offsetted values on
+ // playback.
+ const uint32 millisPassed = g_system->getMillis() - _startMillis;
+ if (!(c & 0x40) || ((millisPassed / 270) & 1))
r.translate(0, 4 * 8 * 2);
}
diff --git a/engines/adl/display.h b/engines/adl/display.h
index bc27b7cb6b..e761e63f2e 100644
--- a/engines/adl/display.h
+++ b/engines/adl/display.h
@@ -102,6 +102,7 @@ private:
Graphics::Surface *_font;
uint _cursorPos;
bool _showCursor;
+ uint32 _startMillis;
};
} // End of namespace Adl
diff --git a/engines/adl/hires0.cpp b/engines/adl/hires0.cpp
new file mode 100644
index 0000000000..a348779e89
--- /dev/null
+++ b/engines/adl/hires0.cpp
@@ -0,0 +1,168 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/textconsole.h"
+
+#include "adl/hires0.h"
+#include "adl/graphics.h"
+#include "adl/disk.h"
+
+namespace Adl {
+
+void HiRes0Engine::init() {
+ _graphics = new Graphics_v2(*_display);
+
+ _disk = new DiskImage();
+ if (!_disk->open(IDS_HR0_DISK_IMAGE))
+ error("Failed to open disk image '" IDS_HR0_DISK_IMAGE "'");
+
+ _disk->setMode13(true);
+
+ StreamPtr stream(_disk->createReadStream(0x1f, 0x2, 0x00, 2));
+
+ // TODO: all these strings/offsets/etc are the same as hires2
+
+ for (uint i = 0; i < IDI_HR0_NUM_MESSAGES; ++i)
+ _messages.push_back(readDataBlockPtr(*stream));
+
+ // Read parser messages
+ stream.reset(_disk->createReadStream(0x1a, 0x1));
+ _strings.verbError = readStringAt(*stream, 0x4f);
+ _strings.nounError = readStringAt(*stream, 0x8e);
+ _strings.enterCommand = readStringAt(*stream, 0xbc);
+
+ // Read time string
+ stream.reset(_disk->createReadStream(0x19, 0x7, 0xd7));
+ _strings_v2.time = readString(*stream, 0xff);
+
+ // Read line feeds
+ stream.reset(_disk->createReadStream(0x19, 0xb, 0xf8, 1));
+ _strings.lineFeeds = readString(*stream);
+
+ // Read opcode strings
+ stream.reset(_disk->createReadStream(0x1a, 0x6, 0x00, 2));
+ _strings_v2.saveInsert = readStringAt(*stream, 0x5f);
+ _strings_v2.saveReplace = readStringAt(*stream, 0xe5);
+ _strings_v2.restoreInsert = readStringAt(*stream, 0x132);
+ _strings_v2.restoreReplace = readStringAt(*stream, 0x1c2);
+ _strings.playAgain = readStringAt(*stream, 0x225);
+ _strings.pressReturn = readStringAt(*stream, 0x25f);
+
+ _messageIds.cantGoThere = IDI_HR0_MSG_CANT_GO_THERE;
+ _messageIds.dontUnderstand = IDI_HR0_MSG_DONT_UNDERSTAND;
+ _messageIds.itemDoesntMove = IDI_HR0_MSG_ITEM_DOESNT_MOVE;
+ _messageIds.itemNotHere = IDI_HR0_MSG_ITEM_NOT_HERE;
+ _messageIds.thanksForPlaying = IDI_HR0_MSG_THANKS_FOR_PLAYING;
+
+ // Load global picture data
+ stream.reset(_disk->createReadStream(0x19, 0xa, 0x80, 0));
+ byte picNr;
+ while ((picNr = stream->readByte()) != 0xff) {
+ if (stream->eos() || stream->err())
+ error("Error reading global pic list");
+
+ _pictures[picNr] = readDataBlockPtr(*stream);
+ }
+
+ // Load item picture data
+ stream.reset(_disk->createReadStream(0x1e, 0x9, 0x05));
+ for (uint i = 0; i < IDI_HR0_NUM_ITEM_PICS; ++i) {
+ stream->readByte(); // number
+ _itemPics.push_back(readDataBlockPtr(*stream));
+ }
+
+ // Load commands from executable
+ stream.reset(_disk->createReadStream(0x1d, 0x7, 0x00, 2));
+ readCommands(*stream, _roomCommands);
+
+ stream.reset(_disk->createReadStream(0x1f, 0x7, 0x00, 3));
+ readCommands(*stream, _globalCommands);
+
+ // Load dropped item offsets
+ stream.reset(_disk->createReadStream(0x1b, 0x4, 0x15));
+ for (uint i = 0; i < IDI_HR0_NUM_ITEM_OFFSETS; ++i) {
+ Common::Point p;
+ p.x = stream->readByte();
+ p.y = stream->readByte();
+ _itemOffsets.push_back(p);
+ }
+
+ // Load verbs
+ stream.reset(_disk->createReadStream(0x19, 0x0, 0x00, 3));
+ loadWords(*stream, _verbs, _priVerbs);
+
+ // Load nouns
+ stream.reset(_disk->createReadStream(0x22, 0x2, 0x00, 2));
+ loadWords(*stream, _nouns, _priNouns);
+}
+
+void HiRes0Engine::initGameState() {
+ _state.vars.resize(IDI_HR0_NUM_VARS);
+
+ StreamPtr stream(_disk->createReadStream(0x21, 0x5, 0x0e, 2));
+
+ for (uint i = 0; i < IDI_HR0_NUM_ROOMS; ++i) {
+ Room room;
+ stream->readByte(); // number
+ for (uint j = 0; j < 6; ++j)
+ room.connections[j] = stream->readByte();
+ room.data = readDataBlockPtr(*stream);
+ room.picture = stream->readByte();
+ room.curPicture = stream->readByte();
+ room.isFirstTime = stream->readByte();
+ _state.rooms.push_back(room);
+ }
+
+ stream.reset(_disk->createReadStream(0x21, 0x0));
+
+ byte id;
+ while ((id = stream->readByte()) != 0xff) {
+ Item item = Item();
+ item.id = id;
+ item.noun = stream->readByte();
+ item.room = stream->readByte();
+ item.picture = stream->readByte();
+ item.isLineArt = stream->readByte();
+ item.position.x = stream->readByte();
+ item.position.y = stream->readByte();
+ item.state = stream->readByte();
+ item.description = stream->readByte();
+
+ stream->readByte(); // Struct size
+
+ byte picListSize = stream->readByte();
+
+ // Flag to keep track of what has been drawn on the screen
+ stream->readByte();
+
+ for (uint i = 0; i < picListSize; ++i)
+ item.roomPictures.push_back(stream->readByte());
+
+ _state.items.push_back(item);
+ }
+}
+
+Engine *HiRes0Engine_create(OSystem *syst, const AdlGameDescription *gd) {
+ return new HiRes0Engine(syst, gd);
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/hires0.h b/engines/adl/hires0.h
new file mode 100644
index 0000000000..a3d8845a4e
--- /dev/null
+++ b/engines/adl/hires0.h
@@ -0,0 +1,59 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ADL_HIRES0_H
+#define ADL_HIRES0_H
+
+#include "adl/adl_v2.h"
+
+namespace Adl {
+
+#define IDS_HR0_DISK_IMAGE "MISSION.NIB"
+
+#define IDI_HR0_NUM_ROOMS 43
+#define IDI_HR0_NUM_MESSAGES 142
+#define IDI_HR0_NUM_VARS 40
+#define IDI_HR0_NUM_ITEM_PICS 2
+#define IDI_HR0_NUM_ITEM_OFFSETS 16
+
+// Messages used outside of scripts
+#define IDI_HR0_MSG_CANT_GO_THERE 110
+#define IDI_HR0_MSG_DONT_UNDERSTAND 112
+#define IDI_HR0_MSG_ITEM_DOESNT_MOVE 114
+#define IDI_HR0_MSG_ITEM_NOT_HERE 115
+#define IDI_HR0_MSG_THANKS_FOR_PLAYING 113
+
+class HiRes0Engine : public AdlEngine_v2 {
+public:
+ HiRes0Engine(OSystem *syst, const AdlGameDescription *gd) :
+ AdlEngine_v2(syst, gd) { }
+ ~HiRes0Engine() { }
+
+private:
+ // AdlEngine
+ void init();
+ void initGameState();
+};
+
+} // End of namespace Adl
+
+#endif
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 096d8ef496..26565c03c3 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -338,6 +338,7 @@ void HiRes1Engine::loadRoom(byte roomNr) {
}
void HiRes1Engine::showRoom() {
+ _state.curPicture = getCurRoom().curPicture;
clearScreen();
loadRoom(_state.room);
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index d8e8a65e29..14db237d82 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -34,6 +34,10 @@
namespace Adl {
void HiRes2Engine::runIntro() const {
+ // This only works for the 16-sector re-release. The original
+ // release is not supported at this time, because we don't have
+ // access to it.
+ _disk->setMode13(false);
StreamPtr stream(_disk->createReadStream(0x00, 0xd, 0x17, 1));
_display->setMode(DISPLAY_MODE_TEXT);
@@ -45,15 +49,19 @@ void HiRes2Engine::runIntro() const {
_display->printString(str);
delay(2000);
+
+ _disk->setMode13(true);
}
void HiRes2Engine::init() {
_graphics = new Graphics_v2(*_display);
- _disk = new DiskImage_DSK();
+ _disk = new DiskImage();
if (!_disk->open(IDS_HR2_DISK_IMAGE))
error("Failed to open disk image '" IDS_HR2_DISK_IMAGE "'");
+ _disk->setMode13(true);
+
StreamPtr stream(_disk->createReadStream(0x1f, 0x2, 0x00, 4));
for (uint i = 0; i < IDI_HR2_NUM_MESSAGES; ++i)
diff --git a/engines/adl/hires4.cpp b/engines/adl/hires4.cpp
new file mode 100644
index 0000000000..22fd9c2f81
--- /dev/null
+++ b/engines/adl/hires4.cpp
@@ -0,0 +1,50 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/system.h"
+#include "common/debug.h"
+#include "common/error.h"
+#include "common/file.h"
+#include "common/stream.h"
+
+#include "adl/hires4.h"
+#include "adl/display.h"
+#include "adl/graphics.h"
+#include "adl/disk.h"
+
+namespace Adl {
+
+void HiRes4Engine::runIntro() const {
+}
+
+void HiRes4Engine::init() {
+ _graphics = new Graphics_v2(*_display);
+}
+
+void HiRes4Engine::initGameState() {
+}
+
+Engine *HiRes4Engine_create(OSystem *syst, const AdlGameDescription *gd) {
+ return new HiRes4Engine(syst, gd);
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/hires4.h b/engines/adl/hires4.h
new file mode 100644
index 0000000000..f1c429ce38
--- /dev/null
+++ b/engines/adl/hires4.h
@@ -0,0 +1,45 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ADL_HIRES4_H
+#define ADL_HIRES4_H
+
+#include "common/str.h"
+
+#include "adl/adl_v3.h"
+
+namespace Adl {
+
+class HiRes4Engine : public AdlEngine_v3 {
+public:
+ HiRes4Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine_v3(syst, gd) { }
+
+private:
+ // AdlEngine
+ void runIntro() const;
+ void init();
+ void initGameState();
+};
+
+} // End of namespace Adl
+
+#endif
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index c42b4165a6..e9df7b513a 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -69,7 +69,7 @@ static Common::MemoryReadStream *loadSectors(DiskImage *disk, byte track, byte s
}
void HiRes6Engine::runIntro() const {
- DiskImage_DSK *boot(new DiskImage_DSK());
+ DiskImage *boot(new DiskImage());
if (!boot->open(disks[0]))
error("Failed to open disk image '%s'", disks[0]);
@@ -109,7 +109,7 @@ void HiRes6Engine::runIntro() const {
}
void HiRes6Engine::init() {
- _boot = new DiskImage_DSK();
+ _boot = new DiskImage();
_graphics = new Graphics_v2(*_display);
if (!_boot->open(disks[0]))
@@ -177,7 +177,7 @@ void HiRes6Engine::init() {
void HiRes6Engine::loadDisk(byte disk) {
delete _disk;
- _disk = new DiskImage_NIB();
+ _disk = new DiskImage();
if (!_disk->open(disks[disk]))
error("Failed to open disk image '%s'", disks[disk]);
@@ -317,6 +317,8 @@ void HiRes6Engine::initGameState() {
}
void HiRes6Engine::showRoom() {
+ _state.curPicture = getCurRoom().curPicture;
+
bool redrawPic = false;
if (getVar(26) == 0xfe)
diff --git a/engines/adl/hires6.h b/engines/adl/hires6.h
index 4bd2bcc7cc..5ff039120b 100644
--- a/engines/adl/hires6.h
+++ b/engines/adl/hires6.h
@@ -25,7 +25,7 @@
#include "common/str.h"
-#include "adl/adl_v3.h"
+#include "adl/adl_v4.h"
#include "adl/disk.h"
namespace Common {
@@ -56,10 +56,10 @@ struct DiskDataDesc {
byte volume;
};
-class HiRes6Engine : public AdlEngine_v3 {
+class HiRes6Engine : public AdlEngine_v4 {
public:
HiRes6Engine(OSystem *syst, const AdlGameDescription *gd) :
- AdlEngine_v3(syst, gd),
+ AdlEngine_v4(syst, gd),
_boot(nullptr),
_currVerb(0),
_currNoun(0) {
@@ -82,7 +82,7 @@ private:
void loadDisk(byte disk);
- DiskImage_DSK *_boot;
+ DiskImage *_boot;
byte _currVerb, _currNoun;
Common::Array<DiskDataDesc> _diskDataDesc;
};
diff --git a/engines/adl/module.mk b/engines/adl/module.mk
index 7ab37efc67..d1de2a6c02 100644
--- a/engines/adl/module.mk
+++ b/engines/adl/module.mk
@@ -4,6 +4,7 @@ MODULE_OBJS := \
adl.o \
adl_v2.o \
adl_v3.o \
+ adl_v4.o \
console.o \
detection.o \
disk.o \
@@ -11,8 +12,10 @@ MODULE_OBJS := \
graphics.o \
graphics_v1.o \
graphics_v2.o \
+ hires0.o \
hires1.o \
hires2.o \
+ hires4.o \
hires6.o \
speaker.o