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

drmccoy at users.sourceforge.net drmccoy at users.sourceforge.net
Sun Nov 19 18:52:52 CET 2006


Revision: 24745
          http://svn.sourceforge.net/scummvm/?rev=24745&view=rev
Author:   drmccoy
Date:     2006-11-19 09:52:52 -0800 (Sun, 19 Nov 2006)

Log Message:
-----------
Implemented (currently still endian-unsafe) save/load

Modified Paths:
--------------
    scummvm/trunk/engines/gob/draw.cpp
    scummvm/trunk/engines/gob/draw.h
    scummvm/trunk/engines/gob/game.cpp
    scummvm/trunk/engines/gob/game.h
    scummvm/trunk/engines/gob/game_v1.cpp
    scummvm/trunk/engines/gob/game_v2.cpp
    scummvm/trunk/engines/gob/gob.cpp
    scummvm/trunk/engines/gob/gob.h
    scummvm/trunk/engines/gob/inter.h
    scummvm/trunk/engines/gob/inter_v2.cpp

Modified: scummvm/trunk/engines/gob/draw.cpp
===================================================================
--- scummvm/trunk/engines/gob/draw.cpp	2006-11-19 02:24:38 UTC (rev 24744)
+++ scummvm/trunk/engines/gob/draw.cpp	2006-11-19 17:52:52 UTC (rev 24745)
@@ -544,4 +544,12 @@
 	spriteOperation(DRAW_PRINTTEXT);
 }
 
+int32 Draw::getSpriteRectSize(int16 index) {
+	if (_spritesArray[index] == 0)
+		return 0;
+
+	return _vm->_video->getRectSize(_spritesArray[index]->width, _spritesArray[index]->height,
+			0, _vm->_global->_videoMode);
+}
+
 } // End of namespace Gob

Modified: scummvm/trunk/engines/gob/draw.h
===================================================================
--- scummvm/trunk/engines/gob/draw.h	2006-11-19 02:24:38 UTC (rev 24744)
+++ scummvm/trunk/engines/gob/draw.h	2006-11-19 17:52:52 UTC (rev 24745)
@@ -135,6 +135,7 @@
 		int16 transp, Video::SurfaceDesc *dest, Video::FontDesc *font);
 	void printTextCentered(int16 arg_0, int16 left, int16 top, int16 right,
 			int16 bottom, char *str, int16 fontIndex, int16 color);
+	int32 getSpriteRectSize(int16 index);
 
 	virtual void initBigSprite(int16 index, int16 width, int16 height, int16 flags) = 0;
 	virtual void printText(void) = 0;

Modified: scummvm/trunk/engines/gob/game.cpp
===================================================================
--- scummvm/trunk/engines/gob/game.cpp	2006-11-19 02:24:38 UTC (rev 24744)
+++ scummvm/trunk/engines/gob/game.cpp	2006-11-19 17:52:52 UTC (rev 24745)
@@ -363,239 +363,6 @@
 	}
 }
 
