aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/graphics/plane32.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/graphics/plane32.cpp')
-rw-r--r--engines/sci/graphics/plane32.cpp182
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