FS#8961 - Anti-Aliased Fonts.
[kugel-rb.git] / apps / plugins / brickmania.c
blobd033cb19a0976b8932ad097a4c018c5e398017b4
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2005, 2006 Ben Basha (Paprica)
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include "plugin.h"
23 #include "lib/configfile.h"
24 #include "lib/display_text.h"
25 #include "lib/helper.h"
26 #include "lib/highscore.h"
27 #include "lib/playback_control.h"
29 PLUGIN_HEADER
31 #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
32 (CONFIG_KEYPAD == IRIVER_H300_PAD)
33 #define QUIT BUTTON_OFF
34 #define LEFT BUTTON_LEFT
35 #define RIGHT BUTTON_RIGHT
36 #define SELECT BUTTON_SELECT
37 #define UP BUTTON_UP
38 #define DOWN BUTTON_DOWN
39 #define RC_QUIT BUTTON_RC_STOP
41 #elif CONFIG_KEYPAD == ONDIO_PAD
42 #define QUIT BUTTON_OFF
43 #define LEFT BUTTON_LEFT
44 #define RIGHT BUTTON_RIGHT
45 #define SELECT BUTTON_MENU
46 #define UP BUTTON_UP
47 #define DOWN BUTTON_DOWN
49 #elif CONFIG_KEYPAD == RECORDER_PAD
50 #define QUIT BUTTON_OFF
51 #define LEFT BUTTON_LEFT
52 #define RIGHT BUTTON_RIGHT
53 #define SELECT BUTTON_PLAY
54 #define UP BUTTON_UP
55 #define DOWN BUTTON_DOWN
57 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
58 #define QUIT BUTTON_OFF
59 #define LEFT BUTTON_LEFT
60 #define RIGHT BUTTON_RIGHT
61 #define SELECT BUTTON_SELECT
62 #define UP BUTTON_UP
63 #define DOWN BUTTON_DOWN
65 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
66 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
67 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
68 #define QUIT BUTTON_MENU
69 #define LEFT BUTTON_LEFT
70 #define RIGHT BUTTON_RIGHT
71 #define SELECT BUTTON_SELECT
72 #define UP BUTTON_SCROLL_BACK
73 #define DOWN BUTTON_SCROLL_FWD
74 #define SCROLL_FWD(x) ((x) & BUTTON_SCROLL_FWD)
75 #define SCROLL_BACK(x) ((x) & BUTTON_SCROLL_BACK)
77 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
78 #define QUIT BUTTON_POWER
79 #define LEFT BUTTON_LEFT
80 #define RIGHT BUTTON_RIGHT
81 #define SELECT BUTTON_SELECT
82 #define UP BUTTON_UP
83 #define DOWN BUTTON_DOWN
85 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
86 #define QUIT BUTTON_POWER
87 #define LEFT BUTTON_LEFT
88 #define RIGHT BUTTON_RIGHT
89 #define SELECT BUTTON_PLAY
90 #define UP BUTTON_UP
91 #define DOWN BUTTON_DOWN
93 #elif (CONFIG_KEYPAD == SANSA_E200_PAD)
94 #define QUIT BUTTON_POWER
95 #define LEFT BUTTON_LEFT
96 #define RIGHT BUTTON_RIGHT
97 #define SELECT BUTTON_SELECT
98 #define UP BUTTON_UP
99 #define DOWN BUTTON_DOWN
100 #define SCROLL_FWD(x) ((x) & BUTTON_SCROLL_FWD)
101 #define SCROLL_BACK(x) ((x) & BUTTON_SCROLL_BACK)
104 #elif (CONFIG_KEYPAD == SANSA_FUZE_PAD)
105 #define QUIT (BUTTON_HOME|BUTTON_REPEAT)
106 #define LEFT BUTTON_LEFT
107 #define RIGHT BUTTON_RIGHT
108 #define SELECT BUTTON_SELECT
109 #define UP BUTTON_UP
110 #define DOWN BUTTON_DOWN
112 #define SCROLL_FWD(x) ((x) & BUTTON_SCROLL_FWD)
113 #define SCROLL_BACK(x) ((x) & BUTTON_SCROLL_BACK)
116 #elif CONFIG_KEYPAD == SANSA_C200_PAD || \
117 CONFIG_KEYPAD == SANSA_CLIP_PAD || \
118 CONFIG_KEYPAD == SANSA_M200_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
128 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
129 #define QUIT BUTTON_POWER
130 #define LEFT BUTTON_LEFT
131 #define RIGHT BUTTON_RIGHT
132 #define SELECT BUTTON_PLAY
133 #define UP BUTTON_SCROLL_UP
134 #define DOWN BUTTON_SCROLL_DOWN
136 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
137 #define QUIT BUTTON_BACK
138 #define LEFT BUTTON_LEFT
139 #define RIGHT BUTTON_RIGHT
140 #define SELECT BUTTON_SELECT
141 #define UP BUTTON_UP
142 #define DOWN BUTTON_DOWN
144 #elif (CONFIG_KEYPAD == MROBE100_PAD)
145 #define QUIT BUTTON_POWER
146 #define LEFT BUTTON_LEFT
147 #define RIGHT BUTTON_RIGHT
148 #define SELECT BUTTON_SELECT
149 #define UP BUTTON_UP
150 #define DOWN BUTTON_DOWN
152 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
153 #define QUIT BUTTON_RC_REC
154 #define LEFT BUTTON_RC_REW
155 #define RIGHT BUTTON_RC_FF
156 #define SELECT BUTTON_RC_PLAY
157 #define UP BUTTON_RC_VOL_UP
158 #define DOWN BUTTON_RC_VOL_DOWN
159 #define RC_QUIT BUTTON_REC
161 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
162 #define QUIT BUTTON_BACK
163 #define LEFT BUTTON_LEFT
164 #define RIGHT BUTTON_RIGHT
165 #define SELECT BUTTON_SELECT
166 #define UP BUTTON_UP
167 #define DOWN BUTTON_DOWN
169 #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
170 #define QUIT BUTTON_POWER
171 #define LEFT BUTTON_LEFT
172 #define RIGHT BUTTON_RIGHT
173 #define SELECT BUTTON_SELECT
174 #define UP BUTTON_UP
175 #define DOWN BUTTON_DOWN
177 #elif CONFIG_KEYPAD == COWOND2_PAD
178 #define QUIT BUTTON_POWER
180 #elif CONFIG_KEYPAD == ONDAVX747_PAD
181 #define QUIT BUTTON_POWER
182 #define LEFT BUTTON_VOL_DOWN
183 #define RIGHT BUTTON_VOL_UP
184 #define SELECT BUTTON_MENU
186 #elif CONFIG_KEYPAD == MROBE500_PAD
187 #define QUIT BUTTON_POWER
189 #elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
190 #define QUIT BUTTON_FFWD
191 #define SELECT BUTTON_PLAY
192 #define LEFT BUTTON_LEFT
193 #define RIGHT BUTTON_RIGHT
194 #define UP BUTTON_UP
195 #define DOWN BUTTON_DOWN
198 #else
199 #error No keymap defined!
200 #endif
202 #ifdef HAVE_TOUCHSCREEN
203 #ifndef LEFT
204 #define LEFT BUTTON_MIDLEFT
205 #endif
206 #ifndef RIGHT
207 #define RIGHT BUTTON_MIDRIGHT
208 #endif
209 #ifndef SELECT
210 #define SELECT BUTTON_CENTER
211 #endif
212 #ifndef UP
213 #define UP BUTTON_TOPMIDDLE
214 #endif
215 #ifndef DOWN
216 #define DOWN BUTTON_BOTTOMMIDDLE
217 #endif
218 #endif
220 #ifndef SCROLL_FWD /* targets without scroll wheel*/
221 #define SCROLL_FWD(x) (0)
222 #define SCROLL_BACK(x) (0)
223 #endif
225 #include "pluginbitmaps/brickmania_pads.h"
226 #include "pluginbitmaps/brickmania_short_pads.h"
227 #include "pluginbitmaps/brickmania_long_pads.h"
228 #include "pluginbitmaps/brickmania_bricks.h"
229 #include "pluginbitmaps/brickmania_powerups.h"
230 #include "pluginbitmaps/brickmania_ball.h"
231 #include "pluginbitmaps/brickmania_gameover.h"
233 #define PAD_WIDTH BMPWIDTH_brickmania_pads
234 #define PAD_HEIGHT (BMPHEIGHT_brickmania_pads/3)
235 #define SHORT_PAD_WIDTH BMPWIDTH_brickmania_short_pads
236 #define LONG_PAD_WIDTH BMPWIDTH_brickmania_long_pads
237 #define BRICK_HEIGHT (BMPHEIGHT_brickmania_bricks/7)
238 #define BRICK_WIDTH BMPWIDTH_brickmania_bricks
239 #define LEFTMARGIN ((LCD_WIDTH-10*BRICK_WIDTH)/2)
240 #define POWERUP_HEIGHT (BMPHEIGHT_brickmania_powerups/9)
241 #define POWERUP_WIDTH BMPWIDTH_brickmania_powerups
242 #define BALL BMPHEIGHT_brickmania_ball
243 #define HALFBALL ((BALL+1)/2)
244 #define GAMEOVER_WIDTH BMPWIDTH_brickmania_gameover
245 #define GAMEOVER_HEIGHT BMPHEIGHT_brickmania_gameover
247 #ifdef HAVE_LCD_COLOR /* currently no transparency for non-colour */
248 #include "pluginbitmaps/brickmania_break.h"
249 #endif
251 /* The time (in ms) for one iteration through the game loop - decrease this
252 to speed up the game - note that current_tick is (currently) only accurate
253 to 10ms.
255 #define CYCLETIME 50
257 #define TOPMARGIN (BRICK_HEIGHT * 2)
259 #if LCD_WIDTH<=LCD_HEIGHT
260 /* Maintain a 4/3 ratio (Width/Height) */
261 #define GAMESCREEN_HEIGHT (LCD_WIDTH * 3 / 4)
262 #else
263 #define GAMESCREEN_HEIGHT LCD_HEIGHT
264 #endif
266 #define STRINGPOS_FINISH (GAMESCREEN_HEIGHT - (GAMESCREEN_HEIGHT / 6))
267 #define STRINGPOS_CONGRATS (STRINGPOS_FINISH - 20)
268 #define STRINGPOS_NAVI (STRINGPOS_FINISH - 10)
269 #define STRINGPOS_FLIP (STRINGPOS_FINISH - 10)
271 /*calculate paddle y-position */
272 #define PAD_POS_Y (GAMESCREEN_HEIGHT - PAD_HEIGHT - 1)
275 int levels_num = 29;
277 static unsigned char levels[29][8][10] = {
278 { /* level1 */
279 {0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1},
280 {0x2,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x2},
281 {0x0,0x2,0x1,0x0,0x0,0x0,0x0,0x1,0x2,0x0},
282 {0x0,0x0,0x2,0x1,0x0,0x0,0x1,0x2,0x0,0x0},
283 {0x0,0x0,0x0,0x2,0x1,0x1,0x2,0x0,0x0,0x0},
284 {0x7,0x0,0x0,0x7,0x2,0x2,0x7,0x0,0x0,0x7},
285 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
286 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}
288 { /* level2 */
289 {0x0,0x0,0x7,0x7,0x1,0x1,0x7,0x7,0x0,0x0},
290 {0x0,0x1,0x0,0x0,0x1,0x1,0x0,0x0,0x1,0x0},
291 {0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1},
292 {0x1,0x1,0x1,0x1,0x0,0x0,0x1,0x1,0x1,0x1},
293 {0x1,0x1,0x2,0x1,0x0,0x0,0x1,0x2,0x1,0x1},
294 {0x1,0x2,0x0,0x2,0x2,0x2,0x2,0x0,0x2,0x1},
295 {0x0,0x1,0x2,0x0,0x0,0x0,0x0,0x2,0x1,0x0},
296 {0x0,0x0,0x1,0x2,0x2,0x2,0x2,0x1,0x0,0x0}
298 { /* level3 */
299 {0x3,0x3,0x3,0x3,0x0,0x0,0x2,0x2,0x2,0x2},
300 {0x3,0x23,0x23,0x3,0x0,0x0,0x2,0x22,0x22,0x2},
301 {0x3,0x3,0x3,0x3,0x0,0x0,0x2,0x2,0x2,0x2},
302 {0x0,0x0,0x0,0x0,0x37,0x37,0x0,0x0,0x0,0x0},
303 {0x0,0x0,0x0,0x0,0x37,0x37,0x0,0x0,0x0,0x0},
304 {0x5,0x5,0x5,0x5,0x0,0x0,0x6,0x6,0x6,0x6},
305 {0x5,0x25,0x25,0x5,0x0,0x0,0x6,0x26,0x26,0x6},
306 {0x5,0x5,0x5,0x5,0x0,0x0,0x6,0x6,0x6,0x6}
308 { /* level4 */
309 {0x0,0x0,0x0,0x27,0x27,0x27,0x27,0x0,0x0,0x0},
310 {0x0,0x0,0x0,0x27,0x7,0x7,0x27,0x0,0x0,0x0},
311 {0x22,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x22},
312 {0x22,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x22},
313 {0x26,0x6,0x0,0x2,0x2,0x2,0x2,0x0,0x6,0x26},
314 {0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0},
315 {0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0},
316 {0x1,0x1,0x1,0x1,0x0,0x0,0x1,0x1,0x1,0x1}
318 { /* level5 */
319 {0x1,0x0,0x2,0x2,0x0,0x3,0x3,0x0,0x4,0x4},
320 {0x0,0x2,0x2,0x0,0x3,0x3,0x0,0x4,0x4,0x0},
321 {0x2,0x2,0x0,0x3,0x3,0x0,0x4,0x4,0x0,0x5},
322 {0x2,0x0,0x3,0x3,0x0,0x4,0x4,0x0,0x5,0x5},
323 {0x0,0x33,0x3,0x0,0x4,0x4,0x0,0x5,0x5,0x0},
324 {0x3,0x33,0x0,0x4,0x4,0x0,0x5,0x5,0x0,0x36},
325 {0x3,0x0,0x4,0x4,0x0,0x5,0x5,0x0,0x6,0x36},
326 {0x0,0x24,0x24,0x0,0x25,0x25,0x0,0x26,0x26,0x0}
328 { /* level6 */
329 {0x0,0x1,0x3,0x7,0x7,0x7,0x7,0x3,0x1,0x0},
330 {0x3,0x1,0x3,0x7,0x0,0x0,0x7,0x3,0x1,0x3},
331 {0x3,0x1,0x3,0x7,0x7,0x7,0x7,0x3,0x1,0x3},
332 {0x0,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x0},
333 {0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5},
334 {0x5,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x5},
335 {0x0,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x0},
336 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}
338 { /* level7 */
339 {0x0,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x0},
340 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
341 {0x6,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x6},
342 {0x6,0x0,0x0,0x2,0x2,0x2,0x2,0x0,0x0,0x6},
343 {0x6,0x6,0x6,0x0,0x0,0x0,0x0,0x6,0x6,0x6},
344 {0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x0,0x0,0x0},
345 {0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0},
346 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}
348 { /* level8 */
349 {0x0,0x7,0x7,0x7,0x7,0x7,0x7,0x7,0x7,0x0},
350 {0x0,0x0,0x0,0x4,0x0,0x0,0x4,0x0,0x0,0x0},
351 {0x6,0x6,0x0,0x2,0x32,0x32,0x2,0x0,0x6,0x6},
352 {0x0,0x0,0x2,0x2,0x2,0x2,0x2,0x2,0x0,0x0},
353 {0x0,0x6,0x6,0x0,0x0,0x0,0x0,0x6,0x6,0x0},
354 {0x0,0x0,0x0,0x5,0x25,0x25,0x5,0x0,0x0,0x0},
355 {0x0,0x5,0x5,0x25,0x5,0x5,0x25,0x5,0x5,0x0},
356 {0x5,0x5,0x25,0x5,0x5,0x5,0x5,0x25,0x5,0x5}
358 { /* level9 */
359 {0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2},
360 {0x2,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x2},
361 {0x2,0x0,0x3,0x0,0x1,0x1,0x0,0x3,0x0,0x2},
362 {0x2,0x0,0x0,0x1,0x0,0x0,0x1,0x0,0x0,0x2},
363 {0x2,0x0,0x1,0x0,0x3,0x3,0x0,0x1,0x0,0x2},
364 {0x2,0x0,0x0,0x1,0x0,0x0,0x1,0x0,0x0,0x2},
365 {0x2,0x2,0x0,0x0,0x1,0x1,0x0,0x0,0x2,0x2},
366 {0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2}
368 { /* level10 */
369 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
370 {0x0,0x5,0x0,0x5,0x0,0x5,0x0,0x5,0x0,0x5},
371 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
372 {0x0,0x0,0x0,0x0,0x1,0x1,0x0,0x0,0x0,0x0},
373 {0x0,0x0,0x0,0x4,0x1,0x1,0x4,0x0,0x0,0x0},
374 {0x0,0x0,0x3,0x4,0x1,0x1,0x4,0x3,0x0,0x0},
375 {0x0,0x2,0x3,0x4,0x1,0x1,0x4,0x3,0x2,0x0},
376 {0x1,0x2,0x3,0x4,0x1,0x1,0x4,0x3,0x2,0x1}
378 { /* level11 */
379 {0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3},
380 {0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x2},
381 {0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2},
382 {0x2,0x0,0x0,0x0,0x7,0x7,0x0,0x0,0x0,0x2},
383 {0x2,0x0,0x0,0x7,0x7,0x7,0x7,0x0,0x0,0x2},
384 {0x0,0x0,0x0,0x1,0x0,0x0,0x1,0x0,0x0,0x0},
385 {0x0,0x2,0x0,0x1,0x0,0x0,0x1,0x0,0x2,0x0},
386 {0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5}
388 { /* level 12 */
389 {0x2,0x1,0x3,0x1,0x0,0x0,0x1,0x3,0x1,0x2},
390 {0x1,0x1,0x1,0x1,0x0,0x0,0x1,0x1,0x1,0x1},
391 {0x1,0x1,0x1,0x0,0x1,0x1,0x0,0x1,0x1,0x1},
392 {0x0,0x1,0x0,0x1,0x6,0x6,0x1,0x0,0x1,0x0},
393 {0x0,0x0,0x1,0x1,0x6,0x6,0x1,0x1,0x0,0x0},
394 {0x1,0x1,0x1,0x7,0x0,0x0,0x7,0x1,0x1,0x1},
395 {0x1,0x1,0x7,0x1,0x0,0x0,0x1,0x7,0x1,0x1},
396 {0x2,0x2,0x0,0x2,0x2,0x2,0x2,0x0,0x2,0x2}
398 {/* levell13 */
399 {0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2},
400 {0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2},
401 {0x2,0x0,0x2,0x2,0x2,0x2,0x2,0x2,0x0,0x2},
402 {0x2,0x0,0x2,0x3,0x3,0x3,0x3,0x3,0x0,0x2},
403 {0x2,0x0,0x2,0x4,0x4,0x4,0x4,0x4,0x0,0x2},
404 {0x2,0x0,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2},
405 {0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
406 {0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2}
408 {/* level14 */
409 {0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1},
410 {0x4,0x4,0x4,0x4,0x2,0x2,0x4,0x4,0x4,0x4},
411 {0x4,0x0,0x0,0x0,0x2,0x2,0x0,0x0,0x0,0x4},
412 {0x4,0x0,0x0,0x2,0x3,0x3,0x2,0x0,0x0,0x4},
413 {0x4,0x0,0x2,0x23,0x3,0x3,0x23,0x2,0x0,0x4},
414 {0x4,0x0,0x2,0x22,0x2,0x2,0x22,0x2,0x0,0x4},
415 {0x4,0x0,0x6,0x21,0x5,0x5,0x21,0x6,0x0,0x4},
416 {0x4,0x6,0x1,0x1,0x5,0x5,0x1,0x1,0x6,0x4}
418 {/* level 15 */
419 {0x4,0x4,0x4,0x4,0x4,0x3,0x3,0x3,0x3,0x3},
420 {0x2,0x2,0x1,0x1,0x1,0x1,0x1,0x5,0x0,0x0},
421 {0x2,0x2,0x1,0x1,0x1,0x0,0x1,0x6,0x0,0x0},
422 {0x2,0x1,0x1,0x2,0x1,0x1,0x1,0x5,0x0,0x0},
423 {0x2,0x1,0x2,0x2,0x2,0x1,0x1,0x6,0x0,0x0},
424 {0x2,0x1,0x2,0x2,0x2,0x1,0x3,0x5,0x3,0x0},
425 {0x2,0x1,0x1,0x2,0x1,0x1,0x1,0x6,0x0,0x0},
426 {0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2}
428 {/* level 16 (Rockbox) by ts-x */
429 {0x2,0x2,0x3,0x3,0x3,0x4,0x4,0x5,0x0,0x5},
430 {0x2,0x0,0x3,0x0,0x3,0x4,0x0,0x5,0x5,0x0},
431 {0x2,0x0,0x3,0x3,0x3,0x4,0x4,0x5,0x0,0x5},
432 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
433 {0x6,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
434 {0x7,0x7,0x7,0x1,0x1,0x1,0x2,0x0,0x2,0x0},
435 {0x7,0x0,0x7,0x1,0x0,0x1,0x0,0x2,0x0,0x0},
436 {0x7,0x7,0x7,0x1,0x1,0x1,0x2,0x0,0x2,0x0}
438 {/* level 17 (Alien) by ts-x */
439 {0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1},
440 {0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2},
441 {0x1,0x0,0x0,0x0,0x1,0x1,0x0,0x0,0x0,0x1},
442 {0x2,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x2},
443 {0x1,0x0,0x1,0x2,0x2,0x2,0x2,0x1,0x0,0x1},
444 {0x2,0x0,0x0,0x1,0x2,0x2,0x1,0x0,0x0,0x2},
445 {0x2,0x1,0x0,0x0,0x1,0x1,0x0,0x0,0x1,0x2},
446 {0x2,0x2,0x1,0x0,0x1,0x1,0x0,0x1,0x2,0x2}
448 {/* level 18 (Tetris) by ts-x */
449 {0x0,0x2,0x0,0x0,0x3,0x4,0x0,0x2,0x2,0x0},
450 {0x0,0x2,0x7,0x0,0x3,0x4,0x0,0x2,0x2,0x0},
451 {0x2,0x2,0x7,0x0,0x3,0x4,0x0,0x6,0x2,0x2},
452 {0x2,0x2,0x7,0x7,0x3,0x4,0x0,0x6,0x2,0x2},
453 {0x2,0x1,0x7,0x7,0x3,0x4,0x4,0x6,0x5,0x5},
454 {0x2,0x1,0x0,0x7,0x3,0x4,0x4,0x6,0x5,0x5},
455 {0x1,0x1,0x1,0x7,0x3,0x0,0x6,0x6,0x5,0x5},
456 {0x1,0x1,0x1,0x0,0x3,0x0,0x6,0x6,0x5,0x5}
458 { /* level 19 (Stalactites) by ts-x */
459 {0x5,0x2,0x6,0x3,0x4,0x7,0x5,0x3,0x1,0x2},
460 {0x5,0x2,0x6,0x3,0x4,0x7,0x5,0x3,0x1,0x2},
461 {0x5,0x0,0x6,0x3,0x4,0x7,0x5,0x0,0x1,0x2},
462 {0x5,0x2,0x6,0x3,0x4,0x0,0x5,0x3,0x1,0x2},
463 {0x5,0x0,0x6,0x0,0x4,0x7,0x5,0x0,0x1,0x0},
464 {0x5,0x0,0x0,0x3,0x4,0x0,0x0,0x0,0x1,0x2},
465 {0x0,0x0,0x6,0x0,0x0,0x0,0x5,0x0,0x0,0x0},
466 {0x5,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x1,0x0}
468 { /* level 20 (Maze) by ts-x */
469 {0x1,0x1,0x21,0x1,0x1,0x1,0x1,0x1,0x1,0x21},
470 {0x1,0x0,0x0,0x3,0x0,0x0,0x3,0x1,0x31,0x1},
471 {0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x31,0x0,0x1},
472 {0x21,0x0,0x21,0x3,0x0,0x3,0x0,0x3,0x0,0x2},
473 {0x1,0x0,0x1,0x21,0x0,0x12,0x0,0x0,0x0,0x0},
474 {0x31,0x0,0x1,0x0,0x0,0x1,0x0,0x0,0x3,0x0},
475 {0x1,0x0,0x1,0x0,0x1,0x1,0x31,0x1,0x1,0x2},
476 {0x22,0x0,0x2,0x1,0x1,0x1,0x1,0x1,0x1,0x21}
478 { /* level 21 (Dentist) by ts-x */
479 {0x0,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x0},
480 {0x2,0x2,0x0,0x6,0x0,0x6,0x0,0x6,0x2,0x2},
481 {0x2,0x6,0x0,0x6,0x0,0x6,0x0,0x6,0x0,0x2},
482 {0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x6,0x0,0x2},
483 {0x2,0x0,0x6,0x0,0x6,0x0,0x0,0x0,0x0,0x2},
484 {0x2,0x0,0x6,0x0,0x6,0x0,0x6,0x0,0x6,0x2},
485 {0x2,0x2,0x6,0x0,0x6,0x0,0x6,0x0,0x2,0x2},
486 {0x0,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x0}
488 { /* level 22 (Spider) by ts-x */
489 {0x31,0x3,0x1,0x1,0x0,0x0,0x1,0x1,0x3,0x31},
490 {0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0},
491 {0x33,0x1,0x1,0x36,0x1,0x1,0x36,0x1,0x1,0x33},
492 {0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0},
493 {0x0,0x0,0x1,0x1,0x0,0x0,0x1,0x1,0x0,0x0},
494 {0x21,0x3,0x1,0x21,0x2,0x2,0x21,0x1,0x3,0x21},
495 {0x0,0x0,0x0,0x1,0x21,0x1,0x1,0x0,0x0,0x0},
496 {0x3,0x1,0x3,0x1,0x0,0x0,0x1,0x3,0x1,0x3}
498 { /* level 23 (Pool) by ts-x */
499 {0x0,0x7,0x7,0x7,0x0,0x7,0x7,0x7,0x7,0x0},
500 {0x0,0x0,0x5,0x0,0x2,0x0,0x0,0x0,0x2,0x0},
501 {0x7,0x3,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x7},
502 {0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x5,0x0,0x7},
503 {0x7,0x0,0x4,0x0,0x0,0x3,0x0,0x0,0x0,0x7},
504 {0x7,0x0,0x0,0x6,0x0,0x0,0x0,0x0,0x4,0x7},
505 {0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
506 {0x0,0x7,0x7,0x7,0x7,0x0,0x7,0x7,0x7,0x0}
508 { /* level 24 (Vorbis Fish) by ts-x */
509 {0x0,0x0,0x4,0x4,0x5,0x5,0x5,0x0,0x0,0x5},
510 {0x0,0x4,0x6,0x4,0x4,0x5,0x5,0x5,0x0,0x5},
511 {0x5,0x6,0x0,0x6,0x4,0x4,0x4,0x5,0x5,0x5},
512 {0x5,0x6,0x0,0x6,0x4,0x4,0x4,0x4,0x5,0x5},
513 {0x0,0x5,0x6,0x4,0x4,0x5,0x5,0x4,0x5,0x0},
514 {0x5,0x5,0x4,0x4,0x5,0x5,0x5,0x4,0x5,0x5},
515 {0x5,0x4,0x4,0x4,0x5,0x5,0x4,0x4,0x5,0x5},
516 {0x0,0x0,0x4,0x4,0x4,0x4,0x4,0x5,0x0,0x5}
518 {/* level 25 (Rainbow) by ts-x */
519 {0x0,0x4,0x1,0x0,0x0,0x0,0x0,0x1,0x4,0x0},
520 {0x24,0x1,0x3,0x1,0x0,0x0,0x21,0x3,0x1,0x24},
521 {0x1,0x23,0x5,0x3,0x1,0x21,0x3,0x5,0x3,0x21},
522 {0x3,0x5,0x6,0x5,0x3,0x3,0x5,0x6,0x5,0x3},
523 {0x5,0x6,0x7,0x6,0x5,0x5,0x6,0x7,0x6,0x5},
524 {0x6,0x7,0x2,0x27,0x6,0x6,0x27,0x2,0x7,0x6},
525 {0x7,0x2,0x0,0x2,0x27,0x27,0x2,0x0,0x2,0x7},
526 {0x32,0x0,0x0,0x0,0x2,0x2,0x0,0x0,0x0,0x32}
528 { /* level 26 (Bowtie) by ts-x */
529 {0x5,0x1,0x5,0x1,0x0,0x0,0x1,0x5,0x1,0x5},
530 {0x1,0x0,0x0,0x1,0x5,0x5,0x1,0x0,0x0,0x1},
531 {0x5,0x0,0x6,0x0,0x1,0x1,0x0,0x6,0x0,0x5},
532 {0x1,0x0,0x6,0x6,0x0,0x0,0x6,0x6,0x0,0x1},
533 {0x1,0x0,0x6,0x6,0x0,0x0,0x6,0x6,0x0,0x1},
534 {0x5,0x0,0x6,0x0,0x1,0x1,0x0,0x6,0x0,0x5},
535 {0x1,0x0,0x0,0x1,0x5,0x5,0x1,0x0,0x0,0x1},
536 {0x5,0x1,0x5,0x1,0x0,0x0,0x1,0x5,0x1,0x5}
538 { /* level 27 (Frog) by ts-x */
539 {0x0,0x5,0x25,0x0,0x0,0x0,0x0,0x25,0x5,0x0},
540 {0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5},
541 {0x25,0x0,0x0,0x5,0x6,0x6,0x5,0x0,0x0,0x25},
542 {0x5,0x0,0x3,0x0,0x6,0x6,0x0,0x3,0x0,0x5},
543 {0x5,0x0,0x31,0x0,0x6,0x6,0x0,0x31,0x0,0x5},
544 {0x5,0x0,0x0,0x5,0x6,0x6,0x5,0x0,0x0,0x5},
545 {0x5,0x5,0x5,0x35,0x0,0x0,0x35,0x5,0x5,0x5},
546 {0x0,0x25,0x5,0x0,0x4,0x4,0x0,0x5,0x25,0x0}
548 { /* level 28 (DigDug) by ts-x */
549 {0x35,0x5,0x5,0x25,0x0,0x25,0x25,0x5,0x5,0x35},
550 {0x6,0x0,0x0,0x6,0x0,0x6,0x6,0x0,0x0,0x6},
551 {0x7,0x0,0x37,0x37,0x0,0x37,0x37,0x7,0x0,0x7},
552 {0x7,0x0,0x7,0x0,0x0,0x0,0x7,0x7,0x7,0x7},
553 {0x4,0x4,0x4,0x24,0x0,0x24,0x4,0x0,0x0,0x4},
554 {0x4,0x4,0x0,0x0,0x0,0x4,0x4,0x0,0x4,0x4},
555 {0x24,0x24,0x4,0x4,0x4,0x4,0x0,0x0,0x24,0x4},
556 {0x1,0x1,0x1,0x1,0x1,0x1,0x21,0x21,0x1,0x1}
558 { /* TheEnd */
559 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
560 {0x22,0x22,0x26,0x0,0x0,0x26,0x24,0x24,0x0,0x0},
561 {0x22,0x0,0x26,0x26,0x0,0x26,0x24,0x0,0x24,0x0},
562 {0x22,0x22,0x26,0x26,0x0,0x26,0x24,0x0,0x24,0x0},
563 {0x22,0x22,0x26,0x0,0x26,0x26,0x24,0x0,0x24,0x0},
564 {0x22,0x0,0x26,0x0,0x26,0x26,0x24,0x0,0x24,0x0},
565 {0x22,0x22,0x26,0x0,0x0,0x26,0x24,0x24,0x0,0x0},
566 {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}
570 #define MAX_BALLS 10
572 enum difficulty_options {
573 EASY, NORMAL
576 int pad_pos_x;
577 int life;
578 enum { ST_READY, ST_START, ST_PAUSE } game_state = ST_READY;
579 int pad_type;
580 int score=0,vscore=0;
581 bool flip_sides=false;
582 int level=0;
583 int brick_on_board=0;
584 int used_balls=1;
585 int difficulty = NORMAL;
586 int pad_width;
587 int num_count;
588 bool resume = false;
590 typedef struct cube {
591 int powertop;
592 int power;
593 char poweruse;
594 char used;
595 int color;
596 int hits;
597 int hiteffect;
598 } cube;
599 cube brick[80];
601 typedef struct balls {
602 int pos_x;
603 int pos_y;
604 int y;
605 int tempy;
606 int x;
607 int tempx;
608 bool glue;
609 } balls;
611 balls ball[MAX_BALLS];
613 typedef struct sfire {
614 int top;
615 int left;
616 } sfire;
617 sfire fire[30];
619 #define CONFIG_FILE_NAME "brickmania.cfg"
620 #define SAVE_FILE PLUGIN_GAMES_DIR "/brickmania.save"
621 #define HIGH_SCORE PLUGIN_GAMES_DIR "/brickmania.score"
622 #define NUM_SCORES 5
624 static struct configdata config[] = {
625 {TYPE_INT, 0, 1, { .int_p = &difficulty }, "difficulty", NULL},
628 struct highscore highest[NUM_SCORES];
630 static void brickmania_init_game(int new_game)
632 int i,j;
634 pad_pos_x=LCD_WIDTH/2-PAD_WIDTH/2;
636 for(i=0;i<MAX_BALLS;i++) {
637 ball[i].x=0;
638 ball[i].y=0;
639 ball[i].tempy=0;
640 ball[i].tempx=0;
641 ball[i].pos_y=PAD_POS_Y-BALL;
642 ball[i].pos_x=LCD_WIDTH/2-2;
643 ball[i].glue=false;
646 used_balls=1;
647 game_state=ST_READY;
648 pad_type=0;
649 pad_width=PAD_WIDTH;
650 flip_sides=false;
651 num_count=10;
653 if (new_game==1) {
654 brick_on_board=0;
655 /* add one life per achieved level */
656 if (difficulty==EASY && life<2) {
657 score-=100;
658 life++;
661 for(i=0;i<30;i++) {
662 fire[i].top=-8;
664 for(i=0;i<=7;i++) {
665 for(j=0;j<=9;j++) {
666 brick[i*10+j].poweruse=(levels[level][i][j]==0?0:1);
667 if (new_game==1) {
668 brick[i*10+j].power=rb->rand()%25;
669 /* +8 make the game with less powerups */
671 brick[i*10+j].hits=levels[level][i][j]>=10?
672 levels[level][i][j]/16-1:0;
673 brick[i*10+j].hiteffect=0;
674 brick[i*10+j].powertop=TOPMARGIN+i*BRICK_HEIGHT+BRICK_HEIGHT;
675 brick[i*10+j].used=(levels[level][i][j]==0?0:1);
676 brick[i*10+j].color=(levels[level][i][j]>=10?
677 levels[level][i][j]%16:
678 levels[level][i][j])-1;
679 if (levels[level][i][j]!=0)
680 brick_on_board++;
686 static void brickmania_loadgame(void)
688 int fd;
690 resume = false;
692 /* open game file */
693 fd = rb->open(SAVE_FILE, O_RDONLY);
694 if(fd < 0) return;
696 /* read in saved game */
697 while(true) {
698 if(rb->read(fd, &pad_pos_x, sizeof(pad_pos_x)) <= 0) break;
699 if(rb->read(fd, &life, sizeof(life)) <= 0) break;
700 if(rb->read(fd, &game_state, sizeof(game_state)) <= 0) break;
701 if(rb->read(fd, &pad_type, sizeof(pad_type)) <= 0) break;
702 if(rb->read(fd, &score, sizeof(score)) <= 0) break;
703 if(rb->read(fd, &flip_sides, sizeof(flip_sides)) <= 0) break;
704 if(rb->read(fd, &level, sizeof(level)) <= 0) break;
705 if(rb->read(fd, &brick_on_board, sizeof(brick_on_board)) <= 0) break;
706 if(rb->read(fd, &used_balls, sizeof(used_balls)) <= 0) break;
707 if(rb->read(fd, &pad_width, sizeof(pad_width)) <= 0) break;
708 if(rb->read(fd, &num_count, sizeof(num_count)) <= 0) break;
709 if(rb->read(fd, &brick, sizeof(brick)) <= 0) break;
710 if(rb->read(fd, &ball, sizeof(ball)) <= 0) break;
711 if(rb->read(fd, &fire, sizeof(fire)) <= 0) break;
712 vscore = score;
713 resume = true;
714 break;
717 rb->close(fd);
719 /* delete saved file */
720 rb->remove(SAVE_FILE);
721 return;
724 static void brickmania_savegame(void)
726 int fd;
728 /* write out the game state to the save file */
729 fd = rb->open(SAVE_FILE, O_WRONLY|O_CREAT);
730 rb->write(fd, &pad_pos_x, sizeof(pad_pos_x));
731 rb->write(fd, &life, sizeof(life));
732 rb->write(fd, &game_state, sizeof(game_state));
733 rb->write(fd, &pad_type, sizeof(pad_type));
734 rb->write(fd, &score, sizeof(score));
735 rb->write(fd, &flip_sides, sizeof(flip_sides));
736 rb->write(fd, &level, sizeof(level));
737 rb->write(fd, &brick_on_board, sizeof(brick_on_board));
738 rb->write(fd, &used_balls, sizeof(used_balls));
739 rb->write(fd, &pad_width, sizeof(pad_width));
740 rb->write(fd, &num_count, sizeof(num_count));
741 rb->write(fd, &brick, sizeof(brick));
742 rb->write(fd, &ball, sizeof(ball));
743 rb->write(fd, &fire, sizeof(fire));
744 rb->close(fd);
747 /* brickmania_sleep timer counting the score */
748 static void brickmania_sleep(int secs)
750 bool done=false;
751 char s[20];
752 int count=0;
753 int sw, w;
755 while (!done) {
756 if (vscore == score) {
757 if (count==0)
758 count=*rb->current_tick+HZ*secs;
759 if (*rb->current_tick>=count)
760 done=true;
761 } else {
762 if (vscore<score)
763 vscore++;
764 if (vscore>score)
765 vscore--;
766 rb->snprintf(s, sizeof(s), "%d", vscore);
767 rb->lcd_getstringsize(s, &sw, &w);
768 rb->lcd_putsxy(LCD_WIDTH/2-sw/2, 0, s);
769 rb->lcd_update_rect(0,0,LCD_WIDTH,w+2);
771 rb->yield();
775 static int brickmania_help(void)
777 #define WORDS (sizeof help_text / sizeof (char*))
778 static char *help_text[] = {
779 "Brickmania", "", "Aim", "",
780 "Destroy", "all", "the", "bricks", "by", "bouncing",
781 "the", "ball", "of", "them", "using", "the", "paddle.", "", "",
782 "Controls", "",
783 "< & >", "Moves", "the", "paddle", "",
784 #if CONFIG_KEYPAD == ONDIO_PAD
785 "MENU:",
786 #elif (CONFIG_KEYPAD == RECORDER_PAD) || (CONFIG_KEYPAD == IAUDIO_M3_PAD)
787 "PLAY:",
788 #elif CONFIG_KEYPAD == IRIVER_H300_PAD
789 "NAVI:",
790 #else
791 "SELECT:",
792 #endif
793 "Releases", "the", "ball/Fire!", "",
794 #if CONFIG_KEYPAD == IAUDIO_M3_PAD
795 "REC:",
796 #elif (CONFIG_KEYPAD == GIGABEAT_S_PAD) || \
797 (CONFIG_KEYPAD == CREATIVEZVM_PAD)
798 "BACK:",
799 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
800 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
801 (CONFIG_KEYPAD == IPOD_1G2G_PAD) || \
802 (CONFIG_KEYPAD == SANSA_FUZE_PAD)
803 "MENU:",
804 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
805 (CONFIG_KEYPAD == IRIVER_H300_PAD) || \
806 (CONFIG_KEYPAD == ONDIO_PAD) || \
807 (CONFIG_KEYPAD == RECORDER_PAD) || \
808 (CONFIG_KEYPAD == ARCHOS_AV300_PAD)
809 "STOP:",
810 #else
811 "POWER:",
812 #endif
813 "Returns", "to", "menu", "", "",
814 "Specials", "",
815 "N", "Normal:", "returns", "paddle", "to", "normal", "",
816 "D", "DIE!:", "loses", "a", "life", "",
817 "L", "Life:", "gains", "a", "life/power", "up", "",
818 "F", "Fire:", "allows", "you", "to", "shoot", "bricks", "",
819 "G", "Glue:", "ball", "sticks", "to", "paddle", "",
820 "B", "Ball:", "generates", "another", "ball", "",
821 "FL", "Flip:", "flips", "left / right", "movement", "",
822 "<->", "or", "<E>:", "enlarges", "the", "paddle", "",
823 ">-<", "or", ">S<:", "shrinks", "the", "paddle", "",
825 static struct style_text formation[]={
826 { 0, TEXT_CENTER|TEXT_UNDERLINE },
827 { 2, C_RED },
828 { 19, C_RED },
829 { 37, C_RED },
830 { 39, C_BLUE },
831 { 46, C_RED },
832 { 52, C_GREEN },
833 { 59, C_ORANGE },
834 { 67, C_GREEN },
835 { 74, C_YELLOW },
836 { 80, C_RED },
837 { -1, 0 }
839 int button;
841 rb->lcd_setfont(FONT_UI);
842 #ifdef HAVE_LCD_COLOR
843 rb->lcd_set_background(LCD_BLACK);
844 rb->lcd_set_foreground(LCD_WHITE);
845 #endif
847 if (display_text(WORDS, help_text, formation, NULL))
848 return 1;
849 do {
850 button = rb->button_get(true);
851 if (rb->default_event_handler(button) == SYS_USB_CONNECTED) {
852 return 1;
854 } while( ( button == BUTTON_NONE )
855 || ( button & (BUTTON_REL|BUTTON_REPEAT) ) );
856 rb->lcd_setfont(FONT_SYSFIXED);
857 return 0;
860 static int brickmania_menu_cb(int action, const struct menu_item_ex *this_item)
862 int i = ((intptr_t)this_item);
863 if(action == ACTION_REQUEST_MENUITEM
864 && !resume && (i==0 || i==6))
865 return ACTION_EXIT_MENUITEM;
866 return action;
869 static int brickmania_menu(void)
871 int selected = 0;
873 static struct opt_items options[] = {
874 { "Easy", -1 },
875 { "Normal", -1 },
878 MENUITEM_STRINGLIST(main_menu, "Brickmania Menu", brickmania_menu_cb,
879 "Resume Game", "Start New Game",
880 "Difficulty", "Help", "High Scores",
881 "Playback Control",
882 "Quit without Saving", "Quit");
884 rb->button_clear_queue();
885 while (true) {
886 switch (rb->do_menu(&main_menu, &selected, NULL, false)) {
887 case 0:
888 if(game_state!=ST_READY)
889 game_state = ST_PAUSE;
890 return 0;
891 case 1:
892 score=0;
893 vscore=0;
894 life=2;
895 level=0;
896 brickmania_init_game(1);
897 return 0;
898 case 2:
899 rb->set_option("Difficulty", &difficulty, INT, options, 2, NULL);
900 break;
901 case 3:
902 if (brickmania_help())
903 return 1;
904 break;
905 case 4:
906 highscore_show(NUM_SCORES, highest, NUM_SCORES, true);
907 break;
908 case 5:
909 if (playback_control(NULL))
910 return 1;
911 break;
912 case 6:
913 return 1;
914 case 7:
915 if (resume) {
916 rb->splash(HZ*1, "Saving game ...");
917 brickmania_savegame();
919 return 1;
920 case MENU_ATTACHED_USB:
921 return 1;
922 default:
923 break;
928 static int brickmania_pad_check(int ballxc, int mode, int pon ,int ballnum)
930 /* pon: positive(1) or negative(0) */
932 if (mode==0) {
933 if (pon == 0)
934 return -ballxc;
935 else
936 return ballxc;
937 } else {
938 if (ball[ballnum].x > 0)
939 return ballxc;
940 else
941 return ballxc*-1;
945 static int brickmania_fire_space(void)
947 int t;
948 for(t=0;t<30;t++)
949 if (fire[t].top+7 < 0)
950 return t;
952 return 0;
955 static int brickmania_game_loop(void)
957 int j,i,k,bricky,brickx;
958 int sw;
959 char s[30];
960 int sec_count=0;
961 int end;
963 if (brickmania_menu()!=0) {
964 return 1;
966 resume = false;
968 while(true) {
969 /* Convert CYCLETIME (in ms) to HZ */
970 end = *rb->current_tick + (CYCLETIME * HZ) / 1000;
972 if (life >= 0) {
973 #ifdef HAVE_LCD_COLOR
974 rb->lcd_set_background(LCD_BLACK);
975 rb->lcd_set_drawmode(DRMODE_SOLID);
976 rb->lcd_clear_display();
977 rb->lcd_set_background(LCD_BLACK);
978 #if LCD_HEIGHT > GAMESCREEN_HEIGHT
979 rb->lcd_set_foreground(rb->global_settings->bg_color);
980 rb->lcd_fillrect(0, GAMESCREEN_HEIGHT, LCD_WIDTH,
981 LCD_HEIGHT - GAMESCREEN_HEIGHT);
982 #endif
983 rb->lcd_set_foreground(LCD_WHITE);
984 #else
985 rb->lcd_clear_display();
986 #endif
988 if (flip_sides) {
989 if (*rb->current_tick>=sec_count) {
990 sec_count=*rb->current_tick+HZ;
991 if (num_count!=0)
992 num_count--;
993 else
994 flip_sides=false;
996 rb->snprintf(s, sizeof(s), "%d", num_count);
997 rb->lcd_getstringsize(s, &sw, NULL);
998 rb->lcd_putsxy(LCD_WIDTH/2-2, STRINGPOS_FLIP, s);
1001 /* write life num */
1002 #if (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
1003 rb->snprintf(s, sizeof(s), "L:%d", life);
1004 #else
1005 rb->snprintf(s, sizeof(s), "Life: %d", life);
1006 #endif
1007 rb->lcd_putsxy(0, 0, s);
1009 #if (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
1010 rb->snprintf(s, sizeof(s), "L%d", level+1);
1011 #else
1012 rb->snprintf(s, sizeof(s), "Level %d", level+1);
1013 #endif
1015 rb->lcd_getstringsize(s, &sw, NULL);
1016 rb->lcd_putsxy(LCD_WIDTH-sw, 0, s);
1018 if (vscore<score) vscore++;
1019 rb->snprintf(s, sizeof(s), "%d", vscore);
1020 rb->lcd_getstringsize(s, &sw, NULL);
1021 rb->lcd_putsxy(LCD_WIDTH/2-sw/2, 0, s);
1023 /* continue game */
1024 if (game_state==ST_PAUSE) {
1025 #if CONFIG_KEYPAD == ONDIO_PAD
1026 rb->snprintf(s, sizeof(s), "MENU To Continue");
1027 #elif CONFIG_KEYPAD == IRIVER_H300_PAD
1028 rb->snprintf(s, sizeof(s), "Press NAVI To Continue");
1029 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
1030 rb->snprintf(s, sizeof(s), "PLAY To Continue");
1031 #else
1032 rb->snprintf(s, sizeof(s), "Press SELECT To Continue");
1033 #endif
1034 rb->lcd_getstringsize(s, &sw, NULL);
1035 rb->lcd_putsxy(LCD_WIDTH/2-sw/2, STRINGPOS_NAVI, s);
1037 sec_count=*rb->current_tick+HZ;
1040 /* draw the ball */
1041 for(i=0;i<used_balls;i++)
1042 rb->lcd_bitmap(brickmania_ball,ball[i].pos_x, ball[i].pos_y,
1043 BALL, BALL);
1045 if (brick_on_board==0)
1046 brick_on_board--;
1048 /* if the pad is fire */
1049 for(i=0;i<30;i++) {
1050 if (fire[i].top+7>0) {
1051 if (game_state!=ST_PAUSE)
1052 fire[i].top-=4;
1053 rb->lcd_vline(fire[i].left, fire[i].top, fire[i].top+7);
1057 /* the bricks */
1058 for (i=0;i<=7;i++) {
1059 for (j=0;j<=9;j++) {
1060 if (brick[i*10+j].power<9) {
1061 if (brick[i*10+j].poweruse==2) {
1062 if (game_state!=ST_PAUSE)
1063 brick[i*10+j].powertop+=2;
1064 rb->lcd_bitmap_part(brickmania_powerups,0,
1065 POWERUP_HEIGHT*brick[i*10+j
1066 ].power,
1067 POWERUP_WIDTH,
1068 LEFTMARGIN+j*BRICK_WIDTH+
1069 (BRICK_WIDTH/2-POWERUP_WIDTH/2),
1070 brick[i*10+j].powertop,
1071 POWERUP_WIDTH,
1072 POWERUP_HEIGHT);
1076 if ((pad_pos_x<LEFTMARGIN+j*BRICK_WIDTH+5 &&
1077 pad_pos_x+pad_width>LEFTMARGIN+j*BRICK_WIDTH+5) &&
1078 brick[i*10+j].powertop+6>=PAD_POS_Y &&
1079 brick[i*10+j].poweruse==2) {
1080 switch(brick[i*10+j].power) {
1081 case 0:
1082 life++;
1083 score+=50;
1084 break;
1085 case 1:
1086 life--;
1087 if (life>=0) {
1088 brickmania_init_game(0);
1089 brickmania_sleep(2);
1091 break;
1092 case 2:
1093 score+=34;
1094 pad_type=1;
1095 break;
1096 case 3:
1097 score+=47;
1098 pad_type=2;
1099 for(k=0;k<used_balls;k++)
1100 ball[k].glue=false;
1101 break;
1102 case 4:
1103 score+=23;
1104 pad_type=0;
1105 for(k=0;k<used_balls;k++)
1106 ball[k].glue=false;
1107 flip_sides=false;
1108 pad_pos_x+=(pad_width-PAD_WIDTH)/2;
1109 pad_width=PAD_WIDTH;
1110 break;
1111 case 5:
1112 score+=23;
1113 sec_count=*rb->current_tick+HZ;
1114 num_count=10;
1115 flip_sides=!flip_sides;
1116 break;
1117 case 6:
1118 score+=23;
1119 if(used_balls<MAX_BALLS) {
1120 ball[used_balls].x= rb->rand()%2 == 0 ?
1121 -1 : 1;
1122 ball[used_balls].y= -4;
1123 ball[used_balls].glue= false;
1124 used_balls++;
1126 break;
1127 case 7:
1128 score+=23;
1129 if (pad_width==PAD_WIDTH) {
1130 pad_width=LONG_PAD_WIDTH;
1131 pad_pos_x-=(LONG_PAD_WIDTH-PAD_WIDTH)/2;
1133 else if (pad_width==SHORT_PAD_WIDTH) {
1134 pad_width=PAD_WIDTH;
1135 pad_pos_x-=(PAD_WIDTH-SHORT_PAD_WIDTH)/2;
1137 if (pad_pos_x < 0)
1138 pad_pos_x = 0;
1139 else if(pad_pos_x+pad_width > LCD_WIDTH)
1140 pad_pos_x = LCD_WIDTH-pad_width;
1141 break;
1142 case 8:
1143 if (pad_width==PAD_WIDTH) {
1144 pad_width=SHORT_PAD_WIDTH;
1145 pad_pos_x+=(PAD_WIDTH-SHORT_PAD_WIDTH)/2;
1147 else if (pad_width==LONG_PAD_WIDTH) {
1148 pad_width=PAD_WIDTH;
1149 pad_pos_x+=(LONG_PAD_WIDTH-PAD_WIDTH)/2;
1151 break;
1153 brick[i*10+j].poweruse=1;
1156 if (brick[i*10+j].powertop>PAD_POS_Y)
1157 brick[i*10+j].poweruse=1;
1159 brickx=LEFTMARGIN+j*BRICK_WIDTH;
1160 bricky=TOPMARGIN+i*BRICK_HEIGHT;
1161 if (pad_type==2) {
1162 for (k=0;k<30;k++) {
1163 if (fire[k].top+7>0) {
1164 if (brick[i*10+j].used==1 &&
1165 (fire[k].left+1 >= brickx &&
1166 fire[k].left+1 <= brickx+BRICK_WIDTH) &&
1167 (bricky+BRICK_HEIGHT>fire[k].top)) {
1168 score+=13;
1169 fire[k].top=-16;
1170 if (brick[i*10+j].hits > 0) {
1171 brick[i*10+j].hits--;
1172 brick[i*10+j].hiteffect++;
1173 score+=3;
1175 else {
1176 brick[i*10+j].used=0;
1177 if (brick[i*10+j].power!=10)
1178 brick[i*10+j].poweruse=2;
1179 brick_on_board--;
1186 if (brick[i*10+j].used==1) {
1187 rb->lcd_bitmap_part(brickmania_bricks,0,
1188 BRICK_HEIGHT*brick[i*10+j].color,
1189 BRICK_WIDTH,
1190 LEFTMARGIN+j*BRICK_WIDTH,
1191 TOPMARGIN+i*BRICK_HEIGHT,
1192 BRICK_WIDTH, BRICK_HEIGHT);
1193 #ifdef HAVE_LCD_COLOR /* No transparent effect for greyscale lcds for now */
1194 if (brick[i*10+j].hiteffect>0)
1195 rb->lcd_bitmap_transparent_part(brickmania_break,0,
1196 BRICK_HEIGHT*brick[i*10+j].hiteffect,
1197 BRICK_WIDTH,
1198 LEFTMARGIN+j*BRICK_WIDTH,
1199 TOPMARGIN+i*BRICK_HEIGHT,
1200 BRICK_WIDTH, BRICK_HEIGHT);
1201 #endif
1203 /* Somewhere in here collision checking is done b/w ball and
1204 * brick.
1206 for(k=0;k<used_balls;k++) {
1207 if (ball[k].pos_y < PAD_POS_Y) {
1208 if (brick[i*10+j].used==1) {
1209 if ((ball[k].pos_x+ball[k].x+HALFBALL >=
1210 brickx &&
1211 ball[k].pos_x+ball[k].x+HALFBALL <=
1212 brickx+BRICK_WIDTH) &&
1213 ((bricky-4<ball[k].pos_y+BALL &&
1214 bricky>ball[k].pos_y+BALL) ||
1215 (bricky+4>ball[k].pos_y+BALL+BALL &&
1216 bricky<ball[k].pos_y+BALL+BALL)) &&
1217 (ball[k].y >0)) {
1218 ball[k].tempy=bricky-ball[k].pos_y-BALL;
1220 else if ((ball[k].pos_x+ball[k].x+HALFBALL >=
1221 brickx &&
1222 ball[k].pos_x+ball[k].x+HALFBALL <=
1223 brickx+BRICK_WIDTH) &&
1224 ((bricky+BRICK_HEIGHT+4>ball[k].pos_y &&
1225 bricky+BRICK_HEIGHT<ball[k].pos_y) ||
1226 (bricky+BRICK_HEIGHT-4<ball[k].pos_y-BALL &&
1227 bricky+BRICK_HEIGHT>ball[k].pos_y-BALL)) &&
1228 (ball[k].y <0)) {
1229 ball[k].tempy=
1230 -(ball[k].pos_y-(bricky+BRICK_HEIGHT));
1233 if ((ball[k].pos_y+HALFBALL >=
1234 bricky &&
1235 ball[k].pos_y+HALFBALL <=
1236 bricky+BRICK_HEIGHT) &&
1237 ((brickx-4<ball[k].pos_x+BALL &&
1238 brickx>ball[k].pos_x+BALL) ||
1239 (brickx+4>ball[k].pos_x+BALL+BALL &&
1240 brickx<ball[k].pos_x+BALL+BALL)) &&
1241 (ball[k].x >0)) {
1242 ball[k].tempx=brickx-ball[k].pos_x-BALL;
1244 else if ((ball[k].pos_y+ball[k].y+HALFBALL >=
1245 bricky &&
1246 ball[k].pos_y+ball[k].y+HALFBALL <=
1247 bricky+BRICK_HEIGHT) &&
1248 ((brickx+BRICK_WIDTH+4>ball[k].pos_x &&
1249 brickx+BRICK_WIDTH<ball[k].pos_x) ||
1250 (brickx+BRICK_WIDTH-4<ball[k].pos_x-
1251 BALL &&
1252 brickx+BRICK_WIDTH>ball[k].pos_x-
1253 BALL)) && (ball[k].x <0)) {
1254 ball[k].tempx=
1255 -(ball[k].pos_x-(brickx+BRICK_WIDTH));
1258 if ((ball[k].pos_x+HALFBALL >= brickx &&
1259 ball[k].pos_x+HALFBALL <=
1260 brickx+BRICK_WIDTH) &&
1261 ((bricky+BRICK_HEIGHT==ball[k].pos_y) ||
1262 (bricky+BRICK_HEIGHT-6<=ball[k].pos_y &&
1263 bricky+BRICK_HEIGHT>ball[k].pos_y)) &&
1264 (ball[k].y <0)) { /* bottom line */
1265 if (brick[i*10+j].hits > 0) {
1266 brick[i*10+j].hits--;
1267 brick[i*10+j].hiteffect++;
1268 score+=2;
1270 else {
1271 brick[i*10+j].used=0;
1272 if (brick[i*10+j].power!=10)
1273 brick[i*10+j].poweruse=2;
1276 ball[k].y = ball[k].y*-1;
1278 else if ((ball[k].pos_x+HALFBALL >= brickx &&
1279 ball[k].pos_x+HALFBALL <=
1280 brickx+BRICK_WIDTH) &&
1281 ((bricky==ball[k].pos_y+BALL) ||
1282 (bricky+6>=ball[k].pos_y+BALL &&
1283 bricky<ball[k].pos_y+BALL)) &&
1284 (ball[k].y >0)) { /* top line */
1285 if (brick[i*10+j].hits > 0) {
1286 brick[i*10+j].hits--;
1287 brick[i*10+j].hiteffect++;
1288 score+=2;
1290 else {
1291 brick[i*10+j].used=0;
1292 if (brick[i*10+j].power!=10)
1293 brick[i*10+j].poweruse=2;
1296 ball[k].y = ball[k].y*-1;
1299 if ((ball[k].pos_y+HALFBALL >= bricky &&
1300 ball[k].pos_y+HALFBALL <=
1301 bricky+BRICK_HEIGHT) &&
1302 ((brickx==ball[k].pos_x+BALL) ||
1303 (brickx+6>=ball[k].pos_x+BALL &&
1304 brickx<ball[k].pos_x+BALL)) &&
1305 (ball[k].x > 0)) { /* left line */
1306 if (brick[i*10+j].hits > 0) {
1307 brick[i*10+j].hits--;
1308 brick[i*10+j].hiteffect++;
1309 score+=2;
1311 else {
1312 brick[i*10+j].used=0;
1313 if (brick[i*10+j].power!=10)
1314 brick[i*10+j].poweruse=2;
1316 ball[k].x = ball[k].x*-1;
1319 else if ((ball[k].pos_y+HALFBALL >= bricky &&
1320 ball[k].pos_y+HALFBALL <=
1321 bricky+BRICK_HEIGHT) &&
1322 ((brickx+BRICK_WIDTH==
1323 ball[k].pos_x) ||
1324 (brickx+BRICK_WIDTH-6<=
1325 ball[k].pos_x &&
1326 brickx+BRICK_WIDTH>
1327 ball[k].pos_x)) &&
1328 (ball[k].x < 0)) { /* Right line */
1329 if (brick[i*10+j].hits > 0) {
1330 brick[i*10+j].hits--;
1331 brick[i*10+j].hiteffect++;
1332 score+=2;
1334 else {
1335 brick[i*10+j].used=0;
1336 if (brick[i*10+j].power!=10)
1337 brick[i*10+j].poweruse=2;
1340 ball[k].x = ball[k].x*-1;
1343 if (brick[i*10+j].used==0) {
1344 brick_on_board--;
1345 score+=8;
1349 } /* for k */
1350 } /* for j */
1351 } /* for i */
1353 /* draw the pad */
1354 rb->lcd_bitmap_part(pad_width==PAD_WIDTH?brickmania_pads:
1355 pad_width==LONG_PAD_WIDTH?brickmania_long_pads:
1356 brickmania_short_pads,
1357 0,pad_type*PAD_HEIGHT,pad_width,
1358 pad_pos_x, PAD_POS_Y, pad_width, PAD_HEIGHT);
1360 if (game_state!=ST_PAUSE) {
1361 for(k=0;k<used_balls;k++) {
1363 if ((ball[k].pos_x >= pad_pos_x &&
1364 ball[k].pos_x <= pad_pos_x+pad_width) &&
1365 (PAD_POS_Y-4<ball[k].pos_y+BALL &&
1366 PAD_POS_Y>ball[k].pos_y+BALL) && (ball[k].y >0))
1367 ball[k].tempy=PAD_POS_Y-ball[k].pos_y-BALL;
1368 else if ((4>ball[k].pos_y && 0<ball[k].pos_y) &&
1369 (ball[k].y <0))
1370 ball[k].tempy=-ball[k].pos_y;
1371 if ((LCD_WIDTH-4<ball[k].pos_x+BALL &&
1372 LCD_WIDTH>ball[k].pos_x+BALL) && (ball[k].x >0))
1373 ball[k].tempx=LCD_WIDTH-ball[k].pos_x-BALL;
1374 else if ((4>ball[k].pos_x && 0<ball[k].pos_x) &&
1375 (ball[k].x <0))
1376 ball[k].tempx=-ball[k].pos_x;
1378 /* top line */
1379 if (ball[k].pos_y<= 0)
1380 ball[k].y = ball[k].y*-1;
1381 /* bottom line */
1382 else if (ball[k].pos_y+BALL >= GAMESCREEN_HEIGHT) {
1383 if (used_balls>1) {
1384 used_balls--;
1385 ball[k].pos_x = ball[used_balls].pos_x;
1386 ball[k].pos_y = ball[used_balls].pos_y;
1387 ball[k].y = ball[used_balls].y;
1388 ball[k].tempy = ball[used_balls].tempy;
1389 ball[k].x = ball[used_balls].x;
1390 ball[k].tempx = ball[used_balls].tempx;
1391 ball[k].glue = ball[used_balls].glue;
1393 ball[used_balls].x=0;
1394 ball[used_balls].y=0;
1395 ball[used_balls].tempy=0;
1396 ball[used_balls].tempx=0;
1397 ball[used_balls].pos_y=PAD_POS_Y-BALL;
1398 ball[used_balls].pos_x=pad_pos_x+(pad_width/2)-2;
1400 k--;
1401 continue;
1402 } else {
1403 life--;
1404 if (life>=0) {
1405 brickmania_init_game(0);
1406 brickmania_sleep(2);
1411 /* left line ,right line */
1412 if ((ball[k].pos_x <= 0) ||
1413 (ball[k].pos_x+BALL >= LCD_WIDTH)) {
1414 ball[k].x = ball[k].x*-1;
1415 ball[k].pos_x = ball[k].pos_x <= 0 ? 0 : LCD_WIDTH-BALL;
1418 if ((ball[k].pos_y+BALL >= PAD_POS_Y &&
1419 (ball[k].pos_x >= pad_pos_x &&
1420 ball[k].pos_x <= pad_pos_x+pad_width)) &&
1421 game_state!=ST_READY && !ball[k].glue) {
1423 if ((ball[k].pos_x+HALFBALL >= pad_pos_x &&
1424 ball[k].pos_x+HALFBALL <=
1425 pad_pos_x+(pad_width/2/4)) ||
1426 (ball[k].pos_x +HALFBALL>=
1427 pad_pos_x+(pad_width-(pad_width/2/4)) &&
1428 ball[k].pos_x+HALFBALL <= pad_pos_x+pad_width)) {
1430 ball[k].y = -2;
1431 if (ball[k].pos_x != 0 &&
1432 ball[k].pos_x+BALL!=LCD_WIDTH)
1433 ball[k].x = brickmania_pad_check(6,0,
1434 ball[k].pos_x+2<=pad_pos_x+
1435 (pad_width/2)?0:1,k);
1438 else if ((ball[k].pos_x+HALFBALL >=
1439 pad_pos_x+(pad_width/2/4) &&
1440 ball[k].pos_x+HALFBALL <=
1441 pad_pos_x+2*(pad_width/2/4)) ||
1442 (ball[k].pos_x+HALFBALL >=
1443 pad_pos_x+(pad_width-2*(pad_width/2/4)) &&
1444 ball[k].pos_x+HALFBALL <=
1445 pad_pos_x+(pad_width-(pad_width/2/4)) )) {
1447 ball[k].y = -3;
1448 if (ball[k].pos_x != 0 &&
1449 ball[k].pos_x+BALL!=LCD_WIDTH)
1450 ball[k].x = brickmania_pad_check(4,0,
1451 ball[k].pos_x+2<=pad_pos_x+
1452 (pad_width/2)?0:1,k);
1455 else if ((ball[k].pos_x+HALFBALL >=
1456 pad_pos_x+2*(pad_width/2/4) &&
1457 ball[k].pos_x+HALFBALL <=
1458 pad_pos_x+3*(pad_width/2/4)) ||
1459 (ball[k].pos_x+2 >=
1460 pad_pos_x+(pad_width-3*(pad_width/2/4)) &&
1461 ball[k].pos_x+2 <=
1462 pad_pos_x+ ((pad_width/2)-2*(pad_width/2/4)) )) {
1464 ball[k].y = -4;
1465 if (ball[k].pos_x != 0 &&
1466 ball[k].pos_x+BALL!=LCD_WIDTH)
1467 ball[k].x = brickmania_pad_check(3,0,
1468 ball[k].pos_x+2<=pad_pos_x+
1469 (pad_width/2)?0:1,k);
1472 else if ((ball[k].pos_x+HALFBALL >=
1473 pad_pos_x+3*(pad_width/2/4) &&
1474 ball[k].pos_x+HALFBALL <=
1475 pad_pos_x+4*(pad_width/2/4)-2) ||
1476 (ball[k].pos_x+2 >= pad_pos_x+(pad_width/2+2) &&
1477 ball[k].pos_x+2 <=
1478 pad_pos_x+(pad_width-3*(pad_width/2/4)) )) {
1480 ball[k].y = -4;
1481 if (ball[k].pos_x != 0 &&
1482 ball[k].pos_x+BALL!=LCD_WIDTH)
1483 ball[k].x = brickmania_pad_check(2,1,0,k);
1486 else {
1487 ball[k].y = -4;
1491 if (!ball[k].glue) {
1492 ball[k].pos_x+=ball[k].tempx!=0?ball[k].tempx:ball[k].x;
1493 ball[k].pos_y+=ball[k].tempy!=0?ball[k].tempy:ball[k].y;
1495 ball[k].tempy=0;
1496 ball[k].tempx=0;
1499 if (ball[k].pos_y+5 >= PAD_POS_Y &&
1500 (pad_type==1 && !ball[k].glue) &&
1501 (ball[k].pos_x >= pad_pos_x &&
1502 ball[k].pos_x <= pad_pos_x+pad_width)) {
1503 ball[k].y=0;
1504 ball[k].pos_y=PAD_POS_Y-BALL;
1505 ball[k].glue=true;
1507 } /* for k */
1510 rb->lcd_update();
1512 if (brick_on_board < 0) {
1513 if (level+1<levels_num) {
1514 level++;
1515 if (difficulty==NORMAL)
1516 score+=100;
1517 brickmania_init_game(1);
1518 brickmania_sleep(2);
1520 else {
1521 rb->lcd_getstringsize("Congratulations!", &sw, NULL);
1522 rb->lcd_putsxy(LCD_WIDTH/2-sw/2, STRINGPOS_CONGRATS,
1523 "Congratulations!");
1524 #if (LCD_WIDTH == 112) && (LCD_HEIGHT == 64)
1525 rb->lcd_getstringsize("No more levels", &sw, NULL);
1526 rb->lcd_putsxy(LCD_WIDTH/2-sw/2, STRINGPOS_FINISH,
1527 "No more levels");
1528 #else
1529 rb->lcd_getstringsize("You have finished the game!",
1530 &sw, NULL);
1531 rb->lcd_putsxy(LCD_WIDTH/2-sw/2, STRINGPOS_FINISH,
1532 "You have finished the game!");
1533 #endif
1534 vscore=score;
1535 rb->lcd_update();
1536 brickmania_sleep(2);
1537 return 0;
1541 int move_button,button;
1542 int button_right,button_left;
1543 button=rb->button_get(false);
1545 #if defined(HAS_BUTTON_HOLD) && !defined(HAVE_REMOTE_LCD_AS_MAIN)
1546 /* FIXME: Should probably check remote hold here */
1547 if (rb->button_hold())
1548 button = QUIT;
1549 #endif
1551 #ifdef HAVE_TOUCHSCREEN
1552 if(button & BUTTON_TOUCHSCREEN)
1554 short touch_x, touch_y;
1555 touch_x = rb->button_get_data() >> 16;
1556 touch_y = rb->button_get_data() & 0xffff;
1557 if(touch_y >= PAD_POS_Y && touch_y <= PAD_POS_Y+PAD_HEIGHT)
1559 pad_pos_x += (flip_sides ? -1 : 1) * ( (touch_x-pad_pos_x-pad_width/2) / 4 );
1561 if(pad_pos_x < 0)
1562 pad_pos_x = 0;
1563 else if(pad_pos_x+pad_width > LCD_WIDTH)
1564 pad_pos_x = LCD_WIDTH-pad_width;
1565 for(k=0;k<used_balls;k++)
1566 if (game_state==ST_READY || ball[k].glue)
1567 ball[k].pos_x = pad_pos_x+pad_width/2;
1570 if(button & BUTTON_REL)
1571 button = SELECT;
1573 else
1575 #endif
1576 move_button=rb->button_status();
1577 #ifdef ALTRIGHT
1578 button_right=((move_button & RIGHT) || (move_button & ALTRIGHT));
1579 button_left=((move_button & LEFT) || (move_button & ALTLEFT));
1580 #else
1581 button_right=((move_button & RIGHT) || (SCROLL_FWD(button)));
1582 button_left=((move_button & LEFT) || (SCROLL_BACK(button)));
1583 #endif
1584 if ((game_state==ST_PAUSE) && (button_right || button_left))
1585 continue;
1586 if ((button_right && flip_sides==false) ||
1587 (button_left && flip_sides==true)) {
1588 if (pad_pos_x+8+pad_width > LCD_WIDTH) {
1589 for(k=0;k<used_balls;k++)
1590 if (game_state==ST_READY || ball[k].glue)
1591 ball[k].pos_x+=LCD_WIDTH-pad_pos_x-pad_width;
1592 pad_pos_x+=LCD_WIDTH-pad_pos_x-pad_width;
1594 else {
1595 for(k=0;k<used_balls;k++)
1596 if ((game_state==ST_READY || ball[k].glue))
1597 ball[k].pos_x+=8;
1598 pad_pos_x+=8;
1601 else if ((button_left && flip_sides==false) ||
1602 (button_right && flip_sides==true)) {
1603 if (pad_pos_x-8 < 0) {
1604 for(k=0;k<used_balls;k++)
1605 if (game_state==ST_READY || ball[k].glue)
1606 ball[k].pos_x-=pad_pos_x;
1607 pad_pos_x-=pad_pos_x;
1609 else {
1610 for(k=0;k<used_balls;k++)
1611 if (game_state==ST_READY || ball[k].glue)
1612 ball[k].pos_x-=8;
1613 pad_pos_x-=8;
1616 #ifdef HAVE_TOUCHSCREEN
1618 #endif
1621 switch(button) {
1622 case UP:
1623 case SELECT:
1624 if (game_state==ST_READY) {
1625 for(k=0;k<used_balls;k++) {
1626 ball[k].y=-4;
1627 ball[k].x=pad_pos_x+(pad_width/2)-2>=
1628 LCD_WIDTH/2?2:-2;
1630 game_state=ST_START;
1632 else if (game_state==ST_PAUSE) {
1633 game_state=ST_START;
1635 else if (pad_type==1) {
1636 for(k=0;k<used_balls;k++) {
1637 if (ball[k].glue)
1638 ball[k].glue=false;
1641 else if (pad_type==2) {
1642 k=brickmania_fire_space();
1643 fire[k].top=PAD_POS_Y-7;
1644 fire[k].left=pad_pos_x+1;
1645 k=brickmania_fire_space();
1646 fire[k].top=PAD_POS_Y-7;
1647 fire[k].left=pad_pos_x+pad_width-1;
1649 break;
1650 #ifdef RC_QUIT
1651 case RC_QUIT:
1652 #endif
1653 case QUIT:
1654 resume = true;
1655 return 0;
1656 break;
1658 default:
1659 if(rb->default_event_handler(button) == SYS_USB_CONNECTED)
1660 return 1;
1661 break;
1664 else {
1665 #ifdef HAVE_LCD_COLOR
1666 rb->lcd_bitmap_transparent(brickmania_gameover,
1667 (LCD_WIDTH - GAMEOVER_WIDTH)/2,
1668 (GAMESCREEN_HEIGHT - GAMEOVER_HEIGHT)/2,
1669 GAMEOVER_WIDTH,GAMEOVER_HEIGHT);
1670 #else /* greyscale and mono */
1671 rb->lcd_bitmap(brickmania_gameover,(LCD_WIDTH - GAMEOVER_WIDTH)/2,
1672 (GAMESCREEN_HEIGHT - GAMEOVER_HEIGHT)/2,
1673 GAMEOVER_WIDTH,GAMEOVER_HEIGHT);
1674 #endif
1675 rb->lcd_update();
1676 brickmania_sleep(2);
1677 return 0;
1679 if (end > *rb->current_tick)
1680 rb->sleep(end-*rb->current_tick);
1681 else
1682 rb->yield();
1684 return 0;
1687 /* this is the plugin entry point */
1688 enum plugin_status plugin_start(const void* parameter)
1690 (void)parameter;
1691 int last_difficulty;
1693 highscore_load(HIGH_SCORE,highest,NUM_SCORES);
1694 configfile_load(CONFIG_FILE_NAME,config,1,0);
1695 last_difficulty = difficulty;
1697 rb->lcd_setfont(FONT_SYSFIXED);
1698 #if LCD_DEPTH > 1
1699 rb->lcd_set_backdrop(NULL);
1700 #endif
1701 /* Turn off backlight timeout */
1702 backlight_force_on(); /* backlight control in lib/helper.c */
1704 /* now go ahead and have fun! */
1705 rb->srand( *rb->current_tick );
1706 brickmania_loadgame();
1707 while(brickmania_game_loop() == 0) {
1708 if(!resume) {
1709 int position = highscore_update(score, level+1, "", highest, NUM_SCORES);
1710 if (position == 0) {
1711 rb->splash(HZ*2, "New High Score");
1713 if (position != -1) {
1714 highscore_show(position, highest, NUM_SCORES, true);
1715 } else {
1716 brickmania_sleep(3);
1721 highscore_save(HIGH_SCORE,highest,NUM_SCORES);
1722 if(last_difficulty != difficulty)
1723 configfile_save(CONFIG_FILE_NAME,config,1,0);
1724 /* Restore user's original backlight setting */
1725 rb->lcd_setfont(FONT_UI);
1726 /* Turn on backlight timeout (revert to settings) */
1727 backlight_use_settings(); /* backlight control in lib/helper.c */
1729 return PLUGIN_OK;