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

strangerke at users.sourceforge.net strangerke at users.sourceforge.net
Wed Sep 30 00:43:30 CEST 2009


Revision: 44472
          http://scummvm.svn.sourceforge.net/scummvm/?rev=44472&view=rev
Author:   strangerke
Date:     2009-09-29 22:43:30 +0000 (Tue, 29 Sep 2009)

Log Message:
-----------
Playtoons - implement some functions related to hotspot texts
Fascination - initial version of several 'Fascination Window' functions, proper naming of most of fascination OPCODEDRAW and OPCODEGOB functions

Modified Paths:
--------------
    scummvm/trunk/engines/gob/dataio.cpp
    scummvm/trunk/engines/gob/draw.cpp
    scummvm/trunk/engines/gob/draw.h
    scummvm/trunk/engines/gob/draw_fascin.cpp
    scummvm/trunk/engines/gob/global.cpp
    scummvm/trunk/engines/gob/global.h
    scummvm/trunk/engines/gob/gob.cpp
    scummvm/trunk/engines/gob/hotspots.cpp
    scummvm/trunk/engines/gob/hotspots.h
    scummvm/trunk/engines/gob/init.cpp
    scummvm/trunk/engines/gob/init.h
    scummvm/trunk/engines/gob/inter.h
    scummvm/trunk/engines/gob/inter_fascin.cpp
    scummvm/trunk/engines/gob/inter_playtoons.cpp
    scummvm/trunk/engines/gob/inter_v3.cpp

