Use a more natural guard for the callback definition
[kugel-rb.git] / apps / plugins / pegbox.c
blobf80b163c3f2924b432f7a3ce1291ec642a6d1fe0
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"
29 PLUGIN_HEADER
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_SA9200_PAD
360 #define PEGBOX_SELECT BUTTON_RIGHT
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_NEXT
368 #define PEGBOX_LEFT BUTTON_PREV
370 #define SELECT_TEXT "RIGHT"
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 == ONDAVX747_PAD || \
377 CONFIG_KEYPAD == ONDAVX777_PAD || \
378 CONFIG_KEYPAD == MROBE500_PAD
379 #define PEGBOX_QUIT BUTTON_POWER
381 #define QUIT_TEXT "POWER"
383 #elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
384 #define PEGBOX_SAVE (BUTTON_REC|BUTTON_FFWD)
385 #define PEGBOX_QUIT (BUTTON_REC|BUTTON_PLAY)
386 #define PEGBOX_RESTART (BUTTON_REC|BUTTON_REW)
387 #define PEGBOX_LVL_UP BUTTON_FFWD
388 #define PEGBOX_LVL_DOWN BUTTON_REW
389 #define PEGBOX_UP BUTTON_UP
390 #define PEGBOX_DOWN BUTTON_DOWN
391 #define PEGBOX_RIGHT BUTTON_RIGHT
392 #define PEGBOX_LEFT BUTTON_LEFT
393 #define PEGBOX_SELECT BUTTON_PLAY
395 #define SAVE_TEXT "REC + FFWD"
396 #define QUIT_TEXT "REC + PLAY"
397 #define RESTART_TEXT "REC + REW"
398 #define LVL_UP_TEXT "FFWD"
399 #define LVL_DOWN_TEXT "REW"
400 #define SELECT_TEXT "PLAY"
402 #elif CONFIG_KEYPAD == PBELL_VIBE500_PAD
403 #define PEGBOX_SAVE (BUTTON_REC|BUTTON_OK)
404 #define PEGBOX_QUIT BUTTON_REC
405 #define PEGBOX_RESTART BUTTON_MENU
406 #define PEGBOX_LVL_UP BUTTON_OK
407 #define PEGBOX_LVL_DOWN BUTTON_CANCEL
408 #define PEGBOX_UP BUTTON_UP
409 #define PEGBOX_DOWN BUTTON_DOWN
410 #define PEGBOX_RIGHT BUTTON_NEXT
411 #define PEGBOX_LEFT BUTTON_PREV
412 #define PEGBOX_SELECT BUTTON_PLAY
414 #define SAVE_TEXT "REC + OK"
415 #define QUIT_TEXT "REC"
416 #define RESTART_TEXT "MENU"
417 #define LVL_UP_TEXT "OK"
418 #define LVL_DOWN_TEXT "CANCEL"
419 #define SELECT_TEXT "PLAY"
421 #else
422 #error Unsupported keymap!
423 #endif
425 #ifdef HAVE_TOUCHSCREEN
426 #ifndef PEGBOX_QUIT
427 #define PEGBOX_QUIT BUTTON_TOPLEFT
428 #endif
429 #ifndef PEGBOX_SELECT
430 #define PEGBOX_SELECT BUTTON_CENTER
431 #endif
432 #ifndef PEGBOX_RESTART
433 #define PEGBOX_RESTART BUTTON_TOPRIGHT
434 #endif
435 #ifndef PEGBOX_LVL_UP
436 #define PEGBOX_LVL_UP BUTTON_BOTTOMLEFT
437 #endif
438 #ifndef PEGBOX_LVL_DOWN
439 #define PEGBOX_LVL_DOWN BUTTON_BOTTOMRIGHT
440 #endif
441 #ifndef PEGBOX_UP
442 #define PEGBOX_UP BUTTON_TOPMIDDLE
443 #endif
444 #ifndef PEGBOX_DOWN
445 #define PEGBOX_DOWN BUTTON_BOTTOMMIDDLE
446 #endif
447 #ifndef PEGBOX_RIGHT
448 #define PEGBOX_RIGHT BUTTON_MIDRIGHT
449 #endif
450 #ifndef PEGBOX_LEFT
451 #define PEGBOX_LEFT BUTTON_MIDLEFT
452 #endif
453 #ifndef SELECT_TEXT
454 #define SELECT_TEXT "CENTER"
455 #endif
456 #ifndef QUIT_TEXT
457 #define QUIT_TEXT "TOPLEFT"
458 #endif
459 #ifndef RESTART_TEXT
460 #define RESTART_TEXT "TOPRIGHT"
461 #endif
462 #ifndef LVL_UP_TEXT
463 #define LVL_UP_TEXT "BOTTOMLEFT"
464 #endif
465 #ifndef LVL_DOWN_TEXT
466 #define LVL_DOWN_TEXT "BOTTOMRIGHT"
467 #endif
468 #endif
471 /* get several sizes from the bitmaps */
472 #ifdef BMPWIDTH_pegbox_pieces
473 #define PIECE_WIDTH BMPWIDTH_pegbox_pieces
474 #define PIECE_HEIGHT (BMPHEIGHT_pegbox_pieces/7)
475 #else
476 /* dummy numbers to avoid #error in dependency generation */
477 #define PIECE_WIDTH 50
478 #define PIECE_HEIGHT 10
479 #endif
481 #define BOARD_WIDTH (12*PIECE_WIDTH)
482 #define BOARD_HEIGHT (8*PIECE_HEIGHT)
485 /* define a wide layout where the statistics are alongside the board, not above
486 * base calculation on the piece bitmaps for the 8x12 board */
487 #if (LCD_WIDTH - BOARD_WIDTH) > (LCD_HEIGHT - BOARD_HEIGHT)
488 #define WIDE_LAYOUT
489 #endif
492 #define HEADER_WIDTH BMPWIDTH_pegbox_header
493 #define HEADER_HEIGHT BMPHEIGHT_pegbox_header
496 #if defined WIDE_LAYOUT
498 #if ((BOARD_WIDTH + HEADER_WIDTH + 4) <= LCD_WIDTH)
499 #define BOARD_X 2
500 #else
501 #define BOARD_X 1
502 #endif
503 #define BOARD_Y (LCD_HEIGHT-BOARD_HEIGHT)/2
505 #if (LCD_WIDTH >= 132) && (LCD_HEIGHT >= 80)
506 #define TEXT_X 116
507 #define LEVEL_TEXT_Y 14
508 #define PEGS_TEXT_Y 58
509 #elif (LCD_WIDTH >= 128) && (LCD_HEIGHT >= 64)
510 #define TEXT_X 112
511 #define LEVEL_TEXT_Y 27
512 #define PEGS_TEXT_Y 50
513 #else
514 #error "Unsupported screen size"
515 #endif
517 #else /* "normal" layout */
519 #define BOARD_X (LCD_WIDTH-BOARD_WIDTH)/2
520 #if ((BOARD_HEIGHT + HEADER_HEIGHT + 4) <= LCD_HEIGHT)
521 #define BOARD_Y HEADER_HEIGHT+2
522 #else
523 #define BOARD_Y HEADER_HEIGHT
524 #endif
526 #if LCD_WIDTH >= 640
527 #define LEVEL_TEXT_X 118
528 #define PEGS_TEXT_X 552
529 #define TEXT_Y 56
530 #elif LCD_WIDTH >= 320
531 #define LEVEL_TEXT_X 59
532 #define PEGS_TEXT_X 276
533 #define TEXT_Y 28
534 #elif LCD_WIDTH >= 240
535 #define LEVEL_TEXT_X 59
536 #define PEGS_TEXT_X 196
537 #define TEXT_Y 28
538 #elif LCD_WIDTH >= 220
539 #define LEVEL_TEXT_X 49
540 #define PEGS_TEXT_X 186
541 #define TEXT_Y 28
542 #elif LCD_WIDTH >= 176
543 #define LEVEL_TEXT_X 38
544 #define PEGS_TEXT_X 155
545 #define TEXT_Y 17
546 #elif LCD_WIDTH >= 160
547 #define LEVEL_TEXT_X 37
548 #define PEGS_TEXT_X 140
549 #define TEXT_Y 13
550 #elif LCD_WIDTH >= 138
551 #define LEVEL_TEXT_X 28
552 #define PEGS_TEXT_X 119
553 #define TEXT_Y 15
554 #elif LCD_WIDTH >= 128
555 #if HEADER_HEIGHT > 16
556 #define LEVEL_TEXT_X 26
557 #define PEGS_TEXT_X 107
558 #define TEXT_Y 31
559 #else
560 #define LEVEL_TEXT_X 15
561 #define PEGS_TEXT_X 100
562 #define TEXT_Y 5
563 #endif /* HEADER_HEIGHT */
564 #elif LCD_WIDTH >= 112
565 #define LEVEL_TEXT_X 25
566 #define PEGS_TEXT_X 90
567 #define TEXT_Y 0
568 #endif /* LCD_WIDTH */
570 #endif /* WIDE_LAYOUT */
573 #ifdef HAVE_LCD_COLOR
574 #define BG_COLOR LCD_BLACK
575 #define TEXT_BG LCD_RGBPACK(189,189,189)
576 #endif
579 #ifdef HAVE_TOUCHSCREEN
580 #include "lib/pluginlib_touchscreen.h"
581 static struct ts_raster pegbox_raster =
582 { BOARD_X, BOARD_Y, COLS*PIECE_WIDTH, ROWS*PIECE_HEIGHT,
583 PIECE_WIDTH, PIECE_HEIGHT };
584 static struct ts_raster_button_mapping pegbox_raster_btn =
585 { &pegbox_raster, false, false, true, false, true, {0, 0}, 0, 0, 0 };
586 #endif
589 struct game_context {
590 unsigned int level;
591 unsigned int highlevel;
592 signed int player_row;
593 signed int player_col;
594 unsigned int num_left;
595 unsigned int playboard[ROWS][COLS];
598 char levels[NUM_LEVELS][ROWS][COLS] = {
599 /* Level 1 */
600 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
601 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
602 {1, 0, 0, 0, 7, 0, 0, 5, 0, 0, 0, 1,},
603 {1, 0, 0, 0, 0, 3, 3, 2, 0, 0, 0, 1,},
604 {1, 0, 0, 0, 4, 6, 0, 5, 0, 0, 0, 1,},
605 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
606 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
607 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
609 /* Level 2 */
610 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
611 {1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 1,},
612 {1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1,},
613 {1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1,},
614 {7, 0, 0, 0, 2, 2, 5, 5, 0, 0, 0, 1,},
615 {1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1,},
616 {1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1,},
617 {1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 1,}},
619 /* Level 3 */
620 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
621 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
622 {1, 0, 0, 0, 0, 0, 2, 0, 7, 0, 0, 0,},
623 {1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 2, 1,},
624 {1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1,},
625 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1,},
626 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
627 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
629 /* Level 4 */
630 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
631 {6, 0, 4, 0, 2, 0, 2, 0, 0, 0, 0, 1,},
632 {6, 0, 3, 0, 5, 0, 2, 0, 0, 0, 0, 1,},
633 {6, 0, 5, 0, 4, 7, 2, 0, 0, 0, 0, 1,},
634 {6, 0, 2, 0, 4, 0, 2, 0, 3, 0, 0, 1,},
635 {6, 0, 4, 0, 5, 0, 2, 0, 0, 0, 0, 1,},
636 {6, 0, 5, 0, 4, 0, 2, 0, 0, 0, 0, 1,},
637 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
639 /* Level 5 */
640 {{0, 6, 6, 0, 4, 6, 0, 0, 6, 0, 0, 0,},
641 {0, 6, 6, 0, 4, 4, 0, 0, 6, 0, 0, 2,},
642 {2, 6, 6, 0, 6, 6, 6, 0, 1, 2, 2, 2,},
643 {0, 6, 6, 0, 6, 4, 6, 0, 1, 2, 0, 2,},
644 {0, 6, 6, 0, 6, 7, 6, 5, 6, 0, 0, 0,},
645 {2, 6, 6, 0, 6, 6, 6, 0, 6, 0, 0, 0,},
646 {0, 6, 6, 0, 4, 0, 0, 0, 6, 0, 0, 0,},
647 {0, 6, 6, 0, 0, 5, 0, 0, 6, 5, 5, 0,}},
649 /* Level 6 */
650 {{7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
651 {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,},
652 {2, 0, 0, 2, 0, 0, 0, 2, 2, 0, 0, 0,},
653 {0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 0,},
654 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
655 {0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1,},
656 {0, 3, 0, 0, 0, 0, 0, 0, 5, 4, 6, 0,},
657 {0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1,}},
659 /* Level 7 */
660 {{1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1,},
661 {1, 1, 1, 6, 0, 0, 4, 6, 0, 1, 1, 1,},
662 {1, 1, 1, 1, 0, 1, 5, 1, 0, 1, 1, 1,},
663 {1, 1, 1, 2, 3, 3, 7, 4, 2, 6, 1, 1,},
664 {1, 1, 1, 1, 0, 1, 2, 1, 0, 0, 0, 1,},
665 {1, 1, 1, 1, 0, 0, 5, 0, 0, 1, 0, 1,},
666 {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1,},
667 {1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,}},
669 /* Level 8 */
670 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
671 {0, 0, 3, 3, 3, 3, 3, 4, 3, 3, 0, 0,},
672 {0, 0, 3, 3, 3, 2, 3, 3, 5, 3, 0, 0,},
673 {7, 0, 3, 3, 3, 2, 3, 3, 4, 3, 0, 0,},
674 {0, 0, 3, 3, 4, 5, 3, 3, 3, 3, 0, 0,},
675 {0, 0, 3, 3, 5, 2, 3, 3, 3, 3, 0, 0,},
676 {0, 0, 3, 3, 2, 4, 3, 3, 3, 3, 0, 0,},
677 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
679 /* Level 9 */
680 {{0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,},
681 {0, 3, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,},
682 {0, 0, 0, 0, 2, 4, 4, 3, 0, 1, 1, 0,},
683 {0, 1, 0, 0, 2, 1, 0, 0, 0, 1, 1, 1,},
684 {0, 0, 0, 2, 2, 7, 1, 0, 0, 0, 0, 2,},
685 {0, 0, 0, 0, 2, 1, 0, 0, 1, 1, 1, 1,},
686 {0, 3, 1, 0, 2, 5, 5, 0, 0, 0, 3, 0,},
687 {0, 0, 0, 0, 4, 1, 0, 0, 0, 0, 0, 0,}},
689 /* Level 10 */
690 {{1, 1, 1, 1, 2, 1, 1, 1, 0, 0, 0, 0,},
691 {1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 7,},
692 {0, 0, 4, 0, 6, 6, 6, 0, 0, 0, 3, 0,},
693 {0, 3, 3, 0, 6, 6, 6, 0, 4, 3, 4, 0,},
694 {0, 3, 3, 0, 6, 6, 6, 0, 4, 3, 4, 0,},
695 {0, 0, 0, 0, 6, 6, 6, 0, 3, 0, 0, 0,},
696 {1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0,},
697 {1, 1, 1, 1, 1, 2, 1, 1, 0, 0, 0, 0,}},
699 /* Level 11 */
700 {{1, 7, 1, 0, 1, 1, 6, 0, 0, 1, 1, 0,},
701 {1, 0, 0, 0, 5, 4, 6, 6, 0, 2, 2, 0,},
702 {1, 2, 1, 2, 0, 1, 6, 0, 0, 2, 2, 0,},
703 {1, 0, 0, 2, 0, 1, 0, 0, 0, 3, 3, 0,},
704 {1, 2, 1, 0, 0, 1, 0, 1, 0, 3, 3, 0,},
705 {0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0,},
706 {0, 3, 4, 3, 0, 1, 0, 1, 0, 0, 0, 0,},
707 {0, 0, 0, 0, 2, 2, 2, 1, 1, 1, 1, 1,}},
709 /* Level 12 */
710 {{7, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,},
711 {1, 2, 1, 2, 1, 2, 1, 1, 0, 0, 0, 1,},
712 {0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1,},
713 {1, 2, 1, 2, 1, 2, 1, 0, 0, 0, 0, 1,},
714 {0, 0, 0, 0, 0, 0, 1, 1, 5, 5, 6, 1,},
715 {1, 2, 1, 2, 1, 2, 1, 1, 0, 2, 2, 1,},
716 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1,},
717 {1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1,}},
719 /* Level 13 */
720 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
721 {0, 0, 4, 0, 2, 0, 5, 0, 4, 0, 0, 6,},
722 {0, 0, 2, 0, 5, 0, 2, 0, 4, 0, 0, 6,},
723 {7, 0, 3, 0, 4, 0, 5, 0, 4, 0, 0, 6,},
724 {0, 0, 5, 0, 4, 0, 2, 0, 4, 0, 0, 6,},
725 {0, 0, 4, 0, 2, 0, 5, 0, 4, 0, 0, 6,},
726 {0, 0, 3, 0, 3, 0, 2, 0, 4, 0, 0, 6,},
727 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
729 /* Level 14 */
730 {{1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1,},
731 {1, 1, 0, 2, 0, 0, 4, 0, 0, 2, 0, 1,},
732 {1, 6, 0, 0, 5, 1, 0, 1, 1, 0, 0, 1,},
733 {1, 1, 1, 0, 0, 3, 5, 3, 0, 0, 1, 1,},
734 {1, 1, 0, 0, 1, 1, 0, 1, 5, 0, 0, 6,},
735 {1, 1, 0, 2, 0, 0, 4, 0, 0, 0, 7, 1,},
736 {1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1,},
737 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
739 /* Level 15 */
740 {{0, 0, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
741 {0, 0, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
742 {0, 3, 4, 6, 0, 6, 0, 6, 0, 6, 0, 2,},
743 {0, 4, 0, 6, 0, 6, 4, 6, 0, 6, 0, 1,},
744 {0, 3, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
745 {7, 0, 0, 6, 4, 6, 0, 6, 0, 6, 0, 1,},
746 {0, 0, 4, 6, 0, 6, 0, 6, 4, 6, 0, 1,},
747 {0, 0, 4, 6, 0, 6, 0, 6, 0, 6, 0, 1,}}
750 /***********************************************************************
751 * pegbox_draw_board() draws the game's current level.
752 ************************************************************************/
753 static void pegbox_draw_board(struct game_context* pb)
755 unsigned int r, c, type;
756 pb->num_left = 0;
757 char str[5];
759 rb->lcd_clear_display();
760 #ifdef WIDE_LAYOUT
761 rb->lcd_bitmap(pegbox_header,LCD_WIDTH-HEADER_WIDTH,0,
762 HEADER_WIDTH,LCD_HEIGHT);
763 #else
764 rb->lcd_bitmap(pegbox_header,(LCD_WIDTH-HEADER_WIDTH)/2,0,
765 HEADER_WIDTH, HEADER_HEIGHT);
766 #endif /* WIDE_LAYOUT */
768 #if ((BOARD_HEIGHT + HEADER_HEIGHT + 4) <= LCD_HEIGHT)
769 rb->lcd_drawrect(BOARD_X-2,BOARD_Y-2,BOARD_WIDTH+4,BOARD_HEIGHT+4);
770 #endif /* enough space for a frame? */
772 #ifdef HAVE_LCD_COLOR
773 rb->lcd_set_foreground(LCD_WHITE);
774 rb->lcd_fillrect(BOARD_X-1,BOARD_Y-1,BOARD_WIDTH+2,BOARD_HEIGHT+2);
775 rb->lcd_set_foreground(LCD_BLACK);
776 rb->lcd_set_background(TEXT_BG);
777 #endif
779 for (r=0 ; r < ROWS ; r++) {
780 for (c = 0 ; c < COLS ; c++) {
782 type = pb->playboard[r][c];
784 if(type != SPACE) {
785 rb->lcd_bitmap_part(pegbox_pieces, 0, (type-1)*PIECE_HEIGHT,
786 STRIDE( SCREEN_MAIN,
787 BMPWIDTH_pegbox_pieces,BMPHEIGHT_pegbox_pieces),
788 c * PIECE_WIDTH + BOARD_X,
789 r * PIECE_HEIGHT + BOARD_Y, PIECE_WIDTH,
790 PIECE_HEIGHT);
793 if(pb->playboard[r][c] == PLAYER) {
794 pb->player_row=r;
795 pb->player_col=c;
797 else if (type != WALL && type != SPACE && type != HOLE)
798 pb->num_left++;
802 #ifdef WIDE_LAYOUT
803 rb->snprintf(str, 3, "%d", pb->level);
804 rb->lcd_putsxy(TEXT_X, LEVEL_TEXT_Y, str);
805 rb->snprintf(str, 3, "%d", pb->num_left);
806 rb->lcd_putsxy(TEXT_X, PEGS_TEXT_Y, str);
807 #else
808 rb->snprintf(str, 3, "%d", pb->level);
809 rb->lcd_putsxy(LEVEL_TEXT_X, TEXT_Y, str);
810 rb->snprintf(str, 3, "%d", pb->num_left);
811 rb->lcd_putsxy(PEGS_TEXT_X, TEXT_Y, str);
812 #endif /*WIDE_LAYOUT*/
814 #ifdef HAVE_LCD_COLOR
815 rb->lcd_set_background(BG_COLOR);
816 rb->lcd_set_foreground(LCD_WHITE);
817 #endif
818 /* print out the screen */
819 rb->lcd_update();
822 /*****************************************************************************
823 * pegbox_load_level() loads the player's current level from the array and sets the
824 * player's position.
825 ******************************************************************************/
826 static void pegbox_load_level(struct game_context* pb)
828 int r, c;
830 for(r = 0; r < ROWS; r++)
831 for(c = 0; c < COLS; c++)
832 pb->playboard[r][c] = levels[pb->level-1][r][c];
835 /*****************************************************************************
836 * pegbox_new_piece() creates a new piece at a specified location. The player
837 * navigates through the pieces and selects one.
838 ******************************************************************************/
839 static void pegbox_new_piece(struct game_context* pb, unsigned int x_loc,
840 unsigned int y_loc)
842 int button;
843 bool exit = false;
845 pb->playboard[x_loc][y_loc] = TRIANGLE;
847 while (!exit) {
848 pegbox_draw_board(pb);
849 button = rb->button_get(true);
850 #ifdef HAVE_TOUCHSCREEN
851 if(button & BUTTON_TOUCHSCREEN)
853 pegbox_raster_btn.two_d_from.y = x_loc;
854 pegbox_raster_btn.two_d_from.x = y_loc;
856 struct ts_raster_button_result ret =
857 touchscreen_raster_map_button(&pegbox_raster_btn,
858 rb->button_get_data() >> 16,
859 rb->button_get_data() & 0xffff,
860 button);
861 if(ret.action == TS_ACTION_TWO_D_MOVEMENT)
863 if(ret.to.x > ret.from.x)
864 button = PEGBOX_UP;
865 else if(ret.to.x < ret.from.x)
866 button = PEGBOX_DOWN;
867 else if(ret.to.y > ret.from.y)
868 button = PEGBOX_LEFT;
869 else if(ret.to.y < ret.from.y)
870 button = PEGBOX_RIGHT;
872 else if(ret.action == TS_ACTION_CLICK
873 && (unsigned)ret.to.x == y_loc
874 && (unsigned)ret.to.y == x_loc)
875 button = PEGBOX_SELECT;
877 #endif
878 switch(button){
879 case PEGBOX_LEFT:
880 case (PEGBOX_LEFT|BUTTON_REPEAT):
881 case PEGBOX_DOWN:
882 case (PEGBOX_DOWN|BUTTON_REPEAT):
883 if (pb->playboard[x_loc][y_loc] < 5)
884 pb->playboard[x_loc][y_loc]++;
885 else
886 pb->playboard[x_loc][y_loc] = TRIANGLE;
887 break;
888 case PEGBOX_RIGHT:
889 case (PEGBOX_RIGHT|BUTTON_REPEAT):
890 case PEGBOX_UP:
891 case (PEGBOX_UP|BUTTON_REPEAT):
892 if (pb->playboard[x_loc][y_loc] > 2)
893 pb->playboard[x_loc][y_loc]--;
894 else
895 pb->playboard[x_loc][y_loc] = CIRCLE;
896 break;
897 case PEGBOX_SELECT:
898 exit=true;
899 break;
904 /*****************************************************************************
905 * pegbox_move_player() moves the player and pieces and updates the board accordingly.
906 ******************************************************************************/
907 static void pegbox_move_player(struct game_context* pb, signed int x_dir,
908 signed int y_dir)
910 unsigned int type1, type2;
911 signed int r1,c1,r2,c2;
913 r1 = pb->player_row+y_dir;
914 c1 = pb->player_col+x_dir;
915 r2 = pb->player_row+y_dir*2;
916 c2 = pb->player_col+x_dir*2;
918 type1 = pb->playboard[r1][c1];
919 type2 = pb->playboard[r2][c2];
921 if (r1 == ROWS || c1 == COLS || r1 < 0 || c1 < 0 || type1 == WALL)
922 return;
923 else if(type1 != SPACE) {
924 if (r2 == ROWS || c2 == COLS || r2 < 0 || c2 < 0 || type2 == WALL)
925 return;
929 pb->playboard[pb->player_row][pb->player_col] = SPACE;
930 pb->player_row += y_dir;
931 pb->player_col += x_dir;
933 if (type1 == HOLE) {
934 pegbox_draw_board(pb);
935 rb->splash(HZ*2, "You fell down a hole!");
936 pegbox_load_level(pb);
938 else if (type1 == SPACE)
939 pb->playboard[r1][c1] = PLAYER;
940 else {
941 pb->playboard[r1][c1] = PLAYER;
942 if(type1 == type2) {
943 if (type1 == TRIANGLE)
944 pb->playboard[r2][c2] = WALL;
945 else if (type1 == CROSS) {
946 pb->playboard[r1][c1] = SPACE;
947 pegbox_new_piece(pb, r2, c2);
948 pb->playboard[r1][c1] = PLAYER;
950 else
951 pb->playboard[r2][c2] = SPACE;
953 else if (type2 == SPACE)
954 pb->playboard[r2][c2] = type1;
955 else if (type2 == HOLE) {
956 if (type1 == SQUARE)
957 pb->playboard[r2][c2] = SPACE;
959 else {
960 rb->splash(HZ*2, "Illegal Move!");
961 pegbox_load_level(pb);
965 pegbox_draw_board(pb);
968 /***********************************************************************
969 * pegbox_help() display help text
970 ************************************************************************/
971 static bool pegbox_help(void)
973 static char* help_text[] = {
974 "Pegbox", "", "Aim", "",
975 "To", "beat", "each", "level,", "you", "must", "destroy", "all", "of",
976 "the", "pegs.", "If", "two", "like", "pegs", "are", "pushed", "into",
977 "each", "other,", "they", "disappear", "except", "for", "triangles",
978 "which", "form", "a", "solid", "block", "and", "crosses", "which",
979 "allow", "you", "to", "choose", "a", "replacement", "block.", "", "",
980 "Controls", "",
981 RESTART_TEXT, "to", "restart", "level", "",
982 LVL_UP_TEXT, "to", "go", "up", "a", "level", "",
983 LVL_DOWN_TEXT, "to", "go", "down", "a", "level", "",
984 SELECT_TEXT, "to", "choose", "peg", "",
985 QUIT_TEXT, "to", "quit"
987 static struct style_text formation[]={
988 { 0, TEXT_CENTER|TEXT_UNDERLINE },
989 { 2, C_RED },
990 { 46, C_RED },
991 LAST_STYLE_ITEM
994 rb->lcd_setfont(FONT_UI);
995 if (display_text(ARRAYLEN(help_text), help_text, formation, NULL, true))
996 return true;
997 rb->lcd_setfont(FONT_SYSFIXED);
999 return false;
1002 /***********************************************************************
1003 * pegbox_menu() is the game menu
1004 ************************************************************************/
1005 static bool _ingame;
1006 static int pegbox_menu_cb(int action, const struct menu_item_ex *this_item)
1008 int i = (intptr_t)this_item;
1009 if( action == ACTION_REQUEST_MENUITEM )
1011 if((!_ingame && (i==0 || i==1)) || ( _ingame && i==2 ))
1012 return ACTION_EXIT_MENUITEM;
1014 return action;
1017 static unsigned int pegbox_menu(struct game_context* pb, bool ingame)
1019 int selected = 0;
1020 int last_level = pb->level;
1022 MENUITEM_STRINGLIST (main_menu, "Pegbox Menu", pegbox_menu_cb,
1023 "Resume Game", "Restart Level", "Start Game",
1024 "Select Level", "Help",
1025 "Playback Control", "Quit");
1026 _ingame = ingame;
1027 rb->button_clear_queue();
1029 while (true) {
1030 switch (rb->do_menu(&main_menu, &selected, NULL, false)) {
1031 case 0:
1032 pb->level = last_level;
1033 pegbox_draw_board(pb);
1034 return 0;
1035 case 1:
1036 case 2:
1037 pegbox_load_level(pb);
1038 pegbox_draw_board(pb);
1039 return 0;
1040 case 3:
1041 if(rb->set_int("Select Level", "", UNIT_INT, &pb->level,
1042 NULL, 1, 1, pb->highlevel, NULL))
1043 return 1;
1044 break;
1045 case 4:
1046 if (pegbox_help())
1047 return 1;
1048 break;
1049 case 5:
1050 if (playback_control(NULL))
1051 return 1;
1052 break;
1053 case 6:
1054 return 1;
1055 case MENU_ATTACHED_USB:
1056 return 1;
1057 default:
1058 break;
1063 /***********************************************************************
1064 * pegbox_main() is the main game subroutine
1065 ************************************************************************/
1066 static int pegbox_main(struct game_context* pb)
1068 int button;
1070 if (pegbox_menu(pb, false)==1) {
1071 return 1;
1074 while (true) {
1075 button = rb->button_get(true);
1076 #ifdef HAVE_TOUCHSCREEN
1077 if(button & BUTTON_TOUCHSCREEN)
1079 pegbox_raster_btn.two_d_from.y = pb->player_row;
1080 pegbox_raster_btn.two_d_from.x = pb->player_col;
1082 struct ts_raster_button_result ret =
1083 touchscreen_raster_map_button(&pegbox_raster_btn,
1084 rb->button_get_data() >> 16,
1085 rb->button_get_data() & 0xffff,
1086 button);
1087 if(ret.action == TS_ACTION_TWO_D_MOVEMENT)
1088 pegbox_move_player(pb, ret.to.x - ret.from.x, ret.to.y - ret.from.y);
1090 #endif
1091 switch(button){
1092 case PEGBOX_LEFT: /* move cursor left */
1093 case (PEGBOX_LEFT|BUTTON_REPEAT):
1094 pegbox_move_player(pb, -1, 0);
1095 break;
1097 case PEGBOX_RIGHT: /* move cursor right */
1098 case (PEGBOX_RIGHT|BUTTON_REPEAT):
1099 pegbox_move_player(pb, 1, 0);
1100 break;
1102 case PEGBOX_DOWN: /* move cursor down */
1103 case (PEGBOX_DOWN|BUTTON_REPEAT):
1104 pegbox_move_player(pb, 0, 1);
1105 break;
1107 case PEGBOX_UP: /* move cursor up */
1108 case (PEGBOX_UP|BUTTON_REPEAT):
1109 pegbox_move_player(pb, 0, -1);
1110 break;
1112 case PEGBOX_QUIT:
1113 if (pegbox_menu(pb, true)==1) {
1114 return 1;
1116 break;
1118 #ifdef PEGBOX_RESTART
1119 case PEGBOX_RESTART:
1120 pegbox_load_level(pb);
1121 pegbox_draw_board(pb);
1122 break;
1123 #endif
1125 #ifdef PEGBOX_LVL_UP
1126 case (PEGBOX_LVL_UP|BUTTON_REPEAT):
1127 case PEGBOX_LVL_UP:
1128 if (pb->level >= pb->highlevel) {
1129 pb->level = 1;
1130 } else {
1131 pb->level++;
1133 pegbox_load_level(pb);
1134 pegbox_draw_board(pb);
1135 break;
1136 #endif
1138 #ifdef PEGBOX_LVL_DOWN
1139 case (PEGBOX_LVL_DOWN|BUTTON_REPEAT):
1140 case PEGBOX_LVL_DOWN:
1141 if(pb->level <= 1) {
1142 pb->level = pb->highlevel;
1143 } else {
1144 pb->level--;
1146 pegbox_load_level(pb);
1147 pegbox_draw_board(pb);
1148 break;
1149 #endif
1152 if (pb->num_left == 0) {
1153 rb->splash(HZ*2, "Nice Pegging!");
1154 if (pb->level == NUM_LEVELS) {
1155 pegbox_draw_board(pb);
1156 rb->splash(HZ*2, "Congratulations!");
1157 rb->splash(HZ*2, "You have finished the game!");
1158 if (pegbox_menu(pb,false)==1) {
1159 return 1;
1162 else {
1163 pb->level++;
1164 pegbox_load_level(pb);
1165 pegbox_draw_board(pb);
1168 if(pb->level > pb->highlevel)
1169 pb->highlevel = pb->level;
1173 return PLUGIN_OK;
1176 /*****************************************************************************
1177 * plugin entry point.
1178 ******************************************************************************/
1179 enum plugin_status plugin_start(const void* parameter)
1181 (void)parameter;
1182 #ifdef HAVE_LCD_BITMAP
1183 rb->lcd_setfont(FONT_SYSFIXED);
1184 #if LCD_DEPTH > 1
1185 rb->lcd_set_backdrop(NULL);
1186 #endif
1187 #ifdef HAVE_LCD_COLOR
1188 rb->lcd_set_foreground(LCD_WHITE);
1189 rb->lcd_set_background(BG_COLOR);
1190 #endif
1191 rb->lcd_clear_display();
1193 struct game_context pb;
1194 pb.level=1;
1195 pb.highlevel=1;
1196 struct configdata config[] = {
1197 {TYPE_INT, 1, NUM_LEVELS, { .int_p = &(pb.level) }, "level", NULL},
1198 {TYPE_INT, 1, NUM_LEVELS, { .int_p = &(pb.highlevel) }, "highlevel", NULL},
1200 configfile_load(CONFIG_FILE_NAME,config,2,0);
1201 pegbox_main(&pb);
1202 configfile_save(CONFIG_FILE_NAME,config,2,0);
1203 rb->lcd_setfont(FONT_UI);
1204 #endif /* HAVE_LCD_BITMAP */
1206 return PLUGIN_OK;