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 #define PIECE_WIDTH BMPWIDTH_pegbox_pieces
338 #define PIECE_HEIGHT (BMPHEIGHT_pegbox_pieces/7)
339 #define BOARD_WIDTH (12*PIECE_WIDTH)
340 #define BOARD_HEIGHT (8*PIECE_HEIGHT)
343 /* define a wide layout where the statistics are alongside the board, not above
344 * base calculation on the piece bitmaps for the 8x12 board */
345 #if (LCD_WIDTH - BOARD_WIDTH) > (LCD_HEIGHT - BOARD_HEIGHT)
350 #define HEADER_WIDTH BMPWIDTH_pegbox_header
351 #define HEADER_HEIGHT BMPHEIGHT_pegbox_header
354 #if defined WIDE_LAYOUT
356 #if ((BOARD_WIDTH + HEADER_WIDTH + 4) <= LCD_WIDTH)
361 #define BOARD_Y (LCD_HEIGHT-BOARD_HEIGHT)/2
363 #if (LCD_WIDTH >= 132) && (LCD_HEIGHT >= 80)
365 #define LEVEL_TEXT_Y 14
366 #define PEGS_TEXT_Y 58
368 #error "Unsupported screen size"
371 #else /* "normal" layout */
373 #define BOARD_X (LCD_WIDTH-BOARD_WIDTH)/2
374 #if ((BOARD_HEIGHT + HEADER_HEIGHT + 4) <= LCD_HEIGHT)
375 #define BOARD_Y HEADER_HEIGHT+2
377 #define BOARD_Y HEADER_HEIGHT
381 #define LEVEL_TEXT_X 59
382 #define PEGS_TEXT_X 276
384 #elif LCD_WIDTH >= 240
385 #define LEVEL_TEXT_X 59
386 #define PEGS_TEXT_X 196
388 #elif LCD_WIDTH >= 220
389 #define LEVEL_TEXT_X 49
390 #define PEGS_TEXT_X 186
392 #elif LCD_WIDTH >= 176
393 #define LEVEL_TEXT_X 38
394 #define PEGS_TEXT_X 155
396 #elif LCD_WIDTH >= 160
397 #define LEVEL_TEXT_X 37
398 #define PEGS_TEXT_X 140
400 #elif LCD_WIDTH >= 138
401 #define LEVEL_TEXT_X 28
402 #define PEGS_TEXT_X 119
404 #elif LCD_WIDTH >= 128
405 #if HEADER_HEIGHT > 16
406 #define LEVEL_TEXT_X 26
407 #define PEGS_TEXT_X 107
410 #define LEVEL_TEXT_X 15
411 #define PEGS_TEXT_X 100
413 #endif /* HEADER_HEIGHT */
414 #elif LCD_WIDTH >= 112
415 #define LEVEL_TEXT_X 25
416 #define PEGS_TEXT_X 90
418 #endif /* LCD_WIDTH */
420 #endif /* WIDE_LAYOUT */
423 #ifdef HAVE_LCD_COLOR
424 #define BG_COLOR LCD_BLACK
425 #define TEXT_BG LCD_RGBPACK(189,189,189)
429 #ifdef HAVE_TOUCHSCREEN
430 #include "lib/touchscreen.h"
432 static struct ts_mapping main_menu_items
[5] =
434 {MENU_X
, MENU_Y
, ITEM_WIDTH
, ITEM_HEIGHT
},
435 {MENU_X
, MENU_Y
+ITEM_HEIGHT
, ITEM_WIDTH
, ITEM_HEIGHT
},
436 {MENU_X
, MENU_Y
+ITEM_HEIGHT
*2, ITEM_WIDTH
, ITEM_HEIGHT
},
437 {MENU_X
, MENU_Y
+ITEM_HEIGHT
*3, ITEM_WIDTH
, ITEM_HEIGHT
},
439 #if (LCD_WIDTH >= 138) && (LCD_HEIGHT > 110)
440 0, MENU_Y
+4*ITEM_HEIGHT
+8, SYSFONT_WIDTH
*28, SYSFONT_HEIGHT
441 #elif LCD_WIDTH > 112
442 0, LCD_HEIGHT
- 8, SYSFONT_WIDTH
*28, SYSFONT_HEIGHT
444 #error "Touchscreen isn't supported on non-bitmap screens!"
449 static struct ts_mappings main_menu
= {main_menu_items
, 5};
451 static struct ts_raster pegbox_raster
=
452 { BOARD_X
, BOARD_Y
, COLS
*PIECE_WIDTH
, ROWS
*PIECE_HEIGHT
,
453 PIECE_WIDTH
, PIECE_HEIGHT
};
454 static struct ts_raster_button_mapping pegbox_raster_btn
=
455 { &pegbox_raster
, false, false, true, false, true, {0, 0}, 0, 0, 0 };
458 struct game_context
{
460 unsigned int highlevel
;
461 signed int player_row
;
462 signed int player_col
;
463 unsigned int num_left
;
465 unsigned int playboard
[ROWS
][COLS
];
468 char levels
[NUM_LEVELS
][ROWS
][COLS
] = {
470 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
471 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
472 {1, 0, 0, 0, 7, 0, 0, 5, 0, 0, 0, 1,},
473 {1, 0, 0, 0, 0, 3, 3, 2, 0, 0, 0, 1,},
474 {1, 0, 0, 0, 4, 6, 0, 5, 0, 0, 0, 1,},
475 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
476 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
477 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
480 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
481 {1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 1,},
482 {1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1,},
483 {1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1,},
484 {7, 0, 0, 0, 2, 2, 5, 5, 0, 0, 0, 1,},
485 {1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1,},
486 {1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1,},
487 {1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 1,}},
490 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
491 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
492 {1, 0, 0, 0, 0, 0, 2, 0, 7, 0, 0, 0,},
493 {1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 2, 1,},
494 {1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1,},
495 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 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,}},
500 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
501 {6, 0, 4, 0, 2, 0, 2, 0, 0, 0, 0, 1,},
502 {6, 0, 3, 0, 5, 0, 2, 0, 0, 0, 0, 1,},
503 {6, 0, 5, 0, 4, 7, 2, 0, 0, 0, 0, 1,},
504 {6, 0, 2, 0, 4, 0, 2, 0, 3, 0, 0, 1,},
505 {6, 0, 4, 0, 5, 0, 2, 0, 0, 0, 0, 1,},
506 {6, 0, 5, 0, 4, 0, 2, 0, 0, 0, 0, 1,},
507 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
510 {{0, 6, 6, 0, 4, 6, 0, 0, 6, 0, 0, 0,},
511 {0, 6, 6, 0, 4, 4, 0, 0, 6, 0, 0, 2,},
512 {2, 6, 6, 0, 6, 6, 6, 0, 1, 2, 2, 2,},
513 {0, 6, 6, 0, 6, 4, 6, 0, 1, 2, 0, 2,},
514 {0, 6, 6, 0, 6, 7, 6, 5, 6, 0, 0, 0,},
515 {2, 6, 6, 0, 6, 6, 6, 0, 6, 0, 0, 0,},
516 {0, 6, 6, 0, 4, 0, 0, 0, 6, 0, 0, 0,},
517 {0, 6, 6, 0, 0, 5, 0, 0, 6, 5, 5, 0,}},
520 {{7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
521 {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,},
522 {2, 0, 0, 2, 0, 0, 0, 2, 2, 0, 0, 0,},
523 {0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 0,},
524 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
525 {0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1,},
526 {0, 3, 0, 0, 0, 0, 0, 0, 5, 4, 6, 0,},
527 {0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1,}},
530 {{1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1,},
531 {1, 1, 1, 6, 0, 0, 4, 6, 0, 1, 1, 1,},
532 {1, 1, 1, 1, 0, 1, 5, 1, 0, 1, 1, 1,},
533 {1, 1, 1, 2, 3, 3, 7, 4, 2, 6, 1, 1,},
534 {1, 1, 1, 1, 0, 1, 2, 1, 0, 0, 0, 1,},
535 {1, 1, 1, 1, 0, 0, 5, 0, 0, 1, 0, 1,},
536 {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1,},
537 {1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,}},
540 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
541 {0, 0, 3, 3, 3, 3, 3, 4, 3, 3, 0, 0,},
542 {0, 0, 3, 3, 3, 2, 3, 3, 5, 3, 0, 0,},
543 {7, 0, 3, 3, 3, 2, 3, 3, 4, 3, 0, 0,},
544 {0, 0, 3, 3, 4, 5, 3, 3, 3, 3, 0, 0,},
545 {0, 0, 3, 3, 5, 2, 3, 3, 3, 3, 0, 0,},
546 {0, 0, 3, 3, 2, 4, 3, 3, 3, 3, 0, 0,},
547 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
550 {{0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,},
551 {0, 3, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,},
552 {0, 0, 0, 0, 2, 4, 4, 3, 0, 1, 1, 0,},
553 {0, 1, 0, 0, 2, 1, 0, 0, 0, 1, 1, 1,},
554 {0, 0, 0, 2, 2, 7, 1, 0, 0, 0, 0, 2,},
555 {0, 0, 0, 0, 2, 1, 0, 0, 1, 1, 1, 1,},
556 {0, 3, 1, 0, 2, 5, 5, 0, 0, 0, 3, 0,},
557 {0, 0, 0, 0, 4, 1, 0, 0, 0, 0, 0, 0,}},
560 {{1, 1, 1, 1, 2, 1, 1, 1, 0, 0, 0, 0,},
561 {1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 7,},
562 {0, 0, 4, 0, 6, 6, 6, 0, 0, 0, 3, 0,},
563 {0, 3, 3, 0, 6, 6, 6, 0, 4, 3, 4, 0,},
564 {0, 3, 3, 0, 6, 6, 6, 0, 4, 3, 4, 0,},
565 {0, 0, 0, 0, 6, 6, 6, 0, 3, 0, 0, 0,},
566 {1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0,},
567 {1, 1, 1, 1, 1, 2, 1, 1, 0, 0, 0, 0,}},
570 {{1, 7, 1, 0, 1, 1, 6, 0, 0, 1, 1, 0,},
571 {1, 0, 0, 0, 5, 4, 6, 6, 0, 2, 2, 0,},
572 {1, 2, 1, 2, 0, 1, 6, 0, 0, 2, 2, 0,},
573 {1, 0, 0, 2, 0, 1, 0, 0, 0, 3, 3, 0,},
574 {1, 2, 1, 0, 0, 1, 0, 1, 0, 3, 3, 0,},
575 {0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0,},
576 {0, 3, 4, 3, 0, 1, 0, 1, 0, 0, 0, 0,},
577 {0, 0, 0, 0, 2, 2, 2, 1, 1, 1, 1, 1,}},
580 {{7, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,},
581 {1, 2, 1, 2, 1, 2, 1, 1, 0, 0, 0, 1,},
582 {0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1,},
583 {1, 2, 1, 2, 1, 2, 1, 0, 0, 0, 0, 1,},
584 {0, 0, 0, 0, 0, 0, 1, 1, 5, 5, 6, 1,},
585 {1, 2, 1, 2, 1, 2, 1, 1, 0, 2, 2, 1,},
586 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1,},
587 {1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1,}},
590 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
591 {0, 0, 4, 0, 2, 0, 5, 0, 4, 0, 0, 6,},
592 {0, 0, 2, 0, 5, 0, 2, 0, 4, 0, 0, 6,},
593 {7, 0, 3, 0, 4, 0, 5, 0, 4, 0, 0, 6,},
594 {0, 0, 5, 0, 4, 0, 2, 0, 4, 0, 0, 6,},
595 {0, 0, 4, 0, 2, 0, 5, 0, 4, 0, 0, 6,},
596 {0, 0, 3, 0, 3, 0, 2, 0, 4, 0, 0, 6,},
597 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
600 {{1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1,},
601 {1, 1, 0, 2, 0, 0, 4, 0, 0, 2, 0, 1,},
602 {1, 6, 0, 0, 5, 1, 0, 1, 1, 0, 0, 1,},
603 {1, 1, 1, 0, 0, 3, 5, 3, 0, 0, 1, 1,},
604 {1, 1, 0, 0, 1, 1, 0, 1, 5, 0, 0, 6,},
605 {1, 1, 0, 2, 0, 0, 4, 0, 0, 0, 7, 1,},
606 {1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1,},
607 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
610 {{0, 0, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
611 {0, 0, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
612 {0, 3, 4, 6, 0, 6, 0, 6, 0, 6, 0, 2,},
613 {0, 4, 0, 6, 0, 6, 4, 6, 0, 6, 0, 1,},
614 {0, 3, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
615 {7, 0, 0, 6, 4, 6, 0, 6, 0, 6, 0, 1,},
616 {0, 0, 4, 6, 0, 6, 0, 6, 4, 6, 0, 1,},
617 {0, 0, 4, 6, 0, 6, 0, 6, 0, 6, 0, 1,}}
621 /*****************************************************************************
622 * display_text() formats and outputs text.
623 ******************************************************************************/
624 static void display_text(char *str
, bool waitkey
)
629 int current_line
= 0;
630 int char_width
, char_height
;
631 int first_char_index
= 0;
639 rb
->lcd_clear_display();
641 rb
->lcd_getstringsize("a", &char_width
, &char_height
);
643 chars_by_line
= LCD_WIDTH
/ char_width
;
644 lines_by_screen
= LCD_HEIGHT
/ char_height
;
648 ptr_char
= str
+ first_char_index
;
652 while (i
< chars_by_line
)
665 *(ptr_line
++) = *ptr_char
;
667 if (*ptr_char
== '\n' || *ptr_char
== '\0')
673 if (chars_for_line
== 0)
676 line
[chars_for_line
] = '\0';
678 /* test if we have cut a word. If it is the case we don't have to */
680 if (i
== chars_by_line
&& chars_for_line
== chars_by_line
)
681 first_char_index
+= chars_for_line
;
683 first_char_index
+= chars_for_line
+ 1;
685 /* print the line on the screen */
686 rb
->lcd_putsxy(0, current_line
* char_height
, line
);
688 /* if the number of line showed on the screen is equals to the */
689 /* maximum number of line we can show, we wait for a key pressed to */
690 /* clear and show the remaining text. */
692 if (current_line
== lines_by_screen
|| *ptr_char
== '\0')
697 while (waitkey
&& !go_on
)
699 key
= rb
->button_get(true);
702 #ifdef HAVE_TOUCHSCREEN
703 case BUTTON_TOUCHSCREEN
:
712 /*if (rb->default_event_handler(key) == SYS_USB_CONNECTED)
721 rb
->lcd_clear_display();
723 } while (*ptr_char
!= '\0');
726 /*****************************************************************************
727 * draw_board() draws the game's current level.
728 ******************************************************************************/
729 static void draw_board(struct game_context
* pb
) {
730 unsigned int r
, c
, type
;
734 rb
->lcd_clear_display();
736 rb
->lcd_bitmap(pegbox_header
,LCD_WIDTH
-HEADER_WIDTH
,0,
737 HEADER_WIDTH
,LCD_HEIGHT
);
739 rb
->lcd_bitmap(pegbox_header
,(LCD_WIDTH
-HEADER_WIDTH
)/2,0,
740 HEADER_WIDTH
, HEADER_HEIGHT
);
741 #endif /* WIDE_LAYOUT */
743 #if ((BOARD_HEIGHT + HEADER_HEIGHT + 4) <= LCD_HEIGHT)
744 rb
->lcd_drawrect(BOARD_X
-2,BOARD_Y
-2,BOARD_WIDTH
+4,BOARD_HEIGHT
+4);
745 #endif /* enough space for a frame? */
747 #ifdef HAVE_LCD_COLOR
748 rb
->lcd_set_foreground(LCD_WHITE
);
749 rb
->lcd_fillrect(BOARD_X
-1,BOARD_Y
-1,BOARD_WIDTH
+2,BOARD_HEIGHT
+2);
750 rb
->lcd_set_foreground(LCD_BLACK
);
751 rb
->lcd_set_background(TEXT_BG
);
754 for (r
=0 ; r
< ROWS
; r
++) {
755 for (c
= 0 ; c
< COLS
; c
++) {
757 type
= pb
->playboard
[r
][c
];
764 rb
->lcd_bitmap_part(pegbox_pieces
, 0, (type
-1)*PIECE_HEIGHT
,
765 PIECE_WIDTH
, c
* PIECE_WIDTH
+ BOARD_X
,
766 r
* PIECE_HEIGHT
+ BOARD_Y
, PIECE_WIDTH
,
771 if(pb
->playboard
[r
][c
] == PLAYER
) {
775 else if (type
!= WALL
&& type
!= SPACE
&& type
!= HOLE
)
781 rb
->snprintf(str
, 3, "%d", pb
->level
);
782 rb
->lcd_putsxy(TEXT_X
, LEVEL_TEXT_Y
, str
);
783 rb
->snprintf(str
, 3, "%d", pb
->num_left
);
784 rb
->lcd_putsxy(TEXT_X
, PEGS_TEXT_Y
, str
);
786 rb
->snprintf(str
, 3, "%d", pb
->level
);
787 rb
->lcd_putsxy(LEVEL_TEXT_X
, TEXT_Y
, str
);
788 rb
->snprintf(str
, 3, "%d", pb
->num_left
);
789 rb
->lcd_putsxy(PEGS_TEXT_X
, TEXT_Y
, str
);
790 #endif /*WIDE_LAYOUT*/
792 #ifdef HAVE_LCD_COLOR
793 rb
->lcd_set_background(BG_COLOR
);
794 rb
->lcd_set_foreground(LCD_WHITE
);
796 /* print out the screen */
800 /*****************************************************************************
801 * load_level() loads the player's current level from the array and sets the
803 ******************************************************************************/
804 static void load_level(struct game_context
* pb
) {
807 for(r
= 0; r
< ROWS
; r
++)
808 for(c
= 0; c
< COLS
; c
++)
809 pb
->playboard
[r
][c
] = levels
[pb
->level
-1][r
][c
];
812 /*****************************************************************************
813 * new_piece() creates a new piece at a specified location. The player
814 * navigates through the pieces and selects one.
815 ******************************************************************************/
816 static void new_piece(struct game_context
* pb
, unsigned int x_loc
,
817 unsigned int y_loc
) {
821 pb
->playboard
[x_loc
][y_loc
] = TRIANGLE
;
825 button
= rb
->button_get(true);
826 #ifdef HAVE_TOUCHSCREEN
827 if(button
& BUTTON_TOUCHSCREEN
)
829 pegbox_raster_btn
.two_d_from
.y
= x_loc
;
830 pegbox_raster_btn
.two_d_from
.x
= y_loc
;
832 struct ts_raster_button_result ret
=
833 touchscreen_raster_map_button(&pegbox_raster_btn
,
834 rb
->button_get_data() >> 16,
835 rb
->button_get_data() & 0xffff,
837 if(ret
.action
== TS_ACTION_TWO_D_MOVEMENT
)
839 if(ret
.to
.x
> ret
.from
.x
)
841 else if(ret
.to
.x
< ret
.from
.x
)
842 button
= PEGBOX_DOWN
;
843 else if(ret
.to
.y
> ret
.from
.y
)
844 button
= PEGBOX_LEFT
;
845 else if(ret
.to
.y
< ret
.from
.y
)
846 button
= PEGBOX_RIGHT
;
848 else if(ret
.action
== TS_ACTION_CLICK
849 && (unsigned)ret
.to
.x
== y_loc
850 && (unsigned)ret
.to
.y
== x_loc
)
851 button
= PEGBOX_SAVE
;
856 case (PEGBOX_LEFT
|BUTTON_REPEAT
):
858 case (PEGBOX_DOWN
|BUTTON_REPEAT
):
859 if (pb
->playboard
[x_loc
][y_loc
] < 5)
860 pb
->playboard
[x_loc
][y_loc
]++;
862 pb
->playboard
[x_loc
][y_loc
] = TRIANGLE
;
865 case (PEGBOX_RIGHT
|BUTTON_REPEAT
):
867 case (PEGBOX_UP
|BUTTON_REPEAT
):
868 if (pb
->playboard
[x_loc
][y_loc
] > 2)
869 pb
->playboard
[x_loc
][y_loc
]--;
871 pb
->playboard
[x_loc
][y_loc
] = CIRCLE
;
880 /*****************************************************************************
881 * move_player() moves the player and pieces and updates the board accordingly.
882 ******************************************************************************/
883 static void move_player(struct game_context
* pb
, signed int x_dir
,
885 unsigned int type1
, type2
;
888 r
= pb
->player_row
+y_dir
;
889 c
= pb
->player_col
+x_dir
;
891 type1
= pb
->playboard
[r
][c
];
892 type2
= pb
->playboard
[r
+y_dir
][c
+x_dir
];
894 if (r
== ROWS
|| c
== COLS
|| r
< 0 || c
< 0 || type1
== WALL
)
896 else if(type1
!= SPACE
) {
897 if (type2
== WALL
|| r
+y_dir
== ROWS
|| c
+x_dir
== COLS
||
898 r
+y_dir
< 0 || c
+x_dir
< 0)
903 pb
->playboard
[pb
->player_row
][pb
->player_col
] = SPACE
;
904 pb
->player_row
+= y_dir
;
905 pb
->player_col
+= x_dir
;
909 rb
->splash(HZ
*2, "You fell down a hole!");
912 else if (type1
== SPACE
)
913 pb
->playboard
[r
][c
] = PLAYER
;
915 pb
->playboard
[r
][c
] = PLAYER
;
917 if (type1
== TRIANGLE
)
918 pb
->playboard
[r
+y_dir
][c
+x_dir
] = WALL
;
919 else if (type1
== CROSS
) {
920 pb
->playboard
[r
][c
] = SPACE
;
921 new_piece(pb
, r
+y_dir
, c
+x_dir
);
922 pb
->playboard
[r
][c
] = PLAYER
;
925 pb
->playboard
[r
+y_dir
][c
+x_dir
] = SPACE
;
927 else if (type2
== SPACE
)
928 pb
->playboard
[r
+y_dir
][c
+x_dir
] = type1
;
929 else if (type2
== HOLE
) {
931 pb
->playboard
[r
+y_dir
][c
+x_dir
] = SPACE
;
934 rb
->splash(HZ
*2, "Illegal Move!");
942 /*****************************************************************************
943 * pegbox_loadgame() loads the saved game and returns load success.
944 ******************************************************************************/
945 static bool pegbox_loadgame(struct game_context
* pb
) {
950 fd
= rb
->open(SAVE_FILE
, O_RDONLY
);
951 if(fd
< 0) return loaded
;
953 /* read in saved game */
955 if(rb
->read(fd
, &pb
->level
, sizeof(pb
->level
)) <= 0) break;
956 if(rb
->read(fd
, &pb
->playboard
, sizeof(pb
->playboard
)) <= 0)
968 /*****************************************************************************
969 * pegbox_savegame() saves the current game state.
970 ******************************************************************************/
971 static void pegbox_savegame(struct game_context
* pb
) {
974 /* write out the game state to the save file */
975 fd
= rb
->open(SAVE_FILE
, O_WRONLY
|O_CREAT
);
976 rb
->write(fd
, &pb
->level
, sizeof(pb
->level
));
977 rb
->write(fd
, &pb
->playboard
, sizeof(pb
->playboard
));
981 /*****************************************************************************
982 * pegbox_loaddata() loads the level and highlevel and returns load success.
983 ******************************************************************************/
984 static void pegbox_loaddata(struct game_context
* pb
) {
988 fd
= rb
->open(DATA_FILE
, O_RDONLY
);
995 /* read in saved game */
997 if(rb
->read(fd
, &pb
->level
, sizeof(pb
->level
)) <= 0) break;
998 if(rb
->read(fd
, &pb
->highlevel
, sizeof(pb
->highlevel
)) <= 0) break;
1006 /*****************************************************************************
1007 * pegbox_savedata() saves the level and highlevel.
1008 ******************************************************************************/
1009 static void pegbox_savedata(struct game_context
* pb
) {
1012 /* write out the game state to the save file */
1013 fd
= rb
->open(DATA_FILE
, O_WRONLY
|O_CREAT
);
1014 rb
->write(fd
, &pb
->level
, sizeof(pb
->level
));
1015 rb
->write(fd
, &pb
->highlevel
, sizeof(pb
->highlevel
));
1019 /*****************************************************************************
1020 * pegbox_callback() is the default event handler callback which is called
1021 * on usb connect and shutdown.
1022 ******************************************************************************/
1023 static void pegbox_callback(void* param
) {
1024 struct game_context
* pb
= (struct game_context
*) param
;
1025 rb
->splash(HZ
, "Saving data...");
1026 pegbox_savedata(pb
);
1029 /*****************************************************************************
1030 * pegbox_menu() is the initial menu at the start of the game.
1031 ******************************************************************************/
1032 static unsigned int pegbox_menu(struct game_context
* pb
) {
1035 unsigned int startlevel
= 1, loc
= 0;
1036 bool breakout
= false, can_resume
= false;
1038 if (pb
->num_left
> 0 || pb
->save_exist
)
1042 #if LCD_HEIGHT >= 80
1043 rb
->lcd_clear_display();
1044 rb
->lcd_bitmap(pegbox_menu_top
,0,0,LCD_WIDTH
, BMPHEIGHT_pegbox_menu_top
);
1048 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
, ITEM_WIDTH
,
1049 MENU_X
, MENU_Y
, ITEM_WIDTH
, ITEM_HEIGHT
);
1052 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, 0, ITEM_WIDTH
,
1053 MENU_X
, MENU_Y
, ITEM_WIDTH
, ITEM_HEIGHT
);
1057 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*3, ITEM_WIDTH
,
1058 MENU_X
, MENU_Y
+ITEM_HEIGHT
, ITEM_WIDTH
, ITEM_HEIGHT
);
1061 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*2, ITEM_WIDTH
,
1062 MENU_X
, MENU_Y
+ITEM_HEIGHT
, ITEM_WIDTH
, ITEM_HEIGHT
);
1066 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*4, ITEM_WIDTH
,
1067 MENU_X
, MENU_Y
+ITEM_HEIGHT
, ITEM_WIDTH
, ITEM_HEIGHT
);
1071 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*6, ITEM_WIDTH
,
1072 MENU_X
, MENU_Y
+ITEM_HEIGHT
*2, ITEM_WIDTH
, ITEM_HEIGHT
);
1075 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*5, ITEM_WIDTH
,
1076 MENU_X
, MENU_Y
+ITEM_HEIGHT
*2, ITEM_WIDTH
, ITEM_HEIGHT
);
1080 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*8, ITEM_WIDTH
,
1081 MENU_X
, MENU_Y
+ITEM_HEIGHT
*3, ITEM_WIDTH
, ITEM_HEIGHT
);
1084 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*7, ITEM_WIDTH
,
1085 MENU_X
, MENU_Y
+ITEM_HEIGHT
*3, ITEM_WIDTH
, ITEM_HEIGHT
);
1089 rb
->lcd_clear_display();
1090 rb
->lcd_getstringsize("PegBox", &w
, &h
);
1091 rb
->lcd_putsxy((LCD_WIDTH
-w
)/2, 0, "PegBox");
1092 rb
->lcd_putsxy((LCD_WIDTH
)/4, 16, "New Game");
1093 rb
->lcd_putsxy((LCD_WIDTH
)/4, 24, "Resume");
1094 rb
->lcd_putsxy((LCD_WIDTH
)/4, 32, "Help");
1095 rb
->lcd_putsxy((LCD_WIDTH
)/4, 40, "Quit");
1098 rb
->lcd_hline((LCD_WIDTH
)/4, (LCD_WIDTH
)/4+30, 28);
1100 rb
->lcd_putsxy((LCD_WIDTH
)/4-8, loc
*8+16, "*");
1104 rb
->snprintf(str
, 28, "Start on level %d of %d", startlevel
,
1106 #if LCD_HEIGHT > 110
1107 rb
->lcd_putsxy(0, MENU_Y
+4*ITEM_HEIGHT
+8, str
);
1108 #elif LCD_HEIGHT > 64
1109 rb
->lcd_putsxy(0, LCD_HEIGHT
- 8, str
);
1111 rb
->lcd_puts_scroll(0, 7, str
);
1115 /* handle menu button presses */
1116 button
= rb
->button_get(true);
1118 #ifdef HAVE_TOUCHSCREEN
1119 if(button
& BUTTON_TOUCHSCREEN
)
1121 unsigned int result
= touchscreen_map(&main_menu
,
1122 rb
->button_get_data() >> 16,
1123 rb
->button_get_data() & 0xffff);
1124 if(result
!= (unsigned)-1 && button
& BUTTON_REL
)
1127 button
= PEGBOX_LVL_UP
;
1131 button
= PEGBOX_RIGHT
;
1139 case PEGBOX_SAVE
: /* start playing */
1143 pb
->level
= startlevel
;
1146 else if (loc
== 1 && can_resume
) {
1149 rb
->remove(SAVE_FILE
);
1150 pb
->save_exist
= false;
1155 display_text("How to Play\nTo beat each level, you must "
1156 "destroy all of the pegs. If two like pegs are "
1157 "pushed into each other they disappear except "
1158 "for triangles which form a solid block and "
1159 "crosses which allow you to choose a "
1160 "replacement block.\n\n"
1163 RESTART_TEXT
" to restart level\n"
1164 LVL_UP_TEXT
" to go up a level\n"
1165 LVL_DOWN_TEXT
" to go down a level\n"
1166 SAVE_TEXT
" to select/save\n"
1167 QUIT_TEXT
" to quit\n",true);
1169 RESTART_TEXT
": restart\n"
1170 LVL_UP_TEXT
": level up\n"
1171 LVL_DOWN_TEXT
" level down\n"
1172 SAVE_TEXT
" select/save\n"
1173 QUIT_TEXT
" quit\n",true);
1179 case PEGBOX_QUIT
: /* quit program */
1182 case (PEGBOX_UP
|BUTTON_REPEAT
):
1188 if (!can_resume
&& loc
== 1) {
1194 case (PEGBOX_DOWN
|BUTTON_REPEAT
):
1200 if (!can_resume
&& loc
== 1) {
1205 case (PEGBOX_LVL_UP
|BUTTON_REPEAT
):
1206 case PEGBOX_LVL_UP
: /* increase starting level */
1207 if(startlevel
>= pb
->highlevel
) {
1214 /* only for targets with enough buttons */
1215 #ifdef PEGBOX_LVL_DOWN
1216 case (PEGBOX_LVL_DOWN
|BUTTON_REPEAT
):
1217 case PEGBOX_LVL_DOWN
: /* decrease starting level */
1218 if(startlevel
<= 1) {
1219 startlevel
= pb
->highlevel
;
1226 if(rb
->default_event_handler_ex(button
, pegbox_callback
,
1227 (void*) pb
) == SYS_USB_CONNECTED
)
1238 /*****************************************************************************
1239 * pegbox() is the main game subroutine, it returns the final game status.
1240 ******************************************************************************/
1241 static int pegbox(struct game_context
* pb
) {
1244 /********************
1246 ********************/
1247 temp_var
= pegbox_menu(pb
);
1248 if (temp_var
== PB_QUIT
|| temp_var
== PB_USB
)
1252 temp_var
= rb
->button_get(true);
1253 #ifdef HAVE_TOUCHSCREEN
1254 if(temp_var
& BUTTON_TOUCHSCREEN
)
1256 pegbox_raster_btn
.two_d_from
.y
= pb
->player_row
;
1257 pegbox_raster_btn
.two_d_from
.x
= pb
->player_col
;
1259 struct ts_raster_button_result ret
=
1260 touchscreen_raster_map_button(&pegbox_raster_btn
,
1261 rb
->button_get_data() >> 16,
1262 rb
->button_get_data() & 0xffff,
1264 if(ret
.action
== TS_ACTION_TWO_D_MOVEMENT
)
1265 move_player(pb
, ret
.to
.x
- ret
.from
.x
, ret
.to
.y
- ret
.from
.y
);
1269 case PEGBOX_LEFT
: /* move cursor left */
1270 case (PEGBOX_LEFT
|BUTTON_REPEAT
):
1271 move_player(pb
, -1, 0);
1274 case PEGBOX_RIGHT
: /* move cursor right */
1275 case (PEGBOX_RIGHT
|BUTTON_REPEAT
):
1276 move_player(pb
, 1, 0);
1279 case PEGBOX_DOWN
: /* move cursor down */
1280 case (PEGBOX_DOWN
|BUTTON_REPEAT
):
1281 move_player(pb
, 0, 1);
1284 case PEGBOX_UP
: /* move cursor up */
1285 case (PEGBOX_UP
|BUTTON_REPEAT
):
1286 move_player(pb
, 0, -1);
1289 case PEGBOX_SAVE
: /* save and end game */
1290 rb
->splash(HZ
, "Saving game...");
1291 pegbox_savegame(pb
);
1292 /* fall through to PEGBOX_QUIT */
1297 case PEGBOX_RESTART
:
1302 case (PEGBOX_LVL_UP
|BUTTON_REPEAT
):
1304 if(pb
->level
>= pb
->highlevel
) {
1313 /* only for targets with enough buttons */
1314 #ifdef PEGBOX_LVL_DOWN
1315 case (PEGBOX_LVL_DOWN
|BUTTON_REPEAT
):
1316 case PEGBOX_LVL_DOWN
:
1317 if(pb
->level
<= 1) {
1318 pb
->level
= pb
->highlevel
;
1329 if(pb
->num_left
== 0) {
1330 rb
->splash(HZ
*2, "Nice Pegging!");
1331 if(pb
->level
== NUM_LEVELS
) {
1333 rb
->splash(HZ
*2, "You Won!");
1342 if(pb
->level
> pb
->highlevel
)
1343 pb
->highlevel
= pb
->level
;
1352 /*****************************************************************************
1353 * plugin entry point.
1354 ******************************************************************************/
1355 enum plugin_status
plugin_start(const struct plugin_api
* api
, const void* parameter
) {
1357 struct game_context pb
;
1362 rb
->lcd_setfont(FONT_SYSFIXED
);
1364 rb
->lcd_set_backdrop(NULL
);
1366 #ifdef HAVE_LCD_COLOR
1367 rb
->lcd_set_foreground(LCD_WHITE
);
1368 rb
->lcd_set_background(BG_COLOR
);
1371 rb
->splash(0, "Loading...");
1372 pegbox_loaddata(&pb
);
1373 pb
.save_exist
= pegbox_loadgame(&pb
);
1376 rb
->lcd_clear_display();
1380 switch(pegbox(&pb
)){
1385 rb
->lcd_setfont(FONT_UI
);
1386 return PLUGIN_USB_CONNECTED
;
1389 rb
->splash(HZ
, "Saving data...");
1390 pegbox_savedata(&pb
);
1399 rb
->lcd_setfont(FONT_UI
);