diff options
Diffstat (limited to 'ext/wittle_generator/Panel.cpp')
| -rw-r--r-- | ext/wittle_generator/Panel.cpp | 116 |
1 files changed, 116 insertions, 0 deletions
| diff --git a/ext/wittle_generator/Panel.cpp b/ext/wittle_generator/Panel.cpp new file mode 100644 index 0000000..a005467 --- /dev/null +++ b/ext/wittle_generator/Panel.cpp | |||
| @@ -0,0 +1,116 @@ | |||
| 1 | #include "Panel.h" | ||
| 2 | |||
| 3 | #include <fstream> | ||
| 4 | #include <sstream> | ||
| 5 | |||
| 6 | template <class T> | ||
| 7 | int find(const std::vector<T>& data, T search, size_t startIndex = 0) { | ||
| 8 | for (size_t i = startIndex; i < data.size(); i++) { | ||
| 9 | if (data[i] == search) return static_cast<int>(i); | ||
| 10 | } | ||
| 11 | return -1; | ||
| 12 | } | ||
| 13 | |||
| 14 | void Panel::SetSymbol(int x, int y, Decoration::Shape symbol, | ||
| 15 | Decoration::Color color) { | ||
| 16 | int gridx = x * 2 + (symbol & IntersectionFlags::COLUMN ? 0 : 1); | ||
| 17 | int gridy = y * 2 + (symbol & IntersectionFlags::ROW ? 0 : 1); | ||
| 18 | if (symbol & IntersectionFlags::DOT) { | ||
| 19 | if (color == Decoration::Color::Blue || color == Decoration::Color::Cyan) | ||
| 20 | color = static_cast<Decoration::Color>(IntersectionFlags::DOT_IS_BLUE); | ||
| 21 | else if (color == Decoration::Color::Orange || | ||
| 22 | color == Decoration::Color::Yellow) | ||
| 23 | color = static_cast<Decoration::Color>(IntersectionFlags::DOT_IS_ORANGE); | ||
| 24 | else | ||
| 25 | color = Decoration::Color::None; | ||
| 26 | if (symmetry) { | ||
| 27 | Point sp = get_sym_point(gridx, gridy); | ||
| 28 | SetGridSymbol(sp.first, sp.second, | ||
| 29 | static_cast<Decoration::Shape>(symbol & ~Decoration::Dot), | ||
| 30 | Decoration::Color::None); | ||
| 31 | } | ||
| 32 | } else if (symbol & IntersectionFlags::ROW || | ||
| 33 | symbol & IntersectionFlags::COLUMN) | ||
| 34 | color = Decoration::Color::None; | ||
| 35 | SetGridSymbol(gridx, gridy, symbol, color); | ||
| 36 | } | ||
| 37 | |||
| 38 | void Panel::SetShape(int x, int y, int shape, bool rotate, bool negative, | ||
| 39 | Decoration::Color color) { | ||
| 40 | if (!shape) return; | ||
| 41 | int symbol = Decoration::Shape::Poly; | ||
| 42 | while (!(shape & 0xf)) shape >>= 4; | ||
| 43 | while (!(shape & 0x1111)) shape >>= 1; | ||
| 44 | shape <<= 16; | ||
| 45 | if (rotate) | ||
| 46 | shape |= Decoration::Shape::Can_Rotate; | ||
| 47 | else | ||
| 48 | shape &= ~Decoration::Shape::Can_Rotate; | ||
| 49 | if (negative) | ||
| 50 | shape |= Decoration::Shape::Negative; | ||
| 51 | else | ||
| 52 | shape &= ~Decoration::Shape::Negative; | ||
| 53 | _grid[x * 2 + 1][y * 2 + 1] = symbol | shape | color; | ||
| 54 | } | ||
| 55 | |||
| 56 | void Panel::ClearSymbol(int x, int y) { ClearGridSymbol(x * 2 + 1, y * 2 + 1); } | ||
| 57 | |||
| 58 | void Panel::SetGridSymbol(int x, int y, Decoration::Shape symbol, | ||
| 59 | Decoration::Color color) { | ||
| 60 | if (symbol == Decoration::Start) _startpoints.push_back({x, y}); | ||
| 61 | if (symbol == Decoration::Exit) { | ||
| 62 | Endpoint::Direction dir; | ||
| 63 | if (y == 0) | ||
| 64 | dir = Endpoint::Direction::UP; | ||
| 65 | else if (y == _height - 1) | ||
| 66 | dir = Endpoint::Direction::DOWN; | ||
| 67 | else if (x == 0) | ||
| 68 | dir = Endpoint::Direction::LEFT; | ||
| 69 | else | ||
| 70 | dir = Endpoint::Direction::RIGHT; | ||
| 71 | /*if (id == 0x033D4 || id == 0x0A3B5) { | ||
| 72 | if (x == 0) | ||
| 73 | dir = Endpoint::Direction::LEFT; | ||
| 74 | else | ||
| 75 | dir = Endpoint::Direction::RIGHT; | ||
| 76 | }*/ | ||
| 77 | if (symmetry == Symmetry::ParallelH || | ||
| 78 | symmetry == Symmetry::ParallelHFlip) { | ||
| 79 | if (x == 0) dir = Endpoint::Direction::LEFT; | ||
| 80 | if (x == _width - 1) dir = Endpoint::Direction::RIGHT; | ||
| 81 | } | ||
| 82 | _endpoints.emplace_back(Endpoint( | ||
| 83 | x, y, dir, | ||
| 84 | IntersectionFlags::ENDPOINT | | ||
| 85 | (dir == Endpoint::Direction::UP || dir == Endpoint::Direction::DOWN | ||
| 86 | ? IntersectionFlags::COLUMN | ||
| 87 | : IntersectionFlags::ROW))); | ||
| 88 | } else | ||
| 89 | _grid[x][y] = symbol | color; | ||
| 90 | } | ||
| 91 | |||
| 92 | void Panel::ClearGridSymbol(int x, int y) { _grid[x][y] = 0; } | ||
| 93 | |||
| 94 | void Panel::Resize(int width, int height) { | ||
| 95 | for (Point& s : _startpoints) { | ||
| 96 | if (s.first == _width - 1) s.first = width - 1; | ||
| 97 | if (s.second == _height - 1) s.second = height - 1; | ||
| 98 | } | ||
| 99 | for (Endpoint& e : _endpoints) { | ||
| 100 | if (e.GetX() == _width - 1) e.SetX(width - 1); | ||
| 101 | if (e.GetY() == _height - 1) e.SetY(height - 1); | ||
| 102 | } | ||
| 103 | if (_width != _height || width != height) { | ||
| 104 | float maxDim = std::max(maxx - minx, maxy - miny); | ||
| 105 | float unitSize = maxDim / std::max(width - 1, height - 1); | ||
| 106 | minx = 0.5f - unitSize * (width - 1) / 2; | ||
| 107 | maxx = 0.5f + unitSize * (width - 1) / 2; | ||
| 108 | miny = 0.5f - unitSize * (height - 1) / 2; | ||
| 109 | maxy = 0.5f + unitSize * (height - 1) / 2; | ||
| 110 | } | ||
| 111 | _width = width; | ||
| 112 | _height = height; | ||
| 113 | _grid.resize(width); | ||
| 114 | for (auto& row : _grid) row.resize(height); | ||
| 115 | _resized = true; | ||
| 116 | } | ||
