about summary refs log tree commit diff stats
path: root/ext/wittle_generator/Panel.cpp
blob: a005467a0dfeccaf7f16eecfc6fa3da66f18c7c2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include "Panel.h"

#include <fstream>
#include <sstream>

template <class T>
int find(const std::vector<T>& data, T search, size_t startIndex = 0) {
  for (size_t i = startIndex; i < data.size(); i++) {
    if (data[i] == search) return static_cast<int>(i);
  }
  return -1;
}

void Panel::SetSymbol(int x, int y, Decoration::Shape symbol,
                      Decoration::Color color) {
  int gridx = x * 2 + (symbol & IntersectionFlags::COLUMN ? 0 : 1);
  int gridy = y * 2 + (symbol & IntersectionFlags::ROW ? 0 : 1);
  if (symbol & IntersectionFlags::DOT) {
    if (color == Decoration::Color::Blue || color == Decoration::Color::Cyan)
      color = static_cast<Decoration::Color>(IntersectionFlags::DOT_IS_BLUE);
    else if (color == Decoration::Color::Orange ||
             color == Decoration::Color::Yellow)
      color = static_cast<Decoration::Color>(IntersectionFlags::DOT_IS_ORANGE);
    else
      color = Decoration::Color::None;
    if (symmetry) {
      Point sp = get_sym_point(gridx, gridy);
      SetGridSymbol(sp.first, sp.second,
                    static_cast<Decoration::Shape>(symbol & ~Decoration::Dot),
                    Decoration::Color::None);
    }
  } else if (symbol & IntersectionFlags::ROW ||
             symbol & IntersectionFlags::COLUMN)
    color = Decoration::Color::None;
  SetGridSymbol(gridx, gridy, symbol, color);
}

void Panel::SetShape(int x, int y, int shape, bool rotate, bool negative,
                     Decoration::Color color) {
  if (!shape) return;
  int symbol = Decoration::Shape::Poly;
  while (!(shape & 0xf)) shape >>= 4;
  while (!(shape & 0x1111)) shape >>= 1;
  shape <<= 16;
  if (rotate)
    shape |= Decoration::Shape::Can_Rotate;
  else
    shape &= ~Decoration::Shape::Can_Rotate;
  if (negative)
    shape |= Decoration::Shape::Negative;
  else
    shape &= ~Decoration::Shape::Negative;
  _grid[x * 2 + 1][y * 2 + 1] = symbol | shape | color;
}

void Panel::ClearSymbol(int x, int y) { ClearGridSymbol(x * 2 + 1, y * 2 + 1); }

void Panel::SetGridSymbol(int x, int y, Decoration::Shape symbol,
                          Decoration::Color color) {
  if (symbol == Decoration::Start) _startpoints.push_back({x, y});
  if (symbol == Decoration::Exit) {
    Endpoint::Direction dir;
    if (y == 0)
      dir = Endpoint::Direction::UP;
    else if (y == _height - 1)
      dir = Endpoint::Direction::DOWN;
    else if (x == 0)
      dir = Endpoint::Direction::LEFT;
    else
      dir = Endpoint::Direction::RIGHT;
    /*if (id == 0x033D4 || id == 0x0A3B5) {
      if (x == 0)
        dir = Endpoint::Direction::LEFT;
      else
        dir = Endpoint::Direction::RIGHT;
    }*/
    if (symmetry == Symmetry::ParallelH ||
        symmetry == Symmetry::ParallelHFlip) {
      if (x == 0) dir = Endpoint::Direction::LEFT;
      if (x == _width - 1) dir = Endpoint::Direction::RIGHT;
    }
    _endpoints.emplace_back(Endpoint(
        x, y, dir,
        IntersectionFlags::ENDPOINT |
            (dir == Endpoint::Direction::UP || dir == Endpoint::Direction::DOWN
                 ? IntersectionFlags::COLUMN
                 : IntersectionFlags::ROW)));
  } else
    _grid[x][y] = symbol | color;
}

void Panel::ClearGridSymbol(int x, int y) { _grid[x][y] = 0; }

void Panel::Resize(int width, int height) {
  for (Point& s : _startpoints) {
    if (s.first == _width - 1) s.first = width - 1;
    if (s.second == _height - 1) s.second = height - 1;
  }
  for (Endpoint& e : _endpoints) {
    if (e.GetX() == _width - 1) e.SetX(width - 1);
    if (e.GetY() == _height - 1) e.SetY(height - 1);
  }
  if (_width != _height || width != height) {
    float maxDim = std::max(maxx - minx, maxy - miny);
    float unitSize = maxDim / std::max(width - 1, height - 1);
    minx = 0.5f - unitSize * (width - 1) / 2;
    maxx = 0.5f + unitSize * (width - 1) / 2;
    miny = 0.5f - unitSize * (height - 1) / 2;
    maxy = 0.5f + unitSize * (height - 1) / 2;
  }
  _width = width;
  _height = height;
  _grid.resize(width);
  for (auto& row : _grid) row.resize(height);
  _resized = true;
}