[Scummvm-cvs-logs] SF.net SVN: scummvm:[53313] scummvm/trunk/engines/sword25

sev at users.sourceforge.net sev at users.sourceforge.net
Wed Oct 13 01:33:51 CEST 2010


Revision: 53313
          http://scummvm.svn.sourceforge.net/scummvm/?rev=53313&view=rev
Author:   sev
Date:     2010-10-12 23:33:51 +0000 (Tue, 12 Oct 2010)

Log Message:
-----------
SWORD25: Load and parse vector images

Libart is temporary solution.

Modified Paths:
--------------
    scummvm/trunk/engines/sword25/gfx/image/vectorimage.cpp
    scummvm/trunk/engines/sword25/gfx/image/vectorimage.h
    scummvm/trunk/engines/sword25/gfx/opengl/openglgfx.cpp
    scummvm/trunk/engines/sword25/module.mk

Modified: scummvm/trunk/engines/sword25/gfx/image/vectorimage.cpp
===================================================================
--- scummvm/trunk/engines/sword25/gfx/image/vectorimage.cpp	2010-10-12 23:33:23 UTC (rev 53312)
+++ scummvm/trunk/engines/sword25/gfx/image/vectorimage.cpp	2010-10-12 23:33:51 UTC (rev 53313)
@@ -41,10 +41,13 @@
 
 #include "graphics/colormasks.h"
 
+#include <libart_lgpl/art_vpath_bpath.h>
+
 namespace Sword25 {
 
 #define BS_LOG_PREFIX "VECTORIMAGE"
 
+#define BEZSMOOTHNESS 0.5
 
 // -----------------------------------------------------------------------------
 // SWF Datentypen
@@ -197,28 +200,30 @@
 // Berechnet die Bounding-Box eines BS_VectorImageElement
 // -----------------------------------------------------------------------------
 
-struct CBBGetId {
-	CBBGetId(const VectorImageElement &vectorImageElement_) : vectorImageElement(vectorImageElement_) {}
-	unsigned operator [](unsigned i) const {
-		return vectorImageElement.getPathInfo(i).getId();
+Common::Rect CalculateBoundingBox(const VectorImageElement &vectorImageElement) {
+	double x0, y0, x1, y1;
+
+	for (int j = vectorImageElement.getPathCount() - 1; j >= 0; j--) {
+		ArtVpath *vec = vectorImageElement.getPathInfo(j).getVec();
+
+		if (vec[0].code == ART_END) {
+			continue;
+		} else {
+			x0 = x1 = vec[0].x;
+			y0 = y1 = vec[0].y;
+			for (int i = 1; vec[i].code != ART_END; i++) {
+				if (vec[i].x < x0) x0 = vec[i].x;
+				if (vec[i].x > x1) x1 = vec[i].x;
+				if (vec[i].y < y0) y0 = vec[i].y;
+				if (vec[i].y > y1) y1 = vec[i].y;
+			}
+		}
 	}
-	const VectorImageElement &vectorImageElement;
-};
 
-Common::Rect CalculateBoundingBox(const VectorImageElement &vectorImageElement) {
-#if 0 // TODO
-	agg::path_storage Path = vectorImageElement.GetPaths();
-	CBBGetId IdSource(vectorImageElement);
+	return Common::Rect(static_cast<int>(x0), static_cast<int>(y0), static_cast<int>(x1) + 1, static_cast<int>(y1) + 1);
+}
 
-	double x1, x2, y1, y2;
-	agg::bounding_rect(Path, IdSource, 0, vectorImageElement.GetPathCount(), &x1, &y1, &x2, &y2);
-#else
-	double x1, x2, y1, y2;
-	x1 = x2 = y1 = y2 = 0;
-#endif
-	return Common::Rect(static_cast<int>(x1), static_cast<int>(y1), static_cast<int>(x2) + 1, static_cast<int>(y2) + 1);
 }
-}
 
 
 // -----------------------------------------------------------------------------
@@ -302,8 +307,39 @@
 	BS_ASSERT(false);
 }
 
-// -----------------------------------------------------------------------------
+VectorImage::~VectorImage() {
+	for (int j = _elements.size() - 1; j >= 0; j--)
+		for (int i = _elements[j].getPathCount() - 1; i >= 0; i--)
+			if (_elements[j].getPathInfo(i).getVec())
+				art_free(_elements[j].getPathInfo(i).getVec());
+}
 
