Add 2008 to the copyright notice.
[Rockbox.git] / apps / plugins / brickmania.c
blob5cefe1bc6d36403eafe17d75e2f11ef20fc380b7
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2005, 2006 Ben Basha (Paprica)
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
20 #include "plugin.h"
21 #include "configfile.h" /* Part of libplugin */
22 #include "helper.h"
24 PLUGIN_HEADER
27 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
29 #define QUIT BUTTON_OFF
30 #define LEFT BUTTON_LEFT
31 #define RIGHT BUTTON_RIGHT
32 #define SELECT BUTTON_SELECT
33 #define UP BUTTON_UP
34 #define DOWN BUTTON_DOWN
36 #define RC_QUIT BUTTON_RC_STOP
39 #elif CONFIG_KEYPAD == ONDIO_PAD
41 #define QUIT BUTTON_OFF
42 #define LEFT BUTTON_LEFT
43 #define RIGHT BUTTON_RIGHT
44 #define SELECT BUTTON_MENU
45 #define UP BUTTON_UP
46 #define DOWN BUTTON_DOWN
49 #elif CONFIG_KEYPAD == RECORDER_PAD
51 #define QUIT BUTTON_OFF
52 #define LEFT BUTTON_LEFT
53 #define RIGHT BUTTON_RIGHT
54 #define SELECT BUTTON_PLAY
55 #define UP BUTTON_UP
56 #define DOWN BUTTON_DOWN
59 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
61 #define QUIT BUTTON_OFF
62 #define LEFT BUTTON_LEFT
63 #define RIGHT BUTTON_RIGHT
64 #define SELECT BUTTON_SELECT
65 #define UP BUTTON_UP
66 #define DOWN BUTTON_DOWN
69 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
70 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
71 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
73 #define QUIT BUTTON_MENU
74 #define LEFT BUTTON_LEFT
75 #define RIGHT BUTTON_RIGHT
76 #define SELECT BUTTON_SELECT
77 #define UP BUTTON_SCROLL_BACK
78 #define DOWN BUTTON_SCROLL_FWD
80 #define SCROLL_FWD(x) ((x) & BUTTON_SCROLL_FWD)
81 #define SCROLL_BACK(x) ((x) & BUTTON_SCROLL_BACK)
84 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
86 #define QUIT BUTTON_POWER
87 #define LEFT BUTTON_LEFT
88 #define RIGHT BUTTON_RIGHT
89 #define SELECT BUTTON_SELECT
90 #define UP BUTTON_UP
91 #define DOWN BUTTON_DOWN
94 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
96 #define QUIT BUTTON_POWER
97 #define LEFT BUTTON_LEFT
98 #define RIGHT BUTTON_RIGHT
99 #define SELECT BUTTON_PLAY
100 #define UP BUTTON_UP
101 #define DOWN BUTTON_DOWN
104 #elif CONFIG_KEYPAD == SANSA_E200_PAD
106 #define QUIT BUTTON_POWER
107 #define LEFT BUTTON_LEFT
108 #define RIGHT BUTTON_RIGHT
109 #define SELECT BUTTON_SELECT
110 #define UP BUTTON_SCROLL_BACK
111 #define DOWN BUTTON_SCROLL_FWD
113 #define SCROLL_FWD(x) ((x) & BUTTON_SCROLL_FWD)
114 #define SCROLL_BACK(x) ((x) & BUTTON_SCROLL_BACK)
117 #elif CONFIG_KEYPAD == SANSA_C200_PAD
119 #define QUIT BUTTON_POWER
120 #define LEFT BUTTON_LEFT
121 #define RIGHT BUTTON_RIGHT
122 #define ALTLEFT BUTTON_VOL_DOWN
123 #define ALTRIGHT BUTTON_VOL_UP
124 #define SELECT BUTTON_SELECT
125 #define UP BUTTON_UP
126 #define DOWN BUTTON_DOWN
129 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
131 #define QUIT BUTTON_POWER
132 #define LEFT BUTTON_LEFT
133 #define RIGHT BUTTON_RIGHT
134 #define SELECT BUTTON_PLAY
135 #define UP BUTTON_SCROLL_UP
136 #define DOWN BUTTON_SCROLL_DOWN
138 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
140 #define QUIT BUTTON_BACK
141 #define LEFT BUTTON_LEFT
142 #define RIGHT BUTTON_RIGHT
143 #define SELECT BUTTON_SELECT
144 #define UP BUTTON_UP
145 #define DOWN BUTTON_DOWN
147 #else
148 #error Unsupported keypad
149 #endif
151 #ifndef SCROLL_FWD /* targets without scroll wheel*/
152 #define SCROLL_FWD(x) (0)
153 #define SCROLL_BACK(x) (0)
154 #endif
157 static struct plugin_api* rb;
159 enum menu_items {
160 BM_START,
161 BM_SEL_START,
162 BM_RESUME,
163 BM_SEL_RESUME,
164 BM_NO_RESUME,
165 BM_HELP,
166 BM_SEL_HELP,
167 BM_QUIT,
168 BM_SEL_QUIT,
171 /* External bitmaps */
172 #if (LCD_WIDTH != 112) && (LCD_HEIGHT != 64)
173 extern const fb_data brickmania_menu_bg[];
174 extern const fb_data brickmania_gameover[];
175 #endif
176 extern const fb_data brickmania_menu_items[];
177 extern const fb_data brickmania_ball[];
178 #ifdef HAVE_LCD_COLOR
179 extern const fb_data brickmania_break[];
180 #endif
182 /* normal, glue, fire */
183 extern const fb_data brickmania_pads[];
185 /* +life, -life, glue, fire, normal */
186 extern const fb_data brickmania_powerups[];
188 /* purple, red, blue, pink, green, yellow orange */
189 extern const fb_data brickmania_bricks[];
191 #include "brickmania_pads.h"
192 #include "brickmania_bricks.h"
193 #include "brickmania_powerups.h"
194 #include "brickmania_ball.h"
195 #include "brickmania_menu_items.h"
196 #include "brickmania_gameover.h"
198 #define PAD_WIDTH BMPWIDTH_brickmania_pads
199 #define PAD_HEIGHT (BMPHEIGHT_brickmania_pads/3)
200 #define BRICK_HEIGHT (BMPHEIGHT_brickmania_bricks/7)
201 #define BRICK_WIDTH BMPWIDTH_brickmania_bricks
202 #define LEFTMARGIN ((LCD_WIDTH-10*BRICK_WIDTH)/2)
203 #define POWERUP_HEIGHT (BMPHEIGHT_brickmania_powerups/7)
204 #define POWERUP_WIDTH BMPWIDTH_brickmania_powerups
205 #define BALL BMPHEIGHT_brickmania_ball
206 #define HALFBALL ((BALL+1)/2)
207 #define MENU_ITEMXOFS ((LCD_WIDTH - BMPWIDTH_brickmania_menu_items)/2)
208 #define MENU_ITEMHEIGHT (BMPHEIGHT_brickmania_menu_items/9)
209 #define MENU_ITEMWIDTH BMPWIDTH_brickmania_menu_items
210 #define GAMEOVER_WIDTH BMPWIDTH_brickmania_gameover
211 #define GAMEOVER_HEIGHT BMPHEIGHT_brickmania_gameover
213 #if LCD_DEPTH > 1 /* currently no background bmp for mono screens */
214 #include "brickmania_menu_bg.h"
215 #define MENU_BGHEIGHT BMPHEIGHT_brickmania_menu_bg
216 #define MENU_BGWIDTH BMPWIDTH_brickmania_menu_bg
217 #endif
220 #if (LCD_WIDTH == 320) && (LCD_HEIGHT == 240)
222 /* The time (in ms) for one iteration through the game loop - decrease this
223 to speed up the game - note that current_tick is (currently) only accurate
224 to 10ms.
226 #define CYCLETIME 30
228 #define TOPMARGIN 30
230 #define BMPYOFS_start 110
231 #define HIGHSCORE_XPOS 57
232 #define HIGHSCORE_YPOS 88
234 #define STRINGPOS_FINISH 140
235 #define STRINGPOS_CONGRATS 157
236 #define STRINGPOS_NAVI 150
237 #define STRINGPOS_FLIP 150
239 #elif (LCD_WIDTH >= 220) && (LCD_HEIGHT >= 176)
241 /* The time (in ms) for one iteration through the game loop - decrease this
242 to speed up the game - note that current_tick is (currently) only accurate
243 to 10ms.
245 #define CYCLETIME 30
247 /* Offsets for LCDS > 220x176 */
249 #define GAMESCREEN_HEIGHT 176
250 #define TOPMARGIN 30
252 #define XOFS ((LCD_WIDTH-220)/BRICK_WIDTH/2)*BRICK_WIDTH
253 #define YOFS ((LCD_HEIGHT-176)/BRICK_HEIGHT/2)*BRICK_HEIGHT
255 #define BMPYOFS_start (78+YOFS)
256 #define HIGHSCORE_XPOS (17+XOFS)
257 #define HIGHSCORE_YPOS (56+YOFS)
259 #define STRINGPOS_FINISH 140
260 #define STRINGPOS_CONGRATS 157
261 #define STRINGPOS_NAVI 150
262 #define STRINGPOS_FLIP 150
264 #elif (LCD_WIDTH == 160) && (LCD_HEIGHT == 128)
265 /* The time (in ms) for one iteration through the game loop - decrease this
266 to speed up the game - note that current_tick is (currently) only accurate
267 to 10ms.
269 #define CYCLETIME 50
271 #define TOPMARGIN 21
273 #if LCD_DEPTH > 2
274 #define BMPYOFS_start 58
275 #else
276 #define BMPYOFS_start 66
277 #endif
278 #define HIGHSCORE_XPOS 10
279 #define HIGHSCORE_YPOS 38
281 #define STRINGPOS_FINISH 110
282 #define STRINGPOS_CONGRATS 100
283 #define STRINGPOS_NAVI 100
284 #define STRINGPOS_FLIP 100
286 #elif (LCD_WIDTH == 132) && (LCD_HEIGHT == 80)
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 50
294 #define TOPMARGIN 10
296 #define BMPYOFS_start 30
297 #define HIGHSCORE_XPOS 68
298 #define HIGHSCORE_YPOS 8
300 #define STRINGPOS_FINISH 55
301 #define STRINGPOS_CONGRATS 45
302 #define STRINGPOS_NAVI 60
303 #define STRINGPOS_FLIP 60
305 #elif (LCD_WIDTH == 128) && (LCD_HEIGHT == 128)
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 50
313 #define GAMESCREEN_HEIGHT 100
314 #define TOPMARGIN 15
316 #define BMPYOFS_start 70
317 #define HIGHSCORE_XPOS 8
318 #define HIGHSCORE_YPOS 36
320 #define STRINGPOS_FINISH 55
321 #define STRINGPOS_CONGRATS 45
322 #define STRINGPOS_NAVI 60
323 #define STRINGPOS_FLIP 60
325 /* iPod Mini */
326 #elif (LCD_WIDTH == 138) && (LCD_HEIGHT == 110)
327 /* The time (in ms) for one iteration through the game loop - decrease this
328 to speed up the game - note that current_tick is (currently) only accurate
329 to 10ms.
331 #define CYCLETIME 50
333 #define TOPMARGIN 10
335 #define BMPYOFS_start 51
336 #define HIGHSCORE_XPOS 73
337 #define HIGHSCORE_YPOS 25
339 #define STRINGPOS_FINISH 54
340 #define STRINGPOS_CONGRATS 44
341 #define STRINGPOS_NAVI 44
342 #define STRINGPOS_FLIP 44
345 #elif (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
346 /* The time (in ms) for one iteration through the game loop - decrease this
347 to speed up the game - note that current_tick is (currently) only accurate
348 to 10ms.
350 #define CYCLETIME 75
352 #define TOPMARGIN 10
354 #define BMPYOFS_start 22
355 #define HIGHSCORE_XPOS 0
356 #define HIGHSCORE_YPOS 0
358 #define STRINGPOS_FINISH 54
359 #define STRINGPOS_CONGRATS 44
360 #define STRINGPOS_NAVI 44
361 #define STRINGPOS_FLIP 44
363 /* nano and sansa */
364 #elif (LCD_WIDTH == 176) && (LCD_HEIGHT >= 132) && (LCD_DEPTH==16)
365 /* The time (in ms) for one iteration through the game loop - decrease this
366 to speed up the game - note that current_tick is (currently) only accurate
367 to 10ms.
370 #define CYCLETIME 30
372 #define GAMESCREEN_HEIGHT 132
373 #define TOPMARGIN 21
375 #define BMPYOFS_start 58
376 #define HIGHSCORE_XPOS 7
377 #define HIGHSCORE_YPOS 36
379 #define STRINGPOS_FINISH 110
380 #define STRINGPOS_CONGRATS 110
381 #define STRINGPOS_NAVI 100
382 #define STRINGPOS_FLIP 100
384 #else
385 #error Unsupported LCD Size
386 #endif
389 #ifndef GAMESCREEN_HEIGHT
390 #define GAMESCREEN_HEIGHT LCD_HEIGHT
391 #endif
393 /* calculate menu item offsets from the first defined and the height*/
394 #define BMPYOFS_resume (BMPYOFS_start + MENU_ITEMHEIGHT)
395 #define BMPYOFS_help (BMPYOFS_start + 2*MENU_ITEMHEIGHT)
396 #define BMPYOFS_quit (BMPYOFS_start + 3*MENU_ITEMHEIGHT)
398 /*calculate paddle y-position */
399 #if GAMESCREEN_HEIGHT >= 128
400 #define PAD_POS_Y GAMESCREEN_HEIGHT -PAD_HEIGHT - 2
401 #else
402 #define PAD_POS_Y GAMESCREEN_HEIGHT -PAD_HEIGHT - 1
403 #endif
406 int levels_num = 29;
408 static unsigned char levels[29][8][10] = {
409 { /* level1 */
410 {0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1},
411 {0x2,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x2},
412 {0x0,0x2,0x1,0x0,0x0,0x0,0x0,0x1,0x2,0x0},
413 {0x0,0x0,0x2,0x1,0x0,0x0,0x1,0x2,0x0,0x0},
414 {0x0,0x0,0x0,0x2,0x1,0x1,0x2,0x0,0x0,0x0},
415 {0x7,0x0,0x0,0x7,0x2,0x2,0x7,0x0,0x0,0x7},
416 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
417 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}
419 { /* level2 */
420 {0x0,0x0,0x7,0x7,0x1,0x1,0x7,0x7,0x0,0x0},
421 {0x0,0x1,0x0,0x0,0x1,0x1,0x0,0x0,0x1,0x0},
422 {0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1},
423 {0x1,0x1,0x1,0x1,0x0,0x0,0x1,0x1,0x1,0x1},
424 {0x1,0x1,0x2,0x1,0x0,0x0,0x1,0x2,0x1,0x1},
425 {0x1,0x2,0x0,0x2,0x2,0x2,0x2,0x0,0x2,0x1},
426 {0x0,0x1,0x2,0x0,0x0,0x0,0x0,0x2,0x1,0x0},
427 {0x0,0x0,0x1,0x2,0x2,0x2,0x2,0x1,0x0,0x0}
429 { /* level3 */
430 {0x3,0x3,0x3,0x3,0x0,0x0,0x2,0x2,0x2,0x2},
431 {0x3,0x23,0x23,0x3,0x0,0x0,0x2,0x22,0x22,0x2},
432 {0x3,0x3,0x3,0x3,0x0,0x0,0x2,0x2,0x2,0x2},
433 {0x0,0x0,0x0,0x0,0x37,0x37,0x0,0x0,0x0,0x0},
434 {0x0,0x0,0x0,0x0,0x37,0x37,0x0,0x0,0x0,0x0},
435 {0x5,0x5,0x5,0x5,0x0,0x0,0x6,0x6,0x6,0x6},
436 {0x5,0x25,0x25,0x5,0x0,0x0,0x6,0x26,0x26,0x6},
437 {0x5,0x5,0x5,0x5,0x0,0x0,0x6,0x6,0x6,0x6}
439 { /* level4 */
440 {0x0,0x0,0x0,0x27,0x27,0x27,0x27,0x0,0x0,0x0},
441 {0x0,0x0,0x0,0x27,0x7,0x7,0x27,0x0,0x0,0x0},
442 {0x22,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x22},
443 {0x22,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x22},
444 {0x26,0x6,0x0,0x2,0x2,0x2,0x2,0x0,0x6,0x26},
445 {0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0},
446 {0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0},
447 {0x1,0x1,0x1,0x1,0x0,0x0,0x1,0x1,0x1,0x1}
449 { /* level5 */
450 {0x1,0x0,0x2,0x2,0x0,0x3,0x3,0x0,0x4,0x4},
451 {0x0,0x2,0x2,0x0,0x3,0x3,0x0,0x4,0x4,0x0},
452 {0x2,0x2,0x0,0x3,0x3,0x0,0x4,0x4,0x0,0x5},
453 {0x2,0x0,0x3,0x3,0x0,0x4,0x4,0x0,0x5,0x5},
454 {0x0,0x33,0x3,0x0,0x4,0x4,0x0,0x5,0x5,0x0},
455 {0x3,0x33,0x0,0x4,0x4,0x0,0x5,0x5,0x0,0x36},
456 {0x3,0x0,0x4,0x4,0x0,0x5,0x5,0x0,0x6,0x36},
457 {0x0,0x24,0x24,0x0,0x25,0x25,0x0,0x26,0x26,0x0}
459 { /* level6 */
460 {0x0,0x1,0x3,0x7,0x7,0x7,0x7,0x3,0x1,0x0},
461 {0x3,0x1,0x3,0x7,0x0,0x0,0x7,0x3,0x1,0x3},
462 {0x3,0x1,0x3,0x7,0x7,0x7,0x7,0x3,0x1,0x3},
463 {0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0},
464 {0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5},
465 {0x5,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x5},
466 {0x0,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x0},
467 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}
469 { /* level7 */
470 {0x0,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x0},
471 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
472 {0x6,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x6},
473 {0x6,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x6},
474 {0x6,0x6,0x6,0x0,0x0,0x0,0x0,0x6,0x6,0x6},
475 {0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0},
476 {0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0},
477 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}
479 { /* level8 */
480 {0x0,0x7,0x7,0x7,0x7,0x7,0x7,0x7,0x7,0x0},
481 {0x0,0x0,0x0,0x4,0x0,0x0,0x4,0x0,0x0,0x0},
482 {0x6,0x6,0x0,0x2,0x32,0x32,0x2,0x0,0x6,0x6},
483 {0x0,0x0,0x2,0x2,0x2,0x2,0x2,0x2,0x0,0x0},
484 {0x0,0x6,0x6,0x0,0x0,0x0,0x0,0x6,0x6,0x0},
485 {0x0,0x0,0x0,0x5,0x25,0x25,0x5,0x0,0x0,0x0},
486 {0x0,0x5,0x5,0x25,0x5,0x5,0x25,0x5,0x5,0x0},
487 {0x5,0x5,0x25,0x5,0x5,0x5,0x5,0x25,0x5,0x5}
489 { /* level9 */
490 {0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2},
491 {0x2,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x2},
492 {0x2,0x0,0x3,0x0,0x1,0x1,0x0,0x3,0x0,0x2},
493 {0x2,0x0,0x0,0x1,0x0,0x0,0x1,0x0,0x0,0x2},
494 {0x2,0x0,0x1,0x0,0x3,0x3,0x0,0x1,0x0,0x2},
495 {0x2,0x0,0x0,0x1,0x0,0x0,0x1,0x0,0x0,0x2},
496 {0x2,0x2,0x0,0x0,0x1,0x1,0x0,0x0,0x2,0x2},
497 {0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2}
499 { /* level10 */
500 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
501 {0x0,0x5,0x0,0x5,0x0,0x5,0x0,0x5,0x0,0x5},
502 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
503 {0x0,0x0,0x0,0x0,0x1,0x1,0x0,0x0,0x0,0x0},
504 {0x0,0x0,0x0,0x4,0x1,0x1,0x4,0x0,0x0,0x0},
505 {0x0,0x0,0x3,0x4,0x1,0x1,0x4,0x3,0x0,0x0},
506 {0x0,0x2,0x3,0x4,0x1,0x1,0x4,0x3,0x2,0x0},
507 {0x1,0x2,0x3,0x4,0x1,0x1,0x4,0x3,0x2,0x1}
509 { /* level11 */
510 {0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3},
511 {0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x2},
512 {0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2},
513 {0x2,0x0,0x0,0x0,0x7,0x7,0x0,0x0,0x0,0x2},
514 {0x2,0x0,0x0,0x7,0x7,0x7,0x7,0x0,0x0,0x2},
515 {0x0,0x0,0x0,0x1,0x0,0x0,0x1,0x0,0x0,0x0},
516 {0x0,0x2,0x0,0x1,0x0,0x0,0x1,0x0,0x2,0x0},
517 {0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5}
519 { /* level 12 */
520 {0x2,0x1,0x3,0x1,0x0,0x0,0x1,0x3,0x1,0x2},
521 {0x1,0x1,0x1,0x1,0x0,0x0,0x1,0x1,0x1,0x1},
522 {0x1,0x1,0x1,0x0,0x1,0x1,0x0,0x1,0x1,0x1},
523 {0x0,0x1,0x0,0x1,0x6,0x6,0x1,0x0,0x1,0x0},
524 {0x0,0x0,0x1,0x1,0x6,0x6,0x1,0x1,0x0,0x0},
525 {0x1,0x1,0x1,0x7,0x0,0x0,0x7,0x1,0x1,0x1},
526 {0x1,0x1,0x7,0x1,0x0,0x0,0x1,0x7,0x1,0x1},
527 {0x2,0x2,0x0,0x2,0x2,0x2,0x2,0x0,0x2,0x2}
529 {/* levell13 */
530 {0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2},
531 {0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2},
532 {0x2,0x0,0x2,0x2,0x2,0x2,0x2,0x2,0x0,0x2},
533 {0x2,0x0,0x2,0x3,0x3,0x3,0x3,0x3,0x0,0x2},
534 {0x2,0x0,0x2,0x4,0x4,0x4,0x4,0x4,0x0,0x2},
535 {0x2,0x0,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2},
536 {0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
537 {0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2}
539 {/* level14 */
540 {0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1},
541 {0x4,0x4,0x4,0x4,0x2,0x2,0x4,0x4,0x4,0x4},
542 {0x4,0x0,0x0,0x0,0x2,0x2,0x0,0x0,0x0,0x4},
543 {0x4,0x0,0x0,0x2,0x3,0x3,0x2,0x0,0x0,0x4},
544 {0x4,0x0,0x2,0x23,0x3,0x3,0x23,0x2,0x0,0x4},
545 {0x4,0x0,0x2,0x22,0x2,0x2,0x22,0x2,0x0,0x4},
546 {0x4,0x0,0x6,0x21,0x5,0x5,0x21,0x6,0x0,0x4},
547 {0x4,0x6,0x1,0x1,0x5,0x5,0x1,0x1,0x6,0x4}
549 {/* level 15 */
550 {0x4,0x4,0x4,0x4,0x4,0x3,0x3,0x3,0x3,0x3},
551 {0x2,0x2,0x1,0x1,0x1,0x1,0x1,0x5,0x0,0x0},
552 {0x2,0x2,0x1,0x1,0x1,0x0,0x1,0x6,0x0,0x0},
553 {0x2,0x1,0x1,0x2,0x1,0x1,0x1,0x5,0x0,0x0},
554 {0x2,0x1,0x2,0x2,0x2,0x1,0x1,0x6,0x0,0x0},
555 {0x2,0x1,0x2,0x2,0x2,0x1,0x3,0x5,0x3,0x0},
556 {0x2,0x1,0x1,0x2,0x1,0x1,0x1,0x6,0x0,0x0},
557 {0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2}
559 {/* level 16 (Rockbox) by ts-x */
560 {0x2,0x2,0x3,0x3,0x3,0x4,0x4,0x5,0x0,0x5},
561 {0x2,0x0,0x3,0x0,0x3,0x4,0x0,0x5,0x5,0x0},
562 {0x2,0x0,0x3,0x3,0x3,0x4,0x4,0x5,0x0,0x5},
563 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
564 {0x6,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
565 {0x7,0x7,0x7,0x1,0x1,0x1,0x2,0x0,0x2,0x0},
566 {0x7,0x0,0x7,0x1,0x0,0x1,0x0,0x2,0x0,0x0},
567 {0x7,0x7,0x7,0x1,0x1,0x1,0x2,0x0,0x2,0x0}
569 {/* level 17 (Alien) by ts-x */
570 {0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1},
571 {0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2},
572 {0x1,0x0,0x0,0x0,0x1,0x1,0x0,0x0,0x0,0x1},
573 {0x2,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x2},
574 {0x1,0x0,0x1,0x2,0x2,0x2,0x2,0x1,0x0,0x1},
575 {0x2,0x0,0x0,0x1,0x2,0x2,0x1,0x0,0x0,0x2},
576 {0x2,0x1,0x0,0x0,0x1,0x1,0x0,0x0,0x1,0x2},
577 {0x2,0x2,0x1,0x0,0x1,0x1,0x0,0x1,0x2,0x2}
579 {/* level 18 (Tetris) by ts-x */
580 {0x0,0x2,0x0,0x0,0x3,0x4,0x0,0x2,0x2,0x0},
581 {0x0,0x2,0x7,0x0,0x3,0x4,0x0,0x2,0x2,0x0},
582 {0x2,0x2,0x7,0x0,0x3,0x4,0x0,0x6,0x2,0x2},
583 {0x2,0x2,0x7,0x7,0x3,0x4,0x0,0x6,0x2,0x2},
584 {0x2,0x1,0x7,0x7,0x3,0x4,0x4,0x6,0x5,0x5},
585 {0x2,0x1,0x0,0x7,0x3,0x4,0x4,0x6,0x5,0x5},
586 {0x1,0x1,0x1,0x7,0x3,0x0,0x6,0x6,0x5,0x5},
587 {0x1,0x1,0x1,0x0,0x3,0x0,0x6,0x6,0x5,0x5}
589 { /* level 19 (Stalactites) by ts-x */
590 {0x5,0x2,0x6,0x3,0x4,0x7,0x5,0x3,0x1,0x2},
591 {0x5,0x2,0x6,0x3,0x4,0x7,0x5,0x3,0x1,0x2},
592 {0x5,0x0,0x6,0x3,0x4,0x7,0x5,0x0,0x1,0x2},
593 {0x5,0x2,0x6,0x3,0x4,0x0,0x5,0x3,0x1,0x2},
594 {0x5,0x0,0x6,0x0,0x4,0x7,0x5,0x0,0x1,0x0},
595 {0x5,0x0,0x0,0x3,0x4,0x0,0x0,0x0,0x1,0x2},
596 {0x0,0x0,0x6,0x0,0x0,0x0,0x5,0x0,0x0,0x0},
597 {0x5,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x1,0x0}
599 { /* level 20 (Maze) by ts-x */
600 {0x1,0x1,0x21,0x1,0x1,0x1,0x1,0x1,0x1,0x21},
601 {0x1,0x0,0x0,0x3,0x0,0x0,0x3,0x1,0x31,0x1},
602 {0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x31,0x0,0x1},
603 {0x21,0x0,0x21,0x3,0x0,0x3,0x0,0x3,0x0,0x2},
604 {0x1,0x0,0x1,0x21,0x0,0x12,0x0,0x0,0x0,0x0},
605 {0x31,0x0,0x1,0x0,0x0,0x1,0x0,0x0,0x3,0x0},
606 {0x1,0x0,0x1,0x0,0x1,0x1,0x31,0x1,0x1,0x2},
607 {0x22,0x0,0x2,0x1,0x1,0x1,0x1,0x1,0x1,0x21}
609 { /* level 21 (Dentist) by ts-x */
610 {0x0,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x0},
611 {0x2,0x2,0x0,0x6,0x0,0x6,0x0,0x6,0x2,0x2},
612 {0x2,0x6,0x0,0x6,0x0,0x6,0x0,0x6,0x0,0x2},
613 {0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x6,0x0,0x2},
614 {0x2,0x0,0x6,0x0,0x6,0x0,0x0,0x0,0x0,0x2},
615 {0x2,0x0,0x6,0x0,0x6,0x0,0x6,0x0,0x6,0x2},
616 {0x2,0x2,0x6,0x0,0x6,0x0,0x6,0x0,0x2,0x2},
617 {0x0,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x0}
619 { /* level 22 (Spider) by ts-x */
620 {0x31,0x3,0x1,0x1,0x0,0x0,0x1,0x1,0x3,0x31},
621 {0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0},
622 {0x33,0x1,0x1,0x36,0x1,0x1,0x36,0x1,0x1,0x33},
623 {0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0},
624 {0x0,0x0,0x1,0x1,0x0,0x0,0x1,0x1,0x0,0x0},
625 {0x21,0x3,0x1,0x21,0x2,0x2,0x21,0x1,0x3,0x21},
626 {0x0,0x0,0x0,0x1,0x21,0x1,0x1,0x0,0x0,0x0},
627 {0x3,0x1,0x3,0x1,0x0,0x0,0x1,0x3,0x1,0x3}
629 { /* level 23 (Pool) by ts-x */
630 {0x0,0x7,0x7,0x7,0x0,0x7,0x7,0x7,0x7,0x0},
631 {0x0,0x0,0x5,0x0,0x2,0x0,0x0,0x0,0x2,0x0},
632 {0x7,0x3,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x7},
633 {0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x5,0x0,0x7},
634 {0x7,0x0,0x4,0x0,0x0,0x3,0x0,0x0,0x0,0x7},
635 {0x7,0x0,0x0,0x6,0x0,0x0,0x0,0x0,0x4,0x7},
636 {0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
637 {0x0,0x7,0x7,0x7,0x7,0x0,0x7,0x7,0x7,0x0}
639 { /* level 24 (Vorbis Fish) by ts-x */
640 {0x0,0x0,0x4,0x4,0x5,0x5,0x5,0x0,0x0,0x5},
641 {0x0,0x4,0x6,0x4,0x4,0x5,0x5,0x5,0x0,0x5},
642 {0x5,0x6,0x0,0x6,0x4,0x4,0x4,0x5,0x5,0x5},
643 {0x5,0x6,0x0,0x6,0x4,0x4,0x4,0x4,0x5,0x5},
644 {0x0,0x5,0x6,0x4,0x4,0x5,0x5,0x4,0x5,0x0},
645 {0x5,0x5,0x4,0x4,0x5,0x5,0x5,0x4,0x5,0x5},
646 {0x5,0x4,0x4,0x4,0x5,0x5,0x4,0x4,0x5,0x5},
647 {0x0,0x0,0x4,0x4,0x4,0x4,0x4,0x5,0x0,0x5}
649 {/* level 25 (Rainbow) by ts-x */
650 {0x0,0x4,0x1,0x0,0x0,0x0,0x0,0x1,0x4,0x0},
651 {0x24,0x1,0x3,0x1,0x0,0x0,0x21,0x3,0x1,0x24},
652 {0x1,0x23,0x5,0x3,0x1,0x21,0x3,0x5,0x3,0x21},
653 {0x3,0x5,0x6,0x5,0x3,0x3,0x5,0x6,0x5,0x3},
654 {0x5,0x6,0x7,0x6,0x5,0x5,0x6,0x7,0x6,0x5},
655 {0x6,0x7,0x2,0x27,0x6,0x6,0x27,0x2,0x7,0x6},
656 {0x7,0x2,0x0,0x2,0x27,0x27,0x2,0x0,0x2,0x7},
657 {0x32,0x0,0x0,0x0,0x2,0x2,0x0,0x0,0x0,0x32}
659 { /* level 26 (Bowtie) by ts-x */
660 {0x5,0x1,0x5,0x1,0x0,0x0,0x1,0x5,0x1,0x5},
661 {0x1,0x0,0x0,0x1,0x5,0x5,0x1,0x0,0x0,0x1},
662 {0x5,0x0,0x6,0x0,0x1,0x1,0x0,0x6,0x0,0x5},
663 {0x1,0x0,0x6,0x6,0x0,0x0,0x6,0x6,0x0,0x1},
664 {0x1,0x0,0x6,0x6,0x0,0x0,0x6,0x6,0x0,0x1},
665 {0x5,0x0,0x6,0x0,0x1,0x1,0x0,0x6,0x0,0x5},
666 {0x1,0x0,0x0,0x1,0x5,0x5,0x1,0x0,0x0,0x1},
667 {0x5,0x1,0x5,0x1,0x0,0x0,0x1,0x5,0x1,0x5}
669 { /* level 27 (Frog) by ts-x */
670 {0x0,0x5,0x25,0x0,0x0,0x0,0x0,0x25,0x5,0x0},
671 {0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5},
672 {0x25,0x0,0x0,0x5,0x6,0x6,0x5,0x0,0x0,0x25},
673 {0x5,0x0,0x3,0x0,0x6,0x6,0x0,0x3,0x0,0x5},
674 {0x5,0x0,0x31,0x0,0x6,0x6,0x0,0x31,0x0,0x5},
675 {0x5,0x0,0x0,0x5,0x6,0x6,0x5,0x0,0x0,0x5},
676 {0x5,0x5,0x5,0x35,0x0,0x0,0x35,0x5,0x5,0x5},
677 {0x0,0x25,0x5,0x0,0x4,0x4,0x0,0x5,0x25,0x0}
679 { /* level 28 (DigDug) by ts-x */
680 {0x35,0x5,0x5,0x25,0x0,0x25,0x25,0x5,0x5,0x35},
681 {0x6,0x0,0x0,0x6,0x0,0x6,0x6,0x0,0x0,0x6},
682 {0x7,0x0,0x37,0x37,0x0,0x37,0x37,0x7,0x0,0x7},
683 {0x7,0x0,0x7,0x0,0x0,0x0,0x7,0x7,0x7,0x7},
684 {0x4,0x4,0x4,0x24,0x0,0x24,0x4,0x0,0x0,0x4},
685 {0x4,0x4,0x0,0x0,0x0,0x4,0x4,0x0,0x4,0x4},
686 {0x24,0x24,0x4,0x4,0x4,0x4,0x0,0x0,0x24,0x4},
687 {0x1,0x1,0x1,0x1,0x1,0x1,0x21,0x21,0x1,0x1}
689 { /* TheEnd */
690 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
691 {0x22,0x22,0x26,0x0,0x0,0x26,0x24,0x24,0x0,0x0},
692 {0x22,0x0,0x26,0x26,0x0,0x26,0x24,0x0,0x24,0x0},
693 {0x22,0x22,0x26,0x26,0x0,0x26,0x24,0x0,0x24,0x0},
694 {0x22,0x22,0x26,0x0,0x26,0x26,0x24,0x0,0x24,0x0},
695 {0x22,0x0,0x26,0x0,0x26,0x26,0x24,0x0,0x24,0x0},
696 {0x22,0x22,0x26,0x0,0x0,0x26,0x24,0x24,0x0,0x0},
697 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}
701 #define MAX_BALLS 10
702 int pad_pos_x;
703 int x[MAX_BALLS],y[MAX_BALLS];
704 int life;
705 int start_game,con_game;
706 int pad_type;
707 int score=0,vscore=0;
708 bool flip_sides=false;
709 int cur_level=0;
710 int brick_on_board=0;
711 int used_balls=1;
713 typedef struct cube {
714 int powertop;
715 int power;
716 char poweruse;
717 char used;
718 int color;
719 int hits;
720 int hiteffect;
721 } cube;
722 cube brick[80];
724 typedef struct balls {
725 int pos_x;
726 int pos_y;
727 int y;
728 int tempy;
729 int x;
730 int tempx;
731 bool glue;
732 } balls;
734 balls ball[MAX_BALLS];
736 typedef struct sfire {
737 int top;
738 int left;
739 } sfire;
740 sfire fire[30];
743 int highscore;
744 #define MAX_POINTS 200000 /* i dont think it needs to be more */
745 static struct configdata config[] =
747 {TYPE_INT, 0, MAX_POINTS, &highscore, "highscore", NULL, NULL}
750 void int_game(int new_game)
752 int i,j;
754 pad_pos_x=LCD_WIDTH/2-PAD_WIDTH/2;
756 for(i=0;i<MAX_BALLS;i++) {
757 ball[i].x=0;
758 ball[i].y=0;
759 ball[i].tempy=0;
760 ball[i].tempx=0;
761 ball[i].pos_y=PAD_POS_Y-BALL;
762 ball[i].pos_x=pad_pos_x+(PAD_WIDTH/2)-2;
763 ball[i].glue=false;
766 used_balls=1;
767 start_game =1;
768 con_game =0;
769 pad_type=0;
771 flip_sides=false;
773 if (new_game==1)
774 brick_on_board=0;
776 for(i=0;i<=7;i++) {
777 for(j=0;j<=9;j++) {
778 brick[i*10+j].poweruse=(levels[cur_level][i][j]==0?0:1);
779 if (i*10+j<=30)
780 fire[i*10+j].top=-8;
781 if (new_game==1) {
782 brick[i*10+j].power=rb->rand()%25;
783 /* +8 make the game with less powerups */
785 brick[i*10+j].hits=levels[cur_level][i][j]>=10?
786 levels[cur_level][i][j]/16-1:0;
787 brick[i*10+j].hiteffect=0;
788 brick[i*10+j].powertop=TOPMARGIN+i*BRICK_HEIGHT+BRICK_HEIGHT;
789 brick[i*10+j].used=(levels[cur_level][i][j]==0?0:1);
790 brick[i*10+j].color=(levels[cur_level][i][j]>=10?
791 levels[cur_level][i][j]%16:
792 levels[cur_level][i][j])-1;
793 if (levels[cur_level][i][j]!=0)
794 brick_on_board++;
800 int sw,i,w;
802 /* sleep timer counting the score */
803 void sleep (int secs)
805 bool done=false;
806 char s[20];
807 int count=0;
809 while (!done) {
811 if (vscore<score) {
812 vscore++;
813 rb->snprintf(s, sizeof(s), "%d", vscore);
814 rb->lcd_getstringsize(s, &sw, &w);
815 #if (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
816 rb->lcd_putsxy(LCD_WIDTH/2-sw/2, 0, s);
817 #else
818 rb->lcd_putsxy(LCD_WIDTH/2-sw/2, 2, s);
819 #endif
820 rb->lcd_update_rect(0,0,LCD_WIDTH,w+2);
821 } else {
822 if (count==0)
823 count=*rb->current_tick+HZ*secs;
824 if (*rb->current_tick>=count)
825 done=true;
827 rb->yield();
832 #define HIGH_SCORE "brickmania.score"
833 #define MENU_LENGTH 4
834 int game_menu(int when)
836 int button,cur=0;
837 char str[10];
838 rb->lcd_clear_display();
839 #if (LCD_WIDTH != 112) && (LCD_HEIGHT != 64)
840 rb->lcd_bitmap(brickmania_menu_bg, 0, 0, MENU_BGWIDTH, MENU_BGHEIGHT);
841 #endif
842 while (true) {
843 for(i=0;i<MENU_LENGTH;i++) {
844 #ifdef HAVE_LCD_COLOR
845 if (cur==0)
846 rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0,
847 MENU_ITEMHEIGHT * BM_SEL_START, MENU_ITEMWIDTH,
848 MENU_ITEMXOFS, BMPYOFS_start, MENU_ITEMWIDTH,
849 MENU_ITEMHEIGHT);
850 else
851 rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0,
852 MENU_ITEMHEIGHT * BM_START, MENU_ITEMWIDTH,
853 MENU_ITEMXOFS, BMPYOFS_start, MENU_ITEMWIDTH,
854 MENU_ITEMHEIGHT);
856 if (when==1) {
857 if (cur==1)
858 rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0,
859 MENU_ITEMHEIGHT * BM_SEL_RESUME, MENU_ITEMWIDTH,
860 MENU_ITEMXOFS, BMPYOFS_resume, MENU_ITEMWIDTH,
861 MENU_ITEMHEIGHT);
862 else
863 rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0,
864 MENU_ITEMHEIGHT * BM_RESUME, MENU_ITEMWIDTH,
865 MENU_ITEMXOFS, BMPYOFS_resume, MENU_ITEMWIDTH,
866 MENU_ITEMHEIGHT);
868 } else {
869 rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0,
870 MENU_ITEMHEIGHT * BM_NO_RESUME, MENU_ITEMWIDTH,
871 MENU_ITEMXOFS, BMPYOFS_resume, MENU_ITEMWIDTH,
872 MENU_ITEMHEIGHT);
876 if (cur==2)
877 rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0,
878 MENU_ITEMHEIGHT * BM_SEL_HELP, MENU_ITEMWIDTH,
879 MENU_ITEMXOFS, BMPYOFS_help, MENU_ITEMWIDTH,
880 MENU_ITEMHEIGHT);
881 else
882 rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0,
883 MENU_ITEMHEIGHT * BM_HELP, MENU_ITEMWIDTH,
884 MENU_ITEMXOFS, BMPYOFS_help, MENU_ITEMWIDTH,
885 MENU_ITEMHEIGHT);
887 if (cur==3)
888 rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0,
889 MENU_ITEMHEIGHT * BM_SEL_QUIT, MENU_ITEMWIDTH,
890 MENU_ITEMXOFS, BMPYOFS_quit, MENU_ITEMWIDTH,
891 MENU_ITEMHEIGHT);
892 else
893 rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0,
894 MENU_ITEMHEIGHT * BM_QUIT, MENU_ITEMWIDTH,
895 MENU_ITEMXOFS, BMPYOFS_quit, MENU_ITEMWIDTH,
896 MENU_ITEMHEIGHT);
897 #else
898 if (cur==0)
899 rb->lcd_bitmap_part(brickmania_menu_items, 0,
900 MENU_ITEMHEIGHT * BM_SEL_START, MENU_ITEMWIDTH,
901 MENU_ITEMXOFS, BMPYOFS_start, MENU_ITEMWIDTH,
902 MENU_ITEMHEIGHT);
903 else
904 rb->lcd_bitmap_part(brickmania_menu_items, 0,
905 MENU_ITEMHEIGHT * BM_START, MENU_ITEMWIDTH,
906 MENU_ITEMXOFS, BMPYOFS_start, MENU_ITEMWIDTH,
907 MENU_ITEMHEIGHT);
909 if (when==1) {
910 if (cur==1)
911 rb->lcd_bitmap_part(brickmania_menu_items, 0,
912 MENU_ITEMHEIGHT * BM_SEL_RESUME, MENU_ITEMWIDTH,
913 MENU_ITEMXOFS, BMPYOFS_resume, MENU_ITEMWIDTH,
914 MENU_ITEMHEIGHT);
915 else
916 rb->lcd_bitmap_part(brickmania_menu_items, 0,
917 MENU_ITEMHEIGHT * BM_RESUME, MENU_ITEMWIDTH,
918 MENU_ITEMXOFS, BMPYOFS_resume, MENU_ITEMWIDTH,
919 MENU_ITEMHEIGHT);
921 } else {
922 rb->lcd_bitmap_part(brickmania_menu_items, 0,
923 MENU_ITEMHEIGHT * BM_NO_RESUME, MENU_ITEMWIDTH,
924 MENU_ITEMXOFS, BMPYOFS_resume, MENU_ITEMWIDTH,
925 MENU_ITEMHEIGHT);
929 if (cur==2)
930 rb->lcd_bitmap_part(brickmania_menu_items, 0,
931 MENU_ITEMHEIGHT * BM_SEL_HELP, MENU_ITEMWIDTH,
932 MENU_ITEMXOFS, BMPYOFS_help, MENU_ITEMWIDTH,
933 MENU_ITEMHEIGHT);
934 else
935 rb->lcd_bitmap_part(brickmania_menu_items, 0,
936 MENU_ITEMHEIGHT * BM_HELP, MENU_ITEMWIDTH,
937 MENU_ITEMXOFS, BMPYOFS_help, MENU_ITEMWIDTH,
938 MENU_ITEMHEIGHT);
940 if (cur==3)
941 rb->lcd_bitmap_part(brickmania_menu_items, 0,
942 MENU_ITEMHEIGHT * BM_SEL_QUIT, MENU_ITEMWIDTH,
943 MENU_ITEMXOFS, BMPYOFS_quit, MENU_ITEMWIDTH,
944 MENU_ITEMHEIGHT);
945 else
946 rb->lcd_bitmap_part(brickmania_menu_items, 0,
947 MENU_ITEMHEIGHT * BM_QUIT, MENU_ITEMWIDTH,
948 MENU_ITEMXOFS, BMPYOFS_quit, MENU_ITEMWIDTH,
949 MENU_ITEMHEIGHT);
950 #endif
952 rb->lcd_set_drawmode(DRMODE_FG);
953 /* high score */
954 #ifdef HAVE_LCD_COLOR
955 rb->lcd_set_background(LCD_RGBPACK(0,0,140));
956 rb->lcd_set_foreground(LCD_WHITE);
957 #endif
958 rb->lcd_putsxy(HIGHSCORE_XPOS, HIGHSCORE_YPOS, "High Score");
959 rb->snprintf(str, sizeof(str), "%d", highscore);
960 rb->lcd_getstringsize("High Score", &sw, NULL);
961 rb->lcd_getstringsize(str, &w, NULL);
962 rb->lcd_putsxy(HIGHSCORE_XPOS+sw/2-w/2, HIGHSCORE_YPOS+9, str);
963 rb->lcd_set_drawmode(DRMODE_SOLID);
965 rb->lcd_update();
967 button = rb->button_get(true);
968 switch(button) {
969 case UP:
970 case UP | BUTTON_REPEAT:
971 if (cur==0)
972 cur = MENU_LENGTH-1;
973 else
974 cur--;
975 if (when==0 && cur==1) {
976 cur = 0;
978 break;
980 case DOWN:
981 case DOWN | BUTTON_REPEAT:
982 if (cur==MENU_LENGTH-1)
983 cur = 0;
984 else
985 cur++;
986 if (when==0 && cur==1) {
987 cur=2;
989 break;
991 case RIGHT:
992 case SELECT:
993 if (cur==0) {
994 score=0;
995 vscore=0;
996 return 0;
997 } else if (cur==1 && when==1) {
998 return 1;
999 } else if (cur==2) {
1000 return 2;
1001 } else if (cur==3) {
1002 return 3;
1004 break;
1005 #ifdef RC_QUIT
1006 case RC_QUIT:
1007 #endif
1008 case QUIT:
1009 return 3;
1010 break;
1012 default:
1013 if(rb->default_event_handler(button) == SYS_USB_CONNECTED)
1014 return 3;
1015 break;
1020 int help(int when)
1022 int w,h;
1023 int button;
1024 int xoffset=0;
1025 int yoffset=0;
1026 /* set the maximum x and y in the helpscreen
1027 dont forget to update, if you change text */
1028 int maxY=180;
1029 int maxX=215;
1031 while(true) {
1032 #ifdef HAVE_LCD_COLOR
1033 rb->lcd_set_background(LCD_BLACK);
1034 rb->lcd_clear_display();
1035 rb->lcd_set_background(LCD_BLACK);
1036 rb->lcd_set_foreground(LCD_WHITE);
1037 #else
1038 rb->lcd_clear_display();
1039 #endif
1041 rb->lcd_getstringsize("BrickMania", &w, &h);
1042 rb->lcd_putsxy(LCD_WIDTH/2-w/2+xoffset, 1+yoffset, "BrickMania");
1044 #ifdef HAVE_LCD_COLOR
1045 rb->lcd_set_foreground(LCD_RGBPACK(245,0,0));
1046 rb->lcd_putsxy(1+xoffset, 1*(h+2)+yoffset,"Aim");
1047 rb->lcd_set_foreground(LCD_WHITE);
1048 #else
1049 rb->lcd_putsxy(1+xoffset, 1*(h+2)+yoffset,"Aim");
1050 #endif
1051 rb->lcd_putsxy(1+xoffset, 2*(h+2)+yoffset,
1052 "destroy all the bricks by bouncing");
1053 rb->lcd_putsxy(1+xoffset, 3*(h+2)+yoffset,
1054 "the ball of them using the paddle.");
1055 #ifdef HAVE_LCD_COLOR
1056 rb->lcd_set_foreground(LCD_RGBPACK(245,0,0));
1057 rb->lcd_putsxy(1+xoffset, 5*(h+2)+yoffset,"Controls");
1058 rb->lcd_set_foreground(LCD_WHITE);
1059 #else
1060 rb->lcd_putsxy(1+xoffset, 5*(h+2)+yoffset,"Controls");
1061 #endif
1062 rb->lcd_putsxy(1+xoffset, 6*(h+2)+yoffset,"< & > Move the paddle");
1063 #if CONFIG_KEYPAD == ONDIO_PAD
1064 rb->lcd_putsxy(1+xoffset, 7*(h+2)+yoffset,
1065 "MENU Releases the ball/Fire!");
1066 #elif CONFIG_KEYPAD == RECORDER_PAD
1067 rb->lcd_putsxy(1+xoffset, 7*(h+2)+yoffset,
1068 "PLAY Releases the ball/Fire!");
1069 #elif CONFIG_KEYPAD == IRIVER_H300_PAD
1070 rb->lcd_putsxy(1+xoffset, 7*(h+2)+yoffset,
1071 "NAVI Releases the ball/Fire!");
1072 #else
1073 rb->lcd_putsxy(1+xoffset, 7*(h+2)+yoffset,
1074 "SELECT Releases the ball/Fire!");
1075 #endif
1076 rb->lcd_putsxy(1+xoffset, 8*(h+2)+yoffset, "STOP Opens menu/Quit");
1077 #ifdef HAVE_LCD_COLOR
1078 rb->lcd_set_foreground(LCD_RGBPACK(245,0,0));
1079 rb->lcd_putsxy(1+xoffset, 10*(h+2)+yoffset, "Specials");
1080 rb->lcd_set_foreground(LCD_WHITE);
1081 #else
1082 rb->lcd_putsxy(1+xoffset, 10*(h+2)+yoffset, "Specials");
1083 #endif
1084 rb->lcd_putsxy(1+xoffset, 11*(h+2)+yoffset,
1085 "N Normal:returns paddle to normal");
1086 rb->lcd_putsxy(1+xoffset, 12*(h+2)+yoffset, "D DIE!:loses a life");
1087 rb->lcd_putsxy(1+xoffset, 13*(h+2)+yoffset,
1088 "L Life:gains a life/power up");
1089 rb->lcd_putsxy(1+xoffset, 14*(h+2)+yoffset,
1090 "F Fire:allows you to shoot bricks");
1091 rb->lcd_putsxy(1+xoffset, 15*(h+2)+yoffset,
1092 "G Glue:ball sticks to paddle");
1093 rb->lcd_putsxy(1+xoffset, 16*(h+2)+yoffset,
1094 "B Ball:generates another ball");
1095 rb->lcd_putsxy(1+xoffset, 17*(h+2)+yoffset,
1096 "FL Flip:flips left / right movement");
1097 rb->lcd_update();
1099 button=rb->button_get(true);
1100 switch (button) {
1101 #ifdef RC_QUIT
1102 case RC_QUIT:
1103 #endif
1104 case QUIT:
1105 switch (game_menu(when)) {
1106 case 0:
1107 cur_level=0;
1108 life=2;
1109 int_game(1);
1110 break;
1111 case 1:
1112 con_game=1;
1113 break;
1114 case 2:
1115 if (help(when)==1)
1116 return 1;
1117 break;
1118 case 3:
1119 return 1;
1120 break;
1122 return 0;
1123 break;
1124 case LEFT:
1125 case LEFT | BUTTON_REPEAT:
1126 #ifdef ALTLEFT
1127 case ALTLEFT:
1128 case ALTLEFT | BUTTON_REPEAT:
1129 #endif
1130 if( xoffset<0)
1131 xoffset+=2;
1132 break;
1133 case RIGHT:
1134 case RIGHT | BUTTON_REPEAT:
1135 #ifdef ALTRIGHT
1136 case ALTRIGHT:
1137 case ALTRIGHT | BUTTON_REPEAT:
1138 #endif
1139 if(xoffset+maxX > LCD_WIDTH)
1140 xoffset-=2;
1141 break;
1142 case UP:
1143 case UP | BUTTON_REPEAT:
1144 if(yoffset <0)
1145 yoffset+=2;
1146 break;
1147 case DOWN:
1148 case DOWN | BUTTON_REPEAT:
1149 if(yoffset+maxY > LCD_HEIGHT)
1150 yoffset-=2;
1151 break;
1153 default:
1154 if(rb->default_event_handler(button) == SYS_USB_CONNECTED)
1155 return 1;
1156 break;
1159 return 0;
1162 int pad_check(int ballxc, int mode, int pon ,int ballnum)
1164 /* pon: positive(1) or negative(0) */
1166 if (mode==0) {
1167 if (pon == 0)
1168 return -ballxc;
1169 else
1170 return ballxc;
1171 } else {
1172 if (ball[ballnum].x > 0)
1173 return ballxc;
1174 else
1175 return ballxc*-1;
1179 int fire_space(void)
1181 int t;
1182 for(t=0;t<=30;t++)
1183 if (fire[t].top+7 < 0)
1184 return t;
1186 return 0;
1189 int game_loop(void)
1191 int j,i,k,bricky,brickx;
1192 char s[30];
1193 int sec_count=0,num_count=10;
1194 int end;
1196 rb->srand( *rb->current_tick );
1198 configfile_init(rb);
1199 configfile_load(HIGH_SCORE,config,1,0);
1201 switch(game_menu(0)) {
1202 case 0:
1203 cur_level = 0;
1204 life = 2;
1205 int_game(1);
1206 break;
1207 case 1:
1208 con_game = 1;
1209 break;
1210 case 2:
1211 if (help(0) == 1) return 1;
1212 break;
1213 case 3:
1214 return 1;
1215 break;
1218 while(true) {
1219 /* Convert CYCLETIME (in ms) to HZ */
1220 end = *rb->current_tick + (CYCLETIME * HZ) / 1000;
1222 if (life >= 0) {
1223 #ifdef HAVE_LCD_COLOR
1224 rb->lcd_set_background(LCD_BLACK);
1225 rb->lcd_set_drawmode(DRMODE_SOLID);
1226 rb->lcd_clear_display();
1227 rb->lcd_set_background(LCD_BLACK);
1228 #if LCD_HEIGHT > GAMESCREEN_HEIGHT
1229 rb->lcd_set_foreground(rb->global_settings->bg_color);
1230 rb->lcd_fillrect(0, GAMESCREEN_HEIGHT, LCD_WIDTH,
1231 LCD_HEIGHT - GAMESCREEN_HEIGHT);
1232 #endif
1233 rb->lcd_set_foreground(LCD_WHITE);
1234 #else
1235 rb->lcd_clear_display();
1236 #endif
1238 if (flip_sides) {
1239 if (*rb->current_tick>=sec_count) {
1240 sec_count=*rb->current_tick+HZ;
1241 if (num_count!=0)
1242 num_count--;
1243 else
1244 flip_sides=false;
1246 rb->snprintf(s, sizeof(s), "%d", num_count);
1247 rb->lcd_getstringsize(s, &sw, NULL);
1248 rb->lcd_putsxy(LCD_WIDTH/2-2, STRINGPOS_FLIP, s);
1251 /* write life num */
1252 #if (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
1253 rb->snprintf(s, sizeof(s), "L:%d", life);
1254 rb->lcd_putsxy(0, 0, s);
1255 #else
1256 rb->snprintf(s, sizeof(s), "Life: %d", life);
1257 rb->lcd_putsxy(2, 2, s);
1258 #endif
1260 #if (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
1261 rb->snprintf(s, sizeof(s), "L%d", cur_level+1);
1262 rb->lcd_getstringsize(s, &sw, NULL);
1263 rb->lcd_putsxy(LCD_WIDTH-sw, 0, s);
1264 #else
1265 rb->snprintf(s, sizeof(s), "Level %d", cur_level+1);
1266 rb->lcd_getstringsize(s, &sw, NULL);
1267 rb->lcd_putsxy(LCD_WIDTH-sw-2, 2, s);
1268 #endif
1270 if (vscore<score) vscore++;
1271 rb->snprintf(s, sizeof(s), "%d", vscore);
1272 rb->lcd_getstringsize(s, &sw, NULL);
1273 #if (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
1274 rb->lcd_putsxy(LCD_WIDTH/2-sw/2, 0, s);
1275 #else
1276 rb->lcd_putsxy(LCD_WIDTH/2-sw/2, 2, s);
1277 #endif
1279 /* continue game */
1280 if (con_game== 1 && start_game!=1) {
1281 #if CONFIG_KEYPAD == ONDIO_PAD
1282 rb->snprintf(s, sizeof(s), "MENU To Continue");
1283 #elif CONFIG_KEYPAD == IRIVER_H300_PAD
1284 rb->snprintf(s, sizeof(s), "Press NAVI To Continue");
1285 #else
1286 rb->snprintf(s, sizeof(s), "Press SELECT To Continue");
1287 #endif
1288 rb->lcd_getstringsize(s, &sw, NULL);
1289 rb->lcd_putsxy(LCD_WIDTH/2-sw/2, STRINGPOS_NAVI, s);
1291 sec_count=*rb->current_tick+HZ;
1294 /* draw the ball */
1295 for(i=0;i<used_balls;i++)
1296 rb->lcd_bitmap(brickmania_ball,ball[i].pos_x, ball[i].pos_y,
1297 BALL, BALL);
1299 if (brick_on_board==0)
1300 brick_on_board--;
1302 /* if the pad is fire */
1303 for(i=0;i<=30;i++) {
1304 if (fire[i].top+7>0) {
1305 if (con_game!=1)
1306 fire[i].top-=4;
1307 rb->lcd_vline(fire[i].left, fire[i].top, fire[i].top+7);
1311 /* the bricks */
1312 for (i=0;i<=7;i++) {
1313 for (j=0;j<=9;j++) {
1314 if (brick[i*10+j].power<7) {
1315 if (brick[i*10+j].poweruse==2) {
1316 if (con_game!=1)
1317 brick[i*10+j].powertop+=2;
1318 rb->lcd_bitmap_part(brickmania_powerups,0,
1319 POWERUP_HEIGHT*brick[i*10+j
1320 ].power,
1321 POWERUP_WIDTH,
1322 LEFTMARGIN+j*BRICK_WIDTH+
1323 (BRICK_WIDTH/2-
1324 POWERUP_WIDTH/2),
1325 brick[i*10+j].powertop,
1326 POWERUP_WIDTH,
1327 POWERUP_HEIGHT);
1331 if ((pad_pos_x<LEFTMARGIN+j*BRICK_WIDTH+5 &&
1332 pad_pos_x+PAD_WIDTH>LEFTMARGIN+j*BRICK_WIDTH+5) &&
1333 brick[i*10+j].powertop+6>=PAD_POS_Y &&
1334 brick[i*10+j].poweruse==2) {
1335 switch(brick[i*10+j].power) {
1336 case 0:
1337 life++;
1338 score+=50;
1339 break;
1340 case 1:
1341 life--;
1342 if (life>=0) {
1343 int_game(0);
1344 sleep(2);
1346 break;
1347 case 2:
1348 score+=34;
1349 pad_type=1;
1350 break;
1351 case 3:
1352 score+=47;
1353 pad_type=2;
1354 for(k=0;k<used_balls;k++)
1355 ball[k].glue=false;
1356 break;
1357 case 4:
1358 score+=23;
1359 pad_type=0;
1360 for(k=0;k<used_balls;k++)
1361 ball[k].glue=false;
1362 flip_sides=false;
1363 break;
1364 case 5:
1365 score+=23;
1366 sec_count=*rb->current_tick+HZ;
1367 num_count=10;
1368 flip_sides=!flip_sides;
1369 break;
1370 case 6:
1371 score+=23;
1372 used_balls++;
1373 ball[used_balls-1].x= rb->rand()%1 == 0 ?
1374 -1 : 1;
1375 ball[used_balls-1].y= -4;
1376 break;
1378 brick[i*10+j].poweruse=1;
1381 if (brick[i*10+j].powertop>PAD_POS_Y)
1382 brick[i*10+j].poweruse=1;
1384 brickx=LEFTMARGIN+j*BRICK_WIDTH;
1385 bricky=TOPMARGIN+i*BRICK_HEIGHT;
1386 if (pad_type==2) {
1387 for (k=0;k<=30;k++) {
1388 if (fire[k].top+7>0) {
1389 if (brick[i*10+j].used==1 &&
1390 (fire[k].left+1 >= brickx &&
1391 fire[k].left+1 <= brickx+BRICK_WIDTH) &&
1392 (bricky+BRICK_HEIGHT>fire[k].top)) {
1393 score+=13;
1394 fire[k].top=-16;
1395 if (brick[i*10+j].hits > 0) {
1396 brick[i*10+j].hits--;
1397 brick[i*10+j].hiteffect++;
1398 score+=3;
1400 else {
1401 brick[i*10+j].used=0;
1402 if (brick[i*10+j].power!=10)
1403 brick[i*10+j].poweruse=2;
1404 brick_on_board--;
1411 if (brick[i*10+j].used==1) {
1412 rb->lcd_bitmap_part(brickmania_bricks,0,
1413 BRICK_HEIGHT*brick[i*10+j].color,
1414 BRICK_WIDTH,
1415 LEFTMARGIN+j*BRICK_WIDTH,
1416 TOPMARGIN+i*BRICK_HEIGHT,
1417 BRICK_WIDTH, BRICK_HEIGHT);
1418 #ifdef HAVE_LCD_COLOR /* No transparent effect for greyscale lcds for now */
1419 if (brick[i*10+j].hiteffect>0)
1420 rb->lcd_bitmap_transparent_part(brickmania_break,
1422 BRICK_HEIGHT*brick[i*10+j].hiteffect,
1423 BRICK_WIDTH,
1424 LEFTMARGIN+j*BRICK_WIDTH,
1425 TOPMARGIN+i*BRICK_HEIGHT,
1426 BRICK_WIDTH,
1427 BRICK_HEIGHT);
1428 #endif
1431 for(k=0;k<used_balls;k++) {
1432 if (ball[k].pos_y <160) {
1433 if (brick[i*10+j].used==1) {
1434 if ((ball[k].pos_x+ball[k].x+HALFBALL >=
1435 brickx &&
1436 ball[k].pos_x+ball[k].x+HALFBALL <=
1437 brickx+BRICK_WIDTH) &&
1438 ((bricky-4<ball[k].pos_y+BALL &&
1439 bricky>ball[k].pos_y+BALL) ||
1440 (bricky+4>ball[k].pos_y+BALL+BALL &&
1441 bricky<ball[k].pos_y+BALL+BALL)) &&
1442 (ball[k].y >0)) {
1443 ball[k].tempy=bricky-ball[k].pos_y-BALL;
1445 else if ((ball[k].pos_x+ball[k].x+HALFBALL >=
1446 brickx &&
1447 ball[k].pos_x+ball[k].x+HALFBALL <=
1448 brickx+BRICK_WIDTH) &&
1449 ((bricky+BRICK_HEIGHT+4>ball[k].pos_y &&
1450 bricky+BRICK_HEIGHT<ball[k].pos_y) ||
1451 (bricky+BRICK_HEIGHT-4<ball[k].pos_y-BALL &&
1452 bricky+BRICK_HEIGHT>ball[k].pos_y-BALL)) &&
1453 (ball[k].y <0)) {
1454 ball[k].tempy=
1455 -(ball[k].pos_y-(bricky+BRICK_HEIGHT));
1458 if ((ball[k].pos_y+HALFBALL >=
1459 bricky &&
1460 ball[k].pos_y+HALFBALL <=
1461 bricky+BRICK_HEIGHT) &&
1462 ((brickx-4<ball[k].pos_x+BALL &&
1463 brickx>ball[k].pos_x+BALL) ||
1464 (brickx+4>ball[k].pos_x+BALL+BALL &&
1465 brickx<ball[k].pos_x+BALL+BALL)) &&
1466 (ball[k].x >0)) {
1467 ball[k].tempx=brickx-ball[k].pos_x-BALL;
1469 else if ((ball[k].pos_y+ball[k].y+HALFBALL >=
1470 bricky &&
1471 ball[k].pos_y+ball[k].y+HALFBALL <=
1472 bricky+BRICK_HEIGHT) &&
1473 ((brickx+BRICK_WIDTH+4>ball[k].pos_x &&
1474 brickx+BRICK_WIDTH<ball[k].pos_x) ||
1475 (brickx+BRICK_WIDTH-4<ball[k].pos_x-
1476 BALL &&
1477 brickx+BRICK_WIDTH>ball[k].pos_x-
1478 BALL)) && (ball[k].x <0)) {
1479 ball[k].tempx=
1480 -(ball[k].pos_x-(brickx+BRICK_WIDTH));
1483 if ((ball[k].pos_x+HALFBALL >= brickx &&
1484 ball[k].pos_x+HALFBALL <=
1485 brickx+BRICK_WIDTH) &&
1486 ((bricky+BRICK_HEIGHT==ball[k].pos_y) ||
1487 (bricky+BRICK_HEIGHT-6<=ball[k].pos_y &&
1488 bricky+BRICK_HEIGHT>ball[k].pos_y)) &&
1489 (ball[k].y <0)) { /* bottom line */
1490 if (brick[i*10+j].hits > 0) {
1491 brick[i*10+j].hits--;
1492 brick[i*10+j].hiteffect++;
1493 score+=2;
1495 else {
1496 brick[i*10+j].used=0;
1497 if (brick[i*10+j].power!=10)
1498 brick[i*10+j].poweruse=2;
1501 ball[k].y = ball[k].y*-1;
1503 else if ((ball[k].pos_x+HALFBALL >= brickx &&
1504 ball[k].pos_x+HALFBALL <=
1505 brickx+BRICK_WIDTH) &&
1506 ((bricky==ball[k].pos_y+BALL) ||
1507 (bricky+6>=ball[k].pos_y+BALL &&
1508 bricky<ball[k].pos_y+BALL)) &&
1509 (ball[k].y >0)) { /* top line */
1510 if (brick[i*10+j].hits > 0) {
1511 brick[i*10+j].hits--;
1512 brick[i*10+j].hiteffect++;
1513 score+=2;
1515 else {
1516 brick[i*10+j].used=0;
1517 if (brick[i*10+j].power!=10)
1518 brick[i*10+j].poweruse=2;
1521 ball[k].y = ball[k].y*-1;
1524 if ((ball[k].pos_y+HALFBALL >= bricky &&
1525 ball[k].pos_y+HALFBALL <=
1526 bricky+BRICK_HEIGHT) &&
1527 ((brickx==ball[k].pos_x+BALL) ||
1528 (brickx+6>=ball[k].pos_x+BALL &&
1529 brickx<ball[k].pos_x+BALL)) &&
1530 (ball[k].x > 0)) { /* left line */
1531 if (brick[i*10+j].hits > 0) {
1532 brick[i*10+j].hits--;
1533 brick[i*10+j].hiteffect++;
1534 score+=2;
1536 else {
1537 brick[i*10+j].used=0;
1538 if (brick[i*10+j].power!=10)
1539 brick[i*10+j].poweruse=2;
1541 ball[k].x = ball[k].x*-1;
1544 else if ((ball[k].pos_y+HALFBALL >= bricky &&
1545 ball[k].pos_y+HALFBALL <=
1546 bricky+BRICK_HEIGHT) &&
1547 ((brickx+BRICK_WIDTH==
1548 ball[k].pos_x) ||
1549 (brickx+BRICK_WIDTH-6<=
1550 ball[k].pos_x &&
1551 brickx+BRICK_WIDTH>
1552 ball[k].pos_x)) &&
1553 (ball[k].x < 0)) { /* Right line */
1554 if (brick[i*10+j].hits > 0) {
1555 brick[i*10+j].hits--;
1556 brick[i*10+j].hiteffect++;
1557 score+=2;
1559 else {
1560 brick[i*10+j].used=0;
1561 if (brick[i*10+j].power!=10)
1562 brick[i*10+j].poweruse=2;
1565 ball[k].x = ball[k].x*-1;
1568 if (brick[i*10+j].used==0) {
1569 brick_on_board--;
1570 score+=8;
1574 } /* for k */
1575 } /* for j */
1576 } /* for i */
1578 /* draw the pad */
1579 rb->lcd_bitmap_part(brickmania_pads,0,pad_type*PAD_HEIGHT,
1580 PAD_WIDTH,pad_pos_x, PAD_POS_Y, PAD_WIDTH,
1581 PAD_HEIGHT);
1583 for(k=0;k<used_balls;k++) {
1585 if ((ball[k].pos_x >= pad_pos_x &&
1586 ball[k].pos_x <= pad_pos_x+PAD_WIDTH) &&
1587 (PAD_POS_Y-4<ball[k].pos_y+BALL &&
1588 PAD_POS_Y>ball[k].pos_y+BALL) && (ball[k].y >0))
1589 ball[k].tempy=PAD_POS_Y-ball[k].pos_y-BALL;
1590 else if ((4>ball[k].pos_y && 0<ball[k].pos_y) &&
1591 (ball[k].y <0))
1592 ball[k].tempy=-ball[k].pos_y;
1593 if ((LCD_WIDTH-4<ball[k].pos_x+BALL &&
1594 LCD_WIDTH>ball[k].pos_x+BALL) && (ball[k].x >0))
1595 ball[k].tempx=LCD_WIDTH-ball[k].pos_x-BALL;
1596 else if ((4>ball[k].pos_x && 0<ball[k].pos_x) &&
1597 (ball[k].x <0))
1598 ball[k].tempx=-ball[k].pos_x;
1600 /* top line */
1601 if (ball[k].pos_y<= 0)
1602 ball[k].y = ball[k].y*-1;
1603 /* bottom line */
1604 else if (ball[k].pos_y+BALL >= GAMESCREEN_HEIGHT) {
1605 if (used_balls>1) {
1606 used_balls--;
1607 ball[k].pos_x = ball[used_balls].pos_x;
1608 ball[k].pos_y = ball[used_balls].pos_y;
1609 ball[k].y = ball[used_balls].y;
1610 ball[k].tempy = ball[used_balls].tempy;
1611 ball[k].x = ball[used_balls].x;
1612 ball[k].tempx = ball[used_balls].tempx;
1613 ball[k].glue = ball[used_balls].glue;
1615 ball[used_balls].x=0;
1616 ball[used_balls].y=0;
1617 ball[used_balls].tempy=0;
1618 ball[used_balls].tempx=0;
1619 ball[used_balls].pos_y=PAD_POS_Y-BALL;
1620 ball[used_balls].pos_x=pad_pos_x+(PAD_WIDTH/2)-2;
1622 k--;
1623 continue;
1624 } else {
1625 life--;
1626 if (life>=0) {
1627 int_game(0);
1628 sleep(2);
1633 /* left line ,right line */
1634 if ((ball[k].pos_x <= 0) ||
1635 (ball[k].pos_x+BALL >= LCD_WIDTH)) {
1636 ball[k].x = ball[k].x*-1;
1637 ball[k].pos_x = ball[k].pos_x <= 0 ? 0 : LCD_WIDTH-BALL;
1640 if ((ball[k].pos_y+BALL >= PAD_POS_Y &&
1641 (ball[k].pos_x >= pad_pos_x &&
1642 ball[k].pos_x <= pad_pos_x+PAD_WIDTH)) &&
1643 start_game != 1 && !ball[k].glue) {
1645 if ((ball[k].pos_x+HALFBALL >= pad_pos_x &&
1646 ball[k].pos_x+HALFBALL <=
1647 pad_pos_x+(PAD_WIDTH/2/4)) ||
1648 (ball[k].pos_x +HALFBALL>=
1649 pad_pos_x+(PAD_WIDTH-(PAD_WIDTH/2/4)) &&
1650 ball[k].pos_x+HALFBALL <= pad_pos_x+PAD_WIDTH)) {
1652 ball[k].y = -2;
1653 if (ball[k].pos_x != 0 &&
1654 ball[k].pos_x+BALL!=LCD_WIDTH)
1655 ball[k].x = pad_check(6,0,ball[k].pos_x+2<=
1656 pad_pos_x+(PAD_WIDTH/2)?
1657 0:1,k);
1660 else if ((ball[k].pos_x+HALFBALL >=
1661 pad_pos_x+(PAD_WIDTH/2/4) &&
1662 ball[k].pos_x+HALFBALL <=
1663 pad_pos_x+2*(PAD_WIDTH/2/4)) ||
1664 (ball[k].pos_x+HALFBALL >=
1665 pad_pos_x+(PAD_WIDTH-2*(PAD_WIDTH/2/4)) &&
1666 ball[k].pos_x+HALFBALL <=
1667 pad_pos_x+(PAD_WIDTH-(PAD_WIDTH/2/4)) )) {
1669 ball[k].y = -3;
1670 if (ball[k].pos_x != 0 &&
1671 ball[k].pos_x+BALL!=LCD_WIDTH)
1672 ball[k].x = pad_check(4,0,ball[k].pos_x+2<=
1673 pad_pos_x+(PAD_WIDTH/2)?
1674 0:1,k);
1677 else if ((ball[k].pos_x+HALFBALL >=
1678 pad_pos_x+2*(PAD_WIDTH/2/4) &&
1679 ball[k].pos_x+HALFBALL <=
1680 pad_pos_x+3*(PAD_WIDTH/2/4)) ||
1681 (ball[k].pos_x+2 >=
1682 pad_pos_x+(PAD_WIDTH-3*(PAD_WIDTH/2/4)) &&
1683 ball[k].pos_x+2 <=
1684 pad_pos_x+ ((PAD_WIDTH/2)-2*(PAD_WIDTH/2/4)) )) {
1686 ball[k].y = -4;
1687 if (ball[k].pos_x != 0 &&
1688 ball[k].pos_x+BALL!=LCD_WIDTH)
1689 ball[k].x = pad_check(3,0,ball[k].pos_x+2<=
1690 pad_pos_x+(PAD_WIDTH/2)?
1691 0:1,k);
1694 else if ((ball[k].pos_x+HALFBALL >=
1695 pad_pos_x+3*(PAD_WIDTH/2/4) &&
1696 ball[k].pos_x+HALFBALL <=
1697 pad_pos_x+4*(PAD_WIDTH/2/4)-2) ||
1698 (ball[k].pos_x+2 >= pad_pos_x+(PAD_WIDTH/2+2) &&
1699 ball[k].pos_x+2 <=
1700 pad_pos_x+(PAD_WIDTH-3*(PAD_WIDTH/2/4)) )) {
1702 ball[k].y = -4;
1703 if (ball[k].pos_x != 0 &&
1704 ball[k].pos_x+BALL!=LCD_WIDTH)
1705 ball[k].x = pad_check(2,1,0,k);
1708 else {
1709 ball[k].y = -4;
1713 if (!ball[k].glue) {
1714 ball[k].pos_x+=ball[k].tempx!=0?ball[k].tempx:ball[k].x;
1715 ball[k].pos_y+=ball[k].tempy!=0?ball[k].tempy:ball[k].y;
1717 ball[k].tempy=0;
1718 ball[k].tempx=0;
1721 if (ball[k].pos_y+5 >= PAD_POS_Y &&
1722 (pad_type==1 && !ball[k].glue) &&
1723 (ball[k].pos_x >= pad_pos_x &&
1724 ball[k].pos_x <= pad_pos_x+PAD_WIDTH)) {
1725 ball[k].y=0;
1726 ball[k].pos_y=PAD_POS_Y-BALL;
1727 ball[k].glue=true;
1729 } /* for k */
1731 rb->lcd_update();
1733 if (brick_on_board < 0) {
1734 if (cur_level+1<levels_num) {
1735 cur_level++;
1736 score+=100;
1737 int_game(1);
1738 sleep(2);
1740 else {
1741 rb->lcd_getstringsize("Congratulations!", &sw, NULL);
1742 rb->lcd_putsxy(LCD_WIDTH/2-sw/2, STRINGPOS_CONGRATS,
1743 "Congratulations!");
1744 #if (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
1745 rb->lcd_getstringsize("No more levels", &sw, NULL);
1746 rb->lcd_putsxy(LCD_WIDTH/2-sw/2, STRINGPOS_FINISH,
1747 "No more levels");
1748 #else
1749 rb->lcd_getstringsize("You have finished the game!",
1750 &sw, NULL);
1751 rb->lcd_putsxy(LCD_WIDTH/2-sw/2, STRINGPOS_FINISH,
1752 "You have finished the game!");
1753 #endif
1754 vscore=score;
1755 rb->lcd_update();
1756 if (score>highscore) {
1757 sleep(2);
1758 highscore=score;
1759 rb->splash(HZ*2, "New High Score");
1761 else {
1762 sleep(3);
1765 switch(game_menu(0)) {
1766 case 0:
1767 life=2;
1768 cur_level=0;
1769 int_game(1);
1770 break;
1771 case 1:
1772 con_game=1;
1773 break;
1774 case 2:
1775 if (help(0)==1) return 1;
1776 break;
1777 case 3:
1778 return 1;
1779 break;
1784 int move_button,button;
1785 int button_right,button_left;
1786 button=rb->button_get(false);
1788 #ifdef HAS_BUTTON_HOLD
1789 if (rb->button_hold())
1790 button = QUIT;
1791 #endif
1793 move_button=rb->button_status();
1794 #ifdef ALTRIGHT
1795 button_right=((move_button & RIGHT) || (move_button & ALTRIGHT));
1796 button_left=((move_button & LEFT) || (move_button & ALTLEFT));
1797 #else
1798 button_right=((move_button & RIGHT) || (SCROLL_FWD(button)));
1799 button_left=((move_button & LEFT) || (SCROLL_BACK(button)));
1800 #endif
1801 if ((con_game== 1 && start_game!=1) && (button_right || button_left))
1802 continue;
1803 if ((button_right && flip_sides==false) ||
1804 (button_left && flip_sides==true)) {
1805 if (pad_pos_x+8+PAD_WIDTH > LCD_WIDTH) {
1806 for(k=0;k<used_balls;k++)
1807 if (start_game==1 || ball[k].glue)
1808 ball[k].pos_x+=LCD_WIDTH-pad_pos_x-PAD_WIDTH;
1809 pad_pos_x+=LCD_WIDTH-pad_pos_x-PAD_WIDTH;
1811 else {
1812 for(k=0;k<used_balls;k++)
1813 if ((start_game==1 || ball[k].glue))
1814 ball[k].pos_x+=8;
1815 pad_pos_x+=8;
1818 else if ((button_left && flip_sides==false) ||
1819 (button_right && flip_sides==true)) {
1820 if (pad_pos_x-8 < 0) {
1821 for(k=0;k<used_balls;k++)
1822 if (start_game==1 || ball[k].glue)
1823 ball[k].pos_x-=pad_pos_x;
1824 pad_pos_x-=pad_pos_x;
1826 else {
1827 for(k=0;k<used_balls;k++)
1828 if (start_game==1 || ball[k].glue)
1829 ball[k].pos_x-=8;
1830 pad_pos_x-=8;
1835 switch(button) {
1836 case UP:
1837 case SELECT:
1838 if (start_game==1 && con_game!=1 && pad_type!=1) {
1839 for(k=0;k<used_balls;k++) {
1840 ball[k].y=-4;
1841 ball[k].x=pad_pos_x+(PAD_WIDTH/2)-2>=
1842 LCD_WIDTH/2?2:-2;
1844 start_game =0;
1846 else if (pad_type==1) {
1847 for(k=0;k<used_balls;k++) {
1848 if (ball[k].glue)
1849 ball[k].glue=false;
1850 else if (start_game==1) {
1851 ball[k].x = x[k];
1852 ball[k].y = y[k];
1856 if (start_game!=1 && con_game==1) {
1857 start_game =0;
1858 con_game=0;
1860 } else if (pad_type==2 && con_game!=1) {
1861 int tfire;
1862 tfire=fire_space();
1863 fire[tfire].top=PAD_POS_Y-7;
1864 fire[tfire].left=pad_pos_x+1;
1865 tfire=fire_space();
1866 fire[tfire].top=PAD_POS_Y-7;
1867 fire[tfire].left=pad_pos_x+PAD_WIDTH-1;
1868 } else if (con_game==1 && start_game!=1) {
1869 for(k=0;k<used_balls;k++) {
1870 ball[k].x=x[k];
1871 ball[k].y=y[k];
1873 con_game=0;
1875 break;
1876 #ifdef RC_QUIT
1877 case RC_QUIT:
1878 #endif
1879 case QUIT:
1880 switch(game_menu(1)) {
1881 case 0:
1882 life=2;
1883 cur_level=0;
1884 int_game(1);
1885 break;
1886 case 1:
1887 for(k=0;k<used_balls;k++)
1888 if (ball[k].x!=0 && ball[k].y !=0)
1889 con_game=1;
1890 break;
1891 case 2:
1892 if (help(1)==1)
1893 return 1;
1894 break;
1895 case 3:
1896 return 1;
1897 break;
1900 for(k=0;k<used_balls;k++) {
1901 if (ball[k].x!=0)
1902 x[k]=ball[k].x;
1903 ball[k].x=0;
1904 if (ball[k].y!=0)
1905 y[k]=ball[k].y;
1906 ball[k].y=0;
1909 break;
1911 default:
1912 if(rb->default_event_handler(button) == SYS_USB_CONNECTED)
1913 return 1;
1914 break;
1917 else {
1918 #ifdef HAVE_LCD_COLOR
1919 rb->lcd_bitmap_transparent(brickmania_gameover,
1920 (LCD_WIDTH - GAMEOVER_WIDTH)/2,
1921 (GAMESCREEN_HEIGHT - GAMEOVER_HEIGHT)/2,
1922 GAMEOVER_WIDTH,GAMEOVER_HEIGHT);
1923 #else /* greyscale and mono */
1924 rb->lcd_bitmap(brickmania_gameover,(LCD_WIDTH - GAMEOVER_WIDTH)/2,
1925 (GAMESCREEN_HEIGHT - GAMEOVER_HEIGHT)/2,
1926 GAMEOVER_WIDTH,GAMEOVER_HEIGHT);
1927 #endif
1928 rb->lcd_update();
1929 if (score>highscore) {
1930 sleep(2);
1931 highscore=score;
1932 rb->splash(HZ*2, "New High Score");
1933 } else {
1934 sleep(3);
1937 for(k=0;k<used_balls;k++) {
1938 ball[k].x=0;
1939 ball[k].y=0;
1942 switch(game_menu(0)) {
1943 case 0:
1944 cur_level=0;
1945 life=2;
1946 int_game(1);
1947 break;
1948 case 1:
1949 con_game=1;
1950 break;
1951 case 2:
1952 if (help(0)==1)
1953 return 1;
1954 break;
1955 case 3:
1956 return 1;
1957 break;
1960 if (end > *rb->current_tick)
1961 rb->sleep(end-*rb->current_tick);
1962 else
1963 rb->yield();
1967 /* this is the plugin entry point */
1968 enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
1970 (void)parameter;
1971 rb = api;
1973 rb->lcd_setfont(FONT_SYSFIXED);
1974 #if LCD_DEPTH > 1
1975 rb->lcd_set_backdrop(NULL);
1976 #endif
1977 /* Turn off backlight timeout */
1978 backlight_force_on(rb); /* backlight control in lib/helper.c */
1980 /* now go ahead and have fun! */
1981 while (game_loop()!=1);
1983 configfile_save(HIGH_SCORE,config,1,0);
1985 /* Restore user's original backlight setting */
1986 rb->lcd_setfont(FONT_UI);
1987 /* Turn on backlight timeout (revert to settings) */
1988 backlight_use_settings(rb); /* backlight control in lib/helper.c */
1990 return PLUGIN_OK;