Ticket #552: score.diff

File score.diff, 22.4 KB (added by takkaria, 11 years ago)

First go at fixing this up

  • score.c

     
    2828 * 
    2929 * Note that "string comparisons" are thus valid on "pts". 
    3030 */ 
    31  
    32 typedef struct high_score high_score; 
    33  
    34 struct high_score 
     31typedef struct 
    3532{ 
    3633        char what[8];           /* Version info (string) */ 
    3734 
     
    5754        char max_dun[4];                /* Max Dungeon Level (number) */ 
    5855 
    5956        char how[32];           /* Method of death (string) */ 
    60 }; 
     57} high_score; 
    6158 
    6259 
    6360 
    6461/* 
    65  * Hack - save index of player's high score 
    66  */ 
    67 int score_idx = -1; 
    68  
    69  
    70  
    71 /* 
    7262 * Hack -- Calculates the total number of points earned 
    7363 */ 
    7464static long total_points(void) 
     
    7868 
    7969 
    8070/* 
    81  * Seek score 'i' in the highscore file 
     71 * Read in a highscore file. 
    8272 */ 
    83 static bool highscore_seek(ang_file *f, int i) 
     73static size_t highscore_read(high_score scores[], size_t sz) 
    8474{ 
    85         /* Seek for the requested record */ 
    86         return (file_seek(f, i * sizeof(high_score))); 
    87 } 
     75        char fname[1024]; 
     76        ang_file *scorefile; 
     77        size_t i; 
    8878 
     79        /* Wipe current scores */ 
     80        C_WIPE(scores, sz, high_score); 
    8981 
    90 /* 
    91  * Read one score from the highscore file 
    92  */ 
    93 static bool highscore_read(ang_file *f, high_score *score) 
    94 { 
    95         /* Read the record, note failure */ 
    96         return (file_read(f, (char *)score, sizeof(high_score)) > 0); 
     82        path_build(fname, sizeof(fname), ANGBAND_DIR_APEX, "scores.raw"); 
     83        scorefile = file_open(fname, MODE_READ, -1); 
     84 
     85        if (!scorefile) return TRUE; 
     86 
     87        for (i = 0; i < sz && 
     88                    file_read(scorefile, (char *)&scores[i], sizeof(high_score)); i++) 
     89                ; 
     90 
     91        file_close(scorefile); 
     92 
     93        return i; 
    9794} 
    9895 
     96 
    9997/* 
    10098 * Just determine where a new score *would* be placed 
    10199 * Return the location (0 is best) or -1 on failure 
    102100 */ 
    103 static int highscore_where(ang_file *f, const high_score *score) 
     101static size_t highscore_where(const high_score *entry, const high_score scores[], size_t sz) 
    104102{ 
    105         int i; 
    106         high_score the_score; 
     103        size_t i; 
    107104 
    108         /* Go to the start of the highscore file */ 
    109         if (!highscore_seek(f, 0)) return (-1); 
    110  
    111105        /* Read until we get to a higher score */ 
    112         for (i = 0; i < MAX_HISCORES; i++) 
     106        for (i = 0; i < sz; i++) 
    113107        { 
    114                 if (!highscore_read(f, &the_score)) return (i); 
    115                 if (strcmp(the_score.pts, score->pts) < 0) return (i); 
     108                long entry_pts = strtoul(entry->pts, NULL, 0); 
     109                long score_pts = strtoul(scores[i].pts, NULL, 0); 
     110 
     111                if (entry_pts >= score_pts) 
     112                        return i; 
     113 
     114                if (scores[i].what[0] == '\0') 
     115                        return i; 
    116116        } 
    117117 
    118         /* The "last" entry is always usable */ 
    119         return (MAX_HISCORES - 1); 
     118        /* The last entry is always usable */ 
     119        return sz - 1; 
    120120} 
    121121 
     122static size_t highscore_add(const high_score *entry, high_score scores[], size_t sz) 
     123{ 
     124        size_t slot = highscore_where(entry, scores, sz); 
     125 
     126        memmove(&scores[slot+1], &scores[slot], sizeof(high_score) * (sz - 1 - slot)); 
     127        memcpy(&scores[slot], entry, sizeof(high_score)); 
     128 
     129        return slot; 
     130} 
     131 
     132static size_t highscore_count(const high_score scores[], size_t sz) 
     133{ 
     134        size_t i; 
     135        for (i = 0; i < sz; i++) 
     136        { 
     137                if (scores[i].what[0] == '\0') break; 
     138        } 
     139 
     140        return i; 
     141} 
     142 
     143 
    122144/* 
    123145 * Actually place an entry into the high score file 
    124146 * Return the location (0 is best) or -1 on "failure" 
    125147 */ 
    126 static int highscore_add(const high_score *score) 
     148static void highscore_write(const high_score scores[], size_t sz) 
    127149{ 
    128         int i, slot; 
    129         bool error = FALSE; 
     150        size_t n; 
    130151 
    131         high_score tmpscore; 
     152        ang_file *lok; 
     153        ang_file *scorefile; 
    132154 
    133         ang_file *old, *new, *lok; 
    134         char cur_name[1024]; 
    135155        char old_name[1024]; 
     156        char cur_name[1024]; 
    136157        char new_name[1024]; 
    137158        char lok_name[1024]; 
    138159 
    139         path_build(cur_name, sizeof(cur_name), ANGBAND_DIR_APEX, "scores.raw"); 
    140160        path_build(old_name, sizeof(old_name), ANGBAND_DIR_APEX, "scores.old"); 
     161        path_build(cur_name, sizeof(cur_name), ANGBAND_DIR_APEX, "scores.raw"); 
    141162        path_build(new_name, sizeof(new_name), ANGBAND_DIR_APEX, "scores.new"); 
    142163        path_build(lok_name, sizeof(lok_name), ANGBAND_DIR_APEX, "scores.lok"); 
    143164 
    144165 
    145         old = file_open(cur_name, MODE_READ, -1); 
     166        /* Read in and add new score */ 
     167        n = highscore_count(scores, sz); 
    146168 
     169 
     170        /*** Lock scores ***/ 
     171 
     172        if (file_exists(lok_name)) 
     173        { 
     174                msg_print("Lock file in place for scorefile; not writing."); 
     175                return; 
     176        } 
     177 
    147178        safe_setuid_grab(); 
    148         new = file_open(new_name, MODE_WRITE, FTYPE_RAW); 
    149179        lok = file_open(lok_name, MODE_WRITE, FTYPE_RAW); 
    150         if (new && lok) 
    151                 file_lock(lok); 
     180        file_lock(lok); 
    152181        safe_setuid_drop(); 
    153182 
    154         if (!new || !lok) return -1; 
    155  
    156         /* Determine where the score should go */ 
    157         if (old) 
     183        if (!lok) 
    158184        { 
    159                 slot = highscore_where(old, score); 
     185                msg_print("Failed to create lock for scorefile; not writing."); 
     186                return; 
     187        } 
    160188 
    161                 /* Read entries from the old and write them to the new */ 
    162                 for (i = 0; (i < MAX_HISCORES) && !error; i++) 
    163                 { 
    164                         if (!highscore_seek(old, i)) return (-1); 
    165189 
    166                         /* Insert the new one at the right slot */ 
    167                         if (i == slot) 
    168                         { 
    169                                 if (!file_write(new, (const char *)score, sizeof(high_score))) 
    170                                 { 
    171                                         error = TRUE; 
    172                                         slot = -1; 
    173                                 } 
    174                         } 
    175          
    176                         /* Read old one, write again */ 
    177                         if (highscore_read(old, &tmpscore)) 
    178                         { 
    179                                 if (!file_write(new, (const char *)&tmpscore, sizeof(high_score))) 
    180                                 { 
    181                                         error = TRUE; 
    182                                         slot = -1; 
    183                                 } 
    184                         } 
    185                 } 
     190        /*** Open the new file for writing ***/ 
    186191 
    187                 file_close(old); 
    188         } 
    189         else 
     192        safe_setuid_grab(); 
     193        scorefile = file_open(new_name, MODE_WRITE, FTYPE_RAW); 
     194        safe_setuid_drop(); 
     195 
     196        if (!scorefile) 
    190197        { 
    191                 slot = 0; 
    192                 if (!file_write(new, (const char *)score, sizeof(high_score))) 
    193                 { 
    194                         error = TRUE; 
    195                         slot = -1; 
    196                 } 
     198                msg_print("Failed to open new scorefile for writing."); 
     199 
     200                file_close(lok); 
     201                file_delete(lok_name); 
     202                return; 
    197203        } 
    198204 
    199         file_close(new); 
     205        file_write(scorefile, (const char *)&scores, sizeof(high_score)*n); 
     206        file_close(scorefile); 
    200207 
    201         /* Move things around */ 
     208        /*** Now move things around ***/ 
     209 
    202210        safe_setuid_grab(); 
    203211 
    204         file_delete(old_name); 
     212        if (file_exists(old_name) && !file_delete(old_name)) 
     213                msg_print("Couldn't delete old scorefile"); 
    205214 
    206         file_move(cur_name, old_name); 
    207         file_move(new_name, cur_name); 
    208         file_delete(old_name); 
     215        if (file_exists(cur_name) && !file_move(cur_name, old_name)) 
     216                msg_print("Couldn't move old scores.raw out of the way"); 
    209217 
     218        if (!file_move(new_name, cur_name)) 
     219                msg_print("Couldn't rename new scorefile to scores.raw"); 
     220 
     221        /* Remove the lock */ 
    210222        file_close(lok); 
    211         safe_setuid_drop(); 
     223        file_delete(lok_name); 
    212224 
    213         /* Return location used */ 
    214         return (slot); 
     225        safe_setuid_drop(); 
    215226} 
    216227 
    217228 
    218229 
    219230/* 
    220231 * Display the scores in a given range. 
    221  * Assumes the high score list is already open. 
    222  * Only five entries per line, too much info. 
    223  * 
    224  * Mega-Hack -- allow "fake" entry at the given position. 
    225232 */ 
    226 static void display_scores_aux(int from, int to, int note, high_score *score) 
     233static void display_scores_aux(const high_score scores[], int from, int to, int highlight) 
    227234{ 
    228235        char ch; 
    229236 
    230237        int j, k, n, place; 
    231238        int count; 
    232239 
    233         high_score the_score; 
    234240 
    235         char out_val[160]; 
    236         char tmp_val[160]; 
    237  
    238         byte attr; 
    239  
    240         ang_file *f; 
    241         char buf[1024]; 
    242  
    243  
    244         path_build(buf, sizeof(buf), ANGBAND_DIR_APEX, "scores.raw"); 
    245         f = file_open(buf, MODE_READ, -1); 
    246         if (!f) return; 
    247  
    248241        /* Assume we will show the first 10 */ 
    249242        if (from < 0) from = 0; 
    250243        if (to < 0) to = 10; 
     
    254247        /* Hack -- Count the high scores */ 
    255248        for (count = 0; count < MAX_HISCORES; count++) 
    256249        { 
    257                 if (!highscore_read(f, &the_score)) break; 
     250                if (!scores[count].what[0]) break; 
    258251        } 
    259252 
    260         /* Hack -- allow "fake" entry to be last */ 
    261         if ((note == count) && score) count++; 
    262  
    263253        /* Forget about the last entries */ 
    264254        if (count > to) count = to; 
    265255 
     
    267257        /* Show 5 per page, until "done" */ 
    268258        for (k = from, j = from, place = k+1; k < count; k += 5) 
    269259        { 
     260                char out_val[160]; 
     261                char tmp_val[160]; 
     262 
    270263                /* Clear screen */ 
    271264                Term_clear(); 
    272265 
    273266                /* Title */ 
    274267                put_str(format("%s Hall of Fame", VERSION_NAME), 0, 26); 
    275268 
    276  
    277269                /* Indicate non-top scores */ 
    278270                if (k > 0) 
    279                 { 
    280                         strnfmt(tmp_val, sizeof(tmp_val), "(from position %d)", place); 
    281                         put_str(tmp_val, 0, 40); 
    282                 } 
     271                        put_str(format("(from position %d)", place), 0, 40); 
    283272 
     273 
    284274                /* Dump 5 entries */ 
    285275                for (n = 0; j < count && n < 5; place++, j++, n++) 
    286276                { 
    287                         int pr, pc, clev, mlev, cdun, mdun; 
     277                        const high_score *score = &scores[j]; 
    288278 
     279                        byte attr; 
     280 
     281                        int pr, pc, clev, mlev, cdun, mdun; 
    289282                        cptr user, gold, when, aged; 
    290283 
    291284 
    292285                        /* Hack -- indicate death in yellow */ 
    293                         attr = (j == note) ? TERM_YELLOW : TERM_WHITE; 
     286                        attr = (j == highlight) ? TERM_L_GREEN : TERM_WHITE; 
    294287 
    295  
    296                         /* Mega-Hack -- insert a "fake" record */ 
    297                         if ((note == j) && score) 
    298                         { 
    299                                 the_score = (*score); 
    300                                 attr = TERM_L_GREEN; 
    301                                 score = NULL; 
    302                                 note = -1; 
    303                                 j--; 
    304                         } 
    305  
    306                         /* Read a normal record */ 
    307                         else 
    308                         { 
    309                                 /* Read the proper record */ 
    310                                 if (!highscore_seek(f, j)) break; 
    311                                 if (!highscore_read(f, &the_score)) break; 
    312                         } 
    313  
    314288                        /* Extract the race/class */ 
    315                         pr = atoi(the_score.p_r); 
    316                         pc = atoi(the_score.p_c); 
     289                        pr = atoi(score->p_r); 
     290                        pc = atoi(score->p_c); 
    317291 
    318292                        /* Extract the level info */ 
    319                         clev = atoi(the_score.cur_lev); 
    320                         mlev = atoi(the_score.max_lev); 
    321                         cdun = atoi(the_score.cur_dun); 
    322                         mdun = atoi(the_score.max_dun); 
     293                        clev = atoi(score->cur_lev); 
     294                        mlev = atoi(score->max_lev); 
     295                        cdun = atoi(score->cur_dun); 
     296                        mdun = atoi(score->max_dun); 
    323297 
    324298                        /* Hack -- extract the gold and such */ 
    325                         for (user = the_score.uid; isspace((unsigned char)*user); user++) /* loop */; 
    326                         for (when = the_score.day; isspace((unsigned char)*when); when++) /* loop */; 
    327                         for (gold = the_score.gold; isspace((unsigned char)*gold); gold++) /* loop */; 
    328                         for (aged = the_score.turns; isspace((unsigned char)*aged); aged++) /* loop */; 
     299                        for (user = score->uid; isspace((unsigned char)*user); user++) /* loop */; 
     300                        for (when = score->day; isspace((unsigned char)*when); when++) /* loop */; 
     301                        for (gold = score->gold; isspace((unsigned char)*gold); gold++) /* loop */; 
     302                        for (aged = score->turns; isspace((unsigned char)*aged); aged++) /* loop */; 
    329303 
    330                         /* Clean up standard encoded form of "when" */ 
    331                         if ((*when == '@') && strlen(when) == 9) 
    332                         { 
    333                                 strnfmt(tmp_val, sizeof(tmp_val), 
    334                                         "%.4s-%.2s-%.2s", 
    335                                         when + 1, when + 5, when + 7); 
    336                                 when = tmp_val; 
    337                         } 
    338  
    339304                        /* Dump some info */ 
    340305                        strnfmt(out_val, sizeof(out_val), 
    341306                                "%3d.%9s  %s the %s %s, Level %d", 
    342                                 place, the_score.pts, the_score.who, 
     307                                place, score->pts, score->who, 
    343308                                p_name + p_info[pr].name, c_name + c_info[pc].name, 
    344309                                clev); 
    345310 
     
    349314                        /* Dump the first line */ 
    350315                        c_put_str(attr, out_val, n*4 + 2, 0); 
    351316 
    352                         /* Another line of info */ 
    353                         strnfmt(out_val, sizeof(out_val), 
    354                                 "               Killed by %s on dungeon level %d", 
    355                                 the_score.how, cdun); 
    356317 
    357                         /* Hack -- some people die in the town */ 
     318                        /* Died where? */ 
    358319                        if (!cdun) 
    359                         { 
    360                                 strnfmt(out_val, sizeof(out_val), 
    361                                         "               Killed by %s in the town", 
    362                                         the_score.how); 
    363                         } 
     320                                strnfmt(out_val, sizeof(out_val), "Killed by %s in the town", score->how); 
     321                        else 
     322                                strnfmt(out_val, sizeof(out_val), "Killed by %s on dungeon level %d", score->how, cdun); 
    364323 
    365324                        /* Append a "maximum level" */ 
    366                         if (mdun > cdun) my_strcat(out_val, format(" (Max %d)", mdun), sizeof(out_val)); 
     325                        if (mdun > cdun) 
     326                                my_strcat(out_val, format(" (Max %d)", mdun), sizeof(out_val)); 
    367327 
    368328                        /* Dump the info */ 
    369                         c_put_str(attr, out_val, n*4 + 3, 0); 
     329                        c_put_str(attr, out_val, n*4 + 3, 15); 
    370330 
     331 
     332                        /* Clean up standard encoded form of "when" */ 
     333                        if ((*when == '@') && strlen(when) == 9) 
     334                        { 
     335                                strnfmt(tmp_val, sizeof(tmp_val), "%.4s-%.2s-%.2s", when + 1, when + 5, when + 7); 
     336                                when = tmp_val; 
     337                        } 
     338 
    371339                        /* And still another line of info */ 
    372                         strnfmt(out_val, sizeof(out_val), 
    373                                 "               (User %s, Date %s, Gold %s, Turn %s).", 
    374                                 user, when, gold, aged); 
    375                         c_put_str(attr, out_val, n*4 + 4, 0); 
     340                        strnfmt(out_val, sizeof(out_val), "(User %s, Date %s, Gold %s, Turn %s).", user, when, gold, aged); 
     341                        c_put_str(attr, out_val, n*4 + 4, 15); 
    376342                } 
    377343 
    378344 
     
    385351                if (ch == ESCAPE) break; 
    386352        } 
    387353 
    388         file_close(f); 
    389354        return; 
    390355} 
    391356 
    392  
    393 /* 
    394  * Hack -- Display the scores in a given range and quit. 
    395  * 
    396  * This function is only called from "main.c" when the user asks 
    397  * to see the "high scores". 
    398  */ 
    399 void display_scores(int from, int to) 
     357static void build_score(high_score *entry, const char *died_from, time_t *death_time) 
    400358{ 
    401         display_scores_aux(from, to, -1, NULL); 
     359        WIPE(entry, high_score); 
    402360 
    403         prt("[Press any key to exit.]", 23, 17); 
    404         (void)inkey(); 
     361        /* Save the version */ 
     362        strnfmt(entry->what, sizeof(entry->what), "%s", VERSION_STRING); 
    405363 
    406         quit(NULL); 
     364        /* Calculate and save the points */ 
     365        strnfmt(entry->pts, sizeof(entry->pts), "%9lu", (long)total_points()); 
     366 
     367        /* Save the current gold */ 
     368        strnfmt(entry->gold, sizeof(entry->gold), "%9lu", (long)p_ptr->au); 
     369 
     370        /* Save the current turn */ 
     371        strnfmt(entry->turns, sizeof(entry->turns), "%9lu", (long)turn); 
     372 
     373        /* Time of death */ 
     374        if (death_time) 
     375                strftime(entry->day, sizeof(entry->day), "@%Y%m%d", localtime(death_time)); 
     376        else 
     377                my_strcpy(entry->day, "TODAY", sizeof(entry->day)); 
     378 
     379        /* Save the player name (15 chars) */ 
     380        strnfmt(entry->who, sizeof(entry->who), "%-.15s", op_ptr->full_name); 
     381 
     382        /* Save the player info XXX XXX XXX */ 
     383        strnfmt(entry->uid, sizeof(entry->uid), "%7u", player_uid); 
     384        strnfmt(entry->sex, sizeof(entry->sex), "%c", (p_ptr->psex ? 'm' : 'f')); 
     385        strnfmt(entry->p_r, sizeof(entry->p_r), "%2d", p_ptr->prace); 
     386        strnfmt(entry->p_c, sizeof(entry->p_c), "%2d", p_ptr->pclass); 
     387 
     388        /* Save the level and such */ 
     389        strnfmt(entry->cur_lev, sizeof(entry->cur_lev), "%3d", p_ptr->lev); 
     390        strnfmt(entry->cur_dun, sizeof(entry->cur_dun), "%3d", p_ptr->depth); 
     391        strnfmt(entry->max_lev, sizeof(entry->max_lev), "%3d", p_ptr->max_lev); 
     392        strnfmt(entry->max_dun, sizeof(entry->max_dun), "%3d", p_ptr->max_depth); 
     393 
     394        /* No cause of death */ 
     395        my_strcpy(entry->how, died_from, sizeof(entry->how)); 
    407396} 
    408397 
    409398 
     399 
    410400/* 
    411401 * Enters a players name on a hi-score table, if "legal". 
    412402 * 
    413403 * Assumes "signals_ignore_tstp()" has been called. 
    414404 */ 
    415 errr enter_score(time_t *death_time) 
     405void enter_score(time_t *death_time) 
    416406{ 
    417407        int j; 
    418         high_score the_score; 
    419408 
     409        /* Cheaters are not scored */ 
     410        for (j = OPT_SCORE; j < OPT_MAX; ++j) 
     411        { 
     412                if (!op_ptr->opt[j]) continue; 
     413 
     414                msg_print("Score not registered for cheaters."); 
     415                message_flush(); 
     416                return; 
     417        } 
     418 
    420419        /* Wizard-mode pre-empts scoring */ 
    421420        if (p_ptr->noscore & (NOSCORE_WIZARD | NOSCORE_DEBUG)) 
    422421        { 
    423422                msg_print("Score not registered for wizards."); 
    424423                message_flush(); 
    425                 score_idx = -1; 
    426                 return (0); 
    427424        } 
    428425 
    429426#ifndef SCORE_BORGS 
    430427 
    431428        /* Borg-mode pre-empts scoring */ 
    432         if (p_ptr->noscore & NOSCORE_BORG) 
     429        else if (p_ptr->noscore & NOSCORE_BORG) 
    433430        { 
    434431                msg_print("Score not registered for borgs."); 
    435432                message_flush(); 
    436                 score_idx = -1; 
    437                 return (0); 
    438433        } 
     434 
    439435#endif /* SCORE_BORGS */ 
    440436 
    441         /* Cheaters are not scored */ 
    442         for (j = OPT_SCORE; j < OPT_MAX; ++j) 
    443         { 
    444                 if (!op_ptr->opt[j]) continue; 
    445  
    446                 msg_print("Score not registered for cheaters."); 
    447                 message_flush(); 
    448                 score_idx = -1; 
    449                 return (0); 
    450         } 
    451  
    452437        /* Hack -- Interupted */ 
    453         if (!p_ptr->total_winner && streq(p_ptr->died_from, "Interrupting")) 
     438        else if (!p_ptr->total_winner && streq(p_ptr->died_from, "Interrupting")) 
    454439        { 
    455440                msg_print("Score not registered due to interruption."); 
    456441                message_flush(); 
    457                 score_idx = -1; 
    458                 return (0); 
    459442        } 
    460443 
    461444        /* Hack -- Quitter */ 
    462         if (!p_ptr->total_winner && streq(p_ptr->died_from, "Quitting")) 
     445        else if (!p_ptr->total_winner && streq(p_ptr->died_from, "Quitting")) 
    463446        { 
    464447                msg_print("Score not registered due to quitting."); 
    465448                message_flush(); 
    466                 score_idx = -1; 
    467                 return (0); 
    468449        } 
    469450 
     451        /* Add a new entry to the score list, see where it went */ 
     452        else 
     453        { 
     454                high_score entry; 
     455                high_score scores[MAX_HISCORES]; 
    470456 
    471         /* Clear the record */ 
    472         (void)WIPE(&the_score, high_score); 
     457                build_score(&entry, p_ptr->died_from, death_time); 
    473458 
    474         /* Save the version */ 
    475         strnfmt(the_score.what, sizeof(the_score.what), "%s", VERSION_STRING); 
     459                highscore_read(scores, N_ELEMENTS(scores)); 
     460                highscore_add(&entry, scores, N_ELEMENTS(scores)); 
     461                highscore_write(scores, N_ELEMENTS(scores)); 
     462        } 
    476463 
    477         /* Calculate and save the points */ 
    478         strnfmt(the_score.pts, sizeof(the_score.pts), "%9lu", (long)total_points()); 
    479         the_score.pts[9] = '\0'; 
    480  
    481         /* Save the current gold */ 
    482         strnfmt(the_score.gold, sizeof(the_score.gold), "%9lu", (long)p_ptr->au); 
    483         the_score.gold[9] = '\0'; 
    484  
    485         /* Save the current turn */ 
    486         strnfmt(the_score.turns, sizeof(the_score.turns), "%9lu", (long)turn); 
    487         the_score.turns[9] = '\0'; 
    488  
    489         /* Save the date in standard encoded form (9 chars) */ 
    490         strftime(the_score.day, sizeof(the_score.day), "@%Y%m%d", localtime(death_time)); 
    491  
    492         /* Save the player name (15 chars) */ 
    493         strnfmt(the_score.who, sizeof(the_score.who), "%-.15s", op_ptr->full_name); 
    494  
    495         /* Save the player info XXX XXX XXX */ 
    496         strnfmt(the_score.uid, sizeof(the_score.uid), "%7u", player_uid); 
    497         strnfmt(the_score.sex, sizeof(the_score.sex), "%c", (p_ptr->psex ? 'm' : 'f')); 
    498         strnfmt(the_score.p_r, sizeof(the_score.p_r), "%2d", p_ptr->prace); 
    499         strnfmt(the_score.p_c, sizeof(the_score.p_c), "%2d", p_ptr->pclass); 
    500  
    501         /* Save the level and such */ 
    502         strnfmt(the_score.cur_lev, sizeof(the_score.cur_lev), "%3d", p_ptr->lev); 
    503         strnfmt(the_score.cur_dun, sizeof(the_score.cur_dun), "%3d", p_ptr->depth); 
    504         strnfmt(the_score.max_lev, sizeof(the_score.max_lev), "%3d", p_ptr->max_lev); 
    505         strnfmt(the_score.max_dun, sizeof(the_score.max_dun), "%3d", p_ptr->max_depth); 
    506  
    507         /* Save the cause of death (31 chars) */ 
    508         strnfmt(the_score.how, sizeof(the_score.how), "%-.31s", p_ptr->died_from); 
    509  
    510         /* Add a new entry to the score list, see where it went */ 
    511         score_idx = highscore_add(&the_score); 
    512  
    513464        /* Success */ 
    514         return (0); 
     465        return; 
    515466} 
    516467 
    517468 
    518  
    519469/* 
    520  * Enters a players name on a hi-score table, if "legal", and in any 
    521  * case, displays some relevant portion of the high score list. 
    522  * 
    523  * Assumes "signals_ignore_tstp()" has been called. 
    524  */ 
    525 void top_twenty(void) 
    526 { 
    527         /* Clear screen */ 
    528         Term_clear(); 
    529  
    530         /* Player's score unavailable */ 
    531         if (score_idx == -1) 
    532                 display_scores_aux(0, 10, -1, NULL); 
    533  
    534         /* Hack -- Display the top fifteen scores */ 
    535         else if (score_idx < 10) 
    536                 display_scores_aux(0, 15, score_idx, NULL); 
    537  
    538         /* Display the scores surrounding the player */ 
    539         else 
    540         { 
    541                 display_scores_aux(0, 5, score_idx, NULL); 
    542                 display_scores_aux(score_idx - 2, score_idx + 7, score_idx, NULL); 
    543         } 
    544 } 
    545  
    546  
    547 /* 
    548470 * Predict the players location, and display it. 
    549471 */ 
    550472void predict_score(void) 
    551473{ 
    552         ang_file *f; 
    553         char buf[1024]; 
    554  
    555474        int j; 
    556475        high_score the_score; 
    557476 
    558         /* Save the version */ 
    559         strnfmt(the_score.what, sizeof(the_score.what), "%s", VERSION_STRING); 
     477        high_score scores[MAX_HISCORES]; 
    560478 
    561         /* Calculate and save the points */ 
    562         strnfmt(the_score.pts, sizeof(the_score.pts), "%9lu", (long)total_points()); 
    563479 
    564         /* Save the current gold */ 
    565         strnfmt(the_score.gold, sizeof(the_score.gold), "%9lu", (long)p_ptr->au); 
     480        /* Read scores, place current score */ 
     481        highscore_read(scores, N_ELEMENTS(scores)); 
     482        build_score(&the_score, "nobody (yet!)", NULL); 
     483        j = highscore_add(&the_score, scores, N_ELEMENTS(scores)); 
    566484 
    567         /* Save the current turn */ 
    568         strnfmt(the_score.turns, sizeof(the_score.turns), "%9lu", (long)turn); 
    569  
    570         /* Hack -- no time needed */ 
    571         my_strcpy(the_score.day, "TODAY", sizeof(the_score.day)); 
    572  
    573         /* Save the player name (15 chars) */ 
    574         strnfmt(the_score.who, sizeof(the_score.who), "%-.15s", op_ptr->full_name); 
    575  
    576         /* Save the player info XXX XXX XXX */ 
    577         strnfmt(the_score.uid, sizeof(the_score.uid), "%7u", player_uid); 
    578         strnfmt(the_score.sex, sizeof(the_score.sex), "%c", (p_ptr->psex ? 'm' : 'f')); 
    579         strnfmt(the_score.p_r, sizeof(the_score.p_r), "%2d", p_ptr->prace); 
    580         strnfmt(the_score.p_c, sizeof(the_score.p_c), "%2d", p_ptr->pclass); 
    581  
    582         /* Save the level and such */ 
    583         strnfmt(the_score.cur_lev, sizeof(the_score.cur_lev), "%3d", p_ptr->lev); 
    584         strnfmt(the_score.cur_dun, sizeof(the_score.cur_dun), "%3d", p_ptr->depth); 
    585         strnfmt(the_score.max_lev, sizeof(the_score.max_lev), "%3d", p_ptr->max_lev); 
    586         strnfmt(the_score.max_dun, sizeof(the_score.max_dun), "%3d", p_ptr->max_depth); 
    587  
    588         /* No cause of death */ 
    589         my_strcpy(the_score.how, "nobody (yet!)", sizeof(the_score.how)); 
    590  
    591  
    592  
    593         /* Open the highscore file */ 
    594         path_build(buf, sizeof(buf), ANGBAND_DIR_APEX, "scores.raw"); 
    595         f = file_open(buf, MODE_READ, -1); 
    596         if (!f) return; 
    597  
    598         /* See where the entry would be placed */ 
    599         j = highscore_where(f, &the_score); 
    600  
    601         file_close(f); 
    602  
    603  
    604485        /* Hack -- Display the top fifteen scores */ 
    605486        if (j < 10) 
    606487        { 
    607                 display_scores_aux(0, 15, j, &the_score); 
     488                display_scores_aux(scores, 0, 15, j); 
    608489        } 
    609490 
    610491        /* Display some "useful" scores */ 
    611492        else 
    612493        { 
    613                 display_scores_aux(0, 5, -1, NULL); 
    614                 display_scores_aux(j - 2, j + 7, j, &the_score); 
     494                display_scores_aux(scores, 0, 5, -1); 
     495                display_scores_aux(scores, j - 2, j + 7, j); 
    615496        } 
    616497} 
    617498 
    618499 
     500/* 
     501 * Show scores. 
     502 */ 
    619503void show_scores(void) 
    620504{ 
     505        high_score scores[MAX_HISCORES]; 
     506 
     507        highscore_read(scores, N_ELEMENTS(scores)); 
     508 
    621509        screen_save(); 
    622510 
    623511        /* Display the scores */ 
    624512        if (character_generated) 
    625513                predict_score(); 
    626514        else 
    627                 display_scores_aux(0, MAX_HISCORES, -1, NULL); 
     515                display_scores_aux(scores, 0, MAX_HISCORES, -1); 
    628516 
    629517        screen_load(); 
    630518 
    631519        /* Hack - Flush it */ 
    632520        Term_fresh(); 
    633521} 
    634  
  • death.c

     
    324324        (void)title; 
    325325 
    326326        screen_save(); 
    327         top_twenty(); 
     327        show_scores(); 
    328328        screen_load(); 
    329329} 
    330330 
  • externs.h

     
    3333extern char pf_result[]; 
    3434extern int pf_result_index; 
    3535 
    36 /* score.c */ 
    37 extern int score_idx; 
    38  
    3936/* tables.c */ 
    4037extern const s16b ddd[9]; 
    4138extern const s16b ddx[10]; 
     
    430427extern errr do_randart(u32b randart_seed, bool full); 
    431428 
    432429/* score.c */ 
    433 extern errr enter_score(time_t *death_time); 
     430extern void enter_score(time_t *death_time); 
    434431extern void show_scores(void); 
    435 extern void display_scores(int from, int to); 
    436 extern void top_twenty(void); 
    437432extern void predict_score(void); 
    438433 
    439434 
  • signals.c

     
    121121                /* Mark the savefile */ 
    122122                my_strcpy(p_ptr->died_from, "Abortion", sizeof(p_ptr->died_from)); 
    123123 
    124                 /* HACK - Skip the tombscreen if it is already displayed */ 
    125                 if (score_idx == -1) 
    126                 { 
    127                         /* Close stuff */ 
    128                         close_game(); 
    129                 } 
     124                close_game(); 
    130125 
    131126                /* Quit */ 
    132127                quit("interrupt");