From 9e9db758fb6600cf6dfb8a1ba10996de6e3425c9 Mon Sep 17 00:00:00 2001 From: Martin Kiewitz Date: Sun, 29 Aug 2010 10:39:34 +0000 Subject: SCI: changing scroll transition behaviour makes scroll smooth on linux (and maybe others too) svn-id: r52436 --- engines/sci/graphics/transitions.cpp | 80 +++++++++++++++++++----------------- engines/sci/graphics/transitions.h | 1 + 2 files changed, 44 insertions(+), 37 deletions(-) diff --git a/engines/sci/graphics/transitions.cpp b/engines/sci/graphics/transitions.cpp index cc3f600a5f..bd5e061094 100644 --- a/engines/sci/graphics/transitions.cpp +++ b/engines/sci/graphics/transitions.cpp @@ -121,20 +121,24 @@ void GfxTransitions::setup(int16 number, bool blackoutFlag) { } } +bool GfxTransitions::doCreateFrame(uint32 shouldBeAtMsec) { + uint32 msecPos = g_system->getMillis() - _transitionStartTime; + + if (shouldBeAtMsec > msecPos) + return true; + return false; +} + void GfxTransitions::updateScreenAndWait(uint32 shouldBeAtMsec) { Common::Event ev; - uint32 msecPos = g_system->getMillis() - _transitionStartTime; while (g_system->getEventManager()->pollEvent(ev)) {} // discard all events - if (shouldBeAtMsec > msecPos) { - // only update screen, if we are not behind schedule - g_system->updateScreen(); - // and if still too early, delay those milliseconds - msecPos = g_system->getMillis() - _transitionStartTime; - if (shouldBeAtMsec > msecPos) - g_system->delayMillis(shouldBeAtMsec - msecPos); - } + g_system->updateScreen(); + // if we have still some time left, delay accordingly + uint32 msecPos = g_system->getMillis() - _transitionStartTime; + if (shouldBeAtMsec > msecPos) + g_system->delayMillis(shouldBeAtMsec - msecPos); } // will translate a number and return corresponding translationEntry @@ -464,44 +468,36 @@ void GfxTransitions::scroll(int16 number) { newMoveRect.left = newMoveRect.right; while (oldMoveRect.left < oldMoveRect.right) { oldMoveRect.right--; oldScreenRect.left++; - if (oldMoveRect.right > oldMoveRect.left) - scrollCopyOldToScreen(oldScreenRect, oldMoveRect.left, oldMoveRect.top); newScreenRect.right++; newMoveRect.left--; - _screen->copyRectToScreen(newScreenRect, newMoveRect.left, newMoveRect.top); if ((stepNr & 1) == 0) { msecCount += 5; - updateScreenAndWait(msecCount); + if (doCreateFrame(msecCount)) { + if (oldMoveRect.right > oldMoveRect.left) + scrollCopyOldToScreen(oldScreenRect, oldMoveRect.left, oldMoveRect.top); + _screen->copyRectToScreen(newScreenRect, newMoveRect.left, newMoveRect.top); + updateScreenAndWait(msecCount); + } } stepNr++; } - if ((stepNr & 1) == 0) { - if (g_system->getMillis() - g_sci->getEngineState()->_screenUpdateTime >= 1000 / 60) { - g_system->updateScreen(); - g_sci->getEngineState()->_screenUpdateTime = g_system->getMillis(); - } - } break; case SCI_TRANSITIONS_SCROLL_RIGHT: newScreenRect.left = newScreenRect.right; while (oldMoveRect.left < oldMoveRect.right) { oldMoveRect.left++; oldScreenRect.right--; - if (oldMoveRect.right > oldMoveRect.left) - scrollCopyOldToScreen(oldScreenRect, oldMoveRect.left, oldMoveRect.top); newScreenRect.left--; - _screen->copyRectToScreen(newScreenRect, newMoveRect.left, newMoveRect.top); if ((stepNr & 1) == 0) { msecCount += 5; - updateScreenAndWait(msecCount); + if (doCreateFrame(msecCount)) { + if (oldMoveRect.right > oldMoveRect.left) + scrollCopyOldToScreen(oldScreenRect, oldMoveRect.left, oldMoveRect.top); + _screen->copyRectToScreen(newScreenRect, newMoveRect.left, newMoveRect.top); + updateScreenAndWait(msecCount); + } } stepNr++; } - if ((stepNr & 1) == 0) { - if (g_system->getMillis() - g_sci->getEngineState()->_screenUpdateTime >= 1000 / 60) { - g_system->updateScreen(); - g_sci->getEngineState()->_screenUpdateTime = g_system->getMillis(); - } - } break; case SCI_TRANSITIONS_SCROLL_UP: @@ -509,12 +505,15 @@ void GfxTransitions::scroll(int16 number) { newMoveRect.top = newMoveRect.bottom; while (oldMoveRect.top < oldMoveRect.bottom) { oldMoveRect.top++; oldScreenRect.top++; - if (oldMoveRect.top < oldMoveRect.bottom) - scrollCopyOldToScreen(oldScreenRect, _picRect.left, _picRect.top); newScreenRect.bottom++; newMoveRect.top--; - _screen->copyRectToScreen(newScreenRect, newMoveRect.left, newMoveRect.top); + msecCount += 5; - updateScreenAndWait(msecCount); + if (doCreateFrame(msecCount)) { + if (oldMoveRect.top < oldMoveRect.bottom) + scrollCopyOldToScreen(oldScreenRect, _picRect.left, _picRect.top); + _screen->copyRectToScreen(newScreenRect, newMoveRect.left, newMoveRect.top); + updateScreenAndWait(msecCount); + } } break; @@ -522,15 +521,22 @@ void GfxTransitions::scroll(int16 number) { newScreenRect.top = newScreenRect.bottom; while (oldMoveRect.top < oldMoveRect.bottom) { oldMoveRect.top++; oldScreenRect.bottom--; - if (oldMoveRect.top < oldMoveRect.bottom) - scrollCopyOldToScreen(oldScreenRect, oldMoveRect.left, oldMoveRect.top); newScreenRect.top--; - _screen->copyRectToScreen(newScreenRect, _picRect.left, _picRect.top); + msecCount += 5; - updateScreenAndWait(msecCount); + if (doCreateFrame(msecCount)) { + if (oldMoveRect.top < oldMoveRect.bottom) + scrollCopyOldToScreen(oldScreenRect, oldMoveRect.left, oldMoveRect.top); + _screen->copyRectToScreen(newScreenRect, _picRect.left, _picRect.top); + updateScreenAndWait(msecCount); + } } break; } + + // Copy over final position just in case + _screen->copyRectToScreen(newScreenRect); + g_system->updateScreen(); } // Vertically displays new screen starting from center - works on _picRect area diff --git a/engines/sci/graphics/transitions.h b/engines/sci/graphics/transitions.h index fbfd715b15..674b7a8173 100644 --- a/engines/sci/graphics/transitions.h +++ b/engines/sci/graphics/transitions.h @@ -91,6 +91,7 @@ private: void horizontalRollToCenter(bool blackoutFlag); void diagonalRollFromCenter(bool blackoutFlag); void diagonalRollToCenter(bool blackoutFlag); + bool doCreateFrame(uint32 shouldBeAtMsec); void updateScreenAndWait(uint32 shouldBeAtMsec); GfxScreen *_screen; -- cgit v1.2.3