Index: apps/plugins/spacerocks.c =================================================================== --- apps/plugins/spacerocks.c (Revision 20884) +++ apps/plugins/spacerocks.c (Arbeitskopie) @@ -21,222 +21,160 @@ #include "plugin.h" #include "lib/helper.h" +#include "lib/highscore.h" +#include "lib/playback_control.h" +#include "lib/text.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 @@ -423,6 +353,13 @@ #define SET_BG(x) #endif +#define MARGIN 5 + +#define HIGH_SCORE PLUGIN_GAMES_DIR "/spacerocks.score" +#define MAX_HIGH_SCORES 5 + +struct highscore Highest[MAX_HIGH_SCORES]; + /* The array of points that make up an asteroid */ static const short asteroid_one[NUM_ASTEROID_VERTICES*2] = { @@ -679,6 +616,167 @@ rb->close(fd); } +static void spacerocks_show_highscores(int p) +{ +#ifdef HAVE_LCD_COLOR + rb->lcd_set_background(LCD_BLACK); + rb->lcd_set_foreground(LCD_WHITE); +#endif + rb->lcd_clear_display(); + + int w, h; + char str[30]; + rb->lcd_setfont(FONT_UI); + rb->font_getstringsize("Highscore", &w, &h, FONT_UI); + /* check wether it fits on screen */ + if ((3*h + h*(MAX_HIGH_SCORES-1) + MARGIN) > LCD_HEIGHT) { + rb->lcd_setfont(FONT_SYSFIXED); + rb->font_getstringsize("Highscore", &w, &h, FONT_SYSFIXED); + } + rb->lcd_putsxy(LCD_WIDTH/2-w/2, MARGIN, "Highscore"); + rb->lcd_putsxy(LCD_WIDTH/4-w/4,2*h, "Score"); + rb->lcd_putsxy(LCD_WIDTH*3/4-w/4,2*h, "Level"); + + int i; + for (i = 1; i<=MAX_HIGH_SCORES; i++) + { + rb->snprintf (str, sizeof (str), "%d)", i); + rb->lcd_putsxy (MARGIN,3*h + h*(i-1), str); + rb->snprintf (str, sizeof (str), "%d", Highest[i-1].score); + rb->lcd_putsxy (LCD_WIDTH/4-w/4,3*h + h*(MAX_HIGH_SCORES-i), str); + rb->snprintf (str, sizeof (str), "%d", (Highest[i-1].level)); + rb->lcd_putsxy (LCD_WIDTH*3/4-w/4,3*h + h*(MAX_HIGH_SCORES-i), str); + } +#ifdef HAVE_LCD_COLOR + rb->lcd_set_foreground(LCD_RGBPACK(245,0,0)); + rb->snprintf (str, sizeof (str), "%d)", MAX_HIGH_SCORES-p+1); + rb->lcd_putsxy (MARGIN,3*h + h*(MAX_HIGH_SCORES-p), str); + rb->snprintf (str, sizeof (str), "%d", Highest[p-1].score); + rb->lcd_putsxy (LCD_WIDTH/4-w/4,3*h + h*(MAX_HIGH_SCORES-p), str); + rb->snprintf (str, sizeof (str), "%d", Highest[p-1].level); + rb->lcd_putsxy (LCD_WIDTH*3/4-w/4,3*h + h*(MAX_HIGH_SCORES-p), str); + rb->lcd_set_foreground(LCD_WHITE); +#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*)) + 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!" + }; + struct style_text formation[WORDS]={}; + formation[0].center=1; + formation[0].underline=1; + formation[2].color=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; +} +static int spacerocks_game_menu(bool ingame) +{ + rb->button_clear_queue(); + int choice = 0; + + if (ingame) { + MENUITEM_STRINGLIST (main_menu, "Spacerocks Menu", NULL, + "Resume Game", + "Restart 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(MAX_HIGH_SCORES); + break; + case 4: + playback_control(NULL); + break; + case 5: + return 1; + case MENU_ATTACHED_USB: + return 1; + default: + break; + } + } + } + else { + MENUITEM_STRINGLIST (main_menu, "Spacerocks Menu", NULL, + "Start New Game", + "Help", + "High Score", + "Playback Control", + "Quit"); + + while (1) { + choice = rb->do_menu(&main_menu, &choice, NULL, false); + switch (choice) { + case 0: + start_attract_mode(); + return 0; + case 1: + spacerocks_help(); + break; + case 2: + spacerocks_show_highscores(MAX_HIGH_SCORES); + break; + case 3: + playback_control(NULL); + break; + case 4: + return 1; + case MENU_ATTACHED_USB: + return 1; + default: + break; + } + } + } +} + bool point_in_poly(struct Point* _point, int num_vertices, int x, int y) { struct Point* pi; @@ -1872,233 +1970,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; - } - 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; + + 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(); + position=highscore_update(current_score,current_level,Highest,MAX_HIGH_SCORES); + if (position==MAX_HIGH_SCORES) { + rb->splash(HZ*2, "New High Score"); + spacerocks_show_highscores(position); } - draw_trail_blaze(); - drawstars(); - draw_and_move_asteroids(); - draw_and_move_enemy(); - - rb->lcd_update(); - button = rb->button_get(false); + else if (position!=0) { + rb->splash(HZ*2, "Top Five"); + spacerocks_show_highscores(position); + } + 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 = 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; @@ -2109,11 +2160,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,MAX_HIGH_SCORES); + spacerocks_game_loop(); rb->lcd_setfont(FONT_UI); + highscore_save(HIGH_SCORE,Highest,MAX_HIGH_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 20884) +++ 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/helper.h" +#include "lib/highscore.h" +#include "lib/playback_control.h" +#include "lib/text.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,15 @@ #define UP BUTTON_UP #define DOWN BUTTON_DOWN +#elif CONFIG_KEYPAD == SANSA_CLIP_PAD +#define QUIT BUTTON_POWER +#define LEFT BUTTON_LEFT +#define RIGHT BUTTON_RIGHT +#define SELECT BUTTON_SELECT +#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 +142,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 +150,6 @@ #define DOWN BUTTON_DOWN #elif (CONFIG_KEYPAD == MROBE100_PAD) - #define QUIT BUTTON_POWER #define LEFT BUTTON_LEFT #define RIGHT BUTTON_RIGHT @@ -171,21 +158,18 @@ #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 +178,6 @@ #define DOWN BUTTON_DOWN #elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD - #define QUIT BUTTON_POWER #define LEFT BUTTON_LEFT #define RIGHT BUTTON_RIGHT @@ -202,12 +185,6 @@ #define UP BUTTON_UP #define DOWN BUTTON_DOWN -#elif CONFIG_KEYPAD == ONDAVX747_PAD -#define QUIT BUTTON_POWER -#define LEFT BUTTON_VOL_DOWN -#define RIGHT BUTTON_VOL_UP -#define SELECT BUTTON_MENU - #elif CONFIG_KEYPAD == MROBE500_PAD #define QUIT BUTTON_POWER @@ -216,6 +193,9 @@ #endif #ifdef HAVE_TOUCHSCREEN +#ifndef QUIT +#define QUIT BUTTON_TOUCHSCREEN +#endif #ifndef LEFT #define LEFT BUTTON_MIDLEFT #endif @@ -238,24 +218,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 +233,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 +251,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 +274,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 +294,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 +311,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 +329,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 +346,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 +363,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 +380,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 +399,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 +414,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 +421,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 Difficult{ + 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 +723,7 @@ }; #define MAX_BALLS 10 + int pad_pos_x; int x[MAX_BALLS],y[MAX_BALLS]; int life; @@ -805,9 +731,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 difficult = EASY; typedef struct cube { int powertop; @@ -838,15 +767,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 = &difficult }, "difficult", 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 MAX_HIGH_SCORES 5 + +struct highscore Highest[MAX_HIGH_SCORES]; + +static void brickmania_int_game(int new_game) { int i,j; @@ -869,27 +805,32 @@ flip_sides=false; - if (new_game==1) + if (new_game==1) { brick_on_board=0; - + /* add one life per achieved level */ + if (difficult==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 +839,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 +865,233 @@ 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 p) { - 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); + rb->lcd_set_background(LCD_BLACK); + rb->lcd_set_foreground(LCD_WHITE); +#endif + rb->lcd_clear_display(); - 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); + int w, h; + char str[30]; + rb->lcd_setfont(FONT_UI); + rb->font_getstringsize("Highscore", &w, &h, FONT_UI); + /* check wether it fits on screen */ + if ((3*h + h*(MAX_HIGH_SCORES-1) + MARGIN) > LCD_HEIGHT) { + rb->lcd_setfont(FONT_SYSFIXED); + rb->font_getstringsize("Highscore", &w, &h, FONT_SYSFIXED); + } + rb->lcd_putsxy(LCD_WIDTH/2-w/2, MARGIN, "Highscore"); + rb->lcd_putsxy(LCD_WIDTH/4-w/4,2*h, "Score"); + rb->lcd_putsxy(LCD_WIDTH*3/4-w/4,2*h, "Level"); - } 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 */ + int i; + for (i = 1; i<=MAX_HIGH_SCORES; i++) + { + rb->snprintf (str, sizeof (str), "%d)", i); + rb->lcd_putsxy (MARGIN,3*h + h*(i-1), str); + rb->snprintf (str, sizeof (str), "%d", Highest[i-1].score); + rb->lcd_putsxy (LCD_WIDTH/4-w/4,3*h + h*(MAX_HIGH_SCORES-i), str); + rb->snprintf (str, sizeof (str), "%d", (Highest[i-1].level)); + rb->lcd_putsxy (LCD_WIDTH*3/4-w/4,3*h + h*(MAX_HIGH_SCORES-i), str); + } #ifdef HAVE_LCD_COLOR - rb->lcd_set_background(LCD_RGBPACK(0,0,140)); - rb->lcd_set_foreground(LCD_WHITE); + rb->lcd_set_foreground(LCD_RGBPACK(245,0,0)); + rb->snprintf (str, sizeof (str), "%d)", MAX_HIGH_SCORES-p+1); + rb->lcd_putsxy (MARGIN,3*h + h*(MAX_HIGH_SCORES-p), str); + rb->snprintf (str, sizeof (str), "%d", Highest[p-1].score); + rb->lcd_putsxy (LCD_WIDTH/4-w/4,3*h + h*(MAX_HIGH_SCORES-p), str); + rb->snprintf (str, sizeof (str), "%d", Highest[p-1].level); + rb->lcd_putsxy (LCD_WIDTH*3/4-w/4,3*h + h*(MAX_HIGH_SCORES-p), str); + 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(); + rb->button_get(true); - rb->lcd_update(); + rb->lcd_setfont(FONT_SYSFIXED); +} - 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; - } +/* submenu to choose difficult */ +static int brickmania_choose_difficult(void) +{ + rb->button_clear_queue(); + int choice = difficult; + MENUITEM_STRINGLIST (main_menu, "Brickmania Difficulty", NULL, + "Easy", + "Hard"); + choice = rb->do_menu(&main_menu, &choice, NULL, false); + switch (choice) { + case 0: + difficult = EASY; break; - - case DOWN: - case DOWN | BUTTON_REPEAT: - if (cur==MENU_LENGTH-1) - cur = 0; - else - cur++; - if (when==0 && cur==1) { - cur=2; - } + case 1: + difficult = HARD; 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; - 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; + rb->lcd_setfont(FONT_UI); +#define WORDS (sizeof help_text / sizeof (char*)) + char *help_text[] = { + "Brickmania", "", "Aim", "", "Destroy", "all", "the", "bricks", "by", "bouncing", + "the", "ball", "of", "them", "using", "the", "paddle.", "", "", "Controls", "", + "< & >", "Move", "the", "paddle", "", "SELECT", "Release", "the", "ball/fire!", "", "", + "Specials:", "", "N", "Normal:", "returns", "paddle", "to", "normal", "", "D", "DIE!:", + "loses", "a", "life", "", "L", "Life:", "gains", "a", "life", "up", "", "F", "Fire:", + "allows", "you", "to", "shoot", "bricks", "", "G", "Glue:", "ball", "sticks", "to", + "paddle", "", "B", "Ball:", "generate", "another", "ball", "", "FL", "Flip:", "flips", + "left/right", "movement", + }; + struct style_text formation[WORDS]={}; + formation[0].center=1; + formation[0].underline=1; + formation[2].color=C_RED; + formation[19].color=C_RED; + formation[32].color=C_RED; + formation[34].color=C_BLUE; + formation[41].color=C_RED; + formation[47].color=C_GREEN; + formation[54].color=C_ORANGE; + formation[62].color=C_GREEN; + formation[69].color=C_YELLOW; + formation[75].color=C_RED; + + if (display_text(WORDS, help_text, formation, NULL)==PLUGIN_USB_CONNECTED) + return PLUGIN_USB_CONNECTED; 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; + 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; +} - 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 +static int brickmania_game_menu(bool ingame) +{ + rb->button_clear_queue(); + int choice = 0; - 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"); -#if CONFIG_KEYPAD == ONDIO_PAD - rb->lcd_putsxy(1+xoffset, 7*(h+2)+yoffset, - "MENU Releases the ball/Fire!"); -#elif (CONFIG_KEYPAD == RECORDER_PAD) || (CONFIG_KEYPAD == IAUDIO_M3_PAD) - rb->lcd_putsxy(1+xoffset, 7*(h+2)+yoffset, - "PLAY Releases the ball/Fire!"); -#elif CONFIG_KEYPAD == IRIVER_H300_PAD - rb->lcd_putsxy(1+xoffset, 7*(h+2)+yoffset, - "NAVI Releases the ball/Fire!"); -#else - rb->lcd_putsxy(1+xoffset, 7*(h+2)+yoffset, - "SELECT Releases the ball/Fire!"); -#endif -#if CONFIG_KEYPAD == IAUDIO_M3_PAD - rb->lcd_putsxy(1+xoffset, 8*(h+2)+yoffset, "REC Opens menu/Quit"); -#else - rb->lcd_putsxy(1+xoffset, 8*(h+2)+yoffset, "STOP Opens menu/Quit"); -#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(); - - 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: + if (ingame) { + MENUITEM_STRINGLIST (main_menu, "Brickmania Menu", NULL, + "Resume Game", + "Restart Game", + "Difficulty", + "Help", + "High Score", + "Playback Control", + "Quit"); + + while (true) { + choice = rb->do_menu(&main_menu, &choice, NULL, false); + switch (choice) { + case 0: + if (saved_game) { + vscore=l_score-1; + score=l_score; + brickmania_int_game(1); + } + else { con_game=1; - break; - case 2: - if (help(when)==1) - return 1; - break; - case 3: + } + return 0; + case 1: + score=0; + vscore=0; + life=2; + level=0; + brickmania_int_game(1); + return 0; + case 2: + brickmania_choose_difficult(); + break; + case 3: + if (brickmania_help()==PLUGIN_USB_CONNECTED) return 1; - break; - } - return 0; - break; - case LEFT: - case LEFT | BUTTON_REPEAT: -#ifdef ALTLEFT - case ALTLEFT: - case ALTLEFT | BUTTON_REPEAT: -#endif - if( xoffset<0) - xoffset+=2; - break; - case RIGHT: - case RIGHT | BUTTON_REPEAT: -#ifdef ALTRIGHT - case ALTRIGHT: - case ALTRIGHT | BUTTON_REPEAT: -#endif - if(xoffset+maxX > LCD_WIDTH) - xoffset-=2; - break; - case UP: - case UP | BUTTON_REPEAT: - if(yoffset <0) - yoffset+=2; - break; - case DOWN: - case DOWN | BUTTON_REPEAT: - if(yoffset+maxY > LCD_HEIGHT) - yoffset-=2; - break; - - default: - if(rb->default_event_handler(button) == SYS_USB_CONNECTED) + break; + case 4: + brickmania_show_highscores(MAX_HIGH_SCORES); + break; + case 5: + playback_control(NULL); + break; + case 6: + if (level>0) { + saved_game=true; + } + else { + saved_game=false; + } + configfile_save(CONFIG_FILE_NAME,config,5,0); return 1; - break; + case MENU_ATTACHED_USB: + return 1; + default: + break; + } } - - rb->yield(); } - return 0; + else { + MENUITEM_STRINGLIST (main_menu, "Brickmania Menu", NULL, + "Start New Game", + "Difficulty", + "Help", + "High Score", + "Playback Control", + "Quit"); + + while (true) { + choice = rb->do_menu(&main_menu, &choice, NULL, false); + switch (choice) { + case 0: + score=0; + vscore=0; + life=2; + level=0; + brickmania_int_game(1); + return 0; + case 1: + brickmania_choose_difficult(); + break; + case 2: + if (brickmania_help()==PLUGIN_USB_CONNECTED) + return 1; + break; + case 3: + brickmania_show_highscores(MAX_HIGH_SCORES); + break; + case 4: + playback_control(NULL); + break; + case 5: + configfile_save(CONFIG_FILE_NAME,config,1,0); + return 1; + case MENU_ATTACHED_USB: + return 1; + default: + break; + } + } + } } -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 +1108,7 @@ } } -int fire_space(void) +static int brickmania_fire_space(void) { int t; for(t=0;t<=30;t++) @@ -1308,32 +1118,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 +1184,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 +1268,8 @@ case 1: life--; if (life>=0) { - int_game(0); - sleep(2); + brickmania_int_game(0); + brickmania_sleep(2); } break; case 2: @@ -1747,8 +1552,8 @@ } else { life--; if (life>=0) { - int_game(0); - sleep(2); + brickmania_int_game(0); + brickmania_sleep(2); } } } @@ -1775,7 +1580,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 +1597,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 +1614,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 +1630,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 +1659,13 @@ rb->lcd_update(); if (brick_on_board < 0) { - if (cur_level+1lcd_getstringsize("Congratulations!", &sw, NULL); @@ -1875,31 +1682,22 @@ "You have finished the game!"); #endif vscore=score; - rb->lcd_update(); - if (score>highscore) { - sleep(2); - highscore=score; - rb->splash(HZ*2, "New High Score"); + brickmania_sleep(2); + position=highscore_update(score,level,Highest,MAX_HIGH_SCORES); + if (position==MAX_HIGH_SCORES) { + rb->splash(HZ*2, "New High Score"); + brickmania_show_highscores(position); + } + else if (position!=0) { + rb->splash(HZ*2, "Top Five"); + brickmania_show_highscores(position); } else { - sleep(3); + brickmania_sleep(3); } - 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; + if (brickmania_game_menu(false)!=0) { + return 0; } } } @@ -2011,10 +1809,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 +1827,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"); - } else { - sleep(3); + brickmania_sleep(2); + position=highscore_update(score,level,Highest,MAX_HIGH_SCORES); + if (position==MAX_HIGH_SCORES) { + rb->splash(HZ*2, "New High Score"); + brickmania_show_highscores(position); + } + else if (position!=0) { + rb->splash(HZ*2, "Top Five"); + brickmania_show_highscores(position); + } + else { + brickmania_sleep(3); } for(k=0;k *rb->current_tick) @@ -2120,6 +1894,8 @@ enum plugin_status plugin_start(const void* parameter) { (void)parameter; +#ifdef HAVE_LCD_BITMAP + highscore_load(HIGH_SCORE,Highest,MAX_HIGH_SCORES); rb->lcd_setfont(FONT_SYSFIXED); #if LCD_DEPTH > 1 @@ -2129,14 +1905,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,MAX_HIGH_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 20884) +++ apps/plugins/jewels.c (Arbeitskopie) @@ -23,9 +23,9 @@ #include "plugin.h" #include "lib/playback_control.h" +#include "lib/highscore.h" +#include "lib/text.h" -#ifdef HAVE_LCD_BITMAP - PLUGIN_HEADER /* button definitions */ @@ -59,19 +59,16 @@ #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) || \ (CONFIG_KEYPAD == IPOD_1G2G_PAD) -#define JEWELS_SCROLLWHEEL -#define JEWELS_UP BUTTON_MENU -#define JEWELS_DOWN BUTTON_PLAY +#define JEWELS_CANCEL BUTTON_MENU #define JEWELS_LEFT BUTTON_LEFT #define JEWELS_RIGHT BUTTON_RIGHT -#define JEWELS_PREV BUTTON_SCROLL_BACK -#define JEWELS_NEXT BUTTON_SCROLL_FWD +#define JEWELS_UP BUTTON_SCROLL_BACK +#define JEWELS_DOWN BUTTON_SCROLL_FWD #define JEWELS_SELECT BUTTON_SELECT #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD @@ -109,7 +106,7 @@ #define JEWELS_SELECT BUTTON_SELECT #define JEWELS_CANCEL BUTTON_POWER -#elif (CONFIG_KEYPAD == SANSA_FUZE_PAD) +#elif CONFIG_KEYPAD == SANSA_FUZE_PAD #define JEWELS_SCROLLWHEEL #define JEWELS_UP BUTTON_UP #define JEWELS_DOWN BUTTON_DOWN @@ -144,7 +141,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 @@ -220,10 +216,9 @@ #endif #endif -/* use 30x30 tiles (iPod Video, Gigabeat, Onda VX747) */ +/* use 30x30 tiles (iPod Video, Gigabeat) */ #if (LCD_HEIGHT == 240) && (LCD_WIDTH == 320) || \ - ((LCD_HEIGHT == 320) && (LCD_WIDTH == 240)) || \ - ((LCD_HEIGHT == 400) && (LCD_WIDTH == 240)) + ((LCD_HEIGHT == 320) && (LCD_WIDTH == 240)) #define TILE_WIDTH 30 #define TILE_HEIGHT 30 #define YOFS 0 @@ -297,17 +292,6 @@ #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,65 +308,15 @@ /* animation frame rate */ #define MAX_FPS 20 +/* text margin */ +#define MARGIN 5 + /* Game types */ enum game_type { GAME_TYPE_NORMAL, GAME_TYPE_PUZZLE }; -/* menu values */ -#define FONT_HEIGHT 8 -#define MAX_MITEMS 6 -#define MENU_WIDTH 100 - -/* menu results */ -enum menu_result { - MRES_NONE, - MRES_NEW, - MRES_PUZZLE, - MRES_SAVE, - MRES_RESUME, - MRES_SCORES, - MRES_HELP, - MRES_QUIT, - MRES_PLAYBACK, - MRES_EXIT -}; - -/* menu commands */ -enum menu_cmd { - MCMD_NONE, - MCMD_NEXT, - MCMD_PREV, - MCMD_SELECT -}; - -/* menus */ -struct jewels_menu { - char *title; - bool hasframe; - int selected; - int itemcnt; - struct jewels_menuitem { - char *text; - enum menu_result res; - } items[MAX_MITEMS]; -} bjmenu[] = { - {"Jewels", false, 0, 6, - {{"New Game", MRES_NEW}, - {"Puzzle", MRES_PUZZLE}, - {"Resume Saved Game", MRES_RESUME}, - {"High Scores", MRES_SCORES}, - {"Help", MRES_HELP}, - {"Quit", MRES_QUIT}}}, - {"Menu", true, 0, 5, - {{"Audio Playback", MRES_PLAYBACK }, - {"Resume Game", MRES_RESUME}, - {"Save Game", MRES_SAVE}, - {"End Game", MRES_QUIT}, - {"Exit Jewels", MRES_EXIT}}} -}; - /* external bitmaps */ extern const fb_data jewels[]; @@ -410,9 +344,6 @@ * segments is the number of cleared segments in the current run * level is the current level * type is the game type (normal or puzzle) - * highscores is the list of high scores - * resume denotes whether to resume the currently loaded game - * dirty denotes whether the high scores are out of sync with the saved file * playboard is the game playing board (first row is hidden) * num_jewels is the number of different jewels to use */ @@ -421,9 +352,6 @@ unsigned int segments; unsigned int level; unsigned int type; - unsigned int highscores[NUM_SCORES]; - bool resume; - bool dirty; struct tile playboard[BJ_HEIGHT][BJ_WIDTH]; unsigned int num_jewels; }; @@ -481,32 +409,19 @@ {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" +#define MAX_HIGH_SCORES 5 - /* reset scoring */ - bj->level = 1; - bj->score = 0; - bj->segments = 0; +struct highscore Highest[MAX_HIGH_SCORES]; - /* 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)); @@ -514,9 +429,60 @@ } /***************************************************************************** +* 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->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); + + /* delete saved file */ + rb->remove(SAVE_FILE); + return loaded; +} + +/***************************************************************************** +* jewels_savegame() saves the current game state. +******************************************************************************/ +static void jewels_savegame(struct game_context* bj, bool playgame) +{ + int fd; + /* write out the game state to the save file */ + fd = rb->open(SAVE_FILE, O_WRONLY|O_CREAT); + rb->write(fd, &bj->type, sizeof(bj->type)); + if (playgame) { + 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; @@ -553,82 +519,85 @@ /* 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); + + rb->lcd_getstringsize(title, &w, &h); + rb->lcd_putsxy(LCD_WIDTH-(LCD_WIDTH-BJ_WIDTH*TILE_WIDTH)/2-w/2, 1, title); - /* draw progress bar */ + 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); + + if (bj->type == GAME_TYPE_NORMAL) { + 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)); + rb->lcd_set_foreground(LCD_RGBPACK(104, 63, 63)); #endif - rb->lcd_fillrect(BJ_WIDTH*TILE_WIDTH+(LCD_WIDTH-BJ_WIDTH*TILE_WIDTH)/4, + rb->lcd_fillrect(BJ_WIDTH*TILE_WIDTH+(LCD_WIDTH-BJ_WIDTH*TILE_WIDTH)/4, (LCD_HEIGHT-10)-(((LCD_HEIGHT-10)-18)* tempscore/LEVEL_PTS), (LCD_WIDTH-BJ_WIDTH*TILE_WIDTH)/2, ((LCD_HEIGHT-10)-18)*tempscore/LEVEL_PTS); #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, + 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, (LCD_WIDTH-BJ_WIDTH*TILE_WIDTH)/2-2, ((LCD_HEIGHT-10)-18)*tempscore/LEVEL_PTS-1); - jewels_setcolors(); - rb->lcd_drawrect(BJ_WIDTH*TILE_WIDTH+(LCD_WIDTH-BJ_WIDTH*TILE_WIDTH)/4, + 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_WIDTH-BJ_WIDTH*TILE_WIDTH)/2, ((LCD_HEIGHT-10)-18)*tempscore/LEVEL_PTS+1); #endif - - /* 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); - + 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 */ /* draw separator lines */ jewels_setcolors(); 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 */ + + if (bj->type == GAME_TYPE_NORMAL) { + 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)); + 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, + 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))/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, + 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))/2-2); - jewels_setcolors(); - rb->lcd_drawrect(0, (8*TILE_HEIGHT+YOFS) - +(LCD_HEIGHT-14-(8*TILE_HEIGHT+YOFS))/4, + 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))/2); #endif - + 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 */ @@ -637,117 +606,51 @@ rb->lcd_hline(0, LCD_WIDTH-1, 8*TILE_HEIGHT+YOFS); rb->lcd_vline(BJ_WIDTH*TILE_WIDTH, 0, 8*TILE_HEIGHT+YOFS); rb->lcd_vline(LCD_WIDTH/2, 8*TILE_HEIGHT+YOFS, LCD_HEIGHT-1); - - /* draw progress bar */ + if (bj->type == GAME_TYPE_NORMAL) { + /* draw progress bar */ #ifdef HAVE_LCD_COLOR - rb->lcd_set_foreground(LCD_RGBPACK(104, 63, 63)); + 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, - (LCD_WIDTH-BJ_WIDTH*TILE_WIDTH)/2, - (8*TILE_HEIGHT+YOFS)*tempscore/LEVEL_PTS); + 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, + (LCD_WIDTH-BJ_WIDTH*TILE_WIDTH)/2, + (8*TILE_HEIGHT+YOFS)*tempscore/LEVEL_PTS); #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, - (LCD_WIDTH-BJ_WIDTH*TILE_WIDTH)/2-2, - (8*TILE_HEIGHT+YOFS)*tempscore/LEVEL_PTS-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, - (LCD_WIDTH-BJ_WIDTH*TILE_WIDTH)/2, - (8*TILE_HEIGHT+YOFS)*tempscore/LEVEL_PTS+1); + 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, + (LCD_WIDTH-BJ_WIDTH*TILE_WIDTH)/2-2, + (8*TILE_HEIGHT+YOFS)*tempscore/LEVEL_PTS-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, + (LCD_WIDTH-BJ_WIDTH*TILE_WIDTH)/2, + (8*TILE_HEIGHT+YOFS)*tempscore/LEVEL_PTS+1); #endif + 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(); } /***************************************************************************** -* jewels_showmenu() displays the chosen menu after performing the chosen -* menu command. -******************************************************************************/ -static enum menu_result jewels_showmenu(struct jewels_menu* menu, - enum menu_cmd cmd) { - int i; - int w, h; - int firstline; - int adj; - int extraline = LCD_HEIGHT <= ((menu->itemcnt+2)*FONT_HEIGHT) ? 0 : 1; - - /* handle menu command */ - switch(cmd) { - case MCMD_NEXT: - menu->selected = (menu->selected+1)%menu->itemcnt; - break; - - case MCMD_PREV: - menu->selected = (menu->selected-1+menu->itemcnt)%menu->itemcnt; - break; - - case MCMD_SELECT: - return menu->items[menu->selected].res; - - default: - break; - } - - /* clear menu area */ - firstline = (LCD_HEIGHT/FONT_HEIGHT-(menu->itemcnt+3))/2; - - rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); - rb->lcd_fillrect((LCD_WIDTH-MENU_WIDTH)/2, firstline*FONT_HEIGHT, - MENU_WIDTH, (menu->itemcnt+3)*FONT_HEIGHT); - rb->lcd_set_drawmode(DRMODE_SOLID); - - if(menu->hasframe) { - rb->lcd_drawrect((LCD_WIDTH-MENU_WIDTH)/2-1, firstline*FONT_HEIGHT-1, - MENU_WIDTH+2, (menu->itemcnt+3)*FONT_HEIGHT+2); - rb->lcd_hline((LCD_WIDTH-MENU_WIDTH)/2-1, - (LCD_WIDTH-MENU_WIDTH)/2-1+MENU_WIDTH+2, - (firstline+1)*FONT_HEIGHT); - } - - /* draw menu items */ - rb->lcd_getstringsize(menu->title, &w, &h); - rb->lcd_putsxy((LCD_WIDTH-w)/2, firstline*FONT_HEIGHT, menu->title); - - for(i=0; iitemcnt; i++) { - if(i == menu->selected) { - rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); - } - rb->lcd_putsxy((LCD_WIDTH-MENU_WIDTH)/2, - (firstline+i+1+extraline)*FONT_HEIGHT, - menu->items[i].text); - if(i == menu->selected) { - rb->lcd_set_drawmode(DRMODE_SOLID); - } - } - - adj = (firstline == 0 ? 0 : 1); - rb->lcd_update_rect((LCD_WIDTH-MENU_WIDTH)/2-1, firstline*FONT_HEIGHT-adj, - MENU_WIDTH+2, (menu->itemcnt+3)*FONT_HEIGHT+2*adj); - return MRES_NONE; -} - -/***************************************************************************** * 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; @@ -869,7 +772,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; @@ -966,8 +869,7 @@ * 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; @@ -1107,7 +1009,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; @@ -1195,17 +1097,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; } /***************************************************************************** @@ -1278,17 +1178,39 @@ } 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); + + /* reset scoring */ + bj->level = 1; + bj->score = 0; + bj->segments = 0; + + /* 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) { @@ -1297,7 +1219,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++; @@ -1319,12 +1241,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; } @@ -1332,717 +1249,374 @@ 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 p) +{ +#ifdef HAVE_LCD_COLOR + rb->lcd_set_background(LCD_BLACK); + rb->lcd_set_foreground(LCD_WHITE); +#endif + rb->lcd_clear_display(); - /* calculate total score */ - current = (bj->level-1)*LEVEL_PTS+bj->score; - if(current <= 0) return 0; - - /* 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; - } + int w, h; + char str[30]; + rb->lcd_setfont(FONT_UI); + rb->font_getstringsize("Highscore", &w, &h, FONT_UI); + /* check wether it fits on screen */ + if ((3*h + h*(MAX_HIGH_SCORES-1) + MARGIN) > LCD_HEIGHT) { + rb->lcd_setfont(FONT_SYSFIXED); + rb->font_getstringsize("Highscore", &w, &h, FONT_SYSFIXED); } + rb->lcd_putsxy(LCD_WIDTH/2-w/2, MARGIN, "Highscore"); + 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)); + int i; + for (i = 1; i<=MAX_HIGH_SCORES; i++) + { + rb->snprintf (str, sizeof (str), "%d)", i); + rb->lcd_putsxy (MARGIN,3*h + h*(i-1), str); + rb->snprintf (str, sizeof (str), "%d", Highest[i-1].score); + rb->lcd_putsxy (LCD_WIDTH/4-w/4,3*h + h*(MAX_HIGH_SCORES-i), str); + rb->snprintf (str, sizeof (str), "%d", (Highest[i-1].level)); + rb->lcd_putsxy (LCD_WIDTH*3/4-w/4,3*h + h*(MAX_HIGH_SCORES-i), str); } +#ifdef HAVE_LCD_COLOR + rb->lcd_set_foreground(LCD_RGBPACK(245,0,0)); + rb->snprintf (str, sizeof (str), "%d)", MAX_HIGH_SCORES-p+1); + rb->lcd_putsxy (MARGIN,3*h + h*(MAX_HIGH_SCORES-p), str); + rb->snprintf (str, sizeof (str), "%d", Highest[p-1].score); + rb->lcd_putsxy (LCD_WIDTH/4-w/4,3*h + h*(MAX_HIGH_SCORES-p), str); + rb->snprintf (str, sizeof (str), "%d", Highest[p-1].level); + rb->lcd_putsxy (LCD_WIDTH*3/4-w/4,3*h + h*(MAX_HIGH_SCORES-p), str); + rb->lcd_set_foreground(LCD_WHITE); +#endif + rb->lcd_update(); + rb->button_get(true); - rb->close(fd); + rb->lcd_setfont(FONT_SYSFIXED); } -/***************************************************************************** -* jewels_savescores() saves the high scores saved file. -******************************************************************************/ -static void jewels_savescores(struct game_context* bj) { - int fd; - - /* 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; -} - -/***************************************************************************** -* 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; -} - -/***************************************************************************** -* 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); - } -} - -/***************************************************************************** -* jewels_main() is the main game subroutine, it returns the final game status. -******************************************************************************/ -static int jewels_main(struct game_context* bj) { - int i, j; - int w, h; +static int jewels_help(void) +{ + rb->lcd_setfont(FONT_UI); +#define WORDS (sizeof help_text / sizeof (char*)) + 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." + }; + struct style_text formation[WORDS]={}; + formation[0].center=1; + formation[0].underline=1; + formation[2].color=C_RED; + + if (display_text(WORDS, help_text, formation, NULL)==PLUGIN_USB_CONNECTED) + return PLUGIN_USB_CONNECTED; int button; - char str[18]; - bool startgame = false; - bool inmenu = false; - bool selected = false; - enum menu_cmd cmd = MCMD_NONE; - enum menu_result res; - - /* the cursor coordinates */ - int x=0, y=0; - - /* don't resume by default */ - bj->resume = false; - - /******************** - * menu * - ********************/ - rb->lcd_clear_display(); - - while(!startgame) { - res = jewels_showmenu(&bjmenu[0], cmd); - cmd = MCMD_NONE; - - rb->snprintf(str, 18, "High Score: %d", bj->highscores[0]); - rb->lcd_getstringsize(str, &w, &h); - rb->lcd_putsxy((LCD_WIDTH-w)/2, LCD_HEIGHT-8, str); - rb->lcd_update(); - - rb->yield(); - - switch(res) { - case MRES_NEW: - startgame = true; - bj->type = GAME_TYPE_NORMAL; - continue; - - case MRES_PUZZLE: - startgame = true; - bj->type = GAME_TYPE_PUZZLE; - continue; - - case MRES_RESUME: - if(!jewels_loadgame(bj)) { - rb->splash(HZ*2, "Nothing to resume"); - rb->lcd_clear_display(); - } else { - startgame = true; - } - continue; - - case MRES_SCORES: - rb->lcd_clear_display(); - - /* room for a title? */ - j = 0; - if(LCD_HEIGHT-NUM_SCORES*8 >= 8) { - rb->snprintf(str, 12, "%s", "High Scores"); - rb->lcd_getstringsize(str, &w, &h); - rb->lcd_putsxy((LCD_WIDTH-w)/2, 0, str); - j = 2; - } - - /* print high scores */ - for(i=0; isnprintf(str, 11, "#%02d: %d", i+1, bj->highscores[i]); - rb->lcd_puts(0, i+j, str); - } - - rb->lcd_update(); - while(true) { - button = rb->button_get(true); - if(button != BUTTON_NONE && !(button&BUTTON_REL)) break; - rb->yield(); - } - rb->lcd_clear_display(); - continue; - - case MRES_HELP: - /* 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(); - continue; - - case MRES_QUIT: - return BJ_QUIT; - - default: - break; + 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; +} - /* handle menu button presses */ - button = rb->button_get(true); - switch(button){ -#ifdef JEWELS_SCROLLWHEEL - case JEWELS_PREV: - case (JEWELS_PREV|BUTTON_REPEAT): -#endif - case JEWELS_UP: - case (JEWELS_UP|BUTTON_REPEAT): - cmd = MCMD_PREV; +static void jewels_choose_mode(struct game_context* bj) +{ + rb->button_clear_queue(); + int choice = bj->type; + MENUITEM_STRINGLIST (main_menu, "Jewels Mode", NULL, + "Normal", + "Puzzle"); + choice = rb->do_menu(&main_menu, &choice, NULL, false); + switch (choice) { + case 0: + bj->type=GAME_TYPE_NORMAL; break; - -#ifdef JEWELS_SCROLLWHEEL - case JEWELS_NEXT: - case (JEWELS_NEXT|BUTTON_REPEAT): -#endif - case JEWELS_DOWN: - case (JEWELS_DOWN|BUTTON_REPEAT): - cmd = MCMD_NEXT; + case 1: + bj->type=GAME_TYPE_PUZZLE; break; - - case JEWELS_SELECT: - case JEWELS_RIGHT: - cmd = MCMD_SELECT; - break; - -#ifdef JEWELS_CANCEL -#ifdef JEWELS_RC_CANCEL - case JEWELS_RC_CANCEL: -#endif - case JEWELS_CANCEL: - return BJ_QUIT; -#endif - default: - if(rb->default_event_handler_ex(button, jewels_callback, - (void*) bj) == SYS_USB_CONNECTED) - return BJ_USB; break; } - } + rb->button_clear_queue(); +} - /******************** - * init * - ********************/ - jewels_init(bj); +static int jewels_game_menu(struct game_context* bj, bool ingame) +{ + rb->button_clear_queue(); + int choice = 0; - /******************** - * 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; + if (ingame) { + MENUITEM_STRINGLIST (main_menu, "Jewels Menu", NULL, + "Resume Game", + "Restart Game", + "Mode", + "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: + jewels_init(bj); + return 0; + case 2: + jewels_choose_mode(bj); + break; + case 3: + jewels_help(); + break; + case 4: + jewels_show_highscores(MAX_HIGH_SCORES); + break; + case 5: + playback_control(NULL); + break; + case 6: + rb->splash(HZ*1, "Saving game ..."); + jewels_savegame(bj, true); + return 1; + case MENU_ATTACHED_USB: + return 1; + default: + break; + } } } - - /********************** - * play * - **********************/ - while(true) { - int no_movesavail = false; - - if(!inmenu) { - /* 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); - } else { - res = jewels_showmenu(&bjmenu[1], cmd); - cmd = MCMD_NONE; - switch(res) { - case MRES_RESUME: - inmenu = false; - selected = false; - continue; - - case MRES_PLAYBACK: + else { + MENUITEM_STRINGLIST (main_menu, "Jewels Menu", NULL, + "Start New Game", + "Mode", + "Help", + "High Score", + "Playback Control", + "Quit"); + + while (1) { + choice = rb->do_menu(&main_menu, &choice, NULL, false); + switch (choice) { + case 0: + jewels_init(bj); + return 0; + case 1: + jewels_choose_mode(bj); + break; + case 2: + jewels_help(); + break; + case 3: + jewels_show_highscores(MAX_HIGH_SCORES); + break; + case 4: playback_control(NULL); - rb->lcd_setfont(FONT_SYSFIXED); - inmenu = false; - selected = false; break; - - case MRES_SAVE: - rb->splash(HZ, "Saving game..."); - jewels_savegame(bj); - return BJ_END; - - case MRES_QUIT: - return BJ_END; - - case MRES_EXIT: - return BJ_QUIT_FROM_GAME; - + case 5: + jewels_savegame(bj, false); + return 1; + case MENU_ATTACHED_USB: + return 1; default: break; } } + } +} +static int jewels_game_loop(struct game_context* bj) { + int button; + int position; + bool selected = false; + bool no_movesavail; + int x=0, y=0; + + if(!jewels_loadgame(bj)) { + if (jewels_game_menu(bj, false)!=0) + return 0; + } else { + if (jewels_game_menu(bj, true)!=0) + return 0; + } + + while(true) { + no_movesavail = false; + + /* 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(!inmenu) { - 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(!inmenu) { - 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; - } - } else { - cmd = MCMD_SELECT; - } + 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(!inmenu) { - 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); - } - } else { - cmd = MCMD_NEXT; - } + 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(!inmenu) { - 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); - } - } else { - cmd = MCMD_PREV; - } + 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(!inmenu) { - if(!selected) { - if(x == 0) { - y = (y+(BJ_HEIGHT-1)-1)%(BJ_HEIGHT-1); - } - x = (x+BJ_WIDTH-1)%BJ_WIDTH; - } - } else { - cmd = MCMD_PREV; - } + 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(!inmenu) { - if(!selected) { - if(x == BJ_WIDTH-1) { - y = (y+1)%(BJ_HEIGHT-1); - } - x = (x+1)%BJ_WIDTH; - } - } else { - cmd = MCMD_NEXT; - } + 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 */ - if(!inmenu) { - selected = !selected; - } else { - cmd = MCMD_SELECT; - } + selected = !selected; break; -#ifdef JEWELS_MENU - case JEWELS_MENU: -#endif - case (JEWELS_SELECT|BUTTON_REPEAT): /* show menu */ - if(!inmenu) inmenu = true; - 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, "Congratulation!"); + 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"); + position=highscore_update(bj->score,bj->level,Highest,MAX_HIGH_SCORES); + if (position==MAX_HIGH_SCORES) { + rb->splash(HZ*2, "New High Score"); + jewels_show_highscores(position); + } + else if (position!=0) { + rb->splash(HZ*2, "Top Five"); + 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. -******************************************************************************/ +/* this is the 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 */ (void)parameter; - /* end of plugin init */ - +#ifdef HAVE_LCD_BITMAP /* load high scores */ - jewels_loadscores(&bj); + highscore_load(HIGH_SCORE,Highest,MAX_HIGH_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.type = GAME_TYPE_NORMAL; + jewels_game_loop(&bj); + rb->lcd_setfont(FONT_UI); +#endif /* HAVE_LCD_BITMAP */ + return PLUGIN_OK; } - -#endif /* HAVE_LCD_BITMAP */ Index: apps/plugins/rockblox.c =================================================================== --- apps/plugins/rockblox.c (Revision 20884) +++ apps/plugins/rockblox.c (Arbeitskopie) @@ -21,9 +21,11 @@ * ****************************************************************************/ #include "plugin.h" +#include "lib/helper.h" #include "lib/highscore.h" +#include "lib/playback_control.h" #include "lib/playergfx.h" -#include "lib/helper.h" +#include "lib/text.h" PLUGIN_HEADER @@ -279,10 +281,6 @@ #define ROCKBLOX_DROP BUTTON_SELECT #define ROCKBLOX_RESTART BUTTON_MENU -#elif CONFIG_KEYPAD == ONDAVX747_PAD -#define ROCKBLOX_OFF BUTTON_POWER -#define ROCKBLOX_RESTART BUTTON_MENU - #else #error No keymap defined! #endif @@ -314,6 +312,8 @@ #endif #endif +#define MARGIN 5 + #define BLOCKS_NUM 7 #define EMPTY_BLOCK 7 @@ -368,7 +368,7 @@ #define LEVEL_Y 70 #define LINES_Y 105 -#elif (LCD_WIDTH == 240) && ((LCD_HEIGHT == 320) || (LCD_HEIGHT == 400)) +#elif (LCD_WIDTH == 240) && (LCD_HEIGHT == 320) #define BLOCK_WIDTH 15 #define BLOCK_HEIGHT 15 @@ -735,7 +735,7 @@ } #ifdef HIGH_SCORE_Y -static void show_highscores (void) +static void rockblox_show_highscores_ingame (void) { int i; char str[25]; /* for strings */ @@ -748,17 +748,60 @@ } #endif -static void init_rockblox (void) +static void rockblox_show_highscores(int p) { - highscore_update(score, level, Highest, MAX_HIGH_SCORES); +#ifdef HAVE_LCD_COLOR + rb->lcd_set_background(LCD_BLACK); + rb->lcd_set_foreground(LCD_WHITE); +#endif + rb->lcd_clear_display(); - level = 1; - lines = 0; - score = 0; - gameover = false; - nf = t_rand (BLOCKS_NUM); - init_board (); + int w, h; + char str[30]; #ifdef HAVE_LCD_BITMAP + rb->lcd_setfont(FONT_UI); + rb->font_getstringsize("Highscore", &w, &h, FONT_UI); + /* check wether it fits on screen */ + if ((3*h + h*(MAX_HIGH_SCORES-1) + MARGIN) > LCD_HEIGHT) { + rb->lcd_setfont(FONT_SYSFIXED); + rb->font_getstringsize("Highscore", &w, &h, FONT_SYSFIXED); + } +#endif + rb->lcd_putsxy(LCD_WIDTH/2-w/2, MARGIN, "Highscore"); + rb->lcd_putsxy(LCD_WIDTH/4-w/4,2*h, "Score"); + rb->lcd_putsxy(LCD_WIDTH*3/4-w/4,2*h, "Level"); + + int i; + for (i = 1; i<=MAX_HIGH_SCORES; i++) + { + rb->snprintf (str, sizeof (str), "%d)", i); + rb->lcd_putsxy (MARGIN,3*h + h*(i-1), str); + rb->snprintf (str, sizeof (str), "%d", Highest[i-1].score); + rb->lcd_putsxy (LCD_WIDTH/4-w/4,3*h + h*(MAX_HIGH_SCORES-i), str); + rb->snprintf (str, sizeof (str), "%d", (Highest[i-1].level)); + rb->lcd_putsxy (LCD_WIDTH*3/4-w/4,3*h + h*(MAX_HIGH_SCORES-i), str); + } +#ifdef HAVE_LCD_COLOR + rb->lcd_set_foreground(LCD_RGBPACK(245,0,0)); + rb->snprintf (str, sizeof (str), "%d)", MAX_HIGH_SCORES-p+1); + rb->lcd_putsxy (MARGIN,3*h + h*(MAX_HIGH_SCORES-p), str); + rb->snprintf (str, sizeof (str), "%d", Highest[p-1].score); + rb->lcd_putsxy (LCD_WIDTH/4-w/4,3*h + h*(MAX_HIGH_SCORES-p), str); + rb->snprintf (str, sizeof (str), "%d", Highest[p-1].level); + rb->lcd_putsxy (LCD_WIDTH*3/4-w/4,3*h + h*(MAX_HIGH_SCORES-p), str); + rb->lcd_set_foreground(LCD_WHITE); +#endif + rb->lcd_update(); + rb->button_get(true); + +#ifdef HAVE_LCD_BITMAP + rb->lcd_setfont(FONT_SYSFIXED); +#endif +} + +static void draw_background (void) +{ +#ifdef HAVE_LCD_BITMAP rb->lcd_bitmap (rockblox_background, 0, 0, LCD_WIDTH, LCD_HEIGHT); #else /* HAVE_LCD_CHARCELLS */ pgfx_display (0, 0); @@ -771,10 +814,21 @@ #endif show_details (); #ifdef HIGH_SCORE_Y - show_highscores (); + rockblox_show_highscores_ingame (); #endif } +static void init_rockblox (void) +{ + 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 @@ -1061,11 +1115,121 @@ move_block (0, 1, co); } -static int rockblox_loop (void) +static int rockblox_help(void) { +#ifdef HAVE_LCD_BITMAP + rb->lcd_setfont(FONT_UI); +#endif +#define WORDS (sizeof help_text / sizeof (char*)) + char *help_text[] = { + "Rockblox", "", "Aim", "", "Make", "the", "falling", "blocks", "of", "different", + "shapes", "form", "full", "rows.", "Whenever", "a", "row", "is", "completed,", "it", + "will", "be", "cleared", "away", "and", "you", "gain", "points." + }; + struct style_text formation[WORDS]={}; + formation[0].center=1; + formation[0].underline=1; + formation[2].color=C_RED; + + if (display_text(WORDS, help_text, formation, NULL)==PLUGIN_USB_CONNECTED) + return 1; + 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; +} + +static int rockblox_game_menu(int when) +{ + rb->button_clear_queue(); + int choice = 0; + + if (when==1) { + MENUITEM_STRINGLIST (main_menu, "Rockblox Menu", NULL, + "Resume Game", + "Restart 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: + init_rockblox(); + return 0; + case 2: + rockblox_help(); + break; + case 3: + rockblox_show_highscores(MAX_HIGH_SCORES); + break; + case 4: + playback_control(NULL); + break; + case 5: + return 1; + case MENU_ATTACHED_USB: + return 1; + default: + break; + } + } + } + else { + MENUITEM_STRINGLIST (main_menu, "Rockblox Menu", NULL, + "Start New Game", + "Help", + "High Score", + "Playback Control", + "Quit"); + + while (1) { + choice = rb->do_menu(&main_menu, &choice, NULL, false); + switch (choice) { + case 0: + init_rockblox(); + return 0; + case 1: + rockblox_help(); + break; + case 2: + rockblox_show_highscores(MAX_HIGH_SCORES); + break; + case 3: + playback_control(NULL); + break; + case 4: + return 1; + case MENU_ATTACHED_USB: + return 1; + default: + break; + } + } + } +} + +static int rockblox_game_loop(void) +{ + int position; + int button; int lastbutton = BUTTON_NONE; long next_down_tick = *rb->current_tick + level_speed(level); + + if (rockblox_game_menu(0)!=0) { + return 0; + } new_block (); @@ -1085,7 +1249,7 @@ rb->lcd_bitmap (rockblox_background, 0, 0, LCD_WIDTH, LCD_HEIGHT); show_details (); #ifdef HIGH_SCORE_Y - show_highscores (); + rockblox_show_highscores_ingame (); #endif draw_next_block (); refresh_board (); @@ -1098,7 +1262,13 @@ case ROCKBLOX_RC_OFF: #endif case ROCKBLOX_OFF: - return PLUGIN_OK; + if (rockblox_game_menu(1)!=0) { + return 0; + } + draw_background (); + refresh_board (); + draw_next_block (); + break; #if defined(ROCKBLOX_ROTATE) case ROCKBLOX_ROTATE: @@ -1214,23 +1384,29 @@ rb->lcd_set_foreground (LCD_BLACK); #endif rb->splash (HZ * 2, "Game Over"); + position=highscore_update(score,level,Highest,MAX_HIGH_SCORES); + if (position==MAX_HIGH_SCORES) { + rb->splash(HZ*2, "New High Score"); + rockblox_show_highscores(position); + } + else if (position!=0) { + rb->splash(HZ*2, "Top Five"); + rockblox_show_highscores(position); + } init_rockblox (); new_block (); } - refresh_board (); } - - return PLUGIN_OK; } enum plugin_status plugin_start (const void *parameter) { - int ret; - (void) parameter; rb->srand (*rb->current_tick); + + rb->lcd_set_drawmode(DRMODE_SOLID); /* Load HighScore if any */ highscore_load(HIGH_SCORE,Highest,MAX_HIGH_SCORES); @@ -1240,7 +1416,7 @@ #endif #ifdef HAVE_LCD_BITMAP - rb->lcd_setfont (FONT_SYSFIXED); + rb->lcd_setfont(FONT_SYSFIXED); #else if (!pgfx_init(4, 2)) { @@ -1252,10 +1428,10 @@ backlight_force_on(); /* backlight control in lib/helper.c */ init_rockblox (); - ret = rockblox_loop (); + rockblox_game_loop (); #ifdef HAVE_LCD_BITMAP - rb->lcd_setfont (FONT_UI); + rb->lcd_setfont(FONT_UI); #else pgfx_release(); #endif @@ -1263,5 +1439,5 @@ highscore_save(HIGH_SCORE,Highest,MAX_HIGH_SCORES); backlight_use_settings(); /* backlight control in lib/helper.c */ - return ret; + return PLUGIN_OK; } Index: apps/plugins/pegbox.c =================================================================== --- apps/plugins/pegbox.c (Revision 20884) +++ apps/plugins/pegbox.c (Arbeitskopie) @@ -19,29 +19,17 @@ * ****************************************************************************/ #include "plugin.h" +#include "lib/configfile.h" +#include "lib/playback_control.h" +#include "lib/text.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_DIR "/games/pegbox.data" -#define SAVE_FILE PLUGIN_DIR "/games/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 */ @@ -76,8 +64,6 @@ #define PEGBOX_SAVE BUTTON_OFF #define PEGBOX_QUIT (BUTTON_MENU | BUTTON_LEFT) #define PEGBOX_RESTART (BUTTON_MENU | BUTTON_RIGHT) -#define PEGBOX_LVL_UP (BUTTON_MENU | BUTTON_UP) -#define PEGBOX_LVL_DOWN (BUTTON_MENU | BUTTON_DOWN) #define PEGBOX_UP BUTTON_UP #define PEGBOX_DOWN BUTTON_DOWN #define PEGBOX_RIGHT BUTTON_RIGHT @@ -193,11 +179,8 @@ #define LVL_DOWN_TEXT "SCROLL FWD" #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_SAVE BUTTON_SELECT #define PEGBOX_UP BUTTON_UP #define PEGBOX_DOWN BUTTON_DOWN #define PEGBOX_RIGHT BUTTON_RIGHT @@ -205,9 +188,6 @@ #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" #elif CONFIG_KEYPAD == GIGABEAT_PAD #define PEGBOX_SAVE BUTTON_SELECT @@ -295,9 +275,8 @@ #define LVL_DOWN_TEXT "VOL-" #elif CONFIG_KEYPAD == SANSA_M200_PAD -#define PEGBOX_SAVE (BUTTON_SELECT | BUTTON_REL) +#define PEGBOX_SAVE BUTTON_SELECT #define PEGBOX_QUIT BUTTON_POWER -#define PEGBOX_RESTART (BUTTON_SELECT | BUTTON_UP) #define PEGBOX_LVL_UP BUTTON_VOL_UP #define PEGBOX_LVL_DOWN BUTTON_VOL_DOWN #define PEGBOX_UP BUTTON_UP @@ -718,116 +697,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 +773,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 +786,18 @@ } /***************************************************************************** -* 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 +847,16 @@ 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 +880,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 +893,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,327 +907,160 @@ } 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; - - /* 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; +/*********************************************************************** +* pegbox_help() display help text +************************************************************************/ +static int pegbox_help(void) +{ + rb->lcd_setfont(FONT_UI); +#define WORDS (sizeof help_text / sizeof (char*)) + 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":", + "Select", "new", "block", "", +#ifdef RESTART_TEXT + RESTART_TEXT":", "Restart", "current", "level", "", +#endif +#ifdef LVL_UP_TEXT + LVL_UP_TEXT":", "Go", "up", "a", "level", "", +#endif +#ifdef LVL_DOWN_TEXT + LVL_DOWN_TEXT":", "Go", "down", "a", "level", "", +#endif + QUIT_TEXT":", "Return", "to", "menu", + }; + struct style_text formation[WORDS]={}; + formation[0].center=1; + formation[0].underline=1; + formation[2].color=C_RED; + formation[46].color=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; } - 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; +/*********************************************************************** +* 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 (ingame) { + MENUITEM_STRINGLIST (main_menu, "Pegbox Menu", NULL, + "Resume Game", + "Restart Level", + "Select Level", + "Help", + "Playback Control", + "Quit"); + + while (true) { + choice = rb->do_menu(&main_menu, &choice, NULL, false); + switch (choice) { + 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; + } + } } - - /* 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; + else { + MENUITEM_STRINGLIST (main_menu, "Pegbox Menu", NULL, + "Start Game", + "Select Level", + "Help", + "Playback Control", + "Quit"); + + while (true) { + choice = rb->do_menu(&main_menu, &choice, NULL, false); + switch (choice) { + 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; + } + } } - - 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) { +/*********************************************************************** +* pegbox_main() is the main game subroutine +************************************************************************/ +static int pegbox_main(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; - - 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 (pegbox_menu(pb, false)==1) { + return 1; + } - 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 */ + while (true) { 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; - } - } - } -#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; - - while (true) { - temp_var = rb->button_get(true); -#ifdef HAVE_TOUCHSCREEN - if(temp_var & BUTTON_TOUCHSCREEN) - { pegbox_raster_btn.two_d_from.y = pb->player_row; pegbox_raster_btn.two_d_from.x = pb->player_col; @@ -1361,57 +1068,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 +1126,44 @@ } 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->lcd_clear_display(); + 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 +1172,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; }