1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2005 Adam Boot
12 * Color graphics from Gweled (http://sebdelestaing.free.fr/gweled/)
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
22 ****************************************************************************/
25 #include "lib/playback_control.h"
27 #ifdef HAVE_LCD_BITMAP
31 /* button definitions */
32 #if CONFIG_KEYPAD == RECORDER_PAD
33 #define JEWELS_UP BUTTON_UP
34 #define JEWELS_DOWN BUTTON_DOWN
35 #define JEWELS_LEFT BUTTON_LEFT
36 #define JEWELS_RIGHT BUTTON_RIGHT
37 #define JEWELS_SELECT BUTTON_PLAY
38 #define JEWELS_CANCEL BUTTON_OFF
40 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
41 #define JEWELS_UP BUTTON_UP
42 #define JEWELS_DOWN BUTTON_DOWN
43 #define JEWELS_LEFT BUTTON_LEFT
44 #define JEWELS_RIGHT BUTTON_RIGHT
45 #define JEWELS_SELECT BUTTON_SELECT
46 #define JEWELS_CANCEL BUTTON_OFF
48 #elif CONFIG_KEYPAD == ONDIO_PAD
49 #define JEWELS_UP BUTTON_UP
50 #define JEWELS_DOWN BUTTON_DOWN
51 #define JEWELS_LEFT BUTTON_LEFT
52 #define JEWELS_RIGHT BUTTON_RIGHT
53 #define JEWELS_SELECT BUTTON_MENU
54 #define JEWELS_CANCEL BUTTON_OFF
56 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
57 #define JEWELS_UP BUTTON_UP
58 #define JEWELS_DOWN BUTTON_DOWN
59 #define JEWELS_LEFT BUTTON_LEFT
60 #define JEWELS_RIGHT BUTTON_RIGHT
61 #define JEWELS_SELECT BUTTON_SELECT
62 #define JEWELS_CANCEL BUTTON_OFF
63 #define JEWELS_RC_CANCEL BUTTON_RC_STOP
65 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
66 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
67 #define JEWELS_SCROLLWHEEL
68 #define JEWELS_UP BUTTON_MENU
69 #define JEWELS_DOWN BUTTON_PLAY
70 #define JEWELS_LEFT BUTTON_LEFT
71 #define JEWELS_RIGHT BUTTON_RIGHT
72 #define JEWELS_PREV BUTTON_SCROLL_BACK
73 #define JEWELS_NEXT BUTTON_SCROLL_FWD
74 #define JEWELS_SELECT BUTTON_SELECT
76 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
77 #define JEWELS_UP BUTTON_UP
78 #define JEWELS_DOWN BUTTON_DOWN
79 #define JEWELS_LEFT BUTTON_LEFT
80 #define JEWELS_RIGHT BUTTON_RIGHT
81 #define JEWELS_SELECT BUTTON_SELECT
82 #define JEWELS_CANCEL BUTTON_PLAY
84 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
85 #define JEWELS_UP BUTTON_UP
86 #define JEWELS_DOWN BUTTON_DOWN
87 #define JEWELS_LEFT BUTTON_LEFT
88 #define JEWELS_RIGHT BUTTON_RIGHT
89 #define JEWELS_SELECT BUTTON_SELECT
90 #define JEWELS_CANCEL BUTTON_POWER
92 #elif CONFIG_KEYPAD == GIGABEAT_PAD
93 #define JEWELS_UP BUTTON_UP
94 #define JEWELS_DOWN BUTTON_DOWN
95 #define JEWELS_LEFT BUTTON_LEFT
96 #define JEWELS_RIGHT BUTTON_RIGHT
97 #define JEWELS_SELECT BUTTON_SELECT
98 #define JEWELS_CANCEL BUTTON_POWER
100 #elif CONFIG_KEYPAD == SANSA_E200_PAD || \
101 (CONFIG_KEYPAD == SANSA_FUZE_PAD)
102 #define JEWELS_SCROLLWHEEL
103 #define JEWELS_UP BUTTON_UP
104 #define JEWELS_DOWN BUTTON_DOWN
105 #define JEWELS_LEFT BUTTON_LEFT
106 #define JEWELS_RIGHT BUTTON_RIGHT
107 #define JEWELS_PREV BUTTON_SCROLL_BACK
108 #define JEWELS_NEXT BUTTON_SCROLL_FWD
109 #define JEWELS_SELECT BUTTON_SELECT
110 #define JEWELS_CANCEL BUTTON_POWER
112 #elif CONFIG_KEYPAD == SANSA_C200_PAD || \
113 CONFIG_KEYPAD == SANSA_CLIP_PAD || \
114 CONFIG_KEYPAD == SANSA_M200_PAD
115 #define JEWELS_UP BUTTON_UP
116 #define JEWELS_DOWN BUTTON_DOWN
117 #define JEWELS_LEFT BUTTON_LEFT
118 #define JEWELS_RIGHT BUTTON_RIGHT
119 #define JEWELS_SELECT BUTTON_SELECT
120 #define JEWELS_CANCEL BUTTON_POWER
122 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
123 #define JEWELS_UP BUTTON_SCROLL_UP
124 #define JEWELS_DOWN BUTTON_SCROLL_DOWN
125 #define JEWELS_LEFT BUTTON_LEFT
126 #define JEWELS_RIGHT BUTTON_RIGHT
127 #define JEWELS_SELECT BUTTON_PLAY
128 #define JEWELS_CANCEL BUTTON_POWER
130 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
131 #define JEWELS_UP BUTTON_UP
132 #define JEWELS_DOWN BUTTON_DOWN
133 #define JEWELS_LEFT BUTTON_LEFT
134 #define JEWELS_RIGHT BUTTON_RIGHT
135 #define JEWELS_SELECT BUTTON_SELECT
136 #define JEWELS_CANCEL BUTTON_BACK
138 #elif CONFIG_KEYPAD == MROBE100_PAD
139 #define JEWELS_UP BUTTON_UP
140 #define JEWELS_DOWN BUTTON_DOWN
141 #define JEWELS_LEFT BUTTON_LEFT
142 #define JEWELS_RIGHT BUTTON_RIGHT
143 #define JEWELS_SELECT BUTTON_SELECT
144 #define JEWELS_CANCEL BUTTON_POWER
146 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
147 #define JEWELS_UP BUTTON_RC_VOL_UP
148 #define JEWELS_DOWN BUTTON_RC_VOL_DOWN
149 #define JEWELS_LEFT BUTTON_RC_REW
150 #define JEWELS_RIGHT BUTTON_RC_FF
151 #define JEWELS_SELECT BUTTON_RC_PLAY
152 #define JEWELS_CANCEL BUTTON_RC_REC
154 #define JEWELS_RC_CANCEL BUTTON_REC
156 #elif CONFIG_KEYPAD == COWOND2_PAD
157 #define JEWELS_CANCEL BUTTON_POWER
159 #elif CONFIG_KEYPAD == IAUDIO67_PAD
160 #define JEWELS_UP BUTTON_STOP
161 #define JEWELS_DOWN BUTTON_PLAY
162 #define JEWELS_LEFT BUTTON_LEFT
163 #define JEWELS_RIGHT BUTTON_RIGHT
164 #define JEWELS_SELECT BUTTON_MENU
165 #define JEWELS_CANCEL BUTTON_POWER
167 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
168 #define JEWELS_UP BUTTON_UP
169 #define JEWELS_DOWN BUTTON_DOWN
170 #define JEWELS_LEFT BUTTON_LEFT
171 #define JEWELS_RIGHT BUTTON_RIGHT
172 #define JEWELS_SELECT BUTTON_SELECT
173 #define JEWELS_CANCEL BUTTON_BACK
175 #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
176 #define JEWELS_UP BUTTON_UP
177 #define JEWELS_DOWN BUTTON_DOWN
178 #define JEWELS_LEFT BUTTON_LEFT
179 #define JEWELS_RIGHT BUTTON_RIGHT
180 #define JEWELS_SELECT BUTTON_SELECT
181 #define JEWELS_CANCEL BUTTON_POWER
184 #error No keymap defined!
187 #ifdef HAVE_TOUCHSCREEN
189 #define JEWELS_UP BUTTON_TOPMIDDLE
192 #define JEWELS_DOWN BUTTON_BOTTOMMIDDLE
195 #define JEWELS_LEFT BUTTON_MIDLEFT
198 #define JEWELS_RIGHT BUTTON_MIDRIGHT
200 #ifndef JEWELS_SELECT
201 #define JEWELS_SELECT BUTTON_CENTER
203 #ifndef JEWELS_CANCEL
204 #define JEWELS_CANCEL BUTTON_TOPLEFT
208 /* use 30x30 tiles (iPod Video, Gigabeat) */
209 #if (LCD_HEIGHT == 240) && (LCD_WIDTH == 320) || \
210 ((LCD_HEIGHT == 320) && (LCD_WIDTH == 240))
211 #define TILE_WIDTH 30
212 #define TILE_HEIGHT 30
214 #define NUM_SCORES 10
216 /* use 22x22 tiles (H300, iPod Color) */
217 #elif ((LCD_HEIGHT == 176) && (LCD_WIDTH == 220)) || \
218 ((LCD_HEIGHT == 220) && (LCD_WIDTH == 176))
219 #define TILE_WIDTH 22
220 #define TILE_HEIGHT 22
222 #define NUM_SCORES 10
224 /* use 16x16 tiles (iPod Nano) */
225 #elif (LCD_HEIGHT == 132) && (LCD_WIDTH == 176)
226 #define TILE_WIDTH 16
227 #define TILE_HEIGHT 16
229 #define NUM_SCORES 10
231 /* use 16x16 tiles (H100, iAudio X5, iPod 3G, iPod 4G grayscale) */
232 #elif (LCD_HEIGHT == 128) && (LCD_WIDTH == 160)
233 #define TILE_WIDTH 16
234 #define TILE_HEIGHT 16
236 #define NUM_SCORES 10
238 /* use 14x14 tiles (H10 5/6 GB) */
239 #elif (LCD_HEIGHT == 128) && (LCD_WIDTH == 128)
240 #define TILE_WIDTH 14
241 #define TILE_HEIGHT 14
243 #define NUM_SCORES 10
245 /* use 13x13 tiles (iPod Mini) */
246 #elif (LCD_HEIGHT == 110) && (LCD_WIDTH == 138)
247 #define TILE_WIDTH 13
248 #define TILE_HEIGHT 13
250 #define NUM_SCORES 10
252 /* use 12x12 tiles (iAudio M3) */
253 #elif (LCD_HEIGHT == 96) && (LCD_WIDTH == 128)
254 #define TILE_WIDTH 12
255 #define TILE_HEIGHT 12
259 /* use 10x10 tiles (Sansa c200) */
260 #elif (LCD_HEIGHT == 80) && (LCD_WIDTH == 132)
261 #define TILE_WIDTH 10
262 #define TILE_HEIGHT 10
266 /* use 10x8 tiles (iFP 700) */
267 #elif (LCD_HEIGHT == 64) && (LCD_WIDTH == 128)
268 #define TILE_WIDTH 10
269 #define TILE_HEIGHT 8
273 /* use 10x8 tiles (Recorder, Ondio) */
274 #elif (LCD_HEIGHT == 64) && (LCD_WIDTH == 112)
275 #define TILE_WIDTH 10
276 #define TILE_HEIGHT 8
281 #error JEWELS: Unsupported LCD
285 #define SCORE_FILE PLUGIN_GAMES_DIR "/jewels.score"
286 #define SAVE_FILE PLUGIN_GAMES_DIR "/jewels.save"
288 /* final game return status */
289 #define BJ_QUIT_FROM_GAME 4
295 /* swap directions */
301 /* play board dimension */
305 /* next level threshold */
306 #define LEVEL_PTS 100
308 /* animation frame rate */
318 #define FONT_HEIGHT 8
320 #define MENU_WIDTH 100
350 struct jewels_menuitem
{
352 enum menu_result res
;
355 {"Jewels", false, 0, 6,
356 {{"New Game", MRES_NEW
},
357 {"Puzzle", MRES_PUZZLE
},
358 {"Resume Game", MRES_RESUME
},
359 {"High Scores", MRES_SCORES
},
361 {"Quit", MRES_QUIT
}}},
363 {{"Audio Playback", MRES_PLAYBACK
},
364 {"Resume Game", MRES_RESUME
},
365 {"Save Game", MRES_SAVE
},
366 {"End Game", MRES_QUIT
},
367 {"Exit Jewels", MRES_EXIT
}}}
370 /* external bitmaps */
371 extern const fb_data jewels
[];
373 /* tile background colors */
374 #ifdef HAVE_LCD_COLOR
375 static const unsigned jewels_bkgd
[2] = {
376 LCD_RGBPACK(104, 63, 63),
377 LCD_RGBPACK(83, 44, 44)
382 * type is the jewel number 0-7
383 * falling if the jewel is falling
384 * delete marks the jewel for deletion
392 /* the game context struct
393 * score is the current level score
394 * segments is the number of cleared segments in the current run
395 * level is the current level
396 * type is the game type (normal or puzzle)
397 * highscores is the list of high scores
398 * resume denotes whether to resume the currently loaded game
399 * dirty denotes whether the high scores are out of sync with the saved file
400 * playboard is the game playing board (first row is hidden)
401 * num_jewels is the number of different jewels to use
403 struct game_context
{
405 unsigned int segments
;
408 unsigned int highscores
[NUM_SCORES
];
411 struct tile playboard
[BJ_HEIGHT
][BJ_WIDTH
];
412 unsigned int num_jewels
;
415 #define MAX_NUM_JEWELS 7
417 #define MAX_PUZZLE_TILES 4
418 #define NUM_PUZZLE_LEVELS 10
426 struct puzzle_level
{
427 unsigned int num_jewels
;
428 unsigned int num_tiles
;
429 struct puzzle_tile tiles
[MAX_PUZZLE_TILES
];
432 #define PUZZLE_TILE_UP 1
433 #define PUZZLE_TILE_DOWN 2
434 #define PUZZLE_TILE_LEFT 4
435 #define PUZZLE_TILE_RIGHT 8
437 struct puzzle_level puzzle_levels
[NUM_PUZZLE_LEVELS
] = {
438 { 5, 2, { {3, 3, PUZZLE_TILE_RIGHT
},
439 {4, 2, PUZZLE_TILE_LEFT
} } },
440 { 5, 2, { {3, 2, PUZZLE_TILE_DOWN
},
441 {3, 4, PUZZLE_TILE_UP
} } },
442 { 6, 3, { {3, 2, PUZZLE_TILE_DOWN
},
443 {3, 4, PUZZLE_TILE_UP
|PUZZLE_TILE_DOWN
},
444 {3, 6, PUZZLE_TILE_UP
} } },
445 { 6, 3, { {3, 2, PUZZLE_TILE_RIGHT
},
446 {4, 3, PUZZLE_TILE_LEFT
|PUZZLE_TILE_RIGHT
},
447 {5, 4, PUZZLE_TILE_LEFT
} } },
448 { 6, 2, { {3, 4, PUZZLE_TILE_RIGHT
},
449 {4, 2, PUZZLE_TILE_LEFT
} } },
450 { 6, 2, { {3, 2, PUZZLE_TILE_DOWN
},
451 {4, 4, PUZZLE_TILE_UP
} } },
452 { 7, 4, { {3, 2, PUZZLE_TILE_RIGHT
|PUZZLE_TILE_DOWN
},
453 {4, 3, PUZZLE_TILE_LEFT
|PUZZLE_TILE_DOWN
},
454 {3, 4, PUZZLE_TILE_RIGHT
|PUZZLE_TILE_UP
},
455 {4, 4, PUZZLE_TILE_LEFT
|PUZZLE_TILE_UP
} } },
456 { 6, 3, { {3, 2, PUZZLE_TILE_DOWN
},
457 {4, 4, PUZZLE_TILE_UP
|PUZZLE_TILE_DOWN
},
458 {3, 6, PUZZLE_TILE_UP
} } },
459 { 7, 3, { {2, 2, PUZZLE_TILE_RIGHT
},
460 {4, 1, PUZZLE_TILE_LEFT
|PUZZLE_TILE_RIGHT
},
461 {5, 4, PUZZLE_TILE_LEFT
} } },
462 { 7, 4, { {3, 0, PUZZLE_TILE_RIGHT
|PUZZLE_TILE_DOWN
},
463 {5, 0, PUZZLE_TILE_LEFT
|PUZZLE_TILE_DOWN
},
464 {2, 7, PUZZLE_TILE_RIGHT
|PUZZLE_TILE_UP
},
465 {4, 7, PUZZLE_TILE_LEFT
|PUZZLE_TILE_UP
} } },
468 /*****************************************************************************
469 * jewels_init() initializes jewels data structures.
470 ******************************************************************************/
471 static void jewels_init(struct game_context
* bj
) {
472 /* seed the rand generator */
473 rb
->srand(*rb
->current_tick
);
475 /* check for resumed game */
486 /* clear playing board */
487 rb
->memset(bj
->playboard
, 0, sizeof(bj
->playboard
));
490 /*****************************************************************************
491 * jewels_setcolors() set the foreground and background colors.
492 ******************************************************************************/
493 static inline void jewels_setcolors(void) {
494 #ifdef HAVE_LCD_COLOR
495 rb
->lcd_set_background(LCD_RGBPACK(49, 26, 26));
496 rb
->lcd_set_foreground(LCD_RGBPACK(210, 181, 181));
500 /*****************************************************************************
501 * jewels_drawboard() redraws the entire game board.
502 ******************************************************************************/
503 static void jewels_drawboard(struct game_context
* bj
) {
506 unsigned int tempscore
;
507 char *title
= "Level";
510 tempscore
= (bj
->score
>LEVEL_PTS
? LEVEL_PTS
: bj
->score
);
513 rb
->lcd_clear_display();
515 /* dispay playing board */
516 for(i
=0; i
<BJ_HEIGHT
-1; i
++){
517 for(j
=0; j
<BJ_WIDTH
; j
++){
518 #ifdef HAVE_LCD_COLOR
519 rb
->lcd_set_foreground(jewels_bkgd
[(i
+j
)%2]);
520 rb
->lcd_fillrect(j
*TILE_WIDTH
, i
*TILE_HEIGHT
+YOFS
,
521 TILE_WIDTH
, TILE_HEIGHT
);
522 rb
->lcd_bitmap_transparent_part(jewels
,
523 0, TILE_HEIGHT
*(bj
->playboard
[i
+1][j
].type
),
524 TILE_WIDTH
, j
*TILE_WIDTH
, i
*TILE_HEIGHT
+YOFS
,
525 TILE_WIDTH
, TILE_HEIGHT
);
527 rb
->lcd_bitmap_part(jewels
,
528 0, TILE_HEIGHT
*(bj
->playboard
[i
+1][j
].type
),
529 TILE_WIDTH
, j
*TILE_WIDTH
, i
*TILE_HEIGHT
+YOFS
,
530 TILE_WIDTH
, TILE_HEIGHT
);
535 #if LCD_WIDTH > LCD_HEIGHT /* horizontal layout */
537 /* draw separator lines */
539 rb
->lcd_vline(BJ_WIDTH
*TILE_WIDTH
, 0, LCD_HEIGHT
-1);
540 rb
->lcd_hline(BJ_WIDTH
*TILE_WIDTH
, LCD_WIDTH
-1, 18);
541 rb
->lcd_hline(BJ_WIDTH
*TILE_WIDTH
, LCD_WIDTH
-1, LCD_HEIGHT
-10);
543 /* draw progress bar */
544 #ifdef HAVE_LCD_COLOR
545 rb
->lcd_set_foreground(LCD_RGBPACK(104, 63, 63));
547 rb
->lcd_fillrect(BJ_WIDTH
*TILE_WIDTH
+(LCD_WIDTH
-BJ_WIDTH
*TILE_WIDTH
)/4,
548 (LCD_HEIGHT
-10)-(((LCD_HEIGHT
-10)-18)*
549 tempscore
/LEVEL_PTS
),
550 (LCD_WIDTH
-BJ_WIDTH
*TILE_WIDTH
)/2,
551 ((LCD_HEIGHT
-10)-18)*tempscore
/LEVEL_PTS
);
552 #ifdef HAVE_LCD_COLOR
553 rb
->lcd_set_foreground(LCD_RGBPACK(83, 44, 44));
554 rb
->lcd_drawrect(BJ_WIDTH
*TILE_WIDTH
+(LCD_WIDTH
-BJ_WIDTH
*TILE_WIDTH
)/4+1,
555 (LCD_HEIGHT
-10)-(((LCD_HEIGHT
-10)-18)*
556 tempscore
/LEVEL_PTS
)+1,
557 (LCD_WIDTH
-BJ_WIDTH
*TILE_WIDTH
)/2-2,
558 ((LCD_HEIGHT
-10)-18)*tempscore
/LEVEL_PTS
-1);
560 rb
->lcd_drawrect(BJ_WIDTH
*TILE_WIDTH
+(LCD_WIDTH
-BJ_WIDTH
*TILE_WIDTH
)/4,
561 (LCD_HEIGHT
-10)-(((LCD_HEIGHT
-10)-18)*
562 tempscore
/LEVEL_PTS
),
563 (LCD_WIDTH
-BJ_WIDTH
*TILE_WIDTH
)/2,
564 ((LCD_HEIGHT
-10)-18)*tempscore
/LEVEL_PTS
+1);
568 rb
->lcd_getstringsize(title
, &w
, &h
);
569 rb
->lcd_putsxy(LCD_WIDTH
-(LCD_WIDTH
-BJ_WIDTH
*TILE_WIDTH
)/2-w
/2, 1, title
);
571 rb
->snprintf(str
, 4, "%d", bj
->level
);
572 rb
->lcd_getstringsize(str
, &w
, &h
);
573 rb
->lcd_putsxy(LCD_WIDTH
-(LCD_WIDTH
-BJ_WIDTH
*TILE_WIDTH
)/2-w
/2, 10, str
);
575 rb
->snprintf(str
, 6, "%d", (bj
->level
-1)*LEVEL_PTS
+bj
->score
);
576 rb
->lcd_getstringsize(str
, &w
, &h
);
577 rb
->lcd_putsxy(LCD_WIDTH
-(LCD_WIDTH
-BJ_WIDTH
*TILE_WIDTH
)/2-w
/2,
580 #elif LCD_WIDTH < LCD_HEIGHT /* vertical layout */
582 /* draw separator lines */
584 rb
->lcd_hline(0, LCD_WIDTH
-1, 8*TILE_HEIGHT
+YOFS
);
585 rb
->lcd_hline(0, LCD_WIDTH
-1, LCD_HEIGHT
-14);
586 rb
->lcd_vline(LCD_WIDTH
/2, LCD_HEIGHT
-14, LCD_HEIGHT
-1);
588 /* draw progress bar */
589 #ifdef HAVE_LCD_COLOR
590 rb
->lcd_set_foreground(LCD_RGBPACK(104, 63, 63));
592 rb
->lcd_fillrect(0, (8*TILE_HEIGHT
+YOFS
)
593 +(LCD_HEIGHT
-14-(8*TILE_HEIGHT
+YOFS
))/4,
594 LCD_WIDTH
*tempscore
/LEVEL_PTS
,
595 (LCD_HEIGHT
-14-(8*TILE_HEIGHT
+YOFS
))/2);
596 #ifdef HAVE_LCD_COLOR
597 rb
->lcd_set_foreground(LCD_RGBPACK(83, 44, 44));
598 rb
->lcd_drawrect(1, (8*TILE_HEIGHT
+YOFS
)
599 +(LCD_HEIGHT
-14-(8*TILE_HEIGHT
+YOFS
))/4+1,
600 LCD_WIDTH
*tempscore
/LEVEL_PTS
-1,
601 (LCD_HEIGHT
-14-(8*TILE_HEIGHT
+YOFS
))/2-2);
603 rb
->lcd_drawrect(0, (8*TILE_HEIGHT
+YOFS
)
604 +(LCD_HEIGHT
-14-(8*TILE_HEIGHT
+YOFS
))/4,
605 LCD_WIDTH
*tempscore
/LEVEL_PTS
+1,
606 (LCD_HEIGHT
-14-(8*TILE_HEIGHT
+YOFS
))/2);
610 rb
->snprintf(str
, 10, "%s %d", title
, bj
->level
);
611 rb
->lcd_putsxy(1, LCD_HEIGHT
-10, str
);
613 rb
->snprintf(str
, 6, "%d", (bj
->level
-1)*LEVEL_PTS
+bj
->score
);
614 rb
->lcd_getstringsize(str
, &w
, &h
);
615 rb
->lcd_putsxy((LCD_WIDTH
-2)-w
, LCD_HEIGHT
-10, str
);
617 #else /* square layout */
619 /* draw separator lines */
621 rb
->lcd_hline(0, LCD_WIDTH
-1, 8*TILE_HEIGHT
+YOFS
);
622 rb
->lcd_vline(BJ_WIDTH
*TILE_WIDTH
, 0, 8*TILE_HEIGHT
+YOFS
);
623 rb
->lcd_vline(LCD_WIDTH
/2, 8*TILE_HEIGHT
+YOFS
, LCD_HEIGHT
-1);
625 /* draw progress bar */
626 #ifdef HAVE_LCD_COLOR
627 rb
->lcd_set_foreground(LCD_RGBPACK(104, 63, 63));
629 rb
->lcd_fillrect(BJ_WIDTH
*TILE_WIDTH
+(LCD_WIDTH
-BJ_WIDTH
*TILE_WIDTH
)/4,
630 (8*TILE_HEIGHT
+YOFS
)-(8*TILE_HEIGHT
+YOFS
)
631 *tempscore
/LEVEL_PTS
,
632 (LCD_WIDTH
-BJ_WIDTH
*TILE_WIDTH
)/2,
633 (8*TILE_HEIGHT
+YOFS
)*tempscore
/LEVEL_PTS
);
634 #ifdef HAVE_LCD_COLOR
635 rb
->lcd_set_foreground(LCD_RGBPACK(83, 44, 44));
636 rb
->lcd_drawrect(BJ_WIDTH
*TILE_WIDTH
+(LCD_WIDTH
-BJ_WIDTH
*TILE_WIDTH
)/4+1,
637 (8*TILE_HEIGHT
+YOFS
)-(8*TILE_HEIGHT
+YOFS
)
638 *tempscore
/LEVEL_PTS
+1,
639 (LCD_WIDTH
-BJ_WIDTH
*TILE_WIDTH
)/2-2,
640 (8*TILE_HEIGHT
+YOFS
)*tempscore
/LEVEL_PTS
-1);
642 rb
->lcd_drawrect(BJ_WIDTH
*TILE_WIDTH
+(LCD_WIDTH
-BJ_WIDTH
*TILE_WIDTH
)/4,
643 (8*TILE_HEIGHT
+YOFS
)-(8*TILE_HEIGHT
+YOFS
)
644 *tempscore
/LEVEL_PTS
,
645 (LCD_WIDTH
-BJ_WIDTH
*TILE_WIDTH
)/2,
646 (8*TILE_HEIGHT
+YOFS
)*tempscore
/LEVEL_PTS
+1);
650 rb
->snprintf(str
, 10, "%s %d", title
, bj
->level
);
651 rb
->lcd_putsxy(1, LCD_HEIGHT
-(LCD_HEIGHT
-(8*TILE_HEIGHT
+YOFS
))/2-3, str
);
653 rb
->snprintf(str
, 6, "%d", (bj
->level
-1)*LEVEL_PTS
+bj
->score
);
654 rb
->lcd_getstringsize(str
, &w
, &h
);
655 rb
->lcd_putsxy((LCD_WIDTH
-2)-w
,
656 LCD_HEIGHT
-(LCD_HEIGHT
-(8*TILE_HEIGHT
+YOFS
))/2-3, str
);
663 /*****************************************************************************
664 * jewels_showmenu() displays the chosen menu after performing the chosen
666 ******************************************************************************/
667 static enum menu_result
jewels_showmenu(struct jewels_menu
* menu
,
673 int extraline
= LCD_HEIGHT
<= ((menu
->itemcnt
+2)*FONT_HEIGHT
) ? 0 : 1;
675 /* handle menu command */
678 menu
->selected
= (menu
->selected
+1)%menu
->itemcnt
;
682 menu
->selected
= (menu
->selected
-1+menu
->itemcnt
)%menu
->itemcnt
;
686 return menu
->items
[menu
->selected
].res
;
692 /* clear menu area */
693 firstline
= (LCD_HEIGHT
/FONT_HEIGHT
-(menu
->itemcnt
+3))/2;
695 rb
->lcd_set_drawmode(DRMODE_SOLID
|DRMODE_INVERSEVID
);
696 rb
->lcd_fillrect((LCD_WIDTH
-MENU_WIDTH
)/2, firstline
*FONT_HEIGHT
,
697 MENU_WIDTH
, (menu
->itemcnt
+3)*FONT_HEIGHT
);
698 rb
->lcd_set_drawmode(DRMODE_SOLID
);
701 rb
->lcd_drawrect((LCD_WIDTH
-MENU_WIDTH
)/2-1, firstline
*FONT_HEIGHT
-1,
702 MENU_WIDTH
+2, (menu
->itemcnt
+3)*FONT_HEIGHT
+2);
703 rb
->lcd_hline((LCD_WIDTH
-MENU_WIDTH
)/2-1,
704 (LCD_WIDTH
-MENU_WIDTH
)/2-1+MENU_WIDTH
+2,
705 (firstline
+1)*FONT_HEIGHT
);
708 /* draw menu items */
709 rb
->lcd_getstringsize(menu
->title
, &w
, &h
);
710 rb
->lcd_putsxy((LCD_WIDTH
-w
)/2, firstline
*FONT_HEIGHT
, menu
->title
);
712 for(i
=0; i
<menu
->itemcnt
; i
++) {
713 if(i
== menu
->selected
) {
714 rb
->lcd_set_drawmode(DRMODE_SOLID
|DRMODE_INVERSEVID
);
716 rb
->lcd_putsxy((LCD_WIDTH
-MENU_WIDTH
)/2,
717 (firstline
+i
+1+extraline
)*FONT_HEIGHT
,
718 menu
->items
[i
].text
);
719 if(i
== menu
->selected
) {
720 rb
->lcd_set_drawmode(DRMODE_SOLID
);
724 adj
= (firstline
== 0 ? 0 : 1);
725 rb
->lcd_update_rect((LCD_WIDTH
-MENU_WIDTH
)/2-1, firstline
*FONT_HEIGHT
-adj
,
726 MENU_WIDTH
+2, (menu
->itemcnt
+3)*FONT_HEIGHT
+2*adj
);
730 /*****************************************************************************
731 * jewels_putjewels() makes the jewels fall to fill empty spots and adds
732 * new random jewels at the empty spots at the top of each row.
733 ******************************************************************************/
734 static void jewels_putjewels(struct game_context
* bj
){
737 long lasttick
, currenttick
;
739 /* loop to make all the jewels fall */
741 /* mark falling jewels and add new jewels to hidden top row*/
744 for(j
=0; j
<BJ_WIDTH
; j
++) {
745 if(bj
->playboard
[1][j
].type
== 0) {
746 bj
->playboard
[0][j
].type
= rb
->rand()%bj
->num_jewels
+1;
748 for(i
=BJ_HEIGHT
-2; i
>=0; i
--) {
749 if(!mark
&& bj
->playboard
[i
+1][j
].type
== 0) {
753 if(mark
) bj
->playboard
[i
][j
].falling
= true;
755 /*if(bj->playboard[1][j].falling) {
756 bj->playboard[0][j].type = rb->rand()%bj->num_jewels+1;
757 bj->playboard[0][j].falling = true;
762 /* break if there are no falling jewels */
765 /* animate falling jewels */
766 lasttick
= *rb
->current_tick
;
768 for(k
=1; k
<=8; k
++) {
769 for(i
=BJ_HEIGHT
-2; i
>=0; i
--) {
770 for(j
=0; j
<BJ_WIDTH
; j
++) {
771 if(bj
->playboard
[i
][j
].falling
&&
772 bj
->playboard
[i
][j
].type
!= 0) {
773 /* clear old position */
774 #ifdef HAVE_LCD_COLOR
776 rb
->lcd_set_foreground(rb
->lcd_get_background());
778 rb
->lcd_set_foreground(jewels_bkgd
[(i
-1+j
)%2]);
780 rb
->lcd_fillrect(j
*TILE_WIDTH
, (i
-1)*TILE_HEIGHT
+YOFS
,
781 TILE_WIDTH
, TILE_HEIGHT
);
782 if(bj
->playboard
[i
+1][j
].type
== 0) {
783 rb
->lcd_set_foreground(jewels_bkgd
[(i
+j
)%2]);
784 rb
->lcd_fillrect(j
*TILE_WIDTH
, i
*TILE_HEIGHT
+YOFS
,
785 TILE_WIDTH
, TILE_HEIGHT
);
788 rb
->lcd_set_drawmode(DRMODE_SOLID
|DRMODE_INVERSEVID
);
789 rb
->lcd_fillrect(j
*TILE_WIDTH
, (i
-1)*TILE_HEIGHT
+YOFS
,
790 TILE_WIDTH
, TILE_HEIGHT
);
791 if(bj
->playboard
[i
+1][j
].type
== 0) {
792 rb
->lcd_fillrect(j
*TILE_WIDTH
, i
*TILE_HEIGHT
+YOFS
,
793 TILE_WIDTH
, TILE_HEIGHT
);
795 rb
->lcd_set_drawmode(DRMODE_SOLID
);
798 /* draw new position */
799 #ifdef HAVE_LCD_COLOR
800 rb
->lcd_bitmap_transparent_part(jewels
, 0,
801 TILE_HEIGHT
*(bj
->playboard
[i
][j
].type
),
802 TILE_WIDTH
, j
*TILE_WIDTH
,
803 (i
-1)*TILE_HEIGHT
+YOFS
+
804 ((((TILE_HEIGHT
<<10)*k
)/8)>>10),
805 TILE_WIDTH
, TILE_HEIGHT
);
807 rb
->lcd_bitmap_part(jewels
, 0,
808 TILE_HEIGHT
*(bj
->playboard
[i
][j
].type
),
809 TILE_WIDTH
, j
*TILE_WIDTH
,
810 (i
-1)*TILE_HEIGHT
+YOFS
+
811 ((((TILE_HEIGHT
<<10)*k
)/8)>>10),
812 TILE_WIDTH
, TILE_HEIGHT
);
818 rb
->lcd_update_rect(0, 0, TILE_WIDTH
*8, LCD_HEIGHT
);
821 /* framerate limiting */
822 currenttick
= *rb
->current_tick
;
823 if(currenttick
-lasttick
< HZ
/MAX_FPS
) {
824 rb
->sleep((HZ
/MAX_FPS
)-(currenttick
-lasttick
));
828 lasttick
= currenttick
;
831 /* shift jewels down */
832 for(j
=0; j
<BJ_WIDTH
; j
++) {
833 for(i
=BJ_HEIGHT
-1; i
>=1; i
--) {
834 if(bj
->playboard
[i
-1][j
].falling
) {
835 bj
->playboard
[i
][j
].type
= bj
->playboard
[i
-1][j
].type
;
840 /* clear out top row */
841 for(j
=0; j
<BJ_WIDTH
; j
++) {
842 bj
->playboard
[0][j
].type
= 0;
845 /* mark everything not falling */
846 for(i
=0; i
<BJ_HEIGHT
; i
++) {
847 for(j
=0; j
<BJ_WIDTH
; j
++) {
848 bj
->playboard
[i
][j
].falling
= false;
854 /*****************************************************************************
855 * jewels_clearjewels() finds all the connected rows and columns and
856 * calculates and returns the points earned.
857 ******************************************************************************/
858 static unsigned int jewels_clearjewels(struct game_context
* bj
) {
861 unsigned int points
= 0;
863 /* check for connected rows */
864 for(i
=1; i
<BJ_HEIGHT
; i
++) {
867 for(j
=0; j
<BJ_WIDTH
; j
++) {
868 if(bj
->playboard
[i
][j
].type
== last
&&
869 bj
->playboard
[i
][j
].type
!= 0 &&
870 bj
->playboard
[i
][j
].type
<= MAX_NUM_JEWELS
) {
875 points
+= bj
->segments
;
876 bj
->playboard
[i
][j
].delete = true;
877 bj
->playboard
[i
][j
-1].delete = true;
878 bj
->playboard
[i
][j
-2].delete = true;
881 bj
->playboard
[i
][j
].delete = true;
885 last
= bj
->playboard
[i
][j
].type
;
890 /* check for connected columns */
891 for(j
=0; j
<BJ_WIDTH
; j
++) {
894 for(i
=1; i
<BJ_HEIGHT
; i
++) {
895 if(bj
->playboard
[i
][j
].type
!= 0 &&
896 bj
->playboard
[i
][j
].type
== last
&&
897 bj
->playboard
[i
][j
].type
<= MAX_NUM_JEWELS
) {
902 points
+= bj
->segments
;
903 bj
->playboard
[i
][j
].delete = true;
904 bj
->playboard
[i
-1][j
].delete = true;
905 bj
->playboard
[i
-2][j
].delete = true;
908 bj
->playboard
[i
][j
].delete = true;
912 last
= bj
->playboard
[i
][j
].type
;
917 /* clear deleted jewels */
918 for(i
=1; i
<BJ_HEIGHT
; i
++) {
919 for(j
=0; j
<BJ_WIDTH
; j
++) {
920 if(bj
->playboard
[i
][j
].delete) {
921 bj
->playboard
[i
][j
].delete = false;
922 bj
->playboard
[i
][j
].type
= 0;
930 /*****************************************************************************
931 * jewels_runboard() runs the board until it settles in a fixed state and
932 * returns points earned.
933 ******************************************************************************/
934 static unsigned int jewels_runboard(struct game_context
* bj
) {
935 unsigned int points
= 0;
940 while((ret
= jewels_clearjewels(bj
)) > 0) {
942 jewels_drawboard(bj
);
943 jewels_putjewels(bj
);
949 /*****************************************************************************
950 * jewels_swapjewels() swaps two jewels as long as it results in points and
951 * returns points earned.
952 ******************************************************************************/
953 static unsigned int jewels_swapjewels(struct game_context
* bj
,
954 int x
, int y
, int direc
) {
956 int horzmod
, vertmod
;
959 unsigned int points
= 0;
960 long lasttick
, currenttick
;
962 /* check for invalid parameters */
963 if(x
< 0 || x
>= BJ_WIDTH
|| y
< 0 || y
>= BJ_HEIGHT
-1 ||
964 direc
< SWAP_UP
|| direc
> SWAP_LEFT
) {
968 /* check for invalid directions */
969 if((x
== 0 && direc
== SWAP_LEFT
) ||
970 (x
== BJ_WIDTH
-1 && direc
== SWAP_RIGHT
) ||
971 (y
== 0 && direc
== SWAP_UP
) ||
972 (y
== BJ_HEIGHT
-2 && direc
== SWAP_DOWN
)) {
976 /* set direction variables */
982 movelen
= TILE_HEIGHT
;
986 movelen
= TILE_WIDTH
;
990 movelen
= TILE_HEIGHT
;
994 movelen
= TILE_WIDTH
;
999 lasttick
= *rb
->current_tick
;
1001 /* animate swapping jewels */
1002 for(k
=0; k
<=8; k
++) {
1003 /* clear old position */
1004 #ifdef HAVE_LCD_COLOR
1005 rb
->lcd_set_foreground(jewels_bkgd
[(x
+y
)%2]);
1006 rb
->lcd_fillrect(x
*TILE_WIDTH
,
1008 TILE_WIDTH
, TILE_HEIGHT
);
1009 rb
->lcd_set_foreground(jewels_bkgd
[(x
+horzmod
+y
+vertmod
)%2]);
1010 rb
->lcd_fillrect((x
+horzmod
)*TILE_WIDTH
,
1011 (y
+vertmod
)*TILE_HEIGHT
+YOFS
,
1012 TILE_WIDTH
, TILE_HEIGHT
);
1014 rb
->lcd_set_drawmode(DRMODE_SOLID
|DRMODE_INVERSEVID
);
1015 rb
->lcd_fillrect(x
*TILE_WIDTH
,
1017 TILE_WIDTH
, TILE_HEIGHT
);
1018 rb
->lcd_fillrect((x
+horzmod
)*TILE_WIDTH
,
1019 (y
+vertmod
)*TILE_HEIGHT
+YOFS
,
1020 TILE_WIDTH
, TILE_HEIGHT
);
1021 rb
->lcd_set_drawmode(DRMODE_SOLID
);
1023 /* draw new position */
1024 #ifdef HAVE_LCD_COLOR
1025 rb
->lcd_bitmap_transparent_part(jewels
,
1026 0, TILE_HEIGHT
*(bj
->playboard
1027 [y
+1+vertmod
][x
+horzmod
].type
), TILE_WIDTH
,
1028 (x
+horzmod
)*TILE_WIDTH
-horzmod
*
1029 ((((movelen
<<10)*k
)/8)>>10),
1030 (y
+vertmod
)*TILE_HEIGHT
-vertmod
*
1031 ((((movelen
<<10)*k
)/8)>>10)+YOFS
,
1032 TILE_WIDTH
, TILE_HEIGHT
);
1033 rb
->lcd_bitmap_transparent_part(jewels
,
1034 0, TILE_HEIGHT
*(bj
->playboard
[y
+1][x
].type
),
1035 TILE_WIDTH
, x
*TILE_WIDTH
+horzmod
*
1036 ((((movelen
<<10)*k
)/8)>>10),
1037 y
*TILE_HEIGHT
+vertmod
*
1038 ((((movelen
<<10)*k
)/8)>>10)+YOFS
,
1039 TILE_WIDTH
, TILE_HEIGHT
);
1041 rb
->lcd_bitmap_part(jewels
,
1042 0, TILE_HEIGHT
*(bj
->playboard
1043 [y
+1+vertmod
][x
+horzmod
].type
), TILE_WIDTH
,
1044 (x
+horzmod
)*TILE_WIDTH
-horzmod
*
1045 ((((movelen
<<10)*k
)/8)>>10),
1046 (y
+vertmod
)*TILE_HEIGHT
-vertmod
*
1047 ((((movelen
<<10)*k
)/8)>>10)+YOFS
,
1048 TILE_WIDTH
, TILE_HEIGHT
);
1049 rb
->lcd_set_drawmode(DRMODE_FG
);
1050 rb
->lcd_bitmap_part(jewels
,
1051 0, TILE_HEIGHT
*(bj
->playboard
[y
+1][x
].type
),
1052 TILE_WIDTH
, x
*TILE_WIDTH
+horzmod
*
1053 ((((movelen
<<10)*k
)/8)>>10),
1054 y
*TILE_HEIGHT
+vertmod
*
1055 ((((movelen
<<10)*k
)/8)>>10)+YOFS
,
1056 TILE_WIDTH
, TILE_HEIGHT
);
1057 rb
->lcd_set_drawmode(DRMODE_SOLID
);
1060 rb
->lcd_update_rect(0, 0, TILE_WIDTH
*8, LCD_HEIGHT
);
1063 /* framerate limiting */
1064 currenttick
= *rb
->current_tick
;
1065 if(currenttick
-lasttick
< HZ
/MAX_FPS
) {
1066 rb
->sleep((HZ
/MAX_FPS
)-(currenttick
-lasttick
));
1070 lasttick
= currenttick
;
1074 int temp
= bj
->playboard
[y
+1][x
].type
;
1075 bj
->playboard
[y
+1][x
].type
=
1076 bj
->playboard
[y
+1+vertmod
][x
+horzmod
].type
;
1077 bj
->playboard
[y
+1+vertmod
][x
+horzmod
].type
= temp
;
1081 points
= jewels_runboard(bj
);
1092 /*****************************************************************************
1093 * jewels_movesavail() uses pattern matching to see if there are any
1094 * available move left.
1095 ******************************************************************************/
1096 static bool jewels_movesavail(struct game_context
* bj
) {
1101 for(i
=1; i
<BJ_HEIGHT
; i
++) {
1102 for(j
=0; j
<BJ_WIDTH
; j
++) {
1103 mytype
= bj
->playboard
[i
][j
].type
;
1104 if(mytype
== 0 || mytype
> MAX_NUM_JEWELS
) continue;
1106 /* check horizontal patterns */
1107 if(j
<= BJ_WIDTH
-3) {
1109 if(bj
->playboard
[i
-1][j
+1].type
== mytype
) {
1110 if(bj
->playboard
[i
-1][j
+2].type
== mytype
)
1111 {moves
= true; break;}
1112 if(bj
->playboard
[i
][j
+2].type
== mytype
)
1113 {moves
= true; break;}
1115 if(bj
->playboard
[i
][j
+1].type
== mytype
) {
1116 if(bj
->playboard
[i
-1][j
+2].type
== mytype
)
1117 {moves
= true; break;}
1121 if(j
<= BJ_WIDTH
-4) {
1122 if(bj
->playboard
[i
][j
+3].type
== mytype
) {
1123 if(bj
->playboard
[i
][j
+1].type
== mytype
)
1124 {moves
= true; break;}
1125 if(bj
->playboard
[i
][j
+2].type
== mytype
)
1126 {moves
= true; break;}
1130 if(i
< BJ_HEIGHT
-1) {
1131 if(bj
->playboard
[i
][j
+1].type
== mytype
) {
1132 if(bj
->playboard
[i
+1][j
+2].type
== mytype
)
1133 {moves
= true; break;}
1135 if(bj
->playboard
[i
+1][j
+1].type
== mytype
) {
1136 if(bj
->playboard
[i
][j
+2].type
== mytype
)
1137 {moves
= true; break;}
1138 if(bj
->playboard
[i
+1][j
+2].type
== mytype
)
1139 {moves
= true; break;}
1144 /* check vertical patterns */
1145 if(i
<= BJ_HEIGHT
-3) {
1147 if(bj
->playboard
[i
+1][j
-1].type
== mytype
) {
1148 if(bj
->playboard
[i
+2][j
-1].type
== mytype
)
1149 {moves
= true; break;}
1150 if(bj
->playboard
[i
+2][j
].type
== mytype
)
1151 {moves
= true; break;}
1153 if(bj
->playboard
[i
+1][j
].type
== mytype
) {
1154 if(bj
->playboard
[i
+2][j
-1].type
== mytype
)
1155 {moves
= true; break;}
1159 if(i
<= BJ_HEIGHT
-4) {
1160 if(bj
->playboard
[i
+3][j
].type
== mytype
) {
1161 if(bj
->playboard
[i
+1][j
].type
== mytype
)
1162 {moves
= true; break;}
1163 if(bj
->playboard
[i
+2][j
].type
== mytype
)
1164 {moves
= true; break;}
1168 if(j
< BJ_WIDTH
-1) {
1169 if(bj
->playboard
[i
+1][j
].type
== mytype
) {
1170 if(bj
->playboard
[i
+2][j
+1].type
== mytype
)
1171 {moves
= true; break;}
1173 if(bj
->playboard
[i
+1][j
+1].type
== mytype
) {
1174 if(bj
->playboard
[i
+2][j
].type
== mytype
)
1175 {moves
= true; break;}
1176 if (bj
->playboard
[i
+2][j
+1].type
== mytype
)
1177 {moves
= true; break;}
1189 /*****************************************************************************
1190 * jewels_puzzle_is_finished(bj) checks if the puzzle is finished.
1191 ******************************************************************************/
1192 static int jewels_puzzle_is_finished(struct game_context
* bj
) {
1194 for(i
=0; i
<BJ_HEIGHT
; i
++) {
1195 for(j
=0; j
<BJ_WIDTH
; j
++) {
1196 int mytype
= bj
->playboard
[i
][j
].type
;
1197 if(mytype
>MAX_NUM_JEWELS
) {
1198 mytype
-= MAX_NUM_JEWELS
;
1199 if(mytype
&PUZZLE_TILE_UP
) {
1200 if(i
==0 || bj
->playboard
[i
-1][j
].type
<=MAX_NUM_JEWELS
||
1201 !((bj
->playboard
[i
-1][j
].type
-MAX_NUM_JEWELS
)
1205 if(mytype
&PUZZLE_TILE_DOWN
) {
1206 if(i
==BJ_HEIGHT
-1 ||
1207 bj
->playboard
[i
+1][j
].type
<=MAX_NUM_JEWELS
||
1208 !((bj
->playboard
[i
+1][j
].type
-MAX_NUM_JEWELS
)
1212 if(mytype
&PUZZLE_TILE_LEFT
) {
1213 if(j
==0 || bj
->playboard
[i
][j
-1].type
<=MAX_NUM_JEWELS
||
1214 !((bj
->playboard
[i
][j
-1].type
-MAX_NUM_JEWELS
)
1215 &PUZZLE_TILE_RIGHT
))
1218 if(mytype
&PUZZLE_TILE_RIGHT
) {
1220 bj
->playboard
[i
][j
+1].type
<=MAX_NUM_JEWELS
||
1221 !((bj
->playboard
[i
][j
+1].type
-MAX_NUM_JEWELS
)
1231 /*****************************************************************************
1232 * jewels_initlevel() initialises a level.
1233 ******************************************************************************/
1234 static unsigned int jewels_initlevel(struct game_context
* bj
) {
1235 unsigned int points
= 0;
1238 case GAME_TYPE_NORMAL
:
1239 bj
->num_jewels
= MAX_NUM_JEWELS
;
1242 case GAME_TYPE_PUZZLE
:
1245 struct puzzle_tile
*tile
;
1247 bj
->num_jewels
= puzzle_levels
[bj
->level
-1].num_jewels
;
1249 for(i
=0; i
<BJ_HEIGHT
; i
++) {
1250 for(j
=0; j
<BJ_WIDTH
; j
++) {
1251 bj
->playboard
[i
][j
].type
= (rb
->rand()%bj
->num_jewels
)+1;
1252 bj
->playboard
[i
][j
].falling
= false;
1253 bj
->playboard
[i
][j
].delete = false;
1256 jewels_runboard(bj
);
1257 tile
= puzzle_levels
[bj
->level
-1].tiles
;
1258 for(i
=0; i
<puzzle_levels
[bj
->level
-1].num_tiles
; i
++, tile
++) {
1259 bj
->playboard
[tile
->y
+1][tile
->x
].type
= MAX_NUM_JEWELS
1266 jewels_drawboard(bj
);
1268 /* run the play board */
1269 jewels_putjewels(bj
);
1270 points
+= jewels_runboard(bj
);
1274 /*****************************************************************************
1275 * jewels_nextlevel() advances the game to the next level and returns
1277 ******************************************************************************/
1278 static void jewels_nextlevel(struct game_context
* bj
) {
1280 unsigned int points
= 0;
1283 case GAME_TYPE_NORMAL
:
1284 /* roll over score, change and display level */
1285 while(bj
->score
>= LEVEL_PTS
) {
1286 bj
->score
-= LEVEL_PTS
;
1288 rb
->splashf(HZ
*2, "Level %d", bj
->level
);
1289 jewels_drawboard(bj
);
1292 /* randomly clear some jewels */
1293 for(i
=0; i
<16; i
++) {
1297 if(bj
->playboard
[y
][x
].type
!= 0) {
1299 bj
->playboard
[y
][x
].type
= 0;
1304 case GAME_TYPE_PUZZLE
:
1306 if(bj
->level
>NUM_PUZZLE_LEVELS
) {
1307 rb
->splash(HZ
*2, "You win!");
1310 rb
->splashf(HZ
*2, "Level %d", bj
->level
);
1315 points
+= jewels_initlevel(bj
);
1316 bj
->score
+= points
;
1319 /*****************************************************************************
1320 * jewels_recordscore() inserts a high score into the high scores list and
1321 * returns the high score position.
1322 ******************************************************************************/
1323 static int jewels_recordscore(struct game_context
* bj
) {
1326 unsigned int current
, temp
;
1328 /* calculate total score */
1329 current
= (bj
->level
-1)*LEVEL_PTS
+bj
->score
;
1330 if(current
<= 0) return 0;
1332 /* insert the current score into the high scores */
1333 for(i
=0; i
<NUM_SCORES
; i
++) {
1334 if(current
>= bj
->highscores
[i
]) {
1339 temp
= bj
->highscores
[i
];
1340 bj
->highscores
[i
] = current
;
1348 /*****************************************************************************
1349 * jewels_loadscores() loads the high scores saved file.
1350 ******************************************************************************/
1351 static void jewels_loadscores(struct game_context
* bj
) {
1356 /* clear high scores */
1357 rb
->memset(bj
->highscores
, 0, sizeof(bj
->highscores
));
1359 /* open scores file */
1360 fd
= rb
->open(SCORE_FILE
, O_RDONLY
);
1363 /* read in high scores */
1364 if(rb
->read(fd
, bj
->highscores
, sizeof(bj
->highscores
)) <= 0) {
1365 /* scores are bad, reset */
1366 rb
->memset(bj
->highscores
, 0, sizeof(bj
->highscores
));
1372 /*****************************************************************************
1373 * jewels_savescores() saves the high scores saved file.
1374 ******************************************************************************/
1375 static void jewels_savescores(struct game_context
* bj
) {
1378 /* write out the high scores to the save file */
1379 fd
= rb
->open(SCORE_FILE
, O_WRONLY
|O_CREAT
);
1380 rb
->write(fd
, bj
->highscores
, sizeof(bj
->highscores
));
1385 /*****************************************************************************
1386 * jewels_loadgame() loads the saved game and returns load success.
1387 ******************************************************************************/
1388 static bool jewels_loadgame(struct game_context
* bj
) {
1390 bool loaded
= false;
1392 /* open game file */
1393 fd
= rb
->open(SAVE_FILE
, O_RDONLY
);
1394 if(fd
< 0) return loaded
;
1396 /* read in saved game */
1398 if(rb
->read(fd
, &bj
->score
, sizeof(bj
->score
)) <= 0) break;
1399 if(rb
->read(fd
, &bj
->level
, sizeof(bj
->level
)) <= 0) break;
1400 if(rb
->read(fd
, &bj
->type
, sizeof(bj
->type
)) <= 0) break;
1401 if(rb
->read(fd
, bj
->playboard
, sizeof(bj
->playboard
)) <= 0) break;
1409 /* delete saved file */
1410 rb
->remove(SAVE_FILE
);
1414 /*****************************************************************************
1415 * jewels_savegame() saves the current game state.
1416 ******************************************************************************/
1417 static void jewels_savegame(struct game_context
* bj
) {
1420 /* write out the game state to the save file */
1421 fd
= rb
->open(SAVE_FILE
, O_WRONLY
|O_CREAT
);
1422 rb
->write(fd
, &bj
->score
, sizeof(bj
->score
));
1423 rb
->write(fd
, &bj
->level
, sizeof(bj
->level
));
1424 rb
->write(fd
, &bj
->type
, sizeof(bj
->type
));
1425 rb
->write(fd
, bj
->playboard
, sizeof(bj
->playboard
));
1431 /*****************************************************************************
1432 * jewels_callback() is the default event handler callback which is called
1433 * on usb connect and shutdown.
1434 ******************************************************************************/
1435 static void jewels_callback(void* param
) {
1436 struct game_context
* bj
= (struct game_context
*) param
;
1438 rb
->splash(HZ
, "Saving high scores...");
1439 jewels_savescores(bj
);
1443 /*****************************************************************************
1444 * jewels_main() is the main game subroutine, it returns the final game status.
1445 ******************************************************************************/
1446 static int jewels_main(struct game_context
* bj
) {
1451 bool startgame
= false;
1452 bool inmenu
= false;
1453 bool selected
= false;
1454 enum menu_cmd cmd
= MCMD_NONE
;
1455 enum menu_result res
;
1457 /* the cursor coordinates */
1460 /* don't resume by default */
1463 /********************
1465 ********************/
1466 rb
->lcd_clear_display();
1469 res
= jewels_showmenu(&bjmenu
[0], cmd
);
1472 rb
->snprintf(str
, 18, "High Score: %d", bj
->highscores
[0]);
1473 rb
->lcd_getstringsize(str
, &w
, &h
);
1474 rb
->lcd_putsxy((LCD_WIDTH
-w
)/2, LCD_HEIGHT
-8, str
);
1482 bj
->type
= GAME_TYPE_NORMAL
;
1487 bj
->type
= GAME_TYPE_PUZZLE
;
1491 if(!jewels_loadgame(bj
)) {
1492 rb
->splash(HZ
*2, "Nothing to resume");
1493 rb
->lcd_clear_display();
1500 rb
->lcd_clear_display();
1502 /* room for a title? */
1504 if(LCD_HEIGHT
-NUM_SCORES
*8 >= 8) {
1505 rb
->snprintf(str
, 12, "%s", "High Scores");
1506 rb
->lcd_getstringsize(str
, &w
, &h
);
1507 rb
->lcd_putsxy((LCD_WIDTH
-w
)/2, 0, str
);
1511 /* print high scores */
1512 for(i
=0; i
<NUM_SCORES
; i
++) {
1513 rb
->snprintf(str
, 11, "#%02d: %d", i
+1, bj
->highscores
[i
]);
1514 rb
->lcd_puts(0, i
+j
, str
);
1519 button
= rb
->button_get(true);
1520 if(button
!= BUTTON_NONE
&& !(button
&BUTTON_REL
)) break;
1523 rb
->lcd_clear_display();
1527 /* welcome screen to display key bindings */
1528 rb
->lcd_clear_display();
1529 rb
->snprintf(str
, 5, "%s", "Help");
1530 rb
->lcd_getstringsize(str
, &w
, &h
);
1531 rb
->lcd_putsxy((LCD_WIDTH
-w
)/2, 0, str
);
1532 #if CONFIG_KEYPAD == RECORDER_PAD
1533 rb
->lcd_puts(0, 2, "Controls:");
1534 rb
->lcd_puts(0, 3, "Directions = move");
1535 rb
->lcd_puts(0, 4, "PLAY = select");
1536 rb
->lcd_puts(0, 5, "Long PLAY = menu");
1537 rb
->lcd_puts(0, 6, "OFF = cancel");
1538 #elif CONFIG_KEYPAD == ONDIO_PAD
1539 rb
->lcd_puts(0, 2, "Controls:");
1540 rb
->lcd_puts(0, 3, "Directions = move");
1541 rb
->lcd_puts(0, 4, "MENU = select");
1542 rb
->lcd_puts(0, 5, "Long MENU = menu");
1543 rb
->lcd_puts(0, 6, "OFF = cancel");
1544 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
1545 rb
->lcd_puts(0, 2, "Controls:");
1546 rb
->lcd_puts(0, 3, "Directions = move");
1547 rb
->lcd_puts(0, 4, "SELECT = select");
1548 rb
->lcd_puts(0, 5, "Long SELECT = menu");
1549 rb
->lcd_puts(0, 6, "PLAY = cancel");
1550 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
1551 rb
->lcd_puts(0, 2, "Swap pairs of jewels to");
1552 rb
->lcd_puts(0, 3, "form connected segments");
1553 rb
->lcd_puts(0, 4, "of three or more of the");
1554 rb
->lcd_puts(0, 5, "same type.");
1555 rb
->lcd_puts(0, 7, "Controls:");
1556 rb
->lcd_puts(0, 8, "Directions to move");
1557 rb
->lcd_puts(0, 9, "SELECT to select");
1558 rb
->lcd_puts(0, 10, "Long SELECT to show menu");
1559 rb
->lcd_puts(0, 11, "OFF to cancel");
1560 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
1561 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
1562 rb
->lcd_puts(0, 2, "Swap pairs of jewels to");
1563 rb
->lcd_puts(0, 3, "form connected segments");
1564 rb
->lcd_puts(0, 4, "of three or more of the");
1565 rb
->lcd_puts(0, 5, "same type.");
1566 rb
->lcd_puts(0, 7, "Controls:");
1567 rb
->lcd_puts(0, 8, "Directions or scroll to move");
1568 rb
->lcd_puts(0, 9, "SELECT to select");
1569 rb
->lcd_puts(0, 10, "Long SELECT to show menu");
1570 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
1571 rb
->lcd_puts(0, 2, "Swap pairs of jewels to");
1572 rb
->lcd_puts(0, 3, "form connected segments");
1573 rb
->lcd_puts(0, 4, "of three or more of the");
1574 rb
->lcd_puts(0, 5, "same type.");
1575 rb
->lcd_puts(0, 7, "Controls:");
1576 rb
->lcd_puts(0, 8, "Directions to move");
1577 rb
->lcd_puts(0, 9, "SELECT to select");
1578 rb
->lcd_puts(0, 10, "Long SELECT to show menu");
1579 rb
->lcd_puts(0, 11, "PLAY to cancel");
1580 #elif CONFIG_KEYPAD == GIGABEAT_PAD \
1581 || CONFIG_KEYPAD == MROBE100_PAD
1582 rb
->lcd_puts(0, 2, "Swap pairs of jewels to");
1583 rb
->lcd_puts(0, 3, "form connected segments");
1584 rb
->lcd_puts(0, 4, "of three or more of the");
1585 rb
->lcd_puts(0, 5, "same type.");
1586 rb
->lcd_puts(0, 7, "Controls:");
1587 rb
->lcd_puts(0, 8, "Directions to move");
1588 rb
->lcd_puts(0, 9, "SELECT to select");
1589 rb
->lcd_puts(0, 10, "Long SELECT to show menu");
1590 rb
->lcd_puts(0, 11, "POWER to cancel");
1591 #elif CONFIG_KEYPAD == SANSA_E200_PAD \
1592 || CONFIG_KEYPAD == SANSA_C200_PAD \
1593 || CONFIG_KEYPAD == SANSA_CLIP_PAD \
1594 || CONFIG_KEYPAD == SANSA_FUZE_PAD \
1595 || CONFIG_KEYPAD == SANSA_M200_PAD
1596 rb
->lcd_puts(0, 2, "Swap pairs of jewels to");
1597 rb
->lcd_puts(0, 3, "form connected segments");
1598 rb
->lcd_puts(0, 4, "of three or more of the");
1599 rb
->lcd_puts(0, 5, "same type.");
1600 rb
->lcd_puts(0, 7, "Controls:");
1601 rb
->lcd_puts(0, 8, "Directions to move");
1602 rb
->lcd_puts(0, 9, "SELECT to select");
1603 rb
->lcd_puts(0, 10, "Long SELECT to show menu");
1604 rb
->lcd_puts(0, 11, "POWER to cancel");
1605 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
1606 rb
->lcd_puts(0, 2, "Swap pairs of jewels");
1607 rb
->lcd_puts(0, 3, "to form connected");
1608 rb
->lcd_puts(0, 4, "segments of three or ");
1609 rb
->lcd_puts(0, 5, "more of the");
1610 rb
->lcd_puts(0, 6, "same type.");
1611 rb
->lcd_puts(0, 8, "Controls:");
1612 rb
->lcd_puts(0, 9, "Directions or scroll to move");
1613 rb
->lcd_puts(0, 10, "PLAY to select");
1614 rb
->lcd_puts(0, 11, "Long PLAY for menu");
1615 rb
->lcd_puts(0, 12, "POWER to cancel");
1616 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
1617 rb
->lcd_puts(0, 2, "Swap pairs of jewels");
1618 rb
->lcd_puts(0, 3, "to form connected");
1619 rb
->lcd_puts(0, 4, "segments of three or ");
1620 rb
->lcd_puts(0, 5, "more of the");
1621 rb
->lcd_puts(0, 6, "same type.");
1622 rb
->lcd_puts(0, 8, "Controls:");
1623 rb
->lcd_puts(0, 9, "Directions or scroll to move");
1624 rb
->lcd_puts(0, 10, "PLAY to select");
1625 rb
->lcd_puts(0, 11, "Long PLAY for menu");
1626 rb
->lcd_puts(0, 12, "REC to cancel");
1627 #elif CONFIG_KEYPAD == COWOND2_PAD
1628 rb
->lcd_puts(0, 11, "POWER to cancel");
1629 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
1630 rb
->lcd_puts(0, 2, "Swap pairs of jewels to");
1631 rb
->lcd_puts(0, 3, "form connected segments");
1632 rb
->lcd_puts(0, 4, "of three or more of the");
1633 rb
->lcd_puts(0, 5, "same type.");
1634 rb
->lcd_puts(0, 7, "Controls:");
1635 rb
->lcd_puts(0, 8, "Directions to move");
1636 rb
->lcd_puts(0, 9, "SELECT to select");
1637 rb
->lcd_puts(0, 10, "Long SELECT to show menu");
1638 rb
->lcd_puts(0, 11, "BACK to cancel");
1639 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
1640 rb
->lcd_puts(0, 2, "Swap pairs of jewels to");
1641 rb
->lcd_puts(0, 3, "form connected segments");
1642 rb
->lcd_puts(0, 4, "of three or more of the");
1643 rb
->lcd_puts(0, 5, "same type.");
1644 rb
->lcd_puts(0, 7, "Controls:");
1645 rb
->lcd_puts(0, 8, "Directions to move");
1646 rb
->lcd_puts(0, 9, "MIDDLE to select");
1647 rb
->lcd_puts(0, 10, "Long MIDDLE to show menu");
1648 rb
->lcd_puts(0, 11, "BACK to cancel");
1649 #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
1650 rb
->lcd_puts(0, 2, "Swap pairs of jewels to");
1651 rb
->lcd_puts(0, 3, "form connected segments");
1652 rb
->lcd_puts(0, 4, "of three or more of the");
1653 rb
->lcd_puts(0, 5, "same type.");
1654 rb
->lcd_puts(0, 7, "Controls:");
1655 rb
->lcd_puts(0, 8, "Directions to move");
1656 rb
->lcd_puts(0, 9, "SELECT/PLAY to select");
1657 rb
->lcd_puts(0, 10, "Long SELECT to show menu");
1658 rb
->lcd_puts(0, 11, "POWER to cancel");
1660 #warning: missing help text.
1663 #ifdef HAVE_TOUCHSCREEN
1664 rb
->lcd_puts(0, 2, "Swap pairs of jewels to");
1665 rb
->lcd_puts(0, 3, "form connected segments");
1666 rb
->lcd_puts(0, 4, "of three or more of the");
1667 rb
->lcd_puts(0, 5, "same type.");
1668 rb
->lcd_puts(0, 7, "Controls:");
1669 rb
->lcd_puts(0, 8, "Directions to move");
1670 rb
->lcd_puts(0, 9, "CENTER to select");
1671 rb
->lcd_puts(0, 10, "Long CENTER to show menu");
1675 button
= rb
->button_get(true);
1676 if(button
!= BUTTON_NONE
&& !(button
&BUTTON_REL
)) break;
1678 rb
->lcd_clear_display();
1688 /* handle menu button presses */
1689 button
= rb
->button_get(true);
1691 #ifdef JEWELS_SCROLLWHEEL
1693 case (JEWELS_PREV
|BUTTON_REPEAT
):
1696 case (JEWELS_UP
|BUTTON_REPEAT
):
1700 #ifdef JEWELS_SCROLLWHEEL
1702 case (JEWELS_NEXT
|BUTTON_REPEAT
):
1705 case (JEWELS_DOWN
|BUTTON_REPEAT
):
1714 #ifdef JEWELS_CANCEL
1715 #ifdef JEWELS_RC_CANCEL
1716 case JEWELS_RC_CANCEL
:
1723 if(rb
->default_event_handler_ex(button
, jewels_callback
,
1724 (void*) bj
) == SYS_USB_CONNECTED
)
1730 /********************
1732 ********************/
1735 /********************
1737 ********************/
1738 bj
->score
+= jewels_initlevel(bj
);
1739 if (!jewels_movesavail(bj
)) {
1741 case GAME_TYPE_NORMAL
:
1744 case GAME_TYPE_PUZZLE
:
1746 rb
->splash(2*HZ
, "No more moves!");
1747 bj
->score
+= jewels_initlevel(bj
);
1748 } while(!jewels_movesavail(bj
));
1753 /**********************
1755 **********************/
1757 int no_movesavail
= false;
1760 /* refresh the board */
1761 jewels_drawboard(bj
);
1763 /* display the cursor */
1765 rb
->lcd_set_drawmode(DRMODE_COMPLEMENT
);
1766 rb
->lcd_fillrect(x
*TILE_WIDTH
, y
*TILE_HEIGHT
+YOFS
,
1767 TILE_WIDTH
, TILE_HEIGHT
);
1768 rb
->lcd_set_drawmode(DRMODE_SOLID
);
1770 rb
->lcd_drawrect(x
*TILE_WIDTH
, y
*TILE_HEIGHT
+YOFS
,
1771 TILE_WIDTH
, TILE_HEIGHT
);
1773 rb
->lcd_update_rect(x
*TILE_WIDTH
, y
*TILE_HEIGHT
+YOFS
,
1774 TILE_WIDTH
, TILE_HEIGHT
);
1776 res
= jewels_showmenu(&bjmenu
[1], cmd
);
1785 playback_control(NULL
);
1786 rb
->lcd_setfont(FONT_SYSFIXED
);
1792 rb
->splash(HZ
, "Saving game...");
1793 jewels_savegame(bj
);
1800 return BJ_QUIT_FROM_GAME
;
1807 /* handle game button presses */
1809 button
= rb
->button_get(true);
1811 case JEWELS_LEFT
: /* move cursor left */
1812 case (JEWELS_LEFT
|BUTTON_REPEAT
):
1815 bj
->score
+= jewels_swapjewels(bj
, x
, y
, SWAP_LEFT
);
1817 if (!jewels_movesavail(bj
)) no_movesavail
= true;
1819 x
= (x
+BJ_WIDTH
-1)%BJ_WIDTH
;
1824 case JEWELS_RIGHT
: /* move cursor right */
1825 case (JEWELS_RIGHT
|BUTTON_REPEAT
):
1828 bj
->score
+= jewels_swapjewels(bj
, x
, y
, SWAP_RIGHT
);
1830 if (!jewels_movesavail(bj
)) no_movesavail
= true;
1839 case JEWELS_DOWN
: /* move cursor down */
1840 case (JEWELS_DOWN
|BUTTON_REPEAT
):
1843 bj
->score
+= jewels_swapjewels(bj
, x
, y
, SWAP_DOWN
);
1845 if (!jewels_movesavail(bj
)) no_movesavail
= true;
1847 y
= (y
+1)%(BJ_HEIGHT
-1);
1854 case JEWELS_UP
: /* move cursor up */
1855 case (JEWELS_UP
|BUTTON_REPEAT
):
1858 bj
->score
+= jewels_swapjewels(bj
, x
, y
, SWAP_UP
);
1860 if (!jewels_movesavail(bj
)) no_movesavail
= true;
1862 y
= (y
+(BJ_HEIGHT
-1)-1)%(BJ_HEIGHT
-1);
1869 #ifdef JEWELS_SCROLLWHEEL
1870 case JEWELS_PREV
: /* scroll backwards */
1871 case (JEWELS_PREV
|BUTTON_REPEAT
):
1875 y
= (y
+(BJ_HEIGHT
-1)-1)%(BJ_HEIGHT
-1);
1877 x
= (x
+BJ_WIDTH
-1)%BJ_WIDTH
;
1884 case JEWELS_NEXT
: /* scroll forwards */
1885 case (JEWELS_NEXT
|BUTTON_REPEAT
):
1888 if(x
== BJ_WIDTH
-1) {
1889 y
= (y
+1)%(BJ_HEIGHT
-1);
1899 case JEWELS_SELECT
: /* toggle selected */
1901 selected
= !selected
;
1907 case (JEWELS_SELECT
|BUTTON_REPEAT
): /* show menu */
1908 if(!inmenu
) inmenu
= true;
1911 #ifdef JEWELS_CANCEL
1912 #ifdef JEWELS_RC_CANCEL
1913 case JEWELS_RC_CANCEL
:
1915 case JEWELS_CANCEL
: /* end game */
1921 if(rb
->default_event_handler_ex(button
, jewels_callback
,
1922 (void*) bj
) == SYS_USB_CONNECTED
)
1927 if (no_movesavail
) {
1929 case GAME_TYPE_NORMAL
:
1932 case GAME_TYPE_PUZZLE
:
1934 rb
->splash(2*HZ
, "No more moves!");
1935 bj
->score
+= jewels_initlevel(bj
);
1936 } while(!jewels_movesavail(bj
));
1942 case GAME_TYPE_NORMAL
:
1943 if(bj
->score
>= LEVEL_PTS
)
1944 jewels_nextlevel(bj
);
1947 case GAME_TYPE_PUZZLE
:
1948 if(jewels_puzzle_is_finished(bj
))
1949 jewels_nextlevel(bj
);
1955 /*****************************************************************************
1956 * plugin entry point.
1957 ******************************************************************************/
1958 enum plugin_status
plugin_start(const void* parameter
) {
1959 struct game_context bj
;
1966 /* end of plugin init */
1968 /* load high scores */
1969 jewels_loadscores(&bj
);
1971 rb
->lcd_setfont(FONT_SYSFIXED
);
1973 rb
->lcd_set_backdrop(NULL
);
1978 switch(jewels_main(&bj
)){
1980 rb
->splash(HZ
*2, "No more moves!");
1981 /* fall through to BJ_END */
1985 if((position
= jewels_recordscore(&bj
))) {
1986 rb
->snprintf(str
, 19, "New high score #%d!", position
);
1987 rb
->splash(HZ
*2, str
);
1993 rb
->lcd_setfont(FONT_UI
);
1994 return PLUGIN_USB_CONNECTED
;
1998 rb
->splash(HZ
, "Saving high scores...");
1999 jewels_savescores(&bj
);
2004 case BJ_QUIT_FROM_GAME
:
2006 if((position
= jewels_recordscore(&bj
))) {
2007 rb
->snprintf(str
, 19, "New high score #%d!", position
);
2008 rb
->splash(HZ
*2, str
);
2012 rb
->splash(HZ
, "Saving high scores...");
2013 jewels_savescores(&bj
);
2023 rb
->lcd_setfont(FONT_UI
);
2027 #endif /* HAVE_LCD_BITMAP */