[Scummvm-cvs-logs] SF.net SVN: scummvm: [26792] scummvm/trunk/engines/agos

kirben at users.sourceforge.net kirben at users.sourceforge.net
Wed May 9 17:36:10 CEST 2007


Revision: 26792
          http://scummvm.svn.sourceforge.net/scummvm/?rev=26792&view=rev
Author:   kirben
Date:     2007-05-09 08:36:05 -0700 (Wed, 09 May 2007)

Log Message:
-----------
Imrproved support for Elvira 1/2 and Waxworks.

Modified Paths:
--------------
    scummvm/trunk/engines/agos/agos.cpp
    scummvm/trunk/engines/agos/agos.h
    scummvm/trunk/engines/agos/charset.cpp
    scummvm/trunk/engines/agos/draw.cpp
    scummvm/trunk/engines/agos/event.cpp
    scummvm/trunk/engines/agos/gfx.cpp
    scummvm/trunk/engines/agos/input.cpp
    scummvm/trunk/engines/agos/saveload.cpp
    scummvm/trunk/engines/agos/script_e1.cpp
    scummvm/trunk/engines/agos/script_e2.cpp
    scummvm/trunk/engines/agos/subroutine.cpp
    scummvm/trunk/engines/agos/verb.cpp
    scummvm/trunk/engines/agos/vga.cpp
    scummvm/trunk/engines/agos/vga.h
    scummvm/trunk/engines/agos/vga_e2.cpp
    scummvm/trunk/engines/agos/vga_s1.cpp
    scummvm/trunk/engines/agos/vga_ww.cpp
    scummvm/trunk/engines/agos/window.cpp

Modified: scummvm/trunk/engines/agos/agos.cpp
===================================================================
--- scummvm/trunk/engines/agos/agos.cpp	2007-05-09 13:25:14 UTC (rev 26791)
+++ scummvm/trunk/engines/agos/agos.cpp	2007-05-09 15:36:05 UTC (rev 26792)
@@ -199,6 +199,9 @@
 	_copyPartialMode = 0;
 	_fastMode = 0;
 	_useBackGround = 0;
+	
+	_oldDrawMethod = 0;
+	_backFlag = 0;
 
 	_debugMode = 0;
 	_startMainScript = false;
@@ -291,6 +294,7 @@
 
 	_leftButtonDown = 0;
 	_rightButtonDown = 0;
+	_clickOnly = 0;
 	_noRightClick = false;
 
 	_leftButton = 0;
@@ -477,6 +481,17 @@
 	_backBuf = 0;
 	_scaleBuf = 0;
 
+	_window3Flag = 0;
+	_window4Flag = 0;
+	_window6Flag = 0;
+	_window4BackScn = 0;
+	_window6BackScn = 0;
+
+	_moveXMin = 0;
+	_moveYMin = 0;
+	_moveXMax = 0;
+	_moveYMax = 0;
+
 	_vc10BasePtrOld = 0;
 	memcpy (_hebrewCharWidths,
 		"\x5\x5\x4\x6\x5\x3\x4\x5\x6\x3\x5\x5\x4\x6\x5\x3\x4\x6\x5\x6\x6\x6\x5\x5\x5\x6\x5\x6\x6\x6\x6\x6", 32);
@@ -511,6 +526,12 @@
 		return -1;
 	}
 
+	// TODO: Enable for Simon the Sorcerer 1/2 when complete
+	if (getGameType() == GType_WW || getGameType() == GType_ELVIRA2 ||
+		getGameType() == GType_ELVIRA1) {
+		_oldDrawMethod = true;
+	}
+
 	if (getGameId() == GID_DIMP) {
 		_screenWidth = 496;
 		_screenHeight = 400;
@@ -562,10 +583,26 @@
 	// allocate buffers
 	_backGroundBuf = (byte *)calloc(_screenWidth * _screenHeight, 1);
 	_frontBuf = (byte *)calloc(_screenWidth * _screenHeight, 1);
-	_backBuf = (byte *)calloc(_screenWidth * _screenHeight, 1);
-	if (getGameType() == GType_FF || getGameType() == GType_PP)
+
+	if (getGameType() == GType_FF || getGameType() == GType_PP) {
 		_scaleBuf = (byte *)calloc(_screenWidth * _screenHeight, 1);
+	}
 
+	if (!_oldDrawMethod) {
+		_backBuf = (byte *)calloc(_screenWidth * _screenHeight, 1);
+	} else {
+		if (getGameType() == GType_SIMON2) {
+			_window4BackScn = (byte *)calloc(_screenWidth * _screenHeight, 1);
+		} else if (getGameType() == GType_SIMON1) {
+			_window4BackScn = (byte *)calloc(_screenWidth * 134, 1);
+		} else if (getGameType() == GType_WW || getGameType() == GType_ELVIRA2) {
+			_window4BackScn = (byte *)calloc(224 * 127, 1);
+		} else if (getGameType() == GType_ELVIRA1) {
+			_window4BackScn = (byte *)calloc(224 * 127, 1);
+			_window6BackScn = (byte *)calloc(48 * 80, 1);
+		}
+	}
+
 	setupGame();
 
 	_debugger = new Debugger(this);
@@ -851,6 +888,9 @@
 	free(_backBuf);
 	free(_scaleBuf);
 
+	free(_window4BackScn);
+	free(_window6BackScn);
+
 	free(_variableArray);
 	free(_variableArray2);
 

Modified: scummvm/trunk/engines/agos/agos.h
===================================================================
--- scummvm/trunk/engines/agos/agos.h	2007-05-09 13:25:14 UTC (rev 26791)
+++ scummvm/trunk/engines/agos/agos.h	2007-05-09 15:36:05 UTC (rev 26792)
@@ -83,9 +83,9 @@
 
 struct VgaSprite {
 	uint16 id;
-	uint16 image;
+	int16 image;
 	uint16 palette;
-	uint16 x, y;									/* actually signed numbers */
+	int16 x, y;
 	uint16 flags;
 	uint16 priority;
 	uint16 windowNum, zoneNum;
@@ -108,6 +108,17 @@
 	VgaTimerEntry() { memset(this, 0, sizeof(*this)); }
 };
 
+struct AnimTable {
+	const byte *srcPtr;
+	int16 x;
+	int16 y;
+	uint16 width;
+	uint16 height;
+	uint16 window;
+	uint16 id;
+	AnimTable() { memset(this, 0, sizeof(*this)); }
+};
+
 enum SIMONGameType {
 	GType_ELVIRA1 = 0,
 	GType_ELVIRA2 = 1,
@@ -262,6 +273,9 @@
 	bool _fastMode;
 	bool _useBackGround;
 
+	bool _oldDrawMethod;
+	bool _backFlag;
+
 	uint16 _debugMode;
 	uint16 _language;
 	bool _copyProtection;
@@ -361,6 +375,7 @@
 	byte _leftButtonDown;
 	byte _leftButton, _leftButtonCount, _leftButtonOld;
 	byte _rightButtonDown;
+	bool _clickOnly;
 	bool _noRightClick;
 
 	Item *_dummyItem1;
@@ -450,10 +465,11 @@
 
 	HitArea _hitAreas[250];
 
+	AnimTable _screenAnim1[60];
 	VgaPointersEntry _vgaBufferPointers[450];
 	VgaSprite _vgaSprites[200];
+	VgaSleepStruct _waitEndTable[60];
 	VgaSleepStruct _waitSyncTable[60];
-	VgaSleepStruct _waitEndTable[60];
 
 	const uint16 *_pathFindArray[100];
 
@@ -472,6 +488,15 @@
 	byte _videoBuf1[32000];
 	uint16 _videoWindows[128];
 
+	uint16 _window3Flag;
+	uint16 _window4Flag;
+	uint16 _window6Flag;
+	byte *_window4BackScn;
+	byte *_window6BackScn;
+
+	uint16 _moveXMin, _moveYMin;
+	uint16 _moveXMax, _moveYMax;
+
 	VgaTimerEntry _vgaTimerList[205];
 
 	WindowBlock *_windowList;
@@ -1025,7 +1050,11 @@
 	void drawImage_init(int16 image, uint16 palette, uint16 x, uint16 y, uint16 flags);
 
 	virtual void drawImage(VC10_state *state);
+	void drawBackGroundImage(VC10_state *state);
+	void drawVertImage(VC10_state *state);
 
+	void setMoveRect(uint16 x, uint16 y, uint16 width, uint16 height);
+
 	void horizontalScroll(VC10_state *state);
 	void verticalScroll(VC10_state *state);
 
@@ -1041,7 +1070,9 @@
 	void checkScrollY(int16 y, int16 ypos);
 	void centreScroll();
 
-	void clearWindow(uint windowNum, uint color);
+	void clearVideoWindow(uint windowNum, uint color);
+	void clearVideoBackGround(uint windowNum, uint color);
+
 	void setPaletteSlot(uint srcOffs, uint dstOffs);
 	void checkWaitEndTable();
 
@@ -1100,6 +1131,11 @@
 	void animateSpritesDebug();
 	void animateSpritesByY();
 
+	void dirtyClips();
+	void dirtyBackGround();
+	void restoreBackGround();
+	void saveBackGround(VgaSprite *vsp);
+
 	void clearSurfaces(uint num_lines);
 	void updateScreen();
 
@@ -1416,6 +1452,8 @@
 	const OpcodeEntrySimon1 *_opcodesSimon1;
 
 	virtual void drawImage(VC10_state *state);
+	void drawMaskedImage(VC10_state *state);
+	void draw32ColorImage(VC10_state *state);
 
 	virtual void drawIcon(WindowBlock *window, uint icon, uint x, uint y);
 

Modified: scummvm/trunk/engines/agos/charset.cpp
===================================================================
--- scummvm/trunk/engines/agos/charset.cpp	2007-05-09 13:25:14 UTC (rev 26791)
+++ scummvm/trunk/engines/agos/charset.cpp	2007-05-09 15:36:05 UTC (rev 26792)
@@ -703,12 +703,16 @@
 }
 
 void AGOSEngine::windowNewLine(WindowBlock *window) {
-	if (window->textRow != window->height)
-		window->textRow++;
-
 	window->textColumn = 0;
 	window->textColumnOffset = 0;
 	window->textLength = 0;
+
+	if (window->textRow == window->height) {
+		// TODO
+		debug(0, "Window Scroll");
+	} else {
+		window->textRow++;
+	}
 }
 
 #ifdef PALMOS_68K

Modified: scummvm/trunk/engines/agos/draw.cpp
===================================================================
--- scummvm/trunk/engines/agos/draw.cpp	2007-05-09 13:25:14 UTC (rev 26791)
+++ scummvm/trunk/engines/agos/draw.cpp	2007-05-09 15:36:05 UTC (rev 26792)
@@ -69,8 +69,15 @@
 		return;
 	}
 
