diff options
-rw-r--r-- | engines/gob/indeo3.cpp | 6 | ||||
-rw-r--r-- | engines/gob/indeo3.h | 1 | ||||
-rw-r--r-- | engines/gob/inter.h | 1 | ||||
-rw-r--r-- | engines/gob/inter_v6.cpp | 41 | ||||
-rw-r--r-- | engines/gob/video.h | 8 | ||||
-rw-r--r-- | engines/gob/video_v6.cpp | 66 |
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 ¶ms); bool o6_palLoad(OpFuncParams ¶ms); bool o6_freeCollision(OpFuncParams ¶ms); + bool o6_fillRect(OpFuncParams ¶ms); 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 ¶ms) { return false; } +bool Inter_v6::o6_fillRect(OpFuncParams ¶ms) { + 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; |