E200: Restore the scroll wheel support in brickmania that got lost in the previous...
[Rockbox.git] / apps / plugins / brickmania.c
blob8a4e07c9d7f3554e78b868a9093f2a2fb9d38a96
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_UP
111 #define DOWN BUTTON_SCROLL_DOWN
113 #define SCROLL_FWD(x) ((x) & BUTTON_SCROLL_DOWN)
114 #define SCROLL_BACK(x) ((x) & BUTTON_SCROLL_UP)
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
139 #else
140 #error Unsupported keypad
141 #endif
143 #ifndef SCROLL_FWD /* targets without scroll wheel*/
144 #define SCROLL_FWD(x) (0)
145 #define SCROLL_BACK(x) (0)
146 #endif
149 static struct plugin_api* rb;
151 enum menu_items {
152 BM_START,
153 BM_SEL_START,
154 BM_RESUME,
155 BM_SEL_RESUME,
156 BM_NO_RESUME,
157 BM_HELP,
158 BM_SEL_HELP,
159 BM_QUIT,
160 BM_SEL_QUIT,
163 /* External bitmaps */
164 #if (LCD_WIDTH != 112) && (LCD_HEIGHT != 64)
165 extern const fb_data brickmania_menu_bg[];
166 extern const fb_data brickmania_gameover[];
167 #endif
168 extern const fb_data brickmania_menu_items[];
169 extern const fb_data brickmania_ball[];
170 #ifdef HAVE_LCD_COLOR
171 extern const fb_data brickmania_break[];
172 #endif
174 /* normal, glue, fire */
175 extern const fb_data brickmania_pads[];
177 /* +life, -life, glue, fire, normal */
178 extern const fb_data brickmania_powerups[];
180 /* purple, red, blue, pink, green, yellow orange */
181 extern const fb_data brickmania_bricks[];
183 #include "brickmania_pads.h"
184 #include "brickmania_bricks.h"
185 #include "brickmania_powerups.h"
186 #include "brickmania_ball.h"
187 #include "brickmania_menu_items.h"
188 #include "brickmania_gameover.h"
190 #define PAD_WIDTH BMPWIDTH_brickmania_pads
191 #define PAD_HEIGHT (BMPHEIGHT_brickmania_pads/3)
192 #define BRICK_HEIGHT (BMPHEIGHT_brickmania_bricks/7)
193 #define BRICK_WIDTH BMPWIDTH_brickmania_bricks
194 #define LEFTMARGIN ((LCD_WIDTH-10*BRICK_WIDTH)/2)
195 #define POWERUP_HEIGHT (BMPHEIGHT_brickmania_powerups/7)
196 #define POWERUP_WIDTH BMPWIDTH_brickmania_powerups
197 #define BALL BMPHEIGHT_brickmania_ball
198 #define HALFBALL ((BALL+1)/2)
199 #define MENU_ITEMXOFS ((LCD_WIDTH - BMPWIDTH_brickmania_menu_items)/2)
200 #define MENU_ITEMHEIGHT (BMPHEIGHT_brickmania_menu_items/9)
201 #define MENU_ITEMWIDTH BMPWIDTH_brickmania_menu_items
202 #define GAMEOVER_WIDTH BMPWIDTH_brickmania_gameover
203 #define GAMEOVER_HEIGHT BMPHEIGHT_brickmania_gameover
205 #if LCD_DEPTH > 1 /* currently no background bmp for mono screens */
206 #include "brickmania_menu_bg.h"
207 #define MENU_BGHEIGHT BMPHEIGHT_brickmania_menu_bg
208 #define MENU_BGWIDTH BMPWIDTH_brickmania_menu_bg
209 #endif
212 #if (LCD_WIDTH == 320) && (LCD_HEIGHT == 240)
214 /* The time (in ms) for one iteration through the game loop - decrease this
215 to speed up the game - note that current_tick is (currently) only accurate
216 to 10ms.
218 #define CYCLETIME 30
220 #define TOPMARGIN 30
222 #define BMPYOFS_start 110
223 #define HIGHSCORE_XPOS 57
224 #define HIGHSCORE_YPOS 88
226 #define STRINGPOS_FINISH 140
227 #define STRINGPOS_CONGRATS 157
228 #define STRINGPOS_NAVI 150
229 #define STRINGPOS_FLIP 150
231 #elif (LCD_WIDTH >= 220) && (LCD_HEIGHT >= 176)
233 /* The time (in ms) for one iteration through the game loop - decrease this
234 to speed up the game - note that current_tick is (currently) only accurate
235 to 10ms.
237 #define CYCLETIME 30
239 /* Offsets for LCDS > 220x176 */
241 #define GAMESCREEN_HEIGHT 176
242 #define TOPMARGIN 30
244 #define XOFS ((LCD_WIDTH-220)/BRICK_WIDTH/2)*BRICK_WIDTH
245 #define YOFS ((LCD_HEIGHT-176)/BRICK_HEIGHT/2)*BRICK_HEIGHT
247 #define BMPYOFS_start (78+YOFS)
248 #define HIGHSCORE_XPOS (17+XOFS)
249 #define HIGHSCORE_YPOS (56+YOFS)
251 #define STRINGPOS_FINISH 140
252 #define STRINGPOS_CONGRATS 157
253 #define STRINGPOS_NAVI 150
254 #define STRINGPOS_FLIP 150
256 #elif (LCD_WIDTH == 160) && (LCD_HEIGHT == 128)
257 /* The time (in ms) for one iteration through the game loop - decrease this
258 to speed up the game - note that current_tick is (currently) only accurate
259 to 10ms.
261 #define CYCLETIME 50
263 #define TOPMARGIN 21
265 #if LCD_DEPTH > 2
266 #define BMPYOFS_start 58
267 #else
268 #define BMPYOFS_start 66
269 #endif
270 #define HIGHSCORE_XPOS 10
271 #define HIGHSCORE_YPOS 38
273 #define STRINGPOS_FINISH 110
274 #define STRINGPOS_CONGRATS 100
275 #define STRINGPOS_NAVI 100
276 #define STRINGPOS_FLIP 100
278 #elif (LCD_WIDTH == 132) && (LCD_HEIGHT == 80)
280 /* The time (in ms) for one iteration through the game loop - decrease this
281 to speed up the game - note that current_tick is (currently) only accurate
282 to 10ms.
284 #define CYCLETIME 50
286 #define TOPMARGIN 10
288 #define BMPYOFS_start 30
289 #define HIGHSCORE_XPOS 68
290 #define HIGHSCORE_YPOS 8
292 #define STRINGPOS_FINISH 55
293 #define STRINGPOS_CONGRATS 45
294 #define STRINGPOS_NAVI 60
295 #define STRINGPOS_FLIP 60
297 #elif (LCD_WIDTH == 128) && (LCD_HEIGHT == 128)
299 /* The time (in ms) for one iteration through the game loop - decrease this
300 to speed up the game - note that current_tick is (currently) only accurate
301 to 10ms.
303 #define CYCLETIME 50
305 #define GAMESCREEN_HEIGHT 100
306 #define TOPMARGIN 15
308 #define BMPYOFS_start 70
309 #define HIGHSCORE_XPOS 8
310 #define HIGHSCORE_YPOS 36
312 #define STRINGPOS_FINISH 55
313 #define STRINGPOS_CONGRATS 45
314 #define STRINGPOS_NAVI 60
315 #define STRINGPOS_FLIP 60
317 /* iPod Mini */
318 #elif (LCD_WIDTH == 138) && (LCD_HEIGHT == 110)
319 /* The time (in ms) for one iteration through the game loop - decrease this
320 to speed up the game - note that current_tick is (currently) only accurate
321 to 10ms.
323 #define CYCLETIME 50
325 #define TOPMARGIN 10
327 #define BMPYOFS_start 51
328 #define HIGHSCORE_XPOS 73
329 #define HIGHSCORE_YPOS 25
331 #define STRINGPOS_FINISH 54
332 #define STRINGPOS_CONGRATS 44
333 #define STRINGPOS_NAVI 44
334 #define STRINGPOS_FLIP 44
337 #elif (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
338 /* The time (in ms) for one iteration through the game loop - decrease this
339 to speed up the game - note that current_tick is (currently) only accurate
340 to 10ms.
342 #define CYCLETIME 75
344 #define TOPMARGIN 10
346 #define BMPYOFS_start 22
347 #define HIGHSCORE_XPOS 0
348 #define HIGHSCORE_YPOS 0
350 #define STRINGPOS_FINISH 54
351 #define STRINGPOS_CONGRATS 44
352 #define STRINGPOS_NAVI 44
353 #define STRINGPOS_FLIP 44
355 /* nano and sansa */
356 #elif (LCD_WIDTH == 176) && (LCD_HEIGHT >= 132) && (LCD_DEPTH==16)
357 /* The time (in ms) for one iteration through the game loop - decrease this
358 to speed up the game - note that current_tick is (currently) only accurate
359 to 10ms.
362 #define CYCLETIME 30
364 #define GAMESCREEN_HEIGHT 132
365 #define TOPMARGIN 21
367 #define BMPYOFS_start 58
368 #define HIGHSCORE_XPOS 7
369 #define HIGHSCORE_YPOS 36
371 #define STRINGPOS_FINISH 110
372 #define STRINGPOS_CONGRATS 110
373 #define STRINGPOS_NAVI 100
374 #define STRINGPOS_FLIP 100
376 #else
377 #error Unsupported LCD Size
378 #endif
381 #ifndef GAMESCREEN_HEIGHT
382 #define GAMESCREEN_HEIGHT LCD_HEIGHT
383 #endif
385 /* calculate menu item offsets from the first defined and the height*/
386 #define BMPYOFS_resume (BMPYOFS_start + MENU_ITEMHEIGHT)
387 #define BMPYOFS_help (BMPYOFS_start + 2*MENU_ITEMHEIGHT)
388 #define BMPYOFS_quit (BMPYOFS_start + 3*MENU_ITEMHEIGHT)
390 /*calculate paddle y-position */
391 #if GAMESCREEN_HEIGHT >= 128
392 #define PAD_POS_Y GAMESCREEN_HEIGHT -PAD_HEIGHT - 2
393 #else
394 #define PAD_POS_Y GAMESCREEN_HEIGHT -PAD_HEIGHT - 1
395 #endif
398 int levels_num = 29;
400 static unsigned char levels[29][8][10] = {
401 { /* level1 */
402 {0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1},
403 {0x2,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x2},
404 {0x0,0x2,0x1,0x0,0x0,0x0,0x0,0x1,0x2,0x0},
405 {0x0,0x0,0x2,0x1,0x0,0x0,0x1,0x2,0x0,0x0},
406 {0x0,0x0,0x0,0x2,0x1,0x1,0x2,0x0,0x0,0x0},
407 {0x7,0x0,0x0,0x7,0x2,0x2,0x7,0x0,0x0,0x7},
408 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
409 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}
411 { /* level2 */
412 {0x0,0x0,0x7,0x7,0x1,0x1,0x7,0x7,0x0,0x0},
413 {0x0,0x1,0x0,0x0,0x1,0x1,0x0,0x0,0x1,0x0},
414 {0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1},
415 {0x1,0x1,0x1,0x1,0x0,0x0,0x1,0x1,0x1,0x1},
416 {0x1,0x1,0x2,0x1,0x0,0x0,0x1,0x2,0x1,0x1},
417 {0x1,0x2,0x0,0x2,0x2,0x2,0x2,0x0,0x2,0x1},
418 {0x0,0x1,0x2,0x0,0x0,0x0,0x0,0x2,0x1,0x0},
419 {0x0,0x0,0x1,0x2,0x2,0x2,0x2,0x1,0x0,0x0}
421 { /* level3 */
422 {0x3,0x3,0x3,0x3,0x0,0x0,0x2,0x2,0x2,0x2},
423 {0x3,0x23,0x23,0x3,0x0,0x0,0x2,0x22,0x22,0x2},
424 {0x3,0x3,0x3,0x3,0x0,0x0,0x2,0x2,0x2,0x2},
425 {0x0,0x0,0x0,0x0,0x37,0x37,0x0,0x0,0x0,0x0},
426 {0x0,0x0,0x0,0x0,0x37,0x37,0x0,0x0,0x0,0x0},
427 {0x5,0x5,0x5,0x5,0x0,0x0,0x6,0x6,0x6,0x6},
428 {0x5,0x25,0x25,0x5,0x0,0x0,0x6,0x26,0x26,0x6},
429 {0x5,0x5,0x5,0x5,0x0,0x0,0x6,0x6,0x6,0x6}
431 { /* level4 */
432 {0x0,0x0,0x0,0x27,0x27,0x27,0x27,0x0,0x0,0x0},
433 {0x0,0x0,0x0,0x27,0x7,0x7,0x27,0x0,0x0,0x0},
434 {0x22,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x22},
435 {0x22,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x22},
436 {0x26,0x6,0x0,0x2,0x2,0x2,0x2,0x0,0x6,0x26},
437 {0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0},
438 {0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0},
439 {0x1,0x1,0x1,0x1,0x0,0x0,0x1,0x1,0x1,0x1}
441 { /* level5 */
442 {0x1,0x0,0x2,0x2,0x0,0x3,0x3,0x0,0x4,0x4},
443 {0x0,0x2,0x2,0x0,0x3,0x3,0x0,0x4,0x4,0x0},
444 {0x2,0x2,0x0,0x3,0x3,0x0,0x4,0x4,0x0,0x5},
445 {0x2,0x0,0x3,0x3,0x0,0x4,0x4,0x0,0x5,0x5},
446 {0x0,0x33,0x3,0x0,0x4,0x4,0x0,0x5,0x5,0x0},
447 {0x3,0x33,0x0,0x4,0x4,0x0,0x5,0x5,0x0,0x36},
448 {0x3,0x0,0x4,0x4,0x0,0x5,0x5,0x0,0x6,0x36},
449 {0x0,0x24,0x24,0x0,0x25,0x25,0x0,0x26,0x26,0x0}
451 { /* level6 */
452 {0x0,0x1,0x3,0x7,0x7,0x7,0x7,0x3,0x1,0x0},
453 {0x3,0x1,0x3,0x7,0x0,0x0,0x7,0x3,0x1,0x3},
454 {0x3,0x1,0x3,0x7,0x7,0x7,0x7,0x3,0x1,0x3},
455 {0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0},
456 {0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5},
457 {0x5,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x5},
458 {0x0,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x0},
459 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}
461 { /* level7 */
462 {0x0,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x0},
463 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
464 {0x6,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x6},
465 {0x6,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x6},
466 {0x6,0x6,0x6,0x0,0x0,0x0,0x0,0x6,0x6,0x6},
467 {0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0},
468 {0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0},
469 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}
471 { /* level8 */
472 {0x0,0x7,0x7,0x7,0x7,0x7,0x7,0x7,0x7,0x0},
473 {0x0,0x0,0x0,0x4,0x0,0x0,0x4,0x0,0x0,0x0},
474 {0x6,0x6,0x0,0x2,0x32,0x32,0x2,0x0,0x6,0x6},
475 {0x0,0x0,0x2,0x2,0x2,0x2,0x2,0x2,0x0,0x0},
476 {0x0,0x6,0x6,0x0,0x0,0x0,0x0,0x6,0x6,0x0},
477 {0x0,0x0,0x0,0x5,0x25,0x25,0x5,0x0,0x0,0x0},
478 {0x0,0x5,0x5,0x25,0x5,0x5,0x25,0x5,0x5,0x0},
479 {0x5,0x5,0x25,0x5,0x5,0x5,0x5,0x25,0x5,0x5}
481 { /* level9 */
482 {0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2},
483 {0x2,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x2},
484 {0x2,0x0,0x3,0x0,0x1,0x1,0x0,0x3,0x0,0x2},
485 {0x2,0x0,0x0,0x1,0x0,0x0,0x1,0x0,0x0,0x2},
486 {0x2,0x0,0x1,0x0,0x3,0x3,0x0,0x1,0x0,0x2},
487 {0x2,0x0,0x0,0x1,0x0,0x0,0x1,0x0,0x0,0x2},
488 {0x2,0x2,0x0,0x0,0x1,0x1,0x0,0x0,0x2,0x2},
489 {0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2}
491 { /* level10 */
492 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
493 {0x0,0x5,0x0,0x5,0x0,0x5,0x0,0x5,0x0,0x5},
494 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
495 {0x0,0x0,0x0,0x0,0x1,0x1,0x0,0x0,0x0,0x0},
496 {0x0,0x0,0x0,0x4,0x1,0x1,0x4,0x0,0x0,0x0},
497 {0x0,0x0,0x3,0x4,0x1,0x1,0x4,0x3,0x0,0x0},
498 {0x0,0x2,0x3,0x4,0x1,0x1,0x4,0x3,0x2,0x0},
499 {0x1,0x2,0x3,0x4,0x1,0x1,0x4,0x3,0x2,0x1}
501 { /* level11 */
502 {0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3},
503 {0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x2},
504 {0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2},
505 {0x2,0x0,0x0,0x0,0x7,0x7,0x0,0x0,0x0,0x2},
506 {0x2,0x0,0x0,0x7,0x7,0x7,0x7,0x0,0x0,0x2},
507 {0x0,0x0,0x0,0x1,0x0,0x0,0x1,0x0,0x0,0x0},
508 {0x0,0x2,0x0,0x1,0x0,0x0,0x1,0x0,0x2,0x0},
509 {0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5}
511 { /* level 12 */
512 {0x2,0x1,0x3,0x1,0x0,0x0,0x1,0x3,0x1,0x2},
513 {0x1,0x1,0x1,0x1,0x0,0x0,0x1,0x1,0x1,0x1},
514 {0x1,0x1,0x1,0x0,0x1,0x1,0x0,0x1,0x1,0x1},
515 {0x0,0x1,0x0,0x1,0x6,0x6,0x1,0x0,0x1,0x0},
516 {0x0,0x0,0x1,0x1,0x6,0x6,0x1,0x1,0x0,0x0},
517 {0x1,0x1,0x1,0x7,0x0,0x0,0x7,0x1,0x1,0x1},
518 {0x1,0x1,0x7,0x1,0x0,0x0,0x1,0x7,0x1,0x1},
519 {0x2,0x2,0x0,0x2,0x2,0x2,0x2,0x0,0x2,0x2}
521 {/* levell13 */
522 {0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2},
523 {0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2},
524 {0x2,0x0,0x2,0x2,0x2,0x2,0x2,0x2,0x0,0x2},
525 {0x2,0x0,0x2,0x3,0x3,0x3,0x3,0x3,0x0,0x2},
526 {0x2,0x0,0x2,0x4,0x4,0x4,0x4,0x4,0x0,0x2},
527 {0x2,0x0,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2},
528 {0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
529 {0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2}
531 {/* level14 */
532 {0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1},
533 {0x4,0x4,0x4,0x4,0x2,0x2,0x4,0x4,0x4,0x4},
534 {0x4,0x0,0x0,0x0,0x2,0x2,0x0,0x0,0x0,0x4},
535 {0x4,0x0,0x0,0x2,0x3,0x3,0x2,0x0,0x0,0x4},
536 {0x4,0x0,0x2,0x23,0x3,0x3,0x23,0x2,0x0,0x4},
537 {0x4,0x0,0x2,0x22,0x2,0x2,0x22,0x2,0x0,0x4},
538 {0x4,0x0,0x6,0x21,0x5,0x5,0x21,0x6,0x0,0x4},
539 {0x4,0x6,0x1,0x1,0x5,0x5,0x1,0x1,0x6,0x4}
541 {/* level 15 */
542 {0x4,0x4,0x4,0x4,0x4,0x3,0x3,0x3,0x3,0x3},
543 {0x2,0x2,0x1,0x1,0x1,0x1,0x1,0x5,0x0,0x0},
544 {0x2,0x2,0x1,0x1,0x1,0x0,0x1,0x6,0x0,0x0},
545 {0x2,0x1,0x1,0x2,0x1,0x1,0x1,0x5,0x0,0x0},
546 {0x2,0x1,0x2,0x2,0x2,0x1,0x1,0x6,0x0,0x0},
547 {0x2,0x1,0x2,0x2,0x2,0x1,0x3,0x5,0x3,0x0},
548 {0x2,0x1,0x1,0x2,0x1,0x1,0x1,0x6,0x0,0x0},
549 {0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2}
551 {/* level 16 (Rockbox) by ts-x */
552 {0x2,0x2,0x3,0x3,0x3,0x4,0x4,0x5,0x0,0x5},
553 {0x2,0x0,0x3,0x0,0x3,0x4,0x0,0x5,0x5,0x0},
554 {0x2,0x0,0x3,0x3,0x3,0x4,0x4,0x5,0x0,0x5},
555 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
556 {0x6,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
557 {0x7,0x7,0x7,0x1,0x1,0x1,0x2,0x0,0x2,0x0},
558 {0x7,0x0,0x7,0x1,0x0,0x1,0x0,0x2,0x0,0x0},
559 {0x7,0x7,0x7,0x1,0x1,0x1,0x2,0x0,0x2,0x0}
561 {/* level 17 (Alien) by ts-x */
562 {0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1},
563 {0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2},
564 {0x1,0x0,0x0,0x0,0x1,0x1,0x0,0x0,0x0,0x1},
565 {0x2,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x2},
566 {0x1,0x0,0x1,0x2,0x2,0x2,0x2,0x1,0x0,0x1},
567 {0x2,0x0,0x0,0x1,0x2,0x2,0x1,0x0,0x0,0x2},
568 {0x2,0x1,0x0,0x0,0x1,0x1,0x0,0x0,0x1,0x2},
569 {0x2,0x2,0x1,0x0,0x1,0x1,0x0,0x1,0x2,0x2}
571 {/* level 18 (Tetris) by ts-x */
572 {0x0,0x2,0x0,0x0,0x3,0x4,0x0,0x2,0x2,0x0},
573 {0x0,0x2,0x7,0x0,0x3,0x4,0x0,0x2,0x2,0x0},
574 {0x2,0x2,0x7,0x0,0x3,0x4,0x0,0x6,0x2,0x2},
575 {0x2,0x2,0x7,0x7,0x3,0x4,0x0,0x6,0x2,0x2},
576 {0x2,0x1,0x7,0x7,0x3,0x4,0x4,0x6,0x5,0x5},
577 {0x2,0x1,0x0,0x7,0x3,0x4,0x4,0x6,0x5,0x5},
578 {0x1,0x1,0x1,0x7,0x3,0x0,0x6,0x6,0x5,0x5},
579 {0x1,0x1,0x1,0x0,0x3,0x0,0x6,0x6,0x5,0x5}
581 { /* level 19 (Stalactites) by ts-x */
582 {0x5,0x2,0x6,0x3,0x4,0x7,0x5,0x3,0x1,0x2},
583 {0x5,0x2,0x6,0x3,0x4,0x7,0x5,0x3,0x1,0x2},
584 {0x5,0x0,0x6,0x3,0x4,0x7,0x5,0x0,0x1,0x2},
585 {0x5,0x2,0x6,0x3,0x4,0x0,0x5,0x3,0x1,0x2},
586 {0x5,0x0,0x6,0x0,0x4,0x7,0x5,0x0,0x1,0x0},
587 {0x5,0x0,0x0,0x3,0x4,0x0,0x0,0x0,0x1,0x2},
588 {0x0,0x0,0x6,0x0,0x0,0x0,0x5,0x0,0x0,0x0},
589 {0x5,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x1,0x0}
591 { /* level 20 (Maze) by ts-x */
592 {0x1,0x1,0x21,0x1,0x1,0x1,0x1,0x1,0x1,0x21},
593 {0x1,0x0,0x0,0x3,0x0,0x0,0x3,0x1,0x31,0x1},
594 {0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x31,0x0,0x1},
595 {0x21,0x0,0x21,0x3,0x0,0x3,0x0,0x3,0x0,0x2},
596 {0x1,0x0,0x1,0x21,0x0,0x12,0x0,0x0,0x0,0x0},
597 {0x31,0x0,0x1,0x0,0x0,0x1,0x0,0x0,0x3,0x0},
598 {0x1,0x0,0x1,0x0,0x1,0x1,0x31,0x1,0x1,0x2},
599 {0x22,0x0,0x2,0x1,0x1,0x1,0x1,0x1,0x1,0x21}
601 { /* level 21 (Dentist) by ts-x */
602 {0x0,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x0},
603 {0x2,0x2,0x0,0x6,0x0,0x6,0x0,0x6,0x2,0x2},
604 {0x2,0x6,0x0,0x6,0x0,0x6,0x0,0x6,0x0,0x2},
605 {0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x6,0x0,0x2},
606 {0x2,0x0,0x6,0x0,0x6,0x0,0x0,0x0,0x0,0x2},
607 {0x2,0x0,0x6,0x0,0x6,0x0,0x6,0x0,0x6,0x2},
608 {0x2,0x2,0x6,0x0,0x6,0x0,0x6,0x0,0x2,0x2},
609 {0x0,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x0}
611 { /* level 22 (Spider) by ts-x */
612 {0x31,0x3,0x1,0x1,0x0,0x0,0x1,0x1,0x3,0x31},
613 {0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0},
614 {0x33,0x1,0x1,0x36,0x1,0x1,0x36,0x1,0x1,0x33},
615 {0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0},
616 {0x0,0x0,0x1,0x1,0x0,0x0,0x1,0x1,0x0,0x0},
617 {0x21,0x3,0x1,0x21,0x2,0x2,0x21,0x1,0x3,0x21},
618 {0x0,0x0,0x0,0x1,0x21,0x1,0x1,0x0,0x0,0x0},
619 {0x3,0x1,0x3,0x1,0x0,0x0,0x1,0x3,0x1,0x3}
621 { /* level 23 (Pool) by ts-x */
622 {0x0,0x7,0x7,0x7,0x0,0x7,0x7,0x7,0x7,0x0},
623 {0x0,0x0,0x5,0x0,0x2,0x0,0x0,0x0,0x2,0x0},
624 {0x7,0x3,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x7},
625 {0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x5,0x0,0x7},
626 {0x7,0x0,0x4,0x0,0x0,0x3,0x0,0x0,0x0,0x7},
627 {0x7,0x0,0x0,0x6,0x0,0x0,0x0,0x0,0x4,0x7},
628 {0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
629 {0x0,0x7,0x7,0x7,0x7,0x0,0x7,0x7,0x7,0x0}
631 { /* level 24 (Vorbis Fish) by ts-x */
632 {0x0,0x0,0x4,0x4,0x5,0x5,0x5,0x0,0x0,0x5},
633 {0x0,0x4,0x6,0x4,0x4,0x5,0x5,0x5,0x0,0x5},
634 {0x5,0x6,0x0,0x6,0x4,0x4,0x4,0x5,0x5,0x5},
635 {0x5,0x6,0x0,0x6,0x4,0x4,0x4,0x4,0x5,0x5},
636 {0x0,0x5,0x6,0x4,0x4,0x5,0x5,0x4,0x5,0x0},
637 {0x5,0x5,0x4,0x4,0x5,0x5,0x5,0x4,0x5,0x5},
638 {0x5,0x4,0x4,0x4,0x5,0x5,0x4,0x4,0x5,0x5},
639 {0x0,0x0,0x4,0x4,0x4,0x4,0x4,0x5,0x0,0x5}
641 {/* level 25 (Rainbow) by ts-x */
642 {0x0,0x4,0x1,0x0,0x0,0x0,0x0,0x1,0x4,0x0},
643 {0x24,0x1,0x3,0x1,0x0,0x0,0x21,0x3,0x1,0x24},
644 {0x1,0x23,0x5,0x3,0x1,0x21,0x3,0x5,0x3,0x21},
645 {0x3,0x5,0x6,0x5,0x3,0x3,0x5,0x6,0x5,0x3},
646 {0x5,0x6,0x7,0x6,0x5,0x5,0x6,0x7,0x6,0x5},
647 {0x6,0x7,0x2,0x27,0x6,0x6,0x27,0x2,0x7,0x6},
648 {0x7,0x2,0x0,0x2,0x27,0x27,0x2,0x0,0x2,0x7},
649 {0x32,0x0,0x0,0x0,0x2,0x2,0x0,0x0,0x0,0x32}
651 { /* level 26 (Bowtie) by ts-x */
652 {0x5,0x1,0x5,0x1,0x0,0x0,0x1,0x5,0x1,0x5},
653 {0x1,0x0,0x0,0x1,0x5,0x5,0x1,0x0,0x0,0x1},
654 {0x5,0x0,0x6,0x0,0x1,0x1,0x0,0x6,0x0,0x5},
655 {0x1,0x0,0x6,0x6,0x0,0x0,0x6,0x6,0x0,0x1},
656 {0x1,0x0,0x6,0x6,0x0,0x0,0x6,0x6,0x0,0x1},
657 {0x5,0x0,0x6,0x0,0x1,0x1,0x0,0x6,0x0,0x5},
658 {0x1,0x0,0x0,0x1,0x5,0x5,0x1,0x0,0x0,0x1},
659 {0x5,0x1,0x5,0x1,0x0,0x0,0x1,0x5,0x1,0x5}
661 { /* level 27 (Frog) by ts-x */
662 {0x0,0x5,0x25,0x0,0x0,0x0,0x0,0x25,0x5,0x0},
663 {0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5},
664 {0x25,0x0,0x0,0x5,0x6,0x6,0x5,0x0,0x0,0x25},
665 {0x5,0x0,0x3,0x0,0x6,0x6,0x0,0x3,0x0,0x5},
666 {0x5,0x0,0x31,0x0,0x6,0x6,0x0,0x31,0x0,0x5},
667 {0x5,0x0,0x0,0x5,0x6,0x6,0x5,0x0,0x0,0x5},
668 {0x5,0x5,0x5,0x35,0x0,0x0,0x35,0x5,0x5,0x5},
669 {0x0,0x25,0x5,0x0,0x4,0x4,0x0,0x5,0x25,0x0}
671 { /* level 28 (DigDug) by ts-x */
672 {0x35,0x5,0x5,0x25,0x0,0x25,0x25,0x5,0x5,0x35},
673 {0x6,0x0,0x0,0x6,0x0,0x6,0x6,0x0,0x0,0x6},
674 {0x7,0x0,0x37,0x37,0x0,0x37,0x37,0x7,0x0,0x7},
675 {0x7,0x0,0x7,0x0,0x0,0x0,0x7,0x7,0x7,0x7},
676 {0x4,0x4,0x4,0x24,0x0,0x24,0x4,0x0,0x0,0x4},
677 {0x4,0x4,0x0,0x0,0x0,0x4,0x4,0x0,0x4,0x4},
678 {0x24,0x24,0x4,0x4,0x4,0x4,0x0,0x0,0x24,0x4},
679 {0x1,0x1,0x1,0x1,0x1,0x1,0x21,0x21,0x1,0x1}
681 { /* TheEnd */
682 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
683 {0x22,0x22,0x26,0x0,0x0,0x26,0x24,0x24,0x0,0x0},
684 {0x22,0x0,0x26,0x26,0x0,0x26,0x24,0x0,0x24,0x0},
685 {0x22,0x22,0x26,0x26,0x0,0x26,0x24,0x0,0x24,0x0},
686 {0x22,0x22,0x26,0x0,0x26,0x26,0x24,0x0,0x24,0x0},
687 {0x22,0x0,0x26,0x0,0x26,0x26,0x24,0x0,0x24,0x0},
688 {0x22,0x22,0x26,0x0,0x0,0x26,0x24,0x24,0x0,0x0},
689 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}
693 #define MAX_BALLS 10
694 int pad_pos_x;
695 int x[MAX_BALLS],y[MAX_BALLS];
696 int life;
697 int start_game,con_game;
698 int pad_type;
699 int score=0,vscore=0;
700 bool flip_sides=false;
701 int cur_level=0;
702 int brick_on_board=0;
703 int used_balls=1;
705 typedef struct cube {
706 int powertop;
707 int power;
708 char poweruse;
709 char used;
710 int color;
711 int hits;
712 int hiteffect;
713 } cube;
714 cube brick[80];
716 typedef struct balls {
717 int pos_x;
718 int pos_y;
719 int y;
720 int tempy;
721 int x;
722 int tempx;
723 bool glue;
724 } balls;
726 balls ball[MAX_BALLS];
728 typedef struct sfire {
729 int top;
730 int left;
731 } sfire;
732 sfire fire[30];
735 int highscore;
736 #define MAX_POINTS 200000 /* i dont think it needs to be more */
737 static struct configdata config[] =
739 {TYPE_INT, 0, MAX_POINTS, &highscore, "highscore", NULL, NULL}
742 void int_game(int new_game)
744 int i,j;
746 pad_pos_x=LCD_WIDTH/2-PAD_WIDTH/2;
748 for(i=0;i<MAX_BALLS;i++) {
749 ball[i].x=0;
750 ball[i].y=0;
751 ball[i].tempy=0;
752 ball[i].tempx=0;
753 ball[i].pos_y=PAD_POS_Y-BALL;
754 ball[i].pos_x=pad_pos_x+(PAD_WIDTH/2)-2;
755 ball[i].glue=false;
758 used_balls=1;
759 start_game =1;
760 con_game =0;
761 pad_type=0;
763 flip_sides=false;
765 if (new_game==1)
766 brick_on_board=0;
768 for(i=0;i<=7;i++) {
769 for(j=0;j<=9;j++) {
770 brick[i*10+j].poweruse=(levels[cur_level][i][j]==0?0:1);
771 if (i*10+j<=30)
772 fire[i*10+j].top=-8;
773 if (new_game==1) {
774 brick[i*10+j].power=rb->rand()%25;
775 /* +8 make the game with less powerups */
777 brick[i*10+j].hits=levels[cur_level][i][j]>=10?
778 levels[cur_level][i][j]/16-1:0;
779 brick[i*10+j].hiteffect=0;
780 brick[i*10+j].powertop=TOPMARGIN+i*BRICK_HEIGHT+BRICK_HEIGHT;
781 brick[i*10+j].used=(levels[cur_level][i][j]==0?0:1);
782 brick[i*10+j].color=(levels[cur_level][i][j]>=10?
783 levels[cur_level][i][j]%16:
784 levels[cur_level][i][j])-1;
785 if (levels[cur_level][i][j]!=0)
786 brick_on_board++;
792 int sw,i,w;
794 /* sleep timer counting the score */
795 void sleep (int secs)
797 bool done=false;
798 char s[20];
799 int count=0;
801 while (!done) {
803 if (vscore<score) {
804 vscore++;
805 rb->snprintf(s, sizeof(s), "%d", vscore);
806 rb->lcd_getstringsize(s, &sw, &w);
807 #if (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
808 rb->lcd_putsxy(LCD_WIDTH/2-sw/2, 0, s);
809 #else
810 rb->lcd_putsxy(LCD_WIDTH/2-sw/2, 2, s);
811 #endif
812 rb->lcd_update_rect(0,0,LCD_WIDTH,w+2);
813 } else {
814 if (count==0)
815 count=*rb->current_tick+HZ*secs;
816 if (*rb->current_tick>=count)
817 done=true;
819 rb->yield();
824 #define HIGH_SCORE "brickmania.score"
825 #define MENU_LENGTH 4
826 int game_menu(int when)
828 int button,cur=0;
829 char str[10];
830 rb->lcd_clear_display();
831 #if (LCD_WIDTH != 112) && (LCD_HEIGHT != 64)
832 rb->lcd_bitmap(brickmania_menu_bg, 0, 0, MENU_BGWIDTH, MENU_BGHEIGHT);
833 #endif
834 while (true) {
835 for(i=0;i<MENU_LENGTH;i++) {
836 #ifdef HAVE_LCD_COLOR
837 if (cur==0)
838 rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0,
839 MENU_ITEMHEIGHT * BM_SEL_START, MENU_ITEMWIDTH,
840 MENU_ITEMXOFS, BMPYOFS_start, MENU_ITEMWIDTH,
841 MENU_ITEMHEIGHT);
842 else
843 rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0,
844 MENU_ITEMHEIGHT * BM_START, MENU_ITEMWIDTH,
845 MENU_ITEMXOFS, BMPYOFS_start, MENU_ITEMWIDTH,
846 MENU_ITEMHEIGHT);
848 if (when==1) {
849 if (cur==1)
850 rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0,
851 MENU_ITEMHEIGHT * BM_SEL_RESUME, MENU_ITEMWIDTH,
852 MENU_ITEMXOFS, BMPYOFS_resume, MENU_ITEMWIDTH,
853 MENU_ITEMHEIGHT);
854 else
855 rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0,
856 MENU_ITEMHEIGHT * BM_RESUME, MENU_ITEMWIDTH,
857 MENU_ITEMXOFS, BMPYOFS_resume, MENU_ITEMWIDTH,
858 MENU_ITEMHEIGHT);
860 } else {
861 rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0,
862 MENU_ITEMHEIGHT * BM_NO_RESUME, MENU_ITEMWIDTH,
863 MENU_ITEMXOFS, BMPYOFS_resume, MENU_ITEMWIDTH,
864 MENU_ITEMHEIGHT);
868 if (cur==2)
869 rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0,
870 MENU_ITEMHEIGHT * BM_SEL_HELP, MENU_ITEMWIDTH,
871 MENU_ITEMXOFS, BMPYOFS_help, MENU_ITEMWIDTH,
872 MENU_ITEMHEIGHT);
873 else
874 rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0,
875 MENU_ITEMHEIGHT * BM_HELP, MENU_ITEMWIDTH,
876 MENU_ITEMXOFS, BMPYOFS_help, MENU_ITEMWIDTH,
877 MENU_ITEMHEIGHT);
879 if (cur==3)
880 rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0,
881 MENU_ITEMHEIGHT * BM_SEL_QUIT, MENU_ITEMWIDTH,
882 MENU_ITEMXOFS, BMPYOFS_quit, MENU_ITEMWIDTH,
883 MENU_ITEMHEIGHT);
884 else
885 rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0,
886 MENU_ITEMHEIGHT * BM_QUIT, MENU_ITEMWIDTH,
887 MENU_ITEMXOFS, BMPYOFS_quit, MENU_ITEMWIDTH,
888 MENU_ITEMHEIGHT);
889 #else
890 if (cur==0)
891 rb->lcd_bitmap_part(brickmania_menu_items, 0,
892 MENU_ITEMHEIGHT * BM_SEL_START, MENU_ITEMWIDTH,
893 MENU_ITEMXOFS, BMPYOFS_start, MENU_ITEMWIDTH,
894 MENU_ITEMHEIGHT);
895 else
896 rb->lcd_bitmap_part(brickmania_menu_items, 0,
897 MENU_ITEMHEIGHT * BM_START, MENU_ITEMWIDTH,
898 MENU_ITEMXOFS, BMPYOFS_start, MENU_ITEMWIDTH,
899 MENU_ITEMHEIGHT);
901 if (when==1) {
902 if (cur==1)
903 rb->lcd_bitmap_part(brickmania_menu_items, 0,
904 MENU_ITEMHEIGHT * BM_SEL_RESUME, MENU_ITEMWIDTH,
905 MENU_ITEMXOFS, BMPYOFS_resume, MENU_ITEMWIDTH,
906 MENU_ITEMHEIGHT);
907 else
908 rb->lcd_bitmap_part(brickmania_menu_items, 0,
909 MENU_ITEMHEIGHT * BM_RESUME, MENU_ITEMWIDTH,
910 MENU_ITEMXOFS, BMPYOFS_resume, MENU_ITEMWIDTH,
911 MENU_ITEMHEIGHT);
913 } else {
914 rb->lcd_bitmap_part(brickmania_menu_items, 0,
915 MENU_ITEMHEIGHT * BM_NO_RESUME, MENU_ITEMWIDTH,
916 MENU_ITEMXOFS, BMPYOFS_resume, MENU_ITEMWIDTH,
917 MENU_ITEMHEIGHT);
921 if (cur==2)
922 rb->lcd_bitmap_part(brickmania_menu_items, 0,
923 MENU_ITEMHEIGHT * BM_SEL_HELP, MENU_ITEMWIDTH,
924 MENU_ITEMXOFS, BMPYOFS_help, MENU_ITEMWIDTH,
925 MENU_ITEMHEIGHT);
926 else
927 rb->lcd_bitmap_part(brickmania_menu_items, 0,
928 MENU_ITEMHEIGHT * BM_HELP, MENU_ITEMWIDTH,
929 MENU_ITEMXOFS, BMPYOFS_help, MENU_ITEMWIDTH,
930 MENU_ITEMHEIGHT);
932 if (cur==3)
933 rb->lcd_bitmap_part(brickmania_menu_items, 0,
934 MENU_ITEMHEIGHT * BM_SEL_QUIT, MENU_ITEMWIDTH,
935 MENU_ITEMXOFS, BMPYOFS_quit, MENU_ITEMWIDTH,
936 MENU_ITEMHEIGHT);
937 else
938 rb->lcd_bitmap_part(brickmania_menu_items, 0,
939 MENU_ITEMHEIGHT * BM_QUIT, MENU_ITEMWIDTH,
940 MENU_ITEMXOFS, BMPYOFS_quit, MENU_ITEMWIDTH,
941 MENU_ITEMHEIGHT);
942 #endif
944 rb->lcd_set_drawmode(DRMODE_FG);
945 /* high score */
946 #ifdef HAVE_LCD_COLOR
947 rb->lcd_set_background(LCD_RGBPACK(0,0,140));
948 rb->lcd_set_foreground(LCD_WHITE);
949 #endif
950 rb->lcd_putsxy(HIGHSCORE_XPOS, HIGHSCORE_YPOS, "High Score");
951 rb->snprintf(str, sizeof(str), "%d", highscore);
952 rb->lcd_getstringsize("High Score", &sw, NULL);
953 rb->lcd_getstringsize(str, &w, NULL);
954 rb->lcd_putsxy(HIGHSCORE_XPOS+sw/2-w/2, HIGHSCORE_YPOS+9, str);
955 rb->lcd_set_drawmode(DRMODE_SOLID);
957 rb->lcd_update();
959 button = rb->button_get(true);
960 switch(button) {
961 case UP:
962 case UP | BUTTON_REPEAT:
963 if (cur==0)
964 cur = MENU_LENGTH-1;
965 else
966 cur--;
967 if (when==0 && cur==1) {
968 cur = 0;
970 break;
972 case DOWN:
973 case DOWN | BUTTON_REPEAT:
974 if (cur==MENU_LENGTH-1)
975 cur = 0;
976 else
977 cur++;
978 if (when==0 && cur==1) {
979 cur=2;
981 break;
983 case RIGHT:
984 case SELECT:
985 if (cur==0) {
986 score=0;
987 vscore=0;
988 return 0;
989 } else if (cur==1 && when==1) {
990 return 1;
991 } else if (cur==2) {
992 return 2;
993 } else if (cur==3) {
994 return 3;
996 break;
997 #ifdef RC_QUIT
998 case RC_QUIT:
999 #endif
1000 case QUIT:
1001 return 3;
1002 break;
1004 default:
1005 if(rb->default_event_handler(button) == SYS_USB_CONNECTED)
1006 return 3;
1007 break;
1012 int help(int when)
1014 int w,h;
1015 int button;
1016 int xoffset=0;
1017 int yoffset=0;
1018 /* set the maximum x and y in the helpscreen
1019 dont forget to update, if you change text */
1020 int maxY=180;
1021 int maxX=215;
1023 while(true) {
1024 #ifdef HAVE_LCD_COLOR
1025 rb->lcd_set_background(LCD_BLACK);
1026 rb->lcd_clear_display();
1027 rb->lcd_set_background(LCD_BLACK);
1028 rb->lcd_set_foreground(LCD_WHITE);
1029 #else
1030 rb->lcd_clear_display();
1031 #endif
1033 rb->lcd_getstringsize("BrickMania", &w, &h);
1034 rb->lcd_putsxy(LCD_WIDTH/2-w/2+xoffset, 1+yoffset, "BrickMania");
1036 #ifdef HAVE_LCD_COLOR
1037 rb->lcd_set_foreground(LCD_RGBPACK(245,0,0));
1038 rb->lcd_putsxy(1+xoffset, 1*(h+2)+yoffset,"Aim");
1039 rb->lcd_set_foreground(LCD_WHITE);
1040 #else
1041 rb->lcd_putsxy(1+xoffset, 1*(h+2)+yoffset,"Aim");
1042 #endif
1043 rb->lcd_putsxy(1+xoffset, 2*(h+2)+yoffset,
1044 "destroy all the bricks by bouncing");
1045 rb->lcd_putsxy(1+xoffset, 3*(h+2)+yoffset,
1046 "the ball of them using the paddle.");
1047 #ifdef HAVE_LCD_COLOR
1048 rb->lcd_set_foreground(LCD_RGBPACK(245,0,0));
1049 rb->lcd_putsxy(1+xoffset, 5*(h+2)+yoffset,"Controls");
1050 rb->lcd_set_foreground(LCD_WHITE);
1051 #else
1052 rb->lcd_putsxy(1+xoffset, 5*(h+2)+yoffset,"Controls");
1053 #endif
1054 rb->lcd_putsxy(1+xoffset, 6*(h+2)+yoffset,"< & > Move the paddle");
1055 #if CONFIG_KEYPAD == ONDIO_PAD
1056 rb->lcd_putsxy(1+xoffset, 7*(h+2)+yoffset,
1057 "MENU Releases the ball/Fire!");
1058 #elif CONFIG_KEYPAD == RECORDER_PAD
1059 rb->lcd_putsxy(1+xoffset, 7*(h+2)+yoffset,
1060 "PLAY Releases the ball/Fire!");
1061 #elif CONFIG_KEYPAD == IRIVER_H300_PAD
1062 rb->lcd_putsxy(1+xoffset, 7*(h+2)+yoffset,
1063 "NAVI Releases the ball/Fire!");
1064 #else
1065 rb->lcd_putsxy(1+xoffset, 7*(h+2)+yoffset,
1066 "SELECT Releases the ball/Fire!");
1067 #endif
1068 rb->lcd_putsxy(1+xoffset, 8*(h+2)+yoffset, "STOP Opens menu/Quit");
1069 #ifdef HAVE_LCD_COLOR
1070 rb->lcd_set_foreground(LCD_RGBPACK(245,0,0));
1071 rb->lcd_putsxy(1+xoffset, 10*(h+2)+yoffset, "Specials");
1072 rb->lcd_set_foreground(LCD_WHITE);
1073 #else
1074 rb->lcd_putsxy(1+xoffset, 10*(h+2)+yoffset, "Specials");
1075 #endif
1076 rb->lcd_putsxy(1+xoffset, 11*(h+2)+yoffset,
1077 "N Normal:returns paddle to normal");
1078 rb->lcd_putsxy(1+xoffset, 12*(h+2)+yoffset, "D DIE!:loses a life");
1079 rb->lcd_putsxy(1+xoffset, 13*(h+2)+yoffset,
1080 "L Life:gains a life/power up");
1081 rb->lcd_putsxy(1+xoffset, 14*(h+2)+yoffset,
1082 "F Fire:allows you to shoot bricks");
1083 rb->lcd_putsxy(1+xoffset, 15*(h+2)+yoffset,
1084 "G Glue:ball sticks to paddle");
1085 rb->lcd_putsxy(1+xoffset, 16*(h+2)+yoffset,
1086 "B Ball:generates another ball");
1087 rb->lcd_putsxy(1+xoffset, 17*(h+2)+yoffset,
1088 "FL Flip:flips left / right movement");
1089 rb->lcd_update();
1091 button=rb->button_get(true);
1092 switch (button) {
1093 #ifdef RC_QUIT
1094 case RC_QUIT:
1095 #endif
1096 case QUIT:
1097 switch (game_menu(when)) {
1098 case 0:
1099 cur_level=0;
1100 life=2;
1101 int_game(1);
1102 break;
1103 case 1:
1104 con_game=1;
1105 break;
1106 case 2:
1107 if (help(when)==1)
1108 return 1;
1109 break;
1110 case 3:
1111 return 1;
1112 break;
1114 return 0;
1115 break;
1116 case LEFT:
1117 case LEFT | BUTTON_REPEAT:
1118 #ifdef ALTLEFT
1119 case ALTLEFT:
1120 case ALTLEFT | BUTTON_REPEAT:
1121 #endif
1122 if( xoffset<0)
1123 xoffset+=2;
1124 break;
1125 case RIGHT:
1126 case RIGHT | BUTTON_REPEAT:
1127 #ifdef ALTRIGHT
1128 case ALTRIGHT:
1129 case ALTRIGHT | BUTTON_REPEAT:
1130 #endif
1131 if(xoffset+maxX > LCD_WIDTH)
1132 xoffset-=2;
1133 break;
1134 case UP:
1135 case UP | BUTTON_REPEAT:
1136 if(yoffset <0)
1137 yoffset+=2;
1138 break;
1139 case DOWN:
1140 case DOWN | BUTTON_REPEAT:
1141 if(yoffset+maxY > LCD_HEIGHT)
1142 yoffset-=2;
1143 break;
1145 default:
1146 if(rb->default_event_handler(button) == SYS_USB_CONNECTED)
1147 return 1;
1148 break;
1151 return 0;
1154 int pad_check(int ballxc, int mode, int pon ,int ballnum)
1156 /* pon: positive(1) or negative(0) */
1158 if (mode==0) {
1159 if (pon == 0)
1160 return -ballxc;
1161 else
1162 return ballxc;
1163 } else {
1164 if (ball[ballnum].x > 0)
1165 return ballxc;
1166 else
1167 return ballxc*-1;
1171 int fire_space(void)
1173 int t;
1174 for(t=0;t<=30;t++)
1175 if (fire[t].top+7 < 0)
1176 return t;
1178 return 0;
1181 int game_loop(void)
1183 int j,i,k,bricky,brickx;
1184 char s[30];
1185 int sec_count=0,num_count=10;
1186 int end;
1188 rb->srand( *rb->current_tick );
1190 configfile_init(rb);
1191 configfile_load(HIGH_SCORE,config,1,0);
1193 switch(game_menu(0)) {
1194 case 0:
1195 cur_level = 0;
1196 life = 2;
1197 int_game(1);
1198 break;
1199 case 1:
1200 con_game = 1;
1201 break;
1202 case 2:
1203 if (help(0) == 1) return 1;
1204 break;
1205 case 3:
1206 return 1;
1207 break;
1210 while(true) {
1211 /* Convert CYCLETIME (in ms) to HZ */
1212 end = *rb->current_tick + (CYCLETIME * HZ) / 1000;
1214 if (life >= 0) {
1215 #ifdef HAVE_LCD_COLOR
1216 rb->lcd_set_background(LCD_BLACK);
1217 rb->lcd_set_drawmode(DRMODE_SOLID);
1218 rb->lcd_clear_display();
1219 rb->lcd_set_background(LCD_BLACK);
1220 #if LCD_HEIGHT > GAMESCREEN_HEIGHT
1221 rb->lcd_set_foreground(rb->global_settings->bg_color);
1222 rb->lcd_fillrect(0, GAMESCREEN_HEIGHT, LCD_WIDTH,
1223 LCD_HEIGHT - GAMESCREEN_HEIGHT);
1224 #endif
1225 rb->lcd_set_foreground(LCD_WHITE);
1226 #else
1227 rb->lcd_clear_display();
1228 #endif
1230 if (flip_sides) {
1231 if (*rb->current_tick>=sec_count) {
1232 sec_count=*rb->current_tick+HZ;
1233 if (num_count!=0)
1234 num_count--;
1235 else
1236 flip_sides=false;
1238 rb->snprintf(s, sizeof(s), "%d", num_count);
1239 rb->lcd_getstringsize(s, &sw, NULL);
1240 rb->lcd_putsxy(LCD_WIDTH/2-2, STRINGPOS_FLIP, s);
1243 /* write life num */
1244 #if (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
1245 rb->snprintf(s, sizeof(s), "L:%d", life);
1246 rb->lcd_putsxy(0, 0, s);
1247 #else
1248 rb->snprintf(s, sizeof(s), "Life: %d", life);
1249 rb->lcd_putsxy(2, 2, s);
1250 #endif
1252 #if (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
1253 rb->snprintf(s, sizeof(s), "L%d", cur_level+1);
1254 rb->lcd_getstringsize(s, &sw, NULL);
1255 rb->lcd_putsxy(LCD_WIDTH-sw, 0, s);
1256 #else
1257 rb->snprintf(s, sizeof(s), "Level %d", cur_level+1);
1258 rb->lcd_getstringsize(s, &sw, NULL);
1259 rb->lcd_putsxy(LCD_WIDTH-sw-2, 2, s);
1260 #endif
1262 if (vscore<score) vscore++;
1263 rb->snprintf(s, sizeof(s), "%d", vscore);
1264 rb->lcd_getstringsize(s, &sw, NULL);
1265 #if (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
1266 rb->lcd_putsxy(LCD_WIDTH/2-sw/2, 0, s);
1267 #else
1268 rb->lcd_putsxy(LCD_WIDTH/2-sw/2, 2, s);
1269 #endif
1271 /* continue game */
1272 if (con_game== 1 && start_game!=1) {
1273 #if CONFIG_KEYPAD == ONDIO_PAD
1274 rb->snprintf(s, sizeof(s), "MENU To Continue");
1275 #elif CONFIG_KEYPAD == IRIVER_H300_PAD
1276 rb->snprintf(s, sizeof(s), "Press NAVI To Continue");
1277 #else
1278 rb->snprintf(s, sizeof(s), "Press SELECT To Continue");
1279 #endif
1280 rb->lcd_getstringsize(s, &sw, NULL);
1281 rb->lcd_putsxy(LCD_WIDTH/2-sw/2, STRINGPOS_NAVI, s);
1283 sec_count=*rb->current_tick+HZ;
1286 /* draw the ball */
1287 for(i=0;i<used_balls;i++)
1288 rb->lcd_bitmap(brickmania_ball,ball[i].pos_x, ball[i].pos_y,
1289 BALL, BALL);
1291 if (brick_on_board==0)
1292 brick_on_board--;
1294 /* if the pad is fire */
1295 for(i=0;i<=30;i++) {
1296 if (fire[i].top+7>0) {
1297 if (con_game!=1)
1298 fire[i].top-=4;
1299 rb->lcd_vline(fire[i].left, fire[i].top, fire[i].top+7);
1303 /* the bricks */
1304 for (i=0;i<=7;i++) {
1305 for (j=0;j<=9;j++) {
1306 if (brick[i*10+j].power<7) {
1307 if (brick[i*10+j].poweruse==2) {
1308 if (con_game!=1)
1309 brick[i*10+j].powertop+=2;
1310 rb->lcd_bitmap_part(brickmania_powerups,0,
1311 POWERUP_HEIGHT*brick[i*10+j
1312 ].power,
1313 POWERUP_WIDTH,
1314 LEFTMARGIN+j*BRICK_WIDTH+
1315 (BRICK_WIDTH/2-
1316 POWERUP_WIDTH/2),
1317 brick[i*10+j].powertop,
1318 POWERUP_WIDTH,
1319 POWERUP_HEIGHT);
1323 if ((pad_pos_x<LEFTMARGIN+j*BRICK_WIDTH+5 &&
1324 pad_pos_x+PAD_WIDTH>LEFTMARGIN+j*BRICK_WIDTH+5) &&
1325 brick[i*10+j].powertop+6>=PAD_POS_Y &&
1326 brick[i*10+j].poweruse==2) {
1327 switch(brick[i*10+j].power) {
1328 case 0:
1329 life++;
1330 score+=50;
1331 break;
1332 case 1:
1333 life--;
1334 if (life>=0) {
1335 int_game(0);
1336 sleep(2);
1338 break;
1339 case 2:
1340 score+=34;
1341 pad_type=1;
1342 break;
1343 case 3:
1344 score+=47;
1345 pad_type=2;
1346 for(k=0;k<used_balls;k++)
1347 ball[k].glue=false;
1348 break;
1349 case 4:
1350 score+=23;
1351 pad_type=0;
1352 for(k=0;k<used_balls;k++)
1353 ball[k].glue=false;
1354 flip_sides=false;
1355 break;
1356 case 5:
1357 score+=23;
1358 sec_count=*rb->current_tick+HZ;
1359 num_count=10;
1360 flip_sides=!flip_sides;
1361 break;
1362 case 6:
1363 score+=23;
1364 used_balls++;
1365 ball[used_balls-1].x= rb->rand()%1 == 0 ?
1366 -1 : 1;
1367 ball[used_balls-1].y= -4;
1368 break;
1370 brick[i*10+j].poweruse=1;
1373 if (brick[i*10+j].powertop>PAD_POS_Y)
1374 brick[i*10+j].poweruse=1;
1376 brickx=LEFTMARGIN+j*BRICK_WIDTH;
1377 bricky=TOPMARGIN+i*BRICK_HEIGHT;
1378 if (pad_type==2) {
1379 for (k=0;k<=30;k++) {
1380 if (fire[k].top+7>0) {
1381 if (brick[i*10+j].used==1 &&
1382 (fire[k].left+1 >= brickx &&
1383 fire[k].left+1 <= brickx+BRICK_WIDTH) &&
1384 (bricky+BRICK_HEIGHT>fire[k].top)) {
1385 score+=13;
1386 fire[k].top=-16;
1387 if (brick[i*10+j].hits > 0) {
1388 brick[i*10+j].hits--;
1389 brick[i*10+j].hiteffect++;
1390 score+=3;
1392 else {
1393 brick[i*10+j].used=0;
1394 if (brick[i*10+j].power!=10)
1395 brick[i*10+j].poweruse=2;
1396 brick_on_board--;
1403 if (brick[i*10+j].used==1) {
1404 rb->lcd_bitmap_part(brickmania_bricks,0,
1405 BRICK_HEIGHT*brick[i*10+j].color,
1406 BRICK_WIDTH,
1407 LEFTMARGIN+j*BRICK_WIDTH,
1408 TOPMARGIN+i*BRICK_HEIGHT,
1409 BRICK_WIDTH, BRICK_HEIGHT);
1410 #ifdef HAVE_LCD_COLOR /* No transparent effect for greyscale lcds for now */
1411 if (brick[i*10+j].hiteffect>0)
1412 rb->lcd_bitmap_transparent_part(brickmania_break,
1414 BRICK_HEIGHT*brick[i*10+j].hiteffect,
1415 BRICK_WIDTH,
1416 LEFTMARGIN+j*BRICK_WIDTH,
1417 TOPMARGIN+i*BRICK_HEIGHT,
1418 BRICK_WIDTH,
1419 BRICK_HEIGHT);
1420 #endif
1423 for(k=0;k<used_balls;k++) {
1424 if (ball[k].pos_y <160) {
1425 if (brick[i*10+j].used==1) {
1426 if ((ball[k].pos_x+ball[k].x+HALFBALL >=
1427 brickx &&
1428 ball[k].pos_x+ball[k].x+HALFBALL <=
1429 brickx+BRICK_WIDTH) &&
1430 ((bricky-4<ball[k].pos_y+BALL &&
1431 bricky>ball[k].pos_y+BALL) ||
1432 (bricky+4>ball[k].pos_y+BALL+BALL &&
1433 bricky<ball[k].pos_y+BALL+BALL)) &&
1434 (ball[k].y >0)) {
1435 ball[k].tempy=bricky-ball[k].pos_y-BALL;
1437 else if ((ball[k].pos_x+ball[k].x+HALFBALL >=
1438 brickx &&
1439 ball[k].pos_x+ball[k].x+HALFBALL <=
1440 brickx+BRICK_WIDTH) &&
1441 ((bricky+BRICK_HEIGHT+4>ball[k].pos_y &&
1442 bricky+BRICK_HEIGHT<ball[k].pos_y) ||
1443 (bricky+BRICK_HEIGHT-4<ball[k].pos_y-BALL &&
1444 bricky+BRICK_HEIGHT>ball[k].pos_y-BALL)) &&
1445 (ball[k].y <0)) {
1446 ball[k].tempy=
1447 -(ball[k].pos_y-(bricky+BRICK_HEIGHT));
1450 if ((ball[k].pos_y+HALFBALL >=
1451 bricky &&
1452 ball[k].pos_y+HALFBALL <=
1453 bricky+BRICK_HEIGHT) &&
1454 ((brickx-4<ball[k].pos_x+BALL &&
1455 brickx>ball[k].pos_x+BALL) ||
1456 (brickx+4>ball[k].pos_x+BALL+BALL &&
1457 brickx<ball[k].pos_x+BALL+BALL)) &&
1458 (ball[k].x >0)) {
1459 ball[k].tempx=brickx-ball[k].pos_x-BALL;
1461 else if ((ball[k].pos_y+ball[k].y+HALFBALL >=
1462 bricky &&
1463 ball[k].pos_y+ball[k].y+HALFBALL <=
1464 bricky+BRICK_HEIGHT) &&
1465 ((brickx+BRICK_WIDTH+4>ball[k].pos_x &&
1466 brickx+BRICK_WIDTH<ball[k].pos_x) ||
1467 (brickx+BRICK_WIDTH-4<ball[k].pos_x-
1468 BALL &&
1469 brickx+BRICK_WIDTH>ball[k].pos_x-
1470 BALL)) && (ball[k].x <0)) {
1471 ball[k].tempx=
1472 -(ball[k].pos_x-(brickx+BRICK_WIDTH));
1475 if ((ball[k].pos_x+HALFBALL >= brickx &&
1476 ball[k].pos_x+HALFBALL <=
1477 brickx+BRICK_WIDTH) &&
1478 ((bricky+BRICK_HEIGHT==ball[k].pos_y) ||
1479 (bricky+BRICK_HEIGHT-6<=ball[k].pos_y &&
1480 bricky+BRICK_HEIGHT>ball[k].pos_y)) &&
1481 (ball[k].y <0)) { /* bottom line */
1482 if (brick[i*10+j].hits > 0) {
1483 brick[i*10+j].hits--;
1484 brick[i*10+j].hiteffect++;
1485 score+=2;
1487 else {
1488 brick[i*10+j].used=0;
1489 if (brick[i*10+j].power!=10)
1490 brick[i*10+j].poweruse=2;
1493 ball[k].y = ball[k].y*-1;
1495 else if ((ball[k].pos_x+HALFBALL >= brickx &&
1496 ball[k].pos_x+HALFBALL <=
1497 brickx+BRICK_WIDTH) &&
1498 ((bricky==ball[k].pos_y+BALL) ||
1499 (bricky+6>=ball[k].pos_y+BALL &&
1500 bricky<ball[k].pos_y+BALL)) &&
1501 (ball[k].y >0)) { /* top line */
1502 if (brick[i*10+j].hits > 0) {
1503 brick[i*10+j].hits--;
1504 brick[i*10+j].hiteffect++;
1505 score+=2;
1507 else {
1508 brick[i*10+j].used=0;
1509 if (brick[i*10+j].power!=10)
1510 brick[i*10+j].poweruse=2;
1513 ball[k].y = ball[k].y*-1;
1516 if ((ball[k].pos_y+HALFBALL >= bricky &&
1517 ball[k].pos_y+HALFBALL <=
1518 bricky+BRICK_HEIGHT) &&
1519 ((brickx==ball[k].pos_x+BALL) ||
1520 (brickx+6>=ball[k].pos_x+BALL &&
1521 brickx<ball[k].pos_x+BALL)) &&
1522 (ball[k].x > 0)) { /* left line */
1523 if (brick[i*10+j].hits > 0) {
1524 brick[i*10+j].hits--;
1525 brick[i*10+j].hiteffect++;
1526 score+=2;
1528 else {
1529 brick[i*10+j].used=0;
1530 if (brick[i*10+j].power!=10)
1531 brick[i*10+j].poweruse=2;
1533 ball[k].x = ball[k].x*-1;
1536 else if ((ball[k].pos_y+HALFBALL >= bricky &&
1537 ball[k].pos_y+HALFBALL <=
1538 bricky+BRICK_HEIGHT) &&
1539 ((brickx+BRICK_WIDTH==
1540 ball[k].pos_x) ||
1541 (brickx+BRICK_WIDTH-6<=
1542 ball[k].pos_x &&
1543 brickx+BRICK_WIDTH>
1544 ball[k].pos_x)) &&
1545 (ball[k].x < 0)) { /* Right line */
1546 if (brick[i*10+j].hits > 0) {
1547 brick[i*10+j].hits--;
1548 brick[i*10+j].hiteffect++;
1549 score+=2;
1551 else {
1552 brick[i*10+j].used=0;
1553 if (brick[i*10+j].power!=10)
1554 brick[i*10+j].poweruse=2;
1557 ball[k].x = ball[k].x*-1;
1560 if (brick[i*10+j].used==0) {
1561 brick_on_board--;
1562 score+=8;
1566 } /* for k */
1567 } /* for j */
1568 } /* for i */
1570 /* draw the pad */
1571 rb->lcd_bitmap_part(brickmania_pads,0,pad_type*PAD_HEIGHT,
1572 PAD_WIDTH,pad_pos_x, PAD_POS_Y, PAD_WIDTH,
1573 PAD_HEIGHT);
1575 for(k=0;k<used_balls;k++) {
1577 if ((ball[k].pos_x >= pad_pos_x &&
1578 ball[k].pos_x <= pad_pos_x+PAD_WIDTH) &&
1579 (PAD_POS_Y-4<ball[k].pos_y+BALL &&
1580 PAD_POS_Y>ball[k].pos_y+BALL) && (ball[k].y >0))
1581 ball[k].tempy=PAD_POS_Y-ball[k].pos_y-BALL;
1582 else if ((4>ball[k].pos_y && 0<ball[k].pos_y) &&
1583 (ball[k].y <0))
1584 ball[k].tempy=-ball[k].pos_y;
1585 if ((LCD_WIDTH-4<ball[k].pos_x+BALL &&
1586 LCD_WIDTH>ball[k].pos_x+BALL) && (ball[k].x >0))
1587 ball[k].tempx=LCD_WIDTH-ball[k].pos_x-BALL;
1588 else if ((4>ball[k].pos_x && 0<ball[k].pos_x) &&
1589 (ball[k].x <0))
1590 ball[k].tempx=-ball[k].pos_x;
1592 /* top line */
1593 if (ball[k].pos_y<= 0)
1594 ball[k].y = ball[k].y*-1;
1595 /* bottom line */
1596 else if (ball[k].pos_y+BALL >= GAMESCREEN_HEIGHT) {
1597 if (used_balls>1) {
1598 used_balls--;
1599 ball[k].pos_x = ball[used_balls].pos_x;
1600 ball[k].pos_y = ball[used_balls].pos_y;
1601 ball[k].y = ball[used_balls].y;
1602 ball[k].tempy = ball[used_balls].tempy;
1603 ball[k].x = ball[used_balls].x;
1604 ball[k].tempx = ball[used_balls].tempx;
1605 ball[k].glue = ball[used_balls].glue;
1607 ball[used_balls].x=0;
1608 ball[used_balls].y=0;
1609 ball[used_balls].tempy=0;
1610 ball[used_balls].tempx=0;
1611 ball[used_balls].pos_y=PAD_POS_Y-BALL;
1612 ball[used_balls].pos_x=pad_pos_x+(PAD_WIDTH/2)-2;
1614 k--;
1615 continue;
1616 } else {
1617 life--;
1618 if (life>=0) {
1619 int_game(0);
1620 sleep(2);
1625 /* left line ,right line */
1626 if ((ball[k].pos_x <= 0) ||
1627 (ball[k].pos_x+BALL >= LCD_WIDTH)) {
1628 ball[k].x = ball[k].x*-1;
1629 ball[k].pos_x = ball[k].pos_x <= 0 ? 0 : LCD_WIDTH-BALL;
1632 if ((ball[k].pos_y+BALL >= PAD_POS_Y &&
1633 (ball[k].pos_x >= pad_pos_x &&
1634 ball[k].pos_x <= pad_pos_x+PAD_WIDTH)) &&
1635 start_game != 1 && !ball[k].glue) {
1637 if ((ball[k].pos_x+HALFBALL >= pad_pos_x &&
1638 ball[k].pos_x+HALFBALL <=
1639 pad_pos_x+(PAD_WIDTH/2/4)) ||
1640 (ball[k].pos_x +HALFBALL>=
1641 pad_pos_x+(PAD_WIDTH-(PAD_WIDTH/2/4)) &&
1642 ball[k].pos_x+HALFBALL <= pad_pos_x+PAD_WIDTH)) {
1644 ball[k].y = -2;
1645 if (ball[k].pos_x != 0 &&
1646 ball[k].pos_x+BALL!=LCD_WIDTH)
1647 ball[k].x = pad_check(6,0,ball[k].pos_x+2<=
1648 pad_pos_x+(PAD_WIDTH/2)?
1649 0:1,k);
1652 else if ((ball[k].pos_x+HALFBALL >=
1653 pad_pos_x+(PAD_WIDTH/2/4) &&
1654 ball[k].pos_x+HALFBALL <=
1655 pad_pos_x+2*(PAD_WIDTH/2/4)) ||
1656 (ball[k].pos_x+HALFBALL >=
1657 pad_pos_x+(PAD_WIDTH-2*(PAD_WIDTH/2/4)) &&
1658 ball[k].pos_x+HALFBALL <=
1659 pad_pos_x+(PAD_WIDTH-(PAD_WIDTH/2/4)) )) {
1661 ball[k].y = -3;
1662 if (ball[k].pos_x != 0 &&
1663 ball[k].pos_x+BALL!=LCD_WIDTH)
1664 ball[k].x = pad_check(4,0,ball[k].pos_x+2<=
1665 pad_pos_x+(PAD_WIDTH/2)?
1666 0:1,k);
1669 else if ((ball[k].pos_x+HALFBALL >=
1670 pad_pos_x+2*(PAD_WIDTH/2/4) &&
1671 ball[k].pos_x+HALFBALL <=
1672 pad_pos_x+3*(PAD_WIDTH/2/4)) ||
1673 (ball[k].pos_x+2 >=
1674 pad_pos_x+(PAD_WIDTH-3*(PAD_WIDTH/2/4)) &&
1675 ball[k].pos_x+2 <=
1676 pad_pos_x+ ((PAD_WIDTH/2)-2*(PAD_WIDTH/2/4)) )) {
1678 ball[k].y = -4;
1679 if (ball[k].pos_x != 0 &&
1680 ball[k].pos_x+BALL!=LCD_WIDTH)
1681 ball[k].x = pad_check(3,0,ball[k].pos_x+2<=
1682 pad_pos_x+(PAD_WIDTH/2)?
1683 0:1,k);
1686 else if ((ball[k].pos_x+HALFBALL >=
1687 pad_pos_x+3*(PAD_WIDTH/2/4) &&
1688 ball[k].pos_x+HALFBALL <=
1689 pad_pos_x+4*(PAD_WIDTH/2/4)-2) ||
1690 (ball[k].pos_x+2 >= pad_pos_x+(PAD_WIDTH/2+2) &&
1691 ball[k].pos_x+2 <=
1692 pad_pos_x+(PAD_WIDTH-3*(PAD_WIDTH/2/4)) )) {
1694 ball[k].y = -4;
1695 if (ball[k].pos_x != 0 &&
1696 ball[k].pos_x+BALL!=LCD_WIDTH)
1697 ball[k].x = pad_check(2,1,0,k);
1700 else {
1701 ball[k].y = -4;
1705 if (!ball[k].glue) {
1706 ball[k].pos_x+=ball[k].tempx!=0?ball[k].tempx:ball[k].x;
1707 ball[k].pos_y+=ball[k].tempy!=0?ball[k].tempy:ball[k].y;
1709 ball[k].tempy=0;
1710 ball[k].tempx=0;
1713 if (ball[k].pos_y+5 >= PAD_POS_Y &&
1714 (pad_type==1 && !ball[k].glue) &&
1715 (ball[k].pos_x >= pad_pos_x &&
1716 ball[k].pos_x <= pad_pos_x+PAD_WIDTH)) {
1717 ball[k].y=0;
1718 ball[k].pos_y=PAD_POS_Y-BALL;
1719 ball[k].glue=true;
1721 } /* for k */
1723 rb->lcd_update();
1725 if (brick_on_board < 0) {
1726 if (cur_level+1<levels_num) {
1727 cur_level++;
1728 score+=100;
1729 int_game(1);
1730 sleep(2);
1732 else {
1733 rb->lcd_getstringsize("Congratulations!", &sw, NULL);
1734 rb->lcd_putsxy(LCD_WIDTH/2-sw/2, STRINGPOS_CONGRATS,
1735 "Congratulations!");
1736 #if (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
1737 rb->lcd_getstringsize("No more levels", &sw, NULL);
1738 rb->lcd_putsxy(LCD_WIDTH/2-sw/2, STRINGPOS_FINISH,
1739 "No more levels");
1740 #else
1741 rb->lcd_getstringsize("You have finished the game!",
1742 &sw, NULL);
1743 rb->lcd_putsxy(LCD_WIDTH/2-sw/2, STRINGPOS_FINISH,
1744 "You have finished the game!");
1745 #endif
1746 vscore=score;
1747 rb->lcd_update();
1748 if (score>highscore) {
1749 sleep(2);
1750 highscore=score;
1751 rb->splash(HZ*2, "New High Score");
1753 else {
1754 sleep(3);
1757 switch(game_menu(0)) {
1758 case 0:
1759 life=2;
1760 cur_level=0;
1761 int_game(1);
1762 break;
1763 case 1:
1764 con_game=1;
1765 break;
1766 case 2:
1767 if (help(0)==1) return 1;
1768 break;
1769 case 3:
1770 return 1;
1771 break;
1776 int move_button,button;
1777 int button_right,button_left;
1778 button=rb->button_get(false);
1780 #ifdef HAS_BUTTON_HOLD
1781 if (rb->button_hold())
1782 button = QUIT;
1783 #endif
1785 move_button=rb->button_status();
1786 #ifdef ALTRIGHT
1787 button_right=((move_button & RIGHT) || (move_button & ALTRIGHT));
1788 button_left=((move_button & LEFT) || (move_button & ALTLEFT));
1789 #else
1790 button_right=((move_button & RIGHT) || (SCROLL_FWD(button)));
1791 button_left=((move_button & LEFT) || (SCROLL_BACK(button)));
1792 #endif
1793 if ((con_game== 1 && start_game!=1) && (button_right || button_left))
1794 continue;
1795 if ((button_right && flip_sides==false) ||
1796 (button_left && flip_sides==true)) {
1797 if (pad_pos_x+8+PAD_WIDTH > LCD_WIDTH) {
1798 for(k=0;k<used_balls;k++)
1799 if (start_game==1 || ball[k].glue)
1800 ball[k].pos_x+=LCD_WIDTH-pad_pos_x-PAD_WIDTH;
1801 pad_pos_x+=LCD_WIDTH-pad_pos_x-PAD_WIDTH;
1803 else {
1804 for(k=0;k<used_balls;k++)
1805 if ((start_game==1 || ball[k].glue))
1806 ball[k].pos_x+=8;
1807 pad_pos_x+=8;
1810 else if ((button_left && flip_sides==false) ||
1811 (button_right && flip_sides==true)) {
1812 if (pad_pos_x-8 < 0) {
1813 for(k=0;k<used_balls;k++)
1814 if (start_game==1 || ball[k].glue)
1815 ball[k].pos_x-=pad_pos_x;
1816 pad_pos_x-=pad_pos_x;
1818 else {
1819 for(k=0;k<used_balls;k++)
1820 if (start_game==1 || ball[k].glue)
1821 ball[k].pos_x-=8;
1822 pad_pos_x-=8;
1827 switch(button) {
1828 case UP:
1829 case SELECT:
1830 if (start_game==1 && con_game!=1 && pad_type!=1) {
1831 for(k=0;k<used_balls;k++) {
1832 ball[k].y=-4;
1833 ball[k].x=pad_pos_x+(PAD_WIDTH/2)-2>=
1834 LCD_WIDTH/2?2:-2;
1836 start_game =0;
1838 else if (pad_type==1) {
1839 for(k=0;k<used_balls;k++) {
1840 if (ball[k].glue)
1841 ball[k].glue=false;
1842 else if (start_game==1) {
1843 ball[k].x = x[k];
1844 ball[k].y = y[k];
1848 if (start_game!=1 && con_game==1) {
1849 start_game =0;
1850 con_game=0;
1852 } else if (pad_type==2 && con_game!=1) {
1853 int tfire;
1854 tfire=fire_space();
1855 fire[tfire].top=PAD_POS_Y-7;
1856 fire[tfire].left=pad_pos_x+1;
1857 tfire=fire_space();
1858 fire[tfire].top=PAD_POS_Y-7;
1859 fire[tfire].left=pad_pos_x+PAD_WIDTH-1;
1860 } else if (con_game==1 && start_game!=1) {
1861 for(k=0;k<used_balls;k++) {
1862 ball[k].x=x[k];
1863 ball[k].y=y[k];
1865 con_game=0;
1867 break;
1868 #ifdef RC_QUIT
1869 case RC_QUIT:
1870 #endif
1871 case QUIT:
1872 switch(game_menu(1)) {
1873 case 0:
1874 life=2;
1875 cur_level=0;
1876 int_game(1);
1877 break;
1878 case 1:
1879 for(k=0;k<used_balls;k++)
1880 if (ball[k].x!=0 && ball[k].y !=0)
1881 con_game=1;
1882 break;
1883 case 2:
1884 if (help(1)==1)
1885 return 1;
1886 break;
1887 case 3:
1888 return 1;
1889 break;
1892 for(k=0;k<used_balls;k++) {
1893 if (ball[k].x!=0)
1894 x[k]=ball[k].x;
1895 ball[k].x=0;
1896 if (ball[k].y!=0)
1897 y[k]=ball[k].y;
1898 ball[k].y=0;
1901 break;
1903 default:
1904 if(rb->default_event_handler(button) == SYS_USB_CONNECTED)
1905 return 1;
1906 break;
1909 else {
1910 #ifdef HAVE_LCD_COLOR
1911 rb->lcd_bitmap_transparent(brickmania_gameover,
1912 (LCD_WIDTH - GAMEOVER_WIDTH)/2,
1913 (GAMESCREEN_HEIGHT - GAMEOVER_HEIGHT)/2,
1914 GAMEOVER_WIDTH,GAMEOVER_HEIGHT);
1915 #else /* greyscale and mono */
1916 rb->lcd_bitmap(brickmania_gameover,(LCD_WIDTH - GAMEOVER_WIDTH)/2,
1917 (GAMESCREEN_HEIGHT - GAMEOVER_HEIGHT)/2,
1918 GAMEOVER_WIDTH,GAMEOVER_HEIGHT);
1919 #endif
1920 rb->lcd_update();
1921 if (score>highscore) {
1922 sleep(2);
1923 highscore=score;
1924 rb->splash(HZ*2, "New High Score");
1925 } else {
1926 sleep(3);
1929 for(k=0;k<used_balls;k++) {
1930 ball[k].x=0;
1931 ball[k].y=0;
1934 switch(game_menu(0)) {
1935 case 0:
1936 cur_level=0;
1937 life=2;
1938 int_game(1);
1939 break;
1940 case 1:
1941 con_game=1;
1942 break;
1943 case 2:
1944 if (help(0)==1)
1945 return 1;
1946 break;
1947 case 3:
1948 return 1;
1949 break;
1952 if (end > *rb->current_tick)
1953 rb->sleep(end-*rb->current_tick);
1954 else
1955 rb->yield();
1959 /* this is the plugin entry point */
1960 enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
1962 (void)parameter;
1963 rb = api;
1965 rb->lcd_setfont(FONT_SYSFIXED);
1966 #if LCD_DEPTH > 1
1967 rb->lcd_set_backdrop(NULL);
1968 #endif
1969 /* Turn off backlight timeout */
1970 backlight_force_on(rb); /* backlight control in lib/helper.c */
1972 /* now go ahead and have fun! */
1973 while (game_loop()!=1);
1975 configfile_save(HIGH_SCORE,config,1,0);
1977 /* Restore user's original backlight setting */
1978 rb->lcd_setfont(FONT_UI);
1979 /* Turn on backlight timeout (revert to settings) */
1980 backlight_use_settings(rb); /* backlight control in lib/helper.c */
1982 return PLUGIN_OK;