Fix red in bootloaders
[maemo-rb.git] / apps / plugins / star.c
blob4bb3afcbd5deb21b122097fc8a4d204c75eabbf7
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 Frederic Dang Ngoc
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 ****************************************************************************/
21 #include "plugin.h"
22 #ifdef HAVE_LCD_BITMAP
24 PLUGIN_HEADER
26 /* size of a level in file */
27 #define STAR_LEVEL_SIZE ((STAR_WIDTH + 1) * STAR_HEIGHT + 1)
29 /* size of the game board */
30 #define STAR_WIDTH 16
31 #define STAR_HEIGHT 9
33 /* number of level */
34 #define STAR_LEVEL_COUNT 20
36 /* values of object in the board */
37 #define STAR_VOID '.'
38 #define STAR_WALL '*'
39 #define STAR_STAR 'o'
40 #define STAR_BALL 'X'
41 #define STAR_BLOCK 'x'
43 /* sleep time between two frames */
44 #if (LCD_HEIGHT * LCD_WIDTH >= 70000) && defined(IPOD_ARCH)
45 /* iPod 5G LCD is *slow* */
46 #define STAR_SLEEP rb->yield();
47 #elif (LCD_HEIGHT * LCD_WIDTH >= 30000)
48 #define STAR_SLEEP rb->sleep(0);
49 #else
50 #define STAR_SLEEP rb->sleep(1);
51 #endif
53 /* value of ball and block control */
54 #define STAR_CONTROL_BALL 0
55 #define STAR_CONTROL_BLOCK 1
57 /* variable button definitions */
58 #if CONFIG_KEYPAD == RECORDER_PAD
59 #define STAR_QUIT BUTTON_OFF
60 #define STAR_LEFT BUTTON_LEFT
61 #define STAR_RIGHT BUTTON_RIGHT
62 #define STAR_UP BUTTON_UP
63 #define STAR_DOWN BUTTON_DOWN
64 #define STAR_TOGGLE_CONTROL BUTTON_ON
65 #define STAR_TOGGLE_CONTROL2 BUTTON_PLAY
66 #define STAR_LEVEL_UP BUTTON_F3
67 #define STAR_LEVEL_DOWN BUTTON_F1
68 #define STAR_LEVEL_REPEAT BUTTON_F2
70 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
71 #define STAR_QUIT BUTTON_OFF
72 #define STAR_LEFT BUTTON_LEFT
73 #define STAR_RIGHT BUTTON_RIGHT
74 #define STAR_UP BUTTON_UP
75 #define STAR_DOWN BUTTON_DOWN
76 #define STAR_TOGGLE_CONTROL BUTTON_ON
77 #define STAR_TOGGLE_CONTROL2 BUTTON_SELECT
78 #define STAR_LEVEL_UP BUTTON_F3
79 #define STAR_LEVEL_DOWN BUTTON_F1
80 #define STAR_LEVEL_REPEAT BUTTON_F2
82 #elif CONFIG_KEYPAD == ONDIO_PAD
83 #define STAR_QUIT BUTTON_OFF
84 #define STAR_LEFT BUTTON_LEFT
85 #define STAR_RIGHT BUTTON_RIGHT
86 #define STAR_UP BUTTON_UP
87 #define STAR_DOWN BUTTON_DOWN
88 #define STAR_TOGGLE_CONTROL_PRE BUTTON_MENU
89 #define STAR_TOGGLE_CONTROL (BUTTON_MENU | BUTTON_REL)
90 #define STAR_LEVEL_UP (BUTTON_MENU | BUTTON_RIGHT)
91 #define STAR_LEVEL_DOWN (BUTTON_MENU | BUTTON_LEFT)
92 #define STAR_LEVEL_REPEAT (BUTTON_MENU | BUTTON_UP)
94 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
95 (CONFIG_KEYPAD == IRIVER_H300_PAD)
96 #define STAR_QUIT BUTTON_OFF
97 #define STAR_LEFT BUTTON_LEFT
98 #define STAR_RIGHT BUTTON_RIGHT
99 #define STAR_UP BUTTON_UP
100 #define STAR_DOWN BUTTON_DOWN
101 #define STAR_TOGGLE_CONTROL BUTTON_MODE
102 #define STAR_TOGGLE_CONTROL2 BUTTON_SELECT
103 #define STAR_LEVEL_UP (BUTTON_ON | BUTTON_RIGHT)
104 #define STAR_LEVEL_DOWN (BUTTON_ON | BUTTON_LEFT)
105 #define STAR_LEVEL_REPEAT (BUTTON_ON | BUTTON_SELECT)
107 #define STAR_RC_QUIT BUTTON_RC_STOP
108 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
109 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
110 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
112 #define STAR_QUIT (BUTTON_SELECT | BUTTON_MENU)
113 #define STAR_LEFT BUTTON_LEFT
114 #define STAR_RIGHT BUTTON_RIGHT
115 #define STAR_UP BUTTON_MENU
116 #define STAR_DOWN BUTTON_PLAY
117 #define STAR_TOGGLE_CONTROL_PRE BUTTON_SELECT
118 #define STAR_TOGGLE_CONTROL (BUTTON_SELECT | BUTTON_REL)
119 #define STAR_LEVEL_UP (BUTTON_SELECT | BUTTON_RIGHT)
120 #define STAR_LEVEL_DOWN (BUTTON_SELECT | BUTTON_LEFT)
121 #define STAR_LEVEL_REPEAT (BUTTON_SELECT | BUTTON_PLAY)
123 #elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
125 #define STAR_QUIT BUTTON_POWER
126 #define STAR_LEFT BUTTON_LEFT
127 #define STAR_RIGHT BUTTON_RIGHT
128 #define STAR_UP BUTTON_UP
129 #define STAR_DOWN BUTTON_DOWN
130 #define STAR_TOGGLE_CONTROL BUTTON_SELECT
131 #define STAR_LEVEL_UP_PRE BUTTON_REC
132 #define STAR_LEVEL_UP (BUTTON_REC|BUTTON_REL)
133 #define STAR_LEVEL_DOWN_PRE BUTTON_REC
134 #define STAR_LEVEL_DOWN (BUTTON_REC|BUTTON_REPEAT)
135 #define STAR_LEVEL_REPEAT BUTTON_PLAY
137 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
139 #define STAR_QUIT BUTTON_POWER
140 #define STAR_LEFT BUTTON_LEFT
141 #define STAR_RIGHT BUTTON_RIGHT
142 #define STAR_UP BUTTON_UP
143 #define STAR_DOWN BUTTON_DOWN
144 #define STAR_TOGGLE_CONTROL BUTTON_SELECT
145 #define STAR_LEVEL_UP BUTTON_VOL_UP
146 #define STAR_LEVEL_DOWN BUTTON_VOL_DOWN
147 #define STAR_LEVEL_REPEAT BUTTON_A
149 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
150 (CONFIG_KEYPAD == SANSA_C200_PAD) || \
151 (CONFIG_KEYPAD == SANSA_CLIP_PAD) || \
152 (CONFIG_KEYPAD == SANSA_M200_PAD)
154 #define STAR_QUIT BUTTON_POWER
155 #define STAR_LEFT BUTTON_LEFT
156 #define STAR_RIGHT BUTTON_RIGHT
157 #define STAR_UP BUTTON_UP
158 #define STAR_DOWN BUTTON_DOWN
159 #define STAR_TOGGLE_CONTROL BUTTON_SELECT
160 #define STAR_LEVEL_UP (BUTTON_SELECT | BUTTON_RIGHT)
161 #define STAR_LEVEL_DOWN (BUTTON_SELECT | BUTTON_LEFT)
162 #define STAR_LEVEL_REPEAT (BUTTON_SELECT | BUTTON_DOWN)
165 #elif (CONFIG_KEYPAD == SANSA_FUZE_PAD)
167 #define STAR_QUIT (BUTTON_HOME|BUTTON_REPEAT)
168 #define STAR_LEFT BUTTON_LEFT
169 #define STAR_RIGHT BUTTON_RIGHT
170 #define STAR_UP BUTTON_UP
171 #define STAR_DOWN BUTTON_DOWN
172 #define STAR_TOGGLE_CONTROL BUTTON_SELECT
173 #define STAR_LEVEL_UP (BUTTON_SELECT | BUTTON_RIGHT)
174 #define STAR_LEVEL_DOWN (BUTTON_SELECT | BUTTON_LEFT)
175 #define STAR_LEVEL_REPEAT (BUTTON_SELECT | BUTTON_DOWN)
177 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
179 #define STAR_QUIT BUTTON_POWER
180 #define STAR_LEFT BUTTON_LEFT
181 #define STAR_RIGHT BUTTON_RIGHT
182 #define STAR_UP BUTTON_SCROLL_UP
183 #define STAR_DOWN BUTTON_SCROLL_DOWN
184 #define STAR_TOGGLE_CONTROL BUTTON_REW
185 #define STAR_LEVEL_UP (BUTTON_PLAY | BUTTON_SCROLL_UP)
186 #define STAR_LEVEL_DOWN (BUTTON_PLAY | BUTTON_SCROLL_DOWN)
187 #define STAR_LEVEL_REPEAT (BUTTON_PLAY | BUTTON_RIGHT)
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
201 #elif (CONFIG_KEYPAD == MROBE100_PAD)
203 #define STAR_QUIT BUTTON_POWER
204 #define STAR_LEFT BUTTON_LEFT
205 #define STAR_RIGHT BUTTON_RIGHT
206 #define STAR_UP BUTTON_UP
207 #define STAR_DOWN BUTTON_DOWN
208 #define STAR_TOGGLE_CONTROL BUTTON_SELECT
209 #define STAR_LEVEL_UP BUTTON_PLAY
210 #define STAR_LEVEL_DOWN BUTTON_MENU
211 #define STAR_LEVEL_REPEAT BUTTON_DISPLAY
213 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
215 #define STAR_QUIT BUTTON_RC_REC
216 #define STAR_LEFT BUTTON_RC_REW
217 #define STAR_RIGHT BUTTON_RC_FF
218 #define STAR_UP BUTTON_RC_VOL_UP
219 #define STAR_DOWN BUTTON_RC_VOL_DOWN
220 #define STAR_TOGGLE_CONTROL BUTTON_RC_MODE
221 #define STAR_LEVEL_UP (BUTTON_RC_PLAY|BUTTON_RC_VOL_UP)
222 #define STAR_LEVEL_DOWN (BUTTON_RC_PLAY|BUTTON_RC_VOL_DOWN)
223 #define STAR_LEVEL_REPEAT (BUTTON_RC_PLAY|BUTTON_RC_MENU)
225 #elif (CONFIG_KEYPAD == COWOND2_PAD)
227 #define STAR_QUIT BUTTON_POWER
228 #define STAR_QUIT_NAME "[POWER]"
230 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
232 #define STAR_QUIT BUTTON_BACK
233 #define STAR_LEFT BUTTON_LEFT
234 #define STAR_RIGHT BUTTON_RIGHT
235 #define STAR_UP BUTTON_UP
236 #define STAR_DOWN BUTTON_DOWN
237 #define STAR_TOGGLE_CONTROL BUTTON_PLAY
238 #define STAR_LEVEL_UP (BUTTON_CUSTOM | BUTTON_UP)
239 #define STAR_LEVEL_DOWN (BUTTON_CUSTOM | BUTTON_DOWN)
240 #define STAR_LEVEL_REPEAT (BUTTON_CUSTOM | BUTTON_RIGHT)
242 #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
244 #define STAR_QUIT BUTTON_POWER
245 #define STAR_LEFT BUTTON_LEFT
246 #define STAR_RIGHT BUTTON_RIGHT
247 #define STAR_UP BUTTON_UP
248 #define STAR_DOWN BUTTON_DOWN
249 #define STAR_TOGGLE_CONTROL BUTTON_SELECT
250 #define STAR_LEVEL_UP BUTTON_VOL_UP
251 #define STAR_LEVEL_DOWN BUTTON_VOL_DOWN
252 #define STAR_LEVEL_REPEAT BUTTON_VIEW
254 #elif (CONFIG_KEYPAD == ONDAVX747_PAD)
256 #define STAR_QUIT BUTTON_POWER
257 #define STAR_QUIT_NAME "[POWER]"
259 #elif CONFIG_KEYPAD == MROBE500_PAD
260 #define STAR_QUIT BUTTON_POWER
261 #define STAR_QUIT_NAME "[POWER]"
263 #else
264 #error No keymap defined!
265 #endif
267 #ifdef HAVE_TOUCHSCREEN
268 //#ifndef STAR_QUIT
269 //#define STAR_QUIT BUTTON_TOPLEFT
270 //#define STAR_QUIT_NAME "[TOPLEFT]"
271 //#endif
272 #ifndef STAR_LEFT
273 #define STAR_LEFT BUTTON_MIDLEFT
274 #endif
275 #ifndef STAR_RIGHT
276 #define STAR_RIGHT BUTTON_MIDRIGHT
277 #endif
278 #ifndef STAR_UP
279 #define STAR_UP BUTTON_TOPMIDDLE
280 #endif
281 #ifndef STAR_DOWN
282 #define STAR_DOWN BUTTON_BOTTOMMIDDLE
283 #endif
284 #ifndef STAR_TOGGLE_CONTROL
285 #define STAR_TOGGLE_CONTROL BUTTON_CENTER
286 #define STAR_TOGGLE_CONTROL_NAME "[CENTER]"
287 #endif
288 #ifndef STAR_LEVEL_UP
289 #define STAR_LEVEL_UP BUTTON_TOPLEFT
290 #define STAR_LEVEL_UP_NAME "[TOPLEFT]"
291 #endif
292 #ifndef STAR_LEVEL_DOWN
293 #define STAR_LEVEL_DOWN BUTTON_BOTTOMLEFT
294 #define STAR_LEVEL_DOWN_NAME "[BOTTOMLEFT]"
295 #endif
296 #ifndef STAR_LEVEL_REPEAT
297 #define STAR_LEVEL_REPEAT BUTTON_BOTTOMRIGHT
298 #define STAR_LEVEL_REPEAT_NAME "[BOTTOMRIGHT]"
299 #endif
300 #endif
302 /* function returns because of USB? */
303 static bool usb_detected = false;
305 /* position of the ball */
306 static int ball_x, ball_y;
308 /* position of the block */
309 static int block_x, block_y;
311 /* number of stars to get to finish the level */
312 static int star_count;
314 /* the object we control : ball or block */
315 static int control;
317 /* the current board */
318 static char board[STAR_HEIGHT][STAR_WIDTH];
320 #include "pluginbitmaps/star_tiles.h"
322 #define TILE_WIDTH BMPWIDTH_star_tiles
323 #define TILE_HEIGHT (BMPHEIGHT_star_tiles/5)
324 #define STAR_OFFSET_X ((LCD_WIDTH - STAR_WIDTH * TILE_WIDTH) / 2)
325 #define STAR_OFFSET_Y ((LCD_HEIGHT - STAR_HEIGHT * TILE_HEIGHT - MAX(TILE_HEIGHT, 8)) / 2)
327 #define WALL 0
328 #define SPACE 1
329 #define BLOCK 2
330 #define STAR 3
331 #define BALL 4
333 #define MENU_START 0
335 /* char font size */
336 static int char_width = -1;
337 static int char_height = -1;
339 /* this arrays contains a group of levels loaded into memory */
340 static unsigned char* levels =
341 "****************\n"
342 "*X**........o*x*\n"
343 "*..........o.***\n"
344 "*.......**o....*\n"
345 "*...**.o......**\n"
346 "**.o..o.....o..*\n"
347 "*.o......o**.o.*\n"
348 "*.....**o.....o*\n"
349 "****************\n"
350 "\n"
351 ".*..*.*.*...*.**\n"
352 "*...o.........X*\n"
353 "...*o..*o...o...\n"
354 "*.*.o.....o..*.*\n"
355 "......*...o...*.\n"
356 "*....*x*..o....*\n"
357 "...*..*.*...*oo*\n"
358 "*.............*.\n"
359 ".*..*........*..\n"
360 "\n"
361 "****************\n"
362 "*...........o*x*\n"
363 "*...**......**X*\n"
364 "*...*o.........*\n"
365 "*.o.....o**...o*\n"
366 "*.*o..o..o*..o**\n"
367 "*.**o.*o..o.o***\n"
368 "*o....**o......*\n"
369 "****************\n"
370 "\n"
371 "****************\n"
372 "*............*x*\n"
373 "*.....*........*\n"
374 "**o*o.o*o*o*o*o*\n"
375 "*.*.*o.o*.*.*.**\n"
376 "**o*o*o.o*o*o*o*\n"
377 "*.....*........*\n"
378 "*...*.......*X.*\n"
379 "****************\n"
380 "\n"
381 ".**************.\n"
382 "*X..*...*..*...*\n"
383 "*..*o.*.o..o.*.*\n"
384 "**......*..*...*\n"
385 "*o.*o*........**\n"
386 "**.....*.o.*...*\n"
387 "*o*..*.*.*...*x*\n"
388 "*...*....o*..*o*\n"
389 ".**************.\n"
390 "\n"
391 "....************\n"
392 "...*...o...*o.o*\n"
393 "..*....o....*.**\n"
394 ".*.....o.......*\n"
395 "*X.....o.......*\n"
396 "**.....o..*...**\n"
397 "*......o....*..*\n"
398 "*x.*...o..**o..*\n"
399 "****************\n"
400 "\n"
401 "****************\n"
402 "*..............*\n"
403 ".**.***..*o.**o*\n"
404 ".*o..*o.*.*.*.*.\n"
405 "..*..*..***.**..\n"
406 ".**..*..*o*.*o**\n"
407 "*..............*\n"
408 "*..X*o....x..*o*\n"
409 "****************\n"
410 "\n"
411 "***************.\n"
412 "*..o**.........*\n"
413 "*..*o..**.o....*\n"
414 "*..o**.*.*o....*\n"
415 "**.....**..*o*.*\n"
416 "**.*.......o*o.*\n"
417 "*oxo*...o..*X*.*\n"
418 "**.............*\n"
419 ".***************\n"
420 "\n"
421 "..*.***********.\n"
422 ".*o*o......*..X*\n"
423 "*o.o*....o....*.\n"
424 ".*.*..o**..o*..*\n"
425 "*..*o.*oxo....o*\n"
426 "*.....o**.....*.\n"
427 "*o*o.........*..\n"
428 "*...........*...\n"
429 ".***********....\n"
430 "\n"
431 "....***********.\n"
432 "*****.o........*\n"
433 "*...x.***o.o*.o*\n"
434 "*.o...*o.*o...*.\n"
435 "*.....*..o..*.o*\n"
436 "*o*o..*.o*..*X*.\n"
437 ".*o...***..***..\n"
438 "*.........*.*.*.\n"
439 ".*********..*..*\n"
440 "\n"
441 "****************\n"
442 "*......*......X*\n"
443 "*..*oo.....oo.**\n"
444 "**...o...**...o*\n"
445 "*o....*o*oo..***\n"
446 "**.**....**....*\n"
447 "*o..o*.o....x.o*\n"
448 "**o***....*...**\n"
449 "***************.\n"
450 "\n"
451 "**.....**..****.\n"
452 "*X*****o.***.o**\n"
453 "*....oo.....o..*\n"
454 "*.**..**o..*o*.*\n"
455 "*.*.o.*.*o.**..*\n"
456 "*.**..**...*x*.*\n"
457 "*.....o........*\n"
458 "*........o.....*\n"
459 "****************\n"
460 "\n"
461 ".**************.\n"
462 "*.X*........o.**\n"
463 "*.*...*o...o**.*\n"
464 "*.......o....*.*\n"
465 "*.o..........*o*\n"
466 "*.*......o.....*\n"
467 "**......o.o..*o*\n"
468 "*x..*....o.*.*.*\n"
469 ".**************.\n"
470 "\n"
471 "****************\n"
472 "*o*o........o*o*\n"
473 "*.o*X......**..*\n"
474 "*.x........o...*\n"
475 "*........o*....*\n"
476 "*......o.......*\n"
477 "*.o*........*..*\n"
478 "*o*o........o*o*\n"
479 "****************\n"
480 "\n"
481 ".******.********\n"
482 "*.....o*.....o.*\n"
483 "*.*.o.*..*...o.*\n"
484 "*..X*...*oo.*o.*\n"
485 ".*.*...*.o..x*.*\n"
486 "*o.......*..*o.*\n"
487 ".*......o.....*.\n"
488 "*o............o*\n"
489 "****************\n"
490 "\n"
491 "****************\n"
492 "**.x*o.o......o*\n"
493 "*o.Xo*o.......**\n"
494 "**.***........**\n"
495 "**.....o*o*....*\n"
496 "*oo.......o*o..*\n"
497 "**.o....****o..*\n"
498 "**o*..*........*\n"
499 "****************\n"
500 "\n"
501 "****************\n"
502 "*.o*........*X.*\n"
503 "*.*..o*oo*o..*.*\n"
504 "*....*o**o*.o..*\n"
505 "*.o*.......o*..*\n"
506 "*..o*o....o*...*\n"
507 "*.*..*.**o*..*.*\n"
508 "*....o.*o...x..*\n"
509 "****************\n"
510 "\n"
511 "****************\n"
512 "*.o....o..x*...*\n"
513 "*..*o*o...*o...*\n"
514 "*...*o*....*o..*\n"
515 "*...o..*...o*o.*\n"
516 "*.*o*...*.o*...*\n"
517 "*.o*o.*.o.*....*\n"
518 "*o*X..*.....*..*\n"
519 "****************\n"
520 "\n"
521 "****************\n"
522 "*o...**.....**o*\n"
523 "*.*..*......*o.*\n"
524 "*.o*...o**..o..*\n"
525 "*.*....*o......*\n"
526 "*....*...o*....*\n"
527 "*.**.o*.**o..*x*\n"
528 "*.o*.*o.....**X*\n"
529 "****************\n"
530 "\n"
531 "****************\n"
532 "*...o*o........*\n"
533 "**o..o*.**o...**\n"
534 "*.*.*.o...*..*.*\n"
535 "*.x.*..**..*.Xo*\n"
536 "*.*..*...o.*.*.*\n"
537 "**...o**.*o..o**\n"
538 "*........o*o...*\n"
539 "****************";
542 * Display text.
544 void star_display_text(char *str, bool waitkey)
546 int chars_by_line;
547 int lines_by_screen;
548 int chars_for_line;
549 int current_line = 0;
550 int first_char_index = 0;
551 char *ptr_char;
552 char *ptr_line;
553 int i;
554 char line[255];
555 int key;
556 bool go_on;
558 rb->lcd_clear_display();
560 chars_by_line = LCD_WIDTH / char_width;
561 lines_by_screen = LCD_HEIGHT / char_height;
565 ptr_char = str + first_char_index;
566 chars_for_line = 0;
567 i = 0;
568 ptr_line = line;
569 while (i < chars_by_line)
571 switch (*ptr_char)
573 case '\t':
574 case ' ':
575 *(ptr_line++) = ' ';
576 case '\n':
577 case '\0':
578 chars_for_line = i;
579 break;
581 default:
582 *(ptr_line++) = *ptr_char;
584 if (*ptr_char == '\n' || *ptr_char == '\0')
585 break;
586 ptr_char++;
587 i++;
590 if (chars_for_line == 0)
591 chars_for_line = i;
593 line[chars_for_line] = '\0';
595 /* test if we have cut a word. If it is the case we don't have to */
596 /* skip the space */
597 if (i == chars_by_line && chars_for_line == chars_by_line)
598 first_char_index += chars_for_line;
599 else
600 first_char_index += chars_for_line + 1;
602 /* print the line on the screen */
603 rb->lcd_putsxy(0, current_line * char_height, line);
605 /* if the number of line showed on the screen is equals to the */
606 /* maximum number of line we can show, we wait for a key pressed to */
607 /* clear and show the remaining text. */
608 current_line++;
609 if (current_line == lines_by_screen || *ptr_char == '\0')
611 current_line = 0;
612 rb->lcd_update();
613 go_on = false;
614 while (waitkey && !go_on)
616 key = rb->button_get(true);
617 switch (key)
619 case STAR_QUIT:
620 case STAR_LEFT:
621 case STAR_DOWN:
622 go_on = true;
623 break;
625 default:
626 if (rb->default_event_handler(key) == SYS_USB_CONNECTED)
628 usb_detected = true;
629 go_on = true;
630 break;
634 rb->lcd_clear_display();
636 } while (*ptr_char != '\0');
640 * Do a pretty transition from one level to another.
642 static void star_transition_update(void)
644 const int center_x = LCD_WIDTH / 2;
645 const int center_y = LCD_HEIGHT / 2;
646 int x = 0;
647 int y = 0;
648 #if LCD_WIDTH >= LCD_HEIGHT
649 #if defined(IPOD_VIDEO)
650 const int step = 4;
651 #else
652 const int step = 1;
653 #endif
654 const int lcd_demi_width = LCD_WIDTH / 2;
655 int var_y = 0;
657 for (; x < lcd_demi_width ; x+=step)
659 var_y += LCD_HEIGHT;
660 if (var_y > LCD_WIDTH)
662 var_y -= LCD_WIDTH;
663 y+=step;
665 if( x )
667 rb->lcd_update_rect(center_x - x, center_y - y, x*2, step);
668 rb->lcd_update_rect(center_x - x, center_y + y - step, x*2, step);
670 if( y )
672 rb->lcd_update_rect(center_x - x, center_y - y, step, y*2);
673 rb->lcd_update_rect(center_x + x - step, center_y - y, step, y*2);
675 STAR_SLEEP
677 #else
678 int lcd_demi_height = LCD_HEIGHT / 2;
679 int var_x = 0;
681 for (; y < lcd_demi_height ; y++)
683 var_x += LCD_WIDTH;
684 if (var_x > LCD_HEIGHT)
686 var_x -= LCD_HEIGHT;
687 x++;
689 if( x )
691 rb->lcd_update_rect(center_x - x, center_y - y, x * 2, 1);
692 rb->lcd_update_rect(center_x - x, center_y + y - 1, x * 2, 1);
694 if( y )
696 rb->lcd_update_rect(center_x - x, center_y - y, 1, y * 2);
697 rb->lcd_update_rect(center_x + x - 1, center_y - y, 1, y * 2);
699 STAR_SLEEP
701 #endif
702 rb->lcd_update();
706 * Display information board of the current level.
708 static void star_display_board_info(int current_level)
710 int label_pos_y, tile_pos_y;
711 char str_info[32];
713 if (TILE_HEIGHT > char_height)
715 tile_pos_y = LCD_HEIGHT - TILE_HEIGHT;
716 label_pos_y = tile_pos_y + (TILE_HEIGHT - char_height) / 2;
718 else
720 label_pos_y = LCD_HEIGHT - char_height;
721 tile_pos_y = label_pos_y + (char_height - TILE_HEIGHT) / 2;
724 rb->snprintf(str_info, sizeof(str_info), "L:%02d", current_level + 1);
725 rb->lcd_putsxy(STAR_OFFSET_X, label_pos_y, str_info);
726 rb->snprintf(str_info, sizeof(str_info), "S:%02d", star_count);
727 rb->lcd_putsxy(LCD_WIDTH/2 - 2 * char_width, label_pos_y, str_info);
728 rb->lcd_putsxy(STAR_OFFSET_X + (STAR_WIDTH-1) * TILE_WIDTH - 2 * char_width,
729 label_pos_y, "C:");
731 rb->lcd_bitmap_part(star_tiles, 0, control == STAR_CONTROL_BALL ?
732 BALL*TILE_HEIGHT : BLOCK*TILE_HEIGHT, TILE_WIDTH,
733 STAR_OFFSET_X + (STAR_WIDTH-1) * TILE_WIDTH,
734 tile_pos_y, TILE_WIDTH, TILE_HEIGHT);
736 rb->lcd_update_rect(0, MIN(label_pos_y, tile_pos_y), LCD_WIDTH,
737 MAX(TILE_HEIGHT, char_height));
742 * Load a level into board array.
744 static int star_load_level(int current_level)
746 int x, y;
747 char *ptr_tab;
749 if (current_level < 0)
750 current_level = 0;
751 else if (current_level > STAR_LEVEL_COUNT-1)
752 current_level = STAR_LEVEL_COUNT-1;
755 ptr_tab = levels + current_level * STAR_LEVEL_SIZE;
756 control = STAR_CONTROL_BALL;
757 star_count = 0;
759 rb->lcd_clear_display();
761 for (y = 0 ; y < STAR_HEIGHT ; y++)
763 for (x = 0 ; x < STAR_WIDTH ; x++)
765 board[y][x] = *ptr_tab;
766 switch (*ptr_tab)
768 # define DRAW_TILE( a ) \
769 rb->lcd_bitmap_part( star_tiles, 0, \
770 a*TILE_HEIGHT, TILE_WIDTH, \
771 STAR_OFFSET_X + x * TILE_WIDTH, \
772 STAR_OFFSET_Y + y * TILE_HEIGHT, \
773 TILE_WIDTH, TILE_HEIGHT);
774 case STAR_VOID:
775 DRAW_TILE( SPACE );
776 break;
778 case STAR_WALL:
779 DRAW_TILE( WALL );
780 break;
782 case STAR_STAR:
783 DRAW_TILE( STAR );
784 star_count++;
785 break;
787 case STAR_BALL:
788 ball_x = x;
789 ball_y = y;
790 DRAW_TILE( BALL );
791 break;
794 case STAR_BLOCK:
795 block_x = x;
796 block_y = y;
797 DRAW_TILE( BLOCK );
798 break;
800 ptr_tab++;
802 ptr_tab++;
804 star_display_board_info(current_level);
805 star_transition_update();
806 return 1;
809 static void star_animate_tile(int tile_no, int start_x, int start_y,
810 int delta_x, int delta_y)
812 int i;
814 if (delta_x != 0) /* horizontal */
816 for (i = 1 ; i <= TILE_WIDTH ; i++)
818 STAR_SLEEP
819 rb->lcd_bitmap_part(star_tiles, 0, SPACE * TILE_HEIGHT, TILE_WIDTH,
820 start_x, start_y, TILE_WIDTH, TILE_HEIGHT);
821 rb->lcd_bitmap_part(star_tiles, 0, tile_no * TILE_HEIGHT, TILE_WIDTH,
822 start_x + delta_x * i, start_y, TILE_WIDTH, TILE_HEIGHT);
823 rb->lcd_update_rect(start_x + delta_x * i - (delta_x>0?1:0),
824 start_y, TILE_WIDTH + 1, TILE_HEIGHT);
827 else /* vertical */
829 for (i = 1 ; i <= TILE_HEIGHT ; i++)
831 STAR_SLEEP
832 rb->lcd_bitmap_part(star_tiles, 0, SPACE * TILE_HEIGHT, TILE_WIDTH,
833 start_x, start_y, TILE_WIDTH, TILE_HEIGHT);
834 rb->lcd_bitmap_part(star_tiles, 0, tile_no * TILE_HEIGHT, TILE_WIDTH,
835 start_x, start_y + delta_y * i, TILE_WIDTH, TILE_HEIGHT);
836 rb->lcd_update_rect(start_x, start_y + delta_y * i - (delta_y>0?1:0),
837 TILE_WIDTH, TILE_HEIGHT + 1);
843 * Run the game.
845 static int star_run_game(int current_level)
847 int move_x = 0;
848 int move_y = 0;
849 int key;
850 int lastkey = BUTTON_NONE;
852 int label_offset_y;
854 label_offset_y = LCD_HEIGHT - char_height;
856 if (!star_load_level(current_level))
857 return 0;
859 while (true)
861 move_x = 0;
862 move_y = 0;
864 while ((move_x == 0) && (move_y == 0))
866 key = rb->button_get(true);
867 switch (key)
869 #ifdef STAR_RC_QUIT
870 case STAR_RC_QUIT:
871 #endif
872 case STAR_QUIT:
873 return -1;
875 case STAR_LEFT:
876 move_x = -1;
877 break;
879 case STAR_RIGHT:
880 move_x = 1;
881 break;
883 case STAR_UP:
884 move_y = -1;
885 break;
887 case STAR_DOWN:
888 move_y = 1;
889 break;
891 case STAR_LEVEL_DOWN:
892 #ifdef STAR_LEVEL_DOWN_PRE
893 if (lastkey != STAR_LEVEL_DOWN_PRE)
894 break;
895 #endif
896 if (current_level > 0)
898 current_level--;
899 star_load_level(current_level);
901 break;
903 case STAR_LEVEL_REPEAT:
904 star_load_level(current_level);
905 break;
907 case STAR_LEVEL_UP:
908 #ifdef STAR_LEVEL_UP_PRE
909 if (lastkey != STAR_LEVEL_UP_PRE)
910 break;
911 #endif
912 if (current_level < STAR_LEVEL_COUNT - 1)
914 current_level++;
915 star_load_level(current_level);
917 break;
919 case STAR_TOGGLE_CONTROL:
920 #ifdef STAR_TOGGLE_CONTROL_PRE
921 if (lastkey != STAR_TOGGLE_CONTROL_PRE)
922 break;
923 #endif
924 #ifdef STAR_TOGGLE_CONTROL2
925 case STAR_TOGGLE_CONTROL2:
926 #endif
927 if (control == STAR_CONTROL_BALL)
928 control = STAR_CONTROL_BLOCK;
929 else
930 control = STAR_CONTROL_BALL;
931 star_display_board_info(current_level);
932 break;
934 default:
935 if (rb->default_event_handler(key) == SYS_USB_CONNECTED)
937 usb_detected = true;
938 return 0;
940 break;
942 if (key != BUTTON_NONE)
943 lastkey = key;
946 if (control == STAR_CONTROL_BALL)
948 board[ball_y][ball_x] = STAR_VOID;
949 while ((board[ball_y + move_y][ball_x + move_x] == STAR_VOID
950 || board[ball_y + move_y][ball_x + move_x] == STAR_STAR))
953 star_animate_tile(BALL, STAR_OFFSET_X + ball_x * TILE_WIDTH,
954 STAR_OFFSET_Y + ball_y * TILE_HEIGHT,
955 move_x, move_y);
956 ball_x += move_x;
957 ball_y += move_y;
959 if (board[ball_y][ball_x] == STAR_STAR)
961 board[ball_y][ball_x] = STAR_VOID;
962 star_count--;
964 star_display_board_info(current_level);
967 board[ball_y][ball_x] = STAR_BALL;
969 else
971 board[block_y][block_x] = STAR_VOID;
972 while (board[block_y + move_y][block_x + move_x] == STAR_VOID)
974 star_animate_tile(BLOCK, STAR_OFFSET_X + block_x * TILE_WIDTH,
975 STAR_OFFSET_Y + block_y * TILE_HEIGHT,
976 move_x, move_y);
977 block_x += move_x;
978 block_y += move_y;
980 board[block_y][block_x] = STAR_BLOCK;
983 if (star_count == 0)
985 current_level++;
986 if (current_level == STAR_LEVEL_COUNT)
988 rb->lcd_clear_display();
989 star_display_text("Congratulations!", true);
990 rb->lcd_update();
992 /* There is no such level as STAR_LEVEL_COUNT so it can't be the
993 * current_level */
994 current_level--;
995 return 1;
997 star_load_level(current_level);
1003 * Display the choice menu.
1005 static int star_menu(void)
1007 int selection, level=1;
1008 bool menu_quit = false;
1009 /* get the size of char */
1010 rb->lcd_getstringsize("a", &char_width, &char_height);
1012 MENUITEM_STRINGLIST(menu,"Star Menu",NULL,"Play","Choose Level",
1013 "Information","Keys","Quit");
1015 while(!menu_quit)
1017 switch(rb->do_menu(&menu, &selection, NULL, false))
1019 case 0:
1020 menu_quit = true;
1021 break;
1022 case 1:
1023 rb->set_int("Level", "", UNIT_INT, &level,
1024 NULL, 1, 1, STAR_LEVEL_COUNT, NULL );
1025 break;
1026 case 2:
1027 star_display_text(
1028 "INFO\n\n"
1029 "Take all the stars to go to the next level. "
1030 "You can toggle control with the block to "
1031 "use it as a mobile wall. The block cannot "
1032 "take stars.", true);
1033 break;
1034 case 3:
1035 #if CONFIG_KEYPAD == RECORDER_PAD
1036 star_display_text("KEYS\n\n"
1037 "[ON] Toggle Ctl.\n"
1038 "[OFF] Exit\n"
1039 "[F1] Prev. level\n"
1040 "[F2] Reset level\n"
1041 "[F3] Next level", true);
1042 #elif CONFIG_KEYPAD == ONDIO_PAD
1043 star_display_text("KEYS\n\n"
1044 "[MODE] Toggle Ctl\n"
1045 "[OFF] Exit\n"
1046 "[M <] Prev. level\n"
1047 "[M ^] Reset level\n"
1048 "[M >] Next level", true);
1049 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
1050 star_display_text("KEYS\n\n"
1051 "[MODE/NAVI] Toggle Ctrl\n"
1052 "[OFF] Exit\n"
1053 "[ON + LEFT] Prev. level\n"
1054 "[ON + NAVI] Reset level\n"
1055 "[ON + RIGHT] Next level", true);
1056 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
1057 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
1058 star_display_text("KEYS\n\n"
1059 "[SELECT] Toggle Ctl\n"
1060 "[S + MENU] Exit\n"
1061 "[S <] Prev. level\n"
1062 "[S + PLAY] Reset level\n"
1063 "[S >] Next level", true);
1064 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
1065 star_display_text("KEYS\n\n"
1066 "[SELECT] Toggle Ctl\n"
1067 "[POWER] Exit\n"
1068 "[REC..] Prev. level\n"
1069 "[PLAY] Reset level\n"
1070 "[REC] Next level", true);
1071 #elif CONFIG_KEYPAD == GIGABEAT_PAD
1072 star_display_text("KEYS\n\n"
1073 "[SELECT] Toggle Control\n"
1074 "[POWER] Exit\n"
1075 "[VOL DOWN] Prev. level\n"
1076 "[A] Reset level\n"
1077 "[VOL UP] Next level", true);
1078 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
1079 star_display_text("KEYS\n\n"
1080 "[REW] Toggle Ctl\n"
1081 "[POWER] Exit\n"
1082 "[PLAY+DOWN] Prev. level\n"
1083 "[PLAY+RIGHT] Reset level\n"
1084 "[PLAY+UP] Next level", true);
1085 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
1086 star_display_text("KEYS\n\n"
1087 "[SELECT] Toggle Control\n"
1088 "[BACK] Exit\n"
1089 "[VOL DOWN] Prev. level\n"
1090 "[MENU] Reset level\n"
1091 "[VOL UP] Next level", true);
1092 #endif
1093 #ifdef HAVE_TOUCHSCREEN
1094 star_display_text("KEYS\n\n"
1095 STAR_TOGGLE_CONTROL_NAME " Toggle Control\n"
1096 STAR_QUIT_NAME " Exit\n"
1097 STAR_LEVEL_DOWN_NAME " Prev. level\n"
1098 STAR_LEVEL_REPEAT_NAME " Reset level\n"
1099 STAR_LEVEL_UP_NAME " Next level", true);
1100 #endif
1101 break;
1102 default:
1103 menu_quit = true;
1104 break;
1108 if (selection == MENU_START)
1110 rb->lcd_setfont(FONT_SYSFIXED);
1111 rb->lcd_getstringsize("a", &char_width, &char_height);
1112 level--;
1113 star_run_game(level);
1115 return PLUGIN_OK;
1119 * Main entry point
1121 enum plugin_status plugin_start(const void* parameter)
1123 (void)parameter;
1125 #if LCD_DEPTH > 1
1126 rb->lcd_set_backdrop(NULL);
1127 rb->lcd_set_background( LCD_BLACK );
1128 rb->lcd_set_foreground( LCD_WHITE );
1129 #endif
1131 /* display choice menu */
1132 return star_menu();
1135 #endif