diff options
Diffstat (limited to 'engines/sci/graphics/plane32.cpp')
-rw-r--r-- | engines/sci/graphics/plane32.cpp | 182 |
1 files changed, 119 insertions, 63 deletions
diff --git a/engines/sci/graphics/plane32.cpp b/engines/sci/graphics/plane32.cpp index 96d57e3917..d05e4f79e1 100644 --- a/engines/sci/graphics/plane32.cpp +++ b/engines/sci/graphics/plane32.cpp @@ -27,6 +27,7 @@ #include "sci/graphics/frameout.h" #include "sci/graphics/lists32.h" #include "sci/graphics/plane32.h" +#include "sci/graphics/remap.h" #include "sci/graphics/screen.h" #include "sci/graphics/screen_item32.h" @@ -43,10 +44,10 @@ void DrawList::add(ScreenItem *screenItem, const Common::Rect &rect) { #pragma mark Plane uint16 Plane::_nextObjectId = 20000; -Plane::Plane(const Common::Rect &gameRect) : +Plane::Plane(const Common::Rect &gameRect, PlanePictureCodes pictureId) : _width(g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth), _height(g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight), -_pictureId(kPlanePicColored), +_pictureId(pictureId), _mirrored(false), _back(0), _priorityChanged(0), @@ -55,6 +56,7 @@ _redrawAllCount(g_sci->_gfxFrameout->getScreenCount()), _created(g_sci->_gfxFrameout->getScreenCount()), _updated(0), _deleted(0), +_moved(0), _gameRect(gameRect) { convertGameRectToPlaneRect(); _priority = MAX(10000, g_sci->_gfxFrameout->getPlanes().getTopPlanePriority() + 1); @@ -136,7 +138,7 @@ void Plane::convertGameRectToPlaneRect() { const Ratio ratioY = Ratio(screenHeight, scriptHeight); _planeRect = _gameRect; - mulru(_planeRect, ratioX, ratioY); + mulru(_planeRect, ratioX, ratioY, 1); } void Plane::printDebugInfo(Console *con) const { @@ -296,7 +298,7 @@ void Plane::calcLists(Plane &visiblePlane, const PlaneList &planeList, DrawList ScreenItemList::size_type planeItemCount = _screenItemList.size(); ScreenItemList::size_type visiblePlaneItemCount = visiblePlane._screenItemList.size(); - for (PlaneList::size_type i = 0; i < planeItemCount; ++i) { + for (ScreenItemList::size_type i = 0; i < planeItemCount; ++i) { ScreenItem *vitem = nullptr; // NOTE: The original engine used an array without bounds checking // so could just get the visible screen item directly; we need to @@ -311,22 +313,23 @@ void Plane::calcLists(Plane &visiblePlane, const PlaneList &planeList, DrawList if (i < _screenItemList.size() && item != nullptr) { if (item->_deleted) { // add item's rect to erase list - if (i < visiblePlane._screenItemList.size() && vitem != nullptr) { - if (!vitem->_screenRect.isEmpty()) { - if (/* TODO: g_Remap_numActiveRemaps */ false) { // active remaps? - mergeToRectList(vitem->_screenRect, eraseList); - } else { - eraseList.add(vitem->_screenRect); - } + if ( + i < visiblePlane._screenItemList.size() && + vitem != nullptr && + !vitem->_screenRect.isEmpty() + ) { + if (g_sci->_gfxRemap32->getRemapCount()) { + mergeToRectList(vitem->_screenRect, eraseList); + } else { + eraseList.add(vitem->_screenRect); } } } else if (item->_created) { // add item to draw list - item->getCelObj(); item->calcRects(*this); if(!item->_screenRect.isEmpty()) { - if (/* TODO: g_Remap_numActiveRemaps */ false) { // active remaps? + if (g_sci->_gfxRemap32->getRemapCount()) { drawList.add(item, item->_screenRect); mergeToRectList(item->_screenRect, eraseList); } else { @@ -335,9 +338,8 @@ void Plane::calcLists(Plane &visiblePlane, const PlaneList &planeList, DrawList } } else if (item->_updated) { // add old rect to erase list, new item to draw list - item->getCelObj(); item->calcRects(*this); - if (/* TODO: g_Remap_numActiveRemaps */ false) { // active remaps + if (g_sci->_gfxRemap32->getRemapCount()) { // if item and vitem don't overlap, ... if (item->_screenRect.isEmpty() || i >= visiblePlaneItemCount || @@ -350,7 +352,11 @@ void Plane::calcLists(Plane &visiblePlane, const PlaneList &planeList, DrawList drawList.add(item, item->_screenRect); mergeToRectList(item->_screenRect, eraseList); } - if (i < visiblePlaneItemCount && vitem != nullptr && !vitem->_screenRect.isEmpty()) { + if ( + i < visiblePlaneItemCount && + vitem != nullptr && + !vitem->_screenRect.isEmpty() + ) { mergeToRectList(vitem->_screenRect, eraseList); } } else { @@ -358,10 +364,11 @@ void Plane::calcLists(Plane &visiblePlane, const PlaneList &planeList, DrawList // and item to draw list // TODO: This was changed from disasm, verify please! - Common::Rect extendedScreenItem = vitem->_screenRect; - extendedScreenItem.extend(item->_screenRect); + Common::Rect extendedScreenRect = vitem->_screenRect; + extendedScreenRect.extend(item->_screenRect); + drawList.add(item, item->_screenRect); - mergeToRectList(extendedScreenItem, eraseList); + mergeToRectList(extendedScreenRect, eraseList); } } else { // if no active remaps, just add item to draw list and old rect @@ -369,7 +376,11 @@ void Plane::calcLists(Plane &visiblePlane, const PlaneList &planeList, DrawList if (!item->_screenRect.isEmpty()) { drawList.add(item, item->_screenRect); } - if (i < visiblePlaneItemCount && vitem != nullptr && !vitem->_screenRect.isEmpty()) { + if ( + i < visiblePlaneItemCount && + vitem != nullptr && + !vitem->_screenRect.isEmpty() + ) { eraseList.add(vitem->_screenRect); } } @@ -381,21 +392,24 @@ void Plane::calcLists(Plane &visiblePlane, const PlaneList &planeList, DrawList breakEraseListByPlanes(eraseList, planeList); breakDrawListByPlanes(drawList, planeList); - // NOTE: Setting this to true fixes the menu bars in GK1 + // We store the current size of the drawlist, as we want to loop + // over the currently inserted entries later. + DrawList::size_type drawListSizePrimary = drawList.size(); + if (/* TODO: dword_C6288 */ false) { // "high resolution pictures"???? _screenItemList.sort(); bool encounteredPic = false; bool v81 = false; for (RectList::size_type i = 0; i < eraseList.size(); ++i) { - Common::Rect *rect = eraseList[i]; + const Common::Rect *rect = eraseList[i]; for (ScreenItemList::size_type j = 0; j < _screenItemList.size(); ++j) { ScreenItem *item = _screenItemList[j]; if (j < _screenItemList.size() && item != nullptr) { if (rect->intersects(item->_screenRect)) { - Common::Rect intersection = rect->findIntersectingRect(item->_screenRect); + const Common::Rect intersection = rect->findIntersectingRect(item->_screenRect); if (!item->_deleted) { if (encounteredPic) { if (item->_celInfo.type == kCelTypePic) { @@ -428,31 +442,42 @@ void Plane::calcLists(Plane &visiblePlane, const PlaneList &planeList, DrawList for (RectList::size_type i = 0; i < eraseList.size(); ++i) { for (ScreenItemList::size_type j = 0; j < _screenItemList.size(); ++j) { ScreenItem *item = _screenItemList[j]; - if (j < _screenItemList.size() && item != nullptr && !item->_updated && !item->_deleted && !item->_created && eraseList[i]->intersects(item->_screenRect)) { + if ( + item != nullptr && + !item->_created && !item->_updated && !item->_deleted && + eraseList[i]->intersects(item->_screenRect) + ) { drawList.add(item, eraseList[i]->findIntersectingRect(item->_screenRect)); } } } } - if (/* TODO: g_Remap_numActiveRemaps */ false) { // no remaps active? + + if (g_sci->_gfxRemap32->getRemapCount() == 0) { // no remaps active? // Add all items that overlap with items in the drawlist and have higher - // priority - for (DrawList::size_type i = 0; i < drawList.size(); ++i) { + // priority. + + // We only loop over "primary" items in the draw list, skipping + // those that were added because of the erase list in the previous loop, + // or those to be added in this loop. + for (DrawList::size_type i = 0; i < drawListSizePrimary; ++i) { DrawItem *dli = drawList[i]; - for (PlaneList::size_type j = 0; j < planeItemCount; ++j) { + for (ScreenItemList::size_type j = 0; j < planeItemCount; ++j) { ScreenItem *sli = _screenItemList[j]; - if (i < drawList.size() && dli) { - if (j < _screenItemList.size() && sli) { - if (!sli->_updated && !sli->_deleted && !sli->_created) { - ScreenItem *item = dli->screenItem; - if (sli->_priority > item->_priority || (sli->_priority == item->_priority && sli->_object > item->_object)) { - if (dli->rect.intersects(sli->_screenRect)) { - drawList.add(sli, dli->rect.findIntersectingRect(sli->_screenRect)); - } - } - } + if ( + i < drawList.size() && dli != nullptr && + j < _screenItemList.size() && sli != nullptr && + !sli->_created && !sli->_updated && !sli->_deleted + ) { + ScreenItem *item = dli->screenItem; + + if ( + (sli->_priority > item->_priority || (sli->_priority == item->_priority && sli->_object > item->_object)) && + dli->rect.intersects(sli->_screenRect) + ) { + drawList.add(sli, dli->rect.findIntersectingRect(sli->_screenRect)); } } } @@ -491,8 +516,7 @@ void Plane::decrementScreenItemArrayCounts(Plane *visiblePlane, const bool force if (item->_created) { item->_created--; if (visiblePlane != nullptr) { - ScreenItem *n = new ScreenItem(*item); - visiblePlane->_screenItemList.add(n); + visiblePlane->_screenItemList.add(new ScreenItem(*item)); } } @@ -511,7 +535,7 @@ void Plane::decrementScreenItemArrayCounts(Plane *visiblePlane, const bool force void Plane::filterDownEraseRects(DrawList &drawList, RectList &eraseList, RectList &transparentEraseList) const { if (_type == kPlaneTypeTransparent) { for (RectList::size_type i = 0; i < transparentEraseList.size(); ++i) { - Common::Rect *r = transparentEraseList[i]; + const Common::Rect *r = transparentEraseList[i]; for (ScreenItemList::size_type j = 0; j < _screenItemList.size(); ++j) { ScreenItem *item = _screenItemList[j]; if (item != nullptr) { @@ -539,7 +563,7 @@ void Plane::filterDownEraseRects(DrawList &drawList, RectList &eraseList, RectLi } Common::Rect ptr[4]; - Common::Rect *r2 = transparentEraseList[i]; + const Common::Rect *r2 = transparentEraseList[i]; int count = splitRects(*r2, *r, ptr); for (int k = count - 1; k >= 0; --k) { transparentEraseList.add(ptr[k]); @@ -554,7 +578,7 @@ void Plane::filterDownEraseRects(DrawList &drawList, RectList &eraseList, RectLi void Plane::filterUpDrawRects(DrawList &transparentDrawList, const DrawList &drawList) const { for (DrawList::size_type i = 0; i < drawList.size(); ++i) { - Common::Rect &r = drawList[i]->rect; + const Common::Rect &r = drawList[i]->rect; for (ScreenItemList::size_type j = 0; j < _screenItemList.size(); ++j) { ScreenItem *item = _screenItemList[j]; @@ -569,7 +593,7 @@ void Plane::filterUpDrawRects(DrawList &transparentDrawList, const DrawList &dra void Plane::filterUpEraseRects(DrawList &drawList, RectList &eraseList) const { for (RectList::size_type i = 0; i < eraseList.size(); ++i) { - Common::Rect &r = *eraseList[i]; + const Common::Rect &r = *eraseList[i]; for (ScreenItemList::size_type j = 0; j < _screenItemList.size(); ++j) { ScreenItem *item = _screenItemList[j]; @@ -582,20 +606,19 @@ void Plane::filterUpEraseRects(DrawList &drawList, RectList &eraseList) const { } } -void Plane::mergeToDrawList(const DrawList::size_type index, const Common::Rect &rect, DrawList &drawList) const { +void Plane::mergeToDrawList(const ScreenItemList::size_type index, const Common::Rect &rect, DrawList &drawList) const { RectList rects; - Common::Rect r = _screenItemList[index]->_screenRect; + ScreenItem *item = _screenItemList[index]; + Common::Rect r = item->_screenRect; r.clip(rect); - rects.add(r); - ScreenItem *item = _screenItemList[index]; for (RectList::size_type i = 0; i < rects.size(); ++i) { r = *rects[i]; for (DrawList::size_type j = 0; j < drawList.size(); ++j) { - DrawItem *drawitem = drawList[j]; + const DrawItem *drawitem = drawList[j]; if (item->_object == drawitem->screenItem->_object) { if (drawitem->rect.contains(r)) { rects.erase_at(i); @@ -603,7 +626,7 @@ void Plane::mergeToDrawList(const DrawList::size_type index, const Common::Rect } Common::Rect outRects[4]; - int count = splitRects(r, drawitem->rect, outRects); + const int count = splitRects(r, drawitem->rect, outRects); if (count != -1) { for (int k = count - 1; k >= 0; --k) { rects.add(outRects[k]); @@ -633,14 +656,14 @@ void Plane::mergeToRectList(const Common::Rect &rect, RectList &rectList) const Common::Rect r = *temp[i]; for (RectList::size_type j = 0; j < rectList.size(); ++j) { - Common::Rect *innerRect = rectList[j]; + const Common::Rect *innerRect = rectList[j]; if (innerRect->contains(r)) { temp.erase_at(i); break; } Common::Rect out[4]; - int count = splitRects(r, *innerRect, out); + const int count = splitRects(r, *innerRect, out); if (count != -1) { for (int k = count - 1; k >= 0; --k) { temp.add(out[k]); @@ -666,7 +689,6 @@ void Plane::redrawAll(Plane *visiblePlane, const PlaneList &planeList, DrawList if (*screenItemPtr != nullptr) { ScreenItem &screenItem = **screenItemPtr; if (!screenItem._deleted) { - screenItem.getCelObj(); screenItem.calcRects(*this); if (!screenItem._screenRect.isEmpty()) { drawList.add(&screenItem, screenItem._screenRect); @@ -776,8 +798,44 @@ void Plane::update(const reg_t object) { _back = readSelectorValue(segMan, object, SELECTOR(back)); } +void Plane::scrollScreenItems(const int16 deltaX, const int16 deltaY, const bool scrollPics) { + _redrawAllCount = g_sci->_gfxFrameout->getScreenCount(); + + for (ScreenItemList::iterator it = _screenItemList.begin(); it != _screenItemList.end(); ++it) { + if (*it != nullptr) { + ScreenItem &screenItem = **it; + if (!screenItem._deleted && (screenItem._celInfo.type != kCelTypePic || scrollPics)) { + screenItem._position.x += deltaX; + screenItem._position.y += deltaY; + } + } + } +} + +void Plane::remapMarkRedraw() { + for (ScreenItemList::const_iterator screenItemPtr = _screenItemList.begin(); screenItemPtr != _screenItemList.end(); ++screenItemPtr) { + if (*screenItemPtr != nullptr) { + ScreenItem &screenItem = **screenItemPtr; + if (screenItem.getCelObj()._remap && !screenItem._deleted && !screenItem._created) { + screenItem._updated = g_sci->_gfxFrameout->getScreenCount(); + } + } + } +} + #pragma mark - #pragma mark PlaneList +void PlaneList::add(Plane *plane) { + for (iterator it = begin(); it != end(); ++it) { + if ((*it)->_priority > plane->_priority) { + insert(it, plane); + return; + } + } + + push_back(plane); +} + void PlaneList::clear() { for (iterator it = begin(); it != end(); ++it) { delete *it; @@ -795,6 +853,11 @@ void PlaneList::erase(Plane *plane) { } } +PlaneList::iterator PlaneList::erase(iterator it) { + delete *it; + return PlaneListBase::erase(it); +} + int PlaneList::findIndexByObject(const reg_t object) const { for (size_type i = 0; i < size(); ++i) { if ((*this)[i] != nullptr && (*this)[i]->_object == object) { @@ -837,15 +900,8 @@ int16 PlaneList::getTopSciPlanePriority() const { return priority; } -void PlaneList::add(Plane *plane) { - for (iterator it = begin(); it != end(); ++it) { - if ((*it)->_priority < plane->_priority) { - insert(it, plane); - return; - } - } - - push_back(plane); +void PlaneList::remove_at(size_type index) { + delete PlaneListBase::remove_at(index); } -} +} // End of namespace Sci |