diff options
author | Matthew Hoops | 2010-06-20 17:17:46 +0000 |
---|---|---|
committer | Matthew Hoops | 2010-06-20 17:17:46 +0000 |
commit | ff785325ad3527394cec06fbd9dc331854e97f30 (patch) | |
tree | 69aa43325cc3063a8192873e2f7441e3a3d3d65c | |
parent | bb1358ae3b224d8cdb1a870778e75334a691cf13 (diff) | |
download | scummvm-rg350-ff785325ad3527394cec06fbd9dc331854e97f30.tar.gz scummvm-rg350-ff785325ad3527394cec06fbd9dc331854e97f30.tar.bz2 scummvm-rg350-ff785325ad3527394cec06fbd9dc331854e97f30.zip |
Sort planes in kFrameOut by priority and keep plane/item priority separate as they represent two different things. Fixes various SCI32 graphical glitches. Most (all?) remaining glitches are because we don't yet handle kSignalFixedPriority.
svn-id: r50087
-rw-r--r-- | engines/sci/graphics/frameout.cpp | 145 | ||||
-rw-r--r-- | engines/sci/graphics/frameout.h | 6 |
2 files changed, 74 insertions, 77 deletions
diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp index d8f7285887..8fa4f417b0 100644 --- a/engines/sci/graphics/frameout.cpp +++ b/engines/sci/graphics/frameout.cpp @@ -47,7 +47,6 @@ GfxFrameout::GfxFrameout(SegManager *segMan, ResourceManager *resMan, GfxCoordAd : _segMan(segMan), _resMan(resMan), _cache(cache), _screen(screen), _palette(palette), _paint32(paint32) { _coordAdjuster = (GfxCoordAdjuster32 *)coordAdjuster; - _highPlanePri = 0; } GfxFrameout::~GfxFrameout() { @@ -55,30 +54,20 @@ GfxFrameout::~GfxFrameout() { void GfxFrameout::kernelAddPlane(reg_t object) { _planes.push_back(object); - int16 planePri = readSelectorValue(_segMan, object, SELECTOR(priority)) & 0xFFFF; - if (planePri > _highPlanePri) - _highPlanePri = planePri; + sortPlanes(); } void GfxFrameout::kernelUpdatePlane(reg_t object) { + sortPlanes(); } void GfxFrameout::kernelDeletePlane(reg_t object) { - for (uint32 planeNr = 0; planeNr < _planes.size(); planeNr++) { - if (_planes[planeNr] == object) { - _planes.remove_at(planeNr); - break; + for (Common::List<reg_t>::iterator it = _planes.begin(); it != _planes.end(); it++) { + if (object == *it) { + _planes.erase(it); + return; } } - - // Recalculate highPlanePri - _highPlanePri = 0; - - for (uint32 planeNr = 0; planeNr < _planes.size(); planeNr++) { - int16 planePri = readSelectorValue(_segMan, _planes[planeNr], SELECTOR(priority)) & 0xFFFF; - if (planePri > _highPlanePri) - _highPlanePri = planePri; - } } void GfxFrameout::kernelAddScreenItem(reg_t object) { @@ -96,70 +85,77 @@ void GfxFrameout::kernelDeleteScreenItem(reg_t object) { } int16 GfxFrameout::kernelGetHighPlanePri() { - return _highPlanePri; + sortPlanes(); + reg_t object = _planes.back(); + return readSelectorValue(g_sci->getEngineState()->_segMan, _planes.back(), SELECTOR(priority)); } bool sortHelper(const FrameoutEntry* entry1, const FrameoutEntry* entry2) { return (entry1->priority == entry2->priority) ? (entry1->y < entry2->y) : (entry1->priority < entry2->priority); } -void GfxFrameout::kernelFrameout() { - int16 itemCount = 0; - reg_t planeObject; - GuiResourceId planePictureNr; - GfxPicture *planePicture = 0; - int16 planePictureCels = 0; - int16 planePictureCel; - int16 planePriority; - Common::Rect planeRect; - int16 planeResY, planeResX; - byte planeBack; - - reg_t itemObject; - reg_t itemPlane; - - FrameoutEntry *itemData; - FrameoutList itemList; - FrameoutEntry *itemEntry; +bool planeSortHelper(const reg_t entry1, const reg_t entry2) { + SegManager *segMan = g_sci->getEngineState()->_segMan; - _palette->palVaryUpdate(); + uint16 plane1Priority = readSelectorValue(segMan, entry1, SELECTOR(priority)); + uint16 plane2Priority = readSelectorValue(segMan, entry2, SELECTOR(priority)); - // Allocate enough space for all screen items - itemData = (FrameoutEntry *)malloc(_screenItems.size() * sizeof(FrameoutEntry)); + if (plane1Priority == 0xffff) + return true; - for (uint32 planeNr = 0; planeNr < _planes.size(); planeNr++) { - planeObject = _planes[planeNr]; + if (plane2Priority == 0xffff) + return false; - // Remove any invalid planes - if (!_segMan->isObject(planeObject)) { - _planes.remove_at(planeNr); - planeNr--; - continue; - } + return plane1Priority < plane2Priority; +} + +void GfxFrameout::sortPlanes() { + // First, remove any invalid planes + for (Common::List<reg_t>::iterator it = _planes.begin(); it != _planes.end();) { + if (!_segMan->isObject(*it)) + it = _planes.erase(it); + else + it++; + } + + // Sort the rest of them + Common::sort(_planes.begin(), _planes.end(), planeSortHelper); +} - planePriority = readSelectorValue(_segMan, planeObject, SELECTOR(priority)); +void GfxFrameout::kernelFrameout() { + _palette->palVaryUpdate(); - if (planePriority == -1) // Plane currently not meant to be shown + // Allocate enough space for all screen items + FrameoutEntry *itemData = (FrameoutEntry *)malloc(_screenItems.size() * sizeof(FrameoutEntry)); + + for (Common::List<reg_t>::iterator it = _planes.begin(); it != _planes.end(); it++) { + reg_t planeObject = *it; + uint16 planePriority = readSelectorValue(_segMan, planeObject, SELECTOR(priority)); + + if (planePriority == 0xffff) // Plane currently not meant to be shown continue; + Common::Rect planeRect; planeRect.top = readSelectorValue(_segMan, planeObject, SELECTOR(top)); planeRect.left = readSelectorValue(_segMan, planeObject, SELECTOR(left)); planeRect.bottom = readSelectorValue(_segMan, planeObject, SELECTOR(bottom)); planeRect.right = readSelectorValue(_segMan, planeObject, SELECTOR(right)); - planeResY = readSelectorValue(_segMan, planeObject, SELECTOR(resY)); - planeResX = readSelectorValue(_segMan, planeObject, SELECTOR(resX)); + int16 planeResY = readSelectorValue(_segMan, planeObject, SELECTOR(resY)); + int16 planeResX = readSelectorValue(_segMan, planeObject, SELECTOR(resX)); planeRect.top = (planeRect.top * _screen->getHeight()) / planeResY; planeRect.left = (planeRect.left * _screen->getWidth()) / planeResX; planeRect.bottom = (planeRect.bottom * _screen->getHeight()) / planeResY; planeRect.right = (planeRect.right * _screen->getWidth()) / planeResX; - planeBack = readSelectorValue(_segMan, planeObject, SELECTOR(back)); - if (planeBack) { + byte planeBack = readSelectorValue(_segMan, planeObject, SELECTOR(back)); + if (planeBack) _paint32->fillRect(planeRect, planeBack); - } - planePictureNr = readSelectorValue(_segMan, planeObject, SELECTOR(picture)); + GuiResourceId planePictureNr = readSelectorValue(_segMan, planeObject, SELECTOR(picture)); + GfxPicture *planePicture = 0; + int16 planePictureCels = 0; + if ((planePictureNr != 0xFFFF) && (planePictureNr != 0xFFFE)) { planePicture = new GfxPicture(_resMan, _coordAdjuster, 0, _screen, _palette, planePictureNr, false); planePictureCels = planePicture->getSci32celCount(); @@ -168,10 +164,12 @@ void GfxFrameout::kernelFrameout() { } // Fill our itemlist for this plane - itemCount = 0; - itemEntry = itemData; + int16 itemCount = 0; + FrameoutEntry *itemEntry = itemData; + FrameoutList itemList; + for (uint32 itemNr = 0; itemNr < _screenItems.size(); itemNr++) { - itemObject = _screenItems[itemNr]; + reg_t itemObject = _screenItems[itemNr]; // Remove any invalid items if (!_segMan->isObject(itemObject)) { @@ -180,7 +178,7 @@ void GfxFrameout::kernelFrameout() { continue; } - itemPlane = readSelector(_segMan, itemObject, SELECTOR(plane)); + reg_t itemPlane = readSelector(_segMan, itemObject, SELECTOR(plane)); if (planeObject == itemPlane) { // Found an item on current plane itemEntry->viewId = readSelectorValue(_segMan, itemObject, SELECTOR(view)); @@ -200,8 +198,9 @@ void GfxFrameout::kernelFrameout() { itemEntry->y += planeRect.top; itemEntry->x += planeRect.left; - if (itemEntry->priority == 0) - itemEntry->priority = itemEntry->y; + if (!(itemEntry->signal & 0x0010)) { // kSignalFixedPriority + // TODO: Change priority of this item + } itemList.push_back(itemEntry); itemEntry++; @@ -213,12 +212,10 @@ void GfxFrameout::kernelFrameout() { Common::sort(itemList.begin(), itemList.end(), sortHelper); // Now display itemlist - planePictureCel = 0; - + int16 planePictureCel = 0; itemEntry = itemData; - FrameoutList::iterator listIterator = itemList.begin(); - FrameoutList::iterator listEnd = itemList.end(); - while (listIterator != listEnd) { + + for (FrameoutList::iterator listIterator = itemList.begin(); listIterator != itemList.end(); listIterator++) { itemEntry = *listIterator; if (planePicture) { while ((planePictureCel <= itemEntry->priority) && (planePictureCel < planePictureCels)) { @@ -226,23 +223,20 @@ void GfxFrameout::kernelFrameout() { planePictureCel++; } } + if (itemEntry->viewId != 0xFFFF) { GfxView *view = _cache->getView(itemEntry->viewId); - if ((itemEntry->scaleX == 128) && (itemEntry->scaleY == 128)) { + if ((itemEntry->scaleX == 128) && (itemEntry->scaleY == 128)) view->getCelRect(itemEntry->loopNo, itemEntry->celNo, itemEntry->x, itemEntry->y, itemEntry->z, &itemEntry->celRect); - } else + else view->getCelScaledRect(itemEntry->loopNo, itemEntry->celNo, itemEntry->x, itemEntry->y, itemEntry->z, itemEntry->scaleX, itemEntry->scaleY, &itemEntry->celRect); - if (itemEntry->celRect.top < 0 || itemEntry->celRect.top >= _screen->getHeight()) { - listIterator++; + if (itemEntry->celRect.top < 0 || itemEntry->celRect.top >= _screen->getHeight()) continue; - } - if (itemEntry->celRect.left < 0 || itemEntry->celRect.left >= _screen->getWidth()) { - listIterator++; + if (itemEntry->celRect.left < 0 || itemEntry->celRect.left >= _screen->getWidth()) continue; - } Common::Rect clipRect; clipRect = itemEntry->celRect; @@ -282,8 +276,8 @@ void GfxFrameout::kernelFrameout() { } } } - listIterator++; } + if (planePicture) { while (planePictureCel < planePictureCels) { planePicture->drawSci32Vga(planePictureCel); @@ -293,6 +287,7 @@ void GfxFrameout::kernelFrameout() { planePicture = 0; } } + free(itemData); _screen->copyToScreen(); } diff --git a/engines/sci/graphics/frameout.h b/engines/sci/graphics/frameout.h index 8015b9879f..e4568ad602 100644 --- a/engines/sci/graphics/frameout.h +++ b/engines/sci/graphics/frameout.h @@ -41,6 +41,7 @@ struct FrameoutEntry { int16 scaleY; Common::Rect celRect; }; + typedef Common::List<FrameoutEntry *> FrameoutList; class GfxCache; @@ -74,8 +75,9 @@ private: GfxPaint32 *_paint32; Common::Array<reg_t> _screenItems; - Common::Array<reg_t> _planes; - int16 _highPlanePri; + Common::List<reg_t> _planes; + + void sortPlanes(); }; } // End of namespace Sci |