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)
37 /* final game return status */
42 #define DATA_FILE PLUGIN_DIR "/games/pegbox.data"
43 #define SAVE_FILE PLUGIN_DIR "/games/pegbox.save"
45 #define ROWS 8 /* Number of rows on each board */
46 #define COLS 12 /* Number of columns on each board */
47 #define NUM_LEVELS 15 /* Number of levels */
58 #if CONFIG_KEYPAD == RECORDER_PAD
59 #define PEGBOX_SAVE BUTTON_ON
60 #define PEGBOX_QUIT BUTTON_OFF
61 #define PEGBOX_RESTART BUTTON_F2
62 #define PEGBOX_LVL_UP BUTTON_F1
63 #define PEGBOX_LVL_DOWN BUTTON_F3
64 #define PEGBOX_UP BUTTON_UP
65 #define PEGBOX_DOWN BUTTON_DOWN
66 #define PEGBOX_RIGHT BUTTON_RIGHT
67 #define PEGBOX_LEFT BUTTON_LEFT
69 #define SAVE_TEXT "ON"
70 #define QUIT_TEXT "OFF"
71 #define RESTART_TEXT "F2"
72 #define LVL_UP_TEXT "F1"
73 #define LVL_DOWN_TEXT "F3"
75 #elif CONFIG_KEYPAD == ONDIO_PAD
76 #define PEGBOX_SAVE BUTTON_OFF
77 #define PEGBOX_QUIT (BUTTON_MENU | BUTTON_LEFT)
78 #define PEGBOX_RESTART (BUTTON_MENU | BUTTON_RIGHT)
79 #define PEGBOX_LVL_UP (BUTTON_MENU | BUTTON_UP)
80 #define PEGBOX_LVL_DOWN (BUTTON_MENU | BUTTON_DOWN)
81 #define PEGBOX_UP BUTTON_UP
82 #define PEGBOX_DOWN BUTTON_DOWN
83 #define PEGBOX_RIGHT BUTTON_RIGHT
84 #define PEGBOX_LEFT BUTTON_LEFT
86 #define SAVE_TEXT "OFF"
87 #define QUIT_TEXT "M+LEFT"
88 #define RESTART_TEXT "M+RIGHT"
89 #define LVL_UP_TEXT "M+UP"
90 #define LVL_DOWN_TEXT "M+DOWN"
92 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
93 (CONFIG_KEYPAD == IRIVER_H300_PAD)
94 #define PEGBOX_SAVE BUTTON_SELECT
95 #define PEGBOX_QUIT BUTTON_OFF
96 #define PEGBOX_RESTART BUTTON_ON
97 #define PEGBOX_LVL_UP BUTTON_MODE
98 #define PEGBOX_LVL_DOWN BUTTON_REC
99 #define PEGBOX_UP BUTTON_UP
100 #define PEGBOX_DOWN BUTTON_DOWN
101 #define PEGBOX_RIGHT BUTTON_RIGHT
102 #define PEGBOX_LEFT BUTTON_LEFT
104 #define SAVE_TEXT "NAVI"
105 #define QUIT_TEXT "OFF"
106 #define RESTART_TEXT "ON"
107 #define LVL_UP_TEXT "AB"
108 #define LVL_DOWN_TEXT "REC"
110 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
111 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
112 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
113 #define PEGBOX_SAVE (BUTTON_SELECT|BUTTON_RIGHT)
114 #define PEGBOX_QUIT (BUTTON_SELECT|BUTTON_PLAY)
115 #define PEGBOX_RESTART (BUTTON_SELECT|BUTTON_LEFT)
116 #define PEGBOX_LVL_UP (BUTTON_SELECT|BUTTON_MENU)
117 #define PEGBOX_UP BUTTON_MENU
118 #define PEGBOX_DOWN BUTTON_PLAY
119 #define PEGBOX_RIGHT BUTTON_RIGHT
120 #define PEGBOX_LEFT BUTTON_LEFT
122 #define SAVE_TEXT "SELECT+RIGHT"
123 #define QUIT_TEXT "SELECT+PLAY"
124 #define RESTART_TEXT "SELECT+LEFT"
125 #define LVL_UP_TEXT "SELECT+MENU"
126 #define LVL_DOWN_TEXT "-"
128 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
129 #define PEGBOX_SAVE BUTTON_SELECT
130 #define PEGBOX_QUIT BUTTON_POWER
131 #define PEGBOX_RESTART BUTTON_REC
132 #define PEGBOX_LVL_UP BUTTON_PLAY
133 #define PEGBOX_UP BUTTON_UP
134 #define PEGBOX_DOWN BUTTON_DOWN
135 #define PEGBOX_RIGHT BUTTON_RIGHT
136 #define PEGBOX_LEFT BUTTON_LEFT
138 #define SAVE_TEXT "SELECT"
139 #define QUIT_TEXT "OFF"
140 #define RESTART_TEXT "REC"
141 #define LVL_UP_TEXT "PLAY"
142 #define LVL_DOWN_TEXT "-"
144 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
145 #define PEGBOX_SAVE BUTTON_MODE
146 #define PEGBOX_QUIT BUTTON_PLAY
147 #define PEGBOX_RESTART (BUTTON_EQ|BUTTON_MODE)
148 #define PEGBOX_LVL_UP (BUTTON_EQ|BUTTON_UP)
149 #define PEGBOX_LVL_DOWN (BUTTON_EQ|BUTTON_DOWN)
150 #define PEGBOX_UP BUTTON_UP
151 #define PEGBOX_DOWN BUTTON_DOWN
152 #define PEGBOX_RIGHT BUTTON_RIGHT
153 #define PEGBOX_LEFT BUTTON_LEFT
155 #define SAVE_TEXT "MODE"
156 #define QUIT_TEXT "PLAY"
157 #define RESTART_TEXT "EQ+MODE"
158 #define LVL_UP_TEXT "EQ+UP"
159 #define LVL_DOWN_TEXT "EQ+DOWN"
161 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
162 #define PEGBOX_SAVE BUTTON_PLAY
163 #define PEGBOX_QUIT BUTTON_POWER
164 #define PEGBOX_RESTART (BUTTON_FF|BUTTON_REPEAT)
165 #define PEGBOX_LVL_UP (BUTTON_FF|BUTTON_SCROLL_UP)
166 #define PEGBOX_LVL_DOWN (BUTTON_FF|BUTTON_SCROLL_DOWN)
167 #define PEGBOX_UP BUTTON_SCROLL_UP
168 #define PEGBOX_DOWN BUTTON_SCROLL_DOWN
169 #define PEGBOX_RIGHT BUTTON_RIGHT
170 #define PEGBOX_LEFT BUTTON_LEFT
172 #define SAVE_TEXT "PLAY"
173 #define QUIT_TEXT "OFF"
174 #define RESTART_TEXT "LONG FF"
175 #define LVL_UP_TEXT "FF+SCROLL_UP"
176 #define LVL_DOWN_TEXT "FF+SCROLL_DOWN"
178 #elif CONFIG_KEYPAD == SANSA_E200_PAD
179 #define PEGBOX_SAVE BUTTON_SELECT
180 #define PEGBOX_QUIT BUTTON_POWER
181 #define PEGBOX_RESTART BUTTON_REC
182 #define PEGBOX_LVL_UP BUTTON_SCROLL_BACK
183 #define PEGBOX_LVL_DOWN BUTTON_SCROLL_FWD
184 #define PEGBOX_UP BUTTON_UP
185 #define PEGBOX_DOWN BUTTON_DOWN
186 #define PEGBOX_RIGHT BUTTON_RIGHT
187 #define PEGBOX_LEFT BUTTON_LEFT
189 #define SAVE_TEXT "SELECT"
190 #define QUIT_TEXT "POWER"
191 #define RESTART_TEXT "REC"
192 #define LVL_UP_TEXT "SCROLL BACK"
193 #define LVL_DOWN_TEXT "SCROLL FWD"
195 #elif CONFIG_KEYPAD == SANSA_FUZE_PAD
196 #define PEGBOX_SAVE BUTTON_SELECT|BUTTON_REL
197 #define PEGBOX_QUIT BUTTON_POWER
199 #define PEGBOX_RESTART BUTTON_HOME */
200 #define PEGBOX_RESTART BUTTON_SELECT|BUTTON_LEFT
201 #define PEGBOX_LVL_UP BUTTON_SCROLL_BACK
202 #define PEGBOX_LVL_DOWN BUTTON_SCROLL_FWD
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 "SELECT & LEFT"
211 #define LVL_UP_TEXT "SCROLL BACK"
212 #define LVL_DOWN_TEXT "SCROLL FWD"
214 #elif CONFIG_KEYPAD == GIGABEAT_PAD
215 #define PEGBOX_SAVE BUTTON_SELECT
216 #define PEGBOX_QUIT BUTTON_POWER
217 #define PEGBOX_RESTART BUTTON_A
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 "POWER"
227 #define RESTART_TEXT "A"
228 #define LVL_UP_TEXT "VOL+"
229 #define LVL_DOWN_TEXT "VOL-"
231 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
232 #define PEGBOX_SAVE BUTTON_SELECT
233 #define PEGBOX_QUIT BUTTON_BACK
234 #define PEGBOX_RESTART BUTTON_MENU
235 #define PEGBOX_LVL_UP BUTTON_VOL_UP
236 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
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 "BACK"
244 #define RESTART_TEXT "MENU"
245 #define LVL_UP_TEXT "VOL+"
246 #define LVL_DOWN_TEXT "VOL-"
248 #elif CONFIG_KEYPAD == MROBE100_PAD
249 #define PEGBOX_SAVE BUTTON_SELECT
250 #define PEGBOX_QUIT BUTTON_POWER
251 #define PEGBOX_RESTART BUTTON_PLAY
252 #define PEGBOX_LVL_UP BUTTON_MENU
253 #define PEGBOX_LVL_DOWN BUTTON_DISPLAY
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 "PLAY"
262 #define LVL_UP_TEXT "MENU"
263 #define LVL_DOWN_TEXT "DISPLAY"
265 #elif CONFIG_KEYPAD == SANSA_C200_PAD
266 #define PEGBOX_SAVE BUTTON_SELECT
267 #define PEGBOX_QUIT BUTTON_POWER
268 #define PEGBOX_RESTART BUTTON_REC
269 #define PEGBOX_LVL_UP BUTTON_VOL_UP
270 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
271 #define PEGBOX_UP BUTTON_UP
272 #define PEGBOX_DOWN BUTTON_DOWN
273 #define PEGBOX_RIGHT BUTTON_RIGHT
274 #define PEGBOX_LEFT BUTTON_LEFT
276 #define SAVE_TEXT "SELECT"
277 #define QUIT_TEXT "POWER"
278 #define RESTART_TEXT "REC"
279 #define LVL_UP_TEXT "VOL+"
280 #define LVL_DOWN_TEXT "VOL-"
282 #elif CONFIG_KEYPAD == SANSA_CLIP_PAD
283 #define PEGBOX_SAVE BUTTON_SELECT
284 #define PEGBOX_QUIT BUTTON_POWER
285 #define PEGBOX_RESTART BUTTON_HOME
286 #define PEGBOX_LVL_UP BUTTON_VOL_UP
287 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
288 #define PEGBOX_UP BUTTON_UP
289 #define PEGBOX_DOWN BUTTON_DOWN
290 #define PEGBOX_RIGHT BUTTON_RIGHT
291 #define PEGBOX_LEFT BUTTON_LEFT
293 #define SAVE_TEXT "SELECT"
294 #define QUIT_TEXT "POWER"
295 #define RESTART_TEXT "HOME"
296 #define LVL_UP_TEXT "VOL+"
297 #define LVL_DOWN_TEXT "VOL-"
299 #elif CONFIG_KEYPAD == SANSA_M200_PAD
300 #define PEGBOX_SAVE (BUTTON_SELECT | BUTTON_REL)
301 #define PEGBOX_QUIT BUTTON_POWER
302 #define PEGBOX_RESTART (BUTTON_SELECT | BUTTON_UP)
303 #define PEGBOX_LVL_UP BUTTON_VOL_UP
304 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
305 #define PEGBOX_UP BUTTON_UP
306 #define PEGBOX_DOWN BUTTON_DOWN
307 #define PEGBOX_RIGHT BUTTON_RIGHT
308 #define PEGBOX_LEFT BUTTON_LEFT
310 #define SAVE_TEXT "SELECT"
311 #define QUIT_TEXT "POWER"
312 #define RESTART_TEXT "SELECT+UP"
313 #define LVL_UP_TEXT "VOL+"
314 #define LVL_DOWN_TEXT "VOL-"
317 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
318 #define PEGBOX_SAVE BUTTON_RC_PLAY
319 #define PEGBOX_QUIT BUTTON_RC_REC
320 #define PEGBOX_RESTART BUTTON_RC_MODE
321 #define PEGBOX_LVL_UP BUTTON_VOL_UP
322 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
323 #define PEGBOX_UP BUTTON_RC_VOL_UP
324 #define PEGBOX_DOWN BUTTON_RC_VOL_DOWN
325 #define PEGBOX_RIGHT BUTTON_RC_FF
326 #define PEGBOX_LEFT BUTTON_RC_REW
328 #define SAVE_TEXT "REM. PLAY"
329 #define QUIT_TEXT "REM. REC"
330 #define RESTART_TEXT "REM. MODE"
331 #define LVL_UP_TEXT "VOL+"
332 #define LVL_DOWN_TEXT "VOL-"
334 #elif CONFIG_KEYPAD == COWOND2_PAD
335 #define PEGBOX_QUIT BUTTON_POWER
337 #define QUIT_TEXT "POWER"
339 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
340 #define PEGBOX_SAVE BUTTON_CUSTOM
341 #define PEGBOX_QUIT BUTTON_BACK
342 #define PEGBOX_RESTART BUTTON_SELECT
343 #define PEGBOX_LVL_UP BUTTON_PLAY
344 #define PEGBOX_LVL_DOWN BUTTON_MENU
345 #define PEGBOX_UP BUTTON_UP
346 #define PEGBOX_DOWN BUTTON_DOWN
347 #define PEGBOX_RIGHT BUTTON_RIGHT
348 #define PEGBOX_LEFT BUTTON_LEFT
350 #define SAVE_TEXT "CUSTOM"
351 #define QUIT_TEXT "BACK"
352 #define RESTART_TEXT "MIDDLE"
353 #define LVL_UP_TEXT "SELECT"
354 #define LVL_DOWN_TEXT "MENU"
356 #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
357 #define PEGBOX_SAVE BUTTON_VIEW
358 #define PEGBOX_QUIT BUTTON_POWER
359 #define PEGBOX_RESTART BUTTON_MENU
360 #define PEGBOX_LVL_UP BUTTON_VOL_UP
361 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
362 #define PEGBOX_UP BUTTON_UP
363 #define PEGBOX_DOWN BUTTON_DOWN
364 #define PEGBOX_RIGHT BUTTON_RIGHT
365 #define PEGBOX_LEFT BUTTON_LEFT
367 #define SAVE_TEXT "VIEW"
368 #define QUIT_TEXT "POWER"
369 #define RESTART_TEXT "MENU"
370 #define LVL_UP_TEXT "VOL+"
371 #define LVL_DOWN_TEXT "VOL-"
374 #error Unsupported keymap!
377 #ifdef HAVE_TOUCHSCREEN
379 #define PEGBOX_QUIT BUTTON_TOPLEFT
382 #define PEGBOX_SAVE BUTTON_CENTER
384 #ifndef PEGBOX_RESTART
385 #define PEGBOX_RESTART BUTTON_TOPRIGHT
387 #ifndef PEGBOX_LVL_UP
388 #define PEGBOX_LVL_UP BUTTON_BOTTOMLEFT
390 #ifndef PEGBOX_LVL_DOWN
391 #define PEGBOX_LVL_DOWN BUTTON_BOTTOMRIGHT
394 #define PEGBOX_UP BUTTON_TOPMIDDLE
397 #define PEGBOX_DOWN BUTTON_BOTTOMMIDDLE
400 #define PEGBOX_RIGHT BUTTON_MIDRIGHT
403 #define PEGBOX_LEFT BUTTON_MIDLEFT
406 #define SAVE_TEXT "CENTER"
409 #define QUIT_TEXT "TOPLEFT"
412 #define RESTART_TEXT "TOPRIGHT"
415 #define LVL_UP_TEXT "BOTTOMLEFT"
417 #ifndef LVL_DOWN_TEXT
418 #define LVL_DOWN_TEXT "BOTTOMRIGHT"
423 /* get several sizes from the bitmaps */
424 #ifdef BMPWIDTH_pegbox_pieces
425 #define PIECE_WIDTH BMPWIDTH_pegbox_pieces
426 #define PIECE_HEIGHT (BMPHEIGHT_pegbox_pieces/7)
428 /* dummy numbers to avoid #error in dependency generation */
429 #define PIECE_WIDTH 50
430 #define PIECE_HEIGHT 10
433 #define BOARD_WIDTH (12*PIECE_WIDTH)
434 #define BOARD_HEIGHT (8*PIECE_HEIGHT)
437 /* define a wide layout where the statistics are alongside the board, not above
438 * base calculation on the piece bitmaps for the 8x12 board */
439 #if (LCD_WIDTH - BOARD_WIDTH) > (LCD_HEIGHT - BOARD_HEIGHT)
444 #define HEADER_WIDTH BMPWIDTH_pegbox_header
445 #define HEADER_HEIGHT BMPHEIGHT_pegbox_header
448 #if defined WIDE_LAYOUT
450 #if ((BOARD_WIDTH + HEADER_WIDTH + 4) <= LCD_WIDTH)
455 #define BOARD_Y (LCD_HEIGHT-BOARD_HEIGHT)/2
457 #if (LCD_WIDTH >= 132) && (LCD_HEIGHT >= 80)
459 #define LEVEL_TEXT_Y 14
460 #define PEGS_TEXT_Y 58
461 #elif (LCD_WIDTH >= 128) && (LCD_HEIGHT >= 64)
463 #define LEVEL_TEXT_Y 14
464 #define PEGS_TEXT_Y 58
466 #error "Unsupported screen size"
469 #else /* "normal" layout */
471 #define BOARD_X (LCD_WIDTH-BOARD_WIDTH)/2
472 #if ((BOARD_HEIGHT + HEADER_HEIGHT + 4) <= LCD_HEIGHT)
473 #define BOARD_Y HEADER_HEIGHT+2
475 #define BOARD_Y HEADER_HEIGHT
479 #define LEVEL_TEXT_X 59
480 #define PEGS_TEXT_X 276
482 #elif LCD_WIDTH >= 240
483 #define LEVEL_TEXT_X 59
484 #define PEGS_TEXT_X 196
486 #elif LCD_WIDTH >= 220
487 #define LEVEL_TEXT_X 49
488 #define PEGS_TEXT_X 186
490 #elif LCD_WIDTH >= 176
491 #define LEVEL_TEXT_X 38
492 #define PEGS_TEXT_X 155
494 #elif LCD_WIDTH >= 160
495 #define LEVEL_TEXT_X 37
496 #define PEGS_TEXT_X 140
498 #elif LCD_WIDTH >= 138
499 #define LEVEL_TEXT_X 28
500 #define PEGS_TEXT_X 119
502 #elif LCD_WIDTH >= 128
503 #if HEADER_HEIGHT > 16
504 #define LEVEL_TEXT_X 26
505 #define PEGS_TEXT_X 107
508 #define LEVEL_TEXT_X 15
509 #define PEGS_TEXT_X 100
511 #endif /* HEADER_HEIGHT */
512 #elif LCD_WIDTH >= 112
513 #define LEVEL_TEXT_X 25
514 #define PEGS_TEXT_X 90
516 #endif /* LCD_WIDTH */
518 #endif /* WIDE_LAYOUT */
521 #ifdef HAVE_LCD_COLOR
522 #define BG_COLOR LCD_BLACK
523 #define TEXT_BG LCD_RGBPACK(189,189,189)
527 #ifdef HAVE_TOUCHSCREEN
528 #include "lib/touchscreen.h"
530 static struct ts_mapping main_menu_items
[5] =
532 {MENU_X
, MENU_Y
, ITEM_WIDTH
, ITEM_HEIGHT
},
533 {MENU_X
, MENU_Y
+ITEM_HEIGHT
, ITEM_WIDTH
, ITEM_HEIGHT
},
534 {MENU_X
, MENU_Y
+ITEM_HEIGHT
*2, ITEM_WIDTH
, ITEM_HEIGHT
},
535 {MENU_X
, MENU_Y
+ITEM_HEIGHT
*3, ITEM_WIDTH
, ITEM_HEIGHT
},
537 #if (LCD_WIDTH >= 138) && (LCD_HEIGHT > 110)
538 0, MENU_Y
+4*ITEM_HEIGHT
+8, SYSFONT_WIDTH
*28, SYSFONT_HEIGHT
539 #elif LCD_WIDTH > 112
540 0, LCD_HEIGHT
- 8, SYSFONT_WIDTH
*28, SYSFONT_HEIGHT
542 #error "Touchscreen isn't supported on non-bitmap screens!"
547 static struct ts_mappings main_menu
= {main_menu_items
, 5};
549 static struct ts_raster pegbox_raster
=
550 { BOARD_X
, BOARD_Y
, COLS
*PIECE_WIDTH
, ROWS
*PIECE_HEIGHT
,
551 PIECE_WIDTH
, PIECE_HEIGHT
};
552 static struct ts_raster_button_mapping pegbox_raster_btn
=
553 { &pegbox_raster
, false, false, true, false, true, {0, 0}, 0, 0, 0 };
556 struct game_context
{
558 unsigned int highlevel
;
559 signed int player_row
;
560 signed int player_col
;
561 unsigned int num_left
;
563 unsigned int playboard
[ROWS
][COLS
];
566 char levels
[NUM_LEVELS
][ROWS
][COLS
] = {
568 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
569 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
570 {1, 0, 0, 0, 7, 0, 0, 5, 0, 0, 0, 1,},
571 {1, 0, 0, 0, 0, 3, 3, 2, 0, 0, 0, 1,},
572 {1, 0, 0, 0, 4, 6, 0, 5, 0, 0, 0, 1,},
573 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
574 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
575 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
578 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
579 {1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 1,},
580 {1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1,},
581 {1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1,},
582 {7, 0, 0, 0, 2, 2, 5, 5, 0, 0, 0, 1,},
583 {1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1,},
584 {1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1,},
585 {1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 1,}},
588 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
589 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
590 {1, 0, 0, 0, 0, 0, 2, 0, 7, 0, 0, 0,},
591 {1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 2, 1,},
592 {1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1,},
593 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1,},
594 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
595 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
598 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
599 {6, 0, 4, 0, 2, 0, 2, 0, 0, 0, 0, 1,},
600 {6, 0, 3, 0, 5, 0, 2, 0, 0, 0, 0, 1,},
601 {6, 0, 5, 0, 4, 7, 2, 0, 0, 0, 0, 1,},
602 {6, 0, 2, 0, 4, 0, 2, 0, 3, 0, 0, 1,},
603 {6, 0, 4, 0, 5, 0, 2, 0, 0, 0, 0, 1,},
604 {6, 0, 5, 0, 4, 0, 2, 0, 0, 0, 0, 1,},
605 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
608 {{0, 6, 6, 0, 4, 6, 0, 0, 6, 0, 0, 0,},
609 {0, 6, 6, 0, 4, 4, 0, 0, 6, 0, 0, 2,},
610 {2, 6, 6, 0, 6, 6, 6, 0, 1, 2, 2, 2,},
611 {0, 6, 6, 0, 6, 4, 6, 0, 1, 2, 0, 2,},
612 {0, 6, 6, 0, 6, 7, 6, 5, 6, 0, 0, 0,},
613 {2, 6, 6, 0, 6, 6, 6, 0, 6, 0, 0, 0,},
614 {0, 6, 6, 0, 4, 0, 0, 0, 6, 0, 0, 0,},
615 {0, 6, 6, 0, 0, 5, 0, 0, 6, 5, 5, 0,}},
618 {{7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
619 {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,},
620 {2, 0, 0, 2, 0, 0, 0, 2, 2, 0, 0, 0,},
621 {0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 0,},
622 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
623 {0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1,},
624 {0, 3, 0, 0, 0, 0, 0, 0, 5, 4, 6, 0,},
625 {0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1,}},
628 {{1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1,},
629 {1, 1, 1, 6, 0, 0, 4, 6, 0, 1, 1, 1,},
630 {1, 1, 1, 1, 0, 1, 5, 1, 0, 1, 1, 1,},
631 {1, 1, 1, 2, 3, 3, 7, 4, 2, 6, 1, 1,},
632 {1, 1, 1, 1, 0, 1, 2, 1, 0, 0, 0, 1,},
633 {1, 1, 1, 1, 0, 0, 5, 0, 0, 1, 0, 1,},
634 {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1,},
635 {1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,}},
638 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
639 {0, 0, 3, 3, 3, 3, 3, 4, 3, 3, 0, 0,},
640 {0, 0, 3, 3, 3, 2, 3, 3, 5, 3, 0, 0,},
641 {7, 0, 3, 3, 3, 2, 3, 3, 4, 3, 0, 0,},
642 {0, 0, 3, 3, 4, 5, 3, 3, 3, 3, 0, 0,},
643 {0, 0, 3, 3, 5, 2, 3, 3, 3, 3, 0, 0,},
644 {0, 0, 3, 3, 2, 4, 3, 3, 3, 3, 0, 0,},
645 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
648 {{0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,},
649 {0, 3, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,},
650 {0, 0, 0, 0, 2, 4, 4, 3, 0, 1, 1, 0,},
651 {0, 1, 0, 0, 2, 1, 0, 0, 0, 1, 1, 1,},
652 {0, 0, 0, 2, 2, 7, 1, 0, 0, 0, 0, 2,},
653 {0, 0, 0, 0, 2, 1, 0, 0, 1, 1, 1, 1,},
654 {0, 3, 1, 0, 2, 5, 5, 0, 0, 0, 3, 0,},
655 {0, 0, 0, 0, 4, 1, 0, 0, 0, 0, 0, 0,}},
658 {{1, 1, 1, 1, 2, 1, 1, 1, 0, 0, 0, 0,},
659 {1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 7,},
660 {0, 0, 4, 0, 6, 6, 6, 0, 0, 0, 3, 0,},
661 {0, 3, 3, 0, 6, 6, 6, 0, 4, 3, 4, 0,},
662 {0, 3, 3, 0, 6, 6, 6, 0, 4, 3, 4, 0,},
663 {0, 0, 0, 0, 6, 6, 6, 0, 3, 0, 0, 0,},
664 {1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0,},
665 {1, 1, 1, 1, 1, 2, 1, 1, 0, 0, 0, 0,}},
668 {{1, 7, 1, 0, 1, 1, 6, 0, 0, 1, 1, 0,},
669 {1, 0, 0, 0, 5, 4, 6, 6, 0, 2, 2, 0,},
670 {1, 2, 1, 2, 0, 1, 6, 0, 0, 2, 2, 0,},
671 {1, 0, 0, 2, 0, 1, 0, 0, 0, 3, 3, 0,},
672 {1, 2, 1, 0, 0, 1, 0, 1, 0, 3, 3, 0,},
673 {0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0,},
674 {0, 3, 4, 3, 0, 1, 0, 1, 0, 0, 0, 0,},
675 {0, 0, 0, 0, 2, 2, 2, 1, 1, 1, 1, 1,}},
678 {{7, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,},
679 {1, 2, 1, 2, 1, 2, 1, 1, 0, 0, 0, 1,},
680 {0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1,},
681 {1, 2, 1, 2, 1, 2, 1, 0, 0, 0, 0, 1,},
682 {0, 0, 0, 0, 0, 0, 1, 1, 5, 5, 6, 1,},
683 {1, 2, 1, 2, 1, 2, 1, 1, 0, 2, 2, 1,},
684 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1,},
685 {1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1,}},
688 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
689 {0, 0, 4, 0, 2, 0, 5, 0, 4, 0, 0, 6,},
690 {0, 0, 2, 0, 5, 0, 2, 0, 4, 0, 0, 6,},
691 {7, 0, 3, 0, 4, 0, 5, 0, 4, 0, 0, 6,},
692 {0, 0, 5, 0, 4, 0, 2, 0, 4, 0, 0, 6,},
693 {0, 0, 4, 0, 2, 0, 5, 0, 4, 0, 0, 6,},
694 {0, 0, 3, 0, 3, 0, 2, 0, 4, 0, 0, 6,},
695 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
698 {{1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1,},
699 {1, 1, 0, 2, 0, 0, 4, 0, 0, 2, 0, 1,},
700 {1, 6, 0, 0, 5, 1, 0, 1, 1, 0, 0, 1,},
701 {1, 1, 1, 0, 0, 3, 5, 3, 0, 0, 1, 1,},
702 {1, 1, 0, 0, 1, 1, 0, 1, 5, 0, 0, 6,},
703 {1, 1, 0, 2, 0, 0, 4, 0, 0, 0, 7, 1,},
704 {1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1,},
705 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
708 {{0, 0, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
709 {0, 0, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
710 {0, 3, 4, 6, 0, 6, 0, 6, 0, 6, 0, 2,},
711 {0, 4, 0, 6, 0, 6, 4, 6, 0, 6, 0, 1,},
712 {0, 3, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
713 {7, 0, 0, 6, 4, 6, 0, 6, 0, 6, 0, 1,},
714 {0, 0, 4, 6, 0, 6, 0, 6, 4, 6, 0, 1,},
715 {0, 0, 4, 6, 0, 6, 0, 6, 0, 6, 0, 1,}}
719 /*****************************************************************************
720 * display_text() formats and outputs text.
721 ******************************************************************************/
722 static void display_text(char *str
, bool waitkey
)
727 int current_line
= 0;
728 int char_width
, char_height
;
729 int first_char_index
= 0;
737 rb
->lcd_clear_display();
739 rb
->lcd_getstringsize("a", &char_width
, &char_height
);
741 chars_by_line
= LCD_WIDTH
/ char_width
;
742 lines_by_screen
= LCD_HEIGHT
/ char_height
;
746 ptr_char
= str
+ first_char_index
;
750 while (i
< chars_by_line
)
763 *(ptr_line
++) = *ptr_char
;
765 if (*ptr_char
== '\n' || *ptr_char
== '\0')
771 if (chars_for_line
== 0)
774 line
[chars_for_line
] = '\0';
776 /* test if we have cut a word. If it is the case we don't have to */
778 if (i
== chars_by_line
&& chars_for_line
== chars_by_line
)
779 first_char_index
+= chars_for_line
;
781 first_char_index
+= chars_for_line
+ 1;
783 /* print the line on the screen */
784 rb
->lcd_putsxy(0, current_line
* char_height
, line
);
786 /* if the number of line showed on the screen is equals to the */
787 /* maximum number of line we can show, we wait for a key pressed to */
788 /* clear and show the remaining text. */
790 if (current_line
== lines_by_screen
|| *ptr_char
== '\0')
795 while (waitkey
&& !go_on
)
797 key
= rb
->button_get(true);
800 #ifdef HAVE_TOUCHSCREEN
801 case BUTTON_TOUCHSCREEN
:
810 /*if (rb->default_event_handler(key) == SYS_USB_CONNECTED)
819 rb
->lcd_clear_display();
821 } while (*ptr_char
!= '\0');
824 /*****************************************************************************
825 * draw_board() draws the game's current level.
826 ******************************************************************************/
827 static void draw_board(struct game_context
* pb
) {
828 unsigned int r
, c
, type
;
832 rb
->lcd_clear_display();
834 rb
->lcd_bitmap(pegbox_header
,LCD_WIDTH
-HEADER_WIDTH
,0,
835 HEADER_WIDTH
,LCD_HEIGHT
);
837 rb
->lcd_bitmap(pegbox_header
,(LCD_WIDTH
-HEADER_WIDTH
)/2,0,
838 HEADER_WIDTH
, HEADER_HEIGHT
);
839 #endif /* WIDE_LAYOUT */
841 #if ((BOARD_HEIGHT + HEADER_HEIGHT + 4) <= LCD_HEIGHT)
842 rb
->lcd_drawrect(BOARD_X
-2,BOARD_Y
-2,BOARD_WIDTH
+4,BOARD_HEIGHT
+4);
843 #endif /* enough space for a frame? */
845 #ifdef HAVE_LCD_COLOR
846 rb
->lcd_set_foreground(LCD_WHITE
);
847 rb
->lcd_fillrect(BOARD_X
-1,BOARD_Y
-1,BOARD_WIDTH
+2,BOARD_HEIGHT
+2);
848 rb
->lcd_set_foreground(LCD_BLACK
);
849 rb
->lcd_set_background(TEXT_BG
);
852 for (r
=0 ; r
< ROWS
; r
++) {
853 for (c
= 0 ; c
< COLS
; c
++) {
855 type
= pb
->playboard
[r
][c
];
862 rb
->lcd_bitmap_part(pegbox_pieces
, 0, (type
-1)*PIECE_HEIGHT
,
863 PIECE_WIDTH
, c
* PIECE_WIDTH
+ BOARD_X
,
864 r
* PIECE_HEIGHT
+ BOARD_Y
, PIECE_WIDTH
,
869 if(pb
->playboard
[r
][c
] == PLAYER
) {
873 else if (type
!= WALL
&& type
!= SPACE
&& type
!= HOLE
)
879 rb
->snprintf(str
, 3, "%d", pb
->level
);
880 rb
->lcd_putsxy(TEXT_X
, LEVEL_TEXT_Y
, str
);
881 rb
->snprintf(str
, 3, "%d", pb
->num_left
);
882 rb
->lcd_putsxy(TEXT_X
, PEGS_TEXT_Y
, str
);
884 rb
->snprintf(str
, 3, "%d", pb
->level
);
885 rb
->lcd_putsxy(LEVEL_TEXT_X
, TEXT_Y
, str
);
886 rb
->snprintf(str
, 3, "%d", pb
->num_left
);
887 rb
->lcd_putsxy(PEGS_TEXT_X
, TEXT_Y
, str
);
888 #endif /*WIDE_LAYOUT*/
890 #ifdef HAVE_LCD_COLOR
891 rb
->lcd_set_background(BG_COLOR
);
892 rb
->lcd_set_foreground(LCD_WHITE
);
894 /* print out the screen */
898 /*****************************************************************************
899 * load_level() loads the player's current level from the array and sets the
901 ******************************************************************************/
902 static void load_level(struct game_context
* pb
) {
905 for(r
= 0; r
< ROWS
; r
++)
906 for(c
= 0; c
< COLS
; c
++)
907 pb
->playboard
[r
][c
] = levels
[pb
->level
-1][r
][c
];
910 /*****************************************************************************
911 * new_piece() creates a new piece at a specified location. The player
912 * navigates through the pieces and selects one.
913 ******************************************************************************/
914 static void new_piece(struct game_context
* pb
, unsigned int x_loc
,
915 unsigned int y_loc
) {
919 pb
->playboard
[x_loc
][y_loc
] = TRIANGLE
;
923 button
= rb
->button_get(true);
924 #ifdef HAVE_TOUCHSCREEN
925 if(button
& BUTTON_TOUCHSCREEN
)
927 pegbox_raster_btn
.two_d_from
.y
= x_loc
;
928 pegbox_raster_btn
.two_d_from
.x
= y_loc
;
930 struct ts_raster_button_result ret
=
931 touchscreen_raster_map_button(&pegbox_raster_btn
,
932 rb
->button_get_data() >> 16,
933 rb
->button_get_data() & 0xffff,
935 if(ret
.action
== TS_ACTION_TWO_D_MOVEMENT
)
937 if(ret
.to
.x
> ret
.from
.x
)
939 else if(ret
.to
.x
< ret
.from
.x
)
940 button
= PEGBOX_DOWN
;
941 else if(ret
.to
.y
> ret
.from
.y
)
942 button
= PEGBOX_LEFT
;
943 else if(ret
.to
.y
< ret
.from
.y
)
944 button
= PEGBOX_RIGHT
;
946 else if(ret
.action
== TS_ACTION_CLICK
947 && (unsigned)ret
.to
.x
== y_loc
948 && (unsigned)ret
.to
.y
== x_loc
)
949 button
= PEGBOX_SAVE
;
954 case (PEGBOX_LEFT
|BUTTON_REPEAT
):
956 case (PEGBOX_DOWN
|BUTTON_REPEAT
):
957 if (pb
->playboard
[x_loc
][y_loc
] < 5)
958 pb
->playboard
[x_loc
][y_loc
]++;
960 pb
->playboard
[x_loc
][y_loc
] = TRIANGLE
;
963 case (PEGBOX_RIGHT
|BUTTON_REPEAT
):
965 case (PEGBOX_UP
|BUTTON_REPEAT
):
966 if (pb
->playboard
[x_loc
][y_loc
] > 2)
967 pb
->playboard
[x_loc
][y_loc
]--;
969 pb
->playboard
[x_loc
][y_loc
] = CIRCLE
;
978 /*****************************************************************************
979 * move_player() moves the player and pieces and updates the board accordingly.
980 ******************************************************************************/
981 static void move_player(struct game_context
* pb
, signed int x_dir
,
983 unsigned int type1
, type2
;
986 r
= pb
->player_row
+y_dir
;
987 c
= pb
->player_col
+x_dir
;
989 type1
= pb
->playboard
[r
][c
];
990 type2
= pb
->playboard
[r
+y_dir
][c
+x_dir
];
992 if (r
== ROWS
|| c
== COLS
|| r
< 0 || c
< 0 || type1
== WALL
)
994 else if(type1
!= SPACE
) {
995 if (type2
== WALL
|| r
+y_dir
== ROWS
|| c
+x_dir
== COLS
||
996 r
+y_dir
< 0 || c
+x_dir
< 0)
1001 pb
->playboard
[pb
->player_row
][pb
->player_col
] = SPACE
;
1002 pb
->player_row
+= y_dir
;
1003 pb
->player_col
+= x_dir
;
1005 if (type1
== HOLE
) {
1007 rb
->splash(HZ
*2, "You fell down a hole!");
1010 else if (type1
== SPACE
)
1011 pb
->playboard
[r
][c
] = PLAYER
;
1013 pb
->playboard
[r
][c
] = PLAYER
;
1014 if(type1
== type2
) {
1015 if (type1
== TRIANGLE
)
1016 pb
->playboard
[r
+y_dir
][c
+x_dir
] = WALL
;
1017 else if (type1
== CROSS
) {
1018 pb
->playboard
[r
][c
] = SPACE
;
1019 new_piece(pb
, r
+y_dir
, c
+x_dir
);
1020 pb
->playboard
[r
][c
] = PLAYER
;
1023 pb
->playboard
[r
+y_dir
][c
+x_dir
] = SPACE
;
1025 else if (type2
== SPACE
)
1026 pb
->playboard
[r
+y_dir
][c
+x_dir
] = type1
;
1027 else if (type2
== HOLE
) {
1028 if (type1
== SQUARE
)
1029 pb
->playboard
[r
+y_dir
][c
+x_dir
] = SPACE
;
1032 rb
->splash(HZ
*2, "Illegal Move!");
1040 /*****************************************************************************
1041 * pegbox_loadgame() loads the saved game and returns load success.
1042 ******************************************************************************/
1043 static bool pegbox_loadgame(struct game_context
* pb
) {
1045 bool loaded
= false;
1047 /* open game file */
1048 fd
= rb
->open(SAVE_FILE
, O_RDONLY
);
1049 if(fd
< 0) return loaded
;
1051 /* read in saved game */
1053 if(rb
->read(fd
, &pb
->level
, sizeof(pb
->level
)) <= 0) break;
1054 if(rb
->read(fd
, &pb
->playboard
, sizeof(pb
->playboard
)) <= 0)
1066 /*****************************************************************************
1067 * pegbox_savegame() saves the current game state.
1068 ******************************************************************************/
1069 static void pegbox_savegame(struct game_context
* pb
) {
1072 /* write out the game state to the save file */
1073 fd
= rb
->open(SAVE_FILE
, O_WRONLY
|O_CREAT
);
1074 rb
->write(fd
, &pb
->level
, sizeof(pb
->level
));
1075 rb
->write(fd
, &pb
->playboard
, sizeof(pb
->playboard
));
1079 /*****************************************************************************
1080 * pegbox_loaddata() loads the level and highlevel and returns load success.
1081 ******************************************************************************/
1082 static void pegbox_loaddata(struct game_context
* pb
) {
1085 /* open game file */
1086 fd
= rb
->open(DATA_FILE
, O_RDONLY
);
1093 /* read in saved game */
1095 if(rb
->read(fd
, &pb
->level
, sizeof(pb
->level
)) <= 0) break;
1096 if(rb
->read(fd
, &pb
->highlevel
, sizeof(pb
->highlevel
)) <= 0) break;
1104 /*****************************************************************************
1105 * pegbox_savedata() saves the level and highlevel.
1106 ******************************************************************************/
1107 static void pegbox_savedata(struct game_context
* pb
) {
1110 /* write out the game state to the save file */
1111 fd
= rb
->open(DATA_FILE
, O_WRONLY
|O_CREAT
);
1112 rb
->write(fd
, &pb
->level
, sizeof(pb
->level
));
1113 rb
->write(fd
, &pb
->highlevel
, sizeof(pb
->highlevel
));
1117 /*****************************************************************************
1118 * pegbox_callback() is the default event handler callback which is called
1119 * on usb connect and shutdown.
1120 ******************************************************************************/
1121 static void pegbox_callback(void* param
) {
1122 struct game_context
* pb
= (struct game_context
*) param
;
1123 rb
->splash(HZ
, "Saving data...");
1124 pegbox_savedata(pb
);
1127 /*****************************************************************************
1128 * pegbox_menu() is the initial menu at the start of the game.
1129 ******************************************************************************/
1130 static unsigned int pegbox_menu(struct game_context
* pb
) {
1133 unsigned int startlevel
= 1, loc
= 0;
1134 bool breakout
= false, can_resume
= false;
1136 if (pb
->num_left
> 0 || pb
->save_exist
)
1140 #if LCD_HEIGHT >= 80
1141 rb
->lcd_clear_display();
1142 rb
->lcd_bitmap(pegbox_menu_top
,0,0,LCD_WIDTH
, BMPHEIGHT_pegbox_menu_top
);
1146 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
, ITEM_WIDTH
,
1147 MENU_X
, MENU_Y
, ITEM_WIDTH
, ITEM_HEIGHT
);
1150 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, 0, ITEM_WIDTH
,
1151 MENU_X
, MENU_Y
, ITEM_WIDTH
, ITEM_HEIGHT
);
1155 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*3, ITEM_WIDTH
,
1156 MENU_X
, MENU_Y
+ITEM_HEIGHT
, ITEM_WIDTH
, ITEM_HEIGHT
);
1159 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*2, ITEM_WIDTH
,
1160 MENU_X
, MENU_Y
+ITEM_HEIGHT
, ITEM_WIDTH
, ITEM_HEIGHT
);
1164 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*4, ITEM_WIDTH
,
1165 MENU_X
, MENU_Y
+ITEM_HEIGHT
, ITEM_WIDTH
, ITEM_HEIGHT
);
1169 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*6, ITEM_WIDTH
,
1170 MENU_X
, MENU_Y
+ITEM_HEIGHT
*2, ITEM_WIDTH
, ITEM_HEIGHT
);
1173 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*5, ITEM_WIDTH
,
1174 MENU_X
, MENU_Y
+ITEM_HEIGHT
*2, ITEM_WIDTH
, ITEM_HEIGHT
);
1178 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*8, ITEM_WIDTH
,
1179 MENU_X
, MENU_Y
+ITEM_HEIGHT
*3, ITEM_WIDTH
, ITEM_HEIGHT
);
1182 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*7, ITEM_WIDTH
,
1183 MENU_X
, MENU_Y
+ITEM_HEIGHT
*3, ITEM_WIDTH
, ITEM_HEIGHT
);
1187 rb
->lcd_clear_display();
1188 rb
->lcd_getstringsize("PegBox", &w
, &h
);
1189 rb
->lcd_putsxy((LCD_WIDTH
-w
)/2, 0, "PegBox");
1190 rb
->lcd_putsxy((LCD_WIDTH
)/4, 16, "New Game");
1191 rb
->lcd_putsxy((LCD_WIDTH
)/4, 24, "Resume");
1192 rb
->lcd_putsxy((LCD_WIDTH
)/4, 32, "Help");
1193 rb
->lcd_putsxy((LCD_WIDTH
)/4, 40, "Quit");
1196 rb
->lcd_hline((LCD_WIDTH
)/4, (LCD_WIDTH
)/4+30, 28);
1198 rb
->lcd_putsxy((LCD_WIDTH
)/4-8, loc
*8+16, "*");
1202 rb
->snprintf(str
, 28, "Start on level %d of %d", startlevel
,
1204 #if LCD_HEIGHT > 110
1205 rb
->lcd_putsxy(0, MENU_Y
+4*ITEM_HEIGHT
+8, str
);
1206 #elif LCD_HEIGHT > 64
1207 rb
->lcd_putsxy(0, LCD_HEIGHT
- 8, str
);
1209 rb
->lcd_puts_scroll(0, 7, str
);
1213 /* handle menu button presses */
1214 button
= rb
->button_get(true);
1216 #ifdef HAVE_TOUCHSCREEN
1217 if(button
& BUTTON_TOUCHSCREEN
)
1219 unsigned int result
= touchscreen_map(&main_menu
,
1220 rb
->button_get_data() >> 16,
1221 rb
->button_get_data() & 0xffff);
1222 if(result
!= (unsigned)-1 && button
& BUTTON_REL
)
1225 button
= PEGBOX_LVL_UP
;
1229 button
= PEGBOX_RIGHT
;
1237 case PEGBOX_SAVE
: /* start playing */
1241 pb
->level
= startlevel
;
1244 else if (loc
== 1 && can_resume
) {
1247 rb
->remove(SAVE_FILE
);
1248 pb
->save_exist
= false;
1253 display_text("How to Play\nTo beat each level, you must "
1254 "destroy all of the pegs. If two like pegs are "
1255 "pushed into each other they disappear except "
1256 "for triangles which form a solid block and "
1257 "crosses which allow you to choose a "
1258 "replacement block.\n\n"
1261 RESTART_TEXT
" to restart level\n"
1262 LVL_UP_TEXT
" to go up a level\n"
1263 LVL_DOWN_TEXT
" to go down a level\n"
1264 SAVE_TEXT
" to select/save\n"
1265 QUIT_TEXT
" to quit\n",true);
1267 RESTART_TEXT
": restart\n"
1268 LVL_UP_TEXT
": level up\n"
1269 LVL_DOWN_TEXT
" level down\n"
1270 SAVE_TEXT
" select/save\n"
1271 QUIT_TEXT
" quit\n",true);
1277 case PEGBOX_QUIT
: /* quit program */
1280 case (PEGBOX_UP
|BUTTON_REPEAT
):
1286 if (!can_resume
&& loc
== 1) {
1292 case (PEGBOX_DOWN
|BUTTON_REPEAT
):
1298 if (!can_resume
&& loc
== 1) {
1303 case (PEGBOX_LVL_UP
|BUTTON_REPEAT
):
1304 case PEGBOX_LVL_UP
: /* increase starting level */
1305 if(startlevel
>= pb
->highlevel
) {
1312 /* only for targets with enough buttons */
1313 #ifdef PEGBOX_LVL_DOWN
1314 case (PEGBOX_LVL_DOWN
|BUTTON_REPEAT
):
1315 case PEGBOX_LVL_DOWN
: /* decrease starting level */
1316 if(startlevel
<= 1) {
1317 startlevel
= pb
->highlevel
;
1324 if(rb
->default_event_handler_ex(button
, pegbox_callback
,
1325 (void*) pb
) == SYS_USB_CONNECTED
)
1336 /*****************************************************************************
1337 * pegbox() is the main game subroutine, it returns the final game status.
1338 ******************************************************************************/
1339 static int pegbox(struct game_context
* pb
) {
1342 /********************
1344 ********************/
1345 temp_var
= pegbox_menu(pb
);
1346 if (temp_var
== PB_QUIT
|| temp_var
== PB_USB
)
1350 temp_var
= rb
->button_get(true);
1351 #ifdef HAVE_TOUCHSCREEN
1352 if(temp_var
& BUTTON_TOUCHSCREEN
)
1354 pegbox_raster_btn
.two_d_from
.y
= pb
->player_row
;
1355 pegbox_raster_btn
.two_d_from
.x
= pb
->player_col
;
1357 struct ts_raster_button_result ret
=
1358 touchscreen_raster_map_button(&pegbox_raster_btn
,
1359 rb
->button_get_data() >> 16,
1360 rb
->button_get_data() & 0xffff,
1362 if(ret
.action
== TS_ACTION_TWO_D_MOVEMENT
)
1363 move_player(pb
, ret
.to
.x
- ret
.from
.x
, ret
.to
.y
- ret
.from
.y
);
1367 case PEGBOX_LEFT
: /* move cursor left */
1368 case (PEGBOX_LEFT
|BUTTON_REPEAT
):
1369 move_player(pb
, -1, 0);
1372 case PEGBOX_RIGHT
: /* move cursor right */
1373 case (PEGBOX_RIGHT
|BUTTON_REPEAT
):
1374 move_player(pb
, 1, 0);
1377 case PEGBOX_DOWN
: /* move cursor down */
1378 case (PEGBOX_DOWN
|BUTTON_REPEAT
):
1379 move_player(pb
, 0, 1);
1382 case PEGBOX_UP
: /* move cursor up */
1383 case (PEGBOX_UP
|BUTTON_REPEAT
):
1384 move_player(pb
, 0, -1);
1387 case PEGBOX_SAVE
: /* save and end game */
1388 rb
->splash(HZ
, "Saving game...");
1389 pegbox_savegame(pb
);
1390 /* fall through to PEGBOX_QUIT */
1395 case PEGBOX_RESTART
:
1400 case (PEGBOX_LVL_UP
|BUTTON_REPEAT
):
1402 if(pb
->level
>= pb
->highlevel
) {
1411 /* only for targets with enough buttons */
1412 #ifdef PEGBOX_LVL_DOWN
1413 case (PEGBOX_LVL_DOWN
|BUTTON_REPEAT
):
1414 case PEGBOX_LVL_DOWN
:
1415 if(pb
->level
<= 1) {
1416 pb
->level
= pb
->highlevel
;
1427 if(pb
->num_left
== 0) {
1428 rb
->splash(HZ
*2, "Nice Pegging!");
1429 if(pb
->level
== NUM_LEVELS
) {
1431 rb
->splash(HZ
*2, "You Won!");
1440 if(pb
->level
> pb
->highlevel
)
1441 pb
->highlevel
= pb
->level
;
1450 /*****************************************************************************
1451 * plugin entry point.
1452 ******************************************************************************/
1453 enum plugin_status
plugin_start(const void* parameter
) {
1455 struct game_context pb
;
1459 rb
->lcd_setfont(FONT_SYSFIXED
);
1461 rb
->lcd_set_backdrop(NULL
);
1463 #ifdef HAVE_LCD_COLOR
1464 rb
->lcd_set_foreground(LCD_WHITE
);
1465 rb
->lcd_set_background(BG_COLOR
);
1468 rb
->splash(0, "Loading...");
1469 pegbox_loaddata(&pb
);
1470 pb
.save_exist
= pegbox_loadgame(&pb
);
1473 rb
->lcd_clear_display();
1477 switch(pegbox(&pb
)){
1482 rb
->lcd_setfont(FONT_UI
);
1483 return PLUGIN_USB_CONNECTED
;
1486 rb
->splash(HZ
, "Saving data...");
1487 pegbox_savedata(&pb
);
1496 rb
->lcd_setfont(FONT_UI
);