From 02f1839bfe4766ac72631bd7b76f2fc7f291b89e Mon Sep 17 00:00:00 2001 From: Nicolas Pennequin Date: Sat, 26 Jan 2008 00:16:06 +0000 Subject: 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 --- apps/plugins/bitmaps/native/SOURCES | 21 + .../bitmaps/native/sliding_puzzle.110x110x2.bmp | Bin 0 -> 13398 bytes .../bitmaps/native/sliding_puzzle.128x128x16.bmp | Bin 0 -> 49206 bytes .../bitmaps/native/sliding_puzzle.128x128x2.bmp | Bin 0 -> 17462 bytes .../bitmaps/native/sliding_puzzle.176x176x16.bmp | Bin 0 -> 92982 bytes .../bitmaps/native/sliding_puzzle.240x240x16.bmp | Bin 0 -> 172854 bytes .../bitmaps/native/sliding_puzzle.80x64x1.bmp | Bin 0 -> 830 bytes .../bitmaps/native/sliding_puzzle.80x80x16.bmp | Bin 0 -> 19254 bytes apps/plugins/bitmaps/native/sliding_puzzle.bmp | Bin 0 -> 480054 bytes apps/plugins/lib/SOURCES | 2 +- apps/plugins/lib/bmp.c | 2 + apps/plugins/lib/bmp.h | 2 + apps/plugins/sliding_puzzle.c | 573 ++++++++++++++------- apps/plugins/viewers.config | 1 + 14 files changed, 414 insertions(+), 187 deletions(-) create mode 100644 apps/plugins/bitmaps/native/sliding_puzzle.110x110x2.bmp create mode 100644 apps/plugins/bitmaps/native/sliding_puzzle.128x128x16.bmp create mode 100644 apps/plugins/bitmaps/native/sliding_puzzle.128x128x2.bmp create mode 100644 apps/plugins/bitmaps/native/sliding_puzzle.176x176x16.bmp create mode 100644 apps/plugins/bitmaps/native/sliding_puzzle.240x240x16.bmp create mode 100644 apps/plugins/bitmaps/native/sliding_puzzle.80x64x1.bmp create mode 100644 apps/plugins/bitmaps/native/sliding_puzzle.80x80x16.bmp create mode 100644 apps/plugins/bitmaps/native/sliding_puzzle.bmp 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 #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 0000000000..e21531ec70 Binary files /dev/null and b/apps/plugins/bitmaps/native/sliding_puzzle.110x110x2.bmp 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 Binary files /dev/null and b/apps/plugins/bitmaps/native/sliding_puzzle.128x128x16.bmp 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 Binary files /dev/null and b/apps/plugins/bitmaps/native/sliding_puzzle.128x128x2.bmp 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 Binary files /dev/null and b/apps/plugins/bitmaps/native/sliding_puzzle.176x176x16.bmp 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 Binary files /dev/null and b/apps/plugins/bitmaps/native/sliding_puzzle.240x240x16.bmp 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 Binary files /dev/null and b/apps/plugins/bitmaps/native/sliding_puzzle.80x64x1.bmp 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 Binary files /dev/null and b/apps/plugins/bitmaps/native/sliding_puzzle.80x80x16.bmp 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 Binary files /dev/null and b/apps/plugins/bitmaps/native/sliding_puzzle.bmp 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 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 03bdc73783..20adc6de86 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 e35c1ecb0a..3e14243d30 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 17a96baf2a..223c107265 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_WIDTH1 +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; isnprintf(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; ilcd_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; ilcd_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; ilcd_update(); rb->sleep(HZ*2); - + return puzzle_loop(); } 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 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 -- cgit v1.2.3