[Scummvm-cvs-logs] SF.net SVN: scummvm: [22754] scummvm/trunk/engines/gob

drmccoy at users.sourceforge.net drmccoy at users.sourceforge.net
Mon May 29 11:26:02 CEST 2006


Revision: 22754
Author:   drmccoy
Date:     2006-05-29 11:24:52 -0700 (Mon, 29 May 2006)
ViewCVS:  http://svn.sourceforge.net/scummvm/?rev=22754&view=rev

Log Message:
-----------
- More GOB2 map conversions
- Added Music_Dummy (for --music-driver=null)
- Implemented IMDs. That took longer than I expected...
  On the bright side, Ween's intro now plays more correctly

Modified Paths:
--------------
    scummvm/trunk/engines/gob/anim.h
    scummvm/trunk/engines/gob/dataio.cpp
    scummvm/trunk/engines/gob/dataio.h
    scummvm/trunk/engines/gob/game.cpp
    scummvm/trunk/engines/gob/game.h
    scummvm/trunk/engines/gob/gob.cpp
    scummvm/trunk/engines/gob/goblin.cpp
    scummvm/trunk/engines/gob/goblin.h
    scummvm/trunk/engines/gob/goblin_v1.cpp
    scummvm/trunk/engines/gob/goblin_v2.cpp
    scummvm/trunk/engines/gob/inter.cpp
    scummvm/trunk/engines/gob/inter.h
    scummvm/trunk/engines/gob/inter_v1.cpp
    scummvm/trunk/engines/gob/inter_v2.cpp
    scummvm/trunk/engines/gob/map.cpp
    scummvm/trunk/engines/gob/map.h
    scummvm/trunk/engines/gob/map_v1.cpp
    scummvm/trunk/engines/gob/map_v2.cpp
    scummvm/trunk/engines/gob/module.mk
    scummvm/trunk/engines/gob/mult.cpp
    scummvm/trunk/engines/gob/mult.h
    scummvm/trunk/engines/gob/mult_v2.cpp
    scummvm/trunk/engines/gob/music.cpp
    scummvm/trunk/engines/gob/music.h
    scummvm/trunk/engines/gob/scenery.cpp
    scummvm/trunk/engines/gob/scenery.h
    scummvm/trunk/engines/gob/sound.cpp
    scummvm/trunk/engines/gob/util.cpp

Added Paths:
-----------
    scummvm/trunk/engines/gob/scenery_v1.cpp
    scummvm/trunk/engines/gob/scenery_v2.cpp
Modified: scummvm/trunk/engines/gob/anim.h
===================================================================
--- scummvm/trunk/engines/gob/anim.h	2006-05-29 18:06:02 UTC (rev 22753)
+++ scummvm/trunk/engines/gob/anim.h	2006-05-29 18:24:52 UTC (rev 22754)
@@ -23,6 +23,8 @@
 #ifndef GOB_ANIM_H
 #define GOB_ANIM_H
 
+#include "gob/video.h"
+
 namespace Gob {
 
 class Anim {

Modified: scummvm/trunk/engines/gob/dataio.cpp
===================================================================
--- scummvm/trunk/engines/gob/dataio.cpp	2006-05-29 18:06:02 UTC (rev 22753)
+++ scummvm/trunk/engines/gob/dataio.cpp	2006-05-29 18:24:52 UTC (rev 22754)
@@ -317,6 +317,10 @@
 	file_getHandle(handle)->seek(pos, from);
 }
 
+int32 DataIO::getPos(int16 handle) {
+	return file_getHandle(handle)->pos();
+}
+
 int32 DataIO::getDataSize(const char *name) {
 	char buf[128];
 	int32 chunkSz;

Modified: scummvm/trunk/engines/gob/dataio.h
===================================================================
--- scummvm/trunk/engines/gob/dataio.h	2006-05-29 18:06:02 UTC (rev 22753)
+++ scummvm/trunk/engines/gob/dataio.h	2006-05-29 18:24:52 UTC (rev 22754)
@@ -55,6 +55,7 @@
 	int16 openData(const char *path, Common::File::AccessMode mode = Common::File::kFileReadMode);
 	int32 readData(int16 handle, char *buf, int16 size);
 	void seekData(int16 handle, int32 pos, int16 from);
+	int32 getPos(int16 handle);
 	int32 getDataSize(const char *name);
 	char *getData(const char *path);
 	char *getSmallData(const char *path);

Modified: scummvm/trunk/engines/gob/game.cpp
===================================================================
--- scummvm/trunk/engines/gob/game.cpp	2006-05-29 18:06:02 UTC (rev 22753)
+++ scummvm/trunk/engines/gob/game.cpp	2006-05-29 18:24:52 UTC (rev 22754)
@@ -39,6 +39,7 @@
 #include "gob/goblin.h"
 #include "gob/cdrom.h"
 #include "gob/music.h"
+#include "gob/palanim.h"
 
 namespace Gob {
 
@@ -107,13 +108,28 @@
 		_curTotFileArray[i][0] = 0;
 	}
 
-	warning("GOB2 Stub! _byte_2FC9B, _word_2FC9C, _word_2FC9E, _word_2E51F, _off_2E51B, _off_2E517");
+	_imdFile = 0;
+	_curImdFile[0] = 0;
+	_imdX = 0;
+	_imdY = 0;
+	_imdFrameDataSize = 0;
+	_imdVidBufferSize = 0;
+	_imdFrameData = 0;
+	_imdVidBuffer = 0;
+
+	warning("GOB2 Stub! _byte_2FC82, _byte_2FC83, _word_2FC80");
+	_byte_2FC82 = 0;
+	_byte_2FC83 = 0;
+	_word_2FC80 = 0;
+
+	warning("GOB2 Stub! _byte_2FC9B, _word_2FC9C, _word_2FC9E, _word_2E51F, _off_2E51B, _off_2E517, _dword_2F2B6");
 	_byte_2FC9B = 0;
 	_word_2FC9C = 0;
 	_word_2FC9E = 0;
 	_word_2E51F = 0;
 	_off_2E51B = 0;
 	_off_2E517 = 0;
+	_dword_2F2B6 = 0;
 }
 
 char *Game::loadExtData(int16 itemId, int16 *pResWidth, int16 *pResHeight) {
@@ -1650,6 +1666,7 @@
 	}
 }
 
+// "DEVinitscreen"
 void Game::sub_ADD2(void) {
 	_word_2FC9C = 0;
 	_word_2FC9E = 0;
@@ -1687,6 +1704,7 @@
 	}*/
 }
 
+// "DEVclosescreen"
 void Game::sub_BB28(void) {
 	_vm->_draw->freeSprite(23);
 	_vm->_video->freeSurfDesc(_vm->_draw->_cursorBack);
@@ -1748,4 +1766,832 @@
 	return soundDesc;
 }
 
