* Onda VX747: add browse screen, pitchscreen, context menu, quickscreen, rewind...
[kugel-rb.git] / apps / plugins / star.c
blob118a18227c7e179386041ee96122817d6fbf1230
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
23 #include "lib/display_text.h"
24 #include "lib/playback_control.h"
26 PLUGIN_HEADER
28 /* size of a level in file */
29 #define STAR_LEVEL_SIZE ((STAR_WIDTH + 1) * STAR_HEIGHT + 1)
31 /* size of the game board */
32 #define STAR_WIDTH 16
33 #define STAR_HEIGHT 9
35 /* number of level */
36 #define STAR_LEVEL_COUNT 20
38 /* values of object in the board */
39 #define STAR_VOID '.'
40 #define STAR_WALL '*'
41 #define STAR_STAR 'o'
42 #define STAR_BALL 'X'
43 #define STAR_BLOCK 'x'
45 /* sleep time between two frames */
46 #if (LCD_HEIGHT * LCD_WIDTH >= 70000) && defined(IPOD_ARCH)
47 /* iPod 5G LCD is *slow* */
48 #define STAR_SLEEP rb->yield();
49 #elif (LCD_HEIGHT * LCD_WIDTH >= 30000)
50 #define STAR_SLEEP rb->sleep(0);
51 #else
52 #define STAR_SLEEP rb->sleep(1);
53 #endif
55 /* value of ball and block control */
56 #define STAR_CONTROL_BALL 0
57 #define STAR_CONTROL_BLOCK 1
59 /* variable button definitions */
60 #if CONFIG_KEYPAD == RECORDER_PAD
61 #define STAR_QUIT BUTTON_OFF
62 #define STAR_LEFT BUTTON_LEFT
63 #define STAR_RIGHT BUTTON_RIGHT
64 #define STAR_UP BUTTON_UP
65 #define STAR_DOWN BUTTON_DOWN
66 #define STAR_TOGGLE_CONTROL BUTTON_ON
67 #define STAR_TOGGLE_CONTROL2 BUTTON_PLAY
68 #define STAR_LEVEL_UP BUTTON_F3
69 #define STAR_LEVEL_DOWN BUTTON_F1
70 #define STAR_LEVEL_REPEAT BUTTON_F2
71 #define STAR_TOGGLE_CONTROL_NAME "ON"
72 #define STAR_QUIT_NAME "OFF"
73 #define STAR_LEVEL_UP_NAME "F3"
74 #define STAR_LEVEL_DOWN_NAME "F1"
75 #define STAR_LEVEL_REPEAT_NAME "F2"
77 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
78 #define STAR_QUIT BUTTON_OFF
79 #define STAR_LEFT BUTTON_LEFT
80 #define STAR_RIGHT BUTTON_RIGHT
81 #define STAR_UP BUTTON_UP
82 #define STAR_DOWN BUTTON_DOWN
83 #define STAR_TOGGLE_CONTROL BUTTON_ON
84 #define STAR_TOGGLE_CONTROL2 BUTTON_SELECT
85 #define STAR_LEVEL_UP BUTTON_F3
86 #define STAR_LEVEL_DOWN BUTTON_F1
87 #define STAR_LEVEL_REPEAT BUTTON_F2
88 #define STAR_TOGGLE_CONTROL_NAME "ON/SELECT"
89 #define STAR_QUIT_NAME "OFF"
90 #define STAR_LEVEL_UP_NAME "F3"
91 #define STAR_LEVEL_DOWN_NAME "F1"
92 #define STAR_LEVEL_REPEAT_NAME "F2"
94 #elif CONFIG_KEYPAD == ONDIO_PAD
95 #define STAR_QUIT BUTTON_OFF
96 #define STAR_LEFT BUTTON_LEFT
97 #define STAR_RIGHT BUTTON_RIGHT
98 #define STAR_UP BUTTON_UP
99 #define STAR_DOWN BUTTON_DOWN
100 #define STAR_TOGGLE_CONTROL_PRE BUTTON_MENU
101 #define STAR_TOGGLE_CONTROL (BUTTON_MENU | BUTTON_REL)
102 #define STAR_LEVEL_UP (BUTTON_MENU | BUTTON_RIGHT)
103 #define STAR_LEVEL_DOWN (BUTTON_MENU | BUTTON_LEFT)
104 #define STAR_LEVEL_REPEAT (BUTTON_MENU | BUTTON_UP)
105 #define STAR_TOGGLE_CONTROL_NAME "MODE"
106 #define STAR_QUIT_NAME "OFF"
107 #define STAR_LEVEL_UP_NAME "M >"
108 #define STAR_LEVEL_DOWN_NAME "M <"
109 #define STAR_LEVEL_REPEAT_NAME "M ^"
111 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
112 (CONFIG_KEYPAD == IRIVER_H300_PAD)
113 #define STAR_QUIT BUTTON_OFF
114 #define STAR_LEFT BUTTON_LEFT
115 #define STAR_RIGHT BUTTON_RIGHT
116 #define STAR_UP BUTTON_UP
117 #define STAR_DOWN BUTTON_DOWN
118 #define STAR_TOGGLE_CONTROL BUTTON_MODE
119 #define STAR_TOGGLE_CONTROL2 BUTTON_SELECT
120 #define STAR_LEVEL_UP (BUTTON_ON | BUTTON_RIGHT)
121 #define STAR_LEVEL_DOWN (BUTTON_ON | BUTTON_LEFT)
122 #define STAR_LEVEL_REPEAT (BUTTON_ON | BUTTON_SELECT)
123 #define STAR_TOGGLE_CONTROL_NAME "MODE/SELECT"
124 #define STAR_QUIT_NAME "OFF"
125 #define STAR_LEVEL_UP_NAME "ON + RIGHT"
126 #define STAR_LEVEL_DOWN_NAME "ON + LEFT"
127 #define STAR_LEVEL_REPEAT_NAME "ON + NAVI"
129 #define STAR_RC_QUIT BUTTON_RC_STOP
130 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
131 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
132 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
134 #define STAR_QUIT (BUTTON_SELECT | BUTTON_MENU)
135 #define STAR_LEFT BUTTON_LEFT
136 #define STAR_RIGHT BUTTON_RIGHT
137 #define STAR_UP BUTTON_MENU
138 #define STAR_DOWN BUTTON_PLAY
139 #define STAR_TOGGLE_CONTROL_PRE BUTTON_SELECT
140 #define STAR_TOGGLE_CONTROL (BUTTON_SELECT | BUTTON_REL)
141 #define STAR_LEVEL_UP (BUTTON_SELECT | BUTTON_RIGHT)
142 #define STAR_LEVEL_DOWN (BUTTON_SELECT | BUTTON_LEFT)
143 #define STAR_LEVEL_REPEAT (BUTTON_SELECT | BUTTON_PLAY)
144 #define STAR_TOGGLE_CONTROL_NAME "SELECT"
145 #define STAR_QUIT_NAME "S + MENU"
146 #define STAR_LEVEL_UP_NAME "S >"
147 #define STAR_LEVEL_DOWN_NAME "S <"
148 #define STAR_LEVEL_REPEAT_NAME "S + PLAY"
150 #elif (CONFIG_KEYPAD == IAUDIO_X5M5_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_PRE BUTTON_REC
159 #define STAR_LEVEL_UP (BUTTON_REC|BUTTON_REL)
160 #define STAR_LEVEL_DOWN_PRE BUTTON_REC
161 #define STAR_LEVEL_DOWN (BUTTON_REC|BUTTON_REPEAT)
162 #define STAR_LEVEL_REPEAT BUTTON_PLAY
163 #define STAR_TOGGLE_CONTROL_NAME "SELECT"
164 #define STAR_QUIT_NAME "POWER"
165 #define STAR_LEVEL_UP_NAME "REC"
166 #define STAR_LEVEL_DOWN_NAME "REC.."
167 #define STAR_LEVEL_REPEAT_NAME "PLAY"
169 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
171 #define STAR_QUIT BUTTON_POWER
172 #define STAR_LEFT BUTTON_LEFT
173 #define STAR_RIGHT BUTTON_RIGHT
174 #define STAR_UP BUTTON_UP
175 #define STAR_DOWN BUTTON_DOWN
176 #define STAR_TOGGLE_CONTROL BUTTON_SELECT
177 #define STAR_LEVEL_UP BUTTON_VOL_UP
178 #define STAR_LEVEL_DOWN BUTTON_VOL_DOWN
179 #define STAR_LEVEL_REPEAT BUTTON_A
180 #define STAR_TOGGLE_CONTROL_NAME "SELECT"
181 #define STAR_QUIT_NAME "POWER"
182 #define STAR_LEVEL_UP_NAME "VOL UP"
183 #define STAR_LEVEL_DOWN_NAME "VOL DOWN"
184 #define STAR_LEVEL_REPEAT_NAME "A"
186 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
187 (CONFIG_KEYPAD == SANSA_C200_PAD) || \
188 (CONFIG_KEYPAD == SANSA_CLIP_PAD) || \
189 (CONFIG_KEYPAD == SANSA_M200_PAD)
191 #define STAR_QUIT BUTTON_POWER
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_SELECT | BUTTON_RIGHT)
198 #define STAR_LEVEL_DOWN (BUTTON_SELECT | BUTTON_LEFT)
199 #define STAR_LEVEL_REPEAT (BUTTON_SELECT | BUTTON_DOWN)
200 #define STAR_TOGGLE_CONTROL_NAME "SELECT"
201 #define STAR_QUIT_NAME "POWER"
202 #define STAR_LEVEL_UP_NAME "SELECT + RIGHT"
203 #define STAR_LEVEL_DOWN_NAME "SELECT + LEFT"
204 #define STAR_LEVEL_REPEAT_NAME "SELECT + DOWN"
206 #elif (CONFIG_KEYPAD == SANSA_FUZE_PAD)
208 #define STAR_QUIT (BUTTON_HOME|BUTTON_REPEAT)
209 #define STAR_LEFT BUTTON_LEFT
210 #define STAR_RIGHT BUTTON_RIGHT
211 #define STAR_UP BUTTON_UP
212 #define STAR_DOWN BUTTON_DOWN
213 #define STAR_TOGGLE_CONTROL BUTTON_SELECT
214 #define STAR_LEVEL_UP (BUTTON_SELECT | BUTTON_RIGHT)
215 #define STAR_LEVEL_DOWN (BUTTON_SELECT | BUTTON_LEFT)
216 #define STAR_LEVEL_REPEAT (BUTTON_SELECT | BUTTON_DOWN)
217 #define STAR_TOGGLE_CONTROL_NAME "SELECT"
218 #define STAR_QUIT_NAME "HOME"
219 #define STAR_LEVEL_UP_NAME "SELECT + RIGHT"
220 #define STAR_LEVEL_DOWN_NAME "SELECT + LEFT"
221 #define STAR_LEVEL_REPEAT_NAME "SELECT + DOWN"
223 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
225 #define STAR_QUIT BUTTON_POWER
226 #define STAR_LEFT BUTTON_LEFT
227 #define STAR_RIGHT BUTTON_RIGHT
228 #define STAR_UP BUTTON_SCROLL_UP
229 #define STAR_DOWN BUTTON_SCROLL_DOWN
230 #define STAR_TOGGLE_CONTROL BUTTON_REW
231 #define STAR_LEVEL_UP (BUTTON_PLAY | BUTTON_SCROLL_UP)
232 #define STAR_LEVEL_DOWN (BUTTON_PLAY | BUTTON_SCROLL_DOWN)
233 #define STAR_LEVEL_REPEAT (BUTTON_PLAY | BUTTON_RIGHT)
234 #define STAR_TOGGLE_CONTROL_NAME "REW"
235 #define STAR_QUIT_NAME "POWER"
236 #define STAR_LEVEL_UP_NAME "PLAY+UP"
237 #define STAR_LEVEL_DOWN_NAME "PLAY+DOWN"
238 #define STAR_LEVEL_REPEAT_NAME "PLAY+RIGHT"
240 #elif (CONFIG_KEYPAD == GIGABEAT_S_PAD)
242 #define STAR_QUIT BUTTON_BACK
243 #define STAR_LEFT BUTTON_LEFT
244 #define STAR_RIGHT BUTTON_RIGHT
245 #define STAR_UP BUTTON_UP
246 #define STAR_DOWN BUTTON_DOWN
247 #define STAR_TOGGLE_CONTROL BUTTON_SELECT
248 #define STAR_LEVEL_UP BUTTON_VOL_UP
249 #define STAR_LEVEL_DOWN BUTTON_VOL_DOWN
250 #define STAR_LEVEL_REPEAT BUTTON_MENU
251 #define STAR_TOGGLE_CONTROL_NAME "SELECT"
252 #define STAR_QUIT_NAME "BACK"
253 #define STAR_LEVEL_UP_NAME "VOL UP"
254 #define STAR_LEVEL_DOWN_NAME "VOL DOWN"
255 #define STAR_LEVEL_REPEAT_NAME "MENU"
257 #elif (CONFIG_KEYPAD == MROBE100_PAD)
259 #define STAR_QUIT BUTTON_POWER
260 #define STAR_LEFT BUTTON_LEFT
261 #define STAR_RIGHT BUTTON_RIGHT
262 #define STAR_UP BUTTON_UP
263 #define STAR_DOWN BUTTON_DOWN
264 #define STAR_TOGGLE_CONTROL BUTTON_SELECT
265 #define STAR_LEVEL_UP BUTTON_PLAY
266 #define STAR_LEVEL_DOWN BUTTON_MENU
267 #define STAR_LEVEL_REPEAT BUTTON_DISPLAY
268 #define STAR_TOGGLE_CONTROL_NAME "SELECT"
269 #define STAR_QUIT_NAME "POWER"
270 #define STAR_LEVEL_UP_NAME "PLAY"
271 #define STAR_LEVEL_DOWN_NAME "MENU"
272 #define STAR_LEVEL_REPEAT_NAME "DISPLAY"
274 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
276 #define STAR_QUIT BUTTON_RC_REC
277 #define STAR_LEFT BUTTON_RC_REW
278 #define STAR_RIGHT BUTTON_RC_FF
279 #define STAR_UP BUTTON_RC_VOL_UP
280 #define STAR_DOWN BUTTON_RC_VOL_DOWN
281 #define STAR_TOGGLE_CONTROL BUTTON_RC_MODE
282 #define STAR_LEVEL_UP (BUTTON_RC_PLAY|BUTTON_RC_VOL_UP)
283 #define STAR_LEVEL_DOWN (BUTTON_RC_PLAY|BUTTON_RC_VOL_DOWN)
284 #define STAR_LEVEL_REPEAT (BUTTON_RC_PLAY|BUTTON_RC_MENU)
285 #define STAR_TOGGLE_CONTROL_NAME "MODE"
286 #define STAR_QUIT_NAME "REC"
287 #define STAR_LEVEL_UP_NAME "PLAY+VOL+"
288 #define STAR_LEVEL_DOWN_NAME "PLAY+VOL-"
289 #define STAR_LEVEL_REPEAT_NAME "PLAY+MENU"
291 #elif (CONFIG_KEYPAD == COWOND2_PAD)
293 #define STAR_QUIT BUTTON_POWER
294 #define STAR_QUIT_NAME "POWER"
296 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
298 #define STAR_QUIT BUTTON_BACK
299 #define STAR_LEFT BUTTON_LEFT
300 #define STAR_RIGHT BUTTON_RIGHT
301 #define STAR_UP BUTTON_UP
302 #define STAR_DOWN BUTTON_DOWN
303 #define STAR_TOGGLE_CONTROL BUTTON_PLAY
304 #define STAR_LEVEL_UP (BUTTON_CUSTOM | BUTTON_UP)
305 #define STAR_LEVEL_DOWN (BUTTON_CUSTOM | BUTTON_DOWN)
306 #define STAR_LEVEL_REPEAT (BUTTON_CUSTOM | BUTTON_RIGHT)
307 #define STAR_TOGGLE_CONTROL_NAME "PLAY"
308 #define STAR_QUIT_NAME "BACK"
309 #define STAR_LEVEL_UP_NAME "CUSTOM+UP"
310 #define STAR_LEVEL_DOWN_NAME "CUSTOM+DOWN"
311 #define STAR_LEVEL_REPEAT_NAME "CUSTOM+RIGHT"
313 #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
315 #define STAR_QUIT BUTTON_POWER
316 #define STAR_LEFT BUTTON_LEFT
317 #define STAR_RIGHT BUTTON_RIGHT
318 #define STAR_UP BUTTON_UP
319 #define STAR_DOWN BUTTON_DOWN
320 #define STAR_TOGGLE_CONTROL BUTTON_SELECT
321 #define STAR_LEVEL_UP BUTTON_VOL_UP
322 #define STAR_LEVEL_DOWN BUTTON_VOL_DOWN
323 #define STAR_LEVEL_REPEAT BUTTON_VIEW
324 #define STAR_TOGGLE_CONTROL_NAME "SELECT"
325 #define STAR_QUIT_NAME "POWER"
326 #define STAR_LEVEL_UP_NAME "VOL UP"
327 #define STAR_LEVEL_DOWN_NAME "VOL DOWN"
328 #define STAR_LEVEL_REPEAT_NAME "VIEW"
330 #elif (CONFIG_KEYPAD == ONDAVX747_PAD)
332 #define STAR_QUIT BUTTON_POWER
333 #define STAR_QUIT_NAME "POWER"
335 #elif CONFIG_KEYPAD == MROBE500_PAD
336 #define STAR_QUIT BUTTON_POWER
337 #define STAR_QUIT_NAME "POWER"
339 #elif (CONFIG_KEYPAD == SAMSUNG_YH_PAD)
341 #define STAR_QUIT BUTTON_REC
342 #define STAR_LEFT BUTTON_LEFT
343 #define STAR_RIGHT BUTTON_RIGHT
344 #define STAR_UP BUTTON_UP
345 #define STAR_DOWN BUTTON_DOWN
346 #define STAR_LEVEL_UP_PRE (BUTTON_FFWD|BUTTON_UP)
347 #define STAR_LEVEL_UP (BUTTON_REW|BUTTON_UP)
348 #define STAR_LEVEL_DOWN_PRE (BUTTON_FFWD|BUTTON_DOWN)
349 #define STAR_LEVEL_DOWN (BUTTON_REW|BUTTON_DOWN)
350 #define STAR_TOGGLE_CONTROL (BUTTON_PLAY|BUTTON_UP)
351 #define STAR_LEVEL_REPEAT (BUTTON_PLAY|BUTTON_DOWN)
352 #define STAR_TOGGLE_CONTROL_NAME "PLAY"
353 #define STAR_QUIT_NAME "REC"
354 #define STAR_LEVEL_UP_NAME "UP"
355 #define STAR_LEVEL_DOWN_NAME "DOWN"
356 #define STAR_LEVEL_REPEAT_NAME "PLAY"
358 #else
359 #error No keymap defined!
360 #endif
362 #ifdef HAVE_TOUCHSCREEN
363 //#ifndef STAR_QUIT
364 //#define STAR_QUIT BUTTON_TOPLEFT
365 //#define STAR_QUIT_NAME "TOPLEFT"
366 //#endif
367 #ifndef STAR_LEFT
368 #define STAR_LEFT BUTTON_MIDLEFT
369 #endif
370 #ifndef STAR_RIGHT
371 #define STAR_RIGHT BUTTON_MIDRIGHT
372 #endif
373 #ifndef STAR_UP
374 #define STAR_UP BUTTON_TOPMIDDLE
375 #endif
376 #ifndef STAR_DOWN
377 #define STAR_DOWN BUTTON_BOTTOMMIDDLE
378 #endif
379 #ifndef STAR_TOGGLE_CONTROL
380 #define STAR_TOGGLE_CONTROL BUTTON_CENTER
381 #define STAR_TOGGLE_CONTROL_NAME "CENTER"
382 #endif
383 #ifndef STAR_LEVEL_UP
384 #define STAR_LEVEL_UP BUTTON_TOPLEFT
385 #define STAR_LEVEL_UP_NAME "TOPLEFT"
386 #endif
387 #ifndef STAR_LEVEL_DOWN
388 #define STAR_LEVEL_DOWN BUTTON_BOTTOMLEFT
389 #define STAR_LEVEL_DOWN_NAME "BOTTOMLEFT"
390 #endif
391 #ifndef STAR_LEVEL_REPEAT
392 #define STAR_LEVEL_REPEAT BUTTON_BOTTOMRIGHT
393 #define STAR_LEVEL_REPEAT_NAME "BOTTOMRIGHT"
394 #endif
395 #endif
397 /* function returns because of USB? */
398 static bool usb_detected = false;
400 /* position of the ball */
401 static int ball_x, ball_y;
403 /* position of the block */
404 static int block_x, block_y;
406 /* number of stars to get to finish the level */
407 static int star_count;
409 /* the object we control : ball or block */
410 static int control;
412 /* the current board */
413 static char board[STAR_HEIGHT][STAR_WIDTH];
415 #include "pluginbitmaps/star_tiles.h"
417 #define TILE_WIDTH BMPWIDTH_star_tiles
418 #define TILE_HEIGHT (BMPHEIGHT_star_tiles/5)
419 #define STAR_OFFSET_X ((LCD_WIDTH - STAR_WIDTH * TILE_WIDTH) / 2)
420 #define STAR_OFFSET_Y ((LCD_HEIGHT - STAR_HEIGHT * TILE_HEIGHT - MAX(TILE_HEIGHT, 8)) / 2)
422 #define WALL 0
423 #define SPACE 1
424 #define BLOCK 2
425 #define STAR 3
426 #define BALL 4
428 /* char font size */
429 static int char_width = -1;
430 static int char_height = -1;
432 /* this arrays contains a group of levels loaded into memory */
433 static unsigned char* levels =
434 "****************\n"
435 "*X**........o*x*\n"
436 "*..........o.***\n"
437 "*.......**o....*\n"
438 "*...**.o......**\n"
439 "**.o..o.....o..*\n"
440 "*.o......o**.o.*\n"
441 "*.....**o.....o*\n"
442 "****************\n"
443 "\n"
444 ".*..*.*.*...*.**\n"
445 "*...o.........X*\n"
446 "...*o..*o...o...\n"
447 "*.*.o.....o..*.*\n"
448 "......*...o...*.\n"
449 "*....*x*..o....*\n"
450 "...*..*.*...*oo*\n"
451 "*.............*.\n"
452 ".*..*........*..\n"
453 "\n"
454 "****************\n"
455 "*...........o*x*\n"
456 "*...**......**X*\n"
457 "*...*o.........*\n"
458 "*.o.....o**...o*\n"
459 "*.*o..o..o*..o**\n"
460 "*.**o.*o..o.o***\n"
461 "*o....**o......*\n"
462 "****************\n"
463 "\n"
464 "****************\n"
465 "*............*x*\n"
466 "*.....*........*\n"
467 "**o*o.o*o*o*o*o*\n"
468 "*.*.*o.o*.*.*.**\n"
469 "**o*o*o.o*o*o*o*\n"
470 "*.....*........*\n"
471 "*...*.......*X.*\n"
472 "****************\n"
473 "\n"
474 ".**************.\n"
475 "*X..*...*..*...*\n"
476 "*..*o.*.o..o.*.*\n"
477 "**......*..*...*\n"
478 "*o.*o*........**\n"
479 "**.....*.o.*...*\n"
480 "*o*..*.*.*...*x*\n"
481 "*...*....o*..*o*\n"
482 ".**************.\n"
483 "\n"
484 "....************\n"
485 "...*...o...*o.o*\n"
486 "..*....o....*.**\n"
487 ".*.....o.......*\n"
488 "*X.....o.......*\n"
489 "**.....o..*...**\n"
490 "*......o....*..*\n"
491 "*x.*...o..**o..*\n"
492 "****************\n"
493 "\n"
494 "****************\n"
495 "*..............*\n"
496 ".**.***..*o.**o*\n"
497 ".*o..*o.*.*.*.*.\n"
498 "..*..*..***.**..\n"
499 ".**..*..*o*.*o**\n"
500 "*..............*\n"
501 "*..X*o....x..*o*\n"
502 "****************\n"
503 "\n"
504 "***************.\n"
505 "*..o**.........*\n"
506 "*..*o..**.o....*\n"
507 "*..o**.*.*o....*\n"
508 "**.....**..*o*.*\n"
509 "**.*.......o*o.*\n"
510 "*oxo*...o..*X*.*\n"
511 "**.............*\n"
512 ".***************\n"
513 "\n"
514 "..*.***********.\n"
515 ".*o*o......*..X*\n"
516 "*o.o*....o....*.\n"
517 ".*.*..o**..o*..*\n"
518 "*..*o.*oxo....o*\n"
519 "*.....o**.....*.\n"
520 "*o*o.........*..\n"
521 "*...........*...\n"
522 ".***********....\n"
523 "\n"
524 "....***********.\n"
525 "*****.o........*\n"
526 "*...x.***o.o*.o*\n"
527 "*.o...*o.*o...*.\n"
528 "*.....*..o..*.o*\n"
529 "*o*o..*.o*..*X*.\n"
530 ".*o...***..***..\n"
531 "*.........*.*.*.\n"
532 ".*********..*..*\n"
533 "\n"
534 "****************\n"
535 "*......*......X*\n"
536 "*..*oo.....oo.**\n"
537 "**...o...**...o*\n"
538 "*o....*o*oo..***\n"
539 "**.**....**....*\n"
540 "*o..o*.o....x.o*\n"
541 "**o***....*...**\n"
542 "***************.\n"
543 "\n"
544 "**.....**..****.\n"
545 "*X*****o.***.o**\n"
546 "*....oo.....o..*\n"
547 "*.**..**o..*o*.*\n"
548 "*.*.o.*.*o.**..*\n"
549 "*.**..**...*x*.*\n"
550 "*.....o........*\n"
551 "*........o.....*\n"
552 "****************\n"
553 "\n"
554 ".**************.\n"
555 "*.X*........o.**\n"
556 "*.*...*o...o**.*\n"
557 "*.......o....*.*\n"
558 "*.o..........*o*\n"
559 "*.*......o.....*\n"
560 "**......o.o..*o*\n"
561 "*x..*....o.*.*.*\n"
562 ".**************.\n"
563 "\n"
564 "****************\n"
565 "*o*o........o*o*\n"
566 "*.o*X......**..*\n"
567 "*.x........o...*\n"
568 "*........o*....*\n"
569 "*......o.......*\n"
570 "*.o*........*..*\n"
571 "*o*o........o*o*\n"
572 "****************\n"
573 "\n"
574 ".******.********\n"
575 "*.....o*.....o.*\n"
576 "*.*.o.*..*...o.*\n"
577 "*..X*...*oo.*o.*\n"
578 ".*.*...*.o..x*.*\n"
579 "*o.......*..*o.*\n"
580 ".*......o.....*.\n"
581 "*o............o*\n"
582 "****************\n"
583 "\n"
584 "****************\n"
585 "**.x*o.o......o*\n"
586 "*o.Xo*o.......**\n"
587 "**.***........**\n"
588 "**.....o*o*....*\n"
589 "*oo.......o*o..*\n"
590 "**.o....****o..*\n"
591 "**o*..*........*\n"
592 "****************\n"
593 "\n"
594 "****************\n"
595 "*.o*........*X.*\n"
596 "*.*..o*oo*o..*.*\n"
597 "*....*o**o*.o..*\n"
598 "*.o*.......o*..*\n"
599 "*..o*o....o*...*\n"
600 "*.*..*.**o*..*.*\n"
601 "*....o.*o...x..*\n"
602 "****************\n"
603 "\n"
604 "****************\n"
605 "*.o....o..x*...*\n"
606 "*..*o*o...*o...*\n"
607 "*...*o*....*o..*\n"
608 "*...o..*...o*o.*\n"
609 "*.*o*...*.o*...*\n"
610 "*.o*o.*.o.*....*\n"
611 "*o*X..*.....*..*\n"
612 "****************\n"
613 "\n"
614 "****************\n"
615 "*o...**.....**o*\n"
616 "*.*..*......*o.*\n"
617 "*.o*...o**..o..*\n"
618 "*.*....*o......*\n"
619 "*....*...o*....*\n"
620 "*.**.o*.**o..*x*\n"
621 "*.o*.*o.....**X*\n"
622 "****************\n"
623 "\n"
624 "****************\n"
625 "*...o*o........*\n"
626 "**o..o*.**o...**\n"
627 "*.*.*.o...*..*.*\n"
628 "*.x.*..**..*.Xo*\n"
629 "*.*..*...o.*.*.*\n"
630 "**...o**.*o..o**\n"
631 "*........o*o...*\n"
632 "****************";
635 * Do a pretty transition from one level to another.
637 static void star_transition_update(void)
639 const int center_x = LCD_WIDTH / 2;
640 const int center_y = LCD_HEIGHT / 2;
641 int x = 0;
642 int y = 0;
643 #if LCD_WIDTH >= LCD_HEIGHT
644 #if defined(IPOD_VIDEO)
645 const int step = 4;
646 #else
647 const int step = 1;
648 #endif
649 const int lcd_demi_width = LCD_WIDTH / 2;
650 int var_y = 0;
652 for (; x < lcd_demi_width ; x+=step)
654 var_y += LCD_HEIGHT;
655 if (var_y > LCD_WIDTH)
657 var_y -= LCD_WIDTH;
658 y+=step;
660 if( x )
662 rb->lcd_update_rect(center_x - x, center_y - y, x*2, step);
663 rb->lcd_update_rect(center_x - x, center_y + y - step, x*2, step);
665 if( y )
667 rb->lcd_update_rect(center_x - x, center_y - y, step, y*2);
668 rb->lcd_update_rect(center_x + x - step, center_y - y, step, y*2);
670 STAR_SLEEP
672 #else
673 int lcd_demi_height = LCD_HEIGHT / 2;
674 int var_x = 0;
676 for (; y < lcd_demi_height ; y++)
678 var_x += LCD_WIDTH;
679 if (var_x > LCD_HEIGHT)
681 var_x -= LCD_HEIGHT;
682 x++;
684 if( x )
686 rb->lcd_update_rect(center_x - x, center_y - y, x * 2, 1);
687 rb->lcd_update_rect(center_x - x, center_y + y - 1, x * 2, 1);
689 if( y )
691 rb->lcd_update_rect(center_x - x, center_y - y, 1, y * 2);
692 rb->lcd_update_rect(center_x + x - 1, center_y - y, 1, y * 2);
694 STAR_SLEEP
696 #endif
697 rb->lcd_update();
701 * Display information board of the current level.
703 static void star_display_board_info(int current_level)
705 int label_pos_y, tile_pos_y;
706 char str_info[32];
708 if (TILE_HEIGHT > char_height)
710 tile_pos_y = LCD_HEIGHT - TILE_HEIGHT;
711 label_pos_y = tile_pos_y + (TILE_HEIGHT - char_height) / 2;
713 else
715 label_pos_y = LCD_HEIGHT - char_height;
716 tile_pos_y = label_pos_y + (char_height - TILE_HEIGHT) / 2;
719 rb->snprintf(str_info, sizeof(str_info), "L:%02d", current_level + 1);
720 rb->lcd_putsxy(STAR_OFFSET_X, label_pos_y, str_info);
721 rb->snprintf(str_info, sizeof(str_info), "S:%02d", star_count);
722 rb->lcd_putsxy(LCD_WIDTH/2 - 2 * char_width, label_pos_y, str_info);
723 rb->lcd_putsxy(STAR_OFFSET_X + (STAR_WIDTH-1) * TILE_WIDTH - 2 * char_width,
724 label_pos_y, "C:");
726 rb->lcd_bitmap_part(star_tiles, 0, control == STAR_CONTROL_BALL ?
727 BALL*TILE_HEIGHT : BLOCK*TILE_HEIGHT, TILE_WIDTH,
728 STAR_OFFSET_X + (STAR_WIDTH-1) * TILE_WIDTH,
729 tile_pos_y, TILE_WIDTH, TILE_HEIGHT);
731 rb->lcd_update_rect(0, MIN(label_pos_y, tile_pos_y), LCD_WIDTH,
732 MAX(TILE_HEIGHT, char_height));
737 * Load a level into board array.
739 static int star_load_level(int current_level)
741 int x, y;
742 char *ptr_tab;
744 if (current_level < 0)
745 current_level = 0;
746 else if (current_level > STAR_LEVEL_COUNT-1)
747 current_level = STAR_LEVEL_COUNT-1;
750 ptr_tab = levels + current_level * STAR_LEVEL_SIZE;
751 control = STAR_CONTROL_BALL;
752 star_count = 0;
754 rb->lcd_clear_display();
756 for (y = 0 ; y < STAR_HEIGHT ; y++)
758 for (x = 0 ; x < STAR_WIDTH ; x++)
760 board[y][x] = *ptr_tab;
761 switch (*ptr_tab)
763 # define DRAW_TILE( a ) \
764 rb->lcd_bitmap_part( star_tiles, 0, \
765 a*TILE_HEIGHT, TILE_WIDTH, \
766 STAR_OFFSET_X + x * TILE_WIDTH, \
767 STAR_OFFSET_Y + y * TILE_HEIGHT, \
768 TILE_WIDTH, TILE_HEIGHT);
769 case STAR_VOID:
770 DRAW_TILE( SPACE );
771 break;
773 case STAR_WALL:
774 DRAW_TILE( WALL );
775 break;
777 case STAR_STAR:
778 DRAW_TILE( STAR );
779 star_count++;
780 break;
782 case STAR_BALL:
783 ball_x = x;
784 ball_y = y;
785 DRAW_TILE( BALL );
786 break;
789 case STAR_BLOCK:
790 block_x = x;
791 block_y = y;
792 DRAW_TILE( BLOCK );
793 break;
795 ptr_tab++;
797 ptr_tab++;
799 star_display_board_info(current_level);
800 star_transition_update();
801 return 1;
804 static void star_animate_tile(int tile_no, int start_x, int start_y,
805 int delta_x, int delta_y)
807 int i;
809 if (delta_x != 0) /* horizontal */
811 for (i = 1 ; i <= TILE_WIDTH ; i++)
813 STAR_SLEEP
814 rb->lcd_bitmap_part(star_tiles, 0, SPACE * TILE_HEIGHT, TILE_WIDTH,
815 start_x, start_y, TILE_WIDTH, TILE_HEIGHT);
816 rb->lcd_bitmap_part(star_tiles, 0, tile_no * TILE_HEIGHT, TILE_WIDTH,
817 start_x + delta_x * i, start_y, TILE_WIDTH, TILE_HEIGHT);
818 rb->lcd_update_rect(start_x + delta_x * i - (delta_x>0?1:0),
819 start_y, TILE_WIDTH + 1, TILE_HEIGHT);
822 else /* vertical */
824 for (i = 1 ; i <= TILE_HEIGHT ; i++)
826 STAR_SLEEP
827 rb->lcd_bitmap_part(star_tiles, 0, SPACE * TILE_HEIGHT, TILE_WIDTH,
828 start_x, start_y, TILE_WIDTH, TILE_HEIGHT);
829 rb->lcd_bitmap_part(star_tiles, 0, tile_no * TILE_HEIGHT, TILE_WIDTH,
830 start_x, start_y + delta_y * i, TILE_WIDTH, TILE_HEIGHT);
831 rb->lcd_update_rect(start_x, start_y + delta_y * i - (delta_y>0?1:0),
832 TILE_WIDTH, TILE_HEIGHT + 1);
838 * Run the game.
840 static int star_run_game(int current_level)
842 int move_x = 0;
843 int move_y = 0;
844 int key;
845 int lastkey = BUTTON_NONE;
847 int label_offset_y;
849 label_offset_y = LCD_HEIGHT - char_height;
851 if (!star_load_level(current_level))
852 return 0;
854 while (true)
856 move_x = 0;
857 move_y = 0;
859 while ((move_x == 0) && (move_y == 0))
861 key = rb->button_get(true);
862 switch (key)
864 #ifdef STAR_RC_QUIT
865 case STAR_RC_QUIT:
866 #endif
867 case STAR_QUIT:
868 return -1;
870 case STAR_LEFT:
871 move_x = -1;
872 break;
874 case STAR_RIGHT:
875 move_x = 1;
876 break;
878 case STAR_UP:
879 move_y = -1;
880 break;
882 case STAR_DOWN:
883 move_y = 1;
884 break;
886 case STAR_LEVEL_DOWN:
887 #ifdef STAR_LEVEL_DOWN_PRE
888 if (lastkey != STAR_LEVEL_DOWN_PRE)
889 break;
890 #endif
891 if (current_level > 0)
893 current_level--;
894 star_load_level(current_level);
896 break;
898 case STAR_LEVEL_REPEAT:
899 star_load_level(current_level);
900 break;
902 case STAR_LEVEL_UP:
903 #ifdef STAR_LEVEL_UP_PRE
904 if (lastkey != STAR_LEVEL_UP_PRE)
905 break;
906 #endif
907 if (current_level < STAR_LEVEL_COUNT - 1)
909 current_level++;
910 star_load_level(current_level);
912 break;
914 case STAR_TOGGLE_CONTROL:
915 #ifdef STAR_TOGGLE_CONTROL_PRE
916 if (lastkey != STAR_TOGGLE_CONTROL_PRE)
917 break;
918 #endif
919 #ifdef STAR_TOGGLE_CONTROL2
920 case STAR_TOGGLE_CONTROL2:
921 #endif
922 if (control == STAR_CONTROL_BALL)
923 control = STAR_CONTROL_BLOCK;
924 else
925 control = STAR_CONTROL_BALL;
926 star_display_board_info(current_level);
927 break;
929 default:
930 if (rb->default_event_handler(key) == SYS_USB_CONNECTED)
932 usb_detected = true;
933 return 0;
935 break;
937 if (key != BUTTON_NONE)
938 lastkey = key;
941 if (control == STAR_CONTROL_BALL)
943 board[ball_y][ball_x] = STAR_VOID;
944 while ((board[ball_y + move_y][ball_x + move_x] == STAR_VOID
945 || board[ball_y + move_y][ball_x + move_x] == STAR_STAR))
948 star_animate_tile(BALL, STAR_OFFSET_X + ball_x * TILE_WIDTH,
949 STAR_OFFSET_Y + ball_y * TILE_HEIGHT,
950 move_x, move_y);
951 ball_x += move_x;
952 ball_y += move_y;
954 if (board[ball_y][ball_x] == STAR_STAR)
956 board[ball_y][ball_x] = STAR_VOID;
957 star_count--;
959 star_display_board_info(current_level);
962 board[ball_y][ball_x] = STAR_BALL;
964 else
966 board[block_y][block_x] = STAR_VOID;
967 while (board[block_y + move_y][block_x + move_x] == STAR_VOID)
969 star_animate_tile(BLOCK, STAR_OFFSET_X + block_x * TILE_WIDTH,
970 STAR_OFFSET_Y + block_y * TILE_HEIGHT,
971 move_x, move_y);
972 block_x += move_x;
973 block_y += move_y;
975 board[block_y][block_x] = STAR_BLOCK;
978 if (star_count == 0)
980 current_level++;
981 if (current_level == STAR_LEVEL_COUNT)
983 rb->lcd_clear_display();
984 rb->splash(HZ*2, "Congratulations!");
985 rb->lcd_update();
987 /* There is no such level as STAR_LEVEL_COUNT so it can't be the
988 * current_level */
989 current_level--;
990 return 1;
992 star_load_level(current_level);
998 * Display help text.
1000 static bool star_help(void)
1002 int button;
1003 #define WORDS (sizeof help_text / sizeof (char*))
1004 static char* help_text[] = {
1005 "Star", "", "Aim", "",
1006 "Take", "all", "the", "stars", "to", "go", "to", "the", "next", "level.",
1007 "You", "can", "toggle", "control", "with", "the", "block", "to", "use",
1008 "it", "as", "a", "mobile", "wall.", "The", "block", "cannot", "take",
1009 "stars.", "", "",
1010 "Controls", "",
1011 STAR_TOGGLE_CONTROL_NAME":", "Toggle", "control", "",
1012 STAR_QUIT_NAME":", "Exit", "",
1013 STAR_LEVEL_DOWN_NAME":", "Prev.", "level", "",
1014 STAR_LEVEL_REPEAT_NAME":", "Reset", "level", "",
1015 STAR_LEVEL_UP_NAME":", "Next", "level"
1017 static struct style_text formation[]={
1018 { 0, TEXT_CENTER|TEXT_UNDERLINE },
1019 { 2, C_RED },
1020 { 35, C_RED },
1021 { -1, 0 }
1023 #if LCD_DEPTH > 1
1024 #ifndef HAVE_LCD_COLOR
1025 rb->lcd_set_background(LCD_WHITE );
1026 rb->lcd_set_foreground(LCD_BLACK );
1027 #endif
1028 #endif
1029 if (display_text(WORDS, help_text, formation, NULL))
1030 return true;
1031 do {
1032 button = rb->button_get(true);
1033 if ( rb->default_event_handler( button ) == SYS_USB_CONNECTED )
1034 return true;
1035 } while( ( button == BUTTON_NONE )
1036 || ( button & (BUTTON_REL|BUTTON_REPEAT) ) );
1037 #if LCD_DEPTH > 1
1038 #ifndef HAVE_LCD_COLOR
1039 rb->lcd_set_background(LCD_BLACK );
1040 rb->lcd_set_foreground(LCD_WHITE );
1041 #endif
1042 #endif
1043 return false;
1047 * Display the choice menu.
1049 static int star_menu(void)
1051 int selection, level=1;
1052 bool menu_quit = false;
1054 MENUITEM_STRINGLIST(menu, "Star Menu", NULL,
1055 "Start Game","Choose Level",
1056 "Help", "Playback Control", "Quit");
1058 while(!menu_quit)
1060 switch(rb->do_menu(&menu, &selection, NULL, false))
1062 case 0:
1063 /* use system font and get the size of char */
1064 rb->lcd_setfont(FONT_SYSFIXED);
1065 rb->lcd_getstringsize("a", &char_width, &char_height);
1066 star_run_game(level-1);
1067 rb->lcd_setfont(FONT_UI);
1068 break;
1069 case 1:
1070 rb->set_int("Level", "", UNIT_INT, &level,
1071 NULL, 1, 1, STAR_LEVEL_COUNT, NULL );
1072 break;
1073 case 2:
1074 if(star_help())
1075 usb_detected = true;
1076 break;
1077 case 3:
1078 playback_control(NULL);
1079 break;
1080 case 4:
1081 menu_quit = true;
1082 break;
1084 if(usb_detected)
1085 return PLUGIN_USB_CONNECTED;
1088 return PLUGIN_OK;
1092 * Main entry point
1094 enum plugin_status plugin_start(const void* parameter)
1096 (void)parameter;
1098 #if LCD_DEPTH > 1
1099 rb->lcd_set_backdrop(NULL);
1100 rb->lcd_set_background( LCD_BLACK );
1101 rb->lcd_set_foreground( LCD_WHITE );
1102 #endif
1104 /* display choice menu */
1105 return star_menu();
1108 #endif