-int16 Game::inputArea(int16 xPos, int16 yPos, int16 width, int16 height, int16 backColor,
-	    int16 frontColor, char *str, int16 fontIndex, char inpType, int16 *pTotTime) {
-	int16 handleMouse;
-	uint32 editSize;
-	Video::FontDesc *pFont;
-	char curSym;
-	int16 key;
-	const char *str1;
-	const char *str2;
-	int16 i;
-	uint32 pos;
-	int16 flag;
-	int16 savedKey;
-
-	if (_handleMouse != 0 &&
-	    (_vm->_global->_useMouse != 0 || _forceHandleMouse != 0))
-		handleMouse = 1;
-	else
-		handleMouse = 0;
-
-	pos = strlen(str);
-	pFont = _vm->_draw->_fonts[fontIndex];
-	editSize = width / pFont->itemWidth;
-
-	while (1) {
-		strcpy(_tempStr, str);
-		strcat(_tempStr, " ");
-		if (strlen(_tempStr) > editSize)
-			strcpy(_tempStr, str);
-
-		_vm->_draw->_destSpriteX = xPos;
-		_vm->_draw->_destSpriteY = yPos;
-		_vm->_draw->_spriteRight = editSize * pFont->itemWidth;
-		_vm->_draw->_spriteBottom = height;
-
-		_vm->_draw->_destSurface = 21;
-		_vm->_draw->_backColor = backColor;
-		_vm->_draw->_frontColor = frontColor;
-		_vm->_draw->_textToPrint = _tempStr;
-		_vm->_draw->_transparency = 1;
-		_vm->_draw->_fontIndex = fontIndex;
-		_vm->_draw->spriteOperation(DRAW_FILLRECT);
-
-		_vm->_draw->_destSpriteY = yPos + (height - 8) / 2;
-
-		_vm->_draw->spriteOperation(DRAW_PRINTTEXT);
-		if (pos == editSize)
-			pos--;
-
-		curSym = _tempStr[pos];
-
-		flag = 1;
-
-		while (1) {
-			_tempStr[0] = curSym;
-			_tempStr[1] = 0;
-
-			_vm->_draw->_destSpriteX = xPos + pFont->itemWidth * pos;
-			_vm->_draw->_destSpriteY = yPos + height - 1;
-			_vm->_draw->_spriteRight = pFont->itemWidth;
-			_vm->_draw->_spriteBottom = 1;
-			_vm->_draw->_destSurface = 21;
-			_vm->_draw->_backColor = frontColor;
-			_vm->_draw->spriteOperation(DRAW_FILLRECT);
-
-			if (flag != 0) {
-				key = checkCollisions(handleMouse, -1,
-				    &_activeCollResId,
-				    &_activeCollIndex);
-			}
-			flag = 0;
-
-			key = checkCollisions(handleMouse, -300,
-			    &_activeCollResId, &_activeCollIndex);
-
-			if (*pTotTime > 0) {
-				*pTotTime -= 300;
-				if (*pTotTime <= 1) {
-					key = 0;
-					_activeCollResId = 0;
-					break;
-				}
-			}
-
-			_tempStr[0] = curSym;
-			_tempStr[1] = 0;
-			_vm->_draw->_destSpriteX = xPos + pFont->itemWidth * pos;
-			_vm->_draw->_destSpriteY = yPos + height - 1;
-			_vm->_draw->_spriteRight = pFont->itemWidth;
-			_vm->_draw->_spriteBottom = 1;
-			_vm->_draw->_destSurface = 21;
-			_vm->_draw->_backColor = backColor;
-			_vm->_draw->_frontColor = frontColor;
-			_vm->_draw->_textToPrint = _tempStr;
-			_vm->_draw->_transparency = 1;
-			_vm->_draw->spriteOperation(DRAW_FILLRECT);
-
-			_vm->_draw->_destSpriteY = yPos + (height - 8) / 2;
-			_vm->_draw->spriteOperation(DRAW_PRINTTEXT);
-
-			if (key != 0 || _activeCollResId != 0)
-				break;
-
-			key = checkCollisions(handleMouse, -300,
-			    &_activeCollResId, &_activeCollIndex);
-
-			if (*pTotTime > 0) {
-				*pTotTime -= 300;
-				if (*pTotTime <= 1) {
-					key = 0;
-					_activeCollResId = 0;
-					break;
-				}
-
-			}
-			if (key != 0 || _activeCollResId != 0)
-				break;
-
-			if (_vm->_inter->_terminate)
-				return 0;
-		}
-
-		if (key == 0 || _activeCollResId != 0 || _vm->_inter->_terminate)
-			return 0;
-
-		switch (key) {
-		case 0x4d00:	// Right Arrow
-			if (pos < strlen(str) && pos < editSize - 1) {
-				pos++;
-				continue;
-			}
-			return 0x5000;
-
-		case 0x4b00:	// Left Arrow
-			if (pos > 0) {
-				pos--;
-				continue;
-			}
-			return 0x4800;
-
-		case 0xe08:	// Backspace
-			if (pos > 0) {
-				_vm->_util->cutFromStr(str, pos - 1, 1);
-				pos--;
-				continue;
-			}
-
-		case 0x5300:	// Del
-
-			if (pos >= strlen(str))
-				continue;
-
-			_vm->_util->cutFromStr(str, pos, 1);
-			continue;
-
-		case 0x1c0d:	// Enter
-		case 0x3b00:	// F1
-		case 0x3c00:	// F2
-		case 0x3d00:	// F3
-		case 0x3e00:	// F4
-		case 0x3f00:	// F5
-		case 0x4000:	// F6
-		case 0x4100:	// F7
-		case 0x4200:	// F8
-		case 0x4300:	// F9
-		case 0x4400:	// F10
-		case 0x4800:	// Up arrow
-		case 0x5000:	// Down arrow
-			return key;
-
-		case 0x11b:	// Escape
-			if (_vm->_global->_useMouse != 0)
-				continue;
-
-			_forceHandleMouse = !_forceHandleMouse;
-
-			if (_handleMouse != 0 &&
-			    (_vm->_global->_useMouse != 0 || _forceHandleMouse != 0))
-				handleMouse = 1;
-			else
-				handleMouse = 0;
-
-			if (_vm->_global->_pressedKeys[1] == 0)
-				continue;
-
-			while (_vm->_global->_pressedKeys[1] != 0);
-			continue;
-
-		default:
-
-			savedKey = key;
-			key &= 0xff;
-
-			if ((inpType == 9 || inpType == 10) && key >= ' '
-			    && key <= 0xff) {
-				str1 = "0123456789-.,+ ";
-				str2 = "0123456789-,,+ ";
-
-				if ((savedKey >> 8) > 1
-				    && (savedKey >> 8) < 12)
-					key = ((savedKey >> 8) - 1) % 10 + '0';
-
-				for (i = 0; str1[i] != 0; i++) {
-					if (key == str1[i]) {
-						key = str2[i];
-						break;
-					}
-				}
-
-				if (i == (int16)strlen(str1))
-					key = 0;
-			}
-
-			if (key >= ' ' && key <= 0xff) {
-				if (editSize == strlen(str))
-					_vm->_util->cutFromStr(str, strlen(str) - 1,
-					    1);
-
-				if (key >= 'a' && key <= 'z')
-					key += ('A' - 'a');
-
-				pos++;
-				_tempStr[0] = key;
-				_tempStr[1] = 0;
-
-				_vm->_util->insertStr(_tempStr, str, pos - 1);
-
-				//strupr(str);
-			}
-		}
-	}
-}
-
 int16 Game::adjustKey(int16 key) {
 	if (key <= 0x60 || key >= 0x7b)
 		return key;
@@ -987,7 +754,6 @@
 	_vm->_video->clearSurf(_vm->_draw->_backSurface);
 	
 	_vm->_draw->initBigSprite(23, 32, 16, 2);
-	// TODO: That assignment is not in the original assembly, why?
 	_vm->_draw->_cursorSpritesBack = _vm->_draw->_spritesArray[23];
 	_vm->_draw->_cursorSprites = _vm->_draw->_cursorSpritesBack;
 	_vm->_draw->_scummvmCursor =

Modified: scummvm/trunk/engines/gob/game.h
===================================================================
--- scummvm/trunk/engines/gob/game.h	2006-11-19 02:24:38 UTC (rev 24744)
+++ scummvm/trunk/engines/gob/game.h	2006-11-19 17:52:52 UTC (rev 24745)
@@ -195,8 +195,6 @@
 	void freeCollision(int16 id);
 
 	void loadSound(int16 slot, char *dataPtr);
-	int16 inputArea(int16 xPos, int16 yPos, int16 width, int16 height, int16 backColor,
-			int16 frontColor, char *str, int16 fontIndex, char inpType, int16 *pTotTime);
 	int16 adjustKey(int16 key);
 	void loadTotFile(char *path);
 	void loadExtTable(void);
@@ -226,6 +224,9 @@
 	virtual void collisionsBlock(void) = 0;
 	virtual int16 multiEdit(int16 time, int16 index, int16 *pCurPos,
 					InputDesc *inpDesc, int16 *collResId, int16 *collIndex) = 0;
+	virtual int16 inputArea(int16 xPos, int16 yPos, int16 width, int16 height,
+			int16 backColor, int16 frontColor, char *str, int16 fontIndex,
+			char inpType, int16 *pTotTime, int16 *collResId, int16 *collIndex) = 0;
 	virtual int16 checkKeys(int16 *pMousex, int16 *pMouseY, int16 *pButtons,
 					char handleMouse) = 0;
 	virtual int16 checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId,
@@ -290,6 +291,9 @@
 	virtual void collisionsBlock(void);
 	virtual int16 multiEdit(int16 time, int16 index, int16 *pCurPos,
 					InputDesc *inpDesc, int16 *collResId, int16 *collIndex);
+	virtual int16 inputArea(int16 xPos, int16 yPos, int16 width, int16 height,
+			int16 backColor, int16 frontColor, char *str, int16 fontIndex,
+			char inpType, int16 *pTotTime, int16 *collResId, int16 *collIndex);
 	virtual int16 checkKeys(int16 *pMousex, int16 *pMouseY, int16 *pButtons,
 					char handleMouse);
 	virtual int16 checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId,
@@ -314,6 +318,9 @@
 	virtual void collisionsBlock(void);
 	virtual int16 multiEdit(int16 time, int16 index, int16 *pCurPos,
 					InputDesc *inpDesc, int16 *collResId, int16 *collIndex);
+	virtual int16 inputArea(int16 xPos, int16 yPos, int16 width, int16 height,
+			int16 backColor, int16 frontColor, char *str, int16 fontIndex,
+			char inpType, int16 *pTotTime, int16 *collResId, int16 *collIndex);
 	virtual int16 checkKeys(int16 *pMousex, int16 *pMouseY, int16 *pButtons,
 					char handleMouse);
 	virtual int16 checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId,

Modified: scummvm/trunk/engines/gob/game_v1.cpp
===================================================================
--- scummvm/trunk/engines/gob/game_v1.cpp	2006-11-19 02:24:38 UTC (rev 24744)
+++ scummvm/trunk/engines/gob/game_v1.cpp	2006-11-19 17:52:52 UTC (rev 24745)
@@ -852,7 +852,7 @@
 		if (var_22 != 0) {
 			key =
 			    multiEdit(deltaTime, index, &curEditIndex,
-			    descArray, 0, 0);
+			    descArray, &_activeCollResId, &_activeCollIndex);
 
 			if (key == 0x1c0d) {
 				for (i = 0; i < 250; i++) {
@@ -1233,22 +1233,20 @@
 		    collArea->bottom - collArea->top + 1,
 		    inpDesc[*pCurPos].backColor, inpDesc[*pCurPos].frontColor,
 		    _vm->_global->_inter_variables + collArea->key,
-		    inpDesc[*pCurPos].fontIndex, collArea->flags, &time);
+		    inpDesc[*pCurPos].fontIndex, collArea->flags, &time, collResId, collIndex);
 
 		if (_vm->_inter->_terminate)
 			return 0;
 
 		switch (key) {
 		case 0:
-			if (_activeCollResId == 0)
+			if (*collResId == 0)
 				return 0;
 
-			if ((_collisionAreas[_activeCollIndex].
-				flags & 0x0f) < 3)
+			if ((_collisionAreas[*collIndex].flags & 0x0f) < 3)
 				return 0;
 
-			if ((_collisionAreas[_activeCollIndex].
-				flags & 0x0f) > 10)
+			if ((_collisionAreas[*collIndex].flags & 0x0f) > 10)
 				return 0;
 
 			*pCurPos = 0;
@@ -1267,7 +1265,7 @@
 				if ((collArea->flags & 0x0f) > 10)
 					continue;
 
-				if (i == _activeCollIndex)
+				if (i == *collIndex)
 					break;
 
 				pCurPos[0]++;
@@ -1312,6 +1310,236 @@
 	}
 }
 
