diff --git a/apps/plugins/bitmaps/native/SOURCES b/apps/plugins/bitmaps/native/SOURCES index 357480a..84b3802 100644 --- a/apps/plugins/bitmaps/native/SOURCES +++ b/apps/plugins/bitmaps/native/SOURCES @@ -5,9 +5,7 @@ brickmania_gameover.112x54x16.bmp #if LCD_WIDTH >= 220 /* common to all big lcds */ brickmania_ball.5x5x16.bmp -brickmania_menu_items.220x176x16.bmp #if LCD_WIDTH >= 320 /* Ipod Video */ -brickmania_menu_bg.320x240x16.bmp brickmania_bricks.320x240x16.bmp brickmania_pads.320x240x16.bmp brickmania_break.320x240x16.bmp @@ -17,49 +15,34 @@ brickmania_bricks.220x176x16.bmp brickmania_pads.220x176x16.bmp brickmania_break.220x176x16.bmp brickmania_powerups.220x176x16.bmp -#if LCD_HEIGHT == 320 -brickmania_menu_bg.240x320x16.bmp -#elif LCD_HEIGHT == 176 -brickmania_menu_bg.220x176x16.bmp -#endif #endif #elif LCD_WIDTH >= 176 brickmania_ball.5x5x16.bmp -brickmania_menu_items.176x132x16.bmp brickmania_bricks.176x132x16.bmp -brickmania_menu_bg.176x132x16.bmp brickmania_pads.176x132x16.bmp brickmania_powerups.176x132x16.bmp brickmania_break.176x132x16.bmp #elif LCD_WIDTH >= 160 brickmania_ball.5x5x16.bmp -brickmania_menu_items.160x128x16.bmp brickmania_bricks.160x128x16.bmp -brickmania_menu_bg.160x128x16.bmp brickmania_pads.160x128x16.bmp brickmania_powerups.160x128x16.bmp brickmania_break.160x128x16.bmp #elif LCD_WIDTH >= 132 brickmania_ball.4x4x16.bmp -brickmania_menu_items.132x80x16.bmp brickmania_bricks.132x80x16.bmp -brickmania_menu_bg.132x80x16.bmp brickmania_pads.132x80x16.bmp brickmania_powerups.132x80x16.bmp brickmania_break.132x80x16.bmp #elif LCD_WIDTH >= 128 brickmania_ball.4x4x16.bmp -brickmania_menu_items.132x80x16.bmp brickmania_bricks.128x128x16.bmp -brickmania_menu_bg.128x128x16.bmp brickmania_pads.132x80x16.bmp brickmania_powerups.132x80x16.bmp brickmania_break.132x80x16.bmp #endif /* different colour displays */ #elif LCD_DEPTH > 1 brickmania_gameover.86x43x2.bmp -brickmania_menu_items.160x128x2.bmp -brickmania_menu_bg.160x128x2.bmp brickmania_pads.160x128x2.bmp brickmania_powerups.160x128x2.bmp #if (LCD_WIDTH >= 160) @@ -74,7 +57,6 @@ brickmania_bricks.128x96x2.bmp #endif #else /* mono */ brickmania_gameover.59x30x1.bmp -brickmania_menu_items.112x64x1.bmp brickmania_bricks.112x64x1.bmp brickmania_ball.3x3x1.bmp brickmania_pads.112x64x1.bmp @@ -329,62 +311,40 @@ minesweeper_tiles.8x8x1.bmp #ifdef HAVE_LCD_COLOR /* currently only LCD_WIDTH is important, e.g. Nano and e200 use the same set */ #if LCD_WIDTH >= 320 -pegbox_menu_top.320x68x16.bmp -pegbox_menu_items.120x32x16.bmp pegbox_pieces.24x24x16.bmp pegbox_header.320x40x16.bmp #elif LCD_WIDTH >= 240 -pegbox_menu_top.240x80x16.bmp -pegbox_menu_items.120x32x16.bmp pegbox_pieces.16x16x16.bmp pegbox_header.240x40x16.bmp #elif LCD_WIDTH >= 220 -pegbox_menu_top.220x60x16.bmp -pegbox_menu_items.70x20x16.bmp pegbox_pieces.16x16x16.bmp pegbox_header.220x40x16.bmp #elif LCD_WIDTH >= 176 -pegbox_menu_top.176x46x16.bmp -pegbox_menu_items.60x17x16.bmp pegbox_pieces.12x12x16.bmp pegbox_header.176x28x16.bmp #elif LCD_WIDTH >= 160 -pegbox_menu_top.160x42x16.bmp -pegbox_menu_items.60x17x16.bmp pegbox_pieces.12x12x16.bmp pegbox_header.160x24x16.bmp #elif LCD_WIDTH >= 132 -pegbox_menu_top.132x17x16.bmp -pegbox_menu_items.60x13x16.bmp pegbox_pieces.9x9x16.bmp pegbox_header.22x80x16.bmp #elif LCD_WIDTH >= 128 -pegbox_menu_top.128x42x16.bmp -pegbox_menu_items.60x17x16.bmp pegbox_pieces.10x10x16.bmp pegbox_header.128x42x16.bmp #endif /* different colour displays */ #elif LCD_DEPTH > 1 #if LCD_WIDTH >= 160 -pegbox_menu_top.160x42x2.bmp -pegbox_menu_items.60x17x2.bmp pegbox_pieces.12x12x2.bmp pegbox_header.160x24x2.bmp #elif LCD_WIDTH >= 138 -pegbox_menu_top.138x31x2.bmp -pegbox_menu_items.60x17x2.bmp pegbox_pieces.10x10x2.bmp pegbox_header.138x26x2.bmp #elif LCD_WIDTH >= 128 -pegbox_menu_top.128x27x2.bmp -pegbox_menu_items.60x15x2.bmp pegbox_pieces.10x10x2.bmp pegbox_header.128x16x2.bmp #endif /* different greyscale displays */ #else /* mono */ #if LCD_WIDTH >= 160 -pegbox_menu_top.160x42x1.bmp -pegbox_menu_items.60x17x1.bmp pegbox_pieces.12x12x1.bmp pegbox_header.160x24x1.bmp #elif LCD_WIDTH >= 112 diff --git a/apps/plugins/brickmania.c b/apps/plugins/brickmania.c index 15c1641..760fb7d 100644 --- a/apps/plugins/brickmania.c +++ b/apps/plugins/brickmania.c @@ -22,6 +22,7 @@ #include "plugin.h" #include "lib/configfile.h" /* Part of libplugin */ #include "lib/helper.h" +#include "lib/playback_control.h" PLUGIN_HEADER @@ -220,21 +221,25 @@ CONFIG_KEYPAD == SANSA_M200_PAD 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, + BM_HIGHSCORE, + BM_PLAYBACK_CONTROL, + BM_QUIT }; +MENUITEM_STRINGLIST (main_menu, "Brickmania", NULL, + "Start", + "Resume", + "Help", + "High Score", + "Playback Control", + "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 @@ -246,18 +251,9 @@ enum menu_items { #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 @@ -273,8 +269,6 @@ enum menu_items { #define TOPMARGIN 30 #define BMPYOFS_start 110 -#define HIGHSCORE_XPOS 57 -#define HIGHSCORE_YPOS 88 #define STRINGPOS_FINISH 140 #define STRINGPOS_CONGRATS 157 @@ -298,8 +292,6 @@ enum menu_items { #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 @@ -320,8 +312,6 @@ enum menu_items { #else #define BMPYOFS_start 66 #endif -#define HIGHSCORE_XPOS 10 -#define HIGHSCORE_YPOS 38 #define STRINGPOS_FINISH 110 #define STRINGPOS_CONGRATS 100 @@ -339,8 +329,6 @@ enum menu_items { #define TOPMARGIN 10 #define BMPYOFS_start 30 -#define HIGHSCORE_XPOS 68 -#define HIGHSCORE_YPOS 8 #define STRINGPOS_FINISH 55 #define STRINGPOS_CONGRATS 45 @@ -359,8 +347,6 @@ enum menu_items { #define TOPMARGIN 15 #define BMPYOFS_start 70 -#define HIGHSCORE_XPOS 8 -#define HIGHSCORE_YPOS 36 #define STRINGPOS_FINISH 55 #define STRINGPOS_CONGRATS 45 @@ -378,8 +364,6 @@ enum menu_items { #define TOPMARGIN 10 #define BMPYOFS_start 51 -#define HIGHSCORE_XPOS 73 -#define HIGHSCORE_YPOS 25 #define STRINGPOS_FINISH 54 #define STRINGPOS_CONGRATS 44 @@ -397,8 +381,6 @@ enum menu_items { #define TOPMARGIN 10 #define BMPYOFS_start 42 -#define HIGHSCORE_XPOS 65 -#define HIGHSCORE_YPOS 25 #define STRINGPOS_FINISH 54 #define STRINGPOS_CONGRATS 44 @@ -416,8 +398,6 @@ enum menu_items { #define TOPMARGIN 10 #define BMPYOFS_start 22 -#define HIGHSCORE_XPOS 0 -#define HIGHSCORE_YPOS 0 #define STRINGPOS_FINISH 54 #define STRINGPOS_CONGRATS 44 @@ -437,8 +417,6 @@ enum menu_items { #define TOPMARGIN 21 #define BMPYOFS_start 58 -#define HIGHSCORE_XPOS 7 -#define HIGHSCORE_YPOS 36 #define STRINGPOS_FINISH 110 #define STRINGPOS_CONGRATS 110 @@ -454,11 +432,6 @@ enum menu_items { #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 @@ -467,20 +440,6 @@ enum menu_items { #endif -#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} -}; -static struct ts_mappings main_menu = {main_menu_items, 4}; -#endif - - int levels_num = 29; static unsigned char levels[29][8][10] = { @@ -907,205 +866,68 @@ void sleep (int secs) } +/* forward declaration, used in game_menu */ +int help(int when); + #define HIGH_SCORE "brickmania.score" -#define MENU_LENGTH 4 int game_menu(int when) { - 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); - - 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); + /* clear any previous button presses (especially when coming from + * game over, but it doesn't hurt to do it always) + */ + rb->button_clear_queue(); + + int choice = 0; + + while (1) { + choice = rb->do_menu(&main_menu, &choice, NULL, false); + + switch (choice) { + case BM_START: + score=0; + vscore=0; + life=2; + cur_level=0; + int_game(1); + return choice; + + case BM_RESUME: + /* resume if we can */ + if (when==1) + return choice; 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); - } - + rb->splash(HZ/2, "Nothing to resume!"); + break; - 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); + case BM_HELP: + if (help(when)==1) + return BM_QUIT; 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); -#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->lcd_update(); + return choice; - 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; - } - } -#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; - } + case BM_HIGHSCORE: + rb->splashf(HZ*2, "High Score: %d", highscore); break; - case DOWN: - case DOWN | BUTTON_REPEAT: - if (cur==MENU_LENGTH-1) - cur = 0; - else - cur++; - if (when==0 && cur==1) { - cur=2; - } + case BM_PLAYBACK_CONTROL: + playback_control(NULL); 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; - } - break; -#ifdef RC_QUIT - case RC_QUIT: -#endif - case QUIT: - return 3; - break; + case BM_QUIT: + case MENU_ATTACHED_USB: + return BM_QUIT; + + case GO_TO_ROOT: + case GO_TO_PREVIOUS: + /* Resume if we can resume, otherwise quit */ + if (when==1) + return BM_RESUME; + else + return BM_QUIT; default: - if(rb->default_event_handler(button) == SYS_USB_CONNECTED) - return 3; break; } - - rb->yield(); } } @@ -1202,20 +1024,12 @@ int help(int when) #endif case QUIT: switch (game_menu(when)) { - case 0: - cur_level=0; - life=2; - int_game(1); - break; - case 1: + case BM_RESUME: con_game=1; break; - case 2: - if (help(when)==1) - return 1; - break; - case 3: + case BM_QUIT: return 1; + default: break; } return 0; @@ -1299,19 +1113,12 @@ int game_loop(void) 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; + case BM_RESUME: + con_game=1; break; - case 2: - if (help(0) == 1) return 1; - break; - case 3: + case BM_QUIT: return 1; + default: break; } @@ -1865,19 +1672,12 @@ int game_loop(void) } switch(game_menu(0)) { - case 0: - life=2; - cur_level=0; - int_game(1); - break; - case 1: + case BM_RESUME: con_game=1; break; - case 2: - if (help(0)==1) return 1; - break; - case 3: + case BM_QUIT: return 1; + default: break; } } @@ -2009,22 +1809,14 @@ int game_loop(void) #endif case QUIT: switch(game_menu(1)) { - case 0: - life=2; - cur_level=0; - int_game(1); - break; - case 1: + case BM_RESUME: for(k=0;klcd_clear_display(); } } break; diff --git a/apps/plugins/flipit.c b/apps/plugins/flipit.c index ae0b1db..a63b358 100644 --- a/apps/plugins/flipit.c +++ b/apps/plugins/flipit.c @@ -19,6 +19,7 @@ * ****************************************************************************/ #include "plugin.h" +#include "lib/playback_control.h" PLUGIN_HEADER @@ -506,18 +507,28 @@ static void move_cursor(int x, int y) rb->lcd_update(); } +static void draw_board(void) +{ + int i; + + rb->lcd_clear_display(); + for (i=0; i<20; i++) { + draw_spot(i); + } + rb->lcd_update(); +} + /* initialize the board */ static void flipit_init(void) { int i; - rb->lcd_clear_display(); for (i=0; i<20; i++) { spots[i]=1; toggle[i]=1; - draw_spot(i); } - rb->lcd_update(); + + draw_board(); for (i=0; i<20; i++) { cursor_pos = (rb->rand() % 20); @@ -546,8 +557,23 @@ static bool flipit_loop(void) case FLIPIT_RC_QUIT: #endif case FLIPIT_QUIT: - /* get out of here */ - return PLUGIN_OK; + switch (playback_control_or_quit (NULL)) + { + case PBC_OR_QUIT_QUIT: + return PLUGIN_OK; + + case PBC_OR_QUIT_USB_CONNECTED: + return PLUGIN_USB_CONNECTED; + + default: + case PBC_OR_QUIT_RESUME: + break; + } + draw_board(); + draw_cursor(); + draw_info_panel(); + rb->lcd_update(); + break; case FLIPIT_SHUFFLE: /* mix up the pieces */ diff --git a/apps/plugins/lib/playback_control.c b/apps/plugins/lib/playback_control.c index 7c28230..6ff7a63 100644 --- a/apps/plugins/lib/playback_control.c +++ b/apps/plugins/lib/playback_control.c @@ -116,3 +116,42 @@ bool playback_control(struct viewport parent[NB_SCREENS]) parentvp = parent; return rb->do_menu(&playback_control_menu, NULL, parent, false) == MENU_ATTACHED_USB; } + +enum pbc_or_quit_ret +playback_control_or_quit(struct viewport parent[NB_SCREENS]) +{ + MENUITEM_STRINGLIST(pbc_or_quit_menu, "Really quit?", NULL, + "Playback Control", + "Resume", + "Quit"); + + int selection = 2; + + while(1) + { + selection = rb->do_menu(&pbc_or_quit_menu, &selection, parent, false); + + switch (selection) + { + case 0: + /* if the usb was plugged in during playback_control, + * the plugin should quit */ + if (playback_control(parent)) + return PBC_OR_QUIT_USB_CONNECTED; + + break; + + case GO_TO_PREVIOUS: + case GO_TO_ROOT: + case 1: + default: + return PBC_OR_QUIT_RESUME; + + case 2: + return PBC_OR_QUIT_QUIT; + + case MENU_ATTACHED_USB: + return PBC_OR_QUIT_USB_CONNECTED; + } + } +} diff --git a/apps/plugins/lib/playback_control.h b/apps/plugins/lib/playback_control.h index 4371961..169d379 100644 --- a/apps/plugins/lib/playback_control.h +++ b/apps/plugins/lib/playback_control.h @@ -32,4 +32,17 @@ void playback_control_init(struct viewport parent[NB_SCREENS]); /* Use this if your menu still uses the old menu api */ bool playback_control(struct viewport parent[NB_SCREENS]); +enum pbc_or_quit_ret +{ + PBC_OR_QUIT_RESUME, + PBC_OR_QUIT_QUIT, + PBC_OR_QUIT_USB_CONNECTED +}; + +/* Use this in plugins to add an optional Playback Control menu + instead of directly quitting. +*/ +enum pbc_or_quit_ret +playback_control_or_quit(struct viewport parent[NB_SCREENS]); + #endif /* __PLAYBACK_CONTROL_H__ */ diff --git a/apps/plugins/maze.c b/apps/plugins/maze.c index 881d804..73ce595 100644 --- a/apps/plugins/maze.c +++ b/apps/plugins/maze.c @@ -32,6 +32,7 @@ #include "plugin.h" #include "lib/helper.h" +#include "lib/playback_control.h" PLUGIN_HEADER @@ -573,7 +574,22 @@ enum plugin_status plugin_start(const void* parameter) break; case MAZE_QUIT: /* quit plugin */ - quit=1; + switch (playback_control_or_quit(NULL)) + { + case PBC_OR_QUIT_QUIT: + quit = 1; + break; + case PBC_OR_QUIT_USB_CONNECTED: + quit = 2; + break; + default: + case PBC_OR_QUIT_RESUME: + FOR_NB_SCREENS(i) + maze_draw(&maze, rb->screens[i]); + + break; + } + break; default: if (rb->default_event_handler(button) == SYS_USB_CONNECTED) { diff --git a/apps/plugins/oscilloscope.c b/apps/plugins/oscilloscope.c index 5d55bb4..85c7b03 100644 --- a/apps/plugins/oscilloscope.c +++ b/apps/plugins/oscilloscope.c @@ -23,6 +23,7 @@ #include "plugin.h" #include "lib/helper.h" +#include "lib/playback_control.h" #ifdef HAVE_LCD_BITMAP #include "lib/xlcd.h" @@ -763,7 +764,24 @@ enum plugin_status plugin_start(const void* parameter) case OSCILLOSCOPE_RC_QUIT: #endif case OSCILLOSCOPE_QUIT: - exit = true; + switch (playback_control_or_quit (NULL)) + { + case PBC_OR_QUIT_QUIT: + exit = true; + break; + + case PBC_OR_QUIT_USB_CONNECTED: + return PLUGIN_USB_CONNECTED; + + default: + case PBC_OR_QUIT_RESUME: + rb->lcd_clear_display(); + rb->lcd_update(); + last_pos = 0; + last_tick = 0; + break; + } + break; case OSCILLOSCOPE_ADVMODE: diff --git a/apps/plugins/pegbox.c b/apps/plugins/pegbox.c index 514b92e..69441a4 100644 --- a/apps/plugins/pegbox.c +++ b/apps/plugins/pegbox.c @@ -20,18 +20,11 @@ ****************************************************************************/ #include "plugin.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 */ @@ -523,29 +516,9 @@ PLUGIN_HEADER #define TEXT_BG LCD_RGBPACK(189,189,189) #endif - #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 }; @@ -1114,217 +1087,99 @@ static void pegbox_savedata(struct game_context* pb) { 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); -} +enum menu_items { + PB_MENU_START, + PB_MENU_RESUME, + PB_MENU_HELP, + PB_MENU_PLAYBACK, + PB_MENU_QUIT +}; + +MENUITEM_STRINGLIST (main_menu, "Pegbox", NULL, + "Start", + "Resume", + "Help", + "Playback Control", + "Quit"); + /***************************************************************************** * 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; - + if (pb->num_left > 0 || pb->save_exist) can_resume = true; + + int selection = 0; 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); - } - 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(); + selection = rb->do_menu(&main_menu, &selection, NULL, false); - /* handle menu button presses */ - button = rb->button_get(true); + switch(selection) { + case PB_MENU_START: + rb->set_int("Starting Level", "", UNIT_INT, &pb->level, + NULL, 1, 1, pb->highlevel, NULL); + breakout = true; + load_level(pb); + break; -#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; - } - } - } -#endif + case GO_TO_ROOT: + case GO_TO_PREVIOUS: + /* resume if we can (by falling through), otherwise exit */ + if (!can_resume) + return PB_QUIT; - 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) - { + case PB_MENU_RESUME: + if (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" + } + else + rb->splash(HZ, "Nothing to resume!"); + + break; + + case PB_MENU_HELP: + 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); + 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" #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); + 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" #endif - else if (loc == 3) - return PB_QUIT; + , true); 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; - } + case PB_MENU_PLAYBACK: + playback_control(NULL); break; + case MENU_ATTACHED_USB: + rb->splash(0, "Saving data..."); + pegbox_savedata(pb); + return PB_USB; - 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 + case PB_MENU_QUIT: default: - if(rb->default_event_handler_ex(button, pegbox_callback, - (void*) pb) == SYS_USB_CONNECTED) - return PB_USB; - break; + return PB_QUIT; } } diff --git a/apps/plugins/robotfindskitten.c b/apps/plugins/robotfindskitten.c index 7ae5721..8f00f1b 100644 --- a/apps/plugins/robotfindskitten.c +++ b/apps/plugins/robotfindskitten.c @@ -30,6 +30,7 @@ #include "plugin.h" #include "lib/pluginlib_actions.h" +#include "lib/playback_control.h" /* This macros must always be included. Should be placed at the top by convention, although the actual position doesn't matter */ @@ -668,8 +669,25 @@ static void play_game() const struct button_mapping *plugin_contexts[] = {generic_directions, generic_actions}; #endif - while (input != RFK_QUIT && exit_rfk == false) + while (exit_rfk == false) { + if (input == RFK_QUIT) + { + switch (playback_control_or_quit (NULL)) + { + case PBC_OR_QUIT_QUIT: + case PBC_OR_QUIT_USB_CONNECTED: + exit_rfk = true; + continue; + + default: + case PBC_OR_QUIT_RESUME: + break; + } + + initialize_screen(); + } + process_input(input); /*Redraw robot, where applicable. We're your station, robot.*/ diff --git a/apps/plugins/rockblox.c b/apps/plugins/rockblox.c index 11fd118..35762b8 100644 --- a/apps/plugins/rockblox.c +++ b/apps/plugins/rockblox.c @@ -24,6 +24,7 @@ #include "lib/highscore.h" #include "lib/playergfx.h" #include "lib/helper.h" +#include "lib/playback_control.h" PLUGIN_HEADER @@ -751,16 +752,8 @@ static void show_highscores (void) } #endif -static void init_rockblox (void) +static void draw_background (void) { - highscore_update(score, level, Highest, MAX_HIGH_SCORES); - - level = 1; - lines = 0; - score = 0; - gameover = false; - nf = t_rand (BLOCKS_NUM); - init_board (); #ifdef HAVE_LCD_BITMAP rb->lcd_bitmap (rockblox_background, 0, 0, LCD_WIDTH, LCD_HEIGHT); #else /* HAVE_LCD_CHARCELLS */ @@ -778,6 +771,19 @@ static void init_rockblox (void) #endif } +static void init_rockblox (void) +{ + highscore_update(score, level, Highest, MAX_HIGH_SCORES); + + level = 1; + lines = 0; + score = 0; + gameover = false; + nf = t_rand (BLOCKS_NUM); + init_board (); + draw_background (); +} + static inline int level_speed(int level) { #if BOARD_HEIGHT == 20 @@ -1101,7 +1107,22 @@ static int rockblox_loop (void) case ROCKBLOX_RC_OFF: #endif case ROCKBLOX_OFF: - return PLUGIN_OK; + switch (playback_control_or_quit (NULL)) + { + case PBC_OR_QUIT_QUIT: + return PLUGIN_OK; + + case PBC_OR_QUIT_USB_CONNECTED: + return PLUGIN_USB_CONNECTED; + + default: + case PBC_OR_QUIT_RESUME: + break; + } + draw_background (); + refresh_board (); + draw_next_block (); + break; #if defined(ROCKBLOX_ROTATE) case ROCKBLOX_ROTATE: diff --git a/apps/plugins/rockblox1d.c b/apps/plugins/rockblox1d.c index d7779fa..df12929 100644 --- a/apps/plugins/rockblox1d.c +++ b/apps/plugins/rockblox1d.c @@ -21,6 +21,7 @@ ****************************************************************************/ #include "plugin.h" +#include "lib/playback_control.h" PLUGIN_HEADER @@ -166,43 +167,29 @@ void draw_brick(int pos, int length) { } } -enum plugin_status plugin_start(const void* parameter) -{ - int i; - int f_width, f_height; - int score_x; +int f_width, f_height; +int score_x; - bool quit = false; - int button; - - int cycletime = 300; - int end; +void draw_next_brick(int type_next_brick) { + int i; - int pos_cur_brick = 0; - int type_cur_brick = 0; - int type_next_brick = 0; - - unsigned long int score = 34126; - char score_buf[10]; - - (void)parameter; + rb->lcd_set_drawmode(DRMODE_BG|DRMODE_INVERSEVID); + rb->lcd_fillrect(NEXT_X, NEXT_Y, WIDTH, WIDTH * 4 + 4); + rb->lcd_set_drawmode(DRMODE_SOLID); -#if LCD_DEPTH > 1 - rb->lcd_set_backdrop(NULL); - rb->lcd_set_background(LCD_BLACK); - rb->lcd_set_foreground(LCD_WHITE); -#endif + for (i = 0; i < type_next_brick; ++i) { + rb->lcd_fillrect(NEXT_X, + NEXT_Y + ((type_next_brick % 2) ? (int)(WIDTH/2) : + ((type_next_brick == 2) ? (WIDTH+1) : 0)) + (WIDTH*i) + i, + WIDTH, WIDTH); + } +} - rb->lcd_setfont(FONT_SYSFIXED); - +void draw_background(void) { rb->lcd_getstringsize("100000000", &f_width, &f_height); - + rb->lcd_clear_display(); - - /*********** - ** Draw EVERYTHING - */ - + /* Playing filed box */ rb->lcd_vline(CENTER_X-2, CENTER_Y, CENTER_Y + (WIDTH*TILES+TILES)); rb->lcd_vline(CENTER_X + WIDTH + 1, CENTER_Y, @@ -219,7 +206,7 @@ enum plugin_status plugin_start(const void* parameter) rb->lcd_putsxy(2, SCORE_Y-6-f_height, "score"); #endif score_x = SCORE_X; - + /* Next box */ rb->lcd_getstringsize("next", &f_width, NULL); #if (LCD_WIDTH > LCD_HEIGHT) && !(LCD_WIDTH > 132) @@ -229,6 +216,34 @@ enum plugin_status plugin_start(const void* parameter) rb->lcd_drawrect(NEXT_X-5, NEXT_Y-5, WIDTH+10, NEXT_H+10); rb->lcd_putsxy(NEXT_X-5, NEXT_Y-5-f_height-1, "next"); #endif +} + +enum plugin_status plugin_start(const void* parameter) +{ + bool quit = false; + int button; + + int cycletime = 300; + int end; + + int pos_cur_brick = 0; + int type_cur_brick = 0; + int type_next_brick = 0; + + unsigned long int score = 34126; + char score_buf[10]; + + (void)parameter; + +#if LCD_DEPTH > 1 + rb->lcd_set_backdrop(NULL); + rb->lcd_set_background(LCD_BLACK); + rb->lcd_set_foreground(LCD_WHITE); +#endif + + rb->lcd_setfont(FONT_SYSFIXED); + + draw_background(); /*********** ** GAMELOOP @@ -243,16 +258,7 @@ enum plugin_status plugin_start(const void* parameter) draw_brick(pos_cur_brick, type_cur_brick); - /* Draw next brick */ - rb->lcd_set_drawmode(DRMODE_BG|DRMODE_INVERSEVID); - rb->lcd_fillrect(NEXT_X, NEXT_Y, WIDTH, WIDTH * 4 + 4); - rb->lcd_set_drawmode(DRMODE_SOLID); - - for (i = 0; i < type_next_brick; ++i) { - rb->lcd_fillrect(NEXT_X, - NEXT_Y + ((type_next_brick % 2) ? (int)(WIDTH/2) : ((type_next_brick == 2) ? (WIDTH+1) : 0)) + (WIDTH*i) + i, - WIDTH, WIDTH); - } + draw_next_brick(type_next_brick); /* Score box */ rb->snprintf(score_buf, sizeof(score_buf), "%8ld0", score); @@ -268,7 +274,21 @@ enum plugin_status plugin_start(const void* parameter) cycletime = 100; break; case ONEDROCKBLOX_QUIT: - quit = true; + rb->button_clear_queue(); + switch (playback_control_or_quit (NULL)) + { + case PBC_OR_QUIT_QUIT: + case PBC_OR_QUIT_USB_CONNECTED: + quit = true; + break; + default: + case PBC_OR_QUIT_RESUME: + cycletime = 300; + break; + } + draw_background(); + draw_brick(pos_cur_brick, type_cur_brick); + draw_next_brick(type_next_brick); break; default: cycletime = 300; diff --git a/apps/plugins/rocklife.c b/apps/plugins/rocklife.c index 2d162fc..8fd31fe 100644 --- a/apps/plugins/rocklife.c +++ b/apps/plugins/rocklife.c @@ -63,6 +63,7 @@ #include "plugin.h" #include "lib/pluginlib_actions.h" #include "lib/helper.h" +#include "lib/playback_control.h" PLUGIN_HEADER @@ -397,7 +398,6 @@ static void next_generation(char *pgrid, char *pnext_grid){ enum plugin_status plugin_start(const void* parameter) { int button = 0; - int quit = 0; int stop = 0; int pattern = 0; char *pgrid; @@ -424,7 +424,7 @@ enum plugin_status plugin_start(const void* parameter) setup_grid(pgrid, pattern++); show_grid(pgrid); - while(!quit) { + while(1) { button = pluginlib_getaction(TIMEOUT_BLOCK, plugin_contexts, 2); switch(button) { case ROCKLIFE_NEXT: @@ -474,9 +474,18 @@ enum plugin_status plugin_start(const void* parameter) show_grid(pgrid); break; case ROCKLIFE_QUIT: - /* quit plugin */ - quit=true; - return PLUGIN_OK; + switch (playback_control_or_quit (NULL)) { + case PBC_OR_QUIT_QUIT: + backlight_use_settings(); + return PLUGIN_OK; + case PBC_OR_QUIT_USB_CONNECTED: + backlight_use_settings(); + return PLUGIN_USB_CONNECTED; + default: + case PBC_OR_QUIT_RESUME: + break; + } + show_grid(pgrid); break; default: if (rb->default_event_handler(button) == SYS_USB_CONNECTED) { @@ -486,9 +495,5 @@ enum plugin_status plugin_start(const void* parameter) } rb->yield(); } - - backlight_use_settings(); /* backlight control in lib/helper.c */ - return PLUGIN_OK; } - diff --git a/apps/plugins/rockpaint.c b/apps/plugins/rockpaint.c index 19d0860..5a67f5b 100644 --- a/apps/plugins/rockpaint.c +++ b/apps/plugins/rockpaint.c @@ -31,6 +31,7 @@ #include "plugin.h" #include "lib/pluginlib_bmp.h" #include "lib/rgb_hsv.h" +#include "lib/playback_control.h" PLUGIN_HEADER @@ -515,7 +516,7 @@ static void buffer_putsxyofs( fb_data *buf, int buf_width, int buf_height, struct menu_items { int value; - char label[16]; /* GRUIK ? */ + char label[17]; /* GRUIK ? */ }; #define MENU_ESC -1242 @@ -526,7 +527,7 @@ enum { MAIN_MENU_RESUME, MAIN_MENU_NEW, MAIN_MENU_LOAD, MAIN_MENU_SAVE, MAIN_MENU_BRUSH_SIZE, MAIN_MENU_BRUSH_SPEED, MAIN_MENU_COLOR, - MAIN_MENU_GRID_SIZE, + MAIN_MENU_GRID_SIZE, MAIN_MENU_PLAYBACK_CONTROL, MAIN_MENU_EXIT, /* Select action menu */ SELECT_MENU_CUT, SELECT_MENU_COPY, SELECT_MENU_INVERT, @@ -548,6 +549,7 @@ static struct menu_items main_menu[]= { MAIN_MENU_BRUSH_SPEED, "Brush Speed" }, { MAIN_MENU_COLOR, "Choose Color" }, { MAIN_MENU_GRID_SIZE, "Grid Size" }, + { MAIN_MENU_PLAYBACK_CONTROL, "Playback Control" }, { MAIN_MENU_EXIT, "Exit" }, { MENU_END, "" } }; @@ -2599,6 +2601,11 @@ static void goto_menu(void) gridsize = multi; break; + case MAIN_MENU_PLAYBACK_CONTROL: + playback_control(NULL); + restore_screen(); + break; + case MAIN_MENU_EXIT: quit=true; return; diff --git a/apps/plugins/sliding_puzzle.c b/apps/plugins/sliding_puzzle.c index c5c8c67..e0f23f2 100644 --- a/apps/plugins/sliding_puzzle.c +++ b/apps/plugins/sliding_puzzle.c @@ -19,6 +19,7 @@ * ****************************************************************************/ #include "plugin.h" +#include "lib/playback_control.h" #ifdef HAVE_LCD_BITMAP PLUGIN_HEADER @@ -564,8 +565,20 @@ static int puzzle_loop(void) case PUZZLE_RC_QUIT: #endif case PUZZLE_QUIT: - /* get out of here */ - return PLUGIN_OK; + switch (playback_control_or_quit (NULL)) + { + case PBC_OR_QUIT_QUIT: + return PLUGIN_OK; + + case PBC_OR_QUIT_USB_CONNECTED: + return PLUGIN_USB_CONNECTED; + + default: + case PBC_OR_QUIT_RESUME: + break; + } + draw_playfield(); + break; case PUZZLE_SHUFFLE: #ifdef PUZZLE_SHUFFLE_PICTURE_PRE diff --git a/apps/plugins/snake.c b/apps/plugins/snake.c index a80aaa0..2de988e 100644 --- a/apps/plugins/snake.c +++ b/apps/plugins/snake.c @@ -33,6 +33,7 @@ dir is the current direction of the snake - 0=up, 1=right, 2=down, 3=left; */ #include "plugin.h" +#include "lib/playback_control.h" #ifdef HAVE_LCD_BITMAP PLUGIN_HEADER @@ -316,35 +317,39 @@ void redraw (void) } 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(); + int selection = 0; + MENUITEM_STRINGLIST (paused_menu, "Game Paused", NULL, + "Resume", + "Playback Control", + "Quit"); + + rb->button_clear_queue(); + 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: + selection = rb->do_menu(&paused_menu, &selection, NULL, false); + switch (selection) { + case GO_TO_ROOT: + case GO_TO_PREVIOUS: + case 0: redraw(); rb->sleep(HZ/2); return; - default: - if (rb->default_event_handler(button)==SYS_USB_CONNECTED) { + + case 1: + /* if USB is attached in playback control, quit. */ + if (playback_control(NULL)) { dead=2; return; } break; + + case 2: + dead=1; + return; + + case MENU_ATTACHED_USB: + dead=2; + return; } } } diff --git a/apps/plugins/snake2.c b/apps/plugins/snake2.c index d5ffc9f..048f962 100644 --- a/apps/plugins/snake2.c +++ b/apps/plugins/snake2.c @@ -30,6 +30,7 @@ Head and Tail are stored */ #include "plugin.h" +#include "lib/playback_control.h" #ifdef HAVE_LCD_BITMAP PLUGIN_HEADER @@ -1196,40 +1197,44 @@ void frame (void) void game_pause (void) { - int button; - - rb->lcd_clear_display(); - rb->lcd_getstringsize("Paused",&strwdt,&strhgt); - rb->lcd_putsxy((LCD_WIDTH - strwdt)/2,LCD_HEIGHT/2,"Paused"); - - rb->lcd_update(); - while (1) - { - button = rb->button_get(true); - switch (button) - { - case SNAKE2_PLAYPAUSE: + int selection = 0; + MENUITEM_STRINGLIST (paused_menu, "Game Paused", NULL, + "Resume", + "Playback Control", + "Quit"); + + rb->button_clear_queue(); + + while (1) { + selection = rb->do_menu(&paused_menu, &selection, NULL, false); + switch (selection) { + case GO_TO_ROOT: + case GO_TO_PREVIOUS: + case 0: rb->lcd_clear_display(); redraw(); rb->lcd_update(); rb->sleep(HZ/2); return; -#ifdef SNAKE2_RC_QUIT - case SNAKE2_RC_QUIT: -#endif - case SNAKE2_QUIT: - dead = 1; - quit = 1; - return; - - default: - if (rb->default_event_handler(button)==SYS_USB_CONNECTED) { - dead = 1; - quit = 2; + case 1: + /* if USB is attached in playback control, quit. */ + if (playback_control(NULL)) { + dead=1; + quit=2; return; } break; + + case 2: + dead=1; + quit=1; + return; + + case MENU_ATTACHED_USB: + dead=1; + quit=2; + return; } } } diff --git a/apps/plugins/spacerocks.c b/apps/plugins/spacerocks.c index 0891906..34f86f7 100644 --- a/apps/plugins/spacerocks.c +++ b/apps/plugins/spacerocks.c @@ -21,6 +21,7 @@ #include "plugin.h" #include "lib/helper.h" +#include "lib/playback_control.h" PLUGIN_HEADER @@ -1980,14 +1981,59 @@ enum plugin_status start_game(void) game_state = PAUSE_MODE; #endif + int selection = 0; + bool pause_menu_done = false; + MENUITEM_STRINGLIST (paused_menu, "Game Paused", NULL, + "Resume", + "Playback Control", + "Quit"); + switch(button) { case(AST_PAUSE): - if(game_state == PLAY_MODE) - game_state = PAUSE_MODE; - else if(game_state == PAUSE_MODE) + if (game_state == PAUSE_MODE) + { game_state = PLAY_MODE; - break; + break; + } + else if (game_state != PLAY_MODE) + break; + + while (!pause_menu_done) { + selection = rb->do_menu(&paused_menu, &selection, + NULL, false); + switch (selection) { + case GO_TO_ROOT: + case GO_TO_PREVIOUS: + case 0: + rb->lcd_clear_display(); + drawstars(); + draw_and_move_missiles(); + draw_lives(); + draw_and_move_ship(); + pause_menu_done = true; + break; + + case 1: + /* if USB is attached in playback control, + * quit. */ + if (playback_control(NULL)) + return PLUGIN_USB_CONNECTED; + break; + + case 2: + pause_menu_done = true; + break; + + case MENU_ATTACHED_USB: + return PLUGIN_USB_CONNECTED; + } + } + /* purposely fall through from case 2 of the pause menu + * to AST_QUIT + */ + if (selection == 0) + break; #ifdef AST_RC_QUIT case AST_RC_QUIT: diff --git a/apps/plugins/star.c b/apps/plugins/star.c index c4251cd..03df9bd 100644 --- a/apps/plugins/star.c +++ b/apps/plugins/star.c @@ -19,6 +19,7 @@ * ****************************************************************************/ #include "plugin.h" +#include "lib/playback_control.h" #ifdef HAVE_LCD_BITMAP PLUGIN_HEADER @@ -742,33 +743,20 @@ static void star_display_board_info(int current_level) MAX(TILE_HEIGHT, char_height)); } - /** - * Load a level into board array. + * Draw the board. Returns the number of stars. */ -static int star_load_level(int current_level) +static int star_display_board(void) { int x, y; - char *ptr_tab; - - if (current_level < 0) - current_level = 0; - else if (current_level > STAR_LEVEL_COUNT-1) - current_level = STAR_LEVEL_COUNT-1; - - - ptr_tab = levels + current_level * STAR_LEVEL_SIZE; - control = STAR_CONTROL_BALL; - star_count = 0; - - rb->lcd_clear_display(); + int star_count = 0; for (y = 0 ; y < STAR_HEIGHT ; y++) { for (x = 0 ; x < STAR_WIDTH ; x++) { - board[y][x] = *ptr_tab; - switch (*ptr_tab) + + switch (board[y][x]) { # define DRAW_TILE( a ) \ rb->lcd_bitmap_part( star_tiles, 0, \ @@ -802,10 +790,42 @@ static int star_load_level(int current_level) DRAW_TILE( BLOCK ); break; } + } + } + + return star_count; +} + +/** + * Load a level into board array. + */ +static int star_load_level(int current_level) +{ + int x, y; + char *ptr_tab; + + if (current_level < 0) + current_level = 0; + else if (current_level > STAR_LEVEL_COUNT-1) + current_level = STAR_LEVEL_COUNT-1; + + + ptr_tab = levels + current_level * STAR_LEVEL_SIZE; + control = STAR_CONTROL_BALL; + + rb->lcd_clear_display(); + + for (y = 0 ; y < STAR_HEIGHT ; y++) + { + for (x = 0 ; x < STAR_WIDTH ; x++) + { + board[y][x] = *ptr_tab; ptr_tab++; } ptr_tab++; } + + star_count = star_display_board(); star_display_board_info(current_level); star_transition_update(); return 1; @@ -875,7 +895,22 @@ static int star_run_game(int current_level) case STAR_RC_QUIT: #endif case STAR_QUIT: - return -1; + switch (playback_control_or_quit (NULL)) + { + case PBC_OR_QUIT_QUIT: + return -1; + case PBC_OR_QUIT_USB_CONNECTED: + usb_detected = true; + return 0; + default: + case PBC_OR_QUIT_RESUME: + break; + } + rb->lcd_clear_display(); + star_display_board(); + rb->lcd_update(); + star_display_board_info(current_level); + break; case STAR_LEFT: move_x = -1; diff --git a/apps/plugins/stopwatch.c b/apps/plugins/stopwatch.c index 4cba167..93788cd 100644 --- a/apps/plugins/stopwatch.c +++ b/apps/plugins/stopwatch.c @@ -20,6 +20,7 @@ ****************************************************************************/ #include "plugin.h" +#include "lib/playback_control.h" PLUGIN_HEADER @@ -427,8 +428,20 @@ enum plugin_status plugin_start(const void* parameter) case STOPWATCH_RC_QUIT: #endif case STOPWATCH_QUIT: - save_stopwatch(); - done = true; + switch (playback_control_or_quit (NULL)) + { + case PBC_OR_QUIT_QUIT: + case PBC_OR_QUIT_USB_CONNECTED: + save_stopwatch(); + done = true; + break; + default: + case PBC_OR_QUIT_RESUME: + rb->lcd_clear_display(); + update_lap = true; + break; + } + break; /* Stop/Start toggle */