[Scummvm-cvs-logs] scummvm master -> f1b6542fd2f705b771f8c46efb328b783f9c5d78

sev- sev at scummvm.org
Thu Mar 24 23:07:54 CET 2016


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

Summary:
c8ab2909c6 ADL: Initial check-in for ADL engine
87e2c4c1a9 ADL: Rename game type
9717aa9561 ADL: Clean-up string handling
183fe8b217 ADL: Move members into base class
d30cfa24fa ADL: Remove dead code
43a37e94dd ADL: Rename AdlEngine_v1 to HiRes1Engine
1e17a23879 ADL: Rename adl_v1.cpp/h to hires1.cpp/h
6a1dd07197 ADL: Move more functionality into base class
ce97d0a26e ADL: Use #defines instead of literals
f9c9f2ac9d ADL: Rename Item struct fields
8f9d4b9653 ADL: Use #defines instead of literals
2104a5095d ADL: Rename Room struct fields
00d87cca90 ADL: Add more #defines for literals
ede25c19bc ADL: Rename some #defines and variables for clarity
24c478c5ec ADL: Add ARG #define to improve readability
34cb2f4c53 ADL: Move functionality into base class
1abaf60cf0 ADL: Rename rightAngles to lineArt
dc2e5e09ba ADL: Put state-related members in _state struct
301b2fdc21 ADL: Remove leftover debug code
727469d4a7 ADL: Add restarting
e3d13d06ee ADL: Add save game support
e1fb585357 ADL: Use #define instead of literal
475eb0cc95 ADL: Fix bug in item taking
9928e51bd7 ADL: Add functions to adjust for 1-based arrays
ba54955bff ADL: Add loading from launcher
339d3bc868 ADL: Move input code into AdlEngine
93f5e36c9f ADL: Add GMM loading and saving
baa2410a1c ADL: Fix "don't understand" parser response override
84a9f6ce95 ADL: Add save game meta info support
912a31fa65 ADL: Add monochrome and scanline rendering
b30fb417ac ADL: Disable scanlines when saving thumbnail
d5cc42f1c2 ADL: Make frame buffer linear
4f7e5da4da ADL: Clean up Display class
115e4cab0d ADL: Fix restoring on restart prompt
ec14c397ee ADL: Clean up Display class
e6d478ad15 ADL: Clean up Display class
6f91289838 ADL: Clean up Display class
f5430f961b ADL: Implement half-pixel shift in color mode
50d6e6938a ADL: Refactor graphics code
d3bfdc3657 ADL: Add more #defines to replace literals
b2d2f3405e ADL: Make palettes static
165e333f4f ADL: Implement half-pixel shift for monochrome
1e1a5d4f07 ADL: Fix darkness setting in a move too late
6379fbc124 ADL: Add more #defines to replace literals
f62c56e384 ADL: Clean up line drawing
af42795ffa ADL: Improve error messages
a73dcdf224 ADL: Move functionality into base class
0ec3ab1422 ADL: Fix const'ness
58e7c53909 ADL: Clean up AdlEngine class
07d0997bef ADL: Clean up AdlMetaEngine
ac79cb081c ADL: Move #defines into header file
fd8a5f419f ADL: Refactor string handling
86d58534e7 ADL: Move ASCII print function into Display class
63adab81ed ADL: Clean up HiRes1Engine class
57af92e0c1 ADL: Fix shadowing warning (GCC 4.8)
d01da596ef ADL: Add note about font
ac39224958 ADL: Limit keyboard input to 256 characters
9d65f901d0 ADL: Clarify detection entry
349245d9b4 ADL: Fix regression in GMM saving/loading
ce3af91ef8 ADL: Disable GMM restore on restart prompt
f1b6542fd2 Merge pull request #700 from waltervn/adl-engine


Commit: c8ab2909c67703ad1255aa27159049f058d1a361
    https://github.com/scummvm/scummvm/commit/c8ab2909c67703ad1255aa27159049f058d1a361
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Initial check-in for ADL engine

Changed paths:
  A engines/adl/adl.cpp
  A engines/adl/adl.h
  A engines/adl/adl_v1.cpp
  A engines/adl/adl_v1.h
  A engines/adl/configure.engine
  A engines/adl/detection.cpp
  A engines/adl/display.cpp
  A engines/adl/display.h
  A engines/adl/module.mk
  A engines/adl/parser.cpp
  A engines/adl/parser.h



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
new file mode 100644
index 0000000..be3d8d7
--- /dev/null
+++ b/engines/adl/adl.cpp
@@ -0,0 +1,155 @@
+/* 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/scummsys.h"
+
+#include "common/config-manager.h"
+#include "common/debug.h"
+#include "common/debug-channels.h"
+#include "common/error.h"
+#include "common/file.h"
+#include "common/fs.h"
+#include "common/system.h"
+#include "common/events.h"
+#include "common/stream.h"
+#include "graphics/palette.h"
+
+#include "engines/util.h"
+
+#include "adl/adl.h"
+#include "adl/display.h"
+#include "adl/parser.h"
+
+namespace Adl {
+
+Common::String asciiToApple(Common::String str) {
+	Common::String ret(str);
+	Common::String::iterator it;
+
+	for (it = ret.begin(); it != ret.end(); ++it)
+		*it = *it | 0x80;
+
+	return ret;
+}
+
+Common::String appleToAscii(Common::String str) {
+	Common::String ret(str);
+	Common::String::iterator it;
+
+	for (it = ret.begin(); it != ret.end(); ++it)
+		*it = *it & 0x7f;
+
+	return ret;
+}
+
+AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) :
+		Engine(syst),
+		_gameDescription(gd),
+		_console(nullptr),
+		_display(nullptr) {
+	// Put your engine in a sane state, but do nothing big yet;
+	// in particular, do not load data from files; rather, if you
+	// need to do such things, do them from run().
+
+	// Do not initialize graphics here
+	// Do not initialize audio devices here
+
+	// However this is the place to specify all default directories
+	const Common::FSNode gameDataDir(ConfMan.get("path"));
+	SearchMan.addSubDirectoryMatching(gameDataDir, "sound");
+
+	// Don't forget to register your random source
+	_rnd = new Common::RandomSource("adl");
+
+	debug("AdlEngine::AdlEngine");
+}
+
+AdlEngine::~AdlEngine() {
+	debug("AdlEngine::~AdlEngine");
+
+	delete _rnd;
+	delete _console;
+	delete _display;
+
+	DebugMan.clearAllDebugChannels();
+}
+
+Common::Error AdlEngine::run() {
+	initGraphics(560, 384, true);
+
+	byte palette[6 * 3] = {
+		0x00, 0x00, 0x00,
+		0xff, 0xff, 0xff,
+		0xc7, 0x34, 0xff,
+		0x38, 0xcb, 0x00,
+		0x00, 0x00, 0xff, // FIXME
+		0xff, 0xa5, 0x00  // FIXME
+	};
+
+	g_system->getPaletteManager()->setPalette(palette, 0, 6);
+
+	_console = new Console(this);
+	_display = new Display();
+	_parser = new Parser(*this, *_display);
+
+	runGame();
+
+	return Common::kNoError;
+}
+
+Common::String AdlEngine::readString(Common::ReadStream &stream, byte until) {
+	Common::String str;
+
+	while (1) {
+		byte b = stream.readByte();
+
+		if (stream.eos() || stream.err() || b == until)
+			break;
+
+		str += b;
+	};
+
+	return str;
+}
+
+void AdlEngine::printStrings(Common::SeekableReadStream &stream, int count) {
+	while (1) {
+		Common::String str = readString(stream);
+		_display->printString(str);
+
+		if (--count == 0)
+			break;
+
+		stream.seek(3, SEEK_CUR);
+	};
+}
+
+AdlEngine *AdlEngine::create(GameType type, OSystem *syst, const AdlGameDescription *gd) {
+	switch(type) {
+	case kGameTypeAdl1:
+		return AdlEngine_v1__create(syst, gd);
+	default:
+		error("Unknown GameType");
+	}
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
new file mode 100644
index 0000000..d5a518fa
--- /dev/null
+++ b/engines/adl/adl.h
@@ -0,0 +1,98 @@
+/* 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_H
+#define ADL_ADL_H
+
+#include "common/random.h"
+#include "engines/engine.h"
+#include "gui/debugger.h"
+
+namespace Common {
+class ReadStream;
+class SeekableReadStream;
+}
+
+namespace Adl {
+
+class Display;
+class Parser;
+class Console;
+struct AdlGameDescription;
+
+enum GameType {
+	kGameTypeNone = 0,
+	kGameTypeAdl1
+};
+
+Common::String asciiToApple(Common::String str);
+Common::String appleToAscii(Common::String str);
+
+enum {
+	STR_COMMON_ENTERCMD,
+	STR_COMMON_VERBERR,
+	STR_COMMON_NOUNERR,
+	STR_CUSTOM_START
+};
+
+#define A2CHAR(C) ((C) | 0x80)
+
+class AdlEngine : public Engine {
+public:
+	AdlEngine(OSystem *syst, const AdlGameDescription *gd);
+	virtual ~AdlEngine();
+
+	const AdlGameDescription *_gameDescription;
+	uint32 getFeatures() const;
+	const char *getGameId() const;
+
+	static AdlEngine *create(GameType type, OSystem *syst, const AdlGameDescription *gd);
+
+	Common::Error run();
+	virtual Common::String getExeString(uint id) = 0;
+
+protected:
+	virtual void runGame() = 0;
+	Common::String readString(Common::ReadStream &stream, byte until = 0);
+	void printStrings(Common::SeekableReadStream &stream, int count = 1);
+	Display *_display;
+	Parser *_parser;
+
+private:
+	Console *_console;
+
+	// We need random numbers
+	Common::RandomSource *_rnd;
+};
+
+// Example console class
+class Console : public GUI::Debugger {
+public:
+	Console(AdlEngine *vm) {}
+	virtual ~Console(void) {}
+};
+
+AdlEngine *AdlEngine_v1__create(OSystem *syst, const AdlGameDescription *gd);
+
+} // End of namespace Adl
+
+#endif
diff --git a/engines/adl/adl_v1.cpp b/engines/adl/adl_v1.cpp
new file mode 100644
index 0000000..61671e5
--- /dev/null
+++ b/engines/adl/adl_v1.cpp
@@ -0,0 +1,690 @@
+/* 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/scummsys.h"
+
+#include "common/config-manager.h"
+#include "common/debug.h"
+#include "common/debug-channels.h"
+#include "common/error.h"
+#include "common/file.h"
+#include "common/fs.h"
+#include "common/system.h"
+#include "common/events.h"
+#include "common/stream.h"
+#include "graphics/palette.h"
+
+#include "engines/util.h"
+
+#include "adl/adl_v1.h"
+#include "adl/display.h"
+#include "adl/parser.h"
+
+namespace Adl {
+
+static uint exeStrings[STR_MH_TOTAL] = {
+	23484, 23375, 23438, 27658, 0x6c31, 27729, 27772, 0x5f1e
+};
+
+AdlEngine_v1::AdlEngine_v1(OSystem *syst, const AdlGameDescription *gd) :
+		AdlEngine(syst, gd),
+		_state(kIntro),
+		_room(1),
+		_steps(1),
+		_isDark(false) {
+	_variables.resize(20);
+}
+
+void AdlEngine_v1::runIntro() {
+	Common::File file;
+
+	if (!file.open("AUTO LOAD OBJ"))
+		error("Failed to open file");
+
+	file.seek(0x1003);
+	_display->setMode(Display::kModeHires);
+	_display->loadFrameBuffer(file);
+	_display->decodeFrameBuffer();
+	_display->delay(4000);
+
+	if (shouldQuit())
+		return;
+
+	_display->setMode(Display::kModeText);
+
+	Common::File basic;
+	if (!basic.open("MYSTERY.HELLO"))
+		error("Failed to open file");
+
+	Common::String str;
+
+	basic.seek(93);
+	str = readString(basic, '"');
+	_display->printASCIIString(str + '\r');
+
+	basic.seek(299);
+	str = readString(basic, '"');
+	_display->printASCIIString(str + "\r\r");
+
+	basic.seek(365);
+	str = readString(basic, '"');
+	_display->printASCIIString(str + "\r\r");
+
+	basic.seek(601);
+	str = readString(basic, '"');
+	_display->printASCIIString(str + '\r');
+
+	_display->inputKey();
+	if (g_engine->shouldQuit())
+		return;
+
+	_display->setMode(Display::kModeMixed);
+
+	file.seek(15);
+	str = readString(file);
+
+	while (1) {
+		_display->printString(str);
+		Common::String s = _display->inputString();
+
+		if (g_engine->shouldQuit())
+			break;
+
+		if (s.empty())
+			continue;
+
+		if ((byte)s[0] == ('I' | 0x80))
+			break;
+		else if ((byte)s[0] == ('G' | 0x80))
+			return;
+	};
+
+	_display->setMode(Display::kModeText);
+	file.seek(102);
+
+	const int pages[] = { 6, 6, 4, 5, 8, 7, 0 };
+
+	int page = 0;
+	while (pages[page] != 0) {
+		_display->home();
+		printStrings(file, pages[page++]);
+		_display->inputString();
+
+		if (g_engine->shouldQuit())
+			return;
+
+		file.seek(9, SEEK_CUR);
+	}
+}
+
+void AdlEngine_v1::drawPic(Common::ReadStream &stream, byte xOffset, byte yOffset) {
+	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 += xOffset;
+		y += yOffset;
+
+		if (y > 160)
+			y = 160;
+
+		if (bNewLine) {
+			_display->drawPixel(x, y, 0x7f);
+			bNewLine = false;
+		} else {
+			_display->drawLine(Common::Point(oldX, oldY), Common::Point(x, y), 0x7f);
+		}
+
+		oldX = x;
+		oldY = y;
+	}
+}
+
+void AdlEngine_v1::drawPic(byte pic, byte xOffset, byte yOffset) {
+	Common::File f;
+	Common::String name = Common::String::format("BLOCK%i", _pictures[pic].block);
+
+	if (!f.open(name))
+		error("Failed to open file");
+
+	f.seek(_pictures[pic].offset);
+	drawPic(f, xOffset, yOffset);
+}
+
+void AdlEngine_v1::drawItems() {
+	Common::Array<Item>::const_iterator it;
+
+	uint dropped = 0;
+
+	for (it = _inventory.begin(); it != _inventory.end(); ++it) {
+		if (it->field2 != _room)
+			continue;
+
+		if (it->field7 == 1) {
+			if (_rooms[_room].field8 == _rooms[_room].picture) {
+				const Common::Point &p =  _itemOffsets[dropped];
+				if (it->field4)
+					_display->drawRightAngles(_drawings[it->field3 - 1], Common::Point(p.x, p.y), 0, 1, 0x7f);
+				else
+					drawPic(it->field3, p.x, p.y);
+				++dropped;
+			}
+			continue;
+		}
+
+		Common::Array<byte>::const_iterator it2;
+
+		for (it2 = it->field10.begin(); it2 != it->field10.end(); ++it2) {
+			if (*it2 == _rooms[_room].picture) {
+				if (it->field4)
+					_display->drawRightAngles(_drawings[it->field3 - 1], Common::Point(it->field5, it->field6), 0, 1, 0x7f);
+				else
+					drawPic(it->field3, it->field5, it->field6);
+				continue;
+			}
+		}
+	}
+}
+
+void AdlEngine_v1::showRoom() {
+	if (!_isDark) {
+		drawPic(_rooms[_room].picture, 0, 0);
+		drawItems();
+	}
+
+	_display->decodeFrameBuffer();
+	printMessage(_rooms[_room].description, false);
+}
+
+Common::String AdlEngine_v1::getExeString(uint idx) {
+	return _exeStrings[idx];
+}
+
+void AdlEngine_v1::wordWrap(Common::String &str) {
+	uint end = 39;
+
+	while (1) {
+		if (str.size() <= end)
+			return;
+
+		while (str[end] != (char)A2CHAR(' '))
+			--end;
+
+		str.setChar((char)A2CHAR('\r'), end);
+		end += 40;
+	}
+}
+
+void AdlEngine_v1::printMessage(uint idx, bool wait) {
+	// Hardcoded overrides that don't wait after printing
+	// Note: strings may differ slightly from the ones in MESSAGES
+	switch (idx) {
+	case 137:
+		_display->printString(_exeStrings[STR_MH_DIRERR]);
+		return;
+	case 127:
+		_display->printString(_exeStrings[STR_MH_DONTHAVEIT]);
+		return;
+	case 37:
+		_display->printString(_exeStrings[STR_MH_DONTUNDERSTAND]);
+		return;
+	case 7:
+		_display->printString(_exeStrings[STR_MH_GETTINGDARK]);
+		return;
+	}
+
+	Common::String msg = _msgStrings[idx - 1];
+	wordWrap(msg);
+	_display->printString(msg);
+
+	if (wait)
+		_display->delay(14 * 166018 / 1000);
+}
+
+void AdlEngine_v1::readCommands(Common::ReadStream &stream, Commands &commands) {
+	while (1) {
+		Command command;
+		command.room = stream.readByte();
+
+		if (command.room == 0xff)
+			return;
+
+		command.verb = stream.readByte();
+		command.noun = stream.readByte();
+
+		byte scriptSize = stream.readByte() - 6;
+
+		command.numCond = stream.readByte();
+		command.numAct = stream.readByte();
+
+		for (uint i = 0; i < scriptSize; ++i)
+			command.script.push_back(stream.readByte());
+
+		if (stream.eos() || stream.err())
+			error("Failed to read commands");
+
+		commands.push_back(command);
+	}
+}
+
+void AdlEngine_v1::takeItem(byte noun) {
+	Common::Array<Item>::iterator it;
+
+	for (it = _inventory.begin(); it != _inventory.end(); ++it) {
+		if (it->field1 != noun || it->field2 != _room)
+			continue;
+
+		if (it->field7 == 2) {
+			// It doesn't move
+			printMessage(151);
+			return;
+		}
+
+		if (it->field7 == 1) {
+			it->field2 = 0xfe;
+			it->field7 = 1;
+			return;
+		}
+
+		Common::Array<byte>::const_iterator it2;
+		for (it2 = it->field10.begin(); it->field10.end(); ++it2) {
+			if (*it2 == _rooms[_room].picture) {
+				it->field2 = 0xfe;
+				it->field7 = 1;
+				return;
+			}
+		}
+	}
+
+	// Item not here
+	printMessage(152);
+}
+
+void AdlEngine_v1::dropItem(byte noun) {
+	Common::Array<Item>::iterator it;
+
+	for (it = _inventory.begin(); it != _inventory.end(); ++it) {
+		if (it->field1 != noun || it->field2 != 0xfe)
+			continue;
+
+		it->field2 = _room;
+		it->field7 = 1;
+		return;
+	}
+
+	// Don't understand
+	printMessage(37);
+}
+
+void AdlEngine_v1::doActions(const Command &command, byte noun, byte offset) {
+	for (uint i = 0; i < command.numAct; ++i) {
+		switch (command.script[offset]) {
+		case 1:
+			_variables[command.script[offset + 2]] += command.script[offset + 1];
+			offset += 3;
+			break;
+		case 2:
+			_variables[command.script[offset + 2]] -= command.script[offset + 1];
+			offset += 3;
+			break;
+		case 3:
+			_variables[command.script[offset + 1]] = command.script[offset + 2];
+			offset += 3;
+			break;
+		case 4: {
+			Common::Array<Item>::const_iterator it;
+
+			for (it = _inventory.begin(); it != _inventory.end(); ++it)
+				if (it->field2 == 0xfe)
+					printMessage(it->field8);
+
+			++offset;
+			break;
+		}
+		case 5:
+			_inventory[command.script[offset + 1] - 1].field2 = command.script[offset + 2];
+			offset += 3;
+			break;
+		case 6:
+			_rooms[_room].picture = _rooms[_room].field8;
+			_room = command.script[offset + 1];
+			offset += 2;
+			break;
+		case 7:
+			_rooms[_room].picture = command.script[offset + 1];
+			offset += 2;
+			break;
+		case 8:
+			_rooms[_room].field8 = _rooms[_room].picture = command.script[offset + 1];
+			offset += 2;
+			break;
+		case 9:
+			printMessage(command.script[offset + 1]);
+			offset += 2;
+			break;
+		case 0xa:
+			_isDark = false;
+			++offset;
+			break;
+		case 0xb:
+			_isDark = true;
+			++offset;
+			break;
+		case 0xf:
+			warning("Save game not implemented");
+			++offset;
+			break;
+		case 0x10:
+			warning("Load game not implemented");
+			++offset;
+			break;
+		case 0x11: {
+			_display->printString(_exeStrings[STR_MH_PLAYAGAIN]);
+			Common::String input = _display->inputString();
+			if (input.size() == 0 || input[0] != (char)A2CHAR('N')) {
+				warning("Restart game not implemented");
+				return;
+			}
+			// Fall-through
+		}
+		case 0xd:
+			printMessage(140);
+			quitGame();
+			return;
+		case 0x12: {
+			byte item = command.script[offset + 1] - 1;
+			_inventory[item].field2 = command.script[offset + 2];
+			_inventory[item].field5 = command.script[offset + 3];
+			_inventory[item].field6 = command.script[offset + 4];
+			offset += 5;
+			break;
+		}
+		case 0x13: {
+			byte item = command.script[offset + 2] - 1;
+			_inventory[item].field3 = command.script[offset + 1];
+			offset += 3;
+			break;
+		}
+		case 0x14:
+			_rooms[_room].picture = _rooms[_room].field8;
+			++offset;
+			break;
+		case 0x15:
+		case 0x16:
+		case 0x17:
+		case 0x18:
+		case 0x19:
+		case 0x1a: {
+			byte room = _rooms[_room].connections[command.script[offset] - 0x15];
+
+			if (room == 0) {
+				printMessage(137);
+				return;
+			}
+
+			_rooms[_room].picture = _rooms[_room].field8;
+			_room = room;
+			return;
+		}
+		case 0x1b:
+			takeItem(noun);
+			++offset;
+			break;
+		case 0x1c:
+			dropItem(noun);
+			++offset;
+			break;
+		case 0x1d:
+			_rooms[command.script[offset + 1]].field8 = _rooms[command.script[offset + 1]].picture = command.script[offset + 2];
+			offset += 3;
+			break;
+		default:
+			error("Invalid action opcode %02x", command.script[offset]);
+		}
+	}
+}
+
+bool AdlEngine_v1::checkCommand(const Command &command, byte verb, byte noun) {
+	if (command.room != 0xfe && command.room != _room)
+		return false;
+
+	if (command.verb != 0xfe && command.verb != verb)
+		return false;
+
+	if (command.noun != 0xfe && command.noun != noun)
+		return false;
+
+	uint offset = 0;
+	for (uint i = 0; i < command.numCond; ++i) {
+		switch (command.script[offset]) {
+		case 3:
+			if (_inventory[command.script[offset + 1] - 1].field2 != command.script[offset + 2])
+				return false;
+			offset += 3;
+			break;
+		case 5:
+			if (command.script[offset + 1] > _steps)
+				return false;
+			offset += 2;
+			break;
+		case 6:
+			if (_variables[command.script[offset + 1]] != command.script[offset + 2])
+				return false;
+			offset += 3;
+			break;
+		case 9:
+			if (_rooms[_room].picture != command.script[offset + 1])
+				return false;
+			offset += 2;
+			break;
+		case 10:
+			if (_inventory[command.script[offset + 1] - 1].field3 != command.script[offset + 2])
+				return false;
+			offset += 3;
+			break;
+		default:
+			error("Invalid condition opcode %02x", command.script[offset]);
+		}
+	}
+
+	doActions(command, noun, offset);
+
+	return true;
+}
+
+bool AdlEngine_v1::doOneCommand(const Commands &commands, byte verb, byte noun) {
+	Commands::const_iterator it;
+
+	for (it = commands.begin(); it != commands.end(); ++it) {
+		if (checkCommand(*it, verb, noun)) {
+			debug("Found match: %i %i %i", it->room, it->verb, it->noun);
+			return true;
+		}
+	}
+
+	return false;
+}
+
+void AdlEngine_v1::doAllCommands(const Commands &commands, byte verb, byte noun) {
+	Commands::const_iterator it;
+
+	for (it = commands.begin(); it != commands.end(); ++it) {
+		if (checkCommand(*it, verb, noun)) {
+			debug("Found match: %i %i %i", it->room, it->verb, it->noun);
+		}
+	}
+}
+
+void AdlEngine_v1::clearScreen() {
+	_display->setMode(Display::kModeMixed);
+	_display->clear(0x00);
+}
+
+void AdlEngine_v1::runGame() {
+	runIntro();
+	_display->printASCIIString("\r");
+
+	Common::File f;
+
+	if (!f.open("MESSAGES"))
+		error("Failed to open file");
+
+	while (!f.eos() && !f.err())
+		_msgStrings.push_back(readString(f, A2CHAR('\r')) + (char)A2CHAR('\r'));
+
+	f.close();
+
+	if (!f.open("ADVENTURE"))
+		error("Failed to open file");
+
+	// Load strings from executable
+	for (uint idx = 0; idx < STR_MH_TOTAL; ++idx) {
+		f.seek(exeStrings[idx]);
+		_exeStrings.push_back(readString(f));
+	}
+
+	// Load room data from executable
+	f.seek(1280);
+	for (uint i = 0; i < MH_ROOMS; ++i) {
+		struct Room room;
+		f.readByte();
+		room.description = f.readByte();
+		for (uint j = 0; j < 6; ++j)
+			room.connections[j] = f.readByte();
+		room.field8 = f.readByte();
+		room.picture = f.readByte();
+		_rooms.push_back(room);
+	}
+
+	// Load inventory data from executable
+	f.seek(0x100);
+	while (f.readByte() != 0xff) {
+		struct Item item;
+		item.field1 = f.readByte();
+		item.field2 = f.readByte();
+		item.field3 = f.readByte();
+		item.field4 = f.readByte();
+		item.field5 = f.readByte();
+		item.field6 = f.readByte();
+		item.field7 = f.readByte();
+		item.field8 = f.readByte();
+
+		f.readByte();
+
+		byte size = f.readByte();
+
+		for (uint i = 0; i < size; ++i)
+			item.field10.push_back(f.readByte());
+
+		_inventory.push_back(item);
+	}
+
+	// Load picture data from executable
+	f.seek(0x4b00);
+	for (uint i = 0; i < MH_PICS; ++i) {
+		struct Picture pic;
+		pic.block = f.readByte();
+		pic.offset = f.readUint16LE();
+		_pictures.push_back(pic);
+	}
+
+	// Load commands from executable
+	f.seek(0x3D00);
+	readCommands(f, _roomCommands);
+
+	f.seek(0x3C00);
+	readCommands(f, _globalCommands);
+
+	// Load dropped item offsets
+	f.seek(0x68ff);
+	for (uint i = 0; i < MH_ITEM_OFFSETS; ++i) {
+		Common::Point p;
+		p.x = f.readByte();
+		p.y = f.readByte();
+		_itemOffsets.push_back(p);
+	}
+
+	// Load right-angle drawings
+	f.seek(0x4f00);
+	uint16 drawingsTotal = f.readUint16LE();
+	for (uint i = 0; i < drawingsTotal; ++i) {
+		f.seek(0x4f00 + 2 + i * 2);
+		uint16 offset = f.readUint16LE();
+		f.seek(0x4f00 + offset);
+
+		Common::Array<byte> drawing;
+		byte b = f.readByte();
+		while (b != 0) {
+			drawing.push_back(b);
+			b = f.readByte();
+		}
+		_drawings.push_back(drawing);
+	}
+
+	// Title screen shown during loading
+	f.seek(0x1800);
+	_display->loadFrameBuffer(f);
+	_display->decodeFrameBuffer();
+	_display->delay(2000);
+
+	f.seek(0x3800);
+	_parser->loadVerbs(f);
+
+	f.seek(0xf00);
+	_parser->loadNouns(f);
+
+	while (1) {
+		uint verb = 0, noun = 0;
+		clearScreen();
+		showRoom();
+		_parser->getInput(verb, noun);
+
+		if (!doOneCommand(_roomCommands, verb, noun))
+			printMessage(37);
+		doAllCommands(_globalCommands, verb, noun);
+
+		_steps++;
+
+		if (shouldQuit())
+			return;
+	}
+}
+
+AdlEngine *AdlEngine_v1__create(OSystem *syst, const AdlGameDescription *gd) {
+	return new AdlEngine_v1(syst, gd);
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/adl_v1.h b/engines/adl/adl_v1.h
new file mode 100644
index 0000000..b8f4c53
--- /dev/null
+++ b/engines/adl/adl_v1.h
@@ -0,0 +1,133 @@
+/* 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_V1_H
+#define ADL_ADL_V1_H
+
+#include "adl/adl.h"
+
+namespace Common {
+class ReadStream;
+}
+
+namespace Adl {
+
+enum {
+	// Some of these are probably common
+	STR_MH_DIRERR = STR_CUSTOM_START,
+	STR_MH_DONTHAVEIT,
+	STR_MH_DONTUNDERSTAND,
+	STR_MH_GETTINGDARK,
+	STR_MH_PLAYAGAIN,
+
+	STR_MH_TOTAL
+};
+
+class AdlEngine_v1 : public AdlEngine {
+public:
+	AdlEngine_v1(OSystem *syst, const AdlGameDescription *gd);
+	Common::String getExeString(uint idx);
+
+protected:
+	void runGame();
+
+private:
+	enum {
+		MH_ROOMS = 42,
+		MH_PICS = 98,
+		MH_ITEM_OFFSETS = 21
+	};
+
+	enum State {
+		kIntro,
+		kIdle
+	};
+
+	struct Room {
+		byte description;
+		byte connections[6];
+		byte field8;
+		byte picture;
+	};
+
+	struct Picture {
+		byte block;
+		uint16 offset;
+	};
+
+	struct Command {
+		byte room;
+		byte verb, noun;
+		byte numCond, numAct;
+		Common::Array<byte> script;
+	};
+
+	struct Item {
+		byte field1;
+		byte field2;
+		byte field3;
+		byte field4;
+		byte field5;
+		byte field6;
+		byte field7;
+		byte field8;
+		Common::Array<byte> field10;
+	};
+
+	typedef Common::List<Command> Commands;
+
+	int _state;
+
+	void runIntro();
+	void drawPic(Common::ReadStream &stream, byte xOffset, byte yOffset);
+	void showRoom();
+	void printMessage(uint idx, bool wait = true);
+	void wordWrap(Common::String &str);
+	void readCommands(Common::ReadStream &stream, Commands &commands);
+	bool checkCommand(const Command &command, byte verb, byte noun);
+	bool doOneCommand(const Commands &commands, byte verb, byte noun);
+	void doAllCommands(const Commands &commands, byte verb, byte noun);
+	void doActions(const Command &command, byte noun, byte offset);
+	void clearScreen();
+	void takeItem(byte noun);
+	void dropItem(byte noun);
+	void drawItems();
+	void drawPic(byte pic, byte xOffset, byte yOffset);
+
+	Common::Array<Common::String> _exeStrings;
+	Common::Array<Common::String> _msgStrings;
+	Common::Array<Room> _rooms;
+	Common::Array<Picture> _pictures;
+	Common::Array<Item> _inventory;
+	Common::Array<Common::Point> _itemOffsets;
+	Common::Array<Common::Array<byte> > _drawings;
+	Commands _roomCommands;
+	Commands _globalCommands;
+	byte _room;
+	uint16 _steps;
+	Common::Array<byte> _variables;
+	bool _isDark;
+};
+
+} // End of namespace Adl
+
+#endif
diff --git a/engines/adl/configure.engine b/engines/adl/configure.engine
new file mode 100644
index 0000000..844e2b8
--- /dev/null
+++ b/engines/adl/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine adl "ADL" no
diff --git a/engines/adl/detection.cpp b/engines/adl/detection.cpp
new file mode 100644
index 0000000..ba4e010
--- /dev/null
+++ b/engines/adl/detection.cpp
@@ -0,0 +1,108 @@
+/* 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.h"
+
+#include "common/config-manager.h"
+#include "common/error.h"
+#include "common/fs.h"
+
+#include "engines/advancedDetector.h"
+#include "engines/metaengine.h"
+
+namespace Adl {
+
+struct AdlGameDescription {
+	ADGameDescription desc;
+	GameType gameType;
+};
+
+uint32 AdlEngine::getFeatures() const {
+	return _gameDescription->desc.flags;
+}
+
+const char *AdlEngine::getGameId() const {
+	return _gameDescription->desc.gameid;
+}
+
+const char *const directoryGlobs[] = {
+	"game",
+	"datafiles",
+	0
+};
+
+static const PlainGameDescriptor adlGames[] = {
+	// Games
+	{"hires1", "Hi-Res Adventure #1: Mystery House"},
+	{0, 0}
+};
+
+static const AdlGameDescription gameDescriptions[] = {
+
+	{ // MD5 by waltervn
+		{
+			"hires1", 0,
+			{
+				{"ADVENTURE", 0, "22d9e63a11d69fa033ba1738715ad09a", 29952},
+				{"AUTO LOAD OBJ", 0, "23bfccfe9fcff9b22cf6c41bde9078ac", 12291},
+				{"MYSTERY.HELLO", 0, "2289b7fea300b506e902a4c597968369", 836},
+				AD_LISTEND
+			},
+			Common::EN_ANY,
+			Common::kPlatformApple2GS, // FIXME
+			ADGF_NO_FLAGS,
+			GUIO0()
+		},
+		kGameTypeAdl1
+	},
+	{AD_TABLE_END_MARKER, kGameTypeNone}
+};
+
+class AdlMetaEngine : public AdvancedMetaEngine {
+public:
+	AdlMetaEngine() : AdvancedMetaEngine(gameDescriptions, sizeof(AdlGameDescription), adlGames) { }
+
+	const char *getName() const {
+		return "Hi-Res Adventure";
+	}
+
+	const char *getOriginalCopyright() const {
+		return "Copyright (C) Sierra On-Line";
+	}
+
+	bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const;
+};
+
+bool AdlMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const {
+	if (gd) {
+		*engine = AdlEngine::create(((const AdlGameDescription *)gd)->gameType, syst, (const AdlGameDescription *)gd);
+	}
+	return gd != 0;
+}
+
+} // End of namespace Adl
+
+#if PLUGIN_ENABLED_DYNAMIC(ADL)
+	REGISTER_PLUGIN_DYNAMIC(ADL, PLUGIN_TYPE_ENGINE, Adl::AdlMetaEngine);
+#else
+	REGISTER_PLUGIN_STATIC(ADL, PLUGIN_TYPE_ENGINE, Adl::AdlMetaEngine);
+#endif
diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp
new file mode 100644
index 0000000..02b8d51
--- /dev/null
+++ b/engines/adl/display.cpp
@@ -0,0 +1,611 @@
+/* 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/display.h"
+#include "common/stream.h"
+#include "common/rect.h"
+#include "graphics/surface.h"
+#include "common/system.h"
+#include "common/str.h"
+#include "common/events.h"
+#include "common/rect.h"
+#include "common/array.h"
+#include "engines/engine.h"
+
+namespace Adl {
+
+static byte font[64][5] = {
+	{ 0x7c, 0x82, 0xba, 0xb2, 0x9c }, { 0xf8, 0x24, 0x22, 0x24, 0xf8 }, // @A
+	{ 0xfe, 0x92, 0x92, 0x92, 0x6c }, { 0x7c, 0x82, 0x82, 0x82, 0x44 }, // BC
+	{ 0xfe, 0x82, 0x82, 0x82, 0x7c }, { 0xfe, 0x92, 0x92, 0x92, 0x82 }, // DE
+	{ 0xfe, 0x12, 0x12, 0x12, 0x02 }, { 0x7c, 0x82, 0x82, 0xa2, 0xe2 }, // FG
+	{ 0xfe, 0x10, 0x10, 0x10, 0xfe }, { 0x00, 0x82, 0xfe, 0x82, 0x00 }, // HI
+	{ 0x40, 0x80, 0x80, 0x80, 0x7e }, { 0xfe, 0x10, 0x28, 0x44, 0x82 }, // JK
+	{ 0xfe, 0x80, 0x80, 0x80, 0x80 }, { 0xfe, 0x04, 0x18, 0x04, 0xfe }, // LM
+	{ 0xfe, 0x08, 0x10, 0x20, 0xfe }, { 0x7c, 0x82, 0x82, 0x82, 0x7c }, // NO
+	{ 0xfe, 0x12, 0x12, 0x12, 0x0c }, { 0x7c, 0x82, 0xa2, 0x42, 0xbc }, // PQ
+	{ 0xfe, 0x12, 0x32, 0x52, 0x8c }, { 0x4c, 0x92, 0x92, 0x92, 0x64 }, // RS
+	{ 0x02, 0x02, 0xfe, 0x02, 0x02 }, { 0x7e, 0x80, 0x80, 0x80, 0x7e }, // TU
+	{ 0x3e, 0x40, 0x80, 0x40, 0x3e }, { 0xfe, 0x40, 0x30, 0x40, 0xfe }, // VW
+	{ 0xc6, 0x28, 0x10, 0x28, 0xc6 }, { 0x06, 0x08, 0xf0, 0x08, 0x06 }, // XY
+	{ 0xc2, 0xa2, 0x92, 0x8a, 0x86 }, { 0xfe, 0xfe, 0x82, 0x82, 0x82 }, // Z[
+	{ 0x04, 0x08, 0x10, 0x20, 0x40 }, { 0x82, 0x82, 0x82, 0xfe, 0xfe }, // \]
+	{ 0x20, 0x10, 0x08, 0x10, 0x20 }, { 0x80, 0x80, 0x80, 0x80, 0x80 }, // ^_
+	{ 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0xbe, 0x00, 0x00 }, //  !
+	{ 0x00, 0x0e, 0x00, 0x0e, 0x00 }, { 0x28, 0xfe, 0x28, 0xfe, 0x28 }, // "#
+	{ 0x48, 0x54, 0xfe, 0x54, 0x24 }, { 0x46, 0x26, 0x10, 0xc8, 0xc4 }, // $%
+	{ 0x6c, 0x92, 0xac, 0x40, 0xa0 }, { 0x00, 0x00, 0x0e, 0x00, 0x00 }, // &'
+	{ 0x38, 0x44, 0x82, 0x00, 0x00 }, { 0x00, 0x00, 0x82, 0x44, 0x38 }, // ()
+	{ 0x44, 0x28, 0xfe, 0x28, 0x44 }, { 0x10, 0x10, 0x7c, 0x10, 0x10 }, // *+
+	{ 0x00, 0x80, 0x60, 0x00, 0x00 }, { 0x10, 0x10, 0x10, 0x10, 0x10 }, // ,-
+	{ 0x00, 0x00, 0x80, 0x00, 0x00 }, { 0x40, 0x20, 0x10, 0x08, 0x04 }, // ./
+	{ 0x7c, 0xa2, 0x92, 0x8a, 0x7c }, { 0x00, 0x84, 0xfe, 0x80, 0x00 }, // 01
+	{ 0xc4, 0xa2, 0x92, 0x92, 0x8c }, { 0x42, 0x82, 0x92, 0x9a, 0x66 }, // 23
+	{ 0x30, 0x28, 0x24, 0xfe, 0x20 }, { 0x4e, 0x8a, 0x8a, 0x8a, 0x72 }, // 45
+	{ 0x78, 0x94, 0x92, 0x92, 0x62 }, { 0x02, 0xe2, 0x12, 0x0a, 0x06 }, // 67
+	{ 0x6c, 0x92, 0x92, 0x92, 0x6c }, { 0x8c, 0x92, 0x92, 0x52, 0x3c }, // 89
+	{ 0x00, 0x00, 0x28, 0x00, 0x00 }, { 0x00, 0x80, 0x68, 0x00, 0x00 }, // :;
+	{ 0x10, 0x28, 0x44, 0x82, 0x00 }, { 0x28, 0x28, 0x28, 0x28, 0x28 }, // <=
+	{ 0x00, 0x82, 0x44, 0x28, 0x10 }, { 0x04, 0x02, 0xb2, 0x0a, 0x04 }  // >?
+};
+
+Display::Display() :
+		_scanlines(false),
+		_cursorPos(0),
+		_mode(kModeText) {
+	_frameBuf = new byte[kFrameBufSize];
+	_frameBufSurface = new Graphics::Surface;
+	_frameBufSurface->create(kWidth * 2, kHeight * 2, Graphics::PixelFormat::createFormatCLUT8());
+
+	_textBuf = new byte[kTextBufSize];
+	memset(_textBuf, ' ' | 0x80, kTextBufSize);
+	_textBufSurface = new Graphics::Surface;
+	_textBufSurface->create(kWidth * 2, kHeight * 2, Graphics::PixelFormat::createFormatCLUT8());
+
+	createFont();
+
+	struct PixelPos rel = getPixelPos(0, 191);
+	struct PixelPos absy;
+	for (int i = 191; i >= 0; --i) {
+		absy = getPixelPos(0, i);
+		if (absy.rowAddr != rel.rowAddr)
+			debug("%i: %04x %04x", i, absy.rowAddr, rel.rowAddr);
+		moveY(rel, false);
+	}
+	absy = getPixelPos(0, 191);
+	if (absy.rowAddr != rel.rowAddr)
+		debug("%i: %04x %04x", 191, absy.rowAddr, rel.rowAddr);
+
+	rel = getPixelPos(0, 0);
+	for (int i = 0; i < 192; ++i) {
+		absy = getPixelPos(0, i);
+		if (absy.rowAddr != rel.rowAddr)
+			debug("%i: %04x %04x", i, absy.rowAddr, rel.rowAddr);
+		moveY(rel, true);
+	}
+	absy = getPixelPos(0, 0);
+	if (absy.rowAddr != rel.rowAddr)
+		debug("%i: %04x %04x", 191, absy.rowAddr, rel.rowAddr);
+}
+
+Display::~Display() {
+	delete[] _frameBuf;
+	_frameBufSurface->free();
+	delete _frameBufSurface;
+
+	delete[] _textBuf;
+	_textBufSurface->free();
+	delete _textBufSurface;
+
+	_font->free();
+	delete _font;
+}
+
+void Display::loadFrameBuffer(Common::ReadStream &stream) {
+	stream.read(_frameBuf, kFrameBufSize);
+}
+
+void Display::decodeScanline(byte *dst, int pitch, byte *src) {
+	// TODO: shift secondPal by half a pixel
+
+	bool prevOn = false;
+
+	for (uint j = 0; j < 39; ++j) {
+		bool secondPal = src[j] & 0x80;
+		byte cur = src[j];
+		byte next = 0;
+		if (j != 39)
+			next = src[j + 1];
+
+		for (uint k = 0; k < 7; ++k) {
+			bool curOn = cur & (1 << k);
+			bool nextOn;
+
+			if (k != 6)
+				nextOn = cur & (1 << (k + 1));
+			else
+				nextOn = next & 1;
+
+			byte color;
+			if (curOn == prevOn || curOn == nextOn)
+				color = curOn ? 1 : 0;
+			else {
+				if (secondPal)
+					color = (curOn == ((j + k) % 2) ? 5 : 4);
+				else
+					color = (curOn == ((j + k) % 2) ? 3 : 2);
+			}
+
+			dst[0] = color;
+			dst[1] = color;
+
+			if (!_scanlines) {
+				dst[pitch] = color;
+				dst[pitch + 1] = color;
+			}
+
+			dst += 2;
+			prevOn = curOn;
+		}
+	}
+}
+
+Display::PixelPos Display::getPixelPos(byte x, byte y) {
+	PixelPos pixelPos;
+
+	// FIXME: check X, Y range
+
+	byte offsetL = y & 0xc0;
+	offsetL |= offsetL >> 2;
+	byte offsetH = y;
+	y <<= 2;
+	offsetH <<= 1;
+	offsetH |= y >> 7;
+	y <<= 1;
+	offsetH <<= 1;
+	offsetH |= y >> 7;
+	y <<= 1;
+	offsetL >>= 1;
+	offsetL |= y & 0x80;
+	y <<= 1;
+	offsetH = offsetH & 0x1f;
+	pixelPos.rowAddr = (offsetH << 8) | offsetL;
+	pixelPos.byteOffset = x / 7;
+	pixelPos.bitMask = 0x80 | (1 << x % 7);
+
+	return pixelPos;
+}
+
+byte Display::getPixelColor(byte offset, byte color) {
+	if (offset & 1) {
+		byte c = color << 1;
+		if (c >= 0x40 && c < 0xc0)
+			return color ^ 0x7f;
+	}
+
+	return color;
+}
+
+void Display::decodeFrameBuffer() {
+	byte *src = _frameBuf;
+	int pitch = _frameBufSurface->pitch;
+	for (int j = 0; j < 8; ++j) {
+		for (int i = 0; i < 8; ++i) {
+			byte *dst = (byte *)_frameBufSurface->getPixels() + pitch * 2 * (i * 8 + j);
+			decodeScanline(dst, pitch, src);
+			src += 40;
+			dst += pitch * 2 * 64;
+			decodeScanline(dst, pitch, src);
+			src += 40;
+			dst += pitch * 2 * 64;
+			decodeScanline(dst, pitch, src);
+			src += 48;
+			dst += pitch * 2 * 64;
+		}
+	}
+}
+
+void Display::drawPixel(byte x, byte y, byte color) {
+	PixelPos p = getPixelPos(x, y);
+	byte c = getPixelColor(p.byteOffset, color);
+	byte *b = _frameBuf + p.rowAddr + p.byteOffset;
+	c ^= *b;
+	c &= p.bitMask;
+	c ^= *b;
+	*b = c;
+}
+
+void Display::moveX(PixelPos &p, byte &color, bool left) {
+	if (left) {
+		byte bit = p.bitMask;
+		bool b = bit & 1;
+		bit >>= 1;
+		if (!b) {
+			bit ^= 0xc0;
+			p.bitMask = bit;
+			return;
+		}
+		--p.byteOffset;
+		if (p.byteOffset & 0x80)
+			p.byteOffset = 39;
+		p.bitMask = 0xc0;
+	} else {
+		byte bit = p.bitMask;
+		bit <<= 1;
+		bit ^= 0x80;
+		if (bit & 0x80) {
+			p.bitMask = bit;
+			return;
+		}
+		p.bitMask = 0x81;
+		++p.byteOffset;
+		if (p.byteOffset == 40)
+			p.byteOffset = 0;
+	}
+
+	color = getPixelColor(p.byteOffset, color);
+}
+
+void Display::moveY(PixelPos &p, bool down) {
+	if (!down) {
+		if (p.rowAddr & 0x1c00)
+			p.rowAddr -= 0x400;
+		else if (p.rowAddr & 0x380)
+			p.rowAddr += 0x1b80;
+		else {
+			p.rowAddr += 0x1f58;
+			if (!(p.rowAddr & 0x80))
+				p.rowAddr += 0x78; // Wrap around
+		}
+	} else {
+		p.rowAddr += 0x400;
+		if (p.rowAddr & 0x1c00)
+			return;
+		else if ((p.rowAddr & 0x380) != 0x380)
+			p.rowAddr -= 0x1f80;
+		else {
+			p.rowAddr -= 0x2358;
+			if ((p.rowAddr & 0x78) == 0x78)
+				p.rowAddr -= 0x78; // Wrap around
+		}
+	}
+}
+
+void Display::drawNextPixel(Display::PixelPos &p, byte &color, byte bits, byte quadrant) {
+	if (bits & 4) {
+		byte b = (_frameBuf[p.rowAddr + p.byteOffset] ^ color) & p.bitMask;
+		_frameBuf[p.rowAddr + p.byteOffset] ^= b;
+	}
+
+	bits += quadrant;
+
+	if (bits & 1)
+		moveX(p, color, bits & 2);
+	else
+		moveY(p, bits & 2);
+}
+
+void Display::drawRightAngles(Common::Array<byte> &rightAngles, Common::Point p, byte rotation, byte scaling, byte color) {
+	const byte stepping[] = {
+		0xff, 0xfe, 0xfa, 0xf4, 0xec, 0xe1, 0xd4, 0xc5,
+		0xb4, 0xa1, 0x8d, 0x78, 0x61, 0x49, 0x31, 0x18,
+		0xff
+	};
+
+	PixelPos pos = getPixelPos(p.x, p.y);
+	byte c = getPixelColor(pos.byteOffset, color);
+
+	byte quadrant = rotation >> 4;
+	rotation &= 0xf;
+	byte xStep = stepping[rotation];
+	byte yStep = stepping[(rotation ^ 0xf) + 1] + 1;
+
+	for (uint i = 0; i < rightAngles.size(); ++i) {
+		byte b = rightAngles[i];
+
+		do {
+			byte xFrac = 0x80;
+			byte yFrac = 0x80;
+			for (uint j = 0; j < scaling; ++j) {
+				if (xFrac + xStep + 1 > 255)
+					drawNextPixel(pos, c, b, quadrant);
+				xFrac += xStep + 1;
+				if (yFrac + yStep > 255)
+					drawNextPixel(pos, c, b, quadrant + 1);
+				yFrac += yStep;
+			}
+			b >>= 3;
+		} while (b != 0);
+	}
+}
+
+void Display::drawLine(Common::Point p1, Common::Point p2, byte color) {
+	PixelPos p = getPixelPos(p1.x, p1.y);
+	byte c = getPixelColor(p.byteOffset, color);
+
+	int16 deltaX = p2.x - p1.x;
+	byte dir = deltaX >> 8;
+
+	if (deltaX < 0)
+		deltaX = -deltaX;
+
+	int16 err = deltaX;
+
+	int16 deltaY = p2.y - p1.y - 1;
+	dir >>= 1;
+	if (deltaY >= 0) {
+		deltaY = -deltaY - 2;
+		dir |= 0x80;
+	}
+
+	int16 steps = deltaY - deltaX;
+
+	err += deltaY + 1;
+
+	while (1) {
+		byte *b = _frameBuf + p.rowAddr + p.byteOffset;
+		byte d = *b;
+		d ^= c;
+		d &= p.bitMask;
+		d ^= *b;
+		*b = d;
+
+		if (++steps == 0)
+			return;
+
+		if (err < 0) {
+			moveY(p, dir & 0x80);
+			err += deltaX;
+		} else {
+			moveX(p, c, dir & 0x40);
+			err += deltaY + 1;
+		}
+	}
+}
+
+void Display::clear(byte color) {
+	for (uint i = 0; i < kFrameBufSize; ++i)
+		_frameBuf[i] = getPixelColor(i & 1, color);
+}
+
+void Display::updateTextSurface() {
+	for (uint row = 0; row < 24; ++row)
+		for (uint col = 0; col < 40; ++col) {
+			char c = _textBuf[row * 40 + col];
+
+			Common::Rect r(7 * 2, 8 * 2);
+			r.translate(((c & 0x3f) % 16) * 7 * 2, (c & 0x3f) / 16 * 8 * 2);
+
+			if (!(c & 0x80)) {
+				if (!(c & 0x40) || ((g_system->getMillis() / 270) & 1))
+					r.translate(0, 4 * 8 * 2);
+			}
+
+			_textBufSurface->copyRectToSurface(*_font, col * 7 * 2, row * 8 * 2, r);
+		}
+}
+
+void Display::printString(const Common::String &str) {
+	Common::String::const_iterator it;
+	for (it = str.begin(); it != str.end(); ++it) {
+		byte b = *it;
+
+		if (b == ('\r' | 0x80))
+			_cursorPos = (_cursorPos / 40 + 1) * 40;
+		else if (b < 0x80 || b >= 0xa0)
+			_textBuf[_cursorPos++] = b;
+
+		if (_cursorPos == kTextBufSize) {
+			memmove(_textBuf, _textBuf + 40, kTextBufSize - 40);
+			memset(_textBuf + kTextBufSize - 40, ' ' | 0x80, 40);
+			_cursorPos -= 40;
+		}
+	}
+
+	updateTextSurface();
+}
+
+void Display::printASCIIString(const Common::String &str) {
+	Common::String aStr;
+
+	Common::String::const_iterator it;
+	for (it = str.begin(); it != str.end(); ++it)
+			aStr += *it | 0x80;
+
+	printString(aStr);
+}
+
+void Display::drawChar(byte c, int x, int y) {
+	byte *buf = (byte *)_font->getPixels() + y * _font->pitch + x;
+
+	for (uint row = 0; row < 8; ++row) {
+		for (uint col = 1; col < 6; ++col)
+			if (font[c][col - 1] & (1 << row)) {
+				buf[col * 2] = 1;
+				buf[col * 2 + 1] = 1;
+
+				if (!_scanlines) {
+					buf[_font->pitch + col * 2] = 1;
+					buf[_font->pitch + col * 2 + 1] = 1;
+				}
+			}
+
+		buf += 2 * _font->pitch;
+	}
+}
+
+void Display::createFont() {
+	_font = new Graphics::Surface;
+	_font->create(16 * 7 * 2, 4 * 8 * 2 * 2, Graphics::PixelFormat::createFormatCLUT8());
+
+	for (uint i = 0; i < 4; ++i)
+		for (uint j = 0; j < 16; ++j)
+			drawChar(i * 16 + j, j * 7 * 2, i * 8 * 2);
+
+	// Create inverted font
+	byte *buf = (byte *)_font->getPixels();
+	byte *bufInv = buf + (_font->h / 2) * _font->pitch;
+
+	for (uint row = 0; row < _font->h / 2; ++row) {
+		if (!_scanlines || !(row & 1))
+			for (uint col = 0; col < _font->w; ++col)
+				bufInv[col] = buf[col] ? 0 : 1;
+
+		buf += _font->pitch;
+		bufInv += _font->pitch;
+	}
+}
+
+void Display::updateScreen() {
+	if (_mode == kModeText) {
+		g_system->copyRectToScreen(_textBufSurface->getPixels(), _textBufSurface->pitch, 0, 0, _textBufSurface->w, _textBufSurface->h);
+	} else if (_mode == kModeHires) {
+		g_system->copyRectToScreen(_frameBufSurface->getPixels(), _frameBufSurface->pitch, 0, 0, _frameBufSurface->w, _frameBufSurface->h);
+	} else {
+		g_system->copyRectToScreen(_frameBufSurface->getPixels(), _frameBufSurface->pitch, 0, 0, _frameBufSurface->w, _frameBufSurface->h - 4 * 8 * 2);
+		g_system->copyRectToScreen(_textBufSurface->getBasePtr(0, _textBufSurface->h - 4 * 8 * 2), _textBufSurface->pitch, 0, _textBufSurface->h - 4 * 8 * 2, _textBufSurface->w, 4 * 8 * 2);
+	}
+}
+
+Common::String Display::inputString(byte prompt) {
+	Common::String s;
+
+	if (prompt > 0)
+		printString(Common::String(prompt));
+
+	while (1) {
+		byte b = inputKey();
+
+		if (g_engine->shouldQuit())
+			return 0;
+
+		if (b == 0)
+			continue;
+
+		if (b == ('\r' | 0x80)) {
+			s += b;
+			printString(Common::String(b));
+			return s;
+		}
+
+		if (b < 0xa0) {
+			switch (b) {
+			case Common::KEYCODE_BACKSPACE | 0x80:
+				if (!s.empty()) {
+					--_cursorPos;
+					_textBuf[_cursorPos] = ' ' | 0x80;
+					s.deleteLastChar();
+				}
+				break;
+			};
+		} else {
+			s += b;
+			printString(Common::String(b));
+		}
+	}
+}
+
+byte Display::convertKey(uint16 ascii) {
+	ascii = toupper(ascii);
+
+	if (ascii >= 0x80)
+		return 0;
+
+	ascii |= 0x80;
+
+	if (ascii >= 0x80 && ascii <= 0xe0)
+		return ascii;
+
+	return 0;
+}
+
+byte Display::inputKey() {
+	Common::EventManager *ev = g_system->getEventManager();
+
+	byte orgChar = _textBuf[_cursorPos];
+	_textBuf[_cursorPos] = (orgChar & 0x3f) | 0x40;
+
+	byte key = 0;
+
+	while (!g_engine->shouldQuit() && key == 0) {
+		Common::Event event;
+		if (ev->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:
+				key = convertKey(event.kbd.keycode);
+				break;
+			default:
+				if (event.kbd.ascii >= 0x20 && event.kbd.ascii < 0x80)
+					key = convertKey(event.kbd.ascii);
+			};
+		}
+
+		updateTextSurface();
+		updateScreen();
+		g_system->updateScreen();
+		g_system->delayMillis(16);
+	}
+
+	_textBuf[_cursorPos] = orgChar;
+	return key;
+}
+
+void Display::delay(uint32 ms) {
+	Common::EventManager *ev = g_system->getEventManager();
+
+	uint32 start = g_system->getMillis();
+
+	while (!g_engine->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;
+				}
+			}
+		}
+		updateScreen();
+		g_system->updateScreen();
+		g_system->delayMillis(16);
+	}
+}
+
+void Display::home() {
+	memset(_textBuf, ' ' | 0x80, kTextBufSize);
+	_cursorPos = 0;
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/display.h b/engines/adl/display.h
new file mode 100644
index 0000000..eabf340
--- /dev/null
+++ b/engines/adl/display.h
@@ -0,0 +1,103 @@
+/* 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_DISPLAY_H
+#define ADL_DISPLAY_H
+
+#include <common/types.h>
+#include <common/array.h>
+
+namespace Common {
+class ReadStream;
+class String;
+class Point;
+}
+
+namespace Graphics {
+class Surface;
+}
+
+namespace Adl {
+ 
+class Display {
+public:
+	enum Mode {
+		kModeHires,
+		kModeText,
+		kModeMixed
+	};
+
+	Display();
+	~Display();
+	void loadFrameBuffer(Common::ReadStream &stream);
+	void decodeFrameBuffer();
+	void printString(const Common::String &str);
+	void printASCIIString(const Common::String &str);
+	void updateScreen();
+	Common::String inputString(byte prompt = 0);
+	void delay(uint32 ms);
+	void setMode(Mode mode) { _mode = mode; }
+	byte inputKey();
+	void home();
+	void drawPixel(byte x, byte y, byte color);
+	void drawLine(Common::Point p1, Common::Point p2, byte color);
+	void clear(byte color);
+	void drawRightAngles(Common::Array<byte> &rightAngles, Common::Point p, byte rotation, byte scaling, byte color);
+
+private:
+	enum {
+		kWidth = 280,
+		kHeight = 192,
+		kFrameBufSize = 0x2000,
+		kTextBufSize = 40 * 24
+	};
+
+	struct PixelPos {
+		uint16 rowAddr;
+		byte byteOffset;
+		byte bitMask;
+	};
+
+	void decodeScanline(byte *dst, int pitch, byte *src);
+	PixelPos getPixelPos(byte x, byte y);
+	byte getPixelColor(byte x, byte color);
+	void drawChar(byte c, int x, int y);
+	void createFont();
+	void updateTextSurface();
+	byte convertKey(uint16 ascii);
+	void moveX(PixelPos &p, byte &color, bool left);
+	void moveY(PixelPos &p, bool down);
+	void drawNextPixel(Display::PixelPos &p, byte &color, byte bits, byte quadrant);
+
+	bool _scanlines;
+	byte *_frameBuf;
+	byte *_textBuf;
+	Graphics::Surface *_frameBufSurface;
+	Graphics::Surface *_textBufSurface;
+	Graphics::Surface *_font;
+	int _cursorPos;
+	Mode _mode;
+};
+ 
+} // End of namespace Adl
+
+#endif
diff --git a/engines/adl/module.mk b/engines/adl/module.mk
new file mode 100644
index 0000000..8f86eee
--- /dev/null
+++ b/engines/adl/module.mk
@@ -0,0 +1,19 @@
+MODULE := engines/adl
+
+MODULE_OBJS := \
+	detection.o \
+	display.o \
+	adl.o \
+	adl_v1.o \
+	parser.o
+
+MODULE_DIRS += \
+	engines/adl
+
+# This module can be built as a plugin
+ifeq ($(ENABLE_ADL), DYNAMIC_PLUGIN)
+PLUGIN := 1
+endif
+
+# Include common rules
+include $(srcdir)/rules.mk
diff --git a/engines/adl/parser.cpp b/engines/adl/parser.cpp
new file mode 100644
index 0000000..cdbaf3b
--- /dev/null
+++ b/engines/adl/parser.cpp
@@ -0,0 +1,172 @@
+/* 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.h"
+#include "adl/parser.h"
+#include "adl/display.h"
+
+#include "engines/engine.h"
+
+#include "common/str.h"
+#include "common/stream.h"
+#include "common/debug.h"
+#include "common/textconsole.h"
+
+namespace Adl {
+
+Parser::Parser(AdlEngine &engine, Display &display) :
+		_engine(engine),
+		_display(display) {
+
+}
+
+void Parser::loadWords(Common::ReadStream &stream, WordMap &map) {
+	uint index = 0;
+
+	while (1) {
+		++index;
+
+		byte buf[kWordSize];
+
+		if (stream.read(buf, kWordSize) < kWordSize)
+			error("Error reading word list");
+
+		Common::String word((char *)buf, kWordSize);
+
+		if (!map.contains(word))
+			map[word] = index;
+
+		byte synonyms = stream.readByte();
+
+		if (stream.err() || stream.eos())
+			error("Error reading word list");
+
+		if (synonyms == 0xff)
+			break;
+
+		for (uint i = 0; i < synonyms; ++i) {
+			if (stream.read((char *)buf, kWordSize) < kWordSize)
+				error("Error reading word list");
+
+			word = Common::String((char *)buf, kWordSize);
+
+			if (!map.contains(word))
+				map[word] = index;
+		}
+	}
+}
+
+Common::String Parser::getLine() {
+ 	// Original engine uses a global here, which isn't reset between
+ 	// calls and may not match actual mode
+	bool textMode = false;
+
+	while (1) {
+		Common::String line = _display.inputString(A2CHAR('?'));
+
+		if (g_engine->shouldQuit())
+			return "";
+
+		if ((byte)line[0] == ('\r' | 0x80)) {
+			textMode = !textMode;
+			_display.setMode(textMode ? Display::kModeText : Display::kModeMixed);
+			continue;
+		}
+
+		// Remove the return
+		line.deleteLastChar();
+		return line;
+	}
+}
+
+Common::String Parser::getWord(const Common::String &line, uint &index) {
+	Common::String str;
+
+	for (uint i = 0; i < 8; ++i)
+		str += (char)(A2CHAR(' '));
+
+	int copied = 0;
+
+	// Skip initial whitespace
+	while (1) {
+		if (index == line.size())
+			return str;
+		if (line[index] != (char)(A2CHAR(' ')))
+			break;
+		++index;
+	}
+
+	// Copy up to 8 characters
+	while (1) {
+		if (copied < 8)
+			str.setChar(line[index], copied++);
+
+		index++;
+
+		if (index == line.size() || line[index] == (char)(A2CHAR(' ')))
+			return str;
+	}
+}
+
+void Parser::getInput(uint &verb, uint &noun) {
+	while (1) {
+		_display.printString(_engine.getExeString(STR_COMMON_ENTERCMD));
+		Common::String line = getLine();
+
+		if (g_engine->shouldQuit())
+			return;
+
+		uint index = 0;
+		Common::String verbStr = getWord(line, index);
+		debug("Verb: \"%s\"", appleToAscii(verbStr).c_str());
+
+		if (!_verbs.contains(verbStr)) {
+			Common::String err = _engine.getExeString(STR_COMMON_VERBERR);
+			for (uint i = 0; i < verbStr.size(); ++i)
+				err.setChar(verbStr[i], i + 19);
+			_display.printString(err);
+			continue;
+		}
+
+		verb = _verbs[verbStr];
+		debug("Verb ID: %i", verb);
+
+		Common::String nounStr = getWord(line, index);
+		debug("Noun: \"%s\"", appleToAscii(nounStr).c_str());
+
+		if (!_nouns.contains(nounStr)) {
+			Common::String err = _engine.getExeString(STR_COMMON_NOUNERR);
+			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);
+			continue;
+		}
+
+		noun = _nouns[nounStr];
+		debug("Noun ID: %i", noun);
+		return;
+	}
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/parser.h b/engines/adl/parser.h
new file mode 100644
index 0000000..3c191d9
--- /dev/null
+++ b/engines/adl/parser.h
@@ -0,0 +1,66 @@
+/* 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_PARSER_H
+#define ADL_PARSER_H
+
+#include "common/types.h"
+#include "common/hashmap.h"
+#include "common/hash-str.h"
+
+namespace Common {
+class ReadStream;
+class String;
+}
+
+namespace Adl {
+
+class Display;
+
+class Parser {
+public:
+	Parser(AdlEngine &engine, Display &display);
+
+	void loadVerbs(Common::ReadStream &stream) { loadWords(stream, _verbs); }
+	void loadNouns(Common::ReadStream &stream) { loadWords(stream, _nouns); }
+	void getInput(uint &verb, uint &noun);
+
+private:
+	enum {
+		kWordSize = 8
+	};
+
+	typedef Common::HashMap<Common::String, uint> WordMap;
+
+	void loadWords(Common::ReadStream &stream, WordMap &map);
+	Common::String getLine();
+	Common::String getWord(const Common::String &line, uint &index);
+
+	AdlEngine &_engine;
+	Display &_display;
+	WordMap _verbs;
+	WordMap _nouns;
+};
+
+} // End of namespace Adl
+
+#endif


Commit: 87e2c4c1a933cbfb8cb03e36531503f0d1122053
    https://github.com/scummvm/scummvm/commit/87e2c4c1a933cbfb8cb03e36531503f0d1122053
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Rename game type

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



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index be3d8d7..b96ecc8 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -145,7 +145,7 @@ void AdlEngine::printStrings(Common::SeekableReadStream &stream, int count) {
 
 AdlEngine *AdlEngine::create(GameType type, OSystem *syst, const AdlGameDescription *gd) {
 	switch(type) {
-	case kGameTypeAdl1:
+	case kGameTypeHires1:
 		return AdlEngine_v1__create(syst, gd);
 	default:
 		error("Unknown GameType");
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index d5a518fa..e945a45 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -41,7 +41,7 @@ struct AdlGameDescription;
 
 enum GameType {
 	kGameTypeNone = 0,
-	kGameTypeAdl1
+	kGameTypeHires1
 };
 
 Common::String asciiToApple(Common::String str);
diff --git a/engines/adl/detection.cpp b/engines/adl/detection.cpp
index ba4e010..9fadb9d 100644
--- a/engines/adl/detection.cpp
+++ b/engines/adl/detection.cpp
@@ -20,14 +20,9 @@
  *
  */
 
-#include "adl/adl.h"
-
-#include "common/config-manager.h"
-#include "common/error.h"
-#include "common/fs.h"
-
 #include "engines/advancedDetector.h"
-#include "engines/metaengine.h"
+
+#include "adl/adl.h"
 
 namespace Adl {
 
@@ -36,22 +31,7 @@ struct AdlGameDescription {
 	GameType gameType;
 };
 
-uint32 AdlEngine::getFeatures() const {
-	return _gameDescription->desc.flags;
-}
-
-const char *AdlEngine::getGameId() const {
-	return _gameDescription->desc.gameid;
-}
-
-const char *const directoryGlobs[] = {
-	"game",
-	"datafiles",
-	0
-};
-
 static const PlainGameDescriptor adlGames[] = {
-	// Games
 	{"hires1", "Hi-Res Adventure #1: Mystery House"},
 	{0, 0}
 };
@@ -72,7 +52,7 @@ static const AdlGameDescription gameDescriptions[] = {
 			ADGF_NO_FLAGS,
 			GUIO0()
 		},
-		kGameTypeAdl1
+		kGameTypeHires1
 	},
 	{AD_TABLE_END_MARKER, kGameTypeNone}
 };
@@ -82,7 +62,7 @@ public:
 	AdlMetaEngine() : AdvancedMetaEngine(gameDescriptions, sizeof(AdlGameDescription), adlGames) { }
 
 	const char *getName() const {
-		return "Hi-Res Adventure";
+		return "ADL";
 	}
 
 	const char *getOriginalCopyright() const {
@@ -93,10 +73,9 @@ public:
 };
 
 bool AdlMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const {
-	if (gd) {
+	if (gd)
 		*engine = AdlEngine::create(((const AdlGameDescription *)gd)->gameType, syst, (const AdlGameDescription *)gd);
-	}
-	return gd != 0;
+	return gd != nullptr;
 }
 
 } // End of namespace Adl


Commit: 9717aa956197480a608622a2e294fa8302258a0e
    https://github.com/scummvm/scummvm/commit/9717aa956197480a608622a2e294fa8302258a0e
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Clean-up string handling

Changed paths:
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/adl_v1.cpp
    engines/adl/display.cpp
    engines/adl/display.h
    engines/adl/parser.cpp



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index b96ecc8..9925e04 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -20,77 +20,35 @@
  *
  */
 
- #include "common/scummsys.h"
-
+#include "common/scummsys.h"
 #include "common/config-manager.h"
 #include "common/debug.h"
-#include "common/debug-channels.h"
 #include "common/error.h"
 #include "common/file.h"
-#include "common/fs.h"
 #include "common/system.h"
 #include "common/events.h"
 #include "common/stream.h"
-#include "graphics/palette.h"
 
 #include "engines/util.h"
 
+#include "graphics/palette.h"
+
 #include "adl/adl.h"
 #include "adl/display.h"
 #include "adl/parser.h"
 
 namespace Adl {
 
-Common::String asciiToApple(Common::String str) {
-	Common::String ret(str);
-	Common::String::iterator it;
-
-	for (it = ret.begin(); it != ret.end(); ++it)
-		*it = *it | 0x80;
-
-	return ret;
-}
-
-Common::String appleToAscii(Common::String str) {
-	Common::String ret(str);
-	Common::String::iterator it;
-
-	for (it = ret.begin(); it != ret.end(); ++it)
-		*it = *it & 0x7f;
-
-	return ret;
-}
-
 AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) :
 		Engine(syst),
 		_gameDescription(gd),
 		_console(nullptr),
 		_display(nullptr) {
-	// Put your engine in a sane state, but do nothing big yet;
-	// in particular, do not load data from files; rather, if you
-	// need to do such things, do them from run().
-
-	// Do not initialize graphics here
-	// Do not initialize audio devices here
-
-	// However this is the place to specify all default directories
-	const Common::FSNode gameDataDir(ConfMan.get("path"));
-	SearchMan.addSubDirectoryMatching(gameDataDir, "sound");
-
-	// Don't forget to register your random source
-	_rnd = new Common::RandomSource("adl");
-
-	debug("AdlEngine::AdlEngine");
 }
 
 AdlEngine::~AdlEngine() {
-	debug("AdlEngine::~AdlEngine");
-
-	delete _rnd;
 	delete _console;
 	delete _display;
-
-	DebugMan.clearAllDebugChannels();
 }
 
 Common::Error AdlEngine::run() {
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index e945a45..954c613 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -44,9 +44,6 @@ enum GameType {
 	kGameTypeHires1
 };
 
-Common::String asciiToApple(Common::String str);
-Common::String appleToAscii(Common::String str);
-
 enum {
 	STR_COMMON_ENTERCMD,
 	STR_COMMON_VERBERR,
@@ -54,7 +51,38 @@ enum {
 	STR_CUSTOM_START
 };
 
-#define A2CHAR(C) ((C) | 0x80)
+struct Room {
+	byte description;
+	byte connections[6];
+	byte field8;
+	byte picture;
+};
+
+struct Picture {
+	byte block;
+	uint16 offset;
+};
+
+struct Command {
+	byte room;
+	byte verb, noun;
+	byte numCond, numAct;
+	Common::Array<byte> script;
+};
+
+struct Item {
+	byte field1;
+	byte field2;
+	byte field3;
+	byte field4;
+	byte field5;
+	byte field6;
+	byte field7;
+	byte field8;
+	Common::Array<byte> field10;
+};
+
+typedef Common::List<Command> Commands;
 
 class AdlEngine : public Engine {
 public:
diff --git a/engines/adl/adl_v1.cpp b/engines/adl/adl_v1.cpp
index 61671e5..4218239 100644
--- a/engines/adl/adl_v1.cpp
+++ b/engines/adl/adl_v1.cpp
@@ -240,10 +240,10 @@ void AdlEngine_v1::wordWrap(Common::String &str) {
 		if (str.size() <= end)
 			return;
 
-		while (str[end] != (char)A2CHAR(' '))
+		while (str[end] != APPLECHAR(' '))
 			--end;
 
-		str.setChar((char)A2CHAR('\r'), end);
+		str.setChar(APPLECHAR('\r'), end);
 		end += 40;
 	}
 }
@@ -414,7 +414,7 @@ void AdlEngine_v1::doActions(const Command &command, byte noun, byte offset) {
 		case 0x11: {
 			_display->printString(_exeStrings[STR_MH_PLAYAGAIN]);
 			Common::String input = _display->inputString();
-			if (input.size() == 0 || input[0] != (char)A2CHAR('N')) {
+			if (input.size() == 0 || input[0] != APPLECHAR('N')) {
 				warning("Restart game not implemented");
 				return;
 			}
@@ -528,12 +528,9 @@ bool AdlEngine_v1::checkCommand(const Command &command, byte verb, byte noun) {
 bool AdlEngine_v1::doOneCommand(const Commands &commands, byte verb, byte noun) {
 	Commands::const_iterator it;
 
-	for (it = commands.begin(); it != commands.end(); ++it) {
-		if (checkCommand(*it, verb, noun)) {
-			debug("Found match: %i %i %i", it->room, it->verb, it->noun);
+	for (it = commands.begin(); it != commands.end(); ++it)
+		if (checkCommand(*it, verb, noun))
 			return true;
-		}
-	}
 
 	return false;
 }
@@ -541,11 +538,8 @@ bool AdlEngine_v1::doOneCommand(const Commands &commands, byte verb, byte noun)
 void AdlEngine_v1::doAllCommands(const Commands &commands, byte verb, byte noun) {
 	Commands::const_iterator it;
 
-	for (it = commands.begin(); it != commands.end(); ++it) {
-		if (checkCommand(*it, verb, noun)) {
-			debug("Found match: %i %i %i", it->room, it->verb, it->noun);
-		}
-	}
+	for (it = commands.begin(); it != commands.end(); ++it)
+		checkCommand(*it, verb, noun);
 }
 
 void AdlEngine_v1::clearScreen() {
@@ -563,7 +557,7 @@ void AdlEngine_v1::runGame() {
 		error("Failed to open file");
 
 	while (!f.eos() && !f.err())
-		_msgStrings.push_back(readString(f, A2CHAR('\r')) + (char)A2CHAR('\r'));
+		_msgStrings.push_back(readString(f, APPLECHAR('\r')) + APPLECHAR('\r'));
 
 	f.close();
 
diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp
index 02b8d51..47b1533 100644
--- a/engines/adl/display.cpp
+++ b/engines/adl/display.cpp
@@ -429,7 +429,7 @@ void Display::printASCIIString(const Common::String &str) {
 
 	Common::String::const_iterator it;
 	for (it = str.begin(); it != str.end(); ++it)
-			aStr += *it | 0x80;
+			aStr += APPLECHAR(*it);
 
 	printString(aStr);
 }
diff --git a/engines/adl/display.h b/engines/adl/display.h
index eabf340..62294d3 100644
--- a/engines/adl/display.h
+++ b/engines/adl/display.h
@@ -37,7 +37,9 @@ class Surface;
 }
 
 namespace Adl {
- 
+
+#define APPLECHAR(C) ((char)((C) | 0x80))
+
 class Display {
 public:
 	enum Mode {
diff --git a/engines/adl/parser.cpp b/engines/adl/parser.cpp
index cdbaf3b..1611fc7 100644
--- a/engines/adl/parser.cpp
+++ b/engines/adl/parser.cpp
@@ -81,7 +81,7 @@ Common::String Parser::getLine() {
 	bool textMode = false;
 
 	while (1) {
-		Common::String line = _display.inputString(A2CHAR('?'));
+		Common::String line = _display.inputString(APPLECHAR('?'));
 
 		if (g_engine->shouldQuit())
 			return "";
@@ -102,7 +102,7 @@ Common::String Parser::getWord(const Common::String &line, uint &index) {
 	Common::String str;
 
 	for (uint i = 0; i < 8; ++i)
-		str += (char)(A2CHAR(' '));
+		str += APPLECHAR(' ');
 
 	int copied = 0;
 
@@ -110,7 +110,7 @@ Common::String Parser::getWord(const Common::String &line, uint &index) {
 	while (1) {
 		if (index == line.size())
 			return str;
-		if (line[index] != (char)(A2CHAR(' ')))
+		if (line[index] != APPLECHAR(' '))
 			break;
 		++index;
 	}
@@ -122,7 +122,7 @@ Common::String Parser::getWord(const Common::String &line, uint &index) {
 
 		index++;
 
-		if (index == line.size() || line[index] == (char)(A2CHAR(' ')))
+		if (index == line.size() || line[index] == APPLECHAR(' '))
 			return str;
 	}
 }
@@ -137,7 +137,6 @@ void Parser::getInput(uint &verb, uint &noun) {
 
 		uint index = 0;
 		Common::String verbStr = getWord(line, index);
-		debug("Verb: \"%s\"", appleToAscii(verbStr).c_str());
 
 		if (!_verbs.contains(verbStr)) {
 			Common::String err = _engine.getExeString(STR_COMMON_VERBERR);
@@ -148,10 +147,8 @@ void Parser::getInput(uint &verb, uint &noun) {
 		}
 
 		verb = _verbs[verbStr];
-		debug("Verb ID: %i", verb);
 
 		Common::String nounStr = getWord(line, index);
-		debug("Noun: \"%s\"", appleToAscii(nounStr).c_str());
 
 		if (!_nouns.contains(nounStr)) {
 			Common::String err = _engine.getExeString(STR_COMMON_NOUNERR);
@@ -164,7 +161,6 @@ void Parser::getInput(uint &verb, uint &noun) {
 		}
 
 		noun = _nouns[nounStr];
-		debug("Noun ID: %i", noun);
 		return;
 	}
 }


Commit: 183fe8b217c09df4deef3e31d5c01531bb532c50
    https://github.com/scummvm/scummvm/commit/183fe8b217c09df4deef3e31d5c01531bb532c50
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Move members into base class

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



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 9925e04..8042a9a 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -42,12 +42,15 @@ namespace Adl {
 AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) :
 		Engine(syst),
 		_gameDescription(gd),
-		_console(nullptr),
-		_display(nullptr) {
+		_display(nullptr),
+		_parser(nullptr),
+		_room(1),
+		_steps(0),
+		_isDark(false) {
 }
 
 AdlEngine::~AdlEngine() {
-	delete _console;
+	delete _parser;
 	delete _display;
 }
 
@@ -65,7 +68,6 @@ Common::Error AdlEngine::run() {
 
 	g_system->getPaletteManager()->setPalette(palette, 0, 6);
 
-	_console = new Console(this);
 	_display = new Display();
 	_parser = new Parser(*this, *_display);
 
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 954c613..55ba0fc 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -24,7 +24,10 @@
 #define ADL_ADL_H
 
 #include "common/random.h"
+#include "common/rect.h"
+
 #include "engines/engine.h"
+
 #include "gui/debugger.h"
 
 namespace Common {
@@ -102,14 +105,24 @@ protected:
 	virtual void runGame() = 0;
 	Common::String readString(Common::ReadStream &stream, byte until = 0);
 	void printStrings(Common::SeekableReadStream &stream, int count = 1);
+
 	Display *_display;
 	Parser *_parser;
 
-private:
-	Console *_console;
-
-	// We need random numbers
-	Common::RandomSource *_rnd;
+	Common::Array<Common::String> _msgStrings;
+	Common::Array<Picture> _pictures;
+	Common::Array<Item> _inventory;
+	Common::Array<Common::Point> _itemOffsets;
+	Common::Array<Common::Array<byte> > _drawings;
+	Commands _roomCommands;
+	Commands _globalCommands;
+
+	// Game state
+	Common::Array<Room> _rooms;
+	byte _room;
+	uint16 _steps;
+	Common::Array<byte> _variables;
+	bool _isDark;
 };
 
 // Example console class
diff --git a/engines/adl/adl_v1.cpp b/engines/adl/adl_v1.cpp
index 4218239..28aa895 100644
--- a/engines/adl/adl_v1.cpp
+++ b/engines/adl/adl_v1.cpp
@@ -46,11 +46,7 @@ static uint exeStrings[STR_MH_TOTAL] = {
 };
 
 AdlEngine_v1::AdlEngine_v1(OSystem *syst, const AdlGameDescription *gd) :
-		AdlEngine(syst, gd),
-		_state(kIntro),
-		_room(1),
-		_steps(1),
-		_isDark(false) {
+		AdlEngine(syst, gd) {
 	_variables.resize(20);
 }
 
diff --git a/engines/adl/adl_v1.h b/engines/adl/adl_v1.h
index b8f4c53..c1e28bc 100644
--- a/engines/adl/adl_v1.h
+++ b/engines/adl/adl_v1.h
@@ -57,46 +57,6 @@ private:
 		MH_ITEM_OFFSETS = 21
 	};
 
-	enum State {
-		kIntro,
-		kIdle
-	};
-
-	struct Room {
-		byte description;
-		byte connections[6];
-		byte field8;
-		byte picture;
-	};
-
-	struct Picture {
-		byte block;
-		uint16 offset;
-	};
-
-	struct Command {
-		byte room;
-		byte verb, noun;
-		byte numCond, numAct;
-		Common::Array<byte> script;
-	};
-
-	struct Item {
-		byte field1;
-		byte field2;
-		byte field3;
-		byte field4;
-		byte field5;
-		byte field6;
-		byte field7;
-		byte field8;
-		Common::Array<byte> field10;
-	};
-
-	typedef Common::List<Command> Commands;
-
-	int _state;
-
 	void runIntro();
 	void drawPic(Common::ReadStream &stream, byte xOffset, byte yOffset);
 	void showRoom();
@@ -114,18 +74,6 @@ private:
 	void drawPic(byte pic, byte xOffset, byte yOffset);
 
 	Common::Array<Common::String> _exeStrings;
-	Common::Array<Common::String> _msgStrings;
-	Common::Array<Room> _rooms;
-	Common::Array<Picture> _pictures;
-	Common::Array<Item> _inventory;
-	Common::Array<Common::Point> _itemOffsets;
-	Common::Array<Common::Array<byte> > _drawings;
-	Commands _roomCommands;
-	Commands _globalCommands;
-	byte _room;
-	uint16 _steps;
-	Common::Array<byte> _variables;
-	bool _isDark;
 };
 
 } // End of namespace Adl


Commit: d30cfa24fad35a668d0006f67b9d39901f0757a9
    https://github.com/scummvm/scummvm/commit/d30cfa24fad35a668d0006f67b9d39901f0757a9
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Remove dead code

Changed paths:
    engines/adl/adl.h



diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 55ba0fc..cc20edf 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -125,13 +125,6 @@ protected:
 	bool _isDark;
 };
 
-// Example console class
-class Console : public GUI::Debugger {
-public:
-	Console(AdlEngine *vm) {}
-	virtual ~Console(void) {}
-};
-
 AdlEngine *AdlEngine_v1__create(OSystem *syst, const AdlGameDescription *gd);
 
 } // End of namespace Adl


Commit: 43a37e94dd466887eabdeb589bdc54ca4cec6c41
    https://github.com/scummvm/scummvm/commit/43a37e94dd466887eabdeb589bdc54ca4cec6c41
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Rename AdlEngine_v1 to HiRes1Engine

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



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 8042a9a..3ee72e8 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -106,7 +106,7 @@ void AdlEngine::printStrings(Common::SeekableReadStream &stream, int count) {
 AdlEngine *AdlEngine::create(GameType type, OSystem *syst, const AdlGameDescription *gd) {
 	switch(type) {
 	case kGameTypeHires1:
-		return AdlEngine_v1__create(syst, gd);
+		return HiRes1Engine__create(syst, gd);
 	default:
 		error("Unknown GameType");
 	}
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index cc20edf..5252916 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -125,7 +125,7 @@ protected:
 	bool _isDark;
 };
 
-AdlEngine *AdlEngine_v1__create(OSystem *syst, const AdlGameDescription *gd);
+AdlEngine *HiRes1Engine__create(OSystem *syst, const AdlGameDescription *gd);
 
 } // End of namespace Adl
 
diff --git a/engines/adl/adl_v1.cpp b/engines/adl/adl_v1.cpp
index 28aa895..566a467 100644
--- a/engines/adl/adl_v1.cpp
+++ b/engines/adl/adl_v1.cpp
@@ -45,12 +45,12 @@ static uint exeStrings[STR_MH_TOTAL] = {
 	23484, 23375, 23438, 27658, 0x6c31, 27729, 27772, 0x5f1e
 };
 
-AdlEngine_v1::AdlEngine_v1(OSystem *syst, const AdlGameDescription *gd) :
+HiRes1Engine::HiRes1Engine(OSystem *syst, const AdlGameDescription *gd) :
 		AdlEngine(syst, gd) {
 	_variables.resize(20);
 }
 
-void AdlEngine_v1::runIntro() {
+void HiRes1Engine::runIntro() {
 	Common::File file;
 
 	if (!file.open("AUTO LOAD OBJ"))
@@ -132,7 +132,7 @@ void AdlEngine_v1::runIntro() {
 	}
 }
 
-void AdlEngine_v1::drawPic(Common::ReadStream &stream, byte xOffset, byte yOffset) {
+void HiRes1Engine::drawPic(Common::ReadStream &stream, byte xOffset, byte yOffset) {
 	byte x, y;
 	bool bNewLine = false;
 	byte oldX = 0, oldY = 0;
@@ -169,7 +169,7 @@ void AdlEngine_v1::drawPic(Common::ReadStream &stream, byte xOffset, byte yOffse
 	}
 }
 
-void AdlEngine_v1::drawPic(byte pic, byte xOffset, byte yOffset) {
+void HiRes1Engine::drawPic(byte pic, byte xOffset, byte yOffset) {
 	Common::File f;
 	Common::String name = Common::String::format("BLOCK%i", _pictures[pic].block);
 
@@ -180,7 +180,7 @@ void AdlEngine_v1::drawPic(byte pic, byte xOffset, byte yOffset) {
 	drawPic(f, xOffset, yOffset);
 }
 
-void AdlEngine_v1::drawItems() {
+void HiRes1Engine::drawItems() {
 	Common::Array<Item>::const_iterator it;
 
 	uint dropped = 0;
@@ -215,7 +215,7 @@ void AdlEngine_v1::drawItems() {
 	}
 }
 
-void AdlEngine_v1::showRoom() {
+void HiRes1Engine::showRoom() {
 	if (!_isDark) {
 		drawPic(_rooms[_room].picture, 0, 0);
 		drawItems();
@@ -225,11 +225,11 @@ void AdlEngine_v1::showRoom() {
 	printMessage(_rooms[_room].description, false);
 }
 
-Common::String AdlEngine_v1::getExeString(uint idx) {
+Common::String HiRes1Engine::getExeString(uint idx) {
 	return _exeStrings[idx];
 }
 
-void AdlEngine_v1::wordWrap(Common::String &str) {
+void HiRes1Engine::wordWrap(Common::String &str) {
 	uint end = 39;
 
 	while (1) {
@@ -244,7 +244,7 @@ void AdlEngine_v1::wordWrap(Common::String &str) {
 	}
 }
 
-void AdlEngine_v1::printMessage(uint idx, bool wait) {
+void HiRes1Engine::printMessage(uint idx, bool wait) {
 	// Hardcoded overrides that don't wait after printing
 	// Note: strings may differ slightly from the ones in MESSAGES
 	switch (idx) {
@@ -270,7 +270,7 @@ void AdlEngine_v1::printMessage(uint idx, bool wait) {
 		_display->delay(14 * 166018 / 1000);
 }
 
-void AdlEngine_v1::readCommands(Common::ReadStream &stream, Commands &commands) {
+void HiRes1Engine::readCommands(Common::ReadStream &stream, Commands &commands) {
 	while (1) {
 		Command command;
 		command.room = stream.readByte();
@@ -296,7 +296,7 @@ void AdlEngine_v1::readCommands(Common::ReadStream &stream, Commands &commands)
 	}
 }
 
-void AdlEngine_v1::takeItem(byte noun) {
+void HiRes1Engine::takeItem(byte noun) {
 	Common::Array<Item>::iterator it;
 
 	for (it = _inventory.begin(); it != _inventory.end(); ++it) {
@@ -329,7 +329,7 @@ void AdlEngine_v1::takeItem(byte noun) {
 	printMessage(152);
 }
 
-void AdlEngine_v1::dropItem(byte noun) {
+void HiRes1Engine::dropItem(byte noun) {
 	Common::Array<Item>::iterator it;
 
 	for (it = _inventory.begin(); it != _inventory.end(); ++it) {
@@ -345,7 +345,7 @@ void AdlEngine_v1::dropItem(byte noun) {
 	printMessage(37);
 }
 
-void AdlEngine_v1::doActions(const Command &command, byte noun, byte offset) {
+void HiRes1Engine::doActions(const Command &command, byte noun, byte offset) {
 	for (uint i = 0; i < command.numAct; ++i) {
 		switch (command.script[offset]) {
 		case 1:
@@ -473,7 +473,7 @@ void AdlEngine_v1::doActions(const Command &command, byte noun, byte offset) {
 	}
 }
 
-bool AdlEngine_v1::checkCommand(const Command &command, byte verb, byte noun) {
+bool HiRes1Engine::checkCommand(const Command &command, byte verb, byte noun) {
 	if (command.room != 0xfe && command.room != _room)
 		return false;
 
@@ -521,7 +521,7 @@ bool AdlEngine_v1::checkCommand(const Command &command, byte verb, byte noun) {
 	return true;
 }
 
-bool AdlEngine_v1::doOneCommand(const Commands &commands, byte verb, byte noun) {
+bool HiRes1Engine::doOneCommand(const Commands &commands, byte verb, byte noun) {
 	Commands::const_iterator it;
 
 	for (it = commands.begin(); it != commands.end(); ++it)
@@ -531,19 +531,19 @@ bool AdlEngine_v1::doOneCommand(const Commands &commands, byte verb, byte noun)
 	return false;
 }
 
-void AdlEngine_v1::doAllCommands(const Commands &commands, byte verb, byte noun) {
+void HiRes1Engine::doAllCommands(const Commands &commands, byte verb, byte noun) {
 	Commands::const_iterator it;
 
 	for (it = commands.begin(); it != commands.end(); ++it)
 		checkCommand(*it, verb, noun);
 }
 
-void AdlEngine_v1::clearScreen() {
+void HiRes1Engine::clearScreen() {
 	_display->setMode(Display::kModeMixed);
 	_display->clear(0x00);
 }
 
-void AdlEngine_v1::runGame() {
+void HiRes1Engine::runGame() {
 	runIntro();
 	_display->printASCIIString("\r");
 
@@ -673,8 +673,8 @@ void AdlEngine_v1::runGame() {
 	}
 }
 
-AdlEngine *AdlEngine_v1__create(OSystem *syst, const AdlGameDescription *gd) {
-	return new AdlEngine_v1(syst, gd);
+AdlEngine *HiRes1Engine__create(OSystem *syst, const AdlGameDescription *gd) {
+	return new HiRes1Engine(syst, gd);
 }
 
 } // End of namespace Adl
diff --git a/engines/adl/adl_v1.h b/engines/adl/adl_v1.h
index c1e28bc..e9e274c 100644
--- a/engines/adl/adl_v1.h
+++ b/engines/adl/adl_v1.h
@@ -42,9 +42,9 @@ enum {
 	STR_MH_TOTAL
 };
 
-class AdlEngine_v1 : public AdlEngine {
+class HiRes1Engine : public AdlEngine {
 public:
-	AdlEngine_v1(OSystem *syst, const AdlGameDescription *gd);
+	HiRes1Engine(OSystem *syst, const AdlGameDescription *gd);
 	Common::String getExeString(uint idx);
 
 protected:


Commit: 1e17a23879c6e81a09e2ad80d0ae7a1c0cc10732
    https://github.com/scummvm/scummvm/commit/1e17a23879c6e81a09e2ad80d0ae7a1c0cc10732
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Rename adl_v1.cpp/h to hires1.cpp/h

Changed paths:
  A engines/adl/hires1.cpp
  A engines/adl/hires1.h
  R engines/adl/adl_v1.cpp
  R engines/adl/adl_v1.h
    engines/adl/module.mk



diff --git a/engines/adl/adl_v1.cpp b/engines/adl/adl_v1.cpp
deleted file mode 100644
index 566a467..0000000
--- a/engines/adl/adl_v1.cpp
+++ /dev/null
@@ -1,680 +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/scummsys.h"
-
-#include "common/config-manager.h"
-#include "common/debug.h"
-#include "common/debug-channels.h"
-#include "common/error.h"
-#include "common/file.h"
-#include "common/fs.h"
-#include "common/system.h"
-#include "common/events.h"
-#include "common/stream.h"
-#include "graphics/palette.h"
-
-#include "engines/util.h"
-
-#include "adl/adl_v1.h"
-#include "adl/display.h"
-#include "adl/parser.h"
-
-namespace Adl {
-
-static uint exeStrings[STR_MH_TOTAL] = {
-	23484, 23375, 23438, 27658, 0x6c31, 27729, 27772, 0x5f1e
-};
-
-HiRes1Engine::HiRes1Engine(OSystem *syst, const AdlGameDescription *gd) :
-		AdlEngine(syst, gd) {
-	_variables.resize(20);
-}
-
-void HiRes1Engine::runIntro() {
-	Common::File file;
-
-	if (!file.open("AUTO LOAD OBJ"))
-		error("Failed to open file");
-
-	file.seek(0x1003);
-	_display->setMode(Display::kModeHires);
-	_display->loadFrameBuffer(file);
-	_display->decodeFrameBuffer();
-	_display->delay(4000);
-
-	if (shouldQuit())
-		return;
-
-	_display->setMode(Display::kModeText);
-
-	Common::File basic;
-	if (!basic.open("MYSTERY.HELLO"))
-		error("Failed to open file");
-
-	Common::String str;
-
-	basic.seek(93);
-	str = readString(basic, '"');
-	_display->printASCIIString(str + '\r');
-
-	basic.seek(299);
-	str = readString(basic, '"');
-	_display->printASCIIString(str + "\r\r");
-
-	basic.seek(365);
-	str = readString(basic, '"');
-	_display->printASCIIString(str + "\r\r");
-
-	basic.seek(601);
-	str = readString(basic, '"');
-	_display->printASCIIString(str + '\r');
-
-	_display->inputKey();
-	if (g_engine->shouldQuit())
-		return;
-
-	_display->setMode(Display::kModeMixed);
-
-	file.seek(15);
-	str = readString(file);
-
-	while (1) {
-		_display->printString(str);
-		Common::String s = _display->inputString();
-
-		if (g_engine->shouldQuit())
-			break;
-
-		if (s.empty())
-			continue;
-
-		if ((byte)s[0] == ('I' | 0x80))
-			break;
-		else if ((byte)s[0] == ('G' | 0x80))
-			return;
-	};
-
-	_display->setMode(Display::kModeText);
-	file.seek(102);
-
-	const int pages[] = { 6, 6, 4, 5, 8, 7, 0 };
-
-	int page = 0;
-	while (pages[page] != 0) {
-		_display->home();
-		printStrings(file, pages[page++]);
-		_display->inputString();
-
-		if (g_engine->shouldQuit())
-			return;
-
-		file.seek(9, SEEK_CUR);
-	}
-}
-
-void HiRes1Engine::drawPic(Common::ReadStream &stream, byte xOffset, byte yOffset) {
-	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 += xOffset;
-		y += yOffset;
-
-		if (y > 160)
-			y = 160;
-
-		if (bNewLine) {
-			_display->drawPixel(x, y, 0x7f);
-			bNewLine = false;
-		} else {
-			_display->drawLine(Common::Point(oldX, oldY), Common::Point(x, y), 0x7f);
-		}
-
-		oldX = x;
-		oldY = y;
-	}
-}
-
-void HiRes1Engine::drawPic(byte pic, byte xOffset, byte yOffset) {
-	Common::File f;
-	Common::String name = Common::String::format("BLOCK%i", _pictures[pic].block);
-
-	if (!f.open(name))
-		error("Failed to open file");
-
-	f.seek(_pictures[pic].offset);
-	drawPic(f, xOffset, yOffset);
-}
-
-void HiRes1Engine::drawItems() {
-	Common::Array<Item>::const_iterator it;
-
-	uint dropped = 0;
-
-	for (it = _inventory.begin(); it != _inventory.end(); ++it) {
-		if (it->field2 != _room)
-			continue;
-
-		if (it->field7 == 1) {
-			if (_rooms[_room].field8 == _rooms[_room].picture) {
-				const Common::Point &p =  _itemOffsets[dropped];
-				if (it->field4)
-					_display->drawRightAngles(_drawings[it->field3 - 1], Common::Point(p.x, p.y), 0, 1, 0x7f);
-				else
-					drawPic(it->field3, p.x, p.y);
-				++dropped;
-			}
-			continue;
-		}
-
-		Common::Array<byte>::const_iterator it2;
-
-		for (it2 = it->field10.begin(); it2 != it->field10.end(); ++it2) {
-			if (*it2 == _rooms[_room].picture) {
-				if (it->field4)
-					_display->drawRightAngles(_drawings[it->field3 - 1], Common::Point(it->field5, it->field6), 0, 1, 0x7f);
-				else
-					drawPic(it->field3, it->field5, it->field6);
-				continue;
-			}
-		}
-	}
-}
-
-void HiRes1Engine::showRoom() {
-	if (!_isDark) {
-		drawPic(_rooms[_room].picture, 0, 0);
-		drawItems();
-	}
-
-	_display->decodeFrameBuffer();
-	printMessage(_rooms[_room].description, false);
-}
-
-Common::String HiRes1Engine::getExeString(uint idx) {
-	return _exeStrings[idx];
-}
-
-void HiRes1Engine::wordWrap(Common::String &str) {
-	uint end = 39;
-
-	while (1) {
-		if (str.size() <= end)
-			return;
-
-		while (str[end] != APPLECHAR(' '))
-			--end;
-
-		str.setChar(APPLECHAR('\r'), end);
-		end += 40;
-	}
-}
-
-void HiRes1Engine::printMessage(uint idx, bool wait) {
-	// Hardcoded overrides that don't wait after printing
-	// Note: strings may differ slightly from the ones in MESSAGES
-	switch (idx) {
-	case 137:
-		_display->printString(_exeStrings[STR_MH_DIRERR]);
-		return;
-	case 127:
-		_display->printString(_exeStrings[STR_MH_DONTHAVEIT]);
-		return;
-	case 37:
-		_display->printString(_exeStrings[STR_MH_DONTUNDERSTAND]);
-		return;
-	case 7:
-		_display->printString(_exeStrings[STR_MH_GETTINGDARK]);
-		return;
-	}
-
-	Common::String msg = _msgStrings[idx - 1];
-	wordWrap(msg);
-	_display->printString(msg);
-
-	if (wait)
-		_display->delay(14 * 166018 / 1000);
-}
-
-void HiRes1Engine::readCommands(Common::ReadStream &stream, Commands &commands) {
-	while (1) {
-		Command command;
-		command.room = stream.readByte();
-
-		if (command.room == 0xff)
-			return;
-
-		command.verb = stream.readByte();
-		command.noun = stream.readByte();
-
-		byte scriptSize = stream.readByte() - 6;
-
-		command.numCond = stream.readByte();
-		command.numAct = stream.readByte();
-
-		for (uint i = 0; i < scriptSize; ++i)
-			command.script.push_back(stream.readByte());
-
-		if (stream.eos() || stream.err())
-			error("Failed to read commands");
-
-		commands.push_back(command);
-	}
-}
-
-void HiRes1Engine::takeItem(byte noun) {
-	Common::Array<Item>::iterator it;
-
-	for (it = _inventory.begin(); it != _inventory.end(); ++it) {
-		if (it->field1 != noun || it->field2 != _room)
-			continue;
-
-		if (it->field7 == 2) {
-			// It doesn't move
-			printMessage(151);
-			return;
-		}
-
-		if (it->field7 == 1) {
-			it->field2 = 0xfe;
-			it->field7 = 1;
-			return;
-		}
-
-		Common::Array<byte>::const_iterator it2;
-		for (it2 = it->field10.begin(); it->field10.end(); ++it2) {
-			if (*it2 == _rooms[_room].picture) {
-				it->field2 = 0xfe;
-				it->field7 = 1;
-				return;
-			}
-		}
-	}
-
-	// Item not here
-	printMessage(152);
-}
-
-void HiRes1Engine::dropItem(byte noun) {
-	Common::Array<Item>::iterator it;
-
-	for (it = _inventory.begin(); it != _inventory.end(); ++it) {
-		if (it->field1 != noun || it->field2 != 0xfe)
-			continue;
-
-		it->field2 = _room;
-		it->field7 = 1;
-		return;
-	}
-
-	// Don't understand
-	printMessage(37);
-}
-
-void HiRes1Engine::doActions(const Command &command, byte noun, byte offset) {
-	for (uint i = 0; i < command.numAct; ++i) {
-		switch (command.script[offset]) {
-		case 1:
-			_variables[command.script[offset + 2]] += command.script[offset + 1];
-			offset += 3;
-			break;
-		case 2:
-			_variables[command.script[offset + 2]] -= command.script[offset + 1];
-			offset += 3;
-			break;
-		case 3:
-			_variables[command.script[offset + 1]] = command.script[offset + 2];
-			offset += 3;
-			break;
-		case 4: {
-			Common::Array<Item>::const_iterator it;
-
-			for (it = _inventory.begin(); it != _inventory.end(); ++it)
-				if (it->field2 == 0xfe)
-					printMessage(it->field8);
-
-			++offset;
-			break;
-		}
-		case 5:
-			_inventory[command.script[offset + 1] - 1].field2 = command.script[offset + 2];
-			offset += 3;
-			break;
-		case 6:
-			_rooms[_room].picture = _rooms[_room].field8;
-			_room = command.script[offset + 1];
-			offset += 2;
-			break;
-		case 7:
-			_rooms[_room].picture = command.script[offset + 1];
-			offset += 2;
-			break;
-		case 8:
-			_rooms[_room].field8 = _rooms[_room].picture = command.script[offset + 1];
-			offset += 2;
-			break;
-		case 9:
-			printMessage(command.script[offset + 1]);
-			offset += 2;
-			break;
-		case 0xa:
-			_isDark = false;
-			++offset;
-			break;
-		case 0xb:
-			_isDark = true;
-			++offset;
-			break;
-		case 0xf:
-			warning("Save game not implemented");
-			++offset;
-			break;
-		case 0x10:
-			warning("Load game not implemented");
-			++offset;
-			break;
-		case 0x11: {
-			_display->printString(_exeStrings[STR_MH_PLAYAGAIN]);
-			Common::String input = _display->inputString();
-			if (input.size() == 0 || input[0] != APPLECHAR('N')) {
-				warning("Restart game not implemented");
-				return;
-			}
-			// Fall-through
-		}
-		case 0xd:
-			printMessage(140);
-			quitGame();
-			return;
-		case 0x12: {
-			byte item = command.script[offset + 1] - 1;
-			_inventory[item].field2 = command.script[offset + 2];
-			_inventory[item].field5 = command.script[offset + 3];
-			_inventory[item].field6 = command.script[offset + 4];
-			offset += 5;
-			break;
-		}
-		case 0x13: {
-			byte item = command.script[offset + 2] - 1;
-			_inventory[item].field3 = command.script[offset + 1];
-			offset += 3;
-			break;
-		}
-		case 0x14:
-			_rooms[_room].picture = _rooms[_room].field8;
-			++offset;
-			break;
-		case 0x15:
-		case 0x16:
-		case 0x17:
-		case 0x18:
-		case 0x19:
-		case 0x1a: {
-			byte room = _rooms[_room].connections[command.script[offset] - 0x15];
-
-			if (room == 0) {
-				printMessage(137);
-				return;
-			}
-
-			_rooms[_room].picture = _rooms[_room].field8;
-			_room = room;
-			return;
-		}
-		case 0x1b:
-			takeItem(noun);
-			++offset;
-			break;
-		case 0x1c:
-			dropItem(noun);
-			++offset;
-			break;
-		case 0x1d:
-			_rooms[command.script[offset + 1]].field8 = _rooms[command.script[offset + 1]].picture = command.script[offset + 2];
-			offset += 3;
-			break;
-		default:
-			error("Invalid action opcode %02x", command.script[offset]);
-		}
-	}
-}
-
-bool HiRes1Engine::checkCommand(const Command &command, byte verb, byte noun) {
-	if (command.room != 0xfe && command.room != _room)
-		return false;
-
-	if (command.verb != 0xfe && command.verb != verb)
-		return false;
-
-	if (command.noun != 0xfe && command.noun != noun)
-		return false;
-
-	uint offset = 0;
-	for (uint i = 0; i < command.numCond; ++i) {
-		switch (command.script[offset]) {
-		case 3:
-			if (_inventory[command.script[offset + 1] - 1].field2 != command.script[offset + 2])
-				return false;
-			offset += 3;
-			break;
-		case 5:
-			if (command.script[offset + 1] > _steps)
-				return false;
-			offset += 2;
-			break;
-		case 6:
-			if (_variables[command.script[offset + 1]] != command.script[offset + 2])
-				return false;
-			offset += 3;
-			break;
-		case 9:
-			if (_rooms[_room].picture != command.script[offset + 1])
-				return false;
-			offset += 2;
-			break;
-		case 10:
-			if (_inventory[command.script[offset + 1] - 1].field3 != command.script[offset + 2])
-				return false;
-			offset += 3;
-			break;
-		default:
-			error("Invalid condition opcode %02x", command.script[offset]);
-		}
-	}
-
-	doActions(command, noun, offset);
-
-	return true;
-}
-
-bool HiRes1Engine::doOneCommand(const Commands &commands, byte verb, byte noun) {
-	Commands::const_iterator it;
-
-	for (it = commands.begin(); it != commands.end(); ++it)
-		if (checkCommand(*it, verb, noun))
-			return true;
-
-	return false;
-}
-
-void HiRes1Engine::doAllCommands(const Commands &commands, byte verb, byte noun) {
-	Commands::const_iterator it;
-
-	for (it = commands.begin(); it != commands.end(); ++it)
-		checkCommand(*it, verb, noun);
-}
-
-void HiRes1Engine::clearScreen() {
-	_display->setMode(Display::kModeMixed);
-	_display->clear(0x00);
-}
-
-void HiRes1Engine::runGame() {
-	runIntro();
-	_display->printASCIIString("\r");
-
-	Common::File f;
-
-	if (!f.open("MESSAGES"))
-		error("Failed to open file");
-
-	while (!f.eos() && !f.err())
-		_msgStrings.push_back(readString(f, APPLECHAR('\r')) + APPLECHAR('\r'));
-
-	f.close();
-
-	if (!f.open("ADVENTURE"))
-		error("Failed to open file");
-
-	// Load strings from executable
-	for (uint idx = 0; idx < STR_MH_TOTAL; ++idx) {
-		f.seek(exeStrings[idx]);
-		_exeStrings.push_back(readString(f));
-	}
-
-	// Load room data from executable
-	f.seek(1280);
-	for (uint i = 0; i < MH_ROOMS; ++i) {
-		struct Room room;
-		f.readByte();
-		room.description = f.readByte();
-		for (uint j = 0; j < 6; ++j)
-			room.connections[j] = f.readByte();
-		room.field8 = f.readByte();
-		room.picture = f.readByte();
-		_rooms.push_back(room);
-	}
-
-	// Load inventory data from executable
-	f.seek(0x100);
-	while (f.readByte() != 0xff) {
-		struct Item item;
-		item.field1 = f.readByte();
-		item.field2 = f.readByte();
-		item.field3 = f.readByte();
-		item.field4 = f.readByte();
-		item.field5 = f.readByte();
-		item.field6 = f.readByte();
-		item.field7 = f.readByte();
-		item.field8 = f.readByte();
-
-		f.readByte();
-
-		byte size = f.readByte();
-
-		for (uint i = 0; i < size; ++i)
-			item.field10.push_back(f.readByte());
-
-		_inventory.push_back(item);
-	}
-
-	// Load picture data from executable
-	f.seek(0x4b00);
-	for (uint i = 0; i < MH_PICS; ++i) {
-		struct Picture pic;
-		pic.block = f.readByte();
-		pic.offset = f.readUint16LE();
-		_pictures.push_back(pic);
-	}
-
-	// Load commands from executable
-	f.seek(0x3D00);
-	readCommands(f, _roomCommands);
-
-	f.seek(0x3C00);
-	readCommands(f, _globalCommands);
-
-	// Load dropped item offsets
-	f.seek(0x68ff);
-	for (uint i = 0; i < MH_ITEM_OFFSETS; ++i) {
-		Common::Point p;
-		p.x = f.readByte();
-		p.y = f.readByte();
-		_itemOffsets.push_back(p);
-	}
-
-	// Load right-angle drawings
-	f.seek(0x4f00);
-	uint16 drawingsTotal = f.readUint16LE();
-	for (uint i = 0; i < drawingsTotal; ++i) {
-		f.seek(0x4f00 + 2 + i * 2);
-		uint16 offset = f.readUint16LE();
-		f.seek(0x4f00 + offset);
-
-		Common::Array<byte> drawing;
-		byte b = f.readByte();
-		while (b != 0) {
-			drawing.push_back(b);
-			b = f.readByte();
-		}
-		_drawings.push_back(drawing);
-	}
-
-	// Title screen shown during loading
-	f.seek(0x1800);
-	_display->loadFrameBuffer(f);
-	_display->decodeFrameBuffer();
-	_display->delay(2000);
-
-	f.seek(0x3800);
-	_parser->loadVerbs(f);
-
-	f.seek(0xf00);
-	_parser->loadNouns(f);
-
-	while (1) {
-		uint verb = 0, noun = 0;
-		clearScreen();
-		showRoom();
-		_parser->getInput(verb, noun);
-
-		if (!doOneCommand(_roomCommands, verb, noun))
-			printMessage(37);
-		doAllCommands(_globalCommands, verb, noun);
-
-		_steps++;
-
-		if (shouldQuit())
-			return;
-	}
-}
-
-AdlEngine *HiRes1Engine__create(OSystem *syst, const AdlGameDescription *gd) {
-	return new HiRes1Engine(syst, gd);
-}
-
-} // End of namespace Adl
diff --git a/engines/adl/adl_v1.h b/engines/adl/adl_v1.h
deleted file mode 100644
index e9e274c..0000000
--- a/engines/adl/adl_v1.h
+++ /dev/null
@@ -1,81 +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_ADL_V1_H
-#define ADL_ADL_V1_H
-
-#include "adl/adl.h"
-
-namespace Common {
-class ReadStream;
-}
-
-namespace Adl {
-
-enum {
-	// Some of these are probably common
-	STR_MH_DIRERR = STR_CUSTOM_START,
-	STR_MH_DONTHAVEIT,
-	STR_MH_DONTUNDERSTAND,
-	STR_MH_GETTINGDARK,
-	STR_MH_PLAYAGAIN,
-
-	STR_MH_TOTAL
-};
-
-class HiRes1Engine : public AdlEngine {
-public:
-	HiRes1Engine(OSystem *syst, const AdlGameDescription *gd);
-	Common::String getExeString(uint idx);
-
-protected:
-	void runGame();
-
-private:
-	enum {
-		MH_ROOMS = 42,
-		MH_PICS = 98,
-		MH_ITEM_OFFSETS = 21
-	};
-
-	void runIntro();
-	void drawPic(Common::ReadStream &stream, byte xOffset, byte yOffset);
-	void showRoom();
-	void printMessage(uint idx, bool wait = true);
-	void wordWrap(Common::String &str);
-	void readCommands(Common::ReadStream &stream, Commands &commands);
-	bool checkCommand(const Command &command, byte verb, byte noun);
-	bool doOneCommand(const Commands &commands, byte verb, byte noun);
-	void doAllCommands(const Commands &commands, byte verb, byte noun);
-	void doActions(const Command &command, byte noun, byte offset);
-	void clearScreen();
-	void takeItem(byte noun);
-	void dropItem(byte noun);
-	void drawItems();
-	void drawPic(byte pic, byte xOffset, byte yOffset);
-
-	Common::Array<Common::String> _exeStrings;
-};
-
-} // End of namespace Adl
-
-#endif
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
new file mode 100644
index 0000000..28aa135
--- /dev/null
+++ b/engines/adl/hires1.cpp
@@ -0,0 +1,680 @@
+/* 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/scummsys.h"
+
+#include "common/config-manager.h"
+#include "common/debug.h"
+#include "common/debug-channels.h"
+#include "common/error.h"
+#include "common/file.h"
+#include "common/fs.h"
+#include "common/system.h"
+#include "common/events.h"
+#include "common/stream.h"
+#include "graphics/palette.h"
+
+#include "engines/util.h"
+
+#include "adl/hires1.h"
+#include "adl/display.h"
+#include "adl/parser.h"
+
+namespace Adl {
+
+static uint exeStrings[STR_MH_TOTAL] = {
+	23484, 23375, 23438, 27658, 0x6c31, 27729, 27772, 0x5f1e
+};
+
+HiRes1Engine::HiRes1Engine(OSystem *syst, const AdlGameDescription *gd) :
+		AdlEngine(syst, gd) {
+	_variables.resize(20);
+}
+
+void HiRes1Engine::runIntro() {
+	Common::File file;
+
+	if (!file.open("AUTO LOAD OBJ"))
+		error("Failed to open file");
+
+	file.seek(0x1003);
+	_display->setMode(Display::kModeHires);
+	_display->loadFrameBuffer(file);
+	_display->decodeFrameBuffer();
+	_display->delay(4000);
+
+	if (shouldQuit())
+		return;
+
+	_display->setMode(Display::kModeText);
+
+	Common::File basic;
+	if (!basic.open("MYSTERY.HELLO"))
+		error("Failed to open file");
+
+	Common::String str;
+
+	basic.seek(93);
+	str = readString(basic, '"');
+	_display->printASCIIString(str + '\r');
+
+	basic.seek(299);
+	str = readString(basic, '"');
+	_display->printASCIIString(str + "\r\r");
+
+	basic.seek(365);
+	str = readString(basic, '"');
+	_display->printASCIIString(str + "\r\r");
+
+	basic.seek(601);
+	str = readString(basic, '"');
+	_display->printASCIIString(str + '\r');
+
+	_display->inputKey();
+	if (g_engine->shouldQuit())
+		return;
+
+	_display->setMode(Display::kModeMixed);
+
+	file.seek(15);
+	str = readString(file);
+
+	while (1) {
+		_display->printString(str);
+		Common::String s = _display->inputString();
+
+		if (g_engine->shouldQuit())
+			break;
+
+		if (s.empty())
+			continue;
+
+		if ((byte)s[0] == ('I' | 0x80))
+			break;
+		else if ((byte)s[0] == ('G' | 0x80))
+			return;
+	};
+
+	_display->setMode(Display::kModeText);
+	file.seek(102);
+
+	const int pages[] = { 6, 6, 4, 5, 8, 7, 0 };
+
+	int page = 0;
+	while (pages[page] != 0) {
+		_display->home();
+		printStrings(file, pages[page++]);
+		_display->inputString();
+
+		if (g_engine->shouldQuit())
+			return;
+
+		file.seek(9, SEEK_CUR);
+	}
+}
+
+void HiRes1Engine::drawPic(Common::ReadStream &stream, byte xOffset, byte yOffset) {
+	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 += xOffset;
+		y += yOffset;
+
+		if (y > 160)
+			y = 160;
+
+		if (bNewLine) {
+			_display->drawPixel(x, y, 0x7f);
+			bNewLine = false;
+		} else {
+			_display->drawLine(Common::Point(oldX, oldY), Common::Point(x, y), 0x7f);
+		}
+
+		oldX = x;
+		oldY = y;
+	}
+}
+
+void HiRes1Engine::drawPic(byte pic, byte xOffset, byte yOffset) {
+	Common::File f;
+	Common::String name = Common::String::format("BLOCK%i", _pictures[pic].block);
+
+	if (!f.open(name))
+		error("Failed to open file");
+
+	f.seek(_pictures[pic].offset);
+	drawPic(f, xOffset, yOffset);
+}
+
+void HiRes1Engine::drawItems() {
+	Common::Array<Item>::const_iterator it;
+
+	uint dropped = 0;
+
+	for (it = _inventory.begin(); it != _inventory.end(); ++it) {
+		if (it->field2 != _room)
+			continue;
+
+		if (it->field7 == 1) {
+			if (_rooms[_room].field8 == _rooms[_room].picture) {
+				const Common::Point &p =  _itemOffsets[dropped];
+				if (it->field4)
+					_display->drawRightAngles(_drawings[it->field3 - 1], Common::Point(p.x, p.y), 0, 1, 0x7f);
+				else
+					drawPic(it->field3, p.x, p.y);
+				++dropped;
+			}
+			continue;
+		}
+
+		Common::Array<byte>::const_iterator it2;
+
+		for (it2 = it->field10.begin(); it2 != it->field10.end(); ++it2) {
+			if (*it2 == _rooms[_room].picture) {
+				if (it->field4)
+					_display->drawRightAngles(_drawings[it->field3 - 1], Common::Point(it->field5, it->field6), 0, 1, 0x7f);
+				else
+					drawPic(it->field3, it->field5, it->field6);
+				continue;
+			}
+		}
+	}
+}
+
+void HiRes1Engine::showRoom() {
+	if (!_isDark) {
+		drawPic(_rooms[_room].picture, 0, 0);
+		drawItems();
+	}
+
+	_display->decodeFrameBuffer();
+	printMessage(_rooms[_room].description, false);
+}
+
+Common::String HiRes1Engine::getExeString(uint idx) {
+	return _exeStrings[idx];
+}
+
+void HiRes1Engine::wordWrap(Common::String &str) {
+	uint end = 39;
+
+	while (1) {
+		if (str.size() <= end)
+			return;
+
+		while (str[end] != APPLECHAR(' '))
+			--end;
+
+		str.setChar(APPLECHAR('\r'), end);
+		end += 40;
+	}
+}
+
+void HiRes1Engine::printMessage(uint idx, bool wait) {
+	// Hardcoded overrides that don't wait after printing
+	// Note: strings may differ slightly from the ones in MESSAGES
+	switch (idx) {
+	case 137:
+		_display->printString(_exeStrings[STR_MH_DIRERR]);
+		return;
+	case 127:
+		_display->printString(_exeStrings[STR_MH_DONTHAVEIT]);
+		return;
+	case 37:
+		_display->printString(_exeStrings[STR_MH_DONTUNDERSTAND]);
+		return;
+	case 7:
+		_display->printString(_exeStrings[STR_MH_GETTINGDARK]);
+		return;
+	}
+
+	Common::String msg = _msgStrings[idx - 1];
+	wordWrap(msg);
+	_display->printString(msg);
+
+	if (wait)
+		_display->delay(14 * 166018 / 1000);
+}
+
+void HiRes1Engine::readCommands(Common::ReadStream &stream, Commands &commands) {
+	while (1) {
+		Command command;
+		command.room = stream.readByte();
+
+		if (command.room == 0xff)
+			return;
+
+		command.verb = stream.readByte();
+		command.noun = stream.readByte();
+
+		byte scriptSize = stream.readByte() - 6;
+
+		command.numCond = stream.readByte();
+		command.numAct = stream.readByte();
+
+		for (uint i = 0; i < scriptSize; ++i)
+			command.script.push_back(stream.readByte());
+
+		if (stream.eos() || stream.err())
+			error("Failed to read commands");
+
+		commands.push_back(command);
+	}
+}
+
+void HiRes1Engine::takeItem(byte noun) {
+	Common::Array<Item>::iterator it;
+
+	for (it = _inventory.begin(); it != _inventory.end(); ++it) {
+		if (it->field1 != noun || it->field2 != _room)
+			continue;
+
+		if (it->field7 == 2) {
+			// It doesn't move
+			printMessage(151);
+			return;
+		}
+
+		if (it->field7 == 1) {
+			it->field2 = 0xfe;
+			it->field7 = 1;
+			return;
+		}
+
+		Common::Array<byte>::const_iterator it2;
+		for (it2 = it->field10.begin(); it->field10.end(); ++it2) {
+			if (*it2 == _rooms[_room].picture) {
+				it->field2 = 0xfe;
+				it->field7 = 1;
+				return;
+			}
+		}
+	}
+
+	// Item not here
+	printMessage(152);
+}
+
+void HiRes1Engine::dropItem(byte noun) {
+	Common::Array<Item>::iterator it;
+
+	for (it = _inventory.begin(); it != _inventory.end(); ++it) {
+		if (it->field1 != noun || it->field2 != 0xfe)
+			continue;
+
+		it->field2 = _room;
+		it->field7 = 1;
+		return;
+	}
+
+	// Don't understand
+	printMessage(37);
+}
+
+void HiRes1Engine::doActions(const Command &command, byte noun, byte offset) {
+	for (uint i = 0; i < command.numAct; ++i) {
+		switch (command.script[offset]) {
+		case 1:
+			_variables[command.script[offset + 2]] += command.script[offset + 1];
+			offset += 3;
+			break;
+		case 2:
+			_variables[command.script[offset + 2]] -= command.script[offset + 1];
+			offset += 3;
+			break;
+		case 3:
+			_variables[command.script[offset + 1]] = command.script[offset + 2];
+			offset += 3;
+			break;
+		case 4: {
+			Common::Array<Item>::const_iterator it;
+
+			for (it = _inventory.begin(); it != _inventory.end(); ++it)
+				if (it->field2 == 0xfe)
+					printMessage(it->field8);
+
+			++offset;
+			break;
+		}
+		case 5:
+			_inventory[command.script[offset + 1] - 1].field2 = command.script[offset + 2];
+			offset += 3;
+			break;
+		case 6:
+			_rooms[_room].picture = _rooms[_room].field8;
+			_room = command.script[offset + 1];
+			offset += 2;
+			break;
+		case 7:
+			_rooms[_room].picture = command.script[offset + 1];
+			offset += 2;
+			break;
+		case 8:
+			_rooms[_room].field8 = _rooms[_room].picture = command.script[offset + 1];
+			offset += 2;
+			break;
+		case 9:
+			printMessage(command.script[offset + 1]);
+			offset += 2;
+			break;
+		case 0xa:
+			_isDark = false;
+			++offset;
+			break;
+		case 0xb:
+			_isDark = true;
+			++offset;
+			break;
+		case 0xf:
+			warning("Save game not implemented");
+			++offset;
+			break;
+		case 0x10:
+			warning("Load game not implemented");
+			++offset;
+			break;
+		case 0x11: {
+			_display->printString(_exeStrings[STR_MH_PLAYAGAIN]);
+			Common::String input = _display->inputString();
+			if (input.size() == 0 || input[0] != APPLECHAR('N')) {
+				warning("Restart game not implemented");
+				return;
+			}
+			// Fall-through
+		}
+		case 0xd:
+			printMessage(140);
+			quitGame();
+			return;
+		case 0x12: {
+			byte item = command.script[offset + 1] - 1;
+			_inventory[item].field2 = command.script[offset + 2];
+			_inventory[item].field5 = command.script[offset + 3];
+			_inventory[item].field6 = command.script[offset + 4];
+			offset += 5;
+			break;
+		}
+		case 0x13: {
+			byte item = command.script[offset + 2] - 1;
+			_inventory[item].field3 = command.script[offset + 1];
+			offset += 3;
+			break;
+		}
+		case 0x14:
+			_rooms[_room].picture = _rooms[_room].field8;
+			++offset;
+			break;
+		case 0x15:
+		case 0x16:
+		case 0x17:
+		case 0x18:
+		case 0x19:
+		case 0x1a: {
+			byte room = _rooms[_room].connections[command.script[offset] - 0x15];
+
+			if (room == 0) {
+				printMessage(137);
+				return;
+			}
+
+			_rooms[_room].picture = _rooms[_room].field8;
+			_room = room;
+			return;
+		}
+		case 0x1b:
+			takeItem(noun);
+			++offset;
+			break;
+		case 0x1c:
+			dropItem(noun);
+			++offset;
+			break;
+		case 0x1d:
+			_rooms[command.script[offset + 1]].field8 = _rooms[command.script[offset + 1]].picture = command.script[offset + 2];
+			offset += 3;
+			break;
+		default:
+			error("Invalid action opcode %02x", command.script[offset]);
+		}
+	}
+}
+
+bool HiRes1Engine::checkCommand(const Command &command, byte verb, byte noun) {
+	if (command.room != 0xfe && command.room != _room)
+		return false;
+
+	if (command.verb != 0xfe && command.verb != verb)
+		return false;
+
+	if (command.noun != 0xfe && command.noun != noun)
+		return false;
+
+	uint offset = 0;
+	for (uint i = 0; i < command.numCond; ++i) {
+		switch (command.script[offset]) {
+		case 3:
+			if (_inventory[command.script[offset + 1] - 1].field2 != command.script[offset + 2])
+				return false;
+			offset += 3;
+			break;
+		case 5:
+			if (command.script[offset + 1] > _steps)
+				return false;
+			offset += 2;
+			break;
+		case 6:
+			if (_variables[command.script[offset + 1]] != command.script[offset + 2])
+				return false;
+			offset += 3;
+			break;
+		case 9:
+			if (_rooms[_room].picture != command.script[offset + 1])
+				return false;
+			offset += 2;
+			break;
+		case 10:
+			if (_inventory[command.script[offset + 1] - 1].field3 != command.script[offset + 2])
+				return false;
+			offset += 3;
+			break;
+		default:
+			error("Invalid condition opcode %02x", command.script[offset]);
+		}
+	}
+
+	doActions(command, noun, offset);
+
+	return true;
+}
+
+bool HiRes1Engine::doOneCommand(const Commands &commands, byte verb, byte noun) {
+	Commands::const_iterator it;
+
+	for (it = commands.begin(); it != commands.end(); ++it)
+		if (checkCommand(*it, verb, noun))
+			return true;
+
+	return false;
+}
+
+void HiRes1Engine::doAllCommands(const Commands &commands, byte verb, byte noun) {
+	Commands::const_iterator it;
+
+	for (it = commands.begin(); it != commands.end(); ++it)
+		checkCommand(*it, verb, noun);
+}
+
+void HiRes1Engine::clearScreen() {
+	_display->setMode(Display::kModeMixed);
+	_display->clear(0x00);
+}
+
+void HiRes1Engine::runGame() {
+	runIntro();
+	_display->printASCIIString("\r");
+
+	Common::File f;
+
+	if (!f.open("MESSAGES"))
+		error("Failed to open file");
+
+	while (!f.eos() && !f.err())
+		_msgStrings.push_back(readString(f, APPLECHAR('\r')) + APPLECHAR('\r'));
+
+	f.close();
+
+	if (!f.open("ADVENTURE"))
+		error("Failed to open file");
+
+	// Load strings from executable
+	for (uint idx = 0; idx < STR_MH_TOTAL; ++idx) {
+		f.seek(exeStrings[idx]);
+		_exeStrings.push_back(readString(f));
+	}
+
+	// Load room data from executable
+	f.seek(1280);
+	for (uint i = 0; i < MH_ROOMS; ++i) {
+		struct Room room;
+		f.readByte();
+		room.description = f.readByte();
+		for (uint j = 0; j < 6; ++j)
+			room.connections[j] = f.readByte();
+		room.field8 = f.readByte();
+		room.picture = f.readByte();
+		_rooms.push_back(room);
+	}
+
+	// Load inventory data from executable
+	f.seek(0x100);
+	while (f.readByte() != 0xff) {
+		struct Item item;
+		item.field1 = f.readByte();
+		item.field2 = f.readByte();
+		item.field3 = f.readByte();
+		item.field4 = f.readByte();
+		item.field5 = f.readByte();
+		item.field6 = f.readByte();
+		item.field7 = f.readByte();
+		item.field8 = f.readByte();
+
+		f.readByte();
+
+		byte size = f.readByte();
+
+		for (uint i = 0; i < size; ++i)
+			item.field10.push_back(f.readByte());
+
+		_inventory.push_back(item);
+	}
+
+	// Load picture data from executable
+	f.seek(0x4b00);
+	for (uint i = 0; i < MH_PICS; ++i) {
+		struct Picture pic;
+		pic.block = f.readByte();
+		pic.offset = f.readUint16LE();
+		_pictures.push_back(pic);
+	}
+
+	// Load commands from executable
+	f.seek(0x3D00);
+	readCommands(f, _roomCommands);
+
+	f.seek(0x3C00);
+	readCommands(f, _globalCommands);
+
+	// Load dropped item offsets
+	f.seek(0x68ff);
+	for (uint i = 0; i < MH_ITEM_OFFSETS; ++i) {
+		Common::Point p;
+		p.x = f.readByte();
+		p.y = f.readByte();
+		_itemOffsets.push_back(p);
+	}
+
+	// Load right-angle drawings
+	f.seek(0x4f00);
+	uint16 drawingsTotal = f.readUint16LE();
+	for (uint i = 0; i < drawingsTotal; ++i) {
+		f.seek(0x4f00 + 2 + i * 2);
+		uint16 offset = f.readUint16LE();
+		f.seek(0x4f00 + offset);
+
+		Common::Array<byte> drawing;
+		byte b = f.readByte();
+		while (b != 0) {
+			drawing.push_back(b);
+			b = f.readByte();
+		}
+		_drawings.push_back(drawing);
+	}
+
+	// Title screen shown during loading
+	f.seek(0x1800);
+	_display->loadFrameBuffer(f);
+	_display->decodeFrameBuffer();
+	_display->delay(2000);
+
+	f.seek(0x3800);
+	_parser->loadVerbs(f);
+
+	f.seek(0xf00);
+	_parser->loadNouns(f);
+
+	while (1) {
+		uint verb = 0, noun = 0;
+		clearScreen();
+		showRoom();
+		_parser->getInput(verb, noun);
+
+		if (!doOneCommand(_roomCommands, verb, noun))
+			printMessage(37);
+		doAllCommands(_globalCommands, verb, noun);
+
+		_steps++;
+
+		if (shouldQuit())
+			return;
+	}
+}
+
+AdlEngine *HiRes1Engine__create(OSystem *syst, const AdlGameDescription *gd) {
+	return new HiRes1Engine(syst, gd);
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
new file mode 100644
index 0000000..e9e274c
--- /dev/null
+++ b/engines/adl/hires1.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.
+ *
+ */
+
+#ifndef ADL_ADL_V1_H
+#define ADL_ADL_V1_H
+
+#include "adl/adl.h"
+
+namespace Common {
+class ReadStream;
+}
+
+namespace Adl {
+
+enum {
+	// Some of these are probably common
+	STR_MH_DIRERR = STR_CUSTOM_START,
+	STR_MH_DONTHAVEIT,
+	STR_MH_DONTUNDERSTAND,
+	STR_MH_GETTINGDARK,
+	STR_MH_PLAYAGAIN,
+
+	STR_MH_TOTAL
+};
+
+class HiRes1Engine : public AdlEngine {
+public:
+	HiRes1Engine(OSystem *syst, const AdlGameDescription *gd);
+	Common::String getExeString(uint idx);
+
+protected:
+	void runGame();
+
+private:
+	enum {
+		MH_ROOMS = 42,
+		MH_PICS = 98,
+		MH_ITEM_OFFSETS = 21
+	};
+
+	void runIntro();
+	void drawPic(Common::ReadStream &stream, byte xOffset, byte yOffset);
+	void showRoom();
+	void printMessage(uint idx, bool wait = true);
+	void wordWrap(Common::String &str);
+	void readCommands(Common::ReadStream &stream, Commands &commands);
+	bool checkCommand(const Command &command, byte verb, byte noun);
+	bool doOneCommand(const Commands &commands, byte verb, byte noun);
+	void doAllCommands(const Commands &commands, byte verb, byte noun);
+	void doActions(const Command &command, byte noun, byte offset);
+	void clearScreen();
+	void takeItem(byte noun);
+	void dropItem(byte noun);
+	void drawItems();
+	void drawPic(byte pic, byte xOffset, byte yOffset);
+
+	Common::Array<Common::String> _exeStrings;
+};
+
+} // End of namespace Adl
+
+#endif
diff --git a/engines/adl/module.mk b/engines/adl/module.mk
index 8f86eee..012b027 100644
--- a/engines/adl/module.mk
+++ b/engines/adl/module.mk
@@ -1,10 +1,10 @@
 MODULE := engines/adl
 
 MODULE_OBJS := \
+	adl.o \
 	detection.o \
 	display.o \
-	adl.o \
-	adl_v1.o \
+	hires1.o \
 	parser.o
 
 MODULE_DIRS += \


Commit: 6a1dd071978f8ef48cb980d736877f1944a9a78f
    https://github.com/scummvm/scummvm/commit/6a1dd071978f8ef48cb980d736877f1944a9a78f
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Move more functionality into base class

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



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 3ee72e8..2c11290 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -103,6 +103,309 @@ void AdlEngine::printStrings(Common::SeekableReadStream &stream, int count) {
 	};
 }
 
+Common::String AdlEngine::getEngineString(int str) {
+	return _strings[str];
+}
+
+void AdlEngine::wordWrap(Common::String &str) {
+	uint end = 39;
+
+	while (1) {
+		if (str.size() <= end)
+			return;
+
+		while (str[end] != APPLECHAR(' '))
+			--end;
+
+		str.setChar(APPLECHAR('\r'), end);
+		end += 40;
+	}
+}
+
+void AdlEngine::printMessage(uint idx, bool wait) {
+	Common::String msg = _messages[idx - 1];
+	wordWrap(msg);
+	_display->printString(msg);
+
+	if (wait)
+		_display->delay(14 * 166018 / 1000);
+}
+
+void AdlEngine::printEngineMessage(EngineMessage msg) {
+	printMessage(getEngineMessage(msg));
+}
+
+void AdlEngine::readCommands(Common::ReadStream &stream, Commands &commands) {
+	while (1) {
+		Command command;
+		command.room = stream.readByte();
+
+		if (command.room == 0xff)
+			return;
+
+		command.verb = stream.readByte();
+		command.noun = stream.readByte();
+
+		byte scriptSize = stream.readByte() - 6;
+
+		command.numCond = stream.readByte();
+		command.numAct = stream.readByte();
+
+		for (uint i = 0; i < scriptSize; ++i)
+			command.script.push_back(stream.readByte());
+
+		if (stream.eos() || stream.err())
+			error("Failed to read commands");
+
+		commands.push_back(command);
+	}
+}
+
+void AdlEngine::takeItem(byte noun) {
+	Common::Array<Item>::iterator it;
+
+	for (it = _inventory.begin(); it != _inventory.end(); ++it) {
+		if (it->field1 != noun || it->field2 != _room)
+			continue;
+
+		if (it->field7 == 2) {
+			printEngineMessage(IDI_MSG_ITEM_DOESNT_MOVE);
+			return;
+		}
+
+		if (it->field7 == 1) {
+			it->field2 = 0xfe;
+			it->field7 = 1;
+			return;
+		}
+
+		Common::Array<byte>::const_iterator it2;
+		for (it2 = it->field10.begin(); it->field10.end(); ++it2) {
+			if (*it2 == _rooms[_room].picture) {
+				it->field2 = 0xfe;
+				it->field7 = 1;
+				return;
+			}
+		}
+	}
+
+	printEngineMessage(IDI_MSG_ITEM_NOT_HERE);
+}
+
+void AdlEngine::dropItem(byte noun) {
+	Common::Array<Item>::iterator it;
+
+	for (it = _inventory.begin(); it != _inventory.end(); ++it) {
+		if (it->field1 != noun || it->field2 != 0xfe)
+			continue;
+
+		it->field2 = _room;
+		it->field7 = 1;
+		return;
+	}
+
+	// Don't understand
+	printEngineMessage(IDI_MSG_DONT_UNDERSTAND);
+}
+
+void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
+	for (uint i = 0; i < command.numAct; ++i) {
+		switch (command.script[offset]) {
+		case 1:
+			_variables[command.script[offset + 2]] += command.script[offset + 1];
+			offset += 3;
+			break;
+		case 2:
+			_variables[command.script[offset + 2]] -= command.script[offset + 1];
+			offset += 3;
+			break;
+		case 3:
+			_variables[command.script[offset + 1]] = command.script[offset + 2];
+			offset += 3;
+			break;
+		case 4: {
+			Common::Array<Item>::const_iterator it;
+
+			for (it = _inventory.begin(); it != _inventory.end(); ++it)
+				if (it->field2 == 0xfe)
+					printMessage(it->field8);
+
+			++offset;
+			break;
+		}
+		case 5:
+			_inventory[command.script[offset + 1] - 1].field2 = command.script[offset + 2];
+			offset += 3;
+			break;
+		case 6:
+			_rooms[_room].picture = _rooms[_room].field8;
+			_room = command.script[offset + 1];
+			offset += 2;
+			break;
+		case 7:
+			_rooms[_room].picture = command.script[offset + 1];
+			offset += 2;
+			break;
+		case 8:
+			_rooms[_room].field8 = _rooms[_room].picture = command.script[offset + 1];
+			offset += 2;
+			break;
+		case 9:
+			printMessage(command.script[offset + 1]);
+			offset += 2;
+			break;
+		case 0xa:
+			_isDark = false;
+			++offset;
+			break;
+		case 0xb:
+			_isDark = true;
+			++offset;
+			break;
+		case 0xf:
+			warning("Save game not implemented");
+			++offset;
+			break;
+		case 0x10:
+			warning("Load game not implemented");
+			++offset;
+			break;
+		case 0x11: {
+			_display->printString(_strings[IDI_STR_PLAY_AGAIN]);
+			Common::String input = _display->inputString();
+			if (input.size() == 0 || input[0] != APPLECHAR('N')) {
+				warning("Restart game not implemented");
+				return;
+			}
+			// Fall-through
+		}
+		case 0xd:
+			printEngineMessage(IDI_MSG_THANKS_FOR_PLAYING);
+			quitGame();
+			return;
+		case 0x12: {
+			byte item = command.script[offset + 1] - 1;
+			_inventory[item].field2 = command.script[offset + 2];
+			_inventory[item].field5 = command.script[offset + 3];
+			_inventory[item].field6 = command.script[offset + 4];
+			offset += 5;
+			break;
+		}
+		case 0x13: {
+			byte item = command.script[offset + 2] - 1;
+			_inventory[item].field3 = command.script[offset + 1];
+			offset += 3;
+			break;
+		}
+		case 0x14:
+			_rooms[_room].picture = _rooms[_room].field8;
+			++offset;
+			break;
+		case 0x15:
+		case 0x16:
+		case 0x17:
+		case 0x18:
+		case 0x19:
+		case 0x1a: {
+			byte room = _rooms[_room].connections[command.script[offset] - 0x15];
+
+			if (room == 0) {
+				printEngineMessage(IDI_MSG_CANT_GO_THERE);
+				return;
+			}
+
+			_rooms[_room].picture = _rooms[_room].field8;
+			_room = room;
+			return;
+		}
+		case 0x1b:
+			takeItem(noun);
+			++offset;
+			break;
+		case 0x1c:
+			dropItem(noun);
+			++offset;
+			break;
+		case 0x1d:
+			_rooms[command.script[offset + 1]].field8 = _rooms[command.script[offset + 1]].picture = command.script[offset + 2];
+			offset += 3;
+			break;
+		default:
+			error("Invalid action opcode %02x", command.script[offset]);
+		}
+	}
+}
+
+bool AdlEngine::checkCommand(const Command &command, byte verb, byte noun) {
+	if (command.room != 0xfe && command.room != _room)
+		return false;
+
+	if (command.verb != 0xfe && command.verb != verb)
+		return false;
+
+	if (command.noun != 0xfe && command.noun != noun)
+		return false;
+
+	uint offset = 0;
+	for (uint i = 0; i < command.numCond; ++i) {
+		switch (command.script[offset]) {
+		case 3:
+			if (_inventory[command.script[offset + 1] - 1].field2 != command.script[offset + 2])
+				return false;
+			offset += 3;
+			break;
+		case 5:
+			if (command.script[offset + 1] > _steps)
+				return false;
+			offset += 2;
+			break;
+		case 6:
+			if (_variables[command.script[offset + 1]] != command.script[offset + 2])
+				return false;
+			offset += 3;
+			break;
+		case 9:
+			if (_rooms[_room].picture != command.script[offset + 1])
+				return false;
+			offset += 2;
+			break;
+		case 10:
+			if (_inventory[command.script[offset + 1] - 1].field3 != command.script[offset + 2])
+				return false;
+			offset += 3;
+			break;
+		default:
+			error("Invalid condition opcode %02x", command.script[offset]);
+		}
+	}
+
+	doActions(command, noun, offset);
+
+	return true;
+}
+
+bool AdlEngine::doOneCommand(const Commands &commands, byte verb, byte noun) {
+	Commands::const_iterator it;
+
+	for (it = commands.begin(); it != commands.end(); ++it)
+		if (checkCommand(*it, verb, noun))
+			return true;
+
+	return false;
+}
+
+void AdlEngine::doAllCommands(const Commands &commands, byte verb, byte noun) {
+	Commands::const_iterator it;
+
+	for (it = commands.begin(); it != commands.end(); ++it)
+		checkCommand(*it, verb, noun);
+}
+
+void AdlEngine::clearScreen() {
+	_display->setMode(Display::kModeMixed);
+	_display->clear(0x00);
+}
+
 AdlEngine *AdlEngine::create(GameType type, OSystem *syst, const AdlGameDescription *gd) {
 	switch(type) {
 	case kGameTypeHires1:
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 5252916..beb915c 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -42,16 +42,33 @@ class Parser;
 class Console;
 struct AdlGameDescription;
 
+struct StringOffset {
+	int stringIdx;
+	uint offset;
+};
+
 enum GameType {
 	kGameTypeNone = 0,
 	kGameTypeHires1
 };
 
-enum {
-	STR_COMMON_ENTERCMD,
-	STR_COMMON_VERBERR,
-	STR_COMMON_NOUNERR,
-	STR_CUSTOM_START
+// Messages used outside of scripts
+enum EngineMessage {
+	IDI_MSG_CANT_GO_THERE,
+	IDI_MSG_DONT_UNDERSTAND,
+	IDI_MSG_ITEM_DOESNT_MOVE,
+	IDI_MSG_ITEM_NOT_HERE,
+	IDI_MSG_THANKS_FOR_PLAYING
+};
+
+// Strings embedded in the executable
+enum EngineString {
+	IDI_STR_ENTER_COMMAND,
+	IDI_STR_VERB_ERROR,
+	IDI_STR_NOUN_ERROR,
+	IDI_STR_PLAY_AGAIN,
+
+	IDI_STR_TOTAL
 };
 
 struct Room {
@@ -99,17 +116,29 @@ public:
 	static AdlEngine *create(GameType type, OSystem *syst, const AdlGameDescription *gd);
 
 	Common::Error run();
-	virtual Common::String getExeString(uint id) = 0;
+	virtual Common::String getEngineString(int str);
 
 protected:
 	virtual void runGame() = 0;
+	virtual uint getEngineMessage(EngineMessage msg) = 0;
 	Common::String readString(Common::ReadStream &stream, byte until = 0);
 	void printStrings(Common::SeekableReadStream &stream, int count = 1);
+	virtual void printMessage(uint idx, bool wait = true);
+	void wordWrap(Common::String &str);
+	void readCommands(Common::ReadStream &stream, Commands &commands);
+	bool checkCommand(const Command &command, byte verb, byte noun);
+	bool doOneCommand(const Commands &commands, byte verb, byte noun);
+	void doAllCommands(const Commands &commands, byte verb, byte noun);
+	void doActions(const Command &command, byte noun, byte offset);
+	void clearScreen();
+	void takeItem(byte noun);
+	void dropItem(byte noun);
 
 	Display *_display;
 	Parser *_parser;
 
-	Common::Array<Common::String> _msgStrings;
+	Common::Array<Common::String> _strings;
+	Common::Array<Common::String> _messages;
 	Common::Array<Picture> _pictures;
 	Common::Array<Item> _inventory;
 	Common::Array<Common::Point> _itemOffsets;
@@ -123,6 +152,9 @@ protected:
 	uint16 _steps;
 	Common::Array<byte> _variables;
 	bool _isDark;
+
+private:
+	void printEngineMessage(EngineMessage);
 };
 
 AdlEngine *HiRes1Engine__create(OSystem *syst, const AdlGameDescription *gd);
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 28aa135..7d52d2a 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -41,8 +41,34 @@
 
 namespace Adl {
 
-static uint exeStrings[STR_MH_TOTAL] = {
-	23484, 23375, 23438, 27658, 0x6c31, 27729, 27772, 0x5f1e
+// Messages used outside of scripts
+#define IDI_HR1_MSG_CANT_GO_THERE 137
+#define IDI_HR1_MSG_DONT_UNDERSTAND 37
+#define IDI_HR1_MSG_ITEM_DOESNT_MOVE 151
+#define IDI_HR1_MSG_ITEM_NOT_HERE 152
+#define IDI_HR1_MSG_THANKS_FOR_PLAYING 140
+#define IDI_HR1_MSG_DONT_HAVE_IT 127
+#define IDI_HR1_MSG_GETTING_DARK 7
+
+// Strings embedded in the executable
+enum {
+	IDI_HR1_STR_CANT_GO_THERE = IDI_STR_TOTAL,
+	IDI_HR1_STR_DONT_HAVE_IT,
+	IDI_HR1_STR_DONT_UNDERSTAND,
+	IDI_HR1_STR_GETTING_DARK,
+
+	IDI_HR1_STR_TOTAL
+};
+
+static const StringOffset stringOffsets[] = {
+	{ IDI_STR_ENTER_COMMAND,       0x5bbc },
+	{ IDI_STR_VERB_ERROR,          0x5b4f },
+	{ IDI_STR_NOUN_ERROR,          0x5b8e },
+	{ IDI_STR_PLAY_AGAIN,          0x5f1e },
+	{ IDI_HR1_STR_CANT_GO_THERE,   0x6c0a },
+	{ IDI_HR1_STR_DONT_HAVE_IT,    0x6c31 },
+	{ IDI_HR1_STR_DONT_UNDERSTAND, 0x6c51 },
+	{ IDI_HR1_STR_GETTING_DARK,    0x6c7c }
 };
 
 HiRes1Engine::HiRes1Engine(OSystem *syst, const AdlGameDescription *gd) :
@@ -225,324 +251,6 @@ void HiRes1Engine::showRoom() {
 	printMessage(_rooms[_room].description, false);
 }
 
-Common::String HiRes1Engine::getExeString(uint idx) {
-	return _exeStrings[idx];
-}
-
-void HiRes1Engine::wordWrap(Common::String &str) {
-	uint end = 39;
-
-	while (1) {
-		if (str.size() <= end)
-			return;
-
-		while (str[end] != APPLECHAR(' '))
-			--end;
-
-		str.setChar(APPLECHAR('\r'), end);
-		end += 40;
-	}
-}
-
-void HiRes1Engine::printMessage(uint idx, bool wait) {
-	// Hardcoded overrides that don't wait after printing
-	// Note: strings may differ slightly from the ones in MESSAGES
-	switch (idx) {
-	case 137:
-		_display->printString(_exeStrings[STR_MH_DIRERR]);
-		return;
-	case 127:
-		_display->printString(_exeStrings[STR_MH_DONTHAVEIT]);
-		return;
-	case 37:
-		_display->printString(_exeStrings[STR_MH_DONTUNDERSTAND]);
-		return;
-	case 7:
-		_display->printString(_exeStrings[STR_MH_GETTINGDARK]);
-		return;
-	}
-
-	Common::String msg = _msgStrings[idx - 1];
-	wordWrap(msg);
-	_display->printString(msg);
-
-	if (wait)
-		_display->delay(14 * 166018 / 1000);
-}
-
-void HiRes1Engine::readCommands(Common::ReadStream &stream, Commands &commands) {
-	while (1) {
-		Command command;
-		command.room = stream.readByte();
-
-		if (command.room == 0xff)
-			return;
-
-		command.verb = stream.readByte();
-		command.noun = stream.readByte();
-
-		byte scriptSize = stream.readByte() - 6;
-
-		command.numCond = stream.readByte();
-		command.numAct = stream.readByte();
-
-		for (uint i = 0; i < scriptSize; ++i)
-			command.script.push_back(stream.readByte());
-
-		if (stream.eos() || stream.err())
-			error("Failed to read commands");
-
-		commands.push_back(command);
-	}
-}
-
-void HiRes1Engine::takeItem(byte noun) {
-	Common::Array<Item>::iterator it;
-
-	for (it = _inventory.begin(); it != _inventory.end(); ++it) {
-		if (it->field1 != noun || it->field2 != _room)
-			continue;
-
-		if (it->field7 == 2) {
-			// It doesn't move
-			printMessage(151);
-			return;
-		}
-
-		if (it->field7 == 1) {
-			it->field2 = 0xfe;
-			it->field7 = 1;
-			return;
-		}
-
-		Common::Array<byte>::const_iterator it2;
-		for (it2 = it->field10.begin(); it->field10.end(); ++it2) {
-			if (*it2 == _rooms[_room].picture) {
-				it->field2 = 0xfe;
-				it->field7 = 1;
-				return;
-			}
-		}
-	}
-
-	// Item not here
-	printMessage(152);
-}
-
-void HiRes1Engine::dropItem(byte noun) {
-	Common::Array<Item>::iterator it;
-
-	for (it = _inventory.begin(); it != _inventory.end(); ++it) {
-		if (it->field1 != noun || it->field2 != 0xfe)
-			continue;
-
-		it->field2 = _room;
-		it->field7 = 1;
-		return;
-	}
-
-	// Don't understand
-	printMessage(37);
-}
-
-void HiRes1Engine::doActions(const Command &command, byte noun, byte offset) {
-	for (uint i = 0; i < command.numAct; ++i) {
-		switch (command.script[offset]) {
-		case 1:
-			_variables[command.script[offset + 2]] += command.script[offset + 1];
-			offset += 3;
-			break;
-		case 2:
-			_variables[command.script[offset + 2]] -= command.script[offset + 1];
-			offset += 3;
-			break;
-		case 3:
-			_variables[command.script[offset + 1]] = command.script[offset + 2];
-			offset += 3;
-			break;
-		case 4: {
-			Common::Array<Item>::const_iterator it;
-
-			for (it = _inventory.begin(); it != _inventory.end(); ++it)
-				if (it->field2 == 0xfe)
-					printMessage(it->field8);
-
-			++offset;
-			break;
-		}
-		case 5:
-			_inventory[command.script[offset + 1] - 1].field2 = command.script[offset + 2];
-			offset += 3;
-			break;
-		case 6:
-			_rooms[_room].picture = _rooms[_room].field8;
-			_room = command.script[offset + 1];
-			offset += 2;
-			break;
-		case 7:
-			_rooms[_room].picture = command.script[offset + 1];
-			offset += 2;
-			break;
-		case 8:
-			_rooms[_room].field8 = _rooms[_room].picture = command.script[offset + 1];
-			offset += 2;
-			break;
-		case 9:
-			printMessage(command.script[offset + 1]);
-			offset += 2;
-			break;
-		case 0xa:
-			_isDark = false;
-			++offset;
-			break;
-		case 0xb:
-			_isDark = true;
-			++offset;
-			break;
-		case 0xf:
-			warning("Save game not implemented");
-			++offset;
-			break;
-		case 0x10:
-			warning("Load game not implemented");
-			++offset;
-			break;
-		case 0x11: {
-			_display->printString(_exeStrings[STR_MH_PLAYAGAIN]);
-			Common::String input = _display->inputString();
-			if (input.size() == 0 || input[0] != APPLECHAR('N')) {
-				warning("Restart game not implemented");
-				return;
-			}
-			// Fall-through
-		}
-		case 0xd:
-			printMessage(140);
-			quitGame();
-			return;
-		case 0x12: {
-			byte item = command.script[offset + 1] - 1;
-			_inventory[item].field2 = command.script[offset + 2];
-			_inventory[item].field5 = command.script[offset + 3];
-			_inventory[item].field6 = command.script[offset + 4];
-			offset += 5;
-			break;
-		}
-		case 0x13: {
-			byte item = command.script[offset + 2] - 1;
-			_inventory[item].field3 = command.script[offset + 1];
-			offset += 3;
-			break;
-		}
-		case 0x14:
-			_rooms[_room].picture = _rooms[_room].field8;
-			++offset;
-			break;
-		case 0x15:
-		case 0x16:
-		case 0x17:
-		case 0x18:
-		case 0x19:
-		case 0x1a: {
-			byte room = _rooms[_room].connections[command.script[offset] - 0x15];
-
-			if (room == 0) {
-				printMessage(137);
-				return;
-			}
-
-			_rooms[_room].picture = _rooms[_room].field8;
-			_room = room;
-			return;
-		}
-		case 0x1b:
-			takeItem(noun);
-			++offset;
-			break;
-		case 0x1c:
-			dropItem(noun);
-			++offset;
-			break;
-		case 0x1d:
-			_rooms[command.script[offset + 1]].field8 = _rooms[command.script[offset + 1]].picture = command.script[offset + 2];
-			offset += 3;
-			break;
-		default:
-			error("Invalid action opcode %02x", command.script[offset]);
-		}
-	}
-}
-
-bool HiRes1Engine::checkCommand(const Command &command, byte verb, byte noun) {
-	if (command.room != 0xfe && command.room != _room)
-		return false;
-
-	if (command.verb != 0xfe && command.verb != verb)
-		return false;
-
-	if (command.noun != 0xfe && command.noun != noun)
-		return false;
-
-	uint offset = 0;
-	for (uint i = 0; i < command.numCond; ++i) {
-		switch (command.script[offset]) {
-		case 3:
-			if (_inventory[command.script[offset + 1] - 1].field2 != command.script[offset + 2])
-				return false;
-			offset += 3;
-			break;
-		case 5:
-			if (command.script[offset + 1] > _steps)
-				return false;
-			offset += 2;
-			break;
-		case 6:
-			if (_variables[command.script[offset + 1]] != command.script[offset + 2])
-				return false;
-			offset += 3;
-			break;
-		case 9:
-			if (_rooms[_room].picture != command.script[offset + 1])
-				return false;
-			offset += 2;
-			break;
-		case 10:
-			if (_inventory[command.script[offset + 1] - 1].field3 != command.script[offset + 2])
-				return false;
-			offset += 3;
-			break;
-		default:
-			error("Invalid condition opcode %02x", command.script[offset]);
-		}
-	}
-
-	doActions(command, noun, offset);
-
-	return true;
-}
-
-bool HiRes1Engine::doOneCommand(const Commands &commands, byte verb, byte noun) {
-	Commands::const_iterator it;
-
-	for (it = commands.begin(); it != commands.end(); ++it)
-		if (checkCommand(*it, verb, noun))
-			return true;
-
-	return false;
-}
-
-void HiRes1Engine::doAllCommands(const Commands &commands, byte verb, byte noun) {
-	Commands::const_iterator it;
-
-	for (it = commands.begin(); it != commands.end(); ++it)
-		checkCommand(*it, verb, noun);
-}
-
-void HiRes1Engine::clearScreen() {
-	_display->setMode(Display::kModeMixed);
-	_display->clear(0x00);
-}
-
 void HiRes1Engine::runGame() {
 	runIntro();
 	_display->printASCIIString("\r");
@@ -553,7 +261,7 @@ void HiRes1Engine::runGame() {
 		error("Failed to open file");
 
 	while (!f.eos() && !f.err())
-		_msgStrings.push_back(readString(f, APPLECHAR('\r')) + APPLECHAR('\r'));
+		_messages.push_back(readString(f, APPLECHAR('\r')) + APPLECHAR('\r'));
 
 	f.close();
 
@@ -561,9 +269,10 @@ void HiRes1Engine::runGame() {
 		error("Failed to open file");
 
 	// Load strings from executable
-	for (uint idx = 0; idx < STR_MH_TOTAL; ++idx) {
-		f.seek(exeStrings[idx]);
-		_exeStrings.push_back(readString(f));
+	_strings.resize(IDI_HR1_STR_TOTAL);
+	for (uint idx = 0; idx < IDI_HR1_STR_TOTAL; ++idx) {
+		f.seek(stringOffsets[idx].offset);
+		_strings[stringOffsets[idx].stringIdx] = readString(f);
 	}
 
 	// Load room data from executable
@@ -673,6 +382,44 @@ void HiRes1Engine::runGame() {
 	}
 }
 
+void HiRes1Engine::printMessage(uint idx, bool wait) {
+	// Hardcoded overrides that don't wait after printing
+	// Note: strings may differ slightly from the ones in MESSAGES
+	switch (idx) {
+	case 137:
+		_display->printString(_strings[IDI_HR1_STR_CANT_GO_THERE]);
+		return;
+	case 127:
+		_display->printString(_strings[IDI_HR1_STR_DONT_HAVE_IT]);
+		return;
+	case 37:
+		_display->printString(_strings[IDI_HR1_STR_DONT_UNDERSTAND]);
+		return;
+	case 7:
+		_display->printString(_strings[IDI_HR1_STR_GETTING_DARK]);
+		return;
+	}
+
+	AdlEngine::printMessage(idx, wait);
+}
+
+uint HiRes1Engine::getEngineMessage(EngineMessage msg) {
+	switch (msg) {
+	case IDI_MSG_CANT_GO_THERE:
+		return IDI_HR1_MSG_CANT_GO_THERE;
+	case IDI_MSG_DONT_UNDERSTAND:
+		return IDI_HR1_MSG_DONT_UNDERSTAND;
+	case IDI_MSG_ITEM_DOESNT_MOVE:
+		return IDI_HR1_MSG_ITEM_DOESNT_MOVE;
+	case IDI_MSG_ITEM_NOT_HERE:
+		return IDI_HR1_MSG_ITEM_NOT_HERE;
+	case IDI_MSG_THANKS_FOR_PLAYING:
+		return IDI_HR1_MSG_THANKS_FOR_PLAYING;
+	default:
+		error("Cannot find engine message %i", msg);
+	}
+}
+
 AdlEngine *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 e9e274c..19aa55e 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -32,20 +32,12 @@ class ReadStream;
 namespace Adl {
 
 enum {
-	// Some of these are probably common
-	STR_MH_DIRERR = STR_CUSTOM_START,
-	STR_MH_DONTHAVEIT,
-	STR_MH_DONTUNDERSTAND,
-	STR_MH_GETTINGDARK,
-	STR_MH_PLAYAGAIN,
-
-	STR_MH_TOTAL
+	IDI_HR1_MSG_
 };
 
 class HiRes1Engine : public AdlEngine {
 public:
 	HiRes1Engine(OSystem *syst, const AdlGameDescription *gd);
-	Common::String getExeString(uint idx);
 
 protected:
 	void runGame();
@@ -57,23 +49,14 @@ private:
 		MH_ITEM_OFFSETS = 21
 	};
 
+	void printMessage(uint idx, bool wait = true);
+	uint getEngineMessage(EngineMessage msg);
+
 	void runIntro();
 	void drawPic(Common::ReadStream &stream, byte xOffset, byte yOffset);
 	void showRoom();
-	void printMessage(uint idx, bool wait = true);
-	void wordWrap(Common::String &str);
-	void readCommands(Common::ReadStream &stream, Commands &commands);
-	bool checkCommand(const Command &command, byte verb, byte noun);
-	bool doOneCommand(const Commands &commands, byte verb, byte noun);
-	void doAllCommands(const Commands &commands, byte verb, byte noun);
-	void doActions(const Command &command, byte noun, byte offset);
-	void clearScreen();
-	void takeItem(byte noun);
-	void dropItem(byte noun);
 	void drawItems();
 	void drawPic(byte pic, byte xOffset, byte yOffset);
-
-	Common::Array<Common::String> _exeStrings;
 };
 
 } // End of namespace Adl
diff --git a/engines/adl/parser.cpp b/engines/adl/parser.cpp
index 1611fc7..a697301 100644
--- a/engines/adl/parser.cpp
+++ b/engines/adl/parser.cpp
@@ -129,7 +129,7 @@ Common::String Parser::getWord(const Common::String &line, uint &index) {
 
 void Parser::getInput(uint &verb, uint &noun) {
 	while (1) {
-		_display.printString(_engine.getExeString(STR_COMMON_ENTERCMD));
+		_display.printString(_engine.getEngineString(IDI_STR_ENTER_COMMAND));
 		Common::String line = getLine();
 
 		if (g_engine->shouldQuit())
@@ -139,7 +139,7 @@ void Parser::getInput(uint &verb, uint &noun) {
 		Common::String verbStr = getWord(line, index);
 
 		if (!_verbs.contains(verbStr)) {
-			Common::String err = _engine.getExeString(STR_COMMON_VERBERR);
+			Common::String err = _engine.getEngineString(IDI_STR_VERB_ERROR);
 			for (uint i = 0; i < verbStr.size(); ++i)
 				err.setChar(verbStr[i], i + 19);
 			_display.printString(err);
@@ -151,7 +151,7 @@ void Parser::getInput(uint &verb, uint &noun) {
 		Common::String nounStr = getWord(line, index);
 
 		if (!_nouns.contains(nounStr)) {
-			Common::String err = _engine.getExeString(STR_COMMON_NOUNERR);
+			Common::String err = _engine.getEngineString(IDI_STR_NOUN_ERROR);
 			for (uint i = 0; i < verbStr.size(); ++i)
 				err.setChar(verbStr[i], i + 19);
 			for (uint i = 0; i < nounStr.size(); ++i)


Commit: ce97d0a26e51ff1253ae3268f09673f0aa31f4a7
    https://github.com/scummvm/scummvm/commit/ce97d0a26e51ff1253ae3268f09673f0aa31f4a7
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Use #defines instead of literals

Changed paths:
    engines/adl/hires1.cpp



diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 7d52d2a..65aa665 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -386,16 +386,16 @@ void HiRes1Engine::printMessage(uint idx, bool wait) {
 	// Hardcoded overrides that don't wait after printing
 	// Note: strings may differ slightly from the ones in MESSAGES
 	switch (idx) {
-	case 137:
+	case IDI_HR1_MSG_CANT_GO_THERE:
 		_display->printString(_strings[IDI_HR1_STR_CANT_GO_THERE]);
 		return;
-	case 127:
+	case IDI_HR1_MSG_DONT_HAVE_IT:
 		_display->printString(_strings[IDI_HR1_STR_DONT_HAVE_IT]);
 		return;
-	case 37:
+	case IDI_MSG_DONT_UNDERSTAND:
 		_display->printString(_strings[IDI_HR1_STR_DONT_UNDERSTAND]);
 		return;
-	case 7:
+	case IDI_HR1_MSG_GETTING_DARK:
 		_display->printString(_strings[IDI_HR1_STR_GETTING_DARK]);
 		return;
 	}


Commit: f9c9f2ac9de984aed7fb2438899aff33104ab3b8
    https://github.com/scummvm/scummvm/commit/f9c9f2ac9de984aed7fb2438899aff33104ab3b8
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Rename Item struct fields

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 2c11290..3ce6d70 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -165,25 +165,24 @@ void AdlEngine::takeItem(byte noun) {
 	Common::Array<Item>::iterator it;
 
 	for (it = _inventory.begin(); it != _inventory.end(); ++it) {
-		if (it->field1 != noun || it->field2 != _room)
+		if (it->noun != noun || it->room != _room)
 			continue;
 
-		if (it->field7 == 2) {
+		if (it->state == IDI_ITEM_DOESNT_MOVE) {
 			printEngineMessage(IDI_MSG_ITEM_DOESNT_MOVE);
 			return;
 		}
 
-		if (it->field7 == 1) {
-			it->field2 = 0xfe;
-			it->field7 = 1;
+		if (it->state == IDI_ITEM_MOVED) {
+			it->room = IDI_NONE;
 			return;
 		}
 
 		Common::Array<byte>::const_iterator it2;
-		for (it2 = it->field10.begin(); it->field10.end(); ++it2) {
+		for (it2 = it->roomPictures.begin(); it->roomPictures.end(); ++it2) {
 			if (*it2 == _rooms[_room].picture) {
-				it->field2 = 0xfe;
-				it->field7 = 1;
+				it->room = IDI_NONE;
+				it->state = IDI_ITEM_MOVED;
 				return;
 			}
 		}
@@ -196,11 +195,11 @@ void AdlEngine::dropItem(byte noun) {
 	Common::Array<Item>::iterator it;
 
 	for (it = _inventory.begin(); it != _inventory.end(); ++it) {
-		if (it->field1 != noun || it->field2 != 0xfe)
+		if (it->noun != noun || it->room != IDI_NONE)
 			continue;
 
-		it->field2 = _room;
-		it->field7 = 1;
+		it->room = _room;
+		it->state = IDI_ITEM_MOVED;
 		return;
 	}
 
@@ -227,14 +226,14 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			Common::Array<Item>::const_iterator it;
 
 			for (it = _inventory.begin(); it != _inventory.end(); ++it)
-				if (it->field2 == 0xfe)
-					printMessage(it->field8);
+				if (it->room == IDI_NONE)
+					printMessage(it->description);
 
 			++offset;
 			break;
 		}
 		case 5:
-			_inventory[command.script[offset + 1] - 1].field2 = command.script[offset + 2];
+			_inventory[command.script[offset + 1] - 1].room = command.script[offset + 2];
 			offset += 3;
 			break;
 		case 6:
@@ -285,15 +284,15 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			return;
 		case 0x12: {
 			byte item = command.script[offset + 1] - 1;
-			_inventory[item].field2 = command.script[offset + 2];
-			_inventory[item].field5 = command.script[offset + 3];
-			_inventory[item].field6 = command.script[offset + 4];
+			_inventory[item].room = command.script[offset + 2];
+			_inventory[item].position.x = command.script[offset + 3];
+			_inventory[item].position.y = command.script[offset + 4];
 			offset += 5;
 			break;
 		}
 		case 0x13: {
 			byte item = command.script[offset + 2] - 1;
-			_inventory[item].field3 = command.script[offset + 1];
+			_inventory[item].picture = command.script[offset + 1];
 			offset += 3;
 			break;
 		}
@@ -337,20 +336,20 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 }
 
 bool AdlEngine::checkCommand(const Command &command, byte verb, byte noun) {
-	if (command.room != 0xfe && command.room != _room)
+	if (command.room != IDI_NONE && command.room != _room)
 		return false;
 
-	if (command.verb != 0xfe && command.verb != verb)
+	if (command.verb != IDI_NONE && command.verb != verb)
 		return false;
 
-	if (command.noun != 0xfe && command.noun != noun)
+	if (command.noun != IDI_NONE && command.noun != noun)
 		return false;
 
 	uint offset = 0;
 	for (uint i = 0; i < command.numCond; ++i) {
 		switch (command.script[offset]) {
 		case 3:
-			if (_inventory[command.script[offset + 1] - 1].field2 != command.script[offset + 2])
+			if (_inventory[command.script[offset + 1] - 1].room != command.script[offset + 2])
 				return false;
 			offset += 3;
 			break;
@@ -370,7 +369,7 @@ bool AdlEngine::checkCommand(const Command &command, byte verb, byte noun) {
 			offset += 2;
 			break;
 		case 10:
-			if (_inventory[command.script[offset + 1] - 1].field3 != command.script[offset + 2])
+			if (_inventory[command.script[offset + 1] - 1].picture != command.script[offset + 2])
 				return false;
 			offset += 3;
 			break;
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index beb915c..987a962 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -90,16 +90,23 @@ struct Command {
 	Common::Array<byte> script;
 };
 
+enum {
+	IDI_ITEM_NOT_MOVED,
+	IDI_ITEM_MOVED,
+	IDI_ITEM_DOESNT_MOVE
+};
+
+#define IDI_NONE 0xfe
+
 struct Item {
-	byte field1;
-	byte field2;
-	byte field3;
-	byte field4;
-	byte field5;
-	byte field6;
-	byte field7;
-	byte field8;
-	Common::Array<byte> field10;
+	byte noun;
+	byte room;
+	byte picture;
+	bool isDrawing;
+	Common::Point position;
+	int state;
+	byte description;
+	Common::Array<byte> roomPictures;
 };
 
 typedef Common::List<Command> Commands;
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 65aa665..a078340 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -212,16 +212,16 @@ void HiRes1Engine::drawItems() {
 	uint dropped = 0;
 
 	for (it = _inventory.begin(); it != _inventory.end(); ++it) {
-		if (it->field2 != _room)
+		if (it->room != _room)
 			continue;
 
-		if (it->field7 == 1) {
+		if (it->state == IDI_ITEM_MOVED) {
 			if (_rooms[_room].field8 == _rooms[_room].picture) {
 				const Common::Point &p =  _itemOffsets[dropped];
-				if (it->field4)
-					_display->drawRightAngles(_drawings[it->field3 - 1], Common::Point(p.x, p.y), 0, 1, 0x7f);
+				if (it->isDrawing)
+					_display->drawRightAngles(_drawings[it->picture - 1], Common::Point(p.x, p.y), 0, 1, 0x7f);
 				else
-					drawPic(it->field3, p.x, p.y);
+					drawPic(it->picture, p.x, p.y);
 				++dropped;
 			}
 			continue;
@@ -229,12 +229,12 @@ void HiRes1Engine::drawItems() {
 
 		Common::Array<byte>::const_iterator it2;
 
-		for (it2 = it->field10.begin(); it2 != it->field10.end(); ++it2) {
+		for (it2 = it->roomPictures.begin(); it2 != it->roomPictures.end(); ++it2) {
 			if (*it2 == _rooms[_room].picture) {
-				if (it->field4)
-					_display->drawRightAngles(_drawings[it->field3 - 1], Common::Point(it->field5, it->field6), 0, 1, 0x7f);
+				if (it->isDrawing)
+					_display->drawRightAngles(_drawings[it->picture - 1], it->position, 0, 1, 0x7f);
 				else
-					drawPic(it->field3, it->field5, it->field6);
+					drawPic(it->picture, it->position.x, it->position.y);
 				continue;
 			}
 		}
@@ -292,21 +292,21 @@ void HiRes1Engine::runGame() {
 	f.seek(0x100);
 	while (f.readByte() != 0xff) {
 		struct Item item;
-		item.field1 = f.readByte();
-		item.field2 = f.readByte();
-		item.field3 = f.readByte();
-		item.field4 = f.readByte();
-		item.field5 = f.readByte();
-		item.field6 = f.readByte();
-		item.field7 = f.readByte();
-		item.field8 = f.readByte();
+		item.noun = f.readByte();
+		item.room = f.readByte();
+		item.picture = f.readByte();
+		item.isDrawing = f.readByte();
+		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.field10.push_back(f.readByte());
+			item.roomPictures.push_back(f.readByte());
 
 		_inventory.push_back(item);
 	}


Commit: 8f9d4b96530a8b30ec2208aa217d6b339e4e94b7
    https://github.com/scummvm/scummvm/commit/8f9d4b96530a8b30ec2208aa217d6b339e4e94b7
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Use #defines instead of literals

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



diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 987a962..4c8180e 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -42,16 +42,16 @@ class Parser;
 class Console;
 struct AdlGameDescription;
 
-struct StringOffset {
-	int stringIdx;
-	uint offset;
-};
-
 enum GameType {
 	kGameTypeNone = 0,
 	kGameTypeHires1
 };
 
+struct StringOffset {
+	int stringIdx;
+	uint offset;
+};
+
 // Messages used outside of scripts
 enum EngineMessage {
 	IDI_MSG_CANT_GO_THERE,
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index a078340..a5dbb89 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -60,6 +60,7 @@ enum {
 	IDI_HR1_STR_TOTAL
 };
 
+// Offsets for strings inside executable
 static const StringOffset stringOffsets[] = {
 	{ IDI_STR_ENTER_COMMAND,       0x5bbc },
 	{ IDI_STR_VERB_ERROR,          0x5b4f },
@@ -71,6 +72,16 @@ static const StringOffset stringOffsets[] = {
 	{ IDI_HR1_STR_GETTING_DARK,    0x6c7c }
 };
 
+#define IDI_HR1_OFS_PD_TEXT_0 0x5d
+#define IDI_HR1_OFS_PD_TEXT_1 0x12b
+#define IDI_HR1_OFS_PD_TEXT_2 0x16d
+#define IDI_HR1_OFS_PD_TEXT_3 0x259
+
+#define IDI_HR1_OFS_INTRO_TEXT 0x66
+#define IDI_HR1_OFS_GAME_OR_HELP 0xf
+
+#define IDI_HR1_OFS_LOGO_0 0x1003
+
 HiRes1Engine::HiRes1Engine(OSystem *syst, const AdlGameDescription *gd) :
 		AdlEngine(syst, gd) {
 	_variables.resize(20);
@@ -82,7 +93,7 @@ void HiRes1Engine::runIntro() {
 	if (!file.open("AUTO LOAD OBJ"))
 		error("Failed to open file");
 
-	file.seek(0x1003);
+	file.seek(IDI_HR1_OFS_LOGO_0);
 	_display->setMode(Display::kModeHires);
 	_display->loadFrameBuffer(file);
 	_display->decodeFrameBuffer();
@@ -99,19 +110,19 @@ void HiRes1Engine::runIntro() {
 
 	Common::String str;
 
-	basic.seek(93);
+	basic.seek(IDI_HR1_OFS_PD_TEXT_0);
 	str = readString(basic, '"');
 	_display->printASCIIString(str + '\r');
 
-	basic.seek(299);
+	basic.seek(IDI_HR1_OFS_PD_TEXT_1);
 	str = readString(basic, '"');
 	_display->printASCIIString(str + "\r\r");
 
-	basic.seek(365);
+	basic.seek(IDI_HR1_OFS_PD_TEXT_2);
 	str = readString(basic, '"');
 	_display->printASCIIString(str + "\r\r");
 
-	basic.seek(601);
+	basic.seek(IDI_HR1_OFS_PD_TEXT_3);
 	str = readString(basic, '"');
 	_display->printASCIIString(str + '\r');
 
@@ -121,7 +132,7 @@ void HiRes1Engine::runIntro() {
 
 	_display->setMode(Display::kModeMixed);
 
-	file.seek(15);
+	file.seek(IDI_HR1_OFS_GAME_OR_HELP);
 	str = readString(file);
 
 	while (1) {
@@ -141,7 +152,7 @@ void HiRes1Engine::runIntro() {
 	};
 
 	_display->setMode(Display::kModeText);
-	file.seek(102);
+	file.seek(IDI_HR1_OFS_INTRO_TEXT);
 
 	const int pages[] = { 6, 6, 4, 5, 8, 7, 0 };
 


Commit: 2104a5095d9d338a05cdf1e3a8e8b7f680b15f46
    https://github.com/scummvm/scummvm/commit/2104a5095d9d338a05cdf1e3a8e8b7f680b15f46
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Rename Room struct fields

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 3ce6d70..6109004 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -180,7 +180,7 @@ void AdlEngine::takeItem(byte noun) {
 
 		Common::Array<byte>::const_iterator it2;
 		for (it2 = it->roomPictures.begin(); it->roomPictures.end(); ++it2) {
-			if (*it2 == _rooms[_room].picture) {
+			if (*it2 == _rooms[_room].curPicture) {
 				it->room = IDI_NONE;
 				it->state = IDI_ITEM_MOVED;
 				return;
@@ -237,16 +237,16 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			offset += 3;
 			break;
 		case 6:
-			_rooms[_room].picture = _rooms[_room].field8;
+			_rooms[_room].curPicture = _rooms[_room].picture;
 			_room = command.script[offset + 1];
 			offset += 2;
 			break;
 		case 7:
-			_rooms[_room].picture = command.script[offset + 1];
+			_rooms[_room].curPicture = command.script[offset + 1];
 			offset += 2;
 			break;
 		case 8:
-			_rooms[_room].field8 = _rooms[_room].picture = command.script[offset + 1];
+			_rooms[_room].picture = _rooms[_room].curPicture = command.script[offset + 1];
 			offset += 2;
 			break;
 		case 9:
@@ -297,7 +297,7 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			break;
 		}
 		case 0x14:
-			_rooms[_room].picture = _rooms[_room].field8;
+			_rooms[_room].curPicture = _rooms[_room].picture;
 			++offset;
 			break;
 		case 0x15:
@@ -313,7 +313,7 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 				return;
 			}
 
-			_rooms[_room].picture = _rooms[_room].field8;
+			_rooms[_room].curPicture = _rooms[_room].picture;
 			_room = room;
 			return;
 		}
@@ -326,7 +326,7 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			++offset;
 			break;
 		case 0x1d:
-			_rooms[command.script[offset + 1]].field8 = _rooms[command.script[offset + 1]].picture = command.script[offset + 2];
+			_rooms[command.script[offset + 1]].picture = _rooms[command.script[offset + 1]].curPicture = command.script[offset + 2];
 			offset += 3;
 			break;
 		default:
@@ -364,7 +364,7 @@ bool AdlEngine::checkCommand(const Command &command, byte verb, byte noun) {
 			offset += 3;
 			break;
 		case 9:
-			if (_rooms[_room].picture != command.script[offset + 1])
+			if (_rooms[_room].curPicture != command.script[offset + 1])
 				return false;
 			offset += 2;
 			break;
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 4c8180e..fffe61e 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -74,8 +74,8 @@ enum EngineString {
 struct Room {
 	byte description;
 	byte connections[6];
-	byte field8;
 	byte picture;
+	byte curPicture;
 };
 
 struct Picture {
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index a5dbb89..730f229 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -42,13 +42,13 @@
 namespace Adl {
 
 // Messages used outside of scripts
-#define IDI_HR1_MSG_CANT_GO_THERE 137
-#define IDI_HR1_MSG_DONT_UNDERSTAND 37
-#define IDI_HR1_MSG_ITEM_DOESNT_MOVE 151
-#define IDI_HR1_MSG_ITEM_NOT_HERE 152
+#define IDI_HR1_MSG_CANT_GO_THERE      137
+#define IDI_HR1_MSG_DONT_UNDERSTAND     37
+#define IDI_HR1_MSG_ITEM_DOESNT_MOVE   151
+#define IDI_HR1_MSG_ITEM_NOT_HERE      152
 #define IDI_HR1_MSG_THANKS_FOR_PLAYING 140
-#define IDI_HR1_MSG_DONT_HAVE_IT 127
-#define IDI_HR1_MSG_GETTING_DARK 7
+#define IDI_HR1_MSG_DONT_HAVE_IT       127
+#define IDI_HR1_MSG_GETTING_DARK         7
 
 // Strings embedded in the executable
 enum {
@@ -227,7 +227,7 @@ void HiRes1Engine::drawItems() {
 			continue;
 
 		if (it->state == IDI_ITEM_MOVED) {
-			if (_rooms[_room].field8 == _rooms[_room].picture) {
+			if (_rooms[_room].picture == _rooms[_room].curPicture) {
 				const Common::Point &p =  _itemOffsets[dropped];
 				if (it->isDrawing)
 					_display->drawRightAngles(_drawings[it->picture - 1], Common::Point(p.x, p.y), 0, 1, 0x7f);
@@ -241,7 +241,7 @@ void HiRes1Engine::drawItems() {
 		Common::Array<byte>::const_iterator it2;
 
 		for (it2 = it->roomPictures.begin(); it2 != it->roomPictures.end(); ++it2) {
-			if (*it2 == _rooms[_room].picture) {
+			if (*it2 == _rooms[_room].curPicture) {
 				if (it->isDrawing)
 					_display->drawRightAngles(_drawings[it->picture - 1], it->position, 0, 1, 0x7f);
 				else
@@ -254,7 +254,7 @@ void HiRes1Engine::drawItems() {
 
 void HiRes1Engine::showRoom() {
 	if (!_isDark) {
-		drawPic(_rooms[_room].picture, 0, 0);
+		drawPic(_rooms[_room].curPicture, 0, 0);
 		drawItems();
 	}
 
@@ -294,8 +294,8 @@ void HiRes1Engine::runGame() {
 		room.description = f.readByte();
 		for (uint j = 0; j < 6; ++j)
 			room.connections[j] = f.readByte();
-		room.field8 = f.readByte();
 		room.picture = f.readByte();
+		room.curPicture = f.readByte();
 		_rooms.push_back(room);
 	}
 


Commit: 00d87cca9007ef69314b00eec5bffd6b9a9f2e72
    https://github.com/scummvm/scummvm/commit/00d87cca9007ef69314b00eec5bffd6b9a9f2e72
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Add more #defines for literals

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



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 6109004..af71bba 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -210,19 +210,19 @@ void AdlEngine::dropItem(byte noun) {
 void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 	for (uint i = 0; i < command.numAct; ++i) {
 		switch (command.script[offset]) {
-		case 1:
+		case IDO_ACT_VAR_ADD:
 			_variables[command.script[offset + 2]] += command.script[offset + 1];
 			offset += 3;
 			break;
-		case 2:
+		case IDO_ACT_VAR_SUB:
 			_variables[command.script[offset + 2]] -= command.script[offset + 1];
 			offset += 3;
 			break;
-		case 3:
+		case IDO_ACT_VAR_SET:
 			_variables[command.script[offset + 1]] = command.script[offset + 2];
 			offset += 3;
 			break;
-		case 4: {
+		case IDO_ACT_LIST_ITEMS: {
 			Common::Array<Item>::const_iterator it;
 
 			for (it = _inventory.begin(); it != _inventory.end(); ++it)
@@ -232,44 +232,44 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			++offset;
 			break;
 		}
-		case 5:
+		case IDO_ACT_MOVE_ITEM:
 			_inventory[command.script[offset + 1] - 1].room = command.script[offset + 2];
 			offset += 3;
 			break;
-		case 6:
+		case IDO_ACT_SET_ROOM:
 			_rooms[_room].curPicture = _rooms[_room].picture;
 			_room = command.script[offset + 1];
 			offset += 2;
 			break;
-		case 7:
+		case IDO_ACT_SET_CUR_PIC:
 			_rooms[_room].curPicture = command.script[offset + 1];
 			offset += 2;
 			break;
-		case 8:
+		case IDO_ACT_SET_PIC:
 			_rooms[_room].picture = _rooms[_room].curPicture = command.script[offset + 1];
 			offset += 2;
 			break;
-		case 9:
+		case IDO_ACT_PRINT_MSG:
 			printMessage(command.script[offset + 1]);
 			offset += 2;
 			break;
-		case 0xa:
+		case IDO_ACT_SET_LIGHT:
 			_isDark = false;
 			++offset;
 			break;
-		case 0xb:
+		case IDO_ACT_SET_DARK:
 			_isDark = true;
 			++offset;
 			break;
-		case 0xf:
+		case IDO_ACT_SAVE:
 			warning("Save game not implemented");
 			++offset;
 			break;
-		case 0x10:
+		case IDO_ACT_LOAD:
 			warning("Load game not implemented");
 			++offset;
 			break;
-		case 0x11: {
+		case IDO_ACT_RESTART: {
 			_display->printString(_strings[IDI_STR_PLAY_AGAIN]);
 			Common::String input = _display->inputString();
 			if (input.size() == 0 || input[0] != APPLECHAR('N')) {
@@ -278,11 +278,11 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			}
 			// Fall-through
 		}
-		case 0xd:
+		case IDO_ACT_QUIT:
 			printEngineMessage(IDI_MSG_THANKS_FOR_PLAYING);
 			quitGame();
 			return;
-		case 0x12: {
+		case IDO_ACT_SET_ITEM_POS: {
 			byte item = command.script[offset + 1] - 1;
 			_inventory[item].room = command.script[offset + 2];
 			_inventory[item].position.x = command.script[offset + 3];
@@ -290,22 +290,22 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			offset += 5;
 			break;
 		}
-		case 0x13: {
+		case IDO_ACT_SET_ITEM_PIC: {
 			byte item = command.script[offset + 2] - 1;
 			_inventory[item].picture = command.script[offset + 1];
 			offset += 3;
 			break;
 		}
-		case 0x14:
+		case IDO_ACT_RESET_PIC:
 			_rooms[_room].curPicture = _rooms[_room].picture;
 			++offset;
 			break;
-		case 0x15:
-		case 0x16:
-		case 0x17:
-		case 0x18:
-		case 0x19:
-		case 0x1a: {
+		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 = _rooms[_room].connections[command.script[offset] - 0x15];
 
 			if (room == 0) {
@@ -317,15 +317,15 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			_room = room;
 			return;
 		}
-		case 0x1b:
+		case IDO_ACT_TAKE_ITEM:
 			takeItem(noun);
 			++offset;
 			break;
-		case 0x1c:
+		case IDO_ACT_DROP_ITEM:
 			dropItem(noun);
 			++offset;
 			break;
-		case 0x1d:
+		case IDO_ACT_SET_ROOM_PIC:
 			_rooms[command.script[offset + 1]].picture = _rooms[command.script[offset + 1]].curPicture = command.script[offset + 2];
 			offset += 3;
 			break;
@@ -348,27 +348,27 @@ bool AdlEngine::checkCommand(const Command &command, byte verb, byte noun) {
 	uint offset = 0;
 	for (uint i = 0; i < command.numCond; ++i) {
 		switch (command.script[offset]) {
-		case 3:
+		case IDO_CND_ITEM_IN_ROOM:
 			if (_inventory[command.script[offset + 1] - 1].room != command.script[offset + 2])
 				return false;
 			offset += 3;
 			break;
-		case 5:
+		case IDO_CND_STEPS_GE:
 			if (command.script[offset + 1] > _steps)
 				return false;
 			offset += 2;
 			break;
-		case 6:
+		case IDO_CND_VAR_EQ:
 			if (_variables[command.script[offset + 1]] != command.script[offset + 2])
 				return false;
 			offset += 3;
 			break;
-		case 9:
+		case IDO_CND_CUR_PIC_EQ:
 			if (_rooms[_room].curPicture != command.script[offset + 1])
 				return false;
 			offset += 2;
 			break;
-		case 10:
+		case IDO_CND_ITEM_PIC_EQ:
 			if (_inventory[command.script[offset + 1] - 1].picture != command.script[offset + 2])
 				return false;
 			offset += 3;
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index fffe61e..e78d9ae 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -71,6 +71,42 @@ enum EngineString {
 	IDI_STR_TOTAL
 };
 
+// Conditional opcodes
+#define IDO_CND_ITEM_IN_ROOM   0x03
+#define IDO_CND_STEPS_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
+#define IDO_ACT_SAVE           0x0f
+#define IDO_ACT_LOAD           0x10
+#define IDO_ACT_RESTART        0x11
+#define IDO_ACT_SET_ITEM_POS   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
+
 struct Room {
 	byte description;
 	byte connections[6];


Commit: ede25c19bcedb802f3b0a7a1a5dc20238277012c
    https://github.com/scummvm/scummvm/commit/ede25c19bcedb802f3b0a7a1a5dc20238277012c
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Rename some #defines and variables for clarity

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 af71bba..eaffbb5 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -162,27 +162,27 @@ void AdlEngine::readCommands(Common::ReadStream &stream, Commands &commands) {
 }
 
 void AdlEngine::takeItem(byte noun) {
-	Common::Array<Item>::iterator it;
+	Common::Array<Item>::iterator item;
 
-	for (it = _inventory.begin(); it != _inventory.end(); ++it) {
-		if (it->noun != noun || it->room != _room)
+	for (item = _inventory.begin(); item != _inventory.end(); ++item) {
+		if (item->noun != noun || item->room != _room)
 			continue;
 
-		if (it->state == IDI_ITEM_DOESNT_MOVE) {
+		if (item->state == IDI_ITEM_DOESNT_MOVE) {
 			printEngineMessage(IDI_MSG_ITEM_DOESNT_MOVE);
 			return;
 		}
 
-		if (it->state == IDI_ITEM_MOVED) {
-			it->room = IDI_NONE;
+		if (item->state == IDI_ITEM_MOVED) {
+			item->room = IDI_NONE;
 			return;
 		}
 
-		Common::Array<byte>::const_iterator it2;
-		for (it2 = it->roomPictures.begin(); it->roomPictures.end(); ++it2) {
-			if (*it2 == _rooms[_room].curPicture) {
-				it->room = IDI_NONE;
-				it->state = IDI_ITEM_MOVED;
+		Common::Array<byte>::const_iterator pic;
+		for (pic = item->roomPictures.begin(); item->roomPictures.end(); ++pic) {
+			if (*pic == _rooms[_room].curPicture) {
+				item->room = IDI_NONE;
+				item->state = IDI_ITEM_MOVED;
 				return;
 			}
 		}
@@ -192,18 +192,17 @@ void AdlEngine::takeItem(byte noun) {
 }
 
 void AdlEngine::dropItem(byte noun) {
-	Common::Array<Item>::iterator it;
+	Common::Array<Item>::iterator item;
 
-	for (it = _inventory.begin(); it != _inventory.end(); ++it) {
-		if (it->noun != noun || it->room != IDI_NONE)
+	for (item = _inventory.begin(); item != _inventory.end(); ++item) {
+		if (item->noun != noun || item->room != IDI_NONE)
 			continue;
 
-		it->room = _room;
-		it->state = IDI_ITEM_MOVED;
+		item->room = _room;
+		item->state = IDI_ITEM_MOVED;
 		return;
 	}
 
-	// Don't understand
 	printEngineMessage(IDI_MSG_DONT_UNDERSTAND);
 }
 
@@ -223,11 +222,11 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			offset += 3;
 			break;
 		case IDO_ACT_LIST_ITEMS: {
-			Common::Array<Item>::const_iterator it;
+			Common::Array<Item>::const_iterator item;
 
-			for (it = _inventory.begin(); it != _inventory.end(); ++it)
-				if (it->room == IDI_NONE)
-					printMessage(it->description);
+			for (item = _inventory.begin(); item != _inventory.end(); ++item)
+				if (item->room == IDI_NONE)
+					printMessage(item->description);
 
 			++offset;
 			break;
@@ -282,7 +281,7 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			printEngineMessage(IDI_MSG_THANKS_FOR_PLAYING);
 			quitGame();
 			return;
-		case IDO_ACT_SET_ITEM_POS: {
+		case IDO_ACT_PLACE_ITEM: {
 			byte item = command.script[offset + 1] - 1;
 			_inventory[item].room = command.script[offset + 2];
 			_inventory[item].position.x = command.script[offset + 3];
@@ -384,20 +383,20 @@ bool AdlEngine::checkCommand(const Command &command, byte verb, byte noun) {
 }
 
 bool AdlEngine::doOneCommand(const Commands &commands, byte verb, byte noun) {
-	Commands::const_iterator it;
+	Commands::const_iterator cmd;
 
-	for (it = commands.begin(); it != commands.end(); ++it)
-		if (checkCommand(*it, verb, noun))
+	for (cmd = commands.begin(); cmd != commands.end(); ++cmd)
+		if (checkCommand(*cmd, verb, noun))
 			return true;
 
 	return false;
 }
 
 void AdlEngine::doAllCommands(const Commands &commands, byte verb, byte noun) {
-	Commands::const_iterator it;
+	Commands::const_iterator cmd;
 
-	for (it = commands.begin(); it != commands.end(); ++it)
-		checkCommand(*it, verb, noun);
+	for (cmd = commands.begin(); cmd != commands.end(); ++cmd)
+		checkCommand(*cmd, verb, noun);
 }
 
 void AdlEngine::clearScreen() {
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index e78d9ae..02207d9 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -94,7 +94,7 @@ enum EngineString {
 #define IDO_ACT_SAVE           0x0f
 #define IDO_ACT_LOAD           0x10
 #define IDO_ACT_RESTART        0x11
-#define IDO_ACT_SET_ITEM_POS   0x12
+#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
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 730f229..dde8ed0 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -218,34 +218,34 @@ void HiRes1Engine::drawPic(byte pic, byte xOffset, byte yOffset) {
 }
 
 void HiRes1Engine::drawItems() {
-	Common::Array<Item>::const_iterator it;
+	Common::Array<Item>::const_iterator item;
 
 	uint dropped = 0;
 
-	for (it = _inventory.begin(); it != _inventory.end(); ++it) {
-		if (it->room != _room)
+	for (item = _inventory.begin(); item != _inventory.end(); ++item) {
+		if (item->room != _room)
 			continue;
 
-		if (it->state == IDI_ITEM_MOVED) {
+		if (item->state == IDI_ITEM_MOVED) {
 			if (_rooms[_room].picture == _rooms[_room].curPicture) {
 				const Common::Point &p =  _itemOffsets[dropped];
-				if (it->isDrawing)
-					_display->drawRightAngles(_drawings[it->picture - 1], Common::Point(p.x, p.y), 0, 1, 0x7f);
+				if (item->isDrawing)
+					_display->drawRightAngles(_drawings[item->picture - 1], Common::Point(p.x, p.y), 0, 1, 0x7f);
 				else
-					drawPic(it->picture, p.x, p.y);
+					drawPic(item->picture, p.x, p.y);
 				++dropped;
 			}
 			continue;
 		}
 
-		Common::Array<byte>::const_iterator it2;
+		Common::Array<byte>::const_iterator pic;
 
-		for (it2 = it->roomPictures.begin(); it2 != it->roomPictures.end(); ++it2) {
-			if (*it2 == _rooms[_room].curPicture) {
-				if (it->isDrawing)
-					_display->drawRightAngles(_drawings[it->picture - 1], it->position, 0, 1, 0x7f);
+		for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
+			if (*pic == _rooms[_room].curPicture) {
+				if (item->isDrawing)
+					_display->drawRightAngles(_drawings[item->picture - 1], item->position, 0, 1, 0x7f);
 				else
-					drawPic(it->picture, it->position.x, it->position.y);
+					drawPic(item->picture, item->position.x, item->position.y);
 				continue;
 			}
 		}


Commit: 24c478c5ecd61d42a1456a7b8cbecec70e24cd1a
    https://github.com/scummvm/scummvm/commit/24c478c5ecd61d42a1456a7b8cbecec70e24cd1a
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Add ARG #define to improve readability

Changed paths:
    engines/adl/adl.cpp



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index eaffbb5..c46b747 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -206,19 +206,21 @@ void AdlEngine::dropItem(byte noun) {
 	printEngineMessage(IDI_MSG_DONT_UNDERSTAND);
 }
 
+#define ARG(N) (command.script[offset + N])
+
 void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 	for (uint i = 0; i < command.numAct; ++i) {
-		switch (command.script[offset]) {
+		switch (ARG(0)) {
 		case IDO_ACT_VAR_ADD:
-			_variables[command.script[offset + 2]] += command.script[offset + 1];
+			_variables[ARG(2)] += ARG(1);
 			offset += 3;
 			break;
 		case IDO_ACT_VAR_SUB:
-			_variables[command.script[offset + 2]] -= command.script[offset + 1];
+			_variables[ARG(2)] -= ARG(1);
 			offset += 3;
 			break;
 		case IDO_ACT_VAR_SET:
-			_variables[command.script[offset + 1]] = command.script[offset + 2];
+			_variables[ARG(1)] = ARG(2);
 			offset += 3;
 			break;
 		case IDO_ACT_LIST_ITEMS: {
@@ -232,24 +234,24 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			break;
 		}
 		case IDO_ACT_MOVE_ITEM:
-			_inventory[command.script[offset + 1] - 1].room = command.script[offset + 2];
+			_inventory[ARG(1) - 1].room = ARG(2);
 			offset += 3;
 			break;
 		case IDO_ACT_SET_ROOM:
 			_rooms[_room].curPicture = _rooms[_room].picture;
-			_room = command.script[offset + 1];
+			_room = ARG(1);
 			offset += 2;
 			break;
 		case IDO_ACT_SET_CUR_PIC:
-			_rooms[_room].curPicture = command.script[offset + 1];
+			_rooms[_room].curPicture = ARG(1);
 			offset += 2;
 			break;
 		case IDO_ACT_SET_PIC:
-			_rooms[_room].picture = _rooms[_room].curPicture = command.script[offset + 1];
+			_rooms[_room].picture = _rooms[_room].curPicture = ARG(1);
 			offset += 2;
 			break;
 		case IDO_ACT_PRINT_MSG:
-			printMessage(command.script[offset + 1]);
+			printMessage(ARG(1));
 			offset += 2;
 			break;
 		case IDO_ACT_SET_LIGHT:
@@ -281,20 +283,16 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			printEngineMessage(IDI_MSG_THANKS_FOR_PLAYING);
 			quitGame();
 			return;
-		case IDO_ACT_PLACE_ITEM: {
-			byte item = command.script[offset + 1] - 1;
-			_inventory[item].room = command.script[offset + 2];
-			_inventory[item].position.x = command.script[offset + 3];
-			_inventory[item].position.y = command.script[offset + 4];
+		case IDO_ACT_PLACE_ITEM:
+			_inventory[ARG(1) - 1].room = ARG(2);
+			_inventory[ARG(1) - 1].position.x = ARG(3);
+			_inventory[ARG(1) - 1].position.y = ARG(4);
 			offset += 5;
 			break;
-		}
-		case IDO_ACT_SET_ITEM_PIC: {
-			byte item = command.script[offset + 2] - 1;
-			_inventory[item].picture = command.script[offset + 1];
+		case IDO_ACT_SET_ITEM_PIC:
+			_inventory[ARG(2) - 1].picture = ARG(1);
 			offset += 3;
 			break;
-		}
 		case IDO_ACT_RESET_PIC:
 			_rooms[_room].curPicture = _rooms[_room].picture;
 			++offset;
@@ -305,7 +303,7 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 		case IDO_ACT_GO_WEST:
 		case IDO_ACT_GO_UP:
 		case IDO_ACT_GO_DOWN: {
-			byte room = _rooms[_room].connections[command.script[offset] - 0x15];
+			byte room = _rooms[_room].connections[ARG(0) - 0x15];
 
 			if (room == 0) {
 				printEngineMessage(IDI_MSG_CANT_GO_THERE);
@@ -325,11 +323,11 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			++offset;
 			break;
 		case IDO_ACT_SET_ROOM_PIC:
-			_rooms[command.script[offset + 1]].picture = _rooms[command.script[offset + 1]].curPicture = command.script[offset + 2];
+			_rooms[ARG(1)].picture = _rooms[ARG(1)].curPicture = ARG(2);
 			offset += 3;
 			break;
 		default:
-			error("Invalid action opcode %02x", command.script[offset]);
+			error("Invalid action opcode %02x", ARG(0));
 		}
 	}
 }
@@ -348,27 +346,27 @@ bool AdlEngine::checkCommand(const Command &command, byte verb, byte noun) {
 	for (uint i = 0; i < command.numCond; ++i) {
 		switch (command.script[offset]) {
 		case IDO_CND_ITEM_IN_ROOM:
-			if (_inventory[command.script[offset + 1] - 1].room != command.script[offset + 2])
+			if (_inventory[ARG(1) - 1].room != ARG(2))
 				return false;
 			offset += 3;
 			break;
 		case IDO_CND_STEPS_GE:
-			if (command.script[offset + 1] > _steps)
+			if (ARG(1) > _steps)
 				return false;
 			offset += 2;
 			break;
 		case IDO_CND_VAR_EQ:
-			if (_variables[command.script[offset + 1]] != command.script[offset + 2])
+			if (_variables[ARG(1)] != ARG(2))
 				return false;
 			offset += 3;
 			break;
 		case IDO_CND_CUR_PIC_EQ:
-			if (_rooms[_room].curPicture != command.script[offset + 1])
+			if (_rooms[_room].curPicture != ARG(1))
 				return false;
 			offset += 2;
 			break;
 		case IDO_CND_ITEM_PIC_EQ:
-			if (_inventory[command.script[offset + 1] - 1].picture != command.script[offset + 2])
+			if (_inventory[ARG(1) - 1].picture != ARG(2))
 				return false;
 			offset += 3;
 			break;
@@ -382,6 +380,8 @@ bool AdlEngine::checkCommand(const Command &command, byte verb, byte noun) {
 	return true;
 }
 
+#undef ARG
+
 bool AdlEngine::doOneCommand(const Commands &commands, byte verb, byte noun) {
 	Commands::const_iterator cmd;
 


Commit: 34cb2f4c53280d5b1f10ded5951d0ca5c0bf754d
    https://github.com/scummvm/scummvm/commit/34cb2f4c53280d5b1f10ded5951d0ca5c0bf754d
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Move functionality into base class

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



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index c46b747..9676924 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -206,7 +206,7 @@ void AdlEngine::dropItem(byte noun) {
 	printEngineMessage(IDI_MSG_DONT_UNDERSTAND);
 }
 
-#define ARG(N) (command.script[offset + N])
+#define ARG(N) (command.script[offset + (N)])
 
 void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 	for (uint i = 0; i < command.numAct; ++i) {
@@ -404,6 +404,51 @@ void AdlEngine::clearScreen() {
 	_display->clear(0x00);
 }
 
+void AdlEngine::drawItems() {
+	Common::Array<Item>::const_iterator item;
+
+	uint dropped = 0;
+
+	for (item = _inventory.begin(); item != _inventory.end(); ++item) {
+		if (item->room != _room)
+			continue;
+
+		if (item->state == IDI_ITEM_MOVED) {
+			if (_rooms[_room].picture == _rooms[_room].curPicture) {
+				const Common::Point &p =  _itemOffsets[dropped];
+				if (item->isDrawing)
+					_display->drawRightAngles(_drawings[item->picture - 1], p, 0, 1, 0x7f);
+				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 == _rooms[_room].curPicture) {
+				if (item->isDrawing)
+					_display->drawRightAngles(_drawings[item->picture - 1], item->position, 0, 1, 0x7f);
+				else
+					drawPic(item->picture, item->position);
+				continue;
+			}
+		}
+	}
+}
+
+void AdlEngine::showRoom() {
+	if (!_isDark) {
+		drawPic(_rooms[_room].curPicture);
+		drawItems();
+	}
+
+	_display->decodeFrameBuffer();
+	printMessage(_rooms[_room].description, false);
+}
+
 AdlEngine *AdlEngine::create(GameType type, OSystem *syst, const AdlGameDescription *gd) {
 	switch(type) {
 	case kGameTypeHires1:
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 02207d9..a030059 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -174,6 +174,9 @@ protected:
 	void doAllCommands(const Commands &commands, byte verb, byte noun);
 	void doActions(const Command &command, byte noun, byte offset);
 	void clearScreen();
+	virtual void drawPic(byte pic, Common::Point pos = Common::Point()) = 0;
+	void drawItems();
+	void showRoom();
 	void takeItem(byte noun);
 	void dropItem(byte noun);
 
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index dde8ed0..64ae81f 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -169,7 +169,7 @@ void HiRes1Engine::runIntro() {
 	}
 }
 
-void HiRes1Engine::drawPic(Common::ReadStream &stream, byte xOffset, byte yOffset) {
+void HiRes1Engine::drawPic(Common::ReadStream &stream, Common::Point pos) {
 	byte x, y;
 	bool bNewLine = false;
 	byte oldX = 0, oldY = 0;
@@ -188,8 +188,8 @@ void HiRes1Engine::drawPic(Common::ReadStream &stream, byte xOffset, byte yOffse
 			continue;
 		}
 
-		x += xOffset;
-		y += yOffset;
+		x += pos.x;
+		y += pos.y;
 
 		if (y > 160)
 			y = 160;
@@ -206,7 +206,7 @@ void HiRes1Engine::drawPic(Common::ReadStream &stream, byte xOffset, byte yOffse
 	}
 }
 
-void HiRes1Engine::drawPic(byte pic, byte xOffset, byte yOffset) {
+void HiRes1Engine::drawPic(byte pic, Common::Point pos) {
 	Common::File f;
 	Common::String name = Common::String::format("BLOCK%i", _pictures[pic].block);
 
@@ -214,52 +214,7 @@ void HiRes1Engine::drawPic(byte pic, byte xOffset, byte yOffset) {
 		error("Failed to open file");
 
 	f.seek(_pictures[pic].offset);
-	drawPic(f, xOffset, yOffset);
-}
-
-void HiRes1Engine::drawItems() {
-	Common::Array<Item>::const_iterator item;
-
-	uint dropped = 0;
-
-	for (item = _inventory.begin(); item != _inventory.end(); ++item) {
-		if (item->room != _room)
-			continue;
-
-		if (item->state == IDI_ITEM_MOVED) {
-			if (_rooms[_room].picture == _rooms[_room].curPicture) {
-				const Common::Point &p =  _itemOffsets[dropped];
-				if (item->isDrawing)
-					_display->drawRightAngles(_drawings[item->picture - 1], Common::Point(p.x, p.y), 0, 1, 0x7f);
-				else
-					drawPic(item->picture, p.x, p.y);
-				++dropped;
-			}
-			continue;
-		}
-
-		Common::Array<byte>::const_iterator pic;
-
-		for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
-			if (*pic == _rooms[_room].curPicture) {
-				if (item->isDrawing)
-					_display->drawRightAngles(_drawings[item->picture - 1], item->position, 0, 1, 0x7f);
-				else
-					drawPic(item->picture, item->position.x, item->position.y);
-				continue;
-			}
-		}
-	}
-}
-
-void HiRes1Engine::showRoom() {
-	if (!_isDark) {
-		drawPic(_rooms[_room].curPicture, 0, 0);
-		drawItems();
-	}
-
-	_display->decodeFrameBuffer();
-	printMessage(_rooms[_room].description, false);
+	drawPic(f, pos);
 }
 
 void HiRes1Engine::runGame() {
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index 19aa55e..4bd0a87 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -53,10 +53,9 @@ private:
 	uint getEngineMessage(EngineMessage msg);
 
 	void runIntro();
-	void drawPic(Common::ReadStream &stream, byte xOffset, byte yOffset);
-	void showRoom();
+	void drawPic(Common::ReadStream &stream, Common::Point pos);
 	void drawItems();
-	void drawPic(byte pic, byte xOffset, byte yOffset);
+	void drawPic(byte pic, Common::Point pos);
 };
 
 } // End of namespace Adl


Commit: 1abaf60cf04c5bc2bf8a3fb37aa8dd83816a7771
    https://github.com/scummvm/scummvm/commit/1abaf60cf04c5bc2bf8a3fb37aa8dd83816a7771
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Rename rightAngles to lineArt

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



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 9676924..d93b771 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -416,8 +416,8 @@ void AdlEngine::drawItems() {
 		if (item->state == IDI_ITEM_MOVED) {
 			if (_rooms[_room].picture == _rooms[_room].curPicture) {
 				const Common::Point &p =  _itemOffsets[dropped];
-				if (item->isDrawing)
-					_display->drawRightAngles(_drawings[item->picture - 1], p, 0, 1, 0x7f);
+				if (item->isLineArt)
+					_display->drawLineArt(_lineArt[item->picture - 1], p);
 				else
 					drawPic(item->picture, p);
 				++dropped;
@@ -429,8 +429,8 @@ void AdlEngine::drawItems() {
 
 		for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
 			if (*pic == _rooms[_room].curPicture) {
-				if (item->isDrawing)
-					_display->drawRightAngles(_drawings[item->picture - 1], item->position, 0, 1, 0x7f);
+				if (item->isLineArt)
+					_display->drawLineArt(_lineArt[item->picture - 1], item->position);
 				else
 					drawPic(item->picture, item->position);
 				continue;
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index a030059..5335211 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -138,7 +138,7 @@ struct Item {
 	byte noun;
 	byte room;
 	byte picture;
-	bool isDrawing;
+	bool isLineArt;
 	Common::Point position;
 	int state;
 	byte description;
@@ -188,7 +188,7 @@ protected:
 	Common::Array<Picture> _pictures;
 	Common::Array<Item> _inventory;
 	Common::Array<Common::Point> _itemOffsets;
-	Common::Array<Common::Array<byte> > _drawings;
+	Common::Array<Common::Array<byte> > _lineArt;
 	Commands _roomCommands;
 	Commands _globalCommands;
 
diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp
index 47b1533..8ea0a7b 100644
--- a/engines/adl/display.cpp
+++ b/engines/adl/display.cpp
@@ -304,7 +304,7 @@ void Display::drawNextPixel(Display::PixelPos &p, byte &color, byte bits, byte q
 		moveY(p, bits & 2);
 }
 
-void Display::drawRightAngles(Common::Array<byte> &rightAngles, Common::Point p, byte rotation, byte scaling, byte color) {
+void Display::drawLineArt(const Common::Array<byte> &lineArt, Common::Point p, byte rotation, byte scaling, byte color) {
 	const byte stepping[] = {
 		0xff, 0xfe, 0xfa, 0xf4, 0xec, 0xe1, 0xd4, 0xc5,
 		0xb4, 0xa1, 0x8d, 0x78, 0x61, 0x49, 0x31, 0x18,
@@ -319,8 +319,8 @@ void Display::drawRightAngles(Common::Array<byte> &rightAngles, Common::Point p,
 	byte xStep = stepping[rotation];
 	byte yStep = stepping[(rotation ^ 0xf) + 1] + 1;
 
-	for (uint i = 0; i < rightAngles.size(); ++i) {
-		byte b = rightAngles[i];
+	for (uint i = 0; i < lineArt.size(); ++i) {
+		byte b = lineArt[i];
 
 		do {
 			byte xFrac = 0x80;
diff --git a/engines/adl/display.h b/engines/adl/display.h
index 62294d3..229446f 100644
--- a/engines/adl/display.h
+++ b/engines/adl/display.h
@@ -63,7 +63,7 @@ public:
 	void drawPixel(byte x, byte y, byte color);
 	void drawLine(Common::Point p1, Common::Point p2, byte color);
 	void clear(byte color);
-	void drawRightAngles(Common::Array<byte> &rightAngles, Common::Point p, byte rotation, byte scaling, byte color);
+	void drawLineArt(const Common::Array<byte> &lineArt, Common::Point p, byte rotation = 0, byte scaling = 1, byte color = 0x7f);
 
 private:
 	enum {
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 64ae81f..9163875 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -261,7 +261,7 @@ void HiRes1Engine::runGame() {
 		item.noun = f.readByte();
 		item.room = f.readByte();
 		item.picture = f.readByte();
-		item.isDrawing = f.readByte();
+		item.isLineArt = f.readByte();
 		item.position.x = f.readByte();
 		item.position.y = f.readByte();
 		item.state = f.readByte();
@@ -302,21 +302,21 @@ void HiRes1Engine::runGame() {
 		_itemOffsets.push_back(p);
 	}
 
-	// Load right-angle drawings
+	// Load right-angle line art
 	f.seek(0x4f00);
-	uint16 drawingsTotal = f.readUint16LE();
-	for (uint i = 0; i < drawingsTotal; ++i) {
+	uint16 lineArtTotal = f.readUint16LE();
+	for (uint i = 0; i < lineArtTotal; ++i) {
 		f.seek(0x4f00 + 2 + i * 2);
 		uint16 offset = f.readUint16LE();
 		f.seek(0x4f00 + offset);
 
-		Common::Array<byte> drawing;
+		Common::Array<byte> lineArt;
 		byte b = f.readByte();
 		while (b != 0) {
-			drawing.push_back(b);
+			lineArt.push_back(b);
 			b = f.readByte();
 		}
-		_drawings.push_back(drawing);
+		_lineArt.push_back(lineArt);
 	}
 
 	// Title screen shown during loading


Commit: dc2e5e09ba045474284521e8db4ff7e40b0fe68a
    https://github.com/scummvm/scummvm/commit/dc2e5e09ba045474284521e8db4ff7e40b0fe68a
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Put state-related members in _state struct

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



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index d93b771..e395c82 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -43,10 +43,7 @@ AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) :
 		Engine(syst),
 		_gameDescription(gd),
 		_display(nullptr),
-		_parser(nullptr),
-		_room(1),
-		_steps(0),
-		_isDark(false) {
+		_parser(nullptr) {
 }
 
 AdlEngine::~AdlEngine() {
@@ -164,8 +161,8 @@ void AdlEngine::readCommands(Common::ReadStream &stream, Commands &commands) {
 void AdlEngine::takeItem(byte noun) {
 	Common::Array<Item>::iterator item;
 
-	for (item = _inventory.begin(); item != _inventory.end(); ++item) {
-		if (item->noun != noun || item->room != _room)
+	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) {
@@ -180,7 +177,7 @@ void AdlEngine::takeItem(byte noun) {
 
 		Common::Array<byte>::const_iterator pic;
 		for (pic = item->roomPictures.begin(); item->roomPictures.end(); ++pic) {
-			if (*pic == _rooms[_room].curPicture) {
+			if (*pic == _state.rooms[_state.room].curPicture) {
 				item->room = IDI_NONE;
 				item->state = IDI_ITEM_MOVED;
 				return;
@@ -194,11 +191,11 @@ void AdlEngine::takeItem(byte noun) {
 void AdlEngine::dropItem(byte noun) {
 	Common::Array<Item>::iterator item;
 
-	for (item = _inventory.begin(); item != _inventory.end(); ++item) {
+	for (item = _state.items.begin(); item != _state.items.end(); ++item) {
 		if (item->noun != noun || item->room != IDI_NONE)
 			continue;
 
-		item->room = _room;
+		item->room = _state.room;
 		item->state = IDI_ITEM_MOVED;
 		return;
 	}
@@ -212,21 +209,21 @@ 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:
-			_variables[ARG(2)] += ARG(1);
+			_state.vars[ARG(2)] += ARG(1);
 			offset += 3;
 			break;
 		case IDO_ACT_VAR_SUB:
-			_variables[ARG(2)] -= ARG(1);
+			_state.vars[ARG(2)] -= ARG(1);
 			offset += 3;
 			break;
 		case IDO_ACT_VAR_SET:
-			_variables[ARG(1)] = ARG(2);
+			_state.vars[ARG(1)] = ARG(2);
 			offset += 3;
 			break;
 		case IDO_ACT_LIST_ITEMS: {
 			Common::Array<Item>::const_iterator item;
 
-			for (item = _inventory.begin(); item != _inventory.end(); ++item)
+			for (item = _state.items.begin(); item != _state.items.end(); ++item)
 				if (item->room == IDI_NONE)
 					printMessage(item->description);
 
@@ -234,20 +231,20 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			break;
 		}
 		case IDO_ACT_MOVE_ITEM:
-			_inventory[ARG(1) - 1].room = ARG(2);
+			_state.items[ARG(1) - 1].room = ARG(2);
 			offset += 3;
 			break;
 		case IDO_ACT_SET_ROOM:
-			_rooms[_room].curPicture = _rooms[_room].picture;
-			_room = ARG(1);
+			_state.rooms[_state.room].curPicture = _state.rooms[_state.room].picture;
+			_state.room = ARG(1);
 			offset += 2;
 			break;
 		case IDO_ACT_SET_CUR_PIC:
-			_rooms[_room].curPicture = ARG(1);
+			_state.rooms[_state.room].curPicture = ARG(1);
 			offset += 2;
 			break;
 		case IDO_ACT_SET_PIC:
-			_rooms[_room].picture = _rooms[_room].curPicture = ARG(1);
+			_state.rooms[_state.room].picture = _state.rooms[_state.room].curPicture = ARG(1);
 			offset += 2;
 			break;
 		case IDO_ACT_PRINT_MSG:
@@ -255,11 +252,11 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			offset += 2;
 			break;
 		case IDO_ACT_SET_LIGHT:
-			_isDark = false;
+			_state.isDark = false;
 			++offset;
 			break;
 		case IDO_ACT_SET_DARK:
-			_isDark = true;
+			_state.isDark = true;
 			++offset;
 			break;
 		case IDO_ACT_SAVE:
@@ -284,17 +281,17 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			quitGame();
 			return;
 		case IDO_ACT_PLACE_ITEM:
-			_inventory[ARG(1) - 1].room = ARG(2);
-			_inventory[ARG(1) - 1].position.x = ARG(3);
-			_inventory[ARG(1) - 1].position.y = ARG(4);
+			_state.items[ARG(1) - 1].room = ARG(2);
+			_state.items[ARG(1) - 1].position.x = ARG(3);
+			_state.items[ARG(1) - 1].position.y = ARG(4);
 			offset += 5;
 			break;
 		case IDO_ACT_SET_ITEM_PIC:
-			_inventory[ARG(2) - 1].picture = ARG(1);
+			_state.items[ARG(2) - 1].picture = ARG(1);
 			offset += 3;
 			break;
 		case IDO_ACT_RESET_PIC:
-			_rooms[_room].curPicture = _rooms[_room].picture;
+			_state.rooms[_state.room].curPicture = _state.rooms[_state.room].picture;
 			++offset;
 			break;
 		case IDO_ACT_GO_NORTH:
@@ -303,15 +300,15 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 		case IDO_ACT_GO_WEST:
 		case IDO_ACT_GO_UP:
 		case IDO_ACT_GO_DOWN: {
-			byte room = _rooms[_room].connections[ARG(0) - 0x15];
+			byte room = _state.rooms[_state.room].connections[ARG(0) - 0x15];
 
 			if (room == 0) {
 				printEngineMessage(IDI_MSG_CANT_GO_THERE);
 				return;
 			}
 
-			_rooms[_room].curPicture = _rooms[_room].picture;
-			_room = room;
+			_state.rooms[_state.room].curPicture = _state.rooms[_state.room].picture;
+			_state.room = room;
 			return;
 		}
 		case IDO_ACT_TAKE_ITEM:
@@ -323,7 +320,7 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			++offset;
 			break;
 		case IDO_ACT_SET_ROOM_PIC:
-			_rooms[ARG(1)].picture = _rooms[ARG(1)].curPicture = ARG(2);
+			_state.rooms[ARG(1)].picture = _state.rooms[ARG(1)].curPicture = ARG(2);
 			offset += 3;
 			break;
 		default:
@@ -333,7 +330,7 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 }
 
 bool AdlEngine::checkCommand(const Command &command, byte verb, byte noun) {
-	if (command.room != IDI_NONE && command.room != _room)
+	if (command.room != IDI_NONE && command.room != _state.room)
 		return false;
 
 	if (command.verb != IDI_NONE && command.verb != verb)
@@ -346,27 +343,27 @@ bool AdlEngine::checkCommand(const Command &command, byte verb, byte noun) {
 	for (uint i = 0; i < command.numCond; ++i) {
 		switch (command.script[offset]) {
 		case IDO_CND_ITEM_IN_ROOM:
-			if (_inventory[ARG(1) - 1].room != ARG(2))
+			if (_state.items[ARG(1) - 1].room != ARG(2))
 				return false;
 			offset += 3;
 			break;
-		case IDO_CND_STEPS_GE:
-			if (ARG(1) > _steps)
+		case IDO_CND_MOVES_GE:
+			if (ARG(1) > _state.moves)
 				return false;
 			offset += 2;
 			break;
 		case IDO_CND_VAR_EQ:
-			if (_variables[ARG(1)] != ARG(2))
+			if (_state.vars[ARG(1)] != ARG(2))
 				return false;
 			offset += 3;
 			break;
 		case IDO_CND_CUR_PIC_EQ:
-			if (_rooms[_room].curPicture != ARG(1))
+			if (_state.rooms[_state.room].curPicture != ARG(1))
 				return false;
 			offset += 2;
 			break;
 		case IDO_CND_ITEM_PIC_EQ:
-			if (_inventory[ARG(1) - 1].picture != ARG(2))
+			if (_state.items[ARG(1) - 1].picture != ARG(2))
 				return false;
 			offset += 3;
 			break;
@@ -409,12 +406,12 @@ void AdlEngine::drawItems() {
 
 	uint dropped = 0;
 
-	for (item = _inventory.begin(); item != _inventory.end(); ++item) {
-		if (item->room != _room)
+	for (item = _state.items.begin(); item != _state.items.end(); ++item) {
+		if (item->room != _state.room)
 			continue;
 
 		if (item->state == IDI_ITEM_MOVED) {
-			if (_rooms[_room].picture == _rooms[_room].curPicture) {
+			if (_state.rooms[_state.room].picture == _state.rooms[_state.room].curPicture) {
 				const Common::Point &p =  _itemOffsets[dropped];
 				if (item->isLineArt)
 					_display->drawLineArt(_lineArt[item->picture - 1], p);
@@ -428,7 +425,7 @@ void AdlEngine::drawItems() {
 		Common::Array<byte>::const_iterator pic;
 
 		for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
-			if (*pic == _rooms[_room].curPicture) {
+			if (*pic == _state.rooms[_state.room].curPicture) {
 				if (item->isLineArt)
 					_display->drawLineArt(_lineArt[item->picture - 1], item->position);
 				else
@@ -440,13 +437,13 @@ void AdlEngine::drawItems() {
 }
 
 void AdlEngine::showRoom() {
-	if (!_isDark) {
-		drawPic(_rooms[_room].curPicture);
+	if (!_state.isDark) {
+		drawPic(_state.rooms[_state.room].curPicture);
 		drawItems();
 	}
 
 	_display->decodeFrameBuffer();
-	printMessage(_rooms[_room].description, false);
+	printMessage(_state.rooms[_state.room].description, false);
 }
 
 AdlEngine *AdlEngine::create(GameType type, OSystem *syst, const AdlGameDescription *gd) {
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 5335211..d39e0e3 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -73,7 +73,7 @@ enum EngineString {
 
 // Conditional opcodes
 #define IDO_CND_ITEM_IN_ROOM   0x03
-#define IDO_CND_STEPS_GE       0x05
+#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
@@ -145,6 +145,18 @@ struct Item {
 	Common::Array<byte> roomPictures;
 };
 
+struct State {
+	Common::Array<Room> rooms;
+	Common::Array<Item> items;
+	Common::Array<byte> vars;
+
+	byte room;
+	uint16 moves;
+	bool isDark;
+
+	State() : room(1), moves(0), isDark(false) { }
+};
+
 typedef Common::List<Command> Commands;
 
 class AdlEngine : public Engine {
@@ -186,18 +198,13 @@ protected:
 	Common::Array<Common::String> _strings;
 	Common::Array<Common::String> _messages;
 	Common::Array<Picture> _pictures;
-	Common::Array<Item> _inventory;
 	Common::Array<Common::Point> _itemOffsets;
 	Common::Array<Common::Array<byte> > _lineArt;
 	Commands _roomCommands;
 	Commands _globalCommands;
 
 	// Game state
-	Common::Array<Room> _rooms;
-	byte _room;
-	uint16 _steps;
-	Common::Array<byte> _variables;
-	bool _isDark;
+	State _state;
 
 private:
 	void printEngineMessage(EngineMessage);
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 9163875..1316bf2 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -84,7 +84,6 @@ static const StringOffset stringOffsets[] = {
 
 HiRes1Engine::HiRes1Engine(OSystem *syst, const AdlGameDescription *gd) :
 		AdlEngine(syst, gd) {
-	_variables.resize(20);
 }
 
 void HiRes1Engine::runIntro() {
@@ -217,47 +216,38 @@ void HiRes1Engine::drawPic(byte pic, Common::Point pos) {
 	drawPic(f, pos);
 }
 
-void HiRes1Engine::runGame() {
-	runIntro();
-	_display->printASCIIString("\r");
-
+void HiRes1Engine::initState() {
 	Common::File f;
 
-	if (!f.open("MESSAGES"))
-		error("Failed to open file");
+	_state.room = 1;
+	_state.moves = 0;
+	_state.isDark = false;
 
-	while (!f.eos() && !f.err())
-		_messages.push_back(readString(f, APPLECHAR('\r')) + APPLECHAR('\r'));
-
-	f.close();
+	_state.vars.clear();
+	_state.vars.resize(20);
 
 	if (!f.open("ADVENTURE"))
 		error("Failed to open file");
 
-	// Load strings from executable
-	_strings.resize(IDI_HR1_STR_TOTAL);
-	for (uint idx = 0; idx < IDI_HR1_STR_TOTAL; ++idx) {
-		f.seek(stringOffsets[idx].offset);
-		_strings[stringOffsets[idx].stringIdx] = readString(f);
-	}
-
 	// Load room data from executable
+	_state.rooms.clear();
 	f.seek(1280);
 	for (uint i = 0; i < MH_ROOMS; ++i) {
-		struct Room room;
+		Room room;
 		f.readByte();
 		room.description = f.readByte();
 		for (uint j = 0; j < 6; ++j)
 			room.connections[j] = f.readByte();
 		room.picture = f.readByte();
 		room.curPicture = f.readByte();
-		_rooms.push_back(room);
+		_state.rooms.push_back(room);
 	}
 
 	// Load inventory data from executable
+	_state.items.clear();
 	f.seek(0x100);
 	while (f.readByte() != 0xff) {
-		struct Item item;
+		Item item;
 		item.noun = f.readByte();
 		item.room = f.readByte();
 		item.picture = f.readByte();
@@ -274,7 +264,34 @@ void HiRes1Engine::runGame() {
 		for (uint i = 0; i < size; ++i)
 			item.roomPictures.push_back(f.readByte());
 
-		_inventory.push_back(item);
+		_state.items.push_back(item);
+	}
+}
+
+void HiRes1Engine::runGame() {
+	runIntro();
+	_display->printASCIIString("\r");
+
+	Common::File f;
+
+	if (!f.open("MESSAGES"))
+		error("Failed to open file");
+
+	while (!f.eos() && !f.err())
+		_messages.push_back(readString(f, APPLECHAR('\r')) + APPLECHAR('\r'));
+
+	f.close();
+
+	initState();
+
+	if (!f.open("ADVENTURE"))
+		error("Failed to open file");
+
+	// Load strings from executable
+	_strings.resize(IDI_HR1_STR_TOTAL);
+	for (uint idx = 0; idx < IDI_HR1_STR_TOTAL; ++idx) {
+		f.seek(stringOffsets[idx].offset);
+		_strings[stringOffsets[idx].stringIdx] = readString(f);
 	}
 
 	// Load picture data from executable
@@ -341,7 +358,7 @@ void HiRes1Engine::runGame() {
 			printMessage(37);
 		doAllCommands(_globalCommands, verb, noun);
 
-		_steps++;
+		_state.moves++;
 
 		if (shouldQuit())
 			return;
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index 4bd0a87..5cc9f3a 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -52,6 +52,7 @@ private:
 	void printMessage(uint idx, bool wait = true);
 	uint getEngineMessage(EngineMessage msg);
 
+	void initState();
 	void runIntro();
 	void drawPic(Common::ReadStream &stream, Common::Point pos);
 	void drawItems();


Commit: 301b2fdc219ecc92cc81cc94d8e2904fc21cec6e
    https://github.com/scummvm/scummvm/commit/301b2fdc219ecc92cc81cc94d8e2904fc21cec6e
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Remove leftover debug code

Changed paths:
    engines/adl/display.cpp



diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp
index 8ea0a7b..05e7c2e 100644
--- a/engines/adl/display.cpp
+++ b/engines/adl/display.cpp
@@ -82,29 +82,6 @@ Display::Display() :
 	_textBufSurface->create(kWidth * 2, kHeight * 2, Graphics::PixelFormat::createFormatCLUT8());
 
 	createFont();
-
-	struct PixelPos rel = getPixelPos(0, 191);
-	struct PixelPos absy;
-	for (int i = 191; i >= 0; --i) {
-		absy = getPixelPos(0, i);
-		if (absy.rowAddr != rel.rowAddr)
-			debug("%i: %04x %04x", i, absy.rowAddr, rel.rowAddr);
-		moveY(rel, false);
-	}
-	absy = getPixelPos(0, 191);
-	if (absy.rowAddr != rel.rowAddr)
-		debug("%i: %04x %04x", 191, absy.rowAddr, rel.rowAddr);
-
-	rel = getPixelPos(0, 0);
-	for (int i = 0; i < 192; ++i) {
-		absy = getPixelPos(0, i);
-		if (absy.rowAddr != rel.rowAddr)
-			debug("%i: %04x %04x", i, absy.rowAddr, rel.rowAddr);
-		moveY(rel, true);
-	}
-	absy = getPixelPos(0, 0);
-	if (absy.rowAddr != rel.rowAddr)
-		debug("%i: %04x %04x", 191, absy.rowAddr, rel.rowAddr);
 }
 
 Display::~Display() {


Commit: 727469d4a7ad9ba516538009efdac3834a6daccd
    https://github.com/scummvm/scummvm/commit/727469d4a7ad9ba516538009efdac3834a6daccd
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Add restarting

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



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index e395c82..24a18d6 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -43,7 +43,8 @@ AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) :
 		Engine(syst),
 		_gameDescription(gd),
 		_display(nullptr),
-		_parser(nullptr) {
+		_parser(nullptr),
+		_isRestarting(false) {
 }
 
 AdlEngine::~AdlEngine() {
@@ -271,7 +272,8 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			_display->printString(_strings[IDI_STR_PLAY_AGAIN]);
 			Common::String input = _display->inputString();
 			if (input.size() == 0 || input[0] != APPLECHAR('N')) {
-				warning("Restart game not implemented");
+				_isRestarting = true;
+				restartGame();
 				return;
 			}
 			// Fall-through
@@ -392,8 +394,11 @@ bool AdlEngine::doOneCommand(const Commands &commands, byte verb, byte noun) {
 void AdlEngine::doAllCommands(const Commands &commands, byte verb, byte noun) {
 	Commands::const_iterator cmd;
 
-	for (cmd = commands.begin(); cmd != commands.end(); ++cmd)
+	for (cmd = commands.begin(); cmd != commands.end(); ++cmd) {
 		checkCommand(*cmd, verb, noun);
+		if (_isRestarting)
+			return;
+	}
 }
 
 void AdlEngine::clearScreen() {
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index d39e0e3..8b0aa45 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -175,6 +175,8 @@ public:
 
 protected:
 	virtual void runGame() = 0;
+	virtual void initState() = 0;
+	virtual void restartGame() = 0;
 	virtual uint getEngineMessage(EngineMessage msg) = 0;
 	Common::String readString(Common::ReadStream &stream, byte until = 0);
 	void printStrings(Common::SeekableReadStream &stream, int count = 1);
@@ -194,6 +196,7 @@ protected:
 
 	Display *_display;
 	Parser *_parser;
+	bool _isRestarting;
 
 	Common::Array<Common::String> _strings;
 	Common::Array<Common::String> _messages;
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 1316bf2..4cf7b45 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -56,6 +56,7 @@ enum {
 	IDI_HR1_STR_DONT_HAVE_IT,
 	IDI_HR1_STR_DONT_UNDERSTAND,
 	IDI_HR1_STR_GETTING_DARK,
+	IDI_HR1_STR_PRESS_RETURN,
 
 	IDI_HR1_STR_TOTAL
 };
@@ -69,7 +70,8 @@ static const StringOffset stringOffsets[] = {
 	{ IDI_HR1_STR_CANT_GO_THERE,   0x6c0a },
 	{ IDI_HR1_STR_DONT_HAVE_IT,    0x6c31 },
 	{ IDI_HR1_STR_DONT_UNDERSTAND, 0x6c51 },
-	{ IDI_HR1_STR_GETTING_DARK,    0x6c7c }
+	{ IDI_HR1_STR_GETTING_DARK,    0x6c7c },
+	{ IDI_HR1_STR_PRESS_RETURN,    0x5f68 }
 };
 
 #define IDI_HR1_OFS_PD_TEXT_0 0x5d
@@ -268,6 +270,13 @@ void HiRes1Engine::initState() {
 	}
 }
 
+void HiRes1Engine::restartGame() {
+	initState();
+	_display->printString(_strings[IDI_HR1_STR_PRESS_RETURN]);
+	_display->inputString(); // Missing in the original
+	_display->printASCIIString("\r\r\r\r\r");
+}
+
 void HiRes1Engine::runGame() {
 	runIntro();
 	_display->printASCIIString("\r");
@@ -348,7 +357,12 @@ void HiRes1Engine::runGame() {
 	f.seek(0xf00);
 	_parser->loadNouns(f);
 
+	_display->printASCIIString("\r\r\r\r\r");
+
 	while (1) {
+		if (_isRestarting)
+			_isRestarting = false;
+
 		uint verb = 0, noun = 0;
 		clearScreen();
 		showRoom();
@@ -356,8 +370,15 @@ void HiRes1Engine::runGame() {
 
 		if (!doOneCommand(_roomCommands, verb, noun))
 			printMessage(37);
+
+		if (_isRestarting)
+			continue;
+
 		doAllCommands(_globalCommands, verb, noun);
 
+		if (_isRestarting)
+			continue;
+
 		_state.moves++;
 
 		if (shouldQuit())
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index 5cc9f3a..a378dc9 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -49,6 +49,7 @@ private:
 		MH_ITEM_OFFSETS = 21
 	};
 
+	void restartGame();
 	void printMessage(uint idx, bool wait = true);
 	uint getEngineMessage(EngineMessage msg);
 


Commit: e3d13d06ee32fa1cb3663c0e9c46f356f08b5c9b
    https://github.com/scummvm/scummvm/commit/e3d13d06ee32fa1cb3663c0e9c46f356f08b5c9b
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Add save game support

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



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 24a18d6..9c86b3a 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -28,6 +28,7 @@
 #include "common/system.h"
 #include "common/events.h"
 #include "common/stream.h"
+#include "common/savefile.h"
 
 #include "engines/util.h"
 
@@ -261,18 +262,21 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			++offset;
 			break;
 		case IDO_ACT_SAVE:
-			warning("Save game not implemented");
+			saveState(0);
 			++offset;
 			break;
 		case IDO_ACT_LOAD:
-			warning("Load game not implemented");
+			loadState(0);
 			++offset;
+			// Original engine continues processing here (?)
 			break;
 		case IDO_ACT_RESTART: {
 			_display->printString(_strings[IDI_STR_PLAY_AGAIN]);
 			Common::String input = _display->inputString();
 			if (input.size() == 0 || input[0] != APPLECHAR('N')) {
 				_isRestarting = true;
+				_display->clear(0x00);
+				_display->decodeFrameBuffer();
 				restartGame();
 				return;
 			}
@@ -451,6 +455,116 @@ void AdlEngine::showRoom() {
 	printMessage(_state.rooms[_state.room].description, false);
 }
 
+bool AdlEngine::saveState(uint slot) {
+	Common::String fileName = Common::String::format("%s.s%02d", _targetName.c_str(), slot);
+	Common::OutSaveFile *outFile = getSaveFileManager()->openForSaving(fileName);
+
+	if (!outFile) {
+		warning("Failed to open file '%s'", fileName.c_str());
+		return false;
+	}
+
+	outFile->writeUint32BE(getTag());
+	outFile->writeByte(SAVEGAME_VERSION);
+
+	outFile->writeByte(_state.room);
+	outFile->writeByte(_state.moves);
+	outFile->writeByte(_state.isDark);
+
+	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->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);
+	}
+
+	outFile->writeUint32BE(_state.vars.size());
+	for (uint i = 0; i < _state.vars.size(); ++i)
+		outFile->writeByte(_state.vars[i]);
+
+	outFile->finalize();
+
+	if (outFile->err()) {
+		delete outFile;
+		warning("Failed to save game '%s'", fileName.c_str());
+		return false;
+	}
+
+	delete outFile;
+	return true;
+}
+
+bool AdlEngine::loadState(uint slot) {
+	Common::String fileName = Common::String::format("%s.s%02d", _targetName.c_str(), slot);
+	Common::InSaveFile *inFile = getSaveFileManager()->openForLoading(fileName);
+
+	if (!inFile) {
+		warning("Failed to open file '%s'", fileName.c_str());
+		return false;
+	}
+
+	if (inFile->readUint32BE() != getTag()) {
+		warning("No header found in '%s'", fileName.c_str());
+		delete inFile;
+		return false;
+	}
+
+	byte saveVersion = inFile->readByte();
+	if (saveVersion != SAVEGAME_VERSION) {
+		warning("Save game version %i not supported", saveVersion);
+		delete inFile;
+		return false;
+	}
+
+	initState();
+
+	_state.room = inFile->readByte();
+	_state.moves = inFile->readByte();
+	_state.isDark = inFile->readByte();
+
+	uint32 size = inFile->readUint32BE();
+	if (size != _state.rooms.size())
+		error("Room count mismatch (expected %i; found %i)", _state.rooms.size(), size);
+
+	for (uint i = 0; i < size; ++i) {
+		_state.rooms[i].picture = inFile->readByte();
+		_state.rooms[i].curPicture = inFile->readByte();
+	}
+
+	size = inFile->readUint32BE();
+	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();
+	}
+
+	size = inFile->readUint32BE();
+	if (size != _state.vars.size())
+		error("Variable count mismatch (expected %i; found %i)", _state.vars.size(), size);
+
+	for (uint i = 0; i < size; ++i)
+		_state.vars[i] = inFile->readByte();
+
+	if (inFile->err() || inFile->eos())
+		error("Failed to load game '%s'", fileName.c_str());
+
+	delete inFile;
+	return true;
+}
+
 AdlEngine *AdlEngine::create(GameType type, OSystem *syst, const AdlGameDescription *gd) {
 	switch(type) {
 	case kGameTypeHires1:
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 8b0aa45..abb62ee 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -37,6 +37,8 @@ class SeekableReadStream;
 
 namespace Adl {
 
+#define SAVEGAME_VERSION 0
+
 class Display;
 class Parser;
 class Console;
@@ -178,6 +180,7 @@ protected:
 	virtual void initState() = 0;
 	virtual void restartGame() = 0;
 	virtual uint getEngineMessage(EngineMessage msg) = 0;
+	virtual uint32 getTag() = 0;
 	Common::String readString(Common::ReadStream &stream, byte until = 0);
 	void printStrings(Common::SeekableReadStream &stream, int count = 1);
 	virtual void printMessage(uint idx, bool wait = true);
@@ -211,6 +214,9 @@ protected:
 
 private:
 	void printEngineMessage(EngineMessage);
+	bool saveState(uint slot);
+	bool loadState(uint slot);
+	Common::String getTargetName() { return _targetName; }
 };
 
 AdlEngine *HiRes1Engine__create(OSystem *syst, const AdlGameDescription *gd);
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index a378dc9..ab26b2c 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -52,6 +52,7 @@ private:
 	void restartGame();
 	void printMessage(uint idx, bool wait = true);
 	uint getEngineMessage(EngineMessage msg);
+	uint32 getTag() { return MKTAG('H', 'R', 'A', '1'); }
 
 	void initState();
 	void runIntro();


Commit: e1fb5853576d8b0c05710ad70e22e10254467153
    https://github.com/scummvm/scummvm/commit/e1fb5853576d8b0c05710ad70e22e10254467153
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Use #define instead of literal

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



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 9c86b3a..711e538 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -306,7 +306,7 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 		case IDO_ACT_GO_WEST:
 		case IDO_ACT_GO_UP:
 		case IDO_ACT_GO_DOWN: {
-			byte room = _state.rooms[_state.room].connections[ARG(0) - 0x15];
+			byte room = _state.rooms[_state.room].connections[ARG(0) - IDO_ACT_GO_NORTH];
 
 			if (room == 0) {
 				printEngineMessage(IDI_MSG_CANT_GO_THERE);
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 4cf7b45..dac6d4c 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -155,9 +155,9 @@ void HiRes1Engine::runIntro() {
 	_display->setMode(Display::kModeText);
 	file.seek(IDI_HR1_OFS_INTRO_TEXT);
 
-	const int pages[] = { 6, 6, 4, 5, 8, 7, 0 };
+	const uint pages[] = { 6, 6, 4, 5, 8, 7, 0 };
 
-	int page = 0;
+	uint page = 0;
 	while (pages[page] != 0) {
 		_display->home();
 		printStrings(file, pages[page++]);


Commit: 475eb0cc95c46be651d15de8eb1c0f42a2921c6a
    https://github.com/scummvm/scummvm/commit/475eb0cc95c46be651d15de8eb1c0f42a2921c6a
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Fix bug in item taking

Changed paths:
    engines/adl/adl.cpp



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 711e538..1847f7f 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -178,7 +178,7 @@ void AdlEngine::takeItem(byte noun) {
 		}
 
 		Common::Array<byte>::const_iterator pic;
-		for (pic = item->roomPictures.begin(); item->roomPictures.end(); ++pic) {
+		for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
 			if (*pic == _state.rooms[_state.room].curPicture) {
 				item->room = IDI_NONE;
 				item->state = IDI_ITEM_MOVED;


Commit: 9928e51bd73985f48c8378308a278fff433eaae1
    https://github.com/scummvm/scummvm/commit/9928e51bd73985f48c8378308a278fff433eaae1
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Add functions to adjust for 1-based arrays

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



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 1847f7f..be90678 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -179,7 +179,7 @@ void AdlEngine::takeItem(byte noun) {
 
 		Common::Array<byte>::const_iterator pic;
 		for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
-			if (*pic == _state.rooms[_state.room].curPicture) {
+			if (*pic == curRoom().curPicture) {
 				item->room = IDI_NONE;
 				item->state = IDI_ITEM_MOVED;
 				return;
@@ -211,15 +211,15 @@ 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:
-			_state.vars[ARG(2)] += ARG(1);
+			var(ARG(2)) += ARG(1);
 			offset += 3;
 			break;
 		case IDO_ACT_VAR_SUB:
-			_state.vars[ARG(2)] -= ARG(1);
+			var(ARG(2)) -= ARG(1);
 			offset += 3;
 			break;
 		case IDO_ACT_VAR_SET:
-			_state.vars[ARG(1)] = ARG(2);
+			var(ARG(1)) = ARG(2);
 			offset += 3;
 			break;
 		case IDO_ACT_LIST_ITEMS: {
@@ -233,20 +233,20 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			break;
 		}
 		case IDO_ACT_MOVE_ITEM:
-			_state.items[ARG(1) - 1].room = ARG(2);
+			item(ARG(1)).room = ARG(2);
 			offset += 3;
 			break;
 		case IDO_ACT_SET_ROOM:
-			_state.rooms[_state.room].curPicture = _state.rooms[_state.room].picture;
+			curRoom().curPicture = curRoom().picture;
 			_state.room = ARG(1);
 			offset += 2;
 			break;
 		case IDO_ACT_SET_CUR_PIC:
-			_state.rooms[_state.room].curPicture = ARG(1);
+			curRoom().curPicture = ARG(1);
 			offset += 2;
 			break;
 		case IDO_ACT_SET_PIC:
-			_state.rooms[_state.room].picture = _state.rooms[_state.room].curPicture = ARG(1);
+			curRoom().picture = curRoom().curPicture = ARG(1);
 			offset += 2;
 			break;
 		case IDO_ACT_PRINT_MSG:
@@ -287,17 +287,17 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			quitGame();
 			return;
 		case IDO_ACT_PLACE_ITEM:
-			_state.items[ARG(1) - 1].room = ARG(2);
-			_state.items[ARG(1) - 1].position.x = ARG(3);
-			_state.items[ARG(1) - 1].position.y = ARG(4);
+			item(ARG(1)).room = ARG(2);
+			item(ARG(1)).position.x = ARG(3);
+			item(ARG(1)).position.y = ARG(4);
 			offset += 5;
 			break;
 		case IDO_ACT_SET_ITEM_PIC:
-			_state.items[ARG(2) - 1].picture = ARG(1);
+			item(ARG(2)).picture = ARG(1);
 			offset += 3;
 			break;
 		case IDO_ACT_RESET_PIC:
-			_state.rooms[_state.room].curPicture = _state.rooms[_state.room].picture;
+			curRoom().curPicture = curRoom().picture;
 			++offset;
 			break;
 		case IDO_ACT_GO_NORTH:
@@ -306,14 +306,14 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 		case IDO_ACT_GO_WEST:
 		case IDO_ACT_GO_UP:
 		case IDO_ACT_GO_DOWN: {
-			byte room = _state.rooms[_state.room].connections[ARG(0) - IDO_ACT_GO_NORTH];
+			byte room = curRoom().connections[ARG(0) - IDO_ACT_GO_NORTH];
 
 			if (room == 0) {
 				printEngineMessage(IDI_MSG_CANT_GO_THERE);
 				return;
 			}
 
-			_state.rooms[_state.room].curPicture = _state.rooms[_state.room].picture;
+			curRoom().curPicture = curRoom().picture;
 			_state.room = room;
 			return;
 		}
@@ -326,7 +326,7 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			++offset;
 			break;
 		case IDO_ACT_SET_ROOM_PIC:
-			_state.rooms[ARG(1)].picture = _state.rooms[ARG(1)].curPicture = ARG(2);
+			room(ARG(1)).picture = room(ARG(1)).curPicture = ARG(2);
 			offset += 3;
 			break;
 		default:
@@ -347,9 +347,9 @@ bool AdlEngine::checkCommand(const Command &command, byte verb, byte noun) {
 
 	uint offset = 0;
 	for (uint i = 0; i < command.numCond; ++i) {
-		switch (command.script[offset]) {
+		switch (ARG(0)) {
 		case IDO_CND_ITEM_IN_ROOM:
-			if (_state.items[ARG(1) - 1].room != ARG(2))
+			if (item(ARG(1)).room != ARG(2))
 				return false;
 			offset += 3;
 			break;
@@ -359,17 +359,17 @@ bool AdlEngine::checkCommand(const Command &command, byte verb, byte noun) {
 			offset += 2;
 			break;
 		case IDO_CND_VAR_EQ:
-			if (_state.vars[ARG(1)] != ARG(2))
+			if (var(ARG(1)) != ARG(2))
 				return false;
 			offset += 3;
 			break;
 		case IDO_CND_CUR_PIC_EQ:
-			if (_state.rooms[_state.room].curPicture != ARG(1))
+			if (curRoom().curPicture != ARG(1))
 				return false;
 			offset += 2;
 			break;
 		case IDO_CND_ITEM_PIC_EQ:
-			if (_state.items[ARG(1) - 1].picture != ARG(2))
+			if (item(ARG(1)).picture != ARG(2))
 				return false;
 			offset += 3;
 			break;
@@ -420,7 +420,7 @@ void AdlEngine::drawItems() {
 			continue;
 
 		if (item->state == IDI_ITEM_MOVED) {
-			if (_state.rooms[_state.room].picture == _state.rooms[_state.room].curPicture) {
+			if (curRoom().picture == curRoom().curPicture) {
 				const Common::Point &p =  _itemOffsets[dropped];
 				if (item->isLineArt)
 					_display->drawLineArt(_lineArt[item->picture - 1], p);
@@ -434,7 +434,7 @@ void AdlEngine::drawItems() {
 		Common::Array<byte>::const_iterator pic;
 
 		for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
-			if (*pic == _state.rooms[_state.room].curPicture) {
+			if (*pic == curRoom().curPicture) {
 				if (item->isLineArt)
 					_display->drawLineArt(_lineArt[item->picture - 1], item->position);
 				else
@@ -447,12 +447,12 @@ void AdlEngine::drawItems() {
 
 void AdlEngine::showRoom() {
 	if (!_state.isDark) {
-		drawPic(_state.rooms[_state.room].curPicture);
+		drawPic(curRoom().curPicture);
 		drawItems();
 	}
 
 	_display->decodeFrameBuffer();
-	printMessage(_state.rooms[_state.room].description, false);
+	printMessage(curRoom().description, false);
 }
 
 bool AdlEngine::saveState(uint slot) {
@@ -565,6 +565,31 @@ bool AdlEngine::loadState(uint slot) {
 	return true;
 }
 
+Room &AdlEngine::room(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];
+}
+
+Room &AdlEngine::curRoom() {
+	return room(_state.room);
+}
+
+Item &AdlEngine::item(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::var(uint i) {
+	if (i >= _state.vars.size())
+		error("Variable %i out of range [0, %i]", i, _state.vars.size() - 1);
+
+	return _state.vars[i];
+}
+
 AdlEngine *AdlEngine::create(GameType type, OSystem *syst, const AdlGameDescription *gd) {
 	switch(type) {
 	case kGameTypeHires1:
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index abb62ee..b7fd3dc 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -196,6 +196,10 @@ protected:
 	void showRoom();
 	void takeItem(byte noun);
 	void dropItem(byte noun);
+	Room &room(uint i);
+	Room &curRoom();
+	Item &item(uint i);
+	byte &var(uint i);
 
 	Display *_display;
 	Parser *_parser;
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index dac6d4c..45a011a 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -233,7 +233,7 @@ void HiRes1Engine::initState() {
 
 	// Load room data from executable
 	_state.rooms.clear();
-	f.seek(1280);
+	f.seek(0x50a);
 	for (uint i = 0; i < MH_ROOMS; ++i) {
 		Room room;
 		f.readByte();
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index ab26b2c..247625c 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -44,7 +44,7 @@ protected:
 
 private:
 	enum {
-		MH_ROOMS = 42,
+		MH_ROOMS = 41,
 		MH_PICS = 98,
 		MH_ITEM_OFFSETS = 21
 	};


Commit: ba54955bffec15ed95aa1ca1ec955aecaa315478
    https://github.com/scummvm/scummvm/commit/ba54955bffec15ed95aa1ca1ec955aecaa315478
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Add loading from launcher

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



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index be90678..ab05c40 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -70,6 +70,16 @@ Common::Error AdlEngine::run() {
 	_display = new Display();
 	_parser = new Parser(*this, *_display);
 
+	int saveSlot = ConfMan.getInt("save_slot");
+	if (saveSlot >= 0) {
+		if (!loadState(saveSlot))
+			error("Failed to load save game from slot %i", saveSlot);
+		_display->setCursorPos(Common::Point(0, 23));
+	} else {
+		runIntro();
+		initState();
+	}
+
 	runGame();
 
 	return Common::kNoError;
@@ -455,7 +465,7 @@ void AdlEngine::showRoom() {
 	printMessage(curRoom().description, false);
 }
 
-bool AdlEngine::saveState(uint slot) {
+bool AdlEngine::saveState(uint slot, const Common::String *description) {
 	Common::String fileName = Common::String::format("%s.s%02d", _targetName.c_str(), slot);
 	Common::OutSaveFile *outFile = getSaveFileManager()->openForSaving(fileName);
 
@@ -464,9 +474,21 @@ bool AdlEngine::saveState(uint slot) {
 		return false;
 	}
 
-	outFile->writeUint32BE(getTag());
+	outFile->writeUint32BE(MKTAG('A', 'D', 'L', ':'));
 	outFile->writeByte(SAVEGAME_VERSION);
 
+	char name[SAVEGAME_NAME_LEN] = { };
+
+	if (description)
+		strncpy(name, description->c_str(), sizeof(name) - 1);
+	else {
+		Common::String defaultName("Save ");
+		defaultName += 'A' + slot;
+		strncpy(name, defaultName.c_str(), sizeof(name) - 1);
+	}
+
+	outFile->write(name, sizeof(name));
+
 	outFile->writeByte(_state.room);
 	outFile->writeByte(_state.moves);
 	outFile->writeByte(_state.isDark);
@@ -511,7 +533,7 @@ bool AdlEngine::loadState(uint slot) {
 		return false;
 	}
 
-	if (inFile->readUint32BE() != getTag()) {
+	if (inFile->readUint32BE() != MKTAG('A', 'D', 'L', ':')) {
 		warning("No header found in '%s'", fileName.c_str());
 		delete inFile;
 		return false;
@@ -526,6 +548,8 @@ bool AdlEngine::loadState(uint slot) {
 
 	initState();
 
+	inFile->seek(SAVEGAME_NAME_LEN, SEEK_CUR);
+
 	_state.room = inFile->readByte();
 	_state.moves = inFile->readByte();
 	_state.isDark = inFile->readByte();
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index b7fd3dc..9955b0d 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -38,6 +38,7 @@ class SeekableReadStream;
 namespace Adl {
 
 #define SAVEGAME_VERSION 0
+#define SAVEGAME_NAME_LEN 32
 
 class Display;
 class Parser;
@@ -176,11 +177,11 @@ public:
 	virtual Common::String getEngineString(int str);
 
 protected:
+	virtual void runIntro() { }
 	virtual void runGame() = 0;
 	virtual void initState() = 0;
 	virtual void restartGame() = 0;
 	virtual uint getEngineMessage(EngineMessage msg) = 0;
-	virtual uint32 getTag() = 0;
 	Common::String readString(Common::ReadStream &stream, byte until = 0);
 	void printStrings(Common::SeekableReadStream &stream, int count = 1);
 	virtual void printMessage(uint idx, bool wait = true);
@@ -218,7 +219,7 @@ protected:
 
 private:
 	void printEngineMessage(EngineMessage);
-	bool saveState(uint slot);
+	bool saveState(uint slot, const Common::String *description = nullptr);
 	bool loadState(uint slot);
 	Common::String getTargetName() { return _targetName; }
 };
diff --git a/engines/adl/detection.cpp b/engines/adl/detection.cpp
index 9fadb9d..5fe469d 100644
--- a/engines/adl/detection.cpp
+++ b/engines/adl/detection.cpp
@@ -20,6 +20,9 @@
  *
  */
 
+#include "common/system.h"
+#include "common/savefile.h"
+
 #include "engines/advancedDetector.h"
 
 #include "adl/adl.h"
@@ -69,9 +72,63 @@ public:
 		return "Copyright (C) Sierra On-Line";
 	}
 
+	bool hasFeature(MetaEngineFeature f) const;
+	int getMaximumSaveSlot() const { return 15; }
+	SaveStateList listSaves(const char *target) const;
+
 	bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const;
 };
 
+bool AdlMetaEngine::hasFeature(MetaEngineFeature f) const {
+	switch(f) {
+	case kSupportsListSaves:
+	case kSupportsLoadingDuringStartup:
+		return true;
+	default:
+		return false;
+	}
+}
+
+SaveStateList AdlMetaEngine::listSaves(const char *target) const {
+	Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+	Common::StringArray files = saveFileMan->listSavefiles(Common::String(target) + ".s##");
+
+	SaveStateList saveList;
+	for (uint i = 0; i < files.size(); ++i) {
+		const Common::String &fileName = files[i];
+		Common::InSaveFile *inFile = saveFileMan->openForLoading(fileName);
+		if (!inFile) {
+			warning("Cannot open save file %s", fileName.c_str());
+			continue;
+		}
+
+		if (inFile->readUint32BE() != MKTAG('A', 'D', 'L', ':')) {
+			warning("No header found in '%s'", fileName.c_str());
+			delete inFile;
+			continue;
+		}
+
+		byte saveVersion = inFile->readByte();
+		if (saveVersion != SAVEGAME_VERSION) {
+			warning("Save game version %i not supported in '%s'", saveVersion, fileName.c_str());
+			delete inFile;
+			continue;
+		}
+
+		char name[SAVEGAME_NAME_LEN] = { };
+		inFile->read(name, sizeof(name) - 1);
+		delete inFile;
+
+		int slotNum = atoi(fileName.c_str() + fileName.size() - 2);
+		SaveStateDescriptor sd(slotNum, name);
+		saveList.push_back(sd);
+	}
+
+	// Sort saves based on slot number.
+	Common::sort(saveList.begin(), saveList.end(), SaveStateDescriptorSlotComparator());
+	return saveList;
+}
+
 bool AdlMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const {
 	if (gd)
 		*engine = AdlEngine::create(((const AdlGameDescription *)gd)->gameType, syst, (const AdlGameDescription *)gd);
diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp
index 05e7c2e..ffb98c4 100644
--- a/engines/adl/display.cpp
+++ b/engines/adl/display.cpp
@@ -585,4 +585,8 @@ void Display::home() {
 	_cursorPos = 0;
 }
 
+void Display::setCursorPos(Common::Point pos) {
+	_cursorPos = pos.y * 40 + pos.x;
+}
+
 } // End of namespace Adl
diff --git a/engines/adl/display.h b/engines/adl/display.h
index 229446f..91d8b0e 100644
--- a/engines/adl/display.h
+++ b/engines/adl/display.h
@@ -64,6 +64,7 @@ public:
 	void drawLine(Common::Point p1, Common::Point p2, byte color);
 	void clear(byte color);
 	void drawLineArt(const Common::Array<byte> &lineArt, Common::Point p, byte rotation = 0, byte scaling = 1, byte color = 0x7f);
+	void setCursorPos(Common::Point pos);
 
 private:
 	enum {
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 45a011a..ba6f19a 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -136,6 +136,8 @@ void HiRes1Engine::runIntro() {
 	file.seek(IDI_HR1_OFS_GAME_OR_HELP);
 	str = readString(file);
 
+	bool instructions = false;
+
 	while (1) {
 		_display->printString(str);
 		Common::String s = _display->inputString();
@@ -146,28 +148,47 @@ void HiRes1Engine::runIntro() {
 		if (s.empty())
 			continue;
 
-		if ((byte)s[0] == ('I' | 0x80))
+		if (s[0] == APPLECHAR('I')) {
+			instructions = true;
 			break;
-		else if ((byte)s[0] == ('G' | 0x80))
-			return;
+		} else if (s[0] == APPLECHAR('G')) {
+			break;
+		}
 	};
 
-	_display->setMode(Display::kModeText);
-	file.seek(IDI_HR1_OFS_INTRO_TEXT);
+	if (instructions) {
+		_display->setMode(Display::kModeText);
+		file.seek(IDI_HR1_OFS_INTRO_TEXT);
 
-	const uint pages[] = { 6, 6, 4, 5, 8, 7, 0 };
+		const uint pages[] = { 6, 6, 4, 5, 8, 7, 0 };
 
-	uint page = 0;
-	while (pages[page] != 0) {
-		_display->home();
-		printStrings(file, pages[page++]);
-		_display->inputString();
+		uint page = 0;
+		while (pages[page] != 0) {
+			_display->home();
+			printStrings(file, pages[page++]);
+			_display->inputString();
 
-		if (g_engine->shouldQuit())
-			return;
+			if (g_engine->shouldQuit())
+				return;
 
-		file.seek(9, SEEK_CUR);
+			file.seek(9, SEEK_CUR);
+		}
 	}
+
+	_display->printASCIIString("\r");
+
+	file.close();
+
+	_display->setMode(Display::kModeMixed);
+
+	if (!file.open("ADVENTURE"))
+		error("Failed to open file");
+
+	// Title screen shown during loading
+	file.seek(0x1800);
+	_display->loadFrameBuffer(file);
+	_display->decodeFrameBuffer();
+	_display->delay(2000);
 }
 
 void HiRes1Engine::drawPic(Common::ReadStream &stream, Common::Point pos) {
@@ -278,8 +299,7 @@ void HiRes1Engine::restartGame() {
 }
 
 void HiRes1Engine::runGame() {
-	runIntro();
-	_display->printASCIIString("\r");
+	_display->setMode(Display::kModeMixed);
 
 	Common::File f;
 
@@ -291,8 +311,6 @@ void HiRes1Engine::runGame() {
 
 	f.close();
 
-	initState();
-
 	if (!f.open("ADVENTURE"))
 		error("Failed to open file");
 
@@ -345,12 +363,6 @@ void HiRes1Engine::runGame() {
 		_lineArt.push_back(lineArt);
 	}
 
-	// Title screen shown during loading
-	f.seek(0x1800);
-	_display->loadFrameBuffer(f);
-	_display->decodeFrameBuffer();
-	_display->delay(2000);
-
 	f.seek(0x3800);
 	_parser->loadVerbs(f);
 
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index 247625c..897327c 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -52,7 +52,6 @@ private:
 	void restartGame();
 	void printMessage(uint idx, bool wait = true);
 	uint getEngineMessage(EngineMessage msg);
-	uint32 getTag() { return MKTAG('H', 'R', 'A', '1'); }
 
 	void initState();
 	void runIntro();


Commit: 339d3bc86813b454447b02481f82b85c4c8be75b
    https://github.com/scummvm/scummvm/commit/339d3bc86813b454447b02481f82b85c4c8be75b
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Move input code into AdlEngine

Changed paths:
  R engines/adl/parser.cpp
  R engines/adl/parser.h
    engines/adl/adl.cpp
    engines/adl/adl.h
    engines/adl/display.cpp
    engines/adl/display.h
    engines/adl/hires1.cpp
    engines/adl/module.mk



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index ab05c40..3c405b6 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -36,7 +36,6 @@
 
 #include "adl/adl.h"
 #include "adl/display.h"
-#include "adl/parser.h"
 
 namespace Adl {
 
@@ -44,12 +43,10 @@ AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) :
 		Engine(syst),
 		_gameDescription(gd),
 		_display(nullptr),
-		_parser(nullptr),
 		_isRestarting(false) {
 }
 
 AdlEngine::~AdlEngine() {
-	delete _parser;
 	delete _display;
 }
 
@@ -68,7 +65,6 @@ Common::Error AdlEngine::run() {
 	g_system->getPaletteManager()->setPalette(palette, 0, 6);
 
 	_display = new Display();
-	_parser = new Parser(*this, *_display);
 
 	int saveSlot = ConfMan.getInt("save_slot");
 	if (saveSlot >= 0) {
@@ -137,7 +133,7 @@ void AdlEngine::printMessage(uint idx, bool wait) {
 	_display->printString(msg);
 
 	if (wait)
-		_display->delay(14 * 166018 / 1000);
+		delay(14 * 166018 / 1000);
 }
 
 void AdlEngine::printEngineMessage(EngineMessage msg) {
@@ -282,7 +278,7 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			break;
 		case IDO_ACT_RESTART: {
 			_display->printString(_strings[IDI_STR_PLAY_AGAIN]);
-			Common::String input = _display->inputString();
+			Common::String input = inputString();
 			if (input.size() == 0 || input[0] != APPLECHAR('N')) {
 				_isRestarting = true;
 				_display->clear(0x00);
@@ -614,6 +610,259 @@ byte &AdlEngine::var(uint i) {
 	return _state.vars[i];
 }
 
+void AdlEngine::loadWords(Common::ReadStream &stream, WordMap &map) {
+	uint index = 0;
+
+	while (1) {
+		++index;
+
+		byte buf[kWordSize];
+
+		if (stream.read(buf, kWordSize) < kWordSize)
+			error("Error reading word list");
+
+		Common::String word((char *)buf, kWordSize);
+
+		if (!map.contains(word))
+			map[word] = index;
+
+		byte synonyms = stream.readByte();
+
+		if (stream.err() || stream.eos())
+			error("Error reading word list");
+
+		if (synonyms == 0xff)
+			break;
+
+		for (uint i = 0; i < synonyms; ++i) {
+			if (stream.read((char *)buf, kWordSize) < kWordSize)
+				error("Error reading word list");
+
+			word = Common::String((char *)buf, kWordSize);
+
+			if (!map.contains(word))
+				map[word] = index;
+		}
+	}
+}
+
+Common::String AdlEngine::getLine() {
+	// Original engine uses a global here, which isn't reset between
+	// calls and may not match actual mode
+	bool textMode = false;
+
+	while (1) {
+		Common::String line = inputString(APPLECHAR('?'));
+
+		if (shouldQuit())
+			return "";
+
+		if ((byte)line[0] == ('\r' | 0x80)) {
+			textMode = !textMode;
+			_display->setMode(textMode ? Display::kModeText : Display::kModeMixed);
+			continue;
+		}
+
+		// Remove the return
+		line.deleteLastChar();
+		return line;
+	}
+}
+
+Common::String AdlEngine::getWord(const Common::String &line, uint &index) {
+	Common::String str;
+
+	for (uint i = 0; i < 8; ++i)
+		str += APPLECHAR(' ');
+
+	int copied = 0;
+
+	// Skip initial whitespace
+	while (1) {
+		if (index == line.size())
+			return str;
+		if (line[index] != APPLECHAR(' '))
+			break;
+		++index;
+	}
+
+	// Copy up to 8 characters
+	while (1) {
+		if (copied < 8)
+			str.setChar(line[index], copied++);
+
+		index++;
+
+		if (index == line.size() || line[index] == APPLECHAR(' '))
+			return str;
+	}
+}
+
+void AdlEngine::getInput(uint &verb, uint &noun) {
+	while (1) {
+		_display->printString(getEngineString(IDI_STR_ENTER_COMMAND));
+		Common::String line = getLine();
+
+		if (shouldQuit())
+			return;
+
+		uint index = 0;
+		Common::String verbStr = getWord(line, index);
+
+		if (!_verbs.contains(verbStr)) {
+			Common::String err = getEngineString(IDI_STR_VERB_ERROR);
+			for (uint i = 0; i < verbStr.size(); ++i)
+				err.setChar(verbStr[i], i + 19);
+			_display->printString(err);
+			continue;
+		}
+
+		verb = _verbs[verbStr];
+
+		Common::String nounStr = getWord(line, index);
+
+		if (!_nouns.contains(nounStr)) {
+			Common::String err = getEngineString(IDI_STR_NOUN_ERROR);
+			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);
+			continue;
+		}
+
+		noun = _nouns[nounStr];
+		return;
+	}
+}
+
+void AdlEngine::printASCIIString(const Common::String &str) {
+	Common::String aStr;
+
+	Common::String::const_iterator it;
+	for (it = str.begin(); it != str.end(); ++it)
+			aStr += APPLECHAR(*it);
+
+	_display->printString(aStr);
+}
+
+Common::String AdlEngine::inputString(byte prompt) {
+	Common::String s;
+
+	if (prompt > 0)
+		_display->printString(Common::String(prompt));
+
+	while (1) {
+		byte b = inputKey();
+
+		if (g_engine->shouldQuit())
+			return 0;
+
+		if (b == 0)
+			continue;
+
+		if (b == ('\r' | 0x80)) {
+			s += b;
+			_display->printString(Common::String(b));
+			return s;
+		}
+
+		if (b < 0xa0) {
+			switch (b) {
+			case Common::KEYCODE_BACKSPACE | 0x80:
+				if (!s.empty()) {
+					_display->moveCursorBackward();
+					_display->setCharAtCursor(APPLECHAR(' '));
+					s.deleteLastChar();
+				}
+				break;
+			};
+		} else {
+			s += b;
+			_display->printString(Common::String(b));
+		}
+	}
+}
+
+byte AdlEngine::convertKey(uint16 ascii) {
+	ascii = toupper(ascii);
+
+	if (ascii >= 0x80)
+		return 0;
+
+	ascii |= 0x80;
+
+	if (ascii >= 0x80 && ascii <= 0xe0)
+		return ascii;
+
+	return 0;
+}
+
+byte AdlEngine::inputKey() {
+	Common::EventManager *ev = g_system->getEventManager();
+
+	byte key = 0;
+
+	_display->showCursor(true);
+
+	while (!g_engine->shouldQuit() && key == 0) {
+		Common::Event event;
+		if (ev->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:
+				key = convertKey(event.kbd.keycode);
+				break;
+			default:
+				if (event.kbd.ascii >= 0x20 && event.kbd.ascii < 0x80)
+					key = convertKey(event.kbd.ascii);
+			};
+		}
+
+		_display->updateTextSurface();
+		_display->updateScreen();
+		g_system->updateScreen();
+		g_system->delayMillis(16);
+	}
+
+	_display->showCursor(false);
+
+	return key;
+}
+
+void AdlEngine::delay(uint32 ms) {
+	Common::EventManager *ev = g_system->getEventManager();
+
+	uint32 start = g_system->getMillis();
+
+	while (!g_engine->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;
+				}
+			}
+		}
+		_display->updateScreen();
+		g_system->updateScreen();
+		g_system->delayMillis(16);
+	}
+}
+
 AdlEngine *AdlEngine::create(GameType type, OSystem *syst, const AdlGameDescription *gd) {
 	switch(type) {
 	case kGameTypeHires1:
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 9955b0d..a9ac79d 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -177,6 +177,8 @@ public:
 	virtual Common::String getEngineString(int str);
 
 protected:
+	typedef Common::HashMap<Common::String, uint> WordMap;
+
 	virtual void runIntro() { }
 	virtual void runGame() = 0;
 	virtual void initState() = 0;
@@ -201,6 +203,16 @@ protected:
 	Room &curRoom();
 	Item &item(uint i);
 	byte &var(uint i);
+	void loadVerbs(Common::ReadStream &stream) { loadWords(stream, _verbs); }
+	void loadNouns(Common::ReadStream &stream) { loadWords(stream, _nouns); }
+	void getInput(uint &verb, uint &noun);
+	void loadWords(Common::ReadStream &stream, WordMap &map);
+	Common::String getLine();
+	Common::String getWord(const Common::String &line, uint &index);
+	void printASCIIString(const Common::String &str);
+	Common::String inputString(byte prompt = 0);
+	void delay(uint32 ms);
+	byte inputKey();
 
 	Display *_display;
 	Parser *_parser;
@@ -222,6 +234,14 @@ private:
 	bool saveState(uint slot, const Common::String *description = nullptr);
 	bool loadState(uint slot);
 	Common::String getTargetName() { return _targetName; }
+	byte convertKey(uint16 ascii);
+
+	enum {
+		kWordSize = 8
+	};
+
+	WordMap _verbs;
+	WordMap _nouns;
 };
 
 AdlEngine *HiRes1Engine__create(OSystem *syst, const AdlGameDescription *gd);
diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp
index ffb98c4..a6d94f6 100644
--- a/engines/adl/display.cpp
+++ b/engines/adl/display.cpp
@@ -71,7 +71,8 @@ static byte font[64][5] = {
 Display::Display() :
 		_scanlines(false),
 		_cursorPos(0),
-		_mode(kModeText) {
+		_mode(kModeText),
+		_showCursor(false) {
 	_frameBuf = new byte[kFrameBufSize];
 	_frameBufSurface = new Graphics::Surface;
 	_frameBufSurface->create(kWidth * 2, kHeight * 2, Graphics::PixelFormat::createFormatCLUT8());
@@ -367,8 +368,12 @@ void Display::clear(byte color) {
 void Display::updateTextSurface() {
 	for (uint row = 0; row < 24; ++row)
 		for (uint col = 0; col < 40; ++col) {
+			int charPos = row * 40 + col;
 			char c = _textBuf[row * 40 + col];
 
+			if (charPos == _cursorPos && _showCursor)
+				c = (c & 0x3f) | 0x40;
+
 			Common::Rect r(7 * 2, 8 * 2);
 			r.translate(((c & 0x3f) % 16) * 7 * 2, (c & 0x3f) / 16 * 8 * 2);
 
@@ -381,36 +386,6 @@ void Display::updateTextSurface() {
 		}
 }
 
-void Display::printString(const Common::String &str) {
-	Common::String::const_iterator it;
-	for (it = str.begin(); it != str.end(); ++it) {
-		byte b = *it;
-
-		if (b == ('\r' | 0x80))
-			_cursorPos = (_cursorPos / 40 + 1) * 40;
-		else if (b < 0x80 || b >= 0xa0)
-			_textBuf[_cursorPos++] = b;
-
-		if (_cursorPos == kTextBufSize) {
-			memmove(_textBuf, _textBuf + 40, kTextBufSize - 40);
-			memset(_textBuf + kTextBufSize - 40, ' ' | 0x80, 40);
-			_cursorPos -= 40;
-		}
-	}
-
-	updateTextSurface();
-}
-
-void Display::printASCIIString(const Common::String &str) {
-	Common::String aStr;
-
-	Common::String::const_iterator it;
-	for (it = str.begin(); it != str.end(); ++it)
-			aStr += APPLECHAR(*it);
-
-	printString(aStr);
-}
-
 void Display::drawChar(byte c, int x, int y) {
 	byte *buf = (byte *)_font->getPixels() + y * _font->pitch + x;
 
@@ -463,126 +438,63 @@ void Display::updateScreen() {
 	}
 }
 
-Common::String Display::inputString(byte prompt) {
-	Common::String s;
-
-	if (prompt > 0)
-		printString(Common::String(prompt));
-
-	while (1) {
-		byte b = inputKey();
-
-		if (g_engine->shouldQuit())
-			return 0;
-
-		if (b == 0)
-			continue;
-
-		if (b == ('\r' | 0x80)) {
-			s += b;
-			printString(Common::String(b));
-			return s;
-		}
-
-		if (b < 0xa0) {
-			switch (b) {
-			case Common::KEYCODE_BACKSPACE | 0x80:
-				if (!s.empty()) {
-					--_cursorPos;
-					_textBuf[_cursorPos] = ' ' | 0x80;
-					s.deleteLastChar();
-				}
-				break;
-			};
-		} else {
-			s += b;
-			printString(Common::String(b));
-		}
-	}
+void Display::home() {
+	memset(_textBuf, APPLECHAR(' '), kTextBufSize);
+	_cursorPos = 0;
 }
 
-byte Display::convertKey(uint16 ascii) {
-	ascii = toupper(ascii);
-
-	if (ascii >= 0x80)
-		return 0;
+void Display::moveCursorForward() {
+	++_cursorPos;
 
-	ascii |= 0x80;
+	if (_cursorPos >= kTextBufSize)
+		scrollUp();
+}
 
-	if (ascii >= 0x80 && ascii <= 0xe0)
-		return ascii;
+void Display::moveCursorBackward() {
+	--_cursorPos;
 
-	return 0;
+	if (_cursorPos < 0)
+		_cursorPos = 0;
 }
 
-byte Display::inputKey() {
-	Common::EventManager *ev = g_system->getEventManager();
+void Display::moveCursorTo(const Common::Point &pos) {
+	_cursorPos = pos.y * 40 + pos.x;
 
-	byte orgChar = _textBuf[_cursorPos];
-	_textBuf[_cursorPos] = (orgChar & 0x3f) | 0x40;
+	if (_cursorPos >= kTextBufSize)
+		error("Cursor position (%i, %i) out of bounds", pos.x, pos.y);
+}
 
-	byte key = 0;
+void Display::setCharAtCursor(byte c) {
+	_textBuf[_cursorPos] = c;
+}
 
-	while (!g_engine->shouldQuit() && key == 0) {
-		Common::Event event;
-		if (ev->pollEvent(event)) {
-			if (event.type != Common::EVENT_KEYDOWN)
-				continue;
+void Display::scrollUp() {
+	memmove(_textBuf, _textBuf + 40, kTextBufSize - 40);
+	memset(_textBuf + kTextBufSize - 40, ' ' | 0x80, 40);
+	_cursorPos -= 40;
+}
 
-			if (event.kbd.flags & Common::KBD_CTRL) {
-				if (event.kbd.keycode == Common::KEYCODE_q)
-					g_engine->quitGame();
-				continue;
-			}
+void Display::printString(const Common::String &str) {
+	Common::String::const_iterator c;
+	for (c = str.begin(); c != str.end(); ++c) {
+		byte b = *c;
 
-			switch (event.kbd.keycode) {
-			case Common::KEYCODE_BACKSPACE:
-			case Common::KEYCODE_RETURN:
-				key = convertKey(event.kbd.keycode);
-				break;
-			default:
-				if (event.kbd.ascii >= 0x20 && event.kbd.ascii < 0x80)
-					key = convertKey(event.kbd.ascii);
-			};
+		if (*c == APPLECHAR('\r'))
+			_cursorPos = (_cursorPos / 40 + 1) * 40;
+		else if (b < 0x80 || b >= 0xa0) {
+			setCharAtCursor(b);
+			++_cursorPos;
 		}
 
-		updateTextSurface();
-		updateScreen();
-		g_system->updateScreen();
-		g_system->delayMillis(16);
+		if (_cursorPos == kTextBufSize)
+			scrollUp();
 	}
 
-	_textBuf[_cursorPos] = orgChar;
-	return key;
-}
-
-void Display::delay(uint32 ms) {
-	Common::EventManager *ev = g_system->getEventManager();
-
-	uint32 start = g_system->getMillis();
-
-	while (!g_engine->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;
-				}
-			}
-		}
-		updateScreen();
-		g_system->updateScreen();
-		g_system->delayMillis(16);
-	}
+	updateTextSurface();
 }
 
-void Display::home() {
-	memset(_textBuf, ' ' | 0x80, kTextBufSize);
-	_cursorPos = 0;
+void Display::showCursor(bool enable) {
+	_showCursor = enable;
 }
 
 void Display::setCursorPos(Common::Point pos) {
diff --git a/engines/adl/display.h b/engines/adl/display.h
index 91d8b0e..91ae447 100644
--- a/engines/adl/display.h
+++ b/engines/adl/display.h
@@ -52,20 +52,23 @@ public:
 	~Display();
 	void loadFrameBuffer(Common::ReadStream &stream);
 	void decodeFrameBuffer();
-	void printString(const Common::String &str);
-	void printASCIIString(const Common::String &str);
 	void updateScreen();
-	Common::String inputString(byte prompt = 0);
-	void delay(uint32 ms);
 	void setMode(Mode mode) { _mode = mode; }
-	byte inputKey();
-	void home();
 	void drawPixel(byte x, byte y, byte color);
 	void drawLine(Common::Point p1, Common::Point p2, byte color);
 	void clear(byte color);
 	void drawLineArt(const Common::Array<byte> &lineArt, Common::Point p, byte rotation = 0, byte scaling = 1, byte color = 0x7f);
 	void setCursorPos(Common::Point pos);
 
+	void home();
+	void moveCursorTo(const Common::Point &pos);
+	void moveCursorForward();
+	void moveCursorBackward();
+	void printString(const Common::String &str);
+	void setCharAtCursor(byte c);
+	void showCursor(bool enable);
+	void updateTextSurface();
+
 private:
 	enum {
 		kWidth = 280,
@@ -85,12 +88,12 @@ private:
 	byte getPixelColor(byte x, byte color);
 	void drawChar(byte c, int x, int y);
 	void createFont();
-	void updateTextSurface();
-	byte convertKey(uint16 ascii);
 	void moveX(PixelPos &p, byte &color, bool left);
 	void moveY(PixelPos &p, bool down);
 	void drawNextPixel(Display::PixelPos &p, byte &color, byte bits, byte quadrant);
 
+	void scrollUp();
+
 	bool _scanlines;
 	byte *_frameBuf;
 	byte *_textBuf;
@@ -99,6 +102,7 @@ private:
 	Graphics::Surface *_font;
 	int _cursorPos;
 	Mode _mode;
+	bool _showCursor;
 };
  
 } // End of namespace Adl
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index ba6f19a..5912166 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -37,7 +37,6 @@
 
 #include "adl/hires1.h"
 #include "adl/display.h"
-#include "adl/parser.h"
 
 namespace Adl {
 
@@ -98,7 +97,7 @@ void HiRes1Engine::runIntro() {
 	_display->setMode(Display::kModeHires);
 	_display->loadFrameBuffer(file);
 	_display->decodeFrameBuffer();
-	_display->delay(4000);
+	delay(4000);
 
 	if (shouldQuit())
 		return;
@@ -113,21 +112,21 @@ void HiRes1Engine::runIntro() {
 
 	basic.seek(IDI_HR1_OFS_PD_TEXT_0);
 	str = readString(basic, '"');
-	_display->printASCIIString(str + '\r');
+	printASCIIString(str + '\r');
 
 	basic.seek(IDI_HR1_OFS_PD_TEXT_1);
 	str = readString(basic, '"');
-	_display->printASCIIString(str + "\r\r");
+	printASCIIString(str + "\r\r");
 
 	basic.seek(IDI_HR1_OFS_PD_TEXT_2);
 	str = readString(basic, '"');
-	_display->printASCIIString(str + "\r\r");
+	printASCIIString(str + "\r\r");
 
 	basic.seek(IDI_HR1_OFS_PD_TEXT_3);
 	str = readString(basic, '"');
-	_display->printASCIIString(str + '\r');
+	printASCIIString(str + '\r');
 
-	_display->inputKey();
+	inputKey();
 	if (g_engine->shouldQuit())
 		return;
 
@@ -140,7 +139,7 @@ void HiRes1Engine::runIntro() {
 
 	while (1) {
 		_display->printString(str);
-		Common::String s = _display->inputString();
+		Common::String s = inputString();
 
 		if (g_engine->shouldQuit())
 			break;
@@ -166,7 +165,7 @@ void HiRes1Engine::runIntro() {
 		while (pages[page] != 0) {
 			_display->home();
 			printStrings(file, pages[page++]);
-			_display->inputString();
+			inputString();
 
 			if (g_engine->shouldQuit())
 				return;
@@ -175,7 +174,7 @@ void HiRes1Engine::runIntro() {
 		}
 	}
 
-	_display->printASCIIString("\r");
+	printASCIIString("\r");
 
 	file.close();
 
@@ -188,7 +187,7 @@ void HiRes1Engine::runIntro() {
 	file.seek(0x1800);
 	_display->loadFrameBuffer(file);
 	_display->decodeFrameBuffer();
-	_display->delay(2000);
+	delay(2000);
 }
 
 void HiRes1Engine::drawPic(Common::ReadStream &stream, Common::Point pos) {
@@ -294,8 +293,8 @@ void HiRes1Engine::initState() {
 void HiRes1Engine::restartGame() {
 	initState();
 	_display->printString(_strings[IDI_HR1_STR_PRESS_RETURN]);
-	_display->inputString(); // Missing in the original
-	_display->printASCIIString("\r\r\r\r\r");
+	inputString(); // Missing in the original
+	printASCIIString("\r\r\r\r\r");
 }
 
 void HiRes1Engine::runGame() {
@@ -364,12 +363,12 @@ void HiRes1Engine::runGame() {
 	}
 
 	f.seek(0x3800);
-	_parser->loadVerbs(f);
+	loadVerbs(f);
 
 	f.seek(0xf00);
-	_parser->loadNouns(f);
+	loadNouns(f);
 
-	_display->printASCIIString("\r\r\r\r\r");
+	printASCIIString("\r\r\r\r\r");
 
 	while (1) {
 		if (_isRestarting)
@@ -378,7 +377,7 @@ void HiRes1Engine::runGame() {
 		uint verb = 0, noun = 0;
 		clearScreen();
 		showRoom();
-		_parser->getInput(verb, noun);
+		getInput(verb, noun);
 
 		if (!doOneCommand(_roomCommands, verb, noun))
 			printMessage(37);
diff --git a/engines/adl/module.mk b/engines/adl/module.mk
index 012b027..6acd06f 100644
--- a/engines/adl/module.mk
+++ b/engines/adl/module.mk
@@ -4,8 +4,7 @@ MODULE_OBJS := \
 	adl.o \
 	detection.o \
 	display.o \
-	hires1.o \
-	parser.o
+	hires1.o
 
 MODULE_DIRS += \
 	engines/adl
diff --git a/engines/adl/parser.cpp b/engines/adl/parser.cpp
deleted file mode 100644
index a697301..0000000
--- a/engines/adl/parser.cpp
+++ /dev/null
@@ -1,168 +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 "adl/adl.h"
-#include "adl/parser.h"
-#include "adl/display.h"
-
-#include "engines/engine.h"
-
-#include "common/str.h"
-#include "common/stream.h"
-#include "common/debug.h"
-#include "common/textconsole.h"
-
-namespace Adl {
-
-Parser::Parser(AdlEngine &engine, Display &display) :
-		_engine(engine),
-		_display(display) {
-
-}
-
-void Parser::loadWords(Common::ReadStream &stream, WordMap &map) {
-	uint index = 0;
-
-	while (1) {
-		++index;
-
-		byte buf[kWordSize];
-
-		if (stream.read(buf, kWordSize) < kWordSize)
-			error("Error reading word list");
-
-		Common::String word((char *)buf, kWordSize);
-
-		if (!map.contains(word))
-			map[word] = index;
-
-		byte synonyms = stream.readByte();
-
-		if (stream.err() || stream.eos())
-			error("Error reading word list");
-
-		if (synonyms == 0xff)
-			break;
-
-		for (uint i = 0; i < synonyms; ++i) {
-			if (stream.read((char *)buf, kWordSize) < kWordSize)
-				error("Error reading word list");
-
-			word = Common::String((char *)buf, kWordSize);
-
-			if (!map.contains(word))
-				map[word] = index;
-		}
-	}
-}
-
-Common::String Parser::getLine() {
- 	// Original engine uses a global here, which isn't reset between
- 	// calls and may not match actual mode
-	bool textMode = false;
-
-	while (1) {
-		Common::String line = _display.inputString(APPLECHAR('?'));
-
-		if (g_engine->shouldQuit())
-			return "";
-
-		if ((byte)line[0] == ('\r' | 0x80)) {
-			textMode = !textMode;
-			_display.setMode(textMode ? Display::kModeText : Display::kModeMixed);
-			continue;
-		}
-
-		// Remove the return
-		line.deleteLastChar();
-		return line;
-	}
-}
-
-Common::String Parser::getWord(const Common::String &line, uint &index) {
-	Common::String str;
-
-	for (uint i = 0; i < 8; ++i)
-		str += APPLECHAR(' ');
-
-	int copied = 0;
-
-	// Skip initial whitespace
-	while (1) {
-		if (index == line.size())
-			return str;
-		if (line[index] != APPLECHAR(' '))
-			break;
-		++index;
-	}
-
-	// Copy up to 8 characters
-	while (1) {
-		if (copied < 8)
-			str.setChar(line[index], copied++);
-
-		index++;
-
-		if (index == line.size() || line[index] == APPLECHAR(' '))
-			return str;
-	}
-}
-
-void Parser::getInput(uint &verb, uint &noun) {
-	while (1) {
-		_display.printString(_engine.getEngineString(IDI_STR_ENTER_COMMAND));
-		Common::String line = getLine();
-
-		if (g_engine->shouldQuit())
-			return;
-
-		uint index = 0;
-		Common::String verbStr = getWord(line, index);
-
-		if (!_verbs.contains(verbStr)) {
-			Common::String err = _engine.getEngineString(IDI_STR_VERB_ERROR);
-			for (uint i = 0; i < verbStr.size(); ++i)
-				err.setChar(verbStr[i], i + 19);
-			_display.printString(err);
-			continue;
-		}
-
-		verb = _verbs[verbStr];
-
-		Common::String nounStr = getWord(line, index);
-
-		if (!_nouns.contains(nounStr)) {
-			Common::String err = _engine.getEngineString(IDI_STR_NOUN_ERROR);
-			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);
-			continue;
-		}
-
-		noun = _nouns[nounStr];
-		return;
-	}
-}
-
-} // End of namespace Adl
diff --git a/engines/adl/parser.h b/engines/adl/parser.h
deleted file mode 100644
index 3c191d9..0000000
--- a/engines/adl/parser.h
+++ /dev/null
@@ -1,66 +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_PARSER_H
-#define ADL_PARSER_H
-
-#include "common/types.h"
-#include "common/hashmap.h"
-#include "common/hash-str.h"
-
-namespace Common {
-class ReadStream;
-class String;
-}
-
-namespace Adl {
-
-class Display;
-
-class Parser {
-public:
-	Parser(AdlEngine &engine, Display &display);
-
-	void loadVerbs(Common::ReadStream &stream) { loadWords(stream, _verbs); }
-	void loadNouns(Common::ReadStream &stream) { loadWords(stream, _nouns); }
-	void getInput(uint &verb, uint &noun);
-
-private:
-	enum {
-		kWordSize = 8
-	};
-
-	typedef Common::HashMap<Common::String, uint> WordMap;
-
-	void loadWords(Common::ReadStream &stream, WordMap &map);
-	Common::String getLine();
-	Common::String getWord(const Common::String &line, uint &index);
-
-	AdlEngine &_engine;
-	Display &_display;
-	WordMap _verbs;
-	WordMap _nouns;
-};
-
-} // End of namespace Adl
-
-#endif


Commit: 93f5e36c9f9a75a2fa939408a76b0a2632c09425
    https://github.com/scummvm/scummvm/commit/93f5e36c9f9a75a2fa939408a76b0a2632c09425
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Add GMM loading and saving

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 3c405b6..8ffb929 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -43,13 +43,31 @@ AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) :
 		Engine(syst),
 		_gameDescription(gd),
 		_display(nullptr),
-		_isRestarting(false) {
+		_isRestarting(false),
+		_isRestoring(false),
+		_saveVerb(0),
+		_saveNoun(0),
+		_restoreVerb(0),
+		_restoreNoun(0),
+		_canSaveNow(false),
+		_canRestoreNow(false) {
 }
 
 AdlEngine::~AdlEngine() {
 	delete _display;
 }
 
+bool AdlEngine::hasFeature(EngineFeature f) const {
+	switch (f) {
+	case kSupportsLoadingDuringRuntime:
+	case kSupportsSavingDuringRuntime:
+	case kSupportsRTL:
+		return true;
+	default:
+		return false;
+	}
+}
+
 Common::Error AdlEngine::run() {
 	initGraphics(560, 384, true);
 
@@ -71,6 +89,7 @@ Common::Error AdlEngine::run() {
 		if (!loadState(saveSlot))
 			error("Failed to load save game from slot %i", saveSlot);
 		_display->setCursorPos(Common::Point(0, 23));
+		_isRestoring = true;
 	} else {
 		runIntro();
 		initState();
@@ -162,6 +181,16 @@ void AdlEngine::readCommands(Common::ReadStream &stream, Commands &commands) {
 		if (stream.eos() || stream.err())
 			error("Failed to read commands");
 
+		if (command.numCond == 0 && command.script[0] == IDO_ACT_SAVE) {
+			_saveVerb = command.verb;
+			_saveNoun = command.noun;
+		}
+
+		if (command.numCond == 0 && command.script[0] == IDO_ACT_LOAD) {
+			_restoreVerb = command.verb;
+			_restoreNoun = command.noun;
+		}
+
 		commands.push_back(command);
 	}
 }
@@ -278,7 +307,15 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			break;
 		case IDO_ACT_RESTART: {
 			_display->printString(_strings[IDI_STR_PLAY_AGAIN]);
+
+			// We allow restoring via GMM here
+			_canRestoreNow = true;
 			Common::String input = inputString();
+			_canRestoreNow = false;
+
+			if (_isRestoring)
+				return;
+
 			if (input.size() == 0 || input[0] != APPLECHAR('N')) {
 				_isRestarting = true;
 				_display->clear(0x00);
@@ -341,7 +378,7 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 	}
 }
 
-bool AdlEngine::checkCommand(const Command &command, byte verb, byte noun) {
+bool AdlEngine::matchCommand(const Command &command, byte verb, byte noun, bool run) {
 	if (command.room != IDI_NONE && command.room != _state.room)
 		return false;
 
@@ -384,7 +421,8 @@ bool AdlEngine::checkCommand(const Command &command, byte verb, byte noun) {
 		}
 	}
 
-	doActions(command, noun, offset);
+	if (run)
+		doActions(command, noun, offset);
 
 	return true;
 }
@@ -395,7 +433,7 @@ bool AdlEngine::doOneCommand(const Commands &commands, byte verb, byte noun) {
 	Commands::const_iterator cmd;
 
 	for (cmd = commands.begin(); cmd != commands.end(); ++cmd)
-		if (checkCommand(*cmd, verb, noun))
+		if (matchCommand(*cmd, verb, noun))
 			return true;
 
 	return false;
@@ -403,14 +441,43 @@ bool AdlEngine::doOneCommand(const Commands &commands, byte verb, byte noun) {
 
 void AdlEngine::doAllCommands(const Commands &commands, byte verb, byte noun) {
 	Commands::const_iterator cmd;
+	bool oldIsRestoring = _isRestoring;
 
 	for (cmd = commands.begin(); cmd != commands.end(); ++cmd) {
-		checkCommand(*cmd, verb, noun);
-		if (_isRestarting)
-			return;
+		matchCommand(*cmd, verb, noun);
+
+		// We assume no restarts happen in this command group. This
+		// simplifies enabling GMM savegame loading on the restart
+		// prompt.
+		if (_isRestarting || _isRestoring != oldIsRestoring)
+			error("Unexpected restart action encountered");
 	}
 }
 
+bool AdlEngine::canSaveGameStateCurrently() {
+	if (!_canSaveNow)
+		return false;
+
+	Commands::const_iterator cmd;
+
+	// Here we check whether or not the game currently accepts the command
+	// "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) {
+		if (matchCommand(*cmd, _saveVerb, _saveNoun, false)) {
+			if (cmd->verb != _saveVerb || cmd->noun != _saveNoun)
+				return false;
+			return cmd->numCond == 0 && cmd->script[0] == IDO_ACT_SAVE;
+		}
+	}
+
+	return false;
+}
+
+bool AdlEngine::canLoadGameStateCurrently() {
+	return _canRestoreNow;
+}
+
 void AdlEngine::clearScreen() {
 	_display->setMode(Display::kModeMixed);
 	_display->clear(0x00);
@@ -654,7 +721,7 @@ Common::String AdlEngine::getLine() {
 	while (1) {
 		Common::String line = inputString(APPLECHAR('?'));
 
-		if (shouldQuit())
+		if (shouldQuit() || _isRestoring)
 			return "";
 
 		if ((byte)line[0] == ('\r' | 0x80)) {
@@ -703,7 +770,7 @@ void AdlEngine::getInput(uint &verb, uint &noun) {
 		_display->printString(getEngineString(IDI_STR_ENTER_COMMAND));
 		Common::String line = getLine();
 
-		if (shouldQuit())
+		if (shouldQuit() || _isRestoring)
 			return;
 
 		uint index = 0;
@@ -755,7 +822,7 @@ Common::String AdlEngine::inputString(byte prompt) {
 	while (1) {
 		byte b = inputKey();
 
-		if (g_engine->shouldQuit())
+		if (g_engine->shouldQuit() || _isRestoring)
 			return 0;
 
 		if (b == 0)
@@ -805,7 +872,7 @@ byte AdlEngine::inputKey() {
 
 	_display->showCursor(true);
 
-	while (!g_engine->shouldQuit() && key == 0) {
+	while (!g_engine->shouldQuit() && !_isRestoring && key == 0) {
 		Common::Event event;
 		if (ev->pollEvent(event)) {
 			if (event.type != Common::EVENT_KEYDOWN)
@@ -863,6 +930,22 @@ void AdlEngine::delay(uint32 ms) {
 	}
 }
 
+Common::Error AdlEngine::loadGameState(int slot) {
+	if (loadState(slot)) {
+		_isRestoring = true;
+		return Common::kNoError;
+	}
+
+	return Common::kUnknownError;
+}
+
+Common::Error AdlEngine::saveGameState(int slot, const Common::String &desc) {
+	if (saveState(slot, &desc))
+		return Common::kNoError;
+
+	return Common::kUnknownError;
+}
+
 AdlEngine *AdlEngine::create(GameType type, OSystem *syst, const AdlGameDescription *gd) {
 	switch(type) {
 	case kGameTypeHires1:
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index a9ac79d..4d160f0 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -168,7 +168,7 @@ public:
 	virtual ~AdlEngine();
 
 	const AdlGameDescription *_gameDescription;
-	uint32 getFeatures() const;
+	bool hasFeature(EngineFeature f) const;
 	const char *getGameId() const;
 
 	static AdlEngine *create(GameType type, OSystem *syst, const AdlGameDescription *gd);
@@ -184,12 +184,14 @@ protected:
 	virtual void initState() = 0;
 	virtual void restartGame() = 0;
 	virtual uint getEngineMessage(EngineMessage msg) = 0;
+	bool canSaveGameStateCurrently();
+	bool canLoadGameStateCurrently();
 	Common::String readString(Common::ReadStream &stream, byte until = 0);
 	void printStrings(Common::SeekableReadStream &stream, int count = 1);
 	virtual void printMessage(uint idx, bool wait = true);
 	void wordWrap(Common::String &str);
 	void readCommands(Common::ReadStream &stream, Commands &commands);
-	bool checkCommand(const Command &command, byte verb, byte noun);
+	bool matchCommand(const Command &command, byte verb, byte noun, bool run = true);
 	bool doOneCommand(const Commands &commands, byte verb, byte noun);
 	void doAllCommands(const Commands &commands, byte verb, byte noun);
 	void doActions(const Command &command, byte noun, byte offset);
@@ -213,10 +215,14 @@ protected:
 	Common::String inputString(byte prompt = 0);
 	void delay(uint32 ms);
 	byte inputKey();
+	Common::Error loadGameState(int slot);
+	Common::Error saveGameState(int slot, const Common::String &desc);
 
 	Display *_display;
 	Parser *_parser;
-	bool _isRestarting;
+	bool _isRestarting, _isRestoring;
+	byte _saveVerb, _saveNoun, _restoreVerb, _restoreNoun;
+	bool _canSaveNow, _canRestoreNow;
 
 	Common::Array<Common::String> _strings;
 	Common::Array<Common::String> _messages;
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 5912166..db69a2d 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -371,29 +371,49 @@ void HiRes1Engine::runGame() {
 	printASCIIString("\r\r\r\r\r");
 
 	while (1) {
-		if (_isRestarting)
-			_isRestarting = false;
-
 		uint verb = 0, noun = 0;
-		clearScreen();
-		showRoom();
-		getInput(verb, noun);
 
-		if (!doOneCommand(_roomCommands, verb, noun))
-			printMessage(37);
+		// When restoring from the launcher, we don't read
+		// input on the first iteration. This is needed to
+		// ensure that restoring from the launcher and
+		// restoring in-game brings us to the same game state.
+		// (Also see comment below.)
+		if (!_isRestoring) {
+			clearScreen();
+			showRoom();
 
-		if (_isRestarting)
-			continue;
+			_canSaveNow = _canRestoreNow = true;
+			getInput(verb, noun);
+			_canSaveNow = _canRestoreNow = false;
 
-		doAllCommands(_globalCommands, verb, noun);
+			if (shouldQuit())
+				return;
+
+			if (!doOneCommand(_roomCommands, verb, noun))
+				printMessage(IDI_HR1_MSG_DONT_UNDERSTAND);
+		}
 
-		if (_isRestarting)
+		if (_isRestoring) {
+			// We restored from the GMM or launcher. As restoring
+			// with "RESTORE GAME" does not end command processing,
+			// we don't break it off here either. This essentially
+			// means that restoring a game will always run through
+			// the global commands and increase the move counter
+			// before the first user input.
+			printASCIIString("\r");
+			_isRestoring = false;
+			verb = _restoreVerb;
+			noun = _restoreNoun;
+		}
+
+		// Restarting does end command processing
+		if (_isRestarting) {
+			_isRestarting = false;
 			continue;
+		}
 
+		doAllCommands(_globalCommands, verb, noun);
 		_state.moves++;
-
-		if (shouldQuit())
-			return;
 	}
 }
 


Commit: baa2410a1cbe34606cbb6c0939a800edb09dfc65
    https://github.com/scummvm/scummvm/commit/baa2410a1cbe34606cbb6c0939a800edb09dfc65
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Fix "don't understand" parser response override

Changed paths:
    engines/adl/hires1.cpp



diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index db69a2d..5435191 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -427,7 +427,7 @@ void HiRes1Engine::printMessage(uint idx, bool wait) {
 	case IDI_HR1_MSG_DONT_HAVE_IT:
 		_display->printString(_strings[IDI_HR1_STR_DONT_HAVE_IT]);
 		return;
-	case IDI_MSG_DONT_UNDERSTAND:
+	case IDI_HR1_MSG_DONT_UNDERSTAND:
 		_display->printString(_strings[IDI_HR1_STR_DONT_UNDERSTAND]);
 		return;
 	case IDI_HR1_MSG_GETTING_DARK:


Commit: 84a9f6ce95822efd2c2e0600daf2aeb27a841106
    https://github.com/scummvm/scummvm/commit/84a9f6ce95822efd2c2e0600daf2aeb27a841106
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Add save game meta info support

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



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 8ffb929..633705f 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -33,6 +33,7 @@
 #include "engines/util.h"
 
 #include "graphics/palette.h"
+#include "graphics/thumbnail.h"
 
 #include "adl/adl.h"
 #include "adl/display.h"
@@ -86,7 +87,7 @@ Common::Error AdlEngine::run() {
 
 	int saveSlot = ConfMan.getInt("save_slot");
 	if (saveSlot >= 0) {
-		if (!loadState(saveSlot))
+		if (loadGameState(saveSlot).getCode() != Common::kNoError)
 			error("Failed to load save game from slot %i", saveSlot);
 		_display->setCursorPos(Common::Point(0, 23));
 		_isRestoring = true;
@@ -297,11 +298,11 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			++offset;
 			break;
 		case IDO_ACT_SAVE:
-			saveState(0);
+			saveGameState(0, "");
 			++offset;
 			break;
 		case IDO_ACT_LOAD:
-			loadState(0);
+			loadGameState(0);
 			++offset;
 			// Original engine continues processing here (?)
 			break;
@@ -528,13 +529,13 @@ void AdlEngine::showRoom() {
 	printMessage(curRoom().description, false);
 }
 
-bool AdlEngine::saveState(uint slot, const Common::String *description) {
+Common::Error AdlEngine::saveGameState(int slot, const Common::String &desc) {
 	Common::String fileName = Common::String::format("%s.s%02d", _targetName.c_str(), slot);
 	Common::OutSaveFile *outFile = getSaveFileManager()->openForSaving(fileName);
 
 	if (!outFile) {
 		warning("Failed to open file '%s'", fileName.c_str());
-		return false;
+		return Common::kUnknownError;
 	}
 
 	outFile->writeUint32BE(MKTAG('A', 'D', 'L', ':'));
@@ -542,8 +543,8 @@ bool AdlEngine::saveState(uint slot, const Common::String *description) {
 
 	char name[SAVEGAME_NAME_LEN] = { };
 
-	if (description)
-		strncpy(name, description->c_str(), sizeof(name) - 1);
+	if (!desc.empty())
+		strncpy(name, desc.c_str(), sizeof(name) - 1);
 	else {
 		Common::String defaultName("Save ");
 		defaultName += 'A' + slot;
@@ -552,6 +553,20 @@ bool AdlEngine::saveState(uint slot, const Common::String *description) {
 
 	outFile->write(name, sizeof(name));
 
+	TimeDate t;
+	g_system->getTimeAndDate(t);
+
+	outFile->writeUint16BE(t.tm_year);
+	outFile->writeByte(t.tm_mon);
+	outFile->writeByte(t.tm_mday);
+	outFile->writeByte(t.tm_hour);
+	outFile->writeByte(t.tm_min);
+
+	uint32 playTime = getTotalPlayTime();
+	outFile->writeUint32BE(playTime);
+
+	Graphics::saveThumbnail(*outFile);
+
 	outFile->writeByte(_state.room);
 	outFile->writeByte(_state.moves);
 	outFile->writeByte(_state.isDark);
@@ -580,38 +595,45 @@ bool AdlEngine::saveState(uint slot, const Common::String *description) {
 	if (outFile->err()) {
 		delete outFile;
 		warning("Failed to save game '%s'", fileName.c_str());
-		return false;
+		return Common::kUnknownError;
 	}
 
 	delete outFile;
-	return true;
+	return Common::kNoError;
 }
 
-bool AdlEngine::loadState(uint slot) {
+Common::Error AdlEngine::loadGameState(int slot) {
 	Common::String fileName = Common::String::format("%s.s%02d", _targetName.c_str(), slot);
 	Common::InSaveFile *inFile = getSaveFileManager()->openForLoading(fileName);
 
 	if (!inFile) {
 		warning("Failed to open file '%s'", fileName.c_str());
-		return false;
+		return Common::kUnknownError;
 	}
 
 	if (inFile->readUint32BE() != MKTAG('A', 'D', 'L', ':')) {
 		warning("No header found in '%s'", fileName.c_str());
 		delete inFile;
-		return false;
+		return Common::kUnknownError;
 	}
 
 	byte saveVersion = inFile->readByte();
 	if (saveVersion != SAVEGAME_VERSION) {
 		warning("Save game version %i not supported", saveVersion);
 		delete inFile;
-		return false;
+		return Common::kUnknownError;
 	}
 
-	initState();
-
+	// Skip description
 	inFile->seek(SAVEGAME_NAME_LEN, SEEK_CUR);
+	// Skip save time
+	inFile->seek(6, SEEK_CUR);
+
+	uint32 playTime = inFile->readUint32BE();
+
+	Graphics::skipThumbnail(*inFile);
+
+	initState();
 
 	_state.room = inFile->readByte();
 	_state.moves = inFile->readByte();
@@ -649,7 +671,10 @@ bool AdlEngine::loadState(uint slot) {
 		error("Failed to load game '%s'", fileName.c_str());
 
 	delete inFile;
-	return true;
+
+	setTotalPlayTime(playTime);
+
+	return Common::kNoError;
 }
 
 Room &AdlEngine::room(uint i) {
@@ -930,22 +955,6 @@ void AdlEngine::delay(uint32 ms) {
 	}
 }
 
-Common::Error AdlEngine::loadGameState(int slot) {
-	if (loadState(slot)) {
-		_isRestoring = true;
-		return Common::kNoError;
-	}
-
-	return Common::kUnknownError;
-}
-
-Common::Error AdlEngine::saveGameState(int slot, const Common::String &desc) {
-	if (saveState(slot, &desc))
-		return Common::kNoError;
-
-	return Common::kUnknownError;
-}
-
 AdlEngine *AdlEngine::create(GameType type, OSystem *syst, const AdlGameDescription *gd) {
 	switch(type) {
 	case kGameTypeHires1:
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 4d160f0..f8b2dca 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -237,8 +237,6 @@ protected:
 
 private:
 	void printEngineMessage(EngineMessage);
-	bool saveState(uint slot, const Common::String *description = nullptr);
-	bool loadState(uint slot);
 	Common::String getTargetName() { return _targetName; }
 	byte convertKey(uint16 ascii);
 
diff --git a/engines/adl/detection.cpp b/engines/adl/detection.cpp
index 5fe469d..27ce593 100644
--- a/engines/adl/detection.cpp
+++ b/engines/adl/detection.cpp
@@ -23,6 +23,8 @@
 #include "common/system.h"
 #include "common/savefile.h"
 
+#include "graphics/thumbnail.h"
+
 #include "engines/advancedDetector.h"
 
 #include "adl/adl.h"
@@ -73,8 +75,10 @@ public:
 	}
 
 	bool hasFeature(MetaEngineFeature f) const;
-	int getMaximumSaveSlot() const { return 15; }
+	SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
+	int getMaximumSaveSlot() const { return 'O' - 'A'; }
 	SaveStateList listSaves(const char *target) const;
+	void removeSaveState(const char *target, int slot) const;
 
 	bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const;
 };
@@ -83,17 +87,76 @@ bool AdlMetaEngine::hasFeature(MetaEngineFeature f) const {
 	switch(f) {
 	case kSupportsListSaves:
 	case kSupportsLoadingDuringStartup:
+	case kSupportsDeleteSave:
+	case kSavesSupportMetaInfo:
+	case kSavesSupportThumbnail:
+	case kSavesSupportCreationDate:
+	case kSavesSupportPlayTime:
 		return true;
 	default:
 		return false;
 	}
 }
 
+SaveStateDescriptor AdlMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
+	Common::String fileName = Common::String::format("%s.s%02d", target, slot);
+	Common::InSaveFile *inFile = g_system->getSavefileManager()->openForLoading(fileName);
+
+	if (!inFile)
+		return SaveStateDescriptor();
+
+	if (inFile->readUint32BE() != MKTAG('A', 'D', 'L', ':')) {
+		delete inFile;
+		return SaveStateDescriptor();
+	}
+
+	byte saveVersion = inFile->readByte();
+	if (saveVersion != SAVEGAME_VERSION) {
+		delete inFile;
+		return SaveStateDescriptor();
+	}
+
+	char name[SAVEGAME_NAME_LEN] = { };
+	inFile->read(name, sizeof(name) - 1);
+	inFile->readByte();
+
+	if (inFile->eos() || inFile->err()) {
+		delete inFile;
+		return SaveStateDescriptor();
+	}
+
+	SaveStateDescriptor sd(slot, name);
+
+	int year = inFile->readUint16BE();
+	int month = inFile->readByte();
+	int day = inFile->readByte();
+	sd.setSaveDate(year + 1900, month + 1, day);
+
+	int hour = inFile->readByte();
+	int minutes = inFile->readByte();
+	sd.setSaveTime(hour, minutes);
+
+	uint32 playTime = inFile->readUint32BE();
+	sd.setPlayTime(playTime);
+
+	if (inFile->eos() || inFile->err()) {
+		delete inFile;
+		return SaveStateDescriptor();
+	}
+
+	Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*inFile);
+	sd.setThumbnail(thumbnail);
+
+	delete inFile;
+	return sd;
+}
+
 SaveStateList AdlMetaEngine::listSaves(const char *target) const {
 	Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
 	Common::StringArray files = saveFileMan->listSavefiles(Common::String(target) + ".s##");
 
 	SaveStateList saveList;
+
 	for (uint i = 0; i < files.size(); ++i) {
 		const Common::String &fileName = files[i];
 		Common::InSaveFile *inFile = saveFileMan->openForLoading(fileName);
@@ -129,6 +192,11 @@ SaveStateList AdlMetaEngine::listSaves(const char *target) const {
 	return saveList;
 }
 
+void AdlMetaEngine::removeSaveState(const char *target, int slot) const {
+	Common::String fileName = Common::String::format("%s.s%02d", target, slot);
+	g_system->getSavefileManager()->removeSavefile(fileName);
+}
+
 bool AdlMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const {
 	if (gd)
 		*engine = AdlEngine::create(((const AdlGameDescription *)gd)->gameType, syst, (const AdlGameDescription *)gd);


Commit: 912a31fa652c389b14e3d77998736813e3b621d0
    https://github.com/scummvm/scummvm/commit/912a31fa652c389b14e3d77998736813e3b621d0
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Add monochrome and scanline rendering

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



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 633705f..15a6c32 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -70,19 +70,6 @@ bool AdlEngine::hasFeature(EngineFeature f) const {
 }
 
 Common::Error AdlEngine::run() {
-	initGraphics(560, 384, true);
-
-	byte palette[6 * 3] = {
-		0x00, 0x00, 0x00,
-		0xff, 0xff, 0xff,
-		0xc7, 0x34, 0xff,
-		0x38, 0xcb, 0x00,
-		0x00, 0x00, 0xff, // FIXME
-		0xff, 0xa5, 0x00  // FIXME
-	};
-
-	g_system->getPaletteManager()->setPalette(palette, 0, 6);
-
 	_display = new Display();
 
 	int saveSlot = ConfMan.getInt("save_slot");
diff --git a/engines/adl/detection.cpp b/engines/adl/detection.cpp
index 27ce593..e556e12 100644
--- a/engines/adl/detection.cpp
+++ b/engines/adl/detection.cpp
@@ -22,6 +22,7 @@
 
 #include "common/system.h"
 #include "common/savefile.h"
+#include "common/translation.h"
 
 #include "graphics/thumbnail.h"
 
@@ -31,6 +32,33 @@
 
 namespace Adl {
 
+#define GAMEOPTION_COLOR      GUIO_GAMEOPTIONS1
+#define GAMEOPTION_SCANLINES  GUIO_GAMEOPTIONS2
+
+static const ADExtraGuiOptionsMap optionsList[] = {
+	{
+		GAMEOPTION_COLOR,
+		{
+			_s("Color mode"),
+			_s("Use color graphics"),
+			"color",
+			false
+		}
+	},
+
+	{
+		GAMEOPTION_SCANLINES,
+		{
+			_s("Scanlines"),
+			_s("Show scanlines"),
+			"scanlines",
+			false
+		}
+	},
+
+	AD_EXTRA_GUI_OPTIONS_TERMINATOR
+};
+
 struct AdlGameDescription {
 	ADGameDescription desc;
 	GameType gameType;
@@ -55,7 +83,7 @@ static const AdlGameDescription gameDescriptions[] = {
 			Common::EN_ANY,
 			Common::kPlatformApple2GS, // FIXME
 			ADGF_NO_FLAGS,
-			GUIO0()
+			GUIO2(GAMEOPTION_COLOR, GAMEOPTION_SCANLINES)
 		},
 		kGameTypeHires1
 	},
@@ -64,7 +92,7 @@ static const AdlGameDescription gameDescriptions[] = {
 
 class AdlMetaEngine : public AdvancedMetaEngine {
 public:
-	AdlMetaEngine() : AdvancedMetaEngine(gameDescriptions, sizeof(AdlGameDescription), adlGames) { }
+	AdlMetaEngine() : AdvancedMetaEngine(gameDescriptions, sizeof(AdlGameDescription), adlGames, optionsList) { }
 
 	const char *getName() const {
 		return "ADL";
diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp
index a6d94f6..ade05ab 100644
--- a/engines/adl/display.cpp
+++ b/engines/adl/display.cpp
@@ -29,11 +29,14 @@
 #include "common/events.h"
 #include "common/rect.h"
 #include "common/array.h"
+#include "common/config-manager.h"
 #include "engines/engine.h"
+#include "engines/util.h"
+#include "graphics/palette.h"
 
 namespace Adl {
 
-static byte font[64][5] = {
+static const byte font[64][5] = {
 	{ 0x7c, 0x82, 0xba, 0xb2, 0x9c }, { 0xf8, 0x24, 0x22, 0x24, 0xf8 }, // @A
 	{ 0xfe, 0x92, 0x92, 0x92, 0x6c }, { 0x7c, 0x82, 0x82, 0x82, 0x44 }, // BC
 	{ 0xfe, 0x82, 0x82, 0x82, 0x7c }, { 0xfe, 0x92, 0x92, 0x92, 0x82 }, // DE
@@ -69,10 +72,17 @@ static byte font[64][5] = {
 };
 
 Display::Display() :
-		_scanlines(false),
 		_cursorPos(0),
 		_mode(kModeText),
 		_showCursor(false) {
+
+	initGraphics(560, 384, true);
+
+	_monochrome = !ConfMan.getBool("color");
+	_scanlines = ConfMan.getBool("scanlines");
+
+	setPalette(_scanlines, _monochrome);
+
 	_frameBuf = new byte[kFrameBufSize];
 	_frameBufSurface = new Graphics::Surface;
 	_frameBufSurface->create(kWidth * 2, kHeight * 2, Graphics::PixelFormat::createFormatCLUT8());
@@ -98,11 +108,37 @@ Display::~Display() {
 	delete _font;
 }
 
+void Display::setPalette(bool scanlines, bool monochrome) {
+	const byte colorPal[6 * 3] = {
+		0x00, 0x00, 0x00,
+		0xff, 0xff, 0xff,
+		0xc7, 0x34, 0xff,
+		0x38, 0xcb, 0x00,
+		0x0d, 0xa1, 0xff,
+		0xf2, 0x5e, 0x00
+	};
+
+	const byte monoPal[2 * 3] = {
+		0x00, 0x00, 0x00,
+		0x00, 0xc0, 0x01
+	};
+
+	if (monochrome) {
+		g_system->getPaletteManager()->setPalette(monoPal, 0, 2);
+		if (!scanlines)
+			g_system->getPaletteManager()->setPalette(monoPal, 6, 2);
+	} else {
+		g_system->getPaletteManager()->setPalette(colorPal, 0, 6);
+		if (!scanlines)
+			g_system->getPaletteManager()->setPalette(colorPal, 6, 6);
+	}
+}
+
 void Display::loadFrameBuffer(Common::ReadStream &stream) {
 	stream.read(_frameBuf, kFrameBufSize);
 }
 
-void Display::decodeScanline(byte *dst, int pitch, byte *src) {
+void Display::decodeScanlineColor(byte *dst, int pitch, byte *src) {
 	// TODO: shift secondPal by half a pixel
 
 	bool prevOn = false;
@@ -135,11 +171,8 @@ void Display::decodeScanline(byte *dst, int pitch, byte *src) {
 
 			dst[0] = color;
 			dst[1] = color;
-
-			if (!_scanlines) {
-				dst[pitch] = color;
-				dst[pitch + 1] = color;
-			}
+			dst[pitch] = color + 6;
+			dst[pitch + 1] = color + 6;
 
 			dst += 2;
 			prevOn = curOn;
@@ -147,6 +180,33 @@ void Display::decodeScanline(byte *dst, int pitch, byte *src) {
 	}
 }
 
+void Display::decodeScanlineMono(byte *dst, int pitch, byte *src) {
+	// TODO: shift secondPal by half a pixel
+
+	for (uint j = 0; j < 39; ++j) {
+		for (uint k = 0; k < 7; ++k) {
+			byte color = 0;
+
+			if (src[j] & (1 << k))
+				color = 1;
+
+			dst[0] = color;
+			dst[1] = color;
+			dst[pitch] = color + 6;
+			dst[pitch + 1] = color + 6;
+
+			dst += 2;
+		}
+	}
+}
+
+void Display::decodeScanline(byte *dst, int pitch, byte *src) {
+	if (_monochrome)
+		decodeScanlineMono(dst, pitch, src);
+	else
+		decodeScanlineColor(dst, pitch, src);
+}
+
 Display::PixelPos Display::getPixelPos(byte x, byte y) {
 	PixelPos pixelPos;
 
@@ -390,16 +450,23 @@ void Display::drawChar(byte c, int x, int y) {
 	byte *buf = (byte *)_font->getPixels() + y * _font->pitch + x;
 
 	for (uint row = 0; row < 8; ++row) {
-		for (uint col = 1; col < 6; ++col)
+		if (row & 1) {
+			buf[_font->pitch] = 6;
+			buf[_font->pitch + 1] = 6;
+			buf[_font->pitch + 6 * 2] = 6;
+			buf[_font->pitch + 6 * 2 + 1] = 6;
+		}
+		for (uint col = 1; col < 6; ++col) {
 			if (font[c][col - 1] & (1 << row)) {
 				buf[col * 2] = 1;
 				buf[col * 2 + 1] = 1;
-
-				if (!_scanlines) {
-					buf[_font->pitch + col * 2] = 1;
-					buf[_font->pitch + col * 2 + 1] = 1;
-				}
+				buf[_font->pitch + col * 2] = 1 + 6;
+				buf[_font->pitch + col * 2 + 1] = 1 + 6;
+			} else {
+				buf[_font->pitch + col * 2] = 6;
+				buf[_font->pitch + col * 2 + 1] = 6;
 			}
+		}
 
 		buf += 2 * _font->pitch;
 	}
@@ -417,10 +484,15 @@ void Display::createFont() {
 	byte *buf = (byte *)_font->getPixels();
 	byte *bufInv = buf + (_font->h / 2) * _font->pitch;
 
-	for (uint row = 0; row < _font->h / 2; ++row) {
-		if (!_scanlines || !(row & 1))
-			for (uint col = 0; col < _font->w; ++col)
-				bufInv[col] = buf[col] ? 0 : 1;
+	for (uint row = 0; row < _font->h / 2; row += 2) {
+		for (uint col = 0; col < _font->w; ++col)
+			bufInv[col] = (buf[col] ? 0 : 1);
+
+		buf += _font->pitch;
+		bufInv += _font->pitch;
+
+		for (uint col = 0; col < _font->w; ++col)
+			bufInv[col] = (buf[col] == 7 ? 6 : 7);
 
 		buf += _font->pitch;
 		bufInv += _font->pitch;
diff --git a/engines/adl/display.h b/engines/adl/display.h
index 91ae447..21cc599 100644
--- a/engines/adl/display.h
+++ b/engines/adl/display.h
@@ -50,6 +50,7 @@ public:
 
 	Display();
 	~Display();
+	void setPalette(bool monochrome, bool scanlines);
 	void loadFrameBuffer(Common::ReadStream &stream);
 	void decodeFrameBuffer();
 	void updateScreen();
@@ -84,6 +85,8 @@ private:
 	};
 
 	void decodeScanline(byte *dst, int pitch, byte *src);
+	void decodeScanlineColor(byte *dst, int pitch, byte *src);
+	void decodeScanlineMono(byte *dst, int pitch, byte *src);
 	PixelPos getPixelPos(byte x, byte y);
 	byte getPixelColor(byte x, byte color);
 	void drawChar(byte c, int x, int y);
@@ -103,6 +106,7 @@ private:
 	int _cursorPos;
 	Mode _mode;
 	bool _showCursor;
+	bool _monochrome;
 };
  
 } // End of namespace Adl


Commit: b30fb417acb29dee415a784f15f63772a010b4d3
    https://github.com/scummvm/scummvm/commit/b30fb417acb29dee415a784f15f63772a010b4d3
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Disable scanlines when saving thumbnail

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



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 15a6c32..083fde9 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -552,7 +552,7 @@ Common::Error AdlEngine::saveGameState(int slot, const Common::String &desc) {
 	uint32 playTime = getTotalPlayTime();
 	outFile->writeUint32BE(playTime);
 
-	Graphics::saveThumbnail(*outFile);
+	_display->saveThumbnail(*outFile);
 
 	outFile->writeByte(_state.room);
 	outFile->writeByte(_state.moves);
diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp
index ade05ab..6a7cc69 100644
--- a/engines/adl/display.cpp
+++ b/engines/adl/display.cpp
@@ -33,6 +33,7 @@
 #include "engines/engine.h"
 #include "engines/util.h"
 #include "graphics/palette.h"
+#include "graphics/thumbnail.h"
 
 namespace Adl {
 
@@ -81,7 +82,12 @@ Display::Display() :
 	_monochrome = !ConfMan.getBool("color");
 	_scanlines = ConfMan.getBool("scanlines");
 
-	setPalette(_scanlines, _monochrome);
+	if (_monochrome)
+		setMonoPalette();
+	else
+		setColorPalette();
+
+	enableScanlines(_scanlines);
 
 	_frameBuf = new byte[kFrameBufSize];
 	_frameBufSurface = new Graphics::Surface;
@@ -108,7 +114,34 @@ Display::~Display() {
 	delete _font;
 }
 
-void Display::setPalette(bool scanlines, bool monochrome) {
+bool Display::saveThumbnail(Common::WriteStream &out) {
+	if (_scanlines) {
+		enableScanlines(false);
+		g_system->updateScreen();
+	}
+
+	bool retval = Graphics::saveThumbnail(out);
+
+	if (_scanlines) {
+		enableScanlines(true);
+		g_system->updateScreen();
+	}
+
+	return retval;
+}
+
+void Display::enableScanlines(bool enable) {
+	byte pal[6 * 3] = { };
+
+	if (enable)
+		g_system->getPaletteManager()->setPalette(pal, 6, 6);
+	else {
+		g_system->getPaletteManager()->grabPalette(pal, 0, 6);
+		g_system->getPaletteManager()->setPalette(pal, 6, 6);
+	}
+}
+
+void Display::setColorPalette() {
 	const byte colorPal[6 * 3] = {
 		0x00, 0x00, 0x00,
 		0xff, 0xff, 0xff,
@@ -118,20 +151,16 @@ void Display::setPalette(bool scanlines, bool monochrome) {
 		0xf2, 0x5e, 0x00
 	};
 
+	g_system->getPaletteManager()->setPalette(colorPal, 0, 6);
+}
+
+void Display::setMonoPalette() {
 	const byte monoPal[2 * 3] = {
 		0x00, 0x00, 0x00,
 		0x00, 0xc0, 0x01
 	};
 
-	if (monochrome) {
-		g_system->getPaletteManager()->setPalette(monoPal, 0, 2);
-		if (!scanlines)
-			g_system->getPaletteManager()->setPalette(monoPal, 6, 2);
-	} else {
-		g_system->getPaletteManager()->setPalette(colorPal, 0, 6);
-		if (!scanlines)
-			g_system->getPaletteManager()->setPalette(colorPal, 6, 6);
-	}
+	g_system->getPaletteManager()->setPalette(monoPal, 0, 2);
 }
 
 void Display::loadFrameBuffer(Common::ReadStream &stream) {
diff --git a/engines/adl/display.h b/engines/adl/display.h
index 21cc599..12e3ab9 100644
--- a/engines/adl/display.h
+++ b/engines/adl/display.h
@@ -28,6 +28,7 @@
 
 namespace Common {
 class ReadStream;
+class WriteStream;
 class String;
 class Point;
 }
@@ -50,7 +51,9 @@ public:
 
 	Display();
 	~Display();
-	void setPalette(bool monochrome, bool scanlines);
+	void enableScanlines(bool enable);
+	void setMonoPalette();
+	void setColorPalette();
 	void loadFrameBuffer(Common::ReadStream &stream);
 	void decodeFrameBuffer();
 	void updateScreen();
@@ -69,6 +72,7 @@ public:
 	void setCharAtCursor(byte c);
 	void showCursor(bool enable);
 	void updateTextSurface();
+	bool saveThumbnail(Common::WriteStream &out);
 
 private:
 	enum {


Commit: d5cc42f1c233a45abb879818af503ec7b91c6f34
    https://github.com/scummvm/scummvm/commit/d5cc42f1c233a45abb879818af503ec7b91c6f34
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Make frame buffer linear

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



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 083fde9..90a9a0d 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -484,7 +484,7 @@ void AdlEngine::drawItems() {
 			if (curRoom().picture == curRoom().curPicture) {
 				const Common::Point &p =  _itemOffsets[dropped];
 				if (item->isLineArt)
-					_display->drawLineArt(_lineArt[item->picture - 1], p);
+					drawLineArt(_lineArt[item->picture - 1], p);
 				else
 					drawPic(item->picture, p);
 				++dropped;
@@ -497,7 +497,7 @@ void AdlEngine::drawItems() {
 		for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
 			if (*pic == curRoom().curPicture) {
 				if (item->isLineArt)
-					_display->drawLineArt(_lineArt[item->picture - 1], item->position);
+					drawLineArt(_lineArt[item->picture - 1], item->position);
 				else
 					drawPic(item->picture, item->position);
 				continue;
@@ -942,6 +942,50 @@ void AdlEngine::delay(uint32 ms) {
 	}
 }
 
+void AdlEngine::drawNextPixel(Common::Point &p, byte color, byte bits, byte quadrant) {
+	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, Common::Point p, byte rotation, byte scaling, byte color) {
+	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;
+
+	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);
+	}
+}
+
 AdlEngine *AdlEngine::create(GameType type, OSystem *syst, const AdlGameDescription *gd) {
 	switch(type) {
 	case kGameTypeHires1:
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index f8b2dca..84b9214 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -198,6 +198,8 @@ protected:
 	void clearScreen();
 	virtual void drawPic(byte pic, Common::Point pos = Common::Point()) = 0;
 	void drawItems();
+	void drawNextPixel(Common::Point &p, byte color, byte bits, byte quadrant);
+	void drawLineArt(const Common::Array<byte> &lineArt, Common::Point p, byte rotation = 0, byte scaling = 1, byte color = 0x7f);
 	void showRoom();
 	void takeItem(byte noun);
 	void dropItem(byte noun);
diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp
index 6a7cc69..90ca1b6 100644
--- a/engines/adl/display.cpp
+++ b/engines/adl/display.cpp
@@ -89,7 +89,7 @@ Display::Display() :
 
 	enableScanlines(_scanlines);
 
-	_frameBuf = new byte[kFrameBufSize];
+	_frameBuf = new byte[kWidth * kHeight / 7];
 	_frameBufSurface = new Graphics::Surface;
 	_frameBufSurface->create(kWidth * 2, kHeight * 2, Graphics::PixelFormat::createFormatCLUT8());
 
@@ -164,7 +164,19 @@ void Display::setMonoPalette() {
 }
 
 void Display::loadFrameBuffer(Common::ReadStream &stream) {
-	stream.read(_frameBuf, kFrameBufSize);
+	for (uint j = 0; j < 8; ++j) {
+		for (uint i = 0; i < 8; ++i) {
+			byte *dst = _frameBuf + kWidth / 7  * (i * 8 + j);
+			stream.read(dst, kWidth / 7);
+			dst += kWidth / 7 * 64;
+			stream.read(dst, kWidth / 7);
+			dst += kWidth / 7 * 64;
+			stream.read(dst, kWidth / 7);
+			stream.readUint32LE();
+			stream.readUint32LE();
+			dst += kWidth / 7 * 64;
+		}
+	}
 }
 
 void Display::decodeScanlineColor(byte *dst, int pitch, byte *src) {
@@ -236,224 +248,45 @@ void Display::decodeScanline(byte *dst, int pitch, byte *src) {
 		decodeScanlineColor(dst, pitch, src);
 }
 
-Display::PixelPos Display::getPixelPos(byte x, byte y) {
-	PixelPos pixelPos;
-
-	// FIXME: check X, Y range
-
-	byte offsetL = y & 0xc0;
-	offsetL |= offsetL >> 2;
-	byte offsetH = y;
-	y <<= 2;
-	offsetH <<= 1;
-	offsetH |= y >> 7;
-	y <<= 1;
-	offsetH <<= 1;
-	offsetH |= y >> 7;
-	y <<= 1;
-	offsetL >>= 1;
-	offsetL |= y & 0x80;
-	y <<= 1;
-	offsetH = offsetH & 0x1f;
-	pixelPos.rowAddr = (offsetH << 8) | offsetL;
-	pixelPos.byteOffset = x / 7;
-	pixelPos.bitMask = 0x80 | (1 << x % 7);
-
-	return pixelPos;
-}
-
-byte Display::getPixelColor(byte offset, byte color) {
-	if (offset & 1) {
-		byte c = color << 1;
-		if (c >= 0x40 && c < 0xc0)
-			return color ^ 0x7f;
-	}
-
-	return color;
-}
-
 void Display::decodeFrameBuffer() {
 	byte *src = _frameBuf;
-	int pitch = _frameBufSurface->pitch;
-	for (int j = 0; j < 8; ++j) {
-		for (int i = 0; i < 8; ++i) {
-			byte *dst = (byte *)_frameBufSurface->getPixels() + pitch * 2 * (i * 8 + j);
-			decodeScanline(dst, pitch, src);
-			src += 40;
-			dst += pitch * 2 * 64;
-			decodeScanline(dst, pitch, src);
-			src += 40;
-			dst += pitch * 2 * 64;
-			decodeScanline(dst, pitch, src);
-			src += 48;
-			dst += pitch * 2 * 64;
-		}
-	}
-}
-
-void Display::drawPixel(byte x, byte y, byte color) {
-	PixelPos p = getPixelPos(x, y);
-	byte c = getPixelColor(p.byteOffset, color);
-	byte *b = _frameBuf + p.rowAddr + p.byteOffset;
-	c ^= *b;
-	c &= p.bitMask;
-	c ^= *b;
-	*b = c;
-}
+	byte *dst = (byte *)_frameBufSurface->getPixels();
 
-void Display::moveX(PixelPos &p, byte &color, bool left) {
-	if (left) {
-		byte bit = p.bitMask;
-		bool b = bit & 1;
-		bit >>= 1;
-		if (!b) {
-			bit ^= 0xc0;
-			p.bitMask = bit;
-			return;
-		}
-		--p.byteOffset;
-		if (p.byteOffset & 0x80)
-			p.byteOffset = 39;
-		p.bitMask = 0xc0;
-	} else {
-		byte bit = p.bitMask;
-		bit <<= 1;
-		bit ^= 0x80;
-		if (bit & 0x80) {
-			p.bitMask = bit;
-			return;
-		}
-		p.bitMask = 0x81;
-		++p.byteOffset;
-		if (p.byteOffset == 40)
-			p.byteOffset = 0;
+	for (uint i = 0; i < kHeight; ++i) {
+		decodeScanline(dst, _frameBufSurface->pitch, src);
+		src += kWidth / 7;
+		dst += _frameBufSurface->pitch * 2;
 	}
-
-	color = getPixelColor(p.byteOffset, color);
 }
 
-void Display::moveY(PixelPos &p, bool down) {
-	if (!down) {
-		if (p.rowAddr & 0x1c00)
-			p.rowAddr -= 0x400;
-		else if (p.rowAddr & 0x380)
-			p.rowAddr += 0x1b80;
-		else {
-			p.rowAddr += 0x1f58;
-			if (!(p.rowAddr & 0x80))
-				p.rowAddr += 0x78; // Wrap around
-		}
-	} else {
-		p.rowAddr += 0x400;
-		if (p.rowAddr & 0x1c00)
-			return;
-		else if ((p.rowAddr & 0x380) != 0x380)
-			p.rowAddr -= 0x1f80;
-		else {
-			p.rowAddr -= 0x2358;
-			if ((p.rowAddr & 0x78) == 0x78)
-				p.rowAddr -= 0x78; // Wrap around
-		}
-	}
-}
+void Display::putPixel(Common::Point p, byte color) {
+	byte offset = p.x / 7;
 
-void Display::drawNextPixel(Display::PixelPos &p, byte &color, byte bits, byte quadrant) {
-	if (bits & 4) {
-		byte b = (_frameBuf[p.rowAddr + p.byteOffset] ^ color) & p.bitMask;
-		_frameBuf[p.rowAddr + p.byteOffset] ^= b;
+	if (offset & 1) {
+		byte c = color << 1;
+		if (c >= 0x40 && c < 0xc0)
+			color ^= 0x7f;
 	}
 
-	bits += quadrant;
-
-	if (bits & 1)
-		moveX(p, color, bits & 2);
-	else
-		moveY(p, bits & 2);
-}
-
-void Display::drawLineArt(const Common::Array<byte> &lineArt, Common::Point p, byte rotation, byte scaling, byte color) {
-	const byte stepping[] = {
-		0xff, 0xfe, 0xfa, 0xf4, 0xec, 0xe1, 0xd4, 0xc5,
-		0xb4, 0xa1, 0x8d, 0x78, 0x61, 0x49, 0x31, 0x18,
-		0xff
-	};
-
-	PixelPos pos = getPixelPos(p.x, p.y);
-	byte c = getPixelColor(pos.byteOffset, color);
-
-	byte quadrant = rotation >> 4;
-	rotation &= 0xf;
-	byte xStep = stepping[rotation];
-	byte yStep = stepping[(rotation ^ 0xf) + 1] + 1;
-
-	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(pos, c, b, quadrant);
-				xFrac += xStep + 1;
-				if (yFrac + yStep > 255)
-					drawNextPixel(pos, c, b, quadrant + 1);
-				yFrac += yStep;
-			}
-			b >>= 3;
-		} while (b != 0);
-	}
+	byte *b = _frameBuf + p.y * kWidth / 7 + offset;
+	color ^= *b;
+	color &= 1 << (p.x % 7);
+	*b ^= color;
 }
 
-void Display::drawLine(Common::Point p1, Common::Point p2, byte color) {
-	PixelPos p = getPixelPos(p1.x, p1.y);
-	byte c = getPixelColor(p.byteOffset, color);
-
-	int16 deltaX = p2.x - p1.x;
-	byte dir = deltaX >> 8;
-
-	if (deltaX < 0)
-		deltaX = -deltaX;
-
-	int16 err = deltaX;
-
-	int16 deltaY = p2.y - p1.y - 1;
-	dir >>= 1;
-	if (deltaY >= 0) {
-		deltaY = -deltaY - 2;
-		dir |= 0x80;
-	}
-
-	int16 steps = deltaY - deltaX;
-
-	err += deltaY + 1;
-
-	while (1) {
-		byte *b = _frameBuf + p.rowAddr + p.byteOffset;
-		byte d = *b;
-		d ^= c;
-		d &= p.bitMask;
-		d ^= *b;
-		*b = d;
+void Display::clear(byte color) {
+	byte val = 0;
 
-		if (++steps == 0)
-			return;
+	byte c = color << 1;
+	if (c >= 0x40 && c < 0xc0)
+		val = 0x7f;
 
-		if (err < 0) {
-			moveY(p, dir & 0x80);
-			err += deltaX;
-		} else {
-			moveX(p, c, dir & 0x40);
-			err += deltaY + 1;
-		}
+	for (uint i = 0; i < kWidth / 7 * kHeight; ++i) {
+		_frameBuf[i] = color;
+		color ^= val;
 	}
 }
 
-void Display::clear(byte color) {
-	for (uint i = 0; i < kFrameBufSize; ++i)
-		_frameBuf[i] = getPixelColor(i & 1, color);
-}
-
 void Display::updateTextSurface() {
 	for (uint row = 0; row < 24; ++row)
 		for (uint col = 0; col < 40; ++col) {
diff --git a/engines/adl/display.h b/engines/adl/display.h
index 12e3ab9..0452b27 100644
--- a/engines/adl/display.h
+++ b/engines/adl/display.h
@@ -58,10 +58,8 @@ public:
 	void decodeFrameBuffer();
 	void updateScreen();
 	void setMode(Mode mode) { _mode = mode; }
-	void drawPixel(byte x, byte y, byte color);
-	void drawLine(Common::Point p1, Common::Point p2, byte color);
+	void putPixel(Common::Point p1, byte color);
 	void clear(byte color);
-	void drawLineArt(const Common::Array<byte> &lineArt, Common::Point p, byte rotation = 0, byte scaling = 1, byte color = 0x7f);
 	void setCursorPos(Common::Point pos);
 
 	void home();
@@ -78,7 +76,6 @@ private:
 	enum {
 		kWidth = 280,
 		kHeight = 192,
-		kFrameBufSize = 0x2000,
 		kTextBufSize = 40 * 24
 	};
 
@@ -91,13 +88,8 @@ private:
 	void decodeScanline(byte *dst, int pitch, byte *src);
 	void decodeScanlineColor(byte *dst, int pitch, byte *src);
 	void decodeScanlineMono(byte *dst, int pitch, byte *src);
-	PixelPos getPixelPos(byte x, byte y);
-	byte getPixelColor(byte x, byte color);
 	void drawChar(byte c, int x, int y);
 	void createFont();
-	void moveX(PixelPos &p, byte &color, bool left);
-	void moveY(PixelPos &p, bool down);
-	void drawNextPixel(Display::PixelPos &p, byte &color, byte bits, byte quadrant);
 
 	void scrollUp();
 
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 5435191..04df01e 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -216,10 +216,10 @@ void HiRes1Engine::drawPic(Common::ReadStream &stream, Common::Point pos) {
 			y = 160;
 
 		if (bNewLine) {
-			_display->drawPixel(x, y, 0x7f);
+			_display->putPixel(Common::Point(x, y), 0x7f);
 			bNewLine = false;
 		} else {
-			_display->drawLine(Common::Point(oldX, oldY), Common::Point(x, y), 0x7f);
+			drawLine(Common::Point(oldX, oldY), Common::Point(x, y), 0x7f);
 		}
 
 		oldX = x;
@@ -455,6 +455,42 @@ uint HiRes1Engine::getEngineMessage(EngineMessage msg) {
 	}
 }
 
+void HiRes1Engine::drawLine(Common::Point p1, Common::Point p2, byte color) {
+	int16 deltaX = p2.x - p1.x;
+	byte dir = deltaX >> 8;
+
+	if (deltaX < 0)
+		deltaX = -deltaX;
+
+	int16 err = deltaX;
+
+	int16 deltaY = p2.y - p1.y - 1;
+	dir >>= 1;
+	if (deltaY >= 0) {
+		deltaY = -deltaY - 2;
+		dir |= 0x80;
+	}
+
+	int16 steps = deltaY - deltaX;
+
+	err += deltaY + 1;
+
+	while (1) {
+		_display->putPixel(p1, color);
+
+		if (++steps == 0)
+			return;
+
+		if (err < 0) {
+			p1.y += (dir & 0x80 ? 1 : -1);
+			err += deltaX;
+		} else {
+			p1.x += (dir & 0x40 ? -1 : 1);
+			err += deltaY + 1;
+		}
+	}
+}
+
 AdlEngine *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 897327c..cae5980 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -57,6 +57,7 @@ private:
 	void runIntro();
 	void drawPic(Common::ReadStream &stream, Common::Point pos);
 	void drawItems();
+	void drawLine(Common::Point p1, Common::Point p2, byte color);
 	void drawPic(byte pic, Common::Point pos);
 };
 


Commit: 4f7e5da4dad61f11553e5f51f00d33506b9ef342
    https://github.com/scummvm/scummvm/commit/4f7e5da4dad61f11553e5f51f00d33506b9ef342
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Clean up Display class

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



diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp
index 90ca1b6..55166f4 100644
--- a/engines/adl/display.cpp
+++ b/engines/adl/display.cpp
@@ -20,23 +20,40 @@
  *
  */
 
-#include "adl/display.h"
 #include "common/stream.h"
 #include "common/rect.h"
-#include "graphics/surface.h"
 #include "common/system.h"
 #include "common/str.h"
-#include "common/events.h"
-#include "common/rect.h"
-#include "common/array.h"
 #include "common/config-manager.h"
-#include "engines/engine.h"
-#include "engines/util.h"
+
+#include "graphics/surface.h"
 #include "graphics/palette.h"
 #include "graphics/thumbnail.h"
 
+#include "engines/util.h"
+
+#include "adl/display.h"
+
 namespace Adl {
 
+#define DISPLAY_PITCH (DISPLAY_WIDTH / 7)
+
+#define COLOR_PALETTE_SIZE 6
+const byte colorPalette[COLOR_PALETTE_SIZE * 3] = {
+	0x00, 0x00, 0x00,
+	0xff, 0xff, 0xff,
+	0xc7, 0x34, 0xff,
+	0x38, 0xcb, 0x00,
+	0x0d, 0xa1, 0xff,
+	0xf2, 0x5e, 0x00
+};
+
+#define MONO_PALETTE_SIZE 2
+const byte monoPalette[MONO_PALETTE_SIZE * 3] = {
+	0x00, 0x00, 0x00,
+	0x00, 0xc0, 0x01
+};
+
 static const byte font[64][5] = {
 	{ 0x7c, 0x82, 0xba, 0xb2, 0x9c }, { 0xf8, 0x24, 0x22, 0x24, 0xf8 }, // @A
 	{ 0xfe, 0x92, 0x92, 0x92, 0x6c }, { 0x7c, 0x82, 0x82, 0x82, 0x44 }, // BC
@@ -73,8 +90,8 @@ static const byte font[64][5] = {
 };
 
 Display::Display() :
-		_cursorPos(0),
 		_mode(kModeText),
+		_cursorPos(0),
 		_showCursor(false) {
 
 	initGraphics(560, 384, true);
@@ -83,20 +100,23 @@ Display::Display() :
 	_scanlines = ConfMan.getBool("scanlines");
 
 	if (_monochrome)
-		setMonoPalette();
+		g_system->getPaletteManager()->setPalette(monoPalette, 0, MONO_PALETTE_SIZE);
 	else
-		setColorPalette();
+		g_system->getPaletteManager()->setPalette(colorPalette, 0, COLOR_PALETTE_SIZE);
 
 	enableScanlines(_scanlines);
 
-	_frameBuf = new byte[kWidth * kHeight / 7];
+	_frameBuf = new byte[DISPLAY_PITCH * DISPLAY_HEIGHT];
 	_frameBufSurface = new Graphics::Surface;
-	_frameBufSurface->create(kWidth * 2, kHeight * 2, Graphics::PixelFormat::createFormatCLUT8());
+	// We need 2x scaling to properly render the half-pixel shift
+	// of the second palette
+	_frameBufSurface->create(DISPLAY_WIDTH * 2, DISPLAY_HEIGHT * 2, Graphics::PixelFormat::createFormatCLUT8());
 
 	_textBuf = new byte[kTextBufSize];
-	memset(_textBuf, ' ' | 0x80, kTextBufSize);
+	memset(_textBuf, APPLECHAR(' '), kTextBufSize);
 	_textBufSurface = new Graphics::Surface;
-	_textBufSurface->create(kWidth * 2, kHeight * 2, Graphics::PixelFormat::createFormatCLUT8());
+	// For ease of copying, also use 2x scaling here
+	_textBufSurface->create(DISPLAY_WIDTH * 2, DISPLAY_HEIGHT * 2, Graphics::PixelFormat::createFormatCLUT8());
 
 	createFont();
 }
@@ -114,6 +134,17 @@ Display::~Display() {
 	delete _font;
 }
 
+void Display::updateScreen() {
+	if (_mode == kModeText) {
+		g_system->copyRectToScreen(_textBufSurface->getPixels(), _textBufSurface->pitch, 0, 0, _textBufSurface->w, _textBufSurface->h);
+	} else if (_mode == kModeHires) {
+		g_system->copyRectToScreen(_frameBufSurface->getPixels(), _frameBufSurface->pitch, 0, 0, _frameBufSurface->w, _frameBufSurface->h);
+	} else {
+		g_system->copyRectToScreen(_frameBufSurface->getPixels(), _frameBufSurface->pitch, 0, 0, _frameBufSurface->w, _frameBufSurface->h - 4 * 8 * 2);
+		g_system->copyRectToScreen(_textBufSurface->getBasePtr(0, _textBufSurface->h - 4 * 8 * 2), _textBufSurface->pitch, 0, _textBufSurface->h - 4 * 8 * 2, _textBufSurface->w, 4 * 8 * 2);
+	}
+}
+
 bool Display::saveThumbnail(Common::WriteStream &out) {
 	if (_scanlines) {
 		enableScanlines(false);
@@ -130,56 +161,153 @@ bool Display::saveThumbnail(Common::WriteStream &out) {
 	return retval;
 }
 
-void Display::enableScanlines(bool enable) {
-	byte pal[6 * 3] = { };
+void Display::loadFrameBuffer(Common::ReadStream &stream) {
+	for (uint j = 0; j < 8; ++j) {
+		for (uint i = 0; i < 8; ++i) {
+			byte *dst = _frameBuf + DISPLAY_PITCH  * (i * 8 + j);
+			stream.read(dst, DISPLAY_PITCH);
+			dst += DISPLAY_PITCH * 64;
+			stream.read(dst, DISPLAY_PITCH);
+			dst += DISPLAY_PITCH * 64;
+			stream.read(dst, DISPLAY_PITCH);
+			stream.readUint32LE();
+			stream.readUint32LE();
+			dst += DISPLAY_PITCH * 64;
+		}
+	}
+}
 
-	if (enable)
-		g_system->getPaletteManager()->setPalette(pal, 6, 6);
-	else {
-		g_system->getPaletteManager()->grabPalette(pal, 0, 6);
-		g_system->getPaletteManager()->setPalette(pal, 6, 6);
+void Display::decodeFrameBuffer() {
+	byte *src = _frameBuf;
+	byte *dst = (byte *)_frameBufSurface->getPixels();
+
+	for (uint i = 0; i < DISPLAY_HEIGHT; ++i) {
+		decodeScanline(dst, _frameBufSurface->pitch, src);
+		src += DISPLAY_PITCH;
+		dst += _frameBufSurface->pitch * 2;
 	}
 }
 
-void Display::setColorPalette() {
-	const byte colorPal[6 * 3] = {
-		0x00, 0x00, 0x00,
-		0xff, 0xff, 0xff,
-		0xc7, 0x34, 0xff,
-		0x38, 0xcb, 0x00,
-		0x0d, 0xa1, 0xff,
-		0xf2, 0x5e, 0x00
-	};
-
-	g_system->getPaletteManager()->setPalette(colorPal, 0, 6);
+void Display::putPixel(Common::Point p, byte color) {
+	byte offset = p.x / 7;
+
+	if (offset & 1) {
+		byte c = color << 1;
+		if (c >= 0x40 && c < 0xc0)
+			color ^= 0x7f;
+	}
+
+	byte *b = _frameBuf + p.y * DISPLAY_PITCH + offset;
+	color ^= *b;
+	color &= 1 << (p.x % 7);
+	*b ^= color;
 }
 
-void Display::setMonoPalette() {
-	const byte monoPal[2 * 3] = {
-		0x00, 0x00, 0x00,
-		0x00, 0xc0, 0x01
-	};
+void Display::clear(byte color) {
+	byte val = 0;
+
+	byte c = color << 1;
+	if (c >= 0x40 && c < 0xc0)
+		val = 0x7f;
 
-	g_system->getPaletteManager()->setPalette(monoPal, 0, 2);
+	for (uint i = 0; i < DISPLAY_PITCH * DISPLAY_HEIGHT; ++i) {
+		_frameBuf[i] = color;
+		color ^= val;
+	}
 }
 
-void Display::loadFrameBuffer(Common::ReadStream &stream) {
-	for (uint j = 0; j < 8; ++j) {
-		for (uint i = 0; i < 8; ++i) {
-			byte *dst = _frameBuf + kWidth / 7  * (i * 8 + j);
-			stream.read(dst, kWidth / 7);
-			dst += kWidth / 7 * 64;
-			stream.read(dst, kWidth / 7);
-			dst += kWidth / 7 * 64;
-			stream.read(dst, kWidth / 7);
-			stream.readUint32LE();
-			stream.readUint32LE();
-			dst += kWidth / 7 * 64;
+void Display::updateTextSurface() {
+	for (uint row = 0; row < 24; ++row)
+		for (uint col = 0; col < 40; ++col) {
+			int charPos = row * 40 + col;
+			char c = _textBuf[row * 40 + col];
+
+			if (charPos == _cursorPos && _showCursor)
+				c = (c & 0x3f) | 0x40;
+
+			Common::Rect r(7 * 2, 8 * 2);
+			r.translate(((c & 0x3f) % 16) * 7 * 2, (c & 0x3f) / 16 * 8 * 2);
+
+			if (!(c & 0x80)) {
+				if (!(c & 0x40) || ((g_system->getMillis() / 270) & 1))
+					r.translate(0, 4 * 8 * 2);
+			}
+
+			_textBufSurface->copyRectToSurface(*_font, col * 7 * 2, row * 8 * 2, r);
+		}
+}
+
+
+void Display::setCursorPos(Common::Point pos) {
+	_cursorPos = pos.y * 40 + pos.x;
+}
+
+
+void Display::home() {
+	memset(_textBuf, APPLECHAR(' '), kTextBufSize);
+	_cursorPos = 0;
+}
+
+void Display::moveCursorForward() {
+	++_cursorPos;
+
+	if (_cursorPos >= kTextBufSize)
+		scrollUp();
+}
+
+void Display::moveCursorBackward() {
+	--_cursorPos;
+
+	if (_cursorPos < 0)
+		_cursorPos = 0;
+}
+
+void Display::moveCursorTo(const Common::Point &pos) {
+	_cursorPos = pos.y * 40 + pos.x;
+
+	if (_cursorPos >= kTextBufSize)
+		error("Cursor position (%i, %i) out of bounds", pos.x, pos.y);
+}
+
+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 / 40 + 1) * 40;
+		else if (b < 0x80 || b >= 0xa0) {
+			setCharAtCursor(b);
+			++_cursorPos;
 		}
+
+		if (_cursorPos == kTextBufSize)
+			scrollUp();
 	}
+
+	updateTextSurface();
 }
 
-void Display::decodeScanlineColor(byte *dst, int pitch, byte *src) {
+void Display::setCharAtCursor(byte c) {
+	_textBuf[_cursorPos] = c;
+}
+
+void Display::showCursor(bool enable) {
+	_showCursor = enable;
+}
+
+void Display::enableScanlines(bool enable) {
+	byte pal[6 * 3] = { };
+
+	if (enable)
+		g_system->getPaletteManager()->setPalette(pal, 6, 6);
+	else {
+		g_system->getPaletteManager()->grabPalette(pal, 0, 6);
+		g_system->getPaletteManager()->setPalette(pal, 6, 6);
+	}
+}
+
+void Display::decodeScanlineColor(byte *dst, int pitch, byte *src) const {
 	// TODO: shift secondPal by half a pixel
 
 	bool prevOn = false;
@@ -221,7 +349,7 @@ void Display::decodeScanlineColor(byte *dst, int pitch, byte *src) {
 	}
 }
 
-void Display::decodeScanlineMono(byte *dst, int pitch, byte *src) {
+void Display::decodeScanlineMono(byte *dst, int pitch, byte *src) const {
 	// TODO: shift secondPal by half a pixel
 
 	for (uint j = 0; j < 39; ++j) {
@@ -241,73 +369,13 @@ void Display::decodeScanlineMono(byte *dst, int pitch, byte *src) {
 	}
 }
 
-void Display::decodeScanline(byte *dst, int pitch, byte *src) {
+void Display::decodeScanline(byte *dst, int pitch, byte *src) const {
 	if (_monochrome)
 		decodeScanlineMono(dst, pitch, src);
 	else
 		decodeScanlineColor(dst, pitch, src);
 }
 
-void Display::decodeFrameBuffer() {
-	byte *src = _frameBuf;
-	byte *dst = (byte *)_frameBufSurface->getPixels();
-
-	for (uint i = 0; i < kHeight; ++i) {
-		decodeScanline(dst, _frameBufSurface->pitch, src);
-		src += kWidth / 7;
-		dst += _frameBufSurface->pitch * 2;
-	}
-}
-
-void Display::putPixel(Common::Point p, byte color) {
-	byte offset = p.x / 7;
-
-	if (offset & 1) {
-		byte c = color << 1;
-		if (c >= 0x40 && c < 0xc0)
-			color ^= 0x7f;
-	}
-
-	byte *b = _frameBuf + p.y * kWidth / 7 + offset;
-	color ^= *b;
-	color &= 1 << (p.x % 7);
-	*b ^= color;
-}
-
-void Display::clear(byte color) {
-	byte val = 0;
-
-	byte c = color << 1;
-	if (c >= 0x40 && c < 0xc0)
-		val = 0x7f;
-
-	for (uint i = 0; i < kWidth / 7 * kHeight; ++i) {
-		_frameBuf[i] = color;
-		color ^= val;
-	}
-}
-
-void Display::updateTextSurface() {
-	for (uint row = 0; row < 24; ++row)
-		for (uint col = 0; col < 40; ++col) {
-			int charPos = row * 40 + col;
-			char c = _textBuf[row * 40 + col];
-
-			if (charPos == _cursorPos && _showCursor)
-				c = (c & 0x3f) | 0x40;
-
-			Common::Rect r(7 * 2, 8 * 2);
-			r.translate(((c & 0x3f) % 16) * 7 * 2, (c & 0x3f) / 16 * 8 * 2);
-
-			if (!(c & 0x80)) {
-				if (!(c & 0x40) || ((g_system->getMillis() / 270) & 1))
-					r.translate(0, 4 * 8 * 2);
-			}
-
-			_textBufSurface->copyRectToSurface(*_font, col * 7 * 2, row * 8 * 2, r);
-		}
-}
-
 void Display::drawChar(byte c, int x, int y) {
 	byte *buf = (byte *)_font->getPixels() + y * _font->pitch + x;
 
@@ -361,78 +429,10 @@ void Display::createFont() {
 	}
 }
 
-void Display::updateScreen() {
-	if (_mode == kModeText) {
-		g_system->copyRectToScreen(_textBufSurface->getPixels(), _textBufSurface->pitch, 0, 0, _textBufSurface->w, _textBufSurface->h);
-	} else if (_mode == kModeHires) {
-		g_system->copyRectToScreen(_frameBufSurface->getPixels(), _frameBufSurface->pitch, 0, 0, _frameBufSurface->w, _frameBufSurface->h);
-	} else {
-		g_system->copyRectToScreen(_frameBufSurface->getPixels(), _frameBufSurface->pitch, 0, 0, _frameBufSurface->w, _frameBufSurface->h - 4 * 8 * 2);
-		g_system->copyRectToScreen(_textBufSurface->getBasePtr(0, _textBufSurface->h - 4 * 8 * 2), _textBufSurface->pitch, 0, _textBufSurface->h - 4 * 8 * 2, _textBufSurface->w, 4 * 8 * 2);
-	}
-}
-
-void Display::home() {
-	memset(_textBuf, APPLECHAR(' '), kTextBufSize);
-	_cursorPos = 0;
-}
-
-void Display::moveCursorForward() {
-	++_cursorPos;
-
-	if (_cursorPos >= kTextBufSize)
-		scrollUp();
-}
-
-void Display::moveCursorBackward() {
-	--_cursorPos;
-
-	if (_cursorPos < 0)
-		_cursorPos = 0;
-}
-
-void Display::moveCursorTo(const Common::Point &pos) {
-	_cursorPos = pos.y * 40 + pos.x;
-
-	if (_cursorPos >= kTextBufSize)
-		error("Cursor position (%i, %i) out of bounds", pos.x, pos.y);
-}
-
-void Display::setCharAtCursor(byte c) {
-	_textBuf[_cursorPos] = c;
-}
-
 void Display::scrollUp() {
 	memmove(_textBuf, _textBuf + 40, kTextBufSize - 40);
-	memset(_textBuf + kTextBufSize - 40, ' ' | 0x80, 40);
+	memset(_textBuf + kTextBufSize - 40, APPLECHAR(' '), 40);
 	_cursorPos -= 40;
 }
 
-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 / 40 + 1) * 40;
-		else if (b < 0x80 || b >= 0xa0) {
-			setCharAtCursor(b);
-			++_cursorPos;
-		}
-
-		if (_cursorPos == kTextBufSize)
-			scrollUp();
-	}
-
-	updateTextSurface();
-}
-
-void Display::showCursor(bool enable) {
-	_showCursor = enable;
-}
-
-void Display::setCursorPos(Common::Point pos) {
-	_cursorPos = pos.y * 40 + pos.x;
-}
-
 } // End of namespace Adl
diff --git a/engines/adl/display.h b/engines/adl/display.h
index 0452b27..70dc42d 100644
--- a/engines/adl/display.h
+++ b/engines/adl/display.h
@@ -24,7 +24,6 @@
 #define ADL_DISPLAY_H
 
 #include <common/types.h>
-#include <common/array.h>
 
 namespace Common {
 class ReadStream;
@@ -39,6 +38,9 @@ class Surface;
 
 namespace Adl {
 
+#define DISPLAY_WIDTH 280
+#define DISPLAY_HEIGHT 192
+
 #define APPLECHAR(C) ((char)((C) | 0x80))
 
 class Display {
@@ -51,17 +53,20 @@ public:
 
 	Display();
 	~Display();
-	void enableScanlines(bool enable);
-	void setMonoPalette();
-	void setColorPalette();
+
+	void setMode(Mode mode) { _mode = mode; }
+	void updateScreen();
+	bool saveThumbnail(Common::WriteStream &out);
+
+	// Graphics
 	void loadFrameBuffer(Common::ReadStream &stream);
 	void decodeFrameBuffer();
-	void updateScreen();
-	void setMode(Mode mode) { _mode = mode; }
 	void putPixel(Common::Point p1, byte color);
 	void clear(byte color);
-	void setCursorPos(Common::Point pos);
 
+	// Text
+	void updateTextSurface();
+	void setCursorPos(Common::Point pos);
 	void home();
 	void moveCursorTo(const Common::Point &pos);
 	void moveCursorForward();
@@ -69,40 +74,33 @@ public:
 	void printString(const Common::String &str);
 	void setCharAtCursor(byte c);
 	void showCursor(bool enable);
-	void updateTextSurface();
-	bool saveThumbnail(Common::WriteStream &out);
 
 private:
 	enum {
-		kWidth = 280,
-		kHeight = 192,
 		kTextBufSize = 40 * 24
 	};
 
-	struct PixelPos {
-		uint16 rowAddr;
-		byte byteOffset;
-		byte bitMask;
-	};
+	void enableScanlines(bool enable);
+	void decodeScanlineColor(byte *dst, int pitch, byte *src) const;
+	void decodeScanlineMono(byte *dst, int pitch, byte *src) const;
+	void decodeScanline(byte *dst, int pitch, byte *src) const;
 
-	void decodeScanline(byte *dst, int pitch, byte *src);
-	void decodeScanlineColor(byte *dst, int pitch, byte *src);
-	void decodeScanlineMono(byte *dst, int pitch, byte *src);
 	void drawChar(byte c, int x, int y);
 	void createFont();
-
 	void scrollUp();
 
-	bool _scanlines;
+	Mode _mode;
+
 	byte *_frameBuf;
-	byte *_textBuf;
 	Graphics::Surface *_frameBufSurface;
+	bool _scanlines;
+	bool _monochrome;
+
+	byte *_textBuf;
 	Graphics::Surface *_textBufSurface;
 	Graphics::Surface *_font;
 	int _cursorPos;
-	Mode _mode;
 	bool _showCursor;
-	bool _monochrome;
 };
  
 } // End of namespace Adl


Commit: 115e4cab0d3bd18b0e189c7c304e32f122836f75
    https://github.com/scummvm/scummvm/commit/115e4cab0d3bd18b0e189c7c304e32f122836f75
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Fix restoring on restart prompt

Changed paths:
    engines/adl/adl.cpp



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 90a9a0d..d2d8492 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -291,7 +291,11 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 		case IDO_ACT_LOAD:
 			loadGameState(0);
 			++offset;
-			// Original engine continues processing here (?)
+			// 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[IDI_STR_PLAY_AGAIN]);
@@ -301,6 +305,7 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			Common::String input = inputString();
 			_canRestoreNow = false;
 
+			// If the user restored with the GMM, we break off the restart
 			if (_isRestoring)
 				return;
 
@@ -661,6 +666,7 @@ Common::Error AdlEngine::loadGameState(int slot) {
 
 	setTotalPlayTime(playTime);
 
+	_isRestoring = true;
 	return Common::kNoError;
 }
 


Commit: ec14c397eec87ee66337a9f15c044b47fec8855d
    https://github.com/scummvm/scummvm/commit/ec14c397eec87ee66337a9f15c044b47fec8855d
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Clean up Display class

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



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index d2d8492..99267ba 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -76,7 +76,7 @@ Common::Error AdlEngine::run() {
 	if (saveSlot >= 0) {
 		if (loadGameState(saveSlot).getCode() != Common::kNoError)
 			error("Failed to load save game from slot %i", saveSlot);
-		_display->setCursorPos(Common::Point(0, 23));
+		_display->moveCursorTo(Common::Point(0, 23));
 		_isRestoring = true;
 	} else {
 		runIntro();
@@ -472,7 +472,7 @@ bool AdlEngine::canLoadGameStateCurrently() {
 }
 
 void AdlEngine::clearScreen() {
-	_display->setMode(Display::kModeMixed);
+	_display->setMode(DISPLAY_MODE_MIXED);
 	_display->clear(0x00);
 }
 
@@ -744,7 +744,7 @@ Common::String AdlEngine::getLine() {
 
 		if ((byte)line[0] == ('\r' | 0x80)) {
 			textMode = !textMode;
-			_display->setMode(textMode ? Display::kModeText : Display::kModeMixed);
+			_display->setMode(textMode ? DISPLAY_MODE_TEXT : DISPLAY_MODE_MIXED);
 			continue;
 		}
 
diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp
index 55166f4..a75b129 100644
--- a/engines/adl/display.cpp
+++ b/engines/adl/display.cpp
@@ -90,7 +90,7 @@ static const byte font[64][5] = {
 };
 
 Display::Display() :
-		_mode(kModeText),
+		_mode(DISPLAY_MODE_TEXT),
 		_cursorPos(0),
 		_showCursor(false) {
 
@@ -135,9 +135,9 @@ Display::~Display() {
 }
 
 void Display::updateScreen() {
-	if (_mode == kModeText) {
+	if (_mode == DISPLAY_MODE_TEXT) {
 		g_system->copyRectToScreen(_textBufSurface->getPixels(), _textBufSurface->pitch, 0, 0, _textBufSurface->w, _textBufSurface->h);
-	} else if (_mode == kModeHires) {
+	} else if (_mode == DISPLAY_MODE_HIRES) {
 		g_system->copyRectToScreen(_frameBufSurface->getPixels(), _frameBufSurface->pitch, 0, 0, _frameBufSurface->w, _frameBufSurface->h);
 	} else {
 		g_system->copyRectToScreen(_frameBufSurface->getPixels(), _frameBufSurface->pitch, 0, 0, _frameBufSurface->w, _frameBufSurface->h - 4 * 8 * 2);
@@ -237,12 +237,6 @@ void Display::updateTextSurface() {
 		}
 }
 
-
-void Display::setCursorPos(Common::Point pos) {
-	_cursorPos = pos.y * 40 + pos.x;
-}
-
-
 void Display::home() {
 	memset(_textBuf, APPLECHAR(' '), kTextBufSize);
 	_cursorPos = 0;
diff --git a/engines/adl/display.h b/engines/adl/display.h
index 70dc42d..40151c1 100644
--- a/engines/adl/display.h
+++ b/engines/adl/display.h
@@ -41,20 +41,20 @@ namespace Adl {
 #define DISPLAY_WIDTH 280
 #define DISPLAY_HEIGHT 192
 
+enum DisplayMode {
+	DISPLAY_MODE_HIRES,
+	DISPLAY_MODE_TEXT,
+	DISPLAY_MODE_MIXED
+};
+
 #define APPLECHAR(C) ((char)((C) | 0x80))
 
 class Display {
 public:
-	enum Mode {
-		kModeHires,
-		kModeText,
-		kModeMixed
-	};
-
 	Display();
 	~Display();
 
-	void setMode(Mode mode) { _mode = mode; }
+	void setMode(DisplayMode mode) { _mode = mode; }
 	void updateScreen();
 	bool saveThumbnail(Common::WriteStream &out);
 
@@ -66,7 +66,6 @@ public:
 
 	// Text
 	void updateTextSurface();
-	void setCursorPos(Common::Point pos);
 	void home();
 	void moveCursorTo(const Common::Point &pos);
 	void moveCursorForward();
@@ -89,7 +88,7 @@ private:
 	void createFont();
 	void scrollUp();
 
-	Mode _mode;
+	DisplayMode _mode;
 
 	byte *_frameBuf;
 	Graphics::Surface *_frameBufSurface;
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 04df01e..6c36922 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -94,7 +94,7 @@ void HiRes1Engine::runIntro() {
 		error("Failed to open file");
 
 	file.seek(IDI_HR1_OFS_LOGO_0);
-	_display->setMode(Display::kModeHires);
+	_display->setMode(DISPLAY_MODE_HIRES);
 	_display->loadFrameBuffer(file);
 	_display->decodeFrameBuffer();
 	delay(4000);
@@ -102,7 +102,7 @@ void HiRes1Engine::runIntro() {
 	if (shouldQuit())
 		return;
 
-	_display->setMode(Display::kModeText);
+	_display->setMode(DISPLAY_MODE_TEXT);
 
 	Common::File basic;
 	if (!basic.open("MYSTERY.HELLO"))
@@ -130,7 +130,7 @@ void HiRes1Engine::runIntro() {
 	if (g_engine->shouldQuit())
 		return;
 
-	_display->setMode(Display::kModeMixed);
+	_display->setMode(DISPLAY_MODE_MIXED);
 
 	file.seek(IDI_HR1_OFS_GAME_OR_HELP);
 	str = readString(file);
@@ -156,7 +156,7 @@ void HiRes1Engine::runIntro() {
 	};
 
 	if (instructions) {
-		_display->setMode(Display::kModeText);
+		_display->setMode(DISPLAY_MODE_TEXT);
 		file.seek(IDI_HR1_OFS_INTRO_TEXT);
 
 		const uint pages[] = { 6, 6, 4, 5, 8, 7, 0 };
@@ -178,7 +178,7 @@ void HiRes1Engine::runIntro() {
 
 	file.close();
 
-	_display->setMode(Display::kModeMixed);
+	_display->setMode(DISPLAY_MODE_MIXED);
 
 	if (!file.open("ADVENTURE"))
 		error("Failed to open file");
@@ -298,7 +298,7 @@ void HiRes1Engine::restartGame() {
 }
 
 void HiRes1Engine::runGame() {
-	_display->setMode(Display::kModeMixed);
+	_display->setMode(DISPLAY_MODE_MIXED);
 
 	Common::File f;
 


Commit: e6d478ad150f7eb702f12c8d3a60bfcd416f2b2e
    https://github.com/scummvm/scummvm/commit/e6d478ad150f7eb702f12c8d3a60bfcd416f2b2e
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Clean up Display class

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



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 99267ba..313b146 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -312,7 +312,7 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			if (input.size() == 0 || input[0] != APPLECHAR('N')) {
 				_isRestarting = true;
 				_display->clear(0x00);
-				_display->decodeFrameBuffer();
+				_display->updateHiResScreen();
 				restartGame();
 				return;
 			}
@@ -515,9 +515,9 @@ void AdlEngine::showRoom() {
 	if (!_state.isDark) {
 		drawPic(curRoom().curPicture);
 		drawItems();
+		_display->updateHiResScreen();
 	}
 
-	_display->decodeFrameBuffer();
 	printMessage(curRoom().description, false);
 }
 
@@ -913,9 +913,7 @@ byte AdlEngine::inputKey() {
 			};
 		}
 
-		_display->updateTextSurface();
-		_display->updateScreen();
-		g_system->updateScreen();
+		_display->updateTextScreen();
 		g_system->delayMillis(16);
 	}
 
@@ -942,8 +940,6 @@ void AdlEngine::delay(uint32 ms) {
 				}
 			}
 		}
-		_display->updateScreen();
-		g_system->updateScreen();
 		g_system->delayMillis(16);
 	}
 }
diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp
index a75b129..05c96cf 100644
--- a/engines/adl/display.cpp
+++ b/engines/adl/display.cpp
@@ -36,10 +36,12 @@
 
 namespace Adl {
 
+// TODO: Implement partial screen updates
+
 #define DISPLAY_PITCH (DISPLAY_WIDTH / 7)
 
-#define COLOR_PALETTE_SIZE 6
-const byte colorPalette[COLOR_PALETTE_SIZE * 3] = {
+#define COLOR_PALETTE_ENTRIES 6
+const byte colorPalette[COLOR_PALETTE_ENTRIES * 3] = {
 	0x00, 0x00, 0x00,
 	0xff, 0xff, 0xff,
 	0xc7, 0x34, 0xff,
@@ -48,8 +50,8 @@ const byte colorPalette[COLOR_PALETTE_SIZE * 3] = {
 	0xf2, 0x5e, 0x00
 };
 
-#define MONO_PALETTE_SIZE 2
-const byte monoPalette[MONO_PALETTE_SIZE * 3] = {
+#define MONO_PALETTE_ENTRIES 2
+const byte monoPalette[MONO_PALETTE_ENTRIES * 3] = {
 	0x00, 0x00, 0x00,
 	0x00, 0xc0, 0x01
 };
@@ -100,9 +102,9 @@ Display::Display() :
 	_scanlines = ConfMan.getBool("scanlines");
 
 	if (_monochrome)
-		g_system->getPaletteManager()->setPalette(monoPalette, 0, MONO_PALETTE_SIZE);
+		g_system->getPaletteManager()->setPalette(monoPalette, 0, MONO_PALETTE_ENTRIES);
 	else
-		g_system->getPaletteManager()->setPalette(colorPalette, 0, COLOR_PALETTE_SIZE);
+		g_system->getPaletteManager()->setPalette(colorPalette, 0, COLOR_PALETTE_ENTRIES);
 
 	enableScanlines(_scanlines);
 
@@ -134,15 +136,35 @@ Display::~Display() {
 	delete _font;
 }
 
-void Display::updateScreen() {
-	if (_mode == DISPLAY_MODE_TEXT) {
+void Display::setMode(DisplayMode mode) {
+	_mode = mode;
+
+	if (_mode == DISPLAY_MODE_TEXT || _mode == DISPLAY_MODE_MIXED)
+		updateTextScreen();
+	if (_mode == DISPLAY_MODE_HIRES || _mode == DISPLAY_MODE_MIXED)
+		updateHiResScreen();
+}
+
+void Display::updateTextScreen() {
+	updateTextSurface();
+
+	if (_mode == DISPLAY_MODE_TEXT)
 		g_system->copyRectToScreen(_textBufSurface->getPixels(), _textBufSurface->pitch, 0, 0, _textBufSurface->w, _textBufSurface->h);
-	} else if (_mode == DISPLAY_MODE_HIRES) {
+	else if (_mode == DISPLAY_MODE_MIXED)
+		g_system->copyRectToScreen(_textBufSurface->getBasePtr(0, _textBufSurface->h - 4 * 8 * 2), _textBufSurface->pitch, 0, _textBufSurface->h - 4 * 8 * 2, _textBufSurface->w, 4 * 8 * 2);
+
+	g_system->updateScreen();
+}
+
+void Display::updateHiResScreen() {
+	updateHiResSurface();
+
+	if (_mode == DISPLAY_MODE_HIRES)
 		g_system->copyRectToScreen(_frameBufSurface->getPixels(), _frameBufSurface->pitch, 0, 0, _frameBufSurface->w, _frameBufSurface->h);
-	} else {
+	else if (_mode == DISPLAY_MODE_MIXED)
 		g_system->copyRectToScreen(_frameBufSurface->getPixels(), _frameBufSurface->pitch, 0, 0, _frameBufSurface->w, _frameBufSurface->h - 4 * 8 * 2);
-		g_system->copyRectToScreen(_textBufSurface->getBasePtr(0, _textBufSurface->h - 4 * 8 * 2), _textBufSurface->pitch, 0, _textBufSurface->h - 4 * 8 * 2, _textBufSurface->w, 4 * 8 * 2);
-	}
+
+	g_system->updateScreen();
 }
 
 bool Display::saveThumbnail(Common::WriteStream &out) {
@@ -177,17 +199,6 @@ void Display::loadFrameBuffer(Common::ReadStream &stream) {
 	}
 }
 
-void Display::decodeFrameBuffer() {
-	byte *src = _frameBuf;
-	byte *dst = (byte *)_frameBufSurface->getPixels();
-
-	for (uint i = 0; i < DISPLAY_HEIGHT; ++i) {
-		decodeScanline(dst, _frameBufSurface->pitch, src);
-		src += DISPLAY_PITCH;
-		dst += _frameBufSurface->pitch * 2;
-	}
-}
-
 void Display::putPixel(Common::Point p, byte color) {
 	byte offset = p.x / 7;
 
@@ -216,27 +227,6 @@ void Display::clear(byte color) {
 	}
 }
 
-void Display::updateTextSurface() {
-	for (uint row = 0; row < 24; ++row)
-		for (uint col = 0; col < 40; ++col) {
-			int charPos = row * 40 + col;
-			char c = _textBuf[row * 40 + col];
-
-			if (charPos == _cursorPos && _showCursor)
-				c = (c & 0x3f) | 0x40;
-
-			Common::Rect r(7 * 2, 8 * 2);
-			r.translate(((c & 0x3f) % 16) * 7 * 2, (c & 0x3f) / 16 * 8 * 2);
-
-			if (!(c & 0x80)) {
-				if (!(c & 0x40) || ((g_system->getMillis() / 270) & 1))
-					r.translate(0, 4 * 8 * 2);
-			}
-
-			_textBufSurface->copyRectToSurface(*_font, col * 7 * 2, row * 8 * 2, r);
-		}
-}
-
 void Display::home() {
 	memset(_textBuf, APPLECHAR(' '), kTextBufSize);
 	_cursorPos = 0;
@@ -279,7 +269,7 @@ void Display::printString(const Common::String &str) {
 			scrollUp();
 	}
 
-	updateTextSurface();
+	updateTextScreen();
 }
 
 void Display::setCharAtCursor(byte c) {
@@ -291,7 +281,7 @@ void Display::showCursor(bool enable) {
 }
 
 void Display::enableScanlines(bool enable) {
-	byte pal[6 * 3] = { };
+	byte pal[COLOR_PALETTE_ENTRIES * 3] = { };
 
 	if (enable)
 		g_system->getPaletteManager()->setPalette(pal, 6, 6);
@@ -301,6 +291,17 @@ void Display::enableScanlines(bool enable) {
 	}
 }
 
+void Display::updateHiResSurface() {
+	byte *src = _frameBuf;
+	byte *dst = (byte *)_frameBufSurface->getPixels();
+
+	for (uint i = 0; i < DISPLAY_HEIGHT; ++i) {
+		decodeScanline(dst, _frameBufSurface->pitch, src);
+		src += DISPLAY_PITCH;
+		dst += _frameBufSurface->pitch * 2;
+	}
+}
+
 void Display::decodeScanlineColor(byte *dst, int pitch, byte *src) const {
 	// TODO: shift secondPal by half a pixel
 
@@ -370,6 +371,27 @@ void Display::decodeScanline(byte *dst, int pitch, byte *src) const {
 		decodeScanlineColor(dst, pitch, src);
 }
 
+void Display::updateTextSurface() {
+	for (uint row = 0; row < 24; ++row)
+		for (uint col = 0; col < 40; ++col) {
+			int charPos = row * 40 + col;
+			char c = _textBuf[row * 40 + col];
+
+			if (charPos == _cursorPos && _showCursor)
+				c = (c & 0x3f) | 0x40;
+
+			Common::Rect r(7 * 2, 8 * 2);
+			r.translate(((c & 0x3f) % 16) * 7 * 2, (c & 0x3f) / 16 * 8 * 2);
+
+			if (!(c & 0x80)) {
+				if (!(c & 0x40) || ((g_system->getMillis() / 270) & 1))
+					r.translate(0, 4 * 8 * 2);
+			}
+
+			_textBufSurface->copyRectToSurface(*_font, col * 7 * 2, row * 8 * 2, r);
+		}
+}
+
 void Display::drawChar(byte c, int x, int y) {
 	byte *buf = (byte *)_font->getPixels() + y * _font->pitch + x;
 
diff --git a/engines/adl/display.h b/engines/adl/display.h
index 40151c1..16b52bf 100644
--- a/engines/adl/display.h
+++ b/engines/adl/display.h
@@ -54,18 +54,17 @@ public:
 	Display();
 	~Display();
 
-	void setMode(DisplayMode mode) { _mode = mode; }
-	void updateScreen();
+	void setMode(DisplayMode mode);
+	void updateTextScreen();
+	void updateHiResScreen();
 	bool saveThumbnail(Common::WriteStream &out);
 
 	// Graphics
 	void loadFrameBuffer(Common::ReadStream &stream);
-	void decodeFrameBuffer();
 	void putPixel(Common::Point p1, byte color);
 	void clear(byte color);
 
 	// Text
-	void updateTextSurface();
 	void home();
 	void moveCursorTo(const Common::Point &pos);
 	void moveCursorForward();
@@ -79,11 +78,13 @@ private:
 		kTextBufSize = 40 * 24
 	};
 
+	void updateHiResSurface();
 	void enableScanlines(bool enable);
 	void decodeScanlineColor(byte *dst, int pitch, byte *src) const;
 	void decodeScanlineMono(byte *dst, int pitch, byte *src) const;
 	void decodeScanline(byte *dst, int pitch, byte *src) const;
 
+	void updateTextSurface();
 	void drawChar(byte c, int x, int y);
 	void createFont();
 	void scrollUp();
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 6c36922..8b5b922 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -96,7 +96,7 @@ void HiRes1Engine::runIntro() {
 	file.seek(IDI_HR1_OFS_LOGO_0);
 	_display->setMode(DISPLAY_MODE_HIRES);
 	_display->loadFrameBuffer(file);
-	_display->decodeFrameBuffer();
+	_display->updateHiResScreen();
 	delay(4000);
 
 	if (shouldQuit())
@@ -186,7 +186,7 @@ void HiRes1Engine::runIntro() {
 	// Title screen shown during loading
 	file.seek(0x1800);
 	_display->loadFrameBuffer(file);
-	_display->decodeFrameBuffer();
+	_display->updateHiResScreen();
 	delay(2000);
 }
 


Commit: 6f9128983847d78a41da7cf2f16a1243c7c1fa28
    https://github.com/scummvm/scummvm/commit/6f9128983847d78a41da7cf2f16a1243c7c1fa28
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Clean up Display class

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



diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp
index 05c96cf..e8ea821 100644
--- a/engines/adl/display.cpp
+++ b/engines/adl/display.cpp
@@ -106,7 +106,7 @@ Display::Display() :
 	else
 		g_system->getPaletteManager()->setPalette(colorPalette, 0, COLOR_PALETTE_ENTRIES);
 
-	enableScanlines(_scanlines);
+	showScanlines(_scanlines);
 
 	_frameBuf = new byte[DISPLAY_PITCH * DISPLAY_HEIGHT];
 	_frameBufSurface = new Graphics::Surface;
@@ -169,14 +169,14 @@ void Display::updateHiResScreen() {
 
 bool Display::saveThumbnail(Common::WriteStream &out) {
 	if (_scanlines) {
-		enableScanlines(false);
+		showScanlines(false);
 		g_system->updateScreen();
 	}
 
 	bool retval = Graphics::saveThumbnail(out);
 
 	if (_scanlines) {
-		enableScanlines(true);
+		showScanlines(true);
 		g_system->updateScreen();
 	}
 
@@ -280,14 +280,14 @@ void Display::showCursor(bool enable) {
 	_showCursor = enable;
 }
 
-void Display::enableScanlines(bool enable) {
+void Display::showScanlines(bool enable) {
 	byte pal[COLOR_PALETTE_ENTRIES * 3] = { };
 
 	if (enable)
-		g_system->getPaletteManager()->setPalette(pal, 6, 6);
+		g_system->getPaletteManager()->setPalette(pal, COLOR_PALETTE_ENTRIES, COLOR_PALETTE_ENTRIES);
 	else {
-		g_system->getPaletteManager()->grabPalette(pal, 0, 6);
-		g_system->getPaletteManager()->setPalette(pal, 6, 6);
+		g_system->getPaletteManager()->grabPalette(pal, 0, COLOR_PALETTE_ENTRIES);
+		g_system->getPaletteManager()->setPalette(pal, COLOR_PALETTE_ENTRIES, COLOR_PALETTE_ENTRIES);
 	}
 }
 
diff --git a/engines/adl/display.h b/engines/adl/display.h
index 16b52bf..b93128f 100644
--- a/engines/adl/display.h
+++ b/engines/adl/display.h
@@ -79,7 +79,7 @@ private:
 	};
 
 	void updateHiResSurface();
-	void enableScanlines(bool enable);
+	void showScanlines(bool enable);
 	void decodeScanlineColor(byte *dst, int pitch, byte *src) const;
 	void decodeScanlineMono(byte *dst, int pitch, byte *src) const;
 	void decodeScanline(byte *dst, int pitch, byte *src) const;


Commit: f5430f961bd937755e85da17d24e8d3f22470545
    https://github.com/scummvm/scummvm/commit/f5430f961bd937755e85da17d24e8d3f22470545
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Implement half-pixel shift in color mode

Changed paths:
    engines/adl/display.cpp



diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp
index e8ea821..678b8c8 100644
--- a/engines/adl/display.cpp
+++ b/engines/adl/display.cpp
@@ -36,20 +36,23 @@
 
 namespace Adl {
 
-// TODO: Implement partial screen updates
+// This implements the Apple II "Hi-Res" display mode
 
 #define DISPLAY_PITCH (DISPLAY_WIDTH / 7)
 
-#define COLOR_PALETTE_ENTRIES 6
+#define COLOR_PALETTE_ENTRIES 8
 const byte colorPalette[COLOR_PALETTE_ENTRIES * 3] = {
 	0x00, 0x00, 0x00,
 	0xff, 0xff, 0xff,
 	0xc7, 0x34, 0xff,
 	0x38, 0xcb, 0x00,
+	0x00, 0x00, 0x00,
+	0xff, 0xff, 0xff,
 	0x0d, 0xa1, 0xff,
 	0xf2, 0x5e, 0x00
 };
 
+// Green monochrome palette
 #define MONO_PALETTE_ENTRIES 2
 const byte monoPalette[MONO_PALETTE_ENTRIES * 3] = {
 	0x00, 0x00, 0x00,
@@ -303,11 +306,12 @@ void Display::updateHiResSurface() {
 }
 
 void Display::decodeScanlineColor(byte *dst, int pitch, byte *src) const {
-	// TODO: shift secondPal by half a pixel
-
 	bool prevOn = false;
 
-	for (uint j = 0; j < 39; ++j) {
+	if (src[0] & 0x80)
+		dst++;
+
+	for (uint j = 0; j < 40; ++j) {
 		bool secondPal = src[j] & 0x80;
 		byte cur = src[j];
 		byte next = 0;
@@ -326,19 +330,39 @@ void Display::decodeScanlineColor(byte *dst, int pitch, byte *src) const {
 			byte color;
 			if (curOn == prevOn || curOn == nextOn)
 				color = curOn ? 1 : 0;
-			else {
-				if (secondPal)
-					color = (curOn == ((j + k) % 2) ? 5 : 4);
-				else
-					color = (curOn == ((j + k) % 2) ? 3 : 2);
-			}
+			else
+				color = (curOn == ((j + k) % 2) ? 3 : 2);
+
+			if (secondPal)
+				color |= 4;
 
 			dst[0] = color;
-			dst[1] = color;
-			dst[pitch] = color + 6;
-			dst[pitch + 1] = color + 6;
+			dst[pitch] = color + COLOR_PALETTE_ENTRIES;
+			++dst;
+
+			if (k == 6) {
+				if (secondPal) {
+					if (next & 0x80) {
+						dst[0] = color;
+						dst[pitch] = color + COLOR_PALETTE_ENTRIES;
+						++dst;
+					}
+				} else {
+					dst[0] = color;
+					dst[pitch] = color + COLOR_PALETTE_ENTRIES;
+					++dst;
+					if (next & 0x80) {
+						dst[0] = color | 4;
+						dst[pitch] = (color | 4) + COLOR_PALETTE_ENTRIES;
+						++dst;
+					}
+				}
+			} else {
+				dst[0] = color;
+				dst[pitch] = color + COLOR_PALETTE_ENTRIES;
+				++dst;
+			}
 
-			dst += 2;
 			prevOn = curOn;
 		}
 	}
@@ -397,20 +421,20 @@ void Display::drawChar(byte c, int x, int y) {
 
 	for (uint row = 0; row < 8; ++row) {
 		if (row & 1) {
-			buf[_font->pitch] = 6;
-			buf[_font->pitch + 1] = 6;
-			buf[_font->pitch + 6 * 2] = 6;
-			buf[_font->pitch + 6 * 2 + 1] = 6;
+			buf[_font->pitch] = COLOR_PALETTE_ENTRIES;
+			buf[_font->pitch + 1] = COLOR_PALETTE_ENTRIES;
+			buf[_font->pitch + 6 * 2] = COLOR_PALETTE_ENTRIES;
+			buf[_font->pitch + 6 * 2 + 1] = COLOR_PALETTE_ENTRIES;
 		}
 		for (uint col = 1; col < 6; ++col) {
 			if (font[c][col - 1] & (1 << row)) {
 				buf[col * 2] = 1;
 				buf[col * 2 + 1] = 1;
-				buf[_font->pitch + col * 2] = 1 + 6;
-				buf[_font->pitch + col * 2 + 1] = 1 + 6;
+				buf[_font->pitch + col * 2] = 1 + COLOR_PALETTE_ENTRIES;
+				buf[_font->pitch + col * 2 + 1] = 1 + COLOR_PALETTE_ENTRIES;
 			} else {
-				buf[_font->pitch + col * 2] = 6;
-				buf[_font->pitch + col * 2 + 1] = 6;
+				buf[_font->pitch + col * 2] = COLOR_PALETTE_ENTRIES;
+				buf[_font->pitch + col * 2 + 1] = COLOR_PALETTE_ENTRIES;
 			}
 		}
 
@@ -438,7 +462,7 @@ void Display::createFont() {
 		bufInv += _font->pitch;
 
 		for (uint col = 0; col < _font->w; ++col)
-			bufInv[col] = (buf[col] == 7 ? 6 : 7);
+			bufInv[col] = (buf[col] == COLOR_PALETTE_ENTRIES + 1 ? COLOR_PALETTE_ENTRIES : COLOR_PALETTE_ENTRIES + 1);
 
 		buf += _font->pitch;
 		bufInv += _font->pitch;


Commit: 50d6e6938a60b323e1a1fbe2559e175492625cba
    https://github.com/scummvm/scummvm/commit/50d6e6938a60b323e1a1fbe2559e175492625cba
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Refactor graphics code

Changed paths:
    engines/adl/display.cpp



diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp
index 678b8c8..2a24b65 100644
--- a/engines/adl/display.cpp
+++ b/engines/adl/display.cpp
@@ -52,6 +52,12 @@ const byte colorPalette[COLOR_PALETTE_ENTRIES * 3] = {
 	0xf2, 0x5e, 0x00
 };
 
+// Corresponding color in second palette
+#define PAL2(X) ((X) | 0x04)
+
+// Alternate color for odd pixel rows (for scanlines)
+#define ALTCOL(X) ((X) | 0x08)
+
 // Green monochrome palette
 #define MONO_PALETTE_ENTRIES 2
 const byte monoPalette[MONO_PALETTE_ENTRIES * 3] = {
@@ -294,6 +300,17 @@ void Display::showScanlines(bool enable) {
 	}
 }
 
+static void copyEvenSurfaceRows(Graphics::Surface &surf) {
+	byte *src = (byte *)surf.getPixels();
+
+	for (uint y = 0; y < surf.h / 2; ++y) {
+		byte *dst = src + surf.pitch;
+		for (uint x = 0; x < surf.w; ++x)
+			dst[x] = ALTCOL(src[x]);
+		src += surf.pitch * 2;
+	}
+}
+
 void Display::updateHiResSurface() {
 	byte *src = _frameBuf;
 	byte *dst = (byte *)_frameBufSurface->getPixels();
@@ -303,68 +320,78 @@ void Display::updateHiResSurface() {
 		src += DISPLAY_PITCH;
 		dst += _frameBufSurface->pitch * 2;
 	}
+
+	copyEvenSurfaceRows(*_frameBufSurface);
 }
 
-void Display::decodeScanlineColor(byte *dst, int pitch, byte *src) const {
-	bool prevOn = false;
+static inline byte processColorBits(uint16 &bits, bool &odd, bool secondPal) {
+	byte color = 0;
+
+	switch (bits & 0x7) {
+	case 0x3: // 011 (white)
+	case 0x6: // 110
+	case 0x7: // 111
+		color = 1;
+		break;
+	case 0x2: // 010 (color)
+		color = 2 + odd;
+		break;
+	case 0x5: // 101 (color)
+		color = 2 + !odd;
+	}
 
-	if (src[0] & 0x80)
-		dst++;
+	if (secondPal)
+		color = PAL2(color);
 
-	for (uint j = 0; j < 40; ++j) {
-		bool secondPal = src[j] & 0x80;
-		byte cur = src[j];
-		byte next = 0;
-		if (j != 39)
-			next = src[j + 1];
+	odd = !odd;
+	bits >>= 1;
 
-		for (uint k = 0; k < 7; ++k) {
-			bool curOn = cur & (1 << k);
-			bool nextOn;
+	return color;
+}
 
-			if (k != 6)
-				nextOn = cur & (1 << (k + 1));
-			else
-				nextOn = next & 1;
+void Display::decodeScanlineColor(byte *dst, int pitch, byte *src) const {
+	uint16 bits = (src[0] & 0x7f) << 1;
+	byte pal = src[0] >> 7;
 
-			byte color;
-			if (curOn == prevOn || curOn == nextOn)
-				color = curOn ? 1 : 0;
-			else
-				color = (curOn == ((j + k) % 2) ? 3 : 2);
+	if (pal != 0)
+		*dst++ = 0;
 
-			if (secondPal)
-				color |= 4;
+	bool odd = false;
 
-			dst[0] = color;
-			dst[pitch] = color + COLOR_PALETTE_ENTRIES;
-			++dst;
-
-			if (k == 6) {
-				if (secondPal) {
-					if (next & 0x80) {
-						dst[0] = color;
-						dst[pitch] = color + COLOR_PALETTE_ENTRIES;
-						++dst;
-					}
-				} else {
-					dst[0] = color;
-					dst[pitch] = color + COLOR_PALETTE_ENTRIES;
-					++dst;
-					if (next & 0x80) {
-						dst[0] = color | 4;
-						dst[pitch] = (color | 4) + COLOR_PALETTE_ENTRIES;
-						++dst;
-					}
-				}
-			} else {
-				dst[0] = color;
-				dst[pitch] = color + COLOR_PALETTE_ENTRIES;
-				++dst;
-			}
+	for (uint i = 0; i < 40; ++i) {
+		if (i != 39) {
+			bits |= (src[i + 1] & 0x7f) << 8;
+			pal |= (src[i + 1] >> 7) << 1;
+		}
 
-			prevOn = curOn;
+		// For the first 6 bits in the block we draw two pixels
+		for (uint j = 0; j < 6; ++j) {
+			byte color = processColorBits(bits, odd, pal & 1);
+			*dst++ = color;
+			*dst++ = color;
 		}
+
+		// Last bit of the block, draw one, two or three pixels
+		byte color = processColorBits(bits, odd, pal & 1);
+
+		// Draw the first pixel
+		*dst++ = color;
+
+		switch (pal) {
+			case 0x0:
+			case 0x3:
+				// If palette stays the same, draw a second pixel
+				*dst++ = color;
+				break;
+			case 0x2:
+				// If we're moving from first to second palette,
+				// draw a second pixel, and a third in the second
+				// palette.
+				*dst++ = color;
+				*dst++ = PAL2(color);
+		}
+
+		pal >>= 1;
 	}
 }
 
@@ -420,21 +447,10 @@ void Display::drawChar(byte c, int x, int y) {
 	byte *buf = (byte *)_font->getPixels() + y * _font->pitch + x;
 
 	for (uint row = 0; row < 8; ++row) {
-		if (row & 1) {
-			buf[_font->pitch] = COLOR_PALETTE_ENTRIES;
-			buf[_font->pitch + 1] = COLOR_PALETTE_ENTRIES;
-			buf[_font->pitch + 6 * 2] = COLOR_PALETTE_ENTRIES;
-			buf[_font->pitch + 6 * 2 + 1] = COLOR_PALETTE_ENTRIES;
-		}
 		for (uint col = 1; col < 6; ++col) {
 			if (font[c][col - 1] & (1 << row)) {
 				buf[col * 2] = 1;
 				buf[col * 2 + 1] = 1;
-				buf[_font->pitch + col * 2] = 1 + COLOR_PALETTE_ENTRIES;
-				buf[_font->pitch + col * 2 + 1] = 1 + COLOR_PALETTE_ENTRIES;
-			} else {
-				buf[_font->pitch + col * 2] = COLOR_PALETTE_ENTRIES;
-				buf[_font->pitch + col * 2 + 1] = COLOR_PALETTE_ENTRIES;
 			}
 		}
 
@@ -458,21 +474,18 @@ void Display::createFont() {
 		for (uint col = 0; col < _font->w; ++col)
 			bufInv[col] = (buf[col] ? 0 : 1);
 
-		buf += _font->pitch;
-		bufInv += _font->pitch;
-
-		for (uint col = 0; col < _font->w; ++col)
-			bufInv[col] = (buf[col] == COLOR_PALETTE_ENTRIES + 1 ? COLOR_PALETTE_ENTRIES : COLOR_PALETTE_ENTRIES + 1);
-
-		buf += _font->pitch;
-		bufInv += _font->pitch;
+		buf += _font->pitch * 2;
+		bufInv += _font->pitch * 2;
 	}
+
+	copyEvenSurfaceRows(*_font);
 }
 
 void Display::scrollUp() {
 	memmove(_textBuf, _textBuf + 40, kTextBufSize - 40);
 	memset(_textBuf + kTextBufSize - 40, APPLECHAR(' '), 40);
-	_cursorPos -= 40;
+	if (_cursorPos >= 40)
+		_cursorPos -= 40;
 }
 
 } // End of namespace Adl


Commit: d3bfdc36578f137352589b8efacc3f4eb24054aa
    https://github.com/scummvm/scummvm/commit/d3bfdc36578f137352589b8efacc3f4eb24054aa
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Add more #defines to replace literals

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



diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp
index 2a24b65..6f72f91 100644
--- a/engines/adl/display.cpp
+++ b/engines/adl/display.cpp
@@ -39,6 +39,11 @@ namespace Adl {
 // This implements the Apple II "Hi-Res" display mode
 
 #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
 const byte colorPalette[COLOR_PALETTE_ENTRIES * 3] = {
@@ -117,14 +122,15 @@ Display::Display() :
 
 	showScanlines(_scanlines);
 
-	_frameBuf = new byte[DISPLAY_PITCH * DISPLAY_HEIGHT];
+	_frameBuf = new byte[DISPLAY_SIZE];
+	memset(_frameBuf, 0, DISPLAY_SIZE);
 	_frameBufSurface = new Graphics::Surface;
 	// We need 2x scaling to properly render the half-pixel shift
 	// of the second palette
 	_frameBufSurface->create(DISPLAY_WIDTH * 2, DISPLAY_HEIGHT * 2, Graphics::PixelFormat::createFormatCLUT8());
 
-	_textBuf = new byte[kTextBufSize];
-	memset(_textBuf, APPLECHAR(' '), kTextBufSize);
+	_textBuf = new byte[TEXT_BUF_SIZE];
+	memset(_textBuf, APPLECHAR(' '), TEXT_BUF_SIZE);
 	_textBufSurface = new Graphics::Surface;
 	// For ease of copying, also use 2x scaling here
 	_textBufSurface->create(DISPLAY_WIDTH * 2, DISPLAY_HEIGHT * 2, Graphics::PixelFormat::createFormatCLUT8());
@@ -193,9 +199,9 @@ bool Display::saveThumbnail(Common::WriteStream &out) {
 }
 
 void Display::loadFrameBuffer(Common::ReadStream &stream) {
+	byte *dst = _frameBuf;
 	for (uint j = 0; j < 8; ++j) {
 		for (uint i = 0; i < 8; ++i) {
-			byte *dst = _frameBuf + DISPLAY_PITCH  * (i * 8 + j);
 			stream.read(dst, DISPLAY_PITCH);
 			dst += DISPLAY_PITCH * 64;
 			stream.read(dst, DISPLAY_PITCH);
@@ -203,12 +209,13 @@ void Display::loadFrameBuffer(Common::ReadStream &stream) {
 			stream.read(dst, DISPLAY_PITCH);
 			stream.readUint32LE();
 			stream.readUint32LE();
-			dst += DISPLAY_PITCH * 64;
+			dst -= DISPLAY_PITCH * 120;
 		}
+		dst -= DISPLAY_PITCH * 63;
 	}
 }
 
-void Display::putPixel(Common::Point p, byte color) {
+void Display::putPixel(const Common::Point &p, byte color) {
 	byte offset = p.x / 7;
 
 	if (offset & 1) {
@@ -230,35 +237,33 @@ void Display::clear(byte color) {
 	if (c >= 0x40 && c < 0xc0)
 		val = 0x7f;
 
-	for (uint i = 0; i < DISPLAY_PITCH * DISPLAY_HEIGHT; ++i) {
+	for (uint i = 0; i < DISPLAY_SIZE; ++i) {
 		_frameBuf[i] = color;
 		color ^= val;
 	}
 }
 
 void Display::home() {
-	memset(_textBuf, APPLECHAR(' '), kTextBufSize);
+	memset(_textBuf, APPLECHAR(' '), TEXT_BUF_SIZE);
 	_cursorPos = 0;
 }
 
 void Display::moveCursorForward() {
 	++_cursorPos;
 
-	if (_cursorPos >= kTextBufSize)
+	if (_cursorPos >= TEXT_BUF_SIZE)
 		scrollUp();
 }
 
 void Display::moveCursorBackward() {
-	--_cursorPos;
-
-	if (_cursorPos < 0)
-		_cursorPos = 0;
+	if (_cursorPos > 0)
+		--_cursorPos;
 }
 
 void Display::moveCursorTo(const Common::Point &pos) {
-	_cursorPos = pos.y * 40 + pos.x;
+	_cursorPos = pos.y * TEXT_WIDTH + pos.x;
 
-	if (_cursorPos >= kTextBufSize)
+	if (_cursorPos >= TEXT_BUF_SIZE)
 		error("Cursor position (%i, %i) out of bounds", pos.x, pos.y);
 }
 
@@ -268,13 +273,13 @@ void Display::printString(const Common::String &str) {
 		byte b = *c;
 
 		if (*c == APPLECHAR('\r'))
-			_cursorPos = (_cursorPos / 40 + 1) * 40;
+			_cursorPos = (_cursorPos / TEXT_WIDTH + 1) * TEXT_WIDTH;
 		else if (b < 0x80 || b >= 0xa0) {
 			setCharAtCursor(b);
 			++_cursorPos;
 		}
 
-		if (_cursorPos == kTextBufSize)
+		if (_cursorPos == TEXT_BUF_SIZE)
 			scrollUp();
 	}
 
@@ -358,8 +363,8 @@ void Display::decodeScanlineColor(byte *dst, int pitch, byte *src) const {
 
 	bool odd = false;
 
-	for (uint i = 0; i < 40; ++i) {
-		if (i != 39) {
+	for (uint i = 0; i < DISPLAY_PITCH; ++i) {
+		if (i != DISPLAY_PITCH - 1) {
 			bits |= (src[i + 1] & 0x7f) << 8;
 			pal |= (src[i + 1] >> 7) << 1;
 		}
@@ -424,9 +429,9 @@ void Display::decodeScanline(byte *dst, int pitch, byte *src) const {
 
 void Display::updateTextSurface() {
 	for (uint row = 0; row < 24; ++row)
-		for (uint col = 0; col < 40; ++col) {
-			int charPos = row * 40 + col;
-			char c = _textBuf[row * 40 + col];
+		for (uint col = 0; col < TEXT_WIDTH; ++col) {
+			uint charPos = row * TEXT_WIDTH + col;
+			char c = _textBuf[row * TEXT_WIDTH + col];
 
 			if (charPos == _cursorPos && _showCursor)
 				c = (c & 0x3f) | 0x40;
@@ -482,10 +487,10 @@ void Display::createFont() {
 }
 
 void Display::scrollUp() {
-	memmove(_textBuf, _textBuf + 40, kTextBufSize - 40);
-	memset(_textBuf + kTextBufSize - 40, APPLECHAR(' '), 40);
-	if (_cursorPos >= 40)
-		_cursorPos -= 40;
+	memmove(_textBuf, _textBuf + TEXT_WIDTH, TEXT_BUF_SIZE - TEXT_WIDTH);
+	memset(_textBuf + TEXT_BUF_SIZE - TEXT_WIDTH, APPLECHAR(' '), TEXT_WIDTH);
+	if (_cursorPos >= TEXT_WIDTH)
+		_cursorPos -= TEXT_WIDTH;
 }
 
 } // End of namespace Adl
diff --git a/engines/adl/display.h b/engines/adl/display.h
index b93128f..102622e 100644
--- a/engines/adl/display.h
+++ b/engines/adl/display.h
@@ -61,7 +61,7 @@ public:
 
 	// Graphics
 	void loadFrameBuffer(Common::ReadStream &stream);
-	void putPixel(Common::Point p1, byte color);
+	void putPixel(const Common::Point &p, byte color);
 	void clear(byte color);
 
 	// Text
@@ -99,7 +99,7 @@ private:
 	byte *_textBuf;
 	Graphics::Surface *_textBufSurface;
 	Graphics::Surface *_font;
-	int _cursorPos;
+	uint _cursorPos;
 	bool _showCursor;
 };
  


Commit: b2d2f3405e0b36e92402b6c38bc2c406ea960147
    https://github.com/scummvm/scummvm/commit/b2d2f3405e0b36e92402b6c38bc2c406ea960147
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Make palettes static

Changed paths:
    engines/adl/display.cpp



diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp
index 6f72f91..235e42b 100644
--- a/engines/adl/display.cpp
+++ b/engines/adl/display.cpp
@@ -46,7 +46,7 @@ namespace Adl {
 #define TEXT_BUF_SIZE (TEXT_WIDTH * TEXT_HEIGHT)
 
 #define COLOR_PALETTE_ENTRIES 8
-const byte colorPalette[COLOR_PALETTE_ENTRIES * 3] = {
+static const byte colorPalette[COLOR_PALETTE_ENTRIES * 3] = {
 	0x00, 0x00, 0x00,
 	0xff, 0xff, 0xff,
 	0xc7, 0x34, 0xff,
@@ -65,7 +65,7 @@ const byte colorPalette[COLOR_PALETTE_ENTRIES * 3] = {
 
 // Green monochrome palette
 #define MONO_PALETTE_ENTRIES 2
-const byte monoPalette[MONO_PALETTE_ENTRIES * 3] = {
+static const byte monoPalette[MONO_PALETTE_ENTRIES * 3] = {
 	0x00, 0x00, 0x00,
 	0x00, 0xc0, 0x01
 };
@@ -110,7 +110,7 @@ Display::Display() :
 		_cursorPos(0),
 		_showCursor(false) {
 
-	initGraphics(560, 384, true);
+	initGraphics(DISPLAY_WIDTH * 2, DISPLAY_HEIGHT * 2, true);
 
 	_monochrome = !ConfMan.getBool("color");
 	_scanlines = ConfMan.getBool("scanlines");


Commit: 165e333f4f3fbde90f83c6cd8fe587e89e7455d7
    https://github.com/scummvm/scummvm/commit/165e333f4f3fbde90f83c6cd8fe587e89e7455d7
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Implement half-pixel shift for monochrome

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



diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp
index 235e42b..cc51e4a 100644
--- a/engines/adl/display.cpp
+++ b/engines/adl/display.cpp
@@ -305,31 +305,7 @@ void Display::showScanlines(bool enable) {
 	}
 }
 
-static void copyEvenSurfaceRows(Graphics::Surface &surf) {
-	byte *src = (byte *)surf.getPixels();
-
-	for (uint y = 0; y < surf.h / 2; ++y) {
-		byte *dst = src + surf.pitch;
-		for (uint x = 0; x < surf.w; ++x)
-			dst[x] = ALTCOL(src[x]);
-		src += surf.pitch * 2;
-	}
-}
-
-void Display::updateHiResSurface() {
-	byte *src = _frameBuf;
-	byte *dst = (byte *)_frameBufSurface->getPixels();
-
-	for (uint i = 0; i < DISPLAY_HEIGHT; ++i) {
-		decodeScanline(dst, _frameBufSurface->pitch, src);
-		src += DISPLAY_PITCH;
-		dst += _frameBufSurface->pitch * 2;
-	}
-
-	copyEvenSurfaceRows(*_frameBufSurface);
-}
-
-static inline byte processColorBits(uint16 &bits, bool &odd, bool secondPal) {
+static byte processColorBits(uint16 &bits, bool &odd, bool secondPal) {
 	byte color = 0;
 
 	switch (bits & 0x7) {
@@ -354,7 +330,7 @@ static inline byte processColorBits(uint16 &bits, bool &odd, bool secondPal) {
 	return color;
 }
 
-void Display::decodeScanlineColor(byte *dst, int pitch, byte *src) const {
+static void renderPixelRowColor(byte *dst, byte *src) {
 	uint16 bits = (src[0] & 0x7f) << 1;
 	byte pal = src[0] >> 7;
 
@@ -400,31 +376,65 @@ void Display::decodeScanlineColor(byte *dst, int pitch, byte *src) const {
 	}
 }
 
-void Display::decodeScanlineMono(byte *dst, int pitch, byte *src) const {
-	// TODO: shift secondPal by half a pixel
+static void renderPixelRowMono(byte *dst, byte *src) {
+	byte pal = src[0] >> 7;
 
-	for (uint j = 0; j < 39; ++j) {
-		for (uint k = 0; k < 7; ++k) {
-			byte color = 0;
+	if (pal != 0)
+		*dst++ = 0;
+
+	for (uint i = 0; i < DISPLAY_PITCH; ++i) {
+		if (i != DISPLAY_PITCH - 1)
+			pal |= (src[i + 1] >> 7) << 1;
+
+		for (uint j = 0; j < 6; ++j) {
+			bool color = src[i] & (1 << j);
+			*dst++ = color;
+			*dst++ = color;
+		}
 
-			if (src[j] & (1 << k))
-				color = 1;
+		bool color = src[i] & (1 << 6);
 
-			dst[0] = color;
-			dst[1] = color;
-			dst[pitch] = color + 6;
-			dst[pitch + 1] = color + 6;
+		*dst++ = color;
 
-			dst += 2;
+		switch (pal) {
+			case 0x0:
+			case 0x3:
+				*dst++ = color;
+				break;
+			case 0x2:
+				*dst++ = color;
+				*dst++ = color;
 		}
+
+		pal >>= 1;
 	}
 }
 
-void Display::decodeScanline(byte *dst, int pitch, byte *src) const {
-	if (_monochrome)
-		decodeScanlineMono(dst, pitch, src);
-	else
-		decodeScanlineColor(dst, pitch, src);
+static void copyEvenSurfaceRows(Graphics::Surface &surf) {
+	byte *src = (byte *)surf.getPixels();
+
+	for (uint y = 0; y < surf.h / 2; ++y) {
+		byte *dst = src + surf.pitch;
+		for (uint x = 0; x < surf.w; ++x)
+			dst[x] = ALTCOL(src[x]);
+		src += surf.pitch * 2;
+	}
+}
+
+void Display::updateHiResSurface() {
+	byte *src = _frameBuf;
+	byte *dst = (byte *)_frameBufSurface->getPixels();
+
+	for (uint i = 0; i < DISPLAY_HEIGHT; ++i) {
+		if (_monochrome)
+			renderPixelRowMono(dst, src);
+		else
+			renderPixelRowColor(dst, src);
+		src += DISPLAY_PITCH;
+		dst += _frameBufSurface->pitch * 2;
+	}
+
+	copyEvenSurfaceRows(*_frameBufSurface);
 }
 
 void Display::updateTextSurface() {
diff --git a/engines/adl/display.h b/engines/adl/display.h
index 102622e..8690659 100644
--- a/engines/adl/display.h
+++ b/engines/adl/display.h
@@ -80,9 +80,6 @@ private:
 
 	void updateHiResSurface();
 	void showScanlines(bool enable);
-	void decodeScanlineColor(byte *dst, int pitch, byte *src) const;
-	void decodeScanlineMono(byte *dst, int pitch, byte *src) const;
-	void decodeScanline(byte *dst, int pitch, byte *src) const;
 
 	void updateTextSurface();
 	void drawChar(byte c, int x, int y);


Commit: 1e1a5d4f0761ba22257f59cfd70aeb53a47b0321
    https://github.com/scummvm/scummvm/commit/1e1a5d4f0761ba22257f59cfd70aeb53a47b0321
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Fix darkness setting in a move too late

Changed paths:
    engines/adl/adl.cpp



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 313b146..c58f28a 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -515,9 +515,9 @@ void AdlEngine::showRoom() {
 	if (!_state.isDark) {
 		drawPic(curRoom().curPicture);
 		drawItems();
-		_display->updateHiResScreen();
 	}
 
+	_display->updateHiResScreen();
 	printMessage(curRoom().description, false);
 }
 


Commit: 6379fbc124b63221576206bed070fa2a91b99718
    https://github.com/scummvm/scummvm/commit/6379fbc124b63221576206bed070fa2a91b99718
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Add more #defines to replace literals

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



diff --git a/engines/adl/display.h b/engines/adl/display.h
index 8690659..ce8f86b 100644
--- a/engines/adl/display.h
+++ b/engines/adl/display.h
@@ -74,10 +74,6 @@ public:
 	void showCursor(bool enable);
 
 private:
-	enum {
-		kTextBufSize = 40 * 24
-	};
-
 	void updateHiResSurface();
 	void showScanlines(bool enable);
 
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 8b5b922..d3e4c3e 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -40,6 +40,11 @@
 
 namespace Adl {
 
+#define IDI_HR1_NUM_ROOMS        41
+#define IDI_HR1_NUM_PICS         98
+#define IDI_HR1_NUM_VARS         20
+#define IDI_HR1_NUM_ITEM_OFFSETS 21
+
 // Messages used outside of scripts
 #define IDI_HR1_MSG_CANT_GO_THERE      137
 #define IDI_HR1_MSG_DONT_UNDERSTAND     37
@@ -73,15 +78,28 @@ static const StringOffset stringOffsets[] = {
 	{ IDI_HR1_STR_PRESS_RETURN,    0x5f68 }
 };
 
-#define IDI_HR1_OFS_PD_TEXT_0 0x5d
-#define IDI_HR1_OFS_PD_TEXT_1 0x12b
-#define IDI_HR1_OFS_PD_TEXT_2 0x16d
-#define IDI_HR1_OFS_PD_TEXT_3 0x259
+#define IDI_HR1_OFS_PD_TEXT_0    0x005d
+#define IDI_HR1_OFS_PD_TEXT_1    0x012b
+#define IDI_HR1_OFS_PD_TEXT_2    0x016d
+#define IDI_HR1_OFS_PD_TEXT_3    0x0259
+
+#define IDI_HR1_OFS_INTRO_TEXT   0x0066
+#define IDI_HR1_OFS_GAME_OR_HELP 0x000f
+
+#define IDI_HR1_OFS_LOGO_0       0x1003
+#define IDI_HR1_OFS_LOGO_1       0x1800
+
+#define IDI_HR1_OFS_ITEMS        0x0100
+#define IDI_HR1_OFS_ROOMS        0x050a
+#define IDI_HR1_OFS_PICS         0x4b00
+#define IDI_HR1_OFS_CMDS_0       0x3c00
+#define IDI_HR1_OFS_CMDS_1       0x3d00
 
-#define IDI_HR1_OFS_INTRO_TEXT 0x66
-#define IDI_HR1_OFS_GAME_OR_HELP 0xf
+#define IDI_HR1_OFS_ITEM_OFFSETS 0x68ff
+#define IDI_HR1_OFS_LINE_ART     0x4f00
 
-#define IDI_HR1_OFS_LOGO_0 0x1003
+#define IDI_HR1_OFS_VERBS        0x3800
+#define IDI_HR1_OFS_NOUNS        0x0f00
 
 HiRes1Engine::HiRes1Engine(OSystem *syst, const AdlGameDescription *gd) :
 		AdlEngine(syst, gd) {
@@ -184,7 +202,7 @@ void HiRes1Engine::runIntro() {
 		error("Failed to open file");
 
 	// Title screen shown during loading
-	file.seek(0x1800);
+	file.seek(IDI_HR1_OFS_LOGO_1);
 	_display->loadFrameBuffer(file);
 	_display->updateHiResScreen();
 	delay(2000);
@@ -246,15 +264,15 @@ void HiRes1Engine::initState() {
 	_state.isDark = false;
 
 	_state.vars.clear();
-	_state.vars.resize(20);
+	_state.vars.resize(IDI_HR1_NUM_VARS);
 
 	if (!f.open("ADVENTURE"))
 		error("Failed to open file");
 
 	// Load room data from executable
 	_state.rooms.clear();
-	f.seek(0x50a);
-	for (uint i = 0; i < MH_ROOMS; ++i) {
+	f.seek(IDI_HR1_OFS_ROOMS);
+	for (uint i = 0; i < IDI_HR1_NUM_ROOMS; ++i) {
 		Room room;
 		f.readByte();
 		room.description = f.readByte();
@@ -265,9 +283,9 @@ void HiRes1Engine::initState() {
 		_state.rooms.push_back(room);
 	}
 
-	// Load inventory data from executable
+	// Load item data from executable
 	_state.items.clear();
-	f.seek(0x100);
+	f.seek(IDI_HR1_OFS_ITEMS);
 	while (f.readByte() != 0xff) {
 		Item item;
 		item.noun = f.readByte();
@@ -321,8 +339,8 @@ void HiRes1Engine::runGame() {
 	}
 
 	// Load picture data from executable
-	f.seek(0x4b00);
-	for (uint i = 0; i < MH_PICS; ++i) {
+	f.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();
@@ -330,15 +348,15 @@ void HiRes1Engine::runGame() {
 	}
 
 	// Load commands from executable
-	f.seek(0x3D00);
+	f.seek(IDI_HR1_OFS_CMDS_1);
 	readCommands(f, _roomCommands);
 
-	f.seek(0x3C00);
+	f.seek(IDI_HR1_OFS_CMDS_0);
 	readCommands(f, _globalCommands);
 
 	// Load dropped item offsets
-	f.seek(0x68ff);
-	for (uint i = 0; i < MH_ITEM_OFFSETS; ++i) {
+	f.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();
@@ -346,12 +364,12 @@ void HiRes1Engine::runGame() {
 	}
 
 	// Load right-angle line art
-	f.seek(0x4f00);
+	f.seek(IDI_HR1_OFS_LINE_ART);
 	uint16 lineArtTotal = f.readUint16LE();
 	for (uint i = 0; i < lineArtTotal; ++i) {
-		f.seek(0x4f00 + 2 + i * 2);
+		f.seek(IDI_HR1_OFS_LINE_ART + 2 + i * 2);
 		uint16 offset = f.readUint16LE();
-		f.seek(0x4f00 + offset);
+		f.seek(IDI_HR1_OFS_LINE_ART + offset);
 
 		Common::Array<byte> lineArt;
 		byte b = f.readByte();
@@ -362,10 +380,10 @@ void HiRes1Engine::runGame() {
 		_lineArt.push_back(lineArt);
 	}
 
-	f.seek(0x3800);
+	f.seek(IDI_HR1_OFS_VERBS);
 	loadVerbs(f);
 
-	f.seek(0xf00);
+	f.seek(IDI_HR1_OFS_NOUNS);
 	loadNouns(f);
 
 	printASCIIString("\r\r\r\r\r");
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index cae5980..f5c6d5b 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -20,8 +20,8 @@
  *
  */
 
-#ifndef ADL_ADL_V1_H
-#define ADL_ADL_V1_H
+#ifndef ADL_HIRES1_H
+#define ADL_HIRES1_H
 
 #include "adl/adl.h"
 
@@ -31,10 +31,6 @@ class ReadStream;
 
 namespace Adl {
 
-enum {
-	IDI_HR1_MSG_
-};
-
 class HiRes1Engine : public AdlEngine {
 public:
 	HiRes1Engine(OSystem *syst, const AdlGameDescription *gd);
@@ -43,12 +39,6 @@ protected:
 	void runGame();
 
 private:
-	enum {
-		MH_ROOMS = 41,
-		MH_PICS = 98,
-		MH_ITEM_OFFSETS = 21
-	};
-
 	void restartGame();
 	void printMessage(uint idx, bool wait = true);
 	uint getEngineMessage(EngineMessage msg);


Commit: f62c56e38475ccab0c94db949a14991e5423fc13
    https://github.com/scummvm/scummvm/commit/f62c56e38475ccab0c94db949a14991e5423fc13
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Clean up line drawing

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



diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index d3e4c3e..1345489 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -20,20 +20,11 @@
  *
  */
 
-#include "common/scummsys.h"
-
-#include "common/config-manager.h"
+#include "common/system.h"
 #include "common/debug.h"
-#include "common/debug-channels.h"
 #include "common/error.h"
 #include "common/file.h"
-#include "common/fs.h"
-#include "common/system.h"
-#include "common/events.h"
 #include "common/stream.h"
-#include "graphics/palette.h"
-
-#include "engines/util.h"
 
 #include "adl/hires1.h"
 #include "adl/display.h"
@@ -208,7 +199,7 @@ void HiRes1Engine::runIntro() {
 	delay(2000);
 }
 
-void HiRes1Engine::drawPic(Common::ReadStream &stream, Common::Point pos) {
+void HiRes1Engine::drawPic(Common::ReadStream &stream, const Common::Point &pos) {
 	byte x, y;
 	bool bNewLine = false;
 	byte oldX = 0, oldY = 0;
@@ -473,38 +464,39 @@ uint HiRes1Engine::getEngineMessage(EngineMessage msg) {
 	}
 }
 
-void HiRes1Engine::drawLine(Common::Point p1, Common::Point p2, byte color) {
+void HiRes1Engine::drawLine(const Common::Point &p1, const Common::Point &p2, byte color) {
 	int16 deltaX = p2.x - p1.x;
-	byte dir = deltaX >> 8;
+	int8 xStep = 1;
 
-	if (deltaX < 0)
+	if (deltaX < 0) {
 		deltaX = -deltaX;
+		xStep = -1;
+	}
 
-	int16 err = deltaX;
+	int16 deltaY = p2.y - p1.y;
+	int8 yStep = -1;
 
-	int16 deltaY = p2.y - p1.y - 1;
-	dir >>= 1;
-	if (deltaY >= 0) {
-		deltaY = -deltaY - 2;
-		dir |= 0x80;
+	if (deltaY > 0) {
+		deltaY = -deltaY;
+		yStep = 1;
 	}
 
-	int16 steps = deltaY - deltaX;
-
-	err += deltaY + 1;
+	Common::Point p(p1);
+	int16 steps = deltaX - deltaY + 1;
+	int16 err = deltaX + deltaY;
 
 	while (1) {
-		_display->putPixel(p1, color);
+		_display->putPixel(p, color);
 
-		if (++steps == 0)
+		if (--steps == 0)
 			return;
 
 		if (err < 0) {
-			p1.y += (dir & 0x80 ? 1 : -1);
+			p.y += yStep;
 			err += deltaX;
 		} else {
-			p1.x += (dir & 0x40 ? -1 : 1);
-			err += deltaY + 1;
+			p.x += xStep;
+			err += deltaY;
 		}
 	}
 }
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index f5c6d5b..12c3c94 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -45,9 +45,9 @@ private:
 
 	void initState();
 	void runIntro();
-	void drawPic(Common::ReadStream &stream, Common::Point pos);
+	void drawPic(Common::ReadStream &stream, const Common::Point &pos);
 	void drawItems();
-	void drawLine(Common::Point p1, Common::Point p2, byte color);
+	void drawLine(const Common::Point &p1, const Common::Point &p2, byte color);
 	void drawPic(byte pic, Common::Point pos);
 };
 


Commit: af42795ffa9331a16c1c6fa819f5c3960fd3cfe1
    https://github.com/scummvm/scummvm/commit/af42795ffa9331a16c1c6fa819f5c3960fd3cfe1
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Improve error messages

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



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index c58f28a..c395fbb 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -94,7 +94,10 @@ Common::String AdlEngine::readString(Common::ReadStream &stream, byte until) {
 	while (1) {
 		byte b = stream.readByte();
 
-		if (stream.eos() || stream.err() || b == until)
+		if (stream.eos() || stream.err())
+			error("Error reading string");
+
+		if (b == until)
 			break;
 
 		str += b;
diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp
index cc51e4a..7af6f66 100644
--- a/engines/adl/display.cpp
+++ b/engines/adl/display.cpp
@@ -213,6 +213,9 @@ void Display::loadFrameBuffer(Common::ReadStream &stream) {
 		}
 		dst -= DISPLAY_PITCH * 63;
 	}
+
+	if (stream.eos() || stream.err())
+		error("Failed to read frame buffer");
 }
 
 void Display::putPixel(const Common::Point &p, byte color) {
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 1345489..9140780 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -31,10 +31,16 @@
 
 namespace Adl {
 
-#define IDI_HR1_NUM_ROOMS        41
-#define IDI_HR1_NUM_PICS         98
-#define IDI_HR1_NUM_VARS         20
-#define IDI_HR1_NUM_ITEM_OFFSETS 21
+#define IDS_HR1_EXE_0    "AUTO LOAD OBJ"
+#define IDS_HR1_EXE_1    "ADVENTURE"
+#define IDS_HR1_LOADER   "MYSTERY.HELLO"
+#define IDS_HR1_MESSAGES "MESSAGES"
+
+#define IDI_HR1_NUM_ROOMS         41
+#define IDI_HR1_NUM_PICS          98
+#define IDI_HR1_NUM_VARS          20
+#define IDI_HR1_NUM_ITEM_OFFSETS  21
+#define IDI_HR1_NUM_MESSAGES     167
 
 // Messages used outside of scripts
 #define IDI_HR1_MSG_CANT_GO_THERE      137
@@ -99,8 +105,8 @@ HiRes1Engine::HiRes1Engine(OSystem *syst, const AdlGameDescription *gd) :
 void HiRes1Engine::runIntro() {
 	Common::File file;
 
-	if (!file.open("AUTO LOAD OBJ"))
-		error("Failed to open file");
+	if (!file.open(IDS_HR1_EXE_0))
+		error("Failed to open file '" IDS_HR1_EXE_0 "'");
 
 	file.seek(IDI_HR1_OFS_LOGO_0);
 	_display->setMode(DISPLAY_MODE_HIRES);
@@ -114,8 +120,8 @@ void HiRes1Engine::runIntro() {
 	_display->setMode(DISPLAY_MODE_TEXT);
 
 	Common::File basic;
-	if (!basic.open("MYSTERY.HELLO"))
-		error("Failed to open file");
+	if (!basic.open(IDS_HR1_LOADER))
+		error("Failed to open file '" IDS_HR1_LOADER "'");
 
 	Common::String str;
 
@@ -189,8 +195,8 @@ void HiRes1Engine::runIntro() {
 
 	_display->setMode(DISPLAY_MODE_MIXED);
 
-	if (!file.open("ADVENTURE"))
-		error("Failed to open file");
+	if (!file.open(IDS_HR1_EXE_1))
+		error("Failed to open file '" IDS_HR1_EXE_1 "'");
 
 	// Title screen shown during loading
 	file.seek(IDI_HR1_OFS_LOGO_1);
@@ -241,7 +247,7 @@ void HiRes1Engine::drawPic(byte pic, Common::Point pos) {
 	Common::String name = Common::String::format("BLOCK%i", _pictures[pic].block);
 
 	if (!f.open(name))
-		error("Failed to open file");
+		error("Failed to open file '%s'", name.c_str());
 
 	f.seek(_pictures[pic].offset);
 	drawPic(f, pos);
@@ -257,8 +263,8 @@ void HiRes1Engine::initState() {
 	_state.vars.clear();
 	_state.vars.resize(IDI_HR1_NUM_VARS);
 
-	if (!f.open("ADVENTURE"))
-		error("Failed to open file");
+	if (!f.open(IDS_HR1_EXE_1))
+		error("Failed to open file '" IDS_HR1_EXE_1 "'");
 
 	// Load room data from executable
 	_state.rooms.clear();
@@ -311,16 +317,16 @@ void HiRes1Engine::runGame() {
 
 	Common::File f;
 
-	if (!f.open("MESSAGES"))
-		error("Failed to open file");
+	if (!f.open(IDS_HR1_MESSAGES))
+		error("Failed to open file '" IDS_HR1_MESSAGES "'");
 
-	while (!f.eos() && !f.err())
+	for (uint i = 0; i < IDI_HR1_NUM_MESSAGES; ++i)
 		_messages.push_back(readString(f, APPLECHAR('\r')) + APPLECHAR('\r'));
 
 	f.close();
 
-	if (!f.open("ADVENTURE"))
-		error("Failed to open file");
+	if (!f.open(IDS_HR1_EXE_1))
+		error("Failed to open file '" IDS_HR1_EXE_1 "'");
 
 	// Load strings from executable
 	_strings.resize(IDI_HR1_STR_TOTAL);
@@ -371,6 +377,9 @@ void HiRes1Engine::runGame() {
 		_lineArt.push_back(lineArt);
 	}
 
+	if (f.eos() || f.err())
+		error("Failed to read game data from '" IDS_HR1_EXE_1 "'");
+
 	f.seek(IDI_HR1_OFS_VERBS);
 	loadVerbs(f);
 
@@ -465,6 +474,8 @@ uint HiRes1Engine::getEngineMessage(EngineMessage msg) {
 }
 
 void HiRes1Engine::drawLine(const Common::Point &p1, const Common::Point &p2, byte color) {
+	// This draws a four-connected line
+
 	int16 deltaX = p2.x - p1.x;
 	int8 xStep = 1;
 
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index 12c3c94..64cf8f3 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -27,6 +27,7 @@
 
 namespace Common {
 class ReadStream;
+class Point;
 }
 
 namespace Adl {
@@ -35,9 +36,6 @@ class HiRes1Engine : public AdlEngine {
 public:
 	HiRes1Engine(OSystem *syst, const AdlGameDescription *gd);
 
-protected:
-	void runGame();
-
 private:
 	void restartGame();
 	void printMessage(uint idx, bool wait = true);
@@ -45,6 +43,7 @@ private:
 
 	void initState();
 	void runIntro();
+	void runGame();
 	void drawPic(Common::ReadStream &stream, const Common::Point &pos);
 	void drawItems();
 	void drawLine(const Common::Point &p1, const Common::Point &p2, byte color);


Commit: a73dcdf224ae88c7bcf73d754781052835af4cd0
    https://github.com/scummvm/scummvm/commit/a73dcdf224ae88c7bcf73d754781052835af4cd0
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Move functionality into base class

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



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index c395fbb..701f902 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -72,6 +72,8 @@ bool AdlEngine::hasFeature(EngineFeature f) const {
 Common::Error AdlEngine::run() {
 	_display = new Display();
 
+	loadData();
+
 	int saveSlot = ConfMan.getInt("save_slot");
 	if (saveSlot >= 0) {
 		if (loadGameState(saveSlot).getCode() != Common::kNoError)
@@ -83,7 +85,54 @@ Common::Error AdlEngine::run() {
 		initState();
 	}
 
-	runGame();
+	_display->setMode(DISPLAY_MODE_MIXED);
+	printASCIIString("\r\r\r\r\r");
+
+	while (1) {
+		uint verb = 0, noun = 0;
+
+		// When restoring from the launcher, we don't read
+		// input on the first iteration. This is needed to
+		// ensure that restoring from the launcher and
+		// restoring in-game brings us to the same game state.
+		// (Also see comment below.)
+		if (!_isRestoring) {
+			clearScreen();
+			showRoom();
+
+			_canSaveNow = _canRestoreNow = true;
+			getInput(verb, noun);
+			_canSaveNow = _canRestoreNow = false;
+
+			if (shouldQuit())
+				break;
+
+			if (!doOneCommand(_roomCommands, verb, noun))
+				printEngineMessage(IDI_MSG_DONT_UNDERSTAND);
+		}
+
+		if (_isRestoring) {
+			// We restored from the GMM or launcher. As restoring
+			// with "RESTORE GAME" does not end command processing,
+			// we don't break it off here either. This essentially
+			// means that restoring a game will always run through
+			// the global commands and increase the move counter
+			// before the first user input.
+			printASCIIString("\r");
+			_isRestoring = false;
+			verb = _restoreVerb;
+			noun = _restoreNoun;
+		}
+
+		// Restarting does end command processing
+		if (_isRestarting) {
+			_isRestarting = false;
+			continue;
+		}
+
+		doAllCommands(_globalCommands, verb, noun);
+		_state.moves++;
+	}
 
 	return Common::kNoError;
 }
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 84b9214..66a5395 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -180,7 +180,8 @@ protected:
 	typedef Common::HashMap<Common::String, uint> WordMap;
 
 	virtual void runIntro() { }
-	virtual void runGame() = 0;
+	virtual void loadData() = 0;
+	void runGame();
 	virtual void initState() = 0;
 	virtual void restartGame() = 0;
 	virtual uint getEngineMessage(EngineMessage msg) = 0;
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 9140780..11d576b 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -312,9 +312,7 @@ void HiRes1Engine::restartGame() {
 	printASCIIString("\r\r\r\r\r");
 }
 
-void HiRes1Engine::runGame() {
-	_display->setMode(DISPLAY_MODE_MIXED);
-
+void HiRes1Engine::loadData() {
 	Common::File f;
 
 	if (!f.open(IDS_HR1_MESSAGES))
@@ -385,54 +383,6 @@ void HiRes1Engine::runGame() {
 
 	f.seek(IDI_HR1_OFS_NOUNS);
 	loadNouns(f);
-
-	printASCIIString("\r\r\r\r\r");
-
-	while (1) {
-		uint verb = 0, noun = 0;
-
-		// When restoring from the launcher, we don't read
-		// input on the first iteration. This is needed to
-		// ensure that restoring from the launcher and
-		// restoring in-game brings us to the same game state.
-		// (Also see comment below.)
-		if (!_isRestoring) {
-			clearScreen();
-			showRoom();
-
-			_canSaveNow = _canRestoreNow = true;
-			getInput(verb, noun);
-			_canSaveNow = _canRestoreNow = false;
-
-			if (shouldQuit())
-				return;
-
-			if (!doOneCommand(_roomCommands, verb, noun))
-				printMessage(IDI_HR1_MSG_DONT_UNDERSTAND);
-		}
-
-		if (_isRestoring) {
-			// We restored from the GMM or launcher. As restoring
-			// with "RESTORE GAME" does not end command processing,
-			// we don't break it off here either. This essentially
-			// means that restoring a game will always run through
-			// the global commands and increase the move counter
-			// before the first user input.
-			printASCIIString("\r");
-			_isRestoring = false;
-			verb = _restoreVerb;
-			noun = _restoreNoun;
-		}
-
-		// Restarting does end command processing
-		if (_isRestarting) {
-			_isRestarting = false;
-			continue;
-		}
-
-		doAllCommands(_globalCommands, verb, noun);
-		_state.moves++;
-	}
 }
 
 void HiRes1Engine::printMessage(uint idx, bool wait) {
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index 64cf8f3..f72093a 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -43,7 +43,7 @@ private:
 
 	void initState();
 	void runIntro();
-	void runGame();
+	void loadData();
 	void drawPic(Common::ReadStream &stream, const Common::Point &pos);
 	void drawItems();
 	void drawLine(const Common::Point &p1, const Common::Point &p2, byte color);


Commit: 0ec3ab142244cbaf24f0f6c97a931d0d073d4f97
    https://github.com/scummvm/scummvm/commit/0ec3ab142244cbaf24f0f6c97a931d0d073d4f97
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Fix const'ness

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



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 701f902..e0c0b3a 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -137,7 +137,7 @@ Common::Error AdlEngine::run() {
 	return Common::kNoError;
 }
 
-Common::String AdlEngine::readString(Common::ReadStream &stream, byte until) {
+Common::String AdlEngine::readString(Common::ReadStream &stream, byte until) const {
 	Common::String str;
 
 	while (1) {
@@ -155,7 +155,7 @@ Common::String AdlEngine::readString(Common::ReadStream &stream, byte until) {
 	return str;
 }
 
-void AdlEngine::printStrings(Common::SeekableReadStream &stream, int count) {
+void AdlEngine::printStrings(Common::SeekableReadStream &stream, int count) const {
 	while (1) {
 		Common::String str = readString(stream);
 		_display->printString(str);
@@ -167,11 +167,11 @@ void AdlEngine::printStrings(Common::SeekableReadStream &stream, int count) {
 	};
 }
 
-Common::String AdlEngine::getEngineString(int str) {
+Common::String AdlEngine::getEngineString(int str) const {
 	return _strings[str];
 }
 
-void AdlEngine::wordWrap(Common::String &str) {
+void AdlEngine::wordWrap(Common::String &str) const {
 	uint end = 39;
 
 	while (1) {
@@ -186,7 +186,7 @@ void AdlEngine::wordWrap(Common::String &str) {
 	}
 }
 
-void AdlEngine::printMessage(uint idx, bool wait) {
+void AdlEngine::printMessage(uint idx, bool wait) const {
 	Common::String msg = _messages[idx - 1];
 	wordWrap(msg);
 	_display->printString(msg);
@@ -195,7 +195,7 @@ void AdlEngine::printMessage(uint idx, bool wait) {
 		delay(14 * 166018 / 1000);
 }
 
-void AdlEngine::printEngineMessage(EngineMessage msg) {
+void AdlEngine::printEngineMessage(EngineMessage msg) const {
 	printMessage(getEngineMessage(msg));
 }
 
@@ -423,7 +423,7 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 	}
 }
 
-bool AdlEngine::matchCommand(const Command &command, byte verb, byte noun, bool run) {
+bool AdlEngine::matchCommand(const Command &command, byte verb, byte noun, uint *actions) const {
 	if (command.room != IDI_NONE && command.room != _state.room)
 		return false;
 
@@ -466,8 +466,7 @@ bool AdlEngine::matchCommand(const Command &command, byte verb, byte noun, bool
 		}
 	}
 
-	if (run)
-		doActions(command, noun, offset);
+	*actions = offset;
 
 	return true;
 }
@@ -477,9 +476,13 @@ bool AdlEngine::matchCommand(const Command &command, byte verb, byte noun, bool
 bool AdlEngine::doOneCommand(const Commands &commands, byte verb, byte noun) {
 	Commands::const_iterator cmd;
 
-	for (cmd = commands.begin(); cmd != commands.end(); ++cmd)
-		if (matchCommand(*cmd, verb, noun))
+	for (cmd = commands.begin(); cmd != commands.end(); ++cmd) {
+		uint offset = 0;
+		if (matchCommand(*cmd, verb, noun, &offset)) {
+			doActions(*cmd, noun, offset);
 			return true;
+		}
+	}
 
 	return false;
 }
@@ -489,7 +492,9 @@ void AdlEngine::doAllCommands(const Commands &commands, byte verb, byte noun) {
 	bool oldIsRestoring = _isRestoring;
 
 	for (cmd = commands.begin(); cmd != commands.end(); ++cmd) {
-		matchCommand(*cmd, verb, noun);
+		uint offset = 0;
+		if (matchCommand(*cmd, verb, noun, &offset))
+			doActions(*cmd, noun, offset);
 
 		// We assume no restarts happen in this command group. This
 		// simplifies enabling GMM savegame loading on the restart
@@ -499,7 +504,7 @@ void AdlEngine::doAllCommands(const Commands &commands, byte verb, byte noun) {
 	}
 }
 
-bool AdlEngine::canSaveGameStateCurrently() {
+bool AdlEngine::canSaveGameStateCurrently() const {
 	if (!_canSaveNow)
 		return false;
 
@@ -509,7 +514,7 @@ 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) {
-		if (matchCommand(*cmd, _saveVerb, _saveNoun, false)) {
+		if (matchCommand(*cmd, _saveVerb, _saveNoun)) {
 			if (cmd->verb != _saveVerb || cmd->noun != _saveNoun)
 				return false;
 			return cmd->numCond == 0 && cmd->script[0] == IDO_ACT_SAVE;
@@ -519,16 +524,16 @@ bool AdlEngine::canSaveGameStateCurrently() {
 	return false;
 }
 
-bool AdlEngine::canLoadGameStateCurrently() {
+bool AdlEngine::canLoadGameStateCurrently() const {
 	return _canRestoreNow;
 }
 
-void AdlEngine::clearScreen() {
+void AdlEngine::clearScreen() const {
 	_display->setMode(DISPLAY_MODE_MIXED);
 	_display->clear(0x00);
 }
 
-void AdlEngine::drawItems() {
+void AdlEngine::drawItems() const {
 	Common::Array<Item>::const_iterator item;
 
 	uint dropped = 0;
@@ -563,7 +568,7 @@ void AdlEngine::drawItems() {
 	}
 }
 
-void AdlEngine::showRoom() {
+void AdlEngine::showRoom() const {
 	if (!_state.isDark) {
 		drawPic(curRoom().curPicture);
 		drawItems();
@@ -722,6 +727,13 @@ Common::Error AdlEngine::loadGameState(int slot) {
 	return Common::kNoError;
 }
 
+const Room &AdlEngine::room(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::room(uint i) {
 	if (i < 1 || i > _state.rooms.size())
 		error("Room %i out of range [1, %i]", i, _state.rooms.size());
@@ -729,10 +741,21 @@ Room &AdlEngine::room(uint i) {
 	return _state.rooms[i - 1];
 }
 
+const Room &AdlEngine::curRoom() const {
+	return room(_state.room);
+}
+
 Room &AdlEngine::curRoom() {
 	return room(_state.room);
 }
 
+const Item &AdlEngine::item(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::item(uint i) {
 	if (i < 1 || i > _state.items.size())
 		error("Item %i out of range [1, %i]", i, _state.items.size());
@@ -740,6 +763,13 @@ Item &AdlEngine::item(uint i) {
 	return _state.items[i - 1];
 }
 
+const byte &AdlEngine::var(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];
+}
+
 byte &AdlEngine::var(uint i) {
 	if (i >= _state.vars.size())
 		error("Variable %i out of range [0, %i]", i, _state.vars.size() - 1);
@@ -783,7 +813,7 @@ void AdlEngine::loadWords(Common::ReadStream &stream, WordMap &map) {
 	}
 }
 
-Common::String AdlEngine::getLine() {
+Common::String AdlEngine::getLine() const {
 	// Original engine uses a global here, which isn't reset between
 	// calls and may not match actual mode
 	bool textMode = false;
@@ -806,7 +836,7 @@ Common::String AdlEngine::getLine() {
 	}
 }
 
-Common::String AdlEngine::getWord(const Common::String &line, uint &index) {
+Common::String AdlEngine::getWord(const Common::String &line, uint &index) const {
 	Common::String str;
 
 	for (uint i = 0; i < 8; ++i)
@@ -873,7 +903,7 @@ void AdlEngine::getInput(uint &verb, uint &noun) {
 	}
 }
 
-void AdlEngine::printASCIIString(const Common::String &str) {
+void AdlEngine::printASCIIString(const Common::String &str) const {
 	Common::String aStr;
 
 	Common::String::const_iterator it;
@@ -883,7 +913,7 @@ void AdlEngine::printASCIIString(const Common::String &str) {
 	_display->printString(aStr);
 }
 
-Common::String AdlEngine::inputString(byte prompt) {
+Common::String AdlEngine::inputString(byte prompt) const {
 	Common::String s;
 
 	if (prompt > 0)
@@ -921,7 +951,7 @@ Common::String AdlEngine::inputString(byte prompt) {
 	}
 }
 
-byte AdlEngine::convertKey(uint16 ascii) {
+byte AdlEngine::convertKey(uint16 ascii) const {
 	ascii = toupper(ascii);
 
 	if (ascii >= 0x80)
@@ -935,7 +965,7 @@ byte AdlEngine::convertKey(uint16 ascii) {
 	return 0;
 }
 
-byte AdlEngine::inputKey() {
+byte AdlEngine::inputKey() const {
 	Common::EventManager *ev = g_system->getEventManager();
 
 	byte key = 0;
@@ -974,7 +1004,7 @@ byte AdlEngine::inputKey() {
 	return key;
 }
 
-void AdlEngine::delay(uint32 ms) {
+void AdlEngine::delay(uint32 ms) const {
 	Common::EventManager *ev = g_system->getEventManager();
 
 	uint32 start = g_system->getMillis();
@@ -996,10 +1026,9 @@ void AdlEngine::delay(uint32 ms) {
 	}
 }
 
-void AdlEngine::drawNextPixel(Common::Point &p, byte color, byte bits, byte quadrant) {
-	if (bits & 4) {
+void AdlEngine::drawNextPixel(Common::Point &p, byte color, byte bits, byte quadrant) const {
+	if (bits & 4)
 		_display->putPixel(p, color);
-	}
 
 	bits += quadrant;
 
@@ -1009,7 +1038,7 @@ void AdlEngine::drawNextPixel(Common::Point &p, byte color, byte bits, byte quad
 		p.y += (bits & 2 ? 1 : -1);
 }
 
-void AdlEngine::drawLineArt(const Common::Array<byte> &lineArt, Common::Point p, byte rotation, byte scaling, byte color) {
+void AdlEngine::drawLineArt(const Common::Array<byte> &lineArt, Common::Point p, 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,
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 66a5395..5afcb0f 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -161,71 +161,30 @@ struct State {
 };
 
 typedef Common::List<Command> Commands;
+typedef Common::HashMap<Common::String, uint> WordMap;
 
 class AdlEngine : public Engine {
 public:
-	AdlEngine(OSystem *syst, const AdlGameDescription *gd);
 	virtual ~AdlEngine();
 
-	const AdlGameDescription *_gameDescription;
-	bool hasFeature(EngineFeature f) const;
-	const char *getGameId() const;
-
 	static AdlEngine *create(GameType type, OSystem *syst, const AdlGameDescription *gd);
 
-	Common::Error run();
-	virtual Common::String getEngineString(int str);
-
 protected:
-	typedef Common::HashMap<Common::String, uint> WordMap;
+	AdlEngine(OSystem *syst, const AdlGameDescription *gd);
 
-	virtual void runIntro() { }
-	virtual void loadData() = 0;
-	void runGame();
-	virtual void initState() = 0;
-	virtual void restartGame() = 0;
-	virtual uint getEngineMessage(EngineMessage msg) = 0;
-	bool canSaveGameStateCurrently();
-	bool canLoadGameStateCurrently();
-	Common::String readString(Common::ReadStream &stream, byte until = 0);
-	void printStrings(Common::SeekableReadStream &stream, int count = 1);
-	virtual void printMessage(uint idx, bool wait = true);
-	void wordWrap(Common::String &str);
-	void readCommands(Common::ReadStream &stream, Commands &commands);
-	bool matchCommand(const Command &command, byte verb, byte noun, bool run = true);
-	bool doOneCommand(const Commands &commands, byte verb, byte noun);
-	void doAllCommands(const Commands &commands, byte verb, byte noun);
-	void doActions(const Command &command, byte noun, byte offset);
-	void clearScreen();
-	virtual void drawPic(byte pic, Common::Point pos = Common::Point()) = 0;
-	void drawItems();
-	void drawNextPixel(Common::Point &p, byte color, byte bits, byte quadrant);
-	void drawLineArt(const Common::Array<byte> &lineArt, Common::Point p, byte rotation = 0, byte scaling = 1, byte color = 0x7f);
-	void showRoom();
-	void takeItem(byte noun);
-	void dropItem(byte noun);
-	Room &room(uint i);
-	Room &curRoom();
-	Item &item(uint i);
-	byte &var(uint i);
+	Common::String readString(Common::ReadStream &stream, byte until = 0) const;
+	void printStrings(Common::SeekableReadStream &stream, int count = 1) const;
+	void printMessage(uint idx, bool wait = true) const;
+	void printASCIIString(const Common::String &str) const;
 	void loadVerbs(Common::ReadStream &stream) { loadWords(stream, _verbs); }
 	void loadNouns(Common::ReadStream &stream) { loadWords(stream, _nouns); }
-	void getInput(uint &verb, uint &noun);
-	void loadWords(Common::ReadStream &stream, WordMap &map);
-	Common::String getLine();
-	Common::String getWord(const Common::String &line, uint &index);
-	void printASCIIString(const Common::String &str);
-	Common::String inputString(byte prompt = 0);
-	void delay(uint32 ms);
-	byte inputKey();
-	Common::Error loadGameState(int slot);
-	Common::Error saveGameState(int slot, const Common::String &desc);
+	void readCommands(Common::ReadStream &stream, Commands &commands);
+	Common::String inputString(byte prompt = 0) const;
+	void delay(uint32 ms) const;
+	byte inputKey() const;
 
 	Display *_display;
 	Parser *_parser;
-	bool _isRestarting, _isRestoring;
-	byte _saveVerb, _saveNoun, _restoreVerb, _restoreNoun;
-	bool _canSaveNow, _canRestoreNow;
 
 	Common::Array<Common::String> _strings;
 	Common::Array<Common::String> _messages;
@@ -239,14 +198,64 @@ protected:
 	State _state;
 
 private:
-	void printEngineMessage(EngineMessage);
-	Common::String getTargetName() { return _targetName; }
-	byte convertKey(uint16 ascii);
+	virtual void runIntro() { }
+	virtual void loadData() = 0;
+	virtual void initState() = 0;
+	virtual void restartGame() = 0;
+	virtual uint getEngineMessage(EngineMessage msg) const = 0;
+	virtual void drawPic(byte pic, Common::Point pos = Common::Point()) const = 0;
+
+	// Engine
+	Common::Error run();
+	bool hasFeature(EngineFeature f) const;
+	Common::Error loadGameState(int slot);
+	bool canLoadGameStateCurrently() const;
+	Common::Error saveGameState(int slot, const Common::String &desc);
+	bool canSaveGameStateCurrently() const;
+
+	// Text output
+	Common::String getEngineString(int str) const;
+	void printEngineMessage(EngineMessage) const;
+	void wordWrap(Common::String &str) const;
+
+	// Text input
+	void loadWords(Common::ReadStream &stream, WordMap &map);
+	byte convertKey(uint16 ascii) const;
+	Common::String getLine() const;
+	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, Common::Point p, byte rotation = 0, byte scaling = 1, byte color = 0x7f) const;
+
+	// Game state functions
+	const Room &room(uint i) const;
+	Room &room(uint i);
+	const Room &curRoom() const;
+	Room &curRoom();
+	const Item &item(uint i) const;
+	Item &item(uint i);
+	const byte &var(uint i) const;
+	byte &var(uint i);
+	void takeItem(byte noun);
+	void dropItem(byte noun);
+	bool matchCommand(const Command &command, byte verb, byte noun, uint *actions = nullptr) const;
+	bool doOneCommand(const Commands &commands, byte verb, byte noun);
+	void doAllCommands(const Commands &commands, byte verb, byte noun);
+	void doActions(const Command &command, byte noun, byte offset);
 
 	enum {
 		kWordSize = 8
 	};
 
+	const AdlGameDescription *_gameDescription;
+	bool _isRestarting, _isRestoring;
+	byte _saveVerb, _saveNoun, _restoreVerb, _restoreNoun;
+	bool _canSaveNow, _canRestoreNow;
 	WordMap _verbs;
 	WordMap _nouns;
 };
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 11d576b..c7b62c1 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -205,7 +205,7 @@ void HiRes1Engine::runIntro() {
 	delay(2000);
 }
 
-void HiRes1Engine::drawPic(Common::ReadStream &stream, const Common::Point &pos) {
+void HiRes1Engine::drawPic(Common::ReadStream &stream, const Common::Point &pos) const {
 	byte x, y;
 	bool bNewLine = false;
 	byte oldX = 0, oldY = 0;
@@ -242,7 +242,7 @@ void HiRes1Engine::drawPic(Common::ReadStream &stream, const Common::Point &pos)
 	}
 }
 
-void HiRes1Engine::drawPic(byte pic, Common::Point pos) {
+void HiRes1Engine::drawPic(byte pic, Common::Point pos) const {
 	Common::File f;
 	Common::String name = Common::String::format("BLOCK%i", _pictures[pic].block);
 
@@ -406,7 +406,7 @@ void HiRes1Engine::printMessage(uint idx, bool wait) {
 	AdlEngine::printMessage(idx, wait);
 }
 
-uint HiRes1Engine::getEngineMessage(EngineMessage msg) {
+uint HiRes1Engine::getEngineMessage(EngineMessage msg) const {
 	switch (msg) {
 	case IDI_MSG_CANT_GO_THERE:
 		return IDI_HR1_MSG_CANT_GO_THERE;
@@ -423,7 +423,7 @@ uint HiRes1Engine::getEngineMessage(EngineMessage msg) {
 	}
 }
 
-void HiRes1Engine::drawLine(const Common::Point &p1, const Common::Point &p2, byte color) {
+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;
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index f72093a..7446e10 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -39,15 +39,15 @@ public:
 private:
 	void restartGame();
 	void printMessage(uint idx, bool wait = true);
-	uint getEngineMessage(EngineMessage msg);
+	uint getEngineMessage(EngineMessage msg) const;
 
 	void initState();
 	void runIntro();
 	void loadData();
-	void drawPic(Common::ReadStream &stream, const Common::Point &pos);
+	void drawPic(Common::ReadStream &stream, const Common::Point &pos) const;
 	void drawItems();
-	void drawLine(const Common::Point &p1, const Common::Point &p2, byte color);
-	void drawPic(byte pic, Common::Point pos);
+	void drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const;
+	void drawPic(byte pic, Common::Point pos) const;
 };
 
 } // End of namespace Adl


Commit: 58e7c539096f6b37c40dd0afa13c7ed500037be8
    https://github.com/scummvm/scummvm/commit/58e7c539096f6b37c40dd0afa13c7ed500037be8
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Clean up AdlEngine class

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 e0c0b3a..442edb7 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -777,18 +777,18 @@ byte &AdlEngine::var(uint i) {
 	return _state.vars[i];
 }
 
-void AdlEngine::loadWords(Common::ReadStream &stream, WordMap &map) {
+void AdlEngine::loadWords(Common::ReadStream &stream, WordMap &map) const {
 	uint index = 0;
 
 	while (1) {
 		++index;
 
-		byte buf[kWordSize];
+		byte buf[IDI_WORD_SIZE];
 
-		if (stream.read(buf, kWordSize) < kWordSize)
+		if (stream.read(buf, IDI_WORD_SIZE) < IDI_WORD_SIZE)
 			error("Error reading word list");
 
-		Common::String word((char *)buf, kWordSize);
+		Common::String word((char *)buf, IDI_WORD_SIZE);
 
 		if (!map.contains(word))
 			map[word] = index;
@@ -802,10 +802,10 @@ void AdlEngine::loadWords(Common::ReadStream &stream, WordMap &map) {
 			break;
 
 		for (uint i = 0; i < synonyms; ++i) {
-			if (stream.read((char *)buf, kWordSize) < kWordSize)
+			if (stream.read((char *)buf, IDI_WORD_SIZE) < IDI_WORD_SIZE)
 				error("Error reading word list");
 
-			word = Common::String((char *)buf, kWordSize);
+			word = Common::String((char *)buf, IDI_WORD_SIZE);
 
 			if (!map.contains(word))
 				map[word] = index;
@@ -1038,7 +1038,7 @@ void AdlEngine::drawNextPixel(Common::Point &p, byte color, byte bits, byte quad
 		p.y += (bits & 2 ? 1 : -1);
 }
 
-void AdlEngine::drawLineArt(const Common::Array<byte> &lineArt, Common::Point p, byte rotation, byte scaling, byte color) const {
+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,
@@ -1050,6 +1050,8 @@ void AdlEngine::drawLineArt(const Common::Array<byte> &lineArt, Common::Point p,
 	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];
 
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 5afcb0f..6d5ab42 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -28,8 +28,6 @@
 
 #include "engines/engine.h"
 
-#include "gui/debugger.h"
-
 namespace Common {
 class ReadStream;
 class SeekableReadStream;
@@ -110,6 +108,8 @@ enum EngineString {
 #define IDO_ACT_DROP_ITEM      0x1c
 #define IDO_ACT_SET_ROOM_PIC   0x1d
 
+#define IDI_WORD_SIZE 8
+
 struct Room {
 	byte description;
 	byte connections[6];
@@ -176,24 +176,33 @@ protected:
 	void printStrings(Common::SeekableReadStream &stream, int count = 1) const;
 	void printMessage(uint idx, bool wait = true) const;
 	void printASCIIString(const Common::String &str) const;
-	void loadVerbs(Common::ReadStream &stream) { loadWords(stream, _verbs); }
-	void loadNouns(Common::ReadStream &stream) { loadWords(stream, _nouns); }
 	void readCommands(Common::ReadStream &stream, Commands &commands);
 	Common::String inputString(byte prompt = 0) const;
 	void delay(uint32 ms) const;
 	byte inputKey() const;
+	void loadWords(Common::ReadStream &stream, WordMap &map) const;
 
 	Display *_display;
 	Parser *_parser;
 
+	// Strings inside executable
 	Common::Array<Common::String> _strings;
+	// Message strings in data file
 	Common::Array<Common::String> _messages;
+	// Picture data
 	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;
 
+	WordMap _verbs;
+	WordMap _nouns;
+
 	// Game state
 	State _state;
 
@@ -219,7 +228,6 @@ private:
 	void wordWrap(Common::String &str) const;
 
 	// Text input
-	void loadWords(Common::ReadStream &stream, WordMap &map);
 	byte convertKey(uint16 ascii) const;
 	Common::String getLine() const;
 	Common::String getWord(const Common::String &line, uint &index) const;
@@ -230,7 +238,7 @@ private:
 	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, Common::Point p, byte rotation = 0, byte scaling = 1, byte color = 0x7f) 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 &room(uint i) const;
@@ -248,16 +256,10 @@ private:
 	void doAllCommands(const Commands &commands, byte verb, byte noun);
 	void doActions(const Command &command, byte noun, byte offset);
 
-	enum {
-		kWordSize = 8
-	};
-
 	const AdlGameDescription *_gameDescription;
 	bool _isRestarting, _isRestoring;
 	byte _saveVerb, _saveNoun, _restoreVerb, _restoreNoun;
 	bool _canSaveNow, _canRestoreNow;
-	WordMap _verbs;
-	WordMap _nouns;
 };
 
 AdlEngine *HiRes1Engine__create(OSystem *syst, const AdlGameDescription *gd);
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index c7b62c1..314434d 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -379,10 +379,10 @@ void HiRes1Engine::loadData() {
 		error("Failed to read game data from '" IDS_HR1_EXE_1 "'");
 
 	f.seek(IDI_HR1_OFS_VERBS);
-	loadVerbs(f);
+	loadWords(f, _verbs);
 
 	f.seek(IDI_HR1_OFS_NOUNS);
-	loadNouns(f);
+	loadWords(f, _nouns);
 }
 
 void HiRes1Engine::printMessage(uint idx, bool wait) {


Commit: 07d0997befe416c56e38b831031b81a30e63925a
    https://github.com/scummvm/scummvm/commit/07d0997befe416c56e38b831031b81a30e63925a
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Clean up AdlMetaEngine

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



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 442edb7..8884015 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -37,6 +37,7 @@
 
 #include "adl/adl.h"
 #include "adl/display.h"
+#include "adl/detection.h"
 
 namespace Adl {
 
@@ -1071,13 +1072,4 @@ void AdlEngine::drawLineArt(const Common::Array<byte> &lineArt, const Common::Po
 	}
 }
 
-AdlEngine *AdlEngine::create(GameType type, OSystem *syst, const AdlGameDescription *gd) {
-	switch(type) {
-	case kGameTypeHires1:
-		return HiRes1Engine__create(syst, gd);
-	default:
-		error("Unknown GameType");
-	}
-}
-
 } // End of namespace Adl
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 6d5ab42..6f9b24d 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -34,20 +34,11 @@ class SeekableReadStream;
 }
 
 namespace Adl {
-
-#define SAVEGAME_VERSION 0
-#define SAVEGAME_NAME_LEN 32
-
 class Display;
 class Parser;
 class Console;
 struct AdlGameDescription;
 
-enum GameType {
-	kGameTypeNone = 0,
-	kGameTypeHires1
-};
-
 struct StringOffset {
 	int stringIdx;
 	uint offset;
@@ -167,8 +158,6 @@ class AdlEngine : public Engine {
 public:
 	virtual ~AdlEngine();
 
-	static AdlEngine *create(GameType type, OSystem *syst, const AdlGameDescription *gd);
-
 protected:
 	AdlEngine(OSystem *syst, const AdlGameDescription *gd);
 
diff --git a/engines/adl/detection.cpp b/engines/adl/detection.cpp
index e556e12..d96d94c 100644
--- a/engines/adl/detection.cpp
+++ b/engines/adl/detection.cpp
@@ -28,7 +28,7 @@
 
 #include "engines/advancedDetector.h"
 
-#include "adl/adl.h"
+#include "adl/detection.h"
 
 namespace Adl {
 
@@ -59,18 +59,12 @@ static const ADExtraGuiOptionsMap optionsList[] = {
 	AD_EXTRA_GUI_OPTIONS_TERMINATOR
 };
 
-struct AdlGameDescription {
-	ADGameDescription desc;
-	GameType gameType;
-};
-
 static const PlainGameDescriptor adlGames[] = {
 	{"hires1", "Hi-Res Adventure #1: Mystery House"},
 	{0, 0}
 };
 
 static const AdlGameDescription gameDescriptions[] = {
-
 	{ // MD5 by waltervn
 		{
 			"hires1", 0,
@@ -85,9 +79,9 @@ static const AdlGameDescription gameDescriptions[] = {
 			ADGF_NO_FLAGS,
 			GUIO2(GAMEOPTION_COLOR, GAMEOPTION_SCANLINES)
 		},
-		kGameTypeHires1
+		GAME_TYPE_HIRES1
 	},
-	{AD_TABLE_END_MARKER, kGameTypeNone}
+	{ AD_TABLE_END_MARKER, GAME_TYPE_NONE }
 };
 
 class AdlMetaEngine : public AdvancedMetaEngine {
@@ -189,7 +183,7 @@ SaveStateList AdlMetaEngine::listSaves(const char *target) const {
 		const Common::String &fileName = files[i];
 		Common::InSaveFile *inFile = saveFileMan->openForLoading(fileName);
 		if (!inFile) {
-			warning("Cannot open save file %s", fileName.c_str());
+			warning("Cannot open save file '%s'", fileName.c_str());
 			continue;
 		}
 
@@ -201,7 +195,7 @@ SaveStateList AdlMetaEngine::listSaves(const char *target) const {
 
 		byte saveVersion = inFile->readByte();
 		if (saveVersion != SAVEGAME_VERSION) {
-			warning("Save game version %i not supported in '%s'", saveVersion, fileName.c_str());
+			warning("Unsupported save game version %i found in '%s'", saveVersion, fileName.c_str());
 			delete inFile;
 			continue;
 		}
@@ -225,10 +219,23 @@ void AdlMetaEngine::removeSaveState(const char *target, int slot) const {
 	g_system->getSavefileManager()->removeSavefile(fileName);
 }
 
+Engine *HiRes1Engine_create(OSystem *syst, const AdlGameDescription *gd);
+
 bool AdlMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const {
-	if (gd)
-		*engine = AdlEngine::create(((const AdlGameDescription *)gd)->gameType, syst, (const AdlGameDescription *)gd);
-	return gd != nullptr;
+	if (!gd)
+		return false;
+
+	const AdlGameDescription *adlGd = (const AdlGameDescription *)gd;
+
+	switch (adlGd->gameType) {
+	case GAME_TYPE_HIRES1:
+		*engine = HiRes1Engine_create(syst, adlGd);
+		break;
+	default:
+		error("Unknown GameType");
+	}
+
+	return true;
 }
 
 } // End of namespace Adl
diff --git a/engines/adl/detection.h b/engines/adl/detection.h
new file mode 100644
index 0000000..c646aeb
--- /dev/null
+++ b/engines/adl/detection.h
@@ -0,0 +1,45 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ADL_DETECTION_H
+#define ADL_DETECTION_H
+
+#include "engines/advancedDetector.h"
+
+namespace Adl {
+
+#define SAVEGAME_VERSION 0
+#define SAVEGAME_NAME_LEN 32
+
+enum GameType {
+	GAME_TYPE_NONE,
+	GAME_TYPE_HIRES1
+};
+
+struct AdlGameDescription {
+	ADGameDescription desc;
+	GameType gameType;
+};
+
+} // End of namespace Adl
+
+#endif
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 314434d..ad02308 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -98,10 +98,6 @@ static const StringOffset stringOffsets[] = {
 #define IDI_HR1_OFS_VERBS        0x3800
 #define IDI_HR1_OFS_NOUNS        0x0f00
 
-HiRes1Engine::HiRes1Engine(OSystem *syst, const AdlGameDescription *gd) :
-		AdlEngine(syst, gd) {
-}
-
 void HiRes1Engine::runIntro() {
 	Common::File file;
 
@@ -462,7 +458,7 @@ void HiRes1Engine::drawLine(const Common::Point &p1, const Common::Point &p2, by
 	}
 }
 
-AdlEngine *HiRes1Engine__create(OSystem *syst, const AdlGameDescription *gd) {
+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 7446e10..540e613 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -34,7 +34,7 @@ namespace Adl {
 
 class HiRes1Engine : public AdlEngine {
 public:
-	HiRes1Engine(OSystem *syst, const AdlGameDescription *gd);
+	HiRes1Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine(syst, gd) { }
 
 private:
 	void restartGame();


Commit: ac79cb081c2e7a137f2196b14e1fb2b7b4099c7f
    https://github.com/scummvm/scummvm/commit/ac79cb081c2e7a137f2196b14e1fb2b7b4099c7f
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Move #defines into header file

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



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 8884015..af379c0 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -156,18 +156,6 @@ Common::String AdlEngine::readString(Common::ReadStream &stream, byte until) con
 	return str;
 }
 
-void AdlEngine::printStrings(Common::SeekableReadStream &stream, int count) const {
-	while (1) {
-		Common::String str = readString(stream);
-		_display->printString(str);
-
-		if (--count == 0)
-			break;
-
-		stream.seek(3, SEEK_CUR);
-	};
-}
-
 Common::String AdlEngine::getEngineString(int str) const {
 	return _strings[str];
 }
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 6f9b24d..591b918 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -162,14 +162,16 @@ protected:
 	AdlEngine(OSystem *syst, const AdlGameDescription *gd);
 
 	Common::String readString(Common::ReadStream &stream, byte until = 0) const;
-	void printStrings(Common::SeekableReadStream &stream, int count = 1) const;
-	void printMessage(uint idx, bool wait = true) const;
+
+	virtual void printMessage(uint idx, bool wait = true) const;
 	void printASCIIString(const Common::String &str) const;
-	void readCommands(Common::ReadStream &stream, Commands &commands);
-	Common::String inputString(byte prompt = 0) const;
 	void delay(uint32 ms) const;
+
+	Common::String inputString(byte prompt = 0) const;
 	byte inputKey() const;
+
 	void loadWords(Common::ReadStream &stream, WordMap &map) const;
+	void readCommands(Common::ReadStream &stream, Commands &commands);
 
 	Display *_display;
 	Parser *_parser;
@@ -196,7 +198,7 @@ protected:
 	State _state;
 
 private:
-	virtual void runIntro() { }
+	virtual void runIntro() const { }
 	virtual void loadData() = 0;
 	virtual void initState() = 0;
 	virtual void restartGame() = 0;
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index ad02308..754ee30 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -31,37 +31,6 @@
 
 namespace Adl {
 
-#define IDS_HR1_EXE_0    "AUTO LOAD OBJ"
-#define IDS_HR1_EXE_1    "ADVENTURE"
-#define IDS_HR1_LOADER   "MYSTERY.HELLO"
-#define IDS_HR1_MESSAGES "MESSAGES"
-
-#define IDI_HR1_NUM_ROOMS         41
-#define IDI_HR1_NUM_PICS          98
-#define IDI_HR1_NUM_VARS          20
-#define IDI_HR1_NUM_ITEM_OFFSETS  21
-#define IDI_HR1_NUM_MESSAGES     167
-
-// Messages used outside of scripts
-#define IDI_HR1_MSG_CANT_GO_THERE      137
-#define IDI_HR1_MSG_DONT_UNDERSTAND     37
-#define IDI_HR1_MSG_ITEM_DOESNT_MOVE   151
-#define IDI_HR1_MSG_ITEM_NOT_HERE      152
-#define IDI_HR1_MSG_THANKS_FOR_PLAYING 140
-#define IDI_HR1_MSG_DONT_HAVE_IT       127
-#define IDI_HR1_MSG_GETTING_DARK         7
-
-// Strings embedded in the executable
-enum {
-	IDI_HR1_STR_CANT_GO_THERE = IDI_STR_TOTAL,
-	IDI_HR1_STR_DONT_HAVE_IT,
-	IDI_HR1_STR_DONT_UNDERSTAND,
-	IDI_HR1_STR_GETTING_DARK,
-	IDI_HR1_STR_PRESS_RETURN,
-
-	IDI_HR1_STR_TOTAL
-};
-
 // Offsets for strings inside executable
 static const StringOffset stringOffsets[] = {
 	{ IDI_STR_ENTER_COMMAND,       0x5bbc },
@@ -75,30 +44,7 @@ static const StringOffset stringOffsets[] = {
 	{ IDI_HR1_STR_PRESS_RETURN,    0x5f68 }
 };
 
-#define IDI_HR1_OFS_PD_TEXT_0    0x005d
-#define IDI_HR1_OFS_PD_TEXT_1    0x012b
-#define IDI_HR1_OFS_PD_TEXT_2    0x016d
-#define IDI_HR1_OFS_PD_TEXT_3    0x0259
-
-#define IDI_HR1_OFS_INTRO_TEXT   0x0066
-#define IDI_HR1_OFS_GAME_OR_HELP 0x000f
-
-#define IDI_HR1_OFS_LOGO_0       0x1003
-#define IDI_HR1_OFS_LOGO_1       0x1800
-
-#define IDI_HR1_OFS_ITEMS        0x0100
-#define IDI_HR1_OFS_ROOMS        0x050a
-#define IDI_HR1_OFS_PICS         0x4b00
-#define IDI_HR1_OFS_CMDS_0       0x3c00
-#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_VERBS        0x3800
-#define IDI_HR1_OFS_NOUNS        0x0f00
-
-void HiRes1Engine::runIntro() {
+void HiRes1Engine::runIntro() const {
 	Common::File file;
 
 	if (!file.open(IDS_HR1_EXE_0))
@@ -175,13 +121,20 @@ void HiRes1Engine::runIntro() {
 		uint page = 0;
 		while (pages[page] != 0) {
 			_display->home();
-			printStrings(file, pages[page++]);
+
+			uint count = pages[page++];
+			for (uint i = 0; i < count; ++i) {
+				str = readString(file);
+				_display->printString(str);
+				file.seek(3, SEEK_CUR);
+			}
+
 			inputString();
 
 			if (g_engine->shouldQuit())
 				return;
 
-			file.seek(9, SEEK_CUR);
+			file.seek(6, SEEK_CUR);
 		}
 	}
 
@@ -381,7 +334,7 @@ void HiRes1Engine::loadData() {
 	loadWords(f, _nouns);
 }
 
-void HiRes1Engine::printMessage(uint idx, bool wait) {
+void HiRes1Engine::printMessage(uint idx, bool wait) const {
 	// Hardcoded overrides that don't wait after printing
 	// Note: strings may differ slightly from the ones in MESSAGES
 	switch (idx) {
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index 540e613..a19e9c0 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -32,22 +32,76 @@ class Point;
 
 namespace Adl {
 
+#define IDS_HR1_EXE_0    "AUTO LOAD OBJ"
+#define IDS_HR1_EXE_1    "ADVENTURE"
+#define IDS_HR1_LOADER   "MYSTERY.HELLO"
+#define IDS_HR1_MESSAGES "MESSAGES"
+
+#define IDI_HR1_NUM_ROOMS         41
+#define IDI_HR1_NUM_PICS          98
+#define IDI_HR1_NUM_VARS          20
+#define IDI_HR1_NUM_ITEM_OFFSETS  21
+#define IDI_HR1_NUM_MESSAGES     167
+
+// Messages used outside of scripts
+#define IDI_HR1_MSG_CANT_GO_THERE      137
+#define IDI_HR1_MSG_DONT_UNDERSTAND     37
+#define IDI_HR1_MSG_ITEM_DOESNT_MOVE   151
+#define IDI_HR1_MSG_ITEM_NOT_HERE      152
+#define IDI_HR1_MSG_THANKS_FOR_PLAYING 140
+#define IDI_HR1_MSG_DONT_HAVE_IT       127
+#define IDI_HR1_MSG_GETTING_DARK         7
+
+// Strings embedded in the executable
+enum {
+	IDI_HR1_STR_CANT_GO_THERE = IDI_STR_TOTAL,
+	IDI_HR1_STR_DONT_HAVE_IT,
+	IDI_HR1_STR_DONT_UNDERSTAND,
+	IDI_HR1_STR_GETTING_DARK,
+	IDI_HR1_STR_PRESS_RETURN,
+
+	IDI_HR1_STR_TOTAL
+};
+
+#define IDI_HR1_OFS_PD_TEXT_0    0x005d
+#define IDI_HR1_OFS_PD_TEXT_1    0x012b
+#define IDI_HR1_OFS_PD_TEXT_2    0x016d
+#define IDI_HR1_OFS_PD_TEXT_3    0x0259
+
+#define IDI_HR1_OFS_INTRO_TEXT   0x0066
+#define IDI_HR1_OFS_GAME_OR_HELP 0x000f
+
+#define IDI_HR1_OFS_LOGO_0       0x1003
+#define IDI_HR1_OFS_LOGO_1       0x1800
+
+#define IDI_HR1_OFS_ITEMS        0x0100
+#define IDI_HR1_OFS_ROOMS        0x050a
+#define IDI_HR1_OFS_PICS         0x4b00
+#define IDI_HR1_OFS_CMDS_0       0x3c00
+#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_VERBS        0x3800
+#define IDI_HR1_OFS_NOUNS        0x0f00
+
 class HiRes1Engine : public AdlEngine {
 public:
 	HiRes1Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine(syst, gd) { }
 
 private:
+	// AdlEngine
+	void runIntro() const;
+	void loadData();
+	void initState();
 	void restartGame();
-	void printMessage(uint idx, bool wait = true);
 	uint getEngineMessage(EngineMessage msg) const;
+	void drawPic(byte pic, Common::Point pos) const;
+	void printMessage(uint idx, bool wait = true) const;
 
-	void initState();
-	void runIntro();
-	void loadData();
-	void drawPic(Common::ReadStream &stream, const Common::Point &pos) const;
-	void drawItems();
 	void drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const;
-	void drawPic(byte pic, Common::Point pos) const;
+	void drawPic(Common::ReadStream &stream, const Common::Point &pos) const;
 };
 
 } // End of namespace Adl


Commit: fd8a5f419f0855babb99f716e526fc20e50882d6
    https://github.com/scummvm/scummvm/commit/fd8a5f419f0855babb99f716e526fc20e50882d6
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Refactor string handling

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



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index af379c0..f466f80 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -109,7 +109,7 @@ Common::Error AdlEngine::run() {
 				break;
 
 			if (!doOneCommand(_roomCommands, verb, noun))
-				printEngineMessage(IDI_MSG_DONT_UNDERSTAND);
+				printMessage(_messageIds.dontUnderstand);
 		}
 
 		if (_isRestoring) {
@@ -156,8 +156,9 @@ Common::String AdlEngine::readString(Common::ReadStream &stream, byte until) con
 	return str;
 }
 
-Common::String AdlEngine::getEngineString(int str) const {
-	return _strings[str];
+Common::String AdlEngine::readStringAt(Common::SeekableReadStream &stream, uint offset, byte until) const {
+	stream.seek(offset);
+	return readString(stream, until);
 }
 
 void AdlEngine::wordWrap(Common::String &str) const {
@@ -184,10 +185,6 @@ void AdlEngine::printMessage(uint idx, bool wait) const {
 		delay(14 * 166018 / 1000);
 }
 
-void AdlEngine::printEngineMessage(EngineMessage msg) const {
-	printMessage(getEngineMessage(msg));
-}
-
 void AdlEngine::readCommands(Common::ReadStream &stream, Commands &commands) {
 	while (1) {
 		Command command;
@@ -232,7 +229,7 @@ void AdlEngine::takeItem(byte noun) {
 			continue;
 
 		if (item->state == IDI_ITEM_DOESNT_MOVE) {
-			printEngineMessage(IDI_MSG_ITEM_DOESNT_MOVE);
+			printMessage(_messageIds.itemDoesntMove);
 			return;
 		}
 
@@ -251,7 +248,7 @@ void AdlEngine::takeItem(byte noun) {
 		}
 	}
 
-	printEngineMessage(IDI_MSG_ITEM_NOT_HERE);
+	printMessage(_messageIds.itemNotHere);
 }
 
 void AdlEngine::dropItem(byte noun) {
@@ -266,7 +263,7 @@ void AdlEngine::dropItem(byte noun) {
 		return;
 	}
 
-	printEngineMessage(IDI_MSG_DONT_UNDERSTAND);
+	printMessage(_messageIds.dontUnderstand);
 }
 
 #define ARG(N) (command.script[offset + (N)])
@@ -339,7 +336,7 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			_isRestoring = false;
 			break;
 		case IDO_ACT_RESTART: {
-			_display->printString(_strings[IDI_STR_PLAY_AGAIN]);
+			_display->printString(_strings.playAgain);
 
 			// We allow restoring via GMM here
 			_canRestoreNow = true;
@@ -360,7 +357,7 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			// Fall-through
 		}
 		case IDO_ACT_QUIT:
-			printEngineMessage(IDI_MSG_THANKS_FOR_PLAYING);
+			printMessage(_messageIds.thanksForPlaying);
 			quitGame();
 			return;
 		case IDO_ACT_PLACE_ITEM:
@@ -386,7 +383,7 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			byte room = curRoom().connections[ARG(0) - IDO_ACT_GO_NORTH];
 
 			if (room == 0) {
-				printEngineMessage(IDI_MSG_CANT_GO_THERE);
+				printMessage(_messageIds.cantGoThere);
 				return;
 			}
 
@@ -856,7 +853,7 @@ Common::String AdlEngine::getWord(const Common::String &line, uint &index) const
 
 void AdlEngine::getInput(uint &verb, uint &noun) {
 	while (1) {
-		_display->printString(getEngineString(IDI_STR_ENTER_COMMAND));
+		_display->printString(_strings.enterCommand);
 		Common::String line = getLine();
 
 		if (shouldQuit() || _isRestoring)
@@ -866,7 +863,7 @@ void AdlEngine::getInput(uint &verb, uint &noun) {
 		Common::String verbStr = getWord(line, index);
 
 		if (!_verbs.contains(verbStr)) {
-			Common::String err = getEngineString(IDI_STR_VERB_ERROR);
+			Common::String err = _strings.verbError;
 			for (uint i = 0; i < verbStr.size(); ++i)
 				err.setChar(verbStr[i], i + 19);
 			_display->printString(err);
@@ -878,7 +875,7 @@ void AdlEngine::getInput(uint &verb, uint &noun) {
 		Common::String nounStr = getWord(line, index);
 
 		if (!_nouns.contains(nounStr)) {
-			Common::String err = getEngineString(IDI_STR_NOUN_ERROR);
+			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)
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 591b918..303f197 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -44,25 +44,6 @@ struct StringOffset {
 	uint offset;
 };
 
-// Messages used outside of scripts
-enum EngineMessage {
-	IDI_MSG_CANT_GO_THERE,
-	IDI_MSG_DONT_UNDERSTAND,
-	IDI_MSG_ITEM_DOESNT_MOVE,
-	IDI_MSG_ITEM_NOT_HERE,
-	IDI_MSG_THANKS_FOR_PLAYING
-};
-
-// Strings embedded in the executable
-enum EngineString {
-	IDI_STR_ENTER_COMMAND,
-	IDI_STR_VERB_ERROR,
-	IDI_STR_NOUN_ERROR,
-	IDI_STR_PLAY_AGAIN,
-
-	IDI_STR_TOTAL
-};
-
 // Conditional opcodes
 #define IDO_CND_ITEM_IN_ROOM   0x03
 #define IDO_CND_MOVES_GE       0x05
@@ -162,6 +143,7 @@ protected:
 	AdlEngine(OSystem *syst, const AdlGameDescription *gd);
 
 	Common::String readString(Common::ReadStream &stream, byte until = 0) const;
+	Common::String readStringAt(Common::SeekableReadStream &stream, uint offset, byte until = 0) const;
 
 	virtual void printMessage(uint idx, bool wait = true) const;
 	void printASCIIString(const Common::String &str) const;
@@ -176,8 +158,6 @@ protected:
 	Display *_display;
 	Parser *_parser;
 
-	// Strings inside executable
-	Common::Array<Common::String> _strings;
 	// Message strings in data file
 	Common::Array<Common::String> _messages;
 	// Picture data
@@ -194,6 +174,23 @@ protected:
 	WordMap _verbs;
 	WordMap _nouns;
 
+	struct {
+		Common::String enterCommand;
+		Common::String dontHaveIt;
+		Common::String gettingDark;
+		Common::String verbError;
+		Common::String nounError;
+		Common::String playAgain;
+	} _strings;
+
+	struct {
+		uint cantGoThere;
+		uint dontUnderstand;
+		uint itemDoesntMove;
+		uint itemNotHere;
+		uint thanksForPlaying;
+	} _messageIds;
+
 	// Game state
 	State _state;
 
@@ -202,7 +199,6 @@ private:
 	virtual void loadData() = 0;
 	virtual void initState() = 0;
 	virtual void restartGame() = 0;
-	virtual uint getEngineMessage(EngineMessage msg) const = 0;
 	virtual void drawPic(byte pic, Common::Point pos = Common::Point()) const = 0;
 
 	// Engine
@@ -214,8 +210,6 @@ private:
 	bool canSaveGameStateCurrently() const;
 
 	// Text output
-	Common::String getEngineString(int str) const;
-	void printEngineMessage(EngineMessage) const;
 	void wordWrap(Common::String &str) const;
 
 	// Text input
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 754ee30..80ea094 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -31,19 +31,6 @@
 
 namespace Adl {
 
-// Offsets for strings inside executable
-static const StringOffset stringOffsets[] = {
-	{ IDI_STR_ENTER_COMMAND,       0x5bbc },
-	{ IDI_STR_VERB_ERROR,          0x5b4f },
-	{ IDI_STR_NOUN_ERROR,          0x5b8e },
-	{ IDI_STR_PLAY_AGAIN,          0x5f1e },
-	{ IDI_HR1_STR_CANT_GO_THERE,   0x6c0a },
-	{ IDI_HR1_STR_DONT_HAVE_IT,    0x6c31 },
-	{ IDI_HR1_STR_DONT_UNDERSTAND, 0x6c51 },
-	{ IDI_HR1_STR_GETTING_DARK,    0x6c7c },
-	{ IDI_HR1_STR_PRESS_RETURN,    0x5f68 }
-};
-
 void HiRes1Engine::runIntro() const {
 	Common::File file;
 
@@ -67,20 +54,16 @@ void HiRes1Engine::runIntro() const {
 
 	Common::String str;
 
-	basic.seek(IDI_HR1_OFS_PD_TEXT_0);
-	str = readString(basic, '"');
+	str = readStringAt(basic, IDI_HR1_OFS_PD_TEXT_0, '"');
 	printASCIIString(str + '\r');
 
-	basic.seek(IDI_HR1_OFS_PD_TEXT_1);
-	str = readString(basic, '"');
+	str = readStringAt(basic, IDI_HR1_OFS_PD_TEXT_1, '"');
 	printASCIIString(str + "\r\r");
 
-	basic.seek(IDI_HR1_OFS_PD_TEXT_2);
-	str = readString(basic, '"');
+	str = readStringAt(basic, IDI_HR1_OFS_PD_TEXT_2, '"');
 	printASCIIString(str + "\r\r");
 
-	basic.seek(IDI_HR1_OFS_PD_TEXT_3);
-	str = readString(basic, '"');
+	str = readStringAt(basic, IDI_HR1_OFS_PD_TEXT_3, '"');
 	printASCIIString(str + '\r');
 
 	inputKey();
@@ -89,8 +72,7 @@ void HiRes1Engine::runIntro() const {
 
 	_display->setMode(DISPLAY_MODE_MIXED);
 
-	file.seek(IDI_HR1_OFS_GAME_OR_HELP);
-	str = readString(file);
+	str = readStringAt(file, IDI_HR1_OFS_GAME_OR_HELP);
 
 	bool instructions = false;
 
@@ -256,7 +238,7 @@ void HiRes1Engine::initState() {
 
 void HiRes1Engine::restartGame() {
 	initState();
-	_display->printString(_strings[IDI_HR1_STR_PRESS_RETURN]);
+	_display->printString(_gameStrings.pressReturn);
 	inputString(); // Missing in the original
 	printASCIIString("\r\r\r\r\r");
 }
@@ -275,12 +257,27 @@ void HiRes1Engine::loadData() {
 	if (!f.open(IDS_HR1_EXE_1))
 		error("Failed to open file '" IDS_HR1_EXE_1 "'");
 
-	// Load strings from executable
-	_strings.resize(IDI_HR1_STR_TOTAL);
-	for (uint idx = 0; idx < IDI_HR1_STR_TOTAL; ++idx) {
-		f.seek(stringOffsets[idx].offset);
-		_strings[stringOffsets[idx].stringIdx] = readString(f);
-	}
+	// 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);
+
+	// 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);
+
+	// Set message IDs
+	_messageIds.cantGoThere = IDI_HR1_MSG_CANT_GO_THERE;
+	_messageIds.dontUnderstand = IDI_HR1_MSG_DONT_UNDERSTAND;
+	_messageIds.itemDoesntMove = IDI_HR1_MSG_ITEM_DOESNT_MOVE;
+	_messageIds.itemNotHere = IDI_HR1_MSG_ITEM_NOT_HERE;
+	_messageIds.thanksForPlaying = IDI_HR1_MSG_THANKS_FOR_PLAYING;
 
 	// Load picture data from executable
 	f.seek(IDI_HR1_OFS_PICS);
@@ -335,43 +332,24 @@ void HiRes1Engine::loadData() {
 }
 
 void HiRes1Engine::printMessage(uint idx, bool wait) const {
-	// Hardcoded overrides that don't wait after printing
-	// Note: strings may differ slightly from the ones in MESSAGES
+	// 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
+	// before the user gets a chance to read them.
+	// NOTE: later games seem to wait for a key when the text window
+	// overflows and don't use delays. It might be better to use
+	// that system for this game as well.
 	switch (idx) {
 	case IDI_HR1_MSG_CANT_GO_THERE:
-		_display->printString(_strings[IDI_HR1_STR_CANT_GO_THERE]);
-		return;
 	case IDI_HR1_MSG_DONT_HAVE_IT:
-		_display->printString(_strings[IDI_HR1_STR_DONT_HAVE_IT]);
-		return;
 	case IDI_HR1_MSG_DONT_UNDERSTAND:
-		_display->printString(_strings[IDI_HR1_STR_DONT_UNDERSTAND]);
-		return;
 	case IDI_HR1_MSG_GETTING_DARK:
-		_display->printString(_strings[IDI_HR1_STR_GETTING_DARK]);
-		return;
+		wait = false;
 	}
 
 	AdlEngine::printMessage(idx, wait);
 }
 
-uint HiRes1Engine::getEngineMessage(EngineMessage msg) const {
-	switch (msg) {
-	case IDI_MSG_CANT_GO_THERE:
-		return IDI_HR1_MSG_CANT_GO_THERE;
-	case IDI_MSG_DONT_UNDERSTAND:
-		return IDI_HR1_MSG_DONT_UNDERSTAND;
-	case IDI_MSG_ITEM_DOESNT_MOVE:
-		return IDI_HR1_MSG_ITEM_DOESNT_MOVE;
-	case IDI_MSG_ITEM_NOT_HERE:
-		return IDI_HR1_MSG_ITEM_NOT_HERE;
-	case IDI_MSG_THANKS_FOR_PLAYING:
-		return IDI_HR1_MSG_THANKS_FOR_PLAYING;
-	default:
-		error("Cannot find engine message %i", msg);
-	}
-}
-
 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 a19e9c0..b7c7f41 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -52,16 +52,15 @@ namespace Adl {
 #define IDI_HR1_MSG_DONT_HAVE_IT       127
 #define IDI_HR1_MSG_GETTING_DARK         7
 
-// Strings embedded in the executable
-enum {
-	IDI_HR1_STR_CANT_GO_THERE = IDI_STR_TOTAL,
-	IDI_HR1_STR_DONT_HAVE_IT,
-	IDI_HR1_STR_DONT_UNDERSTAND,
-	IDI_HR1_STR_GETTING_DARK,
-	IDI_HR1_STR_PRESS_RETURN,
-
-	IDI_HR1_STR_TOTAL
-};
+#define IDI_HR1_OFS_STR_ENTER_COMMAND   0x5bbc
+#define IDI_HR1_OFS_STR_VERB_ERROR      0x5b4f
+#define IDI_HR1_OFS_STR_NOUN_ERROR      0x5b8e
+#define IDI_HR1_OFS_STR_PLAY_AGAIN      0x5f1e
+#define IDI_HR1_OFS_STR_CANT_GO_THERE   0x6c0a
+#define IDI_HR1_OFS_STR_DONT_HAVE_IT    0x6c31
+#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_PD_TEXT_0    0x005d
 #define IDI_HR1_OFS_PD_TEXT_1    0x012b
@@ -96,12 +95,15 @@ private:
 	void loadData();
 	void initState();
 	void restartGame();
-	uint getEngineMessage(EngineMessage msg) const;
 	void drawPic(byte pic, Common::Point pos) const;
 	void printMessage(uint idx, bool wait = true) const;
 
 	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;
 };
 
 } // End of namespace Adl


Commit: 86d58534e7138c7b58995e1f730c8531ca2d4273
    https://github.com/scummvm/scummvm/commit/86d58534e7138c7b58995e1f730c8531ca2d4273
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Move ASCII print function into Display class

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



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index f466f80..5b43a6c 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -87,7 +87,7 @@ Common::Error AdlEngine::run() {
 	}
 
 	_display->setMode(DISPLAY_MODE_MIXED);
-	printASCIIString("\r\r\r\r\r");
+	_display->printAsciiString("\r\r\r\r\r");
 
 	while (1) {
 		uint verb = 0, noun = 0;
@@ -119,7 +119,7 @@ Common::Error AdlEngine::run() {
 			// means that restoring a game will always run through
 			// the global commands and increase the move counter
 			// before the first user input.
-			printASCIIString("\r");
+			_display->printAsciiString("\r");
 			_isRestoring = false;
 			verb = _restoreVerb;
 			noun = _restoreNoun;
@@ -889,16 +889,6 @@ void AdlEngine::getInput(uint &verb, uint &noun) {
 	}
 }
 
-void AdlEngine::printASCIIString(const Common::String &str) const {
-	Common::String aStr;
-
-	Common::String::const_iterator it;
-	for (it = str.begin(); it != str.end(); ++it)
-			aStr += APPLECHAR(*it);
-
-	_display->printString(aStr);
-}
-
 Common::String AdlEngine::inputString(byte prompt) const {
 	Common::String s;
 
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 303f197..b1d5b7c 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -146,7 +146,6 @@ protected:
 	Common::String readStringAt(Common::SeekableReadStream &stream, uint offset, byte until = 0) const;
 
 	virtual void printMessage(uint idx, bool wait = true) const;
-	void printASCIIString(const Common::String &str) const;
 	void delay(uint32 ms) const;
 
 	Common::String inputString(byte prompt = 0) const;
diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp
index 7af6f66..d48296e 100644
--- a/engines/adl/display.cpp
+++ b/engines/adl/display.cpp
@@ -289,6 +289,16 @@ void Display::printString(const Common::String &str) {
 	updateTextScreen();
 }
 
+void Display::printAsciiString(const Common::String &str) {
+	Common::String aStr;
+
+	Common::String::const_iterator it;
+	for (it = str.begin(); it != str.end(); ++it)
+			aStr += APPLECHAR(*it);
+
+	printString(aStr);
+}
+
 void Display::setCharAtCursor(byte c) {
 	_textBuf[_cursorPos] = c;
 }
diff --git a/engines/adl/display.h b/engines/adl/display.h
index ce8f86b..e61477d 100644
--- a/engines/adl/display.h
+++ b/engines/adl/display.h
@@ -70,6 +70,7 @@ public:
 	void moveCursorForward();
 	void moveCursorBackward();
 	void printString(const Common::String &str);
+	void printAsciiString(const Common::String &str);
 	void setCharAtCursor(byte c);
 	void showCursor(bool enable);
 
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 80ea094..95f0289 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -55,16 +55,16 @@ void HiRes1Engine::runIntro() const {
 	Common::String str;
 
 	str = readStringAt(basic, IDI_HR1_OFS_PD_TEXT_0, '"');
-	printASCIIString(str + '\r');
+	_display->printAsciiString(str + '\r');
 
 	str = readStringAt(basic, IDI_HR1_OFS_PD_TEXT_1, '"');
-	printASCIIString(str + "\r\r");
+	_display->printAsciiString(str + "\r\r");
 
 	str = readStringAt(basic, IDI_HR1_OFS_PD_TEXT_2, '"');
-	printASCIIString(str + "\r\r");
+	_display->printAsciiString(str + "\r\r");
 
 	str = readStringAt(basic, IDI_HR1_OFS_PD_TEXT_3, '"');
-	printASCIIString(str + '\r');
+	_display->printAsciiString(str + '\r');
 
 	inputKey();
 	if (g_engine->shouldQuit())
@@ -120,7 +120,7 @@ void HiRes1Engine::runIntro() const {
 		}
 	}
 
-	printASCIIString("\r");
+	_display->printAsciiString("\r");
 
 	file.close();
 
@@ -240,7 +240,7 @@ void HiRes1Engine::restartGame() {
 	initState();
 	_display->printString(_gameStrings.pressReturn);
 	inputString(); // Missing in the original
-	printASCIIString("\r\r\r\r\r");
+	_display->printAsciiString("\r\r\r\r\r");
 }
 
 void HiRes1Engine::loadData() {


Commit: 63adab81edc8f44d4b4387352e0869e3042c2a13
    https://github.com/scummvm/scummvm/commit/63adab81edc8f44d4b4387352e0869e3042c2a13
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Clean up HiRes1Engine class

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



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 5b43a6c..dd4f406 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -41,10 +41,14 @@
 
 namespace Adl {
 
+AdlEngine::~AdlEngine() {
+	delete _display;
+}
+
 AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) :
 		Engine(syst),
-		_gameDescription(gd),
 		_display(nullptr),
+		_gameDescription(gd),
 		_isRestarting(false),
 		_isRestoring(false),
 		_saveVerb(0),
@@ -55,18 +59,206 @@ AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) :
 		_canRestoreNow(false) {
 }
 
-AdlEngine::~AdlEngine() {
-	delete _display;
+Common::String AdlEngine::readString(Common::ReadStream &stream, byte until) const {
+	Common::String str;
+
+	while (1) {
+		byte b = stream.readByte();
+
+		if (stream.eos() || stream.err())
+			error("Error reading string");
+
+		if (b == until)
+			break;
+
+		str += b;
+	};
+
+	return str;
 }
 
-bool AdlEngine::hasFeature(EngineFeature f) const {
-	switch (f) {
-	case kSupportsLoadingDuringRuntime:
-	case kSupportsSavingDuringRuntime:
-	case kSupportsRTL:
-		return true;
-	default:
-		return false;
+Common::String AdlEngine::readStringAt(Common::SeekableReadStream &stream, uint offset, byte until) const {
+	stream.seek(offset);
+	return readString(stream, until);
+}
+
+void AdlEngine::printMessage(uint idx, bool wait) const {
+	Common::String msg = _messages[idx - 1];
+	wordWrap(msg);
+	_display->printString(msg);
+
+	if (wait)
+		delay(14 * 166018 / 1000);
+}
+
+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) {
+		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;
+				}
+			}
+		}
+		g_system->delayMillis(16);
+	}
+}
+
+Common::String AdlEngine::inputString(byte prompt) const {
+	Common::String s;
+
+	if (prompt > 0)
+		_display->printString(Common::String(prompt));
+
+	while (1) {
+		byte b = inputKey();
+
+		if (g_engine->shouldQuit() || _isRestoring)
+			return 0;
+
+		if (b == 0)
+			continue;
+
+		if (b == ('\r' | 0x80)) {
+			s += b;
+			_display->printString(Common::String(b));
+			return s;
+		}
+
+		if (b < 0xa0) {
+			switch (b) {
+			case Common::KEYCODE_BACKSPACE | 0x80:
+				if (!s.empty()) {
+					_display->moveCursorBackward();
+					_display->setCharAtCursor(APPLECHAR(' '));
+					s.deleteLastChar();
+				}
+				break;
+			};
+		} else {
+			s += b;
+			_display->printString(Common::String(b));
+		}
+	}
+}
+
+byte AdlEngine::inputKey() const {
+	Common::EventManager *ev = g_system->getEventManager();
+
+	byte key = 0;
+
+	_display->showCursor(true);
+
+	while (!g_engine->shouldQuit() && !_isRestoring && key == 0) {
+		Common::Event event;
+		if (ev->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:
+				key = convertKey(event.kbd.keycode);
+				break;
+			default:
+				if (event.kbd.ascii >= 0x20 && event.kbd.ascii < 0x80)
+					key = convertKey(event.kbd.ascii);
+			};
+		}
+
+		_display->updateTextScreen();
+		g_system->delayMillis(16);
+	}
+
+	_display->showCursor(false);
+
+	return key;
+}
+
+void AdlEngine::loadWords(Common::ReadStream &stream, WordMap &map) const {
+	uint index = 0;
+
+	while (1) {
+		++index;
+
+		byte buf[IDI_WORD_SIZE];
+
+		if (stream.read(buf, IDI_WORD_SIZE) < IDI_WORD_SIZE)
+			error("Error reading word list");
+
+		Common::String word((char *)buf, IDI_WORD_SIZE);
+
+		if (!map.contains(word))
+			map[word] = index;
+
+		byte synonyms = stream.readByte();
+
+		if (stream.err() || stream.eos())
+			error("Error reading word list");
+
+		if (synonyms == 0xff)
+			break;
+
+		for (uint i = 0; i < synonyms; ++i) {
+			if (stream.read((char *)buf, IDI_WORD_SIZE) < IDI_WORD_SIZE)
+				error("Error reading word list");
+
+			word = Common::String((char *)buf, IDI_WORD_SIZE);
+
+			if (!map.contains(word))
+				map[word] = index;
+		}
+	}
+}
+
+void AdlEngine::readCommands(Common::ReadStream &stream, Commands &commands) {
+	while (1) {
+		Command command;
+		command.room = stream.readByte();
+
+		if (command.room == 0xff)
+			return;
+
+		command.verb = stream.readByte();
+		command.noun = stream.readByte();
+
+		byte scriptSize = stream.readByte() - 6;
+
+		command.numCond = stream.readByte();
+		command.numAct = stream.readByte();
+
+		for (uint i = 0; i < scriptSize; ++i)
+			command.script.push_back(stream.readByte());
+
+		if (stream.eos() || stream.err())
+			error("Failed to read commands");
+
+		if (command.numCond == 0 && command.script[0] == IDO_ACT_SAVE) {
+			_saveVerb = command.verb;
+			_saveNoun = command.noun;
+		}
+
+		if (command.numCond == 0 && command.script[0] == IDO_ACT_LOAD) {
+			_restoreVerb = command.verb;
+			_restoreNoun = command.noun;
+		}
+
+		commands.push_back(command);
 	}
 }
 
@@ -138,380 +330,317 @@ Common::Error AdlEngine::run() {
 	return Common::kNoError;
 }
 
-Common::String AdlEngine::readString(Common::ReadStream &stream, byte until) const {
-	Common::String str;
-
-	while (1) {
-		byte b = stream.readByte();
+bool AdlEngine::hasFeature(EngineFeature f) const {
+	switch (f) {
+	case kSupportsLoadingDuringRuntime:
+	case kSupportsSavingDuringRuntime:
+	case kSupportsRTL:
+		return true;
+	default:
+		return false;
+	}
+}
 
-		if (stream.eos() || stream.err())
-			error("Error reading string");
+Common::Error AdlEngine::loadGameState(int slot) {
+	Common::String fileName = Common::String::format("%s.s%02d", _targetName.c_str(), slot);
+	Common::InSaveFile *inFile = getSaveFileManager()->openForLoading(fileName);
 
-		if (b == until)
-			break;
+	if (!inFile) {
+		warning("Failed to open file '%s'", fileName.c_str());
+		return Common::kUnknownError;
+	}
 
-		str += b;
-	};
+	if (inFile->readUint32BE() != MKTAG('A', 'D', 'L', ':')) {
+		warning("No header found in '%s'", fileName.c_str());
+		delete inFile;
+		return Common::kUnknownError;
+	}
 
-	return str;
-}
+	byte saveVersion = inFile->readByte();
+	if (saveVersion != SAVEGAME_VERSION) {
+		warning("Save game version %i not supported", saveVersion);
+		delete inFile;
+		return Common::kUnknownError;
+	}
 
-Common::String AdlEngine::readStringAt(Common::SeekableReadStream &stream, uint offset, byte until) const {
-	stream.seek(offset);
-	return readString(stream, until);
-}
+	// Skip description
+	inFile->seek(SAVEGAME_NAME_LEN, SEEK_CUR);
+	// Skip save time
+	inFile->seek(6, SEEK_CUR);
 
-void AdlEngine::wordWrap(Common::String &str) const {
-	uint end = 39;
+	uint32 playTime = inFile->readUint32BE();
 
-	while (1) {
-		if (str.size() <= end)
-			return;
+	Graphics::skipThumbnail(*inFile);
 
-		while (str[end] != APPLECHAR(' '))
-			--end;
+	initState();
 
-		str.setChar(APPLECHAR('\r'), end);
-		end += 40;
+	_state.room = inFile->readByte();
+	_state.moves = inFile->readByte();
+	_state.isDark = inFile->readByte();
+
+	uint32 size = inFile->readUint32BE();
+	if (size != _state.rooms.size())
+		error("Room count mismatch (expected %i; found %i)", _state.rooms.size(), size);
+
+	for (uint i = 0; i < size; ++i) {
+		_state.rooms[i].picture = inFile->readByte();
+		_state.rooms[i].curPicture = inFile->readByte();
 	}
-}
 
-void AdlEngine::printMessage(uint idx, bool wait) const {
-	Common::String msg = _messages[idx - 1];
-	wordWrap(msg);
-	_display->printString(msg);
+	size = inFile->readUint32BE();
+	if (size != _state.items.size())
+		error("Item count mismatch (expected %i; found %i)", _state.items.size(), size);
 
-	if (wait)
-		delay(14 * 166018 / 1000);
+	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();
+	}
+
+	size = inFile->readUint32BE();
+	if (size != _state.vars.size())
+		error("Variable count mismatch (expected %i; found %i)", _state.vars.size(), size);
+
+	for (uint i = 0; i < size; ++i)
+		_state.vars[i] = inFile->readByte();
+
+	if (inFile->err() || inFile->eos())
+		error("Failed to load game '%s'", fileName.c_str());
+
+	delete inFile;
+
+	setTotalPlayTime(playTime);
+
+	_isRestoring = true;
+	return Common::kNoError;
 }
 
-void AdlEngine::readCommands(Common::ReadStream &stream, Commands &commands) {
-	while (1) {
-		Command command;
-		command.room = stream.readByte();
+bool AdlEngine::canLoadGameStateCurrently() const {
+	return _canRestoreNow;
+}
 
-		if (command.room == 0xff)
-			return;
+Common::Error AdlEngine::saveGameState(int slot, const Common::String &desc) {
+	Common::String fileName = Common::String::format("%s.s%02d", _targetName.c_str(), slot);
+	Common::OutSaveFile *outFile = getSaveFileManager()->openForSaving(fileName);
 
-		command.verb = stream.readByte();
-		command.noun = stream.readByte();
+	if (!outFile) {
+		warning("Failed to open file '%s'", fileName.c_str());
+		return Common::kUnknownError;
+	}
 
-		byte scriptSize = stream.readByte() - 6;
+	outFile->writeUint32BE(MKTAG('A', 'D', 'L', ':'));
+	outFile->writeByte(SAVEGAME_VERSION);
 
-		command.numCond = stream.readByte();
-		command.numAct = stream.readByte();
+	char name[SAVEGAME_NAME_LEN] = { };
 
-		for (uint i = 0; i < scriptSize; ++i)
-			command.script.push_back(stream.readByte());
+	if (!desc.empty())
+		strncpy(name, desc.c_str(), sizeof(name) - 1);
+	else {
+		Common::String defaultName("Save ");
+		defaultName += 'A' + slot;
+		strncpy(name, defaultName.c_str(), sizeof(name) - 1);
+	}
 
-		if (stream.eos() || stream.err())
-			error("Failed to read commands");
+	outFile->write(name, sizeof(name));
 
-		if (command.numCond == 0 && command.script[0] == IDO_ACT_SAVE) {
-			_saveVerb = command.verb;
-			_saveNoun = command.noun;
-		}
+	TimeDate t;
+	g_system->getTimeAndDate(t);
 
-		if (command.numCond == 0 && command.script[0] == IDO_ACT_LOAD) {
-			_restoreVerb = command.verb;
-			_restoreNoun = command.noun;
-		}
+	outFile->writeUint16BE(t.tm_year);
+	outFile->writeByte(t.tm_mon);
+	outFile->writeByte(t.tm_mday);
+	outFile->writeByte(t.tm_hour);
+	outFile->writeByte(t.tm_min);
 
-		commands.push_back(command);
+	uint32 playTime = getTotalPlayTime();
+	outFile->writeUint32BE(playTime);
+
+	_display->saveThumbnail(*outFile);
+
+	outFile->writeByte(_state.room);
+	outFile->writeByte(_state.moves);
+	outFile->writeByte(_state.isDark);
+
+	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);
 	}
-}
 
-void AdlEngine::takeItem(byte noun) {
-	Common::Array<Item>::iterator item;
+	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);
+	}
 
-	for (item = _state.items.begin(); item != _state.items.end(); ++item) {
-		if (item->noun != noun || item->room != _state.room)
-			continue;
+	outFile->writeUint32BE(_state.vars.size());
+	for (uint i = 0; i < _state.vars.size(); ++i)
+		outFile->writeByte(_state.vars[i]);
 
-		if (item->state == IDI_ITEM_DOESNT_MOVE) {
-			printMessage(_messageIds.itemDoesntMove);
-			return;
-		}
+	outFile->finalize();
 
-		if (item->state == IDI_ITEM_MOVED) {
-			item->room = IDI_NONE;
-			return;
-		}
+	if (outFile->err()) {
+		delete outFile;
+		warning("Failed to save game '%s'", fileName.c_str());
+		return Common::kUnknownError;
+	}
 
-		Common::Array<byte>::const_iterator pic;
-		for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
-			if (*pic == curRoom().curPicture) {
-				item->room = IDI_NONE;
-				item->state = IDI_ITEM_MOVED;
-				return;
-			}
+	delete outFile;
+	return Common::kNoError;
+}
+
+bool AdlEngine::canSaveGameStateCurrently() const {
+	if (!_canSaveNow)
+		return false;
+
+	Commands::const_iterator cmd;
+
+	// Here we check whether or not the game currently accepts the command
+	// "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) {
+		if (matchCommand(*cmd, _saveVerb, _saveNoun)) {
+			if (cmd->verb != _saveVerb || cmd->noun != _saveNoun)
+				return false;
+			return cmd->numCond == 0 && cmd->script[0] == IDO_ACT_SAVE;
 		}
 	}
 
-	printMessage(_messageIds.itemNotHere);
+	return false;
 }
 
-void AdlEngine::dropItem(byte noun) {
-	Common::Array<Item>::iterator item;
+void AdlEngine::wordWrap(Common::String &str) const {
+	uint end = 39;
 
-	for (item = _state.items.begin(); item != _state.items.end(); ++item) {
-		if (item->noun != noun || item->room != IDI_NONE)
-			continue;
+	while (1) {
+		if (str.size() <= end)
+			return;
 
-		item->room = _state.room;
-		item->state = IDI_ITEM_MOVED;
-		return;
+		while (str[end] != APPLECHAR(' '))
+			--end;
+
+		str.setChar(APPLECHAR('\r'), end);
+		end += 40;
 	}
+}
 
-	printMessage(_messageIds.dontUnderstand);
+byte AdlEngine::convertKey(uint16 ascii) const {
+	ascii = toupper(ascii);
+
+	if (ascii >= 0x80)
+		return 0;
+
+	ascii |= 0x80;
+
+	if (ascii >= 0x80 && ascii <= 0xe0)
+		return ascii;
+
+	return 0;
 }
 
-#define ARG(N) (command.script[offset + (N)])
+Common::String AdlEngine::getLine() const {
+	// Original engine uses a global here, which isn't reset between
+	// calls and may not match actual mode
+	bool textMode = false;
 
-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:
-			var(ARG(2)) += ARG(1);
-			offset += 3;
-			break;
-		case IDO_ACT_VAR_SUB:
-			var(ARG(2)) -= ARG(1);
-			offset += 3;
-			break;
-		case IDO_ACT_VAR_SET:
-			var(ARG(1)) = ARG(2);
-			offset += 3;
-			break;
-		case IDO_ACT_LIST_ITEMS: {
-			Common::Array<Item>::const_iterator item;
+	while (1) {
+		Common::String line = inputString(APPLECHAR('?'));
 
-			for (item = _state.items.begin(); item != _state.items.end(); ++item)
-				if (item->room == IDI_NONE)
-					printMessage(item->description);
+		if (shouldQuit() || _isRestoring)
+			return "";
 
-			++offset;
-			break;
+		if ((byte)line[0] == ('\r' | 0x80)) {
+			textMode = !textMode;
+			_display->setMode(textMode ? DISPLAY_MODE_TEXT : DISPLAY_MODE_MIXED);
+			continue;
 		}
-		case IDO_ACT_MOVE_ITEM:
-			item(ARG(1)).room = ARG(2);
-			offset += 3;
-			break;
-		case IDO_ACT_SET_ROOM:
-			curRoom().curPicture = curRoom().picture;
-			_state.room = ARG(1);
-			offset += 2;
-			break;
-		case IDO_ACT_SET_CUR_PIC:
-			curRoom().curPicture = ARG(1);
-			offset += 2;
-			break;
-		case IDO_ACT_SET_PIC:
-			curRoom().picture = curRoom().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);
-
-			// We allow restoring via GMM here
-			_canRestoreNow = true;
-			Common::String input = inputString();
-			_canRestoreNow = false;
-
-			// If the user restored with the GMM, we break off the restart
-			if (_isRestoring)
-				return;
-
-			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:
-			item(ARG(1)).room = ARG(2);
-			item(ARG(1)).position.x = ARG(3);
-			item(ARG(1)).position.y = ARG(4);
-			offset += 5;
-			break;
-		case IDO_ACT_SET_ITEM_PIC:
-			item(ARG(2)).picture = ARG(1);
-			offset += 3;
-			break;
-		case IDO_ACT_RESET_PIC:
-			curRoom().curPicture = curRoom().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 = curRoom().connections[ARG(0) - IDO_ACT_GO_NORTH];
-
-			if (room == 0) {
-				printMessage(_messageIds.cantGoThere);
-				return;
-			}
 
-			curRoom().curPicture = curRoom().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:
-			room(ARG(1)).picture = room(ARG(1)).curPicture = ARG(2);
-			offset += 3;
-			break;
-		default:
-			error("Invalid action opcode %02x", ARG(0));
-		}
+		// Remove the return
+		line.deleteLastChar();
+		return line;
 	}
 }
 
-bool AdlEngine::matchCommand(const Command &command, byte verb, byte noun, uint *actions) const {
-	if (command.room != IDI_NONE && command.room != _state.room)
-		return false;
+Common::String AdlEngine::getWord(const Common::String &line, uint &index) const {
+	Common::String str;
 
-	if (command.verb != IDI_NONE && command.verb != verb)
-		return false;
+	for (uint i = 0; i < 8; ++i)
+		str += APPLECHAR(' ');
 
-	if (command.noun != IDI_NONE && command.noun != noun)
-		return false;
+	int copied = 0;
 
-	uint offset = 0;
-	for (uint i = 0; i < command.numCond; ++i) {
-		switch (ARG(0)) {
-		case IDO_CND_ITEM_IN_ROOM:
-			if (item(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 (var(ARG(1)) != ARG(2))
-				return false;
-			offset += 3;
-			break;
-		case IDO_CND_CUR_PIC_EQ:
-			if (curRoom().curPicture != ARG(1))
-				return false;
-			offset += 2;
-			break;
-		case IDO_CND_ITEM_PIC_EQ:
-			if (item(ARG(1)).picture != ARG(2))
-				return false;
-			offset += 3;
+	// Skip initial whitespace
+	while (1) {
+		if (index == line.size())
+			return str;
+		if (line[index] != APPLECHAR(' '))
 			break;
-		default:
-			error("Invalid condition opcode %02x", command.script[offset]);
-		}
+		++index;
 	}
 
-	*actions = offset;
+	// Copy up to 8 characters
+	while (1) {
+		if (copied < 8)
+			str.setChar(line[index], copied++);
 
-	return true;
+		index++;
+
+		if (index == line.size() || line[index] == APPLECHAR(' '))
+			return str;
+	}
 }
 
-#undef ARG
+void AdlEngine::getInput(uint &verb, uint &noun) {
+	while (1) {
+		_display->printString(_strings.enterCommand);
+		Common::String line = getLine();
 
-bool AdlEngine::doOneCommand(const Commands &commands, byte verb, byte noun) {
-	Commands::const_iterator cmd;
+		if (shouldQuit() || _isRestoring)
+			return;
 
-	for (cmd = commands.begin(); cmd != commands.end(); ++cmd) {
-		uint offset = 0;
-		if (matchCommand(*cmd, verb, noun, &offset)) {
-			doActions(*cmd, noun, offset);
-			return true;
+		uint index = 0;
+		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);
+			continue;
 		}
-	}
 
-	return false;
-}
+		verb = _verbs[verbStr];
 
-void AdlEngine::doAllCommands(const Commands &commands, byte verb, byte noun) {
-	Commands::const_iterator cmd;
-	bool oldIsRestoring = _isRestoring;
+		Common::String nounStr = getWord(line, index);
 
-	for (cmd = commands.begin(); cmd != commands.end(); ++cmd) {
-		uint offset = 0;
-		if (matchCommand(*cmd, verb, noun, &offset))
-			doActions(*cmd, noun, offset);
+		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);
+			continue;
+		}
 
-		// We assume no restarts happen in this command group. This
-		// simplifies enabling GMM savegame loading on the restart
-		// prompt.
-		if (_isRestarting || _isRestoring != oldIsRestoring)
-			error("Unexpected restart action encountered");
+		noun = _nouns[nounStr];
+		return;
 	}
 }
 
-bool AdlEngine::canSaveGameStateCurrently() const {
-	if (!_canSaveNow)
-		return false;
-
-	Commands::const_iterator cmd;
-
-	// Here we check whether or not the game currently accepts the command
-	// "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) {
-		if (matchCommand(*cmd, _saveVerb, _saveNoun)) {
-			if (cmd->verb != _saveVerb || cmd->noun != _saveNoun)
-				return false;
-			return cmd->numCond == 0 && cmd->script[0] == IDO_ACT_SAVE;
-		}
+void AdlEngine::showRoom() const {
+	if (!_state.isDark) {
+		drawPic(curRoom().curPicture);
+		drawItems();
 	}
 
-	return false;
-}
-
-bool AdlEngine::canLoadGameStateCurrently() const {
-	return _canRestoreNow;
+	_display->updateHiResScreen();
+	printMessage(curRoom().description, false);
 }
 
 void AdlEngine::clearScreen() const {
@@ -554,163 +683,49 @@ void AdlEngine::drawItems() const {
 	}
 }
 
-void AdlEngine::showRoom() const {
-	if (!_state.isDark) {
-		drawPic(curRoom().curPicture);
-		drawItems();
-	}
-
-	_display->updateHiResScreen();
-	printMessage(curRoom().description, false);
-}
-
-Common::Error AdlEngine::saveGameState(int slot, const Common::String &desc) {
-	Common::String fileName = Common::String::format("%s.s%02d", _targetName.c_str(), slot);
-	Common::OutSaveFile *outFile = getSaveFileManager()->openForSaving(fileName);
-
-	if (!outFile) {
-		warning("Failed to open file '%s'", fileName.c_str());
-		return Common::kUnknownError;
-	}
-
-	outFile->writeUint32BE(MKTAG('A', 'D', 'L', ':'));
-	outFile->writeByte(SAVEGAME_VERSION);
-
-	char name[SAVEGAME_NAME_LEN] = { };
-
-	if (!desc.empty())
-		strncpy(name, desc.c_str(), sizeof(name) - 1);
-	else {
-		Common::String defaultName("Save ");
-		defaultName += 'A' + slot;
-		strncpy(name, defaultName.c_str(), sizeof(name) - 1);
-	}
-
-	outFile->write(name, sizeof(name));
-
-	TimeDate t;
-	g_system->getTimeAndDate(t);
-
-	outFile->writeUint16BE(t.tm_year);
-	outFile->writeByte(t.tm_mon);
-	outFile->writeByte(t.tm_mday);
-	outFile->writeByte(t.tm_hour);
-	outFile->writeByte(t.tm_min);
-
-	uint32 playTime = getTotalPlayTime();
-	outFile->writeUint32BE(playTime);
-
-	_display->saveThumbnail(*outFile);
-
-	outFile->writeByte(_state.room);
-	outFile->writeByte(_state.moves);
-	outFile->writeByte(_state.isDark);
-
-	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->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);
-	}
-
-	outFile->writeUint32BE(_state.vars.size());
-	for (uint i = 0; i < _state.vars.size(); ++i)
-		outFile->writeByte(_state.vars[i]);
-
-	outFile->finalize();
+void AdlEngine::drawNextPixel(Common::Point &p, byte color, byte bits, byte quadrant) const {
+	if (bits & 4)
+		_display->putPixel(p, color);
 
-	if (outFile->err()) {
-		delete outFile;
-		warning("Failed to save game '%s'", fileName.c_str());
-		return Common::kUnknownError;
-	}
+	bits += quadrant;
 
-	delete outFile;
-	return Common::kNoError;
+	if (bits & 1)
+		p.x += (bits & 2 ? -1 : 1);
+	else
+		p.y += (bits & 2 ? 1 : -1);
 }
 
-Common::Error AdlEngine::loadGameState(int slot) {
-	Common::String fileName = Common::String::format("%s.s%02d", _targetName.c_str(), slot);
-	Common::InSaveFile *inFile = getSaveFileManager()->openForLoading(fileName);
-
-	if (!inFile) {
-		warning("Failed to open file '%s'", fileName.c_str());
-		return Common::kUnknownError;
-	}
-
-	if (inFile->readUint32BE() != MKTAG('A', 'D', 'L', ':')) {
-		warning("No header found in '%s'", fileName.c_str());
-		delete inFile;
-		return Common::kUnknownError;
-	}
-
-	byte saveVersion = inFile->readByte();
-	if (saveVersion != SAVEGAME_VERSION) {
-		warning("Save game version %i not supported", saveVersion);
-		delete inFile;
-		return Common::kUnknownError;
-	}
-
-	// Skip description
-	inFile->seek(SAVEGAME_NAME_LEN, SEEK_CUR);
-	// Skip save time
-	inFile->seek(6, SEEK_CUR);
-
-	uint32 playTime = inFile->readUint32BE();
-
-	Graphics::skipThumbnail(*inFile);
-
-	initState();
-
-	_state.room = inFile->readByte();
-	_state.moves = inFile->readByte();
-	_state.isDark = inFile->readByte();
+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
+	};
 
-	uint32 size = inFile->readUint32BE();
-	if (size != _state.rooms.size())
-		error("Room count mismatch (expected %i; found %i)", _state.rooms.size(), size);
+	byte quadrant = rotation >> 4;
+	rotation &= 0xf;
+	byte xStep = stepping[rotation];
+	byte yStep = stepping[(rotation ^ 0xf) + 1] + 1;
 
-	for (uint i = 0; i < size; ++i) {
-		_state.rooms[i].picture = inFile->readByte();
-		_state.rooms[i].curPicture = inFile->readByte();
-	}
+	Common::Point p(pos);
 
-	size = inFile->readUint32BE();
-	if (size != _state.items.size())
-		error("Item count mismatch (expected %i; found %i)", _state.items.size(), size);
+	for (uint i = 0; i < lineArt.size(); ++i) {
+		byte b = lineArt[i];
 
-	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();
+		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);
 	}
-
-	size = inFile->readUint32BE();
-	if (size != _state.vars.size())
-		error("Variable count mismatch (expected %i; found %i)", _state.vars.size(), size);
-
-	for (uint i = 0; i < size; ++i)
-		_state.vars[i] = inFile->readByte();
-
-	if (inFile->err() || inFile->eos())
-		error("Failed to load game '%s'", fileName.c_str());
-
-	delete inFile;
-
-	setTotalPlayTime(playTime);
-
-	_isRestoring = true;
-	return Common::kNoError;
 }
 
 const Room &AdlEngine::room(uint i) const {
@@ -763,287 +778,272 @@ byte &AdlEngine::var(uint i) {
 	return _state.vars[i];
 }
 
-void AdlEngine::loadWords(Common::ReadStream &stream, WordMap &map) const {
-	uint index = 0;
-
-	while (1) {
-		++index;
-
-		byte buf[IDI_WORD_SIZE];
-
-		if (stream.read(buf, IDI_WORD_SIZE) < IDI_WORD_SIZE)
-			error("Error reading word list");
-
-		Common::String word((char *)buf, IDI_WORD_SIZE);
-
-		if (!map.contains(word))
-			map[word] = index;
-
-		byte synonyms = stream.readByte();
-
-		if (stream.err() || stream.eos())
-			error("Error reading word list");
+void AdlEngine::takeItem(byte noun) {
+	Common::Array<Item>::iterator item;
 
-		if (synonyms == 0xff)
-			break;
+	for (item = _state.items.begin(); item != _state.items.end(); ++item) {
+		if (item->noun != noun || item->room != _state.room)
+			continue;
 
-		for (uint i = 0; i < synonyms; ++i) {
-			if (stream.read((char *)buf, IDI_WORD_SIZE) < IDI_WORD_SIZE)
-				error("Error reading word list");
+		if (item->state == IDI_ITEM_DOESNT_MOVE) {
+			printMessage(_messageIds.itemDoesntMove);
+			return;
+		}
 
-			word = Common::String((char *)buf, IDI_WORD_SIZE);
+		if (item->state == IDI_ITEM_MOVED) {
+			item->room = IDI_NONE;
+			return;
+		}
 
-			if (!map.contains(word))
-				map[word] = index;
+		Common::Array<byte>::const_iterator pic;
+		for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
+			if (*pic == curRoom().curPicture) {
+				item->room = IDI_NONE;
+				item->state = IDI_ITEM_MOVED;
+				return;
+			}
 		}
 	}
-}
 
-Common::String AdlEngine::getLine() const {
-	// Original engine uses a global here, which isn't reset between
-	// calls and may not match actual mode
-	bool textMode = false;
-
-	while (1) {
-		Common::String line = inputString(APPLECHAR('?'));
+	printMessage(_messageIds.itemNotHere);
+}
 
-		if (shouldQuit() || _isRestoring)
-			return "";
+void AdlEngine::dropItem(byte noun) {
+	Common::Array<Item>::iterator item;
 
-		if ((byte)line[0] == ('\r' | 0x80)) {
-			textMode = !textMode;
-			_display->setMode(textMode ? DISPLAY_MODE_TEXT : DISPLAY_MODE_MIXED);
+	for (item = _state.items.begin(); item != _state.items.end(); ++item) {
+		if (item->noun != noun || item->room != IDI_NONE)
 			continue;
-		}
 
-		// Remove the return
-		line.deleteLastChar();
-		return line;
+		item->room = _state.room;
+		item->state = IDI_ITEM_MOVED;
+		return;
 	}
+
+	printMessage(_messageIds.dontUnderstand);
 }
 
-Common::String AdlEngine::getWord(const Common::String &line, uint &index) const {
-	Common::String str;
+#define ARG(N) (command.script[offset + (N)])
 
-	for (uint i = 0; i < 8; ++i)
-		str += APPLECHAR(' ');
+bool AdlEngine::matchCommand(const Command &command, byte verb, byte noun, uint *actions) const {
+	if (command.room != IDI_NONE && command.room != _state.room)
+		return false;
 
-	int copied = 0;
+	if (command.verb != IDI_NONE && command.verb != verb)
+		return false;
 
-	// Skip initial whitespace
-	while (1) {
-		if (index == line.size())
-			return str;
-		if (line[index] != APPLECHAR(' '))
+	if (command.noun != IDI_NONE && command.noun != noun)
+		return false;
+
+	uint offset = 0;
+	for (uint i = 0; i < command.numCond; ++i) {
+		switch (ARG(0)) {
+		case IDO_CND_ITEM_IN_ROOM:
+			if (item(ARG(1)).room != ARG(2))
+				return false;
+			offset += 3;
 			break;
-		++index;
+		case IDO_CND_MOVES_GE:
+			if (ARG(1) > _state.moves)
+				return false;
+			offset += 2;
+			break;
+		case IDO_CND_VAR_EQ:
+			if (var(ARG(1)) != ARG(2))
+				return false;
+			offset += 3;
+			break;
+		case IDO_CND_CUR_PIC_EQ:
+			if (curRoom().curPicture != ARG(1))
+				return false;
+			offset += 2;
+			break;
+		case IDO_CND_ITEM_PIC_EQ:
+			if (item(ARG(1)).picture != ARG(2))
+				return false;
+			offset += 3;
+			break;
+		default:
+			error("Invalid condition opcode %02x", command.script[offset]);
+		}
 	}
 
-	// Copy up to 8 characters
-	while (1) {
-		if (copied < 8)
-			str.setChar(line[index], copied++);
-
-		index++;
+	*actions = offset;
 
-		if (index == line.size() || line[index] == APPLECHAR(' '))
-			return str;
-	}
+	return true;
 }
 
-void AdlEngine::getInput(uint &verb, uint &noun) {
-	while (1) {
-		_display->printString(_strings.enterCommand);
-		Common::String line = getLine();
-
-		if (shouldQuit() || _isRestoring)
-			return;
-
-		uint index = 0;
-		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);
-			continue;
-		}
-
-		verb = _verbs[verbStr];
+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:
+			var(ARG(2)) += ARG(1);
+			offset += 3;
+			break;
+		case IDO_ACT_VAR_SUB:
+			var(ARG(2)) -= ARG(1);
+			offset += 3;
+			break;
+		case IDO_ACT_VAR_SET:
+			var(ARG(1)) = ARG(2);
+			offset += 3;
+			break;
+		case IDO_ACT_LIST_ITEMS: {
+			Common::Array<Item>::const_iterator item;
 
-		Common::String nounStr = getWord(line, index);
+			for (item = _state.items.begin(); item != _state.items.end(); ++item)
+				if (item->room == IDI_NONE)
+					printMessage(item->description);
 
-		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);
-			continue;
+			++offset;
+			break;
 		}
+		case IDO_ACT_MOVE_ITEM:
+			item(ARG(1)).room = ARG(2);
+			offset += 3;
+			break;
+		case IDO_ACT_SET_ROOM:
+			curRoom().curPicture = curRoom().picture;
+			_state.room = ARG(1);
+			offset += 2;
+			break;
+		case IDO_ACT_SET_CUR_PIC:
+			curRoom().curPicture = ARG(1);
+			offset += 2;
+			break;
+		case IDO_ACT_SET_PIC:
+			curRoom().picture = curRoom().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);
 
-		noun = _nouns[nounStr];
-		return;
-	}
-}
-
-Common::String AdlEngine::inputString(byte prompt) const {
-	Common::String s;
-
-	if (prompt > 0)
-		_display->printString(Common::String(prompt));
-
-	while (1) {
-		byte b = inputKey();
-
-		if (g_engine->shouldQuit() || _isRestoring)
-			return 0;
-
-		if (b == 0)
-			continue;
+			// We allow restoring via GMM here
+			_canRestoreNow = true;
+			Common::String input = inputString();
+			_canRestoreNow = false;
 
-		if (b == ('\r' | 0x80)) {
-			s += b;
-			_display->printString(Common::String(b));
-			return s;
-		}
+			// If the user restored with the GMM, we break off the restart
+			if (_isRestoring)
+				return;
 
-		if (b < 0xa0) {
-			switch (b) {
-			case Common::KEYCODE_BACKSPACE | 0x80:
-				if (!s.empty()) {
-					_display->moveCursorBackward();
-					_display->setCharAtCursor(APPLECHAR(' '));
-					s.deleteLastChar();
-				}
-				break;
-			};
-		} else {
-			s += b;
-			_display->printString(Common::String(b));
+			if (input.size() == 0 || input[0] != APPLECHAR('N')) {
+				_isRestarting = true;
+				_display->clear(0x00);
+				_display->updateHiResScreen();
+				restartGame();
+				return;
+			}
+			// Fall-through
 		}
-	}
-}
-
-byte AdlEngine::convertKey(uint16 ascii) const {
-	ascii = toupper(ascii);
-
-	if (ascii >= 0x80)
-		return 0;
-
-	ascii |= 0x80;
-
-	if (ascii >= 0x80 && ascii <= 0xe0)
-		return ascii;
-
-	return 0;
-}
-
-byte AdlEngine::inputKey() const {
-	Common::EventManager *ev = g_system->getEventManager();
-
-	byte key = 0;
-
-	_display->showCursor(true);
-
-	while (!g_engine->shouldQuit() && !_isRestoring && key == 0) {
-		Common::Event event;
-		if (ev->pollEvent(event)) {
-			if (event.type != Common::EVENT_KEYDOWN)
-				continue;
+		case IDO_ACT_QUIT:
+			printMessage(_messageIds.thanksForPlaying);
+			quitGame();
+			return;
+		case IDO_ACT_PLACE_ITEM:
+			item(ARG(1)).room = ARG(2);
+			item(ARG(1)).position.x = ARG(3);
+			item(ARG(1)).position.y = ARG(4);
+			offset += 5;
+			break;
+		case IDO_ACT_SET_ITEM_PIC:
+			item(ARG(2)).picture = ARG(1);
+			offset += 3;
+			break;
+		case IDO_ACT_RESET_PIC:
+			curRoom().curPicture = curRoom().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 = curRoom().connections[ARG(0) - IDO_ACT_GO_NORTH];
 
-			if (event.kbd.flags & Common::KBD_CTRL) {
-				if (event.kbd.keycode == Common::KEYCODE_q)
-					g_engine->quitGame();
-				continue;
+			if (room == 0) {
+				printMessage(_messageIds.cantGoThere);
+				return;
 			}
 
-			switch (event.kbd.keycode) {
-			case Common::KEYCODE_BACKSPACE:
-			case Common::KEYCODE_RETURN:
-				key = convertKey(event.kbd.keycode);
-				break;
-			default:
-				if (event.kbd.ascii >= 0x20 && event.kbd.ascii < 0x80)
-					key = convertKey(event.kbd.ascii);
-			};
+			curRoom().curPicture = curRoom().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:
+			room(ARG(1)).picture = room(ARG(1)).curPicture = ARG(2);
+			offset += 3;
+			break;
+		default:
+			error("Invalid action opcode %02x", ARG(0));
 		}
-
-		_display->updateTextScreen();
-		g_system->delayMillis(16);
 	}
-
-	_display->showCursor(false);
-
-	return key;
 }
 
-void AdlEngine::delay(uint32 ms) const {
-	Common::EventManager *ev = g_system->getEventManager();
+#undef ARG
 
-	uint32 start = g_system->getMillis();
+bool AdlEngine::doOneCommand(const Commands &commands, byte verb, byte noun) {
+	Commands::const_iterator cmd;
 
-	while (!g_engine->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;
-				}
-			}
+	for (cmd = commands.begin(); cmd != commands.end(); ++cmd) {
+		uint offset = 0;
+		if (matchCommand(*cmd, verb, noun, &offset)) {
+			doActions(*cmd, noun, offset);
+			return true;
 		}
-		g_system->delayMillis(16);
 	}
-}
 
-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);
+	return false;
 }
 
-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);
+void AdlEngine::doAllCommands(const Commands &commands, byte verb, byte noun) {
+	Commands::const_iterator cmd;
+	bool oldIsRestoring = _isRestoring;
 
-	for (uint i = 0; i < lineArt.size(); ++i) {
-		byte b = lineArt[i];
+	for (cmd = commands.begin(); cmd != commands.end(); ++cmd) {
+		uint offset = 0;
+		if (matchCommand(*cmd, verb, noun, &offset))
+			doActions(*cmd, noun, offset);
 
-		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);
+		// We assume no restarts happen in this command group. This
+		// simplifies enabling GMM savegame loading on the restart
+		// prompt.
+		if (_isRestarting || _isRestoring != oldIsRestoring)
+			error("Unexpected restart action encountered");
 	}
 }
 
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index b1d5b7c..a230f0f 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -23,8 +23,9 @@
 #ifndef ADL_ADL_H
 #define ADL_ADL_H
 
-#include "common/random.h"
+#include "common/array.h"
 #include "common/rect.h"
+#include "common/str.h"
 
 #include "engines/engine.h"
 
@@ -34,16 +35,10 @@ class SeekableReadStream;
 }
 
 namespace Adl {
+
 class Display;
-class Parser;
-class Console;
 struct AdlGameDescription;
 
-struct StringOffset {
-	int stringIdx;
-	uint offset;
-};
-
 // Conditional opcodes
 #define IDO_CND_ITEM_IN_ROOM   0x03
 #define IDO_CND_MOVES_GE       0x05
@@ -155,7 +150,6 @@ protected:
 	void readCommands(Common::ReadStream &stream, Commands &commands);
 
 	Display *_display;
-	Parser *_parser;
 
 	// Message strings in data file
 	Common::Array<Common::String> _messages;
@@ -236,9 +230,9 @@ private:
 	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);
-	void doActions(const Command &command, byte noun, byte offset);
 
 	const AdlGameDescription *_gameDescription;
 	bool _isRestarting, _isRestoring;
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 95f0289..6e1e31d 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -136,113 +136,6 @@ void HiRes1Engine::runIntro() const {
 	delay(2000);
 }
 
-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;
-	}
-}
-
-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());
-
-	f.seek(_pictures[pic].offset);
-	drawPic(f, pos);
-}
-
-void HiRes1Engine::initState() {
-	Common::File f;
-
-	_state.room = 1;
-	_state.moves = 0;
-	_state.isDark = false;
-
-	_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 "'");
-
-	// Load room data from executable
-	_state.rooms.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();
-		for (uint j = 0; j < 6; ++j)
-			room.connections[j] = f.readByte();
-		room.picture = f.readByte();
-		room.curPicture = f.readByte();
-		_state.rooms.push_back(room);
-	}
-
-	// Load item data from executable
-	_state.items.clear();
-	f.seek(IDI_HR1_OFS_ITEMS);
-	while (f.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();
-
-		f.readByte();
-
-		byte size = f.readByte();
-
-		for (uint i = 0; i < size; ++i)
-			item.roomPictures.push_back(f.readByte());
-
-		_state.items.push_back(item);
-	}
-}
-
-void HiRes1Engine::restartGame() {
-	initState();
-	_display->printString(_gameStrings.pressReturn);
-	inputString(); // Missing in the original
-	_display->printAsciiString("\r\r\r\r\r");
-}
-
 void HiRes1Engine::loadData() {
 	Common::File f;
 
@@ -331,6 +224,76 @@ void HiRes1Engine::loadData() {
 	loadWords(f, _nouns);
 }
 
+void HiRes1Engine::initState() {
+	Common::File f;
+
+	_state.room = 1;
+	_state.moves = 0;
+	_state.isDark = false;
+
+	_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 "'");
+
+	// Load room data from executable
+	_state.rooms.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();
+		for (uint j = 0; j < 6; ++j)
+			room.connections[j] = f.readByte();
+		room.picture = f.readByte();
+		room.curPicture = f.readByte();
+		_state.rooms.push_back(room);
+	}
+
+	// Load item data from executable
+	_state.items.clear();
+	f.seek(IDI_HR1_OFS_ITEMS);
+	while (f.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();
+
+		f.readByte();
+
+		byte size = f.readByte();
+
+		for (uint i = 0; i < size; ++i)
+			item.roomPictures.push_back(f.readByte());
+
+		_state.items.push_back(item);
+	}
+}
+
+void HiRes1Engine::restartGame() {
+	initState();
+	_display->printString(_gameStrings.pressReturn);
+	inputString(); // Missing in the original
+	_display->printAsciiString("\r\r\r\r\r");
+}
+
+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());
+
+	f.seek(_pictures[pic].offset);
+	drawPic(f, pos);
+}
+
 void HiRes1Engine::printMessage(uint idx, bool wait) const {
 	// Messages with hardcoded overrides don't delay after printing.
 	// It's unclear if this is a bug or not. In some cases the result
@@ -389,6 +352,43 @@ void HiRes1Engine::drawLine(const Common::Point &p1, const Common::Point &p2, by
 	}
 }
 
+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 b7c7f41..d9d67c4 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -23,6 +23,8 @@
 #ifndef ADL_HIRES1_H
 #define ADL_HIRES1_H
 
+#include "common/str.h"
+
 #include "adl/adl.h"
 
 namespace Common {


Commit: 57af92e0c11d578ba5361d07d569f0d480a9a29f
    https://github.com/scummvm/scummvm/commit/57af92e0c11d578ba5361d07d569f0d480a9a29f
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Fix shadowing warning (GCC 4.8)

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



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index dd4f406..92b74d2 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -635,12 +635,12 @@ void AdlEngine::getInput(uint &verb, uint &noun) {
 
 void AdlEngine::showRoom() const {
 	if (!_state.isDark) {
-		drawPic(curRoom().curPicture);
+		drawPic(getCurRoom().curPicture);
 		drawItems();
 	}
 
 	_display->updateHiResScreen();
-	printMessage(curRoom().description, false);
+	printMessage(getCurRoom().description, false);
 }
 
 void AdlEngine::clearScreen() const {
@@ -658,7 +658,7 @@ void AdlEngine::drawItems() const {
 			continue;
 
 		if (item->state == IDI_ITEM_MOVED) {
-			if (curRoom().picture == curRoom().curPicture) {
+			if (getCurRoom().picture == getCurRoom().curPicture) {
 				const Common::Point &p =  _itemOffsets[dropped];
 				if (item->isLineArt)
 					drawLineArt(_lineArt[item->picture - 1], p);
@@ -672,7 +672,7 @@ void AdlEngine::drawItems() const {
 		Common::Array<byte>::const_iterator pic;
 
 		for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
-			if (*pic == curRoom().curPicture) {
+			if (*pic == getCurRoom().curPicture) {
 				if (item->isLineArt)
 					drawLineArt(_lineArt[item->picture - 1], item->position);
 				else
@@ -728,54 +728,54 @@ void AdlEngine::drawLineArt(const Common::Array<byte> &lineArt, const Common::Po
 	}
 }
 
-const Room &AdlEngine::room(uint i) const {
+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::room(uint i) {
+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::curRoom() const {
-	return room(_state.room);
+const Room &AdlEngine::getCurRoom() const {
+	return getRoom(_state.room);
 }
 
-Room &AdlEngine::curRoom() {
-	return room(_state.room);
+Room &AdlEngine::getCurRoom() {
+	return getRoom(_state.room);
 }
 
-const Item &AdlEngine::item(uint i) const {
+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::item(uint 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());
 
 	return _state.items[i - 1];
 }
 
-const byte &AdlEngine::var(uint i) const {
+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];
 }
 
-byte &AdlEngine::var(uint 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);
 
-	return _state.vars[i];
+	_state.vars[i] = value;
 }
 
 void AdlEngine::takeItem(byte noun) {
@@ -797,7 +797,7 @@ void AdlEngine::takeItem(byte noun) {
 
 		Common::Array<byte>::const_iterator pic;
 		for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
-			if (*pic == curRoom().curPicture) {
+			if (*pic == getCurRoom().curPicture) {
 				item->room = IDI_NONE;
 				item->state = IDI_ITEM_MOVED;
 				return;
@@ -839,7 +839,7 @@ bool AdlEngine::matchCommand(const Command &command, byte verb, byte noun, uint
 	for (uint i = 0; i < command.numCond; ++i) {
 		switch (ARG(0)) {
 		case IDO_CND_ITEM_IN_ROOM:
-			if (item(ARG(1)).room != ARG(2))
+			if (getItem(ARG(1)).room != ARG(2))
 				return false;
 			offset += 3;
 			break;
@@ -849,17 +849,17 @@ bool AdlEngine::matchCommand(const Command &command, byte verb, byte noun, uint
 			offset += 2;
 			break;
 		case IDO_CND_VAR_EQ:
-			if (var(ARG(1)) != ARG(2))
+			if (getVar(ARG(1)) != ARG(2))
 				return false;
 			offset += 3;
 			break;
 		case IDO_CND_CUR_PIC_EQ:
-			if (curRoom().curPicture != ARG(1))
+			if (getCurRoom().curPicture != ARG(1))
 				return false;
 			offset += 2;
 			break;
 		case IDO_CND_ITEM_PIC_EQ:
-			if (item(ARG(1)).picture != ARG(2))
+			if (getItem(ARG(1)).picture != ARG(2))
 				return false;
 			offset += 3;
 			break;
@@ -877,15 +877,15 @@ 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:
-			var(ARG(2)) += ARG(1);
+			setVar(ARG(2), getVar(ARG(2) + ARG(1)));
 			offset += 3;
 			break;
 		case IDO_ACT_VAR_SUB:
-			var(ARG(2)) -= ARG(1);
+			setVar(ARG(2), getVar(ARG(2)) - ARG(1));
 			offset += 3;
 			break;
 		case IDO_ACT_VAR_SET:
-			var(ARG(1)) = ARG(2);
+			setVar(ARG(1), ARG(2));
 			offset += 3;
 			break;
 		case IDO_ACT_LIST_ITEMS: {
@@ -899,20 +899,20 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			break;
 		}
 		case IDO_ACT_MOVE_ITEM:
-			item(ARG(1)).room = ARG(2);
+			getItem(ARG(1)).room = ARG(2);
 			offset += 3;
 			break;
 		case IDO_ACT_SET_ROOM:
-			curRoom().curPicture = curRoom().picture;
+			getCurRoom().curPicture = getCurRoom().picture;
 			_state.room = ARG(1);
 			offset += 2;
 			break;
 		case IDO_ACT_SET_CUR_PIC:
-			curRoom().curPicture = ARG(1);
+			getCurRoom().curPicture = ARG(1);
 			offset += 2;
 			break;
 		case IDO_ACT_SET_PIC:
-			curRoom().picture = curRoom().curPicture = ARG(1);
+			getCurRoom().picture = getCurRoom().curPicture = ARG(1);
 			offset += 2;
 			break;
 		case IDO_ACT_PRINT_MSG:
@@ -966,17 +966,17 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			quitGame();
 			return;
 		case IDO_ACT_PLACE_ITEM:
-			item(ARG(1)).room = ARG(2);
-			item(ARG(1)).position.x = ARG(3);
-			item(ARG(1)).position.y = ARG(4);
+			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:
-			item(ARG(2)).picture = ARG(1);
+			getItem(ARG(2)).picture = ARG(1);
 			offset += 3;
 			break;
 		case IDO_ACT_RESET_PIC:
-			curRoom().curPicture = curRoom().picture;
+			getCurRoom().curPicture = getCurRoom().picture;
 			++offset;
 			break;
 		case IDO_ACT_GO_NORTH:
@@ -985,14 +985,14 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 		case IDO_ACT_GO_WEST:
 		case IDO_ACT_GO_UP:
 		case IDO_ACT_GO_DOWN: {
-			byte room = curRoom().connections[ARG(0) - IDO_ACT_GO_NORTH];
+			byte room = getCurRoom().connections[ARG(0) - IDO_ACT_GO_NORTH];
 
 			if (room == 0) {
 				printMessage(_messageIds.cantGoThere);
 				return;
 			}
 
-			curRoom().curPicture = curRoom().picture;
+			getCurRoom().curPicture = getCurRoom().picture;
 			_state.room = room;
 			return;
 		}
@@ -1005,7 +1005,7 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			++offset;
 			break;
 		case IDO_ACT_SET_ROOM_PIC:
-			room(ARG(1)).picture = room(ARG(1)).curPicture = ARG(2);
+			getRoom(ARG(1)).picture = getRoom(ARG(1)).curPicture = ARG(2);
 			offset += 3;
 			break;
 		default:
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index a230f0f..8064375 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -219,14 +219,14 @@ private:
 	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 &room(uint i) const;
-	Room &room(uint i);
-	const Room &curRoom() const;
-	Room &curRoom();
-	const Item &item(uint i) const;
-	Item &item(uint i);
-	const byte &var(uint i) const;
-	byte &var(uint i);
+	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;


Commit: d01da596ef596883847d6c3da2b714367e314a06
    https://github.com/scummvm/scummvm/commit/d01da596ef596883847d6c3da2b714367e314a06
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Add note about font

Changed paths:
    engines/adl/display.cpp



diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp
index d48296e..6342504 100644
--- a/engines/adl/display.cpp
+++ b/engines/adl/display.cpp
@@ -70,6 +70,7 @@ static const byte monoPalette[MONO_PALETTE_ENTRIES * 3] = {
 	0x00, 0xc0, 0x01
 };
 
+// Uppercase-only Apple II font (manually created).
 static const byte font[64][5] = {
 	{ 0x7c, 0x82, 0xba, 0xb2, 0x9c }, { 0xf8, 0x24, 0x22, 0x24, 0xf8 }, // @A
 	{ 0xfe, 0x92, 0x92, 0x92, 0x6c }, { 0x7c, 0x82, 0x82, 0x82, 0x44 }, // BC


Commit: ac39224958f6433a98da53606ce57ec8b3f123ee
    https://github.com/scummvm/scummvm/commit/ac39224958f6433a98da53606ce57ec8b3f123ee
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Limit keyboard input to 256 characters

Changed paths:
    engines/adl/adl.cpp



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 92b74d2..e9401cb 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -145,8 +145,10 @@ Common::String AdlEngine::inputString(byte prompt) const {
 				break;
 			};
 		} else {
-			s += b;
-			_display->printString(Common::String(b));
+			if (s.size() < 255) {
+				s += b;
+				_display->printString(Common::String(b));
+			}
 		}
 	}
 }


Commit: 9d65f901d08955a78841581a4c05b1139b3fb41a
    https://github.com/scummvm/scummvm/commit/9d65f901d08955a78841581a4c05b1139b3fb41a
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Clarify detection entry

Changed paths:
    engines/adl/detection.cpp



diff --git a/engines/adl/detection.cpp b/engines/adl/detection.cpp
index d96d94c..1a8c502 100644
--- a/engines/adl/detection.cpp
+++ b/engines/adl/detection.cpp
@@ -65,7 +65,7 @@ static const PlainGameDescriptor adlGames[] = {
 };
 
 static const AdlGameDescription gameDescriptions[] = {
-	{ // MD5 by waltervn
+	{ // Hi-Res Adventure #1: Mystery House - Apple II - 1987 PD release
 		{
 			"hires1", 0,
 			{


Commit: 349245d9b42dbe72f8aaa9c8a7a1fe09f60c9787
    https://github.com/scummvm/scummvm/commit/349245d9b42dbe72f8aaa9c8a7a1fe09f60c9787
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Fix regression in GMM saving/loading

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



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index e9401cb..8e374fa 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -302,8 +302,11 @@ Common::Error AdlEngine::run() {
 			if (shouldQuit())
 				break;
 
-			if (!doOneCommand(_roomCommands, verb, noun))
-				printMessage(_messageIds.dontUnderstand);
+			// 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);
 		}
 
 		if (_isRestoring) {
@@ -419,7 +422,7 @@ Common::Error AdlEngine::loadGameState(int slot) {
 	return Common::kNoError;
 }
 
-bool AdlEngine::canLoadGameStateCurrently() const {
+bool AdlEngine::canLoadGameStateCurrently() {
 	return _canRestoreNow;
 }
 
@@ -496,7 +499,7 @@ Common::Error AdlEngine::saveGameState(int slot, const Common::String &desc) {
 	return Common::kNoError;
 }
 
-bool AdlEngine::canSaveGameStateCurrently() const {
+bool AdlEngine::canSaveGameStateCurrently() {
 	if (!_canSaveNow)
 		return false;
 
@@ -506,11 +509,9 @@ bool AdlEngine::canSaveGameStateCurrently() const {
 	// "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) {
-		if (matchCommand(*cmd, _saveVerb, _saveNoun)) {
-			if (cmd->verb != _saveVerb || cmd->noun != _saveNoun)
-				return false;
-			return cmd->numCond == 0 && cmd->script[0] == IDO_ACT_SAVE;
-		}
+		uint offset;
+		if (matchCommand(*cmd, _saveVerb, _saveNoun, &offset))
+			return cmd->script[offset] == IDO_ACT_SAVE;
 	}
 
 	return false;
@@ -870,7 +871,8 @@ bool AdlEngine::matchCommand(const Command &command, byte verb, byte noun, uint
 		}
 	}
 
-	*actions = offset;
+	if (actions)
+		*actions = offset;
 
 	return true;
 }
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 8064375..4ea7566 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -198,9 +198,9 @@ private:
 	Common::Error run();
 	bool hasFeature(EngineFeature f) const;
 	Common::Error loadGameState(int slot);
-	bool canLoadGameStateCurrently() const;
+	bool canLoadGameStateCurrently();
 	Common::Error saveGameState(int slot, const Common::String &desc);
-	bool canSaveGameStateCurrently() const;
+	bool canSaveGameStateCurrently();
 
 	// Text output
 	void wordWrap(Common::String &str) const;


Commit: ce3af91ef865992fb744463f2bbb8dff8d0369cb
    https://github.com/scummvm/scummvm/commit/ce3af91ef865992fb744463f2bbb8dff8d0369cb
Author: Walter van Niftrik (walter at vanniftrik-it.nl)
Date: 2016-03-09T10:03:13+01:00

Commit Message:
ADL: Disable GMM restore on restart prompt

At the end of the game a restart command is executed
from the global command list. As we assumed that this
would not occur, we disable restoring on the restart
prompt, at least for now.

Changed paths:
    engines/adl/adl.cpp



diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 8e374fa..1ab74c3 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -946,16 +946,7 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
 			break;
 		case IDO_ACT_RESTART: {
 			_display->printString(_strings.playAgain);
-
-			// We allow restoring via GMM here
-			_canRestoreNow = true;
 			Common::String input = inputString();
-			_canRestoreNow = false;
-
-			// If the user restored with the GMM, we break off the restart
-			if (_isRestoring)
-				return;
-
 			if (input.size() == 0 || input[0] != APPLECHAR('N')) {
 				_isRestarting = true;
 				_display->clear(0x00);
@@ -1036,18 +1027,11 @@ bool AdlEngine::doOneCommand(const Commands &commands, byte verb, byte noun) {
 
 void AdlEngine::doAllCommands(const Commands &commands, byte verb, byte noun) {
 	Commands::const_iterator cmd;
-	bool oldIsRestoring = _isRestoring;
 
 	for (cmd = commands.begin(); cmd != commands.end(); ++cmd) {
 		uint offset = 0;
 		if (matchCommand(*cmd, verb, noun, &offset))
 			doActions(*cmd, noun, offset);
-
-		// We assume no restarts happen in this command group. This
-		// simplifies enabling GMM savegame loading on the restart
-		// prompt.
-		if (_isRestarting || _isRestoring != oldIsRestoring)
-			error("Unexpected restart action encountered");
 	}
 }
 


Commit: f1b6542fd2f705b771f8c46efb328b783f9c5d78
    https://github.com/scummvm/scummvm/commit/f1b6542fd2f705b771f8c46efb328b783f9c5d78
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2016-03-24T23:07:15+01:00

Commit Message:
Merge pull request #700 from waltervn/adl-engine

ADL: New engine

Changed paths:
  A engines/adl/adl.cpp
  A engines/adl/adl.h
  A engines/adl/configure.engine
  A engines/adl/detection.cpp
  A engines/adl/detection.h
  A engines/adl/display.cpp
  A engines/adl/display.h
  A engines/adl/hires1.cpp
  A engines/adl/hires1.h
  A engines/adl/module.mk









More information about the Scummvm-git-logs mailing list