Each module now includes its own header first. Removed sstream.h and the definition...
[crack-attack.git] / src / Score.cxx
blob6d2e600fb03782155dd877a90d5165ff13f47777
1 /*
2 * Score.cxx
3 * Daniel Nelson - 12/3/1
5 * Copyright (C) 2000 Daniel Nelson
6 * Copyright (C) 2004 Andrew Sayman
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 * Daniel Nelson - aluminumangel.org
23 * 174 W. 18th Ave.
24 * Columbus, OH 43210
26 * Handles the score for solo games.
29 #include "Score.h"
31 #include <cstring>
32 #include <fstream>
34 #include "TextureLoader.h"
35 #include "Game.h"
36 #include "MetaState.h"
38 using namespace std;
40 int Score::score;
41 int Score::backlog;
42 int Score::top_combo_multiplier;
43 int Score::top_combo_score;
44 ComboRank Score::combo_record[GC_SCORE_MULT_LENGTH];
45 short Score::digits[GC_NUMBER_DIGITS];
46 short Score::previous_digits[GC_NUMBER_DIGITS];
47 int Score::fade_timer;
48 GLfloat Score::inverse_timer_start;
49 int Score::n_digits_displayed;
50 int Score::special_block_scores[BF_NUMBER_SPECIAL]
51 = { 30, // black
52 30, // white
53 5, // special purple
54 5, // special blue
55 8, // special green
56 15, // special yellow
57 10, }; // special orange
59 int Score::player_rank;
60 Rank Score::record[GC_SCORE_REC_LENGTH];
62 void Score::initialize ( )
64 if (!(MetaState::mode & CM_SOLO)) return;
66 score = backlog = top_combo_multiplier = top_combo_score = 0;
67 n_digits_displayed = GC_MIN_NUMBER_DIGITS_DISPLAYED;
68 for (int n = GC_NUMBER_DIGITS; n--; ) {
69 digits[n] = previous_digits[n] = 0;
70 fade_timer = 0;
71 inverse_timer_start = 1.0f;
73 player_rank = -1;
75 if (!readScoreRecord()) setupDefaultScoreRecord();
76 if (!readMultRecord()) setupDefaultMultRecord();
79 void Score::cleanUp ( )
81 if ((MetaState::mode & CM_SOLO) && player_rank != -1)
82 writeScoreRecord();
85 int Score::gameFinish ( )
87 // first do non-victory deciding scores
88 for (int n = GC_SCORE_MULT_LENGTH; n--; )
89 if (top_combo_multiplier > combo_record[n].multiplier) {
90 player_rank = n;
92 // insert player
93 for (int n = 0; n < player_rank; n++) {
94 strncpy(combo_record[n].name, combo_record[n + 1].name, GC_PLAYER_NAME_LENGTH);
95 combo_record[n].multiplier = combo_record[n + 1].multiplier;
97 strncpy(combo_record[player_rank].name, MetaState::player_name,
98 GC_PLAYER_NAME_LENGTH);
99 combo_record[player_rank].multiplier = top_combo_multiplier;
100 break;
103 // now decide the winner
104 for (int n = GC_SCORE_REC_LENGTH; n--; )
105 if (score > record[n].score) {
106 player_rank = n;
108 // insert player
109 for (int n = 0; n < player_rank; n++) {
110 strncpy(record[n].name, record[n + 1].name, GC_PLAYER_NAME_LENGTH);
111 record[n].score = record[n + 1].score;
113 strncpy(record[player_rank].name, MetaState::player_name,
114 GC_PLAYER_NAME_LENGTH);
115 record[player_rank].score = score;
117 return GS_WON;
119 return GS_LOST;
122 bool Score::readMultRecord ( )
124 char file_name[256];
125 char buffer[256];
126 TextureLoader::buildLocalDataFileName(GC_MULT_FILE_NAME, file_name);
127 ifstream new_file(file_name);
128 if (new_file.fail()) return false;
130 for (int n = GC_SCORE_MULT_LENGTH; n--; ) {
131 new_file.getline(combo_record[n].name, GC_PLAYER_NAME_LENGTH);
132 new_file.getline(buffer, 256);
133 combo_record[n].multiplier = atoi(buffer);
134 if (new_file.fail()) return false;
136 return true;
139 bool Score::readScoreRecord ( )
141 char file_name[256];
142 TextureLoader::buildLocalDataFileName((MetaState::mode & CM_X)
143 ? GC_X_REC_FILE_NAME : GC_REC_FILE_NAME, file_name);
144 ifstream file(file_name);
145 if (file.fail()) return false;
147 char buffer[256];
148 for (int n = GC_SCORE_REC_LENGTH; n--; ) {
149 file.getline(record[n].name, GC_PLAYER_NAME_LENGTH);
150 file.getline(buffer, 256);
151 record[n].score = atoi(buffer);
152 if (file.fail()) return false;
154 return true;
157 void Score::writeScoreRecord ( )
159 char file_name[256];
160 TextureLoader::buildLocalDataFileName((MetaState::mode & CM_X)
161 ? GC_X_REC_FILE_NAME : GC_REC_FILE_NAME, file_name);
162 ofstream file(file_name);
163 if (file.fail()) {
164 cerr << "Error writing to score record file '" << file_name << "'." << endl;
165 exit(1);
168 for (int n = GC_SCORE_REC_LENGTH; n--; )
169 file << record[n].name << '\n' << record[n].score << '\n';
170 file.close();
172 // mult record
173 TextureLoader::buildLocalDataFileName(GC_MULT_FILE_NAME, file_name);
174 ofstream mult(file_name);
175 if (mult.fail()) {
176 cerr << "Error writing to score record file '" << file_name << "'." << endl;
177 exit(1);
179 for (int n = GC_SCORE_MULT_LENGTH; n--; )
180 mult << combo_record[n].name << '\n' << combo_record[n].multiplier << '\n';
181 mult.close();
185 void Score::setupDefaultMultRecord ( )
187 ifstream new_file(GC_DEFAULT_MULT_FILE_NAME);
188 if (new_file.fail()) {
189 cerr << "Error opening data file '" << GC_DEFAULT_MULT_FILE_NAME << "'." << endl;
190 exit(1);
193 char buffer[256];
194 for (int n = GC_SCORE_MULT_LENGTH; n--; ) {
195 new_file.getline(combo_record[n].name, GC_PLAYER_NAME_LENGTH);
196 new_file.getline(buffer, 256);
197 combo_record[n].multiplier = atoi(buffer);
198 if (new_file.fail()) break;
200 writeScoreRecord();
203 void Score::setupDefaultScoreRecord ( )
205 ifstream file(GC_DEFAULT_REC_FILE_NAME);
206 if (file.fail()) {
207 cerr << "Error opening data file '" << GC_DEFAULT_REC_FILE_NAME << "'." << endl;
208 exit(1);
211 int n;
212 for (n = GC_SCORE_REC_LENGTH; n--; ) {
213 file.getline(record[n].name, GC_PLAYER_NAME_LENGTH);
214 if (file.fail()) break;
216 if (n != -1)
217 while (n--)
218 strncpy(record[n].name, GC_SCORE_REC_DEFAULT_NAME,
219 GC_PLAYER_NAME_LENGTH);
220 for (n = GC_SCORE_REC_LENGTH; n--; )
221 record[n].score
222 = ((n + 1) * GC_SCORE_DEFAULT_TOP_SCORE) / GC_SCORE_REC_LENGTH;
224 writeScoreRecord();