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