GRAPHICS: Added FloodFill class to Surface.
Moved from WAGE engine and is using stack-based classic floodfill implementation.
This commit is contained in:
parent
2c7976e4e9
commit
531b190d59
4 changed files with 78 additions and 67 deletions
|
@ -422,7 +422,7 @@ void Design::drawBitmap(Graphics::ManagedSurface *surface, Common::SeekableReadS
|
||||||
int x2 = in.readSint16BE();
|
int x2 = in.readSint16BE();
|
||||||
int w = x2 - x1;
|
int w = x2 - x1;
|
||||||
int h = y2 - y1;
|
int h = y2 - y1;
|
||||||
Graphics::ManagedSurface tmp;
|
Graphics::Surface tmp;
|
||||||
|
|
||||||
tmp.create(w, h, Graphics::PixelFormat::createFormatCLUT8());
|
tmp.create(w, h, Graphics::PixelFormat::createFormatCLUT8());
|
||||||
|
|
||||||
|
@ -477,7 +477,7 @@ void Design::drawBitmap(Graphics::ManagedSurface *surface, Common::SeekableReadS
|
||||||
if (_boundsCalculationMode)
|
if (_boundsCalculationMode)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
FloodFill ff(&tmp, kColorWhite, kColorGreen);
|
Graphics::FloodFill ff(&tmp, kColorWhite, kColorGreen);
|
||||||
for (int yy = 0; yy < h; yy++) {
|
for (int yy = 0; yy < h; yy++) {
|
||||||
ff.addSeed(0, yy);
|
ff.addSeed(0, yy);
|
||||||
ff.addSeed(w - 1, yy);
|
ff.addSeed(w - 1, yy);
|
||||||
|
@ -541,54 +541,4 @@ void Design::drawVLine(Graphics::ManagedSurface *surface, int x, int y1, int y2,
|
||||||
Graphics::drawVLine(x, y1, y2, color, drawPixel, &pd);
|
Graphics::drawVLine(x, y1, y2, color, drawPixel, &pd);
|
||||||
}
|
}
|
||||||
|
|
||||||
FloodFill::FloodFill(Graphics::ManagedSurface *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
|
} // End of namespace Wage
|
||||||
|
|
|
@ -100,21 +100,6 @@ private:
|
||||||
void drawBitmap(Graphics::ManagedSurface *surface, Common::SeekableReadStream &in);
|
void drawBitmap(Graphics::ManagedSurface *surface, Common::SeekableReadStream &in);
|
||||||
};
|
};
|
||||||
|
|
||||||
class FloodFill {
|
|
||||||
public:
|
|
||||||
FloodFill(Graphics::ManagedSurface *surface, byte color1, byte color2);
|
|
||||||
~FloodFill();
|
|
||||||
void addSeed(int x, int y);
|
|
||||||
void fill();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Common::List<Common::Point *> _queue;
|
|
||||||
Graphics::ManagedSurface *_surface;
|
|
||||||
byte _color1, _color2;
|
|
||||||
byte *_visited;
|
|
||||||
int _w, _h;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // End of namespace Wage
|
} // End of namespace Wage
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -498,4 +498,64 @@ Graphics::Surface *Surface::convertTo(const PixelFormat &dstFormat, const byte *
|
||||||
return surface;
|
return surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FloodFill::FloodFill(Graphics::Surface *surface, uint32 oldColor, uint32 fillColor) {
|
||||||
|
_surface = surface;
|
||||||
|
_oldColor = oldColor;
|
||||||
|
_fillColor = fillColor;
|
||||||
|
_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) {
|
||||||
|
if (x >= 0 && x < _w && y >= 0 && y < _h) {
|
||||||
|
if (!_visited[y * _w + x]) {
|
||||||
|
_visited[y * _w + x] = 1;
|
||||||
|
void *p = _surface->getBasePtr(x, y);
|
||||||
|
|
||||||
|
if (_surface->format.bytesPerPixel == 1) {
|
||||||
|
if (*((byte *)p) == _oldColor)
|
||||||
|
*((byte *)p) = _fillColor;
|
||||||
|
} else if (_surface->format.bytesPerPixel == 2) {
|
||||||
|
if (READ_UINT16(p) == _oldColor)
|
||||||
|
WRITE_UINT16(p, _fillColor);
|
||||||
|
} else if (_surface->format.bytesPerPixel == 4) {
|
||||||
|
if (READ_UINT32(p) == _oldColor)
|
||||||
|
WRITE_UINT32(p, _fillColor);
|
||||||
|
} else {
|
||||||
|
error("Unsupported bpp in FloodFill");
|
||||||
|
}
|
||||||
|
|
||||||
|
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 Graphics
|
} // End of namespace Graphics
|
||||||
|
|
|
@ -24,9 +24,11 @@
|
||||||
#define GRAPHICS_SURFACE_H
|
#define GRAPHICS_SURFACE_H
|
||||||
|
|
||||||
#include "common/scummsys.h"
|
#include "common/scummsys.h"
|
||||||
|
#include "common/list.h"
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
struct Rect;
|
struct Rect;
|
||||||
|
struct Point;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "graphics/pixelformat.h"
|
#include "graphics/pixelformat.h"
|
||||||
|
@ -341,6 +343,20 @@ struct SharedPtrSurfaceDeleter {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class FloodFill {
|
||||||
|
public:
|
||||||
|
FloodFill(Surface *surface, uint32 oldColor, uint32 fillColor);
|
||||||
|
~FloodFill();
|
||||||
|
void addSeed(int x, int y);
|
||||||
|
void fill();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Common::List<Common::Point *> _queue;
|
||||||
|
Surface *_surface;
|
||||||
|
uint32 _oldColor, _fillColor;
|
||||||
|
byte *_visited;
|
||||||
|
int _w, _h;
|
||||||
|
};
|
||||||
|
|
||||||
} // End of namespace Graphics
|
} // End of namespace Graphics
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue