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
|
@ -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 */
|
||||
|
|
BIN
apps/plugins/bitmaps/native/sliding_puzzle.110x110x2.bmp
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
apps/plugins/bitmaps/native/sliding_puzzle.128x128x16.bmp
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
apps/plugins/bitmaps/native/sliding_puzzle.128x128x2.bmp
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
apps/plugins/bitmaps/native/sliding_puzzle.176x176x16.bmp
Normal file
After Width: | Height: | Size: 91 KiB |
BIN
apps/plugins/bitmaps/native/sliding_puzzle.240x240x16.bmp
Normal file
After Width: | Height: | Size: 169 KiB |
BIN
apps/plugins/bitmaps/native/sliding_puzzle.80x64x1.bmp
Normal file
After Width: | Height: | Size: 830 B |
BIN
apps/plugins/bitmaps/native/sliding_puzzle.80x80x16.bmp
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
apps/plugins/bitmaps/native/sliding_puzzle.bmp
Normal file
After Width: | Height: | Size: 469 KiB |
|
@ -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
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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);
|
||||
} else {
|
||||
rb->lcd_drawrect(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_fillrect(x+1, y+1, 14, 14);
|
||||
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, SPOTS_WIDTH, SPOTS_HEIGHT);
|
||||
rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
|
||||
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);
|
||||
|
||||
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++) {
|
||||
spots[i]=(i+1);
|
||||
draw_spot(spots[i], (i%5)*16, (i/5)*16);
|
||||
#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 = 19;
|
||||
pic = true;
|
||||
|
||||
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();
|
||||
#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%SPOTS_X)*SPOTS_WIDTH, (i/SPOTS_X)*SPOTS_HEIGHT);
|
||||
}
|
||||
|
||||
rb->lcd_update();
|
||||
rb->sleep(HZ*2);
|
||||
|
||||
|
||||
return puzzle_loop();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|