[Scummvm-git-logs] scummvm master -> c089416b380ee2c282d03d4dd2bbae50d17daa8f
OMGPizzaGuy
noreply at scummvm.org
Sun Oct 1 20:00:54 UTC 2023
This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
494a05a507 ULTIMA8: Update adjoined occlusion to retain a height based on the minimal height of all included items
72e2ea8b7d ULTIMA8: Exclude translucent items from also marked as occluding.
c089416b38 ULTIMA8: Fix paint order of tapestry items to match original game.
Commit: 494a05a5071db20a395f6888ff085075686c7522
https://github.com/scummvm/scummvm/commit/494a05a5071db20a395f6888ff085075686c7522
Author: Matthew Jimenez (matthew.jimenez at outlook.com)
Date: 2023-10-01T15:00:21-05:00
Commit Message:
ULTIMA8: Update adjoined occlusion to retain a height based on the minimal height of all included items
Changed paths:
engines/ultima/ultima8/world/item_sorter.cpp
engines/ultima/ultima8/world/sort_item.h
diff --git a/engines/ultima/ultima8/world/item_sorter.cpp b/engines/ultima/ultima8/world/item_sorter.cpp
index c956c13fc3a..bff42fe02a1 100644
--- a/engines/ultima/ultima8/world/item_sorter.cpp
+++ b/engines/ultima/ultima8/world/item_sorter.cpp
@@ -199,8 +199,8 @@ void ItemSorter::AddItem(int32 x, int32 y, int32 z, uint32 shapeNum, uint32 fram
continue;
#ifdef SORTITEM_OCCLUSION_EXPERIMENTAL
- // Find adjoining floor squares for better occlusion
- if (si->_occl && si2->_occl && si->_fbigsq && si2->_fbigsq && si->_z == si2->_z) {
+ // Find adjoining rects for better occlusion
+ if (si->_occl && si2->_occl && si->_z == si2->_z) {
// Does this share an edge?
if (si->_y == si2->_y && si->_yFar == si2->_yFar) {
if (si->_xLeft == si2->_x) {
@@ -289,8 +289,8 @@ void ItemSorter::PaintDisplayList(RenderSurface *surf, bool item_highlight, bool
// This increases odds of occluding items below before checking them.
// Ignore items already occluded or at lowest Z as they are less likely occlude additional items.
for (SortItem *si1 = _itemsTail; si1 != nullptr; si1 = si1->_prev) {
- // Check if item is part of a 2x2 adjoined square
- if (si1->_occl && si1->_fbigsq && !si1->_occluded && si1->_z > minZ &&
+ // Check if item is part of a 2x2 rects square
+ if (si1->_occl && !si1->_occluded && si1->_z > minZ &&
si1->_xAdjoin && si1->_yAdjoin &&
si1->_xAdjoin->_yAdjoin && si1->_yAdjoin->_xAdjoin &&
si1->_xAdjoin->_yAdjoin == si1->_yAdjoin->_xAdjoin) {
@@ -298,10 +298,12 @@ void ItemSorter::PaintDisplayList(RenderSurface *surf, bool item_highlight, bool
SortItem *siX = si1;
SortItem *siY = si1;
- int32 group = si1->_itemNum;
+ uint16 group = si1->_itemNum;
si1->_groupNum = group;
- // Expand NxN adjoined square - up to 4x4 appears sufficient
+ int32 zTop = si1->_zTop;
+
+ // Expand NxN rects square - up to 4x4 appears sufficient
for (int n = 2; n <= 4; n++) {
// Expand out 1 from X and Y edge points
SortItem *p1 = siX->_xAdjoin;
@@ -315,6 +317,9 @@ void ItemSorter::PaintDisplayList(RenderSurface *surf, bool item_highlight, bool
p1->_groupNum = group;
p2->_groupNum = group;
+ zTop = MIN(zTop, p1->_zTop);
+ zTop = MIN(zTop, p2->_zTop);
+
p1 = p1->_yAdjoin;
p2 = p2->_xAdjoin;
}
@@ -326,6 +331,8 @@ void ItemSorter::PaintDisplayList(RenderSurface *surf, bool item_highlight, bool
si2 = p1;
si2->_groupNum = group;
+ zTop = MIN(zTop, p2->_zTop);
+
// Set the new edge points
siX = siX->_xAdjoin;
siY = siY->_yAdjoin;
@@ -334,7 +341,6 @@ void ItemSorter::PaintDisplayList(RenderSurface *surf, bool item_highlight, bool
if (si1 != si2) {
SortItem oc;
oc._occl = true;
- oc._fbigsq = true;
oc._flat = si1->_flat;
oc._solid = si1->_solid;
oc._roof = si1->_roof;
@@ -344,8 +350,8 @@ void ItemSorter::PaintDisplayList(RenderSurface *surf, bool item_highlight, bool
Box box = si1->getBoxBounds();
box.extend(si2->getBoxBounds());
- // Keep the box flat to avoid wrong occlusions caused by different heights
- box._zd = 0;
+ // Use min z top to avoid wrong occlusions caused by different heights
+ box._zd = zTop - box._z;
oc.setBoxBounds(box, _camSx, _camSy);
diff --git a/engines/ultima/ultima8/world/sort_item.h b/engines/ultima/ultima8/world/sort_item.h
index 3f69dbcb448..5e84877e3f6 100644
--- a/engines/ultima/ultima8/world/sort_item.h
+++ b/engines/ultima/ultima8/world/sort_item.h
@@ -98,7 +98,7 @@ struct SortItem {
#ifdef SORTITEM_OCCLUSION_EXPERIMENTAL
SortItem *_xAdjoin; // Item sharing a right x edge with the left x edge - used for occlusion
SortItem *_yAdjoin; // Item sharing a near y edge with the far y edge - used for occlusion
- int32 _groupNum; // Identifier for a member of an occlusion group
+ uint16 _groupNum; // Identifier for a member of an occlusion group
#endif // SORTITEM_OCCLUSION_EXPERIMENTAL
Commit: 72e2ea8b7d1c89f6d7e62c5c2adcf009f5bba299
https://github.com/scummvm/scummvm/commit/72e2ea8b7d1c89f6d7e62c5c2adcf009f5bba299
Author: Matthew Jimenez (matthew.jimenez at outlook.com)
Date: 2023-10-01T15:00:21-05:00
Commit Message:
ULTIMA8: Exclude translucent items from also marked as occluding.
Changed paths:
engines/ultima/ultima8/world/item_sorter.cpp
diff --git a/engines/ultima/ultima8/world/item_sorter.cpp b/engines/ultima/ultima8/world/item_sorter.cpp
index bff42fe02a1..47a5b5e438f 100644
--- a/engines/ultima/ultima8/world/item_sorter.cpp
+++ b/engines/ultima/ultima8/world/item_sorter.cpp
@@ -165,8 +165,9 @@ void ItemSorter::AddItem(int32 x, int32 y, int32 z, uint32 shapeNum, uint32 fram
si->_draw = info->is_draw();
si->_solid = info->is_solid();
- si->_occl = info->is_occl() && !(si->_flags & Item::FLG_INVISIBLE) &&
- !(si->_extFlags & Item::EXT_TRANSPARENT);
+ si->_occl = info->is_occl() && !info->is_translucent() &&
+ !(si->_flags & Item::FLG_INVISIBLE) &&
+ !(si->_extFlags & Item::EXT_TRANSPARENT);
si->_roof = info->is_roof();
si->_noisy = info->is_noisy();
si->_anim = info->_animType != 0;
Commit: c089416b380ee2c282d03d4dd2bbae50d17daa8f
https://github.com/scummvm/scummvm/commit/c089416b380ee2c282d03d4dd2bbae50d17daa8f
Author: Matthew Jimenez (matthew.jimenez at outlook.com)
Date: 2023-10-01T15:00:21-05:00
Commit Message:
ULTIMA8: Fix paint order of tapestry items to match original game.
Switching to screenspace checks may change order for items we have not tested, but may also be correct now.
Changed paths:
engines/ultima/ultima8/world/sort_item.cpp
test/engines/ultima/ultima8/world/sort_item.h
diff --git a/engines/ultima/ultima8/world/sort_item.cpp b/engines/ultima/ultima8/world/sort_item.cpp
index 6d4f823be0d..aa983878406 100644
--- a/engines/ultima/ultima8/world/sort_item.cpp
+++ b/engines/ultima/ultima8/world/sort_item.cpp
@@ -84,7 +84,8 @@ bool SortItem::below(const SortItem &si2) const {
bool yFlat1 = si1._yFar == si1._y;
bool yFlat2 = si2._yFar == si2._y;
if (yFlat1 && yFlat2) {
- if (si1._y != si2._y)
+ // Check with a precision loss based on footpad calculations
+ if (si1._y / 32 != si2._y / 32)
return si1._y < si2._y;
} else {
if (si1._y <= si2._yFar)
@@ -97,7 +98,8 @@ bool SortItem::below(const SortItem &si2) const {
bool xFlat1 = si1._xLeft == si1._x;
bool xFlat2 = si2._xLeft == si2._x;
if (xFlat1 && xFlat2) {
- if (si1._x != si2._x)
+ // Check with a precision loss based on footpad calculations
+ if (si1._x / 32 != si2._x / 32)
return si1._x < si2._x;
} else {
if (si1._x <= si2._xLeft)
@@ -204,21 +206,29 @@ bool SortItem::below(const SortItem &si2) const {
if (si1._z != si2._z)
return si1._z < si2._z;
- // Partial in X + Y front
- if (si1._x + si1._y != si2._x + si2._y)
- return (si1._x + si1._y < si2._x + si2._y);
+ // Higher screenspace left drawn before?
+ if (si1._sxLeft != si2._sxLeft)
+ return si1._sxLeft > si2._sxLeft;
+
+ // Lower screenspace bottom drawn before?
+ if (si1._syBot != si2._syBot)
+ return si1._syBot < si2._syBot;
+
+ //// Partial in X + Y front
+ //if (si1._x + si1._y != si2._x + si2._y)
+ // return (si1._x + si1._y < si2._x + si2._y);
- // Partial in X + Y back
- if (si1._xLeft + si1._yFar != si2._xLeft + si2._yFar)
- return (si1._xLeft + si1._yFar < si2._xLeft + si2._yFar);
+ //// Partial in X + Y back
+ //if (si1._xLeft + si1._yFar != si2._xLeft + si2._yFar)
+ // return (si1._xLeft + si1._yFar < si2._xLeft + si2._yFar);
- // Partial in y?
- if (si1._y != si2._y)
- return si1._y < si2._y;
+ //// Partial in y?
+ //if (si1._y != si2._y)
+ // return si1._y < si2._y;
- // Partial in x?
- if (si1._x != si2._x)
- return si1._x < si2._x;
+ //// Partial in x?
+ //if (si1._x != si2._x)
+ // return si1._x < si2._x;
// Just sort by shape number
if (si1._shapeNum != si2._shapeNum)
diff --git a/test/engines/ultima/ultima8/world/sort_item.h b/test/engines/ultima/ultima8/world/sort_item.h
index 4bac9d77f2d..d2d22b536e9 100644
--- a/test/engines/ultima/ultima8/world/sort_item.h
+++ b/test/engines/ultima/ultima8/world/sort_item.h
@@ -388,11 +388,57 @@ class U8SortItemTestSuite : public CxxTest::TestSuite {
TS_ASSERT(si2.below(si1));
}
+ /**
+ * Overlapping x-flats differing in y position and slightly by x position
+ * Test case for rendering issue at MainActor::teleport 37 17631 17831 104
+ */
+ void test_x_flat_layered_sort() {
+ Ultima::Ultima8::SortItem si1;
+ Ultima::Ultima8::SortItem si2;
+
+ Ultima::Ultima8::Box b1(17410, 17806, 96, 0, 96, 40);
+ si1.setBoxBounds(b1, 0, 0);
+ si1._fixed = true;
+
+ Ultima::Ultima8::Box b2(17408, 17888, 96, 0, 96, 40);
+ si2.setBoxBounds(b2, 0, 0);
+ si1._fixed = true;
+
+ TS_ASSERT(si1.overlap(si2));
+ TS_ASSERT(si2.overlap(si1));
+
+ TS_ASSERT(si1.below(si2));
+ TS_ASSERT(!si2.below(si1));
+ }
+
+ /**
+ * Overlapping y-flats differing in x position
+ * Test case for rendering issue at MainActor::teleport 8 2063 1207 48
+ */
+ void test_y_flat_layered_sort() {
+ Ultima::Ultima8::SortItem si1;
+ Ultima::Ultima8::SortItem si2;
+
+ Ultima::Ultima8::Box b1(2175, 1055, 48, 96, 0, 40);
+ si1.setBoxBounds(b1, 0, 0);
+ si1._fixed = true;
+
+ Ultima::Ultima8::Box b2(2111, 1055, 48, 96, 0, 40);
+ si2.setBoxBounds(b2, 0, 0);
+ si1._fixed = true;
+
+ TS_ASSERT(si1.overlap(si2));
+ TS_ASSERT(si2.overlap(si1));
+
+ TS_ASSERT(si1.below(si2));
+ TS_ASSERT(!si2.below(si1));
+ }
+
/**
* Completely Overlapping y-flats differing only in item number and frame
* Test case for rendering issue at MainActor::teleport 37 17628 19668 56
*/
- void test_y_flat_layered_sort() {
+ void test_y_flat_same_position_sort() {
Ultima::Ultima8::SortItem si1;
Ultima::Ultima8::SortItem si2;
More information about the Scummvm-git-logs
mailing list