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 ****************************************************************************/
22 #include "lib/display_text.h"
24 #include "pluginbitmaps/pegbox_header.h"
25 #include "pluginbitmaps/pegbox_pieces.h"
27 #if LCD_HEIGHT >= 80 /* enough space for a graphical menu */
28 #include "pluginbitmaps/pegbox_menu_top.h"
29 #include "pluginbitmaps/pegbox_menu_items.h"
30 #define MENU_X (LCD_WIDTH-BMPWIDTH_pegbox_menu_items)/2
31 #define MENU_Y BMPHEIGHT_pegbox_menu_top
32 #define ITEM_WIDTH BMPWIDTH_pegbox_menu_items
33 #define ITEM_HEIGHT (BMPHEIGHT_pegbox_menu_items/9)
38 /* final game return status */
43 #define DATA_FILE PLUGIN_GAMES_DIR "/pegbox.data"
44 #define SAVE_FILE PLUGIN_GAMES_DIR "/pegbox.save"
46 #define ROWS 8 /* Number of rows on each board */
47 #define COLS 12 /* Number of columns on each board */
48 #define NUM_LEVELS 15 /* Number of levels */
59 #if CONFIG_KEYPAD == RECORDER_PAD
60 #define PEGBOX_SAVE BUTTON_ON
61 #define PEGBOX_QUIT BUTTON_OFF
62 #define PEGBOX_RESTART BUTTON_F2
63 #define PEGBOX_LVL_UP BUTTON_F1
64 #define PEGBOX_LVL_DOWN BUTTON_F3
65 #define PEGBOX_UP BUTTON_UP
66 #define PEGBOX_DOWN BUTTON_DOWN
67 #define PEGBOX_RIGHT BUTTON_RIGHT
68 #define PEGBOX_LEFT BUTTON_LEFT
70 #define SAVE_TEXT "ON"
71 #define QUIT_TEXT "OFF"
72 #define RESTART_TEXT "F2"
73 #define LVL_UP_TEXT "F1"
74 #define LVL_DOWN_TEXT "F3"
76 #elif CONFIG_KEYPAD == ONDIO_PAD
77 #define PEGBOX_SAVE BUTTON_OFF
78 #define PEGBOX_QUIT (BUTTON_MENU | BUTTON_LEFT)
79 #define PEGBOX_RESTART (BUTTON_MENU | BUTTON_RIGHT)
80 #define PEGBOX_LVL_UP (BUTTON_MENU | BUTTON_UP)
81 #define PEGBOX_LVL_DOWN (BUTTON_MENU | BUTTON_DOWN)
82 #define PEGBOX_UP BUTTON_UP
83 #define PEGBOX_DOWN BUTTON_DOWN
84 #define PEGBOX_RIGHT BUTTON_RIGHT
85 #define PEGBOX_LEFT BUTTON_LEFT
87 #define SAVE_TEXT "OFF"
88 #define QUIT_TEXT "M+LEFT"
89 #define RESTART_TEXT "M+RIGHT"
90 #define LVL_UP_TEXT "M+UP"
91 #define LVL_DOWN_TEXT "M+DOWN"
93 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
94 (CONFIG_KEYPAD == IRIVER_H300_PAD)
95 #define PEGBOX_SAVE BUTTON_SELECT
96 #define PEGBOX_QUIT BUTTON_OFF
97 #define PEGBOX_RESTART BUTTON_ON
98 #define PEGBOX_LVL_UP BUTTON_MODE
99 #define PEGBOX_LVL_DOWN BUTTON_REC
100 #define PEGBOX_UP BUTTON_UP
101 #define PEGBOX_DOWN BUTTON_DOWN
102 #define PEGBOX_RIGHT BUTTON_RIGHT
103 #define PEGBOX_LEFT BUTTON_LEFT
105 #define SAVE_TEXT "NAVI"
106 #define QUIT_TEXT "OFF"
107 #define RESTART_TEXT "ON"
108 #define LVL_UP_TEXT "AB"
109 #define LVL_DOWN_TEXT "REC"
111 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
112 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
113 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
114 #define PEGBOX_SAVE (BUTTON_SELECT|BUTTON_RIGHT)
115 #define PEGBOX_QUIT (BUTTON_SELECT|BUTTON_PLAY)
116 #define PEGBOX_RESTART (BUTTON_SELECT|BUTTON_LEFT)
117 #define PEGBOX_LVL_UP (BUTTON_SELECT|BUTTON_MENU)
118 #define PEGBOX_UP BUTTON_MENU
119 #define PEGBOX_DOWN BUTTON_PLAY
120 #define PEGBOX_RIGHT BUTTON_RIGHT
121 #define PEGBOX_LEFT BUTTON_LEFT
123 #define SAVE_TEXT "SELECT+RIGHT"
124 #define QUIT_TEXT "SELECT+PLAY"
125 #define RESTART_TEXT "SELECT+LEFT"
126 #define LVL_UP_TEXT "SELECT+MENU"
127 #define LVL_DOWN_TEXT "-"
129 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
130 #define PEGBOX_SAVE BUTTON_SELECT
131 #define PEGBOX_QUIT BUTTON_POWER
132 #define PEGBOX_RESTART BUTTON_REC
133 #define PEGBOX_LVL_UP BUTTON_PLAY
134 #define PEGBOX_UP BUTTON_UP
135 #define PEGBOX_DOWN BUTTON_DOWN
136 #define PEGBOX_RIGHT BUTTON_RIGHT
137 #define PEGBOX_LEFT BUTTON_LEFT
139 #define SAVE_TEXT "SELECT"
140 #define QUIT_TEXT "OFF"
141 #define RESTART_TEXT "REC"
142 #define LVL_UP_TEXT "PLAY"
143 #define LVL_DOWN_TEXT "-"
145 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
146 #define PEGBOX_SAVE BUTTON_MODE
147 #define PEGBOX_QUIT BUTTON_PLAY
148 #define PEGBOX_RESTART (BUTTON_EQ|BUTTON_MODE)
149 #define PEGBOX_LVL_UP (BUTTON_EQ|BUTTON_UP)
150 #define PEGBOX_LVL_DOWN (BUTTON_EQ|BUTTON_DOWN)
151 #define PEGBOX_UP BUTTON_UP
152 #define PEGBOX_DOWN BUTTON_DOWN
153 #define PEGBOX_RIGHT BUTTON_RIGHT
154 #define PEGBOX_LEFT BUTTON_LEFT
156 #define SAVE_TEXT "MODE"
157 #define QUIT_TEXT "PLAY"
158 #define RESTART_TEXT "EQ+MODE"
159 #define LVL_UP_TEXT "EQ+UP"
160 #define LVL_DOWN_TEXT "EQ+DOWN"
162 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
163 #define PEGBOX_SAVE BUTTON_PLAY
164 #define PEGBOX_QUIT BUTTON_POWER
165 #define PEGBOX_RESTART (BUTTON_FF|BUTTON_REPEAT)
166 #define PEGBOX_LVL_UP (BUTTON_FF|BUTTON_SCROLL_UP)
167 #define PEGBOX_LVL_DOWN (BUTTON_FF|BUTTON_SCROLL_DOWN)
168 #define PEGBOX_UP BUTTON_SCROLL_UP
169 #define PEGBOX_DOWN BUTTON_SCROLL_DOWN
170 #define PEGBOX_RIGHT BUTTON_RIGHT
171 #define PEGBOX_LEFT BUTTON_LEFT
173 #define SAVE_TEXT "PLAY"
174 #define QUIT_TEXT "OFF"
175 #define RESTART_TEXT "LONG FF"
176 #define LVL_UP_TEXT "FF+SCROLL_UP"
177 #define LVL_DOWN_TEXT "FF+SCROLL_DOWN"
179 #elif CONFIG_KEYPAD == SANSA_E200_PAD
180 #define PEGBOX_SAVE BUTTON_SELECT
181 #define PEGBOX_QUIT BUTTON_POWER
182 #define PEGBOX_RESTART BUTTON_REC
183 #define PEGBOX_LVL_UP BUTTON_SCROLL_BACK
184 #define PEGBOX_LVL_DOWN BUTTON_SCROLL_FWD
185 #define PEGBOX_UP BUTTON_UP
186 #define PEGBOX_DOWN BUTTON_DOWN
187 #define PEGBOX_RIGHT BUTTON_RIGHT
188 #define PEGBOX_LEFT BUTTON_LEFT
190 #define SAVE_TEXT "SELECT"
191 #define QUIT_TEXT "POWER"
192 #define RESTART_TEXT "REC"
193 #define LVL_UP_TEXT "SCROLL BACK"
194 #define LVL_DOWN_TEXT "SCROLL FWD"
196 #elif CONFIG_KEYPAD == SANSA_FUZE_PAD
197 #define PEGBOX_SAVE BUTTON_SELECT|BUTTON_REL
198 #define PEGBOX_QUIT (BUTTON_HOME|BUTTON_REPEAT)
199 #define PEGBOX_RESTART (BUTTON_SELECT|BUTTON_LEFT)
200 #define PEGBOX_LVL_UP (BUTTON_SELECT|BUTTON_UP)
201 #define PEGBOX_LVL_DOWN (BUTTON_SELECT|BUTTON_DOWN)
202 #define PEGBOX_UP BUTTON_UP
203 #define PEGBOX_DOWN BUTTON_DOWN
204 #define PEGBOX_RIGHT BUTTON_RIGHT
205 #define PEGBOX_LEFT BUTTON_LEFT
207 #define SAVE_TEXT "SELECT"
208 #define QUIT_TEXT "HOME"
209 #define RESTART_TEXT "SELECT & LEFT"
210 #define LVL_UP_TEXT "SELECT & UP"
211 #define LVL_DOWN_TEXT "SELECT & DOWN"
213 #elif CONFIG_KEYPAD == GIGABEAT_PAD
214 #define PEGBOX_SAVE BUTTON_SELECT
215 #define PEGBOX_QUIT BUTTON_POWER
216 #define PEGBOX_RESTART BUTTON_A
217 #define PEGBOX_LVL_UP BUTTON_VOL_UP
218 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
219 #define PEGBOX_UP BUTTON_UP
220 #define PEGBOX_DOWN BUTTON_DOWN
221 #define PEGBOX_RIGHT BUTTON_RIGHT
222 #define PEGBOX_LEFT BUTTON_LEFT
224 #define SAVE_TEXT "SELECT"
225 #define QUIT_TEXT "POWER"
226 #define RESTART_TEXT "A"
227 #define LVL_UP_TEXT "VOL+"
228 #define LVL_DOWN_TEXT "VOL-"
230 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
231 #define PEGBOX_SAVE BUTTON_SELECT
232 #define PEGBOX_QUIT BUTTON_BACK
233 #define PEGBOX_RESTART BUTTON_MENU
234 #define PEGBOX_LVL_UP BUTTON_VOL_UP
235 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
236 #define PEGBOX_UP BUTTON_UP
237 #define PEGBOX_DOWN BUTTON_DOWN
238 #define PEGBOX_RIGHT BUTTON_RIGHT
239 #define PEGBOX_LEFT BUTTON_LEFT
241 #define SAVE_TEXT "SELECT"
242 #define QUIT_TEXT "BACK"
243 #define RESTART_TEXT "MENU"
244 #define LVL_UP_TEXT "VOL+"
245 #define LVL_DOWN_TEXT "VOL-"
247 #elif CONFIG_KEYPAD == MROBE100_PAD
248 #define PEGBOX_SAVE BUTTON_SELECT
249 #define PEGBOX_QUIT BUTTON_POWER
250 #define PEGBOX_RESTART BUTTON_PLAY
251 #define PEGBOX_LVL_UP BUTTON_MENU
252 #define PEGBOX_LVL_DOWN BUTTON_DISPLAY
253 #define PEGBOX_UP BUTTON_UP
254 #define PEGBOX_DOWN BUTTON_DOWN
255 #define PEGBOX_RIGHT BUTTON_RIGHT
256 #define PEGBOX_LEFT BUTTON_LEFT
258 #define SAVE_TEXT "SELECT"
259 #define QUIT_TEXT "POWER"
260 #define RESTART_TEXT "PLAY"
261 #define LVL_UP_TEXT "MENU"
262 #define LVL_DOWN_TEXT "DISPLAY"
264 #elif CONFIG_KEYPAD == SANSA_C200_PAD
265 #define PEGBOX_SAVE BUTTON_SELECT
266 #define PEGBOX_QUIT BUTTON_POWER
267 #define PEGBOX_RESTART BUTTON_REC
268 #define PEGBOX_LVL_UP BUTTON_VOL_UP
269 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
270 #define PEGBOX_UP BUTTON_UP
271 #define PEGBOX_DOWN BUTTON_DOWN
272 #define PEGBOX_RIGHT BUTTON_RIGHT
273 #define PEGBOX_LEFT BUTTON_LEFT
275 #define SAVE_TEXT "SELECT"
276 #define QUIT_TEXT "POWER"
277 #define RESTART_TEXT "REC"
278 #define LVL_UP_TEXT "VOL+"
279 #define LVL_DOWN_TEXT "VOL-"
281 #elif CONFIG_KEYPAD == SANSA_CLIP_PAD
282 #define PEGBOX_SAVE BUTTON_SELECT
283 #define PEGBOX_QUIT BUTTON_POWER
284 #define PEGBOX_RESTART BUTTON_HOME
285 #define PEGBOX_LVL_UP BUTTON_VOL_UP
286 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
287 #define PEGBOX_UP BUTTON_UP
288 #define PEGBOX_DOWN BUTTON_DOWN
289 #define PEGBOX_RIGHT BUTTON_RIGHT
290 #define PEGBOX_LEFT BUTTON_LEFT
292 #define SAVE_TEXT "SELECT"
293 #define QUIT_TEXT "POWER"
294 #define RESTART_TEXT "HOME"
295 #define LVL_UP_TEXT "VOL+"
296 #define LVL_DOWN_TEXT "VOL-"
298 #elif CONFIG_KEYPAD == SANSA_M200_PAD
299 #define PEGBOX_SAVE (BUTTON_SELECT | BUTTON_REL)
300 #define PEGBOX_QUIT BUTTON_POWER
301 #define PEGBOX_RESTART (BUTTON_SELECT | BUTTON_UP)
302 #define PEGBOX_LVL_UP BUTTON_VOL_UP
303 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
304 #define PEGBOX_UP BUTTON_UP
305 #define PEGBOX_DOWN BUTTON_DOWN
306 #define PEGBOX_RIGHT BUTTON_RIGHT
307 #define PEGBOX_LEFT BUTTON_LEFT
309 #define SAVE_TEXT "SELECT"
310 #define QUIT_TEXT "POWER"
311 #define RESTART_TEXT "SELECT+UP"
312 #define LVL_UP_TEXT "VOL+"
313 #define LVL_DOWN_TEXT "VOL-"
316 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
317 #define PEGBOX_SAVE BUTTON_RC_PLAY
318 #define PEGBOX_QUIT BUTTON_RC_REC
319 #define PEGBOX_RESTART BUTTON_RC_MODE
320 #define PEGBOX_LVL_UP BUTTON_VOL_UP
321 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
322 #define PEGBOX_UP BUTTON_RC_VOL_UP
323 #define PEGBOX_DOWN BUTTON_RC_VOL_DOWN
324 #define PEGBOX_RIGHT BUTTON_RC_FF
325 #define PEGBOX_LEFT BUTTON_RC_REW
327 #define SAVE_TEXT "REM. PLAY"
328 #define QUIT_TEXT "REM. REC"
329 #define RESTART_TEXT "REM. MODE"
330 #define LVL_UP_TEXT "VOL+"
331 #define LVL_DOWN_TEXT "VOL-"
333 #elif CONFIG_KEYPAD == COWOND2_PAD
334 #define PEGBOX_QUIT BUTTON_POWER
336 #define QUIT_TEXT "POWER"
338 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
339 #define PEGBOX_SAVE BUTTON_CUSTOM
340 #define PEGBOX_QUIT BUTTON_BACK
341 #define PEGBOX_RESTART BUTTON_SELECT
342 #define PEGBOX_LVL_UP BUTTON_PLAY
343 #define PEGBOX_LVL_DOWN BUTTON_MENU
344 #define PEGBOX_UP BUTTON_UP
345 #define PEGBOX_DOWN BUTTON_DOWN
346 #define PEGBOX_RIGHT BUTTON_RIGHT
347 #define PEGBOX_LEFT BUTTON_LEFT
349 #define SAVE_TEXT "CUSTOM"
350 #define QUIT_TEXT "BACK"
351 #define RESTART_TEXT "MIDDLE"
352 #define LVL_UP_TEXT "SELECT"
353 #define LVL_DOWN_TEXT "MENU"
355 #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
356 #define PEGBOX_SAVE BUTTON_VIEW
357 #define PEGBOX_QUIT BUTTON_POWER
358 #define PEGBOX_RESTART BUTTON_MENU
359 #define PEGBOX_LVL_UP BUTTON_VOL_UP
360 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
361 #define PEGBOX_UP BUTTON_UP
362 #define PEGBOX_DOWN BUTTON_DOWN
363 #define PEGBOX_RIGHT BUTTON_RIGHT
364 #define PEGBOX_LEFT BUTTON_LEFT
366 #define SAVE_TEXT "VIEW"
367 #define QUIT_TEXT "POWER"
368 #define RESTART_TEXT "MENU"
369 #define LVL_UP_TEXT "VOL+"
370 #define LVL_DOWN_TEXT "VOL-"
372 #elif CONFIG_KEYPAD == ONDAVX747_PAD || CONFIG_KEYPAD == MROBE500_PAD
373 #define PEGBOX_QUIT BUTTON_POWER
375 #define QUIT_TEXT "POWER"
378 #error Unsupported keymap!
381 #ifdef HAVE_TOUCHSCREEN
383 #define PEGBOX_QUIT BUTTON_TOPLEFT
386 #define PEGBOX_SAVE BUTTON_CENTER
388 #ifndef PEGBOX_RESTART
389 #define PEGBOX_RESTART BUTTON_TOPRIGHT
391 #ifndef PEGBOX_LVL_UP
392 #define PEGBOX_LVL_UP BUTTON_BOTTOMLEFT
394 #ifndef PEGBOX_LVL_DOWN
395 #define PEGBOX_LVL_DOWN BUTTON_BOTTOMRIGHT
398 #define PEGBOX_UP BUTTON_TOPMIDDLE
401 #define PEGBOX_DOWN BUTTON_BOTTOMMIDDLE
404 #define PEGBOX_RIGHT BUTTON_MIDRIGHT
407 #define PEGBOX_LEFT BUTTON_MIDLEFT
410 #define SAVE_TEXT "CENTER"
413 #define QUIT_TEXT "TOPLEFT"
416 #define RESTART_TEXT "TOPRIGHT"
419 #define LVL_UP_TEXT "BOTTOMLEFT"
421 #ifndef LVL_DOWN_TEXT
422 #define LVL_DOWN_TEXT "BOTTOMRIGHT"
427 /* get several sizes from the bitmaps */
428 #ifdef BMPWIDTH_pegbox_pieces
429 #define PIECE_WIDTH BMPWIDTH_pegbox_pieces
430 #define PIECE_HEIGHT (BMPHEIGHT_pegbox_pieces/7)
432 /* dummy numbers to avoid #error in dependency generation */
433 #define PIECE_WIDTH 50
434 #define PIECE_HEIGHT 10
437 #define BOARD_WIDTH (12*PIECE_WIDTH)
438 #define BOARD_HEIGHT (8*PIECE_HEIGHT)
441 /* define a wide layout where the statistics are alongside the board, not above
442 * base calculation on the piece bitmaps for the 8x12 board */
443 #if (LCD_WIDTH - BOARD_WIDTH) > (LCD_HEIGHT - BOARD_HEIGHT)
448 #define HEADER_WIDTH BMPWIDTH_pegbox_header
449 #define HEADER_HEIGHT BMPHEIGHT_pegbox_header
452 #if defined WIDE_LAYOUT
454 #if ((BOARD_WIDTH + HEADER_WIDTH + 4) <= LCD_WIDTH)
459 #define BOARD_Y (LCD_HEIGHT-BOARD_HEIGHT)/2
461 #if (LCD_WIDTH >= 132) && (LCD_HEIGHT >= 80)
463 #define LEVEL_TEXT_Y 14
464 #define PEGS_TEXT_Y 58
465 #elif (LCD_WIDTH >= 128) && (LCD_HEIGHT >= 64)
467 #define LEVEL_TEXT_Y 27
468 #define PEGS_TEXT_Y 50
470 #error "Unsupported screen size"
473 #else /* "normal" layout */
475 #define BOARD_X (LCD_WIDTH-BOARD_WIDTH)/2
476 #if ((BOARD_HEIGHT + HEADER_HEIGHT + 4) <= LCD_HEIGHT)
477 #define BOARD_Y HEADER_HEIGHT+2
479 #define BOARD_Y HEADER_HEIGHT
483 #define LEVEL_TEXT_X 59
484 #define PEGS_TEXT_X 276
486 #elif LCD_WIDTH >= 240
487 #define LEVEL_TEXT_X 59
488 #define PEGS_TEXT_X 196
490 #elif LCD_WIDTH >= 220
491 #define LEVEL_TEXT_X 49
492 #define PEGS_TEXT_X 186
494 #elif LCD_WIDTH >= 176
495 #define LEVEL_TEXT_X 38
496 #define PEGS_TEXT_X 155
498 #elif LCD_WIDTH >= 160
499 #define LEVEL_TEXT_X 37
500 #define PEGS_TEXT_X 140
502 #elif LCD_WIDTH >= 138
503 #define LEVEL_TEXT_X 28
504 #define PEGS_TEXT_X 119
506 #elif LCD_WIDTH >= 128
507 #if HEADER_HEIGHT > 16
508 #define LEVEL_TEXT_X 26
509 #define PEGS_TEXT_X 107
512 #define LEVEL_TEXT_X 15
513 #define PEGS_TEXT_X 100
515 #endif /* HEADER_HEIGHT */
516 #elif LCD_WIDTH >= 112
517 #define LEVEL_TEXT_X 25
518 #define PEGS_TEXT_X 90
520 #endif /* LCD_WIDTH */
522 #endif /* WIDE_LAYOUT */
525 #ifdef HAVE_LCD_COLOR
526 #define BG_COLOR LCD_BLACK
527 #define TEXT_BG LCD_RGBPACK(189,189,189)
531 #ifdef HAVE_TOUCHSCREEN
532 #include "lib/touchscreen.h"
534 static struct ts_mapping main_menu_items
[5] =
536 {MENU_X
, MENU_Y
, ITEM_WIDTH
, ITEM_HEIGHT
},
537 {MENU_X
, MENU_Y
+ITEM_HEIGHT
, ITEM_WIDTH
, ITEM_HEIGHT
},
538 {MENU_X
, MENU_Y
+ITEM_HEIGHT
*2, ITEM_WIDTH
, ITEM_HEIGHT
},
539 {MENU_X
, MENU_Y
+ITEM_HEIGHT
*3, ITEM_WIDTH
, ITEM_HEIGHT
},
541 #if (LCD_WIDTH >= 138) && (LCD_HEIGHT > 110)
542 0, MENU_Y
+4*ITEM_HEIGHT
+8, SYSFONT_WIDTH
*28, SYSFONT_HEIGHT
543 #elif LCD_WIDTH > 112
544 0, LCD_HEIGHT
- 8, SYSFONT_WIDTH
*28, SYSFONT_HEIGHT
546 #error "Touchscreen isn't supported on non-bitmap screens!"
551 static struct ts_mappings main_menu
= {main_menu_items
, 5};
553 static struct ts_raster pegbox_raster
=
554 { BOARD_X
, BOARD_Y
, COLS
*PIECE_WIDTH
, ROWS
*PIECE_HEIGHT
,
555 PIECE_WIDTH
, PIECE_HEIGHT
};
556 static struct ts_raster_button_mapping pegbox_raster_btn
=
557 { &pegbox_raster
, false, false, true, false, true, {0, 0}, 0, 0, 0 };
560 struct game_context
{
562 unsigned int highlevel
;
563 signed int player_row
;
564 signed int player_col
;
565 unsigned int num_left
;
567 unsigned int playboard
[ROWS
][COLS
];
570 char levels
[NUM_LEVELS
][ROWS
][COLS
] = {
572 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
573 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
574 {1, 0, 0, 0, 7, 0, 0, 5, 0, 0, 0, 1,},
575 {1, 0, 0, 0, 0, 3, 3, 2, 0, 0, 0, 1,},
576 {1, 0, 0, 0, 4, 6, 0, 5, 0, 0, 0, 1,},
577 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
578 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
579 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
582 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
583 {1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 1,},
584 {1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1,},
585 {1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1,},
586 {7, 0, 0, 0, 2, 2, 5, 5, 0, 0, 0, 1,},
587 {1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1,},
588 {1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1,},
589 {1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 1,}},
592 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
593 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
594 {1, 0, 0, 0, 0, 0, 2, 0, 7, 0, 0, 0,},
595 {1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 2, 1,},
596 {1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1,},
597 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1,},
598 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
599 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
602 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
603 {6, 0, 4, 0, 2, 0, 2, 0, 0, 0, 0, 1,},
604 {6, 0, 3, 0, 5, 0, 2, 0, 0, 0, 0, 1,},
605 {6, 0, 5, 0, 4, 7, 2, 0, 0, 0, 0, 1,},
606 {6, 0, 2, 0, 4, 0, 2, 0, 3, 0, 0, 1,},
607 {6, 0, 4, 0, 5, 0, 2, 0, 0, 0, 0, 1,},
608 {6, 0, 5, 0, 4, 0, 2, 0, 0, 0, 0, 1,},
609 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
612 {{0, 6, 6, 0, 4, 6, 0, 0, 6, 0, 0, 0,},
613 {0, 6, 6, 0, 4, 4, 0, 0, 6, 0, 0, 2,},
614 {2, 6, 6, 0, 6, 6, 6, 0, 1, 2, 2, 2,},
615 {0, 6, 6, 0, 6, 4, 6, 0, 1, 2, 0, 2,},
616 {0, 6, 6, 0, 6, 7, 6, 5, 6, 0, 0, 0,},
617 {2, 6, 6, 0, 6, 6, 6, 0, 6, 0, 0, 0,},
618 {0, 6, 6, 0, 4, 0, 0, 0, 6, 0, 0, 0,},
619 {0, 6, 6, 0, 0, 5, 0, 0, 6, 5, 5, 0,}},
622 {{7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
623 {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,},
624 {2, 0, 0, 2, 0, 0, 0, 2, 2, 0, 0, 0,},
625 {0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 0,},
626 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
627 {0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1,},
628 {0, 3, 0, 0, 0, 0, 0, 0, 5, 4, 6, 0,},
629 {0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1,}},
632 {{1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1,},
633 {1, 1, 1, 6, 0, 0, 4, 6, 0, 1, 1, 1,},
634 {1, 1, 1, 1, 0, 1, 5, 1, 0, 1, 1, 1,},
635 {1, 1, 1, 2, 3, 3, 7, 4, 2, 6, 1, 1,},
636 {1, 1, 1, 1, 0, 1, 2, 1, 0, 0, 0, 1,},
637 {1, 1, 1, 1, 0, 0, 5, 0, 0, 1, 0, 1,},
638 {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1,},
639 {1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,}},
642 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
643 {0, 0, 3, 3, 3, 3, 3, 4, 3, 3, 0, 0,},
644 {0, 0, 3, 3, 3, 2, 3, 3, 5, 3, 0, 0,},
645 {7, 0, 3, 3, 3, 2, 3, 3, 4, 3, 0, 0,},
646 {0, 0, 3, 3, 4, 5, 3, 3, 3, 3, 0, 0,},
647 {0, 0, 3, 3, 5, 2, 3, 3, 3, 3, 0, 0,},
648 {0, 0, 3, 3, 2, 4, 3, 3, 3, 3, 0, 0,},
649 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
652 {{0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,},
653 {0, 3, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,},
654 {0, 0, 0, 0, 2, 4, 4, 3, 0, 1, 1, 0,},
655 {0, 1, 0, 0, 2, 1, 0, 0, 0, 1, 1, 1,},
656 {0, 0, 0, 2, 2, 7, 1, 0, 0, 0, 0, 2,},
657 {0, 0, 0, 0, 2, 1, 0, 0, 1, 1, 1, 1,},
658 {0, 3, 1, 0, 2, 5, 5, 0, 0, 0, 3, 0,},
659 {0, 0, 0, 0, 4, 1, 0, 0, 0, 0, 0, 0,}},
662 {{1, 1, 1, 1, 2, 1, 1, 1, 0, 0, 0, 0,},
663 {1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 7,},
664 {0, 0, 4, 0, 6, 6, 6, 0, 0, 0, 3, 0,},
665 {0, 3, 3, 0, 6, 6, 6, 0, 4, 3, 4, 0,},
666 {0, 3, 3, 0, 6, 6, 6, 0, 4, 3, 4, 0,},
667 {0, 0, 0, 0, 6, 6, 6, 0, 3, 0, 0, 0,},
668 {1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0,},
669 {1, 1, 1, 1, 1, 2, 1, 1, 0, 0, 0, 0,}},
672 {{1, 7, 1, 0, 1, 1, 6, 0, 0, 1, 1, 0,},
673 {1, 0, 0, 0, 5, 4, 6, 6, 0, 2, 2, 0,},
674 {1, 2, 1, 2, 0, 1, 6, 0, 0, 2, 2, 0,},
675 {1, 0, 0, 2, 0, 1, 0, 0, 0, 3, 3, 0,},
676 {1, 2, 1, 0, 0, 1, 0, 1, 0, 3, 3, 0,},
677 {0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0,},
678 {0, 3, 4, 3, 0, 1, 0, 1, 0, 0, 0, 0,},
679 {0, 0, 0, 0, 2, 2, 2, 1, 1, 1, 1, 1,}},
682 {{7, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,},
683 {1, 2, 1, 2, 1, 2, 1, 1, 0, 0, 0, 1,},
684 {0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1,},
685 {1, 2, 1, 2, 1, 2, 1, 0, 0, 0, 0, 1,},
686 {0, 0, 0, 0, 0, 0, 1, 1, 5, 5, 6, 1,},
687 {1, 2, 1, 2, 1, 2, 1, 1, 0, 2, 2, 1,},
688 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1,},
689 {1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1,}},
692 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
693 {0, 0, 4, 0, 2, 0, 5, 0, 4, 0, 0, 6,},
694 {0, 0, 2, 0, 5, 0, 2, 0, 4, 0, 0, 6,},
695 {7, 0, 3, 0, 4, 0, 5, 0, 4, 0, 0, 6,},
696 {0, 0, 5, 0, 4, 0, 2, 0, 4, 0, 0, 6,},
697 {0, 0, 4, 0, 2, 0, 5, 0, 4, 0, 0, 6,},
698 {0, 0, 3, 0, 3, 0, 2, 0, 4, 0, 0, 6,},
699 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
702 {{1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1,},
703 {1, 1, 0, 2, 0, 0, 4, 0, 0, 2, 0, 1,},
704 {1, 6, 0, 0, 5, 1, 0, 1, 1, 0, 0, 1,},
705 {1, 1, 1, 0, 0, 3, 5, 3, 0, 0, 1, 1,},
706 {1, 1, 0, 0, 1, 1, 0, 1, 5, 0, 0, 6,},
707 {1, 1, 0, 2, 0, 0, 4, 0, 0, 0, 7, 1,},
708 {1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1,},
709 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
712 {{0, 0, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
713 {0, 0, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
714 {0, 3, 4, 6, 0, 6, 0, 6, 0, 6, 0, 2,},
715 {0, 4, 0, 6, 0, 6, 4, 6, 0, 6, 0, 1,},
716 {0, 3, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
717 {7, 0, 0, 6, 4, 6, 0, 6, 0, 6, 0, 1,},
718 {0, 0, 4, 6, 0, 6, 0, 6, 4, 6, 0, 1,},
719 {0, 0, 4, 6, 0, 6, 0, 6, 0, 6, 0, 1,}}
723 /*****************************************************************************
724 * draw_board() draws the game's current level.
725 ******************************************************************************/
726 static void draw_board(struct game_context
* pb
) {
727 unsigned int r
, c
, type
;
731 rb
->lcd_clear_display();
733 rb
->lcd_bitmap(pegbox_header
,LCD_WIDTH
-HEADER_WIDTH
,0,
734 HEADER_WIDTH
,LCD_HEIGHT
);
736 rb
->lcd_bitmap(pegbox_header
,(LCD_WIDTH
-HEADER_WIDTH
)/2,0,
737 HEADER_WIDTH
, HEADER_HEIGHT
);
738 #endif /* WIDE_LAYOUT */
740 #if ((BOARD_HEIGHT + HEADER_HEIGHT + 4) <= LCD_HEIGHT)
741 rb
->lcd_drawrect(BOARD_X
-2,BOARD_Y
-2,BOARD_WIDTH
+4,BOARD_HEIGHT
+4);
742 #endif /* enough space for a frame? */
744 #ifdef HAVE_LCD_COLOR
745 rb
->lcd_set_foreground(LCD_WHITE
);
746 rb
->lcd_fillrect(BOARD_X
-1,BOARD_Y
-1,BOARD_WIDTH
+2,BOARD_HEIGHT
+2);
747 rb
->lcd_set_foreground(LCD_BLACK
);
748 rb
->lcd_set_background(TEXT_BG
);
751 for (r
=0 ; r
< ROWS
; r
++) {
752 for (c
= 0 ; c
< COLS
; c
++) {
754 type
= pb
->playboard
[r
][c
];
761 rb
->lcd_bitmap_part(pegbox_pieces
, 0, (type
-1)*PIECE_HEIGHT
,
762 PIECE_WIDTH
, c
* PIECE_WIDTH
+ BOARD_X
,
763 r
* PIECE_HEIGHT
+ BOARD_Y
, PIECE_WIDTH
,
768 if(pb
->playboard
[r
][c
] == PLAYER
) {
772 else if (type
!= WALL
&& type
!= SPACE
&& type
!= HOLE
)
778 rb
->snprintf(str
, 3, "%d", pb
->level
);
779 rb
->lcd_putsxy(TEXT_X
, LEVEL_TEXT_Y
, str
);
780 rb
->snprintf(str
, 3, "%d", pb
->num_left
);
781 rb
->lcd_putsxy(TEXT_X
, PEGS_TEXT_Y
, str
);
783 rb
->snprintf(str
, 3, "%d", pb
->level
);
784 rb
->lcd_putsxy(LEVEL_TEXT_X
, TEXT_Y
, str
);
785 rb
->snprintf(str
, 3, "%d", pb
->num_left
);
786 rb
->lcd_putsxy(PEGS_TEXT_X
, TEXT_Y
, str
);
787 #endif /*WIDE_LAYOUT*/
789 #ifdef HAVE_LCD_COLOR
790 rb
->lcd_set_background(BG_COLOR
);
791 rb
->lcd_set_foreground(LCD_WHITE
);
793 /* print out the screen */
797 /*****************************************************************************
798 * load_level() loads the player's current level from the array and sets the
800 ******************************************************************************/
801 static void load_level(struct game_context
* pb
) {
804 for(r
= 0; r
< ROWS
; r
++)
805 for(c
= 0; c
< COLS
; c
++)
806 pb
->playboard
[r
][c
] = levels
[pb
->level
-1][r
][c
];
809 /*****************************************************************************
810 * new_piece() creates a new piece at a specified location. The player
811 * navigates through the pieces and selects one.
812 ******************************************************************************/
813 static void new_piece(struct game_context
* pb
, unsigned int x_loc
,
814 unsigned int y_loc
) {
818 pb
->playboard
[x_loc
][y_loc
] = TRIANGLE
;
822 button
= rb
->button_get(true);
823 #ifdef HAVE_TOUCHSCREEN
824 if(button
& BUTTON_TOUCHSCREEN
)
826 pegbox_raster_btn
.two_d_from
.y
= x_loc
;
827 pegbox_raster_btn
.two_d_from
.x
= y_loc
;
829 struct ts_raster_button_result ret
=
830 touchscreen_raster_map_button(&pegbox_raster_btn
,
831 rb
->button_get_data() >> 16,
832 rb
->button_get_data() & 0xffff,
834 if(ret
.action
== TS_ACTION_TWO_D_MOVEMENT
)
836 if(ret
.to
.x
> ret
.from
.x
)
838 else if(ret
.to
.x
< ret
.from
.x
)
839 button
= PEGBOX_DOWN
;
840 else if(ret
.to
.y
> ret
.from
.y
)
841 button
= PEGBOX_LEFT
;
842 else if(ret
.to
.y
< ret
.from
.y
)
843 button
= PEGBOX_RIGHT
;
845 else if(ret
.action
== TS_ACTION_CLICK
846 && (unsigned)ret
.to
.x
== y_loc
847 && (unsigned)ret
.to
.y
== x_loc
)
848 button
= PEGBOX_SAVE
;
853 case (PEGBOX_LEFT
|BUTTON_REPEAT
):
855 case (PEGBOX_DOWN
|BUTTON_REPEAT
):
856 if (pb
->playboard
[x_loc
][y_loc
] < 5)
857 pb
->playboard
[x_loc
][y_loc
]++;
859 pb
->playboard
[x_loc
][y_loc
] = TRIANGLE
;
862 case (PEGBOX_RIGHT
|BUTTON_REPEAT
):
864 case (PEGBOX_UP
|BUTTON_REPEAT
):
865 if (pb
->playboard
[x_loc
][y_loc
] > 2)
866 pb
->playboard
[x_loc
][y_loc
]--;
868 pb
->playboard
[x_loc
][y_loc
] = CIRCLE
;
877 /*****************************************************************************
878 * move_player() moves the player and pieces and updates the board accordingly.
879 ******************************************************************************/
880 static void move_player(struct game_context
* pb
, signed int x_dir
,
882 unsigned int type1
, type2
;
885 r
= pb
->player_row
+y_dir
;
886 c
= pb
->player_col
+x_dir
;
888 type1
= pb
->playboard
[r
][c
];
889 type2
= pb
->playboard
[r
+y_dir
][c
+x_dir
];
891 if (r
== ROWS
|| c
== COLS
|| r
< 0 || c
< 0 || type1
== WALL
)
893 else if(type1
!= SPACE
) {
894 if (type2
== WALL
|| r
+y_dir
== ROWS
|| c
+x_dir
== COLS
||
895 r
+y_dir
< 0 || c
+x_dir
< 0)
900 pb
->playboard
[pb
->player_row
][pb
->player_col
] = SPACE
;
901 pb
->player_row
+= y_dir
;
902 pb
->player_col
+= x_dir
;
906 rb
->splash(HZ
*2, "You fell down a hole!");
909 else if (type1
== SPACE
)
910 pb
->playboard
[r
][c
] = PLAYER
;
912 pb
->playboard
[r
][c
] = PLAYER
;
914 if (type1
== TRIANGLE
)
915 pb
->playboard
[r
+y_dir
][c
+x_dir
] = WALL
;
916 else if (type1
== CROSS
) {
917 pb
->playboard
[r
][c
] = SPACE
;
918 new_piece(pb
, r
+y_dir
, c
+x_dir
);
919 pb
->playboard
[r
][c
] = PLAYER
;
922 pb
->playboard
[r
+y_dir
][c
+x_dir
] = SPACE
;
924 else if (type2
== SPACE
)
925 pb
->playboard
[r
+y_dir
][c
+x_dir
] = type1
;
926 else if (type2
== HOLE
) {
928 pb
->playboard
[r
+y_dir
][c
+x_dir
] = SPACE
;
931 rb
->splash(HZ
*2, "Illegal Move!");
939 /*****************************************************************************
940 * pegbox_loadgame() loads the saved game and returns load success.
941 ******************************************************************************/
942 static bool pegbox_loadgame(struct game_context
* pb
) {
947 fd
= rb
->open(SAVE_FILE
, O_RDONLY
);
948 if(fd
< 0) return loaded
;
950 /* read in saved game */
952 if(rb
->read(fd
, &pb
->level
, sizeof(pb
->level
)) <= 0) break;
953 if(rb
->read(fd
, &pb
->playboard
, sizeof(pb
->playboard
)) <= 0)
965 /*****************************************************************************
966 * pegbox_savegame() saves the current game state.
967 ******************************************************************************/
968 static void pegbox_savegame(struct game_context
* pb
) {
971 /* write out the game state to the save file */
972 fd
= rb
->open(SAVE_FILE
, O_WRONLY
|O_CREAT
);
973 rb
->write(fd
, &pb
->level
, sizeof(pb
->level
));
974 rb
->write(fd
, &pb
->playboard
, sizeof(pb
->playboard
));
978 /*****************************************************************************
979 * pegbox_loaddata() loads the level and highlevel and returns load success.
980 ******************************************************************************/
981 static void pegbox_loaddata(struct game_context
* pb
) {
985 fd
= rb
->open(DATA_FILE
, O_RDONLY
);
992 /* read in saved game */
994 if(rb
->read(fd
, &pb
->level
, sizeof(pb
->level
)) <= 0) break;
995 if(rb
->read(fd
, &pb
->highlevel
, sizeof(pb
->highlevel
)) <= 0) break;
1003 /*****************************************************************************
1004 * pegbox_savedata() saves the level and highlevel.
1005 ******************************************************************************/
1006 static void pegbox_savedata(struct game_context
* pb
) {
1009 /* write out the game state to the save file */
1010 fd
= rb
->open(DATA_FILE
, O_WRONLY
|O_CREAT
);
1011 rb
->write(fd
, &pb
->level
, sizeof(pb
->level
));
1012 rb
->write(fd
, &pb
->highlevel
, sizeof(pb
->highlevel
));
1016 /*****************************************************************************
1017 * pegbox_callback() is the default event handler callback which is called
1018 * on usb connect and shutdown.
1019 ******************************************************************************/
1020 static void pegbox_callback(void* param
) {
1021 struct game_context
* pb
= (struct game_context
*) param
;
1022 rb
->splash(HZ
, "Saving data...");
1023 pegbox_savedata(pb
);
1026 /***********************************************************************
1027 * pegbox_help() display help text
1028 ************************************************************************/
1029 static bool pegbox_help(void)
1032 #define WORDS (sizeof help_text / sizeof (char*))
1033 static char* help_text
[] = {
1034 "Pegbox", "", "Aim", "",
1035 "To", "beat", "each", "level,", "you", "must", "destroy", "all", "of",
1036 "the", "pegs.", "If", "two", "like", "pegs", "are", "pushed", "into",
1037 "each", "other,", "they", "disappear", "except", "for", "triangles",
1038 "which", "form", "a", "solid", "block", "and", "crosses", "which",
1039 "allow", "you", "to", "choose", "a", "replacement", "block.", "", "",
1041 RESTART_TEXT
, "to", "restart", "level", "",
1042 LVL_UP_TEXT
, "to", "go", "up", "a", "level", "",
1043 LVL_DOWN_TEXT
, "to", "go", "down", "a", "level", "",
1044 SAVE_TEXT
, "to", "select/save", "",
1045 QUIT_TEXT
, "to", "quit"
1047 static struct style_text formation
[]={
1048 { 0, TEXT_CENTER
|TEXT_UNDERLINE
},
1054 rb
->lcd_setfont(FONT_UI
);
1056 if (display_text(WORDS
, help_text
, formation
, NULL
))
1059 button
= rb
->button_get(true);
1060 if ( rb
->default_event_handler( button
) == SYS_USB_CONNECTED
)
1062 } while( ( button
== BUTTON_NONE
)
1063 || ( button
& (BUTTON_REL
|BUTTON_REPEAT
) ) );
1064 rb
->lcd_setfont(FONT_SYSFIXED
);
1068 /*****************************************************************************
1069 * pegbox_menu() is the initial menu at the start of the game.
1070 ******************************************************************************/
1071 static unsigned int pegbox_menu(struct game_context
* pb
) {
1074 unsigned int startlevel
= 1, loc
= 0;
1075 bool breakout
= false, can_resume
= false;
1077 if (pb
->num_left
> 0 || pb
->save_exist
)
1081 #if LCD_HEIGHT >= 80
1082 rb
->lcd_clear_display();
1083 rb
->lcd_bitmap(pegbox_menu_top
,0,0,LCD_WIDTH
, BMPHEIGHT_pegbox_menu_top
);
1087 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
, ITEM_WIDTH
,
1088 MENU_X
, MENU_Y
, ITEM_WIDTH
, ITEM_HEIGHT
);
1091 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, 0, ITEM_WIDTH
,
1092 MENU_X
, MENU_Y
, ITEM_WIDTH
, ITEM_HEIGHT
);
1096 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*3, ITEM_WIDTH
,
1097 MENU_X
, MENU_Y
+ITEM_HEIGHT
, ITEM_WIDTH
, ITEM_HEIGHT
);
1100 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*2, ITEM_WIDTH
,
1101 MENU_X
, MENU_Y
+ITEM_HEIGHT
, ITEM_WIDTH
, ITEM_HEIGHT
);
1105 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*4, ITEM_WIDTH
,
1106 MENU_X
, MENU_Y
+ITEM_HEIGHT
, ITEM_WIDTH
, ITEM_HEIGHT
);
1110 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*6, ITEM_WIDTH
,
1111 MENU_X
, MENU_Y
+ITEM_HEIGHT
*2, ITEM_WIDTH
, ITEM_HEIGHT
);
1114 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*5, ITEM_WIDTH
,
1115 MENU_X
, MENU_Y
+ITEM_HEIGHT
*2, ITEM_WIDTH
, ITEM_HEIGHT
);
1119 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*8, ITEM_WIDTH
,
1120 MENU_X
, MENU_Y
+ITEM_HEIGHT
*3, ITEM_WIDTH
, ITEM_HEIGHT
);
1123 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*7, ITEM_WIDTH
,
1124 MENU_X
, MENU_Y
+ITEM_HEIGHT
*3, ITEM_WIDTH
, ITEM_HEIGHT
);
1128 rb
->lcd_clear_display();
1129 rb
->lcd_getstringsize("PegBox", &w
, &h
);
1130 rb
->lcd_putsxy((LCD_WIDTH
-w
)/2, 0, "PegBox");
1131 rb
->lcd_putsxy((LCD_WIDTH
)/4, 16, "New Game");
1132 rb
->lcd_putsxy((LCD_WIDTH
)/4, 24, "Resume");
1133 rb
->lcd_putsxy((LCD_WIDTH
)/4, 32, "Help");
1134 rb
->lcd_putsxy((LCD_WIDTH
)/4, 40, "Quit");
1137 rb
->lcd_hline((LCD_WIDTH
)/4, (LCD_WIDTH
)/4+30, 28);
1139 rb
->lcd_putsxy((LCD_WIDTH
)/4-8, loc
*8+16, "*");
1143 rb
->snprintf(str
, 28, "Start on level %d of %d", startlevel
,
1145 #if LCD_HEIGHT > 110
1146 rb
->lcd_putsxy(0, MENU_Y
+4*ITEM_HEIGHT
+8, str
);
1147 #elif LCD_HEIGHT > 64
1148 rb
->lcd_putsxy(0, LCD_HEIGHT
- 8, str
);
1150 rb
->lcd_puts_scroll(0, 7, str
);
1154 /* handle menu button presses */
1155 button
= rb
->button_get(true);
1157 #ifdef HAVE_TOUCHSCREEN
1158 if(button
& BUTTON_TOUCHSCREEN
)
1160 unsigned int result
= touchscreen_map(&main_menu
,
1161 rb
->button_get_data() >> 16,
1162 rb
->button_get_data() & 0xffff);
1163 if(result
!= (unsigned)-1 && button
& BUTTON_REL
)
1166 button
= PEGBOX_LVL_UP
;
1170 button
= PEGBOX_RIGHT
;
1178 case PEGBOX_SAVE
: /* start playing */
1182 pb
->level
= startlevel
;
1185 else if (loc
== 1 && can_resume
) {
1188 rb
->remove(SAVE_FILE
);
1189 pb
->save_exist
= false;
1202 case PEGBOX_QUIT
: /* quit program */
1205 case (PEGBOX_UP
|BUTTON_REPEAT
):
1211 if (!can_resume
&& loc
== 1) {
1217 case (PEGBOX_DOWN
|BUTTON_REPEAT
):
1223 if (!can_resume
&& loc
== 1) {
1228 case (PEGBOX_LVL_UP
|BUTTON_REPEAT
):
1229 case PEGBOX_LVL_UP
: /* increase starting level */
1230 if(startlevel
>= pb
->highlevel
) {
1237 /* only for targets with enough buttons */
1238 #ifdef PEGBOX_LVL_DOWN
1239 case (PEGBOX_LVL_DOWN
|BUTTON_REPEAT
):
1240 case PEGBOX_LVL_DOWN
: /* decrease starting level */
1241 if(startlevel
<= 1) {
1242 startlevel
= pb
->highlevel
;
1249 if(rb
->default_event_handler_ex(button
, pegbox_callback
,
1250 (void*) pb
) == SYS_USB_CONNECTED
)
1261 /*****************************************************************************
1262 * pegbox() is the main game subroutine, it returns the final game status.
1263 ******************************************************************************/
1264 static int pegbox(struct game_context
* pb
) {
1267 /********************
1269 ********************/
1270 temp_var
= pegbox_menu(pb
);
1271 if (temp_var
== PB_QUIT
|| temp_var
== PB_USB
)
1275 temp_var
= rb
->button_get(true);
1276 #ifdef HAVE_TOUCHSCREEN
1277 if(temp_var
& BUTTON_TOUCHSCREEN
)
1279 pegbox_raster_btn
.two_d_from
.y
= pb
->player_row
;
1280 pegbox_raster_btn
.two_d_from
.x
= pb
->player_col
;
1282 struct ts_raster_button_result ret
=
1283 touchscreen_raster_map_button(&pegbox_raster_btn
,
1284 rb
->button_get_data() >> 16,
1285 rb
->button_get_data() & 0xffff,
1287 if(ret
.action
== TS_ACTION_TWO_D_MOVEMENT
)
1288 move_player(pb
, ret
.to
.x
- ret
.from
.x
, ret
.to
.y
- ret
.from
.y
);
1292 case PEGBOX_LEFT
: /* move cursor left */
1293 case (PEGBOX_LEFT
|BUTTON_REPEAT
):
1294 move_player(pb
, -1, 0);
1297 case PEGBOX_RIGHT
: /* move cursor right */
1298 case (PEGBOX_RIGHT
|BUTTON_REPEAT
):
1299 move_player(pb
, 1, 0);
1302 case PEGBOX_DOWN
: /* move cursor down */
1303 case (PEGBOX_DOWN
|BUTTON_REPEAT
):
1304 move_player(pb
, 0, 1);
1307 case PEGBOX_UP
: /* move cursor up */
1308 case (PEGBOX_UP
|BUTTON_REPEAT
):
1309 move_player(pb
, 0, -1);
1312 case PEGBOX_SAVE
: /* save and end game */
1313 rb
->splash(HZ
, "Saving game...");
1314 pegbox_savegame(pb
);
1315 /* fall through to PEGBOX_QUIT */
1320 case PEGBOX_RESTART
:
1325 case (PEGBOX_LVL_UP
|BUTTON_REPEAT
):
1327 if(pb
->level
>= pb
->highlevel
) {
1336 /* only for targets with enough buttons */
1337 #ifdef PEGBOX_LVL_DOWN
1338 case (PEGBOX_LVL_DOWN
|BUTTON_REPEAT
):
1339 case PEGBOX_LVL_DOWN
:
1340 if(pb
->level
<= 1) {
1341 pb
->level
= pb
->highlevel
;
1352 if(pb
->num_left
== 0) {
1353 rb
->splash(HZ
*2, "Nice Pegging!");
1354 if(pb
->level
== NUM_LEVELS
) {
1356 rb
->splash(HZ
*2, "You Won!");
1365 if(pb
->level
> pb
->highlevel
)
1366 pb
->highlevel
= pb
->level
;
1375 /*****************************************************************************
1376 * plugin entry point.
1377 ******************************************************************************/
1378 enum plugin_status
plugin_start(const void* parameter
) {
1380 struct game_context pb
;
1384 rb
->lcd_setfont(FONT_SYSFIXED
);
1386 rb
->lcd_set_backdrop(NULL
);
1388 #ifdef HAVE_LCD_COLOR
1389 rb
->lcd_set_foreground(LCD_WHITE
);
1390 rb
->lcd_set_background(BG_COLOR
);
1393 rb
->splash(0, "Loading...");
1394 pegbox_loaddata(&pb
);
1395 pb
.save_exist
= pegbox_loadgame(&pb
);
1398 rb
->lcd_clear_display();
1402 switch(pegbox(&pb
)){
1407 rb
->lcd_setfont(FONT_UI
);
1408 return PLUGIN_USB_CONNECTED
;
1411 rb
->splash(HZ
, "Saving data...");
1412 pegbox_savedata(&pb
);
1421 rb
->lcd_setfont(FONT_UI
);