Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

src/score.c

Go to the documentation of this file.
00001 /* {{{
00002  * CalcRogue, a roguelike game for PCs, calculators and PDAs
00003  * Copyright (C) 2003 Jim Babcock
00004  * 
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  * 
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  * 
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00018  * }}} */
00019 // score.c
00022 
00023 #include "crogue.h"
00024 #include "export.h"
00025 
00026 static ulong checksum_scores(high_scores *scores);
00027 
00028 static const uchar scoreScreenNumTabStops = 3;
00029 #ifdef IS_CALCULATOR
00030 #   define SCORESCREEN_LEFT 2
00031 #   define SCORESCREEN_HEADER_LEFT 40
00032 #   define SCORESCREEN_ARROW_SPACE 18
00033 #   define SCORESCREEN_SCORE_SPACE 45
00034 #else
00035 #   define SCORESCREEN_LEFT 11
00036 #   define SCORESCREEN_HEADER_LEFT 30
00037 #   define SCORESCREEN_ARROW_SPACE 5
00038 #   define SCORESCREEN_SCORE_SPACE 13
00039 #endif
00040 
00041 //{{{
00042 void load_options(void)
00043 {
00044     FILE *scorefile;
00045     high_scores table;
00046     
00047 #ifdef REALCOMPUTER
00048     char full_filename[256];
00049     snprintf(full_filename, 256, "%s" SCOREFILENAME, file_prefix);
00050     scorefile = fopen(full_filename, "rb");
00051 #else
00052     scorefile = fopen(SCOREFILENAME, "rb");
00053 #endif
00054     if(scorefile)
00055     {
00056         fread(&table, sizeof(high_scores), 1, scorefile);
00057         fread(&w->options, NUM_OPTIONS, 1, scorefile);
00058         fclose(scorefile);
00059     }
00060 }
00061 //}}}
00062 //{{{
00063 void display_scores(ulong score)
00064 {
00065     FILE *scorefile;
00066     high_scores table;
00067     int i;
00068     int score_highlighted = 0;
00069     char buf[64];
00070     draw_string_info state = {0, 0};
00071     
00072 #ifdef REALCOMPUTER
00073     char full_filename[256];
00074     snprintf(full_filename, 256, "%s" SCOREFILENAME, file_prefix);
00075     scorefile = fopen(full_filename, "rb");
00076 #else
00077     scorefile = fopen(SCOREFILENAME, "rb");
00078 #endif
00079     if(!scorefile)
00080         return;
00081     if(fread(&table, sizeof(high_scores), 1, scorefile)<1)
00082         return;
00083     fclose(scorefile);
00084     
00085     Graph_ClrScr();
00086 #ifdef IS_CALCULATOR
00087     SetFont(OPTION_FONT_SMALL);
00088 #endif
00089     setTabStops(3, 0, SCORESCREEN_ARROW_SPACE, SCORESCREEN_SCORE_SPACE);
00090     draw_string(gettext("\nHIGH SCORES\n\n"), &state, SCORESCREEN_HEADER_LEFT, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 1);
00091     for(i=0; i < min(table.num_games, NUM_SCORES); i++)
00092     {
00093         if(table.scores[i].points==score && !score_highlighted)
00094         {
00095             score_highlighted=1;
00096             strcpy(buf, "--->");
00097         } else {
00098             strcpy(buf, "");
00099         }
00100         catprintf(buf, "\t%li\t%s\n", table.scores[i].points, table.scores[i].cause_of_death);
00101 
00102         draw_string(buf, &state, SCORESCREEN_LEFT, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 1);
00103     }
00104     for(; i < NUM_SCORES; i++)
00105         draw_string("\n", &state, SCORESCREEN_LEFT, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 1);
00106     
00107     sprintf(buf, gettext("\n%li games played"), table.num_games);
00108     if(score != -1)
00109         catprintf(buf, gettext("\nYour score was %li"), score);
00110     draw_string(buf, &state, SCORESCREEN_LEFT+SCORESCREEN_ARROW_SPACE, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 1);
00111     
00112     read_char();
00113 }
00114 //}}}
00115 //{{{
00116 void award_high_score(ulong score, const char *cause_of_death)
00117 {
00118     FILE *scorefile;
00119     high_scores table;
00120     int pos, i;
00121 #ifdef REALCOMPUTER
00122     char full_filename[256];
00123 #endif
00124     memset(&table, 0, sizeof(table));
00125     
00126     // Read old scores
00127 #ifdef REALCOMPUTER
00128     snprintf(full_filename, 256, "%s" SCOREFILENAME, file_prefix);
00129     scorefile = fopen(full_filename, "rb");
00130 #else
00131     scorefile = fopen(SCOREFILENAME, "rb");
00132 #endif
00133     if(scorefile)
00134     {
00135         fread(&table, sizeof(high_scores), 1, scorefile);
00136         fclose(scorefile);
00137         
00138         if(table.checksum != checksum_scores(&table))
00139         {
00140             message(gettext("My scores file has been tampered with...\n"
00141                     "Did you think I wouldn't notice?"));
00142             read_char();
00143             remove(SCOREFILENAME);
00144             return;
00145         }
00146     }
00147     
00148     // Add a game
00149     table.num_games++;
00150     if(table.num_games==1)
00151     {
00152         table.scores[0].points = score;
00153 #       ifdef SHARED_SCORES
00154             sprintf(table.scores[0].cause_of_death, "%s. %s", getlogin(), cause_of_death);
00155 #       else
00156             strcpy(table.scores[0].cause_of_death, cause_of_death);
00157 #       endif
00158     } else {
00159         for(pos=0; pos<NUM_SCORES; pos++)
00160         {
00161             if(table.scores[pos].points <= score)
00162             {
00163                 for(i=NUM_SCORES-1; i>pos; i--)
00164                     table.scores[i] = table.scores[i-1];
00165                 table.scores[pos].points = score;
00166 #               ifdef SHARED_SCORES
00167                     sprintf(table.scores[pos].cause_of_death, "%s. %s", getlogin(), cause_of_death);
00168 #               else
00169                     strcpy(table.scores[pos].cause_of_death, cause_of_death);
00170 #               endif
00171                 break;
00172             }
00173         }
00174     }
00175     table.checksum = checksum_scores(&table);
00176     
00177 #   ifdef IS_CALCULATOR
00178     EM_moveSymFromExtMem(SYMSTR(SCOREFILENAME), HS_NULL);
00179 #   endif
00180     
00181     // Write the scores
00182 #ifdef REALCOMPUTER
00183     scorefile = fopen(full_filename, "wb");
00184 #else
00185     scorefile = fopen(SCOREFILENAME, "wb");
00186 #endif
00187     if(scorefile)
00188     {
00189         fwrite(&table, sizeof(high_scores), 1, scorefile);
00190         fwrite(w->options, NUM_OPTIONS, 1, scorefile);
00191         fclose(scorefile);
00192     } else {
00193         message(gettext("Error writing score file."));
00194     }
00195 #ifdef IS_CALCULATOR
00196     if(w->options[OPTION_ARCHIVESCORES] == OPTION_ARCHIVE_YES)
00197         archive_file(SCOREFILENAME, sizeof(scorefile));
00198 #endif
00199 }
00200 //}}}
00201 //{{{
00202 static ulong checksum_scores(high_scores *scores)
00203 {
00204     return checksum_bytes(scores, sizeof(*scores) - sizeof(scores->checksum));
00205 }
00206 //}}}
00207 

Generated on Thu May 20 13:12:11 2004 for CalcRogue by doxygen 1.3.6