[Scummvm-cvs-logs] SF.net SVN: scummvm:[53004] scummvm/branches/branch-1-2-0/engines/sci

thebluegr at users.sourceforge.net thebluegr at users.sourceforge.net
Mon Oct 4 00:52:56 CEST 2010


Revision: 53004
          http://scummvm.svn.sourceforge.net/scummvm/?rev=53004&view=rev
Author:   thebluegr
Date:     2010-10-03 22:52:55 +0000 (Sun, 03 Oct 2010)

Log Message:
-----------
SCI: Added support for SCI1.1+ magnifier cursors (bug #3034973) (backport).

These are special cursors which zoom parts of a view dynamically. Examples
are Freddy Pharkas, when reading the prescription with the whiskey and LB2,
when using the magnifying glass on the Rosetta Stone

Modified Paths:
--------------
    scummvm/branches/branch-1-2-0/engines/sci/engine/kgraphics.cpp
    scummvm/branches/branch-1-2-0/engines/sci/graphics/cursor.cpp
    scummvm/branches/branch-1-2-0/engines/sci/graphics/cursor.h

Modified: scummvm/branches/branch-1-2-0/engines/sci/engine/kgraphics.cpp
===================================================================
--- scummvm/branches/branch-1-2-0/engines/sci/engine/kgraphics.cpp	2010-10-03 22:41:35 UTC (rev 53003)
+++ scummvm/branches/branch-1-2-0/engines/sci/engine/kgraphics.cpp	2010-10-03 22:52:55 UTC (rev 53004)
@@ -129,8 +129,7 @@
 			g_sci->_gfxCursor->kernelHide();
 			break;
 		case -1:
-			// TODO: Special case at least in kq6, check disassembly
-			//  Does something with magCursor, which is set on argc = 10, which we don't support
+			g_sci->_gfxCursor->kernelClearZoomZone();
 			break;
 		case -2:
 			g_sci->_gfxCursor->kernelResetMoveZone();
@@ -184,15 +183,10 @@
 		break;
 	case 10:
 		// Freddy pharkas, when using the whiskey glass to read the prescription (bug #3034973)
-		// magnifier support, disabled using argc == 1, argv == -1
-		warning("kSetCursor: unsupported magnifier");
-		// we just set the view cursor currently
-		g_sci->_gfxCursor->kernelSetView(argv[5].toUint16(), argv[6].toUint16(), argv[7].toUint16(), hotspot);
-		// argv[0] -> 1, 2, 4 -> maybe magnification multiplier
-		// argv[1-4] -> rect for magnification
-		// argv[5, 6, 7] -> view resource for cursor
-		// argv[8] -> picture resource for mag
-		// argv[9] -> color for magnifier replacement
+		g_sci->_gfxCursor->kernelSetZoomZone(argv[0].toUint16(), 
+			Common::Rect(argv[1].toUint16(), argv[2].toUint16(), argv[3].toUint16(), argv[4].toUint16()),
+			argv[5].toUint16(), argv[6].toUint16(), argv[7].toUint16(),
+			argv[8].toUint16(), argv[9].toUint16());
 		break;
 	default :
 		error("kSetCursor: Unhandled case: %d arguments given", argc);

Modified: scummvm/branches/branch-1-2-0/engines/sci/graphics/cursor.cpp
===================================================================
--- scummvm/branches/branch-1-2-0/engines/sci/graphics/cursor.cpp	2010-10-03 22:41:35 UTC (rev 53003)
+++ scummvm/branches/branch-1-2-0/engines/sci/graphics/cursor.cpp	2010-10-03 22:52:55 UTC (rev 53004)
@@ -49,6 +49,15 @@
 	// center mouse cursor
 	setPosition(Common::Point(_screen->getWidth() / 2, _screen->getHeight() / 2));
 	_moveZoneActive = false;
+
+	_zoomZoneActive = false;
+	_zoomZone = Common::Rect();
+	_zoomColor = 0;
+	_zoomCursorView = 0;
+	_zoomCursorLoop = 0;
+	_zoomCursorCel = 0;
+	_zoomPicView = 0;
+	_zoomMultiplier = 0;
 }
 
 GfxCursor::~GfxCursor() {
@@ -329,9 +338,10 @@
 }
 
 void GfxCursor::refreshPosition() {
+	Common::Point mousePoint = getPosition();
+
 	if (_moveZoneActive) {
 		bool clipped = false;
-		Common::Point mousePoint = getPosition();
 
 		if (mousePoint.x < _moveZone.left) {
 			mousePoint.x = _moveZone.left;
@@ -353,6 +363,47 @@
 		if (clipped)
 			setPosition(mousePoint);
 	}
+
+	if (_zoomZoneActive) {
+		// Cursor
+		const CelInfo *cursorCelInfo = _zoomCursorView->getCelInfo(_zoomCursorLoop, _zoomCursorCel);
+		const byte *cursorBitmap = _zoomCursorView->getBitmap(_zoomCursorLoop, _zoomCursorCel);
+		int16 cursorWidth = cursorCelInfo->width * (_upscaledHires ? 2 : 1);
+		int16 cursorHeight = cursorCelInfo->height * (_upscaledHires ? 2 : 1);
+		byte *finalBitmap = new byte[cursorWidth * cursorHeight];
+		// Pic
+		const CelInfo *picCelInfo = _zoomPicView->getCelInfo(0, 0);
+		int16 picWidth = picCelInfo->width * _zoomMultiplier;
+		//int16 picHeight = picCelInfo->height * _zoomMultiplier;
+		// Compute hotspot from xoffset/yoffset
+		Common::Point cursorHotspot = Common::Point((cursorCelInfo->width >> 1) - cursorCelInfo->displaceX, cursorCelInfo->height - cursorCelInfo->displaceY - 1);
+
+		if (!_upscaledHires) {
+			memcpy(finalBitmap, cursorBitmap, cursorCelInfo->width * cursorCelInfo->height);
+		} else {
+			// Scale cursor by 2x - note: sierra didn't do this, but it looks much better
+			cursorHotspot.x *= 2;
+			cursorHotspot.y *= 2;
+			_screen->scale2x(cursorBitmap, finalBitmap, cursorCelInfo->width, cursorCelInfo->height);
+		}
+
+		uint16 targetX = mousePoint.x * _zoomMultiplier - _zoomZone.left;
+		uint16 targetY = mousePoint.y * _zoomMultiplier - _zoomZone.top;
+
+		// Replace the special magnifier color with the associated magnified pixels
+		for (int x = 0; x < cursorCelInfo->width; x++) {
+			for (int y = 0; y < cursorCelInfo->height; y++) {
+				int curPos = cursorCelInfo->width * y + x;
+				if (finalBitmap[curPos] == _zoomColor) {
+					finalBitmap[curPos] = _zoomBitmap[picWidth * (targetY + y) + (targetX + x)];
+				}
+			}
+		}
+
+		CursorMan.replaceCursor((const byte *)finalBitmap, cursorCelInfo->width, cursorCelInfo->height, cursorHotspot.x, cursorHotspot.y, cursorCelInfo->clearKey);
+
+		delete[] finalBitmap;
+	}
 }
 
 void GfxCursor::kernelResetMoveZone() {
@@ -364,6 +415,55 @@
 	_moveZoneActive = true;
 }
 
+void GfxCursor::kernelClearZoomZone() {
+	delete[] _zoomBitmap;
+	kernelResetMoveZone();
+	_zoomZone = Common::Rect();
+	_zoomColor = 0;
+	_zoomMultiplier = 0;
+	_zoomZoneActive = false;
+}
+
+void GfxCursor::kernelSetZoomZone(byte multiplier, Common::Rect zone, GuiResourceId viewNum, int loopNum, int celNum, GuiResourceId picNum, byte zoomColor) {
+	if (multiplier != 1 && multiplier != 2) {
+		warning("kernelSetZoomZone: Unsupported magnifier %d", multiplier);
+		return;
+	}
+
+	_zoomMultiplier = multiplier;
+
+	if (_cachedCursors.size() >= MAX_CACHED_CURSORS)
+		purgeCache();
+
+	if (!_cachedCursors.contains(viewNum))
+		_cachedCursors[viewNum] = new GfxView(_resMan, _screen, _palette, viewNum);
+	if (!_cachedCursors.contains(picNum))
+		_cachedCursors[picNum] = new GfxView(_resMan, _screen, _palette, picNum);
+
+	_zoomCursorView = _cachedCursors[viewNum];
+	_zoomCursorLoop = (byte)loopNum;
+	_zoomCursorCel = (byte)celNum;
+	_zoomPicView = _cachedCursors[picNum];
+
+	kernelSetView(viewNum, loopNum, celNum, NULL);
+
+	GfxView *zoomPicView = _cachedCursors[picNum];
+	const byte *rawPicBitmap = zoomPicView->getBitmap(0, 0);
+	const CelInfo *celInfo = zoomPicView->getCelInfo(0, 0);
+	_zoomBitmap = new byte[(celInfo->width * _zoomMultiplier) * (celInfo->height * _zoomMultiplier)];
+
+	if (_zoomMultiplier == 1)
+		memcpy(_zoomBitmap, rawPicBitmap, celInfo->width * celInfo->height);
+	else if (_zoomMultiplier == 2)
+		_screen->scale2x(rawPicBitmap, _zoomBitmap, celInfo->width, celInfo->height);
+
+	_zoomZone = zone;
+	kernelSetMoveZone(_zoomZone);
+
+	_zoomColor = zoomColor;
+	_zoomZoneActive = true;
+}
+
 void GfxCursor::kernelSetPos(Common::Point pos) {
 	_coordAdjuster->setCursorPos(pos);
 	kernelMoveCursor(pos);

Modified: scummvm/branches/branch-1-2-0/engines/sci/graphics/cursor.h
===================================================================
--- scummvm/branches/branch-1-2-0/engines/sci/graphics/cursor.h	2010-10-03 22:41:35 UTC (rev 53003)
+++ scummvm/branches/branch-1-2-0/engines/sci/graphics/cursor.h	2010-10-03 22:52:55 UTC (rev 53004)
@@ -79,6 +79,9 @@
 	 */
 	void kernelSetMoveZone(Common::Rect zone);
 
+	void kernelClearZoomZone();
+	void kernelSetZoomZone(byte multiplier, Common::Rect zone, GuiResourceId viewNum, int loopNum, int celNum, GuiResourceId picNum, byte zoomColor);
+
 	void kernelSetPos(Common::Point pos);
 	void kernelMoveCursor(Common::Point pos);
 
@@ -96,6 +99,16 @@
 	bool _moveZoneActive;
 	Common::Rect _moveZone; // Rectangle in which the pointer can move
 
+	bool _zoomZoneActive;
+	Common::Rect _zoomZone;
+	GfxView *_zoomCursorView;
+	byte _zoomCursorLoop;
+	byte _zoomCursorCel;
+	GfxView *_zoomPicView;
+	byte *_zoomBitmap;
+	byte _zoomColor;
+	byte _zoomMultiplier;
+
 	CursorCache _cachedCursors;
 
 	bool _isVisible;


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