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:
parent
2ebc522c36
commit
ed4678c9a8
@ -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));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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)
|
||||
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)
|
||||
if (sender->GetLastTool()->GetIdentifier().find("DEFAULT_TOOL_") != sender->GetLastTool()->GetIdentifier().npos)
|
||||
toolBrush = true;
|
||||
else
|
||||
toolBrush = false;
|
||||
}
|
||||
}
|
||||
|
||||
void GameView::NotifyToolListChanged(GameModel * sender)
|
||||
@ -2057,6 +2067,7 @@ void GameView::OnDraw()
|
||||
}
|
||||
else if(drawMode==DrawFill)// || altBehaviour)
|
||||
{
|
||||
if (!decoBrush)
|
||||
activeBrush->RenderFill(ren, finalCurrentMouse);
|
||||
}
|
||||
if(drawMode == DrawPoints || drawMode==DrawLine || (drawMode == DrawRect && !isMouseDown))
|
||||
|
@ -45,6 +45,7 @@ private:
|
||||
bool showDebug;
|
||||
bool wallBrush;
|
||||
bool toolBrush;
|
||||
bool decoBrush;
|
||||
bool windTool;
|
||||
int toolIndex;
|
||||
int currentSaveType;
|
||||
|
@ -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])
|
||||
|
@ -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);
|
||||
|
Reference in New Issue
Block a user