add deco flood fill, flood fills based on color being close enough

flood fill brush is hidden when deco tools are selected like this because it gets in the way. Renderer::vid is compared here so there could definitely be issues, but it works fine when used under normal conditions
This commit is contained in:
jacob1 2015-08-30 01:38:32 -04:00
parent 2ebc522c36
commit ed4678c9a8
6 changed files with 114 additions and 20 deletions

View File

@ -5,6 +5,7 @@
#include "Tool.h"
#include "graphics/Graphics.h"
class Renderer;
class DecorationTool: public Tool
{
public:
@ -12,6 +13,7 @@ public:
unsigned char Green;
unsigned char Blue;
unsigned char Alpha;
Renderer *ren;
VideoBuffer * GetIcon(int toolID, int width, int height)
{
@ -56,12 +58,13 @@ public:
return newTexture;
}
DecorationTool(int decoMode, string name, string description, int r, int g, int b, std::string identifier):
DecorationTool(Renderer *ren_, int decoMode, string name, string description, int r, int g, int b, std::string identifier):
Tool(decoMode, name, description, r, g, b, identifier),
Red(0),
Green(0),
Blue(0),
Alpha(0)
Alpha(0),
ren(ren_)
{
}
virtual ~DecorationTool() {}
@ -75,7 +78,11 @@ public:
sim->ApplyDecorationBox(position1.X, position1.Y, position2.X, position2.Y, Red, Green, Blue, Alpha, toolID);
}
virtual void DrawFill(Simulation * sim, Brush * brush, ui::Point position) {
pixel loc = ren->vid[position.X+position.Y*WINDOWW];
if (toolID == DECO_CLEAR)
sim->ApplyDecorationFill(ren, position.X, position.Y, 0, 0, 0, 0, PIXR(loc), PIXG(loc), PIXB(loc));
else
sim->ApplyDecorationFill(ren, position.X, position.Y, Red, Green, Blue, Alpha, PIXR(loc), PIXG(loc), PIXB(loc));
}
};

View File

@ -313,13 +313,13 @@ void GameModel::BuildMenus()
menuList[SC_TOOL]->AddTool(new SampleTool(this));
//Add decoration tools to menu
menuList[SC_DECO]->AddTool(new DecorationTool(DECO_ADD, "ADD", "Colour blending: Add.", 0, 0, 0, "DEFAULT_DECOR_ADD"));
menuList[SC_DECO]->AddTool(new DecorationTool(DECO_SUBTRACT, "SUB", "Colour blending: Subtract.", 0, 0, 0, "DEFAULT_DECOR_SUB"));
menuList[SC_DECO]->AddTool(new DecorationTool(DECO_MULTIPLY, "MUL", "Colour blending: Multiply.", 0, 0, 0, "DEFAULT_DECOR_MUL"));
menuList[SC_DECO]->AddTool(new DecorationTool(DECO_DIVIDE, "DIV", "Colour blending: Divide." , 0, 0, 0, "DEFAULT_DECOR_DIV"));
menuList[SC_DECO]->AddTool(new DecorationTool(DECO_SMUDGE, "SMDG", "Smudge tool, blends surrounding deco together.", 0, 0, 0, "DEFAULT_DECOR_SMDG"));
menuList[SC_DECO]->AddTool(new DecorationTool(DECO_CLEAR, "CLR", "Erase any set decoration.", 0, 0, 0, "DEFAULT_DECOR_CLR"));
menuList[SC_DECO]->AddTool(new DecorationTool(DECO_DRAW, "SET", "Draw decoration (No blending).", 0, 0, 0, "DEFAULT_DECOR_SET"));
menuList[SC_DECO]->AddTool(new DecorationTool(ren, DECO_ADD, "ADD", "Colour blending: Add.", 0, 0, 0, "DEFAULT_DECOR_ADD"));
menuList[SC_DECO]->AddTool(new DecorationTool(ren, DECO_SUBTRACT, "SUB", "Colour blending: Subtract.", 0, 0, 0, "DEFAULT_DECOR_SUB"));
menuList[SC_DECO]->AddTool(new DecorationTool(ren, DECO_MULTIPLY, "MUL", "Colour blending: Multiply.", 0, 0, 0, "DEFAULT_DECOR_MUL"));
menuList[SC_DECO]->AddTool(new DecorationTool(ren, DECO_DIVIDE, "DIV", "Colour blending: Divide." , 0, 0, 0, "DEFAULT_DECOR_DIV"));
menuList[SC_DECO]->AddTool(new DecorationTool(ren, DECO_SMUDGE, "SMDG", "Smudge tool, blends surrounding deco together.", 0, 0, 0, "DEFAULT_DECOR_SMDG"));
menuList[SC_DECO]->AddTool(new DecorationTool(ren, DECO_CLEAR, "CLR", "Erase any set decoration.", 0, 0, 0, "DEFAULT_DECOR_CLR"));
menuList[SC_DECO]->AddTool(new DecorationTool(ren, DECO_DRAW, "SET", "Draw decoration (No blending).", 0, 0, 0, "DEFAULT_DECOR_SET"));
decoToolset[0] = GetToolFromIdentifier("DEFAULT_DECOR_SET");
decoToolset[1] = GetToolFromIdentifier("DEFAULT_DECOR_CLR");
decoToolset[2] = GetToolFromIdentifier("DEFAULT_UI_SAMPLE");

