aboutsummaryrefslogtreecommitdiff
path: root/engines/wage/design.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/wage/design.cpp')
-rw-r--r--engines/wage/design.cpp244
1 files changed, 123 insertions, 121 deletions
diff --git a/engines/wage/design.cpp b/engines/wage/design.cpp
index 2a63436f5a..9bb3693be5 100644
--- a/engines/wage/design.cpp
+++ b/engines/wage/design.cpp
@@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
-
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
@@ -45,20 +45,23 @@
*
*/
+#include "graphics/managed_surface.h"
#include "graphics/primitives.h"
-#include "wage/wage.h"
+#include "graphics/macgui/macwindowmanager.h"
+
#include "wage/design.h"
namespace Wage {
struct PlotData {
- Graphics::Surface *surface;
- Patterns *patterns;
+ Graphics::ManagedSurface *surface;
+ Graphics::MacPatterns *patterns;
uint fillType;
int thickness;
+ Design *design;
- PlotData(Graphics::Surface *s, Patterns *p, int f, int t) :
- surface(s), patterns(p), fillType(f), thickness(t) {}
+ PlotData(Graphics::ManagedSurface *s, Graphics::MacPatterns *p, int f, int t, Design *d) :
+ surface(s), patterns(p), fillType(f), thickness(t), design(d) {}
};
void drawPixel(int x, int y, int color, void *data);
@@ -71,6 +74,8 @@ Design::Design(Common::SeekableReadStream *data) {
_surface = NULL;
_bounds = NULL;
+
+ _boundsCalculationMode = false;
}
Design::~Design() {
@@ -80,21 +85,30 @@ Design::~Design() {
delete _surface;
}
-void Design::paint(Graphics::Surface *surface, Patterns &patterns, int x, int y) {
- Common::MemoryReadStream in(_data, _len);
- Common::Rect r(0, 0, _bounds->width(), _bounds->height());
+void Design::paint(Graphics::ManagedSurface *surface, Graphics::MacPatterns &patterns, int x, int y) {
bool needRender = false;
if (_surface == NULL) {
- _surface = new Graphics::Surface;
+ _boundsCalculationMode = true;
+ _bounds->debugPrint(4, "Internal bounds:");
+ render(patterns);
+ _boundsCalculationMode = false;
+ if (_bounds->right == -10000) {
+ _bounds->left = _bounds->top = _bounds->right = _bounds->bottom = 0;
+ }
+ _bounds->debugPrint(4, "Calculated bounds:");
+
+ _surface = new Graphics::ManagedSurface;
_surface->create(_bounds->width(), _bounds->height(), Graphics::PixelFormat::createFormatCLUT8());
- _surface->fillRect(r, kColorGreen);
+
+ _surface->clear(kColorGreen);
needRender = true;
}
+ _bounds->debugPrint(4, "Using bounds:");
#if 0
- PlotData pd(_surface, &patterns, 8, 1);
+ PlotData pd(_surface, &patterns, 8, 1, this);
int x1 = 50, y1 = 50, x2 = 200, y2 = 200, borderThickness = 30;
Common::Rect inn(x1-5, y1-5, x2+5, y2+5);
drawRoundRect(inn, 6, kColorGray, false, drawPixelPlain, &pd);
@@ -115,6 +129,22 @@ void Design::paint(Graphics::Surface *surface, Patterns &patterns, int x, int y)
return;
#endif
+ if (needRender)
+ render(patterns);
+
+ if (_bounds->width() && _bounds->height()) {
+ const int padding = 3;
+ Common::Rect from(padding, padding, _bounds->width() - 2 * padding, _bounds->height() - 2 * padding);
+ Common::Rect to(from);
+ to.moveTo(x, y);
+ surface->transBlitFrom(*_surface, from, to, kColorGreen);
+ }
+}
+
+void Design::render(Graphics::MacPatterns &patterns) {
+ Common::MemoryReadStream in(_data, _len);
+ bool needRender = true;
+
while (needRender) {
byte fillType = in.readByte();
byte borderThickness = in.readByte();
@@ -152,18 +182,6 @@ void Design::paint(Graphics::Surface *surface, Patterns &patterns, int x, int y)
//g_system->updateScreen();
//g_system->delayMillis(500);
}
-
- const int padding = 3;
- for (int i = padding; i < _bounds->height() - 2 * padding; i++) {
- const byte *src = (const byte *)_surface->getBasePtr(padding, i);
- byte *dst = (byte *)surface->getBasePtr(x + padding, y+i);
- for (int j = padding; j < _bounds->width() - 2 * padding; j++) {
- if (*src != kColorGreen)
- *dst = *src;
- src++;
- dst++;
- }
- }
}
bool Design::isPointOpaque(int x, int y) {
@@ -175,18 +193,43 @@ bool Design::isPointOpaque(int x, int y) {
return pixel != kColorGreen;
}
+void Design::adjustBounds(int16 x, int16 y) {
+ _bounds->right = MAX(x, _bounds->right);
+ _bounds->bottom = MAX(y, _bounds->bottom);
+}
+
void drawPixel(int x, int y, int color, void *data) {
PlotData *p = (PlotData *)data;
if (p->fillType > p->patterns->size())
return;
+ if (p->design && p->design->isBoundsCalculation()) {
+ if (x < 0 || y < 0)
+ return;
+ if (p->thickness == 1) {
+ p->design->adjustBounds(x, y);
+ } else {
+ int x1 = x;
+ int x2 = x1 + p->thickness;
+ int y1 = y;
+ int y2 = y1 + p->thickness;
+
+ for (y = y1; y < y2; y++)
+ for (x = x1; x < x2; x++)
+ p->design->adjustBounds(x, y);
+ }
+
+ return;
+ }
+
byte *pat = p->patterns->operator[](p->fillType - 1);
if (p->thickness == 1) {
if (x >= 0 && x < p->surface->w && y >= 0 && y < p->surface->h) {
uint xu = (uint)x; // for letting compiler optimize it
uint yu = (uint)y;
+
*((byte *)p->surface->getBasePtr(xu, yu)) =
(pat[yu % 8] & (1 << (7 - xu % 8))) ?
color : kColorWhite;
@@ -212,12 +255,17 @@ void drawPixel(int x, int y, int color, void *data) {
void drawPixelPlain(int x, int y, int color, void *data) {
PlotData *p = (PlotData *)data;
+ if (p->design && p->design->isBoundsCalculation()) {
+ p->design->adjustBounds(x, y);
+ return;
+ }
+
if (x >= 0 && x < p->surface->w && y >= 0 && y < p->surface->h)
*((byte *)p->surface->getBasePtr(x, y)) = (byte)color;
}
-void Design::drawRect(Graphics::Surface *surface, Common::ReadStream &in,
- Patterns &patterns, byte fillType, byte borderThickness, byte borderFillType) {
+void Design::drawRect(Graphics::ManagedSurface *surface, Common::ReadStream &in,
+ Graphics::MacPatterns &patterns, byte fillType, byte borderThickness, byte borderFillType) {
int16 y1 = in.readSint16BE();
int16 x1 = in.readSint16BE();
int16 y2 = in.readSint16BE();
@@ -229,7 +277,7 @@ void Design::drawRect(Graphics::Surface *surface, Common::ReadStream &in,
SWAP(y1, y2);
Common::Rect r(x1, y1, x2, y2);
- PlotData pd(surface, &patterns, fillType, 1);
+ PlotData pd(surface, &patterns, fillType, 1, this);
if (fillType <= patterns.size())
Graphics::drawFilledRect(r, kColorBlack, drawPixel, &pd);
@@ -245,8 +293,8 @@ void Design::drawRect(Graphics::Surface *surface, Common::ReadStream &in,
}
}
-void Design::drawRoundRect(Graphics::Surface *surface, Common::ReadStream &in,
- Patterns &patterns, byte fillType, byte borderThickness, byte borderFillType) {
+void Design::drawRoundRect(Graphics::ManagedSurface *surface, Common::ReadStream &in,
+ Graphics::MacPatterns &patterns, byte fillType, byte borderThickness, byte borderFillType) {
int16 y1 = in.readSint16BE();
int16 x1 = in.readSint16BE();
int16 y2 = in.readSint16BE();
@@ -259,20 +307,20 @@ void Design::drawRoundRect(Graphics::Surface *surface, Common::ReadStream &in,
SWAP(y1, y2);
Common::Rect r(x1, y1, x2, y2);
- PlotData pd(surface, &patterns, fillType, 1);
+ PlotData pd(surface, &patterns, fillType, 1, this);
if (fillType <= patterns.size())
- Graphics::drawRoundRect(r, arc/2, kColorBlack, true, drawPixel, &pd);
+ Graphics::drawRoundRect(r, arc / 2, kColorBlack, true, drawPixel, &pd);
pd.fillType = borderFillType;
pd.thickness = borderThickness;
if (borderThickness > 0 && borderFillType <= patterns.size())
- Graphics::drawRoundRect(r, arc/2, kColorBlack, false, drawPixel, &pd);
+ Graphics::drawRoundRect(r, arc / 2, kColorBlack, false, drawPixel, &pd);
}
-void Design::drawPolygon(Graphics::Surface *surface, Common::ReadStream &in,
- Patterns &patterns, byte fillType, byte borderThickness, byte borderFillType) {
+void Design::drawPolygon(Graphics::ManagedSurface *surface, Common::ReadStream &in,
+ Graphics::MacPatterns &patterns, byte fillType, byte borderThickness, byte borderFillType) {
byte ignored = in.readSint16BE(); // ignored
@@ -331,7 +379,7 @@ void Design::drawPolygon(Graphics::Surface *surface, Common::ReadStream &in,
ypoints[i] = ycoords[i];
}
- PlotData pd(surface, &patterns, fillType, 1);
+ PlotData pd(surface, &patterns, fillType, 1, this);
if (fillType <= patterns.size()) {
Graphics::drawPolygonScan(xpoints, ypoints, npoints, bbox, kColorBlack, drawPixel, &pd);
@@ -348,13 +396,13 @@ void Design::drawPolygon(Graphics::Surface *surface, Common::ReadStream &in,
free(ypoints);
}
-void Design::drawOval(Graphics::Surface *surface, Common::ReadStream &in,
- Patterns &patterns, byte fillType, byte borderThickness, byte borderFillType) {
+void Design::drawOval(Graphics::ManagedSurface *surface, Common::ReadStream &in,
+ Graphics::MacPatterns &patterns, byte fillType, byte borderThickness, byte borderFillType) {
int16 y1 = in.readSint16BE();
int16 x1 = in.readSint16BE();
int16 y2 = in.readSint16BE();
int16 x2 = in.readSint16BE();
- PlotData pd(surface, &patterns, fillType, 1);
+ PlotData pd(surface, &patterns, fillType, 1, this);
if (fillType <= patterns.size())
Graphics::drawEllipse(x1, y1, x2-1, y2-1, kColorBlack, true, drawPixel, &pd);
@@ -366,7 +414,7 @@ void Design::drawOval(Graphics::Surface *surface, Common::ReadStream &in,
Graphics::drawEllipse(x1, y1, x2-1, y2-1, kColorBlack, false, drawPixel, &pd);
}
-void Design::drawBitmap(Graphics::Surface *surface, Common::SeekableReadStream &in) {
+void Design::drawBitmap(Graphics::ManagedSurface *surface, Common::SeekableReadStream &in) {
int numBytes = in.readSint16BE();
int y1 = in.readSint16BE();
int x1 = in.readSint16BE();
@@ -410,7 +458,9 @@ void Design::drawBitmap(Graphics::Surface *surface, Common::SeekableReadStream &
color = b;
for (int c = 0; c < 8; c++) {
- if (x1 + x >= 0 && x1 + x < surface->w && y1 + y >= 0 && y1 + y < surface->h)
+ if (_boundsCalculationMode) {
+ adjustBounds(x1 + x, y1 + y);
+ } else if (x1 + x >= 0 && x1 + x < surface->w && y1 + y >= 0 && y1 + y < surface->h)
*((byte *)tmp.getBasePtr(x, y)) = (color & (1 << (7 - c % 8))) ? kColorBlack : kColorWhite;
x++;
if (x == w) {
@@ -424,37 +474,39 @@ void Design::drawBitmap(Graphics::Surface *surface, Common::SeekableReadStream &
in.skip(numBytes);
- FloodFill ff(&tmp, kColorWhite, kColorGreen);
- for (int yy = 0; yy < h; yy++) {
- ff.addSeed(0, yy);
- ff.addSeed(w - 1, yy);
- }
- for (int xx = 0; xx < w; xx++) {
- ff.addSeed(xx, 0);
- ff.addSeed(xx, h - 1);
- }
- ff.fill();
-
- for (y = 0; y < h; y++) {
- byte *src = (byte *)tmp.getBasePtr(0, y);
- byte *dst = (byte *)surface->getBasePtr(x1, y1 + y);
- for (x = 0; x < w; x++) {
- if (*src != kColorGreen)
- *dst = *src;
- src++;
- dst++;
+ if (!_boundsCalculationMode) {
+ Graphics::FloodFill ff(&tmp, kColorWhite, kColorGreen);
+ for (int yy = 0; yy < h; yy++) {
+ ff.addSeed(0, yy);
+ ff.addSeed(w - 1, yy);
+ }
+ for (int xx = 0; xx < w; xx++) {
+ ff.addSeed(xx, 0);
+ ff.addSeed(xx, h - 1);
+ }
+ ff.fill();
+
+ for (y = 0; y < h && y1 + y < surface->h; y++) {
+ byte *src = (byte *)tmp.getBasePtr(0, y);
+ byte *dst = (byte *)surface->getBasePtr(x1, y1 + y);
+ for (x = 0; x < w; x++) {
+ if (*src != kColorGreen)
+ *dst = *src;
+ src++;
+ dst++;
+ }
}
}
tmp.free();
}
-void Design::drawRect(Graphics::Surface *surface, Common::Rect &rect, int thickness, int color, Patterns &patterns, byte fillType) {
+void Design::drawRect(Graphics::ManagedSurface *surface, Common::Rect &rect, int thickness, int color, Graphics::MacPatterns &patterns, byte fillType) {
drawRect(surface, rect.left, rect.top, rect.right, rect.bottom, thickness, color, patterns, fillType);
}
-void Design::drawRect(Graphics::Surface *surface, int x1, int y1, int x2, int y2, int thickness, int color, Patterns &patterns, byte fillType) {
- PlotData pd(surface, &patterns, fillType, thickness);
+void Design::drawRect(Graphics::ManagedSurface *surface, int x1, int y1, int x2, int y2, int thickness, int color, Graphics::MacPatterns &patterns, byte fillType) {
+ PlotData pd(surface, &patterns, fillType, thickness, nullptr);
Graphics::drawLine(x1, y1, x2, y1, kColorBlack, drawPixel, &pd);
Graphics::drawLine(x2, y1, x2, y2, kColorBlack, drawPixel, &pd);
@@ -463,79 +515,29 @@ void Design::drawRect(Graphics::Surface *surface, int x1, int y1, int x2, int y2
}
-void Design::drawFilledRect(Graphics::Surface *surface, Common::Rect &rect, int color, Patterns &patterns, byte fillType) {
- PlotData pd(surface, &patterns, fillType, 1);
+void Design::drawFilledRect(Graphics::ManagedSurface *surface, Common::Rect &rect, int color, Graphics::MacPatterns &patterns, byte fillType) {
+ PlotData pd(surface, &patterns, fillType, 1, nullptr);
for (int y = rect.top; y <= rect.bottom; y++)
Graphics::drawHLine(rect.left, rect.right, y, color, drawPixel, &pd);
}
-void Design::drawFilledRoundRect(Graphics::Surface *surface, Common::Rect &rect, int arc, int color, Patterns &patterns, byte fillType) {
- PlotData pd(surface, &patterns, fillType, 1);
+void Design::drawFilledRoundRect(Graphics::ManagedSurface *surface, Common::Rect &rect, int arc, int color, Graphics::MacPatterns &patterns, byte fillType) {
+ PlotData pd(surface, &patterns, fillType, 1, nullptr);
Graphics::drawRoundRect(rect, arc, color, true, drawPixel, &pd);
}
-void Design::drawHLine(Graphics::Surface *surface, int x1, int x2, int y, int thickness, int color, Patterns &patterns, byte fillType) {
- PlotData pd(surface, &patterns, fillType, thickness);
+void Design::drawHLine(Graphics::ManagedSurface *surface, int x1, int x2, int y, int thickness, int color, Graphics::MacPatterns &patterns, byte fillType) {
+ PlotData pd(surface, &patterns, fillType, thickness, nullptr);
Graphics::drawHLine(x1, x2, y, color, drawPixel, &pd);
}
-void Design::drawVLine(Graphics::Surface *surface, int x, int y1, int y2, int thickness, int color, Patterns &patterns, byte fillType) {
- PlotData pd(surface, &patterns, fillType, thickness);
+void Design::drawVLine(Graphics::ManagedSurface *surface, int x, int y1, int y2, int thickness, int color, Graphics::MacPatterns &patterns, byte fillType) {
+ PlotData pd(surface, &patterns, fillType, thickness, nullptr);
Graphics::drawVLine(x, y1, y2, color, drawPixel, &pd);
}
-FloodFill::FloodFill(Graphics::Surface *surface, byte color1, byte color2) {
- _surface = surface;
- _color1 = color1;
- _color2 = color2;
- _w = surface->w;
- _h = surface->h;
-
- _visited = (byte *)calloc(_w * _h, 1);
-}
-
-FloodFill::~FloodFill() {
- while(!_queue.empty()) {
- Common::Point *p = _queue.front();
-
- delete p;
- _queue.pop_front();
- }
-
- free(_visited);
-}
-
-void FloodFill::addSeed(int x, int y) {
- byte *p;
-
- if (x >= 0 && x < _w && y >= 0 && y < _h) {
- if (!_visited[y * _w + x] && *(p = (byte *)_surface->getBasePtr(x, y)) == _color1) {
- _visited[y * _w + x] = 1;
- *p = _color2;
-
- Common::Point *pt = new Common::Point(x, y);
-
- _queue.push_back(pt);
- }
- }
-}
-
-void FloodFill::fill() {
- while (!_queue.empty()) {
- Common::Point *p = _queue.front();
- _queue.pop_front();
- addSeed(p->x , p->y - 1);
- addSeed(p->x - 1, p->y );
- addSeed(p->x , p->y + 1);
- addSeed(p->x + 1, p->y );
-
- delete p;
- }
-}
-
-
} // End of namespace Wage