aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/gob/indeo3.cpp6
-rw-r--r--engines/gob/indeo3.h1
-rw-r--r--engines/gob/inter.h1
-rw-r--r--engines/gob/inter_v6.cpp41
-rw-r--r--engines/gob/video.h8
-rw-r--r--engines/gob/video_v6.cpp66
6 files changed, 121 insertions, 2 deletions
diff --git a/engines/gob/indeo3.cpp b/engines/gob/indeo3.cpp
index a0ad509817..8f439626fe 100644
--- a/engines/gob/indeo3.cpp
+++ b/engines/gob/indeo3.cpp
@@ -137,6 +137,12 @@ inline int PaletteLUT::getIndex(byte c1, byte c2, byte c3) const {
return ((c1 >> _shift) << _depth2) | ((c2 >> _shift) << _depth1) | (c3 >> _shift);
}
+void PaletteLUT::getEntry(byte index, byte &c1, byte &c2, byte &c3) const {
+ c1 = _realPal[index * 3 + 0];
+ c2 = _realPal[index * 3 + 1];
+ c3 = _realPal[index * 3 + 2];
+}
+
byte PaletteLUT::findNearest(byte c1, byte c2, byte c3) {
return _lut[getIndex(c1, c2, c3)];
}
diff --git a/engines/gob/indeo3.h b/engines/gob/indeo3.h
index ae19b1cc1c..6cedecc2af 100644
--- a/engines/gob/indeo3.h
+++ b/engines/gob/indeo3.h
@@ -60,6 +60,7 @@ public:
void buildNext();
+ void getEntry(byte index, byte &c1, byte &c2, byte &c3) const;
byte findNearest(byte c1, byte c2, byte c3);
byte findNearest(byte c1, byte c2, byte c3, byte &nC1, byte &nC2, byte &nC3);
diff --git a/engines/gob/inter.h b/engines/gob/inter.h
index 5670e2f0da..cd59b0a596 100644
--- a/engines/gob/inter.h
+++ b/engines/gob/inter.h
@@ -630,6 +630,7 @@ protected:
bool o6_evaluateStore(OpFuncParams &params);
bool o6_palLoad(OpFuncParams &params);
bool o6_freeCollision(OpFuncParams &params);
+ bool o6_fillRect(OpFuncParams &params);
void probe16bitMusic(char *fileName);
};
diff --git a/engines/gob/inter_v6.cpp b/engines/gob/inter_v6.cpp
index a1ae180068..fa21e4d0ba 100644
--- a/engines/gob/inter_v6.cpp
+++ b/engines/gob/inter_v6.cpp
@@ -439,7 +439,7 @@ void Inter_v6::setupOpcodes() {
OPCODE(o1_returnTo),
OPCODE(o1_loadSpriteContent),
OPCODE(o1_copySprite),
- OPCODE(o1_fillRect),
+ OPCODE(o6_fillRect),
/* 34 */
OPCODE(o1_drawLine),
OPCODE(o1_strToLong),
@@ -947,6 +947,45 @@ bool Inter_v6::o6_freeCollision(OpFuncParams &params) {
return false;
}
+bool Inter_v6::o6_fillRect(OpFuncParams &params) {
+ int16 destSurf;
+
+ _vm->_draw->_destSurface = destSurf = load16();
+
+ _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr();
+ _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr();
+ _vm->_draw->_spriteRight = _vm->_parse->parseValExpr();
+ _vm->_draw->_spriteBottom = _vm->_parse->parseValExpr();
+
+ evalExpr(0);
+
+ _vm->_draw->_backColor = _vm->_global->_inter_resVal & 0xFFFF;
+ uint16 word_63E64 = _vm->_global->_inter_resVal >> 16;
+
+ if (word_63E64 != 0)
+ warning("Urban Stub: o6_fillRect(), word_63E64 = %d", word_63E64);
+
+ if (_vm->_draw->_spriteRight < 0) {
+ _vm->_draw->_destSpriteX += _vm->_draw->_spriteRight - 1;
+ _vm->_draw->_spriteRight = -_vm->_draw->_spriteRight + 2;
+ }
+ if (_vm->_draw->_spriteBottom < 0) {
+ _vm->_draw->_destSpriteY += _vm->_draw->_spriteBottom - 1;
+ _vm->_draw->_spriteBottom = -_vm->_draw->_spriteBottom + 2;
+ }
+
+ if (destSurf & 0x80) {
+ warning("Urban Stub: o6_fillRect(), destSurf & 0x80");
+ return false;
+ }
+
+ if (!_vm->_draw->_spritesArray[(destSurf > 100) ? (destSurf - 80) : destSurf])
+ return false;
+
+ _vm->_draw->spriteOperation(DRAW_FILLRECT);
+ return false;
+}
+
void Inter_v6::probe16bitMusic(char *fileName) {
int len = strlen(fileName);
diff --git a/engines/gob/video.h b/engines/gob/video.h
index 0afd2b31e2..4826c9ef84 100644
--- a/engines/gob/video.h
+++ b/engines/gob/video.h
@@ -137,7 +137,7 @@ public:
void sparseRetrace(int max);
void putPixel(int16 x, int16 y, int16 color, SurfaceDesc *dest);
- void fillRect(SurfaceDesc *dest, int16 left, int16 top,
+ virtual void fillRect(SurfaceDesc *dest, int16 left, int16 top,
int16 right, int16 bottom, int16 color);
void drawLine(SurfaceDesc *dest, int16 x0, int16 y0, int16 x1, int16 y1,
int16 color);
@@ -223,6 +223,9 @@ public:
virtual char spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight,
int16 x, int16 y, int16 transp, SurfaceDesc *destDesc);
+ virtual void fillRect(SurfaceDesc *dest, int16 left, int16 top,
+ int16 right, int16 bottom, int16 color);
+
virtual void init();
Video_v6(GobEngine *vm);
@@ -231,6 +234,9 @@ public:
private:
static const byte _ditherPalette[768];
+ void shadeRect(SurfaceDesc *dest,
+ int16 left, int16 top, int16 right, int16 bottom, byte color, byte strength);
+
void drawPacked(const byte *sprBuf, int16 x, int16 y, SurfaceDesc *surfDesc);
void drawYUVData(const byte *srcData, SurfaceDesc *destDesc,
int16 width, int16 height, int16 x, int16 y);
diff --git a/engines/gob/video_v6.cpp b/engines/gob/video_v6.cpp
index 8e49a04ff4..d90b623947 100644
--- a/engines/gob/video_v6.cpp
+++ b/engines/gob/video_v6.cpp
@@ -66,6 +66,72 @@ char Video_v6::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight,
return 1;
}
+void Video_v6::fillRect(SurfaceDesc *dest,
+ int16 left, int16 top, int16 right, int16 bottom, int16 color) {
+
+ if (!(color & 0xFF00)) {
+ Video::fillRect(dest, left, top, right, bottom, color);
+ return;
+ }
+
+ if (!(color & 0x0100)) {
+ Video::fillRect(dest, left, top, right, bottom, color);
+ return;
+ }
+
+ if (_doRangeClamp) {
+ if (left > right)
+ SWAP(left, right);
+ if (top > bottom)
+ SWAP(top, bottom);
+
+ if ((left >= dest->getWidth()) || (right < 0) ||
+ (top >= dest->getHeight()) || (bottom < 0))
+ return;
+
+ left = CLIP(left, (int16) 0, (int16) (dest->getWidth() - 1));
+ top = CLIP(top, (int16) 0, (int16) (dest->getHeight() - 1));
+ right = CLIP(right, (int16) 0, (int16) (dest->getWidth() - 1));
+ bottom = CLIP(bottom, (int16) 0, (int16) (dest->getHeight() - 1));
+ }
+
+ byte strength = 16 - (((uint16) color) >> 12);
+ shadeRect(dest, left, top, right, bottom, color, strength);
+}
+
+void Video_v6::shadeRect(SurfaceDesc *dest,
+ int16 left, int16 top, int16 right, int16 bottom, byte color, byte strength) {
+
+ int width = right - left + 1;
+ int height = bottom - top + 1;
+ int dWidth = dest->getWidth();
+ byte *vidMem = dest->getVidMem() + dWidth * top + left;
+ byte sY, sU, sV;
+
+ _palLUT->getEntry(color, sY, sU, sV);
+
+ SierraLight *dither = new SierraLight(width, height, _palLUT);
+
+ for (int i = 0; i < height; i++) {
+ byte *d = vidMem;
+
+ for (int j = 0; j < width; j++) {
+ byte dY, dU, dV;
+ byte dC = *d;
+
+ _palLUT->getEntry(dC, dY, dU, dV);
+
+ dY = CLIP<int>(sY + (dY >> 2), 0, 255);
+ *d++ = dither->dither(dY, sU, sV, j);
+ }
+
+ dither->nextLine();
+ vidMem += dWidth;
+ }
+
+ delete dither;
+}
+
void Video_v6::drawPacked(const byte *sprBuf, int16 x, int16 y, SurfaceDesc *surfDesc) {
const byte *data = sprBuf + 2;