[Scummvm-cvs-logs] SF.net SVN: scummvm:[51308] scummvm/trunk/engines/sci/graphics

m_kiewitz at users.sourceforge.net m_kiewitz at users.sourceforge.net
Mon Jul 26 14:20:08 CEST 2010


Revision: 51308
          http://scummvm.svn.sourceforge.net/scummvm/?rev=51308&view=rev
Author:   m_kiewitz
Date:     2010-07-26 12:20:07 +0000 (Mon, 26 Jul 2010)

Log Message:
-----------
SCI: some scrolling support for sci32

not fully done yet

Modified Paths:
--------------
    scummvm/trunk/engines/sci/graphics/frameout.cpp
    scummvm/trunk/engines/sci/graphics/picture.cpp
    scummvm/trunk/engines/sci/graphics/picture.h

Modified: scummvm/trunk/engines/sci/graphics/frameout.cpp
===================================================================
--- scummvm/trunk/engines/sci/graphics/frameout.cpp	2010-07-26 09:34:15 UTC (rev 51307)
+++ scummvm/trunk/engines/sci/graphics/frameout.cpp	2010-07-26 12:20:07 UTC (rev 51308)
@@ -209,9 +209,13 @@
 		planeRect.bottom = (planeRect.bottom * _screen->getHeight()) / scriptsRunningHeight;
 		planeRect.right = (planeRect.right * _screen->getWidth()) / scriptsRunningWidth;
 
+		int16 planeOffsetX = 0;
+
 		// We get negative left in kq7 in scrolling rooms
-		if (planeRect.left < 0)
+		if (planeRect.left < 0) {
+			planeOffsetX = -planeRect.left;
 			planeRect.left = 0;
+		}
 		if (planeRect.top < 0)
 			planeRect.top = 0;
 		// We get bad plane-bottom in sq6
@@ -301,8 +305,6 @@
 		FrameoutEntry *pictureCels = NULL;
 
 		if (planePicture) {
-			// Show base picture
-//			planePicture->drawSci32Vga(0, planePicture->getSci32celX(0), planePicture->getSci32celY(0), planePictureMirrored);
 			// Allocate memory for picture cels
 			pictureCels = new FrameoutEntry[planePicture->getSci32celCount()];
 			// Add following cels to the itemlist
@@ -336,7 +338,7 @@
 				itemEntry->y = ((itemEntry->y * _screen->getHeight()) / scriptsRunningHeight);
 				itemEntry->x = ((itemEntry->x * _screen->getWidth()) / scriptsRunningWidth);
 
-				planePicture->drawSci32Vga(itemEntry->celNo, itemEntry->x, itemEntry->y, planePictureMirrored);
+				planePicture->drawSci32Vga(itemEntry->celNo, itemEntry->x, itemEntry->y, planeOffsetX, planePictureMirrored);
 //				warning("picture cel %d %d", itemEntry->celNo, itemEntry->priority);
 
 			} else if (itemEntry->viewId != 0xFFFF) {
@@ -360,6 +362,8 @@
 				default:
 					break;
 				}
+				// Adjust according to current scroll position
+				itemEntry->x -= planeOffsetX;
 
 				uint16 useInsetRect = readSelectorValue(_segMan, itemEntry->object, SELECTOR(useInsetRect));
 				if (useInsetRect) {

Modified: scummvm/trunk/engines/sci/graphics/picture.cpp
===================================================================
--- scummvm/trunk/engines/sci/graphics/picture.cpp	2010-07-26 09:34:15 UTC (rev 51307)
+++ scummvm/trunk/engines/sci/graphics/picture.cpp	2010-07-26 12:20:07 UTC (rev 51308)
@@ -117,7 +117,7 @@
 
 	// display Cel-data
 	if (has_cel)
-		drawCelData(inbuffer, size, cel_headerPos, cel_RlePos, cel_LiteralPos, 0, 0);
+		drawCelData(inbuffer, size, cel_headerPos, cel_RlePos, cel_LiteralPos, 0, 0, 0);
 
 	// process vector data
 	drawVectorData(inbuffer + vector_dataPos, vector_size);
@@ -153,7 +153,7 @@
 	return READ_LE_UINT16(inbuffer + cel_headerPos + 36);
 }
 
