From 2a6745a9862fc067a7b529feec0943ec56c79c7c Mon Sep 17 00:00:00 2001 From: Robert Göffringmann Date: Sat, 3 Jan 2004 12:29:21 +0000 Subject: changed screen drawing code to only redraw blocks that changed. svn-id: r12109 --- sword1/screen.cpp | 87 ++++++++++++++++++++++++++----------------------------- sword1/screen.h | 2 +- 2 files changed, 42 insertions(+), 47 deletions(-) (limited to 'sword1') diff --git a/sword1/screen.cpp b/sword1/screen.cpp index b85d7c4836..919e5248b9 100644 --- a/sword1/screen.cpp +++ b/sword1/screen.cpp @@ -133,7 +133,6 @@ void SwordScreen::updateScreen(void) { uint16 scrlX = (uint16)SwordLogic::_scriptVars[SCROLL_OFFSET_X]; uint16 scrlY = (uint16)SwordLogic::_scriptVars[SCROLL_OFFSET_Y]; - _fullRefresh = true; if (_fullRefresh) { _fullRefresh = false; uint16 copyWidth = SCREEN_WIDTH; @@ -155,59 +154,65 @@ void SwordScreen::updateScreen(void) { uint16 gridW = SCREEN_WIDTH / SCRNGRID_X; uint16 gridH = SCREEN_DEPTH / SCRNGRID_Y; if (diffY) { - uint8 cpHeight = SCRNGRID_Y - diffY; + diffY = SCRNGRID_Y - diffY; uint16 cpWidth = 0; for (uint16 cntx = 0; cntx < gridW; cntx++) - if (gridPos[cntx] & 1) { - gridPos[cntx] &= ~1; + if (gridPos[cntx]) { + gridPos[cntx] >>= 1; cpWidth++; } else if (cpWidth) { int16 xPos = (cntx - cpWidth) * SCRNGRID_X - diffX; if (xPos < 0) xPos = 0; - _system->copy_rect(scrnBuf + xPos, _scrnSizeX, xPos, 40, cpWidth * SCRNGRID_X, cpHeight); + _system->copy_rect(scrnBuf + xPos, _scrnSizeX, xPos, 40, cpWidth * SCRNGRID_X, diffY); cpWidth = 0; } if (cpWidth) { int16 xPos = (gridW - cpWidth) * SCRNGRID_X - diffX; if (xPos < 0) xPos = 0; - _system->copy_rect(scrnBuf + xPos, _scrnSizeX, xPos, 40, SCREEN_WIDTH - xPos, cpHeight); + _system->copy_rect(scrnBuf + xPos, _scrnSizeX, xPos, 40, SCREEN_WIDTH - xPos, diffY); } - } // okay, y scrolling is compensated. check x now. - gridPos += _gridSizeX; - scrnBuf = _screenBuf + scrlX + diffY * _scrnSizeX; + scrlY += diffY; + } + // okay, y scrolling is compensated. check x now. + gridPos = _screenGrid + (scrlX / SCRNGRID_X) + (scrlY / SCRNGRID_Y) * _gridSizeX; + scrnBuf = _screenBuf + scrlY * _scrnSizeX + scrlX; if (diffX) { - uint8 cpWidth = SCRNGRID_X - diffX; + diffX = SCRNGRID_X - diffX; uint16 cpHeight = 0; - for (uint16 cnty = 0; cnty < gridH; cnty++) - if (gridPos[cnty * SCRNGRID_X] & 1) { - gridPos[cnty * SCRNGRID_X] &= ~1; + for (uint16 cnty = 0; cnty < gridH; cnty++) { + if (*gridPos) { + *gridPos >>= 1; cpHeight++; } else if (cpHeight) { uint16 yPos = (cnty - cpHeight) * SCRNGRID_Y; - _system->copy_rect(scrnBuf + yPos * _scrnSizeX, _scrnSizeX, 0, yPos + diffY + 40, cpWidth, cpHeight * SCRNGRID_Y); + _system->copy_rect(scrnBuf + yPos * _scrnSizeX, _scrnSizeX, 0, yPos + diffY + 40, diffX, cpHeight * SCRNGRID_Y); + cpHeight = 0; } + gridPos += _gridSizeX; + } if (cpHeight) { uint16 yPos = (gridH - cpHeight) * SCRNGRID_Y; - _system->copy_rect(scrnBuf + yPos * _scrnSizeX, _scrnSizeX, 0, yPos + diffY + 40, cpWidth, SCREEN_DEPTH - (yPos + diffY)); - } - } // x scroll is compensated, too. check the rest of the screen, now. - scrlX = (scrlX + SCRNGRID_X - 1) &~ (SCRNGRID_X - 1); - scrlY = (scrlY + SCRNGRID_Y - 1) &~ (SCRNGRID_Y - 1); + _system->copy_rect(scrnBuf + yPos * _scrnSizeX, _scrnSizeX, 0, yPos + diffY + 40, diffX, SCREEN_DEPTH - (yPos + diffY)); + } + scrlX += diffX; + } + // x scroll is compensated, too. check the rest of the screen, now. scrnBuf = _screenBuf + scrlY * _scrnSizeX + scrlX; - gridPos++; + gridPos = _screenGrid + (scrlX / SCRNGRID_X) + (scrlY / SCRNGRID_Y) * _gridSizeX; for (uint16 cnty = 0; cnty < gridH; cnty++) { uint16 cpWidth = 0; uint16 cpHeight = SCRNGRID_Y; if (cnty == gridH - 1) - cpHeight = SCRNGRID_Y - diffY; + cpHeight = diffY; for (uint16 cntx = 0; cntx < gridW; cntx++) - if (gridPos[cntx] & 1) { - gridPos[cntx] &= ~1; + if (gridPos[cntx]) { + gridPos[cntx] >>= 1; cpWidth++; } else if (cpWidth) { _system->copy_rect(scrnBuf + (cntx - cpWidth) * SCRNGRID_X, _scrnSizeX, (cntx - cpWidth) * SCRNGRID_X + diffX, cnty * SCRNGRID_Y + diffY + 40, cpWidth * SCRNGRID_X, cpHeight); + cpWidth = 0; } if (cpWidth) { uint16 xPos = (gridW - cpWidth) * SCRNGRID_X; @@ -243,7 +248,7 @@ void SwordScreen::newScreen(uint32 screen) { } _screenBuf = (uint8*)malloc(_scrnSizeX * _scrnSizeY); _screenGrid = (uint8*)malloc(_gridSizeX * _gridSizeY); - memset(_screenGrid, 0x80, _gridSizeX * _gridSizeY); // force refresh + memset(_screenGrid, 0, _gridSizeX * _gridSizeY); for (cnt = 0; cnt < _roomDefTable[_currentScreen].totalLayers; cnt++) { // open and lock all resources, will be closed in quitScreen() _layerBlocks[cnt] = (uint8*)_resMan->openFetchRes(_roomDefTable[_currentScreen].layers[cnt]); @@ -263,6 +268,7 @@ void SwordScreen::newScreen(uint32 screen) { fnSetPalette(0, 184, _roomDefTable[_currentScreen].palettes[0], SwordEngine::_systemVars.wantFade); fnSetPalette(184, 72, _roomDefTable[_currentScreen].palettes[1], SwordEngine::_systemVars.wantFade); + _fullRefresh = true; } void SwordScreen::quitScreen(void) { @@ -349,7 +355,7 @@ void SwordScreen::processImage(uint32 id) { decompressRLE7(sprData, FROM_LE_32(frameHead->compSize), _rleBuffer); sprData = _rleBuffer; } else if (frameHead->runTimeComp[3] == '0') { // RLE0 encoded? - decompressRLE0(sprData, FROM_LE_32(frameHead->compSize), _rleBuffer, FROM_LE_16(frameHead->width)); + decompressRLE0(sprData, FROM_LE_32(frameHead->compSize), _rleBuffer); sprData = _rleBuffer; } else if (frameHead->runTimeComp[1] == 'I') { // new type tonyBuf = (uint8*)malloc(FROM_LE_16(frameHead->width) * FROM_LE_16(frameHead->height)); @@ -629,28 +635,16 @@ void SwordScreen::decompressRLE7(uint8 *src, uint32 compSize, uint8 *dest) { } } -void SwordScreen::decompressRLE0(uint8 *src, uint32 compSize, uint8 *dest, uint16 width) { +void SwordScreen::decompressRLE0(uint8 *src, uint32 compSize, uint8 *dest) { uint8 *srcBufEnd = src + compSize; - uint16 destX = 0; while (src < srcBufEnd) { uint8 color = *src++; if (color) { - dest[destX] = color; - if (destX == width-1) { - destX = 0; - dest += width; - } else - destX++; + *dest++ = color; } else { uint8 skip = *src++; - for (uint16 cnt = 0; cnt < skip; cnt++) { - dest[destX] = 0; - if (destX == width-1) { - destX = 0; - dest += width; - } else - destX++; - } + memset(dest, 0, skip); + dest += skip; } } } @@ -710,10 +704,11 @@ void SwordScreen::spriteClipAndSet(uint16 *pSprX, uint16 *pSprY, uint16 *pSprWid *pSprX = (uint16)sprX; *pSprY = (uint16)sprY; - if (*pSprWidth && *pSprHeight) { - // sprite will be drawn, so mark it in the grid buffer - uint16 gridH = (*pSprHeight + SCRNGRID_Y - 1) / SCRNGRID_Y; - uint16 gridW = (*pSprWidth + SCRNGRID_X - 1) / SCRNGRID_X; + if (*pSprWidth && *pSprHeight && !_fullRefresh) { + // sprite will be drawn, so mark it in the grid buffer (we don't need to keep + // track of changed blocks if we're going to do a full refresh, anyways. + uint16 gridH = (*pSprHeight + (sprY & (SCRNGRID_Y - 1)) + (SCRNGRID_Y - 1)) / SCRNGRID_Y; + uint16 gridW = (*pSprWidth + (sprX & (SCRNGRID_X - 1)) + (SCRNGRID_X - 1)) / SCRNGRID_X; uint16 gridX = sprX / SCRNGRID_X; uint16 gridY = sprY / SCRNGRID_Y; uint8 *gridBuf = _screenGrid + gridX + gridY * _gridSizeX; @@ -724,7 +719,7 @@ void SwordScreen::spriteClipAndSet(uint16 *pSprX, uint16 *pSprY, uint16 *pSprWid for (uint16 cnty = 0; cnty < gridH; cnty++) { for (uint16 cntx = 0; cntx < gridW; cntx++) - gridBuf[cntx] |= 0x80; + gridBuf[cntx] = 2; gridBuf += _gridSizeX; } } diff --git a/sword1/screen.h b/sword1/screen.h index b99aa87794..b71d343398 100644 --- a/sword1/screen.h +++ b/sword1/screen.h @@ -105,7 +105,7 @@ private: void spriteClipAndSet(uint16 *pSprX, uint16 *pSprY, uint16 *sprWidth, uint16 *sprHeight, uint16 *incr); void drawSprite(uint8 *sprData, uint16 sprX, uint16 sprY, uint16 sprWidth, uint16 sprHeight, uint16 sprPitch); void decompressRLE7(uint8 *src, uint32 compSize, uint8 *dest); - void decompressRLE0(uint8 *src, uint32 compSize, uint8 *dest, uint16 width); + void decompressRLE0(uint8 *src, uint32 compSize, uint8 *dest); void decompressTony(uint8 *src, uint32 compSize, uint8 *dest); void fastShrink(uint8 *src, uint32 width, uint32 height, uint32 scale, uint8 *dest); int32 inRange(int32 a, int32 b, int32 c); -- cgit v1.2.3