diff options
| -rw-r--r-- | engines/sci/graphics/frameout.cpp | 36 | ||||
| -rw-r--r-- | engines/sci/graphics/frameout.h | 1 | ||||
| -rw-r--r-- | engines/sci/graphics/picture.cpp | 48 | ||||
| -rw-r--r-- | engines/sci/graphics/picture.h | 5 | 
4 files changed, 70 insertions, 20 deletions
diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp index 9d15c8233f..9a44f07a60 100644 --- a/engines/sci/graphics/frameout.cpp +++ b/engines/sci/graphics/frameout.cpp @@ -90,6 +90,7 @@ void GfxFrameout::kernelAddPlane(reg_t object) {  	newPlane.priority = readSelectorValue(_segMan, object, SELECTOR(priority));  	newPlane.lastPriority = 0xFFFF; // hidden  	newPlane.planeOffsetX = 0; +	newPlane.planeOffsetY = 0;  	newPlane.pictureId = 0xFFFF;  	newPlane.planePictureMirrored = false;  	newPlane.planeBack = 0; @@ -132,9 +133,14 @@ void GfxFrameout::kernelUpdatePlane(reg_t object) {  			} else {  				it->planeOffsetX = 0;  			} - -			if (it->planeRect.top < 0) +			 +			if (it->planeRect.top < 0) { +				it->planeOffsetY = -it->planeRect.top;  				it->planeRect.top = 0; +			} else { +				it->planeOffsetY = 0; +			} +  			// We get bad plane-bottom in sq6  			if (it->planeRect.right > _screen->getWidth())  				it->planeRect.right = _screen->getWidth(); @@ -447,7 +453,14 @@ void GfxFrameout::kernelFrameout() {  					continue;  				// Out of view vertically (sanity checks) -				// TODO +				int16 pictureCelStartY = itemEntry->picStartY + itemEntry->y; +				int16 pictureCelEndY = pictureCelStartY + itemEntry->picture->getSci32celHeight(itemEntry->celNo); +				int16 planeStartY = it->planeOffsetY; +				int16 planeEndY = planeStartY + it->planeRect.height(); +				if (pictureCelEndY < planeStartY) +					continue; +				if (pictureCelStartY > planeEndY) +					continue;  				int16 pictureOffsetX = it->planeOffsetX;  				int16 pictureX = itemEntry->x; @@ -460,8 +473,18 @@ void GfxFrameout::kernelFrameout() {  					}  				} -				// TODO: pictureOffsetY -				itemEntry->picture->drawSci32Vga(itemEntry->celNo, pictureX, itemEntry->y, pictureOffsetX, it->planePictureMirrored); +				int16 pictureOffsetY = it->planeOffsetY; +				int16 pictureY = itemEntry->y; +				if ((it->planeOffsetY) || (itemEntry->picStartY)) { +					if (it->planeOffsetY <= itemEntry->picStartY) { +						pictureY += itemEntry->picStartY - it->planeOffsetY; +						pictureOffsetY = 0; +					} else { +						pictureOffsetY = it->planeOffsetY - itemEntry->picStartY; +					} +				} + +				itemEntry->picture->drawSci32Vga(itemEntry->celNo, pictureX, itemEntry->y, pictureOffsetX, pictureOffsetY, it->planePictureMirrored);  //				warning("picture cel %d %d", itemEntry->celNo, itemEntry->priority);  			} else if (itemEntry->viewId != 0xFFFF) { @@ -482,6 +505,7 @@ void GfxFrameout::kernelFrameout() {  				// Adjust according to current scroll position  				itemEntry->x -= it->planeOffsetX; +				itemEntry->y -= it->planeOffsetY;  				uint16 useInsetRect = readSelectorValue(_segMan, itemEntry->object, SELECTOR(useInsetRect));  				if (useInsetRect) { @@ -504,7 +528,7 @@ void GfxFrameout::kernelFrameout() {  					Common::Rect nsRect = itemEntry->celRect;  					// Translate back to actual coordinate within scrollable plane -					nsRect.translate(it->planeOffsetX, 0); +					nsRect.translate(it->planeOffsetX, it->planeOffsetY);  					if (view->isSci2Hires()) {  						view->adjustBackUpscaledCoordinates(nsRect.top, nsRect.left); diff --git a/engines/sci/graphics/frameout.h b/engines/sci/graphics/frameout.h index 3176db25fd..160c343b05 100644 --- a/engines/sci/graphics/frameout.h +++ b/engines/sci/graphics/frameout.h @@ -32,6 +32,7 @@ struct PlaneEntry {  	uint16 priority;  	uint16 lastPriority;  	int16 planeOffsetX; +	int16 planeOffsetY;  	GuiResourceId pictureId;  	Common::Rect planeRect;  	Common::Rect planeClipRect; diff --git a/engines/sci/graphics/picture.cpp b/engines/sci/graphics/picture.cpp index dad2b77036..1c85ecddcf 100644 --- a/engines/sci/graphics/picture.cpp +++ b/engines/sci/graphics/picture.cpp @@ -132,7 +132,7 @@ void GfxPicture::drawSci11Vga() {  		_palette->createFromData(inbuffer + palette_data_ptr, size - palette_data_ptr, &palette);  		_palette->set(&palette, true); -		drawCelData(inbuffer, size, cel_headerPos, cel_RlePos, cel_LiteralPos, 0, 0, 0); +		drawCelData(inbuffer, size, cel_headerPos, cel_RlePos, cel_LiteralPos, 0, 0, 0, 0);  	}  	// process vector data @@ -148,18 +148,18 @@ int16 GfxPicture::getSci32celCount() {  	return inbuffer[2];  } -int16 GfxPicture::getSci32celY(int16 celNo) { +int16 GfxPicture::getSci32celX(int16 celNo) {  	byte *inbuffer = _resource->data;  	int header_size = READ_SCI11ENDIAN_UINT16(inbuffer);  	int cel_headerPos = header_size + 42 * celNo; -	return READ_SCI11ENDIAN_UINT16(inbuffer + cel_headerPos + 40); +	return READ_SCI11ENDIAN_UINT16(inbuffer + cel_headerPos + 38);  } -int16 GfxPicture::getSci32celX(int16 celNo) { +int16 GfxPicture::getSci32celY(int16 celNo) {  	byte *inbuffer = _resource->data;  	int header_size = READ_SCI11ENDIAN_UINT16(inbuffer);  	int cel_headerPos = header_size + 42 * celNo; -	return READ_SCI11ENDIAN_UINT16(inbuffer + cel_headerPos + 38); +	return READ_SCI11ENDIAN_UINT16(inbuffer + cel_headerPos + 40);  }  int16 GfxPicture::getSci32celWidth(int16 celNo) { @@ -169,6 +169,14 @@ int16 GfxPicture::getSci32celWidth(int16 celNo) {  	return READ_SCI11ENDIAN_UINT16(inbuffer + cel_headerPos + 0);  } +int16 GfxPicture::getSci32celHeight(int16 celNo) { +	byte *inbuffer = _resource->data; +	int header_size = READ_SCI11ENDIAN_UINT16(inbuffer); +	int cel_headerPos = header_size + 42 * celNo; +	return READ_SCI11ENDIAN_UINT16(inbuffer + cel_headerPos + 2); +} + +  int16 GfxPicture::getSci32celPriority(int16 celNo) {  	byte *inbuffer = _resource->data;  	int header_size = READ_SCI11ENDIAN_UINT16(inbuffer); @@ -176,7 +184,7 @@ int16 GfxPicture::getSci32celPriority(int16 celNo) {  	return READ_SCI11ENDIAN_UINT16(inbuffer + cel_headerPos + 36);  } -void GfxPicture::drawSci32Vga(int16 celNo, int16 drawX, int16 drawY, int16 pictureX, bool mirrored) { +void GfxPicture::drawSci32Vga(int16 celNo, int16 drawX, int16 drawY, int16 pictureX, int16 pictureY, bool mirrored) {  	byte *inbuffer = _resource->data;  	int size = _resource->size;  	int header_size = READ_SCI11ENDIAN_UINT16(inbuffer); @@ -216,14 +224,14 @@ void GfxPicture::drawSci32Vga(int16 celNo, int16 drawX, int16 drawY, int16 pictu  	cel_RlePos = READ_SCI11ENDIAN_UINT32(inbuffer + cel_headerPos + 24);  	cel_LiteralPos = READ_SCI11ENDIAN_UINT32(inbuffer + cel_headerPos + 28); -	drawCelData(inbuffer, size, cel_headerPos, cel_RlePos, cel_LiteralPos, drawX, drawY, pictureX); +	drawCelData(inbuffer, size, cel_headerPos, cel_RlePos, cel_LiteralPos, drawX, drawY, pictureX, pictureY);  	cel_headerPos += 42;  }  #endif  extern void unpackCelData(byte *inBuffer, byte *celBitmap, byte clearColor, int pixelCount, int rlePos, int literalPos, ViewType viewType, uint16 width, bool isMacSci11ViewData); -void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos, int literalPos, int16 drawX, int16 drawY, int16 pictureX) { +void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos, int literalPos, int16 drawX, int16 drawY, int16 pictureX, int16 pictureY) {  	byte *celBitmap = NULL;  	byte *ptr = NULL;  	byte *headerPtr = inbuffer + headerPos; @@ -300,10 +308,11 @@ void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos  	Common::Rect displayArea = _coordAdjuster->pictureGetDisplayArea(); +	// Horizontal clipping  	uint16 skipCelBitmapPixels = 0;  	int16 displayWidth = width;  	if (pictureX) { -		// scroll position for picture active, we need to adjust drawX accordingly +		// horizontal scroll position for picture active, we need to adjust drawX accordingly  		drawX -= pictureX;  		if (drawX < 0) {  			skipCelBitmapPixels = -drawX; @@ -312,7 +321,21 @@ void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos  		}  	} -	if (displayWidth > 0) { +	// Vertical clipping +	uint16 skipCelBitmapLines = 0; +	int16 displayHeight = height; +	if (pictureY) { +		// vertical scroll position for picture active, we need to adjust drawY accordingly +		// TODO: Finish this +		/*drawY -= pictureY; +		if (drawY < 0) { +			skipCelBitmapLines = -drawY; +			displayHeight -= skipCelBitmapLines; +			drawY = 0; +		}*/ +	} + +	if (displayWidth > 0 && displayHeight > 0) {  		y = displayArea.top + drawY;  		lastY = MIN<int16>(height + y, displayArea.bottom);  		leftX = displayArea.left + drawX; @@ -334,6 +357,7 @@ void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos  		ptr = celBitmap;  		ptr += skipCelBitmapPixels; +		ptr += skipCelBitmapLines * width;  		if (!_mirroredFlag) {  			// Draw bitmap to screen  			x = leftX; @@ -714,7 +738,7 @@ void GfxPicture::drawVectorData(byte *data, int dataSize) {  					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, 0); +					drawCelData(data, _resource->size, curPos, curPos + 8, 0, x, y, 0, 0);  					curPos += size;  					break;  				case PIC_OPX_EGA_SET_PRIORITY_TABLE: @@ -757,7 +781,7 @@ void GfxPicture::drawVectorData(byte *data, int dataSize) {  					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, 0); +					drawCelData(data, _resource->size, curPos, curPos + 8, 0, x, y, 0, 0);  					curPos += size;  					break;  				case PIC_OPX_VGA_PRIORITY_TABLE_EQDIST: diff --git a/engines/sci/graphics/picture.h b/engines/sci/graphics/picture.h index 78623d5e09..4f075a6226 100644 --- a/engines/sci/graphics/picture.h +++ b/engines/sci/graphics/picture.h @@ -56,15 +56,16 @@ public:  	int16 getSci32celY(int16 celNo);  	int16 getSci32celX(int16 celNo);  	int16 getSci32celWidth(int16 celNo); +	int16 getSci32celHeight(int16 celNo);  	int16 getSci32celPriority(int16 celNo); -	void drawSci32Vga(int16 celNo, int16 callerX, int16 callerY, int16 pictureX, bool mirrored); +	void drawSci32Vga(int16 celNo, int16 callerX, int16 callerY, int16 pictureX, int16 pictureY, 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 drawX, int16 drawY, int16 pictureX); +	void drawCelData(byte *inbuffer, int size, int headerPos, int rlePos, int literalPos, int16 drawX, int16 drawY, int16 pictureX, int16 pictureY);  	void drawVectorData(byte *data, int size);  	bool vectorIsNonOpcode(byte pixel);  	void vectorGetAbsCoords(byte *data, int &curPos, int16 &x, int16 &y);  | 
