summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/consts.h4
-rw-r--r--src/game.cpp123
-rw-r--r--src/game.h40
-rw-r--r--src/main.cpp2
-rw-r--r--src/map.h184
-rw-r--r--src/renderer.cpp83
6 files changed, 256 insertions, 180 deletions
diff --git a/src/consts.h b/src/consts.h index 141838b..78312c0 100644 --- a/src/consts.h +++ b/src/consts.h
@@ -5,9 +5,11 @@ constexpr int GAME_WIDTH = 1280;//640*2;
5constexpr int GAME_HEIGHT = 720;//480*2; 5constexpr int GAME_HEIGHT = 720;//480*2;
6constexpr int TILE_WIDTH = 8*2; 6constexpr int TILE_WIDTH = 8*2;
7constexpr int TILE_HEIGHT = TILE_WIDTH; 7constexpr int TILE_HEIGHT = TILE_WIDTH;
8constexpr int INIT_ZOOM = 5; 8constexpr int INIT_ZOOM = 2;
9constexpr int ZOOM_X_FACTOR = 16; 9constexpr int ZOOM_X_FACTOR = 16;
10constexpr int ZOOM_Y_FACTOR = 9; 10constexpr int ZOOM_Y_FACTOR = 9;
11constexpr int CHUNK_WIDTH = 80;
12constexpr int CHUNK_HEIGHT = 80;
11constexpr int RADIUS = 8; 13constexpr int RADIUS = 8;
12constexpr int NUM_TITLES = 1; 14constexpr int NUM_TITLES = 1;
13 15
diff --git a/src/game.cpp b/src/game.cpp index a7c94db..62e755b 100644 --- a/src/game.cpp +++ b/src/game.cpp
@@ -8,25 +8,11 @@
8 8
9Game::Game(std::mt19937& rng, Muxer& muxer) : 9Game::Game(std::mt19937& rng, Muxer& muxer) :
10 rng(rng), 10 rng(rng),
11 muxer(muxer), 11 muxer(muxer)
12 map(
13 -INIT_ZOOM * ZOOM_X_FACTOR / 2,
14 -INIT_ZOOM * ZOOM_Y_FACTOR / 2,
15 INIT_ZOOM * ZOOM_X_FACTOR,
16 INIT_ZOOM * ZOOM_Y_FACTOR)
17{ 12{
18 losePopLampTimer.accumulate(losePopLampTimer.getDt()); 13 losePopLampTimer.accumulate(losePopLampTimer.getDt());
19 14
20 for (MapData& md : map.data()) 15 loadMap();
21 {
22 if (std::bernoulli_distribution(0.5)(rng))
23 {
24 md.tile = Tile::Wall;
25 }
26 }
27
28 tick();
29 tick();
30 16
31 for (int y = -1; y <= 1; y++) 17 for (int y = -1; y <= 1; y++)
32 { 18 {
@@ -39,12 +25,12 @@ Game::Game(std::mt19937& rng, Muxer& muxer) :
39 tick(); 25 tick();
40} 26}
41 27
42inline bool isTileSetOrNotLit(const Map<MapData>& map, int x, int y) 28inline bool isTileSetOrNotLit(const Map& map, int x, int y)
43{ 29{
44 return (map.inBounds(x, y) && (map.at(x,y).tile == Tile::Wall || !map.at(x,y).lit)); 30 return (map.inBounds(x, y) && (map.at(x,y).tile == Tile::Wall || !map.at(x,y).lit));
45} 31}
46 32
47inline bool isTileSet(const Map<MapData>& map, int x, int y, Tile val = Tile::Wall) 33inline bool isTileSet(const Map& map, int x, int y, Tile val = Tile::Wall)
48{ 34{
49 return (map.inBounds(x, y) && map.at(x,y).tile == val); 35 return (map.inBounds(x, y) && map.at(x,y).tile == val);
50} 36}
@@ -69,7 +55,7 @@ void Game::tick(
69 bool invert, 55 bool invert,
70 bool onlyDark) 56 bool onlyDark)
71{ 57{
72 Map<MapData> temp(map); 58 std::vector<MapData> temp(map.data());
73 59
74 for (int y = map.getTop(); y < map.getBottom(); y++) 60 for (int y = map.getTop(); y < map.getBottom(); y++)
75 { 61 {
@@ -102,21 +88,22 @@ void Game::tick(
102 incrementIfSet(*this, count, x+1, y ); 88 incrementIfSet(*this, count, x+1, y );
103 incrementIfSet(*this, count, x+1, y+1); 89 incrementIfSet(*this, count, x+1, y+1);
104 90
91 int tempIndex = map.getTrueX(x) + map.getTrueY(y) * map.getWidth();
105 if (count >= 5) 92 if (count >= 5)
106 { 93 {
107 temp.at(x,y).tile = Tile::Wall; 94 temp[tempIndex].tile = Tile::Wall;
108 } else { 95 } else {
109 temp.at(x,y).tile = Tile::Floor; 96 temp[tempIndex].tile = Tile::Floor;
110 } 97 }
111 98
112 if (temp.at(x,y).tile != map.at(x,y).tile) { 99 if (temp[tempIndex].tile != map.at(x,y).tile) {
113 temp.at(x,y).dirtyRender = true; 100 temp[tempIndex].dirtyRender = true;
114 dirtyRender = true; 101 dirtyRender = true;
115 } 102 }
116 } 103 }
117 } 104 }
118 105
119 map = std::move(temp); 106 map.data() = std::move(temp);
120} 107}
121 108
122void Game::tick(bool onlyDark) 109void Game::tick(bool onlyDark)
@@ -132,10 +119,10 @@ void Game::tick(bool onlyDark)
132 119
133bool Game::movePlayer(int x, int y) 120bool Game::movePlayer(int x, int y)
134{ 121{
135 if (x >= curBoundX && 122 if (/*x >= curBoundX &&
136 y >= curBoundY && 123 y >= curBoundY &&
137 x < curBoundX + curZoom * ZOOM_X_FACTOR && 124 x < curBoundX + curZoom * ZOOM_X_FACTOR &&
138 y < curBoundY + curZoom * ZOOM_Y_FACTOR && 125 y < curBoundY + curZoom * ZOOM_Y_FACTOR &&*/
139 map.at(x,y).tile == Tile::Floor) 126 map.at(x,y).tile == Tile::Floor)
140 { 127 {
141 if (map.at(player_x, player_y).tile == Tile::Floor) 128 if (map.at(player_x, player_y).tile == Tile::Floor)
@@ -154,6 +141,13 @@ bool Game::movePlayer(int x, int y)
154 moveProgress.start(66); 141 moveProgress.start(66);
155 dirtyLighting = true; 142 dirtyLighting = true;
156 143
144 int chunkX, chunkY, old_chunkX, old_chunkY;
145 toChunkPos(player_x, player_y, chunkX, chunkY);
146 toChunkPos(player_oldx, player_oldy, old_chunkX, old_chunkY);
147 if ((chunkX != old_chunkX) || (chunkY != old_chunkY)) {
148 loadMap();
149 }
150
157 return true; 151 return true;
158 } else { 152 } else {
159 if (!alreadyBumped) { 153 if (!alreadyBumped) {
@@ -501,39 +495,25 @@ void Game::processKickup()
501 }); 495 });
502} 496}
503 497
504void Game::growMap(size_t zoom) 498void Game::loadMap() {
505{ 499 int newChunksHoriz = std::ceil(static_cast<double>(curZoom) * ZOOM_X_FACTOR / CHUNK_WIDTH) + 4;
506 int ol = map.getLeft(); 500 int newChunksVert = std::ceil(static_cast<double>(curZoom) * ZOOM_Y_FACTOR / CHUNK_HEIGHT) + 4;
507 int ot = map.getTop(); 501 int curPlayerChunkX, curPlayerChunkY;
508 int ow = map.getWidth(); 502 toChunkPos(player_x, player_y, curPlayerChunkX, curPlayerChunkY);
509 int oh = map.getHeight();
510 503
511 map.resize( 504 map.load(
512 -zoom * ZOOM_X_FACTOR / 2, 505 curPlayerChunkX - newChunksHoriz / 2,
513 -zoom * ZOOM_Y_FACTOR / 2, 506 curPlayerChunkY - newChunksVert / 2,
514 zoom * ZOOM_X_FACTOR, 507 newChunksHoriz,
515 zoom * ZOOM_Y_FACTOR); 508 newChunksVert,
509 rng);
516 510
517 maxZoom = zoom; 511 tick();
518 512 tick();
519 for (int y = map.getTop(); y < map.getBottom(); y++) 513 tick();
520 {
521 for (int x = map.getLeft(); x < map.getRight(); x++)
522 {
523 if (!(x >= ol && x < (ol + ow) && y >= ot && y < (ot + oh)))
524 {
525 if (std::bernoulli_distribution(0.5)(rng))
526 {
527 map.at(x,y).tile = Tile::Wall;
528 }
529 }
530 }
531 }
532 514
533 for (int i = 0; i < 3; i++) 515 dirtyLighting = true;
534 { 516 dirtyRender = true;
535 tick(ol, ot, ol + ow, ot + oh, true);
536 }
537} 517}
538 518
539void Game::setZoom(size_t zoom) 519void Game::setZoom(size_t zoom)
@@ -543,40 +523,11 @@ void Game::setZoom(size_t zoom)
543 return; 523 return;
544 } 524 }
545 525
546 if (zoom > maxZoom)
547 {
548 growMap(zoom);
549 }
550
551 std::tie(
552 lastZoomLeft,
553 lastZoomTop,
554 lastZoomWidth,
555 lastZoomHeight) =
556 Renderer::calculateZoomRect(*this);
557
558 zoomProgress = 0; 526 zoomProgress = 0;
559 zoomLength = std::abs(static_cast<long>(zoom - curZoom)) * TILE_WIDTH; 527 zoomLength = std::abs(static_cast<long>(zoom - curZoom)) * TILE_WIDTH;
560 curZoom = zoom; 528 curZoom = zoom;
561 zooming = true; 529 zooming = true;
562 530 loadMap();
563 curBoundX = player_x - zoom * ZOOM_X_FACTOR / 2;
564 if (curBoundX < map.getLeft())
565 {
566 curBoundX = map.getLeft();
567 } else if (curBoundX + zoom * ZOOM_X_FACTOR >= map.getRight())
568 {
569 curBoundX = map.getRight() - zoom * ZOOM_X_FACTOR;
570 }
571
572 curBoundY = player_y - zoom * ZOOM_Y_FACTOR / 2;
573 if (curBoundY < map.getTop())
574 {
575 curBoundY = map.getTop();
576 } else if (curBoundY + zoom * ZOOM_Y_FACTOR >= map.getBottom())
577 {
578 curBoundY = map.getBottom() - zoom * ZOOM_Y_FACTOR;
579 }
580 531
581 int zoomLevel = getZoomLevel(*this); 532 int zoomLevel = getZoomLevel(*this);
582 if (zoomLevel == 0) { 533 if (zoomLevel == 0) {
diff --git a/src/game.h b/src/game.h index 446680a..40ace3d 100644 --- a/src/game.h +++ b/src/game.h
@@ -16,20 +16,6 @@ constexpr int TilesetIndex(int x, int y) {
16 return x + y * 24; 16 return x + y * 24;
17} 17}
18 18
19enum class Tile {
20 Floor,
21 Wall,
22 Dust,
23 Lamp
24};
25
26enum class Source {
27 None,
28 Dust,
29 Lamp,
30 Player
31};
32
33enum class LoseState { 19enum class LoseState {
34 None, 20 None,
35 PoppingLamps, 21 PoppingLamps,
@@ -52,8 +38,6 @@ struct Input {
52 } 38 }
53}; 39};
54 40
55using coord = std::tuple<int, int>;
56
57struct Kickup { 41struct Kickup {
58 int x; 42 int x;
59 int y; 43 int y;
@@ -64,18 +48,6 @@ struct Kickup {
64 std::set<coord> front; 48 std::set<coord> front;
65}; 49};
66 50
67struct MapData {
68 Tile tile = Tile::Floor;
69 bool lit = false;
70 bool wasLit = false;
71 size_t dustLife = 0;
72 Source lightType = Source::None;
73 int lightRadius = 0;
74 std::set<coord> litTiles;
75 int renderId = -1;
76 bool dirtyRender = true;
77};
78
79class Game { 51class Game {
80public: 52public:
81 53
@@ -89,7 +61,7 @@ public:
89 bool quit = false; 61 bool quit = false;
90 LoseState losing = LoseState::None; 62 LoseState losing = LoseState::None;
91 63
92 Map<MapData> map; 64 Map map;
93 std::list<Kickup> kickups; 65 std::list<Kickup> kickups;
94 int litSpots = 0; 66 int litSpots = 0;
95 bool dirtyLighting = true; 67 bool dirtyLighting = true;
@@ -105,18 +77,10 @@ public:
105 Animation playerAnim {"../res/player_anim.txt"}; 77 Animation playerAnim {"../res/player_anim.txt"};
106 78
107 int maxZoom = INIT_ZOOM; 79 int maxZoom = INIT_ZOOM;
108
109 int curZoom = INIT_ZOOM; 80 int curZoom = INIT_ZOOM;
110 int curBoundX = map.getLeft();
111 int curBoundY = map.getTop();
112
113 bool zooming = false; 81 bool zooming = false;
114 int zoomProgress = 0; 82 int zoomProgress = 0;
115 int zoomLength; 83 int zoomLength;
116 int lastZoomTop;
117 int lastZoomLeft;
118 int lastZoomWidth;
119 int lastZoomHeight;
120 84
121 Input keystate; 85 Input keystate;
122 bool firstInput = false; 86 bool firstInput = false;
@@ -159,7 +123,7 @@ private:
159 123
160 void processKickup(); 124 void processKickup();
161 125
162 void growMap(size_t zoom); 126 void loadMap();
163 127
164 void setZoom(size_t zoom); 128 void setZoom(size_t zoom);
165 129
diff --git a/src/main.cpp b/src/main.cpp index 4ae11d6..0d14986 100644 --- a/src/main.cpp +++ b/src/main.cpp
@@ -23,7 +23,7 @@ int main(int, char**)
23 23
24 Game game(rng, muxer); 24 Game game(rng, muxer);
25 25
26 constexpr int titleFadeLen = 3000; 26 constexpr int titleFadeLen = 2000;
27 bool doneTitles = false; 27 bool doneTitles = false;
28 int titleNum = 0; 28 int titleNum = 0;
29 TitleState titleState = TitleState::FadeIn; 29 TitleState titleState = TitleState::FadeIn;
diff --git a/src/map.h b/src/map.h index 329553c..d28b8d4 100644 --- a/src/map.h +++ b/src/map.h
@@ -3,23 +3,62 @@
3 3
4#include <vector> 4#include <vector>
5#include <algorithm> 5#include <algorithm>
6#include <array>
7#include <list>
8#include <map>
9#include <random>
10#include "consts.h"
6 11
7template <typename T> 12using coord = std::tuple<int, int>;
8class Map {
9public:
10 13
11 Map( 14enum class Tile {
12 int left, 15 Floor,
13 int top, 16 Wall,
14 int width, 17 Dust,
15 int height) : 18 Lamp
16 left_(left), 19};
17 top_(top), 20
18 width_(width), 21enum class Source {
19 height_(height), 22 None,
20 data_(width_*height_) 23 Dust,
21 { 24 Lamp,
25 Player
26};
27
28struct MapData {
29 Tile tile = Tile::Floor;
30 bool lit = false;
31 bool wasLit = false;
32 size_t dustLife = 0;
33 Source lightType = Source::None;
34 int lightRadius = 0;
35 std::set<coord> litTiles;
36 int renderId = -1;
37 bool dirtyRender = true;
38};
39
40struct Chunk {
41 std::array<MapData, CHUNK_WIDTH*CHUNK_HEIGHT> data;
42 int litTiles = 0;
43 int x;
44 int y;
45};
46
47inline void toChunkPos(int x, int y, int& cx, int& cy) {
48 cx = x / CHUNK_WIDTH;
49 cy = y / CHUNK_HEIGHT;
50 if (x < 0) {
51 cx *= -1;
52 cx--;
53 }
54 if (y < 0) {
55 cy *= -1;
56 cy--;
22 } 57 }
58}
59
60class Map {
61public:
23 62
24 inline int getLeft() const 63 inline int getLeft() const
25 { 64 {
@@ -69,27 +108,27 @@ public:
69 (y < top_ + height_); 108 (y < top_ + height_);
70 } 109 }
71 110
72 inline const T& at(int x, int y) const 111 inline const MapData& at(int x, int y) const
73 { 112 {
74 return data_.at((x - left_) + width_ * (y - top_)); 113 return loaded_.at((x - left_) + width_ * (y - top_));
75 } 114 }
76 115
77 inline T& at(int x, int y) 116 inline MapData& at(int x, int y)
78 { 117 {
79 return const_cast<T&>(static_cast<const Map&>(*this).at(x, y)); 118 return const_cast<MapData&>(static_cast<const Map&>(*this).at(x, y));
80 } 119 }
81 120
82 inline const std::vector<T>& data() const 121 inline const std::vector<MapData>& data() const
83 { 122 {
84 return data_; 123 return loaded_;
85 } 124 }
86 125
87 inline std::vector<T>& data() 126 inline std::vector<MapData>& data()
88 { 127 {
89 return data_; 128 return loaded_;
90 } 129 }
91 130
92 void resize(int newLeft, int newTop, int newWidth, int newHeight) 131 /*void resize(int newLeft, int newTop, int newWidth, int newHeight)
93 { 132 {
94 std::vector<T> newData(newWidth * newHeight); 133 std::vector<T> newData(newWidth * newHeight);
95 134
@@ -112,6 +151,96 @@ public:
112 width_ = newWidth; 151 width_ = newWidth;
113 height_ = newHeight; 152 height_ = newHeight;
114 data_.swap(newData); 153 data_.swap(newData);
154 }*/
155
156 void load(int newLeftChunk, int newTopChunk, int newWidthChunks, int newHeightChunks, std::mt19937& rng) {
157 // Flush the currently loaded data as long as there is any (this isn't the first load).
158 if (!loaded_.empty()) {
159 std::vector<size_t> touchedChunks;
160
161 for (int chunkY = 0; chunkY < chunksVert_; chunkY++) {
162 for (int chunkX = 0; chunkX < chunksHoriz_; chunkX++) {
163 size_t chunkIndex = chunkByPos_.at(leftmostChunk_ + chunkX).at(topmostChunk_ + chunkY);
164 touchedChunks.push_back(chunkIndex);
165
166 Chunk& chunk = chunks_.at(chunkIndex);
167 chunk.litTiles = 0;
168
169 int startX = chunkX * CHUNK_WIDTH;
170 int startY = chunkY * CHUNK_HEIGHT;
171 for (int y=0; y<CHUNK_HEIGHT; y++) {
172 for (int x=0; x<CHUNK_WIDTH; x++) {
173 chunk.data[x+y*CHUNK_WIDTH] = loaded_[startX+x+(startY+y)*width_];
174 if (chunk.data[x+y*CHUNK_WIDTH].lit) {
175 chunk.litTiles++;
176 }
177 }
178 }
179 }
180 }
181
182 // Destroy any completely unlit chunks.
183 for (size_t chunkIndex : touchedChunks) {
184 if (chunks_[chunkIndex].litTiles == 0) {
185 chunkByPos_[chunks_[chunkIndex].x].erase(chunks_[chunkIndex].y);
186 freeList_.push_back(chunkIndex);
187 }
188 }
189 }
190
191 leftmostChunk_ = newLeftChunk;
192 topmostChunk_ = newTopChunk;
193 chunksHoriz_ = newWidthChunks;
194 chunksVert_ = newHeightChunks;
195 left_ = newLeftChunk * CHUNK_WIDTH;
196 top_ = newTopChunk * CHUNK_HEIGHT;
197 width_ = chunksHoriz_ * CHUNK_WIDTH;
198 height_ = chunksVert_ * CHUNK_HEIGHT;
199 loaded_ = std::vector<MapData>(width_ * height_);
200
201 // Load in the requested chunks.
202 for (int chunkY = 0; chunkY < chunksVert_; chunkY++) {
203 for (int chunkX = 0; chunkX < chunksHoriz_; chunkX++) {
204 // Instantiate a new chunk if necessary.
205 if (!chunkByPos_[leftmostChunk_ + chunkX].count(topmostChunk_ + chunkY)) {
206 size_t chunkIndex;
207 if (!freeList_.empty()) {
208 chunkIndex = freeList_.front();
209 freeList_.pop_front();
210 } else {
211 chunkIndex = chunks_.size();
212 chunks_.emplace_back();
213 }
214 chunkByPos_[leftmostChunk_ + chunkX][topmostChunk_ + chunkY] = chunkIndex;
215
216 Chunk& chunk = chunks_[chunkIndex];
217 chunk.x = leftmostChunk_ + chunkX;
218 chunk.y = topmostChunk_ + chunkY;
219
220 for (MapData& md : chunk.data)
221 {
222 if (std::bernoulli_distribution(0.5)(rng))
223 {
224 md.tile = Tile::Wall;
225 } else {
226 md.tile = Tile::Floor;
227 }
228 md.dirtyRender = true;
229 }
230 }
231
232 size_t chunkIndex = chunkByPos_[leftmostChunk_ + chunkX][topmostChunk_ + chunkY];
233 Chunk& chunk = chunks_[chunkIndex];
234
235 for (int y = 0; y < CHUNK_HEIGHT; y++) {
236 std::copy(
237 std::next(std::begin(chunk.data), y*CHUNK_WIDTH),
238 std::next(std::begin(chunk.data), (y+1)*CHUNK_WIDTH),
239 std::next(std::begin(loaded_), (chunkY*CHUNK_HEIGHT + y)*width_ + chunkX*CHUNK_WIDTH));
240 }
241 }
242 }
243
115 } 244 }
116 245
117private: 246private:
@@ -120,8 +249,15 @@ private:
120 int top_; 249 int top_;
121 int width_; 250 int width_;
122 int height_; 251 int height_;
252 int leftmostChunk_;
253 int topmostChunk_;
254 int chunksHoriz_;
255 int chunksVert_;
256 std::vector<MapData> loaded_;
123 257
124 std::vector<T> data_; 258 std::vector<Chunk> chunks_;
259 std::list<size_t> freeList_;
260 std::map<int, std::map<int, size_t>> chunkByPos_; // chunkByPos_[X][Y]
125}; 261};
126 262
127#endif /* end of include guard: MAP_H_3AB00D12 */ 263#endif /* end of include guard: MAP_H_3AB00D12 */
diff --git a/src/renderer.cpp b/src/renderer.cpp index 9ef8bb9..1f51e0a 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp
@@ -12,7 +12,7 @@ Renderer::Renderer()
12 GAME_HEIGHT, 12 GAME_HEIGHT,
13 SDL_WINDOW_SHOWN)); 13 SDL_WINDOW_SHOWN));
14 14
15 SDL_SetWindowFullscreen(win_.get(), SDL_WINDOW_FULLSCREEN_DESKTOP); 15 //SDL_SetWindowFullscreen(win_.get(), SDL_WINDOW_FULLSCREEN_DESKTOP);
16 16
17 if (!win_) 17 if (!win_)
18 { 18 {
@@ -115,13 +115,16 @@ void Renderer::renderGame(
115 const Game& game, 115 const Game& game,
116 bool drawDark) 116 bool drawDark)
117{ 117{
118 int windowTileWidth = game.curZoom * ZOOM_X_FACTOR + 2;
119 int windowTileHeight = game.curZoom * ZOOM_Y_FACTOR + 2;
120
118 texture_ptr canvas( 121 texture_ptr canvas(
119 SDL_CreateTexture( 122 SDL_CreateTexture(
120 ren_.get(), 123 ren_.get(),
121 SDL_PIXELFORMAT_RGBA8888, 124 SDL_PIXELFORMAT_RGBA8888,
122 SDL_TEXTUREACCESS_TARGET, 125 SDL_TEXTUREACCESS_TARGET,
123 TILE_WIDTH * game.map.getWidth(), 126 windowTileWidth * TILE_WIDTH,
124 TILE_HEIGHT * game.map.getHeight())); 127 windowTileHeight * TILE_HEIGHT));
125 128
126 if (!canvas) 129 if (!canvas)
127 { 130 {
@@ -133,15 +136,17 @@ void Renderer::renderGame(
133 SDL_SetRenderDrawColor(ren_.get(), rand() % 255, rand() % 255, rand() % 255, 255); 136 SDL_SetRenderDrawColor(ren_.get(), rand() % 255, rand() % 255, rand() % 255, 255);
134 SDL_RenderClear(ren_.get()); 137 SDL_RenderClear(ren_.get());
135 138
136 for (int y = game.map.getTop(); y < game.map.getBottom(); y++) 139 int leftmost = game.player_x - game.curZoom * ZOOM_X_FACTOR / 2 - 1;
140 int topmost = game.player_y - game.curZoom * ZOOM_Y_FACTOR / 2 - 1;
141 for (int y = topmost; y < topmost + windowTileHeight; y++)
137 { 142 {
138 for (int x = game.map.getLeft(); x < game.map.getRight(); x++) 143 for (int x = leftmost; x < leftmost + windowTileWidth; x++)
139 { 144 {
140 bool draw = true; 145 bool draw = true;
141 bool drawColour = false; 146 bool drawColour = false;
142 SDL_Rect rect { 147 SDL_Rect rect {
143 game.map.getTrueX(x) * TILE_WIDTH, 148 (x - leftmost) * TILE_WIDTH,
144 game.map.getTrueY(y) * TILE_HEIGHT, 149 (y - topmost) * TILE_HEIGHT,
145 TILE_WIDTH, 150 TILE_WIDTH,
146 TILE_HEIGHT}; 151 TILE_HEIGHT};
147 152
@@ -190,14 +195,14 @@ void Renderer::renderGame(
190 195
191 if (game.renderPlayer) { 196 if (game.renderPlayer) {
192 SDL_Rect rect { 197 SDL_Rect rect {
193 game.map.getTrueX(game.player_x) * TILE_WIDTH, 198 (game.player_x - leftmost) * TILE_WIDTH,
194 game.map.getTrueY(game.player_y) * TILE_HEIGHT, 199 (game.player_y - topmost) * TILE_HEIGHT,
195 TILE_WIDTH, 200 TILE_WIDTH,
196 TILE_HEIGHT}; 201 TILE_HEIGHT};
197 202
198 if (game.moving) { 203 if (game.moving) {
199 rect.x = game.moveProgress.getProgress(game.map.getTrueX(game.player_oldx) * TILE_WIDTH, rect.x); 204 rect.x = game.moveProgress.getProgress((game.player_oldx - leftmost) * TILE_WIDTH, rect.x);
200 rect.y = game.moveProgress.getProgress(game.map.getTrueY(game.player_oldy) * TILE_HEIGHT, rect.y); 205 rect.y = game.moveProgress.getProgress((game.player_oldy - topmost) * TILE_HEIGHT, rect.y);
201 } 206 }
202 207
203 SDL_RenderCopy(ren_.get(), playerSheet_.get(), &game.playerAnim.getRenderRect(), &rect); 208 SDL_RenderCopy(ren_.get(), playerSheet_.get(), &game.playerAnim.getRenderRect(), &rect);
@@ -208,8 +213,8 @@ void Renderer::renderGame(
208 ren_.get(), 213 ren_.get(),
209 SDL_PIXELFORMAT_RGBA8888, 214 SDL_PIXELFORMAT_RGBA8888,
210 SDL_TEXTUREACCESS_TARGET, 215 SDL_TEXTUREACCESS_TARGET,
211 TILE_WIDTH * game.map.getWidth(), 216 windowTileWidth * TILE_WIDTH,
212 TILE_HEIGHT * game.map.getHeight())); 217 windowTileHeight * TILE_HEIGHT));
213 218
214 if (!mask) 219 if (!mask)
215 { 220 {
@@ -220,9 +225,9 @@ void Renderer::renderGame(
220 SDL_SetRenderDrawColor(ren_.get(), 0, 0, 0, 0); 225 SDL_SetRenderDrawColor(ren_.get(), 0, 0, 0, 0);
221 SDL_RenderClear(ren_.get()); 226 SDL_RenderClear(ren_.get());
222 227
223 for (int y = game.map.getTop(); y < game.map.getBottom(); y++) 228 for (int y = topmost; y < topmost + windowTileHeight; y++)
224 { 229 {
225 for (int x = game.map.getLeft(); x < game.map.getRight(); x++) 230 for (int x = leftmost; x < leftmost + windowTileWidth; x++)
226 { 231 {
227 if (game.map.at(x,y).lightType != Source::None) 232 if (game.map.at(x,y).lightType != Source::None)
228 { 233 {
@@ -231,8 +236,8 @@ void Renderer::renderGame(
231 ren_.get(), 236 ren_.get(),
232 SDL_PIXELFORMAT_RGBA8888, 237 SDL_PIXELFORMAT_RGBA8888,
233 SDL_TEXTUREACCESS_TARGET, 238 SDL_TEXTUREACCESS_TARGET,
234 TILE_WIDTH * game.map.getWidth(), 239 windowTileWidth * TILE_WIDTH,
235 TILE_HEIGHT * game.map.getHeight())); 240 windowTileHeight * TILE_HEIGHT));
236 241
237 if (!sourceMask) 242 if (!sourceMask)
238 { 243 {
@@ -244,11 +249,11 @@ void Renderer::renderGame(
244 SDL_SetRenderDrawColor(ren_.get(), 0, 0, 0, 0); 249 SDL_SetRenderDrawColor(ren_.get(), 0, 0, 0, 0);
245 SDL_RenderClear(ren_.get()); 250 SDL_RenderClear(ren_.get());
246 251
247 int posToUseX = game.map.getTrueX(x); 252 int posToUseX = x - leftmost;
248 int posToUseY = game.map.getTrueY(y); 253 int posToUseY = y - topmost;
249 if (game.map.at(x,y).lightType == Source::Player && game.moving) { 254 if (game.map.at(x,y).lightType == Source::Player && game.moving) {
250 posToUseX = game.moveProgress.getProgress(game.map.getTrueX(game.player_oldx), posToUseX); 255 posToUseX = game.moveProgress.getProgress((game.player_oldx) - leftmost, posToUseX);
251 posToUseY = game.moveProgress.getProgress(game.map.getTrueY(game.player_oldy), posToUseY); 256 posToUseY = game.moveProgress.getProgress((game.player_oldy) - topmost, posToUseY);
252 } 257 }
253 258
254 int fadeX = posToUseX - game.map.at(x,y).lightRadius; 259 int fadeX = posToUseX - game.map.at(x,y).lightRadius;
@@ -283,8 +288,8 @@ void Renderer::renderGame(
283 if (!game.map.at(x,y).litTiles.count({sx, sy})) 288 if (!game.map.at(x,y).litTiles.count({sx, sy}))
284 { 289 {
285 SDL_Rect rect { 290 SDL_Rect rect {
286 game.map.getTrueX(sx) * TILE_WIDTH, 291 (sx - leftmost) * TILE_WIDTH,
287 game.map.getTrueY(sy) * TILE_HEIGHT, 292 (sy - topmost) * TILE_HEIGHT,
288 TILE_WIDTH, 293 TILE_WIDTH,
289 TILE_HEIGHT}; 294 TILE_HEIGHT};
290 295
@@ -306,10 +311,28 @@ void Renderer::renderGame(
306 311
307 SDL_SetRenderTarget(ren_.get(), nullptr); 312 SDL_SetRenderTarget(ren_.get(), nullptr);
308 313
309 SDL_Rect zoomRect; 314 // TODO: this is just moving interp. we also need zoom
315 SDL_Rect zoomRect {
316 TILE_WIDTH, TILE_HEIGHT, (windowTileWidth - 2) * TILE_WIDTH, (windowTileHeight - 2) * TILE_HEIGHT
317 };
318
319 if (game.moving) {
320 double interp =
321 static_cast<double>(game.zoomProgress) /
322 static_cast<double>(game.zoomLength);
323
324 if (game.player_x > game.player_oldx) {
325 zoomRect.x = game.moveProgress.getProgress(0, TILE_WIDTH);
326 } else if (game.player_x < game.player_oldx) {
327 zoomRect.x = game.moveProgress.getProgress(2*TILE_WIDTH, TILE_WIDTH);
328 }
310 329
311 std::tie(zoomRect.x, zoomRect.y, zoomRect.w, zoomRect.h) = 330 if (game.player_y > game.player_oldy) {
312 calculateZoomRect(game); 331 zoomRect.y = game.moveProgress.getProgress(0, TILE_HEIGHT);
332 } else if (game.player_y < game.player_oldy) {
333 zoomRect.y = game.moveProgress.getProgress(TILE_HEIGHT*2, TILE_HEIGHT);
334 }
335 }
313 336
314 SDL_RenderCopy(ren_.get(), canvas.get(), &zoomRect, nullptr); 337 SDL_RenderCopy(ren_.get(), canvas.get(), &zoomRect, nullptr);
315 SDL_RenderPresent(ren_.get()); 338 SDL_RenderPresent(ren_.get());
@@ -358,12 +381,12 @@ void Renderer::renderTitle(int num, double fade) {
358 381
359std::tuple<int, int, int, int> Renderer::calculateZoomRect(const Game& game) 382std::tuple<int, int, int, int> Renderer::calculateZoomRect(const Game& game)
360{ 383{
361 int x = game.map.getTrueX(game.curBoundX) * TILE_WIDTH;
362 int y = game.map.getTrueY(game.curBoundY) * TILE_HEIGHT;
363 int w = game.curZoom * TILE_WIDTH * ZOOM_X_FACTOR; 384 int w = game.curZoom * TILE_WIDTH * ZOOM_X_FACTOR;
364 int h = game.curZoom * TILE_HEIGHT * ZOOM_Y_FACTOR; 385 int h = game.curZoom * TILE_HEIGHT * ZOOM_Y_FACTOR;
386 int x = (game.map.getTrueX(game.player_x) * TILE_WIDTH) - (w / 2);
387 int y = (game.map.getTrueY(game.player_y) * TILE_HEIGHT) - (h / 2);
365 388
366 if (game.zooming) 389 /*if (game.zooming)
367 { 390 {
368 double interp = 391 double interp =
369 static_cast<double>(game.zoomProgress) / 392 static_cast<double>(game.zoomProgress) /
@@ -373,7 +396,7 @@ std::tuple<int, int, int, int> Renderer::calculateZoomRect(const Game& game)
373 y = (y - game.lastZoomTop) * interp + game.lastZoomTop; 396 y = (y - game.lastZoomTop) * interp + game.lastZoomTop;
374 w = (w - game.lastZoomWidth) * interp + game.lastZoomWidth; 397 w = (w - game.lastZoomWidth) * interp + game.lastZoomWidth;
375 h = (h - game.lastZoomHeight) * interp + game.lastZoomHeight; 398 h = (h - game.lastZoomHeight) * interp + game.lastZoomHeight;
376 } 399 }*/
377 400
378 return {x, y, w, h}; 401 return {x, y, w, h};
379} 402}