Modified: scummvm/trunk/engines/gob/dataio.cpp
===================================================================
--- scummvm/trunk/engines/gob/dataio.cpp	2009-09-29 20:47:05 UTC (rev 44471)
+++ scummvm/trunk/engines/gob/dataio.cpp	2009-09-29 22:43:30 UTC (rev 44472)
@@ -363,7 +363,7 @@
 int32 DataIO::getChunkSize(const char *chunkName, int32 &packSize) {
 	packSize = -1;
 
-	for (int16 file = 0; file < MAX_DATA_FILES; file++) {
+	for (int file = 0; file < MAX_DATA_FILES; file++) {
 		if (_dataFiles[file] == 0)
 			return -1;
 

Modified: scummvm/trunk/engines/gob/draw.cpp
===================================================================
--- scummvm/trunk/engines/gob/draw.cpp	2009-09-29 20:47:05 UTC (rev 44471)
+++ scummvm/trunk/engines/gob/draw.cpp	2009-09-29 22:43:30 UTC (rev 44472)
@@ -31,6 +31,7 @@
 #include "gob/util.h"
 #include "gob/dataio.h"
 #include "gob/game.h"
+#include "gob/resources.h"
 #include "gob/script.h"
 #include "gob/inter.h"
 #include "gob/video.h"
@@ -57,6 +58,7 @@
 
 	_letterToPrint = 0;
 	_textToPrint = 0;
+	_hotspotText = 0;
 
 	_backDeltaX = 0;
 	_backDeltaY = 0;
@@ -435,6 +437,756 @@
 	spriteOperation(DRAW_PRINTTEXT);
 }
 
+void Draw::oPlaytoons_sub_F_1B( uint16 id, int16 left, int16 top, int16 right, int16 bottom, char *paramStr, int16 fontIndex, int16 var4, int16 shortId) {
+	int16 i, j, width;
+	char tmpStr[128];
+
+	strcpy( tmpStr, paramStr);
+	adjustCoords(1, &left, &top);
+	adjustCoords(1, &right,  &bottom);
+
+	uint16 centerOffset = _vm->_game->_script->getFunctionOffset(TOTFile::kFunctionCenter);
+	if (centerOffset != 0) {
+		_vm->_game->_script->call(centerOffset);
+
+		WRITE_VAR(17, (uint32) id & 0x7FFF);
+		WRITE_VAR(18, (uint32) left);
+		WRITE_VAR(19, (uint32) top); 
+		WRITE_VAR(20, (uint32) (right - left + 1));
+		WRITE_VAR(21, (uint32) (bottom - top + 1));
+
+		if (_vm->_game->_script->peekUint16(41) >= '4') {
+			WRITE_VAR(22, (uint32) fontIndex);
+			WRITE_VAR(23, (uint32) var4);
+			if (id & 0x8000)
+				WRITE_VAR(24, (uint32) 1);
+			else
+				WRITE_VAR(24, (uint32) 0);
+			WRITE_VAR(25, (uint32) shortId);
+			if (_hotspotText) {
+				strncpy(_hotspotText, paramStr, 40);
+				_hotspotText[39] = 0;
+			}
+		}
+		_vm->_inter->funcBlock(0);
+		_vm->_game->_script->pop();
+	}
+	strcpy(paramStr, tmpStr);
+	if (*paramStr) {
+		_transparency = 1;
+		_fontIndex = fontIndex;
+		_frontColor = var4;
+		if (_vm->_game->_script->peekUint16(41) >= '4' && strchr(paramStr, 92)) {
+			char str[80];
+			char *str2;
+			int16 strLen= 0;
+			int16 offY, deltaY;
+
+			str2 = paramStr;
+			do { 
+				strLen++;
+				str2++;
+				str2 = strchr(str2, 92); 
+			} while (str2);
+			deltaY = (bottom - right + 1 - (strLen * _fonts[fontIndex]->getCharHeight())) / (strLen + 1);
+			offY = right + deltaY;
+			for (i = 0; paramStr[i]; i++) {
+				j = 0;
+				while (paramStr[i] && paramStr[i] != 92)
+					str[j++] = paramStr[i++];
+				str[j] = 0;
+				_destSpriteX = left;
+				_destSpriteY = offY;
+				_textToPrint = str;
+				width = stringLength(str, fontIndex);
+				adjustCoords(1, &width, NULL);
+				_destSpriteX += (top - left + 1 - width) / 2;
+				spriteOperation(DRAW_PRINTTEXT);
+				offY += deltaY + _fonts[fontIndex]->getCharHeight();
+			}
+		} else {
+			_destSpriteX = left;
+			if (_vm->_game->_script->peekUint16(41) >= '4') 
+				_destSpriteY = right + (bottom - right + 1 - _fonts[fontIndex]->getCharHeight()) / 2;
+			else 
+				_destSpriteY = right;
+			_textToPrint = paramStr;
+			width = stringLength(paramStr, fontIndex);
+			adjustCoords(1, &width, NULL);
+			_destSpriteX += (top - left + 1 - width) / 2;
+			spriteOperation(DRAW_PRINTTEXT);
+		}
+	}
+	return;
+}
+
+void Draw::activeWin (int16 id) {
+	int i, j;
+	bool found = false;
+	int16 t[10], t2[10];
+	int nextId = -1;
+	int oldId  = -1;
+	SurfaceDescPtr tempSrf;
+	SurfaceDescPtr oldSrf[10];
+
+	warning ("activeWindow %d", id);
+
+	if (_fascinWin[id].id == -1) 
+		return;
+	warning("swap screen ?");
+	forceBlit();
+	_vm->_video->dirtyRectsAll();
+	for (i = 0; i < 10; i++) { 
+		t[i] = -1;
+		t2[i] = -1;
+//		oldSrf[i] = 0;
+	}
+	for (i = 0; i < 10; i++)
+		if ((i != id) && (_fascinWin[i].id > _fascinWin[id].id) && (winOverlap(i, id))) { 
+			t[_fascinWin[i].id] = i;
+			found = true;
+		}
+	if (found) {
+		for (j = 10 - 1; j >= 0; j--)
+			if (t[j] != -1) {
+				if (nextId != -1)
+					_vm->_video->drawSprite(*_spritesArray[_destSurface], *_fascinWin[nextId].savedSurface,
+											 _fascinWin[t[j]].left, _fascinWin[t[j]].top,
+											 _fascinWin[t[j]].left + _fascinWin[t[j]].width  - 1,
+											 _fascinWin[t[j]].top  + _fascinWin[t[j]].height - 1,
+											 _fascinWin[t[j]].left & 15, 0, 0);
+				t2[j] = nextId;
+				restoreWin(t[j]);
+				nextId = t[j];
+			}
+			oldId = nextId;
+			_vm->_video->drawSprite(*_spritesArray[_destSurface], *_fascinWin[nextId].savedSurface,
+									 _fascinWin[id].left, _fascinWin[id].top,
+									 _fascinWin[id].left + _fascinWin[id].width  - 1,
+									 _fascinWin[id].top  + _fascinWin[id].height - 1,
+									 _fascinWin[id].left & 15, 0, 0);
+			restoreWin(id);
+			nextId = id;
+			for (j = 0; j < 10; j++)
+				if (t[j] != -1) {
+					_vm->_video->drawSprite(*_spritesArray[_destSurface], *_fascinWin[nextId].savedSurface,
+											 _fascinWin[t[j]].left, _fascinWin[t[j]].top,
+											 _fascinWin[t[j]].left + _fascinWin[t[j]].width  - 1,
+											 _fascinWin[t[j]].top  + _fascinWin[t[j]].height - 1,
+											 _fascinWin[t[j]].left & 15, 0, 0);
+					oldSrf[t[j]] = _fascinWin[nextId].savedSurface;
+					if (t2[j] != -1)
+						_vm->_video->drawSprite(*_fascinWin[t2[j]].savedSurface, *_spritesArray[_destSurface],
+												 _fascinWin[t[j]].left & 15, 0,
+												(_fascinWin[t[j]].left & 15) + _fascinWin[t[j]].width - 1,
+												 _fascinWin[t[j]].height - 1, _fascinWin[t[j]].left,
+												 _fascinWin[t[j]].top, 0);
+					else {
+// Strangerke not sure concerning the use of _sourceSurface
+// Shift skipped as always set to zero (?)
+						_vm->_video->drawSprite(*_spritesArray[_sourceSurface], *_spritesArray[_destSurface],
+												 _fascinWin[t[j]].left, _fascinWin[t[j]].top,
+												 _fascinWin[t[j]].left + _fascinWin[t[j]].width  - 1,
+												 _fascinWin[t[j]].top  + _fascinWin[t[j]].height - 1,
+												 _fascinWin[t[j]].left, _fascinWin[t[j]].top, 0);
+					}
+// Strangerke not sure concerning the use of _sourceSurface
+					dirtiedRect(_sourceSurface, _fascinWin[t[j]].left, _fascinWin[t[j]].top, 
+								_fascinWin[t[j]].left + _fascinWin[t[j]].width  - 1,
+								_fascinWin[t[j]].top  + _fascinWin[t[j]].height - 1);
+					nextId = t2[j];
+				}
+			tempSrf = _vm->_video->initSurfDesc(_vm->_global->_videoMode, _winMaxWidth + 15, _winMaxHeight, 0);
+			_vm->_video->drawSprite(*_spritesArray[_destSurface], *tempSrf, 
+									 _fascinWin[id].left, _fascinWin[id].top,
+									 _fascinWin[id].left + _fascinWin[id].width  - 1,
+									 _fascinWin[id].top  + _fascinWin[id].height - 1,
+									 _fascinWin[id].left & 15, 0, 0);
+			_vm->_video->drawSprite(*_fascinWin[oldId].savedSurface, *_spritesArray[_destSurface],
+									 _fascinWin[id].left & 15, 0,
+									(_fascinWin[id].left & 15) + _fascinWin[id].width - 1,
+									 _fascinWin[id].height - 1, 
+									 _fascinWin[id].left, _fascinWin[id].top, 0);
+			_fascinWin[oldId].savedSurface.reset();
+			_fascinWin[oldId].savedSurface = tempSrf;
+			oldSrf[id] = _fascinWin[oldId].savedSurface;
+// Strangerke not sure concerning the use of _destSurface
+			dirtiedRect(_destSurface, _fascinWin[id].left, _fascinWin[id].top, 
+						_fascinWin[id].left + _fascinWin[id].width  - 1,
+						_fascinWin[id].top  + _fascinWin[id].height - 1);
+			nextId = id;
+			for (j = 0; j < 10; j++)
+				if (oldSrf[j])
+					_fascinWin[j].savedSurface = oldSrf[j];
+	}
+	for (i = 0; i < 10; i++)
+		if ((i != id) && (_fascinWin[i].id > _fascinWin[id].id))
+			_fascinWin[i].id--;
+	_fascinWin[id].id = _winCount - 1;
+}
+
+bool Draw::winOverlap(int16 idWin1, int16 idWin2) {
+	if ((_fascinWin[idWin1].left + _fascinWin[idWin1].width  <= _fascinWin[idWin2].left) ||
+		(_fascinWin[idWin2].left + _fascinWin[idWin2].width  <= _fascinWin[idWin1].left) ||
+		(_fascinWin[idWin1].top  + _fascinWin[idWin1].height <= _fascinWin[idWin2].top ) ||
+		(_fascinWin[idWin2].top  + _fascinWin[idWin2].height <= _fascinWin[idWin1].top ))
+		return(false);
+ return(true);
+}
+
+void Draw::closeWin (int16 i) {
+	warning("closeWin %d", i);
+	if (_fascinWin[i].id == -1)
+		return;
+	WRITE_VAR((_winVarArrayStatus / 4) + i, VAR((_winVarArrayStatus / 4) + i) | 1);
+	restoreWin(i);
+	_fascinWin[i].id = -1;
+	_fascinWin[i].savedSurface.reset();
+	_winCount--;
+}
+
+int16 Draw::openWin(int16 id) {
+	if (_fascinWin[id].id != -1)
+		return(0);
+	_fascinWin[id].id = _winCount;
+	_winCount++;
+	_fascinWin[id].left   = VAR((_winVarArrayLeft   / 4) + id);
+	_fascinWin[id].top    = VAR((_winVarArrayTop    / 4) + id);
+	_fascinWin[id].width  = VAR((_winVarArrayWidth  / 4) + id);
+	_fascinWin[id].height = VAR((_winVarArrayHeight / 4) + id);
+	_fascinWin[id].savedSurface = _vm->_video->initSurfDesc(_vm->_global->_videoMode, _winMaxWidth + 15, _winMaxHeight, 0);
+
+	warning("Draw::openWin id %d- left %d top %d l %d h%d", id, _fascinWin[id].left, _fascinWin[id].top, _fascinWin[id].width, _fascinWin[id].height);
+
+	saveWin(id);
+	WRITE_VAR((_winVarArrayStatus / 4) + id, VAR((_winVarArrayStatus / 4) + id) & 0xFFFFFFFE);
+	return(1);
+}
+
+void Draw::restoreWin(int16 i) {
+	warning("restoreWin");
+	_vm->_video->drawSprite(*_fascinWin[i].savedSurface, *_spritesArray[_destSurface], 
+							 _fascinWin[i].left & 15, 0,
+							(_fascinWin[i].left & 15) + _fascinWin[i].width - 1, _fascinWin[i].height - 1,
+							 _fascinWin[i].left, _fascinWin[i].top, 0);
+	dirtiedRect(_fascinWin[i].savedSurface, _fascinWin[i].left, _fascinWin[i].top, 
+				_fascinWin[i].left + _fascinWin[i].width  - 1, 
+				_fascinWin[i].top  + _fascinWin[i].height - 1);
+}
+
+void Draw::saveWin(int16 id) {
+	warning("saveWin");
+	_vm->_video->drawSprite(*_spritesArray[_destSurface], *_fascinWin[id].savedSurface,
+							 _fascinWin[id].left,  _fascinWin[id].top,
+							 _fascinWin[id].left + _fascinWin[id].width  - 1,
+							 _fascinWin[id].top  + _fascinWin[id].height - 1,
+							 _fascinWin[id].left & 15, 0, 0);	
+	dirtiedRect(_destSurface, _fascinWin[id].left, 0,
+				_fascinWin[id].left + _fascinWin[id].width  - 1, 
+				_fascinWin[id].top  + _fascinWin[id].height - 1);
+}
+
+void Draw::winMove(int16 id) {
+	int oldLeft, oldTop;
+
+	oldLeft = _fascinWin[id].left;
+	oldTop = _fascinWin[id].top;
+	restoreWin(id);
+
+	_fascinWin[id].left = _vm->_global->_inter_mouseX;
+	_fascinWin[id].top = _vm->_global->_inter_mouseY;
+	WRITE_VAR((_winVarArrayLeft / 4) + id, _fascinWin[id].left);
+	WRITE_VAR((_winVarArrayTop  / 4) + id, _fascinWin[id].top);
+	saveWin(id);
+
+// Shift skipped as always set to zero (?)
+	_vm->_video->drawSprite(*_frontSurface, *_spritesArray[_destSurface],
+							oldLeft, oldTop,
+							oldLeft + _fascinWin[id].width  - 1, 
+							oldTop  + _fascinWin[id].height - 1,
+							_fascinWin[id].left, _fascinWin[id].top, 0);
+	dirtiedRect(_frontSurface, _fascinWin[id].left, _fascinWin[id].top, 
+				_fascinWin[id].left + _fascinWin[id].width  - 1,
+				_fascinWin[id].top  + _fascinWin[id].height - 1);
+}
+
+void Draw::winTrace(int16 left, int16 top, int16 width, int16 height) {
+// TODO : Implement correct the trace of the Window. In short,
+//  - drawline currently use the wrong surface, to be fixed
+//  - dirtiedRect should be put after the 4 drawlines when the surface is fixed
+//  - drawline should be replaced by a drawline with palette inversion
+
+	int16 right, bottom;
+
+	right  = left + width  - 1;
+	bottom = top  + height - 1;
+
+	_vm->_video->drawLine(*_backSurface, left,  top,    right, top,    0);
+	_vm->_video->drawLine(*_backSurface, left,  top,    left,  bottom, 0);
+	_vm->_video->drawLine(*_backSurface, left,  bottom, right, bottom, 0);
+	_vm->_video->drawLine(*_backSurface, right, top,    right, bottom, 0);
+}
+
+void Draw::handleWinBorder(int16 id) {
+	int16 minX = 0;
+	int16 maxX = 320;
+	int16 minY = 0;
+	int16 maxY = 200;
+	warning("handleWinBorder");
+
+	if (VAR((_winVarArrayStatus / 4) + id) & 8) 
+		minX = (int16)(VAR((_winVarArrayLimitsX / 4) + id) >> 16L);
+	if (VAR((_winVarArrayStatus / 4) + id) & 16)
+		maxX = (int16)(VAR((_winVarArrayLimitsX / 4) + id) & 0xFFFFL);
+	if (VAR((_winVarArrayStatus / 4) + id) & 32)
+		minY = (int16)(VAR((_winVarArrayLimitsY / 4) + id) >> 16L);
+	if (VAR((_winVarArrayStatus / 4) + id) & 64) 
+		maxY = (int16)(VAR((_winVarArrayLimitsY / 4) + id) & 0xFFFFL);
+	_vm->_global->_inter_mouseX = _fascinWin[id].left;
+	_vm->_global->_inter_mouseY = _fascinWin[id].top;
+	if (_vm->_global->_mousePresent)
+		_vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY);
+	winTrace(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY, _fascinWin[id].width, _fascinWin[id].height);
+	_cursorX = _vm->_global->_inter_mouseX;
+	_cursorY = _vm->_global->_inter_mouseY;
+
+	do {
+// TODO: Usage of checkKeys to be confirmed. A simple refresh of the mouse buttons is required
+		_vm->_game->checkKeys(&_vm->_global->_inter_mouseX, &_vm->_global->_inter_mouseY, &_vm->_game->_mouseButtons, 1);
+		if (_vm->_global->_inter_mouseX != _cursorX || _vm->_global->_inter_mouseY != _cursorY) {
+			if (_vm->_global->_inter_mouseX < minX) { 
+				_vm->_global->_inter_mouseX = minX;
+				if (_vm->_global->_mousePresent) 
+					_vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY); 
+			}
+			if (_vm->_global->_inter_mouseY < minY) { 
+				_vm->_global->_inter_mouseY = minY;
+				if (_vm->_global->_mousePresent) 
+					_vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY);
+			}
+			if (_vm->_global->_inter_mouseX + _fascinWin[id].width > maxX) {
+				_vm->_global->_inter_mouseX = maxX - _fascinWin[id].width;
+				if (_vm->_global->_mousePresent)
+					_vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY);
+			}
+			if (_vm->_global->_inter_mouseY + _fascinWin[id].height > maxY) {
+				_vm->_global->_inter_mouseY = maxY - _fascinWin[id].height;
+				if (_vm->_global->_mousePresent)
+					_vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY);
+			}
+			winTrace(_cursorX,_cursorY, _fascinWin[id].width, _fascinWin[id].height);
+			winTrace(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY, _fascinWin[id].width, _fascinWin[id].height);
+			_cursorX = _vm->_global->_inter_mouseX;
+			_cursorY = _vm->_global->_inter_mouseY;
+		}
+	} while (_vm->_game->_mouseButtons);
+	winTrace(_cursorX, _cursorY, _fascinWin[id].width, _fascinWin[id].height);
+	_cursorX = _vm->_global->_inter_mouseX;
+	_cursorY = _vm->_global->_inter_mouseY;
+}
+
+int16 Draw::handleCurWin() {
+	int8 i, matchNum;
+	int16 bestMatch = -1;
+
+	warning("handleCurWin");
+	if (_vm->_game->_mouseButtons != 1 || ((_vm->_draw->_renderFlags & 128) == 0))
+		return(0);
+	for (i = 0; i < 10; i++)
+		if (_fascinWin[i].id != -1)
+			if ((_vm->_global->_inter_mouseX >= _fascinWin[i].left) && 
+				(_vm->_global->_inter_mouseX <  _fascinWin[i].left + _fascinWin[i].width) && 
+				(_vm->_global->_inter_mouseY >= _fascinWin[i].top) && 
+				(_vm->_global->_inter_mouseY <  _fascinWin[i].top  + _fascinWin[i].height)) {
+				if (_fascinWin[i].id == _winCount - 1) {
+					if ((_vm->_global->_inter_mouseX < _fascinWin[i].left + 12) && 
+						(_vm->_global->_inter_mouseY < _fascinWin[i].top  + 12) && 
+						(VAR(_winVarArrayStatus / 4 + i) & 2)) {
+						blitCursor();
+						activeWin(i);
+						closeWin(i);
+						_vm->_util->waitMouseRelease(1);
+						return(i);
+					}
+					if ((_vm->_global->_inter_mouseX >= _fascinWin[i].left + _fascinWin[i].width - 12) && 
+						(_vm->_global->_inter_mouseY <  _fascinWin[i].top  + 12) && 
+						(VAR(_winVarArrayStatus / 4 + i) & 4) && 
+						(_vm->_global->_mousePresent) && 
+						(_vm->_global->_videoMode != 0x07)) {
+						blitCursor();
+						handleWinBorder(i);
+						winMove(i);
+						_vm->_global->_inter_mouseX = _fascinWin[i].left + _fascinWin[i].width - 12 + 1;
+						_vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY);
+						return(-i);
+					}
+					return(0);
+				} else
+					if (_fascinWin[i].id > bestMatch) {
+						bestMatch = _fascinWin[i].id;
+						matchNum = i;
+					}
+			}
+	if (bestMatch != -1) {
+		blitCursor();
+		activeWin(matchNum);
+	}
+	return(0);
+}
+
+void Draw::winDecomp(int16 x, int16 y, SurfaceDescPtr bmp) {
+// TODO: Implementation to be confirmed (used cut and paste from another part of the code)
+	Resource *resource;
+
+	resource = _vm->_game->_resources->getResource((uint16) _spriteLeft,
+		                                             &_spriteRight, &_spriteBottom);
+
+	if (!resource)
+		return;
+
+	_vm->_video->drawPackedSprite(resource->getData(),
+			_spriteRight, _spriteBottom, _destSpriteX, _destSpriteY,
+			_transparency, *_spritesArray[_destSurface]);
+
+	dirtiedRect(_destSurface, _destSpriteX, _destSpriteY,
+			_destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1);
+
+	delete resource;
+	return;
+}
+
+void Draw::winDraw(int16 fct) {
+ int16 left;
+ int16 top;
+ int16 width;
+ int16 height;
+
+ bool found = false;
+ int  i, j, k, l;
+ int len;
+ Resource *resource;
+ int table[10];
+ SurfaceDescPtr tempSrf;
+
+	if (_destSurface == 21) {
+		if (_vm->_global->_curWinId) {
+			if (_fascinWin[_vm->_global->_curWinId].id == -1)
+				return;
+			else {
+				_destSpriteX += _fascinWin[_vm->_global->_curWinId].left;
+				_destSpriteY += _fascinWin[_vm->_global->_curWinId].top;
+				if (fct == 3 || (fct >= 7 && fct <= 9)) {
+					_spriteRight  += _fascinWin[_vm->_global->_curWinId].left;
+					_spriteBottom += _fascinWin[_vm->_global->_curWinId].top;
+				}
+			}
+		}
+		left = _destSpriteX;
+		top = _destSpriteY;
+	} else {
+		if (_vm->_global->_curWinId) {
+			if (_fascinWin[_vm->_global->_curWinId].id == -1)
+				return;
+			else {
+				_spriteLeft += _fascinWin[_vm->_global->_curWinId].left;
+				_spriteTop  += _fascinWin[_vm->_global->_curWinId].top;
+			}
+		}
+		left = _spriteLeft;
+		top = _spriteTop;
+	}
+	for (i = 0; i < 10; i++) 
+		table[i] = 0;
+	switch (fct) {
+	case DRAW_BLITSURF:   // 0 - move
+	case DRAW_FILLRECT:   // 2 - fill rectangle 
+		width  = left + _spriteRight - 1;
+		height = top  + _spriteBottom - 1;
+		break;
+	case DRAW_PUTPIXEL:   // 1 - put a pixel
+		width  = _destSpriteX;
+		height = _destSpriteY;
+		break;
+	case DRAW_DRAWLINE:   // 3 - draw line
+	case DRAW_DRAWBAR:    // 7 - draw border
+	case DRAW_CLEARRECT:  // 8 - clear rectangle
+	case DRAW_FILLRECTABS:// 9 - fill rectangle, with other coordinates
+		width  = _spriteRight;
+		height = _spriteBottom;
+		break;
+	case DRAW_INVALIDATE: // 4 - Draw a circle
+		left   = _destSpriteX - _spriteRight;
+		top    = _destSpriteY - _spriteRight;
+		width  = _destSpriteX + _spriteRight;
+		height = _destSpriteY + _spriteBottom;
+		break;
+	case DRAW_LOADSPRITE: // 5 - Uncompress and load a sprite
+
+// TODO: check the implementation, currently dirty cut and paste of DRAW_SPRITE code
+		resource = _vm->_game->_resources->getResource((uint16) _spriteLeft,
+			                                             &_spriteRight, &_spriteBottom);
+
+		if (!resource)
+			break;
+
+		_vm->_video->drawPackedSprite(resource->getData(),
+				_spriteRight, _spriteBottom, _destSpriteX, _destSpriteY,
+				_transparency, *_spritesArray[_destSurface]);
+
+		dirtiedRect(_destSurface, _destSpriteX, _destSpriteY,
+				_destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1);
+
+		delete resource;
+
+		width  = _destSpriteX + _spriteRight - 1;
+		height = _destSpriteY + _spriteBottom - 1;
+		break;
+	case DRAW_PRINTTEXT:  // 6 - Display string
+		width  = _destSpriteX - 1 + strlen(_textToPrint) * _fonts[_fontIndex]->getCharWidth();
+		height = _destSpriteY - 1 + _fonts[_fontIndex]->getCharHeight();
+		break;
+	case DRAW_DRAWLETTER: // 10 - Display a character
+		if (_fontToSprite[_fontIndex].sprite == -1) {
+			width  = _destSpriteX - 1 + _fonts[_fontIndex]->getCharWidth();
+			height = _destSpriteY - 1 + _fonts[_fontIndex]->getCharHeight();
+		} else {
+			width  = _destSpriteX + _fontToSprite[_fontIndex].width - 1;
+			height = _destSpriteY + _fontToSprite[_fontIndex].height - 1;
+		}
+		break;
+	default:
+		warning("Unexpected fct value");
+		break;
+	}
+	for (i = 0; i < 10; i++)
+		if ((i != _vm->_global->_curWinId) && (_fascinWin[i].id != -1))
+			if (!_vm->_global->_curWinId || _fascinWin[i].id>_fascinWin[_vm->_global->_curWinId].id)
+				if ((_fascinWin[i].left + _fascinWin[i].width  > left) && (width  >= _fascinWin[i].left) && 
+					(_fascinWin[i].top  + _fascinWin[i].height > top ) && (height >= _fascinWin[i].top)) {
+					found = true;
+					table[_fascinWin[i].id] = i;
+				}
+	if ((_sourceSurface == 21) && (fct == 0)) {
+		_vm->_video->drawSprite(*_spritesArray[_sourceSurface], *_spritesArray[_destSurface],
+								 _spriteLeft, _spriteTop, _spriteLeft + _spriteRight - 1,
+								 _spriteTop + _spriteBottom - 1, _destSpriteX, _destSpriteY, _transparency);
+		if (!found)
+			return;
+		if (_vm->_global->_curWinId == 0) 
+			j = 0; 
+		else 
+			j = _fascinWin[_vm->_global->_curWinId].id + 1;
+		for (i = 9; i >= j; i--) {
+			if (table[i])
+				_vm->_video->drawSprite(*_fascinWin[table[i]].savedSurface, *_spritesArray[_destSurface],
+										 _fascinWin[table[i]].left & 15, 0,
+										(_fascinWin[table[i]].left & 15) + _fascinWin[table[i]].width - 1,
+										 _fascinWin[table[i]].height - 1, _fascinWin[table[i]].left - _spriteLeft + _destSpriteX,
+										 _fascinWin[table[i]].top - _spriteTop + _destSpriteY, 0);
+		}
+		return;
+	}
+	if (found) {
+		tempSrf = _vm->_video->initSurfDesc(_vm->_global->_videoMode, width - left + 1, height - top + 1, 0);
+		_vm->_video->drawSprite(*_backSurface, *tempSrf, left, top, width, height, 0, 0, 0);
+		if (_vm->_global->_curWinId == 0)
+			j = 0;
+		else 
+			j = _fascinWin[_vm->_global->_curWinId].id + 1;
+		for (i = 9; i >= j; i--) {
+			if (table[i])
+				_vm->_video->drawSprite(*_fascinWin[table[i]].savedSurface, *tempSrf,
+										 _fascinWin[table[i]].left & 15, 0,
+										(_fascinWin[table[i]].left & 15) + _fascinWin[table[i]].width - 1,
+										 _fascinWin[table[i]].height - 1,
+										 _fascinWin[table[i]].left  - left, 
+										 _fascinWin[table[i]].top   - top , 0);
+		}
+// Strangerke not sure concerning the use of _destSurface
+		dirtiedRect(_destSurface, left, top, width, height);
+		switch (fct) {
+		case DRAW_BLITSURF:   // 0 - move
+			_vm->_video->drawSprite(*_spritesArray[_sourceSurface], *tempSrf,
+									 _spriteLeft, _spriteTop, _spriteLeft + _spriteRight - 1,
+									 _spriteTop + _spriteBottom - 1, 0, 0, _transparency);
+			break;
+		case DRAW_PUTPIXEL:   // 1 - put a pixel
+			_vm->_video->putPixel(0, 0, _frontColor, *tempSrf);
+			break;
+		case DRAW_FILLRECT:   // 2 - fill rectangle 
+			_vm->_video->fillRect(*tempSrf, 0, 0, _spriteRight - 1, _spriteBottom - 1, _backColor);
+			break;
+		case DRAW_DRAWLINE:   // 3 - draw line
+			_vm->_video->drawLine(*tempSrf, 0, 0, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _frontColor);
+			break;
+		case DRAW_INVALIDATE: // 4 - Draw a circle
+			_vm->_video->drawCircle(*tempSrf, _spriteRight, _spriteRight, _spriteRight, _frontColor);
+			break;
+		case DRAW_LOADSPRITE: // 5 - Uncompress and load a sprite
+			winDecomp(0, 0, tempSrf);
+			break;
+		case DRAW_PRINTTEXT:  // 6 - Display string
+			len = strlen(_textToPrint);
+			for (j = 0; j < len; j++)
+				_vm->_video->drawLetter(_textToPrint[j], j * _fonts[_fontIndex]->getCharWidth(), 0, 
+										*_fonts[_fontIndex], _transparency, _frontColor, _backColor, *tempSrf);
+			_destSpriteX += len * _fonts[_fontIndex]->getCharWidth();
+			break;
+		case DRAW_DRAWBAR:    // 7 - draw border
+			_vm->_video->drawLine(*tempSrf, 0, _spriteBottom - _destSpriteY, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _frontColor);
+			_vm->_video->drawLine(*tempSrf, 0, 0, 0, _spriteBottom - _destSpriteY, _frontColor);
+			_vm->_video->drawLine(*tempSrf, _spriteRight - _destSpriteX, 0, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _frontColor);
+			_vm->_video->drawLine(*tempSrf, 0, 0, _spriteRight - _destSpriteX, 0, _frontColor);
+			break;
+		case DRAW_CLEARRECT:  // 8 - clear rectangle
+			if (_backColor < 16)
+				_vm->_video->fillRect(*tempSrf, 0, 0, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _backColor);
+			break;
+		case DRAW_FILLRECTABS:// 9 - fill rectangle, with other coordinates
+			_vm->_video->fillRect(*tempSrf, 0, 0, _spriteRight - _destSpriteX, _spriteBottom - _destSpriteY, _backColor);
+			break;
+		case DRAW_DRAWLETTER: // 10 - Display a character
+			if (_fontToSprite[_fontIndex].sprite == -1)
+				_vm->_video->drawLetter(_letterToPrint, 0, 0, *_fonts[_fontIndex], _transparency, _frontColor, _backColor, *tempSrf);
+			else {
+				int xx, yy, nn;
+				nn = _spritesArray[_fontToSprite[_fontIndex].sprite]->getWidth() / _fontToSprite[_fontIndex].width;
+				yy = ((_letterToPrint - _fontToSprite[_fontIndex].base) / nn) * _fontToSprite[_fontIndex].height;
+				xx = ((_letterToPrint - _fontToSprite[_fontIndex].base) % nn) * _fontToSprite[_fontIndex].width;
+				_vm->_video->drawSprite(*_spritesArray[_fontToSprite[_fontIndex].sprite], *tempSrf, 
+										 xx, yy, xx + _fontToSprite[_fontIndex].width - 1,
+										 yy + _fontToSprite[_fontIndex].height - 1, 0, 0, _transparency);
+			}
+			break;
+		default:
+			warning("Unexpected fct value");
+			break;
+		}
+		if (_vm->_global->_curWinId == 0)
+			i = 0; 
+		else 
+			i = _fascinWin[_vm->_global->_curWinId].id + 1;
+		for (;i < 10; i++) {
+			if (table[i]) {
+				k = table[i];
+				_vm->_video->drawSprite(*tempSrf, *_fascinWin[k].savedSurface,
+										0, 0, width - left, height - top,
+										left - _fascinWin[k].left + (_fascinWin[k].left & 15),
+										top  - _fascinWin[k].top, 0);
+// Shift skipped as always set to zero (?)
+				_vm->_video->drawSprite(*_frontSurface, *tempSrf,
+										MAX(left  , _fascinWin[k].left), 
+										MAX(top   , _fascinWin[k].top),
+										MIN(width , (int16) (_fascinWin[k].left + _fascinWin[k].width  - 1)),
+										MIN(height, (int16) (_fascinWin[k].top  + _fascinWin[k].height - 1)),
+										MAX(left  , _fascinWin[k].left) - left,
+										MAX(top   , _fascinWin[k].top)  - top, 0);
+				if (_cursorIndex != -1)
+					_vm->_video->drawSprite(*_cursorSpritesBack, *tempSrf, 
+											0, 0, _cursorWidth - 1, _cursorHeight - 1, 
+											_cursorX - left, _cursorY - top, 0);
+				for (j = 9; j > i; j--) {
+					if (table[j] && winOverlap(k, table[j])) {
+						l = table[j];
+						_vm->_video->drawSprite(*_fascinWin[l].savedSurface, *tempSrf,
+												MAX(_fascinWin[l].left, _fascinWin[k].left) 
+													- _fascinWin[l].left + (_fascinWin[l].left & 15),
+												MAX(_fascinWin[l].top , _fascinWin[k].top ) - _fascinWin[l].top,
+												MIN(_fascinWin[l].left + _fascinWin[l].width  - 1, _fascinWin[k].left + _fascinWin[k].width - 1)
+													- _fascinWin[l].left + (_fascinWin[l].left & 15),
+												MIN(_fascinWin[l].top  + _fascinWin[l].height - 1, _fascinWin[k].top  + _fascinWin[k].height - 1) 
+													- _fascinWin[l].top,
+												MAX(_fascinWin[l].left, _fascinWin[k].left) - left,
+												MAX(_fascinWin[l].top , _fascinWin[k].top ) - top, 0);
+					}
+				}
+			}
+		}
+		_vm->_video->drawSprite(*tempSrf, *_backSurface, 0, 0, width - left, height - top, left, top, 0);
+		tempSrf.reset();
+	} else {
+// Strangerke not sure concerning the use of _destSurface
+		dirtiedRect(_destSurface, left, top, width, height);
+		switch (fct) {
+		case DRAW_BLITSURF:   // 0 - move
+			_vm->_video->drawSprite(*_spritesArray[_sourceSurface], *_backSurface, 
+									 _spriteLeft, _spriteTop, 
+									 _spriteLeft + _spriteRight  - 1,
+									 _spriteTop  + _spriteBottom - 1,
+									 _destSpriteX, _destSpriteY, _transparency);
+			break;
+		case DRAW_PUTPIXEL:   // 1 - put a pixel
+			_vm->_video->putPixel(_destSpriteX, _destSpriteY, _frontColor, *_backSurface);
+			break;
+		case DRAW_FILLRECT:   // 2 - fill rectangle 
+			_vm->_video->fillRect(*_backSurface, _destSpriteX, _destSpriteY, _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1, _backColor);
+			break;
+		case DRAW_DRAWLINE:   // 3 - draw line
+			_vm->_video->drawLine(*_backSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _frontColor);
+			break;
+		case DRAW_INVALIDATE: // 4 - Draw a circle
+			_vm->_video->drawCircle(*_backSurface, _spriteRight, _spriteRight, _spriteRight, _frontColor);
+			break;
+		case DRAW_LOADSPRITE: // 5 - Uncompress and load a sprite
+			winDecomp(_destSpriteX, _destSpriteY, _backSurface);
+			break;
+		case DRAW_PRINTTEXT:  // 6 - Display string
+			len = strlen(_textToPrint);
+			for ( j = 0; j < len; j++)
+				_vm->_video->drawLetter(_textToPrint[j], _destSpriteX + j * _fonts[_fontIndex]->getCharWidth(),
+										_destSpriteY, *_fonts[_fontIndex], _transparency, _frontColor, _backColor, *_backSurface);
+				_destSpriteX += len * _fonts[_fontIndex]->getCharWidth();
+			break;
+		case DRAW_DRAWBAR:    // 7 - draw border
+			_vm->_video->drawLine(*_backSurface, _destSpriteX, _spriteBottom, _spriteRight, _spriteBottom, _frontColor);
+			_vm->_video->drawLine(*_backSurface, _destSpriteX, _destSpriteY,  _destSpriteX, _spriteBottom, _frontColor);
+			_vm->_video->drawLine(*_backSurface, _spriteRight, _destSpriteY,  _spriteRight, _spriteBottom, _frontColor);
+			_vm->_video->drawLine(*_backSurface, _destSpriteX, _destSpriteY,  _spriteRight, _destSpriteY,  _frontColor);
+			break;
+		case DRAW_CLEARRECT:  // 8 - clear rectangle
+		if (_backColor < 16)
+				_vm->_video->fillRect(*_backSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor);
+			break;
+		case DRAW_FILLRECTABS:// 9 - fill rectangle, with other coordinates
+			_vm->_video->fillRect(*_backSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor);
+			break;
+		case DRAW_DRAWLETTER: // 10 - Display a character
+			if (_fontToSprite[_fontIndex].sprite == -1)
+				_vm->_video->drawLetter(_letterToPrint, _destSpriteX, _destSpriteY, *_fonts[_fontIndex], _transparency, 
+										_frontColor, _backColor, *_spritesArray[_destSurface]);
+			else {
+				int xx, yy, nn;
+				nn = _spritesArray[_fontToSprite[_fontIndex].sprite]->getWidth() / _fontToSprite[_fontIndex].width;
+				yy = ((_letterToPrint - _fontToSprite[_fontIndex].base) / nn) * _fontToSprite[_fontIndex].height;
+				xx = ((_letterToPrint - _fontToSprite[_fontIndex].base) % nn) * _fontToSprite[_fontIndex].width;
+				_vm->_video->drawSprite(*_spritesArray[_fontToSprite[_fontIndex].sprite], *_spritesArray[_destSurface], 
+										xx, yy,
+										xx + _fontToSprite[_fontIndex].width  - 1,
+										yy + _fontToSprite[_fontIndex].height - 1,
+										_destSpriteX, _destSpriteY, _transparency);
+			}
+			break;
+		default:
+			warning("Unexpected fct value");
+			break;
+		}
+	}
+	if (_renderFlags & 16) {
+		if (_sourceSurface == 21) {
+			_spriteLeft -= _backDeltaX;
+			_spriteTop -= _backDeltaY;
+		}
+		if (_destSurface == 21) {
+			_destSpriteX -= _backDeltaX;
+			_destSpriteY -= _backDeltaY;
+		}
+	}
+	if (_vm->_global->_curWinId) {
+		_destSpriteX -= _fascinWin[_vm->_global->_curWinId].left;
+		_destSpriteY -= _fascinWin[_vm->_global->_curWinId].top;
+	}
+}
+
 int32 Draw::getSpriteRectSize(int16 index) {
 	if (!_spritesArray[index])
 		return 0;

Modified: scummvm/trunk/engines/gob/draw.h
===================================================================
--- scummvm/trunk/engines/gob/draw.h	2009-09-29 20:47:05 UTC (rev 44471)
+++ scummvm/trunk/engines/gob/draw.h	2009-09-29 22:43:30 UTC (rev 44472)
@@ -55,6 +55,15 @@
 		FontToSprite() : sprite(0), base(0), width(0), height(0) {}
 	};
 
