SCI: Improve kPaletteSetIntensity speed throttling

Detect when kPaletteSetIntensity is called from an unthrottled
script loop and only apply speed throttling in that situation.

This fixes several slow fade-in / fade-outs such as KQ6's Sierra
logo and title screen. We've been throttling kPaletteSetIntensity
on every call, even when it was being used once per game cycle
(which our kGameIsRestarting throttling already handles) or within
kWait-throttled loops. In both cases this has added delays on top
of delays and slowed things down even further.
This commit is contained in:
sluicebox 2021-04-12 10:51:55 -07:00
parent 579727105e
commit 813d5ca6c9
5 changed files with 21 additions and 5 deletions

View File

@ -403,6 +403,7 @@ reg_t kWait(EngineState *s, int argc, reg_t *argv) {
return NULL_REG;
}
s->_paletteSetIntensityCounter = 0;
return make_reg(0, delta);
}
@ -646,6 +647,22 @@ reg_t kPaletteSetIntensity(EngineState *s, int argc, reg_t *argv) {
if (g_sci->_gfxPalette16->getTotalColorCount() < 256)
return s->r_acc;
if (setPalette) {
// Detect if we're being called from an unthrottled script loop.
// Throttled loops that call kWait on each iteration are okay.
if (s->_paletteSetIntensityCounter > 0) {
// Call speed throttler, otherwise the palette fade from this
// unthrottled script loop won't have any visible effect.
// Examples: KQ6 intro text/credits and SQ4CD intro credits
s->speedThrottler(30);
}
s->_paletteSetIntensityCounter++;
// Enable normal throttling in case this is being called from a script that
// doesn't animate anything with kAnimate, such as the LB2 title screen.
s->_throttleTrigger = true;
}
g_sci->_gfxPalette16->kernelSetIntensity(fromColor, toColor, intensity, setPalette);
return s->r_acc;
}

View File

@ -131,6 +131,8 @@ reg_t kGameIsRestarting(EngineState *s, int argc, reg_t *argv) {
}
s->speedThrottler(neededSleep);
s->_paletteSetIntensityCounter = 0;
return s->r_acc;
}

View File

@ -107,6 +107,7 @@ void EngineState::reset(bool isRestoring) {
#ifdef ENABLE_SCI32
_eventCounter = 0;
#endif
_paletteSetIntensityCounter = 0;
_throttleLastTime = 0;
_throttleTrigger = false;
_gameIsBenchmarking = false;

View File

@ -120,6 +120,7 @@ public:
#ifdef ENABLE_SCI32
uint32 _eventCounter; /**< total times kGetEvent was invoked since the last call to kFrameOut */
#endif
uint32 _paletteSetIntensityCounter; /**< total times kPaletteSetIntensity was invoked since the last call to kGameIsRestarting or kWait */
uint32 _throttleLastTime; /**< last time kAnimate was invoked */
bool _throttleTrigger;
bool _gameIsBenchmarking;

View File

@ -557,11 +557,6 @@ void GfxPalette::kernelSetIntensity(uint16 fromColor, uint16 toColor, uint16 int
memset(&_sysPalette.intensity[0] + fromColor, intensity, toColor - fromColor);
if (setPalette) {
setOnScreen();
EngineState *state = g_sci->getEngineState();
// Call speed throttler from here as well just in case we need it
// At least in kq6 intro the scripts call us in a tight loop for fadein/fadeout
state->speedThrottler(30);
state->_throttleTrigger = true;
}
}