summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--.clang-format2
-rw-r--r--gamestate.cpp933
-rw-r--r--gamestate.h5
-rw-r--r--highscore.cpp27
-rw-r--r--highscore.h20
-rw-r--r--hslist.cpp1814
-rw-r--r--hslist.h141
-rw-r--r--mazeoflife.cpp100
-rw-r--r--state.h9
-rw-r--r--titlestate.cpp216
-rw-r--r--titlestate.h13
-rw-r--r--util.cpp89
-rw-r--r--util.h1
13 files changed, 1603 insertions, 1767 deletions
diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..8de7fe6 --- /dev/null +++ b/.clang-format
@@ -0,0 +1,2 @@
1---
2 BasedOnStyle: Google
diff --git a/gamestate.cpp b/gamestate.cpp index 8c2df9c..e77ff76 100644 --- a/gamestate.cpp +++ b/gamestate.cpp
@@ -1,378 +1,363 @@
1#include "gamestate.h" 1#include "gamestate.h"
2
2#include <SDL_ttf.h> 3#include <SDL_ttf.h>
3#include "util.h" 4
4#include "mazeoflife.h"
5#include "highscore.h"
6#include "titlestate.h"
7#include <fstream>
8#include "hslist.h"
9#include <set>
10#include <bitset>
11#include <tuple>
12#include <algorithm> 5#include <algorithm>
13#include <vector> 6#include <bitset>
14#include <deque> 7#include <deque>
8#include <fstream>
15#include <iostream> 9#include <iostream>
16#include <sstream>
17#include <list> 10#include <list>
11#include <set>
12#include <sstream>
13#include <tuple>
18#include <unordered_map> 14#include <unordered_map>
19#include <unordered_set> 15#include <unordered_set>
16#include <vector>
17
18#include "highscore.h"
19#include "hslist.h"
20#include "mazeoflife.h"
21#include "titlestate.h"
22#include "util.h"
20 23
21class GameBoard { 24class GameBoard {
22 public: 25 public:
23 GameBoard(int level, int playerx, int playery); 26 GameBoard(int level, int playerx, int playery);
24 void tick(int playerx, int playery); 27 void tick(int playerx, int playery);
25 void render(SDL_Renderer* renderer, int level) const; 28 void render(SDL_Renderer* renderer, int level) const;
26 bool isObstructed(int x, int y) const; 29 bool isObstructed(int x, int y) const;
27 bool operator<(const GameBoard& other) const; 30 bool operator<(const GameBoard& other) const;
28 31
29 using coord = std::tuple<int, int>; 32 using coord = std::tuple<int, int>;
30 33
31 private: 34 private:
32 void initialize(int level); 35 void initialize(int level);
33 bool solve(int playerx, int playery) const; 36 bool solve(int playerx, int playery) const;
34 std::string dump() const; 37 std::string dump() const;
35 38
36 using board_type = std::bitset<WIDTH*HEIGHT>; 39 using board_type = std::bitset<WIDTH * HEIGHT>;
37 40
38 void incrementIfNeighbor( 41 void incrementIfNeighbor(int x, int y, const board_type& temp, int playerx,
39 int x, 42 int playery, int& tick) const;
40 int y, 43
41 const board_type& temp, 44 bool applyNeighbors(int x, int y, const board_type& temp, int playerx,
42 int playerx, 45 int playery) const;
43 int playery, 46
44 int& tick) const; 47 board_type blocks;
45 48 board_type updateable;
46 bool applyNeighbors( 49 int oldx;
47 int x, 50 int oldy;
48 int y,
49 const board_type& temp,
50 int playerx,
51 int playery) const;
52
53 board_type blocks;
54 board_type updateable;
55 int oldx;
56 int oldy;
57}; 51};
58 52
59class LoadGameState : public State { 53class LoadGameState : public State {
60 public: 54 public:
61 LoadGameState(int level); 55 LoadGameState(int level);
62 State* operator() (SDL_Window* window, SDL_Renderer* renderer); 56 State* operator()(SDL_Window* window, SDL_Renderer* renderer);
63 57
64 private: 58 private:
65 int level; 59 int level;
66}; 60};
67 61
68class PlayGameState : public State { 62class PlayGameState : public State {
69 public: 63 public:
70 PlayGameState(int level, GameBoard* board, int playerx, int playery); 64 PlayGameState(int level, GameBoard* board, int playerx, int playery);
71 State* operator() (SDL_Window* window, SDL_Renderer* renderer); 65 State* operator()(SDL_Window* window, SDL_Renderer* renderer);
72 66
73 private: 67 private:
74 bool move(int x, int y); 68 bool move(int x, int y);
75 int level; 69 int level;
76 GameBoard* board; 70 GameBoard* board;
77 int playerx; 71 int playerx;
78 int playery; 72 int playery;
79}; 73};
80 74
81void setRendererAliveColor(SDL_Renderer* renderer, int level) 75void setRendererAliveColor(SDL_Renderer* renderer, int level) {
82{ 76 switch ((level / 10) % 5) {
83 switch ((level/10)%5) 77 case 0:
84 { 78 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
85 case 0: SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); break; // Black 79 break; // Black
86 case 1: SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); break; // Red 80 case 1:
87 case 2: SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255); break; // Green 81 SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
88 case 3: SDL_SetRenderDrawColor(renderer, 85, 85, 85, 255); break; // Dark Gray 82 break; // Red
89 case 4: SDL_SetRenderDrawColor(renderer, 255, 0, 255, 255); break; // Magenta 83 case 2:
90 } 84 SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
85 break; // Green
86 case 3:
87 SDL_SetRenderDrawColor(renderer, 85, 85, 85, 255);
88 break; // Dark Gray
89 case 4:
90 SDL_SetRenderDrawColor(renderer, 255, 0, 255, 255);
91 break; // Magenta
92 }
91} 93}
92 94
93void setRendererDeadColor(SDL_Renderer* renderer, int level) 95void setRendererDeadColor(SDL_Renderer* renderer, int level) {
94{ 96 switch ((level / 10) % 5) {
95 switch ((level/10)%5) 97 case 0:
96 { 98 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
97 case 0: SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); break; // White 99 break; // White
98 case 1: SDL_SetRenderDrawColor(renderer, 255, 192, 203, 255); break; // Pink 100 case 1:
99 case 2: SDL_SetRenderDrawColor(renderer, 0, 255, 255, 255); break; // Cyan 101 SDL_SetRenderDrawColor(renderer, 255, 192, 203, 255);
100 case 3: SDL_SetRenderDrawColor(renderer, 170, 170, 170, 255); break; // Light Gray 102 break; // Pink
101 case 4: SDL_SetRenderDrawColor(renderer, 255, 128, 0, 255); break; // Orange 103 case 2:
102 } 104 SDL_SetRenderDrawColor(renderer, 0, 255, 255, 255);
105 break; // Cyan
106 case 3:
107 SDL_SetRenderDrawColor(renderer, 170, 170, 170, 255);
108 break; // Light Gray
109 case 4:
110 SDL_SetRenderDrawColor(renderer, 255, 128, 0, 255);
111 break; // Orange
112 }
103} 113}
104 114
105void GameBoard::incrementIfNeighbor( 115void GameBoard::incrementIfNeighbor(int x, int y, const board_type& temp,
106 int x, 116 int playerx, int playery, int& tick) const {
107 int y, 117 int nx = x;
108 const board_type& temp, 118 int ny = y;
109 int playerx, 119
110 int playery, 120 wrap(x, y);
111 int& tick) const
112{
113 int nx = x;
114 int ny = y;
115
116 wrap(x, y);
117
118 if (!((nx!=x)&&(ny!=y)))
119 {
120 if ((temp[x+y*WIDTH])||((playerx==x)&&(playery==y))||((x==15)&&(y==15)))
121 {
122 ++tick;
123 }
124 }
125}
126 121
127State* GameState::operator() (SDL_Window* window, SDL_Renderer* renderer) 122 if (!((nx != x) && (ny != y))) {
128{ 123 if ((temp[x + y * WIDTH]) || ((playerx == x) && (playery == y)) ||
129 return new LoadGameState(0); 124 ((x == 15) && (y == 15))) {
125 ++tick;
126 }
127 }
130} 128}
131 129
132LoadGameState::LoadGameState(int m_level) 130State* GameState::operator()(SDL_Window* window, SDL_Renderer* renderer) {
133{ 131 return new LoadGameState(0);
134 level = m_level;
135} 132}
136 133
137State* LoadGameState::operator() (SDL_Window* window, SDL_Renderer* renderer) 134LoadGameState::LoadGameState(int m_level) { level = m_level; }
138{ 135
139 char* wintitle = new char[50]; 136State* LoadGameState::operator()(SDL_Window* window, SDL_Renderer* renderer) {
140 sprintf(wintitle, "Maze Of Life - Level %d", level); 137 char* wintitle = new char[50];
141 SDL_SetWindowTitle(window, wintitle); 138 sprintf(wintitle, "Maze Of Life - Level %d", level);
142 139 SDL_SetWindowTitle(window, wintitle);
143 // Randomly place the player in a corner 140
144 int playerx, playery; 141 // Randomly place the player in a corner
145 switch (rand()%4) 142 int playerx, playery;
146 { 143 switch (rand() % 4) {
147 case 0: playerx = 1; playery = 1; break; 144 case 0:
148 case 1: playerx = 1; playery = HEIGHT-2; break; 145 playerx = 1;
149 case 2: playerx = WIDTH-2; playery = HEIGHT-2; break; 146 playery = 1;
150 case 3: playerx = WIDTH-2; playery = 1; break; 147 break;
151 } 148 case 1:
152 149 playerx = 1;
153 // Display the level number 150 playery = HEIGHT - 2;
154 setRendererDeadColor(renderer, level); 151 break;
155 SDL_RenderClear(renderer); 152 case 2:
156 153 playerx = WIDTH - 2;
157 TTF_Font* font = loadFont(100); 154 playery = HEIGHT - 2;
158 SDL_Color fontColor = {0, 0, 0, 0}; 155 break;
159 char levelnum[8]; 156 case 3:
160 sprintf(levelnum, "%d", level); 157 playerx = WIDTH - 2;
161 SDL_Surface* dispsurf = TTF_RenderText_Solid(font, levelnum, fontColor); 158 playery = 1;
162 SDL_Texture* disptext = SDL_CreateTextureFromSurface(renderer, dispsurf); 159 break;
163 SDL_FreeSurface(dispsurf); 160 }
164 161
165 SDL_Rect pos; 162 // Display the level number
166 SDL_QueryTexture(disptext, NULL, NULL, &pos.w, &pos.h); 163 setRendererDeadColor(renderer, level);
167 pos.x = 240-(pos.w/2); 164 SDL_RenderClear(renderer);
168 pos.y = 240-(pos.h/2); 165
169 166 TTF_Font* font = loadFont(100);
170 SDL_RenderCopy(renderer, disptext, NULL, &pos); 167 SDL_Color fontColor = {0, 0, 0, 0};
171 SDL_RenderPresent(renderer); 168 char levelnum[8];
172 169 sprintf(levelnum, "%d", level);
173 // Do 50 gens of Conway 170 SDL_Surface* dispsurf = TTF_RenderText_Solid(font, levelnum, fontColor);
174 GameBoard* board = new GameBoard(level, playerx, playery); 171 SDL_Texture* disptext = SDL_CreateTextureFromSurface(renderer, dispsurf);
175 172 SDL_FreeSurface(dispsurf);
176 // Wait a bit 173
177 SDL_Delay(500); 174 SDL_Rect pos;
178 175 SDL_QueryTexture(disptext, NULL, NULL, &pos.w, &pos.h);
179 // Start the level 176 pos.x = 240 - (pos.w / 2);
180 return new PlayGameState(level, board, playerx, playery); 177 pos.y = 240 - (pos.h / 2);
178
179 SDL_RenderCopy(renderer, disptext, NULL, &pos);
180 SDL_RenderPresent(renderer);
181
182 // Do 50 gens of Conway
183 GameBoard* board = new GameBoard(level, playerx, playery);
184
185 // Wait a bit
186 SDL_Delay(500);
187
188 // Start the level
189 return new PlayGameState(level, board, playerx, playery);
181} 190}
182 191
183PlayGameState::PlayGameState(int m_level, GameBoard* m_board, int m_playerx, int m_playery) 192PlayGameState::PlayGameState(int m_level, GameBoard* m_board, int m_playerx,
184{ 193 int m_playery) {
185 level = m_level; 194 level = m_level;
186 board = m_board; 195 board = m_board;
187 playerx = m_playerx; 196 playerx = m_playerx;
188 playery = m_playery; 197 playery = m_playery;
189} 198}
190 199
191State* PlayGameState::operator() (SDL_Window* window, SDL_Renderer* renderer) 200State* PlayGameState::operator()(SDL_Window* window, SDL_Renderer* renderer) {
192{ 201 SDL_Event e;
193 SDL_Event e; 202
194 203 for (;;) {
195 for (;;) 204 // Tick board
196 { 205 board->tick(playerx, playery);
197 // Tick board 206
198 board->tick(playerx, playery); 207 // Paint board
199 208 board->render(renderer, level);
200 // Paint board 209
201 board->render(renderer, level); 210 // Paint event
202 211 SDL_Rect block;
203 // Paint event 212 block.w = 16;
204 SDL_Rect block; 213 block.h = 16;
205 block.w = 16; 214 block.x = 15 * 16;
206 block.h = 16; 215 block.y = 15 * 16;
207 block.x = 15*16; 216 SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
208 block.y = 15*16; 217 SDL_RenderFillRect(renderer, &block);
209 SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255); 218
210 SDL_RenderFillRect(renderer, &block); 219 // Paint player
211 220 block.x = playerx * 16;
212 // Paint player 221 block.y = playery * 16;
213 block.x = playerx*16; 222 SDL_SetRenderDrawColor(renderer, 255, 255, 0, 255);
214 block.y = playery*16; 223 SDL_RenderFillRect(renderer, &block);
215 SDL_SetRenderDrawColor(renderer, 255, 255, 0, 255); 224
216 SDL_RenderFillRect(renderer, &block); 225 SDL_RenderPresent(renderer);
217 226
218 SDL_RenderPresent(renderer); 227 while (SDL_PollEvent(&e)) {
219 228 if (e.type == SDL_QUIT) {
220 while (SDL_PollEvent(&e)) 229 return NULL;
221 { 230 } else if (e.type == SDL_KEYDOWN) {
222 if (e.type == SDL_QUIT) 231 switch (e.key.keysym.sym) {
223 { 232 case SDLK_LEFT:
224 return NULL; 233 if (move(playerx - 1, playery)) {
225 } else if (e.type == SDL_KEYDOWN) 234 return new LoadGameState(level + 1);
226 { 235 } else {
227 switch (e.key.keysym.sym) 236 break;
228 { 237 }
229 case SDLK_LEFT: 238
230 if (move(playerx-1, playery)) 239 case SDLK_RIGHT:
231 { 240 if (move(playerx + 1, playery)) {
232 return new LoadGameState(level+1); 241 return new LoadGameState(level + 1);
233 } else { 242 } else {
234 break; 243 break;
235 } 244 }
236 245
237 case SDLK_RIGHT: 246 case SDLK_UP:
238 if (move(playerx+1, playery)) 247 if (move(playerx, playery - 1)) {
239 { 248 return new LoadGameState(level + 1);
240 return new LoadGameState(level+1); 249 } else {
241 } else { 250 break;
242 break; 251 }
243 } 252
244 253 case SDLK_DOWN:
245 case SDLK_UP: 254 if (move(playerx, playery + 1)) {
246 if (move(playerx, playery-1)) 255 return new LoadGameState(level + 1);
247 { 256 } else {
248 return new LoadGameState(level+1); 257 break;
249 } else { 258 }
250 break; 259
251 } 260 case SDLK_ESCAPE:
252 261 SDL_SetWindowTitle(window, "");
253 case SDLK_DOWN: 262
254 if (move(playerx, playery+1)) 263 std::ifstream exists(getDataFile());
255 { 264 if (exists) {
256 return new LoadGameState(level+1); 265 FILE* hslist = fopen(getDataFile(), "r");
257 } else { 266 int scores;
258 break; 267 Highscore* h;
259 } 268
260 269 fscanf(hslist, "%d%*c", &scores);
261 case SDLK_ESCAPE: 270
262 SDL_SetWindowTitle(window, ""); 271 if (scores < 10) {
263 272 fclose(hslist);
264 std::ifstream exists(getDataFile()); 273
265 if (exists) 274 return new EnterHighscoreState(level);
266 { 275 } else {
267 FILE* hslist = fopen(getDataFile(), "r"); 276 for (int i = 0; i < scores; i++) {
268 int scores; 277 int namelen;
269 Highscore* h; 278 char namelens[4];
270 279 char* name = (char*)calloc(25, sizeof(char));
271 fscanf(hslist, "%d%*c", &scores); 280 int score;
272 281
273 if (scores < 10) 282 fscanf(hslist, "%d", &namelen);
274 { 283 sprintf(namelens, "%%%dc", namelen);
275 fclose(hslist); 284 fscanf(hslist, namelens, name);
276 285 fscanf(hslist, "%d%*c", &score);
277 return new EnterHighscoreState(level); 286
278 } else { 287 h = new Highscore(name, score);
279 for (int i=0; i<scores; i++) 288 }
280 { 289
281 int namelen; 290 fclose(hslist);
282 char namelens[4]; 291
283 char* name = (char*) calloc(25, sizeof(char)); 292 if (h->getLevel() < level) {
284 int score; 293 return new EnterHighscoreState(level);
285 294 } else {
286 fscanf(hslist, "%d", &namelen); 295 return new DisplayAndReturnLocalHighscoreListState();
287 sprintf(namelens, "%%%dc", namelen); 296 }
288 fscanf(hslist, namelens, name); 297 }
289 fscanf(hslist, "%d%*c", &score); 298 } else {
290 299 return new EnterHighscoreState(level);
291 h = new Highscore(name, score); 300 }
292 } 301 }
293 302 }
294 fclose(hslist); 303 }
295 304
296 if (h->getLevel() < level) 305 SDL_Delay(5);
297 { 306 }
298 return new EnterHighscoreState(level);
299 } else {
300 return new DisplayAndReturnLocalHighscoreListState();
301 }
302 }
303 } else {
304 return new EnterHighscoreState(level);
305 }
306 }
307 }
308 }
309
310 SDL_Delay(5);
311 }
312} 307}
313 308
314bool PlayGameState::move(int x, int y) 309bool PlayGameState::move(int x, int y) {
315{ 310 wrap(x, y);
316 wrap(x, y);
317 311
318 // Are we at the event? 312 // Are we at the event?
319 if ((x==15)&&(y==15)) 313 if ((x == 15) && (y == 15)) {
320 { 314 return true;
321 return true; 315 }
322 }
323 316
324 // Can we even go there? 317 // Can we even go there?
325 if (!board->isObstructed(x,y)) 318 if (!board->isObstructed(x, y)) {
326 { 319 playerx = x;
327 playerx = x; 320 playery = y;
328 playery = y; 321 }
329 }
330 322
331 return false; 323 return false;
332} 324}
333 325
334GameBoard::GameBoard(int level, int playerx, int playery) 326GameBoard::GameBoard(int level, int playerx, int playery) {
335{ 327 for (;;) {
336 for (;;)
337 {
338 initialize(level); 328 initialize(level);
339 updateable.set(); 329 updateable.set();
340 oldx = playerx; 330 oldx = playerx;
341 oldy = playery; 331 oldy = playery;
342 332
343 for (int i=0; i<50; i++) 333 for (int i = 0; i < 50; i++) {
344 {
345 tick(playerx, playery); 334 tick(playerx, playery);
346 } 335 }
347 336
348 if (solve(playerx, playery)) 337 if (solve(playerx, playery)) {
349 {
350 break; 338 break;
351 } else { 339 } else {
352 std::cout << "Impossible board: " << playerx << "," << playery << "," << dump() << std::endl; 340 std::cout << "Impossible board: " << playerx << "," << playery << ","
341 << dump() << std::endl;
353 } 342 }
354 } 343 }
355} 344}
356 345
357void GameBoard::tick(int playerx, int playery) 346void GameBoard::tick(int playerx, int playery) {
358{ 347 board_type temp{blocks};
359 board_type temp {blocks}; 348 board_type tempdateable{updateable};
360 board_type tempdateable {updateable}; 349 if ((playerx != oldx) || (playery != oldy)) {
361 if ((playerx != oldx) || (playery != oldy)) 350 for (int dy = -1; dy <= 1; dy++) {
362 { 351 for (int dx = -1; dx <= 1; dx++) {
363 for (int dy = -1; dy <= 1; dy++) 352 int tdx = oldx + dx;
364 { 353 int tdy = oldy + dy;
365 for (int dx = -1; dx <=1; dx++)
366 {
367 int tdx = oldx+dx;
368 int tdy = oldy+dy;
369 wrap(tdx, tdy); 354 wrap(tdx, tdy);
370 tempdateable.set(tdx+tdy*WIDTH); 355 tempdateable.set(tdx + tdy * WIDTH);
371 356
372 tdx = playerx+dx; 357 tdx = playerx + dx;
373 tdy = playery+dy; 358 tdy = playery + dy;
374 wrap(tdx, tdy); 359 wrap(tdx, tdy);
375 tempdateable.set(tdx+tdy*WIDTH); 360 tempdateable.set(tdx + tdy * WIDTH);
376 } 361 }
377 } 362 }
378 } 363 }
@@ -382,135 +367,108 @@ void GameBoard::tick(int playerx, int playery)
382 367
383 updateable.reset(); 368 updateable.reset();
384 369
385 for (int y=0;y<HEIGHT;y++) 370 for (int y = 0; y < HEIGHT; y++) {
386 { 371 for (int x = 0; x < WIDTH; x++) {
387 for (int x=0;x<WIDTH;x++) 372 if (((x == 15) && (y == 15)) || (!tempdateable[x + y * WIDTH])) {
388 { 373 continue;
389 if (((x==15)&&(y==15)) || (!tempdateable[x+y*WIDTH])) 374 }
390 { 375
391 continue; 376 blocks[x + y * WIDTH] = applyNeighbors(x, y, temp, playerx, playery);
392 } 377
393 378 if (temp[x + y * WIDTH] != blocks[x + y * WIDTH]) {
394 blocks[x+y*WIDTH] = applyNeighbors(x, y, temp, playerx, playery); 379 for (int dy = -1; dy <= 1; dy++) {
395 380 for (int dx = -1; dx <= 1; dx++) {
396 if (temp[x+y*WIDTH] != blocks[x+y*WIDTH]) 381 int tdx = x + dx;
397 { 382 int tdy = y + dy;
398 for (int dy = -1; dy <= 1; dy++)
399 {
400 for (int dx = -1; dx <=1; dx++)
401 {
402 int tdx = x+dx;
403 int tdy = y+dy;
404 wrap(tdx, tdy); 383 wrap(tdx, tdy);
405 updateable.set(tdx+tdy*WIDTH); 384 updateable.set(tdx + tdy * WIDTH);
406 } 385 }
407 } 386 }
408 } 387 }
409 } 388 }
410 } 389 }
411} 390}
412 391
413bool GameBoard::applyNeighbors( 392bool GameBoard::applyNeighbors(int x, int y, const board_type& temp,
414 int x, 393 int playerx, int playery) const {
415 int y, 394 int neighbors = 0;
416 const board_type& temp, 395
417 int playerx, 396 incrementIfNeighbor(x - 1, y - 1, temp, playerx, playery, neighbors);
418 int playery) const 397 incrementIfNeighbor(x - 1, y, temp, playerx, playery, neighbors);
419{ 398 incrementIfNeighbor(x - 1, y + 1, temp, playerx, playery, neighbors);
420 int neighbors = 0; 399 incrementIfNeighbor(x, y - 1, temp, playerx, playery, neighbors);
421 400 incrementIfNeighbor(x, y + 1, temp, playerx, playery, neighbors);
422 incrementIfNeighbor(x-1, y-1, temp, playerx, playery, neighbors); 401 incrementIfNeighbor(x + 1, y - 1, temp, playerx, playery, neighbors);
423 incrementIfNeighbor(x-1, y , temp, playerx, playery, neighbors); 402 incrementIfNeighbor(x + 1, y, temp, playerx, playery, neighbors);
424 incrementIfNeighbor(x-1, y+1, temp, playerx, playery, neighbors); 403 incrementIfNeighbor(x + 1, y + 1, temp, playerx, playery, neighbors);
425 incrementIfNeighbor(x , y-1, temp, playerx, playery, neighbors); 404
426 incrementIfNeighbor(x , y+1, temp, playerx, playery, neighbors); 405 if (temp[x + y * WIDTH]) {
427 incrementIfNeighbor(x+1, y-1, temp, playerx, playery, neighbors); 406 return ((neighbors >= 1) && (neighbors <= 4));
428 incrementIfNeighbor(x+1, y , temp, playerx, playery, neighbors); 407 } else {
429 incrementIfNeighbor(x+1, y+1, temp, playerx, playery, neighbors); 408 return (neighbors == 3);
430 409 }
431 if (temp[x+y*WIDTH])
432 {
433 return ((neighbors >= 1) && (neighbors <= 4));
434 } else {
435 return (neighbors == 3);
436 }
437} 410}
438 411
439void GameBoard::render(SDL_Renderer* renderer, int level) const 412void GameBoard::render(SDL_Renderer* renderer, int level) const {
440{ 413 SDL_Rect block;
441 SDL_Rect block; 414 block.w = 16;
442 block.w = 16; 415 block.h = 16;
443 block.h = 16; 416
444 417 for (int y = 0; y < HEIGHT; y++) {
445 for (int y=0; y<HEIGHT; y++) 418 for (int x = 0; x < WIDTH; x++) {
446 { 419 block.x = x * 16;
447 for (int x=0; x<WIDTH; x++) 420 block.y = y * 16;
448 { 421
449 block.x = x*16; 422 if (blocks[x + y * WIDTH]) {
450 block.y = y*16; 423 setRendererAliveColor(renderer, level);
451 424 } else {
452 if (blocks[x+y*WIDTH]) 425 setRendererDeadColor(renderer, level);
453 { 426 }
454 setRendererAliveColor(renderer, level); 427
455 } else { 428 SDL_RenderFillRect(renderer, &block);
456 setRendererDeadColor(renderer, level); 429 }
457 } 430 }
458
459 SDL_RenderFillRect(renderer, &block);
460 }
461 }
462} 431}
463 432
464bool GameBoard::isObstructed(int x, int y) const 433bool GameBoard::isObstructed(int x, int y) const {
465{ 434 return blocks[x + y * WIDTH] || (x == 15 && y == 15);
466 return blocks[x+y*WIDTH] || (x == 15 && y == 15);
467} 435}
468 436
469void GameBoard::initialize(int level) 437void GameBoard::initialize(int level) {
470{ 438 for (int y = 0; y < HEIGHT; y++) {
471 for (int y=0; y<HEIGHT; y++) 439 for (int x = 0; x < WIDTH; x++) {
472 { 440 blocks[x + y * WIDTH] = false;
473 for (int x=0; x<WIDTH; x++) 441
474 { 442 switch (level / 10 + 1) {
475 blocks[x+y*WIDTH] = false; 443 case 1:
476 444 if ((x > 13) && (x < 17) && (y > 13) && (y < 17)) {
477 switch (level/10+1) 445 blocks[x + y * WIDTH] = rand() % 2;
478 { 446 }
479 case 1: 447 break;
480 if ((x>13)&&(x<17)&&(y>13)&&(y<17)) 448 case 2:
481 { 449 case 3:
482 blocks[x+y*WIDTH] = rand() % 2; 450 if ((x > 12) && (x < 18) && (y > 12) && (y < 18)) {
483 } 451 blocks[x + y * WIDTH] = rand() % 2;
484 break; 452 }
485 case 2: 453 break;
486 case 3: 454 case 4:
487 if ((x>12)&&(x<18)&&(y>12)&&(y<18)) 455 case 5:
488 { 456 if ((x > 11) && (x < 19) && (y > 11) && (y < 19)) {
489 blocks[x+y*WIDTH] = rand() % 2; 457 blocks[x + y * WIDTH] = rand() % 2;
490 } 458 }
491 break; 459 break;
492 case 4: 460 default:
493 case 5: 461 blocks[x + y * WIDTH] = rand() % 2;
494 if ((x>11)&&(x<19)&&(y>11)&&(y<19)) 462 }
495 { 463 }
496 blocks[x+y*WIDTH] = rand() % 2; 464 }
497 } 465
498 break; 466 blocks[15 + 15 * WIDTH] = false;
499 default:
500 blocks[x+y*WIDTH] = rand() % 2;
501 }
502 }
503 }
504
505 blocks[15+15*WIDTH] = false;
506} 467}
507 468
508bool GameBoard::operator<(const GameBoard& other) const 469bool GameBoard::operator<(const GameBoard& other) const {
509{ 470 for (int i = WIDTH * HEIGHT - 1; i >= 0; i--) {
510 for (int i = WIDTH*HEIGHT-1; i >= 0; i--) 471 if (blocks[i] ^ other.blocks[i]) {
511 {
512 if (blocks[i] ^ other.blocks[i])
513 {
514 return other.blocks[i]; 472 return other.blocks[i];
515 } 473 }
516 } 474 }
@@ -518,8 +476,7 @@ bool GameBoard::operator<(const GameBoard& other) const
518 return false; 476 return false;
519} 477}
520 478
521bool GameBoard::solve(int playerx, int playery) const 479bool GameBoard::solve(int playerx, int playery) const {
522{
523 std::deque<std::tuple<GameBoard, coord, int>> search; 480 std::deque<std::tuple<GameBoard, coord, int>> search;
524 std::unordered_map<board_type, board_type> done; 481 std::unordered_map<board_type, board_type> done;
525 482
@@ -532,12 +489,10 @@ bool GameBoard::solve(int playerx, int playery) const
532 std::unordered_set<board_type> pastStates; 489 std::unordered_set<board_type> pastStates;
533 pastStates.insert(original.blocks); 490 pastStates.insert(original.blocks);
534 491
535 while (original.updateable.any()) 492 while (original.updateable.any()) {
536 {
537 original.tick(playerx, playery); 493 original.tick(playerx, playery);
538 494
539 if (pastStates.count(original.blocks)) 495 if (pastStates.count(original.blocks)) {
540 {
541 break; 496 break;
542 } 497 }
543 498
@@ -549,8 +504,7 @@ bool GameBoard::solve(int playerx, int playery) const
549 504
550 // Use breadth first search to find a solution. 505 // Use breadth first search to find a solution.
551 bool exists = false; 506 bool exists = false;
552 while (!search.empty()) 507 while (!search.empty()) {
553 {
554 auto cur = std::move(search.front()); 508 auto cur = std::move(search.front());
555 search.pop_front(); 509 search.pop_front();
556 510
@@ -559,8 +513,7 @@ bool GameBoard::solve(int playerx, int playery) const
559 int cns = std::get<2>(cur); 513 int cns = std::get<2>(cur);
560 514
561 // If it has been over 100 generations, give up. 515 // If it has been over 100 generations, give up.
562 if (cns > 100) 516 if (cns > 100) {
563 {
564 continue; 517 continue;
565 } 518 }
566 519
@@ -568,8 +521,7 @@ bool GameBoard::solve(int playerx, int playery) const
568 int cply = std::get<1>(cpl); 521 int cply = std::get<1>(cpl);
569 522
570 // If this section of this board state has already been checked, skip it. 523 // If this section of this board state has already been checked, skip it.
571 if (done.count(cbr.blocks) && done.at(cbr.blocks)[cplx+cply*WIDTH]) 524 if (done.count(cbr.blocks) && done.at(cbr.blocks)[cplx + cply * WIDTH]) {
572 {
573 continue; 525 continue;
574 } 526 }
575 527
@@ -579,44 +531,39 @@ bool GameBoard::solve(int playerx, int playery) const
579 board_type flood; 531 board_type flood;
580 std::deque<coord> front; 532 std::deque<coord> front;
581 front.push_front(cpl); 533 front.push_front(cpl);
582 flood[cplx+cply*WIDTH] = true; 534 flood[cplx + cply * WIDTH] = true;
583 535
584 std::set<coord> edges; 536 std::set<coord> edges;
585 537
586 while (!front.empty()) 538 while (!front.empty()) {
587 {
588 coord frontLoc = std::move(front.front()); 539 coord frontLoc = std::move(front.front());
589 front.pop_front(); 540 front.pop_front();
590 541
591 // Iterate over the positions 4-adjacent to the current one. 542 // Iterate over the positions 4-adjacent to the current one.
592 for (coord& fc : std::list<coord>{ 543 for (coord& fc : std::list<coord>{
593 {std::get<0>(frontLoc) - 1, std::get<1>(frontLoc) }, 544 {std::get<0>(frontLoc) - 1, std::get<1>(frontLoc)},
594 {std::get<0>(frontLoc) + 1, std::get<1>(frontLoc) }, 545 {std::get<0>(frontLoc) + 1, std::get<1>(frontLoc)},
595 {std::get<0>(frontLoc) , std::get<1>(frontLoc) - 1}, 546 {std::get<0>(frontLoc), std::get<1>(frontLoc) - 1},
596 {std::get<0>(frontLoc) , std::get<1>(frontLoc) + 1}, 547 {std::get<0>(frontLoc), std::get<1>(frontLoc) + 1},
597 }) 548 }) {
598 {
599 wrap(std::get<0>(fc), std::get<1>(fc)); 549 wrap(std::get<0>(fc), std::get<1>(fc));
600 int fcx = std::get<0>(fc); 550 int fcx = std::get<0>(fc);
601 int fcy = std::get<1>(fc); 551 int fcy = std::get<1>(fc);
602 552
603 // If this position is already in the flood, skip it. 553 // If this position is already in the flood, skip it.
604 if (flood[fcx+fcy*WIDTH]) 554 if (flood[fcx + fcy * WIDTH]) {
605 {
606 continue; 555 continue;
607 } 556 }
608 557
609 // If the player could not move into this position, skip it. 558 // If the player could not move into this position, skip it.
610 if (cbr.isObstructed(fcx, fcy)) 559 if (cbr.isObstructed(fcx, fcy)) {
611 {
612 continue; 560 continue;
613 } 561 }
614 562
615 // If this position is adjacent to the event, then the board is 563 // If this position is adjacent to the event, then the board is
616 // solvable. 564 // solvable.
617 if (((fcx == 15) && ((fcy == 14) || (fcy == 16))) || 565 if (((fcx == 15) && ((fcy == 14) || (fcy == 16))) ||
618 ((fcy == 15) && ((fcx == 14) || (fcx == 16)))) 566 ((fcy == 15) && ((fcx == 14) || (fcx == 16)))) {
619 {
620 exists = true; 567 exists = true;
621 break; 568 break;
622 } 569 }
@@ -625,12 +572,9 @@ bool GameBoard::solve(int playerx, int playery) const
625 // the start or end positions to change. This is more efficient than 572 // the start or end positions to change. This is more efficient than
626 // copying the board state and then running tick. 573 // copying the board state and then running tick.
627 bool changed = false; 574 bool changed = false;
628 for (int dy = -1; dy <= 1; dy++) 575 for (int dy = -1; dy <= 1; dy++) {
629 { 576 for (int dx = -1; dx <= 1; dx++) {
630 for (int dx = -1; dx <=1; dx++) 577 if (dx == 0 && dy == 0) {
631 {
632 if (dx == 0 && dy == 0)
633 {
634 continue; 578 continue;
635 } 579 }
636 580
@@ -639,13 +583,7 @@ bool GameBoard::solve(int playerx, int playery) const
639 wrap(cpldx, cpldy); 583 wrap(cpldx, cpldy);
640 584
641 if (cbr.isObstructed(cpldx, cpldy) != 585 if (cbr.isObstructed(cpldx, cpldy) !=
642 applyNeighbors( 586 applyNeighbors(cpldx, cpldy, cbr.blocks, fcx, fcy)) {
643 cpldx,
644 cpldy,
645 cbr.blocks,
646 fcx,
647 fcy))
648 {
649 changed = true; 587 changed = true;
650 break; 588 break;
651 } 589 }
@@ -655,43 +593,33 @@ bool GameBoard::solve(int playerx, int playery) const
655 wrap(fcxdx, fcydy); 593 wrap(fcxdx, fcydy);
656 594
657 if (cbr.isObstructed(fcxdx, fcydy) != 595 if (cbr.isObstructed(fcxdx, fcydy) !=
658 applyNeighbors( 596 applyNeighbors(fcxdx, fcydy, cbr.blocks, fcx, fcy)) {
659 fcxdx,
660 fcydy,
661 cbr.blocks,
662 fcx,
663 fcy))
664 {
665 changed = true; 597 changed = true;
666 break; 598 break;
667 } 599 }
668 } 600 }
669 601
670 if (changed) 602 if (changed) {
671 {
672 break; 603 break;
673 } 604 }
674 } 605 }
675 606
676 // If moving to this position would change the board state, add it to 607 // If moving to this position would change the board state, add it to
677 // the set of edges; otherwise, add it to the flood and the flood front. 608 // the set of edges; otherwise, add it to the flood and the flood front.
678 if (changed) 609 if (changed) {
679 {
680 edges.insert(fc); 610 edges.insert(fc);
681 } else { 611 } else {
682 flood[fcx+fcy*WIDTH] = true; 612 flood[fcx + fcy * WIDTH] = true;
683 front.push_back(fc); 613 front.push_back(fc);
684 } 614 }
685 } 615 }
686 616
687 if (exists) 617 if (exists) {
688 {
689 break; 618 break;
690 } 619 }
691 } 620 }
692 621
693 if (exists) 622 if (exists) {
694 {
695 break; 623 break;
696 } 624 }
697 625
@@ -699,8 +627,7 @@ bool GameBoard::solve(int playerx, int playery) const
699 done[cbr.blocks] |= flood; 627 done[cbr.blocks] |= flood;
700 628
701 // Add the edges to the search queue. 629 // Add the edges to the search queue.
702 for (const coord& newLoc : edges) 630 for (const coord& newLoc : edges) {
703 {
704 GameBoard nextState1 = cbr; 631 GameBoard nextState1 = cbr;
705 nextState1.tick(std::get<0>(newLoc), std::get<1>(newLoc)); 632 nextState1.tick(std::get<0>(newLoc), std::get<1>(newLoc));
706 633
@@ -710,12 +637,10 @@ bool GameBoard::solve(int playerx, int playery) const
710 std::unordered_set<board_type> pastStates; 637 std::unordered_set<board_type> pastStates;
711 pastStates.insert(nextState1.blocks); 638 pastStates.insert(nextState1.blocks);
712 639
713 while (nextState1.updateable.any()) 640 while (nextState1.updateable.any()) {
714 {
715 nextState1.tick(std::get<0>(newLoc), std::get<1>(newLoc)); 641 nextState1.tick(std::get<0>(newLoc), std::get<1>(newLoc));
716 642
717 if (pastStates.count(nextState1.blocks)) 643 if (pastStates.count(nextState1.blocks)) {
718 {
719 break; 644 break;
720 } 645 }
721 646
@@ -723,10 +648,9 @@ bool GameBoard::solve(int playerx, int playery) const
723 } 648 }
724 649
725 if (!done.count(nextState1.blocks) || 650 if (!done.count(nextState1.blocks) ||
726 !done.at(nextState1.blocks) 651 !done.at(nextState1.blocks)[std::get<0>(newLoc) +
727 [std::get<0>(newLoc) + std::get<1>(newLoc)*WIDTH]) 652 std::get<1>(newLoc) * WIDTH]) {
728 { 653 search.emplace_back(std::move(nextState1), newLoc, cns + 1);
729 search.emplace_back(std::move(nextState1), newLoc, cns+1);
730 } 654 }
731 } 655 }
732 } 656 }
@@ -734,13 +658,12 @@ bool GameBoard::solve(int playerx, int playery) const
734 return exists; 658 return exists;
735} 659}
736 660
737std::string GameBoard::dump() const 661std::string GameBoard::dump() const {
738{
739 std::stringstream output; 662 std::stringstream output;
740 output << std::hex; 663 output << std::hex;
741 for (int i=0; i<WIDTH*HEIGHT/4; i++) 664 for (int i = 0; i < WIDTH * HEIGHT / 4; i++) {
742 { 665 int chunk = (8 * blocks[i * 4]) + (4 * blocks[i * 4 + 1]) +
743 int chunk = (8 * blocks[i*4]) + (4 * blocks[i*4+1]) + (2 * blocks[i*4+2]) + blocks[i*4+3]; 666 (2 * blocks[i * 4 + 2]) + blocks[i * 4 + 3];
744 output << chunk; 667 output << chunk;
745 } 668 }
746 669
diff --git a/gamestate.h b/gamestate.h index 3c77ba9..32e5d07 100644 --- a/gamestate.h +++ b/gamestate.h
@@ -1,12 +1,13 @@
1#include <SDL.h> 1#include <SDL.h>
2
2#include "state.h" 3#include "state.h"
3 4
4#ifndef GAMESTATE_H 5#ifndef GAMESTATE_H
5#define GAMESTATE_H 6#define GAMESTATE_H
6 7
7class GameState : public State { 8class GameState : public State {
8 public: 9 public:
9 State* operator() (SDL_Window* window, SDL_Renderer* renderer); 10 State* operator()(SDL_Window* window, SDL_Renderer* renderer);
10}; 11};
11 12
12#endif \ No newline at end of file 13#endif \ No newline at end of file
diff --git a/highscore.cpp b/highscore.cpp index 7133e1a..eefe058 100644 --- a/highscore.cpp +++ b/highscore.cpp
@@ -1,27 +1,14 @@
1#include "highscore.h" 1#include "highscore.h"
2 2
3Highscore::Highscore(char* name, int level) 3Highscore::Highscore(char* name, int level) {
4{ 4 this->name = name;
5 this->name = name; 5 this->level = level;
6 this->level = level;
7} 6}
8 7
9char* Highscore::getName() 8char* Highscore::getName() { return name; }
10{
11 return name;
12}
13 9
14int Highscore::getLevel() 10int Highscore::getLevel() { return level; }
15{
16 return level;
17}
18 11
19void Highscore::setRank(int rank) 12void Highscore::setRank(int rank) { this->rank = rank; }
20{
21 this->rank = rank;
22}
23 13
24int Highscore::getRank() 14int Highscore::getRank() { return rank; }
25{
26 return rank;
27}
diff --git a/highscore.h b/highscore.h index 721b226..f7ecacc 100644 --- a/highscore.h +++ b/highscore.h
@@ -2,17 +2,17 @@
2#define HIGHSCORE_H 2#define HIGHSCORE_H
3 3
4class Highscore { 4class Highscore {
5 public: 5 public:
6 Highscore(char* name, int level); 6 Highscore(char* name, int level);
7 char* getName(); 7 char* getName();
8 int getLevel(); 8 int getLevel();
9 void setRank(int rank); 9 void setRank(int rank);
10 int getRank(); 10 int getRank();
11 11
12 private: 12 private:
13 char* name; 13 char* name;
14 int level; 14 int level;
15 int rank; 15 int rank;
16}; 16};
17 17
18#endif 18#endif
diff --git a/hslist.cpp b/hslist.cpp index f71d8be..5eb9b6c 100644 --- a/hslist.cpp +++ b/hslist.cpp
@@ -1,1002 +1,950 @@
1#include "hslist.h" 1#include "hslist.h"
2#include <SDL_ttf.h> 2
3#include <SDL_net.h> 3#include <SDL_net.h>
4#include <sstream> 4#include <SDL_ttf.h>
5#include <fstream> 5
6#include <algorithm> 6#include <algorithm>
7#include "util.h" 7#include <fstream>
8#include "titlestate.h" 8#include <sstream>
9
9#include "gamestate.h" 10#include "gamestate.h"
11#include "titlestate.h"
12#include "util.h"
10 13
11// We want to be able to sort Highscore objects in descending score order 14// We want to be able to sort Highscore objects in descending score order
12struct hslist_comp { 15struct hslist_comp {
13 bool operator() (Highscore* lhs, Highscore* rhs) const 16 bool operator()(Highscore* lhs, Highscore* rhs) const {
14 { 17 return (lhs->getLevel() > rhs->getLevel());
15 return (lhs->getLevel() > rhs->getLevel()); 18 }
16 }
17} hslist_comp_i; 19} hslist_comp_i;
18 20
19// resetRanks : sets the rank of all Highscore objects in a hslist_t to their (one-based) index in the list 21// resetRanks : sets the rank of all Highscore objects in a hslist_t to their
20void resetRanks(hslist_t in) 22// (one-based) index in the list
21{ 23void resetRanks(hslist_t in) {
22 int i=1; 24 int i = 1;
23 for (hslist_t::iterator it = in.begin(); it != in.end(); ++it, ++i) 25 for (hslist_t::iterator it = in.begin(); it != in.end(); ++it, ++i) {
24 { 26 ((Highscore*)*it)->setRank(i);
25 ((Highscore*)*it)->setRank(i); 27 }
26 }
27} 28}
28 29
29SDL_Surface* HighscoreList::render() 30SDL_Surface* HighscoreList::render() {
30{ 31 SDL_Surface* tmp = SDL_CreateRGBSurface(0, 480, 480, 32, 0, 0, 0, 0);
31 SDL_Surface* tmp = SDL_CreateRGBSurface(0, 480, 480, 32, 0,0,0,0); 32 Uint32 bgColor = SDL_MapRGB(tmp->format, 255, 255, 255);
32 Uint32 bgColor = SDL_MapRGB(tmp->format, 255, 255, 255); 33 SDL_FillRect(tmp, NULL, bgColor);
33 SDL_FillRect(tmp, NULL, bgColor); 34 SDL_SetColorKey(tmp, SDL_TRUE, bgColor);
34 SDL_SetColorKey(tmp, SDL_TRUE, bgColor); 35 TTF_Font* posFont = loadFont(40);
35 TTF_Font* posFont = loadFont(40); 36 TTF_Font* dataFont = loadFont(25);
36 TTF_Font* dataFont = loadFont(25); 37 SDL_Color fontColor = {0, 0, 0, 0};
37 SDL_Color fontColor = {0, 0, 0, 0}; 38
38 39 int i = 0;
39 int i=0; 40 for (hslist_t::iterator it = hslist.begin(); it != hslist.end(); ++it, ++i) {
40 for (hslist_t::iterator it = hslist.begin(); it != hslist.end(); ++it, ++i) 41 Highscore* h = *it;
41 { 42
42 Highscore* h = *it; 43 int posw, posh;
43 44 char pos[4]; // 2 max characters in rank plus the colon at the end, plus
44 int posw, posh; 45 // terminator
45 char pos[4]; // 2 max characters in rank plus the colon at the end, plus terminator 46 sprintf(pos, "%d:", h->getRank());
46 sprintf(pos, "%d:", h->getRank()); 47 TTF_SizeText(posFont, pos, &posw, &posh);
47 TTF_SizeText(posFont, pos, &posw, &posh); 48 SDL_Rect posSpace = {0, (i + 1) * 40, posw, posh};
48 SDL_Rect posSpace = {0, (i+1)*40, posw, posh}; 49 SDL_BlitSurface(TTF_RenderText_Blended(posFont, pos, fontColor), NULL, tmp,
49 SDL_BlitSurface(TTF_RenderText_Blended(posFont, pos, fontColor), NULL, tmp, &posSpace); 50 &posSpace);
50 51
51 int namew, nameh; 52 int namew, nameh;
52 char name[27]; // 25 max characters in username plus the space at the beginning, plus terminator 53 char name[27]; // 25 max characters in username plus the space at the
53 sprintf(name, " %s", h->getName()); 54 // beginning, plus terminator
54 TTF_SizeText(dataFont, name, &namew, &nameh); 55 sprintf(name, " %s", h->getName());
55 SDL_Rect nameSpace = {posw, (i+1)*40+((posh/2)-(nameh/2)), namew, nameh}; 56 TTF_SizeText(dataFont, name, &namew, &nameh);
56 SDL_BlitSurface(TTF_RenderText_Blended(dataFont, name, fontColor), NULL, tmp, &nameSpace); 57 SDL_Rect nameSpace = {posw, (i + 1) * 40 + ((posh / 2) - (nameh / 2)),
57 58 namew, nameh};
58 int lvlw, lvlh; 59 SDL_BlitSurface(TTF_RenderText_Blended(dataFont, name, fontColor), NULL,
59 char lvl[11]; // 10 max characters in level (based off the fact that 2^32-1 is 10 characters long, and is the highest int), plus terminator 60 tmp, &nameSpace);
60 sprintf(lvl, "%d", h->getLevel()); 61
61 TTF_SizeText(dataFont, lvl, &lvlw, &lvlh); 62 int lvlw, lvlh;
62 SDL_Rect lvlSpace = {480-lvlw, (i+1)*40+((posh/2)-(nameh/2)), lvlw, lvlh}; 63 char lvl[11]; // 10 max characters in level (based off the fact that 2^32-1
63 SDL_BlitSurface(TTF_RenderText_Blended(dataFont, lvl, fontColor), NULL, tmp, &lvlSpace); 64 // is 10 characters long, and is the highest int), plus
64 } 65 // terminator
65 66 sprintf(lvl, "%d", h->getLevel());
66 return tmp; 67 TTF_SizeText(dataFont, lvl, &lvlw, &lvlh);
68 SDL_Rect lvlSpace = {480 - lvlw, (i + 1) * 40 + ((posh / 2) - (nameh / 2)),
69 lvlw, lvlh};
70 SDL_BlitSurface(TTF_RenderText_Blended(dataFont, lvl, fontColor), NULL, tmp,
71 &lvlSpace);
72 }
73
74 return tmp;
67} 75}
68 76
69hslist_t HighscoreList::getLocalHighscores() 77hslist_t HighscoreList::getLocalHighscores() {
70{ 78 hslist_t temp;
71 hslist_t temp;
72 79
73 std::ifstream exists(getDataFile()); 80 std::ifstream exists(getDataFile());
74 if (exists) 81 if (exists) {
75 { 82 FILE* hslist = fopen(getDataFile(), "r");
76 FILE* hslist = fopen(getDataFile(), "r"); 83 int scores;
77 int scores; 84 fscanf(hslist, "%d%*c", &scores);
78 fscanf(hslist, "%d%*c", &scores);
79 85
80 for (int i=0; i<scores; i++) 86 for (int i = 0; i < scores; i++) {
81 { 87 int namelen;
82 int namelen; 88 char namelens[4];
83 char namelens[4]; 89 char* name = (char*)calloc(25, sizeof(char));
84 char* name = (char*) calloc(25, sizeof(char)); 90 int score;
85 int score;
86 91
87 fscanf(hslist, "%d", &namelen); 92 fscanf(hslist, "%d", &namelen);
88 sprintf(namelens, "%%%dc", namelen); 93 sprintf(namelens, "%%%dc", namelen);
89 fscanf(hslist, namelens, name); 94 fscanf(hslist, namelens, name);
90 fscanf(hslist, "%d%*c", &score); 95 fscanf(hslist, "%d%*c", &score);
91 96
92 Highscore* h = new Highscore(name, score); 97 Highscore* h = new Highscore(name, score);
93 h->setRank(i+1); 98 h->setRank(i + 1);
94 99
95 temp.push_back(h); 100 temp.push_back(h);
96 } 101 }
97 102
98 fclose(hslist); 103 fclose(hslist);
99 } 104 }
100 105
101 return temp; 106 return temp;
102} 107}
103 108
104hslist_t HighscoreList::getGlobalHighscores() 109hslist_t HighscoreList::getGlobalHighscores() {
105{ 110 IPaddress ipaddress;
106 IPaddress ipaddress; 111
107 112 if (SDLNet_ResolveHost(&ipaddress, "other.fourisland.com", 80) == -1) {
108 if (SDLNet_ResolveHost(&ipaddress, "other.fourisland.com", 80) == -1) 113 printf("Could not resolve host \"other.fourisland.com\": %s\n",
109 { 114 SDLNet_GetError());
110 printf("Could not resolve host \"other.fourisland.com\": %s\n", SDLNet_GetError()); 115 throw 1;
111 throw 1; 116 }
112 } 117
113 118 TCPsocket tcpsock = SDLNet_TCP_Open(&ipaddress);
114 TCPsocket tcpsock = SDLNet_TCP_Open(&ipaddress); 119 if (!tcpsock) {
115 if (!tcpsock) 120 printf("Could not connect to host \"other.fourisland.com\": %s\n",
116 { 121 SDLNet_GetError());
117 printf("Could not connect to host \"other.fourisland.com\": %s\n", SDLNet_GetError()); 122 throw 2;
118 throw 2; 123 }
119 } 124
120 125 const char* headers =
121 const char* headers = "GET /mol/hslist.php HTTP/1.1\nHost: other.fourisland.com\nUser-Agent: Maze Of Life v3.0\nAccept: text/plain\nKeep-Alive: 300\nConnection: keep-alive\n\n"; 126 "GET /mol/hslist.php HTTP/1.1\nHost: other.fourisland.com\nUser-Agent: "
122 if (SDLNet_TCP_Send(tcpsock, headers, strlen(headers)+1) < strlen(headers)) 127 "Maze Of Life v3.0\nAccept: text/plain\nKeep-Alive: 300\nConnection: "
123 { 128 "keep-alive\n\n";
124 printf("Connection closed by peer: %s\n", SDLNet_GetError()); 129 if (SDLNet_TCP_Send(tcpsock, headers, strlen(headers) + 1) <
125 throw 3; 130 strlen(headers)) {
126 } 131 printf("Connection closed by peer: %s\n", SDLNet_GetError());
127 132 throw 3;
128 std::stringstream download(std::stringstream::in | std::stringstream::out); 133 }
129 char hslist[1024]; 134
130 SDLNet_TCP_Recv(tcpsock, hslist, 1024); 135 std::stringstream download(std::stringstream::in | std::stringstream::out);
131 download << hslist; 136 char hslist[1024];
132 SDLNet_TCP_Close(tcpsock); 137 SDLNet_TCP_Recv(tcpsock, hslist, 1024);
133 138 download << hslist;
134 char temps[256]; 139 SDLNet_TCP_Close(tcpsock);
135 download.getline(temps,256); 140
136 while (strlen(temps) != 1) 141 char temps[256];
137 { 142 download.getline(temps, 256);
138 download.getline(temps,256); 143 while (strlen(temps) != 1) {
139 } 144 download.getline(temps, 256);
140 145 }
141 hslist_t temp; 146
142 int scores; 147 hslist_t temp;
143 download.getline(temps, 256); 148 int scores;
144 if (sscanf(temps, "%d%*c", &scores) != 1) 149 download.getline(temps, 256);
145 { 150 if (sscanf(temps, "%d%*c", &scores) != 1) {
146 printf("Recieved data is of an invalid format: %s\n", temps); 151 printf("Recieved data is of an invalid format: %s\n", temps);
147 throw 4; 152 throw 4;
148 } 153 }
149 154
150 for (int i=0; i<scores; i++) 155 for (int i = 0; i < scores; i++) {
151 { 156 int namelen;
152 int namelen; 157 char namelens[13];
153 char namelens[13]; 158 char* name = (char*)calloc(25, sizeof(char));
154 char* name = (char*) calloc(25, sizeof(char)); 159 int score;
155 int score; 160 download.getline(temps, 256);
156 download.getline(temps, 256); 161
157 162 if (sscanf(temps, "%d", &namelen) != 1) {
158 if (sscanf(temps, "%d", &namelen) != 1) 163 printf("Recieved data is of an invalid format (1-%d): %s\n", i, temps);
159 { 164 throw 4;
160 printf("Recieved data is of an invalid format (1-%d): %s\n", i, temps); 165 }
161 throw 4; 166
162 } 167 sprintf(namelens, "%%*d%%%dc", namelen);
163 168
164 sprintf(namelens, "%%*d%%%dc", namelen); 169 if (sscanf(temps, namelens, name) != 1) {
165 170 printf("Recieved data is of an invalid format (2-%d): %s\n", i, temps);
166 if (sscanf(temps, namelens, name) != 1) 171 throw 4;
167 { 172 }
168 printf("Recieved data is of an invalid format (2-%d): %s\n", i, temps); 173
169 throw 4; 174 sprintf(namelens, "%%*d%%*%dc%%d", namelen);
170 } 175
171 176 if (sscanf(temps, namelens, &score) != 1) {
172 sprintf(namelens, "%%*d%%*%dc%%d", namelen); 177 printf("Recieved data is of an invalid format (3-%d): %s\n", i, temps);
173 178 throw 4;
174 if (sscanf(temps, namelens, &score) != 1) 179 }
175 { 180
176 printf("Recieved data is of an invalid format (3-%d): %s\n", i, temps); 181 Highscore* h = new Highscore(name, score);
177 throw 4; 182 h->setRank(i + 1);
178 } 183
179 184 temp.push_back(h);
180 Highscore* h = new Highscore(name, score); 185 }
181 h->setRank(i+1); 186
182 187 return temp;
183 temp.push_back(h);
184 }
185
186 return temp;
187} 188}
188 189
189LocalHighscoreList::LocalHighscoreList() 190LocalHighscoreList::LocalHighscoreList() {
190{ 191 this->hslist = getLocalHighscores();
191 this->hslist = getLocalHighscores();
192} 192}
193 193
194int LocalHighscoreList::addHighscore(Highscore* h) 194int LocalHighscoreList::addHighscore(Highscore* h) {
195{ 195 hslist.push_back(h);
196 hslist.push_back(h); 196 std::sort(hslist.begin(), hslist.end(), hslist_comp_i);
197 std::sort(hslist.begin(), hslist.end(), hslist_comp_i); 197 resetRanks(hslist);
198 resetRanks(hslist);
199 198
200 if (hslist.size() > 10) 199 if (hslist.size() > 10) {
201 { 200 hslist.resize(10);
202 hslist.resize(10); 201 }
203 }
204 202
205 return h->getRank(); 203 return h->getRank();
206} 204}
207 205
208void LocalHighscoreList::writeHighscores() 206void LocalHighscoreList::writeHighscores() {
209{ 207 FILE* hsfile = fopen(getDataFile(), "w");
210 FILE* hsfile = fopen(getDataFile(), "w"); 208 fprintf(hsfile, "%d ", (int)this->hslist.size());
211 fprintf(hsfile, "%d ", (int) this->hslist.size());
212 209
213 for (hslist_t::iterator it = hslist.begin(); it != this->hslist.end(); it++) 210 for (hslist_t::iterator it = hslist.begin(); it != this->hslist.end(); it++) {
214 { 211 Highscore* h = *it;
215 Highscore* h = *it;
216 212
217 fprintf(hsfile, "%d%s%d ", (int) strlen(h->getName()), h->getName(), h->getLevel()); 213 fprintf(hsfile, "%d%s%d ", (int)strlen(h->getName()), h->getName(),
218 } 214 h->getLevel());
215 }
219 216
220 fclose(hsfile); 217 fclose(hsfile);
221} 218}
222 219
223GlobalHighscoreList::GlobalHighscoreList() 220GlobalHighscoreList::GlobalHighscoreList() {
224{ 221 fail = false;
225 fail = false;
226
227 try
228 {
229 this->hslist = getGlobalHighscores();
230 } catch (int e)
231 {
232 fail = true;
233 }
234}
235 222
236GlobalHighscoreList::GlobalHighscoreList(Highscore* h) 223 try {
237{ 224 this->hslist = getGlobalHighscores();
238 fail = false; 225 } catch (int e) {
239 226 fail = true;
240 try 227 }
241 {
242 IPaddress ipaddress;
243
244 if (SDLNet_ResolveHost(&ipaddress, "other.fourisland.com", 80) == -1)
245 {
246 printf("Could not resolve host \"other.fourisland.com\": %s\n", SDLNet_GetError());
247 throw 1;
248 }
249
250 TCPsocket tcpsock = SDLNet_TCP_Open(&ipaddress);
251 if (!tcpsock)
252 {
253 printf("Could not connect to host \"other.fourisland.com\": %s\n", SDLNet_GetError());
254 throw 2;
255 }
256
257 char body[256];
258 sprintf(body, "name=%s&level=%d", h->getName(), h->getLevel());
259 char headers[256];
260 sprintf(headers, "POST /mol/hslist.php?add HTTP/1.1\nHost: other.fourisland.com\nUser-Agent: Maze Of Life v2.0\nAccept: text/plain\nKeep-Alive: 300\nConnection: keep-alive\nContent-Type: application/x-www-form-urlencoded\nContent-Length: %d\n\n%s\n", (int) strlen(body), body);
261 if (SDLNet_TCP_Send(tcpsock, headers, strlen(headers)+1) < strlen(headers))
262 {
263 printf("Connection closed by peer: %s\n", SDLNet_GetError());
264 throw 3;
265 }
266
267 std::stringstream download(std::stringstream::in | std::stringstream::out);
268 char hslist[1024];
269 SDLNet_TCP_Recv(tcpsock, hslist, 1024);
270 download << hslist;
271 SDLNet_TCP_Close(tcpsock);
272
273 char temps[256];
274 download.getline(temps,256);
275 while (strlen(temps) != 1)
276 {
277 download.getline(temps,256);
278 }
279
280 int rank;
281 download.getline(temps, 256);
282 if (sscanf(temps, "%d%*c", &rank) != 1)
283 {
284 printf("Recieved data is of an invalid format: %s\n", temps);
285 throw 4;
286 }
287
288 this->hslist = getGlobalHighscores();
289
290 if (this->hslist.empty())
291 {
292 printf("Global Highscore List cannot be empty after adding a score to it.\n");
293 throw 5;
294 }
295
296 if (rank > 10)
297 {
298 h->setRank(rank);
299
300 this->hslist[9] = h;
301 } else {
302 this->hslist.push_back(h);
303 std::sort(this->hslist.begin(), this->hslist.end(), hslist_comp_i);
304 resetRanks(this->hslist);
305
306 if (this->hslist.size() > 10)
307 {
308 this->hslist.resize(10);
309 }
310 }
311 } catch (int e)
312 {
313 fail = true;
314 }
315} 228}
316 229
317SDL_Surface* GlobalHighscoreList::render() 230GlobalHighscoreList::GlobalHighscoreList(Highscore* h) {
318{ 231 fail = false;
319 if (fail) 232
320 { 233 try {
321 SDL_Surface* tmp = SDL_CreateRGBSurface(0, 480, 480, 32, 0,0,0,0); 234 IPaddress ipaddress;
322 Uint32 bgColor = SDL_MapRGB(tmp->format, 255, 255, 255); 235
323 SDL_FillRect(tmp, NULL, bgColor); 236 if (SDLNet_ResolveHost(&ipaddress, "other.fourisland.com", 80) == -1) {
324 SDL_SetColorKey(tmp, SDL_TRUE, bgColor); 237 printf("Could not resolve host \"other.fourisland.com\": %s\n",
325 TTF_Font* dataFont = loadFont(25); 238 SDLNet_GetError());
326 SDL_Color fontColor = {0, 0, 0, 0}; 239 throw 1;
327 SDL_Surface* text = TTF_RenderText_Blended(dataFont, "Error retrieving highscores", fontColor); 240 }
328 SDL_Rect tSpace = {240-(text->w/2), 240-(text->h/2), text->w, text->h}; 241
329 SDL_BlitSurface(text, NULL, tmp, &tSpace); 242 TCPsocket tcpsock = SDLNet_TCP_Open(&ipaddress);
330 243 if (!tcpsock) {
331 return tmp; 244 printf("Could not connect to host \"other.fourisland.com\": %s\n",
332 } else { 245 SDLNet_GetError());
333 return super::render(); 246 throw 2;
334 } 247 }
248
249 char body[256];
250 sprintf(body, "name=%s&level=%d", h->getName(), h->getLevel());
251 char headers[256];
252 sprintf(
253 headers,
254 "POST /mol/hslist.php?add HTTP/1.1\nHost: "
255 "other.fourisland.com\nUser-Agent: Maze Of Life v2.0\nAccept: "
256 "text/plain\nKeep-Alive: 300\nConnection: keep-alive\nContent-Type: "
257 "application/x-www-form-urlencoded\nContent-Length: %d\n\n%s\n",
258 (int)strlen(body), body);
259 if (SDLNet_TCP_Send(tcpsock, headers, strlen(headers) + 1) <
260 strlen(headers)) {
261 printf("Connection closed by peer: %s\n", SDLNet_GetError());
262 throw 3;
263 }
264
265 std::stringstream download(std::stringstream::in | std::stringstream::out);
266 char hslist[1024];
267 SDLNet_TCP_Recv(tcpsock, hslist, 1024);
268 download << hslist;
269 SDLNet_TCP_Close(tcpsock);
270
271 char temps[256];
272 download.getline(temps, 256);
273 while (strlen(temps) != 1) {
274 download.getline(temps, 256);
275 }
276
277 int rank;
278 download.getline(temps, 256);
279 if (sscanf(temps, "%d%*c", &rank) != 1) {
280 printf("Recieved data is of an invalid format: %s\n", temps);
281 throw 4;
282 }
283
284 this->hslist = getGlobalHighscores();
285
286 if (this->hslist.empty()) {
287 printf(
288 "Global Highscore List cannot be empty after adding a score to "
289 "it.\n");
290 throw 5;
291 }
292
293 if (rank > 10) {
294 h->setRank(rank);
295
296 this->hslist[9] = h;
297 } else {
298 this->hslist.push_back(h);
299 std::sort(this->hslist.begin(), this->hslist.end(), hslist_comp_i);
300 resetRanks(this->hslist);
301
302 if (this->hslist.size() > 10) {
303 this->hslist.resize(10);
304 }
305 }
306 } catch (int e) {
307 fail = true;
308 }
335} 309}
336 310
337bool GlobalHighscoreList::didFail() 311SDL_Surface* GlobalHighscoreList::render() {
338{ 312 if (fail) {
339 return fail; 313 SDL_Surface* tmp = SDL_CreateRGBSurface(0, 480, 480, 32, 0, 0, 0, 0);
314 Uint32 bgColor = SDL_MapRGB(tmp->format, 255, 255, 255);
315 SDL_FillRect(tmp, NULL, bgColor);
316 SDL_SetColorKey(tmp, SDL_TRUE, bgColor);
317 TTF_Font* dataFont = loadFont(25);
318 SDL_Color fontColor = {0, 0, 0, 0};
319 SDL_Surface* text = TTF_RenderText_Blended(
320 dataFont, "Error retrieving highscores", fontColor);
321 SDL_Rect tSpace = {240 - (text->w / 2), 240 - (text->h / 2), text->w,
322 text->h};
323 SDL_BlitSurface(text, NULL, tmp, &tSpace);
324
325 return tmp;
326 } else {
327 return super::render();
328 }
340} 329}
341 330
342State* ChooseHighscoreListState::operator() (SDL_Window* window, SDL_Renderer* renderer) 331bool GlobalHighscoreList::didFail() { return fail; }
343{ 332
344 SDL_Texture* background = loadImage(renderer, "resources/chl.bmp"); 333State* ChooseHighscoreListState::operator()(SDL_Window* window,
345 SDL_Texture* pointer = loadImage(renderer, "resources/pointer.bmp"); 334 SDL_Renderer* renderer) {
346 int selection = 0; 335 SDL_Texture* background = loadImage(renderer, "resources/chl.bmp");
347 SDL_Event e; 336 SDL_Texture* pointer = loadImage(renderer, "resources/pointer.bmp");
348 337 int selection = 0;
349 for (;;) 338 SDL_Event e;
350 { 339
351 SDL_RenderClear(renderer); 340 for (;;) {
352 SDL_RenderCopy(renderer, background, NULL, NULL); 341 SDL_RenderClear(renderer);
353 applyTexture(renderer, pointer, 127, selection==0?306:(selection==1?336:396)); 342 SDL_RenderCopy(renderer, background, NULL, NULL);
354 SDL_RenderPresent(renderer); 343 applyTexture(renderer, pointer, 127,
355 344 selection == 0 ? 306 : (selection == 1 ? 336 : 396));
356 while (SDL_PollEvent(&e)) 345 SDL_RenderPresent(renderer);
357 { 346
358 if (e.type == SDL_QUIT) 347 while (SDL_PollEvent(&e)) {
359 { 348 if (e.type == SDL_QUIT) {
360 return NULL; 349 return NULL;
361 } else if (e.type == SDL_KEYDOWN) 350 } else if (e.type == SDL_KEYDOWN) {
362 { 351 if ((e.key.keysym.sym == SDLK_UP) && (selection != 0)) {
363 if ((e.key.keysym.sym == SDLK_UP) && (selection != 0)) 352 selection--;
364 { 353 } else if ((e.key.keysym.sym == SDLK_DOWN) && (selection != 2)) {
365 selection--; 354 selection++;
366 } else if ((e.key.keysym.sym == SDLK_DOWN) && (selection != 2)) 355 } else if (e.key.keysym.sym == SDLK_RETURN) {
367 { 356 switch (selection) {
368 selection++; 357 case 0:
369 } else if (e.key.keysym.sym == SDLK_RETURN) 358 return new DisplayLocalHighscoreListState();
370 { 359 case 1:
371 switch (selection) 360 return new DisplayGlobalHighscoreListState();
372 { 361 case 2:
373 case 0: return new DisplayLocalHighscoreListState(); 362 return new TitleState();
374 case 1: return new DisplayGlobalHighscoreListState(); 363 }
375 case 2: return new TitleState(); 364 }
376 } 365 }
377 } 366 }
378 } 367 }
379 }
380 }
381} 368}
382 369
383State* DisplayLocalHighscoreListState::operator() (SDL_Window* window, SDL_Renderer* renderer) 370State* DisplayLocalHighscoreListState::operator()(SDL_Window* window,
384{ 371 SDL_Renderer* renderer) {
385 SDL_Texture* pointer = loadImage(renderer, "resources/pointer.bmp"); 372 SDL_Texture* pointer = loadImage(renderer, "resources/pointer.bmp");
386 373
387 LocalHighscoreList* lhl = new LocalHighscoreList(); 374 LocalHighscoreList* lhl = new LocalHighscoreList();
388 SDL_Surface* list_s = lhl->render(); 375 SDL_Surface* list_s = lhl->render();
389 SDL_Color fontColor = {0, 0, 0, 0}; 376 SDL_Color fontColor = {0, 0, 0, 0};
390 SDL_Surface* title = TTF_RenderText_Blended(loadFont(40), "Highscore List", fontColor); 377 SDL_Surface* title =
391 SDL_Rect tSpace = {240-(title->w/2), 0, title->w, title->h}; 378 TTF_RenderText_Blended(loadFont(40), "Highscore List", fontColor);
392 SDL_BlitSurface(title, NULL, list_s, &tSpace); 379 SDL_Rect tSpace = {240 - (title->w / 2), 0, title->w, title->h};
393 SDL_FreeSurface(title); 380 SDL_BlitSurface(title, NULL, list_s, &tSpace);
394 381 SDL_FreeSurface(title);
395 SDL_Surface* options_s = SDL_LoadBMP("resources/hlo_rtm.bmp"); 382
396 SDL_Rect oSpace = {0, 440, options_s->w, options_s->h}; 383 SDL_Surface* options_s = SDL_LoadBMP("resources/hlo_rtm.bmp");
397 SDL_BlitSurface(options_s, NULL, list_s, &oSpace); 384 SDL_Rect oSpace = {0, 440, options_s->w, options_s->h};
398 SDL_FreeSurface(options_s); 385 SDL_BlitSurface(options_s, NULL, list_s, &oSpace);
399 386 SDL_FreeSurface(options_s);
400 SDL_Texture* list = SDL_CreateTextureFromSurface(renderer, list_s); 387
401 SDL_FreeSurface(list_s); 388 SDL_Texture* list = SDL_CreateTextureFromSurface(renderer, list_s);
402 389 SDL_FreeSurface(list_s);
403 SDL_Event e; 390
404 391 SDL_Event e;
405 for (;;) 392
406 { 393 for (;;) {
407 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); 394 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
408 SDL_RenderClear(renderer); 395 SDL_RenderClear(renderer);
409 SDL_RenderCopy(renderer, list, NULL, NULL); 396 SDL_RenderCopy(renderer, list, NULL, NULL);
410 applyTexture(renderer, pointer, 137, 449); 397 applyTexture(renderer, pointer, 137, 449);
411 SDL_RenderPresent(renderer); 398 SDL_RenderPresent(renderer);
412 399
413 while (SDL_PollEvent(&e)) 400 while (SDL_PollEvent(&e)) {
414 { 401 if (e.type == SDL_QUIT) {
415 if (e.type == SDL_QUIT) 402 return NULL;
416 { 403 } else if (e.type == SDL_KEYDOWN) {
417 return NULL; 404 if (e.key.keysym.sym == SDLK_RETURN) {
418 } else if (e.type == SDL_KEYDOWN) 405 return new ChooseHighscoreListState();
419 { 406 }
420 if (e.key.keysym.sym == SDLK_RETURN) 407 }
421 { 408 }
422 return new ChooseHighscoreListState(); 409 }
423 }
424 }
425 }
426 }
427} 410}
428 411
429State* DisplayAndReturnLocalHighscoreListState::operator() (SDL_Window* window, SDL_Renderer* renderer) 412State* DisplayAndReturnLocalHighscoreListState::operator()(
430{ 413 SDL_Window* window, SDL_Renderer* renderer) {
431 SDL_Texture* pointer = loadImage(renderer, "resources/pointer.bmp"); 414 SDL_Texture* pointer = loadImage(renderer, "resources/pointer.bmp");
432 415
433 LocalHighscoreList* lhl = new LocalHighscoreList(); 416 LocalHighscoreList* lhl = new LocalHighscoreList();
434 SDL_Surface* list_s = lhl->render(); 417 SDL_Surface* list_s = lhl->render();
435 SDL_Color fontColor = {0, 0, 0, 0}; 418 SDL_Color fontColor = {0, 0, 0, 0};
436 SDL_Surface* title = TTF_RenderText_Blended(loadFont(40), "Highscore List", fontColor); 419 SDL_Surface* title =
437 SDL_Rect tSpace = {240-(title->w/2), 0, title->w, title->h}; 420 TTF_RenderText_Blended(loadFont(40), "Highscore List", fontColor);
438 SDL_BlitSurface(title, NULL, list_s, &tSpace); 421 SDL_Rect tSpace = {240 - (title->w / 2), 0, title->w, title->h};
439 SDL_FreeSurface(title); 422 SDL_BlitSurface(title, NULL, list_s, &tSpace);
440 423 SDL_FreeSurface(title);
441 SDL_Surface* options_s = SDL_LoadBMP("resources/hlo_paartm.bmp"); 424
442 SDL_Rect oSpace = {0, 440, options_s->w, options_s->h}; 425 SDL_Surface* options_s = SDL_LoadBMP("resources/hlo_paartm.bmp");
443 SDL_BlitSurface(options_s, NULL, list_s, &oSpace); 426 SDL_Rect oSpace = {0, 440, options_s->w, options_s->h};
444 SDL_FreeSurface(options_s); 427 SDL_BlitSurface(options_s, NULL, list_s, &oSpace);
445 428 SDL_FreeSurface(options_s);
446 SDL_Texture* list = SDL_CreateTextureFromSurface(renderer, list_s); 429
447 SDL_FreeSurface(list_s); 430 SDL_Texture* list = SDL_CreateTextureFromSurface(renderer, list_s);
448 431 SDL_FreeSurface(list_s);
449 int selection = 0; 432
450 SDL_Event e; 433 int selection = 0;
451 434 SDL_Event e;
452 for (;;) 435
453 { 436 for (;;) {
454 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); 437 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
455 SDL_RenderClear(renderer); 438 SDL_RenderClear(renderer);
456 SDL_RenderCopy(renderer, list, NULL, NULL); 439 SDL_RenderCopy(renderer, list, NULL, NULL);
457 applyTexture(renderer, pointer, selection==0?52:225, 447); 440 applyTexture(renderer, pointer, selection == 0 ? 52 : 225, 447);
458 SDL_RenderPresent(renderer); 441 SDL_RenderPresent(renderer);
459 442
460 while (SDL_PollEvent(&e)) 443 while (SDL_PollEvent(&e)) {
461 { 444 if (e.type == SDL_QUIT) {
462 if (e.type == SDL_QUIT) 445 return NULL;
463 { 446 } else if (e.type == SDL_KEYDOWN) {
464 return NULL; 447 if ((e.key.keysym.sym == SDLK_LEFT) && (selection != 0)) {
465 } else if (e.type == SDL_KEYDOWN) 448 selection--;
466 { 449 } else if ((e.key.keysym.sym == SDLK_RIGHT) && (selection != 1)) {
467 if ((e.key.keysym.sym == SDLK_LEFT) && (selection != 0)) 450 selection++;
468 { 451 } else if (e.key.keysym.sym == SDLK_RETURN) {
469 selection--; 452 switch (selection) {
470 } else if ((e.key.keysym.sym == SDLK_RIGHT) && (selection != 1)) 453 case 0:
471 { 454 return new GameState();
472 selection++; 455 case 1:
473 } else if (e.key.keysym.sym == SDLK_RETURN) 456 return new TitleState();
474 { 457 }
475 switch (selection) 458 }
476 { 459 }
477 case 0: return new GameState(); 460 }
478 case 1: return new TitleState(); 461 }
479 }
480 }
481 }
482 }
483 }
484} 462}
485 463
486State* DisplayGlobalHighscoreListState::operator() (SDL_Window* window, SDL_Renderer* renderer) 464State* DisplayGlobalHighscoreListState::operator()(SDL_Window* window,
487{ 465 SDL_Renderer* renderer) {
488 SDL_Texture* pointer = loadImage(renderer, "resources/pointer.bmp"); 466 SDL_Texture* pointer = loadImage(renderer, "resources/pointer.bmp");
489 467
490 // Display loading message 468 // Display loading message
491 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); 469 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
492 SDL_RenderClear(renderer); 470 SDL_RenderClear(renderer);
493 471
494 SDL_Surface* list_s = SDL_CreateRGBSurface(0, 480, 480, 32, 0,0,0,0); 472 SDL_Surface* list_s = SDL_CreateRGBSurface(0, 480, 480, 32, 0, 0, 0, 0);
495 Uint32 bgColor = SDL_MapRGB(list_s->format, 255, 255, 255); 473 Uint32 bgColor = SDL_MapRGB(list_s->format, 255, 255, 255);
496 SDL_FillRect(list_s, NULL, bgColor); 474 SDL_FillRect(list_s, NULL, bgColor);
497 SDL_SetColorKey(list_s, SDL_TRUE, bgColor); 475 SDL_SetColorKey(list_s, SDL_TRUE, bgColor);
498 TTF_Font* dataFont = loadFont(25); 476 TTF_Font* dataFont = loadFont(25);
499 SDL_Color fontColor = {0, 0, 0, 0}; 477 SDL_Color fontColor = {0, 0, 0, 0};
500 SDL_Surface* text = TTF_RenderText_Blended(dataFont, "Fetching highscores....", fontColor); 478 SDL_Surface* text =
501 SDL_Rect aSpace = {240-(text->w/2), 240-(text->h/2), text->w, text->h}; 479 TTF_RenderText_Blended(dataFont, "Fetching highscores....", fontColor);
502 SDL_BlitSurface(text, NULL, list_s, &aSpace); 480 SDL_Rect aSpace = {240 - (text->w / 2), 240 - (text->h / 2), text->w,
503 SDL_FreeSurface(text); 481 text->h};
504 482 SDL_BlitSurface(text, NULL, list_s, &aSpace);
505 SDL_Surface* title = TTF_RenderText_Blended(loadFont(40), "Highscore List", fontColor); 483 SDL_FreeSurface(text);
506 SDL_Rect tSpace = {240-(title->w/2), 0, title->w, title->h}; 484
507 SDL_BlitSurface(title, NULL, list_s, &tSpace); 485 SDL_Surface* title =
508 SDL_FreeSurface(title); 486 TTF_RenderText_Blended(loadFont(40), "Highscore List", fontColor);
509 487 SDL_Rect tSpace = {240 - (title->w / 2), 0, title->w, title->h};
510 SDL_Surface* options_s = SDL_LoadBMP("resources/hlo_rtm.bmp"); 488 SDL_BlitSurface(title, NULL, list_s, &tSpace);
511 SDL_Rect oSpace = {0, 440, options_s->w, options_s->h}; 489 SDL_FreeSurface(title);
512 SDL_BlitSurface(options_s, NULL, list_s, &oSpace); 490
513 SDL_FreeSurface(options_s); 491 SDL_Surface* options_s = SDL_LoadBMP("resources/hlo_rtm.bmp");
514 492 SDL_Rect oSpace = {0, 440, options_s->w, options_s->h};
515 list = SDL_CreateTextureFromSurface(renderer, list_s); 493 SDL_BlitSurface(options_s, NULL, list_s, &oSpace);
516 SDL_FreeSurface(list_s); 494 SDL_FreeSurface(options_s);
517 495
518 m = SDL_CreateMutex(); 496 list = SDL_CreateTextureFromSurface(renderer, list_s);
519 497 SDL_FreeSurface(list_s);
520 // Start downloading scores 498
521 SDL_CreateThread(&LoadHighscoreList, "LoadHighscoreList", this); 499 m = SDL_CreateMutex();
522 500
523 // Parse keyboard events 501 // Start downloading scores
524 SDL_Event e; 502 SDL_CreateThread(&LoadHighscoreList, "LoadHighscoreList", this);
525 503
526 for (;;) 504 // Parse keyboard events
527 { 505 SDL_Event e;
528 if (SDL_LockMutex(m) == 0) 506
529 { 507 for (;;) {
530 if (lhl != NULL) 508 if (SDL_LockMutex(m) == 0) {
531 { 509 if (lhl != NULL) {
532 SDL_Surface* list_s = lhl->render(); 510 SDL_Surface* list_s = lhl->render();
533 511
534 SDL_Color fontColor = {0, 0, 0, 0}; 512 SDL_Color fontColor = {0, 0, 0, 0};
535 SDL_Surface* title = TTF_RenderText_Blended(loadFont(40), "Highscore List", fontColor); 513 SDL_Surface* title =
536 SDL_Rect tSpace = {240-(title->w/2), 0, title->w, title->h}; 514 TTF_RenderText_Blended(loadFont(40), "Highscore List", fontColor);
537 SDL_BlitSurface(title, NULL, list_s, &tSpace); 515 SDL_Rect tSpace = {240 - (title->w / 2), 0, title->w, title->h};
538 SDL_FreeSurface(title); 516 SDL_BlitSurface(title, NULL, list_s, &tSpace);
539 517 SDL_FreeSurface(title);
540 SDL_Surface* options_s = SDL_LoadBMP("resources/hlo_rtm.bmp"); 518
541 SDL_Rect oSpace = {0, 440, options_s->w, options_s->h}; 519 SDL_Surface* options_s = SDL_LoadBMP("resources/hlo_rtm.bmp");
542 SDL_BlitSurface(options_s, NULL, list_s, &oSpace); 520 SDL_Rect oSpace = {0, 440, options_s->w, options_s->h};
543 SDL_FreeSurface(options_s); 521 SDL_BlitSurface(options_s, NULL, list_s, &oSpace);
544 522 SDL_FreeSurface(options_s);
545 list = SDL_CreateTextureFromSurface(renderer, list_s); 523
546 SDL_FreeSurface(list_s); 524 list = SDL_CreateTextureFromSurface(renderer, list_s);
547 525 SDL_FreeSurface(list_s);
548 lhl = NULL; 526
549 } 527 lhl = NULL;
550 528 }
551 SDL_UnlockMutex(m); 529
552 } 530 SDL_UnlockMutex(m);
553 531 }
554 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); 532
555 SDL_RenderClear(renderer); 533 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
556 SDL_RenderCopy(renderer, list, NULL, NULL); 534 SDL_RenderClear(renderer);
557 applyTexture(renderer, pointer, 137, 449); 535 SDL_RenderCopy(renderer, list, NULL, NULL);
558 SDL_RenderPresent(renderer); 536 applyTexture(renderer, pointer, 137, 449);
559 537 SDL_RenderPresent(renderer);
560 while (SDL_PollEvent(&e)) 538
561 { 539 while (SDL_PollEvent(&e)) {
562 if (e.type == SDL_QUIT) 540 if (e.type == SDL_QUIT) {
563 { 541 SDL_DestroyMutex(m);
564 SDL_DestroyMutex(m); 542
565 543 return NULL;
566 return NULL; 544 } else if (e.type == SDL_KEYDOWN) {
567 } else if (e.type == SDL_KEYDOWN) 545 if (e.key.keysym.sym == SDLK_RETURN) {
568 { 546 SDL_DestroyMutex(m);
569 if (e.key.keysym.sym == SDLK_RETURN) 547
570 { 548 return new ChooseHighscoreListState();
571 SDL_DestroyMutex(m); 549 }
572 550 }
573 return new ChooseHighscoreListState(); 551 }
574 } 552 }
575 }
576 }
577 }
578} 553}
579 554
580int DisplayGlobalHighscoreListState::LoadHighscoreList(void* pParam) 555int DisplayGlobalHighscoreListState::LoadHighscoreList(void* pParam) {
581{ 556 DisplayGlobalHighscoreListState* parent =
582 DisplayGlobalHighscoreListState* parent = ((DisplayGlobalHighscoreListState*)pParam); 557 ((DisplayGlobalHighscoreListState*)pParam);
583 if (SDL_LockMutex(parent->m) == 0) 558 if (SDL_LockMutex(parent->m) == 0) {
584 { 559 parent->lhl = new GlobalHighscoreList();
585 parent->lhl = new GlobalHighscoreList();
586
587 SDL_UnlockMutex(parent->m);
588 } else {
589 printf("Couldn't lock mutex: %s\n", SDL_GetError());
590 }
591}
592
593EnterHighscoreState::EnterHighscoreState(int level)
594{
595 this->level = level;
596}
597 560
598State* EnterHighscoreState::operator() (SDL_Window* window, SDL_Renderer* renderer) 561 SDL_UnlockMutex(parent->m);
599{ 562 } else {
600 SDL_Texture* pointer = loadImage(renderer, "resources/pointer.bmp"); 563 printf("Couldn't lock mutex: %s\n", SDL_GetError());
601 564 }
602 // Render highscore list
603 LocalHighscoreList* lhl = new LocalHighscoreList();
604 char* emp = new char[1];
605 emp[0] = 0;
606 Highscore* h = new Highscore(emp, level);
607 int newpos = lhl->addHighscore(h);
608
609 SDL_Surface* list_s = lhl->render();
610
611 SDL_Color fontColor = {0, 0, 0, 0};
612 SDL_Surface* title = TTF_RenderText_Blended(loadFont(40), "New Highscore!", fontColor);
613 SDL_Rect tSpace = {240-(title->w/2), 0, title->w, title->h};
614 SDL_BlitSurface(title, NULL, list_s, &tSpace);
615 SDL_FreeSurface(title);
616
617 this->lp = 0;
618 this->hsname = (char*) calloc(25, sizeof(char));
619
620 SDL_Surface* text = TTF_RenderText_Blended(loadFont(25), "Enter Your Name", fontColor);
621 SDL_Rect oSpace = {240-(text->w/2), 440, text->w, text->h};
622 SDL_BlitSurface(text, NULL, list_s, &oSpace);
623 SDL_FreeSurface(text);
624
625 SDL_Texture* list = SDL_CreateTextureFromSurface(renderer, list_s);
626 SDL_FreeSurface(list_s);
627
628 int selection = 0;
629 SDL_Event e;
630
631 int posw, posh;
632 char pos[3]; // 2 max characters in rank plus the colon at the end
633 sprintf(pos, "%d:", newpos);
634 char name[26]; // 25 max characters in username plus the space at the beginning
635 sprintf(name, " %s", hsname);
636 SDL_Surface* newName_s = TTF_RenderText_Blended(loadFont(25), name, fontColor);
637 TTF_SizeText(loadFont(40), pos, &posw, &posh);
638 SDL_Rect rntSpace;
639 rntSpace.x = posw;
640 rntSpace.y = newpos*40+((posh/2)-(newName_s->h/2));
641 rntSpace.w = newName_s->w;
642 rntSpace.h = newName_s->h;
643 newName = SDL_CreateTextureFromSurface(renderer, newName_s);
644 SDL_FreeSurface(newName_s);
645
646 for (;;)
647 {
648 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
649 SDL_RenderClear(renderer);
650
651 SDL_Rect eSpace = {0, newpos*40, 480, 40};
652 SDL_SetRenderDrawColor(renderer, 255, 255, 0, 255);
653 SDL_RenderFillRect(renderer, &eSpace);
654
655 SDL_RenderCopy(renderer, list, NULL, NULL);
656 SDL_RenderCopy(renderer, newName, NULL, &rntSpace);
657
658 SDL_RenderPresent(renderer);
659
660 while (SDL_PollEvent(&e))
661 {
662 if (e.type == SDL_QUIT)
663 {
664 return NULL;
665 } else if (e.type == SDL_KEYDOWN)
666 {
667 if ((e.key.keysym.sym == SDLK_BACKSPACE) && (lp > 0))
668 {
669 hsname[--lp] = 0;
670
671 SDL_Color fontColor = {0, 0, 0, 0};
672 char name[26]; // 25 max characters in username plus the space at the beginning
673 sprintf(name, " %s", hsname);
674 newName_s = TTF_RenderText_Blended(loadFont(25), name, fontColor);
675 rntSpace.w = newName_s->w;
676 rntSpace.h = newName_s->h;
677 newName = SDL_CreateTextureFromSurface(renderer, newName_s);
678 SDL_FreeSurface(newName_s);
679 } else if ((e.key.keysym.sym == SDLK_RETURN) && (hsname[0] != 0))
680 {
681 lhl = new LocalHighscoreList();
682 Highscore* h2 = new Highscore(hsname, level);
683 lhl->addHighscore(h2);
684 lhl->writeHighscores();
685
686 return new NewHighscoreState(h2);
687 }
688 } else if (e.type == SDL_TEXTINPUT)
689 {
690 if (((*e.text.text & 0xFF80) == 0) && (*e.text.text >= 32 && *e.text.text < 127) && (lp < 25))
691 {
692 hsname[lp++] = *e.text.text & 0x7f;
693 hsname[lp] = 0;
694
695 SDL_Color fontColor = {0, 0, 0, 0};
696 char name[26]; // 25 max characters in username plus the space at the beginning
697 sprintf(name, " %s", hsname);
698 newName_s = TTF_RenderText_Blended(loadFont(25), name, fontColor);
699 rntSpace.w = newName_s->w;
700 rntSpace.h = newName_s->h;
701 newName = SDL_CreateTextureFromSurface(renderer, newName_s);
702 SDL_FreeSurface(newName_s);
703 }
704 }
705 }
706 }
707} 565}
708 566
709NewHighscoreState::NewHighscoreState(Highscore* h) 567EnterHighscoreState::EnterHighscoreState(int level) { this->level = level; }
710{ 568
711 this->h = h; 569State* EnterHighscoreState::operator()(SDL_Window* window,
570 SDL_Renderer* renderer) {
571 SDL_Texture* pointer = loadImage(renderer, "resources/pointer.bmp");
572
573 // Render highscore list
574 LocalHighscoreList* lhl = new LocalHighscoreList();
575 char* emp = new char[1];
576 emp[0] = 0;
577 Highscore* h = new Highscore(emp, level);
578 int newpos = lhl->addHighscore(h);
579
580 SDL_Surface* list_s = lhl->render();
581
582 SDL_Color fontColor = {0, 0, 0, 0};
583 SDL_Surface* title =
584 TTF_RenderText_Blended(loadFont(40), "New Highscore!", fontColor);
585 SDL_Rect tSpace = {240 - (title->w / 2), 0, title->w, title->h};
586 SDL_BlitSurface(title, NULL, list_s, &tSpace);
587 SDL_FreeSurface(title);
588
589 this->lp = 0;
590 this->hsname = (char*)calloc(25, sizeof(char));
591
592 SDL_Surface* text =
593 TTF_RenderText_Blended(loadFont(25), "Enter Your Name", fontColor);
594 SDL_Rect oSpace = {240 - (text->w / 2), 440, text->w, text->h};
595 SDL_BlitSurface(text, NULL, list_s, &oSpace);
596 SDL_FreeSurface(text);
597
598 SDL_Texture* list = SDL_CreateTextureFromSurface(renderer, list_s);
599 SDL_FreeSurface(list_s);
600
601 int selection = 0;
602 SDL_Event e;
603
604 int posw, posh;
605 char pos[3]; // 2 max characters in rank plus the colon at the end
606 sprintf(pos, "%d:", newpos);
607 char name[26]; // 25 max characters in username plus the space at the
608 // beginning
609 sprintf(name, " %s", hsname);
610 SDL_Surface* newName_s =
611 TTF_RenderText_Blended(loadFont(25), name, fontColor);
612 TTF_SizeText(loadFont(40), pos, &posw, &posh);
613 SDL_Rect rntSpace;
614 rntSpace.x = posw;
615 rntSpace.y = newpos * 40 + ((posh / 2) - (newName_s->h / 2));
616 rntSpace.w = newName_s->w;
617 rntSpace.h = newName_s->h;
618 newName = SDL_CreateTextureFromSurface(renderer, newName_s);
619 SDL_FreeSurface(newName_s);
620
621 for (;;) {
622 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
623 SDL_RenderClear(renderer);
624
625 SDL_Rect eSpace = {0, newpos * 40, 480, 40};
626 SDL_SetRenderDrawColor(renderer, 255, 255, 0, 255);
627 SDL_RenderFillRect(renderer, &eSpace);
628
629 SDL_RenderCopy(renderer, list, NULL, NULL);
630 SDL_RenderCopy(renderer, newName, NULL, &rntSpace);
631
632 SDL_RenderPresent(renderer);
633
634 while (SDL_PollEvent(&e)) {
635 if (e.type == SDL_QUIT) {
636 return NULL;
637 } else if (e.type == SDL_KEYDOWN) {
638 if ((e.key.keysym.sym == SDLK_BACKSPACE) && (lp > 0)) {
639 hsname[--lp] = 0;
640
641 SDL_Color fontColor = {0, 0, 0, 0};
642 char name[26]; // 25 max characters in username plus the space at the
643 // beginning
644 sprintf(name, " %s", hsname);
645 newName_s = TTF_RenderText_Blended(loadFont(25), name, fontColor);
646 rntSpace.w = newName_s->w;
647 rntSpace.h = newName_s->h;
648 newName = SDL_CreateTextureFromSurface(renderer, newName_s);
649 SDL_FreeSurface(newName_s);
650 } else if ((e.key.keysym.sym == SDLK_RETURN) && (hsname[0] != 0)) {
651 lhl = new LocalHighscoreList();
652 Highscore* h2 = new Highscore(hsname, level);
653 lhl->addHighscore(h2);
654 lhl->writeHighscores();
655
656 return new NewHighscoreState(h2);
657 }
658 } else if (e.type == SDL_TEXTINPUT) {
659 if (((*e.text.text & 0xFF80) == 0) &&
660 (*e.text.text >= 32 && *e.text.text < 127) && (lp < 25)) {
661 hsname[lp++] = *e.text.text & 0x7f;
662 hsname[lp] = 0;
663
664 SDL_Color fontColor = {0, 0, 0, 0};
665 char name[26]; // 25 max characters in username plus the space at the
666 // beginning
667 sprintf(name, " %s", hsname);
668 newName_s = TTF_RenderText_Blended(loadFont(25), name, fontColor);
669 rntSpace.w = newName_s->w;
670 rntSpace.h = newName_s->h;
671 newName = SDL_CreateTextureFromSurface(renderer, newName_s);
672 SDL_FreeSurface(newName_s);
673 }
674 }
675 }
676 }
712} 677}
713 678
714State* NewHighscoreState::operator() (SDL_Window* window, SDL_Renderer* renderer) 679NewHighscoreState::NewHighscoreState(Highscore* h) { this->h = h; }
715{ 680
716 SDL_Texture* pointer = loadImage(renderer, "resources/pointer.bmp"); 681State* NewHighscoreState::operator()(SDL_Window* window,
717 682 SDL_Renderer* renderer) {
718 // Render highscore list 683 SDL_Texture* pointer = loadImage(renderer, "resources/pointer.bmp");
719 LocalHighscoreList* lhl = new LocalHighscoreList(); 684
720 SDL_Surface* list_s = lhl->render(); 685 // Render highscore list
721 686 LocalHighscoreList* lhl = new LocalHighscoreList();
722 SDL_Color fontColor = {0, 0, 0, 0}; 687 SDL_Surface* list_s = lhl->render();
723 SDL_Surface* title = TTF_RenderText_Blended(loadFont(40), "New Highscore!", fontColor); 688
724 SDL_Rect tSpace = {240-(title->w/2), 0, title->w, title->h}; 689 SDL_Color fontColor = {0, 0, 0, 0};
725 SDL_BlitSurface(title, NULL, list_s, &tSpace); 690 SDL_Surface* title =
726 SDL_FreeSurface(title); 691 TTF_RenderText_Blended(loadFont(40), "New Highscore!", fontColor);
727 692 SDL_Rect tSpace = {240 - (title->w / 2), 0, title->w, title->h};
728 SDL_Surface* options_s = SDL_LoadBMP("resources/hlo_passartm.bmp"); 693 SDL_BlitSurface(title, NULL, list_s, &tSpace);
729 SDL_Rect oSpace = {0, 440, options_s->w, options_s->h}; 694 SDL_FreeSurface(title);
730 SDL_BlitSurface(options_s, NULL, list_s, &oSpace); 695
731 SDL_FreeSurface(options_s); 696 SDL_Surface* options_s = SDL_LoadBMP("resources/hlo_passartm.bmp");
732 697 SDL_Rect oSpace = {0, 440, options_s->w, options_s->h};
733 SDL_Texture* list = SDL_CreateTextureFromSurface(renderer, list_s); 698 SDL_BlitSurface(options_s, NULL, list_s, &oSpace);
734 SDL_FreeSurface(list_s); 699 SDL_FreeSurface(options_s);
735 700
736 int selection = 0; 701 SDL_Texture* list = SDL_CreateTextureFromSurface(renderer, list_s);
737 SDL_Event e; 702 SDL_FreeSurface(list_s);
738 703
739 for (;;) 704 int selection = 0;
740 { 705 SDL_Event e;
741 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); 706
742 SDL_RenderClear(renderer); 707 for (;;) {
743 708 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
744 SDL_Rect eSpace = {0, h->getRank()*40, 480, 40}; 709 SDL_RenderClear(renderer);
745 SDL_SetRenderDrawColor(renderer, 255, 255, 0, 255); 710
746 SDL_RenderFillRect(renderer, &eSpace); 711 SDL_Rect eSpace = {0, h->getRank() * 40, 480, 40};
747 712 SDL_SetRenderDrawColor(renderer, 255, 255, 0, 255);
748 SDL_RenderCopy(renderer, list, NULL, NULL); 713 SDL_RenderFillRect(renderer, &eSpace);
749 applyTexture(renderer, pointer, selection==0?13:(selection==1?138:284), 448); 714
750 SDL_RenderPresent(renderer); 715 SDL_RenderCopy(renderer, list, NULL, NULL);
751 716 applyTexture(renderer, pointer,
752 while (SDL_PollEvent(&e)) 717 selection == 0 ? 13 : (selection == 1 ? 138 : 284), 448);
753 { 718 SDL_RenderPresent(renderer);
754 if (e.type == SDL_QUIT) 719
755 { 720 while (SDL_PollEvent(&e)) {
756 return NULL; 721 if (e.type == SDL_QUIT) {
757 } else if (e.type == SDL_KEYDOWN) 722 return NULL;
758 { 723 } else if (e.type == SDL_KEYDOWN) {
759 if ((e.key.keysym.sym == SDLK_LEFT) && (selection != 0)) 724 if ((e.key.keysym.sym == SDLK_LEFT) && (selection != 0)) {
760 { 725 selection--;
761 selection--; 726 } else if ((e.key.keysym.sym == SDLK_RIGHT) && (selection != 2)) {
762 } else if ((e.key.keysym.sym == SDLK_RIGHT) && (selection != 2)) 727 selection++;
763 { 728 } else if (e.key.keysym.sym == SDLK_RETURN) {
764 selection++; 729 switch (selection) {
765 } else if (e.key.keysym.sym == SDLK_RETURN) 730 case 0:
766 { 731 return new GameState();
767 switch (selection) 732 case 1:
768 { 733 return new SubmitHighscoreState(h);
769 case 0: return new GameState(); 734 case 2:
770 case 1: return new SubmitHighscoreState(h); 735 return new TitleState();
771 case 2: return new TitleState(); 736 }
772 } 737 }
773 } 738 }
774 } 739 }
775 } 740 }
776 }
777} 741}
778 742
779SubmitHighscoreState::SubmitHighscoreState(Highscore* h) 743SubmitHighscoreState::SubmitHighscoreState(Highscore* h) { this->h = h; }
780{ 744
781 this->h = h; 745State* SubmitHighscoreState::operator()(SDL_Window* window,
746 SDL_Renderer* renderer) {
747 SDL_Surface* list_s = SDL_CreateRGBSurface(0, 480, 480, 32, 0, 0, 0, 0);
748 Uint32 bgColor = SDL_MapRGB(list_s->format, 255, 255, 255);
749 SDL_FillRect(list_s, NULL, bgColor);
750 SDL_SetColorKey(list_s, SDL_TRUE, bgColor);
751 TTF_Font* dataFont = loadFont(25);
752 SDL_Color fontColor = {0, 0, 0, 0};
753 SDL_Surface* text =
754 TTF_RenderText_Blended(dataFont, "Sending highscore....", fontColor);
755 SDL_Rect aSpace = {240 - (text->w / 2), 240 - (text->h / 2), text->w,
756 text->h};
757 SDL_BlitSurface(text, NULL, list_s, &aSpace);
758 SDL_FreeSurface(text);
759
760 SDL_Surface* title =
761 TTF_RenderText_Blended(loadFont(40), "Highscore List", fontColor);
762 SDL_Rect tSpace = {240 - (title->w / 2), 0, title->w, title->h};
763 SDL_BlitSurface(title, NULL, list_s, &tSpace);
764 SDL_FreeSurface(title);
765
766 SDL_Texture* list = SDL_CreateTextureFromSurface(renderer, list_s);
767 SDL_FreeSurface(list_s);
768
769 // Start submitting score
770 m = SDL_CreateMutex();
771 SDL_CreateThread(&SubmitHighscore, "SubmitHighscore", this);
772
773 SDL_Event e;
774
775 for (;;) {
776 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
777 SDL_RenderClear(renderer);
778 SDL_RenderCopy(renderer, list, NULL, NULL);
779 SDL_RenderPresent(renderer);
780
781 if (SDL_LockMutex(m) == 0) {
782 if (lhl != NULL) {
783 SDL_UnlockMutex(m);
784 SDL_DestroyMutex(m);
785
786 if (lhl->didFail()) {
787 return new FailedSubmittingHighscoreState(h);
788 } else {
789 return new SubmittedHighscoreState(lhl, h);
790 }
791 } else {
792 SDL_UnlockMutex(m);
793 }
794 }
795
796 while (SDL_PollEvent(&e)) {
797 if (e.type == SDL_QUIT) {
798 SDL_DestroyMutex(m);
799
800 return NULL;
801 }
802 }
803 }
782} 804}
783 805
784State* SubmitHighscoreState::operator() (SDL_Window* window, SDL_Renderer* renderer) 806int SubmitHighscoreState::SubmitHighscore(void* pParam) {
785{ 807 SubmitHighscoreState* parent = (SubmitHighscoreState*)pParam;
786 SDL_Surface* list_s = SDL_CreateRGBSurface(0, 480, 480, 32, 0,0,0,0); 808 if (SDL_LockMutex(parent->m) == 0) {
787 Uint32 bgColor = SDL_MapRGB(list_s->format, 255, 255, 255); 809 parent->lhl = new GlobalHighscoreList(parent->h);
788 SDL_FillRect(list_s, NULL, bgColor);
789 SDL_SetColorKey(list_s, SDL_TRUE, bgColor);
790 TTF_Font* dataFont = loadFont(25);
791 SDL_Color fontColor = {0, 0, 0, 0};
792 SDL_Surface* text = TTF_RenderText_Blended(dataFont, "Sending highscore....", fontColor);
793 SDL_Rect aSpace = {240-(text->w/2), 240-(text->h/2), text->w, text->h};
794 SDL_BlitSurface(text, NULL, list_s, &aSpace);
795 SDL_FreeSurface(text);
796
797 SDL_Surface* title = TTF_RenderText_Blended(loadFont(40), "Highscore List", fontColor);
798 SDL_Rect tSpace = {240-(title->w/2), 0, title->w, title->h};
799 SDL_BlitSurface(title, NULL, list_s, &tSpace);
800 SDL_FreeSurface(title);
801
802 SDL_Texture* list = SDL_CreateTextureFromSurface(renderer, list_s);
803 SDL_FreeSurface(list_s);
804
805 // Start submitting score
806 m = SDL_CreateMutex();
807 SDL_CreateThread(&SubmitHighscore, "SubmitHighscore", this);
808
809 SDL_Event e;
810
811 for (;;)
812 {
813 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
814 SDL_RenderClear(renderer);
815 SDL_RenderCopy(renderer, list, NULL, NULL);
816 SDL_RenderPresent(renderer);
817
818 if (SDL_LockMutex(m) == 0)
819 {
820 if (lhl != NULL)
821 {
822 SDL_UnlockMutex(m);
823 SDL_DestroyMutex(m);
824
825 if (lhl->didFail())
826 {
827 return new FailedSubmittingHighscoreState(h);
828 } else {
829 return new SubmittedHighscoreState(lhl, h);
830 }
831 } else {
832 SDL_UnlockMutex(m);
833 }
834 }
835
836 while (SDL_PollEvent(&e))
837 {
838 if (e.type == SDL_QUIT)
839 {
840 SDL_DestroyMutex(m);
841
842 return NULL;
843 }
844 }
845 }
846}
847 810
848int SubmitHighscoreState::SubmitHighscore(void* pParam) 811 SDL_UnlockMutex(parent->m);
849{ 812 } else {
850 SubmitHighscoreState* parent = (SubmitHighscoreState*) pParam; 813 printf("Could not lock mutex: %s\n", SDL_GetError());
851 if (SDL_LockMutex(parent->m) == 0) 814 }
852 {
853 parent->lhl = new GlobalHighscoreList(parent->h);
854
855 SDL_UnlockMutex(parent->m);
856 } else {
857 printf("Could not lock mutex: %s\n", SDL_GetError());
858 }
859} 815}
860 816
861FailedSubmittingHighscoreState::FailedSubmittingHighscoreState(Highscore* h) 817FailedSubmittingHighscoreState::FailedSubmittingHighscoreState(Highscore* h) {
862{ 818 this->h = h;
863 this->h = h;
864} 819}
865 820
866State* FailedSubmittingHighscoreState::operator() (SDL_Window* window, SDL_Renderer* renderer) 821State* FailedSubmittingHighscoreState::operator()(SDL_Window* window,
867{ 822 SDL_Renderer* renderer) {
868 SDL_Surface* list_s = SDL_CreateRGBSurface(0, 480, 480, 32, 0,0,0,0); 823 SDL_Surface* list_s = SDL_CreateRGBSurface(0, 480, 480, 32, 0, 0, 0, 0);
869 Uint32 bgColor = SDL_MapRGB(list_s->format, 255, 255, 255); 824 Uint32 bgColor = SDL_MapRGB(list_s->format, 255, 255, 255);
870 SDL_FillRect(list_s, NULL, bgColor); 825 SDL_FillRect(list_s, NULL, bgColor);
871 SDL_SetColorKey(list_s, SDL_TRUE, bgColor); 826 SDL_SetColorKey(list_s, SDL_TRUE, bgColor);
872 TTF_Font* dataFont = loadFont(25); 827 TTF_Font* dataFont = loadFont(25);
873 SDL_Color fontColor = {0, 0, 0, 0}; 828 SDL_Color fontColor = {0, 0, 0, 0};
874 SDL_Surface* text = TTF_RenderText_Blended(dataFont, "Error submitting highscores", fontColor); 829 SDL_Surface* text = TTF_RenderText_Blended(
875 SDL_Rect tSpace = {240-(text->w/2), 240-(text->h/2), text->w, text->h}; 830 dataFont, "Error submitting highscores", fontColor);
876 SDL_BlitSurface(text, NULL, list_s, &tSpace); 831 SDL_Rect tSpace = {240 - (text->w / 2), 240 - (text->h / 2), text->w,
877 SDL_FreeSurface(text); 832 text->h};
878 833 SDL_BlitSurface(text, NULL, list_s, &tSpace);
879 SDL_Surface* title = TTF_RenderText_Blended(loadFont(40), "Highscore List", fontColor); 834 SDL_FreeSurface(text);
880 SDL_Rect aSpace = {240-(title->w/2), 0, title->w, title->h}; 835
881 SDL_BlitSurface(title, NULL, list_s, &aSpace); 836 SDL_Surface* title =
882 SDL_FreeSurface(title); 837 TTF_RenderText_Blended(loadFont(40), "Highscore List", fontColor);
883 838 SDL_Rect aSpace = {240 - (title->w / 2), 0, title->w, title->h};
884 SDL_Surface* options_s = SDL_LoadBMP("resources/hlo_passartm.bmp"); 839 SDL_BlitSurface(title, NULL, list_s, &aSpace);
885 SDL_Rect oSpace = {0, 440, options_s->w, options_s->h}; 840 SDL_FreeSurface(title);
886 SDL_BlitSurface(options_s, NULL, list_s, &oSpace); 841
887 SDL_FreeSurface(options_s); 842 SDL_Surface* options_s = SDL_LoadBMP("resources/hlo_passartm.bmp");
888 843 SDL_Rect oSpace = {0, 440, options_s->w, options_s->h};
889 SDL_Texture* list = SDL_CreateTextureFromSurface(renderer, list_s); 844 SDL_BlitSurface(options_s, NULL, list_s, &oSpace);
890 SDL_FreeSurface(list_s); 845 SDL_FreeSurface(options_s);
891 846
892 SDL_Texture* pointer = loadImage(renderer, "resources/pointer.bmp"); 847 SDL_Texture* list = SDL_CreateTextureFromSurface(renderer, list_s);
893 int selection = 0; 848 SDL_FreeSurface(list_s);
894 SDL_Event e; 849
895 850 SDL_Texture* pointer = loadImage(renderer, "resources/pointer.bmp");
896 for (;;) 851 int selection = 0;
897 { 852 SDL_Event e;
898 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); 853
899 SDL_RenderClear(renderer); 854 for (;;) {
900 SDL_RenderCopy(renderer, list, NULL, NULL); 855 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
901 applyTexture(renderer, pointer, selection==0?13:(selection==1?138:284), 448); 856 SDL_RenderClear(renderer);
902 SDL_RenderPresent(renderer); 857 SDL_RenderCopy(renderer, list, NULL, NULL);
903 858 applyTexture(renderer, pointer,
904 while (SDL_PollEvent(&e)) 859 selection == 0 ? 13 : (selection == 1 ? 138 : 284), 448);
905 { 860 SDL_RenderPresent(renderer);
906 if (e.type == SDL_QUIT) 861
907 { 862 while (SDL_PollEvent(&e)) {
908 return NULL; 863 if (e.type == SDL_QUIT) {
909 } else if (e.type == SDL_KEYDOWN) 864 return NULL;
910 { 865 } else if (e.type == SDL_KEYDOWN) {
911 if ((e.key.keysym.sym == SDLK_LEFT) && (selection != 0)) 866 if ((e.key.keysym.sym == SDLK_LEFT) && (selection != 0)) {
912 { 867 selection--;
913 selection--; 868 } else if ((e.key.keysym.sym == SDLK_RIGHT) && (selection != 2)) {
914 } else if ((e.key.keysym.sym == SDLK_RIGHT) && (selection != 2)) 869 selection++;
915 { 870 } else if (e.key.keysym.sym == SDLK_RETURN) {
916 selection++; 871 switch (selection) {
917 } else if (e.key.keysym.sym == SDLK_RETURN) 872 case 0:
918 { 873 return new GameState();
919 switch (selection) 874 case 1:
920 { 875 return new SubmitHighscoreState(h);
921 case 0: return new GameState(); 876 case 2:
922 case 1: return new SubmitHighscoreState(h); 877 return new TitleState();
923 case 2: return new TitleState(); 878 }
924 } 879 }
925 } 880 }
926 } 881 }
927 } 882 }
928 }
929} 883}
930 884
931SubmittedHighscoreState::SubmittedHighscoreState(GlobalHighscoreList* lhl, Highscore* h) 885SubmittedHighscoreState::SubmittedHighscoreState(GlobalHighscoreList* lhl,
932{ 886 Highscore* h) {
933 this->lhl = lhl; 887 this->lhl = lhl;
934 this->h = h; 888 this->h = h;
935} 889}
936 890
937State* SubmittedHighscoreState::operator() (SDL_Window* window, SDL_Renderer* renderer) 891State* SubmittedHighscoreState::operator()(SDL_Window* window,
938{ 892 SDL_Renderer* renderer) {
939 SDL_Surface* list_s = lhl->render(); 893 SDL_Surface* list_s = lhl->render();
940 894
941 SDL_Color fontColor = {0, 0, 0, 0}; 895 SDL_Color fontColor = {0, 0, 0, 0};
942 SDL_Surface* title = TTF_RenderText_Blended(loadFont(40), "Highscore List", fontColor); 896 SDL_Surface* title =
943 SDL_Rect tSpace = {240-(title->w/2), 0, title->w, title->h}; 897 TTF_RenderText_Blended(loadFont(40), "Highscore List", fontColor);
944 SDL_BlitSurface(title, NULL, list_s, &tSpace); 898 SDL_Rect tSpace = {240 - (title->w / 2), 0, title->w, title->h};
945 SDL_FreeSurface(title); 899 SDL_BlitSurface(title, NULL, list_s, &tSpace);
946 900 SDL_FreeSurface(title);
947 SDL_Surface* options_s = SDL_LoadBMP("resources/hlo_paartm.bmp"); 901
948 SDL_Rect oSpace = {0, 440, options_s->w, options_s->h}; 902 SDL_Surface* options_s = SDL_LoadBMP("resources/hlo_paartm.bmp");
949 SDL_BlitSurface(options_s, NULL, list_s, &oSpace); 903 SDL_Rect oSpace = {0, 440, options_s->w, options_s->h};
950 SDL_FreeSurface(options_s); 904 SDL_BlitSurface(options_s, NULL, list_s, &oSpace);
951 905 SDL_FreeSurface(options_s);
952 SDL_Texture* list = SDL_CreateTextureFromSurface(renderer, list_s); 906
953 SDL_FreeSurface(list_s); 907 SDL_Texture* list = SDL_CreateTextureFromSurface(renderer, list_s);
954 908 SDL_FreeSurface(list_s);
955 SDL_Texture* pointer = loadImage(renderer, "resources/pointer.bmp"); 909
956 int selection = 0; 910 SDL_Texture* pointer = loadImage(renderer, "resources/pointer.bmp");
957 SDL_Event e; 911 int selection = 0;
958 912 SDL_Event e;
959 int newpos = h->getRank(); 913
960 if (newpos > 10) 914 int newpos = h->getRank();
961 { 915 if (newpos > 10) {
962 newpos = 10; 916 newpos = 10;
963 } 917 }
964 918
965 for (;;) 919 for (;;) {
966 { 920 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
967 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); 921 SDL_RenderClear(renderer);
968 SDL_RenderClear(renderer); 922
969 923 SDL_Rect eSpace = {0, newpos * 40, 480, 40};
970 SDL_Rect eSpace = {0, newpos*40, 480, 40}; 924 SDL_SetRenderDrawColor(renderer, 255, 255, 0, 255);
971 SDL_SetRenderDrawColor(renderer, 255, 255, 0, 255); 925 SDL_RenderFillRect(renderer, &eSpace);
972 SDL_RenderFillRect(renderer, &eSpace); 926
973 927 SDL_RenderCopy(renderer, list, NULL, NULL);
974 SDL_RenderCopy(renderer, list, NULL, NULL); 928 applyTexture(renderer, pointer, selection == 0 ? 52 : 225, 447);
975 applyTexture(renderer, pointer, selection==0?52:225, 447); 929 SDL_RenderPresent(renderer);
976 SDL_RenderPresent(renderer); 930
977 931 while (SDL_PollEvent(&e)) {
978 while (SDL_PollEvent(&e)) 932 if (e.type == SDL_QUIT) {
979 { 933 return NULL;
980 if (e.type == SDL_QUIT) 934 } else if (e.type == SDL_KEYDOWN) {
981 { 935 if ((e.key.keysym.sym == SDLK_LEFT) && (selection != 0)) {
982 return NULL; 936 selection--;
983 } else if (e.type == SDL_KEYDOWN) 937 } else if ((e.key.keysym.sym == SDLK_RIGHT) && (selection != 1)) {
984 { 938 selection++;
985 if ((e.key.keysym.sym == SDLK_LEFT) && (selection != 0)) 939 } else if (e.key.keysym.sym == SDLK_RETURN) {
986 { 940 switch (selection) {
987 selection--; 941 case 0:
988 } else if ((e.key.keysym.sym == SDLK_RIGHT) && (selection != 1)) 942 return new GameState();
989 { 943 case 1:
990 selection++; 944 return new TitleState();
991 } else if (e.key.keysym.sym == SDLK_RETURN) 945 }
992 { 946 }
993 switch (selection) 947 }
994 { 948 }
995 case 0: return new GameState(); 949 }
996 case 1: return new TitleState();
997 }
998 }
999 }
1000 }
1001 }
1002} 950}
diff --git a/hslist.h b/hslist.h index 291a526..efffa9d 100644 --- a/hslist.h +++ b/hslist.h
@@ -1,5 +1,7 @@
1#include <SDL.h> 1#include <SDL.h>
2
2#include <vector> 3#include <vector>
4
3#include "highscore.h" 5#include "highscore.h"
4#include "state.h" 6#include "state.h"
5 7
@@ -10,120 +12,119 @@ typedef std::vector<Highscore*> hslist_t;
10 12
11void resetRanks(hslist_t in); 13void resetRanks(hslist_t in);
12 14
13class HighscoreList 15class HighscoreList {
14{ 16 public:
15 public: 17 SDL_Surface* render();
16 SDL_Surface* render();
17 18
18 protected: 19 protected:
19 hslist_t getLocalHighscores(); 20 hslist_t getLocalHighscores();
20 hslist_t getGlobalHighscores(); 21 hslist_t getGlobalHighscores();
21 22
22 hslist_t hslist; 23 hslist_t hslist;
23}; 24};
24 25
25class LocalHighscoreList : public HighscoreList { 26class LocalHighscoreList : public HighscoreList {
26 public: 27 public:
27 LocalHighscoreList(); 28 LocalHighscoreList();
28 int addHighscore(Highscore* h); 29 int addHighscore(Highscore* h);
29 void writeHighscores(); 30 void writeHighscores();
30}; 31};
31 32
32class GlobalHighscoreList : public HighscoreList { 33class GlobalHighscoreList : public HighscoreList {
33 public: 34 public:
34 GlobalHighscoreList(); 35 GlobalHighscoreList();
35 GlobalHighscoreList(Highscore* h); 36 GlobalHighscoreList(Highscore* h);
36 SDL_Surface* render(); 37 SDL_Surface* render();
37 bool didFail(); 38 bool didFail();
38 39
39 private: 40 private:
40 typedef HighscoreList super; 41 typedef HighscoreList super;
41 42
42 protected: 43 protected:
43 bool fail; 44 bool fail;
44}; 45};
45 46
46class ChooseHighscoreListState : public State { 47class ChooseHighscoreListState : public State {
47 public: 48 public:
48 State* operator() (SDL_Window* window, SDL_Renderer* renderer); 49 State* operator()(SDL_Window* window, SDL_Renderer* renderer);
49}; 50};
50 51
51class DisplayLocalHighscoreListState : public State { 52class DisplayLocalHighscoreListState : public State {
52 public: 53 public:
53 State* operator() (SDL_Window* window, SDL_Renderer* renderer); 54 State* operator()(SDL_Window* window, SDL_Renderer* renderer);
54}; 55};
55 56
56class DisplayAndReturnLocalHighscoreListState : public State { 57class DisplayAndReturnLocalHighscoreListState : public State {
57 public: 58 public:
58 State* operator() (SDL_Window* window, SDL_Renderer* renderer); 59 State* operator()(SDL_Window* window, SDL_Renderer* renderer);
59}; 60};
60 61
61class DisplayGlobalHighscoreListState : public State { 62class DisplayGlobalHighscoreListState : public State {
62 public: 63 public:
63 State* operator() (SDL_Window* window, SDL_Renderer* renderer); 64 State* operator()(SDL_Window* window, SDL_Renderer* renderer);
64 65
65 protected: 66 protected:
66 SDL_Surface* list_s; 67 SDL_Surface* list_s;
67 SDL_Texture* list; 68 SDL_Texture* list;
68 GlobalHighscoreList* lhl; 69 GlobalHighscoreList* lhl;
69 SDL_mutex* m; 70 SDL_mutex* m;
70 71
71 private: 72 private:
72 static int LoadHighscoreList(void* pParam); 73 static int LoadHighscoreList(void* pParam);
73}; 74};
74 75
75class EnterHighscoreState : public State { 76class EnterHighscoreState : public State {
76 public: 77 public:
77 EnterHighscoreState(int level); 78 EnterHighscoreState(int level);
78 State* operator() (SDL_Window* window, SDL_Renderer* renderer); 79 State* operator()(SDL_Window* window, SDL_Renderer* renderer);
79 80
80 private: 81 private:
81 int level; 82 int level;
82 int lp; 83 int lp;
83 char* hsname; 84 char* hsname;
84 SDL_Texture* newName; 85 SDL_Texture* newName;
85}; 86};
86 87
87class NewHighscoreState : public State { 88class NewHighscoreState : public State {
88 public: 89 public:
89 NewHighscoreState(Highscore* h); 90 NewHighscoreState(Highscore* h);
90 State* operator() (SDL_Window* window, SDL_Renderer* renderer); 91 State* operator()(SDL_Window* window, SDL_Renderer* renderer);
91 92
92 private: 93 private:
93 Highscore* h; 94 Highscore* h;
94}; 95};
95 96
96class SubmitHighscoreState : public State { 97class SubmitHighscoreState : public State {
97 public: 98 public:
98 SubmitHighscoreState(Highscore* h); 99 SubmitHighscoreState(Highscore* h);
99 State* operator() (SDL_Window* window, SDL_Renderer* renderer); 100 State* operator()(SDL_Window* window, SDL_Renderer* renderer);
100 101
101 protected: 102 protected:
102 Highscore* h; 103 Highscore* h;
103 SDL_mutex* m; 104 SDL_mutex* m;
104 GlobalHighscoreList* lhl; 105 GlobalHighscoreList* lhl;
105 106
106 private: 107 private:
107 static int SubmitHighscore(void* pParam); 108 static int SubmitHighscore(void* pParam);
108}; 109};
109 110
110class FailedSubmittingHighscoreState : public State { 111class FailedSubmittingHighscoreState : public State {
111 public: 112 public:
112 FailedSubmittingHighscoreState(Highscore* h); 113 FailedSubmittingHighscoreState(Highscore* h);
113 State* operator() (SDL_Window* window, SDL_Renderer* renderer); 114 State* operator()(SDL_Window* window, SDL_Renderer* renderer);
114 115
115 private: 116 private:
116 Highscore* h; 117 Highscore* h;
117}; 118};
118 119
119class SubmittedHighscoreState : public State { 120class SubmittedHighscoreState : public State {
120 public: 121 public:
121 SubmittedHighscoreState(GlobalHighscoreList* lhl, Highscore* h); 122 SubmittedHighscoreState(GlobalHighscoreList* lhl, Highscore* h);
122 State* operator() (SDL_Window* window, SDL_Renderer* renderer); 123 State* operator()(SDL_Window* window, SDL_Renderer* renderer);
123 124
124 private: 125 private:
125 GlobalHighscoreList* lhl; 126 GlobalHighscoreList* lhl;
126 Highscore* h; 127 Highscore* h;
127}; 128};
128 129
129#endif 130#endif
diff --git a/mazeoflife.cpp b/mazeoflife.cpp index cf21d2a..952fbdb 100644 --- a/mazeoflife.cpp +++ b/mazeoflife.cpp
@@ -1,61 +1,59 @@
1#include "mazeoflife.h" 1#include "mazeoflife.h"
2
2#include <SDL.h> 3#include <SDL.h>
3#include <SDL_ttf.h>
4#include <SDL_net.h> 4#include <SDL_net.h>
5#include <SDL_ttf.h>
6
5#include <cstdlib> 7#include <cstdlib>
6#include <ctime> 8#include <ctime>
7#include <iostream> 9#include <iostream>
10
8#include "state.h" 11#include "state.h"
9#include "titlestate.h" 12#include "titlestate.h"
10 13
11int main(int argc, char *argv[]) 14int main(int argc, char* argv[]) {
12{ 15 srand(time(NULL));
13 srand(time(NULL)); 16
14 17 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) == -1) {
15 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) == -1) 18 printf("Could not initialize SDL: %s.\n", SDL_GetError());
16 { 19 exit(-1);
17 printf("Could not initialize SDL: %s.\n", SDL_GetError()); 20 }
18 exit(-1); 21
19 } 22 if (TTF_Init() == -1) {
20 23 printf("Could not initialize SDL_ttf: %s.\n", TTF_GetError());
21 if (TTF_Init() == -1) 24 exit(-1);
22 { 25 }
23 printf("Could not initialize SDL_ttf: %s.\n", TTF_GetError()); 26
24 exit(-1); 27 if (SDLNet_Init() == -1) {
25 } 28 printf("Cound not initalize SDL_net: %s.\n", SDLNet_GetError());
26 29 exit(-1);
27 if (SDLNet_Init() == -1) 30 }
28 { 31
29 printf("Cound not initalize SDL_net: %s.\n", SDLNet_GetError()); 32 SDL_Window* window =
30 exit(-1); 33 SDL_CreateWindow("Maze of Life", 100, 100, 480, 480, SDL_WINDOW_SHOWN);
31 } 34 if (window == NULL) {
32 35 std::cout << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
33 SDL_Window* window = SDL_CreateWindow("Maze of Life", 100, 100, 480, 480, SDL_WINDOW_SHOWN); 36 return 1;
34 if (window == NULL) 37 }
35 { 38
36 std::cout << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl; 39 SDL_Surface* icon = SDL_LoadBMP("resources/icon.bmp");
37 return 1; 40 SDL_SetWindowIcon(window, icon);
38 } 41
39 42 SDL_Renderer* renderer = SDL_CreateRenderer(
40 SDL_Surface* icon = SDL_LoadBMP("resources/icon.bmp"); 43 window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
41 SDL_SetWindowIcon(window, icon); 44 if (renderer == NULL) {
42 45 std::cout << "SDL_CreateRenderer Error: " << SDL_GetError() << std::endl;
43 SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); 46 return 1;
44 if (renderer == NULL) 47 }
45 { 48
46 std::cout << "SDL_CreateRenderer Error: " << SDL_GetError() << std::endl; 49 State* state = new TitleState();
47 return 1; 50 while (state != NULL) {
48 } 51 state = (*state)(window, renderer);
49 52 }
50 State* state = new TitleState(); 53
51 while (state != NULL) 54 SDL_DestroyRenderer(renderer);
52 { 55 SDL_DestroyWindow(window);
53 state = (*state)(window, renderer); 56 SDLNet_Quit();
54 } 57 TTF_Quit();
55 58 SDL_Quit();
56 SDL_DestroyRenderer(renderer);
57 SDL_DestroyWindow(window);
58 SDLNet_Quit();
59 TTF_Quit();
60 SDL_Quit();
61} \ No newline at end of file 59} \ No newline at end of file
diff --git a/state.h b/state.h index 5e8c4e7..0d50ab3 100644 --- a/state.h +++ b/state.h
@@ -3,10 +3,11 @@
3#ifndef STATE_H 3#ifndef STATE_H
4#define STATE_H 4#define STATE_H
5 5
6class State 6class State {
7{ 7 public:
8 public: 8 virtual State* operator()(SDL_Window* window, SDL_Renderer* renderer) {
9 virtual State* operator() (SDL_Window* window, SDL_Renderer* renderer) {return NULL;}; 9 return NULL;
10 };
10}; 11};
11 12
12#endif \ No newline at end of file 13#endif \ No newline at end of file
diff --git a/titlestate.cpp b/titlestate.cpp index 014b138..166a55b 100644 --- a/titlestate.cpp +++ b/titlestate.cpp
@@ -1,134 +1,116 @@
1#include "titlestate.h" 1#include "titlestate.h"
2#include "util.h" 2
3#include "gamestate.h" 3#include "gamestate.h"
4#include "hslist.h" 4#include "hslist.h"
5#include "util.h"
5 6
6State* TitleState::operator() (SDL_Window* window, SDL_Renderer* renderer) 7State* TitleState::operator()(SDL_Window* window, SDL_Renderer* renderer) {
7{ 8 SDL_Texture* background = loadImage(renderer, "resources/title.bmp");
8 SDL_Texture* background = loadImage(renderer, "resources/title.bmp"); 9 SDL_Texture* pointer = loadImage(renderer, "resources/pointer.bmp");
9 SDL_Texture* pointer = loadImage(renderer, "resources/pointer.bmp"); 10 int selection = 0;
10 int selection = 0; 11 SDL_Event e;
11 SDL_Event e;
12 12
13 for (;;) 13 for (;;) {
14 { 14 SDL_RenderClear(renderer);
15 SDL_RenderClear(renderer); 15 SDL_RenderCopy(renderer, background, NULL, NULL);
16 SDL_RenderCopy(renderer, background, NULL, NULL); 16 applyTexture(renderer, pointer, 136,
17 applyTexture(renderer, pointer, 136, selection==0?316:(selection==1?350:(selection==2?381:417))); 17 selection == 0
18 SDL_RenderPresent(renderer); 18 ? 316
19 : (selection == 1 ? 350 : (selection == 2 ? 381 : 417)));
20 SDL_RenderPresent(renderer);
19 21
20 while (SDL_PollEvent(&e)) 22 while (SDL_PollEvent(&e)) {
21 { 23 if (e.type == SDL_QUIT) {
22 if (e.type == SDL_QUIT) 24 return NULL;
23 { 25 } else if (e.type == SDL_KEYDOWN) {
24 return NULL; 26 if ((e.key.keysym.sym == SDLK_UP) && (selection != 0)) {
25 } else if (e.type == SDL_KEYDOWN) 27 selection--;
26 { 28 } else if ((e.key.keysym.sym == SDLK_DOWN) && (selection != 3)) {
27 if ((e.key.keysym.sym == SDLK_UP) && (selection != 0)) 29 selection++;
28 { 30 } else if (e.key.keysym.sym == SDLK_RETURN) {
29 selection--; 31 switch (selection) {
30 } else if ((e.key.keysym.sym == SDLK_DOWN) && (selection != 3)) 32 case 0:
31 { 33 return new GameState();
32 selection++; 34 case 1:
33 } else if (e.key.keysym.sym == SDLK_RETURN) 35 return new HowToPlayState();
34 { 36 case 2:
35 switch (selection) 37 return new ChooseHighscoreListState();
36 { 38 case 3:
37 case 0: return new GameState(); 39 return NULL;
38 case 1: return new HowToPlayState(); 40 }
39 case 2: return new ChooseHighscoreListState(); 41 }
40 case 3: return NULL; 42 }
41 } 43 }
42 } 44 }
43 }
44 }
45 }
46} 45}
47 46
48State* HowToPlayState::operator() (SDL_Window* window, SDL_Renderer* renderer) 47State* HowToPlayState::operator()(SDL_Window* window, SDL_Renderer* renderer) {
49{ 48 SDL_Texture* background = loadImage(renderer, "resources/htp1.bmp");
50 SDL_Texture* background = loadImage(renderer, "resources/htp1.bmp"); 49 SDL_Texture* pointer = loadImage(renderer, "resources/pointer.bmp");
51 SDL_Texture* pointer = loadImage(renderer, "resources/pointer.bmp"); 50 int selection = 0;
52 int selection = 0; 51 SDL_Event e;
53 SDL_Event e;
54 52
55 for (;;) 53 for (;;) {
56 { 54 SDL_RenderClear(renderer);
57 SDL_RenderClear(renderer); 55 SDL_RenderCopy(renderer, background, NULL, NULL);
58 SDL_RenderCopy(renderer, background, NULL, NULL); 56 applyTexture(renderer, pointer, selection == 0 ? 74 : 216, 430);
59 applyTexture(renderer, pointer, selection==0?74:216, 430); 57 SDL_RenderPresent(renderer);
60 SDL_RenderPresent(renderer);
61 58
62 while (SDL_PollEvent(&e)) 59 while (SDL_PollEvent(&e)) {
63 { 60 if (e.type == SDL_QUIT) {
64 if (e.type == SDL_QUIT) 61 return NULL;
65 { 62 } else if (e.type == SDL_KEYDOWN) {
66 return NULL; 63 if ((e.key.keysym.sym == SDLK_LEFT) && (selection != 0)) {
67 } else if (e.type == SDL_KEYDOWN) 64 selection--;
68 { 65 } else if ((e.key.keysym.sym == SDLK_RIGHT) && (selection != 1)) {
69 if ((e.key.keysym.sym == SDLK_LEFT) && (selection != 0)) 66 selection++;
70 { 67 } else if (e.key.keysym.sym == SDLK_RETURN) {
71 selection--; 68 switch (selection) {
72 } else if ((e.key.keysym.sym == SDLK_RIGHT) && (selection != 1)) 69 case 0:
73 { 70 return new HowToPlayPageTwoState();
74 selection++;
75 } else if (e.key.keysym.sym == SDLK_RETURN)
76 {
77 switch (selection)
78 {
79 case 0:
80 return new HowToPlayPageTwoState();
81 71
82 break; 72 break;
83 case 1: 73 case 1:
84 return new TitleState(); 74 return new TitleState();
85 } 75 }
86 } 76 }
87 } 77 }
88 } 78 }
89 } 79 }
90} 80}
91 81
92State* HowToPlayPageTwoState::operator() (SDL_Window* window, SDL_Renderer* renderer) 82State* HowToPlayPageTwoState::operator()(SDL_Window* window,
93{ 83 SDL_Renderer* renderer) {
94 SDL_Texture* background = loadImage(renderer, "resources/htp2.bmp"); 84 SDL_Texture* background = loadImage(renderer, "resources/htp2.bmp");
95 SDL_Texture* pointer = loadImage(renderer, "resources/pointer.bmp"); 85 SDL_Texture* pointer = loadImage(renderer, "resources/pointer.bmp");
96 int selection = 0; 86 int selection = 0;
97 SDL_Event e; 87 SDL_Event e;
98 88
99 for (;;) 89 for (;;) {
100 { 90 SDL_RenderClear(renderer);
101 SDL_RenderClear(renderer); 91 SDL_RenderCopy(renderer, background, NULL, NULL);
102 SDL_RenderCopy(renderer, background, NULL, NULL); 92 applyTexture(renderer, pointer, selection == 0 ? 45 : 238, 430);
103 applyTexture(renderer, pointer, selection==0?45:238, 430); 93 SDL_RenderPresent(renderer);
104 SDL_RenderPresent(renderer);
105 94
106 while (SDL_PollEvent(&e)) 95 while (SDL_PollEvent(&e)) {
107 { 96 if (e.type == SDL_QUIT) {
108 if (e.type == SDL_QUIT) 97 return NULL;
109 { 98 } else if (e.type == SDL_KEYDOWN) {
110 return NULL; 99 if ((e.key.keysym.sym == SDLK_LEFT) && (selection != 0)) {
111 } else if (e.type == SDL_KEYDOWN) 100 selection--;
112 { 101 } else if ((e.key.keysym.sym == SDLK_RIGHT) && (selection != 1)) {
113 if ((e.key.keysym.sym == SDLK_LEFT) && (selection != 0)) 102 selection++;
114 { 103 } else if (e.key.keysym.sym == SDLK_RETURN) {
115 selection--; 104 switch (selection) {
116 } else if ((e.key.keysym.sym == SDLK_RIGHT) && (selection != 1)) 105 case 0:
117 { 106 return new HowToPlayState();
118 selection++;
119 } else if (e.key.keysym.sym == SDLK_RETURN)
120 {
121 switch (selection)
122 {
123 case 0:
124 return new HowToPlayState();
125 107
126 break; 108 break;
127 case 1: 109 case 1:
128 return new TitleState(); 110 return new TitleState();
129 } 111 }
130 } 112 }
131 } 113 }
132 } 114 }
133 } 115 }
134} 116}
diff --git a/titlestate.h b/titlestate.h index 8e6ffbc..e989659 100644 --- a/titlestate.h +++ b/titlestate.h
@@ -1,22 +1,23 @@
1#include <SDL.h> 1#include <SDL.h>
2
2#include "state.h" 3#include "state.h"
3 4
4#ifndef TITLESTATE_H 5#ifndef TITLESTATE_H
5#define TITLESTATE_H 6#define TITLESTATE_H
6 7
7class TitleState : public State { 8class TitleState : public State {
8 public: 9 public:
9 State* operator() (SDL_Window* window, SDL_Renderer* renderer); 10 State* operator()(SDL_Window* window, SDL_Renderer* renderer);
10}; 11};
11 12
12class HowToPlayState : public State { 13class HowToPlayState : public State {
13 public: 14 public:
14 State* operator() (SDL_Window* window, SDL_Renderer* renderer); 15 State* operator()(SDL_Window* window, SDL_Renderer* renderer);
15}; 16};
16 17
17class HowToPlayPageTwoState : public State { 18class HowToPlayPageTwoState : public State {
18 public: 19 public:
19 State* operator() (SDL_Window* window, SDL_Renderer* renderer); 20 State* operator()(SDL_Window* window, SDL_Renderer* renderer);
20}; 21};
21 22
22#endif \ No newline at end of file 23#endif \ No newline at end of file
diff --git a/util.cpp b/util.cpp index 9fcdbbd..693d0ad 100644 --- a/util.cpp +++ b/util.cpp
@@ -1,71 +1,62 @@
1#include "util.h" 1#include "util.h"
2#include "mazeoflife.h" 2
3#include <iostream> 3#include <iostream>
4 4
5void wrap(int& x, int& y) 5#include "mazeoflife.h"
6{
7 if (x < 0)
8 {
9 x = WIDTH+x;
10 } else if (x >= WIDTH)
11 {
12 x = x-WIDTH;
13 }
14 6
15 if (y < 0) 7void wrap(int& x, int& y) {
16 { 8 if (x < 0) {
17 y = HEIGHT+y; 9 x = WIDTH + x;
18 } else if (y >= HEIGHT) 10 } else if (x >= WIDTH) {
19 { 11 x = x - WIDTH;
20 y = y-HEIGHT; 12 }
21 } 13
14 if (y < 0) {
15 y = HEIGHT + y;
16 } else if (y >= HEIGHT) {
17 y = y - HEIGHT;
18 }
22} 19}
23 20
24TTF_Font* loadFont(int size) 21TTF_Font* loadFont(int size) {
25{ 22 TTF_Font* tmpfont = TTF_OpenFont("resources/mono.ttf", size);
26 TTF_Font* tmpfont = TTF_OpenFont("resources/mono.ttf", size);
27 23
28 if (tmpfont == NULL) 24 if (tmpfont == NULL) {
29 { 25 printf("Unable to load font: %s\n", TTF_GetError());
30 printf("Unable to load font: %s\n", TTF_GetError()); 26 exit(1);
31 exit(1); 27 }
32 }
33 28
34 return tmpfont; 29 return tmpfont;
35} 30}
36 31
37const char* getDataFile() 32const char* getDataFile() {
38{
39#ifdef WINDOWS 33#ifdef WINDOWS
40 char* dir = getenv("USERPROFILE"); 34 char* dir = getenv("USERPROFILE");
41#else 35#else
42 char* dir = getenv("HOME"); 36 char* dir = getenv("HOME");
43#endif 37#endif
44 38
45 return (std::string(dir) + "/.molhslist").c_str(); 39 return (std::string(dir) + "/.molhslist").c_str();
46} 40}
47 41
48SDL_Texture* loadImage(SDL_Renderer* renderer, std::string file) 42SDL_Texture* loadImage(SDL_Renderer* renderer, std::string file) {
49{ 43 SDL_Surface* surface = SDL_LoadBMP(file.c_str());
50 SDL_Surface* surface = SDL_LoadBMP(file.c_str()); 44 if (surface == NULL) {
51 if (surface == NULL) 45 std::cout << SDL_GetError() << std::endl;
52 { 46 return NULL;
53 std::cout << SDL_GetError() << std::endl; 47 }
54 return NULL;
55 }
56 48
57 SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface); 49 SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
58 SDL_FreeSurface(surface); 50 SDL_FreeSurface(surface);
59 51
60 return texture; 52 return texture;
61} 53}
62 54
63void applyTexture(SDL_Renderer* renderer, SDL_Texture* tex, int x, int y) 55void applyTexture(SDL_Renderer* renderer, SDL_Texture* tex, int x, int y) {
64{ 56 SDL_Rect pos;
65 SDL_Rect pos; 57 pos.x = x;
66 pos.x = x; 58 pos.y = y;
67 pos.y = y; 59 SDL_QueryTexture(tex, NULL, NULL, &pos.w, &pos.h);
68 SDL_QueryTexture(tex, NULL, NULL, &pos.w, &pos.h);
69 60
70 SDL_RenderCopy(renderer, tex, NULL, &pos); 61 SDL_RenderCopy(renderer, tex, NULL, &pos);
71} \ No newline at end of file 62} \ No newline at end of file
diff --git a/util.h b/util.h index 0e1fa2e..836f065 100644 --- a/util.h +++ b/util.h
@@ -1,5 +1,6 @@
1#include <SDL.h> 1#include <SDL.h>
2#include <SDL_ttf.h> 2#include <SDL_ttf.h>
3
3#include <string> 4#include <string>
4 5
5#ifndef UTIL_H 6#ifndef UTIL_H