[Scummvm-cvs-logs] SF.net SVN: scummvm:[39618] scummvm/trunk/engines/tinsel/polygons.cpp

fingolfin at users.sourceforge.net fingolfin at users.sourceforge.net
Mon Mar 23 00:02:54 CET 2009


Revision: 39618
          http://scummvm.svn.sourceforge.net/scummvm/?rev=39618&view=rev
Author:   fingolfin
Date:     2009-03-22 23:02:54 +0000 (Sun, 22 Mar 2009)

Log Message:
-----------
TINSEL: More polygon code cleanup

Modified Paths:
--------------
    scummvm/trunk/engines/tinsel/polygons.cpp

Modified: scummvm/trunk/engines/tinsel/polygons.cpp
===================================================================
--- scummvm/trunk/engines/tinsel/polygons.cpp	2009-03-22 23:02:09 UTC (rev 39617)
+++ scummvm/trunk/engines/tinsel/polygons.cpp	2009-03-22 23:02:54 UTC (rev 39618)
@@ -135,21 +135,38 @@
 
 #include "common/pack-end.h"	// END STRUCT PACKING
 
-// POLY structure class. This is implemented as a class, because the structure
-// of POLY's changed between TINSEL v1 and v2
+/**
+ * POLY structure class. This is implemented as a class, because the structure
+ * of POLY's changed between TINSEL v1 and v2.
+ * 
+ * FIXME: Right now, we always read *all* data in a polygon, even if only a single
+ * field is needed. This is rather inefficient.
+ */
 class Poly {
 private:
 	const byte * const  _pStart;
 	const byte *_pData;
 	int _recordSize;
 	void nextPoly();
+
 public:
 	Poly(const byte *pSrc);
 	Poly(const byte *pSrc, int startIndex);
 	void operator++();
 	void setIndex(int index);
 
+
+	POLY_TYPE getType() const { return (POLY_TYPE)FROM_LE_32(type); }
+	int getNodecount() const { return (int)FROM_LE_32(nodecount); }
+	int getNodeX(int i) const { return (int)FROM_LE_32(nlistx[i]); }
+	int getNodeY(int i) const { return (int)FROM_LE_32(nlisty[i]); }
+
+	// get Inter-node line structure
+	LINEINFO *getLineinfo(int i) const { return ((LINEINFO *)(_pStart + (int)FROM_LE_32(plinelist))) + i; }
+
+protected:
 	POLY_TYPE type;		//!< type of polygon
+public:
 	int32 x[4], y[4];	// Polygon definition
 	uint32 xoff, yoff;	// DW2 - polygon offset
 
@@ -169,7 +186,7 @@
 	int32 reel;			// } PATH and NPATH
 	int32 zFactor;		// }
 
-	//The arrays now stored externally
+protected:
 	int32 nodecount;		//!<The number of nodes in this polygon
 	int32 pnodelistx, pnodelisty;	//!<offset in chunk to this array if present
 	int32 plinelist;
@@ -177,6 +194,7 @@
 	int32 *nlistx;
 	int32 *nlisty;
 
+public:
 	SCNHANDLE hScript;	//!< handle of code segment for polygon events
 };
 
