summary refs log tree commit diff stats
path: root/src/editor.cpp
diff options
context:
space:
mode:
authorKelly Rauchenberger <fefferburbia@gmail.com>2019-03-10 12:07:40 -0400
committerKelly Rauchenberger <fefferburbia@gmail.com>2019-03-10 12:07:40 -0400
commit57fe8f3c4124819b95164547333a33f4c45eac8d (patch)
tree99dd89a0c1cf0a8ceaa2ff941549d631950efd11 /src/editor.cpp
parentbf34f891c5c09e6c8a42797085860fa80ab53814 (diff)
downloaddispatcher-57fe8f3c4124819b95164547333a33f4c45eac8d.tar.gz
dispatcher-57fe8f3c4124819b95164547333a33f4c45eac8d.tar.bz2
dispatcher-57fe8f3c4124819b95164547333a33f4c45eac8d.zip
Editor now allows tile placement
You can scroll through the three layers (map, track, object) with Z/X. You can swap between focusing on the map and the tileset with TAB. You can place tiles with enter or space. Pretty rudimentary, but it's a start.
Diffstat (limited to 'src/editor.cpp')
-rw-r--r--src/editor.cpp246
1 files changed, 235 insertions, 11 deletions
diff --git a/src/editor.cpp b/src/editor.cpp index 92c6b67..30dde45 100644 --- a/src/editor.cpp +++ b/src/editor.cpp
@@ -5,27 +5,150 @@ void Editor::tick(
5 double dt, 5 double dt,
6 const Uint8* keystate) 6 const Uint8* keystate)
7{ 7{
8 if (keystate[SDL_SCANCODE_LEFT] ||
9 keystate[SDL_SCANCODE_UP] ||
10 keystate[SDL_SCANCODE_RIGHT] ||
11 keystate[SDL_SCANCODE_DOWN])
12 {
13 // If the player is holding down a directional key, accumulate the time
14 // since the last tick, and then apply the directional key as many times as
15 // needed. The input lag class automatically handles the delays necessary
16 // for key repeat.
17 inputLag_.accumulate(dt);
8 18
9} 19 while (inputLag_.step())
20 {
21 if (mapFocus_)
22 {
23 // If we are focused on the map, move the map cursor.
24 if (keystate[SDL_SCANCODE_LEFT] && cursor_.x() > 0)
25 {
26 cursor_.x()--;
27 }
10 28
11void Editor::render(SDL_Renderer* ren) 29 if (keystate[SDL_SCANCODE_UP] && cursor_.y() > 0)
12{ 30 {
13 if (!background_) 31 cursor_.y()--;
32 }
33
34 if (keystate[SDL_SCANCODE_RIGHT] &&
35 cursor_.x() < level_.getSize().w() - 1)
36 {
37 cursor_.x()++;
38 }
39
40 if (keystate[SDL_SCANCODE_DOWN] &&
41 cursor_.y() < level_.getSize().h() - 1)
42 {
43 cursor_.y()++;
44 }
45 } else {
46 // If we are focused on the tileset, rotate through the selection of
47 // tiles.
48 if (keystate[SDL_SCANCODE_UP])
49 {
50 selectedTile_--;
51 } else if (keystate[SDL_SCANCODE_DOWN])
52 {
53 selectedTile_++;
54 }
55
56 selectedTile_ %= level_.getTileset(layer_).getNumTiles();
57 }
58 }
59 } else if (inputLag_.isActive())
14 { 60 {
15 surface_ptr bgSurf(IMG_Load("../res/editor_bg.png")); 61 // If the player is not holding down a directional key, reset the input lag.
62 inputLag_.reset();
63 }
64
65 // Check for keypress changes since the last tick.
66 input_.tick(keystate);
16 67
17 if (!bgSurf) 68 if (input_.wasPressed(SDL_SCANCODE_Z))
69 {
70 switch (layer_)
18 { 71 {
19 throw img_error(); 72 case Layer::map:
73 {
74 layer_ = Layer::object;
75
76 break;
77 }
78
79 case Layer::track:
80 {
81 layer_ = Layer::map;
82
83 break;
84 }
85
86 case Layer::object:
87 {
88 layer_ = Layer::track;
89
90 break;
91 }
20 } 92 }
21 93
22 background_.reset(SDL_CreateTextureFromSurface(ren, bgSurf.get())); 94 selectedTile_ = 0;
23 bgSize_ = { bgSurf->w, bgSurf->h }; 95
96 // Reset the cached map so that it gets redrawn with the focused layer.
97 renderedMap_.reset();
98 } else if (input_.wasPressed(SDL_SCANCODE_X))
99 {
100 switch (layer_)
101 {
102 case Layer::map:
103 {
104 layer_ = Layer::track;
105
106 break;
107 }
108
109 case Layer::track:
110 {
111 layer_ = Layer::object;
112
113 break;
114 }
115
116 case Layer::object:
117 {
118 layer_ = Layer::map;
119
120 break;
121 }
122 }
123
124 selectedTile_ = 0;
125
126 // Reset the cached map so that it gets redrawn with the focused layer.
127 renderedMap_.reset();
128 } else if (input_.wasPressed(SDL_SCANCODE_TAB))
129 {
130 mapFocus_ = !mapFocus_;
24 } 131 }
25 132
26 for (int y = 0; y < WINDOW_SIZE.h() / bgSize_.h(); y++) 133 if (mapFocus_)
27 { 134 {
28 for (int x = 0; x < WINDOW_SIZE.w() / bgSize_.w(); x++) 135 if (keystate[SDL_SCANCODE_RETURN] ||
136 keystate[SDL_SCANCODE_SPACE])
137 {
138 level_.at(cursor_.x(), cursor_.y(), layer_) = selectedTile_;
139
140 // Reset the cached map so that it gets redrawn with the new tile.
141 renderedMap_.reset();
142 }
143 }
144}
145
146void Editor::render(SDL_Renderer* ren)
147{
148 // Tile the background art.
149 for (int y = 0; y <= WINDOW_SIZE.h() / bgSize_.h(); y++)
150 {
151 for (int x = 0; x <= WINDOW_SIZE.w() / bgSize_.w(); x++)
29 { 152 {
30 SDL_Rect rect { 153 SDL_Rect rect {
31 x * bgSize_.w(), 154 x * bgSize_.w(),
@@ -37,4 +160,105 @@ void Editor::render(SDL_Renderer* ren)
37 SDL_RenderCopy(ren, background_.get(), nullptr, &rect); 160 SDL_RenderCopy(ren, background_.get(), nullptr, &rect);
38 } 161 }
39 } 162 }
163
164 // Render and cache the map if the cache is currently empty.
165 if (!renderedMap_)
166 {
167 renderedMap_.reset(
168 SDL_CreateTexture(
169 ren,
170 SDL_PIXELFORMAT_RGBA8888,
171 SDL_TEXTUREACCESS_TARGET,
172 LEVEL_SIZE.w(),
173 LEVEL_SIZE.h()));
174
175 // Render each layer separately, then compose them atop each other. Layers
176 // above the currently selected one are drawn semi-transparently.
177 texture_ptr mapRender = level_.render(ren, Layer::map);
178 texture_ptr trackRender = level_.render(ren, Layer::track);
179 texture_ptr objectRender = level_.render(ren, Layer::object);
180
181 if (layer_ < Layer::track)
182 {
183 SDL_SetTextureBlendMode(trackRender.get(), SDL_BLENDMODE_BLEND);
184 SDL_SetTextureAlphaMod(trackRender.get(), 127);
185 }
186
187 if (layer_ < Layer::object)
188 {
189 SDL_SetTextureBlendMode(objectRender.get(), SDL_BLENDMODE_BLEND);
190 SDL_SetTextureAlphaMod(objectRender.get(), 127);
191 }
192
193 SDL_SetRenderTarget(ren, renderedMap_.get());
194 SDL_RenderCopy(ren, mapRender.get(), nullptr, nullptr);
195 SDL_RenderCopy(ren, trackRender.get(), nullptr, nullptr);
196 SDL_RenderCopy(ren, objectRender.get(), nullptr, nullptr);
197 SDL_SetRenderTarget(ren, nullptr);
198 }
199
200 // Copy the rendered map onto the editor.
201 SDL_Rect mapLoc {
202 static_cast<int>(BORDER_SIZE.w()),
203 static_cast<int>(BORDER_SIZE.h()),
204 static_cast<int>(LEVEL_SIZE.w()),
205 static_cast<int>(LEVEL_SIZE.h())
206 };
207
208 SDL_RenderCopy(ren, renderedMap_.get(), nullptr, &mapLoc);
209
210 // If the map is focused, draw an outline around it.
211 if (mapFocus_)
212 {
213 SDL_SetRenderDrawColor(ren, 255, 0, 0, 255);
214 SDL_RenderDrawRect(ren, &mapLoc);
215 }
216
217 // Draw a box indicating the position of the map cursor.
218 vec2s cursorLoc = BORDER_SIZE + TILE_SIZE * cursor_;
219
220 SDL_Rect cursorRect {
221 static_cast<int>(cursorLoc.x()),
222 static_cast<int>(cursorLoc.y()),
223 static_cast<int>(TILE_SIZE.w()),
224 static_cast<int>(TILE_SIZE.h())
225 };
226
227 SDL_SetRenderDrawColor(ren, 255, 0, 0, 255);
228 SDL_RenderDrawRect(ren, &cursorRect);
229
230 // Draw the tileset for the currently selected layer.
231 SDL_Rect tilesetLoc {
232 static_cast<int>(BORDER_SIZE.w() * 2 + LEVEL_SIZE.w()),
233 static_cast<int>(BORDER_SIZE.h()),
234 static_cast<int>(TILE_SIZE.w()),
235 level_.getTileset(layer_).getSize().h()
236 };
237
238 SDL_SetRenderDrawColor(ren, 255, 255, 255, 255);
239 SDL_RenderFillRect(ren, &tilesetLoc);
240
241 SDL_RenderCopy(
242 ren,
243 level_.getTileset(layer_).getImage().get(),
244 nullptr,
245 &tilesetLoc);
246
247 // If the tileset is focused, draw an outline around it.
248 if (!mapFocus_)
249 {
250 SDL_SetRenderDrawColor(ren, 255, 0, 0, 255);
251 SDL_RenderDrawRect(ren, &tilesetLoc);
252 }
253
254 // Draw a box indicating which tile is currently selected.
255 SDL_Rect tileCursorRect {
256 tilesetLoc.x,
257 static_cast<int>((1 + selectedTile_) * TILE_SIZE.h()),
258 static_cast<int>(TILE_SIZE.w()),
259 static_cast<int>(TILE_SIZE.h())
260 };
261
262 SDL_SetRenderDrawColor(ren, 255, 255, 0, 255);
263 SDL_RenderDrawRect(ren, &tileCursorRect);
40} 264}