+
+ArtBpath *ensureBezStorage(ArtBpath *bez, int nodes, int *allocated) {
+	if (*allocated <= nodes) {
+		(*allocated) += 20;
+
+		return art_renew(bez, ArtBpath, *allocated);
+	}
+
+	return bez;
+}
+
+ArtBpath *VectorImage::storeBez(ArtBpath *bez, int lineStyle, int fillStyle0, int fillStyle1, int *bezNodes, int *bezAllocated) {
+	(*bezNodes)++;
+
+	bez = ensureBezStorage(bez, *bezNodes, bezAllocated);
+	bez[*bezNodes].code = ART_END;
+
+	ArtVpath *vec = art_bez_path_to_vec(bez, BEZSMOOTHNESS);
+
+	_elements.back()._pathInfos.push_back(VectorPathInfo(vec, lineStyle, fillStyle0, fillStyle1));
+
+	return bez;
+}
+
+#define SWF_SCALE_FACTOR		(1/20.0)
+
 bool VectorImage::parseDefineShape(uint shapeType, SWFBitStream &bs) {
 	/*uint32 shapeID = */bs.getUInt16();
 
@@ -326,6 +362,12 @@
 	// Shaperecord parsen
 	// ------------------
 
+	double curX = 0;
+	double curY = 0;
+	int bezNodes = 0;
+	int bezAllocated = 10;
+	ArtBpath *bez = art_new(ArtBpath, bezAllocated);
+
 	bool endOfShapeDiscovered = false;
 	while (!endOfShapeDiscovered) {
 		uint32 typeFlag = bs.getBits(1);
@@ -344,12 +386,10 @@
 				endOfShapeDiscovered = true;
 			// Parameter dekodieren
 			} else {
-				int32 moveDeltaX = 0;
-				int32 moveDeltaY = 0;
 				if (stateMoveTo) {
 					uint32 moveToBits = bs.getBits(5);
-					moveDeltaX = bs.getSignedBits(moveToBits);
-					moveDeltaY = bs.getSignedBits(moveToBits);
+					curX = bs.getSignedBits(moveToBits) * SWF_SCALE_FACTOR;
+					curY = bs.getSignedBits(moveToBits) * SWF_SCALE_FACTOR;
 				}
 
 				if (stateFillStyle0) {
@@ -383,21 +423,17 @@
 
 				// Ein neuen Pfad erzeugen, es sei denn, es wurden nur neue Styles definiert
 				if (stateLineStyle || stateFillStyle0 || stateFillStyle1 || stateMoveTo) {
-					// Letzte Zeichenposition merken, beim Aufruf von start_new_path() wird die Zeichenpostionen auf 0, 0 zur\xFCckgesetzt
-#if 0 // TODO
-					double lastX = _elements.back()._paths.last_x();
-					double lastY = _elements.back()._paths.last_y();
+					// Store previous curve if any
+					if (bezNodes) {
+						bez = storeBez(bez, lineStyle, fillStyle0, fillStyle1, &bezNodes, &bezAllocated);
+					}
 
-					// Neue Pfadinformation erzeugen
-					_elements.back()._pathInfos.push_back(VectorPathInfo(_elements.back()._paths.start_new_path(), lineStyle, fillStyle0, fillStyle1));
-
-					// Falls eine Bewegung definiert wurde, wird die Zeichenpositionen an die entsprechende Position gesetzt.
-					// Ansonsten wird die Zeichenposition auf die letzte Zeichenposition gesetzt.
-					if (stateMoveTo)
-						_elements.back()._paths.move_to(moveDeltaX, moveDeltaY);
-					else
-						_elements.back()._paths.move_to(lastX, lastY);
-#endif
+					// Start new curve
+					bez = ensureBezStorage(bez, 1, &bezAllocated);
+					bez[0].code = ART_MOVETO_OPEN;
+					bez[0].x3 = curX;
+					bez[0].y3 = curY;
+					bezNodes = 0;
 				}
 			}
 		} else {
@@ -407,18 +443,30 @@
 
 			// Curved edge
 			if (edgeFlag == 0) {
-				/* int32 controlDeltaX = */bs.getSignedBits(numBits);
-				/* int32 controlDeltaY = */bs.getSignedBits(numBits);
-				/* int32 anchorDeltaX = */bs.getSignedBits(numBits);
-				/* int32 anchorDeltaY = */bs.getSignedBits(numBits);
+				double controlDeltaX = bs.getSignedBits(numBits) * SWF_SCALE_FACTOR;
+				double controlDeltaY = bs.getSignedBits(numBits) * SWF_SCALE_FACTOR;
+				double anchorDeltaX = bs.getSignedBits(numBits) * SWF_SCALE_FACTOR;
+				double anchorDeltaY = bs.getSignedBits(numBits) * SWF_SCALE_FACTOR;
 
-#if 0 // TODO
-				double controlX = _elements.back()._paths.last_x() + controlDeltaX;
-				double controlY = _elements.back()._paths.last_y() + controlDeltaY;
-				double anchorX = controlX + AnchorDeltaX;
-				double anchorY = controlY + AnchorDeltaY;
-				_elements.back()._paths.curve3(controlX, controlY, anchorX, anchorY);
-#endif
+				double newX = curX + controlDeltaX;
+				double newY = curY + controlDeltaY;
+				double anchorX = curX + anchorDeltaX;
+				double anchorY = curY + anchorDeltaY;
+
+#define WEIGHT (2.0/3.0)
+
+				bezNodes++;
+				bez = ensureBezStorage(bez, bezNodes, &bezAllocated);
+				bez[bezNodes].code = ART_CURVETO;
+				bez[bezNodes].x1 = WEIGHT * anchorX + (1 - WEIGHT) * curX;
+				bez[bezNodes].y1 = WEIGHT * anchorY + (1 - WEIGHT) * curY;
+				bez[bezNodes].x2 = WEIGHT * anchorX + (1 - WEIGHT) * newX;
+				bez[bezNodes].y2 = WEIGHT * anchorY + (1 - WEIGHT) * newY;
+				bez[bezNodes].x3 = newX;
+				bez[bezNodes].y3 = newY;
+
+				curX = newX;
+				curY = newY;
 			} else {
 				// Staight edge
 				int32 deltaX = 0;
@@ -436,13 +484,24 @@
 						deltaX = bs.getSignedBits(numBits);
 				}
 
-#if 0 // TODO
-				_elements.back()._paths.line_rel(deltaX, deltaY);
-#endif
+				curX += deltaX * SWF_SCALE_FACTOR;
+				curY += deltaY * SWF_SCALE_FACTOR;
+
+				bezNodes++;
+				bez = ensureBezStorage(bez, bezNodes, &bezAllocated);
+				bez[bezNodes].code = ART_LINETO;
+				bez[bezNodes].x3 = curX;
+				bez[bezNodes].y3 = curY;
 			}
 		}
 	}
 
