aboutsummaryrefslogtreecommitdiff
path: root/engines/cine/gfx.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/cine/gfx.cpp')
-rw-r--r--engines/cine/gfx.cpp135
1 files changed, 91 insertions, 44 deletions
diff --git a/engines/cine/gfx.cpp b/engines/cine/gfx.cpp
index 8db4456485..2730a92e62 100644
--- a/engines/cine/gfx.cpp
+++ b/engines/cine/gfx.cpp
@@ -25,6 +25,7 @@
#include "cine/cine.h"
#include "cine/bg.h"
+#include "cine/bg_list.h"
#include "cine/various.h"
#include "common/endian.h"
@@ -168,7 +169,7 @@ void gfxFillSprite(const byte *spritePtr, uint16 width, uint16 height, byte *pag
byte *destPtr = page + x + y * 320;
destPtr += i * 320;
- for (j = 0; j < width * 8; j++) {
+ for (j = 0; j < width; j++) {
if (x + j >= 0 && x + j < 320 && i + y >= 0
&& i + y < 200) {
if (!*(spritePtr++)) {
@@ -191,7 +192,7 @@ void gfxDrawMaskedSprite(const byte *spritePtr, const byte *maskPtr, uint16 widt
byte *destPtr = page + x + y * 320;
destPtr += i * 320;
- for (j = 0; j < width * 8; j++) {
+ for (j = 0; j < width; j++) {
if (x + j >= 0 && x + j < 320 && i + y >= 0 && i + y < 200 && *maskPtr == 0) {
*destPtr = *spritePtr;
}
@@ -202,61 +203,82 @@ void gfxDrawMaskedSprite(const byte *spritePtr, const byte *maskPtr, uint16 widt
}
}
-void gfxUpdateSpriteMask(const byte *spritePtr, const byte *spriteMskPtr, int16 width, int16 height, const byte *maskPtr,
- int16 maskWidth, int16 maskHeight, byte *bufferSprPtr, byte *bufferMskPtr, int16 xs, int16 ys, int16 xm, int16 ym, byte maskIdx) {
+void gfxUpdateSpriteMask(byte *destMask, int16 x, int16 y, int16 width, int16 height, const byte *srcMask, int16 xm, int16 ym, int16 maskWidth, int16 maskHeight) {
int16 i, j, d, spritePitch, maskPitch;
- width *= 8;
- maskWidth *= 8;
-
spritePitch = width;
maskPitch = maskWidth;
- if (maskIdx == 0) {
- memcpy(bufferSprPtr, spritePtr, spritePitch * height);
- memcpy(bufferMskPtr, spriteMskPtr, spritePitch * height);
- }
-
- if (ys > ym) {
- d = ys - ym;
- maskPtr += d * maskPitch;
+ // crop update area to overlapping parts of masks
+ if (y > ym) {
+ d = y - ym;
+ srcMask += d * maskPitch;
maskHeight -= d;
+ } else if (y < ym) {
+ d = ym - y;
+ destMask += d * spritePitch;
+ height -= d;
}
- if (maskHeight <= 0) {
- return;
- }
- if (xs > xm) {
- d = xs - xm;
- maskPtr += d;
+
+ if (x > xm) {
+ d = x - xm;
+ srcMask += d;
maskWidth -= d;
+ } else if (x < xm) {
+ d = xm - x;
+ destMask += d;
+ width -= d;
}
- if (maskWidth <= 0) {
- return;
+
+ // update mask
+ for (j = 0; j < MIN(maskHeight, height); ++j) {
+ for (i = 0; i < MIN(maskWidth, width); ++i) {
+ destMask[i] |= srcMask[i] ^ 1;
+ }
+ destMask += spritePitch;
+ srcMask += maskPitch;
}
- if (ys < ym) {
- d = ym - ys;
- spriteMskPtr += d * spritePitch;
- bufferMskPtr += d * spritePitch;
+}
+
+void gfxUpdateIncrustMask(byte *destMask, int16 x, int16 y, int16 width, int16 height, const byte *srcMask, int16 xm, int16 ym, int16 maskWidth, int16 maskHeight) {
+ int16 i, j, d, spritePitch, maskPitch;
+
+ spritePitch = width;
+ maskPitch = maskWidth;
+
+ // crop update area to overlapping parts of masks
+ if (y > ym) {
+ d = y - ym;
+ srcMask += d * maskPitch;
+ maskHeight -= d;
+ } else if (y < ym) {
+ d = ym - y > height ? height : ym - y;
+ memset(destMask, 1, d * spritePitch);
+ destMask += d * spritePitch;
height -= d;
}
- if (height <= 0) {
- return;
- }
- if (xs < xm) {
- d = xm - xs;
- spriteMskPtr += d;
- bufferMskPtr += d;
- width -= d;
- }
- if (width <= 0) {
- return;
+
+ if (x > xm) {
+ d = x - xm;
+ xm = x;
+ srcMask += d;
+ maskWidth -= d;
}
+
+ d = xm - x;
+ maskWidth += d;
+
+ // update mask
for (j = 0; j < MIN(maskHeight, height); ++j) {
- for (i = 0; i < MIN(maskWidth, width); ++i) {
- bufferMskPtr[i] |= maskPtr[i] ^ 1;
+ for (i = 0; i < width; ++i) {
+ destMask[i] |= i < d || i >= maskWidth ? 1 : srcMask[i - d];
}
- bufferMskPtr += spritePitch;
- maskPtr += maskPitch;
+ destMask += spritePitch;
+ srcMask += maskPitch;
+ }
+
+ if (j < height) {
+ memset(destMask, 1, (height - j) * spritePitch);
}
}
@@ -431,15 +453,19 @@ void drawSpriteRaw2(const byte *spritePtr, byte transColor, int16 width, int16 h
void maskBgOverlay(const byte *bgPtr, const byte *maskPtr, int16 width, int16 height,
byte *page, int16 x, int16 y) {
- int16 i, j;
+ int16 i, j, tmpWidth, tmpHeight;
+ Common::List<BGIncrust>::iterator it;
+ byte *mask;
+ const byte *backup = maskPtr;
+ // background pass
for (i = 0; i < height; i++) {
byte *destPtr = page + x + y * 320;
const byte *srcPtr = bgPtr + x + y * 320;
destPtr += i * 320;
srcPtr += i * 320;
- for (j = 0; j < width * 8; j++) {
+ for (j = 0; j < width; j++) {
if ((!maskPtr || !(*maskPtr)) && (x + j >= 0
&& x + j < 320 && i + y >= 0 && i + y < 200)) {
*destPtr = *srcPtr;
@@ -450,6 +476,27 @@ void maskBgOverlay(const byte *bgPtr, const byte *maskPtr, int16 width, int16 he
maskPtr++;
}
}
+
+ maskPtr = backup;
+
+ // incrust pass
+ for (it = bgIncrustList.begin(); it != bgIncrustList.end(); ++it) {
+ tmpWidth = animDataTable[it->frame]._realWidth;
+ tmpHeight = animDataTable[it->frame]._height;
+ mask = (byte*)malloc(tmpWidth * tmpHeight);
+
+ if (it->param == 0) {
+ generateMask(animDataTable[it->frame].data(), mask, tmpWidth * tmpHeight, it->part);
+ gfxUpdateIncrustMask(mask, it->x, it->y, tmpWidth, tmpHeight, maskPtr, x, y, width, height);
+ gfxDrawMaskedSprite(animDataTable[it->frame].data(), mask, tmpWidth, tmpHeight, page, it->x, it->y);
+ } else {
+ memcpy(mask, animDataTable[it->frame].data(), tmpWidth * tmpHeight);
+ gfxUpdateIncrustMask(mask, it->x, it->y, tmpWidth, tmpHeight, maskPtr, x, y, width, height);
+ gfxFillSprite(mask, tmpWidth, tmpHeight, page, it->x, it->y);
+ }
+
+ free(mask);
+ }
}
/*! \todo Fix rendering to prevent fadein artifacts