diff options
Diffstat (limited to 'engines/wage/design.cpp')
-rw-r--r-- | engines/wage/design.cpp | 244 |
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 |