]> icculus.org git repositories - taylor/freespace2.git/blob - src/missionui/missionbrief.cpp
Initial revision
[taylor/freespace2.git] / src / missionui / missionbrief.cpp
1 /*
2  * $Logfile: /Freespace2/code/MissionUI/MissionBrief.cpp $
3  * $Revision$
4  * $Date$
5  * $Author$
6  *
7  * C module that contains code to display the mission briefing to the player
8  *
9  * $Log$
10  * Revision 1.1  2002/05/03 03:28:10  root
11  * Initial revision
12  *
13  * 
14  * 48    10/14/99 2:51p Jefff
15  * localiztion fixes
16  * 
17  * 47    10/13/99 3:23p Jefff
18  * fixed unnumbered XSTRs
19  * 
20  * 46    9/12/99 8:09p Dave
21  * Fixed problem where skip-training button would cause mission messages
22  * not to get paged out for the current mission.
23  * 
24  * 45    9/09/99 3:40p Jefff
25  * no exit loop outisde of campaign mode
26  * 
27  * 44    9/07/99 6:53p Jefff
28  * functionality to break out of a loop
29  * 
30  * 43    9/06/99 6:38p Dave
31  * Improved CD detection code.
32  * 
33  * 42    9/03/99 10:57a Jefff
34  * numbered an xstr
35  * 
36  * 41    8/30/99 5:30p Jefff
37  * fixed "more" being cut off in d3d
38  * 
39  * 40    8/30/99 10:29a Jefff
40  * added autocenter flag to closup rendering
41  * 
42  * 39    8/19/99 11:33a Dave
43  * Fixed debug build.
44  * 
45  * 38    8/19/99 10:59a Dave
46  * Packet loss detection.
47  * 
48  * 37    8/16/99 4:05p Dave
49  * Big honking checkin.
50  * 
51  * 36    8/16/99 9:48a Jefff
52  * all clicks on briefing icons should now register
53  * 
54  * 35    8/10/99 7:29p Jefff
55  * added mission title to briefing screen
56  * 
57  * 34    8/03/99 1:34a Andsager
58  * fix skip training mission (again)
59  * 
60  * 33    8/02/99 12:01p Jefff
61  * fixed "skip training" text pos
62  * 
63  * 32    7/30/99 5:42p Jasenw
64  * Fixed coords for skip training button.
65  * 
66  * 31    7/29/99 10:50p Dave
67  * Oops. Accidentally blew away some interface text changes.
68  * 
69  * 30    7/29/99 10:48p Dave
70  * 
71  * 29    7/29/99 3:05p Andsager
72  * Add skip training text. and properly skip.
73  * 
74  * 28    7/24/99 6:07p Jefff
75  * Added "lock" text to multiplayer lock button
76  * 
77  * 27    7/21/99 10:51a Jefff
78  * added "more" indicator to briefing text box
79  * 
80  * 26    7/19/99 3:01p Dave
81  * Fixed icons. Added single transport icon.
82  * 
83  * 25    7/18/99 5:20p Dave
84  * Jump node icon. Fixed debris fogging. Framerate warning stuff.
85  * 
86  * 24    7/16/99 1:49p Dave
87  * 8 bit aabitmaps. yay.
88  * 
89  * 23    7/15/99 9:20a Andsager
90  * FS2_DEMO initial checkin
91  * 
92  * 22    7/09/99 5:54p Dave
93  * Seperated cruiser types into individual types. Added tons of new
94  * briefing icons. Campaign screen.
95  * 
96  * 21    6/29/99 7:39p Dave
97  * Lots of small bug fixes.
98  * 
99  * 20    6/11/99 11:13a Dave
100  * last minute changes before press tour build.
101  * 
102  * 19    6/04/99 1:18p Dave
103  * Fixed briefing model rendering problems. Made show background option in
104  * fred toggle nebula rendering.
105  * 
106  * 18    5/07/99 10:34a Andsager
107  * Make red alert work in FS2
108  * 
109  * 17    4/23/99 12:01p Johnson
110  * Added SIF_HUGE_SHIP
111  * 
112  * 16    3/25/99 2:45p Neilk
113  * Fixed lock button
114  * 
115  * 15    2/11/99 3:08p Dave
116  * PXO refresh button. Very preliminary squad war support.
117  * 
118  * 14    2/05/99 7:19p Neilk
119  * Removed black part from mission screen, fixed info text coords
120  * 
121  * 13    2/02/99 4:35p Neilk
122  * fixed coordinate problem where primary goals was on top of interface in
123  * mission briefing
124  * 
125  * 12    2/01/99 5:55p Dave
126  * Removed the idea of explicit bitmaps for buttons. Fixed text
127  * highlighting for disabled gadgets.
128  * 
129  * 11    1/30/99 7:32p Neilk
130  * Fixed coords problems for mission briefing screens
131  * 
132  * 10    1/30/99 5:08p Dave
133  * More new hi-res stuff.Support for nice D3D textures.
134  * 
135  * 9     1/30/99 1:29a Dave
136  * Fixed nebula thumbnail problem. Full support for 1024x768 choose pilot
137  * screen.  Fixed beam weapon death messages.
138  * 
139  * 8     1/29/99 4:17p Dave
140  * New interface screens.
141  * 
142  * 7     1/13/99 7:19p Neilk
143  * Converted Mission Brief, Barracks, Synch to high res support
144  * 
145  * 6     12/18/98 1:13a Dave
146  * Rough 1024x768 support for Direct3D. Proper detection and usage through
147  * the launcher.
148  * 
149  * 5     11/30/98 1:07p Dave
150  * 16 bit conversion, first run.
151  * 
152  * 4     11/20/98 4:08p Dave
153  * Fixed flak effect in multiplayer.
154  * 
155  * 3     10/13/98 9:28a Dave
156  * Started neatening up freespace.h. Many variables renamed and
157  * reorganized. Added AlphaColors.[h,cpp]
158  * 
159  * 2     10/07/98 10:53a Dave
160  * Initial checkin.
161  * 
162  * 1     10/07/98 10:49a Dave
163  * 
164  * 114   9/17/98 3:08p Dave
165  * PXO to non-pxo game warning popup. Player icon stuff in create and join
166  * game screens. Upped server count refresh time in PXO to 35 secs (from
167  * 20).
168  * 
169  * 113   6/19/98 3:52p Lawrance
170  * Don't use large text in popup, since it is missing large foreign chars
171  * 
172  * 112   6/09/98 5:17p Lawrance
173  * French/German localization
174  * 
175  * 111   6/09/98 10:31a Hoffoss
176  * Created index numbers for all xstr() references.  Any new xstr() stuff
177  * added from here on out should be added to the end if the list.  The
178  * current list count can be found in FreeSpace.cpp (search for
179  * XSTR_SIZE).
180  * 
181  * 110   6/01/98 11:43a John
182  * JAS & MK:  Classified all strings for localization.
183  * 
184  * 109   5/22/98 10:44a Lawrance
185  * put in case label to suppress warning
186  * 
187  * 108   5/19/98 11:35p Lawrance
188  * Play sound for briefing control button presses
189  * 
190  * 107   5/19/98 8:47p Lawrance
191  * Set proper distance for jump nodes
192  * 
193  * 106   5/19/98 8:35p Dave
194  * Revamp PXO channel listing system. Send campaign goals/events to
195  * clients for evaluation. Made lock button pressable on all screens. 
196  * 
197  * 105   5/12/98 2:16p Hoffoss
198  * Added debug code to switch models of closeup icon to more easily check
199  * positions and zooms.
200  * 
201  * 104   5/06/98 11:50p Lawrance
202  * Clean up help overlay code for loadout screens
203  * 
204  * 103   5/06/98 8:03p Allender
205  * AL: only free pointers in brief_compact_stages if non-null
206  * 
207  * 102   5/05/98 4:48p Lawrance
208  * Fix bug with launching closeup icon when pause button is pressed
209  * 
210  * 101   4/29/98 1:45p Lawrance
211  * Print out mission filename if debug build, or if INTERPLAY QA defined
212  * 
213  * 100   4/29/98 12:15a Lawrance
214  * reset demo trailer timer when briefing moves to a new stage
215  * 
216  * 98    4/25/98 11:55p Lawrance
217  * fix bug with the auto-advance button
218  * 
219  * 97    4/25/98 3:49p Lawrance
220  * Save briefing auto-advance pref
221  * 
222  * 96    4/25/98 12:00p Lawrance
223  * disable advance keypress for 1/2 second after autoadvance
224  * 
225  * 95    4/22/98 7:24p Dave
226  * Made sure the "player/ships" locked button for multiplayer appears on
227  * all briefing screens.
228  * 
229  * 94    4/20/98 3:53p Lawrance
230  * Fix various bugs with auto-advancing through briefings.
231  * 
232  * 93    4/19/98 12:11p Lawrance
233  * add new art for pause button in the briefing
234  * 
235  * 92    4/17/98 10:39p Andsager
236  * AL: Fix bug with auto-advance of briefing stages.
237  * 
238  * 91    4/16/98 8:05p Lawrance
239  * Don't show closeup icon for planets
240  * 
241  * 90    4/15/98 5:17p Lawrance
242  * fix bug with skip training 
243  *
244  * $NoKeywords: $
245  *
246 */
247
248 #include "freespace.h"
249 #include "missionload.h"
250 #include "missionscreencommon.h"
251 #include "missionshipchoice.h"
252 #include "missionparse.h"
253 #include "missiongoals.h"
254 #include "gamesequence.h"
255 #include "ship.h"
256 #include "key.h"
257 #include "2d.h"
258 #include "line.h"
259 #include "3d.h"
260 #include "model.h"
261 #include "timer.h"
262 #include "math.h"
263 #include "linklist.h"
264 #include "mouse.h"
265 #include "hud.h"
266 #include "ui.h"
267 #include "osapi.h"
268 #include "audiostr.h"
269 #include "gamesnd.h"
270 #include "eventmusic.h"
271 #include "missioncampaign.h"
272 #include "object.h"
273 #include "multi.h"
274 #include "snazzyui.h"
275 #include "bmpman.h"
276 #include "missionbrief.h"
277 #include "missionbriefcommon.h"
278 #include "missiongrid.h"
279 #include "bmpman.h"
280 #include "multimsgs.h"
281 #include "cmdline.h"
282 #include "contexthelp.h"
283 #include "chatbox.h"
284 #include "multiteamselect.h"
285 #include "multiui.h"
286 #include "asteroid.h"
287 #include "popup.h"
288 #include "sexp.h"
289 #include "alphacolors.h"
290 #include "font.h"
291 #include "missionmessage.h"
292
293 /*
294 #define OBJECTIVES_X    65
295 #define OBJECTIVES_Y    137
296 #define OBJECTIVES_W    508
297 #define OBJECTIVES_H    233
298 */
299
300 static int Brief_goals_coords[GR_NUM_RESOLUTIONS][4] = {
301         {
302                 65,152,508,211          // GR_640
303         },
304         {
305                 104,243,813,332         // GR_1024
306         }
307 };
308
309 static int      Current_brief_stage;    // what stage of the briefing we're on
310 static int      Last_brief_stage;
311 static int      Num_brief_stages;
312 static int      Brief_multiplayer = FALSE;
313
314 static int      Brief_last_auto_advance = 0;    // timestamp of last auto-advance
315
316 // for managing the scene cut transition
317 static int      Quick_transition_stage;
318 static int      Start_fade_up_anim, Start_fade_down_anim;
319 static int      Brief_playing_fade_sound;
320 hud_anim                Fade_anim;
321
322 int     Briefing_music_handle = -1;
323 int     Briefing_music_begin_timestamp = 0;
324
325 // --------------------------------------------------------------------------------------
326 // Module scope globals
327 // --------------------------------------------------------------------------------------
328
329 static MENU_REGION      Briefing_select_region[NUM_BREIFING_REGIONS];
330 static int                              Num_briefing_regions;
331
332 // For closeup display 
333 #define                                 ONE_REV_TIME            6               // time (sec) for one revolution
334 #define                                 MAX_ANG_CHG                     0.15f
335
336 static int Closeup_coords[GR_NUM_RESOLUTIONS][4] = {
337         {
338                 203, 151, 200, 213      // GR_640
339         },
340         {
341                 325, 241, 200, 213      // GR_1024
342         }
343 };
344
345 static int Closeup_img_h[GR_NUM_RESOLUTIONS] = {
346         {
347                 150     // GR_640
348         },
349         {
350                 150     // GR_1024
351         }
352 };
353
354 static int Closeup_text_h[GR_NUM_RESOLUTIONS][4] = {
355         {
356                 63              // GR_640
357         },
358         {
359                 63              // GR_1024
360         }
361 };
362
363 static int Brief_infobox_coords[GR_NUM_RESOLUTIONS][2] = {
364         { // GR_640
365                 0, 391
366         },
367         { // GR_1024
368                 0, 627
369         }
370 };
371
372 static char *Brief_infobox_filename[GR_NUM_RESOLUTIONS] = {
373         "InfoBox",
374         "2_Infobox"
375 };
376
377 static char *Brief_filename[GR_NUM_RESOLUTIONS] = {
378         "Brief",
379         "2_Brief"
380 };
381
382 static char *Brief_multi_filename[GR_NUM_RESOLUTIONS] = {
383         "BriefMulti",
384         "2_BriefMulti"
385 };
386
387 static char *Brief_mask_filename[GR_NUM_RESOLUTIONS] = {
388         "Brief-m",
389         "2_Brief-m"
390 };
391
392 static char *Brief_multi_mask_filename[GR_NUM_RESOLUTIONS] = {
393         "BriefMulti-m",
394         "2_BriefMulti-m"
395 };
396
397
398 static char *Brief_win_filename[GR_NUM_RESOLUTIONS] = {
399         "Briefwin",
400         "2_Briefwin"
401 };
402
403 // coordinate inidices
404 #define BRIEF_X_COORD 0
405 #define BRIEF_Y_COORD 1
406 #define BRIEF_W_COORD 2
407 #define BRIEF_H_COORD 3
408
409 //static int Closeup_region[4] = {220,132,420,269};
410 int Closeup_region[GR_NUM_RESOLUTIONS][4] = {
411         { // GR_640
412                 211, 158, 215, 157
413         }, 
414         { // GR_1024
415                 337, 253, 345, 252
416         }, 
417 };
418
419 char *Closeup_background_filename[GR_NUM_RESOLUTIONS] = {
420         NOX("BriefPop"),        // GR_640
421         NOX("2_BriefPop")       // GR_1024
422 };
423
424 char *Closeup_button_filename[GR_NUM_RESOLUTIONS] = {
425         NOX("BPB_00"),          // GR_640
426         NOX("2_BPB_00"),                // GR_1024
427 };
428
429 int Closeup_button_hotspot = 14;
430
431 //static int                    Closeup_button_coords[2] = {CLOSEUP_X+164,CLOSEUP_Y+227};
432 int Closeup_button_coords[GR_NUM_RESOLUTIONS][2] = {    
433         { 374, 316 },           // GR_640       
434         { 599, 506 }            // GR_1024      
435 };
436
437 UI_BUTTON       Closeup_close_button;
438 int Closeup_bitmap=-1;
439 int Closeup_one_revolution_time=ONE_REV_TIME;
440
441 brief_icon *Closeup_icon;
442 angles Closeup_angles;
443 matrix Closeup_orient;
444 vector Closeup_pos;
445 int Closeup_font_height;
446 int Closeup_x1, Closeup_y1;
447
448 // used for the 3d view of a closeup ship
449 float Closeup_zoom;
450 vector Closeup_cam_pos;
451
452 // Mask bitmap pointer and Mask bitmap_id
453 bitmap* BriefingMaskPtr;                // bitmap pointer to the briefing select mask bitmap
454 ubyte* BriefingMaskData;                // pointer to actual bitmap data
455 int Briefing_mask_w, Briefing_mask_h;
456 int BriefingMaskBitmap; // bitmap id of the briefing mask bitmap
457 int Brief_inited = FALSE;
458
459 // --------------------------------------------------------------------------------------
460 // Briefing specific UI
461 // --------------------------------------------------------------------------------------
462 #define BRIEF_LAST_STAGE_MASK                   7
463 #define BRIEF_NEXT_STAGE_MASK                   8
464 #define BRIEF_PREV_STAGE_MASK                   9
465 #define BRIEF_FIRST_STAGE_MASK                  10
466 #define BRIEF_TEXT_SCROLL_UP_MASK               11
467 #define BRIEF_TEXT_SCROLL_DOWN_MASK     12
468 #define BRIEF_SKIP_TRAINING_MASK                15
469 #define BRIEF_PAUSE_MASK                                        16
470
471 //XSTR:OFF
472 static char *Brief_mask_single[GR_NUM_RESOLUTIONS] = {
473         "brief-m",              // GR_640
474         "2_brief-m"             // GR_1024
475 };
476
477 static char *Brief_mask_multi[GR_NUM_RESOLUTIONS] = {
478         "briefmulti-m",         // GR_640
479         "2_briefmulti-m"                        // GR_1024
480 };
481 //XSTR:ON
482
483 struct brief_buttons {  
484         char *filename;
485         int x, y;
486         int xt, yt;
487         int hotspot;
488         int repeat;
489         UI_BUTTON button;  // because we have a class inside this struct, we need the constructor below..
490
491         brief_buttons(char *name, int x1, int y1, int xt1, int yt1, int h, int r = 0) : filename(name), x(x1), y(y1), xt(xt1), yt(yt1), hotspot(h), repeat(r) {}
492 };
493
494 int     Brief_grid_bitmap = -1;
495 int     Brief_text_bitmap = -1;
496
497 int     Brief_multitext_bitmap = -1;
498 int     Brief_background_bitmap =-1;
499
500 UI_WINDOW Brief_ui_window;
501
502 // Briefing specific buttons
503 #define NUM_BRIEF_BUTTONS 10
504
505 brief_buttons   Brief_buttons[GR_NUM_RESOLUTIONS][NUM_BRIEF_BUTTONS] = {
506         { // GR_640
507                 brief_buttons("BRB_08",         110,    116,    117,    157,    8),
508                 brief_buttons("BRB_09",         84,     116,    117,    157,    9),
509                 brief_buttons("BRB_10",         29,     116,    117,    157,    10),
510                 brief_buttons("BRB_11",         4,              116,    117,    157,    11),
511                 brief_buttons("BRB_12",         0,              405,    117,    157,    12),
512                 brief_buttons("BRB_13",         0,              447,    117,    157,    13),                    
513                 brief_buttons("BRB_15",         562,    0,              117,    157,    15),                    // skip training
514                 brief_buttons("BRB_16",         56,     116,    117,    157,    16),
515                 brief_buttons("TSB_34",         603,    374,    117,    157,    34),    
516                 brief_buttons("BRB_15",         562,    0,              117,    157,    15)                     // exit loop    
517         }, 
518         { // GR_1024
519                 brief_buttons("2_BRB_08",               175,    187,    117,    157,    8),
520                 brief_buttons("2_BRB_09",               135,    187,    117,    157,    9),
521                 brief_buttons("2_BRB_10",               47,     187,    117,    157,    10),
522                 brief_buttons("2_BRB_11",               8,              187,    117,    157,    11),
523                 brief_buttons("2_BRB_12",               0,              649,    117,    157,    12),
524                 brief_buttons("2_BRB_13",               0,              716,    117,    157,    13),                    
525                 brief_buttons("2_BRB_15",               900,    0,              117,    157,    15),            // skip training
526                 brief_buttons("2_BRB_16",               91,     187,    117,    157,    16),
527                 brief_buttons("2_TSB_34",               966,    599,    117,    157,    34),                    
528                 brief_buttons("2_BRB_15",               900,    0,              117,    157,    15)                     // exit loop    
529         },      
530 };
531
532 // briefing UI
533 #define BRIEF_SELECT_NUM_TEXT                   3
534 UI_XSTR Brief_select_text[GR_NUM_RESOLUTIONS][BRIEF_SELECT_NUM_TEXT] = {
535         { // GR_640
536                 { "Lock",                               1270,   602,    364,    UI_XSTR_COLOR_GREEN, -1, &Brief_buttons[0][BRIEF_BUTTON_MULTI_LOCK].button },
537                 { "Skip Training",      1442,   467,    7,              UI_XSTR_COLOR_GREEN, -1, &Brief_buttons[0][BRIEF_BUTTON_SKIP_TRAINING].button },
538                 { "Exit Loop",                  1477,   490,    7,              UI_XSTR_COLOR_GREEN, -1, &Brief_buttons[0][BRIEF_BUTTON_EXIT_LOOP].button }
539         }, 
540         { // GR_1024
541                 { "Lock",                               1270,   964,    584,    UI_XSTR_COLOR_GREEN, -1, &Brief_buttons[1][BRIEF_BUTTON_MULTI_LOCK].button },
542                 { "Skip Training",      1442,   805,    12,     UI_XSTR_COLOR_GREEN, -1, &Brief_buttons[1][BRIEF_BUTTON_SKIP_TRAINING].button },
543                 { "Exit Loop",                  1477,   830,    12,     UI_XSTR_COLOR_GREEN, -1, &Brief_buttons[1][BRIEF_BUTTON_EXIT_LOOP].button }
544         }
545 };
546
547 // coordinates for briefing title -- the x value is for the RIGHT side of the text
548 static int Title_coords[GR_NUM_RESOLUTIONS][2] = {
549         {575, 117},             // GR_640
550         {918, 194}              // GR_1024
551 };
552
553 // coordinates for briefing title in multiplayer briefings -- the x value is for the LEFT side of the text
554 // third coord is max width of area for it to fit into (it is force fit there)
555 static int Title_coords_multi[GR_NUM_RESOLUTIONS][3] = {
556         {1, 105, 190},          // GR_640
557         {1, 174, 304}           // GR_1024
558 };
559
560 // briefing line widths
561 int Brief_max_line_width[GR_NUM_RESOLUTIONS] = {
562         MAX_BRIEF_LINE_W_640, MAX_BRIEF_LINE_W_1024
563 };
564
565 // --------------------------------------------------------------------------------------
566 // Forward declarations
567 // --------------------------------------------------------------------------------------
568 int brief_setup_closeup(brief_icon *bi);
569 void brief_maybe_blit_scene_cut(float frametime);
570 void brief_transition_reset();
571
572 char *brief_tooltip_handler(char *str)
573 {
574         if (!stricmp(str, NOX("@close"))) {
575                 if (Closeup_icon)
576                         return XSTR( "Close", 428);
577         }
578
579         return NULL;
580 }
581
582 // brief_skip_training_pressed()
583 //
584 // called when the skip training button on the briefing screen is hit.  When this happens,
585 // do a popup, then move to the next mission in the campaign.
586 void brief_skip_training_pressed()
587 {
588         int val;
589
590         val = popup(PF_USE_NEGATIVE_ICON | PF_USE_AFFIRMATIVE_ICON,2,POPUP_NO,POPUP_YES,XSTR( "Skip Training\n\n\n\nAre you sure you want to skip this training mission?", 429));
591
592         // val is 0 when we hit no (first on the list)
593         // AL: also, -1 is returned when ESC is hit
594         if ( val <= 0 ){
595                 return;
596         }
597
598         // page out mission messages
599         message_mission_shutdown();
600
601         if ( !(Game_mode & GM_CAMPAIGN_MODE) ){
602                 gameseq_post_event( GS_EVENT_MAIN_MENU );
603         }
604
605         // tricky part.  Need to move to the next mission in the campaign.
606         mission_goal_mark_objectives_complete();
607         mission_goal_fail_incomplete();
608         mission_campaign_store_goals_and_events();
609
610         mission_campaign_eval_next_mission();
611         mission_campaign_mission_over();        
612
613         // CD CHECK
614         if(game_do_cd_mission_check(Game_current_mission_filename)){
615                 gameseq_post_event( GS_EVENT_START_GAME );
616         } else {
617                 gameseq_post_event( GS_EVENT_MAIN_MENU );
618         }
619 }
620
621 #ifdef FS2_DEMO
622         extern void demo_reset_trailer_timer();
623 #endif
624 // --------------------------------------------------------------------------------------
625 //      brief_do_next_pressed()
626 //
627 //
628 void brief_do_next_pressed(int play_sound)
629 {
630         int now;
631         now = timer_get_milliseconds();
632
633         if ( (now - Brief_last_auto_advance) < 500 ) {
634                 return;
635         }
636
637 #ifdef FS2_DEMO
638         demo_reset_trailer_timer();
639 #endif
640
641         Current_brief_stage++;
642         if ( Current_brief_stage >= Num_brief_stages ) {
643                 Current_brief_stage = Num_brief_stages - 1;
644                 gamesnd_play_iface(SND_GENERAL_FAIL);
645                 if ( Quick_transition_stage != -1 )
646                         brief_transition_reset();
647         } else {
648                 if ( play_sound ) {
649                         gamesnd_play_iface(SND_BRIEF_STAGE_CHG);
650                 }
651         }
652
653         Assert(Current_brief_stage >= 0);
654 }
655
656 // --------------------------------------------------------------------------------------
657 //      brief_do_prev_pressed()
658 //
659 //
660 void brief_do_prev_pressed()
661 {
662         Current_brief_stage--;
663         if ( Current_brief_stage < 0 ) {
664                 Current_brief_stage = 0;
665                 gamesnd_play_iface(SND_GENERAL_FAIL);
666                 if ( Quick_transition_stage != -1 )
667                         brief_transition_reset();
668         } else {
669                 gamesnd_play_iface(SND_BRIEF_STAGE_CHG);
670         }
671         Assert(Current_brief_stage >= 0);
672 }
673
674
675 // --------------------------------------------------------------------------------------
676 //      brief_do_start_pressed()
677 //
678 //
679 void brief_do_start_pressed()
680 {
681         if ( Current_brief_stage != 0 ) {
682                 gamesnd_play_iface(SND_BRIEF_STAGE_CHG);
683                 Current_brief_stage = 0;
684                 if ( Quick_transition_stage != -1 )
685                         brief_transition_reset();
686         } else {
687                 gamesnd_play_iface(SND_GENERAL_FAIL);
688         }
689         Assert(Current_brief_stage >= 0);
690 }
691
692 // --------------------------------------------------------------------------------------
693 //      brief_do_end_pressed()
694 //
695 //
696 void brief_do_end_pressed()
697 {
698         if ( Current_brief_stage != Num_brief_stages - 1 ) {
699                 gamesnd_play_iface(SND_BRIEF_STAGE_CHG);
700                 Current_brief_stage = Num_brief_stages - 1;
701                 if ( Quick_transition_stage != -1 )
702                         brief_transition_reset();
703
704         } else {
705                 gamesnd_play_iface(SND_GENERAL_FAIL);
706         }
707         Assert(Current_brief_stage >= 0);
708 }
709
710
711 void brief_scroll_up_text()
712 {
713         Top_brief_text_line--;
714         if ( Top_brief_text_line < 0 ) {
715                 Top_brief_text_line = 0;
716                 gamesnd_play_iface(SND_GENERAL_FAIL);
717         } else {
718                 gamesnd_play_iface(SND_SCROLL);
719         }
720 }
721
722 void brief_scroll_down_text()
723 {
724         Top_brief_text_line++;
725         if ( (Num_brief_text_lines[0] - Top_brief_text_line) < Brief_text_max_lines[gr_screen.res]) {
726                 Top_brief_text_line--;
727                 gamesnd_play_iface(SND_GENERAL_FAIL);
728         } else {
729                 gamesnd_play_iface(SND_SCROLL);
730         }
731 }
732
733
734 // handles the exit loop option
735 void brief_exit_loop_pressed()
736 {
737         int val = popup(PF_USE_NEGATIVE_ICON | PF_USE_AFFIRMATIVE_ICON, 2, POPUP_NO, POPUP_YES, XSTR( "Exit Loop\n\n\n\nAre you sure you want to leave the mission loop?", 1489));
738
739         // bail if esc hit or no clicked
740         if (val <= 0) {
741                 return;
742         }
743
744         // handle the details
745         // this also posts the start game event
746         mission_campaign_exit_loop();
747 }
748
749
750 // -------------------------------------------------------------------------------------
751 // brief_select_button_do() do the button action for the specified pressed button
752 //
753 void brief_button_do(int i)
754 {
755         switch ( i ) {
756                 case BRIEF_BUTTON_LAST_STAGE:
757                         brief_do_end_pressed();
758                         break;
759
760                 case BRIEF_BUTTON_NEXT_STAGE:
761                         brief_do_next_pressed(1);
762                         break;
763
764                 case BRIEF_BUTTON_PREV_STAGE:
765                         brief_do_prev_pressed();
766                         break;
767
768                 case BRIEF_BUTTON_FIRST_STAGE:
769                         brief_do_start_pressed();
770                         break;
771
772                 case BRIEF_BUTTON_SCROLL_UP:
773                         brief_scroll_up_text();
774                         break;
775
776                 case BRIEF_BUTTON_SCROLL_DOWN:
777                         brief_scroll_down_text();
778                         break;
779
780                 case BRIEF_BUTTON_PAUSE:
781                         gamesnd_play_iface(SND_USER_SELECT);
782                         Player->auto_advance ^= 1;
783                         break;
784
785                 case BRIEF_BUTTON_SKIP_TRAINING:
786                         brief_skip_training_pressed();
787                         break;
788
789                 case BRIEF_BUTTON_EXIT_LOOP:
790                         brief_exit_loop_pressed();
791                         break;
792
793                 case BRIEF_BUTTON_MULTI_LOCK:
794                         Assert(Game_mode & GM_MULTIPLAYER);                     
795                         // the "lock" button has been pressed
796                         multi_ts_lock_pressed();
797
798                         // disable the button if it is now locked
799                         if(multi_ts_is_locked()){
800                                 Brief_buttons[gr_screen.res][BRIEF_BUTTON_MULTI_LOCK].button.disable();
801                         }
802                         break;
803         } // end switch
804 }
805
806 // -------------------------------------------------------------------
807 // brief_check_buttons()
808 //
809 // Iterate through the briefing buttons, checking if they are pressed
810 //
811 void brief_check_buttons()
812 {
813         int                     i;
814         UI_BUTTON       *b;
815
816         for (i=0; i<NUM_BRIEF_BUTTONS; i++) {
817                 b = &Brief_buttons[gr_screen.res][i].button;
818                 if ( b->pressed() ) {
819                         common_flash_button_init();
820                         brief_button_do(i);
821                 }
822         }
823
824         if (Closeup_close_button.pressed()) {
825                 brief_turn_off_closeup_icon();
826         }
827 }
828
829 // -------------------------------------------------------------------
830 // brief_redraw_pressed_buttons()
831 //
832 // Redraw any briefing buttons that are pressed down.  This function is needed
833 // since we sometimes need to draw pressed buttons last to ensure the entire
834 // button gets drawn (and not overlapped by other buttons)
835 //
836 void brief_redraw_pressed_buttons()
837 {
838         int                     i;
839         UI_BUTTON       *b;
840         
841         common_redraw_pressed_buttons();
842
843         for ( i = 0; i < NUM_BRIEF_BUTTONS; i++ ) {
844                 b = &Brief_buttons[gr_screen.res][i].button;
845                 if ( b->button_down() ) {
846                         b->draw_forced(2);
847                 }
848         }
849
850         if ( !Player->auto_advance ) {
851                 Brief_buttons[gr_screen.res][BRIEF_BUTTON_PAUSE].button.draw_forced(2);
852         }
853 }
854
855 void brief_buttons_init()
856 {
857         UI_BUTTON       *b;
858         int                     i;
859
860         //if ( Briefing->num_stages <= 0 )
861         //      return;
862
863         for ( i = 0; i < NUM_BRIEF_BUTTONS; i++ ) {
864                 b = &Brief_buttons[gr_screen.res][i].button;
865                 b->create( &Brief_ui_window, "", Brief_buttons[gr_screen.res][i].x, Brief_buttons[gr_screen.res][i].y, 60, 30, 0, 1 );
866                 // set up callback for when a mouse first goes over a button
867                 b->set_highlight_action( common_play_highlight_sound );
868
869                 if ((i == BRIEF_BUTTON_SKIP_TRAINING) || (i == BRIEF_BUTTON_EXIT_LOOP)) {
870                         b->set_bmaps(Brief_buttons[gr_screen.res][i].filename, 3, 0);
871                 } else {
872                         b->set_bmaps(Brief_buttons[gr_screen.res][i].filename);
873                 }
874                 b->link_hotspot(Brief_buttons[gr_screen.res][i].hotspot);
875         }
876
877         // add all xstrs
878         for(i=0; i<BRIEF_SELECT_NUM_TEXT; i++) {
879                 Brief_ui_window.add_XSTR(&Brief_select_text[gr_screen.res][i]);
880         }
881
882         // Hide the 'skip training' button by default.  Only enable and unhide if we are playing a training
883         // mission
884         Brief_buttons[gr_screen.res][BRIEF_BUTTON_SKIP_TRAINING].button.disable();
885         Brief_buttons[gr_screen.res][BRIEF_BUTTON_SKIP_TRAINING].button.hide();
886         if ( (Game_mode & GM_NORMAL) && (The_mission.game_type & MISSION_TYPE_TRAINING) ) {
887                 Brief_buttons[gr_screen.res][BRIEF_BUTTON_SKIP_TRAINING].button.enable();
888                 Brief_buttons[gr_screen.res][BRIEF_BUTTON_SKIP_TRAINING].button.unhide();
889         }
890
891         // Hide the 'exit loop' button by default.  Only enable and unhide if we are playing a loop
892         // mission
893         Brief_buttons[gr_screen.res][BRIEF_BUTTON_EXIT_LOOP].button.disable();
894         Brief_buttons[gr_screen.res][BRIEF_BUTTON_EXIT_LOOP].button.hide();
895         if ( (Game_mode & GM_NORMAL) && (Campaign.loop_enabled) && (Game_mode & GM_CAMPAIGN_MODE) ) {
896                 Brief_buttons[gr_screen.res][BRIEF_BUTTON_EXIT_LOOP].button.enable();
897                 Brief_buttons[gr_screen.res][BRIEF_BUTTON_EXIT_LOOP].button.unhide();
898         }
899
900         // maybe disable the multi-lock button
901         if(!(Game_mode & GM_MULTIPLAYER)){
902                 Brief_buttons[gr_screen.res][BRIEF_BUTTON_MULTI_LOCK].button.hide();
903                 Brief_buttons[gr_screen.res][BRIEF_BUTTON_MULTI_LOCK].button.disable();
904         } else {
905                 // if we're not the host of the game (or a tema captain in team vs. team mode), disable the lock button
906                 if(Netgame.type_flags & NG_TYPE_TEAM){
907                         if(!(Net_player->flags & NETINFO_FLAG_TEAM_CAPTAIN)){
908                                 Brief_buttons[gr_screen.res][BRIEF_BUTTON_MULTI_LOCK].button.disable();
909                         }
910                 } else {
911                         if(!(Net_player->flags & NETINFO_FLAG_GAME_HOST)){
912                                 Brief_buttons[gr_screen.res][BRIEF_BUTTON_MULTI_LOCK].button.disable();
913                         }
914                 }
915         }
916
917         // create close button for closeup popup
918         Closeup_close_button.create( &Brief_ui_window, "", Closeup_button_coords[gr_screen.res][BRIEF_X_COORD], Closeup_button_coords[gr_screen.res][BRIEF_Y_COORD], 60, 30, 0, 1 );
919         Closeup_close_button.set_highlight_action( common_play_highlight_sound );
920         Closeup_close_button.set_bmaps(Closeup_button_filename[gr_screen.res]);
921         Closeup_close_button.link_hotspot(Closeup_button_hotspot);
922
923         // set up hotkeys for buttons so we draw the correct animation frame when a key is pressed
924         Brief_buttons[gr_screen.res][BRIEF_BUTTON_LAST_STAGE].button.set_hotkey(KEY_SHIFTED|KEY_RIGHT);
925         Brief_buttons[gr_screen.res][BRIEF_BUTTON_NEXT_STAGE].button.set_hotkey(KEY_RIGHT);
926         Brief_buttons[gr_screen.res][BRIEF_BUTTON_PREV_STAGE].button.set_hotkey(KEY_LEFT);
927         Brief_buttons[gr_screen.res][BRIEF_BUTTON_FIRST_STAGE].button.set_hotkey(KEY_SHIFTED|KEY_LEFT);
928         Brief_buttons[gr_screen.res][BRIEF_BUTTON_SCROLL_UP].button.set_hotkey(KEY_UP);
929         Brief_buttons[gr_screen.res][BRIEF_BUTTON_SCROLL_DOWN].button.set_hotkey(KEY_DOWN);
930
931         Closeup_close_button.disable();
932         Closeup_close_button.hide();
933
934         // if we have no briefing stages, hide and disable briefing buttons
935         if(Num_brief_stages <= 0){
936                 Brief_buttons[gr_screen.res][BRIEF_BUTTON_LAST_STAGE].button.disable();
937                 Brief_buttons[gr_screen.res][BRIEF_BUTTON_LAST_STAGE].button.hide();
938                 Brief_buttons[gr_screen.res][BRIEF_BUTTON_NEXT_STAGE].button.disable();
939                 Brief_buttons[gr_screen.res][BRIEF_BUTTON_NEXT_STAGE].button.hide();
940                 Brief_buttons[gr_screen.res][BRIEF_BUTTON_PREV_STAGE].button.disable();
941                 Brief_buttons[gr_screen.res][BRIEF_BUTTON_PREV_STAGE].button.hide();
942                 Brief_buttons[gr_screen.res][BRIEF_BUTTON_FIRST_STAGE].button.disable();
943                 Brief_buttons[gr_screen.res][BRIEF_BUTTON_FIRST_STAGE].button.hide();
944                 Brief_buttons[gr_screen.res][BRIEF_BUTTON_SCROLL_UP].button.disable();
945                 Brief_buttons[gr_screen.res][BRIEF_BUTTON_SCROLL_UP].button.hide();
946                 Brief_buttons[gr_screen.res][BRIEF_BUTTON_SCROLL_DOWN].button.disable();
947                 Brief_buttons[gr_screen.res][BRIEF_BUTTON_SCROLL_DOWN].button.hide();
948                 Brief_buttons[gr_screen.res][BRIEF_BUTTON_PAUSE].button.disable();
949                 Brief_buttons[gr_screen.res][BRIEF_BUTTON_PAUSE].button.hide();         
950         }
951 }
952
953 // --------------------------------------------------------------------------------------
954 //      brief_get_closeup_icon()
955 //
956 //
957 uint brief_get_closeup_icon()
958 {
959         return (uint)Closeup_icon;
960 }
961
962 // stop showing the closeup view of an icon
963 void brief_turn_off_closeup_icon()
964 {
965         // turn off closup
966         if ( Closeup_icon != NULL ) {
967                 gamesnd_play_iface(SND_BRIEF_ICON_SELECT);
968                 Closeup_icon = NULL;
969                 Closeup_close_button.disable();
970                 Closeup_close_button.hide();
971         }
972 }
973
974 // --------------------------------------------------------------------------------------
975 //      brief_load_bitmaps()
976 //
977 //
978 void brief_load_bitmaps()
979 {
980         Brief_text_bitmap = bm_load(Brief_infobox_filename[gr_screen.res]);
981         Brief_grid_bitmap = bm_load(Brief_win_filename[gr_screen.res]);
982         
983         if ( Closeup_bitmap == -1 ) {
984                 Closeup_bitmap = bm_load(Closeup_background_filename[gr_screen.res]);
985         }
986 }
987
988 // --------------------------------------------------------------------------------------
989 //      brief_ui_init()
990 //
991 //
992 void brief_ui_init()
993 {
994         if(Game_mode & GM_MULTIPLAYER) {
995                 Brief_background_bitmap = bm_load(Brief_multi_filename[gr_screen.res]);
996         } else {
997                 Brief_background_bitmap = bm_load(Brief_filename[gr_screen.res]);       
998         }
999
1000         if ( Num_brief_stages <= 0 ){
1001                 return;
1002         }
1003
1004         brief_load_bitmaps();
1005 }
1006
1007
1008 // --------------------------------------------------------------------------------------
1009 //      brief_set_default_closeup()
1010 //
1011 //
1012 void brief_set_default_closeup()
1013 {
1014         brief_stage             *bs;
1015         int                             i;
1016
1017         bs = &Briefing->stages[0];
1018
1019         if ( Briefing->num_stages <= 0 ) {
1020                 Closeup_icon = NULL;
1021                 return;
1022         }
1023
1024         if ( bs->num_icons <= 0 ) {
1025                 Closeup_icon = NULL;
1026                 return;
1027         }
1028
1029         // check for the first highlighted icons to have as the default closeup
1030         for ( i = 0; i < bs->num_icons; i++ ) {
1031                 if ( bs->icons[i].flags & BI_HIGHLIGHT )
1032                         break;
1033         }
1034         
1035         if ( i == bs->num_icons ) {
1036                 brief_setup_closeup(&bs->icons[0]);
1037         }
1038         else {
1039                 brief_setup_closeup(&bs->icons[i]);
1040         }
1041 }
1042
1043 //  funciton to evaluate the sexpressions of the briefing stages eliminating those stages
1044 // which shouldn't get shown
1045 void brief_compact_stages()
1046 {
1047         int num, result, i;
1048
1049         /*
1050         if((Game_mode & GM_MULTIPLAYER) && (Netgame.campaign_mode == MP_CAMPAIGN) && !(Net_player->flags & NETINFO_FLAG_AM_MASTER)){
1051                 Game_mode |= GM_CAMPAIGN_MODE;
1052         }
1053         */
1054
1055         num = 0;
1056         while ( num < Briefing->num_stages ) {
1057                 result = eval_sexp( Briefing->stages[num].formula );
1058                 if ( !result ) {
1059                         if ( Briefing->stages[num].new_text ) {
1060                                 free( Briefing->stages[num].new_text );
1061                                 Briefing->stages[num].new_text = NULL;
1062                         }
1063
1064                         if ( Briefing->stages[num].icons ) {
1065                                 free( Briefing->stages[num].icons );
1066                                 Briefing->stages[num].icons = NULL;
1067                         }
1068
1069
1070                         if ( Briefing->stages[num].lines ) {
1071                                 free( Briefing->stages[num].lines );
1072                                 Briefing->stages[num].lines = NULL;
1073                         }
1074
1075                         Briefing->stages[num].num_icons = 0;
1076                         for ( i = num+1; i < Briefing->num_stages; i++ ) {
1077                                 Briefing->stages[i-1] = Briefing->stages[i];
1078                         }
1079                         Briefing->num_stages--;
1080                         continue;
1081                 }
1082                 num++;
1083         }
1084
1085         /*
1086         if((Game_mode & GM_MULTIPLAYER) && (Netgame.campaign_mode == MP_CAMPAIGN) && !(Net_player->flags & NETINFO_FLAG_AM_MASTER)){
1087                 Game_mode &= ~(GM_CAMPAIGN_MODE);
1088         }
1089         */
1090 }
1091
1092
1093 // --------------------------------------------------------------------------------------
1094 // brief_init() 
1095 //
1096         int red_alert_mission(void);
1097 //
1098 void brief_init()
1099 {
1100         // Since first stage of briefing can take some time to arrive and play, 
1101         // reset the trailer timer on briefing init.
1102 #ifdef FS2_DEMO
1103         demo_reset_trailer_timer();
1104 #endif
1105
1106         // for multiplayer, change the state in my netplayer structure
1107         // and initialize the briefing chat area thingy
1108         if ( Game_mode & GM_MULTIPLAYER ){
1109                 Net_player->state = NETPLAYER_STATE_BRIEFING;
1110         }
1111
1112         // Non standard briefing in red alert mission
1113         if ( red_alert_mission() ) {
1114                 gameseq_post_event(GS_EVENT_RED_ALERT);
1115                 return;
1116         }
1117
1118         // get a pointer to the appropriate briefing structure
1119         if((Game_mode & GM_MULTIPLAYER) && (Netgame.type_flags & NG_TYPE_TEAM)){
1120                 Briefing = &Briefings[Net_player->p_info.team];
1121         } else {
1122                 Briefing = &Briefings[0];                       
1123         }
1124
1125         Brief_last_auto_advance = 0;
1126
1127         brief_compact_stages();                 // compact the briefing array to eliminate unused stages
1128
1129         common_set_interface_palette("BriefingPalette");
1130
1131         ship_stop_animation();
1132         set_active_ui(&Brief_ui_window);
1133         Current_screen = ON_BRIEFING_SELECT;
1134         brief_restart_text_wipe();
1135         common_flash_button_init();
1136         common_music_init(SCORE_BRIEFING);
1137
1138
1139         help_overlay_set_state(BR_OVERLAY,0);
1140
1141         if ( Brief_inited == TRUE ) {
1142                 common_buttons_maybe_reload(&Brief_ui_window);  // AL 11-21-97: this is necessary since we may returning from the hotkey
1143                                                                                                                                                 // screen, which can release common button bitmaps.
1144                 common_reset_buttons();
1145                 nprintf(("Alan","brief_init() returning without doing anything\n"));
1146                 return;
1147         }
1148
1149         if (The_mission.game_type & MISSION_TYPE_TRAINING)
1150                 Num_brief_stages = Briefing->num_stages;
1151         else
1152                 Num_brief_stages = Briefing->num_stages + 1;
1153
1154         Current_brief_stage = 0;
1155         Last_brief_stage = 0;
1156
1157         // init the scene-cut data
1158         brief_transition_reset();
1159
1160 #ifndef FS2_DEMO        
1161         hud_anim_init(&Fade_anim, Brief_static_coords[gr_screen.res][0], Brief_static_coords[gr_screen.res][1], Brief_static_name[gr_screen.res]);
1162         hud_anim_load(&Fade_anim);
1163 #endif
1164
1165         nprintf(("Alan","Entering brief_init()\n"));
1166         common_select_init();
1167
1168         if(Game_mode & GM_MULTIPLAYER) {
1169                 BriefingMaskBitmap = bm_load(Brief_multi_mask_filename[gr_screen.res]);
1170         } else {
1171                 BriefingMaskBitmap = bm_load(Brief_mask_filename[gr_screen.res]);
1172         }
1173
1174         if (BriefingMaskBitmap < 0) {
1175                 Error(LOCATION,"Could not load in 'brief-m'!");
1176         }
1177
1178         Briefing_mask_w = -1;
1179         Briefing_mask_h = -1;
1180
1181         // get a pointer to bitmap by using bm_lock()
1182         BriefingMaskPtr = bm_lock(BriefingMaskBitmap, 8, BMP_AABITMAP);
1183         BriefingMaskData = (ubyte*)BriefingMaskPtr->data;
1184         bm_get_info(BriefingMaskBitmap, &Briefing_mask_w, &Briefing_mask_h);
1185
1186         help_overlay_load(BR_OVERLAY);
1187
1188         // Set up the mask regions
1189    // initialize the different regions of the menu that will react when the mouse moves over it
1190         Num_briefing_regions = 0;
1191
1192         snazzy_menu_add_region(&Briefing_select_region[Num_briefing_regions++], "",     COMMON_BRIEFING_REGION,                         0);
1193         snazzy_menu_add_region(&Briefing_select_region[Num_briefing_regions++], "",     COMMON_SS_REGION,                                               0);
1194         snazzy_menu_add_region(&Briefing_select_region[Num_briefing_regions++], "",     COMMON_WEAPON_REGION,                           0);
1195         snazzy_menu_add_region(&Briefing_select_region[Num_briefing_regions++], "",     COMMON_COMMIT_REGION,                           0);
1196         snazzy_menu_add_region(&Briefing_select_region[Num_briefing_regions++], "",     COMMON_HELP_REGION,                                     0);
1197         snazzy_menu_add_region(&Briefing_select_region[Num_briefing_regions++], "",     COMMON_OPTIONS_REGION,                          0);
1198
1199         snazzy_menu_add_region(&Briefing_select_region[Num_briefing_regions++], "",     BRIEF_LAST_STAGE_MASK,                  0);
1200         snazzy_menu_add_region(&Briefing_select_region[Num_briefing_regions++], "",     BRIEF_NEXT_STAGE_MASK,                  0);
1201         snazzy_menu_add_region(&Briefing_select_region[Num_briefing_regions++], "",     BRIEF_PREV_STAGE_MASK,                  0);
1202         snazzy_menu_add_region(&Briefing_select_region[Num_briefing_regions++], "",     BRIEF_FIRST_STAGE_MASK,                 0);
1203         snazzy_menu_add_region(&Briefing_select_region[Num_briefing_regions++], "",     BRIEF_TEXT_SCROLL_UP_MASK,              0);
1204         snazzy_menu_add_region(&Briefing_select_region[Num_briefing_regions++], "",     BRIEF_TEXT_SCROLL_DOWN_MASK,    0);
1205
1206         // init common UI
1207         Brief_ui_window.create( 0, 0, gr_screen.max_w, gr_screen.max_h, 0 );
1208
1209         if(Game_mode & GM_MULTIPLAYER){
1210                 Brief_ui_window.set_mask_bmap(Brief_mask_multi[gr_screen.res]);
1211         } else {
1212                 Brief_ui_window.set_mask_bmap(Brief_mask_single[gr_screen.res]);
1213         }
1214
1215         Brief_ui_window.tooltip_handler = brief_tooltip_handler;
1216         common_buttons_init(&Brief_ui_window);
1217         brief_buttons_init();
1218
1219         // if multiplayer, initialize a few other systems
1220         if(Game_mode & GM_MULTIPLAYER){         
1221                 // again, should not be necessary, but we'll leave it for now
1222                 chatbox_create();
1223
1224                 // force the chatbox to be small
1225                 chatbox_force_small();
1226         }
1227
1228         // set up the screen regions
1229         brief_init_screen(Brief_multiplayer);
1230
1231         // init briefing specific UI
1232         brief_ui_init();
1233
1234         // init the briefing map
1235         brief_init_map();
1236
1237         // init the briefing voice playback
1238         brief_voice_init();
1239         brief_voice_load_all();
1240
1241         // init objectives display stuff
1242         ML_objectives_init(Brief_goals_coords[gr_screen.res][BRIEF_X_COORD], Brief_goals_coords[gr_screen.res][BRIEF_Y_COORD], Brief_goals_coords[gr_screen.res][BRIEF_W_COORD], Brief_goals_coords[gr_screen.res][BRIEF_H_COORD]);
1243
1244         // set the camera target
1245         if ( Briefing->num_stages > 0 ) {
1246                 brief_set_new_stage(&Briefing->stages[0].camera_pos, &Briefing->stages[0].camera_orient, 0, Current_brief_stage);
1247                 brief_reset_icons(Current_brief_stage);
1248         }
1249
1250         Brief_playing_fade_sound = 0;
1251         Brief_mouse_up_flag     = 0;
1252         Closeup_font_height = gr_get_font_height();
1253         Closeup_icon = NULL;
1254    Brief_inited = TRUE;
1255 }
1256
1257 // -------------------------------------------------------------------------------------
1258 // brief_render_closeup_text()
1259 //
1260 //
1261 #define CLOSEUP_TEXT_OFFSET     10
1262 void brief_render_closeup_text()
1263 {
1264 /*
1265         brief_icon      *bi;
1266         char                    line[MAX_ICON_TEXT_LINE_LEN];
1267         int                     n_lines, i, render_x, render_y;
1268         int                     n_chars[MAX_ICON_TEXT_LINES];
1269         char                    *p_str[MAX_ICON_TEXT_LINES];
1270
1271         if ( Closeup_icon == NULL ) {
1272                 Int3();
1273                 return;
1274         }
1275
1276         bi = Closeup_icon;
1277
1278         render_x = Closeup_region[0];
1279         render_y = Closeup_region[1] + CLOSEUP_IMG_H;
1280         
1281         gr_set_clip(render_x+CLOSEUP_TEXT_OFFSET, render_y, CLOSEUP_W,CLOSEUP_TEXT_H);
1282         gr_set_color_fast(&Color_white);
1283
1284 //      n_lines = split_str(bi->text, CLOSEUP_W - 2*CLOSEUP_TEXT_OFFSET, n_chars, p_str, MAX_ICON_TEXT_LINES);
1285         Assert(n_lines != -1);
1286
1287         for ( i = 0; i < n_lines; i++ ) {
1288                 Assert(n_chars[i] < MAX_ICON_TEXT_LINE_LEN);
1289                 strncpy(line, p_str[i], n_chars[i]);
1290                 line[n_chars[i]] = 0;
1291                 gr_printf(0,0+i*Closeup_font_height,line);
1292         }
1293 */
1294 }
1295
1296 // -------------------------------------------------------------------------------------
1297 // brief_render_closeup()
1298 //
1299 //
1300 void brief_render_closeup(int ship_class, float frametime)
1301 {
1302         matrix  view_orient = IDENTITY_MATRIX;
1303         matrix  temp_matrix;
1304         float           ang;
1305         int             w,h;
1306
1307         if (ship_class < 0)
1308                 return;
1309
1310         if (Closeup_bitmap < 0)
1311                 return;
1312
1313         ang = PI2 * frametime/Closeup_one_revolution_time;
1314         if ( ang > MAX_ANG_CHG )
1315                 ang = MAX_ANG_CHG;
1316
1317         Closeup_angles.h += ang;
1318         if ( Closeup_angles.h > PI2 )
1319                 Closeup_angles.h -= PI2;
1320         vm_angles_2_matrix(&temp_matrix, &Closeup_angles );
1321         Closeup_orient = temp_matrix;
1322
1323         w = Closeup_region[gr_screen.res][2];
1324         h = Closeup_region[gr_screen.res][3];
1325         gr_set_clip(Closeup_region[gr_screen.res][0], Closeup_region[gr_screen.res][1], w, h);
1326
1327         g3_start_frame(1);
1328
1329         g3_set_view_matrix(&Closeup_cam_pos, &view_orient, Closeup_zoom);
1330         model_clear_instance( Closeup_icon->modelnum );
1331         model_set_detail_level(0);
1332
1333         int is_neb = The_mission.flags & MISSION_FLAG_FULLNEB;
1334
1335         // maybe switch off nebula rendering
1336         if(is_neb){
1337                 The_mission.flags &= ~MISSION_FLAG_FULLNEB;
1338         }
1339
1340         int model_render_flags;
1341         if ( Closeup_icon->type == ICON_JUMP_NODE ) {
1342                 model_set_outline_color(HUD_color_red, HUD_color_green, HUD_color_blue);                
1343                 model_render_flags = MR_NO_LIGHTING | MR_LOCK_DETAIL | MR_AUTOCENTER | MR_NO_POLYS | MR_SHOW_OUTLINE;
1344         } else {
1345                 model_render_flags = MR_NO_LIGHTING | MR_LOCK_DETAIL | MR_AUTOCENTER;
1346         }
1347
1348         model_render( Closeup_icon->modelnum, &Closeup_orient, &Closeup_pos, model_render_flags );
1349
1350         if (is_neb) {
1351                 The_mission.flags |= MISSION_FLAG_FULLNEB;
1352         }
1353
1354         g3_end_frame();
1355
1356         gr_set_color_fast(&Color_bright_white);
1357
1358         gr_printf(0x8000,2,Closeup_icon->closeup_label);
1359 //      brief_render_closeup_text();
1360
1361         Closeup_close_button.enable();
1362         Closeup_close_button.unhide();
1363
1364         gr_reset_clip();
1365 }
1366
1367 // -------------------------------------------------------------------------------------
1368 // brief_render()
1369 //
1370 //      frametime is in seconds
1371 void brief_render(float frametime)
1372 {
1373         int z;
1374         int w;
1375
1376 #ifndef NDEBUG
1377         int h;
1378 #endif
1379
1380         if ( Num_brief_stages <= 0 ) {
1381                 gr_set_color_fast(&Color_white);
1382                 Assert( Game_current_mission_filename != NULL );
1383                 gr_printf(0x8000,200,XSTR( "No Briefing exists for mission: %s", 430), Game_current_mission_filename);
1384
1385                 #ifndef NDEBUG
1386                 gr_get_string_size(&w, &h, The_mission.name);
1387                 gr_set_color_fast(&Color_normal);
1388                 gr_printf(0x8000, 230, NOX("[filename: %s, last mod: %s]"), Mission_filename, The_mission.modified);
1389                 #endif
1390
1391                 return;
1392         }
1393
1394         gr_set_bitmap(Brief_grid_bitmap);
1395         gr_bitmap(Brief_bmap_coords[gr_screen.res][0], Brief_bmap_coords[gr_screen.res][1]);
1396
1397         brief_render_map(Current_brief_stage, frametime);
1398
1399         // draw the frame bitmaps
1400         gr_set_bitmap(Brief_text_bitmap);
1401         gr_bitmap(Brief_infobox_coords[gr_screen.res][0], Brief_infobox_coords[gr_screen.res][1]);
1402         brief_blit_stage_num(Current_brief_stage, Num_brief_stages);
1403
1404         z = brief_render_text(Top_brief_text_line, Brief_text_coords[gr_screen.res][0], Brief_text_coords[gr_screen.res][1], Brief_text_coords[gr_screen.res][3], frametime);
1405         if (z) {
1406                 brief_voice_play(Current_brief_stage);
1407         }
1408
1409         // maybe output the "more" indicator
1410         if ( (Brief_text_max_lines[gr_screen.res] + Top_brief_text_line + 2) < Num_brief_text_lines[0] ) {
1411                 // can be scrolled down
1412                 int more_txt_x = Brief_text_coords[gr_screen.res][0] + (Brief_max_line_width[gr_screen.res]/2) - 10;
1413                 int more_txt_y = Brief_text_coords[gr_screen.res][1] + Brief_text_coords[gr_screen.res][3] - 2;                         // located below brief text, centered
1414                 int w, h;
1415                 gr_get_string_size(&w, &h, XSTR("more", 1469), strlen(XSTR("more", 1469)));
1416                 gr_set_color_fast(&Color_black);
1417                 gr_rect(more_txt_x-2, more_txt_y, w+3, h);
1418                 gr_set_color_fast(&Color_red);
1419                 gr_string(more_txt_x, more_txt_y, XSTR("more", 1469));  // base location on the input x and y?
1420         }
1421
1422         brief_maybe_blit_scene_cut(frametime);  
1423
1424 #if !defined(NDEBUG) || defined(INTERPLAYQA)
1425         gr_set_color_fast(&Color_normal);
1426         int title_y_offset = (Game_mode & GM_MULTIPLAYER) ? 20 : 10;
1427         gr_printf(Brief_bmap_coords[gr_screen.res][0], Brief_bmap_coords[gr_screen.res][1]-title_y_offset, NOX("[name: %s, mod: %s]"), Mission_filename, The_mission.modified);
1428 #endif
1429
1430         // output mission title
1431         gr_set_color_fast(&Color_bright_white);
1432         if (Game_mode & GM_MULTIPLAYER) {
1433                 char buf[256];
1434                 strncpy(buf, The_mission.name, 256);
1435                 gr_force_fit_string(buf, 255, Title_coords_multi[gr_screen.res][2]);
1436                 gr_string(Title_coords_multi[gr_screen.res][0], Title_coords_multi[gr_screen.res][1], buf);
1437         } else {
1438                 gr_get_string_size(&w, NULL, The_mission.name);
1439                 gr_string(Title_coords[gr_screen.res][0] - w, Title_coords[gr_screen.res][1], The_mission.name);
1440         }
1441
1442         // maybe do objectives
1443         if (Current_brief_stage == Briefing->num_stages) {
1444                 ML_objectives_do_frame(0);
1445         }       
1446 }
1447
1448 // -------------------------------------------------------------------------------------
1449 // brief_set_closeup_pos()
1450 //
1451 //
1452 #define CLOSEUP_OFFSET 20
1453 void brief_set_closeup_pos(brief_icon *bi)
1454 {
1455         Closeup_y1 = 10;
1456         Closeup_x1 = fl2i(320 - Closeup_coords[gr_screen.res][BRIEF_W_COORD]/2.0f + 0.5f);
1457 }
1458
1459 void brief_get_closeup_ship_modelnum(brief_icon *ci)
1460 {
1461         object  *objp;
1462         ship            *sp;
1463
1464         // find the model number for the ship to display
1465         for ( objp = GET_FIRST(&obj_used_list); objp !=END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp) ) {
1466
1467                 if ( objp == &obj_used_list || objp->type != OBJ_SHIP ) {
1468                         continue;
1469                 }
1470                 
1471                 sp = &Ships[objp->instance];
1472                 if ( sp->ship_info_index == ci->ship_class ) {
1473                         ci->ship_class = sp->ship_info_index;
1474                         ci->modelnum = sp->modelnum;
1475                         ci->radius = objp->radius;
1476                         break;
1477                 }
1478         }
1479 }
1480
1481 // cut any text off after (and including) '#' char
1482 void brief_truncate_label(char *src)
1483 {
1484         char *pointer_to_last_char;
1485
1486         pointer_to_last_char = strstr(src, NOX("#"));
1487
1488         if ( pointer_to_last_char ) {
1489                 *pointer_to_last_char = 0;
1490         }
1491 }
1492
1493 // -------------------------------------------------------------------------------------
1494 // brief_setup_closeup()
1495 //
1496 // exit: 0      =>              set-up icon sucessfully
1497 //                      -1      =>              could not setup closeup icon
1498 int brief_setup_closeup(brief_icon *bi)
1499 {
1500         char                            pof_filename[NAME_LENGTH];
1501         ship_info               *sip=NULL;
1502         vector                  tvec;
1503
1504         Closeup_icon = bi;
1505         Closeup_icon->ship_class = bi->ship_class;
1506         Closeup_icon->modelnum = -1;
1507
1508         Closeup_one_revolution_time = ONE_REV_TIME;
1509
1510         switch(Closeup_icon->type) {
1511         case ICON_PLANET:
1512                 Closeup_icon = NULL;
1513                 return -1;
1514                 /*
1515                 strcpy(pof_filename, NOX("planet.pof"));
1516                 strcpy(Closeup_icon->closeup_label, XSTR("planet",-1));
1517                 vm_vec_make(&Closeup_cam_pos, 0.0f, 0.0f, -8300.0f);
1518                 Closeup_zoom = 0.5f;
1519                 Closeup_one_revolution_time = ONE_REV_TIME * 3;
1520                 */
1521                 break;
1522         case ICON_ASTEROID_FIELD:
1523 #ifndef FS2_DEMO
1524                 strcpy(pof_filename, Asteroid_info[ASTEROID_TYPE_BIG].pof_files[0]);
1525                 strcpy(Closeup_icon->closeup_label, XSTR( "asteroid", 431));
1526                 vm_vec_make(&Closeup_cam_pos, 0.0f, 0.0f, -334.0f);
1527                 Closeup_zoom = 0.5f;
1528 #endif
1529                 break;
1530         case ICON_JUMP_NODE:
1531                 strcpy(pof_filename, NOX("subspacenode.pof"));
1532                 strcpy(Closeup_icon->closeup_label, XSTR( "jump node", 432));
1533                 vm_vec_make(&Closeup_cam_pos, 0.0f, 0.0f, -2700.0f);
1534                 Closeup_zoom = 0.5f;
1535                 Closeup_one_revolution_time = ONE_REV_TIME * 3;
1536                 break;
1537         case ICON_UNKNOWN:
1538         case ICON_UNKNOWN_WING:
1539                 strcpy(pof_filename, NOX("unknownship.pof"));
1540                 strcpy(Closeup_icon->closeup_label, XSTR( "unknown", 433));
1541                 vm_vec_make(&Closeup_cam_pos, 0.0f, 0.0f, -22.0f);
1542                 Closeup_zoom = 0.5f;
1543                 break;
1544         default:
1545                 brief_get_closeup_ship_modelnum(Closeup_icon);
1546                 Assert( Closeup_icon->ship_class != -1 );
1547                 sip = &Ship_info[Closeup_icon->ship_class];
1548
1549                 strcpy(Closeup_icon->closeup_label,sip->name);
1550
1551                 // cut any text off after (and including) '#' char
1552                 brief_truncate_label(Closeup_icon->closeup_label);
1553
1554                 if ( sip->flags & (SIF_SMALL_SHIP|SIF_BIG_SHIP|SIF_HUGE_SHIP|SIF_SENTRYGUN) ) {
1555                         strcat(Closeup_icon->closeup_label, XSTR( " class", 434));
1556                 }
1557                 break;
1558         }
1559         
1560         if ( Closeup_icon->modelnum == -1 ) {
1561                 if ( sip == NULL ) {
1562                         Closeup_icon->modelnum = model_load(pof_filename, NULL, NULL);
1563                 } else {
1564                         Closeup_icon->modelnum = model_load(sip->pof_file, sip->n_subsystems, &sip->subsystems[0]);
1565                 }
1566                 Closeup_icon->radius = model_get_radius(Closeup_icon->modelnum);
1567         }
1568
1569         vm_set_identity(&Closeup_orient);
1570         vm_vec_make(&tvec, 0.0f, 0.0f, -1.0f);
1571         Closeup_orient.fvec = tvec;
1572         vm_vec_zero(&Closeup_pos);
1573         Closeup_angles.p  = 0.0f;
1574         Closeup_angles.b  = 0.0f;
1575         Closeup_angles.h  = PI;
1576
1577         brief_set_closeup_pos(bi);
1578
1579         if ( sip ) {
1580                 Closeup_cam_pos = sip->closeup_pos;
1581                 Closeup_zoom = sip->closeup_zoom;
1582         }
1583
1584         return 0;
1585 }
1586
1587 // -------------------------------------------------------------------------------------
1588 // brief_update_closeup_icon()
1589 //
1590 //      input:  mode    =>              how to update the closeup view
1591 //                                                              0 -> disable
1592 //
1593 void brief_update_closeup_icon(int mode)
1594 {
1595         brief_stage             *bs;
1596         brief_icon              *bi;
1597         int                             i, closeup_index;
1598         
1599
1600         if ( mode == 0 ) {
1601                 // mode 0 means disable the closeup icon
1602                 if ( Closeup_icon != NULL ) {
1603                         brief_turn_off_closeup_icon();
1604                 }
1605                 return;
1606         }
1607
1608         if ( Closeup_icon == NULL )
1609                 return;
1610
1611         bs = &Briefing->stages[Current_brief_stage];
1612
1613         closeup_index = -1;
1614         // see if any icons are being highlighted this stage
1615         for ( i = 0; i < bs->num_icons; i++ ) {
1616                 bi = &bs->icons[i];
1617                 if ( bi->flags & BI_HIGHLIGHT ) {
1618                         closeup_index = i;
1619                         break;
1620                 }
1621         }
1622
1623         if ( closeup_index != -1 ) {
1624                 bi = &bs->icons[closeup_index];
1625                 brief_setup_closeup(bi);
1626         }
1627         else {
1628                 Closeup_icon = NULL;
1629         }
1630 }
1631
1632
1633 // -------------------------------------------------------------------------------------
1634 // brief_check_for_anim()
1635 //
1636 //
1637 void brief_check_for_anim()
1638 {
1639         int                             mx, my, i, iw, ih;
1640         brief_stage             *bs;
1641         brief_icon              *bi = NULL;
1642
1643         bs = &Briefing->stages[Current_brief_stage];
1644         mouse_get_pos( &mx, &my );
1645
1646         // if mouse click is over the VCR controls, don't launch an icon
1647         // FIXME - should prolly push these into defines instead of hardcoding this
1648         if ( mx >= 0 && mx <= 115 && my >= 136 && my <= 148 ) {
1649                 return;
1650         }
1651
1652         // if mouse coords are outside the briefing screen, then go away
1653         my -= bscreen.map_y1;
1654         mx -= bscreen.map_x1;
1655         if ( my < 0 || mx < 0 || mx > (bscreen.map_x2-bscreen.map_x1+1) || my > (bscreen.map_y2-bscreen.map_y1+1) )
1656                 return;
1657
1658         for ( i = 0; i < bs->num_icons; i++ ) {
1659                 bi = &bs->icons[i];
1660                 brief_common_get_icon_dimensions(&iw, &ih, bi->type, bi->ship_class);
1661                 if ( mx < bi->x ) continue;
1662                 if ( mx > (bi->x + iw) ) continue;
1663                 if ( my < bi->y ) continue;
1664                 if ( my > (bi->y + ih) ) continue;
1665                 // if we've got here, must be a hit
1666                 break;
1667         }
1668
1669         if ( i == bs->num_icons ) {
1670                 brief_turn_off_closeup_icon();
1671                 return;
1672         }
1673
1674         if ( brief_setup_closeup(bi) == 0 ) {
1675                 gamesnd_play_iface(SND_BRIEF_ICON_SELECT);
1676         } else {
1677                 gamesnd_play_iface(SND_GENERAL_FAIL);
1678         }
1679 }
1680
1681 // maybe flash a button if player hasn't done anything for a while
1682 void brief_maybe_flash_button()
1683 {
1684         UI_BUTTON *b;
1685
1686         if ( Num_brief_stages <= 0 ) 
1687                 return;
1688
1689         if ( Closeup_icon != NULL ) {
1690                 common_flash_button_init();
1691                 return;
1692         }
1693
1694         if ( common_flash_bright() ) {
1695                 if ( Current_brief_stage == (Num_brief_stages-1) ) {
1696
1697                         // AL 4-4-98: Don't flash ship selection button on briefing in demo build
1698 #ifdef FS2_DEMO
1699                                 return;
1700 #else
1701                         // AL 30-3-98: Don't flash ship selection button if in a training mission, 
1702                         if ( brief_only_allow_briefing() ) {
1703                                 return;
1704                         }
1705
1706                         b = &Common_buttons[Current_screen-1][gr_screen.res][1].button;         // ship select button
1707 #endif
1708                 } else {
1709                         b = &Brief_buttons[gr_screen.res][1].button;            // next stage button
1710                 }
1711
1712                 if ( b->button_hilighted() ) {
1713                         common_flash_button_init();
1714                 } else {
1715                         b->draw_forced(1);
1716                 }
1717         }
1718 }
1719
1720 // -------------------------------------------------------------------------------------
1721 // brief_do_frame()
1722 //
1723 // frametime is in seconds
1724 //
1725 void brief_do_frame(float frametime)
1726 {
1727         int k, brief_choice;
1728
1729         if ( red_alert_mission() ) {
1730                 return;
1731         }
1732
1733
1734         if ( !Brief_inited ){
1735                 brief_init();
1736         }
1737
1738         int snazzy_action = -1;
1739         brief_choice = snazzy_menu_do(BriefingMaskData, Briefing_mask_w, Briefing_mask_h, Num_briefing_regions, Briefing_select_region, &snazzy_action, 0);
1740
1741         k = common_select_do(frametime);
1742
1743         if ( Closeup_icon ) {
1744                 Brief_mouse_up_flag = 0;
1745         }
1746
1747         if ( help_overlay_active(BR_OVERLAY) ) {
1748                 common_flash_button_init();
1749                 brief_turn_off_closeup_icon();
1750         }
1751
1752         // Check common keypresses
1753         common_check_keys(k);
1754
1755 #ifndef NDEBUG
1756         int cam_change = 0;
1757 #endif
1758
1759         if ( Briefing->num_stages > 0 ) {
1760
1761                 // check for special keys
1762                 switch(k) {
1763
1764 #ifndef NDEBUG                  
1765                         case KEY_CTRLED | KEY_PAGEUP: {
1766                                 if (Closeup_icon->ship_class) {
1767                                         Closeup_icon->ship_class--;
1768
1769                                         ship_info *sip = &Ship_info[Closeup_icon->ship_class];
1770                                         if (sip->modelnum < 0)
1771                                                 sip->modelnum = model_load(sip->pof_file, NULL, NULL);
1772
1773                                         mprintf(("Shiptype = %d (%s)\n", Closeup_icon->ship_class, sip->name));
1774                                         mprintf(("Modelnum = %d (%s)\n", sip->modelnum, sip->pof_file));
1775                                         brief_setup_closeup(Closeup_icon);
1776                                 }
1777
1778                                 break;
1779                         }
1780
1781                         case KEY_CTRLED | KEY_PAGEDOWN: {
1782                                 if (Closeup_icon->ship_class < Num_ship_types - 1) {
1783                                         Closeup_icon->ship_class++;
1784
1785                                         ship_info *sip = &Ship_info[Closeup_icon->ship_class];
1786                                         if (sip->modelnum < 0)
1787                                                 sip->modelnum = model_load(sip->pof_file, NULL, NULL);
1788
1789                                         mprintf(("Shiptype = %d (%s)\n", Closeup_icon->ship_class, sip->name));
1790                                         mprintf(("Modelnum = %d (%s)\n", sip->modelnum, sip->pof_file));
1791                                         brief_setup_closeup(Closeup_icon);
1792                                 }
1793
1794                                 break;
1795                         }
1796
1797                         case KEY_A:
1798                                 Closeup_cam_pos.z += 1;
1799                                 cam_change = 1;
1800                                 break;
1801
1802                         case KEY_A + KEY_SHIFTED:
1803                                 Closeup_cam_pos.z += 10;
1804                                 cam_change = 1;
1805                                 break;
1806
1807                         case KEY_Z:
1808                                 Closeup_cam_pos.z -= 1;
1809                                 cam_change = 1;
1810                                 break;
1811
1812                         case KEY_Z + KEY_SHIFTED:
1813                                 Closeup_cam_pos.z -= 10;
1814                                 cam_change = 1;
1815                                 break;
1816                         
1817                         case KEY_Y:
1818                                 Closeup_cam_pos.y += 1;
1819                                 cam_change = 1;
1820                                 break;
1821
1822                         case KEY_Y + KEY_SHIFTED:
1823                                 Closeup_cam_pos.y += 10;
1824                                 cam_change = 1;
1825                                 break;
1826
1827                         case KEY_H:
1828                                 Closeup_cam_pos.y -= 1;
1829                                 cam_change = 1;
1830                                 break;
1831
1832                         case KEY_H + KEY_SHIFTED:
1833                                 Closeup_cam_pos.y -= 10;
1834                                 cam_change = 1;
1835                                 break;
1836
1837                         case KEY_COMMA:
1838                                 Closeup_zoom -= 0.1f;
1839                                 if ( Closeup_zoom < 0.1 ) 
1840                                         Closeup_zoom = 0.1f;
1841                                 cam_change = 1;
1842                                 break;
1843
1844                         case KEY_COMMA+KEY_SHIFTED:
1845                                 Closeup_zoom -= 0.5f;
1846                                 if ( Closeup_zoom < 0.1 ) 
1847                                         Closeup_zoom = 0.1f;
1848                                 cam_change = 1;
1849                                 break;
1850
1851                         case KEY_PERIOD:
1852                                 Closeup_zoom += 0.1f;
1853                                 cam_change = 1;
1854                                 break;
1855
1856                         case KEY_PERIOD+KEY_SHIFTED:
1857                                 Closeup_zoom += 0.5f;
1858                                 cam_change = 1;
1859                                 break;
1860 #endif
1861                         case 1000:              // need this to avoid warning about no case
1862                                 break;
1863
1864                         default:
1865                                 break;
1866                 } // end switch
1867         }
1868
1869 #ifndef NDEBUG
1870         if ( cam_change ) {
1871                 nprintf(("General","Camera pos: %.2f, %.2f %.2f // ", Closeup_cam_pos.x, Closeup_cam_pos.y, Closeup_cam_pos.z));
1872                 nprintf(("General","Camera zoom: %.2f\n", Closeup_zoom));
1873         }
1874 #endif
1875
1876         if ( brief_choice > -1 && snazzy_action == SNAZZY_OVER ) {
1877                 Brief_mouse_up_flag = 0;
1878                 brief_choice = -1;
1879         }
1880
1881
1882         common_check_buttons();
1883         // if ( Briefing->num_stages > 0 )
1884         brief_check_buttons();
1885
1886         if ( brief_choice != -1 ) {
1887                 Brief_mouse_up_flag = 0;
1888         }
1889
1890         gr_reset_clip();
1891
1892         common_render(frametime);
1893
1894         if ( Current_brief_stage < (Num_brief_stages-1) ) {
1895                 if ( !help_overlay_active(BR_OVERLAY) && brief_time_to_advance(Current_brief_stage, frametime) ) {
1896                         brief_do_next_pressed(0);
1897                         common_flash_button_init();
1898                         Brief_last_auto_advance = timer_get_milliseconds();
1899                 }
1900         }
1901
1902         if ( !Background_playing ) {
1903                 int time = -1;
1904                 int check_jump_flag = 1;
1905                 if ( Current_brief_stage != Last_brief_stage ) {
1906
1907                         // Check if we have a quick transition pending
1908                         if ( Quick_transition_stage != -1 ) {
1909                                         Quick_transition_stage = -1;
1910                                         brief_reset_last_new_stage();
1911                                         time = 0;
1912                                         check_jump_flag = 0;
1913                         }
1914
1915                         if ( check_jump_flag ) {
1916                                 if ( abs(Current_brief_stage - Last_brief_stage) > 1 ) {
1917                                         Quick_transition_stage = Current_brief_stage;
1918                                         Current_brief_stage = Last_brief_stage;
1919                                         Assert(Current_brief_stage >= 0);
1920                                         Start_fade_up_anim = 1;
1921                                         goto Transition_done;
1922                                 }
1923                         }
1924
1925                         if ( time != 0 ) {
1926                                 if ( Current_brief_stage > Last_brief_stage ) {
1927                                         if ( Briefing->stages[Last_brief_stage].flags & BS_FORWARD_CUT ) {
1928                                                 Quick_transition_stage = Current_brief_stage;
1929                                                 Current_brief_stage = Last_brief_stage;
1930                                                 Assert(Current_brief_stage >= 0);
1931                                                 Start_fade_up_anim = 1;
1932                                                 goto Transition_done;
1933                                         } else {
1934                                                 time = Briefing->stages[Current_brief_stage].camera_time;
1935                                         }
1936                                 }
1937                                 else {
1938                                         if ( Briefing->stages[Last_brief_stage].flags & BS_BACKWARD_CUT ) { 
1939                                                 Quick_transition_stage = Current_brief_stage;
1940                                                 Current_brief_stage = Last_brief_stage;
1941                                                 Assert(Current_brief_stage >= 0);
1942                                                 Start_fade_up_anim = 1;
1943                                                 goto Transition_done;
1944                                         } else {
1945                                                 time = Briefing->stages[Last_brief_stage].camera_time;
1946                                         }
1947                                 }
1948                         }
1949
1950                         brief_voice_stop(Last_brief_stage);
1951
1952                         if ( Current_brief_stage < 0 ) {
1953                                 Int3();
1954                                 Current_brief_stage=0;
1955                         }
1956
1957                         // set the camera target
1958                         brief_set_new_stage(&Briefing->stages[Current_brief_stage].camera_pos,
1959                                                                           &Briefing->stages[Current_brief_stage].camera_orient,
1960                                                                           time, Current_brief_stage);
1961
1962                         Brief_playing_fade_sound = 0;
1963                         Last_brief_stage = Current_brief_stage;
1964                         brief_reset_icons(Current_brief_stage);
1965                         brief_update_closeup_icon(0);
1966                 }
1967
1968                 Transition_done:
1969
1970                 if ( Brief_mouse_up_flag && !Closeup_icon) {
1971                         brief_check_for_anim();
1972                 }
1973
1974                 brief_render(frametime);
1975                 brief_camera_move(frametime, Current_brief_stage);
1976
1977                 if (Closeup_icon && (Closeup_bitmap >= 0)) {
1978                         // blit closeup background
1979                         gr_set_bitmap(Closeup_bitmap);
1980                         gr_bitmap(Closeup_coords[gr_screen.res][BRIEF_X_COORD], Closeup_coords[gr_screen.res][BRIEF_Y_COORD]);
1981                 }
1982
1983                 Brief_ui_window.draw();
1984                 brief_redraw_pressed_buttons();
1985                 common_render_selected_screen_button();
1986
1987                 if (Closeup_icon) {
1988                         brief_render_closeup(Closeup_icon->ship_class, frametime);
1989                 }
1990
1991                 // render some extra stuff in multiplayer
1992                 if (Game_mode & GM_MULTIPLAYER) {
1993                         // should render this last so that it overlaps all controls
1994                         chatbox_render();
1995
1996                         // render the status indicator for the voice system
1997                         multi_common_voice_display_status();
1998
1999                         // blit the "ships/players" locked button
2000                         // multi_ts_blit_locked_button();
2001
2002                         // maybe blit the multiplayer "locked" button   
2003                         // if its locked, everyone blits it as such
2004                         if(multi_ts_is_locked()){
2005                                 Brief_buttons[gr_screen.res][BRIEF_BUTTON_MULTI_LOCK].button.draw_forced(2);
2006                         } 
2007                         // anyone who can't hit the button sees it off, otherwise
2008                         else {
2009                                 if( ((Netgame.type_flags & NG_TYPE_TEAM) && !(Net_player->flags & NETINFO_FLAG_TEAM_CAPTAIN)) ||
2010                                          ((Netgame.type_flags & NG_TYPE_TEAM) && !(Net_player->flags & NETINFO_FLAG_GAME_HOST)) ){
2011                                         Brief_buttons[gr_screen.res][BRIEF_BUTTON_MULTI_LOCK].button.draw_forced(0);
2012                                 } else {
2013                                         Brief_buttons[gr_screen.res][BRIEF_BUTTON_MULTI_LOCK].button.draw();
2014                                 }
2015                         }
2016                 }
2017         }               
2018
2019         // maybe flash a button if player hasn't done anything for a while
2020         brief_maybe_flash_button();
2021
2022         // blit help overlay if active
2023         help_overlay_maybe_blit(BR_OVERLAY);    
2024
2025         gr_flip();      
2026
2027         // If the commit button was pressed, do the commit button actions.  Done at the end of the
2028         // loop so there isn't a skip in the animation (since ship_create() can take a long time if
2029         // the ship model is not in memory
2030         if (Commit_pressed) {
2031                 if (Game_mode & GM_MULTIPLAYER) {
2032                         multi_ts_commit_pressed();
2033                 } else {
2034                         commit_pressed();
2035                 }
2036
2037                 Commit_pressed = 0;
2038         }
2039 }
2040
2041 // --------------------------------------------------------------------------------------
2042 //      brief_unload_bitmaps()
2043 //
2044 //
2045 void brief_unload_bitmaps()
2046 {       
2047         if ( BriefingMaskBitmap != -1 ) {
2048                 bm_unload(BriefingMaskBitmap);
2049                 BriefingMaskBitmap = -1;
2050         }
2051
2052         if ( Brief_text_bitmap != -1 ) {
2053                 bm_unload(Brief_text_bitmap);
2054                 Brief_text_bitmap = -1;
2055         }
2056
2057         if(Brief_grid_bitmap != -1){
2058                 bm_unload(Brief_grid_bitmap);
2059                 Brief_grid_bitmap = -1;
2060         }
2061
2062         if ( Brief_multitext_bitmap != -1 ) {
2063                 bm_unload(Brief_multitext_bitmap);
2064                 Brief_multitext_bitmap = -1;
2065         }
2066
2067         if ( Brief_background_bitmap != -1 ) {
2068                 bm_unload(Brief_background_bitmap);
2069                 Brief_background_bitmap = -1;
2070         }
2071
2072         help_overlay_unload(BR_OVERLAY);
2073 }
2074
2075 // ------------------------------------------------------------------------------------
2076 // brief_close()
2077 //
2078 //
2079 void brief_close()
2080 {
2081         if ( Brief_inited == FALSE ) {
2082                 nprintf(("Warning","brief_close() returning without doing anything\n"));
2083                 return;
2084         }
2085
2086         nprintf(("Alan", "Entering brief_close()\n"));
2087
2088         ML_objectives_close();
2089
2090         // unload the audio streams used for voice playback
2091         brief_voice_unload_all();
2092
2093 #ifndef FS2_DEMO
2094         hud_anim_release(&Fade_anim);
2095 #endif
2096
2097         // done mask bitmap, so unlock it
2098         bm_unlock(BriefingMaskBitmap);
2099
2100         Brief_ui_window.destroy();
2101
2102         // unload the bitmaps
2103         brief_unload_bitmaps();
2104
2105         brief_common_close();
2106
2107         Brief_inited = FALSE;
2108 }
2109
2110 void briefing_stop_music()
2111 {
2112         if ( Briefing_music_handle != -1 ) {
2113                 audiostream_close_file(Briefing_music_handle);
2114                 Briefing_music_handle = -1;
2115         }
2116 }
2117
2118 void briefing_load_music(char* fname)
2119 {
2120         if ( Cmdline_freespace_no_music ) {
2121                 return;
2122         }
2123
2124         if ( Briefing_music_handle != -1 )
2125                 return;
2126
2127         if ( fname )
2128                 Briefing_music_handle = audiostream_open( fname, ASF_EVENTMUSIC );
2129 }
2130
2131 void briefing_start_music()
2132 {
2133         if ( Briefing_music_handle != -1 ) {
2134                 if ( !audiostream_is_playing(Briefing_music_handle) )
2135                         audiostream_play(Briefing_music_handle, Master_event_music_volume);
2136         }
2137         else {
2138                 nprintf(("Warning", "No music file exists to play music at this briefing!\n"));
2139         }
2140 }
2141
2142 void brief_stop_voices()
2143 {
2144         brief_voice_stop(Current_brief_stage);
2145 }
2146
2147 void brief_maybe_blit_scene_cut(float frametime)
2148 {
2149         if ( Start_fade_up_anim ) {
2150
2151 #ifdef FS2_DEMO
2152                 Fade_anim.time_elapsed = 0.0f;
2153                 Start_fade_up_anim = 0;
2154                 Start_fade_down_anim = 1;
2155                 Current_brief_stage = Quick_transition_stage;
2156
2157                 if ( Current_brief_stage < 0 ) {
2158                         brief_transition_reset();
2159                         Current_brief_stage = Last_brief_stage;
2160                 }
2161                 goto Fade_down_anim_start;
2162 #else
2163                 int framenum;
2164
2165                 Fade_anim.time_elapsed += frametime;
2166
2167                 if ( !Brief_playing_fade_sound ) {
2168                         gamesnd_play_iface(SND_BRIEFING_STATIC);                                        
2169                         Brief_playing_fade_sound = 1;
2170                 }
2171
2172                 if ( Fade_anim.time_elapsed > Fade_anim.total_time ) {
2173                         Fade_anim.time_elapsed = 0.0f;
2174                         Start_fade_up_anim = 0;
2175                         Start_fade_down_anim = 1;
2176                         Current_brief_stage = Quick_transition_stage;
2177                 
2178                         if ( Current_brief_stage < 0 ) {
2179                                 brief_transition_reset();
2180                                 Current_brief_stage = Last_brief_stage;
2181                         }
2182
2183                         Assert(Current_brief_stage >= 0);                       
2184                         goto Fade_down_anim_start;
2185                 }
2186
2187                 // draw the correct frame of animation
2188                 framenum = fl2i( (Fade_anim.time_elapsed * Fade_anim.num_frames) / Fade_anim.total_time );
2189                 if ( framenum < 0 )
2190                         framenum = 0;
2191                 if ( framenum >= Fade_anim.num_frames )
2192                         framenum = Fade_anim.num_frames-1;
2193
2194                 // Blit the bitmap for this frame
2195                 gr_set_bitmap(Fade_anim.first_frame + framenum);
2196                 gr_bitmap(Fade_anim.sx, Fade_anim.sy);
2197 #endif
2198         }
2199
2200
2201         Fade_down_anim_start:
2202         if ( Start_fade_down_anim ) {
2203
2204 #ifdef FS2_DEMO
2205                 Fade_anim.time_elapsed = 0.0f;
2206                 Start_fade_up_anim = 0;
2207                 Start_fade_down_anim = 0;
2208                 return;
2209 #else
2210
2211                 int framenum;
2212
2213                 Fade_anim.time_elapsed += frametime;
2214
2215                 if ( Fade_anim.time_elapsed > Fade_anim.total_time ) {
2216                         Fade_anim.time_elapsed = 0.0f;
2217                         Start_fade_up_anim = 0;
2218                         Start_fade_down_anim = 0;
2219                         return;
2220                 }
2221
2222                 // draw the correct frame of animation
2223                 framenum = fl2i( (Fade_anim.time_elapsed * Fade_anim.num_frames) / Fade_anim.total_time );
2224                 if ( framenum < 0 )
2225                         framenum = 0;
2226                 if ( framenum >= Fade_anim.num_frames )
2227                         framenum = Fade_anim.num_frames-1;
2228
2229                 // Blit the bitmap for this frame
2230                 gr_set_bitmap(Fade_anim.first_frame + (Fade_anim.num_frames-1) - framenum);
2231                 gr_bitmap(Fade_anim.sx, Fade_anim.sy);
2232
2233 #endif
2234         }
2235 }
2236
2237 void brief_transition_reset()
2238 {
2239         Quick_transition_stage = -1;
2240         Start_fade_up_anim = 0;
2241         Start_fade_down_anim = 0;
2242         Fade_anim.time_elapsed = 0.0f;
2243 }
2244
2245 // return 1 if this mission only allow players to use the briefing (and not ship or 
2246 // weapon loadout).  Otherwise return 0.
2247 int brief_only_allow_briefing()
2248 {
2249         if ( The_mission.game_type & MISSION_TYPE_TRAINING ) {
2250                 return 1;
2251         }
2252
2253         if ( The_mission.scramble || The_mission.red_alert) {
2254                 return 1;
2255         }
2256
2257         return 0;
2258 }