+int16 Game_v1::inputArea(int16 xPos, int16 yPos, int16 width, int16 height,
+		int16 backColor, int16 frontColor, char *str, int16 fontIndex,
+		char inpType, int16 *pTotTime, int16 *collResId, int16 *collIndex) {
+	int16 handleMouse;
+	uint32 editSize;
+	Video::FontDesc *pFont;
+	char curSym;
+	int16 key;
+	const char *str1;
+	const char *str2;
+	int16 i;
+	uint32 pos;
+	int16 flag;
+	int16 savedKey;
+
+	if (_handleMouse != 0 &&
+	    (_vm->_global->_useMouse != 0 || _forceHandleMouse != 0))
+		handleMouse = 1;
+	else
+		handleMouse = 0;
+
+	pos = strlen(str);
+	pFont = _vm->_draw->_fonts[fontIndex];
+	editSize = width / pFont->itemWidth;
+
+	while (1) {
+		strcpy(_tempStr, str);
+		strcat(_tempStr, " ");
+		if (strlen(_tempStr) > editSize)
+			strcpy(_tempStr, str);
+
+		_vm->_draw->_destSpriteX = xPos;
+		_vm->_draw->_destSpriteY = yPos;
+		_vm->_draw->_spriteRight = editSize * pFont->itemWidth;
+		_vm->_draw->_spriteBottom = height;
+
+		_vm->_draw->_destSurface = 21;
+		_vm->_draw->_backColor = backColor;
+		_vm->_draw->_frontColor = frontColor;
+		_vm->_draw->_textToPrint = _tempStr;
+		_vm->_draw->_transparency = 1;
+		_vm->_draw->_fontIndex = fontIndex;
+		_vm->_draw->spriteOperation(DRAW_FILLRECT);
+
+		_vm->_draw->_destSpriteY = yPos + (height - 8) / 2;
+
+		_vm->_draw->spriteOperation(DRAW_PRINTTEXT);
+		if (pos == editSize)
+			pos--;
+
+		curSym = _tempStr[pos];
+
+		flag = 1;
+
+		while (1) {
+			_tempStr[0] = curSym;
+			_tempStr[1] = 0;
+
+			_vm->_draw->_destSpriteX = xPos + pFont->itemWidth * pos;
+			_vm->_draw->_destSpriteY = yPos + height - 1;
+			_vm->_draw->_spriteRight = pFont->itemWidth;
+			_vm->_draw->_spriteBottom = 1;
+			_vm->_draw->_destSurface = 21;
+			_vm->_draw->_backColor = frontColor;
+			_vm->_draw->spriteOperation(DRAW_FILLRECT);
+
+			if (flag != 0) {
+				key = checkCollisions(handleMouse, -1, collResId, collIndex);
+			}
+			flag = 0;
+
+			key = checkCollisions(handleMouse, -300, collResId, collIndex);
+
+			if (*pTotTime > 0) {
+				*pTotTime -= 300;
+				if (*pTotTime <= 1) {
+					key = 0;
+					*collResId = 0;
+					break;
+				}
+			}
+
+			_tempStr[0] = curSym;
+			_tempStr[1] = 0;
+			_vm->_draw->_destSpriteX = xPos + pFont->itemWidth * pos;
+			_vm->_draw->_destSpriteY = yPos + height - 1;
+			_vm->_draw->_spriteRight = pFont->itemWidth;
+			_vm->_draw->_spriteBottom = 1;
+			_vm->_draw->_destSurface = 21;
+			_vm->_draw->_backColor = backColor;
+			_vm->_draw->_frontColor = frontColor;
+			_vm->_draw->_textToPrint = _tempStr;
+			_vm->_draw->_transparency = 1;
+			_vm->_draw->spriteOperation(DRAW_FILLRECT);
+
+			_vm->_draw->_destSpriteY = yPos + (height - 8) / 2;
+			_vm->_draw->spriteOperation(DRAW_PRINTTEXT);
+
+			if (key != 0 || *collResId != 0)
+				break;
+
+			key = checkCollisions(handleMouse, -300, collResId, collIndex);
+
+			if (*pTotTime > 0) {
+				*pTotTime -= 300;
+				if (*pTotTime <= 1) {
+					key = 0;
+					*collResId = 0;
+					break;
+				}
+
+			}
+			if (key != 0 || *collResId != 0)
+				break;
+
+			if (_vm->_inter->_terminate)
+				return 0;
+		}
+
+		if (key == 0 || *collResId != 0 || _vm->_inter->_terminate)
+			return 0;
+
+		switch (key) {
+		case 0x4d00:	// Right Arrow
+			if (pos < strlen(str) && pos < editSize - 1) {
+				pos++;
+				continue;
+			}
+			return 0x5000;
+
+		case 0x4b00:	// Left Arrow
+			if (pos > 0) {
+				pos--;
+				continue;
+			}
+			return 0x4800;
+
+		case 0xe08:	// Backspace
+			if (pos > 0) {
+				_vm->_util->cutFromStr(str, pos - 1, 1);
+				pos--;
+				continue;
+			}
+
+		case 0x5300:	// Del
+
+			if (pos >= strlen(str))
+				continue;
+
+			_vm->_util->cutFromStr(str, pos, 1);
+			continue;
+
+		case 0x1c0d:	// Enter
+		case 0x3b00:	// F1
+		case 0x3c00:	// F2
+		case 0x3d00:	// F3
+		case 0x3e00:	// F4
+		case 0x3f00:	// F5
+		case 0x4000:	// F6
+		case 0x4100:	// F7
+		case 0x4200:	// F8
+		case 0x4300:	// F9
+		case 0x4400:	// F10
+		case 0x4800:	// Up arrow
+		case 0x5000:	// Down arrow
+			return key;
+
+		case 0x11b:	// Escape
+			if (_vm->_global->_useMouse != 0)
+				continue;
+
+			_forceHandleMouse = !_forceHandleMouse;
+
+			if (_handleMouse != 0 &&
+			    (_vm->_global->_useMouse != 0 || _forceHandleMouse != 0))
+				handleMouse = 1;
+			else
+				handleMouse = 0;
+
+			if (_vm->_global->_pressedKeys[1] == 0)
+				continue;
+
+			while (_vm->_global->_pressedKeys[1] != 0);
+			continue;
+
+		default:
+
+			savedKey = key;
+			key &= 0xff;
+
+			if ((inpType == 9 || inpType == 10) && key >= ' '
+			    && key <= 0xff) {
+				str1 = "0123456789-.,+ ";
+				str2 = "0123456789-,,+ ";
+
+				if ((savedKey >> 8) > 1
+				    && (savedKey >> 8) < 12)
+					key = ((savedKey >> 8) - 1) % 10 + '0';
+
+				for (i = 0; str1[i] != 0; i++) {
+					if (key == str1[i]) {
+						key = str2[i];
+						break;
+					}
+				}
+
+				if (i == (int16)strlen(str1))
+					key = 0;
+			}
+
+			if (key >= ' ' && key <= 0xff) {
+				if (editSize == strlen(str))
+					_vm->_util->cutFromStr(str, strlen(str) - 1,
+					    1);
+
+				if (key >= 'a' && key <= 'z')
+					key += ('A' - 'a');
+
+				pos++;
+				_tempStr[0] = key;
+				_tempStr[1] = 0;
+
+				_vm->_util->insertStr(_tempStr, str, pos - 1);
+
+				//strupr(str);
+			}
+		}
+	}
+}
+
 int16 Game_v1::checkMousePoint(int16 all, int16 *resId, int16 *resIndex) {
 	Collision *ptr;
 	int16 i;

Modified: scummvm/trunk/engines/gob/game_v2.cpp
===================================================================
--- scummvm/trunk/engines/gob/game_v2.cpp	2006-11-19 02:24:38 UTC (rev 24744)
+++ scummvm/trunk/engines/gob/game_v2.cpp	2006-11-19 17:52:52 UTC (rev 24745)
@@ -89,7 +89,7 @@
 				_vm->_mult->initAll();
 				_vm->_mult->zeroMultData();
 
-				for (i = 0; i < 20; i++)
+				for (i = 0; i < 50; i++)
 					_vm->_draw->_spritesArray[i] = 0;
 
 				_vm->_draw->_spritesArray[20] = _vm->_draw->_frontSurface;
@@ -1223,13 +1223,13 @@
 		if (collArea->left == -1)
 			continue;
 
-		if ((collArea->id & 0xC000) == 0x8000)
+		if ((collArea->id & 0xC000) != 0x8000)
 			continue;
 
-		if ((collArea->flags & 0x0f) < 3)
+		if ((collArea->flags & 0x0F) < 3)
 			continue;
 
-		if ((collArea->flags & 0x0f) > 10)
+		if ((collArea->flags & 0x0F) > 10)
 			continue;
 
 		strcpy(_tempStr, _vm->_global->_inter_variables + collArea->key);
@@ -1251,12 +1251,10 @@
 		w2E8E2Bak = _vm->_draw->_word_2E8E2;
 		_vm->_draw->_word_2E8E2 = 2;
 		_vm->_draw->_fonts[_vm->_draw->_fontIndex]->extraData = 0;
-
 		_vm->_draw->spriteOperation(DRAW_FILLRECT | 0x10);
 
 		_vm->_draw->_destSpriteY += ((collArea->bottom - collArea->top + 1) -
 				_vm->_draw->_fonts[_vm->_draw->_fontIndex]->itemHeight) / 2;
-
 		_vm->_draw->spriteOperation(DRAW_PRINTTEXT | 0x10);
 
 		_vm->_draw->_word_2E8E2 = w2E8E2Bak;
@@ -1278,13 +1276,13 @@
 			if (collArea->left == -1)
 				continue;
 
-			if ((collArea->id & 0xC000) == 0x8000)
+			if ((collArea->id & 0xC000) != 0x8000)
 				continue;
 
-			if ((collArea->flags & 0x0f) < 3)
+			if ((collArea->flags & 0x0F) < 3)
 				continue;
 
-			if ((collArea->flags & 0x0f) > 10)
+			if ((collArea->flags & 0x0F) > 10)
 				continue;
 
 			if (descInd == *pCurPos) {
@@ -1304,7 +1302,7 @@
 		    collArea->bottom - collArea->top + 1,
 		    inpDesc[*pCurPos].backColor, inpDesc[*pCurPos].frontColor,
 		    _vm->_global->_inter_variables + collArea->key,
-		    inpDesc[*pCurPos].fontIndex, collArea->flags, &time);
+		    inpDesc[*pCurPos].fontIndex, collArea->flags, &time, collResId, collIndex);
 
 		if (_vm->_inter->_terminate)
 			return 0;
