Bump version numbers for 3.13
[maemo-rb.git] / apps / plugins / snake2.c
blob6de1c196513dcc0ed28c9f0c3fe41d14ef0514d8
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"
34 #include "lib/highscore.h"
35 #include "lib/playback_control.h"
39 #define WIDTH 28
40 #define HEIGHT 16
42 #if (LCD_WIDTH >= 160) && (LCD_HEIGHT >= 128)
43 #include "pluginbitmaps/snake2_header1.h"
44 #include "pluginbitmaps/snake2_header2.h"
45 #include "pluginbitmaps/snake2_left.h"
46 #include "pluginbitmaps/snake2_right.h"
47 #include "pluginbitmaps/snake2_bottom.h"
48 #define BMPHEIGHT_snake2_header BMPHEIGHT_snake2_header1
49 #define BMPWIDTH_snake2_header BMPWIDTH_snake2_header1
50 #endif
52 #if (LCD_WIDTH >= 640) && (LCD_HEIGHT >= 480)
53 #define MULTIPLIER 20 /*Modifier for porting on other screens*/
54 #define MODIFIER_1 20
55 #define MODIFIER_2 16
56 #define CENTER_X 40
57 #define CENTER_Y 110
58 #define TOP_X1 68 /* x-coord of the upperleft item (game type) */
59 #define TOP_X2 562 /* x-coord of the upperright item (maze type) */
60 #define TOP_X3 84 /* x-coord of the lowerleft item (speed) */
61 #define TOP_X4 548 /* x-coord of the lowerright item (hi-score) */
62 #define TOP_Y1 8 /* y-coord of the top row of items */
63 #define TOP_Y2 50 /* y-coord of the bottom row of items */
64 #elif (LCD_WIDTH >= 320) && (LCD_HEIGHT >= 240)
65 #define MULTIPLIER 10 /*Modifier for porting on other screens*/
66 #define MODIFIER_1 10
67 #define MODIFIER_2 8
68 #define CENTER_X 20
69 #define CENTER_Y 55
70 #define TOP_X1 34 /* x-coord of the upperleft item (game type) */
71 #define TOP_X2 281 /* x-coord of the upperright item (maze type) */
72 #define TOP_X3 42 /* x-coord of the lowerleft item (speed) */
73 #define TOP_X4 274 /* x-coord of the lowerright item (hi-score) */
74 #define TOP_Y1 4 /* y-coord of the top row of items */
75 #define TOP_Y2 25 /* y-coord of the bottom row of items */
76 #elif (LCD_WIDTH >= 240) && (LCD_HEIGHT >= 168)
77 #define MULTIPLIER 8
78 #define MODIFIER_1 8
79 #define MODIFIER_2 6
80 #define CENTER_X 8
81 #define CENTER_Y 34
82 #define TOP_X1 34
83 #define TOP_X2 201
84 #define TOP_X3 42
85 #define TOP_X4 194
86 #define TOP_Y1 4
87 #define TOP_Y2 25
88 #elif (LCD_WIDTH >= 220) && (LCD_HEIGHT >= 176)
89 #define MULTIPLIER 7
90 #define MODIFIER_1 7
91 #define MODIFIER_2 5
92 #define CENTER_X 12
93 #define CENTER_Y 46
94 #define TOP_X1 34
95 #define TOP_X2 181
96 #define TOP_X3 42
97 #define TOP_X4 174
98 #define TOP_Y1 4
99 #define TOP_Y2 25
100 #elif (LCD_WIDTH >= 176) && (LCD_HEIGHT >= 132)
101 #define MULTIPLIER 5
102 #define MODIFIER_1 5
103 #define MODIFIER_2 3
104 #define CENTER_X 18
105 #define CENTER_Y 40
106 #define TOP_X1 34
107 #define TOP_X2 137
108 #define TOP_X3 42
109 #define TOP_X4 130
110 #define TOP_Y1 4
111 #define TOP_Y2 25
112 #elif (LCD_WIDTH >= 160) && (LCD_HEIGHT >= 128)
113 #define MULTIPLIER 5
114 #define MODIFIER_1 5
115 #define MODIFIER_2 3
116 #define CENTER_X 10
117 #define CENTER_Y 38
118 #define TOP_X1 34
119 #define TOP_X2 121
120 #define TOP_X3 42
121 #define TOP_X4 114
122 #define TOP_Y1 4
123 #define TOP_Y2 25
124 #elif (LCD_WIDTH == 96) && (LCD_HEIGHT == 96)
125 #define MULTIPLIER 3
126 #define MODIFIER_1 4
127 #define MODIFIER_2 2
128 #define CENTER_X 6
129 #define CENTER_Y 12
130 #else
131 #define MULTIPLIER 4
132 #define MODIFIER_1 4
133 #define MODIFIER_2 2
134 #define CENTER_X 0
135 #define CENTER_Y 0
137 #endif
139 /* variable button definitions */
140 #if CONFIG_KEYPAD == RECORDER_PAD
141 #define SNAKE2_LEFT BUTTON_LEFT
142 #define SNAKE2_RIGHT BUTTON_RIGHT
143 #define SNAKE2_UP BUTTON_UP
144 #define SNAKE2_DOWN BUTTON_DOWN
145 #define SNAKE2_QUIT BUTTON_OFF
146 #define SNAKE2_PLAYPAUSE BUTTON_PLAY
147 #define SNAKE2_PLAYPAUSE_TEXT "Play"
149 #elif CONFIG_KEYPAD == ARCHOS_AV300_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_PLAYPAUSE BUTTON_SELECT
156 #define SNAKE2_PLAYPAUSE_TEXT "Select"
158 #elif CONFIG_KEYPAD == ONDIO_PAD
159 #define SNAKE2_LEFT BUTTON_LEFT
160 #define SNAKE2_RIGHT BUTTON_RIGHT
161 #define SNAKE2_UP BUTTON_UP
162 #define SNAKE2_DOWN BUTTON_DOWN
163 #define SNAKE2_QUIT BUTTON_OFF
164 #define SNAKE2_PLAYPAUSE BUTTON_MENU
165 #define SNAKE2_PLAYPAUSE_TEXT "Menu"
167 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
168 (CONFIG_KEYPAD == IRIVER_H300_PAD)
169 #define SNAKE2_LEFT BUTTON_LEFT
170 #define SNAKE2_RIGHT BUTTON_RIGHT
171 #define SNAKE2_UP BUTTON_UP
172 #define SNAKE2_DOWN BUTTON_DOWN
173 #define SNAKE2_QUIT BUTTON_OFF
174 #define SNAKE2_PLAYPAUSE BUTTON_ON
175 #define SNAKE2_PLAYPAUSE_TEXT "Play"
177 #define SNAKE2_RC_QUIT BUTTON_RC_STOP
179 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
180 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
181 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
182 #define SNAKE2_LEFT BUTTON_LEFT
183 #define SNAKE2_RIGHT BUTTON_RIGHT
184 #define SNAKE2_UP BUTTON_MENU
185 #define SNAKE2_DOWN BUTTON_PLAY
186 #define SNAKE2_QUIT (BUTTON_SELECT | BUTTON_MENU)
187 #define SNAKE2_PLAYPAUSE BUTTON_SELECT
188 #define SNAKE2_PLAYPAUSE_TEXT "Select"
190 #elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
191 #define SNAKE2_LEFT BUTTON_LEFT
192 #define SNAKE2_RIGHT BUTTON_RIGHT
193 #define SNAKE2_UP BUTTON_UP
194 #define SNAKE2_DOWN BUTTON_DOWN
195 #define SNAKE2_QUIT BUTTON_POWER
196 #define SNAKE2_PLAYPAUSE BUTTON_SELECT
197 #define SNAKE2_PLAYPAUSE_TEXT "Select"
199 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
200 #define SNAKE2_LEFT BUTTON_LEFT
201 #define SNAKE2_RIGHT BUTTON_RIGHT
202 #define SNAKE2_UP BUTTON_UP
203 #define SNAKE2_DOWN BUTTON_DOWN
204 #define SNAKE2_QUIT BUTTON_POWER
205 #define SNAKE2_PLAYPAUSE BUTTON_SELECT
206 #define SNAKE2_PLAYPAUSE_TEXT "Select"
208 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
209 (CONFIG_KEYPAD == SANSA_C200_PAD) || \
210 (CONFIG_KEYPAD == SANSA_CONNECT_PAD) || \
211 (CONFIG_KEYPAD == SANSA_CLIP_PAD) || \
212 (CONFIG_KEYPAD == SANSA_M200_PAD)
213 #define SNAKE2_LEFT BUTTON_LEFT
214 #define SNAKE2_RIGHT BUTTON_RIGHT
215 #define SNAKE2_UP BUTTON_UP
216 #define SNAKE2_DOWN BUTTON_DOWN
217 #define SNAKE2_QUIT BUTTON_POWER
218 #define SNAKE2_PLAYPAUSE BUTTON_SELECT
219 #define SNAKE2_PLAYPAUSE_TEXT "Select"
221 #elif (CONFIG_KEYPAD == SANSA_FUZE_PAD)
222 #define SNAKE2_LEFT BUTTON_LEFT
223 #define SNAKE2_RIGHT BUTTON_RIGHT
224 #define SNAKE2_UP BUTTON_UP
225 #define SNAKE2_DOWN BUTTON_DOWN
226 #define SNAKE2_QUIT (BUTTON_HOME|BUTTON_REPEAT)
227 #define SNAKE2_PLAYPAUSE BUTTON_SELECT
228 #define SNAKE2_PLAYPAUSE_TEXT "Select"
230 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
231 #define SNAKE2_LEFT BUTTON_LEFT
232 #define SNAKE2_RIGHT BUTTON_RIGHT
233 #define SNAKE2_UP BUTTON_SCROLL_UP
234 #define SNAKE2_DOWN BUTTON_SCROLL_DOWN
235 #define SNAKE2_QUIT BUTTON_POWER
236 #define SNAKE2_PLAYPAUSE BUTTON_FF
237 #define SNAKE2_PLAYPAUSE_TEXT "FF"
239 #elif (CONFIG_KEYPAD == GIGABEAT_S_PAD) || \
240 (CONFIG_KEYPAD == SAMSUNG_YPR0_PAD)
241 #define SNAKE2_LEFT BUTTON_LEFT
242 #define SNAKE2_RIGHT BUTTON_RIGHT
243 #define SNAKE2_UP BUTTON_UP
244 #define SNAKE2_DOWN BUTTON_DOWN
245 #define SNAKE2_QUIT BUTTON_BACK
246 #define SNAKE2_PLAYPAUSE BUTTON_SELECT
247 #define SNAKE2_PLAYPAUSE_TEXT "Select"
249 #elif (CONFIG_KEYPAD == MROBE100_PAD)
250 #define SNAKE2_LEFT BUTTON_LEFT
251 #define SNAKE2_RIGHT BUTTON_RIGHT
252 #define SNAKE2_UP BUTTON_UP
253 #define SNAKE2_DOWN BUTTON_DOWN
254 #define SNAKE2_QUIT BUTTON_POWER
255 #define SNAKE2_PLAYPAUSE BUTTON_SELECT
256 #define SNAKE2_PLAYPAUSE_TEXT "Select"
258 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
259 #define SNAKE2_LEFT BUTTON_RC_REW
260 #define SNAKE2_RIGHT BUTTON_RC_FF
261 #define SNAKE2_UP BUTTON_RC_VOL_UP
262 #define SNAKE2_DOWN BUTTON_RC_VOL_DOWN
263 #define SNAKE2_QUIT BUTTON_RC_REC
264 #define SNAKE2_PLAYPAUSE BUTTON_RC_PLAY
265 #define SNAKE2_PLAYPAUSE_TEXT "Play"
267 #elif (CONFIG_KEYPAD == COWON_D2_PAD)
268 #define SNAKE2_QUIT BUTTON_POWER
270 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
271 #define SNAKE2_LEFT BUTTON_LEFT
272 #define SNAKE2_RIGHT BUTTON_RIGHT
273 #define SNAKE2_UP BUTTON_UP
274 #define SNAKE2_DOWN BUTTON_DOWN
275 #define SNAKE2_QUIT BUTTON_BACK
276 #define SNAKE2_PLAYPAUSE BUTTON_PLAY
277 #define SNAKE2_PLAYPAUSE_TEXT "Play"
279 #elif (CONFIG_KEYPAD == PHILIPS_HDD1630_PAD) || \
280 (CONFIG_KEYPAD == PHILIPS_HDD6330_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_POWER
286 #define SNAKE2_PLAYPAUSE BUTTON_VIEW
287 #define SNAKE2_PLAYPAUSE_TEXT "View"
289 #elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
290 #define SNAKE2_LEFT BUTTON_PREV
291 #define SNAKE2_RIGHT BUTTON_NEXT
292 #define SNAKE2_UP BUTTON_UP
293 #define SNAKE2_DOWN BUTTON_DOWN
294 #define SNAKE2_QUIT BUTTON_POWER
295 #define SNAKE2_PLAYPAUSE BUTTON_RIGHT
296 #define SNAKE2_PLAYPAUSE_TEXT "Right"
298 #elif (CONFIG_KEYPAD == ONDAVX747_PAD) || \
299 (CONFIG_KEYPAD == ONDAVX777_PAD) || \
300 CONFIG_KEYPAD == MROBE500_PAD
301 #define SNAKE2_QUIT BUTTON_POWER
303 #elif (CONFIG_KEYPAD == SAMSUNG_YH_PAD)
304 #define SNAKE2_LEFT BUTTON_LEFT
305 #define SNAKE2_RIGHT BUTTON_RIGHT
306 #define SNAKE2_UP BUTTON_UP
307 #define SNAKE2_DOWN BUTTON_DOWN
308 #define SNAKE2_QUIT BUTTON_REC
309 #define SNAKE2_PLAYPAUSE BUTTON_PLAY
310 #define SNAKE2_PLAYPAUSE_TEXT "Play"
312 #elif CONFIG_KEYPAD == PBELL_VIBE500_PAD
313 #define SNAKE2_LEFT BUTTON_PREV
314 #define SNAKE2_RIGHT BUTTON_NEXT
315 #define SNAKE2_UP BUTTON_UP
316 #define SNAKE2_DOWN BUTTON_DOWN
317 #define SNAKE2_QUIT BUTTON_REC
318 #define SNAKE2_PLAYPAUSE BUTTON_PLAY
319 #define SNAKE2_PLAYPAUSE_TEXT "Play"
321 #elif CONFIG_KEYPAD == MPIO_HD200_PAD
322 #define SNAKE2_LEFT BUTTON_VOL_DOWN
323 #define SNAKE2_RIGHT BUTTON_VOL_UP
324 #define SNAKE2_UP BUTTON_REW
325 #define SNAKE2_DOWN BUTTON_FF
326 #define SNAKE2_QUIT (BUTTON_REC | BUTTON_PLAY)
327 #define SNAKE2_PLAYPAUSE BUTTON_PLAY
328 #define SNAKE2_PLAYPAUSE_TEXT "Play"
330 #elif CONFIG_KEYPAD == MPIO_HD300_PAD
331 #define SNAKE2_LEFT BUTTON_REW
332 #define SNAKE2_RIGHT BUTTON_FF
333 #define SNAKE2_UP BUTTON_UP
334 #define SNAKE2_DOWN BUTTON_DOWN
335 #define SNAKE2_QUIT (BUTTON_MENU|BUTTON_REPEAT)
336 #define SNAKE2_PLAYPAUSE BUTTON_PLAY
337 #define SNAKE2_PLAYPAUSE_TEXT "Play"
339 #elif CONFIG_KEYPAD == SANSA_FUZEPLUS_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_PLAYPAUSE BUTTON_PLAYPAUSE
346 #define SNAKE2_PLAYPAUSE_TEXT "Play-Pause"
348 #elif (CONFIG_KEYPAD == HM60X_PAD) || \
349 (CONFIG_KEYPAD == HM801_PAD)
350 #define SNAKE2_LEFT BUTTON_LEFT
351 #define SNAKE2_RIGHT BUTTON_RIGHT
352 #define SNAKE2_UP BUTTON_UP
353 #define SNAKE2_DOWN BUTTON_DOWN
354 #define SNAKE2_QUIT BUTTON_POWER
355 #define SNAKE2_PLAYPAUSE BUTTON_SELECT
356 #define SNAKE2_PLAYPAUSE_TEXT "Select"
358 #else
359 #error No keymap defined!
360 #endif
362 #ifdef HAVE_TOUCHSCREEN
363 #ifndef SNAKE2_LEFT
364 #define SNAKE2_LEFT BUTTON_MIDLEFT
365 #endif
366 #ifndef SNAKE2_RIGHT
367 #define SNAKE2_RIGHT BUTTON_MIDRIGHT
368 #endif
369 #ifndef SNAKE2_UP
370 #define SNAKE2_UP BUTTON_TOPMIDDLE
371 #endif
372 #ifndef SNAKE2_DOWN
373 #define SNAKE2_DOWN BUTTON_BOTTOMMIDDLE
374 #endif
375 #ifndef SNAKE2_QUIT
376 #define SNAKE2_QUIT BUTTON_TOPLEFT
377 #endif
378 #ifndef SNAKE2_PLAYPAUSE
379 #define SNAKE2_PLAYPAUSE BUTTON_CENTER
380 #endif
381 #ifndef SNAKE2_PLAYPAUSE_TEXT
382 #define SNAKE2_PLAYPAUSE_TEXT "CENTER"
383 #endif
384 #endif
386 static int max_levels = 0;
387 static char (*level_cache)[HEIGHT][WIDTH];
389 /*Board itself - 2D int array*/
390 static int board[WIDTH][HEIGHT];
392 Buffer for sorting movement (in case user presses two movements during a
393 single frame
395 static int ardirectionbuffer[2];
396 static int score;
397 static int applex;
398 static int appley;
399 static int dir;
400 static int frames;
401 static int apple;
402 static int level = 4, speed = 5,dead = 0, quit = 0;
403 static int sillydir = 0, num_levels = 0;
404 static int level_from_file = 0;
405 static int headx, heady, tailx, taily, applecountdown = 5;
406 static int game_type = 0;
407 static int num_apples_to_get=1;
408 static int num_apples_to_got=0;
409 static int game_b_level=0;
410 static int applecount=0;
411 /* used for string width, height for orientation purposes */
412 static int strwdt, strhgt;
413 static char strbuf[32];
415 #define NUM_SCORES 5
416 static struct highscore highscores[NUM_SCORES];
418 #define NORTH 1
419 #define EAST 2
420 #define SOUTH 4
421 #define WEST 8
422 #define HEAD 16
424 #define EAST_NORTH 32
425 #define EAST_SOUTH 64
426 #define WEST_NORTH 128
427 #define WEST_SOUTH 256
429 #define NORTH_EAST 512
430 #define NORTH_WEST 1024
431 #define SOUTH_EAST 2048
432 #define SOUTH_WEST 4096
434 #define LEVELS_FILE PLUGIN_GAMES_DIR "/snake2.levels"
435 #define SCORE_FILE PLUGIN_GAMES_DATA_DIR "/snake2.score"
437 static int load_all_levels(void)
439 int linecnt = 0;
440 int fd;
441 size_t size;
442 char buf[64]; /* Larger than WIDTH, to allow for whitespace after the
443 lines */
445 /* Init the level_cache pointer and
446 calculate how many levels that will fit */
447 level_cache = rb->plugin_get_buffer(&size);
448 max_levels = size / (HEIGHT*WIDTH);
450 num_levels = 0;
452 /* open file */
453 if ((fd = rb->open(LEVELS_FILE, O_RDONLY)) < 0)
455 return -1;
458 while(rb->read_line(fd, buf, 64) > 0)
460 if(rb->strlen(buf) == 0) /* Separator? */
462 num_levels++;
463 if(num_levels > max_levels)
465 rb->splash(HZ, "Too many levels in file");
466 break;
468 continue;
471 rb->memcpy(level_cache[num_levels][linecnt], buf, WIDTH);
472 linecnt++;
473 if(linecnt == HEIGHT)
475 linecnt = 0;
479 rb->close(fd);
480 return 0;
484 ** Completely clear the board of walls and/or snake
487 static void clear_board( void)
489 int x,y;
491 for (x = 0; x < WIDTH; x++)
493 for (y = 0; y < HEIGHT; y++)
495 board[x][y] = 0;
500 static int load_level( int level_number )
502 int x,y;
503 clear_board();
504 for(y = 0;y < HEIGHT;y++)
506 for(x = 0;x < WIDTH;x++)
508 switch(level_cache[level_number][y][x])
510 case '|':
511 board[x][y] = NORTH;
512 break;
514 case '-':
515 board[x][y] = EAST;
516 break;
518 case '+':
519 board[x][y] = HEAD;
520 break;
524 return 1;
528 ** Gets the currently chosen direction from the first place
529 ** in the direction buffer. If there is something in the
530 ** next part of the buffer then that is moved to the first place
532 static void get_direction( void )
534 /*if 1st place is empty*/
535 if(ardirectionbuffer[0] != -1)
537 /*return this direction*/
538 dir = ardirectionbuffer[0];
539 ardirectionbuffer[0]=-1;
540 /*now see if one needs moving:*/
541 if(ardirectionbuffer[1] != -1)
543 /*there's a move waiting to be done
544 so move it into the space:*/
545 ardirectionbuffer[0] = ardirectionbuffer[1];
546 ardirectionbuffer[1] = -1;
552 ** Sets the direction
554 static void set_direction(int newdir)
556 if(ardirectionbuffer[0] != newdir)
558 /*if 1st place is empty*/
559 if(ardirectionbuffer[0] == -1)
561 /*use 1st space:*/
562 ardirectionbuffer[0] = newdir;
564 else
566 /*use 2nd space:*/
567 if(ardirectionbuffer[0] != newdir) ardirectionbuffer[1] = newdir;
570 if(frames < 0) ardirectionbuffer[0] = newdir;
574 static void new_level(int level)
576 load_level(level);
578 ardirectionbuffer[0] = -1;
579 ardirectionbuffer[1] = -1;
580 dir = EAST;
581 headx = WIDTH/2;
582 heady = HEIGHT/2;
583 tailx = headx - 4;
584 taily = heady;
585 applecountdown = 0;
586 /*Create a small snake to start off with*/
587 board[headx][heady] = dir;
588 board[headx-1][heady] = dir;
589 board[headx-2][heady] = dir;
590 board[headx-3][heady] = dir;
591 board[headx-4][heady] = dir;
592 num_apples_to_got=0;
595 static void init_snake(void)
597 num_apples_to_get=1;
598 if(game_type == 1)
599 level_from_file = 1;
600 game_b_level=1;
601 new_level(level_from_file);
604 #if (LCD_WIDTH >= 160) && (LCD_HEIGHT >= 128)
605 static void draw_frame_bitmap(int header_type)
607 rb->lcd_bitmap(header_type==1? snake2_header1: snake2_header2, 0, 0,
608 BMPWIDTH_snake2_header, BMPHEIGHT_snake2_header);
609 rb->lcd_bitmap(snake2_left, 0, BMPHEIGHT_snake2_header,
610 BMPWIDTH_snake2_left, BMPHEIGHT_snake2_left);
611 rb->lcd_bitmap(snake2_right,
612 LCD_WIDTH - BMPWIDTH_snake2_right, BMPHEIGHT_snake2_header,
613 BMPWIDTH_snake2_right, BMPHEIGHT_snake2_right);
614 rb->lcd_bitmap(snake2_bottom,
615 0, BMPHEIGHT_snake2_header + BMPHEIGHT_snake2_left,
616 BMPWIDTH_snake2_bottom, BMPHEIGHT_snake2_bottom);
618 #endif
621 ** Draws the apple. If it doesn't exist then
622 ** a new one get's created.
624 static void draw_apple_bit(int x, int y)
626 rb->lcd_fillrect((CENTER_X+x*MULTIPLIER)+1, CENTER_Y+y*MULTIPLIER,
627 MODIFIER_2, MODIFIER_1);
628 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER, (CENTER_Y+y*MULTIPLIER)+1,
629 MODIFIER_1, MODIFIER_2);
632 static void draw_apple( void )
634 int x,y;
636 #if LCD_WIDTH >= 160 && LCD_HEIGHT >= 128
637 draw_frame_bitmap(2);
639 rb->snprintf(strbuf, sizeof(strbuf), "%d", applecount);
640 rb->lcd_getstringsize(strbuf, &strwdt, &strhgt);
641 rb->lcd_putsxy(TOP_X3 - strwdt/2, TOP_Y2, strbuf);
643 rb->snprintf(strbuf, sizeof(strbuf), "%d", score);
644 rb->lcd_getstringsize(strbuf, &strwdt, &strhgt);
645 rb->lcd_putsxy(TOP_X4 - strwdt/2, TOP_Y2, strbuf);
646 #endif
648 if (!apple)
652 x = (rb->rand() % (WIDTH-1))+1;
653 y = (rb->rand() % (HEIGHT-1))+1;
654 } while (board[x][y]);
655 apple = 1;
656 board[x][y] = -1;
657 applex = x;appley = y;
659 draw_apple_bit(applex, appley);
663 * x x *
664 * x x *
665 * x x *
666 * x x *
668 static void draw_vertical_bit(int x, int y)
670 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER+1, CENTER_Y+y*MULTIPLIER,
671 MODIFIER_2, MODIFIER_1);
675 * * * *
676 X X X X
677 X X X X
678 * * * *
680 static void draw_horizontal_bit(int x, int y)
682 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER, CENTER_Y+y*MULTIPLIER+1,
683 MODIFIER_1, MODIFIER_2);
687 * * * *
688 * * X X
689 * X X X
690 * X X *
692 static void draw_n_to_e_bit(int x, int y)
694 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER+1, CENTER_Y+y*MULTIPLIER+2,
695 MODIFIER_2, MODIFIER_2);
696 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER+2, CENTER_Y+y*MULTIPLIER+1,
697 MODIFIER_2, MODIFIER_2);
701 * * * *
702 * * X X
703 * X X X
704 * X X *
706 static void draw_w_to_s_bit(int x, int y)
708 draw_n_to_e_bit(x,y);
712 * * * *
713 X X * *
714 X X X *
715 * X X *
717 static void draw_n_to_w_bit(int x, int y)
719 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER, CENTER_Y+y*MULTIPLIER+1,
720 MODIFIER_2, MODIFIER_2);
721 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER+1, CENTER_Y+y*MULTIPLIER+2,
722 MODIFIER_2, MODIFIER_2);
726 * * * *
727 X X * *
728 X X X *
729 * X X *
731 static void draw_e_to_s_bit(int x, int y)
733 draw_n_to_w_bit(x, y);
737 * X X *
738 * X X X
739 * * X X
740 * * * *
742 static void draw_s_to_e_bit(int x, int y)
744 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER+1, CENTER_Y+y*MULTIPLIER,
745 MODIFIER_2, MODIFIER_2);
746 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER+2, CENTER_Y+y*MULTIPLIER+1,
747 MODIFIER_2, MODIFIER_2);
751 * X X *
752 * X X X
753 * * X X
754 * * * *
756 static void draw_w_to_n_bit(int x, int y)
758 draw_s_to_e_bit(x,y);
762 * X X *
763 X X X *
764 X X * *
765 * * * *
767 static void draw_e_to_n_bit(int x, int y)
769 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER+1, CENTER_Y+y*MULTIPLIER,
770 MODIFIER_2, MODIFIER_2);
771 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER, CENTER_Y+y*MULTIPLIER+1,
772 MODIFIER_2, MODIFIER_2);
776 * X X *
777 X X X *
778 X X * *
779 * * * *
781 static void draw_s_to_w_bit(int x, int y)
783 draw_e_to_n_bit(x, y);
786 static void draw_head_bit(int x, int y)
788 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER, CENTER_Y+y*MULTIPLIER,
789 MODIFIER_1, MODIFIER_1);
792 #if 0 /* unused */
794 ** Draws a wall/obsticals
796 static void draw_boundary ( void )
798 int x, y;
800 /*TODO: Load levels from file!*/
802 /*top and bottom line*/
803 for(x=0; x < WIDTH; x++)
805 board[x][0] = EAST;
806 board[x][HEIGHT-1] = WEST;
809 /*left and right lines*/
810 for(y=0; y < HEIGHT; y++)
812 board[0][y] = NORTH;
813 board[WIDTH-1][y] = SOUTH;
816 /*corners:*/
817 board[0][0] = NORTH_EAST;
818 board[WIDTH-1][0] = EAST_SOUTH;
819 board[0][HEIGHT-1] = SOUTH_EAST;
820 board[WIDTH-1][HEIGHT-1] = EAST_NORTH;
822 #endif
825 ** Redraw the entire board
827 static void redraw (void)
829 int x,y;
831 #ifdef HAVE_LCD_COLOR
832 rb->lcd_set_foreground(LCD_BLACK);
833 rb->lcd_set_background(LCD_WHITE);
834 #endif
836 rb->lcd_clear_display();
838 for (x = 0; x < WIDTH; x++)
840 for (y = 0; y < HEIGHT; y++)
842 switch (board[x][y])
844 case -1:
845 draw_apple_bit(x, y);
846 break;
847 case 0:
848 break;
850 case NORTH:
851 case SOUTH:
852 draw_vertical_bit(x,y);
853 break;
855 case EAST:
856 case WEST:
857 draw_horizontal_bit(x,y);
858 break;
860 default:
861 draw_head_bit(x, y);
862 break;
867 #if LCD_WIDTH >= 160 && LCD_HEIGHT >= 128
868 draw_frame_bitmap(2);
870 rb->snprintf(strbuf, sizeof(strbuf), "%d", applecount);
871 rb->lcd_getstringsize(strbuf, &strwdt, &strhgt);
872 rb->lcd_putsxy(TOP_X3 - strwdt/2, TOP_Y2, strbuf);
874 rb->snprintf(strbuf, sizeof(strbuf), "%d", score);
875 rb->lcd_getstringsize(strbuf, &strwdt, &strhgt);
876 rb->lcd_putsxy(TOP_X4 - strwdt/2, TOP_Y2, strbuf);
877 #endif
881 ** Draws the snake bit described by nCurrentBit at position x/y
882 ** deciding whether it's a corner bit by examing the nPrevious bit
884 static void draw_snake_bit(int currentbit, int previousbit, int x, int y)
886 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
887 draw_head_bit(x, y);
888 rb->lcd_set_drawmode(DRMODE_SOLID);
890 switch(currentbit)
892 case(NORTH):
893 switch(previousbit)
895 case(SOUTH):
896 case(NORTH):
897 draw_vertical_bit(x,y);
898 break;
900 case(EAST):
901 draw_e_to_n_bit(x,y);
902 break;
904 case(WEST):
905 draw_w_to_n_bit(x,y);
906 break;
908 break;
910 case(EAST):
911 switch(previousbit)
913 case(WEST):
914 case(EAST):
915 draw_horizontal_bit(x,y);
916 break;
918 case(NORTH):
919 draw_n_to_e_bit(x,y);
920 break;
922 case(SOUTH):
923 draw_s_to_e_bit(x,y);
924 break;
926 break;
928 case(SOUTH):
929 switch(previousbit)
931 case(SOUTH):
932 case(NORTH):
933 draw_vertical_bit(x,y);
934 break;
936 case(EAST):
937 draw_e_to_s_bit(x,y);
938 break;
940 case(WEST):
941 draw_w_to_s_bit(x,y);
942 break;
944 break;
946 case(WEST):
947 switch(previousbit)
949 case(EAST):
950 case(WEST):
951 draw_horizontal_bit(x,y);
952 break;
954 case(SOUTH):
955 draw_s_to_w_bit(x,y);
956 break;
958 case(NORTH):
959 draw_n_to_w_bit(x,y);
960 break;
962 break;
966 static void redraw_snake(void)
968 int x = tailx, y = taily;
969 int olddir, newdir = board[x][y];
971 while (x != headx || y != heady)
973 olddir = newdir;
975 switch (olddir)
977 case(NORTH):
978 y--;
979 break;
981 case(EAST):
982 x++;
983 break;
985 case(SOUTH):
986 y++;
987 break;
989 case(WEST):
990 x--;
991 break;
994 if(x == WIDTH)
995 x = 0;
996 else if(x < 0)
997 x = WIDTH-1;
999 if(y == HEIGHT)
1000 y = 0;
1001 else if(y < 0)
1002 y = HEIGHT-1;
1004 newdir = board[x][y];
1005 if(olddir != newdir)
1006 draw_snake_bit(newdir, olddir, x, y);
1011 ** Death 'sequence' and end game stuff.
1013 static void die (void)
1015 int button;
1016 bool done=false;
1018 rb->splash(HZ*2, "Oops!");
1020 rb->lcd_clear_display();
1022 applecount=0;
1024 rb->lcd_getstringsize("You died!",&strwdt,&strhgt);
1025 rb->lcd_putsxy((LCD_WIDTH - strwdt)/2,strhgt,"You died!");
1027 rb->snprintf(strbuf, sizeof(strbuf), "Your score: %d", score);
1028 rb->lcd_getstringsize(strbuf, &strwdt, &strhgt);
1029 rb->lcd_putsxy((LCD_WIDTH - strwdt)/2, strhgt * 2 + 2, strbuf);
1031 if (highscore_update(score, level_from_file, game_type==0?"Type A":"Type B",
1032 highscores, NUM_SCORES) == 0)
1034 rb->lcd_getstringsize("New high score!",&strwdt,&strhgt);
1035 rb->lcd_putsxy((LCD_WIDTH - strwdt)/2,strhgt * 4 + 2,"New high score!");
1037 else
1039 rb->snprintf(strbuf, sizeof(strbuf), "High score: %d", highscores[0].score);
1040 rb->lcd_getstringsize(strbuf, &strwdt, &strhgt);
1041 rb->lcd_putsxy((LCD_WIDTH - strwdt)/2, strhgt * 5, strbuf);
1044 rb->snprintf(strbuf, sizeof(strbuf), "Press %s...", SNAKE2_PLAYPAUSE_TEXT);
1045 rb->lcd_getstringsize(strbuf, &strwdt, &strhgt);
1046 rb->lcd_putsxy((LCD_WIDTH - strwdt)/2, strhgt * 7, strbuf);
1048 rb->lcd_update();
1050 while(!done)
1052 button=rb->button_get(true);
1053 switch(button)
1055 case SNAKE2_PLAYPAUSE:
1056 done = true;
1057 break;
1061 dead=1;
1065 ** Check for collision. TODO: Currently this
1066 ** sets of the death sequence. What we want is it to only return a true/false
1067 ** depending on whether a collision occured.
1069 static void collision ( int x, int y )
1071 int bdeath=0;
1074 switch (board[x][y])
1076 case 0:
1078 break;
1079 case -1:
1080 score = score + (1 * level);
1081 apple=0;
1082 applecountdown=2;
1083 applecount++;
1085 if(game_type==1)
1087 if(num_apples_to_get == num_apples_to_got)
1089 level_from_file++;
1090 if(level_from_file >= num_levels)
1092 level_from_file = 1;
1093 /*and increase the number of apples to pick up
1094 before level changes*/
1095 num_apples_to_get+=2;
1096 game_b_level++;
1098 rb->splash(HZ, "Level Completed!");
1099 new_level(level_from_file);
1100 redraw();
1101 rb->lcd_update();
1103 else
1104 num_apples_to_got++;
1106 break;
1107 default:
1108 bdeath=1;
1109 break;
1112 if(bdeath==1)
1114 die();
1115 sillydir = dir;
1116 frames = -110;
1120 static void move( void )
1122 int taildir;
1123 /*this actually sets the dir variable.*/
1124 get_direction();
1125 /*draw head*/
1126 switch (dir)
1128 case (NORTH):
1129 board[headx][heady]=NORTH;
1130 heady--;
1131 break;
1132 case (EAST):
1133 board[headx][heady]=EAST;
1134 headx++;
1135 break;
1136 case (SOUTH):
1137 board[headx][heady]=SOUTH;
1138 heady++;
1139 break;
1140 case (WEST):
1141 board[headx][heady]=WEST;
1142 headx--;
1143 break;
1146 if(headx == WIDTH)
1147 headx = 0;
1148 else if(headx < 0)
1149 headx = WIDTH-1;
1151 if(heady == HEIGHT)
1152 heady = 0;
1153 else if(heady < 0)
1154 heady = HEIGHT-1;
1156 draw_head_bit(headx, heady);
1158 /*clear tail*/
1159 if(applecountdown <= 0)
1161 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
1162 draw_head_bit(tailx, taily);
1163 rb->lcd_set_drawmode(DRMODE_SOLID);
1165 taildir = board[tailx][taily];
1166 board[tailx][taily] = 0;
1168 switch (taildir)
1170 case(NORTH):
1171 taily--;
1172 break;
1174 case(EAST):
1175 tailx++;
1176 break;
1178 case(SOUTH):
1179 taily++;
1180 break;
1182 case(WEST):
1183 tailx--;
1184 break;
1187 if(tailx == WIDTH)
1188 tailx = 0;
1189 else if(tailx < 0)
1190 tailx = WIDTH-1;
1192 if(taily == HEIGHT)
1193 taily = 0;
1194 else if(taily < 0)
1195 taily = HEIGHT-1;
1197 else
1198 applecountdown--;
1201 static void frame (void)
1203 int olddir, noldx, noldy, temp;
1204 noldx = headx;
1205 noldy = heady;
1206 olddir = 0;
1207 switch(dir)
1209 case(NORTH):
1210 if(heady == HEIGHT-1)
1211 temp = 0;
1212 else
1213 temp = heady + 1;
1215 olddir = board[headx][temp];
1216 break;
1218 case(EAST):
1219 if(headx == 0)
1220 temp = WIDTH-1;
1221 else
1222 temp = headx - 1;
1224 olddir = board[temp][heady];
1225 break;
1227 case(SOUTH):
1228 if(heady == 0)
1229 temp = HEIGHT-1;
1230 else
1231 temp = heady - 1;
1233 olddir = board[headx][temp];
1234 break;
1236 case(WEST):
1237 if(headx == WIDTH-1)
1238 temp = 0;
1239 else
1240 temp = headx + 1;
1242 olddir = board[temp][heady];
1243 break;
1246 move();
1249 now redraw the bit that was
1250 the tail, to something snake-like:
1252 draw_snake_bit(dir, olddir, noldx, noldy);
1254 collision(headx, heady);
1256 rb->lcd_update();
1259 static void game_pause (void)
1261 int button;
1263 rb->lcd_clear_display();
1264 rb->lcd_getstringsize("Paused",&strwdt,&strhgt);
1265 rb->lcd_putsxy((LCD_WIDTH - strwdt)/2,LCD_HEIGHT/2,"Paused");
1267 rb->lcd_update();
1268 while (1)
1270 button = rb->button_get(true);
1271 switch (button)
1273 case SNAKE2_PLAYPAUSE:
1274 redraw();
1275 redraw_snake();
1276 draw_head_bit(headx, heady);
1277 rb->lcd_update();
1278 rb->sleep(HZ/2);
1279 return;
1281 #ifdef SNAKE2_RC_QUIT
1282 case SNAKE2_RC_QUIT:
1283 #endif
1284 case SNAKE2_QUIT:
1285 dead = 1;
1286 quit = 1;
1287 return;
1289 default:
1290 if (rb->default_event_handler(button)==SYS_USB_CONNECTED) {
1291 dead = 1;
1292 quit = 2;
1293 return;
1295 break;
1300 static void game (void)
1302 int button;
1304 redraw();
1305 rb->lcd_update();
1306 /*main loop:*/
1307 while (1)
1309 if(frames==5)
1311 frame();
1312 if(frames > 0) frames = 0;
1314 frames++;
1316 if(frames == 0)
1318 die();
1320 else
1322 if(frames < 0)
1324 if(sillydir != dir)
1326 /*it has, great set frames to a positive value again:*/
1327 frames = 1;
1332 if (dead) return;
1334 draw_apple();
1336 rb->sleep(HZ/speed);
1338 button = rb->button_get(false);
1340 #ifdef HAS_BUTTON_HOLD
1341 if (rb->button_hold())
1342 button = SNAKE2_PLAYPAUSE;
1343 #endif
1345 switch (button)
1347 case SNAKE2_UP:
1348 case SNAKE2_UP | BUTTON_REPEAT:
1349 if (dir != SOUTH) set_direction(NORTH);
1350 break;
1352 case SNAKE2_RIGHT:
1353 case SNAKE2_RIGHT | BUTTON_REPEAT:
1354 if (dir != WEST) set_direction(EAST);
1355 break;
1357 case SNAKE2_DOWN:
1358 case SNAKE2_DOWN | BUTTON_REPEAT:
1359 if (dir != NORTH) set_direction(SOUTH);
1360 break;
1362 case SNAKE2_LEFT:
1363 case SNAKE2_LEFT | BUTTON_REPEAT:
1364 if (dir != EAST) set_direction(WEST);
1365 break;
1367 #ifdef SNAKE2_RC_QUIT
1368 case SNAKE2_RC_QUIT:
1369 #endif
1370 case SNAKE2_QUIT:
1371 quit = 1;
1372 return;
1374 case SNAKE2_PLAYPAUSE:
1375 game_pause();
1376 break;
1378 default:
1379 if (rb->default_event_handler(button)==SYS_USB_CONNECTED) {
1380 quit = 2;
1381 return;
1383 break;
1389 static void select_maze(void)
1391 int button;
1393 clear_board();
1394 load_level( level_from_file );
1395 redraw();
1396 rb->lcd_update();
1398 while (1)
1400 #if LCD_WIDTH >= 160 && LCD_HEIGHT >= 128
1401 draw_frame_bitmap(1);
1403 rb->snprintf(strbuf, sizeof(strbuf), "%d", level);
1404 rb->lcd_getstringsize(strbuf, &strwdt, &strhgt);
1405 rb->lcd_putsxy(TOP_X3 - strwdt/2, TOP_Y2, strbuf);
1407 rb->snprintf(strbuf, sizeof(strbuf), "%d", level_from_file);
1408 rb->lcd_getstringsize(strbuf, &strwdt, &strhgt);
1409 rb->lcd_putsxy(TOP_X2 - strwdt/2, TOP_Y1, strbuf);
1411 rb->strcpy(strbuf, game_type==0? "A": "B");
1412 rb->lcd_getstringsize(strbuf, &strwdt, &strhgt);
1413 rb->lcd_putsxy(TOP_X1, TOP_Y1, strbuf);
1415 rb->snprintf(strbuf, sizeof(strbuf), "%d", highscores[0].score);
1416 rb->lcd_getstringsize(strbuf, &strwdt, &strhgt);
1417 rb->lcd_putsxy(TOP_X4 - strwdt/2, TOP_Y2, strbuf);
1419 #else
1420 rb->snprintf(strbuf, sizeof(strbuf), "Maze: %d", level_from_file);
1421 rb->lcd_getstringsize(strbuf, &strwdt, &strhgt);
1422 rb->lcd_putsxy((WIDTH*MULTIPLIER - strwdt)/2,
1423 (HEIGHT*MULTIPLIER - strhgt)/2, strbuf);
1424 #endif
1426 rb->lcd_update();
1428 button = rb->button_get(true);
1429 switch (button)
1431 case SNAKE2_QUIT:
1432 case SNAKE2_PLAYPAUSE:
1433 return;
1434 break;
1435 case SNAKE2_UP:
1436 case SNAKE2_RIGHT:
1437 if(level_from_file < num_levels)
1438 level_from_file++;
1439 else
1440 level_from_file = 0;
1441 load_level( level_from_file );
1442 redraw();
1443 break;
1444 case SNAKE2_DOWN:
1445 case SNAKE2_LEFT:
1446 if(level_from_file > 0)
1447 level_from_file--;
1448 else
1449 level_from_file = num_levels;
1450 load_level( level_from_file );
1451 redraw();
1452 break;
1453 default:
1454 if (rb->default_event_handler(button)==SYS_USB_CONNECTED) {
1455 quit = 2;
1456 return;
1458 break;
1464 static void game_init(void)
1466 int selection = 0;
1468 static const struct opt_items type_options[] = {
1469 { "Type A", -1 },
1470 { "Type B", -1 },
1473 MENUITEM_STRINGLIST(menu, "Snake2 Menu", NULL,
1474 "Start New Game",
1475 "Game Type", "Select Maze", "Speed",
1476 "High Scores",
1477 "Playback Control", "Quit");
1479 rb->button_clear_queue();
1481 dead = 0;
1482 apple = 0;
1483 score = 0;
1484 applecount = 0;
1486 while (1) {
1487 switch (rb->do_menu(&menu, &selection, NULL, false)) {
1488 case 0:
1489 speed = level*20;
1490 return;
1491 case 1:
1492 rb->set_option("Game Type", &game_type, INT,
1493 type_options, 2, NULL);
1494 break;
1495 case 2:
1496 select_maze();
1497 if(quit) return;
1498 break;
1499 case 3:
1500 rb->set_int("Speed", "", UNIT_INT, &level,
1501 NULL, 1, 1, 10, NULL);
1502 break;
1503 case 4:
1504 highscore_show(-1, highscores, NUM_SCORES, true);
1505 break;
1506 case 5:
1507 playback_control(NULL);
1508 break;
1509 case 6:
1510 quit = 1;
1511 return;
1512 case MENU_ATTACHED_USB:
1513 quit = 2;
1514 return;
1515 default:
1516 break;
1521 enum plugin_status plugin_start(const void* parameter)
1523 (void)(parameter);
1525 /* Lets use the default font */
1526 rb->lcd_setfont(FONT_SYSFIXED);
1527 #if LCD_DEPTH > 1
1528 rb->lcd_set_backdrop(NULL);
1529 #endif
1531 load_all_levels();
1533 if (num_levels == 0) {
1534 rb->splash(HZ*2, "Failed loading levels!");
1535 return PLUGIN_OK;
1538 highscore_load(SCORE_FILE, highscores, NUM_SCORES);
1540 while(quit==0)
1542 game_init();
1543 if(quit)
1544 break;
1546 rb->lcd_clear_display();
1547 frames=1;
1549 init_snake();
1551 /*Start Game:*/
1552 game();
1555 highscore_save(SCORE_FILE, highscores, NUM_SCORES);
1557 return (quit==1) ? PLUGIN_OK : PLUGIN_USB_CONNECTED;