fix wrong score recording.
[kugel-rb.git] / apps / plugins / snake2.c
blob67678f5e03a9ad82aaa985f38d8cf8e1cfde1778
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2003 Mat Holton
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
23 Snake2!
25 Board consists of a WIDTHxHEIGHT grid. If board element is 0 then nothing is
26 there otherwise it is part of the snake or a wall.
28 Head and Tail are stored
32 #include "plugin.h"
33 #ifdef HAVE_LCD_BITMAP
35 PLUGIN_HEADER
37 #define WIDTH 28
38 #define HEIGHT 16
40 #if (LCD_WIDTH >= 160) && (LCD_HEIGHT >= 128) && (LCD_DEPTH >= 1)
41 #include "pluginbitmaps/snake2_header1.h"
42 #include "pluginbitmaps/snake2_header2.h"
43 #include "pluginbitmaps/snake2_left.h"
44 #include "pluginbitmaps/snake2_right.h"
45 #include "pluginbitmaps/snake2_bottom.h"
46 #define BMPHEIGHT_snake2_header BMPHEIGHT_snake2_header1
47 #define BMPWIDTH_snake2_header BMPWIDTH_snake2_header1
48 #endif
51 #if (LCD_WIDTH >= 320) && (LCD_HEIGHT >= 240)
52 #define MULTIPLIER 10 /*Modifier for porting on other screens*/
53 #define MODIFIER_1 10
54 #define MODIFIER_2 8
55 #define CENTER_X 20
56 #define CENTER_Y 55
57 #define TOP_X1 34 /* x-coord of the upperleft item (game type) */
58 #define TOP_X2 281 /* x-coord of the upperright item (maze type) */
59 #define TOP_X3 42 /* x-coord of the lowerleft item (speed) */
60 #define TOP_X4 274 /* x-coord of the lowerright item (hi-score) */
61 #define TOP_Y1 4 /* y-coord of the top row of items */
62 #define TOP_Y2 25 /* y-coord of the bottom row of items */
63 #elif (LCD_WIDTH >= 240) && (LCD_HEIGHT >= 168)
64 #define MULTIPLIER 8
65 #define MODIFIER_1 8
66 #define MODIFIER_2 6
67 #define CENTER_X 8
68 #define CENTER_Y 34
69 #define TOP_X1 34
70 #define TOP_X2 201
71 #define TOP_X3 42
72 #define TOP_X4 194
73 #define TOP_Y1 4
74 #define TOP_Y2 25
75 #elif (LCD_WIDTH >= 220) && (LCD_HEIGHT >= 176)
76 #define MULTIPLIER 7
77 #define MODIFIER_1 7
78 #define MODIFIER_2 5
79 #define CENTER_X 12
80 #define CENTER_Y 46
81 #define TOP_X1 34
82 #define TOP_X2 181
83 #define TOP_X3 42
84 #define TOP_X4 174
85 #define TOP_Y1 4
86 #define TOP_Y2 25
87 #elif (LCD_WIDTH >= 176) && (LCD_HEIGHT >= 132)
88 #define MULTIPLIER 5
89 #define MODIFIER_1 5
90 #define MODIFIER_2 3
91 #define CENTER_X 18
92 #define CENTER_Y 40
93 #define TOP_X1 34
94 #define TOP_X2 137
95 #define TOP_X3 42
96 #define TOP_X4 130
97 #define TOP_Y1 4
98 #define TOP_Y2 25
99 #elif (LCD_WIDTH >= 160) && (LCD_HEIGHT >= 128)
100 #define MULTIPLIER 5
101 #define MODIFIER_1 5
102 #define MODIFIER_2 3
103 #define CENTER_X 10
104 #define CENTER_Y 38
105 #define TOP_X1 34
106 #define TOP_X2 121
107 #define TOP_X3 42
108 #define TOP_X4 114
109 #define TOP_Y1 4
110 #define TOP_Y2 25
111 #else
112 #define MULTIPLIER 4
113 #define MODIFIER_1 4
114 #define MODIFIER_2 2
115 #define CENTER_X 0
116 #define CENTER_Y 0
118 #endif
120 /* variable button definitions */
121 #if CONFIG_KEYPAD == RECORDER_PAD
122 #define SNAKE2_LEFT BUTTON_LEFT
123 #define SNAKE2_RIGHT BUTTON_RIGHT
124 #define SNAKE2_UP BUTTON_UP
125 #define SNAKE2_DOWN BUTTON_DOWN
126 #define SNAKE2_QUIT BUTTON_OFF
127 #define SNAKE2_LEVEL_UP BUTTON_UP
128 #define SNAKE2_LEVEL_DOWN BUTTON_DOWN
129 #define SNAKE2_MAZE_NEXT BUTTON_RIGHT
130 #define SNAKE2_MAZE_LAST BUTTON_LEFT
131 #define SNAKE2_SELECT_TYPE BUTTON_F3
132 #define SNAKE2_PLAYPAUSE BUTTON_PLAY
133 #define SNAKE2_PLAYPAUSE_TEXT "Play"
135 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
136 #define SNAKE2_LEFT BUTTON_LEFT
137 #define SNAKE2_RIGHT BUTTON_RIGHT
138 #define SNAKE2_UP BUTTON_UP
139 #define SNAKE2_DOWN BUTTON_DOWN
140 #define SNAKE2_QUIT BUTTON_OFF
141 #define SNAKE2_LEVEL_UP BUTTON_UP
142 #define SNAKE2_LEVEL_DOWN BUTTON_DOWN
143 #define SNAKE2_MAZE_NEXT BUTTON_RIGHT
144 #define SNAKE2_MAZE_LAST BUTTON_LEFT
145 #define SNAKE2_SELECT_TYPE BUTTON_F3
146 #define SNAKE2_PLAYPAUSE BUTTON_SELECT
147 #define SNAKE2_PLAYPAUSE_TEXT "Select"
149 #elif CONFIG_KEYPAD == ONDIO_PAD
150 #define SNAKE2_LEFT BUTTON_LEFT
151 #define SNAKE2_RIGHT BUTTON_RIGHT
152 #define SNAKE2_UP BUTTON_UP
153 #define SNAKE2_DOWN BUTTON_DOWN
154 #define SNAKE2_QUIT BUTTON_OFF
155 #define SNAKE2_LEVEL_UP BUTTON_UP
156 #define SNAKE2_LEVEL_DOWN BUTTON_DOWN
157 #define SNAKE2_MAZE_NEXT BUTTON_RIGHT
158 #define SNAKE2_SELECT_TYPE BUTTON_LEFT
159 #define SNAKE2_PLAYPAUSE BUTTON_MENU
160 #define SNAKE2_PLAYPAUSE_TEXT "Menu"
162 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
163 (CONFIG_KEYPAD == IRIVER_H300_PAD)
164 #define SNAKE2_LEFT BUTTON_LEFT
165 #define SNAKE2_RIGHT BUTTON_RIGHT
166 #define SNAKE2_UP BUTTON_UP
167 #define SNAKE2_DOWN BUTTON_DOWN
168 #define SNAKE2_QUIT BUTTON_OFF
169 #define SNAKE2_LEVEL_UP BUTTON_UP
170 #define SNAKE2_LEVEL_DOWN BUTTON_DOWN
171 #define SNAKE2_MAZE_NEXT BUTTON_RIGHT
172 #define SNAKE2_MAZE_LAST BUTTON_LEFT
173 #define SNAKE2_SELECT_TYPE BUTTON_MODE
174 #define SNAKE2_PLAYPAUSE BUTTON_ON
175 #define SNAKE2_PLAYPAUSE_TEXT "Play"
177 #define SNAKE2_RC_QUIT BUTTON_RC_STOP
178 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
179 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
180 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
181 #define SNAKE2_LEFT BUTTON_LEFT
182 #define SNAKE2_RIGHT BUTTON_RIGHT
183 #define SNAKE2_UP BUTTON_MENU
184 #define SNAKE2_DOWN BUTTON_PLAY
185 #define SNAKE2_QUIT (BUTTON_SELECT | BUTTON_MENU)
186 #define SNAKE2_LEVEL_UP BUTTON_SCROLL_FWD
187 #define SNAKE2_LEVEL_DOWN BUTTON_SCROLL_BACK
188 #define SNAKE2_MAZE_NEXT BUTTON_RIGHT
189 #define SNAKE2_MAZE_LAST BUTTON_LEFT
190 #define SNAKE2_SELECT_TYPE BUTTON_PLAY
191 #define SNAKE2_PLAYPAUSE BUTTON_SELECT
192 #define SNAKE2_PLAYPAUSE_TEXT "Select"
194 #elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
195 #define SNAKE2_LEFT BUTTON_LEFT
196 #define SNAKE2_RIGHT BUTTON_RIGHT
197 #define SNAKE2_UP BUTTON_UP
198 #define SNAKE2_DOWN BUTTON_DOWN
199 #define SNAKE2_QUIT BUTTON_POWER
200 #define SNAKE2_LEVEL_UP BUTTON_UP
201 #define SNAKE2_LEVEL_DOWN BUTTON_DOWN
202 #define SNAKE2_MAZE_NEXT BUTTON_RIGHT
203 #define SNAKE2_MAZE_LAST BUTTON_LEFT
204 #define SNAKE2_SELECT_TYPE BUTTON_PLAY
205 #define SNAKE2_PLAYPAUSE BUTTON_SELECT
206 #define SNAKE2_PLAYPAUSE_TEXT "Select"
208 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
209 #define SNAKE2_LEFT BUTTON_LEFT
210 #define SNAKE2_RIGHT BUTTON_RIGHT
211 #define SNAKE2_UP BUTTON_UP
212 #define SNAKE2_DOWN BUTTON_DOWN
213 #define SNAKE2_QUIT BUTTON_POWER
214 #define SNAKE2_LEVEL_UP BUTTON_UP
215 #define SNAKE2_LEVEL_DOWN BUTTON_DOWN
216 #define SNAKE2_MAZE_NEXT BUTTON_RIGHT
217 #define SNAKE2_MAZE_LAST BUTTON_LEFT
218 #define SNAKE2_SELECT_TYPE BUTTON_MENU
219 #define SNAKE2_PLAYPAUSE BUTTON_SELECT
220 #define SNAKE2_PLAYPAUSE_TEXT "Select"
222 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
223 (CONFIG_KEYPAD == SANSA_C200_PAD)
224 #define SNAKE2_LEFT BUTTON_LEFT
225 #define SNAKE2_RIGHT BUTTON_RIGHT
226 #define SNAKE2_UP BUTTON_UP
227 #define SNAKE2_DOWN BUTTON_DOWN
228 #define SNAKE2_QUIT BUTTON_POWER
229 #define SNAKE2_LEVEL_UP BUTTON_UP
230 #define SNAKE2_LEVEL_DOWN BUTTON_DOWN
231 #define SNAKE2_MAZE_NEXT BUTTON_RIGHT
232 #define SNAKE2_MAZE_LAST BUTTON_LEFT
233 #define SNAKE2_SELECT_TYPE BUTTON_REC
234 #define SNAKE2_PLAYPAUSE BUTTON_SELECT
235 #define SNAKE2_PLAYPAUSE_TEXT "Select"
237 #elif (CONFIG_KEYPAD == SANSA_CLIP_PAD) || \
238 (CONFIG_KEYPAD == SANSA_M200_PAD)
239 #define SNAKE2_LEFT BUTTON_LEFT
240 #define SNAKE2_RIGHT BUTTON_RIGHT
241 #define SNAKE2_UP BUTTON_UP
242 #define SNAKE2_DOWN BUTTON_DOWN
243 #define SNAKE2_QUIT BUTTON_POWER
244 #define SNAKE2_LEVEL_UP BUTTON_UP
245 #define SNAKE2_LEVEL_DOWN BUTTON_DOWN
246 #define SNAKE2_MAZE_NEXT BUTTON_RIGHT
247 #define SNAKE2_MAZE_LAST BUTTON_LEFT
248 #define SNAKE2_SELECT_TYPE BUTTON_VOL_UP
249 #define SNAKE2_PLAYPAUSE BUTTON_SELECT
250 #define SNAKE2_PLAYPAUSE_TEXT "Select"
252 #elif (CONFIG_KEYPAD == SANSA_FUZE_PAD)
253 #define SNAKE2_LEFT BUTTON_LEFT
254 #define SNAKE2_RIGHT BUTTON_RIGHT
255 #define SNAKE2_UP BUTTON_UP
256 #define SNAKE2_DOWN BUTTON_DOWN
257 #define SNAKE2_QUIT (BUTTON_HOME|BUTTON_REPEAT)
258 #define SNAKE2_LEVEL_UP BUTTON_UP
259 #define SNAKE2_LEVEL_DOWN BUTTON_DOWN
260 #define SNAKE2_MAZE_NEXT BUTTON_RIGHT
261 #define SNAKE2_MAZE_LAST BUTTON_LEFT
262 #define SNAKE2_SELECT_TYPE BUTTON_SELECT|BUTTON_REL
263 #define SNAKE2_PLAYPAUSE BUTTON_SELECT|BUTTON_REPEAT
264 #define SNAKE2_PLAYPAUSE_TEXT "Hold Select"
266 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
267 #define SNAKE2_LEFT BUTTON_LEFT
268 #define SNAKE2_RIGHT BUTTON_RIGHT
269 #define SNAKE2_UP BUTTON_SCROLL_UP
270 #define SNAKE2_DOWN BUTTON_SCROLL_DOWN
271 #define SNAKE2_QUIT BUTTON_POWER
272 #define SNAKE2_LEVEL_UP BUTTON_SCROLL_UP
273 #define SNAKE2_LEVEL_DOWN BUTTON_SCROLL_DOWN
274 #define SNAKE2_MAZE_NEXT BUTTON_RIGHT
275 #define SNAKE2_MAZE_LAST BUTTON_LEFT
276 #define SNAKE2_SELECT_TYPE BUTTON_PLAY
277 #define SNAKE2_PLAYPAUSE BUTTON_FF
278 #define SNAKE2_PLAYPAUSE_TEXT "FF"
280 #elif (CONFIG_KEYPAD == GIGABEAT_S_PAD)
281 #define SNAKE2_LEFT BUTTON_LEFT
282 #define SNAKE2_RIGHT BUTTON_RIGHT
283 #define SNAKE2_UP BUTTON_UP
284 #define SNAKE2_DOWN BUTTON_DOWN
285 #define SNAKE2_QUIT BUTTON_BACK
286 #define SNAKE2_LEVEL_UP BUTTON_UP
287 #define SNAKE2_LEVEL_DOWN BUTTON_DOWN
288 #define SNAKE2_MAZE_NEXT BUTTON_RIGHT
289 #define SNAKE2_MAZE_LAST BUTTON_LEFT
290 #define SNAKE2_SELECT_TYPE BUTTON_MENU
291 #define SNAKE2_PLAYPAUSE BUTTON_SELECT
292 #define SNAKE2_PLAYPAUSE_TEXT "Select"
294 #elif (CONFIG_KEYPAD == MROBE100_PAD)
295 #define SNAKE2_LEFT BUTTON_LEFT
296 #define SNAKE2_RIGHT BUTTON_RIGHT
297 #define SNAKE2_UP BUTTON_UP
298 #define SNAKE2_DOWN BUTTON_DOWN
299 #define SNAKE2_QUIT BUTTON_POWER
300 #define SNAKE2_LEVEL_UP BUTTON_UP
301 #define SNAKE2_LEVEL_DOWN BUTTON_DOWN
302 #define SNAKE2_MAZE_NEXT BUTTON_RIGHT
303 #define SNAKE2_MAZE_LAST BUTTON_LEFT
304 #define SNAKE2_SELECT_TYPE BUTTON_MENU
305 #define SNAKE2_PLAYPAUSE BUTTON_SELECT
306 #define SNAKE2_PLAYPAUSE_TEXT "Select"
308 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
309 #define SNAKE2_LEFT BUTTON_RC_REW
310 #define SNAKE2_RIGHT BUTTON_RC_FF
311 #define SNAKE2_UP BUTTON_RC_VOL_UP
312 #define SNAKE2_DOWN BUTTON_RC_VOL_DOWN
313 #define SNAKE2_QUIT BUTTON_RC_REC
314 #define SNAKE2_LEVEL_UP BUTTON_RC_VOL_UP
315 #define SNAKE2_LEVEL_DOWN BUTTON_RC_VOL_DOWN
316 #define SNAKE2_MAZE_NEXT BUTTON_RC_FF
317 #define SNAKE2_MAZE_LAST BUTTON_RC_REW
318 #define SNAKE2_SELECT_TYPE BUTTON_RC_MODE
319 #define SNAKE2_PLAYPAUSE BUTTON_RC_PLAY
320 #define SNAKE2_PLAYPAUSE_TEXT "Play"
322 #elif (CONFIG_KEYPAD == COWOND2_PAD)
323 #define SNAKE2_QUIT BUTTON_POWER
325 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
326 #define SNAKE2_LEFT BUTTON_LEFT
327 #define SNAKE2_RIGHT BUTTON_RIGHT
328 #define SNAKE2_UP BUTTON_UP
329 #define SNAKE2_DOWN BUTTON_DOWN
330 #define SNAKE2_QUIT BUTTON_BACK
331 #define SNAKE2_LEVEL_UP BUTTON_UP
332 #define SNAKE2_LEVEL_DOWN BUTTON_DOWN
333 #define SNAKE2_MAZE_NEXT BUTTON_RIGHT
334 #define SNAKE2_MAZE_LAST BUTTON_LEFT
335 #define SNAKE2_SELECT_TYPE BUTTON_MENU
336 #define SNAKE2_PLAYPAUSE BUTTON_PLAY
337 #define SNAKE2_PLAYPAUSE_TEXT "Play"
339 #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
340 #define SNAKE2_LEFT BUTTON_LEFT
341 #define SNAKE2_RIGHT BUTTON_RIGHT
342 #define SNAKE2_UP BUTTON_UP
343 #define SNAKE2_DOWN BUTTON_DOWN
344 #define SNAKE2_QUIT BUTTON_POWER
345 #define SNAKE2_LEVEL_UP BUTTON_UP
346 #define SNAKE2_LEVEL_DOWN BUTTON_DOWN
347 #define SNAKE2_MAZE_NEXT BUTTON_RIGHT
348 #define SNAKE2_MAZE_LAST BUTTON_LEFT
349 #define SNAKE2_SELECT_TYPE BUTTON_MENU
350 #define SNAKE2_PLAYPAUSE BUTTON_VIEW
351 #define SNAKE2_PLAYPAUSE_TEXT "View"
353 #elif (CONFIG_KEYPAD == ONDAVX747_PAD) || CONFIG_KEYPAD == MROBE500_PAD
354 #define SNAKE2_QUIT BUTTON_POWER
356 #else
357 #error No keymap defined!
358 #endif
360 #ifdef HAVE_TOUCHSCREEN
361 #ifndef SNAKE2_LEFT
362 #define SNAKE2_LEFT BUTTON_MIDLEFT
363 #endif
364 #ifndef SNAKE2_RIGHT
365 #define SNAKE2_RIGHT BUTTON_MIDRIGHT
366 #endif
367 #ifndef SNAKE2_UP
368 #define SNAKE2_UP BUTTON_TOPMIDDLE
369 #endif
370 #ifndef SNAKE2_DOWN
371 #define SNAKE2_DOWN BUTTON_BOTTOMMIDDLE
372 #endif
373 #ifndef SNAKE2_QUIT
374 #define SNAKE2_QUIT BUTTON_TOPLEFT
375 #endif
376 #ifndef SNAKE2_LEVEL_UP
377 #define SNAKE2_LEVEL_UP BUTTON_TOPRIGHT
378 #endif
379 #ifndef SNAKE2_LEVEL_DOWN
380 #define SNAKE2_LEVEL_DOWN BUTTON_TOPLEFT
381 #endif
382 #ifndef SNAKE2_MAZE_NEXT
383 #define SNAKE2_MAZE_NEXT BUTTON_TOPMIDDLE
384 #endif
385 #ifndef SNAKE2_MAZE_LAST
386 #define SNAKE2_MAZE_LAST BUTTON_BOTTOMMIDDLE
387 #endif
388 #ifndef SNAKE2_SELECT_TYPE
389 #define SNAKE2_SELECT_TYPE BUTTON_BOTTOMLEFT
390 #endif
391 #ifndef SNAKE2_PLAYPAUSE
392 #define SNAKE2_PLAYPAUSE BUTTON_CENTER
393 #endif
394 #ifndef SNAKE2_PLAYPAUSE_TEXT
395 #define SNAKE2_PLAYPAUSE_TEXT "CENTER"
396 #endif
397 #endif
399 static int max_levels = 0;
400 static char (*level_cache)[HEIGHT][WIDTH];
402 /*Board itself - 2D int array*/
403 static int board[WIDTH][HEIGHT];
405 Buffer for sorting movement (in case user presses two movements during a
406 single frame
408 static int ardirectionbuffer[2];
409 static unsigned int score, hiscore = 0;
410 static int applex;
411 static int appley;
412 static int strwdt,strhgt; /*used for string width, height for orientation purposes*/
413 static int dir;
414 static int frames;
415 static int apple;
416 static int level = 4, speed = 5,dead = 0, quit = 0;
417 static int sillydir = 0, num_levels = 0;
418 static int level_from_file = 0;
419 static int headx, heady, tailx, taily, applecountdown = 5;
420 static int game_type = 0;
421 static int num_apples_to_get=1;
422 static int num_apples_to_got=0;
423 static int game_b_level=0;
424 static int applecount=0;
425 static char phscore[30];
427 #define NORTH 1
428 #define EAST 2
429 #define SOUTH 4
430 #define WEST 8
431 #define HEAD 16
433 #define EAST_NORTH 32
434 #define EAST_SOUTH 64
435 #define WEST_NORTH 128
436 #define WEST_SOUTH 256
438 #define NORTH_EAST 512
439 #define NORTH_WEST 1024
440 #define SOUTH_EAST 2048
441 #define SOUTH_WEST 4096
443 #define LEVELS_FILE PLUGIN_GAMES_DIR "/snake2.levels"
444 #define HISCORE_FILE PLUGIN_GAMES_DIR "/snake2.hs"
446 int load_all_levels(void)
448 int linecnt = 0;
449 int fd;
450 ssize_t size;
451 char buf[64]; /* Larger than WIDTH, to allow for whitespace after the
452 lines */
454 /* Init the level_cache pointer and
455 calculate how many levels that will fit */
456 level_cache = rb->plugin_get_buffer((size_t *)&size);
457 max_levels = size / (HEIGHT*WIDTH);
459 num_levels = 0;
461 /* open file */
462 if ((fd = rb->open(LEVELS_FILE, O_RDONLY)) < 0)
464 return -1;
467 while(rb->read_line(fd, buf, 64))
469 if(rb->strlen(buf) == 0) /* Separator? */
471 num_levels++;
472 if(num_levels > max_levels)
474 rb->splash(HZ, "Too many levels in file");
475 break;
477 continue;
480 rb->memcpy(level_cache[num_levels][linecnt], buf, WIDTH);
481 linecnt++;
482 if(linecnt == HEIGHT)
484 linecnt = 0;
488 rb->close(fd);
489 return 0;
492 /*Hi-Score reading and writing to file "/.rockbox/rocks/games/snake2.levels" function */
493 void iohiscore(void)
495 int fd;
496 unsigned int compare;
498 /* clear the buffer we're about to load the highscore data into */
499 rb->memset(phscore, 0, sizeof(phscore));
501 fd = rb->open(HISCORE_FILE,O_RDWR | O_CREAT);
503 /* highscore used to %d, is now %d\n
504 Deal with no file or bad file */
505 rb->read(fd,phscore, sizeof(phscore));
507 compare = rb->atoi(phscore);
509 if(hiscore > compare){
510 rb->lseek(fd,0,SEEK_SET);
511 rb->fdprintf(fd, "%d\n", hiscore);
513 else
514 hiscore = compare;
516 rb->close(fd);
521 ** Completely clear the board of walls and/or snake */
523 void clear_board( void)
525 int x,y;
527 for (x = 0; x < WIDTH; x++)
529 for (y = 0; y < HEIGHT; y++)
531 board[x][y] = 0;
536 int load_level( int level_number )
538 int x,y;
539 clear_board();
540 for(y = 0;y < HEIGHT;y++)
542 for(x = 0;x < WIDTH;x++)
544 switch(level_cache[level_number][y][x])
546 case '|':
547 board[x][y] = NORTH;
548 break;
550 case '-':
551 board[x][y] = EAST;
552 break;
554 case '+':
555 board[x][y] = HEAD;
556 break;
560 return 1;
564 ** Gets the currently chosen direction from the first place
565 ** in the direction buffer. If there is something in the
566 ** next part of the buffer then that is moved to the first place
568 void get_direction( void )
570 /*if 1st place is empty*/
571 if(ardirectionbuffer[0] != -1)
573 /*return this direction*/
574 dir = ardirectionbuffer[0];
575 ardirectionbuffer[0]=-1;
576 /*now see if one needs moving:*/
577 if(ardirectionbuffer[1] != -1)
579 /*there's a move waiting to be done
580 so move it into the space:*/
581 ardirectionbuffer[0] = ardirectionbuffer[1];
582 ardirectionbuffer[1] = -1;
588 ** Sets the direction
590 void set_direction(int newdir)
592 if(ardirectionbuffer[0] != newdir)
594 /*if 1st place is empty*/
595 if(ardirectionbuffer[0] == -1)
597 /*use 1st space:*/
598 ardirectionbuffer[0] = newdir;
600 else
602 /*use 2nd space:*/
603 if(ardirectionbuffer[0] != newdir) ardirectionbuffer[1] = newdir;
606 if(frames < 0) ardirectionbuffer[0] = newdir;
610 void new_level(int level)
612 load_level(level);
614 ardirectionbuffer[0] = -1;
615 ardirectionbuffer[1] = -1;
616 dir = EAST;
617 headx = WIDTH/2;
618 heady = HEIGHT/2;
619 tailx = headx - 4;
620 taily = heady;
621 applecountdown = 0;
622 /*Create a small snake to start off with*/
623 board[headx][heady] = dir;
624 board[headx-1][heady] = dir;
625 board[headx-2][heady] = dir;
626 board[headx-3][heady] = dir;
627 board[headx-4][heady] = dir;
628 num_apples_to_got=0;
631 void init_snake(void)
633 num_apples_to_get=1;
634 if(game_type == 1)
635 level_from_file = 1;
636 game_b_level=1;
637 new_level(level_from_file);
641 ** Draws the apple. If it doesn't exist then
642 ** a new one get's created.
644 void draw_apple( void )
646 int x,y;
648 #if LCD_WIDTH >= 160 && LCD_HEIGHT >= 128
649 char pscore[5], counter[4];
651 rb->lcd_bitmap(snake2_header2,0,0,BMPWIDTH_snake2_header, BMPHEIGHT_snake2_header);
652 rb->lcd_bitmap(snake2_left,0,BMPHEIGHT_snake2_header,BMPWIDTH_snake2_left, BMPHEIGHT_snake2_left);
653 rb->lcd_bitmap(snake2_right,LCD_WIDTH-BMPWIDTH_snake2_right,BMPHEIGHT_snake2_header,BMPWIDTH_snake2_right, BMPHEIGHT_snake2_right);
654 rb->lcd_bitmap(snake2_bottom,0,BMPHEIGHT_snake2_header+BMPHEIGHT_snake2_left,BMPWIDTH_snake2_bottom, BMPHEIGHT_snake2_bottom);
656 rb->snprintf(counter,sizeof(counter),"%d",applecount);
657 rb->lcd_getstringsize(counter,&strwdt,&strhgt);
658 rb->lcd_putsxy(TOP_X3-strwdt/2,TOP_Y2,counter);
660 rb->snprintf(pscore,sizeof(pscore),"%d",score);
661 rb->lcd_getstringsize(pscore,&strwdt,&strhgt);
662 rb->lcd_putsxy(TOP_X4-strwdt/2,TOP_Y2,pscore);
663 #endif
665 if (!apple)
669 x = (rb->rand() % (WIDTH-1))+1;
670 y = (rb->rand() % (HEIGHT-1))+1;
671 } while (board[x][y]);
672 apple=1;
673 board[x][y]=-1;
674 applex = x;appley = y;
676 rb->lcd_fillrect((CENTER_X+applex*MULTIPLIER)+1,CENTER_Y+appley*MULTIPLIER,MODIFIER_2,MODIFIER_1);
677 rb->lcd_fillrect(CENTER_X+applex*MULTIPLIER,(CENTER_Y+appley*MULTIPLIER)+1,MODIFIER_1,MODIFIER_2);
681 * x x *
682 * x x *
683 * x x *
684 * x x *
686 void draw_vertical_bit(int x, int y)
688 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER+1,CENTER_Y+y*MULTIPLIER,MODIFIER_2,MODIFIER_1);
692 * * * *
693 X X X X
694 X X X X
695 * * * *
697 void draw_horizontal_bit(int x, int y)
699 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER,CENTER_Y+y*MULTIPLIER+1,MODIFIER_1,MODIFIER_2);
703 * * * *
704 * * X X
705 * X X X
706 * X X *
708 void draw_n_to_e_bit(int x, int y)
710 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER+1,CENTER_Y+y*MULTIPLIER+2,MODIFIER_2,MODIFIER_2);
711 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER+2,CENTER_Y+y*MULTIPLIER+1,MODIFIER_2,MODIFIER_2);
715 * * * *
716 * * X X
717 * X X X
718 * X X *
720 void draw_w_to_s_bit(int x, int y)
722 draw_n_to_e_bit(x,y);
726 * * * *
727 X X * *
728 X X X *
729 * X X *
731 void draw_n_to_w_bit(int x, int y)
733 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER,CENTER_Y+y*MULTIPLIER+1,MODIFIER_2,MODIFIER_2);
734 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER+1,CENTER_Y+y*MULTIPLIER+2,MODIFIER_2,MODIFIER_2);
738 * * * *
739 X X * *
740 X X X *
741 * X X *
743 void draw_e_to_s_bit(int x, int y)
745 draw_n_to_w_bit(x, y);
749 * X X *
750 * X X X
751 * * X X
752 * * * *
754 void draw_s_to_e_bit(int x, int y)
756 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER+1,CENTER_Y+y*MULTIPLIER,MODIFIER_2,MODIFIER_2);
757 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER+2,CENTER_Y+y*MULTIPLIER+1,MODIFIER_2,MODIFIER_2);
761 * X X *
762 * X X X
763 * * X X
764 * * * *
766 void draw_w_to_n_bit(int x, int y)
768 draw_s_to_e_bit(x,y);
772 * X X *
773 X X X *
774 X X * *
775 * * * *
777 void draw_e_to_n_bit(int x, int y)
779 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER+1,CENTER_Y+y*MULTIPLIER,MODIFIER_2,MODIFIER_2);
780 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER,CENTER_Y+y*MULTIPLIER+1,MODIFIER_2,MODIFIER_2);
784 * X X *
785 X X X *
786 X X * *
787 * * * *
789 void draw_s_to_w_bit(int x, int y)
791 draw_e_to_n_bit(x, y);
795 ** Draws a wall/obsticals
797 void draw_boundary ( void )
799 int x, y;
801 /*TODO: Load levels from file!*/
803 /*top and bottom line*/
804 for(x=0; x < WIDTH; x++)
806 board[x][0] = EAST;
807 board[x][HEIGHT-1] = WEST;
810 /*left and right lines*/
811 for(y=0; y < HEIGHT; y++)
813 board[0][y] = NORTH;
814 board[WIDTH-1][y] = SOUTH;
817 /*corners:*/
818 board[0][0] = NORTH_EAST;
819 board[WIDTH-1][0] = EAST_SOUTH;
820 board[0][HEIGHT-1] = SOUTH_EAST;
821 board[WIDTH-1][HEIGHT-1] = EAST_NORTH;
825 ** Redraw the entire board
827 void redraw (void)
829 int x,y;
831 for (x = 0; x < WIDTH; x++)
833 for (y = 0; y < HEIGHT; y++)
835 switch (board[x][y])
837 case -1:
838 rb->lcd_fillrect((CENTER_X+x*MULTIPLIER)+1,CENTER_Y+y*MULTIPLIER,MODIFIER_2,MODIFIER_1);
839 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER,(CENTER_Y+y*MULTIPLIER)+1,MODIFIER_1,MODIFIER_2);
840 break;
841 case 0:
842 break;
844 case NORTH:
845 case SOUTH:
846 draw_vertical_bit(x,y);
847 break;
849 case EAST:
850 case WEST:
851 draw_horizontal_bit(x,y);
852 break;
854 default:
855 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER,CENTER_Y+y*MULTIPLIER,MODIFIER_1,MODIFIER_1);
856 break;
863 ** Draws the snake bit described by nCurrentBit at position x/y
864 ** deciding whether it's a corner bit by examing the nPrevious bit
866 void draw_snake_bit(int currentbit, int previousbit, int x, int y)
868 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
869 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER,CENTER_Y+y*MULTIPLIER,MODIFIER_1,MODIFIER_1);
870 rb->lcd_set_drawmode(DRMODE_SOLID);
872 switch(currentbit)
874 case(NORTH):
875 switch(previousbit)
877 case(SOUTH):
878 case(NORTH):
879 draw_vertical_bit(x,y);
880 break;
882 case(EAST):
883 draw_e_to_n_bit(x,y);
884 break;
886 case(WEST):
887 draw_w_to_n_bit(x,y);
888 break;
890 break;
892 case(EAST):
893 switch(previousbit)
895 case(WEST):
896 case(EAST):
897 draw_horizontal_bit(x,y);
898 break;
900 case(NORTH):
901 draw_n_to_e_bit(x,y);
902 break;
904 case(SOUTH):
905 draw_s_to_e_bit(x,y);
906 break;
908 break;
910 case(SOUTH):
911 switch(previousbit)
913 case(SOUTH):
914 case(NORTH):
915 draw_vertical_bit(x,y);
916 break;
918 case(EAST):
919 draw_e_to_s_bit(x,y);
920 break;
922 case(WEST):
923 draw_w_to_s_bit(x,y);
924 break;
926 break;
928 case(WEST):
929 switch(previousbit)
931 case(EAST):
932 case(WEST):
933 draw_horizontal_bit(x,y);
934 break;
936 case(SOUTH):
937 draw_s_to_w_bit(x,y);
938 break;
940 case(NORTH):
941 draw_n_to_w_bit(x,y);
942 break;
944 break;
949 ** Death 'sequence' and end game stuff.
951 void die (void)
953 int button;
954 bool done=false;
955 char pscore[20];
957 rb->splash(HZ*2, "Oops!");
959 rb->lcd_clear_display();
961 applecount=0;
963 rb->lcd_getstringsize("You died!",&strwdt,&strhgt);
964 rb->lcd_putsxy((LCD_WIDTH - strwdt)/2,strhgt,"You died!");
966 rb->snprintf(pscore,sizeof(pscore),"Your score: %d",score);
967 rb->lcd_getstringsize(pscore,&strwdt,&strhgt);
968 rb->lcd_putsxy((LCD_WIDTH - strwdt)/2,strhgt * 2 + 2,pscore);
970 if (score>hiscore)
972 hiscore=score;
973 rb->lcd_getstringsize("New high score!",&strwdt,&strhgt);
974 rb->lcd_putsxy((LCD_WIDTH - strwdt)/2,strhgt * 4 + 2,"New high score!");
976 else
978 rb->snprintf(phscore,sizeof(phscore),"High score: %d",hiscore);
979 rb->lcd_getstringsize(phscore,&strwdt,&strhgt);
980 rb->lcd_putsxy((LCD_WIDTH - strwdt)/2,strhgt * 5,phscore);
983 rb->snprintf(phscore,sizeof(phscore),"Press %s...",SNAKE2_PLAYPAUSE_TEXT);
984 rb->lcd_getstringsize(phscore,&strwdt,&strhgt);
985 rb->lcd_putsxy((LCD_WIDTH - strwdt)/2,strhgt * 7,phscore);
987 rb->lcd_update();
989 while(!done)
991 button=rb->button_get(true);
992 switch(button)
994 case SNAKE2_PLAYPAUSE:
995 done = true;
996 break;
1000 dead=1;
1004 ** Check for collision. TODO: Currently this
1005 ** sets of the death sequence. What we want is it to only return a true/false
1006 ** depending on whether a collision occured.
1008 void collision ( int x, int y )
1010 int bdeath=0;
1013 switch (board[x][y])
1015 case 0:
1017 break;
1018 case -1:
1019 score = score + (1 * level);
1020 apple=0;
1021 applecountdown=2;
1022 applecount++;
1024 if(game_type==1)
1026 if(num_apples_to_get == num_apples_to_got)
1028 level_from_file++;
1029 if(level_from_file >= num_levels)
1031 level_from_file = 1;
1032 /*and increase the number of apples to pick up
1033 before level changes*/
1034 num_apples_to_get+=2;
1035 game_b_level++;
1037 rb->splash(HZ, "Level Completed!");
1038 rb->lcd_clear_display();
1039 new_level(level_from_file);
1040 rb->lcd_clear_display();
1041 redraw();
1042 rb->lcd_update();
1044 else
1045 num_apples_to_got++;
1047 break;
1048 default:
1049 bdeath=1;
1050 break;
1053 if(bdeath==1)
1055 die();
1056 sillydir = dir;
1057 frames = -110;
1061 void move( void )
1063 int taildir;
1064 /*this actually sets the dir variable.*/
1065 get_direction();
1066 /*draw head*/
1067 switch (dir)
1069 case (NORTH):
1070 board[headx][heady]=NORTH;
1071 heady--;
1072 break;
1073 case (EAST):
1074 board[headx][heady]=EAST;
1075 headx++;
1076 break;
1077 case (SOUTH):
1078 board[headx][heady]=SOUTH;
1079 heady++;
1080 break;
1081 case (WEST):
1082 board[headx][heady]=WEST;
1083 headx--;
1084 break;
1087 if(headx == WIDTH)
1088 headx = 0;
1089 else if(headx < 0)
1090 headx = WIDTH-1;
1092 if(heady == HEIGHT)
1093 heady = 0;
1094 else if(heady < 0)
1095 heady = HEIGHT-1;
1097 rb->lcd_fillrect(CENTER_X+headx*MULTIPLIER,CENTER_Y+heady*MULTIPLIER,MODIFIER_1,MODIFIER_1);
1099 /*clear tail*/
1100 if(applecountdown <= 0)
1102 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
1103 rb->lcd_fillrect(CENTER_X+tailx*MULTIPLIER,CENTER_Y+taily*MULTIPLIER,MODIFIER_1,MODIFIER_1);
1104 rb->lcd_set_drawmode(DRMODE_SOLID);
1106 taildir = board[tailx][taily];
1107 board[tailx][taily] = 0;
1109 switch (taildir)
1111 case(NORTH):
1112 taily--;
1113 break;
1115 case(EAST):
1116 tailx++;
1117 break;
1119 case(SOUTH):
1120 taily++;
1121 break;
1123 case(WEST):
1124 tailx--;
1125 break;
1128 if(tailx == WIDTH)
1129 tailx = 0;
1130 else if(tailx < 0)
1131 tailx = WIDTH-1;
1133 if(taily == HEIGHT)
1134 taily = 0;
1135 else if(taily < 0)
1136 taily = HEIGHT-1;
1138 else
1139 applecountdown--;
1142 void frame (void)
1144 int olddir, noldx, noldy, temp;
1145 noldx = headx;
1146 noldy = heady;
1147 olddir = 0;
1148 switch(dir)
1150 case(NORTH):
1151 if(heady == HEIGHT-1)
1152 temp = 0;
1153 else
1154 temp = heady + 1;
1156 olddir = board[headx][temp];
1157 break;
1159 case(EAST):
1160 if(headx == 0)
1161 temp = WIDTH-1;
1162 else
1163 temp = headx - 1;
1165 olddir = board[temp][heady];
1166 break;
1168 case(SOUTH):
1169 if(heady == 0)
1170 temp = HEIGHT-1;
1171 else
1172 temp = heady - 1;
1174 olddir = board[headx][temp];
1175 break;
1177 case(WEST):
1178 if(headx == WIDTH-1)
1179 temp = 0;
1180 else
1181 temp = headx + 1;
1183 olddir = board[temp][heady];
1184 break;
1187 move();
1190 now redraw the bit that was
1191 the tail, to something snake-like:
1193 draw_snake_bit(dir, olddir, noldx, noldy);
1195 collision(headx, heady);
1197 rb->lcd_update();
1200 void game_pause (void)
1202 int button;
1204 rb->lcd_clear_display();
1205 rb->lcd_getstringsize("Paused",&strwdt,&strhgt);
1206 rb->lcd_putsxy((LCD_WIDTH - strwdt)/2,LCD_HEIGHT/2,"Paused");
1208 rb->lcd_update();
1209 while (1)
1211 button = rb->button_get(true);
1212 switch (button)
1214 case SNAKE2_PLAYPAUSE:
1215 rb->lcd_clear_display();
1216 redraw();
1217 rb->lcd_update();
1218 rb->sleep(HZ/2);
1219 return;
1221 #ifdef SNAKE2_RC_QUIT
1222 case SNAKE2_RC_QUIT:
1223 #endif
1224 case SNAKE2_QUIT:
1225 dead = 1;
1226 quit = 1;
1227 return;
1229 default:
1230 if (rb->default_event_handler(button)==SYS_USB_CONNECTED) {
1231 dead = 1;
1232 quit = 2;
1233 return;
1235 break;
1240 void game (void)
1242 int button;
1244 rb->lcd_clear_display();
1245 redraw();
1246 rb->lcd_update();
1247 /*main loop:*/
1248 while (1)
1250 if(frames==5)
1252 frame();
1253 if(frames>0) frames=0;
1255 frames++;
1257 if(frames == 0)
1259 die();
1261 else
1263 if(frames < 0)
1265 if(sillydir != dir)
1267 /*it has, great set frames to a positive value again:*/
1268 frames = 1;
1273 if (dead) return;
1275 draw_apple();
1277 rb->sleep(HZ/speed);
1279 button = rb->button_get(false);
1281 #ifdef HAS_BUTTON_HOLD
1282 if (rb->button_hold())
1283 button = SNAKE2_PLAYPAUSE;
1284 #endif
1286 switch (button)
1288 case SNAKE2_UP:
1289 case SNAKE2_UP | BUTTON_REPEAT:
1290 if (dir != SOUTH) set_direction(NORTH);
1291 break;
1293 case SNAKE2_RIGHT:
1294 case SNAKE2_RIGHT | BUTTON_REPEAT:
1295 if (dir != WEST) set_direction(EAST);
1296 break;
1298 case SNAKE2_DOWN:
1299 case SNAKE2_DOWN | BUTTON_REPEAT:
1300 if (dir != NORTH) set_direction(SOUTH);
1301 break;
1303 case SNAKE2_LEFT:
1304 case SNAKE2_LEFT | BUTTON_REPEAT:
1305 if (dir != EAST) set_direction(WEST);
1306 break;
1308 #ifdef SNAKE2_RC_QUIT
1309 case SNAKE2_RC_QUIT:
1310 #endif
1311 case SNAKE2_QUIT:
1312 dead=1;
1313 return;
1315 case SNAKE2_PLAYPAUSE:
1316 game_pause();
1317 break;
1319 default:
1320 if (rb->default_event_handler(button)==SYS_USB_CONNECTED) {
1321 quit = 2;
1322 return;
1324 break;
1330 void game_init(void)
1332 int button;
1333 char plevel[30];
1335 dead=0;
1336 apple=0;
1337 score=0;
1338 applecount=0;
1340 clear_board();
1341 load_level( level_from_file );
1342 rb->lcd_clear_display();
1343 redraw();
1344 rb->lcd_update();
1346 while (1)
1348 #if LCD_WIDTH >= 160 && LCD_HEIGHT >= 128
1350 rb->lcd_bitmap(snake2_header1,0,0,BMPWIDTH_snake2_header, BMPHEIGHT_snake2_header);
1351 rb->lcd_bitmap(snake2_left,0,BMPHEIGHT_snake2_header,BMPWIDTH_snake2_left, BMPHEIGHT_snake2_left);
1352 rb->lcd_bitmap(snake2_right,LCD_WIDTH-BMPWIDTH_snake2_right,BMPHEIGHT_snake2_header,BMPWIDTH_snake2_right, BMPHEIGHT_snake2_right);
1353 rb->lcd_bitmap(snake2_bottom,0,BMPHEIGHT_snake2_header+BMPHEIGHT_snake2_left,BMPWIDTH_snake2_bottom, BMPHEIGHT_snake2_bottom);
1355 rb->snprintf(plevel,sizeof(plevel),"%d",level);
1356 rb->lcd_getstringsize(plevel,&strwdt,&strhgt);
1357 rb->lcd_putsxy(TOP_X3-strwdt/2,TOP_Y2, plevel);
1359 rb->snprintf(plevel,sizeof(plevel),"%d",level_from_file);
1360 rb->lcd_getstringsize(plevel,&strwdt,&strhgt);
1361 rb->lcd_putsxy(TOP_X2-strwdt/2,TOP_Y1, plevel);
1363 if(game_type==0){
1364 rb->lcd_getstringsize("A",&strwdt,&strhgt);
1365 rb->lcd_putsxy(TOP_X1,TOP_Y1,"A");
1367 else{
1368 rb->lcd_getstringsize("B",&strwdt,&strhgt);
1369 rb->lcd_putsxy(TOP_X1,TOP_Y1,"B");
1372 rb->snprintf(phscore,sizeof(phscore),"%d",hiscore);
1373 rb->lcd_getstringsize(phscore,&strwdt,&strhgt);
1374 rb->lcd_putsxy(TOP_X4-strwdt/2,TOP_Y2, phscore);
1376 #else
1377 rb->snprintf(plevel,sizeof(plevel),"Speed: %02d",level);
1378 rb->lcd_getstringsize("Speed: 00",&strwdt,&strhgt);
1379 rb->lcd_putsxy((LCD_WIDTH - strwdt)/2,strhgt+4, plevel);
1381 rb->snprintf(plevel,sizeof(plevel),"Maze: %d",level_from_file);
1382 rb->lcd_getstringsize(plevel,&strwdt,&strhgt);
1383 rb->lcd_putsxy((LCD_WIDTH - strwdt)/2,strhgt*2+4, plevel);
1385 if(game_type==0){
1386 rb->lcd_getstringsize("Game Type: A ",&strwdt,&strhgt);
1387 rb->lcd_putsxy((LCD_WIDTH - strwdt)/2,strhgt*3+4,"Game Type: A");
1389 else{
1390 rb->lcd_getstringsize("Game Type: B ",&strwdt,&strhgt);
1391 rb->lcd_putsxy((LCD_WIDTH - strwdt)/2,strhgt*3+4,"Game Type: B");
1394 rb->snprintf(phscore,sizeof(phscore),"Hi Score: %d",hiscore);
1395 rb->lcd_getstringsize(phscore,&strwdt,&strhgt);
1396 rb->lcd_putsxy((LCD_WIDTH - strwdt)/2,strhgt*4+4, phscore);
1397 #endif
1399 rb->lcd_update();
1401 button=rb->button_get(true);
1402 switch (button)
1404 case SNAKE2_LEVEL_UP:
1405 case SNAKE2_LEVEL_UP|BUTTON_REPEAT:
1406 if (level<10)
1407 level+=1;
1408 break;
1409 case SNAKE2_LEVEL_DOWN:
1410 case SNAKE2_LEVEL_DOWN|BUTTON_REPEAT:
1411 if (level>1)
1412 level-=1;
1413 break;
1414 case SNAKE2_QUIT:
1415 quit=1;
1416 return;
1417 break;
1418 case SNAKE2_PLAYPAUSE:
1419 speed = level*20;
1420 return;
1421 break;
1422 case SNAKE2_SELECT_TYPE:
1423 if(game_type==0)game_type=1; else game_type=0;
1424 break;
1425 case SNAKE2_MAZE_NEXT:
1426 rb->lcd_set_drawmode(DRMODE_BG|DRMODE_INVERSEVID);
1427 rb->lcd_fillrect(CENTER_X, CENTER_Y, CENTER_X+WIDTH*MULTIPLIER,
1428 CENTER_Y+HEIGHT*MULTIPLIER);
1429 rb->lcd_set_drawmode(DRMODE_SOLID);
1430 if(level_from_file < num_levels)
1431 level_from_file++;
1432 else
1433 level_from_file = 0;
1434 load_level( level_from_file );
1435 redraw();
1436 break;
1437 #ifdef SNAKE2_MAZE_LAST
1438 case SNAKE2_MAZE_LAST:
1439 rb->lcd_set_drawmode(DRMODE_BG|DRMODE_INVERSEVID);
1440 rb->lcd_fillrect(CENTER_X, CENTER_Y, CENTER_X+WIDTH*MULTIPLIER,
1441 CENTER_Y+HEIGHT*MULTIPLIER);
1442 rb->lcd_set_drawmode(DRMODE_SOLID);
1443 if(level_from_file > 0)
1444 level_from_file--;
1445 else
1446 level_from_file = num_levels;
1447 load_level( level_from_file );
1448 redraw();
1449 break;
1450 #endif
1451 default:
1452 if (rb->default_event_handler(button)==SYS_USB_CONNECTED) {
1453 quit = 2;
1454 return;
1456 break;
1462 enum plugin_status plugin_start(const void* parameter)
1464 (void)(parameter);
1466 /* Lets use the default font */
1467 rb->lcd_setfont(FONT_SYSFIXED);
1468 #if LCD_DEPTH > 1
1469 rb->lcd_set_backdrop(NULL);
1470 #endif
1471 #ifdef HAVE_LCD_COLOR
1472 rb->lcd_set_foreground(LCD_BLACK);
1473 rb->lcd_set_background(LCD_WHITE);
1474 #endif
1476 load_all_levels();
1478 if (num_levels == 0) {
1479 rb->splash(HZ*2, "Failed loading levels!");
1480 return PLUGIN_OK;
1483 iohiscore();
1485 while(quit==0)
1487 game_init();
1488 rb->lcd_clear_display();
1489 frames=1;
1491 if(quit==0)
1493 init_snake();
1495 /*Start Game:*/
1496 game();
1500 iohiscore();
1501 return (quit==1) ? PLUGIN_OK : PLUGIN_USB_CONNECTED;
1504 #endif