diff --git a/engines/sci/engine/kgraphics32.cpp b/engines/sci/engine/kgraphics32.cpp index 6c51ec428450..b140062ca061 100644 --- a/engines/sci/engine/kgraphics32.cpp +++ b/engines/sci/engine/kgraphics32.cpp @@ -133,8 +133,6 @@ reg_t kGetHighPlanePri(EngineState *s, int argc, reg_t *argv) { reg_t kFrameOut(EngineState *s, int argc, reg_t *argv) { bool showBits = argc > 0 ? argv[0].toUint16() : true; g_sci->_gfxFrameout->kernelFrameOut(showBits); - s->speedThrottler(16); - s->_throttleTrigger = true; return s->r_acc; } diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp index 009ae2818e08..2d44e383908a 100644 --- a/engines/sci/graphics/frameout.cpp +++ b/engines/sci/graphics/frameout.cpp @@ -77,6 +77,8 @@ GfxFrameout::GfxFrameout(SegManager *segMan, ResourceManager *resMan, GfxCoordAd _screen(screen), _segMan(segMan), _paint32(paint32), + _benchmarkingFinished(false), + _throttleFrameOut(true), _showStyles(nullptr), // TODO: Stop using _gfxScreen _currentBuffer(screen->getDisplayWidth(), screen->getDisplayHeight(), nullptr), @@ -258,6 +260,17 @@ void GfxFrameout::syncWithScripts(bool addElements) { #pragma mark Screen items void GfxFrameout::kernelAddScreenItem(const reg_t object) { + // The "fred" object is used to test graphics performance; + // it is impacted by framerate throttling, so disable the + // throttling when this item is on the screen for the + // performance check to pass. + if (!_benchmarkingFinished && ( + (int16)readSelectorValue(_segMan, object, SELECTOR(view)) == -556 || + Common::String(_segMan->getObjectName(object)) == "fred" + )) { + _throttleFrameOut = false; + } + const reg_t planeObject = readSelector(_segMan, object, SELECTOR(plane)); _segMan->getObject(object)->setInfoSelectorFlag(kInfoFlagViewInserted); @@ -297,6 +310,18 @@ void GfxFrameout::kernelUpdateScreenItem(const reg_t object) { } void GfxFrameout::kernelDeleteScreenItem(const reg_t object) { + // The "fred" object is used to test graphics performance; + // it is impacted by framerate throttling, so disable the + // throttling when this item is on the screen for the + // performance check to pass. + if (!_benchmarkingFinished && ( + (int16)readSelectorValue(_segMan, object, SELECTOR(view)) == -556 || + Common::String(_segMan->getObjectName(object)) == "fred" + )) { + _benchmarkingFinished = true; + _throttleFrameOut = true; + } + _segMan->getObject(object)->clearInfoSelectorFlag(kInfoFlagViewInserted); const reg_t planeObject = readSelector(_segMan, object, SELECTOR(plane)); @@ -1395,6 +1420,11 @@ void GfxFrameout::kernelFrameOut(const bool shouldShowBits) { frameOut(shouldShowBits); } + + if (_throttleFrameOut) { + g_sci->getEngineState()->speedThrottler(16); + g_sci->getEngineState()->_throttleTrigger = true; + } } #pragma mark - diff --git a/engines/sci/graphics/frameout.h b/engines/sci/graphics/frameout.h index 8ed95a00dee7..0f06ee1c852e 100644 --- a/engines/sci/graphics/frameout.h +++ b/engines/sci/graphics/frameout.h @@ -178,6 +178,22 @@ class GfxFrameout { void syncWithScripts(bool addElements); // this is what Game::restore does, only needed when our ScummVM dialogs are patched in void run(); +#pragma mark - +#pragma mark Benchmarking +private: + /** + * Optimization to avoid the more expensive object name + * comparision on every call to kAddScreenItem and + * kRemoveScreenItem. + */ + bool _benchmarkingFinished; + + /** + * Whether or not calls to kFrameOut should be framerate + * limited to ~60fps. + */ + bool _throttleFrameOut; + #pragma mark - #pragma mark Screen items private: