This commit was manufactured by cvs2svn to create branch
[btb/d2x.git] / main / scores.c
1 /* $Id: scores.c,v 1.3 2003-03-15 14:17:52 btb Exp $ */
2 /*
3 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
4 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
5 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
6 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
7 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
8 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
9 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
10 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
11 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
12 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
13 */
14
15 /*
16  *
17  * Inferno High Scores and Statistics System
18  *
19  * Old Log:
20  * Revision 1.1  1995/12/05  16:06:29  allender
21  * Initial revision
22  *
23  * Revision 1.3  1995/08/14  09:25:16  allender
24  * add byteswap header
25  *
26  * Revision 1.2  1995/07/14  13:45:17  allender
27  * fixed up high score code to work and look pretty good
28  * needs some work tho'
29  *
30  * Revision 1.1  1995/05/16  15:30:42  allender
31  * Initial revision
32  *
33  * Revision 2.2  1995/06/15  12:13:54  john
34  * Made end game, win game and title sequences all go
35  * on after 5 minutes automatically.
36  *
37  * Revision 2.1  1995/03/06  15:23:57  john
38  * New screen techniques.
39  *
40  * Revision 2.0  1995/02/27  11:30:53  john
41  * New version 2.0, which has no anonymous unions, builds with
42  * Watcom 10.0, and doesn't require parsing BITMAPS.TBL.
43  *
44  * Revision 1.109  1995/02/09  12:23:19  rob
45  * Added assert for length of filename.
46  *
47  * Revision 1.108  1995/01/03  17:33:24  john
48  * Made scrolling textbox. Used it for scores cool saying.
49  *
50  * Revision 1.107  1994/12/28  10:42:51  john
51  * More VFX tweaking.
52  *
53  * Revision 1.106  1994/12/28  10:26:19  john
54  * Fixed some VFX problems.
55  *
56  * Revision 1.105  1994/12/15  16:42:12  adam
57  * some fix
58  *
59  * Revision 1.104  1994/12/14  11:59:19  john
60  * Changed the default high scores.
61  *
62  * Revision 1.103  1994/12/09  00:41:12  mike
63  * fix hang in automap print screen
64  *
65  * Revision 1.102  1994/12/07  00:36:26  mike
66  * scores sequencing stuff.
67  *
68  * Revision 1.101  1994/12/06  15:14:21  yuan
69  * Localization
70  *
71  * Revision 1.100  1994/12/03  17:07:52  yuan
72  * Localization 368
73  *
74  * Revision 1.99  1994/12/03  14:49:27  mark
75  * Fixed john's bug with previous.
76  *
77  * Revision 1.98  1994/12/03  14:43:54  john
78  * Added enter, space  to exit scores.
79  *
80  * Revision 1.97  1994/12/03  14:32:34  john
81  * Added integrated-super-deluxe-ctrl-r to reset high scores.
82  *
83  * Revision 1.96  1994/12/01  20:15:20  yuan
84  * Localization
85  *
86  * Revision 1.95  1994/11/30  19:36:36  john
87  * Made Gravis Ultrasound work again.  Made the scores blink
88  * at a constant rate.  Revamped the newmenu background storage,
89  * which hopefully fixed some bugs.  Made menus in ame not pause
90  * sound, except for the pause key.               ^== Game!
91  *
92  * Revision 1.94  1994/11/30  12:32:08  john
93  * Made secret levels print correctly.
94  *
95  * Revision 1.93  1994/11/30  12:06:47  mike
96  * fix bug: looper not initialized.
97  *
98  * Revision 1.92  1994/11/29  13:20:04  john
99  * changed the "Wow! You placed .." to something better.
100  *
101  * Revision 1.91  1994/11/29  01:35:38  john
102  * Made it so that even if you don't get a high score, you still show
103  * up on the chart..
104  *
105  * Revision 1.90  1994/11/23  17:29:29  mike
106  * fix xx-xx level bug in high scores.
107  *
108  * Revision 1.89  1994/11/22  16:55:27  mike
109  * allow high scores even in pudly trainee level.
110  *
111  * Revision 1.88  1994/11/21  17:28:33  john
112  * Changed default score values.
113  *
114  * Revision 1.87  1994/11/18  23:37:53  john
115  * Changed some shorts to ints.
116  *
117  * Revision 1.86  1994/11/13  15:39:24  john
118  * Added critical error handler to game.  Took out -editor command line
119  * option because it didn't work anymore and wasn't worth fixing.  Made scores
120  * not use MINER enviroment variable on release version, and made scores
121  * not print an error if there is no descent.hi.
122  *
123  * Revision 1.85  1994/11/06  10:15:58  john
124  * Took out kill % and hostage %
125  *
126  * Revision 1.84  1994/11/05  15:03:39  john
127  * Added non-popup menu for the main menu, so that scores and credits don't have to save
128  * the background.
129  *
130  * Revision 1.83  1994/11/05  14:05:57  john
131  * Fixed fade transitions between all screens by making gr_palette_fade_in and out keep
132  * track of whether the palette is faded in or not.  Then, wherever the code needs to fade out,
133  * it just calls gr_palette_fade_out and it will fade out if it isn't already.  The same with fade_in.
134  * This eliminates the need for all the flags like Menu_fade_out, game_fade_in palette, etc.
135  *
136  * Revision 1.82  1994/11/04  20:11:41  john
137  * Neatening up palette stuff with demos.
138  *
139  * Revision 1.81  1994/11/04  12:02:34  john
140  * Fixed fading transitions a bit more.
141  *
142  * Revision 1.80  1994/10/27  12:10:39  john
143  * Moved kill % a little to the right.
144  *
145  * Revision 1.79  1994/10/24  20:25:03  john
146  * Fixed bug with space at end of 1 line message.
147  * Made Enter go between the two input lines.
148  *
149  * Revision 1.78  1994/10/24  18:20:18  john
150  * Made the current high score flash.
151  *
152  * Revision 1.77  1994/10/24  13:37:22  mike
153  * Fix grammar error.  --anal Mike.
154  *
155  * Revision 1.76  1994/10/22  13:19:19  john
156  * Made joy/mouse buttons leave score screen.
157  *
158  * Revision 1.75  1994/10/21  15:26:57  john
159  * Used PrtScr instead of F2.
160  *
161  * Revision 1.74  1994/10/21  13:54:21  matt
162  * Replace '1' with special wide '1' to make numbers line up
163  *
164  * Revision 1.73  1994/10/19  20:48:01  john
165  * Made so that people playing on wimp level
166  * can't get high scores.
167  *
168  * Revision 1.72  1994/10/19  15:14:05  john
169  * Took % hits out of player structure, made %kills work properly.
170  *
171  * Revision 1.71  1994/10/19  14:39:27  john
172  * Finished up; added keys to prtscr, int3.
173  *
174  * Revision 1.70  1994/10/19  12:44:09  john
175  * Added hours field to player structure.
176  *
177  * Revision 1.69  1994/10/19  11:25:21  john
178  * Looking good.
179  *
180  * Revision 1.68  1994/10/19  10:54:12  john
181  * Test version.
182  *
183  * Revision 1.67  1994/10/19  10:00:27  john
184  * *** empty log message ***
185  *
186  * Revision 1.66  1994/10/19  09:59:03  john
187  * Made cool saying have the potential to be up to 50 chars
188  *
189  * Revision 1.65  1994/10/19  09:53:30  john
190  * Working version of scores.
191  *
192  * Revision 1.64  1994/10/18  21:07:46  john
193  * Fixed bug that didn't print name correctly.
194  *
195  * Revision 1.63  1994/10/18  18:21:46  john
196  * NEw score system.
197  *
198  * Revision 1.62  1994/10/17  20:31:42  john
199  * Made the text for the difficulty labels global so that
200  * the high score screen can print "rookie" or whatever.
201  *
202  * Revision 1.61  1994/10/17  17:27:44  john
203  * Added starting_level to high score system.
204  *
205  * Revision 1.60  1994/10/17  16:56:35  john
206  * Added starting level to stats menu.
207  *
208  * Revision 1.59  1994/10/17  16:55:25  john
209  * Added starting level, but didn't hook it to anything.
210  *
211  * Revision 1.58  1994/10/17  16:47:17  john
212  * Added diff. level.
213  *
214  * Revision 1.57  1994/10/17  15:49:53  john
215  * Added stats screen.
216  *
217  * Revision 1.56  1994/10/03  23:02:29  matt
218  * After player added or not to scores, scores are now displayed
219  *
220  * Revision 1.55  1994/09/01  18:09:38  john
221  * Made commas in scores work correctly .
222  *
223  *
224  * Revision 1.54  1994/09/01  18:03:57  john
225  * Neatened up scores a bit.
226  *
227  * Revision 1.53  1994/08/26  14:27:37  john
228  * Made it prompt for name
229  *
230  * Revision 1.52  1994/08/26  13:03:17  john
231  * *** empty log message ***
232  *
233  * Revision 1.51  1994/08/26  13:01:52  john
234  * Put high score system in.
235  *
236  * Revision 1.50  1994/08/10  19:57:01  john
237  * Changed font stuff; Took out old menu; messed up lots of
238  * other stuff like game sequencing messages, etc.
239  *
240  * Revision 1.49  1994/07/25  15:40:27  matt
241  * Took out debugging code accidentally left in.
242  *
243  *
244  */
245
246 #ifdef HAVE_CONFIG_H
247 #include <conf.h>
248 #endif
249
250 #include <stdio.h>
251 #include <stdlib.h>
252 #include <string.h>
253 #include <ctype.h>
254
255 #include "scores.h"
256 #include "error.h"
257 #include "pstypes.h"
258 #include "gr.h"
259 #include "mono.h"
260 #include "key.h"
261 #include "palette.h"
262 #include "game.h"
263 #include "gamefont.h"
264 #include "u_mem.h"
265 #include "songs.h"
266 #include "newmenu.h"
267 #include "menu.h"
268 #include "player.h"
269 #include "screens.h"
270 #include "gamefont.h"
271 #include "mouse.h"
272 #include "joy.h"
273 #include "timer.h"
274 #include "text.h"
275 #include "d_io.h"
276 #include "strutil.h"
277
278 #define VERSION_NUMBER          1
279 #define SCORES_FILENAME         "DESCENT.HI"
280 #define COOL_MESSAGE_LEN        50
281 #define MAX_HIGH_SCORES         10
282
283 typedef struct stats_info {
284         char    name[CALLSIGN_LEN+1];
285         int             score;
286         byte    starting_level;
287         byte    ending_level;
288         byte    diff_level;
289         short   kill_ratio;             // 0-100
290         short   hostage_ratio;  // 
291         int             seconds;                // How long it took in seconds...
292 } stats_info;
293
294 typedef struct all_scores {
295         char                    signature[3];                   // DHS
296         byte                    version;                                // version
297         char                    cool_saying[COOL_MESSAGE_LEN];
298         stats_info      stats[MAX_HIGH_SCORES];
299 } all_scores;
300
301 static all_scores Scores;
302
303 stats_info Last_game;
304
305 char scores_filename[128];
306
307 #define XX  (7)
308 #define YY  (-3)
309
310 #define LHX(x)          ((x)*(MenuHires?2:1))
311 #define LHY(y)          ((y)*(MenuHires?2.4:1))
312
313
314 char * get_scores_filename()
315 {
316 #ifndef RELEASE
317         // Only use the MINER variable for internal developement
318         char *p;
319         p=getenv( "MINER" );
320         if (p)  {
321                 sprintf( scores_filename, "%s\\game\\%s", p, SCORES_FILENAME );
322                 Assert(strlen(scores_filename) < 128);
323                 return scores_filename;
324         }
325 #endif
326         #ifdef MACINTOSH                // put the high scores into the data folder
327         sprintf( scores_filename, ":Data:%s", SCORES_FILENAME );
328         #else
329         sprintf( scores_filename, "%s", SCORES_FILENAME );
330         #endif
331         return scores_filename;
332 }
333
334 #ifndef D2_OEM
335 #define COOL_SAYING TXT_REGISTER_DESCENT
336 #else
337 #define COOL_SAYING "Get all 30 levels of D2 from 1-800-INTERPLAY"
338 #endif
339
340 void scores_read()
341 {
342         FILE * fp;
343         int fsize;
344
345         // clear score array...
346         memset( &Scores, 0, sizeof(all_scores) );
347
348         fp = fopen( get_scores_filename(), "rb" );
349         if (fp==NULL) {
350                 int i;
351
352                 // No error message needed, code will work without a scores file
353                 sprintf( Scores.cool_saying, COOL_SAYING );
354                 sprintf( Scores.stats[0].name, "Parallax" );
355                 sprintf( Scores.stats[1].name, "Matt" );
356                 sprintf( Scores.stats[2].name, "Mike" );
357                 sprintf( Scores.stats[3].name, "Adam" );
358                 sprintf( Scores.stats[4].name, "Mark" );
359                 sprintf( Scores.stats[5].name, "Jasen" );
360                 sprintf( Scores.stats[6].name, "Samir" );
361                 sprintf( Scores.stats[7].name, "Doug" );
362                 sprintf( Scores.stats[8].name, "Dan" );
363                 sprintf( Scores.stats[9].name, "Jason" );
364
365                 for (i=0; i<10; i++)
366                         Scores.stats[i].score = (10-i)*1000;
367                 return;
368         }
369                 
370         fsize = filelength( fileno( fp ));
371
372         if ( fsize != sizeof(all_scores) )      {
373                 fclose(fp);
374                 return;
375         }
376         // Read 'em in...
377         fread( &Scores, sizeof(all_scores),1, fp );
378         fclose(fp);
379
380         if ( (Scores.version!=VERSION_NUMBER)||(Scores.signature[0]!='D')||(Scores.signature[1]!='H')||(Scores.signature[2]!='S') )     {
381                 memset( &Scores, 0, sizeof(all_scores) );
382                 return;
383         }
384 }
385
386 void scores_write()
387 {
388         FILE * fp;
389
390         fp = fopen( get_scores_filename(), "wb" );
391         if (fp==NULL) {
392                 nm_messagebox( TXT_WARNING, 1, TXT_OK, "%s\n'%s'", TXT_UNABLE_TO_OPEN, get_scores_filename()  );
393                 return;
394         }
395
396         Scores.signature[0]='D';
397         Scores.signature[1]='H';
398         Scores.signature[2]='S';
399         Scores.version = VERSION_NUMBER;
400         fwrite( &Scores,sizeof(all_scores),1, fp );
401         fclose(fp);
402 }
403
404 void int_to_string( int number, char *dest )
405 {
406         int i,l,c;
407         char buffer[20],*p;
408
409         sprintf( buffer, "%d", number );
410
411         l = strlen(buffer);
412         if (l<=3) {
413                 // Don't bother with less than 3 digits
414                 sprintf( dest, "%d", number );
415                 return;
416         }
417
418         c = 0;
419         p=dest;
420         for (i=l-1; i>=0; i-- ) {
421                 if (c==3) {
422                         *p++=',';
423                         c = 0;
424                 }
425                 c++;
426                 *p++ = buffer[i];
427         }
428         *p++ = '\0';
429         strrev(dest);
430 }
431
432 void scores_fill_struct(stats_info * stats)
433 {
434                 strcpy( stats->name, Players[Player_num].callsign );
435                 stats->score = Players[Player_num].score;
436                 stats->ending_level = Players[Player_num].level;
437                 if (Players[Player_num].num_robots_total > 0 )  
438                         stats->kill_ratio = (Players[Player_num].num_kills_total*100)/Players[Player_num].num_robots_total;
439                 else
440                         stats->kill_ratio = 0;
441
442                 if (Players[Player_num].hostages_total > 0 )    
443                         stats->hostage_ratio = (Players[Player_num].hostages_rescued_total*100)/Players[Player_num].hostages_total;
444                 else
445                         stats->hostage_ratio = 0;
446
447                 stats->seconds = f2i(Players[Player_num].time_total)+(Players[Player_num].hours_total*3600);
448
449                 stats->diff_level = Difficulty_level;
450                 stats->starting_level = Players[Player_num].starting_level;
451 }
452
453 //char * score_placement[10] = { TXT_1ST, TXT_2ND, TXT_3RD, TXT_4TH, TXT_5TH, TXT_6TH, TXT_7TH, TXT_8TH, TXT_9TH, TXT_10TH };
454
455 void scores_maybe_add_player(int abort_flag)
456 {
457         char text1[COOL_MESSAGE_LEN+10];
458         newmenu_item m[10];
459         int i,position;
460
461         #ifdef APPLE_DEMO               // no high scores in apple oem version
462         return;
463         #endif
464
465         if ((Game_mode & GM_MULTI) && !(Game_mode & GM_MULTI_COOP))
466                 return;
467   
468         scores_read();
469         
470         position = MAX_HIGH_SCORES;
471         for (i=0; i<MAX_HIGH_SCORES; i++ )      {
472                 if ( Players[Player_num].score > Scores.stats[i].score )        {
473                         position = i;
474                         break;
475                 }
476         }
477         
478         if ( position == MAX_HIGH_SCORES ) {
479                 if (abort_flag)
480                         return;
481                 scores_fill_struct( &Last_game );
482         } else {
483 //--            if ( Difficulty_level < 1 )     {
484 //--                    nm_messagebox( "GRADUATION TIME!", 1, "Ok", "If you would had been\nplaying at a higher difficulty\nlevel, you would have placed\n#%d on the high score list.", position+1 );
485 //--                    return;
486 //--            }
487
488                 if ( position==0 )      {
489                         strcpy( text1,  "" );
490                         m[0].type = NM_TYPE_TEXT; m[0].text = TXT_COOL_SAYING;
491                         m[1].type = NM_TYPE_INPUT; m[1].text = text1; m[1].text_len = COOL_MESSAGE_LEN-5;
492                         newmenu_do( TXT_HIGH_SCORE, TXT_YOU_PLACED_1ST, 2, m, NULL );
493                         strncpy( Scores.cool_saying, text1, COOL_MESSAGE_LEN );
494                         if (strlen(Scores.cool_saying)<1)
495                                 sprintf( Scores.cool_saying, "No Comment" );
496                 } else {
497                         nm_messagebox( TXT_HIGH_SCORE, 1, TXT_OK, "%s %s!", TXT_YOU_PLACED, *(&TXT_1ST + position) );
498                 }
499         
500                 // move everyone down...
501                 for ( i=MAX_HIGH_SCORES-1; i>position; i-- )    {
502                         Scores.stats[i] = Scores.stats[i-1];
503                 }
504
505                 scores_fill_struct( &Scores.stats[position] );
506         
507                 scores_write();
508
509         }
510         scores_view(position);
511 }
512
513 void scores_rprintf(int x, int y, char * format, ... )
514 {
515         va_list args;
516         char buffer[128];
517         int w, h, aw;
518         char *p;
519
520         va_start(args, format );
521         vsprintf(buffer,format,args);
522         va_end(args);
523
524         //replace the digit '1' with special wider 1
525         for (p=buffer;*p;p++)
526                 if (*p=='1') *p=132;
527
528         gr_get_string_size(buffer, &w, &h, &aw );
529
530         gr_string( LHX(x)-w, LHY(y), buffer );
531 }
532
533
534 void scores_draw_item( int  i, stats_info * stats )
535 {
536         char buffer[20];
537
538                 int y;
539
540         WIN(DDGRLOCK(dd_grd_curcanv));
541                 y = 7+70+i*9;
542
543                 if (i==0) y -= 8;
544
545                 if ( i==MAX_HIGH_SCORES )       {
546                         y += 8;
547                         //scores_rprintf( 17+33+XX, y+YY, "" );
548                 } else {
549                         scores_rprintf( 17+33+XX, y+YY, "%d.", i+1 );
550                 }
551
552                 if (strlen(stats->name)==0) {
553                         gr_printf( LHX(26+33+XX), LHY(y+YY), TXT_EMPTY );
554                         WIN(DDGRUNLOCK(dd_grd_curcanv));
555                         return;
556                 }
557                 gr_printf( LHX(26+33+XX), LHY(y+YY), "%s", stats->name );
558                 int_to_string(stats->score, buffer);
559                 scores_rprintf( 109+33+XX, y+YY, "%s", buffer );
560
561                 gr_printf( LHX(125+33+XX), LHY(y+YY), "%s", MENU_DIFFICULTY_TEXT(stats->diff_level) );
562
563                 if ( (stats->starting_level > 0 ) && (stats->ending_level > 0 ))
564                         scores_rprintf( 192+33+XX, y+YY, "%d-%d", stats->starting_level, stats->ending_level );
565                 else if ( (stats->starting_level < 0 ) && (stats->ending_level > 0 ))
566                         scores_rprintf( 192+33+XX, y+YY, "S%d-%d", -stats->starting_level, stats->ending_level );
567                 else if ( (stats->starting_level < 0 ) && (stats->ending_level < 0 ))
568                         scores_rprintf( 192+33+XX, y+YY, "S%d-S%d", -stats->starting_level, -stats->ending_level );
569                 else if ( (stats->starting_level > 0 ) && (stats->ending_level < 0 ))
570                         scores_rprintf( 192+33+XX, y+YY, "%d-S%d", stats->starting_level, -stats->ending_level );
571
572                 {
573                         int h, m, s;
574                         h = stats->seconds/3600;
575                         s = stats->seconds%3600;
576                         m = s / 60;
577                         s = s % 60;
578                         scores_rprintf( 311-42+XX, y+YY, "%d:%02d:%02d", h, m, s );
579                 }
580         WIN(DDGRUNLOCK(dd_grd_curcanv));
581 }
582
583 void scores_view(int citem)
584 {
585         fix t1;
586         int i,done,looper;
587         int k;
588         byte fades[64] = { 1,1,1,2,2,3,4,4,5,6,8,9,10,12,13,15,16,17,19,20,22,23,24,26,27,28,28,29,30,30,31,31,31,31,31,30,30,29,28,28,27,26,24,23,22,20,19,17,16,15,13,12,10,9,8,6,5,4,4,3,2,2,1,1 };
589
590 ReshowScores:
591         scores_read();
592
593         set_screen_mode(SCREEN_MENU);
594  
595         WINDOS( dd_gr_set_current_canvas(NULL),
596                                 gr_set_current_canvas(NULL)
597         );
598         
599         nm_draw_background(0,0,grd_curcanv->cv_bitmap.bm_w, grd_curcanv->cv_bitmap.bm_h );
600
601         grd_curcanv->cv_font = MEDIUM3_FONT;
602
603 WIN(DDGRLOCK(dd_grd_curcanv));
604         gr_string( 0x8000, LHY(15), TXT_HIGH_SCORES );
605
606         grd_curcanv->cv_font = SMALL_FONT;
607
608         gr_set_fontcolor( BM_XRGB(31,26,5), -1 );
609         gr_string(  LHX(31+33+XX), LHY(46+7+YY), TXT_NAME );
610         gr_string(  LHX(82+33+XX), LHY(46+7+YY), TXT_SCORE );
611         gr_string( LHX(127+33+XX), LHY(46+7+YY), TXT_SKILL );
612         gr_string( LHX(170+33+XX), LHY(46+7+YY), TXT_LEVELS );
613 //      gr_string( 202, 46, "Kills" );
614 //      gr_string( 234, 46, "Rescues" );
615         gr_string( LHX(288-42+XX), LHY(46+7+YY), TXT_TIME );
616
617         if ( citem < 0 )        
618                 gr_string( 0x8000, LHY(175), TXT_PRESS_CTRL_R );
619
620         gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
621
622         gr_printf( 0x8000, LHY(31), "%c%s%c  - %s", 34, Scores.cool_saying, 34, Scores.stats[0].name );
623 WIN(DDGRUNLOCK(dd_grd_curcanv));        
624
625         for (i=0; i<MAX_HIGH_SCORES; i++ )              {
626                 //@@if (i==0)   {
627                 //@@    gr_set_fontcolor( BM_XRGB(28,28,28), -1 );
628                 //@@} else {
629                 //@@    gr_set_fontcolor( gr_fade_table[BM_XRGB(28,28,28)+((28-i*2)*256)], -1 );
630                 //@@}                                                                                                            
631
632                 gr_set_fontcolor( BM_XRGB(28-i*2,28-i*2,28-i*2), -1 );
633                 scores_draw_item( i, &Scores.stats[i] );
634         }
635
636         gr_palette_fade_in( gr_palette,32, 0);
637
638 #ifdef OGL
639         gr_update();
640 #endif
641
642         game_flush_inputs();
643
644         done = 0;
645         looper = 0;
646
647         while(!done)    {
648                 if ( citem > -1 )       {
649         
650                         t1      = timer_get_fixed_seconds();
651                         while ( timer_get_fixed_seconds() < t1+F1_0/128 );      
652
653                         //@@gr_set_fontcolor( gr_fade_table[fades[looper]*256+BM_XRGB(28,28,28)], -1 );
654                         gr_set_fontcolor( BM_XRGB(7+fades[looper],7+fades[looper],7+fades[looper]), -1 );
655                         looper++;
656                         if (looper>63) looper=0;
657                         if ( citem ==  MAX_HIGH_SCORES )
658                                 scores_draw_item( MAX_HIGH_SCORES, &Last_game );
659                         else
660                                 scores_draw_item( citem, &Scores.stats[citem] );
661                         gr_update();
662                 }
663
664                 for (i=0; i<4; i++ )    
665                         if (joy_get_button_down_cnt(i)>0) done=1;
666                 for (i=0; i<3; i++ )    
667                         if (mouse_button_down_count(i)>0) done=1;
668
669                 //see if redbook song needs to be restarted
670                 songs_check_redbook_repeat();
671
672         #ifdef WINDOWS
673                 {
674                         MSG msg;
675
676                         DoMessageStuff(&msg);
677
678                         if (_RedrawScreen) {
679                                 _RedrawScreen = FALSE;
680                                 goto ReshowScores;
681                         }
682
683                         DDGRRESTORE;
684                 }
685         #endif
686
687                 k = key_inkey();
688                 switch( k )     {
689                 case KEY_CTRLED+KEY_R:          
690                         if ( citem < 0 )                {
691                                 // Reset scores...
692                                 if ( nm_messagebox( NULL, 2,  TXT_NO, TXT_YES, TXT_RESET_HIGH_SCORES )==1 )     {
693                                         remove( get_scores_filename() );
694                                         gr_palette_fade_out( gr_palette, 32, 0 );
695                                         goto ReshowScores;
696                                 }
697                         }
698                         break;
699                 case KEY_BACKSP:                                Int3(); k = 0; break;
700                 case KEY_PRINT_SCREEN:          save_screen_shot(0); k = 0; break;
701                         
702                 case KEY_ENTER:
703                 case KEY_SPACEBAR:
704                 case KEY_ESC:
705                         done=1;
706                         break;
707                 }
708         }
709
710 // Restore background and exit
711         gr_palette_fade_out( gr_palette, 32, 0 );
712
713 #ifdef WINDOWS
714         DDGRRESTORE;
715 #endif
716
717         WINDOS( dd_gr_set_current_canvas(NULL),
718                                 gr_set_current_canvas(NULL)
719         );
720
721         game_flush_inputs();
722         
723 }