@@ -1314,10 +1312,38 @@
 			if (*collResId == 0)
 				return 0;
 
-			if ((_collisionAreas[*collIndex].flags & 0x0f) < 3)
+			if (_mouseButtons != 0) {
+				for (collArea = _collisionAreas, i = 0; collArea->left != -1; collArea++, i++)
+				{
+					if ((collArea->flags & 0xF00))
+						continue;
+
+					if ((collArea->id & 0x4000))
+						continue;
+
+					if ((collArea->left > _vm->_global->_inter_mouseX) ||
+					    (collArea->right < _vm->_global->_inter_mouseX) ||
+					    (collArea->top > _vm->_global->_inter_mouseY) ||
+					    (collArea->bottom < _vm->_global->_inter_mouseY));
+						continue;
+
+					if ((collArea->id & 0xF000))
+						continue;
+
+					if ((collArea->flags & 0x0F) < 3)
+						continue;
+
+					if ((collArea->flags & 0x0F) > 10)
+						continue;
+
+					*collIndex = i;
+				}
+			}
+
+			if ((_collisionAreas[*collIndex].flags & 0x0F) < 3)
 				return 0;
 
-			if ((_collisionAreas[*collIndex].flags & 0x0f) > 10)
+			if ((_collisionAreas[*collIndex].flags & 0x0F) > 10)
 				return 0;
 
 			*pCurPos = 0;
@@ -1327,19 +1353,17 @@
 				if (collArea->left == -1)
 					continue;
 
-				if ((collArea->id & 0xC000) == 0x8000)
+				if ((collArea->id & 0xC000) != 0x8000)
 					continue;
 
-				if ((collArea->flags & 0x0f) < 3)
+				if ((collArea->flags & 0x0F) < 3)
 					continue;
 
-				if ((collArea->flags & 0x0f) > 10)
+				if ((collArea->flags & 0x0F) > 10)
 					continue;
 
-				if (i == *collIndex)
-					break;
-
-				pCurPos[0]++;
+				if (i != *collIndex)
+					pCurPos[0]++;
 			}
 			break;
 
@@ -1381,6 +1405,251 @@
 	}
 }
 
