[Scummvm-git-logs] scummvm master -> 949d8104195d044d37c22b41debfe1ef51dca207

OMGPizzaGuy noreply at scummvm.org
Fri Nov 11 00:22:17 UTC 2022


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
949d810419 ULTIMA8: Refactor item sorter to allow item trace without render surface


Commit: 949d8104195d044d37c22b41debfe1ef51dca207
    https://github.com/scummvm/scummvm/commit/949d8104195d044d37c22b41debfe1ef51dca207
Author: Matthew Jimenez (matthew.jimenez at outlook.com)
Date: 2022-11-10T18:22:03-06:00

Commit Message:
ULTIMA8: Refactor item sorter to allow item trace without render surface

This eliminates null paint method in favor of passing in a nullptr to the normal paint method and other small changes to allow item sorter use outside of the game map gump.

Changed paths:
    engines/ultima/ultima8/graphics/base_soft_render_surface.cpp
    engines/ultima/ultima8/graphics/base_soft_render_surface.h
    engines/ultima/ultima8/graphics/render_surface.h
    engines/ultima/ultima8/gumps/game_map_gump.cpp
    engines/ultima/ultima8/world/item_sorter.cpp
    engines/ultima/ultima8/world/item_sorter.h


diff --git a/engines/ultima/ultima8/graphics/base_soft_render_surface.cpp b/engines/ultima/ultima8/graphics/base_soft_render_surface.cpp
index 813d9d1767c..af6f1cbbdcf 100644
--- a/engines/ultima/ultima8/graphics/base_soft_render_surface.cpp
+++ b/engines/ultima/ultima8/graphics/base_soft_render_surface.cpp
@@ -328,25 +328,6 @@ void BaseSoftRenderSurface::SetClippingRect(const Rect &r) {
 	_clipWindow.clip(Rect(-_ox, -_oy, -_ox + _width, -_oy + _height));
 }
 
-//
-// int16 BaseSoftRenderSurface::CheckClipped(Rect &r)
-//
-// Desc: Check for a clipped rectangle
-// Returns: -1 if off screen,
-//           0 if not clipped,
-//           1 if clipped
-//
-int16 BaseSoftRenderSurface::CheckClipped(const Rect &c) const {
-	Rect r = c;
-	r.clip(_clipWindow);
-
-	// Clipped away to the void
-	if (r.isEmpty())
-		return -1;
-	else if (r == c) return 0;
-	else return 1;
-}
-
 //
 // void BaseSoftRenderSurface::SetFlipped(bool _flipped)
 //
diff --git a/engines/ultima/ultima8/graphics/base_soft_render_surface.h b/engines/ultima/ultima8/graphics/base_soft_render_surface.h
index 6d01b3e6fd7..8a85f5419e4 100644
--- a/engines/ultima/ultima8/graphics/base_soft_render_surface.h
+++ b/engines/ultima/ultima8/graphics/base_soft_render_surface.h
@@ -110,9 +110,6 @@ public:
 	// Set Clipping Rectangle
 	void SetClippingRect(const Rect &) override;
 
-	// Check Clipped. -1 if off screen, 0 if not clipped, 1 if clipped
-	int16 CheckClipped(const Rect &) const override;
-
 	// Flip the surface
 	void SetFlipped(bool flipped) override;
 
diff --git a/engines/ultima/ultima8/graphics/render_surface.h b/engines/ultima/ultima8/graphics/render_surface.h
index 05211dcac3e..f1c15006f62 100644
--- a/engines/ultima/ultima8/graphics/render_surface.h
+++ b/engines/ultima/ultima8/graphics/render_surface.h
@@ -112,9 +112,6 @@ public:
 	//! Set Clipping Rectangle
 	virtual void SetClippingRect(const Rect &) = 0;
 
-	//! Check Clipped. -1 if off screen, 0 if not clipped, 1 if clipped
-	virtual int16 CheckClipped(const Rect &) const = 0;
-
 	//! Flip the surface
 	virtual void SetFlipped(bool flipped) = 0;
 
diff --git a/engines/ultima/ultima8/gumps/game_map_gump.cpp b/engines/ultima/ultima8/gumps/game_map_gump.cpp
index ee0a4bae0f3..8880d99768c 100644
--- a/engines/ultima/ultima8/gumps/game_map_gump.cpp
+++ b/engines/ultima/ultima8/gumps/game_map_gump.cpp
@@ -45,7 +45,7 @@ bool GameMapGump::_highlightItems = false;
 GameMapGump::GameMapGump() :
 	Gump(), _displayDragging(false), _displayList(0), _draggingShape(0),
 		_draggingFrame(0), _draggingFlags(0) {
-	_displayList = new ItemSorter();
+	_displayList = new ItemSorter(2048);
 }
 
 GameMapGump::GameMapGump(int x, int y, int width, int height) :