+	if (_oldDrawMethod) {
+		if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
+			dirtyClips();
+		}
+
+		restoreBackGround();
+	}
+
 	vsp = _vgaSprites;
-
 	while (vsp->id != 0) {
 		vsp->windowNum &= 0x7FFF;
 
@@ -82,17 +89,119 @@
 		_vgaCurSpriteId = vsp->id;
 		_vgaCurSpritePriority = vsp->priority;
 
+		if (_oldDrawMethod) {
+			saveBackGround(vsp);
+		}
+
 		drawImage_init(vsp->image, vsp->palette, vsp->x, vsp->y, vsp->flags);
-
 		vsp++;
 	}
 
 	if (_drawImagesDebug)
 		memset(_backBuf, 0, _screenWidth * _screenHeight);
 
+	if (_window6Flag == 1)
+		_window6Flag++;
+
+	if (_window4Flag == 1)
+		_window4Flag++;
+
 	_updateScreen = true;
 }
 
+void AGOSEngine::dirtyClips() {
+	// TODO
+}
+
+void AGOSEngine::restoreBackGround() {
+	AnimTable *animTable;
+	uint images = 0;
+
+	animTable = _screenAnim1;
+	while (animTable->srcPtr) {
+		animTable++;
+		images++;
+	}
+
+	while (images--) {
+		animTable--;
+
+		if ((getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) &&
+			!(animTable->window & 0x8000)) {
+			//continue;
+		}
+
+		animTable->window &= 0x7FFF;
+		_windowNum = animTable->window;	
+
+		VC10_state state;
+		state.srcPtr  = animTable->srcPtr;
+		state.height = state.draw_height = animTable->height;
+		state.width = state.draw_width = animTable->width;
+		state.y = animTable->y;
+		state.x = animTable->x;
+		state.palette = 0;
+		state.paletteMod = 0;
+		state.flags = kDFNonTrans;
+
+		_backFlag = 1;
+		drawImage(&state);
+
+		//if (getGameType() != GType_SIMON1 && getGameType() != GType_SIMON2) {
+			animTable->srcPtr = 0;
+		//}
+	}
+	_backFlag = 0;
+
+	if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) {
+		AnimTable *animTableTmp;
+
+		animTable = animTableTmp = _screenAnim1;
+		while (animTable->srcPtr != 0) {
+			if (!(animTable->window & 8000)) {
+				memcpy(animTableTmp, animTable, sizeof(AnimTable));
+				animTableTmp++;
+			}
+			animTable++;
+		}
+		animTableTmp->id = 0;
+	}
+}
+
+void AGOSEngine::saveBackGround(VgaSprite *vsp) {
+	if ((vsp->flags & 4) || !vsp->image)
+		return;
+
+	AnimTable *animTable = _screenAnim1;
+
+	while (animTable->srcPtr)
+		animTable++;
+
+	const byte *ptr = _curVgaFile2 + vsp->image * 8;
+	int16 x = vsp->x - _scrollX;
+	int16 y = vsp->y - _scrollY;
+
+	if (_window3Flag == 1) {
+		animTable->srcPtr = (const byte *)_window4BackScn;
+	} else {
+		uint xoffs = (_videoWindows[vsp->windowNum * 4 + 0] * 2 + x) * 8;
+		uint yoffs = (_videoWindows[vsp->windowNum * 4 + 1] + y);
+		animTable->srcPtr = getBackGround() + xoffs + yoffs * _screenWidth;
+	}
+
+	animTable->x = x;
+	animTable->y = y;
+
+	animTable->width = READ_BE_UINT16(ptr + 6) / 16;
+	if (vsp->flags & 40) {
+		animTable->width++;
+	}
+
+	animTable->height = ptr[5];
+	animTable->window = vsp->windowNum;
+	animTable->id = vsp->id;
+}
+
 void AGOSEngine::animateSpritesDebug() {
 	VgaSprite *vsp;
 	VgaPointersEntry *vpe;
@@ -289,10 +398,16 @@
 }
 
 void AGOSEngine::scrollScreen() {
-	byte *dst = getFrontBuf();
+	byte *dst;
 	const byte *src;
 	uint x, y;
 
+	if (!_oldDrawMethod) {
+		dst = getFrontBuf();
+	} else {
+		dst = getBackGround();
+	}
+
 	if (_scrollXMax == 0) {
 		uint screenSize = 8 * _screenWidth;
 		if (_scrollFlag < 0) {
@@ -340,8 +455,16 @@
 		_scrollX += _scrollFlag;
 		vcWriteVar(251, _scrollX);
 
-		memcpy(_backBuf, _frontBuf, _screenWidth * _screenHeight);
-		memcpy(_backGroundBuf, _backBuf, _scrollHeight * _screenWidth);
+		if (!_oldDrawMethod) {
+			memcpy(_backBuf, _frontBuf, _screenWidth * _screenHeight);
+			memcpy(_backGroundBuf, _backBuf, _scrollHeight * _screenWidth);
+		} else {
+			memcpy(_window4BackScn, _backGroundBuf, _scrollHeight * _screenWidth);
+		}
+
+		setMoveRect(0, 0, 320, _scrollHeight);
+
+		_window4Flag = 1;
 	}
 
 	_scrollFlag = 0;
@@ -390,6 +513,20 @@
 	memcpy(_backGroundBuf, _backBuf, lines * _screenWidth);
 }
 
+void AGOSEngine::setMoveRect(uint16 x, uint16 y, uint16 width, uint16 height) {
+	if (x < _moveXMin)
+		_moveXMin = x;
+
+	if (y < _moveYMin)
+		_moveYMin = y;
+
+	if (width > _moveXMax)
+		_moveXMax = width;
+
+	if (height > _moveYMax)
+		_moveYMax = height;
+}
+
 void AGOSEngine::updateScreen() {
 	if (_fastFadeInFlag == 0 && _paletteFlag == 1) {
 		_paletteFlag = 0;
@@ -399,12 +536,64 @@
 		}
 	}
 
-	_system->copyRectToScreen(getBackBuf(), _screenWidth, 0, 0, _screenWidth, _screenHeight);
-	_system->updateScreen();
+	if (_oldDrawMethod) {
+		if (_window4Flag == 2) {
+			_window4Flag = 0;
 
-	if (getGameId() != GID_DIMP)
-		memcpy(getBackBuf(), getFrontBuf(), _screenWidth * _screenHeight);
+			uint16 srcWidth, width, height;
+			byte *dst = getFrontBuf();
 
+			const byte *src = _window4BackScn;
+			if (_window3Flag == 1) {
+				src = getBackGround();
+			}
+
+			dst += (_moveYMin + _videoWindows[17]) * _screenWidth;
+			dst += (_videoWindows[16] * 16) + _moveXMin;
+
+			src += (_videoWindows[18] * 16 * _moveYMin);
+			src += _moveXMin;
+
+			srcWidth = _videoWindows[18] * 16;
+		
+			width = _moveXMax - _moveXMin;
+			height = _moveYMax - _moveYMin;
+
+			for (; height > 0; height--) {
+				memcpy(dst, src, width);
+				dst += _screenWidth;
+				src += srcWidth;
+			}
+
+			_moveXMin = 0xFFFF;
+			_moveYMin = 0xFFFF;
+			_moveXMax = 0;
+			_moveYMax = 0;
+		}
+		
+		 if (_window6Flag == 2) {
+			_window6Flag = 0;
+
+			byte *src = _window6BackScn;
+			byte *dst = getFrontBuf() + 16320;
+			for (int i = 0; i < 80; i++) {
+				memcpy(dst, src, 48);
+				dst += _screenWidth;
+				src += 48;
+			}
+		} 
+	
+		_system->copyRectToScreen(getFrontBuf(), _screenWidth, 0, 0, _screenWidth, _screenHeight);
+		_system->updateScreen();
+	} else {
+		_system->copyRectToScreen(getBackBuf(), _screenWidth, 0, 0, _screenWidth, _screenHeight);
+		_system->updateScreen();
+
+		if (getGameId() != GID_DIMP)
+			memcpy(getBackBuf(), getFrontBuf(), _screenWidth * _screenHeight);
+
+	}
+
 	if (getGameType() == GType_FF && _scrollFlag) {
 		scrollScreen();
 	}

Modified: scummvm/trunk/engines/agos/event.cpp
===================================================================
--- scummvm/trunk/engines/agos/event.cpp	2007-05-09 13:25:14 UTC (rev 26791)
+++ scummvm/trunk/engines/agos/event.cpp	2007-05-09 15:36:05 UTC (rev 26792)
@@ -123,6 +123,7 @@
 		next = cur->next;
 		delTimeEvent(cur);
 	}