+	struct fascinWin {
+		int16 id;
+		int16 left;
+		int16 top;
+		int16 width;
+		int16 height;
+		SurfaceDescPtr savedSurface;
+	};
+
 	int16 _renderFlags;
 
 	int16 _fontIndex;
@@ -73,6 +82,7 @@
 
 	char _letterToPrint;
 	const char *_textToPrint;
+	char *_hotspotText;
 
 	int16 _backDeltaX;
 	int16 _backDeltaY;
@@ -86,8 +96,8 @@
 	Common::Array<SurfaceDescPtr> _spritesArray;
 
 	int16 _invalidatedCount;
+	int16 _invalidatedLefts[30];
 	int16 _invalidatedTops[30];
-	int16 _invalidatedLefts[30];
 	int16 _invalidatedRights[30];
 	int16 _invalidatedBottoms[30];
 
@@ -140,6 +150,19 @@
 
 	int16 _pattern;
 
+	fascinWin _fascinWin[10];
+	int16 _winMaxWidth;
+	int16 _winMaxHeight;
+	int16 _winCount;
+	int16 _winVarArrayLeft;
+	int16 _winVarArrayTop;
+	int16 _winVarArrayWidth;
+	int16 _winVarArrayHeight;
+	int16 _winVarArrayStatus;
+	int16 _winVarArrayLimitsX;
+	int16 _winVarArrayLimitsY;	
+	
+
 	void invalidateRect(int16 left, int16 top, int16 right, int16 bottom);
 	void blitInvalidated();
 	void setPalette();
