Prepare new maemo release
[maemo-rb.git] / apps / plugins / pegbox.c
blob0f55557b928911cd3c1416bfb5d6a17f8887fc1a
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2007 Tom Ross
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
21 #include "plugin.h"
22 #include "lib/configfile.h"
23 #include "lib/display_text.h"
24 #include "lib/playback_control.h"
26 #include "pluginbitmaps/pegbox_header.h"
27 #include "pluginbitmaps/pegbox_pieces.h"
31 #define CONFIG_FILE_NAME "pegbox.cfg"
33 #define ROWS 8 /* Number of rows on each board */
34 #define COLS 12 /* Number of columns on each board */
35 #define NUM_LEVELS 15 /* Number of levels */
37 #define SPACE 0
38 #define WALL 1
39 #define TRIANGLE 2
40 #define CROSS 3
41 #define SQUARE 4
42 #define CIRCLE 5
43 #define HOLE 6
44 #define PLAYER 7
46 #if CONFIG_KEYPAD == RECORDER_PAD
47 #define PEGBOX_SELECT BUTTON_ON
48 #define PEGBOX_QUIT BUTTON_OFF
49 #define PEGBOX_RESTART BUTTON_F2
50 #define PEGBOX_LVL_UP BUTTON_F1
51 #define PEGBOX_LVL_DOWN BUTTON_F3
52 #define PEGBOX_UP BUTTON_UP
53 #define PEGBOX_DOWN BUTTON_DOWN
54 #define PEGBOX_RIGHT BUTTON_RIGHT
55 #define PEGBOX_LEFT BUTTON_LEFT
57 #define SELECT_TEXT "ON"
58 #define QUIT_TEXT "OFF"
59 #define RESTART_TEXT "F2"
60 #define LVL_UP_TEXT "F1"
61 #define LVL_DOWN_TEXT "F3"
63 #elif CONFIG_KEYPAD == ONDIO_PAD
64 #define PEGBOX_SELECT BUTTON_OFF
65 #define PEGBOX_QUIT (BUTTON_MENU | BUTTON_LEFT)
66 #define PEGBOX_RESTART (BUTTON_MENU | BUTTON_RIGHT)
67 #define PEGBOX_LVL_UP (BUTTON_MENU | BUTTON_UP)
68 #define PEGBOX_LVL_DOWN (BUTTON_MENU | BUTTON_DOWN)
69 #define PEGBOX_UP BUTTON_UP
70 #define PEGBOX_DOWN BUTTON_DOWN
71 #define PEGBOX_RIGHT BUTTON_RIGHT
72 #define PEGBOX_LEFT BUTTON_LEFT
74 #define SELECT_TEXT "OFF"
75 #define QUIT_TEXT "M+LEFT"
76 #define RESTART_TEXT "M+RIGHT"
77 #define LVL_UP_TEXT "M+UP"
78 #define LVL_DOWN_TEXT "M+DOWN"
80 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
81 (CONFIG_KEYPAD == IRIVER_H300_PAD)
82 #define PEGBOX_SELECT BUTTON_SELECT
83 #define PEGBOX_QUIT BUTTON_OFF
84 #define PEGBOX_RESTART BUTTON_ON
85 #define PEGBOX_LVL_UP BUTTON_MODE
86 #define PEGBOX_LVL_DOWN BUTTON_REC
87 #define PEGBOX_UP BUTTON_UP
88 #define PEGBOX_DOWN BUTTON_DOWN
89 #define PEGBOX_RIGHT BUTTON_RIGHT
90 #define PEGBOX_LEFT BUTTON_LEFT
92 #define SELECT_TEXT "NAVI"
93 #define QUIT_TEXT "OFF"
94 #define RESTART_TEXT "ON"
95 #define LVL_UP_TEXT "AB"
96 #define LVL_DOWN_TEXT "REC"
98 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
99 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
100 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
101 #define PEGBOX_SELECT (BUTTON_SELECT|BUTTON_RIGHT)
102 #define PEGBOX_QUIT (BUTTON_SELECT|BUTTON_PLAY)
103 #define PEGBOX_RESTART (BUTTON_SELECT|BUTTON_LEFT)
104 #define PEGBOX_LVL_UP (BUTTON_SELECT|BUTTON_MENU)
105 #define PEGBOX_UP BUTTON_MENU
106 #define PEGBOX_DOWN BUTTON_PLAY
107 #define PEGBOX_RIGHT BUTTON_RIGHT
108 #define PEGBOX_LEFT BUTTON_LEFT
110 #define SELECT_TEXT "SELECT+RIGHT"
111 #define QUIT_TEXT "SELECT+PLAY"
112 #define RESTART_TEXT "SELECT+LEFT"
113 #define LVL_UP_TEXT "SELECT+MENU"
114 #define LVL_DOWN_TEXT "-"
116 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
117 #define PEGBOX_SELECT BUTTON_SELECT
118 #define PEGBOX_QUIT BUTTON_POWER
119 #define PEGBOX_RESTART BUTTON_REC
120 #define PEGBOX_LVL_UP BUTTON_PLAY
121 #define PEGBOX_UP BUTTON_UP
122 #define PEGBOX_DOWN BUTTON_DOWN
123 #define PEGBOX_RIGHT BUTTON_RIGHT
124 #define PEGBOX_LEFT BUTTON_LEFT
126 #define SELECT_TEXT "SELECT"
127 #define QUIT_TEXT "OFF"
128 #define RESTART_TEXT "REC"
129 #define LVL_UP_TEXT "PLAY"
130 #define LVL_DOWN_TEXT "-"
132 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
133 #define PEGBOX_SELECT BUTTON_MODE
134 #define PEGBOX_QUIT BUTTON_PLAY
135 #define PEGBOX_RESTART (BUTTON_EQ|BUTTON_MODE)
136 #define PEGBOX_LVL_UP (BUTTON_EQ|BUTTON_UP)
137 #define PEGBOX_LVL_DOWN (BUTTON_EQ|BUTTON_DOWN)
138 #define PEGBOX_UP BUTTON_UP
139 #define PEGBOX_DOWN BUTTON_DOWN
140 #define PEGBOX_RIGHT BUTTON_RIGHT
141 #define PEGBOX_LEFT BUTTON_LEFT
143 #define SELECT_TEXT "MODE"
144 #define QUIT_TEXT "PLAY"
145 #define RESTART_TEXT "EQ+MODE"
146 #define LVL_UP_TEXT "EQ+UP"
147 #define LVL_DOWN_TEXT "EQ+DOWN"
149 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
150 #define PEGBOX_SELECT BUTTON_PLAY
151 #define PEGBOX_QUIT BUTTON_POWER
152 #define PEGBOX_RESTART (BUTTON_FF|BUTTON_REPEAT)
153 #define PEGBOX_LVL_UP (BUTTON_FF|BUTTON_SCROLL_UP)
154 #define PEGBOX_LVL_DOWN (BUTTON_FF|BUTTON_SCROLL_DOWN)
155 #define PEGBOX_UP BUTTON_SCROLL_UP
156 #define PEGBOX_DOWN BUTTON_SCROLL_DOWN
157 #define PEGBOX_RIGHT BUTTON_RIGHT
158 #define PEGBOX_LEFT BUTTON_LEFT
160 #define SELECT_TEXT "PLAY"
161 #define QUIT_TEXT "OFF"
162 #define RESTART_TEXT "LONG FF"
163 #define LVL_UP_TEXT "FF+SCROLL_UP"
164 #define LVL_DOWN_TEXT "FF+SCROLL_DOWN"
166 #elif CONFIG_KEYPAD == SANSA_E200_PAD
167 #define PEGBOX_SELECT BUTTON_SELECT
168 #define PEGBOX_QUIT BUTTON_POWER
169 #define PEGBOX_RESTART BUTTON_REC
170 #define PEGBOX_LVL_UP BUTTON_SCROLL_BACK
171 #define PEGBOX_LVL_DOWN BUTTON_SCROLL_FWD
172 #define PEGBOX_UP BUTTON_UP
173 #define PEGBOX_DOWN BUTTON_DOWN
174 #define PEGBOX_RIGHT BUTTON_RIGHT
175 #define PEGBOX_LEFT BUTTON_LEFT
177 #define SELECT_TEXT "SELECT"
178 #define QUIT_TEXT "POWER"
179 #define RESTART_TEXT "REC"
180 #define LVL_UP_TEXT "SCROLL BACK"
181 #define LVL_DOWN_TEXT "SCROLL FWD"
183 #elif CONFIG_KEYPAD == SANSA_FUZE_PAD
184 #define PEGBOX_SELECT BUTTON_SELECT|BUTTON_REL
185 #define PEGBOX_QUIT (BUTTON_HOME|BUTTON_REPEAT)
186 #define PEGBOX_RESTART (BUTTON_SELECT|BUTTON_LEFT)
187 #define PEGBOX_LVL_UP (BUTTON_SELECT|BUTTON_UP)
188 #define PEGBOX_LVL_DOWN (BUTTON_SELECT|BUTTON_DOWN)
189 #define PEGBOX_UP BUTTON_UP
190 #define PEGBOX_DOWN BUTTON_DOWN
191 #define PEGBOX_RIGHT BUTTON_RIGHT
192 #define PEGBOX_LEFT BUTTON_LEFT
194 #define SELECT_TEXT "SELECT"
195 #define QUIT_TEXT "HOME"
196 #define RESTART_TEXT "SELECT & LEFT"
197 #define LVL_UP_TEXT "SELECT & UP"
198 #define LVL_DOWN_TEXT "SELECT & DOWN"
200 #elif CONFIG_KEYPAD == GIGABEAT_PAD
201 #define PEGBOX_SELECT BUTTON_SELECT
202 #define PEGBOX_QUIT BUTTON_POWER
203 #define PEGBOX_RESTART BUTTON_A
204 #define PEGBOX_LVL_UP BUTTON_VOL_UP
205 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
206 #define PEGBOX_UP BUTTON_UP
207 #define PEGBOX_DOWN BUTTON_DOWN
208 #define PEGBOX_RIGHT BUTTON_RIGHT
209 #define PEGBOX_LEFT BUTTON_LEFT
211 #define SELECT_TEXT "SELECT"
212 #define QUIT_TEXT "POWER"
213 #define RESTART_TEXT "A"
214 #define LVL_UP_TEXT "VOL+"
215 #define LVL_DOWN_TEXT "VOL-"
217 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
218 #define PEGBOX_SELECT BUTTON_SELECT
219 #define PEGBOX_QUIT BUTTON_BACK
220 #define PEGBOX_RESTART BUTTON_MENU
221 #define PEGBOX_LVL_UP BUTTON_VOL_UP
222 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
223 #define PEGBOX_UP BUTTON_UP
224 #define PEGBOX_DOWN BUTTON_DOWN
225 #define PEGBOX_RIGHT BUTTON_RIGHT
226 #define PEGBOX_LEFT BUTTON_LEFT
228 #define SELECT_TEXT "SELECT"
229 #define QUIT_TEXT "BACK"
230 #define RESTART_TEXT "MENU"
231 #define LVL_UP_TEXT "VOL+"
232 #define LVL_DOWN_TEXT "VOL-"
234 #elif CONFIG_KEYPAD == MROBE100_PAD
235 #define PEGBOX_SELECT BUTTON_SELECT
236 #define PEGBOX_QUIT BUTTON_POWER
237 #define PEGBOX_RESTART BUTTON_PLAY
238 #define PEGBOX_LVL_UP BUTTON_MENU
239 #define PEGBOX_LVL_DOWN BUTTON_DISPLAY
240 #define PEGBOX_UP BUTTON_UP
241 #define PEGBOX_DOWN BUTTON_DOWN
242 #define PEGBOX_RIGHT BUTTON_RIGHT
243 #define PEGBOX_LEFT BUTTON_LEFT
245 #define SELECT_TEXT "SELECT"
246 #define QUIT_TEXT "POWER"
247 #define RESTART_TEXT "PLAY"
248 #define LVL_UP_TEXT "MENU"
249 #define LVL_DOWN_TEXT "DISPLAY"
251 #elif CONFIG_KEYPAD == SANSA_C200_PAD
252 #define PEGBOX_SELECT BUTTON_SELECT
253 #define PEGBOX_QUIT BUTTON_POWER
254 #define PEGBOX_RESTART BUTTON_REC
255 #define PEGBOX_LVL_UP BUTTON_VOL_UP
256 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
257 #define PEGBOX_UP BUTTON_UP
258 #define PEGBOX_DOWN BUTTON_DOWN
259 #define PEGBOX_RIGHT BUTTON_RIGHT
260 #define PEGBOX_LEFT BUTTON_LEFT
262 #define SELECT_TEXT "SELECT"
263 #define QUIT_TEXT "POWER"
264 #define RESTART_TEXT "REC"
265 #define LVL_UP_TEXT "VOL+"
266 #define LVL_DOWN_TEXT "VOL-"
268 #elif CONFIG_KEYPAD == SANSA_CLIP_PAD
269 #define PEGBOX_SELECT BUTTON_SELECT
270 #define PEGBOX_QUIT BUTTON_POWER
271 #define PEGBOX_RESTART BUTTON_HOME
272 #define PEGBOX_LVL_UP BUTTON_VOL_UP
273 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
274 #define PEGBOX_UP BUTTON_UP
275 #define PEGBOX_DOWN BUTTON_DOWN
276 #define PEGBOX_RIGHT BUTTON_RIGHT
277 #define PEGBOX_LEFT BUTTON_LEFT
279 #define SELECT_TEXT "SELECT"
280 #define QUIT_TEXT "POWER"
281 #define RESTART_TEXT "HOME"
282 #define LVL_UP_TEXT "VOL+"
283 #define LVL_DOWN_TEXT "VOL-"
285 #elif CONFIG_KEYPAD == SANSA_M200_PAD
286 #define PEGBOX_SELECT (BUTTON_SELECT | BUTTON_REL)
287 #define PEGBOX_QUIT BUTTON_POWER
288 #define PEGBOX_RESTART (BUTTON_SELECT | BUTTON_UP)
289 #define PEGBOX_LVL_UP BUTTON_VOL_UP
290 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
291 #define PEGBOX_UP BUTTON_UP
292 #define PEGBOX_DOWN BUTTON_DOWN
293 #define PEGBOX_RIGHT BUTTON_RIGHT
294 #define PEGBOX_LEFT BUTTON_LEFT
296 #define SELECT_TEXT "SELECT"
297 #define QUIT_TEXT "POWER"
298 #define RESTART_TEXT "SELECT+UP"
299 #define LVL_UP_TEXT "VOL+"
300 #define LVL_DOWN_TEXT "VOL-"
303 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
304 #define PEGBOX_SELECT BUTTON_RC_PLAY
305 #define PEGBOX_QUIT BUTTON_RC_REC
306 #define PEGBOX_RESTART BUTTON_RC_MODE
307 #define PEGBOX_LVL_UP BUTTON_VOL_UP
308 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
309 #define PEGBOX_UP BUTTON_RC_VOL_UP
310 #define PEGBOX_DOWN BUTTON_RC_VOL_DOWN
311 #define PEGBOX_RIGHT BUTTON_RC_FF
312 #define PEGBOX_LEFT BUTTON_RC_REW
314 #define SELECT_TEXT "REM. PLAY"
315 #define QUIT_TEXT "REM. REC"
316 #define RESTART_TEXT "REM. MODE"
317 #define LVL_UP_TEXT "VOL+"
318 #define LVL_DOWN_TEXT "VOL-"
320 #elif CONFIG_KEYPAD == COWON_D2_PAD
321 #define PEGBOX_QUIT BUTTON_POWER
323 #define QUIT_TEXT "POWER"
325 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
326 #define PEGBOX_SELECT BUTTON_CUSTOM
327 #define PEGBOX_QUIT BUTTON_BACK
328 #define PEGBOX_RESTART BUTTON_SELECT
329 #define PEGBOX_LVL_UP BUTTON_PLAY
330 #define PEGBOX_LVL_DOWN BUTTON_MENU
331 #define PEGBOX_UP BUTTON_UP
332 #define PEGBOX_DOWN BUTTON_DOWN
333 #define PEGBOX_RIGHT BUTTON_RIGHT
334 #define PEGBOX_LEFT BUTTON_LEFT
336 #define SELECT_TEXT "CUSTOM"
337 #define QUIT_TEXT "BACK"
338 #define RESTART_TEXT "MIDDLE"
339 #define LVL_UP_TEXT "SELECT"
340 #define LVL_DOWN_TEXT "MENU"
342 #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
343 #define PEGBOX_SELECT BUTTON_VIEW
344 #define PEGBOX_QUIT BUTTON_POWER
345 #define PEGBOX_RESTART BUTTON_MENU
346 #define PEGBOX_LVL_UP BUTTON_VOL_UP
347 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
348 #define PEGBOX_UP BUTTON_UP
349 #define PEGBOX_DOWN BUTTON_DOWN
350 #define PEGBOX_RIGHT BUTTON_RIGHT
351 #define PEGBOX_LEFT BUTTON_LEFT
353 #define SELECT_TEXT "VIEW"
354 #define QUIT_TEXT "POWER"
355 #define RESTART_TEXT "MENU"
356 #define LVL_UP_TEXT "VOL+"
357 #define LVL_DOWN_TEXT "VOL-"
359 #elif CONFIG_KEYPAD == PHILIPS_HDD6330_PAD
360 #define PEGBOX_SELECT BUTTON_NEXT
361 #define PEGBOX_QUIT BUTTON_POWER
362 #define PEGBOX_RESTART BUTTON_MENU
363 #define PEGBOX_LVL_UP BUTTON_VOL_UP
364 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
365 #define PEGBOX_UP BUTTON_UP
366 #define PEGBOX_DOWN BUTTON_DOWN
367 #define PEGBOX_RIGHT BUTTON_RIGHT
368 #define PEGBOX_LEFT BUTTON_LEFT
370 #define SELECT_TEXT "NEXT"
371 #define QUIT_TEXT "POWER"
372 #define RESTART_TEXT "MENU"
373 #define LVL_UP_TEXT "VOL+"
374 #define LVL_DOWN_TEXT "VOL-"
376 #elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
377 #define PEGBOX_SELECT BUTTON_RIGHT
378 #define PEGBOX_QUIT BUTTON_POWER
379 #define PEGBOX_RESTART BUTTON_MENU
380 #define PEGBOX_LVL_UP BUTTON_VOL_UP
381 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
382 #define PEGBOX_UP BUTTON_UP
383 #define PEGBOX_DOWN BUTTON_DOWN
384 #define PEGBOX_RIGHT BUTTON_NEXT
385 #define PEGBOX_LEFT BUTTON_PREV
387 #define SELECT_TEXT "RIGHT"
388 #define QUIT_TEXT "POWER"
389 #define RESTART_TEXT "MENU"
390 #define LVL_UP_TEXT "VOL+"
391 #define LVL_DOWN_TEXT "VOL-"
393 #elif CONFIG_KEYPAD == ONDAVX747_PAD || \
394 CONFIG_KEYPAD == ONDAVX777_PAD || \
395 CONFIG_KEYPAD == MROBE500_PAD
396 #define PEGBOX_QUIT BUTTON_POWER
398 #define QUIT_TEXT "POWER"
400 #elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
401 #define PEGBOX_SAVE (BUTTON_REC|BUTTON_FFWD)
402 #define PEGBOX_QUIT (BUTTON_REC|BUTTON_PLAY)
403 #define PEGBOX_RESTART (BUTTON_REC|BUTTON_REW)
404 #define PEGBOX_LVL_UP BUTTON_FFWD
405 #define PEGBOX_LVL_DOWN BUTTON_REW
406 #define PEGBOX_UP BUTTON_UP
407 #define PEGBOX_DOWN BUTTON_DOWN
408 #define PEGBOX_RIGHT BUTTON_RIGHT
409 #define PEGBOX_LEFT BUTTON_LEFT
410 #define PEGBOX_SELECT BUTTON_PLAY
412 #define SAVE_TEXT "REC + FFWD"
413 #define QUIT_TEXT "REC + PLAY"
414 #define RESTART_TEXT "REC + REW"
415 #define LVL_UP_TEXT "FFWD"
416 #define LVL_DOWN_TEXT "REW"
417 #define SELECT_TEXT "PLAY"
419 #elif CONFIG_KEYPAD == PBELL_VIBE500_PAD
420 #define PEGBOX_SAVE (BUTTON_REC|BUTTON_OK)
421 #define PEGBOX_QUIT BUTTON_REC
422 #define PEGBOX_RESTART BUTTON_MENU
423 #define PEGBOX_LVL_UP BUTTON_OK
424 #define PEGBOX_LVL_DOWN BUTTON_CANCEL
425 #define PEGBOX_UP BUTTON_UP
426 #define PEGBOX_DOWN BUTTON_DOWN
427 #define PEGBOX_RIGHT BUTTON_NEXT
428 #define PEGBOX_LEFT BUTTON_PREV
429 #define PEGBOX_SELECT BUTTON_PLAY
431 #define SAVE_TEXT "REC + OK"
432 #define QUIT_TEXT "REC"
433 #define RESTART_TEXT "MENU"
434 #define LVL_UP_TEXT "OK"
435 #define LVL_DOWN_TEXT "CANCEL"
436 #define SELECT_TEXT "PLAY"
438 #elif CONFIG_KEYPAD == MPIO_HD200_PAD
439 #define PEGBOX_SAVE (BUTTON_PLAY|BUTTON_FUNC)
440 #define PEGBOX_QUIT (BUTTON_REC|BUTTON_PLAY)
441 #define PEGBOX_RESTART BUTTON_REC
442 #define PEGBOX_LVL_UP (BUTTON_PLAY|BUTTON_REW)
443 #define PEGBOX_LVL_DOWN (BUTTON_PLAY|BUTTON_FF)
444 #define PEGBOX_UP BUTTON_REW
445 #define PEGBOX_DOWN BUTTON_FF
446 #define PEGBOX_RIGHT BUTTON_VOL_UP
447 #define PEGBOX_LEFT BUTTON_VOL_DOWN
448 #define PEGBOX_SELECT BUTTON_FUNC
450 #define SAVE_TEXT "PLAY + FUNC"
451 #define QUIT_TEXT "REC + PLAY"
452 #define RESTART_TEXT "REC"
453 #define LVL_UP_TEXT "REW"
454 #define LVL_DOWN_TEXT "FF"
455 #define SELECT_TEXT "FUNC"
457 #elif CONFIG_KEYPAD == MPIO_HD300_PAD
458 #define PEGBOX_SAVE (BUTTON_ENTER | BUTTON_REPEAT)
459 #define PEGBOX_QUIT (BUTTON_MENU | BUTTON_REPEAT)
460 #define PEGBOX_RESTART (BUTTON_MENU | BUTTON_REL)
461 #define PEGBOX_LVL_UP BUTTON_PLAY
462 #define PEGBOX_LVL_DOWN BUTTON_REC
463 #define PEGBOX_UP BUTTON_UP
464 #define PEGBOX_DOWN BUTTON_DOWN
465 #define PEGBOX_RIGHT BUTTON_FF
466 #define PEGBOX_LEFT BUTTON_REW
467 #define PEGBOX_SELECT (BUTTON_ENTER | BUTTON_REL)
469 #define SAVE_TEXT "Long ENTER"
470 #define QUIT_TEXT "Long MENU"
471 #define RESTART_TEXT "MENU"
472 #define LVL_UP_TEXT "PLAY"
473 #define LVL_DOWN_TEXT "REC"
474 #define SELECT_TEXT "ENTER"
476 #elif CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD
477 #define PEGBOX_QUIT BUTTON_POWER
478 #define PEGBOX_SAVE BUTTON_PLAYPAUSE
479 #define PEGBOX_RESTART BUTTON_BACK
480 #define PEGBOX_LVL_UP BUTTON_VOL_UP
481 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
482 #define PEGBOX_UP BUTTON_UP
483 #define PEGBOX_DOWN BUTTON_DOWN
484 #define PEGBOX_RIGHT BUTTON_RIGHT
485 #define PEGBOX_LEFT BUTTON_LEFT
486 #define PEGBOX_SELECT BUTTON_SELECT
488 #define SAVE_TEXT "PLAYPAUSE"
489 #define QUIT_TEXT "POWER"
490 #define RESTART_TEXT "BACK"
491 #define LVL_UP_TEXT "Vol+"
492 #define LVL_DOWN_TEXT "Vol-"
493 #define SELECT_TEXT "SELECT"
495 #elif CONFIG_KEYPAD == SANSA_CONNECT_PAD
496 #define PEGBOX_SELECT BUTTON_SELECT
497 #define PEGBOX_QUIT BUTTON_POWER
498 #define PEGBOX_SAVE BUTTON_VOL_UP
499 #define PEGBOX_RESTART BUTTON_VOL_DOWN
500 #define PEGBOX_LVL_UP BUTTON_NEXT
501 #define PEGBOX_LVL_DOWN BUTTON_PREV
502 #define PEGBOX_UP BUTTON_UP
503 #define PEGBOX_DOWN BUTTON_DOWN
504 #define PEGBOX_RIGHT BUTTON_RIGHT
505 #define PEGBOX_LEFT BUTTON_LEFT
507 #define SAVE_TEXT "Vol+"
508 #define QUIT_TEXT "POWER"
509 #define RESTART_TEXT "Vol-"
510 #define LVL_UP_TEXT "NEXT"
511 #define LVL_DOWN_TEXT "PREV"
512 #define SELECT_TEXT "SELECT"
514 #elif CONFIG_KEYPAD == SAMSUNG_YPR0_PAD
515 #define PEGBOX_SELECT BUTTON_SELECT
516 #define PEGBOX_QUIT BUTTON_BACK
517 #define PEGBOX_RESTART BUTTON_MENU
518 #define PEGBOX_LVL_UP BUTTON_USER
519 #define PEGBOX_LVL_DOWN BUTTON_POWER
520 #define PEGBOX_UP BUTTON_UP
521 #define PEGBOX_DOWN BUTTON_DOWN
522 #define PEGBOX_RIGHT BUTTON_RIGHT
523 #define PEGBOX_LEFT BUTTON_LEFT
525 #define SAVE_TEXT "PLAYPAUSE"
526 #define QUIT_TEXT "POWER"
527 #define RESTART_TEXT "BACK"
528 #define LVL_UP_TEXT "Vol+"
529 #define LVL_DOWN_TEXT "Vol-"
530 #define SELECT_TEXT "SELECT"
532 #elif CONFIG_KEYPAD == HM60X_PAD
533 #define PEGBOX_SELECT BUTTON_SELECT
534 #define PEGBOX_QUIT BUTTON_POWER
535 #define PEGBOX_SAVE (BUTTON_POWER|BUTTON_SELECT)
536 #define PEGBOX_RESTART (BUTTON_POWER|BUTTON_LEFT)
537 #define PEGBOX_LVL_UP (BUTTON_POWER|BUTTON_UP)
538 #define PEGBOX_LVL_DOWN (BUTTON_POWER|BUTTON_DOWN)
539 #define PEGBOX_UP BUTTON_UP
540 #define PEGBOX_DOWN BUTTON_DOWN
541 #define PEGBOX_RIGHT BUTTON_RIGHT
542 #define PEGBOX_LEFT BUTTON_LEFT
544 #define SAVE_TEXT "POWER + SELECT"
545 #define QUIT_TEXT "POWER"
546 #define RESTART_TEXT "POWER + LEFT"
547 #define LVL_UP_TEXT "POWER + UP"
548 #define LVL_DOWN_TEXT "POWER + DOWN"
549 #define SELECT_TEXT "SELECT"
551 #elif CONFIG_KEYPAD == HM801_PAD
552 #define PEGBOX_SELECT BUTTON_SELECT
553 #define PEGBOX_QUIT BUTTON_POWER
554 #define PEGBOX_SAVE BUTTON_PLAY
555 #define PEGBOX_RESTART (BUTTON_POWER|BUTTON_PREV)
556 #define PEGBOX_LVL_UP BUTTON_NEXT
557 #define PEGBOX_LVL_DOWN BUTTON_PREV
558 #define PEGBOX_UP BUTTON_UP
559 #define PEGBOX_DOWN BUTTON_DOWN
560 #define PEGBOX_RIGHT BUTTON_RIGHT
561 #define PEGBOX_LEFT BUTTON_LEFT
563 #define SAVE_TEXT "PLAY"
564 #define QUIT_TEXT "POWER"
565 #define RESTART_TEXT "POWER + PREV"
566 #define LVL_UP_TEXT "NEXT"
567 #define LVL_DOWN_TEXT "PREV"
568 #define SELECT_TEXT "SELECT"
570 #else
571 #error Unsupported keymap!
572 #endif
574 #ifdef HAVE_TOUCHSCREEN
575 #ifndef PEGBOX_QUIT
576 #define PEGBOX_QUIT BUTTON_TOPLEFT
577 #endif
578 #ifndef PEGBOX_SELECT
579 #define PEGBOX_SELECT BUTTON_CENTER
580 #endif
581 #ifndef PEGBOX_RESTART
582 #define PEGBOX_RESTART BUTTON_TOPRIGHT
583 #endif
584 #ifndef PEGBOX_LVL_UP
585 #define PEGBOX_LVL_UP BUTTON_BOTTOMLEFT
586 #endif
587 #ifndef PEGBOX_LVL_DOWN
588 #define PEGBOX_LVL_DOWN BUTTON_BOTTOMRIGHT
589 #endif
590 #ifndef PEGBOX_UP
591 #define PEGBOX_UP BUTTON_TOPMIDDLE
592 #endif
593 #ifndef PEGBOX_DOWN
594 #define PEGBOX_DOWN BUTTON_BOTTOMMIDDLE
595 #endif
596 #ifndef PEGBOX_RIGHT
597 #define PEGBOX_RIGHT BUTTON_MIDRIGHT
598 #endif
599 #ifndef PEGBOX_LEFT
600 #define PEGBOX_LEFT BUTTON_MIDLEFT
601 #endif
602 #ifndef SELECT_TEXT
603 #define SELECT_TEXT "CENTER"
604 #endif
605 #ifndef QUIT_TEXT
606 #define QUIT_TEXT "TOPLEFT"
607 #endif
608 #ifndef RESTART_TEXT
609 #define RESTART_TEXT "TOPRIGHT"
610 #endif
611 #ifndef LVL_UP_TEXT
612 #define LVL_UP_TEXT "BOTTOMLEFT"
613 #endif
614 #ifndef LVL_DOWN_TEXT
615 #define LVL_DOWN_TEXT "BOTTOMRIGHT"
616 #endif
617 #endif
620 /* get several sizes from the bitmaps */
621 #ifdef BMPWIDTH_pegbox_pieces
622 #define PIECE_WIDTH BMPWIDTH_pegbox_pieces
623 #define PIECE_HEIGHT (BMPHEIGHT_pegbox_pieces/7)
624 #else
625 /* dummy numbers to avoid #error in dependency generation */
626 #define PIECE_WIDTH 50
627 #define PIECE_HEIGHT 10
628 #endif
630 #define BOARD_WIDTH (12*PIECE_WIDTH)
631 #define BOARD_HEIGHT (8*PIECE_HEIGHT)
634 /* define a wide layout where the statistics are alongside the board, not above
635 * base calculation on the piece bitmaps for the 8x12 board */
636 #if (LCD_WIDTH - BOARD_WIDTH) > (LCD_HEIGHT - BOARD_HEIGHT)
637 #define WIDE_LAYOUT
638 #endif
641 #define HEADER_WIDTH BMPWIDTH_pegbox_header
642 #define HEADER_HEIGHT BMPHEIGHT_pegbox_header
645 #if defined WIDE_LAYOUT
647 #if ((BOARD_WIDTH + HEADER_WIDTH + 4) <= LCD_WIDTH)
648 #define BOARD_X 2
649 #else
650 #define BOARD_X 1
651 #endif
652 #define BOARD_Y (LCD_HEIGHT-BOARD_HEIGHT)/2
654 #if (LCD_WIDTH >= 132) && (LCD_HEIGHT >= 80)
655 #define TEXT_X 116
656 #define LEVEL_TEXT_Y 14
657 #define PEGS_TEXT_Y 58
658 #elif (LCD_WIDTH >= 128) && (LCD_HEIGHT >= 64)
659 #define TEXT_X 112
660 #define LEVEL_TEXT_Y 27
661 #define PEGS_TEXT_Y 50
662 #else
663 #error "Unsupported screen size"
664 #endif
666 #else /* "normal" layout */
668 #define BOARD_X (LCD_WIDTH-BOARD_WIDTH)/2
669 #if ((BOARD_HEIGHT + HEADER_HEIGHT + 4) <= LCD_HEIGHT)
670 #define BOARD_Y HEADER_HEIGHT+2
671 #else
672 #define BOARD_Y HEADER_HEIGHT
673 #endif
675 #if LCD_WIDTH >= 640
676 #define LEVEL_TEXT_X 118
677 #define PEGS_TEXT_X 552
678 #define TEXT_Y 56
679 #elif LCD_WIDTH >= 320
680 #define LEVEL_TEXT_X 59
681 #define PEGS_TEXT_X 276
682 #define TEXT_Y 28
683 #elif LCD_WIDTH >= 240
684 #define LEVEL_TEXT_X 59
685 #define PEGS_TEXT_X 196
686 #define TEXT_Y 28
687 #elif LCD_WIDTH >= 220
688 #define LEVEL_TEXT_X 49
689 #define PEGS_TEXT_X 186
690 #define TEXT_Y 28
691 #elif LCD_WIDTH >= 176
692 #define LEVEL_TEXT_X 38
693 #define PEGS_TEXT_X 155
694 #define TEXT_Y 17
695 #elif LCD_WIDTH >= 160
696 #define LEVEL_TEXT_X 37
697 #define PEGS_TEXT_X 140
698 #define TEXT_Y 13
699 #elif LCD_WIDTH >= 138
700 #define LEVEL_TEXT_X 28
701 #define PEGS_TEXT_X 119
702 #define TEXT_Y 15
703 #elif LCD_WIDTH >= 128
704 #if HEADER_HEIGHT > 16
705 #define LEVEL_TEXT_X 26
706 #define PEGS_TEXT_X 107
707 #define TEXT_Y 31
708 #else
709 #define LEVEL_TEXT_X 15
710 #define PEGS_TEXT_X 100
711 #define TEXT_Y 5
712 #endif /* HEADER_HEIGHT */
713 #elif LCD_WIDTH >= 112
714 #define LEVEL_TEXT_X 25
715 #define PEGS_TEXT_X 90
716 #define TEXT_Y 0
717 #elif LCD_WIDTH >= 96
718 #define LEVEL_TEXT_X 25
719 #define PEGS_TEXT_X 86
720 #define TEXT_Y 22
721 #endif /* LCD_WIDTH */
723 #endif /* WIDE_LAYOUT */
726 #ifdef HAVE_LCD_COLOR
727 #define BG_COLOR LCD_BLACK
728 #define TEXT_BG LCD_RGBPACK(189,189,189)
729 #endif
732 #ifdef HAVE_TOUCHSCREEN
733 #include "lib/pluginlib_touchscreen.h"
734 static struct ts_raster pegbox_raster =
735 { BOARD_X, BOARD_Y, COLS*PIECE_WIDTH, ROWS*PIECE_HEIGHT,
736 PIECE_WIDTH, PIECE_HEIGHT };
737 static struct ts_raster_button_mapping pegbox_raster_btn =
738 { &pegbox_raster, false, false, true, false, true, {0, 0}, 0, 0, 0 };
739 #endif
742 struct game_context {
743 unsigned int level;
744 unsigned int highlevel;
745 signed int player_row;
746 signed int player_col;
747 unsigned int num_left;
748 unsigned int playboard[ROWS][COLS];
751 char levels[NUM_LEVELS][ROWS][COLS] = {
752 /* Level 1 */
753 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
754 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
755 {1, 0, 0, 0, 7, 0, 0, 5, 0, 0, 0, 1,},
756 {1, 0, 0, 0, 0, 3, 3, 2, 0, 0, 0, 1,},
757 {1, 0, 0, 0, 4, 6, 0, 5, 0, 0, 0, 1,},
758 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
759 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
760 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
762 /* Level 2 */
763 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
764 {1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 1,},
765 {1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1,},
766 {1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1,},
767 {7, 0, 0, 0, 2, 2, 5, 5, 0, 0, 0, 1,},
768 {1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1,},
769 {1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1,},
770 {1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 1,}},
772 /* Level 3 */
773 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
774 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
775 {1, 0, 0, 0, 0, 0, 2, 0, 7, 0, 0, 0,},
776 {1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 2, 1,},
777 {1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1,},
778 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1,},
779 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
780 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
782 /* Level 4 */
783 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
784 {6, 0, 4, 0, 2, 0, 2, 0, 0, 0, 0, 1,},
785 {6, 0, 3, 0, 5, 0, 2, 0, 0, 0, 0, 1,},
786 {6, 0, 5, 0, 4, 7, 2, 0, 0, 0, 0, 1,},
787 {6, 0, 2, 0, 4, 0, 2, 0, 3, 0, 0, 1,},
788 {6, 0, 4, 0, 5, 0, 2, 0, 0, 0, 0, 1,},
789 {6, 0, 5, 0, 4, 0, 2, 0, 0, 0, 0, 1,},
790 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
792 /* Level 5 */
793 {{0, 6, 6, 0, 4, 6, 0, 0, 6, 0, 0, 0,},
794 {0, 6, 6, 0, 4, 4, 0, 0, 6, 0, 0, 2,},
795 {2, 6, 6, 0, 6, 6, 6, 0, 1, 2, 2, 2,},
796 {0, 6, 6, 0, 6, 4, 6, 0, 1, 2, 0, 2,},
797 {0, 6, 6, 0, 6, 7, 6, 5, 6, 0, 0, 0,},
798 {2, 6, 6, 0, 6, 6, 6, 0, 6, 0, 0, 0,},
799 {0, 6, 6, 0, 4, 0, 0, 0, 6, 0, 0, 0,},
800 {0, 6, 6, 0, 0, 5, 0, 0, 6, 5, 5, 0,}},
802 /* Level 6 */
803 {{7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
804 {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,},
805 {2, 0, 0, 2, 0, 0, 0, 2, 2, 0, 0, 0,},
806 {0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 0,},
807 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
808 {0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1,},
809 {0, 3, 0, 0, 0, 0, 0, 0, 5, 4, 6, 0,},
810 {0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1,}},
812 /* Level 7 */
813 {{1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1,},
814 {1, 1, 1, 6, 0, 0, 4, 6, 0, 1, 1, 1,},
815 {1, 1, 1, 1, 0, 1, 5, 1, 0, 1, 1, 1,},
816 {1, 1, 1, 2, 3, 3, 7, 4, 2, 6, 1, 1,},
817 {1, 1, 1, 1, 0, 1, 2, 1, 0, 0, 0, 1,},
818 {1, 1, 1, 1, 0, 0, 5, 0, 0, 1, 0, 1,},
819 {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1,},
820 {1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,}},
822 /* Level 8 */
823 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
824 {0, 0, 3, 3, 3, 3, 3, 4, 3, 3, 0, 0,},
825 {0, 0, 3, 3, 3, 2, 3, 3, 5, 3, 0, 0,},
826 {7, 0, 3, 3, 3, 2, 3, 3, 4, 3, 0, 0,},
827 {0, 0, 3, 3, 4, 5, 3, 3, 3, 3, 0, 0,},
828 {0, 0, 3, 3, 5, 2, 3, 3, 3, 3, 0, 0,},
829 {0, 0, 3, 3, 2, 4, 3, 3, 3, 3, 0, 0,},
830 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
832 /* Level 9 */
833 {{0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,},
834 {0, 3, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,},
835 {0, 0, 0, 0, 2, 4, 4, 3, 0, 1, 1, 0,},
836 {0, 1, 0, 0, 2, 1, 0, 0, 0, 1, 1, 1,},
837 {0, 0, 0, 2, 2, 7, 1, 0, 0, 0, 0, 2,},
838 {0, 0, 0, 0, 2, 1, 0, 0, 1, 1, 1, 1,},
839 {0, 3, 1, 0, 2, 5, 5, 0, 0, 0, 3, 0,},
840 {0, 0, 0, 0, 4, 1, 0, 0, 0, 0, 0, 0,}},
842 /* Level 10 */
843 {{1, 1, 1, 1, 2, 1, 1, 1, 0, 0, 0, 0,},
844 {1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 7,},
845 {0, 0, 4, 0, 6, 6, 6, 0, 0, 0, 3, 0,},
846 {0, 3, 3, 0, 6, 6, 6, 0, 4, 3, 4, 0,},
847 {0, 3, 3, 0, 6, 6, 6, 0, 4, 3, 4, 0,},
848 {0, 0, 0, 0, 6, 6, 6, 0, 3, 0, 0, 0,},
849 {1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0,},
850 {1, 1, 1, 1, 1, 2, 1, 1, 0, 0, 0, 0,}},
852 /* Level 11 */
853 {{1, 7, 1, 0, 1, 1, 6, 0, 0, 1, 1, 0,},
854 {1, 0, 0, 0, 5, 4, 6, 6, 0, 2, 2, 0,},
855 {1, 2, 1, 2, 0, 1, 6, 0, 0, 2, 2, 0,},
856 {1, 0, 0, 2, 0, 1, 0, 0, 0, 3, 3, 0,},
857 {1, 2, 1, 0, 0, 1, 0, 1, 0, 3, 3, 0,},
858 {0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0,},
859 {0, 3, 4, 3, 0, 1, 0, 1, 0, 0, 0, 0,},
860 {0, 0, 0, 0, 2, 2, 2, 1, 1, 1, 1, 1,}},
862 /* Level 12 */
863 {{7, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,},
864 {1, 2, 1, 2, 1, 2, 1, 1, 0, 0, 0, 1,},
865 {0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1,},
866 {1, 2, 1, 2, 1, 2, 1, 0, 0, 0, 0, 1,},
867 {0, 0, 0, 0, 0, 0, 1, 1, 5, 5, 6, 1,},
868 {1, 2, 1, 2, 1, 2, 1, 1, 0, 2, 2, 1,},
869 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1,},
870 {1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1,}},
872 /* Level 13 */
873 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
874 {0, 0, 4, 0, 2, 0, 5, 0, 4, 0, 0, 6,},
875 {0, 0, 2, 0, 5, 0, 2, 0, 4, 0, 0, 6,},
876 {7, 0, 3, 0, 4, 0, 5, 0, 4, 0, 0, 6,},
877 {0, 0, 5, 0, 4, 0, 2, 0, 4, 0, 0, 6,},
878 {0, 0, 4, 0, 2, 0, 5, 0, 4, 0, 0, 6,},
879 {0, 0, 3, 0, 3, 0, 2, 0, 4, 0, 0, 6,},
880 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
882 /* Level 14 */
883 {{1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1,},
884 {1, 1, 0, 2, 0, 0, 4, 0, 0, 2, 0, 1,},
885 {1, 6, 0, 0, 5, 1, 0, 1, 1, 0, 0, 1,},
886 {1, 1, 1, 0, 0, 3, 5, 3, 0, 0, 1, 1,},
887 {1, 1, 0, 0, 1, 1, 0, 1, 5, 0, 0, 6,},
888 {1, 1, 0, 2, 0, 0, 4, 0, 0, 0, 7, 1,},
889 {1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1,},
890 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
892 /* Level 15 */
893 {{0, 0, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
894 {0, 0, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
895 {0, 3, 4, 6, 0, 6, 0, 6, 0, 6, 0, 2,},
896 {0, 4, 0, 6, 0, 6, 4, 6, 0, 6, 0, 1,},
897 {0, 3, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
898 {7, 0, 0, 6, 4, 6, 0, 6, 0, 6, 0, 1,},
899 {0, 0, 4, 6, 0, 6, 0, 6, 4, 6, 0, 1,},
900 {0, 0, 4, 6, 0, 6, 0, 6, 0, 6, 0, 1,}}
903 /***********************************************************************
904 * pegbox_draw_board() draws the game's current level.
905 ************************************************************************/
906 static void pegbox_draw_board(struct game_context* pb)
908 unsigned int r, c, type;
909 pb->num_left = 0;
911 rb->lcd_clear_display();
912 #ifdef WIDE_LAYOUT
913 rb->lcd_bitmap(pegbox_header,LCD_WIDTH-HEADER_WIDTH,0,
914 HEADER_WIDTH,LCD_HEIGHT);
915 #else
916 rb->lcd_bitmap(pegbox_header,(LCD_WIDTH-HEADER_WIDTH)/2,0,
917 HEADER_WIDTH, HEADER_HEIGHT);
918 #endif /* WIDE_LAYOUT */
920 #if ((BOARD_HEIGHT + HEADER_HEIGHT + 4) <= LCD_HEIGHT)
921 rb->lcd_drawrect(BOARD_X-2,BOARD_Y-2,BOARD_WIDTH+4,BOARD_HEIGHT+4);
922 #endif /* enough space for a frame? */
924 #ifdef HAVE_LCD_COLOR
925 rb->lcd_set_foreground(LCD_WHITE);
926 #if ((BOARD_HEIGHT + HEADER_HEIGHT + 2) <= LCD_HEIGHT)
927 rb->lcd_fillrect(BOARD_X-1,BOARD_Y-1,BOARD_WIDTH+2,BOARD_HEIGHT+2);
928 #else
929 rb->lcd_fillrect(BOARD_X,BOARD_Y,BOARD_WIDTH,BOARD_HEIGHT);
930 #endif
931 rb->lcd_set_foreground(LCD_BLACK);
932 rb->lcd_set_background(TEXT_BG);
933 #endif
935 for (r=0 ; r < ROWS ; r++) {
936 for (c = 0 ; c < COLS ; c++) {
938 type = pb->playboard[r][c];
940 if(type != SPACE) {
941 rb->lcd_bitmap_part(pegbox_pieces, 0, (type-1)*PIECE_HEIGHT,
942 STRIDE( SCREEN_MAIN,
943 BMPWIDTH_pegbox_pieces,BMPHEIGHT_pegbox_pieces),
944 c * PIECE_WIDTH + BOARD_X,
945 r * PIECE_HEIGHT + BOARD_Y, PIECE_WIDTH,
946 PIECE_HEIGHT);
949 if(pb->playboard[r][c] == PLAYER) {
950 pb->player_row=r;
951 pb->player_col=c;
953 else if (type != WALL && type != SPACE && type != HOLE)
954 pb->num_left++;
958 #ifdef WIDE_LAYOUT
959 rb->lcd_putsxyf(TEXT_X, LEVEL_TEXT_Y, "%d", pb->level);
960 rb->lcd_putsxyf(TEXT_X, PEGS_TEXT_Y, "%d", pb->num_left);
961 #else
962 rb->lcd_putsxyf(LEVEL_TEXT_X, TEXT_Y, "%d", pb->level);
963 rb->lcd_putsxyf(PEGS_TEXT_X, TEXT_Y, "%d", pb->num_left);
964 #endif /*WIDE_LAYOUT*/
966 #ifdef HAVE_LCD_COLOR
967 rb->lcd_set_background(BG_COLOR);
968 rb->lcd_set_foreground(LCD_WHITE);
969 #endif
970 /* print out the screen */
971 rb->lcd_update();
974 /*****************************************************************************
975 * pegbox_load_level() loads the player's current level from the array and sets the
976 * player's position.
977 ******************************************************************************/
978 static void pegbox_load_level(struct game_context* pb)
980 int r, c;
982 for(r = 0; r < ROWS; r++)
983 for(c = 0; c < COLS; c++)
984 pb->playboard[r][c] = levels[pb->level-1][r][c];
987 /*****************************************************************************
988 * pegbox_new_piece() creates a new piece at a specified location. The player
989 * navigates through the pieces and selects one.
990 ******************************************************************************/
991 static void pegbox_new_piece(struct game_context* pb, unsigned int x_loc,
992 unsigned int y_loc)
994 int button;
995 bool exit = false;
997 pb->playboard[x_loc][y_loc] = TRIANGLE;
999 while (!exit) {
1000 pegbox_draw_board(pb);
1001 button = rb->button_get(true);
1002 #ifdef HAVE_TOUCHSCREEN
1003 if(button & BUTTON_TOUCHSCREEN)
1005 pegbox_raster_btn.two_d_from.y = x_loc;
1006 pegbox_raster_btn.two_d_from.x = y_loc;
1008 struct ts_raster_button_result ret =
1009 touchscreen_raster_map_button(&pegbox_raster_btn,
1010 rb->button_get_data() >> 16,
1011 rb->button_get_data() & 0xffff,
1012 button);
1013 if(ret.action == TS_ACTION_TWO_D_MOVEMENT)
1015 if(ret.to.x > ret.from.x)
1016 button = PEGBOX_UP;
1017 else if(ret.to.x < ret.from.x)
1018 button = PEGBOX_DOWN;
1019 else if(ret.to.y > ret.from.y)
1020 button = PEGBOX_LEFT;
1021 else if(ret.to.y < ret.from.y)
1022 button = PEGBOX_RIGHT;
1024 else if(ret.action == TS_ACTION_CLICK
1025 && (unsigned)ret.to.x == y_loc
1026 && (unsigned)ret.to.y == x_loc)
1027 button = PEGBOX_SELECT;
1029 #endif
1030 switch(button){
1031 case PEGBOX_LEFT:
1032 case (PEGBOX_LEFT|BUTTON_REPEAT):
1033 case PEGBOX_DOWN:
1034 case (PEGBOX_DOWN|BUTTON_REPEAT):
1035 if (pb->playboard[x_loc][y_loc] < 5)
1036 pb->playboard[x_loc][y_loc]++;
1037 else
1038 pb->playboard[x_loc][y_loc] = TRIANGLE;
1039 break;
1040 case PEGBOX_RIGHT:
1041 case (PEGBOX_RIGHT|BUTTON_REPEAT):
1042 case PEGBOX_UP:
1043 case (PEGBOX_UP|BUTTON_REPEAT):
1044 if (pb->playboard[x_loc][y_loc] > 2)
1045 pb->playboard[x_loc][y_loc]--;
1046 else
1047 pb->playboard[x_loc][y_loc] = CIRCLE;
1048 break;
1049 case PEGBOX_SELECT:
1050 exit=true;
1051 break;
1056 /*****************************************************************************
1057 * pegbox_move_player() moves the player and pieces and updates the board accordingly.
1058 ******************************************************************************/
1059 static void pegbox_move_player(struct game_context* pb, signed int x_dir,
1060 signed int y_dir)
1062 unsigned int type1, type2;
1063 signed int r1,c1,r2,c2;
1065 r1 = pb->player_row+y_dir;
1066 c1 = pb->player_col+x_dir;
1067 r2 = pb->player_row+y_dir*2;
1068 c2 = pb->player_col+x_dir*2;
1070 type1 = pb->playboard[r1][c1];
1071 type2 = pb->playboard[r2][c2];
1073 if (r1 == ROWS || c1 == COLS || r1 < 0 || c1 < 0 || type1 == WALL)
1074 return;
1075 else if(type1 != SPACE) {
1076 if (r2 == ROWS || c2 == COLS || r2 < 0 || c2 < 0 || type2 == WALL)
1077 return;
1081 pb->playboard[pb->player_row][pb->player_col] = SPACE;
1082 pb->player_row += y_dir;
1083 pb->player_col += x_dir;
1085 if (type1 == HOLE) {
1086 pegbox_draw_board(pb);
1087 rb->splash(HZ*2, "You fell down a hole!");
1088 pegbox_load_level(pb);
1090 else if (type1 == SPACE)
1091 pb->playboard[r1][c1] = PLAYER;
1092 else {
1093 pb->playboard[r1][c1] = PLAYER;
1094 if(type1 == type2) {
1095 if (type1 == TRIANGLE)
1096 pb->playboard[r2][c2] = WALL;
1097 else if (type1 == CROSS) {
1098 pb->playboard[r1][c1] = SPACE;
1099 pegbox_new_piece(pb, r2, c2);
1100 pb->playboard[r1][c1] = PLAYER;
1102 else
1103 pb->playboard[r2][c2] = SPACE;
1105 else if (type2 == SPACE)
1106 pb->playboard[r2][c2] = type1;
1107 else if (type2 == HOLE) {
1108 if (type1 == SQUARE)
1109 pb->playboard[r2][c2] = SPACE;
1111 else {
1112 rb->splash(HZ*2, "Illegal Move!");
1113 pegbox_load_level(pb);
1117 pegbox_draw_board(pb);
1120 /***********************************************************************
1121 * pegbox_help() display help text
1122 ************************************************************************/
1123 static bool pegbox_help(void)
1125 static char* help_text[] = {
1126 "Pegbox", "", "Aim", "",
1127 "To", "beat", "each", "level,", "you", "must", "destroy", "all", "of",
1128 "the", "pegs.", "If", "two", "like", "pegs", "are", "pushed", "into",
1129 "each", "other,", "they", "disappear", "except", "for", "triangles",
1130 "which", "form", "a", "solid", "block", "and", "crosses", "which",
1131 "allow", "you", "to", "choose", "a", "replacement", "block.", "", "",
1132 "Controls", "",
1133 RESTART_TEXT, "to", "restart", "level", "",
1134 LVL_UP_TEXT, "to", "go", "up", "a", "level", "",
1135 LVL_DOWN_TEXT, "to", "go", "down", "a", "level", "",
1136 SELECT_TEXT, "to", "choose", "peg", "",
1137 QUIT_TEXT, "to", "quit"
1139 static struct style_text formation[]={
1140 { 0, TEXT_CENTER|TEXT_UNDERLINE },
1141 { 2, C_RED },
1142 { 46, C_RED },
1143 LAST_STYLE_ITEM
1146 rb->lcd_setfont(FONT_UI);
1147 if (display_text(ARRAYLEN(help_text), help_text, formation, NULL, true))
1148 return true;
1149 rb->lcd_setfont(FONT_SYSFIXED);
1151 return false;
1154 /***********************************************************************
1155 * pegbox_menu() is the game menu
1156 ************************************************************************/
1157 static bool _ingame;
1158 static int pegbox_menu_cb(int action, const struct menu_item_ex *this_item)
1160 int i = (intptr_t)this_item;
1161 if( action == ACTION_REQUEST_MENUITEM )
1163 if((!_ingame && (i==0 || i==1)) || ( _ingame && i==2 ))
1164 return ACTION_EXIT_MENUITEM;
1166 return action;
1169 static unsigned int pegbox_menu(struct game_context* pb, bool ingame)
1171 int selected = 0;
1172 int last_level = pb->level;
1174 MENUITEM_STRINGLIST (main_menu, "Pegbox Menu", pegbox_menu_cb,
1175 "Resume Game", "Restart Level", "Start Game",
1176 "Select Level", "Help",
1177 "Playback Control", "Quit");
1178 _ingame = ingame;
1179 rb->button_clear_queue();
1181 while (true) {
1182 switch (rb->do_menu(&main_menu, &selected, NULL, false)) {
1183 case 0:
1184 pb->level = last_level;
1185 pegbox_draw_board(pb);
1186 return 0;
1187 case 1:
1188 case 2:
1189 pegbox_load_level(pb);
1190 pegbox_draw_board(pb);
1191 return 0;
1192 case 3:
1193 if(rb->set_int("Select Level", "", UNIT_INT, &pb->level,
1194 NULL, 1, 1, pb->highlevel, NULL))
1195 return 1;
1196 break;
1197 case 4:
1198 if (pegbox_help())
1199 return 1;
1200 break;
1201 case 5:
1202 if (playback_control(NULL))
1203 return 1;
1204 break;
1205 case 6:
1206 return 1;
1207 case MENU_ATTACHED_USB:
1208 return 1;
1209 default:
1210 break;
1215 /***********************************************************************
1216 * pegbox_main() is the main game subroutine
1217 ************************************************************************/
1218 static int pegbox_main(struct game_context* pb)
1220 int button;
1222 if (pegbox_menu(pb, false)==1) {
1223 return 1;
1226 while (true) {
1227 button = rb->button_get(true);
1228 #ifdef HAVE_TOUCHSCREEN
1229 if(button & BUTTON_TOUCHSCREEN)
1231 pegbox_raster_btn.two_d_from.y = pb->player_row;
1232 pegbox_raster_btn.two_d_from.x = pb->player_col;
1234 struct ts_raster_button_result ret =
1235 touchscreen_raster_map_button(&pegbox_raster_btn,
1236 rb->button_get_data() >> 16,
1237 rb->button_get_data() & 0xffff,
1238 button);
1239 if(ret.action == TS_ACTION_TWO_D_MOVEMENT)
1240 pegbox_move_player(pb, ret.to.x - ret.from.x, ret.to.y - ret.from.y);
1242 #endif
1243 switch(button){
1244 case PEGBOX_LEFT: /* move cursor left */
1245 case (PEGBOX_LEFT|BUTTON_REPEAT):
1246 pegbox_move_player(pb, -1, 0);
1247 break;
1249 case PEGBOX_RIGHT: /* move cursor right */
1250 case (PEGBOX_RIGHT|BUTTON_REPEAT):
1251 pegbox_move_player(pb, 1, 0);
1252 break;
1254 case PEGBOX_DOWN: /* move cursor down */
1255 case (PEGBOX_DOWN|BUTTON_REPEAT):
1256 pegbox_move_player(pb, 0, 1);
1257 break;
1259 case PEGBOX_UP: /* move cursor up */
1260 case (PEGBOX_UP|BUTTON_REPEAT):
1261 pegbox_move_player(pb, 0, -1);
1262 break;
1264 case PEGBOX_QUIT:
1265 if (pegbox_menu(pb, true)==1) {
1266 return 1;
1268 break;
1270 #ifdef PEGBOX_RESTART
1271 case PEGBOX_RESTART:
1272 pegbox_load_level(pb);
1273 pegbox_draw_board(pb);
1274 break;
1275 #endif
1277 #ifdef PEGBOX_LVL_UP
1278 case (PEGBOX_LVL_UP|BUTTON_REPEAT):
1279 case PEGBOX_LVL_UP:
1280 if (pb->level >= pb->highlevel) {
1281 pb->level = 1;
1282 } else {
1283 pb->level++;
1285 pegbox_load_level(pb);
1286 pegbox_draw_board(pb);
1287 break;
1288 #endif
1290 #ifdef PEGBOX_LVL_DOWN
1291 case (PEGBOX_LVL_DOWN|BUTTON_REPEAT):
1292 case PEGBOX_LVL_DOWN:
1293 if(pb->level <= 1) {
1294 pb->level = pb->highlevel;
1295 } else {
1296 pb->level--;
1298 pegbox_load_level(pb);
1299 pegbox_draw_board(pb);
1300 break;
1301 #endif
1304 if (pb->num_left == 0) {
1305 rb->splash(HZ*2, "Nice Pegging!");
1306 if (pb->level == NUM_LEVELS) {
1307 pegbox_draw_board(pb);
1308 rb->splash(HZ*2, "Congratulations!");
1309 rb->splash(HZ*2, "You have finished the game!");
1310 if (pegbox_menu(pb,false)==1) {
1311 return 1;
1314 else {
1315 pb->level++;
1316 pegbox_load_level(pb);
1317 pegbox_draw_board(pb);
1320 if(pb->level > pb->highlevel)
1321 pb->highlevel = pb->level;
1325 return PLUGIN_OK;
1328 /*****************************************************************************
1329 * plugin entry point.
1330 ******************************************************************************/
1331 enum plugin_status plugin_start(const void* parameter)
1333 (void)parameter;
1334 #ifdef HAVE_LCD_BITMAP
1335 rb->lcd_setfont(FONT_SYSFIXED);
1336 #if LCD_DEPTH > 1
1337 rb->lcd_set_backdrop(NULL);
1338 #endif
1339 #ifdef HAVE_LCD_COLOR
1340 rb->lcd_set_foreground(LCD_WHITE);
1341 rb->lcd_set_background(BG_COLOR);
1342 #endif
1343 rb->lcd_clear_display();
1345 struct game_context pb;
1346 pb.level=1;
1347 pb.highlevel=1;
1348 struct configdata config[] = {
1349 {TYPE_INT, 1, NUM_LEVELS, { .int_p = &(pb.level) }, "level", NULL},
1350 {TYPE_INT, 1, NUM_LEVELS, { .int_p = &(pb.highlevel) }, "highlevel", NULL},
1352 configfile_load(CONFIG_FILE_NAME,config,2,0);
1353 pegbox_main(&pb);
1354 configfile_save(CONFIG_FILE_NAME,config,2,0);
1355 rb->lcd_setfont(FONT_UI);
1356 #endif /* HAVE_LCD_BITMAP */
1358 return PLUGIN_OK;