+	// Store last curve
+	if (bezNodes)
+		bez = storeBez(bez, lineStyle, fillStyle0, fillStyle1, &bezNodes, &bezAllocated);
+
+	art_free(bez);
+
 	// Bounding-Boxes der einzelnen Elemente berechnen
 	Common::Array<VectorImageElement>::iterator it = _elements.begin();
 	for (; it != _elements.end(); ++it)

Modified: scummvm/trunk/engines/sword25/gfx/image/vectorimage.h
===================================================================
--- scummvm/trunk/engines/sword25/gfx/image/vectorimage.h	2010-10-12 23:33:23 UTC (rev 53312)
+++ scummvm/trunk/engines/sword25/gfx/image/vectorimage.h	2010-10-12 23:33:51 UTC (rev 53313)
@@ -43,9 +43,9 @@
 #include "sword25/gfx/image/image.h"
 #include "common/rect.h"
 
-#if 0
-#include "agg_path_storage.h"
-#endif
+#include <libart_lgpl/art_vpath.h>
+#include <libart_lgpl/art_bpath.h>
+#include <libart_lgpl/art_misc.h>
 
 namespace Sword25 {
 
@@ -60,15 +60,16 @@
 
 class VectorPathInfo {
 public:
-	VectorPathInfo(uint id, uint lineStyle, uint fillStyle0, uint fillStyle1) :
-		_id(id), _lineStyle(lineStyle), _fillStyle0(fillStyle0), _fillStyle1(fillStyle1) {}
+	VectorPathInfo(ArtVpath *vec, uint lineStyle, uint fillStyle0, uint fillStyle1) :
+		_vec(vec), _lineStyle(lineStyle), _fillStyle0(fillStyle0), _fillStyle1(fillStyle1) {}
 
 	VectorPathInfo() {
-		_id = _lineStyle = _fillStyle0 = _fillStyle1 = 0;
+		_lineStyle = _fillStyle0 = _fillStyle1 = 0;
+		_vec = 0;
 	}
 
-	uint getId() const {
-		return _id;
+	ArtVpath *getVec() const {
+		return _vec;
 	}
 	uint getLineStyle() const {
 		return _lineStyle;
@@ -81,7 +82,7 @@
 	}
 
 private:
-	uint _id;
+	ArtVpath *_vec;
 	uint _lineStyle;
 	uint _fillStyle0;
 	uint _fillStyle1;
@@ -95,12 +96,6 @@
 class VectorImageElement {
 	friend class VectorImage;
 public:
-#if 0 // TODO
-	const agg::path_storage &getPaths() const {
-		return _paths;
-	}
-#endif
-
 	uint getPathCount() const {
 		return _pathInfos.size();
 	}
@@ -144,9 +139,6 @@
 		uint32 color;
 	};
 
-#if 0 // TODO
-	agg::path_storage _paths;
-#endif
 	Common::Array<VectorPathInfo> _pathInfos;
 	Common::Array<LineStyleType> _lineStyles;
 	Common::Array<uint32>  _fillStyles;
@@ -163,6 +155,7 @@
 class VectorImage : public Image {
 public:
 	VectorImage(const byte *pFileData, uint fileSize, bool &success);
+	~VectorImage();
 
 	uint getElementCount() const {
 		return _elements.size();
@@ -223,6 +216,7 @@
 	bool parseDefineShape(uint shapeType, SWFBitStream &bs);
 	bool parseStyles(uint shapeType, SWFBitStream &bs, uint &numFillBits, uint &numLineBits);
 
+	ArtBpath *storeBez(ArtBpath *bez, int lineStyle, int fillStyle0, int fillStyle1, int *bezNodes, int *bezAllocated);
 	Common::Array<VectorImageElement>    _elements;
 	Common::Rect                         _boundingBox;
 };

Modified: scummvm/trunk/engines/sword25/gfx/opengl/openglgfx.cpp
===================================================================
--- scummvm/trunk/engines/sword25/gfx/opengl/openglgfx.cpp	2010-10-12 23:33:23 UTC (rev 53312)
+++ scummvm/trunk/engines/sword25/gfx/opengl/openglgfx.cpp	2010-10-12 23:33:51 UTC (rev 53313)
@@ -326,6 +326,8 @@
 
 	// Vectorgraphik laden
 	if (FileName.hasSuffix(SWF_EXTENSION)) {
+		debug(2, "VectorImage: %s", FileName.c_str());
+
 		// Pointer auf Package-Manager holen
 		PackageManager *pPackage = Kernel::GetInstance()->GetPackage();
 		BS_ASSERT(pPackage);

Modified: scummvm/trunk/engines/sword25/module.mk
===================================================================
--- scummvm/trunk/engines/sword25/module.mk	2010-10-12 23:33:23 UTC (rev 53312)
+++ scummvm/trunk/engines/sword25/module.mk	2010-10-12 23:33:51 UTC (rev 53313)
@@ -110,7 +110,8 @@
 	$(QUIET)$(MKDIR) $(*D)/$(DEPDIR)
 	$(QUIET_CXX)gcc  $(CXX_UPDATE_DEP_FLAG) $(CXXFLAGS) $(CPPFLAGS) -c $(<) -o $*.o
 
-LIBS += -lpng -ltheoradec
+LIBS += -lpng -ltheoradec -lart_lgpl_2
+CXXFLAGS += -I/usr/include/libart-2.0
 
 # This module can be built as a plugin
 ifeq ($(ENABLE_SWORD25), DYNAMIC_PLUGIN)


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