1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 Vicentini Martin
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 #ifdef HAVE_LCD_BITMAP
26 /* variable button definitions */
27 #if CONFIG_KEYPAD == RECORDER_PAD
28 #define PUZZLE_QUIT BUTTON_OFF
29 #define PUZZLE_LEFT BUTTON_LEFT
30 #define PUZZLE_RIGHT BUTTON_RIGHT
31 #define PUZZLE_UP BUTTON_UP
32 #define PUZZLE_DOWN BUTTON_DOWN
33 #define PUZZLE_SHUFFLE BUTTON_F1
34 #define PUZZLE_PICTURE BUTTON_F2
36 #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
37 #define PUZZLE_QUIT BUTTON_OFF
38 #define PUZZLE_LEFT BUTTON_LEFT
39 #define PUZZLE_RIGHT BUTTON_RIGHT
40 #define PUZZLE_UP BUTTON_UP
41 #define PUZZLE_DOWN BUTTON_DOWN
42 #define PUZZLE_SHUFFLE BUTTON_F1
43 #define PUZZLE_PICTURE BUTTON_F2
45 #elif CONFIG_KEYPAD == ONDIO_PAD
46 #define PUZZLE_QUIT BUTTON_OFF
47 #define PUZZLE_LEFT BUTTON_LEFT
48 #define PUZZLE_RIGHT BUTTON_RIGHT
49 #define PUZZLE_UP BUTTON_UP
50 #define PUZZLE_DOWN BUTTON_DOWN
51 #define PUZZLE_SHUFFLE_PICTURE_PRE BUTTON_MENU
52 #define PUZZLE_SHUFFLE (BUTTON_MENU | BUTTON_REPEAT)
53 #define PUZZLE_PICTURE (BUTTON_MENU | BUTTON_REL)
55 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
56 (CONFIG_KEYPAD == IRIVER_H300_PAD)
57 #define PUZZLE_QUIT BUTTON_OFF
58 #define PUZZLE_LEFT BUTTON_LEFT
59 #define PUZZLE_RIGHT BUTTON_RIGHT
60 #define PUZZLE_UP BUTTON_UP
61 #define PUZZLE_DOWN BUTTON_DOWN
62 #define PUZZLE_SHUFFLE BUTTON_SELECT
63 #define PUZZLE_PICTURE BUTTON_ON
65 #define PUZZLE_RC_QUIT BUTTON_RC_STOP
67 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
68 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
69 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
70 #define PUZZLE_QUIT (BUTTON_SELECT | BUTTON_MENU)
71 #define PUZZLE_LEFT BUTTON_LEFT
72 #define PUZZLE_RIGHT BUTTON_RIGHT
73 #define PUZZLE_UP BUTTON_MENU
74 #define PUZZLE_DOWN BUTTON_PLAY
75 #define PUZZLE_SHUFFLE (BUTTON_SELECT | BUTTON_LEFT)
76 #define PUZZLE_PICTURE (BUTTON_SELECT | BUTTON_RIGHT)
78 #elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
79 #define PUZZLE_QUIT BUTTON_POWER
80 #define PUZZLE_LEFT BUTTON_LEFT
81 #define PUZZLE_RIGHT BUTTON_RIGHT
82 #define PUZZLE_UP BUTTON_UP
83 #define PUZZLE_DOWN BUTTON_DOWN
84 #define PUZZLE_SHUFFLE BUTTON_REC
85 #define PUZZLE_PICTURE BUTTON_PLAY
87 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
88 #define PUZZLE_QUIT BUTTON_POWER
89 #define PUZZLE_LEFT BUTTON_LEFT
90 #define PUZZLE_RIGHT BUTTON_RIGHT
91 #define PUZZLE_UP BUTTON_UP
92 #define PUZZLE_DOWN BUTTON_DOWN
93 #define PUZZLE_SHUFFLE BUTTON_SELECT
94 #define PUZZLE_PICTURE BUTTON_A
96 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
97 (CONFIG_KEYPAD == SANSA_C200_PAD)
98 #define PUZZLE_QUIT BUTTON_POWER
99 #define PUZZLE_LEFT BUTTON_LEFT
100 #define PUZZLE_RIGHT BUTTON_RIGHT
101 #define PUZZLE_UP BUTTON_UP
102 #define PUZZLE_DOWN BUTTON_DOWN
103 #define PUZZLE_SHUFFLE BUTTON_REC
104 #define PUZZLE_PICTURE BUTTON_SELECT
106 #elif (CONFIG_KEYPAD == SANSA_FUZE_PAD)
107 #define PUZZLE_QUIT (BUTTON_HOME|BUTTON_REPEAT)
108 #define PUZZLE_LEFT BUTTON_LEFT
109 #define PUZZLE_RIGHT BUTTON_RIGHT
110 #define PUZZLE_UP BUTTON_UP
111 #define PUZZLE_DOWN BUTTON_DOWN
112 #define PUZZLE_SHUFFLE BUTTON_SELECT|BUTTON_DOWN
113 #define PUZZLE_PICTURE BUTTON_SELECT
115 #elif (CONFIG_KEYPAD == SANSA_CLIP_PAD)
116 #define PUZZLE_QUIT BUTTON_POWER
117 #define PUZZLE_LEFT BUTTON_LEFT
118 #define PUZZLE_RIGHT BUTTON_RIGHT
119 #define PUZZLE_UP BUTTON_UP
120 #define PUZZLE_DOWN BUTTON_DOWN
121 #define PUZZLE_SHUFFLE BUTTON_HOME
122 #define PUZZLE_PICTURE BUTTON_SELECT
124 #elif (CONFIG_KEYPAD == SANSA_M200_PAD)
125 #define PUZZLE_QUIT BUTTON_POWER
126 #define PUZZLE_LEFT BUTTON_LEFT
127 #define PUZZLE_RIGHT BUTTON_RIGHT
128 #define PUZZLE_UP BUTTON_UP
129 #define PUZZLE_DOWN BUTTON_DOWN
130 #define PUZZLE_SHUFFLE (BUTTON_SELECT | BUTTON_UP)
131 #define PUZZLE_PICTURE (BUTTON_SELECT | BUTTON_REL)
133 #elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
134 #define PUZZLE_QUIT BUTTON_POWER
135 #define PUZZLE_LEFT BUTTON_LEFT
136 #define PUZZLE_RIGHT BUTTON_RIGHT
137 #define PUZZLE_UP BUTTON_SCROLL_UP
138 #define PUZZLE_DOWN BUTTON_SCROLL_DOWN
139 #define PUZZLE_SHUFFLE BUTTON_REW
140 #define PUZZLE_PICTURE BUTTON_PLAY
142 #elif (CONFIG_KEYPAD == GIGABEAT_S_PAD)
143 #define PUZZLE_QUIT BUTTON_BACK
144 #define PUZZLE_LEFT BUTTON_LEFT
145 #define PUZZLE_RIGHT BUTTON_RIGHT
146 #define PUZZLE_UP BUTTON_UP
147 #define PUZZLE_DOWN BUTTON_DOWN
148 #define PUZZLE_SHUFFLE BUTTON_SELECT
149 #define PUZZLE_PICTURE BUTTON_MENU
151 #elif (CONFIG_KEYPAD == MROBE100_PAD)
152 #define PUZZLE_QUIT BUTTON_POWER
153 #define PUZZLE_LEFT BUTTON_LEFT
154 #define PUZZLE_RIGHT BUTTON_RIGHT
155 #define PUZZLE_UP BUTTON_UP
156 #define PUZZLE_DOWN BUTTON_DOWN
157 #define PUZZLE_SHUFFLE BUTTON_SELECT
158 #define PUZZLE_PICTURE BUTTON_DISPLAY
160 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
161 #define PUZZLE_QUIT BUTTON_RC_REC
162 #define PUZZLE_LEFT BUTTON_RC_REW
163 #define PUZZLE_RIGHT BUTTON_RC_FF
164 #define PUZZLE_UP BUTTON_RC_VOL_UP
165 #define PUZZLE_DOWN BUTTON_RC_VOL_DOWN
166 #define PUZZLE_SHUFFLE BUTTON_RC_MODE
167 #define PUZZLE_PICTURE BUTTON_RC_MENU
169 #elif (CONFIG_KEYPAD == COWON_D2_PAD)
170 #define PUZZLE_QUIT BUTTON_POWER
171 #define PUZZLE_QUIT_TEXT "[POWER]"
173 #elif CONFIG_KEYPAD == CREATIVEZVM_PAD
174 #define PUZZLE_QUIT BUTTON_BACK
175 #define PUZZLE_LEFT BUTTON_LEFT
176 #define PUZZLE_RIGHT BUTTON_RIGHT
177 #define PUZZLE_UP BUTTON_UP
178 #define PUZZLE_DOWN BUTTON_DOWN
179 #define PUZZLE_SHUFFLE BUTTON_PLAY
180 #define PUZZLE_PICTURE BUTTON_MENU
182 #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
183 #define PUZZLE_QUIT BUTTON_POWER
184 #define PUZZLE_LEFT BUTTON_LEFT
185 #define PUZZLE_RIGHT BUTTON_RIGHT
186 #define PUZZLE_UP BUTTON_UP
187 #define PUZZLE_DOWN BUTTON_DOWN
188 #define PUZZLE_SHUFFLE BUTTON_VIEW
189 #define PUZZLE_PICTURE BUTTON_MENU
191 #elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
192 #define PUZZLE_QUIT BUTTON_POWER
193 #define PUZZLE_LEFT BUTTON_PREV
194 #define PUZZLE_RIGHT BUTTON_NEXT
195 #define PUZZLE_UP BUTTON_UP
196 #define PUZZLE_DOWN BUTTON_DOWN
197 #define PUZZLE_SHUFFLE BUTTON_RIGHT
198 #define PUZZLE_PICTURE BUTTON_MENU
200 #elif CONFIG_KEYPAD == ONDAVX747_PAD || \
201 CONFIG_KEYPAD == ONDAVX777_PAD || \
202 CONFIG_KEYPAD == MROBE500_PAD
203 #define PUZZLE_QUIT BUTTON_POWER
204 #define PUZZLE_QUIT_TEXT "[POWER]"
206 #elif (CONFIG_KEYPAD == SAMSUNG_YH_PAD)
207 #define PUZZLE_QUIT BUTTON_REC
208 #define PUZZLE_LEFT BUTTON_LEFT
209 #define PUZZLE_RIGHT BUTTON_RIGHT
210 #define PUZZLE_UP BUTTON_UP
211 #define PUZZLE_DOWN BUTTON_DOWN
212 #define PUZZLE_SHUFFLE BUTTON_REW
213 #define PUZZLE_PICTURE BUTTON_PLAY
216 #error No keymap defined!
219 #ifdef HAVE_TOUCHSCREEN
221 #define PUZZLE_QUIT BUTTON_TOPLEFT
224 #define PUZZLE_LEFT BUTTON_MIDLEFT
227 #define PUZZLE_RIGHT BUTTON_MIDRIGHT
230 #define PUZZLE_UP BUTTON_TOPMIDDLE
233 #define PUZZLE_DOWN BUTTON_BOTTOMMIDDLE
235 #ifndef PUZZLE_SHUFFLE
236 #define PUZZLE_SHUFFLE BUTTON_BOTTOMLEFT
238 #ifndef PUZZLE_PICTURE
239 #define PUZZLE_PICTURE BUTTON_CENTER
241 #ifndef PUZZLE_QUIT_TEXT
242 #define PUZZLE_QUIT_TEXT "[TOPLEFT]"
244 #ifndef PUZZLE_SHUFFLE_TEXT
245 #define PUZZLE_SHUFFLE_TEXT "[BOTTOMLEFT]"
247 #ifndef PUZZLE_PICTURE_TEXT
248 #define PUZZLE_PICTURE_TEXT "[CENTER]"
253 #include "lib/read_image.h"
254 #define READ_IMAGE read_image_file
256 #define READ_IMAGE rb->read_bmp_file
259 #include "pluginbitmaps/sliding_puzzle.h"
260 #define IMAGE_WIDTH BMPWIDTH_sliding_puzzle
261 #define IMAGE_HEIGHT BMPHEIGHT_sliding_puzzle
262 #define IMAGE_SIZE IMAGE_WIDTH
264 /* use a square image, (the default Archos bitmap looks square on its display)
265 Puzzle image dimension is min(lcd_height,lcd_width)
266 4x4 is more convenient for square puzzles
267 Note: sliding_puzzle.bmp should be evenly divisible by SPOTS_X
268 and SPOTS_Y, otherwise lcd_bitmap_part stride won't be correct */
271 #define SPOTS_WIDTH (IMAGE_WIDTH / SPOTS_X)
272 #define SPOTS_HEIGHT (IMAGE_HEIGHT / SPOTS_Y)
273 #define NUM_SPOTS (SPOTS_X*SPOTS_Y)
274 #define HOLE_ID (NUM_SPOTS)
275 #define INITIAL_HOLE (HOLE_ID-1)
279 PICMODE_NUMERALS
= 0,
280 PICMODE_INITIAL_PICTURE
,
281 PICMODE_DEFAULT_PICTURE
,
286 PICMODE_LAST_XXX
/* placeholder */
289 static const char* const picmode_descriptions
[] = {
296 "Shouldn't Get Here",
299 static int spots
[NUM_SPOTS
];
300 static int hole
= INITIAL_HOLE
, moves
;
301 static unsigned char s
[32];
302 static enum picmodes picmode
= PICMODE_INITIAL_PICTURE
;
303 static int num_font
= FONT_UI
;
304 static int moves_font
= FONT_UI
;
305 static int moves_y
= 0;
307 static unsigned char *img_buf
;
308 static size_t img_buf_len
;
310 static char albumart_path
[MAX_PATH
+1];
312 static char img_buf_path
[MAX_PATH
+1];
314 static const fb_data
* puzzle_bmp_ptr
;
315 /* initial_bmp_path points to selected bitmap if this game is launched
316 as a viewer for a .bmp file, or NULL if game is launched regular way */
317 static const char * initial_bmp_path
=NULL
;
320 const char * get_albumart_bmp_path(void)
322 struct mp3entry
* track
= rb
->audio_current_track();
324 if (!track
|| !track
->path
|| track
->path
[0] == '\0')
327 if (!rb
->search_albumart_files(track
, "", albumart_path
, MAX_PATH
) )
330 albumart_path
[ MAX_PATH
] = '\0';
331 return albumart_path
;
335 const char * get_random_bmp_path(void)
337 return(initial_bmp_path
);
340 static bool load_resize_bitmap(void)
343 const char * filename
= NULL
;
345 /* initially assume using the built-in default */
346 puzzle_bmp_ptr
= sliding_puzzle
;
349 /* some modes don't even need to touch disk and trivially succeed */
350 case PICMODE_NUMERALS
:
351 case PICMODE_DEFAULT_PICTURE
:
356 case PICMODE_ALBUM_ART
:
357 filename
= get_albumart_bmp_path();
362 if(NULL == (filename=get_random_bmp_path()) )
363 filename = initial_bmp_path;
366 case PICMODE_INITIAL_PICTURE
:
367 filename
= initial_bmp_path
;
371 if( filename
!= NULL
)
373 /* if we already loaded image before, don't touch disk */
374 if( 0 == rb
->strcmp( filename
, img_buf_path
) )
376 puzzle_bmp_ptr
= (const fb_data
*)img_buf
;
380 struct bitmap main_bitmap
;
381 rb
->memset(&main_bitmap
,0,sizeof(struct bitmap
));
382 main_bitmap
.data
= img_buf
;
384 main_bitmap
.width
= IMAGE_WIDTH
;
385 main_bitmap
.height
= IMAGE_HEIGHT
;
387 rc
= READ_IMAGE( filename
, &main_bitmap
,
389 FORMAT_NATIVE
|FORMAT_RESIZE
|FORMAT_DITHER
,
393 puzzle_bmp_ptr
= (const fb_data
*)img_buf
;
394 rb
->strcpy( img_buf_path
, filename
);
399 /* something must have failed. get_albumart_bmp_path could return
400 NULL if albumart doesn't exist or couldn't be loaded, or
401 read_bmp_file could have failed. return false and caller should
402 try the next mode (PICMODE_DEFAULT_PICTURE and PICMODE_NUMERALS will
407 /* draws a spot at the coordinates (x,y), range of p is 1-20 */
408 static void draw_spot(int p
, int x
, int y
)
415 /* the bottom-right cell of the default sliding_puzzle image is
416 an appropriate hole graphic */
417 rb
->lcd_bitmap_part(sliding_puzzle
, ((p
-1)%SPOTS_X
)*SPOTS_WIDTH
,
418 ((p
-1)/SPOTS_X
)*SPOTS_HEIGHT
,
420 BMPWIDTH_sliding_puzzle
, BMPHEIGHT_sliding_puzzle
),
421 x
, y
, SPOTS_WIDTH
, SPOTS_HEIGHT
);
423 /* just draw a black rectangle */
424 int old_fg
= rb
->lcd_get_foreground();
425 rb
->lcd_set_foreground(LCD_BLACK
);
426 rb
->lcd_fillrect(x
,y
,SPOTS_WIDTH
,SPOTS_HEIGHT
);
427 rb
->lcd_set_foreground(old_fg
);
430 else if (picmode
!= PICMODE_NUMERALS
)
432 rb
->lcd_bitmap_part( puzzle_bmp_ptr
, ((p
-1)%SPOTS_X
)*SPOTS_WIDTH
,
433 ((p
-1)/SPOTS_X
)*SPOTS_HEIGHT
,
435 BMPWIDTH_sliding_puzzle
, BMPHEIGHT_sliding_puzzle
),
436 x
, y
, SPOTS_WIDTH
, SPOTS_HEIGHT
);
438 rb
->lcd_drawrect(x
, y
, SPOTS_WIDTH
, SPOTS_HEIGHT
);
439 rb
->lcd_set_drawmode(DRMODE_SOLID
|DRMODE_INVERSEVID
);
440 rb
->lcd_fillrect(x
+1, y
+1, SPOTS_WIDTH
-2, SPOTS_HEIGHT
-2);
441 rb
->lcd_set_drawmode(DRMODE_SOLID
);
442 rb
->snprintf(s
, sizeof(s
), "%d", p
);
443 rb
->lcd_setfont(num_font
);
444 rb
->lcd_getstringsize(s
, &w
, &h
);
445 rb
->lcd_putsxy(x
+ (SPOTS_WIDTH
/2) - w
/ 2,
446 y
+ (SPOTS_HEIGHT
/2) - h
/ 2, s
);
450 /* check if the puzzle is solved */
451 static bool puzzle_finished(void)
454 for (i
=0; i
<NUM_SPOTS
; i
++)
455 if (spots
[i
] != (i
+1))
460 /* move a piece in any direction */
461 static void move_spot(int x
, int y
)
464 spots
[hole
] = spots
[hole
-x
-SPOTS_X
*y
];
465 hole
-= (x
+SPOTS_X
*y
);
467 rb
->lcd_setfont(moves_font
);
468 #if LCD_WIDTH > LCD_HEIGHT
469 rb
->snprintf(s
, sizeof(s
), "%d", moves
);
470 w
= rb
->lcd_getstringsize(s
, NULL
, NULL
);
471 rb
->lcd_putsxy((IMAGE_WIDTH
+1+(LCD_WIDTH
-IMAGE_WIDTH
-1)/2) - w
/ 2,
475 rb
->snprintf(s
, sizeof(s
), "Moves: %d", moves
);
476 rb
->lcd_putsxy(3, moves_y
, s
);
481 (hole
%SPOTS_X
)*SPOTS_WIDTH
,
482 (hole
/SPOTS_X
)*SPOTS_HEIGHT
);
483 draw_spot(spots
[hole
],
484 (hole
%SPOTS_X
)*SPOTS_WIDTH
+ (i
*x
*SPOTS_WIDTH
)/5,
485 (hole
/SPOTS_X
)*SPOTS_HEIGHT
+ (i
*y
*SPOTS_HEIGHT
)/5);
490 (hole
%SPOTS_X
)*SPOTS_WIDTH
,
491 (hole
/SPOTS_X
)*SPOTS_HEIGHT
);
492 draw_spot(spots
[hole
],
493 ((hole
%SPOTS_X
)+x
)*SPOTS_WIDTH
,
494 ((hole
/SPOTS_X
)+y
)*SPOTS_HEIGHT
);
497 spots
[hole
] = HOLE_ID
;
500 static void draw_playfield(void)
504 rb
->lcd_clear_display();
505 rb
->lcd_setfont(moves_font
);
506 #if LCD_WIDTH > LCD_HEIGHT
507 rb
->lcd_vline(IMAGE_WIDTH
, 0, LCD_HEIGHT
-1);
508 w
= rb
->lcd_getstringsize("Moves", NULL
, NULL
);
509 rb
->lcd_putsxy((IMAGE_WIDTH
+1+(LCD_WIDTH
-IMAGE_WIDTH
-1)/2) - w
/ 2,
511 rb
->snprintf(s
, sizeof(s
), "%d", moves
);
512 w
= rb
->lcd_getstringsize(s
, NULL
, NULL
);
513 rb
->lcd_putsxy((IMAGE_WIDTH
+1+(LCD_WIDTH
-IMAGE_WIDTH
-1)/2) - w
/ 2,
517 rb
->lcd_hline(0, LCD_WIDTH
-1, IMAGE_HEIGHT
);
518 rb
->snprintf(s
, sizeof(s
), "Moves: %d", moves
);
519 rb
->lcd_putsxy(3, moves_y
, s
);
522 /* draw spots to the lcd */
523 for (i
=0; i
<NUM_SPOTS
; i
++)
524 draw_spot(spots
[i
], (i
%SPOTS_X
)*SPOTS_WIDTH
, (i
/SPOTS_X
)*SPOTS_HEIGHT
);
529 /* initializes the puzzle */
530 static void puzzle_init(void)
532 int i
, r
, temp
, tsp
[NUM_SPOTS
];
537 for (i
=NUM_SPOTS
-1; i
>=0; i
--) {
538 r
= (rb
->rand() % (i
+1));
544 if (spots
[i
]==HOLE_ID
)
548 /* test if the puzzle is solvable */
549 for (i
=0; i
<NUM_SPOTS
; i
++)
553 /* First, check if the problem has even or odd parity,
554 depending on where the empty square is */
555 if ((((SPOTS_X
-1)-hole
%SPOTS_X
) + ((SPOTS_Y
-1)-hole
/SPOTS_X
))%2 == 1)
558 /* Now check how many swaps we need to solve it */
559 for (i
=0; i
<NUM_SPOTS
-1; i
++) {
560 while (tsp
[i
] != (i
+1)) {
562 tsp
[i
] = tsp
[temp
-1];
568 /* if the random puzzle isn't solvable just change two spots */
570 if (spots
[0]!=HOLE_ID
&& spots
[1]!=HOLE_ID
) {
584 /* the main game loop */
585 static int puzzle_loop(void)
588 int lastbutton
= BUTTON_NONE
;
593 button
= rb
->button_get(true);
595 #ifdef PUZZLE_RC_QUIT
599 /* get out of here */
603 #ifdef PUZZLE_SHUFFLE_PICTURE_PRE
604 if (lastbutton
!= PUZZLE_SHUFFLE_PICTURE_PRE
)
607 /* mix up the pieces */
612 #ifdef PUZZLE_SHUFFLE_PICTURE_PRE
613 if (lastbutton
!= PUZZLE_SHUFFLE_PICTURE_PRE
)
617 picmode
= (picmode
+1)%PICMODE_LAST_XXX
;
619 /* if load_resize_bitmap fails to load bitmap, try next picmode
623 load_success
= load_resize_bitmap();
625 picmode
= (picmode
+1)%PICMODE_LAST_XXX
;
627 while( !load_success
);
629 /* tell the user what mode we picked in the end! */
630 rb
->splash(HZ
,picmode_descriptions
[ picmode
] );
635 if ((hole
%SPOTS_X
)<(SPOTS_X
-1) && !puzzle_finished())
640 if ((hole
%SPOTS_X
)>0 && !puzzle_finished())
645 if ((hole
/SPOTS_X
)<(SPOTS_Y
-1) && !puzzle_finished())
650 if ((hole
/SPOTS_X
)>0 && !puzzle_finished())
655 if (rb
->default_event_handler(button
) == SYS_USB_CONNECTED
)
656 return PLUGIN_USB_CONNECTED
;
659 if (button
!= BUTTON_NONE
)
664 enum plugin_status
plugin_start(
665 const void* parameter
)
669 initial_bmp_path
=(const char *)parameter
;
670 img_buf
= rb
->plugin_get_buffer(&img_buf_len
);
671 picmode
= PICMODE_INITIAL_PICTURE
;
672 img_buf_path
[0] = '\0';
674 /* If launched as a viewer, just go straight to the game without
675 bothering with the splash or instructions page */
678 /* if not launched as a viewer, use default puzzle, and show help */
679 picmode
= PICMODE_DEFAULT_PICTURE
;
682 rb
->lcd_getstringsize((unsigned char *)"Sliding Puzzle", &w
, &h
);
685 rb
->lcd_clear_display();
686 rb
->lcd_putsxy(LCD_WIDTH
/2-w
, (LCD_HEIGHT
/2)-h
,
687 (unsigned char *)"Sliding Puzzle");
691 /* print instructions */
692 rb
->lcd_clear_display();
693 rb
->lcd_setfont(FONT_SYSFIXED
);
694 #if CONFIG_KEYPAD == RECORDER_PAD || CONFIG_KEYPAD == ARCHOS_AV300_PAD
695 rb
->lcd_putsxy(3, 18, "[OFF] to stop");
696 rb
->lcd_putsxy(3, 28, "[F1] shuffle");
697 rb
->lcd_putsxy(3, 38, "[F2] change pic");
698 #elif CONFIG_KEYPAD == ONDIO_PAD
699 rb
->lcd_putsxy(0, 18, "[OFF] to stop");
700 rb
->lcd_putsxy(0, 28, "[MODE..] shuffle");
701 rb
->lcd_putsxy(0, 38, "[MODE] change pic");
702 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
703 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
704 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
705 rb
->lcd_putsxy(0, 18, "[S-MENU] to stop");
706 rb
->lcd_putsxy(0, 28, "[S-LEFT] shuffle");
707 rb
->lcd_putsxy(0, 38, "[S-RIGHT] change pic");
708 #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
709 (CONFIG_KEYPAD == IRIVER_H300_PAD)
710 rb
->lcd_putsxy(0, 18, "[STOP] to stop");
711 rb
->lcd_putsxy(0, 28, "[SELECT] shuffle");
712 rb
->lcd_putsxy(0, 38, "[PLAY] change pic");
713 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
714 rb
->lcd_putsxy(0, 18, "[OFF] to stop");
715 rb
->lcd_putsxy(0, 28, "[REC] shuffle");
716 rb
->lcd_putsxy(0, 38, "[PLAY] change pic");
717 #elif CONFIG_KEYPAD == GIGABEAT_PAD
718 rb
->lcd_putsxy(0, 18, "[POWER] to stop");
719 rb
->lcd_putsxy(0, 28, "[SELECT] shuffle");
720 rb
->lcd_putsxy(0, 38, "[A] change pic");
721 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
722 (CONFIG_KEYPAD == SANSA_C200_PAD)
723 rb
->lcd_putsxy(0, 18, "[OFF] to stop");
724 rb
->lcd_putsxy(0, 28, "[REC] shuffle");
725 rb
->lcd_putsxy(0, 38, "[SELECT] change pic");
726 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
727 rb
->lcd_putsxy(0, 18, "[OFF] to stop");
728 rb
->lcd_putsxy(0, 28, "[REW] shuffle");
729 rb
->lcd_putsxy(0, 38, "[PLAY] change pic");
730 #elif CONFIG_KEYPAD == GIGABEAT_S_PAD
731 rb
->lcd_putsxy(0, 18, "[BACK] to stop");
732 rb
->lcd_putsxy(0, 28, "[SELECT] shuffle");
733 rb
->lcd_putsxy(0, 38, "[MENU] change pic");
734 #elif CONFIG_KEYPAD == IAUDIO_M3_PAD
735 rb
->lcd_putsxy(0, 18, "[REC] to stop");
736 rb
->lcd_putsxy(0, 28, "[MODE] shuffle");
737 rb
->lcd_putsxy(0, 38, "[MENU] change pic");
739 #ifdef HAVE_TOUCHSCREEN
740 rb
->lcd_putsxy(0, 18, PUZZLE_QUIT_TEXT
" to stop");
741 rb
->lcd_putsxy(0, 28, PUZZLE_SHUFFLE_TEXT
" shuffle");
742 rb
->lcd_putsxy(0, 38, PUZZLE_PICTURE_TEXT
" change pic");
745 rb
->lcd_putsxy(0,48," pic->albumart->num");
747 rb
->lcd_putsxy(0,48," pic<->num");
750 rb
->button_get_w_tmo(HZ
*2);
755 if( !load_resize_bitmap() )
757 rb
->lcd_clear_display();
758 rb
->splash(HZ
*2,"Failed to load bitmap!");
762 /* Calculate possible font sizes and text positions */
763 rb
->lcd_setfont(FONT_UI
);
764 rb
->lcd_getstringsize("15", &w
, &h
);
765 if ((w
> (SPOTS_WIDTH
-2)) || (h
> (SPOTS_HEIGHT
-2)))
766 num_font
= FONT_SYSFIXED
;
768 #if LCD_WIDTH > LCD_HEIGHT
769 rb
->lcd_getstringsize("Moves", &w
, &h
);
770 if (w
> (LCD_WIDTH
-IMAGE_WIDTH
-1))
771 moves_font
= FONT_SYSFIXED
;
772 rb
->lcd_setfont(moves_font
);
773 rb
->lcd_getstringsize("Moves", &w
, &h
);
776 rb
->lcd_getstringsize("Moves: 999", &w
, &h
);
777 if ((w
> LCD_WIDTH
) || (h
> (LCD_HEIGHT
-IMAGE_HEIGHT
-1)))
778 moves_font
= FONT_SYSFIXED
;
779 rb
->lcd_setfont(moves_font
);
780 rb
->lcd_getstringsize("Moves: 999", &w
, &h
);
781 moves_y
= (IMAGE_HEIGHT
+1+(LCD_HEIGHT
-IMAGE_HEIGHT
-1)/2) - h
/ 2;
783 for (i
=0; i
<NUM_SPOTS
; i
++)
786 #ifdef HAVE_LCD_COLOR
787 rb
->lcd_set_background(LCD_BLACK
);
788 rb
->lcd_set_foreground(LCD_WHITE
);
789 rb
->lcd_set_backdrop(NULL
);
791 rb
->lcd_set_background(LCD_WHITE
);
792 rb
->lcd_set_foreground(LCD_BLACK
);
793 rb
->lcd_set_backdrop(NULL
);
799 return puzzle_loop();