Fix crash from new brush code when TPTMP is enabled
Okay yeah this is actually a well-camouflaged refactor.
This commit is contained in:
parent
114017d550
commit
369dadf81e
@ -3,10 +3,7 @@
|
||||
#include "Misc.h"
|
||||
#include <cmath>
|
||||
|
||||
BitmapBrush::BitmapBrush(ui::Point inputSize, unsigned char const *inputBitmap):
|
||||
Brush(),
|
||||
radius(inputSize / 2),
|
||||
origSize(0, 0)
|
||||
BitmapBrush::BitmapBrush(ui::Point inputSize, unsigned char const *inputBitmap)
|
||||
{
|
||||
ui::Point newSize = inputSize;
|
||||
|
||||
@ -24,7 +21,11 @@ BitmapBrush::BitmapBrush(ui::Point inputSize, unsigned char const *inputBitmap):
|
||||
origBitmap[x + y * newSize.X] = inputBitmap[x + y * inputSize.X];
|
||||
}
|
||||
|
||||
std::pair<ui::Point, std::unique_ptr<unsigned char []>> BitmapBrush::GenerateBitmap() const
|
||||
BitmapBrush::BitmapBrush(const BitmapBrush &other) : BitmapBrush(other.origSize, &other.origBitmap[0])
|
||||
{
|
||||
}
|
||||
|
||||
std::unique_ptr<unsigned char []> BitmapBrush::GenerateBitmap() const
|
||||
{
|
||||
ui::Point size = radius * 2 + 1;
|
||||
auto bitmap = std::make_unique<unsigned char []>(size.X * size.Y);
|
||||
@ -58,13 +59,10 @@ std::pair<ui::Point, std::unique_ptr<unsigned char []>> BitmapBrush::GenerateBit
|
||||
}
|
||||
}
|
||||
}
|
||||
return std::make_pair(radius, std::move(bitmap));
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
std::unique_ptr<Brush> BitmapBrush::Clone() const
|
||||
{
|
||||
auto into = std::make_unique<BitmapBrush>(origSize, &origBitmap[0]);
|
||||
into->radius = radius;
|
||||
copyBitmaps(*into);
|
||||
return into;
|
||||
return std::make_unique<BitmapBrush>(*this);
|
||||
}
|
||||
|
@ -1,36 +1,18 @@
|
||||
/*
|
||||
* BitmapBrush.h
|
||||
*
|
||||
* Created on: Nov 18, 2012
|
||||
* Author: Simon Robertshaw
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include "Brush.h"
|
||||
|
||||
class BitmapBrush: public Brush
|
||||
{
|
||||
ui::Point radius;
|
||||
ui::Point origSize;
|
||||
ui::Point origSize{ 0, 0 };
|
||||
// 2D array with coords [0, origSize.X) by [0, origSize.Y)
|
||||
std::unique_ptr<unsigned char []> origBitmap;
|
||||
|
||||
public:
|
||||
BitmapBrush(ui::Point size, unsigned char const *bitmap);
|
||||
BitmapBrush(const BitmapBrush &other);
|
||||
virtual ~BitmapBrush() override = default;
|
||||
std::pair<ui::Point, std::unique_ptr<unsigned char []>> GenerateBitmap() const override;
|
||||
|
||||
ui::Point GetRadius() const override
|
||||
{
|
||||
return radius;
|
||||
}
|
||||
|
||||
void SetRadius(ui::Point radius) override
|
||||
{
|
||||
this->radius = radius;
|
||||
InvalidateCache();
|
||||
}
|
||||
std::unique_ptr<unsigned char []> GenerateBitmap() const override;
|
||||
|
||||
std::unique_ptr<Brush> Clone() const override;
|
||||
};
|
||||
|
@ -1,30 +1,34 @@
|
||||
#include "Brush.h"
|
||||
#include "graphics/Renderer.h"
|
||||
|
||||
void Brush::InvalidateCache()
|
||||
Brush::Brush(const Brush &other)
|
||||
{
|
||||
size = ui::Point(0, 0);
|
||||
bitmap.reset();
|
||||
outline.reset();
|
||||
radius = other.radius;
|
||||
auto size = GetSize();
|
||||
if (other.bitmap)
|
||||
{
|
||||
bitmap = std::make_unique<unsigned char []>(size.X * size.Y);
|
||||
std::copy(&other.bitmap[0], &other.bitmap[0] + size.X * size.Y, &bitmap[0]);
|
||||
}
|
||||
if (other.outline)
|
||||
{
|
||||
outline = std::make_unique<unsigned char []>(size.X * size.Y);
|
||||
std::copy(&other.outline[0], &other.outline[0] + size.X * size.Y, &outline[0]);
|
||||
}
|
||||
}
|
||||
|
||||
void Brush::ensureBitmap() const
|
||||
void Brush::InitBitmap()
|
||||
{
|
||||
if (bitmap)
|
||||
return;
|
||||
auto pair = GenerateBitmap();
|
||||
size = pair.first;
|
||||
bitmap = std::move(pair.second);
|
||||
bitmap = GenerateBitmap();
|
||||
}
|
||||
|
||||
void Brush::ensureOutline() const
|
||||
void Brush::InitOutline()
|
||||
{
|
||||
if (outline)
|
||||
return;
|
||||
ensureBitmap();
|
||||
ui::Point bounds = size * 2 + 1;
|
||||
InitBitmap();
|
||||
ui::Point bounds = GetSize();
|
||||
outline = std::make_unique<unsigned char []>(bounds.X * bounds.Y);
|
||||
for (int j = 0; j < bounds.Y; j++)
|
||||
{
|
||||
for (int i = 0; i < bounds.X; i++)
|
||||
{
|
||||
bool value = false;
|
||||
@ -43,6 +47,13 @@ void Brush::ensureOutline() const
|
||||
}
|
||||
outline[i + j * bounds.X] = value ? 0xFF : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Brush::SetRadius(ui::Point newRadius)
|
||||
{
|
||||
radius = newRadius;
|
||||
InitOutline();
|
||||
}
|
||||
|
||||
void Brush::AdjustSize(int delta, bool logarithmic, bool keepX, bool keepY)
|
||||
@ -73,22 +84,6 @@ 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;
|
||||
@ -123,8 +118,7 @@ void Brush::RenderLine(Renderer * ren, ui::Point position1, ui::Point position2)
|
||||
|
||||
void Brush::RenderPoint(Renderer * ren, ui::Point position) const
|
||||
{
|
||||
ensureOutline();
|
||||
ren->xor_bitmap(&outline[0], position.X - size.X, position.Y - size.Y, 2 * size.X + 1, 2 * size.Y + 1);
|
||||
ren->xor_bitmap(&outline[0], position.X - radius.X, position.Y - radius.Y, 2 * radius.X + 1, 2 * radius.Y + 1);
|
||||
}
|
||||
|
||||
void Brush::RenderFill(Renderer * ren, ui::Point position) const
|
||||
|
@ -6,13 +6,12 @@ class Renderer;
|
||||
class Brush
|
||||
{
|
||||
private:
|
||||
ui::Point mutable size;
|
||||
// 2D arrays indexed by coordinates from [-size.X, size.X] by [-size.Y, size.Y]
|
||||
std::unique_ptr<unsigned char []> mutable bitmap;
|
||||
std::unique_ptr<unsigned char []> mutable outline;
|
||||
// 2D arrays indexed by coordinates from [-radius.X, radius.X] by [-radius.Y, radius.Y]
|
||||
std::unique_ptr<unsigned char []> bitmap;
|
||||
std::unique_ptr<unsigned char []> outline;
|
||||
|
||||
void ensureBitmap() const;
|
||||
void ensureOutline() const;
|
||||
void InitBitmap();
|
||||
void InitOutline();
|
||||
|
||||
struct iterator
|
||||
{
|
||||
@ -21,14 +20,15 @@ private:
|
||||
|
||||
iterator &operator++()
|
||||
{
|
||||
auto radius = parent.GetRadius();
|
||||
do
|
||||
{
|
||||
if (++x > parent.size.X)
|
||||
if (++x > radius.X)
|
||||
{
|
||||
--y;
|
||||
x = -parent.size.X;
|
||||
x = -radius.X;
|
||||
}
|
||||
} while (y >= -parent.size.Y && !parent.bitmap[x + parent.size.X + (y + parent.size.Y) * (2 * parent.size.X + 1)]);
|
||||
} while (y >= -radius.Y && !parent.bitmap[x + radius.X + (y + radius.Y) * (2 * radius.X + 1)]);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -50,42 +50,42 @@ private:
|
||||
};
|
||||
|
||||
protected:
|
||||
Brush():
|
||||
size(0, 0),
|
||||
bitmap(),
|
||||
outline()
|
||||
{
|
||||
}
|
||||
ui::Point radius{ 0, 0 };
|
||||
|
||||
void InvalidateCache();
|
||||
virtual std::pair<ui::Point, std::unique_ptr<unsigned char []>> GenerateBitmap() const = 0;
|
||||
void copyBitmaps(Brush &into) const;
|
||||
virtual std::unique_ptr<unsigned char []> GenerateBitmap() const = 0;
|
||||
|
||||
public:
|
||||
Brush() = default;
|
||||
Brush(const Brush &other);
|
||||
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
|
||||
{
|
||||
return size;
|
||||
return radius * 2 + 1;
|
||||
}
|
||||
|
||||
ui::Point GetRadius() const
|
||||
{
|
||||
return radius;
|
||||
}
|
||||
|
||||
iterator begin() const
|
||||
{
|
||||
// bottom to top is the preferred order for Simulation::CreateParts
|
||||
return ++iterator{*this, size.X, size.Y + 1};
|
||||
return ++iterator{*this, radius.X, radius.Y + 1};
|
||||
}
|
||||
|
||||
iterator end() const
|
||||
{
|
||||
return iterator{*this, -size.X, -size.Y - 1};
|
||||
return iterator{*this, -radius.X, -radius.Y - 1};
|
||||
}
|
||||
|
||||
void RenderRect(Renderer * ren, ui::Point position1, ui::Point position2) const;
|
||||
void RenderLine(Renderer * ren, ui::Point position1, ui::Point position2) const;
|
||||
void RenderPoint(Renderer * ren, ui::Point position) const;
|
||||
void RenderFill(Renderer * ren, ui::Point position) const;
|
||||
|
||||
void SetRadius(ui::Point newRadius);
|
||||
};
|
||||
|
@ -4,19 +4,16 @@
|
||||
|
||||
class EllipseBrush: public Brush
|
||||
{
|
||||
ui::Point radius;
|
||||
bool perfectCircle;
|
||||
|
||||
public:
|
||||
EllipseBrush(ui::Point radius, bool perfectCircle = true):
|
||||
Brush(),
|
||||
radius(radius),
|
||||
perfectCircle(perfectCircle)
|
||||
EllipseBrush(bool newPerfectCircle) :
|
||||
perfectCircle(newPerfectCircle)
|
||||
{
|
||||
}
|
||||
virtual ~EllipseBrush() override = default;
|
||||
|
||||
std::pair<ui::Point, std::unique_ptr<unsigned char []>> GenerateBitmap() const override
|
||||
std::unique_ptr<unsigned char []> GenerateBitmap() const override
|
||||
{
|
||||
ui::Point size = radius * 2 + 1;
|
||||
auto bitmap = std::make_unique<unsigned char []>(size.X * size.Y);
|
||||
@ -64,24 +61,11 @@ public:
|
||||
bitmap[size.X/2] = 255;
|
||||
bitmap[size.X*size.Y-size.X/2-1] = 255;
|
||||
}
|
||||
return std::make_pair(radius, std::move(bitmap));
|
||||
}
|
||||
|
||||
ui::Point GetRadius() const override
|
||||
{
|
||||
return radius;
|
||||
}
|
||||
|
||||
void SetRadius(ui::Point radius) override
|
||||
{
|
||||
this->radius = radius;
|
||||
InvalidateCache();
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
std::unique_ptr<Brush> Clone() const override
|
||||
{
|
||||
auto into = std::make_unique<EllipseBrush>(radius, perfectCircle);
|
||||
copyBitmaps(*into);
|
||||
return into;
|
||||
return std::make_unique<EllipseBrush>(*this);
|
||||
}
|
||||
};
|
||||
|
@ -462,14 +462,14 @@ void GameModel::BuildFavoritesMenu()
|
||||
|
||||
void GameModel::BuildBrushList()
|
||||
{
|
||||
std::optional<ui::Point> radius;
|
||||
ui::Point radius{ 4, 4 };
|
||||
if (brushList.size())
|
||||
radius = brushList[currentBrush]->GetRadius();
|
||||
brushList.clear();
|
||||
|
||||
brushList.push_back(std::make_unique<EllipseBrush>(ui::Point(4, 4), perfectCircle));
|
||||
brushList.push_back(std::make_unique<RectangleBrush>(ui::Point(4, 4)));
|
||||
brushList.push_back(std::make_unique<TriangleBrush>(ui::Point(4, 4)));
|
||||
brushList.push_back(std::make_unique<EllipseBrush>(perfectCircle));
|
||||
brushList.push_back(std::make_unique<RectangleBrush>());
|
||||
brushList.push_back(std::make_unique<TriangleBrush>());
|
||||
|
||||
//Load more from brushes folder
|
||||
for (ByteString brushFile : Platform::DirectorySearch(BRUSH_DIR, "", { ".ptb" }))
|
||||
@ -489,8 +489,7 @@ void GameModel::BuildBrushList()
|
||||
brushList.push_back(std::make_unique<BitmapBrush>(ui::Point(dimension, dimension), reinterpret_cast<unsigned char const *>(brushData.data())));
|
||||
}
|
||||
|
||||
if (radius && (size_t)currentBrush < brushList.size())
|
||||
brushList[currentBrush]->SetRadius(*radius);
|
||||
brushList[currentBrush]->SetRadius(radius);
|
||||
notifyBrushChanged();
|
||||
}
|
||||
|
||||
|
@ -3,40 +3,19 @@
|
||||
|
||||
class RectangleBrush: public Brush
|
||||
{
|
||||
ui::Point radius;
|
||||
|
||||
public:
|
||||
RectangleBrush(ui::Point radius):
|
||||
Brush(),
|
||||
radius(radius)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~RectangleBrush() override = default;
|
||||
|
||||
std::pair<ui::Point, std::unique_ptr<unsigned char []>> GenerateBitmap() const override
|
||||
std::unique_ptr<unsigned char []> GenerateBitmap() const override
|
||||
{
|
||||
ui::Point size = radius * 2 + 1;
|
||||
auto size = GetSize();
|
||||
auto bitmap = std::make_unique<unsigned char []>(size.X * size.Y);
|
||||
std::fill(&bitmap[0], &bitmap[size.X * size.Y], 0xFF);
|
||||
return std::make_pair(radius, std::move(bitmap));
|
||||
}
|
||||
|
||||
ui::Point GetRadius() const override
|
||||
{
|
||||
return radius;
|
||||
}
|
||||
|
||||
void SetRadius(ui::Point radius) override
|
||||
{
|
||||
this->radius = radius;
|
||||
InvalidateCache();
|
||||
std::fill(&bitmap[0], &bitmap[0] + size.X * size.Y, 0xFF);
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
std::unique_ptr<Brush> Clone() const override
|
||||
{
|
||||
auto into = std::make_unique<RectangleBrush>(radius);
|
||||
copyBitmaps(*into);
|
||||
return into;
|
||||
return std::make_unique<RectangleBrush>(*this);
|
||||
}
|
||||
};
|
||||
|
@ -1,28 +1,13 @@
|
||||
/*
|
||||
* TriangleBrush.h
|
||||
*
|
||||
* Created on: Jan 26, 2012
|
||||
* Author: Savely Skresanov
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "Brush.h"
|
||||
#include <cmath>
|
||||
|
||||
class TriangleBrush: public Brush
|
||||
{
|
||||
ui::Point radius;
|
||||
|
||||
public:
|
||||
TriangleBrush(ui::Point radius):
|
||||
Brush(),
|
||||
radius(radius)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~TriangleBrush() override = default;
|
||||
|
||||
std::pair<ui::Point, std::unique_ptr<unsigned char []>> GenerateBitmap() const override
|
||||
std::unique_ptr<unsigned char []> GenerateBitmap() const override
|
||||
{
|
||||
ui::Point size = radius * 2 + 1;
|
||||
auto bitmap = std::make_unique<unsigned char []>(size.X * size.Y);
|
||||
@ -43,24 +28,11 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
return std::make_pair(radius, std::move(bitmap));
|
||||
}
|
||||
|
||||
ui::Point GetRadius() const override
|
||||
{
|
||||
return radius;
|
||||
}
|
||||
|
||||
void SetRadius(ui::Point radius) override
|
||||
{
|
||||
this->radius = radius;
|
||||
InvalidateCache();
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
std::unique_ptr<Brush> Clone() const override
|
||||
{
|
||||
auto into = std::make_unique<RectangleBrush>(radius);
|
||||
copyBitmaps(*into);
|
||||
return into;
|
||||
return std::make_unique<TriangleBrush>(*this);
|
||||
}
|
||||
};
|
||||
|
@ -2202,7 +2202,7 @@ int LuaScriptInterface::simulation_brush(lua_State * l)
|
||||
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(newBrush->begin(), newBrush->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)));
|
||||
|
Loading…
Reference in New Issue
Block a user