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