@@ -162,6 +185,21 @@
 			int16 transp, SurfaceDesc &dest, const Font &font);
 	void printTextCentered(int16 id, int16 left, int16 top, int16 right,
 			int16 bottom, const char *str, int16 fontIndex, int16 color);
+	void oPlaytoons_sub_F_1B( uint16 id, int16 left, int16 top, int16 right, int16 bottom, char *paramStr, int16 var3, int16 var4, int16 shortId);
+
+	int16 openWin(int16 id);
+	int16 handleCurWin();
+	bool winOverlap(int16 idWin1, int16 idWin2);
+	void winDecomp(int16 x, int16 y, SurfaceDescPtr bmp);
+	void activeWin(int16 id);
+	void closeWin(int16 id);
+	void restoreWin(int16 i);
+	void saveWin(int16 id);
+	void winMove(int16 id);
+	void handleWinBorder(int16 id);
+	void winDraw(int16 fct);
+	void winTrace(int16 left, int16 top, int16 width, int16 height);
+
 	int32 getSpriteRectSize(int16 index);
 	void forceBlit(bool backwards = false);
 
@@ -222,12 +260,11 @@
 	virtual ~Draw_Bargon() {}
 };
 
-class Draw_Fascin: public Draw_v2 {
+class Draw_Fascination: public Draw_v1 {
 public:
-	virtual void initScreen();
-
-	Draw_Fascin(GobEngine *vm);
-	virtual ~Draw_Fascin() {}
+	Draw_Fascination(GobEngine *vm);
+	virtual ~Draw_Fascination() {}
+	virtual void spriteOperation(int16 operation);
 };
 
 class Draw_Playtoons: public Draw_v2 {

Modified: scummvm/trunk/engines/gob/draw_fascin.cpp
===================================================================
--- scummvm/trunk/engines/gob/draw_fascin.cpp	2009-09-29 20:47:05 UTC (rev 44471)
+++ scummvm/trunk/engines/gob/draw_fascin.cpp	2009-09-29 22:43:30 UTC (rev 44472)
@@ -23,22 +23,231 @@
  *
  */
 
-#include "gob/gob.h"
+//#include "common/endian.h"
+//#include "graphics/cursorman.h"
+
 #include "gob/draw.h"
-#include "gob/global.h"
-#include "gob/video.h"
+#include "gob/game.h"
+#include "gob/resources.h"
 
 namespace Gob {
 
-Draw_Fascin::Draw_Fascin(GobEngine *vm) : Draw_v2(vm) {
+Draw_Fascination::Draw_Fascination(GobEngine *vm) : Draw_v1(vm) {
 }
 
-void Draw_Fascin::initScreen(void) {
-	_vm->_global->_videoMode = 0x14;
-	_vm->_video->_surfWidth = 640;
-	_vm->_video->initPrimary(_vm->_global->_videoMode);
+void Draw_Fascination::spriteOperation(int16 operation) {
+	int16 len;
+	int16 x, y;
+	int16 perLine;
+	Resource *resource;
 
-	Draw_v2::initScreen();
+	operation &= 0x0F;
+
+	if (_sourceSurface >= 100)
+		_sourceSurface -= 80;
+	if (_destSurface >= 100)
+		_destSurface -= 80;
+
+	if (_renderFlags & RENDERFLAG_USEDELTAS) {
+		if (_sourceSurface == 21) {
+			_spriteLeft += _backDeltaX;
+			_spriteTop += _backDeltaY;
+		}
+
+		if (_destSurface == 21) {
+			_destSpriteX += _backDeltaX;
+			_destSpriteY += _backDeltaY;
+			if ((operation == DRAW_DRAWLINE) ||
+			   ((operation >= DRAW_DRAWBAR) &&
+			    (operation <= DRAW_FILLRECTABS))) {
+				_spriteRight += _backDeltaX;
+				_spriteBottom += _backDeltaY;
+			}
+		}
+	}
+
+	if (_renderFlags & 0x20) {
+		if (_destSurface == 21 || (operation == 0 && _sourceSurface == 21)) {
+			winDraw(operation);
+			return; 
+		}
+	}
+	
+	Font *font = 0;
+	switch (operation) {
+	case DRAW_BLITSURF:
+		_vm->_video->drawSprite(*_spritesArray[_sourceSurface],
+		    *_spritesArray[_destSurface],
+		    _spriteLeft, _spriteTop,
+		    _spriteLeft + _spriteRight  - 1,
+		    _spriteTop  + _spriteBottom - 1,
+		    _destSpriteX, _destSpriteY, _transparency);
+
+		dirtiedRect(_destSurface, _destSpriteX, _destSpriteY,
+				_destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1);
+		break;
+
+	case DRAW_PUTPIXEL:
+		_vm->_video->putPixel(_destSpriteX, _destSpriteY,
+		    _frontColor, *_spritesArray[_destSurface]);
+
+		dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _destSpriteX, _destSpriteY);
+		break;
+
+	case DRAW_FILLRECT:
+		_vm->_video->fillRect(*_spritesArray[_destSurface],
+		    _destSpriteX, _destSpriteY,
+		    _destSpriteX + _spriteRight - 1,
+		    _destSpriteY + _spriteBottom - 1, _backColor);
+
+		dirtiedRect(_destSurface, _destSpriteX, _destSpriteY,
+				_destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1);
+		break;
+
+	case DRAW_DRAWLINE:
+		_vm->_video->drawLine(*_spritesArray[_destSurface],
+		    _destSpriteX, _destSpriteY,
+		    _spriteRight, _spriteBottom, _frontColor);
+
+		dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom);
+		break;
+
+	case DRAW_INVALIDATE:
+		dirtiedRect(_destSurface, _destSpriteX - _spriteRight, _destSpriteY - _spriteBottom,
+				_destSpriteX + _spriteRight, _destSpriteY + _spriteBottom);
+		break;
+
+	case DRAW_LOADSPRITE:
+		resource = _vm->_game->_resources->getResource((uint16) _spriteLeft,
+			                                             &_spriteRight, &_spriteBottom);
+
+		if (!resource)
+			break;
+
+		_vm->_video->drawPackedSprite(resource->getData(),
+				_spriteRight, _spriteBottom, _destSpriteX, _destSpriteY,
+				_transparency, *_spritesArray[_destSurface]);
+
+		dirtiedRect(_destSurface, _destSpriteX, _destSpriteY,
+				_destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1);
+
+		delete resource;
+		break;
+
+	case DRAW_PRINTTEXT:
+		font = _fonts[_fontIndex];
+		if (!font) {
+			warning("Trying to print \"%s\" with undefined font %d", _textToPrint, _fontIndex);
+			break;
+		}
+
+		len = strlen(_textToPrint);
+		dirtiedRect(_destSurface, _destSpriteX, _destSpriteY,
+				_destSpriteX + len * font->getCharWidth() - 1,
+				_destSpriteY + font->getCharHeight() - 1);
+
+		for (int i = 0; i < len; i++) {
+			_vm->_video->drawLetter(_textToPrint[i],
+			    _destSpriteX, _destSpriteY,
+			    *font, _transparency,
+			    _frontColor, _backColor,
+			    *_spritesArray[_destSurface]);
+
+			_destSpriteX += font->getCharWidth();
+		}
+		break;
+
+	case DRAW_DRAWBAR:
+		_vm->_video->drawLine(*_spritesArray[_destSurface],
+		    _destSpriteX, _spriteBottom,
+		    _spriteRight, _spriteBottom, _frontColor);
+
+		_vm->_video->drawLine(*_spritesArray[_destSurface],
+		    _destSpriteX, _destSpriteY,
+		    _destSpriteX, _spriteBottom, _frontColor);
+
+		_vm->_video->drawLine(*_spritesArray[_destSurface],
+		    _spriteRight, _destSpriteY,
+		    _spriteRight, _spriteBottom, _frontColor);
+
+		_vm->_video->drawLine(*_spritesArray[_destSurface],
+		    _destSpriteX, _destSpriteY,
+		    _spriteRight, _destSpriteY, _frontColor);
+
+		dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom);
+		break;
+
+	case DRAW_CLEARRECT:
+		if (_backColor < 16) {
+			_vm->_video->fillRect(*_spritesArray[_destSurface],
+			    _destSpriteX, _destSpriteY,
+			    _spriteRight, _spriteBottom,
+			    _backColor);
+		}
+		dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom);
+		break;
+
+	case DRAW_FILLRECTABS:
+		_vm->_video->fillRect(*_spritesArray[_destSurface],
+		    _destSpriteX, _destSpriteY,
+		    _spriteRight, _spriteBottom, _backColor);
+
+		dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom);
+		break;
+
+	case DRAW_DRAWLETTER:
+		font = _fonts[_fontIndex];
+		if (!font) {
+			warning("Trying to print \'%c\' with undefined font %d", _letterToPrint, _fontIndex);
+			break;
+		}
+
+		if (_fontToSprite[_fontIndex].sprite == -1) {
+			dirtiedRect(_destSurface, _destSpriteX, _destSpriteY,
+					_destSpriteX + font->getCharWidth()  - 1,
+					_destSpriteY + font->getCharHeight() - 1);
+			_vm->_video->drawLetter(_letterToPrint,
+			    _destSpriteX, _destSpriteY,
+			    *font, _transparency,
+			    _frontColor, _backColor,
+			    *_spritesArray[_destSurface]);
+			break;
+		}
+
+		perLine =
+			_spritesArray[(int16)_fontToSprite[_fontIndex].sprite]->getWidth() /
+			_fontToSprite[_fontIndex].width;
+
+		y = (_letterToPrint - _fontToSprite[_fontIndex].base) / perLine *
+			_fontToSprite[_fontIndex].height;
+
+		x = (_letterToPrint - _fontToSprite[_fontIndex].base) % perLine *
+			_fontToSprite[_fontIndex].width;
+
+		dirtiedRect(_destSurface, _destSpriteX, _destSpriteY,
+				_destSpriteX + _fontToSprite[_fontIndex].width,
+				_destSpriteY + _fontToSprite[_fontIndex].height);
+
+		_vm->_video->drawSprite(*_spritesArray[(int16)_fontToSprite[_fontIndex].sprite],
+		    *_spritesArray[_destSurface], x, y,
+		    x + _fontToSprite[_fontIndex].width,
+		    y + _fontToSprite[_fontIndex].height,
+		    _destSpriteX, _destSpriteY, _transparency);
+
+		break;
+	}
+
+	if (_renderFlags & RENDERFLAG_USEDELTAS) {
+		if (_sourceSurface == 21) {
+			_spriteLeft -= _backDeltaX;
+			_spriteTop -= _backDeltaY;
+		}
+
+		if (_destSurface == 21) {
+			_destSpriteX -= _backDeltaX;
+			_destSpriteY -= _backDeltaY;
+		}
+	}
 }
 
 } // End of namespace Gob