-void GfxPicture::drawSci32Vga(int16 celNo, int16 callerX, int16 callerY, bool mirrored) {
+void GfxPicture::drawSci32Vga(int16 celNo, int16 drawX, int16 drawY, int16 pictureX, bool mirrored) {
 	byte *inbuffer = _resource->data;
 	int size = _resource->size;
 	int header_size = READ_LE_UINT16(inbuffer);
@@ -187,18 +187,18 @@
 	if (mirrored) {
 		// switch around relativeXpos
 		Common::Rect displayArea = _coordAdjuster->pictureGetDisplayArea();
-		callerX = displayArea.width() - callerX - READ_LE_UINT16(inbuffer + cel_headerPos + 0);
+		drawX = displayArea.width() - drawX - READ_LE_UINT16(inbuffer + cel_headerPos + 0);
 	}
 
 	cel_RlePos = READ_LE_UINT32(inbuffer + cel_headerPos + 24);
 	cel_LiteralPos = READ_LE_UINT32(inbuffer + cel_headerPos + 28);
 
-	drawCelData(inbuffer, size, cel_headerPos, cel_RlePos, cel_LiteralPos, callerX, callerY);
+	drawCelData(inbuffer, size, cel_headerPos, cel_RlePos, cel_LiteralPos, drawX, drawY, pictureX);
 	cel_headerPos += 42;
 }
 #endif
 
-void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos, int literalPos, int16 callerX, int16 callerY) {
+void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos, int literalPos, int16 drawX, int16 drawY, int16 pictureX) {
 	byte *celBitmap = NULL;
 	byte *ptr = NULL;
 	byte *headerPtr = inbuffer + headerPos;
@@ -326,54 +326,71 @@
 
 	Common::Rect displayArea = _coordAdjuster->pictureGetDisplayArea();
 
-	y = callerY + displayArea.top;
-	lastY = MIN<int16>(height + y, displayArea.bottom);
-	leftX = callerX + displayArea.left;
-	rightX = MIN<int16>(width + leftX, displayArea.right);
+	uint16 skipCelBitmapPixels = 0;
+	int16 displayWidth = width;
+	if (pictureX) {
+		// scroll position for picture active, we need to adjust drawX accordingly
+		drawX -= pictureX;
+		if (drawX < 0) {
+			skipCelBitmapPixels = -drawX;
+			displayWidth -= skipCelBitmapPixels;
+			drawX = 0;
+		}
+	}
 
-	// Change clearcolor to white, if we dont add to an existing picture. That way we will paint everything on screen
-	//  but white and that wont matter because the screen is supposed to be already white. It seems that most (if not all)
-	//  SCI1.1 games use color 0 as transparency and SCI1 games use color 255 as transparency. Sierra SCI seems to paint
-	//  the whole data to screen and wont skip over transparent pixels. So this will actually make it work like Sierra
-	if (!_addToFlag)
-		clearColor = _screen->getColorWhite();
+	if (displayWidth > 0) {
+		y = displayArea.top + drawY;
+		lastY = MIN<int16>(height + y, displayArea.bottom);
+		leftX = displayArea.left + drawX;
+		rightX = MIN<int16>(displayWidth + leftX, displayArea.right);
 
-	byte drawMask = priority == 255 ? GFX_SCREEN_MASK_VISUAL : GFX_SCREEN_MASK_VISUAL | GFX_SCREEN_MASK_PRIORITY;
+		uint16 sourcePixelSkipPerRow = 0;
+		if (width > rightX - leftX)
+			sourcePixelSkipPerRow = width - (rightX - leftX);
 
-	ptr = celBitmap;
-	if (!_mirroredFlag) {
-		// Draw bitmap to screen
-		x = leftX;
-		while (y < lastY) {
-			curByte = *ptr++;
-			if ((curByte != clearColor) && (priority >= _screen->getPriority(x, y)))
-				_screen->putPixel(x, y, drawMask, curByte, priority, 0);
+		// Change clearcolor to white, if we dont add to an existing picture. That way we will paint everything on screen
+		//  but white and that wont matter because the screen is supposed to be already white. It seems that most (if not all)
+		//  SCI1.1 games use color 0 as transparency and SCI1 games use color 255 as transparency. Sierra SCI seems to paint
+		//  the whole data to screen and wont skip over transparent pixels. So this will actually make it work like Sierra
+		if (!_addToFlag)
+			clearColor = _screen->getColorWhite();
 
-			x++;
+		byte drawMask = priority == 255 ? GFX_SCREEN_MASK_VISUAL : GFX_SCREEN_MASK_VISUAL | GFX_SCREEN_MASK_PRIORITY;
 
-			if (x >= rightX) {
-				if (width > rightX - leftX) // Skip extra pixels at the end of the row
-					ptr += width - (rightX - leftX);
-				x = leftX;
-				y++;
+		ptr = celBitmap;
+		ptr += skipCelBitmapPixels;
+		if (!_mirroredFlag) {
+			// Draw bitmap to screen
+			x = leftX;
+			while (y < lastY) {
+				curByte = *ptr++;
+				if ((curByte != clearColor) && (priority >= _screen->getPriority(x, y)))
+					_screen->putPixel(x, y, drawMask, curByte, priority, 0);
+
+				x++;
+
+				if (x >= rightX) {
+					ptr += sourcePixelSkipPerRow;
+					x = leftX;
+					y++;
+				}
 			}
-		}
-	} else {
-		// Draw bitmap to screen (mirrored)
-		x = rightX - 1;
-		while (y < lastY) {
-			curByte = *ptr++;
-			if ((curByte != clearColor) && (priority >= _screen->getPriority(x, y)))
-				_screen->putPixel(x, y, drawMask, curByte, priority, 0);
+		} else {
+			// Draw bitmap to screen (mirrored)
+			x = rightX - 1;
+			while (y < lastY) {
+				curByte = *ptr++;
+				if ((curByte != clearColor) && (priority >= _screen->getPriority(x, y)))
+					_screen->putPixel(x, y, drawMask, curByte, priority, 0);
 			
-			if (x == leftX) {
-				if (width > rightX - leftX) // Skip extra pixels at the end of the row
-					ptr += width - (rightX - leftX);
-				x = rightX;
-				y++;
+				if (x == leftX) {
+					ptr += sourcePixelSkipPerRow;
+					x = rightX;
+					y++;
+				}
+
+				x--;
 			}
-
-			x--;
 		}
 	}
 
@@ -652,7 +669,7 @@
 					vectorGetAbsCoordsNoMirror(data, curPos, x, y);
 					size = READ_LE_UINT16(data + curPos); curPos += 2;
 					_priority = pic_priority; // set global priority so the cel gets drawn using current priority as well
-					drawCelData(data, _resource->size, curPos, curPos + 8, 0, x, y);
+					drawCelData(data, _resource->size, curPos, curPos + 8, 0, x, y, 0);
 					curPos += size;
 					break;
 				case PIC_OPX_EGA_SET_PRIORITY_TABLE:
@@ -692,7 +709,7 @@
 					vectorGetAbsCoordsNoMirror(data, curPos, x, y);
 					size = READ_LE_UINT16(data + curPos); curPos += 2;
 					_priority = pic_priority; // set global priority so the cel gets drawn using current priority as well
-					drawCelData(data, _resource->size, curPos, curPos + 8, 0, x, y);
+					drawCelData(data, _resource->size, curPos, curPos + 8, 0, x, y, 0);
 					curPos += size;
 					break;
 				case PIC_OPX_VGA_PRIORITY_TABLE_EQDIST:

Modified: scummvm/trunk/engines/sci/graphics/picture.h
===================================================================
--- scummvm/trunk/engines/sci/graphics/picture.h	2010-07-26 09:34:15 UTC (rev 51307)
+++ scummvm/trunk/engines/sci/graphics/picture.h	2010-07-26 12:20:07 UTC (rev 51308)
@@ -59,14 +59,14 @@
 	int16 getSci32celY(int16 celNo);
 	int16 getSci32celX(int16 celNo);
 	int16 getSci32celPriority(int16 celNo);
-	void drawSci32Vga(int16 celNo, int16 callerX, int16 callerY, bool mirrored);
+	void drawSci32Vga(int16 celNo, int16 callerX, int16 callerY, int16 pictureX, bool mirrored);
 #endif
 
 private:
 	void initData(GuiResourceId resourceId);
 	void reset();
 	void drawSci11Vga();
-	void drawCelData(byte *inbuffer, int size, int headerPos, int rlePos, int literalPos, int16 callerX, int16 callerY);
+	void drawCelData(byte *inbuffer, int size, int headerPos, int rlePos, int literalPos, int16 drawX, int16 drawY, int16 pictureX);
 	void drawVectorData(byte *data, int size);
 	bool vectorIsNonOpcode(byte pixel);
 	void vectorGetAbsCoords(byte *data, int &curPos, int16 &x, int16 &y);


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