[Scummvm-cvs-logs] scummvm master -> 9acf6c3838d0aaaf5cff8ea120ec4672cf6fe6c8

waltervn walter at vanniftrik-it.nl
Mon Jun 6 20:43:39 CEST 2016


This automated email contains information about 117 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
ee0c5e4452 ADL: Add skeleton for Hi-Res #2
e49085b49d ADL: Implement hires2 title screen
ebb6ceb294 ADL: Load verbs and nouns for hires2
fe384e0ae0 ADL: Make room description hires1-only
c44f18a818 ADL: Load hires2 room data
641d87f752 ADL: Load (some) hires2 strings
930bdcfa91 ADL: Implement hires2 PIC drawing
60892c91a5 ADL: Rename PictureD to Graphics
148814b2a6 ADL: Move hires1 drawing functions into class
0686ba9de8 ADL: Clean up file error handling
b4aea80723 ADL: Implement hires2 word wrapping
0664b51d2f ADL: Add bell function
7cef93739c ADL: Hook up bell in hires2
1e5fff86c8 ADL: Fix hires2 message printing
0a6b7fb6a6 ADL: Add loading of room picture index for hires2
7ff7e0def4 ADL: Add hires2 command loading
46528f2c04 ADL: Fix flood fill palette setting
df4daf954f ADL: Load hires2 items
0593460b1b ADL: Enable global commands in hires2
a653fa2f45 ADL: Add partial hires2 item drawing
6fd580fb66 ADL: Add pic offsetting
c0b33afc4a ADL: Load hires2 dropped item offsets
64cf93198f ADL: Use functors to implement opcodes
eaacfe1eed ADL: Use template for direction opcode
37656db0d4 ADL: Clean up opcodes
a9afe17169 ADL: Replace opcode arg macro with function
f93ae5479e ADL: Make opcodes return arg count
0cb889b55e ADL: Remove unused opcode #defines
60a9a592f5 ADL: Clean up script handling
ddf1151a53 ADL: Add new class for second generation ADL
fab489c530 ADL: Rename IDI_ITEM_MOVED to IDI_ITEM_DROPPED
8d1901c39b ADL: Implement hires2 cond opcodes 0x01 and 0x04
ee8c63183d ADL: Implement hires2 random cond opcode
d09247baca ADL: Fix move counter
d8035140e2 ADL: Clean up opcodes
8a05a9cbca ADL: Implement final hires2 conditional opcode
3f7d5608a9 ADL: Implement a few hires2 opcodes
4ce697e2c3 ADL: Rename IDI_NONE to IDI_ANY
3102ff4a19 ADL: Clean up handling of room value 0xfc
e7c93489e4 ADL: Clean up drawItems()
a7a371c63d ADL: Implement time opcode
905e2cd63f ADL: Add hires2 opcode 0x20
3afcf67643 ADL: Stub init disk opcode
a82ac8973d ADL: Implement hires2 save/restore opcodes
ffbc4da0b0 ADL: Use display class to print init disk message
4af9f32d3f ADL: Add disk format abstraction
bfbacf9397 ADL: Use DiskImage class in hires2
f2de96512a ADL: Add file-based disk access class
5451df3afe ADL: Use new disk class in hires1
3b67b07364 ADL: Set ADGF_UNSTABLE
71ca8de7e6 ADL: Add support for Apple DOS 3.3 disk images
02563df422 ADL: Add support for hires1 disk image
7ee183ca48 ADL: Refactor disk classes
865bd06845 ADL: Move room-local commands into base class
c9824921b4 ADL: Move message delay code into hires1 class
41e8227637 ADL: Set room description in hires1
aa661fae5c ADL: Fix room loading in hires2
bd588d9615 ADL: Use HashMaps for room/global pics
42c41b4495 ADL: Load hires2 global pics
53e7ecb79c ADL: Remove unused DrawPic color parameter
d0f33851bc ADL: Fix regression in message loading
760d5ac733 ADL: Move drawPic() into base class
367cb511d1 ADL: Add Console
73dfe71b1b ADL: Add verbs and nouns debug commands
b24f30527b ADL: Add script dump and trace for hires1
2c8e0cefb1 ADL: Store items in a List instead of an Array
cf6bc0e438 ADL: Add script dump and trace for hires2
3b72a30c0f ADL: Clean up script dump debug command
dd5ce7ebbb ADL: Add valid_cmds debug command
3b7813d971 ADL: Fix debug print for MOVE_ALL_ITEMS
26b8e8d66a ADL: Use columns when printing verb/noun lists
9eb7af0f67 ADL: Add 'room' debugger command
fde2db9d4c ADL: Add items and give_item debug commands
23d4e61260 ADL: Fix hires2 item description debug printing
1d314b2084 ADL: Allow synonyms in give_item debug command
ff4b9fcd9c ADL: Add 'vars' debug command
1b9d712a8b ADL: Add 'var' debug command
d6f34eda99 ADL: Remove DataBlockPtr::isValid()
f275add1e5 ADL: Use pointer for hires2 disk image
4ee8cf4f9e ADL: Move some hires2 functionality into ADL_v2
97168fa200 ADL: Load line feeds string
09146fba6e ADL: Move restartGame() into opcode
b4a82370cd ADL: Partially fix hires2 restarting
adecc10674 ADL: Reset "lines printed" counter on restart
83d75c2f4c ADL: Clean-up
ed0653e393 ADL: Update save game format for hires2
bc0fc246f0 ADL: Implement hires2 screen update routine
d361f2e4b0 ADL: Add (experimental) support for NIB files
5db8f401a8 ADL: Add detection entry for hires0
e89f34857f ADL: Fix NIB track swapping hack
266e63453f ADL: Add support for newer NIB files
ae405707cc ADL: Add skeleton for hires6
7dc5f636f8 ADL: Map DOS 3.3 NIB to logical sectors
a320b319eb ADL: Load more hires6 data
1842d0c45f ADL: Add loadMessage function
4f932afd60 ADL: Load messages on demand
ca47d3bb22 ADL: Decrypt hires6 messages
6044022c8e ADL: Add '%' string code processing for hires6
8cc5100afd ADL: Fix OB1 bug in ADL v2 word wrapping
5fe95d51ea ADL: Separate game-specific state init
bf520ca321 ADL: Fix restarting from AllCommands list
7e9a8c0072 ADL: Partially implement hires6 var handling
b8c40f9a8b ADL: Implement hires6 cond opcode 0xa
bb6cd4612d ADL: Fix bug in hires6 printString
04604ed602 ADL: Implement hires6 showRoom() var handling
d2175a70ce ADL: Implement remaining hires6 conditionals
e79f26c9bc ADL: Implement hires6 item descriptions
e755f8fcba ADL: Implement hires6 "move item" opcode
92b1b287b1 ADL: Preliminary support for hires6 disk changing
2cdb1d49a5 ADL: Add stubs for hires6 opcodes
12fe7dabab ADL: Fix debug output in 'move all items' opcode
d435f5b4eb ADL: Fix item rendering in hires6
f8d75bbc86 ADL: Implement hires6 verb/noun error messages
0c2d2b2c92 ADL: Fix GCC 4.9 shadow warnings
9967ae8c52 ADL: Fix more GCC 4.9 shadow warnings
c71740bc5d ADL: Fix GCC 4.9 missing initializer warnings
9acf6c3838 ADL: Fix formatting


Commit: ee0c5e4452722fcee3304af26d209114b4c80f75
    https://github.com/scummvm/scummvm/commit/ee0c5e4452722fcee3304af26d209114b4c80f75
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Add skeleton for Hi-Res #2

Changed paths:
  A engines/adl/hires2.cpp
  A engines/adl/hires2.h
    engines/adl/detection.cpp
    engines/adl/detection.h
    engines/adl/module.mk



diff --git a/engines/adl/detection.cpp b/engines/adl/detection.cpp
index 1a8c502..3069f21 100644
--- a/engines/adl/detection.cpp
+++ b/engines/adl/detection.cpp
@@ -60,8 +60,9 @@ static const ADExtraGuiOptionsMap optionsList[] = {
 };
 
 static const PlainGameDescriptor adlGames[] = {
-	{"hires1", "Hi-Res Adventure #1: Mystery House"},
-	{0, 0}
+	{ "hires1", "Hi-Res Adventure #1: Mystery House" },
+	{ "hires2", "Hi-Res Adventure #2: Wizard and the Princess" },
+	{ 0, 0 }
 };
 
 static const AdlGameDescription gameDescriptions[] = {
@@ -69,9 +70,9 @@ static const AdlGameDescription gameDescriptions[] = {
 		{
 			"hires1", 0,
 			{
-				{"ADVENTURE", 0, "22d9e63a11d69fa033ba1738715ad09a", 29952},
-				{"AUTO LOAD OBJ", 0, "23bfccfe9fcff9b22cf6c41bde9078ac", 12291},
-				{"MYSTERY.HELLO", 0, "2289b7fea300b506e902a4c597968369", 836},
+				{ "ADVENTURE", 0, "22d9e63a11d69fa033ba1738715ad09a", 29952 },
+				{ "AUTO LOAD OBJ", 0, "23bfccfe9fcff9b22cf6c41bde9078ac", 12291 },
+				{ "MYSTERY.HELLO", 0, "2289b7fea300b506e902a4c597968369", 836 },
 				AD_LISTEND
 			},
 			Common::EN_ANY,
@@ -81,6 +82,20 @@ static const AdlGameDescription gameDescriptions[] = {
 		},
 		GAME_TYPE_HIRES1
 	},
+	{ // Hi-Res Adventure #2: Wizard and the Princess - Apple II - 1986 SierraVenture release
+		{
+			"hires2", 0,
+			{
+				{ "WIZARD.DSK", 0, "816fdfc35e25496213c8db40ecf26569", 143360 },
+				AD_LISTEND
+			},
+			Common::EN_ANY,
+			Common::kPlatformApple2GS, // FIXME
+			ADGF_NO_FLAGS,
+			GUIO1(GAMEOPTION_SCANLINES)
+		},
+		GAME_TYPE_HIRES2
+	},
 	{ AD_TABLE_END_MARKER, GAME_TYPE_NONE }
 };
 
@@ -220,6 +235,7 @@ 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);
 
 bool AdlMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const {
 	if (!gd)
@@ -231,6 +247,9 @@ bool AdlMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameD
 	case GAME_TYPE_HIRES1:
 		*engine = HiRes1Engine_create(syst, adlGd);
 		break;
+	case GAME_TYPE_HIRES2:
+		*engine = HiRes2Engine_create(syst, adlGd);
+		break;
 	default:
 		error("Unknown GameType");
 	}
diff --git a/engines/adl/detection.h b/engines/adl/detection.h
index c646aeb..4275286 100644
--- a/engines/adl/detection.h
+++ b/engines/adl/detection.h
@@ -32,7 +32,8 @@ namespace Adl {
 
 enum GameType {
 	GAME_TYPE_NONE,
-	GAME_TYPE_HIRES1
+	GAME_TYPE_HIRES1,
+	GAME_TYPE_HIRES2
 };
 
 struct AdlGameDescription {
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
new file mode 100644
index 0000000..25e0e6f
--- /dev/null
+++ b/engines/adl/hires2.cpp
@@ -0,0 +1,54 @@
+/* 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/hires2.h"
+#include "adl/display.h"
+
+namespace Adl {
+
+void HiRes2Engine::runIntro() const {
+}
+
+void HiRes2Engine::loadData() {
+}
+
+void HiRes2Engine::initState() {
+}
+
+void HiRes2Engine::restartGame() {
+	initState();
+}
+
+void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
+}
+
+Engine *HiRes2Engine_create(OSystem *syst, const AdlGameDescription *gd) {
+	return new HiRes2Engine(syst, gd);
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
new file mode 100644
index 0000000..005948a
--- /dev/null
+++ b/engines/adl/hires2.h
@@ -0,0 +1,52 @@
+/* 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_HIRES1_H
+#define ADL_HIRES1_H
+
+#include "common/str.h"
+
+#include "adl/adl.h"
+
+namespace Common {
+class ReadStream;
+class Point;
+}
+
+namespace Adl {
+
+class HiRes2Engine : public AdlEngine {
+public:
+	HiRes2Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine(syst, gd) { }
+
+private:
+	// AdlEngine
+	void runIntro() const;
+	void loadData();
+	void initState();
+	void restartGame();
+	void drawPic(byte pic, Common::Point pos) const;
+};
+
+} // End of namespace Adl
+
+#endif
diff --git a/engines/adl/module.mk b/engines/adl/module.mk
index 6acd06f..de69b52 100644
--- a/engines/adl/module.mk
+++ b/engines/adl/module.mk
@@ -4,7 +4,8 @@ MODULE_OBJS := \
 	adl.o \
 	detection.o \
 	display.o \
-	hires1.o
+	hires1.o \
+	hires2.o
 
 MODULE_DIRS += \
 	engines/adl


Commit: e49085b49d0ff0b2962923682db6770ef3c908dd
    https://github.com/scummvm/scummvm/commit/e49085b49d0ff0b2962923682db6770ef3c908dd
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Implement hires2 title screen

Changed paths:
    engines/adl/detection.cpp
    engines/adl/hires2.cpp
    engines/adl/hires2.h



diff --git a/engines/adl/detection.cpp b/engines/adl/detection.cpp
index 3069f21..81050d7 100644
--- a/engines/adl/detection.cpp
+++ b/engines/adl/detection.cpp
@@ -32,8 +32,9 @@
 
 namespace Adl {
 
-#define GAMEOPTION_COLOR      GUIO_GAMEOPTIONS1
-#define GAMEOPTION_SCANLINES  GUIO_GAMEOPTIONS2
+#define GAMEOPTION_COLOR     GUIO_GAMEOPTIONS1
+#define GAMEOPTION_SCANLINES GUIO_GAMEOPTIONS2
+#define GAMEOPTION_MONO      GUIO_GAMEOPTIONS3
 
 static const ADExtraGuiOptionsMap optionsList[] = {
 	{
@@ -47,6 +48,16 @@ static const ADExtraGuiOptionsMap optionsList[] = {
 	},
 
 	{
+		GAMEOPTION_MONO,
+		{
+			_s("Color mode"),
+			_s("Use color graphics"),
+			"color",
+			true
+		}
+	},
+
+	{
 		GAMEOPTION_SCANLINES,
 		{
 			_s("Scanlines"),
@@ -92,7 +103,7 @@ static const AdlGameDescription gameDescriptions[] = {
 			Common::EN_ANY,
 			Common::kPlatformApple2GS, // FIXME
 			ADGF_NO_FLAGS,
-			GUIO1(GAMEOPTION_SCANLINES)
+			GUIO2(GAMEOPTION_MONO, GAMEOPTION_SCANLINES)
 		},
 		GAME_TYPE_HIRES2
 	},
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 25e0e6f..f318ad3 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -32,6 +32,22 @@
 namespace Adl {
 
 void HiRes2Engine::runIntro() const {
+	Common::File f;
+
+	if (!f.open(IDS_HR2_DISK_IMAGE))
+		error("Failed to open file '" IDS_HR2_DISK_IMAGE "'");
+
+	f.seek(IDI_HR2_OFS_INTRO_TEXT);
+
+	_display->setMode(DISPLAY_MODE_TEXT);
+
+	Common::String str = readStringAt(f, IDI_HR2_OFS_INTRO_TEXT);
+
+	if (f.eos() || f.err())
+		error("Error reading disk image");
+
+	_display->printString(str);
+	delay(2000);
 }
 
 void HiRes2Engine::loadData() {
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 005948a..9bb7b98 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -34,6 +34,13 @@ class Point;
 
 namespace Adl {
 
+#define IDS_HR2_DISK_IMAGE "WIZARD.DSK"
+
+// Track, sector, offset
+#define TSO(T, S, O) (((T) * 16 + (S)) * 256 + (O))
+
+#define IDI_HR2_OFS_INTRO_TEXT TSO(0x00, 0xd, 0x17)
+
 class HiRes2Engine : public AdlEngine {
 public:
 	HiRes2Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine(syst, gd) { }


Commit: ebb6ceb2945084e73d1511a02d2ad8fe72d568e0
    https://github.com/scummvm/scummvm/commit/ebb6ceb2945084e73d1511a02d2ad8fe72d568e0
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Load verbs and nouns for hires2

Changed paths:
    engines/adl/hires2.cpp
    engines/adl/hires2.h



diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index f318ad3..1831266 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -51,6 +51,16 @@ void HiRes2Engine::runIntro() const {
 }
 
 void HiRes2Engine::loadData() {
+	Common::File f;
+
+	if (!f.open(IDS_HR2_DISK_IMAGE))
+		error("Failed to open file '" IDS_HR2_DISK_IMAGE "'");
+
+	f.seek(IDI_HR2_OFS_VERBS);
+	loadWords(f, _verbs);
+
+	f.seek(IDI_HR2_OFS_NOUNS);
+	loadWords(f, _nouns);
 }
 
 void HiRes2Engine::initState() {
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 9bb7b98..60c6ca1 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -37,9 +37,13 @@ namespace Adl {
 #define IDS_HR2_DISK_IMAGE "WIZARD.DSK"
 
 // Track, sector, offset
-#define TSO(T, S, O) (((T) * 16 + (S)) * 256 + (O))
+#define TSO(TRACK, SECTOR, OFFSET) (((TRACK) * 16 + (SECTOR)) * 256 + (OFFSET))
+#define TS(TRACK, SECTOR) TSO(TRACK, SECTOR, 0)
+#define T(TRACK) TS(TRACK, 0)
 
 #define IDI_HR2_OFS_INTRO_TEXT TSO(0x00, 0xd, 0x17)
+#define IDI_HR2_OFS_VERBS        T(0x19)
+#define IDI_HR2_OFS_NOUNS       TS(0x22, 0x2)
 
 class HiRes2Engine : public AdlEngine {
 public:


Commit: fe384e0ae09ec3e72d653cd9fd34ab047231e249
    https://github.com/scummvm/scummvm/commit/fe384e0ae09ec3e72d653cd9fd34ab047231e249
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Make room description hires1-only

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/hires1.cpp
    engines/adl/hires1.h
    engines/adl/hires2.cpp
    engines/adl/hires2.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 1ab74c3..47623d4 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -264,6 +264,186 @@ void AdlEngine::readCommands(Common::ReadStream &stream, Commands &commands) {
 	}
 }
 
+void AdlEngine::clearScreen() const {
+	_display->setMode(DISPLAY_MODE_MIXED);
+	_display->clear(0x00);
+}
+
+void AdlEngine::drawItems() const {
+	Common::Array<Item>::const_iterator item;
+
+	uint dropped = 0;
+
+	for (item = _state.items.begin(); item != _state.items.end(); ++item) {
+		if (item->room != _state.room)
+			continue;
+
+		if (item->state == IDI_ITEM_MOVED) {
+			if (getCurRoom().picture == getCurRoom().curPicture) {
+				const Common::Point &p =  _itemOffsets[dropped];
+				if (item->isLineArt)
+					drawLineArt(_lineArt[item->picture - 1], p);
+				else
+					drawPic(item->picture, p);
+				++dropped;
+			}
+			continue;
+		}
+
+		Common::Array<byte>::const_iterator pic;
+
+		for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
+			if (*pic == getCurRoom().curPicture) {
+				if (item->isLineArt)
+					drawLineArt(_lineArt[item->picture - 1], item->position);
+				else
+					drawPic(item->picture, item->position);
+				continue;
+			}
+		}
+	}
+}
+
+void AdlEngine::drawNextPixel(Common::Point &p, byte color, byte bits, byte quadrant) const {
+	if (bits & 4)
+		_display->putPixel(p, color);
+
+	bits += quadrant;
+
+	if (bits & 1)
+		p.x += (bits & 2 ? -1 : 1);
+	else
+		p.y += (bits & 2 ? 1 : -1);
+}
+
+void AdlEngine::drawLineArt(const Common::Array<byte> &lineArt, const Common::Point &pos, byte rotation, byte scaling, byte color) const {
+	const byte stepping[] = {
+		0xff, 0xfe, 0xfa, 0xf4, 0xec, 0xe1, 0xd4, 0xc5,
+		0xb4, 0xa1, 0x8d, 0x78, 0x61, 0x49, 0x31, 0x18,
+		0xff
+	};
+
+	byte quadrant = rotation >> 4;
+	rotation &= 0xf;
+	byte xStep = stepping[rotation];
+	byte yStep = stepping[(rotation ^ 0xf) + 1] + 1;
+
+	Common::Point p(pos);
+
+	for (uint i = 0; i < lineArt.size(); ++i) {
+		byte b = lineArt[i];
+
+		do {
+			byte xFrac = 0x80;
+			byte yFrac = 0x80;
+			for (uint j = 0; j < scaling; ++j) {
+				if (xFrac + xStep + 1 > 255)
+					drawNextPixel(p, color, b, quadrant);
+				xFrac += xStep + 1;
+				if (yFrac + yStep > 255)
+					drawNextPixel(p, color, b, quadrant + 1);
+				yFrac += yStep;
+			}
+			b >>= 3;
+		} while (b != 0);
+	}
+}
+
+const Room &AdlEngine::getRoom(uint i) const {
+	if (i < 1 || i > _state.rooms.size())
+		error("Room %i out of range [1, %i]", i, _state.rooms.size());
+
+	return _state.rooms[i - 1];
+}
+
+Room &AdlEngine::getRoom(uint i) {
+	if (i < 1 || i > _state.rooms.size())
+		error("Room %i out of range [1, %i]", i, _state.rooms.size());
+
+	return _state.rooms[i - 1];
+}
+
+const Room &AdlEngine::getCurRoom() const {
+	return getRoom(_state.room);
+}
+
+Room &AdlEngine::getCurRoom() {
+	return getRoom(_state.room);
+}
+
+const Item &AdlEngine::getItem(uint i) const {
+	if (i < 1 || i > _state.items.size())
+		error("Item %i out of range [1, %i]", i, _state.items.size());
+
+	return _state.items[i - 1];
+}
+
+Item &AdlEngine::getItem(uint i) {
+	if (i < 1 || i > _state.items.size())
+		error("Item %i out of range [1, %i]", i, _state.items.size());
+
+	return _state.items[i - 1];
+}
+
+byte AdlEngine::getVar(uint i) const {
+	if (i >= _state.vars.size())
+		error("Variable %i out of range [0, %i]", i, _state.vars.size() - 1);
+
+	return _state.vars[i];
+}
+
+void AdlEngine::setVar(uint i, byte value) {
+	if (i >= _state.vars.size())
+		error("Variable %i out of range [0, %i]", i, _state.vars.size() - 1);
+
+	_state.vars[i] = value;
+}
+
+void AdlEngine::takeItem(byte noun) {
+	Common::Array<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_MOVED) {
+			item->room = IDI_NONE;
+			return;
+		}
+
+		Common::Array<byte>::const_iterator pic;
+		for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
+			if (*pic == getCurRoom().curPicture) {
+				item->room = IDI_NONE;
+				item->state = IDI_ITEM_MOVED;
+				return;
+			}
+		}
+	}
+
+	printMessage(_messageIds.itemNotHere);
+}
+
+void AdlEngine::dropItem(byte noun) {
+	Common::Array<Item>::iterator item;
+
+	for (item = _state.items.begin(); item != _state.items.end(); ++item) {
+		if (item->noun != noun || item->room != IDI_NONE)
+			continue;
+
+		item->room = _state.room;
+		item->state = IDI_ITEM_MOVED;
+		return;
+	}
+
+	printMessage(_messageIds.dontUnderstand);
+}
+
 Common::Error AdlEngine::run() {
 	_display = new Display();
 
@@ -636,196 +816,6 @@ void AdlEngine::getInput(uint &verb, uint &noun) {
 	}
 }
 
-void AdlEngine::showRoom() const {
-	if (!_state.isDark) {
-		drawPic(getCurRoom().curPicture);
-		drawItems();
-	}
-
-	_display->updateHiResScreen();
-	printMessage(getCurRoom().description, false);
-}
-
-void AdlEngine::clearScreen() const {
-	_display->setMode(DISPLAY_MODE_MIXED);
-	_display->clear(0x00);
-}
-
-void AdlEngine::drawItems() const {
-	Common::Array<Item>::const_iterator item;
-
-	uint dropped = 0;
-
-	for (item = _state.items.begin(); item != _state.items.end(); ++item) {
-		if (item->room != _state.room)
-			continue;
-
-		if (item->state == IDI_ITEM_MOVED) {
-			if (getCurRoom().picture == getCurRoom().curPicture) {
-				const Common::Point &p =  _itemOffsets[dropped];
-				if (item->isLineArt)
-					drawLineArt(_lineArt[item->picture - 1], p);
-				else
-					drawPic(item->picture, p);
-				++dropped;
-			}
-			continue;
-		}
-
-		Common::Array<byte>::const_iterator pic;
-
-		for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
-			if (*pic == getCurRoom().curPicture) {
-				if (item->isLineArt)
-					drawLineArt(_lineArt[item->picture - 1], item->position);
-				else
-					drawPic(item->picture, item->position);
-				continue;
-			}
-		}
-	}
-}
-
-void AdlEngine::drawNextPixel(Common::Point &p, byte color, byte bits, byte quadrant) const {
-	if (bits & 4)
-		_display->putPixel(p, color);
-
-	bits += quadrant;
-
-	if (bits & 1)
-		p.x += (bits & 2 ? -1 : 1);
-	else
-		p.y += (bits & 2 ? 1 : -1);
-}
-
-void AdlEngine::drawLineArt(const Common::Array<byte> &lineArt, const Common::Point &pos, byte rotation, byte scaling, byte color) const {
-	const byte stepping[] = {
-		0xff, 0xfe, 0xfa, 0xf4, 0xec, 0xe1, 0xd4, 0xc5,
-		0xb4, 0xa1, 0x8d, 0x78, 0x61, 0x49, 0x31, 0x18,
-		0xff
-	};
-
-	byte quadrant = rotation >> 4;
-	rotation &= 0xf;
-	byte xStep = stepping[rotation];
-	byte yStep = stepping[(rotation ^ 0xf) + 1] + 1;
-
-	Common::Point p(pos);
-
-	for (uint i = 0; i < lineArt.size(); ++i) {
-		byte b = lineArt[i];
-
-		do {
-			byte xFrac = 0x80;
-			byte yFrac = 0x80;
-			for (uint j = 0; j < scaling; ++j) {
-				if (xFrac + xStep + 1 > 255)
-					drawNextPixel(p, color, b, quadrant);
-				xFrac += xStep + 1;
-				if (yFrac + yStep > 255)
-					drawNextPixel(p, color, b, quadrant + 1);
-				yFrac += yStep;
-			}
-			b >>= 3;
-		} while (b != 0);
-	}
-}
-
-const Room &AdlEngine::getRoom(uint i) const {
-	if (i < 1 || i > _state.rooms.size())
-		error("Room %i out of range [1, %i]", i, _state.rooms.size());
-
-	return _state.rooms[i - 1];
-}
-
-Room &AdlEngine::getRoom(uint i) {
-	if (i < 1 || i > _state.rooms.size())
-		error("Room %i out of range [1, %i]", i, _state.rooms.size());
-
-	return _state.rooms[i - 1];
-}
-
-const Room &AdlEngine::getCurRoom() const {
-	return getRoom(_state.room);
-}
-
-Room &AdlEngine::getCurRoom() {
-	return getRoom(_state.room);
-}
-
-const Item &AdlEngine::getItem(uint i) const {
-	if (i < 1 || i > _state.items.size())
-		error("Item %i out of range [1, %i]", i, _state.items.size());
-
-	return _state.items[i - 1];
-}
-
-Item &AdlEngine::getItem(uint i) {
-	if (i < 1 || i > _state.items.size())
-		error("Item %i out of range [1, %i]", i, _state.items.size());
-
-	return _state.items[i - 1];
-}
-
-byte AdlEngine::getVar(uint i) const {
-	if (i >= _state.vars.size())
-		error("Variable %i out of range [0, %i]", i, _state.vars.size() - 1);
-
-	return _state.vars[i];
-}
-
-void AdlEngine::setVar(uint i, byte value) {
-	if (i >= _state.vars.size())
-		error("Variable %i out of range [0, %i]", i, _state.vars.size() - 1);
-
-	_state.vars[i] = value;
-}
-
-void AdlEngine::takeItem(byte noun) {
-	Common::Array<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_MOVED) {
-			item->room = IDI_NONE;
-			return;
-		}
-
-		Common::Array<byte>::const_iterator pic;
-		for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
-			if (*pic == getCurRoom().curPicture) {
-				item->room = IDI_NONE;
-				item->state = IDI_ITEM_MOVED;
-				return;
-			}
-		}
-	}
-
-	printMessage(_messageIds.itemNotHere);
-}
-
-void AdlEngine::dropItem(byte noun) {
-	Common::Array<Item>::iterator item;
-
-	for (item = _state.items.begin(); item != _state.items.end(); ++item) {
-		if (item->noun != noun || item->room != IDI_NONE)
-			continue;
-
-		item->room = _state.room;
-		item->state = IDI_ITEM_MOVED;
-		return;
-	}
-
-	printMessage(_messageIds.dontUnderstand);
-}
-
 #define ARG(N) (command.script[offset + (N)])
 
 bool AdlEngine::matchCommand(const Command &command, byte verb, byte noun, uint *actions) const {
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 4ea7566..df917b1 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -149,6 +149,28 @@ protected:
 	void loadWords(Common::ReadStream &stream, WordMap &map) const;
 	void readCommands(Common::ReadStream &stream, Commands &commands);
 
+	// Graphics
+	void clearScreen() const;
+	void drawItems() const;
+	void drawNextPixel(Common::Point &p, byte color, byte bits, byte quadrant) const;
+	void drawLineArt(const Common::Array<byte> &lineArt, const Common::Point &pos, byte rotation = 0, byte scaling = 1, byte color = 0x7f) const;
+
+	// Game state functions
+	const Room &getRoom(uint i) const;
+	Room &getRoom(uint i);
+	const Room &getCurRoom() const;
+	Room &getCurRoom();
+	const Item &getItem(uint i) const;
+	Item &getItem(uint i);
+	byte getVar(uint i) const;
+	void setVar(uint i, byte value);
+	void takeItem(byte noun);
+	void dropItem(byte noun);
+	bool matchCommand(const Command &command, byte verb, byte noun, uint *actions = nullptr) const;
+	void doActions(const Command &command, byte noun, byte offset);
+	bool doOneCommand(const Commands &commands, byte verb, byte noun);
+	void doAllCommands(const Commands &commands, byte verb, byte noun);
+
 	Display *_display;
 
 	// Message strings in data file
@@ -193,6 +215,7 @@ private:
 	virtual void initState() = 0;
 	virtual void restartGame() = 0;
 	virtual void drawPic(byte pic, Common::Point pos = Common::Point()) const = 0;
+	virtual void showRoom() const = 0;
 
 	// Engine
 	Common::Error run();
@@ -211,29 +234,6 @@ private:
 	Common::String getWord(const Common::String &line, uint &index) const;
 	void getInput(uint &verb, uint &noun);
 
-	// Graphics
-	void showRoom() const;
-	void clearScreen() const;
-	void drawItems() const;
-	void drawNextPixel(Common::Point &p, byte color, byte bits, byte quadrant) const;
-	void drawLineArt(const Common::Array<byte> &lineArt, const Common::Point &pos, byte rotation = 0, byte scaling = 1, byte color = 0x7f) const;
-
-	// Game state functions
-	const Room &getRoom(uint i) const;
-	Room &getRoom(uint i);
-	const Room &getCurRoom() const;
-	Room &getCurRoom();
-	const Item &getItem(uint i) const;
-	Item &getItem(uint i);
-	byte getVar(uint i) const;
-	void setVar(uint i, byte value);
-	void takeItem(byte noun);
-	void dropItem(byte noun);
-	bool matchCommand(const Command &command, byte verb, byte noun, uint *actions = nullptr) const;
-	void doActions(const Command &command, byte noun, byte offset);
-	bool doOneCommand(const Commands &commands, byte verb, byte noun);
-	void doAllCommands(const Commands &commands, byte verb, byte noun);
-
 	const AdlGameDescription *_gameDescription;
 	bool _isRestarting, _isRestoring;
 	byte _saveVerb, _saveNoun, _restoreVerb, _restoreNoun;
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 6e1e31d..c775044 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -239,11 +239,12 @@ void HiRes1Engine::initState() {
 
 	// Load room data from executable
 	_state.rooms.clear();
+	_roomDesc.clear();
 	f.seek(IDI_HR1_OFS_ROOMS);
 	for (uint i = 0; i < IDI_HR1_NUM_ROOMS; ++i) {
 		Room room;
 		f.readByte();
-		room.description = f.readByte();
+		_roomDesc.push_back(f.readByte());
 		for (uint j = 0; j < 6; ++j)
 			room.connections[j] = f.readByte();
 		room.picture = f.readByte();
@@ -313,6 +314,16 @@ void HiRes1Engine::printMessage(uint idx, bool wait) const {
 	AdlEngine::printMessage(idx, wait);
 }
 
+void HiRes1Engine::showRoom() const {
+	if (!_state.isDark) {
+		drawPic(getCurRoom().curPicture);
+		drawItems();
+	}
+
+	_display->updateHiResScreen();
+	printMessage(_roomDesc[_state.room - 1], false);
+}
+
 void HiRes1Engine::drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const {
 	// This draws a four-connected line
 
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index 25f4744..422118d 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -97,8 +97,9 @@ private:
 	void loadData();
 	void initState();
 	void restartGame();
-	void drawPic(byte pic, Common::Point pos) const;
+	void drawPic(byte pic, Common::Point pos = Common::Point()) const;
 	void printMessage(uint idx, bool wait = true) const;
+	void showRoom() const;
 
 	void drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const;
 	void drawPic(Common::ReadStream &stream, const Common::Point &pos) const;
@@ -106,6 +107,8 @@ private:
 	struct {
 		Common::String pressReturn;
 	} _gameStrings;
+
+	Common::Array<byte> _roomDesc;
 };
 
 } // End of namespace Adl
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 1831266..44abc22 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -73,6 +73,9 @@ void HiRes2Engine::restartGame() {
 void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
 }
 
+void HiRes2Engine::showRoom() const {
+}
+
 Engine *HiRes2Engine_create(OSystem *syst, const AdlGameDescription *gd) {
 	return new HiRes2Engine(syst, gd);
 }
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 60c6ca1..e37af5a 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -56,6 +56,7 @@ private:
 	void initState();
 	void restartGame();
 	void drawPic(byte pic, Common::Point pos) const;
+	void showRoom() const;
 };
 
 } // End of namespace Adl


Commit: c44f18a818c36bf714cf59b1a56589b138842503
    https://github.com/scummvm/scummvm/commit/c44f18a818c36bf714cf59b1a56589b138842503
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Load hires2 room data

Changed paths:
    engines/adl/adl.h
    engines/adl/hires1.cpp
    engines/adl/hires2.cpp
    engines/adl/hires2.h



diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index df917b1..abdbaff 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -80,6 +80,9 @@ struct AdlGameDescription;
 struct Room {
 	byte description;
 	byte connections[6];
+	byte track;
+	byte sector;
+	byte offset;
 	byte picture;
 	byte curPicture;
 };
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index c775044..4bdf47a 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -242,7 +242,7 @@ void HiRes1Engine::initState() {
 	_roomDesc.clear();
 	f.seek(IDI_HR1_OFS_ROOMS);
 	for (uint i = 0; i < IDI_HR1_NUM_ROOMS; ++i) {
-		Room room;
+		Room room = { };
 		f.readByte();
 		_roomDesc.push_back(f.readByte());
 		for (uint j = 0; j < 6; ++j)
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 44abc22..4f8ba48 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -64,6 +64,27 @@ void HiRes2Engine::loadData() {
 }
 
 void HiRes2Engine::initState() {
+	Common::File f;
+
+	if (!f.open(IDS_HR2_DISK_IMAGE))
+		error("Failed to open file '" IDS_HR2_DISK_IMAGE "'");
+
+	_state.rooms.clear();
+	f.seek(IDI_HR2_OFS_ROOMS);
+	for (uint i = 0; i < IDI_HR2_NUM_ROOMS; ++i) {
+		Room room = { };
+		f.readByte(); // number
+		for (uint j = 0; j < 6; ++j)
+			room.connections[j] = f.readByte();
+		room.track = f.readByte();
+		room.sector = f.readByte();
+		room.offset = f.readByte();
+		f.readByte(); // always 1, possibly disk?
+		room.picture = f.readByte();
+		room.curPicture = f.readByte();
+		f.readByte(); // always 1, possibly disk?
+		_state.rooms.push_back(room);
+	}
 }
 
 void HiRes2Engine::restartGame() {
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index e37af5a..01bb29f 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -44,6 +44,8 @@ namespace Adl {
 #define IDI_HR2_OFS_INTRO_TEXT TSO(0x00, 0xd, 0x17)
 #define IDI_HR2_OFS_VERBS        T(0x19)
 #define IDI_HR2_OFS_NOUNS       TS(0x22, 0x2)
+#define IDI_HR2_OFS_ROOMS      TSO(0x21, 0x5, 0x0e) // Skip bogus room 0
+#define IDI_HR2_NUM_ROOMS 135
 
 class HiRes2Engine : public AdlEngine {
 public:


Commit: 641d87f7524781dd1fc7e014e7c8f5bf361eca09
    https://github.com/scummvm/scummvm/commit/641d87f7524781dd1fc7e014e7c8f5bf361eca09
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Load (some) hires2 strings

Changed paths:
    engines/adl/adl.h
    engines/adl/hires1.cpp
    engines/adl/hires1.h
    engines/adl/hires2.cpp
    engines/adl/hires2.h



diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index abdbaff..d0da3bf 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -194,11 +194,10 @@ protected:
 
 	struct {
 		Common::String enterCommand;
-		Common::String dontHaveIt;
-		Common::String gettingDark;
 		Common::String verbError;
 		Common::String nounError;
 		Common::String playAgain;
+		Common::String pressReturn;
 	} _strings;
 
 	struct {
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 4bdf47a..98e33ab 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -158,12 +158,10 @@ void HiRes1Engine::loadData() {
 
 	// Load other strings from executable
 	_strings.enterCommand = readStringAt(f, IDI_HR1_OFS_STR_ENTER_COMMAND);
-	_strings.dontHaveIt = readStringAt(f, IDI_HR1_OFS_STR_DONT_HAVE_IT);
-	_strings.gettingDark = readStringAt(f, IDI_HR1_OFS_STR_GETTING_DARK);
 	_strings.verbError = readStringAt(f, IDI_HR1_OFS_STR_VERB_ERROR);
 	_strings.nounError = readStringAt(f, IDI_HR1_OFS_STR_NOUN_ERROR);
 	_strings.playAgain = readStringAt(f, IDI_HR1_OFS_STR_PLAY_AGAIN);
-	_gameStrings.pressReturn = readStringAt(f, IDI_HR1_OFS_STR_PRESS_RETURN);
+	_strings.pressReturn = readStringAt(f, IDI_HR1_OFS_STR_PRESS_RETURN);
 
 	// Set message IDs
 	_messageIds.cantGoThere = IDI_HR1_MSG_CANT_GO_THERE;
@@ -279,7 +277,7 @@ void HiRes1Engine::initState() {
 
 void HiRes1Engine::restartGame() {
 	initState();
-	_display->printString(_gameStrings.pressReturn);
+	_display->printString(_strings.pressReturn);
 	inputString(); // Missing in the original
 	_display->printAsciiString("\r\r\r\r\r");
 }
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index 422118d..02cec01 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -104,10 +104,6 @@ private:
 	void drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const;
 	void drawPic(Common::ReadStream &stream, const Common::Point &pos) const;
 
-	struct {
-		Common::String pressReturn;
-	} _gameStrings;
-
 	Common::Array<byte> _roomDesc;
 };
 
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 4f8ba48..1c43771 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -56,6 +56,35 @@ void HiRes2Engine::loadData() {
 	if (!f.open(IDS_HR2_DISK_IMAGE))
 		error("Failed to open file '" IDS_HR2_DISK_IMAGE "'");
 
+	for (uint i = 0; i < IDI_HR2_NUM_MESSAGES; ++i) {
+		f.seek(IDI_HR2_OFS_MESSAGES + i * 4);
+		byte track = f.readByte();
+		byte sector = f.readByte();
+		byte offset = f.readByte();
+		// One more byte follows, disk?
+
+		uint diskOffset = TSO(track, sector, offset);
+
+		Common::String str;
+
+		if (diskOffset != 0)
+			str = readStringAt(f, TSO(track, sector, offset), 0xff);
+
+		_messages.push_back(str);
+	}
+
+	_strings.enterCommand = readStringAt(f, IDI_HR2_OFS_STR_ENTER_COMMAND);
+	_strings.verbError = readStringAt(f, IDI_HR2_OFS_STR_VERB_ERROR);
+	_strings.nounError = readStringAt(f, IDI_HR2_OFS_STR_NOUN_ERROR);
+	_strings.playAgain = readStringAt(f, IDI_HR2_OFS_STR_PLAY_AGAIN);
+	_strings.pressReturn = readStringAt(f, IDI_HR2_OFS_STR_PRESS_RETURN);
+
+	_messageIds.cantGoThere = IDI_HR2_MSG_CANT_GO_THERE;
+	_messageIds.dontUnderstand = IDI_HR2_MSG_DONT_UNDERSTAND;
+	_messageIds.itemDoesntMove = IDI_HR2_MSG_ITEM_DOESNT_MOVE;
+	_messageIds.itemNotHere = IDI_HR2_MSG_ITEM_NOT_HERE;
+	_messageIds.thanksForPlaying = IDI_HR2_MSG_THANKS_FOR_PLAYING;
+
 	f.seek(IDI_HR2_OFS_VERBS);
 	loadWords(f, _verbs);
 
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 01bb29f..05926ee 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -45,7 +45,23 @@ namespace Adl {
 #define IDI_HR2_OFS_VERBS        T(0x19)
 #define IDI_HR2_OFS_NOUNS       TS(0x22, 0x2)
 #define IDI_HR2_OFS_ROOMS      TSO(0x21, 0x5, 0x0e) // Skip bogus room 0
+#define IDI_HR2_OFS_MESSAGES   TSO(0x1f, 0x2, 0x04) // Skip bogus message 0
+
 #define IDI_HR2_NUM_ROOMS 135
+#define IDI_HR2_NUM_MESSAGES 254
+
+// Messages used outside of scripts
+#define IDI_HR2_MSG_CANT_GO_THERE      123
+#define IDI_HR2_MSG_DONT_UNDERSTAND     19
+#define IDI_HR2_MSG_ITEM_DOESNT_MOVE   242
+#define IDI_HR2_MSG_ITEM_NOT_HERE        4
+#define IDI_HR2_MSG_THANKS_FOR_PLAYING 239
+
+#define IDI_HR2_OFS_STR_ENTER_COMMAND TSO(0x1a, 0x1, 0xbc)
+#define IDI_HR2_OFS_STR_VERB_ERROR    TSO(0x1a, 0x1, 0x4f)
+#define IDI_HR2_OFS_STR_NOUN_ERROR    TSO(0x1a, 0x1, 0x8e)
+#define IDI_HR2_OFS_STR_PLAY_AGAIN    TSO(0x1a, 0x8, 0x25)
+#define IDI_HR2_OFS_STR_PRESS_RETURN  TSO(0x1a, 0x8, 0x5f)
 
 class HiRes2Engine : public AdlEngine {
 public:


Commit: 930bdcfa9101e37b984072102a8b8ef0a25afbf6
    https://github.com/scummvm/scummvm/commit/930bdcfa9101e37b984072102a8b8ef0a25afbf6
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Implement hires2 PIC drawing

Changed paths:
  A engines/adl/picture.cpp
  A engines/adl/picture.h
    engines/adl/display.cpp
    engines/adl/display.h
    engines/adl/hires2.cpp
    engines/adl/module.mk



diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp
index 6342504..3795973 100644
--- a/engines/adl/display.cpp
+++ b/engines/adl/display.cpp
@@ -219,9 +219,24 @@ void Display::loadFrameBuffer(Common::ReadStream &stream) {
 		error("Failed to read frame buffer");
 }
 
+void Display::putPixelRaw(const Common::Point &p, byte color) {
+	byte *b = _frameBuf + p.y * DISPLAY_PITCH + (p.x / 7);
+	color ^= *b;
+	color &= 0x80 | (1 << (p.x % 7));
+	*b ^= color;
+}
+
 void Display::putPixel(const Common::Point &p, byte color) {
 	byte offset = p.x / 7;
+	byte mask = 0x80 | (1 << (p.x % 7));
 
+	// Since white and black are in both palettes, we leave
+	// the palette bit alone
+	if ((color & 0x7f) == 0x7f || (color & 0x7f) == 0)
+		mask &= 0x7f;
+
+	// Adjust colors starting with bits '01' or '10' for
+	// odd offsets
 	if (offset & 1) {
 		byte c = color << 1;
 		if (c >= 0x40 && c < 0xc0)
@@ -230,10 +245,15 @@ void Display::putPixel(const Common::Point &p, byte color) {
 
 	byte *b = _frameBuf + p.y * DISPLAY_PITCH + offset;
 	color ^= *b;
-	color &= 1 << (p.x % 7);
+	color &= mask;
 	*b ^= color;
 }
 
+bool Display::getPixelBit(const Common::Point &p) const {
+	byte *b = _frameBuf + p.y * DISPLAY_PITCH + (p.x / 7);
+	return *b & (1 << (p.x % 7));
+}
+
 void Display::clear(byte color) {
 	byte val = 0;
 
diff --git a/engines/adl/display.h b/engines/adl/display.h
index ff01e3f..67d8bf4 100644
--- a/engines/adl/display.h
+++ b/engines/adl/display.h
@@ -61,7 +61,9 @@ public:
 
 	// Graphics
 	void loadFrameBuffer(Common::ReadStream &stream);
+	void putPixelRaw(const Common::Point &p, byte color);
 	void putPixel(const Common::Point &p, byte color);
+	bool getPixelBit(const Common::Point &p) const;
 	void clear(byte color);
 
 	// Text
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 1c43771..c36e151 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -28,6 +28,7 @@
 
 #include "adl/hires2.h"
 #include "adl/display.h"
+#include "adl/picture.h"
 
 namespace Adl {
 
@@ -121,9 +122,22 @@ void HiRes2Engine::restartGame() {
 }
 
 void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
+	// Temp hack
+	PictureD test(*_display);
+
+	Common::File f;
+
+	if (!f.open(IDS_HR2_DISK_IMAGE))
+		error("Failed to open file '" IDS_HR2_DISK_IMAGE "'");
+
+	f.seek(0x1000);
+
+	test.draw(f);
 }
 
 void HiRes2Engine::showRoom() const {
+	drawPic(0, Common::Point());
+	_display->updateHiResScreen();
 }
 
 Engine *HiRes2Engine_create(OSystem *syst, const AdlGameDescription *gd) {
diff --git a/engines/adl/module.mk b/engines/adl/module.mk
index de69b52..8162e51 100644
--- a/engines/adl/module.mk
+++ b/engines/adl/module.mk
@@ -5,7 +5,8 @@ MODULE_OBJS := \
 	detection.o \
 	display.o \
 	hires1.o \
-	hires2.o
+	hires2.o \
+	picture.o
 
 MODULE_DIRS += \
 	engines/adl
diff --git a/engines/adl/picture.cpp b/engines/adl/picture.cpp
new file mode 100644
index 0000000..567165a
--- /dev/null
+++ b/engines/adl/picture.cpp
@@ -0,0 +1,298 @@
+/* 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/stream.h"
+#include "common/rect.h"
+#include "common/textconsole.h"
+
+#include "adl/display.h"
+#include "adl/picture.h"
+
+#define MIN_COMMAND 0xe0
+
+namespace Adl {
+
+#define NUM_PATTERNS 22
+#define PATTERN_LEN 4
+static const byte fillPatterns[NUM_PATTERNS][PATTERN_LEN] = {
+	{ 0x00, 0x00, 0x00, 0x00 },
+	{ 0x80, 0x80, 0x80, 0x80 },
+	{ 0xff, 0xff, 0xff, 0xff },
+	{ 0x7f, 0x7f, 0x7f, 0x7f },
+	{ 0x2a, 0x55, 0x2a, 0x55 },
+	{ 0xaa, 0xd5, 0xaa, 0xd5 },
+	{ 0x55, 0x2a, 0x55, 0x2a },
+	{ 0xd5, 0xaa, 0xd5, 0xaa },
+	{ 0x33, 0x66, 0x4c, 0x19 },
+	{ 0xb3, 0xe6, 0xcc, 0x99 },
+	{ 0x22, 0x44, 0x08, 0x11 },
+	{ 0xa2, 0xc4, 0x88, 0x91 },
+	{ 0x11, 0x22, 0x44, 0x08 },
+	{ 0x91, 0xa2, 0xc4, 0x88 },
+	{ 0x6e, 0x5d, 0x3b, 0x77 },
+	{ 0xee, 0xdd, 0xbb, 0xf7 },
+	{ 0x5d, 0x3b, 0x77, 0x6e },
+	{ 0xdd, 0xbb, 0xf7, 0xee },
+	{ 0x66, 0x4c, 0x19, 0x33 },
+	{ 0xe6, 0xcc, 0x99, 0xb3 },
+	{ 0x33, 0x66, 0x4c, 0x19 },
+	{ 0xb3, 0xe6, 0xcc, 0x99 }
+};
+
+#define CHECK_COMMAND(X) \
+	do { \
+		if ((X) >= MIN_COMMAND) { \
+			pic.seek(-1, SEEK_CUR); \
+			return; \
+		} \
+	} while (0)
+
+#define READ_BYTE(b) \
+	do { \
+		b = pic.readByte(); \
+		if (pic.eos() || pic.err()) \
+			return; \
+		CHECK_COMMAND(b); \
+	} while (0)
+
+#define READ_POINT(p) \
+	do { \
+		READ_BYTE(p.x); \
+		p.x <<= 1; \
+		READ_BYTE(p.y); \
+	} while (0)
+
+// Draws a four-connected line
+void PictureD::drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const {
+	int16 deltaX = p2.x - p1.x;
+	int8 xStep = 1;
+
+	if (deltaX < 0) {
+		deltaX = -deltaX;
+		xStep = -1;
+	}
+
+	int16 deltaY = p2.y - p1.y;
+	int8 yStep = -1;
+
+	if (deltaY > 0) {
+		deltaY = -deltaY;
+		yStep = 1;
+	}
+
+	Common::Point p(p1);
+	int16 steps = deltaX - deltaY + 1;
+	int16 err = deltaX + deltaY;
+
+	while (true) {
+		_display.putPixel(p, color);
+
+		if (--steps == 0)
+			return;
+
+		if (err < 0) {
+			p.y += yStep;
+			err += deltaX;
+		} else {
+			p.x += xStep;
+			err += deltaY;
+		}
+	}
+}
+
+void PictureD::clear() {
+	_display.clear(0xff);
+	_color = 0;
+}
+
+void PictureD::drawCorners(Common::SeekableReadStream &pic, bool yFirst) {
+	Common::Point p;
+
+	READ_POINT(p);
+
+	if (yFirst)
+		goto doYStep;
+
+	while (true) {
+		int16 n;
+
+		READ_BYTE(n);
+
+		_display.putPixel(p, _color);
+
+		n <<= 1;
+		drawLine(p, Common::Point(n, p.y), _color);
+		p.x = n;
+
+doYStep:
+		READ_BYTE(n);
+
+		_display.putPixel(p, _color);
+		drawLine(p, Common::Point(p.x, n), _color);
+
+		_display.putPixel(Common::Point(p.x + 1, p.y), _color);
+		drawLine(Common::Point(p.x + 1, p.y), Common::Point(p.x + 1, n), _color);
+
+		p.y = n;
+	}
+}
+
+void PictureD::drawRelativeLines(Common::SeekableReadStream &pic) {
+	Common::Point p1;
+
+	READ_POINT(p1);
+	_display.putPixel(p1, _color);
+
+	while (true) {
+		Common::Point p2(p1);
+
+		byte n;
+		READ_BYTE(n);
+
+		byte h = (n & 0x70) >> 4;
+		byte l = n & 7;
+
+		if (n & 0x80)
+			p2.x -= (h << 1);
+		else
+			p2.x += (h << 1);
+
+		if (n & 8)
+			p2.y -= l;
+		else
+			p2.y += l;
+
+		drawLine(p1, p2, _color);
+		p1 = p2;
+	}
+}
+
+void PictureD::drawAbsoluteLines(Common::SeekableReadStream &pic) {
+	Common::Point p1;
+
+	READ_POINT(p1);
+	_display.putPixel(p1, _color);
+
+	while (true) {
+		Common::Point p2;
+
+		READ_POINT(p2);
+		drawLine(p1, p2, _color);
+		p1 = p2;
+	}
+}
+
+static byte getPatternColor(const Common::Point &p, byte pattern) {
+	if (pattern >= NUM_PATTERNS)
+		error("Invalid fill pattern %i encountered", pattern);
+
+	byte offset = (p.y & 1) << 1;
+	offset += (p.x / 7) & 3;
+
+	return fillPatterns[pattern][offset % PATTERN_LEN];
+}
+
+void PictureD::fillRow(const Common::Point &p, bool stopBit, byte pattern) {
+	const byte color = getPatternColor(p, pattern);
+	_display.putPixelRaw(p, color);
+
+	Common::Point q(p);
+	byte c = color;
+
+	while (++q.x < DISPLAY_WIDTH && _display.getPixelBit(q) != stopBit) {
+		if ((q.x % 7) == 0)
+			c = getPatternColor(q, pattern);
+		_display.putPixelRaw(q, c);
+	}
+
+	q = p;
+	c = color;
+	while (--q.x >= 0 && _display.getPixelBit(q) != stopBit) {
+		if ((q.x % 7) == 6)
+			c = getPatternColor(q, pattern);
+		_display.putPixelRaw(q, c);
+	}
+}
+
+// Basic flood fill
+void PictureD::fill(Common::SeekableReadStream &pic) {
+	byte pattern;
+	READ_BYTE(pattern);
+
+	while (true) {
+		Common::Point p;
+		READ_POINT(p);
+
+		bool stopBit = !_display.getPixelBit(p);
+
+		while (--p.y >= 0) {
+			if (_display.getPixelBit(p) == stopBit)
+				break;
+			if (_display.getPixelBit(Common::Point(p.x + 1, p.y)) == stopBit)
+				break;
+		}
+
+		while (++p.y < DISPLAY_HEIGHT) {
+			if (_display.getPixelBit(p) == stopBit)
+				break;
+			if (_display.getPixelBit(Common::Point(p.x + 1, p.y)) == stopBit)
+				break;
+			fillRow(p, stopBit, pattern);
+		}
+	}
+}
+
+void PictureD::draw(Common::SeekableReadStream &pic) {
+	while (true) {
+		byte opcode = pic.readByte();
+
+		if (pic.eos() || pic.err())
+			error("Error reading picture");
+
+		switch (opcode) {
+		case 0xe0:
+			drawCorners(pic, false);
+			break;
+		case 0xe1:
+			drawCorners(pic, true);
+			break;
+		case 0xe2:
+			drawRelativeLines(pic);
+			break;
+		case 0xe3:
+			drawAbsoluteLines(pic);
+			break;
+		case 0xe4:
+			fill(pic);
+			break;
+		case 0xe5:
+			clear();
+			break;
+		case 0xff:
+			return;
+		default:
+			error("Invalid pic opcode %02x", opcode);
+		}
+	}
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/picture.h b/engines/adl/picture.h
new file mode 100644
index 0000000..990c856
--- /dev/null
+++ b/engines/adl/picture.h
@@ -0,0 +1,56 @@
+/* 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_PICTURE_H
+#define ADL_PICTURE_H
+
+namespace Common{
+class SeekableReadStream;
+class Point;
+}
+
+namespace Adl {
+
+class Display;
+
+class PictureD {
+public:
+	PictureD(Display &display) : _display(display) { }
+
+	void drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const;
+	void draw(Common::SeekableReadStream &pic);
+
+private:
+	void clear();
+	void drawCorners(Common::SeekableReadStream &pic, bool yFirst);
+	void drawRelativeLines(Common::SeekableReadStream &pic);
+	void drawAbsoluteLines(Common::SeekableReadStream &pic);
+	void fillRow(const Common::Point &p, bool fillBit, byte pattern);
+	void fill(Common::SeekableReadStream &pic);
+
+	Display &_display;
+	byte _color;
+};
+
+} // End of namespace Adl
+
+#endif


Commit: 60892c91a5455f1c490c1c1016a9149b6d3a2db2
    https://github.com/scummvm/scummvm/commit/60892c91a5455f1c490c1c1016a9149b6d3a2db2
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Rename PictureD to Graphics

Changed paths:
  A engines/adl/graphics.cpp
  A engines/adl/graphics.h
  R engines/adl/picture.cpp
  R engines/adl/picture.h
    engines/adl/hires2.cpp
    engines/adl/module.mk



diff --git a/engines/adl/graphics.cpp b/engines/adl/graphics.cpp
new file mode 100644
index 0000000..8e8117d
--- /dev/null
+++ b/engines/adl/graphics.cpp
@@ -0,0 +1,298 @@
+/* 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/stream.h"
+#include "common/rect.h"
+#include "common/textconsole.h"
+
+#include "adl/display.h"
+#include "adl/graphics.h"
+
+#define MIN_COMMAND 0xe0
+
+namespace Adl {
+
+#define NUM_PATTERNS 22
+#define PATTERN_LEN 4
+static const byte fillPatterns[NUM_PATTERNS][PATTERN_LEN] = {
+	{ 0x00, 0x00, 0x00, 0x00 },
+	{ 0x80, 0x80, 0x80, 0x80 },
+	{ 0xff, 0xff, 0xff, 0xff },
+	{ 0x7f, 0x7f, 0x7f, 0x7f },
+	{ 0x2a, 0x55, 0x2a, 0x55 },
+	{ 0xaa, 0xd5, 0xaa, 0xd5 },
+	{ 0x55, 0x2a, 0x55, 0x2a },
+	{ 0xd5, 0xaa, 0xd5, 0xaa },
+	{ 0x33, 0x66, 0x4c, 0x19 },
+	{ 0xb3, 0xe6, 0xcc, 0x99 },
+	{ 0x22, 0x44, 0x08, 0x11 },
+	{ 0xa2, 0xc4, 0x88, 0x91 },
+	{ 0x11, 0x22, 0x44, 0x08 },
+	{ 0x91, 0xa2, 0xc4, 0x88 },
+	{ 0x6e, 0x5d, 0x3b, 0x77 },
+	{ 0xee, 0xdd, 0xbb, 0xf7 },
+	{ 0x5d, 0x3b, 0x77, 0x6e },
+	{ 0xdd, 0xbb, 0xf7, 0xee },
+	{ 0x66, 0x4c, 0x19, 0x33 },
+	{ 0xe6, 0xcc, 0x99, 0xb3 },
+	{ 0x33, 0x66, 0x4c, 0x19 },
+	{ 0xb3, 0xe6, 0xcc, 0x99 }
+};
+
+#define CHECK_COMMAND(X) \
+	do { \
+		if ((X) >= MIN_COMMAND) { \
+			pic.seek(-1, SEEK_CUR); \
+			return; \
+		} \
+	} while (0)
+
+#define READ_BYTE(b) \
+	do { \
+		b = pic.readByte(); \
+		if (pic.eos() || pic.err()) \
+			return; \
+		CHECK_COMMAND(b); \
+	} while (0)
+
+#define READ_POINT(p) \
+	do { \
+		READ_BYTE(p.x); \
+		p.x <<= 1; \
+		READ_BYTE(p.y); \
+	} while (0)
+
+// Draws a four-connected line
+void Graphics::drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const {
+	int16 deltaX = p2.x - p1.x;
+	int8 xStep = 1;
+
+	if (deltaX < 0) {
+		deltaX = -deltaX;
+		xStep = -1;
+	}
+
+	int16 deltaY = p2.y - p1.y;
+	int8 yStep = -1;
+
+	if (deltaY > 0) {
+		deltaY = -deltaY;
+		yStep = 1;
+	}
+
+	Common::Point p(p1);
+	int16 steps = deltaX - deltaY + 1;
+	int16 err = deltaX + deltaY;
+
+	while (true) {
+		_display.putPixel(p, color);
+
+		if (--steps == 0)
+			return;
+
+		if (err < 0) {
+			p.y += yStep;
+			err += deltaX;
+		} else {
+			p.x += xStep;
+			err += deltaY;
+		}
+	}
+}
+
+void Graphics::clear() {
+	_display.clear(0xff);
+	_color = 0;
+}
+
+void Graphics::drawCorners(Common::SeekableReadStream &pic, bool yFirst) {
+	Common::Point p;
+
+	READ_POINT(p);
+
+	if (yFirst)
+		goto doYStep;
+
+	while (true) {
+		int16 n;
+
+		READ_BYTE(n);
+
+		_display.putPixel(p, _color);
+
+		n <<= 1;
+		drawLine(p, Common::Point(n, p.y), _color);
+		p.x = n;
+
+doYStep:
+		READ_BYTE(n);
+
+		_display.putPixel(p, _color);
+		drawLine(p, Common::Point(p.x, n), _color);
+
+		_display.putPixel(Common::Point(p.x + 1, p.y), _color);
+		drawLine(Common::Point(p.x + 1, p.y), Common::Point(p.x + 1, n), _color);
+
+		p.y = n;
+	}
+}
+
+void Graphics::drawRelativeLines(Common::SeekableReadStream &pic) {
+	Common::Point p1;
+
+	READ_POINT(p1);
+	_display.putPixel(p1, _color);
+
+	while (true) {
+		Common::Point p2(p1);
+
+		byte n;
+		READ_BYTE(n);
+
+		byte h = (n & 0x70) >> 4;
+		byte l = n & 7;
+
+		if (n & 0x80)
+			p2.x -= (h << 1);
+		else
+			p2.x += (h << 1);
+
+		if (n & 8)
+			p2.y -= l;
+		else
+			p2.y += l;
+
+		drawLine(p1, p2, _color);
+		p1 = p2;
+	}
+}
+
+void Graphics::drawAbsoluteLines(Common::SeekableReadStream &pic) {
+	Common::Point p1;
+
+	READ_POINT(p1);
+	_display.putPixel(p1, _color);
+
+	while (true) {
+		Common::Point p2;
+
+		READ_POINT(p2);
+		drawLine(p1, p2, _color);
+		p1 = p2;
+	}
+}
+
+static byte getPatternColor(const Common::Point &p, byte pattern) {
+	if (pattern >= NUM_PATTERNS)
+		error("Invalid fill pattern %i encountered", pattern);
+
+	byte offset = (p.y & 1) << 1;
+	offset += (p.x / 7) & 3;
+
+	return fillPatterns[pattern][offset % PATTERN_LEN];
+}
+
+void Graphics::fillRow(const Common::Point &p, bool stopBit, byte pattern) {
+	const byte color = getPatternColor(p, pattern);
+	_display.putPixelRaw(p, color);
+
+	Common::Point q(p);
+	byte c = color;
+
+	while (++q.x < DISPLAY_WIDTH && _display.getPixelBit(q) != stopBit) {
+		if ((q.x % 7) == 0)
+			c = getPatternColor(q, pattern);
+		_display.putPixelRaw(q, c);
+	}
+
+	q = p;
+	c = color;
+	while (--q.x >= 0 && _display.getPixelBit(q) != stopBit) {
+		if ((q.x % 7) == 6)
+			c = getPatternColor(q, pattern);
+		_display.putPixelRaw(q, c);
+	}
+}
+
+// Basic flood fill
+void Graphics::fill(Common::SeekableReadStream &pic) {
+	byte pattern;
+	READ_BYTE(pattern);
+
+	while (true) {
+		Common::Point p;
+		READ_POINT(p);
+
+		bool stopBit = !_display.getPixelBit(p);
+
+		while (--p.y >= 0) {
+			if (_display.getPixelBit(p) == stopBit)
+				break;
+			if (_display.getPixelBit(Common::Point(p.x + 1, p.y)) == stopBit)
+				break;
+		}
+
+		while (++p.y < DISPLAY_HEIGHT) {
+			if (_display.getPixelBit(p) == stopBit)
+				break;
+			if (_display.getPixelBit(Common::Point(p.x + 1, p.y)) == stopBit)
+				break;
+			fillRow(p, stopBit, pattern);
+		}
+	}
+}
+
+void Graphics::draw(Common::SeekableReadStream &pic) {
+	while (true) {
+		byte opcode = pic.readByte();
+
+		if (pic.eos() || pic.err())
+			error("Error reading picture");
+
+		switch (opcode) {
+		case 0xe0:
+			drawCorners(pic, false);
+			break;
+		case 0xe1:
+			drawCorners(pic, true);
+			break;
+		case 0xe2:
+			drawRelativeLines(pic);
+			break;
+		case 0xe3:
+			drawAbsoluteLines(pic);
+			break;
+		case 0xe4:
+			fill(pic);
+			break;
+		case 0xe5:
+			clear();
+			break;
+		case 0xff:
+			return;
+		default:
+			error("Invalid pic opcode %02x", opcode);
+		}
+	}
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/graphics.h b/engines/adl/graphics.h
new file mode 100644
index 0000000..9c47820
--- /dev/null
+++ b/engines/adl/graphics.h
@@ -0,0 +1,56 @@
+/* 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_PICTURE_H
+#define ADL_PICTURE_H
+
+namespace Common{
+class SeekableReadStream;
+class Point;
+}
+
+namespace Adl {
+
+class Display;
+
+class Graphics {
+public:
+	Graphics(Display &display) : _display(display) { }
+
+	void drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const;
+	void draw(Common::SeekableReadStream &pic);
+
+private:
+	void clear();
+	void drawCorners(Common::SeekableReadStream &pic, bool yFirst);
+	void drawRelativeLines(Common::SeekableReadStream &pic);
+	void drawAbsoluteLines(Common::SeekableReadStream &pic);
+	void fillRow(const Common::Point &p, bool fillBit, byte pattern);
+	void fill(Common::SeekableReadStream &pic);
+
+	Display &_display;
+	byte _color;
+};
+
+} // End of namespace Adl
+
+#endif
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index c36e151..7bdfde5 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -28,7 +28,7 @@
 
 #include "adl/hires2.h"
 #include "adl/display.h"
-#include "adl/picture.h"
+#include "adl/graphics.h"
 
 namespace Adl {
 
@@ -123,7 +123,7 @@ void HiRes2Engine::restartGame() {
 
 void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
 	// Temp hack
-	PictureD test(*_display);
+	Graphics test(*_display);
 
 	Common::File f;
 
diff --git a/engines/adl/module.mk b/engines/adl/module.mk
index 8162e51..6901279 100644
--- a/engines/adl/module.mk
+++ b/engines/adl/module.mk
@@ -4,9 +4,9 @@ MODULE_OBJS := \
 	adl.o \
 	detection.o \
 	display.o \
+	graphics.o \
 	hires1.o \
-	hires2.o \
-	picture.o
+	hires2.o
 
 MODULE_DIRS += \
 	engines/adl
diff --git a/engines/adl/picture.cpp b/engines/adl/picture.cpp
deleted file mode 100644
index 567165a..0000000
--- a/engines/adl/picture.cpp
+++ /dev/null
@@ -1,298 +0,0 @@
-/* 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/stream.h"
-#include "common/rect.h"
-#include "common/textconsole.h"
-
-#include "adl/display.h"
-#include "adl/picture.h"
-
-#define MIN_COMMAND 0xe0
-
-namespace Adl {
-
-#define NUM_PATTERNS 22
-#define PATTERN_LEN 4
-static const byte fillPatterns[NUM_PATTERNS][PATTERN_LEN] = {
-	{ 0x00, 0x00, 0x00, 0x00 },
-	{ 0x80, 0x80, 0x80, 0x80 },
-	{ 0xff, 0xff, 0xff, 0xff },
-	{ 0x7f, 0x7f, 0x7f, 0x7f },
-	{ 0x2a, 0x55, 0x2a, 0x55 },
-	{ 0xaa, 0xd5, 0xaa, 0xd5 },
-	{ 0x55, 0x2a, 0x55, 0x2a },
-	{ 0xd5, 0xaa, 0xd5, 0xaa },
-	{ 0x33, 0x66, 0x4c, 0x19 },
-	{ 0xb3, 0xe6, 0xcc, 0x99 },
-	{ 0x22, 0x44, 0x08, 0x11 },
-	{ 0xa2, 0xc4, 0x88, 0x91 },
-	{ 0x11, 0x22, 0x44, 0x08 },
-	{ 0x91, 0xa2, 0xc4, 0x88 },
-	{ 0x6e, 0x5d, 0x3b, 0x77 },
-	{ 0xee, 0xdd, 0xbb, 0xf7 },
-	{ 0x5d, 0x3b, 0x77, 0x6e },
-	{ 0xdd, 0xbb, 0xf7, 0xee },
-	{ 0x66, 0x4c, 0x19, 0x33 },
-	{ 0xe6, 0xcc, 0x99, 0xb3 },
-	{ 0x33, 0x66, 0x4c, 0x19 },
-	{ 0xb3, 0xe6, 0xcc, 0x99 }
-};
-
-#define CHECK_COMMAND(X) \
-	do { \
-		if ((X) >= MIN_COMMAND) { \
-			pic.seek(-1, SEEK_CUR); \
-			return; \
-		} \
-	} while (0)
-
-#define READ_BYTE(b) \
-	do { \
-		b = pic.readByte(); \
-		if (pic.eos() || pic.err()) \
-			return; \
-		CHECK_COMMAND(b); \
-	} while (0)
-
-#define READ_POINT(p) \
-	do { \
-		READ_BYTE(p.x); \
-		p.x <<= 1; \
-		READ_BYTE(p.y); \
-	} while (0)
-
-// Draws a four-connected line
-void PictureD::drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const {
-	int16 deltaX = p2.x - p1.x;
-	int8 xStep = 1;
-
-	if (deltaX < 0) {
-		deltaX = -deltaX;
-		xStep = -1;
-	}
-
-	int16 deltaY = p2.y - p1.y;
-	int8 yStep = -1;
-
-	if (deltaY > 0) {
-		deltaY = -deltaY;
-		yStep = 1;
-	}
-
-	Common::Point p(p1);
-	int16 steps = deltaX - deltaY + 1;
-	int16 err = deltaX + deltaY;
-
-	while (true) {
-		_display.putPixel(p, color);
-
-		if (--steps == 0)
-			return;
-
-		if (err < 0) {
-			p.y += yStep;
-			err += deltaX;
-		} else {
-			p.x += xStep;
-			err += deltaY;
-		}
-	}
-}
-
-void PictureD::clear() {
-	_display.clear(0xff);
-	_color = 0;
-}
-
-void PictureD::drawCorners(Common::SeekableReadStream &pic, bool yFirst) {
-	Common::Point p;
-
-	READ_POINT(p);
-
-	if (yFirst)
-		goto doYStep;
-
-	while (true) {
-		int16 n;
-
-		READ_BYTE(n);
-
-		_display.putPixel(p, _color);
-
-		n <<= 1;
-		drawLine(p, Common::Point(n, p.y), _color);
-		p.x = n;
-
-doYStep:
-		READ_BYTE(n);
-
-		_display.putPixel(p, _color);
-		drawLine(p, Common::Point(p.x, n), _color);
-
-		_display.putPixel(Common::Point(p.x + 1, p.y), _color);
-		drawLine(Common::Point(p.x + 1, p.y), Common::Point(p.x + 1, n), _color);
-
-		p.y = n;
-	}
-}
-
-void PictureD::drawRelativeLines(Common::SeekableReadStream &pic) {
-	Common::Point p1;
-
-	READ_POINT(p1);
-	_display.putPixel(p1, _color);
-
-	while (true) {
-		Common::Point p2(p1);
-
-		byte n;
-		READ_BYTE(n);
-
-		byte h = (n & 0x70) >> 4;
-		byte l = n & 7;
-
-		if (n & 0x80)
-			p2.x -= (h << 1);
-		else
-			p2.x += (h << 1);
-
-		if (n & 8)
-			p2.y -= l;
-		else
-			p2.y += l;
-
-		drawLine(p1, p2, _color);
-		p1 = p2;
-	}
-}
-
-void PictureD::drawAbsoluteLines(Common::SeekableReadStream &pic) {
-	Common::Point p1;
-
-	READ_POINT(p1);
-	_display.putPixel(p1, _color);
-
-	while (true) {
-		Common::Point p2;
-
-		READ_POINT(p2);
-		drawLine(p1, p2, _color);
-		p1 = p2;
-	}
-}
-
-static byte getPatternColor(const Common::Point &p, byte pattern) {
-	if (pattern >= NUM_PATTERNS)
-		error("Invalid fill pattern %i encountered", pattern);
-
-	byte offset = (p.y & 1) << 1;
-	offset += (p.x / 7) & 3;
-
-	return fillPatterns[pattern][offset % PATTERN_LEN];
-}
-
-void PictureD::fillRow(const Common::Point &p, bool stopBit, byte pattern) {
-	const byte color = getPatternColor(p, pattern);
-	_display.putPixelRaw(p, color);
-
-	Common::Point q(p);
-	byte c = color;
-
-	while (++q.x < DISPLAY_WIDTH && _display.getPixelBit(q) != stopBit) {
-		if ((q.x % 7) == 0)
-			c = getPatternColor(q, pattern);
-		_display.putPixelRaw(q, c);
-	}
-
-	q = p;
-	c = color;
-	while (--q.x >= 0 && _display.getPixelBit(q) != stopBit) {
-		if ((q.x % 7) == 6)
-			c = getPatternColor(q, pattern);
-		_display.putPixelRaw(q, c);
-	}
-}
-
-// Basic flood fill
-void PictureD::fill(Common::SeekableReadStream &pic) {
-	byte pattern;
-	READ_BYTE(pattern);
-
-	while (true) {
-		Common::Point p;
-		READ_POINT(p);
-
-		bool stopBit = !_display.getPixelBit(p);
-
-		while (--p.y >= 0) {
-			if (_display.getPixelBit(p) == stopBit)
-				break;
-			if (_display.getPixelBit(Common::Point(p.x + 1, p.y)) == stopBit)
-				break;
-		}
-
-		while (++p.y < DISPLAY_HEIGHT) {
-			if (_display.getPixelBit(p) == stopBit)
-				break;
-			if (_display.getPixelBit(Common::Point(p.x + 1, p.y)) == stopBit)
-				break;
-			fillRow(p, stopBit, pattern);
-		}
-	}
-}
-
-void PictureD::draw(Common::SeekableReadStream &pic) {
-	while (true) {
-		byte opcode = pic.readByte();
-
-		if (pic.eos() || pic.err())
-			error("Error reading picture");
-
-		switch (opcode) {
-		case 0xe0:
-			drawCorners(pic, false);
-			break;
-		case 0xe1:
-			drawCorners(pic, true);
-			break;
-		case 0xe2:
-			drawRelativeLines(pic);
-			break;
-		case 0xe3:
-			drawAbsoluteLines(pic);
-			break;
-		case 0xe4:
-			fill(pic);
-			break;
-		case 0xe5:
-			clear();
-			break;
-		case 0xff:
-			return;
-		default:
-			error("Invalid pic opcode %02x", opcode);
-		}
-	}
-}
-
-} // End of namespace Adl
diff --git a/engines/adl/picture.h b/engines/adl/picture.h
deleted file mode 100644
index 990c856..0000000
--- a/engines/adl/picture.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* 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_PICTURE_H
-#define ADL_PICTURE_H
-
-namespace Common{
-class SeekableReadStream;
-class Point;
-}
-
-namespace Adl {
-
-class Display;
-
-class PictureD {
-public:
-	PictureD(Display &display) : _display(display) { }
-
-	void drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const;
-	void draw(Common::SeekableReadStream &pic);
-
-private:
-	void clear();
-	void drawCorners(Common::SeekableReadStream &pic, bool yFirst);
-	void drawRelativeLines(Common::SeekableReadStream &pic);
-	void drawAbsoluteLines(Common::SeekableReadStream &pic);
-	void fillRow(const Common::Point &p, bool fillBit, byte pattern);
-	void fill(Common::SeekableReadStream &pic);
-
-	Display &_display;
-	byte _color;
-};
-
-} // End of namespace Adl
-
-#endif


Commit: 148814b2a6c3dffb53b8d902eb7fcfb68110bea3
    https://github.com/scummvm/scummvm/commit/148814b2a6c3dffb53b8d902eb7fcfb68110bea3
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Move hires1 drawing functions into class

Changed paths:
  A engines/adl/graphics_v1.cpp
  A engines/adl/graphics_v2.cpp
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/graphics.cpp
    engines/adl/graphics.h
    engines/adl/hires1.cpp
    engines/adl/hires1.h
    engines/adl/hires2.cpp
    engines/adl/hires2.h
    engines/adl/module.mk



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 47623d4..a17339f 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -38,16 +38,19 @@
 #include "adl/adl.h"
 #include "adl/display.h"
 #include "adl/detection.h"
+#include "adl/graphics.h"
 
 namespace Adl {
 
 AdlEngine::~AdlEngine() {
 	delete _display;
+	delete _graphics;
 }
 
 AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) :
 		Engine(syst),
 		_display(nullptr),
+		_graphics(nullptr),
 		_gameDescription(gd),
 		_isRestarting(false),
 		_isRestoring(false),
@@ -82,6 +85,14 @@ Common::String AdlEngine::readStringAt(Common::SeekableReadStream &stream, uint
 	return readString(stream, until);
 }
 
+Common::File *AdlEngine::openFile(const Common::String &name) const {
+	Common::File *f = new Common::File();
+	if (!f->open(name))
+		error("Error opening '%s'", name.c_str());
+
+	return f;
+}
+
 void AdlEngine::printMessage(uint idx, bool wait) const {
 	Common::String msg = _messages[idx - 1];
 	wordWrap(msg);
@@ -281,10 +292,7 @@ void AdlEngine::drawItems() const {
 		if (item->state == IDI_ITEM_MOVED) {
 			if (getCurRoom().picture == getCurRoom().curPicture) {
 				const Common::Point &p =  _itemOffsets[dropped];
-				if (item->isLineArt)
-					drawLineArt(_lineArt[item->picture - 1], p);
-				else
-					drawPic(item->picture, p);
+				drawItem(*item, p);
 				++dropped;
 			}
 			continue;
@@ -294,61 +302,13 @@ void AdlEngine::drawItems() const {
 
 		for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
 			if (*pic == getCurRoom().curPicture) {
-				if (item->isLineArt)
-					drawLineArt(_lineArt[item->picture - 1], item->position);
-				else
-					drawPic(item->picture, item->position);
+				drawItem(*item, item->position);
 				continue;
 			}
 		}
 	}
 }
 
-void AdlEngine::drawNextPixel(Common::Point &p, byte color, byte bits, byte quadrant) const {
-	if (bits & 4)
-		_display->putPixel(p, color);
-
-	bits += quadrant;
-
-	if (bits & 1)
-		p.x += (bits & 2 ? -1 : 1);
-	else
-		p.y += (bits & 2 ? 1 : -1);
-}
-
-void AdlEngine::drawLineArt(const Common::Array<byte> &lineArt, const Common::Point &pos, byte rotation, byte scaling, byte color) const {
-	const byte stepping[] = {
-		0xff, 0xfe, 0xfa, 0xf4, 0xec, 0xe1, 0xd4, 0xc5,
-		0xb4, 0xa1, 0x8d, 0x78, 0x61, 0x49, 0x31, 0x18,
-		0xff
-	};
-
-	byte quadrant = rotation >> 4;
-	rotation &= 0xf;
-	byte xStep = stepping[rotation];
-	byte yStep = stepping[(rotation ^ 0xf) + 1] + 1;
-
-	Common::Point p(pos);
-
-	for (uint i = 0; i < lineArt.size(); ++i) {
-		byte b = lineArt[i];
-
-		do {
-			byte xFrac = 0x80;
-			byte yFrac = 0x80;
-			for (uint j = 0; j < scaling; ++j) {
-				if (xFrac + xStep + 1 > 255)
-					drawNextPixel(p, color, b, quadrant);
-				xFrac += xStep + 1;
-				if (yFrac + yStep > 255)
-					drawNextPixel(p, color, b, quadrant + 1);
-				yFrac += yStep;
-			}
-			b >>= 3;
-		} while (b != 0);
-	}
-}
-
 const Room &AdlEngine::getRoom(uint i) const {
 	if (i < 1 || i > _state.rooms.size())
 		error("Room %i out of range [1, %i]", i, _state.rooms.size());
@@ -447,7 +407,7 @@ void AdlEngine::dropItem(byte noun) {
 Common::Error AdlEngine::run() {
 	_display = new Display();
 
-	loadData();
+	init();
 
 	int saveSlot = ConfMan.getInt("save_slot");
 	if (saveSlot >= 0) {
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index d0da3bf..d8c631e 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -37,6 +37,7 @@ class SeekableReadStream;
 namespace Adl {
 
 class Display;
+class GraphicsMan;
 struct AdlGameDescription;
 
 // Conditional opcodes
@@ -142,6 +143,7 @@ protected:
 
 	Common::String readString(Common::ReadStream &stream, byte until = 0) const;
 	Common::String readStringAt(Common::SeekableReadStream &stream, uint offset, byte until = 0) const;
+	Common::File *openFile(const Common::String &name) const;
 
 	virtual void printMessage(uint idx, bool wait = true) const;
 	void delay(uint32 ms) const;
@@ -155,8 +157,6 @@ protected:
 	// Graphics
 	void clearScreen() const;
 	void drawItems() const;
-	void drawNextPixel(Common::Point &p, byte color, byte bits, byte quadrant) const;
-	void drawLineArt(const Common::Array<byte> &lineArt, const Common::Point &pos, byte rotation = 0, byte scaling = 1, byte color = 0x7f) const;
 
 	// Game state functions
 	const Room &getRoom(uint i) const;
@@ -175,6 +175,7 @@ protected:
 	void doAllCommands(const Commands &commands, byte verb, byte noun);
 
 	Display *_display;
+	GraphicsMan *_graphics;
 
 	// Message strings in data file
 	Common::Array<Common::String> _messages;
@@ -182,9 +183,6 @@ protected:
 	Common::Array<Picture> _pictures;
 	// Dropped item screen offsets
 	Common::Array<Common::Point> _itemOffsets;
-	// Drawings consisting of horizontal and vertical lines only, but
-	// supporting scaling and rotation
-	Common::Array<Common::Array<byte> > _lineArt;
 	// <room, verb, noun, script> lists
 	Commands _roomCommands;
 	Commands _globalCommands;
@@ -213,10 +211,10 @@ protected:
 
 private:
 	virtual void runIntro() const { }
-	virtual void loadData() = 0;
+	virtual void init() = 0;
 	virtual void initState() = 0;
 	virtual void restartGame() = 0;
-	virtual void drawPic(byte pic, Common::Point pos = Common::Point()) const = 0;
+	virtual void drawItem(const Item &item, const Common::Point &pos) const = 0;
 	virtual void showRoom() const = 0;
 
 	// Engine
diff --git a/engines/adl/graphics.cpp b/engines/adl/graphics.cpp
index 8e8117d..f9af442 100644
--- a/engines/adl/graphics.cpp
+++ b/engines/adl/graphics.cpp
@@ -22,67 +22,14 @@
 
 #include "common/stream.h"
 #include "common/rect.h"
-#include "common/textconsole.h"
 
 #include "adl/display.h"
 #include "adl/graphics.h"
 
-#define MIN_COMMAND 0xe0
-
 namespace Adl {
 
-#define NUM_PATTERNS 22
-#define PATTERN_LEN 4
-static const byte fillPatterns[NUM_PATTERNS][PATTERN_LEN] = {
-	{ 0x00, 0x00, 0x00, 0x00 },
-	{ 0x80, 0x80, 0x80, 0x80 },
-	{ 0xff, 0xff, 0xff, 0xff },
-	{ 0x7f, 0x7f, 0x7f, 0x7f },
-	{ 0x2a, 0x55, 0x2a, 0x55 },
-	{ 0xaa, 0xd5, 0xaa, 0xd5 },
-	{ 0x55, 0x2a, 0x55, 0x2a },
-	{ 0xd5, 0xaa, 0xd5, 0xaa },
-	{ 0x33, 0x66, 0x4c, 0x19 },
-	{ 0xb3, 0xe6, 0xcc, 0x99 },
-	{ 0x22, 0x44, 0x08, 0x11 },
-	{ 0xa2, 0xc4, 0x88, 0x91 },
-	{ 0x11, 0x22, 0x44, 0x08 },
-	{ 0x91, 0xa2, 0xc4, 0x88 },
-	{ 0x6e, 0x5d, 0x3b, 0x77 },
-	{ 0xee, 0xdd, 0xbb, 0xf7 },
-	{ 0x5d, 0x3b, 0x77, 0x6e },
-	{ 0xdd, 0xbb, 0xf7, 0xee },
-	{ 0x66, 0x4c, 0x19, 0x33 },
-	{ 0xe6, 0xcc, 0x99, 0xb3 },
-	{ 0x33, 0x66, 0x4c, 0x19 },
-	{ 0xb3, 0xe6, 0xcc, 0x99 }
-};
-
-#define CHECK_COMMAND(X) \
-	do { \
-		if ((X) >= MIN_COMMAND) { \
-			pic.seek(-1, SEEK_CUR); \
-			return; \
-		} \
-	} while (0)
-
-#define READ_BYTE(b) \
-	do { \
-		b = pic.readByte(); \
-		if (pic.eos() || pic.err()) \
-			return; \
-		CHECK_COMMAND(b); \
-	} while (0)
-
-#define READ_POINT(p) \
-	do { \
-		READ_BYTE(p.x); \
-		p.x <<= 1; \
-		READ_BYTE(p.y); \
-	} while (0)
-
 // Draws a four-connected line
-void Graphics::drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const {
+void GraphicsMan::drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const {
 	int16 deltaX = p2.x - p1.x;
 	int8 xStep = 1;
 
@@ -119,180 +66,4 @@ void Graphics::drawLine(const Common::Point &p1, const Common::Point &p2, byte c
 	}
 }
 
-void Graphics::clear() {
-	_display.clear(0xff);
-	_color = 0;
-}
-
-void Graphics::drawCorners(Common::SeekableReadStream &pic, bool yFirst) {
-	Common::Point p;
-
-	READ_POINT(p);
-
-	if (yFirst)
-		goto doYStep;
-
-	while (true) {
-		int16 n;
-
-		READ_BYTE(n);
-
-		_display.putPixel(p, _color);
-
-		n <<= 1;
-		drawLine(p, Common::Point(n, p.y), _color);
-		p.x = n;
-
-doYStep:
-		READ_BYTE(n);
-
-		_display.putPixel(p, _color);
-		drawLine(p, Common::Point(p.x, n), _color);
-
-		_display.putPixel(Common::Point(p.x + 1, p.y), _color);
-		drawLine(Common::Point(p.x + 1, p.y), Common::Point(p.x + 1, n), _color);
-
-		p.y = n;
-	}
-}
-
-void Graphics::drawRelativeLines(Common::SeekableReadStream &pic) {
-	Common::Point p1;
-
-	READ_POINT(p1);
-	_display.putPixel(p1, _color);
-
-	while (true) {
-		Common::Point p2(p1);
-
-		byte n;
-		READ_BYTE(n);
-
-		byte h = (n & 0x70) >> 4;
-		byte l = n & 7;
-
-		if (n & 0x80)
-			p2.x -= (h << 1);
-		else
-			p2.x += (h << 1);
-
-		if (n & 8)
-			p2.y -= l;
-		else
-			p2.y += l;
-
-		drawLine(p1, p2, _color);
-		p1 = p2;
-	}
-}
-
-void Graphics::drawAbsoluteLines(Common::SeekableReadStream &pic) {
-	Common::Point p1;
-
-	READ_POINT(p1);
-	_display.putPixel(p1, _color);
-
-	while (true) {
-		Common::Point p2;
-
-		READ_POINT(p2);
-		drawLine(p1, p2, _color);
-		p1 = p2;
-	}
-}
-
-static byte getPatternColor(const Common::Point &p, byte pattern) {
-	if (pattern >= NUM_PATTERNS)
-		error("Invalid fill pattern %i encountered", pattern);
-
-	byte offset = (p.y & 1) << 1;
-	offset += (p.x / 7) & 3;
-
-	return fillPatterns[pattern][offset % PATTERN_LEN];
-}
-
-void Graphics::fillRow(const Common::Point &p, bool stopBit, byte pattern) {
-	const byte color = getPatternColor(p, pattern);
-	_display.putPixelRaw(p, color);
-
-	Common::Point q(p);
-	byte c = color;
-
-	while (++q.x < DISPLAY_WIDTH && _display.getPixelBit(q) != stopBit) {
-		if ((q.x % 7) == 0)
-			c = getPatternColor(q, pattern);
-		_display.putPixelRaw(q, c);
-	}
-
-	q = p;
-	c = color;
-	while (--q.x >= 0 && _display.getPixelBit(q) != stopBit) {
-		if ((q.x % 7) == 6)
-			c = getPatternColor(q, pattern);
-		_display.putPixelRaw(q, c);
-	}
-}
-
-// Basic flood fill
-void Graphics::fill(Common::SeekableReadStream &pic) {
-	byte pattern;
-	READ_BYTE(pattern);
-
-	while (true) {
-		Common::Point p;
-		READ_POINT(p);
-
-		bool stopBit = !_display.getPixelBit(p);
-
-		while (--p.y >= 0) {
-			if (_display.getPixelBit(p) == stopBit)
-				break;
-			if (_display.getPixelBit(Common::Point(p.x + 1, p.y)) == stopBit)
-				break;
-		}
-
-		while (++p.y < DISPLAY_HEIGHT) {
-			if (_display.getPixelBit(p) == stopBit)
-				break;
-			if (_display.getPixelBit(Common::Point(p.x + 1, p.y)) == stopBit)
-				break;
-			fillRow(p, stopBit, pattern);
-		}
-	}
-}
-
-void Graphics::draw(Common::SeekableReadStream &pic) {
-	while (true) {
-		byte opcode = pic.readByte();
-
-		if (pic.eos() || pic.err())
-			error("Error reading picture");
-
-		switch (opcode) {
-		case 0xe0:
-			drawCorners(pic, false);
-			break;
-		case 0xe1:
-			drawCorners(pic, true);
-			break;
-		case 0xe2:
-			drawRelativeLines(pic);
-			break;
-		case 0xe3:
-			drawAbsoluteLines(pic);
-			break;
-		case 0xe4:
-			fill(pic);
-			break;
-		case 0xe5:
-			clear();
-			break;
-		case 0xff:
-			return;
-		default:
-			error("Invalid pic opcode %02x", opcode);
-		}
-	}
-}
-
 } // End of namespace Adl
diff --git a/engines/adl/graphics.h b/engines/adl/graphics.h
index 9c47820..ec29ee0 100644
--- a/engines/adl/graphics.h
+++ b/engines/adl/graphics.h
@@ -32,12 +32,32 @@ namespace Adl {
 
 class Display;
 
-class Graphics {
+class GraphicsMan {
 public:
-	Graphics(Display &display) : _display(display) { }
+	virtual ~GraphicsMan() { }
+	virtual void drawPic(Common::SeekableReadStream &pic, const Common::Point &pos, byte color) = 0;
 
+protected:
+	GraphicsMan(Display &display) : _display(display) { }
 	void drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const;
-	void draw(Common::SeekableReadStream &pic);
+
+	Display &_display;
+};
+
+class Graphics_v1 : public GraphicsMan {
+public:
+	Graphics_v1(Display &display) : GraphicsMan(display) { }
+	void drawPic(Common::SeekableReadStream &pic, const Common::Point &pos, byte color);
+	void drawCorners(Common::ReadStream &corners, const Common::Point &pos, byte rotation = 0, byte scaling = 1, byte color = 0x7f) const;
+
+private:
+	void drawCornerPixel(Common::Point &p, byte color, byte bits, byte quadrant) const;
+};
+
+class Graphics_v2 : public GraphicsMan {
+public:
+	Graphics_v2(Display &display) : GraphicsMan(display), _color(0) { }
+	void drawPic(Common::SeekableReadStream &pic, const Common::Point &pos, byte color);
 
 private:
 	void clear();
@@ -47,7 +67,6 @@ private:
 	void fillRow(const Common::Point &p, bool fillBit, byte pattern);
 	void fill(Common::SeekableReadStream &pic);
 
-	Display &_display;
 	byte _color;
 };
 
diff --git a/engines/adl/graphics_v1.cpp b/engines/adl/graphics_v1.cpp
new file mode 100644
index 0000000..edf16b8
--- /dev/null
+++ b/engines/adl/graphics_v1.cpp
@@ -0,0 +1,120 @@
+/* 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/stream.h"
+#include "common/rect.h"
+#include "common/textconsole.h"
+
+#include "adl/display.h"
+#include "adl/graphics.h"
+
+namespace Adl {
+
+void Graphics_v1::drawPic(Common::SeekableReadStream &pic, const Common::Point &pos, byte color) {
+	byte x, y;
+	bool bNewLine = false;
+	byte oldX = 0, oldY = 0;
+	while (1) {
+		x = pic.readByte();
+		y = pic.readByte();
+
+		if (pic.err() || pic.eos())
+			error("Error reading picture");
+
+		if (x == 0xff && y == 0xff)
+			return;
+
+		if (x == 0 && y == 0) {
+			bNewLine = true;
+			continue;
+		}
+
+		x += pos.x;
+		y += pos.y;
+
+		if (y > 160)
+			y = 160;
+
+		if (bNewLine) {
+			_display.putPixel(Common::Point(x, y), 0x7f);
+			bNewLine = false;
+		} else {
+			drawLine(Common::Point(oldX, oldY), Common::Point(x, y), 0x7f);
+		}
+
+		oldX = x;
+		oldY = y;
+	}
+}
+
+void Graphics_v1::drawCornerPixel(Common::Point &p, byte color, byte bits, byte quadrant) const {
+	if (bits & 4)
+		_display.putPixel(p, color);
+
+	bits += quadrant;
+
+	if (bits & 1)
+		p.x += (bits & 2 ? -1 : 1);
+	else
+		p.y += (bits & 2 ? 1 : -1);
+}
+
+void Graphics_v1::drawCorners(Common::ReadStream &corners, const Common::Point &pos, byte rotation, byte scaling, byte color) const {
+	const byte stepping[] = {
+		0xff, 0xfe, 0xfa, 0xf4, 0xec, 0xe1, 0xd4, 0xc5,
+		0xb4, 0xa1, 0x8d, 0x78, 0x61, 0x49, 0x31, 0x18,
+		0xff
+	};
+
+	byte quadrant = rotation >> 4;
+	rotation &= 0xf;
+	byte xStep = stepping[rotation];
+	byte yStep = stepping[(rotation ^ 0xf) + 1] + 1;
+
+	Common::Point p(pos);
+
+	while (true) {
+		byte b = corners.readByte();
+
+		if (corners.eos() || corners.err())
+			error("Error reading corners");
+
+		if (b == 0)
+			return;
+
+		do {
+			byte xFrac = 0x80;
+			byte yFrac = 0x80;
+			for (uint j = 0; j < scaling; ++j) {
+				if (xFrac + xStep + 1 > 255)
+					drawCornerPixel(p, color, b, quadrant);
+				xFrac += xStep + 1;
+				if (yFrac + yStep > 255)
+					drawCornerPixel(p, color, b, quadrant + 1);
+				yFrac += yStep;
+			}
+			b >>= 3;
+		} while (b != 0);
+	}
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/graphics_v2.cpp b/engines/adl/graphics_v2.cpp
new file mode 100644
index 0000000..289f43e
--- /dev/null
+++ b/engines/adl/graphics_v2.cpp
@@ -0,0 +1,260 @@
+/* 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/stream.h"
+#include "common/rect.h"
+#include "common/textconsole.h"
+
+#include "adl/display.h"
+#include "adl/graphics.h"
+
+namespace Adl {
+
+#define NUM_PATTERNS 22
+#define PATTERN_LEN 4
+static const byte fillPatterns[NUM_PATTERNS][PATTERN_LEN] = {
+	{ 0x00, 0x00, 0x00, 0x00 },
+	{ 0x80, 0x80, 0x80, 0x80 },
+	{ 0xff, 0xff, 0xff, 0xff },
+	{ 0x7f, 0x7f, 0x7f, 0x7f },
+	{ 0x2a, 0x55, 0x2a, 0x55 },
+	{ 0xaa, 0xd5, 0xaa, 0xd5 },
+	{ 0x55, 0x2a, 0x55, 0x2a },
+	{ 0xd5, 0xaa, 0xd5, 0xaa },
+	{ 0x33, 0x66, 0x4c, 0x19 },
+	{ 0xb3, 0xe6, 0xcc, 0x99 },
+	{ 0x22, 0x44, 0x08, 0x11 },
+	{ 0xa2, 0xc4, 0x88, 0x91 },
+	{ 0x11, 0x22, 0x44, 0x08 },
+	{ 0x91, 0xa2, 0xc4, 0x88 },
+	{ 0x6e, 0x5d, 0x3b, 0x77 },
+	{ 0xee, 0xdd, 0xbb, 0xf7 },
+	{ 0x5d, 0x3b, 0x77, 0x6e },
+	{ 0xdd, 0xbb, 0xf7, 0xee },
+	{ 0x66, 0x4c, 0x19, 0x33 },
+	{ 0xe6, 0xcc, 0x99, 0xb3 },
+	{ 0x33, 0x66, 0x4c, 0x19 },
+	{ 0xb3, 0xe6, 0xcc, 0x99 }
+};
+
+#define MIN_COMMAND 0xe0
+
+#define CHECK_COMMAND(X) \
+	do { \
+		if ((X) >= MIN_COMMAND) { \
+			pic.seek(-1, SEEK_CUR); \
+			return; \
+		} \
+	} while (0)
+
+#define READ_BYTE(b) \
+	do { \
+		b = pic.readByte(); \
+		if (pic.eos() || pic.err()) \
+			error("Error reading picture"); \
+		CHECK_COMMAND(b); \
+	} while (0)
+
+#define READ_POINT(p) \
+	do { \
+		READ_BYTE(p.x); \
+		p.x <<= 1; \
+		READ_BYTE(p.y); \
+	} while (0)
+
+void Graphics_v2::clear() {
+	_display.clear(0xff);
+	_color = 0;
+}
+
+void Graphics_v2::drawCorners(Common::SeekableReadStream &pic, bool yFirst) {
+	Common::Point p;
+
+	READ_POINT(p);
+
+	if (yFirst)
+		goto doYStep;
+
+	while (true) {
+		int16 n;
+
+		READ_BYTE(n);
+
+		_display.putPixel(p, _color);
+
+		n <<= 1;
+		drawLine(p, Common::Point(n, p.y), _color);
+		p.x = n;
+
+doYStep:
+		READ_BYTE(n);
+
+		_display.putPixel(p, _color);
+		drawLine(p, Common::Point(p.x, n), _color);
+
+		_display.putPixel(Common::Point(p.x + 1, p.y), _color);
+		drawLine(Common::Point(p.x + 1, p.y), Common::Point(p.x + 1, n), _color);
+
+		p.y = n;
+	}
+}
+
+void Graphics_v2::drawRelativeLines(Common::SeekableReadStream &pic) {
+	Common::Point p1;
+
+	READ_POINT(p1);
+	_display.putPixel(p1, _color);
+
+	while (true) {
+		Common::Point p2(p1);
+
+		byte n;
+		READ_BYTE(n);
+
+		byte h = (n & 0x70) >> 4;
+		byte l = n & 7;
+
+		if (n & 0x80)
+			p2.x -= (h << 1);
+		else
+			p2.x += (h << 1);
+
+		if (n & 8)
+			p2.y -= l;
+		else
+			p2.y += l;
+
+		drawLine(p1, p2, _color);
+		p1 = p2;
+	}
+}
+
+void Graphics_v2::drawAbsoluteLines(Common::SeekableReadStream &pic) {
+	Common::Point p1;
+
+	READ_POINT(p1);
+	_display.putPixel(p1, _color);
+
+	while (true) {
+		Common::Point p2;
+
+		READ_POINT(p2);
+		drawLine(p1, p2, _color);
+		p1 = p2;
+	}
+}
+
+static byte getPatternColor(const Common::Point &p, byte pattern) {
+	if (pattern >= NUM_PATTERNS)
+		error("Invalid fill pattern %i encountered in picture", pattern);
+
+	byte offset = (p.y & 1) << 1;
+	offset += (p.x / 7) & 3;
+
+	return fillPatterns[pattern][offset % PATTERN_LEN];
+}
+
+void Graphics_v2::fillRow(const Common::Point &p, bool stopBit, byte pattern) {
+	const byte color = getPatternColor(p, pattern);
+	_display.putPixelRaw(p, color);
+
+	Common::Point q(p);
+	byte c = color;
+
+	while (++q.x < DISPLAY_WIDTH && _display.getPixelBit(q) != stopBit) {
+		if ((q.x % 7) == 0)
+			c = getPatternColor(q, pattern);
+		_display.putPixelRaw(q, c);
+	}
+
+	q = p;
+	c = color;
+	while (--q.x >= 0 && _display.getPixelBit(q) != stopBit) {
+		if ((q.x % 7) == 6)
+			c = getPatternColor(q, pattern);
+		_display.putPixelRaw(q, c);
+	}
+}
+
+// Basic flood fill
+void Graphics_v2::fill(Common::SeekableReadStream &pic) {
+	byte pattern;
+	READ_BYTE(pattern);
+
+	while (true) {
+		Common::Point p;
+		READ_POINT(p);
+
+		bool stopBit = !_display.getPixelBit(p);
+
+		while (--p.y >= 0) {
+			if (_display.getPixelBit(p) == stopBit)
+				break;
+			if (_display.getPixelBit(Common::Point(p.x + 1, p.y)) == stopBit)
+				break;
+		}
+
+		while (++p.y < DISPLAY_HEIGHT) {
+			if (_display.getPixelBit(p) == stopBit)
+				break;
+			if (_display.getPixelBit(Common::Point(p.x + 1, p.y)) == stopBit)
+				break;
+			fillRow(p, stopBit, pattern);
+		}
+	}
+}
+
+void Graphics_v2::drawPic(Common::SeekableReadStream &pic, const Common::Point &pos, byte color) {
+	while (true) {
+		byte opcode = pic.readByte();
+
+		if (pic.eos() || pic.err())
+			error("Error reading picture");
+
+		switch (opcode) {
+		case 0xe0:
+			drawCorners(pic, false);
+			break;
+		case 0xe1:
+			drawCorners(pic, true);
+			break;
+		case 0xe2:
+			drawRelativeLines(pic);
+			break;
+		case 0xe3:
+			drawAbsoluteLines(pic);
+			break;
+		case 0xe4:
+			fill(pic);
+			break;
+		case 0xe5:
+			clear();
+			break;
+		case 0xff:
+			return;
+		default:
+			error("Invalid pic opcode %02x", opcode);
+		}
+	}
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 98e33ab..7354738 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -136,7 +136,9 @@ void HiRes1Engine::runIntro() const {
 	delay(2000);
 }
 
-void HiRes1Engine::loadData() {
+void HiRes1Engine::init() {
+	_graphics = new Graphics_v1(*_display);
+
 	Common::File f;
 
 	if (!f.open(IDS_HR1_MESSAGES))
@@ -196,21 +198,10 @@ void HiRes1Engine::loadData() {
 	}
 
 	// Load right-angle line art
-	f.seek(IDI_HR1_OFS_LINE_ART);
-	uint16 lineArtTotal = f.readUint16LE();
-	for (uint i = 0; i < lineArtTotal; ++i) {
-		f.seek(IDI_HR1_OFS_LINE_ART + 2 + i * 2);
-		uint16 offset = f.readUint16LE();
-		f.seek(IDI_HR1_OFS_LINE_ART + offset);
-
-		Common::Array<byte> lineArt;
-		byte b = f.readByte();
-		while (b != 0) {
-			lineArt.push_back(b);
-			b = f.readByte();
-		}
-		_lineArt.push_back(lineArt);
-	}
+	f.seek(IDI_HR1_OFS_CORNERS);
+	uint16 cornersCount = f.readUint16LE();
+	for (uint i = 0; i < cornersCount; ++i)
+		_corners.push_back(IDI_HR1_OFS_CORNERS + f.readUint16LE());
 
 	if (f.eos() || f.err())
 		error("Failed to read game data from '" IDS_HR1_EXE_1 "'");
@@ -290,7 +281,7 @@ void HiRes1Engine::drawPic(byte pic, Common::Point pos) const {
 		error("Failed to open file '%s'", name.c_str());
 
 	f.seek(_pictures[pic].offset);
-	drawPic(f, pos);
+	_graphics->drawPic(f, pos, 0x7f);
 }
 
 void HiRes1Engine::printMessage(uint idx, bool wait) const {
@@ -312,6 +303,16 @@ void HiRes1Engine::printMessage(uint idx, bool wait) const {
 	AdlEngine::printMessage(idx, wait);
 }
 
+void HiRes1Engine::drawItem(const Item &item, const Common::Point &pos) const {
+	if (item.isLineArt) {
+		Common::File *f = openFile(IDS_HR1_EXE_1);
+		f->seek(_corners[item.picture - 1]);
+		static_cast<Graphics_v1 *>(_graphics)->drawCorners(*f, pos);
+		delete f;
+	} else
+		drawPic(item.picture, pos);
+}
+
 void HiRes1Engine::showRoom() const {
 	if (!_state.isDark) {
 		drawPic(getCurRoom().curPicture);
@@ -322,82 +323,6 @@ void HiRes1Engine::showRoom() const {
 	printMessage(_roomDesc[_state.room - 1], false);
 }
 
-void HiRes1Engine::drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const {
-	// This draws a four-connected line
-
-	int16 deltaX = p2.x - p1.x;
-	int8 xStep = 1;
-
-	if (deltaX < 0) {
-		deltaX = -deltaX;
-		xStep = -1;
-	}
-
-	int16 deltaY = p2.y - p1.y;
-	int8 yStep = -1;
-
-	if (deltaY > 0) {
-		deltaY = -deltaY;
-		yStep = 1;
-	}
-
-	Common::Point p(p1);
-	int16 steps = deltaX - deltaY + 1;
-	int16 err = deltaX + deltaY;
-
-	while (1) {
-		_display->putPixel(p, color);
-
-		if (--steps == 0)
-			return;
-
-		if (err < 0) {
-			p.y += yStep;
-			err += deltaX;
-		} else {
-			p.x += xStep;
-			err += deltaY;
-		}
-	}
-}
-
-void HiRes1Engine::drawPic(Common::ReadStream &stream, const Common::Point &pos) const {
-	byte x, y;
-	bool bNewLine = false;
-	byte oldX = 0, oldY = 0;
-	while (1) {
-		x = stream.readByte();
-		y = stream.readByte();
-
-		if (stream.err() || stream.eos())
-			error("Failed to read picture");
-
-		if (x == 0xff && y == 0xff)
-			return;
-
-		if (x == 0 && y == 0) {
-			bNewLine = true;
-			continue;
-		}
-
-		x += pos.x;
-		y += pos.y;
-
-		if (y > 160)
-			y = 160;
-
-		if (bNewLine) {
-			_display->putPixel(Common::Point(x, y), 0x7f);
-			bNewLine = false;
-		} else {
-			drawLine(Common::Point(oldX, oldY), Common::Point(x, y), 0x7f);
-		}
-
-		oldX = x;
-		oldY = y;
-	}
-}
-
 Engine *HiRes1Engine_create(OSystem *syst, const AdlGameDescription *gd) {
 	return new HiRes1Engine(syst, gd);
 }
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index 02cec01..96e2fd0 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -26,6 +26,7 @@
 #include "common/str.h"
 
 #include "adl/adl.h"
+#include "adl/graphics.h"
 
 namespace Common {
 class ReadStream;
@@ -82,7 +83,7 @@ namespace Adl {
 #define IDI_HR1_OFS_CMDS_1       0x3d00
 
 #define IDI_HR1_OFS_ITEM_OFFSETS 0x68ff
-#define IDI_HR1_OFS_LINE_ART     0x4f00
+#define IDI_HR1_OFS_CORNERS      0x4f00
 
 #define IDI_HR1_OFS_VERBS        0x3800
 #define IDI_HR1_OFS_NOUNS        0x0f00
@@ -94,16 +95,16 @@ public:
 private:
 	// AdlEngine
 	void runIntro() const;
-	void loadData();
+	void init();
 	void initState();
 	void restartGame();
 	void drawPic(byte pic, Common::Point pos = Common::Point()) const;
 	void printMessage(uint idx, bool wait = true) const;
+	void drawItem(const Item &item, const Common::Point &pos) const;
 	void showRoom() const;
 
-	void drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const;
-	void drawPic(Common::ReadStream &stream, const Common::Point &pos) const;
-
+	Common::File _exe;
+	Common::Array<uint> _corners;
 	Common::Array<byte> _roomDesc;
 };
 
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 7bdfde5..19f447e 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -51,7 +51,9 @@ void HiRes2Engine::runIntro() const {
 	delay(2000);
 }
 
-void HiRes2Engine::loadData() {
+void HiRes2Engine::init() {
+	_graphics = new Graphics_v2(*_display);
+
 	Common::File f;
 
 	if (!f.open(IDS_HR2_DISK_IMAGE))
@@ -122,8 +124,7 @@ void HiRes2Engine::restartGame() {
 }
 
 void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
-	// Temp hack
-	Graphics test(*_display);
+	// Temp hack to show a pic
 
 	Common::File f;
 
@@ -132,7 +133,7 @@ void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
 
 	f.seek(0x1000);
 
-	test.draw(f);
+	_graphics->drawPic(f, pos, 0);
 }
 
 void HiRes2Engine::showRoom() const {
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 05926ee..f09a62f 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -70,10 +70,11 @@ public:
 private:
 	// AdlEngine
 	void runIntro() const;
-	void loadData();
+	void init();
 	void initState();
 	void restartGame();
 	void drawPic(byte pic, Common::Point pos) const;
+	void drawItem(const Item &item, const Common::Point &pos) const { }
 	void showRoom() const;
 };
 
diff --git a/engines/adl/module.mk b/engines/adl/module.mk
index 6901279..de4d645 100644
--- a/engines/adl/module.mk
+++ b/engines/adl/module.mk
@@ -5,6 +5,8 @@ MODULE_OBJS := \
 	detection.o \
 	display.o \
 	graphics.o \
+	graphics_v1.o \
+	graphics_v2.o \
 	hires1.o \
 	hires2.o
 


Commit: 0686ba9de8f77a1928d2d7aa4736384eb0715494
    https://github.com/scummvm/scummvm/commit/0686ba9de8f77a1928d2d7aa4736384eb0715494
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Clean up file error handling

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/hires1.cpp
    engines/adl/hires2.cpp



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index a17339f..e25af25 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -85,12 +85,9 @@ Common::String AdlEngine::readStringAt(Common::SeekableReadStream &stream, uint
 	return readString(stream, until);
 }
 
-Common::File *AdlEngine::openFile(const Common::String &name) const {
-	Common::File *f = new Common::File();
-	if (!f->open(name))
+void AdlEngine::openFile(Common::File &file, const Common::String &name) const {
+	if (!file.open(name))
 		error("Error opening '%s'", name.c_str());
-
-	return f;
 }
 
 void AdlEngine::printMessage(uint idx, bool wait) const {
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index d8c631e..c457291 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -143,7 +143,7 @@ protected:
 
 	Common::String readString(Common::ReadStream &stream, byte until = 0) const;
 	Common::String readStringAt(Common::SeekableReadStream &stream, uint offset, byte until = 0) const;
-	Common::File *openFile(const Common::String &name) const;
+	void openFile(Common::File &file, const Common::String &name) const;
 
 	virtual void printMessage(uint idx, bool wait = true) const;
 	void delay(uint32 ms) const;
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 7354738..59a9e84 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -25,6 +25,7 @@
 #include "common/error.h"
 #include "common/file.h"
 #include "common/stream.h"
+#include "common/ptr.h"
 
 #include "adl/hires1.h"
 #include "adl/display.h"
@@ -34,8 +35,7 @@ namespace Adl {
 void HiRes1Engine::runIntro() const {
 	Common::File file;
 
-	if (!file.open(IDS_HR1_EXE_0))
-		error("Failed to open file '" IDS_HR1_EXE_0 "'");
+	openFile(file, IDS_HR1_EXE_0);
 
 	file.seek(IDI_HR1_OFS_LOGO_0);
 	_display->setMode(DISPLAY_MODE_HIRES);
@@ -49,8 +49,7 @@ void HiRes1Engine::runIntro() const {
 	_display->setMode(DISPLAY_MODE_TEXT);
 
 	Common::File basic;
-	if (!basic.open(IDS_HR1_LOADER))
-		error("Failed to open file '" IDS_HR1_LOADER "'");
+	openFile(basic, IDS_HR1_LOADER);
 
 	Common::String str;
 
@@ -126,10 +125,8 @@ void HiRes1Engine::runIntro() const {
 
 	_display->setMode(DISPLAY_MODE_MIXED);
 
-	if (!file.open(IDS_HR1_EXE_1))
-		error("Failed to open file '" IDS_HR1_EXE_1 "'");
-
 	// Title screen shown during loading
+	openFile(file, IDS_HR1_EXE_1);
 	file.seek(IDI_HR1_OFS_LOGO_1);
 	_display->loadFrameBuffer(file);
 	_display->updateHiResScreen();
@@ -140,17 +137,13 @@ void HiRes1Engine::init() {
 	_graphics = new Graphics_v1(*_display);
 
 	Common::File f;
-
-	if (!f.open(IDS_HR1_MESSAGES))
-		error("Failed to open file '" IDS_HR1_MESSAGES "'");
+	openFile(f, IDS_HR1_MESSAGES);
 
 	for (uint i = 0; i < IDI_HR1_NUM_MESSAGES; ++i)
 		_messages.push_back(readString(f, APPLECHAR('\r')) + APPLECHAR('\r'));
 
 	f.close();
-
-	if (!f.open(IDS_HR1_EXE_1))
-		error("Failed to open file '" IDS_HR1_EXE_1 "'");
+	openFile(f, IDS_HR1_EXE_1);
 
 	// Some messages have overrides inside the executable
 	_messages[IDI_HR1_MSG_CANT_GO_THERE - 1] = readStringAt(f, IDI_HR1_OFS_STR_CANT_GO_THERE);
@@ -223,8 +216,7 @@ void HiRes1Engine::initState() {
 	_state.vars.clear();
 	_state.vars.resize(IDI_HR1_NUM_VARS);
 
-	if (!f.open(IDS_HR1_EXE_1))
-		error("Failed to open file '" IDS_HR1_EXE_1 "'");
+	openFile(f, IDS_HR1_EXE_1);
 
 	// Load room data from executable
 	_state.rooms.clear();
@@ -277,9 +269,7 @@ void HiRes1Engine::drawPic(byte pic, Common::Point pos) const {
 	Common::File f;
 	Common::String name = Common::String::format("BLOCK%i", _pictures[pic].block);
 
-	if (!f.open(name))
-		error("Failed to open file '%s'", name.c_str());
-
+	openFile(f, name);
 	f.seek(_pictures[pic].offset);
 	_graphics->drawPic(f, pos, 0x7f);
 }
@@ -305,10 +295,10 @@ void HiRes1Engine::printMessage(uint idx, bool wait) const {
 
 void HiRes1Engine::drawItem(const Item &item, const Common::Point &pos) const {
 	if (item.isLineArt) {
-		Common::File *f = openFile(IDS_HR1_EXE_1);
-		f->seek(_corners[item.picture - 1]);
-		static_cast<Graphics_v1 *>(_graphics)->drawCorners(*f, pos);
-		delete f;
+		Common::File f;
+		openFile(f, IDS_HR1_EXE_1);
+		f.seek(_corners[item.picture - 1]);
+		static_cast<Graphics_v1 *>(_graphics)->drawCorners(f, pos);
 	} else
 		drawPic(item.picture, pos);
 }
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 19f447e..3655b2a 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -34,10 +34,7 @@ namespace Adl {
 
 void HiRes2Engine::runIntro() const {
 	Common::File f;
-
-	if (!f.open(IDS_HR2_DISK_IMAGE))
-		error("Failed to open file '" IDS_HR2_DISK_IMAGE "'");
-
+	openFile(f, IDS_HR2_DISK_IMAGE);
 	f.seek(IDI_HR2_OFS_INTRO_TEXT);
 
 	_display->setMode(DISPLAY_MODE_TEXT);
@@ -55,9 +52,7 @@ void HiRes2Engine::init() {
 	_graphics = new Graphics_v2(*_display);
 
 	Common::File f;
-
-	if (!f.open(IDS_HR2_DISK_IMAGE))
-		error("Failed to open file '" IDS_HR2_DISK_IMAGE "'");
+	openFile(f, IDS_HR2_DISK_IMAGE);
 
 	for (uint i = 0; i < IDI_HR2_NUM_MESSAGES; ++i) {
 		f.seek(IDI_HR2_OFS_MESSAGES + i * 4);
@@ -97,9 +92,7 @@ void HiRes2Engine::init() {
 
 void HiRes2Engine::initState() {
 	Common::File f;
-
-	if (!f.open(IDS_HR2_DISK_IMAGE))
-		error("Failed to open file '" IDS_HR2_DISK_IMAGE "'");
+	openFile(f, IDS_HR2_DISK_IMAGE);
 
 	_state.rooms.clear();
 	f.seek(IDI_HR2_OFS_ROOMS);
@@ -127,10 +120,7 @@ void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
 	// Temp hack to show a pic
 
 	Common::File f;
-
-	if (!f.open(IDS_HR2_DISK_IMAGE))
-		error("Failed to open file '" IDS_HR2_DISK_IMAGE "'");
-
+	openFile(f, IDS_HR2_DISK_IMAGE);
 	f.seek(0x1000);
 
 	_graphics->drawPic(f, pos, 0);


Commit: b4aea80723460417f3514c8d27a41d69195cd23f
    https://github.com/scummvm/scummvm/commit/b4aea80723460417f3514c8d27a41d69195cd23f
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Implement hires2 word wrapping

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/display.cpp
    engines/adl/display.h
    engines/adl/hires1.cpp
    engines/adl/hires1.h
    engines/adl/hires2.cpp
    engines/adl/hires2.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index e25af25..3ce3989 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -161,12 +161,13 @@ Common::String AdlEngine::inputString(byte prompt) const {
 	}
 }
 
-byte AdlEngine::inputKey() const {
+byte AdlEngine::inputKey(bool showCursor) const {
 	Common::EventManager *ev = g_system->getEventManager();
 
 	byte key = 0;
 
-	_display->showCursor(true);
+	if (showCursor)
+		_display->showCursor(true);
 
 	while (!g_engine->shouldQuit() && !_isRestoring && key == 0) {
 		Common::Event event;
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index c457291..b118a37 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -149,7 +149,7 @@ protected:
 	void delay(uint32 ms) const;
 
 	Common::String inputString(byte prompt = 0) const;
-	byte inputKey() const;
+	byte inputKey(bool showCursor = true) const;
 
 	void loadWords(Common::ReadStream &stream, WordMap &map) const;
 	void readCommands(Common::ReadStream &stream, Commands &commands);
@@ -215,7 +215,7 @@ private:
 	virtual void initState() = 0;
 	virtual void restartGame() = 0;
 	virtual void drawItem(const Item &item, const Common::Point &pos) const = 0;
-	virtual void showRoom() const = 0;
+	virtual void showRoom() = 0;
 
 	// Engine
 	Common::Error run();
diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp
index 3795973..2ecfbeb 100644
--- a/engines/adl/display.cpp
+++ b/engines/adl/display.cpp
@@ -41,8 +41,6 @@ namespace Adl {
 #define DISPLAY_PITCH (DISPLAY_WIDTH / 7)
 #define DISPLAY_SIZE (DISPLAY_PITCH * DISPLAY_HEIGHT)
 
-#define TEXT_WIDTH 40
-#define TEXT_HEIGHT 24
 #define TEXT_BUF_SIZE (TEXT_WIDTH * TEXT_HEIGHT)
 
 #define COLOR_PALETTE_ENTRIES 8
@@ -291,21 +289,23 @@ void Display::moveCursorTo(const Common::Point &pos) {
 		error("Cursor position (%i, %i) out of bounds", pos.x, pos.y);
 }
 
+// FIXME: This does not currently update the surfaces
+void Display::printChar(char c) {
+	if (c == APPLECHAR('\r'))
+		_cursorPos = (_cursorPos / TEXT_WIDTH + 1) * TEXT_WIDTH;
+	else if ((byte)c < 0x80 || (byte)c >= 0xa0) {
+		setCharAtCursor(c);
+		++_cursorPos;
+	}
+
+	if (_cursorPos == TEXT_BUF_SIZE)
+		scrollUp();
+}
+
 void Display::printString(const Common::String &str) {
 	Common::String::const_iterator c;
-	for (c = str.begin(); c != str.end(); ++c) {
-		byte b = *c;
-
-		if (*c == APPLECHAR('\r'))
-			_cursorPos = (_cursorPos / TEXT_WIDTH + 1) * TEXT_WIDTH;
-		else if (b < 0x80 || b >= 0xa0) {
-			setCharAtCursor(b);
-			++_cursorPos;
-		}
-
-		if (_cursorPos == TEXT_BUF_SIZE)
-			scrollUp();
-	}
+	for (c = str.begin(); c != str.end(); ++c)
+		printChar(*c);
 
 	updateTextScreen();
 }
diff --git a/engines/adl/display.h b/engines/adl/display.h
index 67d8bf4..2946a7e 100644
--- a/engines/adl/display.h
+++ b/engines/adl/display.h
@@ -40,6 +40,8 @@ namespace Adl {
 
 #define DISPLAY_WIDTH 280
 #define DISPLAY_HEIGHT 192
+#define TEXT_WIDTH 40
+#define TEXT_HEIGHT 24
 
 enum DisplayMode {
 	DISPLAY_MODE_HIRES,
@@ -71,6 +73,7 @@ public:
 	void moveCursorTo(const Common::Point &pos);
 	void moveCursorForward();
 	void moveCursorBackward();
+	void printChar(char c);
 	void printString(const Common::String &str);
 	void printAsciiString(const Common::String &str);
 	void setCharAtCursor(byte c);
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 59a9e84..438d9c2 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -303,7 +303,7 @@ void HiRes1Engine::drawItem(const Item &item, const Common::Point &pos) const {
 		drawPic(item.picture, pos);
 }
 
-void HiRes1Engine::showRoom() const {
+void HiRes1Engine::showRoom() {
 	if (!_state.isDark) {
 		drawPic(getCurRoom().curPicture);
 		drawItems();
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index 96e2fd0..028148b 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -101,7 +101,7 @@ private:
 	void drawPic(byte pic, Common::Point pos = Common::Point()) const;
 	void printMessage(uint idx, bool wait = true) const;
 	void drawItem(const Item &item, const Common::Point &pos) const;
-	void showRoom() const;
+	void showRoom();
 
 	Common::File _exe;
 	Common::Array<uint> _corners;
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 3655b2a..575bab9 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -110,6 +110,17 @@ void HiRes2Engine::initState() {
 		f.readByte(); // always 1, possibly disk?
 		_state.rooms.push_back(room);
 	}
+
+	loadRoom(_state.room);
+}
+
+void HiRes2Engine::loadRoom(uint i) {
+	Common::File f;
+	openFile(f, IDS_HR2_DISK_IMAGE);
+	Room &room = getRoom(i);
+	uint offset = TSO(room.track, room.sector, room.offset);
+	f.seek(offset);
+	_roomData.description = readStringAt(f, offset + f.readByte(), 0xff);
 }
 
 void HiRes2Engine::restartGame() {
@@ -126,9 +137,72 @@ void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
 	_graphics->drawPic(f, pos, 0);
 }
 
-void HiRes2Engine::showRoom() const {
+void HiRes2Engine::showRoom() {
+	_linesPrinted = 0;
 	drawPic(0, Common::Point());
 	_display->updateHiResScreen();
+	printString(_roomData.description);
+}
+
+void HiRes2Engine::checkTextOverflow(char c) {
+	if (c != APPLECHAR('\r'))
+		return;
+
+	++_linesPrinted;
+
+	if (_linesPrinted < 4)
+		return;
+
+	_linesPrinted = 0;
+	// Bell
+
+	while (true) {
+		char key = inputKey(false);
+
+		if (shouldQuit())
+			return;
+
+		if (key == APPLECHAR('\r'))
+			break;
+
+		// Bell
+		// Bell
+		// Bell
+	}
+}
+
+void HiRes2Engine::printString(const Common::String &str) {
+	Common::String s(str);
+	byte endPos = TEXT_WIDTH - 1;
+	byte pos = 0;
+
+	while (true) {
+		while (pos != endPos && pos != s.size()) {
+			s.setChar(APPLECHAR(s[pos]), pos);
+			++pos;
+		}
+
+		if (pos == s.size())
+			break;
+
+		while (s[pos] != APPLECHAR(' ') && s[pos] != APPLECHAR('\r'))
+			--pos;
+
+		s.setChar(APPLECHAR('\r'), pos);
+		endPos = pos + TEXT_WIDTH;
+		++pos;
+	}
+
+	pos = 0;
+	while (pos != s.size()) {
+		checkTextOverflow(s[pos]);
+		_display->printChar(s[pos]);
+		++pos;
+	}
+
+	checkTextOverflow(APPLECHAR('\r'));
+	_display->printChar(APPLECHAR('\r'));
+	_display->updateTextScreen();
 }
 
 Engine *HiRes2Engine_create(OSystem *syst, const AdlGameDescription *gd) {
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index f09a62f..91bbf0a 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -63,9 +63,20 @@ namespace Adl {
 #define IDI_HR2_OFS_STR_PLAY_AGAIN    TSO(0x1a, 0x8, 0x25)
 #define IDI_HR2_OFS_STR_PRESS_RETURN  TSO(0x1a, 0x8, 0x5f)
 
+struct Picture2 {
+	byte track;
+	byte sector;
+	byte offset;
+};
+
+struct RoomData {
+	Common::String description;
+	Common::Array<Picture2> pictures;
+};
+
 class HiRes2Engine : public AdlEngine {
 public:
-	HiRes2Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine(syst, gd) { }
+	HiRes2Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine(syst, gd), _linesPrinted(0) { }
 
 private:
 	// AdlEngine
@@ -75,7 +86,14 @@ private:
 	void restartGame();
 	void drawPic(byte pic, Common::Point pos) const;
 	void drawItem(const Item &item, const Common::Point &pos) const { }
-	void showRoom() const;
+	void showRoom();
+
+	void loadRoom(uint i);
+	void checkTextOverflow(char c);
+	void printString(const Common::String &str);
+
+	RoomData _roomData;
+	uint _linesPrinted;
 };
 
 } // End of namespace Adl


Commit: 0664b51d2f3c61a2cba64cc6c42b00d86057d908
    https://github.com/scummvm/scummvm/commit/0664b51d2f3c61a2cba64cc6c42b00d86057d908
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Add bell function

Changed paths:
  A engines/adl/speaker.cpp
  A engines/adl/speaker.h
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/module.mk



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 3ce3989..74fc93c 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -39,12 +39,14 @@
 #include "adl/display.h"
 #include "adl/detection.h"
 #include "adl/graphics.h"
+#include "adl/speaker.h"
 
 namespace Adl {
 
 AdlEngine::~AdlEngine() {
 	delete _display;
 	delete _graphics;
+	delete _speaker;
 }
 
 AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) :
@@ -62,6 +64,24 @@ AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) :
 		_canRestoreNow(false) {
 }
 
+bool AdlEngine::pollEvent(Common::Event &event) {
+	if (g_system->getEventManager()->pollEvent(event)) {
+		if (event.type != Common::EVENT_KEYDOWN)
+			return false;
+
+		if (event.kbd.flags & Common::KBD_CTRL) {
+			if (event.kbd.keycode == Common::KEYCODE_q) {
+				quitGame();
+				return false;
+			}
+		}
+
+		return true;
+	}
+
+	return false;
+}
+
 Common::String AdlEngine::readString(Common::ReadStream &stream, byte until) const {
 	Common::String str;
 
@@ -100,23 +120,11 @@ void AdlEngine::printMessage(uint idx, bool wait) const {
 }
 
 void AdlEngine::delay(uint32 ms) const {
-	Common::EventManager *ev = g_system->getEventManager();
-
 	uint32 start = g_system->getMillis();
 
-	while (!g_engine->shouldQuit() && g_system->getMillis() - start < ms) {
+	while (!shouldQuit() && g_system->getMillis() - start < ms) {
 		Common::Event event;
-		if (ev->pollEvent(event)) {
-			if (event.type == Common::EVENT_KEYDOWN && (event.kbd.flags & Common::KBD_CTRL)) {
-				switch(event.kbd.keycode) {
-				case Common::KEYCODE_q:
-					g_engine->quitGame();
-					break;
-				default:
-					break;
-				}
-			}
-		}
+		pollEvent(event);
 		g_system->delayMillis(16);
 	}
 }
@@ -130,7 +138,7 @@ Common::String AdlEngine::inputString(byte prompt) const {
 	while (1) {
 		byte b = inputKey();
 
-		if (g_engine->shouldQuit() || _isRestoring)
+		if (shouldQuit() || _isRestoring)
 			return 0;
 
 		if (b == 0)
@@ -162,25 +170,17 @@ Common::String AdlEngine::inputString(byte prompt) const {
 }
 
 byte AdlEngine::inputKey(bool showCursor) const {
-	Common::EventManager *ev = g_system->getEventManager();
-
 	byte key = 0;
 
 	if (showCursor)
 		_display->showCursor(true);
 
-	while (!g_engine->shouldQuit() && !_isRestoring && key == 0) {
+	while (!shouldQuit() && !_isRestoring && key == 0) {
 		Common::Event event;
-		if (ev->pollEvent(event)) {
+		if (pollEvent(event)) {
 			if (event.type != Common::EVENT_KEYDOWN)
 				continue;
 
-			if (event.kbd.flags & Common::KBD_CTRL) {
-				if (event.kbd.keycode == Common::KEYCODE_q)
-					g_engine->quitGame();
-				continue;
-			}
-
 			switch (event.kbd.keycode) {
 			case Common::KEYCODE_BACKSPACE:
 			case Common::KEYCODE_RETURN:
@@ -307,6 +307,10 @@ void AdlEngine::drawItems() const {
 	}
 }
 
+void AdlEngine::bell(uint count) const {
+	_speaker->bell(count);
+}
+
 const Room &AdlEngine::getRoom(uint i) const {
 	if (i < 1 || i > _state.rooms.size())
 		error("Room %i out of range [1, %i]", i, _state.rooms.size());
@@ -403,6 +407,7 @@ void AdlEngine::dropItem(byte noun) {
 }
 
 Common::Error AdlEngine::run() {
+	_speaker = new Speaker();
 	_display = new Display();
 
 	init();
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index b118a37..9ccd02b 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -26,18 +26,26 @@
 #include "common/array.h"
 #include "common/rect.h"
 #include "common/str.h"
+#include "common/hashmap.h"
+#include "common/hash-str.h"
 
 #include "engines/engine.h"
 
+#include "audio/mixer.h"
+#include "audio/softsynth/pcspk.h"
+
 namespace Common {
 class ReadStream;
 class SeekableReadStream;
+class File;
+struct Event;
 }
 
 namespace Adl {
 
 class Display;
 class GraphicsMan;
+class Speaker;
 struct AdlGameDescription;
 
 // Conditional opcodes
@@ -138,6 +146,8 @@ class AdlEngine : public Engine {
 public:
 	virtual ~AdlEngine();
 
+	static bool pollEvent(Common::Event &event);
+
 protected:
 	AdlEngine(OSystem *syst, const AdlGameDescription *gd);
 
@@ -158,6 +168,9 @@ protected:
 	void clearScreen() const;
 	void drawItems() const;
 
+	// Sound
+	void bell(uint count = 1) const;
+
 	// Game state functions
 	const Room &getRoom(uint i) const;
 	Room &getRoom(uint i);
@@ -176,6 +189,7 @@ protected:
 
 	Display *_display;
 	GraphicsMan *_graphics;
+	Speaker *_speaker;
 
 	// Message strings in data file
 	Common::Array<Common::String> _messages;
diff --git a/engines/adl/module.mk b/engines/adl/module.mk
index de4d645..35e1228 100644
--- a/engines/adl/module.mk
+++ b/engines/adl/module.mk
@@ -8,7 +8,8 @@ MODULE_OBJS := \
 	graphics_v1.o \
 	graphics_v2.o \
 	hires1.o \
-	hires2.o
+	hires2.o \
+	speaker.o
 
 MODULE_DIRS += \
 	engines/adl
diff --git a/engines/adl/speaker.cpp b/engines/adl/speaker.cpp
new file mode 100644
index 0000000..532d361
--- /dev/null
+++ b/engines/adl/speaker.cpp
@@ -0,0 +1,94 @@
+/* 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/events.h"
+
+#include "engines/engine.h"
+
+#include "audio/audiostream.h"
+#include "audio/decoders/raw.h"
+
+#include "adl/speaker.h"
+#include "adl/adl.h"
+
+namespace Adl {
+
+// Number of times to duplicate each sample
+#define SAMPLE_DUP 4
+// Bell frequency in Hz
+#define BELL_FREQ 1000
+// Sample rate
+#define SAMPLE_RATE (BELL_FREQ * SAMPLE_DUP * 2)
+// Number of waves per 0.1 seconds (bell length)
+#define BELL_WAVE_COUNT (SAMPLE_RATE / 10 / SAMPLE_DUP / 2)
+// Length of bell in samples
+#define BELL_LEN (BELL_WAVE_COUNT * SAMPLE_DUP * 2)
+// Length of silence in samples
+#define SILENCE_LEN (SAMPLE_RATE / 80)
+
+Speaker::~Speaker() {
+	delete[] _bell;
+	delete[] _silence;
+}
+
+Speaker::Speaker() {
+	_bell = new byte[BELL_LEN];
+
+	byte *buf = _bell;
+	for (uint i = 0; i < BELL_WAVE_COUNT; ++i) {
+		for (uint j = 0; j < SAMPLE_DUP; ++j)
+			*buf++ = 0x00;
+		for (uint j = 0; j < SAMPLE_DUP; ++j)
+			*buf++ = 0xff;
+	}
+
+	_silence = new byte[SILENCE_LEN];
+
+	buf = _silence;
+	for (uint i = 0; i < SILENCE_LEN; ++i)
+		*buf++ = 0x80;
+}
+
+void Speaker::bell(uint count) {
+	Audio::QueuingAudioStream *stream = Audio::makeQueuingAudioStream(SAMPLE_RATE, false);
+	Audio::SoundHandle handle;
+
+	stream->queueBuffer(_bell, BELL_LEN, DisposeAfterUse::NO, Audio::FLAG_UNSIGNED);
+
+	for (uint i = 1; i < count; ++i) {
+		stream->queueBuffer(_silence, SILENCE_LEN, DisposeAfterUse::NO, Audio::FLAG_UNSIGNED);
+		stream->queueBuffer(_bell, BELL_LEN, DisposeAfterUse::NO, Audio::FLAG_UNSIGNED);
+	}
+
+	stream->finish();
+
+	g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &handle, stream);
+
+	while (!g_engine->shouldQuit() && g_system->getMixer()->isSoundHandleActive(handle)) {
+		Common::Event event;
+		static_cast<AdlEngine *>(g_engine)->pollEvent(event);
+		g_system->delayMillis(16);
+	}
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/speaker.h b/engines/adl/speaker.h
new file mode 100644
index 0000000..31aaac3
--- /dev/null
+++ b/engines/adl/speaker.h
@@ -0,0 +1,49 @@
+/* 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_SPEAKER_H
+#define ADL_SPEAKER_H
+
+#include "common/types.h"
+
+#include "audio/mixer.h"
+
+namespace Audio {
+class AudioStream;
+}
+
+namespace Adl {
+
+class Speaker {
+public:
+	Speaker();
+	~Speaker();
+
+	void bell(uint count);
+
+private:
+	byte *_bell, *_silence;
+};
+
+} // End of namespace Adl
+
+#endif


Commit: 7cef93739c24bb017e31bb2d5c359a93582426cd
    https://github.com/scummvm/scummvm/commit/7cef93739c24bb017e31bb2d5c359a93582426cd
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Hook up bell in hires2

Changed paths:
    engines/adl/hires2.cpp



diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 575bab9..19acf19 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -154,7 +154,8 @@ void HiRes2Engine::checkTextOverflow(char c) {
 		return;
 
 	_linesPrinted = 0;
-	// Bell
+	_display->updateTextScreen();
+	bell();
 
 	while (true) {
 		char key = inputKey(false);
@@ -165,9 +166,7 @@ void HiRes2Engine::checkTextOverflow(char c) {
 		if (key == APPLECHAR('\r'))
 			break;
 
-		// Bell
-		// Bell
-		// Bell
+		bell(3);
 	}
 }
 


Commit: 1e5fff86c875958408f3a5532451139626a4dc56
    https://github.com/scummvm/scummvm/commit/1e5fff86c875958408f3a5532451139626a4dc56
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Fix hires2 message printing

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/hires1.cpp
    engines/adl/hires1.h
    engines/adl/hires2.cpp
    engines/adl/hires2.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 74fc93c..81c9054 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -110,7 +110,7 @@ void AdlEngine::openFile(Common::File &file, const Common::String &name) const {
 		error("Error opening '%s'", name.c_str());
 }
 
-void AdlEngine::printMessage(uint idx, bool wait) const {
+void AdlEngine::printMessage(uint idx, bool wait) {
 	Common::String msg = _messages[idx - 1];
 	wordWrap(msg);
 	_display->printString(msg);
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 9ccd02b..20e8fbc 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -155,7 +155,7 @@ protected:
 	Common::String readStringAt(Common::SeekableReadStream &stream, uint offset, byte until = 0) const;
 	void openFile(Common::File &file, const Common::String &name) const;
 
-	virtual void printMessage(uint idx, bool wait = true) const;
+	virtual void printMessage(uint idx, bool wait = true);
 	void delay(uint32 ms) const;
 
 	Common::String inputString(byte prompt = 0) const;
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 438d9c2..368b08c 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -274,7 +274,7 @@ void HiRes1Engine::drawPic(byte pic, Common::Point pos) const {
 	_graphics->drawPic(f, pos, 0x7f);
 }
 
-void HiRes1Engine::printMessage(uint idx, bool wait) const {
+void HiRes1Engine::printMessage(uint idx, bool wait) {
 	// Messages with hardcoded overrides don't delay after printing.
 	// It's unclear if this is a bug or not. In some cases the result
 	// is that these strings will scroll past the four-line text window
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index 028148b..9c31a39 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -99,7 +99,7 @@ private:
 	void initState();
 	void restartGame();
 	void drawPic(byte pic, Common::Point pos = Common::Point()) const;
-	void printMessage(uint idx, bool wait = true) const;
+	void printMessage(uint idx, bool wait = true);
 	void drawItem(const Item &item, const Common::Point &pos) const;
 	void showRoom();
 
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 19acf19..f44dfc4 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -59,7 +59,7 @@ void HiRes2Engine::init() {
 		byte track = f.readByte();
 		byte sector = f.readByte();
 		byte offset = f.readByte();
-		// One more byte follows, disk?
+		// One more byte follows, disk? or size maybe?
 
 		uint diskOffset = TSO(track, sector, offset);
 
@@ -144,6 +144,10 @@ void HiRes2Engine::showRoom() {
 	printString(_roomData.description);
 }
 
+void HiRes2Engine::printMessage(uint idx, bool wait) {
+	printString(_messages[idx - 1]);
+}
+
 void HiRes2Engine::checkTextOverflow(char c) {
 	if (c != APPLECHAR('\r'))
 		return;
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 91bbf0a..d88e43a 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -87,6 +87,7 @@ private:
 	void drawPic(byte pic, Common::Point pos) const;
 	void drawItem(const Item &item, const Common::Point &pos) const { }
 	void showRoom();
+	void printMessage(uint idx, bool wait);
 
 	void loadRoom(uint i);
 	void checkTextOverflow(char c);


Commit: 0a6b7fb6a6414caa4d8654a75e07b6a33ef6cce3
    https://github.com/scummvm/scummvm/commit/0a6b7fb6a6414caa4d8654a75e07b6a33ef6cce3
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Add loading of room picture index for hires2

Changed paths:
    engines/adl/hires2.cpp
    engines/adl/hires2.h



diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index f44dfc4..226a8e3 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -110,17 +110,31 @@ void HiRes2Engine::initState() {
 		f.readByte(); // always 1, possibly disk?
 		_state.rooms.push_back(room);
 	}
-
-	loadRoom(_state.room);
 }
 
-void HiRes2Engine::loadRoom(uint i) {
+void HiRes2Engine::loadRoom(byte roomNr) {
 	Common::File f;
 	openFile(f, IDS_HR2_DISK_IMAGE);
-	Room &room = getRoom(i);
+	Room &room = getRoom(roomNr);
 	uint offset = TSO(room.track, room.sector, room.offset);
 	f.seek(offset);
-	_roomData.description = readStringAt(f, offset + f.readByte(), 0xff);
+	uint16 descOffset = f.readUint16LE();
+	/* uint16 commandOffset =*/ f.readUint16LE();
+
+	// There's no picture count. The original engine always checks at most
+	// five pictures. We use the description offset to bound our search.
+	uint16 picCount = (descOffset - 4) / 5;
+
+	for (uint i = 0; i < picCount; ++i) {
+		Picture2 pic;
+		pic.nr = f.readByte();
+		pic.track = f.readByte();
+		pic.sector = f.readByte();
+		pic.offset = f.readByte();
+		f.readByte();
+		_roomData.pictures.push_back(pic);
+	}
+	_roomData.description = readStringAt(f, offset + descOffset, 0xff);
 }
 
 void HiRes2Engine::restartGame() {
@@ -128,18 +142,24 @@ void HiRes2Engine::restartGame() {
 }
 
 void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
-	// Temp hack to show a pic
-
-	Common::File f;
-	openFile(f, IDS_HR2_DISK_IMAGE);
-	f.seek(0x1000);
+	Common::Array<Picture2>::const_iterator roomPic;
+
+	for (roomPic = _roomData.pictures.begin(); roomPic != _roomData.pictures.end(); ++roomPic) {
+		if (roomPic->nr == pic) {
+			Common::File f;
+			openFile(f, IDS_HR2_DISK_IMAGE);
+			f.seek(TSO(roomPic->track, roomPic->sector, roomPic->offset));
+			_graphics->drawPic(f, pos, 0);
+		}
+	}
 
-	_graphics->drawPic(f, pos, 0);
+	// Check global pic list here
 }
 
 void HiRes2Engine::showRoom() {
+	loadRoom(_state.room);
 	_linesPrinted = 0;
-	drawPic(0, Common::Point());
+	drawPic(getCurRoom().curPicture, Common::Point());
 	_display->updateHiResScreen();
 	printString(_roomData.description);
 }
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index d88e43a..58831c4 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -64,6 +64,7 @@ namespace Adl {
 #define IDI_HR2_OFS_STR_PRESS_RETURN  TSO(0x1a, 0x8, 0x5f)
 
 struct Picture2 {
+	byte nr;
 	byte track;
 	byte sector;
 	byte offset;
@@ -89,7 +90,7 @@ private:
 	void showRoom();
 	void printMessage(uint idx, bool wait);
 
-	void loadRoom(uint i);
+	void loadRoom(byte roomNr);
 	void checkTextOverflow(char c);
 	void printString(const Common::String &str);
 


Commit: 7ff7e0def4670fee3346c4b75aa1e79d2f684bb0
    https://github.com/scummvm/scummvm/commit/7ff7e0def4670fee3346c4b75aa1e79d2f684bb0
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Add hires2 command loading

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/hires2.cpp
    engines/adl/hires2.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 81c9054..1afc530 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -273,6 +273,11 @@ void AdlEngine::readCommands(Common::ReadStream &stream, Commands &commands) {
 	}
 }
 
+void AdlEngine::checkInput(byte verb, byte noun) {
+	if (!doOneCommand(_roomCommands, verb, noun))
+		printMessage(_messageIds.dontUnderstand);
+}
+
 void AdlEngine::clearScreen() const {
 	_display->setMode(DISPLAY_MODE_MIXED);
 	_display->clear(0x00);
@@ -448,8 +453,7 @@ Common::Error AdlEngine::run() {
 			// If we just restored from the GMM, we skip this command
 			// set, as no command has been input by the user
 			if (!_isRestoring)
-				if (!doOneCommand(_roomCommands, verb, noun))
-					printMessage(_messageIds.dontUnderstand);
+				checkInput(verb, noun);
 		}
 
 		if (_isRestoring) {
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 20e8fbc..97077f9 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -163,6 +163,7 @@ protected:
 
 	void loadWords(Common::ReadStream &stream, WordMap &map) const;
 	void readCommands(Common::ReadStream &stream, Commands &commands);
+	virtual void checkInput(byte verb, byte noun);
 
 	// Graphics
 	void clearScreen() const;
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 226a8e3..8b12746 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -83,6 +83,13 @@ void HiRes2Engine::init() {
 	_messageIds.itemNotHere = IDI_HR2_MSG_ITEM_NOT_HERE;
 	_messageIds.thanksForPlaying = IDI_HR2_MSG_THANKS_FOR_PLAYING;
 
+	// Load commands from executable
+	f.seek(IDI_HR2_OFS_CMDS_1);
+	readCommands(f, _roomCommands);
+
+	f.seek(IDI_HR2_OFS_CMDS_0);
+	// readCommands(f, _globalCommands);
+
 	f.seek(IDI_HR2_OFS_VERBS);
 	loadWords(f, _verbs);
 
@@ -91,6 +98,9 @@ void HiRes2Engine::init() {
 }
 
 void HiRes2Engine::initState() {
+	_state.vars.clear();
+	_state.vars.resize(IDI_HR2_NUM_VARS);
+
 	Common::File f;
 	openFile(f, IDS_HR2_DISK_IMAGE);
 
@@ -119,7 +129,7 @@ void HiRes2Engine::loadRoom(byte roomNr) {
 	uint offset = TSO(room.track, room.sector, room.offset);
 	f.seek(offset);
 	uint16 descOffset = f.readUint16LE();
-	/* uint16 commandOffset =*/ f.readUint16LE();
+	uint16 commandOffset = f.readUint16LE();
 
 	// There's no picture count. The original engine always checks at most
 	// five pictures. We use the description offset to bound our search.
@@ -134,7 +144,12 @@ void HiRes2Engine::loadRoom(byte roomNr) {
 		f.readByte();
 		_roomData.pictures.push_back(pic);
 	}
+
 	_roomData.description = readStringAt(f, offset + descOffset, 0xff);
+
+	f.seek(offset + commandOffset);
+
+	readCommands(f, _roomData.commands);
 }
 
 void HiRes2Engine::restartGame() {
@@ -158,16 +173,23 @@ void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
 
 void HiRes2Engine::showRoom() {
 	loadRoom(_state.room);
-	_linesPrinted = 0;
 	drawPic(getCurRoom().curPicture, Common::Point());
 	_display->updateHiResScreen();
 	printString(_roomData.description);
+	_linesPrinted = 0;
 }
 
 void HiRes2Engine::printMessage(uint idx, bool wait) {
 	printString(_messages[idx - 1]);
 }
 
+void HiRes2Engine::checkInput(byte verb, byte noun) {
+	if (doOneCommand(_roomData.commands, verb, noun))
+		return;
+
+	AdlEngine::checkInput(verb, noun);
+}
+
 void HiRes2Engine::checkTextOverflow(char c) {
 	if (c != APPLECHAR('\r'))
 		return;
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 58831c4..f9d6d92 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -47,8 +47,12 @@ namespace Adl {
 #define IDI_HR2_OFS_ROOMS      TSO(0x21, 0x5, 0x0e) // Skip bogus room 0
 #define IDI_HR2_OFS_MESSAGES   TSO(0x1f, 0x2, 0x04) // Skip bogus message 0
 
+#define IDI_HR2_OFS_CMDS_0      TS(0x1f, 0x7)
+#define IDI_HR2_OFS_CMDS_1      TS(0x1d, 0x7)
+
 #define IDI_HR2_NUM_ROOMS 135
 #define IDI_HR2_NUM_MESSAGES 254
+#define IDI_HR2_NUM_VARS 40
 
 // Messages used outside of scripts
 #define IDI_HR2_MSG_CANT_GO_THERE      123
@@ -73,6 +77,7 @@ struct Picture2 {
 struct RoomData {
 	Common::String description;
 	Common::Array<Picture2> pictures;
+	Commands commands;
 };
 
 class HiRes2Engine : public AdlEngine {
@@ -89,6 +94,7 @@ private:
 	void drawItem(const Item &item, const Common::Point &pos) const { }
 	void showRoom();
 	void printMessage(uint idx, bool wait);
+	void checkInput(byte verb, byte noun);
 
 	void loadRoom(byte roomNr);
 	void checkTextOverflow(char c);


Commit: 46528f2c04d593f50e8c1a04d25c6cd663c3d209
    https://github.com/scummvm/scummvm/commit/46528f2c04d593f50e8c1a04d25c6cd663c3d209
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Fix flood fill palette setting

Changed paths:
    engines/adl/display.cpp
    engines/adl/display.h
    engines/adl/graphics_v2.cpp



diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp
index 2ecfbeb..b7f6eb9 100644
--- a/engines/adl/display.cpp
+++ b/engines/adl/display.cpp
@@ -217,13 +217,6 @@ void Display::loadFrameBuffer(Common::ReadStream &stream) {
 		error("Failed to read frame buffer");
 }
 
-void Display::putPixelRaw(const Common::Point &p, byte color) {
-	byte *b = _frameBuf + p.y * DISPLAY_PITCH + (p.x / 7);
-	color ^= *b;
-	color &= 0x80 | (1 << (p.x % 7));
-	*b ^= color;
-}
-
 void Display::putPixel(const Common::Point &p, byte color) {
 	byte offset = p.x / 7;
 	byte mask = 0x80 | (1 << (p.x % 7));
@@ -241,14 +234,19 @@ void Display::putPixel(const Common::Point &p, byte color) {
 			color ^= 0x7f;
 	}
 
-	byte *b = _frameBuf + p.y * DISPLAY_PITCH + offset;
-	color ^= *b;
-	color &= mask;
-	*b ^= color;
+	writeFrameBuffer(p, color, mask);
+}
+
+void Display::setPixelBit(const Common::Point &p, byte color) {
+	writeFrameBuffer(p, color, 1 << (p.x % 7));
+}
+
+void Display::setPixelPalette(const Common::Point &p, byte color) {
+	writeFrameBuffer(p, color, 0x80);
 }
 
 bool Display::getPixelBit(const Common::Point &p) const {
-	byte *b = _frameBuf + p.y * DISPLAY_PITCH + (p.x / 7);
+	byte *b = _frameBuf + p.y * DISPLAY_PITCH + p.x / 7;
 	return *b & (1 << (p.x % 7));
 }
 
@@ -328,6 +326,13 @@ void Display::showCursor(bool enable) {
 	_showCursor = enable;
 }
 
+void Display::writeFrameBuffer(const Common::Point &p, byte color, byte mask) {
+	byte *b = _frameBuf + p.y * DISPLAY_PITCH + p.x / 7;
+	color ^= *b;
+	color &= mask;
+	*b ^= color;
+}
+
 void Display::showScanlines(bool enable) {
 	byte pal[COLOR_PALETTE_ENTRIES * 3] = { };
 
diff --git a/engines/adl/display.h b/engines/adl/display.h
index 2946a7e..bc27b7c 100644
--- a/engines/adl/display.h
+++ b/engines/adl/display.h
@@ -63,8 +63,9 @@ public:
 
 	// Graphics
 	void loadFrameBuffer(Common::ReadStream &stream);
-	void putPixelRaw(const Common::Point &p, byte color);
 	void putPixel(const Common::Point &p, byte color);
+	void setPixelBit(const Common::Point &p, byte color);
+	void setPixelPalette(const Common::Point &p, byte color);
 	bool getPixelBit(const Common::Point &p) const;
 	void clear(byte color);
 
@@ -80,6 +81,7 @@ public:
 	void showCursor(bool enable);
 
 private:
+	void writeFrameBuffer(const Common::Point &p, byte color, byte mask);
 	void updateHiResSurface();
 	void showScanlines(bool enable);
 
diff --git a/engines/adl/graphics_v2.cpp b/engines/adl/graphics_v2.cpp
index 289f43e..d829b95 100644
--- a/engines/adl/graphics_v2.cpp
+++ b/engines/adl/graphics_v2.cpp
@@ -26,6 +26,7 @@
 
 #include "adl/display.h"
 #include "adl/graphics.h"
+#include "adl/adl.h"
 
 namespace Adl {
 
@@ -175,23 +176,33 @@ static byte getPatternColor(const Common::Point &p, byte pattern) {
 
 void Graphics_v2::fillRow(const Common::Point &p, bool stopBit, byte pattern) {
 	const byte color = getPatternColor(p, pattern);
-	_display.putPixelRaw(p, color);
+	_display.setPixelPalette(p, color);
+	_display.setPixelBit(p, color);
 
 	Common::Point q(p);
 	byte c = color;
 
-	while (++q.x < DISPLAY_WIDTH && _display.getPixelBit(q) != stopBit) {
-		if ((q.x % 7) == 0)
+	while (++q.x < DISPLAY_WIDTH) {
+		if ((q.x % 7) == 0) {
 			c = getPatternColor(q, pattern);
-		_display.putPixelRaw(q, c);
+			// Palette is set before the first bit is tested
+			_display.setPixelPalette(q, c);
+		}
+		if (_display.getPixelBit(q) == stopBit)
+			break;
+		_display.setPixelBit(q, c);
 	}
 
 	q = p;
 	c = color;
-	while (--q.x >= 0 && _display.getPixelBit(q) != stopBit) {
-		if ((q.x % 7) == 6)
+	while (--q.x >= 0) {
+		if ((q.x % 7) == 6) {
 			c = getPatternColor(q, pattern);
-		_display.putPixelRaw(q, c);
+			_display.setPixelPalette(q, c);
+		}
+		if (_display.getPixelBit(q) == stopBit)
+			break;
+		_display.setPixelBit(q, c);
 	}
 }
 


Commit: df4daf954fe1bc379094b4a699267537f1f46916
    https://github.com/scummvm/scummvm/commit/df4daf954fe1bc379094b4a699267537f1f46916
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Load hires2 items

Changed paths:
    engines/adl/hires2.cpp
    engines/adl/hires2.h



diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 8b12746..8dba9a6 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -120,6 +120,32 @@ void HiRes2Engine::initState() {
 		f.readByte(); // always 1, possibly disk?
 		_state.rooms.push_back(room);
 	}
+
+	_state.items.clear();
+	f.seek(IDI_HR2_OFS_ITEMS);
+	while (f.readByte() != 0xff) {
+		Item item;
+		item.noun = f.readByte();
+		item.room = f.readByte();
+		item.picture = f.readByte();
+		item.isLineArt = f.readByte(); // Is this still used in this way?
+		item.position.x = f.readByte();
+		item.position.y = f.readByte();
+		item.state = f.readByte();
+		item.description = f.readByte();
+
+		f.readByte();
+
+		byte size = f.readByte();
+
+		for (uint i = 0; i < size; ++i)
+			item.roomPictures.push_back(f.readByte());
+
+		_state.items.push_back(item);
+
+		// One unknown extra byte compared to hires1
+		f.readByte();
+	}
 }
 
 void HiRes2Engine::loadRoom(byte roomNr) {
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index f9d6d92..6c7904b 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -46,6 +46,7 @@ namespace Adl {
 #define IDI_HR2_OFS_NOUNS       TS(0x22, 0x2)
 #define IDI_HR2_OFS_ROOMS      TSO(0x21, 0x5, 0x0e) // Skip bogus room 0
 #define IDI_HR2_OFS_MESSAGES   TSO(0x1f, 0x2, 0x04) // Skip bogus message 0
+#define IDI_HR2_OFS_ITEMS        T(0x21)
 
 #define IDI_HR2_OFS_CMDS_0      TS(0x1f, 0x7)
 #define IDI_HR2_OFS_CMDS_1      TS(0x1d, 0x7)


Commit: 0593460b1bd1d70e3848f1d5195d83384c347c92
    https://github.com/scummvm/scummvm/commit/0593460b1bd1d70e3848f1d5195d83384c347c92
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Enable global commands in hires2

Changed paths:
    engines/adl/hires2.cpp



diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 8dba9a6..be2e016 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -88,7 +88,7 @@ void HiRes2Engine::init() {
 	readCommands(f, _roomCommands);
 
 	f.seek(IDI_HR2_OFS_CMDS_0);
-	// readCommands(f, _globalCommands);
+	readCommands(f, _globalCommands);
 
 	f.seek(IDI_HR2_OFS_VERBS);
 	loadWords(f, _verbs);


Commit: a653fa2f459957029978f14618ff634ec3485cf8
    https://github.com/scummvm/scummvm/commit/a653fa2f459957029978f14618ff634ec3485cf8
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Add partial hires2 item drawing

Changed paths:
    engines/adl/graphics_v2.cpp
    engines/adl/hires1.cpp
    engines/adl/hires2.cpp
    engines/adl/hires2.h



diff --git a/engines/adl/graphics_v2.cpp b/engines/adl/graphics_v2.cpp
index d829b95..c705b9c 100644
--- a/engines/adl/graphics_v2.cpp
+++ b/engines/adl/graphics_v2.cpp
@@ -235,6 +235,8 @@ void Graphics_v2::fill(Common::SeekableReadStream &pic) {
 }
 
 void Graphics_v2::drawPic(Common::SeekableReadStream &pic, const Common::Point &pos, byte color) {
+	_color = color;
+
 	while (true) {
 		byte opcode = pic.readByte();
 
@@ -260,6 +262,30 @@ void Graphics_v2::drawPic(Common::SeekableReadStream &pic, const Common::Point &
 		case 0xe5:
 			clear();
 			break;
+		case 0xf0:
+			_color = 0x00;
+			break;
+		case 0xf1:
+			_color = 0x2a;
+			break;
+		case 0xf2:
+			_color = 0x55;
+			break;
+		case 0xf3:
+			_color = 0x7f;
+			break;
+		case 0xf4:
+			_color = 0x80;
+			break;
+		case 0xf5:
+			_color = 0xaa;
+			break;
+		case 0xf6:
+			_color = 0xd5;
+			break;
+		case 0xf7:
+			_color = 0xff;
+			break;
 		case 0xff:
 			return;
 		default:
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 368b08c..9527d4e 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -237,7 +237,7 @@ void HiRes1Engine::initState() {
 	_state.items.clear();
 	f.seek(IDI_HR1_OFS_ITEMS);
 	while (f.readByte() != 0xff) {
-		Item item;
+		Item item = { };
 		item.noun = f.readByte();
 		item.room = f.readByte();
 		item.picture = f.readByte();
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index be2e016..e547520 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -32,6 +32,14 @@
 
 namespace Adl {
 
+static void readPictureMeta(Common::ReadStream &f, Picture2 &pic) {
+	pic.nr = f.readByte();
+	pic.track = f.readByte();
+	pic.sector = f.readByte();
+	pic.offset = f.readByte();
+	f.readByte();
+}
+
 void HiRes2Engine::runIntro() const {
 	Common::File f;
 	openFile(f, IDS_HR2_DISK_IMAGE);
@@ -83,6 +91,14 @@ void HiRes2Engine::init() {
 	_messageIds.itemNotHere = IDI_HR2_MSG_ITEM_NOT_HERE;
 	_messageIds.thanksForPlaying = IDI_HR2_MSG_THANKS_FOR_PLAYING;
 
+	// Load item picture data
+	f.seek(IDI_HR2_OFS_ITEM_PICS);
+	for (uint i = 0; i < IDI_HR2_NUM_ITEM_PICS; ++i) {
+		Picture2 pic;
+		readPictureMeta(f, pic);
+		_itemPics.push_back(pic);
+	}
+
 	// Load commands from executable
 	f.seek(IDI_HR2_OFS_CMDS_1);
 	readCommands(f, _roomCommands);
@@ -124,7 +140,7 @@ void HiRes2Engine::initState() {
 	_state.items.clear();
 	f.seek(IDI_HR2_OFS_ITEMS);
 	while (f.readByte() != 0xff) {
-		Item item;
+		Item item = { };
 		item.noun = f.readByte();
 		item.room = f.readByte();
 		item.picture = f.readByte();
@@ -134,17 +150,17 @@ void HiRes2Engine::initState() {
 		item.state = f.readByte();
 		item.description = f.readByte();
 
-		f.readByte();
+		f.readByte(); // Struct size
 
-		byte size = f.readByte();
+		byte picListSize = f.readByte();
+
+		// Flag to keep track of what has been drawn on the screen
+		f.readByte();
 
-		for (uint i = 0; i < size; ++i)
+		for (uint i = 0; i < picListSize; ++i)
 			item.roomPictures.push_back(f.readByte());
 
 		_state.items.push_back(item);
-
-		// One unknown extra byte compared to hires1
-		f.readByte();
 	}
 }
 
@@ -163,11 +179,7 @@ void HiRes2Engine::loadRoom(byte roomNr) {
 
 	for (uint i = 0; i < picCount; ++i) {
 		Picture2 pic;
-		pic.nr = f.readByte();
-		pic.track = f.readByte();
-		pic.sector = f.readByte();
-		pic.offset = f.readByte();
-		f.readByte();
+		readPictureMeta(f, pic);
 		_roomData.pictures.push_back(pic);
 	}
 
@@ -191,15 +203,26 @@ void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
 			openFile(f, IDS_HR2_DISK_IMAGE);
 			f.seek(TSO(roomPic->track, roomPic->sector, roomPic->offset));
 			_graphics->drawPic(f, pos, 0);
+			return;
 		}
 	}
 
 	// Check global pic list here
 }
 
+void HiRes2Engine::drawItem(const Item &item, const Common::Point &pos) const {
+	const Picture2 &pic = _itemPics[item.picture - 1];
+	Common::File f;
+	openFile(f, IDS_HR2_DISK_IMAGE);
+	f.seek(TSO(pic.track, pic.sector, pic.offset));
+	f.readByte(); // Skip clear opcode
+	_graphics->drawPic(f, pos, 0);
+}
+
 void HiRes2Engine::showRoom() {
 	loadRoom(_state.room);
 	drawPic(getCurRoom().curPicture, Common::Point());
+	drawItems();
 	_display->updateHiResScreen();
 	printString(_roomData.description);
 	_linesPrinted = 0;
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 6c7904b..631b341 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -46,6 +46,7 @@ namespace Adl {
 #define IDI_HR2_OFS_NOUNS       TS(0x22, 0x2)
 #define IDI_HR2_OFS_ROOMS      TSO(0x21, 0x5, 0x0e) // Skip bogus room 0
 #define IDI_HR2_OFS_MESSAGES   TSO(0x1f, 0x2, 0x04) // Skip bogus message 0
+#define IDI_HR2_OFS_ITEM_PICS  TSO(0x1e, 0x9, 0x05) // Skip bogus pic 0
 #define IDI_HR2_OFS_ITEMS        T(0x21)
 
 #define IDI_HR2_OFS_CMDS_0      TS(0x1f, 0x7)
@@ -54,6 +55,7 @@ namespace Adl {
 #define IDI_HR2_NUM_ROOMS 135
 #define IDI_HR2_NUM_MESSAGES 254
 #define IDI_HR2_NUM_VARS 40
+#define IDI_HR2_NUM_ITEM_PICS 38
 
 // Messages used outside of scripts
 #define IDI_HR2_MSG_CANT_GO_THERE      123
@@ -92,7 +94,7 @@ private:
 	void initState();
 	void restartGame();
 	void drawPic(byte pic, Common::Point pos) const;
-	void drawItem(const Item &item, const Common::Point &pos) const { }
+	void drawItem(const Item &item, const Common::Point &pos) const;
 	void showRoom();
 	void printMessage(uint idx, bool wait);
 	void checkInput(byte verb, byte noun);
@@ -102,6 +104,7 @@ private:
 	void printString(const Common::String &str);
 
 	RoomData _roomData;
+	Common::Array<Picture2> _itemPics;
 	uint _linesPrinted;
 };
 


Commit: 6fd580fb6661e6cf2e7935aae925457e7c92e822
    https://github.com/scummvm/scummvm/commit/6fd580fb6661e6cf2e7935aae925457e7c92e822
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Add pic offsetting

Changed paths:
    engines/adl/graphics.h
    engines/adl/graphics_v2.cpp



diff --git a/engines/adl/graphics.h b/engines/adl/graphics.h
index ec29ee0..95f4159 100644
--- a/engines/adl/graphics.h
+++ b/engines/adl/graphics.h
@@ -68,6 +68,7 @@ private:
 	void fill(Common::SeekableReadStream &pic);
 
 	byte _color;
+	Common::Point _offset;
 };
 
 } // End of namespace Adl
diff --git a/engines/adl/graphics_v2.cpp b/engines/adl/graphics_v2.cpp
index c705b9c..7da4eed 100644
--- a/engines/adl/graphics_v2.cpp
+++ b/engines/adl/graphics_v2.cpp
@@ -30,6 +30,8 @@
 
 namespace Adl {
 
+// FIXME: Add clipping
+
 #define NUM_PATTERNS 22
 #define PATTERN_LEN 4
 static const byte fillPatterns[NUM_PATTERNS][PATTERN_LEN] = {
@@ -78,8 +80,10 @@ static const byte fillPatterns[NUM_PATTERNS][PATTERN_LEN] = {
 #define READ_POINT(p) \
 	do { \
 		READ_BYTE(p.x); \
+		p.x += _offset.x; \
 		p.x <<= 1; \
 		READ_BYTE(p.y); \
+		p.y += _offset.y; \
 	} while (0)
 
 void Graphics_v2::clear() {
@@ -99,6 +103,7 @@ void Graphics_v2::drawCorners(Common::SeekableReadStream &pic, bool yFirst) {
 		int16 n;
 
 		READ_BYTE(n);
+		n += _offset.x;
 
 		_display.putPixel(p, _color);
 
@@ -108,6 +113,7 @@ void Graphics_v2::drawCorners(Common::SeekableReadStream &pic, bool yFirst) {
 
 doYStep:
 		READ_BYTE(n);
+		n += _offset.y;
 
 		_display.putPixel(p, _color);
 		drawLine(p, Common::Point(p.x, n), _color);
@@ -236,6 +242,7 @@ void Graphics_v2::fill(Common::SeekableReadStream &pic) {
 
 void Graphics_v2::drawPic(Common::SeekableReadStream &pic, const Common::Point &pos, byte color) {
 	_color = color;
+	_offset = pos;
 
 	while (true) {
 		byte opcode = pic.readByte();


Commit: c0b33afc4a41e3c00dfafa6e1262ce17ed68c15c
    https://github.com/scummvm/scummvm/commit/c0b33afc4a41e3c00dfafa6e1262ce17ed68c15c
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Load hires2 dropped item offsets

Changed paths:
    engines/adl/adl.cpp
    engines/adl/hires2.cpp
    engines/adl/hires2.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 1afc530..bd1cc84 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -304,7 +304,8 @@ void AdlEngine::drawItems() const {
 		Common::Array<byte>::const_iterator pic;
 
 		for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
-			if (*pic == getCurRoom().curPicture) {
+			// IDI_NONE check was added in hires2
+			if (*pic == getCurRoom().curPicture || *pic == IDI_NONE) {
 				drawItem(*item, item->position);
 				continue;
 			}
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index e547520..b99f9fc 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -106,6 +106,15 @@ void HiRes2Engine::init() {
 	f.seek(IDI_HR2_OFS_CMDS_0);
 	readCommands(f, _globalCommands);
 
+	// Load dropped item offsets
+	f.seek(IDI_HR2_OFS_ITEM_OFFSETS);
+	for (uint i = 0; i < IDI_HR2_NUM_ITEM_OFFSETS; ++i) {
+		Common::Point p;
+		p.x = f.readByte();
+		p.y = f.readByte();
+		_itemOffsets.push_back(p);
+	}
+
 	f.seek(IDI_HR2_OFS_VERBS);
 	loadWords(f, _verbs);
 
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 631b341..516ea52 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -41,21 +41,23 @@ namespace Adl {
 #define TS(TRACK, SECTOR) TSO(TRACK, SECTOR, 0)
 #define T(TRACK) TS(TRACK, 0)
 
-#define IDI_HR2_OFS_INTRO_TEXT TSO(0x00, 0xd, 0x17)
-#define IDI_HR2_OFS_VERBS        T(0x19)
-#define IDI_HR2_OFS_NOUNS       TS(0x22, 0x2)
-#define IDI_HR2_OFS_ROOMS      TSO(0x21, 0x5, 0x0e) // Skip bogus room 0
-#define IDI_HR2_OFS_MESSAGES   TSO(0x1f, 0x2, 0x04) // Skip bogus message 0
-#define IDI_HR2_OFS_ITEM_PICS  TSO(0x1e, 0x9, 0x05) // Skip bogus pic 0
-#define IDI_HR2_OFS_ITEMS        T(0x21)
-
-#define IDI_HR2_OFS_CMDS_0      TS(0x1f, 0x7)
-#define IDI_HR2_OFS_CMDS_1      TS(0x1d, 0x7)
+#define IDI_HR2_OFS_INTRO_TEXT   TSO(0x00, 0xd, 0x17)
+#define IDI_HR2_OFS_VERBS          T(0x19)
+#define IDI_HR2_OFS_NOUNS         TS(0x22, 0x2)
+#define IDI_HR2_OFS_ROOMS        TSO(0x21, 0x5, 0x0e) // Skip bogus room 0
+#define IDI_HR2_OFS_MESSAGES     TSO(0x1f, 0x2, 0x04) // Skip bogus message 0
+#define IDI_HR2_OFS_ITEM_PICS    TSO(0x1e, 0x9, 0x05) // Skip bogus pic 0
+#define IDI_HR2_OFS_ITEMS          T(0x21)
+#define IDI_HR2_OFS_ITEM_OFFSETS TSO(0x1b, 0x4, 0x15)
+
+#define IDI_HR2_OFS_CMDS_0        TS(0x1f, 0x7)
+#define IDI_HR2_OFS_CMDS_1        TS(0x1d, 0x7)
 
 #define IDI_HR2_NUM_ROOMS 135
 #define IDI_HR2_NUM_MESSAGES 254
 #define IDI_HR2_NUM_VARS 40
 #define IDI_HR2_NUM_ITEM_PICS 38
+#define IDI_HR2_NUM_ITEM_OFFSETS 16
 
 // Messages used outside of scripts
 #define IDI_HR2_MSG_CANT_GO_THERE      123


Commit: 64cf93198fc560d31cc24003d164f656751d2e76
    https://github.com/scummvm/scummvm/commit/64cf93198fc560d31cc24003d164f656751d2e76
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Use functors to implement opcodes

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index bd1cc84..ad5f559 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -278,6 +278,71 @@ void AdlEngine::checkInput(byte verb, byte noun) {
 		printMessage(_messageIds.dontUnderstand);
 }
 
+typedef Common::Functor1Mem<ScriptEnv &, bool, AdlEngine> OpcodeV1;
+#define SetOpcodeTable(x) table = &x;
+#define Opcode(x) table->push_back(new OpcodeV1(this, &AdlEngine::x))
+#define OpcodeUnImpl() table->push_back(new OpcodeV1(this, 0))
+
+void AdlEngine::setupOpcodeTables() {
+	Common::Array<const Opcode *> *table = 0;
+
+	SetOpcodeTable(_condOpcodes);
+	// 0x00
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	Opcode(o1_isItemInRoom);
+	// 0x04
+	OpcodeUnImpl();
+	Opcode(o1_isMovesGrEq);
+	Opcode(o1_isVarEq);
+	OpcodeUnImpl();
+	// 0x08
+	OpcodeUnImpl();
+	Opcode(o1_isCurPicEq);
+	Opcode(o1_isItemPicEq);
+
+	SetOpcodeTable(_actOpcodes);
+	// 0x00
+	OpcodeUnImpl();
+	Opcode(o1_varAdd);
+	Opcode(o1_varSub);
+	Opcode(o1_varSet);
+	// 0x04
+	Opcode(o1_listInv);
+	Opcode(o1_moveItem);
+	Opcode(o1_setRoom);
+	Opcode(o1_setCurPic);
+	// 0x08
+	Opcode(o1_setPic);
+	Opcode(o1_printMsg);
+	Opcode(o1_setLight);
+	Opcode(o1_setDark);
+	// 0x0c
+	OpcodeUnImpl();
+	Opcode(o1_quit);
+	OpcodeUnImpl();
+	Opcode(o1_save);
+	// 0x10
+	Opcode(o1_restore);
+	Opcode(o1_restart);
+	Opcode(o1_placeItem);
+	Opcode(o1_setItemPic);
+	// 0x14
+	Opcode(o1_resetPic);
+	Opcode(o1_goDirection);
+	Opcode(o1_goDirection);
+	Opcode(o1_goDirection);
+	// 0x18
+	Opcode(o1_goDirection);
+	Opcode(o1_goDirection);
+	Opcode(o1_goDirection);
+	Opcode(o1_takeItem);
+	// 0x1c
+	Opcode(o1_dropItem);
+	Opcode(o1_setRoomPic);
+}
+
 void AdlEngine::clearScreen() const {
 	_display->setMode(DISPLAY_MODE_MIXED);
 	_display->clear(0x00);
@@ -416,6 +481,8 @@ Common::Error AdlEngine::run() {
 	_speaker = new Speaker();
 	_display = new Display();
 
+	setupOpcodeTables();
+
 	init();
 
 	int saveSlot = ConfMan.getInt("save_slot");
@@ -657,8 +724,9 @@ bool AdlEngine::canSaveGameStateCurrently() {
 	// "SAVE GAME". This prevents saving via the GMM in situations where
 	// it wouldn't otherwise be possible to do so.
 	for (cmd = _roomCommands.begin(); cmd != _roomCommands.end(); ++cmd) {
+		ScriptEnv env(*cmd, _saveVerb, _saveNoun);
 		uint offset;
-		if (matchCommand(*cmd, _saveVerb, _saveNoun, &offset))
+		if (matchCommand(env, &offset))
 			return cmd->script[offset] == IDO_ACT_SAVE;
 	}
 
@@ -784,198 +852,249 @@ void AdlEngine::getInput(uint &verb, uint &noun) {
 	}
 }
 
-#define ARG(N) (command.script[offset + (N)])
+typedef Common::Functor1Mem<ScriptEnv &, bool, AdlEngine> OpcodeV1;
 
-bool AdlEngine::matchCommand(const Command &command, byte verb, byte noun, uint *actions) const {
-	if (command.room != IDI_NONE && command.room != _state.room)
+#define ARG(N) (env.cmd.script[env.ip + (N)])
+
+bool AdlEngine::o1_isItemInRoom(ScriptEnv &env) {
+	if (getItem(ARG(1)).room != ARG(2))
 		return false;
+	env.ip += 3;
+	return true;
+}
 
-	if (command.verb != IDI_NONE && command.verb != verb)
+bool AdlEngine::o1_isMovesGrEq(ScriptEnv &env) {
+	if (ARG(1) > _state.moves)
 		return false;
+	env.ip += 2;
+	return true;
+}
 
-	if (command.noun != IDI_NONE && command.noun != noun)
+bool AdlEngine::o1_isVarEq(ScriptEnv &env) {
+	if (getVar(ARG(1)) != ARG(2))
 		return false;
+	env.ip += 3;
+	return true;
+}
 
-	uint offset = 0;
-	for (uint i = 0; i < command.numCond; ++i) {
-		switch (ARG(0)) {
-		case IDO_CND_ITEM_IN_ROOM:
-			if (getItem(ARG(1)).room != ARG(2))
-				return false;
-			offset += 3;
-			break;
-		case IDO_CND_MOVES_GE:
-			if (ARG(1) > _state.moves)
-				return false;
-			offset += 2;
-			break;
-		case IDO_CND_VAR_EQ:
-			if (getVar(ARG(1)) != ARG(2))
-				return false;
-			offset += 3;
-			break;
-		case IDO_CND_CUR_PIC_EQ:
-			if (getCurRoom().curPicture != ARG(1))
-				return false;
-			offset += 2;
-			break;
-		case IDO_CND_ITEM_PIC_EQ:
-			if (getItem(ARG(1)).picture != ARG(2))
-				return false;
-			offset += 3;
-			break;
-		default:
-			error("Invalid condition opcode %02x", command.script[offset]);
-		}
+bool AdlEngine::o1_isCurPicEq(ScriptEnv &env) {
+	if (getCurRoom().curPicture != ARG(1))
+		return false;
+	env.ip += 2;
+	return true;
+}
+
+bool AdlEngine::o1_isItemPicEq(ScriptEnv &env) {
+	if (getItem(ARG(1)).picture != ARG(2))
+		return false;
+	env.ip += 3;
+	return true;
+}
+
+bool AdlEngine::o1_varAdd(ScriptEnv &env) {
+	setVar(ARG(2), getVar(ARG(2) + ARG(1)));
+	env.ip += 3;
+	return true;
+}
+
+bool AdlEngine::o1_varSub(ScriptEnv &env) {
+	setVar(ARG(2), getVar(ARG(2)) - ARG(1));
+	env.ip += 3;
+	return true;
+}
+
+bool AdlEngine::o1_varSet(ScriptEnv &env) {
+	setVar(ARG(1), ARG(2));
+	env.ip += 3;
+	return true;
+}
+
+bool AdlEngine::o1_listInv(ScriptEnv &env) {
+	Common::Array<Item>::const_iterator item;
+
+	for (item = _state.items.begin(); item != _state.items.end(); ++item)
+		if (item->room == IDI_NONE)
+			printMessage(item->description);
+
+	++env.ip;
+	return true;
+}
+
+bool AdlEngine::o1_moveItem(ScriptEnv &env) {
+	getItem(ARG(1)).room = ARG(2);
+	env.ip += 3;
+	return true;
+}
+
+bool AdlEngine::o1_setRoom(ScriptEnv &env) {
+	getCurRoom().curPicture = getCurRoom().picture;
+	_state.room = ARG(1);
+	env.ip += 2;
+	return true;
+}
+
+bool AdlEngine::o1_setCurPic(ScriptEnv &env) {
+	getCurRoom().curPicture = ARG(1);
+	env.ip += 2;
+	return true;
+}
+
+bool AdlEngine::o1_setPic(ScriptEnv &env) {
+	getCurRoom().picture = getCurRoom().curPicture = ARG(1);
+	env.ip += 2;
+	return true;
+}
+
+bool AdlEngine::o1_printMsg(ScriptEnv &env) {
+	printMessage(ARG(1));
+	env.ip += 2;
+	return true;
+}
+
+bool AdlEngine::o1_setLight(ScriptEnv &env) {
+	_state.isDark = false;
+	++env.ip;
+	return true;
+}
+
+bool AdlEngine::o1_setDark(ScriptEnv &env) {
+	_state.isDark = true;
+	++env.ip;
+	return true;
+}
+
+bool AdlEngine::o1_save(ScriptEnv &env) {
+	saveGameState(0, "");
+	++env.ip;
+	return true;
+}
+
+bool AdlEngine::o1_restore(ScriptEnv &env) {
+	loadGameState(0);
+	++env.ip;
+	_isRestoring = false;
+	return true;
+}
+
+bool AdlEngine::o1_restart(ScriptEnv &env) {
+	_display->printString(_strings.playAgain);
+	Common::String input = inputString();
+
+	if (input.size() == 0 || input[0] != APPLECHAR('N')) {
+		_isRestarting = true;
+		_display->clear(0x00);
+		_display->updateHiResScreen();
+		restartGame();
+		return false;
 	}
 
-	if (actions)
-		*actions = offset;
+	return o1_quit(env);
+}
+
+bool AdlEngine::o1_quit(ScriptEnv &env) {
+	printMessage(_messageIds.thanksForPlaying);
+	quitGame();
+	return false;
+}
 
+bool AdlEngine::o1_placeItem(ScriptEnv &env) {
+	getItem(ARG(1)).room = ARG(2);
+	getItem(ARG(1)).position.x = ARG(3);
+	getItem(ARG(1)).position.y = ARG(4);
+	env.ip += 5;
 	return true;
 }
 
-void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
-	for (uint i = 0; i < command.numAct; ++i) {
-		switch (ARG(0)) {
-		case IDO_ACT_VAR_ADD:
-			setVar(ARG(2), getVar(ARG(2) + ARG(1)));
-			offset += 3;
-			break;
-		case IDO_ACT_VAR_SUB:
-			setVar(ARG(2), getVar(ARG(2)) - ARG(1));
-			offset += 3;
-			break;
-		case IDO_ACT_VAR_SET:
-			setVar(ARG(1), ARG(2));
-			offset += 3;
-			break;
-		case IDO_ACT_LIST_ITEMS: {
-			Common::Array<Item>::const_iterator item;
+bool AdlEngine::o1_setItemPic(ScriptEnv &env) {
+	getItem(ARG(2)).picture = ARG(1);
+	env.ip += 3;
+	return true;
+}
 
-			for (item = _state.items.begin(); item != _state.items.end(); ++item)
-				if (item->room == IDI_NONE)
-					printMessage(item->description);
+bool AdlEngine::o1_resetPic(ScriptEnv &env) {
+	getCurRoom().curPicture = getCurRoom().picture;
+	++env.ip;
+	return true;
+}
 
-			++offset;
-			break;
-		}
-		case IDO_ACT_MOVE_ITEM:
-			getItem(ARG(1)).room = ARG(2);
-			offset += 3;
-			break;
-		case IDO_ACT_SET_ROOM:
-			getCurRoom().curPicture = getCurRoom().picture;
-			_state.room = ARG(1);
-			offset += 2;
-			break;
-		case IDO_ACT_SET_CUR_PIC:
-			getCurRoom().curPicture = ARG(1);
-			offset += 2;
-			break;
-		case IDO_ACT_SET_PIC:
-			getCurRoom().picture = getCurRoom().curPicture = ARG(1);
-			offset += 2;
-			break;
-		case IDO_ACT_PRINT_MSG:
-			printMessage(ARG(1));
-			offset += 2;
-			break;
-		case IDO_ACT_SET_LIGHT:
-			_state.isDark = false;
-			++offset;
-			break;
-		case IDO_ACT_SET_DARK:
-			_state.isDark = true;
-			++offset;
-			break;
-		case IDO_ACT_SAVE:
-			saveGameState(0, "");
-			++offset;
-			break;
-		case IDO_ACT_LOAD:
-			loadGameState(0);
-			++offset;
-			// Original engine does not jump out of the loop,
-			// so we don't either.
-			// We reset the restore flag, as the restore game
-			// process is complete
-			_isRestoring = false;
-			break;
-		case IDO_ACT_RESTART: {
-			_display->printString(_strings.playAgain);
-			Common::String input = inputString();
-			if (input.size() == 0 || input[0] != APPLECHAR('N')) {
-				_isRestarting = true;
-				_display->clear(0x00);
-				_display->updateHiResScreen();
-				restartGame();
-				return;
-			}
-			// Fall-through
-		}
-		case IDO_ACT_QUIT:
-			printMessage(_messageIds.thanksForPlaying);
-			quitGame();
-			return;
-		case IDO_ACT_PLACE_ITEM:
-			getItem(ARG(1)).room = ARG(2);
-			getItem(ARG(1)).position.x = ARG(3);
-			getItem(ARG(1)).position.y = ARG(4);
-			offset += 5;
-			break;
-		case IDO_ACT_SET_ITEM_PIC:
-			getItem(ARG(2)).picture = ARG(1);
-			offset += 3;
-			break;
-		case IDO_ACT_RESET_PIC:
-			getCurRoom().curPicture = getCurRoom().picture;
-			++offset;
-			break;
-		case IDO_ACT_GO_NORTH:
-		case IDO_ACT_GO_SOUTH:
-		case IDO_ACT_GO_EAST:
-		case IDO_ACT_GO_WEST:
-		case IDO_ACT_GO_UP:
-		case IDO_ACT_GO_DOWN: {
-			byte room = getCurRoom().connections[ARG(0) - IDO_ACT_GO_NORTH];
-
-			if (room == 0) {
-				printMessage(_messageIds.cantGoThere);
-				return;
-			}
+bool AdlEngine::o1_goDirection(ScriptEnv &env) {
+	byte room = getCurRoom().connections[ARG(0) - IDO_ACT_GO_NORTH];
 
-			getCurRoom().curPicture = getCurRoom().picture;
-			_state.room = room;
-			return;
-		}
-		case IDO_ACT_TAKE_ITEM:
-			takeItem(noun);
-			++offset;
-			break;
-		case IDO_ACT_DROP_ITEM:
-			dropItem(noun);
-			++offset;
-			break;
-		case IDO_ACT_SET_ROOM_PIC:
-			getRoom(ARG(1)).picture = getRoom(ARG(1)).curPicture = ARG(2);
-			offset += 3;
-			break;
-		default:
-			error("Invalid action opcode %02x", ARG(0));
-		}
+	if (room == 0) {
+		printMessage(_messageIds.cantGoThere);
+		return false;
 	}
+
+	getCurRoom().curPicture = getCurRoom().picture;
+	_state.room = room;
+	return false;
+}
+
+bool AdlEngine::o1_takeItem(ScriptEnv &env) {
+	takeItem(env.noun);
+	++env.ip;
+	return true;
+}
+
+bool AdlEngine::o1_dropItem(ScriptEnv &env) {
+	dropItem(env.noun);
+	++env.ip;
+	return true;
+}
+
+bool AdlEngine::o1_setRoomPic(ScriptEnv &env) {
+	getRoom(ARG(1)).picture = getRoom(ARG(1)).curPicture = ARG(2);
+	env.ip += 3;
+	return true;
 }
 
 #undef ARG
 
+bool AdlEngine::matchCommand(ScriptEnv &env, uint *actions) const {
+	if (env.cmd.room != IDI_NONE && env.cmd.room != _state.room)
+		return false;
+
+	if (env.cmd.verb != IDI_NONE && env.cmd.verb != env.verb)
+		return false;
+
+	if (env.cmd.noun != IDI_NONE && env.cmd.noun != env.noun)
+		return false;
+
+	for (uint i = 0; i < env.cmd.numCond; ++i) {
+		byte op = env.cmd.script[env.ip];
+
+		if (!_condOpcodes[op] || !_condOpcodes[op]->isValid())
+			error("Unimplemented condition opcode %02x", op);
+
+		if (!(*_condOpcodes[op])(env))
+			return false;
+	}
+
+	if (actions)
+		*actions = env.ip;
+
+	return true;
+}
+
+void AdlEngine::doActions(ScriptEnv &env) {
+	for (uint i = 0; i < env.cmd.numAct; ++i) {
+		byte op = env.cmd.script[env.ip];
+
+		if (!_actOpcodes[op] || !_actOpcodes[op]->isValid())
+			error("Unimplemented action opcode %02x", op);
+
+		if (!(*_actOpcodes[op])(env))
+			return;
+	}
+}
+
 bool AdlEngine::doOneCommand(const Commands &commands, byte verb, byte noun) {
 	Commands::const_iterator cmd;
 
 	for (cmd = commands.begin(); cmd != commands.end(); ++cmd) {
-		uint offset = 0;
-		if (matchCommand(*cmd, verb, noun, &offset)) {
-			doActions(*cmd, noun, offset);
+		ScriptEnv env(*cmd, verb, noun);
+		if (matchCommand(env)) {
+			doActions(env);
 			return true;
 		}
 	}
@@ -987,9 +1106,9 @@ void AdlEngine::doAllCommands(const Commands &commands, byte verb, byte noun) {
 	Commands::const_iterator cmd;
 
 	for (cmd = commands.begin(); cmd != commands.end(); ++cmd) {
-		uint offset = 0;
-		if (matchCommand(*cmd, verb, noun, &offset))
-			doActions(*cmd, noun, offset);
+		ScriptEnv env(*cmd, verb, noun);
+		if (matchCommand(env))
+			doActions(env);
 	}
 }
 
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 97077f9..e007b15 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -28,6 +28,7 @@
 #include "common/str.h"
 #include "common/hashmap.h"
 #include "common/hash-str.h"
+#include "common/func.h"
 
 #include "engines/engine.h"
 
@@ -47,6 +48,9 @@ class Display;
 class GraphicsMan;
 class Speaker;
 struct AdlGameDescription;
+struct ScriptEnv;
+
+typedef Common::Functor1<ScriptEnv &, bool> Opcode;
 
 // Conditional opcodes
 #define IDO_CND_ITEM_IN_ROOM   0x03
@@ -101,11 +105,22 @@ struct Picture {
 	uint16 offset;
 };
 
+typedef Common::Array<byte> Script;
+
 struct Command {
 	byte room;
 	byte verb, noun;
 	byte numCond, numAct;
-	Common::Array<byte> script;
+	Script script;
+};
+
+struct ScriptEnv {
+	ScriptEnv(const Command &cmd_, byte verb_, byte noun_) :
+			cmd(cmd_), verb(verb_), noun(noun_), ip(0) { }
+
+	const Command &cmd;
+	byte verb, noun;
+	byte ip;
 };
 
 enum {
@@ -165,6 +180,38 @@ protected:
 	void readCommands(Common::ReadStream &stream, Commands &commands);
 	virtual void checkInput(byte verb, byte noun);
 
+	virtual void setupOpcodeTables();
+
+	// Opcodes
+	bool o1_isItemInRoom(ScriptEnv &env);
+	bool o1_isMovesGrEq(ScriptEnv &env);
+	bool o1_isVarEq(ScriptEnv &env);
+	bool o1_isCurPicEq(ScriptEnv &env);
+	bool o1_isItemPicEq(ScriptEnv &env);
+
+	bool o1_varAdd(ScriptEnv &env);
+	bool o1_varSub(ScriptEnv &env);
+	bool o1_varSet(ScriptEnv &env);
+	bool o1_listInv(ScriptEnv &env);
+	bool o1_moveItem(ScriptEnv &env);
+	bool o1_setRoom(ScriptEnv &env);
+	bool o1_setCurPic(ScriptEnv &env);
+	bool o1_setPic(ScriptEnv &env);
+	bool o1_printMsg(ScriptEnv &env);
+	bool o1_setLight(ScriptEnv &env);
+	bool o1_setDark(ScriptEnv &env);
+	bool o1_save(ScriptEnv &env);
+	bool o1_restore(ScriptEnv &env);
+	bool o1_restart(ScriptEnv &env);
+	bool o1_quit(ScriptEnv &env);
+	bool o1_placeItem(ScriptEnv &env);
+	bool o1_setItemPic(ScriptEnv &env);
+	bool o1_resetPic(ScriptEnv &env);
+	bool o1_goDirection(ScriptEnv &env);
+	bool o1_takeItem(ScriptEnv &env);
+	bool o1_dropItem(ScriptEnv &env);
+	bool o1_setRoomPic(ScriptEnv &env);
+
 	// Graphics
 	void clearScreen() const;
 	void drawItems() const;
@@ -183,8 +230,8 @@ protected:
 	void setVar(uint i, byte value);
 	void takeItem(byte noun);
 	void dropItem(byte noun);
-	bool matchCommand(const Command &command, byte verb, byte noun, uint *actions = nullptr) const;
-	void doActions(const Command &command, byte noun, byte offset);
+	bool matchCommand(ScriptEnv &env, uint *actions = nullptr) const;
+	void doActions(ScriptEnv &env);
 	bool doOneCommand(const Commands &commands, byte verb, byte noun);
 	void doAllCommands(const Commands &commands, byte verb, byte noun);
 
@@ -192,6 +239,8 @@ protected:
 	GraphicsMan *_graphics;
 	Speaker *_speaker;
 
+	// Opcodes
+	Common::Array<const Opcode *> _condOpcodes, _actOpcodes;
 	// Message strings in data file
 	Common::Array<Common::String> _messages;
 	// Picture data


Commit: eaacfe1eede00d6370d1abb0afe2f0e6cf622b16
    https://github.com/scummvm/scummvm/commit/eaacfe1eede00d6370d1abb0afe2f0e6cf622b16
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Use template for direction opcode

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index ad5f559..8d501d8 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -330,13 +330,13 @@ void AdlEngine::setupOpcodeTables() {
 	Opcode(o1_setItemPic);
 	// 0x14
 	Opcode(o1_resetPic);
-	Opcode(o1_goDirection);
-	Opcode(o1_goDirection);
-	Opcode(o1_goDirection);
+	Opcode(o1_goDirection<IDI_DIR_NORTH>);
+	Opcode(o1_goDirection<IDI_DIR_SOUTH>);
+	Opcode(o1_goDirection<IDI_DIR_EAST>);
 	// 0x18
-	Opcode(o1_goDirection);
-	Opcode(o1_goDirection);
-	Opcode(o1_goDirection);
+	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);
@@ -1017,8 +1017,9 @@ bool AdlEngine::o1_resetPic(ScriptEnv &env) {
 	return true;
 }
 
+template <Direction D>
 bool AdlEngine::o1_goDirection(ScriptEnv &env) {
-	byte room = getCurRoom().connections[ARG(0) - IDO_ACT_GO_NORTH];
+	byte room = getCurRoom().connections[D];
 
 	if (room == 0) {
 		printMessage(_messageIds.cantGoThere);
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index e007b15..ce42114 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -90,9 +90,19 @@ typedef Common::Functor1<ScriptEnv &, bool> Opcode;
 
 #define IDI_WORD_SIZE 8
 
+enum Direction {
+	IDI_DIR_NORTH,
+	IDI_DIR_SOUTH,
+	IDI_DIR_EAST,
+	IDI_DIR_WEST,
+	IDI_DIR_UP,
+	IDI_DIR_DOWN,
+	IDI_DIR_TOTAL
+};
+
 struct Room {
 	byte description;
-	byte connections[6];
+	byte connections[IDI_DIR_TOTAL];
 	byte track;
 	byte sector;
 	byte offset;
@@ -207,6 +217,7 @@ protected:
 	bool o1_placeItem(ScriptEnv &env);
 	bool o1_setItemPic(ScriptEnv &env);
 	bool o1_resetPic(ScriptEnv &env);
+	template <Direction D>
 	bool o1_goDirection(ScriptEnv &env);
 	bool o1_takeItem(ScriptEnv &env);
 	bool o1_dropItem(ScriptEnv &env);


Commit: 37656db0d4959ab454eccd7d35668e0b46861fa6
    https://github.com/scummvm/scummvm/commit/37656db0d4959ab454eccd7d35668e0b46861fa6
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Clean up opcodes

Changed paths:
    engines/adl/adl.cpp



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 8d501d8..6f946b8 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -854,129 +854,129 @@ void AdlEngine::getInput(uint &verb, uint &noun) {
 
 typedef Common::Functor1Mem<ScriptEnv &, bool, AdlEngine> OpcodeV1;
 
-#define ARG(N) (env.cmd.script[env.ip + (N)])
+#define ARG(N) (e.cmd.script[e.ip + (N)])
 
-bool AdlEngine::o1_isItemInRoom(ScriptEnv &env) {
+bool AdlEngine::o1_isItemInRoom(ScriptEnv &e) {
 	if (getItem(ARG(1)).room != ARG(2))
 		return false;
-	env.ip += 3;
+	e.ip += 3;
 	return true;
 }
 
-bool AdlEngine::o1_isMovesGrEq(ScriptEnv &env) {
+bool AdlEngine::o1_isMovesGrEq(ScriptEnv &e) {
 	if (ARG(1) > _state.moves)
 		return false;
-	env.ip += 2;
+	e.ip += 2;
 	return true;
 }
 
-bool AdlEngine::o1_isVarEq(ScriptEnv &env) {
+bool AdlEngine::o1_isVarEq(ScriptEnv &e) {
 	if (getVar(ARG(1)) != ARG(2))
 		return false;
-	env.ip += 3;
+	e.ip += 3;
 	return true;
 }
 
-bool AdlEngine::o1_isCurPicEq(ScriptEnv &env) {
+bool AdlEngine::o1_isCurPicEq(ScriptEnv &e) {
 	if (getCurRoom().curPicture != ARG(1))
 		return false;
-	env.ip += 2;
+	e.ip += 2;
 	return true;
 }
 
-bool AdlEngine::o1_isItemPicEq(ScriptEnv &env) {
+bool AdlEngine::o1_isItemPicEq(ScriptEnv &e) {
 	if (getItem(ARG(1)).picture != ARG(2))
 		return false;
-	env.ip += 3;
+	e.ip += 3;
 	return true;
 }
 
-bool AdlEngine::o1_varAdd(ScriptEnv &env) {
+bool AdlEngine::o1_varAdd(ScriptEnv &e) {
 	setVar(ARG(2), getVar(ARG(2) + ARG(1)));
-	env.ip += 3;
+	e.ip += 3;
 	return true;
 }
 
-bool AdlEngine::o1_varSub(ScriptEnv &env) {
+bool AdlEngine::o1_varSub(ScriptEnv &e) {
 	setVar(ARG(2), getVar(ARG(2)) - ARG(1));
-	env.ip += 3;
+	e.ip += 3;
 	return true;
 }
 
-bool AdlEngine::o1_varSet(ScriptEnv &env) {
+bool AdlEngine::o1_varSet(ScriptEnv &e) {
 	setVar(ARG(1), ARG(2));
-	env.ip += 3;
+	e.ip += 3;
 	return true;
 }
 
-bool AdlEngine::o1_listInv(ScriptEnv &env) {
+bool AdlEngine::o1_listInv(ScriptEnv &e) {
 	Common::Array<Item>::const_iterator item;
 
 	for (item = _state.items.begin(); item != _state.items.end(); ++item)
 		if (item->room == IDI_NONE)
 			printMessage(item->description);
 
-	++env.ip;
+	++e.ip;
 	return true;
 }
 
-bool AdlEngine::o1_moveItem(ScriptEnv &env) {
+bool AdlEngine::o1_moveItem(ScriptEnv &e) {
 	getItem(ARG(1)).room = ARG(2);
-	env.ip += 3;
+	e.ip += 3;
 	return true;
 }
 
-bool AdlEngine::o1_setRoom(ScriptEnv &env) {
+bool AdlEngine::o1_setRoom(ScriptEnv &e) {
 	getCurRoom().curPicture = getCurRoom().picture;
 	_state.room = ARG(1);
-	env.ip += 2;
+	e.ip += 2;
 	return true;
 }
 
-bool AdlEngine::o1_setCurPic(ScriptEnv &env) {
+bool AdlEngine::o1_setCurPic(ScriptEnv &e) {
 	getCurRoom().curPicture = ARG(1);
-	env.ip += 2;
+	e.ip += 2;
 	return true;
 }
 
-bool AdlEngine::o1_setPic(ScriptEnv &env) {
+bool AdlEngine::o1_setPic(ScriptEnv &e) {
 	getCurRoom().picture = getCurRoom().curPicture = ARG(1);
-	env.ip += 2;
+	e.ip += 2;
 	return true;
 }
 
-bool AdlEngine::o1_printMsg(ScriptEnv &env) {
+bool AdlEngine::o1_printMsg(ScriptEnv &e) {
 	printMessage(ARG(1));
-	env.ip += 2;
+	e.ip += 2;
 	return true;
 }
 
-bool AdlEngine::o1_setLight(ScriptEnv &env) {
+bool AdlEngine::o1_setLight(ScriptEnv &e) {
 	_state.isDark = false;
-	++env.ip;
+	++e.ip;
 	return true;
 }
 
-bool AdlEngine::o1_setDark(ScriptEnv &env) {
+bool AdlEngine::o1_setDark(ScriptEnv &e) {
 	_state.isDark = true;
-	++env.ip;
+	++e.ip;
 	return true;
 }
 
-bool AdlEngine::o1_save(ScriptEnv &env) {
+bool AdlEngine::o1_save(ScriptEnv &e) {
 	saveGameState(0, "");
-	++env.ip;
+	++e.ip;
 	return true;
 }
 
-bool AdlEngine::o1_restore(ScriptEnv &env) {
+bool AdlEngine::o1_restore(ScriptEnv &e) {
 	loadGameState(0);
-	++env.ip;
+	++e.ip;
 	_isRestoring = false;
 	return true;
 }
 
-bool AdlEngine::o1_restart(ScriptEnv &env) {
+bool AdlEngine::o1_restart(ScriptEnv &e) {
 	_display->printString(_strings.playAgain);
 	Common::String input = inputString();
 
@@ -988,37 +988,37 @@ bool AdlEngine::o1_restart(ScriptEnv &env) {
 		return false;
 	}
 
-	return o1_quit(env);
+	return o1_quit(e);
 }
 
-bool AdlEngine::o1_quit(ScriptEnv &env) {
+bool AdlEngine::o1_quit(ScriptEnv &e) {
 	printMessage(_messageIds.thanksForPlaying);
 	quitGame();
 	return false;
 }
 
-bool AdlEngine::o1_placeItem(ScriptEnv &env) {
+bool AdlEngine::o1_placeItem(ScriptEnv &e) {
 	getItem(ARG(1)).room = ARG(2);
 	getItem(ARG(1)).position.x = ARG(3);
 	getItem(ARG(1)).position.y = ARG(4);
-	env.ip += 5;
+	e.ip += 5;
 	return true;
 }
 
-bool AdlEngine::o1_setItemPic(ScriptEnv &env) {
+bool AdlEngine::o1_setItemPic(ScriptEnv &e) {
 	getItem(ARG(2)).picture = ARG(1);
-	env.ip += 3;
+	e.ip += 3;
 	return true;
 }
 
-bool AdlEngine::o1_resetPic(ScriptEnv &env) {
+bool AdlEngine::o1_resetPic(ScriptEnv &e) {
 	getCurRoom().curPicture = getCurRoom().picture;
-	++env.ip;
+	++e.ip;
 	return true;
 }
 
 template <Direction D>
-bool AdlEngine::o1_goDirection(ScriptEnv &env) {
+bool AdlEngine::o1_goDirection(ScriptEnv &e) {
 	byte room = getCurRoom().connections[D];
 
 	if (room == 0) {
@@ -1031,21 +1031,21 @@ bool AdlEngine::o1_goDirection(ScriptEnv &env) {
 	return false;
 }
 
-bool AdlEngine::o1_takeItem(ScriptEnv &env) {
-	takeItem(env.noun);
-	++env.ip;
+bool AdlEngine::o1_takeItem(ScriptEnv &e) {
+	takeItem(e.noun);
+	++e.ip;
 	return true;
 }
 
-bool AdlEngine::o1_dropItem(ScriptEnv &env) {
-	dropItem(env.noun);
-	++env.ip;
+bool AdlEngine::o1_dropItem(ScriptEnv &e) {
+	dropItem(e.noun);
+	++e.ip;
 	return true;
 }
 
-bool AdlEngine::o1_setRoomPic(ScriptEnv &env) {
+bool AdlEngine::o1_setRoomPic(ScriptEnv &e) {
 	getRoom(ARG(1)).picture = getRoom(ARG(1)).curPicture = ARG(2);
-	env.ip += 3;
+	e.ip += 3;
 	return true;
 }
 


Commit: a9afe17169295b69c50bc3a727f4dd8034c24f2e
    https://github.com/scummvm/scummvm/commit/a9afe17169295b69c50bc3a727f4dd8034c24f2e
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Replace opcode arg macro with function

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 6f946b8..069e360 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -854,57 +854,55 @@ void AdlEngine::getInput(uint &verb, uint &noun) {
 
 typedef Common::Functor1Mem<ScriptEnv &, bool, AdlEngine> OpcodeV1;
 
-#define ARG(N) (e.cmd.script[e.ip + (N)])
-
 bool AdlEngine::o1_isItemInRoom(ScriptEnv &e) {
-	if (getItem(ARG(1)).room != ARG(2))
+	if (getItem(e.arg(1)).room != e.arg(2))
 		return false;
 	e.ip += 3;
 	return true;
 }
 
 bool AdlEngine::o1_isMovesGrEq(ScriptEnv &e) {
-	if (ARG(1) > _state.moves)
+	if (e.arg(1) > _state.moves)
 		return false;
 	e.ip += 2;
 	return true;
 }
 
 bool AdlEngine::o1_isVarEq(ScriptEnv &e) {
-	if (getVar(ARG(1)) != ARG(2))
+	if (getVar(e.arg(1)) != e.arg(2))
 		return false;
 	e.ip += 3;
 	return true;
 }
 
 bool AdlEngine::o1_isCurPicEq(ScriptEnv &e) {
-	if (getCurRoom().curPicture != ARG(1))
+	if (getCurRoom().curPicture != e.arg(1))
 		return false;
 	e.ip += 2;
 	return true;
 }
 
 bool AdlEngine::o1_isItemPicEq(ScriptEnv &e) {
-	if (getItem(ARG(1)).picture != ARG(2))
+	if (getItem(e.arg(1)).picture != e.arg(2))
 		return false;
 	e.ip += 3;
 	return true;
 }
 
 bool AdlEngine::o1_varAdd(ScriptEnv &e) {
-	setVar(ARG(2), getVar(ARG(2) + ARG(1)));
+	setVar(e.arg(2), getVar(e.arg(2) + e.arg(1)));
 	e.ip += 3;
 	return true;
 }
 
 bool AdlEngine::o1_varSub(ScriptEnv &e) {
-	setVar(ARG(2), getVar(ARG(2)) - ARG(1));
+	setVar(e.arg(2), getVar(e.arg(2)) - e.arg(1));
 	e.ip += 3;
 	return true;
 }
 
 bool AdlEngine::o1_varSet(ScriptEnv &e) {
-	setVar(ARG(1), ARG(2));
+	setVar(e.arg(1), e.arg(2));
 	e.ip += 3;
 	return true;
 }
@@ -921,32 +919,32 @@ bool AdlEngine::o1_listInv(ScriptEnv &e) {
 }
 
 bool AdlEngine::o1_moveItem(ScriptEnv &e) {
-	getItem(ARG(1)).room = ARG(2);
+	getItem(e.arg(1)).room = e.arg(2);
 	e.ip += 3;
 	return true;
 }
 
 bool AdlEngine::o1_setRoom(ScriptEnv &e) {
 	getCurRoom().curPicture = getCurRoom().picture;
-	_state.room = ARG(1);
+	_state.room = e.arg(1);
 	e.ip += 2;
 	return true;
 }
 
 bool AdlEngine::o1_setCurPic(ScriptEnv &e) {
-	getCurRoom().curPicture = ARG(1);
+	getCurRoom().curPicture = e.arg(1);
 	e.ip += 2;
 	return true;
 }
 
 bool AdlEngine::o1_setPic(ScriptEnv &e) {
-	getCurRoom().picture = getCurRoom().curPicture = ARG(1);
+	getCurRoom().picture = getCurRoom().curPicture = e.arg(1);
 	e.ip += 2;
 	return true;
 }
 
 bool AdlEngine::o1_printMsg(ScriptEnv &e) {
-	printMessage(ARG(1));
+	printMessage(e.arg(1));
 	e.ip += 2;
 	return true;
 }
@@ -998,15 +996,15 @@ bool AdlEngine::o1_quit(ScriptEnv &e) {
 }
 
 bool AdlEngine::o1_placeItem(ScriptEnv &e) {
-	getItem(ARG(1)).room = ARG(2);
-	getItem(ARG(1)).position.x = ARG(3);
-	getItem(ARG(1)).position.y = ARG(4);
+	getItem(e.arg(1)).room = e.arg(2);
+	getItem(e.arg(1)).position.x = e.arg(3);
+	getItem(e.arg(1)).position.y = e.arg(4);
 	e.ip += 5;
 	return true;
 }
 
 bool AdlEngine::o1_setItemPic(ScriptEnv &e) {
-	getItem(ARG(2)).picture = ARG(1);
+	getItem(e.arg(2)).picture = e.arg(1);
 	e.ip += 3;
 	return true;
 }
@@ -1044,13 +1042,11 @@ bool AdlEngine::o1_dropItem(ScriptEnv &e) {
 }
 
 bool AdlEngine::o1_setRoomPic(ScriptEnv &e) {
-	getRoom(ARG(1)).picture = getRoom(ARG(1)).curPicture = ARG(2);
+	getRoom(e.arg(1)).picture = getRoom(e.arg(1)).curPicture = e.arg(2);
 	e.ip += 3;
 	return true;
 }
 
-#undef ARG
-
 bool AdlEngine::matchCommand(ScriptEnv &env, uint *actions) const {
 	if (env.cmd.room != IDI_NONE && env.cmd.room != _state.room)
 		return false;
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index ce42114..8e4a7fe 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -124,10 +124,15 @@ struct Command {
 	Script script;
 };
 
-struct ScriptEnv {
+class ScriptEnv {
+public:
 	ScriptEnv(const Command &cmd_, byte verb_, byte noun_) :
 			cmd(cmd_), verb(verb_), noun(noun_), ip(0) { }
 
+	byte op() const { return cmd.script[ip]; }
+	// We keep this 1-based for easier comparison with the original engine
+	byte arg(uint i) const { return cmd.script[ip + i]; }
+
 	const Command &cmd;
 	byte verb, noun;
 	byte ip;


Commit: f93ae5479e21877e3c527b7a7383f3e1edb8e22f
    https://github.com/scummvm/scummvm/commit/f93ae5479e21877e3c527b7a7383f3e1edb8e22f
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Make opcodes return arg count

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 069e360..7128928 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -278,7 +278,7 @@ void AdlEngine::checkInput(byte verb, byte noun) {
 		printMessage(_messageIds.dontUnderstand);
 }
 
-typedef Common::Functor1Mem<ScriptEnv &, bool, AdlEngine> OpcodeV1;
+typedef Common::Functor1Mem<ScriptEnv &, int, AdlEngine> OpcodeV1;
 #define SetOpcodeTable(x) table = &x;
 #define Opcode(x) table->push_back(new OpcodeV1(this, &AdlEngine::x))
 #define OpcodeUnImpl() table->push_back(new OpcodeV1(this, 0))
@@ -852,129 +852,111 @@ void AdlEngine::getInput(uint &verb, uint &noun) {
 	}
 }
 
-typedef Common::Functor1Mem<ScriptEnv &, bool, AdlEngine> OpcodeV1;
+typedef Common::Functor1Mem<ScriptEnv &, int, AdlEngine> OpcodeV1;
 
-bool AdlEngine::o1_isItemInRoom(ScriptEnv &e) {
+int AdlEngine::o1_isItemInRoom(ScriptEnv &e) {
 	if (getItem(e.arg(1)).room != e.arg(2))
-		return false;
-	e.ip += 3;
-	return true;
+		return -1;
+	return 2;
 }
 
-bool AdlEngine::o1_isMovesGrEq(ScriptEnv &e) {
+int AdlEngine::o1_isMovesGrEq(ScriptEnv &e) {
 	if (e.arg(1) > _state.moves)
-		return false;
-	e.ip += 2;
-	return true;
+		return -1;
+	return 1;
 }
 
-bool AdlEngine::o1_isVarEq(ScriptEnv &e) {
+int AdlEngine::o1_isVarEq(ScriptEnv &e) {
 	if (getVar(e.arg(1)) != e.arg(2))
-		return false;
-	e.ip += 3;
-	return true;
+		return -1;
+	return 2;
 }
 
-bool AdlEngine::o1_isCurPicEq(ScriptEnv &e) {
+int AdlEngine::o1_isCurPicEq(ScriptEnv &e) {
 	if (getCurRoom().curPicture != e.arg(1))
-		return false;
-	e.ip += 2;
-	return true;
+		return -1;
+	return 1;
 }
 
-bool AdlEngine::o1_isItemPicEq(ScriptEnv &e) {
+int AdlEngine::o1_isItemPicEq(ScriptEnv &e) {
 	if (getItem(e.arg(1)).picture != e.arg(2))
-		return false;
-	e.ip += 3;
-	return true;
+		return -1;
+	return 2;
 }
 
-bool AdlEngine::o1_varAdd(ScriptEnv &e) {
+int AdlEngine::o1_varAdd(ScriptEnv &e) {
 	setVar(e.arg(2), getVar(e.arg(2) + e.arg(1)));
-	e.ip += 3;
-	return true;
+	return 2;
 }
 
-bool AdlEngine::o1_varSub(ScriptEnv &e) {
+int AdlEngine::o1_varSub(ScriptEnv &e) {
 	setVar(e.arg(2), getVar(e.arg(2)) - e.arg(1));
-	e.ip += 3;
-	return true;
+	return 2;
 }
 
-bool AdlEngine::o1_varSet(ScriptEnv &e) {
+int AdlEngine::o1_varSet(ScriptEnv &e) {
 	setVar(e.arg(1), e.arg(2));
-	e.ip += 3;
-	return true;
+	return 2;
 }
 
-bool AdlEngine::o1_listInv(ScriptEnv &e) {
+int AdlEngine::o1_listInv(ScriptEnv &e) {
 	Common::Array<Item>::const_iterator item;
 
 	for (item = _state.items.begin(); item != _state.items.end(); ++item)
 		if (item->room == IDI_NONE)
 			printMessage(item->description);
 
-	++e.ip;
-	return true;
+	return 0;
 }
 
-bool AdlEngine::o1_moveItem(ScriptEnv &e) {
+int AdlEngine::o1_moveItem(ScriptEnv &e) {
 	getItem(e.arg(1)).room = e.arg(2);
-	e.ip += 3;
-	return true;
+	return 2;
 }
 
-bool AdlEngine::o1_setRoom(ScriptEnv &e) {
+int AdlEngine::o1_setRoom(ScriptEnv &e) {
 	getCurRoom().curPicture = getCurRoom().picture;
 	_state.room = e.arg(1);
-	e.ip += 2;
-	return true;
+	return 1;
 }
 
-bool AdlEngine::o1_setCurPic(ScriptEnv &e) {
+int AdlEngine::o1_setCurPic(ScriptEnv &e) {
 	getCurRoom().curPicture = e.arg(1);
-	e.ip += 2;
-	return true;
+	return 1;
 }
 
-bool AdlEngine::o1_setPic(ScriptEnv &e) {
+int AdlEngine::o1_setPic(ScriptEnv &e) {
 	getCurRoom().picture = getCurRoom().curPicture = e.arg(1);
-	e.ip += 2;
-	return true;
+	return 1;
 }
 
-bool AdlEngine::o1_printMsg(ScriptEnv &e) {
+int AdlEngine::o1_printMsg(ScriptEnv &e) {
 	printMessage(e.arg(1));
-	e.ip += 2;
-	return true;
+	return 1;
 }
 
-bool AdlEngine::o1_setLight(ScriptEnv &e) {
+int AdlEngine::o1_setLight(ScriptEnv &e) {
 	_state.isDark = false;
-	++e.ip;
-	return true;
+	return 0;
 }
 
-bool AdlEngine::o1_setDark(ScriptEnv &e) {
+int AdlEngine::o1_setDark(ScriptEnv &e) {
 	_state.isDark = true;
-	++e.ip;
-	return true;
+	return 0;
 }
 
-bool AdlEngine::o1_save(ScriptEnv &e) {
+int AdlEngine::o1_save(ScriptEnv &e) {
 	saveGameState(0, "");
-	++e.ip;
-	return true;
+	return 0;
 }
 
-bool AdlEngine::o1_restore(ScriptEnv &e) {
+int AdlEngine::o1_restore(ScriptEnv &e) {
 	loadGameState(0);
-	++e.ip;
 	_isRestoring = false;
-	return true;
+	return 0;
 }
 
-bool AdlEngine::o1_restart(ScriptEnv &e) {
+int AdlEngine::o1_restart(ScriptEnv &e) {
 	_display->printString(_strings.playAgain);
 	Common::String input = inputString();
 
@@ -983,68 +965,62 @@ bool AdlEngine::o1_restart(ScriptEnv &e) {
 		_display->clear(0x00);
 		_display->updateHiResScreen();
 		restartGame();
-		return false;
+		return -1;
 	}
 
 	return o1_quit(e);
 }
 
-bool AdlEngine::o1_quit(ScriptEnv &e) {
+int AdlEngine::o1_quit(ScriptEnv &e) {
 	printMessage(_messageIds.thanksForPlaying);
 	quitGame();
-	return false;
+	return -1;
 }
 
-bool AdlEngine::o1_placeItem(ScriptEnv &e) {
+int AdlEngine::o1_placeItem(ScriptEnv &e) {
 	getItem(e.arg(1)).room = e.arg(2);
 	getItem(e.arg(1)).position.x = e.arg(3);
 	getItem(e.arg(1)).position.y = e.arg(4);
-	e.ip += 5;
-	return true;
+	return 4;
 }
 
-bool AdlEngine::o1_setItemPic(ScriptEnv &e) {
+int AdlEngine::o1_setItemPic(ScriptEnv &e) {
 	getItem(e.arg(2)).picture = e.arg(1);
-	e.ip += 3;
-	return true;
+	return 2;
 }
 
-bool AdlEngine::o1_resetPic(ScriptEnv &e) {
+int AdlEngine::o1_resetPic(ScriptEnv &e) {
 	getCurRoom().curPicture = getCurRoom().picture;
-	++e.ip;
-	return true;
+	return 0;
 }
 
 template <Direction D>
-bool AdlEngine::o1_goDirection(ScriptEnv &e) {
+int AdlEngine::o1_goDirection(ScriptEnv &e) {
 	byte room = getCurRoom().connections[D];
 
 	if (room == 0) {
 		printMessage(_messageIds.cantGoThere);
-		return false;
+		return -1;
 	}
 
 	getCurRoom().curPicture = getCurRoom().picture;
 	_state.room = room;
-	return false;
+	return -1;
 }
 
-bool AdlEngine::o1_takeItem(ScriptEnv &e) {
+int AdlEngine::o1_takeItem(ScriptEnv &e) {
 	takeItem(e.noun);
-	++e.ip;
-	return true;
+	return 0;
 }
 
-bool AdlEngine::o1_dropItem(ScriptEnv &e) {
+int AdlEngine::o1_dropItem(ScriptEnv &e) {
 	dropItem(e.noun);
-	++e.ip;
-	return true;
+	return 0;
 }
 
-bool AdlEngine::o1_setRoomPic(ScriptEnv &e) {
+int AdlEngine::o1_setRoomPic(ScriptEnv &e) {
 	getRoom(e.arg(1)).picture = getRoom(e.arg(1)).curPicture = e.arg(2);
-	e.ip += 3;
-	return true;
+	return 2;
 }
 
 bool AdlEngine::matchCommand(ScriptEnv &env, uint *actions) const {
@@ -1063,8 +1039,12 @@ bool AdlEngine::matchCommand(ScriptEnv &env, uint *actions) const {
 		if (!_condOpcodes[op] || !_condOpcodes[op]->isValid())
 			error("Unimplemented condition opcode %02x", op);
 
-		if (!(*_condOpcodes[op])(env))
+		int numArgs = (*_condOpcodes[op])(env);
+
+		if (numArgs < 0)
 			return false;
+
+		env.ip += numArgs + 1;
 	}
 
 	if (actions)
@@ -1080,8 +1060,12 @@ void AdlEngine::doActions(ScriptEnv &env) {
 		if (!_actOpcodes[op] || !_actOpcodes[op]->isValid())
 			error("Unimplemented action opcode %02x", op);
 
-		if (!(*_actOpcodes[op])(env))
+		int numArgs = (*_actOpcodes[op])(env);
+
+		if (numArgs < 0)
 			return;
+
+		env.ip += numArgs + 1;
 	}
 }
 
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 8e4a7fe..1d93553 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -50,8 +50,6 @@ class Speaker;
 struct AdlGameDescription;
 struct ScriptEnv;
 
-typedef Common::Functor1<ScriptEnv &, bool> Opcode;
-
 // Conditional opcodes
 #define IDO_CND_ITEM_IN_ROOM   0x03
 #define IDO_CND_MOVES_GE       0x05
@@ -198,35 +196,35 @@ protected:
 	virtual void setupOpcodeTables();
 
 	// Opcodes
-	bool o1_isItemInRoom(ScriptEnv &env);
-	bool o1_isMovesGrEq(ScriptEnv &env);
-	bool o1_isVarEq(ScriptEnv &env);
-	bool o1_isCurPicEq(ScriptEnv &env);
-	bool o1_isItemPicEq(ScriptEnv &env);
-
-	bool o1_varAdd(ScriptEnv &env);
-	bool o1_varSub(ScriptEnv &env);
-	bool o1_varSet(ScriptEnv &env);
-	bool o1_listInv(ScriptEnv &env);
-	bool o1_moveItem(ScriptEnv &env);
-	bool o1_setRoom(ScriptEnv &env);
-	bool o1_setCurPic(ScriptEnv &env);
-	bool o1_setPic(ScriptEnv &env);
-	bool o1_printMsg(ScriptEnv &env);
-	bool o1_setLight(ScriptEnv &env);
-	bool o1_setDark(ScriptEnv &env);
-	bool o1_save(ScriptEnv &env);
-	bool o1_restore(ScriptEnv &env);
-	bool o1_restart(ScriptEnv &env);
-	bool o1_quit(ScriptEnv &env);
-	bool o1_placeItem(ScriptEnv &env);
-	bool o1_setItemPic(ScriptEnv &env);
-	bool o1_resetPic(ScriptEnv &env);
+	int o1_isItemInRoom(ScriptEnv &e);
+	int o1_isMovesGrEq(ScriptEnv &e);
+	int o1_isVarEq(ScriptEnv &e);
+	int o1_isCurPicEq(ScriptEnv &e);
+	int o1_isItemPicEq(ScriptEnv &e);
+
+	int o1_varAdd(ScriptEnv &e);
+	int o1_varSub(ScriptEnv &e);
+	int o1_varSet(ScriptEnv &e);
+	int o1_listInv(ScriptEnv &e);
+	int o1_moveItem(ScriptEnv &e);
+	int o1_setRoom(ScriptEnv &e);
+	int o1_setCurPic(ScriptEnv &e);
+	int o1_setPic(ScriptEnv &e);
+	int o1_printMsg(ScriptEnv &e);
+	int o1_setLight(ScriptEnv &e);
+	int o1_setDark(ScriptEnv &e);
+	int o1_save(ScriptEnv &e);
+	int o1_restore(ScriptEnv &e);
+	int o1_restart(ScriptEnv &e);
+	int o1_quit(ScriptEnv &e);
+	int o1_placeItem(ScriptEnv &e);
+	int o1_setItemPic(ScriptEnv &e);
+	int o1_resetPic(ScriptEnv &e);
 	template <Direction D>
-	bool o1_goDirection(ScriptEnv &env);
-	bool o1_takeItem(ScriptEnv &env);
-	bool o1_dropItem(ScriptEnv &env);
-	bool o1_setRoomPic(ScriptEnv &env);
+	int o1_goDirection(ScriptEnv &e);
+	int o1_takeItem(ScriptEnv &e);
+	int o1_dropItem(ScriptEnv &e);
+	int o1_setRoomPic(ScriptEnv &e);
 
 	// Graphics
 	void clearScreen() const;
@@ -256,6 +254,7 @@ protected:
 	Speaker *_speaker;
 
 	// Opcodes
+	typedef Common::Functor1<ScriptEnv &, int> Opcode;
 	Common::Array<const Opcode *> _condOpcodes, _actOpcodes;
 	// Message strings in data file
 	Common::Array<Common::String> _messages;


Commit: 0cb889b55e43007bc0fd74d7bccf7aa130fdac6a
    https://github.com/scummvm/scummvm/commit/0cb889b55e43007bc0fd74d7bccf7aa130fdac6a
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Remove unused opcode #defines

Changed paths:
    engines/adl/adl.h



diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 1d93553..c12fb55 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -50,41 +50,9 @@ class Speaker;
 struct AdlGameDescription;
 struct ScriptEnv;
 
-// Conditional opcodes
-#define IDO_CND_ITEM_IN_ROOM   0x03
-#define IDO_CND_MOVES_GE       0x05
-#define IDO_CND_VAR_EQ         0x06
-#define IDO_CND_CUR_PIC_EQ     0x09
-#define IDO_CND_ITEM_PIC_EQ    0x0a
-
-// Action opcodes
-#define IDO_ACT_VAR_ADD        0x01
-#define IDO_ACT_VAR_SUB        0x02
-#define IDO_ACT_VAR_SET        0x03
-#define IDO_ACT_LIST_ITEMS     0x04
-#define IDO_ACT_MOVE_ITEM      0x05
-#define IDO_ACT_SET_ROOM       0x06
-#define IDO_ACT_SET_CUR_PIC    0x07
-#define IDO_ACT_SET_PIC        0x08
-#define IDO_ACT_PRINT_MSG      0x09
-#define IDO_ACT_SET_LIGHT      0x0a
-#define IDO_ACT_SET_DARK       0x0b
-#define IDO_ACT_QUIT           0x0d
+// Save and restore opcodes
 #define IDO_ACT_SAVE           0x0f
 #define IDO_ACT_LOAD           0x10
-#define IDO_ACT_RESTART        0x11
-#define IDO_ACT_PLACE_ITEM     0x12
-#define IDO_ACT_SET_ITEM_PIC   0x13
-#define IDO_ACT_RESET_PIC      0x14
-#define IDO_ACT_GO_NORTH       0x15
-#define IDO_ACT_GO_SOUTH       0x16
-#define IDO_ACT_GO_EAST        0x17
-#define IDO_ACT_GO_WEST        0x18
-#define IDO_ACT_GO_UP          0x19
-#define IDO_ACT_GO_DOWN        0x1a
-#define IDO_ACT_TAKE_ITEM      0x1b
-#define IDO_ACT_DROP_ITEM      0x1c
-#define IDO_ACT_SET_ROOM_PIC   0x1d
 
 #define IDI_WORD_SIZE 8
 


Commit: 60a9a592f5641655d1e0b00731603298bc938ac7
    https://github.com/scummvm/scummvm/commit/60a9a592f5641655d1e0b00731603298bc938ac7
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Clean up script handling

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 7128928..31c4485 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -724,10 +724,9 @@ bool AdlEngine::canSaveGameStateCurrently() {
 	// "SAVE GAME". This prevents saving via the GMM in situations where
 	// it wouldn't otherwise be possible to do so.
 	for (cmd = _roomCommands.begin(); cmd != _roomCommands.end(); ++cmd) {
-		ScriptEnv env(*cmd, _saveVerb, _saveNoun);
-		uint offset;
-		if (matchCommand(env, &offset))
-			return cmd->script[offset] == IDO_ACT_SAVE;
+		ScriptEnv env(*cmd, _state.room, _saveVerb, _saveNoun);
+		if (matchCommand(env))
+			return env.op() == IDO_ACT_SAVE;
 	}
 
 	return false;
@@ -1009,12 +1008,12 @@ int AdlEngine::o1_goDirection(ScriptEnv &e) {
 }
 
 int AdlEngine::o1_takeItem(ScriptEnv &e) {
-	takeItem(e.noun);
+	takeItem(e.getNoun());
 	return 0;
 }
 
 int AdlEngine::o1_dropItem(ScriptEnv &e) {
-	dropItem(e.noun);
+	dropItem(e.getNoun());
 	return 0;
 }
 
@@ -1023,18 +1022,12 @@ int AdlEngine::o1_setRoomPic(ScriptEnv &e) {
 	return 2;
 }
 
-bool AdlEngine::matchCommand(ScriptEnv &env, uint *actions) const {
-	if (env.cmd.room != IDI_NONE && env.cmd.room != _state.room)
-		return false;
-
-	if (env.cmd.verb != IDI_NONE && env.cmd.verb != env.verb)
+bool AdlEngine::matchCommand(ScriptEnv &env) const {
+	if (!env.isMatch())
 		return false;
 
-	if (env.cmd.noun != IDI_NONE && env.cmd.noun != env.noun)
-		return false;
-
-	for (uint i = 0; i < env.cmd.numCond; ++i) {
-		byte op = env.cmd.script[env.ip];
+	for (uint i = 0; i < env.getCondCount(); ++i) {
+		byte op = env.op();
 
 		if (!_condOpcodes[op] || !_condOpcodes[op]->isValid())
 			error("Unimplemented condition opcode %02x", op);
@@ -1044,18 +1037,15 @@ bool AdlEngine::matchCommand(ScriptEnv &env, uint *actions) const {
 		if (numArgs < 0)
 			return false;
 
-		env.ip += numArgs + 1;
+		env.skip(numArgs + 1);
 	}
 
-	if (actions)
-		*actions = env.ip;
-
 	return true;
 }
 
 void AdlEngine::doActions(ScriptEnv &env) {
-	for (uint i = 0; i < env.cmd.numAct; ++i) {
-		byte op = env.cmd.script[env.ip];
+	for (uint i = 0; i < env.getActCount(); ++i) {
+		byte op = env.op();
 
 		if (!_actOpcodes[op] || !_actOpcodes[op]->isValid())
 			error("Unimplemented action opcode %02x", op);
@@ -1065,7 +1055,7 @@ void AdlEngine::doActions(ScriptEnv &env) {
 		if (numArgs < 0)
 			return;
 
-		env.ip += numArgs + 1;
+		env.skip(numArgs + 1);
 	}
 }
 
@@ -1073,7 +1063,7 @@ bool AdlEngine::doOneCommand(const Commands &commands, byte verb, byte noun) {
 	Commands::const_iterator cmd;
 
 	for (cmd = commands.begin(); cmd != commands.end(); ++cmd) {
-		ScriptEnv env(*cmd, verb, noun);
+		ScriptEnv env(*cmd, _state.room, verb, noun);
 		if (matchCommand(env)) {
 			doActions(env);
 			return true;
@@ -1087,7 +1077,7 @@ void AdlEngine::doAllCommands(const Commands &commands, byte verb, byte noun) {
 	Commands::const_iterator cmd;
 
 	for (cmd = commands.begin(); cmd != commands.end(); ++cmd) {
-		ScriptEnv env(*cmd, verb, noun);
+		ScriptEnv env(*cmd, _state.room, verb, noun);
 		if (matchCommand(env))
 			doActions(env);
 	}
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index c12fb55..e7c36ae 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -54,6 +54,8 @@ struct ScriptEnv;
 #define IDO_ACT_SAVE           0x0f
 #define IDO_ACT_LOAD           0x10
 
+#define IDI_NONE 0xfe
+
 #define IDI_WORD_SIZE 8
 
 enum Direction {
@@ -92,16 +94,28 @@ struct Command {
 
 class ScriptEnv {
 public:
-	ScriptEnv(const Command &cmd_, byte verb_, byte noun_) :
-			cmd(cmd_), verb(verb_), noun(noun_), ip(0) { }
+	ScriptEnv(const Command &cmd, byte room, byte verb, byte noun) :
+			_cmd(cmd), _room(room), _verb(verb), _noun(noun), _ip(0) { }
 
-	byte op() const { return cmd.script[ip]; }
+	byte op() const { return _cmd.script[_ip]; }
 	// We keep this 1-based for easier comparison with the original engine
-	byte arg(uint i) const { return cmd.script[ip + i]; }
+	byte arg(uint i) const { return _cmd.script[_ip + i]; }
+	void skip(uint i) { _ip += i; }
 
-	const Command &cmd;
-	byte verb, noun;
-	byte ip;
+	bool isMatch() const {
+		return (_cmd.room == IDI_NONE || _cmd.room == _room) &&
+		       (_cmd.verb == IDI_NONE || _cmd.verb == _verb) &&
+		       (_cmd.noun == IDI_NONE || _cmd.noun == _noun);
+	}
+
+	byte getCondCount() const { return _cmd.numCond; }
+	byte getActCount() const { return _cmd.numAct; }
+	byte getNoun() const { return _noun; }
+
+private:
+	const Command &_cmd;
+	const byte _room, _verb, _noun;
+	byte _ip;
 };
 
 enum {
@@ -110,8 +124,6 @@ enum {
 	IDI_ITEM_DOESNT_MOVE
 };
 
-#define IDI_NONE 0xfe
-
 struct Item {
 	byte noun;
 	byte room;
@@ -212,7 +224,7 @@ protected:
 	void setVar(uint i, byte value);
 	void takeItem(byte noun);
 	void dropItem(byte noun);
-	bool matchCommand(ScriptEnv &env, uint *actions = nullptr) const;
+	bool matchCommand(ScriptEnv &env) const;
 	void doActions(ScriptEnv &env);
 	bool doOneCommand(const Commands &commands, byte verb, byte noun);
 	void doAllCommands(const Commands &commands, byte verb, byte noun);


Commit: ddf1151a534cf215cc0ffe972163489c319bdc63
    https://github.com/scummvm/scummvm/commit/ddf1151a534cf215cc0ffe972163489c319bdc63
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Add new class for second generation ADL

Changed paths:
  A engines/adl/adl_v2.cpp
  A engines/adl/adl_v2.h
    engines/adl/hires2.h
    engines/adl/module.mk



diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
new file mode 100644
index 0000000..55ea15d
--- /dev/null
+++ b/engines/adl/adl_v2.cpp
@@ -0,0 +1,126 @@
+/* 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 "adl/adl_v2.h"
+
+namespace Adl {
+
+AdlEngine_v2::AdlEngine_v2(OSystem *syst, const AdlGameDescription *gd) :
+		AdlEngine(syst, gd) {
+}
+
+typedef Common::Functor1Mem<ScriptEnv &, int, AdlEngine_v2> OpcodeV2;
+#define SetOpcodeTable(x) table = &x;
+#define Opcode(x) table->push_back(new OpcodeV2(this, &AdlEngine_v2::x))
+#define OpcodeUnImpl() table->push_back(new OpcodeV2(this, 0))
+
+void AdlEngine_v2::setupOpcodeTables() {
+	Common::Array<const Opcode *> *table = 0;
+
+	SetOpcodeTable(_condOpcodes);
+	// 0x00
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	OpcodeUnImpl();
+	Opcode(o2_isItemInRoom);
+	// 0x04
+	OpcodeUnImpl();
+	Opcode(o1_isMovesGrEq);
+	Opcode(o1_isVarEq);
+	OpcodeUnImpl();
+	// 0x08
+	OpcodeUnImpl();
+	Opcode(o1_isCurPicEq);
+	Opcode(o1_isItemPicEq);
+
+	SetOpcodeTable(_actOpcodes);
+	// 0x00
+	OpcodeUnImpl();
+	Opcode(o1_varAdd);
+	Opcode(o1_varSub);
+	Opcode(o1_varSet);
+	// 0x04
+	Opcode(o1_listInv);
+	Opcode(o2_moveItem);
+	Opcode(o1_setRoom);
+	Opcode(o1_setCurPic);
+	// 0x08
+	Opcode(o1_setPic);
+	Opcode(o1_printMsg);
+	Opcode(o1_setLight);
+	Opcode(o1_setDark);
+	// 0x0c
+	OpcodeUnImpl();
+	Opcode(o1_quit);
+	OpcodeUnImpl();
+	Opcode(o1_save);
+	// 0x10
+	Opcode(o1_restore);
+	Opcode(o1_restart);
+	Opcode(o1_placeItem);
+	Opcode(o1_setItemPic);
+	// 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);
+}
+
+int AdlEngine_v2::o2_isItemInRoom(ScriptEnv &e) {
+	byte room = e.arg(2);
+
+	if (room == IDI_CUR_ROOM)
+		room = _state.room;
+
+	if (getItem(e.arg(1)).room != room)
+		return -1;
+
+	return 2;
+}
+
+int AdlEngine_v2::o2_moveItem(ScriptEnv &e) {
+	byte room = e.arg(2);
+
+	if (room == IDI_CUR_ROOM)
+		room = _state.room;
+
+	Item &item = getItem(e.arg(1));
+
+	// Not implemented: set redraw flag if item room == displayed room
+
+	// Set items that move from inventory to a room to state "dropped"
+	if (item.room == IDI_NONE && room != IDI_VOID_ROOM)
+		item.state = IDI_ITEM_MOVED;
+
+	item.room = room;
+	return 2;
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
new file mode 100644
index 0000000..2e8b0f0
--- /dev/null
+++ b/engines/adl/adl_v2.h
@@ -0,0 +1,49 @@
+/* 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_V2_H
+#define ADL_ADL_V2_H
+
+#include "adl/adl.h"
+
+#define IDI_CUR_ROOM 0xfc
+#define IDI_VOID_ROOM 0xfd
+
+namespace Adl {
+
+class AdlEngine_v2 : public AdlEngine {
+public:
+	virtual ~AdlEngine_v2() { }
+
+protected:
+	AdlEngine_v2(OSystem *syst, const AdlGameDescription *gd);
+
+	virtual void setupOpcodeTables();
+
+	int o2_isItemInRoom(ScriptEnv &e);
+
+	int o2_moveItem(ScriptEnv &e);
+};
+
+} // End of namespace Adl
+
+#endif
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 516ea52..8ed51b8 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -25,7 +25,7 @@
 
 #include "common/str.h"
 
-#include "adl/adl.h"
+#include "adl/adl_v2.h"
 
 namespace Common {
 class ReadStream;
@@ -85,9 +85,9 @@ struct RoomData {
 	Commands commands;
 };
 
-class HiRes2Engine : public AdlEngine {
+class HiRes2Engine : public AdlEngine_v2 {
 public:
-	HiRes2Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine(syst, gd), _linesPrinted(0) { }
+	HiRes2Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine_v2(syst, gd), _linesPrinted(0) { }
 
 private:
 	// AdlEngine
diff --git a/engines/adl/module.mk b/engines/adl/module.mk
index 35e1228..7599957 100644
--- a/engines/adl/module.mk
+++ b/engines/adl/module.mk
@@ -2,6 +2,7 @@ MODULE := engines/adl
 
 MODULE_OBJS := \
 	adl.o \
+	adl_v2.o \
 	detection.o \
 	display.o \
 	graphics.o \


Commit: fab489c530fb89ce92dcfa0ce62f0ca2f3dcc676
    https://github.com/scummvm/scummvm/commit/fab489c530fb89ce92dcfa0ce62f0ca2f3dcc676
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Rename IDI_ITEM_MOVED to IDI_ITEM_DROPPED

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/adl_v2.cpp



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 31c4485..778d821 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -357,7 +357,7 @@ void AdlEngine::drawItems() const {
 		if (item->room != _state.room)
 			continue;
 
-		if (item->state == IDI_ITEM_MOVED) {
+		if (item->state == IDI_ITEM_DROPPED) {
 			if (getCurRoom().picture == getCurRoom().curPicture) {
 				const Common::Point &p =  _itemOffsets[dropped];
 				drawItem(*item, p);
@@ -444,7 +444,7 @@ void AdlEngine::takeItem(byte noun) {
 			return;
 		}
 
-		if (item->state == IDI_ITEM_MOVED) {
+		if (item->state == IDI_ITEM_DROPPED) {
 			item->room = IDI_NONE;
 			return;
 		}
@@ -453,7 +453,7 @@ void AdlEngine::takeItem(byte noun) {
 		for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
 			if (*pic == getCurRoom().curPicture) {
 				item->room = IDI_NONE;
-				item->state = IDI_ITEM_MOVED;
+				item->state = IDI_ITEM_DROPPED;
 				return;
 			}
 		}
@@ -470,7 +470,7 @@ void AdlEngine::dropItem(byte noun) {
 			continue;
 
 		item->room = _state.room;
-		item->state = IDI_ITEM_MOVED;
+		item->state = IDI_ITEM_DROPPED;
 		return;
 	}
 
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index e7c36ae..d4fe9ed 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -120,7 +120,7 @@ private:
 
 enum {
 	IDI_ITEM_NOT_MOVED,
-	IDI_ITEM_MOVED,
+	IDI_ITEM_DROPPED,
 	IDI_ITEM_DOESNT_MOVE
 };
 
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 55ea15d..6c6a710 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -117,7 +117,7 @@ int AdlEngine_v2::o2_moveItem(ScriptEnv &e) {
 
 	// Set items that move from inventory to a room to state "dropped"
 	if (item.room == IDI_NONE && room != IDI_VOID_ROOM)
-		item.state = IDI_ITEM_MOVED;
+		item.state = IDI_ITEM_DROPPED;
 
 	item.room = room;
 	return 2;


Commit: 8d1901c39bbfd22ff3540e2db68897f2aae652d9
    https://github.com/scummvm/scummvm/commit/8d1901c39bbfd22ff3540e2db68897f2aae652d9
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Implement hires2 cond opcodes 0x01 and 0x04

Changed paths:
    engines/adl/adl.h
    engines/adl/adl_v2.cpp
    engines/adl/adl_v2.h
    engines/adl/hires2.cpp



diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index d4fe9ed..9e29d1f 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -76,6 +76,7 @@ struct Room {
 	byte offset;
 	byte picture;
 	byte curPicture;
+	bool isFirstTime;
 };
 
 struct Picture {
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 6c6a710..7560504 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -43,7 +43,7 @@ void AdlEngine_v2::setupOpcodeTables() {
 	OpcodeUnImpl();
 	Opcode(o2_isItemInRoom);
 	// 0x04
-	OpcodeUnImpl();
+	Opcode(o2_isNounNotInRoom);
 	Opcode(o1_isMovesGrEq);
 	Opcode(o1_isVarEq);
 	OpcodeUnImpl();
@@ -93,6 +93,17 @@ void AdlEngine_v2::setupOpcodeTables() {
 	Opcode(o1_setRoomPic);
 }
 
+int AdlEngine_v2::o2_isFirstTime(ScriptEnv &e) {
+	bool oldFlag = getCurRoom().isFirstTime;
+
+	getCurRoom().isFirstTime = false;
+
+	if (!oldFlag)
+		return -1;
+
+	return 0;
+}
+
 int AdlEngine_v2::o2_isItemInRoom(ScriptEnv &e) {
 	byte room = e.arg(2);
 
@@ -105,6 +116,21 @@ int AdlEngine_v2::o2_isItemInRoom(ScriptEnv &e) {
 	return 2;
 }
 
+int AdlEngine_v2::o2_isNounNotInRoom(ScriptEnv &e) {
+	Common::Array<Item>::const_iterator item;
+
+	byte room = e.arg(1);
+
+	if (room == IDI_CUR_ROOM)
+		room = _state.room;
+
+	for (item = _state.items.begin(); item != _state.items.end(); ++item)
+		if (item->noun == e.getNoun() && (item->room == room))
+			return -1;
+
+	return 1;
+}
+
 int AdlEngine_v2::o2_moveItem(ScriptEnv &e) {
 	byte room = e.arg(2);
 
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 2e8b0f0..61c811b 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -39,7 +39,9 @@ protected:
 
 	virtual void setupOpcodeTables();
 
+	int o2_isFirstTime(ScriptEnv &e);
 	int o2_isItemInRoom(ScriptEnv &e);
+	int o2_isNounNotInRoom(ScriptEnv &e);
 
 	int o2_moveItem(ScriptEnv &e);
 };
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index b99f9fc..6f517da 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -142,7 +142,7 @@ void HiRes2Engine::initState() {
 		f.readByte(); // always 1, possibly disk?
 		room.picture = f.readByte();
 		room.curPicture = f.readByte();
-		f.readByte(); // always 1, possibly disk?
+		room.isFirstTime = f.readByte();
 		_state.rooms.push_back(room);
 	}
 


Commit: ee8c63183d82aa4deebf87ca6c7a63671684d25f
    https://github.com/scummvm/scummvm/commit/ee8c63183d82aa4deebf87ca6c7a63671684d25f
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Implement hires2 random cond opcode

Changed paths:
    engines/adl/adl_v2.cpp
    engines/adl/adl_v2.h



diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 7560504..3a938b3 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -20,12 +20,19 @@
  *
  */
 
+#include "common/random.h"
+
 #include "adl/adl_v2.h"
 
 namespace Adl {
 
+AdlEngine_v2::~AdlEngine_v2() {
+	delete _random;
+}
+
 AdlEngine_v2::AdlEngine_v2(OSystem *syst, const AdlGameDescription *gd) :
 		AdlEngine(syst, gd) {
+	_random = new Common::RandomSource("adl");
 }
 
 typedef Common::Functor1Mem<ScriptEnv &, int, AdlEngine_v2> OpcodeV2;
@@ -39,8 +46,8 @@ void AdlEngine_v2::setupOpcodeTables() {
 	SetOpcodeTable(_condOpcodes);
 	// 0x00
 	OpcodeUnImpl();
-	OpcodeUnImpl();
-	OpcodeUnImpl();
+	Opcode(o2_isFirstTime);
+	Opcode(o2_isRandomGT);
 	Opcode(o2_isItemInRoom);
 	// 0x04
 	Opcode(o2_isNounNotInRoom);
@@ -104,6 +111,15 @@ int AdlEngine_v2::o2_isFirstTime(ScriptEnv &e) {
 	return 0;
 }
 
+int AdlEngine_v2::o2_isRandomGT(ScriptEnv &e) {
+	byte rnd = _random->getRandomNumber(255);
+
+	if (e.arg(1) >= rnd)
+		return -1;
+
+	return 1;
+}
+
 int AdlEngine_v2::o2_isItemInRoom(ScriptEnv &e) {
 	byte room = e.arg(2);
 
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 61c811b..5513da3 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -28,11 +28,15 @@
 #define IDI_CUR_ROOM 0xfc
 #define IDI_VOID_ROOM 0xfd
 
+namespace Common{
+class RandomSource;
+}
+
 namespace Adl {
 
 class AdlEngine_v2 : public AdlEngine {
 public:
-	virtual ~AdlEngine_v2() { }
+	virtual ~AdlEngine_v2();
 
 protected:
 	AdlEngine_v2(OSystem *syst, const AdlGameDescription *gd);
@@ -40,10 +44,14 @@ protected:
 	virtual void setupOpcodeTables();
 
 	int o2_isFirstTime(ScriptEnv &e);
+	int o2_isRandomGT(ScriptEnv &e);
 	int o2_isItemInRoom(ScriptEnv &e);
 	int o2_isNounNotInRoom(ScriptEnv &e);
 
 	int o2_moveItem(ScriptEnv &e);
+
+private:
+	Common::RandomSource *_random;
 };
 
 } // End of namespace Adl


Commit: d09247bacaea68af05703218373479cdb0f558bd
    https://github.com/scummvm/scummvm/commit/d09247bacaea68af05703218373479cdb0f558bd
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Fix move counter

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/adl_v2.cpp
    engines/adl/hires1.cpp



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 778d821..036e8f1 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -294,7 +294,7 @@ void AdlEngine::setupOpcodeTables() {
 	Opcode(o1_isItemInRoom);
 	// 0x04
 	OpcodeUnImpl();
-	Opcode(o1_isMovesGrEq);
+	Opcode(o1_isMovesGT);
 	Opcode(o1_isVarEq);
 	OpcodeUnImpl();
 	// 0x08
@@ -859,8 +859,8 @@ int AdlEngine::o1_isItemInRoom(ScriptEnv &e) {
 	return 2;
 }
 
-int AdlEngine::o1_isMovesGrEq(ScriptEnv &e) {
-	if (e.arg(1) > _state.moves)
+int AdlEngine::o1_isMovesGT(ScriptEnv &e) {
+	if (e.arg(1) >= _state.moves)
 		return -1;
 	return 1;
 }
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 9e29d1f..b6e8dfa 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -145,7 +145,7 @@ struct State {
 	uint16 moves;
 	bool isDark;
 
-	State() : room(1), moves(0), isDark(false) { }
+	State() : room(1), moves(1), isDark(false) { }
 };
 
 typedef Common::List<Command> Commands;
@@ -178,7 +178,7 @@ protected:
 
 	// Opcodes
 	int o1_isItemInRoom(ScriptEnv &e);
-	int o1_isMovesGrEq(ScriptEnv &e);
+	int o1_isMovesGT(ScriptEnv &e);
 	int o1_isVarEq(ScriptEnv &e);
 	int o1_isCurPicEq(ScriptEnv &e);
 	int o1_isItemPicEq(ScriptEnv &e);
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 3a938b3..1e5553a 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -51,7 +51,7 @@ void AdlEngine_v2::setupOpcodeTables() {
 	Opcode(o2_isItemInRoom);
 	// 0x04
 	Opcode(o2_isNounNotInRoom);
-	Opcode(o1_isMovesGrEq);
+	Opcode(o1_isMovesGT);
 	Opcode(o1_isVarEq);
 	OpcodeUnImpl();
 	// 0x08
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 9527d4e..f7f16c0 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -210,7 +210,7 @@ void HiRes1Engine::initState() {
 	Common::File f;
 
 	_state.room = 1;
-	_state.moves = 0;
+	_state.moves = 1;
 	_state.isDark = false;
 
 	_state.vars.clear();


Commit: d8035140e2a0d4210cd77e4b24fe3430aacc6ea2
    https://github.com/scummvm/scummvm/commit/d8035140e2a0d4210cd77e4b24fe3430aacc6ea2
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Clean up opcodes

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/adl_v2.cpp



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 036e8f1..e6ce0f6 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -295,12 +295,12 @@ void AdlEngine::setupOpcodeTables() {
 	// 0x04
 	OpcodeUnImpl();
 	Opcode(o1_isMovesGT);
-	Opcode(o1_isVarEq);
+	Opcode(o1_isVarEQ);
 	OpcodeUnImpl();
 	// 0x08
 	OpcodeUnImpl();
-	Opcode(o1_isCurPicEq);
-	Opcode(o1_isItemPicEq);
+	Opcode(o1_isCurPicEQ);
+	Opcode(o1_isItemPicEQ);
 
 	SetOpcodeTable(_actOpcodes);
 	// 0x00
@@ -854,33 +854,33 @@ void AdlEngine::getInput(uint &verb, uint &noun) {
 typedef Common::Functor1Mem<ScriptEnv &, int, AdlEngine> OpcodeV1;
 
 int AdlEngine::o1_isItemInRoom(ScriptEnv &e) {
-	if (getItem(e.arg(1)).room != e.arg(2))
-		return -1;
-	return 2;
+	if (getItem(e.arg(1)).room == e.arg(2))
+		return 2;
+	return -1;
 }
 
 int AdlEngine::o1_isMovesGT(ScriptEnv &e) {
-	if (e.arg(1) >= _state.moves)
-		return -1;
-	return 1;
+	if (_state.moves > e.arg(1))
+		return 1;
+	return -1;
 }
 
-int AdlEngine::o1_isVarEq(ScriptEnv &e) {
-	if (getVar(e.arg(1)) != e.arg(2))
-		return -1;
-	return 2;
+int AdlEngine::o1_isVarEQ(ScriptEnv &e) {
+	if (getVar(e.arg(1)) == e.arg(2))
+		return 2;
+	return -1;
 }
 
-int AdlEngine::o1_isCurPicEq(ScriptEnv &e) {
-	if (getCurRoom().curPicture != e.arg(1))
-		return -1;
-	return 1;
+int AdlEngine::o1_isCurPicEQ(ScriptEnv &e) {
+	if (getCurRoom().curPicture == e.arg(1))
+		return 1;
+	return -1;
 }
 
-int AdlEngine::o1_isItemPicEq(ScriptEnv &e) {
-	if (getItem(e.arg(1)).picture != e.arg(2))
-		return -1;
-	return 2;
+int AdlEngine::o1_isItemPicEQ(ScriptEnv &e) {
+	if (getItem(e.arg(1)).picture == e.arg(2))
+		return 2;
+	return -1;
 }
 
 int AdlEngine::o1_varAdd(ScriptEnv &e) {
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index b6e8dfa..d13e122 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -179,9 +179,9 @@ protected:
 	// Opcodes
 	int o1_isItemInRoom(ScriptEnv &e);
 	int o1_isMovesGT(ScriptEnv &e);
-	int o1_isVarEq(ScriptEnv &e);
-	int o1_isCurPicEq(ScriptEnv &e);
-	int o1_isItemPicEq(ScriptEnv &e);
+	int o1_isVarEQ(ScriptEnv &e);
+	int o1_isCurPicEQ(ScriptEnv &e);
+	int o1_isItemPicEQ(ScriptEnv &e);
 
 	int o1_varAdd(ScriptEnv &e);
 	int o1_varSub(ScriptEnv &e);
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 1e5553a..4ef2ae2 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -52,12 +52,12 @@ void AdlEngine_v2::setupOpcodeTables() {
 	// 0x04
 	Opcode(o2_isNounNotInRoom);
 	Opcode(o1_isMovesGT);
-	Opcode(o1_isVarEq);
+	Opcode(o1_isVarEQ);
 	OpcodeUnImpl();
 	// 0x08
 	OpcodeUnImpl();
-	Opcode(o1_isCurPicEq);
-	Opcode(o1_isItemPicEq);
+	Opcode(o1_isCurPicEQ);
+	Opcode(o1_isItemPicEQ);
 
 	SetOpcodeTable(_actOpcodes);
 	// 0x00
@@ -114,10 +114,10 @@ int AdlEngine_v2::o2_isFirstTime(ScriptEnv &e) {
 int AdlEngine_v2::o2_isRandomGT(ScriptEnv &e) {
 	byte rnd = _random->getRandomNumber(255);
 
-	if (e.arg(1) >= rnd)
-		return -1;
+	if (rnd > e.arg(1))
+		return 1;
 
-	return 1;
+	return -1;
 }
 
 int AdlEngine_v2::o2_isItemInRoom(ScriptEnv &e) {
@@ -126,10 +126,10 @@ int AdlEngine_v2::o2_isItemInRoom(ScriptEnv &e) {
 	if (room == IDI_CUR_ROOM)
 		room = _state.room;
 
-	if (getItem(e.arg(1)).room != room)
-		return -1;
+	if (getItem(e.arg(1)).room == room)
+		return 2;
 
-	return 2;
+	return -1;
 }
 
 int AdlEngine_v2::o2_isNounNotInRoom(ScriptEnv &e) {


Commit: 8a05a9cbca3c86868e148e09c392c2bd53bc4de0
    https://github.com/scummvm/scummvm/commit/8a05a9cbca3c86868e148e09c392c2bd53bc4de0
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Implement final hires2 conditional opcode

Changed paths:
    engines/adl/adl_v2.cpp
    engines/adl/adl_v2.h



diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 4ef2ae2..8af3fc9 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -53,7 +53,7 @@ void AdlEngine_v2::setupOpcodeTables() {
 	Opcode(o2_isNounNotInRoom);
 	Opcode(o1_isMovesGT);
 	Opcode(o1_isVarEQ);
-	OpcodeUnImpl();
+	Opcode(o2_isCarryingSomething);
 	// 0x08
 	OpcodeUnImpl();
 	Opcode(o1_isCurPicEQ);
@@ -147,6 +147,15 @@ int AdlEngine_v2::o2_isNounNotInRoom(ScriptEnv &e) {
 	return 1;
 }
 
+int AdlEngine_v2::o2_isCarryingSomething(ScriptEnv &e) {
+	Common::Array<Item>::const_iterator item;
+
+	for (item = _state.items.begin(); item != _state.items.end(); ++item)
+		if (item->room == IDI_NONE)
+			return 0;
+	return -1;
+}
+
 int AdlEngine_v2::o2_moveItem(ScriptEnv &e) {
 	byte room = e.arg(2);
 
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 5513da3..585bd96 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -47,6 +47,7 @@ protected:
 	int o2_isRandomGT(ScriptEnv &e);
 	int o2_isItemInRoom(ScriptEnv &e);
 	int o2_isNounNotInRoom(ScriptEnv &e);
+	int o2_isCarryingSomething(ScriptEnv &e);
 
 	int o2_moveItem(ScriptEnv &e);
 


Commit: 3f7d5608a9b3cd967c4ceb6fd9bfb5d2e4c19643
    https://github.com/scummvm/scummvm/commit/3f7d5608a9b3cd967c4ceb6fd9bfb5d2e4c19643
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Implement a few hires2 opcodes

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/adl_v2.cpp
    engines/adl/adl_v2.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index e6ce0f6..b3ac12d 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -343,6 +343,10 @@ void AdlEngine::setupOpcodeTables() {
 	Opcode(o1_setRoomPic);
 }
 
+bool AdlEngine::matchesCurrentPic(byte pic) const {
+	return pic == getCurRoom().curPicture;
+}
+
 void AdlEngine::clearScreen() const {
 	_display->setMode(DISPLAY_MODE_MIXED);
 	_display->clear(0x00);
@@ -369,8 +373,7 @@ void AdlEngine::drawItems() const {
 		Common::Array<byte>::const_iterator pic;
 
 		for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
-			// IDI_NONE check was added in hires2
-			if (*pic == getCurRoom().curPicture || *pic == IDI_NONE) {
+			if (matchesCurrentPic(*pic)) {
 				drawItem(*item, item->position);
 				continue;
 			}
@@ -451,7 +454,7 @@ void AdlEngine::takeItem(byte noun) {
 
 		Common::Array<byte>::const_iterator pic;
 		for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
-			if (*pic == getCurRoom().curPicture) {
+			if (matchesCurrentPic(*pic)) {
 				item->room = IDI_NONE;
 				item->state = IDI_ITEM_DROPPED;
 				return;
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index d13e122..57036b9 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -175,6 +175,7 @@ protected:
 	virtual void checkInput(byte verb, byte noun);
 
 	virtual void setupOpcodeTables();
+	virtual bool matchesCurrentPic(byte pic) const;
 
 	// Opcodes
 	int o1_isItemInRoom(ScriptEnv &e);
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 8af3fc9..61077d5 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -76,14 +76,14 @@ void AdlEngine_v2::setupOpcodeTables() {
 	Opcode(o1_setLight);
 	Opcode(o1_setDark);
 	// 0x0c
-	OpcodeUnImpl();
+	Opcode(o2_moveAllItems);
 	Opcode(o1_quit);
 	OpcodeUnImpl();
-	Opcode(o1_save);
+	Opcode(o1_save); // TODO
 	// 0x10
-	Opcode(o1_restore);
+	Opcode(o1_restore); // TODO
 	Opcode(o1_restart);
-	Opcode(o1_placeItem);
+	Opcode(o2_placeItem);
 	Opcode(o1_setItemPic);
 	// 0x14
 	Opcode(o1_resetPic);
@@ -100,6 +100,10 @@ void AdlEngine_v2::setupOpcodeTables() {
 	Opcode(o1_setRoomPic);
 }
 
+bool AdlEngine_v2::matchesCurrentPic(byte pic) const {
+	return pic == getCurRoom().curPicture || pic == IDI_NONE;
+}
+
 int AdlEngine_v2::o2_isFirstTime(ScriptEnv &e) {
 	bool oldFlag = getCurRoom().isFirstTime;
 
@@ -164,8 +168,6 @@ int AdlEngine_v2::o2_moveItem(ScriptEnv &e) {
 
 	Item &item = getItem(e.arg(1));
 
-	// Not implemented: set redraw flag if item room == displayed room
-
 	// Set items that move from inventory to a room to state "dropped"
 	if (item.room == IDI_NONE && room != IDI_VOID_ROOM)
 		item.state = IDI_ITEM_DROPPED;
@@ -174,4 +176,43 @@ int AdlEngine_v2::o2_moveItem(ScriptEnv &e) {
 	return 2;
 }
 
+int AdlEngine_v2::o2_moveAllItems(ScriptEnv &e) {
+	byte room1 = e.arg(1);
+
+	if (room1 == IDI_CUR_ROOM)
+		room1 = _state.room;
+
+	byte room2 = e.arg(2);
+
+	if (room2 == IDI_CUR_ROOM)
+		room2 = _state.room;
+
+	Common::Array<Item>::iterator item;
+
+	for (item = _state.items.begin(); item != _state.items.end(); ++item)
+		if (item->room == room1) {
+			item->room = room2;
+			if (room1 == IDI_NONE)
+				item->state = IDI_ITEM_DROPPED;
+		}
+
+	return 2;
+}
+
+int AdlEngine_v2::o2_placeItem(ScriptEnv &e) {
+	byte room = e.arg(2);
+
+	if (room == IDI_CUR_ROOM)
+		room = _state.room;
+
+	Item &item = getItem(e.arg(1));
+
+	item.room = room;
+	item.position.x = e.arg(3);
+	item.position.y = e.arg(4);
+	item.state = IDI_ITEM_NOT_MOVED;
+
+	return 4;
+}
+
 } // End of namespace Adl
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 585bd96..d6c18e1 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -25,6 +25,9 @@
 
 #include "adl/adl.h"
 
+// Note: this version of ADL redraws only when necessary, but
+// this is not currently implemented.
+
 #define IDI_CUR_ROOM 0xfc
 #define IDI_VOID_ROOM 0xfd
 
@@ -42,12 +45,15 @@ protected:
 	AdlEngine_v2(OSystem *syst, const AdlGameDescription *gd);
 
 	virtual void setupOpcodeTables();
+	bool matchesCurrentPic(byte pic) const;
 
 	int o2_isFirstTime(ScriptEnv &e);
 	int o2_isRandomGT(ScriptEnv &e);
 	int o2_isItemInRoom(ScriptEnv &e);
 	int o2_isNounNotInRoom(ScriptEnv &e);
 	int o2_isCarryingSomething(ScriptEnv &e);
+	int o2_moveAllItems(ScriptEnv &e);
+	int o2_placeItem(ScriptEnv &e);
 
 	int o2_moveItem(ScriptEnv &e);
 


Commit: 4ce697e2c38dd96eee13a793402d2946f89d856b
    https://github.com/scummvm/scummvm/commit/4ce697e2c38dd96eee13a793402d2946f89d856b
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Rename IDI_NONE to IDI_ANY

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/adl_v2.cpp



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index b3ac12d..9bd22f8 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -448,14 +448,14 @@ void AdlEngine::takeItem(byte noun) {
 		}
 
 		if (item->state == IDI_ITEM_DROPPED) {
-			item->room = IDI_NONE;
+			item->room = IDI_ANY;
 			return;
 		}
 
 		Common::Array<byte>::const_iterator pic;
 		for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
 			if (matchesCurrentPic(*pic)) {
-				item->room = IDI_NONE;
+				item->room = IDI_ANY;
 				item->state = IDI_ITEM_DROPPED;
 				return;
 			}
@@ -469,7 +469,7 @@ void AdlEngine::dropItem(byte noun) {
 	Common::Array<Item>::iterator item;
 
 	for (item = _state.items.begin(); item != _state.items.end(); ++item) {
-		if (item->noun != noun || item->room != IDI_NONE)
+		if (item->noun != noun || item->room != IDI_ANY)
 			continue;
 
 		item->room = _state.room;
@@ -905,7 +905,7 @@ int AdlEngine::o1_listInv(ScriptEnv &e) {
 	Common::Array<Item>::const_iterator item;
 
 	for (item = _state.items.begin(); item != _state.items.end(); ++item)
-		if (item->room == IDI_NONE)
+		if (item->room == IDI_ANY)
 			printMessage(item->description);
 
 	return 0;
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 57036b9..ea6a51c 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -54,7 +54,7 @@ struct ScriptEnv;
 #define IDO_ACT_SAVE           0x0f
 #define IDO_ACT_LOAD           0x10
 
-#define IDI_NONE 0xfe
+#define IDI_ANY 0xfe
 
 #define IDI_WORD_SIZE 8
 
@@ -104,9 +104,9 @@ public:
 	void skip(uint i) { _ip += i; }
 
 	bool isMatch() const {
-		return (_cmd.room == IDI_NONE || _cmd.room == _room) &&
-		       (_cmd.verb == IDI_NONE || _cmd.verb == _verb) &&
-		       (_cmd.noun == IDI_NONE || _cmd.noun == _noun);
+		return (_cmd.room == IDI_ANY || _cmd.room == _room) &&
+		       (_cmd.verb == IDI_ANY || _cmd.verb == _verb) &&
+		       (_cmd.noun == IDI_ANY || _cmd.noun == _noun);
 	}
 
 	byte getCondCount() const { return _cmd.numCond; }
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 61077d5..3383a63 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -101,7 +101,7 @@ void AdlEngine_v2::setupOpcodeTables() {
 }
 
 bool AdlEngine_v2::matchesCurrentPic(byte pic) const {
-	return pic == getCurRoom().curPicture || pic == IDI_NONE;
+	return pic == getCurRoom().curPicture || pic == IDI_ANY;
 }
 
 int AdlEngine_v2::o2_isFirstTime(ScriptEnv &e) {
@@ -155,7 +155,7 @@ int AdlEngine_v2::o2_isCarryingSomething(ScriptEnv &e) {
 	Common::Array<Item>::const_iterator item;
 
 	for (item = _state.items.begin(); item != _state.items.end(); ++item)
-		if (item->room == IDI_NONE)
+		if (item->room == IDI_ANY)
 			return 0;
 	return -1;
 }
@@ -169,7 +169,7 @@ int AdlEngine_v2::o2_moveItem(ScriptEnv &e) {
 	Item &item = getItem(e.arg(1));
 
 	// Set items that move from inventory to a room to state "dropped"
-	if (item.room == IDI_NONE && room != IDI_VOID_ROOM)
+	if (item.room == IDI_ANY && room != IDI_VOID_ROOM)
 		item.state = IDI_ITEM_DROPPED;
 
 	item.room = room;
@@ -192,7 +192,7 @@ int AdlEngine_v2::o2_moveAllItems(ScriptEnv &e) {
 	for (item = _state.items.begin(); item != _state.items.end(); ++item)
 		if (item->room == room1) {
 			item->room = room2;
-			if (room1 == IDI_NONE)
+			if (room1 == IDI_ANY)
 				item->state = IDI_ITEM_DROPPED;
 		}
 


Commit: 3102ff4a1951ca0a3ca6446f8b5bc67849fe3d73
    https://github.com/scummvm/scummvm/commit/3102ff4a1951ca0a3ca6446f8b5bc67849fe3d73
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Clean up handling of room value 0xfc

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/adl_v2.cpp
    engines/adl/adl_v2.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 9bd22f8..1f4ebcd 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -347,6 +347,10 @@ bool AdlEngine::matchesCurrentPic(byte pic) const {
 	return pic == getCurRoom().curPicture;
 }
 
+byte AdlEngine::roomArg(byte room) const {
+	return room;
+}
+
 void AdlEngine::clearScreen() const {
 	_display->setMode(DISPLAY_MODE_MIXED);
 	_display->clear(0x00);
@@ -857,7 +861,7 @@ void AdlEngine::getInput(uint &verb, uint &noun) {
 typedef Common::Functor1Mem<ScriptEnv &, int, AdlEngine> OpcodeV1;
 
 int AdlEngine::o1_isItemInRoom(ScriptEnv &e) {
-	if (getItem(e.arg(1)).room == e.arg(2))
+	if (getItem(e.arg(1)).room == roomArg(e.arg(2)))
 		return 2;
 	return -1;
 }
@@ -980,9 +984,11 @@ int AdlEngine::o1_quit(ScriptEnv &e) {
 }
 
 int AdlEngine::o1_placeItem(ScriptEnv &e) {
-	getItem(e.arg(1)).room = e.arg(2);
-	getItem(e.arg(1)).position.x = e.arg(3);
-	getItem(e.arg(1)).position.y = e.arg(4);
+	Item &item = getItem(e.arg(1));
+
+	item.room = roomArg(e.arg(2));
+	item.position.x = e.arg(3);
+	item.position.y = e.arg(4);
 	return 4;
 }
 
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index ea6a51c..595386c 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -176,6 +176,7 @@ protected:
 
 	virtual void setupOpcodeTables();
 	virtual bool matchesCurrentPic(byte pic) const;
+	virtual byte roomArg(byte room) const;
 
 	// Opcodes
 	int o1_isItemInRoom(ScriptEnv &e);
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 3383a63..1a07d0e 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -48,7 +48,7 @@ void AdlEngine_v2::setupOpcodeTables() {
 	OpcodeUnImpl();
 	Opcode(o2_isFirstTime);
 	Opcode(o2_isRandomGT);
-	Opcode(o2_isItemInRoom);
+	Opcode(o1_isItemInRoom);
 	// 0x04
 	Opcode(o2_isNounNotInRoom);
 	Opcode(o1_isMovesGT);
@@ -104,6 +104,12 @@ 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;
+	return room;
+}
+
 int AdlEngine_v2::o2_isFirstTime(ScriptEnv &e) {
 	bool oldFlag = getCurRoom().isFirstTime;
 
@@ -124,28 +130,11 @@ int AdlEngine_v2::o2_isRandomGT(ScriptEnv &e) {
 	return -1;
 }
 
-int AdlEngine_v2::o2_isItemInRoom(ScriptEnv &e) {
-	byte room = e.arg(2);
-
-	if (room == IDI_CUR_ROOM)
-		room = _state.room;
-
-	if (getItem(e.arg(1)).room == room)
-		return 2;
-
-	return -1;
-}
-
 int AdlEngine_v2::o2_isNounNotInRoom(ScriptEnv &e) {
 	Common::Array<Item>::const_iterator item;
 
-	byte room = e.arg(1);
-
-	if (room == IDI_CUR_ROOM)
-		room = _state.room;
-
 	for (item = _state.items.begin(); item != _state.items.end(); ++item)
-		if (item->noun == e.getNoun() && (item->room == room))
+		if (item->noun == e.getNoun() && (item->room == roomArg(e.arg(1))))
 			return -1;
 
 	return 1;
@@ -161,10 +150,7 @@ int AdlEngine_v2::o2_isCarryingSomething(ScriptEnv &e) {
 }
 
 int AdlEngine_v2::o2_moveItem(ScriptEnv &e) {
-	byte room = e.arg(2);
-
-	if (room == IDI_CUR_ROOM)
-		room = _state.room;
+	byte room = roomArg(e.arg(2));
 
 	Item &item = getItem(e.arg(1));
 
@@ -177,15 +163,8 @@ int AdlEngine_v2::o2_moveItem(ScriptEnv &e) {
 }
 
 int AdlEngine_v2::o2_moveAllItems(ScriptEnv &e) {
-	byte room1 = e.arg(1);
-
-	if (room1 == IDI_CUR_ROOM)
-		room1 = _state.room;
-
-	byte room2 = e.arg(2);
-
-	if (room2 == IDI_CUR_ROOM)
-		room2 = _state.room;
+	byte room1 = roomArg(e.arg(1));
+	byte room2 = roomArg(e.arg(2));
 
 	Common::Array<Item>::iterator item;
 
@@ -200,14 +179,9 @@ int AdlEngine_v2::o2_moveAllItems(ScriptEnv &e) {
 }
 
 int AdlEngine_v2::o2_placeItem(ScriptEnv &e) {
-	byte room = e.arg(2);
-
-	if (room == IDI_CUR_ROOM)
-		room = _state.room;
-
 	Item &item = getItem(e.arg(1));
 
-	item.room = room;
+	item.room = roomArg(e.arg(2));
 	item.position.x = e.arg(3);
 	item.position.y = e.arg(4);
 	item.state = IDI_ITEM_NOT_MOVED;
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index d6c18e1..e21c43c 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -46,10 +46,10 @@ protected:
 
 	virtual void setupOpcodeTables();
 	bool matchesCurrentPic(byte pic) const;
+	byte roomArg(byte room) const;
 
 	int o2_isFirstTime(ScriptEnv &e);
 	int o2_isRandomGT(ScriptEnv &e);
-	int o2_isItemInRoom(ScriptEnv &e);
 	int o2_isNounNotInRoom(ScriptEnv &e);
 	int o2_isCarryingSomething(ScriptEnv &e);
 	int o2_moveAllItems(ScriptEnv &e);


Commit: e7c93489e4f6055c988d048c9c479de3eff94ece
    https://github.com/scummvm/scummvm/commit/e7c93489e4f6055c988d048c9c479de3eff94ece
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Clean up drawItems()

Changed paths:
    engines/adl/adl.cpp



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 1f4ebcd..715d7a8 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -362,24 +362,25 @@ void AdlEngine::drawItems() const {
 	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) {
-				const Common::Point &p =  _itemOffsets[dropped];
-				drawItem(*item, p);
+				drawItem(*item, _itemOffsets[dropped]);
 				++dropped;
 			}
-			continue;
-		}
-
-		Common::Array<byte>::const_iterator pic;
+		} 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);
-				continue;
+			for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
+				if (matchesCurrentPic(*pic)) {
+					drawItem(*item, item->position);
+					break;
+				}
 			}
 		}
 	}


Commit: a7a371c63d1570714c7b5cb766f6acc3fd26f5fc
    https://github.com/scummvm/scummvm/commit/a7a371c63d1570714c7b5cb766f6acc3fd26f5fc
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Implement time opcode

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/adl_v2.cpp
    engines/adl/adl_v2.h
    engines/adl/hires2.cpp
    engines/adl/hires2.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 715d7a8..e2025b9 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -552,6 +552,7 @@ Common::Error AdlEngine::run() {
 		}
 
 		doAllCommands(_globalCommands, verb, noun);
+		advanceClock();
 		_state.moves++;
 	}
 
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 595386c..5aba30e 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -136,6 +136,12 @@ struct Item {
 	Common::Array<byte> roomPictures;
 };
 
+struct Time {
+	byte hours, minutes;
+
+	Time() : hours(12), minutes(0) { }
+};
+
 struct State {
 	Common::Array<Room> rooms;
 	Common::Array<Item> items;
@@ -144,6 +150,7 @@ struct State {
 	byte room;
 	uint16 moves;
 	bool isDark;
+	Time time;
 
 	State() : room(1), moves(1), isDark(false) { }
 };
@@ -177,6 +184,7 @@ protected:
 	virtual void setupOpcodeTables();
 	virtual bool matchesCurrentPic(byte pic) const;
 	virtual byte roomArg(byte room) const;
+	virtual void advanceClock() { }
 
 	// Opcodes
 	int o1_isItemInRoom(ScriptEnv &e);
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 1a07d0e..e5e02d2 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -23,6 +23,7 @@
 #include "common/random.h"
 
 #include "adl/adl_v2.h"
+#include "adl/display.h"
 
 namespace Adl {
 
@@ -31,7 +32,8 @@ AdlEngine_v2::~AdlEngine_v2() {
 }
 
 AdlEngine_v2::AdlEngine_v2(OSystem *syst, const AdlGameDescription *gd) :
-		AdlEngine(syst, gd) {
+		AdlEngine(syst, gd),
+		_linesPrinted(0) {
 	_random = new Common::RandomSource("adl");
 }
 
@@ -98,6 +100,7 @@ void AdlEngine_v2::setupOpcodeTables() {
 	// 0x1c
 	Opcode(o1_dropItem);
 	Opcode(o1_setRoomPic);
+	Opcode(o2_tellTime);
 }
 
 bool AdlEngine_v2::matchesCurrentPic(byte pic) const {
@@ -110,6 +113,81 @@ byte AdlEngine_v2::roomArg(byte room) const {
 	return room;
 }
 
+void AdlEngine_v2::advanceClock() {
+	Time &time = _state.time;
+
+	time.minutes += 5;
+
+	if (time.minutes == 60) {
+		time.minutes = 0;
+
+		++time.hours;
+
+		if (time.hours == 13)
+			time.hours = 1;
+	}
+}
+
+void AdlEngine_v2::checkTextOverflow(char c) {
+	if (c != APPLECHAR('\r'))
+		return;
+
+	++_linesPrinted;
+
+	if (_linesPrinted < 4)
+		return;
+
+	_linesPrinted = 0;
+	_display->updateTextScreen();
+	bell();
+
+	while (true) {
+		char key = inputKey(false);
+
+		if (shouldQuit())
+			return;
+
+		if (key == APPLECHAR('\r'))
+			break;
+
+		bell(3);
+	}
+}
+
+void AdlEngine_v2::printString(const Common::String &str) {
+	Common::String s(str);
+	byte endPos = TEXT_WIDTH - 1;
+	byte pos = 0;
+
+	while (true) {
+		while (pos != endPos && pos != s.size()) {
+			s.setChar(APPLECHAR(s[pos]), pos);
+			++pos;
+		}
+
+		if (pos == s.size())
+			break;
+
+		while (s[pos] != APPLECHAR(' ') && s[pos] != APPLECHAR('\r'))
+			--pos;
+
+		s.setChar(APPLECHAR('\r'), pos);
+		endPos = pos + TEXT_WIDTH;
+		++pos;
+	}
+
+	pos = 0;
+	while (pos != s.size()) {
+		checkTextOverflow(s[pos]);
+		_display->printChar(s[pos]);
+		++pos;
+	}
+
+	checkTextOverflow(APPLECHAR('\r'));
+	_display->printChar(APPLECHAR('\r'));
+	_display->updateTextScreen();
+}
+
 int AdlEngine_v2::o2_isFirstTime(ScriptEnv &e) {
 	bool oldFlag = getCurRoom().isFirstTime;
 
@@ -189,4 +267,17 @@ int AdlEngine_v2::o2_placeItem(ScriptEnv &e) {
 	return 4;
 }
 
+int AdlEngine_v2::o2_tellTime(ScriptEnv &e) {
+	Common::String time = _strings_v2.time;
+
+	time.setChar(APPLECHAR('0') + _state.time.hours / 10, 12);
+	time.setChar(APPLECHAR('0') + _state.time.hours % 10, 13);
+	time.setChar(APPLECHAR('0') + _state.time.minutes / 10, 15);
+	time.setChar(APPLECHAR('0') + _state.time.minutes % 10, 16);
+
+	printString(time);
+
+	return 0;
+}
+
 } // End of namespace Adl
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index e21c43c..d484719 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -44,18 +44,30 @@ public:
 protected:
 	AdlEngine_v2(OSystem *syst, const AdlGameDescription *gd);
 
+	// AdlEngine
 	virtual void setupOpcodeTables();
 	bool matchesCurrentPic(byte pic) const;
 	byte roomArg(byte room) const;
+	void advanceClock();
+
+	void checkTextOverflow(char c);
+	void printString(const Common::String &str);
 
 	int o2_isFirstTime(ScriptEnv &e);
 	int o2_isRandomGT(ScriptEnv &e);
 	int o2_isNounNotInRoom(ScriptEnv &e);
 	int o2_isCarryingSomething(ScriptEnv &e);
+
+	int o2_moveItem(ScriptEnv &e);
 	int o2_moveAllItems(ScriptEnv &e);
 	int o2_placeItem(ScriptEnv &e);
+	int o2_tellTime(ScriptEnv &e);
 
-	int o2_moveItem(ScriptEnv &e);
+	struct {
+		Common::String time;
+	} _strings_v2;
+
+	uint _linesPrinted;
 
 private:
 	Common::RandomSource *_random;
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 6f517da..49e70a1 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -84,6 +84,7 @@ void HiRes2Engine::init() {
 	_strings.nounError = readStringAt(f, IDI_HR2_OFS_STR_NOUN_ERROR);
 	_strings.playAgain = readStringAt(f, IDI_HR2_OFS_STR_PLAY_AGAIN);
 	_strings.pressReturn = readStringAt(f, IDI_HR2_OFS_STR_PRESS_RETURN);
+	_strings_v2.time = readStringAt(f, IDI_HR2_OFS_STR_TIME, 0xff);
 
 	_messageIds.cantGoThere = IDI_HR2_MSG_CANT_GO_THERE;
 	_messageIds.dontUnderstand = IDI_HR2_MSG_DONT_UNDERSTAND;
@@ -248,66 +249,6 @@ void HiRes2Engine::checkInput(byte verb, byte noun) {
 	AdlEngine::checkInput(verb, noun);
 }
 
-void HiRes2Engine::checkTextOverflow(char c) {
-	if (c != APPLECHAR('\r'))
-		return;
-
-	++_linesPrinted;
-
-	if (_linesPrinted < 4)
-		return;
-
-	_linesPrinted = 0;
-	_display->updateTextScreen();
-	bell();
-
-	while (true) {
-		char key = inputKey(false);
-
-		if (shouldQuit())
-			return;
-
-		if (key == APPLECHAR('\r'))
-			break;
-
-		bell(3);
-	}
-}
-
-void HiRes2Engine::printString(const Common::String &str) {
-	Common::String s(str);
-	byte endPos = TEXT_WIDTH - 1;
-	byte pos = 0;
-
-	while (true) {
-		while (pos != endPos && pos != s.size()) {
-			s.setChar(APPLECHAR(s[pos]), pos);
-			++pos;
-		}
-
-		if (pos == s.size())
-			break;
-
-		while (s[pos] != APPLECHAR(' ') && s[pos] != APPLECHAR('\r'))
-			--pos;
-
-		s.setChar(APPLECHAR('\r'), pos);
-		endPos = pos + TEXT_WIDTH;
-		++pos;
-	}
-
-	pos = 0;
-	while (pos != s.size()) {
-		checkTextOverflow(s[pos]);
-		_display->printChar(s[pos]);
-		++pos;
-	}
-
-	checkTextOverflow(APPLECHAR('\r'));
-	_display->printChar(APPLECHAR('\r'));
-	_display->updateTextScreen();
-}
-
 Engine *HiRes2Engine_create(OSystem *syst, const AdlGameDescription *gd) {
 	return new HiRes2Engine(syst, gd);
 }
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 8ed51b8..121a1f6 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -71,6 +71,7 @@ namespace Adl {
 #define IDI_HR2_OFS_STR_NOUN_ERROR    TSO(0x1a, 0x1, 0x8e)
 #define IDI_HR2_OFS_STR_PLAY_AGAIN    TSO(0x1a, 0x8, 0x25)
 #define IDI_HR2_OFS_STR_PRESS_RETURN  TSO(0x1a, 0x8, 0x5f)
+#define IDI_HR2_OFS_STR_TIME          TSO(0x19, 0x7, 0xd7)
 
 struct Picture2 {
 	byte nr;
@@ -87,7 +88,7 @@ struct RoomData {
 
 class HiRes2Engine : public AdlEngine_v2 {
 public:
-	HiRes2Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine_v2(syst, gd), _linesPrinted(0) { }
+	HiRes2Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine_v2(syst, gd) { }
 
 private:
 	// AdlEngine
@@ -102,12 +103,9 @@ private:
 	void checkInput(byte verb, byte noun);
 
 	void loadRoom(byte roomNr);
-	void checkTextOverflow(char c);
-	void printString(const Common::String &str);
 
 	RoomData _roomData;
 	Common::Array<Picture2> _itemPics;
-	uint _linesPrinted;
 };
 
 } // End of namespace Adl


Commit: 905e2cd63f76271029133ac093647025f036176d
    https://github.com/scummvm/scummvm/commit/905e2cd63f76271029133ac093647025f036176d
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Add hires2 opcode 0x20

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl_v2.cpp
    engines/adl/adl_v2.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index e2025b9..a09ec69 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -1040,7 +1040,7 @@ bool AdlEngine::matchCommand(ScriptEnv &env) const {
 	for (uint i = 0; i < env.getCondCount(); ++i) {
 		byte op = env.op();
 
-		if (!_condOpcodes[op] || !_condOpcodes[op]->isValid())
+		if (op >= _condOpcodes.size() || !_condOpcodes[op] || !_condOpcodes[op]->isValid())
 			error("Unimplemented condition opcode %02x", op);
 
 		int numArgs = (*_condOpcodes[op])(env);
@@ -1058,7 +1058,7 @@ void AdlEngine::doActions(ScriptEnv &env) {
 	for (uint i = 0; i < env.getActCount(); ++i) {
 		byte op = env.op();
 
-		if (!_actOpcodes[op] || !_actOpcodes[op]->isValid())
+		if (op >= _actOpcodes.size() || !_actOpcodes[op] || !_actOpcodes[op]->isValid())
 			error("Unimplemented action opcode %02x", op);
 
 		int numArgs = (*_actOpcodes[op])(env);
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index e5e02d2..3db013d 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -101,6 +101,7 @@ void AdlEngine_v2::setupOpcodeTables() {
 	Opcode(o1_dropItem);
 	Opcode(o1_setRoomPic);
 	Opcode(o2_tellTime);
+	Opcode(o2_setRoomFromVar);
 }
 
 bool AdlEngine_v2::matchesCurrentPic(byte pic) const {
@@ -280,4 +281,10 @@ int AdlEngine_v2::o2_tellTime(ScriptEnv &e) {
 	return 0;
 }
 
+int AdlEngine_v2::o2_setRoomFromVar(ScriptEnv &e) {
+	getCurRoom().curPicture = getCurRoom().picture;
+	_state.room = getVar(e.arg(1));
+	return 1;
+}
+
 } // End of namespace Adl
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index d484719..01aa57c 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -62,6 +62,7 @@ protected:
 	int o2_moveAllItems(ScriptEnv &e);
 	int o2_placeItem(ScriptEnv &e);
 	int o2_tellTime(ScriptEnv &e);
+	int o2_setRoomFromVar(ScriptEnv &e);
 
 	struct {
 		Common::String time;


Commit: 3afcf67643873438b98529b71b244ed715e745f7
    https://github.com/scummvm/scummvm/commit/3afcf67643873438b98529b71b244ed715e745f7
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Stub init disk opcode

Changed paths:
    engines/adl/adl_v2.cpp
    engines/adl/adl_v2.h



diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 3db013d..72d60ac 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -102,6 +102,8 @@ void AdlEngine_v2::setupOpcodeTables() {
 	Opcode(o1_setRoomPic);
 	Opcode(o2_tellTime);
 	Opcode(o2_setRoomFromVar);
+	// 0x20
+	Opcode(o2_initDisk);
 }
 
 bool AdlEngine_v2::matchesCurrentPic(byte pic) const {
@@ -287,4 +289,9 @@ int AdlEngine_v2::o2_setRoomFromVar(ScriptEnv &e) {
 	return 1;
 }
 
+int AdlEngine_v2::o2_initDisk(ScriptEnv &e) {
+	printString("NOT REQUIRED");
+	return 0;
+}
+
 } // End of namespace Adl
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 01aa57c..6da8caa 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -63,6 +63,7 @@ protected:
 	int o2_placeItem(ScriptEnv &e);
 	int o2_tellTime(ScriptEnv &e);
 	int o2_setRoomFromVar(ScriptEnv &e);
+	int o2_initDisk(ScriptEnv &e);
 
 	struct {
 		Common::String time;


Commit: a82ac8973d10dcdac885f686aa56ff4ecbc54643
    https://github.com/scummvm/scummvm/commit/a82ac8973d10dcdac885f686aa56ff4ecbc54643
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Implement hires2 save/restore opcodes

Note: underlying save/restore/restart code still incomplete

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/adl_v2.cpp
    engines/adl/adl_v2.h
    engines/adl/hires2.cpp
    engines/adl/hires2.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index a09ec69..d95cfd5 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -53,9 +53,9 @@ AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) :
 		Engine(syst),
 		_display(nullptr),
 		_graphics(nullptr),
-		_gameDescription(gd),
 		_isRestarting(false),
 		_isRestoring(false),
+		_gameDescription(gd),
 		_saveVerb(0),
 		_saveNoun(0),
 		_restoreVerb(0),
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 5aba30e..2e413ac 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -167,6 +167,10 @@ public:
 protected:
 	AdlEngine(OSystem *syst, const AdlGameDescription *gd);
 
+	// Engine
+	Common::Error loadGameState(int slot);
+	Common::Error saveGameState(int slot, const Common::String &desc);
+
 	Common::String readString(Common::ReadStream &stream, byte until = 0) const;
 	Common::String readStringAt(Common::SeekableReadStream &stream, uint offset, byte until = 0) const;
 	void openFile(Common::File &file, const Common::String &name) const;
@@ -279,6 +283,8 @@ protected:
 	// Game state
 	State _state;
 
+	bool _isRestarting, _isRestoring;
+
 private:
 	virtual void runIntro() const { }
 	virtual void init() = 0;
@@ -290,9 +296,7 @@ private:
 	// Engine
 	Common::Error run();
 	bool hasFeature(EngineFeature f) const;
-	Common::Error loadGameState(int slot);
 	bool canLoadGameStateCurrently();
-	Common::Error saveGameState(int slot, const Common::String &desc);
 	bool canSaveGameStateCurrently();
 
 	// Text output
@@ -305,7 +309,6 @@ private:
 	void getInput(uint &verb, uint &noun);
 
 	const AdlGameDescription *_gameDescription;
-	bool _isRestarting, _isRestoring;
 	byte _saveVerb, _saveNoun, _restoreVerb, _restoreNoun;
 	bool _canSaveNow, _canRestoreNow;
 };
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 72d60ac..029c37a 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -21,6 +21,7 @@
  */
 
 #include "common/random.h"
+#include "common/error.h"
 
 #include "adl/adl_v2.h"
 #include "adl/display.h"
@@ -81,9 +82,9 @@ void AdlEngine_v2::setupOpcodeTables() {
 	Opcode(o2_moveAllItems);
 	Opcode(o1_quit);
 	OpcodeUnImpl();
-	Opcode(o1_save); // TODO
+	Opcode(o2_save);
 	// 0x10
-	Opcode(o1_restore); // TODO
+	Opcode(o2_restore);
 	Opcode(o1_restart);
 	Opcode(o2_placeItem);
 	Opcode(o1_setItemPic);
@@ -259,6 +260,33 @@ int AdlEngine_v2::o2_moveAllItems(ScriptEnv &e) {
 	return 2;
 }
 
+int AdlEngine_v2::o2_save(ScriptEnv &e) {
+	int slot = askForSlot(_strings_v2.saveInsert);
+
+	if (slot < 0)
+		return -1;
+
+	saveGameState(slot, "");
+
+	_display->printString(_strings_v2.saveReplace);
+	inputString();
+	return 0;
+}
+
+int AdlEngine_v2::o2_restore(ScriptEnv &e) {
+	int slot = askForSlot(_strings_v2.restoreInsert);
+
+	if (slot < 0)
+		return -1;
+
+	loadGameState(slot);
+	_isRestoring = false;
+
+	_display->printString(_strings_v2.restoreReplace);
+	inputString();
+	return 0;
+}
+
 int AdlEngine_v2::o2_placeItem(ScriptEnv &e) {
 	Item &item = getItem(e.arg(1));
 
@@ -294,4 +322,18 @@ int AdlEngine_v2::o2_initDisk(ScriptEnv &e) {
 	return 0;
 }
 
+int AdlEngine_v2::askForSlot(const Common::String &question) {
+	while (1) {
+		_display->printString(question);
+
+		Common::String input = inputString();
+
+		if (shouldQuit())
+			return -1;
+
+		if (input.size() > 0 && input[0] >= APPLECHAR('A') && input[0] <= APPLECHAR('O'))
+			return input[0] - APPLECHAR('A');
+	}
+}
+
 } // End of namespace Adl
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 6da8caa..cea4a93 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -60,6 +60,8 @@ protected:
 
 	int o2_moveItem(ScriptEnv &e);
 	int o2_moveAllItems(ScriptEnv &e);
+	int o2_save(ScriptEnv &e);
+	int o2_restore(ScriptEnv &e);
 	int o2_placeItem(ScriptEnv &e);
 	int o2_tellTime(ScriptEnv &e);
 	int o2_setRoomFromVar(ScriptEnv &e);
@@ -67,11 +69,15 @@ protected:
 
 	struct {
 		Common::String time;
+		Common::String saveInsert, saveReplace;
+		Common::String restoreInsert, restoreReplace;
 	} _strings_v2;
 
 	uint _linesPrinted;
 
 private:
+	int askForSlot(const Common::String &question);
+
 	Common::RandomSource *_random;
 };
 
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 49e70a1..71aeeb5 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -85,6 +85,10 @@ void HiRes2Engine::init() {
 	_strings.playAgain = readStringAt(f, IDI_HR2_OFS_STR_PLAY_AGAIN);
 	_strings.pressReturn = readStringAt(f, IDI_HR2_OFS_STR_PRESS_RETURN);
 	_strings_v2.time = readStringAt(f, IDI_HR2_OFS_STR_TIME, 0xff);
+	_strings_v2.saveInsert = readStringAt(f, IDI_HR2_OFS_STR_SAVE_INSERT);
+	_strings_v2.saveReplace = readStringAt(f, IDI_HR2_OFS_STR_SAVE_REPLACE);
+	_strings_v2.restoreInsert = readStringAt(f, IDI_HR2_OFS_STR_RESTORE_INSERT);
+	_strings_v2.restoreReplace = readStringAt(f, IDI_HR2_OFS_STR_RESTORE_REPLACE);
 
 	_messageIds.cantGoThere = IDI_HR2_MSG_CANT_GO_THERE;
 	_messageIds.dontUnderstand = IDI_HR2_MSG_DONT_UNDERSTAND;
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 121a1f6..1578109 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -66,12 +66,16 @@ namespace Adl {
 #define IDI_HR2_MSG_ITEM_NOT_HERE        4
 #define IDI_HR2_MSG_THANKS_FOR_PLAYING 239
 
-#define IDI_HR2_OFS_STR_ENTER_COMMAND TSO(0x1a, 0x1, 0xbc)
-#define IDI_HR2_OFS_STR_VERB_ERROR    TSO(0x1a, 0x1, 0x4f)
-#define IDI_HR2_OFS_STR_NOUN_ERROR    TSO(0x1a, 0x1, 0x8e)
-#define IDI_HR2_OFS_STR_PLAY_AGAIN    TSO(0x1a, 0x8, 0x25)
-#define IDI_HR2_OFS_STR_PRESS_RETURN  TSO(0x1a, 0x8, 0x5f)
-#define IDI_HR2_OFS_STR_TIME          TSO(0x19, 0x7, 0xd7)
+#define IDI_HR2_OFS_STR_ENTER_COMMAND   TSO(0x1a, 0x1, 0xbc)
+#define IDI_HR2_OFS_STR_VERB_ERROR      TSO(0x1a, 0x1, 0x4f)
+#define IDI_HR2_OFS_STR_NOUN_ERROR      TSO(0x1a, 0x1, 0x8e)
+#define IDI_HR2_OFS_STR_PLAY_AGAIN      TSO(0x1a, 0x8, 0x25)
+#define IDI_HR2_OFS_STR_PRESS_RETURN    TSO(0x1a, 0x8, 0x5f)
+#define IDI_HR2_OFS_STR_TIME            TSO(0x19, 0x7, 0xd7)
+#define IDI_HR2_OFS_STR_SAVE_INSERT     TSO(0x1a, 0x6, 0x5f)
+#define IDI_HR2_OFS_STR_SAVE_REPLACE    TSO(0x1a, 0x6, 0xe5)
+#define IDI_HR2_OFS_STR_RESTORE_INSERT  TSO(0x1a, 0x7, 0x32)
+#define IDI_HR2_OFS_STR_RESTORE_REPLACE TSO(0x1a, 0x7, 0xc2)
 
 struct Picture2 {
 	byte nr;


Commit: ffbc4da0b0b2f26f88ad94f75d84fe6facbcfd52
    https://github.com/scummvm/scummvm/commit/ffbc4da0b0b2f26f88ad94f75d84fe6facbcfd52
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Use display class to print init disk message

Changed paths:
    engines/adl/adl_v2.cpp



diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 029c37a..8a826e5 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -318,7 +318,7 @@ int AdlEngine_v2::o2_setRoomFromVar(ScriptEnv &e) {
 }
 
 int AdlEngine_v2::o2_initDisk(ScriptEnv &e) {
-	printString("NOT REQUIRED");
+	_display->printAsciiString("NOT REQUIRED\r");
 	return 0;
 }
 


Commit: 4af9f32d3f12badb0573db203c2949ec5173aae6
    https://github.com/scummvm/scummvm/commit/4af9f32d3f12badb0573db203c2949ec5173aae6
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Add disk format abstraction

Changed paths:
  A engines/adl/disk.cpp
  A engines/adl/disk.h
    engines/adl/module.mk



diff --git a/engines/adl/disk.cpp b/engines/adl/disk.cpp
new file mode 100644
index 0000000..b91efec
--- /dev/null
+++ b/engines/adl/disk.cpp
@@ -0,0 +1,90 @@
+/* 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/stream.h"
+
+#include "adl/disk.h"
+
+namespace Adl {
+
+DiskImage::DiskImage() :
+		_tracks(0),
+		_sectorsPerTrack(0),
+		_bytesPerSector(0) {
+	_f = new Common::File();
+}
+
+DiskImage::~DiskImage() {
+	delete _f;
+}
+
+DiskImageDataBlock::DiskImageDataBlock(const DiskImage *disk, uint track, uint sector, uint offset, uint size) :
+		_track(track),
+		_sector(sector),
+		_offset(offset),
+		_size(size),
+		_disk(disk) { }
+
+bool DiskImageDataBlock::isValid() const {
+	return _track != 0 || _sector != 0 || _offset != 0 || _size != 0;
+}
+
+Common::SeekableReadStream *DiskImageDataBlock::createReadStream() const {
+	return _disk->createReadStream(_track, _sector, _offset, _size);
+}
+
+// .DSK disk image - 35 tracks, 16 sectors per track, 256 bytes per sector, raw sector layout
+const DataBlockPtr DiskImage_DSK::getDataBlock(uint track, uint sector, uint offset, uint size) const {
+	return Common::SharedPtr<DiskImageDataBlock>(new DiskImageDataBlock(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 true;
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/disk.h b/engines/adl/disk.h
new file mode 100644
index 0000000..0bf57c7
--- /dev/null
+++ b/engines/adl/disk.h
@@ -0,0 +1,81 @@
+/* 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/ptr.h"
+#include "common/file.h"
+
+#ifndef ADL_DISK_H
+#define ADL_DISK_H
+
+namespace Common {
+class SeekableReadStream;
+class String;
+}
+
+namespace Adl {
+
+class DataBlock {
+public:
+	virtual ~DataBlock() { }
+
+	virtual bool isValid() const = 0;
+	virtual Common::SeekableReadStream *createReadStream() const = 0;
+};
+
+typedef Common::SharedPtr<DataBlock> DataBlockPtr;
+
+class DiskImage {
+public:
+	DiskImage();
+	virtual ~DiskImage();
+
+	virtual bool open(const Common::String &filename) = 0;
+	virtual const DataBlockPtr getDataBlock(uint track, uint sector, uint offset, uint size) const = 0;
+	virtual Common::SeekableReadStream *createReadStream(uint track, uint sector, uint offset, uint size) const = 0;
+
+protected:
+	Common::File *_f;
+	uint _tracks, _sectorsPerTrack, _bytesPerSector;
+};
+
+class DiskImageDataBlock : public DataBlock {
+public:
+	DiskImageDataBlock(const DiskImage *disk, uint track, uint sector, uint offset, uint size);
+
+	bool isValid() const;
+	Common::SeekableReadStream *createReadStream() const;
+
+private:
+	uint _track, _sector, _offset, _size;
+	const DiskImage *_disk;
+};
+
+class DiskImage_DSK : public DiskImage {
+public:
+	bool open(const Common::String &filename);
+	const DataBlockPtr getDataBlock(uint track, uint sector, uint offset, uint size) const;
+	Common::SeekableReadStream *createReadStream(uint track, uint sector, uint offset = 0, uint size = 0) const;
+};
+
+} // End of namespace Adl
+
+#endif
diff --git a/engines/adl/module.mk b/engines/adl/module.mk
index 7599957..661d1b1 100644
--- a/engines/adl/module.mk
+++ b/engines/adl/module.mk
@@ -4,6 +4,7 @@ MODULE_OBJS := \
 	adl.o \
 	adl_v2.o \
 	detection.o \
+	disk.o \
 	display.o \
 	graphics.o \
 	graphics_v1.o \


Commit: bfbacf9397f6baa03e5b79149fc357d6c8d74049
    https://github.com/scummvm/scummvm/commit/bfbacf9397f6baa03e5b79149fc357d6c8d74049
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Use DiskImage class in hires2

Changed paths:
    engines/adl/adl.h
    engines/adl/hires1.cpp
    engines/adl/hires2.cpp
    engines/adl/hires2.h



diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 2e413ac..dba6cc7 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -35,6 +35,8 @@
 #include "audio/mixer.h"
 #include "audio/softsynth/pcspk.h"
 
+#include "adl/disk.h"
+
 namespace Common {
 class ReadStream;
 class SeekableReadStream;
@@ -69,11 +71,16 @@ enum Direction {
 };
 
 struct Room {
+	Room() :
+			description(0),
+			picture(0),
+			curPicture(0) {
+		memset(connections, 0, sizeof(connections));
+	}
+
 	byte description;
 	byte connections[IDI_DIR_TOTAL];
-	byte track;
-	byte sector;
-	byte offset;
+	DataBlockPtr data;
 	byte picture;
 	byte curPicture;
 	bool isFirstTime;
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index f7f16c0..8554b18 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -223,7 +223,7 @@ void HiRes1Engine::initState() {
 	_roomDesc.clear();
 	f.seek(IDI_HR1_OFS_ROOMS);
 	for (uint i = 0; i < IDI_HR1_NUM_ROOMS; ++i) {
-		Room room = { };
+		Room room;
 		f.readByte();
 		_roomDesc.push_back(f.readByte());
 		for (uint j = 0; j < 6; ++j)
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 71aeeb5..5e3da00 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -29,27 +29,31 @@
 #include "adl/hires2.h"
 #include "adl/display.h"
 #include "adl/graphics.h"
+#include "adl/disk.h"
 
 namespace Adl {
 
-static void readPictureMeta(Common::ReadStream &f, Picture2 &pic) {
+DataBlockPtr HiRes2Engine::readDataBlockPtr(Common::ReadStream &f) const {
+	byte track = f.readByte();
+	byte sector = f.readByte();
+	byte offset = f.readByte();
+	byte size = f.readByte();
+	return _disk.getDataBlock(track, sector, offset, size);
+}
+
+void HiRes2Engine::readPictureMeta(Common::ReadStream &f, Picture2 &pic) const {
 	pic.nr = f.readByte();
-	pic.track = f.readByte();
-	pic.sector = f.readByte();
-	pic.offset = f.readByte();
-	f.readByte();
+	pic.data = readDataBlockPtr(f);
 }
 
 void HiRes2Engine::runIntro() const {
-	Common::File f;
-	openFile(f, IDS_HR2_DISK_IMAGE);
-	f.seek(IDI_HR2_OFS_INTRO_TEXT);
+	StreamPtr stream(_disk.createReadStream(0x00, 0xd, 0x17, 1));
 
 	_display->setMode(DISPLAY_MODE_TEXT);
 
-	Common::String str = readStringAt(f, IDI_HR2_OFS_INTRO_TEXT);
+	Common::String str = readString(*stream);
 
-	if (f.eos() || f.err())
+	if (stream->eos() || stream->err())
 		error("Error reading disk image");
 
 	_display->printString(str);
@@ -59,36 +63,38 @@ void HiRes2Engine::runIntro() const {
 void HiRes2Engine::init() {
 	_graphics = new Graphics_v2(*_display);
 
-	Common::File f;
-	openFile(f, IDS_HR2_DISK_IMAGE);
-
-	for (uint i = 0; i < IDI_HR2_NUM_MESSAGES; ++i) {
-		f.seek(IDI_HR2_OFS_MESSAGES + i * 4);
-		byte track = f.readByte();
-		byte sector = f.readByte();
-		byte offset = f.readByte();
-		// One more byte follows, disk? or size maybe?
-
-		uint diskOffset = TSO(track, sector, offset);
+	if (!_disk.open(IDS_HR2_DISK_IMAGE))
+		error("Failed to open disk image '" IDS_HR2_DISK_IMAGE "'");
 
-		Common::String str;
+	StreamPtr stream(_disk.createReadStream(0x1f, 0x2, 0x04, 4));
 
-		if (diskOffset != 0)
-			str = readStringAt(f, TSO(track, sector, offset), 0xff);
+	for (uint i = 0; i < IDI_HR2_NUM_MESSAGES; ++i) {
+		DataBlockPtr str(readDataBlockPtr(*stream));
 
-		_messages.push_back(str);
+		if (str->isValid()) {
+			StreamPtr strStream(str->createReadStream());
+			_messages.push_back(readString(*strStream, 0xff));
+		}
 	}
 
-	_strings.enterCommand = readStringAt(f, IDI_HR2_OFS_STR_ENTER_COMMAND);
-	_strings.verbError = readStringAt(f, IDI_HR2_OFS_STR_VERB_ERROR);
-	_strings.nounError = readStringAt(f, IDI_HR2_OFS_STR_NOUN_ERROR);
-	_strings.playAgain = readStringAt(f, IDI_HR2_OFS_STR_PLAY_AGAIN);
-	_strings.pressReturn = readStringAt(f, IDI_HR2_OFS_STR_PRESS_RETURN);
-	_strings_v2.time = readStringAt(f, IDI_HR2_OFS_STR_TIME, 0xff);
-	_strings_v2.saveInsert = readStringAt(f, IDI_HR2_OFS_STR_SAVE_INSERT);
-	_strings_v2.saveReplace = readStringAt(f, IDI_HR2_OFS_STR_SAVE_REPLACE);
-	_strings_v2.restoreInsert = readStringAt(f, IDI_HR2_OFS_STR_RESTORE_INSERT);
-	_strings_v2.restoreReplace = readStringAt(f, IDI_HR2_OFS_STR_RESTORE_REPLACE);
+	// 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 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_HR2_MSG_CANT_GO_THERE;
 	_messageIds.dontUnderstand = IDI_HR2_MSG_DONT_UNDERSTAND;
@@ -97,95 +103,91 @@ void HiRes2Engine::init() {
 	_messageIds.thanksForPlaying = IDI_HR2_MSG_THANKS_FOR_PLAYING;
 
 	// Load item picture data
-	f.seek(IDI_HR2_OFS_ITEM_PICS);
+	stream.reset(_disk.createReadStream(0x1e, 0x9, 0x05));
 	for (uint i = 0; i < IDI_HR2_NUM_ITEM_PICS; ++i) {
 		Picture2 pic;
-		readPictureMeta(f, pic);
+		readPictureMeta(*stream, pic);
 		_itemPics.push_back(pic);
 	}
 
 	// Load commands from executable
-	f.seek(IDI_HR2_OFS_CMDS_1);
-	readCommands(f, _roomCommands);
+	stream.reset(_disk.createReadStream(0x1d, 0x7, 0x00, 4));
+	readCommands(*stream, _roomCommands);
 
-	f.seek(IDI_HR2_OFS_CMDS_0);
-	readCommands(f, _globalCommands);
+	stream.reset(_disk.createReadStream(0x1f, 0x7, 0x00, 2));
+	readCommands(*stream, _globalCommands);
 
 	// Load dropped item offsets
-	f.seek(IDI_HR2_OFS_ITEM_OFFSETS);
+	stream.reset(_disk.createReadStream(0x1b, 0x4, 0x15));
 	for (uint i = 0; i < IDI_HR2_NUM_ITEM_OFFSETS; ++i) {
 		Common::Point p;
-		p.x = f.readByte();
-		p.y = f.readByte();
+		p.x = stream->readByte();
+		p.y = stream->readByte();
 		_itemOffsets.push_back(p);
 	}
 
-	f.seek(IDI_HR2_OFS_VERBS);
-	loadWords(f, _verbs);
+	// Load verbs
+	stream.reset(_disk.createReadStream(0x19, 0x0, 0x00, 3));
+	loadWords(*stream, _verbs);
 
-	f.seek(IDI_HR2_OFS_NOUNS);
-	loadWords(f, _nouns);
+	// Load nouns
+	stream.reset(_disk.createReadStream(0x22, 0x2, 0x00, 7));
+	loadWords(*stream, _nouns);
 }
 
 void HiRes2Engine::initState() {
 	_state.vars.clear();
 	_state.vars.resize(IDI_HR2_NUM_VARS);
 
-	Common::File f;
-	openFile(f, IDS_HR2_DISK_IMAGE);
+	StreamPtr stream(_disk.createReadStream(0x21, 0x5, 0x0e, 7));
 
 	_state.rooms.clear();
-	f.seek(IDI_HR2_OFS_ROOMS);
 	for (uint i = 0; i < IDI_HR2_NUM_ROOMS; ++i) {
-		Room room = { };
-		f.readByte(); // number
+		Room room;
+		stream->readByte(); // number
 		for (uint j = 0; j < 6; ++j)
-			room.connections[j] = f.readByte();
-		room.track = f.readByte();
-		room.sector = f.readByte();
-		room.offset = f.readByte();
-		f.readByte(); // always 1, possibly disk?
-		room.picture = f.readByte();
-		room.curPicture = f.readByte();
-		room.isFirstTime = f.readByte();
+			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, 0x00, 2));
+
 	_state.items.clear();
-	f.seek(IDI_HR2_OFS_ITEMS);
-	while (f.readByte() != 0xff) {
+	while (stream->readByte() != 0xff) {
 		Item item = { };
-		item.noun = f.readByte();
-		item.room = f.readByte();
-		item.picture = f.readByte();
-		item.isLineArt = f.readByte(); // Is this still used in this way?
-		item.position.x = f.readByte();
-		item.position.y = f.readByte();
-		item.state = f.readByte();
-		item.description = f.readByte();
+		item.noun = stream->readByte();
+		item.room = stream->readByte();
+		item.picture = stream->readByte();
+		item.isLineArt = stream->readByte(); // Is this still used in this way?
+		item.position.x = stream->readByte();
+		item.position.y = stream->readByte();
+		item.state = stream->readByte();
+		item.description = stream->readByte();
 
-		f.readByte(); // Struct size
+		stream->readByte(); // Struct size
 
-		byte picListSize = f.readByte();
+		byte picListSize = stream->readByte();
 
 		// Flag to keep track of what has been drawn on the screen
-		f.readByte();
+		stream->readByte();
 
 		for (uint i = 0; i < picListSize; ++i)
-			item.roomPictures.push_back(f.readByte());
+			item.roomPictures.push_back(stream->readByte());
 
 		_state.items.push_back(item);
 	}
 }
 
 void HiRes2Engine::loadRoom(byte roomNr) {
-	Common::File f;
-	openFile(f, IDS_HR2_DISK_IMAGE);
 	Room &room = getRoom(roomNr);
-	uint offset = TSO(room.track, room.sector, room.offset);
-	f.seek(offset);
-	uint16 descOffset = f.readUint16LE();
-	uint16 commandOffset = f.readUint16LE();
+	StreamPtr stream(room.data->createReadStream());
+
+	uint16 descOffset = stream->readUint16LE();
+	uint16 commandOffset = stream->readUint16LE();
 
 	// There's no picture count. The original engine always checks at most
 	// five pictures. We use the description offset to bound our search.
@@ -193,15 +195,14 @@ void HiRes2Engine::loadRoom(byte roomNr) {
 
 	for (uint i = 0; i < picCount; ++i) {
 		Picture2 pic;
-		readPictureMeta(f, pic);
+		readPictureMeta(*stream, pic);
 		_roomData.pictures.push_back(pic);
 	}
 
-	_roomData.description = readStringAt(f, offset + descOffset, 0xff);
-
-	f.seek(offset + commandOffset);
+	_roomData.description = readStringAt(*stream, descOffset, 0xff);
 
-	readCommands(f, _roomData.commands);
+	stream->seek(commandOffset);
+	readCommands(*stream, _roomData.commands);
 }
 
 void HiRes2Engine::restartGame() {
@@ -213,10 +214,8 @@ void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
 
 	for (roomPic = _roomData.pictures.begin(); roomPic != _roomData.pictures.end(); ++roomPic) {
 		if (roomPic->nr == pic) {
-			Common::File f;
-			openFile(f, IDS_HR2_DISK_IMAGE);
-			f.seek(TSO(roomPic->track, roomPic->sector, roomPic->offset));
-			_graphics->drawPic(f, pos, 0);
+			StreamPtr stream(roomPic->data->createReadStream());
+			_graphics->drawPic(*stream, pos, 0);
 			return;
 		}
 	}
@@ -226,11 +225,9 @@ void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
 
 void HiRes2Engine::drawItem(const Item &item, const Common::Point &pos) const {
 	const Picture2 &pic = _itemPics[item.picture - 1];
-	Common::File f;
-	openFile(f, IDS_HR2_DISK_IMAGE);
-	f.seek(TSO(pic.track, pic.sector, pic.offset));
-	f.readByte(); // Skip clear opcode
-	_graphics->drawPic(f, pos, 0);
+	StreamPtr stream(pic.data->createReadStream());
+	stream->readByte(); // Skip clear opcode
+	_graphics->drawPic(*stream, pos, 0);
 }
 
 void HiRes2Engine::showRoom() {
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 1578109..0d32330 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -26,6 +26,7 @@
 #include "common/str.h"
 
 #include "adl/adl_v2.h"
+#include "adl/disk.h"
 
 namespace Common {
 class ReadStream;
@@ -36,23 +37,6 @@ namespace Adl {
 
 #define IDS_HR2_DISK_IMAGE "WIZARD.DSK"
 
-// Track, sector, offset
-#define TSO(TRACK, SECTOR, OFFSET) (((TRACK) * 16 + (SECTOR)) * 256 + (OFFSET))
-#define TS(TRACK, SECTOR) TSO(TRACK, SECTOR, 0)
-#define T(TRACK) TS(TRACK, 0)
-
-#define IDI_HR2_OFS_INTRO_TEXT   TSO(0x00, 0xd, 0x17)
-#define IDI_HR2_OFS_VERBS          T(0x19)
-#define IDI_HR2_OFS_NOUNS         TS(0x22, 0x2)
-#define IDI_HR2_OFS_ROOMS        TSO(0x21, 0x5, 0x0e) // Skip bogus room 0
-#define IDI_HR2_OFS_MESSAGES     TSO(0x1f, 0x2, 0x04) // Skip bogus message 0
-#define IDI_HR2_OFS_ITEM_PICS    TSO(0x1e, 0x9, 0x05) // Skip bogus pic 0
-#define IDI_HR2_OFS_ITEMS          T(0x21)
-#define IDI_HR2_OFS_ITEM_OFFSETS TSO(0x1b, 0x4, 0x15)
-
-#define IDI_HR2_OFS_CMDS_0        TS(0x1f, 0x7)
-#define IDI_HR2_OFS_CMDS_1        TS(0x1d, 0x7)
-
 #define IDI_HR2_NUM_ROOMS 135
 #define IDI_HR2_NUM_MESSAGES 254
 #define IDI_HR2_NUM_VARS 40
@@ -66,22 +50,9 @@ namespace Adl {
 #define IDI_HR2_MSG_ITEM_NOT_HERE        4
 #define IDI_HR2_MSG_THANKS_FOR_PLAYING 239
 
-#define IDI_HR2_OFS_STR_ENTER_COMMAND   TSO(0x1a, 0x1, 0xbc)
-#define IDI_HR2_OFS_STR_VERB_ERROR      TSO(0x1a, 0x1, 0x4f)
-#define IDI_HR2_OFS_STR_NOUN_ERROR      TSO(0x1a, 0x1, 0x8e)
-#define IDI_HR2_OFS_STR_PLAY_AGAIN      TSO(0x1a, 0x8, 0x25)
-#define IDI_HR2_OFS_STR_PRESS_RETURN    TSO(0x1a, 0x8, 0x5f)
-#define IDI_HR2_OFS_STR_TIME            TSO(0x19, 0x7, 0xd7)
-#define IDI_HR2_OFS_STR_SAVE_INSERT     TSO(0x1a, 0x6, 0x5f)
-#define IDI_HR2_OFS_STR_SAVE_REPLACE    TSO(0x1a, 0x6, 0xe5)
-#define IDI_HR2_OFS_STR_RESTORE_INSERT  TSO(0x1a, 0x7, 0x32)
-#define IDI_HR2_OFS_STR_RESTORE_REPLACE TSO(0x1a, 0x7, 0xc2)
-
 struct Picture2 {
 	byte nr;
-	byte track;
-	byte sector;
-	byte offset;
+	DataBlockPtr data;
 };
 
 struct RoomData {
@@ -90,6 +61,8 @@ struct RoomData {
 	Commands commands;
 };
 
+typedef Common::ScopedPtr<Common::SeekableReadStream> StreamPtr;
+
 class HiRes2Engine : public AdlEngine_v2 {
 public:
 	HiRes2Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine_v2(syst, gd) { }
@@ -107,7 +80,10 @@ private:
 	void checkInput(byte verb, byte noun);
 
 	void loadRoom(byte roomNr);
+	DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const;
+	void readPictureMeta(Common::ReadStream &f, Picture2 &pic) const;
 
+	DiskImage_DSK _disk;
 	RoomData _roomData;
 	Common::Array<Picture2> _itemPics;
 };


Commit: f2de96512a4e53fa2b81c9a1c20f82f283e271ea
    https://github.com/scummvm/scummvm/commit/f2de96512a4e53fa2b81c9a1c20f82f283e271ea
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Add file-based disk access class

Changed paths:
    engines/adl/disk.cpp
    engines/adl/disk.h



diff --git a/engines/adl/disk.cpp b/engines/adl/disk.cpp
index b91efec..e2c3da3 100644
--- a/engines/adl/disk.cpp
+++ b/engines/adl/disk.cpp
@@ -21,6 +21,7 @@
  */
 
 #include "common/stream.h"
+#include "common/substream.h"
 
 #include "adl/disk.h"
 
@@ -87,4 +88,24 @@ bool DiskImage_DSK::open(const Common::String &filename) {
 	return true;
 }
 
+Common::SeekableReadStream *FilesDataBlock::createReadStream() const {
+	return _files->createReadStream(_filename, _offset);
+}
+
+const DataBlockPtr PlainFiles::getDataBlock(const Common::String &filename, uint offset) const {
+	return Common::SharedPtr<FilesDataBlock>(new FilesDataBlock(this, filename, offset));
+}
+
+Common::SeekableReadStream *PlainFiles::createReadStream(const Common::String &filename, uint offset) const {
+	Common::File *f(new Common::File());
+
+	if (!f->open(filename))
+		error("Failed to open '%s'", filename.c_str());
+
+	if (offset == 0)
+		return f;
+	else
+		return new Common::SeekableSubReadStream(f, offset, f->size(), DisposeAfterUse::YES);
+}
+
 } // End of namespace Adl
diff --git a/engines/adl/disk.h b/engines/adl/disk.h
index 0bf57c7..b6a5c60 100644
--- a/engines/adl/disk.h
+++ b/engines/adl/disk.h
@@ -43,6 +43,33 @@ public:
 
 typedef Common::SharedPtr<DataBlock> DataBlockPtr;
 
+class Files {
+public:
+	virtual ~Files() { }
+
+	virtual const DataBlockPtr getDataBlock(const Common::String &filename, uint offset) const = 0;
+	virtual Common::SeekableReadStream *createReadStream(const Common::String &filename, uint offset) const = 0;
+};
+
+class FilesDataBlock : public DataBlock {
+public:
+	FilesDataBlock(const Files *files, const Common::String &filename, uint offset) : _files(files), _filename(filename), _offset(offset) { }
+
+	bool isValid() const { return true; }
+	Common::SeekableReadStream *createReadStream() const;
+
+private:
+	const Common::String _filename;
+	uint _offset;
+	const Files *_files;
+};
+
+class PlainFiles : public Files {
+public:
+	const DataBlockPtr getDataBlock(const Common::String &filename, uint offset = 0) const;
+	Common::SeekableReadStream *createReadStream(const Common::String &filename, uint offset = 0) const;
+};
+
 class DiskImage {
 public:
 	DiskImage();


Commit: 5451df3afe2d3857a6dd6d4d232f02d46cb27e03
    https://github.com/scummvm/scummvm/commit/5451df3afe2d3857a6dd6d4d232f02d46cb27e03
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Use new disk class in hires1

Changed paths:
    engines/adl/adl.h
    engines/adl/hires1.cpp
    engines/adl/hires1.h
    engines/adl/hires2.h



diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index dba6cc7..ba803e8 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -52,6 +52,8 @@ class Speaker;
 struct AdlGameDescription;
 struct ScriptEnv;
 
+typedef Common::ScopedPtr<Common::SeekableReadStream> StreamPtr;
+
 // Save and restore opcodes
 #define IDO_ACT_SAVE           0x0f
 #define IDO_ACT_LOAD           0x10
@@ -87,8 +89,7 @@ struct Room {
 };
 
 struct Picture {
-	byte block;
-	uint16 offset;
+	DataBlockPtr data;
 };
 
 typedef Common::Array<byte> Script;
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 8554b18..109879e 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -33,13 +33,11 @@
 namespace Adl {
 
 void HiRes1Engine::runIntro() const {
-	Common::File file;
+	StreamPtr stream(_files.createReadStream(IDS_HR1_EXE_0));
 
-	openFile(file, IDS_HR1_EXE_0);
-
-	file.seek(IDI_HR1_OFS_LOGO_0);
+	stream->seek(IDI_HR1_OFS_LOGO_0);
 	_display->setMode(DISPLAY_MODE_HIRES);
-	_display->loadFrameBuffer(file);
+	_display->loadFrameBuffer(*stream);
 	_display->updateHiResScreen();
 	delay(4000);
 
@@ -48,21 +46,19 @@ void HiRes1Engine::runIntro() const {
 
 	_display->setMode(DISPLAY_MODE_TEXT);
 
-	Common::File basic;
-	openFile(basic, IDS_HR1_LOADER);
-
+	StreamPtr basic(_files.createReadStream(IDS_HR1_LOADER));
 	Common::String str;
 
-	str = readStringAt(basic, IDI_HR1_OFS_PD_TEXT_0, '"');
+	str = readStringAt(*basic, IDI_HR1_OFS_PD_TEXT_0, '"');
 	_display->printAsciiString(str + '\r');
 
-	str = readStringAt(basic, IDI_HR1_OFS_PD_TEXT_1, '"');
+	str = readStringAt(*basic, IDI_HR1_OFS_PD_TEXT_1, '"');
 	_display->printAsciiString(str + "\r\r");
 
-	str = readStringAt(basic, IDI_HR1_OFS_PD_TEXT_2, '"');
+	str = readStringAt(*basic, IDI_HR1_OFS_PD_TEXT_2, '"');
 	_display->printAsciiString(str + "\r\r");
 
-	str = readStringAt(basic, IDI_HR1_OFS_PD_TEXT_3, '"');
+	str = readStringAt(*basic, IDI_HR1_OFS_PD_TEXT_3, '"');
 	_display->printAsciiString(str + '\r');
 
 	inputKey();
@@ -71,7 +67,7 @@ void HiRes1Engine::runIntro() const {
 
 	_display->setMode(DISPLAY_MODE_MIXED);
 
-	str = readStringAt(file, IDI_HR1_OFS_GAME_OR_HELP);
+	str = readStringAt(*stream, IDI_HR1_OFS_GAME_OR_HELP);
 
 	bool instructions = false;
 
@@ -95,7 +91,7 @@ void HiRes1Engine::runIntro() const {
 
 	if (instructions) {
 		_display->setMode(DISPLAY_MODE_TEXT);
-		file.seek(IDI_HR1_OFS_INTRO_TEXT);
+		stream->seek(IDI_HR1_OFS_INTRO_TEXT);
 
 		const uint pages[] = { 6, 6, 4, 5, 8, 7, 0 };
 
@@ -105,9 +101,9 @@ void HiRes1Engine::runIntro() const {
 
 			uint count = pages[page++];
 			for (uint i = 0; i < count; ++i) {
-				str = readString(file);
+				str = readString(*stream);
 				_display->printString(str);
-				file.seek(3, SEEK_CUR);
+				stream->seek(3, SEEK_CUR);
 			}
 
 			inputString();
@@ -115,20 +111,18 @@ void HiRes1Engine::runIntro() const {
 			if (g_engine->shouldQuit())
 				return;
 
-			file.seek(6, SEEK_CUR);
+			stream->seek(6, SEEK_CUR);
 		}
 	}
 
 	_display->printAsciiString("\r");
 
-	file.close();
-
 	_display->setMode(DISPLAY_MODE_MIXED);
 
 	// Title screen shown during loading
-	openFile(file, IDS_HR1_EXE_1);
-	file.seek(IDI_HR1_OFS_LOGO_1);
-	_display->loadFrameBuffer(file);
+	stream.reset(_files.createReadStream(IDS_HR1_EXE_1));
+	stream->seek(IDI_HR1_OFS_LOGO_1);
+	_display->loadFrameBuffer(*stream);
 	_display->updateHiResScreen();
 	delay(2000);
 }
@@ -136,27 +130,25 @@ void HiRes1Engine::runIntro() const {
 void HiRes1Engine::init() {
 	_graphics = new Graphics_v1(*_display);
 
-	Common::File f;
-	openFile(f, IDS_HR1_MESSAGES);
+	StreamPtr stream(_files.createReadStream(IDS_HR1_MESSAGES));
 
 	for (uint i = 0; i < IDI_HR1_NUM_MESSAGES; ++i)
-		_messages.push_back(readString(f, APPLECHAR('\r')) + APPLECHAR('\r'));
+		_messages.push_back(readString(*stream, APPLECHAR('\r')) + APPLECHAR('\r'));
 
-	f.close();
-	openFile(f, IDS_HR1_EXE_1);
+	stream.reset(_files.createReadStream(IDS_HR1_EXE_1));
 
 	// Some messages have overrides inside the executable
-	_messages[IDI_HR1_MSG_CANT_GO_THERE - 1] = readStringAt(f, IDI_HR1_OFS_STR_CANT_GO_THERE);
-	_messages[IDI_HR1_MSG_DONT_HAVE_IT - 1] = readStringAt(f, IDI_HR1_OFS_STR_DONT_HAVE_IT);
-	_messages[IDI_HR1_MSG_DONT_UNDERSTAND - 1] = readStringAt(f, IDI_HR1_OFS_STR_DONT_UNDERSTAND);
-	_messages[IDI_HR1_MSG_GETTING_DARK - 1] = readStringAt(f, IDI_HR1_OFS_STR_GETTING_DARK);
+	_messages[IDI_HR1_MSG_CANT_GO_THERE - 1] = readStringAt(*stream, IDI_HR1_OFS_STR_CANT_GO_THERE);
+	_messages[IDI_HR1_MSG_DONT_HAVE_IT - 1] = readStringAt(*stream, IDI_HR1_OFS_STR_DONT_HAVE_IT);
+	_messages[IDI_HR1_MSG_DONT_UNDERSTAND - 1] = readStringAt(*stream, IDI_HR1_OFS_STR_DONT_UNDERSTAND);
+	_messages[IDI_HR1_MSG_GETTING_DARK - 1] = readStringAt(*stream, IDI_HR1_OFS_STR_GETTING_DARK);
 
 	// Load other strings from executable
-	_strings.enterCommand = readStringAt(f, IDI_HR1_OFS_STR_ENTER_COMMAND);
-	_strings.verbError = readStringAt(f, IDI_HR1_OFS_STR_VERB_ERROR);
-	_strings.nounError = readStringAt(f, IDI_HR1_OFS_STR_NOUN_ERROR);
-	_strings.playAgain = readStringAt(f, IDI_HR1_OFS_STR_PLAY_AGAIN);
-	_strings.pressReturn = readStringAt(f, IDI_HR1_OFS_STR_PRESS_RETURN);
+	_strings.enterCommand = readStringAt(*stream, IDI_HR1_OFS_STR_ENTER_COMMAND);
+	_strings.verbError = readStringAt(*stream, IDI_HR1_OFS_STR_VERB_ERROR);
+	_strings.nounError = readStringAt(*stream, IDI_HR1_OFS_STR_NOUN_ERROR);
+	_strings.playAgain = readStringAt(*stream, IDI_HR1_OFS_STR_PLAY_AGAIN);
+	_strings.pressReturn = readStringAt(*stream, IDI_HR1_OFS_STR_PRESS_RETURN);
 
 	// Set message IDs
 	_messageIds.cantGoThere = IDI_HR1_MSG_CANT_GO_THERE;
@@ -166,49 +158,49 @@ void HiRes1Engine::init() {
 	_messageIds.thanksForPlaying = IDI_HR1_MSG_THANKS_FOR_PLAYING;
 
 	// Load picture data from executable
-	f.seek(IDI_HR1_OFS_PICS);
+	stream->seek(IDI_HR1_OFS_PICS);
 	for (uint i = 0; i < IDI_HR1_NUM_PICS; ++i) {
 		struct Picture pic;
-		pic.block = f.readByte();
-		pic.offset = f.readUint16LE();
+		byte block = stream->readByte();
+		Common::String name = Common::String::format("BLOCK%i", block);
+		uint16 offset = stream->readUint16LE();
+		pic.data = _files.getDataBlock(name, offset);
 		_pictures.push_back(pic);
 	}
 
 	// Load commands from executable
-	f.seek(IDI_HR1_OFS_CMDS_1);
-	readCommands(f, _roomCommands);
+	stream->seek(IDI_HR1_OFS_CMDS_1);
+	readCommands(*stream, _roomCommands);
 
-	f.seek(IDI_HR1_OFS_CMDS_0);
-	readCommands(f, _globalCommands);
+	stream->seek(IDI_HR1_OFS_CMDS_0);
+	readCommands(*stream, _globalCommands);
 
 	// Load dropped item offsets
-	f.seek(IDI_HR1_OFS_ITEM_OFFSETS);
+	stream->seek(IDI_HR1_OFS_ITEM_OFFSETS);
 	for (uint i = 0; i < IDI_HR1_NUM_ITEM_OFFSETS; ++i) {
 		Common::Point p;
-		p.x = f.readByte();
-		p.y = f.readByte();
+		p.x = stream->readByte();
+		p.y = stream->readByte();
 		_itemOffsets.push_back(p);
 	}
 
 	// Load right-angle line art
-	f.seek(IDI_HR1_OFS_CORNERS);
-	uint16 cornersCount = f.readUint16LE();
+	stream->seek(IDI_HR1_OFS_CORNERS);
+	uint16 cornersCount = stream->readUint16LE();
 	for (uint i = 0; i < cornersCount; ++i)
-		_corners.push_back(IDI_HR1_OFS_CORNERS + f.readUint16LE());
+		_corners.push_back(_files.getDataBlock(IDS_HR1_EXE_1, IDI_HR1_OFS_CORNERS + stream->readUint16LE()));
 
-	if (f.eos() || f.err())
+	if (stream->eos() || stream->err())
 		error("Failed to read game data from '" IDS_HR1_EXE_1 "'");
 
-	f.seek(IDI_HR1_OFS_VERBS);
-	loadWords(f, _verbs);
+	stream->seek(IDI_HR1_OFS_VERBS);
+	loadWords(*stream, _verbs);
 
-	f.seek(IDI_HR1_OFS_NOUNS);
-	loadWords(f, _nouns);
+	stream->seek(IDI_HR1_OFS_NOUNS);
+	loadWords(*stream, _nouns);
 }
 
 void HiRes1Engine::initState() {
-	Common::File f;
-
 	_state.room = 1;
 	_state.moves = 1;
 	_state.isDark = false;
@@ -216,43 +208,43 @@ void HiRes1Engine::initState() {
 	_state.vars.clear();
 	_state.vars.resize(IDI_HR1_NUM_VARS);
 
-	openFile(f, IDS_HR1_EXE_1);
+	StreamPtr stream(_files.createReadStream(IDS_HR1_EXE_1));
 
 	// Load room data from executable
 	_state.rooms.clear();
 	_roomDesc.clear();
-	f.seek(IDI_HR1_OFS_ROOMS);
+	stream->seek(IDI_HR1_OFS_ROOMS);
 	for (uint i = 0; i < IDI_HR1_NUM_ROOMS; ++i) {
 		Room room;
-		f.readByte();
-		_roomDesc.push_back(f.readByte());
+		stream->readByte();
+		_roomDesc.push_back(stream->readByte());
 		for (uint j = 0; j < 6; ++j)
-			room.connections[j] = f.readByte();
-		room.picture = f.readByte();
-		room.curPicture = f.readByte();
+			room.connections[j] = stream->readByte();
+		room.picture = stream->readByte();
+		room.curPicture = stream->readByte();
 		_state.rooms.push_back(room);
 	}
 
 	// Load item data from executable
 	_state.items.clear();
-	f.seek(IDI_HR1_OFS_ITEMS);
-	while (f.readByte() != 0xff) {
+	stream->seek(IDI_HR1_OFS_ITEMS);
+	while (stream->readByte() != 0xff) {
 		Item item = { };
-		item.noun = f.readByte();
-		item.room = f.readByte();
-		item.picture = f.readByte();
-		item.isLineArt = f.readByte();
-		item.position.x = f.readByte();
-		item.position.y = f.readByte();
-		item.state = f.readByte();
-		item.description = f.readByte();
+		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();
 
-		f.readByte();
+		stream->readByte();
 
-		byte size = f.readByte();
+		byte size = stream->readByte();
 
 		for (uint i = 0; i < size; ++i)
-			item.roomPictures.push_back(f.readByte());
+			item.roomPictures.push_back(stream->readByte());
 
 		_state.items.push_back(item);
 	}
@@ -266,12 +258,7 @@ void HiRes1Engine::restartGame() {
 }
 
 void HiRes1Engine::drawPic(byte pic, Common::Point pos) const {
-	Common::File f;
-	Common::String name = Common::String::format("BLOCK%i", _pictures[pic].block);
-
-	openFile(f, name);
-	f.seek(_pictures[pic].offset);
-	_graphics->drawPic(f, pos, 0x7f);
+	_graphics->drawPic(*_pictures[pic].data->createReadStream(), pos, 0x7f);
 }
 
 void HiRes1Engine::printMessage(uint idx, bool wait) {
@@ -295,10 +282,8 @@ void HiRes1Engine::printMessage(uint idx, bool wait) {
 
 void HiRes1Engine::drawItem(const Item &item, const Common::Point &pos) const {
 	if (item.isLineArt) {
-		Common::File f;
-		openFile(f, IDS_HR1_EXE_1);
-		f.seek(_corners[item.picture - 1]);
-		static_cast<Graphics_v1 *>(_graphics)->drawCorners(f, pos);
+		StreamPtr stream(_corners[item.picture - 1]->createReadStream());
+		static_cast<Graphics_v1 *>(_graphics)->drawCorners(*stream, pos);
 	} else
 		drawPic(item.picture, pos);
 }
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index 9c31a39..985a18c 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -27,6 +27,7 @@
 
 #include "adl/adl.h"
 #include "adl/graphics.h"
+#include "adl/disk.h"
 
 namespace Common {
 class ReadStream;
@@ -103,8 +104,9 @@ private:
 	void drawItem(const Item &item, const Common::Point &pos) const;
 	void showRoom();
 
+	PlainFiles _files;
 	Common::File _exe;
-	Common::Array<uint> _corners;
+	Common::Array<DataBlockPtr> _corners;
 	Common::Array<byte> _roomDesc;
 };
 
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 0d32330..a9a4caa 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -61,8 +61,6 @@ struct RoomData {
 	Commands commands;
 };
 
-typedef Common::ScopedPtr<Common::SeekableReadStream> StreamPtr;
-
 class HiRes2Engine : public AdlEngine_v2 {
 public:
 	HiRes2Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine_v2(syst, gd) { }


Commit: 3b67b07364616548e0fdc9809bdb503ba7faad88
    https://github.com/scummvm/scummvm/commit/3b67b07364616548e0fdc9809bdb503ba7faad88
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Set ADGF_UNSTABLE

Changed paths:
    engines/adl/detection.cpp



diff --git a/engines/adl/detection.cpp b/engines/adl/detection.cpp
index 81050d7..3d29687 100644
--- a/engines/adl/detection.cpp
+++ b/engines/adl/detection.cpp
@@ -88,7 +88,7 @@ static const AdlGameDescription gameDescriptions[] = {
 			},
 			Common::EN_ANY,
 			Common::kPlatformApple2GS, // FIXME
-			ADGF_NO_FLAGS,
+			ADGF_UNSTABLE,
 			GUIO2(GAMEOPTION_COLOR, GAMEOPTION_SCANLINES)
 		},
 		GAME_TYPE_HIRES1
@@ -102,7 +102,7 @@ static const AdlGameDescription gameDescriptions[] = {
 			},
 			Common::EN_ANY,
 			Common::kPlatformApple2GS, // FIXME
-			ADGF_NO_FLAGS,
+			ADGF_UNSTABLE,
 			GUIO2(GAMEOPTION_MONO, GAMEOPTION_SCANLINES)
 		},
 		GAME_TYPE_HIRES2


Commit: 71ca8de7e65d535e97d87bb1d30cbc1d9098cc07
    https://github.com/scummvm/scummvm/commit/71ca8de7e65d535e97d87bb1d30cbc1d9098cc07
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Add support for Apple DOS 3.3 disk images

Changed paths:
    engines/adl/disk.cpp
    engines/adl/disk.h



diff --git a/engines/adl/disk.cpp b/engines/adl/disk.cpp
index e2c3da3..b7de55a 100644
--- a/engines/adl/disk.cpp
+++ b/engines/adl/disk.cpp
@@ -22,6 +22,7 @@
 
 #include "common/stream.h"
 #include "common/substream.h"
+#include "common/memstream.h"
 
 #include "adl/disk.h"
 
@@ -80,12 +81,11 @@ bool DiskImage_DSK::open(const Common::String &filename) {
 		_tracks = 35;
 		_sectorsPerTrack = 16;
 		_bytesPerSector = 256;
-		break;
-	default:
-		warning("Unrecognized disk image '%s' of size %d bytes", filename.c_str(), filesize);
+		return true;
 	}
 
-	return true;
+	warning("Unrecognized disk image '%s' of size %d bytes", filename.c_str(), filesize);
+	return false;
 }
 
 Common::SeekableReadStream *FilesDataBlock::createReadStream() const {
@@ -108,4 +108,183 @@ Common::SeekableReadStream *PlainFiles::createReadStream(const Common::String &f
 		return new Common::SeekableSubReadStream(f, offset, f->size(), DisposeAfterUse::YES);
 }
 
+Files_DOS33::~Files_DOS33() {
+	delete _disk;
+}
+
+Files_DOS33::Files_DOS33() :
+		_disk(nullptr) {
+}
+
+void Files_DOS33::readSectorList(TrackSector start, Common::Array<TrackSector> &list) {
+	TrackSector index = start;
+
+	while (index.track != 0) {
+		Common::ScopedPtr<Common::SeekableReadStream> stream(_disk->createReadStream(index.track, index.sector));
+
+		stream->readByte();
+		index.track = stream->readByte();
+		index.sector = stream->readByte();
+
+		stream->seek(9, SEEK_CUR);
+
+		// This only handles sequential files
+		TrackSector ts;
+		ts.track = stream->readByte();
+		ts.sector = stream->readByte();
+
+		while (ts.track != 0) {
+			list.push_back(ts);
+
+			ts.track = stream->readByte();
+			ts.sector = stream->readByte();
+
+			if (stream->err())
+				error("Error reading sector list");
+
+			if (stream->eos())
+				break;
+		}
+	}
+}
+
+void Files_DOS33::readVTOC() {
+	Common::ScopedPtr<Common::SeekableReadStream> stream(_disk->createReadStream(0x11, 0x00));
+	stream->readByte();
+	byte track = stream->readByte();
+	byte sector = stream->readByte();
+
+	while (track != 0) {
+		char name[kFilenameLen + 1] = { };
+
+		stream.reset(_disk->createReadStream(track, sector));
+		stream->readByte();
+		track = stream->readByte();
+		sector = stream->readByte();
+		stream->seek(8, SEEK_CUR);
+
+		for (uint i = 0; i < 7; ++i) {
+			TOCEntry entry;
+			TrackSector sectorList;
+			sectorList.track = stream->readByte();
+			sectorList.sector = stream->readByte();
+			entry.type = stream->readByte();
+			stream->read(name, kFilenameLen);
+
+			// Convert to ASCII
+			for (uint j = 0; j < kFilenameLen; j++)
+				name[j] &= 0x7f;
+
+			// Strip trailing spaces
+			for (int j = kFilenameLen - 1; j >= 0; --j) {
+				if (name[j] == ' ')
+					name[j] = 0;
+				else
+					break;
+			}
+
+			entry.totalSectors = stream->readUint16BE();
+
+			if (sectorList.track != 0) {
+				readSectorList(sectorList, entry.sectors);
+				_toc[name] = entry;
+			}
+		}
+	}
+}
+
+const DataBlockPtr Files_DOS33::getDataBlock(const Common::String &filename, uint offset) const {
+	return Common::SharedPtr<FilesDataBlock>(new FilesDataBlock(this, filename, offset));
+}
+
+Common::SeekableReadStream *Files_DOS33::createReadStreamText(const TOCEntry &entry) const {
+	byte *buf = (byte *)malloc(entry.sectors.size() * kSectorSize);
+	byte *p = buf;
+
+	for (uint i = 0; i < entry.sectors.size(); ++i) {
+		Common::ScopedPtr<Common::SeekableReadStream> stream(_disk->createReadStream(entry.sectors[i].track, entry.sectors[i].sector));
+
+		assert(stream->size() == kSectorSize);
+
+		while (true) {
+			byte textChar = stream->readByte();
+
+			if (stream->eos() || textChar == 0)
+				break;
+
+			if (stream->err())
+				error("Error reading text file");
+
+			*p++ = textChar;
+		}
+	}
+
+	return new Common::MemoryReadStream(buf, p - buf, DisposeAfterUse::YES);
+}
+
+Common::SeekableReadStream *Files_DOS33::createReadStreamBinary(const TOCEntry &entry) const {
+	byte *buf = (byte *)malloc(entry.sectors.size() * kSectorSize);
+
+	Common::ScopedPtr<Common::SeekableReadStream> stream(_disk->createReadStream(entry.sectors[0].track, entry.sectors[0].sector));
+
+	if (entry.type == kFileTypeBinary)
+		stream->readUint16LE(); // Skip start address
+
+	uint16 size = stream->readUint16LE();
+	uint16 offset = 0;
+	uint16 sectorIdx = 1;
+
+	while (true) {
+		offset += stream->read(buf + offset, size - offset);
+
+		if (offset == size)
+			break;
+
+		if (stream->err())
+			error("Error reading binary file");
+
+		assert(stream->eos());
+
+		if (sectorIdx == entry.sectors.size())
+			error("Not enough sectors for binary file size");
+
+		stream.reset(_disk->createReadStream(entry.sectors[sectorIdx].track, entry.sectors[sectorIdx].sector));
+		++sectorIdx;
+	}
+
+	return new Common::MemoryReadStream(buf, size, DisposeAfterUse::YES);
+}
+
+Common::SeekableReadStream *Files_DOS33::createReadStream(const Common::String &filename, uint offset) const {
+	if (!_toc.contains(filename))
+		error("Failed to locate '%s'", filename.c_str());
+
+	const TOCEntry &entry = _toc[filename];
+
+	Common::SeekableReadStream *stream;
+
+	switch(entry.type) {
+	case kFileTypeText:
+		stream = createReadStreamText(entry);
+		break;
+	case kFileTypeAppleSoft:
+	case kFileTypeBinary:
+		stream = createReadStreamBinary(entry);
+		break;
+	default:
+		error("Unsupported file type %i", entry.type);
+	}
+
+	return new Common::SeekableSubReadStream(stream, offset, stream->size(), DisposeAfterUse::YES);
+}
+
+bool Files_DOS33::open(const Common::String &filename) {
+	_disk = new DiskImage_DSK();
+	if (!_disk->open(filename))
+		return false;
+
+	readVTOC();
+	return true;
+}
+
 } // End of namespace Adl
diff --git a/engines/adl/disk.h b/engines/adl/disk.h
index b6a5c60..799fa37 100644
--- a/engines/adl/disk.h
+++ b/engines/adl/disk.h
@@ -22,6 +22,7 @@
 
 #include "common/ptr.h"
 #include "common/file.h"
+#include "common/debug.h"
 
 #ifndef ADL_DISK_H
 #define ADL_DISK_H
@@ -47,8 +48,8 @@ class Files {
 public:
 	virtual ~Files() { }
 
-	virtual const DataBlockPtr getDataBlock(const Common::String &filename, uint offset) const = 0;
-	virtual Common::SeekableReadStream *createReadStream(const Common::String &filename, uint offset) const = 0;
+	virtual const DataBlockPtr getDataBlock(const Common::String &filename, uint offset = 0) const = 0;
+	virtual Common::SeekableReadStream *createReadStream(const Common::String &filename, uint offset = 0) const = 0;
 };
 
 class FilesDataBlock : public DataBlock {
@@ -103,6 +104,47 @@ public:
 	Common::SeekableReadStream *createReadStream(uint track, uint sector, uint offset = 0, uint size = 0) const;
 };
 
+class Files_DOS33 : public Files {
+public:
+	Files_DOS33();
+	~Files_DOS33();
+
+	bool open(const Common::String &filename);
+	const DataBlockPtr getDataBlock(const Common::String &filename, uint offset = 0) const;
+	Common::SeekableReadStream *createReadStream(const Common::String &filename, uint offset = 0) const;
+
+private:
+	enum FileType {
+		kFileTypeText = 0,
+		kFileTypeAppleSoft = 2,
+		kFileTypeBinary = 4 
+	};
+
+	enum {
+		kSectorSize = 256,
+		kFilenameLen = 30
+	};
+
+	struct TrackSector {
+		byte track;
+		byte sector;
+	};
+
+	struct TOCEntry {
+		byte type;
+		uint16 totalSectors;
+		Common::Array<TrackSector> sectors;
+	};
+
+	void readVTOC();
+	void readSectorList(TrackSector start, Common::Array<TrackSector> &list);
+	Common::SeekableReadStream *createReadStreamText(const TOCEntry &entry) const;
+	Common::SeekableReadStream *createReadStreamBinary(const TOCEntry &entry) const;
+
+	DiskImage_DSK *_disk;
+	Common::HashMap<Common::String, TOCEntry> _toc;
+};
+
 } // End of namespace Adl
 
 #endif


Commit: 02563df42218d103a80e9bc5463cc63909b2f495
    https://github.com/scummvm/scummvm/commit/02563df42218d103a80e9bc5463cc63909b2f495
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Add support for hires1 disk image

Changed paths:
    engines/adl/detection.cpp
    engines/adl/hires1.cpp
    engines/adl/hires1.h



diff --git a/engines/adl/detection.cpp b/engines/adl/detection.cpp
index 3d29687..457db2d 100644
--- a/engines/adl/detection.cpp
+++ b/engines/adl/detection.cpp
@@ -77,7 +77,7 @@ static const PlainGameDescriptor adlGames[] = {
 };
 
 static const AdlGameDescription gameDescriptions[] = {
-	{ // Hi-Res Adventure #1: Mystery House - Apple II - 1987 PD release
+	{ // Hi-Res Adventure #1: Mystery House - Apple II - 1987 PD release - Plain files
 		{
 			"hires1", 0,
 			{
@@ -93,6 +93,20 @@ static const AdlGameDescription gameDescriptions[] = {
 		},
 		GAME_TYPE_HIRES1
 	},
+	{ // Hi-Res Adventure #1: Mystery House - Apple II - 1987 PD release - .DSK format
+		{
+			"hires1", 0,
+			{
+				{ "MYSTHOUS.DSK", 0, "34ba05e62bf51404c4475c349ca48921", 143360 },
+				AD_LISTEND
+			},
+			Common::EN_ANY,
+			Common::kPlatformApple2GS, // FIXME
+			ADGF_UNSTABLE,
+			GUIO2(GAMEOPTION_COLOR, GAMEOPTION_SCANLINES)
+		},
+		GAME_TYPE_HIRES1
+	},
 	{ // Hi-Res Adventure #2: Wizard and the Princess - Apple II - 1986 SierraVenture release
 		{
 			"hires2", 0,
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 109879e..1c46ba6 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -33,7 +33,7 @@
 namespace Adl {
 
 void HiRes1Engine::runIntro() const {
-	StreamPtr stream(_files.createReadStream(IDS_HR1_EXE_0));
+	StreamPtr stream(_files->createReadStream(IDS_HR1_EXE_0));
 
 	stream->seek(IDI_HR1_OFS_LOGO_0);
 	_display->setMode(DISPLAY_MODE_HIRES);
@@ -46,7 +46,7 @@ void HiRes1Engine::runIntro() const {
 
 	_display->setMode(DISPLAY_MODE_TEXT);
 
-	StreamPtr basic(_files.createReadStream(IDS_HR1_LOADER));
+	StreamPtr basic(_files->createReadStream(IDS_HR1_LOADER));
 	Common::String str;
 
 	str = readStringAt(*basic, IDI_HR1_OFS_PD_TEXT_0, '"');
@@ -120,7 +120,7 @@ void HiRes1Engine::runIntro() const {
 	_display->setMode(DISPLAY_MODE_MIXED);
 
 	// Title screen shown during loading
-	stream.reset(_files.createReadStream(IDS_HR1_EXE_1));
+	stream.reset(_files->createReadStream(IDS_HR1_EXE_1));
 	stream->seek(IDI_HR1_OFS_LOGO_1);
 	_display->loadFrameBuffer(*stream);
 	_display->updateHiResScreen();
@@ -128,14 +128,21 @@ void HiRes1Engine::runIntro() const {
 }
 
 void HiRes1Engine::init() {
+	if (Common::File::exists("MYSTHOUS.DSK")) {
+		_files = new Files_DOS33();
+		if (!static_cast<Files_DOS33 *>(_files)->open("MYSTHOUS.DSK"))
+			error("Failed to open MYSTHOUS.DSK");
+	} else
+		_files = new PlainFiles();
+
 	_graphics = new Graphics_v1(*_display);
 
-	StreamPtr stream(_files.createReadStream(IDS_HR1_MESSAGES));
+	StreamPtr stream(_files->createReadStream(IDS_HR1_MESSAGES));
 
 	for (uint i = 0; i < IDI_HR1_NUM_MESSAGES; ++i)
 		_messages.push_back(readString(*stream, APPLECHAR('\r')) + APPLECHAR('\r'));
 
-	stream.reset(_files.createReadStream(IDS_HR1_EXE_1));
+	stream.reset(_files->createReadStream(IDS_HR1_EXE_1));
 
 	// Some messages have overrides inside the executable
 	_messages[IDI_HR1_MSG_CANT_GO_THERE - 1] = readStringAt(*stream, IDI_HR1_OFS_STR_CANT_GO_THERE);
@@ -164,7 +171,7 @@ void HiRes1Engine::init() {
 		byte block = stream->readByte();
 		Common::String name = Common::String::format("BLOCK%i", block);
 		uint16 offset = stream->readUint16LE();
-		pic.data = _files.getDataBlock(name, offset);
+		pic.data = _files->getDataBlock(name, offset);
 		_pictures.push_back(pic);
 	}
 
@@ -188,7 +195,7 @@ void HiRes1Engine::init() {
 	stream->seek(IDI_HR1_OFS_CORNERS);
 	uint16 cornersCount = stream->readUint16LE();
 	for (uint i = 0; i < cornersCount; ++i)
-		_corners.push_back(_files.getDataBlock(IDS_HR1_EXE_1, IDI_HR1_OFS_CORNERS + stream->readUint16LE()));
+		_corners.push_back(_files->getDataBlock(IDS_HR1_EXE_1, IDI_HR1_OFS_CORNERS + stream->readUint16LE()));
 
 	if (stream->eos() || stream->err())
 		error("Failed to read game data from '" IDS_HR1_EXE_1 "'");
@@ -208,7 +215,7 @@ void HiRes1Engine::initState() {
 	_state.vars.clear();
 	_state.vars.resize(IDI_HR1_NUM_VARS);
 
-	StreamPtr stream(_files.createReadStream(IDS_HR1_EXE_1));
+	StreamPtr stream(_files->createReadStream(IDS_HR1_EXE_1));
 
 	// Load room data from executable
 	_state.rooms.clear();
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index 985a18c..cb1730a 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -91,7 +91,8 @@ namespace Adl {
 
 class HiRes1Engine : public AdlEngine {
 public:
-	HiRes1Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine(syst, gd) { }
+	HiRes1Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine(syst, gd), _files(nullptr) { }
+	~HiRes1Engine() { delete _files; }
 
 private:
 	// AdlEngine
@@ -104,7 +105,7 @@ private:
 	void drawItem(const Item &item, const Common::Point &pos) const;
 	void showRoom();
 
-	PlainFiles _files;
+	Files *_files;
 	Common::File _exe;
 	Common::Array<DataBlockPtr> _corners;
 	Common::Array<byte> _roomDesc;


Commit: 7ee183ca481c2729cb703ced3b6a3fa4ad7d73a3
    https://github.com/scummvm/scummvm/commit/7ee183ca481c2729cb703ced3b6a3fa4ad7d73a3
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Refactor disk classes

Changed paths:
    engines/adl/adl.h
    engines/adl/disk.cpp
    engines/adl/disk.h
    engines/adl/hires1.cpp



diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index ba803e8..731b7e3 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -52,8 +52,6 @@ class Speaker;
 struct AdlGameDescription;
 struct ScriptEnv;
 
-typedef Common::ScopedPtr<Common::SeekableReadStream> StreamPtr;
-
 // Save and restore opcodes
 #define IDO_ACT_SAVE           0x0f
 #define IDO_ACT_LOAD           0x10
diff --git a/engines/adl/disk.cpp b/engines/adl/disk.cpp
index b7de55a..22a7d7a 100644
--- a/engines/adl/disk.cpp
+++ b/engines/adl/disk.cpp
@@ -28,35 +28,8 @@
 
 namespace Adl {
 
-DiskImage::DiskImage() :
-		_tracks(0),
-		_sectorsPerTrack(0),
-		_bytesPerSector(0) {
-	_f = new Common::File();
-}
-
-DiskImage::~DiskImage() {
-	delete _f;
-}
-
-DiskImageDataBlock::DiskImageDataBlock(const DiskImage *disk, uint track, uint sector, uint offset, uint size) :
-		_track(track),
-		_sector(sector),
-		_offset(offset),
-		_size(size),
-		_disk(disk) { }
-
-bool DiskImageDataBlock::isValid() const {
-	return _track != 0 || _sector != 0 || _offset != 0 || _size != 0;
-}
-
-Common::SeekableReadStream *DiskImageDataBlock::createReadStream() const {
-	return _disk->createReadStream(_track, _sector, _offset, _size);
-}
-
-// .DSK disk image - 35 tracks, 16 sectors per track, 256 bytes per sector, raw sector layout
 const DataBlockPtr DiskImage_DSK::getDataBlock(uint track, uint sector, uint offset, uint size) const {
-	return Common::SharedPtr<DiskImageDataBlock>(new DiskImageDataBlock(this, track, sector, offset, size));
+	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 {
@@ -81,22 +54,20 @@ bool DiskImage_DSK::open(const Common::String &filename) {
 		_tracks = 35;
 		_sectorsPerTrack = 16;
 		_bytesPerSector = 256;
-		return true;
+		break;
+	default:
+		warning("Unrecognized disk image '%s' of size %d bytes", filename.c_str(), filesize);
+		return false;
 	}
 
-	warning("Unrecognized disk image '%s' of size %d bytes", filename.c_str(), filesize);
-	return false;
-}
-
-Common::SeekableReadStream *FilesDataBlock::createReadStream() const {
-	return _files->createReadStream(_filename, _offset);
+	return true;
 }
 
-const DataBlockPtr PlainFiles::getDataBlock(const Common::String &filename, uint offset) const {
-	return Common::SharedPtr<FilesDataBlock>(new FilesDataBlock(this, filename, offset));
+const DataBlockPtr Files_Plain::getDataBlock(const Common::String &filename, uint offset) const {
+	return Common::SharedPtr<Files::DataBlock>(new Files::DataBlock(this, filename, offset));
 }
 
-Common::SeekableReadStream *PlainFiles::createReadStream(const Common::String &filename, uint offset) const {
+Common::SeekableReadStream *Files_Plain::createReadStream(const Common::String &filename, uint offset) const {
 	Common::File *f(new Common::File());
 
 	if (!f->open(filename))
@@ -194,7 +165,7 @@ void Files_DOS33::readVTOC() {
 }
 
 const DataBlockPtr Files_DOS33::getDataBlock(const Common::String &filename, uint offset) const {
-	return Common::SharedPtr<FilesDataBlock>(new FilesDataBlock(this, filename, offset));
+	return Common::SharedPtr<Files::DataBlock>(new Files::DataBlock(this, filename, offset));
 }
 
 Common::SeekableReadStream *Files_DOS33::createReadStreamText(const TOCEntry &entry) const {
diff --git a/engines/adl/disk.h b/engines/adl/disk.h
index 799fa37..12801ec 100644
--- a/engines/adl/disk.h
+++ b/engines/adl/disk.h
@@ -43,6 +43,7 @@ public:
 };
 
 typedef Common::SharedPtr<DataBlock> DataBlockPtr;
+typedef Common::ScopedPtr<Common::SeekableReadStream> StreamPtr;
 
 class Files {
 public:
@@ -50,60 +51,90 @@ public:
 
 	virtual const DataBlockPtr getDataBlock(const Common::String &filename, uint offset = 0) const = 0;
 	virtual Common::SeekableReadStream *createReadStream(const Common::String &filename, uint offset = 0) const = 0;
-};
-
-class FilesDataBlock : public DataBlock {
-public:
-	FilesDataBlock(const Files *files, const Common::String &filename, uint offset) : _files(files), _filename(filename), _offset(offset) { }
-
-	bool isValid() const { return true; }
-	Common::SeekableReadStream *createReadStream() const;
-
-private:
-	const Common::String _filename;
-	uint _offset;
-	const Files *_files;
-};
 
-class PlainFiles : public Files {
-public:
-	const DataBlockPtr getDataBlock(const Common::String &filename, uint offset = 0) const;
-	Common::SeekableReadStream *createReadStream(const Common::String &filename, uint offset = 0) const;
+protected:
+	class DataBlock : public Adl::DataBlock {
+	public:
+		DataBlock(const Files *files, const Common::String &filename, uint offset) :
+				_files(files),
+				_filename(filename),
+				_offset(offset) { }
+
+		bool isValid() const {
+			return true;
+		}
+
+		Common::SeekableReadStream *createReadStream() const {
+			return _files->createReadStream(_filename, _offset);
+		}
+
+	private:
+		const Common::String _filename;
+		uint _offset;
+		const Files *_files;
+	};
 };
 
 class DiskImage {
 public:
-	DiskImage();
-	virtual ~DiskImage();
+	DiskImage() :
+			_tracks(0),
+			_sectorsPerTrack(0),
+			_bytesPerSector(0) {
+		_f = new Common::File();
+	}
+
+	virtual ~DiskImage() {
+		delete _f;
+	}
 
 	virtual bool open(const Common::String &filename) = 0;
-	virtual const DataBlockPtr getDataBlock(uint track, uint sector, uint offset, uint size) const = 0;
-	virtual Common::SeekableReadStream *createReadStream(uint track, uint sector, uint offset, uint size) const = 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;
 
 protected:
+	class DataBlock : public Adl::DataBlock {
+	public:
+		DataBlock(const DiskImage *disk, uint track, uint sector, uint offset, uint size) :
+				_track(track),
+				_sector(sector),
+				_offset(offset),
+				_size(size),
+				_disk(disk) { }
+
+		bool isValid() const {
+			return _track != 0 || _sector != 0 || _offset != 0 || _size != 0;
+		}
+
+		Common::SeekableReadStream *createReadStream() const {
+			return _disk->createReadStream(_track, _sector, _offset, _size);
+		}
+
+	private:
+		uint _track, _sector, _offset, _size;
+		const DiskImage *_disk;
+	};
+
 	Common::File *_f;
 	uint _tracks, _sectorsPerTrack, _bytesPerSector;
 };
 
-class DiskImageDataBlock : public DataBlock {
+// Data in plain files
+class Files_Plain : public Files {
 public:
-	DiskImageDataBlock(const DiskImage *disk, uint track, uint sector, uint offset, uint size);
-
-	bool isValid() const;
-	Common::SeekableReadStream *createReadStream() const;
-
-private:
-	uint _track, _sector, _offset, _size;
-	const DiskImage *_disk;
+	const DataBlockPtr getDataBlock(const Common::String &filename, uint offset = 0) const;
+	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, uint size) const;
+	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;
 };
 
+// Data in files contained in Apple DOS 3.3 disk image
 class Files_DOS33 : public Files {
 public:
 	Files_DOS33();
@@ -141,7 +172,7 @@ private:
 	Common::SeekableReadStream *createReadStreamText(const TOCEntry &entry) const;
 	Common::SeekableReadStream *createReadStreamBinary(const TOCEntry &entry) const;
 
-	DiskImage_DSK *_disk;
+	DiskImage *_disk;
 	Common::HashMap<Common::String, TOCEntry> _toc;
 };
 
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 1c46ba6..8590e84 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -133,7 +133,7 @@ void HiRes1Engine::init() {
 		if (!static_cast<Files_DOS33 *>(_files)->open("MYSTHOUS.DSK"))
 			error("Failed to open MYSTHOUS.DSK");
 	} else
-		_files = new PlainFiles();
+		_files = new Files_Plain();
 
 	_graphics = new Graphics_v1(*_display);
 


Commit: 865bd06845e47897e50b79206cf54439dfef3f04
    https://github.com/scummvm/scummvm/commit/865bd06845e47897e50b79206cf54439dfef3f04
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Move room-local commands into base class

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/hires2.cpp
    engines/adl/hires2.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index d95cfd5..90606f7 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -274,6 +274,11 @@ void AdlEngine::readCommands(Common::ReadStream &stream, Commands &commands) {
 }
 
 void AdlEngine::checkInput(byte verb, byte noun) {
+	// Try room-local command list first
+	if (doOneCommand(_roomData.commands, verb, noun))
+		return;
+
+	// If no match was found, try the global list
 	if (!doOneCommand(_roomCommands, verb, noun))
 		printMessage(_messageIds.dontUnderstand);
 }
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 731b7e3..d21bd7b 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -164,6 +164,17 @@ struct State {
 typedef Common::List<Command> Commands;
 typedef Common::HashMap<Common::String, uint> WordMap;
 
+struct Picture2 {
+	byte nr;
+	DataBlockPtr data;
+};
+
+struct RoomData {
+	Common::String description;
+	Common::Array<Picture2> pictures;
+	Commands commands;
+};
+
 class AdlEngine : public Engine {
 public:
 	virtual ~AdlEngine();
@@ -189,7 +200,7 @@ protected:
 
 	void loadWords(Common::ReadStream &stream, WordMap &map) const;
 	void readCommands(Common::ReadStream &stream, Commands &commands);
-	virtual void checkInput(byte verb, byte noun);
+	void checkInput(byte verb, byte noun);
 
 	virtual void setupOpcodeTables();
 	virtual bool matchesCurrentPic(byte pic) const;
@@ -266,6 +277,8 @@ protected:
 	// <room, verb, noun, script> lists
 	Commands _roomCommands;
 	Commands _globalCommands;
+	// Data related to the current room
+	RoomData _roomData;
 
 	WordMap _verbs;
 	WordMap _nouns;
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 5e3da00..3543c92 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -243,13 +243,6 @@ void HiRes2Engine::printMessage(uint idx, bool wait) {
 	printString(_messages[idx - 1]);
 }
 
-void HiRes2Engine::checkInput(byte verb, byte noun) {
-	if (doOneCommand(_roomData.commands, verb, noun))
-		return;
-
-	AdlEngine::checkInput(verb, noun);
-}
-
 Engine *HiRes2Engine_create(OSystem *syst, const AdlGameDescription *gd) {
 	return new HiRes2Engine(syst, gd);
 }
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index a9a4caa..0281a79 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -50,17 +50,6 @@ namespace Adl {
 #define IDI_HR2_MSG_ITEM_NOT_HERE        4
 #define IDI_HR2_MSG_THANKS_FOR_PLAYING 239
 
-struct Picture2 {
-	byte nr;
-	DataBlockPtr data;
-};
-
-struct RoomData {
-	Common::String description;
-	Common::Array<Picture2> pictures;
-	Commands commands;
-};
-
 class HiRes2Engine : public AdlEngine_v2 {
 public:
 	HiRes2Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine_v2(syst, gd) { }
@@ -75,14 +64,12 @@ private:
 	void drawItem(const Item &item, const Common::Point &pos) const;
 	void showRoom();
 	void printMessage(uint idx, bool wait);
-	void checkInput(byte verb, byte noun);
 
 	void loadRoom(byte roomNr);
 	DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const;
 	void readPictureMeta(Common::ReadStream &f, Picture2 &pic) const;
 
 	DiskImage_DSK _disk;
-	RoomData _roomData;
 	Common::Array<Picture2> _itemPics;
 };
 


Commit: c9824921b4a5b2fa91751b03c24db91acbaac8c5
    https://github.com/scummvm/scummvm/commit/c9824921b4a5b2fa91751b03c24db91acbaac8c5
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Move message delay code into hires1 class

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/hires1.cpp
    engines/adl/hires1.h
    engines/adl/hires2.cpp
    engines/adl/hires2.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 90606f7..ce6ca03 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -110,15 +110,6 @@ void AdlEngine::openFile(Common::File &file, const Common::String &name) const {
 		error("Error opening '%s'", name.c_str());
 }
 
-void AdlEngine::printMessage(uint idx, bool wait) {
-	Common::String msg = _messages[idx - 1];
-	wordWrap(msg);
-	_display->printString(msg);
-
-	if (wait)
-		delay(14 * 166018 / 1000);
-}
-
 void AdlEngine::delay(uint32 ms) const {
 	uint32 start = g_system->getMillis();
 
@@ -746,21 +737,6 @@ bool AdlEngine::canSaveGameStateCurrently() {
 	return false;
 }
 
-void AdlEngine::wordWrap(Common::String &str) const {
-	uint end = 39;
-
-	while (1) {
-		if (str.size() <= end)
-			return;
-
-		while (str[end] != APPLECHAR(' '))
-			--end;
-
-		str.setChar(APPLECHAR('\r'), end);
-		end += 40;
-	}
-}
-
 byte AdlEngine::convertKey(uint16 ascii) const {
 	ascii = toupper(ascii);
 
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index d21bd7b..9121de4 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -192,7 +192,7 @@ protected:
 	Common::String readStringAt(Common::SeekableReadStream &stream, uint offset, byte until = 0) const;
 	void openFile(Common::File &file, const Common::String &name) const;
 
-	virtual void printMessage(uint idx, bool wait = true);
+	virtual void printMessage(uint idx) = 0;
 	void delay(uint32 ms) const;
 
 	Common::String inputString(byte prompt = 0) const;
@@ -318,9 +318,6 @@ private:
 	bool canLoadGameStateCurrently();
 	bool canSaveGameStateCurrently();
 
-	// Text output
-	void wordWrap(Common::String &str) const;
-
 	// Text input
 	byte convertKey(uint16 ascii) const;
 	Common::String getLine() const;
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 8590e84..804b122 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -268,7 +268,11 @@ void HiRes1Engine::drawPic(byte pic, Common::Point pos) const {
 	_graphics->drawPic(*_pictures[pic].data->createReadStream(), pos, 0x7f);
 }
 
-void HiRes1Engine::printMessage(uint idx, bool wait) {
+void HiRes1Engine::printMessage(uint idx) {
+	Common::String msg = _messages[idx - 1];
+	wordWrap(msg);
+	_display->printString(msg);
+
 	// Messages with hardcoded overrides don't delay after printing.
 	// It's unclear if this is a bug or not. In some cases the result
 	// is that these strings will scroll past the four-line text window
@@ -281,10 +285,11 @@ void HiRes1Engine::printMessage(uint idx, bool wait) {
 	case IDI_HR1_MSG_DONT_HAVE_IT:
 	case IDI_HR1_MSG_DONT_UNDERSTAND:
 	case IDI_HR1_MSG_GETTING_DARK:
-		wait = false;
+		return;
 	}
 
-	AdlEngine::printMessage(idx, wait);
+	if (_messageDelay)
+		delay(14 * 166018 / 1000);
 }
 
 void HiRes1Engine::drawItem(const Item &item, const Common::Point &pos) const {
@@ -302,7 +307,24 @@ void HiRes1Engine::showRoom() {
 	}
 
 	_display->updateHiResScreen();
-	printMessage(_roomDesc[_state.room - 1], false);
+	_messageDelay = false;
+	printMessage(_roomDesc[_state.room - 1]);
+	_messageDelay = true;
+}
+
+void HiRes1Engine::wordWrap(Common::String &str) const {
+	uint end = 39;
+
+	while (1) {
+		if (str.size() <= end)
+			return;
+
+		while (str[end] != APPLECHAR(' '))
+			--end;
+
+		str.setChar(APPLECHAR('\r'), end);
+		end += 40;
+	}
 }
 
 Engine *HiRes1Engine_create(OSystem *syst, const AdlGameDescription *gd) {
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index cb1730a..458b2f0 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -91,7 +91,10 @@ namespace Adl {
 
 class HiRes1Engine : public AdlEngine {
 public:
-	HiRes1Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine(syst, gd), _files(nullptr) { }
+	HiRes1Engine(OSystem *syst, const AdlGameDescription *gd) :
+			AdlEngine(syst, gd),
+			_files(nullptr),
+			_messageDelay(true) { }
 	~HiRes1Engine() { delete _files; }
 
 private:
@@ -101,14 +104,17 @@ private:
 	void initState();
 	void restartGame();
 	void drawPic(byte pic, Common::Point pos = Common::Point()) const;
-	void printMessage(uint idx, bool wait = true);
+	void printMessage(uint idx);
 	void drawItem(const Item &item, const Common::Point &pos) const;
 	void showRoom();
 
+	void wordWrap(Common::String &str) const;
+
 	Files *_files;
 	Common::File _exe;
 	Common::Array<DataBlockPtr> _corners;
 	Common::Array<byte> _roomDesc;
+	bool _messageDelay;
 };
 
 } // End of namespace Adl
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 3543c92..dffbd81 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -239,7 +239,7 @@ void HiRes2Engine::showRoom() {
 	_linesPrinted = 0;
 }
 
-void HiRes2Engine::printMessage(uint idx, bool wait) {
+void HiRes2Engine::printMessage(uint idx) {
 	printString(_messages[idx - 1]);
 }
 
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 0281a79..35d5e1e 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -63,7 +63,7 @@ private:
 	void drawPic(byte pic, Common::Point pos) const;
 	void drawItem(const Item &item, const Common::Point &pos) const;
 	void showRoom();
-	void printMessage(uint idx, bool wait);
+	void printMessage(uint idx);
 
 	void loadRoom(byte roomNr);
 	DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const;


Commit: 41e82276379f87c74675cc34b682bc69bced865e
    https://github.com/scummvm/scummvm/commit/41e82276379f87c74675cc34b682bc69bced865e
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Set room description in hires1

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/adl_v2.h
    engines/adl/hires1.cpp
    engines/adl/hires1.h
    engines/adl/hires2.cpp
    engines/adl/hires2.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index ce6ca03..e777559 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -110,6 +110,10 @@ void AdlEngine::openFile(Common::File &file, const Common::String &name) const {
 		error("Error opening '%s'", name.c_str());
 }
 
+void AdlEngine::printMessage(uint idx) {
+	printString(_messages[idx - 1]);
+}
+
 void AdlEngine::delay(uint32 ms) const {
 	uint32 start = g_system->getMillis();
 
@@ -513,6 +517,8 @@ Common::Error AdlEngine::run() {
 		// (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 9121de4..ffa3579 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -192,7 +192,8 @@ protected:
 	Common::String readStringAt(Common::SeekableReadStream &stream, uint offset, byte until = 0) const;
 	void openFile(Common::File &file, const Common::String &name) const;
 
-	virtual void printMessage(uint idx) = 0;
+	virtual void printString(const Common::String &str) = 0;
+	virtual void printMessage(uint idx);
 	void delay(uint32 ms) const;
 
 	Common::String inputString(byte prompt = 0) const;
@@ -310,6 +311,7 @@ private:
 	virtual void initState() = 0;
 	virtual void restartGame() = 0;
 	virtual void drawItem(const Item &item, const Common::Point &pos) const = 0;
+	virtual void loadRoom(byte roomNr) = 0;
 	virtual void showRoom() = 0;
 
 	// Engine
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index cea4a93..3a32f48 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -49,9 +49,9 @@ protected:
 	bool matchesCurrentPic(byte pic) const;
 	byte roomArg(byte room) const;
 	void advanceClock();
+	void printString(const Common::String &str);
 
 	void checkTextOverflow(char c);
-	void printString(const Common::String &str);
 
 	int o2_isFirstTime(ScriptEnv &e);
 	int o2_isRandomGT(ScriptEnv &e);
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 804b122..b191afd 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -268,10 +268,17 @@ void HiRes1Engine::drawPic(byte pic, Common::Point pos) const {
 	_graphics->drawPic(*_pictures[pic].data->createReadStream(), pos, 0x7f);
 }
 
+void HiRes1Engine::printString(const Common::String &str) {
+	Common::String wrap = str;
+	wordWrap(wrap);
+	_display->printString(wrap);
+
+	if (_messageDelay)
+		delay(14 * 166018 / 1000);
+}
+
 void HiRes1Engine::printMessage(uint idx) {
-	Common::String msg = _messages[idx - 1];
-	wordWrap(msg);
-	_display->printString(msg);
+	const Common::String &msg = _messages[idx - 1];
 
 	// Messages with hardcoded overrides don't delay after printing.
 	// It's unclear if this is a bug or not. In some cases the result
@@ -285,11 +292,11 @@ void HiRes1Engine::printMessage(uint idx) {
 	case IDI_HR1_MSG_DONT_HAVE_IT:
 	case IDI_HR1_MSG_DONT_UNDERSTAND:
 	case IDI_HR1_MSG_GETTING_DARK:
+		_display->printString(msg);
 		return;
 	}
 
-	if (_messageDelay)
-		delay(14 * 166018 / 1000);
+	printString(msg);
 }
 
 void HiRes1Engine::drawItem(const Item &item, const Common::Point &pos) const {
@@ -300,6 +307,10 @@ void HiRes1Engine::drawItem(const Item &item, const Common::Point &pos) const {
 		drawPic(item.picture, pos);
 }
 
+void HiRes1Engine::loadRoom(byte roomNr) {
+	_roomData.description = _messages[_roomDesc[_state.room - 1] - 1];
+}
+
 void HiRes1Engine::showRoom() {
 	if (!_state.isDark) {
 		drawPic(getCurRoom().curPicture);
@@ -308,7 +319,7 @@ void HiRes1Engine::showRoom() {
 
 	_display->updateHiResScreen();
 	_messageDelay = false;
-	printMessage(_roomDesc[_state.room - 1]);
+	printString(_roomData.description);
 	_messageDelay = true;
 }
 
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index 458b2f0..d601f7d 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -104,8 +104,10 @@ private:
 	void initState();
 	void restartGame();
 	void drawPic(byte pic, Common::Point pos = Common::Point()) const;
+	void printString(const Common::String &str);
 	void printMessage(uint idx);
 	void drawItem(const Item &item, const Common::Point &pos) const;
+	void loadRoom(byte roomNr);
 	void showRoom();
 
 	void wordWrap(Common::String &str) const;
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index dffbd81..39f2199 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -182,29 +182,6 @@ void HiRes2Engine::initState() {
 	}
 }
 
-void HiRes2Engine::loadRoom(byte roomNr) {
-	Room &room = getRoom(roomNr);
-	StreamPtr stream(room.data->createReadStream());
-
-	uint16 descOffset = stream->readUint16LE();
-	uint16 commandOffset = stream->readUint16LE();
-
-	// There's no picture count. The original engine always checks at most
-	// five pictures. We use the description offset to bound our search.
-	uint16 picCount = (descOffset - 4) / 5;
-
-	for (uint i = 0; i < picCount; ++i) {
-		Picture2 pic;
-		readPictureMeta(*stream, pic);
-		_roomData.pictures.push_back(pic);
-	}
-
-	_roomData.description = readStringAt(*stream, descOffset, 0xff);
-
-	stream->seek(commandOffset);
-	readCommands(*stream, _roomData.commands);
-}
-
 void HiRes2Engine::restartGame() {
 	initState();
 }
@@ -230,8 +207,30 @@ void HiRes2Engine::drawItem(const Item &item, const Common::Point &pos) const {
 	_graphics->drawPic(*stream, pos, 0);
 }
 
+void HiRes2Engine::loadRoom(byte roomNr) {
+	Room &room = getRoom(roomNr);
+	StreamPtr stream(room.data->createReadStream());
+
+	uint16 descOffset = stream->readUint16LE();
+	uint16 commandOffset = stream->readUint16LE();
+
+	// There's no picture count. The original engine always checks at most
+	// five pictures. We use the description offset to bound our search.
+	uint16 picCount = (descOffset - 4) / 5;
+
+	for (uint i = 0; i < picCount; ++i) {
+		Picture2 pic;
+		readPictureMeta(*stream, pic);
+		_roomData.pictures.push_back(pic);
+	}
+
+	_roomData.description = readStringAt(*stream, descOffset, 0xff);
+
+	stream->seek(commandOffset);
+	readCommands(*stream, _roomData.commands);
+}
+
 void HiRes2Engine::showRoom() {
-	loadRoom(_state.room);
 	drawPic(getCurRoom().curPicture, Common::Point());
 	drawItems();
 	_display->updateHiResScreen();
@@ -239,10 +238,6 @@ void HiRes2Engine::showRoom() {
 	_linesPrinted = 0;
 }
 
-void HiRes2Engine::printMessage(uint idx) {
-	printString(_messages[idx - 1]);
-}
-
 Engine *HiRes2Engine_create(OSystem *syst, const AdlGameDescription *gd) {
 	return new HiRes2Engine(syst, gd);
 }
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 35d5e1e..a4bc0b6 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -62,10 +62,9 @@ private:
 	void restartGame();
 	void drawPic(byte pic, Common::Point pos) const;
 	void drawItem(const Item &item, const Common::Point &pos) const;
+	void loadRoom(byte roomNr);
 	void showRoom();
-	void printMessage(uint idx);
 
-	void loadRoom(byte roomNr);
 	DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const;
 	void readPictureMeta(Common::ReadStream &f, Picture2 &pic) const;
 


Commit: aa661fae5c3a6be2d09a0a6632770131ff02c550
    https://github.com/scummvm/scummvm/commit/aa661fae5c3a6be2d09a0a6632770131ff02c550
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Fix room loading in hires2

Changed paths:
    engines/adl/hires2.cpp



diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 39f2199..d4f1c09 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -214,6 +214,7 @@ void HiRes2Engine::loadRoom(byte roomNr) {
 	uint16 descOffset = stream->readUint16LE();
 	uint16 commandOffset = stream->readUint16LE();
 
+	_roomData.pictures.clear();
 	// There's no picture count. The original engine always checks at most
 	// five pictures. We use the description offset to bound our search.
 	uint16 picCount = (descOffset - 4) / 5;
@@ -226,8 +227,11 @@ void HiRes2Engine::loadRoom(byte roomNr) {
 
 	_roomData.description = readStringAt(*stream, descOffset, 0xff);
 
-	stream->seek(commandOffset);
-	readCommands(*stream, _roomData.commands);
+	_roomData.commands.clear();
+	if (commandOffset != 0) {
+		stream->seek(commandOffset);
+		readCommands(*stream, _roomData.commands);
+	}
 }
 
 void HiRes2Engine::showRoom() {


Commit: bd588d96155d2b8626d8f760d4bb41fba60efc8e
    https://github.com/scummvm/scummvm/commit/bd588d96155d2b8626d8f760d4bb41fba60efc8e
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Use HashMaps for room/global pics

Changed paths:
    engines/adl/adl.h
    engines/adl/hires1.cpp
    engines/adl/hires1.h
    engines/adl/hires2.cpp
    engines/adl/hires2.h



diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index ffa3579..d8ee5d9 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -86,9 +86,7 @@ struct Room {
 	bool isFirstTime;
 };
 
-struct Picture {
-	DataBlockPtr data;
-};
+typedef Common::HashMap<byte, DataBlockPtr> PictureMap;
 
 typedef Common::Array<byte> Script;
 
@@ -164,14 +162,9 @@ struct State {
 typedef Common::List<Command> Commands;
 typedef Common::HashMap<Common::String, uint> WordMap;
 
-struct Picture2 {
-	byte nr;
-	DataBlockPtr data;
-};
-
 struct RoomData {
 	Common::String description;
-	Common::Array<Picture2> pictures;
+	PictureMap pictures;
 	Commands commands;
 };
 
@@ -272,7 +265,7 @@ protected:
 	// Message strings in data file
 	Common::Array<Common::String> _messages;
 	// Picture data
-	Common::Array<Picture> _pictures;
+	PictureMap _pictures;
 	// Dropped item screen offsets
 	Common::Array<Common::Point> _itemOffsets;
 	// <room, verb, noun, script> lists
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index b191afd..4161bfe 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -166,13 +166,11 @@ void HiRes1Engine::init() {
 
 	// Load picture data from executable
 	stream->seek(IDI_HR1_OFS_PICS);
-	for (uint i = 0; i < IDI_HR1_NUM_PICS; ++i) {
-		struct Picture pic;
+	for (uint i = 1; i <= IDI_HR1_NUM_PICS; ++i) {
 		byte block = stream->readByte();
 		Common::String name = Common::String::format("BLOCK%i", block);
 		uint16 offset = stream->readUint16LE();
-		pic.data = _files->getDataBlock(name, offset);
-		_pictures.push_back(pic);
+		_pictures[i] = _files->getDataBlock(name, offset);
 	}
 
 	// Load commands from executable
@@ -265,7 +263,7 @@ void HiRes1Engine::restartGame() {
 }
 
 void HiRes1Engine::drawPic(byte pic, Common::Point pos) const {
-	_graphics->drawPic(*_pictures[pic].data->createReadStream(), pos, 0x7f);
+	_graphics->drawPic(*_pictures[pic]->createReadStream(), pos, 0x7f);
 }
 
 void HiRes1Engine::printString(const Common::String &str) {
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index d601f7d..29cdd5a 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -42,7 +42,7 @@ namespace Adl {
 #define IDS_HR1_MESSAGES "MESSAGES"
 
 #define IDI_HR1_NUM_ROOMS         41
-#define IDI_HR1_NUM_PICS          98
+#define IDI_HR1_NUM_PICS          97
 #define IDI_HR1_NUM_VARS          20
 #define IDI_HR1_NUM_ITEM_OFFSETS  21
 #define IDI_HR1_NUM_MESSAGES     167
@@ -79,7 +79,7 @@ namespace Adl {
 
 #define IDI_HR1_OFS_ITEMS        0x0100
 #define IDI_HR1_OFS_ROOMS        0x050a
-#define IDI_HR1_OFS_PICS         0x4b00
+#define IDI_HR1_OFS_PICS         0x4b03
 #define IDI_HR1_OFS_CMDS_0       0x3c00
 #define IDI_HR1_OFS_CMDS_1       0x3d00
 
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index d4f1c09..f6818a6 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -41,11 +41,6 @@ DataBlockPtr HiRes2Engine::readDataBlockPtr(Common::ReadStream &f) const {
 	return _disk.getDataBlock(track, sector, offset, size);
 }
 
-void HiRes2Engine::readPictureMeta(Common::ReadStream &f, Picture2 &pic) const {
-	pic.nr = f.readByte();
-	pic.data = readDataBlockPtr(f);
-}
-
 void HiRes2Engine::runIntro() const {
 	StreamPtr stream(_disk.createReadStream(0x00, 0xd, 0x17, 1));
 
@@ -105,9 +100,8 @@ void HiRes2Engine::init() {
 	// Load item picture data
 	stream.reset(_disk.createReadStream(0x1e, 0x9, 0x05));
 	for (uint i = 0; i < IDI_HR2_NUM_ITEM_PICS; ++i) {
-		Picture2 pic;
-		readPictureMeta(*stream, pic);
-		_itemPics.push_back(pic);
+		stream->readByte(); // number
+		_itemPics.push_back(readDataBlockPtr(*stream));
 	}
 
 	// Load commands from executable
@@ -187,22 +181,14 @@ void HiRes2Engine::restartGame() {
 }
 
 void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
-	Common::Array<Picture2>::const_iterator roomPic;
-
-	for (roomPic = _roomData.pictures.begin(); roomPic != _roomData.pictures.end(); ++roomPic) {
-		if (roomPic->nr == pic) {
-			StreamPtr stream(roomPic->data->createReadStream());
-			_graphics->drawPic(*stream, pos, 0);
-			return;
-		}
-	}
-
-	// Check global pic list here
+	if (_roomData.pictures.contains(pic))
+		_graphics->drawPic(*_roomData.pictures[pic]->createReadStream(), pos, 0);
+	else
+		_graphics->drawPic(*_pictures[pic]->createReadStream(), pos, 0);
 }
 
 void HiRes2Engine::drawItem(const Item &item, const Common::Point &pos) const {
-	const Picture2 &pic = _itemPics[item.picture - 1];
-	StreamPtr stream(pic.data->createReadStream());
+	StreamPtr stream(_itemPics[item.picture - 1]->createReadStream());
 	stream->readByte(); // Skip clear opcode
 	_graphics->drawPic(*stream, pos, 0);
 }
@@ -220,9 +206,8 @@ void HiRes2Engine::loadRoom(byte roomNr) {
 	uint16 picCount = (descOffset - 4) / 5;
 
 	for (uint i = 0; i < picCount; ++i) {
-		Picture2 pic;
-		readPictureMeta(*stream, pic);
-		_roomData.pictures.push_back(pic);
+		byte nr = stream->readByte();
+		_roomData.pictures[nr] = readDataBlockPtr(*stream);
 	}
 
 	_roomData.description = readStringAt(*stream, descOffset, 0xff);
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index a4bc0b6..17687b5 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -66,10 +66,9 @@ private:
 	void showRoom();
 
 	DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const;
-	void readPictureMeta(Common::ReadStream &f, Picture2 &pic) const;
 
 	DiskImage_DSK _disk;
-	Common::Array<Picture2> _itemPics;
+	Common::Array<DataBlockPtr> _itemPics;
 };
 
 } // End of namespace Adl


Commit: 42c41b449587f388796fe6a95a1a68027da629f9
    https://github.com/scummvm/scummvm/commit/42c41b449587f388796fe6a95a1a68027da629f9
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Load hires2 global pics

Changed paths:
    engines/adl/hires2.cpp



diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index f6818a6..1e06135 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -38,6 +38,10 @@ DataBlockPtr HiRes2Engine::readDataBlockPtr(Common::ReadStream &f) const {
 	byte sector = f.readByte();
 	byte offset = f.readByte();
 	byte size = f.readByte();
+
+	if (f.eos() || f.err())
+		error("Error reading DataBlockPtr");
+
 	return _disk.getDataBlock(track, sector, offset, size);
 }
 
@@ -97,6 +101,16 @@ void HiRes2Engine::init() {
 	_messageIds.itemNotHere = IDI_HR2_MSG_ITEM_NOT_HERE;
 	_messageIds.thanksForPlaying = IDI_HR2_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_HR2_NUM_ITEM_PICS; ++i) {


Commit: 53e7ecb79c8926481bf916b16af6b6e0a88f7b7b
    https://github.com/scummvm/scummvm/commit/53e7ecb79c8926481bf916b16af6b6e0a88f7b7b
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Remove unused DrawPic color parameter

Changed paths:
    engines/adl/graphics.h
    engines/adl/graphics_v1.cpp
    engines/adl/graphics_v2.cpp
    engines/adl/hires1.cpp
    engines/adl/hires2.cpp



diff --git a/engines/adl/graphics.h b/engines/adl/graphics.h
index 95f4159..b422959 100644
--- a/engines/adl/graphics.h
+++ b/engines/adl/graphics.h
@@ -35,7 +35,7 @@ class Display;
 class GraphicsMan {
 public:
 	virtual ~GraphicsMan() { }
-	virtual void drawPic(Common::SeekableReadStream &pic, const Common::Point &pos, byte color) = 0;
+	virtual void drawPic(Common::SeekableReadStream &pic, const Common::Point &pos) = 0;
 
 protected:
 	GraphicsMan(Display &display) : _display(display) { }
@@ -47,7 +47,7 @@ protected:
 class Graphics_v1 : public GraphicsMan {
 public:
 	Graphics_v1(Display &display) : GraphicsMan(display) { }
-	void drawPic(Common::SeekableReadStream &pic, const Common::Point &pos, byte color);
+	void drawPic(Common::SeekableReadStream &pic, const Common::Point &pos);
 	void drawCorners(Common::ReadStream &corners, const Common::Point &pos, byte rotation = 0, byte scaling = 1, byte color = 0x7f) const;
 
 private:
@@ -57,7 +57,7 @@ private:
 class Graphics_v2 : public GraphicsMan {
 public:
 	Graphics_v2(Display &display) : GraphicsMan(display), _color(0) { }
-	void drawPic(Common::SeekableReadStream &pic, const Common::Point &pos, byte color);
+	void drawPic(Common::SeekableReadStream &pic, const Common::Point &pos);
 
 private:
 	void clear();
diff --git a/engines/adl/graphics_v1.cpp b/engines/adl/graphics_v1.cpp
index edf16b8..29c5ef4 100644
--- a/engines/adl/graphics_v1.cpp
+++ b/engines/adl/graphics_v1.cpp
@@ -29,7 +29,7 @@
 
 namespace Adl {
 
-void Graphics_v1::drawPic(Common::SeekableReadStream &pic, const Common::Point &pos, byte color) {
+void Graphics_v1::drawPic(Common::SeekableReadStream &pic, const Common::Point &pos) {
 	byte x, y;
 	bool bNewLine = false;
 	byte oldX = 0, oldY = 0;
diff --git a/engines/adl/graphics_v2.cpp b/engines/adl/graphics_v2.cpp
index 7da4eed..40936f5 100644
--- a/engines/adl/graphics_v2.cpp
+++ b/engines/adl/graphics_v2.cpp
@@ -240,8 +240,8 @@ void Graphics_v2::fill(Common::SeekableReadStream &pic) {
 	}
 }
 
-void Graphics_v2::drawPic(Common::SeekableReadStream &pic, const Common::Point &pos, byte color) {
-	_color = color;
+void Graphics_v2::drawPic(Common::SeekableReadStream &pic, const Common::Point &pos) {
+	_color = 0;
 	_offset = pos;
 
 	while (true) {
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 4161bfe..c1a43b8 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -263,7 +263,7 @@ void HiRes1Engine::restartGame() {
 }
 
 void HiRes1Engine::drawPic(byte pic, Common::Point pos) const {
-	_graphics->drawPic(*_pictures[pic]->createReadStream(), pos, 0x7f);
+	_graphics->drawPic(*_pictures[pic]->createReadStream(), pos);
 }
 
 void HiRes1Engine::printString(const Common::String &str) {
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 1e06135..c33857a 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -196,15 +196,15 @@ void HiRes2Engine::restartGame() {
 
 void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
 	if (_roomData.pictures.contains(pic))
-		_graphics->drawPic(*_roomData.pictures[pic]->createReadStream(), pos, 0);
+		_graphics->drawPic(*_roomData.pictures[pic]->createReadStream(), pos);
 	else
-		_graphics->drawPic(*_pictures[pic]->createReadStream(), pos, 0);
+		_graphics->drawPic(*_pictures[pic]->createReadStream(), pos);
 }
 
 void HiRes2Engine::drawItem(const Item &item, const Common::Point &pos) const {
 	StreamPtr stream(_itemPics[item.picture - 1]->createReadStream());
 	stream->readByte(); // Skip clear opcode
-	_graphics->drawPic(*stream, pos, 0);
+	_graphics->drawPic(*stream, pos);
 }
 
 void HiRes2Engine::loadRoom(byte roomNr) {


Commit: d0f33851bc7d6256aed051eb5a3287d24969f681
    https://github.com/scummvm/scummvm/commit/d0f33851bc7d6256aed051eb5a3287d24969f681
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Fix regression in message loading

Changed paths:
    engines/adl/hires2.cpp



diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index c33857a..30114d6 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -73,6 +73,8 @@ void HiRes2Engine::init() {
 		if (str->isValid()) {
 			StreamPtr strStream(str->createReadStream());
 			_messages.push_back(readString(*strStream, 0xff));
+		} else {
+			_messages.push_back(Common::String());
 		}
 	}
 


Commit: 760d5ac733ce41a5d4a3f861234850dcc4e96c38
    https://github.com/scummvm/scummvm/commit/760d5ac733ce41a5d4a3f861234850dcc4e96c38
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Move drawPic() into base class

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/hires1.cpp
    engines/adl/hires1.h
    engines/adl/hires2.cpp
    engines/adl/hires2.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index e777559..db2d9d6 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -356,6 +356,13 @@ void AdlEngine::clearScreen() const {
 	_display->clear(0x00);
 }
 
+void AdlEngine::drawPic(byte pic, Common::Point pos) const {
+	if (_roomData.pictures.contains(pic))
+		_graphics->drawPic(*_roomData.pictures[pic]->createReadStream(), pos);
+	else
+		_graphics->drawPic(*_pictures[pic]->createReadStream(), pos);
+}
+
 void AdlEngine::drawItems() const {
 	Common::Array<Item>::const_iterator item;
 
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index d8ee5d9..4751ed6 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -234,6 +234,7 @@ protected:
 
 	// Graphics
 	void clearScreen() const;
+	void drawPic(byte pic, Common::Point pos = Common::Point()) const;
 	void drawItems() const;
 
 	// Sound
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index c1a43b8..9e24d4f 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -262,10 +262,6 @@ void HiRes1Engine::restartGame() {
 	_display->printAsciiString("\r\r\r\r\r");
 }
 
-void HiRes1Engine::drawPic(byte pic, Common::Point pos) const {
-	_graphics->drawPic(*_pictures[pic]->createReadStream(), pos);
-}
-
 void HiRes1Engine::printString(const Common::String &str) {
 	Common::String wrap = str;
 	wordWrap(wrap);
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index 29cdd5a..02eb75a 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -103,7 +103,6 @@ private:
 	void init();
 	void initState();
 	void restartGame();
-	void drawPic(byte pic, Common::Point pos = Common::Point()) const;
 	void printString(const Common::String &str);
 	void printMessage(uint idx);
 	void drawItem(const Item &item, const Common::Point &pos) const;
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 30114d6..8be8681 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -196,13 +196,6 @@ void HiRes2Engine::restartGame() {
 	initState();
 }
 
-void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
-	if (_roomData.pictures.contains(pic))
-		_graphics->drawPic(*_roomData.pictures[pic]->createReadStream(), pos);
-	else
-		_graphics->drawPic(*_pictures[pic]->createReadStream(), pos);
-}
-
 void HiRes2Engine::drawItem(const Item &item, const Common::Point &pos) const {
 	StreamPtr stream(_itemPics[item.picture - 1]->createReadStream());
 	stream->readByte(); // Skip clear opcode
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 17687b5..c99c0b0 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -60,7 +60,6 @@ private:
 	void init();
 	void initState();
 	void restartGame();
-	void drawPic(byte pic, Common::Point pos) const;
 	void drawItem(const Item &item, const Common::Point &pos) const;
 	void loadRoom(byte roomNr);
 	void showRoom();


Commit: 367cb511d153c6d4733a65b153506b7f0e8b01b3
    https://github.com/scummvm/scummvm/commit/367cb511d153c6d4733a65b153506b7f0e8b01b3
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Add Console

Changed paths:
  A engines/adl/console.cpp
  A engines/adl/console.h
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/module.mk



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index db2d9d6..c9673bd 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -47,6 +47,7 @@ AdlEngine::~AdlEngine() {
 	delete _display;
 	delete _graphics;
 	delete _speaker;
+	delete _console;
 }
 
 AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) :
@@ -64,7 +65,9 @@ AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) :
 		_canRestoreNow(false) {
 }
 
-bool AdlEngine::pollEvent(Common::Event &event) {
+bool AdlEngine::pollEvent(Common::Event &event) const {
+	_console->onFrame();
+
 	if (g_system->getEventManager()->pollEvent(event)) {
 		if (event.type != Common::EVENT_KEYDOWN)
 			return false;
@@ -74,6 +77,11 @@ bool AdlEngine::pollEvent(Common::Event &event) {
 				quitGame();
 				return false;
 			}
+
+			if (event.kbd.keycode == Common::KEYCODE_d) {
+				_console->attach();
+				return false;
+			}
 		}
 
 		return true;
@@ -493,6 +501,7 @@ void AdlEngine::dropItem(byte noun) {
 }
 
 Common::Error AdlEngine::run() {
+	_console = new Console(this);
 	_speaker = new Speaker();
 	_display = new Display();
 
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 4751ed6..d9fc590 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -35,6 +35,7 @@
 #include "audio/mixer.h"
 #include "audio/softsynth/pcspk.h"
 
+#include "adl/console.h"
 #include "adl/disk.h"
 
 namespace Common {
@@ -46,6 +47,7 @@ struct Event;
 
 namespace Adl {
 
+class Console;
 class Display;
 class GraphicsMan;
 class Speaker;
@@ -172,7 +174,7 @@ class AdlEngine : public Engine {
 public:
 	virtual ~AdlEngine();
 
-	static bool pollEvent(Common::Event &event);
+	bool pollEvent(Common::Event &event) const;
 
 protected:
 	AdlEngine(OSystem *syst, const AdlGameDescription *gd);
@@ -320,6 +322,8 @@ private:
 	Common::String getWord(const Common::String &line, uint &index) const;
 	void getInput(uint &verb, uint &noun);
 
+	Console *_console;
+	GUI::Debugger *getDebugger() { return _console; }
 	const AdlGameDescription *_gameDescription;
 	byte _saveVerb, _saveNoun, _restoreVerb, _restoreNoun;
 	bool _canSaveNow, _canRestoreNow;
diff --git a/engines/adl/console.cpp b/engines/adl/console.cpp
new file mode 100644
index 0000000..e051716
--- /dev/null
+++ b/engines/adl/console.cpp
@@ -0,0 +1,31 @@
+/* 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 "adl/console.h"
+
+namespace Adl {
+
+Console::Console(AdlEngine *engine) : GUI::Debugger() {
+	_engine = engine;
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/console.h b/engines/adl/console.h
new file mode 100644
index 0000000..56c84f0
--- /dev/null
+++ b/engines/adl/console.h
@@ -0,0 +1,42 @@
+/* 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_CONSOLE_H
+#define ADL_CONSOLE_H
+
+#include "gui/debugger.h"
+
+namespace Adl {
+
+class AdlEngine;
+
+class Console : public GUI::Debugger {
+public:
+	Console(AdlEngine *engine);
+
+private:
+	AdlEngine *_engine;
+};
+
+} // End of namespace Adl
+
+#endif
diff --git a/engines/adl/module.mk b/engines/adl/module.mk
index 661d1b1..7f097a4 100644
--- a/engines/adl/module.mk
+++ b/engines/adl/module.mk
@@ -3,6 +3,7 @@ MODULE := engines/adl
 MODULE_OBJS := \
 	adl.o \
 	adl_v2.o \
+	console.o \
 	detection.o \
 	disk.o \
 	display.o \


Commit: 73dfe71b1beaca362463104ed90cdab8a04ea968
    https://github.com/scummvm/scummvm/commit/73dfe71b1beaca362463104ed90cdab8a04ea968
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Add verbs and nouns debug commands

Changed paths:
    engines/adl/adl.h
    engines/adl/console.cpp
    engines/adl/console.h



diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index d9fc590..4367e8b 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -171,6 +171,7 @@ struct RoomData {
 };
 
 class AdlEngine : public Engine {
+friend class Console;
 public:
 	virtual ~AdlEngine();
 
diff --git a/engines/adl/console.cpp b/engines/adl/console.cpp
index e051716..5fe7f08 100644
--- a/engines/adl/console.cpp
+++ b/engines/adl/console.cpp
@@ -21,11 +21,68 @@
  */
 
 #include "adl/console.h"
+#include "adl/adl.h"
 
 namespace Adl {
 
 Console::Console(AdlEngine *engine) : GUI::Debugger() {
 	_engine = engine;
+
+	registerCmd("help", WRAP_METHOD(Console, Cmd_Help));
+	registerCmd("nouns", WRAP_METHOD(Console, Cmd_Nouns));
+	registerCmd("verbs", WRAP_METHOD(Console, Cmd_Verbs));
+}
+
+static Common::String toAscii(const Common::String &str) {
+	Common::String ascii(str);
+
+	for (uint i = 0; i < ascii.size(); ++i)
+		ascii.setChar(ascii[i] & 0x7f, i);
+
+	return ascii;
+}
+
+bool Console::Cmd_Help(int argc, const char **argv) {
+	debugPrintf("Parser:\n");
+	debugPrintf(" verbs - Lists the vocabulary verbs\n");
+	debugPrintf(" nouns - Lists the vocabulary nouns\n");
+	return true;
+}
+
+bool Console::Cmd_Verbs(int argc, const char **argv) {
+	if (argc != 1) {
+		debugPrintf("Usage: %s\n", argv[0]);
+		return true;
+	}
+
+	debugPrintf("Verbs in alphabetical order:\n");
+	printWordMap(_engine->_verbs);
+	return true;
+}
+
+bool Console::Cmd_Nouns(int argc, const char **argv) {
+	if (argc != 1) {
+		debugPrintf("Usage: %s\n", argv[0]);
+		return true;
+	}
+
+	debugPrintf("Nouns in alphabetical order:\n");
+	printWordMap(_engine->_nouns);
+	return true;
+}
+
+void Console::printWordMap(const WordMap &wordMap) {
+	Common::StringArray words;
+	WordMap::const_iterator verb;
+
+	for (verb = wordMap.begin(); verb != wordMap.end(); ++verb)
+		words.push_back(verb->_key);
+
+	Common::sort(words.begin(), words.end());
+
+	Common::StringArray::const_iterator word;
+	for (word = words.begin(); word != words.end(); ++word)
+		debugPrintf("%s: %d\n", toAscii(*word).c_str(), wordMap[*word]);
 }
 
 } // End of namespace Adl
diff --git a/engines/adl/console.h b/engines/adl/console.h
index 56c84f0..d8a6525 100644
--- a/engines/adl/console.h
+++ b/engines/adl/console.h
@@ -25,6 +25,12 @@
 
 #include "gui/debugger.h"
 
+#include "common/hashmap.h"
+
+namespace Common {
+class String;
+}
+
 namespace Adl {
 
 class AdlEngine;
@@ -34,6 +40,12 @@ public:
 	Console(AdlEngine *engine);
 
 private:
+	bool Cmd_Help(int argc, const char **argv);
+	bool Cmd_Nouns(int argc, const char **argv);
+	bool Cmd_Verbs(int argc, const char **argv);
+
+	void printWordMap(const Common::HashMap<Common::String, uint> &wordMap);
+
 	AdlEngine *_engine;
 };
 


Commit: b24f30527b4ff79e5341e76a7fd3dc21d75e2ed2
    https://github.com/scummvm/scummvm/commit/b24f30527b4ff79e5341e76a7fd3dc21d75e2ed2
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Add script dump and trace for hires1

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/adl_v2.h
    engines/adl/console.cpp
    engines/adl/console.h
    engines/adl/hires1.cpp
    engines/adl/hires2.cpp



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index c9673bd..5bcf1bc 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -22,6 +22,7 @@
 
 #include "common/scummsys.h"
 #include "common/config-manager.h"
+#include "common/debug-channels.h"
 #include "common/debug.h"
 #include "common/error.h"
 #include "common/file.h"
@@ -48,10 +49,12 @@ AdlEngine::~AdlEngine() {
 	delete _graphics;
 	delete _speaker;
 	delete _console;
+	delete _dumpFile;
 }
 
 AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) :
 		Engine(syst),
+		_dumpFile(nullptr),
 		_display(nullptr),
 		_graphics(nullptr),
 		_isRestarting(false),
@@ -63,6 +66,8 @@ AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) :
 		_restoreNoun(0),
 		_canSaveNow(false),
 		_canRestoreNow(false) {
+
+	DebugMan.addDebugChannel(kDebugChannelScript, "Script", "Trace script execution");
 }
 
 bool AdlEngine::pollEvent(Common::Event &event) const {
@@ -204,7 +209,7 @@ byte AdlEngine::inputKey(bool showCursor) const {
 	return key;
 }
 
-void AdlEngine::loadWords(Common::ReadStream &stream, WordMap &map) const {
+void AdlEngine::loadWords(Common::ReadStream &stream, WordMap &map, Common::StringArray &pri) const {
 	uint index = 0;
 
 	while (1) {
@@ -220,6 +225,8 @@ void AdlEngine::loadWords(Common::ReadStream &stream, WordMap &map) const {
 		if (!map.contains(word))
 			map[word] = index;
 
+		pri.push_back(Console::toAscii(word));
+
 		byte synonyms = stream.readByte();
 
 		if (stream.err() || stream.eos())
@@ -863,54 +870,118 @@ void AdlEngine::getInput(uint &verb, uint &noun) {
 	}
 }
 
-typedef Common::Functor1Mem<ScriptEnv &, int, AdlEngine> OpcodeV1;
+bool AdlEngine::op_debug(const char *fmt, ...) const {
+	if (DebugMan.isDebugChannelEnabled(kDebugChannelScript)) {
+		va_list va;
+		va_start(va, fmt);
+		Common::String output = Common::String::vformat(fmt, va);
+		va_end(va);
+
+		output += '\n';
+		if (_dumpFile) {
+			_dumpFile->write(output.c_str(), output.size());
+			return true;
+		} else
+			debugN("%s", output.c_str());
+	}
+
+	return false;
+}
+
+#define OP_DEBUG_0(F) do { \
+	if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F)) \
+		return 0; \
+} while (0)
+
+#define OP_DEBUG_1(F, P1) do { \
+	if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F, P1)) \
+		return 1; \
+} while (0)
+
+#define OP_DEBUG_2(F, P1, P2) do { \
+	if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F, P1, P2)) \
+		return 2; \
+} while (0)
+
+#define OP_DEBUG_3(F, P1, P2, P3) do { \
+	if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F, P1, P2, P3)) \
+		return 3; \
+} while (0)
+
+#define OP_DEBUG_4(F, P1, P2, P3, P4) do { \
+	if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F, P1, P2, P3, P4)) \
+		return 4; \
+} while (0)
 
 int AdlEngine::o1_isItemInRoom(ScriptEnv &e) {
+	OP_DEBUG_2("\t&& GET_ITEM_ROOM(%s) == %s", itemStr(e.arg(1)).c_str(), itemRoomStr(e.arg(2)).c_str());
+
 	if (getItem(e.arg(1)).room == roomArg(e.arg(2)))
 		return 2;
+
 	return -1;
 }
 
 int AdlEngine::o1_isMovesGT(ScriptEnv &e) {
+	OP_DEBUG_1("\t&& MOVES > %d", e.arg(1));
+
 	if (_state.moves > e.arg(1))
 		return 1;
+
 	return -1;
 }
 
 int AdlEngine::o1_isVarEQ(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::o1_isCurPicEQ(ScriptEnv &e) {
+	OP_DEBUG_1("\t&& GET_CURPIC() == %d", e.arg(1));
+
 	if (getCurRoom().curPicture == e.arg(1))
 		return 1;
+
 	return -1;
 }
 
 int AdlEngine::o1_isItemPicEQ(ScriptEnv &e) {
+	OP_DEBUG_2("\t&& GET_ITEM_PIC(%s) == %d", itemStr(e.arg(1)).c_str(), e.arg(2));
+
 	if (getItem(e.arg(1)).picture == e.arg(2))
 		return 2;
+
 	return -1;
 }
 
 int AdlEngine::o1_varAdd(ScriptEnv &e) {
+	OP_DEBUG_2("\tVARS[%d] += %d", e.arg(2), e.arg(1));
+
 	setVar(e.arg(2), getVar(e.arg(2) + e.arg(1)));
 	return 2;
 }
 
 int AdlEngine::o1_varSub(ScriptEnv &e) {
+	OP_DEBUG_2("\tVARS[%d] -= %d", e.arg(2), e.arg(1));
+
 	setVar(e.arg(2), getVar(e.arg(2)) - e.arg(1));
 	return 2;
 }
 
 int AdlEngine::o1_varSet(ScriptEnv &e) {
+	OP_DEBUG_2("\tVARS[%d] = %d", e.arg(1), e.arg(2));
+
 	setVar(e.arg(1), e.arg(2));
 	return 2;
 }
 
 int AdlEngine::o1_listInv(ScriptEnv &e) {
+	OP_DEBUG_0("\tLIST_INVENTORY()");
+
 	Common::Array<Item>::const_iterator item;
 
 	for (item = _state.items.begin(); item != _state.items.end(); ++item)
@@ -921,53 +992,73 @@ int AdlEngine::o1_listInv(ScriptEnv &e) {
 }
 
 int AdlEngine::o1_moveItem(ScriptEnv &e) {
+	OP_DEBUG_2("\tSET_ITEM_ROOM(%s, %s)", itemStr(e.arg(1)).c_str(), itemRoomStr(e.arg(2)).c_str());
+
 	getItem(e.arg(1)).room = e.arg(2);
 	return 2;
 }
 
 int AdlEngine::o1_setRoom(ScriptEnv &e) {
+	OP_DEBUG_1("\tROOM = %d", e.arg(1));
+
 	getCurRoom().curPicture = getCurRoom().picture;
 	_state.room = e.arg(1);
 	return 1;
 }
 
 int AdlEngine::o1_setCurPic(ScriptEnv &e) {
+	OP_DEBUG_1("\tSET_CURPIC(%d)", e.arg(1));
+
 	getCurRoom().curPicture = e.arg(1);
 	return 1;
 }
 
 int AdlEngine::o1_setPic(ScriptEnv &e) {
+	OP_DEBUG_1("\tSET_PIC(%d)", e.arg(1));
+
 	getCurRoom().picture = getCurRoom().curPicture = e.arg(1);
 	return 1;
 }
 
 int AdlEngine::o1_printMsg(ScriptEnv &e) {
+	OP_DEBUG_1("\tPRINT(%s)", msgStr(e.arg(1)).c_str());
+
 	printMessage(e.arg(1));
 	return 1;
 }
 
 int AdlEngine::o1_setLight(ScriptEnv &e) {
+	OP_DEBUG_0("\tLIGHT()");
+
 	_state.isDark = false;
 	return 0;
 }
 
 int AdlEngine::o1_setDark(ScriptEnv &e) {
+	OP_DEBUG_0("\tDARK()");
+
 	_state.isDark = true;
 	return 0;
 }
 
 int AdlEngine::o1_save(ScriptEnv &e) {
+	OP_DEBUG_0("\tSAVE_GAME()");
+
 	saveGameState(0, "");
 	return 0;
 }
 
 int AdlEngine::o1_restore(ScriptEnv &e) {
+	OP_DEBUG_0("\tRESTORE_GAME()");
+
 	loadGameState(0);
 	_isRestoring = false;
 	return 0;
 }
 
 int AdlEngine::o1_restart(ScriptEnv &e) {
+	OP_DEBUG_0("\tRESTART_GAME()");
+
 	_display->printString(_strings.playAgain);
 	Common::String input = inputString();
 
@@ -983,12 +1074,16 @@ int AdlEngine::o1_restart(ScriptEnv &e) {
 }
 
 int AdlEngine::o1_quit(ScriptEnv &e) {
+	OP_DEBUG_0("\tQUIT_GAME()");
+
 	printMessage(_messageIds.thanksForPlaying);
 	quitGame();
 	return -1;
 }
 
 int AdlEngine::o1_placeItem(ScriptEnv &e) {
+	OP_DEBUG_4("\tPLACE_ITEM(%s, %s, (%d, %d))", itemStr(e.arg(1)).c_str(), itemRoomStr(e.arg(2)).c_str(), e.arg(3), e.arg(4));
+
 	Item &item = getItem(e.arg(1));
 
 	item.room = roomArg(e.arg(2));
@@ -998,17 +1093,23 @@ int AdlEngine::o1_placeItem(ScriptEnv &e) {
 }
 
 int AdlEngine::o1_setItemPic(ScriptEnv &e) {
+	OP_DEBUG_2("\tSET_ITEM_PIC(%s, %d)", itemStr(e.arg(2)).c_str(), e.arg(1));
+
 	getItem(e.arg(2)).picture = e.arg(1);
 	return 2;
 }
 
 int AdlEngine::o1_resetPic(ScriptEnv &e) {
+	OP_DEBUG_0("\tRESET_PIC()");
+
 	getCurRoom().curPicture = getCurRoom().picture;
 	return 0;
 }
 
 template <Direction D>
 int AdlEngine::o1_goDirection(ScriptEnv &e) {
+	OP_DEBUG_0((Common::String("\tGO_") + dirStr(D) + "()").c_str());
+
 	byte room = getCurRoom().connections[D];
 
 	if (room == 0) {
@@ -1022,24 +1123,35 @@ int AdlEngine::o1_goDirection(ScriptEnv &e) {
 }
 
 int AdlEngine::o1_takeItem(ScriptEnv &e) {
+	OP_DEBUG_0("\tTAKE_ITEM()");
+
 	takeItem(e.getNoun());
 	return 0;
 }
 
 int AdlEngine::o1_dropItem(ScriptEnv &e) {
+	OP_DEBUG_0("\tDROP_ITEM()");
+
 	dropItem(e.getNoun());
 	return 0;
 }
 
 int AdlEngine::o1_setRoomPic(ScriptEnv &e) {
+	OP_DEBUG_2("\tSET_ROOM_PIC(%d, %d)", e.arg(1), e.arg(2));
+
 	getRoom(e.arg(1)).picture = getRoom(e.arg(1)).curPicture = e.arg(2);
 	return 2;
 }
 
 bool AdlEngine::matchCommand(ScriptEnv &env) const {
-	if (!env.isMatch())
+	if (!env.isMatch() && !_dumpFile)
 		return false;
 
+	if (DebugMan.isDebugChannelEnabled(kDebugChannelScript)) {
+		op_debug("IF\n\tROOM == %s", roomStr(env.getCommand().room).c_str());
+		op_debug("\t&& SAID(%s, %s)", verbStr(env.getCommand().verb).c_str(), nounStr(env.getCommand().noun).c_str());
+	}
+
 	for (uint i = 0; i < env.getCondCount(); ++i) {
 		byte op = env.op();
 
@@ -1048,8 +1160,11 @@ bool AdlEngine::matchCommand(ScriptEnv &env) const {
 
 		int numArgs = (*_condOpcodes[op])(env);
 
-		if (numArgs < 0)
+		if (numArgs < 0) {
+			if (DebugMan.isDebugChannelEnabled(kDebugChannelScript))
+				op_debug("FAIL\n");
 			return false;
+		}
 
 		env.skip(numArgs + 1);
 	}
@@ -1058,6 +1173,9 @@ bool AdlEngine::matchCommand(ScriptEnv &env) const {
 }
 
 void AdlEngine::doActions(ScriptEnv &env) {
+	if (DebugMan.isDebugChannelEnabled(kDebugChannelScript))
+		op_debug("THEN");
+
 	for (uint i = 0; i < env.getActCount(); ++i) {
 		byte op = env.op();
 
@@ -1066,11 +1184,17 @@ void AdlEngine::doActions(ScriptEnv &env) {
 
 		int numArgs = (*_actOpcodes[op])(env);
 
-		if (numArgs < 0)
+		if (numArgs < 0) {
+			if (DebugMan.isDebugChannelEnabled(kDebugChannelScript))
+				op_debug("ABORT\n");
 			return;
+		}
 
 		env.skip(numArgs + 1);
 	}
+
+	if (DebugMan.isDebugChannelEnabled(kDebugChannelScript))
+		op_debug("END\n");
 }
 
 bool AdlEngine::doOneCommand(const Commands &commands, byte verb, byte noun) {
@@ -1097,4 +1221,68 @@ void AdlEngine::doAllCommands(const Commands &commands, byte verb, byte noun) {
 	}
 }
 
+Common::String AdlEngine::toAscii(const Common::String &str) {
+	Common::String ascii = Console::toAscii(str);
+	if (ascii.lastChar() == '\r')
+		ascii.deleteLastChar();
+	// FIXME: remove '\r's inside string?
+	return ascii;
+}
+
+Common::String AdlEngine::itemStr(uint i) const {
+	byte desc = getItem(i).description;
+	byte noun = getItem(i).noun;
+	Common::String name = Common::String::format("%d", i);
+	if (noun > 0) {
+		name += "/";
+		name += _priNouns[noun - 1];
+	}
+	if (desc > 0) {
+		name += "/";
+		name += toAscii(_messages[desc - 1]);
+	}
+	return name;
+}
+
+Common::String AdlEngine::itemRoomStr(uint i) const {
+	switch (i) {
+	case IDI_ANY:
+		return "CARRYING";
+	case IDI_VOID_ROOM:
+		return "GONE";
+	default:
+		return Common::String::format("%d", i);
+	}
+}
+
+Common::String AdlEngine::roomStr(uint i) const {
+	if (i == IDI_ANY)
+		return "*";
+	else
+		return Common::String::format("%d", i);
+}
+
+Common::String AdlEngine::verbStr(uint i) const {
+	if (i == IDI_ANY)
+		return "*";
+	else
+		return Common::String::format("%d/%s", i, _priVerbs[i - 1].c_str());
+}
+
+Common::String AdlEngine::nounStr(uint i) const {
+	if (i == IDI_ANY)
+		return "*";
+	else
+		return Common::String::format("%d/%s", i, _priNouns[i - 1].c_str());
+}
+
+Common::String AdlEngine::msgStr(uint i) const {
+	return Common::String::format("%d/%s", i, toAscii(_messages[i - 1]).c_str());
+}
+
+Common::String AdlEngine::dirStr(Direction dir) const {
+	static const char *dirs[] = { "NORTH", "SOUTH", "EAST", "WEST", "UP", "DOWN" };
+	return dirs[dir];
+}
+
 } // End of namespace Adl
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 4367e8b..43d3187 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -29,6 +29,7 @@
 #include "common/hashmap.h"
 #include "common/hash-str.h"
 #include "common/func.h"
+#include "common/scummsys.h"
 
 #include "engines/engine.h"
 
@@ -54,10 +55,15 @@ class Speaker;
 struct AdlGameDescription;
 struct ScriptEnv;
 
+enum kDebugChannels {
+	kDebugChannelScript = 1 << 0
+};
+
 // Save and restore opcodes
 #define IDO_ACT_SAVE           0x0f
 #define IDO_ACT_LOAD           0x10
 
+#define IDI_VOID_ROOM 0xfd
 #define IDI_ANY 0xfe
 
 #define IDI_WORD_SIZE 8
@@ -118,6 +124,7 @@ public:
 	byte getCondCount() const { return _cmd.numCond; }
 	byte getActCount() const { return _cmd.numAct; }
 	byte getNoun() const { return _noun; }
+	const Command &getCommand() const { return _cmd; }
 
 private:
 	const Command &_cmd;
@@ -195,7 +202,7 @@ protected:
 	Common::String inputString(byte prompt = 0) const;
 	byte inputKey(bool showCursor = true) const;
 
-	void loadWords(Common::ReadStream &stream, WordMap &map) const;
+	void loadWords(Common::ReadStream &stream, WordMap &map, Common::StringArray &pri) const;
 	void readCommands(Common::ReadStream &stream, Commands &commands);
 	void checkInput(byte verb, byte noun);
 
@@ -259,6 +266,18 @@ protected:
 	bool doOneCommand(const Commands &commands, byte verb, byte noun);
 	void doAllCommands(const Commands &commands, byte verb, byte noun);
 
+	// Debug functions
+	static Common::String toAscii(const Common::String &str);
+	Common::String itemStr(uint i) const;
+	Common::String roomStr(uint i) const;
+	Common::String itemRoomStr(uint i) const;
+	Common::String verbStr(uint i) const;
+	Common::String nounStr(uint i) const;
+	Common::String msgStr(uint i) const;
+	Common::String dirStr(Direction dir) const;
+	bool op_debug(const char *fmt, ...) const;
+	Common::DumpFile *_dumpFile;
+
 	Display *_display;
 	GraphicsMan *_graphics;
 	Speaker *_speaker;
@@ -280,6 +299,8 @@ protected:
 
 	WordMap _verbs;
 	WordMap _nouns;
+	Common::StringArray _priVerbs;
+	Common::StringArray _priNouns;
 
 	struct {
 		Common::String enterCommand;
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 3a32f48..3906021 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -29,7 +29,6 @@
 // this is not currently implemented.
 
 #define IDI_CUR_ROOM 0xfc
-#define IDI_VOID_ROOM 0xfd
 
 namespace Common{
 class RandomSource;
diff --git a/engines/adl/console.cpp b/engines/adl/console.cpp
index 5fe7f08..53e452a 100644
--- a/engines/adl/console.cpp
+++ b/engines/adl/console.cpp
@@ -20,6 +20,8 @@
  *
  */
 
+#include "common/debug-channels.h"
+
 #include "adl/console.h"
 #include "adl/adl.h"
 
@@ -28,12 +30,12 @@ namespace Adl {
 Console::Console(AdlEngine *engine) : GUI::Debugger() {
 	_engine = engine;
 
-	registerCmd("help", WRAP_METHOD(Console, Cmd_Help));
 	registerCmd("nouns", WRAP_METHOD(Console, Cmd_Nouns));
 	registerCmd("verbs", WRAP_METHOD(Console, Cmd_Verbs));
+	registerCmd("dump_scripts", WRAP_METHOD(Console, Cmd_DumpScripts));
 }
 
-static Common::String toAscii(const Common::String &str) {
+Common::String Console::toAscii(const Common::String &str) {
 	Common::String ascii(str);
 
 	for (uint i = 0; i < ascii.size(); ++i)
@@ -42,13 +44,6 @@ static Common::String toAscii(const Common::String &str) {
 	return ascii;
 }
 
-bool Console::Cmd_Help(int argc, const char **argv) {
-	debugPrintf("Parser:\n");
-	debugPrintf(" verbs - Lists the vocabulary verbs\n");
-	debugPrintf(" nouns - Lists the vocabulary nouns\n");
-	return true;
-}
-
 bool Console::Cmd_Verbs(int argc, const char **argv) {
 	if (argc != 1) {
 		debugPrintf("Usage: %s\n", argv[0]);
@@ -71,6 +66,35 @@ bool Console::Cmd_Nouns(int argc, const char **argv) {
 	return true;
 }
 
+bool Console::Cmd_DumpScripts(int argc, const char **argv) {
+	if (argc != 1) {
+		debugPrintf("Usage: %s\n", argv[0]);
+		return true;
+	}
+
+	bool oldFlag = DebugMan.isDebugChannelEnabled(kDebugChannelScript);
+
+	DebugMan.enableDebugChannel("Script");
+
+	_engine->_dumpFile = new Common::DumpFile();
+
+	_engine->_dumpFile->open("GLOBAL.ADL");
+	_engine->doAllCommands(_engine->_globalCommands, IDI_ANY, IDI_ANY);
+	_engine->_dumpFile->close();
+
+	_engine->_dumpFile->open("RESPONSE.ADL");
+	_engine->doAllCommands(_engine->_roomCommands, IDI_ANY, IDI_ANY);
+	_engine->_dumpFile->close();
+
+	delete _engine->_dumpFile;
+	_engine->_dumpFile = nullptr;
+
+	if (!oldFlag)
+		DebugMan.disableDebugChannel("Script");
+
+	return true;
+}
+
 void Console::printWordMap(const WordMap &wordMap) {
 	Common::StringArray words;
 	WordMap::const_iterator verb;
diff --git a/engines/adl/console.h b/engines/adl/console.h
index d8a6525..86538de 100644
--- a/engines/adl/console.h
+++ b/engines/adl/console.h
@@ -39,10 +39,13 @@ class Console : public GUI::Debugger {
 public:
 	Console(AdlEngine *engine);
 
+	static Common::String toAscii(const Common::String &str);
+
 private:
 	bool Cmd_Help(int argc, const char **argv);
 	bool Cmd_Nouns(int argc, const char **argv);
 	bool Cmd_Verbs(int argc, const char **argv);
+	bool Cmd_DumpScripts(int argc, const char **argv);
 
 	void printWordMap(const Common::HashMap<Common::String, uint> &wordMap);
 
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 9e24d4f..005e56e 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -199,10 +199,10 @@ void HiRes1Engine::init() {
 		error("Failed to read game data from '" IDS_HR1_EXE_1 "'");
 
 	stream->seek(IDI_HR1_OFS_VERBS);
-	loadWords(*stream, _verbs);
+	loadWords(*stream, _verbs, _priVerbs);
 
 	stream->seek(IDI_HR1_OFS_NOUNS);
-	loadWords(*stream, _nouns);
+	loadWords(*stream, _nouns, _priNouns);
 }
 
 void HiRes1Engine::initState() {
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 8be8681..6e6692b 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -138,11 +138,11 @@ void HiRes2Engine::init() {
 
 	// Load verbs
 	stream.reset(_disk.createReadStream(0x19, 0x0, 0x00, 3));
-	loadWords(*stream, _verbs);
+	loadWords(*stream, _verbs, _priVerbs);
 
 	// Load nouns
 	stream.reset(_disk.createReadStream(0x22, 0x2, 0x00, 7));
-	loadWords(*stream, _nouns);
+	loadWords(*stream, _nouns, _priNouns);
 }
 
 void HiRes2Engine::initState() {


Commit: 2c8e0cefb15205c61a10a650e63d7fb53fad00a6
    https://github.com/scummvm/scummvm/commit/2c8e0cefb15205c61a10a650e63d7fb53fad00a6
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Store items in a List instead of an Array

Item IDs are not necessarily sequential

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/adl_v2.cpp
    engines/adl/hires1.cpp
    engines/adl/hires2.cpp



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 5bcf1bc..038d4ec 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -379,7 +379,7 @@ void AdlEngine::drawPic(byte pic, Common::Point pos) const {
 }
 
 void AdlEngine::drawItems() const {
-	Common::Array<Item>::const_iterator item;
+	Common::List<Item>::const_iterator item;
 
 	uint dropped = 0;
 
@@ -435,17 +435,23 @@ Room &AdlEngine::getCurRoom() {
 }
 
 const Item &AdlEngine::getItem(uint i) const {
-	if (i < 1 || i > _state.items.size())
-		error("Item %i out of range [1, %i]", i, _state.items.size());
+	Common::List<Item>::const_iterator item;
 
-	return _state.items[i - 1];
+	for (item = _state.items.begin(); item != _state.items.end(); ++item)
+		if (item->id == i)
+			return *item;
+
+	error("Item %i not found", i);
 }
 
 Item &AdlEngine::getItem(uint i) {
-	if (i < 1 || i > _state.items.size())
-		error("Item %i out of range [1, %i]", i, _state.items.size());
+	Common::List<Item>::iterator item;
+
+	for (item = _state.items.begin(); item != _state.items.end(); ++item)
+		if (item->id == i)
+			return *item;
 
-	return _state.items[i - 1];
+	error("Item %i not found", i);
 }
 
 byte AdlEngine::getVar(uint i) const {
@@ -463,7 +469,7 @@ void AdlEngine::setVar(uint i, byte value) {
 }
 
 void AdlEngine::takeItem(byte noun) {
-	Common::Array<Item>::iterator item;
+	Common::List<Item>::iterator item;
 
 	for (item = _state.items.begin(); item != _state.items.end(); ++item) {
 		if (item->noun != noun || item->room != _state.room)
@@ -493,7 +499,7 @@ void AdlEngine::takeItem(byte noun) {
 }
 
 void AdlEngine::dropItem(byte noun) {
-	Common::Array<Item>::iterator item;
+	Common::List<Item>::iterator item;
 
 	for (item = _state.items.begin(); item != _state.items.end(); ++item) {
 		if (item->noun != noun || item->room != IDI_ANY)
@@ -645,12 +651,13 @@ Common::Error AdlEngine::loadGameState(int slot) {
 	if (size != _state.items.size())
 		error("Item count mismatch (expected %i; found %i)", _state.items.size(), size);
 
-	for (uint i = 0; i < size; ++i) {
-		_state.items[i].room = inFile->readByte();
-		_state.items[i].picture = inFile->readByte();
-		_state.items[i].position.x = inFile->readByte();
-		_state.items[i].position.y = inFile->readByte();
-		_state.items[i].state = inFile->readByte();
+	Common::List<Item>::iterator item;
+	for (item = _state.items.begin(); item != _state.items.end(); ++item) {
+		item->room = inFile->readByte();
+		item->picture = inFile->readByte();
+		item->position.x = inFile->readByte();
+		item->position.y = inFile->readByte();
+		item->state = inFile->readByte();
 	}
 
 	size = inFile->readUint32BE();
@@ -724,12 +731,13 @@ Common::Error AdlEngine::saveGameState(int slot, const Common::String &desc) {
 	}
 
 	outFile->writeUint32BE(_state.items.size());
-	for (uint i = 0; i < _state.items.size(); ++i) {
-		outFile->writeByte(_state.items[i].room);
-		outFile->writeByte(_state.items[i].picture);
-		outFile->writeByte(_state.items[i].position.x);
-		outFile->writeByte(_state.items[i].position.y);
-		outFile->writeByte(_state.items[i].state);
+	Common::List<Item>::const_iterator item;
+	for (item = _state.items.begin(); item != _state.items.end(); ++item) {
+		outFile->writeByte(item->room);
+		outFile->writeByte(item->picture);
+		outFile->writeByte(item->position.x);
+		outFile->writeByte(item->position.y);
+		outFile->writeByte(item->state);
 	}
 
 	outFile->writeUint32BE(_state.vars.size());
@@ -982,7 +990,7 @@ int AdlEngine::o1_varSet(ScriptEnv &e) {
 int AdlEngine::o1_listInv(ScriptEnv &e) {
 	OP_DEBUG_0("\tLIST_INVENTORY()");
 
-	Common::Array<Item>::const_iterator item;
+	Common::List<Item>::const_iterator item;
 
 	for (item = _state.items.begin(); item != _state.items.end(); ++item)
 		if (item->room == IDI_ANY)
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 43d3187..42d6667 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -139,6 +139,7 @@ enum {
 };
 
 struct Item {
+	byte id;
 	byte noun;
 	byte room;
 	byte picture;
@@ -157,7 +158,7 @@ struct Time {
 
 struct State {
 	Common::Array<Room> rooms;
-	Common::Array<Item> items;
+	Common::List<Item> items;
 	Common::Array<byte> vars;
 
 	byte room;
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 8a826e5..cc38beb 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -213,7 +213,7 @@ int AdlEngine_v2::o2_isRandomGT(ScriptEnv &e) {
 }
 
 int AdlEngine_v2::o2_isNounNotInRoom(ScriptEnv &e) {
-	Common::Array<Item>::const_iterator item;
+	Common::List<Item>::const_iterator item;
 
 	for (item = _state.items.begin(); item != _state.items.end(); ++item)
 		if (item->noun == e.getNoun() && (item->room == roomArg(e.arg(1))))
@@ -223,7 +223,7 @@ int AdlEngine_v2::o2_isNounNotInRoom(ScriptEnv &e) {
 }
 
 int AdlEngine_v2::o2_isCarryingSomething(ScriptEnv &e) {
-	Common::Array<Item>::const_iterator item;
+	Common::List<Item>::const_iterator item;
 
 	for (item = _state.items.begin(); item != _state.items.end(); ++item)
 		if (item->room == IDI_ANY)
@@ -248,7 +248,7 @@ int AdlEngine_v2::o2_moveAllItems(ScriptEnv &e) {
 	byte room1 = roomArg(e.arg(1));
 	byte room2 = roomArg(e.arg(2));
 
-	Common::Array<Item>::iterator item;
+	Common::List<Item>::iterator item;
 
 	for (item = _state.items.begin(); item != _state.items.end(); ++item)
 		if (item->room == room1) {
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 005e56e..e0f7574 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -233,8 +233,10 @@ void HiRes1Engine::initState() {
 	// Load item data from executable
 	_state.items.clear();
 	stream->seek(IDI_HR1_OFS_ITEMS);
-	while (stream->readByte() != 0xff) {
+	byte id;
+	while ((id = stream->readByte()) != 0xff) {
 		Item item = { };
+		item.id = id;
 		item.noun = stream->readByte();
 		item.room = stream->readByte();
 		item.picture = stream->readByte();
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 6e6692b..4ac8e88 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -167,8 +167,10 @@ void HiRes2Engine::initState() {
 	stream.reset(_disk.createReadStream(0x21, 0x0, 0x00, 2));
 
 	_state.items.clear();
-	while (stream->readByte() != 0xff) {
+	byte id;
+	while ((id = stream->readByte()) != 0xff) {
 		Item item = { };
+		item.id = id;
 		item.noun = stream->readByte();
 		item.room = stream->readByte();
 		item.picture = stream->readByte();


Commit: cf6bc0e438e5a21fb053c4ccd562d6bed8c4b68d
    https://github.com/scummvm/scummvm/commit/cf6bc0e438e5a21fb053c4ccd562d6bed8c4b68d
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Add script dump and trace for hires2

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/adl_v2.cpp
    engines/adl/adl_v2.h
    engines/adl/console.cpp
    engines/adl/console.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 038d4ec..0c27f8b 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -22,7 +22,6 @@
 
 #include "common/scummsys.h"
 #include "common/config-manager.h"
-#include "common/debug-channels.h"
 #include "common/debug.h"
 #include "common/error.h"
 #include "common/file.h"
@@ -896,31 +895,6 @@ bool AdlEngine::op_debug(const char *fmt, ...) const {
 	return false;
 }
 
-#define OP_DEBUG_0(F) do { \
-	if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F)) \
-		return 0; \
-} while (0)
-
-#define OP_DEBUG_1(F, P1) do { \
-	if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F, P1)) \
-		return 1; \
-} while (0)
-
-#define OP_DEBUG_2(F, P1, P2) do { \
-	if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F, P1, P2)) \
-		return 2; \
-} while (0)
-
-#define OP_DEBUG_3(F, P1, P2, P3) do { \
-	if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F, P1, P2, P3)) \
-		return 3; \
-} while (0)
-
-#define OP_DEBUG_4(F, P1, P2, P3, P4) do { \
-	if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F, P1, P2, P3, P4)) \
-		return 4; \
-} while (0)
-
 int AdlEngine::o1_isItemInRoom(ScriptEnv &e) {
 	OP_DEBUG_2("\t&& GET_ITEM_ROOM(%s) == %s", itemStr(e.arg(1)).c_str(), itemRoomStr(e.arg(2)).c_str());
 
@@ -1258,6 +1232,8 @@ Common::String AdlEngine::itemRoomStr(uint i) const {
 		return "CARRYING";
 	case IDI_VOID_ROOM:
 		return "GONE";
+	case IDI_CUR_ROOM:
+		return "HERE";
 	default:
 		return Common::String::format("%d", i);
 	}
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 42d6667..ac5e22c 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -23,6 +23,7 @@
 #ifndef ADL_ADL_H
 #define ADL_ADL_H
 
+#include "common/debug-channels.h"
 #include "common/array.h"
 #include "common/rect.h"
 #include "common/str.h"
@@ -63,6 +64,7 @@ enum kDebugChannels {
 #define IDO_ACT_SAVE           0x0f
 #define IDO_ACT_LOAD           0x10
 
+#define IDI_CUR_ROOM 0xfc
 #define IDI_VOID_ROOM 0xfd
 #define IDI_ANY 0xfe
 
@@ -178,6 +180,32 @@ struct RoomData {
 	Commands commands;
 };
 
+// Opcode debugging macros
+#define OP_DEBUG_0(F) do { \
+	if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F)) \
+		return 0; \
+} while (0)
+
+#define OP_DEBUG_1(F, P1) do { \
+	if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F, P1)) \
+		return 1; \
+} while (0)
+
+#define OP_DEBUG_2(F, P1, P2) do { \
+	if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F, P1, P2)) \
+		return 2; \
+} while (0)
+
+#define OP_DEBUG_3(F, P1, P2, P3) do { \
+	if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F, P1, P2, P3)) \
+		return 3; \
+} while (0)
+
+#define OP_DEBUG_4(F, P1, P2, P3, P4) do { \
+	if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F, P1, P2, P3, P4)) \
+		return 4; \
+} while (0)
+
 class AdlEngine : public Engine {
 friend class Console;
 public:
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index cc38beb..a682c29 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -193,6 +193,8 @@ void AdlEngine_v2::printString(const Common::String &str) {
 }
 
 int AdlEngine_v2::o2_isFirstTime(ScriptEnv &e) {
+	OP_DEBUG_0("\t&& IS_FIRST_TIME()");
+
 	bool oldFlag = getCurRoom().isFirstTime;
 
 	getCurRoom().isFirstTime = false;
@@ -204,6 +206,8 @@ int AdlEngine_v2::o2_isFirstTime(ScriptEnv &e) {
 }
 
 int AdlEngine_v2::o2_isRandomGT(ScriptEnv &e) {
+	OP_DEBUG_1("\t&& RAND() > %d", e.arg(1));
+
 	byte rnd = _random->getRandomNumber(255);
 
 	if (rnd > e.arg(1))
@@ -213,6 +217,8 @@ int AdlEngine_v2::o2_isRandomGT(ScriptEnv &e) {
 }
 
 int AdlEngine_v2::o2_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;
 
 	for (item = _state.items.begin(); item != _state.items.end(); ++item)
@@ -223,6 +229,8 @@ int AdlEngine_v2::o2_isNounNotInRoom(ScriptEnv &e) {
 }
 
 int AdlEngine_v2::o2_isCarryingSomething(ScriptEnv &e) {
+	OP_DEBUG_0("\t&& IS_CARRYING_SOMETHING()");
+
 	Common::List<Item>::const_iterator item;
 
 	for (item = _state.items.begin(); item != _state.items.end(); ++item)
@@ -232,6 +240,8 @@ int AdlEngine_v2::o2_isCarryingSomething(ScriptEnv &e) {
 }
 
 int AdlEngine_v2::o2_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));
@@ -245,6 +255,8 @@ int AdlEngine_v2::o2_moveItem(ScriptEnv &e) {
 }
 
 int AdlEngine_v2::o2_moveAllItems(ScriptEnv &e) {
+	OP_DEBUG_2("\tMOVE_ALL_ITEMS(%d %d)", roomStr(e.arg(1)), roomStr(e.arg(2)));
+
 	byte room1 = roomArg(e.arg(1));
 	byte room2 = roomArg(e.arg(2));
 
@@ -261,6 +273,8 @@ int AdlEngine_v2::o2_moveAllItems(ScriptEnv &e) {
 }
 
 int AdlEngine_v2::o2_save(ScriptEnv &e) {
+	OP_DEBUG_0("\tSAVE_GAME()");
+
 	int slot = askForSlot(_strings_v2.saveInsert);
 
 	if (slot < 0)
@@ -274,6 +288,8 @@ int AdlEngine_v2::o2_save(ScriptEnv &e) {
 }
 
 int AdlEngine_v2::o2_restore(ScriptEnv &e) {
+	OP_DEBUG_0("\tRESTORE_GAME()");
+
 	int slot = askForSlot(_strings_v2.restoreInsert);
 
 	if (slot < 0)
@@ -288,6 +304,8 @@ int AdlEngine_v2::o2_restore(ScriptEnv &e) {
 }
 
 int AdlEngine_v2::o2_placeItem(ScriptEnv &e) {
+	OP_DEBUG_4("\tPLACE_ITEM(%s, %s, (%d, %d))", itemStr(e.arg(1)).c_str(), itemRoomStr(e.arg(2)).c_str(), e.arg(3), e.arg(4));
+
 	Item &item = getItem(e.arg(1));
 
 	item.room = roomArg(e.arg(2));
@@ -299,6 +317,8 @@ int AdlEngine_v2::o2_placeItem(ScriptEnv &e) {
 }
 
 int AdlEngine_v2::o2_tellTime(ScriptEnv &e) {
+	OP_DEBUG_0("\tTELL_TIME()");
+
 	Common::String time = _strings_v2.time;
 
 	time.setChar(APPLECHAR('0') + _state.time.hours / 10, 12);
@@ -312,12 +332,15 @@ int AdlEngine_v2::o2_tellTime(ScriptEnv &e) {
 }
 
 int AdlEngine_v2::o2_setRoomFromVar(ScriptEnv &e) {
+	OP_DEBUG_1("\tROOM = VAR[%d]", e.arg(1));
 	getCurRoom().curPicture = getCurRoom().picture;
 	_state.room = getVar(e.arg(1));
 	return 1;
 }
 
 int AdlEngine_v2::o2_initDisk(ScriptEnv &e) {
+	OP_DEBUG_0("\tINIT_DISK()");
+
 	_display->printAsciiString("NOT REQUIRED\r");
 	return 0;
 }
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 3906021..40bd40a 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -28,8 +28,6 @@
 // Note: this version of ADL redraws only when necessary, but
 // this is not currently implemented.
 
-#define IDI_CUR_ROOM 0xfc
-
 namespace Common{
 class RandomSource;
 }
diff --git a/engines/adl/console.cpp b/engines/adl/console.cpp
index 53e452a..d690524 100644
--- a/engines/adl/console.cpp
+++ b/engines/adl/console.cpp
@@ -78,6 +78,19 @@ bool Console::Cmd_DumpScripts(int argc, const char **argv) {
 
 	_engine->_dumpFile = new Common::DumpFile();
 
+	Common::Array<Room>::const_iterator room;
+	byte roomNr = 1;
+	for (room = _engine->_state.rooms.begin(); room != _engine->_state.rooms.end(); ++room) {
+		_engine->loadRoom(roomNr);
+		if (_engine->_roomData.commands.size() != 0) {
+			_engine->_dumpFile->open(Common::String::format("%03d.ADL", roomNr).c_str());
+			_engine->doAllCommands(_engine->_roomData.commands, IDI_ANY, IDI_ANY);
+			_engine->_dumpFile->close();
+		}
+		++roomNr;
+	}
+	_engine->loadRoom(_engine->_state.room);
+
 	_engine->_dumpFile->open("GLOBAL.ADL");
 	_engine->doAllCommands(_engine->_globalCommands, IDI_ANY, IDI_ANY);
 	_engine->_dumpFile->close();
diff --git a/engines/adl/console.h b/engines/adl/console.h
index 86538de..e007e09 100644
--- a/engines/adl/console.h
+++ b/engines/adl/console.h
@@ -42,7 +42,6 @@ public:
 	static Common::String toAscii(const Common::String &str);
 
 private:
-	bool Cmd_Help(int argc, const char **argv);
 	bool Cmd_Nouns(int argc, const char **argv);
 	bool Cmd_Verbs(int argc, const char **argv);
 	bool Cmd_DumpScripts(int argc, const char **argv);


Commit: 3b72a30c0f32e5b7342f04be086826354525cb24
    https://github.com/scummvm/scummvm/commit/3b72a30c0f32e5b7342f04be086826354525cb24
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Clean up script dump debug command

Changed paths:
    engines/adl/console.cpp



diff --git a/engines/adl/console.cpp b/engines/adl/console.cpp
index d690524..185fb42 100644
--- a/engines/adl/console.cpp
+++ b/engines/adl/console.cpp
@@ -78,16 +78,13 @@ bool Console::Cmd_DumpScripts(int argc, const char **argv) {
 
 	_engine->_dumpFile = new Common::DumpFile();
 
-	Common::Array<Room>::const_iterator room;
-	byte roomNr = 1;
-	for (room = _engine->_state.rooms.begin(); room != _engine->_state.rooms.end(); ++room) {
+	for (byte roomNr = 1; roomNr <= _engine->_state.rooms.size(); ++roomNr) {
 		_engine->loadRoom(roomNr);
 		if (_engine->_roomData.commands.size() != 0) {
 			_engine->_dumpFile->open(Common::String::format("%03d.ADL", roomNr).c_str());
 			_engine->doAllCommands(_engine->_roomData.commands, IDI_ANY, IDI_ANY);
 			_engine->_dumpFile->close();
 		}
-		++roomNr;
 	}
 	_engine->loadRoom(_engine->_state.room);
 


Commit: dd5ce7ebbbc5dd9814a7b1078856f86de1c457cf
    https://github.com/scummvm/scummvm/commit/dd5ce7ebbbc5dd9814a7b1078856f86de1c457cf
Author: Alyssa Milburn (fuzzie at fuzzie.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Add valid_cmds debug command

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/console.cpp
    engines/adl/console.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 0c27f8b..1b6bf6a 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -292,6 +292,28 @@ void AdlEngine::checkInput(byte verb, byte noun) {
 		printMessage(_messageIds.dontUnderstand);
 }
 
+bool AdlEngine::isInputValid(byte verb, byte noun, bool &is_any) {
+	if (isInputValid(_roomData.commands, verb, noun, is_any))
+		return true;
+	return isInputValid(_roomCommands, verb, noun, is_any);
+}
+
+bool AdlEngine::isInputValid(const Commands &commands, byte verb, byte noun, bool &is_any) {
+	Commands::const_iterator cmd;
+
+	is_any = false;
+	for (cmd = commands.begin(); cmd != commands.end(); ++cmd) {
+		ScriptEnv env(*cmd, _state.room, verb, noun);
+		if (matchCommand(env)) {
+			if (cmd->verb == IDI_ANY || cmd->noun == IDI_ANY)
+				is_any = true;
+			return true;
+		}
+	}
+
+	return false;
+}
+
 typedef Common::Functor1Mem<ScriptEnv &, int, AdlEngine> OpcodeV1;
 #define SetOpcodeTable(x) table = &x;
 #define Opcode(x) table->push_back(new OpcodeV1(this, &AdlEngine::x))
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index ac5e22c..18b57ed 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -234,6 +234,8 @@ protected:
 	void loadWords(Common::ReadStream &stream, WordMap &map, Common::StringArray &pri) const;
 	void readCommands(Common::ReadStream &stream, Commands &commands);
 	void checkInput(byte verb, byte noun);
+	virtual bool isInputValid(byte verb, byte noun, bool &is_any);
+	virtual bool isInputValid(const Commands &commands, byte verb, byte noun, bool &is_any);
 
 	virtual void setupOpcodeTables();
 	virtual bool matchesCurrentPic(byte pic) const;
diff --git a/engines/adl/console.cpp b/engines/adl/console.cpp
index 185fb42..003f689 100644
--- a/engines/adl/console.cpp
+++ b/engines/adl/console.cpp
@@ -33,6 +33,7 @@ Console::Console(AdlEngine *engine) : GUI::Debugger() {
 	registerCmd("nouns", WRAP_METHOD(Console, Cmd_Nouns));
 	registerCmd("verbs", WRAP_METHOD(Console, Cmd_Verbs));
 	registerCmd("dump_scripts", WRAP_METHOD(Console, Cmd_DumpScripts));
+	registerCmd("valid_cmds", WRAP_METHOD(Console, Cmd_ValidCommands));
 }
 
 Common::String Console::toAscii(const Common::String &str) {
@@ -66,6 +67,29 @@ bool Console::Cmd_Nouns(int argc, const char **argv) {
 	return true;
 }
 
+bool Console::Cmd_ValidCommands(int argc, const char **argv) {
+	if (argc != 1) {
+		debugPrintf("Usage: %s\n", argv[0]);
+		return true;
+	}
+
+	WordMap::const_iterator verb, noun;
+	bool is_any;
+
+	for (verb = _engine->_verbs.begin(); verb != _engine->_verbs.end(); ++verb) {
+		for (noun = _engine->_nouns.begin(); noun != _engine->_nouns.end(); ++noun) {
+			if (_engine->isInputValid(verb->_value, noun->_value, is_any) && !is_any)
+				debugPrintf("%s %s\n", toAscii(verb->_key).c_str(), toAscii(noun->_key).c_str());
+		}
+		if (_engine->isInputValid(verb->_value, IDI_ANY, is_any))
+			debugPrintf("%s *\n", toAscii(verb->_key).c_str());
+	}
+	if (_engine->isInputValid(IDI_ANY, IDI_ANY, is_any))
+		debugPrintf("* *\n");
+
+	return true;
+}
+
 bool Console::Cmd_DumpScripts(int argc, const char **argv) {
 	if (argc != 1) {
 		debugPrintf("Usage: %s\n", argv[0]);
diff --git a/engines/adl/console.h b/engines/adl/console.h
index e007e09..bfe09a1 100644
--- a/engines/adl/console.h
+++ b/engines/adl/console.h
@@ -45,6 +45,7 @@ private:
 	bool Cmd_Nouns(int argc, const char **argv);
 	bool Cmd_Verbs(int argc, const char **argv);
 	bool Cmd_DumpScripts(int argc, const char **argv);
+	bool Cmd_ValidCommands(int argc, const char **argv);
 
 	void printWordMap(const Common::HashMap<Common::String, uint> &wordMap);
 


Commit: 3b7813d971feb8ac8292ffb7ddf014ead6f5bf36
    https://github.com/scummvm/scummvm/commit/3b7813d971feb8ac8292ffb7ddf014ead6f5bf36
Author: Alyssa Milburn (fuzzie at fuzzie.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Fix debug print for MOVE_ALL_ITEMS

Changed paths:
    engines/adl/adl_v2.cpp



diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index a682c29..51ea4ec 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -255,7 +255,7 @@ int AdlEngine_v2::o2_moveItem(ScriptEnv &e) {
 }
 
 int AdlEngine_v2::o2_moveAllItems(ScriptEnv &e) {
-	OP_DEBUG_2("\tMOVE_ALL_ITEMS(%d %d)", roomStr(e.arg(1)), roomStr(e.arg(2)));
+	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));
 	byte room2 = roomArg(e.arg(2));


Commit: 26b8e8d66a0039281ec3b8fe8d2f29efed37fda2
    https://github.com/scummvm/scummvm/commit/26b8e8d66a0039281ec3b8fe8d2f29efed37fda2
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Use columns when printing verb/noun lists

Changed paths:
    engines/adl/console.cpp



diff --git a/engines/adl/console.cpp b/engines/adl/console.cpp
index 003f689..9653466 100644
--- a/engines/adl/console.cpp
+++ b/engines/adl/console.cpp
@@ -134,13 +134,11 @@ void Console::printWordMap(const WordMap &wordMap) {
 	WordMap::const_iterator verb;
 
 	for (verb = wordMap.begin(); verb != wordMap.end(); ++verb)
-		words.push_back(verb->_key);
+		words.push_back(Common::String::format("%s: %3d", toAscii(verb->_key).c_str(), wordMap[verb->_key]));
 
 	Common::sort(words.begin(), words.end());
 
-	Common::StringArray::const_iterator word;
-	for (word = words.begin(); word != words.end(); ++word)
-		debugPrintf("%s: %d\n", toAscii(*word).c_str(), wordMap[*word]);
+	debugPrintColumns(words);
 }
 
 } // End of namespace Adl


Commit: 9eb7af0f671d6b172c838666f423a3be5eaeae09
    https://github.com/scummvm/scummvm/commit/9eb7af0f671d6b172c838666f423a3be5eaeae09
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Add 'room' debugger command

Changed paths:
    engines/adl/console.cpp
    engines/adl/console.h



diff --git a/engines/adl/console.cpp b/engines/adl/console.cpp
index 9653466..e162597 100644
--- a/engines/adl/console.cpp
+++ b/engines/adl/console.cpp
@@ -23,6 +23,7 @@
 #include "common/debug-channels.h"
 
 #include "adl/console.h"
+#include "adl/display.h"
 #include "adl/adl.h"
 
 namespace Adl {
@@ -34,6 +35,7 @@ Console::Console(AdlEngine *engine) : GUI::Debugger() {
 	registerCmd("verbs", WRAP_METHOD(Console, Cmd_Verbs));
 	registerCmd("dump_scripts", WRAP_METHOD(Console, Cmd_DumpScripts));
 	registerCmd("valid_cmds", WRAP_METHOD(Console, Cmd_ValidCommands));
+	registerCmd("room", WRAP_METHOD(Console, Cmd_Room));
 }
 
 Common::String Console::toAscii(const Common::String &str) {
@@ -129,6 +131,38 @@ bool Console::Cmd_DumpScripts(int argc, const char **argv) {
 	return true;
 }
 
+bool Console::Cmd_Room(int argc, const char **argv) {
+	if (argc > 2) {
+		debugPrintf("Usage: %s [<new_room>]\n", argv[0]);
+		return true;
+	}
+
+	if (argc == 2) {
+		if (!_engine->_canRestoreNow) {
+			debugPrintf("Cannot change rooms right now\n");
+			return true;
+		}
+
+		int roomCount = _engine->_state.rooms.size();
+		int room = strtoul(argv[1], NULL, 0);
+		if (room < 1 || room > roomCount) {
+			debugPrintf("Room %i out of valid range [1, %d]\n", room, roomCount);
+			return true;
+		}
+
+		_engine->_state.room = room;
+		_engine->clearScreen();
+		_engine->loadRoom(_engine->_state.room);
+		_engine->showRoom();
+		_engine->_display->updateTextScreen();
+		_engine->_display->updateHiResScreen();
+	}
+
+	debugPrintf("Current room: %d\n", _engine->_state.room);
+
+	return true;
+}
+
 void Console::printWordMap(const WordMap &wordMap) {
 	Common::StringArray words;
 	WordMap::const_iterator verb;
diff --git a/engines/adl/console.h b/engines/adl/console.h
index bfe09a1..8af23b9 100644
--- a/engines/adl/console.h
+++ b/engines/adl/console.h
@@ -46,6 +46,7 @@ private:
 	bool Cmd_Verbs(int argc, const char **argv);
 	bool Cmd_DumpScripts(int argc, const char **argv);
 	bool Cmd_ValidCommands(int argc, const char **argv);
+	bool Cmd_Room(int argc, const char **argv);
 
 	void printWordMap(const Common::HashMap<Common::String, uint> &wordMap);
 


Commit: fde2db9d4c09d4318d9dbc409044838d456693a6
    https://github.com/scummvm/scummvm/commit/fde2db9d4c09d4318d9dbc409044838d456693a6
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Add items and give_item debug commands

Changed paths:
    engines/adl/console.cpp
    engines/adl/console.h



diff --git a/engines/adl/console.cpp b/engines/adl/console.cpp
index e162597..377909c 100644
--- a/engines/adl/console.cpp
+++ b/engines/adl/console.cpp
@@ -36,6 +36,8 @@ Console::Console(AdlEngine *engine) : GUI::Debugger() {
 	registerCmd("dump_scripts", WRAP_METHOD(Console, Cmd_DumpScripts));
 	registerCmd("valid_cmds", WRAP_METHOD(Console, Cmd_ValidCommands));
 	registerCmd("room", WRAP_METHOD(Console, Cmd_Room));
+	registerCmd("items", WRAP_METHOD(Console, Cmd_Items));
+	registerCmd("give_item", WRAP_METHOD(Console, Cmd_GiveItem));
 }
 
 Common::String Console::toAscii(const Common::String &str) {
@@ -163,6 +165,103 @@ bool Console::Cmd_Room(int argc, const char **argv) {
 	return true;
 }
 
+bool Console::Cmd_Items(int argc, const char **argv) {
+	if (argc != 1) {
+		debugPrintf("Usage: %s\n", argv[0]);
+		return true;
+	}
+
+	Common::List<Item>::const_iterator item;
+
+	for (item = _engine->_state.items.begin(); item != _engine->_state.items.end(); ++item)
+		printItem(*item);
+
+	return true;
+}
+
+bool Console::Cmd_GiveItem(int argc, const char **argv) {
+	if (argc != 2) {
+		debugPrintf("Usage: %s <ID | name>\n", argv[0]);
+		return true;
+	}
+
+	Common::List<Item>::iterator item;
+
+	char *end;
+	int id = strtoul(argv[1], &end, 0);
+
+	if (*end != 0) {
+		Common::Array<Item *> matches;
+
+		Common::String searchName(argv[1]);
+		searchName.toUppercase();
+		while (searchName.size() < IDI_WORD_SIZE)
+			searchName += ' ';
+
+		for (item = _engine->_state.items.begin(); item != _engine->_state.items.end(); ++item) {
+			Common::String itemName;
+
+			if (item->noun > 0)
+				itemName = _engine->_priNouns[item->noun - 1];
+
+			if (itemName == searchName)
+				matches.push_back(&*item);
+		}
+
+		if (matches.size() == 0) {
+			debugPrintf("Item '%s' not found\n", argv[1]);
+			return true;
+		}
+
+		if (matches.size() > 1) {
+			debugPrintf("Multiple matches found, please use item ID:\n");
+			for (uint i = 0; i < matches.size(); ++i)
+				printItem(*matches[i]);
+			return true;
+		}
+
+		matches[0]->room = IDI_ANY;
+		debugPrintf("OK\n");
+		return true;
+	}
+
+	for (item = _engine->_state.items.begin(); item != _engine->_state.items.end(); ++item)
+		if (item->id == id) {
+			item->room = IDI_ANY;
+			debugPrintf("OK\n");
+			return true;
+		}
+
+	debugPrintf("Item %i not found\n", id);
+	return true;
+}
+
+void Console::printItem(const Item &item) {
+	Common::String name, desc, state;
+
+	if (item.noun > 0)
+		name = _engine->_priNouns[item.noun - 1];
+
+	if (item.description > 0) {
+		desc = toAscii(_engine->_messages[item.description - 1]);
+		desc.deleteLastChar();
+	}
+
+	switch (item.state) {
+	case IDI_ITEM_NOT_MOVED:
+		state = "PLACED";
+		break;
+	case IDI_ITEM_DROPPED:
+		state = "DROPPED";
+		break;
+	case IDI_ITEM_DOESNT_MOVE:
+		state = "FIXED";
+		break;
+	}
+
+	debugPrintf("%3d %s %-30s %-10s %-8s (%3d, %3d)\n", item.id, name.c_str(), desc.c_str(), _engine->itemRoomStr(item.room).c_str(), state.c_str(), item.position.x, item.position.y);
+}
+
 void Console::printWordMap(const WordMap &wordMap) {
 	Common::StringArray words;
 	WordMap::const_iterator verb;
diff --git a/engines/adl/console.h b/engines/adl/console.h
index 8af23b9..a1b692d 100644
--- a/engines/adl/console.h
+++ b/engines/adl/console.h
@@ -34,6 +34,7 @@ class String;
 namespace Adl {
 
 class AdlEngine;
+struct Item;
 
 class Console : public GUI::Debugger {
 public:
@@ -47,7 +48,10 @@ private:
 	bool Cmd_DumpScripts(int argc, const char **argv);
 	bool Cmd_ValidCommands(int argc, const char **argv);
 	bool Cmd_Room(int argc, const char **argv);
+	bool Cmd_Items(int argc, const char **argv);
+	bool Cmd_GiveItem(int argc, const char **argv);
 
+	void printItem(const Item &item);
 	void printWordMap(const Common::HashMap<Common::String, uint> &wordMap);
 
 	AdlEngine *_engine;


Commit: 23d4e61260f96cf3aa5104649a3a4f7b72c7df78
    https://github.com/scummvm/scummvm/commit/23d4e61260f96cf3aa5104649a3a4f7b72c7df78
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Fix hires2 item description debug printing

Changed paths:
    engines/adl/console.cpp



diff --git a/engines/adl/console.cpp b/engines/adl/console.cpp
index 377909c..1a670b7 100644
--- a/engines/adl/console.cpp
+++ b/engines/adl/console.cpp
@@ -244,7 +244,8 @@ void Console::printItem(const Item &item) {
 
 	if (item.description > 0) {
 		desc = toAscii(_engine->_messages[item.description - 1]);
-		desc.deleteLastChar();
+		if (desc.lastChar() == '\r')
+			desc.deleteLastChar();
 	}
 
 	switch (item.state) {


Commit: 1d314b20841d78ebbce2652ec874fb131cf9cf36
    https://github.com/scummvm/scummvm/commit/1d314b20841d78ebbce2652ec874fb131cf9cf36
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Allow synonyms in give_item debug command

Changed paths:
    engines/adl/console.cpp
    engines/adl/console.h



diff --git a/engines/adl/console.cpp b/engines/adl/console.cpp
index 1a670b7..af16330 100644
--- a/engines/adl/console.cpp
+++ b/engines/adl/console.cpp
@@ -49,6 +49,22 @@ Common::String Console::toAscii(const Common::String &str) {
 	return ascii;
 }
 
+Common::String Console::toAppleWord(const Common::String &str) {
+	Common::String apple(str);
+
+	if (apple.size() > IDI_WORD_SIZE)
+		apple.erase(IDI_WORD_SIZE);
+	apple.toUppercase();
+
+	for (uint i = 0; i < apple.size(); ++i)
+		apple.setChar(APPLECHAR(apple[i]), i);
+
+	while (apple.size() < IDI_WORD_SIZE)
+		apple += APPLECHAR(' ');
+
+	return apple;
+}
+
 bool Console::Cmd_Verbs(int argc, const char **argv) {
 	if (argc != 1) {
 		debugPrintf("Usage: %s\n", argv[0]);
@@ -193,18 +209,17 @@ bool Console::Cmd_GiveItem(int argc, const char **argv) {
 	if (*end != 0) {
 		Common::Array<Item *> matches;
 
-		Common::String searchName(argv[1]);
-		searchName.toUppercase();
-		while (searchName.size() < IDI_WORD_SIZE)
-			searchName += ' ';
+		Common::String name = toAppleWord(argv[1]);
 
-		for (item = _engine->_state.items.begin(); item != _engine->_state.items.end(); ++item) {
-			Common::String itemName;
+		if (!_engine->_nouns.contains(name)) {
+			debugPrintf("Item '%s' not found\n", argv[1]);
+			return true;
+		}
 
-			if (item->noun > 0)
-				itemName = _engine->_priNouns[item->noun - 1];
+		byte noun = _engine->_nouns[name];
 
-			if (itemName == searchName)
+		for (item = _engine->_state.items.begin(); item != _engine->_state.items.end(); ++item) {
+			if (item->noun == noun)
 				matches.push_back(&*item);
 		}
 
diff --git a/engines/adl/console.h b/engines/adl/console.h
index a1b692d..ece9cd0 100644
--- a/engines/adl/console.h
+++ b/engines/adl/console.h
@@ -41,6 +41,7 @@ public:
 	Console(AdlEngine *engine);
 
 	static Common::String toAscii(const Common::String &str);
+	static Common::String toAppleWord(const Common::String &str);
 
 private:
 	bool Cmd_Nouns(int argc, const char **argv);


Commit: ff4b9fcd9c50204cf31703d56ec55164f5646ba4
    https://github.com/scummvm/scummvm/commit/ff4b9fcd9c50204cf31703d56ec55164f5646ba4
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Add 'vars' debug command

Changed paths:
    engines/adl/console.cpp
    engines/adl/console.h



diff --git a/engines/adl/console.cpp b/engines/adl/console.cpp
index af16330..94d0a73 100644
--- a/engines/adl/console.cpp
+++ b/engines/adl/console.cpp
@@ -38,6 +38,7 @@ Console::Console(AdlEngine *engine) : GUI::Debugger() {
 	registerCmd("room", WRAP_METHOD(Console, Cmd_Room));
 	registerCmd("items", WRAP_METHOD(Console, Cmd_Items));
 	registerCmd("give_item", WRAP_METHOD(Console, Cmd_GiveItem));
+	registerCmd("vars", WRAP_METHOD(Console, Cmd_Vars));
 }
 
 Common::String Console::toAscii(const Common::String &str) {
@@ -251,6 +252,22 @@ bool Console::Cmd_GiveItem(int argc, const char **argv) {
 	return true;
 }
 
+bool Console::Cmd_Vars(int argc, const char **argv) {
+	if (argc != 1) {
+		debugPrintf("Usage: %s\n", argv[0]);
+		return true;
+	}
+
+	Common::StringArray vars;
+	for (uint i = 0; i < _engine->_state.vars.size(); ++i)
+		vars.push_back(Common::String::format("%3d: %3d", i, _engine->_state.vars[i]));
+
+	debugPrintf("Variables:\n");
+	debugPrintColumns(vars);
+
+	return true;
+}
+
 void Console::printItem(const Item &item) {
 	Common::String name, desc, state;
 
diff --git a/engines/adl/console.h b/engines/adl/console.h
index ece9cd0..13f55fc 100644
--- a/engines/adl/console.h
+++ b/engines/adl/console.h
@@ -51,6 +51,7 @@ private:
 	bool Cmd_Room(int argc, const char **argv);
 	bool Cmd_Items(int argc, const char **argv);
 	bool Cmd_GiveItem(int argc, const char **argv);
+	bool Cmd_Vars(int argc, const char **argv);
 
 	void printItem(const Item &item);
 	void printWordMap(const Common::HashMap<Common::String, uint> &wordMap);


Commit: 1b9d712a8b68f75dcd7c22021b50fff1eeaec155
    https://github.com/scummvm/scummvm/commit/1b9d712a8b68f75dcd7c22021b50fff1eeaec155
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Add 'var' debug command

Changed paths:
    engines/adl/console.cpp
    engines/adl/console.h



diff --git a/engines/adl/console.cpp b/engines/adl/console.cpp
index 94d0a73..c62d21c 100644
--- a/engines/adl/console.cpp
+++ b/engines/adl/console.cpp
@@ -39,6 +39,7 @@ Console::Console(AdlEngine *engine) : GUI::Debugger() {
 	registerCmd("items", WRAP_METHOD(Console, Cmd_Items));
 	registerCmd("give_item", WRAP_METHOD(Console, Cmd_GiveItem));
 	registerCmd("vars", WRAP_METHOD(Console, Cmd_Vars));
+	registerCmd("var", WRAP_METHOD(Console, Cmd_Var));
 }
 
 Common::String Console::toAscii(const Common::String &str) {
@@ -162,10 +163,10 @@ bool Console::Cmd_Room(int argc, const char **argv) {
 			return true;
 		}
 
-		int roomCount = _engine->_state.rooms.size();
-		int room = strtoul(argv[1], NULL, 0);
+		uint roomCount = _engine->_state.rooms.size();
+		uint room = strtoul(argv[1], NULL, 0);
 		if (room < 1 || room > roomCount) {
-			debugPrintf("Room %i out of valid range [1, %d]\n", room, roomCount);
+			debugPrintf("Room %u out of valid range [1, %u]\n", room, roomCount);
 			return true;
 		}
 
@@ -177,7 +178,7 @@ bool Console::Cmd_Room(int argc, const char **argv) {
 		_engine->_display->updateHiResScreen();
 	}
 
-	debugPrintf("Current room: %d\n", _engine->_state.room);
+	debugPrintf("Current room: %u\n", _engine->_state.room);
 
 	return true;
 }
@@ -205,7 +206,7 @@ bool Console::Cmd_GiveItem(int argc, const char **argv) {
 	Common::List<Item>::iterator item;
 
 	char *end;
-	int id = strtoul(argv[1], &end, 0);
+	uint id = strtoul(argv[1], &end, 0);
 
 	if (*end != 0) {
 		Common::Array<Item *> matches;
@@ -268,6 +269,30 @@ bool Console::Cmd_Vars(int argc, const char **argv) {
 	return true;
 }
 
+bool Console::Cmd_Var(int argc, const char **argv) {
+	if (argc < 2 || argc > 3) {
+		debugPrintf("Usage: %s <index> [<value>]\n", argv[0]);
+		return true;
+	}
+
+	uint varCount = _engine->_state.vars.size();
+	uint var = strtoul(argv[1], NULL, 0);
+
+	if (var >= varCount) {
+		debugPrintf("Variable %u out of valid range [0, %u]\n", var, varCount - 1);
+		return true;
+	}
+
+	if (argc == 3) {
+		uint value = strtoul(argv[2], NULL, 0);
+		_engine->_state.vars[var] = value;
+	}
+
+	debugPrintf("%3d: %3d\n", var, _engine->_state.vars[var]);
+
+	return true;
+}
+
 void Console::printItem(const Item &item) {
 	Common::String name, desc, state;
 
diff --git a/engines/adl/console.h b/engines/adl/console.h
index 13f55fc..a8c6adc 100644
--- a/engines/adl/console.h
+++ b/engines/adl/console.h
@@ -52,6 +52,7 @@ private:
 	bool Cmd_Items(int argc, const char **argv);
 	bool Cmd_GiveItem(int argc, const char **argv);
 	bool Cmd_Vars(int argc, const char **argv);
+	bool Cmd_Var(int argc, const char **argv);
 
 	void printItem(const Item &item);
 	void printWordMap(const Common::HashMap<Common::String, uint> &wordMap);


Commit: d6f34eda997ef5ace7078ac6d944ac505bb2a35d
    https://github.com/scummvm/scummvm/commit/d6f34eda997ef5ace7078ac6d944ac505bb2a35d
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Remove DataBlockPtr::isValid()

Changed paths:
    engines/adl/disk.h
    engines/adl/hires2.cpp



diff --git a/engines/adl/disk.h b/engines/adl/disk.h
index 12801ec..4cab81d 100644
--- a/engines/adl/disk.h
+++ b/engines/adl/disk.h
@@ -38,7 +38,6 @@ class DataBlock {
 public:
 	virtual ~DataBlock() { }
 
-	virtual bool isValid() const = 0;
 	virtual Common::SeekableReadStream *createReadStream() const = 0;
 };
 
@@ -60,10 +59,6 @@ protected:
 				_filename(filename),
 				_offset(offset) { }
 
-		bool isValid() const {
-			return true;
-		}
-
 		Common::SeekableReadStream *createReadStream() const {
 			return _files->createReadStream(_filename, _offset);
 		}
@@ -102,10 +97,6 @@ protected:
 				_size(size),
 				_disk(disk) { }
 
-		bool isValid() const {
-			return _track != 0 || _sector != 0 || _offset != 0 || _size != 0;
-		}
-
 		Common::SeekableReadStream *createReadStream() const {
 			return _disk->createReadStream(_track, _sector, _offset, _size);
 		}
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 4ac8e88..70b98b9 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -42,6 +42,9 @@ DataBlockPtr HiRes2Engine::readDataBlockPtr(Common::ReadStream &f) const {
 	if (f.eos() || f.err())
 		error("Error reading DataBlockPtr");
 
+	if (track == 0 && sector == 0 && offset == 0 && size == 0)
+		return DataBlockPtr();
+
 	return _disk.getDataBlock(track, sector, offset, size);
 }
 
@@ -70,7 +73,7 @@ void HiRes2Engine::init() {
 	for (uint i = 0; i < IDI_HR2_NUM_MESSAGES; ++i) {
 		DataBlockPtr str(readDataBlockPtr(*stream));
 
-		if (str->isValid()) {
+		if (str) {
 			StreamPtr strStream(str->createReadStream());
 			_messages.push_back(readString(*strStream, 0xff));
 		} else {


Commit: f275add1e53dbbc19de8c0fd6f181456a07bfa92
    https://github.com/scummvm/scummvm/commit/f275add1e53dbbc19de8c0fd6f181456a07bfa92
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Use pointer for hires2 disk image

Changed paths:
    engines/adl/adl_v2.cpp
    engines/adl/adl_v2.h
    engines/adl/hires2.cpp
    engines/adl/hires2.h



diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 51ea4ec..8fcb45a 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -30,11 +30,13 @@ namespace Adl {
 
 AdlEngine_v2::~AdlEngine_v2() {
 	delete _random;
+	delete _disk;
 }
 
 AdlEngine_v2::AdlEngine_v2(OSystem *syst, const AdlGameDescription *gd) :
 		AdlEngine(syst, gd),
-		_linesPrinted(0) {
+		_linesPrinted(0),
+		_disk(nullptr) {
 	_random = new Common::RandomSource("adl");
 }
 
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 40bd40a..66dbcf3 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -71,6 +71,7 @@ protected:
 	} _strings_v2;
 
 	uint _linesPrinted;
+	DiskImage *_disk;
 
 private:
 	int askForSlot(const Common::String &question);
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 70b98b9..4d18b2e 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -45,11 +45,11 @@ DataBlockPtr HiRes2Engine::readDataBlockPtr(Common::ReadStream &f) const {
 	if (track == 0 && sector == 0 && offset == 0 && size == 0)
 		return DataBlockPtr();
 
-	return _disk.getDataBlock(track, sector, offset, size);
+	return _disk->getDataBlock(track, sector, offset, size);
 }
 
 void HiRes2Engine::runIntro() const {
-	StreamPtr stream(_disk.createReadStream(0x00, 0xd, 0x17, 1));
+	StreamPtr stream(_disk->createReadStream(0x00, 0xd, 0x17, 1));
 
 	_display->setMode(DISPLAY_MODE_TEXT);
 
@@ -65,10 +65,11 @@ void HiRes2Engine::runIntro() const {
 void HiRes2Engine::init() {
 	_graphics = new Graphics_v2(*_display);
 
-	if (!_disk.open(IDS_HR2_DISK_IMAGE))
+	_disk = new DiskImage_DSK();
+	if (!_disk->open(IDS_HR2_DISK_IMAGE))
 		error("Failed to open disk image '" IDS_HR2_DISK_IMAGE "'");
 
-	StreamPtr stream(_disk.createReadStream(0x1f, 0x2, 0x04, 4));
+	StreamPtr stream(_disk->createReadStream(0x1f, 0x2, 0x04, 4));
 
 	for (uint i = 0; i < IDI_HR2_NUM_MESSAGES; ++i) {
 		DataBlockPtr str(readDataBlockPtr(*stream));
@@ -82,17 +83,17 @@ void HiRes2Engine::init() {
 	}
 
 	// Read parser messages
-	stream.reset(_disk.createReadStream(0x1a, 0x1));
+	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));
+	stream.reset(_disk->createReadStream(0x19, 0x7, 0xd7));
 	_strings_v2.time = readString(*stream, 0xff);
 
 	// Read opcode strings
-	stream.reset(_disk.createReadStream(0x1a, 0x6, 0x00, 2));
+	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);
@@ -107,7 +108,7 @@ void HiRes2Engine::init() {
 	_messageIds.thanksForPlaying = IDI_HR2_MSG_THANKS_FOR_PLAYING;
 
 	// Load global picture data
-	stream.reset(_disk.createReadStream(0x19, 0xa, 0x80, 0));
+	stream.reset(_disk->createReadStream(0x19, 0xa, 0x80, 0));
 	byte picNr;
 	while ((picNr = stream->readByte()) != 0xff) {
 		if (stream->eos() || stream->err())
@@ -117,21 +118,21 @@ void HiRes2Engine::init() {
 	}
 
 	// Load item picture data
-	stream.reset(_disk.createReadStream(0x1e, 0x9, 0x05));
+	stream.reset(_disk->createReadStream(0x1e, 0x9, 0x05));
 	for (uint i = 0; i < IDI_HR2_NUM_ITEM_PICS; ++i) {
 		stream->readByte(); // number
 		_itemPics.push_back(readDataBlockPtr(*stream));
 	}
 
 	// Load commands from executable
-	stream.reset(_disk.createReadStream(0x1d, 0x7, 0x00, 4));
+	stream.reset(_disk->createReadStream(0x1d, 0x7, 0x00, 4));
 	readCommands(*stream, _roomCommands);
 
-	stream.reset(_disk.createReadStream(0x1f, 0x7, 0x00, 2));
+	stream.reset(_disk->createReadStream(0x1f, 0x7, 0x00, 2));
 	readCommands(*stream, _globalCommands);
 
 	// Load dropped item offsets
-	stream.reset(_disk.createReadStream(0x1b, 0x4, 0x15));
+	stream.reset(_disk->createReadStream(0x1b, 0x4, 0x15));
 	for (uint i = 0; i < IDI_HR2_NUM_ITEM_OFFSETS; ++i) {
 		Common::Point p;
 		p.x = stream->readByte();
@@ -140,11 +141,11 @@ void HiRes2Engine::init() {
 	}
 
 	// Load verbs
-	stream.reset(_disk.createReadStream(0x19, 0x0, 0x00, 3));
+	stream.reset(_disk->createReadStream(0x19, 0x0, 0x00, 3));
 	loadWords(*stream, _verbs, _priVerbs);
 
 	// Load nouns
-	stream.reset(_disk.createReadStream(0x22, 0x2, 0x00, 7));
+	stream.reset(_disk->createReadStream(0x22, 0x2, 0x00, 7));
 	loadWords(*stream, _nouns, _priNouns);
 }
 
@@ -152,7 +153,7 @@ void HiRes2Engine::initState() {
 	_state.vars.clear();
 	_state.vars.resize(IDI_HR2_NUM_VARS);
 
-	StreamPtr stream(_disk.createReadStream(0x21, 0x5, 0x0e, 7));
+	StreamPtr stream(_disk->createReadStream(0x21, 0x5, 0x0e, 7));
 
 	_state.rooms.clear();
 	for (uint i = 0; i < IDI_HR2_NUM_ROOMS; ++i) {
@@ -167,7 +168,7 @@ void HiRes2Engine::initState() {
 		_state.rooms.push_back(room);
 	}
 
-	stream.reset(_disk.createReadStream(0x21, 0x0, 0x00, 2));
+	stream.reset(_disk->createReadStream(0x21, 0x0, 0x00, 2));
 
 	_state.items.clear();
 	byte id;
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index c99c0b0..b8212e0 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -66,7 +66,6 @@ private:
 
 	DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const;
 
-	DiskImage_DSK _disk;
 	Common::Array<DataBlockPtr> _itemPics;
 };
 


Commit: 4ee8cf4f9ea79c9bfcab00b39f26675fc0db2588
    https://github.com/scummvm/scummvm/commit/4ee8cf4f9ea79c9bfcab00b39f26675fc0db2588
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Move some hires2 functionality into ADL_v2

Changed paths:
    engines/adl/adl_v2.cpp
    engines/adl/adl_v2.h
    engines/adl/hires2.cpp
    engines/adl/hires2.h



diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 8fcb45a..8b7a623 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -25,6 +25,7 @@
 
 #include "adl/adl_v2.h"
 #include "adl/display.h"
+#include "adl/graphics.h"
 
 namespace Adl {
 
@@ -194,6 +195,61 @@ void AdlEngine_v2::printString(const Common::String &str) {
 	_display->updateTextScreen();
 }
 
+void AdlEngine_v2::drawItem(const Item &item, const Common::Point &pos) const {
+	StreamPtr stream(_itemPics[item.picture - 1]->createReadStream());
+	stream->readByte(); // Skip clear opcode
+	_graphics->drawPic(*stream, pos);
+}
+
+void AdlEngine_v2::loadRoom(byte roomNr) {
+	Room &room = getRoom(roomNr);
+	StreamPtr stream(room.data->createReadStream());
+
+	uint16 descOffset = stream->readUint16LE();
+	uint16 commandOffset = stream->readUint16LE();
+
+	_roomData.pictures.clear();
+	// There's no picture count. The original engine always checks at most
+	// five pictures. We use the description offset to bound our search.
+	uint16 picCount = (descOffset - 4) / 5;
+
+	for (uint i = 0; i < picCount; ++i) {
+		byte nr = stream->readByte();
+		_roomData.pictures[nr] = readDataBlockPtr(*stream);
+	}
+
+	_roomData.description = readStringAt(*stream, descOffset, 0xff);
+
+	_roomData.commands.clear();
+	if (commandOffset != 0) {
+		stream->seek(commandOffset);
+		readCommands(*stream, _roomData.commands);
+	}
+}
+
+void AdlEngine_v2::showRoom() {
+	drawPic(getCurRoom().curPicture, Common::Point());
+	drawItems();
+	_display->updateHiResScreen();
+	printString(_roomData.description);
+	_linesPrinted = 0;
+}
+
+DataBlockPtr AdlEngine_v2::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();
+
+	return _disk->getDataBlock(track, sector, offset, size);
+}
+
 int AdlEngine_v2::o2_isFirstTime(ScriptEnv &e) {
 	OP_DEBUG_0("\t&& IS_FIRST_TIME()");
 
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 66dbcf3..c8dc189 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -47,6 +47,11 @@ protected:
 	byte roomArg(byte room) const;
 	void advanceClock();
 	void printString(const Common::String &str);
+	void drawItem(const Item &item, const Common::Point &pos) const;
+	void loadRoom(byte roomNr);
+	void showRoom();
+
+	DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const;
 
 	void checkTextOverflow(char c);
 
@@ -72,6 +77,7 @@ protected:
 
 	uint _linesPrinted;
 	DiskImage *_disk;
+	Common::Array<DataBlockPtr> _itemPics;
 
 private:
 	int askForSlot(const Common::String &question);
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 4d18b2e..a1303b6 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -33,21 +33,6 @@
 
 namespace Adl {
 
-DataBlockPtr HiRes2Engine::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();
-
-	return _disk->getDataBlock(track, sector, offset, size);
-}
-
 void HiRes2Engine::runIntro() const {
 	StreamPtr stream(_disk->createReadStream(0x00, 0xd, 0x17, 1));
 
@@ -202,46 +187,6 @@ void HiRes2Engine::restartGame() {
 	initState();
 }
 
-void HiRes2Engine::drawItem(const Item &item, const Common::Point &pos) const {
-	StreamPtr stream(_itemPics[item.picture - 1]->createReadStream());
-	stream->readByte(); // Skip clear opcode
-	_graphics->drawPic(*stream, pos);
-}
-
-void HiRes2Engine::loadRoom(byte roomNr) {
-	Room &room = getRoom(roomNr);
-	StreamPtr stream(room.data->createReadStream());
-
-	uint16 descOffset = stream->readUint16LE();
-	uint16 commandOffset = stream->readUint16LE();
-
-	_roomData.pictures.clear();
-	// There's no picture count. The original engine always checks at most
-	// five pictures. We use the description offset to bound our search.
-	uint16 picCount = (descOffset - 4) / 5;
-
-	for (uint i = 0; i < picCount; ++i) {
-		byte nr = stream->readByte();
-		_roomData.pictures[nr] = readDataBlockPtr(*stream);
-	}
-
-	_roomData.description = readStringAt(*stream, descOffset, 0xff);
-
-	_roomData.commands.clear();
-	if (commandOffset != 0) {
-		stream->seek(commandOffset);
-		readCommands(*stream, _roomData.commands);
-	}
-}
-
-void HiRes2Engine::showRoom() {
-	drawPic(getCurRoom().curPicture, Common::Point());
-	drawItems();
-	_display->updateHiResScreen();
-	printString(_roomData.description);
-	_linesPrinted = 0;
-}
-
 Engine *HiRes2Engine_create(OSystem *syst, const AdlGameDescription *gd) {
 	return new HiRes2Engine(syst, gd);
 }
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index b8212e0..f2ffbf8 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -60,13 +60,6 @@ private:
 	void init();
 	void initState();
 	void restartGame();
-	void drawItem(const Item &item, const Common::Point &pos) const;
-	void loadRoom(byte roomNr);
-	void showRoom();
-
-	DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const;
-
-	Common::Array<DataBlockPtr> _itemPics;
 };
 
 } // End of namespace Adl


Commit: 97168fa200e6e7a437b9e68e6ebc1438c520a4f5
    https://github.com/scummvm/scummvm/commit/97168fa200e6e7a437b9e68e6ebc1438c520a4f5
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Load line feeds string

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/hires1.cpp
    engines/adl/hires1.h
    engines/adl/hires2.cpp



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 1b6bf6a..64e625d 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -552,10 +552,10 @@ Common::Error AdlEngine::run() {
 	} else {
 		runIntro();
 		initState();
+		_display->printAsciiString(_strings.lineFeeds);
 	}
 
 	_display->setMode(DISPLAY_MODE_MIXED);
-	_display->printAsciiString("\r\r\r\r\r");
 
 	while (1) {
 		uint verb = 0, noun = 0;
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 18b57ed..831bf38 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -339,6 +339,7 @@ protected:
 		Common::String nounError;
 		Common::String playAgain;
 		Common::String pressReturn;
+		Common::String lineFeeds;
 	} _strings;
 
 	struct {
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index e0f7574..0765625 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -156,6 +156,7 @@ void HiRes1Engine::init() {
 	_strings.nounError = readStringAt(*stream, IDI_HR1_OFS_STR_NOUN_ERROR);
 	_strings.playAgain = readStringAt(*stream, IDI_HR1_OFS_STR_PLAY_AGAIN);
 	_strings.pressReturn = readStringAt(*stream, IDI_HR1_OFS_STR_PRESS_RETURN);
+	_strings.lineFeeds = readStringAt(*stream, IDI_HR1_OFS_STR_LINE_FEEDS);
 
 	// Set message IDs
 	_messageIds.cantGoThere = IDI_HR1_MSG_CANT_GO_THERE;
@@ -258,10 +259,9 @@ void HiRes1Engine::initState() {
 }
 
 void HiRes1Engine::restartGame() {
-	initState();
 	_display->printString(_strings.pressReturn);
-	inputString(); // Missing in the original
-	_display->printAsciiString("\r\r\r\r\r");
+	initState();
+	_display->printAsciiString(_strings.lineFeeds);
 }
 
 void HiRes1Engine::printString(const Common::String &str) {
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index 02eb75a..251d079 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -65,6 +65,7 @@ namespace Adl {
 #define IDI_HR1_OFS_STR_DONT_UNDERSTAND 0x6c51
 #define IDI_HR1_OFS_STR_GETTING_DARK    0x6c7c
 #define IDI_HR1_OFS_STR_PRESS_RETURN    0x5f68
+#define IDI_HR1_OFS_STR_LINE_FEEDS      0x59d4
 
 #define IDI_HR1_OFS_PD_TEXT_0    0x005d
 #define IDI_HR1_OFS_PD_TEXT_1    0x012b
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index a1303b6..5a4e0e5 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -77,6 +77,10 @@ void HiRes2Engine::init() {
 	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);
@@ -184,7 +188,9 @@ void HiRes2Engine::initState() {
 }
 
 void HiRes2Engine::restartGame() {
+	_display->printString(_strings.pressReturn);
 	initState();
+	_display->printAsciiString(_strings.lineFeeds);
 }
 
 Engine *HiRes2Engine_create(OSystem *syst, const AdlGameDescription *gd) {


Commit: 09146fba6eaad18a221990fd4362c93da34aaafb
    https://github.com/scummvm/scummvm/commit/09146fba6eaad18a221990fd4362c93da34aaafb
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Move restartGame() into opcode

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/hires2.cpp
    engines/adl/hires2.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 64e625d..ba51b45 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -1070,7 +1070,9 @@ int AdlEngine::o1_restart(ScriptEnv &e) {
 		_isRestarting = true;
 		_display->clear(0x00);
 		_display->updateHiResScreen();
-		restartGame();
+		_display->printString(_strings.pressReturn);
+		initState();
+		_display->printAsciiString(_strings.lineFeeds);
 		return -1;
 	}
 
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 831bf38..72353e4 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -359,7 +359,6 @@ private:
 	virtual void runIntro() const { }
 	virtual void init() = 0;
 	virtual void initState() = 0;
-	virtual void restartGame() = 0;
 	virtual void drawItem(const Item &item, const Common::Point &pos) const = 0;
 	virtual void loadRoom(byte roomNr) = 0;
 	virtual void showRoom() = 0;
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 5a4e0e5..943d7a6 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -187,12 +187,6 @@ void HiRes2Engine::initState() {
 	}
 }
 
-void HiRes2Engine::restartGame() {
-	_display->printString(_strings.pressReturn);
-	initState();
-	_display->printAsciiString(_strings.lineFeeds);
-}
-
 Engine *HiRes2Engine_create(OSystem *syst, const AdlGameDescription *gd) {
 	return new HiRes2Engine(syst, gd);
 }
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index f2ffbf8..a882b68 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -59,7 +59,6 @@ private:
 	void runIntro() const;
 	void init();
 	void initState();
-	void restartGame();
 };
 
 } // End of namespace Adl


Commit: b4a82370cd21a0ed14c8bd6a44e22c47de39aeea
    https://github.com/scummvm/scummvm/commit/b4a82370cd21a0ed14c8bd6a44e22c47de39aeea
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Partially fix hires2 restarting

Changed paths:
    engines/adl/hires1.cpp
    engines/adl/hires2.cpp



diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 0765625..1d7e50e 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -207,17 +207,12 @@ void HiRes1Engine::init() {
 }
 
 void HiRes1Engine::initState() {
-	_state.room = 1;
-	_state.moves = 1;
-	_state.isDark = false;
-
-	_state.vars.clear();
+	_state = State();
 	_state.vars.resize(IDI_HR1_NUM_VARS);
 
 	StreamPtr stream(_files->createReadStream(IDS_HR1_EXE_1));
 
 	// Load room data from executable
-	_state.rooms.clear();
 	_roomDesc.clear();
 	stream->seek(IDI_HR1_OFS_ROOMS);
 	for (uint i = 0; i < IDI_HR1_NUM_ROOMS; ++i) {
@@ -232,7 +227,6 @@ void HiRes1Engine::initState() {
 	}
 
 	// Load item data from executable
-	_state.items.clear();
 	stream->seek(IDI_HR1_OFS_ITEMS);
 	byte id;
 	while ((id = stream->readByte()) != 0xff) {
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 943d7a6..9a928ff 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -139,12 +139,11 @@ void HiRes2Engine::init() {
 }
 
 void HiRes2Engine::initState() {
-	_state.vars.clear();
+	_state = State();
 	_state.vars.resize(IDI_HR2_NUM_VARS);
 
 	StreamPtr stream(_disk->createReadStream(0x21, 0x5, 0x0e, 7));
 
-	_state.rooms.clear();
 	for (uint i = 0; i < IDI_HR2_NUM_ROOMS; ++i) {
 		Room room;
 		stream->readByte(); // number
@@ -159,7 +158,6 @@ void HiRes2Engine::initState() {
 
 	stream.reset(_disk->createReadStream(0x21, 0x0, 0x00, 2));
 
-	_state.items.clear();
 	byte id;
 	while ((id = stream->readByte()) != 0xff) {
 		Item item = { };


Commit: adecc106742baed4fbe5752c4319fa8e855c60e1
    https://github.com/scummvm/scummvm/commit/adecc106742baed4fbe5752c4319fa8e855c60e1
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Reset "lines printed" counter on restart

Changed paths:
    engines/adl/hires2.cpp



diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 9a928ff..a0fa5a0 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -139,6 +139,8 @@ void HiRes2Engine::init() {
 }
 
 void HiRes2Engine::initState() {
+	_linesPrinted = 0;
+
 	_state = State();
 	_state.vars.resize(IDI_HR2_NUM_VARS);
 


Commit: 83d75c2f4c74e8e62b1cacc08a54678394daf22b
    https://github.com/scummvm/scummvm/commit/83d75c2f4c74e8e62b1cacc08a54678394daf22b
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Clean-up

Changed paths:
    engines/adl/adl.h



diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 72353e4..d81afe2 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -382,8 +382,6 @@ private:
 	bool _canSaveNow, _canRestoreNow;
 };
 
-AdlEngine *HiRes1Engine__create(OSystem *syst, const AdlGameDescription *gd);
-
 } // End of namespace Adl
 
 #endif


Commit: ed0653e3939a8a9dbfac873a23c40da2c00ab81b
    https://github.com/scummvm/scummvm/commit/ed0653e3939a8a9dbfac873a23c40da2c00ab81b
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Update save game format for hires2

Note: this breaks loading earlier savegames

Changed paths:
    engines/adl/adl.cpp



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index ba51b45..c059258 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -658,6 +658,8 @@ Common::Error AdlEngine::loadGameState(int slot) {
 	_state.room = inFile->readByte();
 	_state.moves = inFile->readByte();
 	_state.isDark = inFile->readByte();
+	_state.time.hours = inFile->readByte();
+	_state.time.minutes = inFile->readByte();
 
 	uint32 size = inFile->readUint32BE();
 	if (size != _state.rooms.size())
@@ -666,6 +668,7 @@ Common::Error AdlEngine::loadGameState(int slot) {
 	for (uint i = 0; i < size; ++i) {
 		_state.rooms[i].picture = inFile->readByte();
 		_state.rooms[i].curPicture = inFile->readByte();
+		_state.rooms[i].isFirstTime = inFile->readByte();
 	}
 
 	size = inFile->readUint32BE();
@@ -744,11 +747,14 @@ Common::Error AdlEngine::saveGameState(int slot, const Common::String &desc) {
 	outFile->writeByte(_state.room);
 	outFile->writeByte(_state.moves);
 	outFile->writeByte(_state.isDark);
+	outFile->writeByte(_state.time.hours);
+	outFile->writeByte(_state.time.minutes);
 
 	outFile->writeUint32BE(_state.rooms.size());
 	for (uint i = 0; i < _state.rooms.size(); ++i) {
 		outFile->writeByte(_state.rooms[i].picture);
 		outFile->writeByte(_state.rooms[i].curPicture);
+		outFile->writeByte(_state.rooms[i].isFirstTime);
 	}
 
 	outFile->writeUint32BE(_state.items.size());


Commit: bc0fc246f047415837d7c7bccf82918303fcccaf
    https://github.com/scummvm/scummvm/commit/bc0fc246f047415837d7c7bccf82918303fcccaf
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Implement hires2 screen update routine

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/adl_v2.cpp
    engines/adl/adl_v2.h
    engines/adl/hires1.cpp
    engines/adl/hires1.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index c059258..50e7af4 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 d81afe2..1b6d02b 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 8b7a623..fd316c0 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 c8dc189..46a8813 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 1d7e50e..cca2fe4 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 251d079..8dc7081 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();
 


Commit: d361f2e4b09fee1b36c4c3c4c8715497990e6e26
    https://github.com/scummvm/scummvm/commit/d361f2e4b09fee1b36c4c3c4c8715497990e6e26
Author: Alyssa Milburn (fuzzie at fuzzie.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Add (experimental) support for NIB files

Changed paths:
    engines/adl/disk.cpp
    engines/adl/disk.h



diff --git a/engines/adl/disk.cpp b/engines/adl/disk.cpp
index 22a7d7a..1ec1218 100644
--- a/engines/adl/disk.cpp
+++ b/engines/adl/disk.cpp
@@ -63,6 +63,159 @@ bool DiskImage_DSK::open(const Common::String &filename) {
 	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");
+
+	return stream;
+}
+
+// 4-and-4 encoding (odd-even)
+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();
+}
+
+bool DiskImage_NIB::open(const Common::String &filename) {
+	assert(!_f->isOpen());
+
+	if (!_f->open(filename))
+		return false;
+
+	uint filesize = _f->size();
+	switch (filesize) {
+	case 232960:
+		_tracks = 35;
+		_sectorsPerTrack = 13;
+		_bytesPerSector = 256;
+		break;
+	default:
+		error("Unrecognized NIB image '%s' of size %d bytes", filename.c_str(), filesize);
+	}
+
+	// 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 };
+
+	uint32 diskSize = _tracks * _sectorsPerTrack * _bytesPerSector;
+	byte *diskImage = (byte *)calloc(diskSize, 1);
+	_memStream = new Common::MemoryReadStream(diskImage, diskSize, DisposeAfterUse::YES);
+
+	bool sawAddress = false;
+	uint8 volNo, track, sector;
+
+	while (_f->pos() < _f->size()) {
+		// Read until we find two sync bytes.
+		if (_f->readByte() != 0xd5 || _f->readByte() != 0xaa)
+			continue;
+
+		byte prologue = _f->readByte();
+
+		if (sawAddress && prologue == 0xb5) {
+			warning("NIB: data for %02x/%02x/%02x missing", volNo, track, sector);
+			sawAddress = false;
+		}
+
+		if (!sawAddress) {
+			sawAddress = true;
+
+			// We should always find the address field first.
+			if (prologue != 0xb5) {
+				// Accept a DOS 3.3(?) header at the start.
+				if (_f->pos() == 3 || prologue == 0x96) {
+					// But skip it.
+					_f->skip(20);
+					sawAddress = false;
+					continue;
+				} else {
+					error("unknown NIB field prologue %02x", prologue);
+				}
+			}
+
+			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 (sector == 1)
+				sector = 2;
+			else if (sector == 2)
+				sector = 1;
+
+			// Epilogue is de/aa plus a gap, but we don't care.
+		} else {
+			sawAddress = false;
+
+			// We should always find the data field after an address field.
+			// TODO: we ignore volNo?
+			byte *output = diskImage + (track * _sectorsPerTrack + sector) * _bytesPerSector;
+
+			// 5-and-3 uses 410 on-disk bytes, decoding to just over 256 bytes
+			byte inbuffer[410];
+			_f->read(inbuffer, 410);
+
+			bool truncated = false;
+			byte oldVal = 0;
+			for (uint n = 0; n < 410; ++n) {
+				// expand
+				assert(inbuffer[n] >= 0xaa); // corrupt file (TODO: assert?)
+				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);
+					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);
+					break;
+				}
+				// undo checksum
+				oldVal = val ^ oldVal;
+				inbuffer[n] = oldVal;
+			}
+			if (!truncated) {
+				byte checksum = _f->readByte();
+				if (checksum < 0xaa || oldVal != c_5and3_lookup[checksum - 0xaa])
+					warning("NIB: checksum mismatch @ (%x, %x)", track, sector);
+			}
+
+			// 8 bytes of nibbles expand to 5 bytes
+			// so we have 51 of these batches (255 bytes), plus 2 bytes of 'leftover' nibbles for byte 256
+			for (uint n = 0; n < 51; ++n) {
+				// e.g. figure 3.18 of Beneath Apple DOS
+				byte lowbits1 = inbuffer[51*3 - n];
+				byte lowbits2 = inbuffer[51*2 - n];
+				byte lowbits3 = inbuffer[51*1 - n];
+				byte lowbits4 = (lowbits1 & 2) << 1 | (lowbits2 & 2) | (lowbits3 & 2) >> 1;
+				byte lowbits5 = (lowbits1 & 1) << 2 | (lowbits2 & 1) << 1 | (lowbits3 & 1);
+				output[250 - 5*n] = (inbuffer[n + 51*3 + 1] << 3) | ((lowbits1 >> 2) & 0x7);
+				output[251 - 5*n] = (inbuffer[n + 51*4 + 1] << 3) | ((lowbits2 >> 2) & 0x7);
+				output[252 - 5*n] = (inbuffer[n + 51*5 + 1] << 3) | ((lowbits3 >> 2) & 0x7);
+				output[253 - 5*n] = (inbuffer[n + 51*6 + 1] << 3) | lowbits4;
+				output[254 - 5*n] = (inbuffer[n + 51*7 + 1] << 3) | lowbits5;
+			}
+			output[255] = (inbuffer[409] << 3) | (inbuffer[0] & 0x7);
+		}
+	}
+
+	return true;
+}
+
 const DataBlockPtr Files_Plain::getDataBlock(const Common::String &filename, uint offset) const {
 	return Common::SharedPtr<Files::DataBlock>(new Files::DataBlock(this, filename, offset));
 }
diff --git a/engines/adl/disk.h b/engines/adl/disk.h
index 4cab81d..43b9e38 100644
--- a/engines/adl/disk.h
+++ b/engines/adl/disk.h
@@ -125,6 +125,22 @@ public:
 	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:


Commit: 5db8f401a89b89f763dc8eb949a1db81f4e3fa90
    https://github.com/scummvm/scummvm/commit/5db8f401a89b89f763dc8eb949a1db81f4e3fa90
Author: Alyssa Milburn (fuzzie at fuzzie.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Add detection entry for hires0

Changed paths:
    engines/adl/detection.cpp
    engines/adl/detection.h



diff --git a/engines/adl/detection.cpp b/engines/adl/detection.cpp
index 457db2d..0a8a98f 100644
--- a/engines/adl/detection.cpp
+++ b/engines/adl/detection.cpp
@@ -71,6 +71,7 @@ static const ADExtraGuiOptionsMap optionsList[] = {
 };
 
 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" },
 	{ 0, 0 }
@@ -107,7 +108,7 @@ static const AdlGameDescription gameDescriptions[] = {
 		},
 		GAME_TYPE_HIRES1
 	},
-	{ // Hi-Res Adventure #2: Wizard and the Princess - Apple II - 1986 SierraVenture release
+	{ // Hi-Res Adventure #2: Wizard and the Princess - Apple II - Roberta Williams Anthology
 		{
 			"hires2", 0,
 			{
@@ -121,6 +122,20 @@ static const AdlGameDescription gameDescriptions[] = {
 		},
 		GAME_TYPE_HIRES2
 	},
+	{ // Hi-Res Adventure #0: Mission Asteroid - Apple II - Roberta Williams Anthology
+		{
+			"hires0", 0,
+			{
+				{ "MISSION.NIB", 0, "b158f6f79681d4edd651e1932f9e01d7", 232960 },
+				AD_LISTEND
+			},
+			Common::EN_ANY,
+			Common::kPlatformApple2GS, // FIXME
+			ADGF_UNSTABLE,
+			GUIO2(GAMEOPTION_MONO, GAMEOPTION_SCANLINES)
+		},
+		GAME_TYPE_HIRES0
+	},
 	{ AD_TABLE_END_MARKER, GAME_TYPE_NONE }
 };
 
diff --git a/engines/adl/detection.h b/engines/adl/detection.h
index 4275286..bd01529 100644
--- a/engines/adl/detection.h
+++ b/engines/adl/detection.h
@@ -32,6 +32,7 @@ namespace Adl {
 
 enum GameType {
 	GAME_TYPE_NONE,
+	GAME_TYPE_HIRES0,
 	GAME_TYPE_HIRES1,
 	GAME_TYPE_HIRES2
 };


Commit: e89f34857f647c608add26dd8317829ab867fa30
    https://github.com/scummvm/scummvm/commit/e89f34857f647c608add26dd8317829ab867fa30
Author: Alyssa Milburn (fuzzie at fuzzie.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Fix NIB track swapping hack

Changed paths:
    engines/adl/disk.cpp



diff --git a/engines/adl/disk.cpp b/engines/adl/disk.cpp
index 1ec1218..80463af 100644
--- a/engines/adl/disk.cpp
+++ b/engines/adl/disk.cpp
@@ -147,10 +147,10 @@ bool DiskImage_NIB::open(const Common::String &filename) {
 				error("invalid NIB checksum");
 
 			// FIXME: This is a hires0/hires2-specific hack.
-			if (sector == 1)
-				sector = 2;
-			else if (sector == 2)
-				sector = 1;
+			if (track == 1)
+				track = 2;
+			else if (track == 2)
+				track = 1;
 
 			// Epilogue is de/aa plus a gap, but we don't care.
 		} else {


Commit: 266e63453f386b5a0b043c4cdc5e278b8b6134a3
    https://github.com/scummvm/scummvm/commit/266e63453f386b5a0b043c4cdc5e278b8b6134a3
Author: Alyssa Milburn (fuzzie at fuzzie.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Add support for newer NIB files

Changed paths:
    engines/adl/disk.cpp



diff --git a/engines/adl/disk.cpp b/engines/adl/disk.cpp
index 80463af..a9c7a59 100644
--- a/engines/adl/disk.cpp
+++ b/engines/adl/disk.cpp
@@ -94,7 +94,7 @@ bool DiskImage_NIB::open(const Common::String &filename) {
 	switch (filesize) {
 	case 232960:
 		_tracks = 35;
-		_sectorsPerTrack = 13;
+		_sectorsPerTrack = 16; // we always pad it out
 		_bytesPerSector = 256;
 		break;
 	default:
@@ -103,6 +103,8 @@ bool DiskImage_NIB::open(const Common::String &filename) {
 
 	// 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);
@@ -110,6 +112,7 @@ bool DiskImage_NIB::open(const Common::String &filename) {
 
 	bool sawAddress = false;
 	uint8 volNo, track, sector;
+	bool newStyle;
 
 	while (_f->pos() < _f->size()) {
 		// Read until we find two sync bytes.
@@ -118,22 +121,20 @@ bool DiskImage_NIB::open(const Common::String &filename) {
 
 		byte prologue = _f->readByte();
 
-		if (sawAddress && prologue == 0xb5) {
+		if (sawAddress && (prologue == 0xb5 || prologue == 0x96)) {
 			warning("NIB: data for %02x/%02x/%02x missing", volNo, track, sector);
 			sawAddress = false;
 		}
 
 		if (!sawAddress) {
 			sawAddress = true;
+			newStyle = false;
 
 			// We should always find the address field first.
 			if (prologue != 0xb5) {
 				// Accept a DOS 3.3(?) header at the start.
-				if (_f->pos() == 3 || prologue == 0x96) {
-					// But skip it.
-					_f->skip(20);
-					sawAddress = false;
-					continue;
+				if (prologue == 0x96) {
+					newStyle = true;
 				} else {
 					error("unknown NIB field prologue %02x", prologue);
 				}
@@ -147,19 +148,59 @@ bool DiskImage_NIB::open(const Common::String &filename) {
 				error("invalid NIB checksum");
 
 			// FIXME: This is a hires0/hires2-specific hack.
-			if (track == 1)
-				track = 2;
-			else if (track == 2)
-				track = 1;
+			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.
-		} else {
-			sawAddress = false;
+			continue;
+		}
 
-			// We should always find the data field after an address field.
-			// TODO: we ignore volNo?
-			byte *output = diskImage + (track * _sectorsPerTrack + sector) * _bytesPerSector;
+		sawAddress = false;
+
+		// We should always find the data field after an address field.
+		// TODO: we ignore volNo?
+		byte *output = diskImage + (track * _sectorsPerTrack + sector) * _bytesPerSector;
+
+		if (newStyle) {
+			// 6-and-2 uses 342 on-disk bytes
+			byte inbuffer[342];
+			_f->read(inbuffer, 342);
+
+			byte oldVal = 0;
+			for (uint n = 0; n < 342; ++n) {
+				// expand
+				assert(inbuffer[n] >= 0x96); // corrupt file (TODO: assert?)
+				byte val = c_6and2_lookup[inbuffer[n] - 0x96];
+				if (val == 0x40) {
+					error("NIB: invalid nibble value %02x", inbuffer[n]);
+				}
+				// undo checksum
+				oldVal = val ^ oldVal;
+				inbuffer[n] = oldVal;
+			}
 
+			byte checksum = _f->readByte();
+			if (checksum < 0x96 || oldVal != c_6and2_lookup[checksum - 0x96])
+				warning("NIB: checksum mismatch @ (%x, %x)", track, sector);
+
+			for (uint n = 0; n < 256; ++n) {
+				output[n] = inbuffer[86 + n] << 2;
+				if (n < 86) { // use first pair of bits
+					output[n] |= ((inbuffer[n] & 1) << 1);
+					output[n] |= ((inbuffer[n] & 2) >> 1);
+				} else if (n < 86*2) { // second pair
+					output[n] |= ((inbuffer[n-86] & 4) >> 1);
+					output[n] |= ((inbuffer[n-86] & 8) >> 3);
+				} else { // third pair
+					output[n] |= ((inbuffer[n-86*2] & 0x10) >> 3);
+					output[n] |= ((inbuffer[n-86*2] & 0x20) >> 5);
+				}
+			}
+		} else {
 			// 5-and-3 uses 410 on-disk bytes, decoding to just over 256 bytes
 			byte inbuffer[410];
 			_f->read(inbuffer, 410);


Commit: ae405707cc398af3afbd7c5c00723eec2a5538f7
    https://github.com/scummvm/scummvm/commit/ae405707cc398af3afbd7c5c00723eec2a5538f7
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Add skeleton for hires6

Changed paths:
  A engines/adl/hires6.cpp
  A engines/adl/hires6.h
    engines/adl/detection.cpp
    engines/adl/detection.h
    engines/adl/hires2.h
    engines/adl/module.mk



diff --git a/engines/adl/detection.cpp b/engines/adl/detection.cpp
index 0a8a98f..12405e7 100644
--- a/engines/adl/detection.cpp
+++ b/engines/adl/detection.cpp
@@ -74,6 +74,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" },
+	{ "hires6", "Hi-Res Adventure #6: The Dark Crystal" },
 	{ 0, 0 }
 };
 
@@ -136,6 +137,23 @@ static const AdlGameDescription gameDescriptions[] = {
 		},
 		GAME_TYPE_HIRES0
 	},
+	{ // Hi-Res Adventure #6: The Dark Crystal - Apple II - Roberta Williams Anthology
+		{
+			"hires6", 0,
+			{
+				{ "DARK1A.DSK", 0, "00c2646d6943d1405717332a6f42d493", 143360 },
+				{ "DARK2A.NIB", 0, "271eb92db107e8d5829437f8ba77991e", 232960 },
+				{ "DARK1B.NIB", 0, "dbedd736617343ade0e6bead8bf2b10c", 232960 },
+				{ "DARK2B.NIB", 0, "cb72044a9b391c4285f4752f746bea2e", 232960 },
+				AD_LISTEND
+			},
+			Common::EN_ANY,
+			Common::kPlatformApple2GS, // FIXME
+			ADGF_UNSTABLE,
+			GUIO2(GAMEOPTION_MONO, GAMEOPTION_SCANLINES)
+		},
+		GAME_TYPE_HIRES6
+	},
 	{ AD_TABLE_END_MARKER, GAME_TYPE_NONE }
 };
 
@@ -276,6 +294,7 @@ 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 *HiRes6Engine_create(OSystem *syst, const AdlGameDescription *gd);
 
 bool AdlMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const {
 	if (!gd)
@@ -290,6 +309,9 @@ bool AdlMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameD
 	case GAME_TYPE_HIRES2:
 		*engine = HiRes2Engine_create(syst, adlGd);
 		break;
+	case GAME_TYPE_HIRES6:
+		*engine = HiRes6Engine_create(syst, adlGd);
+		break;
 	default:
 		error("Unknown GameType");
 	}
diff --git a/engines/adl/detection.h b/engines/adl/detection.h
index bd01529..533466c 100644
--- a/engines/adl/detection.h
+++ b/engines/adl/detection.h
@@ -34,7 +34,8 @@ enum GameType {
 	GAME_TYPE_NONE,
 	GAME_TYPE_HIRES0,
 	GAME_TYPE_HIRES1,
-	GAME_TYPE_HIRES2
+	GAME_TYPE_HIRES2,
+	GAME_TYPE_HIRES6
 };
 
 struct AdlGameDescription {
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index a882b68..b99fd66 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -20,8 +20,8 @@
  *
  */
 
-#ifndef ADL_HIRES1_H
-#define ADL_HIRES1_H
+#ifndef ADL_HIRES2_H
+#define ADL_HIRES2_H
 
 #include "common/str.h"
 
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
new file mode 100644
index 0000000..7c9292f
--- /dev/null
+++ b/engines/adl/hires6.cpp
@@ -0,0 +1,152 @@
+/* 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 "common/memstream.h"
+
+#include "adl/hires6.h"
+#include "adl/display.h"
+#include "adl/graphics.h"
+#include "adl/disk.h"
+
+namespace Adl {
+
+static const char *disks[] = { "DARK1A.DSK", "DARK1B.NIB", "DARK2A.NIB", "DARK2B.NIB" };
+
+#define SECTORS_PER_TRACK 16
+#define BYTES_PER_SECTOR 256
+
+static Common::MemoryReadStream *loadSectors(DiskImage *disk, byte track, byte sector = SECTORS_PER_TRACK - 1, byte count = SECTORS_PER_TRACK) {
+	const int bufSize = count * BYTES_PER_SECTOR;
+	byte *const buf = (byte *)malloc(bufSize);
+	byte *p = buf;
+
+	while (count-- > 0) {
+		StreamPtr stream(disk->createReadStream(track, sector, 0, 0));
+		stream->read(p, BYTES_PER_SECTOR);
+
+		if (stream->err() || stream->eos())
+			error("Error loading from disk image");
+
+		p += BYTES_PER_SECTOR;
+		if (sector > 0)
+			--sector;
+		else {
+			++track;
+
+			// Skip VTOC track
+			if (track == 17)
+				++track;
+
+			sector = SECTORS_PER_TRACK - 1;
+		}
+	}
+
+	return new Common::MemoryReadStream(buf, bufSize, DisposeAfterUse::YES);
+}
+
+void HiRes6Engine::runIntro() const {
+	DiskImage_DSK *boot(new DiskImage_DSK());
+
+	if (!boot->open(disks[0]))
+		error("Failed to open disk image '%s'", disks[0]);
+
+	StreamPtr stream(loadSectors(boot, 11, 1, 96));
+
+	_display->setMode(DISPLAY_MODE_HIRES);
+	_display->loadFrameBuffer(*stream);
+	_display->updateHiResScreen();
+	delay(256 * 8609 / 1000);
+
+	_display->loadFrameBuffer(*stream);
+	_display->updateHiResScreen();
+	delay(256 * 8609 / 1000);
+
+	_display->loadFrameBuffer(*stream);
+
+	delete boot;
+
+	// Load copyright string from boot file
+	Files_DOS33 *files(new Files_DOS33());
+
+	if (!files->open(disks[0]))
+		error("Failed to open disk image '%s'", disks[0]);
+
+	stream.reset(files->createReadStream("\010\010\010\010\010\010"));
+	Common::String copyright(readStringAt(*stream, 0x103, APPLECHAR('\r')));
+
+	delete files;
+
+	_display->updateHiResScreen();
+	_display->home();
+	_display->setMode(DISPLAY_MODE_MIXED);
+	_display->moveCursorTo(Common::Point(0, 21));
+	_display->printString(copyright);
+	delay(256 * 8609 / 1000);
+}
+
+void HiRes6Engine::init() {
+	DiskImage_DSK *boot(new DiskImage_DSK());
+	_graphics = new Graphics_v2(*_display);
+
+	if (!boot->open(disks[0]))
+		error("Failed to open disk image '%s'", disks[0]);
+
+	StreamPtr stream(loadSectors(boot, 7));
+
+	// Read parser messages
+	_strings.verbError = readStringAt(*stream, 0x666);
+	_strings.nounError = readStringAt(*stream, 0x6bd);
+	_strings.enterCommand = readStringAt(*stream, 0x6e9);
+
+	// Read line feeds
+	_strings.lineFeeds = readStringAt(*stream, 0x408);
+
+	// Read opcode strings (TODO)
+	_strings_v2.saveInsert = readStringAt(*stream, 0xad8);
+	readStringAt(*stream, 0xb95); // Confirm save
+	// _strings_v2.saveReplace
+	_strings_v2.restoreInsert = readStringAt(*stream, 0xc07);
+	// _strings_v2.restoreReplace
+	_strings.playAgain = readStringAt(*stream, 0xcdf, 0xff);
+
+	_messageIds.cantGoThere = IDI_HR6_MSG_CANT_GO_THERE;
+	_messageIds.dontUnderstand = IDI_HR6_MSG_DONT_UNDERSTAND;
+	_messageIds.itemDoesntMove = IDI_HR6_MSG_ITEM_DOESNT_MOVE;
+	_messageIds.itemNotHere = IDI_HR6_MSG_ITEM_NOT_HERE;
+	_messageIds.thanksForPlaying = IDI_HR6_MSG_THANKS_FOR_PLAYING;
+
+	delete boot;
+}
+
+void HiRes6Engine::initState() {
+}
+
+Engine *HiRes6Engine_create(OSystem *syst, const AdlGameDescription *gd) {
+	return new HiRes6Engine(syst, gd);
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/hires6.h b/engines/adl/hires6.h
new file mode 100644
index 0000000..ecc0a6a
--- /dev/null
+++ b/engines/adl/hires6.h
@@ -0,0 +1,64 @@
+/* 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_HIRES6_H
+#define ADL_HIRES6_H
+
+#include "common/str.h"
+
+#include "adl/adl_v2.h"
+#include "adl/disk.h"
+
+namespace Common {
+class ReadStream;
+class Point;
+}
+
+namespace Adl {
+
+#define IDI_HR6_NUM_ROOMS 35
+#define IDI_HR6_NUM_MESSAGES 255
+#define IDI_HR6_NUM_VARS 40
+#define IDI_HR6_NUM_ITEM_PICS 15
+#define IDI_HR6_NUM_ITEM_OFFSETS 16
+
+// Messages used outside of scripts
+#define IDI_HR6_MSG_CANT_GO_THERE      249
+#define IDI_HR6_MSG_DONT_UNDERSTAND    247
+#define IDI_HR6_MSG_ITEM_DOESNT_MOVE   253
+#define IDI_HR6_MSG_ITEM_NOT_HERE      254
+#define IDI_HR6_MSG_THANKS_FOR_PLAYING 252
+
+class HiRes6Engine : public AdlEngine_v2 {
+public:
+	HiRes6Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine_v2(syst, gd) { }
+
+private:
+	// AdlEngine
+	void runIntro() const;
+	void init();
+	void initState();
+};
+
+} // End of namespace Adl
+
+#endif
diff --git a/engines/adl/module.mk b/engines/adl/module.mk
index 7f097a4..c726a6b 100644
--- a/engines/adl/module.mk
+++ b/engines/adl/module.mk
@@ -12,6 +12,7 @@ MODULE_OBJS := \
 	graphics_v2.o \
 	hires1.o \
 	hires2.o \
+	hires6.o \
 	speaker.o
 
 MODULE_DIRS += \


Commit: 7dc5f636f8ebbff1ce46cad818f1e241017f83b0
    https://github.com/scummvm/scummvm/commit/7dc5f636f8ebbff1ce46cad818f1e241017f83b0
Author: Alyssa Milburn (fuzzie at fuzzie.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Map DOS 3.3 NIB to logical sectors

Changed paths:
    engines/adl/disk.cpp



diff --git a/engines/adl/disk.cpp b/engines/adl/disk.cpp
index a9c7a59..214f76a 100644
--- a/engines/adl/disk.cpp
+++ b/engines/adl/disk.cpp
@@ -166,6 +166,11 @@ bool DiskImage_NIB::open(const Common::String &filename) {
 		byte *output = diskImage + (track * _sectorsPerTrack + sector) * _bytesPerSector;
 
 		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;
+
 			// 6-and-2 uses 342 on-disk bytes
 			byte inbuffer[342];
 			_f->read(inbuffer, 342);


Commit: a320b319eb385d3ceca16567215a7d7609247bb4
    https://github.com/scummvm/scummvm/commit/a320b319eb385d3ceca16567215a7d7609247bb4
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Load more hires6 data

Now shows pic of first room

Changed paths:
    engines/adl/adl_v2.cpp
    engines/adl/adl_v2.h
    engines/adl/hires6.cpp
    engines/adl/hires6.h



diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index fd316c0..90ed794 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -338,6 +338,8 @@ DataBlockPtr AdlEngine_v2::readDataBlockPtr(Common::ReadStream &f) const {
 	if (track == 0 && sector == 0 && offset == 0 && size == 0)
 		return DataBlockPtr();
 
+	applyDataBlockOffset(track, sector);
+
 	return _disk->getDataBlock(track, sector, offset, size);
 }
 
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 46a8813..2251a93 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -52,6 +52,7 @@ protected:
 	void showRoom();
 	void takeItem(byte noun);
 
+	virtual void applyDataBlockOffset(byte &track, byte &sector) const { }
 	DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const;
 
 	void checkTextOverflow(char c);
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index 7c9292f..a87cb7b 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -115,6 +115,10 @@ void HiRes6Engine::init() {
 	if (!boot->open(disks[0]))
 		error("Failed to open disk image '%s'", disks[0]);
 
+	// TODO (needs refactoring of message handling)
+	for (uint i = 0; i < 256; ++i)
+		_messages.push_back(Common::String());
+
 	StreamPtr stream(loadSectors(boot, 7));
 
 	// Read parser messages
@@ -139,10 +143,106 @@ void HiRes6Engine::init() {
 	_messageIds.itemNotHere = IDI_HR6_MSG_ITEM_NOT_HERE;
 	_messageIds.thanksForPlaying = IDI_HR6_MSG_THANKS_FOR_PLAYING;
 
+	// Load dropped item offsets
+	stream.reset(boot->createReadStream(0x8, 0x9, 0x16));
+	for (uint i = 0; i < IDI_HR6_NUM_ITEM_OFFSETS; ++i) {
+		Common::Point p;
+		p.x = stream->readByte();
+		p.y = stream->readByte();
+		_itemOffsets.push_back(p);
+	}
+
+	_disk = new DiskImage_NIB();
+
+	if (!_disk->open(disks[1]))
+		error("Failed to open disk image '%s'", disks[1]);
+
+	// Load item picture data
+	stream.reset(boot->createReadStream(0xb, 0xd, 0x08));
+	for (uint i = 0; i < IDI_HR6_NUM_ITEM_PICS; ++i) {
+		stream->readByte();
+		_itemPics.push_back(readDataBlockPtr(*stream));
+	}
+
+	// Load global picture data
+	stream.reset(_disk->createReadStream(0x1f, 0xf, 0x16, 0));
+	byte picNr;
+	while ((picNr = stream->readByte()) != 0xff) {
+		if (stream->eos() || stream->err())
+			error("Error reading global pic list");
+		_pictures[picNr] = readDataBlockPtr(*stream);
+	}
+
+	// Load commands
+	stream.reset(_disk->createReadStream(0x21, 0x4, 0x85, 7));
+	readCommands(*stream, _roomCommands);
+
+	stream.reset(_disk->createReadStream(0x20, 0xf, 0x82, 5));
+	readCommands(*stream, _globalCommands);
+
+	// Load verbs
+	stream.reset(_disk->createReadStream(0x1f, 0xf, 0x56, 6));
+	loadWords(*stream, _verbs, _priVerbs);
+
+	// Load nouns
+	stream.reset(_disk->createReadStream(0x20, 0x5, 0x8e, 8));
+	loadWords(*stream, _nouns, _priNouns);
+
 	delete boot;
 }
 
 void HiRes6Engine::initState() {
+	_linesPrinted = 0;
+
+	_state = State();
+	_state.vars.resize(IDI_HR6_NUM_VARS);
+
+	StreamPtr stream(_disk->createReadStream(0x20, 0xd, 0x94, 2));
+
+	for (uint i = 0; i < IDI_HR6_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(0x22, 0x0, 0x07, 0));
+
+	byte id;
+	while ((id = stream->readByte()) != 0xff) {
+		Item item = { };
+		item.id = id;
+		item.noun = stream->readByte();
+		item.room = stream->readByte();
+		item.picture = stream->readByte();
+		item.isLineArt = stream->readByte(); // Now seems to be disk number
+		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);
+	}
+}
+
+void HiRes6Engine::applyDataBlockOffset(byte &track, byte &sector) const {
+	// FIXME: this uses a table
+	++track;
 }
 
 Engine *HiRes6Engine_create(OSystem *syst, const AdlGameDescription *gd) {
diff --git a/engines/adl/hires6.h b/engines/adl/hires6.h
index ecc0a6a..99e9371 100644
--- a/engines/adl/hires6.h
+++ b/engines/adl/hires6.h
@@ -57,6 +57,9 @@ private:
 	void runIntro() const;
 	void init();
 	void initState();
+
+	// AdlEngine_v2
+	void applyDataBlockOffset(byte &track, byte &sector) const;
 };
 
 } // End of namespace Adl


Commit: 1842d0c45f3b37442dcf94466589e0a4960bdc08
    https://github.com/scummvm/scummvm/commit/1842d0c45f3b37442dcf94466589e0a4960bdc08
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Add loadMessage function

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/hires1.cpp



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 50e7af4..37f1d04 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -123,7 +123,7 @@ void AdlEngine::openFile(Common::File &file, const Common::String &name) const {
 }
 
 void AdlEngine::printMessage(uint idx) {
-	printString(_messages[idx - 1]);
+	printString(loadMessage(idx));
 }
 
 void AdlEngine::delay(uint32 ms) const {
@@ -1214,7 +1214,7 @@ Common::String AdlEngine::itemStr(uint i) const {
 	}
 	if (desc > 0) {
 		name += "/";
-		name += toAscii(_messages[desc - 1]);
+		name += toAscii(loadMessage(desc));
 	}
 	return name;
 }
@@ -1254,7 +1254,7 @@ Common::String AdlEngine::nounStr(uint i) const {
 }
 
 Common::String AdlEngine::msgStr(uint i) const {
-	return Common::String::format("%d/%s", i, toAscii(_messages[i - 1]).c_str());
+	return Common::String::format("%d/%s", i, toAscii(loadMessage(i)).c_str());
 }
 
 Common::String AdlEngine::dirStr(Direction dir) const {
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 1b6d02b..6832769 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -226,6 +226,7 @@ protected:
 	void openFile(Common::File &file, const Common::String &name) const;
 
 	virtual void printString(const Common::String &str) = 0;
+	virtual Common::String loadMessage(uint idx) const { return _messages[idx - 1]; }
 	virtual void printMessage(uint idx);
 	void delay(uint32 ms) const;
 
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index cca2fe4..9193c27 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -268,7 +268,7 @@ void HiRes1Engine::printString(const Common::String &str) {
 }
 
 void HiRes1Engine::printMessage(uint idx) {
-	const Common::String &msg = _messages[idx - 1];
+	const Common::String &msg = loadMessage(idx);
 
 	// Messages with hardcoded overrides don't delay after printing.
 	// It's unclear if this is a bug or not. In some cases the result
@@ -326,7 +326,7 @@ void HiRes1Engine::drawItem(Item &item, const Common::Point &pos) {
 }
 
 void HiRes1Engine::loadRoom(byte roomNr) {
-	_roomData.description = _messages[_roomDesc[_state.room - 1] - 1];
+	_roomData.description = loadMessage(_roomDesc[_state.room - 1]);
 }
 
 void HiRes1Engine::showRoom() {


Commit: 4f932afd60a25366188f07a68996c5fcb097ae38
    https://github.com/scummvm/scummvm/commit/4f932afd60a25366188f07a68996c5fcb097ae38
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Load messages on demand

Changed paths:
    engines/adl/adl.h
    engines/adl/adl_v2.cpp
    engines/adl/adl_v2.h
    engines/adl/console.cpp
    engines/adl/hires1.cpp
    engines/adl/hires1.h
    engines/adl/hires2.cpp
    engines/adl/hires2.h
    engines/adl/hires6.cpp
    engines/adl/hires6.h



diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 6832769..14e38eb 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -226,7 +226,7 @@ protected:
 	void openFile(Common::File &file, const Common::String &name) const;
 
 	virtual void printString(const Common::String &str) = 0;
-	virtual Common::String loadMessage(uint idx) const { return _messages[idx - 1]; }
+	virtual Common::String loadMessage(uint idx) const = 0;
 	virtual void printMessage(uint idx);
 	void delay(uint32 ms) const;
 
@@ -317,7 +317,7 @@ protected:
 	typedef Common::Functor1<ScriptEnv &, int> Opcode;
 	Common::Array<const Opcode *> _condOpcodes, _actOpcodes;
 	// Message strings in data file
-	Common::Array<Common::String> _messages;
+	Common::Array<DataBlockPtr> _messages;
 	// Picture data
 	PictureMap _pictures;
 	// Dropped item screen offsets
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 90ed794..39cf0a7 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -161,6 +161,15 @@ void AdlEngine_v2::checkTextOverflow(char c) {
 	}
 }
 
+Common::String AdlEngine_v2::loadMessage(uint idx) const {
+	if (_messages[idx]) {
+		StreamPtr strStream(_messages[idx]->createReadStream());
+		return readString(*strStream, 0xff);
+	}
+
+	return Common::String();
+}
+
 void AdlEngine_v2::printString(const Common::String &str) {
 	Common::String s(str);
 	byte endPos = TEXT_WIDTH - 1;
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 2251a93..947b0d8 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -46,6 +46,7 @@ protected:
 	byte roomArg(byte room) const;
 	void advanceClock();
 	void printString(const Common::String &str);
+	Common::String loadMessage(uint idx) const;
 	void drawItems();
 	void drawItem(Item &item, const Common::Point &pos);
 	void loadRoom(byte roomNr);
diff --git a/engines/adl/console.cpp b/engines/adl/console.cpp
index c62d21c..0415bcd 100644
--- a/engines/adl/console.cpp
+++ b/engines/adl/console.cpp
@@ -300,7 +300,7 @@ void Console::printItem(const Item &item) {
 		name = _engine->_priNouns[item.noun - 1];
 
 	if (item.description > 0) {
-		desc = toAscii(_engine->_messages[item.description - 1]);
+		desc = toAscii(_engine->loadMessage(item.description));
 		if (desc.lastChar() == '\r')
 			desc.deleteLastChar();
 	}
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 9193c27..4b3a83d 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -137,18 +137,13 @@ void HiRes1Engine::init() {
 
 	_graphics = new Graphics_v1(*_display);
 
-	StreamPtr stream(_files->createReadStream(IDS_HR1_MESSAGES));
-
-	for (uint i = 0; i < IDI_HR1_NUM_MESSAGES; ++i)
-		_messages.push_back(readString(*stream, APPLECHAR('\r')) + APPLECHAR('\r'));
-
-	stream.reset(_files->createReadStream(IDS_HR1_EXE_1));
+	StreamPtr stream(_files->createReadStream(IDS_HR1_EXE_1));
 
 	// Some messages have overrides inside the executable
-	_messages[IDI_HR1_MSG_CANT_GO_THERE - 1] = readStringAt(*stream, IDI_HR1_OFS_STR_CANT_GO_THERE);
-	_messages[IDI_HR1_MSG_DONT_HAVE_IT - 1] = readStringAt(*stream, IDI_HR1_OFS_STR_DONT_HAVE_IT);
-	_messages[IDI_HR1_MSG_DONT_UNDERSTAND - 1] = readStringAt(*stream, IDI_HR1_OFS_STR_DONT_UNDERSTAND);
-	_messages[IDI_HR1_MSG_GETTING_DARK - 1] = readStringAt(*stream, IDI_HR1_OFS_STR_GETTING_DARK);
+	_gameStrings.cantGoThere = readStringAt(*stream, IDI_HR1_OFS_STR_CANT_GO_THERE);
+	_gameStrings.dontHaveIt = readStringAt(*stream, IDI_HR1_OFS_STR_DONT_HAVE_IT);
+	_gameStrings.dontUnderstand = readStringAt(*stream, IDI_HR1_OFS_STR_DONT_UNDERSTAND);
+	_gameStrings.gettingDark = readStringAt(*stream, IDI_HR1_OFS_STR_GETTING_DARK);
 
 	// Load other strings from executable
 	_strings.enterCommand = readStringAt(*stream, IDI_HR1_OFS_STR_ENTER_COMMAND);
@@ -165,6 +160,11 @@ void HiRes1Engine::init() {
 	_messageIds.itemNotHere = IDI_HR1_MSG_ITEM_NOT_HERE;
 	_messageIds.thanksForPlaying = IDI_HR1_MSG_THANKS_FOR_PLAYING;
 
+	// Load message offsets
+	stream->seek(IDI_HR1_OFS_MSGS);
+	for (uint i = 0; i < IDI_HR1_NUM_MESSAGES; ++i)
+		_messages.push_back(_files->getDataBlock(IDS_HR1_MESSAGES, stream->readUint16LE()));
+
 	// Load picture data from executable
 	stream->seek(IDI_HR1_OFS_PICS);
 	for (uint i = 1; i <= IDI_HR1_NUM_PICS; ++i) {
@@ -267,9 +267,12 @@ void HiRes1Engine::printString(const Common::String &str) {
 		delay(14 * 166018 / 1000);
 }
 
-void HiRes1Engine::printMessage(uint idx) {
-	const Common::String &msg = loadMessage(idx);
+Common::String HiRes1Engine::loadMessage(uint idx) const {
+	StreamPtr stream(_messages[idx]->createReadStream());
+	return readString(*stream, APPLECHAR('\r')) + APPLECHAR('\r');
+}
 
+void HiRes1Engine::printMessage(uint idx) {
 	// Messages with hardcoded overrides don't delay after printing.
 	// It's unclear if this is a bug or not. In some cases the result
 	// is that these strings will scroll past the four-line text window
@@ -279,14 +282,20 @@ void HiRes1Engine::printMessage(uint idx) {
 	// that system for this game as well.
 	switch (idx) {
 	case IDI_HR1_MSG_CANT_GO_THERE:
+		_display->printString(_gameStrings.cantGoThere);
+		return;
 	case IDI_HR1_MSG_DONT_HAVE_IT:
+		_display->printString(_gameStrings.dontHaveIt);
+		return;
 	case IDI_HR1_MSG_DONT_UNDERSTAND:
+		_display->printString(_gameStrings.dontUnderstand);
+		return;
 	case IDI_HR1_MSG_GETTING_DARK:
-		_display->printString(msg);
+		_display->printString(_gameStrings.gettingDark);
 		return;
+	default:
+		printString(loadMessage(idx));
 	}
-
-	printString(msg);
 }
 
 void HiRes1Engine::drawItems() {
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index 8dc7081..273b781 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -45,7 +45,7 @@ namespace Adl {
 #define IDI_HR1_NUM_PICS          97
 #define IDI_HR1_NUM_VARS          20
 #define IDI_HR1_NUM_ITEM_OFFSETS  21
-#define IDI_HR1_NUM_MESSAGES     167
+#define IDI_HR1_NUM_MESSAGES     168
 
 // Messages used outside of scripts
 #define IDI_HR1_MSG_CANT_GO_THERE      137
@@ -83,6 +83,7 @@ namespace Adl {
 #define IDI_HR1_OFS_PICS         0x4b03
 #define IDI_HR1_OFS_CMDS_0       0x3c00
 #define IDI_HR1_OFS_CMDS_1       0x3d00
+#define IDI_HR1_OFS_MSGS         0x4d00
 
 #define IDI_HR1_OFS_ITEM_OFFSETS 0x68ff
 #define IDI_HR1_OFS_CORNERS      0x4f00
@@ -105,6 +106,7 @@ private:
 	void initState();
 	void restartGame();
 	void printString(const Common::String &str);
+	Common::String loadMessage(uint idx) const;
 	void printMessage(uint idx);
 	void drawItems();
 	void drawItem(Item &item, const Common::Point &pos);
@@ -118,6 +120,13 @@ private:
 	Common::Array<DataBlockPtr> _corners;
 	Common::Array<byte> _roomDesc;
 	bool _messageDelay;
+
+	struct {
+		Common::String cantGoThere;
+		Common::String dontHaveIt;
+		Common::String dontUnderstand;
+		Common::String gettingDark;
+	} _gameStrings;
 };
 
 } // End of namespace Adl
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index a0fa5a0..06fdc5f 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -54,18 +54,10 @@ void HiRes2Engine::init() {
 	if (!_disk->open(IDS_HR2_DISK_IMAGE))
 		error("Failed to open disk image '" IDS_HR2_DISK_IMAGE "'");
 
-	StreamPtr stream(_disk->createReadStream(0x1f, 0x2, 0x04, 4));
+	StreamPtr stream(_disk->createReadStream(0x1f, 0x2, 0x00, 4));
 
-	for (uint i = 0; i < IDI_HR2_NUM_MESSAGES; ++i) {
-		DataBlockPtr str(readDataBlockPtr(*stream));
-
-		if (str) {
-			StreamPtr strStream(str->createReadStream());
-			_messages.push_back(readString(*strStream, 0xff));
-		} else {
-			_messages.push_back(Common::String());
-		}
-	}
+	for (uint i = 0; i < IDI_HR2_NUM_MESSAGES; ++i)
+		_messages.push_back(readDataBlockPtr(*stream));
 
 	// Read parser messages
 	stream.reset(_disk->createReadStream(0x1a, 0x1));
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index b99fd66..6647e00 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -38,7 +38,7 @@ namespace Adl {
 #define IDS_HR2_DISK_IMAGE "WIZARD.DSK"
 
 #define IDI_HR2_NUM_ROOMS 135
-#define IDI_HR2_NUM_MESSAGES 254
+#define IDI_HR2_NUM_MESSAGES 255
 #define IDI_HR2_NUM_VARS 40
 #define IDI_HR2_NUM_ITEM_PICS 38
 #define IDI_HR2_NUM_ITEM_OFFSETS 16
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index a87cb7b..e15cf43 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -115,10 +115,6 @@ void HiRes6Engine::init() {
 	if (!boot->open(disks[0]))
 		error("Failed to open disk image '%s'", disks[0]);
 
-	// TODO (needs refactoring of message handling)
-	for (uint i = 0; i < 256; ++i)
-		_messages.push_back(Common::String());
-
 	StreamPtr stream(loadSectors(boot, 7));
 
 	// Read parser messages
@@ -165,7 +161,7 @@ void HiRes6Engine::init() {
 	}
 
 	// Load global picture data
-	stream.reset(_disk->createReadStream(0x1f, 0xf, 0x16, 0));
+	stream.reset(_disk->createReadStream(0x1f, 0xf, 0x16));
 	byte picNr;
 	while ((picNr = stream->readByte()) != 0xff) {
 		if (stream->eos() || stream->err())
@@ -173,6 +169,11 @@ void HiRes6Engine::init() {
 		_pictures[picNr] = readDataBlockPtr(*stream);
 	}
 
+	// Load message offsets
+	stream.reset(_disk->createReadStream(0x1f, 0xb, 0x16, 4));
+	for (uint i = 0; i < IDI_HR6_NUM_MESSAGES; ++i)
+		_messages.push_back(readDataBlockPtr(*stream));
+
 	// Load commands
 	stream.reset(_disk->createReadStream(0x21, 0x4, 0x85, 7));
 	readCommands(*stream, _roomCommands);
diff --git a/engines/adl/hires6.h b/engines/adl/hires6.h
index 99e9371..c4e279d 100644
--- a/engines/adl/hires6.h
+++ b/engines/adl/hires6.h
@@ -36,7 +36,7 @@ class Point;
 namespace Adl {
 
 #define IDI_HR6_NUM_ROOMS 35
-#define IDI_HR6_NUM_MESSAGES 255
+#define IDI_HR6_NUM_MESSAGES 256
 #define IDI_HR6_NUM_VARS 40
 #define IDI_HR6_NUM_ITEM_PICS 15
 #define IDI_HR6_NUM_ITEM_OFFSETS 16


Commit: ca47d3bb2273f5fde754bb51ef500e0eca3a25ed
    https://github.com/scummvm/scummvm/commit/ca47d3bb2273f5fde754bb51ef500e0eca3a25ed
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Decrypt hires6 messages

Changed paths:
  A engines/adl/adl_v3.cpp
  A engines/adl/adl_v3.h
    engines/adl/hires6.h
    engines/adl/module.mk



diff --git a/engines/adl/adl_v3.cpp b/engines/adl/adl_v3.cpp
new file mode 100644
index 0000000..608c22b
--- /dev/null
+++ b/engines/adl/adl_v3.cpp
@@ -0,0 +1,125 @@
+/* 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_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) {
+}
+
+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;
+}
+
+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(o1_isItemInRoom);
+	// 0x04
+	Opcode(o2_isNounNotInRoom);
+	Opcode(o1_isMovesGT);
+	Opcode(o1_isVarEQ);
+	Opcode(o2_isCarryingSomething);
+	// 0x08
+	Opcode(o3_isVarGT);
+	Opcode(o1_isCurPicEQ);
+	Opcode(o1_isItemPicEQ);
+
+	SetOpcodeTable(_actOpcodes);
+	// 0x00
+	OpcodeUnImpl();
+	Opcode(o1_varAdd);
+	Opcode(o1_varSub);
+	Opcode(o1_varSet);
+	// 0x04
+	Opcode(o1_listInv);
+	Opcode(o2_moveItem);
+	Opcode(o1_setRoom);
+	Opcode(o1_setCurPic);
+	// 0x08
+	Opcode(o1_setPic);
+	Opcode(o1_printMsg);
+	Opcode(o1_setLight);
+	Opcode(o1_setDark);
+	// 0x0c
+	Opcode(o2_moveAllItems);
+	Opcode(o1_quit);
+	OpcodeUnImpl();
+	Opcode(o2_save);
+	// 0x10
+	Opcode(o2_restore);
+	Opcode(o1_restart);
+	Opcode(o2_placeItem);
+	Opcode(o1_setItemPic);
+	// 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(o2_tellTime);
+	Opcode(o2_setRoomFromVar);
+	// 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;
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/adl_v3.h b/engines/adl/adl_v3.h
new file mode 100644
index 0000000..c0b7fad
--- /dev/null
+++ b/engines/adl/adl_v3.h
@@ -0,0 +1,53 @@
+/* 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_V3_H
+#define ADL_ADL_V3_H
+
+#include "adl/adl_v2.h"
+
+// Note: this version of ADL redraws only when necessary, but
+// this is not currently implemented.
+
+namespace Common{
+class RandomSource;
+}
+
+namespace Adl {
+
+class AdlEngine_v3 : public AdlEngine_v2 {
+public:
+	virtual ~AdlEngine_v3() { }
+
+protected:
+	AdlEngine_v3(OSystem *syst, const AdlGameDescription *gd);
+
+	// AdlEngine
+	virtual void setupOpcodeTables();
+	virtual Common::String loadMessage(uint idx) const;
+
+	int o3_isVarGT(ScriptEnv &e);
+};
+
+} // End of namespace Adl
+
+#endif
diff --git a/engines/adl/hires6.h b/engines/adl/hires6.h
index c4e279d..395e852 100644
--- a/engines/adl/hires6.h
+++ b/engines/adl/hires6.h
@@ -25,7 +25,7 @@
 
 #include "common/str.h"
 
-#include "adl/adl_v2.h"
+#include "adl/adl_v3.h"
 #include "adl/disk.h"
 
 namespace Common {
@@ -48,9 +48,9 @@ namespace Adl {
 #define IDI_HR6_MSG_ITEM_NOT_HERE      254
 #define IDI_HR6_MSG_THANKS_FOR_PLAYING 252
 
-class HiRes6Engine : public AdlEngine_v2 {
+class HiRes6Engine : public AdlEngine_v3 {
 public:
-	HiRes6Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine_v2(syst, gd) { }
+	HiRes6Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine_v3(syst, gd) { }
 
 private:
 	// AdlEngine
diff --git a/engines/adl/module.mk b/engines/adl/module.mk
index c726a6b..7ab37ef 100644
--- a/engines/adl/module.mk
+++ b/engines/adl/module.mk
@@ -3,6 +3,7 @@ MODULE := engines/adl
 MODULE_OBJS := \
 	adl.o \
 	adl_v2.o \
+	adl_v3.o \
 	console.o \
 	detection.o \
 	disk.o \


Commit: 6044022c8ed3349242d86206adb57cb9f4f3031e
    https://github.com/scummvm/scummvm/commit/6044022c8ed3349242d86206adb57cb9f4f3031e
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Add '%' string code processing for hires6

Changed paths:
    engines/adl/adl_v2.h
    engines/adl/hires6.cpp
    engines/adl/hires6.h



diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 947b0d8..60af4de 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -45,8 +45,8 @@ protected:
 	virtual void setupOpcodeTables();
 	byte roomArg(byte room) const;
 	void advanceClock();
-	void printString(const Common::String &str);
-	Common::String loadMessage(uint idx) const;
+	virtual void printString(const Common::String &str);
+	virtual Common::String loadMessage(uint idx) const;
 	void drawItems();
 	void drawItem(Item &item, const Common::Point &pos);
 	void loadRoom(byte roomNr);
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index e15cf43..7ac953c 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -246,6 +246,39 @@ void HiRes6Engine::applyDataBlockOffset(byte &track, byte &sector) const {
 	++track;
 }
 
+void HiRes6Engine::printString(const Common::String &str) {
+	Common::String s;
+	uint found = 0;
+
+	// This does not emulate the corner cases of the original, hence this check
+	if (getVar(27) > 1)
+		error("Invalid value %i encountered for variable 27", getVar(27));
+
+	for (uint i = 0; i < str.size(); ++i) {
+		if (str[i] == '%') {
+			++found;
+			if (found == 3)
+				found = 0;
+			continue;
+		}
+
+		switch (found) {
+		case 0:
+			s += str[i];
+			break;
+		case 1:
+			if (getVar(27) == 0)
+				s += str[i];
+			break;
+		case 2:
+			if (getVar(27) == 1)
+				s += str[i];
+		}
+	}
+
+	AdlEngine_v2::printString(s);
+}
+
 Engine *HiRes6Engine_create(OSystem *syst, const AdlGameDescription *gd) {
 	return new HiRes6Engine(syst, gd);
 }
diff --git a/engines/adl/hires6.h b/engines/adl/hires6.h
index 395e852..a845070 100644
--- a/engines/adl/hires6.h
+++ b/engines/adl/hires6.h
@@ -59,6 +59,7 @@ private:
 	void initState();
 
 	// AdlEngine_v2
+	void printString(const Common::String &str);
 	void applyDataBlockOffset(byte &track, byte &sector) const;
 };
 


Commit: 8cc5100afd022f089bcba1cfc9b90d64601b2754
    https://github.com/scummvm/scummvm/commit/8cc5100afd022f089bcba1cfc9b90d64601b2754
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Fix OB1 bug in ADL v2 word wrapping

Changed paths:
    engines/adl/adl_v2.cpp



diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 39cf0a7..dba6b61 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -176,7 +176,7 @@ void AdlEngine_v2::printString(const Common::String &str) {
 	byte pos = 0;
 
 	while (true) {
-		while (pos != endPos && pos != s.size()) {
+		while (pos <= endPos && pos != s.size()) {
 			s.setChar(APPLECHAR(s[pos]), pos);
 			++pos;
 		}


Commit: 5fe95d51ea3d35e9de725a08b3681fbc3f8844bc
    https://github.com/scummvm/scummvm/commit/5fe95d51ea3d35e9de725a08b3681fbc3f8844bc
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Separate game-specific state init

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/adl_v2.cpp
    engines/adl/adl_v2.h
    engines/adl/hires1.cpp
    engines/adl/hires1.h
    engines/adl/hires2.cpp
    engines/adl/hires2.h
    engines/adl/hires6.cpp
    engines/adl/hires6.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 37f1d04..328638a 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -379,6 +379,12 @@ void AdlEngine::setupOpcodeTables() {
 	Opcode(o1_setRoomPic);
 }
 
+void AdlEngine::initState() {
+	_state = State();
+
+	initGameState();
+}
+
 byte AdlEngine::roomArg(byte room) const {
 	return room;
 }
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 14e38eb..f7a6ed9 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -240,6 +240,7 @@ protected:
 	virtual bool isInputValid(const Commands &commands, byte verb, byte noun, bool &is_any);
 
 	virtual void setupOpcodeTables();
+	virtual void initState();
 	virtual byte roomArg(byte room) const;
 	virtual void advanceClock() { }
 
@@ -358,7 +359,7 @@ protected:
 private:
 	virtual void runIntro() const { }
 	virtual void init() = 0;
-	virtual void initState() = 0;
+	virtual void initGameState() = 0;
 	virtual void drawItems() = 0;
 	virtual void drawItem(Item &item, const Common::Point &pos) = 0;
 	virtual void loadRoom(byte roomNr) = 0;
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index dba6b61..55060be 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -114,6 +114,16 @@ void AdlEngine_v2::setupOpcodeTables() {
 	Opcode(o2_initDisk);
 }
 
+void AdlEngine_v2::initState() {
+	AdlEngine::initState();
+
+	_linesPrinted = 0;
+	_picOnScreen = 0;
+	_roomOnScreen = 0;
+	_itemRemoved = false;
+	_itemsOnScreen = 0;
+}
+
 byte AdlEngine_v2::roomArg(byte room) const {
 	if (room == IDI_CUR_ROOM)
 		return _state.room;
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 60af4de..fa12a48 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -43,6 +43,7 @@ protected:
 
 	// AdlEngine
 	virtual void setupOpcodeTables();
+	virtual void initState();
 	byte roomArg(byte room) const;
 	void advanceClock();
 	virtual void printString(const Common::String &str);
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 4b3a83d..c8b9989 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -206,8 +206,7 @@ void HiRes1Engine::init() {
 	loadWords(*stream, _nouns, _priNouns);
 }
 
-void HiRes1Engine::initState() {
-	_state = State();
+void HiRes1Engine::initGameState() {
 	_state.vars.resize(IDI_HR1_NUM_VARS);
 
 	StreamPtr stream(_files->createReadStream(IDS_HR1_EXE_1));
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index 273b781..c060bc8 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -103,7 +103,7 @@ private:
 	// AdlEngine
 	void runIntro() const;
 	void init();
-	void initState();
+	void initGameState();
 	void restartGame();
 	void printString(const Common::String &str);
 	Common::String loadMessage(uint idx) const;
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 06fdc5f..d1dd065 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -130,10 +130,7 @@ void HiRes2Engine::init() {
 	loadWords(*stream, _nouns, _priNouns);
 }
 
-void HiRes2Engine::initState() {
-	_linesPrinted = 0;
-
-	_state = State();
+void HiRes2Engine::initGameState() {
 	_state.vars.resize(IDI_HR2_NUM_VARS);
 
 	StreamPtr stream(_disk->createReadStream(0x21, 0x5, 0x0e, 7));
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 6647e00..7a0769a 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -58,7 +58,7 @@ private:
 	// AdlEngine
 	void runIntro() const;
 	void init();
-	void initState();
+	void initGameState();
 };
 
 } // End of namespace Adl
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index 7ac953c..37c7154 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -192,10 +192,7 @@ void HiRes6Engine::init() {
 	delete boot;
 }
 
-void HiRes6Engine::initState() {
-	_linesPrinted = 0;
-
-	_state = State();
+void HiRes6Engine::initGameState() {
 	_state.vars.resize(IDI_HR6_NUM_VARS);
 
 	StreamPtr stream(_disk->createReadStream(0x20, 0xd, 0x94, 2));
diff --git a/engines/adl/hires6.h b/engines/adl/hires6.h
index a845070..a2f6e42 100644
--- a/engines/adl/hires6.h
+++ b/engines/adl/hires6.h
@@ -56,7 +56,7 @@ private:
 	// AdlEngine
 	void runIntro() const;
 	void init();
-	void initState();
+	void initGameState();
 
 	// AdlEngine_v2
 	void printString(const Common::String &str);


Commit: bf520ca3211a1638396efe71e19291e7dbd979c0
    https://github.com/scummvm/scummvm/commit/bf520ca3211a1638396efe71e19291e7dbd979c0
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Fix restarting from AllCommands list

Changed paths:
    engines/adl/adl.cpp



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 328638a..b77f8da 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -573,6 +573,12 @@ Common::Error AdlEngine::run() {
 		}
 
 		doAllCommands(_globalCommands, verb, noun);
+
+		if (_isRestarting) {
+			_isRestarting = false;
+			continue;
+		}
+
 		advanceClock();
 		_state.moves++;
 	}
@@ -1197,8 +1203,12 @@ void AdlEngine::doAllCommands(const Commands &commands, byte verb, byte noun) {
 
 	for (cmd = commands.begin(); cmd != commands.end(); ++cmd) {
 		ScriptEnv env(*cmd, _state.room, verb, noun);
-		if (matchCommand(env))
+		if (matchCommand(env)) {
 			doActions(env);
+			// The original long jumps on restart, so we need to abort here
+			if (_isRestarting)
+				return;
+		}
 	}
 }
 


Commit: 7e9a8c00728592290c2c4f2ba0aa5bf3bf7efff9
    https://github.com/scummvm/scummvm/commit/7e9a8c00728592290c2c4f2ba0aa5bf3bf7efff9
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Partially implement hires6 var handling

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/adl_v2.cpp
    engines/adl/hires1.cpp
    engines/adl/hires6.cpp
    engines/adl/hires6.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index b77f8da..98895ce 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -385,6 +385,10 @@ void AdlEngine::initState() {
 	initGameState();
 }
 
+void AdlEngine::printRoomDescription() {
+	printString(_roomData.description);
+}
+
 byte AdlEngine::roomArg(byte room) const {
 	return room;
 }
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index f7a6ed9..e5fbf35 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -241,6 +241,7 @@ protected:
 
 	virtual void setupOpcodeTables();
 	virtual void initState();
+	virtual void printRoomDescription();
 	virtual byte roomArg(byte room) const;
 	virtual void advanceClock() { }
 
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 55060be..05cfaac 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -278,7 +278,7 @@ void AdlEngine_v2::showRoom() {
 		drawItems();
 
 	_display->updateHiResScreen();
-	printString(_roomData.description);
+	printRoomDescription();
 
 	// FIXME: move to main loop?
 	_linesPrinted = 0;
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index c8b9989..7a85d89 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -348,7 +348,7 @@ void HiRes1Engine::showRoom() {
 
 	_display->updateHiResScreen();
 	_messageDelay = false;
-	printString(_roomData.description);
+	printRoomDescription();
 	_messageDelay = true;
 }
 
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index 37c7154..5bc7711 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -236,6 +236,13 @@ void HiRes6Engine::initGameState() {
 
 		_state.items.push_back(item);
 	}
+
+	_currVerb = _currNoun = 0;
+}
+
+void HiRes6Engine::printRoomDescription() {
+	setVar(2, 0xff);
+	AdlEngine_v3::printRoomDescription();
 }
 
 void HiRes6Engine::applyDataBlockOffset(byte &track, byte &sector) const {
@@ -256,24 +263,28 @@ void HiRes6Engine::printString(const Common::String &str) {
 			++found;
 			if (found == 3)
 				found = 0;
-			continue;
-		}
-
-		switch (found) {
-		case 0:
-			s += str[i];
-			break;
-		case 1:
-			if (getVar(27) == 0)
-				s += str[i];
-			break;
-		case 2:
-			if (getVar(27) == 1)
+		} else {
+			if (found == 0 || found - 1 == getVar(27))
 				s += str[i];
 		}
 	}
 
-	AdlEngine_v2::printString(s);
+	if (getVar(2) != 0xff) {
+		AdlEngine_v2::printString(s);
+	} else {
+		if (getVar(26) == 0) {
+			if (str.size() != 1 || APPLECHAR(str[0]) != APPLECHAR(' '))
+				return AdlEngine_v2::printString(s);
+			setVar(2, APPLECHAR(' '));
+		} else if (getVar(26) == 0xff) {
+			setVar(2, 'P');
+		} else {
+			setVar(26, _state.room);
+			setVar(2, 1);
+		}
+
+		doAllCommands(_globalCommands, _currVerb, _currNoun);
+	}
 }
 
 Engine *HiRes6Engine_create(OSystem *syst, const AdlGameDescription *gd) {
diff --git a/engines/adl/hires6.h b/engines/adl/hires6.h
index a2f6e42..42211d1 100644
--- a/engines/adl/hires6.h
+++ b/engines/adl/hires6.h
@@ -50,17 +50,20 @@ namespace Adl {
 
 class HiRes6Engine : public AdlEngine_v3 {
 public:
-	HiRes6Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine_v3(syst, gd) { }
+	HiRes6Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine_v3(syst, gd), _currVerb(0), _currNoun(0) { }
 
 private:
 	// AdlEngine
 	void runIntro() const;
 	void init();
 	void initGameState();
+	void printRoomDescription();
 
 	// AdlEngine_v2
 	void printString(const Common::String &str);
 	void applyDataBlockOffset(byte &track, byte &sector) const;
+
+	byte _currVerb, _currNoun;
 };
 
 } // End of namespace Adl


Commit: b8c40f9a8b81631c610c0bdadaefb4b9b7df5792
    https://github.com/scummvm/scummvm/commit/b8c40f9a8b81631c610c0bdadaefb4b9b7df5792
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Implement hires6 cond opcode 0xa

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/adl_v3.cpp
    engines/adl/adl_v3.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 98895ce..fdbb2aa 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -58,6 +58,7 @@ AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) :
 		_graphics(nullptr),
 		_isRestarting(false),
 		_isRestoring(false),
+		_skipOneCommand(false),
 		_gameDescription(gd),
 		_saveVerb(0),
 		_saveNoun(0),
@@ -1192,6 +1193,12 @@ bool AdlEngine::doOneCommand(const Commands &commands, byte verb, byte noun) {
 	Commands::const_iterator cmd;
 
 	for (cmd = commands.begin(); cmd != commands.end(); ++cmd) {
+
+		if (_skipOneCommand) {
+			_skipOneCommand = false;
+			continue;
+		}
+
 		ScriptEnv env(*cmd, _state.room, verb, noun);
 		if (matchCommand(env)) {
 			doActions(env);
@@ -1199,6 +1206,7 @@ bool AdlEngine::doOneCommand(const Commands &commands, byte verb, byte noun) {
 		}
 	}
 
+	_skipOneCommand = false;
 	return false;
 }
 
@@ -1206,6 +1214,11 @@ void AdlEngine::doAllCommands(const Commands &commands, byte verb, byte noun) {
 	Commands::const_iterator cmd;
 
 	for (cmd = commands.begin(); cmd != commands.end(); ++cmd) {
+		if (_skipOneCommand) {
+			_skipOneCommand = false;
+			continue;
+		}
+
 		ScriptEnv env(*cmd, _state.room, verb, noun);
 		if (matchCommand(env)) {
 			doActions(env);
@@ -1214,6 +1227,8 @@ void AdlEngine::doAllCommands(const Commands &commands, byte verb, byte noun) {
 				return;
 		}
 	}
+
+	_skipOneCommand = false;
 }
 
 Common::String AdlEngine::toAscii(const Common::String &str) {
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index e5fbf35..06d378e 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -356,6 +356,7 @@ protected:
 	State _state;
 
 	bool _isRestarting, _isRestoring;
+	bool _skipOneCommand;
 
 private:
 	virtual void runIntro() const { }
diff --git a/engines/adl/adl_v3.cpp b/engines/adl/adl_v3.cpp
index 608c22b..e326b05 100644
--- a/engines/adl/adl_v3.cpp
+++ b/engines/adl/adl_v3.cpp
@@ -66,7 +66,7 @@ void AdlEngine_v3::setupOpcodeTables() {
 	// 0x08
 	Opcode(o3_isVarGT);
 	Opcode(o1_isCurPicEQ);
-	Opcode(o1_isItemPicEQ);
+	Opcode(o3_skipOneCommand);
 
 	SetOpcodeTable(_actOpcodes);
 	// 0x00
@@ -122,4 +122,14 @@ int AdlEngine_v3::o3_isVarGT(ScriptEnv &e) {
 	return -1;
 }
 
+// FIXME: Move to HiRes6 class?
+int AdlEngine_v3::o3_skipOneCommand(ScriptEnv &e) {
+	OP_DEBUG_0("\t&& SKIP_NEXT_COMMAND()");
+
+	_skipOneCommand = true;
+	setVar(2, 0);
+
+	return -1;
+}
+
 } // End of namespace Adl
diff --git a/engines/adl/adl_v3.h b/engines/adl/adl_v3.h
index c0b7fad..f99e0bd 100644
--- a/engines/adl/adl_v3.h
+++ b/engines/adl/adl_v3.h
@@ -46,6 +46,7 @@ protected:
 	virtual Common::String loadMessage(uint idx) const;
 
 	int o3_isVarGT(ScriptEnv &e);
+	int o3_skipOneCommand(ScriptEnv &e);
 };
 
 } // End of namespace Adl


Commit: bb6cd4612dd25d93c6b7d928b8aec5537dac9480
    https://github.com/scummvm/scummvm/commit/bb6cd4612dd25d93c6b7d928b8aec5537dac9480
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Fix bug in hires6 printString

Changed paths:
    engines/adl/hires6.cpp



diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index 5bc7711..4ee5663 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -276,7 +276,7 @@ void HiRes6Engine::printString(const Common::String &str) {
 			if (str.size() != 1 || APPLECHAR(str[0]) != APPLECHAR(' '))
 				return AdlEngine_v2::printString(s);
 			setVar(2, APPLECHAR(' '));
-		} else if (getVar(26) == 0xff) {
+		} else if (getVar(26) != 0xff) {
 			setVar(2, 'P');
 		} else {
 			setVar(26, _state.room);


Commit: 04604ed6023aa322660f3ab5e93a3a067b22bbf4
    https://github.com/scummvm/scummvm/commit/04604ed6023aa322660f3ab5e93a3a067b22bbf4
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Implement hires6 showRoom() var handling

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/adl_v2.cpp
    engines/adl/adl_v2.h
    engines/adl/hires1.cpp
    engines/adl/hires6.cpp
    engines/adl/hires6.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index fdbb2aa..edcd804 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -386,10 +386,6 @@ void AdlEngine::initState() {
 	initGameState();
 }
 
-void AdlEngine::printRoomDescription() {
-	printString(_roomData.description);
-}
-
 byte AdlEngine::roomArg(byte room) const {
 	return room;
 }
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 06d378e..0cf9024 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -241,7 +241,6 @@ protected:
 
 	virtual void setupOpcodeTables();
 	virtual void initState();
-	virtual void printRoomDescription();
 	virtual byte roomArg(byte room) const;
 	virtual void advanceClock() { }
 
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 05cfaac..55060be 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -278,7 +278,7 @@ void AdlEngine_v2::showRoom() {
 		drawItems();
 
 	_display->updateHiResScreen();
-	printRoomDescription();
+	printString(_roomData.description);
 
 	// FIXME: move to main loop?
 	_linesPrinted = 0;
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index fa12a48..164af7d 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -51,7 +51,7 @@ protected:
 	void drawItems();
 	void drawItem(Item &item, const Common::Point &pos);
 	void loadRoom(byte roomNr);
-	void showRoom();
+	virtual void showRoom();
 	void takeItem(byte noun);
 
 	virtual void applyDataBlockOffset(byte &track, byte &sector) const { }
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 7a85d89..c8b9989 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -348,7 +348,7 @@ void HiRes1Engine::showRoom() {
 
 	_display->updateHiResScreen();
 	_messageDelay = false;
-	printRoomDescription();
+	printString(_roomData.description);
 	_messageDelay = true;
 }
 
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index 4ee5663..7f6de17 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -240,9 +240,51 @@ void HiRes6Engine::initGameState() {
 	_currVerb = _currNoun = 0;
 }
 
-void HiRes6Engine::printRoomDescription() {
+void HiRes6Engine::showRoom() {
+	bool redrawPic = false;
+
+	if (getVar(26) == 0xfe)
+		setVar(26, 0);
+	else if (getVar(26) != 0xff)
+		setVar(26, _state.room);
+
+	if (_state.room != _roomOnScreen) {
+		loadRoom(_state.room);
+
+		if (getVar(26) < 0x80 && getCurRoom().isFirstTime)
+			setVar(26, 0);
+
+		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();
 	setVar(2, 0xff);
-	AdlEngine_v3::printRoomDescription();
+	printString(_roomData.description);
+
+	// FIXME: move to main loop?
+	_linesPrinted = 0;
 }
 
 void HiRes6Engine::applyDataBlockOffset(byte &track, byte &sector) const {
diff --git a/engines/adl/hires6.h b/engines/adl/hires6.h
index 42211d1..9f886aa 100644
--- a/engines/adl/hires6.h
+++ b/engines/adl/hires6.h
@@ -58,6 +58,7 @@ private:
 	void init();
 	void initGameState();
 	void printRoomDescription();
+	void showRoom();
 
 	// AdlEngine_v2
 	void printString(const Common::String &str);


Commit: d2175a70ce3873e09f9f7b7bc84dcc1b614ae054
    https://github.com/scummvm/scummvm/commit/d2175a70ce3873e09f9f7b7bc84dcc1b614ae054
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Implement remaining hires6 conditionals

Changed paths:
    engines/adl/adl_v3.cpp
    engines/adl/adl_v3.h



diff --git a/engines/adl/adl_v3.cpp b/engines/adl/adl_v3.cpp
index e326b05..4f2b344 100644
--- a/engines/adl/adl_v3.cpp
+++ b/engines/adl/adl_v3.cpp
@@ -30,7 +30,8 @@
 namespace Adl {
 
 AdlEngine_v3::AdlEngine_v3(OSystem *syst, const AdlGameDescription *gd) :
-		AdlEngine_v2(syst, gd) {
+		AdlEngine_v2(syst, gd),
+		_curDisk(1) {
 }
 
 Common::String AdlEngine_v3::loadMessage(uint idx) const {
@@ -57,9 +58,9 @@ void AdlEngine_v3::setupOpcodeTables() {
 	OpcodeUnImpl();
 	Opcode(o2_isFirstTime);
 	Opcode(o2_isRandomGT);
-	Opcode(o1_isItemInRoom);
+	Opcode(o3_isItemInRoom);
 	// 0x04
-	Opcode(o2_isNounNotInRoom);
+	Opcode(o3_isNounNotInRoom);
 	Opcode(o1_isMovesGT);
 	Opcode(o1_isVarEQ);
 	Opcode(o2_isCarryingSomething);
@@ -122,9 +123,8 @@ int AdlEngine_v3::o3_isVarGT(ScriptEnv &e) {
 	return -1;
 }
 
-// FIXME: Move to HiRes6 class?
 int AdlEngine_v3::o3_skipOneCommand(ScriptEnv &e) {
-	OP_DEBUG_0("\t&& SKIP_NEXT_COMMAND()");
+	OP_DEBUG_0("\t&& SKIP_ONE_COMMAND()");
 
 	_skipOneCommand = true;
 	setVar(2, 0);
@@ -132,4 +132,36 @@ int AdlEngine_v3::o3_skipOneCommand(ScriptEnv &e) {
 	return -1;
 }
 
+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;
+}
+
+int AdlEngine_v3::o3_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;
+}
+
 } // End of namespace Adl
diff --git a/engines/adl/adl_v3.h b/engines/adl/adl_v3.h
index f99e0bd..7d4790f 100644
--- a/engines/adl/adl_v3.h
+++ b/engines/adl/adl_v3.h
@@ -46,7 +46,12 @@ protected:
 	virtual Common::String loadMessage(uint idx) const;
 
 	int o3_isVarGT(ScriptEnv &e);
+	int o3_isItemInRoom(ScriptEnv &e);
+	int o3_isNounNotInRoom(ScriptEnv &e);
 	int o3_skipOneCommand(ScriptEnv &e);
+
+private:
+	byte _curDisk;
 };
 
 } // End of namespace Adl


Commit: e79f26c9bcda2c08ef7a7628960c71cff336daaf
    https://github.com/scummvm/scummvm/commit/e79f26c9bcda2c08ef7a7628960c71cff336daaf
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Implement hires6 item descriptions

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/adl_v3.cpp
    engines/adl/adl_v3.h
    engines/adl/console.cpp
    engines/adl/hires6.cpp
    engines/adl/hires6.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index edcd804..c17855d 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -127,6 +127,13 @@ void AdlEngine::printMessage(uint idx) {
 	printString(loadMessage(idx));
 }
 
+Common::String AdlEngine::getItemDescription(const Item &item) const {
+	if (item.description > 0)
+		return loadMessage(item.description);
+	else
+		return Common::String();
+}
+
 void AdlEngine::delay(uint32 ms) const {
 	uint32 start = g_system->getMillis();
 
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 0cf9024..a23f6b7 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -228,6 +228,7 @@ protected:
 	virtual void printString(const Common::String &str) = 0;
 	virtual Common::String loadMessage(uint idx) const = 0;
 	virtual void printMessage(uint idx);
+	virtual Common::String getItemDescription(const Item &item) const;
 	void delay(uint32 ms) const;
 
 	Common::String inputString(byte prompt = 0) const;
diff --git a/engines/adl/adl_v3.cpp b/engines/adl/adl_v3.cpp
index 4f2b344..d0e9242 100644
--- a/engines/adl/adl_v3.cpp
+++ b/engines/adl/adl_v3.cpp
@@ -45,6 +45,10 @@ Common::String AdlEngine_v3::loadMessage(uint idx) const {
 	return str;
 }
 
+Common::String AdlEngine_v3::getItemDescription(const Item &item) const {
+	return _itemDesc[item.id - 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))
diff --git a/engines/adl/adl_v3.h b/engines/adl/adl_v3.h
index 7d4790f..f022adf 100644
--- a/engines/adl/adl_v3.h
+++ b/engines/adl/adl_v3.h
@@ -44,13 +44,14 @@ protected:
 	// AdlEngine
 	virtual void setupOpcodeTables();
 	virtual Common::String loadMessage(uint idx) const;
+	Common::String getItemDescription(const Item &item) const;
 
 	int o3_isVarGT(ScriptEnv &e);
 	int o3_isItemInRoom(ScriptEnv &e);
 	int o3_isNounNotInRoom(ScriptEnv &e);
 	int o3_skipOneCommand(ScriptEnv &e);
 
-private:
+	Common::Array<Common::String> _itemDesc;
 	byte _curDisk;
 };
 
diff --git a/engines/adl/console.cpp b/engines/adl/console.cpp
index 0415bcd..c35e8b0 100644
--- a/engines/adl/console.cpp
+++ b/engines/adl/console.cpp
@@ -299,11 +299,9 @@ void Console::printItem(const Item &item) {
 	if (item.noun > 0)
 		name = _engine->_priNouns[item.noun - 1];
 
-	if (item.description > 0) {
-		desc = toAscii(_engine->loadMessage(item.description));
-		if (desc.lastChar() == '\r')
-			desc.deleteLastChar();
-	}
+	desc = toAscii(_engine->getItemDescription(item));
+	if (desc.lastChar() == '\r')
+		desc.deleteLastChar();
 
 	switch (item.state) {
 	case IDI_ITEM_NOT_MOVED:
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index 7f6de17..eaf468c 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -115,7 +115,7 @@ void HiRes6Engine::init() {
 	if (!boot->open(disks[0]))
 		error("Failed to open disk image '%s'", disks[0]);
 
-	StreamPtr stream(loadSectors(boot, 7));
+	StreamPtr stream(loadSectors(boot, 0x7));
 
 	// Read parser messages
 	_strings.verbError = readStringAt(*stream, 0x666);
@@ -139,6 +139,12 @@ void HiRes6Engine::init() {
 	_messageIds.itemNotHere = IDI_HR6_MSG_ITEM_NOT_HERE;
 	_messageIds.thanksForPlaying = IDI_HR6_MSG_THANKS_FOR_PLAYING;
 
+	// Item descriptions
+	stream.reset(loadSectors(boot, 0x6, 0xb, 2));
+	stream->seek(0x34);
+	for (uint i = 0; i < IDI_HR6_NUM_ITEM_DESCS; ++i)
+		_itemDesc.push_back(readString(*stream, 0xff));
+
 	// Load dropped item offsets
 	stream.reset(boot->createReadStream(0x8, 0x9, 0x16));
 	for (uint i = 0; i < IDI_HR6_NUM_ITEM_OFFSETS; ++i) {
diff --git a/engines/adl/hires6.h b/engines/adl/hires6.h
index 9f886aa..443a9ca 100644
--- a/engines/adl/hires6.h
+++ b/engines/adl/hires6.h
@@ -38,6 +38,7 @@ namespace Adl {
 #define IDI_HR6_NUM_ROOMS 35
 #define IDI_HR6_NUM_MESSAGES 256
 #define IDI_HR6_NUM_VARS 40
+#define IDI_HR6_NUM_ITEM_DESCS 15
 #define IDI_HR6_NUM_ITEM_PICS 15
 #define IDI_HR6_NUM_ITEM_OFFSETS 16
 


Commit: e755f8fcba4d3dfc746d83f60b70d2aad86360b9
    https://github.com/scummvm/scummvm/commit/e755f8fcba4d3dfc746d83f60b70d2aad86360b9
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Implement hires6 "move item" opcode

Changed paths:
    engines/adl/adl_v3.cpp
    engines/adl/adl_v3.h



diff --git a/engines/adl/adl_v3.cpp b/engines/adl/adl_v3.cpp
index d0e9242..9041a47 100644
--- a/engines/adl/adl_v3.cpp
+++ b/engines/adl/adl_v3.cpp
@@ -81,7 +81,7 @@ void AdlEngine_v3::setupOpcodeTables() {
 	Opcode(o1_varSet);
 	// 0x04
 	Opcode(o1_listInv);
-	Opcode(o2_moveItem);
+	Opcode(o3_moveItem);
 	Opcode(o1_setRoom);
 	Opcode(o1_setCurPic);
 	// 0x08
@@ -136,6 +136,7 @@ int AdlEngine_v3::o3_skipOneCommand(ScriptEnv &e) {
 	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());
 
@@ -168,4 +169,23 @@ int AdlEngine_v3::o3_isNounNotInRoom(ScriptEnv &e) {
 	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;
+}
+
 } // End of namespace Adl
diff --git a/engines/adl/adl_v3.h b/engines/adl/adl_v3.h
index f022adf..77b64fd 100644
--- a/engines/adl/adl_v3.h
+++ b/engines/adl/adl_v3.h
@@ -50,6 +50,7 @@ protected:
 	int o3_isItemInRoom(ScriptEnv &e);
 	int o3_isNounNotInRoom(ScriptEnv &e);
 	int o3_skipOneCommand(ScriptEnv &e);
+	int o3_moveItem(ScriptEnv &e);
 
 	Common::Array<Common::String> _itemDesc;
 	byte _curDisk;


Commit: 92b1b287b1686424a58abfb06661916bf3dfcaeb
    https://github.com/scummvm/scummvm/commit/92b1b287b1686424a58abfb06661916bf3dfcaeb
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Preliminary support for hires6 disk changing

Changed paths:
    engines/adl/adl.cpp
    engines/adl/hires6.cpp
    engines/adl/hires6.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index c17855d..761b60c 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -219,6 +219,9 @@ byte AdlEngine::inputKey(bool showCursor) const {
 void AdlEngine::loadWords(Common::ReadStream &stream, WordMap &map, Common::StringArray &pri) const {
 	uint index = 0;
 
+	map.clear();
+	pri.clear();
+
 	while (1) {
 		++index;
 
@@ -255,6 +258,8 @@ void AdlEngine::loadWords(Common::ReadStream &stream, WordMap &map, Common::Stri
 }
 
 void AdlEngine::readCommands(Common::ReadStream &stream, Commands &commands) {
+	commands.clear();
+
 	while (1) {
 		Command command;
 		command.room = stream.readByte();
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index eaf468c..c3c4138 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -109,13 +109,13 @@ void HiRes6Engine::runIntro() const {
 }
 
 void HiRes6Engine::init() {
-	DiskImage_DSK *boot(new DiskImage_DSK());
+	_boot = new DiskImage_DSK();
 	_graphics = new Graphics_v2(*_display);
 
-	if (!boot->open(disks[0]))
+	if (!_boot->open(disks[0]))
 		error("Failed to open disk image '%s'", disks[0]);
 
-	StreamPtr stream(loadSectors(boot, 0x7));
+	StreamPtr stream(loadSectors(_boot, 0x7));
 
 	// Read parser messages
 	_strings.verbError = readStringAt(*stream, 0x666);
@@ -140,13 +140,13 @@ void HiRes6Engine::init() {
 	_messageIds.thanksForPlaying = IDI_HR6_MSG_THANKS_FOR_PLAYING;
 
 	// Item descriptions
-	stream.reset(loadSectors(boot, 0x6, 0xb, 2));
+	stream.reset(loadSectors(_boot, 0x6, 0xb, 2));
 	stream->seek(0x34);
 	for (uint i = 0; i < IDI_HR6_NUM_ITEM_DESCS; ++i)
 		_itemDesc.push_back(readString(*stream, 0xff));
 
 	// Load dropped item offsets
-	stream.reset(boot->createReadStream(0x8, 0x9, 0x16));
+	stream.reset(_boot->createReadStream(0x8, 0x9, 0x16));
 	for (uint i = 0; i < IDI_HR6_NUM_ITEM_OFFSETS; ++i) {
 		Common::Point p;
 		p.x = stream->readByte();
@@ -154,68 +154,129 @@ void HiRes6Engine::init() {
 		_itemOffsets.push_back(p);
 	}
 
+	// Location of game data for each disc
+	stream.reset(_boot->createReadStream(0x5, 0xa, 0x03));
+	for (uint i = 0; i < sizeof(disks); ++i) {
+		DiskDataDesc desc;
+		desc.track = stream->readByte();
+		desc.sector = stream->readByte();
+		desc.offset = stream->readByte();
+		desc.volume = stream->readByte();
+		_diskDataDesc.push_back(desc);
+	}
+}
+
+void HiRes6Engine::loadDisk(byte disk) {
+	delete _disk;
 	_disk = new DiskImage_NIB();
 
-	if (!_disk->open(disks[1]))
-		error("Failed to open disk image '%s'", disks[1]);
+	if (!_disk->open(disks[disk]))
+		error("Failed to open disk image '%s'", disks[disk]);
 
-	// Load item picture data
-	stream.reset(boot->createReadStream(0xb, 0xd, 0x08));
-	for (uint i = 0; i < IDI_HR6_NUM_ITEM_PICS; ++i) {
-		stream->readByte();
-		_itemPics.push_back(readDataBlockPtr(*stream));
-	}
+	_curDisk = disk;
 
-	// Load global picture data
-	stream.reset(_disk->createReadStream(0x1f, 0xf, 0x16));
-	byte picNr;
-	while ((picNr = stream->readByte()) != 0xff) {
-		if (stream->eos() || stream->err())
-			error("Error reading global pic list");
-		_pictures[picNr] = readDataBlockPtr(*stream);
-	}
+	byte track = _diskDataDesc[disk].track;
+	byte sector = _diskDataDesc[disk].sector;
+	uint offset = _diskDataDesc[disk].offset;
 
-	// Load message offsets
-	stream.reset(_disk->createReadStream(0x1f, 0xb, 0x16, 4));
-	for (uint i = 0; i < IDI_HR6_NUM_MESSAGES; ++i)
-		_messages.push_back(readDataBlockPtr(*stream));
+	applyDataBlockOffset(track, sector);
 
-	// Load commands
-	stream.reset(_disk->createReadStream(0x21, 0x4, 0x85, 7));
-	readCommands(*stream, _roomCommands);
+	StreamPtr stream;
 
-	stream.reset(_disk->createReadStream(0x20, 0xf, 0x82, 5));
-	readCommands(*stream, _globalCommands);
+	for (uint block = 0; block < 7; ++block) {
+		stream.reset(_disk->createReadStream(track, sector, offset, 1));
 
-	// Load verbs
-	stream.reset(_disk->createReadStream(0x1f, 0xf, 0x56, 6));
-	loadWords(*stream, _verbs, _priVerbs);
+		uint16 addr = stream->readUint16LE();
+		uint16 size = stream->readUint16LE();
 
-	// Load nouns
-	stream.reset(_disk->createReadStream(0x20, 0x5, 0x8e, 8));
-	loadWords(*stream, _nouns, _priNouns);
+		stream.reset(_disk->createReadStream(track, sector, offset, size / 256 + 1));
+		stream->skip(4);
 
-	delete boot;
+		switch (addr) {
+		case 0x9000: {
+			// Messages
+			_messages.clear();
+			uint count = size / 4;
+			for (uint i = 0; i < count; ++i)
+				_messages.push_back(readDataBlockPtr(*stream));
+			break;
+		}
+		case 0x4a80: {
+			// Global pics
+			_pictures.clear();
+			byte picNr;
+			while ((picNr = stream->readByte()) != 0xff) {
+				if (stream->eos() || stream->err())
+					error("Error reading global pic list");
+				_pictures[picNr] = readDataBlockPtr(*stream);
+			}
+			break;
+		}
+		case 0x4000:
+			// Verbs
+			loadWords(*stream, _verbs, _priVerbs);
+			break;
+		case 0x1800:
+			// Nouns
+			loadWords(*stream, _nouns, _priNouns);
+			break;
+		case 0x0e00: {
+			// Rooms
+			uint count = size / 14 - 1;
+			stream->skip(14); // Skip invalid room 0
+
+			_state.rooms.clear();
+			for (uint i = 0; i < count; ++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);
+			}
+			break;
+		}
+		case 0x7b00:
+			// Global commands
+			readCommands(*stream, _globalCommands);
+			break;
+		case 0x9500:
+			// Room commands
+			readCommands(*stream, _roomCommands);
+			break;
+		default:
+			error("Unknown data block found (addr %04x; size %04x)", addr, size);
+		}
+
+		offset += 4 + size;
+		while (offset >= 256) {
+			offset -= 256;
+			++sector;
+			if (sector >= 16) {
+				sector = 0;
+				++track;
+			}
+		}
+	}
+
+	// Load item picture data (indexed on boot disk)
+	stream.reset(_boot->createReadStream(0xb, 0xd, 0x08));
+	_itemPics.clear();
+	for (uint i = 0; i < IDI_HR6_NUM_ITEM_PICS; ++i) {
+		stream->readByte();
+		_itemPics.push_back(readDataBlockPtr(*stream));
+	}
 }
 
 void HiRes6Engine::initGameState() {
 	_state.vars.resize(IDI_HR6_NUM_VARS);
 
-	StreamPtr stream(_disk->createReadStream(0x20, 0xd, 0x94, 2));
-
-	for (uint i = 0; i < IDI_HR6_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);
-	}
+	loadDisk(1);
 
-	stream.reset(_disk->createReadStream(0x22, 0x0, 0x07, 0));
+	StreamPtr stream(_boot->createReadStream(0x3, 0xe, 0x03));
 
 	byte id;
 	while ((id = stream->readByte()) != 0xff) {
diff --git a/engines/adl/hires6.h b/engines/adl/hires6.h
index 443a9ca..aa3dbf5 100644
--- a/engines/adl/hires6.h
+++ b/engines/adl/hires6.h
@@ -49,9 +49,23 @@ namespace Adl {
 #define IDI_HR6_MSG_ITEM_NOT_HERE      254
 #define IDI_HR6_MSG_THANKS_FOR_PLAYING 252
 
+struct DiskDataDesc {
+	byte track;
+	byte sector;
+	byte offset;
+	byte volume;
+};
+
 class HiRes6Engine : public AdlEngine_v3 {
 public:
-	HiRes6Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine_v3(syst, gd), _currVerb(0), _currNoun(0) { }
+	HiRes6Engine(OSystem *syst, const AdlGameDescription *gd) :
+			AdlEngine_v3(syst, gd),
+			_boot(nullptr),
+			_currVerb(0),
+			_currNoun(0) {
+	}
+
+	~HiRes6Engine() { delete _boot; }
 
 private:
 	// AdlEngine
@@ -65,7 +79,11 @@ private:
 	void printString(const Common::String &str);
 	void applyDataBlockOffset(byte &track, byte &sector) const;
 
+	void loadDisk(byte disk);
+
+	DiskImage_DSK *_boot;
 	byte _currVerb, _currNoun;
+	Common::Array<DiskDataDesc> _diskDataDesc;
 };
 
 } // End of namespace Adl


Commit: 2cdb1d49a5cb0d91d70244383a05d4fed12d1ca2
    https://github.com/scummvm/scummvm/commit/2cdb1d49a5cb0d91d70244383a05d4fed12d1ca2
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Add stubs for hires6 opcodes

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl_v3.cpp
    engines/adl/adl_v3.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 761b60c..de2edde 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -544,6 +544,7 @@ Common::Error AdlEngine::run() {
 
 	while (1) {
 		uint verb = 0, noun = 0;
+		_isRestarting = false;
 
 		// When restoring from the launcher, we don't read
 		// input on the first iteration. This is needed to
@@ -553,6 +554,9 @@ Common::Error AdlEngine::run() {
 		if (!_isRestoring) {
 			showRoom();
 
+			if (_isRestarting)
+				continue;
+
 			_canSaveNow = _canRestoreNow = true;
 			getInput(verb, noun);
 			_canSaveNow = _canRestoreNow = false;
@@ -580,17 +584,13 @@ Common::Error AdlEngine::run() {
 		}
 
 		// Restarting does end command processing
-		if (_isRestarting) {
-			_isRestarting = false;
+		if (_isRestarting)
 			continue;
-		}
 
 		doAllCommands(_globalCommands, verb, noun);
 
-		if (_isRestarting) {
-			_isRestarting = false;
+		if (_isRestarting)
 			continue;
-		}
 
 		advanceClock();
 		_state.moves++;
diff --git a/engines/adl/adl_v3.cpp b/engines/adl/adl_v3.cpp
index 9041a47..a017f9a 100644
--- a/engines/adl/adl_v3.cpp
+++ b/engines/adl/adl_v3.cpp
@@ -87,18 +87,18 @@ void AdlEngine_v3::setupOpcodeTables() {
 	// 0x08
 	Opcode(o1_setPic);
 	Opcode(o1_printMsg);
-	Opcode(o1_setLight);
-	Opcode(o1_setDark);
+	Opcode(o3_dummy);
+	Opcode(o3_setTextMode);
 	// 0x0c
 	Opcode(o2_moveAllItems);
 	Opcode(o1_quit);
-	OpcodeUnImpl();
+	Opcode(o3_dummy);
 	Opcode(o2_save);
 	// 0x10
 	Opcode(o2_restore);
 	Opcode(o1_restart);
-	Opcode(o2_placeItem);
-	Opcode(o1_setItemPic);
+	Opcode(o3_setDisk);
+	Opcode(o3_dummy);
 	// 0x14
 	Opcode(o1_resetPic);
 	Opcode(o1_goDirection<IDI_DIR_NORTH>);
@@ -112,8 +112,8 @@ void AdlEngine_v3::setupOpcodeTables() {
 	// 0x1c
 	Opcode(o1_dropItem);
 	Opcode(o1_setRoomPic);
-	Opcode(o2_tellTime);
-	Opcode(o2_setRoomFromVar);
+	Opcode(o3_sound);
+	OpcodeUnImpl();
 	// 0x20
 	Opcode(o2_initDisk);
 }
@@ -188,4 +188,45 @@ int AdlEngine_v3::o3_moveItem(ScriptEnv &e) {
 	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;
+}
+
+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_sound(ScriptEnv &e) {
+	OP_DEBUG_0("\tSOUND()");
+
+	// TODO
+
+	return 0;
+}
+
 } // End of namespace Adl
diff --git a/engines/adl/adl_v3.h b/engines/adl/adl_v3.h
index 77b64fd..b36c97e 100644
--- a/engines/adl/adl_v3.h
+++ b/engines/adl/adl_v3.h
@@ -51,6 +51,10 @@ protected:
 	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);
 
 	Common::Array<Common::String> _itemDesc;
 	byte _curDisk;


Commit: 12fe7dabab6d8256f5c50e77c84c33cb769a907b
    https://github.com/scummvm/scummvm/commit/12fe7dabab6d8256f5c50e77c84c33cb769a907b
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Fix debug output in 'move all items' opcode

Changed paths:
    engines/adl/adl_v2.cpp



diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 55060be..6a3cb25 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -428,7 +428,7 @@ int AdlEngine_v2::o2_moveItem(ScriptEnv &e) {
 }
 
 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());
+	OP_DEBUG_2("\tMOVE_ALL_ITEMS(%s, %s)", itemRoomStr(e.arg(1)).c_str(), itemRoomStr(e.arg(2)).c_str());
 
 	byte room1 = roomArg(e.arg(1));
 


Commit: d435f5b4ebd0d2fe0a8d8ac260d69fb67ed7650f
    https://github.com/scummvm/scummvm/commit/d435f5b4ebd0d2fe0a8d8ac260d69fb67ed7650f
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Fix item rendering in hires6

Changed paths:
    engines/adl/adl_v2.cpp
    engines/adl/adl_v2.h
    engines/adl/adl_v3.cpp
    engines/adl/adl_v3.h
    engines/adl/hires6.cpp
    engines/adl/hires6.h



diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 6a3cb25..4fdf796 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -357,8 +357,6 @@ DataBlockPtr AdlEngine_v2::readDataBlockPtr(Common::ReadStream &f) const {
 	if (track == 0 && sector == 0 && offset == 0 && size == 0)
 		return DataBlockPtr();
 
-	applyDataBlockOffset(track, sector);
-
 	return _disk->getDataBlock(track, sector, offset, size);
 }
 
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 164af7d..508af91 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -54,8 +54,7 @@ protected:
 	virtual void showRoom();
 	void takeItem(byte noun);
 
-	virtual void applyDataBlockOffset(byte &track, byte &sector) const { }
-	DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const;
+	virtual DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const;
 
 	void checkTextOverflow(char c);
 
diff --git a/engines/adl/adl_v3.cpp b/engines/adl/adl_v3.cpp
index a017f9a..623db66 100644
--- a/engines/adl/adl_v3.cpp
+++ b/engines/adl/adl_v3.cpp
@@ -31,7 +31,7 @@ namespace Adl {
 
 AdlEngine_v3::AdlEngine_v3(OSystem *syst, const AdlGameDescription *gd) :
 		AdlEngine_v2(syst, gd),
-		_curDisk(1) {
+		_curDisk(0) {
 }
 
 Common::String AdlEngine_v3::loadMessage(uint idx) const {
@@ -49,6 +49,33 @@ 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);
+}
+
 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))
diff --git a/engines/adl/adl_v3.h b/engines/adl/adl_v3.h
index b36c97e..16f61ea 100644
--- a/engines/adl/adl_v3.h
+++ b/engines/adl/adl_v3.h
@@ -32,6 +32,11 @@ namespace Common{
 class RandomSource;
 }
 
+struct DiskOffset {
+	byte track;
+	byte sector;
+};
+
 namespace Adl {
 
 class AdlEngine_v3 : public AdlEngine_v2 {
@@ -46,6 +51,11 @@ protected:
 	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);
@@ -58,6 +68,7 @@ protected:
 
 	Common::Array<Common::String> _itemDesc;
 	byte _curDisk;
+	Common::Array<DiskOffset> _diskOffsets;
 };
 
 } // End of namespace Adl
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index c3c4138..c44a917 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -164,6 +164,15 @@ void HiRes6Engine::init() {
 		desc.volume = stream->readByte();
 		_diskDataDesc.push_back(desc);
 	}
+
+	// DataBlockPtr offsets for each disk
+	stream.reset(_boot->createReadStream(0x3, 0xf, 0x03));
+	for (uint i = 0; i < sizeof(disks); ++i) {
+		DiskOffset offset;
+		offset.track = stream->readByte();
+		offset.sector = stream->readByte();
+		_diskOffsets.push_back(offset);
+	}
 }
 
 void HiRes6Engine::loadDisk(byte disk) {
@@ -173,15 +182,23 @@ void HiRes6Engine::loadDisk(byte disk) {
 	if (!_disk->open(disks[disk]))
 		error("Failed to open disk image '%s'", disks[disk]);
 
+	_curDisk = 0;
+
+	// Load item picture data (indexed on boot disk)
+	StreamPtr stream(_boot->createReadStream(0xb, 0xd, 0x08));
+	_itemPics.clear();
+	for (uint i = 0; i < IDI_HR6_NUM_ITEM_PICS; ++i) {
+		stream->readByte();
+		_itemPics.push_back(readDataBlockPtr(*stream));
+	}
+
 	_curDisk = disk;
 
 	byte track = _diskDataDesc[disk].track;
 	byte sector = _diskDataDesc[disk].sector;
 	uint offset = _diskDataDesc[disk].offset;
 
-	applyDataBlockOffset(track, sector);
-
-	StreamPtr stream;
+	applyDiskOffset(track, sector);
 
 	for (uint block = 0; block < 7; ++block) {
 		stream.reset(_disk->createReadStream(track, sector, offset, 1));
@@ -261,14 +278,6 @@ void HiRes6Engine::loadDisk(byte disk) {
 			}
 		}
 	}
-
-	// Load item picture data (indexed on boot disk)
-	stream.reset(_boot->createReadStream(0xb, 0xd, 0x08));
-	_itemPics.clear();
-	for (uint i = 0; i < IDI_HR6_NUM_ITEM_PICS; ++i) {
-		stream->readByte();
-		_itemPics.push_back(readDataBlockPtr(*stream));
-	}
 }
 
 void HiRes6Engine::initGameState() {
@@ -354,11 +363,6 @@ void HiRes6Engine::showRoom() {
 	_linesPrinted = 0;
 }
 
-void HiRes6Engine::applyDataBlockOffset(byte &track, byte &sector) const {
-	// FIXME: this uses a table
-	++track;
-}
-
 void HiRes6Engine::printString(const Common::String &str) {
 	Common::String s;
 	uint found = 0;
diff --git a/engines/adl/hires6.h b/engines/adl/hires6.h
index aa3dbf5..27aa956 100644
--- a/engines/adl/hires6.h
+++ b/engines/adl/hires6.h
@@ -77,7 +77,6 @@ private:
 
 	// AdlEngine_v2
 	void printString(const Common::String &str);
-	void applyDataBlockOffset(byte &track, byte &sector) const;
 
 	void loadDisk(byte disk);
 


Commit: f8d75bbc8642ffe3baa56220c05f37eae31c3829
    https://github.com/scummvm/scummvm/commit/f8d75bbc8642ffe3baa56220c05f37eae31c3829
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Implement hires6 verb/noun error messages

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/hires6.cpp
    engines/adl/hires6.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index de2edde..f9d04b7 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -855,6 +855,22 @@ Common::String AdlEngine::getWord(const Common::String &line, uint &index) const
 	}
 }
 
+Common::String AdlEngine::formatVerbError(const Common::String &verbStr) const {
+	Common::String err = _strings.verbError;
+	for (uint i = 0; i < verbStr.size(); ++i)
+		err.setChar(verbStr[i], i + 19);
+	return err;
+}
+
+Common::String AdlEngine::formatNounError(const Common::String &verbStr, const Common::String &nounStr) const {
+	Common::String err = _strings.nounError;
+	for (uint i = 0; i < verbStr.size(); ++i)
+		err.setChar(verbStr[i], i + 19);
+	for (uint i = 0; i < nounStr.size(); ++i)
+		err.setChar(nounStr[i], i + 30);
+	return err;
+}
+
 void AdlEngine::getInput(uint &verb, uint &noun) {
 	while (1) {
 		_display->printString(_strings.enterCommand);
@@ -867,10 +883,7 @@ void AdlEngine::getInput(uint &verb, uint &noun) {
 		Common::String verbStr = getWord(line, index);
 
 		if (!_verbs.contains(verbStr)) {
-			Common::String err = _strings.verbError;
-			for (uint i = 0; i < verbStr.size(); ++i)
-				err.setChar(verbStr[i], i + 19);
-			_display->printString(err);
+			_display->printString(formatVerbError(verbStr));
 			continue;
 		}
 
@@ -879,12 +892,7 @@ void AdlEngine::getInput(uint &verb, uint &noun) {
 		Common::String nounStr = getWord(line, index);
 
 		if (!_nouns.contains(nounStr)) {
-			Common::String err = _strings.nounError;
-			for (uint i = 0; i < verbStr.size(); ++i)
-				err.setChar(verbStr[i], i + 19);
-			for (uint i = 0; i < nounStr.size(); ++i)
-				err.setChar(nounStr[i], i + 30);
-			_display->printString(err);
+			_display->printString(formatNounError(verbStr, nounStr));
 			continue;
 		}
 
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index a23f6b7..9b6a7ea 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -234,6 +234,8 @@ protected:
 	Common::String inputString(byte prompt = 0) const;
 	byte inputKey(bool showCursor = true) const;
 
+	virtual Common::String formatVerbError(const Common::String &verbStr) const;
+	virtual Common::String formatNounError(const Common::String &verbStr, const Common::String &nounStr) const;
 	void loadWords(Common::ReadStream &stream, WordMap &map, Common::StringArray &pri) const;
 	void readCommands(Common::ReadStream &stream, Commands &commands);
 	void checkInput(byte verb, byte noun);
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index c44a917..d743d1a 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -363,6 +363,43 @@ void HiRes6Engine::showRoom() {
 	_linesPrinted = 0;
 }
 
+Common::String HiRes6Engine::formatVerbError(const Common::String &verbStr) const {
+	Common::String err = _strings.verbError;
+
+	for (uint i = 0; i < verbStr.size(); ++i)
+		err.setChar(verbStr[i], i + 24);
+
+	err.setChar(APPLECHAR(' '), 32);
+
+	uint i = 24;
+	while (err[i] != APPLECHAR(' '))
+		++i;
+
+	err.setChar(APPLECHAR('.'), i);
+
+	return err;
+}
+
+Common::String HiRes6Engine::formatNounError(const Common::String &verbStr, const Common::String &nounStr) const {
+	Common::String err = _strings.nounError;
+
+	for (uint i = 0; i < nounStr.size(); ++i)
+		err.setChar(nounStr[i], i + 24);
+
+	for (uint  i = 35; i > 31; --i)
+		err.setChar(APPLECHAR(' '), i);
+
+	uint i = 24;
+	while (err[i] != APPLECHAR(' '))
+		++i;
+
+	err.setChar(APPLECHAR('I'), i + 1);
+	err.setChar(APPLECHAR('S'), i + 2);
+	err.setChar(APPLECHAR('.'), i + 3);
+
+	return err;
+}
+
 void HiRes6Engine::printString(const Common::String &str) {
 	Common::String s;
 	uint found = 0;
diff --git a/engines/adl/hires6.h b/engines/adl/hires6.h
index 27aa956..439d688 100644
--- a/engines/adl/hires6.h
+++ b/engines/adl/hires6.h
@@ -74,6 +74,8 @@ private:
 	void initGameState();
 	void printRoomDescription();
 	void showRoom();
+	Common::String formatVerbError(const Common::String &verbStr) const;
+	Common::String formatNounError(const Common::String &verbStr, const Common::String &nounStr) const;
 
 	// AdlEngine_v2
 	void printString(const Common::String &str);


Commit: 0c2d2b2c925e1a6ec639f6d59fe086b03cb440c2
    https://github.com/scummvm/scummvm/commit/0c2d2b2c925e1a6ec639f6d59fe086b03cb440c2
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Fix GCC 4.9 shadow warnings

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/hires6.cpp
    engines/adl/hires6.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index f9d04b7..de1f8aa 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -855,19 +855,19 @@ Common::String AdlEngine::getWord(const Common::String &line, uint &index) const
 	}
 }
 
-Common::String AdlEngine::formatVerbError(const Common::String &verbStr) const {
+Common::String AdlEngine::formatVerbError(const Common::String &verb) const {
 	Common::String err = _strings.verbError;
-	for (uint i = 0; i < verbStr.size(); ++i)
-		err.setChar(verbStr[i], i + 19);
+	for (uint i = 0; i < verb.size(); ++i)
+		err.setChar(verb[i], i + 19);
 	return err;
 }
 
-Common::String AdlEngine::formatNounError(const Common::String &verbStr, const Common::String &nounStr) const {
+Common::String AdlEngine::formatNounError(const Common::String &verb, const Common::String &noun) const {
 	Common::String err = _strings.nounError;
-	for (uint i = 0; i < verbStr.size(); ++i)
-		err.setChar(verbStr[i], i + 19);
-	for (uint i = 0; i < nounStr.size(); ++i)
-		err.setChar(nounStr[i], i + 30);
+	for (uint i = 0; i < verb.size(); ++i)
+		err.setChar(verb[i], i + 19);
+	for (uint i = 0; i < noun.size(); ++i)
+		err.setChar(noun[i], i + 30);
 	return err;
 }
 
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 9b6a7ea..ee9bbb3 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -234,8 +234,8 @@ protected:
 	Common::String inputString(byte prompt = 0) const;
 	byte inputKey(bool showCursor = true) const;
 
-	virtual Common::String formatVerbError(const Common::String &verbStr) const;
-	virtual Common::String formatNounError(const Common::String &verbStr, const Common::String &nounStr) const;
+	virtual Common::String formatVerbError(const Common::String &verb) const;
+	virtual Common::String formatNounError(const Common::String &verb, const Common::String &noun) const;
 	void loadWords(Common::ReadStream &stream, WordMap &map, Common::StringArray &pri) const;
 	void readCommands(Common::ReadStream &stream, Commands &commands);
 	void checkInput(byte verb, byte noun);
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index d743d1a..422e9a9 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -363,11 +363,11 @@ void HiRes6Engine::showRoom() {
 	_linesPrinted = 0;
 }
 
-Common::String HiRes6Engine::formatVerbError(const Common::String &verbStr) const {
+Common::String HiRes6Engine::formatVerbError(const Common::String &verb) const {
 	Common::String err = _strings.verbError;
 
-	for (uint i = 0; i < verbStr.size(); ++i)
-		err.setChar(verbStr[i], i + 24);
+	for (uint i = 0; i < verb.size(); ++i)
+		err.setChar(verb[i], i + 24);
 
 	err.setChar(APPLECHAR(' '), 32);
 
@@ -380,11 +380,11 @@ Common::String HiRes6Engine::formatVerbError(const Common::String &verbStr) cons
 	return err;
 }
 
-Common::String HiRes6Engine::formatNounError(const Common::String &verbStr, const Common::String &nounStr) const {
+Common::String HiRes6Engine::formatNounError(const Common::String &verb, const Common::String &noun) const {
 	Common::String err = _strings.nounError;
 
-	for (uint i = 0; i < nounStr.size(); ++i)
-		err.setChar(nounStr[i], i + 24);
+	for (uint i = 0; i < noun.size(); ++i)
+		err.setChar(noun[i], i + 24);
 
 	for (uint  i = 35; i > 31; --i)
 		err.setChar(APPLECHAR(' '), i);
diff --git a/engines/adl/hires6.h b/engines/adl/hires6.h
index 439d688..ebd0ce1 100644
--- a/engines/adl/hires6.h
+++ b/engines/adl/hires6.h
@@ -74,8 +74,8 @@ private:
 	void initGameState();
 	void printRoomDescription();
 	void showRoom();
-	Common::String formatVerbError(const Common::String &verbStr) const;
-	Common::String formatNounError(const Common::String &verbStr, const Common::String &nounStr) const;
+	Common::String formatVerbError(const Common::String &verb) const;
+	Common::String formatNounError(const Common::String &verb, const Common::String &noun) const;
 
 	// AdlEngine_v2
 	void printString(const Common::String &str);


Commit: 9967ae8c521716083f9edd1228a65f5d2eaee65d
    https://github.com/scummvm/scummvm/commit/9967ae8c521716083f9edd1228a65f5d2eaee65d
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Fix more GCC 4.9 shadow warnings

Changed paths:
    engines/adl/adl.cpp



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index de1f8aa..b6af549 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -880,23 +880,23 @@ void AdlEngine::getInput(uint &verb, uint &noun) {
 			return;
 
 		uint index = 0;
-		Common::String verbStr = getWord(line, index);
+		Common::String verbString = getWord(line, index);
 
-		if (!_verbs.contains(verbStr)) {
-			_display->printString(formatVerbError(verbStr));
+		if (!_verbs.contains(verbString)) {
+			_display->printString(formatVerbError(verbString));
 			continue;
 		}
 
-		verb = _verbs[verbStr];
+		verb = _verbs[verbString];
 
-		Common::String nounStr = getWord(line, index);
+		Common::String nounString = getWord(line, index);
 
-		if (!_nouns.contains(nounStr)) {
-			_display->printString(formatNounError(verbStr, nounStr));
+		if (!_nouns.contains(nounString)) {
+			_display->printString(formatNounError(verbString, nounString));
 			continue;
 		}
 
-		noun = _nouns[nounStr];
+		noun = _nouns[nounString];
 		return;
 	}
 }


Commit: c71740bc5d9f2fae54c5d7722d3e0d0ac7bd7b89
    https://github.com/scummvm/scummvm/commit/c71740bc5d9f2fae54c5d7722d3e0d0ac7bd7b89
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Fix GCC 4.9 missing initializer warnings

Changed paths:
    engines/adl/hires1.cpp
    engines/adl/hires2.cpp
    engines/adl/hires6.cpp



diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index c8b9989..096d8ef 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -229,7 +229,7 @@ void HiRes1Engine::initGameState() {
 	stream->seek(IDI_HR1_OFS_ITEMS);
 	byte id;
 	while ((id = stream->readByte()) != 0xff) {
-		Item item = { };
+		Item item = Item();
 		item.id = id;
 		item.noun = stream->readByte();
 		item.room = stream->readByte();
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index d1dd065..d8e8a65 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -151,7 +151,7 @@ void HiRes2Engine::initGameState() {
 
 	byte id;
 	while ((id = stream->readByte()) != 0xff) {
-		Item item = { };
+		Item item = Item();
 		item.id = id;
 		item.noun = stream->readByte();
 		item.room = stream->readByte();
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index 422e9a9..c42b416 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -289,7 +289,7 @@ void HiRes6Engine::initGameState() {
 
 	byte id;
 	while ((id = stream->readByte()) != 0xff) {
-		Item item = { };
+		Item item = Item();
 		item.id = id;
 		item.noun = stream->readByte();
 		item.room = stream->readByte();


Commit: 9acf6c3838d0aaaf5cff8ea120ec4672cf6fe6c8
    https://github.com/scummvm/scummvm/commit/9acf6c3838d0aaaf5cff8ea120ec4672cf6fe6c8
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00

Commit Message:
ADL: Fix formatting

Changed paths:
    engines/adl/adl_v2.h
    engines/adl/adl_v3.h
    engines/adl/graphics.h



diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 508af91..f18972b 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -28,7 +28,7 @@
 // Note: this version of ADL redraws only when necessary, but
 // this is not currently implemented.
 
-namespace Common{
+namespace Common {
 class RandomSource;
 }
 
diff --git a/engines/adl/adl_v3.h b/engines/adl/adl_v3.h
index 16f61ea..61dd585 100644
--- a/engines/adl/adl_v3.h
+++ b/engines/adl/adl_v3.h
@@ -28,7 +28,7 @@
 // Note: this version of ADL redraws only when necessary, but
 // this is not currently implemented.
 
-namespace Common{
+namespace Common {
 class RandomSource;
 }
 
diff --git a/engines/adl/graphics.h b/engines/adl/graphics.h
index b422959..3a300fb 100644
--- a/engines/adl/graphics.h
+++ b/engines/adl/graphics.h
@@ -23,7 +23,7 @@
 #ifndef ADL_PICTURE_H
 #define ADL_PICTURE_H
 
-namespace Common{
+namespace Common {
 class SeekableReadStream;
 class Point;
 }






More information about the Scummvm-git-logs mailing list