Index: engines/scumm/scumm.cpp =================================================================== --- engines/scumm/scumm.cpp (revision 23186) +++ engines/scumm/scumm.cpp (working copy) @@ -370,7 +370,6 @@ _newEffect = 0; _switchRoomEffect2 = 0; _switchRoomEffect = 0; - _scrollBuffer = NULL; _doEffect = false; _currentLights = 0; Index: engines/scumm/gfx.cpp =================================================================== --- engines/scumm/gfx.cpp (revision 23186) +++ engines/scumm/gfx.cpp (working copy) @@ -3052,18 +3052,6 @@ _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 @@ -3244,13 +3232,68 @@ } } +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::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 +3309,14 @@ 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 +3324,14 @@ 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 +3339,14 @@ 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 +3354,20 @@ 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() { Index: engines/scumm/scumm.h =================================================================== --- engines/scumm/scumm.h (revision 23186) +++ engines/scumm/scumm.h (working copy) @@ -988,8 +988,6 @@ byte _newEffect, _switchRoomEffect2, _switchRoomEffect; bool _doEffect; - byte *_scrollBuffer; - public: bool isLightOn() const; @@ -1084,6 +1082,7 @@ void transitionEffect(int a); void dissolveEffect(int width, int height); void scrollEffect(int dir); + void moveScreen(int dx, int dy, int height); // bomp public: Index: engines/scumm/he/script_v60he.cpp =================================================================== --- engines/scumm/he/script_v60he.cpp (revision 23186) +++ engines/scumm/he/script_v60he.cpp (working copy) @@ -519,7 +519,6 @@ } else if (a) { _switchRoomEffect = (byte)(a & 0xFF); _switchRoomEffect2 = (byte)(a >> 8); - setScrollBuffer(); } else { fadeIn(_newEffect); } Index: engines/scumm/script_v5.cpp =================================================================== --- engines/scumm/script_v5.cpp (revision 23186) +++ engines/scumm/script_v5.cpp (working copy) @@ -1926,7 +1926,6 @@ } _switchRoomEffect = (byte)(a & 0xFF); _switchRoomEffect2 = (byte)(a >> 8); - setScrollBuffer(); } else { fadeIn(_newEffect); } Index: engines/scumm/script_v6.cpp =================================================================== --- engines/scumm/script_v6.cpp (revision 23186) +++ engines/scumm/script_v6.cpp (working copy) @@ -1707,7 +1707,6 @@ if (a) { _switchRoomEffect = (byte)(a & 0xFF); _switchRoomEffect2 = (byte)(a >> 8); - setScrollBuffer(); } else { fadeIn(_newEffect); }