]> icculus.org git repositories - taylor/freespace2.git/blob - src/stats/medals.cpp
added copyright header
[taylor/freespace2.git] / src / stats / medals.cpp
1 /*
2  * Copyright (C) Volition, Inc. 1999.  All rights reserved.
3  *
4  * All source code herein is the property of Volition, Inc. You may not sell 
5  * or otherwise commercially exploit the source or things you created based on
6  * the source.
7  */
8
9 /*
10  * $Logfile: /Freespace2/code/Stats/Medals.cpp $
11  * $Revision$
12  * $Date$
13  * $Author$
14  * 
15  * $Log$
16  * Revision 1.7  2002/06/09 04:41:27  relnev
17  * added copyright header
18  *
19  * Revision 1.6  2002/06/09 03:16:05  relnev
20  * added _splitpath.
21  *
22  * removed unneeded asm, old sdl 2d setup.
23  *
24  * fixed crash caused by opengl_get_region.
25  *
26  * Revision 1.5  2002/05/28 08:52:03  relnev
27  * implemented two assembly stubs.
28  *
29  * cleaned up a few warnings.
30  *
31  * added a little demo hackery to make it progress a little farther.
32  *
33  * Revision 1.4  2002/05/28 04:56:51  theoddone33
34  * runs a little bit now
35  *
36  * Revision 1.3  2002/05/26 20:22:48  theoddone33
37  * Most of network/ works
38  *
39  * Revision 1.2  2002/05/04 04:36:56  theoddone33
40  * More changes, took out a lot of the sound stuff which will bite later but
41  * I don't care.
42  *
43  * Revision 1.1.1.1  2002/05/03 03:28:11  root
44  * Initial import.
45  *
46  * 
47  * 12    10/29/99 10:40p Jefff
48  * hack to make german medal names display without actually changing them
49  * 
50  * 11    9/02/99 3:41p Jefff
51  * changed badge voice handling to be similar to promotion voice handling
52  * 
53  * 10    8/26/99 8:49p Jefff
54  * Updated medals screen and about everything that ever touches medals in
55  * one way or another.  Sheesh.
56  * 
57  * 9     7/16/99 1:50p Dave
58  * 8 bit aabitmaps. yay.
59  * 
60  * 8     3/19/99 9:51a Dave
61  * Checkin to repair massive source safe crash. Also added support for
62  * pof-style nebulae, and some new weapons code.
63  * 
64  * 8     3/15/99 10:29a Neilk
65  * 
66  * 7     1/30/99 5:08p Dave
67  * More new hi-res stuff.Support for nice D3D textures.
68  * 
69  * 6     12/18/98 1:13a Dave
70  * Rough 1024x768 support for Direct3D. Proper detection and usage through
71  * the launcher.
72  * 
73  * 5     11/30/98 1:07p Dave
74  * 16 bit conversion, first run.
75  * 
76  * 4     10/23/98 3:51p Dave
77  * Full support for tstrings.tbl and foreign languages. All that remains
78  * is to make it active in Fred.
79  * 
80  * 3     10/13/98 9:29a Dave
81  * Started neatening up freespace.h. Many variables renamed and
82  * reorganized. Added AlphaColors.[h,cpp]
83  * 
84  * 2     10/07/98 10:54a Dave
85  * Initial checkin.
86  * 
87  * 1     10/07/98 10:51a Dave
88  * 
89  * 26    6/13/98 3:18p Hoffoss
90  * NOX()ed out a bunch of strings that shouldn't be translated.
91  * 
92  * 25    6/01/98 11:43a John
93  * JAS & MK:  Classified all strings for localization.
94  * 
95  * 24    5/01/98 12:34p John
96  * Added code to force FreeSpace to run in the same dir as exe and made
97  * all the parse error messages a little nicer.
98  * 
99  * 23    4/27/98 3:13p Allender
100  * make ctrl-enter work on medals screen
101  * 
102  * 22    4/23/98 8:27p Allender
103  * basic support for cutscene playback.  Into movie code in place.  Tech
104  * room can view cutscenes stored in CDROM_dir variable
105  * 
106  * 21    4/12/98 8:30p Allender
107  * minor medal changes to show number of medals if > 1
108  * 
109  * 20    4/10/98 4:51p Hoffoss
110  * Made several changes related to tooltips.
111  * 
112  * 19    3/18/98 12:03p John
113  * Marked all the new strings as externalized or not.
114  * 
115  * 18    3/11/98 5:02p Dave
116  * Put in code to support new medals artwork. Assorted multiplayer bug
117  * fixes.
118  * 
119  * 17    3/07/98 5:44p Dave
120  * Finished player info popup. Ironed out a few todo bugs.
121  * 
122  * 16    3/05/98 5:11p Allender
123  * fix up medals screen (again).  Don't do state transition when viewing
124  * medals from debriefing screen.
125  * 
126  * 15    3/05/98 2:32p Hoffoss
127  * Renamed Rank_bitmap to Rank_bm so it isn't named the same as the
128  * variable in the debrief screen which confuses the debugger.
129  * 
130  * 14    2/22/98 2:48p John
131  * More String Externalization Classification
132  * 
133  * 13    2/09/98 5:21p Hoffoss
134  * Made exit from medals screen to previous screen (instead of assuming
135  * it's the barracks) work.
136  * 
137  * 12    1/27/98 4:23p Allender
138  * enhanced internal scoring mechanisms.
139  * 
140  * 11    11/12/97 4:40p Dave
141  * Put in multiplayer campaign support parsing, loading and saving. Made
142  * command-line variables better named. Changed some things on the initial
143  * pilot select screen.
144  * 
145  * 10    11/12/97 9:30a Dave
146  * Fixed rank insignia tooltip not showing up.
147  * 
148  * 9     11/06/97 4:39p Allender
149  * a ton of medal work.  Removed an uneeded elemen in the scoring
150  * structure.  Fix up medals screen to apprioriate display medals (after
151  * mask was changed).  Fix Fred to only display medals which may actually
152  * be granted.  Added image_filename to player struct for Jason Hoffoss
153  * 
154  * 8     11/05/97 4:43p Allender
155  * reworked medal/rank system to read all data from tables.  Made Fred
156  * read medals.tbl.  Changed ai-warp to ai-warp-out which doesn't require
157  * waypoint for activation
158  *
159  * $NoKeywords: $
160  */
161
162
163 #include "medals.h"
164 #include "2d.h"
165 #include "snazzyui.h"
166 #include "bmpman.h"
167 #include "gamesequence.h"
168 #include "animplay.h"
169 #include "mouse.h"
170 #include "freespace.h"
171 #include "scoring.h"
172 #include "player.h"
173 #include "palman.h"
174 #include "ui.h"
175 #include "key.h"
176 #include "cmdline.h"
177 #include "gamesnd.h"
178 #include "alphacolors.h"
179 #include "localize.h"
180
181 //#define MAX_MEDAL_TYPES 63 // the # of medals which exist so far
182
183 /*
184 #define CALLSIGN_X 198
185 #define CALLSIGN_Y 80
186 #define CALLSIGN_W (439-CALLSIGN_X)
187 #define CALLSIGN_H (116-CALLSIGN_Y)
188 */
189
190 // define for the medal information
191 medal_stuff Medals[NUM_MEDALS];
192 badge_stuff Badge_info[MAX_BADGES];
193
194 // holds indices into Medals array of the badges for # kills
195 int Badge_index[MAX_BADGES];
196
197 // the rank section of the screen
198 #define RANK_MEDAL_REGION               12                      // region number of the rank medal
199
200 #warning Find real FS2_DEMO spot for medals
201 // coords for indiv medal bitmaps
202 int Medal_coords[GR_NUM_RESOLUTIONS][NUM_MEDALS][2] = {
203         {                               // GR_640
204                 { 89, 47 },                                     // eps. peg. lib
205                 { 486, 47 },                            // imp. order o' vasuda
206                 { 129, 130 },                           // dist flying cross
207                 { 208, 132 },                           // soc service
208                 { 361, 131 },                           // dist intel cross
209                 { 439, 130 },                           // order of galatea
210                 { 64, 234 },                            // meritorious unit comm.
211                 { 153, 234 },                           // medal of valor
212                 { 239, 241 },                           // gtva leg of honor
213                 { 326, 240 },                           // allied defense citation
214                 { 411, 234 },                           // neb campaign victory
215                 { 494, 234 },                           // ntf campaign victory
216                 { 189, 80 },                            // rank
217                 { 283, 91 },                            // wings
218                 { 372, 76 },                            // bronze kills badge
219                 { 403, 76 },                            // silver kills badge
220 #ifndef FS2_DEMO
221                 { 435, 76 },                            // gold kills badge
222                 { 300, 152 },                           // SOC unit crest
223 #endif
224         },
225         {                               // GR_1024
226                 { 143, 75 },                            // eps. peg. lib
227                 { 777, 75 },                            // imp. order o' vasuda
228                 { 206, 208 },                           // dist flying cross
229                 { 333, 212 },                           // soc service
230                 { 578, 210 },                           // dist intel cross
231                 { 703, 208 },                           // order of galatea
232                 { 103, 374 },                           // meritorious unit comm.
233                 { 245, 374 },                           // medal of valor
234                 { 383, 386 },                           // gtva leg of honor
235                 { 522, 384 },                           // allied defense citation
236                 { 658, 374 },                           // neb campaign victory
237                 { 790, 374 },                           // ntf campaign victory
238                 { 302, 128 },                           // rank
239                 { 453, 146 },                           // wings
240                 { 595, 121 },                           // bronze kills badge
241                 { 646, 121 },                           // silver kills badge
242 #ifndef FS2_DEMO
243                 { 696, 121 },                           // gold kills badge
244                 { 480, 244 },                           // SOC unit crest
245 #endif
246         }
247 };
248
249 // coords for the medal title
250 static int Medals_label_coords[GR_NUM_RESOLUTIONS][3] = {
251         { 241, 458, 300 },                      // GR_640 x, y, w
252         { 386, 734, 480 }                               // GR_1024 x, y, w
253 };
254
255 #define MEDALS_NUM_BUTTONS                      1
256 #define MEDALS_EXIT                                     0       
257 ui_button_info Medals_buttons[GR_NUM_RESOLUTIONS][MEDALS_NUM_BUTTONS] = {
258         { // GR_640
259                 ui_button_info("MEB_18",        574,    432,    -1,     -1,     18),
260         },
261         { // GR_1024
262                 ui_button_info("2_MEB_18",      919,    691,    -1,     -1,     18),
263         }
264 };
265
266 #define MEDALS_NUM_TEXT                         1
267 UI_XSTR Medals_text[GR_NUM_RESOLUTIONS][MEDALS_NUM_TEXT] = {
268         {       // GR_640
269                 {"Exit",                1466,           587,    416,    UI_XSTR_COLOR_PINK, -1, &Medals_buttons[GR_640][MEDALS_EXIT].button },
270         },
271         {       // GR_1024
272                 {"Exit",                1466,           943,    673,    UI_XSTR_COLOR_PINK, -1, &Medals_buttons[GR_1024][MEDALS_EXIT].button },
273         },
274 };
275
276 static char* Medals_background_filename[GR_NUM_RESOLUTIONS] = {
277         "MedalsDisplayEmpty",
278         "2_MedalsDisplayEmpty"
279 };
280
281 static char* Medals_mask_filename[GR_NUM_RESOLUTIONS] = {
282         "Medals-m",
283         "2_Medals-m"
284 };
285
286 static int Medals_callsign_y[GR_NUM_RESOLUTIONS] = {
287         54, 89
288 };
289
290 scoring_struct *Player_score=NULL;
291
292 int Medals_mode;
293 player *Medals_player;
294
295 // -----------------------------------------------------------------------------
296 // Main medals screen state
297 //
298 #define NUM_MEDAL_REGIONS                       NUM_MEDALS + 1                          // the extra one is for the rank medal
299
300 static bitmap *Medals_mask;
301 int Medals_mask_w, Medals_mask_h;
302 static int Medal_palette;              // Medal palette bitmap
303 static int Medals_bitmap_mask;         // the mask for the medal case
304 static int Medals_bitmap;              // the medal case itself
305 static int Medal_bitmaps[NUM_MEDALS];  // bitmaps for the individual medals
306 static int Rank_bm;                                                     // bitmap for the rank medal
307
308 static MENU_REGION Medal_regions[NUM_MEDAL_REGIONS]; // a semi-hack for now because we only have 4 medals, but we also include the close button
309
310 static UI_WINDOW Medals_window;
311
312 //#define MAX_MEDALS_BUTTONS                                            1
313 //#define MEDAL_BUTTON_EXIT                                             0
314 //static UI_BUTTON Medal_buttons[MAX_MEDALS_BUTTONS];
315
316 /*static char *Medal_button_names[MAX_MEDALS_BUTTONS] = {
317 //XSTR:OFF
318         "MX_17"
319 //XSTR:ON
320 };
321 */
322 /*
323 static int Medal_button_coords[MAX_MEDALS_BUTTONS][2] = {
324         {561,411}
325 };
326 static int Medal_button_masks[MAX_MEDALS_BUTTONS] = {
327         17
328 };
329 */
330
331
332 #define MEDAL_BITMAP_INIT (1<<0)
333 #define MASK_BITMAP_INIT  (1<<1)
334 int Init_flags;
335
336 void parse_medal_tbl()
337 {
338         int rval, num_medals, i, bi;
339
340         if ((rval = setjmp(parse_abort)) != 0) {
341                 Error(LOCATION, "Error parsing 'medals.tbl'\r\nError code = %i.\r\n", rval);
342         } 
343
344         // open localization
345         lcl_ext_open();
346
347         read_file_text("medals.tbl");
348
349         reset_parse();
350
351         // parse in all the rank names
352         num_medals = 0;
353         bi = 0;
354         required_string("#Medals");
355         while ( required_string_either("#End", "$Name:") ) {
356                 Assert ( num_medals < NUM_MEDALS);
357                 required_string("$Name:");
358                 stuff_string( Medals[num_medals].name, F_NAME, NULL );
359                 required_string("$Bitmap:");
360                 stuff_string( Medals[num_medals].bitmap, F_NAME, NULL );
361                 required_string("$Num mods:");
362                 stuff_int( &Medals[num_medals].num_versions);
363
364                 // some medals are based on kill counts.  When string +Num Kills: is present, we know that
365                 // this medal is a badge and should be treated specially
366                 Medals[num_medals].kills_needed = 0;
367                 if ( optional_string("+Num Kills:") ) {
368                         char buf[MULTITEXT_LENGTH + 1];
369
370                         Assert( bi < MAX_BADGES );
371                         stuff_int( &Medals[num_medals].kills_needed );
372                         Badge_index[bi] = num_medals;
373 #ifdef FS2_DEMO
374 #warning FS2_DEMO HACK: Wavefile 1/2: wave1? wave2?
375                         required_string("$Wavefile 1:");
376                         stuff_string(Badge_info[bi].voice_base, F_NAME, NULL, MAX_FILENAME_LEN);
377                         required_string("$Wavefile 2:");
378                         stuff_string(Badge_info[bi].voice_base, F_NAME, NULL, MAX_FILENAME_LEN);
379                         //stuff_string(Badge_info[bi].wave2, F_NAME, NULL, MAX_FILENAME_LEN);
380 #else
381                         required_string("$Wavefile Base:");
382                         stuff_string(Badge_info[bi].voice_base, F_NAME, NULL, MAX_FILENAME_LEN);
383 #endif                  
384
385                         required_string("$Promotion Text:");
386                         stuff_string(buf, F_MULTITEXT, NULL);
387                         Badge_info[bi].promotion_text = strdup(buf);
388
389                         bi++;
390                 }
391
392                 num_medals++;
393         }
394
395         required_string("#End");
396         Assert( num_medals == NUM_MEDALS );
397
398         // be sure that the badges kill numbers show up in order
399         for (i = 0; i < MAX_BADGES-1; i++ ) {
400                 if ( Medals[Badge_index[i]].kills_needed >= Medals[Badge_index[i+1]].kills_needed ){
401                         Error(LOCATION, "Badges must appear sorted by lowest kill # first in medals.tbl\nFind Allender for most information.");
402                 }
403         }
404
405         // close localization
406         lcl_ext_close();
407 }
408
409 void medal_main_init(player *pl, int mode)
410 {
411         int idx;
412
413         Assert(pl != NULL);
414         Medals_player = pl;
415
416    Player_score = &Medals_player->stats;
417
418         #ifndef NDEBUG
419         if(Cmdline_gimme_all_medals){
420                 //int idx;
421                 for(idx=0; idx < NUM_MEDALS; idx++){
422                         Medals_player->stats.medals[idx] = 1;           
423                 }
424         }
425         #endif
426
427         Medals_mode = mode;
428
429         snazzy_menu_init();
430         Medals_window.create( 0, 0, gr_screen.max_w, gr_screen.max_h, 0 );      
431
432         // create the interface buttons
433         for (idx=0; idx<MEDALS_NUM_BUTTONS; idx++) {
434                 // create the object
435                 Medals_buttons[gr_screen.res][idx].button.create(&Medals_window, "", Medals_buttons[gr_screen.res][idx].x, Medals_buttons[gr_screen.res][idx].y, 1, 1, 0, 1);
436
437                 // set the sound to play when highlighted
438                 Medals_buttons[gr_screen.res][idx].button.set_highlight_action(common_play_highlight_sound);
439
440                 // set the ani for the button
441                 Medals_buttons[gr_screen.res][idx].button.set_bmaps(Medals_buttons[gr_screen.res][idx].filename);
442
443                 // set the hotspot
444                 Medals_buttons[gr_screen.res][idx].button.link_hotspot(Medals_buttons[gr_screen.res][idx].hotspot);
445         }       
446
447         // add all xstrs
448         for (idx=0; idx<MEDALS_NUM_TEXT; idx++) {
449                 Medals_window.add_XSTR(&Medals_text[gr_screen.res][idx]);
450         }
451
452
453         Init_flags = 0; 
454
455         //init_medal_palette();
456         
457         Medals_bitmap = bm_load(Medals_background_filename[gr_screen.res]);
458         if (Medals_bitmap < 0) {
459            Error(LOCATION, "Error loading medal background bitmap %s", Medals_background_filename[gr_screen.res]);
460         } else {
461                 Init_flags |= MEDAL_BITMAP_INIT;
462         }
463
464         Medals_mask_w = -1;
465         Medals_mask_h = -1;
466       
467         Medals_bitmap_mask = bm_load(Medals_mask_filename[gr_screen.res]);
468         if(Medals_bitmap_mask < 0){
469                 Error(LOCATION, "Error loading medal mask file %s", Medals_mask_filename[gr_screen.res]);
470         } else {
471                 Init_flags |= MASK_BITMAP_INIT;
472                 Medals_mask = bm_lock(Medals_bitmap_mask, 8, BMP_AABITMAP);
473                 bm_get_info(Medals_bitmap_mask, &Medals_mask_w, &Medals_mask_h);
474         }
475         init_medal_bitmaps();
476         init_snazzy_regions();
477
478         gr_set_color_fast(&Color_normal);
479
480         Medals_window.set_mask_bmap(Medals_mask_filename[gr_screen.res]);
481 }
482
483 // this is just a hack to display translated names without actually changing the names, 
484 // which would break stuff
485 void medals_translate_name(char *name, int max_len)
486 {
487         if (!strcmp(name, "Epsilon Pegasi Liberation")) {
488                 strncpy(name, "Epsilon Pegasi Befreiungsmedaille", max_len);
489
490         } else if (!strcmp(name, "Imperial Order of Vasuda")) {
491                 strncpy(name, "Imperialer Orden von Vasuda ", max_len);
492
493         } else if (!strcmp(name, "Distinguished Flying Cross")) {
494                 strncpy(name, "Fliegerkreuz Erster Klasse", max_len);
495
496         } else if (!strcmp(name, "SOC Service Medallion")) {
497                 strncpy(name, "SEK-Dienstmedaille ", max_len);
498
499         } else if (!strcmp(name, "Intelligence Cross")) {
500                 strncpy(name, "Geheimdienstkreuz am Bande", max_len);
501
502         } else if (!strcmp(name, "Order of Galatea")) {
503                 strncpy(name, "Orden von Galatea ", max_len);
504
505         } else if (!strcmp(name, "Meritorious Unit Commendation")) {
506                 strncpy(name, "Ehrenspange der Allianz", max_len);
507
508         } else if (!strcmp(name, "Medal of Valor")) {
509                 strncpy(name, "Tapferkeitsmedaille ", max_len);
510
511         } else if (!strcmp(name, "GTVA Legion of Honor")) {
512                 strncpy(name, "Orden der GTVA-Ehrenlegion", max_len);
513
514         } else if (!strcmp(name, "Allied Defense Citation")) {
515                 strncpy(name, "Alliierte Abwehrspange ", max_len);
516
517         } else if (!strcmp(name, "Nebula Campaign Victory Star")) {
518                 strncpy(name, "Nebel-Siegesstern", max_len);
519
520         } else if (!strcmp(name, "NTF Campaign Victory Star")) {
521                 strncpy(name, "NTF-Siegesstern ", max_len);
522
523         } else if (!strcmp(name, "Rank")) {
524                 strncpy(name, "Dienstgrad", max_len);
525
526         } else if (!strcmp(name, "Wings")) {
527                 strncpy(name, "Fliegerspange", max_len);
528
529         } else if (!strcmp(name, "Ace")) {
530                 strncpy(name, "Flieger-As", max_len);   
531
532         } else if (!strcmp(name, "Double Ace")) {
533                 strncpy(name, "Doppel-As ", max_len);
534
535         } else if (!strcmp(name, "Triple Ace")) {
536                 strncpy(name, "Dreifach-As ", max_len);
537                 
538         } else if (!strcmp(name, "SOC Unit Crest")) {
539                 strncpy(name, "SEK-Abzeichen ", max_len);       
540         }
541 }
542
543 void blit_label(char *label, int *coords, int num)
544 {
545         int x, y, sw;
546         char text[256];
547
548         gr_set_color_fast(&Color_bright);
549
550         // translate medal names before displaying
551         // cant translate in table cuz the names are used in comparisons
552         if (Lcl_gr) {
553                 char translated_label[256];
554                 strncpy(translated_label, label, 256);
555                 medals_translate_name(translated_label, 256);
556
557                 // set correct string
558                 if ( num > 1 ) {
559                         sprintf( text, NOX("%s (%d)"), translated_label, num );
560                 } else {
561                         sprintf( text, "%s", translated_label );
562                 }               
563         } else {
564                 // set correct string
565                 if ( num > 1 ) {
566                         sprintf( text, NOX("%s (%d)"), label, num );
567                 } else {
568                         sprintf( text, "%s", label );
569                 }
570         }
571
572         // find correct coords
573         gr_get_string_size(&sw, NULL, text);
574         x = Medals_label_coords[gr_screen.res][0] + (Medals_label_coords[gr_screen.res][2] - sw) / 2;
575         y = Medals_label_coords[gr_screen.res][1];
576
577         // do it
578         gr_string(x, y, text);
579 }
580
581 void blit_callsign()
582 {
583         gr_set_color_fast(&Color_normal);
584
585         // nothing special, just do it.
586         gr_string(0x8000, Medals_callsign_y[gr_screen.res], Medals_player->callsign);
587 }
588
589 int medal_main_do()
590 {
591    int region,selected, k;
592
593         k = Medals_window.process();    
594
595         // process an exit command
596         if ((k == KEY_ESC) && (Medals_mode == MM_NORMAL)) {
597                 gameseq_post_event(GS_EVENT_PREVIOUS_STATE);
598         }
599
600         // draw the background medal display case
601         gr_reset_clip();
602         GR_MAYBE_CLEAR_RES(Medals_bitmap);
603         if(Medals_bitmap != -1){
604                 gr_set_bitmap(Medals_bitmap);
605                 gr_bitmap(0,0);
606         }
607
608         // check to see if a button was pressed
609         if( (k == (KEY_CTRLED|KEY_ENTER)) || (Medals_buttons[gr_screen.res][MEDALS_EXIT].button.pressed()) ) {  
610                 gamesnd_play_iface(SND_COMMIT_PRESSED);
611                 if(Medals_mode == MM_NORMAL){
612                         gameseq_post_event(GS_EVENT_PREVIOUS_STATE);
613                 } else {
614                         // any calling popup function will know to close the screen down
615                         return 0;
616                 }               
617         }
618
619         // blit medals also takes care of blitting the rank insignia
620         blit_medals(); 
621         blit_callsign();        
622         
623         region = snazzy_menu_do((ubyte*)Medals_mask->data, Medals_mask_w, Medals_mask_h, NUM_MEDAL_REGIONS, Medal_regions, &selected);
624         switch (region) {
625                 case ESC_PRESSED:
626                         if (Medals_mode == MM_NORMAL) {
627                                 gameseq_post_event(GS_EVENT_PREVIOUS_STATE);
628                         } else {
629                                 // any calling popup function will know to close the screen down
630                                 return 0;
631                         }
632                         break;
633
634                 case RANK_MEDAL_REGION :
635                         blit_label(Ranks[Player_score->rank].name, &Medal_coords[gr_screen.res][region][0], 1);
636                         break;
637
638                 case -1:
639                         break;
640
641                 default :
642         if (Player_score->medals[region] > 0){
643                                 blit_label(Medals[region].name, &Medal_coords[gr_screen.res][region][0], Player_score->medals[region] );
644                         }
645                         break;
646         } // end switch
647
648         Medals_window.draw();
649
650         gr_flip();
651
652         return 1;
653 }
654
655 void medal_main_close()
656 {
657         int idx;
658         if (Init_flags & MEDAL_BITMAP_INIT)
659                 bm_unload(Medals_bitmap);
660
661         if (Init_flags & MASK_BITMAP_INIT) {
662                 bm_unlock(Medals_bitmap_mask);
663                 bm_unload(Medals_bitmap_mask);
664         }
665
666    for (idx=0; idx < NUM_MEDALS; idx++) {
667                 if (Medal_bitmaps[idx] > -1){
668                         bm_unload(Medal_bitmaps[idx]);
669                 }
670         }
671
672    Player_score = NULL;
673         Medals_window.destroy();
674         snazzy_menu_close();
675         palette_restore_palette();
676 }
677
678 /*
679 void init_medal_palette()
680 {
681         Medal_palette = bm_load("MedalsPalette.pcx");
682         if(Medal_palette > -1){
683 #ifndef HARDWARE_ONLY
684                 palette_use_bm_palette(Medal_palette);
685 #endif
686         }
687 }
688 */
689
690 // function to load in the medals for this player.  It loads medals that the player has (known
691 // by whether or not a non-zero number is present in the player's medal array), then loads the
692 // rank bitmap
693
694 void init_medal_bitmaps()
695 {
696         int idx;
697         Assert(Player_score);
698
699         for (idx=0; idx<NUM_MEDALS; idx++) {
700                 Medal_bitmaps[idx] = -1;
701                 if (Player_score->medals[idx] > 0) {
702                         int num_medals;
703                         char filename[NAME_LENGTH], base[NAME_LENGTH];
704                         
705                         // possibly load a different filename that is specified by the bitmap filename
706                         // for this medal.  if the player has > 1 of these types of medals, then determien
707                         // which of the possible version to use based on the player's count of this medal
708                         strcpy( filename, Medals[idx].bitmap );
709
710                         _splitpath( filename, NULL, NULL, base, NULL );
711
712                         num_medals = Player_score->medals[idx];
713
714                         // can't display more than the maximum number of version for this medal
715                         if ( num_medals > Medals[idx].num_versions )
716                                 num_medals = Medals[idx].num_versions;
717
718                         if ( num_medals > 1 ) {
719                                 // append the proper character onto the end of the medal filename.  Base version
720                                 // has no character. next version is a, then b, etc.
721                                 sprintf( base, "%s%c", base, (num_medals-2)+'a');
722                         }
723         
724                         // hi-res support
725                         if (gr_screen.res == GR_1024) {
726                                 sprintf( filename, "2_%s", base );
727                         }
728
729                         // base now contains the actual medal bitmap filename needed to load
730                         // we don't need to pass extension to bm_load anymore, so just use the basename
731                         // as is.
732          Medal_bitmaps[idx] = bm_load( filename );
733                         Assert( Medal_bitmaps[idx] != -1 );
734                 }
735         }
736
737         // load up rank insignia
738         if (gr_screen.res == GR_1024) {
739                 char filename[NAME_LENGTH];
740                 sprintf(filename, "2_%s", Ranks[Player_score->rank].bitmap);
741                 Rank_bm = bm_load(filename);
742         } else {
743                 Rank_bm = bm_load(Ranks[Player_score->rank].bitmap);
744         }
745 }
746
747 void init_snazzy_regions()
748 {
749         int idx;
750
751         // snazzy regions for the medals/ranks, etc.
752         for (idx=0; idx<NUM_MEDALS; idx++) {
753                 if (idx == RANK_MEDAL_REGION) 
754                         continue;
755
756                 snazzy_menu_add_region(&Medal_regions[idx], "", idx, 0);
757         }
758
759         // add the rank medal region
760         snazzy_menu_add_region(&Medal_regions[RANK_MEDAL_REGION], "", RANK_MEDAL_REGION,0);
761 }
762
763
764 // blit the medals -- this includes the rank insignia
765 void blit_medals()
766 {
767         int idx;
768
769         for (idx=0; idx<NUM_MEDALS; idx++) {
770                 if (Player_score->medals[idx] > 0) {
771                         gr_set_bitmap(Medal_bitmaps[idx]);
772                         gr_bitmap(Medal_coords[gr_screen.res][idx][0], Medal_coords[gr_screen.res][idx][1]);
773                 }
774         }
775
776         // now blit rank, since that "medal" doesnt get loaded (or drawn) the normal way
777         gr_set_bitmap(Rank_bm);
778         gr_bitmap(Medal_coords[gr_screen.res][RANK_MEDAL_REGION][0], Medal_coords[gr_screen.res][RANK_MEDAL_REGION][1]);
779 }
780