1 /* Pipepanic - a game.
2 Copyright (C) 2006 TheGreenKnight <thegreenknight1500@hotmail.com>
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
17
18 /* Includes */
19 #include <SDL/SDL_main.h>
20 #include <SDL/SDL.h>
21 #include <string.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <time.h>
26 #include "main.h"
27
28 /* Variable declarations */
29 int xres = 640;
30 int yres = 480;
31 int tilew = 48;
32 int tileh = 48;
33 int digitw = 30;
34 int digith = 48;
35 int asciiw = 30;
36 int asciih = 30;
37 int sdl_fullscreen = FALSE;
38 int fpstest = 0;
39 SDL_Surface *screen;
40 SDL_Surface *digits;
41 SDL_Surface *tiles;
42 SDL_Surface *ascii;
43 SDL_Surface *temp;
44 SDL_Event event;
45 char *current_dir;
46 char *user_home_dir;
47 int quit = 0;
48 int game_mode = GAMEON;
49 int previous_game_mode = 0;
50 int redraw = REDRAWALL;
51 int highscoretable[5] = {0, 0, 0, 0, 0};
52 int highscoreboard[5][BOARDH * BOARDW];
53 int score = 0;
54 int disablescoring = FALSE;
55 int gametime = GAMETIME;
56 Uint32 gametime_ticks = 0;
57 Uint32 fps_ticks = 0;
58 Uint32 cleardeadpipes_ticks = 0;
59 Uint32 fillpipes_ticks = 0;
60 Uint32 flashhighscore_ticks = 0;
61 long int frames = 0;
62 int drawpipearray[BOARDH * BOARDW + 1][3]; /* y|x|filled-or-empty */
63 int previewarray[PREVIEWARRAYSIZE];
64 int pipearray[PIPEARRAYSIZE];
65 int pipearraypointer = PIPEARRAYSIZE;
66 int boardarray[BOARDH][BOARDW];
67 int deadpipesarray[BOARDH][BOARDW];
68 int cleardeadpipesy = 0, cleardeadpipesx = 0;
69 int fillpipespasscounter = FILLEDCOUNTERBASE;
70 int flashhighscorestate = FALSE;
71 int helppage = 0;
72 /* ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ' a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ */
73 int asciiwidths[100] = {7,5,10,11,11,18,15,6,6,6,9,11,5,8,5,7,13,10,12,13,14,13,13,13,13,13,5,5,11,11,11,12,15,15,14,13,14,13,12,15,14,6,12,15,12,16,14,16,13,16,14,14,14,14,15,19,13,13,14,8,6,8,11,10,6,13,12,13,12,13,8,13,11,6,6,12,6,17,11,13,12,12,8,12,9,11,12,18,13,12,11,8,4,8,11};
74
75 /* Function prototypes */
76 int get_machine_id(void);
77 void clear_screen(void);
78 int load_bitmaps(void);
79 void draw_game(void);
80 void draw_digits(int value, int digitcount, int xpos, int ypos);
81 void initialise_new_game(void);
82 void manage_user_input(void);
83 int getnextpipepiece(void);
84 void fillpipearray(void);
85 int fillpipearraypieces(int pipepiece, int frequency, int nextpointer);
86 void get_pipe_src_xy(int pipeid, int *x, int *y, int drawpipefilled);
87 void createdeadpipesarray(void);
88 void cleardeadpipes(void);
89 void fillpipes(void);
90 void read_rc_file(void);
91 void save_rc_file(void);
92 void draw_ascii(char *text, int xpos, int ypos);
93 void manage_help_input(int input);
94
95 /***************************************************************************
96 * Main *
97 ***************************************************************************/
98
99 #ifdef __cplusplus
100 extern "C"
101 #endif
main(int argc,char * argv[])102 int main(int argc, char *argv[]) {
103 int count, count2;
104
105 /* Initialise the highscoreboard array because there may not yet
106 be a saved highscore[board]/rc file */
107 for (count = 0; count < 5; count++) {
108 for (count2 = 0; count2 < BOARDH * BOARDW; count2++) {
109 highscoreboard[count][count2] = NULLPIPEVAL;
110 }
111 }
112
113 srand((unsigned) time(NULL)); /* Seed C's random number generator */
114
115 current_dir = getenv("PWD");
116 user_home_dir = getenv("HOME");
117
118 #ifdef DEBUG
119 printf("PWD=%s\n", current_dir);
120 printf("HOME=%s\n", user_home_dir);
121 #endif
122
123 if (get_machine_id()) return 1; /* This sets up the screen and tile sizes. */
124
125 #ifdef DEBUG
126 printf("Reading resource file -> ");
127 #endif
128 read_rc_file(); /* This gets the saved highscore[s] */
129
130 /* Process any command line arguments. These will override any found in the resource file. */
131 if (argc > 1) {
132 int count;
133 for (count = argc - 1; count > 0; count--) {
134 if (!strcmp(argv[count], "--help")) {
135 /* 1234567890123456789012345678901234567890 <- Formatting for small terminal. */
136 printf("\nPipepanic version %s\n", VERSION);
137 printf("Usage: pipepanic [option] [option]...\n");
138 printf("Options:\n");
139 printf(" -240x320 Suitable for the SL5X00\n");
140 printf(" -320x240 Suitable for the SL5X00\n");
141 printf(" -640x480 Suitable for the C Series\n");
142 printf(" -480x640 Suitable for the SL6000\n");
143 printf(" -f Run the game fullscreen\n");
144 printf(" -fpstest Run a 10s fps test and quit\n\n");
145 return 0;
146 } else if (!strcmp(argv[count], "-240x320")) {
147 xres = 240; yres = 320;
148 tilew = tileh = digith = 24; digitw = 15; asciiw = asciih = 15;
149 } else if (!strcmp(argv[count], "-320x240")) {
150 xres = 320; yres = 240;
151 tilew = tileh = digith = 24; digitw = 15; asciiw = asciih = 15;
152 } else if (!strcmp(argv[count], "-640x480")) {
153 xres = 640; yres = 480;
154 tilew = tileh = digith = 48; digitw = 30; asciiw = asciih = 30;
155 } else if (!strcmp(argv[count], "-480x640")) {
156 xres = 480; yres = 640;
157 tilew = tileh = digith = 48; digitw = 30; asciiw = asciih = 30;
158 } else if (!strcmp(argv[count], "-fpstest")) {
159 fpstest = 1;
160 } else if (!strcmp(argv[count], "-f")) {
161 sdl_fullscreen = SDL_FULLSCREEN;
162 } else {
163 printf("\n'%s' not recognised. Try '--help'.\n\n", argv[count]);
164 return 0;
165 }
166 }
167 }
168
169 /* Initialise SDL */
170 if(SDL_Init(SDL_INIT_VIDEO)) {
171 printf("%s: Cannot initialise SDL: %s\n", __func__, SDL_GetError());
172 return 1;
173 }
174
175 atexit(SDL_Quit);
176
177 #ifdef DEBUG
178 printf("Setting video mode %ix%i\n", xres, yres);
179 #endif
180
181 /* Set SDL video mode */
182 screen = SDL_SetVideoMode(xres, yres, 16, SDL_DOUBLEBUF | SDL_HWSURFACE | SDL_ANYFORMAT | sdl_fullscreen);
183 if(screen == NULL) {
184 printf("%s: Cannot initialise screen: %s\n", __func__, SDL_GetError());
185 exit(1);
186 }
187
188 #ifdef DEBUG
189 printf ("Loading bitmaps\n");
190 #endif
191
192 if (load_bitmaps()) exit(1);
193
194 /* Initialise new game */
195 initialise_new_game();
196
197 /* Main game loop */
198 while(quit == 0) {
199 if(game_mode == GAMESHOWHELP) {
200 /***************************************************************************
201 * GAMESHOWHELP *
202 ***************************************************************************/
203 draw_game();
204 manage_user_input();
205 } else if(game_mode == GAMEON) {
206 /***************************************************************************
207 * GAMEON *
208 ***************************************************************************/
209 /* Check to see if the time needs to be updated */
210 if (SDL_GetTicks() - gametime_ticks >= 1000) {
211 redraw = redraw | REDRAWTIMER;
212 gametime_ticks = SDL_GetTicks();
213 gametime = gametime - 1;
214 if (gametime <= 0) {
215 gametime = 0;
216 createdeadpipesarray();
217 }
218 }
219 draw_game();
220 manage_user_input();
221 } else if(game_mode == GAMECLEARDEADPIPES) {
222 /***************************************************************************
223 * GAMECLEARDEADPIPES *
224 ***************************************************************************/
225 if (SDL_GetTicks() - cleardeadpipes_ticks >= CLEARDEADPIPESTIMEOUT) {
226 cleardeadpipes_ticks = SDL_GetTicks();
227 cleardeadpipes();
228 }
229 draw_game();
230 manage_user_input();
231 } else if(game_mode == GAMEFILLPIPES) {
232 /***************************************************************************
233 * GAMEFILLPIPES *
234 ***************************************************************************/
235 if(SDL_GetTicks() - fillpipes_ticks >= FILLPIPESTIMEOUT) {
236 fillpipes_ticks = SDL_GetTicks();
237 fillpipes();
238 }
239 draw_game();
240 manage_user_input();
241 } else if(game_mode == GAMEFLASHHIGHSCORE) {
242 /***************************************************************************
243 * GAMEFLASHHIGHSCORE *
244 ***************************************************************************/
245 if (SDL_GetTicks() - flashhighscore_ticks >= FLASHHIGHSCORETIMEOUT) {
246 flashhighscore_ticks = SDL_GetTicks();
247 redraw = redraw | REDRAWHIGHSCORE;
248 if (flashhighscorestate) {
249 flashhighscorestate = FALSE;
250 } else {
251 flashhighscorestate = TRUE;
252 }
253 }
254 draw_game();
255 manage_user_input();
256 } else if(game_mode == GAMEOVER) {
257 /***************************************************************************
258 * GAMEOVER *
259 ***************************************************************************/
260 draw_game();
261 manage_user_input();
262 }
263 if (!fpstest) SDL_Delay(9); /* Reduce CPU load to almost nothing */
264 }
265
266 /* Shutdown all subsystems */
267 SDL_Quit();
268
269 /* Show fps if requested */
270 if (fpstest) printf("fps=%li\n", frames / 10);
271
272 return 0;
273 }
274
275 /***************************************************************************
276 * Get Machine ID *
277 ***************************************************************************/
278 /* This looks for the file /proc/deviceinfo/product which exists on the
279 Zaurus and not the PC and then sets the screen resolution accordingly.
280 On exit: returns 1 if file found but product unknown else 0. */
281
get_machine_id(void)282 int get_machine_id(void) {
283 char buffer[256];
284 int returnval = 0;
285 FILE *file = fopen( "/proc/deviceinfo/product", "r" );
286
287 if (file) {
288 fgets(buffer, 255, file);
289 #ifdef DEBUG
290 printf("product=%s\n", buffer);
291 #endif
292 if (!strncmp(buffer, "SL-5", 4)) {
293 xres = 240; yres = 320;
294 tilew = tileh = digith = 24; digitw = 15; asciiw = asciih = 15;
295 } else if (!strncmp(buffer, "SL-C", 4)) {
296 xres = 640; yres = 480;
297 tilew = tileh = digith = 48; digitw = 30; asciiw = asciih = 30;
298 } else if (!strncmp(buffer, "SL-6", 4)) {
299 xres = 480; yres = 640;
300 tilew = tileh = digith = 48; digitw = 30; asciiw = asciih = 30;
301 } else {
302 printf("product=%s\n", buffer);
303 printf("Unknown Zaurus model! Please email me the product shown above.\n");
304 returnval = 1;
305 }
306 fclose (file);
307 }
308 return returnval;
309 }
310
311 /***************************************************************************
312 * Clear Screen *
313 ***************************************************************************/
314 /* This simply sets the screen to black. */
315
clear_screen(void)316 void clear_screen(void) {
317 SDL_Rect dest;
318
319 dest.x = dest.y = 0; dest.w = screen->w; dest.h = screen->h;
320 SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format, BLACK));
321 }
322
323 /***************************************************************************
324 * Load Bitmaps *
325 ***************************************************************************/
326 /* This locates and loads the relevant bitmap images. They are converted to
327 the display format for optimisation. Also RLE is enabled for the colorkey
328 which makes probably the biggest difference in frame rate I have found yet.
329 On exit: returns 1 if an error occured else 0. */
330
load_bitmaps(void)331 int load_bitmaps(void) {
332 if (xres == 320 || xres == 240) {
333 /* First check current dir. */
334 if((temp = SDL_LoadBMP(DIGITS24BMP)) == NULL) {
335 /* Now check DATADIR. */
336 if((temp = SDL_LoadBMP(DATADIR DIGITS24BMP)) == NULL) {
337 printf("%s: Cannot find file %s\n", __func__, DIGITS24BMP);
338 return 1;
339 }
340 }
341 if((digits = SDL_DisplayFormat(temp)) == NULL) {
342 printf("%s: SDL_DisplayFormat error: %s\n", __func__, SDL_GetError());
343 return 1;
344 }
345 SDL_FreeSurface(temp);
346
347 /* First check current dir. */
348 if((temp = SDL_LoadBMP(TILES24BMP)) == NULL) {
349 /* Now check DATADIR. */
350 if((temp = SDL_LoadBMP(DATADIR TILES24BMP)) == NULL) {
351 printf("%s: Cannot find file %s\n", __func__, TILES24BMP);
352 return 1;
353 }
354 }
355 SDL_SetColorKey(temp, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB(temp->format, MAGENTA));
356 if((tiles = SDL_DisplayFormat(temp)) == NULL) {
357 printf("%s: SDL_DisplayFormat error: %s\n", __func__, SDL_GetError());
358 return 1;
359 }
360 SDL_FreeSurface(temp);
361
362 /* First check current dir. */
363 if((temp = SDL_LoadBMP(ASCII15BMP)) == NULL) {
364 /* Now check DATADIR. */
365 if((temp = SDL_LoadBMP(DATADIR ASCII15BMP)) == NULL) {
366 printf("%s: Cannot find file %s\n", __func__, ASCII15BMP);
367 return 1;
368 }
369 }
370 SDL_SetColorKey(temp, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB(temp->format, WHITE));
371 if((ascii = SDL_DisplayFormat(temp)) == NULL) {
372 printf("%s: SDL_DisplayFormat error: %s\n", __func__, SDL_GetError());
373 return 1;
374 }
375 SDL_FreeSurface(temp);
376
377 } else if (xres == 640 || xres == 480) {
378 /* First check current dir. */
379 if((temp = SDL_LoadBMP(DIGITS48BMP)) == NULL) {
380 /* Now check DATADIR. */
381 if((temp = SDL_LoadBMP(DATADIR DIGITS48BMP)) == NULL) {
382 printf("%s: Cannot find file %s\n", __func__, DIGITS48BMP);
383 return 1;
384 }
385 }
386 if((digits = SDL_DisplayFormat(temp)) == NULL) {
387 printf("%s: SDL_DisplayFormat error: %s\n", __func__, SDL_GetError());
388 return 1;
389 }
390 SDL_FreeSurface(temp);
391
392 /* First check current dir. */
393 if((temp = SDL_LoadBMP(TILES48BMP)) == NULL) {
394 /* Now check DATADIR. */
395 if((temp = SDL_LoadBMP(DATADIR TILES48BMP)) == NULL) {
396 printf("%s: Cannot find file %s\n", __func__, TILES48BMP);
397 return 1;
398 }
399 }
400 SDL_SetColorKey(temp, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB(temp->format, MAGENTA));
401 if((tiles = SDL_DisplayFormat(temp)) == NULL) {
402 printf("%s: SDL_DisplayFormat error: %s\n", __func__, SDL_GetError());
403 return 1;
404 }
405 SDL_FreeSurface(temp);
406
407 /* First check current dir. */
408 if((temp = SDL_LoadBMP(ASCII30BMP)) == NULL) {
409 /* Now check DATADIR. */
410 if((temp = SDL_LoadBMP(DATADIR ASCII30BMP)) == NULL) {
411 printf("%s: Cannot find file %s\n", __func__, ASCII30BMP);
412 return 1;
413 }
414 }
415 SDL_SetColorKey(temp, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB(temp->format, WHITE));
416 if((ascii = SDL_DisplayFormat(temp)) == NULL) {
417 printf("%s: SDL_DisplayFormat error: %s\n", __func__, SDL_GetError());
418 return 1;
419 }
420 SDL_FreeSurface(temp);
421 }
422
423 return 0;
424 }
425
426 /***************************************************************************
427 * Draw Game *
428 ***************************************************************************/
429 /* This draws the game. Either it draws all of it or just parts of it. */
430
draw_game(void)431 void draw_game(void) {
432 SDL_Rect src, dest;
433 int row, column, x, y;
434
435 if (fpstest) redraw = REDRAWALL;
436
437 if ((redraw & REDRAWBOARD) == REDRAWBOARD) {
438 /* Paint the whole screen yellow. */
439 dest.x = dest.y = 0; dest.w = screen->w; dest.h = screen->h;
440 SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format, YELLOW));
441
442 /* Draw all the game board background tiles. */
443 src.x = 4 * tilew; src.y = 6 * tileh;
444 src.w = tilew; src.h = tileh;
445 dest.y = 0; if (xres == 240 || xres == 480) dest.y = 2 * tileh;
446 dest.w = tilew; dest.h = tileh;
447 for (row = 0; row < BOARDH; row++) {
448 dest.x = xres - BOARDW * tilew;
449 for (column = 0; column < BOARDW; column++) {
450 if(SDL_BlitSurface(tiles, &src, screen, &dest) < 0)
451 printf("%s: BlitSurface error: %s\n", __func__, SDL_GetError());
452 dest.x = dest.x + tilew;
453 }
454 dest.y = dest.y + tileh;
455 }
456
457 /* Draw all the text. */
458 /* High Score. */
459 src.x = 0 * tilew; src.y = 8 * tileh;
460 src.w = 3 * tilew; src.h = tileh;
461 dest.x = dest.y = 0; if (xres == 240 || xres == 480) dest.x = 3.7 * tilew;
462 dest.w = 3 * tilew; dest.h = tileh;
463 if(SDL_BlitSurface(tiles, &src, screen, &dest) < 0)
464 printf("%s: BlitSurface error: %s\n", __func__, SDL_GetError());
465
466 /* Score. */
467 src.x = 3 * tilew; src.y = 8 * tileh;
468 src.w = 2 * tilew; src.h = tileh;
469 dest.x = 0; dest.y = 2 * tileh; if (xres == 240 || xres == 480) dest.y = 0;
470 dest.w = 2 * tilew; dest.h = tileh;
471 if(SDL_BlitSurface(tiles, &src, screen, &dest) < 0)
472 printf("%s: BlitSurface error: %s\n", __func__, SDL_GetError());
473
474 /* Time (s). */
475 src.x = 0 * tilew; src.y = 9 * tileh;
476 src.w = 3 * tilew; src.h = tileh;
477 dest.x = 0; if (xres == 240 || xres == 480) dest.x = 7.6 * tilew;
478 dest.y = 4 * tileh; if (xres == 240 || xres == 480) dest.y = 0;
479 dest.w = 3 * tilew; dest.h = tileh;
480 if(SDL_BlitSurface(tiles, &src, screen, &dest) < 0)
481 printf("%s: BlitSurface error: %s\n", __func__, SDL_GetError());
482
483 /* Fill. */
484 src.x = 3 * tilew; src.y = 10 * tileh;
485 src.w = tilew; src.h = tileh;
486 dest.x = 0; if (xres == 240 || xres == 480) dest.x = 4 * tilew;
487 dest.y = 7 * tileh; if (xres == 240 || xres == 480) dest.y = 12.18 * tileh;
488 dest.w = tilew; dest.h = tileh;
489 if(SDL_BlitSurface(tiles, &src, screen, &dest) < 0)
490 printf("%s: BlitSurface error: %s\n", __func__, SDL_GetError());
491
492 /* Help. */
493 src.x = 3 * tilew; src.y = 9 * tileh;
494 src.w = 2 * tilew; src.h = tileh;
495 dest.x = 0; if (xres == 240 || xres == 480) dest.x = 5.25 * tilew;
496 dest.y = 8 * tileh; if (xres == 240 || xres == 480) dest.y = 12.18 * tileh;
497 dest.w = 3 * tilew; dest.h = tileh;
498 if(SDL_BlitSurface(tiles, &src, screen, &dest) < 0)
499 printf("%s: BlitSurface error: %s\n", __func__, SDL_GetError());
500
501 /* New Game. */
502 src.x = 0 * tilew; src.y = 10 * tileh;
503 src.w = 3 * tilew; src.h = tileh;
504 dest.x = 0; if (xres == 240 || xres == 480) dest.x = 6.9 * tilew;
505 dest.y = 9 * tileh; if (xres == 240 || xres == 480) dest.y = 12.18 * tileh;
506 dest.w = 3 * tilew; dest.h = tileh;
507 if(SDL_BlitSurface(tiles, &src, screen, &dest) < 0)
508 printf("%s: BlitSurface error: %s\n", __func__, SDL_GetError());
509 }
510
511 if ((redraw & REDRAWALLPIPES) == REDRAWALLPIPES) {
512 /* Draw any pipes found in the board array.
513 NOTE that this doesn't draw the background tile first.
514 This is done in REDRAWBOARD above. */
515 src.w = tilew; src.h = tileh;
516 dest.y = 0; if (xres == 240 || xres == 480) dest.y = 2 * tileh;
517 dest.w = tilew; dest.h = tileh;
518 for (row = 0; row < BOARDH; row++) {
519 dest.x = xres - BOARDW * tilew;
520 for (column = 0; column < BOARDW; column++) {
521 if (boardarray[row][column] != NULLPIPEVAL) {
522 get_pipe_src_xy(boardarray[row][column], &x, &y, FALSE);
523 src.x = x; src.y = y;
524 if(SDL_BlitSurface(tiles, &src, screen, &dest) < 0)
525 printf("%s: BlitSurface error: %s\n", __func__, SDL_GetError());
526 }
527 dest.x = dest.x + tilew;
528 }
529 dest.y = dest.y + tileh;
530 }
531 }
532
533 if ((redraw & REDRAWHIGHSCORE) == REDRAWHIGHSCORE) {
534 /* The top high score */
535 /* If flashhighscorestate is TRUE then no score is shown
536 (it is blanked out with the background colour). */
537 dest.x = 0.15 * tilew; if (xres == 240 || xres == 480) dest.x = 4 * tilew;
538 dest.y = 0.9 * tileh;
539 if (flashhighscorestate) {
540 dest.w = 5 * digitw; dest.h = digith;
541 SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format, YELLOW));
542 } else {
543 draw_digits(highscoretable[0], 4, dest.x, dest.y);
544 }
545 }
546
547 if ((redraw & REDRAWTIMER) == REDRAWTIMER) {
548 /* The time */
549 dest.x = 0.15 * tilew; if (xres == 240 || xres == 480) dest.x = 8 * tilew;
550 dest.y = 4.9 * tileh; if (xres == 240 || xres == 480) dest.y = 0.9 * tileh;
551 draw_digits(gametime, 3, dest.x, dest.y);
552 }
553
554 if ((redraw & REDRAWSCORE) == REDRAWSCORE) {
555 /* The score */
556 dest.x = 0.15 * tilew; if (xres == 240 || xres == 480) dest.x = 0.15 * tilew;
557 dest.y = 2.9 * tileh; if (xres == 240 || xres == 480) dest.y = 0.9 * tileh;
558 draw_digits(score, 4, dest.x, dest.y);
559 }
560
561 if ((redraw & REDRAWPREVIEW) == REDRAWPREVIEW) {
562 /* Draw preview array */
563 /* Left */
564 src.x = 1 * tilew; src.y = 7 * tileh;
565 src.w = tilew; src.h = tileh;
566 dest.x = 0.09 * tilew; if (xres == 240 || xres == 480) dest.x = 0.09 * tilew;
567 dest.y = 6 * tileh; if (xres == 240 || xres == 480) dest.y = 12.18 * tileh;
568 dest.w = tilew; dest.h = tileh;
569 if(SDL_BlitSurface(tiles, &src, screen, &dest) < 0)
570 printf("%s: BlitSurface error: %s\n", __func__, SDL_GetError());
571 get_pipe_src_xy(previewarray[2], &x, &y, FALSE);
572 src.x = x; src.y = y;
573 if(SDL_BlitSurface(tiles, &src, screen, &dest) < 0)
574 printf("%s: BlitSurface error: %s\n", __func__, SDL_GetError());
575
576 /* Middle */
577 src.x = 1 * tilew; src.y = 7 * tileh;
578 src.w = tilew; src.h = tileh;
579 dest.x = 1.18 * tilew; if (xres == 240 || xres == 480) dest.x = 1.18 * tilew;
580 dest.y = 6 * tileh; if (xres == 240 || xres == 480) dest.y = 12.18 * tileh;
581 dest.w = tilew; dest.h = tileh;
582 if(SDL_BlitSurface(tiles, &src, screen, &dest) < 0)
583 printf("%s: BlitSurface error: %s\n", __func__, SDL_GetError());
584 get_pipe_src_xy(previewarray[1], &x, &y, FALSE);
585 src.x = x; src.y = y;
586 if(SDL_BlitSurface(tiles, &src, screen, &dest) < 0)
587 printf("%s: BlitSurface error: %s\n", __func__, SDL_GetError());
588
589 /* Right */
590 src.x = 0; src.y = 7 * tileh;
591 src.w = tilew; src.h = tileh;
592 dest.x = 2.27 * tilew; if (xres == 240 || xres == 480) dest.x = 2.27 * tilew;
593 dest.y = 6 * tileh; if (xres == 240 || xres == 480) dest.y = 12.18 * tileh;
594 dest.w = tilew; dest.h = tileh;
595 if(SDL_BlitSurface(tiles, &src, screen, &dest) < 0)
596 printf("%s: BlitSurface error: %s\n", __func__, SDL_GetError());
597 get_pipe_src_xy(previewarray[0], &x, &y, FALSE);
598 src.x = x; src.y = y;
599 if(SDL_BlitSurface(tiles, &src, screen, &dest) < 0)
600 printf("%s: BlitSurface error: %s\n", __func__, SDL_GetError());
601 }
602
603 if ((redraw & REDRAWTILE) == REDRAWTILE) {
604 /* Draw one or more background tiles within the board.
605 The offsets into the board are in the draw pipes array */
606 row = 0;
607 while(drawpipearray[row][0] != NULLPIPEVAL) {
608 src.x = 4 * tilew; src.y = 6 * tileh;
609 src.w = tilew; src.h = tileh;
610 dest.x = (xres - BOARDW * tilew) + drawpipearray[row][1] * tilew; if (xres == 240 || xres == 480) dest.x = drawpipearray[row][1] * tilew;
611 dest.y = drawpipearray[row][0] * tileh; if (xres == 240 || xres == 480) dest.y = drawpipearray[row][0] * tileh + 2 * tileh;
612 dest.w = tilew; dest.h = tileh;
613 if(SDL_BlitSurface(tiles, &src, screen, &dest) < 0)
614 printf("%s: BlitSurface error: %s\n", __func__, SDL_GetError());
615 row++;
616 }
617 }
618
619 if ((redraw & REDRAWPIPE) == REDRAWPIPE) {
620 /* Draw one or more pipe pieces within the board.
621 The offsets into the board array are in the
622 draw pipes array */
623 row = 0;
624 while(drawpipearray[row][0] != NULLPIPEVAL) {
625 get_pipe_src_xy(boardarray[drawpipearray[row][0]][drawpipearray[row][1]], &x, &y, drawpipearray[row][2]);
626 src.x = x; src.y = y;
627 src.w = tilew; src.h = tileh;
628 dest.x = (xres - BOARDW * tilew) + drawpipearray[row][1] * tilew; if (xres == 240 || xres == 480) dest.x = drawpipearray[row][1] * tilew;
629 dest.y = drawpipearray[row][0] * tileh; if (xres == 240 || xres == 480) dest.y = drawpipearray[row][0] * tileh + 2 * tileh;
630 dest.w = tilew; dest.h = tileh;
631 if(SDL_BlitSurface(tiles, &src, screen, &dest) < 0)
632 printf("%s: BlitSurface error: %s\n", __func__, SDL_GetError());
633 row++;
634 }
635 }
636
637 if ((redraw & REDRAWHELP) == REDRAWHELP) {
638 /* Show the help pages */
639 /* Draw a white box to cover the game board */
640 dest.x = xres - BOARDW * tilew;
641 dest.y = 0; if (xres == 240 || xres == 480) dest.y = 2 * tileh;
642 dest.w = BOARDW * tilew; dest.h = BOARDH * tileh;
643 SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format, WHITE));
644 /* Draw the Exit text and the navigation buttons */
645 if(helppage > 0) {
646 /* Left arrow */
647 src.x = 2 * tilew; src.y = 7 * tileh;
648 src.w = tilew; src.h = tileh;
649 dest.x = xres - BOARDW * tilew; if (xres == 240 || xres == 480) dest.x = 0;
650 dest.y = (BOARDH - 1) * tileh; if (xres == 240 || xres == 480) dest.y = (BOARDH - 1) * tileh + 2 * tileh;
651 dest.w = tilew; dest.h = tileh;
652 if(SDL_BlitSurface(tiles, &src, screen, &dest) < 0)
653 printf("%s: BlitSurface error: %s\n", __func__, SDL_GetError());
654 }
655 if(helppage < HELPPAGES - 1) {
656 /* Right arrow */
657 src.x = 4 * tilew; src.y = 10 * tileh;
658 src.w = tilew; src.h = tileh;
659 dest.x = xres - tilew;
660 dest.y = (BOARDH - 1) * tileh; if (xres == 240 || xres == 480) dest.y = (BOARDH - 1) * tileh + 2 * tileh;
661 dest.w = tilew; dest.h = tileh;
662 if(SDL_BlitSurface(tiles, &src, screen, &dest) < 0)
663 printf("%s: BlitSurface error: %s\n", __func__, SDL_GetError());
664 }
665 /* Exit */
666 src.x = 3 * tilew; src.y = 7 * tileh;
667 src.w = 2 * tilew; src.h = tileh;
668 dest.x = xres - 5.6 * tilew;
669 dest.y = (BOARDH - 1) * tileh; if (xres == 240 || xres == 480) dest.y = (BOARDH - 1) * tileh + 2 * tileh;
670 dest.w = 2 * tilew; dest.h = tileh;
671 if(SDL_BlitSurface(tiles, &src, screen, &dest) < 0)
672 printf("%s: BlitSurface error: %s\n", __func__, SDL_GetError());
673 /* Draw a black surround */
674 if(xres == 240 || xres == 480) {
675 /* Top */
676 dest.x = xres - BOARDW * tilew;
677 dest.y = 2 * tileh;
678 dest.w = BOARDW * tilew; dest.h = 1;
679 /* Bottom */
680 SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format, BLACK));
681 dest.x = xres - BOARDW * tilew;
682 dest.y = 2 * tileh + BOARDH * tileh - 1;
683 dest.w = BOARDW * tilew; dest.h = 1;
684 SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format, BLACK));
685 } else if (xres == 320 || xres == 640){
686 /* Left */
687 dest.x = xres - BOARDW * tilew;
688 dest.y = 0;
689 dest.w = 1; dest.h = BOARDW * tilew;
690 SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format, BLACK));
691 }
692
693 x = xres - (BOARDW - 0.2) * tilew;
694 y = 0.2 * BOARDH; if (xres == 240 || xres == 480) y = 2.2 * tileh;
695 if(helppage == 0) {
696 draw_ascii(HELPPAGE0, x, y);
697 } else if(helppage == 1) {
698 draw_ascii(HELPPAGE1, x, y);
699 } else if(helppage == 2) {
700 draw_ascii(HELPPAGE2, x, y);
701 } else if(helppage == 3) {
702 draw_ascii(HELPPAGE3, x, y);
703 } else if(helppage == 4) {
704 draw_ascii(HELPPAGE4, x, y);
705 } else if(helppage == 5) {
706 draw_ascii(HELPPAGE5, x, y);
707 }
708 }
709
710 if (redraw != REDRAWNONE) SDL_Flip(screen);
711
712 if (fpstest) {
713 frames++;
714 if (SDL_GetTicks() - fps_ticks >= 10000) quit = 1;
715 }
716
717 redraw = REDRAWNONE;
718 }
719
720 /***************************************************************************
721 * Draw Ascii *
722 ***************************************************************************/
723 /* This writes ASCII text. Embedded "\n" are translated into newlines.
724 On entry: text = pointer to a (C) null terminated string */
725
draw_ascii(char * text,int xpos,int ypos)726 void draw_ascii(char *text, int xpos, int ypos) {
727 SDL_Rect src, dest;
728 int count = 0, x = xpos, y = ypos;
729
730 while(text[count] != 0) {
731 while(text[count] == '\n') {
732 x = xpos;
733 y = y + asciih * 0.8;
734 count++;
735 }
736 src.x = ((text[count] - 32) % 10) * asciiw;
737 src.y = ((text[count] - 32) / 10) * asciih;
738 src.w = asciiwidths[text[count] - 32]; if (xres == 320 || xres == 240) src.w = src.w / 2;
739 src.h = asciih;
740 dest.x = x; dest.y = y;
741 dest.w = src.w; dest.h = asciih;
742 if(SDL_BlitSurface(ascii, &src, screen, &dest) < 0)
743 printf("%s: BlitSurface error: %s\n", __func__, SDL_GetError());
744 x = x + src.w;
745 count++;
746 }
747 }
748
749 /***************************************************************************
750 * Draw Digits *
751 ***************************************************************************/
752 /* This writes an integer value. If it is negative the minus sign will be
753 shown at the end of the number.
754 On entry: value = an integer value positive or negative
755 digitcount = number of digits to draw
756 xpos = x position to write the number
757 ypos = y position to write the number */
758
draw_digits(int value,int digitcount,int xpos,int ypos)759 void draw_digits(int value, int digitcount, int xpos, int ypos) {
760 SDL_Rect src, dest;
761 int tempvalue = abs(value);
762 int count, count2, base;
763
764 dest.x = xpos; dest.y = ypos;
765 dest.w = digitw; dest.h = digith;
766 src.y = 0;
767 src.w = digitw; src.h = digith;
768
769 for (count = digitcount - 1; count >= 0; count--) {
770 base = count == 0 ? 1 : 10;
771 for (count2 = count; count2 > 1; count2--) base = base * 10;
772
773 src.x = tempvalue / base * digitw;
774 if(SDL_BlitSurface(digits, &src, screen, &dest) < 0)
775 printf("%s: BlitSurface error: %s\n", __func__, SDL_GetError());
776
777 tempvalue = tempvalue % base;
778 dest.x = dest.x + digitw;
779 }
780
781 if (value < 0) {
782 src.x = 10 * digitw;
783 if(SDL_BlitSurface(digits, &src, screen, &dest) < 0)
784 printf("%s: BlitSurface error: %s\n", __func__, SDL_GetError());
785 } else {
786 SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format, YELLOW));
787 }
788 }
789
790 /***************************************************************************
791 * Initialise New Game *
792 ***************************************************************************/
793 /* This sets up the variables necessary to start the game afresh. */
794
initialise_new_game(void)795 void initialise_new_game(void) {
796 int rowloop, colloop, count;
797
798 game_mode = GAMEON;
799 redraw = REDRAWALL;
800 score = 0;
801 disablescoring = FALSE;
802 flashhighscorestate = FALSE;
803 gametime = GAMETIME;
804 gametime_ticks = SDL_GetTicks();
805
806 /* Clear the game board array */
807 for (rowloop = 0; rowloop < BOARDH; rowloop++) {
808 for (colloop = 0; colloop < BOARDW; colloop++) {
809 boardarray[rowloop][colloop] = NULLPIPEVAL;
810 }
811 }
812
813 /* Setup and initialise preview pieces/array. */
814 pipearraypointer = PIPEARRAYSIZE;
815 for (count = 0; count < PREVIEWARRAYSIZE; count++) {
816 previewarray[count] = getnextpipepiece();
817 }
818
819 /* Place end points and record in game board array. */
820 boardarray[rand() % BOARDH][0] = 1; /* yx */
821 boardarray[rand() % BOARDH][BOARDW - 1] = 0; /* yx */
822
823 drawpipearray[0][0] = NULLPIPEVAL;
824
825 if (fpstest) {
826 fps_ticks = SDL_GetTicks();
827 gametime = 10;
828 }
829 }
830
831 /***************************************************************************
832 * Get Next Pipe Piece *
833 ***************************************************************************/
834 /* Get next piece from the pipe array, or if at end
835 of array refill it and get piece from start. */
836
getnextpipepiece(void)837 int getnextpipepiece(void) {
838 pipearraypointer++;
839 if (pipearraypointer >= PIPEARRAYSIZE) {
840 fillpipearray();
841 pipearraypointer = 0;
842 }
843 return pipearray[pipearraypointer];
844 }
845
846 /***************************************************************************
847 * Fill Pipe Array *
848 ***************************************************************************/
849 /* This fills the pipe array with a set frequency of pipe pieces. The array
850 is then shuffled. */
851
fillpipearray(void)852 void fillpipearray(void) {
853 int nextpointer = 0, count, temp, swap;
854
855 /* Fill pipe array with our recommended frequency */
856 nextpointer = fillpipearraypieces(2, 7, nextpointer);
857 nextpointer = fillpipearraypieces(3, 7, nextpointer);
858 nextpointer = fillpipearraypieces(4, 7, nextpointer);
859 nextpointer = fillpipearraypieces(5, 7, nextpointer);
860 nextpointer = fillpipearraypieces(6, 5, nextpointer);
861 nextpointer = fillpipearraypieces(7, 5, nextpointer);
862 nextpointer = fillpipearraypieces(8, 5, nextpointer);
863 nextpointer = fillpipearraypieces(9, 5, nextpointer);
864 nextpointer = fillpipearraypieces(10, 5, nextpointer);
865 nextpointer = fillpipearraypieces(11, 18, nextpointer);
866 nextpointer = fillpipearraypieces(12, 18, nextpointer);
867 nextpointer = fillpipearraypieces(13, 4, nextpointer);
868 nextpointer = fillpipearraypieces(14, 4, nextpointer);
869 nextpointer = fillpipearraypieces(15, 4, nextpointer);
870 nextpointer = fillpipearraypieces(16, 4, nextpointer);
871
872 /* Go through the pipe array and shuffle the pieces. This maintains frequency :)
873 Fiddle with the above figures to tweek it, but don't forget the array size
874 is set as a constant and will need to be adjusted accordingly */
875 for (count = 0; count < PIPEARRAYSIZE; count++) {
876 temp = pipearray[count];
877 swap = rand() % PIPEARRAYSIZE;
878 pipearray[count] = pipearray[swap];
879 pipearray[swap] = temp;
880 }
881 }
882
883 /***************************************************************************
884 * Fill Pipe Array Pieces *
885 ***************************************************************************/
886 /* This is called by Fill Pipe Array only. */
887
fillpipearraypieces(int pipepiece,int frequency,int nextpointer)888 int fillpipearraypieces(int pipepiece, int frequency, int nextpointer) {
889 while (frequency > 0) {
890 pipearray[nextpointer] = pipepiece;
891 nextpointer++;
892 if (nextpointer >= PIPEARRAYSIZE) nextpointer = 0;
893 frequency--;
894 }
895 return nextpointer;
896 }
897
898 /***************************************************************************
899 * Get Pipe XY *
900 ***************************************************************************/
901 /* This translates a number identifying a pipe into x and y coordinates
902 into the tiles surface.
903 On entry: pipeid = 0 to 16, the same order the pipes are within the bmp
904 *x
905 *y
906 drawpipefilled = FALSE for empty or TRUE for filled */
907
get_pipe_src_xy(int pipeid,int * x,int * y,int drawpipefilled)908 void get_pipe_src_xy(int pipeid, int *x, int *y, int drawpipefilled) {
909 if (pipeid > 16) {
910 printf("%s: Invalid pipe: %i\n", __func__, pipeid);
911 } else {
912 if (drawpipefilled) pipeid = pipeid + 17;
913 *x = (pipeid % 5) * tilew;
914 *y = (pipeid / 5) * tileh;
915 }
916 }
917
918 /***************************************************************************
919 * Manage User Input *
920 ***************************************************************************/
921 /* This manages all user input. */
922
manage_user_input(void)923 void manage_user_input(void) {
924 int mbut, mx, my, count;
925 int column = 0, row = 0;
926
927 while(SDL_PollEvent(&event)) {
928 switch(event.type) {
929 case SDL_KEYDOWN:
930 switch(event.key.keysym.sym) {
931 case SDLK_ESCAPE: /* Cancel on the Zaurus */
932 if (!fpstest) {
933 if(game_mode == GAMESHOWHELP) {
934 manage_help_input(SDLK_ESCAPE);
935 } else {
936 quit = 1;
937 }
938 }
939 break;
940 case SDLK_LEFT:
941 if (!fpstest) {
942 if(game_mode == GAMESHOWHELP) {
943 manage_help_input(SDLK_LEFT);
944 }
945 }
946 break;
947 case SDLK_RIGHT:
948 if (!fpstest) {
949 if(game_mode == GAMESHOWHELP) {
950 manage_help_input(SDLK_RIGHT);
951 }
952 }
953 break;
954 default:
955 break;
956 }
957 break;
958 case SDL_QUIT:
959 if (!fpstest) {
960 quit = 1;
961 }
962 break;
963 case SDL_MOUSEBUTTONDOWN:
964 if (!fpstest) {
965 mbut = SDL_GetMouseState(&mx, &my);
966
967 #ifdef DEBUG
968 printf("mbut=%i mx=%i my=%i\n", mbut, mx, my);
969 #endif
970
971 switch(mbut) {
972 case SDL_BUTTON_LEFT:
973 /* Process game board clicks */
974 if (game_mode == GAMEON) {
975 if (((xres == 320 || xres == 640) && (mx >= xres - BOARDW * tilew) && (mx < xres) && (my >= 0) && (my < yres)) || ((xres == 240 || xres == 480) && (mx >= 0) && (mx < xres) && (my >= 2 * tileh) && (my < 12 * tileh))) {
976 /* Convert the mouse coordinates to offsets into the board array */
977 if (xres == 320 || xres == 640) {
978 column = (mx - (xres - BOARDW * tilew)) / tilew;
979 row = my / tileh;
980 } else if (xres == 240 || xres == 480) {
981 column = mx / tilew;
982 row = (my - 2 * tileh) / tileh;
983 }
984
985 #ifdef DEBUG
986 printf("row column : %i %i\n", row, column);
987 #endif
988
989 /* Don't allow replacing of the end points. */
990 if (boardarray[row][column] > 1) {
991 /* Place pipe piece from start of preview array. */
992 if (boardarray[row][column] != NULLPIPEVAL) {
993 score = score + PIPEOVERWRITESCORE;
994 } else {
995 score = score + PIPEPLACEMENTSCORE;
996 }
997 boardarray[row][column] = previewarray[0];
998 /* Move all preview pieces down 1 place. */
999 for (count = 0; count < PREVIEWARRAYSIZE - 1; count++) {
1000 previewarray[count] = previewarray[count + 1];
1001 }
1002 /* Add a new preview piece at the end. */
1003 previewarray[PREVIEWARRAYSIZE - 1] = getnextpipepiece();
1004 /* Mark tile for drawing and redraw everything related */
1005 drawpipearray[0][0] = row; drawpipearray[0][1] = column; drawpipearray[0][2] = FALSE;
1006 drawpipearray[1][0] = NULLPIPEVAL;
1007 redraw = redraw | REDRAWTILE | REDRAWPIPE | REDRAWSCORE | REDRAWPREVIEW;
1008 } else if (boardarray[row][column] == 0) {
1009 score = score + gametime * FILLNOWSCORE;
1010 gametime = 0;
1011 redraw = redraw | REDRAWSCORE | REDRAWTIMER;
1012 createdeadpipesarray();
1013 }
1014
1015 #ifdef DEBUG
1016 printf("boardarray:-\n");
1017 for (row = 0; row < BOARDH; row++) {
1018 for (column = 0; column < BOARDW; column++) {
1019 printf("%3i ", boardarray[row][column]);
1020 }
1021 printf("\n");
1022 }
1023 printf("\n");
1024 #endif
1025 }
1026 }
1027 /* Process New Game clicks */
1028 if (game_mode == GAMEON || game_mode == GAMEFLASHHIGHSCORE || game_mode == GAMEOVER) {
1029 if (((xres == 320 || xres == 640) && (mx >= 0) && (mx < 3 * tilew) && (my >= 9.25 * tileh) && (my < 9.75 * tileh)) || ((xres == 240 || xres == 480) && (mx >= 6.9 * tilew) && (mx < 9.9 * tilew) && (my >= 12.43 * tileh) && (my < 12.93 * tileh))) {
1030 /* Initialise new game */
1031 initialise_new_game();
1032 #ifdef DEBUG
1033 printf("New Game\n");
1034 #endif
1035 }
1036 }
1037 /* Process Fill clicks */
1038 if (game_mode == GAMEON) {
1039 if (((xres == 320 || xres == 640) && (mx >= 0) && (mx < 1 * tilew) && (my >= 7.25 * tileh) && (my < 7.75 * tileh)) || ((xres == 240 || xres == 480) && (mx >= 4 * tilew) && (mx < 5 * tilew) && (my >= 12.43 * tileh) && (my < 12.93 * tileh))) {
1040 score = score + gametime * FILLNOWSCORE;
1041 gametime = 0;
1042 redraw = redraw | REDRAWSCORE | REDRAWTIMER;
1043 createdeadpipesarray();
1044 #ifdef DEBUG
1045 printf("Fill\n");
1046 #endif
1047 }
1048 }
1049 /* Process High Score clicks */
1050 if (game_mode == GAMEON || game_mode == GAMEFLASHHIGHSCORE || game_mode == GAMEOVER) {
1051 if (((xres == 320 || xres == 640) && (mx >= 0) && (mx < 3 * tilew) && (my >= 0.25 * tileh) && (my < 0.75 * tileh)) || ((xres == 240 || xres == 480) && (mx >= 3.7 * tilew) && (mx < 6.7 * tilew) && (my >= 0.25 * tileh) && (my < 0.75 * tileh))) {
1052 initialise_new_game();
1053 /* Copy the highscoreboard into the board array */
1054 for (row = 0; row < BOARDH; row++) {
1055 for (column = 0; column < BOARDW; column++) {
1056 boardarray[row][column] = highscoreboard[0][row * BOARDH + column];
1057 }
1058 }
1059 gametime = 0;
1060 disablescoring = TRUE; /* This is only used here to prevent the score from incrementing whilst filling. */
1061 createdeadpipesarray();
1062 #ifdef DEBUG
1063 printf("High Score\n");
1064 #endif
1065 }
1066 }
1067 /* Process Help clicks */
1068 if (game_mode == GAMEON || game_mode == GAMEFLASHHIGHSCORE || game_mode == GAMEOVER) {
1069 if (((xres == 320 || xres == 640) && (mx >= 0) && (mx < 1.4 * tilew) && (my >= 8.25 * tileh) && (my < 8.75 * tileh)) || ((xres == 240 || xres == 480) && (mx >= 5.25 * tilew) && (mx < 6.65 * tilew) && (my >= 12.43 * tileh) && (my < 12.93 * tileh))) {
1070 previous_game_mode = game_mode;
1071 game_mode = GAMESHOWHELP;
1072 redraw = redraw | REDRAWHELP;
1073 #ifdef DEBUG
1074 printf("Help\n");
1075 #endif
1076 }
1077 }
1078 /* Process Help->Left clicks.
1079 I've purposely made the hit area big. */
1080 if (game_mode == GAMESHOWHELP) {
1081 if (((xres == 320 || xres == 640) && (mx >= xres - BOARDW * tilew) && (mx < xres - (BOARDW - 1) * tilew) && (my >= (BOARDH - 1) * tileh) && (my < BOARDH * tileh)) || ((xres == 240 || xres == 480) && (mx >= 0) && (mx < 1 * tilew) && (my >= (BOARDH - 1) * tileh + 2 * tileh) && (my < BOARDH * tileh + 2 * tileh))) {
1082 manage_help_input(SDLK_LEFT);
1083 }
1084 }
1085 /* Process Help->Right clicks.
1086 I've purposely made the hit area big. */
1087 if (game_mode == GAMESHOWHELP) {
1088 if (((xres == 320 || xres == 640) && (mx >= xres - 1 * tilew) && (mx < xres) && (my >= (BOARDH - 1) * tileh) && (my < BOARDH * tileh)) || ((xres == 240 || xres == 480) && (mx >= xres - 1 * tilew) && (mx < xres) && (my >= (BOARDH - 1) * tileh + 2 * tileh) && (my < BOARDH * tileh + 2 * tileh))) {
1089 manage_help_input(SDLK_RIGHT);
1090 }
1091 }
1092 /* Process Help->Exit clicks */
1093 if (game_mode == GAMESHOWHELP) {
1094 if (((xres == 320 || xres == 640) && (mx >= xres - 5.6 * tilew) && (mx < xres - 4.4 * tilew) && (my >= yres - 0.75 * tileh) && (my < yres - 0.25 * tileh)) || ((xres == 240 || xres == 480) && (mx >= xres - 5.6 * tilew) && (mx < xres - 4.4 * tilew) && (my >= (BOARDH - 0.75) * tileh + 2 * tileh) && (my < (BOARDH - 0.25) * tileh + 2 * tileh))) {
1095 manage_help_input(SDLK_ESCAPE);
1096 }
1097 }
1098 break;
1099 default:
1100 break;
1101 }
1102 }
1103 default:
1104 break;
1105 }
1106 }
1107 }
1108
1109 /***************************************************************************
1110 * Manage Help Input *
1111 ***************************************************************************/
1112 /* This manages all user input relating to Help. */
1113
manage_help_input(int input)1114 void manage_help_input(int input) {
1115 int rowloop, colloop, count = 0, leakypipefound = FALSE;
1116 int nomorepipes, passcounter = FILLEDCOUNTERBASE, filled = TRUE, endpipefound = FALSE;
1117
1118 switch(input) {
1119 case SDLK_ESCAPE:
1120 game_mode = previous_game_mode;
1121 redraw = REDRAWALL;
1122 if (game_mode == GAMEFLASHHIGHSCORE || game_mode == GAMEOVER) {
1123 /* I originally wrote this game in Javascript for a web browser
1124 and it wasn't designed to have anything drawn over the top of
1125 it, so the pipe network needs to be rebuilt. At this point the
1126 deadpipesarray still holds the filled pipe network so it just
1127 needs to be decoded.*/
1128 do {
1129 nomorepipes = TRUE;
1130 for (rowloop = 0; rowloop < BOARDH; rowloop++) {
1131 for (colloop = 0; colloop < BOARDW; colloop++) {
1132 if (deadpipesarray[rowloop][colloop] == passcounter || deadpipesarray[rowloop][colloop] - LEAKYPIPEVAL == passcounter) {
1133 /* Mark pipe to be drawn */
1134 drawpipearray[count][0] = rowloop;
1135 drawpipearray[count][1] = colloop;
1136 drawpipearray[count][2] = filled;
1137 count++;
1138 /* If a leaky pipe is found then after this pass all pipes will be unfilled. */
1139 if (deadpipesarray[rowloop][colloop] >= FILLEDCOUNTERBASE + LEAKYPIPEVAL) {
1140 leakypipefound = TRUE;
1141 }
1142 /* At least one pipe was found for this pass */
1143 nomorepipes = FALSE;
1144 } else if (deadpipesarray[rowloop][colloop] == DEADPIPEVAL && boardarray[rowloop][colloop] == 1 && !endpipefound) {
1145 /* Mark the unvisited end pipe for drawing */
1146 drawpipearray[count][0] = rowloop;
1147 drawpipearray[count][1] = colloop;
1148 drawpipearray[count][2] = FALSE;
1149 count++;
1150 endpipefound = TRUE; /* Only record it once */
1151 }
1152 }
1153 }
1154 if(leakypipefound) filled = FALSE; /* Draw unfilled pipes from now on */
1155 passcounter++;
1156 } while(!nomorepipes);
1157 drawpipearray[count][0] = NULLPIPEVAL;
1158 redraw = (redraw | REDRAWPIPE) ^ REDRAWALLPIPES;
1159 }
1160 #ifdef DEBUG
1161 printf("Help->Exit\n");
1162 #endif
1163 break;
1164 case SDLK_LEFT:
1165 if(helppage > 0) {
1166 helppage = helppage - 1;
1167 redraw = redraw | REDRAWHELP;
1168 #ifdef DEBUG
1169 printf("Help->Left\n");
1170 #endif
1171 }
1172 break;
1173 case SDLK_RIGHT:
1174 if(helppage < HELPPAGES - 1) {
1175 helppage = helppage + 1;
1176 redraw = redraw | REDRAWHELP;
1177 #ifdef DEBUG
1178 printf("Help->Right\n");
1179 #endif
1180 }
1181 break;
1182 default:
1183 break;
1184 }
1185 }
1186
1187 /***************************************************************************
1188 * Create Dead Pipes Array *
1189 ***************************************************************************/
1190 /* This is the main guts of the game. Originally I wrote it in JavaScript for
1191 use in a browser and have simply pasted it here and converted it.
1192 I believe it's quite clever and I found it very enjoyable to write, having
1193 no idea how the pipe-filling would be accomplished. Basically a point is
1194 created at the start pipe and proceeds to travel through any connected
1195 pipes and splits at junctions. Each pipe that is filled is given a number
1196 starting at 20 and is incremented as the network fills. This is used to
1197 animate the fill with a timer so that all pipes marked 20 get shown, then
1198 next timer event all 21s get shown and so on. Leaky pipes are marked and
1199 so are dead pipes (those with no connection to the network). Enable DEBUG
1200 and look at the array dump in the console for a better understanding. */
1201
createdeadpipesarray(void)1202 void createdeadpipesarray(void) {
1203 int count = 0, rowloop = 0, colloop = 0;
1204 int pointexists = FALSE, endreached = FALSE, pointsconverge = FALSE;
1205 int leakcount = 0, deadcount = 0, freepointer = 0;
1206 int filledcounter = FILLEDCOUNTERBASE;
1207 int north = FALSE, south = FALSE, east = FALSE, west = FALSE;
1208 int targety = 0, targetx = 0;
1209 int targettype = NULLPIPEVAL, targetvalid = FALSE, targetvisited = FALSE;
1210 /* --- Create 2 dimensional array for the route tracing points. --- */
1211 int pointsarray[POINTSARRAYSIZE][4];
1212 for (rowloop = 0; rowloop < POINTSARRAYSIZE; rowloop++) {
1213 /* Array Format: y|x|direction|passcounter. */
1214 pointsarray[rowloop][0] = pointsarray[rowloop][1] = pointsarray[rowloop][3] = 0;
1215 pointsarray[rowloop][2] = NULLPIPEVAL; /* dead point. */
1216 }
1217
1218 /* Find endpoints in game board array. */
1219 for (rowloop = 0; rowloop < BOARDH; rowloop++) {
1220 for (colloop = 0; colloop < BOARDW; colloop++) {
1221 if (boardarray[rowloop][colloop] == 0) {
1222 /* Create a single point at start heading west (0=n|1=e|2=s|3=w). */
1223 pointsarray[POINTSARRAYSIZE - 1][0] = rowloop;
1224 pointsarray[POINTSARRAYSIZE - 1][1] = colloop;
1225 pointsarray[POINTSARRAYSIZE - 1][2] = 3;
1226 pointsarray[POINTSARRAYSIZE - 1][3] = filledcounter;
1227 }
1228 /* Duplicate the game board array into the dead pipes array. */
1229 deadpipesarray[rowloop][colloop] = boardarray[rowloop][colloop];
1230 }
1231 }
1232 /* MAIN LOOP. Do this while points exist (no points means no more routes). */
1233 do {
1234 pointexists = FALSE;
1235 for (rowloop = 0; rowloop < POINTSARRAYSIZE; rowloop++) {
1236 if (pointsarray[rowloop][2] != NULLPIPEVAL && pointsarray[rowloop][3] == filledcounter) {
1237 /* Get target yx.*/
1238 switch (pointsarray[rowloop][2]) { /* point direction. */
1239 case 0 : /* north. */
1240 targety = pointsarray[rowloop][0] - 1;
1241 targetx = pointsarray[rowloop][1];
1242 break;
1243 case 1 : /* east. */
1244 targety = pointsarray[rowloop][0];
1245 targetx = pointsarray[rowloop][1] + 1;
1246 break;
1247 case 2 : /* south. */
1248 targety = pointsarray[rowloop][0] + 1;
1249 targetx = pointsarray[rowloop][1];
1250 break;
1251 case 3 : /* west. */
1252 targety = pointsarray[rowloop][0];
1253 targetx = pointsarray[rowloop][1] - 1;
1254 break;
1255 }
1256 /* Get target pipe type. */
1257 if (targety < 0 || targety >= BOARDH || targetx < 0 || targetx >= BOARDW) {
1258 targettype = NULLPIPEVAL; /* targets outside the game board are invalid. */
1259 } else {
1260 targettype = boardarray[targety][targetx];
1261 }
1262 /* Get direction information on the target piece. */
1263 switch (targettype) {
1264 case 0 :
1265 north = FALSE; east = FALSE; south = FALSE; west = TRUE;
1266 break;
1267 case 1 :
1268 north = FALSE; east = TRUE; south = FALSE; west = FALSE;
1269 break;
1270 case 2 :
1271 north = TRUE; east = FALSE; south = FALSE; west = TRUE;
1272 break;
1273 case 3 :
1274 north = FALSE; east = FALSE; south = TRUE; west = TRUE;
1275 break;
1276 case 4 :
1277 north = FALSE; east = TRUE; south = TRUE; west = FALSE;
1278 break;
1279 case 5 :
1280 north = TRUE; east = TRUE; south = FALSE; west = FALSE;
1281 break;
1282 case 6 :
1283 north = TRUE; east = FALSE; south = TRUE; west = TRUE;
1284 break;
1285 case 7 :
1286 north = FALSE; east = TRUE; south = TRUE; west = TRUE;
1287 break;
1288 case 8 :
1289 north = TRUE; east = TRUE; south = TRUE; west = FALSE;
1290 break;
1291 case 9 :
1292 north = TRUE; east = TRUE; south = FALSE; west = TRUE;
1293 break;
1294 case 10 :
1295 north = TRUE; east = TRUE; south = TRUE; west = TRUE;
1296 break;
1297 case 11 :
1298 north = FALSE; east = TRUE; south = FALSE; west = TRUE;
1299 break;
1300 case 12 :
1301 north = TRUE; east = FALSE; south = TRUE; west = FALSE;
1302 break;
1303 case 13 :
1304 north = FALSE; east = FALSE; south = FALSE; west = TRUE;
1305 break;
1306 case 14 :
1307 north = TRUE; east = FALSE; south = FALSE; west = FALSE;
1308 break;
1309 case 15 :
1310 north = FALSE; east = TRUE; south = FALSE; west = FALSE;
1311 break;
1312 case 16 :
1313 north = FALSE; east = FALSE; south = TRUE; west = FALSE;
1314 break;
1315 default :
1316 north = FALSE; east = FALSE; south = FALSE; west = FALSE;
1317 break;
1318 }
1319 /* Get validity of target move. */
1320 targetvalid = FALSE;
1321 if (pointsarray[rowloop][2] == 0 && south == TRUE) targetvalid = TRUE;
1322 if (pointsarray[rowloop][2] == 1 && west == TRUE) targetvalid = TRUE;
1323 if (pointsarray[rowloop][2] == 2 && north == TRUE) targetvalid = TRUE;
1324 if (pointsarray[rowloop][2] == 3 && east == TRUE) targetvalid = TRUE;
1325 /* Get visited status of target pipe. */
1326 targetvisited = FALSE;
1327 if (targetvalid) { /* don't try and reference array elements using -1 ;) */
1328 if (deadpipesarray[targety][targetx] >= FILLEDCOUNTERBASE && deadpipesarray[targety][targetx] != NULLPIPEVAL) targetvisited = TRUE;
1329 }
1330 /* Now that we have all the info we make the MAIN DECISIONS HERE. */
1331 /* If source is THE endpoint... */
1332 if (boardarray[pointsarray[rowloop][0]][pointsarray[rowloop][1]] == 1) {
1333 if (deadpipesarray[pointsarray[rowloop][0]][pointsarray[rowloop][1]] >= 0 && deadpipesarray[pointsarray[rowloop][0]][pointsarray[rowloop][1]] < FILLEDCOUNTERBASE) deadpipesarray[pointsarray[rowloop][0]][pointsarray[rowloop][1]] = filledcounter; /* mark source as filled. */
1334 pointsarray[rowloop][2] = NULLPIPEVAL; /* kill current point. */
1335 endreached = TRUE;
1336 } else {
1337 /* ElseIf target is valid and not visited... */
1338 if (targetvalid && !targetvisited) {
1339 if (deadpipesarray[pointsarray[rowloop][0]][pointsarray[rowloop][1]] >= 0 && deadpipesarray[pointsarray[rowloop][0]][pointsarray[rowloop][1]] < FILLEDCOUNTERBASE) deadpipesarray[pointsarray[rowloop][0]][pointsarray[rowloop][1]] = filledcounter; /* mark source as filled. */
1340 pointsarray[rowloop][2] = NULLPIPEVAL; /* kill current point. */
1341 /* Create a new point at target for each direction. */
1342 /* Merge converging paths, caused when 2 sources converge on the same target at the same time. */
1343 if (north) {
1344 pointsconverge = FALSE;
1345 for (count = 0; count < POINTSARRAYSIZE; count++) {
1346 if (pointsarray[count][2] != NULLPIPEVAL) {
1347 /* We don't want 2 points in the same square going in the same direction. */
1348 if (pointsarray[count][0] == targety && pointsarray[count][1] == targetx && pointsarray[count][2] == 0) {
1349 pointsconverge = TRUE;
1350 }
1351 } else {
1352 freepointer = count; /* record this as we'll use it to store the new point. */
1353 }
1354 }
1355 if (!pointsconverge) {
1356 pointsarray[freepointer][0] = targety; pointsarray[freepointer][1] = targetx;
1357 pointsarray[freepointer][2] = 0; pointsarray[freepointer][3] = filledcounter + 1; /* process it next do-while iteration. */
1358 pointexists = TRUE;
1359 }
1360 }
1361 if (east) {
1362 pointsconverge = FALSE;
1363 for (count = 0; count < POINTSARRAYSIZE; count++) {
1364 if (pointsarray[count][2] != NULLPIPEVAL) {
1365 /* We don't want 2 points in the same square going in the same direction. */
1366 if (pointsarray[count][0] == targety && pointsarray[count][1] == targetx && pointsarray[count][2] == 1) {
1367 pointsconverge = TRUE;
1368 }
1369 } else {
1370 freepointer = count; /* record this as we'll use it to store the new point. */
1371 }
1372 }
1373 if (!pointsconverge) {
1374 pointsarray[freepointer][0] = targety; pointsarray[freepointer][1] = targetx;
1375 pointsarray[freepointer][2] = 1; pointsarray[freepointer][3] = filledcounter + 1; /* process it next do-while iteration. */
1376 pointexists = TRUE;
1377 }
1378 }
1379 if (south) {
1380 pointsconverge = FALSE;
1381 for (count = 0; count < POINTSARRAYSIZE; count++) {
1382 if (pointsarray[count][2] != NULLPIPEVAL) {
1383 /* We don't want 2 points in the same square going in the same direction. */
1384 if (pointsarray[count][0] == targety && pointsarray[count][1] == targetx && pointsarray[count][2] == 2) {
1385 pointsconverge = TRUE;
1386 }
1387 } else {
1388 freepointer = count; /* record this as we'll use it to store the new point. */
1389 }
1390 }
1391 if (!pointsconverge) {
1392 pointsarray[freepointer][0] = targety; pointsarray[freepointer][1] = targetx;
1393 pointsarray[freepointer][2] = 2; pointsarray[freepointer][3] = filledcounter + 1; /* process it next do-while iteration. */
1394 pointexists = TRUE;
1395 }
1396 }
1397 if (west) {
1398 pointsconverge = FALSE;
1399 for (count = 0; count < POINTSARRAYSIZE; count++) {
1400 if (pointsarray[count][2] != NULLPIPEVAL) {
1401 /* We don't want 2 points in the same square going in the same direction. */
1402 if (pointsarray[count][0] == targety && pointsarray[count][1] == targetx && pointsarray[count][2] == 3) {
1403 pointsconverge = TRUE;
1404 }
1405 } else {
1406 freepointer = count; /* record this as we'll use it to store the new point. */
1407 }
1408 }
1409 if (!pointsconverge) {
1410 pointsarray[freepointer][0] = targety; pointsarray[freepointer][1] = targetx;
1411 pointsarray[freepointer][2] = 3; pointsarray[freepointer][3] = filledcounter + 1; /* process it next do-while iteration. */
1412 pointexists = TRUE;
1413 }
1414 }
1415 } else {
1416 /* ElseIf target is valid and visited... */
1417 if (targetvalid && targetvisited) {
1418 if (deadpipesarray[pointsarray[rowloop][0]][pointsarray[rowloop][1]] >= 0 && deadpipesarray[pointsarray[rowloop][0]][pointsarray[rowloop][1]] < FILLEDCOUNTERBASE) deadpipesarray[pointsarray[rowloop][0]][pointsarray[rowloop][1]] = filledcounter; /* mark source as filled. */
1419 pointsarray[rowloop][2] = NULLPIPEVAL; /* kill current point. */
1420 } else {
1421 /* ElseIf target is not valid... */
1422 if (!targetvalid) {
1423 deadpipesarray[pointsarray[rowloop][0]][pointsarray[rowloop][1]] = filledcounter + LEAKYPIPEVAL; /* mark source as leaky retaining fill count (important). */
1424 pointsarray[rowloop][2] = NULLPIPEVAL; /* kill current point. */
1425 leakcount++;
1426 }
1427 }
1428 }
1429 }
1430 }
1431 }
1432 filledcounter++;
1433 } while (pointexists);
1434
1435 /* MARK DEAD PIPES. The easy bit :) */
1436 deadcount = 0;
1437 for (rowloop = 0; rowloop < BOARDH; rowloop++) {
1438 for (colloop = 0; colloop < BOARDW; colloop++) {
1439 if (deadpipesarray[rowloop][colloop] >= 0 && deadpipesarray[rowloop][colloop] < FILLEDCOUNTERBASE) {
1440 deadpipesarray[rowloop][colloop] = DEADPIPEVAL;
1441 deadcount++; /* count can include endpoint if it is unvisited. */
1442 }
1443 }
1444 }
1445
1446 #ifdef DEBUG
1447 printf("deadpipesarray:-\n");
1448 for (rowloop = 0; rowloop < BOARDH; rowloop++) {
1449 for (colloop = 0; colloop < BOARDW; colloop++) {
1450 printf("%3i ", deadpipesarray[rowloop][colloop]);
1451 }
1452 printf("\n");
1453 }
1454 printf("\n");
1455 #endif
1456
1457 cleardeadpipesy = 0;
1458 cleardeadpipesx = 0;
1459 cleardeadpipes_ticks = 0;
1460 game_mode = GAMECLEARDEADPIPES; /* And off we go next main loop cycle... */
1461 }
1462
1463 /***************************************************************************
1464 * Clear Dead Pipes *
1465 ***************************************************************************/
1466 /* This clears one dead pipe at a time from the board array and the screen
1467 and is designed to be called from a timer so that it appears animated. */
1468
cleardeadpipes(void)1469 void cleardeadpipes(void) {
1470 int deadpipefound = FALSE, nomorepipes = FALSE;
1471
1472 do {
1473 /* Officially if the endpoint is unvisited it's dead, but we'll leave it onscreen anyway. */
1474 if (deadpipesarray[cleardeadpipesy][cleardeadpipesx] == DEADPIPEVAL && boardarray[cleardeadpipesy][cleardeadpipesx] != 1) {
1475 /* Erase dead pipe from the screen. */
1476 drawpipearray[0][0] = cleardeadpipesy; drawpipearray[0][1] = cleardeadpipesx;
1477 drawpipearray[1][0] = NULLPIPEVAL;
1478 redraw = redraw | REDRAWTILE;
1479 /* Erase dead pipe from the board array. */
1480 boardarray[cleardeadpipesy][cleardeadpipesx] = NULLPIPEVAL;
1481 score = score + DEADPIPESCORE;
1482 redraw = redraw | REDRAWSCORE;
1483 deadpipefound = TRUE;
1484 }
1485 /* Work our way from top left to bottom right. */
1486 cleardeadpipesx++;
1487 if (cleardeadpipesx >= BOARDW) {
1488 cleardeadpipesx = 0; cleardeadpipesy++;
1489 if (cleardeadpipesy >= BOARDH) nomorepipes = TRUE;
1490 }
1491 } while (!deadpipefound && !nomorepipes);
1492 if (nomorepipes) {
1493 fillpipespasscounter = FILLEDCOUNTERBASE;
1494 fillpipes_ticks = 0;
1495 game_mode = GAMEFILLPIPES; /* And off we go next main loop cycle... */
1496 }
1497 }
1498
1499 /***************************************************************************
1500 * Fill Pipes *
1501 ***************************************************************************/
1502 /* This fills one or several pipes at a time. */
1503
fillpipes(void)1504 void fillpipes(void) {
1505 int rowloop, colloop, count = 0;
1506 int leakypipefound, nomorepipes;
1507
1508 /* Show all filled pipes onscreen for this passcounter */
1509 leakypipefound = FALSE;
1510 nomorepipes = TRUE;
1511 for (rowloop = 0; rowloop < BOARDH; rowloop++) {
1512 for (colloop = 0; colloop < BOARDW; colloop++) {
1513 if (deadpipesarray[rowloop][colloop] == fillpipespasscounter || deadpipesarray[rowloop][colloop] - LEAKYPIPEVAL == fillpipespasscounter) {
1514 /* Draw filled pipe. */
1515 drawpipearray[count][0] = rowloop;
1516 drawpipearray[count][1] = colloop;
1517 drawpipearray[count][2] = TRUE;
1518 drawpipearray[count + 1][0] = NULLPIPEVAL;
1519 count++;
1520 redraw = redraw | REDRAWTILE | REDRAWPIPE;
1521 /* When displaying the highscoreboard ignore scoring */
1522 if (!disablescoring) {
1523 score = score + FILLEDPIPESCORE;
1524 redraw = redraw | REDRAWSCORE;
1525 }
1526 /* If a leaky pipe is found then flag it */
1527 if (deadpipesarray[rowloop][colloop] >= FILLEDCOUNTERBASE + LEAKYPIPEVAL) leakypipefound = TRUE;
1528 } else {
1529 if (deadpipesarray[rowloop][colloop] > fillpipespasscounter && deadpipesarray[rowloop][colloop] < DEADPIPEVAL) nomorepipes = FALSE;
1530 }
1531 }
1532 }
1533
1534 fillpipespasscounter++;
1535
1536 if (leakypipefound || nomorepipes) {
1537 /* Ok, last bit: high score, again ignoring whilst displaying the highscoreboard */
1538 if (!disablescoring && score > highscoretable[0]) {
1539 highscoretable[0] = score;
1540 /* Copy the board into the highscoreboard */
1541 for (rowloop = 0; rowloop < BOARDH; rowloop++) {
1542 for (colloop = 0; colloop < BOARDW; colloop++) {
1543 highscoreboard[0][rowloop * BOARDH + colloop] = boardarray[rowloop][colloop];
1544 }
1545 }
1546 redraw = redraw | REDRAWHIGHSCORE;
1547 flashhighscore_ticks = SDL_GetTicks();
1548 game_mode = GAMEFLASHHIGHSCORE;
1549
1550 #ifdef DEBUG
1551 printf("Saving resource file -> ");
1552 #endif
1553
1554 save_rc_file(); /* This saves the new highscore[s] */
1555 } else {
1556 game_mode = GAMEOVER;
1557 }
1558 }
1559 }
1560
1561 /***************************************************************************
1562 * Read Resource File *
1563 ***************************************************************************/
1564
read_rc_file(void)1565 void read_rc_file(void) {
1566 char buffer[256];
1567 FILE* file;
1568 int result, value, count;
1569
1570 strcpy(buffer, user_home_dir);
1571 strcat(buffer, "/");
1572 strcat(buffer, RESOURCEFILE);
1573
1574 #ifdef DEBUG
1575 printf("%s\n", buffer);
1576 #endif
1577
1578 if ((file = fopen(buffer,"r")) == NULL) {
1579 printf("%s: Cannot read from file %s\n", __func__, buffer);
1580 return;
1581 }
1582
1583 result = fscanf(file,"%s", buffer); /* [highscore0] */
1584 if (result != 1 || strcmp(buffer, "[highscore0]") != 0) {
1585 printf("%s: Data from resource file is unreliable\n", __func__);
1586 fclose(file);
1587 return;
1588 } else {
1589 #ifdef DEBUG
1590 printf("%s\n", buffer);
1591 #endif
1592 }
1593 result = fscanf(file,"%i", &value); /* highscore0 */
1594 if (result != 1) {
1595 printf("%s: Data from resource file is unreliable\n", __func__);
1596 fclose(file);
1597 return;
1598 } else {
1599 #ifdef DEBUG
1600 printf("%d\n", value);
1601 #endif
1602 highscoretable[0] = value;
1603 }
1604
1605 result = fscanf(file,"%s", buffer); /* [highscoreboard0] */
1606 if (result != 1 || strcmp(buffer, "[highscoreboard0]") != 0) {
1607 printf("%s: Data from resource file is unreliable\n", __func__);
1608 fclose(file);
1609 return;
1610 } else {
1611 #ifdef DEBUG
1612 printf("%s\n", buffer);
1613 #endif
1614 }
1615 for (count = 0; count < BOARDH * BOARDW; count++) {
1616 result = fscanf(file,"%i", &value); /* pipe piece id */
1617 if (result != 1) {
1618 printf("%s: Data from resource file is unreliable\n", __func__);
1619 fclose(file);
1620 return;
1621 } else {
1622 #ifdef DEBUG
1623 if (count > 0 && count % BOARDH == 0) printf("\n");
1624 printf("%3i ", value);
1625 #endif
1626 highscoreboard[0][count] = value;
1627 }
1628 }
1629 #ifdef DEBUG
1630 printf("\n");
1631 #endif
1632
1633 fclose(file);
1634 }
1635
1636 /***************************************************************************
1637 * Save Resource File *
1638 ***************************************************************************/
1639
save_rc_file(void)1640 void save_rc_file(void) {
1641 char buffer[256];
1642 FILE* file;
1643 int count;
1644
1645 strcpy(buffer, user_home_dir);
1646 strcat(buffer, "/");
1647 strcat(buffer, RESOURCEFILE);
1648
1649 #ifdef DEBUG
1650 printf("%s\n", buffer);
1651 #endif
1652
1653 if ((file = fopen(buffer,"w")) == NULL) {
1654 printf("%s: Cannot write to file %s\n", __func__, buffer);
1655 return;
1656 }
1657
1658 fprintf(file,"[highscore0]\n%i\n", highscoretable[0]);
1659
1660 fprintf(file,"[highscoreboard0]\n");
1661 for (count = 0; count < BOARDH * BOARDW; count++) {
1662 if (count > 0 && count % BOARDH == 0) fprintf(file,"\n");
1663 fprintf(file,"%3i ", highscoreboard[0][count]);
1664 }
1665 fprintf(file,"\n");
1666
1667 fclose(file);
1668 }
1669
1670
1671