@@ -55,8 +55,7 @@ GameMapGump::GameMapGump(int x, int y, int width, int height) :
 	// Offset the gump. We want 0,0 to be the centre
 	_dims.moveTo(-_dims.width() / 2, -_dims.height() / 2);
 
-	pout << "Create _displayList ItemSorter object" << Std::endl;
-	_displayList = new ItemSorter();
+	_displayList = new ItemSorter(2048);
 }
 
 GameMapGump::~GameMapGump() {
@@ -106,7 +105,9 @@ void GameMapGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled)
 		zlimit = roof->getZ();
 	}
 
-	_displayList->BeginDisplayList(surf, lx, ly, lz);
+	Rect clipWindow;
+	surf->GetClippingRect(clipWindow);
+	_displayList->BeginDisplayList(clipWindow, lx, ly, lz);
 
 	uint32 gametick = Kernel::get_instance()->getFrameNum();
 
@@ -165,7 +166,7 @@ void GameMapGump::PaintThis(RenderSurface *surf, int32 lerp_factor, bool scaled)
 	}
 
 
-	_displayList->PaintDisplayList(_highlightItems);
+	_displayList->PaintDisplayList(surf, _highlightItems);
 }
 
 // Trace a click, and return ObjId
diff --git a/engines/ultima/ultima8/world/item_sorter.cpp b/engines/ultima/ultima8/world/item_sorter.cpp
index ba2ee23c374..1bb7e525100 100644
--- a/engines/ultima/ultima8/world/item_sorter.cpp
+++ b/engines/ultima/ultima8/world/item_sorter.cpp
@@ -26,7 +26,6 @@
 #include "ultima/ultima8/graphics/shape_frame.h"
 #include "ultima/ultima8/graphics/main_shape_archive.h"
 #include "ultima/ultima8/graphics/render_surface.h"
-#include "ultima/ultima8/misc/rect.h"
 #include "ultima/ultima8/games/game_data.h"
 #include "ultima/ultima8/ultima8.h"
 
