1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2003 Mat Holton
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
23 Board consists of a WIDTHxHEIGHT grid. If board element is 0 then nothing is
24 there otherwise it is part of the snake or a wall.
26 Head and Tail are stored
31 #ifdef HAVE_LCD_BITMAP
38 #if (LCD_WIDTH >= 320) && (LCD_HEIGHT >= 240)
39 #define MULTIPLIER 10 /*Modifier for porting on other screens*/
44 #define TOP_X1 34 /* x-coord of the upperleft item (game type) */
45 #define TOP_X2 281 /* x-coord of the upperright item (maze type) */
46 #define TOP_X3 42 /* x-coord of the lowerleft item (speed) */
47 #define TOP_X4 274 /* x-coord of the lowerright item (hi-score) */
48 #define TOP_Y1 4 /* y-coord of the top row of items */
49 #define TOP_Y2 25 /* y-coord of the bottom row of items */
50 #define BMPHEIGHT_snake2_header 38
51 #define BMPWIDTH_snake2_header 320
52 #define BMPHEIGHT_snake2_right 192
53 #define BMPWIDTH_snake2_right 10
54 #define BMPHEIGHT_snake2_left 192
55 #define BMPWIDTH_snake2_left 10
56 #define BMPHEIGHT_snake2_bottom 10
57 #define BMPWIDTH_snake2_bottom 320
58 #elif (LCD_WIDTH >= 240) && (LCD_HEIGHT >= 168)
70 #define BMPHEIGHT_snake2_header 38
71 #define BMPWIDTH_snake2_header 240
72 #define BMPHEIGHT_snake2_right 120
73 #define BMPWIDTH_snake2_right 10
74 #define BMPHEIGHT_snake2_left 120
75 #define BMPWIDTH_snake2_left 10
76 #define BMPHEIGHT_snake2_bottom 10
77 #define BMPWIDTH_snake2_bottom 240
78 #elif (LCD_WIDTH >= 220) && (LCD_HEIGHT >= 176)
90 #define BMPHEIGHT_snake2_header 38
91 #define BMPWIDTH_snake2_header 220
92 #define BMPHEIGHT_snake2_right 128
93 #define BMPWIDTH_snake2_right 10
94 #define BMPHEIGHT_snake2_left 128
95 #define BMPWIDTH_snake2_left 10
96 #define BMPHEIGHT_snake2_bottom 10
97 #define BMPWIDTH_snake2_bottom 220
98 #elif (LCD_WIDTH >= 176) && (LCD_HEIGHT >= 132)
110 #define BMPHEIGHT_snake2_header 38
111 #define BMPWIDTH_snake2_header 176
112 #define BMPHEIGHT_snake2_right 84
113 #define BMPWIDTH_snake2_right 10
114 #define BMPHEIGHT_snake2_left 84
115 #define BMPWIDTH_snake2_left 10
116 #define BMPHEIGHT_snake2_bottom 10
117 #define BMPWIDTH_snake2_bottom 176
118 #elif (LCD_WIDTH >= 160) && (LCD_HEIGHT >= 128)
130 #define BMPHEIGHT_snake2_header 38
131 #define BMPWIDTH_snake2_header 160
132 #define BMPHEIGHT_snake2_right 80
133 #define BMPWIDTH_snake2_right 10
134 #define BMPHEIGHT_snake2_left 80
135 #define BMPWIDTH_snake2_left 10
136 #define BMPHEIGHT_snake2_bottom 10
137 #define BMPWIDTH_snake2_bottom 160
147 /* variable button definitions */
148 #if CONFIG_KEYPAD == RECORDER_PAD
149 #define SNAKE2_UP BUTTON_UP
150 #define SNAKE2_DOWN BUTTON_DOWN
151 #define SNAKE2_QUIT BUTTON_OFF
152 #define SNAKE2_LEVEL_UP BUTTON_UP
153 #define SNAKE2_LEVEL_DOWN BUTTON_DOWN
154 #define SNAKE2_MAZE_NEXT BUTTON_RIGHT
155 #define SNAKE2_MAZE_LAST BUTTON_LEFT
156 #define SNAKE2_SELECT_TYPE BUTTON_F3
157 #define SNAKE2_PLAYPAUSE BUTTON_PLAY
158 #define SNAKE2_PLAYPAUSE_TEXT "Play"
160 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
161 #define SNAKE2_UP BUTTON_UP
162 #define SNAKE2_DOWN BUTTON_DOWN
163 #define SNAKE2_QUIT BUTTON_OFF
164 #define SNAKE2_LEVEL_UP BUTTON_UP
165 #define SNAKE2_LEVEL_DOWN BUTTON_DOWN
166 #define SNAKE2_MAZE_NEXT BUTTON_RIGHT
167 #define SNAKE2_MAZE_LAST BUTTON_LEFT
168 #define SNAKE2_SELECT_TYPE BUTTON_F3
169 #define SNAKE2_PLAYPAUSE BUTTON_SELECT
170 #define SNAKE2_PLAYPAUSE_TEXT "Select"
172 #elif CONFIG_KEYPAD == ONDIO_PAD
173 #define SNAKE2_UP BUTTON_UP
174 #define SNAKE2_DOWN BUTTON_DOWN
175 #define SNAKE2_QUIT BUTTON_OFF
176 #define SNAKE2_LEVEL_UP BUTTON_UP
177 #define SNAKE2_LEVEL_DOWN BUTTON_DOWN
178 #define SNAKE2_MAZE_NEXT BUTTON_RIGHT
179 #define SNAKE2_SELECT_TYPE BUTTON_LEFT
180 #define SNAKE2_PLAYPAUSE BUTTON_MENU
181 #define SNAKE2_PLAYPAUSE_TEXT "Menu"
183 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
184 (CONFIG_KEYPAD == IRIVER_H300_PAD)
185 #define SNAKE2_UP BUTTON_UP
186 #define SNAKE2_DOWN BUTTON_DOWN
187 #define SNAKE2_QUIT BUTTON_OFF
188 #define SNAKE2_LEVEL_UP BUTTON_UP
189 #define SNAKE2_LEVEL_DOWN BUTTON_DOWN
190 #define SNAKE2_MAZE_NEXT BUTTON_RIGHT
191 #define SNAKE2_MAZE_LAST BUTTON_LEFT
192 #define SNAKE2_SELECT_TYPE BUTTON_MODE
193 #define SNAKE2_PLAYPAUSE BUTTON_ON
194 #define SNAKE2_PLAYPAUSE_TEXT "Play"
196 #define SNAKE2_RC_QUIT BUTTON_RC_STOP
197 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
198 (CONFIG_KEYPAD == IPOD_3G_PAD)
199 #define SNAKE2_UP BUTTON_MENU
200 #define SNAKE2_DOWN BUTTON_PLAY
201 #define SNAKE2_QUIT (BUTTON_SELECT | BUTTON_MENU)
202 #define SNAKE2_LEVEL_UP BUTTON_SCROLL_FWD
203 #define SNAKE2_LEVEL_DOWN BUTTON_SCROLL_BACK
204 #define SNAKE2_MAZE_NEXT BUTTON_RIGHT
205 #define SNAKE2_MAZE_LAST BUTTON_LEFT
206 #define SNAKE2_SELECT_TYPE BUTTON_PLAY
207 #define SNAKE2_PLAYPAUSE BUTTON_SELECT
208 #define SNAKE2_PLAYPAUSE_TEXT "Select"
210 #elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
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_PLAY
219 #define SNAKE2_PLAYPAUSE BUTTON_SELECT
220 #define SNAKE2_PLAYPAUSE_TEXT "Select"
222 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
223 #define SNAKE2_UP BUTTON_UP
224 #define SNAKE2_DOWN BUTTON_DOWN
225 #define SNAKE2_QUIT BUTTON_POWER
226 #define SNAKE2_LEVEL_UP BUTTON_UP
227 #define SNAKE2_LEVEL_DOWN BUTTON_DOWN
228 #define SNAKE2_MAZE_NEXT BUTTON_RIGHT
229 #define SNAKE2_MAZE_LAST BUTTON_LEFT
230 #define SNAKE2_SELECT_TYPE BUTTON_MENU
231 #define SNAKE2_PLAYPAUSE BUTTON_SELECT
232 #define SNAKE2_PLAYPAUSE_TEXT "Select"
234 #elif (CONFIG_KEYPAD == SANSA_E200_PAD)
235 #define SNAKE2_UP BUTTON_UP
236 #define SNAKE2_DOWN BUTTON_DOWN
237 #define SNAKE2_QUIT BUTTON_POWER
238 #define SNAKE2_LEVEL_UP BUTTON_UP
239 #define SNAKE2_LEVEL_DOWN BUTTON_DOWN
240 #define SNAKE2_MAZE_NEXT BUTTON_RIGHT
241 #define SNAKE2_MAZE_LAST BUTTON_LEFT
242 #define SNAKE2_SELECT_TYPE BUTTON_REC
243 #define SNAKE2_PLAYPAUSE BUTTON_SELECT
244 #define SNAKE2_PLAYPAUSE_TEXT "Select"
246 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
247 #define SNAKE2_UP BUTTON_SCROLL_UP
248 #define SNAKE2_DOWN BUTTON_SCROLL_DOWN
249 #define SNAKE2_QUIT BUTTON_POWER
250 #define SNAKE2_LEVEL_UP BUTTON_SCROLL_UP
251 #define SNAKE2_LEVEL_DOWN BUTTON_SCROLL_DOWN
252 #define SNAKE2_MAZE_NEXT BUTTON_RIGHT
253 #define SNAKE2_MAZE_LAST BUTTON_LEFT
254 #define SNAKE2_SELECT_TYPE BUTTON_PLAY
255 #define SNAKE2_PLAYPAUSE BUTTON_FF
256 #define SNAKE2_PLAYPAUSE_TEXT "FF"
259 #error "lacks keymapping"
262 static int max_levels
= 0;
263 static char (*level_cache
)[HEIGHT
][WIDTH
];
265 /*Board itself - 2D int array*/
266 static int board
[WIDTH
][HEIGHT
];
268 Buffer for sorting movement (in case user presses two movements during a
271 static int ardirectionbuffer
[2];
272 static unsigned int score
, hiscore
= 0;
275 static int strwdt
,strhgt
; /*used for string width, height for orientation purposes*/
279 static int level
= 4, speed
= 5,dead
= 0, quit
= 0;
280 static int sillydir
= 0, num_levels
= 0;
281 static int level_from_file
= 0;
282 static struct plugin_api
* rb
;
283 static int headx
, heady
, tailx
, taily
, applecountdown
= 5;
284 static int game_type
= 0;
285 static int num_apples_to_get
=1;
286 static int num_apples_to_got
=0;
287 static int game_b_level
=0;
288 static int applecount
=0;
289 static char phscore
[30];
291 #if (LCD_WIDTH >= 160) && (LCD_HEIGHT >= 128)
292 #ifdef HAVE_LCD_COLOR
293 extern const unsigned short snake2_header1
[];
294 extern const unsigned short snake2_header2
[];
295 extern const unsigned short snake2_left
[];
296 extern const unsigned short snake2_right
[];
297 extern const unsigned short snake2_bottom
[];
299 extern const unsigned char snake2_header1
[];
300 extern const unsigned char snake2_header2
[];
301 extern const unsigned char snake2_left
[];
302 extern const unsigned char snake2_right
[];
303 extern const unsigned char snake2_bottom
[];
313 #define EAST_NORTH 32
314 #define EAST_SOUTH 64
315 #define WEST_NORTH 128
316 #define WEST_SOUTH 256
318 #define NORTH_EAST 512
319 #define NORTH_WEST 1024
320 #define SOUTH_EAST 2048
321 #define SOUTH_WEST 4096
323 #define LEVELS_FILE PLUGIN_DIR "/snake2.levels"
324 #define HISCORE_FILE PLUGIN_DIR "/snake2.hs"
326 int load_all_levels(void)
331 char buf
[64]; /* Larger than WIDTH, to allow for whitespace after the
334 /* Init the level_cache pointer and
335 calculate how many levels that will fit */
336 level_cache
= rb
->plugin_get_buffer((size_t *)&size
);
337 max_levels
= size
/ (HEIGHT
*WIDTH
);
342 if ((fd
= rb
->open(LEVELS_FILE
, O_RDONLY
)) < 0)
347 while(rb
->read_line(fd
, buf
, 64))
349 if(rb
->strlen(buf
) == 0) /* Separator? */
352 if(num_levels
> max_levels
)
354 rb
->splash(HZ
, "Too many levels in file");
360 rb
->memcpy(level_cache
[num_levels
][linecnt
], buf
, WIDTH
);
362 if(linecnt
== HEIGHT
)
372 /*Hi-Score reading and writing to file "/.rockbox/snake2.levels" function */
376 unsigned int compare
;
378 /* clear the buffer we're about to load the highscore data into */
379 rb
->memset(phscore
, 0, sizeof(phscore
));
381 fd
= rb
->open(HISCORE_FILE
,O_RDWR
| O_CREAT
);
383 /* highscore used to %d, is now %d\n
384 Deal with no file or bad file */
385 rb
->read(fd
,phscore
, sizeof(phscore
));
387 compare
= rb
->atoi(phscore
);
389 if(hiscore
> compare
){
390 rb
->lseek(fd
,0,SEEK_SET
);
391 rb
->fdprintf(fd
, "%d\n", hiscore
);
401 ** Completely clear the board of walls and/or snake */
403 void clear_board( void)
407 for (x
= 0; x
< WIDTH
; x
++)
409 for (y
= 0; y
< HEIGHT
; y
++)
416 int load_level( int level_number
)
420 for(y
= 0;y
< HEIGHT
;y
++)
422 for(x
= 0;x
< WIDTH
;x
++)
424 switch(level_cache
[level_number
][y
][x
])
444 ** Gets the currently chosen direction from the first place
445 ** in the direction buffer. If there is something in the
446 ** next part of the buffer then that is moved to the first place
448 void get_direction( void )
450 /*if 1st place is empty*/
451 if(ardirectionbuffer
[0] != -1)
453 /*return this direction*/
454 dir
= ardirectionbuffer
[0];
455 ardirectionbuffer
[0]=-1;
456 /*now see if one needs moving:*/
457 if(ardirectionbuffer
[1] != -1)
459 /*there's a move waiting to be done
460 so move it into the space:*/
461 ardirectionbuffer
[0] = ardirectionbuffer
[1];
462 ardirectionbuffer
[1] = -1;
468 ** Sets the direction
470 void set_direction(int newdir
)
472 if(ardirectionbuffer
[0] != newdir
)
474 /*if 1st place is empty*/
475 if(ardirectionbuffer
[0] == -1)
478 ardirectionbuffer
[0] = newdir
;
483 if(ardirectionbuffer
[0] != newdir
) ardirectionbuffer
[1] = newdir
;
486 if(frames
< 0) ardirectionbuffer
[0] = newdir
;
490 void new_level(int level
)
494 ardirectionbuffer
[0] = -1;
495 ardirectionbuffer
[1] = -1;
502 /*Create a small snake to start off with*/
503 board
[headx
][heady
] = dir
;
504 board
[headx
-1][heady
] = dir
;
505 board
[headx
-2][heady
] = dir
;
506 board
[headx
-3][heady
] = dir
;
507 board
[headx
-4][heady
] = dir
;
511 void init_snake(void)
517 new_level(level_from_file
);
521 ** Draws the apple. If it doesn't exist then
522 ** a new one get's created.
524 void draw_apple( void )
528 #if LCD_WIDTH >= 160 && LCD_HEIGHT >= 128
529 char pscore
[5], counter
[4];
531 rb
->lcd_bitmap(snake2_header2
,0,0,BMPWIDTH_snake2_header
, BMPHEIGHT_snake2_header
);
532 rb
->lcd_bitmap(snake2_left
,0,BMPHEIGHT_snake2_header
,BMPWIDTH_snake2_left
, BMPHEIGHT_snake2_left
);
533 rb
->lcd_bitmap(snake2_right
,LCD_WIDTH
-BMPWIDTH_snake2_right
,BMPHEIGHT_snake2_header
,BMPWIDTH_snake2_right
, BMPHEIGHT_snake2_right
);
534 rb
->lcd_bitmap(snake2_bottom
,0,BMPHEIGHT_snake2_header
+BMPHEIGHT_snake2_left
,BMPWIDTH_snake2_bottom
, BMPHEIGHT_snake2_bottom
);
536 rb
->snprintf(counter
,sizeof(counter
),"%d",applecount
);
537 rb
->lcd_getstringsize(counter
,&strwdt
,&strhgt
);
538 rb
->lcd_putsxy(TOP_X3
-strwdt
/2,TOP_Y2
,counter
);
540 rb
->snprintf(pscore
,sizeof(pscore
),"%d",score
);
541 rb
->lcd_getstringsize(pscore
,&strwdt
,&strhgt
);
542 rb
->lcd_putsxy(TOP_X4
-strwdt
/2,TOP_Y2
,pscore
);
549 x
= (rb
->rand() % (WIDTH
-1))+1;
550 y
= (rb
->rand() % (HEIGHT
-1))+1;
551 } while (board
[x
][y
]);
554 applex
= x
;appley
= y
;
556 rb
->lcd_fillrect((CENTER_X
+applex
*MULTIPLIER
)+1,CENTER_Y
+appley
*MULTIPLIER
,MODIFIER_2
,MODIFIER_1
);
557 rb
->lcd_fillrect(CENTER_X
+applex
*MULTIPLIER
,(CENTER_Y
+appley
*MULTIPLIER
)+1,MODIFIER_1
,MODIFIER_2
);
566 void draw_vertical_bit(int x
, int y
)
568 rb
->lcd_fillrect(CENTER_X
+x
*MULTIPLIER
+1,CENTER_Y
+y
*MULTIPLIER
,MODIFIER_2
,MODIFIER_1
);
577 void draw_horizontal_bit(int x
, int y
)
579 rb
->lcd_fillrect(CENTER_X
+x
*MULTIPLIER
,CENTER_Y
+y
*MULTIPLIER
+1,MODIFIER_1
,MODIFIER_2
);
588 void draw_n_to_e_bit(int x
, int y
)
590 rb
->lcd_fillrect(CENTER_X
+x
*MULTIPLIER
+1,CENTER_Y
+y
*MULTIPLIER
+2,MODIFIER_2
,MODIFIER_2
);
591 rb
->lcd_fillrect(CENTER_X
+x
*MULTIPLIER
+2,CENTER_Y
+y
*MULTIPLIER
+1,MODIFIER_2
,MODIFIER_2
);
600 void draw_w_to_s_bit(int x
, int y
)
602 draw_n_to_e_bit(x
,y
);
611 void draw_n_to_w_bit(int x
, int y
)
613 rb
->lcd_fillrect(CENTER_X
+x
*MULTIPLIER
,CENTER_Y
+y
*MULTIPLIER
+1,MODIFIER_2
,MODIFIER_2
);
614 rb
->lcd_fillrect(CENTER_X
+x
*MULTIPLIER
+1,CENTER_Y
+y
*MULTIPLIER
+2,MODIFIER_2
,MODIFIER_2
);
623 void draw_e_to_s_bit(int x
, int y
)
625 draw_n_to_w_bit(x
, y
);
634 void draw_s_to_e_bit(int x
, int y
)
636 rb
->lcd_fillrect(CENTER_X
+x
*MULTIPLIER
+1,CENTER_Y
+y
*MULTIPLIER
,MODIFIER_2
,MODIFIER_2
);
637 rb
->lcd_fillrect(CENTER_X
+x
*MULTIPLIER
+2,CENTER_Y
+y
*MULTIPLIER
+1,MODIFIER_2
,MODIFIER_2
);
646 void draw_w_to_n_bit(int x
, int y
)
648 draw_s_to_e_bit(x
,y
);
657 void draw_e_to_n_bit(int x
, int y
)
659 rb
->lcd_fillrect(CENTER_X
+x
*MULTIPLIER
+1,CENTER_Y
+y
*MULTIPLIER
,MODIFIER_2
,MODIFIER_2
);
660 rb
->lcd_fillrect(CENTER_X
+x
*MULTIPLIER
,CENTER_Y
+y
*MULTIPLIER
+1,MODIFIER_2
,MODIFIER_2
);
669 void draw_s_to_w_bit(int x
, int y
)
671 draw_e_to_n_bit(x
, y
);
675 ** Draws a wall/obsticals
677 void draw_boundary ( void )
681 /*TODO: Load levels from file!*/
683 /*top and bottom line*/
684 for(x
=0; x
< WIDTH
; x
++)
687 board
[x
][HEIGHT
-1] = WEST
;
690 /*left and right lines*/
691 for(y
=0; y
< HEIGHT
; y
++)
694 board
[WIDTH
-1][y
] = SOUTH
;
698 board
[0][0] = NORTH_EAST
;
699 board
[WIDTH
-1][0] = EAST_SOUTH
;
700 board
[0][HEIGHT
-1] = SOUTH_EAST
;
701 board
[WIDTH
-1][HEIGHT
-1] = EAST_NORTH
;
705 ** Redraw the entire board
711 for (x
= 0; x
< WIDTH
; x
++)
713 for (y
= 0; y
< HEIGHT
; y
++)
718 rb
->lcd_fillrect((CENTER_X
+x
*MULTIPLIER
)+1,CENTER_Y
+y
*MULTIPLIER
,MODIFIER_2
,MODIFIER_1
);
719 rb
->lcd_fillrect(CENTER_X
+x
*MULTIPLIER
,(CENTER_Y
+y
*MULTIPLIER
)+1,MODIFIER_1
,MODIFIER_2
);
726 draw_vertical_bit(x
,y
);
731 draw_horizontal_bit(x
,y
);
735 rb
->lcd_fillrect(CENTER_X
+x
*MULTIPLIER
,CENTER_Y
+y
*MULTIPLIER
,MODIFIER_1
,MODIFIER_1
);
743 ** Draws the snake bit described by nCurrentBit at position x/y
744 ** deciding whether it's a corner bit by examing the nPrevious bit
746 void draw_snake_bit(int currentbit
, int previousbit
, int x
, int y
)
748 rb
->lcd_set_drawmode(DRMODE_SOLID
|DRMODE_INVERSEVID
);
749 rb
->lcd_fillrect(CENTER_X
+x
*MULTIPLIER
,CENTER_Y
+y
*MULTIPLIER
,MODIFIER_1
,MODIFIER_1
);
750 rb
->lcd_set_drawmode(DRMODE_SOLID
);
759 draw_vertical_bit(x
,y
);
763 draw_e_to_n_bit(x
,y
);
767 draw_w_to_n_bit(x
,y
);
777 draw_horizontal_bit(x
,y
);
781 draw_n_to_e_bit(x
,y
);
785 draw_s_to_e_bit(x
,y
);
795 draw_vertical_bit(x
,y
);
799 draw_e_to_s_bit(x
,y
);
803 draw_w_to_s_bit(x
,y
);
813 draw_horizontal_bit(x
,y
);
817 draw_s_to_w_bit(x
,y
);
821 draw_n_to_w_bit(x
,y
);
829 ** Death 'sequence' and end game stuff.
837 rb
->splash(HZ
*2, "Oops!");
839 rb
->lcd_clear_display();
843 rb
->lcd_getstringsize("You died!",&strwdt
,&strhgt
);
844 rb
->lcd_putsxy((LCD_WIDTH
- strwdt
)/2,strhgt
,"You died!");
846 rb
->snprintf(pscore
,sizeof(pscore
),"Your score: %d",score
);
847 rb
->lcd_getstringsize(pscore
,&strwdt
,&strhgt
);
848 rb
->lcd_putsxy((LCD_WIDTH
- strwdt
)/2,strhgt
* 2 + 2,pscore
);
853 rb
->lcd_getstringsize("New high score!",&strwdt
,&strhgt
);
854 rb
->lcd_putsxy((LCD_WIDTH
- strwdt
)/2,strhgt
* 4 + 2,"New high score!");
858 rb
->snprintf(phscore
,sizeof(phscore
),"High score: %d",hiscore
);
859 rb
->lcd_getstringsize(phscore
,&strwdt
,&strhgt
);
860 rb
->lcd_putsxy((LCD_WIDTH
- strwdt
)/2,strhgt
* 5,phscore
);
863 rb
->snprintf(phscore
,sizeof(phscore
),"Press %s...",SNAKE2_PLAYPAUSE_TEXT
);
864 rb
->lcd_getstringsize(phscore
,&strwdt
,&strhgt
);
865 rb
->lcd_putsxy((LCD_WIDTH
- strwdt
)/2,strhgt
* 7,phscore
);
871 button
=rb
->button_get(true);
874 case SNAKE2_PLAYPAUSE
:
884 ** Check for collision. TODO: Currently this
885 ** sets of the death sequence. What we want is it to only return a true/false
886 ** depending on whether a collision occured.
888 void collision ( int x
, int y
)
899 score
= score
+ (1 * level
);
906 if(num_apples_to_get
== num_apples_to_got
)
909 if(level_from_file
>= num_levels
)
912 /*and increase the number of apples to pick up
913 before level changes*/
914 num_apples_to_get
+=2;
917 rb
->splash(HZ
, "Level Completed!");
918 rb
->lcd_clear_display();
919 new_level(level_from_file
);
920 rb
->lcd_clear_display();
944 /*this actually sets the dir variable.*/
950 board
[headx
][heady
]=NORTH
;
954 board
[headx
][heady
]=EAST
;
958 board
[headx
][heady
]=SOUTH
;
962 board
[headx
][heady
]=WEST
;
977 rb
->lcd_fillrect(CENTER_X
+headx
*MULTIPLIER
,CENTER_Y
+heady
*MULTIPLIER
,MODIFIER_1
,MODIFIER_1
);
980 if(applecountdown
<= 0)
982 rb
->lcd_set_drawmode(DRMODE_SOLID
|DRMODE_INVERSEVID
);
983 rb
->lcd_fillrect(CENTER_X
+tailx
*MULTIPLIER
,CENTER_Y
+taily
*MULTIPLIER
,MODIFIER_1
,MODIFIER_1
);
984 rb
->lcd_set_drawmode(DRMODE_SOLID
);
986 taildir
= board
[tailx
][taily
];
987 board
[tailx
][taily
] = 0;
1024 int olddir
, noldx
, noldy
, temp
;
1031 if(heady
== HEIGHT
-1)
1036 olddir
= board
[headx
][temp
];
1045 olddir
= board
[temp
][heady
];
1054 olddir
= board
[headx
][temp
];
1058 if(headx
== WIDTH
-1)
1063 olddir
= board
[temp
][heady
];
1070 now redraw the bit that was
1071 the tail, to something snake-like:
1073 draw_snake_bit(dir
, olddir
, noldx
, noldy
);
1075 collision(headx
, heady
);
1080 void game_pause (void)
1084 rb
->lcd_clear_display();
1085 rb
->lcd_getstringsize("Paused",&strwdt
,&strhgt
);
1086 rb
->lcd_putsxy((LCD_WIDTH
- strwdt
)/2,LCD_HEIGHT
/2,"Paused");
1091 button
= rb
->button_get(true);
1094 case SNAKE2_PLAYPAUSE
:
1095 rb
->lcd_clear_display();
1101 #ifdef SNAKE2_RC_QUIT
1102 case SNAKE2_RC_QUIT
:
1110 if (rb
->default_event_handler(button
)==SYS_USB_CONNECTED
) {
1124 rb
->lcd_clear_display();
1133 if(frames
>0) frames
=0;
1147 /*it has, great set frames to a positive value again:*/
1157 rb
->sleep(HZ
/speed
);
1159 button
= rb
->button_get(false);
1161 #ifdef HAS_BUTTON_HOLD
1162 if (rb
->button_hold())
1163 button
= SNAKE2_PLAYPAUSE
;
1169 case SNAKE2_UP
| BUTTON_REPEAT
:
1170 if (dir
!= SOUTH
) set_direction(NORTH
);
1174 case BUTTON_RIGHT
| BUTTON_REPEAT
:
1175 if (dir
!= WEST
) set_direction(EAST
);
1179 case SNAKE2_DOWN
| BUTTON_REPEAT
:
1180 if (dir
!= NORTH
) set_direction(SOUTH
);
1184 case BUTTON_LEFT
| BUTTON_REPEAT
:
1185 if (dir
!= EAST
) set_direction(WEST
);
1188 #ifdef SNAKE2_RC_QUIT
1189 case SNAKE2_RC_QUIT
:
1195 case SNAKE2_PLAYPAUSE
:
1200 if (rb
->default_event_handler(button
)==SYS_USB_CONNECTED
) {
1210 void game_init(void)
1221 load_level( level_from_file
);
1222 rb
->lcd_clear_display();
1228 #if LCD_WIDTH >= 160 && LCD_HEIGHT >= 128
1230 rb
->lcd_bitmap(snake2_header1
,0,0,BMPWIDTH_snake2_header
, BMPHEIGHT_snake2_header
);
1231 rb
->lcd_bitmap(snake2_left
,0,BMPHEIGHT_snake2_header
,BMPWIDTH_snake2_left
, BMPHEIGHT_snake2_left
);
1232 rb
->lcd_bitmap(snake2_right
,LCD_WIDTH
-BMPWIDTH_snake2_right
,BMPHEIGHT_snake2_header
,BMPWIDTH_snake2_right
, BMPHEIGHT_snake2_right
);
1233 rb
->lcd_bitmap(snake2_bottom
,0,BMPHEIGHT_snake2_header
+BMPHEIGHT_snake2_left
,BMPWIDTH_snake2_bottom
, BMPHEIGHT_snake2_bottom
);
1235 rb
->snprintf(plevel
,sizeof(plevel
),"%d",level
);
1236 rb
->lcd_getstringsize(plevel
,&strwdt
,&strhgt
);
1237 rb
->lcd_putsxy(TOP_X3
-strwdt
/2,TOP_Y2
, plevel
);
1239 rb
->snprintf(plevel
,sizeof(plevel
),"%d",level_from_file
);
1240 rb
->lcd_getstringsize(plevel
,&strwdt
,&strhgt
);
1241 rb
->lcd_putsxy(TOP_X2
-strwdt
/2,TOP_Y1
, plevel
);
1244 rb
->lcd_getstringsize("A",&strwdt
,&strhgt
);
1245 rb
->lcd_putsxy(TOP_X1
,TOP_Y1
,"A");
1248 rb
->lcd_getstringsize("B",&strwdt
,&strhgt
);
1249 rb
->lcd_putsxy(TOP_X1
,TOP_Y1
,"B");
1252 rb
->snprintf(phscore
,sizeof(phscore
),"%d",hiscore
);
1253 rb
->lcd_getstringsize(phscore
,&strwdt
,&strhgt
);
1254 rb
->lcd_putsxy(TOP_X4
-strwdt
/2,TOP_Y2
, phscore
);
1257 rb
->snprintf(plevel
,sizeof(plevel
),"Speed: %02d",level
);
1258 rb
->lcd_getstringsize("Speed: 00",&strwdt
,&strhgt
);
1259 rb
->lcd_putsxy((LCD_WIDTH
- strwdt
)/2,strhgt
+4, plevel
);
1261 rb
->snprintf(plevel
,sizeof(plevel
),"Maze: %d",level_from_file
);
1262 rb
->lcd_getstringsize(plevel
,&strwdt
,&strhgt
);
1263 rb
->lcd_putsxy((LCD_WIDTH
- strwdt
)/2,strhgt
*2+4, plevel
);
1266 rb
->lcd_getstringsize("Game Type: A ",&strwdt
,&strhgt
);
1267 rb
->lcd_putsxy((LCD_WIDTH
- strwdt
)/2,strhgt
*3+4,"Game Type: A");
1270 rb
->lcd_getstringsize("Game Type: B ",&strwdt
,&strhgt
);
1271 rb
->lcd_putsxy((LCD_WIDTH
- strwdt
)/2,strhgt
*3+4,"Game Type: B");
1274 rb
->snprintf(phscore
,sizeof(phscore
),"Hi Score: %d",hiscore
);
1275 rb
->lcd_getstringsize(phscore
,&strwdt
,&strhgt
);
1276 rb
->lcd_putsxy((LCD_WIDTH
- strwdt
)/2,strhgt
*4+4, phscore
);
1281 button
=rb
->button_get(true);
1284 case SNAKE2_LEVEL_UP
:
1285 case SNAKE2_LEVEL_UP
|BUTTON_REPEAT
:
1289 case SNAKE2_LEVEL_DOWN
:
1290 case SNAKE2_LEVEL_DOWN
|BUTTON_REPEAT
:
1298 case SNAKE2_PLAYPAUSE
:
1302 case SNAKE2_SELECT_TYPE
:
1303 if(game_type
==0)game_type
=1; else game_type
=0;
1305 case SNAKE2_MAZE_NEXT
:
1306 rb
->lcd_set_drawmode(DRMODE_BG
|DRMODE_INVERSEVID
);
1307 rb
->lcd_fillrect(CENTER_X
, CENTER_Y
, CENTER_X
+WIDTH
*MULTIPLIER
,
1308 CENTER_Y
+HEIGHT
*MULTIPLIER
);
1309 rb
->lcd_set_drawmode(DRMODE_SOLID
);
1310 if(level_from_file
< num_levels
)
1313 level_from_file
= 0;
1314 load_level( level_from_file
);
1317 #ifdef SNAKE2_MAZE_LAST
1318 case SNAKE2_MAZE_LAST
:
1319 rb
->lcd_set_drawmode(DRMODE_BG
|DRMODE_INVERSEVID
);
1320 rb
->lcd_fillrect(CENTER_X
, CENTER_Y
, CENTER_X
+WIDTH
*MULTIPLIER
,
1321 CENTER_Y
+HEIGHT
*MULTIPLIER
);
1322 rb
->lcd_set_drawmode(DRMODE_SOLID
);
1323 if(level_from_file
> 0)
1326 level_from_file
= num_levels
;
1327 load_level( level_from_file
);
1332 if (rb
->default_event_handler(button
)==SYS_USB_CONNECTED
) {
1342 enum plugin_status
plugin_start(struct plugin_api
* api
, void* parameter
)
1347 /* Lets use the default font */
1348 rb
->lcd_setfont(FONT_SYSFIXED
);
1350 rb
->lcd_set_backdrop(NULL
);
1352 #ifdef HAVE_LCD_COLOR
1353 rb
->lcd_set_foreground(LCD_BLACK
);
1354 rb
->lcd_set_background(LCD_WHITE
);
1359 if (num_levels
== 0) {
1360 rb
->splash(HZ
*2, "Failed loading levels!");
1369 rb
->lcd_clear_display();
1382 return (quit
==1) ? PLUGIN_OK
: PLUGIN_USB_CONNECTED
;