Add another delay in the AMSv2 sd controller driver as a work-around for SD initialis...
[maemo-rb.git] / apps / plugins / pegbox.c
blobe3d096e507022d5143d7a843f878e6b73fdf34bc
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 #else
476 #error Unsupported keymap!
477 #endif
479 #ifdef HAVE_TOUCHSCREEN
480 #ifndef PEGBOX_QUIT
481 #define PEGBOX_QUIT BUTTON_TOPLEFT
482 #endif
483 #ifndef PEGBOX_SELECT
484 #define PEGBOX_SELECT BUTTON_CENTER
485 #endif
486 #ifndef PEGBOX_RESTART
487 #define PEGBOX_RESTART BUTTON_TOPRIGHT
488 #endif
489 #ifndef PEGBOX_LVL_UP
490 #define PEGBOX_LVL_UP BUTTON_BOTTOMLEFT
491 #endif
492 #ifndef PEGBOX_LVL_DOWN
493 #define PEGBOX_LVL_DOWN BUTTON_BOTTOMRIGHT
494 #endif
495 #ifndef PEGBOX_UP
496 #define PEGBOX_UP BUTTON_TOPMIDDLE
497 #endif
498 #ifndef PEGBOX_DOWN
499 #define PEGBOX_DOWN BUTTON_BOTTOMMIDDLE
500 #endif
501 #ifndef PEGBOX_RIGHT
502 #define PEGBOX_RIGHT BUTTON_MIDRIGHT
503 #endif
504 #ifndef PEGBOX_LEFT
505 #define PEGBOX_LEFT BUTTON_MIDLEFT
506 #endif
507 #ifndef SELECT_TEXT
508 #define SELECT_TEXT "CENTER"
509 #endif
510 #ifndef QUIT_TEXT
511 #define QUIT_TEXT "TOPLEFT"
512 #endif
513 #ifndef RESTART_TEXT
514 #define RESTART_TEXT "TOPRIGHT"
515 #endif
516 #ifndef LVL_UP_TEXT
517 #define LVL_UP_TEXT "BOTTOMLEFT"
518 #endif
519 #ifndef LVL_DOWN_TEXT
520 #define LVL_DOWN_TEXT "BOTTOMRIGHT"
521 #endif
522 #endif
525 /* get several sizes from the bitmaps */
526 #ifdef BMPWIDTH_pegbox_pieces
527 #define PIECE_WIDTH BMPWIDTH_pegbox_pieces
528 #define PIECE_HEIGHT (BMPHEIGHT_pegbox_pieces/7)
529 #else
530 /* dummy numbers to avoid #error in dependency generation */
531 #define PIECE_WIDTH 50
532 #define PIECE_HEIGHT 10
533 #endif
535 #define BOARD_WIDTH (12*PIECE_WIDTH)
536 #define BOARD_HEIGHT (8*PIECE_HEIGHT)
539 /* define a wide layout where the statistics are alongside the board, not above
540 * base calculation on the piece bitmaps for the 8x12 board */
541 #if (LCD_WIDTH - BOARD_WIDTH) > (LCD_HEIGHT - BOARD_HEIGHT)
542 #define WIDE_LAYOUT
543 #endif
546 #define HEADER_WIDTH BMPWIDTH_pegbox_header
547 #define HEADER_HEIGHT BMPHEIGHT_pegbox_header
550 #if defined WIDE_LAYOUT
552 #if ((BOARD_WIDTH + HEADER_WIDTH + 4) <= LCD_WIDTH)
553 #define BOARD_X 2
554 #else
555 #define BOARD_X 1
556 #endif
557 #define BOARD_Y (LCD_HEIGHT-BOARD_HEIGHT)/2
559 #if (LCD_WIDTH >= 132) && (LCD_HEIGHT >= 80)
560 #define TEXT_X 116
561 #define LEVEL_TEXT_Y 14
562 #define PEGS_TEXT_Y 58
563 #elif (LCD_WIDTH >= 128) && (LCD_HEIGHT >= 64)
564 #define TEXT_X 112
565 #define LEVEL_TEXT_Y 27
566 #define PEGS_TEXT_Y 50
567 #else
568 #error "Unsupported screen size"
569 #endif
571 #else /* "normal" layout */
573 #define BOARD_X (LCD_WIDTH-BOARD_WIDTH)/2
574 #if ((BOARD_HEIGHT + HEADER_HEIGHT + 4) <= LCD_HEIGHT)
575 #define BOARD_Y HEADER_HEIGHT+2
576 #else
577 #define BOARD_Y HEADER_HEIGHT
578 #endif
580 #if LCD_WIDTH >= 640
581 #define LEVEL_TEXT_X 118
582 #define PEGS_TEXT_X 552
583 #define TEXT_Y 56
584 #elif LCD_WIDTH >= 320
585 #define LEVEL_TEXT_X 59
586 #define PEGS_TEXT_X 276
587 #define TEXT_Y 28
588 #elif LCD_WIDTH >= 240
589 #define LEVEL_TEXT_X 59
590 #define PEGS_TEXT_X 196
591 #define TEXT_Y 28
592 #elif LCD_WIDTH >= 220
593 #define LEVEL_TEXT_X 49
594 #define PEGS_TEXT_X 186
595 #define TEXT_Y 28
596 #elif LCD_WIDTH >= 176
597 #define LEVEL_TEXT_X 38
598 #define PEGS_TEXT_X 155
599 #define TEXT_Y 17
600 #elif LCD_WIDTH >= 160
601 #define LEVEL_TEXT_X 37
602 #define PEGS_TEXT_X 140
603 #define TEXT_Y 13
604 #elif LCD_WIDTH >= 138
605 #define LEVEL_TEXT_X 28
606 #define PEGS_TEXT_X 119
607 #define TEXT_Y 15
608 #elif LCD_WIDTH >= 128
609 #if HEADER_HEIGHT > 16
610 #define LEVEL_TEXT_X 26
611 #define PEGS_TEXT_X 107
612 #define TEXT_Y 31
613 #else
614 #define LEVEL_TEXT_X 15
615 #define PEGS_TEXT_X 100
616 #define TEXT_Y 5
617 #endif /* HEADER_HEIGHT */
618 #elif LCD_WIDTH >= 112
619 #define LEVEL_TEXT_X 25
620 #define PEGS_TEXT_X 90
621 #define TEXT_Y 0
622 #endif /* LCD_WIDTH */
624 #endif /* WIDE_LAYOUT */
627 #ifdef HAVE_LCD_COLOR
628 #define BG_COLOR LCD_BLACK
629 #define TEXT_BG LCD_RGBPACK(189,189,189)
630 #endif
633 #ifdef HAVE_TOUCHSCREEN
634 #include "lib/pluginlib_touchscreen.h"
635 static struct ts_raster pegbox_raster =
636 { BOARD_X, BOARD_Y, COLS*PIECE_WIDTH, ROWS*PIECE_HEIGHT,
637 PIECE_WIDTH, PIECE_HEIGHT };
638 static struct ts_raster_button_mapping pegbox_raster_btn =
639 { &pegbox_raster, false, false, true, false, true, {0, 0}, 0, 0, 0 };
640 #endif
643 struct game_context {
644 unsigned int level;
645 unsigned int highlevel;
646 signed int player_row;
647 signed int player_col;
648 unsigned int num_left;
649 unsigned int playboard[ROWS][COLS];
652 char levels[NUM_LEVELS][ROWS][COLS] = {
653 /* Level 1 */
654 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
655 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
656 {1, 0, 0, 0, 7, 0, 0, 5, 0, 0, 0, 1,},
657 {1, 0, 0, 0, 0, 3, 3, 2, 0, 0, 0, 1,},
658 {1, 0, 0, 0, 4, 6, 0, 5, 0, 0, 0, 1,},
659 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
660 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
661 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
663 /* Level 2 */
664 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
665 {1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 1,},
666 {1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1,},
667 {1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1,},
668 {7, 0, 0, 0, 2, 2, 5, 5, 0, 0, 0, 1,},
669 {1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1,},
670 {1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1,},
671 {1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 1,}},
673 /* Level 3 */
674 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
675 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
676 {1, 0, 0, 0, 0, 0, 2, 0, 7, 0, 0, 0,},
677 {1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 2, 1,},
678 {1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1,},
679 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1,},
680 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
681 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
683 /* Level 4 */
684 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
685 {6, 0, 4, 0, 2, 0, 2, 0, 0, 0, 0, 1,},
686 {6, 0, 3, 0, 5, 0, 2, 0, 0, 0, 0, 1,},
687 {6, 0, 5, 0, 4, 7, 2, 0, 0, 0, 0, 1,},
688 {6, 0, 2, 0, 4, 0, 2, 0, 3, 0, 0, 1,},
689 {6, 0, 4, 0, 5, 0, 2, 0, 0, 0, 0, 1,},
690 {6, 0, 5, 0, 4, 0, 2, 0, 0, 0, 0, 1,},
691 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
693 /* Level 5 */
694 {{0, 6, 6, 0, 4, 6, 0, 0, 6, 0, 0, 0,},
695 {0, 6, 6, 0, 4, 4, 0, 0, 6, 0, 0, 2,},
696 {2, 6, 6, 0, 6, 6, 6, 0, 1, 2, 2, 2,},
697 {0, 6, 6, 0, 6, 4, 6, 0, 1, 2, 0, 2,},
698 {0, 6, 6, 0, 6, 7, 6, 5, 6, 0, 0, 0,},
699 {2, 6, 6, 0, 6, 6, 6, 0, 6, 0, 0, 0,},
700 {0, 6, 6, 0, 4, 0, 0, 0, 6, 0, 0, 0,},
701 {0, 6, 6, 0, 0, 5, 0, 0, 6, 5, 5, 0,}},
703 /* Level 6 */
704 {{7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
705 {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,},
706 {2, 0, 0, 2, 0, 0, 0, 2, 2, 0, 0, 0,},
707 {0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 0,},
708 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
709 {0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1,},
710 {0, 3, 0, 0, 0, 0, 0, 0, 5, 4, 6, 0,},
711 {0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1,}},
713 /* Level 7 */
714 {{1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1,},
715 {1, 1, 1, 6, 0, 0, 4, 6, 0, 1, 1, 1,},
716 {1, 1, 1, 1, 0, 1, 5, 1, 0, 1, 1, 1,},
717 {1, 1, 1, 2, 3, 3, 7, 4, 2, 6, 1, 1,},
718 {1, 1, 1, 1, 0, 1, 2, 1, 0, 0, 0, 1,},
719 {1, 1, 1, 1, 0, 0, 5, 0, 0, 1, 0, 1,},
720 {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1,},
721 {1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,}},
723 /* Level 8 */
724 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
725 {0, 0, 3, 3, 3, 3, 3, 4, 3, 3, 0, 0,},
726 {0, 0, 3, 3, 3, 2, 3, 3, 5, 3, 0, 0,},
727 {7, 0, 3, 3, 3, 2, 3, 3, 4, 3, 0, 0,},
728 {0, 0, 3, 3, 4, 5, 3, 3, 3, 3, 0, 0,},
729 {0, 0, 3, 3, 5, 2, 3, 3, 3, 3, 0, 0,},
730 {0, 0, 3, 3, 2, 4, 3, 3, 3, 3, 0, 0,},
731 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
733 /* Level 9 */
734 {{0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,},
735 {0, 3, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,},
736 {0, 0, 0, 0, 2, 4, 4, 3, 0, 1, 1, 0,},
737 {0, 1, 0, 0, 2, 1, 0, 0, 0, 1, 1, 1,},
738 {0, 0, 0, 2, 2, 7, 1, 0, 0, 0, 0, 2,},
739 {0, 0, 0, 0, 2, 1, 0, 0, 1, 1, 1, 1,},
740 {0, 3, 1, 0, 2, 5, 5, 0, 0, 0, 3, 0,},
741 {0, 0, 0, 0, 4, 1, 0, 0, 0, 0, 0, 0,}},
743 /* Level 10 */
744 {{1, 1, 1, 1, 2, 1, 1, 1, 0, 0, 0, 0,},
745 {1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 7,},
746 {0, 0, 4, 0, 6, 6, 6, 0, 0, 0, 3, 0,},
747 {0, 3, 3, 0, 6, 6, 6, 0, 4, 3, 4, 0,},
748 {0, 3, 3, 0, 6, 6, 6, 0, 4, 3, 4, 0,},
749 {0, 0, 0, 0, 6, 6, 6, 0, 3, 0, 0, 0,},
750 {1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0,},
751 {1, 1, 1, 1, 1, 2, 1, 1, 0, 0, 0, 0,}},
753 /* Level 11 */
754 {{1, 7, 1, 0, 1, 1, 6, 0, 0, 1, 1, 0,},
755 {1, 0, 0, 0, 5, 4, 6, 6, 0, 2, 2, 0,},
756 {1, 2, 1, 2, 0, 1, 6, 0, 0, 2, 2, 0,},
757 {1, 0, 0, 2, 0, 1, 0, 0, 0, 3, 3, 0,},
758 {1, 2, 1, 0, 0, 1, 0, 1, 0, 3, 3, 0,},
759 {0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0,},
760 {0, 3, 4, 3, 0, 1, 0, 1, 0, 0, 0, 0,},
761 {0, 0, 0, 0, 2, 2, 2, 1, 1, 1, 1, 1,}},
763 /* Level 12 */
764 {{7, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,},
765 {1, 2, 1, 2, 1, 2, 1, 1, 0, 0, 0, 1,},
766 {0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1,},
767 {1, 2, 1, 2, 1, 2, 1, 0, 0, 0, 0, 1,},
768 {0, 0, 0, 0, 0, 0, 1, 1, 5, 5, 6, 1,},
769 {1, 2, 1, 2, 1, 2, 1, 1, 0, 2, 2, 1,},
770 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1,},
771 {1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1,}},
773 /* Level 13 */
774 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
775 {0, 0, 4, 0, 2, 0, 5, 0, 4, 0, 0, 6,},
776 {0, 0, 2, 0, 5, 0, 2, 0, 4, 0, 0, 6,},
777 {7, 0, 3, 0, 4, 0, 5, 0, 4, 0, 0, 6,},
778 {0, 0, 5, 0, 4, 0, 2, 0, 4, 0, 0, 6,},
779 {0, 0, 4, 0, 2, 0, 5, 0, 4, 0, 0, 6,},
780 {0, 0, 3, 0, 3, 0, 2, 0, 4, 0, 0, 6,},
781 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
783 /* Level 14 */
784 {{1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1,},
785 {1, 1, 0, 2, 0, 0, 4, 0, 0, 2, 0, 1,},
786 {1, 6, 0, 0, 5, 1, 0, 1, 1, 0, 0, 1,},
787 {1, 1, 1, 0, 0, 3, 5, 3, 0, 0, 1, 1,},
788 {1, 1, 0, 0, 1, 1, 0, 1, 5, 0, 0, 6,},
789 {1, 1, 0, 2, 0, 0, 4, 0, 0, 0, 7, 1,},
790 {1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1,},
791 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
793 /* Level 15 */
794 {{0, 0, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
795 {0, 0, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
796 {0, 3, 4, 6, 0, 6, 0, 6, 0, 6, 0, 2,},
797 {0, 4, 0, 6, 0, 6, 4, 6, 0, 6, 0, 1,},
798 {0, 3, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
799 {7, 0, 0, 6, 4, 6, 0, 6, 0, 6, 0, 1,},
800 {0, 0, 4, 6, 0, 6, 0, 6, 4, 6, 0, 1,},
801 {0, 0, 4, 6, 0, 6, 0, 6, 0, 6, 0, 1,}}
804 /***********************************************************************
805 * pegbox_draw_board() draws the game's current level.
806 ************************************************************************/
807 static void pegbox_draw_board(struct game_context* pb)
809 unsigned int r, c, type;
810 pb->num_left = 0;
812 rb->lcd_clear_display();
813 #ifdef WIDE_LAYOUT
814 rb->lcd_bitmap(pegbox_header,LCD_WIDTH-HEADER_WIDTH,0,
815 HEADER_WIDTH,LCD_HEIGHT);
816 #else
817 rb->lcd_bitmap(pegbox_header,(LCD_WIDTH-HEADER_WIDTH)/2,0,
818 HEADER_WIDTH, HEADER_HEIGHT);
819 #endif /* WIDE_LAYOUT */
821 #if ((BOARD_HEIGHT + HEADER_HEIGHT + 4) <= LCD_HEIGHT)
822 rb->lcd_drawrect(BOARD_X-2,BOARD_Y-2,BOARD_WIDTH+4,BOARD_HEIGHT+4);
823 #endif /* enough space for a frame? */
825 #ifdef HAVE_LCD_COLOR
826 rb->lcd_set_foreground(LCD_WHITE);
827 rb->lcd_fillrect(BOARD_X-1,BOARD_Y-1,BOARD_WIDTH+2,BOARD_HEIGHT+2);
828 rb->lcd_set_foreground(LCD_BLACK);
829 rb->lcd_set_background(TEXT_BG);
830 #endif
832 for (r=0 ; r < ROWS ; r++) {
833 for (c = 0 ; c < COLS ; c++) {
835 type = pb->playboard[r][c];
837 if(type != SPACE) {
838 rb->lcd_bitmap_part(pegbox_pieces, 0, (type-1)*PIECE_HEIGHT,
839 STRIDE( SCREEN_MAIN,
840 BMPWIDTH_pegbox_pieces,BMPHEIGHT_pegbox_pieces),
841 c * PIECE_WIDTH + BOARD_X,
842 r * PIECE_HEIGHT + BOARD_Y, PIECE_WIDTH,
843 PIECE_HEIGHT);
846 if(pb->playboard[r][c] == PLAYER) {
847 pb->player_row=r;
848 pb->player_col=c;
850 else if (type != WALL && type != SPACE && type != HOLE)
851 pb->num_left++;
855 #ifdef WIDE_LAYOUT
856 rb->lcd_putsxyf(TEXT_X, LEVEL_TEXT_Y, "%d", pb->level);
857 rb->lcd_putsxyf(TEXT_X, PEGS_TEXT_Y, "%d", pb->num_left);
858 #else
859 rb->lcd_putsxyf(LEVEL_TEXT_X, TEXT_Y, "%d", pb->level);
860 rb->lcd_putsxyf(PEGS_TEXT_X, TEXT_Y, "%d", pb->num_left);
861 #endif /*WIDE_LAYOUT*/
863 #ifdef HAVE_LCD_COLOR
864 rb->lcd_set_background(BG_COLOR);
865 rb->lcd_set_foreground(LCD_WHITE);
866 #endif
867 /* print out the screen */
868 rb->lcd_update();
871 /*****************************************************************************
872 * pegbox_load_level() loads the player's current level from the array and sets the
873 * player's position.
874 ******************************************************************************/
875 static void pegbox_load_level(struct game_context* pb)
877 int r, c;
879 for(r = 0; r < ROWS; r++)
880 for(c = 0; c < COLS; c++)
881 pb->playboard[r][c] = levels[pb->level-1][r][c];
884 /*****************************************************************************
885 * pegbox_new_piece() creates a new piece at a specified location. The player
886 * navigates through the pieces and selects one.
887 ******************************************************************************/
888 static void pegbox_new_piece(struct game_context* pb, unsigned int x_loc,
889 unsigned int y_loc)
891 int button;
892 bool exit = false;
894 pb->playboard[x_loc][y_loc] = TRIANGLE;
896 while (!exit) {
897 pegbox_draw_board(pb);
898 button = rb->button_get(true);
899 #ifdef HAVE_TOUCHSCREEN
900 if(button & BUTTON_TOUCHSCREEN)
902 pegbox_raster_btn.two_d_from.y = x_loc;
903 pegbox_raster_btn.two_d_from.x = y_loc;
905 struct ts_raster_button_result ret =
906 touchscreen_raster_map_button(&pegbox_raster_btn,
907 rb->button_get_data() >> 16,
908 rb->button_get_data() & 0xffff,
909 button);
910 if(ret.action == TS_ACTION_TWO_D_MOVEMENT)
912 if(ret.to.x > ret.from.x)
913 button = PEGBOX_UP;
914 else if(ret.to.x < ret.from.x)
915 button = PEGBOX_DOWN;
916 else if(ret.to.y > ret.from.y)
917 button = PEGBOX_LEFT;
918 else if(ret.to.y < ret.from.y)
919 button = PEGBOX_RIGHT;
921 else if(ret.action == TS_ACTION_CLICK
922 && (unsigned)ret.to.x == y_loc
923 && (unsigned)ret.to.y == x_loc)
924 button = PEGBOX_SELECT;
926 #endif
927 switch(button){
928 case PEGBOX_LEFT:
929 case (PEGBOX_LEFT|BUTTON_REPEAT):
930 case PEGBOX_DOWN:
931 case (PEGBOX_DOWN|BUTTON_REPEAT):
932 if (pb->playboard[x_loc][y_loc] < 5)
933 pb->playboard[x_loc][y_loc]++;
934 else
935 pb->playboard[x_loc][y_loc] = TRIANGLE;
936 break;
937 case PEGBOX_RIGHT:
938 case (PEGBOX_RIGHT|BUTTON_REPEAT):
939 case PEGBOX_UP:
940 case (PEGBOX_UP|BUTTON_REPEAT):
941 if (pb->playboard[x_loc][y_loc] > 2)
942 pb->playboard[x_loc][y_loc]--;
943 else
944 pb->playboard[x_loc][y_loc] = CIRCLE;
945 break;
946 case PEGBOX_SELECT:
947 exit=true;
948 break;
953 /*****************************************************************************
954 * pegbox_move_player() moves the player and pieces and updates the board accordingly.
955 ******************************************************************************/
956 static void pegbox_move_player(struct game_context* pb, signed int x_dir,
957 signed int y_dir)
959 unsigned int type1, type2;
960 signed int r1,c1,r2,c2;
962 r1 = pb->player_row+y_dir;
963 c1 = pb->player_col+x_dir;
964 r2 = pb->player_row+y_dir*2;
965 c2 = pb->player_col+x_dir*2;
967 type1 = pb->playboard[r1][c1];
968 type2 = pb->playboard[r2][c2];
970 if (r1 == ROWS || c1 == COLS || r1 < 0 || c1 < 0 || type1 == WALL)
971 return;
972 else if(type1 != SPACE) {
973 if (r2 == ROWS || c2 == COLS || r2 < 0 || c2 < 0 || type2 == WALL)
974 return;
978 pb->playboard[pb->player_row][pb->player_col] = SPACE;
979 pb->player_row += y_dir;
980 pb->player_col += x_dir;
982 if (type1 == HOLE) {
983 pegbox_draw_board(pb);
984 rb->splash(HZ*2, "You fell down a hole!");
985 pegbox_load_level(pb);
987 else if (type1 == SPACE)
988 pb->playboard[r1][c1] = PLAYER;
989 else {
990 pb->playboard[r1][c1] = PLAYER;
991 if(type1 == type2) {
992 if (type1 == TRIANGLE)
993 pb->playboard[r2][c2] = WALL;
994 else if (type1 == CROSS) {
995 pb->playboard[r1][c1] = SPACE;
996 pegbox_new_piece(pb, r2, c2);
997 pb->playboard[r1][c1] = PLAYER;
999 else
1000 pb->playboard[r2][c2] = SPACE;
1002 else if (type2 == SPACE)
1003 pb->playboard[r2][c2] = type1;
1004 else if (type2 == HOLE) {
1005 if (type1 == SQUARE)
1006 pb->playboard[r2][c2] = SPACE;
1008 else {
1009 rb->splash(HZ*2, "Illegal Move!");
1010 pegbox_load_level(pb);
1014 pegbox_draw_board(pb);
1017 /***********************************************************************
1018 * pegbox_help() display help text
1019 ************************************************************************/
1020 static bool pegbox_help(void)
1022 static char* help_text[] = {
1023 "Pegbox", "", "Aim", "",
1024 "To", "beat", "each", "level,", "you", "must", "destroy", "all", "of",
1025 "the", "pegs.", "If", "two", "like", "pegs", "are", "pushed", "into",
1026 "each", "other,", "they", "disappear", "except", "for", "triangles",
1027 "which", "form", "a", "solid", "block", "and", "crosses", "which",
1028 "allow", "you", "to", "choose", "a", "replacement", "block.", "", "",
1029 "Controls", "",
1030 RESTART_TEXT, "to", "restart", "level", "",
1031 LVL_UP_TEXT, "to", "go", "up", "a", "level", "",
1032 LVL_DOWN_TEXT, "to", "go", "down", "a", "level", "",
1033 SELECT_TEXT, "to", "choose", "peg", "",
1034 QUIT_TEXT, "to", "quit"
1036 static struct style_text formation[]={
1037 { 0, TEXT_CENTER|TEXT_UNDERLINE },
1038 { 2, C_RED },
1039 { 46, C_RED },
1040 LAST_STYLE_ITEM
1043 rb->lcd_setfont(FONT_UI);
1044 if (display_text(ARRAYLEN(help_text), help_text, formation, NULL, true))
1045 return true;
1046 rb->lcd_setfont(FONT_SYSFIXED);
1048 return false;
1051 /***********************************************************************
1052 * pegbox_menu() is the game menu
1053 ************************************************************************/
1054 static bool _ingame;
1055 static int pegbox_menu_cb(int action, const struct menu_item_ex *this_item)
1057 int i = (intptr_t)this_item;
1058 if( action == ACTION_REQUEST_MENUITEM )
1060 if((!_ingame && (i==0 || i==1)) || ( _ingame && i==2 ))
1061 return ACTION_EXIT_MENUITEM;
1063 return action;
1066 static unsigned int pegbox_menu(struct game_context* pb, bool ingame)
1068 int selected = 0;
1069 int last_level = pb->level;
1071 MENUITEM_STRINGLIST (main_menu, "Pegbox Menu", pegbox_menu_cb,
1072 "Resume Game", "Restart Level", "Start Game",
1073 "Select Level", "Help",
1074 "Playback Control", "Quit");
1075 _ingame = ingame;
1076 rb->button_clear_queue();
1078 while (true) {
1079 switch (rb->do_menu(&main_menu, &selected, NULL, false)) {
1080 case 0:
1081 pb->level = last_level;
1082 pegbox_draw_board(pb);
1083 return 0;
1084 case 1:
1085 case 2:
1086 pegbox_load_level(pb);
1087 pegbox_draw_board(pb);
1088 return 0;
1089 case 3:
1090 if(rb->set_int("Select Level", "", UNIT_INT, &pb->level,
1091 NULL, 1, 1, pb->highlevel, NULL))
1092 return 1;
1093 break;
1094 case 4:
1095 if (pegbox_help())
1096 return 1;
1097 break;
1098 case 5:
1099 if (playback_control(NULL))
1100 return 1;
1101 break;
1102 case 6:
1103 return 1;
1104 case MENU_ATTACHED_USB:
1105 return 1;
1106 default:
1107 break;
1112 /***********************************************************************
1113 * pegbox_main() is the main game subroutine
1114 ************************************************************************/
1115 static int pegbox_main(struct game_context* pb)
1117 int button;
1119 if (pegbox_menu(pb, false)==1) {
1120 return 1;
1123 while (true) {
1124 button = rb->button_get(true);
1125 #ifdef HAVE_TOUCHSCREEN
1126 if(button & BUTTON_TOUCHSCREEN)
1128 pegbox_raster_btn.two_d_from.y = pb->player_row;
1129 pegbox_raster_btn.two_d_from.x = pb->player_col;
1131 struct ts_raster_button_result ret =
1132 touchscreen_raster_map_button(&pegbox_raster_btn,
1133 rb->button_get_data() >> 16,
1134 rb->button_get_data() & 0xffff,
1135 button);
1136 if(ret.action == TS_ACTION_TWO_D_MOVEMENT)
1137 pegbox_move_player(pb, ret.to.x - ret.from.x, ret.to.y - ret.from.y);
1139 #endif
1140 switch(button){
1141 case PEGBOX_LEFT: /* move cursor left */
1142 case (PEGBOX_LEFT|BUTTON_REPEAT):
1143 pegbox_move_player(pb, -1, 0);
1144 break;
1146 case PEGBOX_RIGHT: /* move cursor right */
1147 case (PEGBOX_RIGHT|BUTTON_REPEAT):
1148 pegbox_move_player(pb, 1, 0);
1149 break;
1151 case PEGBOX_DOWN: /* move cursor down */
1152 case (PEGBOX_DOWN|BUTTON_REPEAT):
1153 pegbox_move_player(pb, 0, 1);
1154 break;
1156 case PEGBOX_UP: /* move cursor up */
1157 case (PEGBOX_UP|BUTTON_REPEAT):
1158 pegbox_move_player(pb, 0, -1);
1159 break;
1161 case PEGBOX_QUIT:
1162 if (pegbox_menu(pb, true)==1) {
1163 return 1;
1165 break;
1167 #ifdef PEGBOX_RESTART
1168 case PEGBOX_RESTART:
1169 pegbox_load_level(pb);
1170 pegbox_draw_board(pb);
1171 break;
1172 #endif
1174 #ifdef PEGBOX_LVL_UP
1175 case (PEGBOX_LVL_UP|BUTTON_REPEAT):
1176 case PEGBOX_LVL_UP:
1177 if (pb->level >= pb->highlevel) {
1178 pb->level = 1;
1179 } else {
1180 pb->level++;
1182 pegbox_load_level(pb);
1183 pegbox_draw_board(pb);
1184 break;
1185 #endif
1187 #ifdef PEGBOX_LVL_DOWN
1188 case (PEGBOX_LVL_DOWN|BUTTON_REPEAT):
1189 case PEGBOX_LVL_DOWN:
1190 if(pb->level <= 1) {
1191 pb->level = pb->highlevel;
1192 } else {
1193 pb->level--;
1195 pegbox_load_level(pb);
1196 pegbox_draw_board(pb);
1197 break;
1198 #endif
1201 if (pb->num_left == 0) {
1202 rb->splash(HZ*2, "Nice Pegging!");
1203 if (pb->level == NUM_LEVELS) {
1204 pegbox_draw_board(pb);
1205 rb->splash(HZ*2, "Congratulations!");
1206 rb->splash(HZ*2, "You have finished the game!");
1207 if (pegbox_menu(pb,false)==1) {
1208 return 1;
1211 else {
1212 pb->level++;
1213 pegbox_load_level(pb);
1214 pegbox_draw_board(pb);
1217 if(pb->level > pb->highlevel)
1218 pb->highlevel = pb->level;
1222 return PLUGIN_OK;
1225 /*****************************************************************************
1226 * plugin entry point.
1227 ******************************************************************************/
1228 enum plugin_status plugin_start(const void* parameter)
1230 (void)parameter;
1231 #ifdef HAVE_LCD_BITMAP
1232 rb->lcd_setfont(FONT_SYSFIXED);
1233 #if LCD_DEPTH > 1
1234 rb->lcd_set_backdrop(NULL);
1235 #endif
1236 #ifdef HAVE_LCD_COLOR
1237 rb->lcd_set_foreground(LCD_WHITE);
1238 rb->lcd_set_background(BG_COLOR);
1239 #endif
1240 rb->lcd_clear_display();
1242 struct game_context pb;
1243 pb.level=1;
1244 pb.highlevel=1;
1245 struct configdata config[] = {
1246 {TYPE_INT, 1, NUM_LEVELS, { .int_p = &(pb.level) }, "level", NULL},
1247 {TYPE_INT, 1, NUM_LEVELS, { .int_p = &(pb.highlevel) }, "highlevel", NULL},
1249 configfile_load(CONFIG_FILE_NAME,config,2,0);
1250 pegbox_main(&pb);
1251 configfile_save(CONFIG_FILE_NAME,config,2,0);
1252 rb->lcd_setfont(FONT_UI);
1253 #endif /* HAVE_LCD_BITMAP */
1255 return PLUGIN_OK;