summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2009-08-02 16:41:30 +0000
committerThomas Martitz <kugel@rockbox.org>2009-08-02 16:41:30 +0000
commit322fae42992040a30416ddd1587fd96dbca0a5e7 (patch)
treef9873dd12ea04ae1c7f210a86c182f27c4d0d0a1 /apps
parent1060326f027292b0760666180019359fc6e0240f (diff)
downloadrockbox-322fae42992040a30416ddd1587fd96dbca0a5e7.tar.gz
rockbox-322fae42992040a30416ddd1587fd96dbca0a5e7.tar.bz2
rockbox-322fae42992040a30416ddd1587fd96dbca0a5e7.zip
A bit of rework in bubbles:
*) Change saving mechanism: always save into RAM on any exit button, and offer an additional quit item in the game menu (so that 1 item doesn't save -> no disk spinup) *) Change loading mechanism: always load on entering the game, but delete the save file still on actually resuming (that fixes weirdnesses with the level choosing menu item) *) Remove the highscores from the bubbles struct. *) Swap the "Start New Game" and "Resume Game" menu items to help against accidental deletion of progress. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@22116 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r--apps/plugins/bubbles.c189
1 files changed, 102 insertions, 87 deletions
diff --git a/apps/plugins/bubbles.c b/apps/plugins/bubbles.c
index 4ed15bd124..1f1e3ac905 100644
--- a/apps/plugins/bubbles.c
+++ b/apps/plugins/bubbles.c
@@ -38,12 +38,15 @@ PLUGIN_HEADER
#define SAVE_FILE PLUGIN_GAMES_DIR "/bubbles.save"
/* final game return status */
-#define BB_NONE 5
-#define BB_WIN 4
-#define BB_END 3
-#define BB_USB 2
-#define BB_QUIT 1
-#define BB_LOSE 0
+enum {
+ BB_LOSE,
+ BB_QUIT,
+ BB_QUIT_AND_SAVE,
+ BB_USB,
+ BB_END,
+ BB_WIN,
+ BB_NONE,
+};
/* play board dimension */
#define BB_HEIGHT 12
@@ -1223,7 +1226,6 @@ struct tile {
* score is the current score
* level is the current level
* highlevel is the highest level beaten
- * highscores is the list of high scores
* angle is the current cannon direction
* shots is the number of shots fired since last compression
* compress is the height of the compressor
@@ -1240,8 +1242,7 @@ struct tile {
struct game_context {
unsigned int score;
unsigned int level;
- struct highscore highlevel;
- struct highscore highscores[NUM_SCORES];
+ unsigned int highlevel;
int angle;
int shots;
int compress;
@@ -1252,10 +1253,14 @@ struct game_context {
long elapsedlvl;
long elapsedshot;
long startedshot;
- bool resume;
struct tile playboard[BB_HEIGHT][BB_WIDTH];
};
+struct highscore highscores[NUM_SCORES];
+
+/* used to denote available resume info */
+static bool resume = false;
+
static void bubbles_init(struct game_context* bb);
static bool bubbles_nextlevel(struct game_context* bb);
static void bubbles_getonboard(struct game_context* bb);
@@ -1288,8 +1293,9 @@ static void bubbles_init(struct game_context* bb) {
rb->srand(*rb->current_tick);
/* check for resumed game */
- if(bb->resume) {
- bb->resume = false;
+ if (resume)
+ {
+ resume = false;
return;
}
@@ -1304,11 +1310,16 @@ static void bubbles_init(struct game_context* bb) {
static bool bubbles_nextlevel(struct game_context* bb) {
int i, j, pos;
+ /* save highest level */
+ if (bb->level > bb->highlevel)
+ bb->highlevel = bb->level;
+
bb->level++;
/* check if there are no more levels */
if(bb->level > NUM_LEVELS) return false;
+
/* set up the play board */
rb->memset(bb->playboard, 0, sizeof(bb->playboard));
for(i=0; i<BB_LEVEL_HEIGHT; i++) {
@@ -2112,11 +2123,11 @@ static void bubbles_recordscore(struct game_context* bb) {
int position;
position = highscore_update(bb->score, bb->level, "",
- bb->highscores, NUM_SCORES);
+ highscores, NUM_SCORES);
if (position==0)
rb->splash(HZ*2, "New High Score");
if (position != -1)
- highscore_show(position, bb->highscores, NUM_SCORES);
+ highscore_show(position, highscores, NUM_SCORES);
}
/*****************************************************************************
@@ -2124,11 +2135,21 @@ static void bubbles_recordscore(struct game_context* bb) {
******************************************************************************/
static void bubbles_loadscores(struct game_context* bb) {
+ int i;
+ int highlevel = 0;
/* highlevel and highscores */
- highscore_load(SCORE_FILE, &bb->highlevel, NUM_SCORES+1);
+ highscore_load(SCORE_FILE, highscores, NUM_SCORES);
+
+ for (i = 0; i < NUM_SCORES; i++)
+ {
+ if (highscores[i].level >= highlevel)
+ {
+ highlevel = highscores[i].level+1;
+ }
+ }
- if( bb->highlevel.level >= NUM_LEVELS )
- bb->highlevel.level = NUM_LEVELS - 1;
+ if (bb->highlevel < (unsigned)highlevel)
+ bb->highlevel = highlevel;
}
/*****************************************************************************
@@ -2136,8 +2157,9 @@ static void bubbles_loadscores(struct game_context* bb) {
******************************************************************************/
static void bubbles_savescores(struct game_context* bb) {
- /* highlevel and highscores */
- highscore_save(SCORE_FILE, &bb->highlevel, NUM_SCORES+1);
+ /* highscores */
+ (void)bb;
+ highscore_save(SCORE_FILE, highscores, NUM_SCORES+1);
}
/*****************************************************************************
@@ -2145,35 +2167,22 @@ static void bubbles_savescores(struct game_context* bb) {
******************************************************************************/
static bool bubbles_loadgame(struct game_context* bb) {
int fd;
- bool loaded = false;
+ bool ret = true;
/* open game file */
fd = rb->open(SAVE_FILE, O_RDONLY);
- if(fd < 0) return loaded;
+ if(fd < 0) return false;
/* read in saved game */
- while(true) {
- if(rb->read(fd, &bb->score, sizeof(bb->score)) <= 0) break;
- if(rb->read(fd, &bb->level, sizeof(bb->level)) <= 0) break;
- if(rb->read(fd, &bb->angle, sizeof(bb->angle)) <= 0) break;
- if(rb->read(fd, &bb->shots, sizeof(bb->shots)) <= 0) break;
- if(rb->read(fd, &bb->compress, sizeof(bb->compress)) <= 0) break;
- if(rb->read(fd, &bb->onboardcnt, sizeof(bb->onboardcnt)) <= 0) break;
- if(rb->read(fd, bb->onboard, sizeof(bb->onboard)) <= 0) break;
- if(rb->read(fd, &bb->nextinq, sizeof(bb->nextinq)) <= 0) break;
- if(rb->read(fd, bb->queue, sizeof(bb->queue)) <= 0) break;
- if(rb->read(fd, &bb->elapsedlvl, sizeof(bb->elapsedlvl)) <= 0) break;
- if(rb->read(fd, bb->playboard, sizeof(bb->playboard)) <= 0) break;
- bb->resume = true;
- loaded = true;
- break;
+ if(rb->read(fd, bb, sizeof(struct game_context))
+ < (long)sizeof(struct game_context))
+ {
+ ret = false;
}
+ DEBUGF("highlevel: %d\n", bb->highlevel);
rb->close(fd);
-
- /* delete saved file */
- rb->remove(SAVE_FILE);
- return loaded;
+ return ret;
}
/*****************************************************************************
@@ -2182,22 +2191,22 @@ static bool bubbles_loadgame(struct game_context* bb) {
static void bubbles_savegame(struct game_context* bb) {
int fd;
+ if (!resume) /* nothing to save */
+ return;
/* write out the game state to the save file */
fd = rb->open(SAVE_FILE, O_WRONLY|O_CREAT);
- rb->write(fd, &bb->score, sizeof(bb->score));
- rb->write(fd, &bb->level, sizeof(bb->level));
- rb->write(fd, &bb->angle, sizeof(bb->angle));
- rb->write(fd, &bb->shots, sizeof(bb->shots));
- rb->write(fd, &bb->compress, sizeof(bb->compress));
- rb->write(fd, &bb->onboardcnt, sizeof(bb->onboardcnt));
- rb->write(fd, bb->onboard, sizeof(bb->onboard));
- rb->write(fd, &bb->nextinq, sizeof(bb->nextinq));
- rb->write(fd, bb->queue, sizeof(bb->queue));
- rb->write(fd, &bb->elapsedlvl, sizeof(bb->elapsedlvl));
- rb->write(fd, bb->playboard, sizeof(bb->playboard));
+ if (fd < 0)
+ {
+ rb->splash(HZ/2, "Failed to save game");
+ return;
+ }
+ if (rb->write(fd, bb, sizeof(struct game_context)) <= 0)
+ {
+ rb->splash(HZ/2, "Failed to save game");
+ }
+ DEBUGF("highlevel: %d\n", bb->highlevel);
rb->close(fd);
- bb->resume = true;
}
/*****************************************************************************
@@ -2280,14 +2289,12 @@ static int bubbles_handlebuttons(struct game_context* bb, bool animblock,
break;
case BUBBLES_RESUME: /* save and end the game */
+ case BUBBLES_QUIT: /* end the game */
if(!animblock) {
- rb->splash(HZ/2, "Saving game...");
- bubbles_savegame(bb);
+ resume = true;
return BB_END;
}
break;
- case BUBBLES_QUIT: /* end the game */
- return BB_END;
case ACTION_UNKNOWN:
case ACTION_NONE: /* no button pressed */
@@ -2312,44 +2319,51 @@ static int bubbles(struct game_context* bb) {
bool startgame = false;
long timeout;
- /* don't resume by default */
- bb->resume = false;
-
/********************
* menu *
********************/
MENUITEM_STRINGLIST(menu,"Bubbles Menu",NULL,
- "Start New Game", "Resume Game",
+ "Resume Game", "Start New Game",
"Level", "High Scores", "Playback Control",
- "Quit");
+ "Quit", "Quit and Save");
while(!startgame){
switch (rb->do_menu(&menu, NULL, NULL, false))
{
- case 0: /* new game */
- bb->level = startlevel;
- startgame = true;
- break;
- case 1: /* resume game */
- if(!bubbles_loadgame(bb)) {
- rb->splash(HZ*2, "Nothing to resume");
- } else {
+ case 0: /* resume game */
+ if (!resume)
+ {
+ rb->splash(HZ/2, "Nothing to resume");
+ break;
+ }
+ else
+ {
+ startlevel = bb->level - 1;
startgame = true;
}
+ /* delete saved file */
+ rb->remove(SAVE_FILE);
+ break;
+ case 1: /* new game */
+ bb->level = startlevel;
+ startgame = true;
+ resume = false;
break;
case 2: /* choose level */
startlevel++;
rb->set_int("Choose start level", "", UNIT_INT, &startlevel,
- NULL, 1, 1, bb->highlevel.level+1, NULL);
+ NULL, 1, 1, bb->highlevel+1, NULL);
startlevel--;
break;
case 3: /* High scores */
- highscore_show(NUM_SCORES, bb->highscores, NUM_SCORES);
+ highscore_show(NUM_SCORES, highscores, NUM_SCORES);
break;
case 4: /* Playback Control */
playback_control(NULL);
break;
case 5: /* quit */
return BB_QUIT;
+ case 6: /* quit and save */
+ return BB_QUIT_AND_SAVE;
case MENU_ATTACHED_USB:
bubbles_callback(bb);
return BB_USB;
@@ -2404,14 +2418,16 @@ static int bubbles(struct game_context* bb) {
* plugin entry point.
******************************************************************************/
enum plugin_status plugin_start(const void* parameter) {
- struct game_context bb;
+ static struct game_context bb;
bool exit = false;
+ enum plugin_status ret = PLUGIN_OK;
/* plugin init */
(void)parameter;
/* end of plugin init */
/* load files */
+ resume = bubbles_loadgame(&bb);
bubbles_loadscores(&bb);
rb->lcd_clear_display();
@@ -2426,35 +2442,34 @@ enum plugin_status plugin_start(const void* parameter) {
case BB_WIN:
rb->splash(HZ*2, "You Win!");
/* record high level */
- if( NUM_LEVELS-1 > bb.highlevel.level) {
- bb.highlevel.level = NUM_LEVELS-1;
+ if( NUM_LEVELS-1 > bb.highlevel) {
+ bb.highlevel = NUM_LEVELS-1;
}
/* record high score */
bubbles_recordscore(&bb);
break;
case BB_LOSE:
+ resume = false;
rb->splash(HZ*2, "Game Over");
+ /* record high score */
+ bubbles_recordscore(&bb);
/* fall through to BB_END */
case BB_END:
- if(!bb.resume) {
- /* record high level */
- if((int)bb.level-1 > bb.highlevel.level) {
- bb.highlevel.score = -1;
- highscore_update(0, bb.level-1, "", &bb.highlevel, 1);
- }
- /* record high score */
- bubbles_recordscore(&bb);
- }
break;
case BB_USB:
- rb->lcd_setfont(FONT_UI);
- return PLUGIN_USB_CONNECTED;
+ ret = PLUGIN_USB_CONNECTED;
+ break;
- case BB_QUIT:
+ case BB_QUIT_AND_SAVE:
+ rb->splash(HZ/2, "Saving Game and Scors");
bubbles_savescores(&bb);
+ bubbles_savegame(&bb);
+ /* fall through */
+
+ case BB_QUIT:
exit = true;
break;
@@ -2464,7 +2479,7 @@ enum plugin_status plugin_start(const void* parameter) {
}
rb->lcd_setfont(FONT_UI);
- return PLUGIN_OK;
+ return ret;
}
#endif