+int16 Game_v2::inputArea(int16 xPos, int16 yPos, int16 width, int16 height,
+		int16 backColor, int16 frontColor, char *str, int16 fontIndex,
+		char inpType, int16 *pTotTime, int16 *collResId, int16 *collIndex) {
+	int16 handleMouse;
+	uint32 editSize;
+	Video::FontDesc *pFont;
+	char curSym;
+	int16 key;
+	const char *str1;
+	const char *str2;
+	int16 i;
+	uint32 pos;
+	int16 flag;
+	int16 savedKey;
+	void *fontExtraBak;
+	int16 w2E8E2Bak;
+
+	if ((_handleMouse != 0) &&
+	    ((_vm->_global->_useMouse != 0) || (_forceHandleMouse != 0)))
+		handleMouse = 1;
+	else
+		handleMouse = 0;
+
+	pos = strlen(str);
+	pFont = _vm->_draw->_fonts[fontIndex];
+	editSize = width / pFont->itemWidth;
+
+	while (1) {
+		strcpy(_tempStr, str);
+		strcat(_tempStr, " ");
+		if (strlen(_tempStr) > editSize)
+			strcpy(_tempStr, str);
+
+		fontExtraBak = _vm->_draw->_fonts[fontIndex]->extraData;
+		w2E8E2Bak = _vm->_draw->_word_2E8E2;
+		_vm->_draw->_word_2E8E2 = 2;
+		_vm->_draw->_fonts[fontIndex]->extraData = 0;
+
+		_vm->_draw->_destSpriteX = xPos;
+		_vm->_draw->_destSpriteY = yPos;
+		_vm->_draw->_spriteRight = editSize * pFont->itemWidth;
+		_vm->_draw->_spriteBottom = height;
+
+		_vm->_draw->_destSurface = 21;
+		_vm->_draw->_backColor = backColor;
+		_vm->_draw->_frontColor = frontColor;
+		_vm->_draw->_textToPrint = _tempStr;
+		_vm->_draw->_transparency = 1;
+		_vm->_draw->_fontIndex = fontIndex;
+		_vm->_draw->spriteOperation(DRAW_FILLRECT | 0x10 );
+
+		_vm->_draw->_destSpriteY = yPos + (height - pFont->itemHeight) / 2;
+		_vm->_draw->spriteOperation(DRAW_PRINTTEXT | 0x10);
+
+		_vm->_draw->_word_2E8E2 = w2E8E2Bak;
+		_vm->_draw->_fonts[fontIndex]->extraData = fontExtraBak;
+
+		if (pos == editSize)
+			pos--;
+
+		curSym = _tempStr[pos];
+
+		flag = 1;
+
+		if (_vm->_global->_inter_variables != 0)
+			WRITE_VAR(56, pos);
+
+		while (1) {
+			fontExtraBak = _vm->_draw->_fonts[fontIndex]->extraData;
+			w2E8E2Bak = _vm->_draw->_word_2E8E2;
+			_vm->_draw->_word_2E8E2 = 2;
+			_vm->_draw->_fonts[fontIndex]->extraData = 0;
+
+			_tempStr[0] = curSym;
+			_tempStr[1] = 0;
+
+			_vm->_draw->_destSpriteX = xPos + pFont->itemWidth * pos;
+			_vm->_draw->_destSpriteY = yPos + height - 1;
+			_vm->_draw->_spriteRight = pFont->itemWidth;
+			_vm->_draw->_spriteBottom = 1;
+			_vm->_draw->_destSurface = 21;
+			_vm->_draw->_backColor = frontColor;
+			_vm->_draw->spriteOperation(DRAW_FILLRECT | 0x10);
+
+			_vm->_draw->_word_2E8E2 = w2E8E2Bak;
+			_vm->_draw->_fonts[fontIndex]->extraData = fontExtraBak;
+
+			if (flag != 0) {
+				key = checkCollisions(handleMouse, -1, collResId, collIndex);
+				if (key == 0)
+					key = checkCollisions(handleMouse, -300, collResId, collIndex);
+				flag = 0;
+			} else
+				key = checkCollisions(handleMouse, -300, collResId, collIndex);
+
+			fontExtraBak = _vm->_draw->_fonts[fontIndex]->extraData;
+			w2E8E2Bak = _vm->_draw->_word_2E8E2;
+			_vm->_draw->_word_2E8E2 = 2;
+			_vm->_draw->_fonts[fontIndex]->extraData = 0;
+
+			_tempStr[0] = curSym;
+			_tempStr[1] = 0;
+			_vm->_draw->_destSpriteX = xPos + pFont->itemWidth * pos;
+			_vm->_draw->_destSpriteY = yPos + height - 1;
+			_vm->_draw->_spriteRight = pFont->itemWidth;
+			_vm->_draw->_spriteBottom = 1;
+			_vm->_draw->_destSurface = 21;
+			_vm->_draw->_backColor = backColor;
+			_vm->_draw->_frontColor = frontColor;
+			_vm->_draw->_textToPrint = _tempStr;
+			_vm->_draw->_transparency = 1;
+			_vm->_draw->_fontIndex = fontIndex;
+			_vm->_draw->spriteOperation(DRAW_FILLRECT | 0x10);
+
+			_vm->_draw->_destSpriteY = yPos + (height - pFont->itemHeight) / 2;
+			_vm->_draw->spriteOperation(DRAW_PRINTTEXT | 0x10);
+
+			_vm->_draw->_word_2E8E2 = w2E8E2Bak;
+			_vm->_draw->_fonts[fontIndex]->extraData = fontExtraBak;
+
+			if (key != 0 || *collResId != 0)
+				break;
+
+			key = checkCollisions(handleMouse, -300, collResId, collIndex);
+
+			if ((key != 0) || (*collResId != 0) || _vm->_inter->_terminate || _vm->_quitRequested)
+				break;
+
+			if (*pTotTime > 0) {
+				*pTotTime -= 600;
+				if (*pTotTime <= 1) {
+					key = 0;
+					*collResId = 0;
+					break;
+				}
+			}
+		}
+
+		if ((key == 0) || (*collResId != 0) || _vm->_inter->_terminate || _vm->_quitRequested)
+			return 0;
+
+		switch (key) {
+		case 0x4d00:	// Right Arrow
+			if (pos < strlen(str) && pos < editSize - 1) {
+				pos++;
+				continue;
+			}
+			return 0x5000;
+
+		case 0x4b00:	// Left Arrow
+			if (pos > 0) {
+				pos--;
+				continue;
+			}
+			return 0x4800;
+
+		case 0xe08:	// Backspace
+			if (pos > 0) {
+				_vm->_util->cutFromStr(str, pos - 1, 1);
+				pos--;
+				continue;
+			}
+
+		case 0x5300:	// Del
+
+			if (pos >= strlen(str))
+				continue;
+
+			_vm->_util->cutFromStr(str, pos, 1);
+			continue;
+
+		case 0x1c0d:	// Enter
+		case 0x3b00:	// F1
+		case 0x3c00:	// F2
+		case 0x3d00:	// F3
+		case 0x3e00:	// F4
+		case 0x3f00:	// F5
+		case 0x4000:	// F6
+		case 0x4100:	// F7
+		case 0x4200:	// F8
+		case 0x4300:	// F9
+		case 0x4400:	// F10
+		case 0x4800:	// Up arrow
+		case 0x5000:	// Down arrow
+			return key;
+
+		case 0x11b:	// Escape
+			if (_vm->_global->_useMouse != 0)
+				continue;
+
+			_forceHandleMouse = !_forceHandleMouse;
+
+			if (_handleMouse != 0 &&
+			    (_vm->_global->_useMouse != 0 || _forceHandleMouse != 0))
+				handleMouse = 1;
+			else
+				handleMouse = 0;
+
+			while (_vm->_global->_pressedKeys[1] != 0);
+			continue;
+
+		default:
+
+			savedKey = key;
+			key &= 0xff;
+
+			if ((inpType == 9 || inpType == 10) && key >= ' '
+			    && key <= 0xff) {
+				str1 = "0123456789-.,+ ";
+				str2 = "0123456789-,,+ ";
+
+				if (((savedKey >> 8) > 1 && (savedKey >> 8) < 12) &&
+						((_vm->_global->_pressedKeys[42] != 0) || (_vm->_global->_pressedKeys[56] != 0)))
+					key = ((savedKey >> 8) - 1) % 10 + '0';
+
+				for (i = 0; str1[i] != 0; i++) {
+					if (key == str1[i]) {
+						key = str2[i];
+						break;
+					}
+				}
+
+				if (i == (int16)strlen(str1))
+					key = 0;
+			}
+
+			if (key >= ' ' && key <= 0xff) {
+				if (editSize == strlen(str))
+					_vm->_util->cutFromStr(str, strlen(str) - 1, 1);
+
+/*				if (key >= 'a' && key <= 'z')
+					key += ('A' - 'a');*/
+
+				pos++;
+				_tempStr[0] = key;
+				_tempStr[1] = 0;
+
+				_vm->_util->insertStr(_tempStr, str, pos - 1);
+
+				//strupr(str);
+			}
+		}
+	}
+}
+
 int16 Game_v2::checkMousePoint(int16 all, int16 *resId, int16 *resIndex) {
 	Collision *ptr;
 	int16 i;

Modified: scummvm/trunk/engines/gob/gob.cpp
===================================================================
--- scummvm/trunk/engines/gob/gob.cpp	2006-11-19 02:24:38 UTC (rev 24744)
+++ scummvm/trunk/engines/gob/gob.cpp	2006-11-19 17:52:52 UTC (rev 24745)
@@ -20,6 +20,7 @@
  *
  */
 #include "common/stdafx.h"
+#include "common/endian.h"
 
 #include "base/plugins.h"
 #include "common/config-manager.h"
@@ -168,6 +169,14 @@
 		strcat(_startTot0, "0.tot");
 	}
 