Modified: scummvm/trunk/engines/gob/global.cpp
===================================================================
--- scummvm/trunk/engines/gob/global.cpp	2009-09-29 20:47:05 UTC (rev 44471)
+++ scummvm/trunk/engines/gob/global.cpp	2009-09-29 22:43:30 UTC (rev 44472)
@@ -127,6 +127,8 @@
 	_doSubtitles = false;
 
 	_noCd = false;
+
+	_curWinId = 0;
 }
 
 Global::~Global() {

Modified: scummvm/trunk/engines/gob/global.h
===================================================================
--- scummvm/trunk/engines/gob/global.h	2009-09-29 20:47:05 UTC (rev 44471)
+++ scummvm/trunk/engines/gob/global.h	2009-09-29 22:43:30 UTC (rev 44472)
@@ -145,6 +145,8 @@
 
 	bool _noCd;
 
+	int16 _curWinId;
+
 	Global(GobEngine *vm);
 	~Global();
 

Modified: scummvm/trunk/engines/gob/gob.cpp
===================================================================
--- scummvm/trunk/engines/gob/gob.cpp	2009-09-29 20:47:05 UTC (rev 44471)
+++ scummvm/trunk/engines/gob/gob.cpp	2009-09-29 22:43:30 UTC (rev 44472)
@@ -362,7 +362,7 @@
 		_video    = new Video_v2(this);
 		_inter    = new Inter_Fascination(this);
 		_mult     = new Mult_v2(this);
-		_draw     = new Draw_v2(this);
+		_draw     = new Draw_Fascination(this);
 		_map      = new Map_v2(this);
 		_goblin   = new Goblin_v2(this);
 		_scenery  = new Scenery_v2(this);

Modified: scummvm/trunk/engines/gob/hotspots.cpp
===================================================================
--- scummvm/trunk/engines/gob/hotspots.cpp	2009-09-29 20:47:05 UTC (rev 44471)
+++ scummvm/trunk/engines/gob/hotspots.cpp	2009-09-29 22:43:30 UTC (rev 44472)
@@ -646,7 +646,6 @@
 			if (isValid(_currentKey, _currentId, _currentIndex))
 				enter(_currentIndex);
 		}
