aboutsummaryrefslogtreecommitdiff
path: root/engines/wage/design.cpp
diff options
context:
space:
mode:
authorEugene Sandulenko2015-12-18 18:02:10 +0100
committerEugene Sandulenko2015-12-27 15:40:53 +0100
commit8950bd52482e316f5d38e36332d6b1ea056fdd61 (patch)
tree566ff643013658cd2caa59c566f8b0cda300592e /engines/wage/design.cpp
parentc00bd70f02f3523930dbe5072575b04eff37dd4d (diff)
downloadscummvm-rg350-8950bd52482e316f5d38e36332d6b1ea056fdd61.tar.gz
scummvm-rg350-8950bd52482e316f5d38e36332d6b1ea056fdd61.tar.bz2
scummvm-rg350-8950bd52482e316f5d38e36332d6b1ea056fdd61.zip
WAGE: Implemented drawing of think lines
Diffstat (limited to 'engines/wage/design.cpp')
-rw-r--r--engines/wage/design.cpp193
1 files changed, 190 insertions, 3 deletions
diff --git a/engines/wage/design.cpp b/engines/wage/design.cpp
index 31835f88d6..1388db974f 100644
--- a/engines/wage/design.cpp
+++ b/engines/wage/design.cpp
@@ -51,6 +51,14 @@
namespace Wage {
+struct plotData {
+ Graphics::Surface *surface;
+ Patterns *patterns;
+ int fillType;
+ int x0;
+ int y0;
+};
+
Design::Design(Common::SeekableReadStream *data) {
_len = data->readUint16BE() - 2;
_data = (byte *)malloc(_len);
@@ -110,6 +118,15 @@ void Design::paint(Graphics::Surface *canvas, Patterns &patterns, bool mask) {
}
}
+void drawPixel(int x, int y, int color, void *data) {
+ plotData *p = (plotData *)data;
+
+ if (x >= 0 && x < p->surface->w && y >= 0 && y < p->surface->h)
+ *((byte *)p->surface->getBasePtr(x, y)) =
+ ((*p->patterns)[p->fillType - 1][(y - p->y0) % 8] & (1 << (7 - (x - p->x0) % 8))) ?
+ kColorBlack : kColorWhite;
+}
+
void Design::drawRect(Graphics::Surface *surface, Common::ReadStream &in, bool mask,
Patterns &patterns, byte fillType, byte borderThickness, byte borderFillType) {
int16 y1 = in.readSint16BE();
@@ -129,6 +146,8 @@ void Design::drawRect(Graphics::Surface *surface, Common::ReadStream &in, bool m
void Design::drawPolygon(Graphics::Surface *surface, Common::ReadStream &in, bool mask,
Patterns &patterns, byte fillType, byte borderThickness, byte borderFillType) {
+ plotData pd;
+
//surface->setColor(Color.BLACK);
//in.readUint16BE();
warning("ignored => %d", in.readSint16BE());
@@ -143,6 +162,12 @@ void Design::drawPolygon(Graphics::Surface *surface, Common::ReadStream &in, boo
Common::Rect bbox(bx1, by1, bx2, by2);
warning("Bbox: %d, %d, %d, %d", bx1, by1, bx2, by2);
+ pd.surface = surface;
+ pd.patterns = &patterns;
+ pd.fillType = fillType;
+ pd.x0 = bx1;
+ pd.y0 = by1;
+
numBytes -= 8;
int y1 = in.readSint16BE();
@@ -224,6 +249,12 @@ void Design::drawPolygon(Graphics::Surface *surface, Common::ReadStream &in, boo
// surface->setStroke(oldStroke);
// }
+ pd.fillType = borderFillType;
+ if (borderThickness > 0) {
+ for (int i = 1; i < npoints; i++)
+ drawThickLine(xpoints[i-1], ypoints[i-1], xpoints[i], ypoints[i], borderThickness, kColorBlack, drawPixel, &pd);
+ }
+
free(xpoints);
free(ypoints);
}
@@ -349,9 +380,6 @@ void Design::patternThickPolygon(Graphics::Surface *surface, Patterns &patterns,
}
free(nodeX);
-
- for (i = 1; i < npoints; i++)
- surface->drawLine(polyX[i-1], polyY[i-1], polyX[i], polyY[i], kColorBlack);
}
void Design::drawOval(Graphics::Surface *surface, Common::ReadStream &in, bool mask,
@@ -410,5 +438,164 @@ void Design::patternHLine(Graphics::Surface *surface, Patterns &patterns, byte f
kColorBlack : kColorWhite;
}
+void Design::patternVLine(Graphics::Surface *surface, Patterns &patterns, byte fillType, int x, int y1, int y2, int x0, int y0) {
+ if (y1 > y2)
+ SWAP(y1, y2);
+
+ if (fillType > patterns.size())
+ return;
+
+ for (int y = y1; y < y2; y++)
+ if (x >= 0 && x < surface->w && y >= 0 && y < surface->h)
+ *((byte *)surface->getBasePtr(x, y)) =
+ (patterns[fillType - 1][(y - y0) % 8] & (1 << (7 - (x - x0) % 8))) ?
+ kColorBlack : kColorWhite;
+}
+
+/* Bresenham as presented in Foley & Van Dam */
+/* Code is based on GD lib http://libgd.github.io/ */
+void Design::drawThickLine (int x1, int y1, int x2, int y2, int thick, int color,
+ void (*plotProc)(int, int, int, void *), void *data) {
+ int incr1, incr2, d, x, y, xend, yend, xdirflag, ydirflag;
+ int wid;
+ int w, wstart;
+
+ int dx = abs(x2 - x1);
+ int dy = abs(y2 - y1);
+
+/*
+ if (dx == 0) {
+ patternVLine(surface, patterns, fillType, x1, y1, y2, x1, y1);
+ return;
+ } else if (dy == 0) {
+ patternHLine(surface, patterns, fillType, x1, x2, y1, x1, y1);
+ return;
+ }
+*/
+ if (dy <= dx) {
+ /* More-or-less horizontal. use wid for vertical stroke */
+ /* Doug Claar: watch out for NaN in atan2 (2.0.5) */
+
+ /* 2.0.12: Michael Schwartz: divide rather than multiply;
+ TBB: but watch out for /0! */
+ double ac = cos(atan2 (dy, dx));
+ if (ac != 0) {
+ wid = thick / ac;
+ } else {
+ wid = 1;
+ }
+ if (wid == 0) {
+ wid = 1;
+ }
+ d = 2 * dy - dx;
+ incr1 = 2 * dy;
+ incr2 = 2 * (dy - dx);
+ if (x1 > x2) {
+ x = x2;
+ y = y2;
+ ydirflag = (-1);
+ xend = x1;
+ } else {
+ x = x1;
+ y = y1;
+ ydirflag = 1;
+ xend = x2;
+ }
+
+ /* Set up line thickness */
+ wstart = y - wid / 2;
+ for (w = wstart; w < wstart + wid; w++)
+ (*plotProc)(x, y, color, data);
+
+ if (((y2 - y1) * ydirflag) > 0) {
+ while (x < xend) {
+ x++;
+ if (d < 0) {
+ d += incr1;
+ } else {
+ y++;
+ d += incr2;
+ }
+ wstart = y - wid / 2;
+ for (w = wstart; w < wstart + wid; w++)
+ (*plotProc)(x, w, color, data);
+ }
+ } else {
+ while (x < xend) {
+ x++;
+ if (d < 0) {
+ d += incr1;
+ } else {
+ y--;
+ d += incr2;
+ }
+ wstart = y - wid / 2;
+ for (w = wstart; w < wstart + wid; w++)
+ (*plotProc)(x, w, color, data);
+ }
+ }
+ } else {
+ /* More-or-less vertical. use wid for horizontal stroke */
+ /* 2.0.12: Michael Schwartz: divide rather than multiply;
+ TBB: but watch out for /0! */
+ double as = sin(atan2(dy, dx));
+ if (as != 0) {
+ wid = thick / as;
+ } else {
+ wid = 1;
+ }
+ if (wid == 0)
+ wid = 1;
+
+ d = 2 * dx - dy;
+ incr1 = 2 * dx;
+ incr2 = 2 * (dx - dy);
+ if (y1 > y2) {
+ y = y2;
+ x = x2;
+ yend = y1;
+ xdirflag = (-1);
+ } else {
+ y = y1;
+ x = x1;
+ yend = y2;
+ xdirflag = 1;
+ }
+
+ /* Set up line thickness */
+ wstart = x - wid / 2;
+ for (w = wstart; w < wstart + wid; w++)
+ (*plotProc)(w, y, color, data);
+
+ if (((x2 - x1) * xdirflag) > 0) {
+ while (y < yend) {
+ y++;
+ if (d < 0) {
+ d += incr1;
+ } else {
+ x++;
+ d += incr2;
+ }
+ wstart = x - wid / 2;
+ for (w = wstart; w < wstart + wid; w++)
+ (*plotProc)(w, y, color, data);
+ }
+ } else {
+ while (y < yend) {
+ y++;
+ if (d < 0) {
+ d += incr1;
+ } else {
+ x--;
+ d += incr2;
+ }
+ wstart = x - wid / 2;
+ for (w = wstart; w < wstart + wid; w++)
+ (*plotProc)(w, y, color, data);
+ }
+ }
+ }
+}
+
} // End of namespace Wage