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