diff --git a/base/plugins.cpp b/base/plugins.cpp
index 446c26e..1ec923c 100644
--- a/base/plugins.cpp
+++ b/base/plugins.cpp
@@ -157,6 +157,9 @@ public:
 		#if PLUGIN_ENABLED_STATIC(TUCKER)
 		LINK_PLUGIN(TUCKER)
 		#endif
+		#if PLUGIN_ENABLED_STATIC(DHE)
+		LINK_PLUGIN(DHE)
+		#endif
 
 		// Music plugins
 		// TODO: Use defines to disable or enable each MIDI driver as a
diff --git a/configure b/configure
index 2bd998c..5832321 100755
--- a/configure
+++ b/configure
@@ -96,6 +96,7 @@ add_engine sword2 "Broken Sword 2" yes
 add_engine tinsel "Tinsel" no
 add_engine touche "Touche: The Adventures of the Fifth Musketeer" yes
 add_engine tucker "Bud Tucker in Double Trouble" yes
+add_engine dhe "Dragon History" no
 
 
 #
diff --git a/engines/dh/barchive.cpp b/engines/dh/barchive.cpp
new file mode 100644
index 0000000..04c397d
--- /dev/null
+++ b/engines/dh/barchive.cpp
@@ -0,0 +1,250 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/str.h"
+#include "common/file.h"
+#include "common/stream.h"
+#include "common/debug.h"
+
+#include "dh/barchive.h"
+#include "dh/dh.h"
+
+namespace DH {
+
+const char BArchive::_signature[] = "BAR!";
+const char BArchive::_dfwSignature[] = "BS";
+
+/**
+ * @brief Simple RLE decompression
+ * @param dst Destination BArchive entry
+ * @param src ReadStream containing input data
+ *
+ * input: [uint16LE] uncompressed length, [uint16LE] compressed length,
+ *     [byte] stopper mark, [multiple bytes] data
+ */
+void decompress(BArchive::BAEntry &dst, Common::ReadStream &src) {
+	unsigned int length, i;
+	byte *tmp, stopper, last;
+
+	dst._length = src.readUint16LE();
+	dst._data = tmp = new byte[dst._length];
+	dst._uncompressed = 1;
+
+	// 2 bytes for compressed size, 1 for stopper mark
+	length = src.readUint16LE() - 3;
+	stopper = src.readByte();
+
+	debugC(5, kDHDebugResource, "Uncompressing %d bytes to %d", length,
+		dst._length);
+	debugC(5, kDHDebugResource, "Stopper mark is %02x", stopper);
+
+	for (last = src.readByte(); !src.eos(); last = src.readByte()) {
+		// inflate RLE block
+		if ((last == stopper) && (length = src.readByte())) {
+			last = src.readByte();
+			for (i = 0; i < length; i++) {
+				*tmp++ = last;
+			}
+		// just copy the byte
+		} else {
+			*tmp++ = last;
+		}
+	}
+}
+
+/**
+ * @brief DFW archive reader
+ * @param path Path to input file
+ *
+ * file format: header, index table, data
+ * header format: [uint16LE] archived file count, [uint16LE] index table
+ *     length, [2 bytes] signature "BS"
+ * index table format: [uint16LE] compressed data length, [uint32LE] data
+ *     offset from start of file
+ * data format: [uint16LE] uncompressed length, [uint16LE] compressed length
+ *     (not including uncompressed length), [byte] stopper mark,
+ *     [multiple bytes] data
+ */
+void BArchive::openDFW(const Common::String &path) {
+	byte *buf;
+	unsigned int i, pos, offset, length, tableCount, bufSize = 4096;
+	Common::File fr;
+
+	debugC(5, kDHDebugResource, "Retrying file %s as DFW:", path.c_str());
+
+	fr.open(path);
+	if (fr.isOpen()) {
+		debugC(5, kDHDebugResource, "OK");
+	} else {
+		debugC(5, kDHDebugResource, "Error");
+		return;
+	}
+
+	// read file header
+	debugC(5, kDHDebugResource, "Checking DFW signature:");
+
+	_itemCount = fr.readUint16LE();
+	tableCount = fr.readUint16LE();
+	buf = new byte[bufSize];
+	fr.read(buf, 2);
+
+	if (!memcmp(buf, _dfwSignature, 2)) {
+		debugC(5, kDHDebugResource, "OK");
+	} else {
+		debugC(5, kDHDebugResource, "Error");
+		_itemCount = 0;
+		return;
+	}
+
+	debugC(5, kDHDebugResource, "Archive stats: %d files, %d table items",
+		_itemCount, tableCount);
+
+	// read files from archive
+	_contents = new BAEntry[_itemCount];
+	_rawData = NULL;
+
+	for (i = 0; i < _itemCount; i++) {
+		// 2 extra bytes for uncompressed size not included
+		length = fr.readUint16LE() + 2;
+		offset = fr.readUint32LE();
+
+		pos = fr.pos();
+		debugC(5, kDHDebugResource, "Reading %d bytes at offset %d (pos %d)",
+			length, offset, pos);
+		fr.seek(offset);
+
+		Common::MemoryReadStream *comp = fr.readStream(length);
+		decompress(_contents[i], *comp);
+		delete comp;
+		fr.seek(pos);
+	}
+}
+
+/**
+ * @brief BArchive reader
+ * @param path Path to input file
+ *
+ * file format: header, data, footer
+ * header format: [4 bytes] signature "BAR!", [uint16LE] archived file count,
+ *     [uint32LE] footer offset from start of file
+ * data format: [multiple bytes]
+ * footer format: [uint32LE] offset from start of file (last entry is footer
+ *     offset again)
+ */
+void BArchive::openArchive(const Common::String &path) {
+	byte buf[4], crc, tmp;
+	unsigned int i, j, footerOffset, offset;
+	Common::File fr;
+
+	// free old memory
+	closeArchive();
+
+	debugC(5, kDHDebugResource, "Opening file %s as Barchive:",
+		path.c_str());
+
+	fr.open(path);
+	if (fr.isOpen()) {
+		debugC(5, kDHDebugResource, "OK");
+	} else {
+		debugC(5, kDHDebugResource, "Error");
+		return;
+	}
+
+	// read file header
+	debugC(5, kDHDebugResource, "Checking signature:");
+	fr.read(buf, 4);
+	if (!memcmp(buf, _signature, 4)) {
+		debugC(5, kDHDebugResource, "OK");
+	} else {
+		debugC(5, kDHDebugResource, "Error");
+		fr.close();
+		openDFW(path); // try DFW format instead
+		return;
+	}
+
+	_itemCount = fr.readUint16LE();
+	footerOffset = fr.readUint32LE();
+	debugC(5, kDHDebugResource, "Archive stats: %d files, %d data bytes total",
+		_itemCount, footerOffset - _headerSize);
+
+	// read files in archive
+	_rawData = new byte[footerOffset - _headerSize];
+	_contents = new BAEntry[_itemCount];
+
+	fr.read(_rawData, footerOffset - _headerSize);
+	Common::MemoryReadStream reader(_rawData, footerOffset - _headerSize);
+
+	for (i = 0; i < _itemCount; i++) {
+		offset = fr.readUint32LE() - _headerSize;
+		reader.seek(offset);
+		reader.readUint16LE(); // compressed size, not used here
+		_contents[i]._length = reader.readUint16LE();
+		// compression type flag, must be 0.
+		assert(!reader.readByte() && "Decompression not implemented!");
+		crc = reader.readByte(); // CRC checksum of the file
+
+		_contents[i]._data = _rawData + offset + 6;
+		_contents[i]._uncompressed = 0;
+
+		// CRC check
+		for (tmp = 0, j = 0; j < _contents[i]._length; j++) {
+			tmp ^= _contents[i]._data[j];
+		}
+
+		assert(tmp == crc && "CRC check failed");
+	}
+
+	// last footer entry points back at the start of the footer.
+	assert(fr.readUint32LE() == footerOffset && "Last footer entry doesn't "
+		"match footer offset");
+}
+
+/**
+ * @brief Memory cleanup
+ */
+void BArchive::closeArchive(void) {
+	unsigned int i;
+
+	if (!_contents) {
+		return;
+	}
+
+	for (i = 0; i < _itemCount; i++) {
+		// _uncompressed == 0 means that _data points somewhere into _rawData
+		// otherwise it's a buffer allocated separately
+		if (_contents[i]._uncompressed) {
+			delete[] _contents[i]._data;
+		}
+	}
+
+	delete[] _contents;
+	delete[] _rawData;
+
+	_contents = NULL;
+	_rawData = NULL;
+	_itemCount = 0;
+}
+
+} // End of namespace DH
diff --git a/engines/dh/barchive.h b/engines/dh/barchive.h
new file mode 100644
index 0000000..db7f1fb
--- /dev/null
+++ b/engines/dh/barchive.h
@@ -0,0 +1,71 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef BARCHIVE_H
+#define BARCHIVE_H
+
+#include "common/str.h"
+
+namespace DH {
+
+class BArchive {
+public:
+	struct BAEntry {
+		unsigned int _length;
+		const byte *_data;
+		int _uncompressed; //!< whether data points into rawdata buffer
+	};
+
+private:
+	// file header data
+	static const char _signature[];
+	static const char _dfwSignature[];
+	static const int _headerSize = 10;
+	static const int _dfwHeaderSize = 6;
+	static const int _dfwTableSize = 6;
+
+	BAEntry *_contents;
+	unsigned char *_rawData; //!< raw data read from file, may be NULL
+	unsigned int _itemCount; //!< size of _contents
+
+	void openDFW(const Common::String &path);
+
+public:
+	BArchive() : _contents(NULL), _rawData(NULL), _itemCount(0) { }
+	~BArchive() { closeArchive(); }
+
+	void openArchive(const Common::String &path);
+	void closeArchive(void);
+
+	const BAEntry *operator[](unsigned int i) const {
+		return i < _itemCount ? _contents + i : NULL;
+	}
+
+	unsigned int size() const { return _itemCount; }
+};
+
+} // End of namespace DH
+
+#endif
diff --git a/engines/dh/detection.cpp b/engines/dh/detection.cpp
new file mode 100644
index 0000000..6ec1691
--- /dev/null
+++ b/engines/dh/detection.cpp
@@ -0,0 +1,159 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "dh/dh.h"
+ 
+#include "base/plugins.h"
+#include "engines/metaengine.h"
+#include "engines/advancedDetector.h"
+ 
+static const PlainGameDescriptor gameList[] = {
+	{ "dh", "Dragon History" },
+	{ 0, 0 }
+};
+
+const ADGameDescription adGameDescs[] = {
+	{
+		"dh",
+		0,
+		{
+			{"HRA.DFW", 0, "a461d1b1ffbbeb8128bfbcb13e8aa406", -1},
+			{"INIT.DFW", 0, "9921c8f0045679a8f37eca8d41c5ec02", -1},
+			{NULL, 0, NULL, 0}
+		},
+		Common::CZ_CZE,
+		Common::kPlatformPC,
+		ADGF_NO_FLAGS
+	},
+
+	{
+		"dh",
+		0,
+		{
+			{"HRA.DFW", 0, "a461d1b1ffbbeb8128bfbcb13e8aa406", -1},
+			{"INIT.DFW", 0, "b890a5aeebaf16af39219cba2416b0a3", -1},
+			{NULL, 0, NULL, 0}
+		},
+		Common::EN_ANY,
+		Common::kPlatformPC,
+		ADGF_NO_FLAGS
+	},
+
+	{
+		"dh",
+		0,
+		{
+			{"HRA.DFW", 0, "a461d1b1ffbbeb8128bfbcb13e8aa406", -1},
+			{"INIT.DFW", 0, "76b9b78a8a8809a240acc395df4d0715", -1},
+			{NULL, 0, NULL, 0}
+		},
+		Common::PL_POL,
+		Common::kPlatformPC,
+		ADGF_NO_FLAGS
+	},
+
+	AD_TABLE_END_MARKER
+};
+
+const ADParams detectionParams = {
+	// Pointer to ADGameDescription or its superset structure
+	(const byte *)adGameDescs,
+	// Size of that superset structure
+	sizeof(ADGameDescription),
+	// Number of bytes to compute MD5 sum for
+	4096,
+	// List of all engine targets
+	gameList,
+	// Structure for autoupgrading obsolete targets
+	0,
+	// Name of single gameid (optional)
+	0,
+	// List of files for file-based fallback detection (optional)
+	0,
+	// Flags
+	0
+};
+
+class DHMetaEngine : public AdvancedMetaEngine {
+public:
+	DHMetaEngine() : AdvancedMetaEngine(detectionParams) {}
+
+	virtual const char *getName() const {
+		return "Dragon History game engine";
+	}
+
+	virtual const char *getOriginalCopyright() const {
+		return "Copyright (C) 1995 NoSense";
+	}
+
+	virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
+	virtual bool hasFeature(MetaEngineFeature f) const;
+	virtual SaveStateList listSaves(const char *target) const;
+	virtual int getMaximumSaveSlot() const;
+	virtual void removeSaveState(const char *target, int slot) const;
+};
+
+bool DHMetaEngine::hasFeature(MetaEngineFeature f) const {
+	return false;
+/*
+		(f == kSupportsListSaves) ||
+		(f == kSupportsLoadingDuringStartup) ||
+		(f == kSupportsDeleteSave);
+*/
+}
+
+bool DH::DHEngine::hasFeature(EngineFeature f) const {
+	return false;
+/*
+		(f == kSupportsRTL) ||
+		(f == kSupportsLoadingDuringRuntime) ||
+		(f == kSupportsSavingDuringRuntime);
+*/
+}
+
+bool DHMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
+	if (desc) {
+		*engine = new DH::DHEngine(syst, desc);
+	}
+	return desc != 0;
+}
+
+SaveStateList DHMetaEngine::listSaves(const char *target) const {
+
+}
+
+int DHMetaEngine::getMaximumSaveSlot() const {
+	return 0;
+}
+
+void DHMetaEngine::removeSaveState(const char *target, int slot) const {
+
+}
+
+#if PLUGIN_ENABLED_DYNAMIC(DHE)
+	REGISTER_PLUGIN_DYNAMIC(DHE, PLUGIN_TYPE_ENGINE, DHMetaEngine);
+#else
+	REGISTER_PLUGIN_STATIC(DHE, PLUGIN_TYPE_ENGINE, DHMetaEngine);
+#endif
diff --git a/engines/dh/dh.cpp b/engines/dh/dh.cpp
new file mode 100644
index 0000000..02923e0
--- /dev/null
+++ b/engines/dh/dh.cpp
@@ -0,0 +1,84 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/scummsys.h"
+#include "common/system.h"
+ 
+#include "common/events.h" // for getEventManager()
+#include "common/config-manager.h"
+#include "common/file.h"
+#include "common/fs.h"
+ 
+#include "dh/dh.h"
+#include "dh/barchive.h"
+ 
+namespace DH {
+ 
+DHEngine::DHEngine(OSystem *syst, const ADGameDescription *gameDesc) 
+ : Engine(syst) {
+	// 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 init().
+ 
+	// Do not initialize graphics here
+ 
+	// However this is the place to specify all default directories
+	//Common::File::addDefaultDirectory(_gameDataPath + "sound/");
+ 
+	// Here is the right place to set up the engine specific debug levels
+	Common::addDebugChannel(kDHDebugResource, "resource", "Resource management debug channel");
+ 
+	// Don't forget to register your random source
+	//syst->getEventManager()->registerRandomSource(_rnd, "dh");
+}
+ 
+DHEngine::~DHEngine() {
+	// Dispose your resources here
+ 
+	// Remove all of our debug levels here
+	Common::clearAllDebugChannels();
+}
+ 
+int DHEngine::init() {
+	// Initialize graphics using following:
+	initGraphics(320, 200, false);
+ 
+	return 0;
+}
+ 
+int DHEngine::go() {
+	// Your main even loop should be (invoked from) here.
+	//printf("DHEngine::go: Hello, World!\n");
+ 
+	return 0;
+}
+
+Common::Error DHEngine::run() {
+	init();
+	go();
+	return Common::kNoError;
+}
+ 
+} // End of namespace DH
diff --git a/engines/dh/dh.h b/engines/dh/dh.h
new file mode 100644
index 0000000..3741b70
--- /dev/null
+++ b/engines/dh/dh.h
@@ -0,0 +1,54 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef DH_H
+#define DH_H
+
+#include "common/scummsys.h"
+
+#include "engines/engine.h"
+#include "engines/advancedDetector.h"
+
+namespace DH {
+
+class DHEngine : public Engine {
+public:
+	DHEngine(OSystem *syst, const ADGameDescription *gameDesc);
+	~DHEngine();
+
+	int init();
+	int go();
+	Common::Error run();
+
+	bool hasFeature(Engine::EngineFeature f) const;
+};
+
+enum {
+	kDHDebugResource = 1 << 0
+};
+
+} // End of namespace DH
+
+#endif
diff --git a/engines/dh/module.mk b/engines/dh/module.mk
new file mode 100644
index 0000000..e05e580
--- /dev/null
+++ b/engines/dh/module.mk
@@ -0,0 +1,15 @@
+MODULE := engines/dh
+ 
+MODULE_OBJS := \
+	dh.o detection.o barchive.o
+ 
+MODULE_DIRS += \
+	engines/dh
+ 
+# This module can be built as a plugin
+ifeq ($(ENABLE_DHE), DYNAMIC_PLUGIN)
+PLUGIN := 1
+endif
+ 
+# Include common rules 
+include $(srcdir)/rules.mk
diff --git a/engines/engines.mk b/engines/engines.mk
index 8d7d8de..ca5acf8 100644
--- a/engines/engines.mk
+++ b/engines/engines.mk
@@ -141,3 +141,8 @@ ifdef ENABLE_TUCKER
 DEFINES += -DENABLE_TUCKER=$(ENABLE_TUCKER)
 MODULES += engines/tucker
 endif
+
+ifdef ENABLE_DHE
+DEFINES += -DENABLE_DHE=$(ENABLE_DHE)
+MODULES += engines/dh
+endif
