From bbb9da3f8ce19421e7fe9f12e7401f7d84989cc0 Mon Sep 17 00:00:00 2001 From: Antoine Cellerier Date: Sat, 16 Jun 2007 23:12:41 +0000 Subject: Add "Puzzle" game type to jewels. Idea from Sam Hocevar's MonsterZ (http://sam.zoy.org/monsterz). git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13644 a1c6a512-1295-4272-9138-f99709370657 --- apps/plugins/bitmaps/native/jewels.112x64x1.bmp | Bin 318 -> 798 bytes apps/plugins/bitmaps/native/jewels.128x128x16.bmp | Bin 4982 -> 14222 bytes apps/plugins/bitmaps/native/jewels.138x110x2.bmp | Bin 2742 -> 5862 bytes apps/plugins/bitmaps/native/jewels.160x128x16.bmp | Bin 6200 -> 17718 bytes apps/plugins/bitmaps/native/jewels.160x128x2.bmp | Bin 3126 -> 6966 bytes apps/plugins/bitmaps/native/jewels.220x176x16.bmp | Bin 12024 -> 34462 bytes apps/plugins/bitmaps/native/jewels.320x240x16.bmp | Bin 22136 -> 63534 bytes apps/plugins/jewels.c | 226 +++++++++++++++++++--- 8 files changed, 198 insertions(+), 28 deletions(-) (limited to 'apps') diff --git a/apps/plugins/bitmaps/native/jewels.112x64x1.bmp b/apps/plugins/bitmaps/native/jewels.112x64x1.bmp index 447df6d1da..f245f330e5 100644 Binary files a/apps/plugins/bitmaps/native/jewels.112x64x1.bmp and b/apps/plugins/bitmaps/native/jewels.112x64x1.bmp differ diff --git a/apps/plugins/bitmaps/native/jewels.128x128x16.bmp b/apps/plugins/bitmaps/native/jewels.128x128x16.bmp index c22c8d917e..0061df3c3d 100644 Binary files a/apps/plugins/bitmaps/native/jewels.128x128x16.bmp and b/apps/plugins/bitmaps/native/jewels.128x128x16.bmp differ diff --git a/apps/plugins/bitmaps/native/jewels.138x110x2.bmp b/apps/plugins/bitmaps/native/jewels.138x110x2.bmp index b2096e19b0..75bd9566bd 100644 Binary files a/apps/plugins/bitmaps/native/jewels.138x110x2.bmp and b/apps/plugins/bitmaps/native/jewels.138x110x2.bmp differ diff --git a/apps/plugins/bitmaps/native/jewels.160x128x16.bmp b/apps/plugins/bitmaps/native/jewels.160x128x16.bmp index 5d9606d012..6874564585 100644 Binary files a/apps/plugins/bitmaps/native/jewels.160x128x16.bmp and b/apps/plugins/bitmaps/native/jewels.160x128x16.bmp differ diff --git a/apps/plugins/bitmaps/native/jewels.160x128x2.bmp b/apps/plugins/bitmaps/native/jewels.160x128x2.bmp index 603925f145..f6b5e9ea61 100644 Binary files a/apps/plugins/bitmaps/native/jewels.160x128x2.bmp and b/apps/plugins/bitmaps/native/jewels.160x128x2.bmp differ diff --git a/apps/plugins/bitmaps/native/jewels.220x176x16.bmp b/apps/plugins/bitmaps/native/jewels.220x176x16.bmp index 36d4f51249..64f54b0391 100644 Binary files a/apps/plugins/bitmaps/native/jewels.220x176x16.bmp and b/apps/plugins/bitmaps/native/jewels.220x176x16.bmp differ diff --git a/apps/plugins/bitmaps/native/jewels.320x240x16.bmp b/apps/plugins/bitmaps/native/jewels.320x240x16.bmp index 201c178183..67b2d16541 100644 Binary files a/apps/plugins/bitmaps/native/jewels.320x240x16.bmp and b/apps/plugins/bitmaps/native/jewels.320x240x16.bmp differ diff --git a/apps/plugins/jewels.c b/apps/plugins/jewels.c index c6efcbccef..20fb60c808 100644 --- a/apps/plugins/jewels.c +++ b/apps/plugins/jewels.c @@ -203,15 +203,22 @@ PLUGIN_HEADER /* animation frame rate */ #define MAX_FPS 20 +/* Game types */ +enum game_type { + GAME_TYPE_NORMAL, + GAME_TYPE_PUZZLE +}; + /* menu values */ #define FONT_HEIGHT 8 -#define MAX_MITEMS 5 +#define MAX_MITEMS 6 #define MENU_WIDTH 100 /* menu results */ enum menu_result { MRES_NONE, MRES_NEW, + MRES_PUZZLE, MRES_SAVE, MRES_RESUME, MRES_SCORES, @@ -240,8 +247,9 @@ struct jewels_menu { enum menu_result res; } items[MAX_MITEMS]; } bjmenu[] = { - {"Jewels", false, 0, 5, + {"Jewels", false, 0, 6, {{"New Game", MRES_NEW}, + {"Puzzle", MRES_PUZZLE}, {"Resume Game", MRES_RESUME}, {"High Scores", MRES_SCORES}, {"Help", MRES_HELP}, @@ -283,19 +291,76 @@ struct tile { * score is the current level score * segments is the number of cleared segments in the current run * level is the current level + * type is the game type (normal or puzzle) * highscores is the list of high scores * resume denotes whether to resume the currently loaded game * dirty denotes whether the high scores are out of sync with the saved file * playboard is the game playing board (first row is hidden) + * num_jewels is the number of different jewels to use */ struct game_context { unsigned int score; unsigned int segments; unsigned int level; + unsigned int type; unsigned int highscores[NUM_SCORES]; bool resume; bool dirty; struct tile playboard[BJ_HEIGHT][BJ_WIDTH]; + unsigned int num_jewels; +}; + +#define MAX_NUM_JEWELS 7 + +#define MAX_PUZZLE_TILES 4 +#define NUM_PUZZLE_LEVELS 10 + +struct puzzle_tile { + int x; + int y; + int tile_type; +}; + +struct puzzle_level { + unsigned int num_jewels; + unsigned int num_tiles; + struct puzzle_tile tiles[MAX_PUZZLE_TILES]; +}; + +#define PUZZLE_TILE_UP 1 +#define PUZZLE_TILE_DOWN 2 +#define PUZZLE_TILE_LEFT 4 +#define PUZZLE_TILE_RIGHT 8 + +struct puzzle_level puzzle_levels[NUM_PUZZLE_LEVELS] = { + { 5, 2, { {3, 3, PUZZLE_TILE_RIGHT}, + {4, 2, PUZZLE_TILE_LEFT} } }, + { 5, 2, { {3, 2, PUZZLE_TILE_DOWN}, + {3, 4, PUZZLE_TILE_UP} } }, + { 6, 3, { {3, 2, PUZZLE_TILE_DOWN}, + {3, 4, PUZZLE_TILE_UP|PUZZLE_TILE_DOWN}, + {3, 6, PUZZLE_TILE_UP} } }, + { 6, 3, { {3, 2, PUZZLE_TILE_RIGHT}, + {4, 3, PUZZLE_TILE_LEFT|PUZZLE_TILE_RIGHT}, + {5, 4, PUZZLE_TILE_LEFT} } }, + { 6, 2, { {3, 4, PUZZLE_TILE_RIGHT}, + {4, 2, PUZZLE_TILE_LEFT} } }, + { 6, 2, { {3, 2, PUZZLE_TILE_DOWN}, + {4, 4, PUZZLE_TILE_UP} } }, + { 7, 4, { {3, 2, PUZZLE_TILE_LEFT|PUZZLE_TILE_DOWN}, + {4, 3, PUZZLE_TILE_LEFT|PUZZLE_TILE_UP}, + {3, 4, PUZZLE_TILE_RIGHT|PUZZLE_TILE_DOWN}, + {4, 4, PUZZLE_TILE_RIGHT|PUZZLE_TILE_UP} } }, + { 6, 3, { {3, 2, PUZZLE_TILE_DOWN}, + {4, 4, PUZZLE_TILE_UP|PUZZLE_TILE_DOWN}, + {3, 6, PUZZLE_TILE_UP} } }, + { 7, 3, { {2, 2, PUZZLE_TILE_RIGHT}, + {4, 1, PUZZLE_TILE_LEFT|PUZZLE_TILE_RIGHT}, + {5, 4, PUZZLE_TILE_LEFT} } }, + { 7, 4, { {3, 0, PUZZLE_TILE_LEFT|PUZZLE_TILE_DOWN}, + {5, 0, PUZZLE_TILE_LEFT|PUZZLE_TILE_UP}, + {2, 7, PUZZLE_TILE_RIGHT|PUZZLE_TILE_DOWN}, + {4, 7, PUZZLE_TILE_RIGHT|PUZZLE_TILE_UP} } }, }; /***************************************************************************** @@ -574,7 +639,7 @@ static void jewels_putjewels(struct game_context* bj){ done = true; for(j=0; jplayboard[1][j].type == 0) { - bj->playboard[0][j].type = rb->rand()%7+1; + bj->playboard[0][j].type = rb->rand()%bj->num_jewels+1; } for(i=BJ_HEIGHT-2; i>=0; i--) { if(!mark && bj->playboard[i+1][j].type == 0) { @@ -584,7 +649,7 @@ static void jewels_putjewels(struct game_context* bj){ if(mark) bj->playboard[i][j].falling = true; } /*if(bj->playboard[1][j].falling) { - bj->playboard[0][j].type = rb->rand()%7+1; + bj->playboard[0][j].type = rb->rand()%bj->num_jewels+1; bj->playboard[0][j].falling = true; }*/ mark = false; @@ -697,7 +762,8 @@ static unsigned int jewels_clearjewels(struct game_context* bj) { run = 1; for(j=0; jplayboard[i][j].type == last && - bj->playboard[i][j].type != 0) { + bj->playboard[i][j].type != 0 && + bj->playboard[i][j].type <= MAX_NUM_JEWELS) { run++; if(run == 3) { @@ -723,7 +789,8 @@ static unsigned int jewels_clearjewels(struct game_context* bj) { run = 1; for(i=1; iplayboard[i][j].type != 0 && - bj->playboard[i][j].type == last) { + bj->playboard[i][j].type == last && + bj->playboard[i][j].type <= MAX_NUM_JEWELS) { run++; if(run == 3) { @@ -930,6 +997,7 @@ static bool jewels_movesavail(struct game_context* bj) { for(i=1; iplayboard[i][j].type; + if(mytype == 0 || mytype > MAX_NUM_JEWELS) continue; /* check horizontal patterns */ if(j <= BJ_WIDTH-3) { @@ -1015,31 +1083,82 @@ static bool jewels_movesavail(struct game_context* bj) { } /***************************************************************************** -* jewels_nextlevel() advances the game to the next level and returns -* points earned. +* jewels_puzzle_is_finished(bj) checks if the puzzle is finished. ******************************************************************************/ -static unsigned int jewels_nextlevel(struct game_context* bj) { - int i, x, y; +static int jewels_puzzle_is_finished(struct game_context* bj) { + unsigned int i, j; + for(i=0; iplayboard[i][j].type; + if(mytype>MAX_NUM_JEWELS) { + mytype -= MAX_NUM_JEWELS; + if(mytype&PUZZLE_TILE_UP) { + if(i==0 || bj->playboard[i-1][j].type<=MAX_NUM_JEWELS || + !((bj->playboard[i-1][j].type-MAX_NUM_JEWELS) + &PUZZLE_TILE_DOWN)) + return 0; + } + if(mytype&PUZZLE_TILE_DOWN) { + if(i==BJ_HEIGHT-1 || + bj->playboard[i+1][j].type<=MAX_NUM_JEWELS || + !((bj->playboard[i+1][j].type-MAX_NUM_JEWELS) + &PUZZLE_TILE_UP)) + return 0; + } + if(mytype&PUZZLE_TILE_LEFT) { + if(j==0 || bj->playboard[i][j-1].type<=MAX_NUM_JEWELS || + !((bj->playboard[i][j-1].type-MAX_NUM_JEWELS) + &PUZZLE_TILE_RIGHT)) + return 0; + } + if(mytype&PUZZLE_TILE_RIGHT) { + if(j==BJ_WIDTH-1 || + bj->playboard[i][j+1].type<=MAX_NUM_JEWELS || + !((bj->playboard[i][j+1].type-MAX_NUM_JEWELS) + &PUZZLE_TILE_LEFT)) + return 0; + } + } + } + } + return 1; +} + +/***************************************************************************** +* jewels_initlevel() initialises a level. +******************************************************************************/ +static unsigned int jewels_initlevel(struct game_context* bj) { unsigned int points = 0; - /* roll over score, change and display level */ - while(bj->score >= LEVEL_PTS) { - bj->score -= LEVEL_PTS; - bj->level++; - rb->splash(HZ*2, "Level %d", bj->level); - jewels_drawboard(bj); - } + switch(bj->type) { + case GAME_TYPE_NORMAL: + bj->num_jewels = MAX_NUM_JEWELS; + break; - /* randomly clear some jewels */ - for(i=0; i<16; i++) { - x = rb->rand()%8; - y = rb->rand()%8; + case GAME_TYPE_PUZZLE: + { + unsigned int i, j; + struct puzzle_tile *tile; - if(bj->playboard[y][x].type != 0) { - points++; - bj->playboard[y][x].type = 0; + bj->num_jewels = puzzle_levels[bj->level-1].num_jewels; + + for(i=0; iplayboard[i][j].type = (rand()%bj->num_jewels)+1; + bj->playboard[i][j].falling = false; + bj->playboard[i][j].delete = false; + } + } + jewels_runboard(bj); + tile = puzzle_levels[bj->level-1].tiles; + for(i=0; ilevel-1].num_tiles; i++, tile++) { + bj->playboard[tile->y][tile->x].type = MAX_NUM_JEWELS + +tile->tile_type; + } } + break; } + jewels_drawboard(bj); /* run the play board */ @@ -1048,6 +1167,44 @@ static unsigned int jewels_nextlevel(struct game_context* bj) { return points; } +/***************************************************************************** +* jewels_nextlevel() advances the game to the next level and returns +* points earned. +******************************************************************************/ +static unsigned int jewels_nextlevel(struct game_context* bj) { + int i, x, y; + unsigned int points = 0; + + switch(bj->type) { + case GAME_TYPE_NORMAL: + /* roll over score, change and display level */ + while(bj->score >= LEVEL_PTS) { + bj->score -= LEVEL_PTS; + bj->level++; + rb->splash(HZ*2, "Level %d", bj->level); + jewels_drawboard(bj); + } + + /* randomly clear some jewels */ + for(i=0; i<16; i++) { + x = rb->rand()%8; + y = rb->rand()%8; + + if(bj->playboard[y][x].type != 0) { + points++; + bj->playboard[y][x].type = 0; + } + } + break; + + case GAME_TYPE_PUZZLE: + bj->level++; + break; + } + + return jewels_initlevel(bj); +} + /***************************************************************************** * jewels_recordscore() inserts a high score into the high scores list and * returns the high score position. @@ -1207,6 +1364,12 @@ static int jewels_main(struct game_context* bj) { switch(res) { case MRES_NEW: startgame = true; + bj->type = GAME_TYPE_NORMAL; + continue; + + case MRES_PUZZLE: + startgame = true; + bj->type = GAME_TYPE_PUZZLE; continue; case MRES_RESUME: @@ -1396,9 +1559,7 @@ static int jewels_main(struct game_context* bj) { /******************** * setup the board * ********************/ - jewels_drawboard(bj); - jewels_putjewels(bj); - bj->score += jewels_runboard(bj); + bj->score += jewels_initlevel(bj); if (!jewels_movesavail(bj)) return BJ_LOSE; /********************** @@ -1572,7 +1733,16 @@ static int jewels_main(struct game_context* bj) { break; } - if(bj->score >= LEVEL_PTS) bj->score = jewels_nextlevel(bj); + switch(bj->type) { + case GAME_TYPE_NORMAL: + if(bj->score >= LEVEL_PTS) bj->score = jewels_nextlevel(bj); + break; + + case GAME_TYPE_PUZZLE: + if(jewels_puzzle_is_finished(bj)) + bj->score += jewels_nextlevel(bj); + break; + } } } -- cgit v1.2.3