]> icculus.org git repositories - taylor/freespace2.git/blob - src/menuui/barracks.cpp
Freespace 1 support
[taylor/freespace2.git] / src / menuui / barracks.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/MenuUI/Barracks.cpp $
11  * $Revision$
12  * $Date$
13  * $Author$
14  *
15  * C file for implementing barracks section
16  *
17  * $Log$
18  * Revision 1.4  2003/05/25 02:30:42  taylor
19  * Freespace 1 support
20  *
21  * Revision 1.3  2002/06/09 04:41:22  relnev
22  * added copyright header
23  *
24  * Revision 1.2  2002/05/07 03:16:46  theoddone33
25  * The Great Newline Fix
26  *
27  * Revision 1.1.1.1  2002/05/03 03:28:09  root
28  * Initial import.
29  *
30  * 
31  * 42    10/25/99 5:47p Jefff
32  * reassigned some xstr ids
33  * 
34  * 41    9/14/99 11:01p Jefff
35  * stats area coord fix
36  * 
37  * 40    9/09/99 11:24a Jefff
38  * 
39  * 39    9/02/99 11:26a Jefff
40  * fixed incorrect pilot list dimensions
41  * 
42  * 38    8/17/99 2:24p Dave
43  * Fixed wacky squad color stuff.
44  * 
45  * 37    8/16/99 4:27p Jefff
46  * fix button position on squad change error popup
47  * 
48  * 36    8/11/99 3:58p Jefff
49  * fixed player list box coord bug
50  * 
51  * 35    8/05/99 2:46p Jefff
52  * added popup to the disabled squad selection buttons in single player
53  * 
54  * 34    8/02/99 11:02p Dave
55  * Fixed up squad filename and squad name copying when converting a pilot
56  * between single and multiplayer.
57  * 
58  * 33    7/27/99 7:17p Jefff
59  * Replaced some art text with XSTR() text.
60  * 
61  * 32    7/15/99 9:20a Andsager
62  * FS2_DEMO initial checkin
63  * 
64  * 31    6/29/99 7:39p Dave
65  * Lots of small bug fixes.
66  * 
67  * 30    6/16/99 4:06p Dave
68  * New pilot info popup. Added new draw-bitmap-as-poly function.
69  * 
70  * 29    6/11/99 11:13a Dave
71  * last minute changes before press tour build.
72  * 
73  * 28    4/25/99 7:43p Dave
74  * Misc small bug fixes. Made sun draw properly.
75  * 
76  * 27    4/25/99 3:02p Dave
77  * Build defines for the E3 build.
78  * 
79  * 26    3/24/99 4:05p Dave
80  * Put in support for assigning the player to a specific squadron with a
81  * specific logo. Preliminary work for doing pos/orient checksumming in
82  * multiplayer to reduce bandwidth.
83  * 
84  * 25    2/25/99 4:19p Dave
85  * Added multiplayer_beta defines. Added cd_check define. Fixed a few
86  * release build warnings. Added more data to the squad war request and
87  * response packets.
88  * 
89  * 24    2/02/99 12:09p Neilk
90  * Fixed text coords, centered pilot and squad pics in 1024x768, added vss
91  * comment template
92  *
93  * $NoKeywords: $
94  */
95
96 #include "barracks.h"
97 #include "managepilot.h"
98 #include "ui.h"
99 #include "font.h"
100 #include "key.h"
101 #include "gamesnd.h"
102 #include "osapi.h"
103 #include "popup.h"
104 #include "playermenu.h"
105 #include "gamesequence.h"
106 #include "contexthelp.h"
107 #include "2d.h"
108 #include "ctype.h"
109 #include "freespace.h"
110 #include "systemvars.h"
111 #include "bmpman.h"
112 #include "mouse.h"
113 #include "osregistry.h"
114 #include "alphacolors.h"
115
116 void delete_pilot_file( char *pilot_name, int single );         // manage_pilot.cpp
117
118 // stats defines
119 #define NUM_STAT_LINES 85
120 #define STAT_COLUMN1_W 40
121 #define STAT_COLUMN2_W 10
122
123 static int Stat_column1_w[GR_NUM_RESOLUTIONS] =
124 {
125         40,             // GR_640
126         40                      // GR_1024
127 };
128
129 static int Stat_column2_w[GR_NUM_RESOLUTIONS] =
130 {
131         10,             // GR_640
132         10                      // GR_1024
133 };
134
135 // constants for coordinate lookup
136 #define BARRACKS_X_COORD 0
137 #define BARRACKS_Y_COORD 1
138 #define BARRACKS_W_COORD 2
139 #define BARRACKS_H_COORD 3
140
141 // area ints
142
143 // pilot selection field
144 static int Barracks_list_coords[GR_NUM_RESOLUTIONS][4] = {
145         { // GR_640
146 #ifdef MAKE_FS1
147                 58, 42, 400, 105
148 #else
149                 42, 34, 400, 90
150 #endif
151         },
152         { // GR_1024
153                 45, 51, 646, 144
154         }
155 };
156
157 // pilot stats field
158 static int Barracks_stats_coords[GR_NUM_RESOLUTIONS][4] = {
159         { // GR_640
160 #ifdef MAKE_FS1
161                 35, 215, 240, 250
162 #else
163                 32, 212, 240, 250
164 #endif
165         },
166         { // GR_1024
167                 42, 351, 240, 400
168         }
169 };
170
171 static int Barracks_stats2_coords[GR_NUM_RESOLUTIONS][3] = {
172         { // GR_640
173                 276, 212, 81            // X2, , W2
174         },
175         { // GR_1024
176                 286, 351, 81            // X2, , W2
177         }
178 };
179
180 // pilot picture field
181 static int Barracks_image_coords[GR_NUM_RESOLUTIONS][4] = {
182         { // GR_640
183 #ifdef MAKE_FS1
184                 460, 33, 160, 120
185 #else
186                 461, 23, 160, 120
187 #endif
188         },
189         { // GR_1024
190                 782, 58, 160, 120
191         }
192 };
193
194 // pilot picture # of # location
195 static int Barracks_image_number_coords[GR_NUM_RESOLUTIONS][2] = {
196         { // GR_640
197 #ifdef MAKE_FS1
198 #ifndef FS1_DEMO
199                 489, 171
200 #else
201                 489, 183
202 #endif  // FS1_DEMO
203 #else
204                 461, 145
205 #endif
206         },
207         { // GR_1024
208                 732, 239
209         }
210 };
211
212 // pilot squad logo field
213 int Barracks_squad_coords[GR_NUM_RESOLUTIONS][4] = {
214         { // GR_640
215                 495, 177, 128, 128
216         },
217         { // GR_1024
218                 829, 323, 128, 128
219         }
220 };
221
222 // pilot squad # of # location
223 int Barracks_squad_number_coords[GR_NUM_RESOLUTIONS][2] = {
224         { // GR_640
225                 492, 307
226         },
227         { // GR_1024
228                 794, 500
229         }
230 };
231
232 // button defines
233 #ifdef MAKE_FS1
234         #define BARRACKS_NUM_BUTTONS            17
235 #else
236         #define BARRACKS_NUM_BUTTONS            19
237 #endif
238
239 // pilot selection buttons
240 #define B_PILOT_CREATE_BOTTON                   0       // B_PILOT_CREATE_BOTTON
241 #define B_PILOT_SCROLL_UP_BUTTON                1       // B_PILOT_SCROLL_UP_BUTTON
242 #define B_PILOT_SCROLL_DOWN_BUTTON      2       // B_PILOT_SCROLL_DOWN_BUTTON
243 #define B_PILOT_DELETE_BUTTON                   11      // B_PILOT_B_PILOT_DELETE_BUTTON
244 #define B_PILOT_SET_ACTIVE_BUTTON       12      // B_PILOT_B_PILOT_SET_ACTIVE_BUTTON
245 #define B_PILOT_CLONE_BUTTON                    13      // B_PILOT_B_PILOT_CLONE_BUTTON
246 #define B_PILOT_SINGLE_MODE_BUTTON      14      // B_PILOT_SINGLE_MODE_BUTTON
247 #define B_PILOT_MULTI_MODE_BUTTON       15      // B_PILOT_MULTI_MODE_BUTTON
248 #define B_PILOT_CONVERT_BUTTON          16      // B_PILOT_B_PILOT_CONVERT_BUTTON
249
250 #ifndef MAKE_FS1
251 // squad logo picture buttons
252 #define B_SQUAD_PREV_BUTTON                     17
253 #define B_SQUAD_NEXT_BUTTON                     18
254 #endif
255
256 // pilot picture buttons
257 #define B_PIC_PREV_PILOT_BUTTON         3       // B_PILOT_B_PIC_PREV_PILOT_BUTTON
258 #define B_PIC_NEXT_PILOT_BUTTON         4       // B_PILOT_B_PIC_NEXT_PILOT_BUTTON
259
260 // pilot stat buttons
261 #define B_STATS_MEDAL_BUTTON                    8       // B_STATS_MEDAL_BUTTON
262 #define B_STATS_SCROLL_DOWN_BUTTON      9       // B_STATS_SCROLL_DOWN_BUTTON
263 #define B_STATS_SCROLL_UP_BUTTON                10      // B_STATS_SCROLL_UP_BUTTON
264
265 // general buttons
266 #define B_ACCEPT_BUTTON                                 5       // B_B_ACCEPT_BUTTON
267 #define B_HELP_BUTTON                                   6       // B_B_HELP_BUTTON
268 #define B_OPTION_BUTTON                                 7       // B_OPTION_BUTTON
269
270 //XSTR:OFF
271 // bitmaps defs
272 static char *Barracks_bitmap_fname[GR_NUM_RESOLUTIONS] = {
273         "Barracks",             // GR_640
274         "2_Barracks"            // GR_1024
275 };
276
277 static char *Barracks_bitmap_mask_fname[GR_NUM_RESOLUTIONS] = {
278         "Barracks-M",           // GR_640
279         "2_Barracks-M"          // GR_1024
280 };
281
282 //XSTR:ON
283
284 #define BARRACKS_IMAGE_NOT_LOADED       -2
285
286 struct barracks_bitmaps {
287         char *filename;
288         int x, y;
289         int b;
290 };
291
292 struct barracks_buttons {
293         char *filename;
294         int x, y;
295         int text_x, text_y;     // this is where the text label is
296         int hotspot;
297         int repeat;
298         UI_BUTTON button;  // because we have a class inside this struct, we need the constructor below..
299
300         barracks_buttons(char *name, int x1, int y1, int x2, int y2, int h, int r = 0) : filename(name), x(x1), y(y1), text_x(x2), text_y(y2), hotspot(h), repeat(r) {}
301 };
302
303 #if defined(MAKE_FS1) && !defined(FS1_DEMO)
304 static int Background_bitmap;
305 static int PilotWin01 = -1;
306 static int PilotWin02 = -1;
307 static int PilotWin03 = -1;
308 static int PilotWin04 = -1;
309 #else
310 static int Background_bitmap = -1;
311 #endif
312 static UI_WINDOW Ui_window;
313 static UI_BUTTON List_region;
314 static UI_INPUTBOX Inputbox;
315
316 static barracks_buttons Buttons[GR_NUM_RESOLUTIONS][BARRACKS_NUM_BUTTONS] = {
317 //XSTR:OFF
318         {               // GR_640
319 #ifdef MAKE_FS1
320                         barracks_buttons("BAB_00",      12,             121,    -1,     -1,             0),             // create
321                         barracks_buttons("BAB_01",      322,    137,    -1,     -1,     1,      1),             // barracks - arrow up
322                         barracks_buttons("BAB_02",      347,    137,    -1,     -1,     2,      1),             // barracks - arrow down
323 #ifndef FS1_DEMO
324                         barracks_buttons("BAB_03",      570,    140,    -1,     -1,     3,      1),             // pilot window - arrow left
325                         barracks_buttons("BAB_04",      591,    140,    -1,     -1,     4,      1),             // pilot window - arrow right
326 #else
327                         barracks_buttons("BAB_03",      570,    157,    -1,     -1,     3,      1),             // pilot window - arrow left
328                         barracks_buttons("BAB_04",      591,    157,    -1,     -1,     4,      1),             // pilot window - arrow right
329 #endif
330                         barracks_buttons("BAB_05",      562,    410,    -1,     -1,             5),             // accept
331                         barracks_buttons("BAB_06",      469,    427,    -1,     -1,             6),             // help
332                         barracks_buttons("BAB_07",      447,    452,    -1,     -1,             7),             // options
333                         barracks_buttons("BAB_08",      365,    415,    -1,     -1,             8),             // medals
334                         barracks_buttons("BAB_09",      0,              225,    -1,     -1,     9,      1),             // pilot stats - arrows down
335                         barracks_buttons("BAB_10",      0,              185,    -1,     -1,     10,     1),             // pilot stats - arrows up
336                         barracks_buttons("BAB_11",      124,    121,    -1,     -1,             11),    // remove
337                         barracks_buttons("BAB_12",      374,    127,    -1,     -1,             12),    // barracks - accept
338                         barracks_buttons("BAB_13",      70,             121,    -1,     -1,             13),    // clone
339                         barracks_buttons("BAB_14",      329,    13,             -1,     -1,             14),    // single
340                         barracks_buttons("BAB_15",      380,    13,             -1,     -1,             15),    // multi
341                         barracks_buttons("BAB_16",      183,    121,    -1,     -1,             16)             // convert
342 #else
343                         barracks_buttons("BAB_00", 8,           122,    11,     157,    0),             
344                         barracks_buttons("BAB_01", 323, 130,    0,              0,              1, 1),
345                         barracks_buttons("BAB_02", 350, 130,    0,              0,              2,      1),
346                         barracks_buttons("BAB_03", 559, 143,    0,              0,              3,      1),                     
347                         barracks_buttons("BAB_04", 598, 143,    0,              0,              4,      1),
348                         barracks_buttons("BAB_05", 571, 425,    578,    413,    5),
349                         barracks_buttons("BAB_06", 533, 425,    500,    438,    6),
350                         barracks_buttons("BAB_07", 533, 453,    481,    465,    7),
351                         barracks_buttons("BAB_08", 361, 425,    401,    465,    8),
352                         barracks_buttons("BAB_09", 0,           267,    0,              0,              9,      1),
353                         barracks_buttons("BAB_10", 0,           224,    0,              0,              10,1),
354                         barracks_buttons("BAB_11", 120, 122,    123,    157,    11),    
355                         barracks_buttons("BAB_12", 376, 124,    378,    163,    12),
356                         barracks_buttons("BAB_13", 66,  122,    69,     157,    13),
357                         barracks_buttons("BAB_14", 323, 0,              324,    25,     14),
358                         barracks_buttons("BAB_15", 372, 0,              374,    25,     15),
359                         barracks_buttons("BAB_16", 180, 122,    182,    157,    16),
360                         barracks_buttons("BAB_17", 559, 306,    0,              0,              17),
361                         barracks_buttons("BAB_18", 598, 306,    0,              0,              18)
362 #endif
363         },
364         {               // GR_1024
365                         barracks_buttons("2_BAB_00", 14,                196,    35,     252,    0),
366                         barracks_buttons("2_BAB_01", 518,       209,    0,              0,              1,      1),
367                         barracks_buttons("2_BAB_02", 561,       209,    0,              0,              2,      1),
368                         barracks_buttons("2_BAB_03", 896,       229,    0,              0,              3,      1),
369                         barracks_buttons("2_BAB_04", 958,       229,    0,              0,              4,      1),
370                         barracks_buttons("2_BAB_05", 914,       681,    932,    665,    5),
371                         barracks_buttons("2_BAB_06", 854,       681,    800,    704,    6),
372                         barracks_buttons("2_BAB_07", 854,       724,    778,    743,    7),
373                         barracks_buttons("2_BAB_08", 579,       681,    641,    743,    8),
374                         barracks_buttons("2_BAB_09", 0,         428,    0,              0,              9,      1),
375                         barracks_buttons("2_BAB_10", 0,         360,    0,              0,              10,1),
376                         barracks_buttons("2_BAB_11", 193,       196,    214,    252,    11),
377                         barracks_buttons("2_BAB_12", 602,       200,    617,    262,    12),
378                         barracks_buttons("2_BAB_13", 107,       196,    128,    252,    13),
379                         barracks_buttons("2_BAB_14", 517,       0,              532,    40,     14),
380                         barracks_buttons("2_BAB_15", 596,       0,              614,    40,     15),
381                         barracks_buttons("2_BAB_16", 289,       196,    309,    252,    16),
382 #ifndef MAKE_FS1
383                         barracks_buttons("2_BAB_17", 896,       491,    0,              0,              17),
384                         barracks_buttons("2_BAB_18", 958,       491,    0,              0,              18)
385 #endif
386         }
387 //XSTR:ON
388 };
389
390
391 // FIXME add to strings.tbl, set correct coords
392 #ifdef MAKE_FS1
393         #define BARRACKS_NUM_TEXT                       0
394 #else
395         #define BARRACKS_NUM_TEXT                       2
396 #endif
397 UI_XSTR Barracks_text[GR_NUM_RESOLUTIONS][BARRACKS_NUM_TEXT] = {
398         { 
399                 // GR_640
400 #ifdef MAKE_FS1
401                 // nothing needed
402 #else
403                 { "Barracks",                   1434,           17, 7,          UI_XSTR_COLOR_GREEN, -1, NULL },
404                 { "Pilot Stats",                1435,           17, 180,                UI_XSTR_COLOR_GREEN, -1, NULL }
405 #endif
406         }, 
407         { 
408                 // GR_1024
409 #ifdef MAKE_FS1
410                 // nothing needed
411 #else
412                 { "Barracks",                   1434,           27, 11,         UI_XSTR_COLOR_GREEN, -1, NULL },
413                 { "Pilot Stats",                1435,           27, 288,                UI_XSTR_COLOR_GREEN, -1, NULL }
414 #endif
415         }
416 };
417
418
419 static int Num_stat_lines;
420 static char Stat_labels[NUM_STAT_LINES][STAT_COLUMN1_W];
421 static char Stats[NUM_STAT_LINES][STAT_COLUMN2_W];
422
423 extern int Player_sel_mode;
424
425 static player *Cur_pilot;
426 static int Num_pilots;
427 static int Selected_line;
428 static char Pilots_arr[MAX_PILOTS][MAX_FILENAME_LEN];
429 static char *Pilots[MAX_PILOTS];
430 static int Pic_number;
431 static int Pic_squad_number;
432 static bool Barracks_callsign_enter_mode;
433 static int Pilot_ranks[MAX_PILOTS];
434 static int List_scroll_offset;
435 static int Stats_scroll_offset;
436 static int Clone_flag;
437 static int Pilot_images[MAX_PILOT_IMAGES];
438 static int Pilot_squad_images[MAX_PILOT_IMAGES];
439 static int Rank_pips_bitmaps;
440 static int Rank_pips_count;
441
442 void barracks_squad_change_popup();
443
444
445 // -------------------------------------------------------------------------------------------------
446 //
447 // BARRACKS screen
448 //
449
450 #define STRCPY1(a, b) do {      \
451         Assert(strlen(b) < STAT_COLUMN1_W); \
452         strcpy(a, b); \
453 } while (0)
454
455 void barracks_init_stats(scoring_struct *stats)
456 {
457         int i;
458         float f;
459
460         Num_stat_lines = 0;
461
462         STRCPY1(Stat_labels[Num_stat_lines], XSTR( "*All Time Stats", 50));
463         Stats[Num_stat_lines][0] = 0;
464         Num_stat_lines++;
465
466         Assert(Num_stat_lines < NUM_STAT_LINES);
467         Stat_labels[Num_stat_lines][0] = 0;
468         Stats[Num_stat_lines][0] = 0;
469         Num_stat_lines++;       
470
471         Assert(Num_stat_lines < NUM_STAT_LINES);
472         STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Primary weapon shots:", 51));
473         sprintf(Stats[Num_stat_lines], "%d", stats->p_shots_fired);
474         Num_stat_lines++;
475
476         Assert(Num_stat_lines < NUM_STAT_LINES);
477         STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Primary weapon hits:", 52));
478         sprintf(Stats[Num_stat_lines], "%d", stats->p_shots_hit);
479         Num_stat_lines++;
480
481         Assert(Num_stat_lines < NUM_STAT_LINES);
482         STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Primary friendly hits:", 53));
483         sprintf(Stats[Num_stat_lines], "%d", stats->p_bonehead_hits);
484         Num_stat_lines++;
485
486         Assert(Num_stat_lines < NUM_STAT_LINES);
487         STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Primary hit %:", 54));
488         if (stats->p_shots_fired > 0) {
489                 f = (float) stats->p_shots_hit * 100.0f / (float) stats->p_shots_fired;
490         } else {
491                 f = 0.0f;
492         }
493         sprintf(Stats[Num_stat_lines], XSTR( "%.1f%%", 55), f);
494         Num_stat_lines++;
495
496         Assert(Num_stat_lines < NUM_STAT_LINES);
497         STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Primary friendly hit %:", 56));
498         if (stats->p_bonehead_hits > 0) {
499                 f = (float) stats->p_bonehead_hits * 100.0f / (float) stats->p_shots_fired;
500         } else {
501                 f = 0.0f;
502         }
503         sprintf(Stats[Num_stat_lines], XSTR( "%.1f%%", 55), f);
504         Num_stat_lines++;
505
506         Assert(Num_stat_lines < NUM_STAT_LINES);
507         Stat_labels[Num_stat_lines][0] = 0;
508         Stats[Num_stat_lines][0] = 0;
509         Num_stat_lines++;
510
511         Assert(Num_stat_lines < NUM_STAT_LINES);
512         STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Secondary weapon shots:", 57));
513         sprintf(Stats[Num_stat_lines], "%d", stats->s_shots_fired);
514         Num_stat_lines++;
515
516         Assert(Num_stat_lines < NUM_STAT_LINES);
517         STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Secondary weapon hits:", 58));
518         sprintf(Stats[Num_stat_lines], "%d", stats->s_shots_hit);
519         Num_stat_lines++;
520
521         Assert(Num_stat_lines < NUM_STAT_LINES);
522         STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Secondary friendly hits:", 59));
523         sprintf(Stats[Num_stat_lines], "%d", stats->s_bonehead_hits);
524         Num_stat_lines++;
525
526         Assert(Num_stat_lines < NUM_STAT_LINES);
527         STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Secondary hit %:", 60));
528         if (stats->s_shots_fired > 0) {
529                 f = (float) stats->s_shots_hit * 100.0f / (float) stats->s_shots_fired;
530         } else {
531                 f = 0.0f;
532         }
533         sprintf(Stats[Num_stat_lines], XSTR( "%.1f%%", 55), f);
534         Num_stat_lines++;
535
536         Assert(Num_stat_lines < NUM_STAT_LINES);
537         STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Secondary friendly hit %:", 61));
538         if (stats->s_bonehead_hits > 0) {
539                 f = (float) stats->s_bonehead_hits * 100.0f / (float) stats->s_shots_fired;
540         } else {
541                 f = 0.0f;
542         }
543         sprintf(Stats[Num_stat_lines], XSTR( "%.1f%%", 55), f);
544         Num_stat_lines++;
545
546         Assert(Num_stat_lines < NUM_STAT_LINES);
547         Stat_labels[Num_stat_lines][0] = 0;
548         Stats[Num_stat_lines][0] = 0;
549         Num_stat_lines++;
550
551         Assert(Num_stat_lines < NUM_STAT_LINES);
552         STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Total kills:", 62));
553         sprintf(Stats[Num_stat_lines], "%d", stats->kill_count_ok);
554         Num_stat_lines++;
555
556         Assert(Num_stat_lines < NUM_STAT_LINES);
557         STRCPY1(Stat_labels[Num_stat_lines], XSTR( "Assists:", 63));
558         sprintf(Stats[Num_stat_lines], "%d", stats->assists);
559         Num_stat_lines++;
560
561         Assert(Num_stat_lines < NUM_STAT_LINES);
562         Stat_labels[Num_stat_lines][0] = 0;
563         Stats[Num_stat_lines][0] = 0;
564         Num_stat_lines++;
565
566         Assert(Num_stat_lines < NUM_STAT_LINES);
567         Stat_labels[Num_stat_lines][0] = 0;
568         Stats[Num_stat_lines][0] = 0;
569         Num_stat_lines++;
570
571         STRCPY1(Stat_labels[Num_stat_lines], XSTR( "*Kills by Ship Type", 64));
572         Stats[Num_stat_lines][0] = 0;
573         Num_stat_lines++;
574
575         Assert(Num_stat_lines < NUM_STAT_LINES);
576         Stat_labels[Num_stat_lines][0] = 0;
577         Stats[Num_stat_lines][0] = 0;
578         Num_stat_lines++;
579
580         for (i=0; i<Num_ship_types; i++) {
581                 if (stats->kills[i]) {
582                         Assert(Num_stat_lines < NUM_STAT_LINES);
583                         Assert(strlen(Ship_info[i].name) + 1 < STAT_COLUMN1_W);
584                         sprintf(Stat_labels[Num_stat_lines], NOX("%s:"), Ship_info[i].name);
585                         sprintf(Stats[Num_stat_lines], "%d", stats->kills[i]);
586                         Num_stat_lines++;
587                 }
588         }
589
590         for (i=0; i<Num_stat_lines; i++) {
591                 gr_force_fit_string(Stat_labels[i], Stat_column1_w[gr_screen.res], Barracks_stats_coords[gr_screen.res][BARRACKS_W_COORD]);
592                 gr_force_fit_string(Stats[i], Stat_column2_w[gr_screen.res], Barracks_stats2_coords[gr_screen.res][BARRACKS_W_COORD]);
593         }
594 }
595
596 // sets or clears hotkeys for pilot selection.
597 void barracks_set_hotkeys(bool pilot_text_enter_mode)
598 {
599         Buttons[gr_screen.res][B_PILOT_SCROLL_UP_BUTTON].button.set_hotkey(pilot_text_enter_mode ? KEY_UP : -1);
600         Buttons[gr_screen.res][B_PILOT_SCROLL_DOWN_BUTTON].button.set_hotkey(pilot_text_enter_mode ? KEY_DOWN : -1);
601
602         Buttons[gr_screen.res][B_PILOT_CREATE_BOTTON].button.set_hotkey(pilot_text_enter_mode ? KEY_C : -1);
603         Buttons[gr_screen.res][B_PILOT_SET_ACTIVE_BUTTON].button.set_hotkey(pilot_text_enter_mode ? KEY_ENTER : -1);
604         Buttons[gr_screen.res][B_PILOT_DELETE_BUTTON].button.set_hotkey(pilot_text_enter_mode ? KEY_DELETE : -1);
605
606         Buttons[gr_screen.res][B_PIC_PREV_PILOT_BUTTON].button.set_hotkey(pilot_text_enter_mode ? KEY_LEFT : -1);
607         Buttons[gr_screen.res][B_PIC_NEXT_PILOT_BUTTON].button.set_hotkey(pilot_text_enter_mode ? KEY_RIGHT : -1);
608
609         Buttons[gr_screen.res][B_ACCEPT_BUTTON].button.set_hotkey(pilot_text_enter_mode ? KEY_CTRLED | KEY_ENTER : -1);
610 }
611
612 // strip the possible .pcx extension off a filename
613 void barracks_strip_pcx(char *str)
614 {
615         int flen = strlen(str);
616         int elen = 4;           
617         if ((flen > 4) && !stricmp(str + flen - elen, ".pcx")) {
618                 str[flen - elen] = '\0';
619         }
620 }
621
622 // new pilot name has focus, so update stats/pic to that pilot
623 int barracks_new_pilot_selected()
624 {
625         char stripped[MAX_FILENAME_LEN+1] = "";
626
627         // save the previous pilot first, so changes to it are kept
628         if (strlen(Cur_pilot->callsign)) {
629                 write_pilot_file();
630         }
631
632         // check if we have a valid pilot hilighted.  If so, attempt to active it
633         if ((Num_pilots < 1) || (Selected_line < 0) || (Selected_line >= Num_pilots)) {
634                 Cur_pilot->callsign[0] = 0;  // this indicates no pilot active
635                 return -1;
636         }
637
638         if (read_pilot_file(Pilots[Selected_line], !Player_sel_mode, Cur_pilot)) {
639                 Cur_pilot->callsign[0] = 0;  // this indicates no pilot active
640                 return -1;
641         }
642
643         // init stuff to reflect new pilot
644         int i;
645         barracks_init_stats(&Cur_pilot->stats);
646         for (i=0; i<Num_pilot_images; i++) {
647                 strcpy(stripped, Cur_pilot->image_filename);
648                 barracks_strip_pcx(stripped);
649                 if (!stricmp(stripped, Pilot_image_names[i])) {
650                         break;
651                 }
652         }
653         Pic_number = i;
654         for ( i=0; i<Num_pilot_squad_images; i++) {
655                 strcpy(stripped, Cur_pilot->squad_filename);
656                 barracks_strip_pcx(stripped);
657                 if (!stricmp(stripped, Pilot_squad_image_names[i])) {
658                         break;
659                 }
660         }
661         Pic_squad_number = i;   
662         
663         return 0;
664 }
665
666 void barracks_set_callsign_enter_mode(bool set_callsign_enter_mode)
667 {
668         // set global mode variable
669         Barracks_callsign_enter_mode = set_callsign_enter_mode;
670
671         // disable/enable all buttons
672         for (int idx=0; idx<BARRACKS_NUM_BUTTONS; idx++) {
673                 // don't ever mess with the prev and next squad logo buttons
674 #ifdef MAKE_FS1
675                 Buttons[gr_screen.res][idx].button.enable(!set_callsign_enter_mode);
676 #else
677                 if((idx != B_SQUAD_PREV_BUTTON) && (idx != B_SQUAD_NEXT_BUTTON)){
678                         Buttons[gr_screen.res][idx].button.enable(!set_callsign_enter_mode);
679                 }
680 #endif
681         }
682
683         // enable/disable hotkeys
684         barracks_set_hotkeys(!set_callsign_enter_mode);
685         // disable/enable inputbox
686         Inputbox.enable(set_callsign_enter_mode);
687         // hide/unhide inputbox
688         Inputbox.hide(!set_callsign_enter_mode);
689 }
690
691 // creates a new pilot file
692 void barracks_create_new_pilot()
693 {
694         // check if too many pilots
695         if (Num_pilots >= MAX_PILOTS) {
696                 gamesnd_play_iface(SND_GENERAL_FAIL);
697                 return;
698         }
699
700         // play sound for pilot creation
701         gamesnd_play_iface(SND_SCROLL);
702         
703         // only write pilot file if there is an active pilot
704         if (strlen(Player->callsign)) {
705                 write_pilot_file();
706         }
707
708         // move other pilot names and ranks down to make room for the new one
709         int idx = Num_pilots;
710         Assert(Num_pilots >= 0);
711         while (idx--) {
712                 strcpy(Pilots[idx + 1], Pilots[idx]);
713                 Pilot_ranks[idx + 1] = Pilot_ranks[idx];
714         }
715
716         Selected_line = 0;
717         Num_pilots++;
718         Pilots[Selected_line][0] = 0;
719         Pilot_ranks[Selected_line] = 0;
720         List_scroll_offset = 0;
721
722         // set mode to accept pilot name text
723         barracks_set_callsign_enter_mode(true);
724         // set focus to input box
725         Inputbox.set_focus();
726         // set initial pilot name to ""
727         Inputbox.set_text("");
728         // reset size of input box to only 1 line
729         Inputbox.update_dimensions(Barracks_list_coords[gr_screen.res][BARRACKS_X_COORD], Barracks_list_coords[gr_screen.res][BARRACKS_Y_COORD], Barracks_list_coords[gr_screen.res][BARRACKS_W_COORD], gr_get_font_height());
730 }
731
732 // exiting screen without canceling, so load in the new pilot selected here
733 int barracks_pilot_accepted()
734 {
735         char str[CALLSIGN_LEN + 1];
736
737         // check if pilot active.  If not, don't allow accept.
738         if (!Cur_pilot->callsign[0]){
739                 return -1;
740         }
741
742         // set his image 
743         player_set_squad_bitmap(Cur_pilot, Cur_pilot->squad_filename);
744
745 //      Skill_level = get_default_skill_level();
746
747         // MWA -- I think that we should be writing Cur_pilot here.
748         //write_pilot_file(!is_pilot_multi(Cur_pilot));
749         write_pilot_file( Cur_pilot );
750         
751         // when we store the LastPlayer key, we have to mark it as being single or multiplayer, so we know where to look for him
752         // (since we could have a single and a multiplayer pilot with the same callsign)
753         // we'll distinguish them by putting an M and the end of the multiplayer callsign and a P at the end of a single player
754         strcpy(str, Cur_pilot->callsign);
755         strcat(str, is_pilot_multi(Cur_pilot) ? NOX("M") : NOX("S"));
756         os_config_write_string( NULL, "LastPlayer", str );
757         return 0;
758 }
759
760 // scroll up barracks pilot list one line
761 void barracks_scroll_callsign_up()
762 {
763         if (Selected_line > 0) {
764                 Selected_line--;
765                 gamesnd_play_iface(SND_SCROLL);
766         } else {
767                 gamesnd_play_iface(SND_GENERAL_FAIL);
768         }
769         
770         if ((Selected_line >= 0) && (Selected_line < List_scroll_offset)) {
771                 List_scroll_offset = Selected_line;
772         }
773 }
774
775 // scroll down barracks pilot list one line
776 void barracks_scroll_callsign_down()
777 {
778         if (Selected_line < Num_pilots - 1) {
779                 Selected_line++;
780                 gamesnd_play_iface(SND_SCROLL);
781         } else {
782                 gamesnd_play_iface(SND_GENERAL_FAIL);
783         }
784         
785         // num_pilots_to_fill_height is the number of pilots that can fit in given height
786         int num_pilots_to_fill_height = Barracks_list_coords[gr_screen.res][BARRACKS_H_COORD] / gr_get_font_height();
787         if (Selected_line >= List_scroll_offset + num_pilots_to_fill_height) {
788                 List_scroll_offset++;
789         }
790 }
791
792 // scroll up barracks stats list one line
793 void barracks_scroll_stats_up()
794 {
795         if (Stats_scroll_offset > 0) {
796                 Stats_scroll_offset--;
797                 gamesnd_play_iface(SND_SCROLL);
798         } else {
799                 gamesnd_play_iface(SND_GENERAL_FAIL);
800         }
801 }
802
803 // scroll down barracks stats list one line
804 void barracks_scroll_stats_down()
805 {
806         int font_height = gr_get_font_height();
807
808         if (Stats_scroll_offset + Barracks_stats_coords[gr_screen.res][BARRACKS_H_COORD] / font_height < Num_stat_lines) {
809                 Stats_scroll_offset++;
810                 gamesnd_play_iface(SND_SCROLL);
811         } else {
812                 gamesnd_play_iface(SND_GENERAL_FAIL);
813         }
814 }
815
816 // show previous pilot pic
817 void barracks_prev_pic()
818 {
819         // check if no pilot images or no pilot selected
820         if ((Num_pilot_images == 0) || (Cur_pilot->callsign[0] == '\0')) {
821                 gamesnd_play_iface(SND_GENERAL_FAIL);
822                 return;
823         }
824
825         // reset pilot pic number
826         Pic_number--;
827         if (Pic_number < 0) {
828                 Pic_number = Num_pilot_images - 1;
829         }
830
831         // copy pilot pic filename into pilot struct
832         if ((Pic_number >= 0) && (Pic_number < Num_pilot_images)) {
833                 strcpy(Cur_pilot->image_filename, Pilot_image_names[Pic_number]);
834         }
835
836         // play scroll sound
837         gamesnd_play_iface(SND_SCROLL);
838 }
839
840 // show next pilot pic
841 void barracks_next_pic()
842 {
843         // check if no pilot images or no pilot selected
844         if ((Num_pilot_images == 0) || (Cur_pilot->callsign[0] == '\0')) {
845                 gamesnd_play_iface(SND_GENERAL_FAIL);
846                 return;
847         }
848
849         // reset pilot pic number
850         Pic_number++;
851         if (Pic_number >= Num_pilot_images){
852                 Pic_number = 0;
853         }
854
855         // copy pilot pic filename into pilot struct
856         if ((Pic_number >= 0) && (Pic_number < Num_pilot_images)){
857                 strcpy(Cur_pilot->image_filename, Pilot_image_names[Pic_number]);
858         }
859
860         // play scroll sound
861         gamesnd_play_iface(SND_SCROLL);
862 }
863
864 // show previous squad pic
865 void barracks_prev_squad_pic()
866 {
867         // check if no pilot images or no pilot selected
868         if ((Num_pilot_squad_images == 0) || (Cur_pilot->callsign[0] == '\0')) {
869                 gamesnd_play_iface(SND_GENERAL_FAIL);
870                 return;
871         }
872
873         // reset pilot pic number
874         Pic_squad_number--;
875         if (Pic_squad_number < 0) {
876                 Pic_squad_number = Num_pilot_squad_images - 1;
877         }
878
879         // copy pilot pic filename into pilot struct
880         if ((Pic_squad_number >= 0) && (Pic_squad_number < Num_pilot_squad_images)) {
881                 strcpy(Cur_pilot->squad_filename, Pilot_squad_image_names[Pic_squad_number]);
882         }
883
884         // play scroll sound
885         gamesnd_play_iface(SND_SCROLL);
886 }
887
888 // show next pilot pic
889 void barracks_next_squad_pic()
890 {
891         // check if no pilot images or no pilot selected
892         if ((Num_pilot_squad_images == 0) || (Cur_pilot->callsign[0] == '\0')) {
893                 gamesnd_play_iface(SND_GENERAL_FAIL);
894                 return;
895         }
896
897         // reset pilot pic number
898         Pic_squad_number++;
899         if (Pic_squad_number >= Num_pilot_squad_images){
900                 Pic_squad_number = 0;
901         }
902
903         // copy pilot pic filename into pilot struct
904         if ((Pic_squad_number >= 0) && (Pic_squad_number < Num_pilot_squad_images)){
905                 strcpy(Cur_pilot->squad_filename, Pilot_squad_image_names[Pic_squad_number]);
906         }
907
908         // play scroll sound
909         gamesnd_play_iface(SND_SCROLL);
910 }
911
912 void barracks_delete_pilot()
913 {
914         char buf[MAX_FILENAME_LEN];
915         int active = 0;
916
917         if (!Num_pilots) {
918                 gamesnd_play_iface(SND_GENERAL_FAIL);
919                 return;
920         }
921
922         int popup_rval = popup(PF_TITLE_BIG | PF_TITLE_RED, 2, POPUP_NO, POPUP_YES, XSTR( "Warning!\n\nAre you sure you wish to delete this pilot?", 65));
923         if (popup_rval != 1) {
924                 return;
925         }
926
927         if (!stricmp(Pilots[Selected_line], Cur_pilot->callsign)) {
928                 active = 1;
929         }
930
931         strcpy(buf, Pilots[Selected_line]);
932         for (int i=Selected_line; i<Num_pilots-1; i++) {
933                 strcpy(Pilots[i], Pilots[i + 1]);
934                 Pilot_ranks[i] = Pilot_ranks[i + 1];
935         }
936
937         Num_pilots--;
938         if (Selected_line >= Num_pilots) {
939                 Selected_line = Num_pilots - 1;
940         }
941
942         if (active) {
943                 if (Selected_line >= 0) {
944                         barracks_new_pilot_selected();
945                 } else {
946                         Cur_pilot->callsign[0] = 0;
947                 }
948         }
949
950         delete_pilot_file(buf, Player_sel_mode == PLAYER_SELECT_MODE_SINGLE ? 1 : 0);
951         gamesnd_play_iface(SND_USER_SELECT);
952 }
953
954 // Filter out pilots of wrong type (which shouldn't be in the directory we are checking, but just to be safe..)
955 int barracks_pilot_filter(char *filename)
956 {
957         int r, rank;
958
959         r = verify_pilot_file(filename, Player_sel_mode == PLAYER_SELECT_MODE_SINGLE, &rank);
960         if (rank >= Rank_pips_count)
961                 rank = Rank_pips_count - 1;
962
963         if (!r) {
964                 Pilot_ranks[Num_pilots++] = rank;
965         }
966
967         return !r;
968 }
969
970 // callback handler for the squadon selection buttons when they are disabled (in single player)
971 void barracks_squad_change_popup()
972 {
973         // show a popup
974         popup( PF_USE_AFFIRMATIVE_ICON | PF_NO_NETWORKING, 1, POPUP_OK, XSTR("You cannot change your squadron in Single Player mode.", 1445));
975 }
976
977
978 void barracks_init_player_stuff(int mode)
979 {
980         // determine if we should be looking for single or multiplayers at the outset
981         Player_sel_mode = mode;
982         
983         // get the list of pilots based upon whether we're in single or multiplayer mode
984         Num_pilots = 0;
985         Get_file_list_filter = barracks_pilot_filter;
986
987         // single player specific stuff
988         if (mode == PLAYER_SELECT_MODE_SINGLE) {
989                 Num_pilots = cf_get_file_list_preallocated(MAX_PILOTS, Pilots_arr, Pilots, CF_TYPE_SINGLE_PLAYERS, NOX("*.plr"), CF_SORT_TIME);
990
991 #ifndef MAKE_FS1
992                 // disable squad logo switching         
993                 Buttons[gr_screen.res][B_SQUAD_PREV_BUTTON].button.hide();
994                 Buttons[gr_screen.res][B_SQUAD_PREV_BUTTON].button.disable();
995                 Buttons[gr_screen.res][B_SQUAD_PREV_BUTTON].button.set_disabled_action(barracks_squad_change_popup);
996                 Buttons[gr_screen.res][B_SQUAD_NEXT_BUTTON].button.hide();
997                 Buttons[gr_screen.res][B_SQUAD_NEXT_BUTTON].button.disable();                   
998                 Buttons[gr_screen.res][B_SQUAD_NEXT_BUTTON].button.set_disabled_action(barracks_squad_change_popup);
999 #endif
1000         }
1001         // multiplayer specific stuff
1002         else {
1003                 Num_pilots = cf_get_file_list_preallocated(MAX_PILOTS, Pilots_arr, Pilots, CF_TYPE_MULTI_PLAYERS, NOX("*.plr"), CF_SORT_TIME);
1004
1005 #ifndef MAKE_FS1
1006                 // enable squad logo switching
1007                 Buttons[gr_screen.res][B_SQUAD_PREV_BUTTON].button.enable();
1008                 Buttons[gr_screen.res][B_SQUAD_PREV_BUTTON].button.unhide();
1009                 Buttons[gr_screen.res][B_SQUAD_NEXT_BUTTON].button.enable();
1010                 Buttons[gr_screen.res][B_SQUAD_NEXT_BUTTON].button.unhide();                    
1011 #endif
1012         }
1013
1014         int ranks[MAX_PILOTS];
1015
1016         for (int i=0; i<Num_pilots; i++) {
1017                 int j;
1018                 for (j=0; j<Num_pilots; j++) {
1019                         if (!strcmp(Pilots[i], Pilots_arr[j])) {
1020                                 ranks[i] = Pilot_ranks[j];
1021                                 break;
1022                         }
1023                 }
1024                 Assert(j < Num_pilots);  // Pilot not found?  How is that possible?
1025         }
1026
1027         for (int i=0; i<Num_pilots; i++) {
1028                 Pilot_ranks[i] = ranks[i];
1029         }
1030
1031         Selected_line = List_scroll_offset = 0;
1032         barracks_new_pilot_selected();
1033
1034 }
1035
1036 void barracks_button_pressed(int n)
1037 {
1038         switch (n) {
1039                 case B_PILOT_SCROLL_UP_BUTTON:
1040                         barracks_scroll_callsign_up();
1041                         break;
1042
1043                 case B_PILOT_SCROLL_DOWN_BUTTON:
1044                         barracks_scroll_callsign_down();
1045                         break;
1046
1047                 case B_STATS_SCROLL_UP_BUTTON:
1048                         barracks_scroll_stats_up();
1049                         break;
1050
1051                 case B_STATS_SCROLL_DOWN_BUTTON:
1052                         barracks_scroll_stats_down();
1053                         break;
1054
1055                 case B_PIC_PREV_PILOT_BUTTON:
1056                         barracks_prev_pic();
1057                         break;
1058
1059                 case B_PIC_NEXT_PILOT_BUTTON:
1060                         barracks_next_pic();
1061                         break;
1062
1063 #ifndef MAKE_FS1
1064                 case B_SQUAD_PREV_BUTTON:
1065                         barracks_prev_squad_pic();
1066                         break;
1067
1068                 case B_SQUAD_NEXT_BUTTON:
1069                         barracks_next_squad_pic();
1070                         break;
1071 #endif
1072
1073                 case B_PILOT_SET_ACTIVE_BUTTON:
1074                         if (barracks_new_pilot_selected()){
1075                                 gamesnd_play_iface(SND_GENERAL_FAIL);
1076                                 
1077                                 // throw up a popup telling the player that he should create a pilot first
1078                                 if(Player_sel_mode == PLAYER_SELECT_MODE_SINGLE){
1079                                         popup(PF_USE_AFFIRMATIVE_ICON,1,POPUP_OK,XSTR( "You must create a single player pilot.", 66));
1080                                 } else {
1081                                         popup(PF_USE_AFFIRMATIVE_ICON,1,POPUP_OK,XSTR( "You must create a multi player pilot.", 67));
1082                                 }
1083                         } else {
1084                                 gamesnd_play_iface(SND_SCROLL);
1085                         }
1086                         break;
1087
1088                 case B_ACCEPT_BUTTON:                   
1089                         if (Num_pilots && !barracks_pilot_accepted()) {
1090                                 gamesnd_play_iface(SND_COMMIT_PRESSED);
1091                                 gameseq_post_event(GS_EVENT_MAIN_MENU);
1092                         } else {
1093                                 gamesnd_play_iface(SND_GENERAL_FAIL);
1094
1095                                 // throw up a popup telling the player that he should create a pilot first
1096                                 if(Player_sel_mode == PLAYER_SELECT_MODE_SINGLE){
1097                                         popup(PF_USE_AFFIRMATIVE_ICON,1,POPUP_OK,XSTR( "You must create a single player pilot.", 66));
1098                                 } else {
1099                                         popup(PF_USE_AFFIRMATIVE_ICON,1,POPUP_OK,XSTR( "You must create a multi player pilot.", 67));
1100                                 }
1101                         }
1102                         break;
1103
1104                 case B_PILOT_CLONE_BUTTON:
1105                         if (Num_pilots < 1) {
1106                                 gamesnd_play_error_beep();
1107                                 break;
1108                         }
1109
1110                         Clone_flag = 1;
1111                         barracks_create_new_pilot();
1112                         break;
1113
1114                 case B_PILOT_CONVERT_BUTTON: {
1115 #if defined(DEMO) || defined(OEM_BUILD)
1116                         game_feature_not_in_demo_popup();
1117 #else
1118                         char temp[256], *str;
1119                         char old_pic[256] = "";
1120                         char old_squad_pic[256] = "";
1121                         char old_squad[256] = "";
1122                         int z;
1123
1124                         if (!barracks_new_pilot_selected()) {
1125                                 if (Player_sel_mode == PLAYER_SELECT_MODE_SINGLE)
1126                                         str = XSTR( "multiplayer", 68);
1127                                 else
1128                                         str = XSTR( "single player", 69);
1129
1130                                 sprintf(temp, XSTR( "This will overwrite your %s pilot.  Proceed?", 70), str);
1131                                 if (!verify_pilot_file(Cur_pilot->callsign, Player_sel_mode == PLAYER_SELECT_MODE_MULTI)) {
1132                                         z = popup(0, 2, POPUP_CANCEL, POPUP_OK, temp);
1133                                         if (z != 1)
1134                                                 break;
1135                                 }
1136
1137                                 strcpy(old_pic, Cur_pilot->image_filename);
1138                                 strcpy(old_squad_pic, Cur_pilot->squad_filename);
1139                                 strcpy(old_squad, Cur_pilot->squad_name);
1140                                 init_new_pilot(Cur_pilot, 0);
1141                                 strcpy(Cur_pilot->image_filename, old_pic);
1142                                 strcpy(Cur_pilot->squad_filename, old_squad_pic);
1143                                 strcpy(Cur_pilot->squad_name, old_squad);
1144                                 if (Player_sel_mode == PLAYER_SELECT_MODE_SINGLE) {
1145                                         Cur_pilot->flags |= PLAYER_FLAGS_IS_MULTI;
1146                                         write_pilot_file();
1147                                         barracks_init_player_stuff(PLAYER_SELECT_MODE_MULTI);
1148
1149                                 } else {
1150                                         write_pilot_file();
1151                                         barracks_init_player_stuff(PLAYER_SELECT_MODE_SINGLE);
1152                                 }
1153
1154                                 gamesnd_play_iface(SND_USER_SELECT);
1155
1156                         } else {
1157                                 gamesnd_play_iface(SND_GENERAL_FAIL);
1158                         }
1159 #endif
1160                         break;
1161                 }
1162
1163                 case B_PILOT_CREATE_BOTTON:
1164                         Clone_flag = 0;
1165                         barracks_create_new_pilot();
1166                         break;
1167
1168                 case B_HELP_BUTTON:
1169                         launch_context_help();
1170                         gamesnd_play_iface(SND_HELP_PRESSED);
1171                         break;
1172
1173                 case B_OPTION_BUTTON:
1174                         gamesnd_play_iface(SND_SWITCH_SCREENS);
1175                         gameseq_post_event(GS_EVENT_OPTIONS_MENU);
1176                         break;
1177
1178                 case B_STATS_MEDAL_BUTTON:
1179 #if defined(FS2_DEMO) || defined(FS1_DEMO)
1180                         game_feature_not_in_demo_popup();
1181 #else
1182                         gamesnd_play_iface(SND_SWITCH_SCREENS);
1183                         gameseq_post_event(GS_EVENT_VIEW_MEDALS);
1184 #endif
1185                         break;
1186
1187                 case B_PILOT_DELETE_BUTTON:
1188                         barracks_delete_pilot();
1189                         break;
1190
1191                 case B_PILOT_SINGLE_MODE_BUTTON:
1192                         if (Player_sel_mode != PLAYER_SELECT_MODE_SINGLE) {
1193                                 gamesnd_play_iface(SND_USER_SELECT);
1194                                 barracks_init_player_stuff(PLAYER_SELECT_MODE_SINGLE);
1195                         }                                               
1196                         break;
1197
1198                 case B_PILOT_MULTI_MODE_BUTTON:
1199 #if defined(DEMO) || defined(OEM_BUILD) // not for FS2_DEMO
1200                         game_feature_not_in_demo_popup();
1201 #else
1202                         if (Player_sel_mode != PLAYER_SELECT_MODE_MULTI) {
1203                                 gamesnd_play_iface(SND_USER_SELECT);
1204                                 barracks_init_player_stuff(PLAYER_SELECT_MODE_MULTI);
1205                         }
1206 #endif
1207                         break;
1208         }
1209 }
1210
1211
1212 void barracks_display_pilot_callsigns(int prospective_pilot)
1213 {
1214         int y = 0;
1215         int cur_pilot_idx = List_scroll_offset;
1216
1217         int multi = 0;
1218         if (Player_sel_mode == PLAYER_SELECT_MODE_MULTI) {
1219                 multi = 1;
1220         }
1221
1222         int font_height = gr_get_font_height();
1223         while (y + font_height <= Barracks_list_coords[gr_screen.res][BARRACKS_H_COORD]) {
1224                 if (cur_pilot_idx >= Num_pilots)
1225                         break;
1226
1227                 if (!stricmp(Cur_pilot->callsign, Pilots[cur_pilot_idx]) && (is_pilot_multi(Cur_pilot) == multi)) {
1228                         if ((cur_pilot_idx == Selected_line) || (cur_pilot_idx == prospective_pilot)) {
1229                                 gr_set_color_fast(&Color_text_active_hi);
1230                         } else {
1231                                 gr_set_color_fast(&Color_text_active);
1232                         }
1233                 } else {
1234                         if (cur_pilot_idx == Selected_line) {
1235                                 gr_set_color_fast(&Color_text_selected);
1236                         } else if (cur_pilot_idx == prospective_pilot) {
1237                                 gr_set_color_fast(&Color_text_subselected);
1238                         } else {
1239                                 gr_set_color_fast(&Color_text_normal);
1240                         }
1241                 }
1242
1243                 gr_printf(Barracks_list_coords[gr_screen.res][BARRACKS_X_COORD], Barracks_list_coords[gr_screen.res][BARRACKS_Y_COORD] + y, Pilots[cur_pilot_idx]);
1244 #ifndef FS1_DEMO
1245                 gr_set_bitmap(Rank_pips_bitmaps + Pilot_ranks[cur_pilot_idx]);
1246                 gr_bitmap(Barracks_list_coords[gr_screen.res][BARRACKS_X_COORD] - 34, Barracks_list_coords[gr_screen.res][BARRACKS_Y_COORD] + y);
1247 #endif
1248  
1249                 y += font_height;
1250                 cur_pilot_idx++;
1251         }
1252 }
1253
1254
1255
1256 void barracks_display_pilot_stats()
1257 {
1258         int y = 0;
1259         int z = Stats_scroll_offset;
1260         int font_height = gr_get_font_height();
1261         char *str;
1262         int i, w, h;
1263         while (y + font_height <= Barracks_stats_coords[gr_screen.res][BARRACKS_H_COORD]) {
1264                 if (z >= Num_stat_lines) {
1265                         break;
1266                 }
1267
1268                 str = Stat_labels[z];
1269                 if (*str == '*') {
1270                         gr_set_color_fast(&Color_text_heading);
1271                         str++;
1272
1273                         gr_get_string_size(&w, &h, str);
1274                         i = Barracks_stats_coords[gr_screen.res][BARRACKS_Y_COORD] + y + h / 2 - 1;                     
1275                         gr_line(Barracks_stats_coords[gr_screen.res][BARRACKS_X_COORD], i, Barracks_stats_coords[gr_screen.res][BARRACKS_X_COORD] + Barracks_stats_coords[gr_screen.res][BARRACKS_W_COORD] - w - 2, i);
1276                         gr_line(Barracks_stats_coords[gr_screen.res][BARRACKS_X_COORD] + Barracks_stats_coords[gr_screen.res][BARRACKS_W_COORD] + 1, i, Barracks_stats2_coords[gr_screen.res][BARRACKS_X_COORD] + Barracks_stats2_coords[gr_screen.res][BARRACKS_W_COORD], i);
1277
1278                 } else {
1279                         gr_set_color_fast(&Color_text_normal);
1280                 }
1281
1282                 gr_get_string_size(&w, NULL, str);
1283                 gr_printf(Barracks_stats_coords[gr_screen.res][BARRACKS_X_COORD] + Barracks_stats_coords[gr_screen.res][BARRACKS_W_COORD] - w, Barracks_stats_coords[gr_screen.res][BARRACKS_Y_COORD] + y, "%s", str);
1284                 str = Stats[z];
1285                 if (*str) {
1286                         gr_printf(Barracks_stats2_coords[gr_screen.res][BARRACKS_X_COORD], Barracks_stats_coords[gr_screen.res][BARRACKS_Y_COORD] + y, "%s", str);
1287                 }
1288
1289                 y += font_height;
1290                 z++;
1291         }
1292 }
1293
1294
1295 // process pilot callsign
1296 void barracks_accept_new_pilot_callsign()
1297 {
1298         char buf[CALLSIGN_LEN + 1];
1299         char name[MAX_FILENAME_LEN];
1300         int i;
1301
1302         int z = 0;
1303         Inputbox.get_text(buf);
1304         drop_white_space(buf);
1305
1306         if (!isalpha(*buf)) {
1307                 z = 1;
1308         } else {
1309                 for (i=1; buf[i]; i++) {
1310                         if (!isalpha(buf[i]) && !isdigit(buf[i]) && !strchr(VALID_PILOT_CHARS, buf[i])) {
1311                                 z = 1;
1312                                 return;
1313                         }
1314                 }
1315         }
1316
1317         for (i=1; i<Num_pilots; i++) {
1318                 if (!stricmp(buf, Pilots[i])) {
1319                         z = 1;
1320                         if (pilot_verify_overwrite() == 1) {
1321                                 strcpy(name, Pilots[Selected_line]);
1322                                 for (z=i; z<Num_pilots-1; z++) {
1323                                         strcpy(Pilots[z], Pilots[z + 1]);
1324                                         Pilot_ranks[z] = Pilot_ranks[z + 1];
1325                                 }
1326
1327                                 Num_pilots--;
1328                                 delete_pilot_file(name, Player_sel_mode == PLAYER_SELECT_MODE_SINGLE ? 1 : 0);
1329                                 z = 0;
1330                         }
1331                         return;
1332                 }
1333         }
1334
1335         if (!*buf || (i < Num_pilots)) { // duplicate name, alert user
1336                 z = 1;
1337         }
1338
1339         if (z) {
1340                 gamesnd_play_iface(SND_GENERAL_FAIL);
1341                 return;
1342         }
1343
1344         strcpy(Pilots[0], buf);
1345         strcpy(Cur_pilot->callsign, buf);
1346         init_new_pilot(Cur_pilot, !Clone_flag);
1347         
1348         // again, make sure we set his flags correctly to ensure that he gets saved to the proper directory and gets
1349         // displayed correctly
1350         if (Player_sel_mode == PLAYER_SELECT_MODE_SINGLE) {
1351                 Cur_pilot->flags &= ~(PLAYER_FLAGS_IS_MULTI);
1352         } else {
1353                 Cur_pilot->flags |= PLAYER_FLAGS_IS_MULTI;
1354                 Cur_pilot->stats.flags |= STATS_FLAG_MULTIPLAYER;
1355         }
1356
1357         if ( !(Game_mode & GM_STANDALONE_SERVER) ) {
1358                 write_pilot_file(Cur_pilot);
1359         }
1360
1361         Selected_line = 0;
1362         barracks_new_pilot_selected();
1363         barracks_set_callsign_enter_mode(false);
1364 }
1365
1366
1367 // draw pilot image and clean up afterwards
1368 void barracks_draw_pilot_pic()
1369 {
1370         // draw pilot pic
1371         if (Cur_pilot->callsign[0] && (Pic_number >= 0) && (Pic_number < Num_pilot_images)) {
1372                 if (Pilot_images[Pic_number] >= 0) {
1373                         // JAS: This code is hacked to allow the animation to use all 256 colors
1374                         extern int Palman_allow_any_color;
1375                         Palman_allow_any_color = 1;
1376                         gr_set_bitmap(Pilot_images[Pic_number]);
1377                         gr_bitmap(Barracks_image_coords[gr_screen.res][BARRACKS_X_COORD], Barracks_image_coords[gr_screen.res][BARRACKS_Y_COORD]);
1378                         Palman_allow_any_color = 0;
1379
1380                         // print number of the current pic
1381                         char buf[40];                   
1382                         sprintf(buf, XSTR( "%d of %d", 71), Pic_number + 1, Num_pilot_images);
1383                         gr_printf(Barracks_image_number_coords[gr_screen.res][BARRACKS_X_COORD], Barracks_image_number_coords[gr_screen.res][BARRACKS_Y_COORD], buf);                           
1384                 }
1385         } else {
1386                 Pic_number = -1;
1387         }
1388 }
1389
1390 // draw squad image and clean up afterwards
1391 void barracks_draw_squad_pic()
1392 {
1393         char buf[40];
1394
1395         // draw pilot pic
1396         if (Cur_pilot->callsign[0] && (Pic_squad_number >= 0) && (Pic_squad_number < Num_pilot_squad_images)) {
1397                 if (Pilot_squad_images[Pic_squad_number] >= 0) {
1398                         // JAS: This code is hacked to allow the animation to use all 256 colors
1399                         extern int Palman_allow_any_color;
1400                         Palman_allow_any_color = 1;
1401                         gr_set_bitmap(Pilot_squad_images[Pic_squad_number]);
1402                         gr_bitmap(Barracks_squad_coords[gr_screen.res][BARRACKS_X_COORD], Barracks_squad_coords[gr_screen.res][BARRACKS_Y_COORD]);
1403                         Palman_allow_any_color = 0;
1404
1405                         // print number of current squad pic
1406                         if(Player_sel_mode != PLAYER_SELECT_MODE_SINGLE){
1407                                 sprintf(buf,XSTR( "%d of %d", 71), Pic_squad_number+1, Num_pilot_squad_images);
1408                                 gr_printf(Barracks_squad_number_coords[gr_screen.res][BARRACKS_X_COORD], Barracks_squad_number_coords[gr_screen.res][BARRACKS_Y_COORD], buf);
1409                         }
1410                 }
1411         } else {
1412                 Pic_squad_number = -1;
1413         }       
1414 }
1415
1416 // -----------------------------------------------------------------------------
1417 void barracks_init()
1418 {
1419 #ifndef MAKE_FS1
1420         UI_WINDOW *w = &Ui_window;
1421 #endif
1422
1423         // save current pilot file, so we don't possibly loose it.
1424         write_pilot_file();
1425
1426         // create interface
1427         Ui_window.create(0, 0, gr_screen.max_w, gr_screen.max_h, 0);
1428         Ui_window.set_mask_bmap(Barracks_bitmap_mask_fname[gr_screen.res]);
1429
1430         // load background bitmap
1431         Background_bitmap = bm_load(Barracks_bitmap_fname[gr_screen.res]);
1432         if(Background_bitmap < 0){
1433                 // we failed to load the bitmap - this is very bad
1434                 Int3();
1435         }
1436
1437         // create buttons
1438         for (int i=0; i<BARRACKS_NUM_BUTTONS; i++) {
1439                 // create the object
1440                 Buttons[gr_screen.res][i].button.create(&Ui_window, "", Buttons[gr_screen.res][i].x, Buttons[gr_screen.res][i].y, 60, 30, Buttons[gr_screen.res][i].repeat, 1);
1441
1442                 // set the sound to play when highlighted
1443                 Buttons[gr_screen.res][i].button.set_highlight_action(common_play_highlight_sound);
1444
1445                 // set the ani for the button
1446                 Buttons[gr_screen.res][i].button.set_bmaps(Buttons[gr_screen.res][i].filename);
1447
1448                 // set the hotspot
1449                 Buttons[gr_screen.res][i].button.link_hotspot(Buttons[gr_screen.res][i].hotspot);
1450         }
1451
1452         // add all strings      
1453 #ifndef MAKE_FS1
1454         w->add_XSTR("Create", 1034, Buttons[gr_screen.res][0].text_x,  Buttons[gr_screen.res][0].text_y, &Buttons[gr_screen.res][0].button, UI_XSTR_COLOR_GREEN);
1455         w->add_XSTR("Accept", 1035, Buttons[gr_screen.res][5].text_x,  Buttons[gr_screen.res][5].text_y, &Buttons[gr_screen.res][5].button, UI_XSTR_COLOR_PINK);
1456         w->add_XSTR("Help",   928, Buttons[gr_screen.res][6].text_x,  Buttons[gr_screen.res][6].text_y, &Buttons[gr_screen.res][6].button, UI_XSTR_COLOR_GREEN);
1457         w->add_XSTR("Options",1036, Buttons[gr_screen.res][7].text_x,  Buttons[gr_screen.res][7].text_y, &Buttons[gr_screen.res][7].button, UI_XSTR_COLOR_GREEN);
1458         w->add_XSTR("Medals", 1037, Buttons[gr_screen.res][8].text_x,  Buttons[gr_screen.res][8].text_y, &Buttons[gr_screen.res][8].button, UI_XSTR_COLOR_GREEN);
1459         w->add_XSTR("Remove", 1038, Buttons[gr_screen.res][11].text_x,  Buttons[gr_screen.res][11].text_y, &Buttons[gr_screen.res][11].button, UI_XSTR_COLOR_GREEN);
1460         w->add_XSTR("Select", 1552, Buttons[gr_screen.res][12].text_x,  Buttons[gr_screen.res][12].text_y, &Buttons[gr_screen.res][12].button, UI_XSTR_COLOR_GREEN);
1461         w->add_XSTR("Clone",  1040, Buttons[gr_screen.res][13].text_x,  Buttons[gr_screen.res][13].text_y, &Buttons[gr_screen.res][13].button, UI_XSTR_COLOR_GREEN);
1462         w->add_XSTR("Single", 1041, Buttons[gr_screen.res][14].text_x,  Buttons[gr_screen.res][14].text_y,  &Buttons[gr_screen.res][14].button, UI_XSTR_COLOR_GREEN);
1463         w->add_XSTR("Multi",  1042, Buttons[gr_screen.res][15].text_x,  Buttons[gr_screen.res][15].text_y,  &Buttons[gr_screen.res][15].button, UI_XSTR_COLOR_GREEN);
1464         w->add_XSTR("Convert",1043, Buttons[gr_screen.res][16].text_x,  Buttons[gr_screen.res][16].text_y, &Buttons[gr_screen.res][16].button, UI_XSTR_COLOR_GREEN);    
1465         for(int i=0; i<BARRACKS_NUM_TEXT; i++) {
1466                 w->add_XSTR(&Barracks_text[gr_screen.res][i]);
1467         }
1468 #endif
1469
1470         // button for selecting pilot
1471         List_region.create(&Ui_window, "", Barracks_list_coords[gr_screen.res][BARRACKS_X_COORD], Barracks_list_coords[gr_screen.res][BARRACKS_Y_COORD], Barracks_list_coords[gr_screen.res][BARRACKS_W_COORD], Barracks_list_coords[gr_screen.res][BARRACKS_H_COORD], 0, 1);
1472         List_region.hide();
1473
1474         // create input box (for new pilot)
1475         Inputbox.create(&Ui_window, Barracks_list_coords[gr_screen.res][BARRACKS_X_COORD], Barracks_list_coords[gr_screen.res][BARRACKS_Y_COORD], Barracks_list_coords[gr_screen.res][BARRACKS_W_COORD], CALLSIGN_LEN - 1, "", UI_INPUTBOX_FLAG_INVIS | UI_INPUTBOX_FLAG_KEYTHRU | UI_INPUTBOX_FLAG_LETTER_FIRST);
1476         Inputbox.set_valid_chars(VALID_PILOT_CHARS);
1477         Inputbox.disable();
1478         Inputbox.hide();
1479
1480         // load in help overlay bitmap  
1481         help_overlay_load(BARRACKS_OVERLAY);
1482         help_overlay_set_state(BARRACKS_OVERLAY,0);     
1483
1484         // other init stuff
1485         Barracks_callsign_enter_mode = 0;       
1486         List_scroll_offset = Stats_scroll_offset = Pic_number = Pic_squad_number = Selected_line = 0;
1487         Cur_pilot = &Players[Player_num];
1488
1489         // disable squad logo selection buttons in single player
1490 #ifndef MAKE_FS1
1491         if(!(Cur_pilot->flags & PLAYER_FLAGS_IS_MULTI)){
1492                 // squad logo picture buttons           
1493                 Buttons[gr_screen.res][B_SQUAD_PREV_BUTTON].button.hide();
1494                 Buttons[gr_screen.res][B_SQUAD_PREV_BUTTON].button.disable();
1495                 Buttons[gr_screen.res][B_SQUAD_NEXT_BUTTON].button.hide();
1496                 Buttons[gr_screen.res][B_SQUAD_NEXT_BUTTON].button.disable();
1497         } else {
1498                 // squad logo picture buttons           
1499                 Buttons[gr_screen.res][B_SQUAD_PREV_BUTTON].button.enable();
1500                 Buttons[gr_screen.res][B_SQUAD_PREV_BUTTON].button.unhide();
1501                 Buttons[gr_screen.res][B_SQUAD_NEXT_BUTTON].button.enable();
1502                 Buttons[gr_screen.res][B_SQUAD_NEXT_BUTTON].button.unhide();            
1503         }
1504 #endif
1505
1506         // set up hotkeys for buttons so we draw the correct animation frame when a key is pressed
1507         barracks_set_hotkeys(1);
1508
1509         // load ramp pips
1510 #ifndef FS1_DEMO
1511         Rank_pips_bitmaps = bm_load_animation("IconRankMini.ani", &Rank_pips_count);    
1512 #endif
1513
1514         // load up the pilot pic list
1515         pilot_load_pic_list();  
1516         pilot_load_squad_pic_list();
1517         
1518         // don't load pilot images yet
1519         for (int i=0; i<MAX_PILOT_IMAGES; i++) {
1520                 Pilot_images[i] = BARRACKS_IMAGE_NOT_LOADED;  // while -1 is can't load
1521                 Pilot_squad_images[i] = BARRACKS_IMAGE_NOT_LOADED;
1522         }
1523         
1524         // init stats
1525         barracks_init_stats(&Cur_pilot->stats);
1526
1527         // disable some buttons for the multiplayer beta and e3 build
1528 #if defined(MULTIPLAYER_BETA_BUILD) || defined(E3_BUILD) || defined(PRESS_TOUR_BUILD)
1529         Buttons[gr_screen.res][B_PILOT_CLONE_BUTTON].button.hide();
1530         Buttons[gr_screen.res][B_PILOT_CONVERT_BUTTON].button.hide();   
1531         Buttons[gr_screen.res][B_PILOT_CLONE_BUTTON].button.disable();  
1532         Buttons[gr_screen.res][B_PILOT_CONVERT_BUTTON].button.disable();        
1533 #endif
1534
1535         // multiplayer beta build
1536 #ifdef MULTIPLAYER_BETA_BUILD
1537         Buttons[gr_screen.res][B_PILOT_SINGLE_MODE_BUTTON].button.hide();
1538         Buttons[gr_screen.res][B_PILOT_SINGLE_MODE_BUTTON].button.disable();
1539 #endif
1540
1541         // e3 build
1542 #if defined(E3_BUILD) || defined(PRESS_TOUR_BUILD)
1543         Buttons[gr_screen.res][B_PILOT_MULTI_MODE_BUTTON].button.hide();
1544         Buttons[gr_screen.res][B_PILOT_MULTI_MODE_BUTTON].button.disable();
1545 #endif
1546
1547         // base the mode we're in (single or multi) on the status of the currently selected pilot
1548 #ifdef MULTIPLAYER_BETA_BUILD
1549         barracks_init_player_stuff(1);
1550 #elif defined(E3_BUILD) || defined(PRESS_TOUR_BUILD)
1551         barracks_init_player_stuff(0);
1552 #else
1553         barracks_init_player_stuff(is_pilot_multi(Player));     
1554 #endif
1555
1556 #if defined(MAKE_FS1) && !defined(FS1_DEMO)
1557         PilotWin01 = bm_load(NOX("PilotWin01"));
1558         PilotWin02 = bm_load(NOX("PilotWin02"));
1559         PilotWin03 = bm_load(NOX("PilotWin03"));
1560         PilotWin04 = bm_load(NOX("PilotWin04"));
1561 #endif
1562 }
1563
1564 // -----------------------------------------------------------------------------
1565 void barracks_do_frame(float frametime)
1566 {
1567         int k = Ui_window.process();
1568
1569         if ( k > 0 ) {
1570                 if ( help_overlay_active(BARRACKS_OVERLAY) ) {
1571                         help_overlay_set_state(BARRACKS_OVERLAY,0);
1572                         k = 0;
1573                 }
1574         }
1575
1576         // pilot that mouse is over
1577         int prospective_pilot = -1;
1578         int i;
1579
1580         // Entering pilot callsign
1581         if (Barracks_callsign_enter_mode) {
1582                 // set focus to inputbox
1583                 Inputbox.set_focus();
1584
1585                 switch (k) {
1586                         case KEY_ESC:
1587                                 // cancel create pilot
1588                                 Num_pilots--;
1589                                 for (i=0; i<Num_pilots; i++) {
1590                                         strcpy(Pilots[i], Pilots[i + 1]);
1591                                         Pilot_ranks[i] = Pilot_ranks[i + 1];
1592                                 }
1593
1594                                 barracks_set_callsign_enter_mode(false);
1595                                 break;
1596
1597                         case KEY_ENTER: 
1598                                 barracks_accept_new_pilot_callsign();
1599                                 break;
1600                 } 
1601         } else {
1602                 // not entering pilot callsign
1603                 switch (k) {
1604                         case KEY_ENTER:
1605                                 if (barracks_new_pilot_selected()) {
1606                                         gamesnd_play_iface(SND_GENERAL_FAIL);
1607                                 } else {
1608                                         gamesnd_play_iface(SND_USER_SELECT);
1609                                 }
1610                                 break;
1611
1612                         case KEY_ESC:  // cancel
1613                                 if (!help_overlay_active(BARRACKS_OVERLAY)) {
1614                                         if (Num_pilots && !barracks_pilot_accepted()) {
1615                                                 gameseq_post_event(GS_EVENT_MAIN_MENU);
1616                                         } else {
1617                                                 gamesnd_play_iface(SND_GENERAL_FAIL);
1618                                         }
1619                                 } else {
1620                                         // kill the overlay
1621                                         help_overlay_set_state(BARRACKS_OVERLAY,0);
1622                                 }
1623                                 break;
1624
1625                         case KEY_TAB:  // switch mode (simgle/multi)
1626 #if defined(DEMO) || defined(OEM_BUILD) // not for FS2_DEMO
1627         game_feature_not_in_demo_popup();
1628 #else
1629                                 if (Player_sel_mode == PLAYER_SELECT_MODE_SINGLE) {
1630                                         barracks_init_player_stuff(PLAYER_SELECT_MODE_MULTI);
1631                                 } else {
1632                                         barracks_init_player_stuff(PLAYER_SELECT_MODE_SINGLE);
1633                                 }
1634
1635                                 gamesnd_play_iface(SND_USER_SELECT);
1636 #endif
1637                                 break;
1638
1639                         case KEY_F1:  // show help overlay
1640                                 gamesnd_play_iface(SND_HELP_PRESSED);
1641                                 break;
1642
1643                         case KEY_F2:  // goto options screen
1644                                 gamesnd_play_iface(SND_SWITCH_SCREENS);
1645                                 gameseq_post_event(GS_EVENT_OPTIONS_MENU);
1646                                 break;
1647                 }       // end switch
1648
1649                 // process buttons
1650                 for (i=0; i<BARRACKS_NUM_BUTTONS; i++) {
1651                         if (Buttons[gr_screen.res][i].button.pressed()) {
1652                                 barracks_button_pressed(i);
1653                         }
1654                 }
1655
1656                 // if mouse is over a pilot, find index into Pilots array
1657                 if (List_region.is_mouse_on()) {
1658                         int y;
1659                         List_region.get_mouse_pos(NULL, &y);
1660                         int pilot_index = List_scroll_offset + (y / gr_get_font_height());
1661                         if ((pilot_index >= 0) && (pilot_index < Num_pilots)) {
1662                                 prospective_pilot = pilot_index;
1663                         }
1664                 }
1665                 
1666                 // if mouse clicked in list region, find index into Pilots array 
1667                 if (List_region.pressed()) {
1668                         if (prospective_pilot != -1) {
1669                                 Selected_line = prospective_pilot;
1670                                 gamesnd_play_iface(SND_USER_SELECT);
1671                         }
1672                 }
1673         }
1674
1675         // check mouse over help
1676         if (mouse_down(MOUSE_LEFT_BUTTON)) {
1677                 help_overlay_set_state(BARRACKS_OVERLAY, 0);
1678         }
1679
1680         // do pilot pic stuff
1681         if ((Pic_number >= 0) && (Pic_number < Num_pilot_images)) {
1682                 if (Pilot_images[Pic_number] == BARRACKS_IMAGE_NOT_LOADED) {  // haven't tried loading it yet
1683                         Pilot_images[Pic_number] = bm_load(Pilot_image_names[Pic_number]);
1684                         if (Pilot_images[Pic_number] >= 0) {
1685                                 int w, h;
1686
1687                                 bm_get_info(Pilot_images[Pic_number], &w, &h, NULL);
1688                                 // check for invalid pilot pic file
1689                                 if ((w != PLAYER_PILOT_PIC_W) || (h != PLAYER_PILOT_PIC_H)) {
1690                                         bm_unload(Pilot_images[Pic_number]);
1691                                         Pilot_images[Pic_number] = -1;
1692                                 }
1693                         }
1694                 }               
1695         } else {
1696                 Pic_number = -1;
1697         }
1698
1699         // do squad pic stuff
1700         if ((Pic_squad_number >= 0) && (Pic_squad_number < Num_pilot_squad_images)) {
1701                 if (Pilot_squad_images[Pic_squad_number] == BARRACKS_IMAGE_NOT_LOADED) {  // haven't tried loading it yet
1702                         Pilot_squad_images[Pic_squad_number] = bm_load_duplicate(Pilot_squad_image_names[Pic_squad_number]);
1703                         if (Pilot_squad_images[Pic_squad_number] >= 0) {
1704                                 int w, h;
1705
1706                                 bm_get_info(Pilot_squad_images[Pic_squad_number], &w, &h, NULL);
1707                                 // check for invalid pilot pic file
1708                                 if ((w != PLAYER_SQUAD_PIC_W) || (h != PLAYER_SQUAD_PIC_H)) {
1709                                         bm_unload(Pilot_squad_images[Pic_squad_number]);
1710                                         Pilot_squad_images[Pic_squad_number] = -1;
1711                                 }
1712                         }
1713                 }
1714         } else {
1715                 Pic_squad_number = -1;
1716         }
1717
1718         // draw the background, etc
1719         gr_reset_clip();        
1720         GR_MAYBE_CLEAR_RES(Background_bitmap);
1721         if (Background_bitmap >= 0) {
1722                 gr_set_bitmap(Background_bitmap);
1723                 gr_bitmap(0, 0);        
1724         }               
1725
1726         // draw pilot image and clean up afterwards
1727         barracks_draw_pilot_pic();
1728         barracks_draw_squad_pic();
1729
1730 #if defined(MAKE_FS1) && !defined(FS1_DEMO)
1731         if (PilotWin01 != -1) {
1732                 gr_set_bitmap(PilotWin01);
1733                 gr_bitmap(447, 18);
1734         }
1735
1736         if (PilotWin02 != -1) {
1737                 gr_set_bitmap(PilotWin02);
1738                 gr_bitmap(620, 38);
1739         }
1740
1741         if (PilotWin03 != -1) {
1742                 gr_set_bitmap(PilotWin03);
1743                 gr_bitmap(447, 137);
1744         }
1745
1746         if (PilotWin04 != -1) {
1747                 gr_set_bitmap(PilotWin04);
1748                 gr_bitmap(447, 36);
1749         }
1750 #endif
1751
1752
1753         // draw the window      
1754         Ui_window.draw();       
1755
1756         // light up the correct mode button (single or multi)   
1757         if (Player_sel_mode == PLAYER_SELECT_MODE_SINGLE) {
1758                 Buttons[gr_screen.res][B_PILOT_SINGLE_MODE_BUTTON].button.draw_forced(2);
1759         } else {
1760                 Buttons[gr_screen.res][B_PILOT_MULTI_MODE_BUTTON].button.draw_forced(2);
1761         }       
1762
1763         // write out pilot call signs
1764         barracks_display_pilot_callsigns(prospective_pilot);
1765
1766         // write out current pilot stats
1767         barracks_display_pilot_stats();
1768
1769         // blit help overlay if active
1770         help_overlay_maybe_blit(BARRACKS_OVERLAY);      
1771         
1772         // flip the page
1773         gr_flip();
1774 }
1775
1776 // -----------------------------------------------------------------------------
1777 void barracks_close()
1778 {
1779 #if defined(MAKE_FS1) && !defined(FS1_DEMO)
1780     if (PilotWin01 != -1){
1781         bm_unload(PilotWin01);
1782         PilotWin01 = -1;
1783     }
1784     if (PilotWin02 != -1){
1785         bm_unload(PilotWin02);
1786         PilotWin02 = -1;
1787     }
1788     if (PilotWin03 != -1){
1789         bm_unload(PilotWin03);
1790         PilotWin03 = -1;
1791     }
1792     if (PilotWin04 != -1){
1793         bm_unload(PilotWin04);
1794         PilotWin04 = -1;
1795     }
1796 #endif
1797
1798         // destroy window
1799         Ui_window.destroy();
1800
1801         // release background bitmap
1802         if (Background_bitmap >= 0) {
1803                 bm_unload(Background_bitmap);
1804         }       
1805
1806         // release rank pip bitmaps
1807         for (int i=0; i<Rank_pips_count; i++) {
1808                 bm_release(Rank_pips_bitmaps + i);
1809         }       
1810
1811         // release pilot pic bitmaps
1812         for (int i=0; i<Num_pilot_images; i++) {
1813                 if (Pilot_images[i] >= 0) {
1814                         bm_unload(Pilot_images[i]);
1815                 }
1816         }
1817
1818         // unload the overlay bitmap
1819         help_overlay_unload(BARRACKS_OVERLAY);
1820
1821         game_flush();
1822 }
1823