Some formatting fixes, reported by Alexander Levin
[kugel-rb.git] / apps / plugins / pegbox.c
blob72b9f70c875412c463bc9e58ca10c8d169624316
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 #else
403 #error Unsupported keymap!
404 #endif
406 #ifdef HAVE_TOUCHSCREEN
407 #ifndef PEGBOX_QUIT
408 #define PEGBOX_QUIT BUTTON_TOPLEFT
409 #endif
410 #ifndef PEGBOX_SELECT
411 #define PEGBOX_SELECT BUTTON_CENTER
412 #endif
413 #ifndef PEGBOX_RESTART
414 #define PEGBOX_RESTART BUTTON_TOPRIGHT
415 #endif
416 #ifndef PEGBOX_LVL_UP
417 #define PEGBOX_LVL_UP BUTTON_BOTTOMLEFT
418 #endif
419 #ifndef PEGBOX_LVL_DOWN
420 #define PEGBOX_LVL_DOWN BUTTON_BOTTOMRIGHT
421 #endif
422 #ifndef PEGBOX_UP
423 #define PEGBOX_UP BUTTON_TOPMIDDLE
424 #endif
425 #ifndef PEGBOX_DOWN
426 #define PEGBOX_DOWN BUTTON_BOTTOMMIDDLE
427 #endif
428 #ifndef PEGBOX_RIGHT
429 #define PEGBOX_RIGHT BUTTON_MIDRIGHT
430 #endif
431 #ifndef PEGBOX_LEFT
432 #define PEGBOX_LEFT BUTTON_MIDLEFT
433 #endif
434 #ifndef SELECT_TEXT
435 #define SELECT_TEXT "CENTER"
436 #endif
437 #ifndef QUIT_TEXT
438 #define QUIT_TEXT "TOPLEFT"
439 #endif
440 #ifndef RESTART_TEXT
441 #define RESTART_TEXT "TOPRIGHT"
442 #endif
443 #ifndef LVL_UP_TEXT
444 #define LVL_UP_TEXT "BOTTOMLEFT"
445 #endif
446 #ifndef LVL_DOWN_TEXT
447 #define LVL_DOWN_TEXT "BOTTOMRIGHT"
448 #endif
449 #endif
452 /* get several sizes from the bitmaps */
453 #ifdef BMPWIDTH_pegbox_pieces
454 #define PIECE_WIDTH BMPWIDTH_pegbox_pieces
455 #define PIECE_HEIGHT (BMPHEIGHT_pegbox_pieces/7)
456 #else
457 /* dummy numbers to avoid #error in dependency generation */
458 #define PIECE_WIDTH 50
459 #define PIECE_HEIGHT 10
460 #endif
462 #define BOARD_WIDTH (12*PIECE_WIDTH)
463 #define BOARD_HEIGHT (8*PIECE_HEIGHT)
466 /* define a wide layout where the statistics are alongside the board, not above
467 * base calculation on the piece bitmaps for the 8x12 board */
468 #if (LCD_WIDTH - BOARD_WIDTH) > (LCD_HEIGHT - BOARD_HEIGHT)
469 #define WIDE_LAYOUT
470 #endif
473 #define HEADER_WIDTH BMPWIDTH_pegbox_header
474 #define HEADER_HEIGHT BMPHEIGHT_pegbox_header
477 #if defined WIDE_LAYOUT
479 #if ((BOARD_WIDTH + HEADER_WIDTH + 4) <= LCD_WIDTH)
480 #define BOARD_X 2
481 #else
482 #define BOARD_X 1
483 #endif
484 #define BOARD_Y (LCD_HEIGHT-BOARD_HEIGHT)/2
486 #if (LCD_WIDTH >= 132) && (LCD_HEIGHT >= 80)
487 #define TEXT_X 116
488 #define LEVEL_TEXT_Y 14
489 #define PEGS_TEXT_Y 58
490 #elif (LCD_WIDTH >= 128) && (LCD_HEIGHT >= 64)
491 #define TEXT_X 112
492 #define LEVEL_TEXT_Y 27
493 #define PEGS_TEXT_Y 50
494 #else
495 #error "Unsupported screen size"
496 #endif
498 #else /* "normal" layout */
500 #define BOARD_X (LCD_WIDTH-BOARD_WIDTH)/2
501 #if ((BOARD_HEIGHT + HEADER_HEIGHT + 4) <= LCD_HEIGHT)
502 #define BOARD_Y HEADER_HEIGHT+2
503 #else
504 #define BOARD_Y HEADER_HEIGHT
505 #endif
507 #if LCD_WIDTH >= 640
508 #define LEVEL_TEXT_X 118
509 #define PEGS_TEXT_X 552
510 #define TEXT_Y 56
511 #elif LCD_WIDTH >= 320
512 #define LEVEL_TEXT_X 59
513 #define PEGS_TEXT_X 276
514 #define TEXT_Y 28
515 #elif LCD_WIDTH >= 240
516 #define LEVEL_TEXT_X 59
517 #define PEGS_TEXT_X 196
518 #define TEXT_Y 28
519 #elif LCD_WIDTH >= 220
520 #define LEVEL_TEXT_X 49
521 #define PEGS_TEXT_X 186
522 #define TEXT_Y 28
523 #elif LCD_WIDTH >= 176
524 #define LEVEL_TEXT_X 38
525 #define PEGS_TEXT_X 155
526 #define TEXT_Y 17
527 #elif LCD_WIDTH >= 160
528 #define LEVEL_TEXT_X 37
529 #define PEGS_TEXT_X 140
530 #define TEXT_Y 13
531 #elif LCD_WIDTH >= 138
532 #define LEVEL_TEXT_X 28
533 #define PEGS_TEXT_X 119
534 #define TEXT_Y 15
535 #elif LCD_WIDTH >= 128
536 #if HEADER_HEIGHT > 16
537 #define LEVEL_TEXT_X 26
538 #define PEGS_TEXT_X 107
539 #define TEXT_Y 31
540 #else
541 #define LEVEL_TEXT_X 15
542 #define PEGS_TEXT_X 100
543 #define TEXT_Y 5
544 #endif /* HEADER_HEIGHT */
545 #elif LCD_WIDTH >= 112
546 #define LEVEL_TEXT_X 25
547 #define PEGS_TEXT_X 90
548 #define TEXT_Y 0
549 #endif /* LCD_WIDTH */
551 #endif /* WIDE_LAYOUT */
554 #ifdef HAVE_LCD_COLOR
555 #define BG_COLOR LCD_BLACK
556 #define TEXT_BG LCD_RGBPACK(189,189,189)
557 #endif
560 #ifdef HAVE_TOUCHSCREEN
561 #include "lib/pluginlib_touchscreen.h"
562 static struct ts_raster pegbox_raster =
563 { BOARD_X, BOARD_Y, COLS*PIECE_WIDTH, ROWS*PIECE_HEIGHT,
564 PIECE_WIDTH, PIECE_HEIGHT };
565 static struct ts_raster_button_mapping pegbox_raster_btn =
566 { &pegbox_raster, false, false, true, false, true, {0, 0}, 0, 0, 0 };
567 #endif
570 struct game_context {
571 unsigned int level;
572 unsigned int highlevel;
573 signed int player_row;
574 signed int player_col;
575 unsigned int num_left;
576 unsigned int playboard[ROWS][COLS];
579 char levels[NUM_LEVELS][ROWS][COLS] = {
580 /* Level 1 */
581 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
582 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
583 {1, 0, 0, 0, 7, 0, 0, 5, 0, 0, 0, 1,},
584 {1, 0, 0, 0, 0, 3, 3, 2, 0, 0, 0, 1,},
585 {1, 0, 0, 0, 4, 6, 0, 5, 0, 0, 0, 1,},
586 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
587 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
588 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
590 /* Level 2 */
591 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
592 {1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 1,},
593 {1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1,},
594 {1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1,},
595 {7, 0, 0, 0, 2, 2, 5, 5, 0, 0, 0, 1,},
596 {1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1,},
597 {1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1,},
598 {1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 1,}},
600 /* Level 3 */
601 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
602 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
603 {1, 0, 0, 0, 0, 0, 2, 0, 7, 0, 0, 0,},
604 {1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 2, 1,},
605 {1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1,},
606 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1,},
607 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
608 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
610 /* Level 4 */
611 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
612 {6, 0, 4, 0, 2, 0, 2, 0, 0, 0, 0, 1,},
613 {6, 0, 3, 0, 5, 0, 2, 0, 0, 0, 0, 1,},
614 {6, 0, 5, 0, 4, 7, 2, 0, 0, 0, 0, 1,},
615 {6, 0, 2, 0, 4, 0, 2, 0, 3, 0, 0, 1,},
616 {6, 0, 4, 0, 5, 0, 2, 0, 0, 0, 0, 1,},
617 {6, 0, 5, 0, 4, 0, 2, 0, 0, 0, 0, 1,},
618 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
620 /* Level 5 */
621 {{0, 6, 6, 0, 4, 6, 0, 0, 6, 0, 0, 0,},
622 {0, 6, 6, 0, 4, 4, 0, 0, 6, 0, 0, 2,},
623 {2, 6, 6, 0, 6, 6, 6, 0, 1, 2, 2, 2,},
624 {0, 6, 6, 0, 6, 4, 6, 0, 1, 2, 0, 2,},
625 {0, 6, 6, 0, 6, 7, 6, 5, 6, 0, 0, 0,},
626 {2, 6, 6, 0, 6, 6, 6, 0, 6, 0, 0, 0,},
627 {0, 6, 6, 0, 4, 0, 0, 0, 6, 0, 0, 0,},
628 {0, 6, 6, 0, 0, 5, 0, 0, 6, 5, 5, 0,}},
630 /* Level 6 */
631 {{7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
632 {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,},
633 {2, 0, 0, 2, 0, 0, 0, 2, 2, 0, 0, 0,},
634 {0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 0,},
635 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
636 {0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1,},
637 {0, 3, 0, 0, 0, 0, 0, 0, 5, 4, 6, 0,},
638 {0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1,}},
640 /* Level 7 */
641 {{1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1,},
642 {1, 1, 1, 6, 0, 0, 4, 6, 0, 1, 1, 1,},
643 {1, 1, 1, 1, 0, 1, 5, 1, 0, 1, 1, 1,},
644 {1, 1, 1, 2, 3, 3, 7, 4, 2, 6, 1, 1,},
645 {1, 1, 1, 1, 0, 1, 2, 1, 0, 0, 0, 1,},
646 {1, 1, 1, 1, 0, 0, 5, 0, 0, 1, 0, 1,},
647 {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1,},
648 {1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,}},
650 /* Level 8 */
651 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
652 {0, 0, 3, 3, 3, 3, 3, 4, 3, 3, 0, 0,},
653 {0, 0, 3, 3, 3, 2, 3, 3, 5, 3, 0, 0,},
654 {7, 0, 3, 3, 3, 2, 3, 3, 4, 3, 0, 0,},
655 {0, 0, 3, 3, 4, 5, 3, 3, 3, 3, 0, 0,},
656 {0, 0, 3, 3, 5, 2, 3, 3, 3, 3, 0, 0,},
657 {0, 0, 3, 3, 2, 4, 3, 3, 3, 3, 0, 0,},
658 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
660 /* Level 9 */
661 {{0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,},
662 {0, 3, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,},
663 {0, 0, 0, 0, 2, 4, 4, 3, 0, 1, 1, 0,},
664 {0, 1, 0, 0, 2, 1, 0, 0, 0, 1, 1, 1,},
665 {0, 0, 0, 2, 2, 7, 1, 0, 0, 0, 0, 2,},
666 {0, 0, 0, 0, 2, 1, 0, 0, 1, 1, 1, 1,},
667 {0, 3, 1, 0, 2, 5, 5, 0, 0, 0, 3, 0,},
668 {0, 0, 0, 0, 4, 1, 0, 0, 0, 0, 0, 0,}},
670 /* Level 10 */
671 {{1, 1, 1, 1, 2, 1, 1, 1, 0, 0, 0, 0,},
672 {1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 7,},
673 {0, 0, 4, 0, 6, 6, 6, 0, 0, 0, 3, 0,},
674 {0, 3, 3, 0, 6, 6, 6, 0, 4, 3, 4, 0,},
675 {0, 3, 3, 0, 6, 6, 6, 0, 4, 3, 4, 0,},
676 {0, 0, 0, 0, 6, 6, 6, 0, 3, 0, 0, 0,},
677 {1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0,},
678 {1, 1, 1, 1, 1, 2, 1, 1, 0, 0, 0, 0,}},
680 /* Level 11 */
681 {{1, 7, 1, 0, 1, 1, 6, 0, 0, 1, 1, 0,},
682 {1, 0, 0, 0, 5, 4, 6, 6, 0, 2, 2, 0,},
683 {1, 2, 1, 2, 0, 1, 6, 0, 0, 2, 2, 0,},
684 {1, 0, 0, 2, 0, 1, 0, 0, 0, 3, 3, 0,},
685 {1, 2, 1, 0, 0, 1, 0, 1, 0, 3, 3, 0,},
686 {0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0,},
687 {0, 3, 4, 3, 0, 1, 0, 1, 0, 0, 0, 0,},
688 {0, 0, 0, 0, 2, 2, 2, 1, 1, 1, 1, 1,}},
690 /* Level 12 */
691 {{7, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,},
692 {1, 2, 1, 2, 1, 2, 1, 1, 0, 0, 0, 1,},
693 {0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1,},
694 {1, 2, 1, 2, 1, 2, 1, 0, 0, 0, 0, 1,},
695 {0, 0, 0, 0, 0, 0, 1, 1, 5, 5, 6, 1,},
696 {1, 2, 1, 2, 1, 2, 1, 1, 0, 2, 2, 1,},
697 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1,},
698 {1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1,}},
700 /* Level 13 */
701 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
702 {0, 0, 4, 0, 2, 0, 5, 0, 4, 0, 0, 6,},
703 {0, 0, 2, 0, 5, 0, 2, 0, 4, 0, 0, 6,},
704 {7, 0, 3, 0, 4, 0, 5, 0, 4, 0, 0, 6,},
705 {0, 0, 5, 0, 4, 0, 2, 0, 4, 0, 0, 6,},
706 {0, 0, 4, 0, 2, 0, 5, 0, 4, 0, 0, 6,},
707 {0, 0, 3, 0, 3, 0, 2, 0, 4, 0, 0, 6,},
708 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
710 /* Level 14 */
711 {{1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1,},
712 {1, 1, 0, 2, 0, 0, 4, 0, 0, 2, 0, 1,},
713 {1, 6, 0, 0, 5, 1, 0, 1, 1, 0, 0, 1,},
714 {1, 1, 1, 0, 0, 3, 5, 3, 0, 0, 1, 1,},
715 {1, 1, 0, 0, 1, 1, 0, 1, 5, 0, 0, 6,},
716 {1, 1, 0, 2, 0, 0, 4, 0, 0, 0, 7, 1,},
717 {1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1,},
718 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
720 /* Level 15 */
721 {{0, 0, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
722 {0, 0, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
723 {0, 3, 4, 6, 0, 6, 0, 6, 0, 6, 0, 2,},
724 {0, 4, 0, 6, 0, 6, 4, 6, 0, 6, 0, 1,},
725 {0, 3, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
726 {7, 0, 0, 6, 4, 6, 0, 6, 0, 6, 0, 1,},
727 {0, 0, 4, 6, 0, 6, 0, 6, 4, 6, 0, 1,},
728 {0, 0, 4, 6, 0, 6, 0, 6, 0, 6, 0, 1,}}
731 /***********************************************************************
732 * pegbox_draw_board() draws the game's current level.
733 ************************************************************************/
734 static void pegbox_draw_board(struct game_context* pb)
736 unsigned int r, c, type;
737 pb->num_left = 0;
738 char str[5];
740 rb->lcd_clear_display();
741 #ifdef WIDE_LAYOUT
742 rb->lcd_bitmap(pegbox_header,LCD_WIDTH-HEADER_WIDTH,0,
743 HEADER_WIDTH,LCD_HEIGHT);
744 #else
745 rb->lcd_bitmap(pegbox_header,(LCD_WIDTH-HEADER_WIDTH)/2,0,
746 HEADER_WIDTH, HEADER_HEIGHT);
747 #endif /* WIDE_LAYOUT */
749 #if ((BOARD_HEIGHT + HEADER_HEIGHT + 4) <= LCD_HEIGHT)
750 rb->lcd_drawrect(BOARD_X-2,BOARD_Y-2,BOARD_WIDTH+4,BOARD_HEIGHT+4);
751 #endif /* enough space for a frame? */
753 #ifdef HAVE_LCD_COLOR
754 rb->lcd_set_foreground(LCD_WHITE);
755 rb->lcd_fillrect(BOARD_X-1,BOARD_Y-1,BOARD_WIDTH+2,BOARD_HEIGHT+2);
756 rb->lcd_set_foreground(LCD_BLACK);
757 rb->lcd_set_background(TEXT_BG);
758 #endif
760 for (r=0 ; r < ROWS ; r++) {
761 for (c = 0 ; c < COLS ; c++) {
763 type = pb->playboard[r][c];
765 if(type != SPACE) {
766 rb->lcd_bitmap_part(pegbox_pieces, 0, (type-1)*PIECE_HEIGHT,
767 STRIDE( SCREEN_MAIN,
768 BMPWIDTH_pegbox_pieces,BMPHEIGHT_pegbox_pieces),
769 c * PIECE_WIDTH + BOARD_X,
770 r * PIECE_HEIGHT + BOARD_Y, PIECE_WIDTH,
771 PIECE_HEIGHT);
774 if(pb->playboard[r][c] == PLAYER) {
775 pb->player_row=r;
776 pb->player_col=c;
778 else if (type != WALL && type != SPACE && type != HOLE)
779 pb->num_left++;
783 #ifdef WIDE_LAYOUT
784 rb->snprintf(str, 3, "%d", pb->level);
785 rb->lcd_putsxy(TEXT_X, LEVEL_TEXT_Y, str);
786 rb->snprintf(str, 3, "%d", pb->num_left);
787 rb->lcd_putsxy(TEXT_X, PEGS_TEXT_Y, str);
788 #else
789 rb->snprintf(str, 3, "%d", pb->level);
790 rb->lcd_putsxy(LEVEL_TEXT_X, TEXT_Y, str);
791 rb->snprintf(str, 3, "%d", pb->num_left);
792 rb->lcd_putsxy(PEGS_TEXT_X, TEXT_Y, str);
793 #endif /*WIDE_LAYOUT*/
795 #ifdef HAVE_LCD_COLOR
796 rb->lcd_set_background(BG_COLOR);
797 rb->lcd_set_foreground(LCD_WHITE);
798 #endif
799 /* print out the screen */
800 rb->lcd_update();
803 /*****************************************************************************
804 * pegbox_load_level() loads the player's current level from the array and sets the
805 * player's position.
806 ******************************************************************************/
807 static void pegbox_load_level(struct game_context* pb)
809 int r, c;
811 for(r = 0; r < ROWS; r++)
812 for(c = 0; c < COLS; c++)
813 pb->playboard[r][c] = levels[pb->level-1][r][c];
816 /*****************************************************************************
817 * pegbox_new_piece() creates a new piece at a specified location. The player
818 * navigates through the pieces and selects one.
819 ******************************************************************************/
820 static void pegbox_new_piece(struct game_context* pb, unsigned int x_loc,
821 unsigned int y_loc)
823 int button;
824 bool exit = false;
826 pb->playboard[x_loc][y_loc] = TRIANGLE;
828 while (!exit) {
829 pegbox_draw_board(pb);
830 button = rb->button_get(true);
831 #ifdef HAVE_TOUCHSCREEN
832 if(button & BUTTON_TOUCHSCREEN)
834 pegbox_raster_btn.two_d_from.y = x_loc;
835 pegbox_raster_btn.two_d_from.x = y_loc;
837 struct ts_raster_button_result ret =
838 touchscreen_raster_map_button(&pegbox_raster_btn,
839 rb->button_get_data() >> 16,
840 rb->button_get_data() & 0xffff,
841 button);
842 if(ret.action == TS_ACTION_TWO_D_MOVEMENT)
844 if(ret.to.x > ret.from.x)
845 button = PEGBOX_UP;
846 else if(ret.to.x < ret.from.x)
847 button = PEGBOX_DOWN;
848 else if(ret.to.y > ret.from.y)
849 button = PEGBOX_LEFT;
850 else if(ret.to.y < ret.from.y)
851 button = PEGBOX_RIGHT;
853 else if(ret.action == TS_ACTION_CLICK
854 && (unsigned)ret.to.x == y_loc
855 && (unsigned)ret.to.y == x_loc)
856 button = PEGBOX_SELECT;
858 #endif
859 switch(button){
860 case PEGBOX_LEFT:
861 case (PEGBOX_LEFT|BUTTON_REPEAT):
862 case PEGBOX_DOWN:
863 case (PEGBOX_DOWN|BUTTON_REPEAT):
864 if (pb->playboard[x_loc][y_loc] < 5)
865 pb->playboard[x_loc][y_loc]++;
866 else
867 pb->playboard[x_loc][y_loc] = TRIANGLE;
868 break;
869 case PEGBOX_RIGHT:
870 case (PEGBOX_RIGHT|BUTTON_REPEAT):
871 case PEGBOX_UP:
872 case (PEGBOX_UP|BUTTON_REPEAT):
873 if (pb->playboard[x_loc][y_loc] > 2)
874 pb->playboard[x_loc][y_loc]--;
875 else
876 pb->playboard[x_loc][y_loc] = CIRCLE;
877 break;
878 case PEGBOX_SELECT:
879 exit=true;
880 break;
885 /*****************************************************************************
886 * pegbox_move_player() moves the player and pieces and updates the board accordingly.
887 ******************************************************************************/
888 static void pegbox_move_player(struct game_context* pb, signed int x_dir,
889 signed int y_dir)
891 unsigned int type1, type2;
892 signed int r1,c1,r2,c2;
894 r1 = pb->player_row+y_dir;
895 c1 = pb->player_col+x_dir;
896 r2 = pb->player_row+y_dir*2;
897 c2 = pb->player_col+x_dir*2;
899 type1 = pb->playboard[r1][c1];
900 type2 = pb->playboard[r2][c2];
902 if (r1 == ROWS || c1 == COLS || r1 < 0 || c1 < 0 || type1 == WALL)
903 return;
904 else if(type1 != SPACE) {
905 if (r2 == ROWS || c2 == COLS || r2 < 0 || c2 < 0 || type2 == WALL)
906 return;
910 pb->playboard[pb->player_row][pb->player_col] = SPACE;
911 pb->player_row += y_dir;
912 pb->player_col += x_dir;
914 if (type1 == HOLE) {
915 pegbox_draw_board(pb);
916 rb->splash(HZ*2, "You fell down a hole!");
917 pegbox_load_level(pb);
919 else if (type1 == SPACE)
920 pb->playboard[r1][c1] = PLAYER;
921 else {
922 pb->playboard[r1][c1] = PLAYER;
923 if(type1 == type2) {
924 if (type1 == TRIANGLE)
925 pb->playboard[r2][c2] = WALL;
926 else if (type1 == CROSS) {
927 pb->playboard[r1][c1] = SPACE;
928 pegbox_new_piece(pb, r2, c2);
929 pb->playboard[r1][c1] = PLAYER;
931 else
932 pb->playboard[r2][c2] = SPACE;
934 else if (type2 == SPACE)
935 pb->playboard[r2][c2] = type1;
936 else if (type2 == HOLE) {
937 if (type1 == SQUARE)
938 pb->playboard[r2][c2] = SPACE;
940 else {
941 rb->splash(HZ*2, "Illegal Move!");
942 pegbox_load_level(pb);
946 pegbox_draw_board(pb);
949 /***********************************************************************
950 * pegbox_help() display help text
951 ************************************************************************/
952 static bool pegbox_help(void)
954 int button;
955 #define WORDS (sizeof help_text / sizeof (char*))
956 static char* help_text[] = {
957 "Pegbox", "", "Aim", "",
958 "To", "beat", "each", "level,", "you", "must", "destroy", "all", "of",
959 "the", "pegs.", "If", "two", "like", "pegs", "are", "pushed", "into",
960 "each", "other,", "they", "disappear", "except", "for", "triangles",
961 "which", "form", "a", "solid", "block", "and", "crosses", "which",
962 "allow", "you", "to", "choose", "a", "replacement", "block.", "", "",
963 "Controls", "",
964 RESTART_TEXT, "to", "restart", "level", "",
965 LVL_UP_TEXT, "to", "go", "up", "a", "level", "",
966 LVL_DOWN_TEXT, "to", "go", "down", "a", "level", "",
967 SELECT_TEXT, "to", "choose", "peg", "",
968 QUIT_TEXT, "to", "quit"
970 static struct style_text formation[]={
971 { 0, TEXT_CENTER|TEXT_UNDERLINE },
972 { 2, C_RED },
973 { 46, C_RED },
974 { -1, 0 }
977 rb->lcd_setfont(FONT_UI);
979 if (display_text(WORDS, help_text, formation, NULL))
980 return true;
981 do {
982 button = rb->button_get(true);
983 if ( rb->default_event_handler( button ) == SYS_USB_CONNECTED )
984 return true;
985 } while( ( button == BUTTON_NONE )
986 || ( button & (BUTTON_REL|BUTTON_REPEAT) ) );
987 rb->lcd_setfont(FONT_SYSFIXED);
988 return false;
991 /***********************************************************************
992 * pegbox_menu() is the game menu
993 ************************************************************************/
994 static bool _ingame;
995 static int pegbox_menu_cb(int action, const struct menu_item_ex *this_item)
997 int i = (intptr_t)this_item;
998 if( action == ACTION_REQUEST_MENUITEM )
1000 if((!_ingame && (i==0 || i==1)) || ( _ingame && i==2 ))
1001 return ACTION_EXIT_MENUITEM;
1003 return action;
1006 static unsigned int pegbox_menu(struct game_context* pb, bool ingame)
1008 int selected = 0;
1009 int last_level = pb->level;
1011 MENUITEM_STRINGLIST (main_menu, "Pegbox Menu", pegbox_menu_cb,
1012 "Resume Game", "Restart Level", "Start Game",
1013 "Select Level", "Help",
1014 "Playback Control", "Quit");
1015 _ingame = ingame;
1016 rb->button_clear_queue();
1018 while (true) {
1019 switch (rb->do_menu(&main_menu, &selected, NULL, false)) {
1020 case 0:
1021 pb->level = last_level;
1022 pegbox_draw_board(pb);
1023 return 0;
1024 case 1:
1025 case 2:
1026 pegbox_load_level(pb);
1027 pegbox_draw_board(pb);
1028 return 0;
1029 case 3:
1030 if(rb->set_int("Select Level", "", UNIT_INT, &pb->level,
1031 NULL, 1, 1, pb->highlevel, NULL))
1032 return 1;
1033 break;
1034 case 4:
1035 if (pegbox_help())
1036 return 1;
1037 break;
1038 case 5:
1039 if (playback_control(NULL))
1040 return 1;
1041 break;
1042 case 6:
1043 return 1;
1044 case MENU_ATTACHED_USB:
1045 return 1;
1046 default:
1047 break;
1052 /***********************************************************************
1053 * pegbox_main() is the main game subroutine
1054 ************************************************************************/
1055 static int pegbox_main(struct game_context* pb)
1057 int button;
1059 if (pegbox_menu(pb, false)==1) {
1060 return 1;
1063 while (true) {
1064 button = rb->button_get(true);
1065 #ifdef HAVE_TOUCHSCREEN
1066 if(button & BUTTON_TOUCHSCREEN)
1068 pegbox_raster_btn.two_d_from.y = pb->player_row;
1069 pegbox_raster_btn.two_d_from.x = pb->player_col;
1071 struct ts_raster_button_result ret =
1072 touchscreen_raster_map_button(&pegbox_raster_btn,
1073 rb->button_get_data() >> 16,
1074 rb->button_get_data() & 0xffff,
1075 button);
1076 if(ret.action == TS_ACTION_TWO_D_MOVEMENT)
1077 pegbox_move_player(pb, ret.to.x - ret.from.x, ret.to.y - ret.from.y);
1079 #endif
1080 switch(button){
1081 case PEGBOX_LEFT: /* move cursor left */
1082 case (PEGBOX_LEFT|BUTTON_REPEAT):
1083 pegbox_move_player(pb, -1, 0);
1084 break;
1086 case PEGBOX_RIGHT: /* move cursor right */
1087 case (PEGBOX_RIGHT|BUTTON_REPEAT):
1088 pegbox_move_player(pb, 1, 0);
1089 break;
1091 case PEGBOX_DOWN: /* move cursor down */
1092 case (PEGBOX_DOWN|BUTTON_REPEAT):
1093 pegbox_move_player(pb, 0, 1);
1094 break;
1096 case PEGBOX_UP: /* move cursor up */
1097 case (PEGBOX_UP|BUTTON_REPEAT):
1098 pegbox_move_player(pb, 0, -1);
1099 break;
1101 case PEGBOX_QUIT:
1102 if (pegbox_menu(pb, true)==1) {
1103 return 1;
1105 break;
1107 #ifdef PEGBOX_RESTART
1108 case PEGBOX_RESTART:
1109 pegbox_load_level(pb);
1110 pegbox_draw_board(pb);
1111 break;
1112 #endif
1114 #ifdef PEGBOX_LVL_UP
1115 case (PEGBOX_LVL_UP|BUTTON_REPEAT):
1116 case PEGBOX_LVL_UP:
1117 if (pb->level >= pb->highlevel) {
1118 pb->level = 1;
1119 } else {
1120 pb->level++;
1122 pegbox_load_level(pb);
1123 pegbox_draw_board(pb);
1124 break;
1125 #endif
1127 #ifdef PEGBOX_LVL_DOWN
1128 case (PEGBOX_LVL_DOWN|BUTTON_REPEAT):
1129 case PEGBOX_LVL_DOWN:
1130 if(pb->level <= 1) {
1131 pb->level = pb->highlevel;
1132 } else {
1133 pb->level--;
1135 pegbox_load_level(pb);
1136 pegbox_draw_board(pb);
1137 break;
1138 #endif
1141 if (pb->num_left == 0) {
1142 rb->splash(HZ*2, "Nice Pegging!");
1143 if (pb->level == NUM_LEVELS) {
1144 pegbox_draw_board(pb);
1145 rb->splash(HZ*2, "Congratulations!");
1146 rb->splash(HZ*2, "You have finished the game!");
1147 if (pegbox_menu(pb,false)==1) {
1148 return 1;
1151 else {
1152 pb->level++;
1153 pegbox_load_level(pb);
1154 pegbox_draw_board(pb);
1157 if(pb->level > pb->highlevel)
1158 pb->highlevel = pb->level;
1162 return PLUGIN_OK;
1165 /*****************************************************************************
1166 * plugin entry point.
1167 ******************************************************************************/
1168 enum plugin_status plugin_start(const void* parameter)
1170 (void)parameter;
1171 #ifdef HAVE_LCD_BITMAP
1172 rb->lcd_setfont(FONT_SYSFIXED);
1173 #if LCD_DEPTH > 1
1174 rb->lcd_set_backdrop(NULL);
1175 #endif
1176 #ifdef HAVE_LCD_COLOR
1177 rb->lcd_set_foreground(LCD_WHITE);
1178 rb->lcd_set_background(BG_COLOR);
1179 #endif
1180 rb->lcd_clear_display();
1182 struct game_context pb;
1183 pb.level=1;
1184 pb.highlevel=1;
1185 struct configdata config[] = {
1186 {TYPE_INT, 1, NUM_LEVELS, { .int_p = &(pb.level) }, "level", NULL},
1187 {TYPE_INT, 1, NUM_LEVELS, { .int_p = &(pb.highlevel) }, "highlevel", NULL},
1189 configfile_load(CONFIG_FILE_NAME,config,2,0);
1190 pegbox_main(&pb);
1191 configfile_save(CONFIG_FILE_NAME,config,2,0);
1192 rb->lcd_setfont(FONT_UI);
1193 #endif /* HAVE_LCD_BITMAP */
1195 return PLUGIN_OK;