Fix warning about missing newline at the EOF
[maemo-rb.git] / apps / plugins / pegbox.c
blob479f7c5ec2559bfd5a4a0eb0c554412d2813b82b
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_QUIT BUTTON_REC
459 #define PEGBOX_RESTART (BUTTON_MENU | BUTTON_REC)
460 #define PEGBOX_LVL_UP BUTTON_REW
461 #define PEGBOX_LVL_DOWN BUTTON_FF
462 #define PEGBOX_UP BUTTON_UP
463 #define PEGBOX_DOWN BUTTON_DOWN
464 #define PEGBOX_RIGHT BUTTON_ENTER
465 #define PEGBOX_LEFT BUTTON_MENU
466 #define PEGBOX_SELECT BUTTON_PLAY
468 #define SAVE_TEXT "PLAY + FUNC"
469 #define QUIT_TEXT "REC + PLAY"
470 #define RESTART_TEXT "REC"
471 #define LVL_UP_TEXT "REW"
472 #define LVL_DOWN_TEXT "FF"
473 #define SELECT_TEXT "FUNC"
475 #elif CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD
476 #define PEGBOX_QUIT BUTTON_POWER
477 #define PEGBOX_SAVE BUTTON_PLAYPAUSE
478 #define PEGBOX_RESTART BUTTON_BACK
479 #define PEGBOX_LVL_UP BUTTON_VOL_UP
480 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
481 #define PEGBOX_UP BUTTON_UP
482 #define PEGBOX_DOWN BUTTON_DOWN
483 #define PEGBOX_RIGHT BUTTON_RIGHT
484 #define PEGBOX_LEFT BUTTON_LEFT
485 #define PEGBOX_SELECT BUTTON_SELECT
487 #define SAVE_TEXT "PLAYPAUSE"
488 #define QUIT_TEXT "POWER"
489 #define RESTART_TEXT "BACK"
490 #define LVL_UP_TEXT "Vol+"
491 #define LVL_DOWN_TEXT "Vol-"
492 #define SELECT_TEXT "SELECT"
494 #elif CONFIG_KEYPAD == SANSA_CONNECT_PAD
495 #define PEGBOX_SELECT BUTTON_SELECT
496 #define PEGBOX_QUIT BUTTON_POWER
497 #define PEGBOX_SAVE BUTTON_VOL_UP
498 #define PEGBOX_RESTART BUTTON_VOL_DOWN
499 #define PEGBOX_LVL_UP BUTTON_NEXT
500 #define PEGBOX_LVL_DOWN BUTTON_PREV
501 #define PEGBOX_UP BUTTON_UP
502 #define PEGBOX_DOWN BUTTON_DOWN
503 #define PEGBOX_RIGHT BUTTON_RIGHT
504 #define PEGBOX_LEFT BUTTON_LEFT
506 #define SAVE_TEXT "Vol+"
507 #define QUIT_TEXT "POWER"
508 #define RESTART_TEXT "Vol-"
509 #define LVL_UP_TEXT "NEXT"
510 #define LVL_DOWN_TEXT "PREV"
511 #define SELECT_TEXT "SELECT"
513 #elif CONFIG_KEYPAD == SAMSUNG_YPR0_PAD
514 #define PEGBOX_SELECT BUTTON_SELECT
515 #define PEGBOX_QUIT BUTTON_BACK
516 #define PEGBOX_RESTART BUTTON_MENU
517 #define PEGBOX_LVL_UP BUTTON_USER
518 #define PEGBOX_LVL_DOWN BUTTON_POWER
519 #define PEGBOX_UP BUTTON_UP
520 #define PEGBOX_DOWN BUTTON_DOWN
521 #define PEGBOX_RIGHT BUTTON_RIGHT
522 #define PEGBOX_LEFT BUTTON_LEFT
524 #define SAVE_TEXT "PLAYPAUSE"
525 #define QUIT_TEXT "POWER"
526 #define RESTART_TEXT "BACK"
527 #define LVL_UP_TEXT "Vol+"
528 #define LVL_DOWN_TEXT "Vol-"
529 #define SELECT_TEXT "SELECT"
531 #else
532 #error Unsupported keymap!
533 #endif
535 #ifdef HAVE_TOUCHSCREEN
536 #ifndef PEGBOX_QUIT
537 #define PEGBOX_QUIT BUTTON_TOPLEFT
538 #endif
539 #ifndef PEGBOX_SELECT
540 #define PEGBOX_SELECT BUTTON_CENTER
541 #endif
542 #ifndef PEGBOX_RESTART
543 #define PEGBOX_RESTART BUTTON_TOPRIGHT
544 #endif
545 #ifndef PEGBOX_LVL_UP
546 #define PEGBOX_LVL_UP BUTTON_BOTTOMLEFT
547 #endif
548 #ifndef PEGBOX_LVL_DOWN
549 #define PEGBOX_LVL_DOWN BUTTON_BOTTOMRIGHT
550 #endif
551 #ifndef PEGBOX_UP
552 #define PEGBOX_UP BUTTON_TOPMIDDLE
553 #endif
554 #ifndef PEGBOX_DOWN
555 #define PEGBOX_DOWN BUTTON_BOTTOMMIDDLE
556 #endif
557 #ifndef PEGBOX_RIGHT
558 #define PEGBOX_RIGHT BUTTON_MIDRIGHT
559 #endif
560 #ifndef PEGBOX_LEFT
561 #define PEGBOX_LEFT BUTTON_MIDLEFT
562 #endif
563 #ifndef SELECT_TEXT
564 #define SELECT_TEXT "CENTER"
565 #endif
566 #ifndef QUIT_TEXT
567 #define QUIT_TEXT "TOPLEFT"
568 #endif
569 #ifndef RESTART_TEXT
570 #define RESTART_TEXT "TOPRIGHT"
571 #endif
572 #ifndef LVL_UP_TEXT
573 #define LVL_UP_TEXT "BOTTOMLEFT"
574 #endif
575 #ifndef LVL_DOWN_TEXT
576 #define LVL_DOWN_TEXT "BOTTOMRIGHT"
577 #endif
578 #endif
581 /* get several sizes from the bitmaps */
582 #ifdef BMPWIDTH_pegbox_pieces
583 #define PIECE_WIDTH BMPWIDTH_pegbox_pieces
584 #define PIECE_HEIGHT (BMPHEIGHT_pegbox_pieces/7)
585 #else
586 /* dummy numbers to avoid #error in dependency generation */
587 #define PIECE_WIDTH 50
588 #define PIECE_HEIGHT 10
589 #endif
591 #define BOARD_WIDTH (12*PIECE_WIDTH)
592 #define BOARD_HEIGHT (8*PIECE_HEIGHT)
595 /* define a wide layout where the statistics are alongside the board, not above
596 * base calculation on the piece bitmaps for the 8x12 board */
597 #if (LCD_WIDTH - BOARD_WIDTH) > (LCD_HEIGHT - BOARD_HEIGHT)
598 #define WIDE_LAYOUT
599 #endif
602 #define HEADER_WIDTH BMPWIDTH_pegbox_header
603 #define HEADER_HEIGHT BMPHEIGHT_pegbox_header
606 #if defined WIDE_LAYOUT
608 #if ((BOARD_WIDTH + HEADER_WIDTH + 4) <= LCD_WIDTH)
609 #define BOARD_X 2
610 #else
611 #define BOARD_X 1
612 #endif
613 #define BOARD_Y (LCD_HEIGHT-BOARD_HEIGHT)/2
615 #if (LCD_WIDTH >= 132) && (LCD_HEIGHT >= 80)
616 #define TEXT_X 116
617 #define LEVEL_TEXT_Y 14
618 #define PEGS_TEXT_Y 58
619 #elif (LCD_WIDTH >= 128) && (LCD_HEIGHT >= 64)
620 #define TEXT_X 112
621 #define LEVEL_TEXT_Y 27
622 #define PEGS_TEXT_Y 50
623 #else
624 #error "Unsupported screen size"
625 #endif
627 #else /* "normal" layout */
629 #define BOARD_X (LCD_WIDTH-BOARD_WIDTH)/2
630 #if ((BOARD_HEIGHT + HEADER_HEIGHT + 4) <= LCD_HEIGHT)
631 #define BOARD_Y HEADER_HEIGHT+2
632 #else
633 #define BOARD_Y HEADER_HEIGHT
634 #endif
636 #if LCD_WIDTH >= 640
637 #define LEVEL_TEXT_X 118
638 #define PEGS_TEXT_X 552
639 #define TEXT_Y 56
640 #elif LCD_WIDTH >= 320
641 #define LEVEL_TEXT_X 59
642 #define PEGS_TEXT_X 276
643 #define TEXT_Y 28
644 #elif LCD_WIDTH >= 240
645 #define LEVEL_TEXT_X 59
646 #define PEGS_TEXT_X 196
647 #define TEXT_Y 28
648 #elif LCD_WIDTH >= 220
649 #define LEVEL_TEXT_X 49
650 #define PEGS_TEXT_X 186
651 #define TEXT_Y 28
652 #elif LCD_WIDTH >= 176
653 #define LEVEL_TEXT_X 38
654 #define PEGS_TEXT_X 155
655 #define TEXT_Y 17
656 #elif LCD_WIDTH >= 160
657 #define LEVEL_TEXT_X 37
658 #define PEGS_TEXT_X 140
659 #define TEXT_Y 13
660 #elif LCD_WIDTH >= 138
661 #define LEVEL_TEXT_X 28
662 #define PEGS_TEXT_X 119
663 #define TEXT_Y 15
664 #elif LCD_WIDTH >= 128
665 #if HEADER_HEIGHT > 16
666 #define LEVEL_TEXT_X 26
667 #define PEGS_TEXT_X 107
668 #define TEXT_Y 31
669 #else
670 #define LEVEL_TEXT_X 15
671 #define PEGS_TEXT_X 100
672 #define TEXT_Y 5
673 #endif /* HEADER_HEIGHT */
674 #elif LCD_WIDTH >= 112
675 #define LEVEL_TEXT_X 25
676 #define PEGS_TEXT_X 90
677 #define TEXT_Y 0
678 #elif LCD_WIDTH >= 96
679 #define LEVEL_TEXT_X 25
680 #define PEGS_TEXT_X 86
681 #define TEXT_Y 22
682 #endif /* LCD_WIDTH */
684 #endif /* WIDE_LAYOUT */
687 #ifdef HAVE_LCD_COLOR
688 #define BG_COLOR LCD_BLACK
689 #define TEXT_BG LCD_RGBPACK(189,189,189)
690 #endif
693 #ifdef HAVE_TOUCHSCREEN
694 #include "lib/pluginlib_touchscreen.h"
695 static struct ts_raster pegbox_raster =
696 { BOARD_X, BOARD_Y, COLS*PIECE_WIDTH, ROWS*PIECE_HEIGHT,
697 PIECE_WIDTH, PIECE_HEIGHT };
698 static struct ts_raster_button_mapping pegbox_raster_btn =
699 { &pegbox_raster, false, false, true, false, true, {0, 0}, 0, 0, 0 };
700 #endif
703 struct game_context {
704 unsigned int level;
705 unsigned int highlevel;
706 signed int player_row;
707 signed int player_col;
708 unsigned int num_left;
709 unsigned int playboard[ROWS][COLS];
712 char levels[NUM_LEVELS][ROWS][COLS] = {
713 /* Level 1 */
714 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
715 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
716 {1, 0, 0, 0, 7, 0, 0, 5, 0, 0, 0, 1,},
717 {1, 0, 0, 0, 0, 3, 3, 2, 0, 0, 0, 1,},
718 {1, 0, 0, 0, 4, 6, 0, 5, 0, 0, 0, 1,},
719 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
720 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
721 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
723 /* Level 2 */
724 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
725 {1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 1,},
726 {1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1,},
727 {1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1,},
728 {7, 0, 0, 0, 2, 2, 5, 5, 0, 0, 0, 1,},
729 {1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1,},
730 {1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1,},
731 {1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 1,}},
733 /* Level 3 */
734 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
735 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
736 {1, 0, 0, 0, 0, 0, 2, 0, 7, 0, 0, 0,},
737 {1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 2, 1,},
738 {1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1,},
739 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1,},
740 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
741 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
743 /* Level 4 */
744 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
745 {6, 0, 4, 0, 2, 0, 2, 0, 0, 0, 0, 1,},
746 {6, 0, 3, 0, 5, 0, 2, 0, 0, 0, 0, 1,},
747 {6, 0, 5, 0, 4, 7, 2, 0, 0, 0, 0, 1,},
748 {6, 0, 2, 0, 4, 0, 2, 0, 3, 0, 0, 1,},
749 {6, 0, 4, 0, 5, 0, 2, 0, 0, 0, 0, 1,},
750 {6, 0, 5, 0, 4, 0, 2, 0, 0, 0, 0, 1,},
751 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
753 /* Level 5 */
754 {{0, 6, 6, 0, 4, 6, 0, 0, 6, 0, 0, 0,},
755 {0, 6, 6, 0, 4, 4, 0, 0, 6, 0, 0, 2,},
756 {2, 6, 6, 0, 6, 6, 6, 0, 1, 2, 2, 2,},
757 {0, 6, 6, 0, 6, 4, 6, 0, 1, 2, 0, 2,},
758 {0, 6, 6, 0, 6, 7, 6, 5, 6, 0, 0, 0,},
759 {2, 6, 6, 0, 6, 6, 6, 0, 6, 0, 0, 0,},
760 {0, 6, 6, 0, 4, 0, 0, 0, 6, 0, 0, 0,},
761 {0, 6, 6, 0, 0, 5, 0, 0, 6, 5, 5, 0,}},
763 /* Level 6 */
764 {{7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
765 {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,},
766 {2, 0, 0, 2, 0, 0, 0, 2, 2, 0, 0, 0,},
767 {0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 0,},
768 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
769 {0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1,},
770 {0, 3, 0, 0, 0, 0, 0, 0, 5, 4, 6, 0,},
771 {0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1,}},
773 /* Level 7 */
774 {{1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1,},
775 {1, 1, 1, 6, 0, 0, 4, 6, 0, 1, 1, 1,},
776 {1, 1, 1, 1, 0, 1, 5, 1, 0, 1, 1, 1,},
777 {1, 1, 1, 2, 3, 3, 7, 4, 2, 6, 1, 1,},
778 {1, 1, 1, 1, 0, 1, 2, 1, 0, 0, 0, 1,},
779 {1, 1, 1, 1, 0, 0, 5, 0, 0, 1, 0, 1,},
780 {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1,},
781 {1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,}},
783 /* Level 8 */
784 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
785 {0, 0, 3, 3, 3, 3, 3, 4, 3, 3, 0, 0,},
786 {0, 0, 3, 3, 3, 2, 3, 3, 5, 3, 0, 0,},
787 {7, 0, 3, 3, 3, 2, 3, 3, 4, 3, 0, 0,},
788 {0, 0, 3, 3, 4, 5, 3, 3, 3, 3, 0, 0,},
789 {0, 0, 3, 3, 5, 2, 3, 3, 3, 3, 0, 0,},
790 {0, 0, 3, 3, 2, 4, 3, 3, 3, 3, 0, 0,},
791 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
793 /* Level 9 */
794 {{0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,},
795 {0, 3, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,},
796 {0, 0, 0, 0, 2, 4, 4, 3, 0, 1, 1, 0,},
797 {0, 1, 0, 0, 2, 1, 0, 0, 0, 1, 1, 1,},
798 {0, 0, 0, 2, 2, 7, 1, 0, 0, 0, 0, 2,},
799 {0, 0, 0, 0, 2, 1, 0, 0, 1, 1, 1, 1,},
800 {0, 3, 1, 0, 2, 5, 5, 0, 0, 0, 3, 0,},
801 {0, 0, 0, 0, 4, 1, 0, 0, 0, 0, 0, 0,}},
803 /* Level 10 */
804 {{1, 1, 1, 1, 2, 1, 1, 1, 0, 0, 0, 0,},
805 {1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 7,},
806 {0, 0, 4, 0, 6, 6, 6, 0, 0, 0, 3, 0,},
807 {0, 3, 3, 0, 6, 6, 6, 0, 4, 3, 4, 0,},
808 {0, 3, 3, 0, 6, 6, 6, 0, 4, 3, 4, 0,},
809 {0, 0, 0, 0, 6, 6, 6, 0, 3, 0, 0, 0,},
810 {1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0,},
811 {1, 1, 1, 1, 1, 2, 1, 1, 0, 0, 0, 0,}},
813 /* Level 11 */
814 {{1, 7, 1, 0, 1, 1, 6, 0, 0, 1, 1, 0,},
815 {1, 0, 0, 0, 5, 4, 6, 6, 0, 2, 2, 0,},
816 {1, 2, 1, 2, 0, 1, 6, 0, 0, 2, 2, 0,},
817 {1, 0, 0, 2, 0, 1, 0, 0, 0, 3, 3, 0,},
818 {1, 2, 1, 0, 0, 1, 0, 1, 0, 3, 3, 0,},
819 {0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0,},
820 {0, 3, 4, 3, 0, 1, 0, 1, 0, 0, 0, 0,},
821 {0, 0, 0, 0, 2, 2, 2, 1, 1, 1, 1, 1,}},
823 /* Level 12 */
824 {{7, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,},
825 {1, 2, 1, 2, 1, 2, 1, 1, 0, 0, 0, 1,},
826 {0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1,},
827 {1, 2, 1, 2, 1, 2, 1, 0, 0, 0, 0, 1,},
828 {0, 0, 0, 0, 0, 0, 1, 1, 5, 5, 6, 1,},
829 {1, 2, 1, 2, 1, 2, 1, 1, 0, 2, 2, 1,},
830 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1,},
831 {1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1,}},
833 /* Level 13 */
834 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
835 {0, 0, 4, 0, 2, 0, 5, 0, 4, 0, 0, 6,},
836 {0, 0, 2, 0, 5, 0, 2, 0, 4, 0, 0, 6,},
837 {7, 0, 3, 0, 4, 0, 5, 0, 4, 0, 0, 6,},
838 {0, 0, 5, 0, 4, 0, 2, 0, 4, 0, 0, 6,},
839 {0, 0, 4, 0, 2, 0, 5, 0, 4, 0, 0, 6,},
840 {0, 0, 3, 0, 3, 0, 2, 0, 4, 0, 0, 6,},
841 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
843 /* Level 14 */
844 {{1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1,},
845 {1, 1, 0, 2, 0, 0, 4, 0, 0, 2, 0, 1,},
846 {1, 6, 0, 0, 5, 1, 0, 1, 1, 0, 0, 1,},
847 {1, 1, 1, 0, 0, 3, 5, 3, 0, 0, 1, 1,},
848 {1, 1, 0, 0, 1, 1, 0, 1, 5, 0, 0, 6,},
849 {1, 1, 0, 2, 0, 0, 4, 0, 0, 0, 7, 1,},
850 {1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1,},
851 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
853 /* Level 15 */
854 {{0, 0, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
855 {0, 0, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
856 {0, 3, 4, 6, 0, 6, 0, 6, 0, 6, 0, 2,},
857 {0, 4, 0, 6, 0, 6, 4, 6, 0, 6, 0, 1,},
858 {0, 3, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
859 {7, 0, 0, 6, 4, 6, 0, 6, 0, 6, 0, 1,},
860 {0, 0, 4, 6, 0, 6, 0, 6, 4, 6, 0, 1,},
861 {0, 0, 4, 6, 0, 6, 0, 6, 0, 6, 0, 1,}}
864 /***********************************************************************
865 * pegbox_draw_board() draws the game's current level.
866 ************************************************************************/
867 static void pegbox_draw_board(struct game_context* pb)
869 unsigned int r, c, type;
870 pb->num_left = 0;
872 rb->lcd_clear_display();
873 #ifdef WIDE_LAYOUT
874 rb->lcd_bitmap(pegbox_header,LCD_WIDTH-HEADER_WIDTH,0,
875 HEADER_WIDTH,LCD_HEIGHT);
876 #else
877 rb->lcd_bitmap(pegbox_header,(LCD_WIDTH-HEADER_WIDTH)/2,0,
878 HEADER_WIDTH, HEADER_HEIGHT);
879 #endif /* WIDE_LAYOUT */
881 #if ((BOARD_HEIGHT + HEADER_HEIGHT + 4) <= LCD_HEIGHT)
882 rb->lcd_drawrect(BOARD_X-2,BOARD_Y-2,BOARD_WIDTH+4,BOARD_HEIGHT+4);
883 #endif /* enough space for a frame? */
885 #ifdef HAVE_LCD_COLOR
886 rb->lcd_set_foreground(LCD_WHITE);
887 #if ((BOARD_HEIGHT + HEADER_HEIGHT + 2) <= LCD_HEIGHT)
888 rb->lcd_fillrect(BOARD_X-1,BOARD_Y-1,BOARD_WIDTH+2,BOARD_HEIGHT+2);
889 #else
890 rb->lcd_fillrect(BOARD_X,BOARD_Y,BOARD_WIDTH,BOARD_HEIGHT);
891 #endif
892 rb->lcd_set_foreground(LCD_BLACK);
893 rb->lcd_set_background(TEXT_BG);
894 #endif
896 for (r=0 ; r < ROWS ; r++) {
897 for (c = 0 ; c < COLS ; c++) {
899 type = pb->playboard[r][c];
901 if(type != SPACE) {
902 rb->lcd_bitmap_part(pegbox_pieces, 0, (type-1)*PIECE_HEIGHT,
903 STRIDE( SCREEN_MAIN,
904 BMPWIDTH_pegbox_pieces,BMPHEIGHT_pegbox_pieces),
905 c * PIECE_WIDTH + BOARD_X,
906 r * PIECE_HEIGHT + BOARD_Y, PIECE_WIDTH,
907 PIECE_HEIGHT);
910 if(pb->playboard[r][c] == PLAYER) {
911 pb->player_row=r;
912 pb->player_col=c;
914 else if (type != WALL && type != SPACE && type != HOLE)
915 pb->num_left++;
919 #ifdef WIDE_LAYOUT
920 rb->lcd_putsxyf(TEXT_X, LEVEL_TEXT_Y, "%d", pb->level);
921 rb->lcd_putsxyf(TEXT_X, PEGS_TEXT_Y, "%d", pb->num_left);
922 #else
923 rb->lcd_putsxyf(LEVEL_TEXT_X, TEXT_Y, "%d", pb->level);
924 rb->lcd_putsxyf(PEGS_TEXT_X, TEXT_Y, "%d", pb->num_left);
925 #endif /*WIDE_LAYOUT*/
927 #ifdef HAVE_LCD_COLOR
928 rb->lcd_set_background(BG_COLOR);
929 rb->lcd_set_foreground(LCD_WHITE);
930 #endif
931 /* print out the screen */
932 rb->lcd_update();
935 /*****************************************************************************
936 * pegbox_load_level() loads the player's current level from the array and sets the
937 * player's position.
938 ******************************************************************************/
939 static void pegbox_load_level(struct game_context* pb)
941 int r, c;
943 for(r = 0; r < ROWS; r++)
944 for(c = 0; c < COLS; c++)
945 pb->playboard[r][c] = levels[pb->level-1][r][c];
948 /*****************************************************************************
949 * pegbox_new_piece() creates a new piece at a specified location. The player
950 * navigates through the pieces and selects one.
951 ******************************************************************************/
952 static void pegbox_new_piece(struct game_context* pb, unsigned int x_loc,
953 unsigned int y_loc)
955 int button;
956 bool exit = false;
958 pb->playboard[x_loc][y_loc] = TRIANGLE;
960 while (!exit) {
961 pegbox_draw_board(pb);
962 button = rb->button_get(true);
963 #ifdef HAVE_TOUCHSCREEN
964 if(button & BUTTON_TOUCHSCREEN)
966 pegbox_raster_btn.two_d_from.y = x_loc;
967 pegbox_raster_btn.two_d_from.x = y_loc;
969 struct ts_raster_button_result ret =
970 touchscreen_raster_map_button(&pegbox_raster_btn,
971 rb->button_get_data() >> 16,
972 rb->button_get_data() & 0xffff,
973 button);
974 if(ret.action == TS_ACTION_TWO_D_MOVEMENT)
976 if(ret.to.x > ret.from.x)
977 button = PEGBOX_UP;
978 else if(ret.to.x < ret.from.x)
979 button = PEGBOX_DOWN;
980 else if(ret.to.y > ret.from.y)
981 button = PEGBOX_LEFT;
982 else if(ret.to.y < ret.from.y)
983 button = PEGBOX_RIGHT;
985 else if(ret.action == TS_ACTION_CLICK
986 && (unsigned)ret.to.x == y_loc
987 && (unsigned)ret.to.y == x_loc)
988 button = PEGBOX_SELECT;
990 #endif
991 switch(button){
992 case PEGBOX_LEFT:
993 case (PEGBOX_LEFT|BUTTON_REPEAT):
994 case PEGBOX_DOWN:
995 case (PEGBOX_DOWN|BUTTON_REPEAT):
996 if (pb->playboard[x_loc][y_loc] < 5)
997 pb->playboard[x_loc][y_loc]++;
998 else
999 pb->playboard[x_loc][y_loc] = TRIANGLE;
1000 break;
1001 case PEGBOX_RIGHT:
1002 case (PEGBOX_RIGHT|BUTTON_REPEAT):
1003 case PEGBOX_UP:
1004 case (PEGBOX_UP|BUTTON_REPEAT):
1005 if (pb->playboard[x_loc][y_loc] > 2)
1006 pb->playboard[x_loc][y_loc]--;
1007 else
1008 pb->playboard[x_loc][y_loc] = CIRCLE;
1009 break;
1010 case PEGBOX_SELECT:
1011 exit=true;
1012 break;
1017 /*****************************************************************************
1018 * pegbox_move_player() moves the player and pieces and updates the board accordingly.
1019 ******************************************************************************/
1020 static void pegbox_move_player(struct game_context* pb, signed int x_dir,
1021 signed int y_dir)
1023 unsigned int type1, type2;
1024 signed int r1,c1,r2,c2;
1026 r1 = pb->player_row+y_dir;
1027 c1 = pb->player_col+x_dir;
1028 r2 = pb->player_row+y_dir*2;
1029 c2 = pb->player_col+x_dir*2;
1031 type1 = pb->playboard[r1][c1];
1032 type2 = pb->playboard[r2][c2];
1034 if (r1 == ROWS || c1 == COLS || r1 < 0 || c1 < 0 || type1 == WALL)
1035 return;
1036 else if(type1 != SPACE) {
1037 if (r2 == ROWS || c2 == COLS || r2 < 0 || c2 < 0 || type2 == WALL)
1038 return;
1042 pb->playboard[pb->player_row][pb->player_col] = SPACE;
1043 pb->player_row += y_dir;
1044 pb->player_col += x_dir;
1046 if (type1 == HOLE) {
1047 pegbox_draw_board(pb);
1048 rb->splash(HZ*2, "You fell down a hole!");
1049 pegbox_load_level(pb);
1051 else if (type1 == SPACE)
1052 pb->playboard[r1][c1] = PLAYER;
1053 else {
1054 pb->playboard[r1][c1] = PLAYER;
1055 if(type1 == type2) {
1056 if (type1 == TRIANGLE)
1057 pb->playboard[r2][c2] = WALL;
1058 else if (type1 == CROSS) {
1059 pb->playboard[r1][c1] = SPACE;
1060 pegbox_new_piece(pb, r2, c2);
1061 pb->playboard[r1][c1] = PLAYER;
1063 else
1064 pb->playboard[r2][c2] = SPACE;
1066 else if (type2 == SPACE)
1067 pb->playboard[r2][c2] = type1;
1068 else if (type2 == HOLE) {
1069 if (type1 == SQUARE)
1070 pb->playboard[r2][c2] = SPACE;
1072 else {
1073 rb->splash(HZ*2, "Illegal Move!");
1074 pegbox_load_level(pb);
1078 pegbox_draw_board(pb);
1081 /***********************************************************************
1082 * pegbox_help() display help text
1083 ************************************************************************/
1084 static bool pegbox_help(void)
1086 static char* help_text[] = {
1087 "Pegbox", "", "Aim", "",
1088 "To", "beat", "each", "level,", "you", "must", "destroy", "all", "of",
1089 "the", "pegs.", "If", "two", "like", "pegs", "are", "pushed", "into",
1090 "each", "other,", "they", "disappear", "except", "for", "triangles",
1091 "which", "form", "a", "solid", "block", "and", "crosses", "which",
1092 "allow", "you", "to", "choose", "a", "replacement", "block.", "", "",
1093 "Controls", "",
1094 RESTART_TEXT, "to", "restart", "level", "",
1095 LVL_UP_TEXT, "to", "go", "up", "a", "level", "",
1096 LVL_DOWN_TEXT, "to", "go", "down", "a", "level", "",
1097 SELECT_TEXT, "to", "choose", "peg", "",
1098 QUIT_TEXT, "to", "quit"
1100 static struct style_text formation[]={
1101 { 0, TEXT_CENTER|TEXT_UNDERLINE },
1102 { 2, C_RED },
1103 { 46, C_RED },
1104 LAST_STYLE_ITEM
1107 rb->lcd_setfont(FONT_UI);
1108 if (display_text(ARRAYLEN(help_text), help_text, formation, NULL, true))
1109 return true;
1110 rb->lcd_setfont(FONT_SYSFIXED);
1112 return false;
1115 /***********************************************************************
1116 * pegbox_menu() is the game menu
1117 ************************************************************************/
1118 static bool _ingame;
1119 static int pegbox_menu_cb(int action, const struct menu_item_ex *this_item)
1121 int i = (intptr_t)this_item;
1122 if( action == ACTION_REQUEST_MENUITEM )
1124 if((!_ingame && (i==0 || i==1)) || ( _ingame && i==2 ))
1125 return ACTION_EXIT_MENUITEM;
1127 return action;
1130 static unsigned int pegbox_menu(struct game_context* pb, bool ingame)
1132 int selected = 0;
1133 int last_level = pb->level;
1135 MENUITEM_STRINGLIST (main_menu, "Pegbox Menu", pegbox_menu_cb,
1136 "Resume Game", "Restart Level", "Start Game",
1137 "Select Level", "Help",
1138 "Playback Control", "Quit");
1139 _ingame = ingame;
1140 rb->button_clear_queue();
1142 while (true) {
1143 switch (rb->do_menu(&main_menu, &selected, NULL, false)) {
1144 case 0:
1145 pb->level = last_level;
1146 pegbox_draw_board(pb);
1147 return 0;
1148 case 1:
1149 case 2:
1150 pegbox_load_level(pb);
1151 pegbox_draw_board(pb);
1152 return 0;
1153 case 3:
1154 if(rb->set_int("Select Level", "", UNIT_INT, &pb->level,
1155 NULL, 1, 1, pb->highlevel, NULL))
1156 return 1;
1157 break;
1158 case 4:
1159 if (pegbox_help())
1160 return 1;
1161 break;
1162 case 5:
1163 if (playback_control(NULL))
1164 return 1;
1165 break;
1166 case 6:
1167 return 1;
1168 case MENU_ATTACHED_USB:
1169 return 1;
1170 default:
1171 break;
1176 /***********************************************************************
1177 * pegbox_main() is the main game subroutine
1178 ************************************************************************/
1179 static int pegbox_main(struct game_context* pb)
1181 int button;
1183 if (pegbox_menu(pb, false)==1) {
1184 return 1;
1187 while (true) {
1188 button = rb->button_get(true);
1189 #ifdef HAVE_TOUCHSCREEN
1190 if(button & BUTTON_TOUCHSCREEN)
1192 pegbox_raster_btn.two_d_from.y = pb->player_row;
1193 pegbox_raster_btn.two_d_from.x = pb->player_col;
1195 struct ts_raster_button_result ret =
1196 touchscreen_raster_map_button(&pegbox_raster_btn,
1197 rb->button_get_data() >> 16,
1198 rb->button_get_data() & 0xffff,
1199 button);
1200 if(ret.action == TS_ACTION_TWO_D_MOVEMENT)
1201 pegbox_move_player(pb, ret.to.x - ret.from.x, ret.to.y - ret.from.y);
1203 #endif
1204 switch(button){
1205 case PEGBOX_LEFT: /* move cursor left */
1206 case (PEGBOX_LEFT|BUTTON_REPEAT):
1207 pegbox_move_player(pb, -1, 0);
1208 break;
1210 case PEGBOX_RIGHT: /* move cursor right */
1211 case (PEGBOX_RIGHT|BUTTON_REPEAT):
1212 pegbox_move_player(pb, 1, 0);
1213 break;
1215 case PEGBOX_DOWN: /* move cursor down */
1216 case (PEGBOX_DOWN|BUTTON_REPEAT):
1217 pegbox_move_player(pb, 0, 1);
1218 break;
1220 case PEGBOX_UP: /* move cursor up */
1221 case (PEGBOX_UP|BUTTON_REPEAT):
1222 pegbox_move_player(pb, 0, -1);
1223 break;
1225 case PEGBOX_QUIT:
1226 if (pegbox_menu(pb, true)==1) {
1227 return 1;
1229 break;
1231 #ifdef PEGBOX_RESTART
1232 case PEGBOX_RESTART:
1233 pegbox_load_level(pb);
1234 pegbox_draw_board(pb);
1235 break;
1236 #endif
1238 #ifdef PEGBOX_LVL_UP
1239 case (PEGBOX_LVL_UP|BUTTON_REPEAT):
1240 case PEGBOX_LVL_UP:
1241 if (pb->level >= pb->highlevel) {
1242 pb->level = 1;
1243 } else {
1244 pb->level++;
1246 pegbox_load_level(pb);
1247 pegbox_draw_board(pb);
1248 break;
1249 #endif
1251 #ifdef PEGBOX_LVL_DOWN
1252 case (PEGBOX_LVL_DOWN|BUTTON_REPEAT):
1253 case PEGBOX_LVL_DOWN:
1254 if(pb->level <= 1) {
1255 pb->level = pb->highlevel;
1256 } else {
1257 pb->level--;
1259 pegbox_load_level(pb);
1260 pegbox_draw_board(pb);
1261 break;
1262 #endif
1265 if (pb->num_left == 0) {
1266 rb->splash(HZ*2, "Nice Pegging!");
1267 if (pb->level == NUM_LEVELS) {
1268 pegbox_draw_board(pb);
1269 rb->splash(HZ*2, "Congratulations!");
1270 rb->splash(HZ*2, "You have finished the game!");
1271 if (pegbox_menu(pb,false)==1) {
1272 return 1;
1275 else {
1276 pb->level++;
1277 pegbox_load_level(pb);
1278 pegbox_draw_board(pb);
1281 if(pb->level > pb->highlevel)
1282 pb->highlevel = pb->level;
1286 return PLUGIN_OK;
1289 /*****************************************************************************
1290 * plugin entry point.
1291 ******************************************************************************/
1292 enum plugin_status plugin_start(const void* parameter)
1294 (void)parameter;
1295 #ifdef HAVE_LCD_BITMAP
1296 rb->lcd_setfont(FONT_SYSFIXED);
1297 #if LCD_DEPTH > 1
1298 rb->lcd_set_backdrop(NULL);
1299 #endif
1300 #ifdef HAVE_LCD_COLOR
1301 rb->lcd_set_foreground(LCD_WHITE);
1302 rb->lcd_set_background(BG_COLOR);
1303 #endif
1304 rb->lcd_clear_display();
1306 struct game_context pb;
1307 pb.level=1;
1308 pb.highlevel=1;
1309 struct configdata config[] = {
1310 {TYPE_INT, 1, NUM_LEVELS, { .int_p = &(pb.level) }, "level", NULL},
1311 {TYPE_INT, 1, NUM_LEVELS, { .int_p = &(pb.highlevel) }, "highlevel", NULL},
1313 configfile_load(CONFIG_FILE_NAME,config,2,0);
1314 pegbox_main(&pb);
1315 configfile_save(CONFIG_FILE_NAME,config,2,0);
1316 rb->lcd_setfont(FONT_UI);
1317 #endif /* HAVE_LCD_BITMAP */
1319 return PLUGIN_OK;