From c1505d6e51d008e2a482f600a960d8fe8e378f75 Mon Sep 17 00:00:00 2001 From: Andrew Kurushin Date: Thu, 21 Oct 2010 20:13:25 +0000 Subject: SAGA: unroll IsoMap::drawTile buffer copy loop; refactor Sprite::drawClip svn-id: r53677 --- engines/saga/isomap.cpp | 32 +++++++++++----- engines/saga/sprite.cpp | 98 ++++++++++++++++++++++++++++++++----------------- 2 files changed, 87 insertions(+), 43 deletions(-) (limited to 'engines') diff --git a/engines/saga/isomap.cpp b/engines/saga/isomap.cpp index 87c49047c5..197055a45d 100644 --- a/engines/saga/isomap.cpp +++ b/engines/saga/isomap.cpp @@ -831,18 +831,30 @@ void IsoMap::drawTile(uint16 tileIndex, const Point &point, const Location *loca widthCount += fgRunCount; count = 0; - while ((col < _tileClip.left) && (count < fgRunCount)) { - count++; - col++; + int colDiff = _tileClip.left - col; + if (colDiff > 0) { + if (colDiff > fgRunCount) { + colDiff = fgRunCount; + } + count = colDiff; + col += colDiff; } - while ((col < _tileClip.right) && (count < fgRunCount)) { - assert(_vm->_gfx->getBackBufferPixels() <= (byte *)(drawPointer + count)); - assert((_vm->_gfx->getBackBufferPixels() + (_vm->getDisplayInfo().width * - _vm->getDisplayInfo().height)) > (byte *)(drawPointer + count)); - drawPointer[count] = readPointer[count]; - count++; - col++; + + colDiff = _tileClip.right - col; + if (colDiff > 0) { + int countDiff = fgRunCount - count; + if (colDiff > countDiff) { + colDiff = countDiff; + } + if (colDiff > 0) { + byte *dst = (byte *)(drawPointer + count); + assert(_vm->_gfx->getBackBufferPixels() <= dst); + assert((_vm->_gfx->getBackBufferPixels() + (_vm->getDisplayInfo().width * _vm->getDisplayInfo().height)) >= (byte *)(dst + colDiff)); + memcpy(dst, (readPointer + count), colDiff); + col += colDiff; + } } + readPointer += fgRunCount; drawPointer += fgRunCount; } diff --git a/engines/saga/sprite.cpp b/engines/saga/sprite.cpp index 6d9d1b6669..53ec170914 100644 --- a/engines/saga/sprite.cpp +++ b/engines/saga/sprite.cpp @@ -204,54 +204,86 @@ void Sprite::getScaledSpriteBuffer(SpriteList &spriteList, uint spriteNumber, in } void Sprite::drawClip(const Point &spritePointer, int width, int height, const byte *spriteBuffer, bool clipToScene) { - int clipWidth; - int clipHeight; Common::Rect clipRect = clipToScene ? _vm->_scene->getSceneClip() : _vm->getDisplayClip(); - int i, j, jo, io; + int xDstOffset, yDstOffset, xSrcOffset, ySrcOffset, xDiff, yDiff, cWidth, cHeight; byte *bufRowPointer; + byte *bufPointer; const byte *srcRowPointer; + const byte *srcPointer; - bufRowPointer = _vm->_gfx->getBackBufferPixels() + _vm->_gfx->getBackBufferPitch() * spritePointer.y; - srcRowPointer = spriteBuffer; - - clipWidth = CLIP(width, 0, clipRect.right - spritePointer.x); - clipHeight = CLIP(height, 0, clipRect.bottom - spritePointer.y); + int backBufferPitch = _vm->_gfx->getBackBufferPitch(); + + //find Rects intersection + yDiff = clipRect.top - spritePointer.y; + if (yDiff > 0) { + ySrcOffset = yDiff; + yDstOffset = clipRect.top; + cHeight = height - yDiff; + } else { + ySrcOffset = 0; + yDstOffset = spritePointer.y; + cHeight = height; + } - jo = 0; - io = 0; - if (spritePointer.x < clipRect.left) { - jo = clipRect.left - spritePointer.x; + xDiff = clipRect.left - spritePointer.x; + if (xDiff > 0) { + xSrcOffset = xDiff; + xDstOffset = clipRect.left; + cWidth = width - xDiff; + } else { + xSrcOffset = 0; + xDstOffset = spritePointer.x; + cWidth = width; } - if (spritePointer.y < clipRect.top) { - io = clipRect.top - spritePointer.y; - bufRowPointer += _vm->_gfx->getBackBufferPitch() * io; - srcRowPointer += width * io; + + yDiff = yDstOffset + cHeight - clipRect.bottom; + if (yDiff > 0) { + cHeight -= yDiff; } - for (i = io; i < clipHeight; i++) { - for (j = jo; j < clipWidth; j++) { - assert(_vm->_gfx->getBackBufferPixels() <= (byte *)(bufRowPointer + j + spritePointer.x)); - assert((_vm->_gfx->getBackBufferPixels() + (_vm->getDisplayInfo().width * - _vm->getDisplayInfo().height)) > (byte *)(bufRowPointer + j + spritePointer.x)); - assert((const byte *)spriteBuffer <= (const byte *)(srcRowPointer + j)); - assert(((const byte *)spriteBuffer + (width * height)) > (const byte *)(srcRowPointer + j)); + xDiff = xDstOffset + cWidth - clipRect.right; + if (xDiff > 0) { + cWidth -= xDiff; + } - if (*(srcRowPointer + j) != 0) { - *(bufRowPointer + j + spritePointer.x) = *(srcRowPointer + j); + if ((cHeight <= 0) || (cWidth <= 0)) { + //no intersection + return; + } + bufRowPointer = _vm->_gfx->getBackBufferPixels() + backBufferPitch * yDstOffset + xDstOffset; + srcRowPointer = spriteBuffer + width * ySrcOffset + xSrcOffset; + + // validate src, dst buffers + assert(_vm->_gfx->getBackBufferPixels() <= bufRowPointer); + assert((_vm->_gfx->getBackBufferPixels() + (_vm->getDisplayInfo().width * _vm->getDisplayInfo().height)) >= + (byte *)(bufRowPointer + backBufferPitch * (cHeight - 1) + cWidth)); + assert((const byte *)spriteBuffer <= srcRowPointer); + assert(((const byte *)spriteBuffer + (width * height)) >= (const byte *)(srcRowPointer + width * (cHeight - 1) + cWidth)); + + const byte *srcPointerFinish2 = srcRowPointer + width * cHeight; + for (;;) { + srcPointer = srcRowPointer; + bufPointer = bufRowPointer; + const byte *srcPointerFinish = srcRowPointer + cWidth; + for (;;) { + if (*srcPointer != 0) { + *bufPointer = *srcPointer; + } + srcPointer++; + bufPointer++; + if (srcPointer == srcPointerFinish) { + break; } } - bufRowPointer += _vm->_gfx->getBackBufferPitch(); srcRowPointer += width; + if (srcRowPointer == srcPointerFinish2) { + break; + } + bufRowPointer += backBufferPitch; } - int x1 = MAX(spritePointer.x, 0); - int y1 = MAX(spritePointer.y, 0); - int x2 = MIN(MAX(spritePointer.x + clipWidth, 0), clipRect.right); - int y2 = MIN(MAX(spritePointer.y + clipHeight, 0), clipRect.bottom); - - if (x2 > x1 && y2 > y1) - _vm->_render->addDirtyRect(Common::Rect(x1, y1, x2, y2)); + _vm->_render->addDirtyRect(Common::Rect(xDstOffset, yDstOffset, xDstOffset + cWidth, yDstOffset + cHeight)); } void Sprite::draw(SpriteList &spriteList, uint spriteNumber, const Point &screenCoord, int scale, bool clipToScene) { -- cgit v1.2.3