original 1.0.1 release
[xwelltris.git] / src / welltopnine.cxx
blob218f038e3ef0438d7a27d2c1ec0daf04c6979fc1
1 // docm_prefix(///)
2 /****************************************************************************
3 * Copyright (C) 2002 by Leo Khramov
4 * email: leo@xnc.dubna.su
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 ****************************************************************************/
16 // $Id: welltopnine.cxx,v 1.3 2003/02/23 06:33:40 leo Exp $
17 #include "welltopnine.h"
18 #include "wellengine.h"
19 #include "commonfuncs.h"
21 WellTopNine *default_top_nine;
23 //===========================================================================
24 /// global Score()
25 /// constructor, set all to zeros and current date
26 /// tags Score
27 Score::Score()
29 player[0]=date_time[0]=0;
30 level=score=lines=squares=play_time=0;
31 mixed=rotation=next_piece=false;
32 set_current_time();
35 //===========================================================================
36 /// global get_next_token(char* from, char* to)
37 /// cut buffer by tokens
38 /// tags Score
39 char* Score::get_next_token(char* from, char* to)
41 int delta=0;
42 char *orig_to=to;
43 *to=0;
44 if(*from==';')
45 from++;
46 while(*from==' ')
47 from++;
48 while(*from!=0 && *from!=';' && *from!='\n' && *from!='\r' && *from!=0)
49 *to++=*from++;
50 while(to!=orig_to && *to==' ')
52 to--;
53 delta=1;
55 to+=delta;
56 *to=0;
57 return from;
60 //===========================================================================
61 /// global save(FILE*)
62 /// save score_line to file
63 /// tags Score
64 void Score::save(FILE* fp)
66 fprintf(fp,"%d;%-12s;%s;%8d;%5d;%2d;%d;%d;%d;%d\n",
67 squares,player,date_time,score,lines,level,
68 mixed ? 1 : 0, rotation ? 1 : 0,play_time,
69 next_piece ? 1 : 0);
72 //===========================================================================
73 /// global load(FILE*)
74 /// load score_line from file
75 /// tags Score
76 bool Score::load(FILE* fp)
78 char buf[L_MAXPATH];
79 char *ptr=buf;
80 char token[L_MAXPATH];
81 while(1)
83 if(fgets(buf,L_MAXPATH-1,fp)==0)
84 return false;
85 if(buf[0]=='#') //Skipping comments
86 continue;
88 //squares
89 ptr=get_next_token(ptr,token);
90 squares=atoi(token);
91 //player
92 ptr=get_next_token(ptr,token);
93 strncpy(player,token,PLAYER_NAME_LEN-1);
94 player[PLAYER_NAME_LEN-1]=0;
95 //date_time
96 ptr=get_next_token(ptr,token);
97 strncpy(date_time,token,L_DATE-1);
98 date_time[L_DATE-1]=0;
99 //score
100 ptr=get_next_token(ptr,token);
101 score=atoi(token);
102 //lines
103 ptr=get_next_token(ptr,token);
104 lines=atoi(token);
105 //level
106 ptr=get_next_token(ptr,token);
107 level=atoi(token);
108 //mixed
109 ptr=get_next_token(ptr,token);
110 mixed= atoi(token) ? true : false;
111 //rotation
112 ptr=get_next_token(ptr,token);
113 rotation= atoi(token) ? true : false;
114 //play_time
115 ptr=get_next_token(ptr,token);
116 play_time=atoi(token);
117 //rotation
118 ptr=get_next_token(ptr,token);
119 next_piece= atoi(token) ? true : false;
120 break;
122 dbgprintf(("scores: %d;%s;%s;%8d;%5d;%2d;%d;%d\n",
123 squares,player,date_time,score,lines,level,
124 mixed ? 1 : 0, rotation ? 1 : 0));
125 return true;
128 //===========================================================================
129 /// global set_current_time()
130 /// set current date and time to date (format YYYY-MM-DD HH:MI)
131 /// tags Score
132 void Score::set_current_time()
134 struct tm *time_str;
135 time(&start_t);
136 time_str=localtime(&start_t);
137 strftime(date_time,L_DATE,"%Y-%m-%d",time_str);
140 //===========================================================================
141 /// global calc_play_time()
142 /// calculate playing time from start_t till now
143 /// tags Score
144 void Score::calc_play_time()
146 time_t now_t;
147 time(&now_t);
148 play_time=now_t - start_t;
151 //===========================================================================
152 /// global set_player(char* pl)
153 /// set player name
154 /// tags Score
155 void Score::set_player(char* name)
157 if(name)
158 strncpy(player,name,PLAYER_NAME_LEN);
159 else
160 strcpy(player,"unknown");
161 player[PLAYER_NAME_LEN-1]=0;
164 //////////////////////////ScoreTable struct methods/////////////////////////
168 //===========================================================================
169 /// global ScoreTable()
170 /// constructor of scoretable
171 /// tags ScoreTable
172 ScoreTable::ScoreTable()
174 int i;
175 for(i=0;i<TOP_NINE;i++)
177 table[i]=new Score;
178 table[i]->place=i+1;
182 //===========================================================================
183 /// global ~ScoreTable()
184 /// destructor of scoretable
185 /// tags ScoreTable
186 ScoreTable::~ScoreTable()
188 int i;
189 for(i=0;i<TOP_NINE;i++)
190 delete table[i];
193 //===========================================================================
194 /// global sort_by_score()
195 /// sort table by score
196 /// tags ScoreTable
197 void ScoreTable::sort_by_score()
199 int i,j;
200 Score *ptr;
202 for(i=0;i<TOP_NINE;i++)
203 table[i]->place=i+1;
205 for(j=0;j<TOP_NINE-1;j++)
206 for(i=j+1;i<TOP_NINE;i++)
207 if(table[j]->score<table[i]->score)
209 ptr=table[i];
210 table[i]=table[j];
211 table[j]=ptr;
213 table[j]->place=j+1;
214 table[i]->place=i+1;
218 //===========================================================================
219 /// global save(FILE* fp)
220 /// save table to give file descr
221 /// tags ScoreTable
222 void ScoreTable::save(FILE* fp)
224 int i;
225 for(i=0;i<TOP_NINE;i++)
226 table[i]->save(fp);
229 //===========================================================================
230 /// global set_squares(int isquare)
231 /// set squares to given number
232 /// tags ScoreTable
233 void ScoreTable::set_squares(int isquares)
235 int i;
236 for(i=0;i<TOP_NINE;i++)
237 table[i]->squares=isquares;
240 //===========================================================================
241 /// global set_and_get(int idx,Score*)
242 /// set new Score and get old one. If new == 0 just return old
243 /// tags ScoreTable
244 Score* ScoreTable::set_and_get(int idx, Score* new_one)
246 Score *old_one;
247 if(idx<0 || idx>=TOP_NINE)
248 return new_one;
250 old_one=table[idx];
251 if(new_one)
253 table[idx]=new_one;
254 table[idx]->place=idx+1;
256 return old_one;
262 //////////////////////////////WellTopNine class///////////////////////////////
266 //===========================================================================
267 /// global WellTopNine()
268 /// constructor - fill table
269 /// tags WellTopNine
270 WellTopNine::WellTopNine() : WellObject()
272 int i;
273 current_score=0;
274 page=3;
276 geo=get_geo_by_name("top_nine_elements");
278 for(i=0;i<MAX_SQUARES;i++)
279 tables[i].set_squares(i+1);
280 for(i=0;i<TOP_NINE;i++)
282 text_lines[i]=default_well_engine->new_well_image_font(imFont1,
283 FONT3_L,FONT3_H,
284 FONT3_DX,FONT3_DY);
285 text_lines[i]->set_screen_region(TOPNINE_TXT_X,
286 TOPNINE_TXT_Y + i*TOPNINE_TXT_STEPY,
287 TOPNINE_TXT_L,TOPNINE_TXT_H);
289 key_exit=default_well_engine->new_well_key("top_key_exit");
290 key_exit->set_object_on_press(ObjectCaller(this,&WellObject::hide_by_call));
293 //===========================================================================
294 /// global save_scores()
295 /// save score table to file
296 /// tags WellTopNine
297 bool WellTopNine::save_scores()
299 int i;
300 char fname[L_MAXPATH];
302 if(!find_full_path_for_file(SCOREFILE,fname,ReadWrite))
304 #ifndef WIN32
305 sprintf(fname, "%s/.xwelltris",getenv("HOME"));
306 mkdir(fname,0755);
307 strcat(fname,"/");
308 strcat(fname,SCOREFILE);
309 #endif
312 FILE* fp=fopen(fname,"w");
313 if(!fp)
315 fprintf(stderr,"PANIC: can't save scores file: %s - %s\n",
316 fname,strerror(errno));
317 return false;
319 for(i=0;i<MAX_SQUARES;i++)
320 tables[i].save(fp);
321 fclose(fp);
322 return true;
325 //===========================================================================
326 /// global load_scores()
327 /// load score table from file
328 /// tags WellTopNine
329 bool WellTopNine::load_scores()
331 int i;
332 int idx[MAX_SQUARES];
333 char fname[L_MAXPATH];
334 Score *pscore=new Score;
336 find_full_path_for_file(SCOREFILE,fname,ReadWrite);
338 FILE* fp=fopen(fname,"r");
340 if(!fp)
342 fprintf(stderr,"ERROR: can't load scores file: %s - %s\n",
343 fname,strerror(errno));
344 return false;
347 for(i=0;i<MAX_SQUARES;i++)
348 idx[i]=0;
350 while(pscore->load(fp))
352 i=pscore->squares-1;
353 pscore=tables[i].set_and_get(idx[i],pscore);
354 idx[i]++;
356 fclose(fp);
358 for(i=0;i<MAX_SQUARES;i++)
359 tables[i].sort_by_score();
361 delete pscore;
362 return true;
365 //===========================================================================
366 /// global try_add_to_table()
367 /// trying to add given player score to table of winners
368 /// return looser pointer (the same one if you are a looser :)
369 /// tags WellTopNine
370 Score* WellTopNine::try_add_to_table(Score* new_one)
372 Score *pscore;
373 if(new_one==0)
374 return 0;
375 page=new_one->squares-1;
376 current_score=new_one;
377 if(tables[page].table[TOP_NINE-1]->score < new_one->score)
379 pscore=tables[page].table[TOP_NINE-1];
380 tables[page].table[TOP_NINE-1]=new_one;
381 tables[page].sort_by_score();
382 return pscore;
384 return new_one;
387 //===========================================================================
388 /// global find_challenger(Score* me)
389 /// Find challenger, whose score > than mine
390 // return 0 if you are the first
391 /// tags WellTopNine
392 Score* WellTopNine::find_challenger(Score* me)
394 int i;
395 ScoreTable *pcur;
397 if(me==0)
398 return 0;
399 pcur= &tables[me->squares-1];
400 for(i=TOP_NINE-1;i>=0;i--)
401 if(pcur->table[i]->score > me->score)
402 return pcur->table[i];
403 return 0;
407 //===========================================================================
408 /// global process_event(wEvent)
409 /// stub that process events (empty here)
410 /// tags WellTopNine
411 bool WellTopNine::process_event(wEvent)
413 return true;
416 //===========================================================================
417 /// global show()
418 /// stub that show object (empty)
419 /// tags WellTopNine
420 void WellTopNine::show()
422 key_exit->show();
423 default_well_engine->set_main_background_image(imScoreBG);
424 default_well_engine->add_object(this);
425 redraw_table();
426 shown=true;
427 save_scores();
430 //===========================================================================
431 /// global hide()
432 /// stub that hide object (empty)
433 /// tags WellTopNine
434 void WellTopNine::hide()
436 shown=false;
437 default_well_engine->del_object(this);
438 key_exit->hide();
439 object_on_exit.call(wEvent(aEmpty,this));
442 //===========================================================================
443 /// global redraw_table()
444 /// redraw all data for score table according to current_score and page
445 /// tags WellTopNine
446 void WellTopNine::redraw_table()
448 int i,j;
449 char buf[L_MAXPATH];
450 Score *pscore;
452 for(i=0;i<TOP_NINE;i++)
454 pscore=tables[page].table[i];
455 sprintf(buf,"%d.%-15s %s %7d %4d %2d",
456 pscore->place,pscore->player,pscore->date_time,
457 pscore->score,pscore->lines,pscore->level);
458 if(pscore!=current_score)
460 text_lines[i]->set_font(FONT3_L,FONT3_H,
461 FONT3_DX,FONT3_DY);
462 text_lines[i]->set_screen_region(TOPNINE_TXT_X,
463 TOPNINE_TXT_Y + i*TOPNINE_TXT_STEPY,
464 TOPNINE_TXT_L,TOPNINE_TXT_H);
465 } else
467 dbgprintf(("Highlighting item %d\n",i));
468 text_lines[i]->set_font(FONT5_L,FONT5_H,
469 FONT5_DX,FONT5_DY);
470 text_lines[i]->set_screen_region(TOPNINE_TXT_X,
471 TOPNINE_TXT_Y + i*TOPNINE_TXT_STEPY,
472 TOPNINE_TXT_L,TOPNINE_TXT_H);
474 text_lines[i]->set_text(buf);
475 text_lines[i]->draw_text();
476 for(j=0;j<3;j++)
478 geo[j].toy=TOPNINE_TXT_Y + i*TOPNINE_TXT_STEPY - 2;
480 if(pscore->rotation)
481 default_well_engine->screen_copy(&geo[0]);
482 if(pscore->next_piece)
483 default_well_engine->screen_copy(&geo[1]);
484 if(pscore->mixed)
485 default_well_engine->screen_copy(&geo[2]);