View File

@ -161,6 +161,7 @@ GameView::GameView():
showDebug(false),
wallBrush(false),
toolBrush(false),
decoBrush(false),
windTool(false),
toolIndex(0),
currentSaveType(0),
@ -637,6 +638,7 @@ bool GameView::GetPlacingZoom()
void GameView::NotifyActiveToolsChanged(GameModel * sender)
{
decoBrush = false;
for (size_t i = 0; i < toolButtons.size(); i++)
{
Tool * tool = ((ToolAction*)toolButtons[i]->GetActionCallback())->tool;
@ -647,10 +649,15 @@ void GameView::NotifyActiveToolsChanged(GameModel * sender)
windTool = true;
else
windTool = false;
if (sender->GetActiveTool(0)->GetIdentifier().find("DEFAULT_DECOR_") != sender->GetActiveTool(0)->GetIdentifier().npos)
decoBrush = true;
}
else if(sender->GetActiveTool(1) == tool)
{
toolButtons[i]->SetSelectionState(1); //Secondary
if (sender->GetActiveTool(1)->GetIdentifier().find("DEFAULT_DECOR_") != sender->GetActiveTool(1)->GetIdentifier().npos)
decoBrush = true;
}
else if(sender->GetActiveTool(2) == tool)
{
@ -674,15 +681,18 @@ void GameView::NotifyActiveToolsChanged(GameModel * sender)
void GameView::NotifyLastToolChanged(GameModel * sender)
{
if(sender->GetLastTool() && sender->GetLastTool()->GetResolution() == CELL)
wallBrush = true;
else
wallBrush = false;
if (sender->GetLastTool())
{
if (sender->GetLastTool()->GetResolution() == CELL)
wallBrush = true;
else
wallBrush = false;
if (sender->GetLastTool() && sender->GetLastTool()->GetIdentifier().find("DEFAULT_TOOL_") != sender->GetLastTool()->GetIdentifier().npos)
toolBrush = true;
else
toolBrush = false;
if (sender->GetLastTool()->GetIdentifier().find("DEFAULT_TOOL_") != sender->GetLastTool()->GetIdentifier().npos)
toolBrush = true;
else
toolBrush = false;
}
}
void GameView::NotifyToolListChanged(GameModel * sender)
@ -2057,7 +2067,8 @@ void GameView::OnDraw()
}
else if(drawMode==DrawFill)// || altBehaviour)
{
activeBrush->RenderFill(ren, finalCurrentMouse);
if (!decoBrush)
activeBrush->RenderFill(ren, finalCurrentMouse);
}
if(drawMode == DrawPoints || drawMode==DrawLine || (drawMode == DrawRect && !isMouseDown))
{

View File

@ -45,6 +45,7 @@ private:
bool showDebug;
bool wallBrush;
bool toolBrush;
bool decoBrush;
bool windTool;
int toolIndex;
int currentSaveType;

View File

@ -422,7 +422,6 @@ int Simulation::flood_prop(int x, int y, size_t propoffset, PropertyValue propva
{
cs.pop(x, y);
x1 = x2 = x;
x1 = x2 = x;
while (x1>=CELL)
{
if (!FloodFillPmapCheck(x1-1, y, parttype) || bitmap[(y*XRES)+x1-1])
@ -983,6 +982,80 @@ void Simulation::ApplyDecorationBox(int x1, int y1, int x2, int y2, int colR, in
ApplyDecoration(i, j, colR, colG, colB, colA, mode);
}
bool Simulation::ColorCompare(Renderer *ren, int x, int y, int replaceR, int replaceG, int replaceB)
{
pixel pix = ren->vid[x+y*WINDOWW];
int r = PIXR(pix);
int g = PIXG(pix);
int b = PIXB(pix);
int diff = std::abs(replaceR-r) + std::abs(replaceG-g) + std::abs(replaceB-b);
return diff < 15;
}
void Simulation::ApplyDecorationFill(Renderer *ren, int x, int y, int colR, int colG, int colB, int colA, int replaceR, int replaceG, int replaceB)
{
int x1, x2;
char *bitmap = (char*)malloc(XRES*YRES); //Bitmap for checking
if (!bitmap)
return;
memset(bitmap, 0, XRES*YRES);
if (!ColorCompare(ren, x, y, replaceR, replaceG, replaceB))
return;
try
{
CoordStack cs;
cs.push(x, y);
do
{
cs.pop(x, y);
x1 = x2 = x;
// go left as far as possible
while (x1>0)
{
if (bitmap[(x1-1)+y*XRES] || !ColorCompare(ren, x1-1, y, replaceR, replaceG, replaceB))
{
break;
}
x1--;
}
// go right as far as possible
while (x2<XRES-1)
{
if (bitmap[(x1+1)+y*XRES] || !ColorCompare(ren, x2+1, y, replaceR, replaceG, replaceB))
{
break;
}
x2++;
}
// fill span
for (x=x1; x<=x2; x++)
{
ApplyDecoration(x, y, colR, colG, colB, colA, DECO_DRAW);
bitmap[x+y*XRES] = 1;
}
if (y >= 1)
for (x=x1; x<=x2; x++)
if (!bitmap[x+(y-1)*XRES] && ColorCompare(ren, x, y-1, replaceR, replaceG, replaceB))
cs.push(x, y-1);
if (y < YRES-1)
for (x=x1; x<=x2; x++)
if (!bitmap[x+(y+1)*XRES] && ColorCompare(ren, x, y+1, replaceR, replaceG, replaceB))
cs.push(x, y+1);
} while (cs.getSize() > 0);
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
free(bitmap);
return;
}
free(bitmap);
}
int Simulation::Tool(int x, int y, int tool, float strength)
{
if(tools[tool])

View File

@ -170,6 +170,8 @@ public:
void ApplyDecorationPoint(int x, int y, int colR, int colG, int colB, int colA, int mode, Brush * cBrush = NULL);
void ApplyDecorationLine(int x1, int y1, int x2, int y2, int colR, int colG, int colB, int colA, int mode, Brush * cBrush = NULL);
void ApplyDecorationBox(int x1, int y1, int x2, int y2, int colR, int colG, int colB, int colA, int mode);
bool ColorCompare(Renderer *ren, int x, int y, int replaceR, int replaceG, int replaceB);
void ApplyDecorationFill(Renderer *ren, int x, int y, int colR, int colG, int colB, int colA, int replaceR, int replaceG, int replaceB);
//Drawing Tools like HEAT, AIR, and GRAV
int Tool(int x, int y, int tool, float strength = 1.0f);