summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Pennequin <nicolas.pennequin@free.fr>2008-01-26 00:16:06 +0000
committerNicolas Pennequin <nicolas.pennequin@free.fr>2008-01-26 00:16:06 +0000
commit02f1839bfe4766ac72631bd7b76f2fc7f291b89e (patch)
tree533f71fe6ded348dc9c5add13dae25dde9a30c57
parent59914786289033648db9bd5f4222978767e4d665 (diff)
downloadrockbox-02f1839bfe4766ac72631bd7b76f2fc7f291b89e.tar.gz
rockbox-02f1839bfe4766ac72631bd7b76f2fc7f291b89e.zip
Accept FS#7218 by Dave Hooper: Bitmap version of the sliding puzzle game.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16168 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugins/bitmaps/native/SOURCES21
-rw-r--r--apps/plugins/bitmaps/native/sliding_puzzle.110x110x2.bmpbin0 -> 13398 bytes
-rw-r--r--apps/plugins/bitmaps/native/sliding_puzzle.128x128x16.bmpbin0 -> 49206 bytes
-rw-r--r--apps/plugins/bitmaps/native/sliding_puzzle.128x128x2.bmpbin0 -> 17462 bytes
-rw-r--r--apps/plugins/bitmaps/native/sliding_puzzle.176x176x16.bmpbin0 -> 92982 bytes
-rw-r--r--apps/plugins/bitmaps/native/sliding_puzzle.240x240x16.bmpbin0 -> 172854 bytes
-rw-r--r--apps/plugins/bitmaps/native/sliding_puzzle.80x64x1.bmpbin0 -> 830 bytes
-rw-r--r--apps/plugins/bitmaps/native/sliding_puzzle.80x80x16.bmpbin0 -> 19254 bytes
-rw-r--r--apps/plugins/bitmaps/native/sliding_puzzle.bmpbin0 -> 480054 bytes
-rw-r--r--apps/plugins/lib/SOURCES2
-rw-r--r--apps/plugins/lib/bmp.c2
-rw-r--r--apps/plugins/lib/bmp.h2
-rw-r--r--apps/plugins/sliding_puzzle.c573
-rw-r--r--apps/plugins/viewers.config1
14 files changed, 414 insertions, 187 deletions
diff --git a/apps/plugins/bitmaps/native/SOURCES b/apps/plugins/bitmaps/native/SOURCES
index 61c9b7a70f..73ee2113c6 100644
--- a/apps/plugins/bitmaps/native/SOURCES
+++ b/apps/plugins/bitmaps/native/SOURCES
@@ -546,4 +546,25 @@ matrix_normal.bmp
546#endif 546#endif
547#endif 547#endif
548 548
549#if defined(HAVE_LCD_COLOR)
550#if (LCD_WIDTH==132 && LCD_HEIGHT==80)
551 sliding_puzzle.80x80x16.bmp
552#elif (LCD_WIDTH==128 || LCD_HEIGHT==128)
553 sliding_puzzle.128x128x16.bmp
554#elif (LCD_WIDTH==176 || LCD_WIDTH==176)
555 sliding_puzzle.176x176x16.bmp
556#elif (LCD_WIDTH==240 || LCD_HEIGHT==240)
557 sliding_puzzle.240x240x16.bmp
558#endif
559#elif (LCD_DEPTH>1)
560#if (LCD_WIDTH==110 || LCD_HEIGHT==110)
561 sliding_puzzle.110x110x2.bmp
562#elif (LCD_WIDTH==128 || LCD_HEIGHT==128)
563 sliding_puzzle.128x128x2.bmp
564#endif
565#elif (LCD_WIDTH>=80 && LCD_HEIGHT==64)
566 sliding_puzzle.80x64x1.bmp
567#endif
568
569
549#endif /* HAVE_LCD_BITMAP */ 570#endif /* HAVE_LCD_BITMAP */
diff --git a/apps/plugins/bitmaps/native/sliding_puzzle.110x110x2.bmp b/apps/plugins/bitmaps/native/sliding_puzzle.110x110x2.bmp
new file mode 100644
index 0000000000..e21531ec70
--- /dev/null
+++ b/apps/plugins/bitmaps/native/sliding_puzzle.110x110x2.bmp
Binary files differ
diff --git a/apps/plugins/bitmaps/native/sliding_puzzle.128x128x16.bmp b/apps/plugins/bitmaps/native/sliding_puzzle.128x128x16.bmp
new file mode 100644
index 0000000000..1fc05dc054
--- /dev/null
+++ b/apps/plugins/bitmaps/native/sliding_puzzle.128x128x16.bmp
Binary files differ
diff --git a/apps/plugins/bitmaps/native/sliding_puzzle.128x128x2.bmp b/apps/plugins/bitmaps/native/sliding_puzzle.128x128x2.bmp
new file mode 100644
index 0000000000..e8ef4eead8
--- /dev/null
+++ b/apps/plugins/bitmaps/native/sliding_puzzle.128x128x2.bmp
Binary files differ
diff --git a/apps/plugins/bitmaps/native/sliding_puzzle.176x176x16.bmp b/apps/plugins/bitmaps/native/sliding_puzzle.176x176x16.bmp
new file mode 100644
index 0000000000..dff5a119c2
--- /dev/null
+++ b/apps/plugins/bitmaps/native/sliding_puzzle.176x176x16.bmp
Binary files differ
diff --git a/apps/plugins/bitmaps/native/sliding_puzzle.240x240x16.bmp b/apps/plugins/bitmaps/native/sliding_puzzle.240x240x16.bmp
new file mode 100644
index 0000000000..d1de3a84ca
--- /dev/null
+++ b/apps/plugins/bitmaps/native/sliding_puzzle.240x240x16.bmp
Binary files differ
diff --git a/apps/plugins/bitmaps/native/sliding_puzzle.80x64x1.bmp b/apps/plugins/bitmaps/native/sliding_puzzle.80x64x1.bmp
new file mode 100644
index 0000000000..a394e8eba3
--- /dev/null
+++ b/apps/plugins/bitmaps/native/sliding_puzzle.80x64x1.bmp
Binary files differ
diff --git a/apps/plugins/bitmaps/native/sliding_puzzle.80x80x16.bmp b/apps/plugins/bitmaps/native/sliding_puzzle.80x80x16.bmp
new file mode 100644
index 0000000000..4c386bfa0d
--- /dev/null
+++ b/apps/plugins/bitmaps/native/sliding_puzzle.80x80x16.bmp
Binary files differ
diff --git a/apps/plugins/bitmaps/native/sliding_puzzle.bmp b/apps/plugins/bitmaps/native/sliding_puzzle.bmp
new file mode 100644
index 0000000000..ed7e191239
--- /dev/null
+++ b/apps/plugins/bitmaps/native/sliding_puzzle.bmp
Binary files differ
diff --git a/apps/plugins/lib/SOURCES b/apps/plugins/lib/SOURCES
index 94372dcf97..c1f5a483f2 100644
--- a/apps/plugins/lib/SOURCES
+++ b/apps/plugins/lib/SOURCES
@@ -25,7 +25,7 @@ picture.c
25xlcd_core.c 25xlcd_core.c
26xlcd_draw.c 26xlcd_draw.c
27xlcd_scroll.c 27xlcd_scroll.c
28#ifdef HAVE_LCD_COLOR 28#if LCD_DEPTH>1
29bmp.c 29bmp.c
30#endif 30#endif
31#endif 31#endif
diff --git a/apps/plugins/lib/bmp.c b/apps/plugins/lib/bmp.c
index 03bdc73783..20adc6de86 100644
--- a/apps/plugins/lib/bmp.c
+++ b/apps/plugins/lib/bmp.c
@@ -24,6 +24,7 @@
24#include "lcd.h" 24#include "lcd.h"
25#include "system.h" 25#include "system.h"
26 26
27#ifdef HAVE_LCD_COLOR
27#define LE16(x) (htole16(x))&0xff, ((htole16(x))>>8)&0xff 28#define LE16(x) (htole16(x))&0xff, ((htole16(x))>>8)&0xff
28#define LE32(x) (htole32(x))&0xff, ((htole32(x))>>8)&0xff, ((htole32(x))>>16)&0xff, ((htole32(x))>>24)&0xff 29#define LE32(x) (htole32(x))&0xff, ((htole32(x))>>8)&0xff, ((htole32(x))>>16)&0xff, ((htole32(x))>>24)&0xff
29/** 30/**
@@ -82,6 +83,7 @@ int save_bmp_file( char* filename, struct bitmap *bm, struct plugin_api* rb )
82 rb->close( fh ); 83 rb->close( fh );
83 return 1; 84 return 1;
84} 85}
86#endif
85 87
86/** 88/**
87 Very simple image scale from src to dst (nearest neighbour). 89 Very simple image scale from src to dst (nearest neighbour).
diff --git a/apps/plugins/lib/bmp.h b/apps/plugins/lib/bmp.h
index e35c1ecb0a..3e14243d30 100644
--- a/apps/plugins/lib/bmp.h
+++ b/apps/plugins/lib/bmp.h
@@ -22,10 +22,12 @@
22#include "lcd.h" 22#include "lcd.h"
23#include "plugin.h" 23#include "plugin.h"
24 24
25#ifdef HAVE_LCD_COLOR
25/** 26/**
26 * Save bitmap to file 27 * Save bitmap to file
27 */ 28 */
28int save_bmp_file( char* filename, struct bitmap *bm, struct plugin_api* rb ); 29int save_bmp_file( char* filename, struct bitmap *bm, struct plugin_api* rb );
30#endif
29 31
30/** 32/**
31 Very simple image scale from src to dst (nearest neighbour). 33 Very simple image scale from src to dst (nearest neighbour).
diff --git a/apps/plugins/sliding_puzzle.c b/apps/plugins/sliding_puzzle.c
index 17a96baf2a..223c107265 100644
--- a/apps/plugins/sliding_puzzle.c
+++ b/apps/plugins/sliding_puzzle.c
@@ -17,8 +17,9 @@
17 * 17 *
18 ****************************************************************************/ 18 ****************************************************************************/
19#include "plugin.h" 19#include "plugin.h"
20#ifdef HAVE_LCD_BITMAP 20#include "bmp.h"
21 21
22#ifdef HAVE_LCD_BITMAP
22PLUGIN_HEADER 23PLUGIN_HEADER
23 24
24/* variable button definitions */ 25/* variable button definitions */
@@ -95,190 +96,304 @@ PLUGIN_HEADER
95#endif 96#endif
96 97
97static struct plugin_api* rb; 98static struct plugin_api* rb;
98static int spots[20]; 99#if LCD_DEPTH==1
99static int hole = 19, moves; 100/* for recorder, use rectangular image, 5x4 puzzle */
100static char s[5]; 101#define SPOTS_X 5
101static bool pic = true; 102#define SPOTS_Y 4
102static unsigned char picture[20][32] = { 103#define SPOTS_WIDTH 16
103 { 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0xf8, 0xd9, 104#define SPOTS_HEIGHT 16
104 0x10, 0xb0, 0x60, 0xc0, 0x80, 0x00, 0x30, 0x78, 105#define IMAGE_WIDTH 80
105 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x01, 0x07, 106#define IMAGE_HEIGHT 64
106 0xbf, 0xf8, 0x43, 0x1c, 0x61, 0x5e, 0xfc, 0xfc }, 107#define IMAGE_SIZE 80
107 108#else
108 { 0x68, 0xc8, 0x48, 0x08, 0x98, 0x90, 0xb0, 0xa4, 109/* for other targets, use a square image, 4x4 puzzle
109 0xa0, 0xc0, 0xc0, 0x88, 0x14, 0x08, 0x00, 0x00, 110 Puzzle image dimension is min(lcd_height,lcd_width)
110 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x03, 111 4x4 is more convenient than 5x4 for square puzzles
111 0x00, 0x00, 0x30, 0x48, 0x79, 0x33, 0x06, 0x1c }, 112 Note: sliding_puzzle.bmp should be evenly divisible by SPOTS_X
112 113 and SPOTS_Y, otherwise lcd_bitmap_part stride won't be correct */
113 { 0x20, 0x00, 0x06, 0x09, 0x09, 0x06, 0x00, 0x80, 114#define SPOTS_X 4
114 0x40, 0x80, 0x00, 0x08, 0x14, 0x08, 0x20, 0x00, 115#define SPOTS_Y 4
115 0x60, 0x30, 0x18, 0xf9, 0x70, 0x00, 0x00, 0x00, 116#define IMAGE_SIZE ( (LCD_WIDTH<LCD_HEIGHT)?LCD_WIDTH:LCD_HEIGHT )
116 0xf9, 0x18, 0x30, 0x60, 0x30, 0x18, 0x06, 0x32 }, 117#define IMAGE_WIDTH IMAGE_SIZE
117 118#define IMAGE_HEIGHT IMAGE_SIZE
118 { 0x00, 0x80, 0x42, 0xa0, 0x50, 0x90, 0x88, 0x88, 119#define SPOTS_WIDTH (IMAGE_WIDTH/SPOTS_X)
119 0x84, 0xa4, 0xa4, 0x64, 0x24, 0x18, 0x00, 0x40, 120#define SPOTS_HEIGHT (IMAGE_HEIGHT/SPOTS_Y)
120 0x79, 0x4a, 0x31, 0x02, 0x05, 0x2a, 0xd5, 0xaa, 121#endif
121 0x55, 0xaa, 0x55, 0xab, 0x56, 0xac, 0x58, 0xb0 }, 122
122 123#define NUM_SPOTS (SPOTS_X*SPOTS_Y)
123 { 0x04, 0x0a, 0x04, 0x00, 0x80, 0x80, 0xc0, 0xc8, 124#define HOLE_ID (NUM_SPOTS)
124 0x40, 0xc2, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 125#define INITIAL_HOLE (HOLE_ID-1)
125 0x60, 0x38, 0x9c, 0xe7, 0x59, 0x0c, 0xc4, 0xfc, 126
126 0x3f, 0x07, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00 }, 127enum picmodes
127 128{
128 { 0x00, 0x04, 0x00, 0x00, 0x80, 0xe0, 0x78, 0x1e, 129 PICMODE_NUMERALS = 0,
129 0xa7, 0xd9, 0xcc, 0x76, 0x3b, 0x0d, 0x1f, 0xff, 130 PICMODE_INITIAL_PICTURE,
130 0x00, 0x00, 0x00, 0x00, 0x03, 0x13, 0x03, 0x03, 131 PICMODE_DEFAULT_PICTURE,
131 0x11, 0x29, 0x10, 0x00, 0x04, 0x2a, 0x0b, 0x0b }, 132#ifdef HAVE_ALBUMART
132 133 PICMODE_ALBUM_ART,
133 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 134#endif
134 0xc0, 0x8e, 0x10, 0x00, 0x80, 0x80, 0x60, 0x38, 135// PICMODE_RANDOM,
135 0x0a, 0x08, 0x05, 0x05, 0x07, 0x03, 0x03, 0x03, 136 PICMODE_LAST_XXX /* placeholder */
136 0x03, 0x03, 0x01, 0x11, 0x01, 0x00, 0x00, 0x80 }, 137};
137 138
138 { 0x0e, 0x18, 0x31, 0x3e, 0x1c, 0x00, 0x00, 0x1c, 139static const char* const picmode_descriptions[] = {
139 0x3e, 0x31, 0x18, 0x0c, 0x0c, 0x18, 0x30, 0x20, 140 "Numerals",
140 0x00, 0x00, 0x08, 0x14, 0x08, 0x00, 0x02, 0x80, 141 "Viewer Picture",
141 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00 }, 142 "Default Picture",
142 143#ifdef HAVE_ALBUMART
143 { 0x60, 0xc0, 0x48, 0xc7, 0x60, 0xb8, 0x57, 0xaa, 144 "Album Art",
144 0x55, 0xaa, 0x55, 0xaa, 0xd5, 0xaa, 0x75, 0x3a, 145#endif
145 0x00, 0x00, 0x01, 0x23, 0x05, 0x05, 0x09, 0x0a, 146 "Shouldn't Get Here",
146 0x0b, 0x0a, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00 },
147
148 { 0xe5, 0x8d, 0x18, 0x30, 0x41, 0xc1, 0x8f, 0xfe,
149 0xf0, 0x81, 0x0a, 0x01, 0x00, 0x00, 0x00, 0x00,
150 0x00, 0x01, 0x03, 0x02, 0x06, 0x06, 0x04, 0x04,
151 0x04, 0x05, 0x07, 0x06, 0x00, 0x00, 0x00, 0x00 },
152
153 { 0x00, 0x00, 0x00, 0x10, 0x28, 0x10, 0x00, 0x04,
154 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
155 0xc0, 0xb0, 0x18, 0xcc, 0x24, 0x86, 0x42, 0x22,
156 0x31, 0x69, 0xd1, 0xa9, 0x51, 0xa1, 0x41, 0x02 },
157
158 { 0x00, 0x00, 0x00, 0x00, 0x40, 0xa1, 0x40, 0x00,
159 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
160 0x12, 0x16, 0x5c, 0x58, 0xf0, 0xc0, 0x00, 0x00,
161 0x06, 0x09, 0x09, 0x86, 0x60, 0x18, 0xc4, 0xf2 },
162
163 { 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x40, 0x40,
164 0x40, 0x40, 0x40, 0x40, 0xc0, 0x80, 0x8c, 0x12,
165 0x6a, 0xa5, 0x95, 0xd2, 0xca, 0xc9, 0xe9, 0xe9,
166 0xe1, 0xe9, 0xe1, 0xe1, 0x62, 0x62, 0xc5, 0xc5 },
167
168 { 0x12, 0x0c, 0x00, 0x80, 0x80, 0x40, 0x40, 0x40,
169 0x40, 0x40, 0x40, 0x82, 0x85, 0x02, 0x00, 0x00,
170 0x8a, 0x32, 0x6f, 0xd6, 0xaa, 0x55, 0x83, 0x01,
171 0x81, 0x01, 0x81, 0x82, 0x82, 0x0d, 0xbe, 0xdc },
172
173 { 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00,
174 0x41, 0x00, 0x00, 0x00, 0x02, 0x05, 0x02, 0x00,
175 0x00, 0x00, 0x01, 0x02, 0x01, 0x04, 0x00, 0x60,
176 0x90, 0x90, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00 },
177
178 { 0x3f, 0x6a, 0xc0, 0x9f, 0x20, 0x27, 0x48, 0x4b,
179 0x47, 0x22, 0x50, 0x0f, 0x95, 0x4a, 0x25, 0x90,
180 0x07, 0x0f, 0x17, 0x23, 0x43, 0x42, 0x44, 0x40,
181 0x44, 0x40, 0x42, 0x40, 0x60, 0x30, 0x3c, 0x1f },
182
183 { 0xd0, 0x50, 0x11, 0xb9, 0xef, 0x07, 0x80, 0x40,
184 0x30, 0x98, 0x9c, 0xbf, 0x60, 0xc7, 0x0d, 0x36,
185 0x59, 0x11, 0x21, 0x23, 0x22, 0x21, 0x30, 0x10,
186 0x0d, 0x42, 0x01, 0x80, 0x00, 0x40, 0x03, 0x0c },
187
188 { 0xc3, 0x81, 0x81, 0x00, 0x00, 0x01, 0x03, 0x03,
189 0x03, 0x03, 0x02, 0x01, 0x00, 0x00, 0x80, 0x80,
190 0x10, 0x91, 0x23, 0x23, 0x67, 0xe6, 0xe6, 0xa6,
191 0xa6, 0xa6, 0xa6, 0xa6, 0xb3, 0x93, 0x59, 0x49 },
192
193 { 0xc1, 0x71, 0xff, 0x54, 0x0a, 0x02, 0x06, 0x0e,
194 0x0e, 0x0a, 0x06, 0x02, 0x02, 0xc5, 0x7b, 0x17,
195 0x24, 0x10, 0x3b, 0x7f, 0x92, 0xa6, 0xa4, 0xa4,
196 0xa4, 0xa4, 0xa4, 0x66, 0x23, 0x11, 0x12, 0x0c },
197
198 { 0x55, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
199 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0xaa,
200 0x55, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80,
201 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0xaa }
202}; 147};
203 148
149static int spots[NUM_SPOTS];
150static int hole = INITIAL_HOLE, moves;
151static char s[5];
152static enum picmodes picmode = PICMODE_INITIAL_PICTURE;
153
154static unsigned char img_buf[IMAGE_WIDTH*IMAGE_HEIGHT*sizeof(fb_data)]
155__attribute__ ((aligned(16)));
156#if LCD_DEPTH>1
157static unsigned char temp_img_buf[LCD_WIDTH*LCD_HEIGHT*sizeof(fb_data)]
158__attribute__ ((aligned(16)));
159#endif
160#ifdef HAVE_ALBUMART
161static char albumart_path[MAX_PATH+1];
162#endif
163static char img_buf_path[MAX_PATH+1];
164
165static const fb_data * puzzle_bmp_ptr;
166extern const fb_data sliding_puzzle[];
167/* initial_bmp_path points to selected bitmap if this game is launched
168 as a viewer for a .bmp file, or NULL if game is launched regular way */
169static const char * initial_bmp_path=NULL;
170
171#ifdef HAVE_ALBUMART
172const char * get_albumart_bmp_path(void)
173{
174 struct mp3entry* track = rb->audio_current_track();
175
176 if (!track || !track->path || track->path[0] == '\0')
177 return NULL;
178
179 if (!rb->search_albumart_files(track, "", albumart_path, MAX_PATH ) )
180 return NULL;
181
182 albumart_path[ MAX_PATH ] = '\0';
183 return albumart_path;
184}
185#endif
186
187const char * get_random_bmp_path(void)
188{
189 return(initial_bmp_path);
190}
191
192static bool load_resize_bitmap(void)
193{
194 int rc;
195 const char * filename = NULL;
196
197 /* initially assume using the built-in default */
198 puzzle_bmp_ptr = sliding_puzzle;
199
200 switch( picmode ){
201 /* some modes don't even need to touch disk and trivially succeed */
202 case PICMODE_NUMERALS:
203 case PICMODE_DEFAULT_PICTURE:
204 default:
205 return(true);
206
207#ifdef HAVE_ALBUMART
208 case PICMODE_ALBUM_ART:
209 filename = get_albumart_bmp_path();
210 break;
211#endif
212/*
213 case PICMODE_RANDOM:
214 if(NULL == (filename=get_random_bmp_path()) )
215 filename = initial_bmp_path;
216 break;
217*/
218 case PICMODE_INITIAL_PICTURE:
219 filename = initial_bmp_path;
220 break;
221 };
222
223 if( filename != NULL )
224 {
225 /* if we already loaded image before, don't touch disk */
226 if( 0 == rb->strcmp( filename, img_buf_path ) )
227 {
228 puzzle_bmp_ptr = (const fb_data *)img_buf;
229 return true;
230 }
231
232 struct bitmap main_bitmap;
233 rb->memset(&main_bitmap,0,sizeof(struct bitmap));
234 main_bitmap.data = img_buf;
235
236#if LCD_DEPTH>1
237 struct bitmap temp_bitmap;
238 rb->memset(&temp_bitmap,0,sizeof(struct bitmap));
239 temp_bitmap.data = temp_img_buf;
240
241 main_bitmap.width = IMAGE_WIDTH;
242 main_bitmap.height = IMAGE_HEIGHT;
243
244 rc = rb->read_bmp_file( filename, &temp_bitmap, sizeof(temp_img_buf),
245 FORMAT_NATIVE );
246 if( rc > 0 )
247 {
248 simple_resize_bitmap( &temp_bitmap, &main_bitmap );
249 puzzle_bmp_ptr = (const fb_data *)img_buf;
250 rb->strcpy( img_buf_path, filename );
251 return true;
252 }
253#else
254 rc = rb->read_bmp_file( filename, &main_bitmap, sizeof(img_buf),
255 FORMAT_NATIVE );
256 if( rc > 0 )
257 {
258 puzzle_bmp_ptr = (const fb_data *)img_buf;
259 rb->strcpy( img_buf_path, filename );
260 return true;
261 }
262#endif
263 }
264
265 /* something must have failed. get_albumart_bmp_path could return
266 NULL if albumart doesn't exist or couldn't be loaded, or
267 read_bmp_file could have failed. return false and caller should
268 try the next mode (PICMODE_DEFAULT_PICTURE and PICMODE_NUMERALS will
269 always succeed) */
270 return false;
271}
272
204/* draws a spot at the coordinates (x,y), range of p is 1-20 */ 273/* draws a spot at the coordinates (x,y), range of p is 1-20 */
205static void draw_spot(int p, int x, int y) 274static void draw_spot(int p, int x, int y)
206{ 275{
207 if (pic || p==20) { 276 if (p == HOLE_ID)
208 rb->lcd_mono_bitmap (picture[p-1], x, y, 16, 16); 277 {
278#if LCD_DEPTH==1
279 /* the bottom-right cell of the default sliding_puzzle image is
280 an appropriate hole graphic */
281 rb->lcd_bitmap_part(sliding_puzzle, ((p-1)%SPOTS_X)*SPOTS_WIDTH,
282 ((p-1)/SPOTS_X)*SPOTS_HEIGHT,
283 IMAGE_WIDTH, x, y, SPOTS_WIDTH, SPOTS_HEIGHT);
284#else
285 /* just draw a black rectangle */
286 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
287 rb->lcd_set_background(LCD_BLACK);
288 rb->lcd_fillrect(x,y,SPOTS_WIDTH,SPOTS_HEIGHT);
289 rb->lcd_set_drawmode(DRMODE_SOLID);
290#endif
291 }
292 else if (picmode != PICMODE_NUMERALS)
293 {
294 rb->lcd_bitmap_part( puzzle_bmp_ptr, ((p-1)%SPOTS_X)*SPOTS_WIDTH,
295 ((p-1)/SPOTS_X)*SPOTS_HEIGHT,
296 IMAGE_WIDTH, x, y, SPOTS_WIDTH, SPOTS_HEIGHT);
209 } else { 297 } else {
210 rb->lcd_drawrect(x, y, 16, 16); 298 rb->lcd_drawrect(x, y, SPOTS_WIDTH, SPOTS_HEIGHT);
211 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); 299 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
212 rb->lcd_fillrect(x+1, y+1, 14, 14); 300 rb->lcd_fillrect(x+1, y+1, SPOTS_WIDTH-2, SPOTS_HEIGHT-2);
213 rb->lcd_set_drawmode(DRMODE_SOLID); 301 rb->lcd_set_drawmode(DRMODE_SOLID);
214 rb->snprintf(s, sizeof(s), "%d", p); 302 rb->snprintf(s, sizeof(s), "%d", p);
215 rb->lcd_putsxy(x+2, y+4, (unsigned char *)s); 303 rb->lcd_putsxy(x+2, y+4, (unsigned char *)s);
216 } 304 }
217} 305}
218 306
219/* check if the puzzle is solved */ 307/* check if the puzzle is solved */
220static bool puzzle_finished(void) 308static bool puzzle_finished(void)
221{ 309{
222 int i; 310 int i;
223 for (i=0; i<20; i++) 311 for (i=0; i<NUM_SPOTS; i++)
224 if (spots[i] != (i+1)) 312 if (spots[i] != (i+1))
225 return false; 313 return false;
226 return true; 314 return true;
227} 315}
228 316
229/* move a piece in any direction */ 317/* move a piece in any direction */
230static void move_spot(int x, int y) 318static void move_spot(int x, int y)
231{ 319{
232 int i; 320 int i;
233 spots[hole] = spots[hole-x-5*y]; 321 spots[hole] = spots[hole-x-SPOTS_X*y];
234 hole -= (x+5*y); 322 hole -= (x+SPOTS_X*y);
235 moves++; 323 moves++;
236 rb->snprintf(s, sizeof(s), "%d", moves); 324 rb->snprintf(s, sizeof(s), "%d", moves);
237 rb->lcd_putsxy(85, 20, (unsigned char *)s); 325 s[sizeof(s)-1] = '\0';
326#if (LCD_WIDTH>IMAGE_SIZE)
327 rb->lcd_putsxy(IMAGE_WIDTH+5, 20, (unsigned char *)s);
328#else
329 rb->lcd_putsxy(5, IMAGE_HEIGHT+20, (unsigned char *)s);
330#endif
238 331
239 for (i=4; i<=16; i+=4) { 332 for(i=1;i<=4;i++)
240 draw_spot(20, (hole%5)*16, (hole/5)*16); 333 {
241 draw_spot(spots[hole], (hole%5)*16 + x*i, (hole/5)*16 + y*i); 334 draw_spot(HOLE_ID,
242 rb->lcd_update(); 335 (hole%SPOTS_X)*SPOTS_WIDTH,
336 (hole/SPOTS_X)*SPOTS_HEIGHT);
337 draw_spot(spots[hole],
338 (hole%SPOTS_X)*SPOTS_WIDTH + (i*x*SPOTS_WIDTH)/5,
339 (hole/SPOTS_X)*SPOTS_HEIGHT + (i*y*SPOTS_HEIGHT)/5);
340 rb->lcd_update();
341 rb->sleep(HZ/50);
243 } 342 }
244 spots[hole] = 20; 343 draw_spot(HOLE_ID,
344 (hole%SPOTS_X)*SPOTS_WIDTH,
345 (hole/SPOTS_X)*SPOTS_HEIGHT);
346 draw_spot(spots[hole],
347 ((hole%SPOTS_X)+x)*SPOTS_WIDTH,
348 ((hole/SPOTS_X)+y)*SPOTS_HEIGHT);
349 rb->lcd_update();
350
351 spots[hole] = HOLE_ID;
245} 352}
246 353
247/* initializes the puzzle */ 354/* initializes the puzzle */
248static void puzzle_init(void) 355static void puzzle_init(void)
249{ 356{
250 int i, r, temp, tsp[20]; 357 int i, r, temp, tsp[NUM_SPOTS];
358
251 moves = 0; 359 moves = 0;
252 rb->lcd_clear_display(); 360 rb->lcd_clear_display();
253 rb->lcd_drawrect(80, 0, 32, 64);
254 rb->lcd_putsxy(81, 10, (unsigned char *)"Moves");
255 rb->snprintf(s, sizeof(s), "%d", moves); 361 rb->snprintf(s, sizeof(s), "%d", moves);
256 rb->lcd_putsxy(85, 20, (unsigned char *)s); 362
257 363#if (LCD_WIDTH>IMAGE_SIZE)
364 rb->lcd_drawrect(IMAGE_WIDTH, 0, 32, 64);
365 rb->lcd_putsxy(IMAGE_WIDTH+1, 10, (unsigned char *)"Moves");
366 rb->lcd_putsxy(IMAGE_WIDTH+5, 20, (unsigned char *)s);
367#else
368 rb->lcd_drawrect(0, IMAGE_HEIGHT, 32, 64);
369 rb->lcd_putsxy(1, IMAGE_HEIGHT+10, (unsigned char *)"Moves");
370 rb->lcd_putsxy(5, IMAGE_HEIGHT+20, (unsigned char *)s);
371#endif
372
258 /* shuffle spots */ 373 /* shuffle spots */
259 for (i=19; i>=0; i--) { 374 for (i=NUM_SPOTS-1; i>=0; i--) {
260 r = (rb->rand() % (i+1)); 375 r = (rb->rand() % (i+1));
261 376
262 temp = spots[r]; 377 temp = spots[r];
263 spots[r] = spots[i]; 378 spots[r] = spots[i];
264 spots[i] = temp; 379 spots[i] = temp;
265 380
266 if (spots[i]==20) 381 if (spots[i]==HOLE_ID)
267 hole = i; 382 hole = i;
268 } 383 }
269 384
270 /* test if the puzzle is solvable */ 385 /* test if the puzzle is solvable */
271 for (i=0; i<20; i++) 386 for (i=0; i<NUM_SPOTS; i++)
272 tsp[i] = spots[i]; 387 tsp[i] = spots[i];
273 r=0; 388 r=0;
274 389
275 /* First, check if the problem has even or odd parity, 390 /* First, check if the problem has even or odd parity,
276 depending on where the empty square is */ 391 depending on where the empty square is */
277 if (((4-hole%5) + (3-hole/5))%2 == 1) 392 if ((((SPOTS_X-1)-hole%SPOTS_X) + ((SPOTS_Y-1)-hole/SPOTS_X))%2 == 1)
278 ++r; 393 ++r;
279 394
280 /* Now check how many swaps we need to solve it */ 395 /* Now check how many swaps we need to solve it */
281 for (i=0; i<19; i++) { 396 for (i=0; i<NUM_SPOTS-1; i++) {
282 while (tsp[i] != (i+1)) { 397 while (tsp[i] != (i+1)) {
283 temp = tsp[i]; 398 temp = tsp[i];
284 tsp[i] = tsp[temp-1]; 399 tsp[i] = tsp[temp-1];
@@ -286,10 +401,10 @@ static void puzzle_init(void)
286 ++r; 401 ++r;
287 } 402 }
288 } 403 }
289 404
290 /* if the random puzzle isn't solvable just change two spots */ 405 /* if the random puzzle isn't solvable just change two spots */
291 if (r%2 == 1) { 406 if (r%2 == 1) {
292 if (spots[0]!=20 && spots[1]!=20) { 407 if (spots[0]!=HOLE_ID && spots[1]!=HOLE_ID) {
293 temp = spots[0]; 408 temp = spots[0];
294 spots[0] = spots[1]; 409 spots[0] = spots[1];
295 spots[1] = temp; 410 spots[1] = temp;
@@ -299,10 +414,11 @@ static void puzzle_init(void)
299 spots[3] = temp; 414 spots[3] = temp;
300 } 415 }
301 } 416 }
302 417
303 /* draw spots to the lcd */ 418 /* draw spots to the lcd */
304 for (i=0; i<20; i++) 419 for (i=0; i<NUM_SPOTS; i++)
305 draw_spot(spots[i], (i%5)*16, (i/5)*16); 420 draw_spot(spots[i], (i%SPOTS_X)*SPOTS_WIDTH, (i/SPOTS_X)*SPOTS_HEIGHT);
421
306 rb->lcd_update(); 422 rb->lcd_update();
307} 423}
308 424
@@ -312,6 +428,8 @@ static int puzzle_loop(void)
312 int button; 428 int button;
313 int lastbutton = BUTTON_NONE; 429 int lastbutton = BUTTON_NONE;
314 int i; 430 int i;
431 bool load_success;
432
315 puzzle_init(); 433 puzzle_init();
316 while(true) { 434 while(true) {
317 button = rb->button_get(true); 435 button = rb->button_get(true);
@@ -331,39 +449,63 @@ static int puzzle_loop(void)
331 /* mix up the pieces */ 449 /* mix up the pieces */
332 puzzle_init(); 450 puzzle_init();
333 break; 451 break;
334 452
335 case PUZZLE_PICTURE: 453 case PUZZLE_PICTURE:
336#ifdef PUZZLE_SHUFFLE_PICTURE_PRE 454#ifdef PUZZLE_SHUFFLE_PICTURE_PRE
337 if (lastbutton != PUZZLE_SHUFFLE_PICTURE_PRE) 455 if (lastbutton != PUZZLE_SHUFFLE_PICTURE_PRE)
338 break; 456 break;
339#endif 457#endif
340 /* change picture */ 458 /* change picture */
341 pic = (pic==true?false:true); 459 picmode = (picmode+1)%PICMODE_LAST_XXX;
342 for (i=0; i<20; i++) 460
343 draw_spot(spots[i], (i%5)*16, (i/5)*16); 461 /* if load_resize_bitmap fails to load bitmap, try next picmode */
462 do
463 {
464 load_success = load_resize_bitmap();
465 if( !load_success )
466 picmode = (picmode+1)%PICMODE_LAST_XXX;
467 }
468 while( !load_success );
469
470 /* tell the user what mode we picked in the end! */
471 rb->splash(HZ,picmode_descriptions[ picmode ] );
472 rb->lcd_clear_display();
473#if (LCD_WIDTH>IMAGE_SIZE)
474 rb->lcd_drawrect(IMAGE_WIDTH, 0, 32, 64);
475 rb->lcd_putsxy(IMAGE_WIDTH+1, 10, (unsigned char *)"Moves");
476#else
477 rb->lcd_drawrect(0,IMAGE_HEIGHT,32,64);
478 rb->lcd_putsxy(1,IMAGE_HEIGHT+10, (unsigned char *)"Moves");
479#endif
480
481 for (i=0; i<NUM_SPOTS; i++)
482 draw_spot(spots[i],
483 (i%SPOTS_X)*SPOTS_WIDTH,
484 (i/SPOTS_X)*SPOTS_HEIGHT);
344 rb->lcd_update(); 485 rb->lcd_update();
486
345 break; 487 break;
346 488
347 case BUTTON_LEFT: 489 case BUTTON_LEFT:
348 if ((hole%5)<4 && !puzzle_finished()) 490 if ((hole%SPOTS_X)<(SPOTS_X-1) && !puzzle_finished())
349 move_spot(-1, 0); 491 move_spot(-1, 0);
350 break; 492 break;
351 493
352 case BUTTON_RIGHT: 494 case BUTTON_RIGHT:
353 if ((hole%5)>0 && !puzzle_finished()) 495 if ((hole%SPOTS_X)>0 && !puzzle_finished())
354 move_spot(1, 0); 496 move_spot(1, 0);
355 break; 497 break;
356 498
357 case PUZZLE_UP: 499 case PUZZLE_UP:
358 if ((hole/5)<3 && !puzzle_finished()) 500 if ((hole/SPOTS_X)<(SPOTS_Y-1) && !puzzle_finished())
359 move_spot(0, -1); 501 move_spot(0, -1);
360 break; 502 break;
361 503
362 case PUZZLE_DOWN: 504 case PUZZLE_DOWN:
363 if ((hole/5)>0 && !puzzle_finished()) 505 if ((hole/SPOTS_X)>0 && !puzzle_finished())
364 move_spot(0, 1); 506 move_spot(0, 1);
365 break; 507 break;
366 508
367 default: 509 default:
368 if (rb->default_event_handler(button) == SYS_USB_CONNECTED) 510 if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
369 return PLUGIN_USB_CONNECTED; 511 return PLUGIN_USB_CONNECTED;
@@ -373,56 +515,115 @@ static int puzzle_loop(void)
373 lastbutton = button; 515 lastbutton = button;
374 } 516 }
375} 517}
376 518
377enum plugin_status plugin_start(struct plugin_api* api, void* parameter) 519enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
378{ 520{
379 int i, w, h; 521 int i, w, h;
380 522
381 (void)parameter;
382 rb = api; 523 rb = api;
383
384 /* print title */
385 rb->lcd_getstringsize((unsigned char *)"Sliding Puzzle", &w, &h);
386 w = (w+1)/2;
387 h = (h+1)/2;
388 rb->lcd_clear_display();
389 rb->lcd_putsxy(LCD_WIDTH/2-w, (LCD_HEIGHT/2)-h, (unsigned char *)"Sliding Puzzle");
390 rb->lcd_update();
391 rb->sleep(HZ);
392 524
393 /* print instructions */ 525 initial_bmp_path=(const char *)parameter;
394 rb->lcd_clear_display(); 526 picmode = PICMODE_INITIAL_PICTURE;
395 rb->lcd_setfont(FONT_SYSFIXED); 527 img_buf_path[0] = '\0';
396#if CONFIG_KEYPAD == RECORDER_PAD 528
397 rb->lcd_putsxy(3, 18, "[OFF] to stop"); 529 /* If launched as a viewer, just go straight to the game without
398 rb->lcd_putsxy(3, 28, "[F1] shuffle"); 530 bothering with the splash or instructions page */
399 rb->lcd_putsxy(3, 38, "[F2] change pic"); 531 if(parameter==NULL)
532 {
533 /* if not launched as a viewer, use default puzzle, and show help */
534 picmode = PICMODE_DEFAULT_PICTURE;
535
536 /* print title */
537 rb->lcd_getstringsize((unsigned char *)"Sliding Puzzle", &w, &h);
538 w = (w+1)/2;
539 h = (h+1)/2;
540 rb->lcd_clear_display();
541 rb->lcd_putsxy(LCD_WIDTH/2-w, (LCD_HEIGHT/2)-h,
542 (unsigned char *)"Sliding Puzzle");
543 rb->lcd_update();
544 rb->sleep(HZ);
545
546 /* print instructions */
547 rb->lcd_clear_display();
548 rb->lcd_setfont(FONT_SYSFIXED);
549#if CONFIG_KEYPAD == RECORDER_PAD || CONFIG_KEYPAD == ARCHOS_AV300_PAD
550 rb->lcd_putsxy(3, 18, "[OFF] to stop");
551 rb->lcd_putsxy(3, 28, "[F1] shuffle");
552 rb->lcd_putsxy(3, 38, "[F2] change pic");
400#elif CONFIG_KEYPAD == ONDIO_PAD 553#elif CONFIG_KEYPAD == ONDIO_PAD
401 rb->lcd_putsxy(0, 18, "[OFF] to stop"); 554 rb->lcd_putsxy(0, 18, "[OFF] to stop");
402 rb->lcd_putsxy(0, 28, "[MODE..] shuffle"); 555 rb->lcd_putsxy(0, 28, "[MODE..] shuffle");
403 rb->lcd_putsxy(0, 38, "[MODE] change pic"); 556 rb->lcd_putsxy(0, 38, "[MODE] change pic");
404#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \ 557#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
405 (CONFIG_KEYPAD == IPOD_3G_PAD) || \ 558 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
406 (CONFIG_KEYPAD == IPOD_1G2G_PAD) 559 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
407 rb->lcd_putsxy(0, 18, "[S-MENU] to stop"); 560 rb->lcd_putsxy(0, 18, "[S-MENU] to stop");
408 rb->lcd_putsxy(0, 28, "[S-LEFT] shuffle"); 561 rb->lcd_putsxy(0, 28, "[S-LEFT] shuffle");
409 rb->lcd_putsxy(0, 38, "[S-RIGHT] change pic"); 562 rb->lcd_putsxy(0, 38, "[S-RIGHT] change pic");
563#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
564 (CONFIG_KEYPAD == IRIVER_H300_PAD)
565 rb->lcd_putsxy(0, 18, "[STOP] to stop");
566 rb->lcd_putsxy(0, 28, "[SELECT] shuffle");
567 rb->lcd_putsxy(0, 38, "[PLAY] change pic");
568#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
569 rb->lcd_putsxy(0, 18, "[OFF] to stop");
570 rb->lcd_putsxy(0, 28, "[REC] shuffle");
571 rb->lcd_putsxy(0, 38, "[PLAY] change pic");
572#elif CONFIG_KEYPAD == GIGABEAT_PAD
573 rb->lcd_putsxy(0, 18, "[OFF] to stop");
574 rb->lcd_putsxy(0, 28, "[SELECT] shuffle");
575 rb->lcd_putsxy(0, 38, "[A] change pic");
576#elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
577 (CONFIG_KEYPAD == SANSE_C200_PAD)
578 rb->lcd_putsxy(0, 18, "[OFF] to stop");
579 rb->lcd_putsxy(0, 28, "[REC] shuffle");
580 rb->lcd_putsxy(0, 38, "[SELECT] change pic");
581#elif CONFIG_KEYPAD == IRIVER_H10_PAD
582 rb->lcd_putsxy(0, 18, "[OFF] to stop");
583 rb->lcd_putsxy(0, 28, "[REW] shuffle");
584 rb->lcd_putsxy(0, 38, "[PLAY] change pic");
410#endif 585#endif
411 rb->lcd_update(); 586#ifdef HAVE_ALBUMART
412 rb->button_get_w_tmo(HZ*2); 587 rb->lcd_putsxy(0,48," pic->albumart->num");
413 588#else
589 rb->lcd_putsxy(0,48," pic<->num");
590#endif
591 rb->lcd_update();
592 rb->button_get_w_tmo(HZ*2);
593 }
594
595 hole = INITIAL_HOLE;
596
597 if( !load_resize_bitmap() )
598 {
599 rb->lcd_clear_display();
600 rb->splash(HZ*2,"Failed to load bitmap!");
601 return PLUGIN_OK;
602 }
603
604#if LCD_DEPTH>1
605 rb->lcd_set_background(LCD_BLACK);
606 rb->lcd_set_foreground(LCD_WHITE);
607 rb->lcd_set_backdrop(NULL);
608#endif
609
414 rb->lcd_clear_display(); 610 rb->lcd_clear_display();
415 rb->lcd_drawrect(80, 0, 32, 64); 611#if (LCD_WIDTH>IMAGE_SIZE)
416 rb->lcd_putsxy(81, 10, (unsigned char *)"Moves"); 612 rb->lcd_drawrect(IMAGE_WIDTH, 0, 32, 64);
417 for (i=0; i<20; i++) { 613 rb->lcd_putsxy(IMAGE_WIDTH+1, 10, (unsigned char *)"Moves");
614#else
615 rb->lcd_drawrect(0,IMAGE_HEIGHT,32,64);
616 rb->lcd_putsxy(1,IMAGE_HEIGHT+10, (unsigned char *)"Moves");
617#endif
618
619 for (i=0; i<NUM_SPOTS; i++) {
418 spots[i]=(i+1); 620 spots[i]=(i+1);
419 draw_spot(spots[i], (i%5)*16, (i/5)*16); 621 draw_spot(spots[i], (i%SPOTS_X)*SPOTS_WIDTH, (i/SPOTS_X)*SPOTS_HEIGHT);
420 } 622 }
421 hole = 19; 623
422 pic = true;
423 rb->lcd_update(); 624 rb->lcd_update();
424 rb->sleep(HZ*2); 625 rb->sleep(HZ*2);
425 626
426 return puzzle_loop(); 627 return puzzle_loop();
427} 628}
428 629
diff --git a/apps/plugins/viewers.config b/apps/plugins/viewers.config
index 375128e7c4..bfb408c397 100644
--- a/apps/plugins/viewers.config
+++ b/apps/plugins/viewers.config
@@ -26,6 +26,7 @@ wav,viewers/wavplay,9
26wav,viewers/wavview,10 26wav,viewers/wavview,10
27wav,viewers/test_codec,- 27wav,viewers/test_codec,-
28bmp,apps/rockpaint,11 28bmp,apps/rockpaint,11
29bmp,games/sliding_puzzle,11
29mpg,viewers/mpegplayer,4 30mpg,viewers/mpegplayer,4
30mpeg,viewers/mpegplayer,4 31mpeg,viewers/mpegplayer,4
31mpv,viewers/mpegplayer,4 32mpv,viewers/mpegplayer,4