+int8 Game::openImd(const char *path, int16 x, int16 y, int16 repeat, int16 flags) {
+	int i;
+	int j;
+	const char *src;
+	byte *vidMem;
+	Video::SurfaceDesc *surfDesc;
+
+	if (path[0] != 0) {
+		if (_imdFile == 0)
+			_curImdFile[0] = 0;
+
+		src = strrchr(path, '\\');
+		src = src == 0 ? path : src+1;
+
+		if (strcmp(_curImdFile, src) != 0) {
+			closeImd();
+			_imdFile = loadImdFile(path, 0, 2);
+			if (_imdFile == 0)
+				return 0;
+
+			_imdX = _imdFile->x;
+			_imdY = _imdFile->y;
+			strcpy(_curImdFile, src);
+			_imdFrameData = new byte[_imdFrameDataSize + 1000];
+			_imdVidBuffer = new byte[_imdVidBufferSize + 1000];
+			memset(_imdFrameData, 0, _imdFrameDataSize + 1000);
+			memset(_imdVidBuffer, 0, _imdVidBufferSize + 1000);
+
+			if (_vm->_video->_extraMode) {
+				_byte_2FC83 = (flags & 0x80) ? 1 : 0;
+				if (!(_imdFile->field_E & 0x100) || (_imdFile->field_E & 0x2000)) {
+					setImdXY(_imdFile, 0, 0);
+					_imdFile->surfDesc =
+						_vm->_video->initSurfDesc(0x13, _imdFile->width, _imdFile->height, 0);
+				} else {
+					if (_byte_2FC82 == 0)
+						_imdFile->surfDesc = _vm->_draw->_spritesArray[21];
+					else
+						_imdFile->surfDesc = _vm->_draw->_spritesArray[20];
+					if ((x != -1) || (y != -1)) {
+						_imdX = x != -1 ? x : _imdX;
+						_imdY = y != -1 ? y : _imdY;
+						setImdXY(_imdFile, _imdX, _imdY);
+					}
+				}
+				if (flags & 0x40) {
+					_imdX = x != -1 ? x : _imdX;
+					_imdY = y != -1 ? y : _imdY;
+					if (_vm->_video->_extraMode && ((_imdFile->surfDesc->vidMode & 0x7F) == 0x13)) {
+						surfDesc = _vm->_video->initSurfDesc(0x13, _imdFile->width, _imdFile->height, 0);
+						_vm->_video->drawSprite(_vm->_draw->_spritesArray[21], surfDesc, _imdX, _imdY,
+								_imdX + _imdFile->width - 1, _imdY + _imdFile->height - 1, 0, 0, 0);
+						vidMem = _imdFile->surfDesc->vidPtr;
+						for (i = 0; i < _imdFile->height; i++)
+							for (j = 0; j < _imdFile->width; j++, vidMem++) {
+								*(vidMem) = *(surfDesc->vidPtr
+										+ (j / 4)
+										+ (surfDesc->width / 4 * i)
+										+ (surfDesc->reserved2 * (j & 3)));
+							}
+						_vm->_video->freeSurfDesc(surfDesc);
+					}
+				}
+			} else {
+				if ((x != -1) || (y != -1)) {
+					_imdX = x != -1 ? x : _imdX;
+					_imdY = y != -1 ? y : _imdY;
+					setImdXY(_imdFile, _imdX, _imdY);
+				}
+				_byte_2FC83 = (flags & 0x80) ? 1 : 0;
+				if (_byte_2FC83 == 0)
+					_imdFile->surfDesc = _vm->_draw->_spritesArray[21];
+				else
+					_imdFile->surfDesc = _vm->_draw->_spritesArray[20];
+			}
+		}
+	}
+
+	if (_imdFile == 0)
+		return 0;
+
+	if (repeat == -1) {
+		closeImd();
+		return 0;
+	}
+
+	_imdX = x != -1 ? x : _imdX;
+	_imdY = y != -1 ? y : _imdY;
+
+	WRITE_VAR(7, _imdFile->framesCount);
+
+	return 1;
+}
+
+void Game::closeImd(void) {
+	if (_imdFile == 0)
+		return;
+
+	if ((_imdFile->surfDesc != _vm->_draw->_spritesArray[20]) &&
+			(_imdFile->surfDesc != _vm->_draw->_spritesArray[21]))
+		_vm->_video->freeSurfDesc(_imdFile->surfDesc);
+
+	finishImd(_imdFile);
+
+	delete[] _imdFrameData;
+	delete[] _imdVidBuffer;
+	_imdFrameData = 0;
+	_imdVidBuffer = 0;
+
+	_imdFile = 0;
+}
+
+void Game::finishImd(Game::Imd *imdPtr) {
+	if (imdPtr == 0)
+		return;
+
+/*
+	if (dword_31345 != 0) {
+		_vm->_sound->stopSound(0);
+		dword_31345 = 0;
+		delete off_31461;
+		byte_31344 = 0;
+	}
+*/
+
+	_vm->_dataio->closeData(imdPtr->fileHandle);
+
+	if (imdPtr->frameCoords != 0)
+		delete[] imdPtr->frameCoords;
+	if (imdPtr->palette != 0)
+		delete[] imdPtr->palette;
+	if (imdPtr->framesPos != 0)
+		delete[] imdPtr->framesPos;
+
+	delete imdPtr;
+	imdPtr = 0;
+}
+
+// flagsBit: 0 = read and set palette
+//           1 = read palette
+Game::Imd *Game::loadImdFile(const char *path, Video::SurfaceDesc *surfDesc, int8 flags) {
+	int i;
+	Imd *imdPtr;
+	int16 handle;
+	int16 setAllPalBak;
+	char buf[18];
+	Video::Color *palBak;
+
+	int32 byte_31449 = 0;
+	int32 byte_3144D = 0;
+
+	buf[0] = 0;
+	strcpy(buf, path);
+	strcat(buf, ".IMD");
+
+	handle = _vm->_dataio->openData(buf);
+
+	if (handle < 0) {
+		warning("Can't open IMD \"%s\"", buf);
+		return 0;
+	}
+
+	imdPtr = new Imd;
+	memset(imdPtr, 0, sizeof(Imd));
+
+	imdPtr->palette = 0;
+
+	_vm->_dataio->readData(handle, buf, 18);
+
+	// "fileHandle" holds the major version while loading
+	imdPtr->fileHandle = READ_LE_UINT16(buf);
+	imdPtr->verMin = READ_LE_UINT16(buf + 2);
+	imdPtr->framesCount = READ_LE_UINT16(buf + 4);
+	imdPtr->x = READ_LE_UINT16(buf + 6);
+	imdPtr->y = READ_LE_UINT16(buf + 8);
+	imdPtr->width = READ_LE_UINT16(buf + 10);
+	imdPtr->height = READ_LE_UINT16(buf + 12);
+	imdPtr->field_E = READ_LE_UINT16(buf + 14);
+	imdPtr->curFrame = READ_LE_UINT16(buf + 16);
+
+	if (imdPtr->fileHandle != 0)
+		imdPtr->verMin = 0;
+
+	if ((imdPtr->verMin & 0xFF) < 2) {
+		warning("IMD version incorrect (%d,%d)", imdPtr->fileHandle, imdPtr->verMin);
+		_vm->_dataio->closeData(handle);
+		delete imdPtr;
+		return 0;
+	}
+
+	imdPtr->surfDesc = surfDesc;
+	imdPtr->framesPos = 0;
+	imdPtr->firstFramePos = imdPtr->curFrame;
+	
+	if (flags & 3) {
+		imdPtr->palette = new Video::Color[256];
+		_vm->_dataio->readData(handle, (char *) imdPtr->palette, 768);
+	} else {
+		_vm->_dataio->seekData(handle, 768, 1);
+		imdPtr->palette = 0;
+	}
+	if ((flags & 3) == 1) {
+		palBak = _vm->_global->_pPaletteDesc->vgaPal;
+		setAllPalBak = _vm->_global->_setAllPalette;
+		_vm->_global->_pPaletteDesc->vgaPal = imdPtr->palette;
+		_vm->_global->_setAllPalette = 1;
+		_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
+		_vm->_global->_setAllPalette = setAllPalBak;
+		_vm->_global->_pPaletteDesc->vgaPal = palBak;
+	}
+
+	if ((imdPtr->verMin & 0xFF) >= 3) {
+		_vm->_dataio->readData(handle, buf, 2);
+		imdPtr->stdX = READ_LE_UINT16(buf);
+		if (imdPtr->stdX > 1) {
+			warning("IMD ListI incorrect (%d)", imdPtr->stdX);
+			_vm->_dataio->closeData(handle);
+			delete imdPtr;
+			return 0;
+		}
+		if(imdPtr->stdX != 0) {
+			_vm->_dataio->readData(handle, buf, 8);
+			imdPtr->stdX = READ_LE_UINT16(buf);
+			imdPtr->stdY = READ_LE_UINT16(buf + 2);
+			imdPtr->stdWidth = READ_LE_UINT16(buf + 4);
+			imdPtr->stdHeight = READ_LE_UINT16(buf + 6);
+		} else
+			imdPtr->stdX = -1;
+	} else
+		imdPtr->stdX = -1;
+
+	if ((imdPtr->verMin & 0xFF) >= 4) {
+		_vm->_dataio->readData(handle, buf, 4);
+		byte_31449 = READ_LE_UINT32(buf);
+		imdPtr->framesPos = byte_31449 == 0 ? 0 : new int32[imdPtr->framesCount];
+	} else
+		imdPtr->framesPos = 0;
+
+	if (imdPtr->verMin & 0x8000) {
+		_vm->_dataio->readData(handle, buf, 4);
+		byte_3144D = READ_LE_UINT32(buf);
+	}
+
+	if (imdPtr->verMin & 0x4000) {
+		// loc_29C4F
+		error("GOB2 Stub! loadImdFile, imdPtr->verMin & 0x4000");
+		// Sound stuff, I presume...
+	}
+
+	if (imdPtr->verMin & 0x2000) {
+		_vm->_dataio->readData(handle, buf, 4);
+		imdPtr->frameDataSize = READ_LE_UINT16(buf);
+		imdPtr->vidBufferSize = READ_LE_UINT16(buf + 2);
+	} else {
+		imdPtr->frameDataSize = imdPtr->width * imdPtr->height + 1000;
+		imdPtr->vidBufferSize = imdPtr->width * imdPtr->height + 1000;
+	}
+
+	if (imdPtr->framesPos != 0) {
+		_vm->_dataio->seekData(handle, byte_31449, 0);
+		for (i = 0; i < imdPtr->framesCount; i++) {
+			_vm->_dataio->readData(handle, buf, 4);
+			imdPtr->framesPos[i] = READ_LE_UINT32(buf);
+		}
+	}
+
+	if (imdPtr->verMin & 0x8000) {
+		_vm->_dataio->seekData(handle, byte_3144D, 0);
+		imdPtr->frameCoords = new ImdCoord[imdPtr->framesCount];
+		for (i = 0; i < imdPtr->framesCount; i++) {
+			_vm->_dataio->readData(handle, buf, 8);
+			imdPtr->frameCoords[i].left = READ_LE_UINT16(buf);
+			imdPtr->frameCoords[i].top = READ_LE_UINT16(buf + 2);
+			imdPtr->frameCoords[i].right = READ_LE_UINT16(buf + 4);
+			imdPtr->frameCoords[i].bottom = READ_LE_UINT16(buf + 6);
+		}
+	} else
+		imdPtr->frameCoords = 0;
+
+	_vm->_dataio->seekData(handle, imdPtr->firstFramePos, 0);
+	imdPtr->curFrame = 0;
+	imdPtr->fileHandle = handle;
+	imdPtr->filePos = imdPtr->firstFramePos;
+	_imdFrameDataSize = imdPtr->frameDataSize;
+	_imdVidBufferSize = imdPtr->vidBufferSize;
+	if (flags & 0x80) {
+		imdPtr->verMin |= 0x1000;
+		warning("GOB2 Stub! loadImdFile(), flags & 0x80");
+	}
+
+	return imdPtr;
+}
+
+void Game::setImdXY(Game::Imd *imdPtr, int16 x, int16 y) {
+	int i;
+
+	if (imdPtr->stdX != -1) {
+		imdPtr->stdX = imdPtr->stdX - imdPtr->x + x;
+		imdPtr->stdY = imdPtr->stdY - imdPtr->y + y;
+	}
+	
+	if (imdPtr->frameCoords != 0) {
+		for (i = 0; i < imdPtr->framesCount; i++) {
+			imdPtr->frameCoords[i].left -= imdPtr->frameCoords[i].left - imdPtr->x + x;
+			imdPtr->frameCoords[i].top -= imdPtr->frameCoords[i].top - imdPtr->y + y;
+			imdPtr->frameCoords[i].right -= imdPtr->frameCoords[i].right - imdPtr->x + x;
+			imdPtr->frameCoords[i].bottom -= imdPtr->frameCoords[i].bottom - imdPtr->y + y;
+		}
+	}
+
+	imdPtr->x = x;
+	imdPtr->y = y;
+}
+
+void Game::playImd(int16 frame, int16 arg_2, int16 arg_4, int16 arg_6, int16 arg_8, int16 lastFrame) {
+	int16 var_1;
+	int16 var_4 = 0;
+	byte *vidMemBak;
+	Video::SurfaceDesc *surfDescBak;
+	Video::SurfaceDesc frontSurfBak;
+
+	int8 byte_31344 = 0;
+
+	if ((frame < 0) || (frame > lastFrame))
+		return;
+
+	if ((frame == arg_8) || ((frame == lastFrame) && (arg_2 == 8))) { // loc_1C3F0
+		var_1 = 1;
+		_vm->_draw->_applyPal = 0;
+		if (arg_2 >= 4) {
+			if (arg_4 != -1)
+				memcpy( ((char *) (_vm->_global->_pPaletteDesc->vgaPal)) + arg_4 * 3,
+						((char *) (_imdFile->palette)) + arg_4 * 3, (arg_6 - arg_4 + 1) * 3);
+			else
+				memcpy((char *) _vm->_global->_pPaletteDesc->vgaPal, (char *) _imdFile->palette, 768);
+		}
+	} else
+		var_1 = 0;
+
+	if ((var_1 == 1) && (arg_2 == 8) && (_byte_2FC83 != 0))
+		_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
+
+	if (_vm->_video->_extraMode && (_imdFile->surfDesc->vidMode == 0x13)) {
+		if ((_byte_2FC82 != 0) && (_word_2FC80 == _vm->_draw->_spritesArray[20]->vidPtr)) {
+			vidMemBak = _vm->_draw->_spritesArray[20]->vidPtr;
+			_vm->_draw->_spritesArray[20]->vidPtr = _vm->_draw->_spritesArray[21]->vidPtr;
+			var_4 = viewImd(_imdFile, frame);
+			_vm->_draw->_spritesArray[20]->vidPtr = vidMemBak;
+		} else
+			var_4 = viewImd(_imdFile, frame);
+		if (_byte_2FC82 == 0) {
+			if ((_imdFile->frameCoords == 0) || (_imdFile->frameCoords[frame].left == -1))
+				_vm->_draw->invalidateRect(_imdX, _imdY,
+						_imdX + _imdFile->width - 1, _imdY + _imdFile->height - 1);
+			else
+				_vm->_draw->invalidateRect(_imdFile->frameCoords[frame].left,
+						_imdFile->frameCoords[frame].top, _imdFile->frameCoords[frame].right,
+						_imdFile->frameCoords[frame].bottom);
+		}
+	} else {
+		if ((_imdFile->field_E & 0x100) && (_vm->_video->_extraMode) &&
+				(_byte_2FC82 != 0) && (sub_2C825(_imdFile) & 0x8000) && (_byte_2FC83 == 0)) {
+			surfDescBak = _imdFile->surfDesc;
+			if (_word_2FC80 == _vm->_draw->_spritesArray[20]->vidPtr)
+				_imdFile->surfDesc = _vm->_draw->_spritesArray[21];
+			else
+				_imdFile->surfDesc = _vm->_draw->_spritesArray[20];
+			setImdXY(_imdFile, _imdX, _imdY);
+			var_4 = viewImd(_imdFile, frame);
+			_imdFile->surfDesc = surfDescBak;
+			setImdXY(_imdFile, 0, 0);
+		} else {
+			var_4 = viewImd(_imdFile, frame);
+			if (!(var_4 & 0x800)) {
+				if (_byte_2FC83 == 0) {
+					if (_vm->_video->_extraMode) {
+						if (_byte_2FC82 == 0) {
+							memcpy((char *) &frontSurfBak, (char *) &_vm->_draw->_frontSurface,
+									sizeof(Video::SurfaceDesc));
+							memcpy((char *) &_vm->_draw->_frontSurface, (char *) &_vm->_draw->_spritesArray[21],
+									sizeof(Video::SurfaceDesc));
+							imdDrawFrame(_imdFile, frame, _imdX, _imdY);
+							memcpy((char *) &_vm->_draw->_frontSurface, (char *) &frontSurfBak,
+									sizeof(Video::SurfaceDesc));
+							if ((_imdFile->frameCoords == 0) || (_imdFile->frameCoords[frame].left == -1))
+								_vm->_draw->invalidateRect(_imdX, _imdY, _imdX + _imdFile->width - 1,
+										_imdY + _imdFile->height - 1);
+							else
+								_vm->_draw->invalidateRect(_imdFile->frameCoords[frame].left,
+										_imdFile->frameCoords[frame].top, _imdFile->frameCoords[frame].right,
+										_imdFile->frameCoords[frame].bottom);
+						} else {
+							if (_word_2FC80 == _vm->_draw->_spritesArray[20]->vidPtr) { // loc_1C68D
+								memcpy((char *) &frontSurfBak, (char *) &_vm->_draw->_frontSurface,
+										sizeof(Video::SurfaceDesc));
+								memcpy((char *) &_vm->_draw->_frontSurface, (char *) &_vm->_draw->_spritesArray[21],
+										sizeof(Video::SurfaceDesc));
+								imdDrawFrame(_imdFile, frame, _imdX, _imdY);
+								memcpy((char *) &_vm->_draw->_frontSurface, (char *) &frontSurfBak,
+										sizeof(Video::SurfaceDesc));
+							} else
+								imdDrawFrame(_imdFile, frame, _imdX, _imdY);
+						}
+					} else {
+						if ((_imdFile->frameCoords == 0) || (_imdFile->frameCoords[frame].left == -1))
+							_vm->_draw->invalidateRect(_imdX, _imdY, _imdX + _imdFile->width - 1,
+									_imdY + _imdFile->height - 1);
+						else
+							_vm->_draw->invalidateRect(_imdFile->frameCoords[frame].left,
+									_imdFile->frameCoords[frame].top, _imdFile->frameCoords[frame].right,
+									_imdFile->frameCoords[frame].bottom);
+					}
+				} else
+					if (_vm->_video->_extraMode)
+						imdDrawFrame(_imdFile, frame, _imdX, _imdY);
+			}
+		}
+	}
+
+	if ((var_1 != 0) && (arg_2 == 16)) {
+		if ((_vm->_draw->_spritesArray[20] != _vm->_draw->_spritesArray[21]) && (_byte_2FC83 == 0))
+			_vm->_video->drawSprite(_vm->_draw->_spritesArray[21],
+					_vm->_draw->_spritesArray[20], 0, 0,
+					_vm->_draw->_spritesArray[21]->width - 1,
+					_vm->_draw->_spritesArray[21]->height - 1, 0, 0, 0);
+		_vm->_palanim->fade(_vm->_global->_pPaletteDesc, -2, 0);
+		_vm->_draw->_noInvalidated = 1;
+	}
+	if ((var_1 != 0) && (arg_2 == 8) && (_byte_2FC83 == 0))
+		_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
+
+	if (!(var_4 & 0x800)) {
+		if (_vm->_draw->_cursorIndex == -1) {
+			if (_byte_2FC82 != 0) {
+				if (_word_2FC80 == _vm->_draw->_spritesArray[20]->vidPtr)
+					_word_2FC80 = _vm->_draw->_spritesArray[21]->vidPtr;
+				else
+					_word_2FC80 = _vm->_draw->_spritesArray[20]->vidPtr;
+				warning("GOB2 Stub! sub_1BC3A(_word_2FC80);");
+			} else
+				_vm->_draw->blitInvalidated();
+		} else
+			_vm->_draw->animateCursor(-1);
+	}
+
+	if ((var_1 != 0) && ((arg_2 == 2) || (arg_2 == 4)))
+		_vm->_palanim->fade(_vm->_global->_pPaletteDesc, -2, 0);
+
+	// To allow quitting, etc. during IMDs
+	_vm->_util->processInput();
+
+	if (byte_31344 != 2) {
+		if (var_4 & 0x800) {
+			if (_dword_2F2B6 == 0)
+				_vm->_util->delay(30);
+			else {
+				_dword_2F2B6 -= 30;
+				if (_dword_2F2B6 < 0)
+					_dword_2F2B6 = 0;
+			}
+		} else
+			_vm->_util->waitEndFrame();
+	}
+	_vm->_inter->animPalette();
+}
+
+int16 Game::viewImd(Game::Imd *imdPtr, int16 frame) {
+	int16 x;
+	int16 y;
+	int16 width;
+	int16 height;
+	int16 retVal;
+	uint32 tmp;
+	char buf[4];
+
+	int8 var_4;
+	int32 var_12 = 0;
+
+	// .---
+	int16 word_31451 = 0;
+	int8 byte_31344 = 0;
+	int8 byte_2DA60 = 0;
+	int16 word_2DA61 = -1;
+	// '---
+
+	word_31451 = 0;
+
+	if (imdPtr == 0)
+		return 0x8000;
+
+	retVal = 0;
+	var_4 = 0;
+
+	if (frame != imdPtr->curFrame) {
+		retVal |= 0x2000;
+		if (frame == 0)
+			imdPtr->filePos = imdPtr->firstFramePos;
+		else if (frame == 1) {
+			imdPtr->filePos = imdPtr->firstFramePos;
+			_vm->_dataio->seekData(imdPtr->fileHandle, imdPtr->filePos, 0);
+			_vm->_dataio->readData(imdPtr->fileHandle, buf, 2);
+			tmp = READ_LE_UINT16(buf);
+			imdPtr->filePos += tmp + 4;
+		} else if (imdPtr->framesPos != 0)
+			imdPtr->filePos = imdPtr->framesPos[frame];
+		else
+			error("Image %d innaccessible in IMD", frame);
+		imdPtr->curFrame = frame;
+		_vm->_dataio->seekData(imdPtr->fileHandle, imdPtr->filePos, 0);
+	}
+
+	x = imdPtr->x;
+	y = imdPtr->y;
+	width = imdPtr->width;
+	height = imdPtr->height;
+
+	do {
+		if (frame != 0) {
+			if (imdPtr->stdX != -1) {
+				imdPtr->x = imdPtr->stdX;
+				imdPtr->y = imdPtr->stdY;
+				imdPtr->width = imdPtr->stdWidth;
+				imdPtr->height = imdPtr->stdHeight;
+				retVal |= 0x1000;
+			}
+			if ((imdPtr->frameCoords != 0) && (imdPtr->frameCoords[frame].left != -1)) {
+				var_4 |= 0x400;
+				imdPtr->x = imdPtr->frameCoords[frame].left;
+				imdPtr->y = imdPtr->frameCoords[frame].top;
+				imdPtr->width = imdPtr->frameCoords[frame].right - imdPtr->x + 1;
+				imdPtr->height = imdPtr->frameCoords[frame].bottom - imdPtr->y + 1;
+			}
+		}
+
+		_vm->_dataio->readData(imdPtr->fileHandle, buf, 2);
+		tmp = READ_LE_UINT16(buf);
+
+		imdPtr->filePos += 2;
+
+		if ((tmp & 0xFFF8) == 0xFFF0) {
+			if (tmp == 0xFFF0) {
+				_vm->_dataio->readData(imdPtr->fileHandle, buf, 2);
+				tmp = READ_LE_UINT16(buf);
+				if (var_4 == 0)
+					word_31451 = tmp;
+				_vm->_dataio->readData(imdPtr->fileHandle, buf, 2);
+				tmp = READ_LE_UINT16(buf);
+				imdPtr->filePos += 4;
+			} else if (tmp == 0xFFF1) {
+				retVal = 0x8000;
+				continue;
+			} else if (tmp == 0xFFF2) {
+				_vm->_dataio->readData(imdPtr->fileHandle, buf, 2);
+				tmp = READ_LE_UINT16(buf);
+				imdPtr->filePos += 2;
+				_vm->_dataio->seekData(imdPtr->fileHandle, tmp, 1);
+				imdPtr->filePos += tmp;
+				retVal = 0x8000;
+				continue;
+			} else if (tmp == 0xFFF3) {
+				_vm->_dataio->readData(imdPtr->fileHandle, buf, 4);
+				tmp = READ_LE_UINT32(buf);
+				imdPtr->filePos += 4;
+				_vm->_dataio->seekData(imdPtr->fileHandle, tmp, 1);
+				imdPtr->filePos += tmp;
+				retVal = 0x8000;
+				continue;
+			}
+		}
+		if (byte_31344 != 0) {
+			if ((var_4 == 0) && (_vm->_global->_soundFlags & 0x14) && (byte_31344 == 2)) { // loc_2A503
+				var_12 = _vm->_util->getTimeKey();
+				warning("GOB2 Stub! viewImd, IMD sound stuff");
+			}
+		}
+		var_4 = 0;
+		if (tmp == 0xFFFD) {
+			_vm->_dataio->readData(imdPtr->fileHandle, buf, 2);
+			frame = READ_LE_UINT16(buf);
+			if ((imdPtr->framesPos != 0) && (byte_2DA60 == 0)) {
+				word_2DA61 = frame;
+				imdPtr->filePos = imdPtr->framesPos[frame];
+				_vm->_dataio->seekData(imdPtr->fileHandle, imdPtr->filePos, 0);
+				var_4 = 1;
+				retVal |= 0x200;
+				imdPtr->curFrame = frame;
+			} else
+				imdPtr->filePos += 2;
+			continue;
+		}
+		if (tmp != 0) {
+			imdPtr->filePos += tmp + 2;
+			if (byte_2DA60 != 0) {
+				_vm->_dataio->seekData(imdPtr->fileHandle, tmp + 2, 1);
+			} else {
+				_vm->_dataio->readData(imdPtr->fileHandle, (char *) _imdFrameData, tmp + 2);
+				retVal |= *_imdFrameData;
+				if (imdPtr->surfDesc == 0)
+					continue;
+				if (!(_vm->_video->_extraMode && (imdPtr->surfDesc->vidMode == 0x13))) // MODIFIED... NOT!
+					imdRenderFrame(imdPtr);
+				else
+					warning("GOB2 Stub! viedImd, sub_2C69A(imdPtr);");
+			}
+		} else
+			retVal |= 0x800;
+	} while(var_4 != 0);
+
+	if (byte_2DA60 != 0) {
+		byte_2DA60 = 0;
+		retVal |= 0x100;
+	}
+
+	imdPtr->x = x;
+	imdPtr->y = y;
+	imdPtr->width = width;
+	imdPtr->height = height;
+	imdPtr->curFrame++;
+	
+	return retVal;
+}
+
+void Game::imdDrawFrame(Imd *imdPtr, int16 frame, int16 x, int16 y) {
+	// In the original asm, "sub_2C348" is called instead of Video::drawSprite();
+	// it basically just blits.
+
+	if (frame == 0)
+		_vm->_video->drawSprite(imdPtr->surfDesc, _vm->_draw->_frontSurface, 0, 0,
+				imdPtr->width - 1, imdPtr->height - 1, x, y, 1);
+	else if ((imdPtr->frameCoords != 0) && (imdPtr->frameCoords[frame].left != -1))
+		_vm->_video->drawSprite(imdPtr->surfDesc, _vm->_draw->_frontSurface,
+				imdPtr->frameCoords[frame].left, imdPtr->frameCoords[frame].top,
+				imdPtr->frameCoords[frame].right, imdPtr->frameCoords[frame].bottom,
+				imdPtr->frameCoords[frame].left, imdPtr->frameCoords[frame].top, 1);
+	else if (imdPtr->stdX != -1)
+		_vm->_video->drawSprite(imdPtr->surfDesc, _vm->_draw->_frontSurface,
+				imdPtr->stdX, imdPtr->stdY, imdPtr->stdX + imdPtr->stdWidth - 1,
+				imdPtr->stdY + imdPtr->stdHeight - 1, x + imdPtr->stdX,
+				y + imdPtr->stdY, 1);
+	else
+		_vm->_video->drawSprite(imdPtr->surfDesc, _vm->_draw->_frontSurface, 0, 0,
+				imdPtr->width - 1, imdPtr->height - 1, x, y, 1);
+}
+
+void Game::imdRenderFrame(Imd *imdPtr) {
+	int i;
+	int16 imdX;
+	int16 imdY;
+	int16 imdW;
+	int16 imdH;
+	int16 sW;
+	uint16 pixCount, pixWritten;
+	uint8 type;
+	byte *imdVidMem;
+	byte *imdVidMemBak;
+	byte *dataPtr = 0;
+	byte *srcPtr = 0;
+	byte *srcPtrBak = 0;
+
+	dataPtr = (byte *) _imdFrameData;
+	imdX = imdPtr->x;
+	imdY = imdPtr->y;
+	imdW = imdPtr->width;
+	imdH = imdPtr->height;
+	sW = imdPtr->surfDesc->width;
+	imdVidMem = imdPtr->surfDesc->vidPtr + sW * imdY + imdX;
+
+	type = *dataPtr++;
+	srcPtr = dataPtr;
+
+	if (type & 0x10) {
+		type ^= 0x10;
+		dataPtr++; // => 0x3C8       |_ palette
+		dataPtr += 48; // => 0x3C9   |  stuff
+	}
+
+	srcPtr = dataPtr;
+	if (type & 0x80) {
+		srcPtr = (byte *) _imdVidBuffer;
+		type &= 0x7F;
+		if ((type == 2) && (imdW == sW)) {
+			imdFrameUncompressor(imdVidMem, dataPtr);
+			return;
+		} else
+			imdFrameUncompressor(srcPtr, dataPtr);
+	}
+
+	if (type == 2) {
+		for (i = 0; i < imdH; i++) {
+			memcpy(imdVidMem, srcPtr, imdW);
+			srcPtr += imdW;
+			imdVidMem += sW;
+		}
+	} else if (type == 1) {
+		imdVidMemBak = imdVidMem;
+		for (i = 0; i < imdH; i++) {
+			pixWritten = 0;
+			while (pixWritten < imdW) {
+				pixCount = *srcPtr++;
+				if (pixCount & 0x80) {
+					pixCount = (pixCount & 0x7F) + 1;
+					// Just to be safe
+					pixCount = (pixWritten + pixCount) > imdW ? imdW - pixWritten : pixCount;
+					pixWritten += pixCount;
+					memcpy(imdVidMem, srcPtr, pixCount);
+					imdVidMem += pixCount;
+					srcPtr += pixCount;
+				} else {
+					pixCount = (pixCount + 1) % 256;
+					pixWritten += pixCount;
+					imdVidMem += pixCount;
+				}
+			}
+			imdVidMemBak += sW;
+			imdVidMem = imdVidMemBak;
+		}
+	} else if (type == 0x42) { // loc_2AFC4
+		warning("=> type == 0x42");
+	} else if ((type & 0xF) == 2) { // loc_2AFEC
+		warning("=> (type & 0xF) == 2");
+	} else { // loc_2B021
+		srcPtrBak = srcPtr;
+		for (i = 0; i < imdH; i += 2) {
+			pixWritten = 0;
+			while (pixWritten < imdW) {
+				pixCount = *srcPtr++;
+				if (pixCount & 0x80) {
+					pixCount = (pixCount & 0x7F) + 1;
+					// Just to be safe
+					pixCount = (pixWritten + pixCount) > imdW ? imdW - pixWritten : pixCount;
+					pixWritten += pixCount;
+					memcpy(imdVidMem, srcPtr, pixCount);
+					memcpy(imdVidMem + sW, srcPtr, pixCount);
+					imdVidMem += pixCount;
+					srcPtr += pixCount;
+				} else {
+					pixCount = (pixCount + 1) % 256;
+					pixWritten += pixCount;
+					imdVidMem += pixCount;
+				}
+			}
+			srcPtrBak += sW + sW;
+			srcPtr = srcPtrBak;
+		}
+	}
+}
+
+void Game::imdFrameUncompressor(byte *dest, byte *src) {
+	int i;
+	byte buf[4370];
+	int16 chunkLength;
+	int16 frameLength;
+	uint16 bufPos1;
+	uint16 bufPos2;
+	uint16 tmp;
+	uint8 chunkBitField;
+	uint8 chunkCount;
+	bool mode;
+
+	memset(buf, 0, sizeof(buf));
+
+	frameLength = READ_LE_UINT16(src);
+	src += 4;
+	bufPos1 = 4078;
+	mode = 0; // 275h (jnz +2)
+	if ((READ_LE_UINT16(src) == 0x1234) && (READ_LE_UINT16(src + 2) == 0x5678)) {
+		src += 4;
+		bufPos1 = 273;
+		mode = 1; // 123Ch (cmp al, 12h)
+	}
+	chunkCount = 1;
+	chunkBitField = 0;
+
+	while(frameLength > 0) {
+		chunkCount--;
+		if (chunkCount == 0) {
+			tmp = *src++;
+			chunkCount = 8;
+			chunkBitField = tmp;
+		}
+		if (chunkBitField % 2) {
+			chunkBitField >>= 1;
+			buf[bufPos1] = *src;
+			*dest++ = *src++;
+			bufPos1 = (bufPos1 + 1) % 4096;
+			frameLength--;
+			continue;
+		}
+		chunkBitField >>= 1;
+
+		tmp = READ_LE_UINT16(src);
+		src += 2;
+		chunkLength = ((tmp & 0xF00) >> 8) + 3;
+
+		if ((mode && ((chunkLength & 0xFF) == 0x12)) || (!mode && (chunkLength == 0)))
+			chunkLength = *src++ + 0x12;
+
+		bufPos2 = (tmp & 0xFF) + ((tmp >> 4) & 0x0F00);
+		if (((tmp + chunkLength) >= 4096) || ((chunkLength + bufPos1) >= 4096)) {
+			for (i = 0; i < chunkLength; i++, dest++) {
+				*dest = buf[bufPos2];
+				buf[bufPos1] = buf[bufPos2];
+				bufPos1 = (bufPos1 + 1) % 4096;
+				bufPos2 = (bufPos2 + 1) % 4096;
+			}
+			frameLength -= chunkLength;
+		} else if (((tmp + chunkLength) < bufPos1) || ((chunkLength + bufPos1) < bufPos2)) {
+			memcpy(dest, buf + bufPos2, chunkLength);
+			dest += chunkLength;
+			memmove(buf + bufPos1, buf + bufPos2, chunkLength);
+			bufPos1 += chunkLength;
+			bufPos2 += chunkLength;
+			frameLength -= chunkLength;
+		} else {
+			for (i = 0; i < chunkLength; i++, dest++, bufPos1++, bufPos2++) {
+				*dest = buf[bufPos2];
+				buf[bufPos1] = buf[bufPos2];
+			}
+			frameLength -= chunkLength;
+		}
+	}
+}
+
+int16 Game::sub_2C825(Imd *imdPtr) {
+	warning("GOB2 Stub! sub_2C825()");
+	return 0;
+}
+
 } // End of namespace Gob

