1 | #ifndef GAME_EDITOR_MAPITEMS_LAYER_TILES_H |
2 | #define GAME_EDITOR_MAPITEMS_LAYER_TILES_H |
3 | |
4 | #include <game/editor/editor_trackers.h> |
5 | #include <map> |
6 | |
7 | #include "layer.h" |
8 | |
9 | struct STileStateChange |
10 | { |
11 | bool m_Changed; |
12 | CTile m_Previous; |
13 | CTile m_Current; |
14 | }; |
15 | |
16 | template<typename T> |
17 | using EditorTileStateChangeHistory = std::map<int, std::map<int, T>>; |
18 | |
19 | enum |
20 | { |
21 | DIRECTION_LEFT = 0, |
22 | DIRECTION_RIGHT, |
23 | DIRECTION_UP, |
24 | DIRECTION_DOWN, |
25 | }; |
26 | |
27 | struct RECTi |
28 | { |
29 | int x, y; |
30 | int w, h; |
31 | }; |
32 | |
33 | class CLayerTiles : public CLayer |
34 | { |
35 | protected: |
36 | template<typename T> |
37 | void ShiftImpl(T *pTiles, int Direction, int ShiftBy) |
38 | { |
39 | switch(Direction) |
40 | { |
41 | case DIRECTION_LEFT: |
42 | ShiftBy = minimum(a: ShiftBy, b: m_Width); |
43 | for(int y = 0; y < m_Height; ++y) |
44 | { |
45 | if(ShiftBy < m_Width) |
46 | mem_move(&pTiles[y * m_Width], &pTiles[y * m_Width + ShiftBy], (m_Width - ShiftBy) * sizeof(T)); |
47 | mem_zero(&pTiles[y * m_Width + (m_Width - ShiftBy)], ShiftBy * sizeof(T)); |
48 | } |
49 | break; |
50 | case DIRECTION_RIGHT: |
51 | ShiftBy = minimum(a: ShiftBy, b: m_Width); |
52 | for(int y = 0; y < m_Height; ++y) |
53 | { |
54 | if(ShiftBy < m_Width) |
55 | mem_move(&pTiles[y * m_Width + ShiftBy], &pTiles[y * m_Width], (m_Width - ShiftBy) * sizeof(T)); |
56 | mem_zero(&pTiles[y * m_Width], ShiftBy * sizeof(T)); |
57 | } |
58 | break; |
59 | case DIRECTION_UP: |
60 | ShiftBy = minimum(a: ShiftBy, b: m_Height); |
61 | for(int y = ShiftBy; y < m_Height; ++y) |
62 | { |
63 | mem_copy(&pTiles[(y - ShiftBy) * m_Width], &pTiles[y * m_Width], m_Width * sizeof(T)); |
64 | } |
65 | for(int y = m_Height - ShiftBy; y < m_Height; ++y) |
66 | { |
67 | mem_zero(&pTiles[y * m_Width], m_Width * sizeof(T)); |
68 | } |
69 | break; |
70 | case DIRECTION_DOWN: |
71 | ShiftBy = minimum(a: ShiftBy, b: m_Height); |
72 | for(int y = m_Height - ShiftBy - 1; y >= 0; --y) |
73 | { |
74 | mem_copy(&pTiles[(y + ShiftBy) * m_Width], &pTiles[y * m_Width], m_Width * sizeof(T)); |
75 | } |
76 | for(int y = 0; y < ShiftBy; ++y) |
77 | { |
78 | mem_zero(&pTiles[y * m_Width], m_Width * sizeof(T)); |
79 | } |
80 | break; |
81 | } |
82 | } |
83 | template<typename T> |
84 | void BrushFlipXImpl(T *pTiles) |
85 | { |
86 | for(int y = 0; y < m_Height; y++) |
87 | for(int x = 0; x < m_Width / 2; x++) |
88 | std::swap(pTiles[y * m_Width + x], pTiles[(y + 1) * m_Width - 1 - x]); |
89 | } |
90 | template<typename T> |
91 | void BrushFlipYImpl(T *pTiles) |
92 | { |
93 | for(int y = 0; y < m_Height / 2; y++) |
94 | for(int x = 0; x < m_Width; x++) |
95 | std::swap(pTiles[y * m_Width + x], pTiles[(m_Height - 1 - y) * m_Width + x]); |
96 | } |
97 | |
98 | public: |
99 | CLayerTiles(CEditor *pEditor, int w, int h); |
100 | CLayerTiles(const CLayerTiles &Other); |
101 | ~CLayerTiles(); |
102 | |
103 | virtual CTile GetTile(int x, int y); |
104 | virtual void SetTile(int x, int y, CTile Tile); |
105 | void SetTileIgnoreHistory(int x, int y, CTile Tile) const; |
106 | |
107 | virtual void Resize(int NewW, int NewH); |
108 | virtual void Shift(int Direction); |
109 | |
110 | void MakePalette() const; |
111 | void Render(bool Tileset = false) override; |
112 | |
113 | int ConvertX(float x) const; |
114 | int ConvertY(float y) const; |
115 | void Convert(CUIRect Rect, RECTi *pOut) const; |
116 | void Snap(CUIRect *pRect) const; |
117 | void Clamp(RECTi *pRect) const; |
118 | |
119 | virtual bool IsEntitiesLayer() const override; |
120 | |
121 | virtual bool IsEmpty(const std::shared_ptr<CLayerTiles> &pLayer); |
122 | void BrushSelecting(CUIRect Rect) override; |
123 | int BrushGrab(std::shared_ptr<CLayerGroup> pBrush, CUIRect Rect) override; |
124 | void FillSelection(bool Empty, std::shared_ptr<CLayer> pBrush, CUIRect Rect) override; |
125 | void BrushDraw(std::shared_ptr<CLayer> pBrush, float wx, float wy) override; |
126 | void BrushFlipX() override; |
127 | void BrushFlipY() override; |
128 | void BrushRotate(float Amount) override; |
129 | |
130 | std::shared_ptr<CLayer> Duplicate() const override; |
131 | const char *TypeName() const override; |
132 | |
133 | virtual void ShowInfo(); |
134 | CUi::EPopupMenuFunctionResult RenderProperties(CUIRect *pToolbox) override; |
135 | |
136 | struct SCommonPropState |
137 | { |
138 | enum |
139 | { |
140 | MODIFIED_SIZE = 1 << 0, |
141 | MODIFIED_COLOR = 1 << 1, |
142 | }; |
143 | int m_Modified = 0; |
144 | int m_Width = -1; |
145 | int m_Height = -1; |
146 | int m_Color = 0; |
147 | }; |
148 | static CUi::EPopupMenuFunctionResult RenderCommonProperties(SCommonPropState &State, CEditor *pEditor, CUIRect *pToolbox, std::vector<std::shared_ptr<CLayerTiles>> &vpLayers, std::vector<int> &vLayerIndices); |
149 | |
150 | void ModifyImageIndex(FIndexModifyFunction pfnFunc) override; |
151 | void ModifyEnvelopeIndex(FIndexModifyFunction pfnFunc) override; |
152 | |
153 | void PrepareForSave(); |
154 | void (int TilemapItemVersion, const CTile *pSavedTiles, size_t SavedTilesSize) const; |
155 | |
156 | void GetSize(float *pWidth, float *pHeight) override |
157 | { |
158 | *pWidth = m_Width * 32.0f; |
159 | *pHeight = m_Height * 32.0f; |
160 | } |
161 | |
162 | void FlagModified(int x, int y, int w, int h); |
163 | |
164 | int m_Game; |
165 | int m_Image; |
166 | int m_Width; |
167 | int m_Height; |
168 | CColor m_Color; |
169 | int m_ColorEnv; |
170 | int m_ColorEnvOffset; |
171 | CTile *m_pTiles; |
172 | |
173 | // DDRace |
174 | |
175 | int m_AutoMapperConfig; |
176 | int m_Seed; |
177 | bool m_AutoAutoMap; |
178 | int m_Tele; |
179 | int m_Speedup; |
180 | int m_Front; |
181 | int m_Switch; |
182 | int m_Tune; |
183 | char m_aFileName[IO_MAX_PATH_LENGTH]; |
184 | |
185 | EditorTileStateChangeHistory<STileStateChange> m_TilesHistory; |
186 | inline virtual void ClearHistory() { m_TilesHistory.clear(); } |
187 | |
188 | static bool HasAutomapEffect(ETilesProp Prop); |
189 | |
190 | protected: |
191 | void RecordStateChange(int x, int y, CTile Previous, CTile Tile); |
192 | |
193 | void ShowPreventUnusedTilesWarning(); |
194 | |
195 | friend class CAutoMapper; |
196 | }; |
197 | |
198 | #endif |
199 | |