-
 		_vm->_draw->animateCursor(-1);
 	}
 
@@ -712,48 +711,59 @@
 
 			if (_vm->_game->_mouseButtons != kMouseButtonsNone) {
 				// Mouse button pressed
+				int i;
+				if (_vm->getGameType() == kGameTypeFascination)
+					i = _vm->_draw->handleCurWin();
+				else
+					i = 0;
+				if (!i) {
+					_vm->_draw->animateCursor(2);
+					if (delay > 0) {
+						// If a delay was requested, wait the specified time
+						_vm->_util->delay(delay);
+					} else if (handleMouse & 1)
+						_vm->_util->waitMouseRelease(1);
 
-				if (delay > 0) {
-					// If a delay was requested, wait the specified time
+					_vm->_draw->animateCursor(-1);
 
-					_vm->_draw->animateCursor(2);
-					_vm->_util->delay(delay);
-				} else if (handleMouse & 1)
-					_vm->_util->waitMouseRelease(1);
+					// Which region was clicked?
+					key = checkMouse(kTypeClick, id, index);
 
-				_vm->_draw->animateCursor(-1);
+					if ((key != 0) || (id != 0)) {
+						// Got a valid region
 
-				// Which region was clicked?
-				key = checkMouse(kTypeClick, id, index);
+						if ( (handleMouse & 1) &&
+							  ((delay <= 0) || (_vm->_game->_mouseButtons == kMouseButtonsNone)))
+							_vm->_draw->blitCursor();
 
-				if ((key != 0) || (id != 0)) {
-					// Got a valid region
+						// If the hotspot changed, leave the old one
+						if (key != _currentKey)
+							leave(_currentIndex);
 
-					if ( (handleMouse & 1) &&
-						  ((delay <= 0) || (_vm->_game->_mouseButtons == kMouseButtonsNone)))
-						_vm->_draw->blitCursor();
+						_currentKey = 0;
+						break;
+					}
 
-					// If the hotspot changed, leave the old one
-					if (key != _currentKey)
+					if (handleMouse & 4)
+						// Nothing further than one simple check was requested => return
+						return 0;
+
+					// Leave the current area
+					if (_currentKey != 0)
 						leave(_currentIndex);
 
-					_currentKey = 0;
-					break;
+					// No click, but do we have a move event? If so, enter that hotspot
+					_currentKey = checkMouse(kTypeMove, _currentId, _currentIndex);
+					if (isValid(_currentKey, _currentId, _currentIndex))
+						enter(_currentIndex);
+				} else {
+					WRITE_VAR(16, (int32) i);
+					if (id) 
+						id=0;
+					if (index) 
+						index=0;
+					return(0);
 				}
-
-				if (handleMouse & 4)
-					// Nothing further than one simple check was requested => return
-					return 0;
-
-				// Leave the current area
-				if (_currentKey != 0)
-					leave(_currentIndex);
-
-				// No click, but do we have a move event? If so, enter that hotspot
-				_currentKey = checkMouse(kTypeMove, _currentId, _currentIndex);
-				if (isValid(_currentKey, _currentId, _currentIndex))
-					enter(_currentIndex);
-
 			} else
 				// No mouse button pressed, check whether the position changed at least
 				checkHotspotChanged();
@@ -1180,6 +1190,30 @@
 		width   = _vm->_game->_script->readUint16();
 		height  = _vm->_game->_script->readUint16();
 	}
+	if (_vm->_draw->_renderFlags & 64) {
+		warning("_renderFlags check added for Fascination");
+		_vm->_draw->_invalidatedTops[0] = 0;
+		_vm->_draw->_invalidatedLefts[0] = 0;
+		_vm->_draw->_invalidatedRights[0] = 319;
+		_vm->_draw->_invalidatedBottoms[0] = 199;
+		_vm->_draw->_invalidatedCount = 1;
+		if (window == 0) {
+			_vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left + width - 1, top, left + width - 1, top + height - 1, 0);
+			_vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left, top, left, top + height - 1, 0);
+			_vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left, top, left + width - 1, top, 0);
+			_vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left, top + height - 1, left + width - 1, top + height - 1, 0);
+		} else
+			if ((_vm->_draw->_fascinWin[window].id != -1) && (_vm->_draw->_fascinWin[window].id == _vm->_draw->_winCount - 1)) {
+				left += _vm->_draw->_fascinWin[window].left;
+				top  += _vm->_draw->_fascinWin[window].top;
+				_vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left + width - 1, top, left + width - 1, top + height - 1, 0);
+				_vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left, top, left, top + height - 1, 0);
+				_vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left, top, left + width - 1, top, 0);
+				_vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left, top + height - 1, left + width - 1, top + height - 1, 0);
+				left -= _vm->_draw->_fascinWin[window].left;
+				top  -= _vm->_draw->_fascinWin[window].top;
+			}
+	}
 	type &= 0x7F;
 
 	// Apply global drawing offset
@@ -1569,7 +1603,7 @@
 	int16 shortId;
 	int16 longId;
 	int16 var2;
-	int16 var3;
+	int16 fontIndex;
 	int16 var4;
 
 	uint16 left;
@@ -1582,7 +1616,7 @@
 
 	_vm->_game->_script->evalExpr(0);
 
-	var3 = _vm->_game->_script->readValExpr();
+	fontIndex = _vm->_game->_script->readValExpr();
 	var4 = _vm->_game->_script->readValExpr();
 
 //  this variable is always set to 0 in Playtoons
