Fix red in bootloaders
[maemo-rb.git] / apps / plugins / brickmania.c
blob2f11cef24e924a0aad9e6253d12f9fd799a50383
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2005, 2006 Ben Basha (Paprica)
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 ****************************************************************************/
22 #include "plugin.h"
23 #include "lib/configfile.h" /* Part of libplugin */
24 #include "lib/helper.h"
26 PLUGIN_HEADER
29 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
31 #define QUIT BUTTON_OFF
32 #define LEFT BUTTON_LEFT
33 #define RIGHT BUTTON_RIGHT
34 #define SELECT BUTTON_SELECT
35 #define UP BUTTON_UP
36 #define DOWN BUTTON_DOWN
38 #define RC_QUIT BUTTON_RC_STOP
41 #elif CONFIG_KEYPAD == ONDIO_PAD
43 #define QUIT BUTTON_OFF
44 #define LEFT BUTTON_LEFT
45 #define RIGHT BUTTON_RIGHT
46 #define SELECT BUTTON_MENU
47 #define UP BUTTON_UP
48 #define DOWN BUTTON_DOWN
51 #elif CONFIG_KEYPAD == RECORDER_PAD
53 #define QUIT BUTTON_OFF
54 #define LEFT BUTTON_LEFT
55 #define RIGHT BUTTON_RIGHT
56 #define SELECT BUTTON_PLAY
57 #define UP BUTTON_UP
58 #define DOWN BUTTON_DOWN
61 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
63 #define QUIT BUTTON_OFF
64 #define LEFT BUTTON_LEFT
65 #define RIGHT BUTTON_RIGHT
66 #define SELECT BUTTON_SELECT
67 #define UP BUTTON_UP
68 #define DOWN BUTTON_DOWN
71 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
72 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
73 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
75 #define QUIT BUTTON_MENU
76 #define LEFT BUTTON_LEFT
77 #define RIGHT BUTTON_RIGHT
78 #define SELECT BUTTON_SELECT
79 #define UP BUTTON_SCROLL_BACK
80 #define DOWN BUTTON_SCROLL_FWD
82 #define SCROLL_FWD(x) ((x) & BUTTON_SCROLL_FWD)
83 #define SCROLL_BACK(x) ((x) & BUTTON_SCROLL_BACK)
86 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
88 #define QUIT BUTTON_POWER
89 #define LEFT BUTTON_LEFT
90 #define RIGHT BUTTON_RIGHT
91 #define SELECT BUTTON_SELECT
92 #define UP BUTTON_UP
93 #define DOWN BUTTON_DOWN
96 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
98 #define QUIT BUTTON_POWER
99 #define LEFT BUTTON_LEFT
100 #define RIGHT BUTTON_RIGHT
101 #define SELECT BUTTON_PLAY
102 #define UP BUTTON_UP
103 #define DOWN BUTTON_DOWN
106 #elif (CONFIG_KEYPAD == SANSA_E200_PAD)
108 #define QUIT BUTTON_POWER
109 #define LEFT BUTTON_LEFT
110 #define RIGHT BUTTON_RIGHT
111 #define SELECT BUTTON_SELECT
112 #define UP BUTTON_SCROLL_BACK
113 #define DOWN BUTTON_SCROLL_FWD
115 #define SCROLL_FWD(x) ((x) & BUTTON_SCROLL_FWD)
116 #define SCROLL_BACK(x) ((x) & BUTTON_SCROLL_BACK)
119 #elif (CONFIG_KEYPAD == SANSA_FUZE_PAD)
121 #define QUIT (BUTTON_HOME|BUTTON_REPEAT)
122 #define LEFT BUTTON_LEFT
123 #define RIGHT BUTTON_RIGHT
124 #define SELECT BUTTON_SELECT
125 #define UP BUTTON_SCROLL_BACK
126 #define DOWN BUTTON_SCROLL_FWD
128 #define SCROLL_FWD(x) ((x) & BUTTON_SCROLL_FWD)
129 #define SCROLL_BACK(x) ((x) & BUTTON_SCROLL_BACK)
132 #elif CONFIG_KEYPAD == SANSA_C200_PAD || \
133 CONFIG_KEYPAD == SANSA_CLIP_PAD || \
134 CONFIG_KEYPAD == SANSA_M200_PAD
136 #define QUIT BUTTON_POWER
137 #define LEFT BUTTON_LEFT
138 #define RIGHT BUTTON_RIGHT
139 #define ALTLEFT BUTTON_VOL_DOWN
140 #define ALTRIGHT BUTTON_VOL_UP
141 #define SELECT BUTTON_SELECT
142 #define UP BUTTON_UP
143 #define DOWN BUTTON_DOWN
146 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
148 #define QUIT BUTTON_POWER
149 #define LEFT BUTTON_LEFT
150 #define RIGHT BUTTON_RIGHT
151 #define SELECT BUTTON_PLAY
152 #define UP BUTTON_SCROLL_UP
153 #define DOWN BUTTON_SCROLL_DOWN
155 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
157 #define QUIT BUTTON_BACK
158 #define LEFT BUTTON_LEFT
159 #define RIGHT BUTTON_RIGHT
160 #define SELECT BUTTON_SELECT
161 #define UP BUTTON_UP
162 #define DOWN BUTTON_DOWN
164 #elif (CONFIG_KEYPAD == MROBE100_PAD)
166 #define QUIT BUTTON_POWER
167 #define LEFT BUTTON_LEFT
168 #define RIGHT BUTTON_RIGHT
169 #define SELECT BUTTON_SELECT
170 #define UP BUTTON_UP
171 #define DOWN BUTTON_DOWN
173 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
175 #define QUIT BUTTON_RC_REC
176 #define LEFT BUTTON_RC_REW
177 #define RIGHT BUTTON_RC_FF
178 #define SELECT BUTTON_RC_PLAY
179 #define UP BUTTON_RC_VOL_UP
180 #define DOWN BUTTON_RC_VOL_DOWN
182 #define RC_QUIT BUTTON_REC
184 #elif CONFIG_KEYPAD == COWOND2_PAD
185 #define QUIT BUTTON_POWER
187 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
189 #define QUIT BUTTON_BACK
190 #define LEFT BUTTON_LEFT
191 #define RIGHT BUTTON_RIGHT
192 #define SELECT BUTTON_SELECT
193 #define UP BUTTON_UP
194 #define DOWN BUTTON_DOWN
196 #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
198 #define QUIT BUTTON_POWER
199 #define LEFT BUTTON_LEFT
200 #define RIGHT BUTTON_RIGHT
201 #define SELECT BUTTON_SELECT
202 #define UP BUTTON_UP
203 #define DOWN BUTTON_DOWN
205 #elif CONFIG_KEYPAD == ONDAVX747_PAD
206 #define QUIT BUTTON_POWER
207 #define LEFT BUTTON_VOL_DOWN
208 #define RIGHT BUTTON_VOL_UP
209 #define SELECT BUTTON_MENU
211 #elif CONFIG_KEYPAD == MROBE500_PAD
212 #define QUIT BUTTON_POWER
214 #else
215 #error No keymap defined!
216 #endif
218 #ifdef HAVE_TOUCHSCREEN
219 #ifndef LEFT
220 #define LEFT BUTTON_MIDLEFT
221 #endif
222 #ifndef RIGHT
223 #define RIGHT BUTTON_MIDRIGHT
224 #endif
225 #ifndef SELECT
226 #define SELECT BUTTON_CENTER
227 #endif
228 #ifndef UP
229 #define UP BUTTON_TOPMIDDLE
230 #endif
231 #ifndef DOWN
232 #define DOWN BUTTON_BOTTOMMIDDLE
233 #endif
234 #endif
236 #ifndef SCROLL_FWD /* targets without scroll wheel*/
237 #define SCROLL_FWD(x) (0)
238 #define SCROLL_BACK(x) (0)
239 #endif
242 enum menu_items {
243 BM_START,
244 BM_SEL_START,
245 BM_RESUME,
246 BM_SEL_RESUME,
247 BM_NO_RESUME,
248 BM_HELP,
249 BM_SEL_HELP,
250 BM_QUIT,
251 BM_SEL_QUIT,
254 #include "pluginbitmaps/brickmania_pads.h"
255 #include "pluginbitmaps/brickmania_bricks.h"
256 #include "pluginbitmaps/brickmania_powerups.h"
257 #include "pluginbitmaps/brickmania_ball.h"
258 #include "pluginbitmaps/brickmania_menu_items.h"
259 #include "pluginbitmaps/brickmania_gameover.h"
261 #define PAD_WIDTH BMPWIDTH_brickmania_pads
262 #define PAD_HEIGHT (BMPHEIGHT_brickmania_pads/3)
263 #define BRICK_HEIGHT (BMPHEIGHT_brickmania_bricks/7)
264 #define BRICK_WIDTH BMPWIDTH_brickmania_bricks
265 #define LEFTMARGIN ((LCD_WIDTH-10*BRICK_WIDTH)/2)
266 #define POWERUP_HEIGHT (BMPHEIGHT_brickmania_powerups/7)
267 #define POWERUP_WIDTH BMPWIDTH_brickmania_powerups
268 #define BALL BMPHEIGHT_brickmania_ball
269 #define HALFBALL ((BALL+1)/2)
270 #define MENU_ITEMXOFS ((LCD_WIDTH - BMPWIDTH_brickmania_menu_items)/2)
271 #define MENU_ITEMHEIGHT (BMPHEIGHT_brickmania_menu_items/9)
272 #define MENU_ITEMWIDTH BMPWIDTH_brickmania_menu_items
273 #define GAMEOVER_WIDTH BMPWIDTH_brickmania_gameover
274 #define GAMEOVER_HEIGHT BMPHEIGHT_brickmania_gameover
276 #if LCD_DEPTH > 1 /* currently no background bmp for mono screens */
277 #include "pluginbitmaps/brickmania_menu_bg.h"
278 #define MENU_BGHEIGHT BMPHEIGHT_brickmania_menu_bg
279 #define MENU_BGWIDTH BMPWIDTH_brickmania_menu_bg
280 #endif
282 #ifdef HAVE_LCD_COLOR /* currently no transparency for non-colour */
283 #include "pluginbitmaps/brickmania_break.h"
284 #endif
286 #if ((LCD_WIDTH == 320) || (LCD_WIDTH == 400)) && (LCD_HEIGHT == 240)
288 /* The time (in ms) for one iteration through the game loop - decrease this
289 to speed up the game - note that current_tick is (currently) only accurate
290 to 10ms.
292 #define CYCLETIME 30
294 #define TOPMARGIN 30
296 #define BMPYOFS_start 110
297 #define HIGHSCORE_XPOS 57
298 #define HIGHSCORE_YPOS 88
300 #define STRINGPOS_FINISH 140
301 #define STRINGPOS_CONGRATS 157
302 #define STRINGPOS_NAVI 150
303 #define STRINGPOS_FLIP 150
305 #elif (LCD_WIDTH >= 220) && (LCD_HEIGHT >= 176)
307 /* The time (in ms) for one iteration through the game loop - decrease this
308 to speed up the game - note that current_tick is (currently) only accurate
309 to 10ms.
311 #define CYCLETIME 30
313 /* Offsets for LCDS > 220x176 */
315 #define GAMESCREEN_HEIGHT 176
316 #define TOPMARGIN 30
318 #define XOFS ((LCD_WIDTH-220)/BRICK_WIDTH/2)*BRICK_WIDTH
319 #define YOFS ((LCD_HEIGHT-176)/BRICK_HEIGHT/2)*BRICK_HEIGHT
321 #define BMPYOFS_start (78+YOFS)
322 #define HIGHSCORE_XPOS (17+XOFS)
323 #define HIGHSCORE_YPOS (56+YOFS)
325 #define STRINGPOS_FINISH 140
326 #define STRINGPOS_CONGRATS 157
327 #define STRINGPOS_NAVI 150
328 #define STRINGPOS_FLIP 150
330 #elif (LCD_WIDTH == 160) && (LCD_HEIGHT == 128)
331 /* The time (in ms) for one iteration through the game loop - decrease this
332 to speed up the game - note that current_tick is (currently) only accurate
333 to 10ms.
335 #define CYCLETIME 50
337 #define TOPMARGIN 21
339 #if LCD_DEPTH > 2
340 #define BMPYOFS_start 58
341 #else
342 #define BMPYOFS_start 66
343 #endif
344 #define HIGHSCORE_XPOS 10
345 #define HIGHSCORE_YPOS 38
347 #define STRINGPOS_FINISH 110
348 #define STRINGPOS_CONGRATS 100
349 #define STRINGPOS_NAVI 100
350 #define STRINGPOS_FLIP 100
352 #elif (LCD_WIDTH == 132) && (LCD_HEIGHT == 80)
354 /* The time (in ms) for one iteration through the game loop - decrease this
355 to speed up the game - note that current_tick is (currently) only accurate
356 to 10ms.
358 #define CYCLETIME 50
360 #define TOPMARGIN 10
362 #define BMPYOFS_start 30
363 #define HIGHSCORE_XPOS 68
364 #define HIGHSCORE_YPOS 8
366 #define STRINGPOS_FINISH 55
367 #define STRINGPOS_CONGRATS 45
368 #define STRINGPOS_NAVI 60
369 #define STRINGPOS_FLIP 60
371 #elif (LCD_WIDTH == 128) && (LCD_HEIGHT == 128)
373 /* The time (in ms) for one iteration through the game loop - decrease this
374 to speed up the game - note that current_tick is (currently) only accurate
375 to 10ms.
377 #define CYCLETIME 50
379 #define GAMESCREEN_HEIGHT 100
380 #define TOPMARGIN 15
382 #define BMPYOFS_start 70
383 #define HIGHSCORE_XPOS 8
384 #define HIGHSCORE_YPOS 36
386 #define STRINGPOS_FINISH 55
387 #define STRINGPOS_CONGRATS 45
388 #define STRINGPOS_NAVI 60
389 #define STRINGPOS_FLIP 60
391 /* iPod Mini */
392 #elif (LCD_WIDTH == 138) && (LCD_HEIGHT == 110)
393 /* The time (in ms) for one iteration through the game loop - decrease this
394 to speed up the game - note that current_tick is (currently) only accurate
395 to 10ms.
397 #define CYCLETIME 50
399 #define TOPMARGIN 10
401 #define BMPYOFS_start 51
402 #define HIGHSCORE_XPOS 73
403 #define HIGHSCORE_YPOS 25
405 #define STRINGPOS_FINISH 54
406 #define STRINGPOS_CONGRATS 44
407 #define STRINGPOS_NAVI 44
408 #define STRINGPOS_FLIP 44
410 /* iAudio M3 */
411 #elif (LCD_WIDTH == 128) && (LCD_HEIGHT == 96)
412 /* The time (in ms) for one iteration through the game loop - decrease this
413 to speed up the game - note that current_tick is (currently) only accurate
414 to 10ms.
416 #define CYCLETIME 50
418 #define TOPMARGIN 10
420 #define BMPYOFS_start 42
421 #define HIGHSCORE_XPOS 65
422 #define HIGHSCORE_YPOS 25
424 #define STRINGPOS_FINISH 54
425 #define STRINGPOS_CONGRATS 44
426 #define STRINGPOS_NAVI 44
427 #define STRINGPOS_FLIP 44
429 /* Archos / Sansa Clip / Sansa m200 */
430 #elif ((LCD_WIDTH == 112) | (LCD_WIDTH == 128)) && (LCD_HEIGHT == 64)
431 /* The time (in ms) for one iteration through the game loop - decrease this
432 to speed up the game - note that current_tick is (currently) only accurate
433 to 10ms.
435 #define CYCLETIME 75
437 #define TOPMARGIN 10
439 #define BMPYOFS_start 22
440 #define HIGHSCORE_XPOS 0
441 #define HIGHSCORE_YPOS 0
443 #define STRINGPOS_FINISH 54
444 #define STRINGPOS_CONGRATS 44
445 #define STRINGPOS_NAVI 44
446 #define STRINGPOS_FLIP 44
448 /* nano and sansa */
449 #elif (LCD_WIDTH == 176) && (LCD_HEIGHT >= 132) && (LCD_DEPTH==16)
450 /* The time (in ms) for one iteration through the game loop - decrease this
451 to speed up the game - note that current_tick is (currently) only accurate
452 to 10ms.
455 #define CYCLETIME 30
457 #define GAMESCREEN_HEIGHT 132
458 #define TOPMARGIN 21
460 #define BMPYOFS_start 58
461 #define HIGHSCORE_XPOS 7
462 #define HIGHSCORE_YPOS 36
464 #define STRINGPOS_FINISH 110
465 #define STRINGPOS_CONGRATS 110
466 #define STRINGPOS_NAVI 100
467 #define STRINGPOS_FLIP 100
469 #else
470 #error Unsupported LCD Size
471 #endif
474 #ifndef GAMESCREEN_HEIGHT
475 #define GAMESCREEN_HEIGHT LCD_HEIGHT
476 #endif
478 /* calculate menu item offsets from the first defined and the height*/
479 #define BMPYOFS_resume (BMPYOFS_start + MENU_ITEMHEIGHT)
480 #define BMPYOFS_help (BMPYOFS_start + 2*MENU_ITEMHEIGHT)
481 #define BMPYOFS_quit (BMPYOFS_start + 3*MENU_ITEMHEIGHT)
483 /*calculate paddle y-position */
484 #if GAMESCREEN_HEIGHT >= 128
485 #define PAD_POS_Y GAMESCREEN_HEIGHT -PAD_HEIGHT - 2
486 #else
487 #define PAD_POS_Y GAMESCREEN_HEIGHT -PAD_HEIGHT - 1
488 #endif
491 #ifdef HAVE_TOUCHSCREEN
492 #include "lib/touchscreen.h"
494 static struct ts_mapping main_menu_items[4] =
496 {MENU_ITEMXOFS, BMPYOFS_start, MENU_ITEMWIDTH, MENU_ITEMHEIGHT},
497 {MENU_ITEMXOFS, BMPYOFS_resume, MENU_ITEMWIDTH, MENU_ITEMHEIGHT},
498 {MENU_ITEMXOFS, BMPYOFS_help, MENU_ITEMWIDTH, MENU_ITEMHEIGHT},
499 {MENU_ITEMXOFS, BMPYOFS_quit, MENU_ITEMWIDTH, MENU_ITEMHEIGHT}
501 static struct ts_mappings main_menu = {main_menu_items, 4};
502 #endif
505 int levels_num = 29;
507 static unsigned char levels[29][8][10] = {
508 { /* level1 */
509 {0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1},
510 {0x2,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x2},
511 {0x0,0x2,0x1,0x0,0x0,0x0,0x0,0x1,0x2,0x0},
512 {0x0,0x0,0x2,0x1,0x0,0x0,0x1,0x2,0x0,0x0},
513 {0x0,0x0,0x0,0x2,0x1,0x1,0x2,0x0,0x0,0x0},
514 {0x7,0x0,0x0,0x7,0x2,0x2,0x7,0x0,0x0,0x7},
515 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
516 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}
518 { /* level2 */
519 {0x0,0x0,0x7,0x7,0x1,0x1,0x7,0x7,0x0,0x0},
520 {0x0,0x1,0x0,0x0,0x1,0x1,0x0,0x0,0x1,0x0},
521 {0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1},
522 {0x1,0x1,0x1,0x1,0x0,0x0,0x1,0x1,0x1,0x1},
523 {0x1,0x1,0x2,0x1,0x0,0x0,0x1,0x2,0x1,0x1},
524 {0x1,0x2,0x0,0x2,0x2,0x2,0x2,0x0,0x2,0x1},
525 {0x0,0x1,0x2,0x0,0x0,0x0,0x0,0x2,0x1,0x0},
526 {0x0,0x0,0x1,0x2,0x2,0x2,0x2,0x1,0x0,0x0}
528 { /* level3 */
529 {0x3,0x3,0x3,0x3,0x0,0x0,0x2,0x2,0x2,0x2},
530 {0x3,0x23,0x23,0x3,0x0,0x0,0x2,0x22,0x22,0x2},
531 {0x3,0x3,0x3,0x3,0x0,0x0,0x2,0x2,0x2,0x2},
532 {0x0,0x0,0x0,0x0,0x37,0x37,0x0,0x0,0x0,0x0},
533 {0x0,0x0,0x0,0x0,0x37,0x37,0x0,0x0,0x0,0x0},
534 {0x5,0x5,0x5,0x5,0x0,0x0,0x6,0x6,0x6,0x6},
535 {0x5,0x25,0x25,0x5,0x0,0x0,0x6,0x26,0x26,0x6},
536 {0x5,0x5,0x5,0x5,0x0,0x0,0x6,0x6,0x6,0x6}
538 { /* level4 */
539 {0x0,0x0,0x0,0x27,0x27,0x27,0x27,0x0,0x0,0x0},
540 {0x0,0x0,0x0,0x27,0x7,0x7,0x27,0x0,0x0,0x0},
541 {0x22,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x22},
542 {0x22,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x22},
543 {0x26,0x6,0x0,0x2,0x2,0x2,0x2,0x0,0x6,0x26},
544 {0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0},
545 {0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0},
546 {0x1,0x1,0x1,0x1,0x0,0x0,0x1,0x1,0x1,0x1}
548 { /* level5 */
549 {0x1,0x0,0x2,0x2,0x0,0x3,0x3,0x0,0x4,0x4},
550 {0x0,0x2,0x2,0x0,0x3,0x3,0x0,0x4,0x4,0x0},
551 {0x2,0x2,0x0,0x3,0x3,0x0,0x4,0x4,0x0,0x5},
552 {0x2,0x0,0x3,0x3,0x0,0x4,0x4,0x0,0x5,0x5},
553 {0x0,0x33,0x3,0x0,0x4,0x4,0x0,0x5,0x5,0x0},
554 {0x3,0x33,0x0,0x4,0x4,0x0,0x5,0x5,0x0,0x36},
555 {0x3,0x0,0x4,0x4,0x0,0x5,0x5,0x0,0x6,0x36},
556 {0x0,0x24,0x24,0x0,0x25,0x25,0x0,0x26,0x26,0x0}
558 { /* level6 */
559 {0x0,0x1,0x3,0x7,0x7,0x7,0x7,0x3,0x1,0x0},
560 {0x3,0x1,0x3,0x7,0x0,0x0,0x7,0x3,0x1,0x3},
561 {0x3,0x1,0x3,0x7,0x7,0x7,0x7,0x3,0x1,0x3},
562 {0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0},
563 {0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5},
564 {0x5,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x5},
565 {0x0,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x0},
566 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}
568 { /* level7 */
569 {0x0,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x0},
570 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
571 {0x6,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x6},
572 {0x6,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x6},
573 {0x6,0x6,0x6,0x0,0x0,0x0,0x0,0x6,0x6,0x6},
574 {0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0},
575 {0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0},
576 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}
578 { /* level8 */
579 {0x0,0x7,0x7,0x7,0x7,0x7,0x7,0x7,0x7,0x0},
580 {0x0,0x0,0x0,0x4,0x0,0x0,0x4,0x0,0x0,0x0},
581 {0x6,0x6,0x0,0x2,0x32,0x32,0x2,0x0,0x6,0x6},
582 {0x0,0x0,0x2,0x2,0x2,0x2,0x2,0x2,0x0,0x0},
583 {0x0,0x6,0x6,0x0,0x0,0x0,0x0,0x6,0x6,0x0},
584 {0x0,0x0,0x0,0x5,0x25,0x25,0x5,0x0,0x0,0x0},
585 {0x0,0x5,0x5,0x25,0x5,0x5,0x25,0x5,0x5,0x0},
586 {0x5,0x5,0x25,0x5,0x5,0x5,0x5,0x25,0x5,0x5}
588 { /* level9 */
589 {0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2},
590 {0x2,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x2},
591 {0x2,0x0,0x3,0x0,0x1,0x1,0x0,0x3,0x0,0x2},
592 {0x2,0x0,0x0,0x1,0x0,0x0,0x1,0x0,0x0,0x2},
593 {0x2,0x0,0x1,0x0,0x3,0x3,0x0,0x1,0x0,0x2},
594 {0x2,0x0,0x0,0x1,0x0,0x0,0x1,0x0,0x0,0x2},
595 {0x2,0x2,0x0,0x0,0x1,0x1,0x0,0x0,0x2,0x2},
596 {0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2}
598 { /* level10 */
599 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
600 {0x0,0x5,0x0,0x5,0x0,0x5,0x0,0x5,0x0,0x5},
601 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
602 {0x0,0x0,0x0,0x0,0x1,0x1,0x0,0x0,0x0,0x0},
603 {0x0,0x0,0x0,0x4,0x1,0x1,0x4,0x0,0x0,0x0},
604 {0x0,0x0,0x3,0x4,0x1,0x1,0x4,0x3,0x0,0x0},
605 {0x0,0x2,0x3,0x4,0x1,0x1,0x4,0x3,0x2,0x0},
606 {0x1,0x2,0x3,0x4,0x1,0x1,0x4,0x3,0x2,0x1}
608 { /* level11 */
609 {0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3},
610 {0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x2},
611 {0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2},
612 {0x2,0x0,0x0,0x0,0x7,0x7,0x0,0x0,0x0,0x2},
613 {0x2,0x0,0x0,0x7,0x7,0x7,0x7,0x0,0x0,0x2},
614 {0x0,0x0,0x0,0x1,0x0,0x0,0x1,0x0,0x0,0x0},
615 {0x0,0x2,0x0,0x1,0x0,0x0,0x1,0x0,0x2,0x0},
616 {0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5}
618 { /* level 12 */
619 {0x2,0x1,0x3,0x1,0x0,0x0,0x1,0x3,0x1,0x2},
620 {0x1,0x1,0x1,0x1,0x0,0x0,0x1,0x1,0x1,0x1},
621 {0x1,0x1,0x1,0x0,0x1,0x1,0x0,0x1,0x1,0x1},
622 {0x0,0x1,0x0,0x1,0x6,0x6,0x1,0x0,0x1,0x0},
623 {0x0,0x0,0x1,0x1,0x6,0x6,0x1,0x1,0x0,0x0},
624 {0x1,0x1,0x1,0x7,0x0,0x0,0x7,0x1,0x1,0x1},
625 {0x1,0x1,0x7,0x1,0x0,0x0,0x1,0x7,0x1,0x1},
626 {0x2,0x2,0x0,0x2,0x2,0x2,0x2,0x0,0x2,0x2}
628 {/* levell13 */
629 {0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2},
630 {0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2},
631 {0x2,0x0,0x2,0x2,0x2,0x2,0x2,0x2,0x0,0x2},
632 {0x2,0x0,0x2,0x3,0x3,0x3,0x3,0x3,0x0,0x2},
633 {0x2,0x0,0x2,0x4,0x4,0x4,0x4,0x4,0x0,0x2},
634 {0x2,0x0,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2},
635 {0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
636 {0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2}
638 {/* level14 */
639 {0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1},
640 {0x4,0x4,0x4,0x4,0x2,0x2,0x4,0x4,0x4,0x4},
641 {0x4,0x0,0x0,0x0,0x2,0x2,0x0,0x0,0x0,0x4},
642 {0x4,0x0,0x0,0x2,0x3,0x3,0x2,0x0,0x0,0x4},
643 {0x4,0x0,0x2,0x23,0x3,0x3,0x23,0x2,0x0,0x4},
644 {0x4,0x0,0x2,0x22,0x2,0x2,0x22,0x2,0x0,0x4},
645 {0x4,0x0,0x6,0x21,0x5,0x5,0x21,0x6,0x0,0x4},
646 {0x4,0x6,0x1,0x1,0x5,0x5,0x1,0x1,0x6,0x4}
648 {/* level 15 */
649 {0x4,0x4,0x4,0x4,0x4,0x3,0x3,0x3,0x3,0x3},
650 {0x2,0x2,0x1,0x1,0x1,0x1,0x1,0x5,0x0,0x0},
651 {0x2,0x2,0x1,0x1,0x1,0x0,0x1,0x6,0x0,0x0},
652 {0x2,0x1,0x1,0x2,0x1,0x1,0x1,0x5,0x0,0x0},
653 {0x2,0x1,0x2,0x2,0x2,0x1,0x1,0x6,0x0,0x0},
654 {0x2,0x1,0x2,0x2,0x2,0x1,0x3,0x5,0x3,0x0},
655 {0x2,0x1,0x1,0x2,0x1,0x1,0x1,0x6,0x0,0x0},
656 {0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2}
658 {/* level 16 (Rockbox) by ts-x */
659 {0x2,0x2,0x3,0x3,0x3,0x4,0x4,0x5,0x0,0x5},
660 {0x2,0x0,0x3,0x0,0x3,0x4,0x0,0x5,0x5,0x0},
661 {0x2,0x0,0x3,0x3,0x3,0x4,0x4,0x5,0x0,0x5},
662 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
663 {0x6,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
664 {0x7,0x7,0x7,0x1,0x1,0x1,0x2,0x0,0x2,0x0},
665 {0x7,0x0,0x7,0x1,0x0,0x1,0x0,0x2,0x0,0x0},
666 {0x7,0x7,0x7,0x1,0x1,0x1,0x2,0x0,0x2,0x0}
668 {/* level 17 (Alien) by ts-x */
669 {0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1},
670 {0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2},
671 {0x1,0x0,0x0,0x0,0x1,0x1,0x0,0x0,0x0,0x1},
672 {0x2,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x2},
673 {0x1,0x0,0x1,0x2,0x2,0x2,0x2,0x1,0x0,0x1},
674 {0x2,0x0,0x0,0x1,0x2,0x2,0x1,0x0,0x0,0x2},
675 {0x2,0x1,0x0,0x0,0x1,0x1,0x0,0x0,0x1,0x2},
676 {0x2,0x2,0x1,0x0,0x1,0x1,0x0,0x1,0x2,0x2}
678 {/* level 18 (Tetris) by ts-x */
679 {0x0,0x2,0x0,0x0,0x3,0x4,0x0,0x2,0x2,0x0},
680 {0x0,0x2,0x7,0x0,0x3,0x4,0x0,0x2,0x2,0x0},
681 {0x2,0x2,0x7,0x0,0x3,0x4,0x0,0x6,0x2,0x2},
682 {0x2,0x2,0x7,0x7,0x3,0x4,0x0,0x6,0x2,0x2},
683 {0x2,0x1,0x7,0x7,0x3,0x4,0x4,0x6,0x5,0x5},
684 {0x2,0x1,0x0,0x7,0x3,0x4,0x4,0x6,0x5,0x5},
685 {0x1,0x1,0x1,0x7,0x3,0x0,0x6,0x6,0x5,0x5},
686 {0x1,0x1,0x1,0x0,0x3,0x0,0x6,0x6,0x5,0x5}
688 { /* level 19 (Stalactites) by ts-x */
689 {0x5,0x2,0x6,0x3,0x4,0x7,0x5,0x3,0x1,0x2},
690 {0x5,0x2,0x6,0x3,0x4,0x7,0x5,0x3,0x1,0x2},
691 {0x5,0x0,0x6,0x3,0x4,0x7,0x5,0x0,0x1,0x2},
692 {0x5,0x2,0x6,0x3,0x4,0x0,0x5,0x3,0x1,0x2},
693 {0x5,0x0,0x6,0x0,0x4,0x7,0x5,0x0,0x1,0x0},
694 {0x5,0x0,0x0,0x3,0x4,0x0,0x0,0x0,0x1,0x2},
695 {0x0,0x0,0x6,0x0,0x0,0x0,0x5,0x0,0x0,0x0},
696 {0x5,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x1,0x0}
698 { /* level 20 (Maze) by ts-x */
699 {0x1,0x1,0x21,0x1,0x1,0x1,0x1,0x1,0x1,0x21},
700 {0x1,0x0,0x0,0x3,0x0,0x0,0x3,0x1,0x31,0x1},
701 {0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x31,0x0,0x1},
702 {0x21,0x0,0x21,0x3,0x0,0x3,0x0,0x3,0x0,0x2},
703 {0x1,0x0,0x1,0x21,0x0,0x12,0x0,0x0,0x0,0x0},
704 {0x31,0x0,0x1,0x0,0x0,0x1,0x0,0x0,0x3,0x0},
705 {0x1,0x0,0x1,0x0,0x1,0x1,0x31,0x1,0x1,0x2},
706 {0x22,0x0,0x2,0x1,0x1,0x1,0x1,0x1,0x1,0x21}
708 { /* level 21 (Dentist) by ts-x */
709 {0x0,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x0},
710 {0x2,0x2,0x0,0x6,0x0,0x6,0x0,0x6,0x2,0x2},
711 {0x2,0x6,0x0,0x6,0x0,0x6,0x0,0x6,0x0,0x2},
712 {0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x6,0x0,0x2},
713 {0x2,0x0,0x6,0x0,0x6,0x0,0x0,0x0,0x0,0x2},
714 {0x2,0x0,0x6,0x0,0x6,0x0,0x6,0x0,0x6,0x2},
715 {0x2,0x2,0x6,0x0,0x6,0x0,0x6,0x0,0x2,0x2},
716 {0x0,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x0}
718 { /* level 22 (Spider) by ts-x */
719 {0x31,0x3,0x1,0x1,0x0,0x0,0x1,0x1,0x3,0x31},
720 {0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0},
721 {0x33,0x1,0x1,0x36,0x1,0x1,0x36,0x1,0x1,0x33},
722 {0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0},
723 {0x0,0x0,0x1,0x1,0x0,0x0,0x1,0x1,0x0,0x0},
724 {0x21,0x3,0x1,0x21,0x2,0x2,0x21,0x1,0x3,0x21},
725 {0x0,0x0,0x0,0x1,0x21,0x1,0x1,0x0,0x0,0x0},
726 {0x3,0x1,0x3,0x1,0x0,0x0,0x1,0x3,0x1,0x3}
728 { /* level 23 (Pool) by ts-x */
729 {0x0,0x7,0x7,0x7,0x0,0x7,0x7,0x7,0x7,0x0},
730 {0x0,0x0,0x5,0x0,0x2,0x0,0x0,0x0,0x2,0x0},
731 {0x7,0x3,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x7},
732 {0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x5,0x0,0x7},
733 {0x7,0x0,0x4,0x0,0x0,0x3,0x0,0x0,0x0,0x7},
734 {0x7,0x0,0x0,0x6,0x0,0x0,0x0,0x0,0x4,0x7},
735 {0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
736 {0x0,0x7,0x7,0x7,0x7,0x0,0x7,0x7,0x7,0x0}
738 { /* level 24 (Vorbis Fish) by ts-x */
739 {0x0,0x0,0x4,0x4,0x5,0x5,0x5,0x0,0x0,0x5},
740 {0x0,0x4,0x6,0x4,0x4,0x5,0x5,0x5,0x0,0x5},
741 {0x5,0x6,0x0,0x6,0x4,0x4,0x4,0x5,0x5,0x5},
742 {0x5,0x6,0x0,0x6,0x4,0x4,0x4,0x4,0x5,0x5},
743 {0x0,0x5,0x6,0x4,0x4,0x5,0x5,0x4,0x5,0x0},
744 {0x5,0x5,0x4,0x4,0x5,0x5,0x5,0x4,0x5,0x5},
745 {0x5,0x4,0x4,0x4,0x5,0x5,0x4,0x4,0x5,0x5},
746 {0x0,0x0,0x4,0x4,0x4,0x4,0x4,0x5,0x0,0x5}
748 {/* level 25 (Rainbow) by ts-x */
749 {0x0,0x4,0x1,0x0,0x0,0x0,0x0,0x1,0x4,0x0},
750 {0x24,0x1,0x3,0x1,0x0,0x0,0x21,0x3,0x1,0x24},
751 {0x1,0x23,0x5,0x3,0x1,0x21,0x3,0x5,0x3,0x21},
752 {0x3,0x5,0x6,0x5,0x3,0x3,0x5,0x6,0x5,0x3},
753 {0x5,0x6,0x7,0x6,0x5,0x5,0x6,0x7,0x6,0x5},
754 {0x6,0x7,0x2,0x27,0x6,0x6,0x27,0x2,0x7,0x6},
755 {0x7,0x2,0x0,0x2,0x27,0x27,0x2,0x0,0x2,0x7},
756 {0x32,0x0,0x0,0x0,0x2,0x2,0x0,0x0,0x0,0x32}
758 { /* level 26 (Bowtie) by ts-x */
759 {0x5,0x1,0x5,0x1,0x0,0x0,0x1,0x5,0x1,0x5},
760 {0x1,0x0,0x0,0x1,0x5,0x5,0x1,0x0,0x0,0x1},
761 {0x5,0x0,0x6,0x0,0x1,0x1,0x0,0x6,0x0,0x5},
762 {0x1,0x0,0x6,0x6,0x0,0x0,0x6,0x6,0x0,0x1},
763 {0x1,0x0,0x6,0x6,0x0,0x0,0x6,0x6,0x0,0x1},
764 {0x5,0x0,0x6,0x0,0x1,0x1,0x0,0x6,0x0,0x5},
765 {0x1,0x0,0x0,0x1,0x5,0x5,0x1,0x0,0x0,0x1},
766 {0x5,0x1,0x5,0x1,0x0,0x0,0x1,0x5,0x1,0x5}
768 { /* level 27 (Frog) by ts-x */
769 {0x0,0x5,0x25,0x0,0x0,0x0,0x0,0x25,0x5,0x0},
770 {0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5},
771 {0x25,0x0,0x0,0x5,0x6,0x6,0x5,0x0,0x0,0x25},
772 {0x5,0x0,0x3,0x0,0x6,0x6,0x0,0x3,0x0,0x5},
773 {0x5,0x0,0x31,0x0,0x6,0x6,0x0,0x31,0x0,0x5},
774 {0x5,0x0,0x0,0x5,0x6,0x6,0x5,0x0,0x0,0x5},
775 {0x5,0x5,0x5,0x35,0x0,0x0,0x35,0x5,0x5,0x5},
776 {0x0,0x25,0x5,0x0,0x4,0x4,0x0,0x5,0x25,0x0}
778 { /* level 28 (DigDug) by ts-x */
779 {0x35,0x5,0x5,0x25,0x0,0x25,0x25,0x5,0x5,0x35},
780 {0x6,0x0,0x0,0x6,0x0,0x6,0x6,0x0,0x0,0x6},
781 {0x7,0x0,0x37,0x37,0x0,0x37,0x37,0x7,0x0,0x7},
782 {0x7,0x0,0x7,0x0,0x0,0x0,0x7,0x7,0x7,0x7},
783 {0x4,0x4,0x4,0x24,0x0,0x24,0x4,0x0,0x0,0x4},
784 {0x4,0x4,0x0,0x0,0x0,0x4,0x4,0x0,0x4,0x4},
785 {0x24,0x24,0x4,0x4,0x4,0x4,0x0,0x0,0x24,0x4},
786 {0x1,0x1,0x1,0x1,0x1,0x1,0x21,0x21,0x1,0x1}
788 { /* TheEnd */
789 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
790 {0x22,0x22,0x26,0x0,0x0,0x26,0x24,0x24,0x0,0x0},
791 {0x22,0x0,0x26,0x26,0x0,0x26,0x24,0x0,0x24,0x0},
792 {0x22,0x22,0x26,0x26,0x0,0x26,0x24,0x0,0x24,0x0},
793 {0x22,0x22,0x26,0x0,0x26,0x26,0x24,0x0,0x24,0x0},
794 {0x22,0x0,0x26,0x0,0x26,0x26,0x24,0x0,0x24,0x0},
795 {0x22,0x22,0x26,0x0,0x0,0x26,0x24,0x24,0x0,0x0},
796 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}
800 #define MAX_BALLS 10
801 int pad_pos_x;
802 int x[MAX_BALLS],y[MAX_BALLS];
803 int life;
804 int start_game,con_game;
805 int pad_type;
806 int score=0,vscore=0;
807 bool flip_sides=false;
808 int cur_level=0;
809 int brick_on_board=0;
810 int used_balls=1;
812 typedef struct cube {
813 int powertop;
814 int power;
815 char poweruse;
816 char used;
817 int color;
818 int hits;
819 int hiteffect;
820 } cube;
821 cube brick[80];
823 typedef struct balls {
824 int pos_x;
825 int pos_y;
826 int y;
827 int tempy;
828 int x;
829 int tempx;
830 bool glue;
831 } balls;
833 balls ball[MAX_BALLS];
835 typedef struct sfire {
836 int top;
837 int left;
838 } sfire;
839 sfire fire[30];
842 int highscore;
843 #define MAX_POINTS 200000 /* i dont think it needs to be more */
844 static struct configdata config[] =
846 {TYPE_INT, 0, MAX_POINTS, { .int_p = &highscore }, "highscore", NULL}
849 void int_game(int new_game)
851 int i,j;
853 pad_pos_x=LCD_WIDTH/2-PAD_WIDTH/2;
855 for(i=0;i<MAX_BALLS;i++) {
856 ball[i].x=0;
857 ball[i].y=0;
858 ball[i].tempy=0;
859 ball[i].tempx=0;
860 ball[i].pos_y=PAD_POS_Y-BALL;
861 ball[i].pos_x=pad_pos_x+(PAD_WIDTH/2)-2;
862 ball[i].glue=false;
865 used_balls=1;
866 start_game =1;
867 con_game =0;
868 pad_type=0;
870 flip_sides=false;
872 if (new_game==1)
873 brick_on_board=0;
875 for(i=0;i<=7;i++) {
876 for(j=0;j<=9;j++) {
877 brick[i*10+j].poweruse=(levels[cur_level][i][j]==0?0:1);
878 if (i*10+j<=30)
879 fire[i*10+j].top=-8;
880 if (new_game==1) {
881 brick[i*10+j].power=rb->rand()%25;
882 /* +8 make the game with less powerups */
884 brick[i*10+j].hits=levels[cur_level][i][j]>=10?
885 levels[cur_level][i][j]/16-1:0;
886 brick[i*10+j].hiteffect=0;
887 brick[i*10+j].powertop=TOPMARGIN+i*BRICK_HEIGHT+BRICK_HEIGHT;
888 brick[i*10+j].used=(levels[cur_level][i][j]==0?0:1);
889 brick[i*10+j].color=(levels[cur_level][i][j]>=10?
890 levels[cur_level][i][j]%16:
891 levels[cur_level][i][j])-1;
892 if (levels[cur_level][i][j]!=0)
893 brick_on_board++;
899 int sw,i,w;
901 /* sleep timer counting the score */
902 void sleep (int secs)
904 bool done=false;
905 char s[20];
906 int count=0;
908 while (!done) {
910 if (vscore<score) {
911 vscore++;
912 rb->snprintf(s, sizeof(s), "%d", vscore);
913 rb->lcd_getstringsize(s, &sw, &w);
914 #if (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
915 rb->lcd_putsxy(LCD_WIDTH/2-sw/2, 0, s);
916 #else
917 rb->lcd_putsxy(LCD_WIDTH/2-sw/2, 2, s);
918 #endif
919 rb->lcd_update_rect(0,0,LCD_WIDTH,w+2);
920 } else {
921 if (count==0)
922 count=*rb->current_tick+HZ*secs;
923 if (*rb->current_tick>=count)
924 done=true;
926 rb->yield();
931 #define HIGH_SCORE "brickmania.score"
932 #define MENU_LENGTH 4
933 int game_menu(int when)
935 int button,cur=0;
936 char str[10];
937 rb->lcd_clear_display();
938 #if LCD_DEPTH > 1 /* currently no background bmp for mono screens */
939 rb->lcd_bitmap(brickmania_menu_bg, 0, 0, MENU_BGWIDTH, MENU_BGHEIGHT);
940 #endif
941 while (true) {
942 for(i=0;i<MENU_LENGTH;i++) {
943 #ifdef HAVE_LCD_COLOR
944 if (cur==0)
945 rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0,
946 MENU_ITEMHEIGHT * BM_SEL_START, MENU_ITEMWIDTH,
947 MENU_ITEMXOFS, BMPYOFS_start, MENU_ITEMWIDTH,
948 MENU_ITEMHEIGHT);
949 else
950 rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0,
951 MENU_ITEMHEIGHT * BM_START, MENU_ITEMWIDTH,
952 MENU_ITEMXOFS, BMPYOFS_start, MENU_ITEMWIDTH,
953 MENU_ITEMHEIGHT);
955 if (when==1) {
956 if (cur==1)
957 rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0,
958 MENU_ITEMHEIGHT * BM_SEL_RESUME, MENU_ITEMWIDTH,
959 MENU_ITEMXOFS, BMPYOFS_resume, MENU_ITEMWIDTH,
960 MENU_ITEMHEIGHT);
961 else
962 rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0,
963 MENU_ITEMHEIGHT * BM_RESUME, MENU_ITEMWIDTH,
964 MENU_ITEMXOFS, BMPYOFS_resume, MENU_ITEMWIDTH,
965 MENU_ITEMHEIGHT);
967 } else {
968 rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0,
969 MENU_ITEMHEIGHT * BM_NO_RESUME, MENU_ITEMWIDTH,
970 MENU_ITEMXOFS, BMPYOFS_resume, MENU_ITEMWIDTH,
971 MENU_ITEMHEIGHT);
975 if (cur==2)
976 rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0,
977 MENU_ITEMHEIGHT * BM_SEL_HELP, MENU_ITEMWIDTH,
978 MENU_ITEMXOFS, BMPYOFS_help, MENU_ITEMWIDTH,
979 MENU_ITEMHEIGHT);
980 else
981 rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0,
982 MENU_ITEMHEIGHT * BM_HELP, MENU_ITEMWIDTH,
983 MENU_ITEMXOFS, BMPYOFS_help, MENU_ITEMWIDTH,
984 MENU_ITEMHEIGHT);
986 if (cur==3)
987 rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0,
988 MENU_ITEMHEIGHT * BM_SEL_QUIT, MENU_ITEMWIDTH,
989 MENU_ITEMXOFS, BMPYOFS_quit, MENU_ITEMWIDTH,
990 MENU_ITEMHEIGHT);
991 else
992 rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0,
993 MENU_ITEMHEIGHT * BM_QUIT, MENU_ITEMWIDTH,
994 MENU_ITEMXOFS, BMPYOFS_quit, MENU_ITEMWIDTH,
995 MENU_ITEMHEIGHT);
996 #else
997 if (cur==0)
998 rb->lcd_bitmap_part(brickmania_menu_items, 0,
999 MENU_ITEMHEIGHT * BM_SEL_START, MENU_ITEMWIDTH,
1000 MENU_ITEMXOFS, BMPYOFS_start, MENU_ITEMWIDTH,
1001 MENU_ITEMHEIGHT);
1002 else
1003 rb->lcd_bitmap_part(brickmania_menu_items, 0,
1004 MENU_ITEMHEIGHT * BM_START, MENU_ITEMWIDTH,
1005 MENU_ITEMXOFS, BMPYOFS_start, MENU_ITEMWIDTH,
1006 MENU_ITEMHEIGHT);
1008 if (when==1) {
1009 if (cur==1)
1010 rb->lcd_bitmap_part(brickmania_menu_items, 0,
1011 MENU_ITEMHEIGHT * BM_SEL_RESUME, MENU_ITEMWIDTH,
1012 MENU_ITEMXOFS, BMPYOFS_resume, MENU_ITEMWIDTH,
1013 MENU_ITEMHEIGHT);
1014 else
1015 rb->lcd_bitmap_part(brickmania_menu_items, 0,
1016 MENU_ITEMHEIGHT * BM_RESUME, MENU_ITEMWIDTH,
1017 MENU_ITEMXOFS, BMPYOFS_resume, MENU_ITEMWIDTH,
1018 MENU_ITEMHEIGHT);
1020 } else {
1021 rb->lcd_bitmap_part(brickmania_menu_items, 0,
1022 MENU_ITEMHEIGHT * BM_NO_RESUME, MENU_ITEMWIDTH,
1023 MENU_ITEMXOFS, BMPYOFS_resume, MENU_ITEMWIDTH,
1024 MENU_ITEMHEIGHT);
1028 if (cur==2)
1029 rb->lcd_bitmap_part(brickmania_menu_items, 0,
1030 MENU_ITEMHEIGHT * BM_SEL_HELP, MENU_ITEMWIDTH,
1031 MENU_ITEMXOFS, BMPYOFS_help, MENU_ITEMWIDTH,
1032 MENU_ITEMHEIGHT);
1033 else
1034 rb->lcd_bitmap_part(brickmania_menu_items, 0,
1035 MENU_ITEMHEIGHT * BM_HELP, MENU_ITEMWIDTH,
1036 MENU_ITEMXOFS, BMPYOFS_help, MENU_ITEMWIDTH,
1037 MENU_ITEMHEIGHT);
1039 if (cur==3)
1040 rb->lcd_bitmap_part(brickmania_menu_items, 0,
1041 MENU_ITEMHEIGHT * BM_SEL_QUIT, MENU_ITEMWIDTH,
1042 MENU_ITEMXOFS, BMPYOFS_quit, MENU_ITEMWIDTH,
1043 MENU_ITEMHEIGHT);
1044 else
1045 rb->lcd_bitmap_part(brickmania_menu_items, 0,
1046 MENU_ITEMHEIGHT * BM_QUIT, MENU_ITEMWIDTH,
1047 MENU_ITEMXOFS, BMPYOFS_quit, MENU_ITEMWIDTH,
1048 MENU_ITEMHEIGHT);
1049 #endif
1051 rb->lcd_set_drawmode(DRMODE_FG);
1052 /* high score */
1053 #ifdef HAVE_LCD_COLOR
1054 rb->lcd_set_background(LCD_RGBPACK(0,0,140));
1055 rb->lcd_set_foreground(LCD_WHITE);
1056 #endif
1057 rb->lcd_putsxy(HIGHSCORE_XPOS, HIGHSCORE_YPOS, "High Score");
1058 rb->snprintf(str, sizeof(str), "%d", highscore);
1059 rb->lcd_getstringsize("High Score", &sw, NULL);
1060 rb->lcd_getstringsize(str, &w, NULL);
1061 rb->lcd_putsxy(HIGHSCORE_XPOS+sw/2-w/2, HIGHSCORE_YPOS+9, str);
1062 rb->lcd_set_drawmode(DRMODE_SOLID);
1064 rb->lcd_update();
1066 button = rb->button_get(true);
1067 #ifdef HAVE_TOUCHSCREEN
1068 if(button & BUTTON_TOUCHSCREEN)
1070 unsigned int result = touchscreen_map(&main_menu, rb->button_get_data() >> 16, rb->button_get_data() & 0xffff);
1071 if(result != (unsigned)-1 && button & BUTTON_REL)
1073 if(cur == (signed)result)
1074 button = SELECT;
1075 cur = result;
1078 #endif
1079 switch(button) {
1080 case UP:
1081 case UP | BUTTON_REPEAT:
1082 if (cur==0)
1083 cur = MENU_LENGTH-1;
1084 else
1085 cur--;
1086 if (when==0 && cur==1) {
1087 cur = 0;
1089 break;
1091 case DOWN:
1092 case DOWN | BUTTON_REPEAT:
1093 if (cur==MENU_LENGTH-1)
1094 cur = 0;
1095 else
1096 cur++;
1097 if (when==0 && cur==1) {
1098 cur=2;
1100 break;
1102 case RIGHT:
1103 case SELECT:
1104 if (cur==0) {
1105 score=0;
1106 vscore=0;
1107 return 0;
1108 } else if (cur==1 && when==1) {
1109 return 1;
1110 } else if (cur==2) {
1111 return 2;
1112 } else if (cur==3) {
1113 return 3;
1115 break;
1116 #ifdef RC_QUIT
1117 case RC_QUIT:
1118 #endif
1119 case QUIT:
1120 return 3;
1121 break;
1123 default:
1124 if(rb->default_event_handler(button) == SYS_USB_CONNECTED)
1125 return 3;
1126 break;
1129 rb->yield();
1133 int help(int when)
1135 int w,h;
1136 int button;
1137 int xoffset=0;
1138 int yoffset=0;
1139 /* set the maximum x and y in the helpscreen
1140 dont forget to update, if you change text */
1141 int maxY=180;
1142 int maxX=215;
1144 while(true) {
1145 #ifdef HAVE_LCD_COLOR
1146 rb->lcd_set_background(LCD_BLACK);
1147 rb->lcd_clear_display();
1148 rb->lcd_set_background(LCD_BLACK);
1149 rb->lcd_set_foreground(LCD_WHITE);
1150 #else
1151 rb->lcd_clear_display();
1152 #endif
1154 rb->lcd_getstringsize("BrickMania", &w, &h);
1155 rb->lcd_putsxy(LCD_WIDTH/2-w/2+xoffset, 1+yoffset, "BrickMania");
1157 #ifdef HAVE_LCD_COLOR
1158 rb->lcd_set_foreground(LCD_RGBPACK(245,0,0));
1159 rb->lcd_putsxy(1+xoffset, 1*(h+2)+yoffset,"Aim");
1160 rb->lcd_set_foreground(LCD_WHITE);
1161 #else
1162 rb->lcd_putsxy(1+xoffset, 1*(h+2)+yoffset,"Aim");
1163 #endif
1164 rb->lcd_putsxy(1+xoffset, 2*(h+2)+yoffset,
1165 "destroy all the bricks by bouncing");
1166 rb->lcd_putsxy(1+xoffset, 3*(h+2)+yoffset,
1167 "the ball of them using the paddle.");
1168 #ifdef HAVE_LCD_COLOR
1169 rb->lcd_set_foreground(LCD_RGBPACK(245,0,0));
1170 rb->lcd_putsxy(1+xoffset, 5*(h+2)+yoffset,"Controls");
1171 rb->lcd_set_foreground(LCD_WHITE);
1172 #else
1173 rb->lcd_putsxy(1+xoffset, 5*(h+2)+yoffset,"Controls");
1174 #endif
1175 rb->lcd_putsxy(1+xoffset, 6*(h+2)+yoffset,"< & > Move the paddle");
1176 #if CONFIG_KEYPAD == ONDIO_PAD
1177 rb->lcd_putsxy(1+xoffset, 7*(h+2)+yoffset,
1178 "MENU Releases the ball/Fire!");
1179 #elif (CONFIG_KEYPAD == RECORDER_PAD) || (CONFIG_KEYPAD == IAUDIO_M3_PAD)
1180 rb->lcd_putsxy(1+xoffset, 7*(h+2)+yoffset,
1181 "PLAY Releases the ball/Fire!");
1182 #elif CONFIG_KEYPAD == IRIVER_H300_PAD
1183 rb->lcd_putsxy(1+xoffset, 7*(h+2)+yoffset,
1184 "NAVI Releases the ball/Fire!");
1185 #else
1186 rb->lcd_putsxy(1+xoffset, 7*(h+2)+yoffset,
1187 "SELECT Releases the ball/Fire!");
1188 #endif
1189 #if CONFIG_KEYPAD == IAUDIO_M3_PAD
1190 rb->lcd_putsxy(1+xoffset, 8*(h+2)+yoffset, "REC Opens menu/Quit");
1191 #else
1192 rb->lcd_putsxy(1+xoffset, 8*(h+2)+yoffset, "STOP Opens menu/Quit");
1193 #endif
1194 #ifdef HAVE_LCD_COLOR
1195 rb->lcd_set_foreground(LCD_RGBPACK(245,0,0));
1196 rb->lcd_putsxy(1+xoffset, 10*(h+2)+yoffset, "Specials");
1197 rb->lcd_set_foreground(LCD_WHITE);
1198 #else
1199 rb->lcd_putsxy(1+xoffset, 10*(h+2)+yoffset, "Specials");
1200 #endif
1201 rb->lcd_putsxy(1+xoffset, 11*(h+2)+yoffset,
1202 "N Normal:returns paddle to normal");
1203 rb->lcd_putsxy(1+xoffset, 12*(h+2)+yoffset, "D DIE!:loses a life");
1204 rb->lcd_putsxy(1+xoffset, 13*(h+2)+yoffset,
1205 "L Life:gains a life/power up");
1206 rb->lcd_putsxy(1+xoffset, 14*(h+2)+yoffset,
1207 "F Fire:allows you to shoot bricks");
1208 rb->lcd_putsxy(1+xoffset, 15*(h+2)+yoffset,
1209 "G Glue:ball sticks to paddle");
1210 rb->lcd_putsxy(1+xoffset, 16*(h+2)+yoffset,
1211 "B Ball:generates another ball");
1212 rb->lcd_putsxy(1+xoffset, 17*(h+2)+yoffset,
1213 "FL Flip:flips left / right movement");
1214 rb->lcd_update();
1216 button=rb->button_get(true);
1217 switch (button) {
1218 #ifdef RC_QUIT
1219 case RC_QUIT:
1220 #endif
1221 #ifdef HAVE_TOUCHSCREEN
1222 case BUTTON_TOUCHSCREEN:
1223 #endif
1224 case QUIT:
1225 switch (game_menu(when)) {
1226 case 0:
1227 cur_level=0;
1228 life=2;
1229 int_game(1);
1230 break;
1231 case 1:
1232 con_game=1;
1233 break;
1234 case 2:
1235 if (help(when)==1)
1236 return 1;
1237 break;
1238 case 3:
1239 return 1;
1240 break;
1242 return 0;
1243 break;
1244 case LEFT:
1245 case LEFT | BUTTON_REPEAT:
1246 #ifdef ALTLEFT
1247 case ALTLEFT:
1248 case ALTLEFT | BUTTON_REPEAT:
1249 #endif
1250 if( xoffset<0)
1251 xoffset+=2;
1252 break;
1253 case RIGHT:
1254 case RIGHT | BUTTON_REPEAT:
1255 #ifdef ALTRIGHT
1256 case ALTRIGHT:
1257 case ALTRIGHT | BUTTON_REPEAT:
1258 #endif
1259 if(xoffset+maxX > LCD_WIDTH)
1260 xoffset-=2;
1261 break;
1262 case UP:
1263 case UP | BUTTON_REPEAT:
1264 if(yoffset <0)
1265 yoffset+=2;
1266 break;
1267 case DOWN:
1268 case DOWN | BUTTON_REPEAT:
1269 if(yoffset+maxY > LCD_HEIGHT)
1270 yoffset-=2;
1271 break;
1273 default:
1274 if(rb->default_event_handler(button) == SYS_USB_CONNECTED)
1275 return 1;
1276 break;
1279 rb->yield();
1281 return 0;
1284 int pad_check(int ballxc, int mode, int pon ,int ballnum)
1286 /* pon: positive(1) or negative(0) */
1288 if (mode==0) {
1289 if (pon == 0)
1290 return -ballxc;
1291 else
1292 return ballxc;
1293 } else {
1294 if (ball[ballnum].x > 0)
1295 return ballxc;
1296 else
1297 return ballxc*-1;
1301 int fire_space(void)
1303 int t;
1304 for(t=0;t<=30;t++)
1305 if (fire[t].top+7 < 0)
1306 return t;
1308 return 0;
1311 int game_loop(void)
1313 int j,i,k,bricky,brickx;
1314 char s[30];
1315 int sec_count=0,num_count=10;
1316 int end;
1318 rb->srand( *rb->current_tick );
1320 configfile_load(HIGH_SCORE,config,1,0);
1322 switch(game_menu(0)) {
1323 case 0:
1324 cur_level = 0;
1325 life = 2;
1326 int_game(1);
1327 break;
1328 case 1:
1329 con_game = 1;
1330 break;
1331 case 2:
1332 if (help(0) == 1) return 1;
1333 break;
1334 case 3:
1335 return 1;
1336 break;
1339 while(true) {
1340 /* Convert CYCLETIME (in ms) to HZ */
1341 end = *rb->current_tick + (CYCLETIME * HZ) / 1000;
1343 if (life >= 0) {
1344 #ifdef HAVE_LCD_COLOR
1345 rb->lcd_set_background(LCD_BLACK);
1346 rb->lcd_set_drawmode(DRMODE_SOLID);
1347 rb->lcd_clear_display();
1348 rb->lcd_set_background(LCD_BLACK);
1349 #if LCD_HEIGHT > GAMESCREEN_HEIGHT
1350 rb->lcd_set_foreground(rb->global_settings->bg_color);
1351 rb->lcd_fillrect(0, GAMESCREEN_HEIGHT, LCD_WIDTH,
1352 LCD_HEIGHT - GAMESCREEN_HEIGHT);
1353 #endif
1354 rb->lcd_set_foreground(LCD_WHITE);
1355 #else
1356 rb->lcd_clear_display();
1357 #endif
1359 if (flip_sides) {
1360 if (*rb->current_tick>=sec_count) {
1361 sec_count=*rb->current_tick+HZ;
1362 if (num_count!=0)
1363 num_count--;
1364 else
1365 flip_sides=false;
1367 rb->snprintf(s, sizeof(s), "%d", num_count);
1368 rb->lcd_getstringsize(s, &sw, NULL);
1369 rb->lcd_putsxy(LCD_WIDTH/2-2, STRINGPOS_FLIP, s);
1372 /* write life num */
1373 #if (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
1374 rb->snprintf(s, sizeof(s), "L:%d", life);
1375 rb->lcd_putsxy(0, 0, s);
1376 #else
1377 rb->snprintf(s, sizeof(s), "Life: %d", life);
1378 rb->lcd_putsxy(2, 2, s);
1379 #endif
1381 #if (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
1382 rb->snprintf(s, sizeof(s), "L%d", cur_level+1);
1383 rb->lcd_getstringsize(s, &sw, NULL);
1384 rb->lcd_putsxy(LCD_WIDTH-sw, 0, s);
1385 #else
1386 rb->snprintf(s, sizeof(s), "Level %d", cur_level+1);
1387 rb->lcd_getstringsize(s, &sw, NULL);
1388 rb->lcd_putsxy(LCD_WIDTH-sw-2, 2, s);
1389 #endif
1391 if (vscore<score) vscore++;
1392 rb->snprintf(s, sizeof(s), "%d", vscore);
1393 rb->lcd_getstringsize(s, &sw, NULL);
1394 #if (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
1395 rb->lcd_putsxy(LCD_WIDTH/2-sw/2, 0, s);
1396 #else
1397 rb->lcd_putsxy(LCD_WIDTH/2-sw/2, 2, s);
1398 #endif
1400 /* continue game */
1401 if (con_game== 1 && start_game!=1) {
1402 #if CONFIG_KEYPAD == ONDIO_PAD
1403 rb->snprintf(s, sizeof(s), "MENU To Continue");
1404 #elif CONFIG_KEYPAD == IRIVER_H300_PAD
1405 rb->snprintf(s, sizeof(s), "Press NAVI To Continue");
1406 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
1407 rb->snprintf(s, sizeof(s), "PLAY To Continue");
1408 #else
1409 rb->snprintf(s, sizeof(s), "Press SELECT To Continue");
1410 #endif
1411 rb->lcd_getstringsize(s, &sw, NULL);
1412 rb->lcd_putsxy(LCD_WIDTH/2-sw/2, STRINGPOS_NAVI, s);
1414 sec_count=*rb->current_tick+HZ;
1417 /* draw the ball */
1418 for(i=0;i<used_balls;i++)
1419 rb->lcd_bitmap(brickmania_ball,ball[i].pos_x, ball[i].pos_y,
1420 BALL, BALL);
1422 if (brick_on_board==0)
1423 brick_on_board--;
1425 /* if the pad is fire */
1426 for(i=0;i<=30;i++) {
1427 if (fire[i].top+7>0) {
1428 if (con_game!=1)
1429 fire[i].top-=4;
1430 rb->lcd_vline(fire[i].left, fire[i].top, fire[i].top+7);
1434 /* the bricks */
1435 for (i=0;i<=7;i++) {
1436 for (j=0;j<=9;j++) {
1437 if (brick[i*10+j].power<7) {
1438 if (brick[i*10+j].poweruse==2) {
1439 if (con_game!=1)
1440 brick[i*10+j].powertop+=2;
1441 rb->lcd_bitmap_part(brickmania_powerups,0,
1442 POWERUP_HEIGHT*brick[i*10+j
1443 ].power,
1444 POWERUP_WIDTH,
1445 LEFTMARGIN+j*BRICK_WIDTH+
1446 (BRICK_WIDTH/2-
1447 POWERUP_WIDTH/2),
1448 brick[i*10+j].powertop,
1449 POWERUP_WIDTH,
1450 POWERUP_HEIGHT);
1454 if ((pad_pos_x<LEFTMARGIN+j*BRICK_WIDTH+5 &&
1455 pad_pos_x+PAD_WIDTH>LEFTMARGIN+j*BRICK_WIDTH+5) &&
1456 brick[i*10+j].powertop+6>=PAD_POS_Y &&
1457 brick[i*10+j].poweruse==2) {
1458 switch(brick[i*10+j].power) {
1459 case 0:
1460 life++;
1461 score+=50;
1462 break;
1463 case 1:
1464 life--;
1465 if (life>=0) {
1466 int_game(0);
1467 sleep(2);
1469 break;
1470 case 2:
1471 score+=34;
1472 pad_type=1;
1473 break;
1474 case 3:
1475 score+=47;
1476 pad_type=2;
1477 for(k=0;k<used_balls;k++)
1478 ball[k].glue=false;
1479 break;
1480 case 4:
1481 score+=23;
1482 pad_type=0;
1483 for(k=0;k<used_balls;k++)
1484 ball[k].glue=false;
1485 flip_sides=false;
1486 break;
1487 case 5:
1488 score+=23;
1489 sec_count=*rb->current_tick+HZ;
1490 num_count=10;
1491 flip_sides=!flip_sides;
1492 break;
1493 case 6:
1494 score+=23;
1495 used_balls++;
1496 ball[used_balls-1].x= rb->rand()%1 == 0 ?
1497 -1 : 1;
1498 ball[used_balls-1].y= -4;
1499 break;
1501 brick[i*10+j].poweruse=1;
1504 if (brick[i*10+j].powertop>PAD_POS_Y)
1505 brick[i*10+j].poweruse=1;
1507 brickx=LEFTMARGIN+j*BRICK_WIDTH;
1508 bricky=TOPMARGIN+i*BRICK_HEIGHT;
1509 if (pad_type==2) {
1510 for (k=0;k<=30;k++) {
1511 if (fire[k].top+7>0) {
1512 if (brick[i*10+j].used==1 &&
1513 (fire[k].left+1 >= brickx &&
1514 fire[k].left+1 <= brickx+BRICK_WIDTH) &&
1515 (bricky+BRICK_HEIGHT>fire[k].top)) {
1516 score+=13;
1517 fire[k].top=-16;
1518 if (brick[i*10+j].hits > 0) {
1519 brick[i*10+j].hits--;
1520 brick[i*10+j].hiteffect++;
1521 score+=3;
1523 else {
1524 brick[i*10+j].used=0;
1525 if (brick[i*10+j].power!=10)
1526 brick[i*10+j].poweruse=2;
1527 brick_on_board--;
1534 if (brick[i*10+j].used==1) {
1535 rb->lcd_bitmap_part(brickmania_bricks,0,
1536 BRICK_HEIGHT*brick[i*10+j].color,
1537 BRICK_WIDTH,
1538 LEFTMARGIN+j*BRICK_WIDTH,
1539 TOPMARGIN+i*BRICK_HEIGHT,
1540 BRICK_WIDTH, BRICK_HEIGHT);
1541 #ifdef HAVE_LCD_COLOR /* No transparent effect for greyscale lcds for now */
1542 if (brick[i*10+j].hiteffect>0)
1543 rb->lcd_bitmap_transparent_part(brickmania_break,
1545 BRICK_HEIGHT*brick[i*10+j].hiteffect,
1546 BRICK_WIDTH,
1547 LEFTMARGIN+j*BRICK_WIDTH,
1548 TOPMARGIN+i*BRICK_HEIGHT,
1549 BRICK_WIDTH,
1550 BRICK_HEIGHT);
1551 #endif
1554 for(k=0;k<used_balls;k++) {
1555 if (ball[k].pos_y <160) {
1556 if (brick[i*10+j].used==1) {
1557 if ((ball[k].pos_x+ball[k].x+HALFBALL >=
1558 brickx &&
1559 ball[k].pos_x+ball[k].x+HALFBALL <=
1560 brickx+BRICK_WIDTH) &&
1561 ((bricky-4<ball[k].pos_y+BALL &&
1562 bricky>ball[k].pos_y+BALL) ||
1563 (bricky+4>ball[k].pos_y+BALL+BALL &&
1564 bricky<ball[k].pos_y+BALL+BALL)) &&
1565 (ball[k].y >0)) {
1566 ball[k].tempy=bricky-ball[k].pos_y-BALL;
1568 else if ((ball[k].pos_x+ball[k].x+HALFBALL >=
1569 brickx &&
1570 ball[k].pos_x+ball[k].x+HALFBALL <=
1571 brickx+BRICK_WIDTH) &&
1572 ((bricky+BRICK_HEIGHT+4>ball[k].pos_y &&
1573 bricky+BRICK_HEIGHT<ball[k].pos_y) ||
1574 (bricky+BRICK_HEIGHT-4<ball[k].pos_y-BALL &&
1575 bricky+BRICK_HEIGHT>ball[k].pos_y-BALL)) &&
1576 (ball[k].y <0)) {
1577 ball[k].tempy=
1578 -(ball[k].pos_y-(bricky+BRICK_HEIGHT));
1581 if ((ball[k].pos_y+HALFBALL >=
1582 bricky &&
1583 ball[k].pos_y+HALFBALL <=
1584 bricky+BRICK_HEIGHT) &&
1585 ((brickx-4<ball[k].pos_x+BALL &&
1586 brickx>ball[k].pos_x+BALL) ||
1587 (brickx+4>ball[k].pos_x+BALL+BALL &&
1588 brickx<ball[k].pos_x+BALL+BALL)) &&
1589 (ball[k].x >0)) {
1590 ball[k].tempx=brickx-ball[k].pos_x-BALL;
1592 else if ((ball[k].pos_y+ball[k].y+HALFBALL >=
1593 bricky &&
1594 ball[k].pos_y+ball[k].y+HALFBALL <=
1595 bricky+BRICK_HEIGHT) &&
1596 ((brickx+BRICK_WIDTH+4>ball[k].pos_x &&
1597 brickx+BRICK_WIDTH<ball[k].pos_x) ||
1598 (brickx+BRICK_WIDTH-4<ball[k].pos_x-
1599 BALL &&
1600 brickx+BRICK_WIDTH>ball[k].pos_x-
1601 BALL)) && (ball[k].x <0)) {
1602 ball[k].tempx=
1603 -(ball[k].pos_x-(brickx+BRICK_WIDTH));
1606 if ((ball[k].pos_x+HALFBALL >= brickx &&
1607 ball[k].pos_x+HALFBALL <=
1608 brickx+BRICK_WIDTH) &&
1609 ((bricky+BRICK_HEIGHT==ball[k].pos_y) ||
1610 (bricky+BRICK_HEIGHT-6<=ball[k].pos_y &&
1611 bricky+BRICK_HEIGHT>ball[k].pos_y)) &&
1612 (ball[k].y <0)) { /* bottom line */
1613 if (brick[i*10+j].hits > 0) {
1614 brick[i*10+j].hits--;
1615 brick[i*10+j].hiteffect++;
1616 score+=2;
1618 else {
1619 brick[i*10+j].used=0;
1620 if (brick[i*10+j].power!=10)
1621 brick[i*10+j].poweruse=2;
1624 ball[k].y = ball[k].y*-1;
1626 else if ((ball[k].pos_x+HALFBALL >= brickx &&
1627 ball[k].pos_x+HALFBALL <=
1628 brickx+BRICK_WIDTH) &&
1629 ((bricky==ball[k].pos_y+BALL) ||
1630 (bricky+6>=ball[k].pos_y+BALL &&
1631 bricky<ball[k].pos_y+BALL)) &&
1632 (ball[k].y >0)) { /* top line */
1633 if (brick[i*10+j].hits > 0) {
1634 brick[i*10+j].hits--;
1635 brick[i*10+j].hiteffect++;
1636 score+=2;
1638 else {
1639 brick[i*10+j].used=0;
1640 if (brick[i*10+j].power!=10)
1641 brick[i*10+j].poweruse=2;
1644 ball[k].y = ball[k].y*-1;
1647 if ((ball[k].pos_y+HALFBALL >= bricky &&
1648 ball[k].pos_y+HALFBALL <=
1649 bricky+BRICK_HEIGHT) &&
1650 ((brickx==ball[k].pos_x+BALL) ||
1651 (brickx+6>=ball[k].pos_x+BALL &&
1652 brickx<ball[k].pos_x+BALL)) &&
1653 (ball[k].x > 0)) { /* left line */
1654 if (brick[i*10+j].hits > 0) {
1655 brick[i*10+j].hits--;
1656 brick[i*10+j].hiteffect++;
1657 score+=2;
1659 else {
1660 brick[i*10+j].used=0;
1661 if (brick[i*10+j].power!=10)
1662 brick[i*10+j].poweruse=2;
1664 ball[k].x = ball[k].x*-1;
1667 else if ((ball[k].pos_y+HALFBALL >= bricky &&
1668 ball[k].pos_y+HALFBALL <=
1669 bricky+BRICK_HEIGHT) &&
1670 ((brickx+BRICK_WIDTH==
1671 ball[k].pos_x) ||
1672 (brickx+BRICK_WIDTH-6<=
1673 ball[k].pos_x &&
1674 brickx+BRICK_WIDTH>
1675 ball[k].pos_x)) &&
1676 (ball[k].x < 0)) { /* Right line */
1677 if (brick[i*10+j].hits > 0) {
1678 brick[i*10+j].hits--;
1679 brick[i*10+j].hiteffect++;
1680 score+=2;
1682 else {
1683 brick[i*10+j].used=0;
1684 if (brick[i*10+j].power!=10)
1685 brick[i*10+j].poweruse=2;
1688 ball[k].x = ball[k].x*-1;
1691 if (brick[i*10+j].used==0) {
1692 brick_on_board--;
1693 score+=8;
1697 } /* for k */
1698 } /* for j */
1699 } /* for i */
1701 /* draw the pad */
1702 rb->lcd_bitmap_part(brickmania_pads,0,pad_type*PAD_HEIGHT,
1703 PAD_WIDTH,pad_pos_x, PAD_POS_Y, PAD_WIDTH,
1704 PAD_HEIGHT);
1706 for(k=0;k<used_balls;k++) {
1708 if ((ball[k].pos_x >= pad_pos_x &&
1709 ball[k].pos_x <= pad_pos_x+PAD_WIDTH) &&
1710 (PAD_POS_Y-4<ball[k].pos_y+BALL &&
1711 PAD_POS_Y>ball[k].pos_y+BALL) && (ball[k].y >0))
1712 ball[k].tempy=PAD_POS_Y-ball[k].pos_y-BALL;
1713 else if ((4>ball[k].pos_y && 0<ball[k].pos_y) &&
1714 (ball[k].y <0))
1715 ball[k].tempy=-ball[k].pos_y;
1716 if ((LCD_WIDTH-4<ball[k].pos_x+BALL &&
1717 LCD_WIDTH>ball[k].pos_x+BALL) && (ball[k].x >0))
1718 ball[k].tempx=LCD_WIDTH-ball[k].pos_x-BALL;
1719 else if ((4>ball[k].pos_x && 0<ball[k].pos_x) &&
1720 (ball[k].x <0))
1721 ball[k].tempx=-ball[k].pos_x;
1723 /* top line */
1724 if (ball[k].pos_y<= 0)
1725 ball[k].y = ball[k].y*-1;
1726 /* bottom line */
1727 else if (ball[k].pos_y+BALL >= GAMESCREEN_HEIGHT) {
1728 if (used_balls>1) {
1729 used_balls--;
1730 ball[k].pos_x = ball[used_balls].pos_x;
1731 ball[k].pos_y = ball[used_balls].pos_y;
1732 ball[k].y = ball[used_balls].y;
1733 ball[k].tempy = ball[used_balls].tempy;
1734 ball[k].x = ball[used_balls].x;
1735 ball[k].tempx = ball[used_balls].tempx;
1736 ball[k].glue = ball[used_balls].glue;
1738 ball[used_balls].x=0;
1739 ball[used_balls].y=0;
1740 ball[used_balls].tempy=0;
1741 ball[used_balls].tempx=0;
1742 ball[used_balls].pos_y=PAD_POS_Y-BALL;
1743 ball[used_balls].pos_x=pad_pos_x+(PAD_WIDTH/2)-2;
1745 k--;
1746 continue;
1747 } else {
1748 life--;
1749 if (life>=0) {
1750 int_game(0);
1751 sleep(2);
1756 /* left line ,right line */
1757 if ((ball[k].pos_x <= 0) ||
1758 (ball[k].pos_x+BALL >= LCD_WIDTH)) {
1759 ball[k].x = ball[k].x*-1;
1760 ball[k].pos_x = ball[k].pos_x <= 0 ? 0 : LCD_WIDTH-BALL;
1763 if ((ball[k].pos_y+BALL >= PAD_POS_Y &&
1764 (ball[k].pos_x >= pad_pos_x &&
1765 ball[k].pos_x <= pad_pos_x+PAD_WIDTH)) &&
1766 start_game != 1 && !ball[k].glue) {
1768 if ((ball[k].pos_x+HALFBALL >= pad_pos_x &&
1769 ball[k].pos_x+HALFBALL <=
1770 pad_pos_x+(PAD_WIDTH/2/4)) ||
1771 (ball[k].pos_x +HALFBALL>=
1772 pad_pos_x+(PAD_WIDTH-(PAD_WIDTH/2/4)) &&
1773 ball[k].pos_x+HALFBALL <= pad_pos_x+PAD_WIDTH)) {
1775 ball[k].y = -2;
1776 if (ball[k].pos_x != 0 &&
1777 ball[k].pos_x+BALL!=LCD_WIDTH)
1778 ball[k].x = pad_check(6,0,ball[k].pos_x+2<=
1779 pad_pos_x+(PAD_WIDTH/2)?
1780 0:1,k);
1783 else if ((ball[k].pos_x+HALFBALL >=
1784 pad_pos_x+(PAD_WIDTH/2/4) &&
1785 ball[k].pos_x+HALFBALL <=
1786 pad_pos_x+2*(PAD_WIDTH/2/4)) ||
1787 (ball[k].pos_x+HALFBALL >=
1788 pad_pos_x+(PAD_WIDTH-2*(PAD_WIDTH/2/4)) &&
1789 ball[k].pos_x+HALFBALL <=
1790 pad_pos_x+(PAD_WIDTH-(PAD_WIDTH/2/4)) )) {
1792 ball[k].y = -3;
1793 if (ball[k].pos_x != 0 &&
1794 ball[k].pos_x+BALL!=LCD_WIDTH)
1795 ball[k].x = pad_check(4,0,ball[k].pos_x+2<=
1796 pad_pos_x+(PAD_WIDTH/2)?
1797 0:1,k);
1800 else if ((ball[k].pos_x+HALFBALL >=
1801 pad_pos_x+2*(PAD_WIDTH/2/4) &&
1802 ball[k].pos_x+HALFBALL <=
1803 pad_pos_x+3*(PAD_WIDTH/2/4)) ||
1804 (ball[k].pos_x+2 >=
1805 pad_pos_x+(PAD_WIDTH-3*(PAD_WIDTH/2/4)) &&
1806 ball[k].pos_x+2 <=
1807 pad_pos_x+ ((PAD_WIDTH/2)-2*(PAD_WIDTH/2/4)) )) {
1809 ball[k].y = -4;
1810 if (ball[k].pos_x != 0 &&
1811 ball[k].pos_x+BALL!=LCD_WIDTH)
1812 ball[k].x = pad_check(3,0,ball[k].pos_x+2<=
1813 pad_pos_x+(PAD_WIDTH/2)?
1814 0:1,k);
1817 else if ((ball[k].pos_x+HALFBALL >=
1818 pad_pos_x+3*(PAD_WIDTH/2/4) &&
1819 ball[k].pos_x+HALFBALL <=
1820 pad_pos_x+4*(PAD_WIDTH/2/4)-2) ||
1821 (ball[k].pos_x+2 >= pad_pos_x+(PAD_WIDTH/2+2) &&
1822 ball[k].pos_x+2 <=
1823 pad_pos_x+(PAD_WIDTH-3*(PAD_WIDTH/2/4)) )) {
1825 ball[k].y = -4;
1826 if (ball[k].pos_x != 0 &&
1827 ball[k].pos_x+BALL!=LCD_WIDTH)
1828 ball[k].x = pad_check(2,1,0,k);
1831 else {
1832 ball[k].y = -4;
1836 if (!ball[k].glue) {
1837 ball[k].pos_x+=ball[k].tempx!=0?ball[k].tempx:ball[k].x;
1838 ball[k].pos_y+=ball[k].tempy!=0?ball[k].tempy:ball[k].y;
1840 ball[k].tempy=0;
1841 ball[k].tempx=0;
1844 if (ball[k].pos_y+5 >= PAD_POS_Y &&
1845 (pad_type==1 && !ball[k].glue) &&
1846 (ball[k].pos_x >= pad_pos_x &&
1847 ball[k].pos_x <= pad_pos_x+PAD_WIDTH)) {
1848 ball[k].y=0;
1849 ball[k].pos_y=PAD_POS_Y-BALL;
1850 ball[k].glue=true;
1852 } /* for k */
1854 rb->lcd_update();
1856 if (brick_on_board < 0) {
1857 if (cur_level+1<levels_num) {
1858 cur_level++;
1859 score+=100;
1860 int_game(1);
1861 sleep(2);
1863 else {
1864 rb->lcd_getstringsize("Congratulations!", &sw, NULL);
1865 rb->lcd_putsxy(LCD_WIDTH/2-sw/2, STRINGPOS_CONGRATS,
1866 "Congratulations!");
1867 #if (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
1868 rb->lcd_getstringsize("No more levels", &sw, NULL);
1869 rb->lcd_putsxy(LCD_WIDTH/2-sw/2, STRINGPOS_FINISH,
1870 "No more levels");
1871 #else
1872 rb->lcd_getstringsize("You have finished the game!",
1873 &sw, NULL);
1874 rb->lcd_putsxy(LCD_WIDTH/2-sw/2, STRINGPOS_FINISH,
1875 "You have finished the game!");
1876 #endif
1877 vscore=score;
1878 rb->lcd_update();
1879 if (score>highscore) {
1880 sleep(2);
1881 highscore=score;
1882 rb->splash(HZ*2, "New High Score");
1884 else {
1885 sleep(3);
1888 switch(game_menu(0)) {
1889 case 0:
1890 life=2;
1891 cur_level=0;
1892 int_game(1);
1893 break;
1894 case 1:
1895 con_game=1;
1896 break;
1897 case 2:
1898 if (help(0)==1) return 1;
1899 break;
1900 case 3:
1901 return 1;
1902 break;
1907 int move_button,button;
1908 int button_right,button_left;
1909 button=rb->button_get(false);
1911 #if defined(HAS_BUTTON_HOLD) && !defined(HAVE_REMOTE_LCD_AS_MAIN)
1912 /* FIXME: Should probably check remote hold here */
1913 if (rb->button_hold())
1914 button = QUIT;
1915 #endif
1917 #ifdef HAVE_TOUCHSCREEN
1918 if(button & BUTTON_TOUCHSCREEN)
1920 short touch_x, touch_y;
1921 touch_x = rb->button_get_data() >> 16;
1922 touch_y = rb->button_get_data() & 0xffff;
1923 if(touch_y >= PAD_POS_Y && touch_y <= PAD_POS_Y+PAD_HEIGHT)
1925 pad_pos_x += (flip_sides ? -1 : 1) * ( (touch_x-pad_pos_x-PAD_WIDTH/2) / 4 );
1927 if(pad_pos_x < 0)
1928 pad_pos_x = 0;
1929 else if(pad_pos_x+PAD_WIDTH > LCD_WIDTH)
1930 pad_pos_x = LCD_WIDTH-PAD_WIDTH;
1931 for(k=0;k<used_balls;k++)
1932 if ((start_game==1 || ball[k].glue))
1933 ball[k].pos_x = pad_pos_x+PAD_WIDTH/2;
1936 if(button & BUTTON_REL)
1937 button = SELECT;
1939 else
1941 #endif
1942 move_button=rb->button_status();
1943 #ifdef ALTRIGHT
1944 button_right=((move_button & RIGHT) || (move_button & ALTRIGHT));
1945 button_left=((move_button & LEFT) || (move_button & ALTLEFT));
1946 #else
1947 button_right=((move_button & RIGHT) || (SCROLL_FWD(button)));
1948 button_left=((move_button & LEFT) || (SCROLL_BACK(button)));
1949 #endif
1950 if ((con_game== 1 && start_game!=1) && (button_right || button_left))
1951 continue;
1952 if ((button_right && flip_sides==false) ||
1953 (button_left && flip_sides==true)) {
1954 if (pad_pos_x+8+PAD_WIDTH > LCD_WIDTH) {
1955 for(k=0;k<used_balls;k++)
1956 if (start_game==1 || ball[k].glue)
1957 ball[k].pos_x+=LCD_WIDTH-pad_pos_x-PAD_WIDTH;
1958 pad_pos_x+=LCD_WIDTH-pad_pos_x-PAD_WIDTH;
1960 else {
1961 for(k=0;k<used_balls;k++)
1962 if ((start_game==1 || ball[k].glue))
1963 ball[k].pos_x+=8;
1964 pad_pos_x+=8;
1967 else if ((button_left && flip_sides==false) ||
1968 (button_right && flip_sides==true)) {
1969 if (pad_pos_x-8 < 0) {
1970 for(k=0;k<used_balls;k++)
1971 if (start_game==1 || ball[k].glue)
1972 ball[k].pos_x-=pad_pos_x;
1973 pad_pos_x-=pad_pos_x;
1975 else {
1976 for(k=0;k<used_balls;k++)
1977 if (start_game==1 || ball[k].glue)
1978 ball[k].pos_x-=8;
1979 pad_pos_x-=8;
1982 #ifdef HAVE_TOUCHSCREEN
1984 #endif
1987 switch(button) {
1988 case UP:
1989 case SELECT:
1990 if (start_game==1 && con_game!=1 && pad_type!=1) {
1991 for(k=0;k<used_balls;k++) {
1992 ball[k].y=-4;
1993 ball[k].x=pad_pos_x+(PAD_WIDTH/2)-2>=
1994 LCD_WIDTH/2?2:-2;
1996 start_game =0;
1998 else if (pad_type==1) {
1999 for(k=0;k<used_balls;k++) {
2000 if (ball[k].glue)
2001 ball[k].glue=false;
2002 else if (start_game==1) {
2003 ball[k].x = x[k];
2004 ball[k].y = y[k];
2008 if (start_game!=1 && con_game==1) {
2009 start_game =0;
2010 con_game=0;
2012 } else if (pad_type==2 && con_game!=1) {
2013 int tfire;
2014 tfire=fire_space();
2015 fire[tfire].top=PAD_POS_Y-7;
2016 fire[tfire].left=pad_pos_x+1;
2017 tfire=fire_space();
2018 fire[tfire].top=PAD_POS_Y-7;
2019 fire[tfire].left=pad_pos_x+PAD_WIDTH-1;
2020 } else if (con_game==1 && start_game!=1) {
2021 for(k=0;k<used_balls;k++) {
2022 ball[k].x=x[k];
2023 ball[k].y=y[k];
2025 con_game=0;
2027 break;
2028 #ifdef RC_QUIT
2029 case RC_QUIT:
2030 #endif
2031 case QUIT:
2032 switch(game_menu(1)) {
2033 case 0:
2034 life=2;
2035 cur_level=0;
2036 int_game(1);
2037 break;
2038 case 1:
2039 for(k=0;k<used_balls;k++)
2040 if (ball[k].x!=0 && ball[k].y !=0)
2041 con_game=1;
2042 break;
2043 case 2:
2044 if (help(1)==1)
2045 return 1;
2046 break;
2047 case 3:
2048 return 1;
2049 break;
2052 for(k=0;k<used_balls;k++) {
2053 if (ball[k].x!=0)
2054 x[k]=ball[k].x;
2055 ball[k].x=0;
2056 if (ball[k].y!=0)
2057 y[k]=ball[k].y;
2058 ball[k].y=0;
2061 break;
2063 default:
2064 if(rb->default_event_handler(button) == SYS_USB_CONNECTED)
2065 return 1;
2066 break;
2069 else {
2070 #ifdef HAVE_LCD_COLOR
2071 rb->lcd_bitmap_transparent(brickmania_gameover,
2072 (LCD_WIDTH - GAMEOVER_WIDTH)/2,
2073 (GAMESCREEN_HEIGHT - GAMEOVER_HEIGHT)/2,
2074 GAMEOVER_WIDTH,GAMEOVER_HEIGHT);
2075 #else /* greyscale and mono */
2076 rb->lcd_bitmap(brickmania_gameover,(LCD_WIDTH - GAMEOVER_WIDTH)/2,
2077 (GAMESCREEN_HEIGHT - GAMEOVER_HEIGHT)/2,
2078 GAMEOVER_WIDTH,GAMEOVER_HEIGHT);
2079 #endif
2080 rb->lcd_update();
2081 if (score>highscore) {
2082 sleep(2);
2083 highscore=score;
2084 rb->splash(HZ*2, "New High Score");
2085 } else {
2086 sleep(3);
2089 for(k=0;k<used_balls;k++) {
2090 ball[k].x=0;
2091 ball[k].y=0;
2094 switch(game_menu(0)) {
2095 case 0:
2096 cur_level=0;
2097 life=2;
2098 int_game(1);
2099 break;
2100 case 1:
2101 con_game=1;
2102 break;
2103 case 2:
2104 if (help(0)==1)
2105 return 1;
2106 break;
2107 case 3:
2108 return 1;
2109 break;
2112 if (end > *rb->current_tick)
2113 rb->sleep(end-*rb->current_tick);
2114 else
2115 rb->yield();
2119 /* this is the plugin entry point */
2120 enum plugin_status plugin_start(const void* parameter)
2122 (void)parameter;
2124 rb->lcd_setfont(FONT_SYSFIXED);
2125 #if LCD_DEPTH > 1
2126 rb->lcd_set_backdrop(NULL);
2127 #endif
2128 /* Turn off backlight timeout */
2129 backlight_force_on(); /* backlight control in lib/helper.c */
2131 /* now go ahead and have fun! */
2132 while (game_loop()!=1);
2134 configfile_save(HIGH_SCORE,config,1,0);
2136 /* Restore user's original backlight setting */
2137 rb->lcd_setfont(FONT_UI);
2138 /* Turn on backlight timeout (revert to settings) */
2139 backlight_use_settings(); /* backlight control in lib/helper.c */
2141 return PLUGIN_OK;