Reverting parts of r19760 that was mistakenly committed.
[kugel-rb.git] / apps / plugins / star.c
blob2c4be27c34c193ce03256c31ee294f8092a5dfc4
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
69 #define STAR_MENU_RUN BUTTON_PLAY
70 #define STAR_MENU_RUN2 BUTTON_RIGHT
71 #define STAR_MENU_RUN3 BUTTON_ON
73 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
74 #define STAR_QUIT BUTTON_OFF
75 #define STAR_LEFT BUTTON_LEFT
76 #define STAR_RIGHT BUTTON_RIGHT
77 #define STAR_UP BUTTON_UP
78 #define STAR_DOWN BUTTON_DOWN
79 #define STAR_TOGGLE_CONTROL BUTTON_ON
80 #define STAR_TOGGLE_CONTROL2 BUTTON_SELECT
81 #define STAR_LEVEL_UP BUTTON_F3
82 #define STAR_LEVEL_DOWN BUTTON_F1
83 #define STAR_LEVEL_REPEAT BUTTON_F2
84 #define STAR_MENU_RUN BUTTON_SELECT
85 #define STAR_MENU_RUN2 BUTTON_RIGHT
86 #define STAR_MENU_RUN3 BUTTON_ON
88 #elif CONFIG_KEYPAD == ONDIO_PAD
89 #define STAR_QUIT BUTTON_OFF
90 #define STAR_LEFT BUTTON_LEFT
91 #define STAR_RIGHT BUTTON_RIGHT
92 #define STAR_UP BUTTON_UP
93 #define STAR_DOWN BUTTON_DOWN
94 #define STAR_TOGGLE_CONTROL_PRE BUTTON_MENU
95 #define STAR_TOGGLE_CONTROL (BUTTON_MENU | BUTTON_REL)
96 #define STAR_LEVEL_UP (BUTTON_MENU | BUTTON_RIGHT)
97 #define STAR_LEVEL_DOWN (BUTTON_MENU | BUTTON_LEFT)
98 #define STAR_LEVEL_REPEAT (BUTTON_MENU | BUTTON_UP)
99 #define STAR_MENU_RUN BUTTON_RIGHT
101 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
102 (CONFIG_KEYPAD == IRIVER_H300_PAD)
103 #define STAR_QUIT BUTTON_OFF
104 #define STAR_LEFT BUTTON_LEFT
105 #define STAR_RIGHT BUTTON_RIGHT
106 #define STAR_UP BUTTON_UP
107 #define STAR_DOWN BUTTON_DOWN
108 #define STAR_TOGGLE_CONTROL BUTTON_MODE
109 #define STAR_TOGGLE_CONTROL2 BUTTON_SELECT
110 #define STAR_LEVEL_UP (BUTTON_ON | BUTTON_RIGHT)
111 #define STAR_LEVEL_DOWN (BUTTON_ON | BUTTON_LEFT)
112 #define STAR_LEVEL_REPEAT (BUTTON_ON | BUTTON_SELECT)
113 #define STAR_MENU_RUN BUTTON_RIGHT
114 #define STAR_MENU_RUN2 BUTTON_SELECT
116 #define STAR_RC_QUIT BUTTON_RC_STOP
117 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
118 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
119 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
121 #define STAR_QUIT (BUTTON_SELECT | BUTTON_MENU)
122 #define STAR_LEFT BUTTON_LEFT
123 #define STAR_RIGHT BUTTON_RIGHT
124 #define STAR_UP BUTTON_MENU
125 #define STAR_DOWN BUTTON_PLAY
126 #define STAR_TOGGLE_CONTROL_PRE BUTTON_SELECT
127 #define STAR_TOGGLE_CONTROL (BUTTON_SELECT | BUTTON_REL)
128 #define STAR_LEVEL_UP (BUTTON_SELECT | BUTTON_RIGHT)
129 #define STAR_LEVEL_DOWN (BUTTON_SELECT | BUTTON_LEFT)
130 #define STAR_LEVEL_REPEAT (BUTTON_SELECT | BUTTON_PLAY)
131 #define STAR_MENU_RUN BUTTON_RIGHT
132 #define STAR_MENU_RUN2 BUTTON_SELECT
134 #elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
136 #define STAR_QUIT BUTTON_POWER
137 #define STAR_LEFT BUTTON_LEFT
138 #define STAR_RIGHT BUTTON_RIGHT
139 #define STAR_UP BUTTON_UP
140 #define STAR_DOWN BUTTON_DOWN
141 #define STAR_TOGGLE_CONTROL BUTTON_SELECT
142 #define STAR_LEVEL_UP_PRE BUTTON_REC
143 #define STAR_LEVEL_UP (BUTTON_REC|BUTTON_REL)
144 #define STAR_LEVEL_DOWN_PRE BUTTON_REC
145 #define STAR_LEVEL_DOWN (BUTTON_REC|BUTTON_REPEAT)
146 #define STAR_LEVEL_REPEAT BUTTON_PLAY
147 #define STAR_MENU_RUN BUTTON_RIGHT
148 #define STAR_MENU_RUN2 BUTTON_SELECT
150 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
152 #define STAR_QUIT BUTTON_POWER
153 #define STAR_LEFT BUTTON_LEFT
154 #define STAR_RIGHT BUTTON_RIGHT
155 #define STAR_UP BUTTON_UP
156 #define STAR_DOWN BUTTON_DOWN
157 #define STAR_TOGGLE_CONTROL BUTTON_SELECT
158 #define STAR_LEVEL_UP BUTTON_VOL_UP
159 #define STAR_LEVEL_DOWN BUTTON_VOL_DOWN
160 #define STAR_LEVEL_REPEAT BUTTON_A
161 #define STAR_MENU_RUN BUTTON_SELECT
163 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
164 (CONFIG_KEYPAD == SANSA_C200_PAD) || \
165 (CONFIG_KEYPAD == SANSA_CLIP_PAD) || \
166 (CONFIG_KEYPAD == SANSA_M200_PAD) || \
167 (CONFIG_KEYPAD == SANSA_FUZE_PAD)
169 #define STAR_QUIT BUTTON_POWER
170 #define STAR_LEFT BUTTON_LEFT
171 #define STAR_RIGHT BUTTON_RIGHT
172 #define STAR_UP BUTTON_UP
173 #define STAR_DOWN BUTTON_DOWN
174 #define STAR_TOGGLE_CONTROL BUTTON_SELECT
175 #define STAR_LEVEL_UP (BUTTON_SELECT | BUTTON_RIGHT)
176 #define STAR_LEVEL_DOWN (BUTTON_SELECT | BUTTON_LEFT)
177 #define STAR_LEVEL_REPEAT (BUTTON_SELECT | BUTTON_DOWN)
178 #define STAR_MENU_RUN BUTTON_SELECT
181 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
183 #define STAR_QUIT BUTTON_POWER
184 #define STAR_LEFT BUTTON_LEFT
185 #define STAR_RIGHT BUTTON_RIGHT
186 #define STAR_UP BUTTON_SCROLL_UP
187 #define STAR_DOWN BUTTON_SCROLL_DOWN
188 #define STAR_TOGGLE_CONTROL BUTTON_REW
189 #define STAR_LEVEL_UP (BUTTON_PLAY | BUTTON_SCROLL_UP)
190 #define STAR_LEVEL_DOWN (BUTTON_PLAY | BUTTON_SCROLL_DOWN)
191 #define STAR_LEVEL_REPEAT (BUTTON_PLAY | BUTTON_RIGHT)
192 #define STAR_MENU_RUN BUTTON_FF
194 #elif (CONFIG_KEYPAD == GIGABEAT_S_PAD)
196 #define STAR_QUIT BUTTON_BACK
197 #define STAR_LEFT BUTTON_LEFT
198 #define STAR_RIGHT BUTTON_RIGHT
199 #define STAR_UP BUTTON_UP
200 #define STAR_DOWN BUTTON_DOWN
201 #define STAR_TOGGLE_CONTROL BUTTON_SELECT
202 #define STAR_LEVEL_UP BUTTON_VOL_UP
203 #define STAR_LEVEL_DOWN BUTTON_VOL_DOWN
204 #define STAR_LEVEL_REPEAT BUTTON_MENU
205 #define STAR_MENU_RUN BUTTON_SELECT
207 #elif (CONFIG_KEYPAD == MROBE100_PAD)
209 #define STAR_QUIT BUTTON_POWER
210 #define STAR_LEFT BUTTON_LEFT
211 #define STAR_RIGHT BUTTON_RIGHT
212 #define STAR_UP BUTTON_UP
213 #define STAR_DOWN BUTTON_DOWN
214 #define STAR_TOGGLE_CONTROL BUTTON_SELECT
215 #define STAR_LEVEL_UP BUTTON_PLAY
216 #define STAR_LEVEL_DOWN BUTTON_MENU
217 #define STAR_LEVEL_REPEAT BUTTON_DISPLAY
218 #define STAR_MENU_RUN BUTTON_SELECT
220 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
222 #define STAR_QUIT BUTTON_RC_REC
223 #define STAR_LEFT BUTTON_RC_REW
224 #define STAR_RIGHT BUTTON_RC_FF
225 #define STAR_UP BUTTON_RC_VOL_UP
226 #define STAR_DOWN BUTTON_RC_VOL_DOWN
227 #define STAR_TOGGLE_CONTROL BUTTON_RC_MODE
228 #define STAR_LEVEL_UP (BUTTON_RC_PLAY|BUTTON_RC_VOL_UP)
229 #define STAR_LEVEL_DOWN (BUTTON_RC_PLAY|BUTTON_RC_VOL_DOWN)
230 #define STAR_LEVEL_REPEAT (BUTTON_RC_PLAY|BUTTON_RC_MENU)
231 #define STAR_MENU_RUN BUTTON_RC_FF
233 #elif (CONFIG_KEYPAD == COWOND2_PAD)
235 #define STAR_QUIT BUTTON_POWER
236 #define STAR_QUIT_NAME "[POWER]"
237 #define STAR_MENU_RUN BUTTON_MENU
239 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
241 #define STAR_QUIT BUTTON_BACK
242 #define STAR_LEFT BUTTON_LEFT
243 #define STAR_RIGHT BUTTON_RIGHT
244 #define STAR_UP BUTTON_UP
245 #define STAR_DOWN BUTTON_DOWN
246 #define STAR_TOGGLE_CONTROL BUTTON_PLAY
247 #define STAR_LEVEL_UP (BUTTON_CUSTOM | BUTTON_UP)
248 #define STAR_LEVEL_DOWN (BUTTON_CUSTOM | BUTTON_DOWN)
249 #define STAR_LEVEL_REPEAT (BUTTON_CUSTOM | BUTTON_RIGHT)
250 #define STAR_MENU_RUN BUTTON_MENU
252 #else
253 #error No keymap defined!
254 #endif
256 #ifdef HAVE_TOUCHSCREEN
257 //#ifndef STAR_QUIT
258 //#define STAR_QUIT BUTTON_TOPLEFT
259 //#define STAR_QUIT_NAME "[TOPLEFT]"
260 //#endif
261 #ifndef STAR_MENU_RUN
262 #define STAR_MENU_RUN BUTTON_TOPRIGHT
263 #endif
264 #ifndef STAR_LEFT
265 #define STAR_LEFT BUTTON_MIDLEFT
266 #endif
267 #ifndef STAR_RIGHT
268 #define STAR_RIGHT BUTTON_MIDRIGHT
269 #endif
270 #ifndef STAR_UP
271 #define STAR_UP BUTTON_TOPMIDDLE
272 #endif
273 #ifndef STAR_DOWN
274 #define STAR_DOWN BUTTON_BOTTOMMIDDLE
275 #endif
276 #ifndef STAR_TOGGLE_CONTROL
277 #define STAR_TOGGLE_CONTROL BUTTON_CENTER
278 #define STAR_TOGGLE_CONTROL_NAME "[CENTER]"
279 #endif
280 #ifndef STAR_LEVEL_UP
281 #define STAR_LEVEL_UP BUTTON_TOPLEFT
282 #define STAR_LEVEL_UP_NAME "[TOPLEFT]"
283 #endif
284 #ifndef STAR_LEVEL_DOWN
285 #define STAR_LEVEL_DOWN BUTTON_BOTTOMLEFT
286 #define STAR_LEVEL_DOWN_NAME "[BOTTOMLEFT]"
287 #endif
288 #ifndef STAR_LEVEL_REPEAT
289 #define STAR_LEVEL_REPEAT BUTTON_BOTTOMRIGHT
290 #define STAR_LEVEL_REPEAT_NAME "[BOTTOMRIGHT]"
291 #endif
292 #endif
294 /* function returns because of USB? */
295 static bool usb_detected = false;
297 /* position of the ball */
298 static int ball_x, ball_y;
300 /* position of the block */
301 static int block_x, block_y;
303 /* number of stars to get to finish the level */
304 static int star_count;
306 /* the object we control : ball or block */
307 static int control;
309 /* the current board */
310 static char board[STAR_HEIGHT][STAR_WIDTH];
312 #include "pluginbitmaps/star_tiles.h"
314 #define TILE_WIDTH BMPWIDTH_star_tiles
315 #define TILE_HEIGHT (BMPHEIGHT_star_tiles/5)
316 #define STAR_OFFSET_X ((LCD_WIDTH - STAR_WIDTH * TILE_WIDTH) / 2)
317 #define STAR_OFFSET_Y ((LCD_HEIGHT - STAR_HEIGHT * TILE_HEIGHT - MAX(TILE_HEIGHT, 8)) / 2)
319 #define WALL 0
320 #define SPACE 1
321 #define BLOCK 2
322 #define STAR 3
323 #define BALL 4
325 #define MENU_START 0
327 /* char font size */
328 static int char_width = -1;
329 static int char_height = -1;
331 static const struct plugin_api* rb;
333 /* this arrays contains a group of levels loaded into memory */
334 static unsigned char* levels =
335 "****************\n"
336 "*X**........o*x*\n"
337 "*..........o.***\n"
338 "*.......**o....*\n"
339 "*...**.o......**\n"
340 "**.o..o.....o..*\n"
341 "*.o......o**.o.*\n"
342 "*.....**o.....o*\n"
343 "****************\n"
344 "\n"
345 ".*..*.*.*...*.**\n"
346 "*...o.........X*\n"
347 "...*o..*o...o...\n"
348 "*.*.o.....o..*.*\n"
349 "......*...o...*.\n"
350 "*....*x*..o....*\n"
351 "...*..*.*...*oo*\n"
352 "*.............*.\n"
353 ".*..*........*..\n"
354 "\n"
355 "****************\n"
356 "*...........o*x*\n"
357 "*...**......**X*\n"
358 "*...*o.........*\n"
359 "*.o.....o**...o*\n"
360 "*.*o..o..o*..o**\n"
361 "*.**o.*o..o.o***\n"
362 "*o....**o......*\n"
363 "****************\n"
364 "\n"
365 "****************\n"
366 "*............*x*\n"
367 "*.....*........*\n"
368 "**o*o.o*o*o*o*o*\n"
369 "*.*.*o.o*.*.*.**\n"
370 "**o*o*o.o*o*o*o*\n"
371 "*.....*........*\n"
372 "*...*.......*X.*\n"
373 "****************\n"
374 "\n"
375 ".**************.\n"
376 "*X..*...*..*...*\n"
377 "*..*o.*.o..o.*.*\n"
378 "**......*..*...*\n"
379 "*o.*o*........**\n"
380 "**.....*.o.*...*\n"
381 "*o*..*.*.*...*x*\n"
382 "*...*....o*..*o*\n"
383 ".**************.\n"
384 "\n"
385 "....************\n"
386 "...*...o...*o.o*\n"
387 "..*....o....*.**\n"
388 ".*.....o.......*\n"
389 "*X.....o.......*\n"
390 "**.....o..*...**\n"
391 "*......o....*..*\n"
392 "*x.*...o..**o..*\n"
393 "****************\n"
394 "\n"
395 "****************\n"
396 "*..............*\n"
397 ".**.***..*o.**o*\n"
398 ".*o..*o.*.*.*.*.\n"
399 "..*..*..***.**..\n"
400 ".**..*..*o*.*o**\n"
401 "*..............*\n"
402 "*..X*o....x..*o*\n"
403 "****************\n"
404 "\n"
405 "***************.\n"
406 "*..o**.........*\n"
407 "*..*o..**.o....*\n"
408 "*..o**.*.*o....*\n"
409 "**.....**..*o*.*\n"
410 "**.*.......o*o.*\n"
411 "*oxo*...o..*X*.*\n"
412 "**.............*\n"
413 ".***************\n"
414 "\n"
415 "..*.***********.\n"
416 ".*o*o......*..X*\n"
417 "*o.o*....o....*.\n"
418 ".*.*..o**..o*..*\n"
419 "*..*o.*oxo....o*\n"
420 "*.....o**.....*.\n"
421 "*o*o.........*..\n"
422 "*...........*...\n"
423 ".***********....\n"
424 "\n"
425 "....***********.\n"
426 "*****.o........*\n"
427 "*...x.***o.o*.o*\n"
428 "*.o...*o.*o...*.\n"
429 "*.....*..o..*.o*\n"
430 "*o*o..*.o*..*X*.\n"
431 ".*o...***..***..\n"
432 "*.........*.*.*.\n"
433 ".*********..*..*\n"
434 "\n"
435 "****************\n"
436 "*......*......X*\n"
437 "*..*oo.....oo.**\n"
438 "**...o...**...o*\n"
439 "*o....*o*oo..***\n"
440 "**.**....**....*\n"
441 "*o..o*.o....x.o*\n"
442 "**o***....*...**\n"
443 "***************.\n"
444 "\n"
445 "**.....**..****.\n"
446 "*X*****o.***.o**\n"
447 "*....oo.....o..*\n"
448 "*.**..**o..*o*.*\n"
449 "*.*.o.*.*o.**..*\n"
450 "*.**..**...*x*.*\n"
451 "*.....o........*\n"
452 "*........o.....*\n"
453 "****************\n"
454 "\n"
455 ".**************.\n"
456 "*.X*........o.**\n"
457 "*.*...*o...o**.*\n"
458 "*.......o....*.*\n"
459 "*.o..........*o*\n"
460 "*.*......o.....*\n"
461 "**......o.o..*o*\n"
462 "*x..*....o.*.*.*\n"
463 ".**************.\n"
464 "\n"
465 "****************\n"
466 "*o*o........o*o*\n"
467 "*.o*X......**..*\n"
468 "*.x........o...*\n"
469 "*........o*....*\n"
470 "*......o.......*\n"
471 "*.o*........*..*\n"
472 "*o*o........o*o*\n"
473 "****************\n"
474 "\n"
475 ".******.********\n"
476 "*.....o*.....o.*\n"
477 "*.*.o.*..*...o.*\n"
478 "*..X*...*oo.*o.*\n"
479 ".*.*...*.o..x*.*\n"
480 "*o.......*..*o.*\n"
481 ".*......o.....*.\n"
482 "*o............o*\n"
483 "****************\n"
484 "\n"
485 "****************\n"
486 "**.x*o.o......o*\n"
487 "*o.Xo*o.......**\n"
488 "**.***........**\n"
489 "**.....o*o*....*\n"
490 "*oo.......o*o..*\n"
491 "**.o....****o..*\n"
492 "**o*..*........*\n"
493 "****************\n"
494 "\n"
495 "****************\n"
496 "*.o*........*X.*\n"
497 "*.*..o*oo*o..*.*\n"
498 "*....*o**o*.o..*\n"
499 "*.o*.......o*..*\n"
500 "*..o*o....o*...*\n"
501 "*.*..*.**o*..*.*\n"
502 "*....o.*o...x..*\n"
503 "****************\n"
504 "\n"
505 "****************\n"
506 "*.o....o..x*...*\n"
507 "*..*o*o...*o...*\n"
508 "*...*o*....*o..*\n"
509 "*...o..*...o*o.*\n"
510 "*.*o*...*.o*...*\n"
511 "*.o*o.*.o.*....*\n"
512 "*o*X..*.....*..*\n"
513 "****************\n"
514 "\n"
515 "****************\n"
516 "*o...**.....**o*\n"
517 "*.*..*......*o.*\n"
518 "*.o*...o**..o..*\n"
519 "*.*....*o......*\n"
520 "*....*...o*....*\n"
521 "*.**.o*.**o..*x*\n"
522 "*.o*.*o.....**X*\n"
523 "****************\n"
524 "\n"
525 "****************\n"
526 "*...o*o........*\n"
527 "**o..o*.**o...**\n"
528 "*.*.*.o...*..*.*\n"
529 "*.x.*..**..*.Xo*\n"
530 "*.*..*...o.*.*.*\n"
531 "**...o**.*o..o**\n"
532 "*........o*o...*\n"
533 "****************";
536 * Display text.
538 void star_display_text(char *str, bool waitkey)
540 int chars_by_line;
541 int lines_by_screen;
542 int chars_for_line;
543 int current_line = 0;
544 int first_char_index = 0;
545 char *ptr_char;
546 char *ptr_line;
547 int i;
548 char line[255];
549 int key;
550 bool go_on;
552 rb->lcd_clear_display();
554 chars_by_line = LCD_WIDTH / char_width;
555 lines_by_screen = LCD_HEIGHT / char_height;
559 ptr_char = str + first_char_index;
560 chars_for_line = 0;
561 i = 0;
562 ptr_line = line;
563 while (i < chars_by_line)
565 switch (*ptr_char)
567 case '\t':
568 case ' ':
569 *(ptr_line++) = ' ';
570 case '\n':
571 case '\0':
572 chars_for_line = i;
573 break;
575 default:
576 *(ptr_line++) = *ptr_char;
578 if (*ptr_char == '\n' || *ptr_char == '\0')
579 break;
580 ptr_char++;
581 i++;
584 if (chars_for_line == 0)
585 chars_for_line = i;
587 line[chars_for_line] = '\0';
589 /* test if we have cut a word. If it is the case we don't have to */
590 /* skip the space */
591 if (i == chars_by_line && chars_for_line == chars_by_line)
592 first_char_index += chars_for_line;
593 else
594 first_char_index += chars_for_line + 1;
596 /* print the line on the screen */
597 rb->lcd_putsxy(0, current_line * char_height, line);
599 /* if the number of line showed on the screen is equals to the */
600 /* maximum number of line we can show, we wait for a key pressed to */
601 /* clear and show the remaining text. */
602 current_line++;
603 if (current_line == lines_by_screen || *ptr_char == '\0')
605 current_line = 0;
606 rb->lcd_update();
607 go_on = false;
608 while (waitkey && !go_on)
610 key = rb->button_get(true);
611 switch (key)
613 case STAR_QUIT:
614 case STAR_LEFT:
615 case STAR_DOWN:
616 go_on = true;
617 break;
619 default:
620 if (rb->default_event_handler(key) == SYS_USB_CONNECTED)
622 usb_detected = true;
623 go_on = true;
624 break;
628 rb->lcd_clear_display();
630 } while (*ptr_char != '\0');
634 * Do a pretty transition from one level to another.
636 static void star_transition_update(void)
638 const int center_x = LCD_WIDTH / 2;
639 const int center_y = LCD_HEIGHT / 2;
640 int x = 0;
641 int y = 0;
642 #if LCD_WIDTH >= LCD_HEIGHT
643 #if defined(IPOD_VIDEO)
644 const int step = 4;
645 #else
646 const int step = 1;
647 #endif
648 const int lcd_demi_width = LCD_WIDTH / 2;
649 int var_y = 0;
651 for (; x < lcd_demi_width ; x+=step)
653 var_y += LCD_HEIGHT;
654 if (var_y > LCD_WIDTH)
656 var_y -= LCD_WIDTH;
657 y+=step;
659 if( x )
661 rb->lcd_update_rect(center_x - x, center_y - y, x*2, step);
662 rb->lcd_update_rect(center_x - x, center_y + y - step, x*2, step);
664 if( y )
666 rb->lcd_update_rect(center_x - x, center_y - y, step, y*2);
667 rb->lcd_update_rect(center_x + x - step, center_y - y, step, y*2);
669 STAR_SLEEP
671 #else
672 int lcd_demi_height = LCD_HEIGHT / 2;
673 int var_x = 0;
675 for (; y < lcd_demi_height ; y++)
677 var_x += LCD_WIDTH;
678 if (var_x > LCD_HEIGHT)
680 var_x -= LCD_HEIGHT;
681 x++;
683 if( x )
685 rb->lcd_update_rect(center_x - x, center_y - y, x * 2, 1);
686 rb->lcd_update_rect(center_x - x, center_y + y - 1, x * 2, 1);
688 if( y )
690 rb->lcd_update_rect(center_x - x, center_y - y, 1, y * 2);
691 rb->lcd_update_rect(center_x + x - 1, center_y - y, 1, y * 2);
693 STAR_SLEEP
695 #endif
696 rb->lcd_update();
700 * Display information board of the current level.
702 static void star_display_board_info(int current_level)
704 int label_pos_y, tile_pos_y;
705 char str_info[32];
707 if (TILE_HEIGHT > char_height)
709 tile_pos_y = LCD_HEIGHT - TILE_HEIGHT;
710 label_pos_y = tile_pos_y + (TILE_HEIGHT - char_height) / 2;
712 else
714 label_pos_y = LCD_HEIGHT - char_height;
715 tile_pos_y = label_pos_y + (char_height - TILE_HEIGHT) / 2;
718 rb->snprintf(str_info, sizeof(str_info), "L:%02d", current_level + 1);
719 rb->lcd_putsxy(STAR_OFFSET_X, label_pos_y, str_info);
720 rb->snprintf(str_info, sizeof(str_info), "S:%02d", star_count);
721 rb->lcd_putsxy(LCD_WIDTH/2 - 2 * char_width, label_pos_y, str_info);
722 rb->lcd_putsxy(STAR_OFFSET_X + (STAR_WIDTH-1) * TILE_WIDTH - 2 * char_width,
723 label_pos_y, "C:");
725 rb->lcd_bitmap_part(star_tiles, 0, control == STAR_CONTROL_BALL ?
726 BALL*TILE_HEIGHT : BLOCK*TILE_HEIGHT, TILE_WIDTH,
727 STAR_OFFSET_X + (STAR_WIDTH-1) * TILE_WIDTH,
728 tile_pos_y, TILE_WIDTH, TILE_HEIGHT);
730 rb->lcd_update_rect(0, MIN(label_pos_y, tile_pos_y), LCD_WIDTH,
731 MAX(TILE_HEIGHT, char_height));
736 * Load a level into board array.
738 static int star_load_level(int current_level)
740 int x, y;
741 char *ptr_tab;
743 if (current_level < 0)
744 current_level = 0;
745 else if (current_level > STAR_LEVEL_COUNT-1)
746 current_level = STAR_LEVEL_COUNT-1;
749 ptr_tab = levels + current_level * STAR_LEVEL_SIZE;
750 control = STAR_CONTROL_BALL;
751 star_count = 0;
753 rb->lcd_clear_display();
755 for (y = 0 ; y < STAR_HEIGHT ; y++)
757 for (x = 0 ; x < STAR_WIDTH ; x++)
759 board[y][x] = *ptr_tab;
760 switch (*ptr_tab)
762 # define DRAW_TILE( a ) \
763 rb->lcd_bitmap_part( star_tiles, 0, \
764 a*TILE_HEIGHT, TILE_WIDTH, \
765 STAR_OFFSET_X + x * TILE_WIDTH, \
766 STAR_OFFSET_Y + y * TILE_HEIGHT, \
767 TILE_WIDTH, TILE_HEIGHT);
768 case STAR_VOID:
769 DRAW_TILE( SPACE );
770 break;
772 case STAR_WALL:
773 DRAW_TILE( WALL );
774 break;
776 case STAR_STAR:
777 DRAW_TILE( STAR );
778 star_count++;
779 break;
781 case STAR_BALL:
782 ball_x = x;
783 ball_y = y;
784 DRAW_TILE( BALL );
785 break;
788 case STAR_BLOCK:
789 block_x = x;
790 block_y = y;
791 DRAW_TILE( BLOCK );
792 break;
794 ptr_tab++;
796 ptr_tab++;
798 star_display_board_info(current_level);
799 star_transition_update();
800 return 1;
803 static void star_animate_tile(int tile_no, int start_x, int start_y,
804 int delta_x, int delta_y)
806 int i;
808 if (delta_x != 0) /* horizontal */
810 for (i = 1 ; i <= TILE_WIDTH ; i++)
812 STAR_SLEEP
813 rb->lcd_bitmap_part(star_tiles, 0, SPACE * TILE_HEIGHT, TILE_WIDTH,
814 start_x, start_y, TILE_WIDTH, TILE_HEIGHT);
815 rb->lcd_bitmap_part(star_tiles, 0, tile_no * TILE_HEIGHT, TILE_WIDTH,
816 start_x + delta_x * i, start_y, TILE_WIDTH, TILE_HEIGHT);
817 rb->lcd_update_rect(start_x + delta_x * i - (delta_x>0?1:0),
818 start_y, TILE_WIDTH + 1, TILE_HEIGHT);
821 else /* vertical */
823 for (i = 1 ; i <= TILE_HEIGHT ; i++)
825 STAR_SLEEP
826 rb->lcd_bitmap_part(star_tiles, 0, SPACE * TILE_HEIGHT, TILE_WIDTH,
827 start_x, start_y, TILE_WIDTH, TILE_HEIGHT);
828 rb->lcd_bitmap_part(star_tiles, 0, tile_no * TILE_HEIGHT, TILE_WIDTH,
829 start_x, start_y + delta_y * i, TILE_WIDTH, TILE_HEIGHT);
830 rb->lcd_update_rect(start_x, start_y + delta_y * i - (delta_y>0?1:0),
831 TILE_WIDTH, TILE_HEIGHT + 1);
837 * Run the game.
839 static int star_run_game(int current_level)
841 int move_x = 0;
842 int move_y = 0;
843 int key;
844 int lastkey = BUTTON_NONE;
846 int label_offset_y;
848 label_offset_y = LCD_HEIGHT - char_height;
850 if (!star_load_level(current_level))
851 return 0;
853 while (true)
855 move_x = 0;
856 move_y = 0;
858 while ((move_x == 0) && (move_y == 0))
860 key = rb->button_get(true);
861 switch (key)
863 #ifdef STAR_RC_QUIT
864 case STAR_RC_QUIT:
865 #endif
866 case STAR_QUIT:
867 return -1;
869 case STAR_LEFT:
870 move_x = -1;
871 break;
873 case STAR_RIGHT:
874 move_x = 1;
875 break;
877 case STAR_UP:
878 move_y = -1;
879 break;
881 case STAR_DOWN:
882 move_y = 1;
883 break;
885 case STAR_LEVEL_DOWN:
886 #ifdef STAR_LEVEL_DOWN_PRE
887 if (lastkey != STAR_LEVEL_DOWN_PRE)
888 break;
889 #endif
890 if (current_level > 0)
892 current_level--;
893 star_load_level(current_level);
895 break;
897 case STAR_LEVEL_REPEAT:
898 star_load_level(current_level);
899 break;
901 case STAR_LEVEL_UP:
902 #ifdef STAR_LEVEL_UP_PRE
903 if (lastkey != STAR_LEVEL_UP_PRE)
904 break;
905 #endif
906 if (current_level < STAR_LEVEL_COUNT - 1)
908 current_level++;
909 star_load_level(current_level);
911 break;
913 case STAR_TOGGLE_CONTROL:
914 #ifdef STAR_TOGGLE_CONTROL_PRE
915 if (lastkey != STAR_TOGGLE_CONTROL_PRE)
916 break;
917 #endif
918 #ifdef STAR_TOGGLE_CONTROL2
919 case STAR_TOGGLE_CONTROL2:
920 #endif
921 if (control == STAR_CONTROL_BALL)
922 control = STAR_CONTROL_BLOCK;
923 else
924 control = STAR_CONTROL_BALL;
925 star_display_board_info(current_level);
926 break;
928 default:
929 if (rb->default_event_handler(key) == SYS_USB_CONNECTED)
931 usb_detected = true;
932 return 0;
934 break;
936 if (key != BUTTON_NONE)
937 lastkey = key;
940 if (control == STAR_CONTROL_BALL)
942 board[ball_y][ball_x] = STAR_VOID;
943 while ((board[ball_y + move_y][ball_x + move_x] == STAR_VOID
944 || board[ball_y + move_y][ball_x + move_x] == STAR_STAR))
947 star_animate_tile(BALL, STAR_OFFSET_X + ball_x * TILE_WIDTH,
948 STAR_OFFSET_Y + ball_y * TILE_HEIGHT,
949 move_x, move_y);
950 ball_x += move_x;
951 ball_y += move_y;
953 if (board[ball_y][ball_x] == STAR_STAR)
955 board[ball_y][ball_x] = STAR_VOID;
956 star_count--;
958 star_display_board_info(current_level);
961 board[ball_y][ball_x] = STAR_BALL;
963 else
965 board[block_y][block_x] = STAR_VOID;
966 while (board[block_y + move_y][block_x + move_x] == STAR_VOID)
968 star_animate_tile(BLOCK, STAR_OFFSET_X + block_x * TILE_WIDTH,
969 STAR_OFFSET_Y + block_y * TILE_HEIGHT,
970 move_x, move_y);
971 block_x += move_x;
972 block_y += move_y;
974 board[block_y][block_x] = STAR_BLOCK;
977 if (star_count == 0)
979 current_level++;
980 if (current_level == STAR_LEVEL_COUNT)
982 rb->lcd_clear_display();
983 star_display_text("Congratulations!", true);
984 rb->lcd_update();
986 /* There is no such level as STAR_LEVEL_COUNT so it can't be the
987 * current_level */
988 current_level--;
989 return 1;
991 star_load_level(current_level);
997 * Display the choice menu.
999 static int star_menu(void)
1001 int selection, level=1;
1002 bool menu_quit = false;
1003 struct viewport vp[NB_SCREENS];
1004 /* get the size of char */
1005 rb->lcd_getstringsize("a", &char_width, &char_height);
1007 MENUITEM_STRINGLIST(menu,"Star Menu",NULL,"Play","Choose Level",
1008 "Information","Keys","Quit");
1009 FOR_NB_SCREENS(selection)
1011 rb->viewport_set_defaults(&vp[selection], selection);
1012 #if LCD_DEPTH > 1
1013 if (rb->screens[selection]->depth > 1)
1015 vp->bg_pattern = LCD_BLACK;
1016 vp->fg_pattern = LCD_WHITE;
1018 #endif
1020 while(!menu_quit)
1022 switch(rb->do_menu(&menu, &selection, vp, true))
1024 case 0:
1025 menu_quit = true;
1026 break;
1027 case 1:
1028 rb->set_int("Level", "", UNIT_INT, &level,
1029 NULL, 1, 1, STAR_LEVEL_COUNT, NULL );
1030 break;
1031 case 2:
1032 star_display_text(
1033 "INFO\n\n"
1034 "Take all the stars to go to the next level. "
1035 "You can toggle control with the block to "
1036 "use it as a mobile wall. The block cannot "
1037 "take stars.", true);
1038 break;
1039 case 3:
1040 #if CONFIG_KEYPAD == RECORDER_PAD
1041 star_display_text("KEYS\n\n"
1042 "[ON] Toggle Ctl.\n"
1043 "[OFF] Exit\n"
1044 "[F1] Prev. level\n"
1045 "[F2] Reset level\n"
1046 "[F3] Next level", true);
1047 #elif CONFIG_KEYPAD == ONDIO_PAD
1048 star_display_text("KEYS\n\n"
1049 "[MODE] Toggle Ctl\n"
1050 "[OFF] Exit\n"
1051 "[M <] Prev. level\n"
1052 "[M ^] Reset level\n"
1053 "[M >] Next level", true);
1054 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
1055 star_display_text("KEYS\n\n"
1056 "[MODE/NAVI] Toggle Ctrl\n"
1057 "[OFF] Exit\n"
1058 "[ON + LEFT] Prev. level\n"
1059 "[ON + NAVI] Reset level\n"
1060 "[ON + RIGHT] Next level", true);
1061 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
1062 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
1063 star_display_text("KEYS\n\n"
1064 "[SELECT] Toggle Ctl\n"
1065 "[S + MENU] Exit\n"
1066 "[S <] Prev. level\n"
1067 "[S + PLAY] Reset level\n"
1068 "[S >] Next level", true);
1069 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
1070 star_display_text("KEYS\n\n"
1071 "[SELECT] Toggle Ctl\n"
1072 "[POWER] Exit\n"
1073 "[REC..] Prev. level\n"
1074 "[PLAY] Reset level\n"
1075 "[REC] Next level", true);
1076 #elif CONFIG_KEYPAD == GIGABEAT_PAD
1077 star_display_text("KEYS\n\n"
1078 "[MENU] Toggle Control\n"
1079 "[A] Exit\n"
1080 "[PWR+DOWN] Prev. level\n"
1081 "[PWR+RIGHT] Reset level\n"
1082 "[PWR+UP] Next level", true);
1083 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
1084 star_display_text("KEYS\n\n"
1085 "[REW] Toggle Ctl\n"
1086 "[POWER] Exit\n"
1087 "[PLAY+DOWN] Prev. level\n"
1088 "[PLAY+RIGHT] Reset level\n"
1089 "[PLAY+UP] Next level", true);
1090 #endif
1091 #ifdef HAVE_TOUCHSCREEN
1092 star_display_text("KEYS\n\n"
1093 STAR_TOGGLE_CONTROL_NAME " Toggle Control\n"
1094 STAR_QUIT_NAME " Exit\n"
1095 STAR_LEVEL_DOWN_NAME " Prev. level\n"
1096 STAR_LEVEL_REPEAT_NAME " Reset level\n"
1097 STAR_LEVEL_UP_NAME " Next level", true);
1098 #endif
1099 break;
1100 default:
1101 menu_quit = true;
1102 break;
1106 if (selection == MENU_START)
1108 rb->lcd_setfont(FONT_SYSFIXED);
1109 rb->lcd_getstringsize("a", &char_width, &char_height);
1110 level--;
1111 star_run_game(level);
1113 return PLUGIN_OK;
1117 * Main entry point
1119 enum plugin_status plugin_start(const struct plugin_api* api, const void* parameter)
1121 (void)parameter;
1122 rb = api;
1124 #if LCD_DEPTH > 1
1125 rb->lcd_set_backdrop(NULL);
1126 rb->lcd_set_background( LCD_BLACK );
1127 rb->lcd_set_foreground( LCD_WHITE );
1128 #endif
1130 /* display choice menu */
1131 return star_menu();
1134 #endif