+	_clickOnly = 0;
 }
 
 bool AGOSEngine::kickoffTimeEvents() {
@@ -164,32 +165,30 @@
 }
 
 void AGOSEngine::haltAnimation() {
-	VgaTimerEntry *vte = _vgaTimerList;
+	if (_lockWord & 0x10)
+		return;
 
 	_lockWord |= 0x10;
 
-	while (vte->delay) {
-		vte->delay += 10;
+	if (_updateScreen != false) {
+		updateScreen();
+		_updateScreen = false;
 	}
 }
 
 void AGOSEngine::restartAnimation() {
+	if (!(_lockWord & 0x10))
+		return;
+
+	updateScreen();
 	_lockWord &= ~0x10;
+
+	// Check picture queue
 }
 
 void AGOSEngine::addVgaEvent(uint16 num, const byte *code_ptr, uint16 cur_sprite, uint16 curZoneNum) {
 	VgaTimerEntry *vte;
 
-	// When Simon talks to the Golum about stew in French version of
-	// Simon the Sorcerer 1 the code_ptr is at wrong location for
-	// sprite 200. This  was a bug in the original game, which
-	// caused several glitches in this scene.
-	// We work around the problem by correcting the code_ptr for sprite
-	// 200 in this scene, if it is wrong.
-	if (getGameType() == GType_SIMON1 && _language == Common::FR_FRA &&
-		(code_ptr - _vgaBufferPointers[curZoneNum].vgaFile1 == 4) && (cur_sprite == 200) && (curZoneNum == 2))
-		code_ptr += 0x66;
-
 	_lockWord |= 1;
 
 	for (vte = _vgaTimerList; vte->delay; vte++) {

Modified: scummvm/trunk/engines/agos/gfx.cpp
===================================================================
--- scummvm/trunk/engines/agos/gfx.cpp	2007-05-09 13:25:14 UTC (rev 26791)
+++ scummvm/trunk/engines/agos/gfx.cpp	2007-05-09 15:36:05 UTC (rev 26792)
@@ -224,6 +224,70 @@
 	return 1;
 }
 
+void AGOSEngine_Feeble::scaleClip(int16 h, int16 w, int16 y, int16 x, int16 scrollY) {
+	Common::Rect srcRect, dstRect;
+	float factor, xscale;
+
+	srcRect.left = 0;
+	srcRect.top = 0;
+	srcRect.right = w;
+	srcRect.bottom = h;
+
+	if (scrollY > _baseY)
+		factor = 1 + ((scrollY - _baseY) * _scale);
+	else
+		factor = 1 - ((_baseY - scrollY) * _scale);
+
+	xscale = ((w * factor) / 2);
+
+	dstRect.left   = (int16)(x - xscale);
+	if (dstRect.left > _screenWidth - 1)
+		return;
+	dstRect.top    = (int16)(y - (h * factor));
+	if (dstRect.top > _screenHeight - 1)
+		return;
+
+	dstRect.right  = (int16)(x + xscale);
+	dstRect.bottom = y;
+
+	_feebleRect = dstRect;
+
+	_variableArray[20] = _feebleRect.top;
+	_variableArray[21] = _feebleRect.left;
+	_variableArray[22] = _feebleRect.bottom;
+	_variableArray[23] = _feebleRect.right;
+
+	debug(5, "Left %d Right %d Top %d Bottom %d", dstRect.left, dstRect.right, dstRect.top, dstRect.bottom);
+
+	// Unlike normal rectangles in ScummVM, it seems that in the case of
+	// the destination rectangle the bottom and right coordinates are
+	// considered to be inside the rectangle. For the source rectangle,
+	// I believe that they are not.
+
+	int scaledW = dstRect.width() + 1;
+	int scaledH = dstRect.height() + 1;
+
+	byte *src = getScaleBuf();
+	byte *dst = getBackBuf();
+
+	dst += _dxSurfacePitch * dstRect.top + dstRect.left;
+
+	for (int dstY = 0; dstY < scaledH; dstY++) {
+		if (dstRect.top + dstY >= 0 && dstRect.top + dstY < _screenHeight) {
+			int srcY = (dstY * h) / scaledH;
+			byte *srcPtr = src + _dxSurfacePitch * srcY;
+			byte *dstPtr = dst + _dxSurfacePitch * dstY;
+			for (int dstX = 0; dstX < scaledW; dstX++) {
+				if (dstRect.left + dstX >= 0 && dstRect.left + dstX < _screenWidth) {
+					int srcX = (dstX * w) / scaledW;
+					if (srcPtr[srcX])
+						dstPtr[dstX] = srcPtr[srcX];
+				}
+			}
+		}
+	}
+}
+
 void AGOSEngine_Feeble::drawImage(VC10_state *state) {
 	if (state->flags & kDFCompressed) {
 		if (state->flags & kDFScaled) {
@@ -387,304 +451,285 @@
 	} 
 }
 
-void AGOSEngine_Simon1::drawImage(VC10_state *state) {
-	const uint16 *vlut = &_videoWindows[_windowNum * 4];
+void AGOSEngine_Simon1::drawMaskedImage(VC10_state *state) {
+	if (getFeatures() & GF_32COLOR) {
+		const byte *mask = state->srcPtr + (state->width * state->y_skip * 16) + (state->x_skip * 8);
+		byte *src = state->surf2_addr;
+		byte *dst = state->surf_addr;
 
-	if (drawImage_clip(state) == 0)
-		return;
+		state->draw_width *= 2;
 
-	if (getFeatures() & GF_32COLOR)
-		state->palette = 0xC0;
+		uint h = state->draw_height;
+		do {
+			for (uint i = 0; i != state->draw_width; i++) {
+				if (getGameType() == GType_SIMON1 && getBitFlag(88)) {
+					/* transparency */
+					if (mask[i] && (dst[i] & 16))
+						dst[i] = src[i];
+				} else {
+					/* no transparency */
+					if (mask[i])
+						dst[i] = src[i];
+				}
+			}
+			dst += state->surf_pitch;
+			src += state->surf2_pitch;
+			mask += state->width * 16;
+		} while (--h);
+	} else if (state->flags & kDFCompressed) {
+		byte *mask, *src, *dst;
+		byte h;
+		uint w;
 
-	uint xoffs, yoffs;
-	if (getGameType() == GType_SIMON1 && (_subroutine == 2923 || _subroutine == 2926)) {
-		// Allow one section of Simon the Sorcerer 1 introduction to be displayed
-		// in lower half of screen
-		xoffs = state->x * 8;
-		yoffs = state->y;
-	} else {
-		xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
-		yoffs = (vlut[1] - _videoWindows[17] + state->y);
-	}
+		state->x_skip *= 4;
+		state->dl = state->width;
+		state->dh = state->height;
 
-	state->surf2_addr += xoffs + yoffs * state->surf_pitch;
-	state->surf_addr += xoffs + yoffs * state->surf2_pitch;
+		vc10_skip_cols(state);
 
-	if (state->flags & kDFMasked) {
-		if (getFeatures() & GF_32COLOR) {
-			const byte *mask = state->srcPtr + (state->width * state->y_skip * 16) + (state->x_skip * 8);
-			byte *src = state->surf2_addr;
-			byte *dst = state->surf_addr;
+		w = 0;
+		do {
+			mask = vc10_depackColumn(state);	/* esi */
+			src = state->surf2_addr + w * 2;	/* ebx */
+			dst = state->surf_addr + w * 2;		/* edi */
 
-			state->draw_width *= 2;
-
-			uint h = state->draw_height;
+			h = state->draw_height;
 			do {
-				for (uint i = 0; i != state->draw_width; i++) {
-					if (getGameType() == GType_SIMON1 && getBitFlag(88)) {
-						/* transparency */
-						if (mask[i] && (dst[i] & 16))
-							dst[i] = src[i];
-					} else {
-						/* no transparency */
-						if (mask[i])
-							dst[i] = src[i];
-					}
+				if (getGameType() == GType_SIMON1 && getBitFlag(88)) {
+					/* transparency */
+					if ((mask[0] & 0xF0) && (dst[0] & 0x0F0) == 0x20)
+						dst[0] = src[0];
+					if ((mask[0] & 0x0F) && (dst[1] & 0x0F0) == 0x20)
+						dst[1] = src[1];
+				} else {	
+					/* no transparency */
+					if (mask[0] & 0xF0)
+						dst[0] = src[0];
+					if (mask[0] & 0x0F)
+						dst[1] = src[1];
 				}
+				mask++;
 				dst += state->surf_pitch;
 				src += state->surf2_pitch;
-				mask += state->width * 16;
 			} while (--h);
-		} else if (state->flags & kDFCompressed) {
-			byte *mask, *src, *dst;
-			byte h;
-			uint w;
+		} while (++w != state->draw_width);
+	} else {
+		const byte *src, *mask;
+		byte *dst;
+		uint count;
 
-			state->x_skip *= 4;
-			state->dl = state->width;
-			state->dh = state->height;
+		mask = state->srcPtr + (state->width * state->y_skip) * 8;
+		src = state->surf2_addr;
+		dst = state->surf_addr;
 
-			vc10_skip_cols(state);
+		state->x_skip *= 4;
 
-			w = 0;
-			do {
-				mask = vc10_depackColumn(state);	/* esi */
-				src = state->surf2_addr + w * 2;	/* ebx */
-				dst = state->surf_addr + w * 2;		/* edi */
+		do {
+			for (count = 0; count != state->draw_width; count++) {
+				if (getGameType() == GType_SIMON1 && getBitFlag(88)) {
+					/* transparency */
+					if (mask[count + state->x_skip] & 0xF0)
+						if ((dst[count * 2] & 0xF0) == 0x20)
+							dst[count * 2] = src[count * 2];
+					if (mask[count + state->x_skip] & 0x0F)
+						if ((dst[count * 2 + 1] & 0x0F) == 0x20)
+							dst[count * 2 + 1] = src[count * 2 + 1];
+				} else {
+					/* no transparency */
+					if (mask[count + state->x_skip] & 0xF0)
+						dst[count * 2] = src[count * 2];
+					if (mask[count + state->x_skip] & 0x0F)
+						dst[count * 2 + 1] = src[count * 2 + 1];
+				}
+			}
+			src += _screenWidth;
+			dst += _screenWidth;
+			mask += state->width * 8;
+		} while (--state->draw_height);
+	}
+}
 
-				h = state->draw_height;
-				do {
-					if (getGameType() == GType_SIMON1 && getBitFlag(88)) {
-						/* transparency */
-						if ((mask[0] & 0xF0) && (dst[0] & 0x0F0) == 0x20)
-							dst[0] = src[0];
-						if ((mask[0] & 0x0F) && (dst[1] & 0x0F0) == 0x20)
-							dst[1] = src[1];
-					} else {
-						/* no transparency */
-						if (mask[0] & 0xF0)
-							dst[0] = src[0];
-						if (mask[0] & 0x0F)
-							dst[1] = src[1];
-					}
-					mask++;
-					dst += state->surf_pitch;
-					src += state->surf2_pitch;
-				} while (--h);
-			} while (++w != state->draw_width);
-		} else {
-			const byte *src, *mask;
-			byte *dst;
-			uint count;
+void AGOSEngine_Simon1::draw32ColorImage(VC10_state *state) {
+	const byte *src;
+	byte *dst;
+	uint h, i;
 
-			mask = state->srcPtr + (state->width * state->y_skip) * 8;
-			src = state->surf2_addr;
-			dst = state->surf_addr;
+	if (state->flags & kDFCompressed) {
+		byte *dstPtr = state->surf_addr;
+		src = state->srcPtr;
+		/* AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD EEEEEEEE
+		 * aaaaabbb bbcccccd ddddeeee efffffgg ggghhhhh
+		 */
 
-			state->x_skip *= 4;
+		do {
+			uint count = state->draw_width / 4;
 
+			dst = dstPtr;
 			do {
-				for (count = 0; count != state->draw_width; count++) {
-					if (getGameType() == GType_SIMON1 && getBitFlag(88)) {
-						/* transparency */
-						if (mask[count + state->x_skip] & 0xF0)
-							if ((dst[count * 2] & 0xF0) == 0x20)
-								dst[count * 2] = src[count * 2];
-						if (mask[count + state->x_skip] & 0x0F)
-							if ((dst[count * 2 + 1] & 0x0F) == 0x20)
-								dst[count * 2 + 1] = src[count * 2 + 1];
-					} else {
-						/* no transparency */
-						if (mask[count + state->x_skip] & 0xF0)
-							dst[count * 2] = src[count * 2];
-						if (mask[count + state->x_skip] & 0x0F)
-							dst[count * 2 + 1] = src[count * 2 + 1];
-					}
-				}
-				src += _screenWidth;
-				dst += _screenWidth;
-				mask += state->width * 8;
-			} while (--state->draw_height);
-		}
-	} else if (((_lockWord & 0x20) && state->palette == 0) || state->palette == 0xC0) {
-		const byte *src;
-		byte *dst;
-		uint h, i;
+				uint32 bits = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | (src[3]);
+				byte color;
 
-		if (state->flags & kDFCompressed) {
-			byte *dstPtr = state->surf_addr;
-			src = state->srcPtr;
-			/* AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD EEEEEEEE
-			 * aaaaabbb bbcccccd ddddeeee efffffgg ggghhhhh
-			 */
+				color = (byte)((bits >> (32 - 5)) & 31);
+				if ((state->flags & kDFNonTrans) || color)
+					dst[0] = color;
+				color = (byte)((bits >> (32 - 10)) & 31);
+				if ((state->flags & kDFNonTrans) || color)
+					dst[1] = color;
+				color = (byte)((bits >> (32 - 15)) & 31);
+				if ((state->flags & kDFNonTrans) || color)
+					dst[2] = color;
+				color = (byte)((bits >> (32 - 20)) & 31);
+				if ((state->flags & kDFNonTrans) || color)
+					dst[3] = color;
+				color = (byte)((bits >> (32 - 25)) & 31);
+				if ((state->flags & kDFNonTrans) || color)
+					dst[4] = color;
+				color = (byte)((bits >> (32 - 30)) & 31);
+				if ((state->flags & kDFNonTrans) || color)
+					dst[5] = color;
 
-			do {
-				uint count = state->draw_width / 4;
+				bits = (bits << 8) | src[4];
 
-				dst = dstPtr;
-				do {
-					uint32 bits = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | (src[3]);
-					byte color;
+				color = (byte)((bits >> (40 - 35)) & 31);
+				if ((state->flags & kDFNonTrans) || color)
+					dst[6] = color;
+				color = (byte)((bits) & 31);
+				if ((state->flags & kDFNonTrans) || color)
+					dst[7] = color;
 
-					color = (byte)((bits >> (32 - 5)) & 31);
-					if ((state->flags & kDFNonTrans) || color)
-						dst[0] = color;
-					color = (byte)((bits >> (32 - 10)) & 31);
-					if ((state->flags & kDFNonTrans) || color)
-						dst[1] = color;
-					color = (byte)((bits >> (32 - 15)) & 31);
-					if ((state->flags & kDFNonTrans) || color)
-						dst[2] = color;
-					color = (byte)((bits >> (32 - 20)) & 31);
-					if ((state->flags & kDFNonTrans) || color)
-						dst[3] = color;
-					color = (byte)((bits >> (32 - 25)) & 31);
-					if ((state->flags & kDFNonTrans) || color)
-						dst[4] = color;
-					color = (byte)((bits >> (32 - 30)) & 31);
-					if ((state->flags & kDFNonTrans) || color)
-						dst[5] = color;
+				dst += 8;
+				src += 5;
+			} while (--count);
+			dstPtr += _screenWidth;
+		} while (--state->draw_height);
+	} else {
+		src = state->srcPtr + (state->width * state->y_skip * 16) + (state->x_skip * 8);
+		dst = state->surf_addr;
 
-					bits = (bits << 8) | src[4];
+		state->draw_width *= 2;
 
-					color = (byte)((bits >> (40 - 35)) & 31);
-					if ((state->flags & kDFNonTrans) || color)
-						dst[6] = color;
-					color = (byte)((bits) & 31);
-					if ((state->flags & kDFNonTrans) || color)
-						dst[7] = color;
+		h = state->draw_height;
+		do {
+			for (i = 0; i != state->draw_width; i++)
+				if ((state->flags & kDFNonTrans) || src[i])
+					dst[i] = src[i];
+			dst += _screenWidth;
+			src += state->width * 16;
+		} while (--h);
+	}
+}
 
-					dst += 8;
-					src += 5;
-				} while (--count);
-				dstPtr += _screenWidth;
-			} while (--state->draw_height);
-		} else {
-			src = state->srcPtr + (state->width * state->y_skip * 16) + (state->x_skip * 8);
-			dst = state->surf_addr;
+void AGOSEngine_Simon1::drawImage(VC10_state *state) {
+	const uint16 *vlut = &_videoWindows[_windowNum * 4];
 
-			state->draw_width *= 2;
+	if (drawImage_clip(state) == 0)
+		return;
 
-			h = state->draw_height;
-			do {
-				for (i = 0; i != state->draw_width; i++)
-					if ((state->flags & kDFNonTrans) || src[i])
-						dst[i] = src[i];
-				dst += _screenWidth;
-				src += state->width * 16;
-			} while (--h);
+	if (getFeatures() & GF_32COLOR)
+		state->palette = 0xC0;
+
+	uint16 xoffs, yoffs;
+	if (!_oldDrawMethod) {
+		if (getGameType() == GType_SIMON1 && (_subroutine == 2923 || _subroutine == 2926)) {
+			// Allow one section of Simon the Sorcerer 1 introduction to be displayed
+			// in lower half of screen
+			xoffs = state->x * 8;
+			yoffs = state->y;
+		} else {
+			xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
+			yoffs = (vlut[1] - _videoWindows[17] + state->y);
 		}
-	} else {
-		if (getGameType() == GType_SIMON2 && state->flags & kDFUseFrontBuf && getBitFlag(171)) {
-			state->surf_addr = state->surf2_addr;
-			state->surf_pitch = state->surf2_pitch;
-		}
+	} else if (getGameType() == GType_SIMON2) {
+		state->surf2_addr = getBackGround();
+		state->surf2_pitch = _screenWidth;
 
-		if (state->flags & kDFCompressed) {
-			uint w, h;
-			byte *src, *dst, *dstPtr;
+		state->surf_addr = _window4BackScn;
+		state->surf_pitch = _screenWidth;
 
-			state->x_skip *= 4;				/* reached */
+		xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
+		yoffs = (vlut[1] - _videoWindows[17] + state->y);
 
-			state->dl = state->width;
-			state->dh = state->height;
+		uint xmax = (xoffs + state->draw_width * 2);
+		uint ymax = (yoffs + state->draw_height);
+		setMoveRect(xoffs, yoffs, xmax, ymax);
 
-			vc10_skip_cols(state);
+		_window4Flag = 1;
+	} else if (getGameType() == GType_SIMON1) {
+		if (_windowNum == 3 || _windowNum == 4 || _windowNum >= 10) {
+			if (_windowNum == 3) {
+				state->surf2_addr = getBackGround();
+				state->surf2_pitch = _screenWidth;
 
-			dstPtr = state->surf_addr;
-			if (!(state->flags & kDFNonTrans) && (state->flags & 0x40)) { /* reached */
-				dstPtr += vcReadVar(252);
+				state->surf_addr = getBackGround();
+				state->surf_pitch = _screenWidth;
+			} else {
+				state->surf2_addr = getBackGround();
+				state->surf2_pitch = _screenWidth;
+
+				state->surf_addr = _window4BackScn;
+				state->surf_pitch = _screenWidth;
 			}
-			w = 0;
-			do {
-				byte color;
 
-				src = vc10_depackColumn(state);
-				dst = dstPtr;
+			xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
+			yoffs = (vlut[1] - _videoWindows[17] + state->y);
 
-				h = 0;
-				do {
-					color = (*src / 16);
-					if ((state->flags & kDFNonTrans) || color != 0)
-						dst[0] = color | state->palette;
-					color = (*src & 15);
-					if ((state->flags & kDFNonTrans) || color != 0)
-						dst[1] = color | state->palette;
-					dst += _screenWidth;
-					src++;
-				} while (++h != state->draw_height);
-				dstPtr += 2;
-			} while (++w != state->draw_width);
+			uint xmax = (xoffs + state->draw_width * 2);
+			uint ymax = (yoffs + state->draw_height);
+			setMoveRect(xoffs, yoffs, xmax, ymax);
+
+			_window4Flag = 1;
 		} else {
-			const byte *src;
-			byte *dst;
-			uint count;
+			state->surf2_addr = getBackGround();
+			state->surf2_pitch = _screenWidth;
 
-			src = state->srcPtr + (state->width * state->y_skip) * 8;
-			dst = state->surf_addr;
-			state->x_skip *= 4;
+			state->surf_addr = getFrontBuf();
+			state->surf_pitch = _screenWidth;
 
-			do {
-				for (count = 0; count != state->draw_width; count++) {
-					byte color;
-					color = (src[count + state->x_skip] / 16);
-					if ((state->flags & kDFNonTrans) || color)
-						dst[count * 2] = color | state->palette;
-					color = (src[count + state->x_skip] & 15);
-					if ((state->flags & kDFNonTrans) || color)
-						dst[count * 2 + 1] = color | state->palette;
-				}
-				dst += _screenWidth;
-				src += state->width * 8;
-			} while (--state->draw_height);
+			xoffs = (vlut[0] * 2 + state->x) * 8;
+			yoffs = vlut[1] + state->y;
 		}
 	}
+
+	state->surf_addr += xoffs + yoffs * state->surf_pitch;
+	state->surf2_addr += xoffs + yoffs * state->surf2_pitch;
+
+	if (_backFlag == 1) {
+		drawBackGroundImage(state);
+	} else if (state->flags & kDFMasked) {
+		drawMaskedImage(state);
+	} else if (((_lockWord & 0x20) && state->palette == 0) || state->palette == 0xC0) {
+		draw32ColorImage(state);
+	} else {
+		drawVertImage(state);
+	}
 }
 
-void AGOSEngine::drawImage(VC10_state *state) {
-	const uint16 *vlut = &_videoWindows[_windowNum * 4];
+void AGOSEngine::drawBackGroundImage(VC10_state *state) {
+	const byte *src;
+	byte *dst;
+	uint h, i;
 
-	if (drawImage_clip(state) == 0)
-		return;
+	src = state->srcPtr + (_screenWidth * state->y_skip) + (state->x_skip * 8);
+	dst = state->surf_addr;
 
-	uint xoffs = 0, yoffs = 0;
-	if (getGameType() == GType_ELVIRA1) {
-		//if (_windowNum != 2 && _windowNum != 3 && _windowNum != 6) {
-		//	xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
-		//	yoffs = (vlut[1] - _videoWindows[17] + state->y);
-		//} else {
-			xoffs = (vlut[0] * 2 + state->x) * 8;
-			yoffs = vlut[1] + state->y;
-		//}
-	} else if (getGameType() == GType_ELVIRA2) {
-		//if (_windowNum == 4 || _windowNum >= 10) {
-		//	xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
-		//	yoffs = (vlut[1] - _videoWindows[17] + state->y);
-		//} else {
-			xoffs = (vlut[0] * 2 + state->x) * 8;
-			yoffs = vlut[1] + state->y;
-		//}
-	} else if (getGameType() == GType_WW) {
-		//if (_windowNum == 4 || (_windowNum >= 10 && _windowNum < 28)) {
-		//	xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
-		//	yoffs = (vlut[1] - _videoWindows[17] + state->y);
-		//} else {
-			xoffs = (vlut[0] * 2 + state->x) * 8;
-			yoffs = vlut[1] + state->y;
-		//}
-	}
+	state->draw_width *= 2;
 
-	state->surf_addr += xoffs + yoffs * state->surf_pitch;
-	state->surf2_addr += xoffs + yoffs * state->surf2_pitch;
+	h = state->draw_height;
+	do {
+		for (i = 0; i != state->draw_width; i++)
+			dst[i] = src[i] + state->paletteMod;
+		dst += state->surf_pitch;
+		src += _screenWidth;
+	} while (--h);
+}
 
-	if (state->flags & kDFUseFrontBuf) {
+void AGOSEngine::drawVertImage(VC10_state *state) {
+	if (getGameType() == GType_SIMON2 && (state->flags & kDFUseFrontBuf) && getBitFlag(171) &&
+		!_oldDrawMethod) {
 		state->surf_addr = state->surf2_addr;
 		state->surf_pitch = state->surf2_pitch;
 	}
 
-	if (getGameType() == GType_ELVIRA2 || getGameType() == GType_WW)
-		state->palette = state->surf_addr[0] & 0xF0;
-
 	if (state->flags & kDFCompressed) {
 		uint w, h;
 		byte *src, *dst, *dstPtr;
@@ -697,6 +742,9 @@
 		vc10_skip_cols(state);
 
 		dstPtr = state->surf_addr;
+		if (!(state->flags & kDFNonTrans) && (state->flags & 0x40)) { /* reached */
+			dstPtr += vcReadVar(252);
+		}
 		w = 0;
 		do {
 			byte color;
@@ -712,7 +760,7 @@
 				color = (*src & 15);
 				if ((state->flags & kDFNonTrans) || color != 0)
 					dst[1] = color | state->palette;
-				dst += _screenWidth;
+				dst += state->surf_pitch;
 				src++;
 			} while (++h != state->draw_height);
 			dstPtr += 2;
@@ -726,27 +774,113 @@
 		dst = state->surf_addr;
 		state->x_skip *= 4;
 
-		uint8 extraPal = 0;
-		if (getGameType() == GType_ELVIRA1 && (state->flags & kDFNonTrans) && yoffs > 133)
-			extraPal = 16;
-
 		do {
 			for (count = 0; count != state->draw_width; count++) {
 				byte color;
-				color = (src[count + state->x_skip] / 16) + extraPal;
+				color = (src[count + state->x_skip] / 16) + state->paletteMod;
 				if ((state->flags & kDFNonTrans) || color)
 					dst[count * 2] = color | state->palette;
-				color = (src[count + state->x_skip] & 15) + extraPal;
+				color = (src[count + state->x_skip] & 15) + state->paletteMod;
 				if ((state->flags & kDFNonTrans) || color)
 					dst[count * 2 + 1] = color | state->palette;
 			}
-			dst += _screenWidth;
+			dst += state->surf_pitch;
 			src += state->width * 8;
 		} while (--state->draw_height);
 	}
 }
 
+void AGOSEngine::drawImage(VC10_state *state) {
+	const uint16 *vlut = &_videoWindows[_windowNum * 4];
 
+	if (drawImage_clip(state) == 0)
+		return;
+
+	uint16 xoffs, yoffs;
+	if (getGameType() == GType_WW) {
+		if (_windowNum == 4 || (_windowNum >= 10 && _windowNum <= 27)) {
+			state->surf_addr = _window4BackScn;
+			state->surf_pitch = _videoWindows[18] * 16;
+
+			xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
+			yoffs = (vlut[1] - _videoWindows[17] + state->y);
+
+			uint xmax = (xoffs + state->draw_width * 2);
+			uint ymax = (yoffs + state->draw_height);
+			setMoveRect(xoffs, yoffs, xmax, ymax);
+
+			_window4Flag = 1;
+		} else {
+			state->surf_addr = getFrontBuf();
+			state->surf_pitch = _screenWidth;
+
+			xoffs = (vlut[0] * 2 + state->x) * 8;
+			yoffs = vlut[1] + state->y;
+		}
+	} else if (getGameType() == GType_ELVIRA2) {
+		if (_windowNum == 4 || _windowNum >= 10) {
+			state->surf_addr = _window4BackScn;
+			state->surf_pitch = _videoWindows[18] * 16;
+
+			xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
+			yoffs = (vlut[1] - _videoWindows[17] + state->y);
+
+			uint xmax = (xoffs + state->draw_width * 2);
+			uint ymax = (yoffs + state->draw_height);
+			setMoveRect(xoffs, yoffs, xmax, ymax);
+
+			_window4Flag = 1;
+		} else {
+			state->surf_addr = getFrontBuf();
+			state->surf_pitch = _screenWidth;
+
+			xoffs = (vlut[0] * 2 + state->x) * 8;
+			yoffs = vlut[1] + state->y;
+		}
+	} else if (getGameType() == GType_ELVIRA1) {
+		if (_windowNum == 6) {
+			state->surf_addr = _window6BackScn;
+			state->surf_pitch = 48;	
+
+			xoffs = state->x * 8;
+			yoffs = state->y;
+		} else if (_windowNum == 2 || _windowNum == 3) {
+			state->surf_addr = getFrontBuf();
+			state->surf_pitch = _screenWidth;
+
+			xoffs = (vlut[0] * 2 + state->x) * 8;
+			yoffs = vlut[1] + state->y;
+
+		} else {
+			state->surf_addr = _window4BackScn;
+			state->surf_pitch = _videoWindows[18] * 16;
+
+			xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8;
+			yoffs = (vlut[1] - _videoWindows[17] + state->y);
+
+			uint xmax = (xoffs + state->draw_width * 2);
+			uint ymax = (yoffs + state->draw_height);
+			setMoveRect(xoffs, yoffs, xmax, ymax);
+
+			_window4Flag = 1;
+		}
+	}
+
+	state->surf_addr += xoffs + yoffs * state->surf_pitch;
+
+	if (getGameType() == GType_ELVIRA1 && (state->flags & kDFNonTrans) && yoffs > 133)
+		state->paletteMod = 16;
+
+	if (getGameType() == GType_ELVIRA2 || getGameType() == GType_WW)
+		state->palette = state->surf_addr[0] & 0xF0;
+
+	if (_backFlag == 1) {
+		drawBackGroundImage(state);
+	} else {
+		drawVertImage(state);
+	}
+}
+
 void AGOSEngine::horizontalScroll(VC10_state *state) {
 	const byte *src;
 	byte *dst;
@@ -766,7 +900,11 @@
 
 	vcWriteVar(251, _scrollX);
 
-	dst = getBackBuf();
+	if (!_oldDrawMethod) {
+		dst = getBackBuf();
+	} else {
+		dst = _window4BackScn;
+	}
 
 	if (getGameType() == GType_FF)
 		src = state->srcPtr + _scrollX / 2;
@@ -778,6 +916,10 @@
 		dst += 8;
 		src += 4;
 	}
+
+	setMoveRect(0, 0, 320, _scrollHeight);
+
+	_window4Flag = 1;
 }
 
 void AGOSEngine::verticalScroll(VC10_state *state) {
@@ -806,70 +948,6 @@
 	}
 }
 
-void AGOSEngine_Feeble::scaleClip(int16 h, int16 w, int16 y, int16 x, int16 scrollY) {
-	Common::Rect srcRect, dstRect;
-	float factor, xscale;
-
-	srcRect.left = 0;
-	srcRect.top = 0;
-	srcRect.right = w;
-	srcRect.bottom = h;
-
-	if (scrollY > _baseY)
-		factor = 1 + ((scrollY - _baseY) * _scale);
-	else
-		factor = 1 - ((_baseY - scrollY) * _scale);
-
-	xscale = ((w * factor) / 2);
-
-	dstRect.left   = (int16)(x - xscale);
-	if (dstRect.left > _screenWidth - 1)
-		return;
-	dstRect.top    = (int16)(y - (h * factor));
-	if (dstRect.top > _screenHeight - 1)
-		return;
-
-	dstRect.right  = (int16)(x + xscale);
-	dstRect.bottom = y;
-
-	_feebleRect = dstRect;
-
-	_variableArray[20] = _feebleRect.top;
-	_variableArray[21] = _feebleRect.left;
-	_variableArray[22] = _feebleRect.bottom;
-	_variableArray[23] = _feebleRect.right;
-
-	debug(5, "Left %d Right %d Top %d Bottom %d", dstRect.left, dstRect.right, dstRect.top, dstRect.bottom);
-
-	// Unlike normal rectangles in ScummVM, it seems that in the case of
-	// the destination rectangle the bottom and right coordinates are
-	// considered to be inside the rectangle. For the source rectangle,
-	// I believe that they are not.
-
-	int scaledW = dstRect.width() + 1;
-	int scaledH = dstRect.height() + 1;
-
-	byte *src = getScaleBuf();
-	byte *dst = getBackBuf();
-
-	dst += _dxSurfacePitch * dstRect.top + dstRect.left;
-
-	for (int dstY = 0; dstY < scaledH; dstY++) {
-		if (dstRect.top + dstY >= 0 && dstRect.top + dstY < _screenHeight) {
-			int srcY = (dstY * h) / scaledH;
-			byte *srcPtr = src + _dxSurfacePitch * srcY;
-			byte *dstPtr = dst + _dxSurfacePitch * dstY;
-			for (int dstX = 0; dstX < scaledW; dstX++) {
-				if (dstRect.left + dstX >= 0 && dstRect.left + dstX < _screenWidth) {
-					int srcX = (dstX * w) / scaledW;
-					if (srcPtr[srcX])
-						dstPtr[dstX] = srcPtr[srcX];
-				}
-			}
-		}
-	}
-}
-
 void AGOSEngine::paletteFadeOut(byte *palPtr, uint num, uint size) {
 	byte *p = palPtr;
 
@@ -1074,6 +1152,9 @@
 			b += sizeof(ImageHeader_Simon);
 		}
 		assert(READ_BE_UINT16(&((ImageHeader_Simon *) b)->id) == vga_res_id);
+
+		if (!vgaScript && _oldDrawMethod)
+			clearVideoWindow(_windowNum, READ_BE_UINT16(&((ImageHeader_Simon *) b)->color));
 	} else {
 		b = bb + READ_BE_UINT16(bb + 10);
 		b += 20;
@@ -1089,7 +1170,7 @@
 		assert(READ_BE_UINT16(&((ImageHeader_WW *) b)->id) == vga_res_id);
 
 		if (!vgaScript)
-			clearWindow(_windowNum, READ_BE_UINT16(&((ImageHeader_WW *) b)->color));
+			clearVideoWindow(_windowNum, READ_BE_UINT16(&((ImageHeader_WW *) b)->color));
 	}
 
 	if (_startVgaScript) {
@@ -1117,6 +1198,8 @@
 }
 
 void AGOSEngine::setWindowImageEx(uint16 mode, uint16 vga_res) {
+	_window3Flag = 0;
+
 	if (mode == 4) {
 		vc29_stopAllSounds();
 
@@ -1151,10 +1234,10 @@
 		vc27_resetSprite();
 	}
 
-	if (vga_res_id == 0) {
+	if (!vga_res_id) {
 		if (getGameType() == GType_SIMON1) {
 			_unkPalFlag = true;
-		} else if (getGameType() == GType_SIMON2) {
+		} else if (getGameType() == GType_SIMON2 && !_oldDrawMethod) {
 			_useBackGround = true;
 			_restoreWindow6 = true;
 		}
@@ -1187,7 +1270,7 @@
 		fillFrontFromBack(0, 0, _screenWidth, _screenHeight);
 		fillBackGroundFromBack(_screenHeight);
 		_syncFlag2 = 1;
-	} else if (getGameType() == GType_SIMON2) {
+	} else if (getGameType() == GType_SIMON2 && !_oldDrawMethod) { 
 		if (!_useBackGround) {
 			num_lines = _windowNum == 4 ? 134 : 200;
 			_boxStarHeight = num_lines;
@@ -1196,7 +1279,7 @@
 			_syncFlag2 = 1;
 		}
 		_useBackGround = false;
-	} else if (getGameType() == GType_SIMON1) {
+	} else if (getGameType() == GType_SIMON1 && !_oldDrawMethod) {
 		// Allow one section of Simon the Sorcerer 1 introduction to be displayed
 		// in lower half of screen
 		if (_subroutine == 2923 || _subroutine == 2926)
@@ -1209,21 +1292,90 @@
 		_syncFlag2 = 1;
 		_timer5 = 0;
 	} else {
-		num_lines = _windowNum == 4 ? 134 : 200;
-		fillFrontFromBack(0, 0, _screenWidth, num_lines);
-		fillBackGroundFromBack(num_lines);
-		_syncFlag2 = 1;
-		_timer5 = 0;
-	}
+		if (_window3Flag == 1) {
+			clearVideoBackGround(3, 0); // (window, color)
+		}
 
-	if (getGameType() == GType_ELVIRA1 && updateWindow == 3 && _bottomPalette != 0) {
-		byte *dst = getBackBuf() + 42560;
-		int size = 21440;
+		uint xoffs = _videoWindows[updateWindow * 4 + 0] * 16;
+		uint yoffs = _videoWindows[updateWindow * 4 + 1];
+		uint width = _videoWindows[updateWindow * 4 + 2] * 16;
+		uint height = _videoWindows[updateWindow * 4 + 3];
 
-		while (size--) {
-			*dst += 0x10;
-			dst++;
+		byte *dst = getBackGround() + xoffs + yoffs * _screenWidth;
+		byte *src;
+		uint srcWidth;
+
+		if (getGameType() == GType_SIMON2) {
+			src = _window4BackScn + xoffs + yoffs * 320;
+			srcWidth = 320;
+		} else if (getGameType() == GType_SIMON1) {
+			if (updateWindow == 4) {
+				src = _window4BackScn;
+				srcWidth = _videoWindows[18] * 16;
+			} else if (updateWindow >= 10) {
+				src = _window4BackScn + xoffs + yoffs * 320;
+				srcWidth = _videoWindows[18] * 16;
+			} else if (updateWindow == 0) {
+				src = getFrontBuf() + xoffs + yoffs * _screenWidth;
+				srcWidth = _screenWidth;
+			} else {
+				_lockWord &= ~0x20;
+				return;
+			}
+		} else if (getGameType() == GType_WW) {
+			if (updateWindow == 4 || updateWindow >= 10) {
+				src = _window4BackScn;
+				srcWidth = _videoWindows[18] * 16;
+			} else if (updateWindow == 3 || updateWindow == 9) {
+				src = getFrontBuf() + xoffs + yoffs * _screenWidth;
+				srcWidth = _screenWidth;
+			} else {
+				_lockWord &= ~0x20;
+				return;
+			}
+		} else if (getGameType() == GType_ELVIRA2) {
+			if (updateWindow == 4 || updateWindow >= 10) {
+				src = _window4BackScn;
+				srcWidth = _videoWindows[18] * 16;
+			} else if (updateWindow == 3) {
+				src = getFrontBuf() + xoffs + yoffs * _screenWidth;
+				srcWidth = _screenWidth;
+			} else {
+				_lockWord &= ~0x20;
+				return;
+			}
+		} else if (getGameType() == GType_ELVIRA1) {
+			if (updateWindow == 6) {
+				_window6Flag = 1;
+				src = _window6BackScn;
+				srcWidth = 48;
+			} else if (updateWindow == 2 || updateWindow == 3) {
+				src = getFrontBuf() + xoffs + yoffs * _screenWidth;
+				srcWidth = _screenWidth;
+			} else {
+				src = _window4BackScn;
+				srcWidth = _videoWindows[18] * 16;
+			}
 		}
+
+		for (; height > 0; height--) {
+			memcpy(dst, src, width);
+			dst += _screenWidth;
+			src += srcWidth;
+		}
+
+		if (getGameType() == GType_ELVIRA1 && updateWindow == 3 && _bottomPalette != 0) {
+			dst = getFrontBuf() + 42560;
+			int size = 21440;
+
+			while (size--) {
+				*dst += 0x10;
+				dst++;
+			}
+		}
+
+		_syncFlag2 = 1;
+		_timer5 = 0;
 	}
 
 	_lockWord &= ~0x20;

Modified: scummvm/trunk/engines/agos/input.cpp
===================================================================
--- scummvm/trunk/engines/agos/input.cpp	2007-05-09 13:25:14 UTC (rev 26791)
+++ scummvm/trunk/engines/agos/input.cpp	2007-05-09 15:36:05 UTC (rev 26792)
@@ -174,6 +174,7 @@
 	_verbHitArea = 0;
 	_hitAreaSubjectItem = NULL;
 	_hitAreaObjectItem = NULL;
+	_clickOnly = 0;
 	_nameLocked = 0;
 
 	if (getGameType() == GType_WW) {

Modified: scummvm/trunk/engines/agos/saveload.cpp
===================================================================
--- scummvm/trunk/engines/agos/saveload.cpp	2007-05-09 13:25:14 UTC (rev 26791)
+++ scummvm/trunk/engines/agos/saveload.cpp	2007-05-09 15:36:05 UTC (rev 26792)
@@ -118,15 +118,21 @@
 		sprintf(buf, "feeble.%.3d", slot);
 	} else if (getGameType() == GType_SIMON2) {
 		sprintf(buf, "simon2.%.3d", slot);
-	} else {
+	} else if (getGameType() == GType_SIMON1) {
 		sprintf(buf, "simon1.%.3d", slot);
+	} else if (getGameType() == GType_WW) {
+		sprintf(buf, "waxworks.%.3d", slot);
+	} else if (getGameType() == GType_ELVIRA2) {
+		sprintf(buf, "elvira2.%.3d", slot);
+	} else if (getGameType() == GType_ELVIRA1) {
+		sprintf(buf, "elvira1.%.3d", slot);
 	}
 	return buf;
 }
 
 void AGOSEngine::quickLoadOrSave() {
 	// Quick load & save is only supported complete version of Simon the Sorcerer 1/2
-	if (getGameType() != GType_SIMON1 && getGameType() != GType_SIMON2 ||
+	if (getGameType() == GType_PP || getGameType() == GType_FF ||
 		(getFeatures() & GF_DEMO)) {
 		return;
 	}

Modified: scummvm/trunk/engines/agos/script_e1.cpp
===================================================================
--- scummvm/trunk/engines/agos/script_e1.cpp	2007-05-09 13:25:14 UTC (rev 26791)
+++ scummvm/trunk/engines/agos/script_e1.cpp	2007-05-09 15:36:05 UTC (rev 26792)
@@ -608,9 +608,9 @@
 void AGOSEngine_Elvira1::oe1_pcName() {
 	// 115:
 	Item *i = getNextItemPtr();
-	Common::String name = (const char *)getStringPtrByID(i->itemName);
-	name.toUppercase();
-	showMessageFormat("%s", name.c_str());
+
+	// TODO: Change first letter to upper case.
+	showMessageFormat("%s\n", (const byte *)getStringPtrByID(i->itemName)); // Difference
 }
 
 void AGOSEngine_Elvira1::oe1_isCalled() {
@@ -815,6 +815,8 @@
 
 	_lastHitArea3 = 0;
 	_lastHitArea = 0;
+
+	_clickOnly = 1;
 }
 
 void AGOSEngine_Elvira1::oe1_setTime() {
@@ -1208,12 +1210,6 @@
 	state.x_skip = 0;
 	state.y_skip = 0;
 
-	state.surf2_addr = getFrontBuf();
-	state.surf2_pitch = _dxSurfacePitch;
-
-	state.surf_addr = getBackBuf();
-	state.surf_pitch = _dxSurfacePitch;
-
 	drawImage(&state);
 }
 

Modified: scummvm/trunk/engines/agos/script_e2.cpp
===================================================================
--- scummvm/trunk/engines/agos/script_e2.cpp	2007-05-09 13:25:14 UTC (rev 26791)
+++ scummvm/trunk/engines/agos/script_e2.cpp	2007-05-09 15:36:05 UTC (rev 26792)
@@ -310,7 +310,7 @@
 	SubObject *subObject = (SubObject *)findChildOfType(getNextItemPtr(), 2);
 
 	if (subObject != NULL && subObject->objectFlags & kOFText)
-		showMessageFormat((const char *)getStringPtrByID(subObject->objectFlagValue[0]));
+		showMessageFormat("%s\n", (const char *)getStringPtrByID(subObject->objectFlagValue[0])); // Difference
 }
 
 void AGOSEngine_Elvira2::oe2_loadGame() {

Modified: scummvm/trunk/engines/agos/subroutine.cpp
===================================================================
--- scummvm/trunk/engines/agos/subroutine.cpp	2007-05-09 13:25:14 UTC (rev 26791)
+++ scummvm/trunk/engines/agos/subroutine.cpp	2007-05-09 15:36:05 UTC (rev 26792)
@@ -522,7 +522,7 @@
 	// WORKAROUND: Bit Flag 171 isn't set when Simon rides the lion to the
 	// goblin camp in non-English versions. Bit Flag 171 is required to display 
 	// the red trail between locations on the map, during the ride.
-	if (getGameType() == GType_SIMON2) {
+	if (getGameType() == GType_SIMON2 && !_oldDrawMethod) {
 		if (sub->id == 13020)
 			setBitFlag(171, true);
 		if (sub->id == 13021)

Modified: scummvm/trunk/engines/agos/verb.cpp
===================================================================
--- scummvm/trunk/engines/agos/verb.cpp	2007-05-09 13:25:14 UTC (rev 26791)
+++ scummvm/trunk/engines/agos/verb.cpp	2007-05-09 15:36:05 UTC (rev 26792)
@@ -682,8 +682,18 @@
 						_variableArray[500] = best_ha->verb & 0xBFFF;
 					}
 				}
-			} 
 
+				if (_clickOnly != 0 && best_ha->id < 8) {
+					uint id = best_ha->id;
+					if (id >= 4)
+						id -= 4;
+
+					invertBox(findBox(id), 0, 0, 0, 0);
+					_clickOnly = 0;
+					return;
+				}
+			}
+
 			if (best_ha->flags & kBFDragBox) {
 				_lastClickRem = best_ha;
 			}

Modified: scummvm/trunk/engines/agos/vga.cpp
===================================================================
--- scummvm/trunk/engines/agos/vga.cpp	2007-05-09 13:25:14 UTC (rev 26791)
+++ scummvm/trunk/engines/agos/vga.cpp	2007-05-09 15:36:05 UTC (rev 26792)
@@ -210,6 +210,17 @@
 	return item->state == b;
 }
 
+void AGOSEngine::dirtyBackGround() {
+	AnimTable *animTable = _screenAnim1;
+	while (animTable->srcPtr) {
+		if (animTable->id == _vgaCurSpriteId) {
+			animTable->window |= 0x8000;
+			break;
+		}
+		animTable++;
+	}
+}
+
 VgaSprite *AGOSEngine::findCurSprite() {
 	VgaSprite *vsp = _vgaSprites;
 	while (vsp->id) {
@@ -400,19 +411,22 @@
 		return;
 	}
 
-	windowNum = vcReadNextWord();		/* 0 */
+	windowNum = vcReadNextWord();
+	if (getGameType() == GType_SIMON1 && windowNum == 3) {
+		_window3Flag = 1;
+	}
 
 	if (getGameType() == GType_SIMON2 || getGameType() == GType_FF || getGameType() == GType_PP) {
-		zoneNum = vcReadNextWord();	/* 0 */
-		vgaSpriteId = vcReadNextWord();	/* 2 */
+		zoneNum = vcReadNextWord();
+		vgaSpriteId = vcReadNextWord();
 	} else {
-		vgaSpriteId = vcReadNextWord();	/* 2 */
+		vgaSpriteId = vcReadNextWord();
 		zoneNum = vgaSpriteId / 100;
 	}
 
-	x = vcReadNextWord();			/* 4 */
-	y = vcReadNextWord();			/* 6 */
-	palette = vcReadNextWord();		/* 8 */
+	x = vcReadNextWord();
+	y = vcReadNextWord();
+	palette = vcReadNextWord();
 
 	old_file_1 = _curVgaFile1;
 
@@ -607,6 +621,7 @@
 		state.image = vcReadVar(-state.image);
 
 	state.palette = palette * 16;
+	state.paletteMod = 0;
 
 	state.x = x - _scrollX;
 	state.y = y - _scrollY;
@@ -718,12 +733,18 @@
 void AGOSEngine::vc13_addToSpriteX() {
 	VgaSprite *vsp = findCurSprite();
 	vsp->x += (int16)vcReadNextWord();
+
+	vsp->windowNum |= 0x8000;
+	dirtyBackGround();
 	_vgaSpriteChanged++;
 }
 
 void AGOSEngine::vc14_addToSpriteY() {
 	VgaSprite *vsp = findCurSprite();
 	vsp->y += (int16)vcReadNextWord();
+
+	vsp->windowNum |= 0x8000;
+	dirtyBackGround();
 	_vgaSpriteChanged++;
 }
 
@@ -951,6 +972,8 @@
 		vsp->flags = vcReadNextWord();
 	}
 
+	vsp->windowNum |= 0x8000;
+	dirtyBackGround();
 	_vgaSpriteChanged++;
 }
 
@@ -963,6 +986,8 @@
 		vsp++;
 	}
 	_vcPtr = (byte *)&_vc_get_out_of_code;
+
+	dirtyBackGround();
 	_vgaSpriteChanged++;
 }
 
@@ -1024,6 +1049,14 @@
 		}
 	}
 
+	if (_lockWord & 0x20) {
+		AnimTable *animTable = _screenAnim1;
+		while (animTable->srcPtr) {
+			animTable->srcPtr = 0;
+			animTable++;
+		}
+	}
+
 	if (getGameType() == GType_SIMON2 || getGameType() == GType_FF || getGameType() == GType_PP)
 		vcWriteVar(254, 0);
 
@@ -1083,8 +1116,20 @@
 }
 
 void AGOSEngine::vc32_saveScreen() {
-	// TODO
-	debug(0, "vc32_saveScreen: stub");
+	uint xoffs = _videoWindows[4 * 4 + 0] * 16;
+	uint yoffs = _videoWindows[4 * 4 + 1];
+	uint width = _videoWindows[4 * 4 + 2] * 16;
+	uint height = _videoWindows[4 * 4 + 3];
+
+	byte *dst = getBackGround() + xoffs + yoffs * _screenWidth;
+	byte *src = _window4BackScn;
+	uint srcWidth = _videoWindows[4 * 4 + 2] * 16;
+
+	for (; height > 0; height--) {
+		memcpy(dst, src, width);
+		dst += _screenWidth;
+		src += srcWidth;
+	}
 }
 
 void AGOSEngine::vc33_setMouseOn() {
@@ -1111,32 +1156,89 @@
 	_leftButtonDown = 0;
 }
 
-void AGOSEngine::clearWindow(uint num, uint color) {
+void AGOSEngine::clearVideoBackGround(uint num, uint color) {
+	debug(0, "clearVideoBackGround: num %d color %d", num, color);
+
+	const uint16 *vlut = &_videoWindows[num * 4];
+	byte *dst = getBackGround() + vlut[0] * 16 + (vlut[1] * (vlut[2] * 16));
+
+	for (uint h = 0; h < vlut[3]; h++) {
+		memset(dst, color, vlut[2] * 16);
+		dst += _screenWidth;
+	}
+}
+
+void AGOSEngine::clearVideoWindow(uint num, uint color) {
 	if (getGameType() == GType_ELVIRA1) {
 		if (num == 2 || num == 6)
 			return;
 	} else if (getGameType() == GType_ELVIRA2 || getGameType() == GType_WW) {
 		if (num != 4 && num < 10)
 			return;
+	} else if (getGameType() == GType_SIMON1) {
+		if (num != 4)
+			return;
 	}
 
-	if (num == 3) {
-		memset(getBackBuf(), 0, _screenWidth * _screenHeight);
-	} else { 
+	debug(0, "clearVideoWindow: num %d color %d", num, color);
+
+	if (getGameType() == GType_SIMON2) {
 		const uint16 *vlut = &_videoWindows[num * 4];
-		byte *dst = getBackBuf() + vlut[0] * 16 + vlut[1] * _dxSurfacePitch;
+		uint xoffs = vlut[0] * 16;
+		uint yoffs = vlut[1];
+		uint dstWidth = _videoWindows[18] * 16;
+		byte *dst =  _window4BackScn + xoffs + yoffs * dstWidth;
 
+		setMoveRect(0, 0, vlut[2] * 16, vlut[3]);
+
 		for (uint h = 0; h < vlut[3]; h++) {
-			memset(dst, 0, vlut[2] * 16);
-			dst += _screenWidth;
+			memset(dst, color, vlut[2] * 16);
+			dst += dstWidth;
 		}
+
+		_window4Flag = 1;
+	} else {
+		if (getGameType() == GType_ELVIRA1 && num == 3) {
+			memset(getFrontBuf(), color, _screenWidth * _screenHeight);
+		} else if (num == 4) {
+			const uint16 *vlut = &_videoWindows[num * 4];
+			uint xoffs = (vlut[0] - _videoWindows[16]) * 16;
+			uint yoffs = (vlut[1] - _videoWindows[17]);
+			uint dstWidth = _videoWindows[18] * 16;
+			byte *dst =  _window4BackScn + xoffs + yoffs * dstWidth;
+
+			setMoveRect(0, 0, vlut[2] * 16, vlut[3]);
+
+			for (uint h = 0; h < vlut[3]; h++) {
+				memset(dst, color, vlut[2] * 16);
+				dst += dstWidth;
+			}
+
+			_window4Flag = 1;
+		}
 	}
 }
 
 void AGOSEngine::vc35_clearWindow() {
 	uint16 num = vcReadNextWord();
 	uint16 color = vcReadNextWord();
-	clearWindow(num, color);
+
+	// Clear video window
+	clearVideoWindow(num, color);
+
+	// Clear video background
+	if (getGameType() == GType_ELVIRA1) {
+		if (num == 2 || num == 6)
+			return;
+	} else if (getGameType() == GType_ELVIRA2 || getGameType() == GType_WW) {
+		if (num != 4 && num < 10)
+			return;
+	} else if (getGameType() == GType_SIMON1) {
+		if (num != 4)
+			return;
+	}
+
+	clearVideoBackGround(num, color);
 }
 
 void AGOSEngine::vc36_setWindowImage() {
@@ -1147,7 +1249,7 @@
 	if (getGameType() == GType_FF || getGameType() == GType_PP) {
 		_copyPartialMode = 2;
 	} else if (getGameType() == GType_SIMON1) {
-		if (windowNum == 16) {
+		if (windowNum == 16 && !_oldDrawMethod) {
 			_copyPartialMode = 2;
 		} else {
 			setWindowImage(windowNum, vga_res);

Modified: scummvm/trunk/engines/agos/vga.h
===================================================================
--- scummvm/trunk/engines/agos/vga.h	2007-05-09 13:25:14 UTC (rev 26791)
+++ scummvm/trunk/engines/agos/vga.h	2007-05-09 15:36:05 UTC (rev 26792)
@@ -56,7 +56,7 @@
 // Simon 1/2
 struct ImageHeader_Simon {
 	uint16 id;
-	uint16 x_1;
+	uint16 color;
 	uint16 x_2;
 	uint16 scriptOffs;
 };
@@ -116,6 +116,7 @@
 	int16 image;
 	uint16 flags;
 	byte palette;
+	byte paletteMod;
 
 	int16 x, y;
 	uint16 width, height;

Modified: scummvm/trunk/engines/agos/vga_e2.cpp
===================================================================
--- scummvm/trunk/engines/agos/vga_e2.cpp	2007-05-09 13:25:14 UTC (rev 26791)
+++ scummvm/trunk/engines/agos/vga_e2.cpp	2007-05-09 15:36:05 UTC (rev 26792)
@@ -68,21 +68,37 @@
 	uint num = vcReadNextWord();
 	uint color = vcReadNextWord();
 
-	const uint16 *vlut = &_videoWindows[num * 4];
-	uint16 *dst = (uint16 *)getBackBuf() + vlut[0] * 8 + vlut[1] * _dxSurfacePitch / 2;
-	uint width = vlut[2] * 8;
+	if (num == 4) {
+		const uint16 *vlut = &_videoWindows[num * 4];
+		uint16 *dst = (uint16 *)_window4BackScn;
+		uint width = vlut[2] * 16 / 2;
+		uint height = vlut[3];
 
-	if (getGameType() == GType_ELVIRA2 && num == 7) {
-		dst -= 4;
-		width += 4;
-	}
+		for (uint h = 0; h < height; h++) {
+			for (uint w = 0; w < width; w++) {
+				dst[w] &= 0xF0F;
+				dst[w] |= color * 16;
+			}
+			dst += width;
+		}
+	} else {
+		const uint16 *vlut = &_videoWindows[num * 4];
+		uint16 *dst = (uint16 *)getFrontBuf() + vlut[0] * 8 + vlut[1] * _dxSurfacePitch / 2;
+		uint width = vlut[2] * 16 / 2;
+		uint height = vlut[3];
 
-	for (uint h = 0; h < vlut[3]; h++) {
-		for (uint w = 0; w < width; w++) {
-			dst[w] &= 0xF0F;
-			dst[w] |= color * 16;
+		if (getGameType() == GType_ELVIRA2 && num == 7) {
+			dst -= 4;
+			width += 4;
 		}
-		dst += _dxSurfacePitch / 2;
+
+		for (uint h = 0; h < height; h++) {
+			for (uint w = 0; w < width; w++) {
+				dst[w] &= 0xF0F;
+				dst[w] |= color * 16;
+			}
+			dst += _dxSurfacePitch / 2;
+		}
 	}
 }
 
@@ -211,7 +227,7 @@
 
 void AGOSEngine::vc56_fullScreen() {
 	byte *src = _curVgaFile2 + 32;
-	byte *dst = getBackBuf();
+	byte *dst = getFrontBuf();
 
 	memcpy(dst, src + 768, _screenHeight * _screenWidth);
 	//fullFade();

Modified: scummvm/trunk/engines/agos/vga_s1.cpp
===================================================================
--- scummvm/trunk/engines/agos/vga_s1.cpp	2007-05-09 13:25:14 UTC (rev 26791)
+++ scummvm/trunk/engines/agos/vga_s1.cpp	2007-05-09 15:36:05 UTC (rev 26792)
@@ -103,18 +103,27 @@
 void AGOSEngine::vc37_addToSpriteY() {
 	VgaSprite *vsp = findCurSprite();
 	vsp->y += vcReadVar(vcReadNextWord());
+
+	vsp->windowNum |= 0x8000;
+	dirtyBackGround();
 	_vgaSpriteChanged++;
 }
 
 void AGOSEngine::vc45_setSpriteX() {
 	VgaSprite *vsp = findCurSprite();
 	vsp->x = vcReadVar(vcReadNextWord());
+
+	vsp->windowNum |= 0x8000;
+	dirtyBackGround();
 	_vgaSpriteChanged++;
 }
 
 void AGOSEngine::vc46_setSpriteY() {
 	VgaSprite *vsp = findCurSprite();
 	vsp->y = vcReadVar(vcReadNextWord());
+
+	vsp->windowNum |= 0x8000;
+	dirtyBackGround();
 	_vgaSpriteChanged++;
 }
 
@@ -209,6 +218,8 @@
 	vsp->y += vcReadNextWord();
 	vsp->flags = kDFMasked | kDFUseFrontBuf;
 
+	vsp->windowNum |= 0x8000;
+	dirtyBackGround();
 	_vgaSpriteChanged++;
 }
 

Modified: scummvm/trunk/engines/agos/vga_ww.cpp
===================================================================
--- scummvm/trunk/engines/agos/vga_ww.cpp	2007-05-09 13:25:14 UTC (rev 26791)
+++ scummvm/trunk/engines/agos/vga_ww.cpp	2007-05-09 15:36:05 UTC (rev 26792)
@@ -110,7 +110,7 @@
 
 	if (a == 6) {
 		src = _curVgaFile2 + 800;
-		dstPtr = getBackBuf();
+		dstPtr = getFrontBuf();
 		memcpy(dstPtr, src, 64000);
 		tmp = 4 - 1;
 	} else {
@@ -218,14 +218,21 @@
 			}
 		}
 
-		// Allow one section of Simon the Sorcerer 1 introduction to be displayed
-		// in lower half of screen
-		if ((getGameType() == GType_SIMON1) && (_subroutine == 2923 || _subroutine == 2926)) {
-			clearSurfaces(200);
-		} else if (getGameType() == GType_FF || getGameType() == GType_PP) {
+		if (getGameType() == GType_FF || getGameType() == GType_PP) {
 			clearSurfaces(480);
+		} else if (getGameType() == GType_WW) {
+			memset(getFrontBuf(), 0, _screenWidth * _screenHeight);
+		} else if (!_oldDrawMethod) {
+			// Allow one section of Simon the Sorcerer 1 introduction to be displayed
+			// in lower half of screen
+			if ((getGameType() == GType_SIMON1) && (_subroutine == 2923 || _subroutine == 2926)) {
+				clearSurfaces(200);
+			} else {
+				clearSurfaces(_windowNum == 4 ? 134 : 200);
+			}
 		} else {
-			clearSurfaces(_windowNum == 4 ? 134 : 200);
+			if (_windowNum != 4)
+				memset(getFrontBuf(), 0, _screenWidth * _screenHeight);
 		}
 	}
 	if (getGameType() == GType_SIMON2) {

Modified: scummvm/trunk/engines/agos/window.cpp
===================================================================
--- scummvm/trunk/engines/agos/window.cpp	2007-05-09 13:25:14 UTC (rev 26791)
+++ scummvm/trunk/engines/agos/window.cpp	2007-05-09 15:36:05 UTC (rev 26792)
@@ -123,6 +123,18 @@
 			dst += _screenWidth;
 		}
 	} else {
+		if (getGameType() == GType_ELVIRA2 && window->y == 146) {
+			if (window->fill_color == 1) {
+				_displayPalette[33 * 4 + 0] = 48 * 4;
+				_displayPalette[33 * 4 + 1] = 40 * 4;
+				_displayPalette[33 * 4 + 2] = 32 * 4;
+			} else {
+				_displayPalette[33 * 4 + 0] = 56 * 4;
+				_displayPalette[33 * 4 + 1] = 56 * 4;
+				_displayPalette[33 * 4 + 2] = 40 * 4;
+			}
+		}
+
 		dst = getFrontBuf() + _dxSurfacePitch * window->y + window->x * 8;
 		h = window->height * 8;
 		w = window->width * 8;
@@ -170,7 +182,7 @@
 	uint i;
 
 	dst = getFrontBuf();
-	src = _backGroundBuf;
+	src = getBackGround();
 
 	dst += y * _dxSurfacePitch;
 	src += y * _dxSurfacePitch;


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