aboutsummaryrefslogtreecommitdiff
path: root/engines/sword25
diff options
context:
space:
mode:
authorEugene Sandulenko2010-09-03 21:49:33 +0000
committerEugene Sandulenko2010-10-12 23:33:51 +0000
commit5f83fd19540c3072f50edff0acddf1cb6a072b78 (patch)
treebd6bb1991fc48808e5ce88ba904c7d3929f63532 /engines/sword25
parentdcf70dc6a66c054c6cb9398ff68a12c38cc4223c (diff)
downloadscummvm-rg350-5f83fd19540c3072f50edff0acddf1cb6a072b78.tar.gz
scummvm-rg350-5f83fd19540c3072f50edff0acddf1cb6a072b78.tar.bz2
scummvm-rg350-5f83fd19540c3072f50edff0acddf1cb6a072b78.zip
SWORD25: Load and parse vector images
Libart is temporary solution. svn-id: r53313
Diffstat (limited to 'engines/sword25')
-rw-r--r--engines/sword25/gfx/image/vectorimage.cpp165
-rw-r--r--engines/sword25/gfx/image/vectorimage.h30
-rw-r--r--engines/sword25/gfx/opengl/openglgfx.cpp2
-rw-r--r--engines/sword25/module.mk3
4 files changed, 128 insertions, 72 deletions
diff --git a/engines/sword25/gfx/image/vectorimage.cpp b/engines/sword25/gfx/image/vectorimage.cpp
index 35da539597..45e81b6f71 100644
--- a/engines/sword25/gfx/image/vectorimage.cpp
+++ b/engines/sword25/gfx/image/vectorimage.cpp
@@ -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,27 +200,29 @@ uint32 flashColorToAGGRGBA8(uint flashColor) {
// 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);
-
- 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);
+ return Common::Rect(static_cast<int>(x0), static_cast<int>(y0), static_cast<int>(x1) + 1, static_cast<int>(y1) + 1);
}
+
}
@@ -302,7 +307,38 @@ VectorImage::VectorImage(const byte *pFileData, uint fileSize, bool &success) {
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 @@ bool VectorImage::parseDefineShape(uint shapeType, SWFBitStream &bs) {
// 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 @@ bool VectorImage::parseDefineShape(uint shapeType, SWFBitStream &bs) {
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 @@ bool VectorImage::parseDefineShape(uint shapeType, SWFBitStream &bs) {
// 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ückgesetzt
-#if 0 // TODO
- double lastX = _elements.back()._paths.last_x();
- double lastY = _elements.back()._paths.last_y();
-
- // 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
+ // Store previous curve if any
+ if (bezNodes) {
+ bez = storeBez(bez, lineStyle, fillStyle0, fillStyle1, &bezNodes, &bezAllocated);
+ }
+
+ // 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 @@ bool VectorImage::parseDefineShape(uint shapeType, SWFBitStream &bs) {
// 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);
-
-#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 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;
+
+ 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 @@ bool VectorImage::parseDefineShape(uint shapeType, SWFBitStream &bs) {
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)
diff --git a/engines/sword25/gfx/image/vectorimage.h b/engines/sword25/gfx/image/vectorimage.h
index 7f14da907c..e5688078ee 100644
--- a/engines/sword25/gfx/image/vectorimage.h
+++ b/engines/sword25/gfx/image/vectorimage.h
@@ -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 VectorImage;
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 @@ public:
}
private:
- uint _id;
+ ArtVpath *_vec;
uint _lineStyle;
uint _fillStyle0;
uint _fillStyle1;
@@ -95,12 +96,6 @@ private:
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 @@ private:
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 @@ private:
class VectorImage : public Image {
public:
VectorImage(const byte *pFileData, uint fileSize, bool &success);
+ ~VectorImage();
uint getElementCount() const {
return _elements.size();
@@ -223,6 +216,7 @@ private:
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;
};
diff --git a/engines/sword25/gfx/opengl/openglgfx.cpp b/engines/sword25/gfx/opengl/openglgfx.cpp
index 0401a99e4d..77fc416c77 100644
--- a/engines/sword25/gfx/opengl/openglgfx.cpp
+++ b/engines/sword25/gfx/opengl/openglgfx.cpp
@@ -326,6 +326,8 @@ Resource *OpenGLGfx::LoadResource(const Common::String &FileName) {
// 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);
diff --git a/engines/sword25/module.mk b/engines/sword25/module.mk
index 0abeb5e01a..40be7fad24 100644
--- a/engines/sword25/module.mk
+++ b/engines/sword25/module.mk
@@ -110,7 +110,8 @@ MODULE_OBJS := \
$(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)