ypr0: Fix graphical eq keymap.
[maemo-rb.git] / apps / plugins / snake2.c
blobeec6e7f5c90290af49f0a16b22adcc8c62d8a228
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 #else
125 #define MULTIPLIER 4
126 #define MODIFIER_1 4
127 #define MODIFIER_2 2
128 #define CENTER_X 0
129 #define CENTER_Y 0
131 #endif
133 /* variable button definitions */
134 #if CONFIG_KEYPAD == RECORDER_PAD
135 #define SNAKE2_LEFT BUTTON_LEFT
136 #define SNAKE2_RIGHT BUTTON_RIGHT
137 #define SNAKE2_UP BUTTON_UP
138 #define SNAKE2_DOWN BUTTON_DOWN
139 #define SNAKE2_QUIT BUTTON_OFF
140 #define SNAKE2_PLAYPAUSE BUTTON_PLAY
141 #define SNAKE2_PLAYPAUSE_TEXT "Play"
143 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
144 #define SNAKE2_LEFT BUTTON_LEFT
145 #define SNAKE2_RIGHT BUTTON_RIGHT
146 #define SNAKE2_UP BUTTON_UP
147 #define SNAKE2_DOWN BUTTON_DOWN
148 #define SNAKE2_QUIT BUTTON_OFF
149 #define SNAKE2_PLAYPAUSE BUTTON_SELECT
150 #define SNAKE2_PLAYPAUSE_TEXT "Select"
152 #elif CONFIG_KEYPAD == ONDIO_PAD
153 #define SNAKE2_LEFT BUTTON_LEFT
154 #define SNAKE2_RIGHT BUTTON_RIGHT
155 #define SNAKE2_UP BUTTON_UP
156 #define SNAKE2_DOWN BUTTON_DOWN
157 #define SNAKE2_QUIT BUTTON_OFF
158 #define SNAKE2_PLAYPAUSE BUTTON_MENU
159 #define SNAKE2_PLAYPAUSE_TEXT "Menu"
161 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
162 (CONFIG_KEYPAD == IRIVER_H300_PAD)
163 #define SNAKE2_LEFT BUTTON_LEFT
164 #define SNAKE2_RIGHT BUTTON_RIGHT
165 #define SNAKE2_UP BUTTON_UP
166 #define SNAKE2_DOWN BUTTON_DOWN
167 #define SNAKE2_QUIT BUTTON_OFF
168 #define SNAKE2_PLAYPAUSE BUTTON_ON
169 #define SNAKE2_PLAYPAUSE_TEXT "Play"
171 #define SNAKE2_RC_QUIT BUTTON_RC_STOP
173 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
174 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
175 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
176 #define SNAKE2_LEFT BUTTON_LEFT
177 #define SNAKE2_RIGHT BUTTON_RIGHT
178 #define SNAKE2_UP BUTTON_MENU
179 #define SNAKE2_DOWN BUTTON_PLAY
180 #define SNAKE2_QUIT (BUTTON_SELECT | BUTTON_MENU)
181 #define SNAKE2_PLAYPAUSE BUTTON_SELECT
182 #define SNAKE2_PLAYPAUSE_TEXT "Select"
184 #elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
185 #define SNAKE2_LEFT BUTTON_LEFT
186 #define SNAKE2_RIGHT BUTTON_RIGHT
187 #define SNAKE2_UP BUTTON_UP
188 #define SNAKE2_DOWN BUTTON_DOWN
189 #define SNAKE2_QUIT BUTTON_POWER
190 #define SNAKE2_PLAYPAUSE BUTTON_SELECT
191 #define SNAKE2_PLAYPAUSE_TEXT "Select"
193 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
194 #define SNAKE2_LEFT BUTTON_LEFT
195 #define SNAKE2_RIGHT BUTTON_RIGHT
196 #define SNAKE2_UP BUTTON_UP
197 #define SNAKE2_DOWN BUTTON_DOWN
198 #define SNAKE2_QUIT BUTTON_POWER
199 #define SNAKE2_PLAYPAUSE BUTTON_SELECT
200 #define SNAKE2_PLAYPAUSE_TEXT "Select"
202 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
203 (CONFIG_KEYPAD == SANSA_C200_PAD) || \
204 (CONFIG_KEYPAD == SANSA_CONNECT_PAD)
205 #define SNAKE2_LEFT BUTTON_LEFT
206 #define SNAKE2_RIGHT BUTTON_RIGHT
207 #define SNAKE2_UP BUTTON_UP
208 #define SNAKE2_DOWN BUTTON_DOWN
209 #define SNAKE2_QUIT BUTTON_POWER
210 #define SNAKE2_PLAYPAUSE BUTTON_SELECT
211 #define SNAKE2_PLAYPAUSE_TEXT "Select"
213 #elif (CONFIG_KEYPAD == SANSA_CLIP_PAD) || \
214 (CONFIG_KEYPAD == SANSA_M200_PAD)
215 #define SNAKE2_LEFT BUTTON_LEFT
216 #define SNAKE2_RIGHT BUTTON_RIGHT
217 #define SNAKE2_UP BUTTON_UP
218 #define SNAKE2_DOWN BUTTON_DOWN
219 #define SNAKE2_QUIT BUTTON_POWER
220 #define SNAKE2_PLAYPAUSE BUTTON_SELECT
221 #define SNAKE2_PLAYPAUSE_TEXT "Select"
223 #elif (CONFIG_KEYPAD == SANSA_FUZE_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_HOME|BUTTON_REPEAT)
229 #define SNAKE2_PLAYPAUSE BUTTON_SELECT
230 #define SNAKE2_PLAYPAUSE_TEXT "Select"
232 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
233 #define SNAKE2_LEFT BUTTON_LEFT
234 #define SNAKE2_RIGHT BUTTON_RIGHT
235 #define SNAKE2_UP BUTTON_SCROLL_UP
236 #define SNAKE2_DOWN BUTTON_SCROLL_DOWN
237 #define SNAKE2_QUIT BUTTON_POWER
238 #define SNAKE2_PLAYPAUSE BUTTON_FF
239 #define SNAKE2_PLAYPAUSE_TEXT "FF"
241 #elif (CONFIG_KEYPAD == GIGABEAT_S_PAD) || \
242 (CONFIG_KEYPAD == SAMSUNG_YPR0_PAD)
243 #define SNAKE2_LEFT BUTTON_LEFT
244 #define SNAKE2_RIGHT BUTTON_RIGHT
245 #define SNAKE2_UP BUTTON_UP
246 #define SNAKE2_DOWN BUTTON_DOWN
247 #define SNAKE2_QUIT BUTTON_BACK
248 #define SNAKE2_PLAYPAUSE BUTTON_SELECT
249 #define SNAKE2_PLAYPAUSE_TEXT "Select"
251 #elif (CONFIG_KEYPAD == MROBE100_PAD)
252 #define SNAKE2_LEFT BUTTON_LEFT
253 #define SNAKE2_RIGHT BUTTON_RIGHT
254 #define SNAKE2_UP BUTTON_UP
255 #define SNAKE2_DOWN BUTTON_DOWN
256 #define SNAKE2_QUIT BUTTON_POWER
257 #define SNAKE2_PLAYPAUSE BUTTON_SELECT
258 #define SNAKE2_PLAYPAUSE_TEXT "Select"
260 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
261 #define SNAKE2_LEFT BUTTON_RC_REW
262 #define SNAKE2_RIGHT BUTTON_RC_FF
263 #define SNAKE2_UP BUTTON_RC_VOL_UP
264 #define SNAKE2_DOWN BUTTON_RC_VOL_DOWN
265 #define SNAKE2_QUIT BUTTON_RC_REC
266 #define SNAKE2_PLAYPAUSE BUTTON_RC_PLAY
267 #define SNAKE2_PLAYPAUSE_TEXT "Play"
269 #elif (CONFIG_KEYPAD == COWON_D2_PAD)
270 #define SNAKE2_QUIT BUTTON_POWER
272 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
273 #define SNAKE2_LEFT BUTTON_LEFT
274 #define SNAKE2_RIGHT BUTTON_RIGHT
275 #define SNAKE2_UP BUTTON_UP
276 #define SNAKE2_DOWN BUTTON_DOWN
277 #define SNAKE2_QUIT BUTTON_BACK
278 #define SNAKE2_PLAYPAUSE BUTTON_PLAY
279 #define SNAKE2_PLAYPAUSE_TEXT "Play"
281 #elif (CONFIG_KEYPAD == PHILIPS_HDD1630_PAD) || \
282 (CONFIG_KEYPAD == PHILIPS_HDD6330_PAD)
283 #define SNAKE2_LEFT BUTTON_LEFT
284 #define SNAKE2_RIGHT BUTTON_RIGHT
285 #define SNAKE2_UP BUTTON_UP
286 #define SNAKE2_DOWN BUTTON_DOWN
287 #define SNAKE2_QUIT BUTTON_POWER
288 #define SNAKE2_PLAYPAUSE BUTTON_VIEW
289 #define SNAKE2_PLAYPAUSE_TEXT "View"
291 #elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
292 #define SNAKE2_LEFT BUTTON_PREV
293 #define SNAKE2_RIGHT BUTTON_NEXT
294 #define SNAKE2_UP BUTTON_UP
295 #define SNAKE2_DOWN BUTTON_DOWN
296 #define SNAKE2_QUIT BUTTON_POWER
297 #define SNAKE2_PLAYPAUSE BUTTON_RIGHT
298 #define SNAKE2_PLAYPAUSE_TEXT "Right"
300 #elif (CONFIG_KEYPAD == ONDAVX747_PAD) || \
301 (CONFIG_KEYPAD == ONDAVX777_PAD) || \
302 CONFIG_KEYPAD == MROBE500_PAD
303 #define SNAKE2_QUIT BUTTON_POWER
305 #elif (CONFIG_KEYPAD == SAMSUNG_YH_PAD)
306 #define SNAKE2_LEFT BUTTON_LEFT
307 #define SNAKE2_RIGHT BUTTON_RIGHT
308 #define SNAKE2_UP BUTTON_UP
309 #define SNAKE2_DOWN BUTTON_DOWN
310 #define SNAKE2_QUIT BUTTON_REC
311 #define SNAKE2_PLAYPAUSE BUTTON_PLAY
312 #define SNAKE2_PLAYPAUSE_TEXT "Play"
314 #elif CONFIG_KEYPAD == PBELL_VIBE500_PAD
315 #define SNAKE2_LEFT BUTTON_PREV
316 #define SNAKE2_RIGHT BUTTON_NEXT
317 #define SNAKE2_UP BUTTON_UP
318 #define SNAKE2_DOWN BUTTON_DOWN
319 #define SNAKE2_QUIT BUTTON_REC
320 #define SNAKE2_PLAYPAUSE BUTTON_PLAY
321 #define SNAKE2_PLAYPAUSE_TEXT "Play"
323 #elif CONFIG_KEYPAD == MPIO_HD200_PAD
324 #define SNAKE2_LEFT BUTTON_VOL_DOWN
325 #define SNAKE2_RIGHT BUTTON_VOL_UP
326 #define SNAKE2_UP BUTTON_REW
327 #define SNAKE2_DOWN BUTTON_FF
328 #define SNAKE2_QUIT (BUTTON_REC | BUTTON_PLAY)
329 #define SNAKE2_PLAYPAUSE BUTTON_PLAY
330 #define SNAKE2_PLAYPAUSE_TEXT "Play"
332 #elif CONFIG_KEYPAD == MPIO_HD300_PAD
333 #define SNAKE2_LEFT BUTTON_REW
334 #define SNAKE2_RIGHT BUTTON_FF
335 #define SNAKE2_UP BUTTON_UP
336 #define SNAKE2_DOWN BUTTON_DOWN
337 #define SNAKE2_QUIT (BUTTON_MENU|BUTTON_REPEAT)
338 #define SNAKE2_PLAYPAUSE BUTTON_PLAY
339 #define SNAKE2_PLAYPAUSE_TEXT "Play"
341 #elif CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD
342 #define SNAKE2_LEFT BUTTON_LEFT
343 #define SNAKE2_RIGHT BUTTON_RIGHT
344 #define SNAKE2_UP BUTTON_UP
345 #define SNAKE2_DOWN BUTTON_DOWN
346 #define SNAKE2_QUIT BUTTON_POWER
347 #define SNAKE2_PLAYPAUSE BUTTON_PLAYPAUSE
348 #define SNAKE2_PLAYPAUSE_TEXT "Play-Pause"
350 #elif (CONFIG_KEYPAD == HM60X_PAD) || \
351 (CONFIG_KEYPAD == HM801_PAD)
352 #define SNAKE2_LEFT BUTTON_LEFT
353 #define SNAKE2_RIGHT BUTTON_RIGHT
354 #define SNAKE2_UP BUTTON_UP
355 #define SNAKE2_DOWN BUTTON_DOWN
356 #define SNAKE2_QUIT BUTTON_POWER
357 #define SNAKE2_PLAYPAUSE BUTTON_SELECT
358 #define SNAKE2_PLAYPAUSE_TEXT "Select"
360 #else
361 #error No keymap defined!
362 #endif
364 #ifdef HAVE_TOUCHSCREEN
365 #ifndef SNAKE2_LEFT
366 #define SNAKE2_LEFT BUTTON_MIDLEFT
367 #endif
368 #ifndef SNAKE2_RIGHT
369 #define SNAKE2_RIGHT BUTTON_MIDRIGHT
370 #endif
371 #ifndef SNAKE2_UP
372 #define SNAKE2_UP BUTTON_TOPMIDDLE
373 #endif
374 #ifndef SNAKE2_DOWN
375 #define SNAKE2_DOWN BUTTON_BOTTOMMIDDLE
376 #endif
377 #ifndef SNAKE2_QUIT
378 #define SNAKE2_QUIT BUTTON_TOPLEFT
379 #endif
380 #ifndef SNAKE2_PLAYPAUSE
381 #define SNAKE2_PLAYPAUSE BUTTON_CENTER
382 #endif
383 #ifndef SNAKE2_PLAYPAUSE_TEXT
384 #define SNAKE2_PLAYPAUSE_TEXT "CENTER"
385 #endif
386 #endif
388 static int max_levels = 0;
389 static char (*level_cache)[HEIGHT][WIDTH];
391 /*Board itself - 2D int array*/
392 static int board[WIDTH][HEIGHT];
394 Buffer for sorting movement (in case user presses two movements during a
395 single frame
397 static int ardirectionbuffer[2];
398 static int score;
399 static int applex;
400 static int appley;
401 static int dir;
402 static int frames;
403 static int apple;
404 static int level = 4, speed = 5,dead = 0, quit = 0;
405 static int sillydir = 0, num_levels = 0;
406 static int level_from_file = 0;
407 static int headx, heady, tailx, taily, applecountdown = 5;
408 static int game_type = 0;
409 static int num_apples_to_get=1;
410 static int num_apples_to_got=0;
411 static int game_b_level=0;
412 static int applecount=0;
413 /* used for string width, height for orientation purposes */
414 static int strwdt, strhgt;
415 static char strbuf[32];
417 #define NUM_SCORES 5
418 static struct highscore highscores[NUM_SCORES];
420 #define NORTH 1
421 #define EAST 2
422 #define SOUTH 4
423 #define WEST 8
424 #define HEAD 16
426 #define EAST_NORTH 32
427 #define EAST_SOUTH 64
428 #define WEST_NORTH 128
429 #define WEST_SOUTH 256
431 #define NORTH_EAST 512
432 #define NORTH_WEST 1024
433 #define SOUTH_EAST 2048
434 #define SOUTH_WEST 4096
436 #define LEVELS_FILE PLUGIN_GAMES_DIR "/snake2.levels"
437 #define SCORE_FILE PLUGIN_GAMES_DATA_DIR "/snake2.score"
439 static int load_all_levels(void)
441 int linecnt = 0;
442 int fd;
443 size_t size;
444 char buf[64]; /* Larger than WIDTH, to allow for whitespace after the
445 lines */
447 /* Init the level_cache pointer and
448 calculate how many levels that will fit */
449 level_cache = rb->plugin_get_buffer(&size);
450 max_levels = size / (HEIGHT*WIDTH);
452 num_levels = 0;
454 /* open file */
455 if ((fd = rb->open(LEVELS_FILE, O_RDONLY)) < 0)
457 return -1;
460 while(rb->read_line(fd, buf, 64) > 0)
462 if(rb->strlen(buf) == 0) /* Separator? */
464 num_levels++;
465 if(num_levels > max_levels)
467 rb->splash(HZ, "Too many levels in file");
468 break;
470 continue;
473 rb->memcpy(level_cache[num_levels][linecnt], buf, WIDTH);
474 linecnt++;
475 if(linecnt == HEIGHT)
477 linecnt = 0;
481 rb->close(fd);
482 return 0;
486 ** Completely clear the board of walls and/or snake
489 static void clear_board( void)
491 int x,y;
493 for (x = 0; x < WIDTH; x++)
495 for (y = 0; y < HEIGHT; y++)
497 board[x][y] = 0;
502 static int load_level( int level_number )
504 int x,y;
505 clear_board();
506 for(y = 0;y < HEIGHT;y++)
508 for(x = 0;x < WIDTH;x++)
510 switch(level_cache[level_number][y][x])
512 case '|':
513 board[x][y] = NORTH;
514 break;
516 case '-':
517 board[x][y] = EAST;
518 break;
520 case '+':
521 board[x][y] = HEAD;
522 break;
526 return 1;
530 ** Gets the currently chosen direction from the first place
531 ** in the direction buffer. If there is something in the
532 ** next part of the buffer then that is moved to the first place
534 static void get_direction( void )
536 /*if 1st place is empty*/
537 if(ardirectionbuffer[0] != -1)
539 /*return this direction*/
540 dir = ardirectionbuffer[0];
541 ardirectionbuffer[0]=-1;
542 /*now see if one needs moving:*/
543 if(ardirectionbuffer[1] != -1)
545 /*there's a move waiting to be done
546 so move it into the space:*/
547 ardirectionbuffer[0] = ardirectionbuffer[1];
548 ardirectionbuffer[1] = -1;
554 ** Sets the direction
556 static void set_direction(int newdir)
558 if(ardirectionbuffer[0] != newdir)
560 /*if 1st place is empty*/
561 if(ardirectionbuffer[0] == -1)
563 /*use 1st space:*/
564 ardirectionbuffer[0] = newdir;
566 else
568 /*use 2nd space:*/
569 if(ardirectionbuffer[0] != newdir) ardirectionbuffer[1] = newdir;
572 if(frames < 0) ardirectionbuffer[0] = newdir;
576 static void new_level(int level)
578 load_level(level);
580 ardirectionbuffer[0] = -1;
581 ardirectionbuffer[1] = -1;
582 dir = EAST;
583 headx = WIDTH/2;
584 heady = HEIGHT/2;
585 tailx = headx - 4;
586 taily = heady;
587 applecountdown = 0;
588 /*Create a small snake to start off with*/
589 board[headx][heady] = dir;
590 board[headx-1][heady] = dir;
591 board[headx-2][heady] = dir;
592 board[headx-3][heady] = dir;
593 board[headx-4][heady] = dir;
594 num_apples_to_got=0;
597 static void init_snake(void)
599 num_apples_to_get=1;
600 if(game_type == 1)
601 level_from_file = 1;
602 game_b_level=1;
603 new_level(level_from_file);
606 #if (LCD_WIDTH >= 160) && (LCD_HEIGHT >= 128)
607 static void draw_frame_bitmap(int header_type)
609 rb->lcd_bitmap(header_type==1? snake2_header1: snake2_header2, 0, 0,
610 BMPWIDTH_snake2_header, BMPHEIGHT_snake2_header);
611 rb->lcd_bitmap(snake2_left, 0, BMPHEIGHT_snake2_header,
612 BMPWIDTH_snake2_left, BMPHEIGHT_snake2_left);
613 rb->lcd_bitmap(snake2_right,
614 LCD_WIDTH - BMPWIDTH_snake2_right, BMPHEIGHT_snake2_header,
615 BMPWIDTH_snake2_right, BMPHEIGHT_snake2_right);
616 rb->lcd_bitmap(snake2_bottom,
617 0, BMPHEIGHT_snake2_header + BMPHEIGHT_snake2_left,
618 BMPWIDTH_snake2_bottom, BMPHEIGHT_snake2_bottom);
620 #endif
623 ** Draws the apple. If it doesn't exist then
624 ** a new one get's created.
626 static void draw_apple_bit(int x, int y)
628 rb->lcd_fillrect((CENTER_X+x*MULTIPLIER)+1, CENTER_Y+y*MULTIPLIER,
629 MODIFIER_2, MODIFIER_1);
630 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER, (CENTER_Y+y*MULTIPLIER)+1,
631 MODIFIER_1, MODIFIER_2);
634 static void draw_apple( void )
636 int x,y;
638 #if LCD_WIDTH >= 160 && LCD_HEIGHT >= 128
639 draw_frame_bitmap(2);
641 rb->snprintf(strbuf, sizeof(strbuf), "%d", applecount);
642 rb->lcd_getstringsize(strbuf, &strwdt, &strhgt);
643 rb->lcd_putsxy(TOP_X3 - strwdt/2, TOP_Y2, strbuf);
645 rb->snprintf(strbuf, sizeof(strbuf), "%d", score);
646 rb->lcd_getstringsize(strbuf, &strwdt, &strhgt);
647 rb->lcd_putsxy(TOP_X4 - strwdt/2, TOP_Y2, strbuf);
648 #endif
650 if (!apple)
654 x = (rb->rand() % (WIDTH-1))+1;
655 y = (rb->rand() % (HEIGHT-1))+1;
656 } while (board[x][y]);
657 apple = 1;
658 board[x][y] = -1;
659 applex = x;appley = y;
661 draw_apple_bit(applex, appley);
665 * x x *
666 * x x *
667 * x x *
668 * x x *
670 static void draw_vertical_bit(int x, int y)
672 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER+1, CENTER_Y+y*MULTIPLIER,
673 MODIFIER_2, MODIFIER_1);
677 * * * *
678 X X X X
679 X X X X
680 * * * *
682 static void draw_horizontal_bit(int x, int y)
684 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER, CENTER_Y+y*MULTIPLIER+1,
685 MODIFIER_1, MODIFIER_2);
689 * * * *
690 * * X X
691 * X X X
692 * X X *
694 static void draw_n_to_e_bit(int x, int y)
696 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER+1, CENTER_Y+y*MULTIPLIER+2,
697 MODIFIER_2, MODIFIER_2);
698 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER+2, CENTER_Y+y*MULTIPLIER+1,
699 MODIFIER_2, MODIFIER_2);
703 * * * *
704 * * X X
705 * X X X
706 * X X *
708 static void draw_w_to_s_bit(int x, int y)
710 draw_n_to_e_bit(x,y);
714 * * * *
715 X X * *
716 X X X *
717 * X X *
719 static void draw_n_to_w_bit(int x, int y)
721 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER, CENTER_Y+y*MULTIPLIER+1,
722 MODIFIER_2, MODIFIER_2);
723 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER+1, CENTER_Y+y*MULTIPLIER+2,
724 MODIFIER_2, MODIFIER_2);
728 * * * *
729 X X * *
730 X X X *
731 * X X *
733 static void draw_e_to_s_bit(int x, int y)
735 draw_n_to_w_bit(x, y);
739 * X X *
740 * X X X
741 * * X X
742 * * * *
744 static void draw_s_to_e_bit(int x, int y)
746 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER+1, CENTER_Y+y*MULTIPLIER,
747 MODIFIER_2, MODIFIER_2);
748 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER+2, CENTER_Y+y*MULTIPLIER+1,
749 MODIFIER_2, MODIFIER_2);
753 * X X *
754 * X X X
755 * * X X
756 * * * *
758 static void draw_w_to_n_bit(int x, int y)
760 draw_s_to_e_bit(x,y);
764 * X X *
765 X X X *
766 X X * *
767 * * * *
769 static void draw_e_to_n_bit(int x, int y)
771 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER+1, CENTER_Y+y*MULTIPLIER,
772 MODIFIER_2, MODIFIER_2);
773 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER, CENTER_Y+y*MULTIPLIER+1,
774 MODIFIER_2, MODIFIER_2);
778 * X X *
779 X X X *
780 X X * *
781 * * * *
783 static void draw_s_to_w_bit(int x, int y)
785 draw_e_to_n_bit(x, y);
788 static void draw_head_bit(int x, int y)
790 rb->lcd_fillrect(CENTER_X+x*MULTIPLIER, CENTER_Y+y*MULTIPLIER,
791 MODIFIER_1, MODIFIER_1);
794 #if 0 /* unused */
796 ** Draws a wall/obsticals
798 static void draw_boundary ( void )
800 int x, y;
802 /*TODO: Load levels from file!*/
804 /*top and bottom line*/
805 for(x=0; x < WIDTH; x++)
807 board[x][0] = EAST;
808 board[x][HEIGHT-1] = WEST;
811 /*left and right lines*/
812 for(y=0; y < HEIGHT; y++)
814 board[0][y] = NORTH;
815 board[WIDTH-1][y] = SOUTH;
818 /*corners:*/
819 board[0][0] = NORTH_EAST;
820 board[WIDTH-1][0] = EAST_SOUTH;
821 board[0][HEIGHT-1] = SOUTH_EAST;
822 board[WIDTH-1][HEIGHT-1] = EAST_NORTH;
824 #endif
827 ** Redraw the entire board
829 static void redraw (void)
831 int x,y;
833 #ifdef HAVE_LCD_COLOR
834 rb->lcd_set_foreground(LCD_BLACK);
835 rb->lcd_set_background(LCD_WHITE);
836 #endif
838 rb->lcd_clear_display();
840 for (x = 0; x < WIDTH; x++)
842 for (y = 0; y < HEIGHT; y++)
844 switch (board[x][y])
846 case -1:
847 draw_apple_bit(x, y);
848 break;
849 case 0:
850 break;
852 case NORTH:
853 case SOUTH:
854 draw_vertical_bit(x,y);
855 break;
857 case EAST:
858 case WEST:
859 draw_horizontal_bit(x,y);
860 break;
862 default:
863 draw_head_bit(x, y);
864 break;
869 #if LCD_WIDTH >= 160 && LCD_HEIGHT >= 128
870 draw_frame_bitmap(2);
872 rb->snprintf(strbuf, sizeof(strbuf), "%d", applecount);
873 rb->lcd_getstringsize(strbuf, &strwdt, &strhgt);
874 rb->lcd_putsxy(TOP_X3 - strwdt/2, TOP_Y2, strbuf);
876 rb->snprintf(strbuf, sizeof(strbuf), "%d", score);
877 rb->lcd_getstringsize(strbuf, &strwdt, &strhgt);
878 rb->lcd_putsxy(TOP_X4 - strwdt/2, TOP_Y2, strbuf);
879 #endif
883 ** Draws the snake bit described by nCurrentBit at position x/y
884 ** deciding whether it's a corner bit by examing the nPrevious bit
886 static void draw_snake_bit(int currentbit, int previousbit, int x, int y)
888 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
889 draw_head_bit(x, y);
890 rb->lcd_set_drawmode(DRMODE_SOLID);
892 switch(currentbit)
894 case(NORTH):
895 switch(previousbit)
897 case(SOUTH):
898 case(NORTH):
899 draw_vertical_bit(x,y);
900 break;
902 case(EAST):
903 draw_e_to_n_bit(x,y);
904 break;
906 case(WEST):
907 draw_w_to_n_bit(x,y);
908 break;
910 break;
912 case(EAST):
913 switch(previousbit)
915 case(WEST):
916 case(EAST):
917 draw_horizontal_bit(x,y);
918 break;
920 case(NORTH):
921 draw_n_to_e_bit(x,y);
922 break;
924 case(SOUTH):
925 draw_s_to_e_bit(x,y);
926 break;
928 break;
930 case(SOUTH):
931 switch(previousbit)
933 case(SOUTH):
934 case(NORTH):
935 draw_vertical_bit(x,y);
936 break;
938 case(EAST):
939 draw_e_to_s_bit(x,y);
940 break;
942 case(WEST):
943 draw_w_to_s_bit(x,y);
944 break;
946 break;
948 case(WEST):
949 switch(previousbit)
951 case(EAST):
952 case(WEST):
953 draw_horizontal_bit(x,y);
954 break;
956 case(SOUTH):
957 draw_s_to_w_bit(x,y);
958 break;
960 case(NORTH):
961 draw_n_to_w_bit(x,y);
962 break;
964 break;
968 static void redraw_snake(void)
970 int x = tailx, y = taily;
971 int olddir, newdir = board[x][y];
973 while (x != headx || y != heady)
975 olddir = newdir;
977 switch (olddir)
979 case(NORTH):
980 y--;
981 break;
983 case(EAST):
984 x++;
985 break;
987 case(SOUTH):
988 y++;
989 break;
991 case(WEST):
992 x--;
993 break;
996 if(x == WIDTH)
997 x = 0;
998 else if(x < 0)
999 x = WIDTH-1;
1001 if(y == HEIGHT)
1002 y = 0;
1003 else if(y < 0)
1004 y = HEIGHT-1;
1006 newdir = board[x][y];
1007 if(olddir != newdir)
1008 draw_snake_bit(newdir, olddir, x, y);
1013 ** Death 'sequence' and end game stuff.
1015 static void die (void)
1017 int button;
1018 bool done=false;
1020 rb->splash(HZ*2, "Oops!");
1022 rb->lcd_clear_display();
1024 applecount=0;
1026 rb->lcd_getstringsize("You died!",&strwdt,&strhgt);
1027 rb->lcd_putsxy((LCD_WIDTH - strwdt)/2,strhgt,"You died!");
1029 rb->snprintf(strbuf, sizeof(strbuf), "Your score: %d", score);
1030 rb->lcd_getstringsize(strbuf, &strwdt, &strhgt);
1031 rb->lcd_putsxy((LCD_WIDTH - strwdt)/2, strhgt * 2 + 2, strbuf);
1033 if (highscore_update(score, level_from_file, game_type==0?"Type A":"Type B",
1034 highscores, NUM_SCORES) == 0)
1036 rb->lcd_getstringsize("New high score!",&strwdt,&strhgt);
1037 rb->lcd_putsxy((LCD_WIDTH - strwdt)/2,strhgt * 4 + 2,"New high score!");
1039 else
1041 rb->snprintf(strbuf, sizeof(strbuf), "High score: %d", highscores[0].score);
1042 rb->lcd_getstringsize(strbuf, &strwdt, &strhgt);
1043 rb->lcd_putsxy((LCD_WIDTH - strwdt)/2, strhgt * 5, strbuf);
1046 rb->snprintf(strbuf, sizeof(strbuf), "Press %s...", SNAKE2_PLAYPAUSE_TEXT);
1047 rb->lcd_getstringsize(strbuf, &strwdt, &strhgt);
1048 rb->lcd_putsxy((LCD_WIDTH - strwdt)/2, strhgt * 7, strbuf);
1050 rb->lcd_update();
1052 while(!done)
1054 button=rb->button_get(true);
1055 switch(button)
1057 case SNAKE2_PLAYPAUSE:
1058 done = true;
1059 break;
1063 dead=1;
1067 ** Check for collision. TODO: Currently this
1068 ** sets of the death sequence. What we want is it to only return a true/false
1069 ** depending on whether a collision occured.
1071 static void collision ( int x, int y )
1073 int bdeath=0;
1076 switch (board[x][y])
1078 case 0:
1080 break;
1081 case -1:
1082 score = score + (1 * level);
1083 apple=0;
1084 applecountdown=2;
1085 applecount++;
1087 if(game_type==1)
1089 if(num_apples_to_get == num_apples_to_got)
1091 level_from_file++;
1092 if(level_from_file >= num_levels)
1094 level_from_file = 1;
1095 /*and increase the number of apples to pick up
1096 before level changes*/
1097 num_apples_to_get+=2;
1098 game_b_level++;
1100 rb->splash(HZ, "Level Completed!");
1101 new_level(level_from_file);
1102 redraw();
1103 rb->lcd_update();
1105 else
1106 num_apples_to_got++;
1108 break;
1109 default:
1110 bdeath=1;
1111 break;
1114 if(bdeath==1)
1116 die();
1117 sillydir = dir;
1118 frames = -110;
1122 static void move( void )
1124 int taildir;
1125 /*this actually sets the dir variable.*/
1126 get_direction();
1127 /*draw head*/
1128 switch (dir)
1130 case (NORTH):
1131 board[headx][heady]=NORTH;
1132 heady--;
1133 break;
1134 case (EAST):
1135 board[headx][heady]=EAST;
1136 headx++;
1137 break;
1138 case (SOUTH):
1139 board[headx][heady]=SOUTH;
1140 heady++;
1141 break;
1142 case (WEST):
1143 board[headx][heady]=WEST;
1144 headx--;
1145 break;
1148 if(headx == WIDTH)
1149 headx = 0;
1150 else if(headx < 0)
1151 headx = WIDTH-1;
1153 if(heady == HEIGHT)
1154 heady = 0;
1155 else if(heady < 0)
1156 heady = HEIGHT-1;
1158 draw_head_bit(headx, heady);
1160 /*clear tail*/
1161 if(applecountdown <= 0)
1163 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
1164 draw_head_bit(tailx, taily);
1165 rb->lcd_set_drawmode(DRMODE_SOLID);
1167 taildir = board[tailx][taily];
1168 board[tailx][taily] = 0;
1170 switch (taildir)
1172 case(NORTH):
1173 taily--;
1174 break;
1176 case(EAST):
1177 tailx++;
1178 break;
1180 case(SOUTH):
1181 taily++;
1182 break;
1184 case(WEST):
1185 tailx--;
1186 break;
1189 if(tailx == WIDTH)
1190 tailx = 0;
1191 else if(tailx < 0)
1192 tailx = WIDTH-1;
1194 if(taily == HEIGHT)
1195 taily = 0;
1196 else if(taily < 0)
1197 taily = HEIGHT-1;
1199 else
1200 applecountdown--;
1203 static void frame (void)
1205 int olddir, noldx, noldy, temp;
1206 noldx = headx;
1207 noldy = heady;
1208 olddir = 0;
1209 switch(dir)
1211 case(NORTH):
1212 if(heady == HEIGHT-1)
1213 temp = 0;
1214 else
1215 temp = heady + 1;
1217 olddir = board[headx][temp];
1218 break;
1220 case(EAST):
1221 if(headx == 0)
1222 temp = WIDTH-1;
1223 else
1224 temp = headx - 1;
1226 olddir = board[temp][heady];
1227 break;
1229 case(SOUTH):
1230 if(heady == 0)
1231 temp = HEIGHT-1;
1232 else
1233 temp = heady - 1;
1235 olddir = board[headx][temp];
1236 break;
1238 case(WEST):
1239 if(headx == WIDTH-1)
1240 temp = 0;
1241 else
1242 temp = headx + 1;
1244 olddir = board[temp][heady];
1245 break;
1248 move();
1251 now redraw the bit that was
1252 the tail, to something snake-like:
1254 draw_snake_bit(dir, olddir, noldx, noldy);
1256 collision(headx, heady);
1258 rb->lcd_update();
1261 static void game_pause (void)
1263 int button;
1265 rb->lcd_clear_display();
1266 rb->lcd_getstringsize("Paused",&strwdt,&strhgt);
1267 rb->lcd_putsxy((LCD_WIDTH - strwdt)/2,LCD_HEIGHT/2,"Paused");
1269 rb->lcd_update();
1270 while (1)
1272 button = rb->button_get(true);
1273 switch (button)
1275 case SNAKE2_PLAYPAUSE:
1276 redraw();
1277 redraw_snake();
1278 draw_head_bit(headx, heady);
1279 rb->lcd_update();
1280 rb->sleep(HZ/2);
1281 return;
1283 #ifdef SNAKE2_RC_QUIT
1284 case SNAKE2_RC_QUIT:
1285 #endif
1286 case SNAKE2_QUIT:
1287 dead = 1;
1288 quit = 1;
1289 return;
1291 default:
1292 if (rb->default_event_handler(button)==SYS_USB_CONNECTED) {
1293 dead = 1;
1294 quit = 2;
1295 return;
1297 break;
1302 static void game (void)
1304 int button;
1306 redraw();
1307 rb->lcd_update();
1308 /*main loop:*/
1309 while (1)
1311 if(frames==5)
1313 frame();
1314 if(frames > 0) frames = 0;
1316 frames++;
1318 if(frames == 0)
1320 die();
1322 else
1324 if(frames < 0)
1326 if(sillydir != dir)
1328 /*it has, great set frames to a positive value again:*/
1329 frames = 1;
1334 if (dead) return;
1336 draw_apple();
1338 rb->sleep(HZ/speed);
1340 button = rb->button_get(false);
1342 #ifdef HAS_BUTTON_HOLD
1343 if (rb->button_hold())
1344 button = SNAKE2_PLAYPAUSE;
1345 #endif
1347 switch (button)
1349 case SNAKE2_UP:
1350 case SNAKE2_UP | BUTTON_REPEAT:
1351 if (dir != SOUTH) set_direction(NORTH);
1352 break;
1354 case SNAKE2_RIGHT:
1355 case SNAKE2_RIGHT | BUTTON_REPEAT:
1356 if (dir != WEST) set_direction(EAST);
1357 break;
1359 case SNAKE2_DOWN:
1360 case SNAKE2_DOWN | BUTTON_REPEAT:
1361 if (dir != NORTH) set_direction(SOUTH);
1362 break;
1364 case SNAKE2_LEFT:
1365 case SNAKE2_LEFT | BUTTON_REPEAT:
1366 if (dir != EAST) set_direction(WEST);
1367 break;
1369 #ifdef SNAKE2_RC_QUIT
1370 case SNAKE2_RC_QUIT:
1371 #endif
1372 case SNAKE2_QUIT:
1373 quit = 1;
1374 return;
1376 case SNAKE2_PLAYPAUSE:
1377 game_pause();
1378 break;
1380 default:
1381 if (rb->default_event_handler(button)==SYS_USB_CONNECTED) {
1382 quit = 2;
1383 return;
1385 break;
1391 static void select_maze(void)
1393 int button;
1395 clear_board();
1396 load_level( level_from_file );
1397 redraw();
1398 rb->lcd_update();
1400 while (1)
1402 #if LCD_WIDTH >= 160 && LCD_HEIGHT >= 128
1403 draw_frame_bitmap(1);
1405 rb->snprintf(strbuf, sizeof(strbuf), "%d", level);
1406 rb->lcd_getstringsize(strbuf, &strwdt, &strhgt);
1407 rb->lcd_putsxy(TOP_X3 - strwdt/2, TOP_Y2, strbuf);
1409 rb->snprintf(strbuf, sizeof(strbuf), "%d", level_from_file);
1410 rb->lcd_getstringsize(strbuf, &strwdt, &strhgt);
1411 rb->lcd_putsxy(TOP_X2 - strwdt/2, TOP_Y1, strbuf);
1413 rb->strcpy(strbuf, game_type==0? "A": "B");
1414 rb->lcd_getstringsize(strbuf, &strwdt, &strhgt);
1415 rb->lcd_putsxy(TOP_X1, TOP_Y1, strbuf);
1417 rb->snprintf(strbuf, sizeof(strbuf), "%d", highscores[0].score);
1418 rb->lcd_getstringsize(strbuf, &strwdt, &strhgt);
1419 rb->lcd_putsxy(TOP_X4 - strwdt/2, TOP_Y2, strbuf);
1421 #else
1422 rb->snprintf(strbuf, sizeof(strbuf), "Maze: %d", level_from_file);
1423 rb->lcd_getstringsize(strbuf, &strwdt, &strhgt);
1424 rb->lcd_putsxy((WIDTH*MULTIPLIER - strwdt)/2,
1425 (HEIGHT*MULTIPLIER - strhgt)/2, strbuf);
1426 #endif
1428 rb->lcd_update();
1430 button = rb->button_get(true);
1431 switch (button)
1433 case SNAKE2_QUIT:
1434 case SNAKE2_PLAYPAUSE:
1435 return;
1436 break;
1437 case SNAKE2_UP:
1438 case SNAKE2_RIGHT:
1439 if(level_from_file < num_levels)
1440 level_from_file++;
1441 else
1442 level_from_file = 0;
1443 load_level( level_from_file );
1444 redraw();
1445 break;
1446 case SNAKE2_DOWN:
1447 case SNAKE2_LEFT:
1448 if(level_from_file > 0)
1449 level_from_file--;
1450 else
1451 level_from_file = num_levels;
1452 load_level( level_from_file );
1453 redraw();
1454 break;
1455 default:
1456 if (rb->default_event_handler(button)==SYS_USB_CONNECTED) {
1457 quit = 2;
1458 return;
1460 break;
1466 static void game_init(void)
1468 int selection = 0;
1470 static const struct opt_items type_options[] = {
1471 { "Type A", -1 },
1472 { "Type B", -1 },
1475 MENUITEM_STRINGLIST(menu, "Snake2 Menu", NULL,
1476 "Start New Game",
1477 "Game Type", "Select Maze", "Speed",
1478 "High Scores",
1479 "Playback Control", "Quit");
1481 rb->button_clear_queue();
1483 dead = 0;
1484 apple = 0;
1485 score = 0;
1486 applecount = 0;
1488 while (1) {
1489 switch (rb->do_menu(&menu, &selection, NULL, false)) {
1490 case 0:
1491 speed = level*20;
1492 return;
1493 case 1:
1494 rb->set_option("Game Type", &game_type, INT,
1495 type_options, 2, NULL);
1496 break;
1497 case 2:
1498 select_maze();
1499 if(quit) return;
1500 break;
1501 case 3:
1502 rb->set_int("Speed", "", UNIT_INT, &level,
1503 NULL, 1, 1, 10, NULL);
1504 break;
1505 case 4:
1506 highscore_show(-1, highscores, NUM_SCORES, true);
1507 break;
1508 case 5:
1509 playback_control(NULL);
1510 break;
1511 case 6:
1512 quit = 1;
1513 return;
1514 case MENU_ATTACHED_USB:
1515 quit = 2;
1516 return;
1517 default:
1518 break;
1523 enum plugin_status plugin_start(const void* parameter)
1525 (void)(parameter);
1527 /* Lets use the default font */
1528 rb->lcd_setfont(FONT_SYSFIXED);
1529 #if LCD_DEPTH > 1
1530 rb->lcd_set_backdrop(NULL);
1531 #endif
1533 load_all_levels();
1535 if (num_levels == 0) {
1536 rb->splash(HZ*2, "Failed loading levels!");
1537 return PLUGIN_OK;
1540 highscore_load(SCORE_FILE, highscores, NUM_SCORES);
1542 while(quit==0)
1544 game_init();
1545 if(quit)
1546 break;
1548 rb->lcd_clear_display();
1549 frames=1;
1551 init_snake();
1553 /*Start Game:*/
1554 game();
1557 highscore_save(SCORE_FILE, highscores, NUM_SCORES);
1559 return (quit==1) ? PLUGIN_OK : PLUGIN_USB_CONNECTED;