Fix some quotation marks. Thanks to Alexander Levin for pointing it out.
[Rockbox.git] / apps / plugins / star.c
blobc2546d2385a638e38f93aa980748f01c98a120a8
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 Frederic Dang Ngoc
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 ****************************************************************************/
19 #include "plugin.h"
20 #ifdef HAVE_LCD_BITMAP
22 PLUGIN_HEADER
24 /* size of a level in file */
25 #define STAR_LEVEL_SIZE ((STAR_WIDTH + 1) * STAR_HEIGHT + 1)
27 /* size of the game board */
28 #define STAR_WIDTH 16
29 #define STAR_HEIGHT 9
31 /* number of level */
32 #define STAR_LEVEL_COUNT 20
34 /* values of object in the board */
35 #define STAR_VOID '.'
36 #define STAR_WALL '*'
37 #define STAR_STAR 'o'
38 #define STAR_BALL 'X'
39 #define STAR_BLOCK 'x'
41 /* sleep time between two frames */
42 #if (LCD_HEIGHT * LCD_WIDTH >= 70000) && defined(IPOD_ARCH)
43 /* iPod 5G LCD is *slow* */
44 #define STAR_SLEEP rb->yield();
45 #elif (LCD_HEIGHT * LCD_WIDTH >= 30000)
46 #define STAR_SLEEP rb->sleep(0);
47 #else
48 #define STAR_SLEEP rb->sleep(1);
49 #endif
51 /* value of ball and block control */
52 #define STAR_CONTROL_BALL 0
53 #define STAR_CONTROL_BLOCK 1
55 /* variable button definitions */
56 #if CONFIG_KEYPAD == RECORDER_PAD
57 #define STAR_QUIT BUTTON_OFF
58 #define STAR_LEFT BUTTON_LEFT
59 #define STAR_RIGHT BUTTON_RIGHT
60 #define STAR_UP BUTTON_UP
61 #define STAR_DOWN BUTTON_DOWN
62 #define STAR_TOGGLE_CONTROL BUTTON_ON
63 #define STAR_TOGGLE_CONTROL2 BUTTON_PLAY
64 #define STAR_LEVEL_UP BUTTON_F3
65 #define STAR_LEVEL_DOWN BUTTON_F1
66 #define STAR_LEVEL_REPEAT BUTTON_F2
67 #define STAR_MENU_RUN BUTTON_PLAY
68 #define STAR_MENU_RUN2 BUTTON_RIGHT
69 #define STAR_MENU_RUN3 BUTTON_ON
71 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
72 #define STAR_QUIT BUTTON_OFF
73 #define STAR_LEFT BUTTON_LEFT
74 #define STAR_RIGHT BUTTON_RIGHT
75 #define STAR_UP BUTTON_UP
76 #define STAR_DOWN BUTTON_DOWN
77 #define STAR_TOGGLE_CONTROL BUTTON_ON
78 #define STAR_TOGGLE_CONTROL2 BUTTON_SELECT
79 #define STAR_LEVEL_UP BUTTON_F3
80 #define STAR_LEVEL_DOWN BUTTON_F1
81 #define STAR_LEVEL_REPEAT BUTTON_F2
82 #define STAR_MENU_RUN BUTTON_SELECT
83 #define STAR_MENU_RUN2 BUTTON_RIGHT
84 #define STAR_MENU_RUN3 BUTTON_ON
86 #elif CONFIG_KEYPAD == ONDIO_PAD
87 #define STAR_QUIT BUTTON_OFF
88 #define STAR_LEFT BUTTON_LEFT
89 #define STAR_RIGHT BUTTON_RIGHT
90 #define STAR_UP BUTTON_UP
91 #define STAR_DOWN BUTTON_DOWN
92 #define STAR_TOGGLE_CONTROL_PRE BUTTON_MENU
93 #define STAR_TOGGLE_CONTROL (BUTTON_MENU | BUTTON_REL)
94 #define STAR_LEVEL_UP (BUTTON_MENU | BUTTON_RIGHT)
95 #define STAR_LEVEL_DOWN (BUTTON_MENU | BUTTON_LEFT)
96 #define STAR_LEVEL_REPEAT (BUTTON_MENU | BUTTON_UP)
97 #define STAR_MENU_RUN BUTTON_RIGHT
99 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
100 (CONFIG_KEYPAD == IRIVER_H300_PAD)
101 #define STAR_QUIT BUTTON_OFF
102 #define STAR_LEFT BUTTON_LEFT
103 #define STAR_RIGHT BUTTON_RIGHT
104 #define STAR_UP BUTTON_UP
105 #define STAR_DOWN BUTTON_DOWN
106 #define STAR_TOGGLE_CONTROL BUTTON_MODE
107 #define STAR_TOGGLE_CONTROL2 BUTTON_SELECT
108 #define STAR_LEVEL_UP (BUTTON_ON | BUTTON_RIGHT)
109 #define STAR_LEVEL_DOWN (BUTTON_ON | BUTTON_LEFT)
110 #define STAR_LEVEL_REPEAT (BUTTON_ON | BUTTON_SELECT)
111 #define STAR_MENU_RUN BUTTON_RIGHT
112 #define STAR_MENU_RUN2 BUTTON_SELECT
114 #define STAR_RC_QUIT BUTTON_RC_STOP
115 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
116 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
117 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
119 #define STAR_QUIT (BUTTON_SELECT | BUTTON_MENU)
120 #define STAR_LEFT BUTTON_LEFT
121 #define STAR_RIGHT BUTTON_RIGHT
122 #define STAR_UP BUTTON_MENU
123 #define STAR_DOWN BUTTON_PLAY
124 #define STAR_TOGGLE_CONTROL_PRE BUTTON_SELECT
125 #define STAR_TOGGLE_CONTROL (BUTTON_SELECT | BUTTON_REL)
126 #define STAR_LEVEL_UP (BUTTON_SELECT | BUTTON_RIGHT)
127 #define STAR_LEVEL_DOWN (BUTTON_SELECT | BUTTON_LEFT)
128 #define STAR_LEVEL_REPEAT (BUTTON_SELECT | BUTTON_PLAY)
129 #define STAR_MENU_RUN BUTTON_RIGHT
130 #define STAR_MENU_RUN2 BUTTON_SELECT
132 #elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
134 #define STAR_QUIT BUTTON_POWER
135 #define STAR_LEFT BUTTON_LEFT
136 #define STAR_RIGHT BUTTON_RIGHT
137 #define STAR_UP BUTTON_UP
138 #define STAR_DOWN BUTTON_DOWN
139 #define STAR_TOGGLE_CONTROL BUTTON_SELECT
140 #define STAR_LEVEL_UP_PRE BUTTON_REC
141 #define STAR_LEVEL_UP (BUTTON_REC|BUTTON_REL)
142 #define STAR_LEVEL_DOWN_PRE BUTTON_REC
143 #define STAR_LEVEL_DOWN (BUTTON_REC|BUTTON_REPEAT)
144 #define STAR_LEVEL_REPEAT BUTTON_PLAY
145 #define STAR_MENU_RUN BUTTON_RIGHT
146 #define STAR_MENU_RUN2 BUTTON_SELECT
148 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
150 #define STAR_QUIT BUTTON_POWER
151 #define STAR_LEFT BUTTON_LEFT
152 #define STAR_RIGHT BUTTON_RIGHT
153 #define STAR_UP BUTTON_UP
154 #define STAR_DOWN BUTTON_DOWN
155 #define STAR_TOGGLE_CONTROL BUTTON_SELECT
156 #define STAR_LEVEL_UP BUTTON_VOL_UP
157 #define STAR_LEVEL_DOWN BUTTON_VOL_DOWN
158 #define STAR_LEVEL_REPEAT BUTTON_A
159 #define STAR_MENU_RUN BUTTON_SELECT
161 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
162 (CONFIG_KEYPAD == SANSA_C200_PAD)
164 #define STAR_QUIT BUTTON_POWER
165 #define STAR_LEFT BUTTON_LEFT
166 #define STAR_RIGHT BUTTON_RIGHT
167 #define STAR_UP BUTTON_UP
168 #define STAR_DOWN BUTTON_DOWN
169 #define STAR_TOGGLE_CONTROL BUTTON_SELECT
170 #define STAR_LEVEL_UP (BUTTON_SELECT | BUTTON_RIGHT)
171 #define STAR_LEVEL_DOWN (BUTTON_SELECT | BUTTON_LEFT)
172 #define STAR_LEVEL_REPEAT (BUTTON_SELECT | BUTTON_DOWN)
173 #define STAR_MENU_RUN BUTTON_SELECT
176 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
178 #define STAR_QUIT BUTTON_POWER
179 #define STAR_LEFT BUTTON_LEFT
180 #define STAR_RIGHT BUTTON_RIGHT
181 #define STAR_UP BUTTON_SCROLL_UP
182 #define STAR_DOWN BUTTON_SCROLL_DOWN
183 #define STAR_TOGGLE_CONTROL BUTTON_REW
184 #define STAR_LEVEL_UP (BUTTON_PLAY | BUTTON_SCROLL_UP)
185 #define STAR_LEVEL_DOWN (BUTTON_PLAY | BUTTON_SCROLL_DOWN)
186 #define STAR_LEVEL_REPEAT (BUTTON_PLAY | BUTTON_RIGHT)
187 #define STAR_MENU_RUN BUTTON_FF
189 #elif (CONFIG_KEYPAD == GIGABEAT_S_PAD)
191 #define STAR_QUIT BUTTON_BACK
192 #define STAR_LEFT BUTTON_LEFT
193 #define STAR_RIGHT BUTTON_RIGHT
194 #define STAR_UP BUTTON_UP
195 #define STAR_DOWN BUTTON_DOWN
196 #define STAR_TOGGLE_CONTROL BUTTON_SELECT
197 #define STAR_LEVEL_UP BUTTON_VOL_UP
198 #define STAR_LEVEL_DOWN BUTTON_VOL_DOWN
199 #define STAR_LEVEL_REPEAT BUTTON_MENU
200 #define STAR_MENU_RUN BUTTON_SELECT
202 #elif (CONFIG_KEYPAD == MROBE100_PAD)
204 #define STAR_QUIT BUTTON_POWER
205 #define STAR_LEFT BUTTON_LEFT
206 #define STAR_RIGHT BUTTON_RIGHT
207 #define STAR_UP BUTTON_UP
208 #define STAR_DOWN BUTTON_DOWN
209 #define STAR_TOGGLE_CONTROL BUTTON_SELECT
210 #define STAR_LEVEL_UP BUTTON_PLAY
211 #define STAR_LEVEL_DOWN BUTTON_MENU
212 #define STAR_LEVEL_REPEAT BUTTON_DISPLAY
213 #define STAR_MENU_RUN BUTTON_SELECT
215 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
217 #define STAR_QUIT BUTTON_RC_REC
218 #define STAR_LEFT BUTTON_RC_REW
219 #define STAR_RIGHT BUTTON_RC_FF
220 #define STAR_UP BUTTON_RC_VOL_UP
221 #define STAR_DOWN BUTTON_RC_VOL_DOWN
222 #define STAR_TOGGLE_CONTROL BUTTON_RC_MODE
223 #define STAR_LEVEL_UP (BUTTON_RC_PLAY|BUTTON_RC_VOL_UP)
224 #define STAR_LEVEL_DOWN (BUTTON_RC_PLAY|BUTTON_RC_VOL_DOWN)
225 #define STAR_LEVEL_REPEAT (BUTTON_RC_PLAY|BUTTON_RC_MENU)
226 #define STAR_MENU_RUN BUTTON_RC_FF
228 #elif (CONFIG_KEYPAD == COWOND2_PAD)
230 #define STAR_QUIT BUTTON_POWER
231 #define STAR_LEFT BUTTON_LEFT
232 #define STAR_RIGHT BUTTON_RIGHT
233 #define STAR_UP BUTTON_UP
234 #define STAR_DOWN BUTTON_DOWN
235 #define STAR_TOGGLE_CONTROL BUTTON_SELECT
236 #define STAR_LEVEL_UP BUTTON_PLUS
237 #define STAR_LEVEL_DOWN BUTTON_MINUS
238 #define STAR_LEVEL_REPEAT (BUTTON_SELECT | BUTTON_MENU)
239 #define STAR_MENU_RUN BUTTON_MENU
241 #else
242 #error No keymap defined!
243 #endif
245 /* function returns because of USB? */
246 static bool usb_detected = false;
248 /* position of the ball */
249 static int ball_x, ball_y;
251 /* position of the block */
252 static int block_x, block_y;
254 /* number of stars to get to finish the level */
255 static int star_count;
257 /* the object we control : ball or block */
258 static int control;
260 /* the current board */
261 static char board[STAR_HEIGHT][STAR_WIDTH];
263 #include "star_tiles.h"
265 #define TILE_WIDTH BMPWIDTH_star_tiles
266 #define TILE_HEIGHT (BMPHEIGHT_star_tiles/5)
267 #define STAR_OFFSET_X ((LCD_WIDTH - STAR_WIDTH * TILE_WIDTH) / 2)
268 #define STAR_OFFSET_Y ((LCD_HEIGHT - STAR_HEIGHT * TILE_HEIGHT - MAX(TILE_HEIGHT, 8)) / 2)
270 #define WALL 0
271 #define SPACE 1
272 #define BLOCK 2
273 #define STAR 3
274 #define BALL 4
276 #define MENU_START 0
278 /* char font size */
279 static int char_width = -1;
280 static int char_height = -1;
282 static struct plugin_api* rb;
284 /* this arrays contains a group of levels loaded into memory */
285 static unsigned char* levels =
286 "****************\n"
287 "*X**........o*x*\n"
288 "*..........o.***\n"
289 "*.......**o....*\n"
290 "*...**.o......**\n"
291 "**.o..o.....o..*\n"
292 "*.o......o**.o.*\n"
293 "*.....**o.....o*\n"
294 "****************\n"
295 "\n"
296 ".*..*.*.*...*.**\n"
297 "*...o.........X*\n"
298 "...*o..*o...o...\n"
299 "*.*.o.....o..*.*\n"
300 "......*...o...*.\n"
301 "*....*x*..o....*\n"
302 "...*..*.*...*oo*\n"
303 "*.............*.\n"
304 ".*..*........*..\n"
305 "\n"
306 "****************\n"
307 "*...........o*x*\n"
308 "*...**......**X*\n"
309 "*...*o.........*\n"
310 "*.o.....o**...o*\n"
311 "*.*o..o..o*..o**\n"
312 "*.**o.*o..o.o***\n"
313 "*o....**o......*\n"
314 "****************\n"
315 "\n"
316 "****************\n"
317 "*............*x*\n"
318 "*.....*........*\n"
319 "**o*o.o*o*o*o*o*\n"
320 "*.*.*o.o*.*.*.**\n"
321 "**o*o*o.o*o*o*o*\n"
322 "*.....*........*\n"
323 "*...*.......*X.*\n"
324 "****************\n"
325 "\n"
326 ".**************.\n"
327 "*X..*...*..*...*\n"
328 "*..*o.*.o..o.*.*\n"
329 "**......*..*...*\n"
330 "*o.*o*........**\n"
331 "**.....*.o.*...*\n"
332 "*o*..*.*.*...*x*\n"
333 "*...*....o*..*o*\n"
334 ".**************.\n"
335 "\n"
336 "....************\n"
337 "...*...o...*o.o*\n"
338 "..*....o....*.**\n"
339 ".*.....o.......*\n"
340 "*X.....o.......*\n"
341 "**.....o..*...**\n"
342 "*......o....*..*\n"
343 "*x.*...o..**o..*\n"
344 "****************\n"
345 "\n"
346 "****************\n"
347 "*..............*\n"
348 ".**.***..*o.**o*\n"
349 ".*o..*o.*.*.*.*.\n"
350 "..*..*..***.**..\n"
351 ".**..*..*o*.*o**\n"
352 "*..............*\n"
353 "*..X*o....x..*o*\n"
354 "****************\n"
355 "\n"
356 "***************.\n"
357 "*..o**.........*\n"
358 "*..*o..**.o....*\n"
359 "*..o**.*.*o....*\n"
360 "**.....**..*o*.*\n"
361 "**.*.......o*o.*\n"
362 "*oxo*...o..*X*.*\n"
363 "**.............*\n"
364 ".***************\n"
365 "\n"
366 "..*.***********.\n"
367 ".*o*o......*..X*\n"
368 "*o.o*....o....*.\n"
369 ".*.*..o**..o*..*\n"
370 "*..*o.*oxo....o*\n"
371 "*.....o**.....*.\n"
372 "*o*o.........*..\n"
373 "*...........*...\n"
374 ".***********....\n"
375 "\n"
376 "....***********.\n"
377 "*****.o........*\n"
378 "*...x.***o.o*.o*\n"
379 "*.o...*o.*o...*.\n"
380 "*.....*..o..*.o*\n"
381 "*o*o..*.o*..*X*.\n"
382 ".*o...***..***..\n"
383 "*.........*.*.*.\n"
384 ".*********..*..*\n"
385 "\n"
386 "****************\n"
387 "*......*......X*\n"
388 "*..*oo.....oo.**\n"
389 "**...o...**...o*\n"
390 "*o....*o*oo..***\n"
391 "**.**....**....*\n"
392 "*o..o*.o....x.o*\n"
393 "**o***....*...**\n"
394 "***************.\n"
395 "\n"
396 "**.....**..****.\n"
397 "*X*****o.***.o**\n"
398 "*....oo.....o..*\n"
399 "*.**..**o..*o*.*\n"
400 "*.*.o.*.*o.**..*\n"
401 "*.**..**...*x*.*\n"
402 "*.....o........*\n"
403 "*........o.....*\n"
404 "****************\n"
405 "\n"
406 ".**************.\n"
407 "*.X*........o.**\n"
408 "*.*...*o...o**.*\n"
409 "*.......o....*.*\n"
410 "*.o..........*o*\n"
411 "*.*......o.....*\n"
412 "**......o.o..*o*\n"
413 "*x..*....o.*.*.*\n"
414 ".**************.\n"
415 "\n"
416 "****************\n"
417 "*o*o........o*o*\n"
418 "*.o*X......**..*\n"
419 "*.x........o...*\n"
420 "*........o*....*\n"
421 "*......o.......*\n"
422 "*.o*........*..*\n"
423 "*o*o........o*o*\n"
424 "****************\n"
425 "\n"
426 ".******.********\n"
427 "*.....o*.....o.*\n"
428 "*.*.o.*..*...o.*\n"
429 "*..X*...*oo.*o.*\n"
430 ".*.*...*.o..x*.*\n"
431 "*o.......*..*o.*\n"
432 ".*......o.....*.\n"
433 "*o............o*\n"
434 "****************\n"
435 "\n"
436 "****************\n"
437 "**.x*o.o......o*\n"
438 "*o.Xo*o.......**\n"
439 "**.***........**\n"
440 "**.....o*o*....*\n"
441 "*oo.......o*o..*\n"
442 "**.o....****o..*\n"
443 "**o*..*........*\n"
444 "****************\n"
445 "\n"
446 "****************\n"
447 "*.o*........*X.*\n"
448 "*.*..o*oo*o..*.*\n"
449 "*....*o**o*.o..*\n"
450 "*.o*.......o*..*\n"
451 "*..o*o....o*...*\n"
452 "*.*..*.**o*..*.*\n"
453 "*....o.*o...x..*\n"
454 "****************\n"
455 "\n"
456 "****************\n"
457 "*.o....o..x*...*\n"
458 "*..*o*o...*o...*\n"
459 "*...*o*....*o..*\n"
460 "*...o..*...o*o.*\n"
461 "*.*o*...*.o*...*\n"
462 "*.o*o.*.o.*....*\n"
463 "*o*X..*.....*..*\n"
464 "****************\n"
465 "\n"
466 "****************\n"
467 "*o...**.....**o*\n"
468 "*.*..*......*o.*\n"
469 "*.o*...o**..o..*\n"
470 "*.*....*o......*\n"
471 "*....*...o*....*\n"
472 "*.**.o*.**o..*x*\n"
473 "*.o*.*o.....**X*\n"
474 "****************\n"
475 "\n"
476 "****************\n"
477 "*...o*o........*\n"
478 "**o..o*.**o...**\n"
479 "*.*.*.o...*..*.*\n"
480 "*.x.*..**..*.Xo*\n"
481 "*.*..*...o.*.*.*\n"
482 "**...o**.*o..o**\n"
483 "*........o*o...*\n"
484 "****************";
487 * Display text.
489 void star_display_text(char *str, bool waitkey)
491 int chars_by_line;
492 int lines_by_screen;
493 int chars_for_line;
494 int current_line = 0;
495 int first_char_index = 0;
496 char *ptr_char;
497 char *ptr_line;
498 int i;
499 char line[255];
500 int key;
501 bool go_on;
503 rb->lcd_clear_display();
505 chars_by_line = LCD_WIDTH / char_width;
506 lines_by_screen = LCD_HEIGHT / char_height;
510 ptr_char = str + first_char_index;
511 chars_for_line = 0;
512 i = 0;
513 ptr_line = line;
514 while (i < chars_by_line)
516 switch (*ptr_char)
518 case '\t':
519 case ' ':
520 *(ptr_line++) = ' ';
521 case '\n':
522 case '\0':
523 chars_for_line = i;
524 break;
526 default:
527 *(ptr_line++) = *ptr_char;
529 if (*ptr_char == '\n' || *ptr_char == '\0')
530 break;
531 ptr_char++;
532 i++;
535 if (chars_for_line == 0)
536 chars_for_line = i;
538 line[chars_for_line] = '\0';
540 /* test if we have cut a word. If it is the case we don't have to */
541 /* skip the space */
542 if (i == chars_by_line && chars_for_line == chars_by_line)
543 first_char_index += chars_for_line;
544 else
545 first_char_index += chars_for_line + 1;
547 /* print the line on the screen */
548 rb->lcd_putsxy(0, current_line * char_height, line);
550 /* if the number of line showed on the screen is equals to the */
551 /* maximum number of line we can show, we wait for a key pressed to */
552 /* clear and show the remaining text. */
553 current_line++;
554 if (current_line == lines_by_screen || *ptr_char == '\0')
556 current_line = 0;
557 rb->lcd_update();
558 go_on = false;
559 while (waitkey && !go_on)
561 key = rb->button_get(true);
562 switch (key)
564 case STAR_QUIT:
565 case STAR_LEFT:
566 case STAR_DOWN:
567 go_on = true;
568 break;
570 default:
571 if (rb->default_event_handler(key) == SYS_USB_CONNECTED)
573 usb_detected = true;
574 go_on = true;
575 break;
579 rb->lcd_clear_display();
581 } while (*ptr_char != '\0');
585 * Do a pretty transition from one level to another.
587 static void star_transition_update(void)
589 const int center_x = LCD_WIDTH / 2;
590 const int center_y = LCD_HEIGHT / 2;
591 int x = 0;
592 int y = 0;
593 #if LCD_WIDTH >= LCD_HEIGHT
594 #if defined(IPOD_VIDEO)
595 const int step = 4;
596 #else
597 const int step = 1;
598 #endif
599 const int lcd_demi_width = LCD_WIDTH / 2;
600 int var_y = 0;
602 for (; x < lcd_demi_width ; x+=step)
604 var_y += LCD_HEIGHT;
605 if (var_y > LCD_WIDTH)
607 var_y -= LCD_WIDTH;
608 y+=step;
610 if( x )
612 rb->lcd_update_rect(center_x - x, center_y - y, x*2, step);
613 rb->lcd_update_rect(center_x - x, center_y + y - step, x*2, step);
615 if( y )
617 rb->lcd_update_rect(center_x - x, center_y - y, step, y*2);
618 rb->lcd_update_rect(center_x + x - step, center_y - y, step, y*2);
620 STAR_SLEEP
622 #else
623 int lcd_demi_height = LCD_HEIGHT / 2;
624 int var_x = 0;
626 for (; y < lcd_demi_height ; y++)
628 var_x += LCD_WIDTH;
629 if (var_x > LCD_HEIGHT)
631 var_x -= LCD_HEIGHT;
632 x++;
634 if( x )
636 rb->lcd_update_rect(center_x - x, center_y - y, x * 2, 1);
637 rb->lcd_update_rect(center_x - x, center_y + y - 1, x * 2, 1);
639 if( y )
641 rb->lcd_update_rect(center_x - x, center_y - y, 1, y * 2);
642 rb->lcd_update_rect(center_x + x - 1, center_y - y, 1, y * 2);
644 STAR_SLEEP
646 #endif
647 rb->lcd_update();
651 * Display information board of the current level.
653 static void star_display_board_info(int current_level)
655 int label_pos_y, tile_pos_y;
656 char str_info[32];
658 if (TILE_HEIGHT > char_height)
660 tile_pos_y = LCD_HEIGHT - TILE_HEIGHT;
661 label_pos_y = tile_pos_y + (TILE_HEIGHT - char_height) / 2;
663 else
665 label_pos_y = LCD_HEIGHT - char_height;
666 tile_pos_y = label_pos_y + (char_height - TILE_HEIGHT) / 2;
669 rb->snprintf(str_info, sizeof(str_info), "L:%02d", current_level + 1);
670 rb->lcd_putsxy(STAR_OFFSET_X, label_pos_y, str_info);
671 rb->snprintf(str_info, sizeof(str_info), "S:%02d", star_count);
672 rb->lcd_putsxy(LCD_WIDTH/2 - 2 * char_width, label_pos_y, str_info);
673 rb->lcd_putsxy(STAR_OFFSET_X + (STAR_WIDTH-1) * TILE_WIDTH - 2 * char_width,
674 label_pos_y, "C:");
676 rb->lcd_bitmap_part(star_tiles, 0, control == STAR_CONTROL_BALL ?
677 BALL*TILE_HEIGHT : BLOCK*TILE_HEIGHT, TILE_WIDTH,
678 STAR_OFFSET_X + (STAR_WIDTH-1) * TILE_WIDTH,
679 tile_pos_y, TILE_WIDTH, TILE_HEIGHT);
681 rb->lcd_update_rect(0, MIN(label_pos_y, tile_pos_y), LCD_WIDTH,
682 MAX(TILE_HEIGHT, char_height));
687 * Load a level into board array.
689 static int star_load_level(int current_level)
691 int x, y;
692 char *ptr_tab;
694 if (current_level < 0)
695 current_level = 0;
696 else if (current_level > STAR_LEVEL_COUNT-1)
697 current_level = STAR_LEVEL_COUNT-1;
700 ptr_tab = levels + current_level * STAR_LEVEL_SIZE;
701 control = STAR_CONTROL_BALL;
702 star_count = 0;
704 rb->lcd_clear_display();
706 for (y = 0 ; y < STAR_HEIGHT ; y++)
708 for (x = 0 ; x < STAR_WIDTH ; x++)
710 board[y][x] = *ptr_tab;
711 switch (*ptr_tab)
713 # define DRAW_TILE( a ) \
714 rb->lcd_bitmap_part( star_tiles, 0, \
715 a*TILE_HEIGHT, TILE_WIDTH, \
716 STAR_OFFSET_X + x * TILE_WIDTH, \
717 STAR_OFFSET_Y + y * TILE_HEIGHT, \
718 TILE_WIDTH, TILE_HEIGHT);
719 case STAR_VOID:
720 DRAW_TILE( SPACE );
721 break;
723 case STAR_WALL:
724 DRAW_TILE( WALL );
725 break;
727 case STAR_STAR:
728 DRAW_TILE( STAR );
729 star_count++;
730 break;
732 case STAR_BALL:
733 ball_x = x;
734 ball_y = y;
735 DRAW_TILE( BALL );
736 break;
739 case STAR_BLOCK:
740 block_x = x;
741 block_y = y;
742 DRAW_TILE( BLOCK );
743 break;
745 ptr_tab++;
747 ptr_tab++;
749 star_display_board_info(current_level);
750 star_transition_update();
751 return 1;
754 static void star_animate_tile(int tile_no, int start_x, int start_y,
755 int delta_x, int delta_y)
757 int i;
759 if (delta_x != 0) /* horizontal */
761 for (i = 1 ; i <= TILE_WIDTH ; i++)
763 STAR_SLEEP
764 rb->lcd_bitmap_part(star_tiles, 0, SPACE * TILE_HEIGHT, TILE_WIDTH,
765 start_x, start_y, TILE_WIDTH, TILE_HEIGHT);
766 rb->lcd_bitmap_part(star_tiles, 0, tile_no * TILE_HEIGHT, TILE_WIDTH,
767 start_x + delta_x * i, start_y, TILE_WIDTH, TILE_HEIGHT);
768 rb->lcd_update_rect(start_x + delta_x * i - (delta_x>0?1:0),
769 start_y, TILE_WIDTH + 1, TILE_HEIGHT);
772 else /* vertical */
774 for (i = 1 ; i <= TILE_HEIGHT ; i++)
776 STAR_SLEEP
777 rb->lcd_bitmap_part(star_tiles, 0, SPACE * TILE_HEIGHT, TILE_WIDTH,
778 start_x, start_y, TILE_WIDTH, TILE_HEIGHT);
779 rb->lcd_bitmap_part(star_tiles, 0, tile_no * TILE_HEIGHT, TILE_WIDTH,
780 start_x, start_y + delta_y * i, TILE_WIDTH, TILE_HEIGHT);
781 rb->lcd_update_rect(start_x, start_y + delta_y * i - (delta_y>0?1:0),
782 TILE_WIDTH, TILE_HEIGHT + 1);
788 * Run the game.
790 static int star_run_game(int current_level)
792 int move_x = 0;
793 int move_y = 0;
794 int key;
795 int lastkey = BUTTON_NONE;
797 int label_offset_y;
799 label_offset_y = LCD_HEIGHT - char_height;
801 if (!star_load_level(current_level))
802 return 0;
804 while (true)
806 move_x = 0;
807 move_y = 0;
809 while ((move_x == 0) && (move_y == 0))
811 key = rb->button_get(true);
812 switch (key)
814 #ifdef STAR_RC_QUIT
815 case STAR_RC_QUIT:
816 #endif
817 case STAR_QUIT:
818 return -1;
820 case STAR_LEFT:
821 move_x = -1;
822 break;
824 case STAR_RIGHT:
825 move_x = 1;
826 break;
828 case STAR_UP:
829 move_y = -1;
830 break;
832 case STAR_DOWN:
833 move_y = 1;
834 break;
836 case STAR_LEVEL_DOWN:
837 #ifdef STAR_LEVEL_DOWN_PRE
838 if (lastkey != STAR_LEVEL_DOWN_PRE)
839 break;
840 #endif
841 if (current_level > 0)
843 current_level--;
844 star_load_level(current_level);
846 break;
848 case STAR_LEVEL_REPEAT:
849 star_load_level(current_level);
850 break;
852 case STAR_LEVEL_UP:
853 #ifdef STAR_LEVEL_UP_PRE
854 if (lastkey != STAR_LEVEL_UP_PRE)
855 break;
856 #endif
857 if (current_level < STAR_LEVEL_COUNT - 1)
859 current_level++;
860 star_load_level(current_level);
862 break;
864 case STAR_TOGGLE_CONTROL:
865 #ifdef STAR_TOGGLE_CONTROL_PRE
866 if (lastkey != STAR_TOGGLE_CONTROL_PRE)
867 break;
868 #endif
869 #ifdef STAR_TOGGLE_CONTROL2
870 case STAR_TOGGLE_CONTROL2:
871 #endif
872 if (control == STAR_CONTROL_BALL)
873 control = STAR_CONTROL_BLOCK;
874 else
875 control = STAR_CONTROL_BALL;
876 star_display_board_info(current_level);
877 break;
879 default:
880 if (rb->default_event_handler(key) == SYS_USB_CONNECTED)
882 usb_detected = true;
883 return 0;
885 break;
887 if (key != BUTTON_NONE)
888 lastkey = key;
891 if (control == STAR_CONTROL_BALL)
893 board[ball_y][ball_x] = STAR_VOID;
894 while ((board[ball_y + move_y][ball_x + move_x] == STAR_VOID
895 || board[ball_y + move_y][ball_x + move_x] == STAR_STAR))
898 star_animate_tile(BALL, STAR_OFFSET_X + ball_x * TILE_WIDTH,
899 STAR_OFFSET_Y + ball_y * TILE_HEIGHT,
900 move_x, move_y);
901 ball_x += move_x;
902 ball_y += move_y;
904 if (board[ball_y][ball_x] == STAR_STAR)
906 board[ball_y][ball_x] = STAR_VOID;
907 star_count--;
909 star_display_board_info(current_level);
912 board[ball_y][ball_x] = STAR_BALL;
914 else
916 board[block_y][block_x] = STAR_VOID;
917 while (board[block_y + move_y][block_x + move_x] == STAR_VOID)
919 star_animate_tile(BLOCK, STAR_OFFSET_X + block_x * TILE_WIDTH,
920 STAR_OFFSET_Y + block_y * TILE_HEIGHT,
921 move_x, move_y);
922 block_x += move_x;
923 block_y += move_y;
925 board[block_y][block_x] = STAR_BLOCK;
928 if (star_count == 0)
930 current_level++;
931 if (current_level == STAR_LEVEL_COUNT)
933 rb->lcd_clear_display();
934 star_display_text("Congratulations!", true);
935 rb->lcd_update();
937 /* There is no such level as STAR_LEVEL_COUNT so it can't be the
938 * current_level */
939 current_level--;
940 return 1;
942 star_load_level(current_level);
948 * Display the choice menu.
950 static int star_menu(void)
952 int selection, level=1;
953 bool menu_quit = false;
954 struct viewport vp[NB_SCREENS];
955 /* get the size of char */
956 rb->lcd_getstringsize("a", &char_width, &char_height);
958 MENUITEM_STRINGLIST(menu,"Star Menu",NULL,"Play","Choose Level",
959 "Information","Keys","Quit");
960 FOR_NB_SCREENS(selection)
962 rb->viewport_set_defaults(&vp[selection], selection);
963 /* we are hiding the statusbar so fix the height also */
964 vp->y = 0; vp->height = rb->screens[selection]->height;
965 #if LCD_DEPTH > 1
966 if (rb->screens[selection]->depth > 1)
968 vp->bg_pattern = LCD_BLACK;
969 vp->fg_pattern = LCD_WHITE;
971 #endif
973 while(!menu_quit)
975 switch(rb->do_menu(&menu, &selection, vp, true))
977 case 0:
978 menu_quit = true;
979 break;
980 case 1:
981 rb->set_int("Level", "", UNIT_INT, &level,
982 NULL, 1, 1, STAR_LEVEL_COUNT, NULL );
983 break;
984 case 2:
985 star_display_text(
986 "INFO\n\n"
987 "Take all the stars to go to the next level. "
988 "You can toggle control with the block to "
989 "use it as a mobile wall. The block cannot "
990 "take stars.", true);
991 break;
992 case 3:
993 #if CONFIG_KEYPAD == RECORDER_PAD
994 star_display_text("KEYS\n\n"
995 "[ON] Toggle Ctl.\n"
996 "[OFF] Exit\n"
997 "[F1] Prev. level\n"
998 "[F2] Reset level\n"
999 "[F3] Next level", true);
1000 #elif CONFIG_KEYPAD == ONDIO_PAD
1001 star_display_text("KEYS\n\n"
1002 "[MODE] Toggle Ctl\n"
1003 "[OFF] Exit\n"
1004 "[M <] Prev. level\n"
1005 "[M ^] Reset level\n"
1006 "[M >] Next level", true);
1007 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
1008 star_display_text("KEYS\n\n"
1009 "[MODE/NAVI] Toggle Ctrl\n"
1010 "[OFF] Exit\n"
1011 "[ON + LEFT] Prev. level\n"
1012 "[ON + NAVI] Reset level\n"
1013 "[ON + RIGHT] Next level", true);
1014 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
1015 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
1016 star_display_text("KEYS\n\n"
1017 "[SELECT] Toggle Ctl\n"
1018 "[S + MENU] Exit\n"
1019 "[S <] Prev. level\n"
1020 "[S + PLAY] Reset level\n"
1021 "[S >] Next level", true);
1022 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
1023 star_display_text("KEYS\n\n"
1024 "[SELECT] Toggle Ctl\n"
1025 "[POWER] Exit\n"
1026 "[REC..] Prev. level\n"
1027 "[PLAY] Reset level\n"
1028 "[REC] Next level", true);
1029 #elif CONFIG_KEYPAD == GIGABEAT_PAD
1030 star_display_text("KEYS\n\n"
1031 "[MENU] Toggle Control\n"
1032 "[A] Exit\n"
1033 "[PWR+DOWN] Prev. level\n"
1034 "[PWR+RIGHT] Reset level\n"
1035 "[PWR+UP] Next level", true);
1036 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
1037 star_display_text("KEYS\n\n"
1038 "[REW] Toggle Ctl\n"
1039 "[POWER] Exit\n"
1040 "[PLAY+DOWN] Prev. level\n"
1041 "[PLAY+RIGHT] Reset level\n"
1042 "[PLAY+UP] Next level", true);
1043 #endif
1044 break;
1045 default:
1046 menu_quit = true;
1047 break;
1051 if (selection == MENU_START)
1053 rb->lcd_setfont(FONT_SYSFIXED);
1054 rb->lcd_getstringsize("a", &char_width, &char_height);
1055 level--;
1056 star_run_game(level);
1059 return PLUGIN_OK;
1063 * Main entry point
1065 enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
1067 (void)parameter;
1068 rb = api;
1070 #if LCD_DEPTH > 1
1071 rb->lcd_set_backdrop(NULL);
1072 rb->lcd_set_background( LCD_BLACK );
1073 rb->lcd_set_foreground( LCD_WHITE );
1074 #endif
1076 /* display choice menu */
1077 return star_menu();
1080 #endif