diff options
author | Vincent Hamm | 2012-08-09 23:19:46 -0700 |
---|---|---|
committer | D G Turner | 2012-08-10 14:38:31 +0100 |
commit | 92b5ee0a48e7393220e7f89d58e241565e9d00af (patch) | |
tree | bbcb9af0ae5fa22beb55aa8dcc537883908982cc /engines/cine | |
parent | 571fa943106009b99a39bbe0a729f9c32afa8a9a (diff) | |
download | scummvm-rg350-92b5ee0a48e7393220e7f89d58e241565e9d00af.tar.gz scummvm-rg350-92b5ee0a48e7393220e7f89d58e241565e9d00af.tar.bz2 scummvm-rg350-92b5ee0a48e7393220e7f89d58e241565e9d00af.zip |
CINE: Fix masking in Operation Stealth.
Diffstat (limited to 'engines/cine')
-rw-r--r-- | engines/cine/gfx.cpp | 99 | ||||
-rw-r--r-- | engines/cine/gfx.h | 2 |
2 files changed, 86 insertions, 15 deletions
diff --git a/engines/cine/gfx.cpp b/engines/cine/gfx.cpp index 918d522606..b22e57400d 100644 --- a/engines/cine/gfx.cpp +++ b/engines/cine/gfx.cpp @@ -1235,14 +1235,8 @@ void OSRenderer::renderOverlay(const Common::List<overlay>::iterator &it) { break; } sprite = &g_cine->_animDataTable[g_cine->_objectTable[it->objIdx].frame]; - len = sprite->_realWidth * sprite->_height; - mask = new byte[len]; - generateMask(sprite->data(), mask, len, g_cine->_objectTable[it->objIdx].part); - remaskSprite(mask, it); - drawMaskedSprite(g_cine->_objectTable[it->objIdx], mask); - delete[] mask; + drawSprite(&(*it), sprite->data(), sprite->_realWidth, sprite->_height, _backBuffer, g_cine->_objectTable[it->objIdx].x, g_cine->_objectTable[it->objIdx].y, g_cine->_objectTable[it->objIdx].part, sprite->_bpp); break; - // game message case 2: if (it->objIdx >= g_cine->_messageTable.size()) { @@ -1290,14 +1284,6 @@ void OSRenderer::renderOverlay(const Common::List<overlay>::iterator &it) { maskBgOverlay(_bgTable[it->x].bg, sprite->data(), sprite->_realWidth, sprite->_height, _backBuffer, obj->x, obj->y); break; - // FIXME: Implement correct drawing of type 21 overlays. - // Type 21 overlays aren't just filled rectangles, I found their drawing routine - // from Operation Stealth's drawSprite routine. So they're likely some kind of sprites - // and it's just a coincidence that the oxygen meter during the first arcade sequence - // works even somehow currently. I tried the original under DOSBox and the oxygen gauge - // is a long red bar that gets shorter as the air runs out. - case 21: - // A filled rectangle: case 22: // TODO: Check it this implementation really works correctly (Some things might be wrong, needs testing). assert(it->objIdx < NUM_MAX_OBJECT); @@ -1752,6 +1738,89 @@ void drawSpriteRaw(const byte *spritePtr, const byte *maskPtr, int16 width, int1 } } +void OSRenderer::drawSprite(overlay *overlayPtr, const byte *spritePtr, int16 width, int16 height, byte *page, int16 x, int16 y, byte transparentColor, byte bpp) +{ + byte* pMask = NULL; + + // draw the mask based on next objects in the list + Common::List<overlay>::iterator it; + for (it = g_cine->_overlayList.begin(); it != g_cine->_overlayList.end(); ++it) + { + if(&(*it) == overlayPtr) + { + break; + } + } + + while(it != g_cine->_overlayList.end()) + { + overlay* pCurrentOverlay = &(*it); + if((pCurrentOverlay->type==5) || ((pCurrentOverlay->type==21) && (pCurrentOverlay->x==overlayPtr->objIdx))) + { + AnimData* sprite = &g_cine->_animDataTable[g_cine->_objectTable[it->objIdx].frame]; + + if(pMask == NULL) + { + pMask = new byte[width*height]; + + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + byte spriteColor= spritePtr[width*i+j]; + pMask[width*i+j] = spriteColor; + } + } + } + + for (int i = 0; i < sprite->_realWidth; i++) { + for (int j = 0; j < sprite->_height; j++) { + int inMaskX = (g_cine->_objectTable[it->objIdx].x+i) - x; + int inMaskY = (g_cine->_objectTable[it->objIdx].y+j) - y; + + if(inMaskX >=0 && inMaskX < width) + { + if(inMaskY >=0 && inMaskY < height) + { + if(sprite->_bpp == 1) + { + if(!sprite->getColor(i, j)) + { + pMask[inMaskY*width+inMaskX] = page[x + y * 320 + inMaskX + inMaskY * 320]; + } + } + } + } + } + } + + + } + it++; + } + + // now, draw with the mask we created + if(pMask) + { + spritePtr = pMask; + } + { + for (int i = 0; i < height; i++) { + byte *destPtr = page + x + y * 320; + destPtr += i * 320; + + for (int j = 0; j < width; j++) { + byte color= *(spritePtr++); + if ((transparentColor != color) && x + j >= 0 && x + j < 320 && i + y >= 0 && i + y < 200) { + *(destPtr++) = color; + } else { + destPtr++; + } + } + } + } + + delete[] pMask; +}; + void drawSpriteRaw2(const byte *spritePtr, byte transColor, int16 width, int16 height, byte *page, int16 x, int16 y) { int16 i, j; diff --git a/engines/cine/gfx.h b/engines/cine/gfx.h index 737c49cc36..8b21d839e4 100644 --- a/engines/cine/gfx.h +++ b/engines/cine/gfx.h @@ -223,6 +223,7 @@ private: protected: void drawSprite(const ObjectStruct &obj); + void drawSprite(overlay *overlayPtr, const byte *spritePtr, int16 width, int16 height, byte *page, int16 x, int16 y, byte transparentColor, byte bpp); int drawChar(char character, int x, int y); void drawBackground(); void renderOverlay(const Common::List<overlay>::iterator &it); @@ -291,6 +292,7 @@ void drawSpriteRaw(const byte *spritePtr, const byte *maskPtr, int16 width, int1 void gfxDrawPlainBoxRaw(int16 x1, int16 y1, int16 x2, int16 y2, byte color, byte *page); void drawSpriteRaw2(const byte *spritePtr, byte transColor, int16 width, int16 height, byte *page, int16 x, int16 y); void maskBgOverlay(const byte *spritePtr, const byte *maskPtr, int16 width, int16 height, byte *page, int16 x, int16 y); +void drawOsSprite(overlay *overlayPtr, const byte *spritePtr, int16 width, int16 height, byte *page, int16 x, int16 y, byte transparentColor, byte bpp); void fadeFromBlack(); void fadeToBlack(); |