@@ -41,10 +40,10 @@
 namespace Ultima {
 namespace Ultima8 {
 
-ItemSorter::ItemSorter() :
-	_shapes(nullptr), _surf(nullptr), _items(nullptr), _itemsTail(nullptr),
-	_itemsUnused(nullptr), _sortLimit(0), _camSx(0), _camSy(0), _orderCounter(0) {
-	int i = 2048;
+ItemSorter::ItemSorter(int capacity) :
+	_shapes(nullptr), _clipWindow(0, 0, 0, 0), _items(nullptr), _itemsTail(nullptr),
+	_itemsUnused(nullptr), _painted(nullptr), _sortLimit(0), _camSx(0), _camSy(0) {
+	int i = capacity;
 	while (i--) _itemsUnused = new SortItem(_itemsUnused);
 }
 
@@ -66,22 +65,21 @@ ItemSorter::~ItemSorter() {
 	delete [] _items;
 }
 
-void ItemSorter::BeginDisplayList(RenderSurface *rs,
-								  int32 camx, int32 camy, int32 camz) {
+void ItemSorter::BeginDisplayList(const Rect &clipWindow, int32 camx, int32 camy, int32 camz) {
 	// Get the _shapes, if required
 	if (!_shapes) _shapes = GameData::get_instance()->getMainShapes();
 
-	//
+	// Set the clip window, and reset the item list
+	_clipWindow = clipWindow;
+
 	if (_itemsTail) {
 		_itemsTail->_next = _itemsUnused;
 		_itemsUnused = _items;
 	}
+
 	_items = nullptr;
 	_itemsTail = nullptr;
-
-	// Set the RenderSurface, and reset the item list
-	_surf = rs;
-	_orderCounter = 0;
+	_painted = nullptr;
 
 	// Screenspace bounding box bottom x coord (RNB x coord)
 	_camSx = (camx - camy) / 4;
@@ -151,7 +149,7 @@ void ItemSorter::AddItem(int32 x, int32 y, int32 z, uint32 shapeNum, uint32 fram
 	si->_sy2 = si->_sy + frame->_height;   // Bottom
 
 	// Do Clipping here
-	int16 clipped = _surf->CheckClipped(Rect(si->_sx, si->_sy, si->_sx2, si->_sy2));
+	int16 clipped = CheckClipped(Rect(si->_sx, si->_sy, si->_sx2, si->_sy2));
 	if (clipped < 0)
 		// Clipped away entirely - don't add to the list.
 		return;
@@ -252,15 +250,12 @@ void ItemSorter::AddItem(const Item *add) {
 			add->getFlags(), add->getExtFlags(), add->getObjId());
 }
 
-SortItem *_prev = nullptr;
-
-void ItemSorter::PaintDisplayList(bool item_highlight) {
-	_prev = nullptr;
+void ItemSorter::PaintDisplayList(RenderSurface *surf, bool item_highlight) {
 	SortItem *it = _items;
 	SortItem *end = nullptr;
-	_orderCounter = 0;  // Reset the _orderCounter
+	_painted = nullptr;  // Reset the paint tracking
 	while (it != end) {
-		if (it->_order == -1) if (PaintSortItem(it)) return;
+		if (it->_order == -1) if (PaintSortItem(surf, it)) return;
 		it = it->_next;
 	}
 
@@ -269,7 +264,7 @@ void ItemSorter::PaintDisplayList(bool item_highlight) {
 		it = _items;
 		while (it != end) {
 			if (!(it->_flags & (Item::FLG_DISPOSABLE | Item::FLG_FAST_ONLY)) && !it->_fixed) {
-				_surf->PaintHighlightInvis(it->_shape,
+				surf->PaintHighlightInvis(it->_shape,
 				                          it->_frame,
 				                          it->_sxBot,
 				                          it->_syBot,
@@ -287,7 +282,7 @@ void ItemSorter::PaintDisplayList(bool item_highlight) {
  * Recursively paint this item and all its dependencies.
  * Returns true if recursion should stop.
  */
-bool ItemSorter::PaintSortItem(SortItem *si) {
+bool ItemSorter::PaintSortItem(RenderSurface *surf, SortItem *si) {
 	// Don't paint this, or dependencies (yet) if occluded
 	if (si->_occluded)
 		return false;
@@ -305,94 +300,67 @@ bool ItemSorter::PaintSortItem(SortItem *si) {
 			break;
 		}
 		else if ((*it)->_order == -1) {
-			if (PaintSortItem(*it))
+			if (PaintSortItem(surf, *it))
 				return true;
 		}
 		++it;
 	}
 
-	// Set our painting _order
-	si->_order = _orderCounter;
-	_orderCounter++;
+	// Set our painting _order based on previously painted item
+	si->_order = _painted ? _painted->_order + 1 : 0;
 
 	// Now paint us!
-
-//	if (wire) si->info->draw_box_back(s, dispx, dispy, 255);
-
-	if (si->_extFlags & Item::EXT_HIGHLIGHT && si->_extFlags & Item::EXT_TRANSPARENT)
-		_surf->PaintHighlightInvis(si->_shape, si->_frame, si->_sxBot, si->_syBot, si->_trans, (si->_flags & Item::FLG_FLIPPED) != 0, 0x7F00007F);
-	if (si->_extFlags & Item::EXT_HIGHLIGHT)
-		_surf->PaintHighlight(si->_shape, si->_frame, si->_sxBot, si->_syBot, si->_trans, (si->_flags & Item::FLG_FLIPPED) != 0, 0x7F00007F);
-	else if (si->_extFlags & Item::EXT_TRANSPARENT)
-		_surf->PaintInvisible(si->_shape, si->_frame, si->_sxBot, si->_syBot, si->_trans, (si->_flags & Item::FLG_FLIPPED) != 0);
-	else if (si->_flags & Item::FLG_FLIPPED)
-		_surf->PaintMirrored(si->_shape, si->_frame, si->_sxBot, si->_syBot, si->_trans);
-	else if (si->_trans)
-		_surf->PaintTranslucent(si->_shape, si->_frame, si->_sxBot, si->_syBot);
-	else if (!si->_clipped)
-		_surf->PaintNoClip(si->_shape, si->_frame, si->_sxBot, si->_syBot);
-	else
-		_surf->Paint(si->_shape, si->_frame, si->_sxBot, si->_syBot);
-
-//	if (wire) si->info->draw_box_front(s, dispx, dispy, 255);
-
-	// weapon overlay
-	// FIXME: use highlight/invisibility, also add to Trace() ?
-	if (si->_shapeNum == 1 && si->_itemNum == 1) {
-		MainActor *av = getMainActor();
-		const WeaponOverlayFrame *wo_frame = nullptr;
-		uint32 wo_shapenum;
-		av->getWeaponOverlay(wo_frame, wo_shapenum);
-		if (wo_frame) {
-			const Shape *wo_shape = GameData::get_instance()->getMainShapes()->getShape(wo_shapenum);
-			_surf->Paint(wo_shape, wo_frame->_frame,
-			            si->_sxBot + wo_frame->_xOff,
-			            si->_syBot + wo_frame->_yOff);
+	if (surf) {
+		//	if (wire) si->info->draw_box_back(s, dispx, dispy, 255);
+
+		if (si->_extFlags & Item::EXT_HIGHLIGHT && si->_extFlags & Item::EXT_TRANSPARENT)
+			surf->PaintHighlightInvis(si->_shape, si->_frame, si->_sxBot, si->_syBot, si->_trans, (si->_flags & Item::FLG_FLIPPED) != 0, 0x7F00007F);
+		if (si->_extFlags & Item::EXT_HIGHLIGHT)
+			surf->PaintHighlight(si->_shape, si->_frame, si->_sxBot, si->_syBot, si->_trans, (si->_flags & Item::FLG_FLIPPED) != 0, 0x7F00007F);
+		else if (si->_extFlags & Item::EXT_TRANSPARENT)
+			surf->PaintInvisible(si->_shape, si->_frame, si->_sxBot, si->_syBot, si->_trans, (si->_flags & Item::FLG_FLIPPED) != 0);
+		else if (si->_flags & Item::FLG_FLIPPED)
+			surf->PaintMirrored(si->_shape, si->_frame, si->_sxBot, si->_syBot, si->_trans);
+		else if (si->_trans)
+			surf->PaintTranslucent(si->_shape, si->_frame, si->_sxBot, si->_syBot);
+		else if (!si->_clipped)
+			surf->PaintNoClip(si->_shape, si->_frame, si->_sxBot, si->_syBot);
+		else
+			surf->Paint(si->_shape, si->_frame, si->_sxBot, si->_syBot);
+
+	//	if (wire) si->info->draw_box_front(s, dispx, dispy, 255);
+
+		// weapon overlay
+		// FIXME: use highlight/invisibility, also add to Trace() ?
+		if (si->_shapeNum == 1 && si->_itemNum == 1) {
+			MainActor *av = getMainActor();
+			const WeaponOverlayFrame *wo_frame = nullptr;
+			uint32 wo_shapenum;
+			av->getWeaponOverlay(wo_frame, wo_shapenum);
+			if (wo_frame) {
+				const Shape *wo_shape = GameData::get_instance()->getMainShapes()->getShape(wo_shapenum);
+				surf->Paint(wo_shape, wo_frame->_frame,
+							si->_sxBot + wo_frame->_xOff,
+							si->_syBot + wo_frame->_yOff);
+			}
 		}
 	}
 
 	if (_sortLimit) {
-		if (_orderCounter == _sortLimit) {
-			static uint32 previt = 0;
-			if (!previt || previt != si->_itemNum) {
-				previt = si->_itemNum;
+		if (si->_order == _sortLimit) {
+			if (!_painted || _painted->_itemNum != si->_itemNum) {
 				pout << "SortItem: " << *si << Std::endl;
-				if (_prev && si->overlap(_prev)) {
-					pout << "Overlaps: " << *_prev << Std::endl;
+				if (_painted && si->overlap(_painted)) {
+					pout << "Overlaps: " << *_painted << Std::endl;
 				}
 			}
+
+			_painted = si;
 			return true;
 		}
-		_prev = si;
 	}
 
-	return false;
-}
-
-bool ItemSorter::NullPaintSortItem(SortItem *si) {
-	// Don't paint this, or dependencies if occluded
-	if (si->_occluded) return false;
-
-	// Resursion, detection
-	si->_order = -2;
-
-	// Iterate through our dependancies, and paint them, if possible
-	SortItem::DependsList::iterator it = si->_depends.begin();
-	SortItem::DependsList::iterator end = si->_depends.end();
-	while (it != end) {
-		// Well, it can't. Implies recursive sorting. Can happen though so
-		// you had best leave this commented out
-		//if ((*it)->_order == -2) CANT_HAPPEN_MSG("Recursive item sorting");
-
-		if ((*it)->_order == -1) if (NullPaintSortItem((*it))) return true;
-
-		++it;
-	}
-
-	// Set our painting/sorting _order
-	si->_order = _orderCounter;
-	_orderCounter++;
-
+	_painted = si;
 	return false;
 }
 
@@ -400,11 +368,11 @@ uint16 ItemSorter::Trace(int32 x, int32 y, HitFace *face, bool item_highlight) {
 	SortItem *it;
 	SortItem *selected;
 
-	if (!_orderCounter) { // If no _orderCounter we need to sort the _items
+	if (!_painted) { // If no painted item found, we need to sort the items
 		it = _items;
-		_orderCounter = 0;  // Reset the _orderCounter
+		_painted = nullptr;
 		while (it != nullptr) {
-			if (it->_order == -1) if (NullPaintSortItem(it)) break;
+			if (it->_order == -1) if (PaintSortItem(nullptr ,it)) break;
 
 			it = it->_next;
 		}
@@ -516,5 +484,24 @@ void ItemSorter::IncSortLimit(int count) {
 		_sortLimit = 0;
 }
 
+//
+// int16 ItemSorter::CheckClipped(Rect &r)
+//
+// Desc: Check for a clipped rectangle
+// Returns: -1 if off screen,
+//           0 if not clipped,
+//           1 if clipped
+//
+int16 ItemSorter::CheckClipped(const Rect &c) const {
+	Rect r = c;
+	r.clip(_clipWindow);
+
+	// Clipped away to the void
+	if (r.isEmpty())
+		return -1;
+	else if (r == c) return 0;
+	else return 1;
+}
+
 } // End of namespace Ultima8
 } // End of namespace Ultima
diff --git a/engines/ultima/ultima8/world/item_sorter.h b/engines/ultima/ultima8/world/item_sorter.h
index 0f227c80fa8..cf4a04b4370 100644
--- a/engines/ultima/ultima8/world/item_sorter.h
+++ b/engines/ultima/ultima8/world/item_sorter.h
@@ -22,6 +22,8 @@
 #ifndef ULTIMA8_WORLD_ITEMSORTER_H
 #define ULTIMA8_WORLD_ITEMSORTER_H
 
+#include "ultima/ultima8/misc/rect.h"
+
 namespace Ultima {
 namespace Ultima8 {
 
@@ -32,19 +34,18 @@ struct SortItem;
 
 class ItemSorter {
 	MainShapeArchive    *_shapes;
-	RenderSurface   *_surf;
+	Rect        _clipWindow;
 
 	SortItem    *_items;
 	SortItem    *_itemsTail;
 	SortItem    *_itemsUnused;
-	int32       _sortLimit;
-
-	int32       _orderCounter;
+	SortItem    *_painted;
 
+	int32       _sortLimit;
 	int32       _camSx, _camSy;
 
 public:
-	ItemSorter();
+	ItemSorter(int capacity);
 	~ItemSorter();
 
 	enum HitFace {
@@ -52,13 +53,13 @@ public:
 	};
 
 	// Begin creating the display list
-	void BeginDisplayList(RenderSurface *,
-	                      int32 camx, int32 camy, int32 camz);
+	void BeginDisplayList(const Rect &clipWindow, int32 camx, int32 camy, int32 camz);
 
 	void AddItem(int32 x, int32 y, int32 z, uint32 shape_num, uint32 frame_num, uint32 item_flags, uint32 ext_flags, uint16 item_num = 0);
 	void AddItem(const Item *);                   // Add an Item. SetupLerp() MUST have been called
 
-	void PaintDisplayList(bool item_highlight = false);             // Finishes the display list and Paints
+	// Finishes the display list and Paints
+	void PaintDisplayList(RenderSurface *surf, bool item_highlight = false);
 
 	// Trace and find an object. Returns objid.
 	// If face is non-NULL, also return the face of the 3d bbox (x,y) is on
@@ -67,8 +68,11 @@ public:
 	void IncSortLimit(int count);
 
 private:
-	bool PaintSortItem(SortItem *);
-	bool NullPaintSortItem(SortItem *);
+	bool PaintSortItem(RenderSurface *surf, SortItem *si);
+
+	//! Check Clipped. -1 if off screen, 0 if not clipped, 1 if clipped
+	int16 CheckClipped(const Rect &) const;
+
 };
 
 } // End of namespace Ultima8




More information about the Scummvm-git-logs mailing list