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 | } | ||