Skip to content

Commit

Permalink
SCI32: Fix video performance benchmarking in most SCI32 games
Browse files Browse the repository at this point in the history
Most SCI32 games draw a "fred" object to the screen when the game
first starts to benchmark video performance. When framerate
throttling is enabled (which fixes many/most timing-related bugs
and reduces system load caused by unnecessary graphics updates),
the game's performance check will think that video card is slow,
causing some "high-performance" game features to be disabled.

To avoid this, we simply disable throttling during benchmarking by
detecting the "fred" object.
  • Loading branch information
csnover committed Jun 15, 2016
1 parent 934e186 commit b56266d
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 2 deletions.
2 changes: 0 additions & 2 deletions engines/sci/engine/kgraphics32.cpp
Expand Up @@ -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;
}

Expand Down
30 changes: 30 additions & 0 deletions engines/sci/graphics/frameout.cpp
Expand Up @@ -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),
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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 -
Expand Down
16 changes: 16 additions & 0 deletions engines/sci/graphics/frameout.h
Expand Up @@ -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:
Expand Down

0 comments on commit b56266d

Please sign in to comment.