aboutsummaryrefslogtreecommitdiff
path: root/engines/mads/msurface.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/mads/msurface.cpp')
-rw-r--r--engines/mads/msurface.cpp343
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;
}
}