diff options
author | Johannes Schickel | 2006-09-15 16:04:32 +0000 |
---|---|---|
committer | Johannes Schickel | 2006-09-15 16:04:32 +0000 |
commit | 75fd84e85a166b5871c3a30677daadef18201e00 (patch) | |
tree | 3af222b5995e256e8484a42efb9dbce336fbcb5d /engines/kyra/screen.cpp | |
parent | 0cd1f0fbf91589eab48b92bdb82d36c6646223a3 (diff) | |
download | scummvm-rg350-75fd84e85a166b5871c3a30677daadef18201e00.tar.gz scummvm-rg350-75fd84e85a166b5871c3a30677daadef18201e00.tar.bz2 scummvm-rg350-75fd84e85a166b5871c3a30677daadef18201e00.zip |
- adds dirty rect handling to the kyra engine (needs some more tests before I commit it to branch though)
- initializes an uninitiliazied variable which caused crashes from time to time
svn-id: r23878
Diffstat (limited to 'engines/kyra/screen.cpp')
-rw-r--r-- | engines/kyra/screen.cpp | 100 |
1 files changed, 89 insertions, 11 deletions
diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp index 482bc598a9..e2d22a4140 100644 --- a/engines/kyra/screen.cpp +++ b/engines/kyra/screen.cpp @@ -60,14 +60,15 @@ Screen::~Screen() { free(_unkPtr1); free(_unkPtr2); + + delete [] _dirtyRects; } bool Screen::init() { debugC(9, kDebugLevelScreen, "Screen::init()"); _disableScreen = false; - // enable this for now - _system->setFeatureState(OSystem::kFeatureAutoComputeDirtyRects, true); + _system->setFeatureState(OSystem::kFeatureAutoComputeDirtyRects, false); _system->beginGFXTransaction(); _vm->initCommonGFX(false); @@ -124,6 +125,11 @@ bool Screen::init() { memset(_unkPtr1, 0, getRectSize(1, 144)); _unkPtr2 = (uint8*)malloc(getRectSize(1, 144)); memset(_unkPtr2, 0, getRectSize(1, 144)); + + _forceFullUpdate = false; + _numDirtyRects = 0; + _dirtyRects = new Rect[kMaxDirtyRects]; + assert(_dirtyRects); return true; } @@ -133,7 +139,17 @@ void Screen::updateScreen() { if (_disableScreen) return; - _system->copyRectToScreen(getPagePtr(0), SCREEN_W, 0, 0, SCREEN_W, SCREEN_H); + if (_forceFullUpdate) { + _system->copyRectToScreen(getCPagePtr(0), SCREEN_W, 0, 0, SCREEN_W, SCREEN_H); + } else { + const byte *page0 = getCPagePtr(0); + for (int i = 0; i < _numDirtyRects; ++i) { + Rect &cur = _dirtyRects[i]; + _system->copyRectToScreen(page0 + cur.y * SCREEN_W + cur.x, SCREEN_W, cur.x, cur.y, cur.x2, cur.y2); + } + } + _forceFullUpdate = false; + _numDirtyRects = 0; //for debug reasons (needs 640x200 screen) //_system->copyRectToScreen(getPagePtr(2), SCREEN_W, 320, 0, SCREEN_W, SCREEN_H); _system->updateScreen(); @@ -142,7 +158,6 @@ void Screen::updateScreen() { uint8 *Screen::getPagePtr(int pageNum) { debugC(9, kDebugLevelScreen, "Screen::getPagePtr(%d)", pageNum); assert(pageNum < SCREEN_PAGE_NUM); - // if pageNum == 0 wholeScreenDirty return _pagePtrs[pageNum]; } @@ -155,13 +170,14 @@ const uint8 *Screen::getCPagePtr(int pageNum) const { uint8 *Screen::getPageRect(int pageNum, int x, int y, int w, int h) { debugC(9, kDebugLevelScreen, "Screen::getPageRect(%d, %d, %d, %d, %d)", pageNum, x, y, w, h); assert(pageNum < SCREEN_PAGE_NUM); - // if pageNum == 0 rectDirty(x, y, w, h) + if (pageNum == 0 || pageNum == 1) addDirtyRect(x, y, w, h); return _pagePtrs[pageNum] + y * SCREEN_W + x; } void Screen::clearPage(int pageNum) { debugC(9, kDebugLevelScreen, "Screen::clearPage(%d)", pageNum); assert(pageNum < SCREEN_PAGE_NUM); + if (pageNum == 0 || pageNum == 1) _forceFullUpdate = true; memset(getPagePtr(pageNum), 0, SCREEN_PAGE_SIZE); } @@ -175,6 +191,7 @@ int Screen::setCurPage(int pageNum) { void Screen::clearCurPage() { debugC(9, kDebugLevelScreen, "Screen::clearCurPage()"); + if (_curPage == 0 || _curPage == 1) _forceFullUpdate = true; memset(getPagePtr(_curPage), 0, SCREEN_PAGE_SIZE); } @@ -189,6 +206,8 @@ void Screen::setPagePixel(int pageNum, int x, int y, uint8 color) { debugC(9, kDebugLevelScreen, "Screen::setPagePixel(%d, %d, %d, %d)", pageNum, x, y, color); assert(pageNum < SCREEN_PAGE_NUM); assert(x >= 0 && x < SCREEN_W && y >= 0 && y < SCREEN_H); + if (pageNum == 0 || pageNum == 1) + addDirtyRect(x, y, 1, 1); _pagePtrs[pageNum][y * SCREEN_W + x] = color; } @@ -317,6 +336,7 @@ void Screen::copyToPage0(int y, int h, uint8 page, uint8 *seqBuf) { seqBuf += SCREEN_W; dstPage += SCREEN_W; } + addDirtyRect(0, y, SCREEN_W, h); } void Screen::copyRegion(int x1, int y1, int x2, int y2, int w, int h, int srcPage, int dstPage, int flags) { @@ -352,6 +372,9 @@ void Screen::copyRegion(int x1, int y1, int x2, int y2, int w, int h, int srcPag const uint8 *src = getPagePtr(srcPage) + y1 * SCREEN_W + x1; assert(x2 + w <= SCREEN_W && y2 + h <= SCREEN_H); uint8 *dst = getPagePtr(dstPage) + y2 * SCREEN_W + x2; + + if (dstPage == 0 || dstPage == 1) + addDirtyRect(x2, y2, w, h); if (flags & CR_X_FLIPPED) { while (h--) { @@ -391,12 +414,18 @@ void Screen::copyPage(uint8 srcPage, uint8 dstPage) { uint8 *src = getPagePtr(srcPage); uint8 *dst = getPagePtr(dstPage); memcpy(dst, src, SCREEN_W * SCREEN_H); + + if (dstPage == 0 || dstPage == 1) _forceFullUpdate = true; } void Screen::copyBlockToPage(int pageNum, int x, int y, int w, int h, const uint8 *src) { debugC(9, kDebugLevelScreen, "Screen::copyBlockToPage(%d, %d, %d, %d, %d, %p)", pageNum, x, y, w, h, (const void *)src); assert(x >= 0 && x < Screen::SCREEN_W && y >= 0 && y < Screen::SCREEN_H); uint8 *dst = getPagePtr(pageNum) + y * SCREEN_W + x; + + if (pageNum == 0 || pageNum == 1) + addDirtyRect(x, y, w, h); + while (h--) { memcpy(dst, src, w); dst += SCREEN_W; @@ -423,6 +452,10 @@ void Screen::copyFromCurPageBlock(int x, int y, int w, int h, const uint8 *src) h = 200 - y; } uint8 *dst = getPagePtr(_curPage) + y * SCREEN_W + x * 8; + + if (_curPage == 0 || _curPage == 1) + addDirtyRect(x*8, y, w*8, h); + while (h--) { memcpy(dst, src, w*8); dst += SCREEN_W; @@ -498,6 +531,8 @@ void Screen::shuffleScreen(int sx, int sy, int w, int h, int srcPage, int dstPag setPagePixel(dstPage, i, j, color); } } + // forcing full update for now + _forceFullUpdate = true; updateScreen(); now = (int32)_system->getMillis(); wait = ticks * _vm->tickLength() - (now - start); @@ -518,6 +553,10 @@ void Screen::fillRect(int x1, int y1, int x2, int y2, uint8 color, int pageNum) pageNum = _curPage; } uint8 *dst = getPagePtr(pageNum) + y1 * SCREEN_W + x1; + + if (pageNum == 0 || pageNum == 1) + addDirtyRect(x1, y1, x2-x1+1, y2-y1+1); + for (; y1 <= y2; ++y1) { memset(dst, color, x2 - x1 + 1); dst += SCREEN_W; @@ -584,12 +623,12 @@ void Screen::drawClippedLine(int x1, int y1, int x2, int y2, int color) { drawLine(false, x1, y1, x2 - x1 + 1, color); } -void Screen::drawLine(bool horizontal, int x, int y, int length, int color) { - debugC(9, kDebugLevelScreen, "Screen::drawLine(%i, %i, %i, %i, %i)", horizontal, x, y, length, color); +void Screen::drawLine(bool vertical, int x, int y, int length, int color) { + debugC(9, kDebugLevelScreen, "Screen::drawLine(%i, %i, %i, %i, %i)", vertical, x, y, length, color); uint8 *ptr = getPagePtr(_curPage) + y * SCREEN_W + x; - if (horizontal) { + if (vertical) { assert((y + length) <= SCREEN_H); int currLine = 0; while (currLine < length) { @@ -601,6 +640,9 @@ void Screen::drawLine(bool horizontal, int x, int y, int length, int color) { assert((x + length) <= SCREEN_W); memset(ptr, color, length); } + + if (_curPage == 0 || _curPage == 1) + addDirtyRect(x, y, (vertical) ? 1 : length, (vertical) ? length : 1); } void Screen::setAnimBlockPtr(int size) { @@ -801,6 +843,9 @@ void Screen::drawChar(uint8 c, int x, int y) { } dst += pitch; } + + if (_curPage == 0 || _curPage == 1) + addDirtyRect(x, y, charWidth, *(fnt->fontData + fnt->charSizeOffset + 4)); } void Screen::setScreenDim(int dim) { @@ -999,6 +1044,8 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int uint8 *dst = getPagePtr(pageNum) + y * SCREEN_W + x; uint8 *dstStart = getPagePtr(pageNum); + if (pageNum == 0 || pageNum == 1) + addDirtyRect(x, y, x2-x1, y2-y1); int scaleYTable[SCREEN_H]; assert(y1 >= 0 && y2 < SCREEN_H); @@ -1932,22 +1979,24 @@ void Screen::setMouseCursor(int x, int y, byte *shape) { _system->updateScreen(); } -void Screen::copyScreenFromRect(int x, int y, int w, int h, uint8 *ptr) { +void Screen::copyScreenFromRect(int x, int y, int w, int h, const uint8 *ptr) { debugC(9, kDebugLevelScreen, "Screen::copyScreenFromRect(%d, %d, %d, %d, %p)", x, y, w, h, (const void *)ptr); x <<= 3; w <<= 3; - uint8 *src = ptr; + const uint8 *src = ptr; uint8 *dst = &_pagePtrs[0][y * SCREEN_W + x]; for (int i = 0; i < h; ++i) { memcpy(dst, src, w); src += w; dst += SCREEN_W; } + + addDirtyRect(x, y, w, h); } void Screen::copyScreenToRect(int x, int y, int w, int h, uint8 *ptr) { debugC(9, kDebugLevelScreen, "Screen::copyScreenToRect(%d, %d, %d, %d, %p)", x, y, w, h, (const void *)ptr); x <<= 3; w <<= 3; - uint8 *src = &_pagePtrs[0][y * SCREEN_W + x]; + const uint8 *src = &_pagePtrs[0][y * SCREEN_W + x]; uint8 *dst = ptr; for (int i = 0; i < h; ++i) { memcpy(dst, src, w); @@ -2228,6 +2277,8 @@ void Screen::loadBitmap(const char *filename, int tempPage, int dstPage, uint8 * uint8 *srcPtr = srcData + 10 + palSize; uint8 *dstData = getPagePtr(dstPage); + if (dstPage == 0 || tempPage == 0) + _forceFullUpdate = true; switch (compType) { case 0: @@ -2279,4 +2330,31 @@ uint16 Screen::getShapeSize(const uint8 *shp) { return READ_LE_UINT16(shp+6); } +// dirty rect handling + +void Screen::addDirtyRect(int x, int y, int w, int h) { + if (_numDirtyRects == kMaxDirtyRects || _forceFullUpdate) { + _forceFullUpdate = true; + return; + } + + if (w == 0 || h == 0) + return; + + if (x < 0) + x = 0; + if (x + w >= 320) + w = 320 - x; + if (y < 0) + y = 0; + if (y + h >= 200) + h = 200 - y; + + Rect &cur = _dirtyRects[_numDirtyRects++]; + cur.x = x; + cur.x2 = w; + cur.y = y; + cur.y2 = h; +} + } // End of namespace Kyra |