Fix the pitch detector plugin for iaudioM3
[kugel-rb.git] / apps / plugins / pegbox.c
blob2766bb613c10b099a6bb8f415c09278fdef71a27
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 == COWOND2_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 == ONDAVX747_PAD || \
360 CONFIG_KEYPAD == ONDAVX777_PAD || \
361 CONFIG_KEYPAD == MROBE500_PAD
362 #define PEGBOX_QUIT BUTTON_POWER
364 #define QUIT_TEXT "POWER"
366 #elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
367 #define PEGBOX_SAVE (BUTTON_REC|BUTTON_FFWD)
368 #define PEGBOX_QUIT (BUTTON_REC|BUTTON_PLAY)
369 #define PEGBOX_RESTART (BUTTON_REC|BUTTON_REW)
370 #define PEGBOX_LVL_UP BUTTON_FFWD
371 #define PEGBOX_LVL_DOWN BUTTON_REW
372 #define PEGBOX_UP BUTTON_UP
373 #define PEGBOX_DOWN BUTTON_DOWN
374 #define PEGBOX_RIGHT BUTTON_RIGHT
375 #define PEGBOX_LEFT BUTTON_LEFT
376 #define PEGBOX_SELECT BUTTON_PLAY
378 #define SAVE_TEXT "REC + FFWD"
379 #define QUIT_TEXT "REC + PLAY"
380 #define RESTART_TEXT "REC + REW"
381 #define LVL_UP_TEXT "FFWD"
382 #define LVL_DOWN_TEXT "REW"
383 #define SELECT_TEXT "PLAY"
385 #else
386 #error Unsupported keymap!
387 #endif
389 #ifdef HAVE_TOUCHSCREEN
390 #ifndef PEGBOX_QUIT
391 #define PEGBOX_QUIT BUTTON_TOPLEFT
392 #endif
393 #ifndef PEGBOX_SELECT
394 #define PEGBOX_SELECT BUTTON_CENTER
395 #endif
396 #ifndef PEGBOX_RESTART
397 #define PEGBOX_RESTART BUTTON_TOPRIGHT
398 #endif
399 #ifndef PEGBOX_LVL_UP
400 #define PEGBOX_LVL_UP BUTTON_BOTTOMLEFT
401 #endif
402 #ifndef PEGBOX_LVL_DOWN
403 #define PEGBOX_LVL_DOWN BUTTON_BOTTOMRIGHT
404 #endif
405 #ifndef PEGBOX_UP
406 #define PEGBOX_UP BUTTON_TOPMIDDLE
407 #endif
408 #ifndef PEGBOX_DOWN
409 #define PEGBOX_DOWN BUTTON_BOTTOMMIDDLE
410 #endif
411 #ifndef PEGBOX_RIGHT
412 #define PEGBOX_RIGHT BUTTON_MIDRIGHT
413 #endif
414 #ifndef PEGBOX_LEFT
415 #define PEGBOX_LEFT BUTTON_MIDLEFT
416 #endif
417 #ifndef SELECT_TEXT
418 #define SELECT_TEXT "CENTER"
419 #endif
420 #ifndef QUIT_TEXT
421 #define QUIT_TEXT "TOPLEFT"
422 #endif
423 #ifndef RESTART_TEXT
424 #define RESTART_TEXT "TOPRIGHT"
425 #endif
426 #ifndef LVL_UP_TEXT
427 #define LVL_UP_TEXT "BOTTOMLEFT"
428 #endif
429 #ifndef LVL_DOWN_TEXT
430 #define LVL_DOWN_TEXT "BOTTOMRIGHT"
431 #endif
432 #endif
435 /* get several sizes from the bitmaps */
436 #ifdef BMPWIDTH_pegbox_pieces
437 #define PIECE_WIDTH BMPWIDTH_pegbox_pieces
438 #define PIECE_HEIGHT (BMPHEIGHT_pegbox_pieces/7)
439 #else
440 /* dummy numbers to avoid #error in dependency generation */
441 #define PIECE_WIDTH 50
442 #define PIECE_HEIGHT 10
443 #endif
445 #define BOARD_WIDTH (12*PIECE_WIDTH)
446 #define BOARD_HEIGHT (8*PIECE_HEIGHT)
449 /* define a wide layout where the statistics are alongside the board, not above
450 * base calculation on the piece bitmaps for the 8x12 board */
451 #if (LCD_WIDTH - BOARD_WIDTH) > (LCD_HEIGHT - BOARD_HEIGHT)
452 #define WIDE_LAYOUT
453 #endif
456 #define HEADER_WIDTH BMPWIDTH_pegbox_header
457 #define HEADER_HEIGHT BMPHEIGHT_pegbox_header
460 #if defined WIDE_LAYOUT
462 #if ((BOARD_WIDTH + HEADER_WIDTH + 4) <= LCD_WIDTH)
463 #define BOARD_X 2
464 #else
465 #define BOARD_X 1
466 #endif
467 #define BOARD_Y (LCD_HEIGHT-BOARD_HEIGHT)/2
469 #if (LCD_WIDTH >= 132) && (LCD_HEIGHT >= 80)
470 #define TEXT_X 116
471 #define LEVEL_TEXT_Y 14
472 #define PEGS_TEXT_Y 58
473 #elif (LCD_WIDTH >= 128) && (LCD_HEIGHT >= 64)
474 #define TEXT_X 112
475 #define LEVEL_TEXT_Y 27
476 #define PEGS_TEXT_Y 50
477 #else
478 #error "Unsupported screen size"
479 #endif
481 #else /* "normal" layout */
483 #define BOARD_X (LCD_WIDTH-BOARD_WIDTH)/2
484 #if ((BOARD_HEIGHT + HEADER_HEIGHT + 4) <= LCD_HEIGHT)
485 #define BOARD_Y HEADER_HEIGHT+2
486 #else
487 #define BOARD_Y HEADER_HEIGHT
488 #endif
490 #if LCD_WIDTH >= 640
491 #define LEVEL_TEXT_X 118
492 #define PEGS_TEXT_X 552
493 #define TEXT_Y 56
494 #elif LCD_WIDTH >= 320
495 #define LEVEL_TEXT_X 59
496 #define PEGS_TEXT_X 276
497 #define TEXT_Y 28
498 #elif LCD_WIDTH >= 240
499 #define LEVEL_TEXT_X 59
500 #define PEGS_TEXT_X 196
501 #define TEXT_Y 28
502 #elif LCD_WIDTH >= 220
503 #define LEVEL_TEXT_X 49
504 #define PEGS_TEXT_X 186
505 #define TEXT_Y 28
506 #elif LCD_WIDTH >= 176
507 #define LEVEL_TEXT_X 38
508 #define PEGS_TEXT_X 155
509 #define TEXT_Y 17
510 #elif LCD_WIDTH >= 160
511 #define LEVEL_TEXT_X 37
512 #define PEGS_TEXT_X 140
513 #define TEXT_Y 13
514 #elif LCD_WIDTH >= 138
515 #define LEVEL_TEXT_X 28
516 #define PEGS_TEXT_X 119
517 #define TEXT_Y 15
518 #elif LCD_WIDTH >= 128
519 #if HEADER_HEIGHT > 16
520 #define LEVEL_TEXT_X 26
521 #define PEGS_TEXT_X 107
522 #define TEXT_Y 31
523 #else
524 #define LEVEL_TEXT_X 15
525 #define PEGS_TEXT_X 100
526 #define TEXT_Y 5
527 #endif /* HEADER_HEIGHT */
528 #elif LCD_WIDTH >= 112
529 #define LEVEL_TEXT_X 25
530 #define PEGS_TEXT_X 90
531 #define TEXT_Y 0
532 #endif /* LCD_WIDTH */
534 #endif /* WIDE_LAYOUT */
537 #ifdef HAVE_LCD_COLOR
538 #define BG_COLOR LCD_BLACK
539 #define TEXT_BG LCD_RGBPACK(189,189,189)
540 #endif
543 #ifdef HAVE_TOUCHSCREEN
544 #include "lib/pluginlib_touchscreen.h"
545 static struct ts_raster pegbox_raster =
546 { BOARD_X, BOARD_Y, COLS*PIECE_WIDTH, ROWS*PIECE_HEIGHT,
547 PIECE_WIDTH, PIECE_HEIGHT };
548 static struct ts_raster_button_mapping pegbox_raster_btn =
549 { &pegbox_raster, false, false, true, false, true, {0, 0}, 0, 0, 0 };
550 #endif
553 struct game_context {
554 unsigned int level;
555 unsigned int highlevel;
556 signed int player_row;
557 signed int player_col;
558 unsigned int num_left;
559 unsigned int playboard[ROWS][COLS];
562 char levels[NUM_LEVELS][ROWS][COLS] = {
563 /* Level 1 */
564 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
565 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
566 {1, 0, 0, 0, 7, 0, 0, 5, 0, 0, 0, 1,},
567 {1, 0, 0, 0, 0, 3, 3, 2, 0, 0, 0, 1,},
568 {1, 0, 0, 0, 4, 6, 0, 5, 0, 0, 0, 1,},
569 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
570 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
571 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
573 /* Level 2 */
574 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
575 {1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 1,},
576 {1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1,},
577 {1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1,},
578 {7, 0, 0, 0, 2, 2, 5, 5, 0, 0, 0, 1,},
579 {1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1,},
580 {1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1,},
581 {1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 1,}},
583 /* Level 3 */
584 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
585 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
586 {1, 0, 0, 0, 0, 0, 2, 0, 7, 0, 0, 0,},
587 {1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 2, 1,},
588 {1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1,},
589 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1,},
590 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
591 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
593 /* Level 4 */
594 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
595 {6, 0, 4, 0, 2, 0, 2, 0, 0, 0, 0, 1,},
596 {6, 0, 3, 0, 5, 0, 2, 0, 0, 0, 0, 1,},
597 {6, 0, 5, 0, 4, 7, 2, 0, 0, 0, 0, 1,},
598 {6, 0, 2, 0, 4, 0, 2, 0, 3, 0, 0, 1,},
599 {6, 0, 4, 0, 5, 0, 2, 0, 0, 0, 0, 1,},
600 {6, 0, 5, 0, 4, 0, 2, 0, 0, 0, 0, 1,},
601 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
603 /* Level 5 */
604 {{0, 6, 6, 0, 4, 6, 0, 0, 6, 0, 0, 0,},
605 {0, 6, 6, 0, 4, 4, 0, 0, 6, 0, 0, 2,},
606 {2, 6, 6, 0, 6, 6, 6, 0, 1, 2, 2, 2,},
607 {0, 6, 6, 0, 6, 4, 6, 0, 1, 2, 0, 2,},
608 {0, 6, 6, 0, 6, 7, 6, 5, 6, 0, 0, 0,},
609 {2, 6, 6, 0, 6, 6, 6, 0, 6, 0, 0, 0,},
610 {0, 6, 6, 0, 4, 0, 0, 0, 6, 0, 0, 0,},
611 {0, 6, 6, 0, 0, 5, 0, 0, 6, 5, 5, 0,}},
613 /* Level 6 */
614 {{7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
615 {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,},
616 {2, 0, 0, 2, 0, 0, 0, 2, 2, 0, 0, 0,},
617 {0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 0,},
618 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
619 {0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1,},
620 {0, 3, 0, 0, 0, 0, 0, 0, 5, 4, 6, 0,},
621 {0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1,}},
623 /* Level 7 */
624 {{1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1,},
625 {1, 1, 1, 6, 0, 0, 4, 6, 0, 1, 1, 1,},
626 {1, 1, 1, 1, 0, 1, 5, 1, 0, 1, 1, 1,},
627 {1, 1, 1, 2, 3, 3, 7, 4, 2, 6, 1, 1,},
628 {1, 1, 1, 1, 0, 1, 2, 1, 0, 0, 0, 1,},
629 {1, 1, 1, 1, 0, 0, 5, 0, 0, 1, 0, 1,},
630 {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1,},
631 {1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,}},
633 /* Level 8 */
634 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
635 {0, 0, 3, 3, 3, 3, 3, 4, 3, 3, 0, 0,},
636 {0, 0, 3, 3, 3, 2, 3, 3, 5, 3, 0, 0,},
637 {7, 0, 3, 3, 3, 2, 3, 3, 4, 3, 0, 0,},
638 {0, 0, 3, 3, 4, 5, 3, 3, 3, 3, 0, 0,},
639 {0, 0, 3, 3, 5, 2, 3, 3, 3, 3, 0, 0,},
640 {0, 0, 3, 3, 2, 4, 3, 3, 3, 3, 0, 0,},
641 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
643 /* Level 9 */
644 {{0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,},
645 {0, 3, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,},
646 {0, 0, 0, 0, 2, 4, 4, 3, 0, 1, 1, 0,},
647 {0, 1, 0, 0, 2, 1, 0, 0, 0, 1, 1, 1,},
648 {0, 0, 0, 2, 2, 7, 1, 0, 0, 0, 0, 2,},
649 {0, 0, 0, 0, 2, 1, 0, 0, 1, 1, 1, 1,},
650 {0, 3, 1, 0, 2, 5, 5, 0, 0, 0, 3, 0,},
651 {0, 0, 0, 0, 4, 1, 0, 0, 0, 0, 0, 0,}},
653 /* Level 10 */
654 {{1, 1, 1, 1, 2, 1, 1, 1, 0, 0, 0, 0,},
655 {1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 7,},
656 {0, 0, 4, 0, 6, 6, 6, 0, 0, 0, 3, 0,},
657 {0, 3, 3, 0, 6, 6, 6, 0, 4, 3, 4, 0,},
658 {0, 3, 3, 0, 6, 6, 6, 0, 4, 3, 4, 0,},
659 {0, 0, 0, 0, 6, 6, 6, 0, 3, 0, 0, 0,},
660 {1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0,},
661 {1, 1, 1, 1, 1, 2, 1, 1, 0, 0, 0, 0,}},
663 /* Level 11 */
664 {{1, 7, 1, 0, 1, 1, 6, 0, 0, 1, 1, 0,},
665 {1, 0, 0, 0, 5, 4, 6, 6, 0, 2, 2, 0,},
666 {1, 2, 1, 2, 0, 1, 6, 0, 0, 2, 2, 0,},
667 {1, 0, 0, 2, 0, 1, 0, 0, 0, 3, 3, 0,},
668 {1, 2, 1, 0, 0, 1, 0, 1, 0, 3, 3, 0,},
669 {0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0,},
670 {0, 3, 4, 3, 0, 1, 0, 1, 0, 0, 0, 0,},
671 {0, 0, 0, 0, 2, 2, 2, 1, 1, 1, 1, 1,}},
673 /* Level 12 */
674 {{7, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,},
675 {1, 2, 1, 2, 1, 2, 1, 1, 0, 0, 0, 1,},
676 {0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1,},
677 {1, 2, 1, 2, 1, 2, 1, 0, 0, 0, 0, 1,},
678 {0, 0, 0, 0, 0, 0, 1, 1, 5, 5, 6, 1,},
679 {1, 2, 1, 2, 1, 2, 1, 1, 0, 2, 2, 1,},
680 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1,},
681 {1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1,}},
683 /* Level 13 */
684 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
685 {0, 0, 4, 0, 2, 0, 5, 0, 4, 0, 0, 6,},
686 {0, 0, 2, 0, 5, 0, 2, 0, 4, 0, 0, 6,},
687 {7, 0, 3, 0, 4, 0, 5, 0, 4, 0, 0, 6,},
688 {0, 0, 5, 0, 4, 0, 2, 0, 4, 0, 0, 6,},
689 {0, 0, 4, 0, 2, 0, 5, 0, 4, 0, 0, 6,},
690 {0, 0, 3, 0, 3, 0, 2, 0, 4, 0, 0, 6,},
691 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
693 /* Level 14 */
694 {{1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1,},
695 {1, 1, 0, 2, 0, 0, 4, 0, 0, 2, 0, 1,},
696 {1, 6, 0, 0, 5, 1, 0, 1, 1, 0, 0, 1,},
697 {1, 1, 1, 0, 0, 3, 5, 3, 0, 0, 1, 1,},
698 {1, 1, 0, 0, 1, 1, 0, 1, 5, 0, 0, 6,},
699 {1, 1, 0, 2, 0, 0, 4, 0, 0, 0, 7, 1,},
700 {1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1,},
701 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
703 /* Level 15 */
704 {{0, 0, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
705 {0, 0, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
706 {0, 3, 4, 6, 0, 6, 0, 6, 0, 6, 0, 2,},
707 {0, 4, 0, 6, 0, 6, 4, 6, 0, 6, 0, 1,},
708 {0, 3, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
709 {7, 0, 0, 6, 4, 6, 0, 6, 0, 6, 0, 1,},
710 {0, 0, 4, 6, 0, 6, 0, 6, 4, 6, 0, 1,},
711 {0, 0, 4, 6, 0, 6, 0, 6, 0, 6, 0, 1,}}
714 /***********************************************************************
715 * pegbox_draw_board() draws the game's current level.
716 ************************************************************************/
717 static void pegbox_draw_board(struct game_context* pb)
719 unsigned int r, c, type;
720 pb->num_left = 0;
721 char str[5];
723 rb->lcd_clear_display();
724 #ifdef WIDE_LAYOUT
725 rb->lcd_bitmap(pegbox_header,LCD_WIDTH-HEADER_WIDTH,0,
726 HEADER_WIDTH,LCD_HEIGHT);
727 #else
728 rb->lcd_bitmap(pegbox_header,(LCD_WIDTH-HEADER_WIDTH)/2,0,
729 HEADER_WIDTH, HEADER_HEIGHT);
730 #endif /* WIDE_LAYOUT */
732 #if ((BOARD_HEIGHT + HEADER_HEIGHT + 4) <= LCD_HEIGHT)
733 rb->lcd_drawrect(BOARD_X-2,BOARD_Y-2,BOARD_WIDTH+4,BOARD_HEIGHT+4);
734 #endif /* enough space for a frame? */
736 #ifdef HAVE_LCD_COLOR
737 rb->lcd_set_foreground(LCD_WHITE);
738 rb->lcd_fillrect(BOARD_X-1,BOARD_Y-1,BOARD_WIDTH+2,BOARD_HEIGHT+2);
739 rb->lcd_set_foreground(LCD_BLACK);
740 rb->lcd_set_background(TEXT_BG);
741 #endif
743 for (r=0 ; r < ROWS ; r++) {
744 for (c = 0 ; c < COLS ; c++) {
746 type = pb->playboard[r][c];
748 if(type != SPACE) {
749 rb->lcd_bitmap_part(pegbox_pieces, 0, (type-1)*PIECE_HEIGHT,
750 STRIDE( SCREEN_MAIN,
751 BMPWIDTH_pegbox_pieces,BMPHEIGHT_pegbox_pieces),
752 c * PIECE_WIDTH + BOARD_X,
753 r * PIECE_HEIGHT + BOARD_Y, PIECE_WIDTH,
754 PIECE_HEIGHT);
757 if(pb->playboard[r][c] == PLAYER) {
758 pb->player_row=r;
759 pb->player_col=c;
761 else if (type != WALL && type != SPACE && type != HOLE)
762 pb->num_left++;
766 #ifdef WIDE_LAYOUT
767 rb->snprintf(str, 3, "%d", pb->level);
768 rb->lcd_putsxy(TEXT_X, LEVEL_TEXT_Y, str);
769 rb->snprintf(str, 3, "%d", pb->num_left);
770 rb->lcd_putsxy(TEXT_X, PEGS_TEXT_Y, str);
771 #else
772 rb->snprintf(str, 3, "%d", pb->level);
773 rb->lcd_putsxy(LEVEL_TEXT_X, TEXT_Y, str);
774 rb->snprintf(str, 3, "%d", pb->num_left);
775 rb->lcd_putsxy(PEGS_TEXT_X, TEXT_Y, str);
776 #endif /*WIDE_LAYOUT*/
778 #ifdef HAVE_LCD_COLOR
779 rb->lcd_set_background(BG_COLOR);
780 rb->lcd_set_foreground(LCD_WHITE);
781 #endif
782 /* print out the screen */
783 rb->lcd_update();
786 /*****************************************************************************
787 * pegbox_load_level() loads the player's current level from the array and sets the
788 * player's position.
789 ******************************************************************************/
790 static void pegbox_load_level(struct game_context* pb)
792 int r, c;
794 for(r = 0; r < ROWS; r++)
795 for(c = 0; c < COLS; c++)
796 pb->playboard[r][c] = levels[pb->level-1][r][c];
799 /*****************************************************************************
800 * pegbox_new_piece() creates a new piece at a specified location. The player
801 * navigates through the pieces and selects one.
802 ******************************************************************************/
803 static void pegbox_new_piece(struct game_context* pb, unsigned int x_loc,
804 unsigned int y_loc)
806 int button;
807 bool exit = false;
809 pb->playboard[x_loc][y_loc] = TRIANGLE;
811 while (!exit) {
812 pegbox_draw_board(pb);
813 button = rb->button_get(true);
814 #ifdef HAVE_TOUCHSCREEN
815 if(button & BUTTON_TOUCHSCREEN)
817 pegbox_raster_btn.two_d_from.y = x_loc;
818 pegbox_raster_btn.two_d_from.x = y_loc;
820 struct ts_raster_button_result ret =
821 touchscreen_raster_map_button(&pegbox_raster_btn,
822 rb->button_get_data() >> 16,
823 rb->button_get_data() & 0xffff,
824 button);
825 if(ret.action == TS_ACTION_TWO_D_MOVEMENT)
827 if(ret.to.x > ret.from.x)
828 button = PEGBOX_UP;
829 else if(ret.to.x < ret.from.x)
830 button = PEGBOX_DOWN;
831 else if(ret.to.y > ret.from.y)
832 button = PEGBOX_LEFT;
833 else if(ret.to.y < ret.from.y)
834 button = PEGBOX_RIGHT;
836 else if(ret.action == TS_ACTION_CLICK
837 && (unsigned)ret.to.x == y_loc
838 && (unsigned)ret.to.y == x_loc)
839 button = PEGBOX_SELECT;
841 #endif
842 switch(button){
843 case PEGBOX_LEFT:
844 case (PEGBOX_LEFT|BUTTON_REPEAT):
845 case PEGBOX_DOWN:
846 case (PEGBOX_DOWN|BUTTON_REPEAT):
847 if (pb->playboard[x_loc][y_loc] < 5)
848 pb->playboard[x_loc][y_loc]++;
849 else
850 pb->playboard[x_loc][y_loc] = TRIANGLE;
851 break;
852 case PEGBOX_RIGHT:
853 case (PEGBOX_RIGHT|BUTTON_REPEAT):
854 case PEGBOX_UP:
855 case (PEGBOX_UP|BUTTON_REPEAT):
856 if (pb->playboard[x_loc][y_loc] > 2)
857 pb->playboard[x_loc][y_loc]--;
858 else
859 pb->playboard[x_loc][y_loc] = CIRCLE;
860 break;
861 case PEGBOX_SELECT:
862 exit=true;
863 break;
868 /*****************************************************************************
869 * pegbox_move_player() moves the player and pieces and updates the board accordingly.
870 ******************************************************************************/
871 static void pegbox_move_player(struct game_context* pb, signed int x_dir,
872 signed int y_dir)
874 unsigned int type1, type2;
875 signed int r1,c1,r2,c2;
877 r1 = pb->player_row+y_dir;
878 c1 = pb->player_col+x_dir;
879 r2 = pb->player_row+y_dir*2;
880 c2 = pb->player_col+x_dir*2;
882 type1 = pb->playboard[r1][c1];
883 type2 = pb->playboard[r2][c2];
885 if (r1 == ROWS || c1 == COLS || r1 < 0 || c1 < 0 || type1 == WALL)
886 return;
887 else if(type1 != SPACE) {
888 if (r2 == ROWS || c2 == COLS || r2 < 0 || c2 < 0 || type2 == WALL)
889 return;
893 pb->playboard[pb->player_row][pb->player_col] = SPACE;
894 pb->player_row += y_dir;
895 pb->player_col += x_dir;
897 if (type1 == HOLE) {
898 pegbox_draw_board(pb);
899 rb->splash(HZ*2, "You fell down a hole!");
900 pegbox_load_level(pb);
902 else if (type1 == SPACE)
903 pb->playboard[r1][c1] = PLAYER;
904 else {
905 pb->playboard[r1][c1] = PLAYER;
906 if(type1 == type2) {
907 if (type1 == TRIANGLE)
908 pb->playboard[r2][c2] = WALL;
909 else if (type1 == CROSS) {
910 pb->playboard[r1][c1] = SPACE;
911 pegbox_new_piece(pb, r2, c2);
912 pb->playboard[r1][c1] = PLAYER;
914 else
915 pb->playboard[r2][c2] = SPACE;
917 else if (type2 == SPACE)
918 pb->playboard[r2][c2] = type1;
919 else if (type2 == HOLE) {
920 if (type1 == SQUARE)
921 pb->playboard[r2][c2] = SPACE;
923 else {
924 rb->splash(HZ*2, "Illegal Move!");
925 pegbox_load_level(pb);
929 pegbox_draw_board(pb);
932 /***********************************************************************
933 * pegbox_help() display help text
934 ************************************************************************/
935 static bool pegbox_help(void)
937 int button;
938 #define WORDS (sizeof help_text / sizeof (char*))
939 static char* help_text[] = {
940 "Pegbox", "", "Aim", "",
941 "To", "beat", "each", "level,", "you", "must", "destroy", "all", "of",
942 "the", "pegs.", "If", "two", "like", "pegs", "are", "pushed", "into",
943 "each", "other,", "they", "disappear", "except", "for", "triangles",
944 "which", "form", "a", "solid", "block", "and", "crosses", "which",
945 "allow", "you", "to", "choose", "a", "replacement", "block.", "", "",
946 "Controls", "",
947 RESTART_TEXT, "to", "restart", "level", "",
948 LVL_UP_TEXT, "to", "go", "up", "a", "level", "",
949 LVL_DOWN_TEXT, "to", "go", "down", "a", "level", "",
950 SELECT_TEXT, "to", "choose", "peg", "",
951 QUIT_TEXT, "to", "quit"
953 static struct style_text formation[]={
954 { 0, TEXT_CENTER|TEXT_UNDERLINE },
955 { 2, C_RED },
956 { 46, C_RED },
957 { -1, 0 }
960 rb->lcd_setfont(FONT_UI);
962 if (display_text(WORDS, help_text, formation, NULL))
963 return true;
964 do {
965 button = rb->button_get(true);
966 if ( rb->default_event_handler( button ) == SYS_USB_CONNECTED )
967 return true;
968 } while( ( button == BUTTON_NONE )
969 || ( button & (BUTTON_REL|BUTTON_REPEAT) ) );
970 rb->lcd_setfont(FONT_SYSFIXED);
971 return false;
974 /***********************************************************************
975 * pegbox_menu() is the game menu
976 ************************************************************************/
977 static bool _ingame;
978 static int pegbox_menu_cb(int action, const struct menu_item_ex *this_item)
980 int i = (intptr_t)this_item;
981 if( action == ACTION_REQUEST_MENUITEM )
983 if((!_ingame && (i==0 || i==1)) || ( _ingame && i==2 ))
984 return ACTION_EXIT_MENUITEM;
986 return action;
989 static unsigned int pegbox_menu(struct game_context* pb, bool ingame)
991 int selected = 0;
992 int last_level = pb->level;
994 MENUITEM_STRINGLIST (main_menu, "Pegbox Menu", pegbox_menu_cb,
995 "Resume Game", "Restart Level", "Start Game",
996 "Select Level", "Help",
997 "Playback Control", "Quit");
998 _ingame = ingame;
999 rb->button_clear_queue();
1001 while (true) {
1002 switch (rb->do_menu(&main_menu, &selected, NULL, false)) {
1003 case 0:
1004 pb->level = last_level;
1005 pegbox_draw_board(pb);
1006 return 0;
1007 case 1:
1008 case 2:
1009 pegbox_load_level(pb);
1010 pegbox_draw_board(pb);
1011 return 0;
1012 case 3:
1013 if(rb->set_int("Select Level", "", UNIT_INT, &pb->level,
1014 NULL, 1, 1, pb->highlevel, NULL))
1015 return 1;
1016 break;
1017 case 4:
1018 if (pegbox_help())
1019 return 1;
1020 break;
1021 case 5:
1022 if (playback_control(NULL))
1023 return 1;
1024 break;
1025 case 6:
1026 return 1;
1027 case MENU_ATTACHED_USB:
1028 return 1;
1029 default:
1030 break;
1035 /***********************************************************************
1036 * pegbox_main() is the main game subroutine
1037 ************************************************************************/
1038 static int pegbox_main(struct game_context* pb)
1040 int button;
1042 if (pegbox_menu(pb, false)==1) {
1043 return 1;
1046 while (true) {
1047 button = rb->button_get(true);
1048 #ifdef HAVE_TOUCHSCREEN
1049 if(button & BUTTON_TOUCHSCREEN)
1051 pegbox_raster_btn.two_d_from.y = pb->player_row;
1052 pegbox_raster_btn.two_d_from.x = pb->player_col;
1054 struct ts_raster_button_result ret =
1055 touchscreen_raster_map_button(&pegbox_raster_btn,
1056 rb->button_get_data() >> 16,
1057 rb->button_get_data() & 0xffff,
1058 button);
1059 if(ret.action == TS_ACTION_TWO_D_MOVEMENT)
1060 pegbox_move_player(pb, ret.to.x - ret.from.x, ret.to.y - ret.from.y);
1062 #endif
1063 switch(button){
1064 case PEGBOX_LEFT: /* move cursor left */
1065 case (PEGBOX_LEFT|BUTTON_REPEAT):
1066 pegbox_move_player(pb, -1, 0);
1067 break;
1069 case PEGBOX_RIGHT: /* move cursor right */
1070 case (PEGBOX_RIGHT|BUTTON_REPEAT):
1071 pegbox_move_player(pb, 1, 0);
1072 break;
1074 case PEGBOX_DOWN: /* move cursor down */
1075 case (PEGBOX_DOWN|BUTTON_REPEAT):
1076 pegbox_move_player(pb, 0, 1);
1077 break;
1079 case PEGBOX_UP: /* move cursor up */
1080 case (PEGBOX_UP|BUTTON_REPEAT):
1081 pegbox_move_player(pb, 0, -1);
1082 break;
1084 case PEGBOX_QUIT:
1085 if (pegbox_menu(pb, true)==1) {
1086 return 1;
1088 break;
1090 #ifdef PEGBOX_RESTART
1091 case PEGBOX_RESTART:
1092 pegbox_load_level(pb);
1093 pegbox_draw_board(pb);
1094 break;
1095 #endif
1097 #ifdef PEGBOX_LVL_UP
1098 case (PEGBOX_LVL_UP|BUTTON_REPEAT):
1099 case PEGBOX_LVL_UP:
1100 if (pb->level >= pb->highlevel) {
1101 pb->level = 1;
1102 } else {
1103 pb->level++;
1105 pegbox_load_level(pb);
1106 pegbox_draw_board(pb);
1107 break;
1108 #endif
1110 #ifdef PEGBOX_LVL_DOWN
1111 case (PEGBOX_LVL_DOWN|BUTTON_REPEAT):
1112 case PEGBOX_LVL_DOWN:
1113 if(pb->level <= 1) {
1114 pb->level = pb->highlevel;
1115 } else {
1116 pb->level--;
1118 pegbox_load_level(pb);
1119 pegbox_draw_board(pb);
1120 break;
1121 #endif
1124 if (pb->num_left == 0) {
1125 rb->splash(HZ*2, "Nice Pegging!");
1126 if (pb->level == NUM_LEVELS) {
1127 pegbox_draw_board(pb);
1128 rb->splash(HZ*2, "Congratulations!");
1129 rb->splash(HZ*2, "You have finished the game!");
1130 if (pegbox_menu(pb,false)==1) {
1131 return 1;
1134 else {
1135 pb->level++;
1136 pegbox_load_level(pb);
1137 pegbox_draw_board(pb);
1140 if(pb->level > pb->highlevel)
1141 pb->highlevel = pb->level;
1145 return PLUGIN_OK;
1148 /*****************************************************************************
1149 * plugin entry point.
1150 ******************************************************************************/
1151 enum plugin_status plugin_start(const void* parameter)
1153 (void)parameter;
1154 #ifdef HAVE_LCD_BITMAP
1155 rb->lcd_setfont(FONT_SYSFIXED);
1156 #if LCD_DEPTH > 1
1157 rb->lcd_set_backdrop(NULL);
1158 #endif
1159 #ifdef HAVE_LCD_COLOR
1160 rb->lcd_set_foreground(LCD_WHITE);
1161 rb->lcd_set_background(BG_COLOR);
1162 #endif
1163 rb->lcd_clear_display();
1165 struct game_context pb;
1166 pb.level=1;
1167 pb.highlevel=1;
1168 struct configdata config[] = {
1169 {TYPE_INT, 1, NUM_LEVELS, { .int_p = &(pb.level) }, "level", NULL},
1170 {TYPE_INT, 1, NUM_LEVELS, { .int_p = &(pb.highlevel) }, "highlevel", NULL},
1172 configfile_load(CONFIG_FILE_NAME,config,2,0);
1173 pegbox_main(&pb);
1174 configfile_save(CONFIG_FILE_NAME,config,2,0);
1175 rb->lcd_setfont(FONT_UI);
1176 #endif /* HAVE_LCD_BITMAP */
1178 return PLUGIN_OK;