1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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 ****************************************************************************/
23 #include "pluginbitmaps/pegbox_header.h"
24 #include "pluginbitmaps/pegbox_pieces.h"
26 #if LCD_HEIGHT >= 80 /* enough space for a graphical menu */
27 #include "pluginbitmaps/pegbox_menu_top.h"
28 #include "pluginbitmaps/pegbox_menu_items.h"
29 #define MENU_X (LCD_WIDTH-BMPWIDTH_pegbox_menu_items)/2
30 #define MENU_Y BMPHEIGHT_pegbox_menu_top
31 #define ITEM_WIDTH BMPWIDTH_pegbox_menu_items
32 #define ITEM_HEIGHT (BMPHEIGHT_pegbox_menu_items/9)
35 static const struct plugin_api
* rb
;
39 /* final game return status */
44 #define DATA_FILE PLUGIN_DIR "/games/pegbox.data"
45 #define SAVE_FILE PLUGIN_DIR "/games/pegbox.save"
47 #define ROWS 8 /* Number of rows on each board */
48 #define COLS 12 /* Number of columns on each board */
49 #define NUM_LEVELS 15 /* Number of levels */
60 #if CONFIG_KEYPAD == RECORDER_PAD
61 #define PEGBOX_SAVE BUTTON_ON
62 #define PEGBOX_QUIT BUTTON_OFF
63 #define PEGBOX_RESTART BUTTON_F2
64 #define PEGBOX_LVL_UP BUTTON_F1
65 #define PEGBOX_LVL_DOWN BUTTON_F3
66 #define PEGBOX_UP BUTTON_UP
67 #define PEGBOX_DOWN BUTTON_DOWN
68 #define PEGBOX_RIGHT BUTTON_RIGHT
69 #define PEGBOX_LEFT BUTTON_LEFT
71 #define SAVE_TEXT "ON"
72 #define QUIT_TEXT "OFF"
73 #define RESTART_TEXT "F2"
74 #define LVL_UP_TEXT "F1"
75 #define LVL_DOWN_TEXT "F3"
77 #elif CONFIG_KEYPAD == ONDIO_PAD
78 #define PEGBOX_SAVE BUTTON_OFF
79 #define PEGBOX_QUIT (BUTTON_MENU | BUTTON_LEFT)
80 #define PEGBOX_RESTART (BUTTON_MENU | BUTTON_RIGHT)
81 #define PEGBOX_LVL_UP (BUTTON_MENU | BUTTON_UP)
82 #define PEGBOX_LVL_DOWN (BUTTON_MENU | BUTTON_DOWN)
83 #define PEGBOX_UP BUTTON_UP
84 #define PEGBOX_DOWN BUTTON_DOWN
85 #define PEGBOX_RIGHT BUTTON_RIGHT
86 #define PEGBOX_LEFT BUTTON_LEFT
88 #define SAVE_TEXT "OFF"
89 #define QUIT_TEXT "M+LEFT"
90 #define RESTART_TEXT "M+RIGHT"
91 #define LVL_UP_TEXT "M+UP"
92 #define LVL_DOWN_TEXT "M+DOWN"
94 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
95 (CONFIG_KEYPAD == IRIVER_H300_PAD)
96 #define PEGBOX_SAVE BUTTON_SELECT
97 #define PEGBOX_QUIT BUTTON_OFF
98 #define PEGBOX_RESTART BUTTON_ON
99 #define PEGBOX_LVL_UP BUTTON_MODE
100 #define PEGBOX_LVL_DOWN BUTTON_REC
101 #define PEGBOX_UP BUTTON_UP
102 #define PEGBOX_DOWN BUTTON_DOWN
103 #define PEGBOX_RIGHT BUTTON_RIGHT
104 #define PEGBOX_LEFT BUTTON_LEFT
106 #define SAVE_TEXT "NAVI"
107 #define QUIT_TEXT "OFF"
108 #define RESTART_TEXT "ON"
109 #define LVL_UP_TEXT "AB"
110 #define LVL_DOWN_TEXT "REC"
112 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
113 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
114 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
115 #define PEGBOX_SAVE (BUTTON_SELECT|BUTTON_RIGHT)
116 #define PEGBOX_QUIT (BUTTON_SELECT|BUTTON_PLAY)
117 #define PEGBOX_RESTART (BUTTON_SELECT|BUTTON_LEFT)
118 #define PEGBOX_LVL_UP (BUTTON_SELECT|BUTTON_MENU)
119 #define PEGBOX_UP BUTTON_MENU
120 #define PEGBOX_DOWN BUTTON_PLAY
121 #define PEGBOX_RIGHT BUTTON_RIGHT
122 #define PEGBOX_LEFT BUTTON_LEFT
124 #define SAVE_TEXT "SELECT+RIGHT"
125 #define QUIT_TEXT "SELECT+PLAY"
126 #define RESTART_TEXT "SELECT+LEFT"
127 #define LVL_UP_TEXT "SELECT+MENU"
128 #define LVL_DOWN_TEXT "-"
130 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
131 #define PEGBOX_SAVE BUTTON_SELECT
132 #define PEGBOX_QUIT BUTTON_POWER
133 #define PEGBOX_RESTART BUTTON_REC
134 #define PEGBOX_LVL_UP BUTTON_PLAY
135 #define PEGBOX_UP BUTTON_UP
136 #define PEGBOX_DOWN BUTTON_DOWN
137 #define PEGBOX_RIGHT BUTTON_RIGHT
138 #define PEGBOX_LEFT BUTTON_LEFT
140 #define SAVE_TEXT "SELECT"
141 #define QUIT_TEXT "OFF"
142 #define RESTART_TEXT "REC"
143 #define LVL_UP_TEXT "PLAY"
144 #define LVL_DOWN_TEXT "-"
146 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
147 #define PEGBOX_SAVE BUTTON_MODE
148 #define PEGBOX_QUIT BUTTON_PLAY
149 #define PEGBOX_RESTART (BUTTON_EQ|BUTTON_MODE)
150 #define PEGBOX_LVL_UP (BUTTON_EQ|BUTTON_UP)
151 #define PEGBOX_LVL_DOWN (BUTTON_EQ|BUTTON_DOWN)
152 #define PEGBOX_UP BUTTON_UP
153 #define PEGBOX_DOWN BUTTON_DOWN
154 #define PEGBOX_RIGHT BUTTON_RIGHT
155 #define PEGBOX_LEFT BUTTON_LEFT
157 #define SAVE_TEXT "MODE"
158 #define QUIT_TEXT "PLAY"
159 #define RESTART_TEXT "EQ+MODE"
160 #define LVL_UP_TEXT "EQ+UP"
161 #define LVL_DOWN_TEXT "EQ+DOWN"
163 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
164 #define PEGBOX_SAVE BUTTON_PLAY
165 #define PEGBOX_QUIT BUTTON_POWER
166 #define PEGBOX_RESTART (BUTTON_FF|BUTTON_REPEAT)
167 #define PEGBOX_LVL_UP (BUTTON_FF|BUTTON_SCROLL_UP)
168 #define PEGBOX_LVL_DOWN (BUTTON_FF|BUTTON_SCROLL_DOWN)
169 #define PEGBOX_UP BUTTON_SCROLL_UP
170 #define PEGBOX_DOWN BUTTON_SCROLL_DOWN
171 #define PEGBOX_RIGHT BUTTON_RIGHT
172 #define PEGBOX_LEFT BUTTON_LEFT
174 #define SAVE_TEXT "PLAY"
175 #define QUIT_TEXT "OFF"
176 #define RESTART_TEXT "LONG FF"
177 #define LVL_UP_TEXT "FF+SCROLL_UP"
178 #define LVL_DOWN_TEXT "FF+SCROLL_DOWN"
180 #elif CONFIG_KEYPAD == SANSA_E200_PAD
181 #define PEGBOX_SAVE BUTTON_SELECT
182 #define PEGBOX_QUIT BUTTON_POWER
183 #define PEGBOX_RESTART BUTTON_REC
184 #define PEGBOX_LVL_UP BUTTON_SCROLL_BACK
185 #define PEGBOX_LVL_DOWN BUTTON_SCROLL_FWD
186 #define PEGBOX_UP BUTTON_UP
187 #define PEGBOX_DOWN BUTTON_DOWN
188 #define PEGBOX_RIGHT BUTTON_RIGHT
189 #define PEGBOX_LEFT BUTTON_LEFT
191 #define SAVE_TEXT "SELECT"
192 #define QUIT_TEXT "POWER"
193 #define RESTART_TEXT "REC"
194 #define LVL_UP_TEXT "SCROLL BACK"
195 #define LVL_DOWN_TEXT "SCROLL FWD"
197 #elif CONFIG_KEYPAD == GIGABEAT_PAD
198 #define PEGBOX_SAVE BUTTON_SELECT
199 #define PEGBOX_QUIT BUTTON_POWER
200 #define PEGBOX_RESTART BUTTON_A
201 #define PEGBOX_LVL_UP BUTTON_VOL_UP
202 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
203 #define PEGBOX_UP BUTTON_UP
204 #define PEGBOX_DOWN BUTTON_DOWN
205 #define PEGBOX_RIGHT BUTTON_RIGHT
206 #define PEGBOX_LEFT BUTTON_LEFT
208 #define SAVE_TEXT "SELECT"
209 #define QUIT_TEXT "POWER"
210 #define RESTART_TEXT "A"
211 #define LVL_UP_TEXT "VOL+"
212 #define LVL_DOWN_TEXT "VOL-"
214 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
215 #define PEGBOX_SAVE BUTTON_SELECT
216 #define PEGBOX_QUIT BUTTON_BACK
217 #define PEGBOX_RESTART BUTTON_MENU
218 #define PEGBOX_LVL_UP BUTTON_VOL_UP
219 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
220 #define PEGBOX_UP BUTTON_UP
221 #define PEGBOX_DOWN BUTTON_DOWN
222 #define PEGBOX_RIGHT BUTTON_RIGHT
223 #define PEGBOX_LEFT BUTTON_LEFT
225 #define SAVE_TEXT "SELECT"
226 #define QUIT_TEXT "BACK"
227 #define RESTART_TEXT "MENU"
228 #define LVL_UP_TEXT "VOL+"
229 #define LVL_DOWN_TEXT "VOL-"
231 #elif CONFIG_KEYPAD == MROBE100_PAD
232 #define PEGBOX_SAVE BUTTON_SELECT
233 #define PEGBOX_QUIT BUTTON_POWER
234 #define PEGBOX_RESTART BUTTON_PLAY
235 #define PEGBOX_LVL_UP BUTTON_MENU
236 #define PEGBOX_LVL_DOWN BUTTON_DISPLAY
237 #define PEGBOX_UP BUTTON_UP
238 #define PEGBOX_DOWN BUTTON_DOWN
239 #define PEGBOX_RIGHT BUTTON_RIGHT
240 #define PEGBOX_LEFT BUTTON_LEFT
242 #define SAVE_TEXT "SELECT"
243 #define QUIT_TEXT "POWER"
244 #define RESTART_TEXT "PLAY"
245 #define LVL_UP_TEXT "MENU"
246 #define LVL_DOWN_TEXT "DISPLAY"
248 #elif CONFIG_KEYPAD == SANSA_C200_PAD
249 #define PEGBOX_SAVE BUTTON_SELECT
250 #define PEGBOX_QUIT BUTTON_POWER
251 #define PEGBOX_RESTART BUTTON_REC
252 #define PEGBOX_LVL_UP BUTTON_VOL_UP
253 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
254 #define PEGBOX_UP BUTTON_UP
255 #define PEGBOX_DOWN BUTTON_DOWN
256 #define PEGBOX_RIGHT BUTTON_RIGHT
257 #define PEGBOX_LEFT BUTTON_LEFT
259 #define SAVE_TEXT "SELECT"
260 #define QUIT_TEXT "POWER"
261 #define RESTART_TEXT "REC"
262 #define LVL_UP_TEXT "VOL+"
263 #define LVL_DOWN_TEXT "VOL-"
265 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
266 #define PEGBOX_SAVE BUTTON_RC_PLAY
267 #define PEGBOX_QUIT BUTTON_RC_REC
268 #define PEGBOX_RESTART BUTTON_RC_MODE
269 #define PEGBOX_LVL_UP BUTTON_VOL_UP
270 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
271 #define PEGBOX_UP BUTTON_RC_VOL_UP
272 #define PEGBOX_DOWN BUTTON_RC_VOL_DOWN
273 #define PEGBOX_RIGHT BUTTON_RC_FF
274 #define PEGBOX_LEFT BUTTON_RC_REW
276 #define SAVE_TEXT "REM. PLAY"
277 #define QUIT_TEXT "REM. REC"
278 #define RESTART_TEXT "REM. MODE"
279 #define LVL_UP_TEXT "VOL+"
280 #define LVL_DOWN_TEXT "VOL-"
282 #elif CONFIG_KEYPAD == COWOND2_PAD
283 #define PEGBOX_QUIT BUTTON_POWER
285 #define QUIT_TEXT "POWER"
287 #error Unsupported keymap!
290 #ifdef HAVE_TOUCHSCREEN
292 #define PEGBOX_QUIT BUTTON_TOPLEFT
295 #define PEGBOX_SAVE BUTTON_CENTER
297 #ifndef PEGBOX_RESTART
298 #define PEGBOX_RESTART BUTTON_TOPRIGHT
300 #ifndef PEGBOX_LVL_UP
301 #define PEGBOX_LVL_UP BUTTON_BOTTOMLEFT
303 #ifndef PEGBOX_LVL_DOWN
304 #define PEGBOX_LVL_DOWN BUTTON_BOTTOMRIGHT
307 #define PEGBOX_UP BUTTON_TOPMIDDLE
310 #define PEGBOX_DOWN BUTTON_BOTTOMMIDDLE
313 #define PEGBOX_RIGHT BUTTON_MIDRIGHT
316 #define PEGBOX_LEFT BUTTON_MIDLEFT
319 #define SAVE_TEXT "CENTER"
322 #define QUIT_TEXT "TOPLEFT"
325 #define RESTART_TEXT "TOPRIGHT"
328 #define LVL_UP_TEXT "BOTTOMLEFT"
330 #ifndef LVL_DOWN_TEXT
331 #define LVL_DOWN_TEXT "BOTTOMRIGHT"
336 /* get several sizes from the bitmaps */
337 #ifdef BMPWIDTH_pegbox_pieces
338 #define PIECE_WIDTH BMPWIDTH_pegbox_pieces
339 #define PIECE_HEIGHT (BMPHEIGHT_pegbox_pieces/7)
341 /* dummy numbers to avoid #error in dependency generation */
342 #define PIECE_WIDTH 50
343 #define PIECE_HEIGHT 10
345 #define BOARD_WIDTH (12*PIECE_WIDTH)
346 #define BOARD_HEIGHT (8*PIECE_HEIGHT)
349 /* define a wide layout where the statistics are alongside the board, not above
350 * base calculation on the piece bitmaps for the 8x12 board */
351 #if (LCD_WIDTH - BOARD_WIDTH) > (LCD_HEIGHT - BOARD_HEIGHT)
356 #define HEADER_WIDTH BMPWIDTH_pegbox_header
357 #define HEADER_HEIGHT BMPHEIGHT_pegbox_header
360 #if defined WIDE_LAYOUT
362 #if ((BOARD_WIDTH + HEADER_WIDTH + 4) <= LCD_WIDTH)
367 #define BOARD_Y (LCD_HEIGHT-BOARD_HEIGHT)/2
369 #if (LCD_WIDTH >= 132) && (LCD_HEIGHT >= 80)
371 #define LEVEL_TEXT_Y 14
372 #define PEGS_TEXT_Y 58
374 #error "Unsupported screen size"
377 #else /* "normal" layout */
379 #define BOARD_X (LCD_WIDTH-BOARD_WIDTH)/2
380 #if ((BOARD_HEIGHT + HEADER_HEIGHT + 4) <= LCD_HEIGHT)
381 #define BOARD_Y HEADER_HEIGHT+2
383 #define BOARD_Y HEADER_HEIGHT
387 #define LEVEL_TEXT_X 59
388 #define PEGS_TEXT_X 276
390 #elif LCD_WIDTH >= 240
391 #define LEVEL_TEXT_X 59
392 #define PEGS_TEXT_X 196
394 #elif LCD_WIDTH >= 220
395 #define LEVEL_TEXT_X 49
396 #define PEGS_TEXT_X 186
398 #elif LCD_WIDTH >= 176
399 #define LEVEL_TEXT_X 38
400 #define PEGS_TEXT_X 155
402 #elif LCD_WIDTH >= 160
403 #define LEVEL_TEXT_X 37
404 #define PEGS_TEXT_X 140
406 #elif LCD_WIDTH >= 138
407 #define LEVEL_TEXT_X 28
408 #define PEGS_TEXT_X 119
410 #elif LCD_WIDTH >= 128
411 #if HEADER_HEIGHT > 16
412 #define LEVEL_TEXT_X 26
413 #define PEGS_TEXT_X 107
416 #define LEVEL_TEXT_X 15
417 #define PEGS_TEXT_X 100
419 #endif /* HEADER_HEIGHT */
420 #elif LCD_WIDTH >= 112
421 #define LEVEL_TEXT_X 25
422 #define PEGS_TEXT_X 90
424 #endif /* LCD_WIDTH */
426 #endif /* WIDE_LAYOUT */
429 #ifdef HAVE_LCD_COLOR
430 #define BG_COLOR LCD_BLACK
431 #define TEXT_BG LCD_RGBPACK(189,189,189)
435 #ifdef HAVE_TOUCHSCREEN
436 #include "lib/touchscreen.h"
438 static struct ts_mapping main_menu_items
[5] =
440 {MENU_X
, MENU_Y
, ITEM_WIDTH
, ITEM_HEIGHT
},
441 {MENU_X
, MENU_Y
+ITEM_HEIGHT
, ITEM_WIDTH
, ITEM_HEIGHT
},
442 {MENU_X
, MENU_Y
+ITEM_HEIGHT
*2, ITEM_WIDTH
, ITEM_HEIGHT
},
443 {MENU_X
, MENU_Y
+ITEM_HEIGHT
*3, ITEM_WIDTH
, ITEM_HEIGHT
},
445 #if (LCD_WIDTH >= 138) && (LCD_HEIGHT > 110)
446 0, MENU_Y
+4*ITEM_HEIGHT
+8, SYSFONT_WIDTH
*28, SYSFONT_HEIGHT
447 #elif LCD_WIDTH > 112
448 0, LCD_HEIGHT
- 8, SYSFONT_WIDTH
*28, SYSFONT_HEIGHT
450 #error "Touchscreen isn't supported on non-bitmap screens!"
455 static struct ts_mappings main_menu
= {main_menu_items
, 5};
457 static struct ts_raster pegbox_raster
=
458 { BOARD_X
, BOARD_Y
, COLS
*PIECE_WIDTH
, ROWS
*PIECE_HEIGHT
,
459 PIECE_WIDTH
, PIECE_HEIGHT
};
460 static struct ts_raster_button_mapping pegbox_raster_btn
=
461 { &pegbox_raster
, false, false, true, false, true, {0, 0}, 0, 0, 0 };
464 struct game_context
{
466 unsigned int highlevel
;
467 signed int player_row
;
468 signed int player_col
;
469 unsigned int num_left
;
471 unsigned int playboard
[ROWS
][COLS
];
474 char levels
[NUM_LEVELS
][ROWS
][COLS
] = {
476 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
477 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
478 {1, 0, 0, 0, 7, 0, 0, 5, 0, 0, 0, 1,},
479 {1, 0, 0, 0, 0, 3, 3, 2, 0, 0, 0, 1,},
480 {1, 0, 0, 0, 4, 6, 0, 5, 0, 0, 0, 1,},
481 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
482 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
483 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
486 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
487 {1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 1,},
488 {1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1,},
489 {1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1,},
490 {7, 0, 0, 0, 2, 2, 5, 5, 0, 0, 0, 1,},
491 {1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1,},
492 {1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1,},
493 {1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 1,}},
496 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
497 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
498 {1, 0, 0, 0, 0, 0, 2, 0, 7, 0, 0, 0,},
499 {1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 2, 1,},
500 {1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1,},
501 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1,},
502 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
503 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
506 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
507 {6, 0, 4, 0, 2, 0, 2, 0, 0, 0, 0, 1,},
508 {6, 0, 3, 0, 5, 0, 2, 0, 0, 0, 0, 1,},
509 {6, 0, 5, 0, 4, 7, 2, 0, 0, 0, 0, 1,},
510 {6, 0, 2, 0, 4, 0, 2, 0, 3, 0, 0, 1,},
511 {6, 0, 4, 0, 5, 0, 2, 0, 0, 0, 0, 1,},
512 {6, 0, 5, 0, 4, 0, 2, 0, 0, 0, 0, 1,},
513 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
516 {{0, 6, 6, 0, 4, 6, 0, 0, 6, 0, 0, 0,},
517 {0, 6, 6, 0, 4, 4, 0, 0, 6, 0, 0, 2,},
518 {2, 6, 6, 0, 6, 6, 6, 0, 1, 2, 2, 2,},
519 {0, 6, 6, 0, 6, 4, 6, 0, 1, 2, 0, 2,},
520 {0, 6, 6, 0, 6, 7, 6, 5, 6, 0, 0, 0,},
521 {2, 6, 6, 0, 6, 6, 6, 0, 6, 0, 0, 0,},
522 {0, 6, 6, 0, 4, 0, 0, 0, 6, 0, 0, 0,},
523 {0, 6, 6, 0, 0, 5, 0, 0, 6, 5, 5, 0,}},
526 {{7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
527 {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,},
528 {2, 0, 0, 2, 0, 0, 0, 2, 2, 0, 0, 0,},
529 {0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 0,},
530 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
531 {0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1,},
532 {0, 3, 0, 0, 0, 0, 0, 0, 5, 4, 6, 0,},
533 {0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1,}},
536 {{1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1,},
537 {1, 1, 1, 6, 0, 0, 4, 6, 0, 1, 1, 1,},
538 {1, 1, 1, 1, 0, 1, 5, 1, 0, 1, 1, 1,},
539 {1, 1, 1, 2, 3, 3, 7, 4, 2, 6, 1, 1,},
540 {1, 1, 1, 1, 0, 1, 2, 1, 0, 0, 0, 1,},
541 {1, 1, 1, 1, 0, 0, 5, 0, 0, 1, 0, 1,},
542 {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1,},
543 {1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,}},
546 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
547 {0, 0, 3, 3, 3, 3, 3, 4, 3, 3, 0, 0,},
548 {0, 0, 3, 3, 3, 2, 3, 3, 5, 3, 0, 0,},
549 {7, 0, 3, 3, 3, 2, 3, 3, 4, 3, 0, 0,},
550 {0, 0, 3, 3, 4, 5, 3, 3, 3, 3, 0, 0,},
551 {0, 0, 3, 3, 5, 2, 3, 3, 3, 3, 0, 0,},
552 {0, 0, 3, 3, 2, 4, 3, 3, 3, 3, 0, 0,},
553 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
556 {{0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,},
557 {0, 3, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,},
558 {0, 0, 0, 0, 2, 4, 4, 3, 0, 1, 1, 0,},
559 {0, 1, 0, 0, 2, 1, 0, 0, 0, 1, 1, 1,},
560 {0, 0, 0, 2, 2, 7, 1, 0, 0, 0, 0, 2,},
561 {0, 0, 0, 0, 2, 1, 0, 0, 1, 1, 1, 1,},
562 {0, 3, 1, 0, 2, 5, 5, 0, 0, 0, 3, 0,},
563 {0, 0, 0, 0, 4, 1, 0, 0, 0, 0, 0, 0,}},
566 {{1, 1, 1, 1, 2, 1, 1, 1, 0, 0, 0, 0,},
567 {1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 7,},
568 {0, 0, 4, 0, 6, 6, 6, 0, 0, 0, 3, 0,},
569 {0, 3, 3, 0, 6, 6, 6, 0, 4, 3, 4, 0,},
570 {0, 3, 3, 0, 6, 6, 6, 0, 4, 3, 4, 0,},
571 {0, 0, 0, 0, 6, 6, 6, 0, 3, 0, 0, 0,},
572 {1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0,},
573 {1, 1, 1, 1, 1, 2, 1, 1, 0, 0, 0, 0,}},
576 {{1, 7, 1, 0, 1, 1, 6, 0, 0, 1, 1, 0,},
577 {1, 0, 0, 0, 5, 4, 6, 6, 0, 2, 2, 0,},
578 {1, 2, 1, 2, 0, 1, 6, 0, 0, 2, 2, 0,},
579 {1, 0, 0, 2, 0, 1, 0, 0, 0, 3, 3, 0,},
580 {1, 2, 1, 0, 0, 1, 0, 1, 0, 3, 3, 0,},
581 {0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0,},
582 {0, 3, 4, 3, 0, 1, 0, 1, 0, 0, 0, 0,},
583 {0, 0, 0, 0, 2, 2, 2, 1, 1, 1, 1, 1,}},
586 {{7, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,},
587 {1, 2, 1, 2, 1, 2, 1, 1, 0, 0, 0, 1,},
588 {0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1,},
589 {1, 2, 1, 2, 1, 2, 1, 0, 0, 0, 0, 1,},
590 {0, 0, 0, 0, 0, 0, 1, 1, 5, 5, 6, 1,},
591 {1, 2, 1, 2, 1, 2, 1, 1, 0, 2, 2, 1,},
592 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1,},
593 {1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1,}},
596 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
597 {0, 0, 4, 0, 2, 0, 5, 0, 4, 0, 0, 6,},
598 {0, 0, 2, 0, 5, 0, 2, 0, 4, 0, 0, 6,},
599 {7, 0, 3, 0, 4, 0, 5, 0, 4, 0, 0, 6,},
600 {0, 0, 5, 0, 4, 0, 2, 0, 4, 0, 0, 6,},
601 {0, 0, 4, 0, 2, 0, 5, 0, 4, 0, 0, 6,},
602 {0, 0, 3, 0, 3, 0, 2, 0, 4, 0, 0, 6,},
603 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
606 {{1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1,},
607 {1, 1, 0, 2, 0, 0, 4, 0, 0, 2, 0, 1,},
608 {1, 6, 0, 0, 5, 1, 0, 1, 1, 0, 0, 1,},
609 {1, 1, 1, 0, 0, 3, 5, 3, 0, 0, 1, 1,},
610 {1, 1, 0, 0, 1, 1, 0, 1, 5, 0, 0, 6,},
611 {1, 1, 0, 2, 0, 0, 4, 0, 0, 0, 7, 1,},
612 {1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1,},
613 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
616 {{0, 0, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
617 {0, 0, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
618 {0, 3, 4, 6, 0, 6, 0, 6, 0, 6, 0, 2,},
619 {0, 4, 0, 6, 0, 6, 4, 6, 0, 6, 0, 1,},
620 {0, 3, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
621 {7, 0, 0, 6, 4, 6, 0, 6, 0, 6, 0, 1,},
622 {0, 0, 4, 6, 0, 6, 0, 6, 4, 6, 0, 1,},
623 {0, 0, 4, 6, 0, 6, 0, 6, 0, 6, 0, 1,}}
627 /*****************************************************************************
628 * display_text() formats and outputs text.
629 ******************************************************************************/
630 static void display_text(char *str
, bool waitkey
)
635 int current_line
= 0;
636 int char_width
, char_height
;
637 int first_char_index
= 0;
645 rb
->lcd_clear_display();
647 rb
->lcd_getstringsize("a", &char_width
, &char_height
);
649 chars_by_line
= LCD_WIDTH
/ char_width
;
650 lines_by_screen
= LCD_HEIGHT
/ char_height
;
654 ptr_char
= str
+ first_char_index
;
658 while (i
< chars_by_line
)
671 *(ptr_line
++) = *ptr_char
;
673 if (*ptr_char
== '\n' || *ptr_char
== '\0')
679 if (chars_for_line
== 0)
682 line
[chars_for_line
] = '\0';
684 /* test if we have cut a word. If it is the case we don't have to */
686 if (i
== chars_by_line
&& chars_for_line
== chars_by_line
)
687 first_char_index
+= chars_for_line
;
689 first_char_index
+= chars_for_line
+ 1;
691 /* print the line on the screen */
692 rb
->lcd_putsxy(0, current_line
* char_height
, line
);
694 /* if the number of line showed on the screen is equals to the */
695 /* maximum number of line we can show, we wait for a key pressed to */
696 /* clear and show the remaining text. */
698 if (current_line
== lines_by_screen
|| *ptr_char
== '\0')
703 while (waitkey
&& !go_on
)
705 key
= rb
->button_get(true);
708 #ifdef HAVE_TOUCHSCREEN
709 case BUTTON_TOUCHSCREEN
:
718 /*if (rb->default_event_handler(key) == SYS_USB_CONNECTED)
727 rb
->lcd_clear_display();
729 } while (*ptr_char
!= '\0');
732 /*****************************************************************************
733 * draw_board() draws the game's current level.
734 ******************************************************************************/
735 static void draw_board(struct game_context
* pb
) {
736 unsigned int r
, c
, type
;
740 rb
->lcd_clear_display();
742 rb
->lcd_bitmap(pegbox_header
,LCD_WIDTH
-HEADER_WIDTH
,0,
743 HEADER_WIDTH
,LCD_HEIGHT
);
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
);
760 for (r
=0 ; r
< ROWS
; r
++) {
761 for (c
= 0 ; c
< COLS
; c
++) {
763 type
= pb
->playboard
[r
][c
];
770 rb
->lcd_bitmap_part(pegbox_pieces
, 0, (type
-1)*PIECE_HEIGHT
,
771 PIECE_WIDTH
, c
* PIECE_WIDTH
+ BOARD_X
,
772 r
* PIECE_HEIGHT
+ BOARD_Y
, PIECE_WIDTH
,
777 if(pb
->playboard
[r
][c
] == PLAYER
) {
781 else if (type
!= WALL
&& type
!= SPACE
&& type
!= HOLE
)
787 rb
->snprintf(str
, 3, "%d", pb
->level
);
788 rb
->lcd_putsxy(TEXT_X
, LEVEL_TEXT_Y
, str
);
789 rb
->snprintf(str
, 3, "%d", pb
->num_left
);
790 rb
->lcd_putsxy(TEXT_X
, PEGS_TEXT_Y
, str
);
792 rb
->snprintf(str
, 3, "%d", pb
->level
);
793 rb
->lcd_putsxy(LEVEL_TEXT_X
, TEXT_Y
, str
);
794 rb
->snprintf(str
, 3, "%d", pb
->num_left
);
795 rb
->lcd_putsxy(PEGS_TEXT_X
, TEXT_Y
, str
);
796 #endif /*WIDE_LAYOUT*/
798 #ifdef HAVE_LCD_COLOR
799 rb
->lcd_set_background(BG_COLOR
);
800 rb
->lcd_set_foreground(LCD_WHITE
);
802 /* print out the screen */
806 /*****************************************************************************
807 * load_level() loads the player's current level from the array and sets the
809 ******************************************************************************/
810 static void load_level(struct game_context
* pb
) {
813 for(r
= 0; r
< ROWS
; r
++)
814 for(c
= 0; c
< COLS
; c
++)
815 pb
->playboard
[r
][c
] = levels
[pb
->level
-1][r
][c
];
818 /*****************************************************************************
819 * new_piece() creates a new piece at a specified location. The player
820 * navigates through the pieces and selects one.
821 ******************************************************************************/
822 static void new_piece(struct game_context
* pb
, unsigned int x_loc
,
823 unsigned int y_loc
) {
827 pb
->playboard
[x_loc
][y_loc
] = TRIANGLE
;
831 button
= rb
->button_get(true);
832 #ifdef HAVE_TOUCHSCREEN
833 if(button
& BUTTON_TOUCHSCREEN
)
835 pegbox_raster_btn
.two_d_from
.y
= x_loc
;
836 pegbox_raster_btn
.two_d_from
.x
= y_loc
;
838 struct ts_raster_button_result ret
=
839 touchscreen_raster_map_button(&pegbox_raster_btn
,
840 rb
->button_get_data() >> 16,
841 rb
->button_get_data() & 0xffff,
843 if(ret
.action
== TS_ACTION_TWO_D_MOVEMENT
)
845 if(ret
.to
.x
> ret
.from
.x
)
847 else if(ret
.to
.x
< ret
.from
.x
)
848 button
= PEGBOX_DOWN
;
849 else if(ret
.to
.y
> ret
.from
.y
)
850 button
= PEGBOX_LEFT
;
851 else if(ret
.to
.y
< ret
.from
.y
)
852 button
= PEGBOX_RIGHT
;
854 else if(ret
.action
== TS_ACTION_CLICK
855 && (unsigned)ret
.to
.x
== y_loc
856 && (unsigned)ret
.to
.y
== x_loc
)
857 button
= PEGBOX_SAVE
;
862 case (PEGBOX_LEFT
|BUTTON_REPEAT
):
864 case (PEGBOX_DOWN
|BUTTON_REPEAT
):
865 if (pb
->playboard
[x_loc
][y_loc
] < 5)
866 pb
->playboard
[x_loc
][y_loc
]++;
868 pb
->playboard
[x_loc
][y_loc
] = TRIANGLE
;
871 case (PEGBOX_RIGHT
|BUTTON_REPEAT
):
873 case (PEGBOX_UP
|BUTTON_REPEAT
):
874 if (pb
->playboard
[x_loc
][y_loc
] > 2)
875 pb
->playboard
[x_loc
][y_loc
]--;
877 pb
->playboard
[x_loc
][y_loc
] = CIRCLE
;
886 /*****************************************************************************
887 * move_player() moves the player and pieces and updates the board accordingly.
888 ******************************************************************************/
889 static void move_player(struct game_context
* pb
, signed int x_dir
,
891 unsigned int type1
, type2
;
894 r
= pb
->player_row
+y_dir
;
895 c
= pb
->player_col
+x_dir
;
897 type1
= pb
->playboard
[r
][c
];
898 type2
= pb
->playboard
[r
+y_dir
][c
+x_dir
];
900 if (r
== ROWS
|| c
== COLS
|| r
< 0 || c
< 0 || type1
== WALL
)
902 else if(type1
!= SPACE
) {
903 if (type2
== WALL
|| r
+y_dir
== ROWS
|| c
+x_dir
== COLS
||
904 r
+y_dir
< 0 || c
+x_dir
< 0)
909 pb
->playboard
[pb
->player_row
][pb
->player_col
] = SPACE
;
910 pb
->player_row
+= y_dir
;
911 pb
->player_col
+= x_dir
;
915 rb
->splash(HZ
*2, "You fell down a hole!");
918 else if (type1
== SPACE
)
919 pb
->playboard
[r
][c
] = PLAYER
;
921 pb
->playboard
[r
][c
] = PLAYER
;
923 if (type1
== TRIANGLE
)
924 pb
->playboard
[r
+y_dir
][c
+x_dir
] = WALL
;
925 else if (type1
== CROSS
) {
926 pb
->playboard
[r
][c
] = SPACE
;
927 new_piece(pb
, r
+y_dir
, c
+x_dir
);
928 pb
->playboard
[r
][c
] = PLAYER
;
931 pb
->playboard
[r
+y_dir
][c
+x_dir
] = SPACE
;
933 else if (type2
== SPACE
)
934 pb
->playboard
[r
+y_dir
][c
+x_dir
] = type1
;
935 else if (type2
== HOLE
) {
937 pb
->playboard
[r
+y_dir
][c
+x_dir
] = SPACE
;
940 rb
->splash(HZ
*2, "Illegal Move!");
948 /*****************************************************************************
949 * pegbox_loadgame() loads the saved game and returns load success.
950 ******************************************************************************/
951 static bool pegbox_loadgame(struct game_context
* pb
) {
956 fd
= rb
->open(SAVE_FILE
, O_RDONLY
);
957 if(fd
< 0) return loaded
;
959 /* read in saved game */
961 if(rb
->read(fd
, &pb
->level
, sizeof(pb
->level
)) <= 0) break;
962 if(rb
->read(fd
, &pb
->playboard
, sizeof(pb
->playboard
)) <= 0)
974 /*****************************************************************************
975 * pegbox_savegame() saves the current game state.
976 ******************************************************************************/
977 static void pegbox_savegame(struct game_context
* pb
) {
980 /* write out the game state to the save file */
981 fd
= rb
->open(SAVE_FILE
, O_WRONLY
|O_CREAT
);
982 rb
->write(fd
, &pb
->level
, sizeof(pb
->level
));
983 rb
->write(fd
, &pb
->playboard
, sizeof(pb
->playboard
));
987 /*****************************************************************************
988 * pegbox_loaddata() loads the level and highlevel and returns load success.
989 ******************************************************************************/
990 static void pegbox_loaddata(struct game_context
* pb
) {
994 fd
= rb
->open(DATA_FILE
, O_RDONLY
);
1001 /* read in saved game */
1003 if(rb
->read(fd
, &pb
->level
, sizeof(pb
->level
)) <= 0) break;
1004 if(rb
->read(fd
, &pb
->highlevel
, sizeof(pb
->highlevel
)) <= 0) break;
1012 /*****************************************************************************
1013 * pegbox_savedata() saves the level and highlevel.
1014 ******************************************************************************/
1015 static void pegbox_savedata(struct game_context
* pb
) {
1018 /* write out the game state to the save file */
1019 fd
= rb
->open(DATA_FILE
, O_WRONLY
|O_CREAT
);
1020 rb
->write(fd
, &pb
->level
, sizeof(pb
->level
));
1021 rb
->write(fd
, &pb
->highlevel
, sizeof(pb
->highlevel
));
1025 /*****************************************************************************
1026 * pegbox_callback() is the default event handler callback which is called
1027 * on usb connect and shutdown.
1028 ******************************************************************************/
1029 static void pegbox_callback(void* param
) {
1030 struct game_context
* pb
= (struct game_context
*) param
;
1031 rb
->splash(HZ
, "Saving data...");
1032 pegbox_savedata(pb
);
1035 /*****************************************************************************
1036 * pegbox_menu() is the initial menu at the start of the game.
1037 ******************************************************************************/
1038 static unsigned int pegbox_menu(struct game_context
* pb
) {
1041 unsigned int startlevel
= 1, loc
= 0;
1042 bool breakout
= false, can_resume
= false;
1044 if (pb
->num_left
> 0 || pb
->save_exist
)
1048 #if LCD_HEIGHT >= 80
1049 rb
->lcd_clear_display();
1050 rb
->lcd_bitmap(pegbox_menu_top
,0,0,LCD_WIDTH
, BMPHEIGHT_pegbox_menu_top
);
1054 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
, ITEM_WIDTH
,
1055 MENU_X
, MENU_Y
, ITEM_WIDTH
, ITEM_HEIGHT
);
1058 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, 0, ITEM_WIDTH
,
1059 MENU_X
, MENU_Y
, ITEM_WIDTH
, ITEM_HEIGHT
);
1063 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*3, ITEM_WIDTH
,
1064 MENU_X
, MENU_Y
+ITEM_HEIGHT
, ITEM_WIDTH
, ITEM_HEIGHT
);
1067 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*2, ITEM_WIDTH
,
1068 MENU_X
, MENU_Y
+ITEM_HEIGHT
, ITEM_WIDTH
, ITEM_HEIGHT
);
1072 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*4, ITEM_WIDTH
,
1073 MENU_X
, MENU_Y
+ITEM_HEIGHT
, ITEM_WIDTH
, ITEM_HEIGHT
);
1077 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*6, ITEM_WIDTH
,
1078 MENU_X
, MENU_Y
+ITEM_HEIGHT
*2, ITEM_WIDTH
, ITEM_HEIGHT
);
1081 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*5, ITEM_WIDTH
,
1082 MENU_X
, MENU_Y
+ITEM_HEIGHT
*2, ITEM_WIDTH
, ITEM_HEIGHT
);
1086 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*8, ITEM_WIDTH
,
1087 MENU_X
, MENU_Y
+ITEM_HEIGHT
*3, ITEM_WIDTH
, ITEM_HEIGHT
);
1090 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*7, ITEM_WIDTH
,
1091 MENU_X
, MENU_Y
+ITEM_HEIGHT
*3, ITEM_WIDTH
, ITEM_HEIGHT
);
1095 rb
->lcd_clear_display();
1096 rb
->lcd_getstringsize("PegBox", &w
, &h
);
1097 rb
->lcd_putsxy((LCD_WIDTH
-w
)/2, 0, "PegBox");
1098 rb
->lcd_putsxy((LCD_WIDTH
)/4, 16, "New Game");
1099 rb
->lcd_putsxy((LCD_WIDTH
)/4, 24, "Resume");
1100 rb
->lcd_putsxy((LCD_WIDTH
)/4, 32, "Help");
1101 rb
->lcd_putsxy((LCD_WIDTH
)/4, 40, "Quit");
1104 rb
->lcd_hline((LCD_WIDTH
)/4, (LCD_WIDTH
)/4+30, 28);
1106 rb
->lcd_putsxy((LCD_WIDTH
)/4-8, loc
*8+16, "*");
1110 rb
->snprintf(str
, 28, "Start on level %d of %d", startlevel
,
1112 #if LCD_HEIGHT > 110
1113 rb
->lcd_putsxy(0, MENU_Y
+4*ITEM_HEIGHT
+8, str
);
1114 #elif LCD_HEIGHT > 64
1115 rb
->lcd_putsxy(0, LCD_HEIGHT
- 8, str
);
1117 rb
->lcd_puts_scroll(0, 7, str
);
1121 /* handle menu button presses */
1122 button
= rb
->button_get(true);
1124 #ifdef HAVE_TOUCHSCREEN
1125 if(button
& BUTTON_TOUCHSCREEN
)
1127 unsigned int result
= touchscreen_map(&main_menu
,
1128 rb
->button_get_data() >> 16,
1129 rb
->button_get_data() & 0xffff);
1130 if(result
!= (unsigned)-1 && button
& BUTTON_REL
)
1133 button
= PEGBOX_LVL_UP
;
1137 button
= PEGBOX_RIGHT
;
1145 case PEGBOX_SAVE
: /* start playing */
1149 pb
->level
= startlevel
;
1152 else if (loc
== 1 && can_resume
) {
1155 rb
->remove(SAVE_FILE
);
1156 pb
->save_exist
= false;
1161 display_text("How to Play\nTo beat each level, you must "
1162 "destroy all of the pegs. If two like pegs are "
1163 "pushed into each other they disappear except "
1164 "for triangles which form a solid block and "
1165 "crosses which allow you to choose a "
1166 "replacement block.\n\n"
1169 RESTART_TEXT
" to restart level\n"
1170 LVL_UP_TEXT
" to go up a level\n"
1171 LVL_DOWN_TEXT
" to go down a level\n"
1172 SAVE_TEXT
" to select/save\n"
1173 QUIT_TEXT
" to quit\n",true);
1175 RESTART_TEXT
": restart\n"
1176 LVL_UP_TEXT
": level up\n"
1177 LVL_DOWN_TEXT
" level down\n"
1178 SAVE_TEXT
" select/save\n"
1179 QUIT_TEXT
" quit\n",true);
1185 case PEGBOX_QUIT
: /* quit program */
1188 case (PEGBOX_UP
|BUTTON_REPEAT
):
1194 if (!can_resume
&& loc
== 1) {
1200 case (PEGBOX_DOWN
|BUTTON_REPEAT
):
1206 if (!can_resume
&& loc
== 1) {
1211 case (PEGBOX_LVL_UP
|BUTTON_REPEAT
):
1212 case PEGBOX_LVL_UP
: /* increase starting level */
1213 if(startlevel
>= pb
->highlevel
) {
1220 /* only for targets with enough buttons */
1221 #ifdef PEGBOX_LVL_DOWN
1222 case (PEGBOX_LVL_DOWN
|BUTTON_REPEAT
):
1223 case PEGBOX_LVL_DOWN
: /* decrease starting level */
1224 if(startlevel
<= 1) {
1225 startlevel
= pb
->highlevel
;
1232 if(rb
->default_event_handler_ex(button
, pegbox_callback
,
1233 (void*) pb
) == SYS_USB_CONNECTED
)
1244 /*****************************************************************************
1245 * pegbox() is the main game subroutine, it returns the final game status.
1246 ******************************************************************************/
1247 static int pegbox(struct game_context
* pb
) {
1250 /********************
1252 ********************/
1253 temp_var
= pegbox_menu(pb
);
1254 if (temp_var
== PB_QUIT
|| temp_var
== PB_USB
)
1258 temp_var
= rb
->button_get(true);
1259 #ifdef HAVE_TOUCHSCREEN
1260 if(temp_var
& BUTTON_TOUCHSCREEN
)
1262 pegbox_raster_btn
.two_d_from
.y
= pb
->player_row
;
1263 pegbox_raster_btn
.two_d_from
.x
= pb
->player_col
;
1265 struct ts_raster_button_result ret
=
1266 touchscreen_raster_map_button(&pegbox_raster_btn
,
1267 rb
->button_get_data() >> 16,
1268 rb
->button_get_data() & 0xffff,
1270 if(ret
.action
== TS_ACTION_TWO_D_MOVEMENT
)
1271 move_player(pb
, ret
.to
.x
- ret
.from
.x
, ret
.to
.y
- ret
.from
.y
);
1275 case PEGBOX_LEFT
: /* move cursor left */
1276 case (PEGBOX_LEFT
|BUTTON_REPEAT
):
1277 move_player(pb
, -1, 0);
1280 case PEGBOX_RIGHT
: /* move cursor right */
1281 case (PEGBOX_RIGHT
|BUTTON_REPEAT
):
1282 move_player(pb
, 1, 0);
1285 case PEGBOX_DOWN
: /* move cursor down */
1286 case (PEGBOX_DOWN
|BUTTON_REPEAT
):
1287 move_player(pb
, 0, 1);
1290 case PEGBOX_UP
: /* move cursor up */
1291 case (PEGBOX_UP
|BUTTON_REPEAT
):
1292 move_player(pb
, 0, -1);
1295 case PEGBOX_SAVE
: /* save and end game */
1296 rb
->splash(HZ
, "Saving game...");
1297 pegbox_savegame(pb
);
1298 /* fall through to PEGBOX_QUIT */
1303 case PEGBOX_RESTART
:
1308 case (PEGBOX_LVL_UP
|BUTTON_REPEAT
):
1310 if(pb
->level
>= pb
->highlevel
) {
1319 /* only for targets with enough buttons */
1320 #ifdef PEGBOX_LVL_DOWN
1321 case (PEGBOX_LVL_DOWN
|BUTTON_REPEAT
):
1322 case PEGBOX_LVL_DOWN
:
1323 if(pb
->level
<= 1) {
1324 pb
->level
= pb
->highlevel
;
1335 if(pb
->num_left
== 0) {
1336 rb
->splash(HZ
*2, "Nice Pegging!");
1337 if(pb
->level
== NUM_LEVELS
) {
1339 rb
->splash(HZ
*2, "You Won!");
1348 if(pb
->level
> pb
->highlevel
)
1349 pb
->highlevel
= pb
->level
;
1358 /*****************************************************************************
1359 * plugin entry point.
1360 ******************************************************************************/
1361 enum plugin_status
plugin_start(const struct plugin_api
* api
, const void* parameter
) {
1363 struct game_context pb
;
1368 rb
->lcd_setfont(FONT_SYSFIXED
);
1370 rb
->lcd_set_backdrop(NULL
);
1372 #ifdef HAVE_LCD_COLOR
1373 rb
->lcd_set_foreground(LCD_WHITE
);
1374 rb
->lcd_set_background(BG_COLOR
);
1377 rb
->splash(0, "Loading...");
1378 pegbox_loaddata(&pb
);
1379 pb
.save_exist
= pegbox_loadgame(&pb
);
1382 rb
->lcd_clear_display();
1386 switch(pegbox(&pb
)){
1391 rb
->lcd_setfont(FONT_UI
);
1392 return PLUGIN_USB_CONNECTED
;
1395 rb
->splash(HZ
, "Saving data...");
1396 pegbox_savedata(&pb
);
1405 rb
->lcd_setfont(FONT_UI
);