1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 Vicentini Martin
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
22 #ifdef HAVE_LCD_BITMAP
25 /* variable button definitions */
26 #if CONFIG_KEYPAD == RECORDER_PAD
27 #define PUZZLE_QUIT BUTTON_OFF
28 #define PUZZLE_LEFT BUTTON_LEFT
29 #define PUZZLE_RIGHT BUTTON_RIGHT
30 #define PUZZLE_UP BUTTON_UP
31 #define PUZZLE_DOWN BUTTON_DOWN
32 #define PUZZLE_SHUFFLE BUTTON_F1
33 #define PUZZLE_PICTURE BUTTON_F2
35 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
36 #define PUZZLE_QUIT BUTTON_OFF
37 #define PUZZLE_LEFT BUTTON_LEFT
38 #define PUZZLE_RIGHT BUTTON_RIGHT
39 #define PUZZLE_UP BUTTON_UP
40 #define PUZZLE_DOWN BUTTON_DOWN
41 #define PUZZLE_SHUFFLE BUTTON_F1
42 #define PUZZLE_PICTURE BUTTON_F2
44 #elif CONFIG_KEYPAD == ONDIO_PAD
45 #define PUZZLE_QUIT BUTTON_OFF
46 #define PUZZLE_LEFT BUTTON_LEFT
47 #define PUZZLE_RIGHT BUTTON_RIGHT
48 #define PUZZLE_UP BUTTON_UP
49 #define PUZZLE_DOWN BUTTON_DOWN
50 #define PUZZLE_SHUFFLE_PICTURE_PRE BUTTON_MENU
51 #define PUZZLE_SHUFFLE (BUTTON_MENU | BUTTON_REPEAT)
52 #define PUZZLE_PICTURE (BUTTON_MENU | BUTTON_REL)
54 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
55 (CONFIG_KEYPAD == IRIVER_H300_PAD)
56 #define PUZZLE_QUIT BUTTON_OFF
57 #define PUZZLE_LEFT BUTTON_LEFT
58 #define PUZZLE_RIGHT BUTTON_RIGHT
59 #define PUZZLE_UP BUTTON_UP
60 #define PUZZLE_DOWN BUTTON_DOWN
61 #define PUZZLE_SHUFFLE BUTTON_SELECT
62 #define PUZZLE_PICTURE BUTTON_ON
64 #define PUZZLE_RC_QUIT BUTTON_RC_STOP
66 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
67 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
68 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
69 #define PUZZLE_QUIT (BUTTON_SELECT | BUTTON_MENU)
70 #define PUZZLE_LEFT BUTTON_LEFT
71 #define PUZZLE_RIGHT BUTTON_RIGHT
72 #define PUZZLE_UP BUTTON_MENU
73 #define PUZZLE_DOWN BUTTON_PLAY
74 #define PUZZLE_SHUFFLE (BUTTON_SELECT | BUTTON_LEFT)
75 #define PUZZLE_PICTURE (BUTTON_SELECT | BUTTON_RIGHT)
77 #elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
78 #define PUZZLE_QUIT BUTTON_POWER
79 #define PUZZLE_LEFT BUTTON_LEFT
80 #define PUZZLE_RIGHT BUTTON_RIGHT
81 #define PUZZLE_UP BUTTON_UP
82 #define PUZZLE_DOWN BUTTON_DOWN
83 #define PUZZLE_SHUFFLE BUTTON_REC
84 #define PUZZLE_PICTURE BUTTON_PLAY
86 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
87 #define PUZZLE_QUIT BUTTON_POWER
88 #define PUZZLE_LEFT BUTTON_LEFT
89 #define PUZZLE_RIGHT BUTTON_RIGHT
90 #define PUZZLE_UP BUTTON_UP
91 #define PUZZLE_DOWN BUTTON_DOWN
92 #define PUZZLE_SHUFFLE BUTTON_SELECT
93 #define PUZZLE_PICTURE BUTTON_A
95 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
96 (CONFIG_KEYPAD == SANSA_C200_PAD)
97 #define PUZZLE_QUIT BUTTON_POWER
98 #define PUZZLE_LEFT BUTTON_LEFT
99 #define PUZZLE_RIGHT BUTTON_RIGHT
100 #define PUZZLE_UP BUTTON_UP
101 #define PUZZLE_DOWN BUTTON_DOWN
102 #define PUZZLE_SHUFFLE BUTTON_REC
103 #define PUZZLE_PICTURE BUTTON_SELECT
105 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
106 #define PUZZLE_QUIT BUTTON_POWER
107 #define PUZZLE_LEFT BUTTON_LEFT
108 #define PUZZLE_RIGHT BUTTON_RIGHT
109 #define PUZZLE_UP BUTTON_SCROLL_UP
110 #define PUZZLE_DOWN BUTTON_SCROLL_DOWN
111 #define PUZZLE_SHUFFLE BUTTON_REW
112 #define PUZZLE_PICTURE BUTTON_PLAY
114 #elif (CONFIG_KEYPAD == GIGABEAT_S_PAD)
115 #define PUZZLE_QUIT BUTTON_BACK
116 #define PUZZLE_LEFT BUTTON_LEFT
117 #define PUZZLE_RIGHT BUTTON_RIGHT
118 #define PUZZLE_UP BUTTON_UP
119 #define PUZZLE_DOWN BUTTON_DOWN
120 #define PUZZLE_SHUFFLE BUTTON_SELECT
121 #define PUZZLE_PICTURE BUTTON_MENU
123 #elif (CONFIG_KEYPAD == MROBE100_PAD)
124 #define PUZZLE_QUIT BUTTON_POWER
125 #define PUZZLE_LEFT BUTTON_LEFT
126 #define PUZZLE_RIGHT BUTTON_RIGHT
127 #define PUZZLE_UP BUTTON_UP
128 #define PUZZLE_DOWN BUTTON_DOWN
129 #define PUZZLE_SHUFFLE BUTTON_SELECT
130 #define PUZZLE_PICTURE BUTTON_DISPLAY
132 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
133 #define PUZZLE_QUIT BUTTON_RC_REC
134 #define PUZZLE_LEFT BUTTON_RC_REW
135 #define PUZZLE_RIGHT BUTTON_RC_FF
136 #define PUZZLE_UP BUTTON_RC_VOL_UP
137 #define PUZZLE_DOWN BUTTON_RC_VOL_DOWN
138 #define PUZZLE_SHUFFLE BUTTON_RC_MODE
139 #define PUZZLE_PICTURE BUTTON_RC_MENU
141 #elif (CONFIG_KEYPAD == COWOND2_PAD)
142 #define PUZZLE_QUIT BUTTON_POWER
143 #define PUZZLE_QUIT_TEXT "[POWER]"
146 #error No keymap defined!
151 #define PUZZLE_QUIT BUTTON_TOPLEFT
154 #define PUZZLE_LEFT BUTTON_MIDLEFT
157 #define PUZZLE_RIGHT BUTTON_MIDRIGHT
160 #define PUZZLE_UP BUTTON_TOPMIDDLE
163 #define PUZZLE_DOWN BUTTON_BOTTOMMIDDLE
165 #ifndef PUZZLE_SHUFFLE
166 #define PUZZLE_SHUFFLE BUTTON_BOTTOMLEFT
168 #ifndef PUZZLE_PICTURE
169 #define PUZZLE_PICTURE BUTTON_CENTER
171 #ifndef PUZZLE_QUIT_TEXT
172 #define PUZZLE_QUIT_TEXT "[TOPLEFT]"
174 #ifndef PUZZLE_SHUFFLE_TEXT
175 #define PUZZLE_SHUFFLE_TEXT "[BOTTOMLEFT]"
177 #ifndef PUZZLE_PICTURE_TEXT
178 #define PUZZLE_PICTURE_TEXT "[CENTER]"
182 #include "sliding_puzzle.h"
183 #define IMAGE_WIDTH BMPWIDTH_sliding_puzzle
184 #define IMAGE_HEIGHT BMPHEIGHT_sliding_puzzle
185 #define IMAGE_SIZE IMAGE_WIDTH
187 static const struct plugin_api
* rb
;
189 /* use a square image, (the default Archos bitmap looks square on its display)
190 Puzzle image dimension is min(lcd_height,lcd_width)
191 4x4 is more convenient for square puzzles
192 Note: sliding_puzzle.bmp should be evenly divisible by SPOTS_X
193 and SPOTS_Y, otherwise lcd_bitmap_part stride won't be correct */
196 #define SPOTS_WIDTH (IMAGE_WIDTH / SPOTS_X)
197 #define SPOTS_HEIGHT (IMAGE_HEIGHT / SPOTS_Y)
198 #define NUM_SPOTS (SPOTS_X*SPOTS_Y)
199 #define HOLE_ID (NUM_SPOTS)
200 #define INITIAL_HOLE (HOLE_ID-1)
204 PICMODE_NUMERALS
= 0,
205 PICMODE_INITIAL_PICTURE
,
206 PICMODE_DEFAULT_PICTURE
,
211 PICMODE_LAST_XXX
/* placeholder */
214 static const char* const picmode_descriptions
[] = {
221 "Shouldn't Get Here",
224 static int spots
[NUM_SPOTS
];
225 static int hole
= INITIAL_HOLE
, moves
;
226 static unsigned char s
[32];
227 static enum picmodes picmode
= PICMODE_INITIAL_PICTURE
;
228 static int num_font
= FONT_UI
;
229 static int moves_font
= FONT_UI
;
230 static int moves_y
= 0;
232 static unsigned char img_buf
[IMAGE_WIDTH
*IMAGE_HEIGHT
*sizeof(fb_data
)]
233 __attribute__ ((aligned(16)));
235 static unsigned char temp_img_buf
[LCD_WIDTH
*LCD_HEIGHT
*sizeof(fb_data
)]
236 __attribute__ ((aligned(16)));
239 static char albumart_path
[MAX_PATH
+1];
241 static char img_buf_path
[MAX_PATH
+1];
243 static const fb_data
* puzzle_bmp_ptr
;
244 /* initial_bmp_path points to selected bitmap if this game is launched
245 as a viewer for a .bmp file, or NULL if game is launched regular way */
246 static const char * initial_bmp_path
=NULL
;
249 const char * get_albumart_bmp_path(void)
251 struct mp3entry
* track
= rb
->audio_current_track();
253 if (!track
|| !track
->path
|| track
->path
[0] == '\0')
256 if (!rb
->search_albumart_files(track
, "", albumart_path
, MAX_PATH
) )
259 albumart_path
[ MAX_PATH
] = '\0';
260 return albumart_path
;
264 const char * get_random_bmp_path(void)
266 return(initial_bmp_path
);
269 static bool load_resize_bitmap(void)
272 const char * filename
= NULL
;
274 /* initially assume using the built-in default */
275 puzzle_bmp_ptr
= sliding_puzzle
;
278 /* some modes don't even need to touch disk and trivially succeed */
279 case PICMODE_NUMERALS
:
280 case PICMODE_DEFAULT_PICTURE
:
285 case PICMODE_ALBUM_ART
:
286 filename
= get_albumart_bmp_path();
291 if(NULL == (filename=get_random_bmp_path()) )
292 filename = initial_bmp_path;
295 case PICMODE_INITIAL_PICTURE
:
296 filename
= initial_bmp_path
;
300 if( filename
!= NULL
)
302 /* if we already loaded image before, don't touch disk */
303 if( 0 == rb
->strcmp( filename
, img_buf_path
) )
305 puzzle_bmp_ptr
= (const fb_data
*)img_buf
;
309 struct bitmap main_bitmap
;
310 rb
->memset(&main_bitmap
,0,sizeof(struct bitmap
));
311 main_bitmap
.data
= img_buf
;
314 struct bitmap temp_bitmap
;
315 rb
->memset(&temp_bitmap
,0,sizeof(struct bitmap
));
316 temp_bitmap
.data
= temp_img_buf
;
318 main_bitmap
.width
= IMAGE_WIDTH
;
319 main_bitmap
.height
= IMAGE_HEIGHT
;
321 rc
= rb
->read_bmp_file( filename
, &temp_bitmap
, sizeof(temp_img_buf
),
325 #ifdef HAVE_LCD_COLOR
326 smooth_resize_bitmap( &temp_bitmap
, &main_bitmap
);
328 simple_resize_bitmap( &temp_bitmap
, &main_bitmap
);
330 puzzle_bmp_ptr
= (const fb_data
*)img_buf
;
331 rb
->strcpy( img_buf_path
, filename
);
335 rc
= rb
->read_bmp_file( filename
, &main_bitmap
, sizeof(img_buf
),
339 puzzle_bmp_ptr
= (const fb_data
*)img_buf
;
340 rb
->strcpy( img_buf_path
, filename
);
346 /* something must have failed. get_albumart_bmp_path could return
347 NULL if albumart doesn't exist or couldn't be loaded, or
348 read_bmp_file could have failed. return false and caller should
349 try the next mode (PICMODE_DEFAULT_PICTURE and PICMODE_NUMERALS will
354 /* draws a spot at the coordinates (x,y), range of p is 1-20 */
355 static void draw_spot(int p
, int x
, int y
)
362 /* the bottom-right cell of the default sliding_puzzle image is
363 an appropriate hole graphic */
364 rb
->lcd_bitmap_part(sliding_puzzle
, ((p
-1)%SPOTS_X
)*SPOTS_WIDTH
,
365 ((p
-1)/SPOTS_X
)*SPOTS_HEIGHT
,
366 IMAGE_WIDTH
, x
, y
, SPOTS_WIDTH
, SPOTS_HEIGHT
);
368 /* just draw a black rectangle */
369 int old_fg
= rb
->lcd_get_foreground();
370 rb
->lcd_set_foreground(LCD_BLACK
);
371 rb
->lcd_fillrect(x
,y
,SPOTS_WIDTH
,SPOTS_HEIGHT
);
372 rb
->lcd_set_foreground(old_fg
);
375 else if (picmode
!= PICMODE_NUMERALS
)
377 rb
->lcd_bitmap_part( puzzle_bmp_ptr
, ((p
-1)%SPOTS_X
)*SPOTS_WIDTH
,
378 ((p
-1)/SPOTS_X
)*SPOTS_HEIGHT
,
379 IMAGE_WIDTH
, x
, y
, SPOTS_WIDTH
, SPOTS_HEIGHT
);
381 rb
->lcd_drawrect(x
, y
, SPOTS_WIDTH
, SPOTS_HEIGHT
);
382 rb
->lcd_set_drawmode(DRMODE_SOLID
|DRMODE_INVERSEVID
);
383 rb
->lcd_fillrect(x
+1, y
+1, SPOTS_WIDTH
-2, SPOTS_HEIGHT
-2);
384 rb
->lcd_set_drawmode(DRMODE_SOLID
);
385 rb
->snprintf(s
, sizeof(s
), "%d", p
);
386 rb
->lcd_setfont(num_font
);
387 rb
->lcd_getstringsize(s
, &w
, &h
);
388 rb
->lcd_putsxy(x
+ (SPOTS_WIDTH
/2) - w
/ 2,
389 y
+ (SPOTS_HEIGHT
/2) - h
/ 2, s
);
393 /* check if the puzzle is solved */
394 static bool puzzle_finished(void)
397 for (i
=0; i
<NUM_SPOTS
; i
++)
398 if (spots
[i
] != (i
+1))
403 /* move a piece in any direction */
404 static void move_spot(int x
, int y
)
407 spots
[hole
] = spots
[hole
-x
-SPOTS_X
*y
];
408 hole
-= (x
+SPOTS_X
*y
);
410 rb
->lcd_setfont(moves_font
);
411 #if LCD_WIDTH > LCD_HEIGHT
412 rb
->snprintf(s
, sizeof(s
), "%d", moves
);
413 w
= rb
->lcd_getstringsize(s
, NULL
, NULL
);
414 rb
->lcd_putsxy((IMAGE_WIDTH
+1+(LCD_WIDTH
-IMAGE_WIDTH
-1)/2) - w
/ 2,
418 rb
->snprintf(s
, sizeof(s
), "Moves: %d", moves
);
419 rb
->lcd_putsxy(3, moves_y
, s
);
424 (hole
%SPOTS_X
)*SPOTS_WIDTH
,
425 (hole
/SPOTS_X
)*SPOTS_HEIGHT
);
426 draw_spot(spots
[hole
],
427 (hole
%SPOTS_X
)*SPOTS_WIDTH
+ (i
*x
*SPOTS_WIDTH
)/5,
428 (hole
/SPOTS_X
)*SPOTS_HEIGHT
+ (i
*y
*SPOTS_HEIGHT
)/5);
433 (hole
%SPOTS_X
)*SPOTS_WIDTH
,
434 (hole
/SPOTS_X
)*SPOTS_HEIGHT
);
435 draw_spot(spots
[hole
],
436 ((hole
%SPOTS_X
)+x
)*SPOTS_WIDTH
,
437 ((hole
/SPOTS_X
)+y
)*SPOTS_HEIGHT
);
440 spots
[hole
] = HOLE_ID
;
443 static void draw_playfield(void)
447 rb
->lcd_clear_display();
448 rb
->lcd_setfont(moves_font
);
449 #if LCD_WIDTH > LCD_HEIGHT
450 rb
->lcd_vline(IMAGE_WIDTH
, 0, LCD_HEIGHT
-1);
451 w
= rb
->lcd_getstringsize("Moves", NULL
, NULL
);
452 rb
->lcd_putsxy((IMAGE_WIDTH
+1+(LCD_WIDTH
-IMAGE_WIDTH
-1)/2) - w
/ 2,
454 rb
->snprintf(s
, sizeof(s
), "%d", moves
);
455 w
= rb
->lcd_getstringsize(s
, NULL
, NULL
);
456 rb
->lcd_putsxy((IMAGE_WIDTH
+1+(LCD_WIDTH
-IMAGE_WIDTH
-1)/2) - w
/ 2,
460 rb
->lcd_hline(0, LCD_WIDTH
-1, IMAGE_HEIGHT
);
461 rb
->snprintf(s
, sizeof(s
), "Moves: %d", moves
);
462 rb
->lcd_putsxy(3, moves_y
, s
);
465 /* draw spots to the lcd */
466 for (i
=0; i
<NUM_SPOTS
; i
++)
467 draw_spot(spots
[i
], (i
%SPOTS_X
)*SPOTS_WIDTH
, (i
/SPOTS_X
)*SPOTS_HEIGHT
);
472 /* initializes the puzzle */
473 static void puzzle_init(void)
475 int i
, r
, temp
, tsp
[NUM_SPOTS
];
480 for (i
=NUM_SPOTS
-1; i
>=0; i
--) {
481 r
= (rb
->rand() % (i
+1));
487 if (spots
[i
]==HOLE_ID
)
491 /* test if the puzzle is solvable */
492 for (i
=0; i
<NUM_SPOTS
; i
++)
496 /* First, check if the problem has even or odd parity,
497 depending on where the empty square is */
498 if ((((SPOTS_X
-1)-hole
%SPOTS_X
) + ((SPOTS_Y
-1)-hole
/SPOTS_X
))%2 == 1)
501 /* Now check how many swaps we need to solve it */
502 for (i
=0; i
<NUM_SPOTS
-1; i
++) {
503 while (tsp
[i
] != (i
+1)) {
505 tsp
[i
] = tsp
[temp
-1];
511 /* if the random puzzle isn't solvable just change two spots */
513 if (spots
[0]!=HOLE_ID
&& spots
[1]!=HOLE_ID
) {
527 /* the main game loop */
528 static int puzzle_loop(void)
531 int lastbutton
= BUTTON_NONE
;
536 button
= rb
->button_get(true);
538 #ifdef PUZZLE_RC_QUIT
542 /* get out of here */
546 #ifdef PUZZLE_SHUFFLE_PICTURE_PRE
547 if (lastbutton
!= PUZZLE_SHUFFLE_PICTURE_PRE
)
550 /* mix up the pieces */
555 #ifdef PUZZLE_SHUFFLE_PICTURE_PRE
556 if (lastbutton
!= PUZZLE_SHUFFLE_PICTURE_PRE
)
560 picmode
= (picmode
+1)%PICMODE_LAST_XXX
;
562 /* if load_resize_bitmap fails to load bitmap, try next picmode */
565 load_success
= load_resize_bitmap();
567 picmode
= (picmode
+1)%PICMODE_LAST_XXX
;
569 while( !load_success
);
571 /* tell the user what mode we picked in the end! */
572 rb
->splash(HZ
,picmode_descriptions
[ picmode
] );
577 if ((hole
%SPOTS_X
)<(SPOTS_X
-1) && !puzzle_finished())
582 if ((hole
%SPOTS_X
)>0 && !puzzle_finished())
587 if ((hole
/SPOTS_X
)<(SPOTS_Y
-1) && !puzzle_finished())
592 if ((hole
/SPOTS_X
)>0 && !puzzle_finished())
597 if (rb
->default_event_handler(button
) == SYS_USB_CONNECTED
)
598 return PLUGIN_USB_CONNECTED
;
601 if (button
!= BUTTON_NONE
)
606 enum plugin_status
plugin_start(const struct plugin_api
* api
, const void* parameter
)
612 initial_bmp_path
=(const char *)parameter
;
613 picmode
= PICMODE_INITIAL_PICTURE
;
614 img_buf_path
[0] = '\0';
616 /* If launched as a viewer, just go straight to the game without
617 bothering with the splash or instructions page */
620 /* if not launched as a viewer, use default puzzle, and show help */
621 picmode
= PICMODE_DEFAULT_PICTURE
;
624 rb
->lcd_getstringsize((unsigned char *)"Sliding Puzzle", &w
, &h
);
627 rb
->lcd_clear_display();
628 rb
->lcd_putsxy(LCD_WIDTH
/2-w
, (LCD_HEIGHT
/2)-h
,
629 (unsigned char *)"Sliding Puzzle");
633 /* print instructions */
634 rb
->lcd_clear_display();
635 rb
->lcd_setfont(FONT_SYSFIXED
);
636 #if CONFIG_KEYPAD == RECORDER_PAD || CONFIG_KEYPAD == ARCHOS_AV300_PAD
637 rb
->lcd_putsxy(3, 18, "[OFF] to stop");
638 rb
->lcd_putsxy(3, 28, "[F1] shuffle");
639 rb
->lcd_putsxy(3, 38, "[F2] change pic");
640 #elif CONFIG_KEYPAD == ONDIO_PAD
641 rb
->lcd_putsxy(0, 18, "[OFF] to stop");
642 rb
->lcd_putsxy(0, 28, "[MODE..] shuffle");
643 rb
->lcd_putsxy(0, 38, "[MODE] change pic");
644 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
645 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
646 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
647 rb
->lcd_putsxy(0, 18, "[S-MENU] to stop");
648 rb
->lcd_putsxy(0, 28, "[S-LEFT] shuffle");
649 rb
->lcd_putsxy(0, 38, "[S-RIGHT] change pic");
650 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
651 (CONFIG_KEYPAD == IRIVER_H300_PAD)
652 rb
->lcd_putsxy(0, 18, "[STOP] to stop");
653 rb
->lcd_putsxy(0, 28, "[SELECT] shuffle");
654 rb
->lcd_putsxy(0, 38, "[PLAY] change pic");
655 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
656 rb
->lcd_putsxy(0, 18, "[OFF] to stop");
657 rb
->lcd_putsxy(0, 28, "[REC] shuffle");
658 rb
->lcd_putsxy(0, 38, "[PLAY] change pic");
659 #elif CONFIG_KEYPAD == GIGABEAT_PAD
660 rb
->lcd_putsxy(0, 18, "[OFF] to stop");
661 rb
->lcd_putsxy(0, 28, "[SELECT] shuffle");
662 rb
->lcd_putsxy(0, 38, "[A] change pic");
663 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
664 (CONFIG_KEYPAD == SANSA_C200_PAD)
665 rb
->lcd_putsxy(0, 18, "[OFF] to stop");
666 rb
->lcd_putsxy(0, 28, "[REC] shuffle");
667 rb
->lcd_putsxy(0, 38, "[SELECT] change pic");
668 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
669 rb
->lcd_putsxy(0, 18, "[OFF] to stop");
670 rb
->lcd_putsxy(0, 28, "[REW] shuffle");
671 rb
->lcd_putsxy(0, 38, "[PLAY] change pic");
672 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
673 rb
->lcd_putsxy(0, 18, "[REC] to stop");
674 rb
->lcd_putsxy(0, 28, "[MODE] shuffle");
675 rb
->lcd_putsxy(0, 38, "[MENU] change pic");
678 rb
->lcd_putsxy(0, 18, PUZZLE_QUIT_TEXT
" to stop");
679 rb
->lcd_putsxy(0, 28, PUZZLE_SHUFFLE_TEXT
" shuffle");
680 rb
->lcd_putsxy(0, 38, PUZZLE_PICTURE_TEXT
" change pic");
683 rb
->lcd_putsxy(0,48," pic->albumart->num");
685 rb
->lcd_putsxy(0,48," pic<->num");
688 rb
->button_get_w_tmo(HZ
*2);
693 if( !load_resize_bitmap() )
695 rb
->lcd_clear_display();
696 rb
->splash(HZ
*2,"Failed to load bitmap!");
700 /* Calculate possible font sizes and text positions */
701 rb
->lcd_setfont(FONT_UI
);
702 rb
->lcd_getstringsize("15", &w
, &h
);
703 if ((w
> (SPOTS_WIDTH
-2)) || (h
> (SPOTS_HEIGHT
-2)))
704 num_font
= FONT_SYSFIXED
;
706 #if LCD_WIDTH > LCD_HEIGHT
707 rb
->lcd_getstringsize("Moves", &w
, &h
);
708 if (w
> (LCD_WIDTH
-IMAGE_WIDTH
-1))
709 moves_font
= FONT_SYSFIXED
;
710 rb
->lcd_setfont(moves_font
);
711 rb
->lcd_getstringsize("Moves", &w
, &h
);
714 rb
->lcd_getstringsize("Moves: 999", &w
, &h
);
715 if ((w
> LCD_WIDTH
) || (h
> (LCD_HEIGHT
-IMAGE_HEIGHT
-1)))
716 moves_font
= FONT_SYSFIXED
;
717 rb
->lcd_setfont(moves_font
);
718 rb
->lcd_getstringsize("Moves: 999", &w
, &h
);
719 moves_y
= (IMAGE_HEIGHT
+1+(LCD_HEIGHT
-IMAGE_HEIGHT
-1)/2) - h
/ 2;
721 for (i
=0; i
<NUM_SPOTS
; i
++)
724 #ifdef HAVE_LCD_COLOR
725 rb
->lcd_set_background(LCD_BLACK
);
726 rb
->lcd_set_foreground(LCD_WHITE
);
727 rb
->lcd_set_backdrop(NULL
);
729 rb
->lcd_set_background(LCD_WHITE
);
730 rb
->lcd_set_foreground(LCD_BLACK
);
731 rb
->lcd_set_backdrop(NULL
);
737 return puzzle_loop();