From b016c16300577ae29d5a78e5be532cef3d4e21ce Mon Sep 17 00:00:00 2001 From: Martin Kiewitz Date: Sun, 20 Jun 2010 16:31:24 +0000 Subject: SCI: some kPalVary support - intro of island dr. brain works fine now svn-id: r50082 --- engines/sci/engine/kgraphics.cpp | 11 ++--- engines/sci/graphics/palette.cpp | 91 +++++++++++++++++++++++++++++++++------- engines/sci/graphics/palette.h | 18 ++++---- 3 files changed, 94 insertions(+), 26 deletions(-) diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp index da0f533709..f011f0e2d6 100644 --- a/engines/sci/engine/kgraphics.cpp +++ b/engines/sci/engine/kgraphics.cpp @@ -646,14 +646,15 @@ reg_t kPalVary(EngineState *s, int argc, reg_t *argv) { switch (operation) { case 0: { // Init GuiResourceId paletteId; - uint16 ticks, paletteStop, paletteDirection; + uint16 ticks, stepStop; + int16 direction; if ((argc >= 3) && (argc <= 5)) { paletteId = argv[1].toUint16(); ticks = argv[2].toUint16(); - paletteStop = argc >= 4 ? argv[3].toUint16() : 64; - paletteDirection = argc >= 5 ? argv[4].toUint16() : 1; - g_sci->_gfxPalette->kernelPalVaryInit(paletteId, ticks); - warning("kPalVary(init) called with paletteId = %d, ticks = %d, stop = %d, direction = %d", paletteId, ticks, paletteStop, paletteDirection); + stepStop = argc >= 4 ? argv[3].toUint16() : 64; + direction = argc >= 5 ? argv[4].toUint16() : 1; + g_sci->_gfxPalette->kernelPalVaryInit(paletteId, ticks, stepStop, direction); + warning("kPalVary(init) called with paletteId = %d, ticks = %d, stop = %d, direction = %d", paletteId, ticks, stepStop, direction); } else { warning("kPalVary(init) called with unsupported argc %d", argc); } diff --git a/engines/sci/graphics/palette.cpp b/engines/sci/graphics/palette.cpp index 5a0a661a56..68483ac954 100644 --- a/engines/sci/graphics/palette.cpp +++ b/engines/sci/graphics/palette.cpp @@ -212,6 +212,10 @@ void GfxPalette::setEGA() { void GfxPalette::set(Palette *newPalette, bool force, bool forceRealMerge) { uint32 systime = _sysPalette.timestamp; + // Pal-Vary is taking place -> abort merge + if (_palVaryResourceId != -1) + return; + if (force || newPalette->timestamp != systime) { _sysPaletteChanged |= merge(newPalette, force, forceRealMerge); newPalette->timestamp = _sysPalette.timestamp; @@ -475,17 +479,36 @@ void GfxPalette::kernelAssertPalette(GuiResourceId resourceId) { // Saving/restoring // need to save start and target-palette, when palVaryOn = true -void GfxPalette::kernelPalVaryInit(GuiResourceId resourceId, uint16 ticks) { - kernelSetFromResource(resourceId, true); - return; +void GfxPalette::palVaryInit() { + _palVaryResourceId = -1; + _palVaryPaused = 0; + _palVarySignal = 0; + _palVaryStep = 0; + _palVaryStepStop = 0; + _palVaryDirection = 0; +} - if (_palVaryResourceId >= 0) // another palvary is taking place, return +void GfxPalette::kernelPalVaryInit(GuiResourceId resourceId, uint16 ticks, uint16 stepStop, int16 direction) { + //kernelSetFromResource(resourceId, true); + //return; + if (_palVaryResourceId != -1) // another palvary is taking place, return return; _palVaryResourceId = resourceId; - _palVarySignal = 0; - // Call signal increase every [ticks] - g_sci->getTimerManager()->installTimerProc(&palVaryCallback, 1000000 / 60 * ticks, this); + Resource *palResource = _resMan->findResource(ResourceId(kResourceTypePalette, resourceId), 0); + if (palResource) { + // Load and initialize destination palette + createFromData(palResource->data, &_palVaryTargetPalette); + // Save current palette + memcpy(&_palVaryOriginPalette, &_sysPalette, sizeof(Palette)); + + _palVarySignal = 0; + _palVaryStep = 1; + _palVaryStepStop = stepStop; + _palVaryDirection = direction; + // Call signal increase every [ticks] + g_sci->getTimerManager()->installTimerProc(&palVaryCallback, 1000000 / 60 * ticks, this); + } } void GfxPalette::kernelPalVaryToggle(bool pause) { @@ -503,17 +526,11 @@ void GfxPalette::kernelPalVaryDeinit() { g_sci->getTimerManager()->removeTimerProc(&palVaryCallback); // HACK: just set the target palette - kernelSetFromResource(_palVaryResourceId, true); + //kernelSetFromResource(_palVaryResourceId, true); _palVaryResourceId = -1; // invalidate the target palette } -void GfxPalette::palVaryInit() { - _palVaryResourceId = -1; - _palVaryPaused = 0; - _palVarySignal = 0; -} - void GfxPalette::palVaryCallback(void *refCon) { ((GfxPalette *)refCon)->palVaryIncreaseSignal(); } @@ -525,7 +542,53 @@ void GfxPalette::palVaryIncreaseSignal() { // Actually do the pal vary processing void GfxPalette::palVaryUpdate() { + if (_palVarySignal) { + palVaryProcess(_palVarySignal, true); + _palVarySignal = 0; + } +} + +// Processes pal vary updates +void GfxPalette::palVaryProcess(int signal, bool setPalette) { + int16 stepChange = signal * _palVaryDirection; + + _palVaryStep += stepChange; + if (stepChange > 0) { + if (_palVaryStep > _palVaryStepStop) + _palVaryStep = _palVaryStepStop; + } else { + if (_palVaryStep < _palVaryStepStop) { + if (!signal) + _palVaryStep = _palVaryStepStop; + } + } + // We don't need updates anymore, if we reached end-position + if (_palVaryStep == _palVaryStepStop) + g_sci->getTimerManager()->removeTimerProc(&palVaryCallback); + + // Calculate inbetween palette + Sci::Color inbetween; + int16 color; + for (int colorNr = 1; colorNr < 255; colorNr++) { + inbetween.used = _sysPalette.colors[colorNr].used; + color = _palVaryTargetPalette.colors[colorNr].r - _palVaryOriginPalette.colors[colorNr].r; + inbetween.r = ((color * _palVaryStep) >> 6) + _palVaryOriginPalette.colors[colorNr].r; + color = _palVaryTargetPalette.colors[colorNr].g - _palVaryOriginPalette.colors[colorNr].g; + inbetween.g = ((color * _palVaryStep) >> 6) + _palVaryOriginPalette.colors[colorNr].g; + color = _palVaryTargetPalette.colors[colorNr].b - _palVaryOriginPalette.colors[colorNr].b; + inbetween.b = ((color * _palVaryStep) >> 6) + _palVaryOriginPalette.colors[colorNr].b; + + if (memcmp(&inbetween, &_sysPalette.colors[colorNr], sizeof(Sci::Color))) { + _sysPalette.colors[colorNr] = inbetween; + _sysPaletteChanged = true; + } + } + + if ((_sysPaletteChanged) && (setPalette) && (_screen->_picNotValid == 0)) { + setOnScreen(); + _sysPaletteChanged = false; + } } } // End of namespace Sci diff --git a/engines/sci/graphics/palette.h b/engines/sci/graphics/palette.h index af649015d5..861684ecb4 100644 --- a/engines/sci/graphics/palette.h +++ b/engines/sci/graphics/palette.h @@ -62,10 +62,11 @@ public: void kernelAnimateSet(); void kernelAssertPalette(GuiResourceId resourceId); - void kernelPalVaryInit(GuiResourceId resourceId, uint16 ticks); + void kernelPalVaryInit(GuiResourceId resourceId, uint16 ticks, uint16 stopPercentage, int16 direction); void kernelPalVaryToggle(bool pause); void kernelPalVaryDeinit(); void palVaryUpdate(); + void palVaryProcess(int signal, bool setPalette); Palette _sysPalette; @@ -77,16 +78,19 @@ private: GfxScreen *_screen; ResourceManager *_resMan; - GuiResourceId _palVaryResourceId; - uint32 _palVaryStart; - uint32 _palVaryEnd; - int _palVaryPaused; - int _palVarySignal; - bool _sysPaletteChanged; bool _alwaysForceRealMerge; Common::Array _schedules; + + GuiResourceId _palVaryResourceId; + Palette _palVaryOriginPalette; + Palette _palVaryTargetPalette; + uint16 _palVaryStep; + uint16 _palVaryStepStop; + int16 _palVaryDirection; + int _palVaryPaused; + int _palVarySignal; }; } // End of namespace Sci -- cgit v1.2.3