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_GAMES_DIR "/pegbox.data"
43 #define SAVE_FILE PLUGIN_GAMES_DIR "/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_HOME|BUTTON_REPEAT)
198 #define PEGBOX_RESTART BUTTON_SELECT|BUTTON_LEFT
199 #define PEGBOX_LVL_UP BUTTON_SCROLL_BACK
200 #define PEGBOX_LVL_DOWN BUTTON_SCROLL_FWD
201 #define PEGBOX_UP BUTTON_UP
202 #define PEGBOX_DOWN BUTTON_DOWN
203 #define PEGBOX_RIGHT BUTTON_RIGHT
204 #define PEGBOX_LEFT BUTTON_LEFT
206 #define SAVE_TEXT "SELECT"
207 #define QUIT_TEXT "HOME"
208 #define RESTART_TEXT "SELECT & LEFT"
209 #define LVL_UP_TEXT "SCROLL BACK"
210 #define LVL_DOWN_TEXT "SCROLL FWD"
212 #elif CONFIG_KEYPAD == GIGABEAT_PAD
213 #define PEGBOX_SAVE BUTTON_SELECT
214 #define PEGBOX_QUIT BUTTON_POWER
215 #define PEGBOX_RESTART BUTTON_A
216 #define PEGBOX_LVL_UP BUTTON_VOL_UP
217 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
218 #define PEGBOX_UP BUTTON_UP
219 #define PEGBOX_DOWN BUTTON_DOWN
220 #define PEGBOX_RIGHT BUTTON_RIGHT
221 #define PEGBOX_LEFT BUTTON_LEFT
223 #define SAVE_TEXT "SELECT"
224 #define QUIT_TEXT "POWER"
225 #define RESTART_TEXT "A"
226 #define LVL_UP_TEXT "VOL+"
227 #define LVL_DOWN_TEXT "VOL-"
229 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
230 #define PEGBOX_SAVE BUTTON_SELECT
231 #define PEGBOX_QUIT BUTTON_BACK
232 #define PEGBOX_RESTART BUTTON_MENU
233 #define PEGBOX_LVL_UP BUTTON_VOL_UP
234 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
235 #define PEGBOX_UP BUTTON_UP
236 #define PEGBOX_DOWN BUTTON_DOWN
237 #define PEGBOX_RIGHT BUTTON_RIGHT
238 #define PEGBOX_LEFT BUTTON_LEFT
240 #define SAVE_TEXT "SELECT"
241 #define QUIT_TEXT "BACK"
242 #define RESTART_TEXT "MENU"
243 #define LVL_UP_TEXT "VOL+"
244 #define LVL_DOWN_TEXT "VOL-"
246 #elif CONFIG_KEYPAD == MROBE100_PAD
247 #define PEGBOX_SAVE BUTTON_SELECT
248 #define PEGBOX_QUIT BUTTON_POWER
249 #define PEGBOX_RESTART BUTTON_PLAY
250 #define PEGBOX_LVL_UP BUTTON_MENU
251 #define PEGBOX_LVL_DOWN BUTTON_DISPLAY
252 #define PEGBOX_UP BUTTON_UP
253 #define PEGBOX_DOWN BUTTON_DOWN
254 #define PEGBOX_RIGHT BUTTON_RIGHT
255 #define PEGBOX_LEFT BUTTON_LEFT
257 #define SAVE_TEXT "SELECT"
258 #define QUIT_TEXT "POWER"
259 #define RESTART_TEXT "PLAY"
260 #define LVL_UP_TEXT "MENU"
261 #define LVL_DOWN_TEXT "DISPLAY"
263 #elif CONFIG_KEYPAD == SANSA_C200_PAD
264 #define PEGBOX_SAVE BUTTON_SELECT
265 #define PEGBOX_QUIT BUTTON_POWER
266 #define PEGBOX_RESTART BUTTON_REC
267 #define PEGBOX_LVL_UP BUTTON_VOL_UP
268 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
269 #define PEGBOX_UP BUTTON_UP
270 #define PEGBOX_DOWN BUTTON_DOWN
271 #define PEGBOX_RIGHT BUTTON_RIGHT
272 #define PEGBOX_LEFT BUTTON_LEFT
274 #define SAVE_TEXT "SELECT"
275 #define QUIT_TEXT "POWER"
276 #define RESTART_TEXT "REC"
277 #define LVL_UP_TEXT "VOL+"
278 #define LVL_DOWN_TEXT "VOL-"
280 #elif CONFIG_KEYPAD == SANSA_CLIP_PAD
281 #define PEGBOX_SAVE BUTTON_SELECT
282 #define PEGBOX_QUIT BUTTON_POWER
283 #define PEGBOX_RESTART BUTTON_HOME
284 #define PEGBOX_LVL_UP BUTTON_VOL_UP
285 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
286 #define PEGBOX_UP BUTTON_UP
287 #define PEGBOX_DOWN BUTTON_DOWN
288 #define PEGBOX_RIGHT BUTTON_RIGHT
289 #define PEGBOX_LEFT BUTTON_LEFT
291 #define SAVE_TEXT "SELECT"
292 #define QUIT_TEXT "POWER"
293 #define RESTART_TEXT "HOME"
294 #define LVL_UP_TEXT "VOL+"
295 #define LVL_DOWN_TEXT "VOL-"
297 #elif CONFIG_KEYPAD == SANSA_M200_PAD
298 #define PEGBOX_SAVE (BUTTON_SELECT | BUTTON_REL)
299 #define PEGBOX_QUIT BUTTON_POWER
300 #define PEGBOX_RESTART (BUTTON_SELECT | BUTTON_UP)
301 #define PEGBOX_LVL_UP BUTTON_VOL_UP
302 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
303 #define PEGBOX_UP BUTTON_UP
304 #define PEGBOX_DOWN BUTTON_DOWN
305 #define PEGBOX_RIGHT BUTTON_RIGHT
306 #define PEGBOX_LEFT BUTTON_LEFT
308 #define SAVE_TEXT "SELECT"
309 #define QUIT_TEXT "POWER"
310 #define RESTART_TEXT "SELECT+UP"
311 #define LVL_UP_TEXT "VOL+"
312 #define LVL_DOWN_TEXT "VOL-"
315 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
316 #define PEGBOX_SAVE BUTTON_RC_PLAY
317 #define PEGBOX_QUIT BUTTON_RC_REC
318 #define PEGBOX_RESTART BUTTON_RC_MODE
319 #define PEGBOX_LVL_UP BUTTON_VOL_UP
320 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
321 #define PEGBOX_UP BUTTON_RC_VOL_UP
322 #define PEGBOX_DOWN BUTTON_RC_VOL_DOWN
323 #define PEGBOX_RIGHT BUTTON_RC_FF
324 #define PEGBOX_LEFT BUTTON_RC_REW
326 #define SAVE_TEXT "REM. PLAY"
327 #define QUIT_TEXT "REM. REC"
328 #define RESTART_TEXT "REM. MODE"
329 #define LVL_UP_TEXT "VOL+"
330 #define LVL_DOWN_TEXT "VOL-"
332 #elif CONFIG_KEYPAD == COWOND2_PAD
333 #define PEGBOX_QUIT BUTTON_POWER
335 #define QUIT_TEXT "POWER"
337 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
338 #define PEGBOX_SAVE BUTTON_CUSTOM
339 #define PEGBOX_QUIT BUTTON_BACK
340 #define PEGBOX_RESTART BUTTON_SELECT
341 #define PEGBOX_LVL_UP BUTTON_PLAY
342 #define PEGBOX_LVL_DOWN BUTTON_MENU
343 #define PEGBOX_UP BUTTON_UP
344 #define PEGBOX_DOWN BUTTON_DOWN
345 #define PEGBOX_RIGHT BUTTON_RIGHT
346 #define PEGBOX_LEFT BUTTON_LEFT
348 #define SAVE_TEXT "CUSTOM"
349 #define QUIT_TEXT "BACK"
350 #define RESTART_TEXT "MIDDLE"
351 #define LVL_UP_TEXT "SELECT"
352 #define LVL_DOWN_TEXT "MENU"
354 #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
355 #define PEGBOX_SAVE BUTTON_VIEW
356 #define PEGBOX_QUIT BUTTON_POWER
357 #define PEGBOX_RESTART BUTTON_MENU
358 #define PEGBOX_LVL_UP BUTTON_VOL_UP
359 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
360 #define PEGBOX_UP BUTTON_UP
361 #define PEGBOX_DOWN BUTTON_DOWN
362 #define PEGBOX_RIGHT BUTTON_RIGHT
363 #define PEGBOX_LEFT BUTTON_LEFT
365 #define SAVE_TEXT "VIEW"
366 #define QUIT_TEXT "POWER"
367 #define RESTART_TEXT "MENU"
368 #define LVL_UP_TEXT "VOL+"
369 #define LVL_DOWN_TEXT "VOL-"
371 #elif CONFIG_KEYPAD == ONDAVX747_PAD || CONFIG_KEYPAD == MROBE500_PAD
372 #define PEGBOX_QUIT BUTTON_POWER
374 #define QUIT_TEXT "POWER"
377 #error Unsupported keymap!
380 #ifdef HAVE_TOUCHSCREEN
382 #define PEGBOX_QUIT BUTTON_TOPLEFT
385 #define PEGBOX_SAVE BUTTON_CENTER
387 #ifndef PEGBOX_RESTART
388 #define PEGBOX_RESTART BUTTON_TOPRIGHT
390 #ifndef PEGBOX_LVL_UP
391 #define PEGBOX_LVL_UP BUTTON_BOTTOMLEFT
393 #ifndef PEGBOX_LVL_DOWN
394 #define PEGBOX_LVL_DOWN BUTTON_BOTTOMRIGHT
397 #define PEGBOX_UP BUTTON_TOPMIDDLE
400 #define PEGBOX_DOWN BUTTON_BOTTOMMIDDLE
403 #define PEGBOX_RIGHT BUTTON_MIDRIGHT
406 #define PEGBOX_LEFT BUTTON_MIDLEFT
409 #define SAVE_TEXT "CENTER"
412 #define QUIT_TEXT "TOPLEFT"
415 #define RESTART_TEXT "TOPRIGHT"
418 #define LVL_UP_TEXT "BOTTOMLEFT"
420 #ifndef LVL_DOWN_TEXT
421 #define LVL_DOWN_TEXT "BOTTOMRIGHT"
426 /* get several sizes from the bitmaps */
427 #ifdef BMPWIDTH_pegbox_pieces
428 #define PIECE_WIDTH BMPWIDTH_pegbox_pieces
429 #define PIECE_HEIGHT (BMPHEIGHT_pegbox_pieces/7)
431 /* dummy numbers to avoid #error in dependency generation */
432 #define PIECE_WIDTH 50
433 #define PIECE_HEIGHT 10
436 #define BOARD_WIDTH (12*PIECE_WIDTH)
437 #define BOARD_HEIGHT (8*PIECE_HEIGHT)
440 /* define a wide layout where the statistics are alongside the board, not above
441 * base calculation on the piece bitmaps for the 8x12 board */
442 #if (LCD_WIDTH - BOARD_WIDTH) > (LCD_HEIGHT - BOARD_HEIGHT)
447 #define HEADER_WIDTH BMPWIDTH_pegbox_header
448 #define HEADER_HEIGHT BMPHEIGHT_pegbox_header
451 #if defined WIDE_LAYOUT
453 #if ((BOARD_WIDTH + HEADER_WIDTH + 4) <= LCD_WIDTH)
458 #define BOARD_Y (LCD_HEIGHT-BOARD_HEIGHT)/2
460 #if (LCD_WIDTH >= 132) && (LCD_HEIGHT >= 80)
462 #define LEVEL_TEXT_Y 14
463 #define PEGS_TEXT_Y 58
464 #elif (LCD_WIDTH >= 128) && (LCD_HEIGHT >= 64)
466 #define LEVEL_TEXT_Y 27
467 #define PEGS_TEXT_Y 50
469 #error "Unsupported screen size"
472 #else /* "normal" layout */
474 #define BOARD_X (LCD_WIDTH-BOARD_WIDTH)/2
475 #if ((BOARD_HEIGHT + HEADER_HEIGHT + 4) <= LCD_HEIGHT)
476 #define BOARD_Y HEADER_HEIGHT+2
478 #define BOARD_Y HEADER_HEIGHT
482 #define LEVEL_TEXT_X 59
483 #define PEGS_TEXT_X 276
485 #elif LCD_WIDTH >= 240
486 #define LEVEL_TEXT_X 59
487 #define PEGS_TEXT_X 196
489 #elif LCD_WIDTH >= 220
490 #define LEVEL_TEXT_X 49
491 #define PEGS_TEXT_X 186
493 #elif LCD_WIDTH >= 176
494 #define LEVEL_TEXT_X 38
495 #define PEGS_TEXT_X 155
497 #elif LCD_WIDTH >= 160
498 #define LEVEL_TEXT_X 37
499 #define PEGS_TEXT_X 140
501 #elif LCD_WIDTH >= 138
502 #define LEVEL_TEXT_X 28
503 #define PEGS_TEXT_X 119
505 #elif LCD_WIDTH >= 128
506 #if HEADER_HEIGHT > 16
507 #define LEVEL_TEXT_X 26
508 #define PEGS_TEXT_X 107
511 #define LEVEL_TEXT_X 15
512 #define PEGS_TEXT_X 100
514 #endif /* HEADER_HEIGHT */
515 #elif LCD_WIDTH >= 112
516 #define LEVEL_TEXT_X 25
517 #define PEGS_TEXT_X 90
519 #endif /* LCD_WIDTH */
521 #endif /* WIDE_LAYOUT */
524 #ifdef HAVE_LCD_COLOR
525 #define BG_COLOR LCD_BLACK
526 #define TEXT_BG LCD_RGBPACK(189,189,189)
530 #ifdef HAVE_TOUCHSCREEN
531 #include "lib/touchscreen.h"
533 static struct ts_mapping main_menu_items
[5] =
535 {MENU_X
, MENU_Y
, ITEM_WIDTH
, ITEM_HEIGHT
},
536 {MENU_X
, MENU_Y
+ITEM_HEIGHT
, ITEM_WIDTH
, ITEM_HEIGHT
},
537 {MENU_X
, MENU_Y
+ITEM_HEIGHT
*2, ITEM_WIDTH
, ITEM_HEIGHT
},
538 {MENU_X
, MENU_Y
+ITEM_HEIGHT
*3, ITEM_WIDTH
, ITEM_HEIGHT
},
540 #if (LCD_WIDTH >= 138) && (LCD_HEIGHT > 110)
541 0, MENU_Y
+4*ITEM_HEIGHT
+8, SYSFONT_WIDTH
*28, SYSFONT_HEIGHT
542 #elif LCD_WIDTH > 112
543 0, LCD_HEIGHT
- 8, SYSFONT_WIDTH
*28, SYSFONT_HEIGHT
545 #error "Touchscreen isn't supported on non-bitmap screens!"
550 static struct ts_mappings main_menu
= {main_menu_items
, 5};
552 static struct ts_raster pegbox_raster
=
553 { BOARD_X
, BOARD_Y
, COLS
*PIECE_WIDTH
, ROWS
*PIECE_HEIGHT
,
554 PIECE_WIDTH
, PIECE_HEIGHT
};
555 static struct ts_raster_button_mapping pegbox_raster_btn
=
556 { &pegbox_raster
, false, false, true, false, true, {0, 0}, 0, 0, 0 };
559 struct game_context
{
561 unsigned int highlevel
;
562 signed int player_row
;
563 signed int player_col
;
564 unsigned int num_left
;
566 unsigned int playboard
[ROWS
][COLS
];
569 char levels
[NUM_LEVELS
][ROWS
][COLS
] = {
571 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
572 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
573 {1, 0, 0, 0, 7, 0, 0, 5, 0, 0, 0, 1,},
574 {1, 0, 0, 0, 0, 3, 3, 2, 0, 0, 0, 1,},
575 {1, 0, 0, 0, 4, 6, 0, 5, 0, 0, 0, 1,},
576 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
577 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
578 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
581 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
582 {1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 1,},
583 {1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1,},
584 {1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1,},
585 {7, 0, 0, 0, 2, 2, 5, 5, 0, 0, 0, 1,},
586 {1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1,},
587 {1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1,},
588 {1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 1,}},
591 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
592 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
593 {1, 0, 0, 0, 0, 0, 2, 0, 7, 0, 0, 0,},
594 {1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 2, 1,},
595 {1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1,},
596 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1,},
597 {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,}},
601 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
602 {6, 0, 4, 0, 2, 0, 2, 0, 0, 0, 0, 1,},
603 {6, 0, 3, 0, 5, 0, 2, 0, 0, 0, 0, 1,},
604 {6, 0, 5, 0, 4, 7, 2, 0, 0, 0, 0, 1,},
605 {6, 0, 2, 0, 4, 0, 2, 0, 3, 0, 0, 1,},
606 {6, 0, 4, 0, 5, 0, 2, 0, 0, 0, 0, 1,},
607 {6, 0, 5, 0, 4, 0, 2, 0, 0, 0, 0, 1,},
608 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
611 {{0, 6, 6, 0, 4, 6, 0, 0, 6, 0, 0, 0,},
612 {0, 6, 6, 0, 4, 4, 0, 0, 6, 0, 0, 2,},
613 {2, 6, 6, 0, 6, 6, 6, 0, 1, 2, 2, 2,},
614 {0, 6, 6, 0, 6, 4, 6, 0, 1, 2, 0, 2,},
615 {0, 6, 6, 0, 6, 7, 6, 5, 6, 0, 0, 0,},
616 {2, 6, 6, 0, 6, 6, 6, 0, 6, 0, 0, 0,},
617 {0, 6, 6, 0, 4, 0, 0, 0, 6, 0, 0, 0,},
618 {0, 6, 6, 0, 0, 5, 0, 0, 6, 5, 5, 0,}},
621 {{7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
622 {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,},
623 {2, 0, 0, 2, 0, 0, 0, 2, 2, 0, 0, 0,},
624 {0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 0,},
625 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
626 {0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1,},
627 {0, 3, 0, 0, 0, 0, 0, 0, 5, 4, 6, 0,},
628 {0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1,}},
631 {{1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1,},
632 {1, 1, 1, 6, 0, 0, 4, 6, 0, 1, 1, 1,},
633 {1, 1, 1, 1, 0, 1, 5, 1, 0, 1, 1, 1,},
634 {1, 1, 1, 2, 3, 3, 7, 4, 2, 6, 1, 1,},
635 {1, 1, 1, 1, 0, 1, 2, 1, 0, 0, 0, 1,},
636 {1, 1, 1, 1, 0, 0, 5, 0, 0, 1, 0, 1,},
637 {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1,},
638 {1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,}},
641 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
642 {0, 0, 3, 3, 3, 3, 3, 4, 3, 3, 0, 0,},
643 {0, 0, 3, 3, 3, 2, 3, 3, 5, 3, 0, 0,},
644 {7, 0, 3, 3, 3, 2, 3, 3, 4, 3, 0, 0,},
645 {0, 0, 3, 3, 4, 5, 3, 3, 3, 3, 0, 0,},
646 {0, 0, 3, 3, 5, 2, 3, 3, 3, 3, 0, 0,},
647 {0, 0, 3, 3, 2, 4, 3, 3, 3, 3, 0, 0,},
648 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
651 {{0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,},
652 {0, 3, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,},
653 {0, 0, 0, 0, 2, 4, 4, 3, 0, 1, 1, 0,},
654 {0, 1, 0, 0, 2, 1, 0, 0, 0, 1, 1, 1,},
655 {0, 0, 0, 2, 2, 7, 1, 0, 0, 0, 0, 2,},
656 {0, 0, 0, 0, 2, 1, 0, 0, 1, 1, 1, 1,},
657 {0, 3, 1, 0, 2, 5, 5, 0, 0, 0, 3, 0,},
658 {0, 0, 0, 0, 4, 1, 0, 0, 0, 0, 0, 0,}},
661 {{1, 1, 1, 1, 2, 1, 1, 1, 0, 0, 0, 0,},
662 {1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 7,},
663 {0, 0, 4, 0, 6, 6, 6, 0, 0, 0, 3, 0,},
664 {0, 3, 3, 0, 6, 6, 6, 0, 4, 3, 4, 0,},
665 {0, 3, 3, 0, 6, 6, 6, 0, 4, 3, 4, 0,},
666 {0, 0, 0, 0, 6, 6, 6, 0, 3, 0, 0, 0,},
667 {1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0,},
668 {1, 1, 1, 1, 1, 2, 1, 1, 0, 0, 0, 0,}},
671 {{1, 7, 1, 0, 1, 1, 6, 0, 0, 1, 1, 0,},
672 {1, 0, 0, 0, 5, 4, 6, 6, 0, 2, 2, 0,},
673 {1, 2, 1, 2, 0, 1, 6, 0, 0, 2, 2, 0,},
674 {1, 0, 0, 2, 0, 1, 0, 0, 0, 3, 3, 0,},
675 {1, 2, 1, 0, 0, 1, 0, 1, 0, 3, 3, 0,},
676 {0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0,},
677 {0, 3, 4, 3, 0, 1, 0, 1, 0, 0, 0, 0,},
678 {0, 0, 0, 0, 2, 2, 2, 1, 1, 1, 1, 1,}},
681 {{7, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,},
682 {1, 2, 1, 2, 1, 2, 1, 1, 0, 0, 0, 1,},
683 {0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1,},
684 {1, 2, 1, 2, 1, 2, 1, 0, 0, 0, 0, 1,},
685 {0, 0, 0, 0, 0, 0, 1, 1, 5, 5, 6, 1,},
686 {1, 2, 1, 2, 1, 2, 1, 1, 0, 2, 2, 1,},
687 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1,},
688 {1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1,}},
691 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
692 {0, 0, 4, 0, 2, 0, 5, 0, 4, 0, 0, 6,},
693 {0, 0, 2, 0, 5, 0, 2, 0, 4, 0, 0, 6,},
694 {7, 0, 3, 0, 4, 0, 5, 0, 4, 0, 0, 6,},
695 {0, 0, 5, 0, 4, 0, 2, 0, 4, 0, 0, 6,},
696 {0, 0, 4, 0, 2, 0, 5, 0, 4, 0, 0, 6,},
697 {0, 0, 3, 0, 3, 0, 2, 0, 4, 0, 0, 6,},
698 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
701 {{1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1,},
702 {1, 1, 0, 2, 0, 0, 4, 0, 0, 2, 0, 1,},
703 {1, 6, 0, 0, 5, 1, 0, 1, 1, 0, 0, 1,},
704 {1, 1, 1, 0, 0, 3, 5, 3, 0, 0, 1, 1,},
705 {1, 1, 0, 0, 1, 1, 0, 1, 5, 0, 0, 6,},
706 {1, 1, 0, 2, 0, 0, 4, 0, 0, 0, 7, 1,},
707 {1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1,},
708 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
711 {{0, 0, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
712 {0, 0, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
713 {0, 3, 4, 6, 0, 6, 0, 6, 0, 6, 0, 2,},
714 {0, 4, 0, 6, 0, 6, 4, 6, 0, 6, 0, 1,},
715 {0, 3, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
716 {7, 0, 0, 6, 4, 6, 0, 6, 0, 6, 0, 1,},
717 {0, 0, 4, 6, 0, 6, 0, 6, 4, 6, 0, 1,},
718 {0, 0, 4, 6, 0, 6, 0, 6, 0, 6, 0, 1,}}
722 /*****************************************************************************
723 * display_text() formats and outputs text.
724 ******************************************************************************/
725 static void display_text(char *str
, bool waitkey
)
730 int current_line
= 0;
731 int char_width
, char_height
;
732 int first_char_index
= 0;
740 rb
->lcd_clear_display();
742 rb
->lcd_getstringsize("a", &char_width
, &char_height
);
744 chars_by_line
= LCD_WIDTH
/ char_width
;
745 lines_by_screen
= LCD_HEIGHT
/ char_height
;
749 ptr_char
= str
+ first_char_index
;
753 while (i
< chars_by_line
)
766 *(ptr_line
++) = *ptr_char
;
768 if (*ptr_char
== '\n' || *ptr_char
== '\0')
774 if (chars_for_line
== 0)
777 line
[chars_for_line
] = '\0';
779 /* test if we have cut a word. If it is the case we don't have to */
781 if (i
== chars_by_line
&& chars_for_line
== chars_by_line
)
782 first_char_index
+= chars_for_line
;
784 first_char_index
+= chars_for_line
+ 1;
786 /* print the line on the screen */
787 rb
->lcd_putsxy(0, current_line
* char_height
, line
);
789 /* if the number of line showed on the screen is equals to the */
790 /* maximum number of line we can show, we wait for a key pressed to */
791 /* clear and show the remaining text. */
793 if (current_line
== lines_by_screen
|| *ptr_char
== '\0')
798 while (waitkey
&& !go_on
)
800 key
= rb
->button_get(true);
803 #ifdef HAVE_TOUCHSCREEN
804 case BUTTON_TOUCHSCREEN
:
813 /*if (rb->default_event_handler(key) == SYS_USB_CONNECTED)
822 rb
->lcd_clear_display();
824 } while (*ptr_char
!= '\0');
827 /*****************************************************************************
828 * draw_board() draws the game's current level.
829 ******************************************************************************/
830 static void draw_board(struct game_context
* pb
) {
831 unsigned int r
, c
, type
;
835 rb
->lcd_clear_display();
837 rb
->lcd_bitmap(pegbox_header
,LCD_WIDTH
-HEADER_WIDTH
,0,
838 HEADER_WIDTH
,LCD_HEIGHT
);
840 rb
->lcd_bitmap(pegbox_header
,(LCD_WIDTH
-HEADER_WIDTH
)/2,0,
841 HEADER_WIDTH
, HEADER_HEIGHT
);
842 #endif /* WIDE_LAYOUT */
844 #if ((BOARD_HEIGHT + HEADER_HEIGHT + 4) <= LCD_HEIGHT)
845 rb
->lcd_drawrect(BOARD_X
-2,BOARD_Y
-2,BOARD_WIDTH
+4,BOARD_HEIGHT
+4);
846 #endif /* enough space for a frame? */
848 #ifdef HAVE_LCD_COLOR
849 rb
->lcd_set_foreground(LCD_WHITE
);
850 rb
->lcd_fillrect(BOARD_X
-1,BOARD_Y
-1,BOARD_WIDTH
+2,BOARD_HEIGHT
+2);
851 rb
->lcd_set_foreground(LCD_BLACK
);
852 rb
->lcd_set_background(TEXT_BG
);
855 for (r
=0 ; r
< ROWS
; r
++) {
856 for (c
= 0 ; c
< COLS
; c
++) {
858 type
= pb
->playboard
[r
][c
];
865 rb
->lcd_bitmap_part(pegbox_pieces
, 0, (type
-1)*PIECE_HEIGHT
,
866 PIECE_WIDTH
, c
* PIECE_WIDTH
+ BOARD_X
,
867 r
* PIECE_HEIGHT
+ BOARD_Y
, PIECE_WIDTH
,
872 if(pb
->playboard
[r
][c
] == PLAYER
) {
876 else if (type
!= WALL
&& type
!= SPACE
&& type
!= HOLE
)
882 rb
->snprintf(str
, 3, "%d", pb
->level
);
883 rb
->lcd_putsxy(TEXT_X
, LEVEL_TEXT_Y
, str
);
884 rb
->snprintf(str
, 3, "%d", pb
->num_left
);
885 rb
->lcd_putsxy(TEXT_X
, PEGS_TEXT_Y
, str
);
887 rb
->snprintf(str
, 3, "%d", pb
->level
);
888 rb
->lcd_putsxy(LEVEL_TEXT_X
, TEXT_Y
, str
);
889 rb
->snprintf(str
, 3, "%d", pb
->num_left
);
890 rb
->lcd_putsxy(PEGS_TEXT_X
, TEXT_Y
, str
);
891 #endif /*WIDE_LAYOUT*/
893 #ifdef HAVE_LCD_COLOR
894 rb
->lcd_set_background(BG_COLOR
);
895 rb
->lcd_set_foreground(LCD_WHITE
);
897 /* print out the screen */
901 /*****************************************************************************
902 * load_level() loads the player's current level from the array and sets the
904 ******************************************************************************/
905 static void load_level(struct game_context
* pb
) {
908 for(r
= 0; r
< ROWS
; r
++)
909 for(c
= 0; c
< COLS
; c
++)
910 pb
->playboard
[r
][c
] = levels
[pb
->level
-1][r
][c
];
913 /*****************************************************************************
914 * new_piece() creates a new piece at a specified location. The player
915 * navigates through the pieces and selects one.
916 ******************************************************************************/
917 static void new_piece(struct game_context
* pb
, unsigned int x_loc
,
918 unsigned int y_loc
) {
922 pb
->playboard
[x_loc
][y_loc
] = TRIANGLE
;
926 button
= rb
->button_get(true);
927 #ifdef HAVE_TOUCHSCREEN
928 if(button
& BUTTON_TOUCHSCREEN
)
930 pegbox_raster_btn
.two_d_from
.y
= x_loc
;
931 pegbox_raster_btn
.two_d_from
.x
= y_loc
;
933 struct ts_raster_button_result ret
=
934 touchscreen_raster_map_button(&pegbox_raster_btn
,
935 rb
->button_get_data() >> 16,
936 rb
->button_get_data() & 0xffff,
938 if(ret
.action
== TS_ACTION_TWO_D_MOVEMENT
)
940 if(ret
.to
.x
> ret
.from
.x
)
942 else if(ret
.to
.x
< ret
.from
.x
)
943 button
= PEGBOX_DOWN
;
944 else if(ret
.to
.y
> ret
.from
.y
)
945 button
= PEGBOX_LEFT
;
946 else if(ret
.to
.y
< ret
.from
.y
)
947 button
= PEGBOX_RIGHT
;
949 else if(ret
.action
== TS_ACTION_CLICK
950 && (unsigned)ret
.to
.x
== y_loc
951 && (unsigned)ret
.to
.y
== x_loc
)
952 button
= PEGBOX_SAVE
;
957 case (PEGBOX_LEFT
|BUTTON_REPEAT
):
959 case (PEGBOX_DOWN
|BUTTON_REPEAT
):
960 if (pb
->playboard
[x_loc
][y_loc
] < 5)
961 pb
->playboard
[x_loc
][y_loc
]++;
963 pb
->playboard
[x_loc
][y_loc
] = TRIANGLE
;
966 case (PEGBOX_RIGHT
|BUTTON_REPEAT
):
968 case (PEGBOX_UP
|BUTTON_REPEAT
):
969 if (pb
->playboard
[x_loc
][y_loc
] > 2)
970 pb
->playboard
[x_loc
][y_loc
]--;
972 pb
->playboard
[x_loc
][y_loc
] = CIRCLE
;
981 /*****************************************************************************
982 * move_player() moves the player and pieces and updates the board accordingly.
983 ******************************************************************************/
984 static void move_player(struct game_context
* pb
, signed int x_dir
,
986 unsigned int type1
, type2
;
989 r
= pb
->player_row
+y_dir
;
990 c
= pb
->player_col
+x_dir
;
992 type1
= pb
->playboard
[r
][c
];
993 type2
= pb
->playboard
[r
+y_dir
][c
+x_dir
];
995 if (r
== ROWS
|| c
== COLS
|| r
< 0 || c
< 0 || type1
== WALL
)
997 else if(type1
!= SPACE
) {
998 if (type2
== WALL
|| r
+y_dir
== ROWS
|| c
+x_dir
== COLS
||
999 r
+y_dir
< 0 || c
+x_dir
< 0)
1004 pb
->playboard
[pb
->player_row
][pb
->player_col
] = SPACE
;
1005 pb
->player_row
+= y_dir
;
1006 pb
->player_col
+= x_dir
;
1008 if (type1
== HOLE
) {
1010 rb
->splash(HZ
*2, "You fell down a hole!");
1013 else if (type1
== SPACE
)
1014 pb
->playboard
[r
][c
] = PLAYER
;
1016 pb
->playboard
[r
][c
] = PLAYER
;
1017 if(type1
== type2
) {
1018 if (type1
== TRIANGLE
)
1019 pb
->playboard
[r
+y_dir
][c
+x_dir
] = WALL
;
1020 else if (type1
== CROSS
) {
1021 pb
->playboard
[r
][c
] = SPACE
;
1022 new_piece(pb
, r
+y_dir
, c
+x_dir
);
1023 pb
->playboard
[r
][c
] = PLAYER
;
1026 pb
->playboard
[r
+y_dir
][c
+x_dir
] = SPACE
;
1028 else if (type2
== SPACE
)
1029 pb
->playboard
[r
+y_dir
][c
+x_dir
] = type1
;
1030 else if (type2
== HOLE
) {
1031 if (type1
== SQUARE
)
1032 pb
->playboard
[r
+y_dir
][c
+x_dir
] = SPACE
;
1035 rb
->splash(HZ
*2, "Illegal Move!");
1043 /*****************************************************************************
1044 * pegbox_loadgame() loads the saved game and returns load success.
1045 ******************************************************************************/
1046 static bool pegbox_loadgame(struct game_context
* pb
) {
1048 bool loaded
= false;
1050 /* open game file */
1051 fd
= rb
->open(SAVE_FILE
, O_RDONLY
);
1052 if(fd
< 0) return loaded
;
1054 /* read in saved game */
1056 if(rb
->read(fd
, &pb
->level
, sizeof(pb
->level
)) <= 0) break;
1057 if(rb
->read(fd
, &pb
->playboard
, sizeof(pb
->playboard
)) <= 0)
1069 /*****************************************************************************
1070 * pegbox_savegame() saves the current game state.
1071 ******************************************************************************/
1072 static void pegbox_savegame(struct game_context
* pb
) {
1075 /* write out the game state to the save file */
1076 fd
= rb
->open(SAVE_FILE
, O_WRONLY
|O_CREAT
);
1077 rb
->write(fd
, &pb
->level
, sizeof(pb
->level
));
1078 rb
->write(fd
, &pb
->playboard
, sizeof(pb
->playboard
));
1082 /*****************************************************************************
1083 * pegbox_loaddata() loads the level and highlevel and returns load success.
1084 ******************************************************************************/
1085 static void pegbox_loaddata(struct game_context
* pb
) {
1088 /* open game file */
1089 fd
= rb
->open(DATA_FILE
, O_RDONLY
);
1096 /* read in saved game */
1098 if(rb
->read(fd
, &pb
->level
, sizeof(pb
->level
)) <= 0) break;
1099 if(rb
->read(fd
, &pb
->highlevel
, sizeof(pb
->highlevel
)) <= 0) break;
1107 /*****************************************************************************
1108 * pegbox_savedata() saves the level and highlevel.
1109 ******************************************************************************/
1110 static void pegbox_savedata(struct game_context
* pb
) {
1113 /* write out the game state to the save file */
1114 fd
= rb
->open(DATA_FILE
, O_WRONLY
|O_CREAT
);
1115 rb
->write(fd
, &pb
->level
, sizeof(pb
->level
));
1116 rb
->write(fd
, &pb
->highlevel
, sizeof(pb
->highlevel
));
1120 /*****************************************************************************
1121 * pegbox_callback() is the default event handler callback which is called
1122 * on usb connect and shutdown.
1123 ******************************************************************************/
1124 static void pegbox_callback(void* param
) {
1125 struct game_context
* pb
= (struct game_context
*) param
;
1126 rb
->splash(HZ
, "Saving data...");
1127 pegbox_savedata(pb
);
1130 /*****************************************************************************
1131 * pegbox_menu() is the initial menu at the start of the game.
1132 ******************************************************************************/
1133 static unsigned int pegbox_menu(struct game_context
* pb
) {
1136 unsigned int startlevel
= 1, loc
= 0;
1137 bool breakout
= false, can_resume
= false;
1139 if (pb
->num_left
> 0 || pb
->save_exist
)
1143 #if LCD_HEIGHT >= 80
1144 rb
->lcd_clear_display();
1145 rb
->lcd_bitmap(pegbox_menu_top
,0,0,LCD_WIDTH
, BMPHEIGHT_pegbox_menu_top
);
1149 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
, ITEM_WIDTH
,
1150 MENU_X
, MENU_Y
, ITEM_WIDTH
, ITEM_HEIGHT
);
1153 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, 0, ITEM_WIDTH
,
1154 MENU_X
, MENU_Y
, ITEM_WIDTH
, ITEM_HEIGHT
);
1158 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*3, ITEM_WIDTH
,
1159 MENU_X
, MENU_Y
+ITEM_HEIGHT
, ITEM_WIDTH
, ITEM_HEIGHT
);
1162 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*2, ITEM_WIDTH
,
1163 MENU_X
, MENU_Y
+ITEM_HEIGHT
, ITEM_WIDTH
, ITEM_HEIGHT
);
1167 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*4, ITEM_WIDTH
,
1168 MENU_X
, MENU_Y
+ITEM_HEIGHT
, ITEM_WIDTH
, ITEM_HEIGHT
);
1172 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*6, ITEM_WIDTH
,
1173 MENU_X
, MENU_Y
+ITEM_HEIGHT
*2, ITEM_WIDTH
, ITEM_HEIGHT
);
1176 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*5, ITEM_WIDTH
,
1177 MENU_X
, MENU_Y
+ITEM_HEIGHT
*2, ITEM_WIDTH
, ITEM_HEIGHT
);
1181 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*8, ITEM_WIDTH
,
1182 MENU_X
, MENU_Y
+ITEM_HEIGHT
*3, ITEM_WIDTH
, ITEM_HEIGHT
);
1185 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, ITEM_HEIGHT
*7, ITEM_WIDTH
,
1186 MENU_X
, MENU_Y
+ITEM_HEIGHT
*3, ITEM_WIDTH
, ITEM_HEIGHT
);
1190 rb
->lcd_clear_display();
1191 rb
->lcd_getstringsize("PegBox", &w
, &h
);
1192 rb
->lcd_putsxy((LCD_WIDTH
-w
)/2, 0, "PegBox");
1193 rb
->lcd_putsxy((LCD_WIDTH
)/4, 16, "New Game");
1194 rb
->lcd_putsxy((LCD_WIDTH
)/4, 24, "Resume");
1195 rb
->lcd_putsxy((LCD_WIDTH
)/4, 32, "Help");
1196 rb
->lcd_putsxy((LCD_WIDTH
)/4, 40, "Quit");
1199 rb
->lcd_hline((LCD_WIDTH
)/4, (LCD_WIDTH
)/4+30, 28);
1201 rb
->lcd_putsxy((LCD_WIDTH
)/4-8, loc
*8+16, "*");
1205 rb
->snprintf(str
, 28, "Start on level %d of %d", startlevel
,
1207 #if LCD_HEIGHT > 110
1208 rb
->lcd_putsxy(0, MENU_Y
+4*ITEM_HEIGHT
+8, str
);
1209 #elif LCD_HEIGHT > 64
1210 rb
->lcd_putsxy(0, LCD_HEIGHT
- 8, str
);
1212 rb
->lcd_puts_scroll(0, 7, str
);
1216 /* handle menu button presses */
1217 button
= rb
->button_get(true);
1219 #ifdef HAVE_TOUCHSCREEN
1220 if(button
& BUTTON_TOUCHSCREEN
)
1222 unsigned int result
= touchscreen_map(&main_menu
,
1223 rb
->button_get_data() >> 16,
1224 rb
->button_get_data() & 0xffff);
1225 if(result
!= (unsigned)-1 && button
& BUTTON_REL
)
1228 button
= PEGBOX_LVL_UP
;
1232 button
= PEGBOX_RIGHT
;
1240 case PEGBOX_SAVE
: /* start playing */
1244 pb
->level
= startlevel
;
1247 else if (loc
== 1 && can_resume
) {
1250 rb
->remove(SAVE_FILE
);
1251 pb
->save_exist
= false;
1256 display_text("How to Play\nTo beat each level, you must "
1257 "destroy all of the pegs. If two like pegs are "
1258 "pushed into each other they disappear except "
1259 "for triangles which form a solid block and "
1260 "crosses which allow you to choose a "
1261 "replacement block.\n\n"
1264 RESTART_TEXT
" to restart level\n"
1265 LVL_UP_TEXT
" to go up a level\n"
1266 LVL_DOWN_TEXT
" to go down a level\n"
1267 SAVE_TEXT
" to select/save\n"
1268 QUIT_TEXT
" to quit\n",true);
1270 RESTART_TEXT
": restart\n"
1271 LVL_UP_TEXT
": level up\n"
1272 LVL_DOWN_TEXT
" level down\n"
1273 SAVE_TEXT
" select/save\n"
1274 QUIT_TEXT
" quit\n",true);
1280 case PEGBOX_QUIT
: /* quit program */
1283 case (PEGBOX_UP
|BUTTON_REPEAT
):
1289 if (!can_resume
&& loc
== 1) {
1295 case (PEGBOX_DOWN
|BUTTON_REPEAT
):
1301 if (!can_resume
&& loc
== 1) {
1306 case (PEGBOX_LVL_UP
|BUTTON_REPEAT
):
1307 case PEGBOX_LVL_UP
: /* increase starting level */
1308 if(startlevel
>= pb
->highlevel
) {
1315 /* only for targets with enough buttons */
1316 #ifdef PEGBOX_LVL_DOWN
1317 case (PEGBOX_LVL_DOWN
|BUTTON_REPEAT
):
1318 case PEGBOX_LVL_DOWN
: /* decrease starting level */
1319 if(startlevel
<= 1) {
1320 startlevel
= pb
->highlevel
;
1327 if(rb
->default_event_handler_ex(button
, pegbox_callback
,
1328 (void*) pb
) == SYS_USB_CONNECTED
)
1339 /*****************************************************************************
1340 * pegbox() is the main game subroutine, it returns the final game status.
1341 ******************************************************************************/
1342 static int pegbox(struct game_context
* pb
) {
1345 /********************
1347 ********************/
1348 temp_var
= pegbox_menu(pb
);
1349 if (temp_var
== PB_QUIT
|| temp_var
== PB_USB
)
1353 temp_var
= rb
->button_get(true);
1354 #ifdef HAVE_TOUCHSCREEN
1355 if(temp_var
& BUTTON_TOUCHSCREEN
)
1357 pegbox_raster_btn
.two_d_from
.y
= pb
->player_row
;
1358 pegbox_raster_btn
.two_d_from
.x
= pb
->player_col
;
1360 struct ts_raster_button_result ret
=
1361 touchscreen_raster_map_button(&pegbox_raster_btn
,
1362 rb
->button_get_data() >> 16,
1363 rb
->button_get_data() & 0xffff,
1365 if(ret
.action
== TS_ACTION_TWO_D_MOVEMENT
)
1366 move_player(pb
, ret
.to
.x
- ret
.from
.x
, ret
.to
.y
- ret
.from
.y
);
1370 case PEGBOX_LEFT
: /* move cursor left */
1371 case (PEGBOX_LEFT
|BUTTON_REPEAT
):
1372 move_player(pb
, -1, 0);
1375 case PEGBOX_RIGHT
: /* move cursor right */
1376 case (PEGBOX_RIGHT
|BUTTON_REPEAT
):
1377 move_player(pb
, 1, 0);
1380 case PEGBOX_DOWN
: /* move cursor down */
1381 case (PEGBOX_DOWN
|BUTTON_REPEAT
):
1382 move_player(pb
, 0, 1);
1385 case PEGBOX_UP
: /* move cursor up */
1386 case (PEGBOX_UP
|BUTTON_REPEAT
):
1387 move_player(pb
, 0, -1);
1390 case PEGBOX_SAVE
: /* save and end game */
1391 rb
->splash(HZ
, "Saving game...");
1392 pegbox_savegame(pb
);
1393 /* fall through to PEGBOX_QUIT */
1398 case PEGBOX_RESTART
:
1403 case (PEGBOX_LVL_UP
|BUTTON_REPEAT
):
1405 if(pb
->level
>= pb
->highlevel
) {
1414 /* only for targets with enough buttons */
1415 #ifdef PEGBOX_LVL_DOWN
1416 case (PEGBOX_LVL_DOWN
|BUTTON_REPEAT
):
1417 case PEGBOX_LVL_DOWN
:
1418 if(pb
->level
<= 1) {
1419 pb
->level
= pb
->highlevel
;
1430 if(pb
->num_left
== 0) {
1431 rb
->splash(HZ
*2, "Nice Pegging!");
1432 if(pb
->level
== NUM_LEVELS
) {
1434 rb
->splash(HZ
*2, "You Won!");
1443 if(pb
->level
> pb
->highlevel
)
1444 pb
->highlevel
= pb
->level
;
1453 /*****************************************************************************
1454 * plugin entry point.
1455 ******************************************************************************/
1456 enum plugin_status
plugin_start(const void* parameter
) {
1458 struct game_context pb
;
1462 rb
->lcd_setfont(FONT_SYSFIXED
);
1464 rb
->lcd_set_backdrop(NULL
);
1466 #ifdef HAVE_LCD_COLOR
1467 rb
->lcd_set_foreground(LCD_WHITE
);
1468 rb
->lcd_set_background(BG_COLOR
);
1471 rb
->splash(0, "Loading...");
1472 pegbox_loaddata(&pb
);
1473 pb
.save_exist
= pegbox_loadgame(&pb
);
1476 rb
->lcd_clear_display();
1480 switch(pegbox(&pb
)){
1485 rb
->lcd_setfont(FONT_UI
);
1486 return PLUGIN_USB_CONNECTED
;
1489 rb
->splash(HZ
, "Saving data...");
1490 pegbox_savedata(&pb
);
1499 rb
->lcd_setfont(FONT_UI
);