1 
2 #include "snoutlib/mfont.h"
3 #include "hiscore.h"
4 #include "resources.h"
5 
HSitem(const string & name,int score,bool builtin)6 HSitem::HSitem(const string& name, int score, bool builtin) :
7 	m_name(name),m_score(score),m_builtin(builtin)
8 {}
9 
HSitem()10 HSitem::HSitem() {}
11 
12 
HiScore(const string & fname)13 HiScore::HiScore(const string& fname) :
14   m_fname(fname)
15 {
16   for(int i=0;i<NUMSCORES;++i)
17     m_scores[i] = HSitem("",0,true);
18 
19   add_highscore("sigflup",1000,true);
20   add_highscore("texel",2000,true);
21   add_highscore("mfx",3000,true);
22   add_highscore("Farbrausch",4000,true);
23   add_highscore("BitFellas",5000,true);
24   add_highscore("Tigrou",6000,true);
25   add_highscore("Navis",7000,true);
26   add_highscore("rrrola",8000,true);
27   add_highscore("SQNY",9000,true);
28   add_highscore("iq/RGBA",10000,true);
29 
30   read_from_file();
31 }
32 
draw(void)33 void HiScore::draw(void)
34 {
35 	MFont *font = g_resources.font;
36 
37   font->setup_drawing();
38 
39   float width=0.8;
40   float start = (1.6 - width) / 2.0;
41   float end = start + width;
42   float y_start = 0.38;
43   float y_step = 0.05;
44   float font_size = 1.0;
45   float dotsize = font->size_of_text(".",font_size);
46   vec4 color;
47 
48 	font->print_text_with_shadow("High scores", vec2(0.0+0.002,0.29+0.003),1.5,true,vec4(1.0,1.0,0.0,1.0));
49 
50   for(int i=0;i<NUMSCORES;++i) {
51     char line[256];
52     char score[64];
53     strcpy(line,m_scores[i].m_name.c_str());
54     sprintf(score,"%i",m_scores[i].m_score);
55 
56     float textsize = font->size_of_text(line,font_size) + font->size_of_text(score,font_size);
57 
58 
59     int dots = (width - textsize) / dotsize;
60 
61     for (int j=0;j<dots;++j)
62       strcat(line,".");
63 
64     color = vec4(1.0-i/9.0,1.0,i/9.0,1.0);
65 
66     float y_pos = y_start + y_step*i;
67 
68 			font->print_text(line,	vec2(start,y_pos),font_size,false,color);
69 			font->print_text(score,	vec2(end-font->size_of_text(score,font_size),y_pos),font_size,false,color);
70   }
71 
72 
73   font->finish_drawing();
74 }
75 
xor_buffer(unsigned char * buf,int size,unsigned char xorvalue)76 void xor_buffer(unsigned char *buf,int size,unsigned char xorvalue)
77 {
78   for(int i=0;i<size;++i)
79     buf[i] ^= xorvalue;
80 }
81 
calc_crc(unsigned char * buf,int size)82 int calc_crc(unsigned char *buf,int size)
83 {
84   int crc=0;
85   for(int i=0;i<size;++i)
86     crc ^= buf[i];
87 
88   return crc;
89 }
90 
read_from_file(void)91 void HiScore::read_from_file(void)
92 {
93   FILE *f = fopen(m_fname.c_str(),"rb");
94 
95   if (f==NULL)
96     return;
97 
98   const int bsize = (16+4)*NUMSCORES;
99   unsigned char buffer[bsize];
100   memset(buffer,0,bsize);
101 
102   int readbytes = fread(buffer,1,bsize,f);
103   fclose(f);
104 
105   xor_buffer(buffer,readbytes,XORVALUE);
106 
107   int pos=0;
108   for(int i=0;i<NUMSCORES;++i) {
109     int score=0;
110     char name[17] = {0};
111     memcpy(name,buffer+pos,16);
112     pos+=16;
113     score += buffer[pos++];
114     score += (buffer[pos++]) <<8;
115     score += (buffer[pos++]) <<16;
116     int stored_crc = buffer[pos++];
117     int crc = calc_crc(buffer+pos-16,15);
118 
119     if (crc!=stored_crc)
120       continue;
121 
122     add_highscore(name,score,false);
123   }
124 
125 }
126 
save_to_file(void)127 void HiScore::save_to_file(void)
128 {
129   const int bsize = (16+4)*NUMSCORES;
130   unsigned char buffer[bsize];
131   memset(buffer,0,bsize);
132 
133   int pos = 0;
134   for(int i=0;i<NUMSCORES;++i) {
135     if (m_scores[i].m_builtin==true)
136       continue;
137 
138     int score = m_scores[i].m_score;
139     sprintf((char *)buffer+pos,"%s",m_scores[i].m_name.c_str()); // %16s
140     pos += 16;
141     buffer[pos++] = score & 0xFF;
142     buffer[pos++] = (score >> 8) & 0xFF;
143     buffer[pos++] = (score >> 16) & 0xFF;
144 
145     int crc=calc_crc(buffer+pos-15,15);
146     buffer[pos++] = crc;
147   }
148 
149   if (pos<1) // nothing to write
150     return;
151 
152   xor_buffer(buffer,pos,XORVALUE);
153 
154   // write
155   FILE *f = fopen(m_fname.c_str(),"wb");
156   if (f==NULL) // can't write ? silent fail
157     return;
158 
159   fwrite(buffer,pos,1,f);
160   fclose(f);
161 }
162 
is_highscore(int score)163 bool HiScore::is_highscore(int score)
164 {
165   if (m_scores[NUMSCORES-1].m_score>score)
166     return false;
167   else
168     return true;
169 }
170 
add_highscore(const string & name,int score,bool builtin)171 void HiScore::add_highscore(const string& name, int score, bool builtin)
172 {
173   HSitem myscore(name,score,builtin);
174 
175   for(int i=0;i<NUMSCORES;++i) {
176     if (score > m_scores[i].m_score) {
177       for(int j=NUMSCORES-1;j>i;j--)
178         m_scores[j] = m_scores[j-1];
179       m_scores[i] = myscore;
180       break;
181     }
182   }
183 }
184 
first_nonbuiltin_name(void)185 string HiScore::first_nonbuiltin_name(void)
186 {
187   for(int i=0;i<NUMSCORES;++i) {
188     if (m_scores[i].m_builtin==false)
189       return m_scores[i].m_name;
190   }
191 
192   return string("");
193 }
194