+	int i;
+	_saveFiles = new char*[3];
+	for (i = 0; i < 3; i++)
+		_saveFiles[i] = new char[_targetName.size() + 5];
+	sprintf(_saveFiles[0], "%s.cat", _targetName.c_str());
+	sprintf(_saveFiles[1], "%s.sav", _targetName.c_str());
+	sprintf(_saveFiles[2], "%s.blo", _targetName.c_str());
+
 	Common::addSpecialDebugLevel(DEBUG_FUNCOP, "FuncOpcodes", "Script FuncOpcodes debug level");
 	Common::addSpecialDebugLevel(DEBUG_DRAWOP, "DrawOpcodes", "Script DrawOpcodes debug level");
 	Common::addSpecialDebugLevel(DEBUG_GOBOP, "GoblinOpcodes", "Script GoblinOpcodes debug level");
@@ -202,6 +211,11 @@
 	delete _music;
 	delete[] _startTot;
 	delete[] _startTot0;
+
+	int i;
+	for (i = 0; i < 3; i++)
+		delete[] _saveFiles[i];
+	delete[] _saveFiles;
 }
 
 int GobEngine::go() {
@@ -219,6 +233,218 @@
 	(*(uint32 *)(_global->_inter_variables + (offs))) = v;
 }
 
+// Seeking with SEEK_END (and therefore also pos()) doesn't work with
+// gzip'd save files, so reading the whole thing in is necessary
+uint32 GobEngine::getSaveSize(Common::InSaveFile &in) {
+	char buf[1024];
+	uint32 size;
+	uint32 i;
+	uint32 pos;
+
+	size = 0;
+	pos = in.pos();
+	in.seek(0, SEEK_SET);
+	while ((i = in.read(buf, 1024)) > 0)
+		size += i;
+	in.seek(0, pos);
+
+	return size;
+}
+
+int32 GobEngine::getSaveSize(enum SaveFiles sFile) {
+	int32 size;
+	Common::InSaveFile *in;
+
+	if ((in = _saveFileMan->openForLoading(_saveFiles[(int) sFile]))) {
+		size = getSaveSize(*in);
+		delete in;
+	} else
+		size = -1;
+
+	debugC(1, DEBUG_FILEIO, "Requested size of file \"%s\": %d", _saveFiles[(int) sFile], size);
+
+	return size;
+}
+
+void GobEngine::saveGame(enum SaveFiles sFile, int16 dataVar, int32 size, int32 offset) {
+	int32 retSize;
+	int16 index;
+	int16 top;
+	bool writePal;
+	char *sName;
+	char *buf;
+	char *oBuf;
+	int32 iSize;
+	int32 oSize;
+	int32 oOff;
+	Video::SurfaceDesc *destDesc;
+	Video::SurfaceDesc *srcDesc;
+	Common::InSaveFile *in;
+	Common::OutSaveFile *out;
+
+	index = 0;
+	oBuf = 0;
+	in = 0;
+	writePal = false;
+	sName = _saveFiles[(int) sFile];
+
+	// WRITE_VAR(1, 1)
+	*((uint32*)(_global->_inter_variables + 4)) = 1;
+
+	if (size < 0) {
+		if (size < -1000) {
+			writePal = true;
+			size += 1000;
+		}
+		index = -size - 1;
+		assert((index >= 0) && (index < 50)); // Just to be sure...
+		buf = (char *) _draw->_spritesArray[index]->vidPtr;
+		size = _draw->getSpriteRectSize(index);
+		if ((_draw->_spritesArray[index]->vidMode & 0x80) == 0)
+			size = -size;
+	} else if (size == 0) {
+		dataVar = 0;
+		size = READ_LE_UINT32(_game->_totFileData + 0x2C) * 4;
+		buf = _global->_inter_variables;
+	} else
+		buf = _global->_inter_variables + dataVar;
+
+	if ((in = _saveFileMan->openForLoading(sName)))
+		iSize = getSaveSize(*in);
+	else
+		iSize = 0;
+
+	oOff = offset < 0 ? MAX(0, iSize - (-offset - 1)) : offset;
+	oSize = MAX(iSize, oOff + ABS(size));
+	oBuf = new char[oSize];
+	memset(oBuf, 0, oSize);
+
+	if (in) {
+		in->read(oBuf, iSize);
+		delete in;
+	}
+
+	if(!(out = _saveFileMan->openForSaving(sName))) {
+		warning("Can't write file \"%s\"", sName);
+		delete[] oBuf;
+		return;
+	}
+	
+	if (writePal) {
+		memcpy(oBuf + oOff, (char *) _global->_pPaletteDesc->vgaPal, 768);
+		oOff += 768;
+	}
+
+	if (size < 0) {
+		srcDesc = _draw->_spritesArray[index];
+		destDesc = _video->initSurfDesc(_global->_videoMode, srcDesc->width, 25, 0);
+		for (top = 0, retSize = 0; top < srcDesc->height; top += 25) {
+			int16 height = MIN(25, srcDesc->height - top);
+			_video->drawSprite(srcDesc, destDesc, 0, top, srcDesc->width - 1,
+					top + height - 1, 0, 0, 0);
+			memcpy(oBuf + oOff, (char *) destDesc->vidPtr, srcDesc->width * 25);
+			oOff += srcDesc->width * 25;
+		}
+		_video->freeSurfDesc(destDesc);
+	} else
+		memcpy(oBuf + oOff, buf, size);
+
+	out->write(oBuf, oSize);
+	out->flush();
+
+	if (out->ioFailed())
+		warning("Can't write file \"%s\"", sName);
+	else {
+		debugC(1, DEBUG_FILEIO, "Saved file \"%s\" (%d, %d bytes at %d)",
+				sName, dataVar, size, offset);
+		// WRITE_VAR(1, 0)
+		*((uint32*)(_global->_inter_variables + 4)) = 0;
+	}
+
+	delete out;
+	delete[] oBuf;
+}
+
+void GobEngine::loadGame(enum SaveFiles sFile, int16 dataVar, int32 size, int32 offset) {
+	int32 sSize;
+	int32 retSize;
+	int16 index;
+	int16 y;
+	char *buf;
+	char *sName;
+	bool readPal;
+	Video::SurfaceDesc *destDesc;
+	Video::SurfaceDesc *srcDesc;
+	Common::InSaveFile *in;
+
+	readPal = false;
+	sName = _saveFiles[(int) sFile];
+	if (size < 0) {
+		if (size < -1000) {
+			readPal = true;
+			size += 1000;
+		}
+		index = -size - 1;
+		assert((index >= 0) && (index < 50)); // Just to be sure...
+		buf = (char *) _draw->_spritesArray[index]->vidPtr;
+		size = _draw->getSpriteRectSize(index);
+		if ((_draw->_spritesArray[index]->vidMode & 0x80) == 0)
+			size = -size;
+	} else if (size == 0) {
+		dataVar = 0;
+		size = READ_LE_UINT32(_game->_totFileData + 0x2C) * 4;
+		buf = _global->_inter_variables;
+	} else
+		buf = _global->_inter_variables + dataVar;
+
+	if (_global->_inter_resStr[0] == 0) {
+		if (readPal)
+			size += 768;
+		// WRITE_VAR(1, size)
+		*((uint32*)(_global->_inter_variables + 4)) = (uint32) size;
+		return;
+	}
+
+	// WRITE_VAR(1, 1)
+	*((uint32*)(_global->_inter_variables + 4)) = 1;
+	if(!(in = _saveFileMan->openForLoading(sName)))
+		return;
+
+	debugC(1, DEBUG_FILEIO, "Loading file \"%s\" (%d, %d bytes at %d)",
+			sName, dataVar, size, offset);
+
+	sSize = getSaveSize(*in);
+	_draw->animateCursor(4);
+	if (offset < 0)
+		in->seek(sSize - (-offset - 1), 0);
+	else
+		in->seek(offset, 0);
+
+	if (readPal) {
+		retSize = in->read((char *) _global->_pPaletteDesc->vgaPal, 768);
+		_draw->_applyPal = 1;
+	}
+
+	if (size < 0) {
+		destDesc = _draw->_spritesArray[index];
+		srcDesc = _video->initSurfDesc(_global->_videoMode, destDesc->width, 25, 0);
+		for (y = 0, retSize = 0; y < destDesc->height; y += 25) {
+			int16 height = MIN(25, destDesc->height - y);
+			retSize += in->read((char *) srcDesc->vidPtr, destDesc->width * 25);
+			_video->drawSprite(srcDesc, destDesc, 0, 0, destDesc->width - 1, height - 1, 0, y, 0);
+		}
+		_video->freeSurfDesc(srcDesc);
+	} else
+		retSize = in->read(buf, size);
+
+	if (retSize == size)
+		// WRITE_VAR(1, 0)
+		*((uint32*)(_global->_inter_variables + 4)) = 0;
+
+	delete in;
+	return;
+}
+
 int GobEngine::init() {
 	_snd = new Snd(this);
 	_global = new Global(this);

Modified: scummvm/trunk/engines/gob/gob.h
===================================================================
--- scummvm/trunk/engines/gob/gob.h	2006-11-19 02:24:38 UTC (rev 24744)
+++ scummvm/trunk/engines/gob/gob.h	2006-11-19 17:52:52 UTC (rev 24745)
@@ -25,6 +25,7 @@
 
 #include "common/stdafx.h"
 #include "common/system.h"
+#include "common/savefile.h"
 
 #include "engines/engine.h"
 
@@ -81,6 +82,12 @@
 	DEBUG_COLLISIONS = 1 << 8
 };
 