Modified: scummvm/trunk/engines/gob/game.h
===================================================================
--- scummvm/trunk/engines/gob/game.h	2006-05-29 18:06:02 UTC (rev 22753)
+++ scummvm/trunk/engines/gob/game.h	2006-05-29 18:24:52 UTC (rev 22754)
@@ -94,6 +94,37 @@
 		int16 frontColor;
 		char *ptr;
 	} GCC_PACK;
+
+	struct ImdCoord {
+		int16 left;
+		int16 top;
+		int16 right;
+		int16 bottom;
+	} GCC_PACK;
+
+	struct Imd {
+		int16 fileHandle;
+		int16 verMin;
+		int16 framesCount;
+		int16 x;
+		int16 y;
+		int16 width;
+		int16 height;
+		int16 field_E;
+		int16 curFrame;
+		Video::Color *palette;
+		Video::SurfaceDesc *surfDesc;
+		int32 *framesPos;
+		int32 firstFramePos;
+		int16 stdX;
+		int16 stdY;
+		int16 stdWidth;
+		int16 stdHeight;
+		int32 filePos;
+		ImdCoord *frameCoords;
+		int32 frameDataSize;
+		int32 vidBufferSize;
+	} GCC_PACK;
 #pragma END_PACK_STRUCTS
 
 	TotResTable *_totResourceTable;
@@ -135,6 +166,18 @@
 	char *_variablesArray[5];
 	char _curTotFileArray[5][14];
 
+	Imd *_imdFile;
+	char _curImdFile[15];
+	int16 _imdX;
+	int16 _imdY;
+	int16 _imdFrameDataSize;
+	int16 _imdVidBufferSize;
+	byte *_imdFrameData;
+	byte *_imdVidBuffer;
+	int8 _byte_2FC82;
+	int8 _byte_2FC83;
+	byte *_word_2FC80;
+
 	Game(GobEngine *vm);
 	virtual ~Game() {};
 
@@ -163,6 +206,18 @@
 	char *loadLocTexts(void);
 	Snd::SoundDesc *loadSND(const char *path, int8 arg_4);
 
