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
This commit is contained in:
Nicolas Pennequin 2008-01-26 00:16:06 +00:00
parent 5991478628
commit 02f1839bfe
14 changed files with 417 additions and 190 deletions

View file

@ -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 */

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 830 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 469 KiB

View file

@ -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

View file

@ -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).

View file

@ -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).

View file

@ -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();
}

View file

@ -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