diff options
-rw-r--r-- | engines/scumm/gfx.cpp | 141 | ||||
-rw-r--r-- | engines/scumm/he/script_v60he.cpp | 1 | ||||
-rw-r--r-- | engines/scumm/script_v5.cpp | 1 | ||||
-rw-r--r-- | engines/scumm/script_v6.cpp | 1 | ||||
-rw-r--r-- | engines/scumm/scumm.cpp | 1 | ||||
-rw-r--r-- | engines/scumm/scumm.h | 4 |
6 files changed, 90 insertions, 59 deletions
diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp index 6dff3ac265..e7aa88b459 100644 --- a/engines/scumm/gfx.cpp +++ b/engines/scumm/gfx.cpp @@ -1092,6 +1092,74 @@ void ScummEngine::drawBox(int x, int y, int x2, int y2, int color) { } } +/** + * Moves the screen content by the offset specified via dx/dy. + * Only the region from x=0 till x=height-1 is affected. + * @param dx the horizontal offset. + * @param dy the vertical offset. + * @param height the number of lines which in which the move will be done. + */ +void ScummEngine::moveScreen(int dx, int dy, int height) { + // Short circuit check - do we have to do anything anyway? + if ((dx == 0 && dy == 0) || height <= 0) + return; + + byte *src, *dst; + int x, y; + + Graphics::Surface screen; + assert(_system->grabRawScreen(&screen)); + + // vertical movement + if (dy > 0) { + // move down - copy from bottom to top + dst = (byte *)screen.pixels + (height - 1) * _screenWidth; + src = dst - dy * _screenWidth; + for (y = dy; y < height; y++) { + memcpy(dst, src, _screenWidth); + src -= _screenWidth; + dst -= _screenWidth; + } + } else if (dy < 0) { + // move up - copy from top to bottom + dst = (byte *)screen.pixels; + src = dst - dy * _screenWidth; + for (y = -dy; y < height; y++) { + memcpy(dst, src, _screenWidth); + src += _screenWidth; + dst += _screenWidth; + } + } + + // horizontal movement + if (dx > 0) { + // move right - copy from right to left + dst = (byte *)screen.pixels + (_screenWidth - 1); + src = dst - dx; + for (y = 0; y < height; y++) { + for (x = dx; x < _screenWidth; x++) { + *dst-- = *src--; + } + src += _screenWidth + (_screenWidth - dx); + dst += _screenWidth + (_screenWidth - dx); + } + } else if (dx < 0) { + // move left - copy from left to right + dst = (byte *)screen.pixels; + src = dst - dx; + for (y = 0; y < height; y++) { + for (x = -dx; x < _screenWidth; x++) { + *dst++ = *src++; + } + src += _screenWidth - (_screenWidth + dx); + dst += _screenWidth - (_screenWidth + dx); + } + } + + _system->copyRectToScreen((byte *)screen.pixels, screen.pitch, 0, 0, screen.w, screen.h); + screen.free(); +} + void ScummEngine_v5::clearFlashlight() { _flashlight.isDrawn = false; _flashlight.buffer = NULL; @@ -3052,18 +3120,6 @@ void ScummEngine::fadeOut(int effect) { _screenEffectFlag = false; } -void ScummEngine::setScrollBuffer() { - if (_switchRoomEffect >= 130 && _switchRoomEffect <= 133) { - // We're going to use scrollEffect(), so we'll need a copy of - // the current VirtScreen zero. - VirtScreen *vs = &virtscr[0]; - - free(_scrollBuffer); - _scrollBuffer = (byte *) malloc(vs->h * vs->pitch); - memcpy(_scrollBuffer, vs->getPixels(0, 0), vs->h * vs->pitch); - } -} - /** * Perform a transition effect. There are four different effects possible: * 0: Iris effect @@ -3245,12 +3301,6 @@ void ScummEngine::dissolveEffect(int width, int height) { } void ScummEngine::scrollEffect(int dir) { - // It is at least technically possible that this function will be - // called without _scrollBuffer having been set up, but will it ever - // happen? I don't know. - if (!_scrollBuffer) - warning("scrollEffect: No scroll buffer. This may look bad"); - VirtScreen *vs = &virtscr[0]; int x, y; @@ -3266,17 +3316,14 @@ void ScummEngine::scrollEffect(int dir) { switch (dir) { case 0: //up - y = step; + y = 1 + step; while (y < vs->h) { - _system->copyRectToScreen(vs->getPixels(0, 0), + moveScreen(0, -step, vs->h); + _system->copyRectToScreen(vs->getPixels(0, y - step), vs->pitch, - 0, vs->h - y, - vs->w, y); - if (_scrollBuffer) - _system->copyRectToScreen(_scrollBuffer + y * vs->w, - vs->pitch, - 0, 0, - vs->w, vs->h - y); + 0, vs->h - step, + vs->w, step); + _system->updateScreen(); waitForTimer(kPictureDelay); y += step; @@ -3284,17 +3331,14 @@ void ScummEngine::scrollEffect(int dir) { break; case 1: // down - y = step; + y = 1 + step; while (y < vs->h) { + moveScreen(0, step, vs->h); _system->copyRectToScreen(vs->getPixels(0, vs->h - y), vs->pitch, 0, 0, - vs->w, y); - if (_scrollBuffer) - _system->copyRectToScreen(_scrollBuffer, - vs->pitch, - 0, y, - vs->w, vs->h - y); + vs->w, step); + _system->updateScreen(); waitForTimer(kPictureDelay); y += step; @@ -3302,17 +3346,14 @@ void ScummEngine::scrollEffect(int dir) { break; case 2: // left - x = step; + x = 1 + step; while (x < vs->w) { - _system->copyRectToScreen(vs->getPixels(0, 0), + moveScreen(-step, 0, vs->h); + _system->copyRectToScreen(vs->getPixels(x - step, 0), vs->pitch, - vs->w - x, 0, - x, vs->h); - if (_scrollBuffer) - _system->copyRectToScreen(_scrollBuffer + x, - vs->pitch, - 0, 0, - vs->w - x, vs->h); + vs->w - step, 0, + step, vs->h); + _system->updateScreen(); waitForTimer(kPictureDelay); x += step; @@ -3320,26 +3361,20 @@ void ScummEngine::scrollEffect(int dir) { break; case 3: // right - x = step; + x = 1 + step; while (x < vs->w) { + moveScreen(step, 0, vs->h); _system->copyRectToScreen(vs->getPixels(vs->w - x, 0), vs->pitch, 0, 0, - x, vs->h); - if (_scrollBuffer) - _system->copyRectToScreen(_scrollBuffer, - vs->pitch, - x, 0, - vs->w - x, vs->h); + step, vs->h); + _system->updateScreen(); waitForTimer(kPictureDelay); x += step; } break; } - - free(_scrollBuffer); - _scrollBuffer = NULL; } void ScummEngine::unkScreenEffect6() { diff --git a/engines/scumm/he/script_v60he.cpp b/engines/scumm/he/script_v60he.cpp index d6de73d123..24efa9eabc 100644 --- a/engines/scumm/he/script_v60he.cpp +++ b/engines/scumm/he/script_v60he.cpp @@ -519,7 +519,6 @@ void ScummEngine_v60he::o60_roomOps() { } else if (a) { _switchRoomEffect = (byte)(a & 0xFF); _switchRoomEffect2 = (byte)(a >> 8); - setScrollBuffer(); } else { fadeIn(_newEffect); } diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp index a7c5c3f9c6..92560514bd 100644 --- a/engines/scumm/script_v5.cpp +++ b/engines/scumm/script_v5.cpp @@ -1921,7 +1921,6 @@ void ScummEngine_v5::o5_roomOps() { } _switchRoomEffect = (byte)(a & 0xFF); _switchRoomEffect2 = (byte)(a >> 8); - setScrollBuffer(); } else { fadeIn(_newEffect); } diff --git a/engines/scumm/script_v6.cpp b/engines/scumm/script_v6.cpp index a809439c00..1e9b769916 100644 --- a/engines/scumm/script_v6.cpp +++ b/engines/scumm/script_v6.cpp @@ -1707,7 +1707,6 @@ void ScummEngine_v6::o6_roomOps() { if (a) { _switchRoomEffect = (byte)(a & 0xFF); _switchRoomEffect2 = (byte)(a >> 8); - setScrollBuffer(); } else { fadeIn(_newEffect); } diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index 04ccac9818..ea862eeb43 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -370,7 +370,6 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr) _newEffect = 0; _switchRoomEffect2 = 0; _switchRoomEffect = 0; - _scrollBuffer = NULL; _doEffect = false; _currentLights = 0; diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h index 0c2f46171b..e1595a72d5 100644 --- a/engines/scumm/scumm.h +++ b/engines/scumm/scumm.h @@ -988,8 +988,6 @@ protected: byte _newEffect, _switchRoomEffect2, _switchRoomEffect; bool _doEffect; - byte *_scrollBuffer; - public: bool isLightOn() const; @@ -1009,6 +1007,8 @@ protected: void drawRoomObject(int i, int arg); void drawBox(int x, int y, int x2, int y2, int color); + void moveScreen(int dx, int dy, int height); + void restoreBG(Common::Rect rect, byte backcolor = 0); void redrawBGStrip(int start, int num); virtual void redrawBGAreas(); |