@@ -1595,8 +1629,7 @@
 		if ((_hotspots[i].id == 0xD000 + shortId) || (_hotspots[i].id == 0xB000 + shortId) || 
 			(_hotspots[i].id == 0x4000 + shortId)) {
 			longId = _hotspots[i].id;
-			warning("oPlaytoons_F_1B not fully handled");
-			warning("shortId %d, var2 %d var3 %d var4 %d", shortId, var2, var3, var4);
+			warning("oPlaytoons_F_1B: shortId %d, var2 %d fontIndex %d var4 %d - longId %d", shortId, var2, fontIndex, var4, longId);
 			
 			left = _hotspots[i].left;
 			top = _hotspots[i].top;
@@ -1613,7 +1646,8 @@
 				right -= 2;
 				bottom -= 2;
 			}
-			oPlaytoons_sub_F_1B(0x8000 + var2, left, top, right, bottom, _vm->_game->_script->getResultStr(), var3, var4, shortId);
+//			oPlaytoons_sub_F_1B(0x8000 + var2, left, top, right, bottom, _vm->_game->_script->getResultStr(), var3, var4, shortId);
+			_vm->_draw->oPlaytoons_sub_F_1B(0x8000+ var2, left, top, right, bottom, _vm->_game->_script->getResultStr(), fontIndex, var4, shortId);
 			return;
 		}
 	}
@@ -2030,17 +2064,4 @@
 		input++;
 	}
 }
-
-void Hotspots::oPlaytoons_sub_F_1B( uint16 id, int16 left, int16 top, int16 right, int16 bottom, char *paramStr, int16 var3, int16 var4, int16 shortId)
-{
-	char tmpStr[128];
-
-	strcpy( tmpStr, paramStr);
-	_vm->_draw->adjustCoords(1, &left, &right);
-	_vm->_draw->adjustCoords(1, &top,  &bottom);
-
-	warning("oPlaytoons_sub_F_1B display string %s", paramStr);
-	return;
-}
-
 } // End of namespace Gob

Modified: scummvm/trunk/engines/gob/hotspots.h
===================================================================
--- scummvm/trunk/engines/gob/hotspots.h	2009-09-29 20:47:05 UTC (rev 44471)
+++ scummvm/trunk/engines/gob/hotspots.h	2009-09-29 22:43:30 UTC (rev 44472)
@@ -269,8 +269,6 @@
 
 	/** Go through all inputs we manage and redraw their texts. */
 	void updateAllTexts(const InputDesc *inputs) const;
-
-	void oPlaytoons_sub_F_1B( uint16 id, int16 left, int16 top, int16 right, int16 bottom, char *str, int16 var3, int16 var4, int16 shortId);
 };
 
 } // End of namespace Gob

Modified: scummvm/trunk/engines/gob/init.cpp
===================================================================
--- scummvm/trunk/engines/gob/init.cpp	2009-09-29 20:47:05 UTC (rev 44471)
+++ scummvm/trunk/engines/gob/init.cpp	2009-09-29 22:43:30 UTC (rev 44472)
@@ -113,6 +113,11 @@
 	_palDesc->unused2 = _vm->_draw->_unusedPalette2;
 	_vm->_video->setFullPalette(_palDesc);
 
+	for (int i = 0; i < 10; i++)
+		_vm->_draw->_fascinWin[i].id = -1;
+
+	_vm->_draw->_winCount = 0;
+
 	for (int i = 0; i < 8; i++)
 		_vm->_draw->_fonts[i] = 0;
 

Modified: scummvm/trunk/engines/gob/init.h
===================================================================
--- scummvm/trunk/engines/gob/init.h	2009-09-29 20:47:05 UTC (rev 44471)
+++ scummvm/trunk/engines/gob/init.h	2009-09-29 22:43:30 UTC (rev 44472)
@@ -90,6 +90,13 @@
 	void initGame();
 };
 
+class Init_Fascination : public Init_v2 {
+public:
+	Init_Fascination(GobEngine *vm);
+	~Init_Fascination();
+
+	void initGame();
+};
 } // End of namespace Gob
 
 #endif // GOB_INIT_H

Modified: scummvm/trunk/engines/gob/inter.h
===================================================================
--- scummvm/trunk/engines/gob/inter.h	2009-09-29 20:47:05 UTC (rev 44471)
+++ scummvm/trunk/engines/gob/inter.h	2009-09-29 22:43:30 UTC (rev 44472)
@@ -432,29 +432,29 @@
 
 	void oFascin_playProtracker(OpGobParams &params);
 
-	void oFascin_geUnknown0(OpGobParams &params);
-	void oFascin_geUnknown1(OpGobParams &params);
-	void oFascin_geUnknown2(OpGobParams &params);
-	void oFascin_geUnknown3(OpGobParams &params);
-	void oFascin_geUnknown4(OpGobParams &params);
-	void oFascin_geUnknown5(OpGobParams &params);
-	void oFascin_geUnknown6(OpGobParams &params);
-	void oFascin_geUnknown7(OpGobParams &params);
-	void oFascin_geUnknown8(OpGobParams &params);
-	void oFascin_geUnknown9(OpGobParams &params);
-	void oFascin_geUnknown10(OpGobParams &params);
-	void oFascin_geUnknown11(OpGobParams &params);
+	void oFascin_playTirb(OpGobParams &params);
+	void oFascin_playTira(OpGobParams &params);
+	void oFascin_loadExtasy(OpGobParams &params);
+	void oFascin_adlibPlay(OpGobParams &params);
+	void oFascin_adlibStop(OpGobParams &params);
+	void oFascin_adlibUnload(OpGobParams &params);
+	void oFascin_loadMus1(OpGobParams &params);
+	void oFascin_loadMus2(OpGobParams &params);
+	void oFascin_loadMus3(OpGobParams &params);
+	void oFascin_loadBatt1(OpGobParams &params);
+	void oFascin_loadBatt2(OpGobParams &params);
+	void oFascin_loadBatt3(OpGobParams &params);
 	void oFascin_geUnknown1000(OpGobParams &params);
 	void oFascin_geUnknown1001(OpGobParams &params);
 	void oFascin_geUnknown1002(OpGobParams &params);
 	bool oFascin_feUnknown4(OpFuncParams &params);
 	bool oFascin_feUnknown27(OpFuncParams &params);
-	void oFascin_cdUnknown3();
-	void oFascin_cdUnknown4();
-	void oFascin_cdUnknown5();
-	void oFascin_cdUnknown6();
+	void oFascin_setWinSize();
+	void oFascin_closeWin();
+	void oFascin_activeWin();
+	void oFascin_openWin();
 	void oFascin_setRenderFlags();