+enum SaveFiles {
+	SAVE_CAT = 0,
+	SAVE_SAV,
+	SAVE_BLO
+};
+
 class GobEngine : public Engine {
 protected:
 	int go();
@@ -98,6 +105,7 @@
 	Common::Language _language;
 	char *_startTot;
 	char *_startTot0;
+	char **_saveFiles;
 	bool _copyProtection;
 	bool _quitRequested;
 
@@ -123,6 +131,10 @@
 	Music *_music;
 
 	void writeVarDebug(uint32 offs, uint32 v);
+	inline uint32 getSaveSize(Common::InSaveFile &in);
+	int32 getSaveSize(enum SaveFiles sFile);
+	void saveGame(enum SaveFiles sFile, int16 dataVar, int32 size, int32 offset);
+	void loadGame(enum SaveFiles sFile, int16 dataVar, int32 size, int32 offset);
 };
 
 } // End of namespace Gob

Modified: scummvm/trunk/engines/gob/inter.h
===================================================================
--- scummvm/trunk/engines/gob/inter.h	2006-11-19 02:24:38 UTC (rev 24744)
+++ scummvm/trunk/engines/gob/inter.h	2006-11-19 17:52:52 UTC (rev 24745)
@@ -318,6 +318,9 @@
 	void o2_stub0x80(void);
 	void o2_stub0x82(void);
 	void o2_stub0x85(void);
+	bool o2_getFreeMem(char &cmdCount, int16 &counter, int16 &retFlag);
+	bool o2_readData(char &cmdCount, int16 &counter, int16 &retFlag);
+	bool o2_writeData(char &cmdCount, int16 &counter, int16 &retFlag);
 	bool o2_checkData(char &cmdCount, int16 &counter, int16 &retFlag);
 	bool o2_stopSound(char &cmdCount, int16 &counter, int16 &retFlag);
 	bool o2_createSprite(char &cmdCount, int16 &counter, int16 &retFlag);

Modified: scummvm/trunk/engines/gob/inter_v2.cpp
===================================================================
--- scummvm/trunk/engines/gob/inter_v2.cpp	2006-11-19 02:24:38 UTC (rev 24744)
+++ scummvm/trunk/engines/gob/inter_v2.cpp	2006-11-19 17:52:52 UTC (rev 24745)
@@ -525,7 +525,7 @@
 		/* 3C */
 		OPCODE(o1_waitEndPlay),
 		OPCODE(o1_playComposition),
-		OPCODE(o1_getFreeMem),
+		OPCODE(o2_getFreeMem),
 		OPCODE(o2_checkData),
 		/* 40 */
 		{NULL, ""},
@@ -544,8 +544,8 @@
 		OPCODE(o1_loadFont),
 		/* 4C */
 		OPCODE(o1_freeFont),
-		OPCODE(o1_readData),
-		OPCODE(o1_writeData),
+		OPCODE(o2_readData),
+		OPCODE(o2_writeData),
 		OPCODE(o1_manageDataFile),
 	};
 
@@ -1271,20 +1271,175 @@
 	}
 }
 
