diff options
Diffstat (limited to 'engines/mads/msurface.cpp')
| -rw-r--r-- | engines/mads/msurface.cpp | 343 | 
1 files changed, 138 insertions, 205 deletions
diff --git a/engines/mads/msurface.cpp b/engines/mads/msurface.cpp index f768624278..40c69c0f08 100644 --- a/engines/mads/msurface.cpp +++ b/engines/mads/msurface.cpp @@ -32,37 +32,6 @@ namespace MADS {  MADSEngine *MSurface::_vm = nullptr; -MSurface::MSurface() { -	pixels = nullptr; -	_freeFlag = false; -} - -MSurface::MSurface(int width, int height) { -	pixels = nullptr; -	_freeFlag = false; -	setSize(width, height); -} - -MSurface::~MSurface() { -	if (_freeFlag) -		Graphics::Surface::free(); -} - -void MSurface::setSize(int width, int height) { -	if (_freeFlag) -		Graphics::Surface::free(); -	Graphics::Surface::create(width, height, Graphics::PixelFormat::createFormatCLUT8()); -	_freeFlag = true; -} - -void MSurface::setPixels(byte *pData, int horizSize, int vertSize) { -	_freeFlag = false; -	pixels = pData; -	w = pitch = horizSize; -	h = vertSize; -	format.bytesPerPixel = 1; -} -  int MSurface::scaleValue(int value, int scale, int err) {  	int scaled = 0;  	while (value--) { @@ -76,7 +45,6 @@ int MSurface::scaleValue(int value, int scale, int err) {  }  void MSurface::drawSprite(const Common::Point &pt, SpriteInfo &info, const Common::Rect &clipRect) { -  	enum {  		kStatusSkip,  		kStatusScale, @@ -116,8 +84,8 @@ void MSurface::drawSprite(const Common::Point &pt, SpriteInfo &info, const Commo  		return;  	int heightAmt = scaledHeight; -	byte *src = info.sprite->getData(); -	byte *dst = getBasePtr(x - info.hotX - clipX, y - info.hotY - clipY); +	const byte *src = (const byte *)info.sprite->getPixels(); +	byte *dst = (byte *)getBasePtr(x - info.hotX - clipX, y - info.hotY - clipY);  	int status = kStatusSkip;  	byte *scaledLineBuf = new byte[scaledWidth]; @@ -138,7 +106,7 @@ void MSurface::drawSprite(const Common::Point &pt, SpriteInfo &info, const Commo  				byte *lineDst = scaledLineBuf;  				int curErrX = errX;  				int width = scaledWidth; -				byte *tempSrc = src; +				const byte *tempSrc = src;  				int startX = clipX;  				while (width > 0) {  					byte pixel = *tempSrc++; @@ -201,63 +169,136 @@ void MSurface::drawSprite(const Common::Point &pt, SpriteInfo &info, const Commo  	}  	delete[] scaledLineBuf; -  } -void MSurface::empty() { -	Common::fill(getBasePtr(0, 0), getBasePtr(0, h), 0); +void MSurface::scrollX(int xAmount) { +	if (xAmount == 0) +		return; + +	byte buffer[80]; +	int direction = (xAmount > 0) ? -1 : 1; +	int xSize = ABS(xAmount); +	assert(xSize <= 80); + +	byte *srcP = (byte *)getBasePtr(0, 0); + +	for (int y = 0; y < this->h; ++y, srcP += pitch) { +		if (direction < 0) { +			// Copy area to be overwritten +			Common::copy(srcP, srcP + xSize, &buffer[0]); +			// Shift the remainder of the line over the given area +			Common::copy(srcP + xSize, srcP + this->w, srcP); +			// Move buffered area to the end of the line +			Common::copy(&buffer[0], &buffer[xSize], srcP + this->w - xSize); +		} else { +			// Copy area to be overwritten +			Common::copy_backward(srcP + this->w - xSize, srcP + this->w, &buffer[80]); +			// Shift the remainder of the line over the given area +			Common::copy_backward(srcP, srcP + this->w - xSize, srcP + this->w); +			// Move buffered area to the start of the line +			Common::copy_backward(&buffer[80 - xSize], &buffer[80], srcP + xSize); +		} +	} + +	markAllDirty();  } -void MSurface::copyFrom(MSurface *src, const Common::Rect &srcBounds, -		const Common::Point &destPos, int transparentColor) { -	// Validation of the rectangle and position -	int destX = destPos.x, destY = destPos.y; -	if ((destX >= w) || (destY >= h)) +void MSurface::scrollY(int yAmount) { +	if (yAmount == 0)  		return; -	Common::Rect copyRect = srcBounds; -	if (destX < 0) { -		copyRect.left += -destX; -		destX = 0; -	} else if (destX + copyRect.width() > w) { -		copyRect.right -= destX + copyRect.width() - w; -	} -	if (destY < 0) { -		copyRect.top += -destY; -		destY = 0; -	} else if (destY + copyRect.height() > h) { -		copyRect.bottom -= destY + copyRect.height() - h; +	int direction = (yAmount > 0) ? 1 : -1; +	int ySize = ABS(yAmount); +	assert(ySize < (this->h / 2)); +	assert(this->w == pitch); + +	int blockSize = ySize * this->w; +	byte *tempData = new byte[blockSize]; +	byte *pixelsP = (byte *)getBasePtr(0, 0); + +	if (direction > 0) { +		// Buffer the lines to be overwritten +		byte *srcP = (byte *)getBasePtr(0, this->h - ySize); +		Common::copy(srcP, srcP + (pitch * ySize), tempData); +		// Vertically shift all the lines +		Common::copy_backward(pixelsP, pixelsP + (pitch * (this->h - ySize)), +			pixelsP + (pitch * this->h)); +		// Transfer the buffered lines top the top of the screen +		Common::copy(tempData, tempData + blockSize, pixelsP); +	} else { +		// Buffer the lines to be overwritten +		Common::copy(pixelsP, pixelsP + (pitch * ySize), tempData); +		// Vertically shift all the lines +		Common::copy(pixelsP + (pitch * ySize), pixelsP + (pitch * this->h), pixelsP); +		// Transfer the buffered lines to the bottom of the screen +		Common::copy(tempData, tempData + blockSize, pixelsP + (pitch * (this->h - ySize)));  	} -	if (!copyRect.isValidRect()) -		return; +	markAllDirty(); +	delete[] tempData; +} -	// Copy the specified area +void MSurface::translate(Common::Array<RGB6> &palette) { +	for (int y = 0; y < this->h; ++y) { +		byte *pDest = (byte *)getBasePtr(0, y); + +		for (int x = 0; x < this->w; ++x, ++pDest) { +			if (*pDest < 255)	// scene 752 has some palette indices of 255 +				*pDest = palette[*pDest]._palIndex; +		} +	} -	byte *data = src->getData(); -	byte *srcPtr = data + (src->getWidth() * copyRect.top + copyRect.left); -	byte *destPtr = (byte *)pixels + (destY * getWidth()) + destX; +	markAllDirty(); +} -	for (int rowCtr = 0; rowCtr < copyRect.height(); ++rowCtr) { -		if (transparentColor == -1) { -			// No transparency, so copy line over -			Common::copy(srcPtr, srcPtr + copyRect.width(), destPtr); -		} else { -			// Copy each byte one at a time checking for the transparency color -			for (int xCtr = 0; xCtr < copyRect.width(); ++xCtr) -				if (srcPtr[xCtr] != transparentColor) destPtr[xCtr] = srcPtr[xCtr]; +void MSurface::translate(byte map[PALETTE_COUNT]) { +	for (int y = 0; y < this->h; ++y) { +		byte *pDest = (byte *)getBasePtr(0, y); + +		for (int x = 0; x < this->w; ++x, ++pDest) { +				*pDest = map[*pDest];  		} +	} + +	markAllDirty(); +} + +MSurface *MSurface::flipHorizontal() const { +	MSurface *dest = new MSurface(this->w, this->h); + +	for (int y = 0; y < this->h; ++y) { +		const byte *srcP = getBasePtr(this->w - 1, y); +		byte *destP = dest->getBasePtr(0, y); -		srcPtr += src->getWidth(); -		destPtr += getWidth(); +		for (int x = 0; x < this->w; ++x) +			*destP++ = *srcP--; +	} + +	return dest; +} + +void MSurface::copyRectTranslate(MSurface &srcSurface, const byte *paletteMap, +		const Common::Point &destPos, const Common::Rect &srcRect) { +	// Loop through the lines +	for (int yCtr = 0; yCtr < srcRect.height(); ++yCtr) { +		const byte *srcP = (const byte *)srcSurface.getBasePtr(srcRect.left, srcRect.top + yCtr); +		byte *destP = (byte *)getBasePtr(destPos.x, destPos.y + yCtr); + +		// Copy the line over +		for (int xCtr = 0; xCtr < srcRect.width(); ++xCtr, ++srcP, ++destP) { +			*destP = paletteMap[*srcP]; +		}  	} + +	addDirtyRect(Common::Rect(destPos.x, destPos.y, destPos.x + srcRect.width(), +		destPos.y + srcRect.height()));  } -void MSurface::copyFrom(MSurface *src, const Common::Point &destPos, int depth, +void MSurface::copyFrom(MSurface &src, const Common::Point &destPos, int depth,  	DepthSurface *depthSurface, int scale, bool flipped, int transparentColor) {  	int destX = destPos.x, destY = destPos.y; -	int frameWidth = src->getWidth(); -	int frameHeight = src->getHeight(); +	int frameWidth = src.w; +	int frameHeight = src.h;  	int direction = flipped ? -1 : 1;  	int highestDim = MAX(frameWidth, frameHeight); @@ -271,7 +312,8 @@ void MSurface::copyFrom(MSurface *src, const Common::Point &destPos, int depth,  			distCtr += scale;  			if (distCtr < 100) {  				lineDist[distIndex] = false; -			} else { +			} +			else {  				lineDist[distIndex] = true;  				distCtr -= 100; @@ -290,18 +332,20 @@ void MSurface::copyFrom(MSurface *src, const Common::Point &destPos, int depth,  	// Special case for quicker drawing of non-scaled images  	if (scale == 100 || scale == -1) {  		// Copy the specified area -		Common::Rect copyRect(0, 0, src->getWidth(), src->getHeight()); +		Common::Rect copyRect(0, 0, src.w, src.h);  		if (destX < 0) {  			copyRect.left += -destX;  			destX = 0; -		} else if (destX + copyRect.width() > w) { +		} +		else if (destX + copyRect.width() > w) {  			copyRect.right -= destX + copyRect.width() - w;  		}  		if (destY < 0) {  			copyRect.top += -destY;  			destY = 0; -		} else if (destY + copyRect.height() > h) { +		} +		else if (destY + copyRect.height() > h) {  			copyRect.bottom -= destY + copyRect.height() - h;  		} @@ -311,9 +355,9 @@ void MSurface::copyFrom(MSurface *src, const Common::Point &destPos, int depth,  		if (flipped)  			copyRect.moveTo(0, copyRect.top); -		byte *data = src->getData(); -		byte *srcPtr = data + (src->getWidth() * copyRect.top + copyRect.left); -		byte *destPtr = (byte *)pixels + (destY * pitch) + destX; +		byte *data = src.getPixels(); +		byte *srcPtr = data + (src.w * copyRect.top + copyRect.left); +		byte *destPtr = (byte *)getPixels() + (destY * pitch) + destX;  		if (flipped)  			srcPtr += copyRect.width() - 1; @@ -329,18 +373,18 @@ void MSurface::copyFrom(MSurface *src, const Common::Point &destPos, int depth,  					destPtr[xCtr] = *srcP;  			} -			srcPtr += src->getWidth(); -			destPtr += getWidth(); +			srcPtr += src.w; +			destPtr += this->w;  		}  		return;  	}  	// Start of draw logic for scaled sprites -	const byte *srcPixelsP = src->getData(); +	const byte *srcPixelsP = src.getPixels(); -	int destRight = this->getWidth() - 1; -	int destBottom = this->getHeight() - 1; +	int destRight = this->w - 1; +	int destBottom = this->h - 1;  	// Check x bounding area  	int spriteLeft = 0; @@ -387,7 +431,7 @@ void MSurface::copyFrom(MSurface *src, const Common::Point &destPos, int depth,  	spriteLeft = spriteLeft * direction;  	// Loop through the lines of the sprite -	for (int yp = 0, sprY = -1; yp < frameHeight; ++yp, srcPixelsP += src->pitch) { +	for (int yp = 0, sprY = -1; yp < frameHeight; ++yp, srcPixelsP += src.pitch) {  		if (!lineDist[yp])  			// Not a display line, so skip it  			continue; @@ -411,8 +455,8 @@ void MSurface::copyFrom(MSurface *src, const Common::Point &destPos, int depth,  				continue;  			// Get depth of current output pixel in depth surface -			Common::Point pt((destP - (byte *)this->pixels) % this->pitch, -				(destP - (byte *)this->pixels) / this->pitch); +			Common::Point pt((destP - (byte *)getPixels()) % this->pitch, +				(destP - (byte *)getPixels()) / this->pitch);  			int pixelDepth = (depthSurface == nullptr) ? 15 : depthSurface->getDepth(pt);  			if ((*srcP != transparentColor) && (depth <= pixelDepth)) @@ -424,119 +468,8 @@ void MSurface::copyFrom(MSurface *src, const Common::Point &destPos, int depth,  		// Move to the next destination line  		destPixelsP += this->pitch;  	} -} - -void MSurface::scrollX(int xAmount) { -	if (xAmount == 0) -		return; - -	byte buffer[80]; -	int direction = (xAmount > 0) ? -1 : 1; -	int xSize = ABS(xAmount); -	assert(xSize <= 80); - -	byte *srcP = getBasePtr(0, 0); - -	for (int y = 0; y < this->h; ++y, srcP += pitch) { -		if (direction < 0) { -			// Copy area to be overwritten -			Common::copy(srcP, srcP + xSize, &buffer[0]); -			// Shift the remainder of the line over the given area -			Common::copy(srcP + xSize, srcP + this->w, srcP); -			// Move buffered area to the end of the line -			Common::copy(&buffer[0], &buffer[xSize], srcP + this->w - xSize); -		} else { -			// Copy area to be overwritten -			Common::copy_backward(srcP + this->w - xSize, srcP + this->w, &buffer[80]); -			// Shift the remainder of the line over the given area -			Common::copy_backward(srcP, srcP + this->w - xSize, srcP + this->w); -			// Move buffered area to the start of the line -			Common::copy_backward(&buffer[80 - xSize], &buffer[80], srcP + xSize); -		} -	} -} - -void MSurface::scrollY(int yAmount) { -	if (yAmount == 0) -		return; - -	int direction = (yAmount > 0) ? 1 : -1; -	int ySize = ABS(yAmount); -	assert(ySize < (this->h / 2)); -	assert(this->w == pitch); - -	int blockSize = ySize * this->w; -	byte *tempData = new byte[blockSize]; -	byte *pixelsP = getBasePtr(0, 0); - -	if (direction > 0) { -		// Buffer the lines to be overwritten -		byte *srcP = (byte *)getBasePtr(0, this->h - ySize); -		Common::copy(srcP, srcP + (pitch * ySize), tempData); -		// Vertically shift all the lines -		Common::copy_backward(pixelsP, pixelsP + (pitch * (this->h - ySize)), -			pixelsP + (pitch * this->h)); -		// Transfer the buffered lines top the top of the screen -		Common::copy(tempData, tempData + blockSize, pixelsP); -	} else { -		// Buffer the lines to be overwritten -		Common::copy(pixelsP, pixelsP + (pitch * ySize), tempData); -		// Vertically shift all the lines -		Common::copy(pixelsP + (pitch * ySize), pixelsP + (pitch * this->h), pixelsP); -		// Transfer the buffered lines to the bottom of the screen -		Common::copy(tempData, tempData + blockSize, pixelsP + (pitch * (this->h - ySize))); -	} - -	delete[] tempData; -} - -void MSurface::translate(Common::Array<RGB6> &palette) { -	for (int y = 0; y < this->h; ++y) { -		byte *pDest = getBasePtr(0, y); - -		for (int x = 0; x < this->w; ++x, ++pDest) { -			if (*pDest < 255)	// scene 752 has some palette indices of 255 -				*pDest = palette[*pDest]._palIndex; -		} -	} -} - -void MSurface::translate(byte map[PALETTE_COUNT]) { -	for (int y = 0; y < this->h; ++y) { -		byte *pDest = getBasePtr(0, y); - -		for (int x = 0; x < this->w; ++x, ++pDest) { -				*pDest = map[*pDest]; -		} -	} -} - -MSurface *MSurface::flipHorizontal() const { -	MSurface *dest = new MSurface(this->w, this->h); - -	for (int y = 0; y < this->h; ++y) { -		const byte *srcP = getBasePtr(this->w - 1, y); -		byte *destP = dest->getBasePtr(0, y); - -		for (int x = 0; x < this->w; ++x) -			*destP++ = *srcP--; -	} - -	return dest; -} - -void MSurface::copyRectTranslate(MSurface &srcSurface, const byte *paletteMap, -		const Common::Point &destPos, const Common::Rect &srcRect) { -	// Loop through the lines -	for (int yCtr = 0; yCtr < srcRect.height(); ++yCtr) { -		const byte *srcP = srcSurface.getBasePtr(srcRect.left, srcRect.top + yCtr); -		byte *destP = getBasePtr(destPos.x, destPos.y + yCtr); -		// Copy the line over -		for (int xCtr = 0; xCtr < srcRect.width(); ++xCtr, ++srcP, ++destP) { -			*destP = paletteMap[*srcP]; -		} -	} +	addDirtyRect(Common::Rect(destX, destY, destX + frameWidth, destY + frameHeight));  }  /*------------------------------------------------------------------------*/ @@ -544,26 +477,26 @@ void MSurface::copyRectTranslate(MSurface &srcSurface, const byte *paletteMap,  int DepthSurface::getDepth(const Common::Point &pt) {  	if (_depthStyle == 2) {  		int bits = (3 - (pt.x % 4)) * 2; -		byte v = *getBasePtr(pt.x >> 2, pt.y); +		byte v = *(const byte *)getBasePtr(pt.x >> 2, pt.y);  		return v >> bits;  	} else {  		if (pt.x < 0 || pt.y < 0 || pt.x >= this->w || pt.y >= this->h)  			return 0; -		return *getBasePtr(pt.x, pt.y) & 0xF; +		return *(const byte *)getBasePtr(pt.x, pt.y) & 0xF;  	}  }  int DepthSurface::getDepthHighBit(const Common::Point &pt) {  	if (_depthStyle == 2) {  		int bits = (3 - (pt.x % 4)) * 2; -		byte v = *getBasePtr(pt.x >> 2, pt.y); +		byte v = *(const byte *)getBasePtr(pt.x >> 2, pt.y);  		return (v >> bits) & 2;  	} else {  		if (pt.x < 0 || pt.y < 0 || pt.x >= this->w || pt.y >= this->h)  			return 0; -		return *getBasePtr(pt.x, pt.y) & 0x80; +		return *(const byte *)getBasePtr(pt.x, pt.y) & 0x80;  	}  }  | 
