summaryrefslogtreecommitdiff
path: root/apps/plugins
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 /apps/plugins
parent59914786289033648db9bd5f4222978767e4d665 (diff)
downloadrockbox-02f1839bfe4766ac72631bd7b76f2fc7f291b89e.zip
rockbox-02f1839bfe4766ac72631bd7b76f2fc7f291b89e.tar.gz
rockbox-02f1839bfe4766ac72631bd7b76f2fc7f291b89e.tar.bz2
rockbox-02f1839bfe4766ac72631bd7b76f2fc7f291b89e.tar.xz
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
Diffstat (limited to 'apps/plugins')
-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 61c9b7a..73ee211 100644
--- a/apps/plugins/bitmaps/native/SOURCES
+++ b/apps/plugins/bitmaps/native/SOURCES
@@ -546,4 +546,25 @@ matrix_normal.bmp
#endif
#endif
+#if defined(HAVE_LCD_COLOR)
+#if (LCD_WIDTH==132 && LCD_HEIGHT==80)
+ sliding_puzzle.80x80x16.bmp
+#elif (LCD_WIDTH==128 || LCD_HEIGHT==128)
+ sliding_puzzle.128x128x16.bmp
+#elif (LCD_WIDTH==176 || LCD_WIDTH==176)
+ sliding_puzzle.176x176x16.bmp
+#elif (LCD_WIDTH==240 || LCD_HEIGHT==240)
+ sliding_puzzle.240x240x16.bmp
+#endif
+#elif (LCD_DEPTH>1)
+#if (LCD_WIDTH==110 || LCD_HEIGHT==110)
+ sliding_puzzle.110x110x2.bmp
+#elif (LCD_WIDTH==128 || LCD_HEIGHT==128)
+ sliding_puzzle.128x128x2.bmp
+#endif
+#elif (LCD_WIDTH>=80 && LCD_HEIGHT==64)
+ sliding_puzzle.80x64x1.bmp
+#endif
+
+
#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 0000000..e21531e
--- /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 0000000..1fc05dc
--- /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 0000000..e8ef4ee
--- /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 0000000..dff5a11
--- /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 0000000..d1de3a8
--- /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 0000000..a394e8e
--- /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 0000000..4c386bf
--- /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 0000000..ed7e191
--- /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 94372dc..c1f5a48 100644
--- a/apps/plugins/lib/SOURCES
+++ b/apps/plugins/lib/SOURCES
@@ -25,7 +25,7 @@ picture.c
xlcd_core.c
xlcd_draw.c
xlcd_scroll.c
-#ifdef HAVE_LCD_COLOR
+#if LCD_DEPTH>1
bmp.c
#endif
#endif
diff --git a/apps/plugins/lib/bmp.c b/apps/plugins/lib/bmp.c
index 03bdc73..20adc6d 100644
--- a/apps/plugins/lib/bmp.c
+++ b/apps/plugins/lib/bmp.c
@@ -24,6 +24,7 @@
#include "lcd.h"
#include "system.h"
+#ifdef HAVE_LCD_COLOR
#define LE16(x) (htole16(x))&0xff, ((htole16(x))>>8)&0xff
#define LE32(x) (htole32(x))&0xff, ((htole32(x))>>8)&0xff, ((htole32(x))>>16)&0xff, ((htole32(x))>>24)&0xff
/**
@@ -82,6 +83,7 @@ int save_bmp_file( char* filename, struct bitmap *bm, struct plugin_api* rb )
rb->close( fh );
return 1;
}
+#endif
/**
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 e35c1ec..3e14243 100644
--- a/apps/plugins/lib/bmp.h
+++ b/apps/plugins/lib/bmp.h
@@ -22,10 +22,12 @@
#include "lcd.h"
#include "plugin.h"
+#ifdef HAVE_LCD_COLOR
/**
* Save bitmap to file
*/
int save_bmp_file( char* filename, struct bitmap *bm, struct plugin_api* rb );
+#endif
/**
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 17a96ba..223c107 100644
--- a/apps/plugins/sliding_puzzle.c
+++ b/apps/plugins/sliding_puzzle.c
@@ -17,8 +17,9 @@
*
****************************************************************************/
#include "plugin.h"
-#ifdef HAVE_LCD_BITMAP
+#include "bmp.h"
+#ifdef HAVE_LCD_BITMAP
PLUGIN_HEADER
/* variable button definitions */
@@ -95,190 +96,304 @@ PLUGIN_HEADER
#endif
static struct plugin_api* rb;
-static int spots[20];
-static int hole = 19, moves;
-static char s[5];
-static bool pic = true;
-static unsigned char picture[20][32] = {
- { 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0xf8, 0xd9,
- 0x10, 0xb0, 0x60, 0xc0, 0x80, 0x00, 0x30, 0x78,
- 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x01, 0x07,
- 0xbf, 0xf8, 0x43, 0x1c, 0x61, 0x5e, 0xfc, 0xfc },
-
- { 0x68, 0xc8, 0x48, 0x08, 0x98, 0x90, 0xb0, 0xa4,
- 0xa0, 0xc0, 0xc0, 0x88, 0x14, 0x08, 0x00, 0x00,
- 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x03,
- 0x00, 0x00, 0x30, 0x48, 0x79, 0x33, 0x06, 0x1c },
-
- { 0x20, 0x00, 0x06, 0x09, 0x09, 0x06, 0x00, 0x80,
- 0x40, 0x80, 0x00, 0x08, 0x14, 0x08, 0x20, 0x00,
- 0x60, 0x30, 0x18, 0xf9, 0x70, 0x00, 0x00, 0x00,
- 0xf9, 0x18, 0x30, 0x60, 0x30, 0x18, 0x06, 0x32 },
-
- { 0x00, 0x80, 0x42, 0xa0, 0x50, 0x90, 0x88, 0x88,
- 0x84, 0xa4, 0xa4, 0x64, 0x24, 0x18, 0x00, 0x40,
- 0x79, 0x4a, 0x31, 0x02, 0x05, 0x2a, 0xd5, 0xaa,
- 0x55, 0xaa, 0x55, 0xab, 0x56, 0xac, 0x58, 0xb0 },
-
- { 0x04, 0x0a, 0x04, 0x00, 0x80, 0x80, 0xc0, 0xc8,
- 0x40, 0xc2, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00,
- 0x60, 0x38, 0x9c, 0xe7, 0x59, 0x0c, 0xc4, 0xfc,
- 0x3f, 0x07, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00 },
-
- { 0x00, 0x04, 0x00, 0x00, 0x80, 0xe0, 0x78, 0x1e,
- 0xa7, 0xd9, 0xcc, 0x76, 0x3b, 0x0d, 0x1f, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x03, 0x13, 0x03, 0x03,
- 0x11, 0x29, 0x10, 0x00, 0x04, 0x2a, 0x0b, 0x0b },
-
- { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0,
- 0xc0, 0x8e, 0x10, 0x00, 0x80, 0x80, 0x60, 0x38,
- 0x0a, 0x08, 0x05, 0x05, 0x07, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x01, 0x11, 0x01, 0x00, 0x00, 0x80 },
-
- { 0x0e, 0x18, 0x31, 0x3e, 0x1c, 0x00, 0x00, 0x1c,
- 0x3e, 0x31, 0x18, 0x0c, 0x0c, 0x18, 0x30, 0x20,
- 0x00, 0x00, 0x08, 0x14, 0x08, 0x00, 0x02, 0x80,
- 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00 },
-
- { 0x60, 0xc0, 0x48, 0xc7, 0x60, 0xb8, 0x57, 0xaa,
- 0x55, 0xaa, 0x55, 0xaa, 0xd5, 0xaa, 0x75, 0x3a,
- 0x00, 0x00, 0x01, 0x23, 0x05, 0x05, 0x09, 0x0a,
- 0x0b, 0x0a, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00 },
-
- { 0xe5, 0x8d, 0x18, 0x30, 0x41, 0xc1, 0x8f, 0xfe,
- 0xf0, 0x81, 0x0a, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x01, 0x03, 0x02, 0x06, 0x06, 0x04, 0x04,
- 0x04, 0x05, 0x07, 0x06, 0x00, 0x00, 0x00, 0x00 },
-
- { 0x00, 0x00, 0x00, 0x10, 0x28, 0x10, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
- 0xc0, 0xb0, 0x18, 0xcc, 0x24, 0x86, 0x42, 0x22,
- 0x31, 0x69, 0xd1, 0xa9, 0x51, 0xa1, 0x41, 0x02 },
-
- { 0x00, 0x00, 0x00, 0x00, 0x40, 0xa1, 0x40, 0x00,
- 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x12, 0x16, 0x5c, 0x58, 0xf0, 0xc0, 0x00, 0x00,
- 0x06, 0x09, 0x09, 0x86, 0x60, 0x18, 0xc4, 0xf2 },
-
- { 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x40, 0x40,
- 0x40, 0x40, 0x40, 0x40, 0xc0, 0x80, 0x8c, 0x12,
- 0x6a, 0xa5, 0x95, 0xd2, 0xca, 0xc9, 0xe9, 0xe9,
- 0xe1, 0xe9, 0xe1, 0xe1, 0x62, 0x62, 0xc5, 0xc5 },
-
- { 0x12, 0x0c, 0x00, 0x80, 0x80, 0x40, 0x40, 0x40,
- 0x40, 0x40, 0x40, 0x82, 0x85, 0x02, 0x00, 0x00,
- 0x8a, 0x32, 0x6f, 0xd6, 0xaa, 0x55, 0x83, 0x01,
- 0x81, 0x01, 0x81, 0x82, 0x82, 0x0d, 0xbe, 0xdc },
-
- { 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00,
- 0x41, 0x00, 0x00, 0x00, 0x02, 0x05, 0x02, 0x00,
- 0x00, 0x00, 0x01, 0x02, 0x01, 0x04, 0x00, 0x60,
- 0x90, 0x90, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00 },
-
- { 0x3f, 0x6a, 0xc0, 0x9f, 0x20, 0x27, 0x48, 0x4b,
- 0x47, 0x22, 0x50, 0x0f, 0x95, 0x4a, 0x25, 0x90,
- 0x07, 0x0f, 0x17, 0x23, 0x43, 0x42, 0x44, 0x40,
- 0x44, 0x40, 0x42, 0x40, 0x60, 0x30, 0x3c, 0x1f },
-
- { 0xd0, 0x50, 0x11, 0xb9, 0xef, 0x07, 0x80, 0x40,
- 0x30, 0x98, 0x9c, 0xbf, 0x60, 0xc7, 0x0d, 0x36,
- 0x59, 0x11, 0x21, 0x23, 0x22, 0x21, 0x30, 0x10,
- 0x0d, 0x42, 0x01, 0x80, 0x00, 0x40, 0x03, 0x0c },
-
- { 0xc3, 0x81, 0x81, 0x00, 0x00, 0x01, 0x03, 0x03,
- 0x03, 0x03, 0x02, 0x01, 0x00, 0x00, 0x80, 0x80,
- 0x10, 0x91, 0x23, 0x23, 0x67, 0xe6, 0xe6, 0xa6,
- 0xa6, 0xa6, 0xa6, 0xa6, 0xb3, 0x93, 0x59, 0x49 },
-
- { 0xc1, 0x71, 0xff, 0x54, 0x0a, 0x02, 0x06, 0x0e,
- 0x0e, 0x0a, 0x06, 0x02, 0x02, 0xc5, 0x7b, 0x17,
- 0x24, 0x10, 0x3b, 0x7f, 0x92, 0xa6, 0xa4, 0xa4,
- 0xa4, 0xa4, 0xa4, 0x66, 0x23, 0x11, 0x12, 0x0c },
-
- { 0x55, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
- 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0xaa,
- 0x55, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80,
- 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0xaa }
+#if LCD_DEPTH==1
+/* for recorder, use rectangular image, 5x4 puzzle */
+#define SPOTS_X 5
+#define SPOTS_Y 4
+#define SPOTS_WIDTH 16
+#define SPOTS_HEIGHT 16
+#define IMAGE_WIDTH 80
+#define IMAGE_HEIGHT 64
+#define IMAGE_SIZE 80
+#else
+/* for other targets, use a square image, 4x4 puzzle
+ Puzzle image dimension is min(lcd_height,lcd_width)
+ 4x4 is more convenient than 5x4 for square puzzles
+ Note: sliding_puzzle.bmp should be evenly divisible by SPOTS_X
+ and SPOTS_Y, otherwise lcd_bitmap_part stride won't be correct */
+#define SPOTS_X 4
+#define SPOTS_Y 4
+#define IMAGE_SIZE ( (LCD_WIDTH<LCD_HEIGHT)?LCD_WIDTH:LCD_HEIGHT )
+#define IMAGE_WIDTH IMAGE_SIZE
+#define IMAGE_HEIGHT IMAGE_SIZE
+#define SPOTS_WIDTH (IMAGE_WIDTH/SPOTS_X)
+#define SPOTS_HEIGHT (IMAGE_HEIGHT/SPOTS_Y)
+#endif
+
+#define NUM_SPOTS (SPOTS_X*SPOTS_Y)
+#define HOLE_ID (NUM_SPOTS)
+#define INITIAL_HOLE (HOLE_ID-1)
+
+enum picmodes
+{
+ PICMODE_NUMERALS = 0,
+ PICMODE_INITIAL_PICTURE,
+ PICMODE_DEFAULT_PICTURE,
+#ifdef HAVE_ALBUMART
+ PICMODE_ALBUM_ART,
+#endif
+// PICMODE_RANDOM,
+ PICMODE_LAST_XXX /* placeholder */
+};
+
+static const char* const picmode_descriptions[] = {
+ "Numerals",
+ "Viewer Picture",
+ "Default Picture",
+#ifdef HAVE_ALBUMART
+ "Album Art",
+#endif
+ "Shouldn't Get Here",
};
+static int spots[NUM_SPOTS];
+static int hole = INITIAL_HOLE, moves;
+static char s[5];
+static enum picmodes picmode = PICMODE_INITIAL_PICTURE;
+
+static unsigned char img_buf[IMAGE_WIDTH*IMAGE_HEIGHT*sizeof(fb_data)]
+__attribute__ ((aligned(16)));
+#if LCD_DEPTH>1
+static unsigned char temp_img_buf[LCD_WIDTH*LCD_HEIGHT*sizeof(fb_data)]
+__attribute__ ((aligned(16)));
+#endif
+#ifdef HAVE_ALBUMART
+static char albumart_path[MAX_PATH+1];
+#endif
+static char img_buf_path[MAX_PATH+1];
+
+static const fb_data * puzzle_bmp_ptr;
+extern const fb_data sliding_puzzle[];
+/* initial_bmp_path points to selected bitmap if this game is launched
+ as a viewer for a .bmp file, or NULL if game is launched regular way */
+static const char * initial_bmp_path=NULL;
+
+#ifdef HAVE_ALBUMART
+const char * get_albumart_bmp_path(void)
+{
+ struct mp3entry* track = rb->audio_current_track();
+
+ if (!track || !track->path || track->path[0] == '\0')
+ return NULL;
+
+ if (!rb->search_albumart_files(track, "", albumart_path, MAX_PATH ) )
+ return NULL;
+
+ albumart_path[ MAX_PATH ] = '\0';
+ return albumart_path;
+}
+#endif
+
+const char * get_random_bmp_path(void)
+{
+ return(initial_bmp_path);
+}
+
+static bool load_resize_bitmap(void)
+{
+ int rc;
+ const char * filename = NULL;
+
+ /* initially assume using the built-in default */
+ puzzle_bmp_ptr = sliding_puzzle;
+
+ switch( picmode ){
+ /* some modes don't even need to touch disk and trivially succeed */
+ case PICMODE_NUMERALS:
+ case PICMODE_DEFAULT_PICTURE:
+ default:
+ return(true);
+
+#ifdef HAVE_ALBUMART
+ case PICMODE_ALBUM_ART:
+ filename = get_albumart_bmp_path();
+ break;
+#endif
+/*
+ case PICMODE_RANDOM:
+ if(NULL == (filename=get_random_bmp_path()) )
+ filename = initial_bmp_path;
+ break;
+*/
+ case PICMODE_INITIAL_PICTURE:
+ filename = initial_bmp_path;
+ break;
+ };
+
+ if( filename != NULL )
+ {
+ /* if we already loaded image before, don't touch disk */
+ if( 0 == rb->strcmp( filename, img_buf_path ) )
+ {
+ puzzle_bmp_ptr = (const fb_data *)img_buf;
+ return true;
+ }
+
+ struct bitmap main_bitmap;
+ rb->memset(&main_bitmap,0,sizeof(struct bitmap));
+ main_bitmap.data = img_buf;
+
+#if LCD_DEPTH>1
+ struct bitmap temp_bitmap;
+ rb->memset(&temp_bitmap,0,sizeof(struct bitmap));
+ temp_bitmap.data = temp_img_buf;
+
+ main_bitmap.width = IMAGE_WIDTH;
+ main_bitmap.height = IMAGE_HEIGHT;
+
+ rc = rb->read_bmp_file( filename, &temp_bitmap, sizeof(temp_img_buf),
+ FORMAT_NATIVE );
+ if( rc > 0 )
+ {
+ simple_resize_bitmap( &temp_bitmap, &main_bitmap );
+ puzzle_bmp_ptr = (const fb_data *)img_buf;
+ rb->strcpy( img_buf_path, filename );
+ return true;
+ }
+#else
+ rc = rb->read_bmp_file( filename, &main_bitmap, sizeof(img_buf),
+ FORMAT_NATIVE );
+ if( rc > 0 )
+ {
+ puzzle_bmp_ptr = (const fb_data *)img_buf;
+ rb->strcpy( img_buf_path, filename );
+ return true;
+ }
+#endif
+ }
+
+ /* something must have failed. get_albumart_bmp_path could return
+ NULL if albumart doesn't exist or couldn't be loaded, or
+ read_bmp_file could have failed. return false and caller should
+ try the next mode (PICMODE_DEFAULT_PICTURE and PICMODE_NUMERALS will
+ always succeed) */
+ return false;
+}
+
/* draws a spot at the coordinates (x,y), range of p is 1-20 */
static void draw_spot(int p, int x, int y)
{
- if (pic || p==20) {
- rb->lcd_mono_bitmap (picture[p-1], x, y, 16, 16);
+ if (p == HOLE_ID)
+ {
+#if LCD_DEPTH==1
+ /* the bottom-right cell of the default sliding_puzzle image is
+ an appropriate hole graphic */
+ rb->lcd_bitmap_part(sliding_puzzle, ((p-1)%SPOTS_X)*SPOTS_WIDTH,
+ ((p-1)/SPOTS_X)*SPOTS_HEIGHT,
+ IMAGE_WIDTH, x, y, SPOTS_WIDTH, SPOTS_HEIGHT);
+#else
+ /* just draw a black rectangle */
+ rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
+ rb->lcd_set_background(LCD_BLACK);
+ rb->lcd_fillrect(x,y,SPOTS_WIDTH,SPOTS_HEIGHT);
+ rb->lcd_set_drawmode(DRMODE_SOLID);
+#endif
+ }
+ else if (picmode != PICMODE_NUMERALS)
+ {
+ rb->lcd_bitmap_part( puzzle_bmp_ptr, ((p-1)%SPOTS_X)*SPOTS_WIDTH,
+ ((p-1)/SPOTS_X)*SPOTS_HEIGHT,
+ IMAGE_WIDTH, x, y, SPOTS_WIDTH, SPOTS_HEIGHT);
} else {
- rb->lcd_drawrect(x, y, 16, 16);
+ rb->lcd_drawrect(x, y, SPOTS_WIDTH, SPOTS_HEIGHT);
rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
- rb->lcd_fillrect(x+1, y+1, 14, 14);
+ rb->lcd_fillrect(x+1, y+1, SPOTS_WIDTH-2, SPOTS_HEIGHT-2);
rb->lcd_set_drawmode(DRMODE_SOLID);
rb->snprintf(s, sizeof(s), "%d", p);
rb->lcd_putsxy(x+2, y+4, (unsigned char *)s);
}
}
-
+
/* check if the puzzle is solved */
static bool puzzle_finished(void)
{
int i;
- for (i=0; i<20; i++)
+ for (i=0; i<NUM_SPOTS; i++)
if (spots[i] != (i+1))
return false;
return true;
}
-
+
/* move a piece in any direction */
static void move_spot(int x, int y)
{
int i;
- spots[hole] = spots[hole-x-5*y];
- hole -= (x+5*y);
+ spots[hole] = spots[hole-x-SPOTS_X*y];
+ hole -= (x+SPOTS_X*y);
moves++;
rb->snprintf(s, sizeof(s), "%d", moves);
- rb->lcd_putsxy(85, 20, (unsigned char *)s);
+ s[sizeof(s)-1] = '\0';
+#if (LCD_WIDTH>IMAGE_SIZE)
+ rb->lcd_putsxy(IMAGE_WIDTH+5, 20, (unsigned char *)s);
+#else
+ rb->lcd_putsxy(5, IMAGE_HEIGHT+20, (unsigned char *)s);
+#endif
- for (i=4; i<=16; i+=4) {
- draw_spot(20, (hole%5)*16, (hole/5)*16);
- draw_spot(spots[hole], (hole%5)*16 + x*i, (hole/5)*16 + y*i);
- rb->lcd_update();
+ for(i=1;i<=4;i++)
+ {
+ draw_spot(HOLE_ID,
+ (hole%SPOTS_X)*SPOTS_WIDTH,
+ (hole/SPOTS_X)*SPOTS_HEIGHT);
+ draw_spot(spots[hole],
+ (hole%SPOTS_X)*SPOTS_WIDTH + (i*x*SPOTS_WIDTH)/5,
+ (hole/SPOTS_X)*SPOTS_HEIGHT + (i*y*SPOTS_HEIGHT)/5);
+ rb->lcd_update();
+ rb->sleep(HZ/50);
}
- spots[hole] = 20;
+ draw_spot(HOLE_ID,
+ (hole%SPOTS_X)*SPOTS_WIDTH,
+ (hole/SPOTS_X)*SPOTS_HEIGHT);
+ draw_spot(spots[hole],
+ ((hole%SPOTS_X)+x)*SPOTS_WIDTH,
+ ((hole/SPOTS_X)+y)*SPOTS_HEIGHT);
+ rb->lcd_update();
+
+ spots[hole] = HOLE_ID;
}
-
+
/* initializes the puzzle */
static void puzzle_init(void)
{
- int i, r, temp, tsp[20];
+ int i, r, temp, tsp[NUM_SPOTS];
+
moves = 0;
rb->lcd_clear_display();
- rb->lcd_drawrect(80, 0, 32, 64);
- rb->lcd_putsxy(81, 10, (unsigned char *)"Moves");
rb->snprintf(s, sizeof(s), "%d", moves);
- rb->lcd_putsxy(85, 20, (unsigned char *)s);
-
+
+#if (LCD_WIDTH>IMAGE_SIZE)
+ rb->lcd_drawrect(IMAGE_WIDTH, 0, 32, 64);
+ rb->lcd_putsxy(IMAGE_WIDTH+1, 10, (unsigned char *)"Moves");
+ rb->lcd_putsxy(IMAGE_WIDTH+5, 20, (unsigned char *)s);
+#else
+ rb->lcd_drawrect(0, IMAGE_HEIGHT, 32, 64);
+ rb->lcd_putsxy(1, IMAGE_HEIGHT+10, (unsigned char *)"Moves");
+ rb->lcd_putsxy(5, IMAGE_HEIGHT+20, (unsigned char *)s);
+#endif
+
/* shuffle spots */
- for (i=19; i>=0; i--) {
+ for (i=NUM_SPOTS-1; i>=0; i--) {
r = (rb->rand() % (i+1));
-
+
temp = spots[r];
spots[r] = spots[i];
spots[i] = temp;
-
- if (spots[i]==20)
+
+ if (spots[i]==HOLE_ID)
hole = i;
}
-
+
/* test if the puzzle is solvable */
- for (i=0; i<20; i++)
+ for (i=0; i<NUM_SPOTS; i++)
tsp[i] = spots[i];
r=0;
/* First, check if the problem has even or odd parity,
depending on where the empty square is */
- if (((4-hole%5) + (3-hole/5))%2 == 1)
+ if ((((SPOTS_X-1)-hole%SPOTS_X) + ((SPOTS_Y-1)-hole/SPOTS_X))%2 == 1)
++r;
/* Now check how many swaps we need to solve it */
- for (i=0; i<19; i++) {
+ for (i=0; i<NUM_SPOTS-1; i++) {
while (tsp[i] != (i+1)) {
temp = tsp[i];
tsp[i] = tsp[temp-1];
@@ -286,10 +401,10 @@ static void puzzle_init(void)
++r;
}
}
-
+
/* if the random puzzle isn't solvable just change two spots */
if (r%2 == 1) {
- if (spots[0]!=20 && spots[1]!=20) {
+ if (spots[0]!=HOLE_ID && spots[1]!=HOLE_ID) {
temp = spots[0];
spots[0] = spots[1];
spots[1] = temp;
@@ -299,10 +414,11 @@ static void puzzle_init(void)
spots[3] = temp;
}
}
-
+
/* draw spots to the lcd */
- for (i=0; i<20; i++)
- draw_spot(spots[i], (i%5)*16, (i/5)*16);
+ for (i=0; i<NUM_SPOTS; i++)
+ draw_spot(spots[i], (i%SPOTS_X)*SPOTS_WIDTH, (i/SPOTS_X)*SPOTS_HEIGHT);
+
rb->lcd_update();
}
@@ -312,6 +428,8 @@ static int puzzle_loop(void)
int button;
int lastbutton = BUTTON_NONE;
int i;
+ bool load_success;
+
puzzle_init();
while(true) {
button = rb->button_get(true);
@@ -331,39 +449,63 @@ static int puzzle_loop(void)
/* mix up the pieces */
puzzle_init();
break;
-
+
case PUZZLE_PICTURE:
#ifdef PUZZLE_SHUFFLE_PICTURE_PRE
if (lastbutton != PUZZLE_SHUFFLE_PICTURE_PRE)
break;
#endif
/* change picture */
- pic = (pic==true?false:true);
- for (i=0; i<20; i++)
- draw_spot(spots[i], (i%5)*16, (i/5)*16);
+ picmode = (picmode+1)%PICMODE_LAST_XXX;
+
+ /* if load_resize_bitmap fails to load bitmap, try next picmode */
+ do
+ {
+ load_success = load_resize_bitmap();
+ if( !load_success )
+ picmode = (picmode+1)%PICMODE_LAST_XXX;
+ }
+ while( !load_success );
+
+ /* tell the user what mode we picked in the end! */
+ rb->splash(HZ,picmode_descriptions[ picmode ] );
+ rb->lcd_clear_display();
+#if (LCD_WIDTH>IMAGE_SIZE)
+ rb->lcd_drawrect(IMAGE_WIDTH, 0, 32, 64);
+ rb->lcd_putsxy(IMAGE_WIDTH+1, 10, (unsigned char *)"Moves");
+#else
+ rb->lcd_drawrect(0,IMAGE_HEIGHT,32,64);
+ rb->lcd_putsxy(1,IMAGE_HEIGHT+10, (unsigned char *)"Moves");
+#endif
+
+ for (i=0; i<NUM_SPOTS; i++)
+ draw_spot(spots[i],
+ (i%SPOTS_X)*SPOTS_WIDTH,
+ (i/SPOTS_X)*SPOTS_HEIGHT);
rb->lcd_update();
+
break;
-
+
case BUTTON_LEFT:
- if ((hole%5)<4 && !puzzle_finished())
+ if ((hole%SPOTS_X)<(SPOTS_X-1) && !puzzle_finished())
move_spot(-1, 0);
break;
-
+
case BUTTON_RIGHT:
- if ((hole%5)>0 && !puzzle_finished())
+ if ((hole%SPOTS_X)>0 && !puzzle_finished())
move_spot(1, 0);
break;
-
+
case PUZZLE_UP:
- if ((hole/5)<3 && !puzzle_finished())
+ if ((hole/SPOTS_X)<(SPOTS_Y-1) && !puzzle_finished())
move_spot(0, -1);
break;
-
+
case PUZZLE_DOWN:
- if ((hole/5)>0 && !puzzle_finished())
+ if ((hole/SPOTS_X)>0 && !puzzle_finished())
move_spot(0, 1);
break;
-
+
default:
if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
return PLUGIN_USB_CONNECTED;
@@ -373,56 +515,115 @@ static int puzzle_loop(void)
lastbutton = button;
}
}
-
+
enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
{
int i, w, h;
- (void)parameter;
rb = api;
-
- /* print title */
- rb->lcd_getstringsize((unsigned char *)"Sliding Puzzle", &w, &h);
- w = (w+1)/2;
- h = (h+1)/2;
- rb->lcd_clear_display();
- rb->lcd_putsxy(LCD_WIDTH/2-w, (LCD_HEIGHT/2)-h, (unsigned char *)"Sliding Puzzle");
- rb->lcd_update();
- rb->sleep(HZ);
- /* print instructions */
- rb->lcd_clear_display();
- rb->lcd_setfont(FONT_SYSFIXED);
-#if CONFIG_KEYPAD == RECORDER_PAD
- rb->lcd_putsxy(3, 18, "[OFF] to stop");
- rb->lcd_putsxy(3, 28, "[F1] shuffle");
- rb->lcd_putsxy(3, 38, "[F2] change pic");
+ initial_bmp_path=(const char *)parameter;
+ picmode = PICMODE_INITIAL_PICTURE;
+ img_buf_path[0] = '\0';
+
+ /* If launched as a viewer, just go straight to the game without
+ bothering with the splash or instructions page */
+ if(parameter==NULL)
+ {
+ /* if not launched as a viewer, use default puzzle, and show help */
+ picmode = PICMODE_DEFAULT_PICTURE;
+
+ /* print title */
+ rb->lcd_getstringsize((unsigned char *)"Sliding Puzzle", &w, &h);
+ w = (w+1)/2;
+ h = (h+1)/2;
+ rb->lcd_clear_display();
+ rb->lcd_putsxy(LCD_WIDTH/2-w, (LCD_HEIGHT/2)-h,
+ (unsigned char *)"Sliding Puzzle");
+ rb->lcd_update();
+ rb->sleep(HZ);
+
+ /* print instructions */
+ rb->lcd_clear_display();
+ rb->lcd_setfont(FONT_SYSFIXED);
+#if CONFIG_KEYPAD == RECORDER_PAD || CONFIG_KEYPAD == ARCHOS_AV300_PAD
+ rb->lcd_putsxy(3, 18, "[OFF] to stop");
+ rb->lcd_putsxy(3, 28, "[F1] shuffle");
+ rb->lcd_putsxy(3, 38, "[F2] change pic");
#elif CONFIG_KEYPAD == ONDIO_PAD
- rb->lcd_putsxy(0, 18, "[OFF] to stop");
- rb->lcd_putsxy(0, 28, "[MODE..] shuffle");
- rb->lcd_putsxy(0, 38, "[MODE] change pic");
+ rb->lcd_putsxy(0, 18, "[OFF] to stop");
+ rb->lcd_putsxy(0, 28, "[MODE..] shuffle");
+ rb->lcd_putsxy(0, 38, "[MODE] change pic");
#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
(CONFIG_KEYPAD == IPOD_3G_PAD) || \
(CONFIG_KEYPAD == IPOD_1G2G_PAD)
- rb->lcd_putsxy(0, 18, "[S-MENU] to stop");
- rb->lcd_putsxy(0, 28, "[S-LEFT] shuffle");
- rb->lcd_putsxy(0, 38, "[S-RIGHT] change pic");
+ rb->lcd_putsxy(0, 18, "[S-MENU] to stop");
+ rb->lcd_putsxy(0, 28, "[S-LEFT] shuffle");
+ rb->lcd_putsxy(0, 38, "[S-RIGHT] change pic");
+#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
+ (CONFIG_KEYPAD == IRIVER_H300_PAD)
+ rb->lcd_putsxy(0, 18, "[STOP] to stop");
+ rb->lcd_putsxy(0, 28, "[SELECT] shuffle");
+ rb->lcd_putsxy(0, 38, "[PLAY] change pic");
+#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
+ rb->lcd_putsxy(0, 18, "[OFF] to stop");
+ rb->lcd_putsxy(0, 28, "[REC] shuffle");
+ rb->lcd_putsxy(0, 38, "[PLAY] change pic");
+#elif CONFIG_KEYPAD == GIGABEAT_PAD
+ rb->lcd_putsxy(0, 18, "[OFF] to stop");
+ rb->lcd_putsxy(0, 28, "[SELECT] shuffle");
+ rb->lcd_putsxy(0, 38, "[A] change pic");
+#elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
+ (CONFIG_KEYPAD == SANSE_C200_PAD)
+ rb->lcd_putsxy(0, 18, "[OFF] to stop");
+ rb->lcd_putsxy(0, 28, "[REC] shuffle");
+ rb->lcd_putsxy(0, 38, "[SELECT] change pic");
+#elif CONFIG_KEYPAD == IRIVER_H10_PAD
+ rb->lcd_putsxy(0, 18, "[OFF] to stop");
+ rb->lcd_putsxy(0, 28, "[REW] shuffle");
+ rb->lcd_putsxy(0, 38, "[PLAY] change pic");
#endif
- rb->lcd_update();
- rb->button_get_w_tmo(HZ*2);
-
+#ifdef HAVE_ALBUMART
+ rb->lcd_putsxy(0,48," pic->albumart->num");
+#else
+ rb->lcd_putsxy(0,48," pic<->num");
+#endif
+ rb->lcd_update();
+ rb->button_get_w_tmo(HZ*2);
+ }
+
+ hole = INITIAL_HOLE;
+
+ if( !load_resize_bitmap() )
+ {
+ rb->lcd_clear_display();
+ rb->splash(HZ*2,"Failed to load bitmap!");
+ return PLUGIN_OK;
+ }
+
+#if LCD_DEPTH>1
+ rb->lcd_set_background(LCD_BLACK);
+ rb->lcd_set_foreground(LCD_WHITE);
+ rb->lcd_set_backdrop(NULL);
+#endif
+
rb->lcd_clear_display();
- rb->lcd_drawrect(80, 0, 32, 64);
- rb->lcd_putsxy(81, 10, (unsigned char *)"Moves");
- for (i=0; i<20; i++) {
+#if (LCD_WIDTH>IMAGE_SIZE)
+ rb->lcd_drawrect(IMAGE_WIDTH, 0, 32, 64);
+ rb->lcd_putsxy(IMAGE_WIDTH+1, 10, (unsigned char *)"Moves");
+#else
+ rb->lcd_drawrect(0,IMAGE_HEIGHT,32,64);
+ rb->lcd_putsxy(1,IMAGE_HEIGHT+10, (unsigned char *)"Moves");
+#endif
+
+ for (i=0; i<NUM_SPOTS; i++) {
spots[i]=(i+1);
- draw_spot(spots[i], (i%5)*16, (i/5)*16);
+ draw_spot(spots[i], (i%SPOTS_X)*SPOTS_WIDTH, (i/SPOTS_X)*SPOTS_HEIGHT);
}
- hole = 19;
- pic = true;
+
rb->lcd_update();
rb->sleep(HZ*2);
-
+
return puzzle_loop();
}
diff --git a/apps/plugins/viewers.config b/apps/plugins/viewers.config
index 375128e..bfb408c 100644
--- a/apps/plugins/viewers.config
+++ b/apps/plugins/viewers.config
@@ -26,6 +26,7 @@ wav,viewers/wavplay,9
wav,viewers/wavview,10
wav,viewers/test_codec,-
bmp,apps/rockpaint,11
+bmp,games/sliding_puzzle,11
mpg,viewers/mpegplayer,4
mpeg,viewers/mpegplayer,4
mpv,viewers/mpegplayer,4