From 5d9c8b7c47d17015048ac3f7650de0fbe426173a Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Thu, 4 Dec 2008 18:38:55 +0000 Subject: Changing the GobEngine to use its dirty rects also for OSystem-copies, instead of relying on kFeatureAutoComputeDirtyRects svn-id: r35239 --- engines/gob/draw.cpp | 35 +++++++++++++++--- engines/gob/draw.h | 3 ++ engines/gob/draw_v1.cpp | 87 +++++++++++++------------------------------- engines/gob/draw_v2.cpp | 75 ++++++++++++-------------------------- engines/gob/game.cpp | 4 ++ engines/gob/gob.cpp | 5 --- engines/gob/inter_bargon.cpp | 6 ++- engines/gob/inter_v2.cpp | 2 + engines/gob/video.cpp | 59 +++++++++++++++++++++++++++--- engines/gob/video.h | 11 ++++++ engines/gob/videoplayer.cpp | 4 +- 11 files changed, 160 insertions(+), 131 deletions(-) (limited to 'engines') diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp index 7136646018..9b160d818c 100644 --- a/engines/gob/draw.cpp +++ b/engines/gob/draw.cpp @@ -135,8 +135,10 @@ Draw::Draw(GobEngine *vm) : _vm(vm) { } void Draw::invalidateRect(int16 left, int16 top, int16 right, int16 bottom) { - if (_renderFlags & RENDERFLAG_NOINVALIDATE) + if (_renderFlags & RENDERFLAG_NOINVALIDATE) { + _vm->_video->dirtyRectsAll(); return; + } if (left > right) SWAP(left, right); @@ -262,6 +264,8 @@ void Draw::blitInvalidated() { _invalidatedLefts[i], _invalidatedTops[i], _invalidatedRights[i], _invalidatedBottoms[i], _invalidatedLefts[i], _invalidatedTops[i], 0); + _vm->_video->dirtyRectsAdd(_invalidatedLefts[i], _invalidatedTops[i], + _invalidatedRights[i], _invalidatedBottoms[i]); } _vm->_video->_doRangeClamp = true; @@ -287,6 +291,21 @@ void Draw::clearPalette() { } } +void Draw::dirtiedRect(int16 surface, + int16 left, int16 top, int16 right, int16 bottom) { + + dirtiedRect(_spritesArray[surface], left, top, right, bottom); +} + +void Draw::dirtiedRect(SurfaceDesc::Ptr surface, + int16 left, int16 top, int16 right, int16 bottom) { + + if (surface == _backSurface) + invalidateRect(left, top, right, bottom); + else if (surface == _frontSurface) + _vm->_video->dirtyRectsAdd(left, top, right, bottom); +} + void Draw::initSpriteSurf(int16 index, int16 width, int16 height, int16 flags) { @@ -432,14 +451,16 @@ void Draw::forceBlit(bool backwards) { if (_spritesArray[21] != _backSurface) return; - if (backwards) - _vm->_video->drawSprite(_frontSurface, _backSurface, 0, 0, - _frontSurface->getWidth() - 1, _frontSurface->getHeight() - 1, - 0, 0, 0); - else + if (!backwards) { _vm->_video->drawSprite(_backSurface, _frontSurface, 0, 0, _backSurface->getWidth() - 1, _backSurface->getHeight() - 1, 0, 0, 0); + _vm->_video->dirtyRectsAll(); + } else + _vm->_video->drawSprite(_frontSurface, _backSurface, 0, 0, + _frontSurface->getWidth() - 1, _frontSurface->getHeight() - 1, + 0, 0, 0); + } const int16 Draw::_wobbleTable[360] = { @@ -513,6 +534,7 @@ void Draw::wobble(SurfaceDesc *surfDesc) { 0, y, _vm->_width - 1, y, offsets[y], y, 0); _vm->_palAnim->fadeStep(0); + _vm->_video->dirtyRectsAll(); _vm->_video->waitRetrace(); } @@ -522,6 +544,7 @@ void Draw::wobble(SurfaceDesc *surfDesc) { _applyPal = false; _invalidatedCount = 0; _noInvalidated = true; + _vm->_video->dirtyRectsAll(); delete[] offsets; } diff --git a/engines/gob/draw.h b/engines/gob/draw.h index 897208a42d..cf1675f587 100644 --- a/engines/gob/draw.h +++ b/engines/gob/draw.h @@ -137,6 +137,9 @@ public: void setPalette(); void clearPalette(); + void dirtiedRect(int16 surface, int16 left, int16 top, int16 right, int16 bottom); + void dirtiedRect(SurfaceDesc::Ptr surface, int16 left, int16 top, int16 right, int16 bottom); + void initSpriteSurf(int16 index, int16 width, int16 height, int16 flags); void freeSprite(int16 index) { assert(index < SPRITES_COUNT); diff --git a/engines/gob/draw_v1.cpp b/engines/gob/draw_v1.cpp index b5bc56b6f5..8a5ac021eb 100644 --- a/engines/gob/draw_v1.cpp +++ b/engines/gob/draw_v1.cpp @@ -362,20 +362,15 @@ void Draw_v1::spriteOperation(int16 operation) { _spriteTop + _spriteBottom - 1, _destSpriteX, _destSpriteY, _transparency); - if (_destSurface == 21) { - invalidateRect(_destSpriteX, _destSpriteY, - _destSpriteX + _spriteRight - 1, - _destSpriteY + _spriteBottom - 1); - } + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, + _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1); break; case DRAW_PUTPIXEL: _vm->_video->putPixel(_destSpriteX, _destSpriteY, _frontColor, _spritesArray[_destSurface]); - if (_destSurface == 21) { - invalidateRect(_destSpriteX, _destSpriteY, - _destSpriteX, _destSpriteY); - } + + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _destSpriteX, _destSpriteY); break; case DRAW_FILLRECT: @@ -384,11 +379,8 @@ void Draw_v1::spriteOperation(int16 operation) { _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1, _backColor); - if (_destSurface == 21) { - invalidateRect(_destSpriteX, _destSpriteY, - _destSpriteX + _spriteRight - 1, - _destSpriteY + _spriteBottom - 1); - } + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, + _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1); break; case DRAW_DRAWLINE: @@ -396,19 +388,12 @@ void Draw_v1::spriteOperation(int16 operation) { _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); - if (_destSurface == 21) { - invalidateRect(_destSpriteX, _destSpriteY, - _spriteRight, _spriteBottom); - } + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom); break; case DRAW_INVALIDATE: - if (_destSurface == 21) { - invalidateRect(_destSpriteX - _spriteRight, - _destSpriteY - _spriteBottom, - _destSpriteX + _spriteRight, - _destSpriteY + _spriteBottom); - } + dirtiedRect(_destSurface, _destSpriteX - _spriteRight, _destSpriteY - _spriteBottom, + _destSpriteX + _spriteRight, _destSpriteY + _spriteBottom); break; case DRAW_LOADSPRITE: @@ -420,11 +405,8 @@ void Draw_v1::spriteOperation(int16 operation) { _spriteRight, _spriteBottom, _destSpriteX, _destSpriteY, _transparency, _spritesArray[_destSurface]); - if (_destSurface == 21) { - invalidateRect(_destSpriteX, _destSpriteY, - _destSpriteX + _spriteRight - 1, - _destSpriteY + _spriteBottom - 1); - } + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, + _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1); delete[] dataBuf; break; } else if (id >= _vm->_game->_totResourceTable->itemsCount) { @@ -451,20 +433,15 @@ void Draw_v1::spriteOperation(int16 operation) { _destSpriteX, _destSpriteY, _transparency, _spritesArray[_destSurface]); - if (_destSurface == 21) { - invalidateRect(_destSpriteX, _destSpriteY, - _destSpriteX + _spriteRight - 1, - _destSpriteY + _spriteBottom - 1); - } + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, + _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1); break; case DRAW_PRINTTEXT: len = strlen(_textToPrint); - if (_destSurface == 21) { - invalidateRect(_destSpriteX, _destSpriteY, - _destSpriteX + len * _fonts[_fontIndex]->itemWidth - 1, - _destSpriteY + _fonts[_fontIndex]->itemHeight - 1); - } + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, + _destSpriteX + len * _fonts[_fontIndex]->itemWidth - 1, + _destSpriteY + _fonts[_fontIndex]->itemHeight - 1); for (int i = 0; i < len; i++) { _vm->_video->drawLetter(_textToPrint[i], @@ -495,10 +472,7 @@ void Draw_v1::spriteOperation(int16 operation) { _destSpriteX, _destSpriteY, _spriteRight, _destSpriteY, _frontColor); - if (_destSurface == 21) { - invalidateRect(_destSpriteX, _destSpriteY, - _spriteRight, _spriteBottom); - } + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom); break; case DRAW_CLEARRECT: @@ -508,10 +482,7 @@ void Draw_v1::spriteOperation(int16 operation) { _spriteRight, _spriteBottom, _backColor); } - if (_destSurface == 21) { - invalidateRect(_destSpriteX, _destSpriteY, - _spriteRight, _spriteBottom); - } + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom); break; case DRAW_FILLRECTABS: @@ -519,20 +490,14 @@ void Draw_v1::spriteOperation(int16 operation) { _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor); - if (_destSurface == 21) { - invalidateRect(_destSpriteX, _destSpriteY, - _spriteRight, _spriteBottom); - } + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom); break; case DRAW_DRAWLETTER: if (_fontToSprite[_fontIndex].sprite == -1) { - if (_destSurface == 21) { - invalidateRect(_destSpriteX, - _destSpriteY, - _destSpriteX + _fonts[_fontIndex]->itemWidth - 1, - _destSpriteY + _fonts[_fontIndex]->itemHeight - 1); - } + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, + _destSpriteX + _fonts[_fontIndex]->itemWidth - 1, + _destSpriteY + _fonts[_fontIndex]->itemHeight - 1); _vm->_video->drawLetter(_letterToPrint, _destSpriteX, _destSpriteY, _fonts[_fontIndex], @@ -552,11 +517,9 @@ void Draw_v1::spriteOperation(int16 operation) { x = (_letterToPrint - _fontToSprite[_fontIndex].base) % perLine * _fontToSprite[_fontIndex].width; - if (_destSurface == 21) { - invalidateRect(_destSpriteX, _destSpriteY, - _destSpriteX + _fontToSprite[_fontIndex].width, - _destSpriteY + _fontToSprite[_fontIndex].height); - } + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, + _destSpriteX + _fontToSprite[_fontIndex].width, + _destSpriteY + _fontToSprite[_fontIndex].height); _vm->_video->drawSprite(_spritesArray[(int16)_fontToSprite[_fontIndex].sprite], _spritesArray[_destSurface], x, y, diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp index 378ff0dcdf..db2d23ac39 100644 --- a/engines/gob/draw_v2.cpp +++ b/engines/gob/draw_v2.cpp @@ -57,6 +57,8 @@ void Draw_v2::initScreen() { _spritesArray[20] = _frontSurface; _spritesArray[21] = _backSurface; + + _vm->_video->dirtyRectsAll(); } void Draw_v2::closeScreen() { @@ -715,20 +717,15 @@ void Draw_v2::spriteOperation(int16 operation) { _spriteTop + _spriteBottom - 1, _destSpriteX, _destSpriteY, _transparency); - if (_destSurface == 21) { - invalidateRect(_destSpriteX, _destSpriteY, - _destSpriteX + _spriteRight - 1, - _destSpriteY + _spriteBottom - 1); - } + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, + _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1); break; case DRAW_PUTPIXEL: _vm->_video->putPixel(_destSpriteX, _destSpriteY, _frontColor, _spritesArray[_destSurface]); - if (_destSurface == 21) { - invalidateRect(_destSpriteX, _destSpriteY, - _destSpriteX, _destSpriteY); - } + + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _destSpriteX, _destSpriteY); break; case DRAW_FILLRECT: @@ -736,11 +733,8 @@ void Draw_v2::spriteOperation(int16 operation) { _destSpriteY, _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1, _backColor); - if (_destSurface == 21) { - invalidateRect(_destSpriteX, _destSpriteY, - _destSpriteX + _spriteRight - 1, - _destSpriteY + _spriteBottom - 1); - } + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, + _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1); break; case DRAW_DRAWLINE: @@ -748,21 +742,15 @@ void Draw_v2::spriteOperation(int16 operation) { _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); - if (_destSurface == 21) { - invalidateRect(_destSpriteX, _destSpriteY, - _spriteRight, _spriteBottom); - } + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom); break; case DRAW_INVALIDATE: _vm->_video->drawCircle(_spritesArray[_destSurface], _destSpriteX, _destSpriteY, _spriteRight, _frontColor); - if (_destSurface == 21) { - invalidateRect(_destSpriteX - _spriteRight, - _destSpriteY - _spriteBottom, - _destSpriteX + _spriteRight, - _destSpriteY + _spriteBottom); - } + + dirtiedRect(_destSurface, _destSpriteX - _spriteRight, _destSpriteY - _spriteBottom, + _destSpriteX + _spriteRight, _destSpriteY + _spriteBottom); break; case DRAW_LOADSPRITE: @@ -773,11 +761,9 @@ void Draw_v2::spriteOperation(int16 operation) { _vm->_video->drawPackedSprite(dataBuf, _spriteRight, _spriteBottom, _destSpriteX, _destSpriteY, _transparency, _spritesArray[_destSurface]); - if (_destSurface == 21) { - invalidateRect(_destSpriteX, _destSpriteY, - _destSpriteX + _spriteRight - 1, - _destSpriteY + _spriteBottom - 1); - } + + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, + _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1); delete[] dataBuf; break; } @@ -800,11 +786,8 @@ void Draw_v2::spriteOperation(int16 operation) { _destSpriteX, _destSpriteY, _transparency, _spritesArray[_destSurface]); - if (_destSurface == 21) { - invalidateRect(_destSpriteX, _destSpriteY, - _destSpriteX + _spriteRight - 1, - _destSpriteY + _spriteBottom - 1); - } + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, + _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1); break; case DRAW_PRINTTEXT: @@ -863,11 +846,8 @@ void Draw_v2::spriteOperation(int16 operation) { } } - if (_destSurface == 21) { - invalidateRect(left, _destSpriteY, - _destSpriteX - 1, - _destSpriteY + _fonts[_fontIndex]->itemHeight - 1); - } + dirtiedRect(_destSurface, left, _destSpriteY, + _destSpriteX - 1, _destSpriteY + _fonts[_fontIndex]->itemHeight - 1); break; case DRAW_DRAWBAR: @@ -904,10 +884,8 @@ void Draw_v2::spriteOperation(int16 operation) { _destSpriteX, _destSpriteY, _spriteRight, _destSpriteY, _frontColor); } - if (_destSurface == 21) { - invalidateRect(_destSpriteX, _destSpriteY, - _spriteRight, _spriteBottom); - } + + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom); break; case DRAW_CLEARRECT: @@ -917,10 +895,8 @@ void Draw_v2::spriteOperation(int16 operation) { _spriteRight, _spriteBottom, _backColor); } - if (_destSurface == 21) { - invalidateRect(_destSpriteX, _destSpriteY, - _spriteRight, _spriteBottom); - } + + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom); break; case DRAW_FILLRECTABS: @@ -928,10 +904,7 @@ void Draw_v2::spriteOperation(int16 operation) { _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor); - if (_destSurface == 21) { - invalidateRect(_destSpriteX, _destSpriteY, - _spriteRight, _spriteBottom); - } + dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom); break; } diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp index b544b2c234..8a6d6b6188 100644 --- a/engines/gob/game.cpp +++ b/engines/gob/game.cpp @@ -305,12 +305,14 @@ void Game::evaluateScroll(int16 x, int16 y) { off = MIN(_vm->_draw->_cursorWidth, _vm->_draw->_scrollOffsetX); off = MAX(off / 2, 1); _vm->_draw->_scrollOffsetX -= off; + _vm->_video->dirtyRectsAll(); } else if ((y == 0) && (_vm->_draw->_scrollOffsetY > 0)) { uint16 off; off = MIN(_vm->_draw->_cursorHeight, _vm->_draw->_scrollOffsetY); off = MAX(off / 2, 1); _vm->_draw->_scrollOffsetY -= off; + _vm->_video->dirtyRectsAll(); } int16 cursorRight = x + _vm->_draw->_cursorWidth; @@ -327,6 +329,7 @@ void Game::evaluateScroll(int16 x, int16 y) { off = MAX(off / 2, 1); _vm->_draw->_scrollOffsetX += off; + _vm->_video->dirtyRectsAll(); _vm->_util->setMousePos(_vm->_width - _vm->_draw->_cursorWidth, y); } else if ((cursorBottom >= (_vm->_height - _vm->_video->_splitHeight2)) && @@ -338,6 +341,7 @@ void Game::evaluateScroll(int16 x, int16 y) { off = MAX(off / 2, 1); _vm->_draw->_scrollOffsetY += off; + _vm->_video->dirtyRectsAll(); _vm->_util->setMousePos(x, _vm->_height - _vm->_video->_splitHeight2 - _vm->_draw->_cursorHeight); diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index de369c5528..f341c3e0a8 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -254,11 +254,6 @@ Common::Error GobEngine::init() { } _global->_languageWanted = _global->_language; - // FIXME: This is the ugly way of reducing redraw overhead. It works - // well for 320x200 but it's unclear how well it will work for - // 640x480. - - g_system->setFeatureState(OSystem::kFeatureAutoComputeDirtyRects, true); return Common::kNoError; } diff --git a/engines/gob/inter_bargon.cpp b/engines/gob/inter_bargon.cpp index 0ee7dfaf24..5bb695c92b 100644 --- a/engines/gob/inter_bargon.cpp +++ b/engines/gob/inter_bargon.cpp @@ -745,10 +745,12 @@ void Inter_Bargon::oBargon_intro2(OpGobParams ¶ms) { _vm->_video->drawPackedSprite("2ille4.ims", surface); _vm->_video->drawSprite(surface, _vm->_draw->_frontSurface, 0, 0, 319, 199, 320, 0, 0); _vm->_util->setScrollOffset(320, 0); + _vm->_video->dirtyRectsAll(); _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, -2, 0); _vm->_util->longDelay(1000); for (i = 320; i >= 0; i--) { _vm->_util->setScrollOffset(i, 0); + _vm->_video->dirtyRectsAll(); if ((_vm->_game->checkKeys(&mouseX, &mouseY, &buttons, 0) == 0x11B) || _vm->shouldQuit()) { _vm->_palAnim->fade(0, -2, 0); @@ -760,8 +762,10 @@ void Inter_Bargon::oBargon_intro2(OpGobParams ¶ms) { break; } } - if (!_vm->shouldQuit()) + if (!_vm->shouldQuit()) { _vm->_util->setScrollOffset(0, 0); + _vm->_video->dirtyRectsAll(); + } surface = 0; if (VAR(57) == ((uint32) -1)) return; diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp index 3f1ffba7c1..2d370c8e7e 100644 --- a/engines/gob/inter_v2.cpp +++ b/engines/gob/inter_v2.cpp @@ -1499,6 +1499,7 @@ void Inter_v2::o2_scroll() { _vm->_draw->_scrollOffsetX = curX; _vm->_draw->_scrollOffsetY = curY; _vm->_util->setScrollOffset(); + _vm->_video->dirtyRectsAll(); } } @@ -1522,6 +1523,7 @@ void Inter_v2::o2_setScrollOffset() { _vm->_draw->_scrollOffsetX = CLIP(offsetX, 0, screenW); _vm->_draw->_scrollOffsetY = CLIP(offsetY, 0, screenH); + _vm->_video->dirtyRectsAll(); } _vm->_util->setScrollOffset(); diff --git a/engines/gob/video.cpp b/engines/gob/video.cpp index 361f8573d3..6dd159ddca 100644 --- a/engines/gob/video.cpp +++ b/engines/gob/video.cpp @@ -103,6 +103,8 @@ Video::Video(GobEngine *vm) : _vm(vm) { _curSparse = 0; _lastSparse = 0xFFFFFFFF; + + _dirtyAll = false; } char Video::initDriver(int16 vidMode) { @@ -182,8 +184,8 @@ void Video::retrace(bool mouse) { int screenWidth = MIN(_surfWidth - _scrollOffsetX, _vm->_width); int screenHeight = MIN(_surfHeight - _splitHeight2 - _scrollOffsetY, _vm->_height); - g_system->copyRectToScreen(_vm->_global->_primarySurfDesc->getVidMem() + screenOffset, - _surfWidth, screenX, screenY, screenWidth, screenHeight); + dirtyRectsApply(_scrollOffsetX, _scrollOffsetY, screenWidth, screenHeight, + screenX, screenY); if (_splitSurf) { @@ -204,13 +206,13 @@ void Video::retrace(bool mouse) { screenWidth = MIN(_surfWidth, _vm->_width); screenHeight = _splitHeight2; - g_system->copyRectToScreen(_vm->_global->_primarySurfDesc->getVidMem() + screenOffset, - _surfWidth, screenX, screenY, screenWidth, screenHeight); - + dirtyRectsApply(0, _splitStart, screenWidth, screenHeight, screenX, screenY); } + dirtyRectsClear(); g_system->updateScreen(); } + } void Video::waitRetrace(bool mouse) { @@ -481,4 +483,51 @@ void Video::setPalette(Color *palette) { _vm->_global->_pPaletteDesc->vgaPal = palBak; } +void Video::dirtyRectsClear() { + _dirtyRects.clear(); + _dirtyAll = false; +} + +void Video::dirtyRectsAll() { + _dirtyRects.clear(); + _dirtyAll = true; +} + +void Video::dirtyRectsAdd(int16 left, int16 top, int16 right, int16 bottom) { + if (_dirtyAll) + return; + + _dirtyRects.push_back(Common::Rect(left, top, right + 1, bottom + 1)); +} + +void Video::dirtyRectsApply(int left, int top, int width, int height, int x, int y) { + byte *vidMem = _vm->_global->_primarySurfDesc->getVidMem(); + + if (_dirtyAll) { + g_system->copyRectToScreen(vidMem + top * _surfWidth + left, + _surfWidth, x, y, width, height); + return; + } + + int right = left + width; + int bottom = top + height; + + Common::List::const_iterator it; + for (it = _dirtyRects.begin(); it != _dirtyRects.end(); ++it) { + int l = MAX(left, it->left); + int t = MAX(top, it->top); + int r = MIN(right, it->right); + int b = MIN(bottom, it->bottom); + int w = r - l; + int h = b - t; + + if ((w <= 0) || (h <= 0)) + continue; + + byte *v = vidMem + t * _surfWidth + l; + + g_system->copyRectToScreen(v, _surfWidth, x + (l - left), y + (t - top), w, h); + } +} + } // End of namespace Gob diff --git a/engines/gob/video.h b/engines/gob/video.h index e6baf9a67d..f539fa76e0 100644 --- a/engines/gob/video.h +++ b/engines/gob/video.h @@ -26,6 +26,9 @@ #ifndef GOB_VIDEO_H #define GOB_VIDEO_H +#include "common/list.h" +#include "common/rect.h" + #include "gob/gob.h" namespace Gob { @@ -158,6 +161,11 @@ public: void setFullPalette(PalDesc *palDesc); void setPalette(Color *palette); + void dirtyRectsClear(); + void dirtyRectsAll(); + void dirtyRectsAdd(int16 left, int16 top, int16 right, int16 bottom); + void dirtyRectsApply(int left, int top, int width, int height, int x, int y); + virtual char spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, int16 x, int16 y, int16 transp, SurfaceDesc *destDesc) = 0; @@ -168,6 +176,9 @@ public: protected: class VideoDriver *_videoDriver; + bool _dirtyAll; + Common::List _dirtyRects; + int _curSparse; uint32 _lastSparse; diff --git a/engines/gob/videoplayer.cpp b/engines/gob/videoplayer.cpp index 4ae9dfdd53..4c821d1fd5 100644 --- a/engines/gob/videoplayer.cpp +++ b/engines/gob/videoplayer.cpp @@ -583,6 +583,7 @@ bool VideoPlayer::doPlay(int16 frame, int16 breakKey, _vm->_draw->forceBlit(); _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, -2, 0); _vm->_draw->_noInvalidated = true; + _vm->_video->dirtyRectsAll(); } if ((state.flags & CoktelVideo::kStatePalette) && (palCmd > 1)) { @@ -601,7 +602,8 @@ bool VideoPlayer::doPlay(int16 frame, int16 breakKey, if (_backSurf) { _vm->_draw->invalidateRect(state.left, state.top, state.right, state.bottom); _vm->_draw->blitInvalidated(); - } + } else + _vm->_video->dirtyRectsAdd(state.left, state.top, state.right, state.bottom); _vm->_video->retrace(); -- cgit v1.2.3