Copy brushes instead of making temporary changes to them
This commit is contained in:
parent
515df765e4
commit
ed8ec51f95
@ -22,7 +22,7 @@ BitmapBrush::BitmapBrush(ui::Point inputSize, unsigned char const *inputBitmap):
|
||||
for (int y = 0; y < inputSize.Y; y++)
|
||||
for (int x = 0; x < inputSize.X; x++)
|
||||
origBitmap[x + y * newSize.X] = inputBitmap[x + y * inputSize.X];
|
||||
};
|
||||
}
|
||||
|
||||
std::pair<ui::Point, std::unique_ptr<unsigned char []>> BitmapBrush::GenerateBitmap() const
|
||||
{
|
||||
@ -60,3 +60,11 @@ std::pair<ui::Point, std::unique_ptr<unsigned char []>> BitmapBrush::GenerateBit
|
||||
}
|
||||
return std::make_pair(radius, std::move(bitmap));
|
||||
}
|
||||
|
||||
std::unique_ptr<Brush> BitmapBrush::Clone() const
|
||||
{
|
||||
auto into = std::make_unique<BitmapBrush>(origSize, &origBitmap[0]);
|
||||
into->radius = radius;
|
||||
copyBitmaps(*into);
|
||||
return into;
|
||||
}
|
||||
|
@ -31,4 +31,6 @@ public:
|
||||
this->radius = radius;
|
||||
InvalidateCache();
|
||||
}
|
||||
|
||||
std::unique_ptr<Brush> Clone() const override;
|
||||
};
|
||||
|
@ -73,6 +73,22 @@ void Brush::AdjustSize(int delta, bool logarithmic, bool keepX, bool keepY)
|
||||
SetRadius(newSize);
|
||||
}
|
||||
|
||||
void Brush::copyBitmaps(Brush &into) const
|
||||
{
|
||||
into.size = size;
|
||||
size_t bounds = (2 * size.X + 1) * (2 * size.Y + 1);
|
||||
if (bitmap)
|
||||
{
|
||||
into.bitmap = std::make_unique<unsigned char []>(bounds);
|
||||
std::copy(&bitmap[0], &bitmap[bounds], &into.bitmap[0]);
|
||||
}
|
||||
if (outline)
|
||||
{
|
||||
into.outline = std::make_unique<unsigned char []>(bounds);
|
||||
std::copy(&outline[0], &outline[bounds], &into.outline[0]);
|
||||
}
|
||||
}
|
||||
|
||||
void Brush::RenderRect(Renderer * ren, ui::Point position1, ui::Point position2) const
|
||||
{
|
||||
int width, height;
|
||||
|
@ -42,7 +42,6 @@ private:
|
||||
return x != other.x || y != other.y;
|
||||
}
|
||||
|
||||
public:
|
||||
using difference_type = void;
|
||||
using value_type = ui::Point;
|
||||
using pointer = void;
|
||||
@ -60,12 +59,14 @@ protected:
|
||||
|
||||
void InvalidateCache();
|
||||
virtual std::pair<ui::Point, std::unique_ptr<unsigned char []>> GenerateBitmap() const = 0;
|
||||
void copyBitmaps(Brush &into) const;
|
||||
|
||||
public:
|
||||
virtual ~Brush() = default;
|
||||
virtual ui::Point GetRadius() const = 0;
|
||||
virtual void SetRadius(ui::Point radius) = 0;
|
||||
virtual void AdjustSize(int delta, bool logarithmic, bool keepX, bool keepY);
|
||||
virtual std::unique_ptr<Brush> Clone() const = 0;
|
||||
|
||||
ui::Point GetSize() const
|
||||
{
|
||||
|
@ -77,4 +77,11 @@ public:
|
||||
this->radius = radius;
|
||||
InvalidateCache();
|
||||
}
|
||||
|
||||
std::unique_ptr<Brush> Clone() const override
|
||||
{
|
||||
auto into = std::make_unique<EllipseBrush>(radius, perfectCircle);
|
||||
copyBitmaps(*into);
|
||||
return into;
|
||||
}
|
||||
};
|
||||
|
@ -472,19 +472,18 @@ void GameModel::BuildBrushList()
|
||||
brushList.push_back(std::make_unique<TriangleBrush>(ui::Point(4, 4)));
|
||||
|
||||
//Load more from brushes folder
|
||||
std::vector<ByteString> brushFiles = Platform::DirectorySearch(BRUSH_DIR, "", { ".ptb" });
|
||||
for (size_t i = 0; i < brushFiles.size(); i++)
|
||||
for (ByteString brushFile : Platform::DirectorySearch(BRUSH_DIR, "", { ".ptb" }))
|
||||
{
|
||||
std::vector<char> brushData;
|
||||
if (!Platform::ReadFile(brushData, ByteString::Build(BRUSH_DIR, PATH_SEP_CHAR, brushFiles[i])))
|
||||
if (!Platform::ReadFile(brushData, ByteString::Build(BRUSH_DIR, PATH_SEP_CHAR, brushFile)))
|
||||
{
|
||||
std::cout << "Brushes: Skipping " << brushFiles[i] << ". Could not open" << std::endl;
|
||||
std::cout << "Brushes: Skipping " << brushFile << ". Could not open" << std::endl;
|
||||
continue;
|
||||
}
|
||||
auto dimension = size_t(std::sqrt(float(brushData.size())));
|
||||
auto dimension = size_t(std::sqrt(brushData.size()));
|
||||
if (dimension * dimension != brushData.size())
|
||||
{
|
||||
std::cout << "Brushes: Skipping " << brushFiles[i] << ". Invalid bitmap size" << std::endl;
|
||||
std::cout << "Brushes: Skipping " << brushFile << ". Invalid bitmap size" << std::endl;
|
||||
continue;
|
||||
}
|
||||
brushList.push_back(std::make_unique<BitmapBrush>(ui::Point(dimension, dimension), reinterpret_cast<unsigned char const *>(brushData.data())));
|
||||
@ -812,9 +811,12 @@ Brush &GameModel::GetBrush()
|
||||
return *brushList[currentBrush];
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<Brush>> const &GameModel::GetBrushList()
|
||||
Brush *GameModel::GetBrushByID(int i)
|
||||
{
|
||||
return brushList;
|
||||
if (i >= 0 && i < (int)brushList.size())
|
||||
return brushList[i].get();
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int GameModel::GetBrushID()
|
||||
|
@ -176,7 +176,7 @@ public:
|
||||
std::vector<Tool*> GetUnlistedTools();
|
||||
|
||||
Brush &GetBrush();
|
||||
std::vector<std::unique_ptr<Brush>> const &GetBrushList();
|
||||
Brush *GetBrushByID(int i);
|
||||
int GetBrushID();
|
||||
void SetBrushID(int i);
|
||||
|
||||
|
@ -32,4 +32,11 @@ public:
|
||||
this->radius = radius;
|
||||
InvalidateCache();
|
||||
}
|
||||
|
||||
std::unique_ptr<Brush> Clone() const override
|
||||
{
|
||||
auto into = std::make_unique<RectangleBrush>(radius);
|
||||
copyBitmaps(*into);
|
||||
return into;
|
||||
}
|
||||
};
|
||||
|
@ -56,4 +56,11 @@ public:
|
||||
this->radius = radius;
|
||||
InvalidateCache();
|
||||
}
|
||||
|
||||
std::unique_ptr<Brush> Clone() const override
|
||||
{
|
||||
auto into = std::make_unique<RectangleBrush>(radius);
|
||||
copyBitmaps(*into);
|
||||
return into;
|
||||
}
|
||||
};
|
||||
|
@ -1469,17 +1469,16 @@ int LuaScriptInterface::simulation_createParts(lua_State * l)
|
||||
int rx = luaL_optint(l,3,5);
|
||||
int ry = luaL_optint(l,4,5);
|
||||
int c = luaL_optint(l,5,luacon_model->GetActiveTool(0)->GetToolID());
|
||||
int brush = luaL_optint(l,6,CIRCLE_BRUSH);
|
||||
int brushID = luaL_optint(l,6,CIRCLE_BRUSH);
|
||||
int flags = luaL_optint(l,7,luacon_sim->replaceModeFlags);
|
||||
|
||||
auto &brushList = luacon_model->GetBrushList();
|
||||
if (brush < 0 || brush >= (int)brushList.size())
|
||||
return luaL_error(l, "Invalid brush id '%d'", brush);
|
||||
ui::Point tempRadius = brushList[brush]->GetRadius();
|
||||
brushList[brush]->SetRadius(ui::Point(rx, ry));
|
||||
Brush *brush = luacon_model->GetBrushByID(brushID);
|
||||
if (!brush)
|
||||
return luaL_error(l, "Invalid brush id '%d'", brushID);
|
||||
auto newBrush = brush->Clone();
|
||||
newBrush->SetRadius(ui::Point(rx, ry));
|
||||
|
||||
int ret = luacon_sim->CreateParts(x, y, c, *brushList[brush], flags);
|
||||
brushList[brush]->SetRadius(tempRadius);
|
||||
int ret = luacon_sim->CreateParts(x, y, c, *newBrush, flags);
|
||||
lua_pushinteger(l, ret);
|
||||
return 1;
|
||||
}
|
||||
@ -1493,17 +1492,16 @@ int LuaScriptInterface::simulation_createLine(lua_State * l)
|
||||
int rx = luaL_optint(l,5,5);
|
||||
int ry = luaL_optint(l,6,5);
|
||||
int c = luaL_optint(l,7,luacon_model->GetActiveTool(0)->GetToolID());
|
||||
int brush = luaL_optint(l,8,CIRCLE_BRUSH);
|
||||
int brushID = luaL_optint(l,8,CIRCLE_BRUSH);
|
||||
int flags = luaL_optint(l,9,luacon_sim->replaceModeFlags);
|
||||
|
||||
auto &brushList = luacon_model->GetBrushList();
|
||||
if (brush < 0 || brush >= (int)brushList.size())
|
||||
return luaL_error(l, "Invalid brush id '%d'", brush);
|
||||
ui::Point tempRadius = brushList[brush]->GetRadius();
|
||||
brushList[brush]->SetRadius(ui::Point(rx, ry));
|
||||
Brush *brush = luacon_model->GetBrushByID(brushID);
|
||||
if (!brush)
|
||||
return luaL_error(l, "Invalid brush id '%d'", brushID);
|
||||
auto newBrush = brush->Clone();
|
||||
newBrush->SetRadius(ui::Point(rx, ry));
|
||||
|
||||
luacon_sim->CreateLine(x1, y1, x2, y2, c, *brushList[brush], flags);
|
||||
brushList[brush]->SetRadius(tempRadius);
|
||||
luacon_sim->CreateLine(x1, y1, x2, y2, c, *newBrush, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1527,10 +1525,10 @@ int LuaScriptInterface::simulation_floodParts(lua_State * l)
|
||||
int c = luaL_optint(l,3,luacon_model->GetActiveTool(0)->GetToolID());
|
||||
int cm = luaL_optint(l,4,-1);
|
||||
int flags = luaL_optint(l,5,luacon_sim->replaceModeFlags);
|
||||
|
||||
|
||||
if (x < 0 || x >= XRES || y < 0 || y >= YRES)
|
||||
return luaL_error(l, "coordinates out of range (%d,%d)", x, y);
|
||||
|
||||
|
||||
int ret = luacon_sim->FloodParts(x, y, c, cm, flags);
|
||||
lua_pushinteger(l, ret);
|
||||
return 1;
|
||||
@ -1617,7 +1615,7 @@ int LuaScriptInterface::simulation_toolBrush(lua_State * l)
|
||||
int rx = luaL_optint(l,3,5);
|
||||
int ry = luaL_optint(l,4,5);
|
||||
int tool = luaL_optint(l,5,0);
|
||||
int brush = luaL_optint(l,6,CIRCLE_BRUSH);
|
||||
int brushID = luaL_optint(l,6,CIRCLE_BRUSH);
|
||||
float strength = luaL_optnumber(l,7,1.0f);
|
||||
if (tool == (int)luacon_sim->tools.size())
|
||||
{
|
||||
@ -1627,14 +1625,13 @@ int LuaScriptInterface::simulation_toolBrush(lua_State * l)
|
||||
else if (tool < 0 || tool > (int)luacon_sim->tools.size())
|
||||
return luaL_error(l, "Invalid tool id '%d'", tool);
|
||||
|
||||
auto &brushList = luacon_model->GetBrushList();
|
||||
if (brush < 0 || brush >= (int)brushList.size())
|
||||
return luaL_error(l, "Invalid brush id '%d'", brush);
|
||||
ui::Point tempRadius = brushList[brush]->GetRadius();
|
||||
brushList[brush]->SetRadius(ui::Point(rx, ry));
|
||||
Brush *brush = luacon_model->GetBrushByID(brushID);
|
||||
if (!brush)
|
||||
return luaL_error(l, "Invalid brush id '%d'", brushID);
|
||||
auto newBrush = brush->Clone();
|
||||
newBrush->SetRadius(ui::Point(rx, ry));
|
||||
|
||||
int ret = luacon_sim->ToolBrush(x, y, tool, *brushList[brush], strength);
|
||||
brushList[brush]->SetRadius(tempRadius);
|
||||
int ret = luacon_sim->ToolBrush(x, y, tool, *newBrush, strength);
|
||||
lua_pushinteger(l, ret);
|
||||
return 1;
|
||||
}
|
||||
@ -1648,31 +1645,30 @@ int LuaScriptInterface::simulation_toolLine(lua_State * l)
|
||||
int rx = luaL_optint(l,5,5);
|
||||
int ry = luaL_optint(l,6,5);
|
||||
int tool = luaL_optint(l,7,0);
|
||||
int brush = luaL_optint(l,8,CIRCLE_BRUSH);
|
||||
int brushID = luaL_optint(l,8,CIRCLE_BRUSH);
|
||||
float strength = luaL_optnumber(l,9,1.0f);
|
||||
|
||||
|
||||
if (x1 < 0 || x2 < 0 || x1 >= XRES || x2 >= XRES || y1 < 0 || y2 < 0 || y1 >= YRES || y2 >= YRES)
|
||||
return luaL_error(l, "coordinates out of range (%d,%d),(%d,%d)", x1, y1, x2, y2);
|
||||
if (tool < 0 || tool >= (int)luacon_sim->tools.size()+1)
|
||||
return luaL_error(l, "Invalid tool id '%d'", tool);
|
||||
|
||||
auto &brushList = luacon_model->GetBrushList();
|
||||
if (brush < 0 || brush >= (int)brushList.size())
|
||||
return luaL_error(l, "Invalid brush id '%d'", brush);
|
||||
ui::Point tempRadius = brushList[brush]->GetRadius();
|
||||
brushList[brush]->SetRadius(ui::Point(rx, ry));
|
||||
Brush *brush = luacon_model->GetBrushByID(brushID);
|
||||
if (!brush)
|
||||
return luaL_error(l, "Invalid brush id '%d'", brushID);
|
||||
auto newBrush = brush->Clone();
|
||||
newBrush->SetRadius(ui::Point(rx, ry));
|
||||
|
||||
if (tool == (int)luacon_sim->tools.size())
|
||||
{
|
||||
Tool *windTool = luacon_model->GetToolFromIdentifier("DEFAULT_UI_WIND");
|
||||
float oldStrength = windTool->GetStrength();
|
||||
windTool->SetStrength(strength);
|
||||
windTool->DrawLine(luacon_sim, *brushList[brush], ui::Point(x1, y1), ui::Point(x2, y2));
|
||||
windTool->DrawLine(luacon_sim, *newBrush, ui::Point(x1, y1), ui::Point(x2, y2));
|
||||
windTool->SetStrength(oldStrength);
|
||||
}
|
||||
else
|
||||
luacon_sim->ToolLine(x1, y1, x2, y2, tool, *brushList[brush], strength);
|
||||
brushList[brush]->SetRadius(tempRadius);
|
||||
luacon_sim->ToolLine(x1, y1, x2, y2, tool, *newBrush, strength);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1709,16 +1705,15 @@ int LuaScriptInterface::simulation_decoBrush(lua_State * l)
|
||||
int b = luaL_optint(l,7,255);
|
||||
int a = luaL_optint(l,8,255);
|
||||
int tool = luaL_optint(l,9,DECO_DRAW);
|
||||
int brush = luaL_optint(l,10,CIRCLE_BRUSH);
|
||||
int brushID = luaL_optint(l,10,CIRCLE_BRUSH);
|
||||
|
||||
auto &brushList = luacon_model->GetBrushList();
|
||||
if (brush < 0 || brush >= (int)brushList.size())
|
||||
return luaL_error(l, "Invalid brush id '%d'", brush);
|
||||
ui::Point tempRadius = brushList[brush]->GetRadius();
|
||||
brushList[brush]->SetRadius(ui::Point(rx, ry));
|
||||
Brush *brush = luacon_model->GetBrushByID(brushID);
|
||||
if (!brush)
|
||||
return luaL_error(l, "Invalid brush id '%d'", brushID);
|
||||
auto newBrush = brush->Clone();
|
||||
newBrush->SetRadius(ui::Point(rx, ry));
|
||||
|
||||
luacon_sim->ApplyDecorationPoint(x, y, r, g, b, a, tool, *brushList[brush]);
|
||||
brushList[brush]->SetRadius(tempRadius);
|
||||
luacon_sim->ApplyDecorationPoint(x, y, r, g, b, a, tool, *newBrush);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1735,19 +1730,18 @@ int LuaScriptInterface::simulation_decoLine(lua_State * l)
|
||||
int b = luaL_optint(l,9,255);
|
||||
int a = luaL_optint(l,10,255);
|
||||
int tool = luaL_optint(l,11,DECO_DRAW);
|
||||
int brush = luaL_optint(l,12,CIRCLE_BRUSH);
|
||||
int brushID = luaL_optint(l,12,CIRCLE_BRUSH);
|
||||
|
||||
if (x1 < 0 || x2 < 0 || x1 >= XRES || x2 >= XRES || y1 < 0 || y2 < 0 || y1 >= YRES || y2 >= YRES)
|
||||
return luaL_error(l, "coordinates out of range (%d,%d),(%d,%d)", x1, y1, x2, y2);
|
||||
|
||||
auto &brushList = luacon_model->GetBrushList();
|
||||
if (brush < 0 || brush >= (int)brushList.size())
|
||||
return luaL_error(l, "Invalid brush id '%d'", brush);
|
||||
ui::Point tempRadius = brushList[brush]->GetRadius();
|
||||
brushList[brush]->SetRadius(ui::Point(rx, ry));
|
||||
Brush *brush = luacon_model->GetBrushByID(brushID);
|
||||
if (!brush)
|
||||
return luaL_error(l, "Invalid brush id '%d'", brushID);
|
||||
auto newBrush = brush->Clone();
|
||||
newBrush->SetRadius(ui::Point(rx, ry));
|
||||
|
||||
luacon_sim->ApplyDecorationLine(x1, y1, x2, y2, r, g, b, a, tool, *brushList[brush]);
|
||||
brushList[brush]->SetRadius(tempRadius);
|
||||
luacon_sim->ApplyDecorationLine(x1, y1, x2, y2, r, g, b, a, tool, *newBrush);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2200,22 +2194,19 @@ int LuaScriptInterface::simulation_brush(lua_State * l)
|
||||
}
|
||||
int brushID = luaL_optint(l, 5, luacon_model->GetBrushID());
|
||||
|
||||
auto &brushList = luacon_model->GetBrushList();
|
||||
if (brushID < 0 || brushID >= (int)brushList.size())
|
||||
Brush *brush = luacon_model->GetBrushByID(brushID);
|
||||
if (!brush)
|
||||
return luaL_error(l, "Invalid brush id '%d'", brushID);
|
||||
|
||||
Brush &brush = *brushList[brushID];
|
||||
ui::Point tempRadius = brush.GetRadius();
|
||||
brush.SetRadius(ui::Point(brushradiusX, brushradiusY));
|
||||
auto newBrush = brush->Clone();
|
||||
newBrush->SetRadius(ui::Point(brushradiusX, brushradiusY));
|
||||
lua_pushnumber(l, positionX);
|
||||
lua_pushnumber(l, positionY);
|
||||
std::vector<ui::Point> points;
|
||||
std::copy(brush.begin(), brush.end(), std::back_inserter(points));
|
||||
std::copy(brush->begin(), brush->end(), std::back_inserter(points));
|
||||
lua_pushnumber(l, 0); // index
|
||||
lua_pushnumber(l, points.size());
|
||||
auto points_ud = reinterpret_cast<ui::Point *>(lua_newuserdata(l, points.size() * sizeof(ui::Point)));
|
||||
std::copy(points.begin(), points.end(), points_ud);
|
||||
brush.SetRadius(tempRadius);
|
||||
|
||||
lua_pushcclosure(l, BrushClosure, 5);
|
||||
return 1;
|
||||
|
Reference in New Issue
Block a user