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