+bool Inter_v2::o2_getFreeMem(char &cmdCount, int16 &counter, int16 &retFlag) {
+	int16 freeVar;
+	int16 maxFreeVar;
+
+	freeVar = _vm->_parse->parseVarIndex();
+	maxFreeVar = _vm->_parse->parseVarIndex();
+
+	// HACK
+	WRITE_VAR_OFFSET(freeVar, 1000000);
+	WRITE_VAR_OFFSET(maxFreeVar, 1000000);
+	WRITE_VAR(16, READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4);
+	return false;
+}
+
+bool Inter_v2::o2_readData(char &cmdCount, int16 &counter, int16 &retFlag) {
+	int32 retSize;
+	int32 size;
+	int32 offset;
+	int16 dataVar; // si
+	int16 handle;
+	int16 index;
+	int16 y;
+	char *buf;
+	bool readPal;
+	Video::SurfaceDesc *destDesc;
+	Video::SurfaceDesc *srcDesc;
+
+	readPal = false;
+	evalExpr(0);
+	dataVar = _vm->_parse->parseVarIndex();
+	size = _vm->_parse->parseValExpr();
+	evalExpr(0);
+	offset = _vm->_global->_inter_resVal;
+
+	if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.inf")) {
+		_vm->loadGame(SAVE_CAT, dataVar, size, offset);
+		return false;
+	}
+	else if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.cat")) {
+		_vm->loadGame(SAVE_CAT, dataVar, size, offset);
+		return false;
+	}
+	else if (!scumm_stricmp(_vm->_global->_inter_resStr, "save.inf")) {
+		_vm->loadGame(SAVE_SAV, dataVar, size, offset);
+		return false;
+	}
+	else if (!scumm_stricmp(_vm->_global->_inter_resStr, "bloc.inf")) {
+		_vm->loadGame(SAVE_BLO, dataVar, size, offset);
+		return false;
+	}
+
+	if (size < 0) {
+		if (size < -1000) {
+			readPal = true;
+			size += 1000;
+		}
+		index = -size - 1;
+		assert((index >= 0) && (index < 50)); // Just to be sure...
+		buf = (char *) _vm->_draw->_spritesArray[index]->vidPtr;
+		size = _vm->_draw->getSpriteRectSize(index);
+		if ((_vm->_draw->_spritesArray[index]->vidMode & 0x80) == 0)
+			size = -size;
+	} else if (size == 0) {
+		dataVar = 0;
+		size = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4;
+		buf = _vm->_global->_inter_variables;
+	} else
+		buf = _vm->_global->_inter_variables + dataVar;
+
+	if (_vm->_global->_inter_resStr[0] == 0) {
+		if (readPal)
+			size += 768;
+		WRITE_VAR(1, size);
+		return false;
+	}
+
+	WRITE_VAR(1, 1);
+	handle = _vm->_dataio->openData(_vm->_global->_inter_resStr);
+
+	if (handle < 0)
+		return false;
+
+	_vm->_draw->animateCursor(4);
+	if (offset < 0)
+		_vm->_dataio->seekData(handle, -offset - 1, 2);
+	else
+		_vm->_dataio->seekData(handle, offset, 0);
+
+	if (readPal) {
+		retSize = _vm->_dataio->readData(handle, (char *) _vm->_global->_pPaletteDesc->vgaPal, 768);
+		_vm->_draw->_applyPal = 1;
+	}
+
+	if (size < 0) {
+		destDesc = _vm->_draw->_spritesArray[index];
+		srcDesc = _vm->_video->initSurfDesc(_vm->_global->_videoMode, destDesc->width, 25, 0);
+		for (y = 0, retSize = 0; y < destDesc->height; y += 25) {
+			int16 height = MIN(25, destDesc->height - y);
+			retSize += _vm->_dataio->readData(handle, (char *) srcDesc->vidPtr, destDesc->width * 25);
+			_vm->_video->drawSprite(srcDesc, destDesc, 0, 0, destDesc->width - 1, height - 1, 0, y, 0);
+		}
+		_vm->_video->freeSurfDesc(srcDesc);
+	} else
+		retSize = _vm->_dataio->readData(handle, buf, size);
+
+	if (retSize == size)
+		WRITE_VAR(1, 0);
+
+	_vm->_dataio->closeData(handle);
+	return false;
+}
+
+bool Inter_v2::o2_writeData(char &cmdCount, int16 &counter, int16 &retFlag) {
+	int32 offset;
+	int32 size;
+	int16 dataVar;
+
+	evalExpr(0);
+	dataVar = _vm->_parse->parseVarIndex();
+	size = _vm->_parse->parseValExpr();
+	evalExpr(0);
+	offset = _vm->_global->_inter_resVal;
+
+	if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.inf"))
+		_vm->saveGame(SAVE_CAT, dataVar, size, offset);
+	else if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.cat"))
+		_vm->saveGame(SAVE_CAT, dataVar, size, offset);
+	else if (!scumm_stricmp(_vm->_global->_inter_resStr, "save.inf"))
+		_vm->saveGame(SAVE_SAV, dataVar, size, offset);
+	else if (!scumm_stricmp(_vm->_global->_inter_resStr, "bloc.inf"))
+		_vm->saveGame(SAVE_BLO, dataVar, size, offset);
+	else
+		warning("Attempted to write to file \"%s\"", _vm->_global->_inter_resStr);
+
+	return false;
+}
+
 bool Inter_v2::o2_checkData(char &cmdCount, int16 &counter, int16 &retFlag) {
 	int16 handle;
 	int16 varOff;
+	int32 size;
 
 	evalExpr(0);
 	varOff = _vm->_parse->parseVarIndex();
-	handle = _vm->_dataio->openData(_vm->_global->_inter_resStr);
 
+	handle = 0;
+	if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.inf"))
+		size = _vm->getSaveSize(SAVE_CAT);
+	else if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.cat"))
+		size = _vm->getSaveSize(SAVE_CAT);
+	else if (!scumm_stricmp(_vm->_global->_inter_resStr, "save.inf"))
+		size = _vm->getSaveSize(SAVE_SAV);
+	else if (!scumm_stricmp(_vm->_global->_inter_resStr, "bloc.inf"))
+		size = _vm->getSaveSize(SAVE_BLO);
+	else {
+		handle = _vm->_dataio->openData(_vm->_global->_inter_resStr);
+
+		if (handle >= 0) {
+			_vm->_dataio->closeData(handle);
+			size = _vm->_dataio->getDataSize(_vm->_global->_inter_resStr);
+		} else
+			size = -1;
+	}
+	if (size == -1)
+		handle = -1;
+
 	WRITE_VAR_OFFSET(varOff, handle);
-	if (handle >= 0) {
-		_vm->_dataio->closeData(handle);
-		WRITE_VAR(16, (uint32) _vm->_dataio->getDataSize(_vm->_global->_inter_resStr));
-	} else
-		WRITE_VAR(16, (uint32) -1);
+	WRITE_VAR(16, (uint32) size);
+
 	return false;
 }
 
@@ -1685,7 +1840,7 @@
 		if (expr & 0x4000)
 			_vm->_draw->_renderFlags &= expr & 0x3fff;
 		else
-			_vm->_draw->_renderFlags = _vm->_parse->parseValExpr();
+			_vm->_draw->_renderFlags = expr;
 	}
 }
 


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