diff options
| author | Kelly Rauchenberger <fefferburbia@gmail.com> | 2019-03-10 12:07:40 -0400 |
|---|---|---|
| committer | Kelly Rauchenberger <fefferburbia@gmail.com> | 2019-03-10 12:07:40 -0400 |
| commit | 57fe8f3c4124819b95164547333a33f4c45eac8d (patch) | |
| tree | 99dd89a0c1cf0a8ceaa2ff941549d631950efd11 /src/editor.cpp | |
| parent | bf34f891c5c09e6c8a42797085860fa80ab53814 (diff) | |
| download | dispatcher-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.cpp | 246 |
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 | ||
| 11 | void 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 | |||
| 146 | void 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 | } |
