diff options
Diffstat (limited to 'engines/sci/graphics/animate.cpp')
-rw-r--r-- | engines/sci/graphics/animate.cpp | 91 |
1 files changed, 78 insertions, 13 deletions
diff --git a/engines/sci/graphics/animate.cpp b/engines/sci/graphics/animate.cpp index c637ef8374..ab4362cda9 100644 --- a/engines/sci/graphics/animate.cpp +++ b/engines/sci/graphics/animate.cpp @@ -177,6 +177,15 @@ void GfxAnimate::makeSortedList(List *list) { curNode = _s->_segMan->lookupNode(curAddress); } + // Possible TODO: As noted in the comment in sortHelper we actually + // require a stable sorting algorithm here. Since Common::sort is not stable + // at the time of writing this comment, we work around that in our ordering + // comparator. If that changes in the future or we want to use some + // stable sorting algorithm here, we should change that. + // In that case we should test such changes intensively. A good place to test stable sort + // is iceman, cupboard within the submarine. If sort isn't stable, the cupboard will be + // half-open, half-closed. Of course that's just one of many special cases. + // Now sort the list according y and z (descending) Common::sort(_list.begin(), _list.end(), sortHelper); } @@ -190,6 +199,7 @@ void GfxAnimate::fill(byte &old_picNotValid) { for (it = _list.begin(); it != end; ++it) { curObject = it->object; + signal = it->signal; // Get the corresponding view view = _cache->getView(it->viewId); @@ -233,18 +243,30 @@ void GfxAnimate::fill(byte &old_picNotValid) { } } + if (!view->isScaleable()) { + // Laura Bow 2 (especially floppy) depends on this, some views are not supposed to be scaleable + // this "feature" was removed in later versions of SCI1.1 + it->scaleSignal = 0; + it->scaleY = it->scaleX = 128; + } + + bool setNsRect = true; + // Create rect according to coordinates and given cel if (it->scaleSignal & kScaleSignalDoScaling) { view->getCelScaledRect(it->loopNo, it->celNo, it->x, it->y, it->z, it->scaleX, it->scaleY, it->celRect); + // when being scaled, only set nsRect, if object will get drawn + if ((signal & kSignalHidden) && !(signal & kSignalAlwaysUpdate)) + setNsRect = false; } else { view->getCelRect(it->loopNo, it->celNo, it->x, it->y, it->z, it->celRect); } - writeSelectorValue(_s->_segMan, curObject, SELECTOR(nsLeft), it->celRect.left); - writeSelectorValue(_s->_segMan, curObject, SELECTOR(nsTop), it->celRect.top); - writeSelectorValue(_s->_segMan, curObject, SELECTOR(nsRight), it->celRect.right); - writeSelectorValue(_s->_segMan, curObject, SELECTOR(nsBottom), it->celRect.bottom); - - signal = it->signal; + if (setNsRect) { + writeSelectorValue(_s->_segMan, curObject, SELECTOR(nsLeft), it->celRect.left); + writeSelectorValue(_s->_segMan, curObject, SELECTOR(nsTop), it->celRect.top); + writeSelectorValue(_s->_segMan, curObject, SELECTOR(nsRight), it->celRect.right); + writeSelectorValue(_s->_segMan, curObject, SELECTOR(nsBottom), it->celRect.bottom); + } // Calculate current priority according to y-coordinate if (!(signal & kSignalFixedPriority)) { @@ -521,13 +543,21 @@ void GfxAnimate::addToPicDrawCels() { } } -void GfxAnimate::addToPicDrawView(GuiResourceId viewId, int16 loopNo, int16 celNo, int16 leftPos, int16 topPos, int16 priority, int16 control) { +void GfxAnimate::addToPicDrawView(GuiResourceId viewId, int16 loopNo, int16 celNo, int16 x, int16 y, int16 priority, int16 control) { GfxView *view = _cache->getView(viewId); Common::Rect celRect; + if (priority == -1) + priority = _ports->kernelCoordinateToPriority(y); + // Create rect according to coordinates and given cel - view->getCelRect(loopNo, celNo, leftPos, topPos, priority, celRect); + view->getCelRect(loopNo, celNo, x, y, 0, celRect); _paint16->drawCel(view, loopNo, celNo, celRect, priority, 0); + + if (control != -1) { + celRect.top = CLIP<int16>(_ports->kernelPriorityToCoordinate(priority) - 1, celRect.top, celRect.bottom - 1); + _paint16->fillRect(celRect, GFX_SCREEN_MASK_CONTROL, 0, 0, control); + } } @@ -595,14 +625,49 @@ void GfxAnimate::kernelAnimate(reg_t listReference, bool cycle, int argc, reg_t updateScreen(old_picNotValid); restoreAndDelete(argc, argv); - if (_lastCastData.size() > 1) - _s->_throttleTrigger = true; - // We update the screen here as well, some scenes like EQ1 credits run w/o calling kGetEvent thus we wouldn't update // screen at all g_sci->getEventManager()->updateScreen(); _ports->setPort(oldPort); + + + // Now trigger speed throttler + switch (_lastCastData.size()) { + case 0: + // No entries drawn -> no speed throttler triggering + break; + case 1: { + + // One entry drawn -> check if that entry was a speed benchmark view, if not enable speed throttler + AnimateEntry *onlyCast = &_lastCastData[0]; + if ((onlyCast->viewId == 0) && (onlyCast->loopNo == 13) && (onlyCast->celNo == 0)) { + // this one is used by jones talkie + if ((onlyCast->celRect.height() == 8) && (onlyCast->celRect.width() == 8)) + return; + } + // first loop and first cel used? + if ((onlyCast->loopNo == 0) && (onlyCast->celNo == 0)) { + // and that cel has a known speed benchmark resolution + int16 onlyHeight = onlyCast->celRect.height(); + int16 onlyWidth = onlyCast->celRect.width(); + if (((onlyWidth == 12) && (onlyHeight == 35)) || // regular benchmark view ("fred", "Speedy", "ego") + ((onlyWidth == 29) && (onlyHeight == 45)) || // King's Quest 5 french "fred" + ((onlyWidth == 1) && (onlyHeight == 1))) { // Laura Bow 2 Talkie + // check further that there is only one cel in that view + GfxView *onlyView = _cache->getView(onlyCast->viewId); + if ((onlyView->getLoopCount() == 1) && (onlyView->getCelCount(0))) + return; + } + } + _s->_throttleTrigger = true; + break; + } + default: + // More than 1 entry drawn -> time for speed throttling + _s->_throttleTrigger = true; + break; + } } void GfxAnimate::addToPicSetPicNotValid() { @@ -627,9 +692,9 @@ void GfxAnimate::kernelAddToPicList(reg_t listReference, int argc, reg_t *argv) addToPicSetPicNotValid(); } -void GfxAnimate::kernelAddToPicView(GuiResourceId viewId, int16 loopNo, int16 celNo, int16 leftPos, int16 topPos, int16 priority, int16 control) { +void GfxAnimate::kernelAddToPicView(GuiResourceId viewId, int16 loopNo, int16 celNo, int16 x, int16 y, int16 priority, int16 control) { _ports->setPort((Port *)_ports->_picWind); - addToPicDrawView(viewId, loopNo, celNo, leftPos, topPos, priority, control); + addToPicDrawView(viewId, loopNo, celNo, x, y, priority, control); addToPicSetPicNotValid(); } |