Use the AMS_LOWMEM define to indicate memory size as the .lds files do in config...
[kugel-rb.git] / apps / plugins / star.c
blob880bcdebe390d423ecf8d89584935067849ddb59
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
164 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
165 (CONFIG_KEYPAD == SANSA_C200_PAD) || \
166 (CONFIG_KEYPAD == SANSA_CLIP_PAD) || \
167 (CONFIG_KEYPAD == SANSA_M200_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 == SANSA_FUZE_PAD)
183 #define STAR_QUIT (BUTTON_HOME|BUTTON_REPEAT)
184 #define STAR_LEFT BUTTON_LEFT
185 #define STAR_RIGHT BUTTON_RIGHT
186 #define STAR_UP BUTTON_UP
187 #define STAR_DOWN BUTTON_DOWN
188 #define STAR_TOGGLE_CONTROL BUTTON_SELECT
189 #define STAR_LEVEL_UP (BUTTON_SELECT | BUTTON_RIGHT)
190 #define STAR_LEVEL_DOWN (BUTTON_SELECT | BUTTON_LEFT)
191 #define STAR_LEVEL_REPEAT (BUTTON_SELECT | BUTTON_DOWN)
192 #define STAR_MENU_RUN BUTTON_SELECT
195 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
197 #define STAR_QUIT BUTTON_POWER
198 #define STAR_LEFT BUTTON_LEFT
199 #define STAR_RIGHT BUTTON_RIGHT
200 #define STAR_UP BUTTON_SCROLL_UP
201 #define STAR_DOWN BUTTON_SCROLL_DOWN
202 #define STAR_TOGGLE_CONTROL BUTTON_REW
203 #define STAR_LEVEL_UP (BUTTON_PLAY | BUTTON_SCROLL_UP)
204 #define STAR_LEVEL_DOWN (BUTTON_PLAY | BUTTON_SCROLL_DOWN)
205 #define STAR_LEVEL_REPEAT (BUTTON_PLAY | BUTTON_RIGHT)
206 #define STAR_MENU_RUN BUTTON_FF
208 #elif (CONFIG_KEYPAD == GIGABEAT_S_PAD)
210 #define STAR_QUIT BUTTON_BACK
211 #define STAR_LEFT BUTTON_LEFT
212 #define STAR_RIGHT BUTTON_RIGHT
213 #define STAR_UP BUTTON_UP
214 #define STAR_DOWN BUTTON_DOWN
215 #define STAR_TOGGLE_CONTROL BUTTON_SELECT
216 #define STAR_LEVEL_UP BUTTON_VOL_UP
217 #define STAR_LEVEL_DOWN BUTTON_VOL_DOWN
218 #define STAR_LEVEL_REPEAT BUTTON_MENU
219 #define STAR_MENU_RUN BUTTON_SELECT
221 #elif (CONFIG_KEYPAD == MROBE100_PAD)
223 #define STAR_QUIT BUTTON_POWER
224 #define STAR_LEFT BUTTON_LEFT
225 #define STAR_RIGHT BUTTON_RIGHT
226 #define STAR_UP BUTTON_UP
227 #define STAR_DOWN BUTTON_DOWN
228 #define STAR_TOGGLE_CONTROL BUTTON_SELECT
229 #define STAR_LEVEL_UP BUTTON_PLAY
230 #define STAR_LEVEL_DOWN BUTTON_MENU
231 #define STAR_LEVEL_REPEAT BUTTON_DISPLAY
232 #define STAR_MENU_RUN BUTTON_SELECT
234 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
236 #define STAR_QUIT BUTTON_RC_REC
237 #define STAR_LEFT BUTTON_RC_REW
238 #define STAR_RIGHT BUTTON_RC_FF
239 #define STAR_UP BUTTON_RC_VOL_UP
240 #define STAR_DOWN BUTTON_RC_VOL_DOWN
241 #define STAR_TOGGLE_CONTROL BUTTON_RC_MODE
242 #define STAR_LEVEL_UP (BUTTON_RC_PLAY|BUTTON_RC_VOL_UP)
243 #define STAR_LEVEL_DOWN (BUTTON_RC_PLAY|BUTTON_RC_VOL_DOWN)
244 #define STAR_LEVEL_REPEAT (BUTTON_RC_PLAY|BUTTON_RC_MENU)
245 #define STAR_MENU_RUN BUTTON_RC_FF
247 #elif (CONFIG_KEYPAD == COWOND2_PAD)
249 #define STAR_QUIT BUTTON_POWER
250 #define STAR_QUIT_NAME "[POWER]"
251 #define STAR_MENU_RUN BUTTON_MENU
253 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
255 #define STAR_QUIT BUTTON_BACK
256 #define STAR_LEFT BUTTON_LEFT
257 #define STAR_RIGHT BUTTON_RIGHT
258 #define STAR_UP BUTTON_UP
259 #define STAR_DOWN BUTTON_DOWN
260 #define STAR_TOGGLE_CONTROL BUTTON_PLAY
261 #define STAR_LEVEL_UP (BUTTON_CUSTOM | BUTTON_UP)
262 #define STAR_LEVEL_DOWN (BUTTON_CUSTOM | BUTTON_DOWN)
263 #define STAR_LEVEL_REPEAT (BUTTON_CUSTOM | BUTTON_RIGHT)
264 #define STAR_MENU_RUN BUTTON_MENU
266 #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
268 #define STAR_QUIT BUTTON_POWER
269 #define STAR_LEFT BUTTON_LEFT
270 #define STAR_RIGHT BUTTON_RIGHT
271 #define STAR_UP BUTTON_UP
272 #define STAR_DOWN BUTTON_DOWN
273 #define STAR_TOGGLE_CONTROL BUTTON_SELECT
274 #define STAR_LEVEL_UP BUTTON_VOL_UP
275 #define STAR_LEVEL_DOWN BUTTON_VOL_DOWN
276 #define STAR_LEVEL_REPEAT BUTTON_VIEW
277 #define STAR_MENU_RUN BUTTON_MENU
279 #elif (CONFIG_KEYPAD == ONDAVX747_PAD)
281 #define STAR_QUIT BUTTON_POWER
282 #define STAR_QUIT_NAME "[POWER]"
283 #define STAR_MENU_RUN BUTTON_MENU
285 #elif CONFIG_KEYPAD == MROBE500_PAD
286 #define STAR_QUIT BUTTON_POWER
287 #define STAR_QUIT_NAME "[POWER]"
289 #else
290 #error No keymap defined!
291 #endif
293 #ifdef HAVE_TOUCHSCREEN
294 //#ifndef STAR_QUIT
295 //#define STAR_QUIT BUTTON_TOPLEFT
296 //#define STAR_QUIT_NAME "[TOPLEFT]"
297 //#endif
298 #ifndef STAR_MENU_RUN
299 #define STAR_MENU_RUN BUTTON_TOPRIGHT
300 #endif
301 #ifndef STAR_LEFT
302 #define STAR_LEFT BUTTON_MIDLEFT
303 #endif
304 #ifndef STAR_RIGHT
305 #define STAR_RIGHT BUTTON_MIDRIGHT
306 #endif
307 #ifndef STAR_UP
308 #define STAR_UP BUTTON_TOPMIDDLE
309 #endif
310 #ifndef STAR_DOWN
311 #define STAR_DOWN BUTTON_BOTTOMMIDDLE
312 #endif
313 #ifndef STAR_TOGGLE_CONTROL
314 #define STAR_TOGGLE_CONTROL BUTTON_CENTER
315 #define STAR_TOGGLE_CONTROL_NAME "[CENTER]"
316 #endif
317 #ifndef STAR_LEVEL_UP
318 #define STAR_LEVEL_UP BUTTON_TOPLEFT
319 #define STAR_LEVEL_UP_NAME "[TOPLEFT]"
320 #endif
321 #ifndef STAR_LEVEL_DOWN
322 #define STAR_LEVEL_DOWN BUTTON_BOTTOMLEFT
323 #define STAR_LEVEL_DOWN_NAME "[BOTTOMLEFT]"
324 #endif
325 #ifndef STAR_LEVEL_REPEAT
326 #define STAR_LEVEL_REPEAT BUTTON_BOTTOMRIGHT
327 #define STAR_LEVEL_REPEAT_NAME "[BOTTOMRIGHT]"
328 #endif
329 #endif
331 /* function returns because of USB? */
332 static bool usb_detected = false;
334 /* position of the ball */
335 static int ball_x, ball_y;
337 /* position of the block */
338 static int block_x, block_y;
340 /* number of stars to get to finish the level */
341 static int star_count;
343 /* the object we control : ball or block */
344 static int control;
346 /* the current board */
347 static char board[STAR_HEIGHT][STAR_WIDTH];
349 #include "pluginbitmaps/star_tiles.h"
351 #define TILE_WIDTH BMPWIDTH_star_tiles
352 #define TILE_HEIGHT (BMPHEIGHT_star_tiles/5)
353 #define STAR_OFFSET_X ((LCD_WIDTH - STAR_WIDTH * TILE_WIDTH) / 2)
354 #define STAR_OFFSET_Y ((LCD_HEIGHT - STAR_HEIGHT * TILE_HEIGHT - MAX(TILE_HEIGHT, 8)) / 2)
356 #define WALL 0
357 #define SPACE 1
358 #define BLOCK 2
359 #define STAR 3
360 #define BALL 4
362 #define MENU_START 0
364 /* char font size */
365 static int char_width = -1;
366 static int char_height = -1;
368 /* this arrays contains a group of levels loaded into memory */
369 static unsigned char* levels =
370 "****************\n"
371 "*X**........o*x*\n"
372 "*..........o.***\n"
373 "*.......**o....*\n"
374 "*...**.o......**\n"
375 "**.o..o.....o..*\n"
376 "*.o......o**.o.*\n"
377 "*.....**o.....o*\n"
378 "****************\n"
379 "\n"
380 ".*..*.*.*...*.**\n"
381 "*...o.........X*\n"
382 "...*o..*o...o...\n"
383 "*.*.o.....o..*.*\n"
384 "......*...o...*.\n"
385 "*....*x*..o....*\n"
386 "...*..*.*...*oo*\n"
387 "*.............*.\n"
388 ".*..*........*..\n"
389 "\n"
390 "****************\n"
391 "*...........o*x*\n"
392 "*...**......**X*\n"
393 "*...*o.........*\n"
394 "*.o.....o**...o*\n"
395 "*.*o..o..o*..o**\n"
396 "*.**o.*o..o.o***\n"
397 "*o....**o......*\n"
398 "****************\n"
399 "\n"
400 "****************\n"
401 "*............*x*\n"
402 "*.....*........*\n"
403 "**o*o.o*o*o*o*o*\n"
404 "*.*.*o.o*.*.*.**\n"
405 "**o*o*o.o*o*o*o*\n"
406 "*.....*........*\n"
407 "*...*.......*X.*\n"
408 "****************\n"
409 "\n"
410 ".**************.\n"
411 "*X..*...*..*...*\n"
412 "*..*o.*.o..o.*.*\n"
413 "**......*..*...*\n"
414 "*o.*o*........**\n"
415 "**.....*.o.*...*\n"
416 "*o*..*.*.*...*x*\n"
417 "*...*....o*..*o*\n"
418 ".**************.\n"
419 "\n"
420 "....************\n"
421 "...*...o...*o.o*\n"
422 "..*....o....*.**\n"
423 ".*.....o.......*\n"
424 "*X.....o.......*\n"
425 "**.....o..*...**\n"
426 "*......o....*..*\n"
427 "*x.*...o..**o..*\n"
428 "****************\n"
429 "\n"
430 "****************\n"
431 "*..............*\n"
432 ".**.***..*o.**o*\n"
433 ".*o..*o.*.*.*.*.\n"
434 "..*..*..***.**..\n"
435 ".**..*..*o*.*o**\n"
436 "*..............*\n"
437 "*..X*o....x..*o*\n"
438 "****************\n"
439 "\n"
440 "***************.\n"
441 "*..o**.........*\n"
442 "*..*o..**.o....*\n"
443 "*..o**.*.*o....*\n"
444 "**.....**..*o*.*\n"
445 "**.*.......o*o.*\n"
446 "*oxo*...o..*X*.*\n"
447 "**.............*\n"
448 ".***************\n"
449 "\n"
450 "..*.***********.\n"
451 ".*o*o......*..X*\n"
452 "*o.o*....o....*.\n"
453 ".*.*..o**..o*..*\n"
454 "*..*o.*oxo....o*\n"
455 "*.....o**.....*.\n"
456 "*o*o.........*..\n"
457 "*...........*...\n"
458 ".***********....\n"
459 "\n"
460 "....***********.\n"
461 "*****.o........*\n"
462 "*...x.***o.o*.o*\n"
463 "*.o...*o.*o...*.\n"
464 "*.....*..o..*.o*\n"
465 "*o*o..*.o*..*X*.\n"
466 ".*o...***..***..\n"
467 "*.........*.*.*.\n"
468 ".*********..*..*\n"
469 "\n"
470 "****************\n"
471 "*......*......X*\n"
472 "*..*oo.....oo.**\n"
473 "**...o...**...o*\n"
474 "*o....*o*oo..***\n"
475 "**.**....**....*\n"
476 "*o..o*.o....x.o*\n"
477 "**o***....*...**\n"
478 "***************.\n"
479 "\n"
480 "**.....**..****.\n"
481 "*X*****o.***.o**\n"
482 "*....oo.....o..*\n"
483 "*.**..**o..*o*.*\n"
484 "*.*.o.*.*o.**..*\n"
485 "*.**..**...*x*.*\n"
486 "*.....o........*\n"
487 "*........o.....*\n"
488 "****************\n"
489 "\n"
490 ".**************.\n"
491 "*.X*........o.**\n"
492 "*.*...*o...o**.*\n"
493 "*.......o....*.*\n"
494 "*.o..........*o*\n"
495 "*.*......o.....*\n"
496 "**......o.o..*o*\n"
497 "*x..*....o.*.*.*\n"
498 ".**************.\n"
499 "\n"
500 "****************\n"
501 "*o*o........o*o*\n"
502 "*.o*X......**..*\n"
503 "*.x........o...*\n"
504 "*........o*....*\n"
505 "*......o.......*\n"
506 "*.o*........*..*\n"
507 "*o*o........o*o*\n"
508 "****************\n"
509 "\n"
510 ".******.********\n"
511 "*.....o*.....o.*\n"
512 "*.*.o.*..*...o.*\n"
513 "*..X*...*oo.*o.*\n"
514 ".*.*...*.o..x*.*\n"
515 "*o.......*..*o.*\n"
516 ".*......o.....*.\n"
517 "*o............o*\n"
518 "****************\n"
519 "\n"
520 "****************\n"
521 "**.x*o.o......o*\n"
522 "*o.Xo*o.......**\n"
523 "**.***........**\n"
524 "**.....o*o*....*\n"
525 "*oo.......o*o..*\n"
526 "**.o....****o..*\n"
527 "**o*..*........*\n"
528 "****************\n"
529 "\n"
530 "****************\n"
531 "*.o*........*X.*\n"
532 "*.*..o*oo*o..*.*\n"
533 "*....*o**o*.o..*\n"
534 "*.o*.......o*..*\n"
535 "*..o*o....o*...*\n"
536 "*.*..*.**o*..*.*\n"
537 "*....o.*o...x..*\n"
538 "****************\n"
539 "\n"
540 "****************\n"
541 "*.o....o..x*...*\n"
542 "*..*o*o...*o...*\n"
543 "*...*o*....*o..*\n"
544 "*...o..*...o*o.*\n"
545 "*.*o*...*.o*...*\n"
546 "*.o*o.*.o.*....*\n"
547 "*o*X..*.....*..*\n"
548 "****************\n"
549 "\n"
550 "****************\n"
551 "*o...**.....**o*\n"
552 "*.*..*......*o.*\n"
553 "*.o*...o**..o..*\n"
554 "*.*....*o......*\n"
555 "*....*...o*....*\n"
556 "*.**.o*.**o..*x*\n"
557 "*.o*.*o.....**X*\n"
558 "****************\n"
559 "\n"
560 "****************\n"
561 "*...o*o........*\n"
562 "**o..o*.**o...**\n"
563 "*.*.*.o...*..*.*\n"
564 "*.x.*..**..*.Xo*\n"
565 "*.*..*...o.*.*.*\n"
566 "**...o**.*o..o**\n"
567 "*........o*o...*\n"
568 "****************";
571 * Display text.
573 void star_display_text(char *str, bool waitkey)
575 int chars_by_line;
576 int lines_by_screen;
577 int chars_for_line;
578 int current_line = 0;
579 int first_char_index = 0;
580 char *ptr_char;
581 char *ptr_line;
582 int i;
583 char line[255];
584 int key;
585 bool go_on;
587 rb->lcd_clear_display();
589 chars_by_line = LCD_WIDTH / char_width;
590 lines_by_screen = LCD_HEIGHT / char_height;
594 ptr_char = str + first_char_index;
595 chars_for_line = 0;
596 i = 0;
597 ptr_line = line;
598 while (i < chars_by_line)
600 switch (*ptr_char)
602 case '\t':
603 case ' ':
604 *(ptr_line++) = ' ';
605 case '\n':
606 case '\0':
607 chars_for_line = i;
608 break;
610 default:
611 *(ptr_line++) = *ptr_char;
613 if (*ptr_char == '\n' || *ptr_char == '\0')
614 break;
615 ptr_char++;
616 i++;
619 if (chars_for_line == 0)
620 chars_for_line = i;
622 line[chars_for_line] = '\0';
624 /* test if we have cut a word. If it is the case we don't have to */
625 /* skip the space */
626 if (i == chars_by_line && chars_for_line == chars_by_line)
627 first_char_index += chars_for_line;
628 else
629 first_char_index += chars_for_line + 1;
631 /* print the line on the screen */
632 rb->lcd_putsxy(0, current_line * char_height, line);
634 /* if the number of line showed on the screen is equals to the */
635 /* maximum number of line we can show, we wait for a key pressed to */
636 /* clear and show the remaining text. */
637 current_line++;
638 if (current_line == lines_by_screen || *ptr_char == '\0')
640 current_line = 0;
641 rb->lcd_update();
642 go_on = false;
643 while (waitkey && !go_on)
645 key = rb->button_get(true);
646 switch (key)
648 case STAR_QUIT:
649 case STAR_LEFT:
650 case STAR_DOWN:
651 go_on = true;
652 break;
654 default:
655 if (rb->default_event_handler(key) == SYS_USB_CONNECTED)
657 usb_detected = true;
658 go_on = true;
659 break;
663 rb->lcd_clear_display();
665 } while (*ptr_char != '\0');
669 * Do a pretty transition from one level to another.
671 static void star_transition_update(void)
673 const int center_x = LCD_WIDTH / 2;
674 const int center_y = LCD_HEIGHT / 2;
675 int x = 0;
676 int y = 0;
677 #if LCD_WIDTH >= LCD_HEIGHT
678 #if defined(IPOD_VIDEO)
679 const int step = 4;
680 #else
681 const int step = 1;
682 #endif
683 const int lcd_demi_width = LCD_WIDTH / 2;
684 int var_y = 0;
686 for (; x < lcd_demi_width ; x+=step)
688 var_y += LCD_HEIGHT;
689 if (var_y > LCD_WIDTH)
691 var_y -= LCD_WIDTH;
692 y+=step;
694 if( x )
696 rb->lcd_update_rect(center_x - x, center_y - y, x*2, step);
697 rb->lcd_update_rect(center_x - x, center_y + y - step, x*2, step);
699 if( y )
701 rb->lcd_update_rect(center_x - x, center_y - y, step, y*2);
702 rb->lcd_update_rect(center_x + x - step, center_y - y, step, y*2);
704 STAR_SLEEP
706 #else
707 int lcd_demi_height = LCD_HEIGHT / 2;
708 int var_x = 0;
710 for (; y < lcd_demi_height ; y++)
712 var_x += LCD_WIDTH;
713 if (var_x > LCD_HEIGHT)
715 var_x -= LCD_HEIGHT;
716 x++;
718 if( x )
720 rb->lcd_update_rect(center_x - x, center_y - y, x * 2, 1);
721 rb->lcd_update_rect(center_x - x, center_y + y - 1, x * 2, 1);
723 if( y )
725 rb->lcd_update_rect(center_x - x, center_y - y, 1, y * 2);
726 rb->lcd_update_rect(center_x + x - 1, center_y - y, 1, y * 2);
728 STAR_SLEEP
730 #endif
731 rb->lcd_update();
735 * Display information board of the current level.
737 static void star_display_board_info(int current_level)
739 int label_pos_y, tile_pos_y;
740 char str_info[32];
742 if (TILE_HEIGHT > char_height)
744 tile_pos_y = LCD_HEIGHT - TILE_HEIGHT;
745 label_pos_y = tile_pos_y + (TILE_HEIGHT - char_height) / 2;
747 else
749 label_pos_y = LCD_HEIGHT - char_height;
750 tile_pos_y = label_pos_y + (char_height - TILE_HEIGHT) / 2;
753 rb->snprintf(str_info, sizeof(str_info), "L:%02d", current_level + 1);
754 rb->lcd_putsxy(STAR_OFFSET_X, label_pos_y, str_info);
755 rb->snprintf(str_info, sizeof(str_info), "S:%02d", star_count);
756 rb->lcd_putsxy(LCD_WIDTH/2 - 2 * char_width, label_pos_y, str_info);
757 rb->lcd_putsxy(STAR_OFFSET_X + (STAR_WIDTH-1) * TILE_WIDTH - 2 * char_width,
758 label_pos_y, "C:");
760 rb->lcd_bitmap_part(star_tiles, 0, control == STAR_CONTROL_BALL ?
761 BALL*TILE_HEIGHT : BLOCK*TILE_HEIGHT, TILE_WIDTH,
762 STAR_OFFSET_X + (STAR_WIDTH-1) * TILE_WIDTH,
763 tile_pos_y, TILE_WIDTH, TILE_HEIGHT);
765 rb->lcd_update_rect(0, MIN(label_pos_y, tile_pos_y), LCD_WIDTH,
766 MAX(TILE_HEIGHT, char_height));
771 * Load a level into board array.
773 static int star_load_level(int current_level)
775 int x, y;
776 char *ptr_tab;
778 if (current_level < 0)
779 current_level = 0;
780 else if (current_level > STAR_LEVEL_COUNT-1)
781 current_level = STAR_LEVEL_COUNT-1;
784 ptr_tab = levels + current_level * STAR_LEVEL_SIZE;
785 control = STAR_CONTROL_BALL;
786 star_count = 0;
788 rb->lcd_clear_display();
790 for (y = 0 ; y < STAR_HEIGHT ; y++)
792 for (x = 0 ; x < STAR_WIDTH ; x++)
794 board[y][x] = *ptr_tab;
795 switch (*ptr_tab)
797 # define DRAW_TILE( a ) \
798 rb->lcd_bitmap_part( star_tiles, 0, \
799 a*TILE_HEIGHT, TILE_WIDTH, \
800 STAR_OFFSET_X + x * TILE_WIDTH, \
801 STAR_OFFSET_Y + y * TILE_HEIGHT, \
802 TILE_WIDTH, TILE_HEIGHT);
803 case STAR_VOID:
804 DRAW_TILE( SPACE );
805 break;
807 case STAR_WALL:
808 DRAW_TILE( WALL );
809 break;
811 case STAR_STAR:
812 DRAW_TILE( STAR );
813 star_count++;
814 break;
816 case STAR_BALL:
817 ball_x = x;
818 ball_y = y;
819 DRAW_TILE( BALL );
820 break;
823 case STAR_BLOCK:
824 block_x = x;
825 block_y = y;
826 DRAW_TILE( BLOCK );
827 break;
829 ptr_tab++;
831 ptr_tab++;
833 star_display_board_info(current_level);
834 star_transition_update();
835 return 1;
838 static void star_animate_tile(int tile_no, int start_x, int start_y,
839 int delta_x, int delta_y)
841 int i;
843 if (delta_x != 0) /* horizontal */
845 for (i = 1 ; i <= TILE_WIDTH ; i++)
847 STAR_SLEEP
848 rb->lcd_bitmap_part(star_tiles, 0, SPACE * TILE_HEIGHT, TILE_WIDTH,
849 start_x, start_y, TILE_WIDTH, TILE_HEIGHT);
850 rb->lcd_bitmap_part(star_tiles, 0, tile_no * TILE_HEIGHT, TILE_WIDTH,
851 start_x + delta_x * i, start_y, TILE_WIDTH, TILE_HEIGHT);
852 rb->lcd_update_rect(start_x + delta_x * i - (delta_x>0?1:0),
853 start_y, TILE_WIDTH + 1, TILE_HEIGHT);
856 else /* vertical */
858 for (i = 1 ; i <= TILE_HEIGHT ; i++)
860 STAR_SLEEP
861 rb->lcd_bitmap_part(star_tiles, 0, SPACE * TILE_HEIGHT, TILE_WIDTH,
862 start_x, start_y, TILE_WIDTH, TILE_HEIGHT);
863 rb->lcd_bitmap_part(star_tiles, 0, tile_no * TILE_HEIGHT, TILE_WIDTH,
864 start_x, start_y + delta_y * i, TILE_WIDTH, TILE_HEIGHT);
865 rb->lcd_update_rect(start_x, start_y + delta_y * i - (delta_y>0?1:0),
866 TILE_WIDTH, TILE_HEIGHT + 1);
872 * Run the game.
874 static int star_run_game(int current_level)
876 int move_x = 0;
877 int move_y = 0;
878 int key;
879 int lastkey = BUTTON_NONE;
881 int label_offset_y;
883 label_offset_y = LCD_HEIGHT - char_height;
885 if (!star_load_level(current_level))
886 return 0;
888 while (true)
890 move_x = 0;
891 move_y = 0;
893 while ((move_x == 0) && (move_y == 0))
895 key = rb->button_get(true);
896 switch (key)
898 #ifdef STAR_RC_QUIT
899 case STAR_RC_QUIT:
900 #endif
901 case STAR_QUIT:
902 return -1;
904 case STAR_LEFT:
905 move_x = -1;
906 break;
908 case STAR_RIGHT:
909 move_x = 1;
910 break;
912 case STAR_UP:
913 move_y = -1;
914 break;
916 case STAR_DOWN:
917 move_y = 1;
918 break;
920 case STAR_LEVEL_DOWN:
921 #ifdef STAR_LEVEL_DOWN_PRE
922 if (lastkey != STAR_LEVEL_DOWN_PRE)
923 break;
924 #endif
925 if (current_level > 0)
927 current_level--;
928 star_load_level(current_level);
930 break;
932 case STAR_LEVEL_REPEAT:
933 star_load_level(current_level);
934 break;
936 case STAR_LEVEL_UP:
937 #ifdef STAR_LEVEL_UP_PRE
938 if (lastkey != STAR_LEVEL_UP_PRE)
939 break;
940 #endif
941 if (current_level < STAR_LEVEL_COUNT - 1)
943 current_level++;
944 star_load_level(current_level);
946 break;
948 case STAR_TOGGLE_CONTROL:
949 #ifdef STAR_TOGGLE_CONTROL_PRE
950 if (lastkey != STAR_TOGGLE_CONTROL_PRE)
951 break;
952 #endif
953 #ifdef STAR_TOGGLE_CONTROL2
954 case STAR_TOGGLE_CONTROL2:
955 #endif
956 if (control == STAR_CONTROL_BALL)
957 control = STAR_CONTROL_BLOCK;
958 else
959 control = STAR_CONTROL_BALL;
960 star_display_board_info(current_level);
961 break;
963 default:
964 if (rb->default_event_handler(key) == SYS_USB_CONNECTED)
966 usb_detected = true;
967 return 0;
969 break;
971 if (key != BUTTON_NONE)
972 lastkey = key;
975 if (control == STAR_CONTROL_BALL)
977 board[ball_y][ball_x] = STAR_VOID;
978 while ((board[ball_y + move_y][ball_x + move_x] == STAR_VOID
979 || board[ball_y + move_y][ball_x + move_x] == STAR_STAR))
982 star_animate_tile(BALL, STAR_OFFSET_X + ball_x * TILE_WIDTH,
983 STAR_OFFSET_Y + ball_y * TILE_HEIGHT,
984 move_x, move_y);
985 ball_x += move_x;
986 ball_y += move_y;
988 if (board[ball_y][ball_x] == STAR_STAR)
990 board[ball_y][ball_x] = STAR_VOID;
991 star_count--;
993 star_display_board_info(current_level);
996 board[ball_y][ball_x] = STAR_BALL;
998 else
1000 board[block_y][block_x] = STAR_VOID;
1001 while (board[block_y + move_y][block_x + move_x] == STAR_VOID)
1003 star_animate_tile(BLOCK, STAR_OFFSET_X + block_x * TILE_WIDTH,
1004 STAR_OFFSET_Y + block_y * TILE_HEIGHT,
1005 move_x, move_y);
1006 block_x += move_x;
1007 block_y += move_y;
1009 board[block_y][block_x] = STAR_BLOCK;
1012 if (star_count == 0)
1014 current_level++;
1015 if (current_level == STAR_LEVEL_COUNT)
1017 rb->lcd_clear_display();
1018 star_display_text("Congratulations!", true);
1019 rb->lcd_update();
1021 /* There is no such level as STAR_LEVEL_COUNT so it can't be the
1022 * current_level */
1023 current_level--;
1024 return 1;
1026 star_load_level(current_level);
1032 * Display the choice menu.
1034 static int star_menu(void)
1036 int selection, level=1;
1037 bool menu_quit = false;
1038 struct viewport vp[NB_SCREENS];
1039 /* get the size of char */
1040 rb->lcd_getstringsize("a", &char_width, &char_height);
1042 MENUITEM_STRINGLIST(menu,"Star Menu",NULL,"Play","Choose Level",
1043 "Information","Keys","Quit");
1044 FOR_NB_SCREENS(selection)
1046 rb->viewport_set_defaults(&vp[selection], selection);
1047 #if LCD_DEPTH > 1
1048 if (rb->screens[selection]->depth > 1)
1050 vp->bg_pattern = LCD_BLACK;
1051 vp->fg_pattern = LCD_WHITE;
1053 #endif
1055 while(!menu_quit)
1057 switch(rb->do_menu(&menu, &selection, vp, false))
1059 case 0:
1060 menu_quit = true;
1061 break;
1062 case 1:
1063 rb->set_int("Level", "", UNIT_INT, &level,
1064 NULL, 1, 1, STAR_LEVEL_COUNT, NULL );
1065 break;
1066 case 2:
1067 star_display_text(
1068 "INFO\n\n"
1069 "Take all the stars to go to the next level. "
1070 "You can toggle control with the block to "
1071 "use it as a mobile wall. The block cannot "
1072 "take stars.", true);
1073 break;
1074 case 3:
1075 #if CONFIG_KEYPAD == RECORDER_PAD
1076 star_display_text("KEYS\n\n"
1077 "[ON] Toggle Ctl.\n"
1078 "[OFF] Exit\n"
1079 "[F1] Prev. level\n"
1080 "[F2] Reset level\n"
1081 "[F3] Next level", true);
1082 #elif CONFIG_KEYPAD == ONDIO_PAD
1083 star_display_text("KEYS\n\n"
1084 "[MODE] Toggle Ctl\n"
1085 "[OFF] Exit\n"
1086 "[M <] Prev. level\n"
1087 "[M ^] Reset level\n"
1088 "[M >] Next level", true);
1089 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
1090 star_display_text("KEYS\n\n"
1091 "[MODE/NAVI] Toggle Ctrl\n"
1092 "[OFF] Exit\n"
1093 "[ON + LEFT] Prev. level\n"
1094 "[ON + NAVI] Reset level\n"
1095 "[ON + RIGHT] Next level", true);
1096 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
1097 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
1098 star_display_text("KEYS\n\n"
1099 "[SELECT] Toggle Ctl\n"
1100 "[S + MENU] Exit\n"
1101 "[S <] Prev. level\n"
1102 "[S + PLAY] Reset level\n"
1103 "[S >] Next level", true);
1104 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
1105 star_display_text("KEYS\n\n"
1106 "[SELECT] Toggle Ctl\n"
1107 "[POWER] Exit\n"
1108 "[REC..] Prev. level\n"
1109 "[PLAY] Reset level\n"
1110 "[REC] Next level", true);
1111 #elif CONFIG_KEYPAD == GIGABEAT_PAD
1112 star_display_text("KEYS\n\n"
1113 "[SELECT] Toggle Control\n"
1114 "[POWER] Exit\n"
1115 "[VOL DOWN] Prev. level\n"
1116 "[A] Reset level\n"
1117 "[VOL UP] Next level", true);
1118 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
1119 star_display_text("KEYS\n\n"
1120 "[REW] Toggle Ctl\n"
1121 "[POWER] Exit\n"
1122 "[PLAY+DOWN] Prev. level\n"
1123 "[PLAY+RIGHT] Reset level\n"
1124 "[PLAY+UP] Next level", true);
1125 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
1126 star_display_text("KEYS\n\n"
1127 "[SELECT] Toggle Control\n"
1128 "[BACK] Exit\n"
1129 "[VOL DOWN] Prev. level\n"
1130 "[MENU] Reset level\n"
1131 "[VOL UP] Next level", true);
1132 #endif
1133 #ifdef HAVE_TOUCHSCREEN
1134 star_display_text("KEYS\n\n"
1135 STAR_TOGGLE_CONTROL_NAME " Toggle Control\n"
1136 STAR_QUIT_NAME " Exit\n"
1137 STAR_LEVEL_DOWN_NAME " Prev. level\n"
1138 STAR_LEVEL_REPEAT_NAME " Reset level\n"
1139 STAR_LEVEL_UP_NAME " Next level", true);
1140 #endif
1141 break;
1142 default:
1143 menu_quit = true;
1144 break;
1148 if (selection == MENU_START)
1150 rb->lcd_setfont(FONT_SYSFIXED);
1151 rb->lcd_getstringsize("a", &char_width, &char_height);
1152 level--;
1153 star_run_game(level);
1155 return PLUGIN_OK;
1159 * Main entry point
1161 enum plugin_status plugin_start(const void* parameter)
1163 (void)parameter;
1165 #if LCD_DEPTH > 1
1166 rb->lcd_set_backdrop(NULL);
1167 rb->lcd_set_background( LCD_BLACK );
1168 rb->lcd_set_foreground( LCD_WHITE );
1169 #endif
1171 /* display choice menu */
1172 return star_menu();
1175 #endif