diff options
author | Alexander Levin <al.le@rockbox.org> | 2009-06-30 20:00:46 +0000 |
---|---|---|
committer | Alexander Levin <al.le@rockbox.org> | 2009-06-30 20:00:46 +0000 |
commit | 6a5245ae08e35bd90436ddb97a8c7fbfea89b1fd (patch) | |
tree | 1238b06f8a88573c3fe0c4a5c31c09892e263306 | |
parent | e905ca61d4a2d90d9a2fac0ae1b70c55451eaf88 (diff) | |
download | rockbox-6a5245ae08e35bd90436ddb97a8c7fbfea89b1fd.tar.gz rockbox-6a5245ae08e35bd90436ddb97a8c7fbfea89b1fd.zip |
Improve the highscore related functions in plugin lib (FS#10350)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21578 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/plugins/lib/highscore.c | 98 | ||||
-rw-r--r-- | apps/plugins/lib/highscore.h | 52 | ||||
-rw-r--r-- | apps/plugins/rockblox.c | 26 |
3 files changed, 113 insertions, 63 deletions
diff --git a/apps/plugins/lib/highscore.c b/apps/plugins/lib/highscore.c index 9d3b19ea48..e8e1c883b0 100644 --- a/apps/plugins/lib/highscore.c +++ b/apps/plugins/lib/highscore.c | |||
@@ -34,8 +34,8 @@ int highscore_save(char *filename, struct highscore *scores, int num_scores) | |||
34 | 34 | ||
35 | for(i = 0;i < num_scores;i++) | 35 | for(i = 0;i < num_scores;i++) |
36 | { | 36 | { |
37 | rb->snprintf(buf, sizeof(buf)-1, "%s:%d:%d\n", | 37 | rb->snprintf(buf, sizeof(buf), "%d:%d:%s\n", |
38 | scores[i].name, scores[i].score, scores[i].level); | 38 | scores[i].score, scores[i].level, scores[i].name); |
39 | rc = rb->write(fd, buf, rb->strlen(buf)); | 39 | rc = rb->write(fd, buf, rb->strlen(buf)); |
40 | if(rc < 0) | 40 | if(rc < 0) |
41 | { | 41 | { |
@@ -52,72 +52,62 @@ int highscore_load(char *filename, struct highscore *scores, int num_scores) | |||
52 | int i; | 52 | int i; |
53 | int fd; | 53 | int fd; |
54 | char buf[80]; | 54 | char buf[80]; |
55 | char *name, *score, *level; | 55 | char *score, *level, *name; |
56 | char *ptr; | ||
57 | 56 | ||
58 | fd = rb->open(filename, O_RDONLY); | 57 | rb->memset(scores, 0, sizeof(struct highscore)*num_scores); |
59 | 58 | ||
60 | rb->memset(scores, 0, sizeof(struct highscore)*(num_scores+1)); | 59 | fd = rb->open(filename, O_RDONLY); |
61 | |||
62 | if(fd < 0) | 60 | if(fd < 0) |
63 | return -1; | 61 | return -1; |
64 | 62 | ||
65 | i = -1; | 63 | i = 0; |
66 | while(rb->read_line(fd, buf, sizeof(buf)-1) && i < num_scores) | 64 | while(rb->read_line(fd, buf, sizeof(buf)) > 0 && i < num_scores) |
67 | { | 65 | { |
68 | i++; | ||
69 | |||
70 | DEBUGF("%s\n", buf); | 66 | DEBUGF("%s\n", buf); |
71 | name = buf; | 67 | |
72 | ptr = rb->strchr(buf, ':'); | 68 | if ( !rb->settings_parseline(buf, &score, &level) ) |
73 | if ( !ptr ) | ||
74 | continue; | 69 | continue; |
75 | *ptr = 0; | 70 | if ( !rb->settings_parseline(level, &level, &name) ) |
76 | ptr++; | ||
77 | |||
78 | rb->strncpy(scores[i].name, name, sizeof(scores[i].name)); | ||
79 | |||
80 | DEBUGF("%s\n", scores[i].name); | ||
81 | score = ptr; | ||
82 | |||
83 | ptr = rb->strchr(ptr, ':'); | ||
84 | if ( !ptr ) | ||
85 | continue; | 71 | continue; |
86 | *ptr = 0; | 72 | |
87 | ptr++; | ||
88 | |||
89 | scores[i].score = rb->atoi(score); | 73 | scores[i].score = rb->atoi(score); |
90 | |||
91 | level = ptr; | ||
92 | scores[i].level = rb->atoi(level); | 74 | scores[i].level = rb->atoi(level); |
93 | } | 75 | rb->strncpy(scores[i].name, name, sizeof(scores[i].name)-1); |
76 | i++; | ||
77 | } | ||
78 | rb->close(fd); | ||
94 | return 0; | 79 | return 0; |
95 | } | 80 | } |
96 | 81 | ||
97 | int highscore_update(int score, int level, struct highscore *scores, int num_scores) | 82 | int highscore_update(int score, int level, const char *name, |
83 | struct highscore *scores, int num_scores) | ||
98 | { | 84 | { |
99 | int i, j; | 85 | int pos; |
100 | int new = 0; | 86 | struct highscore *entry; |
101 | 87 | ||
102 | /* look through the scores and see if this one is in the top ones */ | 88 | if (!highscore_would_update(score, scores, num_scores)) |
103 | for(i = num_scores-1;i >= 0; i--) | 89 | return -1; |
90 | |||
91 | pos = num_scores-1; | ||
92 | while (pos > 0 && score > scores[pos-1].score) | ||
104 | { | 93 | { |
105 | if ((score > scores[i].score)) | 94 | /* move down one */ |
106 | { | 95 | rb->memcpy((void *)&scores[pos], (void *)&scores[pos-1], |
107 | /* Move the rest down one... */ | 96 | sizeof(struct highscore)); |
108 | if (i > 0) | 97 | pos--; |
109 | { | 98 | } |
110 | for (j=1; j<=i; j++) | 99 | |
111 | { | 100 | entry = scores + pos; |
112 | rb->memcpy((void *)&scores[j-1], (void *)&scores[j], sizeof(struct highscore)); | 101 | entry->score = score; |
113 | } | 102 | entry->level = level; |
114 | } | 103 | rb->strncpy(entry->name, name, sizeof(entry->name)); |
115 | scores[i].score = score; | 104 | entry->name[sizeof(entry->name)-1] = '\0'; |
116 | scores[i].level = level; | 105 | |
117 | /* Need to sort out entering a name... maybe old three letter arcade style */ | 106 | return pos; |
118 | new = 1; | 107 | } |
119 | break; | 108 | |
120 | } | 109 | bool highscore_would_update(int score, struct highscore *scores, |
121 | } | 110 | int num_scores) |
122 | return new; | 111 | { |
112 | return (num_scores > 0) && (score > scores[num_scores-1].score); | ||
123 | } | 113 | } |
diff --git a/apps/plugins/lib/highscore.h b/apps/plugins/lib/highscore.h index db09172c7d..a38a6f7bf3 100644 --- a/apps/plugins/lib/highscore.h +++ b/apps/plugins/lib/highscore.h | |||
@@ -21,6 +21,8 @@ | |||
21 | #ifndef HIGHSCORE_H | 21 | #ifndef HIGHSCORE_H |
22 | #define HIGHSCORE_H | 22 | #define HIGHSCORE_H |
23 | 23 | ||
24 | /* see rockblox.c for the example of usage. */ | ||
25 | |||
24 | struct highscore | 26 | struct highscore |
25 | { | 27 | { |
26 | char name[32]; | 28 | char name[32]; |
@@ -28,8 +30,56 @@ struct highscore | |||
28 | int level; | 30 | int level; |
29 | }; | 31 | }; |
30 | 32 | ||
33 | /* Saves the scores to a file | ||
34 | * - filename: name of the file to write the data to | ||
35 | * - scores : scores to store | ||
36 | * - num_scores: number of the elements in the array 'scores' | ||
37 | * Returns 0 on success or a negative value if an error occures | ||
38 | */ | ||
31 | int highscore_save(char *filename, struct highscore *scores, int num_scores); | 39 | int highscore_save(char *filename, struct highscore *scores, int num_scores); |
40 | |||
41 | /* Reads the scores from a file. The file must be a text file, each line | ||
42 | * represents a score entry. | ||
43 | * | ||
44 | * - filename: name of the file to read the data from | ||
45 | * - scores : where to put the read data | ||
46 | * - num_scores: max number of the scores to read (array capacity) | ||
47 | * | ||
48 | * Returns 0 on success or a negative value if an error occures | ||
49 | */ | ||
32 | int highscore_load(char *filename, struct highscore *scores, int num_scores); | 50 | int highscore_load(char *filename, struct highscore *scores, int num_scores); |
33 | int highscore_update(int score, int level, struct highscore *scores, int num_scores); | 51 | |
52 | /* Inserts score and level into array of struct highscore in the | ||
53 | * descending order of scores, i.e. higher scores are at lower array | ||
54 | * indexes. | ||
55 | * | ||
56 | * - score : the new score value to insert | ||
57 | * - level : the game level at which the score was reached | ||
58 | * - name : the name of the new entry (whatever it means) | ||
59 | * - scores: the array of scores to insert the new value into | ||
60 | * - num_scores: number of elements in 'scores' | ||
61 | * | ||
62 | * Returns the 0-based position of the newly inserted score if it was | ||
63 | * inserted. Returns a negative value if the score was not inserted | ||
64 | * (i.e. it was less than the lowest score in the array). | ||
65 | */ | ||
66 | int highscore_update(int score, int level, const char *name, | ||
67 | struct highscore *scores, int num_scores); | ||
68 | |||
69 | /* Checks whether the new score would be inserted into the score table. | ||
70 | * This function can be used to find out whether a score with the given | ||
71 | * value would be inserted into the score table. If yes, the program | ||
72 | * can collect the name of the entry from the user (if it's done that | ||
73 | * way) and then really update the score table with 'highscore_update'. | ||
74 | * | ||
75 | * - score : the score value to check | ||
76 | * - scores: the array of existing scores | ||
77 | * - num_scores: number of elements in 'scores' | ||
78 | * | ||
79 | * Returns true iff the given score would be inserted into the score | ||
80 | * table by highscore_update. | ||
81 | */ | ||
82 | bool highscore_would_update(int score, struct highscore *scores, | ||
83 | int num_scores); | ||
34 | 84 | ||
35 | #endif | 85 | #endif |
diff --git a/apps/plugins/rockblox.c b/apps/plugins/rockblox.c index 7aaf26fe03..9b4987747d 100644 --- a/apps/plugins/rockblox.c +++ b/apps/plugins/rockblox.c | |||
@@ -723,7 +723,7 @@ figures[BLOCKS_NUM] = { | |||
723 | #define MAX_HIGH_SCORES 5 | 723 | #define MAX_HIGH_SCORES 5 |
724 | 724 | ||
725 | /* Default High Scores... */ | 725 | /* Default High Scores... */ |
726 | struct highscore Highest[MAX_HIGH_SCORES]; | 726 | struct highscore highest[MAX_HIGH_SCORES]; |
727 | 727 | ||
728 | /* get random number from (0) to (range-1) */ | 728 | /* get random number from (0) to (range-1) */ |
729 | static int t_rand (int range) | 729 | static int t_rand (int range) |
@@ -776,10 +776,11 @@ static void show_highscores (void) | |||
776 | int i; | 776 | int i; |
777 | char str[25]; /* for strings */ | 777 | char str[25]; /* for strings */ |
778 | 778 | ||
779 | for (i = MAX_HIGH_SCORES-1; i>=0; i--) | 779 | for (i = 0; i<MAX_HIGH_SCORES; i++) |
780 | { | 780 | { |
781 | rb->snprintf (str, sizeof (str), "%06d" _SPACE "L%1d",Highest[i].score, Highest[i].level); | 781 | rb->snprintf (str, sizeof (str), "%06d" _SPACE "L%1d", |
782 | rb->lcd_putsxy (HIGH_LABEL_X, HIGH_SCORE_Y + (10 * ((MAX_HIGH_SCORES-1) - i)), str); | 782 | highest[i].score, highest[i].level); |
783 | rb->lcd_putsxy (HIGH_LABEL_X, HIGH_SCORE_Y + (10 * i), str); | ||
783 | } | 784 | } |
784 | } | 785 | } |
785 | #endif | 786 | #endif |
@@ -831,8 +832,17 @@ fail: | |||
831 | } | 832 | } |
832 | static void init_rockblox (bool resume) | 833 | static void init_rockblox (bool resume) |
833 | { | 834 | { |
834 | highscore_update(rockblox_status.score, rockblox_status.level, Highest, | 835 | char score_name[50]; |
835 | MAX_HIGH_SCORES); | 836 | struct tm* tm; |
837 | |||
838 | tm = rb->get_time(); | ||
839 | rb->snprintf(score_name, sizeof(score_name), "%04d%02d%02d %02d%02d%02d", | ||
840 | tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, | ||
841 | tm->tm_hour, tm->tm_min, tm->tm_sec); | ||
842 | |||
843 | highscore_update(rockblox_status.score, rockblox_status.level, | ||
844 | score_name, highest, MAX_HIGH_SCORES); | ||
845 | |||
836 | #ifdef HAVE_LCD_BITMAP | 846 | #ifdef HAVE_LCD_BITMAP |
837 | rb->lcd_bitmap (rockblox_background, 0, 0, LCD_WIDTH, LCD_HEIGHT); | 847 | rb->lcd_bitmap (rockblox_background, 0, 0, LCD_WIDTH, LCD_HEIGHT); |
838 | #else /* HAVE_LCD_CHARCELLS */ | 848 | #else /* HAVE_LCD_CHARCELLS */ |
@@ -1332,7 +1342,7 @@ enum plugin_status plugin_start (const void *parameter) | |||
1332 | rb->srand (*rb->current_tick); | 1342 | rb->srand (*rb->current_tick); |
1333 | 1343 | ||
1334 | /* Load HighScore if any */ | 1344 | /* Load HighScore if any */ |
1335 | highscore_load(HIGH_SCORE,Highest,MAX_HIGH_SCORES); | 1345 | highscore_load(HIGH_SCORE, highest, MAX_HIGH_SCORES); |
1336 | 1346 | ||
1337 | #if LCD_DEPTH > 1 | 1347 | #if LCD_DEPTH > 1 |
1338 | rb->lcd_set_backdrop(NULL); | 1348 | rb->lcd_set_backdrop(NULL); |
@@ -1357,7 +1367,7 @@ enum plugin_status plugin_start (const void *parameter) | |||
1357 | pgfx_release(); | 1367 | pgfx_release(); |
1358 | #endif | 1368 | #endif |
1359 | /* Save user's HighScore */ | 1369 | /* Save user's HighScore */ |
1360 | highscore_save(HIGH_SCORE,Highest,MAX_HIGH_SCORES); | 1370 | highscore_save(HIGH_SCORE, highest, MAX_HIGH_SCORES); |
1361 | backlight_use_settings(); /* backlight control in lib/helper.c */ | 1371 | backlight_use_settings(); /* backlight control in lib/helper.c */ |
1362 | 1372 | ||
1363 | dump_resume(); | 1373 | dump_resume(); |