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 #if (LCD_WIDTH >= 138) && (LCD_HEIGHT >= 110)
24 #include "pegbox_menu_top.h"
25 #include "pegbox_menu_items.h"
26 #include "pegbox_header.h"
28 #include "pegbox_pieces.h"
30 static const struct plugin_api
* rb
;
34 /* final game return status */
39 #define DATA_FILE PLUGIN_DIR "/games/pegbox.data"
40 #define SAVE_FILE PLUGIN_DIR "/games/pegbox.save"
42 #define ROWS 8 /* Number of rows on each board */
43 #define COLS 12 /* Number of columns on each board */
44 #define NUM_LEVELS 15 /* Number of levels */
55 #if CONFIG_KEYPAD == RECORDER_PAD
56 #define PEGBOX_SAVE BUTTON_ON
57 #define PEGBOX_QUIT BUTTON_OFF
58 #define PEGBOX_RESTART BUTTON_F2
59 #define PEGBOX_LVL_UP BUTTON_F1
60 #define PEGBOX_LVL_DOWN BUTTON_F3
61 #define PEGBOX_UP BUTTON_UP
62 #define PEGBOX_DOWN BUTTON_DOWN
63 #define PEGBOX_RIGHT BUTTON_RIGHT
64 #define PEGBOX_LEFT BUTTON_LEFT
66 #define SAVE_TEXT "ON"
67 #define QUIT_TEXT "OFF"
68 #define RESTART_TEXT "F2"
69 #define LVL_UP_TEXT "F1"
70 #define LVL_DOWN_TEXT "F3"
72 #elif CONFIG_KEYPAD == ONDIO_PAD
73 #define PEGBOX_SAVE BUTTON_OFF
74 #define PEGBOX_QUIT (BUTTON_MENU | BUTTON_LEFT)
75 #define PEGBOX_RESTART (BUTTON_MENU | BUTTON_RIGHT)
76 #define PEGBOX_LVL_UP (BUTTON_MENU | BUTTON_UP)
77 #define PEGBOX_LVL_DOWN (BUTTON_MENU | BUTTON_DOWN)
78 #define PEGBOX_UP BUTTON_UP
79 #define PEGBOX_DOWN BUTTON_DOWN
80 #define PEGBOX_RIGHT BUTTON_RIGHT
81 #define PEGBOX_LEFT BUTTON_LEFT
83 #define SAVE_TEXT "OFF"
84 #define QUIT_TEXT "M+LEFT"
85 #define RESTART_TEXT "M+RIGHT"
86 #define LVL_UP_TEXT "M+UP"
87 #define LVL_DOWN_TEXT "M+DOWN"
89 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
90 (CONFIG_KEYPAD == IRIVER_H300_PAD)
91 #define PEGBOX_SAVE BUTTON_SELECT
92 #define PEGBOX_QUIT BUTTON_OFF
93 #define PEGBOX_RESTART BUTTON_ON
94 #define PEGBOX_LVL_UP BUTTON_MODE
95 #define PEGBOX_LVL_DOWN BUTTON_REC
96 #define PEGBOX_UP BUTTON_UP
97 #define PEGBOX_DOWN BUTTON_DOWN
98 #define PEGBOX_RIGHT BUTTON_RIGHT
99 #define PEGBOX_LEFT BUTTON_LEFT
101 #define SAVE_TEXT "NAVI"
102 #define QUIT_TEXT "OFF"
103 #define RESTART_TEXT "ON"
104 #define LVL_UP_TEXT "AB"
105 #define LVL_DOWN_TEXT "REC"
107 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
108 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
109 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
110 #define PEGBOX_SAVE (BUTTON_SELECT|BUTTON_RIGHT)
111 #define PEGBOX_QUIT (BUTTON_SELECT|BUTTON_PLAY)
112 #define PEGBOX_RESTART (BUTTON_SELECT|BUTTON_LEFT)
113 #define PEGBOX_LVL_UP (BUTTON_SELECT|BUTTON_MENU)
114 #define PEGBOX_UP BUTTON_MENU
115 #define PEGBOX_DOWN BUTTON_PLAY
116 #define PEGBOX_RIGHT BUTTON_RIGHT
117 #define PEGBOX_LEFT BUTTON_LEFT
119 #define SAVE_TEXT "SELECT+RIGHT"
120 #define QUIT_TEXT "SELECT+PLAY"
121 #define RESTART_TEXT "SELECT+LEFT"
122 #define LVL_UP_TEXT "SELECT+MENU"
123 #define LVL_DOWN_TEXT "-"
125 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
126 #define PEGBOX_SAVE BUTTON_SELECT
127 #define PEGBOX_QUIT BUTTON_POWER
128 #define PEGBOX_RESTART BUTTON_REC
129 #define PEGBOX_LVL_UP BUTTON_PLAY
130 #define PEGBOX_UP BUTTON_UP
131 #define PEGBOX_DOWN BUTTON_DOWN
132 #define PEGBOX_RIGHT BUTTON_RIGHT
133 #define PEGBOX_LEFT BUTTON_LEFT
135 #define SAVE_TEXT "SELECT"
136 #define QUIT_TEXT "OFF"
137 #define RESTART_TEXT "REC"
138 #define LVL_UP_TEXT "PLAY"
139 #define LVL_DOWN_TEXT "-"
141 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
142 #define PEGBOX_SAVE BUTTON_MODE
143 #define PEGBOX_QUIT BUTTON_PLAY
144 #define PEGBOX_RESTART (BUTTON_EQ|BUTTON_MODE)
145 #define PEGBOX_LVL_UP (BUTTON_EQ|BUTTON_UP)
146 #define PEGBOX_LVL_DOWN (BUTTON_EQ|BUTTON_DOWN)
147 #define PEGBOX_UP BUTTON_UP
148 #define PEGBOX_DOWN BUTTON_DOWN
149 #define PEGBOX_RIGHT BUTTON_RIGHT
150 #define PEGBOX_LEFT BUTTON_LEFT
152 #define SAVE_TEXT "MODE"
153 #define QUIT_TEXT "PLAY"
154 #define RESTART_TEXT "EQ+MODE"
155 #define LVL_UP_TEXT "EQ+UP"
156 #define LVL_DOWN_TEXT "EQ+DOWN"
158 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
159 #define PEGBOX_SAVE BUTTON_PLAY
160 #define PEGBOX_QUIT BUTTON_POWER
161 #define PEGBOX_RESTART (BUTTON_FF|BUTTON_REPEAT)
162 #define PEGBOX_LVL_UP (BUTTON_FF|BUTTON_SCROLL_UP)
163 #define PEGBOX_LVL_DOWN (BUTTON_FF|BUTTON_SCROLL_DOWN)
164 #define PEGBOX_UP BUTTON_SCROLL_UP
165 #define PEGBOX_DOWN BUTTON_SCROLL_DOWN
166 #define PEGBOX_RIGHT BUTTON_RIGHT
167 #define PEGBOX_LEFT BUTTON_LEFT
169 #define SAVE_TEXT "PLAY"
170 #define QUIT_TEXT "OFF"
171 #define RESTART_TEXT "LONG FF"
172 #define LVL_UP_TEXT "FF+SCROLL_UP"
173 #define LVL_DOWN_TEXT "FF+SCROLL_DOWN"
175 #elif CONFIG_KEYPAD == SANSA_E200_PAD
176 #define PEGBOX_SAVE BUTTON_SELECT
177 #define PEGBOX_QUIT BUTTON_POWER
178 #define PEGBOX_RESTART BUTTON_REC
179 #define PEGBOX_LVL_UP BUTTON_SCROLL_BACK
180 #define PEGBOX_LVL_DOWN BUTTON_SCROLL_FWD
181 #define PEGBOX_UP BUTTON_UP
182 #define PEGBOX_DOWN BUTTON_DOWN
183 #define PEGBOX_RIGHT BUTTON_RIGHT
184 #define PEGBOX_LEFT BUTTON_LEFT
186 #define SAVE_TEXT "SELECT"
187 #define QUIT_TEXT "POWER"
188 #define RESTART_TEXT "REC"
189 #define LVL_UP_TEXT "SCROLL BACK"
190 #define LVL_DOWN_TEXT "SCROLL FWD"
192 #elif CONFIG_KEYPAD == GIGABEAT_PAD
193 #define PEGBOX_SAVE BUTTON_SELECT
194 #define PEGBOX_QUIT BUTTON_POWER
195 #define PEGBOX_RESTART BUTTON_A
196 #define PEGBOX_LVL_UP BUTTON_VOL_UP
197 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
198 #define PEGBOX_UP BUTTON_UP
199 #define PEGBOX_DOWN BUTTON_DOWN
200 #define PEGBOX_RIGHT BUTTON_RIGHT
201 #define PEGBOX_LEFT BUTTON_LEFT
203 #define SAVE_TEXT "SELECT"
204 #define QUIT_TEXT "POWER"
205 #define RESTART_TEXT "A"
206 #define LVL_UP_TEXT "VOL+"
207 #define LVL_DOWN_TEXT "VOL-"
209 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
210 #define PEGBOX_SAVE BUTTON_SELECT
211 #define PEGBOX_QUIT BUTTON_BACK
212 #define PEGBOX_RESTART BUTTON_MENU
213 #define PEGBOX_LVL_UP BUTTON_VOL_UP
214 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
215 #define PEGBOX_UP BUTTON_UP
216 #define PEGBOX_DOWN BUTTON_DOWN
217 #define PEGBOX_RIGHT BUTTON_RIGHT
218 #define PEGBOX_LEFT BUTTON_LEFT
220 #define SAVE_TEXT "SELECT"
221 #define QUIT_TEXT "BACK"
222 #define RESTART_TEXT "MENU"
223 #define LVL_UP_TEXT "VOL+"
224 #define LVL_DOWN_TEXT "VOL-"
226 #elif CONFIG_KEYPAD == MROBE100_PAD
227 #define PEGBOX_SAVE BUTTON_SELECT
228 #define PEGBOX_QUIT BUTTON_POWER
229 #define PEGBOX_RESTART BUTTON_PLAY
230 #define PEGBOX_LVL_UP BUTTON_MENU
231 #define PEGBOX_LVL_DOWN BUTTON_DISPLAY
232 #define PEGBOX_UP BUTTON_UP
233 #define PEGBOX_DOWN BUTTON_DOWN
234 #define PEGBOX_RIGHT BUTTON_RIGHT
235 #define PEGBOX_LEFT BUTTON_LEFT
237 #define SAVE_TEXT "SELECT"
238 #define QUIT_TEXT "POWER"
239 #define RESTART_TEXT "PLAY"
240 #define LVL_UP_TEXT "MENU"
241 #define LVL_DOWN_TEXT "DISPLAY"
243 #elif CONFIG_KEYPAD == SANSA_C200_PAD
244 #define PEGBOX_SAVE BUTTON_SELECT
245 #define PEGBOX_QUIT BUTTON_POWER
246 #define PEGBOX_RESTART BUTTON_REC
247 #define PEGBOX_LVL_UP BUTTON_VOL_UP
248 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
249 #define PEGBOX_UP BUTTON_UP
250 #define PEGBOX_DOWN BUTTON_DOWN
251 #define PEGBOX_RIGHT BUTTON_RIGHT
252 #define PEGBOX_LEFT BUTTON_LEFT
254 #define SAVE_TEXT "SELECT"
255 #define QUIT_TEXT "POWER"
256 #define RESTART_TEXT "REC"
257 #define LVL_UP_TEXT "VOL+"
258 #define LVL_DOWN_TEXT "VOL-"
260 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
261 #define PEGBOX_SAVE BUTTON_RC_PLAY
262 #define PEGBOX_QUIT BUTTON_RC_REC
263 #define PEGBOX_RESTART BUTTON_RC_MODE
264 #define PEGBOX_LVL_UP BUTTON_VOL_UP
265 #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN
266 #define PEGBOX_UP BUTTON_RC_VOL_UP
267 #define PEGBOX_DOWN BUTTON_RC_VOL_DOWN
268 #define PEGBOX_RIGHT BUTTON_RC_FF
269 #define PEGBOX_LEFT BUTTON_RC_REW
271 #define SAVE_TEXT "REM. PLAY"
272 #define QUIT_TEXT "REM. REC"
273 #define RESTART_TEXT "REM. MODE"
274 #define LVL_UP_TEXT "VOL+"
275 #define LVL_DOWN_TEXT "VOL-"
277 #elif CONFIG_KEYPAD == COWOND2_PAD
278 #define PEGBOX_QUIT BUTTON_POWER
280 #define QUIT_TEXT "POWER"
282 #error Unsupported keymap!
287 #define PEGBOX_QUIT BUTTON_TOPLEFT
290 #define PEGBOX_SAVE BUTTON_CENTER
292 #ifndef PEGBOX_RESTART
293 #define PEGBOX_RESTART BUTTON_TOPRIGHT
295 #ifndef PEGBOX_LVL_UP
296 #define PEGBOX_LVL_UP BUTTON_BOTTOMLEFT
298 #ifndef PEGBOX_LVL_DOWN
299 #define PEGBOX_LVL_DOWN BUTTON_BOTTOMRIGHT
302 #define PEGBOX_UP BUTTON_TOPMIDDLE
305 #define PEGBOX_DOWN BUTTON_BOTTOMMIDDLE
308 #define PEGBOX_RIGHT BUTTON_MIDRIGHT
311 #define PEGBOX_LEFT BUTTON_MIDLEFT
314 #define SAVE_TEXT "CENTER"
317 #define QUIT_TEXT "TOPLEFT"
320 #define RESTART_TEXT "TOPRIGHT"
323 #define LVL_UP_TEXT "BOTTOMLEFT"
325 #ifndef LVL_DOWN_TEXT
326 #define LVL_DOWN_TEXT "BOTTOMRIGHT"
330 #if (LCD_WIDTH >= 320) && (LCD_HEIGHT >= 240)
331 #define LEVEL_TEXT_X 59
332 #define PEGS_TEXT_X 276
334 #elif (LCD_WIDTH >= 240) && (LCD_HEIGHT >= 192)
335 #define LEVEL_TEXT_X 59
336 #define PEGS_TEXT_X 196
338 #elif (LCD_WIDTH >= 220) && (LCD_HEIGHT >= 176)
339 #define LEVEL_TEXT_X 49
340 #define PEGS_TEXT_X 186
342 #elif (LCD_WIDTH >= 176) && (LCD_HEIGHT >= 132)
343 #define LEVEL_TEXT_X 38
344 #define PEGS_TEXT_X 155
346 #elif (LCD_WIDTH >= 160) && (LCD_HEIGHT >= 128)
347 #define LEVEL_TEXT_X 37
348 #define PEGS_TEXT_X 140
350 #elif (LCD_WIDTH >= 138) && (LCD_HEIGHT >= 110)
351 #define LEVEL_TEXT_X 28
352 #define PEGS_TEXT_X 119
354 #elif (LCD_WIDTH >= 128) && (LCD_HEIGHT >= 128)
355 #define LEVEL_TEXT_X 28
356 #define PEGS_TEXT_X 119
360 #ifdef HAVE_LCD_COLOR
361 #define BG_COLOR LCD_BLACK
362 #define TEXT_BG LCD_RGBPACK(189,189,189)
365 #define BOARD_X (LCD_WIDTH-12*BMPWIDTH_pegbox_pieces)/2
367 #if (LCD_WIDTH >= 138) && (LCD_HEIGHT >= 110)
368 #define BOARD_Y BMPHEIGHT_pegbox_header+2
374 #include "lib/touchscreen.h"
376 static struct ts_mapping main_menu_items
[5] =
378 {(LCD_WIDTH
-BMPWIDTH_pegbox_menu_items
)/2, BMPHEIGHT_pegbox_menu_top
, BMPWIDTH_pegbox_menu_items
, (BMPHEIGHT_pegbox_menu_items
/9)},
379 {(LCD_WIDTH
-BMPWIDTH_pegbox_menu_items
)/2, BMPHEIGHT_pegbox_menu_top
+(BMPHEIGHT_pegbox_menu_items
/9), BMPWIDTH_pegbox_menu_items
, (BMPHEIGHT_pegbox_menu_items
/9)},
380 {(LCD_WIDTH
-BMPWIDTH_pegbox_menu_items
)/2, BMPHEIGHT_pegbox_menu_top
+(BMPHEIGHT_pegbox_menu_items
/9)*2, BMPWIDTH_pegbox_menu_items
, (BMPHEIGHT_pegbox_menu_items
/9)},
381 {(LCD_WIDTH
-BMPWIDTH_pegbox_menu_items
)/2, BMPHEIGHT_pegbox_menu_top
+(BMPHEIGHT_pegbox_menu_items
/9)*3, BMPWIDTH_pegbox_menu_items
, (BMPHEIGHT_pegbox_menu_items
/9)},
383 #if (LCD_WIDTH >= 138) && (LCD_HEIGHT >= 110)
384 0, BMPHEIGHT_pegbox_menu_top
+4*(BMPHEIGHT_pegbox_menu_items
/9)+8, SYSFONT_WIDTH
*28, SYSFONT_HEIGHT
385 #elif LCD_WIDTH > 112
386 0, LCD_HEIGHT
- 8, SYSFONT_WIDTH
*28, SYSFONT_HEIGHT
388 #error "Touchpad isn't supported on non-bitmap screens!"
393 static struct ts_mappings main_menu
= {main_menu_items
, 5};
395 static struct ts_raster pegbox_raster
= { BOARD_X
, BOARD_Y
, COLS
*BMPWIDTH_pegbox_pieces
, ROWS
*BMPWIDTH_pegbox_pieces
, BMPWIDTH_pegbox_pieces
, BMPWIDTH_pegbox_pieces
};
396 static struct ts_raster_button_mapping pegbox_raster_btn
= { &pegbox_raster
, false, false, true, false, true, {0, 0}, 0, 0, 0 };
399 struct game_context
{
401 unsigned int highlevel
;
402 signed int player_row
;
403 signed int player_col
;
404 unsigned int num_left
;
406 unsigned int playboard
[ROWS
][COLS
];
409 char levels
[NUM_LEVELS
][ROWS
][COLS
] = {
411 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
412 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
413 {1, 0, 0, 0, 7, 0, 0, 5, 0, 0, 0, 1,},
414 {1, 0, 0, 0, 0, 3, 3, 2, 0, 0, 0, 1,},
415 {1, 0, 0, 0, 4, 6, 0, 5, 0, 0, 0, 1,},
416 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
417 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,},
418 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
421 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
422 {1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 1,},
423 {1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1,},
424 {1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1,},
425 {7, 0, 0, 0, 2, 2, 5, 5, 0, 0, 0, 1,},
426 {1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1,},
427 {1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1,},
428 {1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 1,}},
431 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
432 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
433 {1, 0, 0, 0, 0, 0, 2, 0, 7, 0, 0, 0,},
434 {1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 2, 1,},
435 {1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1,},
436 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1,},
437 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
438 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
441 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
442 {6, 0, 4, 0, 2, 0, 2, 0, 0, 0, 0, 1,},
443 {6, 0, 3, 0, 5, 0, 2, 0, 0, 0, 0, 1,},
444 {6, 0, 5, 0, 4, 7, 2, 0, 0, 0, 0, 1,},
445 {6, 0, 2, 0, 4, 0, 2, 0, 3, 0, 0, 1,},
446 {6, 0, 4, 0, 5, 0, 2, 0, 0, 0, 0, 1,},
447 {6, 0, 5, 0, 4, 0, 2, 0, 0, 0, 0, 1,},
448 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
451 {{0, 6, 6, 0, 4, 6, 0, 0, 6, 0, 0, 0,},
452 {0, 6, 6, 0, 4, 4, 0, 0, 6, 0, 0, 2,},
453 {2, 6, 6, 0, 6, 6, 6, 0, 1, 2, 2, 2,},
454 {0, 6, 6, 0, 6, 4, 6, 0, 1, 2, 0, 2,},
455 {0, 6, 6, 0, 6, 7, 6, 5, 6, 0, 0, 0,},
456 {2, 6, 6, 0, 6, 6, 6, 0, 6, 0, 0, 0,},
457 {0, 6, 6, 0, 4, 0, 0, 0, 6, 0, 0, 0,},
458 {0, 6, 6, 0, 0, 5, 0, 0, 6, 5, 5, 0,}},
461 {{7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
462 {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0,},
463 {2, 0, 0, 2, 0, 0, 0, 2, 2, 0, 0, 0,},
464 {0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 0,},
465 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
466 {0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1,},
467 {0, 3, 0, 0, 0, 0, 0, 0, 5, 4, 6, 0,},
468 {0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1,}},
471 {{1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1,},
472 {1, 1, 1, 6, 0, 0, 4, 6, 0, 1, 1, 1,},
473 {1, 1, 1, 1, 0, 1, 5, 1, 0, 1, 1, 1,},
474 {1, 1, 1, 2, 3, 3, 7, 4, 2, 6, 1, 1,},
475 {1, 1, 1, 1, 0, 1, 2, 1, 0, 0, 0, 1,},
476 {1, 1, 1, 1, 0, 0, 5, 0, 0, 1, 0, 1,},
477 {1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1,},
478 {1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,}},
481 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
482 {0, 0, 3, 3, 3, 3, 3, 4, 3, 3, 0, 0,},
483 {0, 0, 3, 3, 3, 2, 3, 3, 5, 3, 0, 0,},
484 {7, 0, 3, 3, 3, 2, 3, 3, 4, 3, 0, 0,},
485 {0, 0, 3, 3, 4, 5, 3, 3, 3, 3, 0, 0,},
486 {0, 0, 3, 3, 5, 2, 3, 3, 3, 3, 0, 0,},
487 {0, 0, 3, 3, 2, 4, 3, 3, 3, 3, 0, 0,},
488 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
491 {{0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,},
492 {0, 3, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,},
493 {0, 0, 0, 0, 2, 4, 4, 3, 0, 1, 1, 0,},
494 {0, 1, 0, 0, 2, 1, 0, 0, 0, 1, 1, 1,},
495 {0, 0, 0, 2, 2, 7, 1, 0, 0, 0, 0, 2,},
496 {0, 0, 0, 0, 2, 1, 0, 0, 1, 1, 1, 1,},
497 {0, 3, 1, 0, 2, 5, 5, 0, 0, 0, 3, 0,},
498 {0, 0, 0, 0, 4, 1, 0, 0, 0, 0, 0, 0,}},
501 {{1, 1, 1, 1, 2, 1, 1, 1, 0, 0, 0, 0,},
502 {1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 7,},
503 {0, 0, 4, 0, 6, 6, 6, 0, 0, 0, 3, 0,},
504 {0, 3, 3, 0, 6, 6, 6, 0, 4, 3, 4, 0,},
505 {0, 3, 3, 0, 6, 6, 6, 0, 4, 3, 4, 0,},
506 {0, 0, 0, 0, 6, 6, 6, 0, 3, 0, 0, 0,},
507 {1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0,},
508 {1, 1, 1, 1, 1, 2, 1, 1, 0, 0, 0, 0,}},
511 {{1, 7, 1, 0, 1, 1, 6, 0, 0, 1, 1, 0,},
512 {1, 0, 0, 0, 5, 4, 6, 6, 0, 2, 2, 0,},
513 {1, 2, 1, 2, 0, 1, 6, 0, 0, 2, 2, 0,},
514 {1, 0, 0, 2, 0, 1, 0, 0, 0, 3, 3, 0,},
515 {1, 2, 1, 0, 0, 1, 0, 1, 0, 3, 3, 0,},
516 {0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0,},
517 {0, 3, 4, 3, 0, 1, 0, 1, 0, 0, 0, 0,},
518 {0, 0, 0, 0, 2, 2, 2, 1, 1, 1, 1, 1,}},
521 {{7, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,},
522 {1, 2, 1, 2, 1, 2, 1, 1, 0, 0, 0, 1,},
523 {0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1,},
524 {1, 2, 1, 2, 1, 2, 1, 0, 0, 0, 0, 1,},
525 {0, 0, 0, 0, 0, 0, 1, 1, 5, 5, 6, 1,},
526 {1, 2, 1, 2, 1, 2, 1, 1, 0, 2, 2, 1,},
527 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1,},
528 {1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1,}},
531 {{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,},
532 {0, 0, 4, 0, 2, 0, 5, 0, 4, 0, 0, 6,},
533 {0, 0, 2, 0, 5, 0, 2, 0, 4, 0, 0, 6,},
534 {7, 0, 3, 0, 4, 0, 5, 0, 4, 0, 0, 6,},
535 {0, 0, 5, 0, 4, 0, 2, 0, 4, 0, 0, 6,},
536 {0, 0, 4, 0, 2, 0, 5, 0, 4, 0, 0, 6,},
537 {0, 0, 3, 0, 3, 0, 2, 0, 4, 0, 0, 6,},
538 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
541 {{1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1,},
542 {1, 1, 0, 2, 0, 0, 4, 0, 0, 2, 0, 1,},
543 {1, 6, 0, 0, 5, 1, 0, 1, 1, 0, 0, 1,},
544 {1, 1, 1, 0, 0, 3, 5, 3, 0, 0, 1, 1,},
545 {1, 1, 0, 0, 1, 1, 0, 1, 5, 0, 0, 6,},
546 {1, 1, 0, 2, 0, 0, 4, 0, 0, 0, 7, 1,},
547 {1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1,},
548 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,}},
551 {{0, 0, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
552 {0, 0, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
553 {0, 3, 4, 6, 0, 6, 0, 6, 0, 6, 0, 2,},
554 {0, 4, 0, 6, 0, 6, 4, 6, 0, 6, 0, 1,},
555 {0, 3, 0, 6, 0, 6, 0, 6, 0, 6, 0, 1,},
556 {7, 0, 0, 6, 4, 6, 0, 6, 0, 6, 0, 1,},
557 {0, 0, 4, 6, 0, 6, 0, 6, 4, 6, 0, 1,},
558 {0, 0, 4, 6, 0, 6, 0, 6, 0, 6, 0, 1,}}
562 /*****************************************************************************
563 * display_text() formats and outputs text.
564 ******************************************************************************/
565 static void display_text(char *str
, bool waitkey
)
570 int current_line
= 0;
571 int char_width
, char_height
;
572 int first_char_index
= 0;
580 rb
->lcd_clear_display();
582 rb
->lcd_getstringsize("a", &char_width
, &char_height
);
584 chars_by_line
= LCD_WIDTH
/ char_width
;
585 lines_by_screen
= LCD_HEIGHT
/ char_height
;
589 ptr_char
= str
+ first_char_index
;
593 while (i
< chars_by_line
)
606 *(ptr_line
++) = *ptr_char
;
608 if (*ptr_char
== '\n' || *ptr_char
== '\0')
614 if (chars_for_line
== 0)
617 line
[chars_for_line
] = '\0';
619 /* test if we have cut a word. If it is the case we don't have to */
621 if (i
== chars_by_line
&& chars_for_line
== chars_by_line
)
622 first_char_index
+= chars_for_line
;
624 first_char_index
+= chars_for_line
+ 1;
626 /* print the line on the screen */
627 rb
->lcd_putsxy(0, current_line
* char_height
, line
);
629 /* if the number of line showed on the screen is equals to the */
630 /* maximum number of line we can show, we wait for a key pressed to */
631 /* clear and show the remaining text. */
633 if (current_line
== lines_by_screen
|| *ptr_char
== '\0')
638 while (waitkey
&& !go_on
)
640 key
= rb
->button_get(true);
644 case BUTTON_TOUCHPAD
:
653 /*if (rb->default_event_handler(key) == SYS_USB_CONNECTED)
662 rb
->lcd_clear_display();
664 } while (*ptr_char
!= '\0');
667 /*****************************************************************************
668 * draw_board() draws the game's current level.
669 ******************************************************************************/
670 static void draw_board(struct game_context
* pb
) {
671 unsigned int r
, c
, type
;
673 #if (LCD_WIDTH >= 138) && (LCD_HEIGHT >= 110)
676 rb
->lcd_clear_display();
677 rb
->lcd_bitmap(pegbox_header
,0,0,LCD_WIDTH
, BMPHEIGHT_pegbox_header
);
678 rb
->lcd_drawrect((LCD_WIDTH
-12*BMPWIDTH_pegbox_pieces
)/2-2,
679 BMPHEIGHT_pegbox_header
,
680 12*BMPWIDTH_pegbox_pieces
+4,8*BMPWIDTH_pegbox_pieces
+4);
682 #ifdef HAVE_LCD_COLOR
683 rb
->lcd_set_foreground(LCD_WHITE
);
684 rb
->lcd_fillrect((LCD_WIDTH
-12*BMPWIDTH_pegbox_pieces
)/2-1,BMPHEIGHT_pegbox_header
+1,
685 12*BMPWIDTH_pegbox_pieces
+2,8*BMPWIDTH_pegbox_pieces
+2);
686 rb
->lcd_set_foreground(LCD_BLACK
);
687 rb
->lcd_set_background(TEXT_BG
);
691 rb
->lcd_clear_display();
693 #ifdef HAVE_LCD_COLOR
694 rb
->lcd_set_foreground(LCD_WHITE
);
695 rb
->lcd_fillrect((LCD_WIDTH
-12*BMPWIDTH_pegbox_pieces
)/2-1,0,
696 12*BMPWIDTH_pegbox_pieces
+2,8*BMPWIDTH_pegbox_pieces
+1);
697 rb
->lcd_set_foreground(LCD_BLACK
);
698 rb
->lcd_set_background(TEXT_BG
);
703 for (r
=0 ; r
< ROWS
; r
++) {
704 for (c
= 0 ; c
< COLS
; c
++) {
706 type
= pb
->playboard
[r
][c
];
713 rb
->lcd_bitmap_part(pegbox_pieces
, 0,
714 (type
-1)*BMPWIDTH_pegbox_pieces
,
715 BMPWIDTH_pegbox_pieces
,
716 c
* BMPWIDTH_pegbox_pieces
+ BOARD_X
,
717 r
* BMPWIDTH_pegbox_pieces
+ BOARD_Y
,
718 BMPWIDTH_pegbox_pieces
,
719 BMPWIDTH_pegbox_pieces
);
723 if(pb
->playboard
[r
][c
] == PLAYER
) {
727 else if (type
!= WALL
&& type
!= SPACE
&& type
!= HOLE
)
731 #if (LCD_WIDTH >= 138) && (LCD_HEIGHT >= 110)
732 rb
->snprintf(str
, 3, "%d", pb
->level
);
733 rb
->lcd_putsxy(LEVEL_TEXT_X
, TEXT_Y
, str
);
734 rb
->snprintf(str
, 3, "%d", pb
->num_left
);
735 rb
->lcd_putsxy(PEGS_TEXT_X
, TEXT_Y
, str
);
738 #ifdef HAVE_LCD_COLOR
739 rb
->lcd_set_background(BG_COLOR
);
740 rb
->lcd_set_foreground(LCD_WHITE
);
742 /* print out the screen */
746 /*****************************************************************************
747 * load_level() loads the player's current level from the array and sets the
749 ******************************************************************************/
750 static void load_level(struct game_context
* pb
) {
753 for(r
= 0; r
< ROWS
; r
++)
754 for(c
= 0; c
< COLS
; c
++)
755 pb
->playboard
[r
][c
] = levels
[pb
->level
-1][r
][c
];
758 /*****************************************************************************
759 * new_piece() creates a new piece at a specified location. The player
760 * navigates through the pieces and selects one.
761 ******************************************************************************/
762 static void new_piece(struct game_context
* pb
, unsigned int x_loc
,
763 unsigned int y_loc
) {
767 pb
->playboard
[x_loc
][y_loc
] = TRIANGLE
;
771 button
= rb
->button_get(true);
773 if(button
& BUTTON_TOUCHPAD
)
775 pegbox_raster_btn
.two_d_from
.y
= x_loc
;
776 pegbox_raster_btn
.two_d_from
.x
= y_loc
;
778 struct ts_raster_button_result ret
= touchscreen_raster_map_button(&pegbox_raster_btn
, rb
->button_get_data() >> 16, rb
->button_get_data() & 0xffff, button
);
779 if(ret
.action
== TS_ACTION_TWO_D_MOVEMENT
)
781 if(ret
.to
.x
> ret
.from
.x
)
783 else if(ret
.to
.x
< ret
.from
.x
)
784 button
= PEGBOX_DOWN
;
785 else if(ret
.to
.y
> ret
.from
.y
)
786 button
= PEGBOX_LEFT
;
787 else if(ret
.to
.y
< ret
.from
.y
)
788 button
= PEGBOX_RIGHT
;
790 else if(ret
.action
== TS_ACTION_CLICK
&& (unsigned)ret
.to
.x
== y_loc
&& (unsigned)ret
.to
.y
== x_loc
)
791 button
= PEGBOX_SAVE
;
796 case (PEGBOX_LEFT
|BUTTON_REPEAT
):
798 case (PEGBOX_DOWN
|BUTTON_REPEAT
):
799 if (pb
->playboard
[x_loc
][y_loc
] < 5)
800 pb
->playboard
[x_loc
][y_loc
]++;
802 pb
->playboard
[x_loc
][y_loc
] = TRIANGLE
;
805 case (PEGBOX_RIGHT
|BUTTON_REPEAT
):
807 case (PEGBOX_UP
|BUTTON_REPEAT
):
808 if (pb
->playboard
[x_loc
][y_loc
] > 2)
809 pb
->playboard
[x_loc
][y_loc
]--;
811 pb
->playboard
[x_loc
][y_loc
] = CIRCLE
;
820 /*****************************************************************************
821 * move_player() moves the player and pieces and updates the board accordingly.
822 ******************************************************************************/
823 static void move_player(struct game_context
* pb
, signed int x_dir
,
825 unsigned int type1
, type2
;
828 r
= pb
->player_row
+y_dir
;
829 c
= pb
->player_col
+x_dir
;
831 type1
= pb
->playboard
[r
][c
];
832 type2
= pb
->playboard
[r
+y_dir
][c
+x_dir
];
834 if (r
== ROWS
|| c
== COLS
|| r
< 0 || c
< 0 || type1
== WALL
)
836 else if(type1
!= SPACE
) {
837 if (type2
== WALL
|| r
+y_dir
== ROWS
|| c
+x_dir
== COLS
||
838 r
+y_dir
< 0 || c
+x_dir
< 0)
843 pb
->playboard
[pb
->player_row
][pb
->player_col
] = SPACE
;
844 pb
->player_row
+= y_dir
;
845 pb
->player_col
+= x_dir
;
849 rb
->splash(HZ
*2, "You fell down a hole!");
852 else if (type1
== SPACE
)
853 pb
->playboard
[r
][c
] = PLAYER
;
855 pb
->playboard
[r
][c
] = PLAYER
;
857 if (type1
== TRIANGLE
)
858 pb
->playboard
[r
+y_dir
][c
+x_dir
] = WALL
;
859 else if (type1
== CROSS
) {
860 pb
->playboard
[r
][c
] = SPACE
;
861 new_piece(pb
, r
+y_dir
, c
+x_dir
);
862 pb
->playboard
[r
][c
] = PLAYER
;
865 pb
->playboard
[r
+y_dir
][c
+x_dir
] = SPACE
;
867 else if (type2
== SPACE
)
868 pb
->playboard
[r
+y_dir
][c
+x_dir
] = type1
;
869 else if (type2
== HOLE
) {
871 pb
->playboard
[r
+y_dir
][c
+x_dir
] = SPACE
;
874 rb
->splash(HZ
*2, "Illegal Move!");
882 /*****************************************************************************
883 * pegbox_loadgame() loads the saved game and returns load success.
884 ******************************************************************************/
885 static bool pegbox_loadgame(struct game_context
* pb
) {
890 fd
= rb
->open(SAVE_FILE
, O_RDONLY
);
891 if(fd
< 0) return loaded
;
893 /* read in saved game */
895 if(rb
->read(fd
, &pb
->level
, sizeof(pb
->level
)) <= 0) break;
896 if(rb
->read(fd
, &pb
->playboard
, sizeof(pb
->playboard
)) <= 0)
908 /*****************************************************************************
909 * pegbox_savegame() saves the current game state.
910 ******************************************************************************/
911 static void pegbox_savegame(struct game_context
* pb
) {
914 /* write out the game state to the save file */
915 fd
= rb
->open(SAVE_FILE
, O_WRONLY
|O_CREAT
);
916 rb
->write(fd
, &pb
->level
, sizeof(pb
->level
));
917 rb
->write(fd
, &pb
->playboard
, sizeof(pb
->playboard
));
921 /*****************************************************************************
922 * pegbox_loaddata() loads the level and highlevel and returns load success.
923 ******************************************************************************/
924 static void pegbox_loaddata(struct game_context
* pb
) {
928 fd
= rb
->open(DATA_FILE
, O_RDONLY
);
935 /* read in saved game */
937 if(rb
->read(fd
, &pb
->level
, sizeof(pb
->level
)) <= 0) break;
938 if(rb
->read(fd
, &pb
->highlevel
, sizeof(pb
->highlevel
)) <= 0) break;
946 /*****************************************************************************
947 * pegbox_savedata() saves the level and highlevel.
948 ******************************************************************************/
949 static void pegbox_savedata(struct game_context
* pb
) {
952 /* write out the game state to the save file */
953 fd
= rb
->open(DATA_FILE
, O_WRONLY
|O_CREAT
);
954 rb
->write(fd
, &pb
->level
, sizeof(pb
->level
));
955 rb
->write(fd
, &pb
->highlevel
, sizeof(pb
->highlevel
));
959 /*****************************************************************************
960 * pegbox_callback() is the default event handler callback which is called
961 * on usb connect and shutdown.
962 ******************************************************************************/
963 static void pegbox_callback(void* param
) {
964 struct game_context
* pb
= (struct game_context
*) param
;
965 rb
->splash(HZ
, "Saving data...");
969 /*****************************************************************************
970 * pegbox_menu() is the initial menu at the start of the game.
971 ******************************************************************************/
972 static unsigned int pegbox_menu(struct game_context
* pb
) {
975 unsigned int startlevel
= 1, loc
= 0;
976 bool breakout
= false, can_resume
= false;
978 if (pb
->num_left
> 0 || pb
->save_exist
)
982 #if (LCD_WIDTH >= 138) && (LCD_HEIGHT >= 110)
983 rb
->lcd_clear_display();
984 rb
->lcd_bitmap(pegbox_menu_top
,0,0,LCD_WIDTH
, BMPHEIGHT_pegbox_menu_top
);
988 rb
->lcd_bitmap_part(pegbox_menu_items
, 0,
989 (BMPHEIGHT_pegbox_menu_items
/9),
990 BMPWIDTH_pegbox_menu_items
,
991 (LCD_WIDTH
-BMPWIDTH_pegbox_menu_items
)/2,
992 BMPHEIGHT_pegbox_menu_top
,
993 BMPWIDTH_pegbox_menu_items
,
994 (BMPHEIGHT_pegbox_menu_items
/9));
997 rb
->lcd_bitmap_part(pegbox_menu_items
, 0, 0,
998 BMPWIDTH_pegbox_menu_items
,
999 (LCD_WIDTH
-BMPWIDTH_pegbox_menu_items
)/2,
1000 BMPHEIGHT_pegbox_menu_top
,
1001 BMPWIDTH_pegbox_menu_items
,
1002 (BMPHEIGHT_pegbox_menu_items
/9));
1006 rb
->lcd_bitmap_part(pegbox_menu_items
, 0,
1007 (BMPHEIGHT_pegbox_menu_items
/9)*3,
1008 BMPWIDTH_pegbox_menu_items
,
1009 (LCD_WIDTH
-BMPWIDTH_pegbox_menu_items
)/2,
1010 BMPHEIGHT_pegbox_menu_top
+
1011 (BMPHEIGHT_pegbox_menu_items
/9),
1012 BMPWIDTH_pegbox_menu_items
,
1013 (BMPHEIGHT_pegbox_menu_items
/9));
1016 rb
->lcd_bitmap_part(pegbox_menu_items
, 0,
1017 (BMPHEIGHT_pegbox_menu_items
/9)*2,
1018 BMPWIDTH_pegbox_menu_items
,
1019 (LCD_WIDTH
-BMPWIDTH_pegbox_menu_items
)/2,
1020 BMPHEIGHT_pegbox_menu_top
+
1021 (BMPHEIGHT_pegbox_menu_items
/9),
1022 BMPWIDTH_pegbox_menu_items
,
1023 (BMPHEIGHT_pegbox_menu_items
/9));
1027 rb
->lcd_bitmap_part(pegbox_menu_items
, 0,
1028 (BMPHEIGHT_pegbox_menu_items
/9)*4,
1029 BMPWIDTH_pegbox_menu_items
,
1030 (LCD_WIDTH
-BMPWIDTH_pegbox_menu_items
)/2,
1031 BMPHEIGHT_pegbox_menu_top
+
1032 (BMPHEIGHT_pegbox_menu_items
/9),
1033 BMPWIDTH_pegbox_menu_items
,
1034 (BMPHEIGHT_pegbox_menu_items
/9));
1038 rb
->lcd_bitmap_part(pegbox_menu_items
, 0,
1039 (BMPHEIGHT_pegbox_menu_items
/9)*6,
1040 BMPWIDTH_pegbox_menu_items
,
1041 (LCD_WIDTH
-BMPWIDTH_pegbox_menu_items
)/2,
1042 BMPHEIGHT_pegbox_menu_top
+
1043 (BMPHEIGHT_pegbox_menu_items
/9)*2,
1044 BMPWIDTH_pegbox_menu_items
,
1045 (BMPHEIGHT_pegbox_menu_items
/9));
1048 rb
->lcd_bitmap_part(pegbox_menu_items
, 0,
1049 (BMPHEIGHT_pegbox_menu_items
/9)*5,
1050 BMPWIDTH_pegbox_menu_items
,
1051 (LCD_WIDTH
-BMPWIDTH_pegbox_menu_items
)/2,
1052 BMPHEIGHT_pegbox_menu_top
+
1053 (BMPHEIGHT_pegbox_menu_items
/9)*2,
1054 BMPWIDTH_pegbox_menu_items
,
1055 (BMPHEIGHT_pegbox_menu_items
/9));
1059 rb
->lcd_bitmap_part(pegbox_menu_items
, 0,
1060 (BMPHEIGHT_pegbox_menu_items
/9)*8,
1061 BMPWIDTH_pegbox_menu_items
,
1062 (LCD_WIDTH
-BMPWIDTH_pegbox_menu_items
)/2,
1063 BMPHEIGHT_pegbox_menu_top
+
1064 (BMPHEIGHT_pegbox_menu_items
/9)*3,
1065 BMPWIDTH_pegbox_menu_items
,
1066 (BMPHEIGHT_pegbox_menu_items
/9));
1069 rb
->lcd_bitmap_part(pegbox_menu_items
, 0,
1070 (BMPHEIGHT_pegbox_menu_items
/9)*7,
1071 BMPWIDTH_pegbox_menu_items
,
1072 (LCD_WIDTH
-BMPWIDTH_pegbox_menu_items
)/2,
1073 BMPHEIGHT_pegbox_menu_top
+
1074 (BMPHEIGHT_pegbox_menu_items
/9)*3,
1075 BMPWIDTH_pegbox_menu_items
,
1076 (BMPHEIGHT_pegbox_menu_items
/9));
1080 rb
->lcd_clear_display();
1081 rb
->lcd_getstringsize("PegBox", &w
, &h
);
1082 rb
->lcd_putsxy((LCD_WIDTH
-w
)/2, 0, "PegBox");
1083 rb
->lcd_putsxy((LCD_WIDTH
)/4, 16, "New Game");
1084 rb
->lcd_putsxy((LCD_WIDTH
)/4, 24, "Resume");
1085 rb
->lcd_putsxy((LCD_WIDTH
)/4, 32, "Help");
1086 rb
->lcd_putsxy((LCD_WIDTH
)/4, 40, "Quit");
1089 rb
->lcd_hline((LCD_WIDTH
)/4, (LCD_WIDTH
)/4+30, 28);
1091 rb
->lcd_putsxy((LCD_WIDTH
)/4-8, loc
*8+16, "*");
1095 rb
->snprintf(str
, 28, "Start on level %d of %d", startlevel
,
1097 #if (LCD_WIDTH >= 138) && (LCD_HEIGHT >= 110)
1098 rb
->lcd_putsxy(0, BMPHEIGHT_pegbox_menu_top
+4*
1099 (BMPHEIGHT_pegbox_menu_items
/9)+8, str
);
1100 #elif LCD_WIDTH > 112
1101 rb
->lcd_putsxy(0, LCD_HEIGHT
- 8, str
);
1103 rb
->lcd_puts_scroll(0, 7, str
);
1107 /* handle menu button presses */
1108 button
= rb
->button_get(true);
1110 #ifdef HAVE_TOUCHPAD
1111 if(button
& BUTTON_TOUCHPAD
)
1113 unsigned int result
= touchscreen_map(&main_menu
, rb
->button_get_data() >> 16, rb
->button_get_data() & 0xffff);
1114 if(result
!= (unsigned)-1 && button
& BUTTON_REL
)
1117 button
= PEGBOX_LVL_UP
;
1121 button
= PEGBOX_RIGHT
;
1129 case PEGBOX_SAVE
: /* start playing */
1133 pb
->level
= startlevel
;
1136 else if (loc
== 1 && can_resume
) {
1139 rb
->remove(SAVE_FILE
);
1140 pb
->save_exist
= false;
1145 display_text("How to Play\nTo beat each level, you must "
1146 "destroy all of the pegs. If two like pegs are "
1147 "pushed into each other they disappear except "
1148 "for triangles which form a solid block and "
1149 "crosses which allow you to choose a "
1150 "replacement block.\n\n"
1153 RESTART_TEXT
" to restart level\n"
1154 LVL_UP_TEXT
" to go up a level\n"
1155 LVL_DOWN_TEXT
" to go down a level\n"
1156 SAVE_TEXT
" to select/save\n"
1157 QUIT_TEXT
" to quit\n",true);
1159 RESTART_TEXT
": restart\n"
1160 LVL_UP_TEXT
": level up\n"
1161 LVL_DOWN_TEXT
" level down\n"
1162 SAVE_TEXT
" select/save\n"
1163 QUIT_TEXT
" quit\n",true);
1169 case PEGBOX_QUIT
: /* quit program */
1172 case (PEGBOX_UP
|BUTTON_REPEAT
):
1178 if (!can_resume
&& loc
== 1) {
1184 case (PEGBOX_DOWN
|BUTTON_REPEAT
):
1190 if (!can_resume
&& loc
== 1) {
1195 case (PEGBOX_LVL_UP
|BUTTON_REPEAT
):
1196 case PEGBOX_LVL_UP
: /* increase starting level */
1197 if(startlevel
>= pb
->highlevel
) {
1204 /* only for targets with enough buttons */
1205 #ifdef PEGBOX_LVL_DOWN
1206 case (PEGBOX_LVL_DOWN
|BUTTON_REPEAT
):
1207 case PEGBOX_LVL_DOWN
: /* decrease starting level */
1208 if(startlevel
<= 1) {
1209 startlevel
= pb
->highlevel
;
1216 if(rb
->default_event_handler_ex(button
, pegbox_callback
,
1217 (void*) pb
) == SYS_USB_CONNECTED
)
1228 /*****************************************************************************
1229 * pegbox() is the main game subroutine, it returns the final game status.
1230 ******************************************************************************/
1231 static int pegbox(struct game_context
* pb
) {
1234 /********************
1236 ********************/
1237 temp_var
= pegbox_menu(pb
);
1238 if (temp_var
== PB_QUIT
|| temp_var
== PB_USB
)
1242 temp_var
= rb
->button_get(true);
1243 #ifdef HAVE_TOUCHPAD
1244 if(temp_var
& BUTTON_TOUCHPAD
)
1246 pegbox_raster_btn
.two_d_from
.y
= pb
->player_row
;
1247 pegbox_raster_btn
.two_d_from
.x
= pb
->player_col
;
1249 struct ts_raster_button_result ret
= touchscreen_raster_map_button(&pegbox_raster_btn
, rb
->button_get_data() >> 16, rb
->button_get_data() & 0xffff, temp_var
);
1250 if(ret
.action
== TS_ACTION_TWO_D_MOVEMENT
)
1251 move_player(pb
, ret
.to
.x
- ret
.from
.x
, ret
.to
.y
- ret
.from
.y
);
1255 case PEGBOX_LEFT
: /* move cursor left */
1256 case (PEGBOX_LEFT
|BUTTON_REPEAT
):
1257 move_player(pb
, -1, 0);
1260 case PEGBOX_RIGHT
: /* move cursor right */
1261 case (PEGBOX_RIGHT
|BUTTON_REPEAT
):
1262 move_player(pb
, 1, 0);
1265 case PEGBOX_DOWN
: /* move cursor down */
1266 case (PEGBOX_DOWN
|BUTTON_REPEAT
):
1267 move_player(pb
, 0, 1);
1270 case PEGBOX_UP
: /* move cursor up */
1271 case (PEGBOX_UP
|BUTTON_REPEAT
):
1272 move_player(pb
, 0, -1);
1275 case PEGBOX_SAVE
: /* save and end game */
1276 rb
->splash(HZ
, "Saving game...");
1277 pegbox_savegame(pb
);
1278 /* fall through to PEGBOX_QUIT */
1283 case PEGBOX_RESTART
:
1288 case (PEGBOX_LVL_UP
|BUTTON_REPEAT
):
1290 if(pb
->level
>= pb
->highlevel
) {
1299 /* only for targets with enough buttons */
1300 #ifdef PEGBOX_LVL_DOWN
1301 case (PEGBOX_LVL_DOWN
|BUTTON_REPEAT
):
1302 case PEGBOX_LVL_DOWN
:
1303 if(pb
->level
<= 1) {
1304 pb
->level
= pb
->highlevel
;
1315 if(pb
->num_left
== 0) {
1316 rb
->splash(HZ
*2, "Nice Pegging!");
1317 if(pb
->level
== NUM_LEVELS
) {
1319 rb
->splash(HZ
*2, "You Won!");
1328 if(pb
->level
> pb
->highlevel
)
1329 pb
->highlevel
= pb
->level
;
1338 /*****************************************************************************
1339 * plugin entry point.
1340 ******************************************************************************/
1341 enum plugin_status
plugin_start(const struct plugin_api
* api
, const void* parameter
) {
1343 struct game_context pb
;
1348 rb
->lcd_setfont(FONT_SYSFIXED
);
1350 rb
->lcd_set_backdrop(NULL
);
1352 #ifdef HAVE_LCD_COLOR
1353 rb
->lcd_set_foreground(LCD_WHITE
);
1354 rb
->lcd_set_background(BG_COLOR
);
1357 rb
->splash(0, "Loading...");
1358 pegbox_loaddata(&pb
);
1359 pb
.save_exist
= pegbox_loadgame(&pb
);
1362 rb
->lcd_clear_display();
1366 switch(pegbox(&pb
)){
1371 rb
->lcd_setfont(FONT_UI
);
1372 return PLUGIN_USB_CONNECTED
;
1375 rb
->splash(HZ
, "Saving data...");
1376 pegbox_savedata(&pb
);
1385 rb
->lcd_setfont(FONT_UI
);