@@ -209,9 +227,8 @@
 }
 
 void Poly::nextPoly() {
-	// Note: Originally I used a Serialiser, but dropped because for now we want
-	// the endian to remain as it is. It may be cleaner to later on switch to using
-	// it, and removing all endian conversions from the code that uses POLY's
+	// Note: For now we perform no endian conversion of the data. We could change that
+	// at some point, and remove all endian conversions from the code that uses POLY's
 	const byte *pRecord = _pData;
 
 	int typeVal = nextLong(_pData);
@@ -403,7 +420,6 @@
 /**
  * Finds a polygon of the specified type containing the supplied point.
  */
-
 HPOLYGON InPolygon(int xt, int yt, PTYPE type) {
 	for (int j = 0; j <= MAX_POLY; j++)	{
 		if (Polys[j] && Polys[j]->polyType == type) {
@@ -558,7 +574,6 @@
 	int	dropD;		// length of perpendicular (i.e. distance of point from line)
 	int	dropX, dropY;	// (X, Y) where dropped perpendicular intersects the line
 	int	d1, d2;		// distance from perpendicular intersect to line's end nodes
-	int32	*nlistx, *nlisty;
 
 	int	shortestD = 10000;	// Shortest distance found
 	int	nearestL = -1;		// Nearest line
@@ -566,7 +581,6 @@
 
 	int	h = *x;		// For readability/conveniance
 	int	k = *y;		//	- why aren't these #defines?
-	LINEINFO *llist;		// Inter-node line structure
 
 	CHECK_HP(hp, "Out of range polygon handle (3)");
 	pp = Polys[hp];
@@ -575,16 +589,14 @@
 	pps = LockMem(pHandle);	// All polygons
 	Poly ptp(pps, pp->pIndex);	// This polygon
 
-	nlistx = ptp.nlistx;
-	nlisty = ptp.nlisty;
-	llist = (LINEINFO *)(pps + (int)FROM_LE_32(ptp.plinelist));
-
 	// Look for fit of perpendicular to lines between nodes
-	for (int i = 0; i < (int)FROM_LE_32(ptp.nodecount) - 1; i++) {
-		const int32	a = (int)FROM_LE_32(llist[i].a);
-		const int32	b = (int)FROM_LE_32(llist[i].b);
-		const int32	c = (int)FROM_LE_32(llist[i].c);
+	for (int i = 0; i < ptp.getNodecount() - 1; i++) {
+		LINEINFO *line = ptp.getLineinfo(i);
 
+		const int32	a = (int)FROM_LE_32(line->a);
+		const int32	b = (int)FROM_LE_32(line->b);
+		const int32	c = (int)FROM_LE_32(line->c);
+
 #if 1
 		// TODO: If the comments of the LINEINFO struct are correct, then it contains mostly
 		// duplicate data, probably in an effort to safe CPU cycles. Even on the slowest devices
@@ -598,7 +610,6 @@
 		// One bad thing: We use sqrt to compute a square root. Might not be a good idea,
 		// speed wise. Maybe we should take Vicent's fp_sqroot. But that's a problem for later.
 
-		LINEINFO *line = &llist[i];
 		int32	a2 = (int)FROM_LE_32(line->a2);             //!< a squared
 		int32	b2 = (int)FROM_LE_32(line->b2);             //!< b squared
 		int32	a2pb2 = (int)FROM_LE_32(line->a2pb2);          //!< a squared + b squared
@@ -626,8 +637,8 @@
 		dropX = ((b*b * h) - (a*b * k) - a*c) / (a*a + b*b);
 
 		// X distances from intersection to end nodes
-		d1 = dropX - (int)FROM_LE_32(nlistx[i]);
-		d2 = dropX - (int)FROM_LE_32(nlistx[i+1]);
+		d1 = dropX - ptp.getNodeX(i);
+		d2 = dropX - ptp.getNodeX(i+1);
 
 		// if both -ve or both +ve, no fit
 		if ((d1 < 0 && d2 < 0) || (d1 > 0 && d2 > 0))
@@ -637,8 +648,8 @@
 		dropY = ((a*a * k) - (a*b * h) - b*c) / (a*a + b*b);
 
 		// Y distances from intersection to end nodes
-		d1 = dropY - (int)FROM_LE_32(nlisty[i]);
-		d2 = dropY - (int)FROM_LE_32(nlisty[i+1]);
+		d1 = dropY - ptp.getNodeY(i);
+		d2 = dropY - ptp.getNodeY(i+1);
 
 		// if both -ve or both +ve, no fit
 		if ((d1 < 0 && d2 < 0) || (d1 > 0 && d2 > 0))
@@ -654,21 +665,22 @@
 
 	// Distance to nearest node
 	nearestN = NearestNodeWithin(hp, h, k);
-	dropD = ABS(h - (int)FROM_LE_32(nlistx[nearestN])) + ABS(k - (int)FROM_LE_32(nlisty[nearestN]));
+	dropD = ABS(h - ptp.getNodeX(nearestN)) + ABS(k - ptp.getNodeY(nearestN));
 
 	// Go to a node or a point on a line
 	if (dropD < shortestD) {
 		// A node is nearest
-		*x = (int)FROM_LE_32(nlistx[nearestN]);
-		*y = (int)FROM_LE_32(nlisty[nearestN]);
+		*x = ptp.getNodeX(nearestN);
+		*y = ptp.getNodeY(nearestN);
 		*pline = nearestN;
 	} else {
 		assert(nearestL != -1);
 
 		// A point on a line is nearest
-		const int32	a = (int)FROM_LE_32(llist[nearestL].a);
-		const int32	b = (int)FROM_LE_32(llist[nearestL].b);
-		const int32	c = (int)FROM_LE_32(llist[nearestL].c);
+		LINEINFO *line = ptp.getLineinfo(nearestL);
+		const int32	a = (int)FROM_LE_32(line->a);
+		const int32	b = (int)FROM_LE_32(line->b);
+		const int32	c = (int)FROM_LE_32(line->c);
 		dropX = ((b*b * h) - (a*b * k) - a*c) / (a*a + b*b);
 		dropY = ((a*a * k) - (a*b * h) - b*c) / (a*a + b*b);
 		*x = dropX;
@@ -811,7 +823,6 @@
 
 	int	d1, d2;
 	uint8	*pps;		// Compiled polygon data
-	int32	*nlistx, *nlisty;
 
 	CHECK_HP(hPath, "Out of range polygon handle (8)");
 	pp = Polys[hPath];
@@ -819,15 +830,12 @@
 	pps = LockMem(pHandle);		// All polygons
 	Poly ptp(pps, pp->pIndex);	// This polygon
 
-	nlistx = ptp.nlistx;
-	nlisty = ptp.nlisty;
+	const int nodecount = ptp.getNodecount() - 1;
 
-	const int nodecount = (int)FROM_LE_32(ptp.nodecount);
+	d1 = ABS(x - ptp.getNodeX(0)) + ABS(y - ptp.getNodeY(0));
+	d2 = ABS(x - ptp.getNodeX(nodecount)) + ABS(y - ptp.getNodeY(nodecount));
 
-	d1 = ABS(x - (int)FROM_LE_32(nlistx[0])) + ABS(y - (int)FROM_LE_32(nlisty[0]));
-	d2 = ABS(x - (int)FROM_LE_32(nlistx[nodecount - 1])) + ABS(y - (int)FROM_LE_32(nlisty[nodecount - 1]));
-
-	return (d2 > d1) ? 0 : nodecount - 1;
+	return (d2 > d1) ? 0 : nodecount;
 }
 
 
@@ -839,7 +847,6 @@
 int NearEndNode(HPOLYGON hSpath, HPOLYGON hDpath) {
 	const POLYGON *pSpath, *pDpath;
 
-	int	ns, nd;		// 'top' nodes in each path
 	int	dist, NearDist;
 	int	NearNode;
 	uint8	*pps;		// Compiled polygon data
@@ -853,27 +860,28 @@
 	Poly ps(pps, pSpath->pIndex);	// Start polygon
 	Poly pd(pps, pDpath->pIndex);	// Dest polygon
 
-	ns = (int)FROM_LE_32(ps.nodecount) - 1;
-	nd = (int)FROM_LE_32(pd.nodecount) - 1;
+	// 'top' nodes in each path
+	const int ns = ps.getNodecount() - 1;
+	const int nd = pd.getNodecount() - 1;
 
 	// start[0] to dest[0]
-	NearDist = ABS((int)FROM_LE_32(ps.nlistx[0]) - (int)FROM_LE_32(pd.nlistx[0])) + ABS((int)FROM_LE_32(ps.nlisty[0]) - (int)FROM_LE_32(pd.nlisty[0]));
+	NearDist = ABS(ps.getNodeX(0) - pd.getNodeX(0)) + ABS(ps.getNodeY(0) - pd.getNodeY(0));
 	NearNode = 0;
 
 	// start[0] to dest[top]
-	dist = ABS((int)FROM_LE_32(ps.nlistx[0]) - (int)FROM_LE_32(pd.nlistx[nd])) + ABS((int)FROM_LE_32(ps.nlisty[0]) - (int)FROM_LE_32(pd.nlisty[nd]));
+	dist = ABS(ps.getNodeX(0) - pd.getNodeX(nd)) + ABS(ps.getNodeY(0) - pd.getNodeY(nd));
 	if (dist < NearDist)
 		NearDist = dist;
 
 	// start[top] to dest[0]
-	dist = ABS((int)FROM_LE_32(ps.nlistx[ns]) - (int)FROM_LE_32(pd.nlistx[0])) + ABS((int)FROM_LE_32(ps.nlisty[ns]) - (int)FROM_LE_32(pd.nlisty[0]));
+	dist = ABS(ps.getNodeX(ns) - pd.getNodeX(0)) + ABS(ps.getNodeY(ns) - pd.getNodeY(0));
 	if (dist < NearDist) {
 		NearDist = dist;
 		NearNode = ns;
 	}
 
 	// start[top] to dest[top]
-	dist = ABS((int)FROM_LE_32(ps.nlistx[ns]) - (int)FROM_LE_32(pd.nlistx[nd])) + ABS((int)FROM_LE_32(ps.nlisty[ns]) - (int)FROM_LE_32(pd.nlisty[nd]));
+	dist = ABS(ps.getNodeX(ns) - pd.getNodeX(nd)) + ABS(ps.getNodeY(ns) - pd.getNodeY(nd));
 	if (dist < NearDist) {
 		NearNode = ns;
 	}
@@ -887,7 +895,6 @@
  */
 int NearestNodeWithin(HPOLYGON hNpath, int x, int y) {
 	int	ThisDistance, SmallestDistance = 1000;
-	int	NumNodes;	// Number of nodes in this follow nodes path
 	int	NearestYet = 0;	// Number of nearest node
 	uint8	*pps;		// Compiled polygon data
 
@@ -896,10 +903,10 @@
 	pps = LockMem(pHandle);		// All polygons
 	Poly ptp(pps, Polys[hNpath]->pIndex);	// This polygon
 
-	NumNodes = (int)FROM_LE_32(ptp.nodecount);
+	const int numNodes = ptp.getNodecount();	// Number of nodes in this follow nodes path
 
-	for (int i = 0; i < NumNodes; i++) {
-		ThisDistance = ABS(x - (int)FROM_LE_32(ptp.nlistx[i])) + ABS(y - (int)FROM_LE_32(ptp.nlisty[i]));
+	for (int i = 0; i < numNodes; i++) {
+		ThisDistance = ABS(x - ptp.getNodeX(i)) + ABS(y - ptp.getNodeY(i));
 
 		if (ThisDistance < SmallestDistance) {
 			NearestYet = i;
@@ -1066,11 +1073,11 @@
 	Poly ptp(pps, Polys[hNpath]->pIndex);	// This polygon
 
 	// Might have just walked to the node from above.
-	if (node == (int)FROM_LE_32(ptp.nodecount))
+	if (node == ptp.getNodecount())
 		node -= 1;
 
-	*px = (int)FROM_LE_32(ptp.nlistx[node]);
-	*py = (int)FROM_LE_32(ptp.nlisty[node]);
+	*px = ptp.getNodeX(node);
+	*py = ptp.getNodeY(node);
 }
 
 /**
@@ -1135,7 +1142,7 @@
 
 	Poly pp(LockMem(pHandle), Polys[hp]->pIndex);
 
-	return (int)FROM_LE_32(pp.nodecount);
+	return pp.getNodecount();
 }
 
 // *************************************************************************
@@ -1411,17 +1418,15 @@
 		if (rp && rp->polyType == PATH && rp->subtype == NODE) { //...if it's a node path
 			// Get compiled polygon structure
 			cp = (const Poly *)pps + rp->pIndex;	// This polygon
-			nlistx = cp->nlistx;
-			nlisty = cp->nlisty;
 
-			n = (int)FROM_LE_32(cp->nodecount) - 1;		// Last node
+			n = cp->getNodecount() - 1;		// Last node
 			assert(n >= 1); // Node paths must have at least 2 nodes
 
 			hp = PolygonIndex(rp);
 			for (j = 0; j <= n; j++) {
-				if (!IsInPolygon((int)FROM_LE_32(nlistx[j]), (int)FROM_LE_32(nlisty[j]), hp)) {
+				if (!IsInPolygon(cp->getNodeX(j), cp->getNodeY(j), hp)) {
 					sprintf(TextBufferAddr(), "Node (%d, %d) is not in its own path (starting (%d, %d))",
-						 (int)FROM_LE_32(nlistx[j]), (int)FROM_LE_32(nlisty[j]), rp->cx[0], rp->cy[0]);
+						 cp->getNodeX(j), cp->getNodeY(j), rp->cx[0], rp->cy[0]);
 					error(TextBufferAddr());
 				}
 			}
@@ -1431,14 +1436,14 @@
 				if (rp->adjpaths[j] == NULL)
 					break;
 
-				if (IsInPolygon((int)FROM_LE_32(nlistx[0]), (int)FROM_LE_32(nlisty[0]), PolygonIndex(rp->adjpaths[j]))) {
+				if (IsInPolygon(cp->getNodeX(0), cp->getNodeY(0), PolygonIndex(rp->adjpaths[j]))) {
 					sprintf(TextBufferAddr(), "Node (%d, %d) is in another path (starting (%d, %d))",
-						 (int)FROM_LE_32(nlistx[0]), (int)FROM_LE_32(nlisty[0]), rp->adjpaths[j]->cx[0], rp->adjpaths[j]->cy[0]);
+						 cp->getNodeX(0), cp->getNodeY(0), rp->adjpaths[j]->cx[0], rp->adjpaths[j]->cy[0]);
 					error(TextBufferAddr());
 				}
-				if (IsInPolygon((int)FROM_LE_32(nlistx[n]), (int)FROM_LE_32(nlisty[n]), PolygonIndex(rp->adjpaths[j]))) {
+				if (IsInPolygon(cp->getNodeX(n), cp->getNodeY(n), PolygonIndex(rp->adjpaths[j]))) {
 					sprintf(TextBufferAddr(), "Node (%d, %d) is in another path (starting (%d, %d))",
-						 (int)FROM_LE_32(nlistx[n]), (int)FROM_LE_32(nlisty[n]), rp->adjpaths[j]->cx[0], rp->adjpaths[j]->cy[0]);
+						 cp->getNodeX(n), cp->getNodeY(n), rp->adjpaths[j]->cx[0], rp->adjpaths[j]->cy[0]);
 					error(TextBufferAddr());
 				}
 			}
@@ -1828,7 +1833,7 @@
 		Poly pp(LockMem(ph));
 
 		for (int i = 0; i < numPoly; ++i, ++pp) {
-			switch (FROM_LE_32(pp.type)) {
+			switch (pp.getType()) {
 			case POLY_PATH:
 				InitPath(pp, false, i, bRestart);
 				break;


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list