+	Imd *loadImdFile(const char *path, Video::SurfaceDesc *surfDesc, int8 flags);
+	int8 openImd(const char *path, int16 x, int16 y, int16 repeat, int16 flags);
+	void closeImd(void);
+	void finishImd(Imd *imdPtr);
+	void setImdXY(Imd *imdPtr, int16 x, int16 y);
+	void playImd(int16 arg_0, int16 arg_2, int16 arg_4, int16 arg_6, int16 arg_8, int16 arg_A);
+	int16 viewImd(Game::Imd *imdPtr, int16 arg_4);
+	void imdDrawFrame(Imd *imdPtr, int16 arg_4, int16 arg_6, int16 arg_8);
+	void imdRenderFrame(Imd *imdPtr);
+	void imdFrameUncompressor(byte *dest, byte *src);
+	int16 sub_2C825(Imd *imdPtr);
+
 	virtual void playTot(int16 skipPlay) = 0;
 	virtual void clearCollisions(void) = 0;
 	virtual void addNewCollision(int16 id, int16 left, int16 top, int16 right,
@@ -177,10 +232,12 @@
 	int16 _word_2FC9C;
 	int16 _word_2FC9E;
 	int16 _word_2E51F;
+	int32 _dword_2F2B6;
 	Video::SurfaceDesc *_off_2E51B;
 	Video::SurfaceDesc *_off_2E517;
 	void sub_ADD2(void);
 	void sub_BB28(void);
+
 protected:
 
 	int16 _lastCollKey;

Modified: scummvm/trunk/engines/gob/gob.cpp
===================================================================
--- scummvm/trunk/engines/gob/gob.cpp	2006-05-29 18:06:02 UTC (rev 22753)
+++ scummvm/trunk/engines/gob/gob.cpp	2006-05-29 18:24:52 UTC (rev 22754)
@@ -199,7 +199,6 @@
 	_dataio = new DataIO(this);
 	_pack = new Pack();
 	_palanim = new PalAnim(this);
-	_scenery = new Scenery(this);
 	_gtimer = new GTimer();
 	_util = new Util(this);
 	if (_features & Gob::GF_GOB1) {
@@ -212,6 +211,7 @@
 		_init = new Init_v1(this);
 		_map = new Map_v1(this);
 		_goblin = new Goblin_v1(this);
+		_scenery = new Scenery_v1(this);
 	}
 	else if (_features & Gob::GF_GOB2) {
 		_inter = new Inter_v2(this);
@@ -223,11 +223,16 @@
 		_init = new Init_v2(this);
 		_map = new Map_v2(this);
 		_goblin = new Goblin_v2(this);
+		_scenery = new Scenery_v2(this);
 	}
 	else
 		error("GobEngine::init(): Unknown version of game engine");
-	if ((_features & Gob::GF_MAC) || (_features & Gob::GF_GOB1) || (_features & Gob::GF_GOB2))
-		_music = new Music(this);
+	if ((_features & Gob::GF_MAC) || (_features & Gob::GF_GOB1) || (_features & Gob::GF_GOB2)) {
+		if (ConfMan.get("music_driver") == "null")
+			_music = new Music_Dummy(this);
+		else
+			_music = new Music(this);
+	}
 
 	_system->beginGFXTransaction();
 		initCommonGFX(false);

Modified: scummvm/trunk/engines/gob/goblin.cpp
===================================================================
--- scummvm/trunk/engines/gob/goblin.cpp	2006-05-29 18:06:02 UTC (rev 22753)
+++ scummvm/trunk/engines/gob/goblin.cpp	2006-05-29 18:24:52 UTC (rev 22754)
@@ -159,7 +159,6 @@
 	_word_2F9BA = 0;
 	_dword_2F9B6 = 0;
 	_dword_2F9B2 = 0;
-	_dword_2F2A4 = 0;
 }
 
 char Goblin::rotateState(int16 from, int16 to) {
@@ -633,8 +632,8 @@
 	else
 		next = index - 1;
 
-	if (_vm->_map->_passMap[_vm->_map->_curGoblinY][_vm->_map->_curGoblinX] == 3 ||
-	    _vm->_map->_passMap[_vm->_map->_curGoblinY][_vm->_map->_curGoblinX] == 6)
+	if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 3 ||
+	    _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 6)
 		return;
 
 	if (_goblins[(_currentGoblin + 1) % 3]->type != 0 &&
@@ -686,7 +685,7 @@
 	int16 deltaPix;
 	int16 i;
 
-	if (_vm->_map->_passMap[_pressedMapY][_pressedMapX] == 0 &&
+	if (_vm->_map->getPass(_pressedMapX, _pressedMapY) == 0 &&
 	    (_gobAction == 0
 		|| _vm->_map->_itemsMap[_pressedMapY][_pressedMapX] == 0)) {
 
@@ -696,7 +695,7 @@
 
 		for (i = 1;
 		    i <= _pressedMapX
-		    && _vm->_map->_passMap[_pressedMapY][_pressedMapX - i] == 0;
+		    && _vm->_map->getPass(_pressedMapX - i, _pressedMapY) == 0;
 		    i++);
 
 		if (i <= _pressedMapX) {
@@ -705,11 +704,11 @@
 		}
 
 		for (i = 1;
-				(i + _pressedMapX) < Map::kMapWidth
-		    && _vm->_map->_passMap[_pressedMapY][_pressedMapX + i] == 0;
+				(i + _pressedMapX) < _vm->_map->_mapWidth
+		    && _vm->_map->getPass(_pressedMapX + i, _pressedMapY) == 0;
 		    i++);
 
-		if (_pressedMapX + i < Map::kMapWidth) {
+		if (_pressedMapX + i < _vm->_map->_mapWidth) {
 			deltaPix = (i * 12) - (posX % 12);
 			if (resDelta == -1 || deltaPix < resDeltaPix) {
 				resDeltaPix = deltaPix;
@@ -719,11 +718,11 @@
 		}
 
 		for (i = 1;
-				(i + _pressedMapY) < Map::kMapHeight
-		    && _vm->_map->_passMap[_pressedMapY + i][_pressedMapX] == 0;
+				(i + _pressedMapY) < _vm->_map->_mapHeight
+		    && _vm->_map->getPass(_pressedMapX, _pressedMapY + i) == 0;
 		    i++);
 
-		if (_pressedMapY + i < Map::kMapHeight) {
+		if (_pressedMapY + i < _vm->_map->_mapHeight) {
 			deltaPix = (i * 6) - (posY % 6);
 			if (resDelta == -1 || deltaPix < resDeltaPix) {
 				resDeltaPix = deltaPix;
@@ -734,7 +733,7 @@
 
 		for (i = 1;
 		    i <= _pressedMapY
-		    && _vm->_map->_passMap[_pressedMapY - i][_pressedMapX] == 0;
+		    && _vm->_map->getPass(_pressedMapX, _pressedMapY - i) == 0;
 		    i++);
 
 		if (i <= _pressedMapY) {
@@ -775,11 +774,11 @@
 		    && _vm->_map->_itemsMap[_pressedMapY - 1][_pressedMapX] !=
 		    0) {
 			_pressedMapY--;
-		} else if (_pressedMapX < Map::kMapWidth - 1
+		} else if (_pressedMapX < _vm->_map->_mapWidth - 1
 		    && _vm->_map->_itemsMap[_pressedMapY][_pressedMapX + 1] !=
 		    0) {
 			_pressedMapX++;
-		} else if (_pressedMapX < Map::kMapWidth - 1 && _pressedMapY > 0
+		} else if (_pressedMapX < _vm->_map->_mapWidth - 1 && _pressedMapY > 0
 		    && _vm->_map->_itemsMap[_pressedMapY - 1][_pressedMapX +
 			1] != 0) {
 			_pressedMapY--;
@@ -790,7 +789,7 @@
 
 void Goblin::targetDummyItem(Gob_Object *gobDesc) {
 	if (_vm->_map->_itemsMap[_pressedMapY][_pressedMapX] == 0 &&
-	    _vm->_map->_passMap[_pressedMapY][_pressedMapX] == 1) {
+	    _vm->_map->getPass(_pressedMapX, _pressedMapY) == 1) {
 		if (gobDesc->curLookDir == 0) {
 			_vm->_map->_itemPoses[0].x = _pressedMapX;
 			_vm->_map->_itemPoses[0].y = _pressedMapY;
@@ -938,7 +937,7 @@
 				tmpPosX++;
 			}
 
-			if (_vm->_map->_passMap[tmpPosY][tmpPosX] == 1) {
+			if (_vm->_map->getPass(tmpPosX, tmpPosY) == 1) {
 				_pressedMapX = tmpPosX;
 				_vm->_map->_destX = tmpPosX;
 				_gobDestX = tmpPosX;
@@ -951,26 +950,6 @@
 	}
 }
 
-void Goblin::initiateMove(void) {
-	_vm->_map->findNearestToDest();
-	_vm->_map->findNearestToGob();
-	_vm->_map->optimizePoints();
-
-	_pathExistence = _vm->_map->checkDirectPath(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY,
-	    _pressedMapX, _pressedMapY);
-
-	if (_pathExistence == 3) {
-		if (_vm->_map->checkLongPath(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY,
-			_pressedMapX, _pressedMapY,
-			_vm->_map->_nearestWayPoint, _vm->_map->_nearestDest) == 0) {
-			_pathExistence = 0;
-		} else {
-			_vm->_map->_destX = _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].x;
-			_vm->_map->_destY = _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].y;
-		}
-	}
-}
-
 void Goblin::moveFindItem(int16 posX, int16 posY) {
 	int16 i;
 	if (_gobAction == 3 || _gobAction == 4) {
@@ -1121,7 +1100,7 @@
 		targetDummyItem(gobDesc);
 
 		targetItem();
-		initiateMove();
+		initiateMove(0);
 
 		moveCheckSelect(framesCount, gobDesc, pGobIndex, pNextAct);
 	} else {
@@ -1142,57 +1121,57 @@
 		return;
 
 	if (gobDesc->nextState == 28
-	    && _vm->_map->_passMap[_vm->_map->_curGoblinY - 1][_vm->_map->_curGoblinX] == 6) {
+	    && _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY - 1) == 6) {
 		_forceNextState[0] = 28;
 		_forceNextState[1] = -1;
 	}
 
 	if (gobDesc->nextState == 29
-	    && _vm->_map->_passMap[_vm->_map->_curGoblinY + 1][_vm->_map->_curGoblinX] == 6) {
+	    && _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY + 1) == 6) {
 		_forceNextState[0] = 29;
 		_forceNextState[1] = -1;
 	}
 
 	if ((gobDesc->nextState == 28 || gobDesc->nextState == 29
 		|| gobDesc->nextState == 20)
-	    && _vm->_map->_passMap[_vm->_map->_curGoblinY][_vm->_map->_curGoblinX] == 6) {
+	    && _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 6) {
 		if ((gobDesc->curLookDir == 0 || gobDesc->curLookDir == 4
 			|| gobDesc->curLookDir == 2)
-		    && _vm->_map->_passMap[_vm->_map->_curGoblinY - 1][_vm->_map->_curGoblinX] == 6) {
+		    && _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY - 1) == 6) {
 			_forceNextState[0] = 28;
 			_forceNextState[1] = -1;
 		} else if ((gobDesc->curLookDir == 0
 			|| gobDesc->curLookDir == 4
 			|| gobDesc->curLookDir == 6)
-		    && _vm->_map->_passMap[_vm->_map->_curGoblinY + 1][_vm->_map->_curGoblinX] == 6) {
+		    && _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY + 1) == 6) {
 			_forceNextState[0] = 29;
 			_forceNextState[1] = -1;
 		}
 	}
 
 	if (gobDesc->nextState == 8
-	    && _vm->_map->_passMap[_vm->_map->_curGoblinY - 1][_vm->_map->_curGoblinX] == 3) {
+	    && _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY - 1) == 3) {
 		_forceNextState[0] = 8;
 		_forceNextState[1] = -1;
 	}
 
 	if (gobDesc->nextState == 9
-	    && _vm->_map->_passMap[_vm->_map->_curGoblinY + 1][_vm->_map->_curGoblinX] == 3) {
+	    && _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY + 1) == 3) {
 		_forceNextState[0] = 9;
 		_forceNextState[1] = -1;
 	}
 
 	if (gobDesc->nextState == 20
-	    && _vm->_map->_passMap[_vm->_map->_curGoblinY][_vm->_map->_curGoblinX] == 3) {
+	    && _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 3) {
 		if ((gobDesc->curLookDir == 0 || gobDesc->curLookDir == 4
 			|| gobDesc->curLookDir == 2)
-		    && _vm->_map->_passMap[_vm->_map->_curGoblinY - 1][_vm->_map->_curGoblinX] == 3) {
+		    && _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY - 1) == 3) {
 			_forceNextState[0] = 8;
 			_forceNextState[1] = -1;
 		} else if ((gobDesc->curLookDir == 0
 			|| gobDesc->curLookDir == 4
 			|| gobDesc->curLookDir == 6)
-		    && _vm->_map->_passMap[_vm->_map->_curGoblinY + 1][_vm->_map->_curGoblinX] == 3) {
+		    && _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY + 1) == 3) {
 			_forceNextState[0] = 9;
 			_forceNextState[1] = -1;
 		}
@@ -1226,14 +1205,14 @@
 			_vm->_map->_destY = _pressedMapY;
 		} else {
 
-			if (_vm->_map->checkDirectPath(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY,
+			if (_vm->_map->checkDirectPath(-1, _vm->_map->_curGoblinX, _vm->_map->_curGoblinY,
 				_gobDestX, _gobDestY) == 1) {
 				_vm->_map->_destX = _gobDestX;
 				_vm->_map->_destY = _gobDestY;
 			} else if (_vm->_map->_curGoblinX == _vm->_map->_destX && _vm->_map->_curGoblinY == _vm->_map->_destY) {
 
 				if (_vm->_map->_nearestWayPoint > _vm->_map->_nearestDest) {
-					_vm->_map->optimizePoints();
+					_vm->_map->optimizePoints(0, 0, 0);
 
 					_vm->_map->_destX =
 					    _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].
@@ -1245,7 +1224,7 @@
 					if (_vm->_map->_nearestWayPoint > _vm->_map->_nearestDest)
 						_vm->_map->_nearestWayPoint--;
 				} else if (_vm->_map->_nearestWayPoint < _vm->_map->_nearestDest) {
-					_vm->_map->optimizePoints();
+					_vm->_map->optimizePoints(0, 0, 0);
 
 					_vm->_map->_destX =
 					    _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].
@@ -1257,9 +1236,9 @@
 					if (_vm->_map->_nearestWayPoint < _vm->_map->_nearestDest)
 						_vm->_map->_nearestWayPoint++;
 				} else {
-					if (_vm->_map->checkDirectPath(_vm->_map->_curGoblinX,
+					if (_vm->_map->checkDirectPath(-1, _vm->_map->_curGoblinX,
 						_vm->_map->_curGoblinY, _gobDestX,
-						_gobDestY) == 3 && _vm->_map->_passMap[_pressedMapY][_pressedMapX] != 0) {
+						_gobDestY) == 3 && _vm->_map->getPass(_pressedMapX, _pressedMapY) != 0) {
 						_vm->_map->_destX = _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].x;
 						_vm->_map->_destY = _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].y;
 					} else {
@@ -1296,18 +1275,18 @@
 		break;
 
 	case Map::kDirN:
-		if (_vm->_map->_passMap[_vm->_map->_curGoblinY - 1][_vm->_map->_curGoblinX] == 6 &&
+		if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY - 1) == 6 &&
 		    _currentGoblin != 1) {
 			_pathExistence = 0;
 			break;
 		}
 
-		if (_vm->_map->_passMap[_vm->_map->_curGoblinY][_vm->_map->_curGoblinX] == 3) {
+		if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 3) {
 			gobDesc->nextState = 8;
 			break;
 		}
 
-		if (_vm->_map->_passMap[_vm->_map->_curGoblinY][_vm->_map->_curGoblinX] == 6 &&
+		if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 6 &&
 		    _currentGoblin == 1) {
 			gobDesc->nextState = 28;
 			break;
@@ -1317,18 +1296,18 @@
 		break;
 
 	case Map::kDirS:
-		if (_vm->_map->_passMap[_vm->_map->_curGoblinY + 1][_vm->_map->_curGoblinX] == 6 &&
+		if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY + 1) == 6 &&
 		    _currentGoblin != 1) {
 			_pathExistence = 0;
 			break;
 		}
 
-		if (_vm->_map->_passMap[_vm->_map->_curGoblinY][_vm->_map->_curGoblinX] == 3) {
+		if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 3) {
 			gobDesc->nextState = 9;
 			break;
 		}
 
-		if (_vm->_map->_passMap[_vm->_map->_curGoblinY][_vm->_map->_curGoblinX] == 6 &&
+		if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 6 &&
 		    _currentGoblin == 1) {
 			gobDesc->nextState = 29;
 			break;
@@ -1338,7 +1317,7 @@
 		break;
 
 	case Map::kDirSE:
-		if (_vm->_map->_passMap[_vm->_map->_curGoblinY + 1][_vm->_map->_curGoblinX + 1] == 6 &&
+		if (_vm->_map->getPass(_vm->_map->_curGoblinX + 1, _vm->_map->_curGoblinY + 1) == 6 &&
 		    _currentGoblin != 1) {
 			_pathExistence = 0;
 			break;
@@ -1352,7 +1331,7 @@
 		break;
 
 	case Map::kDirSW:
-		if (_vm->_map->_passMap[_vm->_map->_curGoblinY + 1][_vm->_map->_curGoblinX - 1] == 6 &&
+		if (_vm->_map->getPass(_vm->_map->_curGoblinX - 1, _vm->_map->_curGoblinY + 1) == 6 &&
 		    _currentGoblin != 1) {
 			_pathExistence = 0;
 			break;
@@ -1366,7 +1345,7 @@
 		break;
 
 	case Map::kDirNW:
-		if (_vm->_map->_passMap[_vm->_map->_curGoblinY - 1][_vm->_map->_curGoblinX - 1] == 6 &&
+		if (_vm->_map->getPass(_vm->_map->_curGoblinX - 1, _vm->_map->_curGoblinY - 1) == 6 &&
 		    _currentGoblin != 1) {
 			_pathExistence = 0;
 			break;
@@ -1380,7 +1359,7 @@
 		break;
 
 	case Map::kDirNE:
-		if (_vm->_map->_passMap[_vm->_map->_curGoblinY - 1][_vm->_map->_curGoblinX + 1] == 6 &&
+		if (_vm->_map->getPass(_vm->_map->_curGoblinX + 1, _vm->_map->_curGoblinY - 1) == 6 &&
 		    _currentGoblin != 1) {
 			_pathExistence = 0;
 			break;
@@ -1439,8 +1418,8 @@
 		break;
 
 	default:
-		if (_vm->_map->_passMap[_vm->_map->_curGoblinY][_vm->_map->_curGoblinX] == 3 ||
-		    (_vm->_map->_passMap[_vm->_map->_curGoblinY][_vm->_map->_curGoblinX] == 6
+		if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 3 ||
+		    (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 6
 			&& _currentGoblin == 1)) {
 			gobDesc->nextState = 20;
 			break;
@@ -2017,8 +1996,8 @@
 	_itemIndInPocket = indexToPocket;
 	_itemIdInPocket = idToPocket;
 
-	for (y = 0; y < Map::kMapHeight; y++) {
-		for (x = 0; x < Map::kMapWidth; x++) {
+	for (y = 0; y < _vm->_map->_mapHeight; y++) {
+		for (x = 0; x < _vm->_map->_mapWidth; x++) {
 			if (_itemByteFlag == 1) {
 				if (((_vm->_map->_itemsMap[y][x] & 0xff00) >> 8) ==
 				    idToPocket)
@@ -2084,7 +2063,7 @@
 	}
 
 	if (lookDir == 4) {
-		if (xPos < Map::kMapWidth - 1) {
+		if (xPos < _vm->_map->_mapWidth - 1) {
 			_vm->_map->placeItem(xPos + 1, yPos, idInPocket);
 
 			if (yPos > 0) {
@@ -2107,10 +2086,10 @@
 		_vm->_map->_itemPoses[idInPocket].orient = lookDir;
 		if (_vm->_map->_itemPoses[idInPocket].orient == 0) {
 //                      _vm->_map->_itemPoses[idInPocket].x++;
-			if (_vm->_map->_passMap[(int)_vm->_map->_itemPoses[idInPocket].y][_vm->_map->_itemPoses[idInPocket].x + 1] == 1)
+			if (_vm->_map->getPass(_vm->_map->_itemPoses[idInPocket].x + 1, (int)_vm->_map->_itemPoses[idInPocket].y) == 1)
 				_vm->_map->_itemPoses[idInPocket].x++;
 		} else {
-			if (_vm->_map->_passMap[(int)_vm->_map->_itemPoses[idInPocket].y][_vm->_map->_itemPoses[idInPocket].x - 1] == 1)
+			if (_vm->_map->getPass(_vm->_map->_itemPoses[idInPocket].x - 1, (int)_vm->_map->_itemPoses[idInPocket].y) == 1)
 				_vm->_map->_itemPoses[idInPocket].x--;
 		}
 	}
@@ -2133,8 +2112,8 @@
 	_itemIdInPocket = idToPick;
 
 	if (_itemByteFlag == 0) {
-		for (y = 0; y < Map::kMapHeight; y++) {
-			for (x = 0; x < Map::kMapWidth; x++) {
+		for (y = 0; y < _vm->_map->_mapHeight; y++) {
+			for (x = 0; x < _vm->_map->_mapWidth; x++) {
 				if ((_vm->_map->_itemsMap[y][x] & 0xff) == idToPick)
 					_vm->_map->_itemsMap[y][x] =
 					    (_vm->_map->_itemsMap[y][x] & 0xff00) +
@@ -2143,8 +2122,8 @@
 		}
 	} else {
 
-		for (y = 0; y < Map::kMapHeight; y++) {
-			for (x = 0; x < Map::kMapWidth; x++) {
+		for (y = 0; y < _vm->_map->_mapHeight; y++) {
+			for (x = 0; x < _vm->_map->_mapWidth; x++) {
 				if (((_vm->_map->_itemsMap[y][x] & 0xff00) >> 8) ==
 				    idToPick)
 					_vm->_map->_itemsMap[y][x] =
@@ -2296,11 +2275,11 @@
 	Mult::Mult_Object *obj1;
 	Mult::Mult_AnimData *anim0;
 	Mult::Mult_AnimData *anim1;
-	int16 varVal;
-	int16 var_2;
-	int16 var_4;
-	int16 var_6;
-	int16 var_8;
+	int16 pass;
+	int16 gob1X;
+	int16 gob2X;
+	int16 gob1Y;
+	int16 gob2Y;
 	int16 var_A;
 	int16 var_C;
 	int16 di;
@@ -2380,73 +2359,73 @@
 		warning("GOB2 Stub! sub_195C7(1, 16);");
 	}
 
-	var_2 = obj0->goblinX;
-	var_4 = obj1->goblinX;
-	var_6 = obj0->goblinY;
-	var_8 = obj1->goblinY;
+	gob1X = obj0->goblinX;
+	gob2X = obj1->goblinX;
+	gob1Y = obj0->goblinY;
+	gob2Y = obj1->goblinY;
 	di = anim0->field_13;
 	si = anim0->field_14;
 	var_A = anim1->field_13;
 	var_C = anim1->field_14;
 
-	varVal = _vm->_util->readVariableByte(_dword_2F2A4 + var_6 * 40 + var_2);
-	if ((varVal > 17) && (varVal < 21))
-		warning("GOB2 Stub! sub_195C7(anim0);");
-	varVal = _vm->_util->readVariableByte(_dword_2F2A4 + var_8 * 40 + var_4);
-	if ((varVal > 17) && (varVal < 21))
+	pass = _vm->_map->getPass(gob1X, gob1Y, 40);
+	if ((pass > 17) && (pass < 21))
+		warning("GOB2 Stub! sub_19AB7(anim0);");
+	pass = _vm->_map->getPass(gob2X, gob2Y, 40);
+	if ((pass > 17) && (pass < 21))
 		warning("GOB2 Stub! sub_19B45(anim1);");
 
 	if ((di < 0) || (di > 39) || (si < 0) || (si > 39))
 		return;
 
-	if (var_6 > si) {
-		if (_vm->_util->readVariableByte(_dword_2F2A4 + si * 40 + di) > 17) {
+	if (gob1Y > si) {
+		if (_vm->_map->getPass(di, si, 40) > 17) {
 			do {
 				si--;
-			} while (_vm->_util->readVariableByte(_dword_2F2A4 + si * 40 + di) > 17);
+			} while (_vm->_map->getPass(di, si, 40) > 17);
 			si++;
-			if (_vm->_util->readVariableByte(_dword_2F2A4 + si * 40 + di - 1) == 0) {
-				if (_vm->_util->readVariableByte(_dword_2F2A4 + si * 40 + di + 1) != 0)
+			if (_vm->_map->getPass(di - 1, si, 40) == 0) {
+				if (_vm->_map->getPass(di + 1, si, 40) != 0)
 					di++;
 			} else
 				di--;
 			warning("GOB2 Stub! sub_197A6(di (=%d), si (=%d), 0);", si, di);
 		}
 	} else {
-		if (_vm->_util->readVariableByte(_dword_2F2A4 + si * 40 + di) > 17) {
+		if (_vm->_map->getPass(di, si, 40) > 17) {
 			do {
 				si++;
-			} while (_vm->_util->readVariableByte(_dword_2F2A4 + si * 40 + di) > 17);
+			} while (_vm->_map->getPass(di, si, 40) > 17);
 			si--;
-			if (_vm->_util->readVariableByte(_dword_2F2A4 + si * 40 + di - 1) == 0) {
-				if (_vm->_util->readVariableByte(_dword_2F2A4 + si * 40 + di + 1) != 0)
+			if (_vm->_map->getPass(di - 1, si, 40) == 0) {
+				if (_vm->_map->getPass(di + 1, si, 40) != 0)
 					di++;
 			} else
 				di--;
 			warning("GOB2 Stub! sub_197A6(di (=%d), si (=%d), 0);", si, di);
 		}
 	}
-	if (var_8 > var_C) {
-		if (_vm->_util->readVariableByte(_dword_2F2A4 + var_C * 40 + var_A) > 17) {
+	if (gob2Y > var_C) {
+		if (_vm->_map->getPass(var_A, var_C, 40) > 17) {
 			do {
 				var_C--;
-			} while (_vm->_util->readVariableByte(_dword_2F2A4 + var_C * 40 + var_A) > 17);
+			} while (_vm->_map->getPass(var_A, var_C, 40) > 17);
 			var_C++;
-			if (_vm->_util->readVariableByte(_dword_2F2A4 + var_C * 40 + var_A) == 0) {
-				if (_vm->_util->readVariableByte(_dword_2F2A4 + var_C * 40 + var_A) != 0)
+			if (_vm->_map->getPass(var_A - 1, var_C, 40) == 0) {
+				if (_vm->_map->getPass(var_A + 1, var_C, 40) != 0)
 					var_A++;
 			} else
 				var_A--;
 			warning("GOB2 Stub! sub_197A6(var_A (=%d), var_C (=%d), 1);", var_A, var_C);
 		}
 	} else {
-		if (_vm->_util->readVariableByte(_dword_2F2A4 + var_C * 40 + var_A) > 17) {
+		if (_vm->_map->getPass(var_A, var_C, 40) > 17) {
 			do {
 				var_C++;
-			} while (_vm->_util->readVariableByte(_dword_2F2A4 + var_C * 40 + var_A) > 17);
+			} while (_vm->_map->getPass(var_A, var_C, 40) > 17);
 			var_C--;
-			if (_vm->_util->readVariableByte(_dword_2F2A4 + var_C * 40 + var_A) == 0) {
-				if (_vm->_util->readVariableByte(_dword_2F2A4 + var_C * 40 + var_A) != 0)
+			if (_vm->_map->getPass(var_A - 1, var_C, 40) == 0) {
+				if (_vm->_map->getPass(var_A + 1, var_C, 40) != 0)
 					var_A++;
 			} else
 				var_A--;

Modified: scummvm/trunk/engines/gob/goblin.h
===================================================================
--- scummvm/trunk/engines/gob/goblin.h	2006-05-29 18:06:02 UTC (rev 22753)
+++ scummvm/trunk/engines/gob/goblin.h	2006-05-29 18:24:52 UTC (rev 22754)
@@ -23,6 +23,7 @@
 #ifndef GOB_GOBLIN_H
 #define GOB_GOBLIN_H
 
+#include "gob/gob.h"
 #include "gob/util.h"
 #include "gob/sound.h"
 
@@ -192,7 +193,6 @@
 	int16 _word_2F9BA;
 	int16 _dword_2F9B6; // index into the variables array
 	int16 _dword_2F9B2; // index into the variables array
-	char *_dword_2F2A4; // index into the variables array
 
 	// Functions
 	char rotateState(int16 from, int16 to);
@@ -223,6 +223,7 @@
 	virtual void placeObject(Gob_Object * objDesc, char animated,
 			int16 index, int16 x, int16 y, int16 state) = 0;
 	virtual void freeObjects(void) = 0;
+	virtual void initiateMove(int16 index) = 0;
 
 	Goblin(GobEngine *vm);
 	virtual ~Goblin() {};
@@ -238,7 +239,6 @@
 	void adjustTarget(void);
 	void targetDummyItem(Gob_Object *gobDesc);
 	void targetItem(void);
-	void initiateMove(void);
 	void moveFindItem(int16 posX, int16 posY);
 	void moveCheckSelect(int16 framesCount, Gob_Object * gobDesc, int16 *pGobIndex, int16 *nextAct);
 	void moveInitStep(int16 framesCount, int16 action, int16 cont,
@@ -253,6 +253,7 @@
 	virtual void placeObject(Gob_Object * objDesc, char animated,
 			int16 index, int16 x, int16 y, int16 state);
 	virtual void freeObjects(void);
+	virtual void initiateMove(int16 index);
 
 	Goblin_v1(GobEngine *vm);
 	virtual ~Goblin_v1() {};
@@ -263,6 +264,7 @@
 	virtual void placeObject(Gob_Object * objDesc, char animated,
 			int16 index, int16 x, int16 y, int16 state);
 	virtual void freeObjects(void);
+	virtual void initiateMove(int16 index);
 
 	Goblin_v2(GobEngine *vm);
 	virtual ~Goblin_v2() {};

Modified: scummvm/trunk/engines/gob/goblin_v1.cpp
===================================================================
--- scummvm/trunk/engines/gob/goblin_v1.cpp	2006-05-29 18:06:02 UTC (rev 22753)
+++ scummvm/trunk/engines/gob/goblin_v1.cpp	2006-05-29 18:24:52 UTC (rev 22754)
@@ -27,6 +27,7 @@
 #include "gob/gob.h"
 #include "gob/goblin.h"
 #include "gob/scenery.h"
+#include "gob/map.h"
 
 namespace Gob {
 
@@ -137,4 +138,24 @@
 	}
 }
 
+void Goblin_v1::initiateMove(int16 index) {
+	_vm->_map->findNearestToDest(0);
+	_vm->_map->findNearestToGob(0);
+	_vm->_map->optimizePoints(0, 0, 0);
+
+	_pathExistence = _vm->_map->checkDirectPath(0, _vm->_map->_curGoblinX, _vm->_map->_curGoblinY,
+	    _pressedMapX, _pressedMapY);
+
+	if (_pathExistence == 3) {
+		if (_vm->_map->checkLongPath(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY,
+			_pressedMapX, _pressedMapY,
+			_vm->_map->_nearestWayPoint, _vm->_map->_nearestDest) == 0) {
+			_pathExistence = 0;
+		} else {
+			_vm->_map->_destX = _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].x;
+			_vm->_map->_destY = _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].y;
+		}
+	}
+}
+
 } // End of namespace Gob

Modified: scummvm/trunk/engines/gob/goblin_v2.cpp
===================================================================
--- scummvm/trunk/engines/gob/goblin_v2.cpp	2006-05-29 18:06:02 UTC (rev 22753)
+++ scummvm/trunk/engines/gob/goblin_v2.cpp	2006-05-29 18:24:52 UTC (rev 22754)
@@ -29,6 +29,7 @@
 #include "gob/mult.h"
 #include "gob/game.h"
 #include "gob/scenery.h"
+#include "gob/map.h"
 
 namespace Gob {
 
@@ -74,11 +75,13 @@
 		objAnim->newCycle = 0;
 		_vm->_scenery->updateAnim(objAnim->layer, 0, objAnim->animation, 0,
 				*obj->pPosX, *obj->pPosY, 0);
-		if (_vm->_mult->_word_2CC86 == 0)
-			*obj->pPosY = (y + 1) * _vm->_mult->_word_2F2AF; // - (_vm->_scenery->_animBottom - _vm->scenery->_animTop);
+		if (!_vm->_map->_bigTiles)
+			*obj->pPosY = (y + 1) * _vm->_map->_tilesHeight
+				- (_vm->_scenery->_animBottom - _vm->_scenery->_animTop);
 		else
-			*obj->pPosY = ((y + 1) / 2) * _vm->_mult->_word_2F2AF; //- (_vm->_scenery->_animBottom - _vm->scenery->_animTop);
-		*obj->pPosX = x * _vm->_mult->_word_2F2B1;
+			*obj->pPosY = ((y + 1) / 2) * _vm->_map->_tilesHeight
+				- (_vm->_scenery->_animBottom - _vm->_scenery->_animTop);
+		*obj->pPosX = x * _vm->_map->_tilesWidth;
 	} else {
 		if (obj->goblinStates[state] != 0) {
 			layer = obj->goblinStates[state][0].layer;
@@ -91,15 +94,33 @@
 			objAnim->isStatic = 0;
 			objAnim->newCycle = _vm->_scenery->_animations[animation].layers[layer]->framesCount;
 			_vm->_scenery->updateAnim(layer, 0, animation, 0, *obj->pPosX, *obj->pPosY, 0);
-			if (_vm->_mult->_word_2CC86 == 0)
-				*obj->pPosY = (y + 1) * _vm->_mult->_word_2F2AF; // - (_vm->_scenery->_animBottom - _vm->scenery->_animTop);
+			if (!_vm->_map->_bigTiles)
+				*obj->pPosY = (y + 1) * _vm->_map->_tilesHeight
+					- (_vm->_scenery->_animBottom - _vm->_scenery->_animTop);
 			else
-				*obj->pPosY = ((y + 1) / 2) * _vm->_mult->_word_2F2AF; //- (_vm->_scenery->_animBottom - _vm->scenery->_animTop);
-			*obj->pPosX = x * _vm->_mult->_word_2F2B1;
-			warning("GOB2 Stub! sub_FE1D(obj");
+				*obj->pPosY = ((y + 1) / 2) * _vm->_map->_tilesHeight
+					- (_vm->_scenery->_animBottom - _vm->_scenery->_animTop);
+			*obj->pPosX = x * _vm->_map->_tilesWidth;
+			initiateMove(index);
 		} else
-			warning("GOB2 Stub! sub_FE1D(obj");
+			initiateMove(index);
 	}
 }
 
+void Goblin_v2::initiateMove(int16 index) {
+	Mult::Mult_Object *obj = &_vm->_mult->_objects[index];
+
+	obj->destX = obj->gobDestX;
+	obj->destY = obj->gobDestY;
+	_vm->_map->findNearestToDest(index);
+	_vm->_map->findNearestToGob(index);
+	_vm->_map->optimizePoints(index, obj->goblinX, obj->goblinY);
+	obj->pAnimData->field_12 = _vm->_map->checkDirectPath(index,
+			obj->goblinX, obj->goblinY, obj->gobDestX, obj->gobDestY);
+	if (obj->pAnimData->field_12 == 3) {
+		obj->destX = _vm->_map->_wayPoints[obj->nearestWayPoint].x;
+		obj->destY = _vm->_map->_wayPoints[obj->nearestWayPoint].y;
+	}
+}
+
 } // End of namespace Gob

Modified: scummvm/trunk/engines/gob/inter.cpp
===================================================================
--- scummvm/trunk/engines/gob/inter.cpp	2006-05-29 18:06:02 UTC (rev 22753)
+++ scummvm/trunk/engines/gob/inter.cpp	2006-05-29 18:24:52 UTC (rev 22754)
@@ -304,8 +304,8 @@
 }
 
 void Inter::manipulateMap(int16 xPos, int16 yPos, int16 item) {
-	for (int16 y = 0; y < Map::kMapHeight; y++) {
-		for (int16 x = 0; x < Map::kMapWidth; x++) {
+	for (int16 y = 0; y < _vm->_map->_mapHeight; y++) {
+		for (int16 x = 0; x < _vm->_map->_mapWidth; x++) {
 			if ((_vm->_map->_itemsMap[y][x] & 0xff) == item) {
 				_vm->_map->_itemsMap[y][x] &= 0xff00;
 			} else if (((_vm->_map->_itemsMap[y][x] & 0xff00) >> 8)
@@ -315,7 +315,7 @@
 		}
 	}
 
-	if (xPos < Map::kMapWidth - 1) {
+	if (xPos < _vm->_map->_mapWidth - 1) {
 		if (yPos > 0) {
 			if ((_vm->_map->_itemsMap[yPos][xPos] & 0xff00) != 0 ||
 					(_vm->_map->_itemsMap[yPos - 1][xPos] & 0xff00) !=
@@ -415,28 +415,28 @@
 	if (item < 0 || item >= 20)
 		return;
 
-	if (xPos > 1 && _vm->_map->_passMap[yPos][xPos - 2] == 1) {
+	if (xPos > 1 && _vm->_map->getPass(xPos - 2, yPos) == 1) {
 		_vm->_map->_itemPoses[item].x = xPos - 2;
 		_vm->_map->_itemPoses[item].y = yPos;
 		_vm->_map->_itemPoses[item].orient = 4;
 		return;
 	}
 
-	if (xPos < Map::kMapWidth - 2 && _vm->_map->_passMap[yPos][xPos + 2] == 1) {
+	if (xPos < _vm->_map->_mapWidth - 2 && _vm->_map->getPass(xPos + 2, yPos) == 1) {
 		_vm->_map->_itemPoses[item].x = xPos + 2;
 		_vm->_map->_itemPoses[item].y = yPos;
 		_vm->_map->_itemPoses[item].orient = 0;
 		return;
 	}
 
-	if (xPos < Map::kMapWidth - 1 && _vm->_map->_passMap[yPos][xPos + 1] == 1) {
+	if (xPos < _vm->_map->_mapWidth - 1 && _vm->_map->getPass(xPos + 1, yPos) == 1) {
 		_vm->_map->_itemPoses[item].x = xPos + 1;
 		_vm->_map->_itemPoses[item].y = yPos;
 		_vm->_map->_itemPoses[item].orient = 0;
 		return;
 	}
 
-	if (xPos > 0 && _vm->_map->_passMap[yPos][xPos - 1] == 1) {
+	if (xPos > 0 && _vm->_map->getPass(xPos - 1, yPos) == 1) {
 		_vm->_map->_itemPoses[item].x = xPos - 1;
 		_vm->_map->_itemPoses[item].y = yPos;
 		_vm->_map->_itemPoses[item].orient = 4;

Modified: scummvm/trunk/engines/gob/inter.h
===================================================================
--- scummvm/trunk/engines/gob/inter.h	2006-05-29 18:06:02 UTC (rev 22753)
+++ scummvm/trunk/engines/gob/inter.h	2006-05-29 18:24:52 UTC (rev 22754)
@@ -62,6 +62,7 @@
 	void manipulateMap(int16 xPos, int16 yPos, int16 item);
 	virtual int16 loadSound(int16 slot) = 0;
 	virtual void storeMouse(void) = 0;
+	virtual void animPalette(void) = 0;
 
 	Inter(GobEngine *vm);
 	virtual ~Inter() {};
@@ -77,7 +78,6 @@
 	virtual const char *getOpcodeFuncDesc(byte i, byte j) = 0;
 	virtual const char *getOpcodeGoblinDesc(int i) = 0;
 	virtual void loadMult(void) = 0;
-	virtual void animPalette(void) = 0;
 };
 
 class Inter_v1 : public Inter {
@@ -86,6 +86,7 @@
 	virtual ~Inter_v1() {};
 	virtual int16 loadSound(int16 slot);
 	virtual void storeMouse(void);
+	virtual void animPalette(void);
 
 protected:
 	typedef void (Inter_v1::*OpcodeDrawProcV1)(void);
@@ -116,7 +117,6 @@
 	virtual const char *getOpcodeFuncDesc(byte i, byte j);
 	virtual const char *getOpcodeGoblinDesc(int i);
 	virtual void loadMult(void);
-	virtual void animPalette(void);
 
 	void o1_loadMult(void);
 	void o1_playMult(void);
@@ -278,6 +278,7 @@
 	virtual ~Inter_v2() {};
 	virtual int16 loadSound(int16 search);
 	virtual void storeMouse(void);
+	virtual void animPalette(void);
 
 protected:
 	typedef void (Inter_v2::*OpcodeDrawProcV2)(void);
@@ -308,16 +309,13 @@
 	virtual const char *getOpcodeFuncDesc(byte i, byte j);
 	virtual const char *getOpcodeGoblinDesc(int i);
 	virtual void loadMult(void);
-	virtual void animPalette(void);
 
 	void o2_drawStub(void) { error("Gob2 stub"); }
 	void o2_totSub(void);
 	void o2_switchTotSub(void);
-	void o2_stub0x52(void);
 	void o2_stub0x54(void);
 	void o2_stub0x80(void);
 	void o2_stub0x82(void);
-	void o2_stub0x83(void);
 	void o2_stub0x85(void);
 	void o2_renderStatic(void);
 	bool o2_animPalInit(char &cmdCount, int16 &counter, int16 &retFlag);
@@ -332,6 +330,7 @@
 	void o2_freeGoblins(void);
 	void o2_writeGoblinPos(void);
 	void o2_placeGoblin(void);
+	void o2_moveGoblin(void);
 	void o2_multSub(void);
 	void o2_setRenderFlags(void);
 	void o2_initMult(void);
@@ -343,6 +342,7 @@
 	void o2_getCDTrackPos(void);
 	void o2_playMult(void);
 	void o2_initCursor(void);
+	void o2_playImd(void);
 	void o2_setPickable(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
 };
 

Modified: scummvm/trunk/engines/gob/inter_v1.cpp
===================================================================
--- scummvm/trunk/engines/gob/inter_v1.cpp	2006-05-29 18:06:02 UTC (rev 22753)
+++ scummvm/trunk/engines/gob/inter_v1.cpp	2006-05-29 18:24:52 UTC (rev 22754)
@@ -1485,7 +1485,20 @@
 }
 
 void Inter_v1::o1_updateAnim(void) {
-	_vm->_scenery->interUpdateAnim();
+	int16 deltaX;
+	int16 deltaY;
+	int16 flags;
+	int16 frame;
+	int16 layer;
+	int16 animation;
+
+	evalExpr(&deltaX);
+	evalExpr(&deltaY);
+	evalExpr(&animation);
+	evalExpr(&layer);
+	evalExpr(&frame);
+	flags = load16();
+	_vm->_scenery->updateAnim(layer, frame, animation, flags, deltaX, deltaY, 1);
 }
 
 void Inter_v1::o1_initMult(void) {
@@ -2230,7 +2243,7 @@
 	int16 xPos = load16();
 	int16 yPos = load16();
 	int16 val = load16();
-	_vm->_map->_passMap[yPos][xPos] = val;
+	_vm->_map->setPass(xPos, yPos, val);
 }
 
 void Inter_v1::o1_setGoblinPosH(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) {

Modified: scummvm/trunk/engines/gob/inter_v2.cpp
===================================================================
--- scummvm/trunk/engines/gob/inter_v2.cpp	2006-05-29 18:06:02 UTC (rev 22753)
+++ scummvm/trunk/engines/gob/inter_v2.cpp	2006-05-29 18:24:52 UTC (rev 22754)
@@ -227,7 +227,7 @@
 		/* 50 */
 		OPCODE(o2_loadMapObjects),
 		OPCODE(o2_freeGoblins),
-		OPCODE(o2_stub0x52),
+		OPCODE(o2_moveGoblin),
 		OPCODE(o2_writeGoblinPos),
 		/* 54 */
 		OPCODE(o2_stub0x54),
@@ -288,7 +288,7 @@
 		OPCODE(o2_stub0x80),
 		OPCODE(o2_drawStub),
 		OPCODE(o2_stub0x82),
-		OPCODE(o2_stub0x83),
+		OPCODE(o2_playImd),
 		/* 84 */
 		OPCODE(o2_drawStub),
 		OPCODE(o2_stub0x85),
@@ -712,20 +712,10 @@
 	return "";
 }
 
-void Inter_v2::o2_stub0x52(void) {
-	int16 expr1 = _vm->_parse->parseValExpr();
-	int16 expr2 = _vm->_parse->parseValExpr();
-	int16 expr3 = _vm->_parse->parseValExpr();
-
-	warning("STUB: Gob2 drawOperation 0x52 (%d %d %d)", expr1, expr2, expr3);
-}
-
 void Inter_v2::o2_stub0x54(void) {
 	int16 index = _vm->_parse->parseValExpr();
 
-	warning("STUB: Gob2 drawOperation 0x54 (%d)", index);
-
-//	_vm->_mult->_objects[index].pAnimData->field_12 = 4;
+	_vm->_mult->_objects[index].pAnimData->field_12 = 4;
 }
 
 void Inter_v2::o2_stub0x80(void) {
@@ -757,7 +747,7 @@
 	memset(_vm->_global->_redPalette, 0, 256);
 	memset(_vm->_global->_greenPalette, 0, 256);
 	memset(_vm->_global->_bluePalette, 0, 256);
-	warning("GOB2 Stub! _vid_setStubDriver");
+//	warning("GOB2 Stub! _vid_setStubDriver");
 
 	if (videoMode == 0x10) {
 		_vm->_global->_videoMode = 0x12;
@@ -820,32 +810,6 @@
 		warning("GOB2 Stub! _vid_setPixelShift(_vm->_game->_word_2FC9E, _vm->_game->_word_2FC9C);");*/
 }
 
-// some sub
-void Inter_v2::o2_stub0x83(void) {
-	char dest[128];
-	int16 expr1;
-	int16 expr2;
-	int16 expr3;
-	int16 expr4;
-	int16 expr5;
-	int16 expr6;
-	int16 expr7;
-	int16 expr8;
-
-	evalExpr(0);
-	strcpy(dest, _vm->_global->_inter_resStr);
-	expr1 = _vm->_parse->parseValExpr();
-	expr2 = _vm->_parse->parseValExpr();
-	expr3 = _vm->_parse->parseValExpr();
-	expr4 = _vm->_parse->parseValExpr();
-	expr5 = _vm->_parse->parseValExpr();
-	expr6 = _vm->_parse->parseValExpr();
-	expr7 = _vm->_parse->parseValExpr();
-	expr8 = _vm->_parse->parseValExpr();
-	
-	warning("STUB: Gob2 drawOperation 0x83 (\"%s\" %d %d %d %d %d %d %d %d)", dest, expr1, expr2, expr3, expr4, expr5, expr6, expr7, expr8);
-}
-
 void Inter_v2::o2_stub0x85(void) {
 	char dest[32];
 
@@ -977,6 +941,28 @@
 	_vm->_goblin->placeObject(0, 0, index, x, y, state);
 }
 
+void Inter_v2::o2_moveGoblin(void) {
+	Mult::Mult_Object *obj;
+	Mult::Mult_AnimData *objAnim;
+	int16 destX = _vm->_parse->parseValExpr();
+	int16 destY = _vm->_parse->parseValExpr();
+	int16 index = _vm->_parse->parseValExpr();
+
+	obj = &_vm->_mult->_objects[index];
+	objAnim = obj->pAnimData;
+
+	obj->gobDestX = destX;
+	obj->gobDestY = destY;
+	objAnim->field_13 = destX;
+	objAnim->field_14 = destY;
+	if (objAnim->someFlag != 0) {
+		if ((destX == -1) && (destY == -1)) {
+			warning("STUB: Gob2 drawOperation moveGoblin (%d %d %d), someFlag: %d", destX, destY, index, objAnim->someFlag);
+		}
+	}
+	_vm->_goblin->initiateMove(index);
+}
+
 void Inter_v2::o2_writeGoblinPos(void) {
 	int16 var1;
 	int16 var2;
@@ -1033,14 +1019,14 @@
 			objAnim = obj->pAnimData;
 
 			val = *obj->pPosX % 256;
-			obj->field_1C = val;
-			obj->field_1E = val;
+			obj->destX = val;
+			obj->gobDestX = val;
 			obj->goblinX = val;
 			val = *obj->pPosY % 256;
-			obj->field_1D = val;
-			obj->field_1F = val;
+			obj->destY = val;
+			obj->gobDestY = val;
 			obj->goblinY = val;
-			*obj->pPosX *= _vm->_mult->_word_2F2B1;
+			*obj->pPosX *= _vm->_map->_tilesWidth;
 			objAnim->field_15 = objAnim->unknown;
 			objAnim->field_E = -1;
 			objAnim->field_F = -1;
@@ -1050,12 +1036,14 @@
 			objAnim->animation = obj->goblinStates[objAnim->state][0].animation;
 			animation = objAnim->animation;
 			_vm->_scenery->updateAnim(objAnim->state, 0, 0, 0, *obj->pPosX, *obj->pPosY, 0);
-			if (_vm->_mult->_word_2CC86 == 0) {
-				*obj->pPosY = (obj->goblinY + 1) * _vm->_mult->_word_2F2AF; //- (_vm->_scenery->_animBottom - _vm->_scenery->_animTop)
+			if (!_vm->_map->_bigTiles) {
+				*obj->pPosY = (obj->goblinY + 1) * _vm->_map->_tilesHeight
+					- (_vm->_scenery->_animBottom - _vm->_scenery->_animTop);
 			} else {
-				*obj->pPosY = (obj->goblinY + 1) * _vm->_mult->_word_2F2AF; //- (_vm->_scenery->_animBottom - _vm->_scenery->_animTop) - (obj->goblinY + 1) / 2;
+				*obj->pPosY = ((obj->goblinY + 1) / 2) * _vm->_map->_tilesHeight
+					- (_vm->_scenery->_animBottom - _vm->_scenery->_animTop);
 			}
-			*obj->pPosX = obj->goblinX * _vm->_mult->_word_2F2B1;
+			*obj->pPosX = obj->goblinX * _vm->_map->_tilesWidth;
 		}
 	}
 	if (_vm->_mult->_objects[objIndex].pAnimData->animType == 101) {
@@ -1675,6 +1663,53 @@
 	}
 }
 
+void Inter_v2::o2_playImd(void) {
+	char imd[128];
+	int i;
+	int16 x;
+	int16 y;
+	int16 startFrame; // di
+	int16 lastFrame; // si
+	int16 breakKey;
+	int16 flags;
+	int16 expr7;
+	int16 expr8;
+
+	evalExpr(0);
+	_vm->_global->_inter_resStr[8] = 0;
+	strcpy(imd, _vm->_global->_inter_resStr);
+	x = _vm->_parse->parseValExpr();
+	y = _vm->_parse->parseValExpr();
+	startFrame = _vm->_parse->parseValExpr();
+	lastFrame = _vm->_parse->parseValExpr();
+	breakKey = _vm->_parse->parseValExpr();
+	flags = _vm->_parse->parseValExpr();
+	expr7 = _vm->_parse->parseValExpr();
+	expr8 = _vm->_parse->parseValExpr();
+	
+	if (_vm->_game->openImd(imd, x, y, startFrame, flags) == 0)
+		return;
+
+	int16 var_C;
+
+	var_C = lastFrame;
+	if (lastFrame < 0)
+		lastFrame = _vm->_game->_imdFile->framesCount - 1;
+	for (i = startFrame; i <= lastFrame; i++) {
+		_vm->_game->playImd(i, 1 << (flags & 0x3F), expr7, expr8, 0, lastFrame);
+		WRITE_VAR(11, i);
+		if (breakKey != 0) {
+			_vm->_util->getMouseState(&_vm->_global->_inter_mouseX,
+					&_vm->_global->_inter_mouseY, &_vm->_game->_mouseButtons);
+			storeKey(_vm->_util->checkKey());
+			if (VAR(0) == (unsigned) breakKey)
+				return;
+		}
+	}
+	if (var_C == -1)
+		_vm->_game->closeImd();
+}
+
 void Inter_v2::o2_totSub(void) {
 	char totFile[14];
 	int flags;

Modified: scummvm/trunk/engines/gob/map.cpp
===================================================================
--- scummvm/trunk/engines/gob/map.cpp	2006-05-29 18:06:02 UTC (rev 22753)
+++ scummvm/trunk/engines/gob/map.cpp	2006-05-29 18:24:52 UTC (rev 22754)
@@ -33,22 +33,27 @@
 #include "gob/goblin.h"
 #include "gob/sound.h"
 #include "gob/scenery.h"
+#include "gob/mult.h"
 
 namespace Gob {
 
 Map::Map(GobEngine *vm) : _vm(vm) {
 	int i;
 
-	for (i = 0; i < kMapHeight; i++)
-		for (int j = 0; j < kMapWidth; j++) {
-			_passMap[i][j] = 0;
-			_itemsMap[i][j] = 0;
-		}
+	_mapWidth = -1;
+	_mapHeight = -1;
+	_screenWidth = 0;
+	_tilesWidth = 0;
+	_tilesHeight = 0;
+	_passWidth = 0;
+
+	_passMap = 0;
+	_itemsMap = 0;
+	_wayPointsCount = 0;
+	_wayPoints = 0;
+	_bigTiles = false;
+
 	for (i = 0; i < 40; i++) {
-		_wayPoints[i].x = 0;
-		_wayPoints[i].y = 0;
-	}
-	for (i = 0; i < 40; i++) {
 		_itemPoses[i].x = 0;
 		_itemPoses[i].y = 0;
 		_itemPoses[i].orient = 0;
@@ -85,7 +90,7 @@
 	if (x0 == x1 && y0 == y1)
 		return 0;
 
-	if (!(x1 >= 0 && x1 < kMapWidth && y1 >= 0 && y1 < kMapHeight))
+	if (!(x1 >= 0 && x1 < _mapWidth && y1 >= 0 && y1 < _mapHeight))
 		return 0;
 
 	if (y1 > y0)
@@ -98,91 +103,91 @@
 	else if (x1 < x0)
 		dir |= kLeft;
 
-	if (_passMap[y0][x0] == 3 && (dir & kUp)) {
-		if (_passMap[y0 - 1][x0] != 0)
+	if (getPass(x0, y0) == 3 && (dir & kUp)) {
+		if (getPass(x0, y0 - 1) != 0)
 			return kDirN;
 	}
 
-	if (_passMap[y0][x0] == 3 && (dir & kDown)) {
-		if (_passMap[y0 + 1][x0] != 0)
+	if (getPass(x0, y0) == 3 && (dir & kDown)) {
+		if (getPass(x0, y0 + 1) != 0)
 			return kDirS;
 	}
 
-	if (_passMap[y0][x0] == 6 && (dir & kUp)) {
-		if (_passMap[y0 - 1][x0] != 0)
+	if (getPass(x0, y0) == 6 && (dir & kUp)) {
+		if (getPass(x0, y0 - 1) != 0)
 			return kDirN;
 	}
 
-	if (_passMap[y0][x0] == 6 && (dir & kDown)) {
-		if (_passMap[y0 + 1][x0] != 0)
+	if (getPass(x0, y0) == 6 && (dir & kDown)) {
+		if (getPass(x0, y0 + 1) != 0)
 			return kDirS;
 	}
 
 	if (dir == kLeft) {
-		if (x0 - 1 >= 0 && _passMap[y0][x0 - 1] != 0)
+		if (x0 - 1 >= 0 && getPass(x0 - 1, y0) != 0)
 			return kDirW;
 		return 0;
 	}
 
 	if (dir == kRight) {
-		if (x0 + 1 < kMapWidth && _passMap[y0][x0 + 1] != 0)
+		if (x0 + 1 < _mapWidth && getPass(x0 + 1, y0) != 0)
 			return kDirE;
 		return 0;
 	}
 
 	if (dir == kUp) {
-		if (y0 - 1 >= 0 && _passMap[y0 - 1][x0] != 0)
+		if (y0 - 1 >= 0 && getPass(x0, y0 - 1) != 0)
 			return kDirN;
 
 		if (y0 - 1 >= 0 && x0 - 1 >= 0
-		    && _passMap[y0 - 1][x0 - 1] != 0)
+		    && getPass(x0 - 1, y0 - 1) != 0)
 			return kDirNW;
 
-		if (y0 - 1 >= 0 && x0 + 1 < kMapWidth
-		    && _passMap[y0 - 1][x0 + 1] != 0)
+		if (y0 - 1 >= 0 && x0 + 1 < _mapWidth
+		    && getPass(x0 + 1, y0 - 1) != 0)
 			return kDirNE;
 
 		return 0;
 	}
 
 	if (dir == kDown) {
-		if (y0 + 1 < kMapHeight && _passMap[y0 + 1][x0] != 0)
+		if (y0 + 1 < _mapHeight && getPass(x0, y0 + 1) != 0)
 			return kDirS;
 
-		if (y0 + 1 < kMapHeight && x0 - 1 >= 0
-		    && _passMap[y0 + 1][x0 - 1] != 0)
+		if (y0 + 1 < _mapHeight && x0 - 1 >= 0
+		    && getPass(x0 - 1, y0 + 1) != 0)
 			return kDirSW;
 
-		if (y0 + 1 < kMapHeight && x0 + 1 < kMapWidth
-		    && _passMap[y0 + 1][x0 + 1] != 0)
+		if (y0 + 1 < _mapHeight && x0 + 1 < _mapWidth
+		    && getPass(x0 + 1, y0 + 1) != 0)
 			return kDirSE;
 
 		return 0;
 	}
 
 	if (dir == (kRight | kUp)) {
-		if (y0 - 1 >= 0 && x0 + 1 < kMapWidth
-		    && _passMap[y0 - 1][x0 + 1] != 0)
+		if (y0 - 1 >= 0 && x0 + 1 < _mapWidth
+		    && getPass(x0 + 1, y0 - 1) != 0)
 			return kDirNE;
 
-		if (y0 - 1 >= 0 && _passMap[y0 - 1][x0] != 0)
+		if (y0 - 1 >= 0 && getPass(x0, y0 - 1) != 0)
 			return kDirN;
 
-		if (x0 + 1 < kMapWidth && _passMap[y0][x0 + 1] != 0)
+		if (x0 + 1 < _mapWidth && getPass(x0 + 1, y0) != 0)
 			return kDirE;
 
 		return 0;
 	}
 
 	if (dir == (kRight | kDown)) {
-		if (x0 + 1 < kMapWidth && y0 + 1 < kMapHeight
-		    && _passMap[y0 + 1][x0 + 1] != 0)
+		if (x0 + 1 < _mapWidth && y0 + 1 < _mapHeight
+		    && getPass(x0 + 1, y0 + 1) != 0)
 			return kDirSE;
 
-		if (y0 + 1 < kMapHeight && _passMap[y0 + 1][x0] != 0)
+		if (y0 + 1 < _mapHeight && getPass(x0, y0 + 1) != 0)
 			return kDirS;
 
-		if (x0 + 1 < kMapWidth && _passMap[y0][x0 + 1] != 0)
+		if (x0 + 1 < _mapWidth && getPass(x0 + 1, y0) != 0)
 			return kDirE;
 
 		return 0;
@@ -190,27 +195,27 @@
 
 	if (dir == (kLeft | kUp)) {
 		if (x0 - 1 >= 0 && y0 - 1 >= 0
-		    && _passMap[y0 - 1][x0 - 1] != 0)
+		    && getPass(x0 - 1, y0 - 1) != 0)
 			return kDirNW;
 
-		if (y0 - 1 >= 0 && _passMap[y0 - 1][x0] != 0)
+		if (y0 - 1 >= 0 && getPass(x0, y0 - 1) != 0)
 			return kDirN;
 
-		if (x0 - 1 >= 0 && _passMap[y0][x0 - 1] != 0)
+		if (x0 - 1 >= 0 && getPass(x0 - 1, y0) != 0)
 			return kDirW;
 
 		return 0;
 	}
 
 	if (dir == (kLeft | kDown)) {
-		if (x0 - 1 >= 0 && y0 + 1 < kMapHeight
-		    && _passMap[y0 + 1][x0 - 1] != 0)
+		if (x0 - 1 >= 0 && y0 + 1 < _mapHeight
+		    && getPass(x0 - 1, y0 + 1) != 0)
 			return kDirSW;
 
-		if (y0 + 1 < kMapHeight && _passMap[y0 + 1][x0] != 0)
+		if (y0 + 1 < _mapHeight && getPass(x0, y0 + 1) != 0)
 			return kDirS;
 
-		if (x0 - 1 >= 0 && _passMap[y0][x0 - 1] != 0)
+		if (x0 - 1 >= 0 && getPass(x0 - 1, y0) != 0)
 			return kDirW;
 
 		return 0;
@@ -226,10 +231,10 @@
 
 	length = 30000;
 
-	for (i = 0; i < 40; i++) {
+	for (i = 0; i < _wayPointsCount; i++) {
 		if (_wayPoints[i].x < 0 ||
-				_wayPoints[i].x >= kMapWidth ||
-				_wayPoints[i].y < 0 || _wayPoints[i].y >= kMapHeight)
+				_wayPoints[i].x >= _mapWidth ||
+				_wayPoints[i].y < 0 || _wayPoints[i].y >= _mapHeight)
 			return -1;
 
 		tmp = ABS(x - _wayPoints[i].x) + ABS(y - _wayPoints[i].y);
@@ -243,26 +248,24 @@
 	return lnearestWayPoint;
 }
 
-void Map::findNearestToGob(void) {
-	int16 wayPoint = findNearestWayPoint(_curGoblinX, _curGoblinY);
-
-	if (wayPoint != -1)
-		_nearestWayPoint = wayPoint;
-}
-
-void Map::findNearestToDest(void) {
-	int16 wayPoint = findNearestWayPoint(_destX, _destY);
-
-	if (wayPoint != -1)
-		_nearestDest = wayPoint;
-}
-
-int16 Map::checkDirectPath(int16 x0, int16 y0, int16 x1, int16 y1) {
+int16 Map::checkDirectPath(int16 index, int16 x0, int16 y0, int16 x1, int16 y1) {
+	Mult::Mult_Object *obj = 0;
 	uint16 dir;
 
+	if ((index >= 0) && (index < _vm->_mult->_objCount))
+		obj = &_vm->_mult->_objects[index];
+
 	while (1) {
 		dir = getDirection(x0, y0, x1, y1);
 
+		if (obj) {
+			if (obj->nearestWayPoint < obj->nearestDest)
+				if (_wayPoints[obj->nearestWayPoint + 1].field_2 == 1)
+					return 3;
+			if (_wayPoints[obj->nearestDest - 1].field_2 == 1)
+				return 3;
+		}
+
 		if (x0 == x1 && y0 == y1)
 			return 1;
 
@@ -326,7 +329,7 @@
 			nextLink = 1;
 
 		if (nextLink != 0) {
-			if (checkDirectPath(x0, y0, x1, y1) == 1)
+			if (checkDirectPath(-1, x0, y0, x1, y1) == 1)
 				return 1;
 
 			nextLink = 0;
@@ -345,7 +348,7 @@
 		}
 		if (i0 == i1 && _wayPoints[i0].x == x0
 		    && _wayPoints[i0].y == y0) {
-			if (checkDirectPath(x0, y0, x1, y1) == 1)
+			if (checkDirectPath(-1, x0, y0, x1, y1) == 1)
 				return 1;
 			return 0;
 		}
@@ -393,24 +396,6 @@
 	}
 }
 
-void Map::optimizePoints(void) {
-	int16 i;
-
-	if (_nearestWayPoint < _nearestDest) {
-		for (i = _nearestWayPoint; i <= _nearestDest; i++) {
-			if (checkDirectPath(_curGoblinX, _curGoblinY,
-				_wayPoints[i].x, _wayPoints[i].y) == 1)
-				_nearestWayPoint = i;
-		}
-	} else if (_nearestWayPoint > _nearestDest) {
-		for (i = _nearestWayPoint; i >= _nearestDest; i--) {
-			if (checkDirectPath(_curGoblinX, _curGoblinY,
-				_wayPoints[i].x, _wayPoints[i].y) == 1)
-				_nearestWayPoint = i;
-		}
-	}
-}
-
 void Map::loadDataFromAvo(char *dest, int16 size) {
 	memcpy(dest, _avoDataPtr, size);
 	_avoDataPtr += size;

Modified: scummvm/trunk/engines/gob/map.h
===================================================================
--- scummvm/trunk/engines/gob/map.h	2006-05-29 18:06:02 UTC (rev 22753)
+++ scummvm/trunk/engines/gob/map.h	2006-05-29 18:24:52 UTC (rev 22754)
@@ -23,6 +23,8 @@
 #ifndef GOB_MAP_H
 #define GOB_MAP_H
 
+#include "gob/util.h"
+
 namespace Gob {
 
 // The same numeric values are also used for the arrow keys.
@@ -39,16 +41,13 @@
 		kDirS  = 0x5000,
 		kDirSE = 0x5100
 	};
-	enum {
-		kMapWidth  = 26,
-		kMapHeight = 28
-	};
 
 #pragma START_PACK_STRUCTS
 
 	struct Point {
 		int16 x;
 		int16 y;
+		int16 field_2; // Gob2
 	} GCC_PACK;
 
 #define szMap_ItemPos 3
@@ -61,13 +60,22 @@
 
 #pragma END_PACK_STRUCTS
 
-	int8 _passMap[kMapHeight][kMapWidth];	// [y][x]
-	int16 _itemsMap[kMapHeight][kMapWidth];	// [y][x]
-	Point _wayPoints[40];
+	int16 _mapWidth;
+	int16 _mapHeight;
+	int16 _screenWidth;
+	int16 _tilesWidth;
+	int16 _tilesHeight;
+	int16 _passWidth;
+	bool _bigTiles;
+
+	int8 *_passMap; // [y * _mapWidth + x], getPass(x, y);
+	int16 **_itemsMap;	// [y][x]
+	int16 _wayPointsCount;
+	Point *_wayPoints;
 	int16 _nearestWayPoint;
 	int16 _nearestDest;
 
-   	int16 _curGoblinX;
+	int16 _curGoblinX;
 	int16 _curGoblinY;
 	int16 _destX;
 	int16 _destY;
@@ -79,16 +87,19 @@
 	void placeItem(int16 x, int16 y, int16 id);
 
 	int16 getDirection(int16 x0, int16 y0, int16 x1, int16 y1);
-	void findNearestToGob(void);
-	void findNearestToDest(void);
-	int16 checkDirectPath(int16 x0, int16 y0, int16 x1, int16 y1);
+	int16 checkDirectPath(int16 index, int16 x0, int16 y0, int16 x1, int16 y1);
 	int16 checkLongPath(int16 x0, int16 y0, int16 x1, int16 y1, int16 i0, int16 i1);
-	void optimizePoints(void);
 	void loadItemToObject(void);
 	void loadDataFromAvo(char *dest, int16 size);
 	void loadMapsInitGobs(void);
 
+	virtual int8 getPass(int x, int y, int heightOff = -1) = 0;
+	virtual void setPass(int x, int y, int8 pass, int heightOff = -1) = 0;
+
 	virtual void loadMapObjects(char *avjFile) = 0;
+	virtual void findNearestToGob(int16 index) = 0;
+	virtual void findNearestToDest(int16 index) = 0;
+	virtual void optimizePoints(int16 index, int16 x, int16 y) = 0;
 
 	Map(GobEngine *vm);
 	virtual ~Map() {};
@@ -104,15 +115,41 @@
 class Map_v1 : public Map {
 public:
 	virtual void loadMapObjects(char *avjFile);
+	virtual void optimizePoints(int16 index, int16 x, int16 y);
+	virtual void findNearestToGob(int16 index);
+	virtual void findNearestToDest(int16 index);
 
+	virtual inline int8 getPass(int x, int y, int heightOff = -1) {
+		return _passMap[y * _mapWidth + x];
+	}
+	
+	virtual inline void setPass(int x, int y, int8 pass, int heightOff = -1) {
+		_passMap[y * _mapWidth + x] = pass;
+	}
+
 	Map_v1(GobEngine *vm);
-	virtual ~Map_v1() {};
+	virtual ~Map_v1();
 };
 
 class Map_v2 : public Map_v1 {
 public:
 	virtual void loadMapObjects(char *avjFile);
+	virtual void optimizePoints(int16 index, int16 x, int16 y);
+	virtual void findNearestToGob(int16 index);
+	virtual void findNearestToDest(int16 index);
 
+	virtual inline int8 getPass(int x, int y, int heightOff = -1) {
+		if (heightOff == -1)
+			heightOff = _passWidth;
+		return _vm->_util->readVariableByte((char *) (_passMap + y * heightOff + x));
+	}
+	
+	virtual inline void setPass(int x, int y, int8 pass, int heightOff = -1) {
+		if (heightOff == -1)
+			heightOff = _passWidth;
+		_vm->_util->writeVariableByte((char *) (_passMap + y * heightOff + x) , pass);
+	}
+
 	Map_v2(GobEngine *vm);
 	virtual ~Map_v2() {};
 };

Modified: scummvm/trunk/engines/gob/map_v1.cpp
===================================================================
--- scummvm/trunk/engines/gob/map_v1.cpp	2006-05-29 18:06:02 UTC (rev 22753)
+++ scummvm/trunk/engines/gob/map_v1.cpp	2006-05-29 18:24:52 UTC (rev 22754)
@@ -29,12 +29,41 @@
 #include "gob/dataio.h"
 #include "gob/goblin.h"
 #include "gob/sound.h"
+#include "gob/scenery.h"
+#include "gob/mult.h"
 
 namespace Gob {
 
 Map_v1::Map_v1(GobEngine *vm) : Map(vm) {
+	int i;
+	int j;
+
+	_mapWidth = 26;
+	_mapHeight = 28;
+
+	_passMap = new int8[_mapHeight * _mapWidth];
+	_itemsMap = new int16*[_mapHeight];
+	for (i = 0; i < _mapHeight; i++) {
+		_itemsMap[i] = new int16[_mapWidth];
+		for (j = 0; j < _mapWidth; j++) {
+			setPass(j, i, 0);
+			_itemsMap[i][j] = 0;
+		}
+	}
+
+	_wayPointsCount = 40;
+	_wayPoints = new Point[40];
+	for (i = 0; i < 40; i++) {
+		_wayPoints[i].x = 0;
+		_wayPoints[i].y = 0;
+		_wayPoints[i].field_2 = 0;
+	}
 }
 
+Map_v1::~Map_v1() {
+	delete[] _passMap;
+}
+
 void Map_v1::loadMapObjects(char *avjFile) {
 	int16 i;
 	char avoName[128];
@@ -66,10 +95,10 @@
 		_vm->_dataio->closeData(handle);
 		_avoDataPtr = _vm->_dataio->getData(avoName);
 		dataBuf = _avoDataPtr;
-		loadDataFromAvo((char *)_passMap, kMapHeight * kMapWidth);
+		loadDataFromAvo((char *)_passMap, _mapHeight * _mapWidth);
 
-		for (y = 0; y < kMapHeight; y++) {
-			for (x = 0; x < kMapWidth; x++) {
+		for (y = 0; y < _mapHeight; y++) {
+			for (x = 0; x < _mapWidth; x++) {
 				loadDataFromAvo(&item, 1);
 				_itemsMap[y][x] = item;
 			}
@@ -343,4 +372,36 @@
 	}
 }
 
+void Map_v1::optimizePoints(int16 index, int16 x, int16 y) {
+	int16 i;
+
+	if (_nearestWayPoint < _nearestDest) {
+		for (i = _nearestWayPoint; i <= _nearestDest; i++) {
+			if (checkDirectPath(-1, _curGoblinX, _curGoblinY,
+				_wayPoints[i].x, _wayPoints[i].y) == 1)
+				_nearestWayPoint = i;
+		}
+	} else if (_nearestWayPoint > _nearestDest) {
+		for (i = _nearestWayPoint; i >= _nearestDest; i--) {
+			if (checkDirectPath(-1, _curGoblinX, _curGoblinY,
+				_wayPoints[i].x, _wayPoints[i].y) == 1)
+				_nearestWayPoint = i;
+		}
+	}
+}
+
+void Map_v1::findNearestToGob(int16 index) {
+	int16 wayPoint = findNearestWayPoint(_curGoblinX, _curGoblinY);
+
+	if (wayPoint != -1)
+		_nearestWayPoint = wayPoint;
+}
+
+void Map_v1::findNearestToDest(int16 index) {
+	int16 wayPoint = findNearestWayPoint(_destX, _destY);
+
+	if (wayPoint != -1)
+		_nearestDest = wayPoint;
+}
+
 } // End of namespace Gob

Modified: scummvm/trunk/engines/gob/map_v2.cpp
===================================================================
--- scummvm/trunk/engines/gob/map_v2.cpp	2006-05-29 18:06:02 UTC (rev 22753)
+++ scummvm/trunk/engines/gob/map_v2.cpp	2006-05-29 18:24:52 UTC (rev 22754)
@@ -33,6 +33,7 @@
 #include "gob/game.h"
 #include "gob/parse.h"
 #include "gob/mult.h"
+#include "gob/scenery.h"
 
 namespace Gob {
 
@@ -43,11 +44,11 @@
 	int i;
 	int j;
 	int k;
+	uint8 wayPointsCount;
 	int16 var;
 	int16 id;
-	int16 numChunks;
-	int16 chunkLength;
-	int16 offVar;
+	int16 mapHeight;
+	int16 mapWidth;
 	int16 offData;
 	int16 tmp;
 	int16 numData;
@@ -61,17 +62,13 @@
 	char statesMask[102];
 	Goblin::Gob2_State *statesPtr;
 
-	uint8 var_9;
-	uint8 byte_2F2AA;
-	byte *off_2F2AB;
-
 	var = _vm->_parse->parseVarIndex();
 	variables = _vm->_global->_inter_variables + var;
 
 	id = _vm->_inter->load16();
 
 	if (id == -1) {
-		_vm->_goblin->_dword_2F2A4 = _vm->_global->_inter_variables + var;
+		_passMap = (int8 *)(_vm->_global->_inter_variables + var);
 		return;
 	}
 
@@ -79,51 +76,53 @@
 	dataPtr = extData;
 
 	if (*dataPtr++ == 3) {
-		_vm->_mult->_word_2F22A = 640;
-		_vm->_mult->_word_2CC84 = 65;
+		_vm->_map->_screenWidth = 640;
+		_vm->_map->_passWidth = 65;
 	} else {
-		_vm->_mult->_word_2F22A = 320;
-		_vm->_mult->_word_2CC84 = 40;
+		_vm->_map->_screenWidth = 320;
+		_vm->_map->_passWidth = 40;
 	}
-	byte_2F2AA = *dataPtr++;
-	_vm->_mult->_word_2F2B1 = READ_LE_UINT16(dataPtr);
+	_wayPointsCount = *dataPtr++;
+	_vm->_map->_tilesWidth = READ_LE_UINT16(dataPtr);
 	dataPtr += 2;
-	_vm->_mult->_word_2F2AF = READ_LE_UINT16(dataPtr);
+	_vm->_map->_tilesHeight = READ_LE_UINT16(dataPtr);
 	dataPtr += 2;
 
-	_vm->_mult->_word_2CC86 = _vm->_mult->_word_2F2AF & 0xFF00 ? 0 : 1;
-	_vm->_mult->_word_2F2AF &= 0xFF;
+	_vm->_map->_bigTiles = !(_vm->_map->_tilesHeight & 0xFF00);
+	_vm->_map->_tilesHeight &= 0xFF;
 
+	_mapWidth = _vm->_map->_screenWidth / _vm->_map->_tilesWidth;
+	_mapHeight = 200 / _vm->_map->_tilesHeight;
+
 	dataPtrBak = dataPtr;
-	dataPtr += (_vm->_mult->_word_2F22A / _vm->_mult->_word_2F2B1) * (200 / _vm->_mult->_word_2F2AF);
+	dataPtr += _mapWidth * _mapHeight;
 
-	if (*extData == 1) {
-		byte_2F2AA = 40;
-		var_9 = 40;
-	} else {
-		if (byte_2F2AA == 0) {
-			var_9 = 1;
-		} else {
-			var_9 = byte_2F2AA;
-		}
+	if (*extData == 1)
+		wayPointsCount = _wayPointsCount = 40;
+	else
+		wayPointsCount = _wayPointsCount == 0 ? 1 : _wayPointsCount;
+
+	_wayPoints = new Point[wayPointsCount];
+	for (i = 0; i < wayPointsCount; i++) {
+		_wayPoints[i].x = -1;
+		_wayPoints[i].y = -1;
+		_wayPoints[i].field_2 = -1;
 	}
+	for (i = 0; i < _wayPointsCount; i++) {
+		_wayPoints[i].x = *dataPtr++;
+		_wayPoints[i].y = *dataPtr++;
+		_wayPoints[i].field_2 = *dataPtr++;
+	}
 
-	off_2F2AB = new byte[3 * var_9];
-	memset(off_2F2AB, -1, 3 * var_9);
-	memcpy(off_2F2AB, dataPtr, 3 * byte_2F2AA);
-	dataPtr += 3 * byte_2F2AA;
-
 	// In the original asm, this writes byte-wise into the variables-array
 	if (variables != _vm->_global->_inter_variables) {
-		_vm->_goblin->_dword_2F2A4 = variables;
-		numChunks = 200 / _vm->_mult->_word_2F2AF;
-		chunkLength = _vm->_mult->_word_2F22A / _vm->_mult->_word_2F2B1;
-		for (i = 0; i < numChunks; i++) {
-			offVar = _vm->_mult->_word_2CC84 * i;
-			offData = (chunkLength * i);
-			for (j = 0; j < chunkLength; j++) {
-				_vm->_util->writeVariableByte(_vm->_goblin->_dword_2F2A4 + offVar + j,
-						*(dataPtrBak + offData + j));
+		_passMap = (int8 *) variables;
+		mapHeight = 200 / _vm->_map->_tilesHeight;
+		mapWidth = _vm->_map->_screenWidth / _vm->_map->_tilesWidth;
+		for (i = 0; i < mapHeight; i++) {
+			offData = (mapWidth * i);
+			for (j = 0; j < mapWidth; j++) {
+				setPass(j, i, *(dataPtrBak + offData + j), _vm->_map->_passWidth);
 			}
 		}
 	}
@@ -189,4 +188,42 @@
 		_vm->_goblin->_soundSlots[i] = _vm->_inter->loadSound(1);
 }
 
+void Map_v2::findNearestToGob(int16 index) {
+	Mult::Mult_Object *obj = &_vm->_mult->_objects[index];
+	int16 wayPoint = findNearestWayPoint(obj->goblinX, obj->goblinY);
+
+	if (wayPoint != -1)
+		obj->nearestWayPoint = wayPoint;
+}
+
+void Map_v2::findNearestToDest(int16 index) {
+	Mult::Mult_Object *obj = &_vm->_mult->_objects[index];
+	int16 wayPoint = findNearestWayPoint(obj->destX, obj->destY);
+
+	if (wayPoint != -1)
+		obj->nearestDest = wayPoint;
+}
+
+void Map_v2::optimizePoints(int16 index, int16 x, int16 y) {
+	Mult::Mult_Object *obj;
+	int i;
+	
+	int16 var_2;
+
+	obj = &_vm->_mult->_objects[index];
+
+	if (obj->nearestWayPoint < obj->nearestDest) {
+		var_2 = obj->nearestWayPoint;
+		for (i = obj->nearestWayPoint; i <= obj->nearestDest; i++) {
+			if (checkDirectPath(index, x, y, _wayPoints[i].x, _wayPoints[i].y) == 1)
+				obj->nearestWayPoint = i;
+		}
+	} else {
+		for (i = obj->nearestWayPoint; i >= obj->nearestDest && _wayPoints[i].field_2 != 1; i--) {
+			if (checkDirectPath(index, x, y, _wayPoints[i].x, _wayPoints[i].y) == 1)
+				obj->nearestWayPoint = i;
+		}
+	}
+}
+
 } // End of namespace Gob

Modified: scummvm/trunk/engines/gob/module.mk
===================================================================
--- scummvm/trunk/engines/gob/module.mk	2006-05-29 18:06:02 UTC (rev 22753)
+++ scummvm/trunk/engines/gob/module.mk	2006-05-29 18:24:52 UTC (rev 22754)
@@ -35,6 +35,8 @@
 	parse_v1.o \
 	parse_v2.o \
 	scenery.o \
+	scenery_v1.o \
+	scenery_v2.o \
 	sound.o \
 	timer.o \
 	util.o \

Modified: scummvm/trunk/engines/gob/mult.cpp
===================================================================
--- scummvm/trunk/engines/gob/mult.cpp	2006-05-29 18:06:02 UTC (rev 22753)
+++ scummvm/trunk/engines/gob/mult.cpp	2006-05-29 18:24:52 UTC (rev 22754)
@@ -120,12 +120,6 @@
 		}
 
 	_orderArray = 0;
-	warning("GOB2 Stub! _word_2F2B1, _word_2F2AF, _word_2CC86, _word_2F22A, _word_2CC84");
-	_word_2F2B1 = 0;
-	_word_2F2AF = 0;
-	_word_2CC86 = 0;
-	_word_2F22A = 0;
-	_word_2CC84 = 0;
 }
 
 void Mult::interGetObjAnimSize(void) {

Modified: scummvm/trunk/engines/gob/mult.h
===================================================================
--- scummvm/trunk/engines/gob/mult.h	2006-05-29 18:06:02 UTC (rev 22753)
+++ scummvm/trunk/engines/gob/mult.h	2006-05-29 18:24:52 UTC (rev 22754)
@@ -23,6 +23,7 @@
 #ifndef GOB_MULT_H
 #define GOB_MULT_H
 
+#include "gob/gob.h"
 #include "gob/sound.h"
 #include "gob/video.h"
 #include "gob/goblin.h"
@@ -77,10 +78,12 @@
 		int16 somethingBottom;             // New in GOB2
 		int8 goblinX;                      // New in GOB2
 		int8 goblinY;                      // New in GOB2
-		int8 field_1C;                     // New in GOB2
-		int8 field_1D;                     // New in GOB2
-		int8 field_1E;                     // New in GOB2
-		int8 field_1F;                     // New in GOB2
+		int8 destX;                        // New in GOB2
+		int8 destY;                        // New in GOB2
+		int8 gobDestX;                     // New in GOB2
+		int8 gobDestY;                     // New in GOB2
+		int8 nearestWayPoint;              // New in GOB2
+		int8 nearestDest;                  // New in GOB2
 		Goblin::Gob2_State **goblinStates; // New in GOB2
 	};
 
@@ -202,12 +205,6 @@
 
 	int8 *_orderArray;
 
-	uint16 _word_2F2B1;
-	uint16 _word_2F2AF;
-	uint16 _word_2CC86;
-	uint16 _word_2F22A;
-	uint16 _word_2CC84;
-
 	void zeroMultData(void);
 	void checkFreeMult(void);
 	void interGetObjAnimSize(void);

Modified: scummvm/trunk/engines/gob/mult_v2.cpp
===================================================================
--- scummvm/trunk/engines/gob/mult_v2.cpp	2006-05-29 18:06:02 UTC (rev 22753)
+++ scummvm/trunk/engines/gob/mult_v2.cpp	2006-05-29 18:24:52 UTC (rev 22754)
@@ -816,6 +816,7 @@
 	return stop;
 }
 
+// "deplaceheros"
 void Mult_v2::sub_62DD(int16 index) {
 	Mult_Object *animObj;
 	Mult_AnimKey *animKey;
@@ -952,6 +953,7 @@
 	WRITE_VAR(18 + index, frame);
 }
 
+// "avancerperso"
 void Mult_v2::sub_6A35(void) {
 	int i;
 	int j;
@@ -1273,7 +1275,6 @@
 
 void Mult_v2::playSound(Snd::SoundDesc * soundDesc, int16 repCount, int16 freq,
 	    int16 channel) {
-	warning("PlaySound(%p, %d, %d, %d), %d", (void *) soundDesc, repCount, freq, channel, soundDesc->frequency);
 	if (soundDesc->frequency >= 0) {
 		if (soundDesc->frequency == freq)
 			_vm->_snd->playSample(soundDesc, repCount, -channel);
@@ -1292,13 +1293,9 @@
 	char animCount;
 	char staticCount;
 
-	warning("GOB2 Stub! Mult_v2::freeMultKeys()");
-
 	if (_multData2 == 0)
 		return;
 
-	// loc_7323
-
 	staticCount = (_multData2->staticCount + 1) && 0x7F;
 	animCount = _multData2->animCount + 1;
 

Modified: scummvm/trunk/engines/gob/music.cpp
===================================================================
--- scummvm/trunk/engines/gob/music.cpp	2006-05-29 18:06:02 UTC (rev 22753)
+++ scummvm/trunk/engines/gob/music.cpp	2006-05-29 18:24:52 UTC (rev 22754)
@@ -1,6 +1,6 @@
 /* ScummVM - Scumm Interpreter
  * Copyright (C) 2006 The ScummVM project
- * Original ADL-Player source Copyright (C) 2004 by Dorian Gray
+ * Original ADL-Player source Copyright (C) 2004 by Patrick Combet aka Dorian Gray
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -337,6 +337,12 @@
 			setVolume(channel, *(_playPos++));
 			setKey(channel, note, true, false);
 			break;
+		case 0x10:
+			warning("GOB2 Stub! ADL command 0x10");
+			break;
+		case 0x50:
+			warning("GOB2 Stub! ADL command 0x50");
+			break;
 		// Note on
 		case 0x90:
 			note = *(_playPos++);
@@ -364,17 +370,23 @@
 			break;
 		// Special
 		case 0xF0:
+			switch (instr & 0x0F) {
+			case 0xF: // End instruction
+				_ended = true;
+				break;
+			default:
+				warning("Unknown special command in ADL, stopping playback: %X", instr & 0x0F);
+				_repCount = 0;
+				_ended = true;
+				break;
+			}
 			break;
 		default:
-			warning("Unknown command in ADL, stopping playback");
+			warning("Unknown command in ADL, stopping playback: %X", instr & 0xF0);
 			_repCount = 0;
 			_ended = true;
 			break;
 	}
-	// End instruction
-	if (instr == 0xFF) {
-		_ended = true;
-	}
 
 	// Temporization
 	tempo = *(_playPos++);

Modified: scummvm/trunk/engines/gob/music.h
===================================================================
--- scummvm/trunk/engines/gob/music.h	2006-05-29 18:06:02 UTC (rev 22753)
+++ scummvm/trunk/engines/gob/music.h	2006-05-29 18:24:52 UTC (rev 22754)
@@ -1,6 +1,6 @@
 /* ScummVM - Scumm Interpreter
  * Copyright (C) 2006 The ScummVM project
- * Original ADL-Player source Copyright (C) 2004 by Dorian Gray
+ * Original ADL-Player source Copyright (C) 2004 by Patrick Combet aka Dorian Gray
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -25,6 +25,7 @@
 #define GOB_MUSIC_H
 
 #include "sound/audiostream.h"
+#include "sound/mixer.h"
 #include "sound/fmopl.h"
 #include "common/mutex.h"
 
@@ -37,20 +38,20 @@
 class Music : public Audio::AudioStream {
 public:
 	Music(GobEngine *vm);
-	~Music();
+	virtual ~Music();
 
 	void lock() { _mutex.lock(); }
 	void unlock() { _mutex.unlock(); }
 	bool playing() { return _playing; }
 	bool getRepeating(void) { return _repCount != 0; }
 	void setRepeating (int32 repCount) { _repCount = repCount; }
-	void startPlay(void);
-	void stopPlay(void) { _mutex.lock(); _playing = false; _mutex.unlock(); }
-	void playTrack(const char *trackname);
-	void playBgMusic(void);
-	bool loadMusic(const char *filename);
-	void loadFromMemory(byte *data);
-	void unloadMusic(void);
+	virtual void startPlay(void);
+	virtual void stopPlay(void) { _mutex.lock(); _playing = false; _mutex.unlock(); }
+	virtual void playTrack(const char *trackname);
+	virtual void playBgMusic(void);
+	virtual bool loadMusic(const char *filename);
+	virtual void loadFromMemory(byte *data);
+	virtual void unloadMusic(void);
 
 // AudioStream API
 	int readBuffer(int16 *buffer, const int numSamples) {
@@ -96,6 +97,24 @@
 	void pollMusic(void);
 };
 
+class Music_Dummy: public Music {
+public:
+	Music_Dummy(GobEngine *vm) : Music(vm) {
+		_vm->_mixer->setupPremix(0);
+		OPLDestroy(_opl);
+	}
+
+	virtual void startPlay(void) {};
+	virtual void stopPlay(void) {};
+	virtual void playTrack(const char *trackname) {};
+	virtual void playBgMusic(void) {};
+	virtual bool loadMusic(const char *filename) { return true; };
+	virtual void loadFromMemory(byte *data) {};
+	virtual void unloadMusic(void) {};
+
+	virtual ~Music_Dummy() {};
+};
+
 } // End of namespace Gob
 
 #endif

Modified: scummvm/trunk/engines/gob/scenery.cpp
===================================================================
--- scummvm/trunk/engines/gob/scenery.cpp	2006-05-29 18:06:02 UTC (rev 22753)
+++ scummvm/trunk/engines/gob/scenery.cpp	2006-05-29 18:24:52 UTC (rev 22754)
@@ -32,7 +32,6 @@
 #include "gob/game.h"
 #include "gob/global.h"
 #include "gob/util.h"
-#include "gob/anim.h"
 #include "gob/parse.h"
 #include "gob/cdrom.h"
 
@@ -489,212 +488,6 @@
 	return sceneryIndex + 100;
 }
 
-// flags & 1 - do capture all area animation is occupying
-// flags & 4 == 0 - calculate animation final size
-// flags & 2 != 0 - don't check with "toRedraw"'s
-// flags & 4 != 0 - checkk view toRedraw
-void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags,
-	    int16 drawDeltaX, int16 drawDeltaY, char doDraw) {
-	AnimLayer *layerPtr;
-	PieceDesc **pictPtr;
-	AnimFramePiece *framePtr;
-
-	uint16 pieceIndex;
-	uint16 pictIndex;
-
-	int16 left;
-	int16 right;
-	int16 top;
-	int16 bottom;
-
-	byte highX;
-	byte highY;
-
-	int16 i;
-	int16 transp;
-
-	int16 destX;
-	int16 destY;
-
-	if (layer >= _animations[animation].layersCount)
-		return;
-
-	layerPtr = _animations[animation].layers[layer];
-
-	if (frame >= layerPtr->framesCount)
-		return;
-
-	if (flags & 1)		// Do capture
-	{
-		updateAnim(layer, frame, animation, 0, drawDeltaX,
-		    drawDeltaY, 0);
-
-		if (_toRedrawLeft == -12345)	// Some magic number?
-			return;
-
-		_vm->_game->capturePush(_toRedrawLeft, _toRedrawTop,
-		    _toRedrawRight - _toRedrawLeft + 1,
-		    _toRedrawBottom - _toRedrawTop + 1);
-
-		*_pCaptureCounter = *_pCaptureCounter + 1;
-	}
-	pictPtr = _animations[animation].pieces;
-	framePtr = layerPtr->frames;
-
-	for (i = 0; i < frame; i++, framePtr++) {
-		while (framePtr->notFinal == 1)
-			framePtr++;
-	}
-
-	if ((flags & 4) == 0) {
-		_toRedrawLeft = -12345;
-	} else {
-		_toRedrawLeft =
-		    MAX(_toRedrawLeft, _vm->_anim->_areaLeft);
-		_toRedrawTop =
-		    MAX(_toRedrawTop, _vm->_anim->_areaTop);
-		_toRedrawRight =
-		    MIN(_toRedrawRight,
-		    (int16)(_vm->_anim->_areaLeft + _vm->_anim->_areaWidth - 1));
-		_toRedrawBottom =
-		    MIN(_toRedrawBottom,
-		    (int16)(_vm->_anim->_areaTop + _vm->_anim->_areaHeight - 1));
-	}
-
-	transp = layerPtr->transp ? 3 : 0;
-
-	framePtr--;
-	do {
-		framePtr++;
-
-		pieceIndex = framePtr->pieceIndex;
-		pictIndex = framePtr->pictIndex;
-
-		destX = framePtr->destX;
-		destY = framePtr->destY;
-
-		highX = pictIndex & 0xc0;
-		highY = pictIndex & 0x30;
-		highX >>= 6;
-		highY >>= 4;
-		if (destX >= 0)
-			destX += ((uint16)highX) << 7;
-		else
-			destX -= ((uint16)highX) << 7;
-
-		if (destY >= 0)
-			destY += ((uint16)highY) << 7;
-		else
-			destY -= ((uint16)highY) << 7;
-
-		if (drawDeltaX == 1000)
-			destX += layerPtr->posX;
-		else
-			destX += drawDeltaX;
-
-		if (drawDeltaY == 1000)
-			destY += layerPtr->posY;
-		else
-			destY += drawDeltaY;
-
-		pictIndex = (pictIndex & 15) - 1;
-
-		left = FROM_LE_16(pictPtr[pictIndex][pieceIndex].left);
-		right = FROM_LE_16(pictPtr[pictIndex][pieceIndex].right);
-		top = FROM_LE_16(pictPtr[pictIndex][pieceIndex].top);
-		bottom = FROM_LE_16(pictPtr[pictIndex][pieceIndex].bottom);
-
-		if (flags & 2) {
-			if (destX < _vm->_anim->_areaLeft) {
-				left += _vm->_anim->_areaLeft - destX;
-				destX = _vm->_anim->_areaLeft;
-			}
-
-			if (left <= right
-			    && destX + right - left >=
-			    _vm->_anim->_areaLeft + _vm->_anim->_areaWidth)
-				right -=
-				    (destX + right - left) -
-				    (_vm->_anim->_areaLeft + _vm->_anim->_areaWidth) +
-				    1;
-
-			if (destY < _vm->_anim->_areaTop) {
-				top += _vm->_anim->_areaTop - destY;
-				destY = _vm->_anim->_areaTop;
-			}
-
-			if (top <= bottom
-			    && destY + bottom - top >=
-			    _vm->_anim->_areaTop + _vm->_anim->_areaHeight)
-				bottom -=
-				    (destY + bottom - top) -
-				    (_vm->_anim->_areaTop + _vm->_anim->_areaHeight) +
-				    1;
-
-		} else if (flags & 4) {
-			if (destX < _toRedrawLeft) {
-				left += _toRedrawLeft - destX;
-				destX = _toRedrawLeft;
-			}
-
-			if (left <= right
-			    && destX + right - left > _toRedrawRight)
-				right -=
-				    destX + right - left - _toRedrawRight;
-
-			if (destY < _toRedrawTop) {
-				top += _toRedrawTop - destY;
-				destY = _toRedrawTop;
-			}
-
-			if (top <= bottom
-			    && destY + bottom - top > _toRedrawBottom)
-				bottom -=
-				    destY + bottom - top - _toRedrawBottom;
-		}
-
-		if (left > right || top > bottom)
-			continue;
-
-		if (doDraw) {
-			_vm->_draw->_sourceSurface =
-			    _animPictToSprite[animation * 7 + pictIndex];
-			_vm->_draw->_destSurface = 21;
-
-			_vm->_draw->_spriteLeft = left;
-			_vm->_draw->_spriteTop = top;
-			_vm->_draw->_spriteRight = right - left + 1;
-			_vm->_draw->_spriteBottom = bottom - top + 1;
-			_vm->_draw->_destSpriteX = destX;
-			_vm->_draw->_destSpriteY = destY;
-			_vm->_draw->_transparency = transp;
-			_vm->_draw->spriteOperation(DRAW_BLITSURF);
-		}
-
-		if ((flags & 4) == 0) {
-			if (_toRedrawLeft == -12345) {
-				_toRedrawLeft = destX;
-				_animLeft = destX;
-				_toRedrawTop = destY;
-				_animTop = destY;
-				_toRedrawRight = destX + right - left;
-				_toRedrawBottom = destY + bottom - top;
-			} else {
-				_toRedrawLeft =
-				    MIN(_toRedrawLeft, destX);
-				_toRedrawTop =
-				    MIN(_toRedrawTop, destY);
-				_toRedrawRight =
-				    MAX(_toRedrawRight,
-				    (int16)(destX + right - left));
-				_toRedrawBottom =
-				    MAX(_toRedrawBottom,
-				    (int16)(destY + bottom - top));
-			}
-		}
-	} while (framePtr->notFinal == 1);
-}
-
 void Scenery::freeAnim(int16 animation) {
 	int16 i;
 	int16 spr;
@@ -729,23 +522,6 @@
 	_animPictCount[animation] = 0;
 }
 
-void Scenery::interUpdateAnim(void) {
-	int16 deltaX;
-	int16 deltaY;
-	int16 flags;
-	int16 frame;
-	int16 layer;
-	int16 animation;
-
-	_vm->_inter->evalExpr(&deltaX);
-	_vm->_inter->evalExpr(&deltaY);
-	_vm->_inter->evalExpr(&animation);
-	_vm->_inter->evalExpr(&layer);
-	_vm->_inter->evalExpr(&frame);
-	flags = _vm->_inter->load16();
-	updateAnim(layer, frame, animation, flags, deltaX, deltaY, 1);
-}
-
 void Scenery::interStoreParams(void) {
 	AnimLayer *layerPtr;
 	int16 animation;

Modified: scummvm/trunk/engines/gob/scenery.h
===================================================================
--- scummvm/trunk/engines/gob/scenery.h	2006-05-29 18:06:02 UTC (rev 22753)
+++ scummvm/trunk/engines/gob/scenery.h	2006-05-29 18:24:52 UTC (rev 22754)
@@ -119,6 +119,8 @@
 
 	int16 _animTop;
 	int16 _animLeft;
+	int16 _animBottom;
+	int16 _animRight;
 
 	int16 *_pCaptureCounter;
 
@@ -129,18 +131,37 @@
 	void renderStatic(int16 scenery, int16 layer);
 	void updateStatic(int16 orderFrom);
 	int16 loadAnim(char search);
-	void updateAnim(int16 layer, int16 frame, int16 animation, int16 flags,
-					int16 drawDeltaX, int16 drawDeltaY, char doDraw);
 	void freeAnim(int16 animation);
-	void interUpdateAnim(void);
 	void interStoreParams(void);
 
+	virtual void updateAnim(int16 layer, int16 frame, int16 animation,
+			int16 flags, int16 drawDeltaX, int16 drawDeltaY, char doDraw) = 0;
+
 	Scenery(GobEngine *vm);
+	virtual ~Scenery() {};
 
 protected:
 	GobEngine *_vm;
 };
 
+class Scenery_v1 : public Scenery {
+public:
+	virtual void updateAnim(int16 layer, int16 frame, int16 animation,
+			int16 flags, int16 drawDeltaX, int16 drawDeltaY, char doDraw);
+
+	Scenery_v1(GobEngine *vm);
+	virtual ~Scenery_v1() {};
+};
+
+class Scenery_v2 : public Scenery_v1 {
+public:
+	virtual void updateAnim(int16 layer, int16 frame, int16 animation,
+			int16 flags, int16 drawDeltaX, int16 drawDeltaY, char doDraw);
+
+	Scenery_v2(GobEngine *vm);
+	virtual ~Scenery_v2() {};
+};
+
 }				// End of namespace Gob
 
 #endif	/* __SCENERY_H */

Added: scummvm/trunk/engines/gob/scenery_v1.cpp
===================================================================
--- scummvm/trunk/engines/gob/scenery_v1.cpp	                        (rev 0)
+++ scummvm/trunk/engines/gob/scenery_v1.cpp	2006-05-29 18:24:52 UTC (rev 22754)
@@ -0,0 +1,244 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2004 Ivan Dubrov
+ * Copyright (C) 2004-2006 The ScummVM project
+ *
+ * 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/stdafx.h"
+#include "common/endian.h"
+
+#include "gob/gob.h"
+#include "gob/scenery.h"
+#include "gob/anim.h"
+#include "gob/draw.h"
+#include "gob/game.h"
+
+namespace Gob {
+
+Scenery_v1::Scenery_v1(GobEngine *vm) : Scenery(vm) {
+}
+

@@ Diff output truncated at 100000 characters. @@

This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.





More information about the Scummvm-git-logs mailing list