Index: apps/plugins/snake.c =================================================================== --- apps/plugins/snake.c (Revision 21733) +++ apps/plugins/snake.c (Arbeitskopie) @@ -33,7 +33,8 @@ */ #include "plugin.h" -#ifdef HAVE_LCD_BITMAP +#include "lib/playback_control.h" +#include "lib/configfile.h" PLUGIN_HEADER @@ -208,10 +209,16 @@ static int board[BOARD_WIDTH][BOARD_HEIGHT],snakelength; static unsigned int score,hiscore=0,level=1; -static int dir,dead=0; -static bool apple; +static int dir; +static bool apple, dead; -void die (void) +#define CONFIG_FILE_NAME "snake.cfg" +static struct configdata config[] = { + {TYPE_INT, 0, 10, { .int_p = &level }, "level", NULL}, + {TYPE_INT, 0, 10000, { .int_p = &hiscore }, "hiscore", NULL}, +}; + +static void snake_die (void) { char pscore[17]; rb->lcd_clear_display(); @@ -228,10 +235,10 @@ } rb->lcd_update(); rb->sleep(3*HZ); - dead=1; + dead=true; } -void colission (short x, short y) +static void snake_colission (short x, short y) { switch (board[x][y]) { case 0: @@ -242,14 +249,14 @@ apple=false; break; default: - die(); + snake_die(); break; } if (x==BOARD_WIDTH || x<0 || y==BOARD_HEIGHT || y<0) - die(); + snake_die(); } -void move_head (short x, short y) +static void snake_move_head (short x, short y) { switch (dir) { case 0: @@ -265,22 +272,44 @@ x-=1; break; } - colission (x,y); + snake_colission (x,y); if (dead) return; board[x][y]=1; rb->lcd_fillrect(x*4,y*4,4,4); } -void frame (void) +static void snake_redraw (void) { + short x,y; + rb->lcd_clear_display(); + for (x=0; xlcd_fillrect((x*4)+1,y*4,2,4); + rb->lcd_fillrect(x*4,(y*4)+1,4,2); + break; + case 0: + break; + default: + rb->lcd_fillrect(x*4,y*4,4,4); + break; + } + } + } + rb->lcd_update(); +} + +static void snake_frame (void) +{ short x,y,head=0; for (x=0; xlcd_update(); } -void redraw (void) -{ +static void snake_game_init(void) { short x,y; - rb->lcd_clear_display(); + rb->lcd_clear_display(); + for (x=0; xlcd_fillrect((x*4)+1,y*4,2,4); - rb->lcd_fillrect(x*4,(y*4)+1,4,2); - break; - case 0: - break; - default: - rb->lcd_fillrect(x*4,y*4,4,4); - break; - } + board[x][y]=0; } } - rb->lcd_update(); + apple=false; + dead=false; + snakelength=4; + score=0; + board[11][7]=1; } -void game_pause (void) { - int button; - rb->lcd_clear_display(); - rb->lcd_putsxy(3,12,"Game Paused"); -#if CONFIG_KEYPAD == RECORDER_PAD - rb->lcd_putsxy(3,22,"[Play] to resume"); -#elif CONFIG_KEYPAD == ONDIO_PAD - rb->lcd_putsxy(3,22,"[Mode] to resume"); -#endif - rb->lcd_putsxy(3,32,"[Off] to quit"); - rb->lcd_update(); - while (1) { - button=rb->button_get(true); - switch (button) { -#ifdef SNAKE_RC_QUIT - case SNAKE_RC_QUIT: -#endif - case SNAKE_QUIT: - dead=1; - return; - case SNAKE_PLAYPAUSE: - redraw(); - rb->sleep(HZ/2); - return; +static void snake_choose_level(void) +{ + int choice=level-1; + MENUITEM_STRINGLIST (main_menu,"Snake Speed",NULL, "1","2","3","4","5","6","7","8","9"); + level = rb->do_menu(&main_menu, &choice, NULL, false)+1; +} + +static bool _ingame; +static int snake_menu_cb(int action, const struct menu_item_ex *this_item) +{ + if(action == ACTION_REQUEST_MENUITEM + && !_ingame && ((intptr_t)this_item)==0) + return ACTION_EXIT_MENUITEM; + return action; +} + +static int snake_game_menu(bool ingame) +{ + rb->button_clear_queue(); + int choice = 0; + + _ingame = ingame; + + MENUITEM_STRINGLIST(main_menu,"Snake Menu",snake_menu_cb, + "Resume Game", + "Start New Game", + "Snake Speed", + "High Score", + "Playback Control", + "Quit"); + + while (true) { + choice = rb->do_menu(&main_menu, &choice, NULL, false); + switch (choice) { + case 0: + snake_redraw(); + return 0; + case 1: + snake_game_init(); + return 0; + case 2: + snake_choose_level(); + break; + case 3: + rb->splashf(HZ*2, "High Score: %d", hiscore); + break; + case 4: + playback_control(NULL); + break; + case 5: + return 1; + case MENU_ATTACHED_USB: + return 1; default: - if (rb->default_event_handler(button)==SYS_USB_CONNECTED) { - dead=2; - return; - } break; } } } - -void game (void) { +static int snake_game_loop (void) { int button; short x,y; - while (1) { - frame(); - if (dead) - return; + bool pause = false; + + if (snake_game_menu(false)!=0) { + return 1; + } + while (true) { + if (!pause) { + snake_frame(); + if (dead==true) { + if (snake_game_menu(false)!=0) { + return 1; + } + } if (!apple) { do { x=rb->rand() % BOARD_WIDTH; @@ -383,14 +439,16 @@ } rb->sleep(HZ/level); + } button=rb->button_get(false); #ifdef HAS_BUTTON_HOLD - if (rb->button_hold()) - button = SNAKE_PLAYPAUSE; + if (rb->button_hold()) { + pause = true; + rb->splash (HZ, "Paused"); + } #endif - switch (button) { case SNAKE_UP: if (dir!=2) dir=0; @@ -404,73 +462,41 @@ case SNAKE_LEFT: if (dir!=1) dir=3; break; + case SNAKE_PLAYPAUSE: + pause = !pause; + if (pause) + rb->splash (HZ, "Paused"); + else { + snake_redraw(); + } + break; #ifdef SNAKE_RC_QUIT case SNAKE_RC_QUIT: #endif case SNAKE_QUIT: - dead=1; - return; - case SNAKE_PLAYPAUSE: - game_pause(); - break; - default: - if (rb->default_event_handler(button)==SYS_USB_CONNECTED) { - dead=2; - return; - } - break; - } - } -} - -void game_init(void) { - int selection=0; - short x,y; - bool menu_quit = false; - - for (x=0; xdo_menu(&menu, &selection, NULL, false)) - { - case 0: - menu_quit = true; /* start playing */ + if (!pause) { + if (snake_game_menu(true)) { + dead = true; + } + } break; - - case 1: - rb->set_int("Starting Level", "", UNIT_INT, &level, NULL, - 1, 1, 9, NULL ); - break; - default: - dead=1; /* quit program */ - menu_quit = true; + if (rb->default_event_handler (button) == SYS_USB_CONNECTED) + return PLUGIN_USB_CONNECTED; break; - } } } enum plugin_status plugin_start(const void* parameter) { - (void)(parameter); - - game_init(); + (void)parameter; + +#ifdef HAVE_LCD_BITMAP + configfile_load(CONFIG_FILE_NAME,config,2,0); rb->lcd_clear_display(); - game(); - return (dead==1)?PLUGIN_OK:PLUGIN_USB_CONNECTED; + snake_game_loop(); + configfile_save(CONFIG_FILE_NAME,config,2,0); +#endif + return PLUGIN_OK; } - -#endif Index: apps/plugins/spacerocks.c =================================================================== --- apps/plugins/spacerocks.c (Revision 21733) +++ apps/plugins/spacerocks.c (Arbeitskopie) @@ -20,223 +20,161 @@ ****************************************************************************/ #include "plugin.h" +#include "lib/display_text.h" #include "lib/helper.h" +#include "lib/highscore.h" +#include "lib/playback_control.h" PLUGIN_HEADER -/******************************* Globals ***********************************/ /* variable button definitions */ #if CONFIG_KEYPAD == RECORDER_PAD #define AST_PAUSE BUTTON_ON #define AST_QUIT BUTTON_OFF -#define AST_THRUST_REP BUTTON_UP | BUTTON_REPEAT #define AST_THRUST BUTTON_UP #define AST_HYPERSPACE BUTTON_DOWN #define AST_LEFT BUTTON_LEFT -#define AST_LEFT_REP BUTTON_LEFT | BUTTON_REPEAT #define AST_RIGHT BUTTON_RIGHT -#define AST_RIGHT_REP (BUTTON_RIGHT | BUTTON_REPEAT) #define AST_FIRE BUTTON_PLAY -#define AST_FIRE_REP BUTTON_PLAY | BUTTON_REPEAT #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD #define AST_PAUSE BUTTON_ON #define AST_QUIT BUTTON_OFF -#define AST_THRUST_REP BUTTON_UP | BUTTON_REPEAT #define AST_THRUST BUTTON_UP #define AST_HYPERSPACE BUTTON_DOWN #define AST_LEFT BUTTON_LEFT -#define AST_LEFT_REP BUTTON_LEFT | BUTTON_REPEAT #define AST_RIGHT BUTTON_RIGHT -#define AST_RIGHT_REP (BUTTON_RIGHT | BUTTON_REPEAT) #define AST_FIRE BUTTON_SELECT -#define AST_FIRE_REP BUTTON_SELECT | BUTTON_REPEAT #elif CONFIG_KEYPAD == ONDIO_PAD #define AST_PAUSE (BUTTON_MENU | BUTTON_OFF) #define AST_QUIT BUTTON_OFF #define AST_THRUST BUTTON_UP -#define AST_THRUST_REP BUTTON_UP | BUTTON_REPEAT #define AST_HYPERSPACE BUTTON_DOWN #define AST_LEFT BUTTON_LEFT -#define AST_LEFT_REP BUTTON_LEFT | BUTTON_REPEAT #define AST_RIGHT BUTTON_RIGHT -#define AST_RIGHT_REP (BUTTON_RIGHT | BUTTON_REPEAT) #define AST_FIRE BUTTON_MENU -#define AST_FIRE_REP BUTTON_MENU | BUTTON_REPEAT #elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ (CONFIG_KEYPAD == IRIVER_H300_PAD) #define AST_PAUSE BUTTON_REC #define AST_QUIT BUTTON_OFF -#define AST_THRUST_REP BUTTON_UP | BUTTON_REPEAT #define AST_THRUST BUTTON_UP #define AST_HYPERSPACE BUTTON_DOWN #define AST_LEFT BUTTON_LEFT -#define AST_LEFT_REP BUTTON_LEFT | BUTTON_REPEAT #define AST_RIGHT BUTTON_RIGHT -#define AST_RIGHT_REP (BUTTON_RIGHT | BUTTON_REPEAT) #define AST_FIRE BUTTON_SELECT -#define AST_FIRE_REP BUTTON_SELECT | BUTTON_REPEAT #define AST_RC_QUIT BUTTON_RC_STOP #elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD) #define AST_PAUSE BUTTON_PLAY #define AST_QUIT BUTTON_POWER -#define AST_THRUST_REP BUTTON_UP | BUTTON_REPEAT #define AST_THRUST BUTTON_UP #define AST_HYPERSPACE BUTTON_DOWN #define AST_LEFT BUTTON_LEFT -#define AST_LEFT_REP BUTTON_LEFT | BUTTON_REPEAT #define AST_RIGHT BUTTON_RIGHT -#define AST_RIGHT_REP (BUTTON_RIGHT | BUTTON_REPEAT) #define AST_FIRE BUTTON_SELECT -#define AST_FIRE_REP BUTTON_SELECT | BUTTON_REPEAT #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \ (CONFIG_KEYPAD == IPOD_1G2G_PAD) #define AST_PAUSE (BUTTON_SELECT | BUTTON_PLAY) #define AST_QUIT (BUTTON_SELECT | BUTTON_MENU) #define AST_THRUST BUTTON_MENU -#define AST_THRUST_REP (BUTTON_MENU | BUTTON_REPEAT) #define AST_HYPERSPACE BUTTON_PLAY #define AST_LEFT BUTTON_SCROLL_BACK -#define AST_LEFT_REP (BUTTON_SCROLL_BACK | BUTTON_REPEAT) #define AST_RIGHT BUTTON_SCROLL_FWD -#define AST_RIGHT_REP (BUTTON_SCROLL_FWD | BUTTON_REPEAT) #define AST_FIRE BUTTON_SELECT -#define AST_FIRE_REP (BUTTON_SELECT | BUTTON_REPEAT) #elif (CONFIG_KEYPAD == GIGABEAT_PAD) #define AST_PAUSE BUTTON_A #define AST_QUIT BUTTON_POWER -#define AST_THRUST_REP BUTTON_UP | BUTTON_REPEAT #define AST_THRUST BUTTON_UP #define AST_HYPERSPACE BUTTON_DOWN #define AST_LEFT BUTTON_LEFT -#define AST_LEFT_REP BUTTON_LEFT | BUTTON_REPEAT #define AST_RIGHT BUTTON_RIGHT -#define AST_RIGHT_REP (BUTTON_RIGHT | BUTTON_REPEAT) #define AST_FIRE BUTTON_SELECT -#define AST_FIRE_REP BUTTON_SELECT | BUTTON_REPEAT #elif (CONFIG_KEYPAD == SANSA_E200_PAD) #define AST_PAUSE BUTTON_REC #define AST_QUIT BUTTON_POWER -#define AST_THRUST_REP (BUTTON_UP | BUTTON_REPEAT) #define AST_THRUST BUTTON_UP #define AST_HYPERSPACE BUTTON_DOWN #define AST_LEFT BUTTON_SCROLL_BACK -#define AST_LEFT_REP (BUTTON_SCROLL_BACK | BUTTON_REPEAT) #define AST_RIGHT BUTTON_SCROLL_FWD -#define AST_RIGHT_REP (BUTTON_SCROLL_FWD | BUTTON_REPEAT) #define AST_FIRE BUTTON_SELECT -#define AST_FIRE_REP (BUTTON_SELECT | BUTTON_REPEAT) #elif (CONFIG_KEYPAD == SANSA_FUZE_PAD) #define AST_PAUSE (BUTTON_SELECT | BUTTON_UP) #define AST_QUIT (BUTTON_HOME|BUTTON_REPEAT) -#define AST_THRUST_REP (BUTTON_UP | BUTTON_REPEAT) #define AST_THRUST BUTTON_UP #define AST_HYPERSPACE BUTTON_DOWN #define AST_LEFT BUTTON_SCROLL_BACK -#define AST_LEFT_REP (BUTTON_SCROLL_BACK | BUTTON_REPEAT) #define AST_RIGHT BUTTON_SCROLL_FWD -#define AST_RIGHT_REP (BUTTON_SCROLL_FWD | BUTTON_REPEAT) #define AST_FIRE BUTTON_SELECT -#define AST_FIRE_REP (BUTTON_SELECT | BUTTON_REPEAT) #elif (CONFIG_KEYPAD == SANSA_C200_PAD) #define AST_PAUSE BUTTON_REC #define AST_QUIT BUTTON_POWER -#define AST_THRUST_REP (BUTTON_UP | BUTTON_REPEAT) #define AST_THRUST BUTTON_UP #define AST_HYPERSPACE BUTTON_DOWN #define AST_LEFT BUTTON_LEFT -#define AST_LEFT_REP (BUTTON_LEFT | BUTTON_REPEAT) #define AST_RIGHT BUTTON_RIGHT -#define AST_RIGHT_REP (BUTTON_RIGHT | BUTTON_REPEAT) #define AST_FIRE BUTTON_SELECT -#define AST_FIRE_REP (BUTTON_SELECT | BUTTON_REPEAT) #elif (CONFIG_KEYPAD == SANSA_CLIP_PAD) #define AST_PAUSE BUTTON_HOME #define AST_QUIT BUTTON_POWER -#define AST_THRUST_REP (BUTTON_UP | BUTTON_REPEAT) #define AST_THRUST BUTTON_UP #define AST_HYPERSPACE BUTTON_DOWN #define AST_LEFT BUTTON_LEFT -#define AST_LEFT_REP (BUTTON_LEFT | BUTTON_REPEAT) #define AST_RIGHT BUTTON_RIGHT -#define AST_RIGHT_REP (BUTTON_RIGHT | BUTTON_REPEAT) #define AST_FIRE BUTTON_SELECT -#define AST_FIRE_REP (BUTTON_SELECT | BUTTON_REPEAT) #elif (CONFIG_KEYPAD == SANSA_M200_PAD) #define AST_PAUSE (BUTTON_SELECT | BUTTON_UP) #define AST_QUIT BUTTON_POWER -#define AST_THRUST_REP (BUTTON_UP | BUTTON_REPEAT) #define AST_THRUST BUTTON_UP #define AST_HYPERSPACE BUTTON_DOWN #define AST_LEFT BUTTON_LEFT -#define AST_LEFT_REP (BUTTON_LEFT | BUTTON_REPEAT) #define AST_RIGHT BUTTON_RIGHT -#define AST_RIGHT_REP (BUTTON_RIGHT | BUTTON_REPEAT) #define AST_FIRE (BUTTON_SELECT | BUTTON_REL) -#define AST_FIRE_REP (BUTTON_SELECT | BUTTON_REPEAT) #elif (CONFIG_KEYPAD == IRIVER_H10_PAD) #define AST_PAUSE BUTTON_PLAY #define AST_QUIT BUTTON_POWER -#define AST_THRUST_REP BUTTON_SCROLL_UP | BUTTON_REPEAT #define AST_THRUST BUTTON_SCROLL_UP #define AST_HYPERSPACE BUTTON_SCROLL_DOWN #define AST_LEFT BUTTON_LEFT -#define AST_LEFT_REP BUTTON_LEFT | BUTTON_REPEAT #define AST_RIGHT BUTTON_RIGHT -#define AST_RIGHT_REP (BUTTON_RIGHT | BUTTON_REPEAT) #define AST_FIRE BUTTON_REW -#define AST_FIRE_REP BUTTON_REW | BUTTON_REPEAT #elif (CONFIG_KEYPAD == GIGABEAT_S_PAD) #define AST_PAUSE BUTTON_PLAY #define AST_QUIT BUTTON_BACK -#define AST_THRUST_REP BUTTON_UP | BUTTON_REPEAT #define AST_THRUST BUTTON_UP #define AST_HYPERSPACE BUTTON_DOWN #define AST_LEFT BUTTON_LEFT -#define AST_LEFT_REP BUTTON_LEFT | BUTTON_REPEAT #define AST_RIGHT BUTTON_RIGHT -#define AST_RIGHT_REP (BUTTON_RIGHT | BUTTON_REPEAT) #define AST_FIRE BUTTON_SELECT -#define AST_FIRE_REP BUTTON_SELECT | BUTTON_REPEAT #elif (CONFIG_KEYPAD == MROBE100_PAD) #define AST_PAUSE BUTTON_DISPLAY #define AST_QUIT BUTTON_POWER -#define AST_THRUST_REP BUTTON_UP | BUTTON_REPEAT #define AST_THRUST BUTTON_UP #define AST_HYPERSPACE BUTTON_DOWN #define AST_LEFT BUTTON_LEFT -#define AST_LEFT_REP BUTTON_LEFT | BUTTON_REPEAT #define AST_RIGHT BUTTON_RIGHT -#define AST_RIGHT_REP (BUTTON_RIGHT | BUTTON_REPEAT) #define AST_FIRE BUTTON_SELECT -#define AST_FIRE_REP BUTTON_SELECT | BUTTON_REPEAT #elif CONFIG_KEYPAD == IAUDIO_M3_PAD #define AST_PAUSE BUTTON_RC_PLAY #define AST_QUIT BUTTON_RC_REC -#define AST_THRUST_REP BUTTON_RC_VOL_UP | BUTTON_REPEAT #define AST_THRUST BUTTON_RC_VOL_UP #define AST_HYPERSPACE BUTTON_RC_VOL_DOWN #define AST_LEFT BUTTON_RC_REW -#define AST_LEFT_REP (BUTTON_RC_REW | BUTTON_REPEAT) #define AST_RIGHT BUTTON_RC_FF -#define AST_RIGHT_REP (BUTTON_RC_FF | BUTTON_REPEAT) #define AST_FIRE BUTTON_RC_MODE -#define AST_FIRE_REP (BUTTON_RC_MODE | BUTTON_REPEAT) #elif (CONFIG_KEYPAD == COWOND2_PAD) #define AST_QUIT BUTTON_POWER @@ -244,28 +182,20 @@ #elif CONFIG_KEYPAD == CREATIVEZVM_PAD #define AST_PAUSE BUTTON_PLAY #define AST_QUIT BUTTON_BACK -#define AST_THRUST_REP (BUTTON_UP | BUTTON_REPEAT) #define AST_THRUST BUTTON_UP #define AST_HYPERSPACE BUTTON_DOWN #define AST_LEFT BUTTON_LEFT -#define AST_LEFT_REP (BUTTON_LEFT | BUTTON_REPEAT) #define AST_RIGHT BUTTON_RIGHT -#define AST_RIGHT_REP (BUTTON_RIGHT | BUTTON_REPEAT) #define AST_FIRE BUTTON_SELECT -#define AST_FIRE_REP (BUTTON_SELECT | BUTTON_REPEAT) #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD #define AST_PAUSE BUTTON_VIEW #define AST_QUIT BUTTON_POWER -#define AST_THRUST_REP (BUTTON_UP | BUTTON_REPEAT) #define AST_THRUST BUTTON_UP #define AST_HYPERSPACE BUTTON_DOWN #define AST_LEFT BUTTON_LEFT -#define AST_LEFT_REP (BUTTON_LEFT | BUTTON_REPEAT) #define AST_RIGHT BUTTON_RIGHT -#define AST_RIGHT_REP (BUTTON_RIGHT | BUTTON_REPEAT) #define AST_FIRE BUTTON_PLAYLIST -#define AST_FIRE_REP (BUTTON_PLAYLIST | BUTTON_REPEAT) #elif (CONFIG_KEYPAD == ONDAVX747_PAD) || CONFIG_KEYPAD == MROBE500_PAD #define AST_QUIT BUTTON_POWER @@ -332,7 +262,6 @@ #define WRAP_GAP 12 #define EXPLOSION_LENGTH 20 #define SHOW_COL 0 -#define HISCORE_FILE PLUGIN_GAMES_DIR "/astrorocks.hs" #define POINT_SIZE 2 #define MAX_NUM_ASTEROIDS 25 #define MAX_NUM_MISSILES 6 @@ -426,6 +355,13 @@ #define SET_BG(x) #endif +#define MARGIN 5 + +#define HIGH_SCORE PLUGIN_GAMES_DIR "/spacerocks.score" +#define NUM_SCORES 5 + +struct highscore highest[NUM_SCORES]; + /* The array of points that make up an asteroid */ static const short asteroid_one[NUM_ASTEROID_VERTICES*2] = { @@ -598,14 +534,11 @@ static int extra_life; static int show_level_timeout; static int attract_flip_timeout; -static int show_game_over; static int current_level; static int current_score; -static int high_score; static int space_check_size = 30*SCALE; static bool enemy_on_screen; -static char phscore[30]; static struct Ship ship; static struct Point stars[NUM_STARS]; static struct Asteroid asteroids_array[MAX_NUM_ASTEROIDS]; @@ -648,40 +581,145 @@ void drawstars(void); bool is_ship_within_asteroid(struct Asteroid* asteroid); - - -/*Hi-Score reading and writing to file - this needs moving to the hi-score plugin lib as -a 3rd function */ -void iohiscore(void) +static void spacerocks_show_highscores(int position) { - int fd; - int compare; + int i, w, h; + char str[30]; - /* clear the buffer we're about to load the highscore data into */ - rb->memset(phscore, 0, sizeof(phscore)); +#ifdef HAVE_LCD_COLOR + rb->lcd_set_background(LCD_BLACK); + rb->lcd_set_foreground(LCD_WHITE); +#endif + rb->button_clear_queue(); + rb->lcd_clear_display(); - fd = rb->open(HISCORE_FILE,O_RDWR | O_CREAT); - if(fd < 0) + rb->lcd_setfont(FONT_UI); + rb->lcd_getstringsize("High Scores", &w, &h); + /* check wether it fits on screen */ + if ((4*h + h*(NUM_SCORES-1) + MARGIN) > LCD_HEIGHT) { + rb->lcd_setfont(FONT_SYSFIXED); + rb->lcd_getstringsize("High Scores", &w, &h); + } + rb->lcd_putsxy(LCD_WIDTH/2-w/2, MARGIN, "High Scores"); + rb->lcd_putsxy(LCD_WIDTH/4-w/4,2*h, "Score"); + rb->lcd_putsxy(LCD_WIDTH*3/4-w/4,2*h, "Level"); + + for (i = 0; isplash(HZ, "Highscore file read error"); - return; +#ifdef HAVE_LCD_COLOR + if (i == position) { + rb->lcd_set_foreground(LCD_RGBPACK(245,0,0)); + } +#endif + rb->snprintf (str, sizeof (str), "%d)", i+1); + rb->lcd_putsxy (MARGIN,3*h + h*i, str); + rb->snprintf (str, sizeof (str), "%d", highest[i].score); + rb->lcd_putsxy (LCD_WIDTH/4-w/4,3*h + h*i, str); + rb->snprintf (str, sizeof (str), "%d", highest[i].level); + rb->lcd_putsxy (LCD_WIDTH*3/4-w/4,3*h + h*i, str); + if(i == position) { +#ifdef HAVE_LCD_COLOR + rb->lcd_set_foreground(LCD_WHITE); +#else + rb->lcd_hline(MARGIN, LCD_WIDTH-MARGIN, 3*h + h*(i+1)); +#endif + } } + rb->lcd_update(); + rb->button_get(true); + rb->lcd_setfont(FONT_SYSFIXED); +} + +void start_attract_mode(void) +{ + enemy.appear_probability = ENEMY_APPEAR_PROBABILITY_START; + enemy.appear_timing = ENEMY_APPEAR_TIMING_START; + current_level = 5; + num_lives = START_LIVES; + current_score = 0; + attract_flip_timeout = ATTRACT_FLIP_TIME; + game_state = ATTRACT_MODE; + if(asteroid_count < 3) + initialise_game(current_level); +} + +static int spacerocks_help(void) +{ + rb->lcd_setfont(FONT_UI); +#define WORDS (sizeof help_text / sizeof (char*)) + static char *help_text[] = { + "Spacerocks", "", "Aim", "", "The", "goal", "of", "the", "game", "is", + "to", "blow", "up", "the", "asteroids", "and", "avoid", "being", "hit", "by", + "them.", "Also", "you'd", "better", "watch", "out", "for", "the", "UFOs!" + }; + static struct style_text formation[]={ + { 0, TEXT_CENTER|TEXT_UNDERLINE }, + { 2, C_RED } + }; - /* highscore used to %d, is now %d\n - Deal with no file or bad file */ - rb->read(fd,phscore, sizeof(phscore)); + if (display_text(WORDS, help_text, formation, NULL)==PLUGIN_USB_CONNECTED) + return PLUGIN_USB_CONNECTED; + int button; + do { + button = rb->button_get(true); + if (button == SYS_USB_CONNECTED) { + return PLUGIN_USB_CONNECTED; + } + } while( ( button == BUTTON_NONE ) + || ( button & (BUTTON_REL|BUTTON_REPEAT) ) ); + rb->lcd_setfont(FONT_SYSFIXED); + return 0; +} - compare = rb->atoi(phscore); +static bool _ingame; +static int spacerocks_menu_cb(int action, const struct menu_item_ex *this_item) +{ + if(action == ACTION_REQUEST_MENUITEM + && !_ingame && ((intptr_t)this_item)==0) + return ACTION_EXIT_MENUITEM; + return action; +} - if(high_score > compare) - { - rb->lseek(fd,0,SEEK_SET); - rb->fdprintf(fd, "%d\n", high_score); +static int spacerocks_game_menu(bool ingame) +{ + rb->button_clear_queue(); + int choice = 0; + + _ingame = ingame; + + MENUITEM_STRINGLIST (main_menu, "Spacerocks Menu", spacerocks_menu_cb, + "Resume Game", + "Start New Game", + "Help", + "High Score", + "Playback Control", + "Quit"); + + while (1) { + choice = rb->do_menu(&main_menu, &choice, NULL, false); + switch (choice) { + case 0: + return 0; + case 1: + start_attract_mode(); + return 0; + case 2: + spacerocks_help(); + break; + case 3: + spacerocks_show_highscores(NUM_SCORES); + break; + case 4: + playback_control(NULL); + break; + case 5: + return 1; + case MENU_ATTACHED_USB: + return 1; + default: + break; + } } - else - high_score = compare; - - rb->close(fd); } bool point_in_poly(struct Point* _point, int num_vertices, int x, int y) @@ -1729,7 +1767,6 @@ num_lives--; if(!num_lives) { - show_game_over = SHOW_GAME_OVER_TIME; game_state = GAME_OVER; } else @@ -1904,233 +1941,186 @@ } } -void start_attract_mode(void) -{ - enemy.appear_probability = ENEMY_APPEAR_PROBABILITY_START; - enemy.appear_timing = ENEMY_APPEAR_TIMING_START; - current_level = 5; - num_lives = START_LIVES; - current_score = 0; - attract_flip_timeout = ATTRACT_FLIP_TIME; - game_state = ATTRACT_MODE; - if(asteroid_count < 3) - initialise_game(current_level); -} -enum plugin_status start_game(void) +static int spacerocks_game_loop(void) { char s[20]; char level[10]; int button; int end; int CYCLETIME = 30; - + int position; + /*create stars once, and once only:*/ create_stars(); + + if (spacerocks_game_menu(false)!=0) { + return 0; + } SET_BG(LCD_BLACK); - - while(true) - { - /*game starts with at level 1 - with 1 asteroid.*/ - start_attract_mode(); - - /*Main loop*/ - while(true) - { - end = *rb->current_tick + (CYCLETIME * HZ) / 1000; - rb->lcd_clear_display(); - SET_FG(COL_TEXT); - switch(game_state) - { - case(ATTRACT_MODE): - if(attract_flip_timeout < ATTRACT_FLIP_TIME/2) - { - rb->lcd_putsxy(CENTER_LCD_X - 39, - CENTER_LCD_Y + CENTER_LCD_Y/2 - 4, - "Fire to Start"); - if(!attract_flip_timeout) - attract_flip_timeout = ATTRACT_FLIP_TIME; + + while(true) + { + end = *rb->current_tick + (CYCLETIME * HZ) / 1000; + rb->lcd_clear_display(); + SET_FG(COL_TEXT); + switch(game_state) { + case(ATTRACT_MODE): + rb->lcd_putsxy(CENTER_LCD_X - 39, + CENTER_LCD_Y + CENTER_LCD_Y/2 - 4, + "Fire to Start"); + break; + + case(GAME_OVER): + rb->splash (HZ * 2, "Game Over"); + rb->lcd_clear_display(); + if (highscore_would_update(current_score, highest, + NUM_SCORES)) { + position=highscore_update(current_score, current_level, "", + highest,NUM_SCORES); + if (position == 0) { + rb->splash(HZ*2, "New High Score"); } - else - { - rb->snprintf(s, sizeof(s), "Hi Score %d ", high_score); - rb->lcd_putsxy(CENTER_LCD_X - 30, - CENTER_LCD_Y + CENTER_LCD_Y/2 - 4, s); - } - attract_flip_timeout--; - break; - - case(GAME_OVER): - rb->lcd_putsxy(CENTER_LCD_X - 25, - CENTER_LCD_Y + CENTER_LCD_Y/2 - 4, "Game Over"); - rb->snprintf(s, sizeof(s), "score %d ", current_score); - rb->lcd_putsxy(1,LCD_HEIGHT-8, s); - show_game_over--; - if(!show_game_over) - start_attract_mode(); - break; - - case(PAUSE_MODE): - rb->snprintf(s, sizeof(s), "score %d ", current_score); - rb->lcd_putsxy(1,LCD_HEIGHT-8, s); - rb->lcd_putsxy(CENTER_LCD_X - 15, - CENTER_LCD_Y + CENTER_LCD_Y/2 - 4, "pause"); - draw_and_move_missiles(); - draw_lives(); - draw_and_move_ship(); - break; - - case(PLAY_MODE): - rb->snprintf(s, sizeof(s), "score %d ", current_score); - rb->lcd_putsxy(1,LCD_HEIGHT-8, s); - draw_and_move_missiles(); - draw_lives(); - check_collisions(); - draw_and_move_ship(); - break; - - case(SHOW_LEVEL): - show_level_timeout--; - rb->snprintf(s, sizeof(s), "score %d ", current_score); - rb->lcd_putsxy(1,LCD_HEIGHT-8, s); - rb->snprintf(level, sizeof(level), "stage %d ", current_level); - rb->lcd_putsxy(CENTER_LCD_X - 20, - CENTER_LCD_Y + CENTER_LCD_Y/2 - 4, level); - draw_and_move_ship(); - draw_lives(); - if(!show_level_timeout) - { - initialise_game(current_level); - game_state = PLAY_MODE; - draw_lives(); - } - break; + spacerocks_show_highscores(position); } - draw_trail_blaze(); - drawstars(); - draw_and_move_asteroids(); - draw_and_move_enemy(); - - rb->lcd_update(); - button = rb->button_get(false); + if (spacerocks_game_menu(false)!=0) { + return 0; + } + break; + + case(PAUSE_MODE): + rb->snprintf(s, sizeof(s), "score %d ", current_score); + rb->lcd_putsxy(1,LCD_HEIGHT-8, s); + rb->lcd_putsxy(CENTER_LCD_X - 15, + CENTER_LCD_Y + CENTER_LCD_Y/2 - 4, "pause"); + draw_and_move_missiles(); + draw_lives(); + draw_and_move_ship(); + break; + + case(PLAY_MODE): + rb->snprintf(s, sizeof(s), "score %d ", current_score); + rb->lcd_putsxy(1,LCD_HEIGHT-8, s); + draw_and_move_missiles(); + draw_lives(); + check_collisions(); + draw_and_move_ship(); + break; + case(SHOW_LEVEL): + show_level_timeout--; + rb->snprintf(s, sizeof(s), "score %d ", current_score); + rb->lcd_putsxy(1,LCD_HEIGHT-8, s); + rb->snprintf(level, sizeof(level), "stage %d ", current_level); + rb->lcd_putsxy(CENTER_LCD_X - 20, + CENTER_LCD_Y + CENTER_LCD_Y/2 - 4, level); + draw_and_move_ship(); + draw_lives(); + if(!show_level_timeout) { + initialise_game(current_level); + game_state = PLAY_MODE; + draw_lives(); + } + break; + } + draw_trail_blaze(); + drawstars(); + draw_and_move_asteroids(); + draw_and_move_enemy(); + + rb->lcd_update(); + #ifdef HAS_BUTTON_HOLD - if (rb->button_hold() && game_state == PLAY_MODE) - game_state = PAUSE_MODE; -#endif + if (rb->button_hold()) + game_state = PAUSE_MODE; - switch(button) - { - case(AST_PAUSE): - if(game_state == PLAY_MODE) - game_state = PAUSE_MODE; - else if(game_state == PAUSE_MODE) - game_state = PLAY_MODE; - break; - -#ifdef AST_RC_QUIT - case AST_RC_QUIT: #endif - case(AST_QUIT): - if(game_state == ATTRACT_MODE) - return PLUGIN_OK; - else if(game_state == GAME_OVER) - { - start_attract_mode(); - } - else - { - show_game_over = SHOW_GAME_OVER_TIME; - game_state = GAME_OVER; - } - break; - - case (AST_LEFT_REP): - case (AST_LEFT): - if(game_state == PLAY_MODE || game_state == SHOW_LEVEL) - rotate_ship(SHIP_ROT_ACW_COS, SHIP_ROT_ACW_SIN); - break; - - case (AST_RIGHT_REP): - case (AST_RIGHT): - if(game_state == PLAY_MODE || game_state == SHOW_LEVEL) - rotate_ship(SHIP_ROT_CW_COS, SHIP_ROT_CW_SIN); - break; - - case (AST_THRUST_REP): - case (AST_THRUST): - if((game_state == PLAY_MODE || game_state == SHOW_LEVEL) && !next_thrust_count) - { - thrust_ship(); - next_thrust_count = 5; - } - break; - - case (AST_HYPERSPACE): - if(game_state == PLAY_MODE) - hyperspace(); - /*maybe shield if it gets too hard */ - break; - - case (AST_FIRE_REP): - case (AST_FIRE): - if(game_state == ATTRACT_MODE) - { - current_level = START_LEVEL; - initialise_ship(); - initialise_game(current_level); - show_level_timeout = SHOW_LEVEL_TIME; + button = rb->button_get(false); + switch(button) { + case(AST_QUIT): + if (spacerocks_game_menu(true)!=0) { + return 0; + } + break; +#ifdef AST_PAUSE + case(AST_PAUSE): + if (game_state == PAUSE_MODE) { game_state = PLAY_MODE; - } - else if(game_state == PLAY_MODE) - { - if(!next_missile_count) - { - fire_missile(); - next_missile_count = 10; - } - } - else if(game_state == PAUSE_MODE) - { - game_state = PLAY_MODE; - } - break; - - default: - if (rb->default_event_handler(button)==SYS_USB_CONNECTED) - return PLUGIN_USB_CONNECTED; - break; - } - - if(!num_lives) - { - if(high_score < current_score) - high_score = current_score; - if(!show_game_over) break; - } - - if(next_missile_count) - next_missile_count--; - - if(next_thrust_count) - next_thrust_count--; - - if (end > *rb->current_tick) - rb->sleep(end-*rb->current_tick); - else - rb->yield(); - } - - } + } + else if (game_state != PLAY_MODE) + break; +#endif + case (AST_LEFT): + case (AST_LEFT | BUTTON_REPEAT): + if(game_state == PLAY_MODE || game_state == SHOW_LEVEL) + rotate_ship(SHIP_ROT_ACW_COS, SHIP_ROT_ACW_SIN); + break; + + case (AST_RIGHT): + case (AST_RIGHT | BUTTON_REPEAT): + if(game_state == PLAY_MODE || game_state == SHOW_LEVEL) + rotate_ship(SHIP_ROT_CW_COS, SHIP_ROT_CW_SIN); + break; + + case (AST_THRUST): + case (AST_THRUST | BUTTON_REPEAT): + if((game_state == PLAY_MODE || game_state == SHOW_LEVEL) && !next_thrust_count) { + thrust_ship(); + next_thrust_count = 5; + } + break; + + case (AST_HYPERSPACE): + if(game_state == PLAY_MODE) + hyperspace(); + /*maybe shield if it gets too hard */ + break; + + case (AST_FIRE): + case (AST_FIRE | BUTTON_REPEAT): + if(game_state == ATTRACT_MODE) { + current_level = START_LEVEL; + initialise_ship(); + initialise_game(current_level); + show_level_timeout = SHOW_LEVEL_TIME; + game_state = PLAY_MODE; + } + else if(game_state == PLAY_MODE) { + if(!next_missile_count) { + fire_missile(); + next_missile_count = 10; + } + } + else if(game_state == PAUSE_MODE) { + game_state = PLAY_MODE; + } + break; + + default: + if (rb->default_event_handler(button)==SYS_USB_CONNECTED) + return PLUGIN_USB_CONNECTED; + break; + } + + if(next_missile_count) + next_missile_count--; + + if(next_thrust_count) + next_thrust_count--; + + if (end > *rb->current_tick) + rb->sleep(end-*rb->current_tick); + else + rb->yield(); + } } enum plugin_status plugin_start(const void* parameter) { - enum plugin_status retval; - (void)(parameter); + (void)parameter; +#ifdef HAVE_LCD_BITMAP game_state = ATTRACT_MODE; @@ -2141,11 +2131,13 @@ rb->lcd_setfont(FONT_SYSFIXED); /* Turn off backlight timeout */ backlight_force_on(); /* backlight control in lib/helper.c */ - iohiscore(); - retval = start_game(); - iohiscore(); + highscore_load(HIGH_SCORE,highest,NUM_SCORES); + spacerocks_game_loop(); rb->lcd_setfont(FONT_UI); + highscore_save(HIGH_SCORE,highest,NUM_SCORES); /* Turn on backlight timeout (revert to settings) */ backlight_use_settings(); /* backlight control in lib/helper.c */ - return retval; +#endif + + return PLUGIN_OK; } Index: apps/plugins/brickmania.c =================================================================== --- apps/plugins/brickmania.c (Revision 21733) +++ apps/plugins/brickmania.c (Arbeitskopie) @@ -20,26 +20,25 @@ ****************************************************************************/ #include "plugin.h" -#include "lib/configfile.h" /* Part of libplugin */ +#include "lib/configfile.h" +#include "lib/display_text.h" #include "lib/helper.h" +#include "lib/highscore.h" +#include "lib/playback_control.h" PLUGIN_HEADER - -#if (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD) - +#if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ + (CONFIG_KEYPAD == IRIVER_H300_PAD) #define QUIT BUTTON_OFF #define LEFT BUTTON_LEFT #define RIGHT BUTTON_RIGHT #define SELECT BUTTON_SELECT #define UP BUTTON_UP #define DOWN BUTTON_DOWN - #define RC_QUIT BUTTON_RC_STOP - #elif CONFIG_KEYPAD == ONDIO_PAD - #define QUIT BUTTON_OFF #define LEFT BUTTON_LEFT #define RIGHT BUTTON_RIGHT @@ -47,9 +46,7 @@ #define UP BUTTON_UP #define DOWN BUTTON_DOWN - #elif CONFIG_KEYPAD == RECORDER_PAD - #define QUIT BUTTON_OFF #define LEFT BUTTON_LEFT #define RIGHT BUTTON_RIGHT @@ -57,9 +54,7 @@ #define UP BUTTON_UP #define DOWN BUTTON_DOWN - #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD - #define QUIT BUTTON_OFF #define LEFT BUTTON_LEFT #define RIGHT BUTTON_RIGHT @@ -67,24 +62,19 @@ #define UP BUTTON_UP #define DOWN BUTTON_DOWN - #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \ (CONFIG_KEYPAD == IPOD_3G_PAD) || \ (CONFIG_KEYPAD == IPOD_1G2G_PAD) - #define QUIT BUTTON_MENU #define LEFT BUTTON_LEFT #define RIGHT BUTTON_RIGHT #define SELECT BUTTON_SELECT #define UP BUTTON_SCROLL_BACK #define DOWN BUTTON_SCROLL_FWD - #define SCROLL_FWD(x) ((x) & BUTTON_SCROLL_FWD) #define SCROLL_BACK(x) ((x) & BUTTON_SCROLL_BACK) - #elif (CONFIG_KEYPAD == GIGABEAT_PAD) - #define QUIT BUTTON_POWER #define LEFT BUTTON_LEFT #define RIGHT BUTTON_RIGHT @@ -92,9 +82,7 @@ #define UP BUTTON_UP #define DOWN BUTTON_DOWN - #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD - #define QUIT BUTTON_POWER #define LEFT BUTTON_LEFT #define RIGHT BUTTON_RIGHT @@ -102,28 +90,24 @@ #define UP BUTTON_UP #define DOWN BUTTON_DOWN - #elif (CONFIG_KEYPAD == SANSA_E200_PAD) - -#define QUIT BUTTON_POWER -#define LEFT BUTTON_LEFT -#define RIGHT BUTTON_RIGHT -#define SELECT BUTTON_SELECT -#define UP BUTTON_SCROLL_BACK -#define DOWN BUTTON_SCROLL_FWD - +#define QUIT BUTTON_POWER +#define LEFT BUTTON_LEFT +#define RIGHT BUTTON_RIGHT +#define SELECT BUTTON_SELECT +#define UP BUTTON_UP +#define DOWN BUTTON_DOWN #define SCROLL_FWD(x) ((x) & BUTTON_SCROLL_FWD) #define SCROLL_BACK(x) ((x) & BUTTON_SCROLL_BACK) #elif (CONFIG_KEYPAD == SANSA_FUZE_PAD) - #define QUIT (BUTTON_HOME|BUTTON_REPEAT) #define LEFT BUTTON_LEFT #define RIGHT BUTTON_RIGHT #define SELECT BUTTON_SELECT -#define UP BUTTON_SCROLL_BACK -#define DOWN BUTTON_SCROLL_FWD +#define UP BUTTON_UP +#define DOWN BUTTON_DOWN #define SCROLL_FWD(x) ((x) & BUTTON_SCROLL_FWD) #define SCROLL_BACK(x) ((x) & BUTTON_SCROLL_BACK) @@ -132,7 +116,6 @@ #elif CONFIG_KEYPAD == SANSA_C200_PAD || \ CONFIG_KEYPAD == SANSA_CLIP_PAD || \ CONFIG_KEYPAD == SANSA_M200_PAD - #define QUIT BUTTON_POWER #define LEFT BUTTON_LEFT #define RIGHT BUTTON_RIGHT @@ -142,9 +125,7 @@ #define UP BUTTON_UP #define DOWN BUTTON_DOWN - #elif CONFIG_KEYPAD == IRIVER_H10_PAD - #define QUIT BUTTON_POWER #define LEFT BUTTON_LEFT #define RIGHT BUTTON_RIGHT @@ -153,7 +134,6 @@ #define DOWN BUTTON_SCROLL_DOWN #elif CONFIG_KEYPAD == GIGABEAT_S_PAD - #define QUIT BUTTON_BACK #define LEFT BUTTON_LEFT #define RIGHT BUTTON_RIGHT @@ -162,7 +142,6 @@ #define DOWN BUTTON_DOWN #elif (CONFIG_KEYPAD == MROBE100_PAD) - #define QUIT BUTTON_POWER #define LEFT BUTTON_LEFT #define RIGHT BUTTON_RIGHT @@ -171,21 +150,15 @@ #define DOWN BUTTON_DOWN #elif CONFIG_KEYPAD == IAUDIO_M3_PAD - #define QUIT BUTTON_RC_REC #define LEFT BUTTON_RC_REW #define RIGHT BUTTON_RC_FF #define SELECT BUTTON_RC_PLAY #define UP BUTTON_RC_VOL_UP #define DOWN BUTTON_RC_VOL_DOWN - #define RC_QUIT BUTTON_REC -#elif CONFIG_KEYPAD == COWOND2_PAD -#define QUIT BUTTON_POWER - #elif CONFIG_KEYPAD == CREATIVEZVM_PAD - #define QUIT BUTTON_BACK #define LEFT BUTTON_LEFT #define RIGHT BUTTON_RIGHT @@ -194,7 +167,6 @@ #define DOWN BUTTON_DOWN #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD - #define QUIT BUTTON_POWER #define LEFT BUTTON_LEFT #define RIGHT BUTTON_RIGHT @@ -202,6 +174,9 @@ #define UP BUTTON_UP #define DOWN BUTTON_DOWN +#elif CONFIG_KEYPAD == COWOND2_PAD +#define QUIT BUTTON_POWER + #elif CONFIG_KEYPAD == ONDAVX747_PAD #define QUIT BUTTON_POWER #define LEFT BUTTON_VOL_DOWN @@ -238,24 +213,10 @@ #define SCROLL_BACK(x) (0) #endif - -enum menu_items { - BM_START, - BM_SEL_START, - BM_RESUME, - BM_SEL_RESUME, - BM_NO_RESUME, - BM_HELP, - BM_SEL_HELP, - BM_QUIT, - BM_SEL_QUIT, -}; - #include "pluginbitmaps/brickmania_pads.h" #include "pluginbitmaps/brickmania_bricks.h" #include "pluginbitmaps/brickmania_powerups.h" #include "pluginbitmaps/brickmania_ball.h" -#include "pluginbitmaps/brickmania_menu_items.h" #include "pluginbitmaps/brickmania_gameover.h" #define PAD_WIDTH BMPWIDTH_brickmania_pads @@ -267,23 +228,14 @@ #define POWERUP_WIDTH BMPWIDTH_brickmania_powerups #define BALL BMPHEIGHT_brickmania_ball #define HALFBALL ((BALL+1)/2) -#define MENU_ITEMXOFS ((LCD_WIDTH - BMPWIDTH_brickmania_menu_items)/2) -#define MENU_ITEMHEIGHT (BMPHEIGHT_brickmania_menu_items/9) -#define MENU_ITEMWIDTH BMPWIDTH_brickmania_menu_items #define GAMEOVER_WIDTH BMPWIDTH_brickmania_gameover #define GAMEOVER_HEIGHT BMPHEIGHT_brickmania_gameover -#if LCD_DEPTH > 1 /* currently no background bmp for mono screens */ -#include "pluginbitmaps/brickmania_menu_bg.h" -#define MENU_BGHEIGHT BMPHEIGHT_brickmania_menu_bg -#define MENU_BGWIDTH BMPWIDTH_brickmania_menu_bg -#endif - #ifdef HAVE_LCD_COLOR /* currently no transparency for non-colour */ #include "pluginbitmaps/brickmania_break.h" #endif -#if ((LCD_WIDTH == 320) || (LCD_WIDTH == 400)) && (LCD_HEIGHT == 240) +#if (LCD_WIDTH == 320) && (LCD_HEIGHT == 240) /* The time (in ms) for one iteration through the game loop - decrease this to speed up the game - note that current_tick is (currently) only accurate @@ -294,8 +246,6 @@ #define TOPMARGIN 30 #define BMPYOFS_start 110 -#define HIGHSCORE_XPOS 57 -#define HIGHSCORE_YPOS 88 #define STRINGPOS_FINISH 140 #define STRINGPOS_CONGRATS 157 @@ -319,8 +269,6 @@ #define YOFS ((LCD_HEIGHT-176)/BRICK_HEIGHT/2)*BRICK_HEIGHT #define BMPYOFS_start (78+YOFS) -#define HIGHSCORE_XPOS (17+XOFS) -#define HIGHSCORE_YPOS (56+YOFS) #define STRINGPOS_FINISH 140 #define STRINGPOS_CONGRATS 157 @@ -341,8 +289,6 @@ #else #define BMPYOFS_start 66 #endif -#define HIGHSCORE_XPOS 10 -#define HIGHSCORE_YPOS 38 #define STRINGPOS_FINISH 110 #define STRINGPOS_CONGRATS 100 @@ -360,8 +306,6 @@ #define TOPMARGIN 10 #define BMPYOFS_start 30 -#define HIGHSCORE_XPOS 68 -#define HIGHSCORE_YPOS 8 #define STRINGPOS_FINISH 55 #define STRINGPOS_CONGRATS 45 @@ -380,8 +324,6 @@ #define TOPMARGIN 15 #define BMPYOFS_start 70 -#define HIGHSCORE_XPOS 8 -#define HIGHSCORE_YPOS 36 #define STRINGPOS_FINISH 55 #define STRINGPOS_CONGRATS 45 @@ -399,8 +341,6 @@ #define TOPMARGIN 10 #define BMPYOFS_start 51 -#define HIGHSCORE_XPOS 73 -#define HIGHSCORE_YPOS 25 #define STRINGPOS_FINISH 54 #define STRINGPOS_CONGRATS 44 @@ -418,8 +358,6 @@ #define TOPMARGIN 10 #define BMPYOFS_start 42 -#define HIGHSCORE_XPOS 65 -#define HIGHSCORE_YPOS 25 #define STRINGPOS_FINISH 54 #define STRINGPOS_CONGRATS 44 @@ -437,8 +375,6 @@ #define TOPMARGIN 10 #define BMPYOFS_start 22 -#define HIGHSCORE_XPOS 0 -#define HIGHSCORE_YPOS 0 #define STRINGPOS_FINISH 54 #define STRINGPOS_CONGRATS 44 @@ -458,8 +394,6 @@ #define TOPMARGIN 21 #define BMPYOFS_start 58 -#define HIGHSCORE_XPOS 7 -#define HIGHSCORE_YPOS 36 #define STRINGPOS_FINISH 110 #define STRINGPOS_CONGRATS 110 @@ -475,11 +409,6 @@ #define GAMESCREEN_HEIGHT LCD_HEIGHT #endif -/* calculate menu item offsets from the first defined and the height*/ -#define BMPYOFS_resume (BMPYOFS_start + MENU_ITEMHEIGHT) -#define BMPYOFS_help (BMPYOFS_start + 2*MENU_ITEMHEIGHT) -#define BMPYOFS_quit (BMPYOFS_start + 3*MENU_ITEMHEIGHT) - /*calculate paddle y-position */ #if GAMESCREEN_HEIGHT >= 128 #define PAD_POS_Y GAMESCREEN_HEIGHT -PAD_HEIGHT - 2 @@ -487,21 +416,12 @@ #define PAD_POS_Y GAMESCREEN_HEIGHT -PAD_HEIGHT - 1 #endif +#define MARGIN 5 -#ifdef HAVE_TOUCHSCREEN -#include "lib/touchscreen.h" - -static struct ts_mapping main_menu_items[4] = -{ - {MENU_ITEMXOFS, BMPYOFS_start, MENU_ITEMWIDTH, MENU_ITEMHEIGHT}, - {MENU_ITEMXOFS, BMPYOFS_resume, MENU_ITEMWIDTH, MENU_ITEMHEIGHT}, - {MENU_ITEMXOFS, BMPYOFS_help, MENU_ITEMWIDTH, MENU_ITEMHEIGHT}, - {MENU_ITEMXOFS, BMPYOFS_quit, MENU_ITEMWIDTH, MENU_ITEMHEIGHT} +enum Difficulty{ + EASY, HARD }; -static struct ts_mappings main_menu = {main_menu_items, 4}; -#endif - int levels_num = 29; static unsigned char levels[29][8][10] = { @@ -798,6 +718,7 @@ }; #define MAX_BALLS 10 + int pad_pos_x; int x[MAX_BALLS],y[MAX_BALLS]; int life; @@ -805,9 +726,12 @@ int pad_type; int score=0,vscore=0; bool flip_sides=false; -int cur_level=0; +int level=0; int brick_on_board=0; int used_balls=1; +bool saved_game=false; +int l_score=0; +int difficulty = EASY; typedef struct cube { int powertop; @@ -838,15 +762,22 @@ } sfire; sfire fire[30]; +#define CONFIG_FILE_NAME "brickmania.cfg" -int highscore; -#define MAX_POINTS 200000 /* i dont think it needs to be more */ -static struct configdata config[] = -{ - {TYPE_INT, 0, MAX_POINTS, { .int_p = &highscore }, "highscore", NULL} +static struct configdata config[] = { + {TYPE_INT, 0, 1, { .int_p = &difficulty }, "difficulty", NULL}, + {TYPE_BOOL, 0, 1, { .bool_p = &saved_game }, "saved_game", NULL}, + {TYPE_INT, 0, 40000, { .int_p = &l_score }, "l_score", NULL}, + {TYPE_INT, 0, 29, { .int_p = &level }, "level", NULL}, + {TYPE_INT, 0, 30, { .int_p = &life }, "life", NULL}, }; -void int_game(int new_game) +#define HIGH_SCORE PLUGIN_GAMES_DIR "/brickmania.score" +#define NUM_SCORES 5 + +struct highscore highest[NUM_SCORES]; + +static void brickmania_int_game(int new_game) { int i,j; @@ -869,27 +800,32 @@ flip_sides=false; - if (new_game==1) + if (new_game==1) { brick_on_board=0; - + /* add one life per achieved level */ + if (difficulty==EASY && life<2) { + score-=100; + life++; + } + } for(i=0;i<=7;i++) { for(j=0;j<=9;j++) { - brick[i*10+j].poweruse=(levels[cur_level][i][j]==0?0:1); + brick[i*10+j].poweruse=(levels[level][i][j]==0?0:1); if (i*10+j<=30) fire[i*10+j].top=-8; if (new_game==1) { brick[i*10+j].power=rb->rand()%25; /* +8 make the game with less powerups */ - brick[i*10+j].hits=levels[cur_level][i][j]>=10? - levels[cur_level][i][j]/16-1:0; + brick[i*10+j].hits=levels[level][i][j]>=10? + levels[level][i][j]/16-1:0; brick[i*10+j].hiteffect=0; brick[i*10+j].powertop=TOPMARGIN+i*BRICK_HEIGHT+BRICK_HEIGHT; - brick[i*10+j].used=(levels[cur_level][i][j]==0?0:1); - brick[i*10+j].color=(levels[cur_level][i][j]>=10? - levels[cur_level][i][j]%16: - levels[cur_level][i][j])-1; - if (levels[cur_level][i][j]!=0) + brick[i*10+j].used=(levels[level][i][j]==0?0:1); + brick[i*10+j].color=(levels[level][i][j]>=10? + levels[level][i][j]%16: + levels[level][i][j])-1; + if (levels[level][i][j]!=0) brick_on_board++; } } @@ -898,17 +834,24 @@ int sw,i,w; -/* sleep timer counting the score */ -void sleep (int secs) +/* brickmania_sleep timer counting the score */ +static void brickmania_sleep(int secs) { bool done=false; char s[20]; int count=0; while (!done) { - - if (vscorecurrent_tick+HZ*secs; + if (*rb->current_tick>=count) + done=true; + } else { + if (vscorescore) + vscore--; rb->snprintf(s, sizeof(s), "%d", vscore); rb->lcd_getstringsize(s, &sw, &w); #if (LCD_WIDTH == 112) && (LCD_HEIGHT == 64) @@ -917,371 +860,239 @@ rb->lcd_putsxy(LCD_WIDTH/2-sw/2, 2, s); #endif rb->lcd_update_rect(0,0,LCD_WIDTH,w+2); - } else { - if (count==0) - count=*rb->current_tick+HZ*secs; - if (*rb->current_tick>=count) - done=true; } rb->yield(); } - } -#define HIGH_SCORE "brickmania.score" -#define MENU_LENGTH 4 -int game_menu(int when) +/* display a highscore*/ +static void brickmania_show_highscores(int position) { - int button,cur=0; - char str[10]; - rb->lcd_clear_display(); -#if LCD_DEPTH > 1 /* currently no background bmp for mono screens */ - rb->lcd_bitmap(brickmania_menu_bg, 0, 0, MENU_BGWIDTH, MENU_BGHEIGHT); -#endif - while (true) { - for(i=0;ilcd_bitmap_transparent_part(brickmania_menu_items, 0, - MENU_ITEMHEIGHT * BM_SEL_START, MENU_ITEMWIDTH, - MENU_ITEMXOFS, BMPYOFS_start, MENU_ITEMWIDTH, - MENU_ITEMHEIGHT); - else - rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0, - MENU_ITEMHEIGHT * BM_START, MENU_ITEMWIDTH, - MENU_ITEMXOFS, BMPYOFS_start, MENU_ITEMWIDTH, - MENU_ITEMHEIGHT); + int i, w, h; + char str[30]; - if (when==1) { - if (cur==1) - rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0, - MENU_ITEMHEIGHT * BM_SEL_RESUME, MENU_ITEMWIDTH, - MENU_ITEMXOFS, BMPYOFS_resume, MENU_ITEMWIDTH, - MENU_ITEMHEIGHT); - else - rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0, - MENU_ITEMHEIGHT * BM_RESUME, MENU_ITEMWIDTH, - MENU_ITEMXOFS, BMPYOFS_resume, MENU_ITEMWIDTH, - MENU_ITEMHEIGHT); - - } else { - rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0, - MENU_ITEMHEIGHT * BM_NO_RESUME, MENU_ITEMWIDTH, - MENU_ITEMXOFS, BMPYOFS_resume, MENU_ITEMWIDTH, - MENU_ITEMHEIGHT); - } - - - if (cur==2) - rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0, - MENU_ITEMHEIGHT * BM_SEL_HELP, MENU_ITEMWIDTH, - MENU_ITEMXOFS, BMPYOFS_help, MENU_ITEMWIDTH, - MENU_ITEMHEIGHT); - else - rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0, - MENU_ITEMHEIGHT * BM_HELP, MENU_ITEMWIDTH, - MENU_ITEMXOFS, BMPYOFS_help, MENU_ITEMWIDTH, - MENU_ITEMHEIGHT); - - if (cur==3) - rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0, - MENU_ITEMHEIGHT * BM_SEL_QUIT, MENU_ITEMWIDTH, - MENU_ITEMXOFS, BMPYOFS_quit, MENU_ITEMWIDTH, - MENU_ITEMHEIGHT); - else - rb->lcd_bitmap_transparent_part(brickmania_menu_items, 0, - MENU_ITEMHEIGHT * BM_QUIT, MENU_ITEMWIDTH, - MENU_ITEMXOFS, BMPYOFS_quit, MENU_ITEMWIDTH, - MENU_ITEMHEIGHT); -#else - if (cur==0) - rb->lcd_bitmap_part(brickmania_menu_items, 0, - MENU_ITEMHEIGHT * BM_SEL_START, MENU_ITEMWIDTH, - MENU_ITEMXOFS, BMPYOFS_start, MENU_ITEMWIDTH, - MENU_ITEMHEIGHT); - else - rb->lcd_bitmap_part(brickmania_menu_items, 0, - MENU_ITEMHEIGHT * BM_START, MENU_ITEMWIDTH, - MENU_ITEMXOFS, BMPYOFS_start, MENU_ITEMWIDTH, - MENU_ITEMHEIGHT); - - if (when==1) { - if (cur==1) - rb->lcd_bitmap_part(brickmania_menu_items, 0, - MENU_ITEMHEIGHT * BM_SEL_RESUME, MENU_ITEMWIDTH, - MENU_ITEMXOFS, BMPYOFS_resume, MENU_ITEMWIDTH, - MENU_ITEMHEIGHT); - else - rb->lcd_bitmap_part(brickmania_menu_items, 0, - MENU_ITEMHEIGHT * BM_RESUME, MENU_ITEMWIDTH, - MENU_ITEMXOFS, BMPYOFS_resume, MENU_ITEMWIDTH, - MENU_ITEMHEIGHT); - - } else { - rb->lcd_bitmap_part(brickmania_menu_items, 0, - MENU_ITEMHEIGHT * BM_NO_RESUME, MENU_ITEMWIDTH, - MENU_ITEMXOFS, BMPYOFS_resume, MENU_ITEMWIDTH, - MENU_ITEMHEIGHT); - } - - - if (cur==2) - rb->lcd_bitmap_part(brickmania_menu_items, 0, - MENU_ITEMHEIGHT * BM_SEL_HELP, MENU_ITEMWIDTH, - MENU_ITEMXOFS, BMPYOFS_help, MENU_ITEMWIDTH, - MENU_ITEMHEIGHT); - else - rb->lcd_bitmap_part(brickmania_menu_items, 0, - MENU_ITEMHEIGHT * BM_HELP, MENU_ITEMWIDTH, - MENU_ITEMXOFS, BMPYOFS_help, MENU_ITEMWIDTH, - MENU_ITEMHEIGHT); - - if (cur==3) - rb->lcd_bitmap_part(brickmania_menu_items, 0, - MENU_ITEMHEIGHT * BM_SEL_QUIT, MENU_ITEMWIDTH, - MENU_ITEMXOFS, BMPYOFS_quit, MENU_ITEMWIDTH, - MENU_ITEMHEIGHT); - else - rb->lcd_bitmap_part(brickmania_menu_items, 0, - MENU_ITEMHEIGHT * BM_QUIT, MENU_ITEMWIDTH, - MENU_ITEMXOFS, BMPYOFS_quit, MENU_ITEMWIDTH, - MENU_ITEMHEIGHT); -#endif - } - rb->lcd_set_drawmode(DRMODE_FG); - /* high score */ #ifdef HAVE_LCD_COLOR - rb->lcd_set_background(LCD_RGBPACK(0,0,140)); - rb->lcd_set_foreground(LCD_WHITE); + rb->lcd_set_background(LCD_BLACK); + rb->lcd_set_foreground(LCD_WHITE); #endif - rb->lcd_putsxy(HIGHSCORE_XPOS, HIGHSCORE_YPOS, "High Score"); - rb->snprintf(str, sizeof(str), "%d", highscore); - rb->lcd_getstringsize("High Score", &sw, NULL); - rb->lcd_getstringsize(str, &w, NULL); - rb->lcd_putsxy(HIGHSCORE_XPOS+sw/2-w/2, HIGHSCORE_YPOS+9, str); - rb->lcd_set_drawmode(DRMODE_SOLID); + rb->button_clear_queue(); + rb->lcd_clear_display(); - rb->lcd_update(); + rb->lcd_setfont(FONT_UI); + rb->lcd_getstringsize("High Scores", &w, &h); + /* check wether it fits on screen */ + if ((4*h + h*(NUM_SCORES-1) + MARGIN) > LCD_HEIGHT) { + rb->lcd_setfont(FONT_SYSFIXED); + rb->lcd_getstringsize("High Scores", &w, &h); + } + rb->lcd_putsxy(LCD_WIDTH/2-w/2, MARGIN, "High Scores"); + rb->lcd_putsxy(LCD_WIDTH/4-w/4,2*h, "Score"); + rb->lcd_putsxy(LCD_WIDTH*3/4-w/4,2*h, "Level"); - button = rb->button_get(true); -#ifdef HAVE_TOUCHSCREEN - if(button & BUTTON_TOUCHSCREEN) - { - unsigned int result = touchscreen_map(&main_menu, rb->button_get_data() >> 16, rb->button_get_data() & 0xffff); - if(result != (unsigned)-1 && button & BUTTON_REL) - { - if(cur == (signed)result) - button = SELECT; - cur = result; - } + for (i = 0; ilcd_set_foreground(LCD_RGBPACK(245,0,0)); } #endif - switch(button) { - case UP: - case UP | BUTTON_REPEAT: - if (cur==0) - cur = MENU_LENGTH-1; - else - cur--; - if (when==0 && cur==1) { - cur = 0; - } - break; + rb->snprintf (str, sizeof (str), "%d)", i+1); + rb->lcd_putsxy (MARGIN,3*h + h*i, str); + rb->snprintf (str, sizeof (str), "%d", highest[i].score); + rb->lcd_putsxy (LCD_WIDTH/4-w/4,3*h + h*i, str); + rb->snprintf (str, sizeof (str), "%d", highest[i].level); + rb->lcd_putsxy (LCD_WIDTH*3/4-w/4,3*h + h*i, str); + if(i == position) { +#ifdef HAVE_LCD_COLOR + rb->lcd_set_foreground(LCD_WHITE); +#else + rb->lcd_hline(MARGIN, LCD_WIDTH-MARGIN, 3*h + h*(i+1)); +#endif + } + } + rb->lcd_update(); + rb->button_get(true); + rb->lcd_setfont(FONT_SYSFIXED); +} - case DOWN: - case DOWN | BUTTON_REPEAT: - if (cur==MENU_LENGTH-1) - cur = 0; - else - cur++; - if (when==0 && cur==1) { - cur=2; - } +/* submenu to choose difficulty */ +static int brickmania_choose_difficult(void) +{ + rb->button_clear_queue(); + int choice = difficulty; + MENUITEM_STRINGLIST (main_menu, "Brickmania Difficulty", NULL, + "Easy", + "Hard"); + choice = rb->do_menu(&main_menu, &choice, NULL, false); + switch (choice) { + case 0: + difficulty = EASY; break; - - case RIGHT: - case SELECT: - if (cur==0) { - score=0; - vscore=0; - return 0; - } else if (cur==1 && when==1) { - return 1; - } else if (cur==2) { - return 2; - } else if (cur==3) { - return 3; - } + case 1: + difficulty = HARD; break; -#ifdef RC_QUIT - case RC_QUIT: -#endif - case QUIT: - return 3; - break; - default: - if(rb->default_event_handler(button) == SYS_USB_CONNECTED) - return 3; break; } - - rb->yield(); - } + rb->button_clear_queue(); + return 0; } -int help(int when) +static int brickmania_help(void) { - int w,h; - int button; - int xoffset=0; - int yoffset=0; - /* set the maximum x and y in the helpscreen - dont forget to update, if you change text */ - int maxY=180; - int maxX=215; - - while(true) { -#ifdef HAVE_LCD_COLOR - rb->lcd_set_background(LCD_BLACK); - rb->lcd_clear_display(); - rb->lcd_set_background(LCD_BLACK); - rb->lcd_set_foreground(LCD_WHITE); -#else - rb->lcd_clear_display(); -#endif - - rb->lcd_getstringsize("BrickMania", &w, &h); - rb->lcd_putsxy(LCD_WIDTH/2-w/2+xoffset, 1+yoffset, "BrickMania"); - -#ifdef HAVE_LCD_COLOR - rb->lcd_set_foreground(LCD_RGBPACK(245,0,0)); - rb->lcd_putsxy(1+xoffset, 1*(h+2)+yoffset,"Aim"); - rb->lcd_set_foreground(LCD_WHITE); -#else - rb->lcd_putsxy(1+xoffset, 1*(h+2)+yoffset,"Aim"); -#endif - rb->lcd_putsxy(1+xoffset, 2*(h+2)+yoffset, - "destroy all the bricks by bouncing"); - rb->lcd_putsxy(1+xoffset, 3*(h+2)+yoffset, - "the ball of them using the paddle."); -#ifdef HAVE_LCD_COLOR - rb->lcd_set_foreground(LCD_RGBPACK(245,0,0)); - rb->lcd_putsxy(1+xoffset, 5*(h+2)+yoffset,"Controls"); - rb->lcd_set_foreground(LCD_WHITE); -#else - rb->lcd_putsxy(1+xoffset, 5*(h+2)+yoffset,"Controls"); -#endif - rb->lcd_putsxy(1+xoffset, 6*(h+2)+yoffset,"< & > Move the paddle"); + rb->lcd_setfont(FONT_UI); +#define WORDS (sizeof help_text / sizeof (char*)) + static char *help_text[] = { + "Brickmania", "", "Aim", "", + "Destroy", "all", "the", "bricks", "by", "bouncing", + "the", "ball", "of", "them", "using", "the", "paddle.", "", "", + "Controls", "", + "< & >", "Moves", "the", "paddle", "", #if CONFIG_KEYPAD == ONDIO_PAD - rb->lcd_putsxy(1+xoffset, 7*(h+2)+yoffset, - "MENU Releases the ball/Fire!"); + "MENU:", #elif (CONFIG_KEYPAD == RECORDER_PAD) || (CONFIG_KEYPAD == IAUDIO_M3_PAD) - rb->lcd_putsxy(1+xoffset, 7*(h+2)+yoffset, - "PLAY Releases the ball/Fire!"); + "PLAY:", #elif CONFIG_KEYPAD == IRIVER_H300_PAD - rb->lcd_putsxy(1+xoffset, 7*(h+2)+yoffset, - "NAVI Releases the ball/Fire!"); + "NAVI:", #else - rb->lcd_putsxy(1+xoffset, 7*(h+2)+yoffset, - "SELECT Releases the ball/Fire!"); + "SELECT:", #endif + "Releases", "the", "ball/Fire!", "", #if CONFIG_KEYPAD == IAUDIO_M3_PAD - rb->lcd_putsxy(1+xoffset, 8*(h+2)+yoffset, "REC Opens menu/Quit"); + "REC:", +#elif (CONFIG_KEYPAD == GIGABEAT_S_PAD) || \ + (CONFIG_KEYPAD == CREATIVEZVM_PAD) + "BACK:", +#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \ + (CONFIG_KEYPAD == IPOD_3G_PAD) || \ + (CONFIG_KEYPAD == IPOD_1G2G_PAD) || \ + (CONFIG_KEYPAD == SANSA_FUZE_PAD) + "MENU:", +#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ + (CONFIG_KEYPAD == IRIVER_H300_PAD) || \ + (CONFIG_KEYPAD == ONDIO_PAD) || \ + (CONFIG_KEYPAD == RECORDER_PAD) || \ + (CONFIG_KEYPAD == ARCHOS_AV300_PAD) + "STOP:", #else - rb->lcd_putsxy(1+xoffset, 8*(h+2)+yoffset, "STOP Opens menu/Quit"); + "POWER:", #endif -#ifdef HAVE_LCD_COLOR - rb->lcd_set_foreground(LCD_RGBPACK(245,0,0)); - rb->lcd_putsxy(1+xoffset, 10*(h+2)+yoffset, "Specials"); - rb->lcd_set_foreground(LCD_WHITE); -#else - rb->lcd_putsxy(1+xoffset, 10*(h+2)+yoffset, "Specials"); -#endif - rb->lcd_putsxy(1+xoffset, 11*(h+2)+yoffset, - "N Normal:returns paddle to normal"); - rb->lcd_putsxy(1+xoffset, 12*(h+2)+yoffset, "D DIE!:loses a life"); - rb->lcd_putsxy(1+xoffset, 13*(h+2)+yoffset, - "L Life:gains a life/power up"); - rb->lcd_putsxy(1+xoffset, 14*(h+2)+yoffset, - "F Fire:allows you to shoot bricks"); - rb->lcd_putsxy(1+xoffset, 15*(h+2)+yoffset, - "G Glue:ball sticks to paddle"); - rb->lcd_putsxy(1+xoffset, 16*(h+2)+yoffset, - "B Ball:generates another ball"); - rb->lcd_putsxy(1+xoffset, 17*(h+2)+yoffset, - "FL Flip:flips left / right movement"); - rb->lcd_update(); + "Returns", "to", "menu", "", "", + "Specials", "", + "N", "Normal:", "returns", "paddle", "to", "normal", "", + "D", "DIE!:", "loses", "a", "life", "", + "L", "Life:", "gains", "a", "life/power", "up", "", + "F", "Fire:", "allows", "you", "to", "shoot", "bricks", "", + "G", "Glue:", "ball", "sticks", "to", "paddle", "", + "B", "Ball:", "generates", "another", "ball", "", + "FL", "Flip:", "flips", "left / right", "movement", "", + }; + static struct style_text formation[]={ + { 0, TEXT_CENTER|TEXT_UNDERLINE }, + { 2, C_RED }, + { 19, C_RED }, + { 37, C_RED }, + { 39, C_BLUE }, + { 46, C_RED }, + { 52, C_GREEN }, + { 59, C_ORANGE }, + { 67, C_GREEN }, + { 74, C_YELLOW }, + { 80, C_RED }, + }; + + if (display_text(WORDS, help_text, formation, NULL)==PLUGIN_USB_CONNECTED) + return PLUGIN_USB_CONNECTED; + int button; + do { + button = rb->button_get(true); + if (button == SYS_USB_CONNECTED) { + return PLUGIN_USB_CONNECTED; + } + } while( ( button == BUTTON_NONE ) + || ( button & (BUTTON_REL|BUTTON_REPEAT) ) ); + rb->lcd_setfont(FONT_SYSFIXED); + return 0; +} - button=rb->button_get(true); - switch (button) { -#ifdef RC_QUIT - case RC_QUIT: -#endif -#ifdef HAVE_TOUCHSCREEN - case BUTTON_TOUCHSCREEN: -#endif - case QUIT: - switch (game_menu(when)) { - case 0: - cur_level=0; - life=2; - int_game(1); - break; - case 1: - con_game=1; - break; - case 2: - if (help(when)==1) - return 1; - break; - case 3: - return 1; - break; +static bool _ingame; +static int brickmania_menu_cb(int action, const struct menu_item_ex *this_item) +{ + if(action == ACTION_REQUEST_MENUITEM + && !_ingame && ((intptr_t)this_item)==0) + return ACTION_EXIT_MENUITEM; + return action; +} + +static int brickmania_game_menu(bool ingame) +{ + rb->button_clear_queue(); + int choice = 0; + + _ingame = ingame; + + MENUITEM_STRINGLIST (main_menu, "Brickmania Menu", brickmania_menu_cb, + "Resume Game", + "Start New Game", + "Difficulty", + "Help", + "High Score", + "Playback Control", + "Quit"); + + while (true) { + switch (rb->do_menu(&main_menu, &choice, NULL, false)) { + case 0: + if (saved_game) { + saved_game = false; + vscore=l_score-1; + score=l_score; + brickmania_int_game(1); + } else { + int i; + for(i=0;i LCD_WIDTH) - xoffset-=2; + case 4: + brickmania_show_highscores(NUM_SCORES); break; - case UP: - case UP | BUTTON_REPEAT: - if(yoffset <0) - yoffset+=2; + case 5: + playback_control(NULL); break; - case DOWN: - case DOWN | BUTTON_REPEAT: - if(yoffset+maxY > LCD_HEIGHT) - yoffset-=2; - break; - + case 6: + if (level>0 && ingame) { + saved_game=true; + } + else { + saved_game=false; + } + configfile_save(CONFIG_FILE_NAME,config,5,0); + return 1; + case MENU_ATTACHED_USB: + return 1; default: - if(rb->default_event_handler(button) == SYS_USB_CONNECTED) - return 1; break; } - - rb->yield(); } - return 0; } -int pad_check(int ballxc, int mode, int pon ,int ballnum) +static int brickmania_pad_check(int ballxc, int mode, int pon ,int ballnum) { /* pon: positive(1) or negative(0) */ @@ -1298,7 +1109,7 @@ } } -int fire_space(void) +static int brickmania_fire_space(void) { int t; for(t=0;t<=30;t++) @@ -1308,32 +1119,27 @@ return 0; } -int game_loop(void) +static int brickmania_game_loop(void) { int j,i,k,bricky,brickx; char s[30]; int sec_count=0,num_count=10; int end; + int position; + + configfile_load(CONFIG_FILE_NAME,config,5,0); rb->srand( *rb->current_tick ); - - configfile_load(HIGH_SCORE,config,1,0); - - switch(game_menu(0)) { - case 0: - cur_level = 0; - life = 2; - int_game(1); - break; - case 1: - con_game = 1; - break; - case 2: - if (help(0) == 1) return 1; - break; - case 3: + if (saved_game) { + + if (brickmania_game_menu(true)!=0) { + return 1; + } + } + else { + if (brickmania_game_menu(false)!=0) { return 1; - break; + } } while(true) { @@ -1379,11 +1185,11 @@ #endif #if (LCD_WIDTH == 112) && (LCD_HEIGHT == 64) - rb->snprintf(s, sizeof(s), "L%d", cur_level+1); + rb->snprintf(s, sizeof(s), "L%d", level+1); rb->lcd_getstringsize(s, &sw, NULL); rb->lcd_putsxy(LCD_WIDTH-sw, 0, s); #else - rb->snprintf(s, sizeof(s), "Level %d", cur_level+1); + rb->snprintf(s, sizeof(s), "Level %d", level+1); rb->lcd_getstringsize(s, &sw, NULL); rb->lcd_putsxy(LCD_WIDTH-sw-2, 2, s); #endif @@ -1463,8 +1269,8 @@ case 1: life--; if (life>=0) { - int_game(0); - sleep(2); + brickmania_int_game(0); + brickmania_sleep(2); } break; case 2: @@ -1747,8 +1553,8 @@ } else { life--; if (life>=0) { - int_game(0); - sleep(2); + brickmania_int_game(0); + brickmania_sleep(2); } } } @@ -1775,7 +1581,7 @@ ball[k].y = -2; if (ball[k].pos_x != 0 && ball[k].pos_x+BALL!=LCD_WIDTH) - ball[k].x = pad_check(6,0,ball[k].pos_x+2<= + ball[k].x = brickmania_pad_check(6,0,ball[k].pos_x+2<= pad_pos_x+(PAD_WIDTH/2)? 0:1,k); @@ -1792,7 +1598,7 @@ ball[k].y = -3; if (ball[k].pos_x != 0 && ball[k].pos_x+BALL!=LCD_WIDTH) - ball[k].x = pad_check(4,0,ball[k].pos_x+2<= + ball[k].x = brickmania_pad_check(4,0,ball[k].pos_x+2<= pad_pos_x+(PAD_WIDTH/2)? 0:1,k); @@ -1809,7 +1615,7 @@ ball[k].y = -4; if (ball[k].pos_x != 0 && ball[k].pos_x+BALL!=LCD_WIDTH) - ball[k].x = pad_check(3,0,ball[k].pos_x+2<= + ball[k].x = brickmania_pad_check(3,0,ball[k].pos_x+2<= pad_pos_x+(PAD_WIDTH/2)? 0:1,k); @@ -1825,7 +1631,7 @@ ball[k].y = -4; if (ball[k].pos_x != 0 && ball[k].pos_x+BALL!=LCD_WIDTH) - ball[k].x = pad_check(2,1,0,k); + ball[k].x = brickmania_pad_check(2,1,0,k); } else { @@ -1854,11 +1660,13 @@ rb->lcd_update(); if (brick_on_board < 0) { - if (cur_level+1lcd_getstringsize("Congratulations!", &sw, NULL); @@ -1875,32 +1683,24 @@ "You have finished the game!"); #endif vscore=score; + rb->lcd_clear_display(); rb->lcd_update(); - if (score>highscore) { - sleep(2); - highscore=score; - rb->splash(HZ*2, "New High Score"); + rb->sleep(2); + if (highscore_would_update(score, highest, NUM_SCORES)) { + position=highscore_update(score, level+1, "", + highest,NUM_SCORES); + if (position == 0) { + rb->splash(HZ*2, "New High Score"); + } else { + rb->splash(HZ*2, "Top Five"); + } + brickmania_show_highscores(position); + } else { + brickmania_sleep(3); } - else { - sleep(3); + if (brickmania_game_menu(false)!=0) { + return 0; } - - switch(game_menu(0)) { - case 0: - life=2; - cur_level=0; - int_game(1); - break; - case 1: - con_game=1; - break; - case 2: - if (help(0)==1) return 1; - break; - case 3: - return 1; - break; - } } } @@ -2011,10 +1811,10 @@ } } else if (pad_type==2 && con_game!=1) { int tfire; - tfire=fire_space(); + tfire=brickmania_fire_space(); fire[tfire].top=PAD_POS_Y-7; fire[tfire].left=pad_pos_x+1; - tfire=fire_space(); + tfire=brickmania_fire_space(); fire[tfire].top=PAD_POS_Y-7; fire[tfire].left=pad_pos_x+PAD_WIDTH-1; } else if (con_game==1 && start_game!=1) { @@ -2029,24 +1829,8 @@ case RC_QUIT: #endif case QUIT: - switch(game_menu(1)) { - case 0: - life=2; - cur_level=0; - int_game(1); - break; - case 1: - for(k=0;klcd_update(); - if (score>highscore) { - sleep(2); - highscore=score; - rb->splash(HZ*2, "New High Score"); + brickmania_sleep(2); + if (highscore_would_update(score, highest, NUM_SCORES)) { + position=highscore_update(score, level+1, "", + highest,NUM_SCORES); + if (position == 0) { + rb->splash(HZ*2, "New High Score"); + } else { + rb->splash(HZ*2, "Top Five"); + } + brickmania_show_highscores(position); } else { - sleep(3); + brickmania_sleep(3); } for(k=0;k *rb->current_tick) @@ -2120,6 +1896,8 @@ enum plugin_status plugin_start(const void* parameter) { (void)parameter; +#ifdef HAVE_LCD_BITMAP + highscore_load(HIGH_SCORE,highest,NUM_SCORES); rb->lcd_setfont(FONT_SYSFIXED); #if LCD_DEPTH > 1 @@ -2129,14 +1907,13 @@ backlight_force_on(); /* backlight control in lib/helper.c */ /* now go ahead and have fun! */ - while (game_loop()!=1); + brickmania_game_loop(); - configfile_save(HIGH_SCORE,config,1,0); - + highscore_save(HIGH_SCORE,highest,NUM_SCORES); /* Restore user's original backlight setting */ rb->lcd_setfont(FONT_UI); /* Turn on backlight timeout (revert to settings) */ backlight_use_settings(); /* backlight control in lib/helper.c */ - +#endif return PLUGIN_OK; } Index: apps/plugins/jewels.c =================================================================== --- apps/plugins/jewels.c (Revision 21733) +++ apps/plugins/jewels.c (Arbeitskopie) @@ -22,10 +22,10 @@ ****************************************************************************/ #include "plugin.h" +#include "lib/display_text.h" +#include "lib/highscore.h" #include "lib/playback_control.h" -#ifdef HAVE_LCD_BITMAP - PLUGIN_HEADER /* button definitions */ @@ -59,11 +59,10 @@ #define JEWELS_LEFT BUTTON_LEFT #define JEWELS_RIGHT BUTTON_RIGHT #define JEWELS_SELECT BUTTON_SELECT -#define JEWELS_MENU BUTTON_MODE #define JEWELS_CANCEL BUTTON_OFF #define JEWELS_RC_CANCEL BUTTON_RC_STOP -#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \ +#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \ (CONFIG_KEYPAD == IPOD_1G2G_PAD) #define JEWELS_SCROLLWHEEL #define JEWELS_UP BUTTON_MENU @@ -73,7 +72,16 @@ #define JEWELS_PREV BUTTON_SCROLL_BACK #define JEWELS_NEXT BUTTON_SCROLL_FWD #define JEWELS_SELECT BUTTON_SELECT +#define JEWELS_CANCEL (BUTTON_SELECT | BUTTON_MENU) +#elif (CONFIG_KEYPAD == IPOD_3G_PAD) +#define JEWELS_LEFT BUTTON_LEFT +#define JEWELS_RIGHT BUTTON_RIGHT +#define JEWELS_UP BUTTON_SCROLL_BACK +#define JEWELS_DOWN BUTTON_SCROLL_FWD +#define JEWELS_SELECT BUTTON_SELECT +#define JEWELS_CANCEL BUTTON_MENU + #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD #define JEWELS_UP BUTTON_UP #define JEWELS_DOWN BUTTON_DOWN @@ -144,7 +152,6 @@ #define JEWELS_LEFT BUTTON_LEFT #define JEWELS_RIGHT BUTTON_RIGHT #define JEWELS_SELECT BUTTON_SELECT -#define JEWELS_MENU BUTTON_MENU #define JEWELS_CANCEL BUTTON_BACK #elif CONFIG_KEYPAD == MROBE100_PAD @@ -162,7 +169,6 @@ #define JEWELS_RIGHT BUTTON_RC_FF #define JEWELS_SELECT BUTTON_RC_PLAY #define JEWELS_CANCEL BUTTON_RC_REC - #define JEWELS_RC_CANCEL BUTTON_REC #elif CONFIG_KEYPAD == COWOND2_PAD @@ -192,7 +198,8 @@ #define JEWELS_SELECT BUTTON_SELECT #define JEWELS_CANCEL BUTTON_POWER -#elif CONFIG_KEYPAD == ONDAVX747_PAD || CONFIG_KEYPAD == MROBE500_PAD +#elif CONFIG_KEYPAD == ONDAVX747_PAD || \ +CONFIG_KEYPAD == MROBE500_PAD #define JEWELS_CANCEL BUTTON_POWER #else @@ -235,79 +242,68 @@ #define TILE_WIDTH 22 #define TILE_HEIGHT 22 #define YOFS 0 -#define NUM_SCORES 10 +#define NUM_SCORES 5 /* use 16x16 tiles (iPod Nano) */ #elif (LCD_HEIGHT == 132) && (LCD_WIDTH == 176) #define TILE_WIDTH 16 #define TILE_HEIGHT 16 #define YOFS 4 -#define NUM_SCORES 10 +#define NUM_SCORES 5 /* use 16x16 tiles (H100, iAudio X5, iPod 3G, iPod 4G grayscale) */ #elif (LCD_HEIGHT == 128) && (LCD_WIDTH == 160) #define TILE_WIDTH 16 #define TILE_HEIGHT 16 #define YOFS 0 -#define NUM_SCORES 10 +#define NUM_SCORES 5 /* use 14x14 tiles (H10 5/6 GB) */ #elif (LCD_HEIGHT == 128) && (LCD_WIDTH == 128) #define TILE_WIDTH 14 #define TILE_HEIGHT 14 #define YOFS 0 -#define NUM_SCORES 10 +#define NUM_SCORES 5 /* use 13x13 tiles (iPod Mini) */ #elif (LCD_HEIGHT == 110) && (LCD_WIDTH == 138) #define TILE_WIDTH 13 #define TILE_HEIGHT 13 #define YOFS 6 -#define NUM_SCORES 10 +#define NUM_SCORES 5 /* use 12x12 tiles (iAudio M3) */ #elif (LCD_HEIGHT == 96) && (LCD_WIDTH == 128) #define TILE_WIDTH 12 #define TILE_HEIGHT 12 #define YOFS 0 -#define NUM_SCORES 9 +#define NUM_SCORES 5 /* use 10x10 tiles (Sansa c200) */ #elif (LCD_HEIGHT == 80) && (LCD_WIDTH == 132) #define TILE_WIDTH 10 #define TILE_HEIGHT 10 #define YOFS 0 -#define NUM_SCORES 8 +#define NUM_SCORES 5 /* use 10x8 tiles (iFP 700) */ #elif (LCD_HEIGHT == 64) && (LCD_WIDTH == 128) #define TILE_WIDTH 10 #define TILE_HEIGHT 8 #define YOFS 0 -#define NUM_SCORES 8 +#define NUM_SCORES 5 /* use 10x8 tiles (Recorder, Ondio) */ #elif (LCD_HEIGHT == 64) && (LCD_WIDTH == 112) #define TILE_WIDTH 10 #define TILE_HEIGHT 8 #define YOFS 0 -#define NUM_SCORES 8 +#define NUM_SCORES 5 #else #error JEWELS: Unsupported LCD #endif -/* save files */ -#define SCORE_FILE PLUGIN_GAMES_DIR "/jewels.score" -#define SAVE_FILE PLUGIN_GAMES_DIR "/jewels.save" - -/* final game return status */ -#define BJ_QUIT_FROM_GAME 4 -#define BJ_END 3 -#define BJ_USB 2 -#define BJ_QUIT 1 -#define BJ_LOSE 0 - /* swap directions */ #define SWAP_UP 0 #define SWAP_RIGHT 1 @@ -324,6 +320,9 @@ /* animation frame rate */ #define MAX_FPS 20 +/* text margin */ +#define MARGIN 5 + /* Game types */ enum game_type { GAME_TYPE_NORMAL, @@ -356,23 +355,21 @@ * score is the current level score * segments is the number of cleared segments in the current run * level is the current level + * tmp_type is the select type in the menu * 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 + * playgame is true, if a game is started */ struct game_context { unsigned int score; unsigned int segments; unsigned int level; unsigned int type; - unsigned int highscores[NUM_SCORES]; - bool resume; - bool dirty; + unsigned int tmp_type; struct tile playboard[BJ_HEIGHT][BJ_WIDTH]; unsigned int num_jewels; + bool playgame; }; #define MAX_NUM_JEWELS 7 @@ -428,32 +425,17 @@ {4, 7, PUZZLE_TILE_LEFT|PUZZLE_TILE_UP} } }, }; -/***************************************************************************** -* jewels_init() initializes jewels data structures. -******************************************************************************/ -static void jewels_init(struct game_context* bj) { - /* seed the rand generator */ - rb->srand(*rb->current_tick); +#define SAVE_FILE PLUGIN_GAMES_DIR "/jewels.save" - /* check for resumed game */ - if(bj->resume) { - bj->resume = false; - return; - } +#define HIGH_SCORE PLUGIN_GAMES_DIR "/jewels.score" +struct highscore highest[NUM_SCORES]; - /* reset scoring */ - bj->level = 1; - bj->score = 0; - bj->segments = 0; - /* clear playing board */ - rb->memset(bj->playboard, 0, sizeof(bj->playboard)); -} - /***************************************************************************** * jewels_setcolors() set the foreground and background colors. ******************************************************************************/ -static inline void jewels_setcolors(void) { +static inline void jewels_setcolors(void) +{ #ifdef HAVE_LCD_COLOR rb->lcd_set_background(LCD_RGBPACK(49, 26, 26)); rb->lcd_set_foreground(LCD_RGBPACK(210, 181, 181)); @@ -461,16 +443,71 @@ } /***************************************************************************** +* jewels_loadgame() loads the saved game and returns load success. +******************************************************************************/ +static bool jewels_loadgame(struct game_context* bj) +{ + int fd; + bool loaded = false; + + /* open game file */ + fd = rb->open(SAVE_FILE, O_RDONLY); + if(fd < 0) return loaded; + + /* read in saved game */ + while(true) { + if(rb->read(fd, &bj->tmp_type, sizeof(bj->tmp_type)) <= 0) break; + if(rb->read(fd, &bj->type, sizeof(bj->type)) <= 0) break; + if(rb->read(fd, &bj->score, sizeof(bj->score)) <= 0) break; + if(rb->read(fd, &bj->level, sizeof(bj->level)) <= 0) break; + if(rb->read(fd, &bj->segments, sizeof(bj->segments)) <= 0) break; + if(rb->read(fd, &bj->num_jewels, sizeof(bj->num_jewels)) <= 0) break; + if(rb->read(fd, bj->playboard, sizeof(bj->playboard)) <= 0) break; + loaded = true; + break; + } + + rb->close(fd); + + return loaded; +} + +/***************************************************************************** +* jewels_savegame() saves the current game state. +******************************************************************************/ +static void jewels_savegame(struct game_context* bj) +{ + int fd; + /* write out the game state to the save file */ + fd = rb->open(SAVE_FILE, O_WRONLY|O_CREAT); + rb->write(fd, &bj->tmp_type, sizeof(bj->tmp_type)); + rb->write(fd, &bj->type, sizeof(bj->type)); + rb->write(fd, &bj->score, sizeof(bj->score)); + rb->write(fd, &bj->level, sizeof(bj->level)); + rb->write(fd, &bj->segments, sizeof(bj->segments)); + rb->write(fd, &bj->num_jewels, sizeof(bj->num_jewels)); + rb->write(fd, bj->playboard, sizeof(bj->playboard)); + rb->close(fd); +} + +/***************************************************************************** * jewels_drawboard() redraws the entire game board. ******************************************************************************/ -static void jewels_drawboard(struct game_context* bj) { +static void jewels_drawboard(struct game_context* bj) +{ int i, j; int w, h; - unsigned int tempscore; + float progress; char *title = "Level"; char str[10]; - tempscore = (bj->score>LEVEL_PTS ? LEVEL_PTS : bj->score); +if (bj->type == GAME_TYPE_NORMAL) { + progress = (bj->score>LEVEL_PTS ? LEVEL_PTS : bj->score); + progress = progress/LEVEL_PTS; +} else if (bj->type == GAME_TYPE_PUZZLE) { + progress = (bj->level>NUM_PUZZLE_LEVELS ? NUM_PUZZLE_LEVELS : bj->level); + progress = progress/NUM_PUZZLE_LEVELS; +} /* clear screen */ rb->lcd_clear_display(); @@ -500,45 +537,47 @@ /* draw separator lines */ jewels_setcolors(); rb->lcd_vline(BJ_WIDTH*TILE_WIDTH, 0, LCD_HEIGHT-1); + rb->lcd_hline(BJ_WIDTH*TILE_WIDTH, LCD_WIDTH-1, 18); rb->lcd_hline(BJ_WIDTH*TILE_WIDTH, LCD_WIDTH-1, LCD_HEIGHT-10); - + /* draw progress bar */ #ifdef HAVE_LCD_COLOR rb->lcd_set_foreground(LCD_RGBPACK(104, 63, 63)); #endif rb->lcd_fillrect(BJ_WIDTH*TILE_WIDTH+(LCD_WIDTH-BJ_WIDTH*TILE_WIDTH)/4, (LCD_HEIGHT-10)-(((LCD_HEIGHT-10)-18)* - tempscore/LEVEL_PTS), + progress), (LCD_WIDTH-BJ_WIDTH*TILE_WIDTH)/2, - ((LCD_HEIGHT-10)-18)*tempscore/LEVEL_PTS); + ((LCD_HEIGHT-10)-18)*progress); #ifdef HAVE_LCD_COLOR rb->lcd_set_foreground(LCD_RGBPACK(83, 44, 44)); rb->lcd_drawrect(BJ_WIDTH*TILE_WIDTH+(LCD_WIDTH-BJ_WIDTH*TILE_WIDTH)/4+1, (LCD_HEIGHT-10)-(((LCD_HEIGHT-10)-18)* - tempscore/LEVEL_PTS)+1, + progress)+1, (LCD_WIDTH-BJ_WIDTH*TILE_WIDTH)/2-2, - ((LCD_HEIGHT-10)-18)*tempscore/LEVEL_PTS-1); + ((LCD_HEIGHT-10)-18)*progress-1); jewels_setcolors(); rb->lcd_drawrect(BJ_WIDTH*TILE_WIDTH+(LCD_WIDTH-BJ_WIDTH*TILE_WIDTH)/4, - (LCD_HEIGHT-10)-(((LCD_HEIGHT-10)-18)* - tempscore/LEVEL_PTS), + (LCD_HEIGHT-10)-(((LCD_HEIGHT-10)-18)*progress), (LCD_WIDTH-BJ_WIDTH*TILE_WIDTH)/2, - ((LCD_HEIGHT-10)-18)*tempscore/LEVEL_PTS+1); + ((LCD_HEIGHT-10)-18)*progress+1); #endif + if (bj->type == GAME_TYPE_NORMAL) { + rb->snprintf(str, 6, "%d", (bj->level-1)*LEVEL_PTS+bj->score); + rb->lcd_getstringsize(str, &w, &h); + rb->lcd_putsxy(LCD_WIDTH-(LCD_WIDTH-BJ_WIDTH*TILE_WIDTH)/2-w/2, + LCD_HEIGHT-8, str); + } + /* print text */ rb->lcd_getstringsize(title, &w, &h); rb->lcd_putsxy(LCD_WIDTH-(LCD_WIDTH-BJ_WIDTH*TILE_WIDTH)/2-w/2, 1, title); - rb->snprintf(str, 4, "%d", bj->level); rb->lcd_getstringsize(str, &w, &h); rb->lcd_putsxy(LCD_WIDTH-(LCD_WIDTH-BJ_WIDTH*TILE_WIDTH)/2-w/2, 10, str); - rb->snprintf(str, 6, "%d", (bj->level-1)*LEVEL_PTS+bj->score); - rb->lcd_getstringsize(str, &w, &h); - rb->lcd_putsxy(LCD_WIDTH-(LCD_WIDTH-BJ_WIDTH*TILE_WIDTH)/2-w/2, - LCD_HEIGHT-8, str); #elif LCD_WIDTH < LCD_HEIGHT /* vertical layout */ @@ -547,35 +586,38 @@ rb->lcd_hline(0, LCD_WIDTH-1, 8*TILE_HEIGHT+YOFS); rb->lcd_hline(0, LCD_WIDTH-1, LCD_HEIGHT-14); rb->lcd_vline(LCD_WIDTH/2, LCD_HEIGHT-14, LCD_HEIGHT-1); - + /* draw progress bar */ #ifdef HAVE_LCD_COLOR rb->lcd_set_foreground(LCD_RGBPACK(104, 63, 63)); #endif rb->lcd_fillrect(0, (8*TILE_HEIGHT+YOFS) - +(LCD_HEIGHT-14-(8*TILE_HEIGHT+YOFS))/4, - LCD_WIDTH*tempscore/LEVEL_PTS, + +(LCD_HEIGHT-14-(8*TILE_HEIGHT+YOFS))/4, + LCD_WIDTH*progress, (LCD_HEIGHT-14-(8*TILE_HEIGHT+YOFS))/2); #ifdef HAVE_LCD_COLOR rb->lcd_set_foreground(LCD_RGBPACK(83, 44, 44)); rb->lcd_drawrect(1, (8*TILE_HEIGHT+YOFS) - +(LCD_HEIGHT-14-(8*TILE_HEIGHT+YOFS))/4+1, - LCD_WIDTH*tempscore/LEVEL_PTS-1, + +(LCD_HEIGHT-14-(8*TILE_HEIGHT+YOFS))/4+1, + LCD_WIDTH*progress-1, (LCD_HEIGHT-14-(8*TILE_HEIGHT+YOFS))/2-2); jewels_setcolors(); rb->lcd_drawrect(0, (8*TILE_HEIGHT+YOFS) - +(LCD_HEIGHT-14-(8*TILE_HEIGHT+YOFS))/4, - LCD_WIDTH*tempscore/LEVEL_PTS+1, + +(LCD_HEIGHT-14-(8*TILE_HEIGHT+YOFS))/4, + LCD_WIDTH*progress+1, (LCD_HEIGHT-14-(8*TILE_HEIGHT+YOFS))/2); #endif - + + if (bj->type == GAME_TYPE_NORMAL) { + rb->snprintf(str, 6, "%d", (bj->level-1)*LEVEL_PTS+bj->score); + rb->lcd_getstringsize(str, &w, &h); + rb->lcd_putsxy((LCD_WIDTH-2)-w, LCD_HEIGHT-10, str); + } + /* print text */ rb->snprintf(str, 10, "%s %d", title, bj->level); rb->lcd_putsxy(1, LCD_HEIGHT-10, str); - rb->snprintf(str, 6, "%d", (bj->level-1)*LEVEL_PTS+bj->score); - rb->lcd_getstringsize(str, &w, &h); - rb->lcd_putsxy((LCD_WIDTH-2)-w, LCD_HEIGHT-10, str); #else /* square layout */ @@ -590,34 +632,35 @@ rb->lcd_set_foreground(LCD_RGBPACK(104, 63, 63)); #endif rb->lcd_fillrect(BJ_WIDTH*TILE_WIDTH+(LCD_WIDTH-BJ_WIDTH*TILE_WIDTH)/4, - (8*TILE_HEIGHT+YOFS)-(8*TILE_HEIGHT+YOFS) - *tempscore/LEVEL_PTS, + (8*TILE_HEIGHT+YOFS)-(8*TILE_HEIGHT+YOFS)*progress, (LCD_WIDTH-BJ_WIDTH*TILE_WIDTH)/2, - (8*TILE_HEIGHT+YOFS)*tempscore/LEVEL_PTS); + (8*TILE_HEIGHT+YOFS)*progress); #ifdef HAVE_LCD_COLOR rb->lcd_set_foreground(LCD_RGBPACK(83, 44, 44)); rb->lcd_drawrect(BJ_WIDTH*TILE_WIDTH+(LCD_WIDTH-BJ_WIDTH*TILE_WIDTH)/4+1, (8*TILE_HEIGHT+YOFS)-(8*TILE_HEIGHT+YOFS) - *tempscore/LEVEL_PTS+1, + *progress+1, (LCD_WIDTH-BJ_WIDTH*TILE_WIDTH)/2-2, - (8*TILE_HEIGHT+YOFS)*tempscore/LEVEL_PTS-1); + (8*TILE_HEIGHT+YOFS)*progress-1); jewels_setcolors(); rb->lcd_drawrect(BJ_WIDTH*TILE_WIDTH+(LCD_WIDTH-BJ_WIDTH*TILE_WIDTH)/4, (8*TILE_HEIGHT+YOFS)-(8*TILE_HEIGHT+YOFS) - *tempscore/LEVEL_PTS, + *progress, (LCD_WIDTH-BJ_WIDTH*TILE_WIDTH)/2, - (8*TILE_HEIGHT+YOFS)*tempscore/LEVEL_PTS+1); + (8*TILE_HEIGHT+YOFS)*progress+1); #endif + + if (bj->type == GAME_TYPE_NORMAL) { + rb->snprintf(str, 6, "%d", (bj->level-1)*LEVEL_PTS+bj->score); + rb->lcd_getstringsize(str, &w, &h); + rb->lcd_putsxy((LCD_WIDTH-2)-w, + LCD_HEIGHT-(LCD_HEIGHT-(8*TILE_HEIGHT+YOFS))/2-3, str); + } /* print text */ rb->snprintf(str, 10, "%s %d", title, bj->level); rb->lcd_putsxy(1, LCD_HEIGHT-(LCD_HEIGHT-(8*TILE_HEIGHT+YOFS))/2-3, str); - rb->snprintf(str, 6, "%d", (bj->level-1)*LEVEL_PTS+bj->score); - rb->lcd_getstringsize(str, &w, &h); - rb->lcd_putsxy((LCD_WIDTH-2)-w, - LCD_HEIGHT-(LCD_HEIGHT-(8*TILE_HEIGHT+YOFS))/2-3, str); - #endif /* layout */ rb->lcd_update(); @@ -627,7 +670,8 @@ * jewels_putjewels() makes the jewels fall to fill empty spots and adds * new random jewels at the empty spots at the top of each row. ******************************************************************************/ -static void jewels_putjewels(struct game_context* bj){ +static void jewels_putjewels(struct game_context* bj) +{ int i, j, k; bool mark, done; long lasttick, currenttick; @@ -749,7 +793,7 @@ /***************************************************************************** * jewels_clearjewels() finds all the connected rows and columns and -* calculates and returns the points earned. +* calculates and returns the points earned. ******************************************************************************/ static unsigned int jewels_clearjewels(struct game_context* bj) { int i, j; @@ -846,14 +890,15 @@ * jewels_swapjewels() swaps two jewels as long as it results in points and * returns points earned. ******************************************************************************/ -static unsigned int jewels_swapjewels(struct game_context* bj, - int x, int y, int direc) { +static unsigned int jewels_swapjewels(struct game_context* bj, int x, int y, int direc) { int k; int horzmod, vertmod; int movelen = 0; bool undo = false; unsigned int points = 0; long lasttick, currenttick; + + bj->playgame = true; /* check for invalid parameters */ if(x < 0 || x >= BJ_WIDTH || y < 0 || y >= BJ_HEIGHT-1 || @@ -987,7 +1032,7 @@ /***************************************************************************** * jewels_movesavail() uses pattern matching to see if there are any -* available move left. +* available move left. ******************************************************************************/ static bool jewels_movesavail(struct game_context* bj) { int i, j; @@ -1075,17 +1120,15 @@ } } } - if(moves) break; } - return moves; } /***************************************************************************** -* jewels_puzzle_is_finished(bj) checks if the puzzle is finished. +* jewels_puzzle_is_finished() checks if the puzzle is finished. ******************************************************************************/ -static int jewels_puzzle_is_finished(struct game_context* bj) { +static bool jewels_puzzle_is_finished(struct game_context* bj) { unsigned int i, j; for(i=0; iplayboard[i-1][j].type<=MAX_NUM_JEWELS || !((bj->playboard[i-1][j].type-MAX_NUM_JEWELS) &PUZZLE_TILE_DOWN)) - return 0; + return false; } 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; + return false; } 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; + return false; } 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 false; } } } } - return 1; + return true; } /***************************************************************************** @@ -1158,17 +1201,40 @@ } break; } - + jewels_drawboard(bj); /* run the play board */ jewels_putjewels(bj); + points += jewels_runboard(bj); + return points; } /***************************************************************************** -* jewels_nextlevel() advances the game to the next level and returns +* jewels_init() initializes jewels data structures. +******************************************************************************/ +static void jewels_init(struct game_context* bj) { + /* seed the rand generator */ + rb->srand(*rb->current_tick); + + bj->type = bj->tmp_type; + bj->level = 1; + bj->score = 0; + bj->segments = 0; + + jewels_setcolors(); + + /* clear playing board */ + rb->memset(bj->playboard, 0, sizeof(bj->playboard)); + do { + bj->score += jewels_initlevel(bj); + } while(!jewels_movesavail(bj)); +} + +/***************************************************************************** +* jewels_nextlevel() advances the game to the next bj->level and returns * points earned. ******************************************************************************/ static void jewels_nextlevel(struct game_context* bj) { @@ -1177,7 +1243,7 @@ switch(bj->type) { case GAME_TYPE_NORMAL: - /* roll over score, change and display level */ + /* roll over score, change and display bj->level */ while(bj->score >= LEVEL_PTS) { bj->score -= LEVEL_PTS; bj->level++; @@ -1199,12 +1265,7 @@ case GAME_TYPE_PUZZLE: bj->level++; - if(bj->level>NUM_PUZZLE_LEVELS) { - rb->splash(HZ*2, "You win!"); - bj->level = 1; - } else { - rb->splashf(HZ*2, "Level %d", bj->level); - } + rb->splashf(HZ*2, "Level %d", bj->level); break; } @@ -1212,658 +1273,360 @@ bj->score += points; } -/***************************************************************************** -* jewels_recordscore() inserts a high score into the high scores list and -* returns the high score position. -******************************************************************************/ -static int jewels_recordscore(struct game_context* bj) { - int i; - int position = 0; - unsigned int current, temp; +static void jewels_show_highscores(int position) +{ + int i, w, h; + char str[30]; - /* calculate total score */ - current = (bj->level-1)*LEVEL_PTS+bj->score; - if(current <= 0) return 0; +#ifdef HAVE_LCD_COLOR + rb->lcd_set_background(LCD_BLACK); + rb->lcd_set_foreground(LCD_WHITE); +#endif + rb->button_clear_queue(); + rb->lcd_clear_display(); - /* insert the current score into the high scores */ - for(i=0; i= bj->highscores[i]) { - if(!position) { - position = i+1; - bj->dirty = true; - } - temp = bj->highscores[i]; - bj->highscores[i] = current; - current = temp; - } + rb->lcd_setfont(FONT_UI); + rb->lcd_getstringsize("High Scores", &w, &h); + /* check wether it fits on screen */ + if ((4*h + h*(NUM_SCORES-1) + MARGIN) > LCD_HEIGHT) { + rb->lcd_setfont(FONT_SYSFIXED); + rb->lcd_getstringsize("High Scores", &w, &h); } + rb->lcd_putsxy(LCD_WIDTH/2-w/2, MARGIN, "High Scores"); + rb->lcd_putsxy(LCD_WIDTH/4-w/4,2*h, "Score"); + rb->lcd_putsxy(LCD_WIDTH*3/4-w/4,2*h, "Level"); - return position; - } - -/***************************************************************************** -* jewels_loadscores() loads the high scores saved file. -******************************************************************************/ -static void jewels_loadscores(struct game_context* bj) { - int fd; - - bj->dirty = false; - - /* clear high scores */ - rb->memset(bj->highscores, 0, sizeof(bj->highscores)); - - /* open scores file */ - fd = rb->open(SCORE_FILE, O_RDONLY); - if(fd < 0) return; - - /* read in high scores */ - if(rb->read(fd, bj->highscores, sizeof(bj->highscores)) <= 0) { - /* scores are bad, reset */ - rb->memset(bj->highscores, 0, sizeof(bj->highscores)); + for (i = 0; ilcd_set_foreground(LCD_RGBPACK(245,0,0)); + } +#endif + rb->snprintf (str, sizeof (str), "%d)", i+1); + rb->lcd_putsxy (MARGIN,3*h + h*i, str); + rb->snprintf (str, sizeof (str), "%d", highest[i].score); + rb->lcd_putsxy (LCD_WIDTH/4-w/4,3*h + h*i, str); + rb->snprintf (str, sizeof (str), "%d", highest[i].level); + rb->lcd_putsxy (LCD_WIDTH*3/4-w/4,3*h + h*i, str); + if(i == position) { +#ifdef HAVE_LCD_COLOR + rb->lcd_set_foreground(LCD_WHITE); +#else + rb->lcd_hline(MARGIN, LCD_WIDTH-MARGIN, 3*h + h*(i+1)); +#endif + } } - - rb->close(fd); + rb->lcd_update(); + rb->button_get(true); + rb->lcd_setfont(FONT_SYSFIXED); } -/***************************************************************************** -* jewels_savescores() saves the high scores saved file. -******************************************************************************/ -static void jewels_savescores(struct game_context* bj) { - int fd; +static int jewels_help(void) +{ + rb->lcd_setfont(FONT_UI); +#define WORDS (sizeof help_text / sizeof (char*)) + static char *help_text[] = { + "Jewels", "", "Aim", "", "Swap", "pairs", "of", "jewels", "to", + "form", "connected", "segments", "of", "three", "or", "more", "of", + "the", "same", "type.", "", "The", "goal", "of", "the", "game", + "is", "to", "score", "as", "many", "points", "as", "possible", + "before", "running", "out", "of", "available", "moves." + }; + static struct style_text formation[]={ + { 0, TEXT_CENTER|TEXT_UNDERLINE }, + { 2, C_RED } + }; - /* write out the high scores to the save file */ - fd = rb->open(SCORE_FILE, O_WRONLY|O_CREAT); - rb->write(fd, bj->highscores, sizeof(bj->highscores)); - rb->close(fd); - bj->dirty = false; -} +#ifdef HAVE_LCD_COLOR + rb->lcd_set_background(LCD_BLACK); + rb->lcd_set_foreground(LCD_WHITE); +#endif + if (display_text(WORDS, help_text, formation, NULL)==PLUGIN_USB_CONNECTED) + return PLUGIN_USB_CONNECTED; + int button; + do { + button = rb->button_get(true); + if (button == SYS_USB_CONNECTED) { + return PLUGIN_USB_CONNECTED; + } + } while( ( button == BUTTON_NONE ) + || ( button & (BUTTON_REL|BUTTON_REPEAT) ) ); + rb->lcd_setfont(FONT_SYSFIXED); -/***************************************************************************** -* jewels_loadgame() loads the saved game and returns load success. -******************************************************************************/ -static bool jewels_loadgame(struct game_context* bj) { - int fd; - bool loaded = false; - - /* open game file */ - fd = rb->open(SAVE_FILE, O_RDONLY); - if(fd < 0) return loaded; - - /* read in saved game */ - while(true) { - if(rb->read(fd, &bj->score, sizeof(bj->score)) <= 0) break; - if(rb->read(fd, &bj->level, sizeof(bj->level)) <= 0) break; - if(rb->read(fd, &bj->type, sizeof(bj->type)) <= 0) break; - if(rb->read(fd, bj->playboard, sizeof(bj->playboard)) <= 0) break; - bj->resume = true; - loaded = true; - break; - } - - rb->close(fd); - - /* delete saved file */ - rb->remove(SAVE_FILE); - return loaded; + return 0; } -/***************************************************************************** -* jewels_savegame() saves the current game state. -******************************************************************************/ -static void jewels_savegame(struct game_context* bj) { - int fd; - - /* write out the game state to the save file */ - fd = rb->open(SAVE_FILE, O_WRONLY|O_CREAT); - rb->write(fd, &bj->score, sizeof(bj->score)); - rb->write(fd, &bj->level, sizeof(bj->level)); - rb->write(fd, &bj->type, sizeof(bj->type)); - rb->write(fd, bj->playboard, sizeof(bj->playboard)); - rb->close(fd); - - bj->resume = true; -} - -/***************************************************************************** -* jewels_callback() is the default event handler callback which is called -* on usb connect and shutdown. -******************************************************************************/ -static void jewels_callback(void* param) { - struct game_context* bj = (struct game_context*) param; - if(bj->dirty) { - rb->splash(HZ, "Saving high scores..."); - jewels_savescores(bj); +static void jewels_choose_mode(struct game_context* bj) +{ + rb->button_clear_queue(); + int choice = bj->tmp_type; + MENUITEM_STRINGLIST (main_menu, "Jewels Mode", NULL, + "Normal", + "Puzzle"); + choice = rb->do_menu(&main_menu, &choice, NULL, false); + switch (choice) { + case 0: + bj->tmp_type=GAME_TYPE_NORMAL; + break; + case 1: + bj->tmp_type=GAME_TYPE_PUZZLE; + break; + default: + break; } } -/***************************************************************************** -* jewels_displayscores() displays the high scores -******************************************************************************/ -static char * scores_get_name(int selected_item, void * data, - char * buffer, size_t buffer_len) +static bool _ingame; +static int jewels_menu_cb(int action, const struct menu_item_ex *this_item) { - struct game_context* bj = (struct game_context*)data; - rb->snprintf(buffer, buffer_len, "#%02d: %d", - selected_item+1, bj->highscores[selected_item]); - return buffer; + if(action == ACTION_REQUEST_MENUITEM + && !_ingame && ((intptr_t)this_item)==0) + return ACTION_EXIT_MENUITEM; + return action; } -static void jewels_displayscores(struct game_context* bj) -{ - struct simplelist_info info; - rb->simplelist_info_init(&info, "High Scores", NUM_SCORES, (void*)bj); - info.hide_selection = true; - info.get_name = scores_get_name; - rb->simplelist_show_list(&info); -} - - /***************************************************************************** -* jewels_main() is the main game subroutine, it returns the final game status. +* jewels_game_menu() shows the game menu. ******************************************************************************/ -static int jewels_main(struct game_context* bj) { - int w, h; - int button; - struct viewport vp[NB_SCREENS]; - char str[18]; - bool inmenu = true; - bool selected = false; +static int jewels_game_menu(struct game_context* bj, bool ingame) +{ + rb->button_clear_queue(); + int choice = 0; - /* the cursor coordinates */ - int x=0, y=0; + _ingame = ingame; - /* don't resume by default */ - bj->resume = false; - - /******************** - * menu * - ********************/ - MENUITEM_STRINGLIST(main_menu,"Jewels",NULL, - "New Game", "Puzzle", "Resume Saved Game", - "High Scores", "Help", "Quit"); - FOR_NB_SCREENS(h) - { - rb->viewport_set_defaults(&vp[h], h); -#if (LCD_DEPTH >= 16) || defined(LCD_REMOTE_DEPTH) && (LCD_REMOTE_DEPTH >= 16) - if (rb->screens[h]->depth >= 16) - { - vp->bg_pattern = LCD_RGBPACK(49, 26, 26); - vp->fg_pattern = LCD_RGBPACK(210, 181, 181); - } -#endif - } - - while(inmenu) { - - switch (rb->do_menu(&main_menu, NULL, vp, true)) { + MENUITEM_STRINGLIST (main_menu, "Jewels Menu", jewels_menu_cb, + "Resume Game", + "Start New Game", + "Mode", + "Help", + "High Score", + "Playback Control", + "Quit"); + + while (1) { + switch (rb->do_menu(&main_menu, &choice, NULL, false)) { case 0: - inmenu = false; - bj->type = GAME_TYPE_NORMAL; - break; - + jewels_setcolors(); + return 0; case 1: - inmenu = false; - bj->type = GAME_TYPE_PUZZLE; - break; - + jewels_init(bj); + return 0; case 2: - if(!jewels_loadgame(bj)) { - rb->splash(HZ*2, "Nothing to resume"); - } else { - inmenu = false; - } + jewels_choose_mode(bj); break; - case 3: - jewels_displayscores(bj); + jewels_help(); break; - case 4: - /* welcome screen to display key bindings */ - rb->lcd_clear_display(); - rb->snprintf(str, 5, "%s", "Help"); - rb->lcd_getstringsize(str, &w, &h); - rb->lcd_putsxy((LCD_WIDTH-w)/2, 0, str); -#if CONFIG_KEYPAD == RECORDER_PAD - rb->lcd_puts(0, 2, "Controls:"); - rb->lcd_puts(0, 3, "Directions = move"); - rb->lcd_puts(0, 4, "PLAY = select"); - rb->lcd_puts(0, 5, "Long PLAY = menu"); - rb->lcd_puts(0, 6, "OFF = cancel"); -#elif CONFIG_KEYPAD == ONDIO_PAD - rb->lcd_puts(0, 2, "Controls:"); - rb->lcd_puts(0, 3, "Directions = move"); - rb->lcd_puts(0, 4, "MENU = select"); - rb->lcd_puts(0, 5, "Long MENU = menu"); - rb->lcd_puts(0, 6, "OFF = cancel"); -#elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD - rb->lcd_puts(0, 2, "Controls:"); - rb->lcd_puts(0, 3, "Directions = move"); - rb->lcd_puts(0, 4, "SELECT = select"); - rb->lcd_puts(0, 5, "Long SELECT = menu"); - rb->lcd_puts(0, 6, "PLAY = cancel"); -#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD) - rb->lcd_puts(0, 2, "Swap pairs of jewels to"); - rb->lcd_puts(0, 3, "form connected segments"); - rb->lcd_puts(0, 4, "of three or more of the"); - rb->lcd_puts(0, 5, "same type."); - rb->lcd_puts(0, 7, "Controls:"); - rb->lcd_puts(0, 8, "Directions to move"); - rb->lcd_puts(0, 9, "SELECT to select"); - rb->lcd_puts(0, 10, "Long SELECT to show menu"); - rb->lcd_puts(0, 11, "OFF to cancel"); -#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \ - (CONFIG_KEYPAD == IPOD_1G2G_PAD) - rb->lcd_puts(0, 2, "Swap pairs of jewels to"); - rb->lcd_puts(0, 3, "form connected segments"); - rb->lcd_puts(0, 4, "of three or more of the"); - rb->lcd_puts(0, 5, "same type."); - rb->lcd_puts(0, 7, "Controls:"); - rb->lcd_puts(0, 8, "Directions or scroll to move"); - rb->lcd_puts(0, 9, "SELECT to select"); - rb->lcd_puts(0, 10, "Long SELECT to show menu"); -#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD - rb->lcd_puts(0, 2, "Swap pairs of jewels to"); - rb->lcd_puts(0, 3, "form connected segments"); - rb->lcd_puts(0, 4, "of three or more of the"); - rb->lcd_puts(0, 5, "same type."); - rb->lcd_puts(0, 7, "Controls:"); - rb->lcd_puts(0, 8, "Directions to move"); - rb->lcd_puts(0, 9, "SELECT to select"); - rb->lcd_puts(0, 10, "Long SELECT to show menu"); - rb->lcd_puts(0, 11, "PLAY to cancel"); -#elif CONFIG_KEYPAD == GIGABEAT_PAD \ - || CONFIG_KEYPAD == MROBE100_PAD - rb->lcd_puts(0, 2, "Swap pairs of jewels to"); - rb->lcd_puts(0, 3, "form connected segments"); - rb->lcd_puts(0, 4, "of three or more of the"); - rb->lcd_puts(0, 5, "same type."); - rb->lcd_puts(0, 7, "Controls:"); - rb->lcd_puts(0, 8, "Directions to move"); - rb->lcd_puts(0, 9, "SELECT to select"); - rb->lcd_puts(0, 10, "Long SELECT to show menu"); - rb->lcd_puts(0, 11, "POWER to cancel"); -#elif CONFIG_KEYPAD == SANSA_E200_PAD \ - || CONFIG_KEYPAD == SANSA_C200_PAD \ - || CONFIG_KEYPAD == SANSA_CLIP_PAD \ - || CONFIG_KEYPAD == SANSA_FUZE_PAD \ - || CONFIG_KEYPAD == SANSA_M200_PAD - rb->lcd_puts(0, 2, "Swap pairs of jewels to"); - rb->lcd_puts(0, 3, "form connected segments"); - rb->lcd_puts(0, 4, "of three or more of the"); - rb->lcd_puts(0, 5, "same type."); - rb->lcd_puts(0, 7, "Controls:"); - rb->lcd_puts(0, 8, "Directions to move"); - rb->lcd_puts(0, 9, "SELECT to select"); - rb->lcd_puts(0, 10, "Long SELECT to show menu"); - rb->lcd_puts(0, 11, "POWER to cancel"); -#elif CONFIG_KEYPAD == IRIVER_H10_PAD - rb->lcd_puts(0, 2, "Swap pairs of jewels"); - rb->lcd_puts(0, 3, "to form connected"); - rb->lcd_puts(0, 4, "segments of three or "); - rb->lcd_puts(0, 5, "more of the"); - rb->lcd_puts(0, 6, "same type."); - rb->lcd_puts(0, 8, "Controls:"); - rb->lcd_puts(0, 9, "Directions or scroll to move"); - rb->lcd_puts(0, 10, "PLAY to select"); - rb->lcd_puts(0, 11, "Long PLAY for menu"); - rb->lcd_puts(0, 12, "POWER to cancel"); -#elif CONFIG_KEYPAD == IAUDIO_M3_PAD - rb->lcd_puts(0, 2, "Swap pairs of jewels"); - rb->lcd_puts(0, 3, "to form connected"); - rb->lcd_puts(0, 4, "segments of three or "); - rb->lcd_puts(0, 5, "more of the"); - rb->lcd_puts(0, 6, "same type."); - rb->lcd_puts(0, 8, "Controls:"); - rb->lcd_puts(0, 9, "Directions or scroll to move"); - rb->lcd_puts(0, 10, "PLAY to select"); - rb->lcd_puts(0, 11, "Long PLAY for menu"); - rb->lcd_puts(0, 12, "REC to cancel"); -#elif CONFIG_KEYPAD == COWOND2_PAD - rb->lcd_puts(0, 11, "POWER to cancel"); -#elif CONFIG_KEYPAD == GIGABEAT_S_PAD - rb->lcd_puts(0, 2, "Swap pairs of jewels to"); - rb->lcd_puts(0, 3, "form connected segments"); - rb->lcd_puts(0, 4, "of three or more of the"); - rb->lcd_puts(0, 5, "same type."); - rb->lcd_puts(0, 7, "Controls:"); - rb->lcd_puts(0, 8, "Directions to move"); - rb->lcd_puts(0, 9, "SELECT to select"); - rb->lcd_puts(0, 10, "Long SELECT to show menu"); - rb->lcd_puts(0, 11, "BACK to cancel"); -#elif CONFIG_KEYPAD == CREATIVEZVM_PAD - rb->lcd_puts(0, 2, "Swap pairs of jewels to"); - rb->lcd_puts(0, 3, "form connected segments"); - rb->lcd_puts(0, 4, "of three or more of the"); - rb->lcd_puts(0, 5, "same type."); - rb->lcd_puts(0, 7, "Controls:"); - rb->lcd_puts(0, 8, "Directions to move"); - rb->lcd_puts(0, 9, "MIDDLE to select"); - rb->lcd_puts(0, 10, "Long MIDDLE to show menu"); - rb->lcd_puts(0, 11, "BACK to cancel"); -#elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD - rb->lcd_puts(0, 2, "Swap pairs of jewels to"); - rb->lcd_puts(0, 3, "form connected segments"); - rb->lcd_puts(0, 4, "of three or more of the"); - rb->lcd_puts(0, 5, "same type."); - rb->lcd_puts(0, 7, "Controls:"); - rb->lcd_puts(0, 8, "Directions to move"); - rb->lcd_puts(0, 9, "SELECT/PLAY to select"); - rb->lcd_puts(0, 10, "Long SELECT to show menu"); - rb->lcd_puts(0, 11, "POWER to cancel"); -#elif CONFIG_KEYPAD == ONDAVX747_PAD || CONFIG_KEYPAD == MROBE500_PAD - rb->lcd_puts(0, 11, "POWER to cancel"); -#else - #warning: missing help text. -#endif - -#ifdef HAVE_TOUCHSCREEN - rb->lcd_puts(0, 2, "Swap pairs of jewels to"); - rb->lcd_puts(0, 3, "form connected segments"); - rb->lcd_puts(0, 4, "of three or more of the"); - rb->lcd_puts(0, 5, "same type."); - rb->lcd_puts(0, 7, "Controls:"); - rb->lcd_puts(0, 8, "Directions to move"); - rb->lcd_puts(0, 9, "CENTER to select"); - rb->lcd_puts(0, 10, "Long CENTER to show menu"); -#endif - rb->lcd_update(); - while(true) { - button = rb->button_get(true); - if(button != BUTTON_NONE && !(button&BUTTON_REL)) break; - } - rb->lcd_clear_display(); + jewels_show_highscores(NUM_SCORES); break; - case 5: - return BJ_QUIT; - + playback_control(NULL); + break; + case 6: + if (bj->playgame) { + rb->splash(HZ*1, "Saving game ..."); + jewels_savegame(bj); + } + return 1; case MENU_ATTACHED_USB: - jewels_callback(bj); - return BJ_USB; - + return 1; default: - return BJ_QUIT; + break; } } +} - /******************** - * init * - ********************/ - jewels_init(bj); - - /******************** - * setup the board * - ********************/ - bj->score += jewels_initlevel(bj); - if (!jewels_movesavail(bj)) { - switch(bj->type) { - case GAME_TYPE_NORMAL: - return BJ_LOSE; - - case GAME_TYPE_PUZZLE: - do { - rb->splash(2*HZ, "No more moves!"); - bj->score += jewels_initlevel(bj); - } while(!jewels_movesavail(bj)); - break; - } +static int jewels_main(struct game_context* bj) { + int button; + int position; + bool selected = false; + bool no_movesavail; + int x=0, y=0; + + bj->playgame = false; + if(!jewels_loadgame(bj)) { + if (jewels_game_menu(bj, false)!=0) + return 0; + } else { + if (jewels_game_menu(bj, true)!=0) + return 0; } - /********************** - * play * - **********************/ - MENUITEM_STRINGLIST(ingame_menu,"Menu",NULL, - "Audio Playback", "Resume Game", - "Save Game", "End Game", "Exit Jewels"); - - selected = false; while(true) { - bool no_movesavail = false; + no_movesavail = false; - while(inmenu) { - switch (rb->do_menu(&ingame_menu, NULL, vp, true)) { - case 0: - playback_control(NULL); - inmenu = false; - break; + /* refresh the board */ + jewels_drawboard(bj); - case 1: - inmenu = false; - break; + /* display the cursor */ + if(selected) { + rb->lcd_set_drawmode(DRMODE_COMPLEMENT); + rb->lcd_fillrect(x*TILE_WIDTH, y*TILE_HEIGHT+YOFS, + TILE_WIDTH, TILE_HEIGHT); + rb->lcd_set_drawmode(DRMODE_SOLID); + } else { + rb->lcd_drawrect(x*TILE_WIDTH, y*TILE_HEIGHT+YOFS, + TILE_WIDTH, TILE_HEIGHT); + } + rb->lcd_update_rect(x*TILE_WIDTH, y*TILE_HEIGHT+YOFS, + TILE_WIDTH, TILE_HEIGHT); - case 2: - rb->splash(HZ, "Saving game..."); - jewels_savegame(bj); - return BJ_END; - - case 3: - return BJ_END; - - case 4: - return BJ_QUIT_FROM_GAME; - - case MENU_ATTACHED_USB: - jewels_callback(bj); - return BJ_USB; - - default: - inmenu = false; - break; - } - } - - /* refresh the board */ - jewels_drawboard(bj); - - /* display the cursor */ - if(selected) { - rb->lcd_set_drawmode(DRMODE_COMPLEMENT); - rb->lcd_fillrect(x*TILE_WIDTH, y*TILE_HEIGHT+YOFS, - TILE_WIDTH, TILE_HEIGHT); - rb->lcd_set_drawmode(DRMODE_SOLID); - } else { - rb->lcd_drawrect(x*TILE_WIDTH, y*TILE_HEIGHT+YOFS, - TILE_WIDTH, TILE_HEIGHT); - } - rb->lcd_update_rect(x*TILE_WIDTH, y*TILE_HEIGHT+YOFS, - TILE_WIDTH, TILE_HEIGHT); - /* handle game button presses */ rb->yield(); button = rb->button_get(true); switch(button){ case JEWELS_LEFT: /* move cursor left */ case (JEWELS_LEFT|BUTTON_REPEAT): - if(selected) { - bj->score += jewels_swapjewels(bj, x, y, SWAP_LEFT); - selected = false; - if (!jewels_movesavail(bj)) no_movesavail = true; - } else { - x = (x+BJ_WIDTH-1)%BJ_WIDTH; - } + if(selected) { + bj->score += jewels_swapjewels(bj, x, y, SWAP_LEFT); + selected = false; + if (!jewels_movesavail(bj)) no_movesavail = true; + } else { + x = (x+BJ_WIDTH-1)%BJ_WIDTH; + } break; case JEWELS_RIGHT: /* move cursor right */ case (JEWELS_RIGHT|BUTTON_REPEAT): - if(selected) { - bj->score += jewels_swapjewels(bj, x, y, SWAP_RIGHT); - selected = false; - if (!jewels_movesavail(bj)) no_movesavail = true; - } else { - x = (x+1)%BJ_WIDTH; - } + if(selected) { + bj->score += jewels_swapjewels(bj, x, y, SWAP_RIGHT); + selected = false; + if (!jewels_movesavail(bj)) no_movesavail = true; + } else { + x = (x+1)%BJ_WIDTH; + } break; case JEWELS_DOWN: /* move cursor down */ case (JEWELS_DOWN|BUTTON_REPEAT): - if(selected) { - bj->score += jewels_swapjewels(bj, x, y, SWAP_DOWN); - selected = false; - if (!jewels_movesavail(bj)) no_movesavail = true; - } else { - y = (y+1)%(BJ_HEIGHT-1); - } + if(selected) { + bj->score += jewels_swapjewels(bj, x, y, SWAP_DOWN); + selected = false; + if (!jewels_movesavail(bj)) no_movesavail = true; + } else { + y = (y+1)%(BJ_HEIGHT-1); + } break; case JEWELS_UP: /* move cursor up */ case (JEWELS_UP|BUTTON_REPEAT): - if(selected) { - bj->score += jewels_swapjewels(bj, x, y, SWAP_UP); - selected = false; - if (!jewels_movesavail(bj)) no_movesavail = true; - } else { - y = (y+(BJ_HEIGHT-1)-1)%(BJ_HEIGHT-1); - } + if(selected) { + bj->score += jewels_swapjewels(bj, x, y, SWAP_UP); + selected = false; + if (!jewels_movesavail(bj)) no_movesavail = true; + } else { + y = (y+(BJ_HEIGHT-1)-1)%(BJ_HEIGHT-1); + } break; #ifdef JEWELS_SCROLLWHEEL case JEWELS_PREV: /* scroll backwards */ case (JEWELS_PREV|BUTTON_REPEAT): - if(!selected) { - if(x == 0) { - y = (y+(BJ_HEIGHT-1)-1)%(BJ_HEIGHT-1); - } - x = (x+BJ_WIDTH-1)%BJ_WIDTH; - } + if(!selected) { + if(x == 0) { + y = (y+(BJ_HEIGHT-1)-1)%(BJ_HEIGHT-1); + } + x = (x+BJ_WIDTH-1)%BJ_WIDTH; + } break; case JEWELS_NEXT: /* scroll forwards */ case (JEWELS_NEXT|BUTTON_REPEAT): - if(!selected) { - if(x == BJ_WIDTH-1) { - y = (y+1)%(BJ_HEIGHT-1); - } - x = (x+1)%BJ_WIDTH; - } + if(!selected) { + if(x == BJ_WIDTH-1) { + y = (y+1)%(BJ_HEIGHT-1); + } + x = (x+1)%BJ_WIDTH; + } break; #endif case JEWELS_SELECT: /* toggle selected */ - selected = !selected; + selected = !selected; break; -#ifdef JEWELS_MENU - case JEWELS_MENU: -#endif - case (JEWELS_SELECT|BUTTON_REPEAT): /* show menu */ - inmenu = true; - selected = false; - break; - -#ifdef JEWELS_CANCEL #ifdef JEWELS_RC_CANCEL case JEWELS_RC_CANCEL: #endif case JEWELS_CANCEL: /* end game */ - return BJ_END; + if (jewels_game_menu(bj, true)!=0) + return 0; break; -#endif default: - if(rb->default_event_handler_ex(button, jewels_callback, - (void*) bj) == SYS_USB_CONNECTED) - return BJ_USB; + if (rb->default_event_handler (button) == SYS_USB_CONNECTED) + return PLUGIN_USB_CONNECTED; break; } + + switch(bj->type) { + case GAME_TYPE_NORMAL: + if(bj->score >= LEVEL_PTS) + jewels_nextlevel(bj); + break; + case GAME_TYPE_PUZZLE: + if (jewels_puzzle_is_finished(bj)) { + if (bj->level < NUM_PUZZLE_LEVELS) { + jewels_nextlevel(bj); + } else { + rb->splash(2*HZ, "Congratulations!"); + rb->splash(2*HZ, "You have finished the game!"); + if (jewels_game_menu(bj, false)!=0) { + return 0; + } + } + break; + } + } if (no_movesavail) { switch(bj->type) { case GAME_TYPE_NORMAL: - return BJ_LOSE; - + rb->splash(HZ*2, "Game Over!"); + rb->lcd_clear_display(); + if (highscore_would_update(bj->score, highest, + NUM_SCORES)) { + position=highscore_update(bj->score, + bj->level, "", + highest,NUM_SCORES); + if (position == 0) { + rb->splash(HZ*2, "New High Score"); + } + jewels_show_highscores(position); + } + break; case GAME_TYPE_PUZZLE: - do { - rb->splash(2*HZ, "No more moves!"); - bj->score += jewels_initlevel(bj); - } while(!jewels_movesavail(bj)); + rb->splash(2*HZ, "Game Over"); break; } + if (jewels_game_menu(bj, false)!=0) { + return 0; + } } - - switch(bj->type) { - case GAME_TYPE_NORMAL: - if(bj->score >= LEVEL_PTS) - jewels_nextlevel(bj); - break; - - case GAME_TYPE_PUZZLE: - if(jewels_puzzle_is_finished(bj)) - jewels_nextlevel(bj); - break; - } } } -/***************************************************************************** -* plugin entry point. -******************************************************************************/ -enum plugin_status plugin_start(const void* parameter) { - struct game_context bj; - bool exit = false; - int position; - char str[19]; - - /* plugin init */ +/* this is the plugin entry point */ +enum plugin_status plugin_start(const void* parameter) +{ (void)parameter; - /* end of plugin init */ - +#ifdef HAVE_LCD_BITMAP /* load high scores */ - jewels_loadscores(&bj); + highscore_load(HIGH_SCORE,highest,NUM_SCORES); rb->lcd_setfont(FONT_SYSFIXED); #if LCD_DEPTH > 1 rb->lcd_set_backdrop(NULL); #endif - jewels_setcolors(); - while(!exit) { - switch(jewels_main(&bj)){ - case BJ_LOSE: - rb->splash(HZ*2, "No more moves!"); - /* fall through to BJ_END */ - - case BJ_END: - if(!bj.resume) { - if((position = jewels_recordscore(&bj))) { - rb->snprintf(str, 19, "New high score #%d!", position); - rb->splash(HZ*2, str); - } - } - break; - - case BJ_USB: - rb->lcd_setfont(FONT_UI); - return PLUGIN_USB_CONNECTED; - - case BJ_QUIT: - if(bj.dirty) { - rb->splash(HZ, "Saving high scores..."); - jewels_savescores(&bj); - } - exit = true; - break; - - case BJ_QUIT_FROM_GAME: - if(!bj.resume) { - if((position = jewels_recordscore(&bj))) { - rb->snprintf(str, 19, "New high score #%d!", position); - rb->splash(HZ*2, str); - } - } - if(bj.dirty) { - rb->splash(HZ, "Saving high scores..."); - jewels_savescores(&bj); - } - exit = true; - break; - - default: - break; - } - } - + struct game_context bj; + bj.tmp_type = GAME_TYPE_NORMAL; + jewels_main(&bj); + highscore_save(HIGH_SCORE,highest,NUM_SCORES); rb->lcd_setfont(FONT_UI); +#endif /* HAVE_LCD_BITMAP */ + return PLUGIN_OK; } - -#endif /* HAVE_LCD_BITMAP */ Index: apps/plugins/pegbox.c =================================================================== --- apps/plugins/pegbox.c (Revision 21733) +++ apps/plugins/pegbox.c (Arbeitskopie) @@ -19,29 +19,17 @@ * ****************************************************************************/ #include "plugin.h" +#include "lib/configfile.h" +#include "lib/display_text.h" +#include "lib/playback_control.h" #include "pluginbitmaps/pegbox_header.h" #include "pluginbitmaps/pegbox_pieces.h" -#if LCD_HEIGHT >= 80 /* enough space for a graphical menu */ -#include "pluginbitmaps/pegbox_menu_top.h" -#include "pluginbitmaps/pegbox_menu_items.h" -#define MENU_X (LCD_WIDTH-BMPWIDTH_pegbox_menu_items)/2 -#define MENU_Y BMPHEIGHT_pegbox_menu_top -#define ITEM_WIDTH BMPWIDTH_pegbox_menu_items -#define ITEM_HEIGHT (BMPHEIGHT_pegbox_menu_items/9) -#endif - PLUGIN_HEADER -/* final game return status */ -#define PB_END 3 -#define PB_USB 2 -#define PB_QUIT 1 +#define CONFIG_FILE_NAME "pegbox.cfg" -#define DATA_FILE PLUGIN_GAMES_DIR "/pegbox.data" -#define SAVE_FILE PLUGIN_GAMES_DIR "/pegbox.save" - #define ROWS 8 /* Number of rows on each board */ #define COLS 12 /* Number of columns on each board */ #define NUM_LEVELS 15 /* Number of levels */ @@ -195,9 +183,9 @@ #elif CONFIG_KEYPAD == SANSA_FUZE_PAD #define PEGBOX_SAVE BUTTON_SELECT|BUTTON_REL #define PEGBOX_QUIT (BUTTON_HOME|BUTTON_REPEAT) -#define PEGBOX_RESTART BUTTON_SELECT|BUTTON_LEFT -#define PEGBOX_LVL_UP BUTTON_SCROLL_BACK -#define PEGBOX_LVL_DOWN BUTTON_SCROLL_FWD +#define PEGBOX_RESTART (BUTTON_SELECT|BUTTON_LEFT) +#define PEGBOX_LVL_UP (BUTTON_SELECT|BUTTON_UP) +#define PEGBOX_LVL_DOWN (BUTTON_SELECT|BUTTON_DOWN) #define PEGBOX_UP BUTTON_UP #define PEGBOX_DOWN BUTTON_DOWN #define PEGBOX_RIGHT BUTTON_RIGHT @@ -206,8 +194,8 @@ #define SAVE_TEXT "SELECT" #define QUIT_TEXT "HOME" #define RESTART_TEXT "SELECT & LEFT" -#define LVL_UP_TEXT "SCROLL BACK" -#define LVL_DOWN_TEXT "SCROLL FWD" +#define LVL_UP_TEXT "SELECT & UP" +#define LVL_DOWN_TEXT "SELECT & DOWN" #elif CONFIG_KEYPAD == GIGABEAT_PAD #define PEGBOX_SAVE BUTTON_SELECT @@ -529,26 +517,6 @@ #ifdef HAVE_TOUCHSCREEN #include "lib/touchscreen.h" - -static struct ts_mapping main_menu_items[5] = -{ -{MENU_X, MENU_Y, ITEM_WIDTH, ITEM_HEIGHT}, -{MENU_X, MENU_Y+ITEM_HEIGHT, ITEM_WIDTH, ITEM_HEIGHT}, -{MENU_X, MENU_Y+ITEM_HEIGHT*2, ITEM_WIDTH, ITEM_HEIGHT}, -{MENU_X, MENU_Y+ITEM_HEIGHT*3, ITEM_WIDTH, ITEM_HEIGHT}, -{ -#if (LCD_WIDTH >= 138) && (LCD_HEIGHT > 110) -0, MENU_Y+4*ITEM_HEIGHT+8, SYSFONT_WIDTH*28, SYSFONT_HEIGHT -#elif LCD_WIDTH > 112 -0, LCD_HEIGHT - 8, SYSFONT_WIDTH*28, SYSFONT_HEIGHT -#else -#error "Touchscreen isn't supported on non-bitmap screens!" -#endif -} - -}; -static struct ts_mappings main_menu = {main_menu_items, 5}; - static struct ts_raster pegbox_raster = { BOARD_X, BOARD_Y, COLS*PIECE_WIDTH, ROWS*PIECE_HEIGHT, PIECE_WIDTH, PIECE_HEIGHT }; @@ -556,13 +524,13 @@ { &pegbox_raster, false, false, true, false, true, {0, 0}, 0, 0, 0 }; #endif + struct game_context { unsigned int level; unsigned int highlevel; signed int player_row; signed int player_col; unsigned int num_left; - bool save_exist; unsigned int playboard[ROWS][COLS]; }; @@ -718,116 +686,11 @@ {0, 0, 4, 6, 0, 6, 0, 6, 0, 6, 0, 1,}} }; - -/***************************************************************************** -* display_text() formats and outputs text. -******************************************************************************/ -static void display_text(char *str, bool waitkey) +/*********************************************************************** +* pegbox_draw_board() draws the game's current level. +************************************************************************/ +static void pegbox_draw_board(struct game_context* pb) { - int chars_by_line; - int lines_by_screen; - int chars_for_line; - int current_line = 0; - int char_width, char_height; - int first_char_index = 0; - char *ptr_char; - char *ptr_line; - int i; - char line[255]; - int key; - bool go_on; - - rb->lcd_clear_display(); - - rb->lcd_getstringsize("a", &char_width, &char_height); - - chars_by_line = LCD_WIDTH / char_width; - lines_by_screen = LCD_HEIGHT / char_height; - - do - { - ptr_char = str + first_char_index; - chars_for_line = 0; - i = 0; - ptr_line = line; - while (i < chars_by_line) - { - switch (*ptr_char) - { - case '\t': - case ' ': - *(ptr_line++) = ' '; - case '\n': - case '\0': - chars_for_line = i; - break; - - default: - *(ptr_line++) = *ptr_char; - } - if (*ptr_char == '\n' || *ptr_char == '\0') - break; - ptr_char++; - i++; - } - - if (chars_for_line == 0) - chars_for_line = i; - - line[chars_for_line] = '\0'; - - /* test if we have cut a word. If it is the case we don't have to */ - /* skip the space */ - if (i == chars_by_line && chars_for_line == chars_by_line) - first_char_index += chars_for_line; - else - first_char_index += chars_for_line + 1; - - /* print the line on the screen */ - rb->lcd_putsxy(0, current_line * char_height, line); - - /* if the number of line showed on the screen is equals to the */ - /* maximum number of line we can show, we wait for a key pressed to */ - /* clear and show the remaining text. */ - current_line++; - if (current_line == lines_by_screen || *ptr_char == '\0') - { - current_line = 0; - rb->lcd_update(); - go_on = false; - while (waitkey && !go_on) - { - key = rb->button_get(true); - switch (key) - { -#ifdef HAVE_TOUCHSCREEN - case BUTTON_TOUCHSCREEN: -#endif - case PEGBOX_QUIT: - case PEGBOX_LEFT: - case PEGBOX_DOWN: - go_on = true; - break; - - default: - /*if (rb->default_event_handler(key) == SYS_USB_CONNECTED) - { - usb_detected = true; - go_on = true; - break; - }*/ - break; - } - } - rb->lcd_clear_display(); - } - } while (*ptr_char != '\0'); -} - -/***************************************************************************** -* draw_board() draws the game's current level. -******************************************************************************/ -static void draw_board(struct game_context* pb) { unsigned int r, c, type; pb->num_left = 0; char str[5]; @@ -899,10 +762,11 @@ } /***************************************************************************** -* load_level() loads the player's current level from the array and sets the +* pegbox_load_level() loads the player's current level from the array and sets the * player's position. ******************************************************************************/ -static void load_level(struct game_context* pb) { +static void pegbox_load_level(struct game_context* pb) +{ int r, c; for(r = 0; r < ROWS; r++) @@ -911,18 +775,19 @@ } /***************************************************************************** -* new_piece() creates a new piece at a specified location. The player +* pegbox_new_piece() creates a new piece at a specified location. The player * navigates through the pieces and selects one. ******************************************************************************/ -static void new_piece(struct game_context* pb, unsigned int x_loc, - unsigned int y_loc) { +static void pegbox_new_piece(struct game_context* pb, unsigned int x_loc, + unsigned int y_loc) +{ int button; bool exit = false; pb->playboard[x_loc][y_loc] = TRIANGLE; while (!exit) { - draw_board(pb); + pegbox_draw_board(pb); button = rb->button_get(true); #ifdef HAVE_TOUCHSCREEN if(button & BUTTON_TOUCHSCREEN) @@ -972,17 +837,17 @@ pb->playboard[x_loc][y_loc] = CIRCLE; break; case PEGBOX_SAVE: - exit = true; - break; + exit=true; } } } /***************************************************************************** -* move_player() moves the player and pieces and updates the board accordingly. +* pegbox_move_player() moves the player and pieces and updates the board accordingly. ******************************************************************************/ -static void move_player(struct game_context* pb, signed int x_dir, - signed int y_dir) { +static void pegbox_move_player(struct game_context* pb, signed int x_dir, + signed int y_dir) +{ unsigned int type1, type2; signed int r,c; @@ -1006,9 +871,9 @@ pb->player_col += x_dir; if (type1 == HOLE) { - draw_board(pb); + pegbox_draw_board(pb); rb->splash(HZ*2, "You fell down a hole!"); - load_level(pb); + pegbox_load_level(pb); } else if (type1 == SPACE) pb->playboard[r][c] = PLAYER; @@ -1019,7 +884,7 @@ pb->playboard[r+y_dir][c+x_dir] = WALL; else if (type1 == CROSS) { pb->playboard[r][c] = SPACE; - new_piece(pb, r+y_dir, c+x_dir); + pegbox_new_piece(pb, r+y_dir, c+x_dir); pb->playboard[r][c] = PLAYER; } else @@ -1033,326 +898,161 @@ } else { rb->splash(HZ*2, "Illegal Move!"); - load_level(pb); + pegbox_load_level(pb); } } - draw_board(pb); + pegbox_draw_board(pb); } -/***************************************************************************** -* pegbox_loadgame() loads the saved game and returns load success. -******************************************************************************/ -static bool pegbox_loadgame(struct game_context* pb) { - signed int fd; - bool loaded = false; +/*********************************************************************** +* pegbox_help() display help text +************************************************************************/ +static int pegbox_help(void) +{ + rb->lcd_setfont(FONT_UI); +#define WORDS (sizeof help_text / sizeof (char*)) + static char *help_text[] = { + "Pegbox", "", "Aim", "", "To", "beat", "each", "level", "you", "must", + "destroy", "all", "of", "the", "pegs.", "If", "two", "like", "pegs", "are", + "pushed", "into", "each", "other", "they", "disappear", "except", "for", + "triangles", "which", "form", "a", "new", "block", "and", "crosses", + "which", "allow", "you", "to", "choose", "a", "replacement", "block.", + "", "", "Controls", "", SAVE_TEXT":", "Selects", "new", "block", "", +#ifdef RESTART_TEXT + RESTART_TEXT":", "Restarts", "current", "level", "", +#endif +#ifdef LVL_UP_TEXT + LVL_UP_TEXT":", "Goes", "up", "a", "level", "", +#endif +#ifdef LVL_DOWN_TEXT + LVL_DOWN_TEXT":", "Goes", "down", "a", "level", "", +#endif + QUIT_TEXT":", "Returns", "to", "menu", + }; + static struct style_text formation[WORDS]={ + { 0, TEXT_CENTER|TEXT_UNDERLINE }, + { 2, C_RED }, + { 46, C_RED } + }; - /* open game file */ - fd = rb->open(SAVE_FILE, O_RDONLY); - if(fd < 0) return loaded; - - /* read in saved game */ - while(true) { - if(rb->read(fd, &pb->level, sizeof(pb->level)) <= 0) break; - if(rb->read(fd, &pb->playboard, sizeof(pb->playboard)) <= 0) - { - loaded = true; - break; +#ifdef HAVE_LCD_COLOR + rb->lcd_set_background(LCD_BLACK); + rb->lcd_set_foreground(LCD_WHITE); +#endif + if (display_text(WORDS, help_text, formation,NULL)==PLUGIN_USB_CONNECTED) + return PLUGIN_USB_CONNECTED; + int button; + do { + button = rb->button_get(true); + if (button == SYS_USB_CONNECTED) { + return PLUGIN_USB_CONNECTED; } - break; - } - - rb->close(fd); - return loaded; + } while( ( button == BUTTON_NONE ) + || ( button & (BUTTON_REL|BUTTON_REPEAT) ) ); + rb->lcd_setfont(FONT_SYSFIXED); + return 0; } -/***************************************************************************** -* pegbox_savegame() saves the current game state. -******************************************************************************/ -static void pegbox_savegame(struct game_context* pb) { - unsigned int fd; - /* write out the game state to the save file */ - fd = rb->open(SAVE_FILE, O_WRONLY|O_CREAT); - rb->write(fd, &pb->level, sizeof(pb->level)); - rb->write(fd, &pb->playboard, sizeof(pb->playboard)); - rb->close(fd); -} - -/***************************************************************************** -* pegbox_loaddata() loads the level and highlevel and returns load success. -******************************************************************************/ -static void pegbox_loaddata(struct game_context* pb) { - signed int fd; - - /* open game file */ - fd = rb->open(DATA_FILE, O_RDONLY); - if(fd < 0) { - pb->level = 1; - pb->highlevel = 1; - return; - } - - /* read in saved game */ - while(true) { - if(rb->read(fd, &pb->level, sizeof(pb->level)) <= 0) break; - if(rb->read(fd, &pb->highlevel, sizeof(pb->highlevel)) <= 0) break; - break; - } - - rb->close(fd); - return; -} - -/***************************************************************************** -* pegbox_savedata() saves the level and highlevel. -******************************************************************************/ -static void pegbox_savedata(struct game_context* pb) { - unsigned int fd; - - /* write out the game state to the save file */ - fd = rb->open(DATA_FILE, O_WRONLY|O_CREAT); - rb->write(fd, &pb->level, sizeof(pb->level)); - rb->write(fd, &pb->highlevel, sizeof(pb->highlevel)); - rb->close(fd); -} - -/***************************************************************************** -* pegbox_callback() is the default event handler callback which is called -* on usb connect and shutdown. -******************************************************************************/ -static void pegbox_callback(void* param) { - struct game_context* pb = (struct game_context*) param; - rb->splash(HZ, "Saving data..."); - pegbox_savedata(pb); -} - -/***************************************************************************** -* pegbox_menu() is the initial menu at the start of the game. -******************************************************************************/ -static unsigned int pegbox_menu(struct game_context* pb) { - int button; - char str[30]; - unsigned int startlevel = 1, loc = 0; - bool breakout = false, can_resume = false; +/*********************************************************************** +* pegbox_menu() is the game menu +************************************************************************/ +static unsigned int pegbox_menu(struct game_context* pb, bool ingame) +{ + rb->button_clear_queue(); + int choice = 0; - if (pb->num_left > 0 || pb->save_exist) - can_resume = true; - - while(!breakout){ -#if LCD_HEIGHT >= 80 - rb->lcd_clear_display(); - rb->lcd_bitmap(pegbox_menu_top,0,0,LCD_WIDTH, BMPHEIGHT_pegbox_menu_top); - - /* menu bitmaps */ - if (loc == 0) { - rb->lcd_bitmap_part(pegbox_menu_items, 0, ITEM_HEIGHT, ITEM_WIDTH, - MENU_X, MENU_Y, ITEM_WIDTH, ITEM_HEIGHT); - } - else { - rb->lcd_bitmap_part(pegbox_menu_items, 0, 0, ITEM_WIDTH, - MENU_X, MENU_Y, ITEM_WIDTH, ITEM_HEIGHT); - } - if (can_resume) { - if (loc == 1) { - rb->lcd_bitmap_part(pegbox_menu_items, 0, ITEM_HEIGHT*3, ITEM_WIDTH, - MENU_X, MENU_Y+ITEM_HEIGHT, ITEM_WIDTH, ITEM_HEIGHT); + if (ingame) { + MENUITEM_STRINGLIST (main_menu, "Pegbox Menu", NULL, + "Resume Game", + "Restart Level", + "Select Level", + "Help", + "Playback Control", + "Quit"); + + while (true) { + switch (rb->do_menu(&main_menu, &choice, NULL, false)) { + case 0: + pegbox_draw_board(pb); + return 0; + case 1: + pegbox_load_level(pb); + pegbox_draw_board(pb); + return 0; + case 2: + rb->set_int("Select Level", "", UNIT_INT, + &pb->level, NULL, 1, 1, + pb->highlevel, NULL); + break; + case 3: + if (pegbox_help()==PLUGIN_USB_CONNECTED) + return 1; + break; + case 4: + playback_control(NULL); + break; + case 5: + return 1; + case MENU_ATTACHED_USB: + return 1; + default: + break; } - else { - rb->lcd_bitmap_part(pegbox_menu_items, 0, ITEM_HEIGHT*2, ITEM_WIDTH, - MENU_X, MENU_Y+ITEM_HEIGHT, ITEM_WIDTH, ITEM_HEIGHT); - } } - else { - rb->lcd_bitmap_part(pegbox_menu_items, 0, ITEM_HEIGHT*4, ITEM_WIDTH, - MENU_X, MENU_Y+ITEM_HEIGHT, ITEM_WIDTH, ITEM_HEIGHT); - } - - if (loc==2) { - rb->lcd_bitmap_part(pegbox_menu_items, 0, ITEM_HEIGHT*6, ITEM_WIDTH, - MENU_X, MENU_Y+ITEM_HEIGHT*2, ITEM_WIDTH, ITEM_HEIGHT); - } - else { - rb->lcd_bitmap_part(pegbox_menu_items, 0, ITEM_HEIGHT*5, ITEM_WIDTH, - MENU_X, MENU_Y+ITEM_HEIGHT*2, ITEM_WIDTH, ITEM_HEIGHT); - } - - if (loc==3) { - rb->lcd_bitmap_part(pegbox_menu_items, 0, ITEM_HEIGHT*8, ITEM_WIDTH, - MENU_X, MENU_Y+ITEM_HEIGHT*3, ITEM_WIDTH, ITEM_HEIGHT); - } - else { - rb->lcd_bitmap_part(pegbox_menu_items, 0, ITEM_HEIGHT*7, ITEM_WIDTH, - MENU_X, MENU_Y+ITEM_HEIGHT*3, ITEM_WIDTH, ITEM_HEIGHT); - } -#else - unsigned int w,h; - rb->lcd_clear_display(); - rb->lcd_getstringsize("PegBox", &w, &h); - rb->lcd_putsxy((LCD_WIDTH-w)/2, 0, "PegBox"); - rb->lcd_putsxy((LCD_WIDTH)/4, 16, "New Game"); - rb->lcd_putsxy((LCD_WIDTH)/4, 24, "Resume"); - rb->lcd_putsxy((LCD_WIDTH)/4, 32, "Help"); - rb->lcd_putsxy((LCD_WIDTH)/4, 40, "Quit"); - - if(!can_resume) - rb->lcd_hline((LCD_WIDTH)/4, (LCD_WIDTH)/4+30, 28); - - rb->lcd_putsxy((LCD_WIDTH)/4-8, loc*8+16, "*"); - - -#endif - rb->snprintf(str, 28, "Start on level %d of %d", startlevel, - pb->highlevel); -#if LCD_HEIGHT > 110 - rb->lcd_putsxy(0, MENU_Y+4*ITEM_HEIGHT+8, str); -#elif LCD_HEIGHT > 64 - rb->lcd_putsxy(0, LCD_HEIGHT - 8, str); -#else - rb->lcd_puts_scroll(0, 7, str); -#endif - rb->lcd_update(); - - /* handle menu button presses */ - button = rb->button_get(true); - -#ifdef HAVE_TOUCHSCREEN - if(button & BUTTON_TOUCHSCREEN) - { - unsigned int result = touchscreen_map(&main_menu, - rb->button_get_data() >> 16, - rb->button_get_data() & 0xffff); - if(result != (unsigned)-1 && button & BUTTON_REL) - { - if(result == 4) - button = PEGBOX_LVL_UP; - else - { - if(loc == result) - button = PEGBOX_RIGHT; - loc = result; - } + } else { + MENUITEM_STRINGLIST (main_menu, "Pegbox Menu", NULL, + "Start Game", + "Select Level", + "Help", + "Playback Control", + "Quit"); + + while (true) { + switch (rb->do_menu(&main_menu, &choice, NULL, false)) { + case 0: + pegbox_load_level(pb); + pegbox_draw_board(pb); + return 0; + case 1: + rb->set_int("Select Level", "", UNIT_INT, + &pb->level, NULL, 1, 1, + pb->highlevel, NULL); + break; + case 2: + if (pegbox_help()==PLUGIN_USB_CONNECTED) + return 1; + break; + case 3: + playback_control(NULL); + break; + case 4: + return 1; + case MENU_ATTACHED_USB: + return 1; + default: + break; } } -#endif - - switch(button) { - case PEGBOX_SAVE: /* start playing */ - case PEGBOX_RIGHT: - if (loc == 0) { - breakout = true; - pb->level = startlevel; - load_level(pb); - } - else if (loc == 1 && can_resume) { - if(pb->save_exist) - { - rb->remove(SAVE_FILE); - pb->save_exist = false; - } - breakout = true; - } - else if (loc == 2) - display_text("How to Play\nTo beat each level, you must " - "destroy all of the pegs. If two like pegs are " - "pushed into each other they disappear except " - "for triangles which form a solid block and " - "crosses which allow you to choose a " - "replacement block.\n\n" - "Controls\n" -#if LCD_HEIGHT > 64 - RESTART_TEXT " to restart level\n" - LVL_UP_TEXT " to go up a level\n" - LVL_DOWN_TEXT " to go down a level\n" - SAVE_TEXT " to select/save\n" - QUIT_TEXT " to quit\n",true); -#else - RESTART_TEXT ": restart\n" - LVL_UP_TEXT ": level up\n" - LVL_DOWN_TEXT " level down\n" - SAVE_TEXT " select/save\n" - QUIT_TEXT " quit\n",true); -#endif - else if (loc == 3) - return PB_QUIT; - break; - - case PEGBOX_QUIT: /* quit program */ - return PB_QUIT; - - case (PEGBOX_UP|BUTTON_REPEAT): - case PEGBOX_UP: - if (loc <= 0) - loc = 3; - else - loc--; - if (!can_resume && loc == 1) { - loc = 0; - } - break; - - - case (PEGBOX_DOWN|BUTTON_REPEAT): - case PEGBOX_DOWN: - if (loc >= 3) - loc = 0; - else - loc++; - if (!can_resume && loc == 1) { - loc = 2; - } - break; - - case (PEGBOX_LVL_UP|BUTTON_REPEAT): - case PEGBOX_LVL_UP: /* increase starting level */ - if(startlevel >= pb->highlevel) { - startlevel = 1; - } else { - startlevel++; - } - break; - -/* only for targets with enough buttons */ -#ifdef PEGBOX_LVL_DOWN - case (PEGBOX_LVL_DOWN|BUTTON_REPEAT): - case PEGBOX_LVL_DOWN: /* decrease starting level */ - if(startlevel <= 1) { - startlevel = pb->highlevel; - } else { - startlevel--; - } - break; -#endif - default: - if(rb->default_event_handler_ex(button, pegbox_callback, - (void*) pb) == SYS_USB_CONNECTED) - return PB_USB; - break; - } - } - draw_board(pb); - - return 0; } -/***************************************************************************** -* pegbox() is the main game subroutine, it returns the final game status. -******************************************************************************/ -static int pegbox(struct game_context* pb) { - int temp_var; - - /******************** - * menu * - ********************/ - temp_var = pegbox_menu(pb); - if (temp_var == PB_QUIT || temp_var == PB_USB) - return temp_var; +/*********************************************************************** +* pegbox_main() is the main game subroutine +************************************************************************/ +static int pegbox_main(struct game_context* pb) +{ + int button; + if (pegbox_menu(pb, false)==1) { + return 1; + } + while (true) { - temp_var = rb->button_get(true); + button = rb->button_get(true); #ifdef HAVE_TOUCHSCREEN - if(temp_var & BUTTON_TOUCHSCREEN) + if(button & BUTTON_TOUCHSCREEN) { pegbox_raster_btn.two_d_from.y = pb->player_row; pegbox_raster_btn.two_d_from.x = pb->player_col; @@ -1361,57 +1061,56 @@ touchscreen_raster_map_button(&pegbox_raster_btn, rb->button_get_data() >> 16, rb->button_get_data() & 0xffff, - temp_var); + button); if(ret.action == TS_ACTION_TWO_D_MOVEMENT) - move_player(pb, ret.to.x - ret.from.x, ret.to.y - ret.from.y); + pegbox_move_player(pb, ret.to.x - ret.from.x, ret.to.y - ret.from.y); } #endif - switch(temp_var){ + switch(button){ case PEGBOX_LEFT: /* move cursor left */ case (PEGBOX_LEFT|BUTTON_REPEAT): - move_player(pb, -1, 0); + pegbox_move_player(pb, -1, 0); break; case PEGBOX_RIGHT: /* move cursor right */ case (PEGBOX_RIGHT|BUTTON_REPEAT): - move_player(pb, 1, 0); + pegbox_move_player(pb, 1, 0); break; case PEGBOX_DOWN: /* move cursor down */ case (PEGBOX_DOWN|BUTTON_REPEAT): - move_player(pb, 0, 1); + pegbox_move_player(pb, 0, 1); break; case PEGBOX_UP: /* move cursor up */ case (PEGBOX_UP|BUTTON_REPEAT): - move_player(pb, 0, -1); + pegbox_move_player(pb, 0, -1); break; - case PEGBOX_SAVE: /* save and end game */ - rb->splash(HZ, "Saving game..."); - pegbox_savegame(pb); - /* fall through to PEGBOX_QUIT */ - case PEGBOX_QUIT: - return PB_END; - + if (pegbox_menu(pb, true)==1) { + return 1; + } +#ifdef PEGBOX_RESTART case PEGBOX_RESTART: - load_level(pb); - draw_board(pb); + pegbox_load_level(pb); + pegbox_draw_board(pb); break; +#endif +#ifdef PEGBOX_LVL_UP case (PEGBOX_LVL_UP|BUTTON_REPEAT): case PEGBOX_LVL_UP: - if(pb->level >= pb->highlevel) { + if (pb->level >= pb->highlevel) { pb->level = 1; } else { pb->level++; } - load_level(pb); - draw_board(pb); + pegbox_load_level(pb); + pegbox_draw_board(pb); break; +#endif -/* only for targets with enough buttons */ #ifdef PEGBOX_LVL_DOWN case (PEGBOX_LVL_DOWN|BUTTON_REPEAT): case PEGBOX_LVL_DOWN: @@ -1420,45 +1119,43 @@ } else { pb->level--; } - load_level(pb); - draw_board(pb); + pegbox_load_level(pb); + pegbox_draw_board(pb); break; #endif - } - if(pb->num_left == 0) { + if (pb->num_left == 0) { rb->splash(HZ*2, "Nice Pegging!"); - if(pb->level == NUM_LEVELS) { - draw_board(pb); - rb->splash(HZ*2, "You Won!"); - break; + if (pb->level == NUM_LEVELS) { + pegbox_draw_board(pb); + rb->splash(HZ*2, "Congratulations!"); + rb->splash(HZ*2, "You have finished the game!"); + if (pegbox_menu(pb,false)==1) { + return 1; + } } else { pb->level++; - load_level(pb); - draw_board(pb); + pegbox_load_level(pb); + pegbox_draw_board(pb); } if(pb->level > pb->highlevel) pb->highlevel = pb->level; - + } } - return PLUGIN_OK; } - /***************************************************************************** * plugin entry point. ******************************************************************************/ -enum plugin_status plugin_start(const void* parameter) { - bool exit = false; - struct game_context pb; - +enum plugin_status plugin_start(const void* parameter) +{ (void)parameter; - +#ifdef HAVE_LCD_BITMAP rb->lcd_setfont(FONT_SYSFIXED); #if LCD_DEPTH > 1 rb->lcd_set_backdrop(NULL); @@ -1467,35 +1164,20 @@ rb->lcd_set_foreground(LCD_WHITE); rb->lcd_set_background(BG_COLOR); #endif - - rb->splash(0, "Loading..."); - pegbox_loaddata(&pb); - pb.save_exist = pegbox_loadgame(&pb); - pb.num_left = 0; - rb->lcd_clear_display(); - - while(!exit) { - switch(pegbox(&pb)){ - case PB_END: - break; - - case PB_USB: - rb->lcd_setfont(FONT_UI); - return PLUGIN_USB_CONNECTED; - - case PB_QUIT: - rb->splash(HZ, "Saving data..."); - pegbox_savedata(&pb); - exit = true; - break; - - default: - break; - } - } - + struct game_context pb; + pb.level=1; + pb.highlevel=1; + struct configdata config[] = { + {TYPE_INT, 1, NUM_LEVELS, { .int_p = &(pb.level) }, "level", NULL}, + {TYPE_INT, 1, NUM_LEVELS, { .int_p = &(pb.highlevel) }, "highlevel", NULL}, + }; + configfile_load(CONFIG_FILE_NAME,config,2,0); + pegbox_main(&pb); + configfile_save(CONFIG_FILE_NAME,config,2,0); rb->lcd_setfont(FONT_UI); +#endif /* HAVE_LCD_BITMAP */ + return PLUGIN_OK; }