-	void oFascin_cdUnknown11();
+	void oFascin_setWinFlags();
 };
 
 class Inter_v3 : public Inter_v2 {

Modified: scummvm/trunk/engines/gob/inter_fascin.cpp
===================================================================
--- scummvm/trunk/engines/gob/inter_fascin.cpp	2009-09-29 20:47:05 UTC (rev 44471)
+++ scummvm/trunk/engines/gob/inter_fascin.cpp	2009-09-29 22:43:30 UTC (rev 44472)
@@ -51,14 +51,13 @@
 void Inter_Fascination::setupOpcodesDraw() {
 	Inter_v2::setupOpcodesDraw();
 
-	OPCODEDRAW(0x03, oFascin_cdUnknown3);
+	OPCODEDRAW(0x03, oFascin_setWinSize);
+	OPCODEDRAW(0x04, oFascin_closeWin);
+	OPCODEDRAW(0x05, oFascin_activeWin);
+	OPCODEDRAW(0x06, oFascin_openWin);
 
-	OPCODEDRAW(0x04, oFascin_cdUnknown4);
-	OPCODEDRAW(0x05, oFascin_cdUnknown5);
-	OPCODEDRAW(0x06, oFascin_cdUnknown6);
-
 	OPCODEDRAW(0x0A, oFascin_setRenderFlags);
-	OPCODEDRAW(0x0B, oFascin_cdUnknown11);
+	OPCODEDRAW(0x0B, oFascin_setWinFlags);
 
 	CLEAROPCODEDRAW(0x50);
 	CLEAROPCODEDRAW(0x51);
@@ -89,27 +88,27 @@
 }
 
 void Inter_Fascination::setupOpcodesGob() {
-	OPCODEGOB(   1, oFascin_geUnknown0);
-	OPCODEGOB(   2, oFascin_geUnknown1);
-	OPCODEGOB(   3, oFascin_geUnknown2);
-	OPCODEGOB(   4, oFascin_geUnknown3);
+	OPCODEGOB(   1, oFascin_playTirb);
+	OPCODEGOB(   2, oFascin_playTira);
+	OPCODEGOB(   3, oFascin_loadExtasy);
+	OPCODEGOB(   4, oFascin_adlibPlay);
 
-	OPCODEGOB(   5, oFascin_geUnknown4);
-	OPCODEGOB(   6, oFascin_geUnknown5);
-	OPCODEGOB(   7, oFascin_geUnknown6);
-	OPCODEGOB(   8, oFascin_geUnknown7);
+	OPCODEGOB(   5, oFascin_adlibStop);
+	OPCODEGOB(   6, oFascin_adlibUnload);
+	OPCODEGOB(   7, oFascin_loadMus1);
+	OPCODEGOB(   8, oFascin_loadMus2);
 
-	OPCODEGOB(   9, oFascin_geUnknown8);
-	OPCODEGOB(  10, oFascin_geUnknown9);
-	OPCODEGOB(  11, oFascin_geUnknown10);
-	OPCODEGOB(  12, oFascin_geUnknown11);
+	OPCODEGOB(   9, oFascin_loadMus3);
+	OPCODEGOB(  10, oFascin_loadBatt1);
+	OPCODEGOB(  11, oFascin_loadBatt2);
+	OPCODEGOB(  12, oFascin_loadBatt3);
 
 	OPCODEGOB(1000, oFascin_geUnknown1000);
 	OPCODEGOB(1001, oFascin_geUnknown1001); //protrackerPlay doesn't play correctly "mod.extasy"
 	OPCODEGOB(1002, oFascin_geUnknown1002); //to be replaced by o2_stopProtracker when protrackerPlay is fixed
 }
 
-void Inter_Fascination::oFascin_geUnknown0(OpGobParams &params) {
+void Inter_Fascination::oFascin_playTirb(OpGobParams &params) {
 	warning("Fascination Unknown GE Function 0");
 	warning("funcPlayImd with parameter : 'tirb.imd'");
 
@@ -120,7 +119,7 @@
 	_vm->_draw->closeScreen();
 }
 
-void Inter_Fascination::oFascin_geUnknown1(OpGobParams &params) {
+void Inter_Fascination::oFascin_playTira(OpGobParams &params) {
 	warning("Fascination Unknown GE Function 1");
 	warning("funcPlayImd with parameter : 'tira.imd'");
 	if (_vm->_vidPlayer->primaryOpen("tira.imd")) {
@@ -130,49 +129,49 @@
 	_vm->_draw->closeScreen();
 }
 
-void Inter_Fascination::oFascin_geUnknown2(OpGobParams &params) {
+void Inter_Fascination::oFascin_loadExtasy(OpGobParams &params) {
 	_vm->_sound->adlibLoadTBR("extasy.tbr");
 	_vm->_sound->adlibLoadMDY("extasy.mdy");
 }
 
-void Inter_Fascination::oFascin_geUnknown3(OpGobParams &params) {
+void Inter_Fascination::oFascin_adlibPlay(OpGobParams &params) {
 	_vm->_sound->adlibPlay();
 }
 
-void Inter_Fascination::oFascin_geUnknown4(OpGobParams &params) {
+void Inter_Fascination::oFascin_adlibStop(OpGobParams &params) {
 	_vm->_sound->adlibStop();
 }
 
-void Inter_Fascination::oFascin_geUnknown5(OpGobParams &params) {
+void Inter_Fascination::oFascin_adlibUnload(OpGobParams &params) {
 	_vm->_sound->adlibUnload();
 }
 
-void Inter_Fascination::oFascin_geUnknown6(OpGobParams &params) {
+void Inter_Fascination::oFascin_loadMus1(OpGobParams &params) {
 	_vm->_sound->adlibLoadTBR("music1.tbr");
 	_vm->_sound->adlibLoadMDY("music1.mdy");
 }
 
-void Inter_Fascination::oFascin_geUnknown7(OpGobParams &params) {
+void Inter_Fascination::oFascin_loadMus2(OpGobParams &params) {
 	_vm->_sound->adlibLoadTBR("music2.tbr");
 	_vm->_sound->adlibLoadMDY("music2.mdy");
 }
 
-void Inter_Fascination::oFascin_geUnknown8(OpGobParams &params) {
+void Inter_Fascination::oFascin_loadMus3(OpGobParams &params) {
 	_vm->_sound->adlibLoadTBR("music3.tbr");
 	_vm->_sound->adlibLoadMDY("music3.mdy");
 }
 
-void Inter_Fascination::oFascin_geUnknown9(OpGobParams &params) {
+void Inter_Fascination::oFascin_loadBatt1(OpGobParams &params) {
 	_vm->_sound->adlibLoadTBR("batt1.tbr");
 	_vm->_sound->adlibLoadMDY("batt1.mdy");
 }
 
-void Inter_Fascination::oFascin_geUnknown10(OpGobParams &params) {
+void Inter_Fascination::oFascin_loadBatt2(OpGobParams &params) {
 	_vm->_sound->adlibLoadTBR("batt2.tbr");
 	_vm->_sound->adlibLoadMDY("batt2.mdy");
 }
 
-void Inter_Fascination::oFascin_geUnknown11(OpGobParams &params) {
+void Inter_Fascination::oFascin_loadBatt3(OpGobParams &params) {
 	_vm->_sound->adlibLoadTBR("batt3.tbr");
 	_vm->_sound->adlibLoadMDY("batt3.mdy");
 }
@@ -199,59 +198,58 @@
 	return true;
 }
 
-void Inter_Fascination::oFascin_cdUnknown3() {
-	uint16 resVar, resVar2;
-	int16 retVal1, retVal2, retVal3, retVal4, retVal5, retVal6, retVal7;
-
-	warning("Fascination oFascin_cdUnknown3 - Variables initialisations");
-
-	resVar = _vm->_game->_script->readUint16();
-	resVar2 = _vm->_game->_script->readUint16();
-	retVal1 = _vm->_game->_script->readVarIndex();
-	retVal2 = _vm->_game->_script->readVarIndex();
-	retVal3 = _vm->_game->_script->readVarIndex();
-	retVal4 = _vm->_game->_script->readVarIndex();
-	retVal5 = _vm->_game->_script->readVarIndex();
-	retVal6 = _vm->_game->_script->readVarIndex();
-	retVal7 = _vm->_game->_script->readVarIndex();
-	warning ("Width? :%d Height? :%d",resVar, resVar2);
-	warning ("Fetched variables 1:%d 2:%d 3:%d 4:%d 5:%d 6:%d 7:%d", retVal1, retVal2, retVal3, retVal4, retVal5, retVal6, retVal7);
+void Inter_Fascination::oFascin_setWinSize() {
+	_vm->_draw->_winMaxWidth  = _vm->_game->_script->readUint16();
+	_vm->_draw->_winMaxHeight = _vm->_game->_script->readUint16();
+	_vm->_draw->_winVarArrayLeft   = _vm->_game->_script->readVarIndex();
+	_vm->_draw->_winVarArrayTop    = _vm->_game->_script->readVarIndex();
+	_vm->_draw->_winVarArrayWidth  = _vm->_game->_script->readVarIndex();
+	_vm->_draw->_winVarArrayHeight = _vm->_game->_script->readVarIndex();
+	_vm->_draw->_winVarArrayStatus = _vm->_game->_script->readVarIndex();
+	_vm->_draw->_winVarArrayLimitsX = _vm->_game->_script->readVarIndex();
+	_vm->_draw->_winVarArrayLimitsY = _vm->_game->_script->readVarIndex();
+	warning("Inter_Fascination::oFascin_setWinSize lmax %d hmax %d x %d y %d l %d h %d stat %d limx %d limy %d",
+			 _vm->_draw->_winMaxWidth, _vm->_draw->_winMaxHeight,
+			 _vm->_draw->_winVarArrayLeft,  _vm->_draw->_winVarArrayTop,
+			 _vm->_draw->_winVarArrayWidth, _vm->_draw->_winVarArrayHeight, _vm->_draw->_winVarArrayStatus, 
+			 _vm->_draw->_winVarArrayLimitsX, _vm->_draw->_winVarArrayLimitsY);
 }
 
-void Inter_Fascination::oFascin_cdUnknown4() {
-	int16 expr;
-	warning("Fascination oFascin_cdUnknown4");
-	_vm->_game->_script->evalExpr(&expr);
-	warning ("_vm->_game->_script->evalExpr: %d, the rest is not yet implemented",expr);
+void Inter_Fascination::oFascin_closeWin() {
+	int16 id;
+	_vm->_game->_script->evalExpr(&id);
+	warning("Inter_Fascination::closeWin id %d", id);
+	_vm->_draw->activeWin(id);
+	_vm->_draw->closeWin(id);	
 }
 
-void Inter_Fascination::oFascin_cdUnknown5() {
-	int16 retVal1,expr;
-	warning("Fascination oFascin_cdUnknown5");
-	_vm->_game->_script->evalExpr(&expr);
-	retVal1 = _vm->_game->_script->readVarIndex();
-	warning ("_vm->_game->_script->evalExpr: %d Variable index %d, the rest is not yet implemented",expr, retVal1);
+void Inter_Fascination::oFascin_activeWin() {
+	int16 id;
+	_vm->_game->_script->evalExpr(&id);
+	warning("Inter_Fascination::activeWin id %d", id);
+	_vm->_draw->activeWin(id);
 }
 
-void Inter_Fascination::oFascin_cdUnknown6() {
-	int16 retVal1,expr;
-	warning("Fascination oFascin_cdUnknown6");
-	_vm->_game->_script->evalExpr(&expr);
-	retVal1 = _vm->_game->_script->readVarIndex();
-	warning ("_vm->_game->_script->evalExpr: %d Variable index %d, the rest is not yet implemented",expr, retVal1);
+void Inter_Fascination::oFascin_openWin() {
+	int16 retVal,id;
+	_vm->_game->_script->evalExpr(&id);
+	retVal = _vm->_game->_script->readVarIndex();
+	warning("Inter_Fascination::openWin index %d, id %d", retVal, id);
+	WRITE_VAR((retVal / 4), (int32) _vm->_draw->openWin(id));
 }
 
 void Inter_Fascination::oFascin_setRenderFlags() {
 	int16 expr;
-//	warning("Fascination oFascin_cdUnknown10 (set render flags)");
 	_vm->_game->_script->evalExpr(&expr);
-	warning("_draw_renderFlags <- %d",expr);
 	_vm->_draw->_renderFlags = expr;
+	warning("Inter_Fascination::oFascin_setRenderFlags: _draw_renderFlags <- %d",expr);
 }
 
-void Inter_Fascination::oFascin_cdUnknown11() {
-//	warning("Fascination oFascin_cdUnknown11 (set variable)");
-	_vm->_game->_script->evalExpr(0);
+void Inter_Fascination::oFascin_setWinFlags() {
+	int16 expr;
+	_vm->_game->_script->evalExpr(&expr);
+	_vm->_global->_curWinId = expr;
+	warning("Inter_Fascination::oFascin_setWinFlags: _global_DEVwnd <- %d",expr);
 }
 
 void Inter_Fascination::oFascin_playProtracker(OpGobParams &params) {

Modified: scummvm/trunk/engines/gob/inter_playtoons.cpp
===================================================================
--- scummvm/trunk/engines/gob/inter_playtoons.cpp	2009-09-29 20:47:05 UTC (rev 44471)
+++ scummvm/trunk/engines/gob/inter_playtoons.cpp	2009-09-29 22:43:30 UTC (rev 44472)
@@ -380,6 +380,7 @@
 		warning("oPlaytoons_getObjAnimSize case -2 not implemented");
 		return;
 	}
+
 	if ((objIndex < 0) || (objIndex >= _vm->_mult->_objCount)) {
 		warning("oPlaytoons_getObjAnimSize(): objIndex = %d (%d)", objIndex, _vm->_mult->_objCount);
 		_vm->_scenery->_toRedrawLeft   = 0;

Modified: scummvm/trunk/engines/gob/inter_v3.cpp
===================================================================
--- scummvm/trunk/engines/gob/inter_v3.cpp	2009-09-29 20:47:05 UTC (rev 44471)
+++ scummvm/trunk/engines/gob/inter_v3.cpp	2009-09-29 22:43:30 UTC (rev 44472)
@@ -80,6 +80,11 @@
 	part = _vm->_game->_script->readValExpr();
 
 	stringVar = stringStartVar;
+	if (part == -1) {
+		warning("o3_getTotTextItemPart, part == -1");
+		_vm->_draw->_hotspotText = GET_VARO_STR(stringVar);
+	}
+
 	WRITE_VARO_UINT8(stringVar, 0);
 
 	TextItem *textItem = _vm->_game->_resources->getTextItem(totTextItem);


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