fix wrong score recording.
[kugel-rb.git] / apps / plugins / pegbox.c
blob8fea85e029001f2d4bdaef7fbbf3ee12266a13db
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_SAVE 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 SAVE_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_SAVE 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 SAVE_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_SAVE 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 SAVE_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_SAVE (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 SAVE_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_SAVE 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 SAVE_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_SAVE 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 SAVE_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_SAVE 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 SAVE_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_SAVE 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 SAVE_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_SAVE 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 SAVE_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_SAVE 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 SAVE_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_SAVE 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 SAVE_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_SAVE 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 SAVE_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_SAVE 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 SAVE_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_SAVE 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 SAVE_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_SAVE (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 SAVE_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_SAVE 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 SAVE_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_SAVE 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 SAVE_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_SAVE 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 SAVE_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 || CONFIG_KEYPAD == MROBE500_PAD
360 #define PEGBOX_QUIT BUTTON_POWER
362 #define QUIT_TEXT "POWER"
364 #else
365 #error Unsupported keymap!
366 #endif
368 #ifdef HAVE_TOUCHSCREEN
369 #ifndef PEGBOX_QUIT
370 #define PEGBOX_QUIT BUTTON_TOPLEFT
371 #endif
372 #ifndef PEGBOX_SAVE
373 #define PEGBOX_SAVE BUTTON_CENTER
374 #endif
375 #ifndef PEGBOX_RESTART
376 #define PEGBOX_RESTART BUTTON_TOPRIGHT
377 #endif
378 #ifndef PEGBOX_LVL_UP
379 #define PEGBOX_LVL_UP BUTTON_BOTTOMLEFT
380 #endif
381 #ifndef PEGBOX_LVL_DOWN
382 #define PEGBOX_LVL_DOWN BUTTON_BOTTOMRIGHT
383 #endif
384 #ifndef PEGBOX_UP
385 #define PEGBOX_UP BUTTON_TOPMIDDLE
386 #endif
387 #ifndef PEGBOX_DOWN
388 #define PEGBOX_DOWN BUTTON_BOTTOMMIDDLE
389 #endif
390 #ifndef PEGBOX_RIGHT
391 #define PEGBOX_RIGHT BUTTON_MIDRIGHT
392 #endif
393 #ifndef PEGBOX_LEFT
394 #define PEGBOX_LEFT BUTTON_MIDLEFT
395 #endif
396 #ifndef SAVE_TEXT
397 #define SAVE_TEXT "CENTER"
398 #endif
399 #ifndef QUIT_TEXT
400 #define QUIT_TEXT "TOPLEFT"
401 #endif
402 #ifndef RESTART_TEXT
403 #define RESTART_TEXT "TOPRIGHT"
404 #endif
405 #ifndef LVL_UP_TEXT
406 #define LVL_UP_TEXT "BOTTOMLEFT"
407 #endif
408 #ifndef LVL_DOWN_TEXT
409 #define LVL_DOWN_TEXT "BOTTOMRIGHT"
410 #endif
411 #endif
414 /* get several sizes from the bitmaps */
415 #ifdef BMPWIDTH_pegbox_pieces
416 #define PIECE_WIDTH BMPWIDTH_pegbox_pieces
417 #define PIECE_HEIGHT (BMPHEIGHT_pegbox_pieces/7)
418 #else
419 /* dummy numbers to avoid #error in dependency generation */
420 #define PIECE_WIDTH 50
421 #define PIECE_HEIGHT 10
422 #endif
424 #define BOARD_WIDTH (12*PIECE_WIDTH)
425 #define BOARD_HEIGHT (8*PIECE_HEIGHT)
428 /* define a wide layout where the statistics are alongside the board, not above
429 * base calculation on the piece bitmaps for the 8x12 board */
430 #if (LCD_WIDTH - BOARD_WIDTH) > (LCD_HEIGHT - BOARD_HEIGHT)
431 #define WIDE_LAYOUT
432 #endif
435 #define HEADER_WIDTH BMPWIDTH_pegbox_header
436 #define HEADER_HEIGHT BMPHEIGHT_pegbox_header
439 #if defined WIDE_LAYOUT
441 #if ((BOARD_WIDTH + HEADER_WIDTH + 4) <= LCD_WIDTH)
442 #define BOARD_X 2
443 #else
444 #define BOARD_X 1
445 #endif
446 #define BOARD_Y (LCD_HEIGHT-BOARD_HEIGHT)/2
448 #if (LCD_WIDTH >= 132) && (LCD_HEIGHT >= 80)
449 #define TEXT_X 116
450 #define LEVEL_TEXT_Y 14
451 #define PEGS_TEXT_Y 58
452 #elif (LCD_WIDTH >= 128) && (LCD_HEIGHT >= 64)
453 #define TEXT_X 112
454 #define LEVEL_TEXT_Y 27
455 #define PEGS_TEXT_Y 50
456 #else
457 #error "Unsupported screen size"
458 #endif
460 #else /* "normal" layout */
462 #define BOARD_X (LCD_WIDTH-BOARD_WIDTH)/2
463 #if ((BOARD_HEIGHT + HEADER_HEIGHT + 4) <= LCD_HEIGHT)
464 #define BOARD_Y HEADER_HEIGHT+2
465 #else
466 #define BOARD_Y HEADER_HEIGHT
467 #endif
469 #if LCD_WIDTH >= 320
470 #define LEVEL_TEXT_X 59
471 #define PEGS_TEXT_X 276
472 #define TEXT_Y 28
473 #elif LCD_WIDTH >= 240
474 #define LEVEL_TEXT_X 59
475 #define PEGS_TEXT_X 196
476 #define TEXT_Y 28
477 #elif LCD_WIDTH >= 220
478 #define LEVEL_TEXT_X 49
479 #define PEGS_TEXT_X 186
480 #define TEXT_Y 28
481 #elif LCD_WIDTH >= 176
482 #define LEVEL_TEXT_X 38
483 #define PEGS_TEXT_X 155
484 #define TEXT_Y 17
485 #elif LCD_WIDTH >= 160
486 #define LEVEL_TEXT_X 37
487 #define PEGS_TEXT_X 140
488 #define TEXT_Y 13
489 #elif LCD_WIDTH >= 138
490 #define LEVEL_TEXT_X 28
491 #define PEGS_TEXT_X 119
492 #define TEXT_Y 15
493 #elif LCD_WIDTH >= 128
494 #if HEADER_HEIGHT > 16
495 #define LEVEL_TEXT_X 26
496 #define PEGS_TEXT_X 107
497 #define TEXT_Y 31
498 #else
499 #define LEVEL_TEXT_X 15
500 #define PEGS_TEXT_X 100
501 #define TEXT_Y 5
502 #endif /* HEADER_HEIGHT */
503 #elif LCD_WIDTH >= 112
504 #define LEVEL_TEXT_X 25
505 #define PEGS_TEXT_X 90
506 #define TEXT_Y 0
507 #endif /* LCD_WIDTH */
509 #endif /* WIDE_LAYOUT */
512 #ifdef HAVE_LCD_COLOR
513 #define BG_COLOR LCD_BLACK
514 #define TEXT_BG LCD_RGBPACK(189,189,189)
515 #endif
518 #ifdef HAVE_TOUCHSCREEN
519 #include "lib/touchscreen.h"
520 static struct ts_raster pegbox_raster =
521 { BOARD_X, BOARD_Y, COLS*PIECE_WIDTH, ROWS*PIECE_HEIGHT,
522 PIECE_WIDTH, PIECE_HEIGHT };
523 static struct ts_raster_button_mapping pegbox_raster_btn =
524 { &pegbox_raster, false, false, true, false, true, {0, 0}, 0, 0, 0 };
525 #endif
528 struct game_context {
529 unsigned int level;
530 unsigned int highlevel;
531 signed int player_row;
532 signed int player_col;
533 unsigned int num_left;
534 unsigned int playboard[ROWS][COLS];
537 char levels[NUM_LEVELS][ROWS][COLS] = {
538 /* Level 1 */
539 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
540 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
541 {1, 0, 0, 0, 7, 0, 0, 5, 0, 0, 0, 1,},
542 {1, 0, 0, 0, 0, 3, 3, 2, 0, 0, 0, 1,},
543 {1, 0, 0, 0, 4, 6, 0, 5, 0, 0, 0, 1,},
544 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
545 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
546 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
548 /* Level 2 */
549 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
550 {1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 1,},
551 {1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1,},
552 {1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1,},
553 {7, 0, 0, 0, 2, 2, 5, 5, 0, 0, 0, 1,},
554 {1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1,},
555 {1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1,},
556 {1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 1,}},
558 /* Level 3 */
559 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
560 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
561 {1, 0, 0, 0, 0, 0, 2, 0, 7, 0, 0, 0,},
562 {1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 2, 1,},
563 {1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1,},
564 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1,},
565 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
566 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
568 /* Level 4 */
569 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
570 {6, 0, 4, 0, 2, 0, 2, 0, 0, 0, 0, 1,},
571 {6, 0, 3, 0, 5, 0, 2, 0, 0, 0, 0, 1,},
572 {6, 0, 5, 0, 4, 7, 2, 0, 0, 0, 0, 1,},
573 {6, 0, 2, 0, 4, 0, 2, 0, 3, 0, 0, 1,},
574 {6, 0, 4, 0, 5, 0, 2, 0, 0, 0, 0, 1,},
575 {6, 0, 5, 0, 4, 0, 2, 0, 0, 0, 0, 1,},
576 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
578 /* Level 5 */
579 {{0, 6, 6, 0, 4, 6, 0, 0, 6, 0, 0, 0,},
580 {0, 6, 6, 0, 4, 4, 0, 0, 6, 0, 0, 2,},
581 {2, 6, 6, 0, 6, 6, 6, 0, 1, 2, 2, 2,},
582 {0, 6, 6, 0, 6, 4, 6, 0, 1, 2, 0, 2,},
583 {0, 6, 6, 0, 6, 7, 6, 5, 6, 0, 0, 0,},
584 {2, 6, 6, 0, 6, 6, 6, 0, 6, 0, 0, 0,},
585 {0, 6, 6, 0, 4, 0, 0, 0, 6, 0, 0, 0,},
586 {0, 6, 6, 0, 0, 5, 0, 0, 6, 5, 5, 0,}},
588 /* Level 6 */
589 {{7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
590 {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,},
591 {2, 0, 0, 2, 0, 0, 0, 2, 2, 0, 0, 0,},
592 {0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 0,},
593 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
594 {0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1,},
595 {0, 3, 0, 0, 0, 0, 0, 0, 5, 4, 6, 0,},
596 {0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1,}},
598 /* Level 7 */
599 {{1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1,},
600 {1, 1, 1, 6, 0, 0, 4, 6, 0, 1, 1, 1,},
601 {1, 1, 1, 1, 0, 1, 5, 1, 0, 1, 1, 1,},
602 {1, 1, 1, 2, 3, 3, 7, 4, 2, 6, 1, 1,},
603 {1, 1, 1, 1, 0, 1, 2, 1, 0, 0, 0, 1,},
604 {1, 1, 1, 1, 0, 0, 5, 0, 0, 1, 0, 1,},
605 {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1,},
606 {1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,}},
608 /* Level 8 */
609 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
610 {0, 0, 3, 3, 3, 3, 3, 4, 3, 3, 0, 0,},
611 {0, 0, 3, 3, 3, 2, 3, 3, 5, 3, 0, 0,},
612 {7, 0, 3, 3, 3, 2, 3, 3, 4, 3, 0, 0,},
613 {0, 0, 3, 3, 4, 5, 3, 3, 3, 3, 0, 0,},
614 {0, 0, 3, 3, 5, 2, 3, 3, 3, 3, 0, 0,},
615 {0, 0, 3, 3, 2, 4, 3, 3, 3, 3, 0, 0,},
616 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
618 /* Level 9 */
619 {{0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,},
620 {0, 3, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,},
621 {0, 0, 0, 0, 2, 4, 4, 3, 0, 1, 1, 0,},
622 {0, 1, 0, 0, 2, 1, 0, 0, 0, 1, 1, 1,},
623 {0, 0, 0, 2, 2, 7, 1, 0, 0, 0, 0, 2,},
624 {0, 0, 0, 0, 2, 1, 0, 0, 1, 1, 1, 1,},
625 {0, 3, 1, 0, 2, 5, 5, 0, 0, 0, 3, 0,},
626 {0, 0, 0, 0, 4, 1, 0, 0, 0, 0, 0, 0,}},
628 /* Level 10 */
629 {{1, 1, 1, 1, 2, 1, 1, 1, 0, 0, 0, 0,},
630 {1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 7,},
631 {0, 0, 4, 0, 6, 6, 6, 0, 0, 0, 3, 0,},
632 {0, 3, 3, 0, 6, 6, 6, 0, 4, 3, 4, 0,},
633 {0, 3, 3, 0, 6, 6, 6, 0, 4, 3, 4, 0,},
634 {0, 0, 0, 0, 6, 6, 6, 0, 3, 0, 0, 0,},
635 {1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0,},
636 {1, 1, 1, 1, 1, 2, 1, 1, 0, 0, 0, 0,}},
638 /* Level 11 */
639 {{1, 7, 1, 0, 1, 1, 6, 0, 0, 1, 1, 0,},
640 {1, 0, 0, 0, 5, 4, 6, 6, 0, 2, 2, 0,},
641 {1, 2, 1, 2, 0, 1, 6, 0, 0, 2, 2, 0,},
642 {1, 0, 0, 2, 0, 1, 0, 0, 0, 3, 3, 0,},
643 {1, 2, 1, 0, 0, 1, 0, 1, 0, 3, 3, 0,},
644 {0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0,},
645 {0, 3, 4, 3, 0, 1, 0, 1, 0, 0, 0, 0,},
646 {0, 0, 0, 0, 2, 2, 2, 1, 1, 1, 1, 1,}},
648 /* Level 12 */
649 {{7, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,},
650 {1, 2, 1, 2, 1, 2, 1, 1, 0, 0, 0, 1,},
651 {0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1,},
652 {1, 2, 1, 2, 1, 2, 1, 0, 0, 0, 0, 1,},
653 {0, 0, 0, 0, 0, 0, 1, 1, 5, 5, 6, 1,},
654 {1, 2, 1, 2, 1, 2, 1, 1, 0, 2, 2, 1,},
655 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1,},
656 {1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1,}},
658 /* Level 13 */
659 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
660 {0, 0, 4, 0, 2, 0, 5, 0, 4, 0, 0, 6,},
661 {0, 0, 2, 0, 5, 0, 2, 0, 4, 0, 0, 6,},
662 {7, 0, 3, 0, 4, 0, 5, 0, 4, 0, 0, 6,},
663 {0, 0, 5, 0, 4, 0, 2, 0, 4, 0, 0, 6,},
664 {0, 0, 4, 0, 2, 0, 5, 0, 4, 0, 0, 6,},
665 {0, 0, 3, 0, 3, 0, 2, 0, 4, 0, 0, 6,},
666 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
668 /* Level 14 */
669 {{1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1,},
670 {1, 1, 0, 2, 0, 0, 4, 0, 0, 2, 0, 1,},
671 {1, 6, 0, 0, 5, 1, 0, 1, 1, 0, 0, 1,},
672 {1, 1, 1, 0, 0, 3, 5, 3, 0, 0, 1, 1,},
673 {1, 1, 0, 0, 1, 1, 0, 1, 5, 0, 0, 6,},
674 {1, 1, 0, 2, 0, 0, 4, 0, 0, 0, 7, 1,},
675 {1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1,},
676 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
678 /* Level 15 */
679 {{0, 0, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
680 {0, 0, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
681 {0, 3, 4, 6, 0, 6, 0, 6, 0, 6, 0, 2,},
682 {0, 4, 0, 6, 0, 6, 4, 6, 0, 6, 0, 1,},
683 {0, 3, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
684 {7, 0, 0, 6, 4, 6, 0, 6, 0, 6, 0, 1,},
685 {0, 0, 4, 6, 0, 6, 0, 6, 4, 6, 0, 1,},
686 {0, 0, 4, 6, 0, 6, 0, 6, 0, 6, 0, 1,}}
689 /***********************************************************************
690 * pegbox_draw_board() draws the game's current level.
691 ************************************************************************/
692 static void pegbox_draw_board(struct game_context* pb)
694 unsigned int r, c, type;
695 pb->num_left = 0;
696 char str[5];
698 rb->lcd_clear_display();
699 #ifdef WIDE_LAYOUT
700 rb->lcd_bitmap(pegbox_header,LCD_WIDTH-HEADER_WIDTH,0,
701 HEADER_WIDTH,LCD_HEIGHT);
702 #else
703 rb->lcd_bitmap(pegbox_header,(LCD_WIDTH-HEADER_WIDTH)/2,0,
704 HEADER_WIDTH, HEADER_HEIGHT);
705 #endif /* WIDE_LAYOUT */
707 #if ((BOARD_HEIGHT + HEADER_HEIGHT + 4) <= LCD_HEIGHT)
708 rb->lcd_drawrect(BOARD_X-2,BOARD_Y-2,BOARD_WIDTH+4,BOARD_HEIGHT+4);
709 #endif /* enough space for a frame? */
711 #ifdef HAVE_LCD_COLOR
712 rb->lcd_set_foreground(LCD_WHITE);
713 rb->lcd_fillrect(BOARD_X-1,BOARD_Y-1,BOARD_WIDTH+2,BOARD_HEIGHT+2);
714 rb->lcd_set_foreground(LCD_BLACK);
715 rb->lcd_set_background(TEXT_BG);
716 #endif
718 for (r=0 ; r < ROWS ; r++) {
719 for (c = 0 ; c < COLS ; c++) {
721 type = pb->playboard[r][c];
723 switch(type) {
724 case SPACE:
725 break;
727 default:
728 rb->lcd_bitmap_part(pegbox_pieces, 0, (type-1)*PIECE_HEIGHT,
729 PIECE_WIDTH, c * PIECE_WIDTH + BOARD_X,
730 r * PIECE_HEIGHT + BOARD_Y, PIECE_WIDTH,
731 PIECE_HEIGHT);
732 break;
735 if(pb->playboard[r][c] == PLAYER) {
736 pb->player_row=r;
737 pb->player_col=c;
739 else if (type != WALL && type != SPACE && type != HOLE)
740 pb->num_left++;
744 #ifdef WIDE_LAYOUT
745 rb->snprintf(str, 3, "%d", pb->level);
746 rb->lcd_putsxy(TEXT_X, LEVEL_TEXT_Y, str);
747 rb->snprintf(str, 3, "%d", pb->num_left);
748 rb->lcd_putsxy(TEXT_X, PEGS_TEXT_Y, str);
749 #else
750 rb->snprintf(str, 3, "%d", pb->level);
751 rb->lcd_putsxy(LEVEL_TEXT_X, TEXT_Y, str);
752 rb->snprintf(str, 3, "%d", pb->num_left);
753 rb->lcd_putsxy(PEGS_TEXT_X, TEXT_Y, str);
754 #endif /*WIDE_LAYOUT*/
756 #ifdef HAVE_LCD_COLOR
757 rb->lcd_set_background(BG_COLOR);
758 rb->lcd_set_foreground(LCD_WHITE);
759 #endif
760 /* print out the screen */
761 rb->lcd_update();
764 /*****************************************************************************
765 * pegbox_load_level() loads the player's current level from the array and sets the
766 * player's position.
767 ******************************************************************************/
768 static void pegbox_load_level(struct game_context* pb)
770 int r, c;
772 for(r = 0; r < ROWS; r++)
773 for(c = 0; c < COLS; c++)
774 pb->playboard[r][c] = levels[pb->level-1][r][c];
777 /*****************************************************************************
778 * pegbox_new_piece() creates a new piece at a specified location. The player
779 * navigates through the pieces and selects one.
780 ******************************************************************************/
781 static void pegbox_new_piece(struct game_context* pb, unsigned int x_loc,
782 unsigned int y_loc)
784 int button;
785 bool exit = false;
787 pb->playboard[x_loc][y_loc] = TRIANGLE;
789 while (!exit) {
790 pegbox_draw_board(pb);
791 button = rb->button_get(true);
792 #ifdef HAVE_TOUCHSCREEN
793 if(button & BUTTON_TOUCHSCREEN)
795 pegbox_raster_btn.two_d_from.y = x_loc;
796 pegbox_raster_btn.two_d_from.x = y_loc;
798 struct ts_raster_button_result ret =
799 touchscreen_raster_map_button(&pegbox_raster_btn,
800 rb->button_get_data() >> 16,
801 rb->button_get_data() & 0xffff,
802 button);
803 if(ret.action == TS_ACTION_TWO_D_MOVEMENT)
805 if(ret.to.x > ret.from.x)
806 button = PEGBOX_UP;
807 else if(ret.to.x < ret.from.x)
808 button = PEGBOX_DOWN;
809 else if(ret.to.y > ret.from.y)
810 button = PEGBOX_LEFT;
811 else if(ret.to.y < ret.from.y)
812 button = PEGBOX_RIGHT;
814 else if(ret.action == TS_ACTION_CLICK
815 && (unsigned)ret.to.x == y_loc
816 && (unsigned)ret.to.y == x_loc)
817 button = PEGBOX_SAVE;
819 #endif
820 switch(button){
821 case PEGBOX_LEFT:
822 case (PEGBOX_LEFT|BUTTON_REPEAT):
823 case PEGBOX_DOWN:
824 case (PEGBOX_DOWN|BUTTON_REPEAT):
825 if (pb->playboard[x_loc][y_loc] < 5)
826 pb->playboard[x_loc][y_loc]++;
827 else
828 pb->playboard[x_loc][y_loc] = TRIANGLE;
829 break;
830 case PEGBOX_RIGHT:
831 case (PEGBOX_RIGHT|BUTTON_REPEAT):
832 case PEGBOX_UP:
833 case (PEGBOX_UP|BUTTON_REPEAT):
834 if (pb->playboard[x_loc][y_loc] > 2)
835 pb->playboard[x_loc][y_loc]--;
836 else
837 pb->playboard[x_loc][y_loc] = CIRCLE;
838 break;
839 case PEGBOX_SAVE:
840 exit=true;
845 /*****************************************************************************
846 * pegbox_move_player() moves the player and pieces and updates the board accordingly.
847 ******************************************************************************/
848 static void pegbox_move_player(struct game_context* pb, signed int x_dir,
849 signed int y_dir)
851 unsigned int type1, type2;
852 signed int r,c;
854 r = pb->player_row+y_dir;
855 c = pb->player_col+x_dir;
857 type1 = pb->playboard[r][c];
858 type2 = pb->playboard[r+y_dir][c+x_dir];
860 if (r == ROWS || c == COLS || r < 0 || c < 0 || type1 == WALL)
861 return;
862 else if(type1 != SPACE) {
863 if (type2 == WALL || r+y_dir == ROWS || c+x_dir == COLS ||
864 r+y_dir < 0 || c+x_dir < 0)
865 return;
869 pb->playboard[pb->player_row][pb->player_col] = SPACE;
870 pb->player_row += y_dir;
871 pb->player_col += x_dir;
873 if (type1 == HOLE) {
874 pegbox_draw_board(pb);
875 rb->splash(HZ*2, "You fell down a hole!");
876 pegbox_load_level(pb);
878 else if (type1 == SPACE)
879 pb->playboard[r][c] = PLAYER;
880 else {
881 pb->playboard[r][c] = PLAYER;
882 if(type1 == type2) {
883 if (type1 == TRIANGLE)
884 pb->playboard[r+y_dir][c+x_dir] = WALL;
885 else if (type1 == CROSS) {
886 pb->playboard[r][c] = SPACE;
887 pegbox_new_piece(pb, r+y_dir, c+x_dir);
888 pb->playboard[r][c] = PLAYER;
890 else
891 pb->playboard[r+y_dir][c+x_dir] = SPACE;
893 else if (type2 == SPACE)
894 pb->playboard[r+y_dir][c+x_dir] = type1;
895 else if (type2 == HOLE) {
896 if (type1 == SQUARE)
897 pb->playboard[r+y_dir][c+x_dir] = SPACE;
899 else {
900 rb->splash(HZ*2, "Illegal Move!");
901 pegbox_load_level(pb);
905 pegbox_draw_board(pb);
908 /***********************************************************************
909 * pegbox_help() display help text
910 ************************************************************************/
911 static bool pegbox_help(void)
913 int button;
914 #define WORDS (sizeof help_text / sizeof (char*))
915 static char* help_text[] = {
916 "Pegbox", "", "Aim", "",
917 "To", "beat", "each", "level,", "you", "must", "destroy", "all", "of",
918 "the", "pegs.", "If", "two", "like", "pegs", "are", "pushed", "into",
919 "each", "other,", "they", "disappear", "except", "for", "triangles",
920 "which", "form", "a", "solid", "block", "and", "crosses", "which",
921 "allow", "you", "to", "choose", "a", "replacement", "block.", "", "",
922 "Controls", "",
923 RESTART_TEXT, "to", "restart", "level", "",
924 LVL_UP_TEXT, "to", "go", "up", "a", "level", "",
925 LVL_DOWN_TEXT, "to", "go", "down", "a", "level", "",
926 SAVE_TEXT, "to", "choose", "peg", "",
927 QUIT_TEXT, "to", "quit"
929 static struct style_text formation[]={
930 { 0, TEXT_CENTER|TEXT_UNDERLINE },
931 { 2, C_RED },
932 { 46, C_RED },
933 { -1, 0 }
936 rb->lcd_setfont(FONT_UI);
938 if (display_text(WORDS, help_text, formation, NULL))
939 return true;
940 do {
941 button = rb->button_get(true);
942 if ( rb->default_event_handler( button ) == SYS_USB_CONNECTED )
943 return true;
944 } while( ( button == BUTTON_NONE )
945 || ( button & (BUTTON_REL|BUTTON_REPEAT) ) );
946 rb->lcd_setfont(FONT_SYSFIXED);
947 return false;
950 /***********************************************************************
951 * pegbox_menu() is the game menu
952 ************************************************************************/
953 static unsigned int pegbox_menu(struct game_context* pb, bool ingame)
955 rb->button_clear_queue();
956 int choice = 0;
958 if (ingame) {
959 MENUITEM_STRINGLIST (main_menu, "Pegbox Menu", NULL,
960 "Resume Game",
961 "Restart Level",
962 "Select Level",
963 "Help",
964 "Playback Control",
965 "Quit");
967 while (true) {
968 switch (rb->do_menu(&main_menu, &choice, NULL, false)) {
969 case 0:
970 pegbox_draw_board(pb);
971 return 0;
972 case 1:
973 pegbox_load_level(pb);
974 pegbox_draw_board(pb);
975 return 0;
976 case 2:
977 rb->set_int("Select Level", "", UNIT_INT,
978 &pb->level, NULL, 1, 1,
979 pb->highlevel, NULL);
980 break;
981 case 3:
982 if (pegbox_help()==PLUGIN_USB_CONNECTED)
983 return 1;
984 break;
985 case 4:
986 playback_control(NULL);
987 break;
988 case 5:
989 return 1;
990 case MENU_ATTACHED_USB:
991 return 1;
992 default:
993 break;
996 } else {
997 MENUITEM_STRINGLIST (main_menu, "Pegbox Menu", NULL,
998 "Start Game",
999 "Select Level",
1000 "Help",
1001 "Playback Control",
1002 "Quit");
1004 while (true) {
1005 switch (rb->do_menu(&main_menu, &choice, NULL, false)) {
1006 case 0:
1007 pegbox_load_level(pb);
1008 pegbox_draw_board(pb);
1009 return 0;
1010 case 1:
1011 rb->set_int("Select Level", "", UNIT_INT,
1012 &pb->level, NULL, 1, 1,
1013 pb->highlevel, NULL);
1014 break;
1015 case 2:
1016 if (pegbox_help()==PLUGIN_USB_CONNECTED)
1017 return 1;
1018 break;
1019 case 3:
1020 playback_control(NULL);
1021 break;
1022 case 4:
1023 return 1;
1024 case MENU_ATTACHED_USB:
1025 return 1;
1026 default:
1027 break;
1033 /***********************************************************************
1034 * pegbox_main() is the main game subroutine
1035 ************************************************************************/
1036 static int pegbox_main(struct game_context* pb)
1038 int button;
1040 if (pegbox_menu(pb, false)==1) {
1041 return 1;
1044 while (true) {
1045 button = rb->button_get(true);
1046 #ifdef HAVE_TOUCHSCREEN
1047 if(button & BUTTON_TOUCHSCREEN)
1049 pegbox_raster_btn.two_d_from.y = pb->player_row;
1050 pegbox_raster_btn.two_d_from.x = pb->player_col;
1052 struct ts_raster_button_result ret =
1053 touchscreen_raster_map_button(&pegbox_raster_btn,
1054 rb->button_get_data() >> 16,
1055 rb->button_get_data() & 0xffff,
1056 button);
1057 if(ret.action == TS_ACTION_TWO_D_MOVEMENT)
1058 pegbox_move_player(pb, ret.to.x - ret.from.x, ret.to.y - ret.from.y);
1060 #endif
1061 switch(button){
1062 case PEGBOX_LEFT: /* move cursor left */
1063 case (PEGBOX_LEFT|BUTTON_REPEAT):
1064 pegbox_move_player(pb, -1, 0);
1065 break;
1067 case PEGBOX_RIGHT: /* move cursor right */
1068 case (PEGBOX_RIGHT|BUTTON_REPEAT):
1069 pegbox_move_player(pb, 1, 0);
1070 break;
1072 case PEGBOX_DOWN: /* move cursor down */
1073 case (PEGBOX_DOWN|BUTTON_REPEAT):
1074 pegbox_move_player(pb, 0, 1);
1075 break;
1077 case PEGBOX_UP: /* move cursor up */
1078 case (PEGBOX_UP|BUTTON_REPEAT):
1079 pegbox_move_player(pb, 0, -1);
1080 break;
1082 case PEGBOX_QUIT:
1083 if (pegbox_menu(pb, true)==1) {
1084 return 1;
1086 #ifdef PEGBOX_RESTART
1087 case PEGBOX_RESTART:
1088 pegbox_load_level(pb);
1089 pegbox_draw_board(pb);
1090 break;
1091 #endif
1093 #ifdef PEGBOX_LVL_UP
1094 case (PEGBOX_LVL_UP|BUTTON_REPEAT):
1095 case PEGBOX_LVL_UP:
1096 if (pb->level >= pb->highlevel) {
1097 pb->level = 1;
1098 } else {
1099 pb->level++;
1101 pegbox_load_level(pb);
1102 pegbox_draw_board(pb);
1103 break;
1104 #endif
1106 #ifdef PEGBOX_LVL_DOWN
1107 case (PEGBOX_LVL_DOWN|BUTTON_REPEAT):
1108 case PEGBOX_LVL_DOWN:
1109 if(pb->level <= 1) {
1110 pb->level = pb->highlevel;
1111 } else {
1112 pb->level--;
1114 pegbox_load_level(pb);
1115 pegbox_draw_board(pb);
1116 break;
1117 #endif
1120 if (pb->num_left == 0) {
1121 rb->splash(HZ*2, "Nice Pegging!");
1122 if (pb->level == NUM_LEVELS) {
1123 pegbox_draw_board(pb);
1124 rb->splash(HZ*2, "Congratulations!");
1125 rb->splash(HZ*2, "You have finished the game!");
1126 if (pegbox_menu(pb,false)==1) {
1127 return 1;
1130 else {
1131 pb->level++;
1132 pegbox_load_level(pb);
1133 pegbox_draw_board(pb);
1136 if(pb->level > pb->highlevel)
1137 pb->highlevel = pb->level;
1141 return PLUGIN_OK;
1144 /*****************************************************************************
1145 * plugin entry point.
1146 ******************************************************************************/
1147 enum plugin_status plugin_start(const void* parameter)
1149 (void)parameter;
1150 #ifdef HAVE_LCD_BITMAP
1151 rb->lcd_setfont(FONT_SYSFIXED);
1152 #if LCD_DEPTH > 1
1153 rb->lcd_set_backdrop(NULL);
1154 #endif
1155 #ifdef HAVE_LCD_COLOR
1156 rb->lcd_set_foreground(LCD_WHITE);
1157 rb->lcd_set_background(BG_COLOR);
1158 #endif
1159 rb->lcd_clear_display();
1161 struct game_context pb;
1162 pb.level=1;
1163 pb.highlevel=1;
1164 struct configdata config[] = {
1165 {TYPE_INT, 1, NUM_LEVELS, { .int_p = &(pb.level) }, "level", NULL},
1166 {TYPE_INT, 1, NUM_LEVELS, { .int_p = &(pb.highlevel) }, "highlevel", NULL},
1168 configfile_load(CONFIG_FILE_NAME,config,2,0);
1169 pegbox_main(&pb);
1170 configfile_save(CONFIG_FILE_NAME,config,2,0);
1171 rb->lcd_setfont(FONT_UI);
1172 #endif /* HAVE_LCD_BITMAP */
1174 return PLUGIN_OK;