diff options
author | Björn Stenberg <bjorn@haxx.se> | 2003-06-29 21:10:27 +0000 |
---|---|---|
committer | Björn Stenberg <bjorn@haxx.se> | 2003-06-29 21:10:27 +0000 |
commit | 020ab8f01ee369a1955d891e500edfbf22219b49 (patch) | |
tree | c281b05ca65833499b3fa0ce86bb182ea5b690f4 /apps/plugins/star.c | |
parent | 51119303bbf2534b830ed56d1972ac04dac634e4 (diff) | |
download | rockbox-020ab8f01ee369a1955d891e500edfbf22219b49.tar.gz rockbox-020ab8f01ee369a1955d891e500edfbf22219b49.zip |
Frederic Dang Ngoc's 'Star' game. Very nice graphic effects.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@3777 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/star.c')
-rw-r--r-- | apps/plugins/star.c | 786 |
1 files changed, 786 insertions, 0 deletions
diff --git a/apps/plugins/star.c b/apps/plugins/star.c new file mode 100644 index 0000000000..961c17f143 --- /dev/null +++ b/apps/plugins/star.c | |||
@@ -0,0 +1,786 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 Frederic Dang Ngoc | ||
11 | * | ||
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. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include "plugin.h" | ||
20 | #ifdef HAVE_LCD_BITMAP | ||
21 | |||
22 | /* file which contains the levels */ | ||
23 | #define STAR_LEVELS_FILE "/.rockbox/star/levels.txt" | ||
24 | |||
25 | /* title of the game */ | ||
26 | #define STAR_TITLE "Star" | ||
27 | |||
28 | /* font used to display title */ | ||
29 | #define STAR_TITLE_FONT 2 | ||
30 | |||
31 | /* size of a level in file */ | ||
32 | #define STAR_LEVEL_SIZE ((STAR_WIDTH + 1) * STAR_HEIGHT + 1) | ||
33 | |||
34 | /* size of the game board */ | ||
35 | #define STAR_WIDTH 16 | ||
36 | #define STAR_HEIGHT 9 | ||
37 | |||
38 | /* left and top margin */ | ||
39 | #define STAR_OFFSET_X 8 | ||
40 | #define STAR_OFFSET_Y 0 | ||
41 | |||
42 | /* number of level */ | ||
43 | #define STAR_LEVEL_COUNT 20 | ||
44 | |||
45 | /* size of a tile */ | ||
46 | #define STAR_TILE_SIZE 6 | ||
47 | |||
48 | /* values of object in the board */ | ||
49 | #define STAR_VOID '.' | ||
50 | #define STAR_WALL '*' | ||
51 | #define STAR_STAR 'o' | ||
52 | #define STAR_BALL 'X' | ||
53 | #define STAR_BLOCK 'x' | ||
54 | |||
55 | /* sleep time between two frames */ | ||
56 | #define STAR_SLEEP 1 | ||
57 | |||
58 | /* value of ball and block control */ | ||
59 | #define STAR_CONTROL_BALL 0 | ||
60 | #define STAR_CONTROL_BLOCK 1 | ||
61 | |||
62 | /* position of the ball */ | ||
63 | static int ball_x, ball_y; | ||
64 | |||
65 | /* position of the block */ | ||
66 | static int block_x, block_y; | ||
67 | |||
68 | /* number of stars to get to finish the level */ | ||
69 | static int star_count; | ||
70 | |||
71 | /* the object we control : ball or block */ | ||
72 | static int control; | ||
73 | |||
74 | /* the current board */ | ||
75 | static char board[STAR_HEIGHT][STAR_WIDTH]; | ||
76 | |||
77 | /* bitmap of the wall */ | ||
78 | static unsigned char wall_bmp[STAR_TILE_SIZE] | ||
79 | = {0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55}; | ||
80 | |||
81 | /* bitmap of the star */ | ||
82 | static unsigned char star_bmp[STAR_TILE_SIZE] | ||
83 | = {0x00, 0x0c, 0x12, 0x12, 0x0c, 0x00}; | ||
84 | |||
85 | /* bitmap of the ball */ | ||
86 | static unsigned char ball_bmp[STAR_TILE_SIZE] | ||
87 | = {0x00, 0x0c, 0x1e, 0x1a, 0x0c, 0x00}; | ||
88 | |||
89 | /* bitmap of the block */ | ||
90 | static unsigned char block_bmp[STAR_TILE_SIZE] | ||
91 | = {0x00, 0x1e, 0x1e, 0x1e, 0x1e, 0x00}; | ||
92 | |||
93 | /* bitmap of the arrow animation */ | ||
94 | static unsigned char arrow_bmp[4][7] = | ||
95 | { | ||
96 | {0x7f, 0x7f, 0x3e, 0x3e, 0x1c, 0x1c, 0x08}, | ||
97 | {0x3e, 0x3e, 0x1c, 0x1c, 0x08, 0x08, 0x08}, | ||
98 | {0x1c, 0x1c, 0x1c, 0x1c, 0x08, 0x08, 0x08}, | ||
99 | {0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08} | ||
100 | }; | ||
101 | |||
102 | /* sequence of the bitmap arrow to follow to do one turn */ | ||
103 | static unsigned char anim_arrow[8] = {0, 1, 2, 3, 2, 1, 0}; | ||
104 | |||
105 | /* current_level */ | ||
106 | static int current_level = 0; | ||
107 | |||
108 | /* char font size */ | ||
109 | static int char_width = -1; | ||
110 | static int char_height = -1; | ||
111 | |||
112 | static struct plugin_api* rb; | ||
113 | |||
114 | /* this arrays contains a group of levels loaded into memory */ | ||
115 | static unsigned char* levels = | ||
116 | "****************\n" | ||
117 | "*X**........o*x*\n" | ||
118 | "*..........o.***\n" | ||
119 | "*.......**o....*\n" | ||
120 | "*...**.o......**\n" | ||
121 | "**.o..o.....o..*\n" | ||
122 | "*.o......o**.o.*\n" | ||
123 | "*.....**o.....o*\n" | ||
124 | "****************\n" | ||
125 | "\n" | ||
126 | ".*..*.*.*...*.**\n" | ||
127 | "*...o.........X*\n" | ||
128 | "...*o..*o...o...\n" | ||
129 | "*.*.o.....o..*.*\n" | ||
130 | "......*...o...*.\n" | ||
131 | "*....*x*..o....*\n" | ||
132 | "...*..*.*...*oo*\n" | ||
133 | "*.............*.\n" | ||
134 | ".*..*........*..\n" | ||
135 | "\n" | ||
136 | "****************\n" | ||
137 | "*...........o*x*\n" | ||
138 | "*...**......**X*\n" | ||
139 | "*...*o.........*\n" | ||
140 | "*.o.....o**...o*\n" | ||
141 | "*.*o..o..o*..o**\n" | ||
142 | "*.**o.*o..o.o***\n" | ||
143 | "*o....**o......*\n" | ||
144 | "****************\n" | ||
145 | "\n" | ||
146 | "****************\n" | ||
147 | "*............*x*\n" | ||
148 | "*.....*........*\n" | ||
149 | "**o*o.o*o*o*o*o*\n" | ||
150 | "*.*.*o.o*.*.*.**\n" | ||
151 | "**o*o*o.o*o*o*o*\n" | ||
152 | "*.....*........*\n" | ||
153 | "*...*.......*X.*\n" | ||
154 | "****************\n" | ||
155 | "\n" | ||
156 | ".**************.\n" | ||
157 | "*X..*...*..*...*\n" | ||
158 | "*..*o.*.o..o.*.*\n" | ||
159 | "**......*..*...*\n" | ||
160 | "*o.*o*........**\n" | ||
161 | "**.....*.o.*...*\n" | ||
162 | "*o*..*.*.*...*x*\n" | ||
163 | "*...*....o*..*o*\n" | ||
164 | ".**************.\n" | ||
165 | "\n" | ||
166 | "....************\n" | ||
167 | "...*...o...*o.o*\n" | ||
168 | "..*....o....*.**\n" | ||
169 | ".*.....o.......*\n" | ||
170 | "*X.....o.......*\n" | ||
171 | "**.....o..*...**\n" | ||
172 | "*......o....*..*\n" | ||
173 | "*x.*...o..**o..*\n" | ||
174 | "****************\n" | ||
175 | "\n" | ||
176 | "****************\n" | ||
177 | "*..............*\n" | ||
178 | ".**.***..*o.**o*\n" | ||
179 | ".*o..*o.*.*.*.*.\n" | ||
180 | "..*..*..***.**..\n" | ||
181 | ".**..*..*o*.*o**\n" | ||
182 | "*..............*\n" | ||
183 | "*..X*o....x..*o*\n" | ||
184 | "****************\n" | ||
185 | "\n" | ||
186 | "***************.\n" | ||
187 | "*..o**.........*\n" | ||
188 | "*..*o..**.o....*\n" | ||
189 | "*..o**.*.*o....*\n" | ||
190 | "**.....**..*o*.*\n" | ||
191 | "**.*.......o*o.*\n" | ||
192 | "*oxo*...o..*X*.*\n" | ||
193 | "**.............*\n" | ||
194 | ".***************\n" | ||
195 | "\n" | ||
196 | "..*.***********.\n" | ||
197 | ".*o*o......*..X*\n" | ||
198 | "*o.o*....o....*.\n" | ||
199 | ".*.*..o**..o*..*\n" | ||
200 | "*..*o.*oxo....o*\n" | ||
201 | "*.....o**.....*.\n" | ||
202 | "*o*o.........*..\n" | ||
203 | "*...........*...\n" | ||
204 | ".***********....\n" | ||
205 | "\n" | ||
206 | "....***********.\n" | ||
207 | "*****.o........*\n" | ||
208 | "*...x.***o.o*.o*\n" | ||
209 | "*.o...*o.*o...*.\n" | ||
210 | "*.....*..o..*.o*\n" | ||
211 | "*o*o..*.o*..*X*.\n" | ||
212 | ".*o...***..***..\n" | ||
213 | "*.........*.*.*.\n" | ||
214 | ".*********..*..*\n" | ||
215 | "\n" | ||
216 | "****************\n" | ||
217 | "*......*......X*\n" | ||
218 | "*..*oo.....oo.**\n" | ||
219 | "**...o...**...o*\n" | ||
220 | "*o....*o*oo..***\n" | ||
221 | "**.**....**....*\n" | ||
222 | "*o..o*.o....x.o*\n" | ||
223 | "**o***....*...**\n" | ||
224 | "***************.\n" | ||
225 | "\n" | ||
226 | "**.....**..****.\n" | ||
227 | "*X*****o.***.o**\n" | ||
228 | "*....oo.....o..*\n" | ||
229 | "*.**..**o..*o*.*\n" | ||
230 | "*.*.o.*.*o.**..*\n" | ||
231 | "*.**..**...*x*.*\n" | ||
232 | "*.....o........*\n" | ||
233 | "*........o.....*\n" | ||
234 | "****************\n" | ||
235 | "\n" | ||
236 | ".**************.\n" | ||
237 | "*.X*........o.**\n" | ||
238 | "*.*...*o...o**.*\n" | ||
239 | "*.......o....*.*\n" | ||
240 | "*.o..........*o*\n" | ||
241 | "*.*......o.....*\n" | ||
242 | "**......o.o..*o*\n" | ||
243 | "*x..*....o.*.*.*\n" | ||
244 | ".**************.\n" | ||
245 | "\n" | ||
246 | "****************\n" | ||
247 | "*o*o........o*o*\n" | ||
248 | "*.o*X......**..*\n" | ||
249 | "*.x........o...*\n" | ||
250 | "*........o*....*\n" | ||
251 | "*......o.......*\n" | ||
252 | "*.o*........*..*\n" | ||
253 | "*o*o........o*o*\n" | ||
254 | "****************\n" | ||
255 | "\n" | ||
256 | ".******.********\n" | ||
257 | "*.....o*.....o.*\n" | ||
258 | "*.*.o.*..*...o.*\n" | ||
259 | "*..X*...*oo.*o.*\n" | ||
260 | ".*.*...*.o..x*.*\n" | ||
261 | "*o.......*..*o.*\n" | ||
262 | ".*......o.....*.\n" | ||
263 | "*o............o*\n" | ||
264 | "****************\n" | ||
265 | "\n" | ||
266 | "****************\n" | ||
267 | "**.x*o.o......o*\n" | ||
268 | "*o.Xo*o.......**\n" | ||
269 | "**.***........**\n" | ||
270 | "**.....o*o*....*\n" | ||
271 | "*oo.......o*o..*\n" | ||
272 | "**.o....****o..*\n" | ||
273 | "**o*..*........*\n" | ||
274 | "****************\n" | ||
275 | "\n" | ||
276 | "****************\n" | ||
277 | "*.o*........*X.*\n" | ||
278 | "*.*..o*oo*o..*.*\n" | ||
279 | "*....*o**o*.o..*\n" | ||
280 | "*.o*.......o*..*\n" | ||
281 | "*..o*o....o*...*\n" | ||
282 | "*.*..*.**o*..*.*\n" | ||
283 | "*....o.*o...x..*\n" | ||
284 | "****************\n" | ||
285 | "\n" | ||
286 | "****************\n" | ||
287 | "*.o....o..x*...*\n" | ||
288 | "*..*o*o...*o...*\n" | ||
289 | "*...*o*....*o..*\n" | ||
290 | "*...o..*...o*o.*\n" | ||
291 | "*.*o*...*.o*...*\n" | ||
292 | "*.o*o.*.o.*....*\n" | ||
293 | "*o*X..*.....*..*\n" | ||
294 | "****************\n" | ||
295 | "\n" | ||
296 | "****************\n" | ||
297 | "*o...**.....**o*\n" | ||
298 | "*.*..*......*o.*\n" | ||
299 | "*.o*...o**..o..*\n" | ||
300 | "*.*....*o......*\n" | ||
301 | "*....*...o*....*\n" | ||
302 | "*.**.o*.**o..*x*\n" | ||
303 | "*.o*.*o.....**X*\n" | ||
304 | "****************\n" | ||
305 | "\n" | ||
306 | "****************\n" | ||
307 | "*...o*o........*\n" | ||
308 | "**o..o*.**o...**\n" | ||
309 | "*.*.*.o...*..*.*\n" | ||
310 | "*.x.*..**..*.Xo*\n" | ||
311 | "*.*..*...o.*.*.*\n" | ||
312 | "**...o**.*o..o**\n" | ||
313 | "*........o*o...*\n" | ||
314 | "****************"; | ||
315 | |||
316 | /** | ||
317 | * Display text. | ||
318 | */ | ||
319 | static void star_display_text(char *str, bool waitkey) | ||
320 | { | ||
321 | int chars_by_line; | ||
322 | int lines_by_screen; | ||
323 | int chars_for_line; | ||
324 | int current_line = 0; | ||
325 | int first_char_index = 0; | ||
326 | char *ptr_char; | ||
327 | char *ptr_line; | ||
328 | int i; | ||
329 | char line[255]; | ||
330 | int key; | ||
331 | |||
332 | rb->lcd_clear_display(); | ||
333 | |||
334 | chars_by_line = LCD_WIDTH / char_width; | ||
335 | lines_by_screen = LCD_HEIGHT / char_height; | ||
336 | |||
337 | do | ||
338 | { | ||
339 | ptr_char = str + first_char_index; | ||
340 | chars_for_line = 0; | ||
341 | i = 0; | ||
342 | ptr_line = line; | ||
343 | while (i < chars_by_line) | ||
344 | { | ||
345 | switch (*ptr_char) | ||
346 | { | ||
347 | case '\t': | ||
348 | case ' ': | ||
349 | *(ptr_line++) = ' '; | ||
350 | case '\n': | ||
351 | case '\0': | ||
352 | chars_for_line = i; | ||
353 | break; | ||
354 | |||
355 | default: | ||
356 | *(ptr_line++) = *ptr_char; | ||
357 | } | ||
358 | if (*ptr_char == '\n' || *ptr_char == '\0') | ||
359 | break; | ||
360 | ptr_char++; | ||
361 | i++; | ||
362 | } | ||
363 | |||
364 | if (chars_for_line == 0) | ||
365 | chars_for_line = i; | ||
366 | |||
367 | line[chars_for_line] = '\0'; | ||
368 | |||
369 | // test if we have cutted a word. If it is the case we don't have to | ||
370 | // skip the space | ||
371 | if (i == chars_by_line && chars_for_line == chars_by_line) | ||
372 | first_char_index += chars_for_line; | ||
373 | else | ||
374 | first_char_index += chars_for_line + 1; | ||
375 | |||
376 | // print the line on the screen | ||
377 | rb->lcd_putsxy(0, current_line * char_height, line); | ||
378 | |||
379 | // if the number of line showed on the screen is equals to the | ||
380 | // maximum number of line we can show, we wait for a key pressed to | ||
381 | // clear and show the remaining text. | ||
382 | current_line++; | ||
383 | if (current_line == lines_by_screen || *ptr_char == '\0') | ||
384 | { | ||
385 | current_line = 0; | ||
386 | rb->lcd_update(); | ||
387 | if (waitkey) | ||
388 | while ((key = rb->button_get(true)) != BUTTON_PLAY | ||
389 | && key != BUTTON_ON | ||
390 | && key != BUTTON_DOWN); | ||
391 | rb->lcd_clear_display(); | ||
392 | } | ||
393 | } while (*ptr_char != '\0'); | ||
394 | } | ||
395 | |||
396 | /** | ||
397 | * Do a pretty transition from one level to another. | ||
398 | */ | ||
399 | static void star_transition_update(void) | ||
400 | { | ||
401 | int center_x = LCD_WIDTH / 2; | ||
402 | int lcd_demi_width = LCD_WIDTH / 2; | ||
403 | int center_y = LCD_HEIGHT / 2; | ||
404 | int x; | ||
405 | int y = 0; | ||
406 | int var_y = 0; | ||
407 | |||
408 | for (x = 0 ; x < lcd_demi_width ; x++) | ||
409 | { | ||
410 | var_y += LCD_HEIGHT; | ||
411 | if (var_y > LCD_WIDTH) | ||
412 | { | ||
413 | var_y -= LCD_WIDTH; | ||
414 | y++; | ||
415 | } | ||
416 | rb->lcd_update_rect(center_x - x, center_y - y, | ||
417 | x * 2, y * 2); | ||
418 | rb->sleep(STAR_SLEEP); | ||
419 | } | ||
420 | rb->lcd_update(); | ||
421 | } | ||
422 | |||
423 | /** | ||
424 | * Display information board of the current level. | ||
425 | */ | ||
426 | static void star_display_board_info(void) | ||
427 | { | ||
428 | int label_offset_y = label_offset_y = LCD_HEIGHT - char_height; | ||
429 | char str_info[32]; | ||
430 | |||
431 | rb->snprintf(str_info, sizeof(str_info), "L:%02d S:%02d C:", | ||
432 | current_level, star_count); | ||
433 | rb->lcd_putsxy(0, label_offset_y, str_info); | ||
434 | |||
435 | if (control == STAR_CONTROL_BALL) | ||
436 | rb->lcd_bitmap (ball_bmp, 103, label_offset_y + 1, STAR_TILE_SIZE, | ||
437 | STAR_TILE_SIZE, true); | ||
438 | else | ||
439 | rb->lcd_bitmap (block_bmp, 103, label_offset_y + 1, STAR_TILE_SIZE, | ||
440 | STAR_TILE_SIZE, true); | ||
441 | |||
442 | rb->lcd_update_rect(0, label_offset_y, LCD_WIDTH, char_height); | ||
443 | } | ||
444 | |||
445 | |||
446 | /** | ||
447 | * Load a level into board array. | ||
448 | */ | ||
449 | static int star_load_level(int current_level) | ||
450 | { | ||
451 | int x, y; | ||
452 | char *ptr_tab; | ||
453 | |||
454 | ptr_tab = levels + current_level * STAR_LEVEL_SIZE; | ||
455 | control = STAR_CONTROL_BALL; | ||
456 | star_count = 0; | ||
457 | |||
458 | rb->lcd_clear_display(); | ||
459 | |||
460 | for (y = 0 ; y < STAR_HEIGHT ; y++) | ||
461 | { | ||
462 | for (x = 0 ; x < STAR_WIDTH ; x++) | ||
463 | { | ||
464 | board[y][x] = *ptr_tab; | ||
465 | switch (*ptr_tab) | ||
466 | { | ||
467 | case STAR_VOID: | ||
468 | break; | ||
469 | |||
470 | case STAR_WALL: | ||
471 | rb->lcd_bitmap (wall_bmp, | ||
472 | STAR_OFFSET_X + x * STAR_TILE_SIZE, | ||
473 | STAR_OFFSET_Y + y * STAR_TILE_SIZE, | ||
474 | STAR_TILE_SIZE, STAR_TILE_SIZE, false); | ||
475 | break; | ||
476 | |||
477 | case STAR_STAR: | ||
478 | rb->lcd_bitmap (star_bmp, | ||
479 | STAR_OFFSET_X + x * STAR_TILE_SIZE, | ||
480 | STAR_OFFSET_Y + y * STAR_TILE_SIZE, | ||
481 | STAR_TILE_SIZE, STAR_TILE_SIZE, false); | ||
482 | star_count++; | ||
483 | break; | ||
484 | |||
485 | case STAR_BALL: | ||
486 | ball_x = x; | ||
487 | ball_y = y; | ||
488 | rb->lcd_bitmap (ball_bmp, | ||
489 | STAR_OFFSET_X + x * STAR_TILE_SIZE, | ||
490 | STAR_OFFSET_Y + y * STAR_TILE_SIZE, | ||
491 | STAR_TILE_SIZE, STAR_TILE_SIZE, false); | ||
492 | break; | ||
493 | |||
494 | |||
495 | case STAR_BLOCK: | ||
496 | block_x = x; | ||
497 | block_y = y; | ||
498 | rb->lcd_bitmap (block_bmp, | ||
499 | STAR_OFFSET_X + x * STAR_TILE_SIZE, | ||
500 | STAR_OFFSET_Y + y * STAR_TILE_SIZE, | ||
501 | STAR_TILE_SIZE, STAR_TILE_SIZE, false); | ||
502 | break; | ||
503 | } | ||
504 | ptr_tab++; | ||
505 | } | ||
506 | ptr_tab++; | ||
507 | } | ||
508 | star_display_board_info(); | ||
509 | star_transition_update(); | ||
510 | return 1; | ||
511 | } | ||
512 | |||
513 | /** | ||
514 | * Run the game. | ||
515 | */ | ||
516 | static int star_run_game(void) | ||
517 | { | ||
518 | int move_x = 0; | ||
519 | int move_y = 0; | ||
520 | int i; | ||
521 | |||
522 | int label_offset_y; | ||
523 | |||
524 | label_offset_y = LCD_HEIGHT - char_height; | ||
525 | |||
526 | if (!star_load_level(current_level)) | ||
527 | return 0; | ||
528 | |||
529 | while (true) | ||
530 | { | ||
531 | move_x = 0; | ||
532 | move_y = 0; | ||
533 | |||
534 | switch (rb->button_get(true)) | ||
535 | { | ||
536 | case BUTTON_OFF: | ||
537 | return PLUGIN_OK; | ||
538 | |||
539 | case BUTTON_LEFT: | ||
540 | move_x = -1; | ||
541 | break; | ||
542 | |||
543 | case BUTTON_RIGHT: | ||
544 | move_x = 1; | ||
545 | break; | ||
546 | |||
547 | case BUTTON_UP: | ||
548 | move_y = -1; | ||
549 | break; | ||
550 | |||
551 | case BUTTON_DOWN: | ||
552 | move_y = 1; | ||
553 | break; | ||
554 | |||
555 | case BUTTON_F1: | ||
556 | if (current_level > 0) | ||
557 | { | ||
558 | current_level--; | ||
559 | star_load_level(current_level); | ||
560 | } | ||
561 | continue; | ||
562 | |||
563 | case BUTTON_F2: | ||
564 | star_load_level(current_level); | ||
565 | continue; | ||
566 | |||
567 | case BUTTON_F3: | ||
568 | if (current_level < STAR_LEVEL_COUNT - 1) | ||
569 | { | ||
570 | current_level++; | ||
571 | star_load_level(current_level); | ||
572 | } | ||
573 | continue; | ||
574 | |||
575 | case BUTTON_PLAY: | ||
576 | case BUTTON_ON: | ||
577 | if (control == STAR_CONTROL_BALL) | ||
578 | control = STAR_CONTROL_BLOCK; | ||
579 | else | ||
580 | control = STAR_CONTROL_BALL; | ||
581 | star_display_board_info(); | ||
582 | continue; | ||
583 | |||
584 | default: | ||
585 | continue; | ||
586 | } | ||
587 | |||
588 | if (control == STAR_CONTROL_BALL) | ||
589 | { | ||
590 | board[ball_y][ball_x] = STAR_VOID; | ||
591 | while ((board[ball_y + move_y][ball_x + move_x] == STAR_VOID | ||
592 | || board[ball_y + move_y][ball_x + move_x] == STAR_STAR)) | ||
593 | |||
594 | { | ||
595 | for (i = 0 ; i < 7 ; i++) | ||
596 | { | ||
597 | rb->lcd_bitmap( | ||
598 | ball_bmp, | ||
599 | STAR_OFFSET_X + ball_x * STAR_TILE_SIZE + move_x * i, | ||
600 | STAR_OFFSET_Y + ball_y * STAR_TILE_SIZE + move_y * i, | ||
601 | STAR_TILE_SIZE, STAR_TILE_SIZE, true); | ||
602 | |||
603 | rb->lcd_update_rect( | ||
604 | STAR_OFFSET_X + ball_x * STAR_TILE_SIZE + move_x * i, | ||
605 | STAR_OFFSET_Y + ball_y * STAR_TILE_SIZE + move_y * i, | ||
606 | STAR_TILE_SIZE, STAR_TILE_SIZE); | ||
607 | rb->sleep(STAR_SLEEP); | ||
608 | } | ||
609 | ball_x += move_x; | ||
610 | ball_y += move_y; | ||
611 | |||
612 | if (board[ball_y][ball_x] == STAR_STAR) | ||
613 | { | ||
614 | board[ball_y][ball_x] = STAR_VOID; | ||
615 | star_count--; | ||
616 | |||
617 | star_display_board_info(); | ||
618 | } | ||
619 | } | ||
620 | board[ball_y][ball_x] = STAR_BALL; | ||
621 | } | ||
622 | else | ||
623 | { | ||
624 | board[block_y][block_x] = STAR_VOID; | ||
625 | while (board[block_y + move_y][block_x + move_x] == STAR_VOID) | ||
626 | { | ||
627 | for (i = 0 ; i < 7 ; i++) | ||
628 | { | ||
629 | rb->lcd_bitmap( | ||
630 | block_bmp, | ||
631 | STAR_OFFSET_X + block_x * STAR_TILE_SIZE + move_x * i, | ||
632 | STAR_OFFSET_Y + block_y * STAR_TILE_SIZE + move_y * i, | ||
633 | STAR_TILE_SIZE, STAR_TILE_SIZE, true); | ||
634 | |||
635 | rb->lcd_update_rect( | ||
636 | STAR_OFFSET_X + block_x * STAR_TILE_SIZE + move_x * i, | ||
637 | STAR_OFFSET_Y + block_y * STAR_TILE_SIZE + move_y * i, | ||
638 | STAR_TILE_SIZE, STAR_TILE_SIZE); | ||
639 | |||
640 | rb->sleep(STAR_SLEEP); | ||
641 | } | ||
642 | block_x += move_x; | ||
643 | block_y += move_y; | ||
644 | } | ||
645 | board[block_y][block_x] = STAR_BLOCK; | ||
646 | } | ||
647 | |||
648 | if (star_count == 0) | ||
649 | { | ||
650 | current_level++; | ||
651 | if (current_level == STAR_LEVEL_COUNT) | ||
652 | { | ||
653 | rb->lcd_clear_display(); | ||
654 | star_display_text("Congratulation !", true); | ||
655 | rb->lcd_update(); | ||
656 | return 1; | ||
657 | } | ||
658 | star_load_level(current_level); | ||
659 | } | ||
660 | } | ||
661 | } | ||
662 | |||
663 | /** | ||
664 | * Display the choice menu. | ||
665 | */ | ||
666 | static int star_menu(void) | ||
667 | { | ||
668 | int move_y; | ||
669 | int menu_y = 0; | ||
670 | int i = 0; | ||
671 | bool refresh = true; | ||
672 | char anim_state = 0; | ||
673 | unsigned char *menu[4] = {"Start", "Information", "Keys", "Exit"}; | ||
674 | int menu_count = sizeof(menu) / sizeof(unsigned char *); | ||
675 | int menu_offset_y; | ||
676 | |||
677 | menu_offset_y = LCD_HEIGHT - char_height * menu_count; | ||
678 | |||
679 | while (true) | ||
680 | { | ||
681 | if (refresh) | ||
682 | { | ||
683 | rb->lcd_clear_display(); | ||
684 | rb->lcd_putsxy((LCD_WIDTH - char_width * | ||
685 | rb->strlen(STAR_TITLE)) / 2, | ||
686 | 0, STAR_TITLE); | ||
687 | for (i = 0 ; i < menu_count ; i++) | ||
688 | { | ||
689 | rb->lcd_putsxy(15, menu_offset_y + char_height * i, menu[i]); | ||
690 | } | ||
691 | |||
692 | rb->lcd_update(); | ||
693 | refresh = false; | ||
694 | } | ||
695 | |||
696 | move_y = 0; | ||
697 | rb->lcd_bitmap(arrow_bmp[anim_arrow[(anim_state & 0x38) >> 3]], | ||
698 | 2, menu_offset_y + menu_y * char_height, 7, 8, true); | ||
699 | rb->lcd_update_rect (2, menu_offset_y + menu_y * 8, 8, 8); | ||
700 | rb->sleep(STAR_SLEEP); | ||
701 | anim_state++; | ||
702 | |||
703 | switch (rb->button_get(false)) | ||
704 | { | ||
705 | case BUTTON_OFF: | ||
706 | return PLUGIN_OK; | ||
707 | case BUTTON_UP: | ||
708 | if (menu_y > 0) | ||
709 | move_y = -1; | ||
710 | break; | ||
711 | case BUTTON_DOWN: | ||
712 | if (menu_y < 3) | ||
713 | move_y = 1; | ||
714 | break; | ||
715 | |||
716 | case BUTTON_ON: | ||
717 | case BUTTON_PLAY: | ||
718 | case BUTTON_RIGHT: | ||
719 | refresh = true; | ||
720 | switch (menu_y) | ||
721 | { | ||
722 | case 0: | ||
723 | if (!star_run_game()) | ||
724 | return PLUGIN_OK; | ||
725 | break; | ||
726 | case 1: | ||
727 | star_display_text( | ||
728 | "INFO\n\n" | ||
729 | "Take all \"o\" to go to the next level. " | ||
730 | "You can toggle control with the block to " | ||
731 | "use it as a mobile wall. The block cannot " | ||
732 | "take \"o\".", true); | ||
733 | break; | ||
734 | case 2: | ||
735 | star_display_text("KEYS\n\n" | ||
736 | "[ON] Toggle Ctl.\n" | ||
737 | "[OFF] Exit\n" | ||
738 | "[F1] Prev. level\n" | ||
739 | "[F2] Reset level\n" | ||
740 | "[F3] Next level", true); | ||
741 | break; | ||
742 | case 3: | ||
743 | return PLUGIN_OK; | ||
744 | } | ||
745 | break; | ||
746 | |||
747 | case SYS_USB_CONNECTED: | ||
748 | rb->usb_screen(); | ||
749 | return PLUGIN_USB_CONNECTED; | ||
750 | |||
751 | default: | ||
752 | continue; | ||
753 | } | ||
754 | |||
755 | for (i = 0 ; i < char_height ; i++) | ||
756 | { | ||
757 | rb->lcd_clearrect (2, 30, 7, 4 * 8); | ||
758 | rb->lcd_bitmap(arrow_bmp[anim_arrow[(anim_state & 0x38) >> 3]], | ||
759 | 2, menu_offset_y + menu_y * 8 + move_y * i, 7, 8, | ||
760 | false); | ||
761 | rb->lcd_update_rect(2, 30, 8, 4 * 8); | ||
762 | anim_state++; | ||
763 | rb->sleep(STAR_SLEEP); | ||
764 | } | ||
765 | menu_y += move_y; | ||
766 | } | ||
767 | } | ||
768 | |||
769 | /** | ||
770 | * Main entry point | ||
771 | */ | ||
772 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | ||
773 | { | ||
774 | TEST_PLUGIN_API(api); | ||
775 | (void)parameter; | ||
776 | rb = api; | ||
777 | |||
778 | /* get the size of char */ | ||
779 | if (char_width == -1) | ||
780 | rb->lcd_getstringsize("a", &char_width, &char_height); | ||
781 | |||
782 | /* display choice menu */ | ||
783 | return star_menu(); | ||
784 | } | ||
785 | |||
786 | #endif | ||