2 * Copyright (C) Volition, Inc. 1999. All rights reserved.
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
10 * $Logfile: /Freespace2/code/MissionUI/MissionBrief.cpp $
15 * C module that contains code to display the mission briefing to the player
18 * Revision 1.13 2005/10/03 11:25:42 taylor
19 * be sure to properly clean out old briefing entries when compacting
21 * Revision 1.12 2005/10/01 22:04:58 taylor
22 * fix FS1 (de)briefing voices, the directory names are different in FS1
23 * hard code the table values so that the fs1.vp file isn't needed
24 * hard code a mission fix for sm2-08a since a have no idea how to fix it otherwise
25 * generally cleanup some FS1 code
26 * fix volume sliders in the options screen that never went all the way up
28 * Revision 1.11 2005/08/12 08:58:41 taylor
29 * fix the strange mouse click issues on briefing, ship select and weapon select screens
31 * Revision 1.10 2005/03/29 02:18:47 taylor
32 * Various 64-bit platform fixes
33 * Fix compiler errors with MAKE_FS1 and fix gr_set_bitmap() too
34 * Make sure that turrets can fire at asteroids for FS1 (needed for a couple missions)
35 * Streaming audio support (big thanks to Pierre Willenbrock!!)
36 * Removed dependance on strings.tbl for FS1 since we don't actually need it now
38 * Revision 1.9 2004/09/20 01:31:44 theoddone33
41 * Revision 1.8 2004/07/04 11:31:43 taylor
42 * amd64 support, compiler warning fixes, don't use software rendering
44 * Revision 1.7 2003/05/25 02:30:43 taylor
47 * Revision 1.6 2003/01/30 19:55:33 relnev
48 * remove second bmpman.h include (Taylor Richards)
50 * Revision 1.5 2002/06/17 06:33:09 relnev
51 * ryan's struct patch for gcc 2.95
53 * Revision 1.4 2002/06/09 04:41:22 relnev
54 * added copyright header
56 * Revision 1.3 2002/06/02 04:26:34 relnev
59 * Revision 1.2 2002/05/07 03:16:46 theoddone33
60 * The Great Newline Fix
62 * Revision 1.1.1.1 2002/05/03 03:28:10 root
66 * 48 10/14/99 2:51p Jefff
69 * 47 10/13/99 3:23p Jefff
70 * fixed unnumbered XSTRs
72 * 46 9/12/99 8:09p Dave
73 * Fixed problem where skip-training button would cause mission messages
74 * not to get paged out for the current mission.
76 * 45 9/09/99 3:40p Jefff
77 * no exit loop outisde of campaign mode
79 * 44 9/07/99 6:53p Jefff
80 * functionality to break out of a loop
82 * 43 9/06/99 6:38p Dave
83 * Improved CD detection code.
85 * 42 9/03/99 10:57a Jefff
88 * 41 8/30/99 5:30p Jefff
89 * fixed "more" being cut off in d3d
91 * 40 8/30/99 10:29a Jefff
92 * added autocenter flag to closup rendering
94 * 39 8/19/99 11:33a Dave
97 * 38 8/19/99 10:59a Dave
98 * Packet loss detection.
100 * 37 8/16/99 4:05p Dave
101 * Big honking checkin.
103 * 36 8/16/99 9:48a Jefff
104 * all clicks on briefing icons should now register
106 * 35 8/10/99 7:29p Jefff
107 * added mission title to briefing screen
109 * 34 8/03/99 1:34a Andsager
110 * fix skip training mission (again)
112 * 33 8/02/99 12:01p Jefff
113 * fixed "skip training" text pos
115 * 32 7/30/99 5:42p Jasenw
116 * Fixed coords for skip training button.
118 * 31 7/29/99 10:50p Dave
119 * Oops. Accidentally blew away some interface text changes.
121 * 30 7/29/99 10:48p Dave
123 * 29 7/29/99 3:05p Andsager
124 * Add skip training text. and properly skip.
126 * 28 7/24/99 6:07p Jefff
127 * Added "lock" text to multiplayer lock button
129 * 27 7/21/99 10:51a Jefff
130 * added "more" indicator to briefing text box
132 * 26 7/19/99 3:01p Dave
133 * Fixed icons. Added single transport icon.
135 * 25 7/18/99 5:20p Dave
136 * Jump node icon. Fixed debris fogging. Framerate warning stuff.
138 * 24 7/16/99 1:49p Dave
139 * 8 bit aabitmaps. yay.
141 * 23 7/15/99 9:20a Andsager
142 * FS2_DEMO initial checkin
144 * 22 7/09/99 5:54p Dave
145 * Seperated cruiser types into individual types. Added tons of new
146 * briefing icons. Campaign screen.
148 * 21 6/29/99 7:39p Dave
149 * Lots of small bug fixes.
151 * 20 6/11/99 11:13a Dave
152 * last minute changes before press tour build.
154 * 19 6/04/99 1:18p Dave
155 * Fixed briefing model rendering problems. Made show background option in
156 * fred toggle nebula rendering.
158 * 18 5/07/99 10:34a Andsager
159 * Make red alert work in FS2
161 * 17 4/23/99 12:01p Johnson
162 * Added SIF_HUGE_SHIP
164 * 16 3/25/99 2:45p Neilk
167 * 15 2/11/99 3:08p Dave
168 * PXO refresh button. Very preliminary squad war support.
170 * 14 2/05/99 7:19p Neilk
171 * Removed black part from mission screen, fixed info text coords
173 * 13 2/02/99 4:35p Neilk
174 * fixed coordinate problem where primary goals was on top of interface in
177 * 12 2/01/99 5:55p Dave
178 * Removed the idea of explicit bitmaps for buttons. Fixed text
179 * highlighting for disabled gadgets.
181 * 11 1/30/99 7:32p Neilk
182 * Fixed coords problems for mission briefing screens
184 * 10 1/30/99 5:08p Dave
185 * More new hi-res stuff.Support for nice D3D textures.
187 * 9 1/30/99 1:29a Dave
188 * Fixed nebula thumbnail problem. Full support for 1024x768 choose pilot
189 * screen. Fixed beam weapon death messages.
191 * 8 1/29/99 4:17p Dave
192 * New interface screens.
194 * 7 1/13/99 7:19p Neilk
195 * Converted Mission Brief, Barracks, Synch to high res support
197 * 6 12/18/98 1:13a Dave
198 * Rough 1024x768 support for Direct3D. Proper detection and usage through
201 * 5 11/30/98 1:07p Dave
202 * 16 bit conversion, first run.
204 * 4 11/20/98 4:08p Dave
205 * Fixed flak effect in multiplayer.
207 * 3 10/13/98 9:28a Dave
208 * Started neatening up freespace.h. Many variables renamed and
209 * reorganized. Added AlphaColors.[h,cpp]
211 * 2 10/07/98 10:53a Dave
214 * 1 10/07/98 10:49a Dave
216 * 114 9/17/98 3:08p Dave
217 * PXO to non-pxo game warning popup. Player icon stuff in create and join
218 * game screens. Upped server count refresh time in PXO to 35 secs (from
221 * 113 6/19/98 3:52p Lawrance
222 * Don't use large text in popup, since it is missing large foreign chars
224 * 112 6/09/98 5:17p Lawrance
225 * French/German localization
227 * 111 6/09/98 10:31a Hoffoss
228 * Created index numbers for all xstr() references. Any new xstr() stuff
229 * added from here on out should be added to the end if the list. The
230 * current list count can be found in FreeSpace.cpp (search for
233 * 110 6/01/98 11:43a John
234 * JAS & MK: Classified all strings for localization.
236 * 109 5/22/98 10:44a Lawrance
237 * put in case label to suppress warning
239 * 108 5/19/98 11:35p Lawrance
240 * Play sound for briefing control button presses
242 * 107 5/19/98 8:47p Lawrance
243 * Set proper distance for jump nodes
245 * 106 5/19/98 8:35p Dave
246 * Revamp PXO channel listing system. Send campaign goals/events to
247 * clients for evaluation. Made lock button pressable on all screens.
249 * 105 5/12/98 2:16p Hoffoss
250 * Added debug code to switch models of closeup icon to more easily check
251 * positions and zooms.
253 * 104 5/06/98 11:50p Lawrance
254 * Clean up help overlay code for loadout screens
256 * 103 5/06/98 8:03p Allender
257 * AL: only free pointers in brief_compact_stages if non-null
259 * 102 5/05/98 4:48p Lawrance
260 * Fix bug with launching closeup icon when pause button is pressed
262 * 101 4/29/98 1:45p Lawrance
263 * Print out mission filename if debug build, or if INTERPLAY QA defined
265 * 100 4/29/98 12:15a Lawrance
266 * reset demo trailer timer when briefing moves to a new stage
268 * 98 4/25/98 11:55p Lawrance
269 * fix bug with the auto-advance button
271 * 97 4/25/98 3:49p Lawrance
272 * Save briefing auto-advance pref
274 * 96 4/25/98 12:00p Lawrance
275 * disable advance keypress for 1/2 second after autoadvance
277 * 95 4/22/98 7:24p Dave
278 * Made sure the "player/ships" locked button for multiplayer appears on
279 * all briefing screens.
281 * 94 4/20/98 3:53p Lawrance
282 * Fix various bugs with auto-advancing through briefings.
284 * 93 4/19/98 12:11p Lawrance
285 * add new art for pause button in the briefing
287 * 92 4/17/98 10:39p Andsager
288 * AL: Fix bug with auto-advance of briefing stages.
290 * 91 4/16/98 8:05p Lawrance
291 * Don't show closeup icon for planets
293 * 90 4/15/98 5:17p Lawrance
294 * fix bug with skip training
300 #include "freespace.h"
301 #include "missionload.h"
302 #include "missionscreencommon.h"
303 #include "missionshipchoice.h"
304 #include "missionparse.h"
305 #include "missiongoals.h"
306 #include "gamesequence.h"
315 #include "linklist.h"
320 #include "audiostr.h"
322 #include "eventmusic.h"
323 #include "missioncampaign.h"
326 #include "snazzyui.h"
328 #include "missionbrief.h"
329 #include "missionbriefcommon.h"
330 #include "missiongrid.h"
331 #include "multimsgs.h"
333 #include "contexthelp.h"
335 #include "multiteamselect.h"
337 #include "asteroid.h"
340 #include "alphacolors.h"
342 #include "missionmessage.h"
345 #define OBJECTIVES_X 65
346 #define OBJECTIVES_Y 137
347 #define OBJECTIVES_W 508
348 #define OBJECTIVES_H 233
351 static int Brief_goals_coords[GR_NUM_RESOLUTIONS][4] = {
356 65,152,508,211 // GR_640
360 104,243,813,332 // GR_1024
364 static int Current_brief_stage; // what stage of the briefing we're on
365 static int Last_brief_stage;
366 static int Num_brief_stages;
367 static int Brief_multiplayer = FALSE;
369 static int Brief_last_auto_advance = 0; // timestamp of last auto-advance
371 // for managing the scene cut transition
372 static int Quick_transition_stage;
373 static int Start_fade_up_anim, Start_fade_down_anim;
374 static int Brief_playing_fade_sound;
377 int Briefing_music_handle = -1;
378 int Briefing_music_begin_timestamp = 0;
380 // --------------------------------------------------------------------------------------
381 // Module scope globals
382 // --------------------------------------------------------------------------------------
384 static MENU_REGION Briefing_select_region[NUM_BREIFING_REGIONS];
385 static int Num_briefing_regions;
387 // For closeup display
388 #define ONE_REV_TIME 6 // time (sec) for one revolution
389 #define MAX_ANG_CHG 0.15f
391 static int Closeup_coords[GR_NUM_RESOLUTIONS][4] = {
393 203, 151, 200, 213 // GR_640
396 325, 241, 200, 213 // GR_1024
400 static int Brief_infobox_coords[GR_NUM_RESOLUTIONS][2] = {
413 static const char *Brief_infobox_filename[GR_NUM_RESOLUTIONS] = {
418 static const char *Brief_filename[GR_NUM_RESOLUTIONS] = {
423 static const char *Brief_multi_filename[GR_NUM_RESOLUTIONS] = {
425 "Brief", // use the standard bitmap and slap the chatbox on later
432 static const char *Brief_mask_filename[GR_NUM_RESOLUTIONS] = {
437 static const char *Brief_multi_mask_filename[GR_NUM_RESOLUTIONS] = {
443 static const char *Brief_win_filename[GR_NUM_RESOLUTIONS] = {
453 // coordinate inidices
454 #define BRIEF_X_COORD 0
455 #define BRIEF_Y_COORD 1
456 #define BRIEF_W_COORD 2
457 #define BRIEF_H_COORD 3
459 //static int Closeup_region[4] = {220,132,420,269};
460 int Closeup_region[GR_NUM_RESOLUTIONS][4] = {
469 const char *Closeup_background_filename[GR_NUM_RESOLUTIONS] = {
470 NOX("BriefPop"), // GR_640
471 NOX("2_BriefPop") // GR_1024
474 const char *Closeup_button_filename[GR_NUM_RESOLUTIONS] = {
475 NOX("BPB_00"), // GR_640
476 NOX("2_BPB_00"), // GR_1024
479 int Closeup_button_hotspot = 14;
481 //static int Closeup_button_coords[2] = {CLOSEUP_X+164,CLOSEUP_Y+227};
482 int Closeup_button_coords[GR_NUM_RESOLUTIONS][2] = {
486 { 374, 316 }, // GR_640
488 { 599, 506 } // GR_1024
491 UI_BUTTON Closeup_close_button;
492 int Closeup_bitmap=-1;
493 int Closeup_one_revolution_time=ONE_REV_TIME;
495 brief_icon *Closeup_icon;
496 angles Closeup_angles;
497 matrix Closeup_orient;
499 int Closeup_font_height;
500 int Closeup_x1, Closeup_y1;
502 // used for the 3d view of a closeup ship
504 vector Closeup_cam_pos;
506 // Mask bitmap pointer and Mask bitmap_id
507 bitmap* BriefingMaskPtr; // bitmap pointer to the briefing select mask bitmap
508 ubyte* BriefingMaskData; // pointer to actual bitmap data
509 int Briefing_mask_w, Briefing_mask_h;
510 int BriefingMaskBitmap; // bitmap id of the briefing mask bitmap
511 int Brief_inited = FALSE;
513 // --------------------------------------------------------------------------------------
514 // Briefing specific UI
515 // --------------------------------------------------------------------------------------
516 #define BRIEF_LAST_STAGE_MASK 7
517 #define BRIEF_NEXT_STAGE_MASK 8
518 #define BRIEF_PREV_STAGE_MASK 9
519 #define BRIEF_FIRST_STAGE_MASK 10
520 #define BRIEF_TEXT_SCROLL_UP_MASK 11
521 #define BRIEF_TEXT_SCROLL_DOWN_MASK 12
522 #define BRIEF_SKIP_TRAINING_MASK 15
523 #define BRIEF_PAUSE_MASK 16
526 static const char *Brief_mask_single[GR_NUM_RESOLUTIONS] = {
528 "2_brief-m" // GR_1024
531 static const char *Brief_mask_multi[GR_NUM_RESOLUTIONS] = {
532 "briefmulti-m", // GR_640
533 "2_briefmulti-m" // GR_1024
537 struct brief_buttons {
538 const char *filename;
543 UI_BUTTON button; // because we have a class inside this struct, we need the constructor below..
545 brief_buttons(const 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) {}
548 int Brief_grid_bitmap = -1;
549 int Brief_text_bitmap = -1;
551 int Brief_multitext_bitmap = -1;
552 int Brief_background_bitmap =-1;
555 static int MapWin01 = -1;
556 static int MapWin02 = -1;
557 static int MapWin03 = -1;
558 static int MapWin04 = -1;
561 UI_WINDOW Brief_ui_window;
563 // Briefing specific buttons
564 #define NUM_BRIEF_BUTTONS 10
566 brief_buttons Brief_buttons[GR_NUM_RESOLUTIONS][NUM_BRIEF_BUTTONS] = {
569 brief_buttons("BRB_08", 356, 351, -1, -1, 8), // vcr - fastforward
570 brief_buttons("BRB_09", 331, 351, -1, -1, 9), // vcr - play forwards
571 brief_buttons("BRB_10", 277, 351, -1, -1, 10), // vcr - play backwards
572 brief_buttons("BRB_11", 253, 351, -1, -1, 11), // vcr - reverse
573 brief_buttons("BRB_12", 0, 400, -1, -1, 12), // scroll up
574 brief_buttons("BRB_13", 0, 442, -1, -1, 13), // scroll down
575 brief_buttons("BRB_15", 562, 0, -1, -1, 15), // skip training
576 brief_buttons("BRB_16", 304, 351, -1, -1, 16), // vcr - pause
577 brief_buttons("TSB_34", 601, 344, -1, -1, 50), // multi lock
578 brief_buttons("BRB_15", 562, 0, -1, -1, 15) // exit loop
580 brief_buttons("BRB_08", 110, 116, 117, 157, 8),
581 brief_buttons("BRB_09", 84, 116, 117, 157, 9),
582 brief_buttons("BRB_10", 29, 116, 117, 157, 10),
583 brief_buttons("BRB_11", 4, 116, 117, 157, 11),
584 brief_buttons("BRB_12", 0, 405, 117, 157, 12),
585 brief_buttons("BRB_13", 0, 447, 117, 157, 13),
586 brief_buttons("BRB_15", 562, 0, 117, 157, 15), // skip training
587 brief_buttons("BRB_16", 56, 116, 117, 157, 16),
588 brief_buttons("TSB_34", 603, 374, 117, 157, 34),
589 brief_buttons("BRB_15", 562, 0, 117, 157, 15) // exit loop
593 brief_buttons("2_BRB_08", 175, 187, 117, 157, 8),
594 brief_buttons("2_BRB_09", 135, 187, 117, 157, 9),
595 brief_buttons("2_BRB_10", 47, 187, 117, 157, 10),
596 brief_buttons("2_BRB_11", 8, 187, 117, 157, 11),
597 brief_buttons("2_BRB_12", 0, 649, 117, 157, 12),
598 brief_buttons("2_BRB_13", 0, 716, 117, 157, 13),
599 brief_buttons("2_BRB_15", 900, 0, 117, 157, 15), // skip training
600 brief_buttons("2_BRB_16", 91, 187, 117, 157, 16),
601 brief_buttons("2_TSB_34", 966, 599, 117, 157, 34),
602 brief_buttons("2_BRB_15", 900, 0, 117, 157, 15) // exit loop
608 #define BRIEF_SELECT_NUM_TEXT 3
610 UI_XSTR Brief_select_text[GR_NUM_RESOLUTIONS][BRIEF_SELECT_NUM_TEXT] = {
612 { "Lock", 1270, 602, 364, UI_XSTR_COLOR_GREEN, -1, &Brief_buttons[0][BRIEF_BUTTON_MULTI_LOCK].button },
613 { "Skip Training", 1442, 467, 7, UI_XSTR_COLOR_GREEN, -1, &Brief_buttons[0][BRIEF_BUTTON_SKIP_TRAINING].button },
614 { "Exit Loop", 1477, 490, 7, UI_XSTR_COLOR_GREEN, -1, &Brief_buttons[0][BRIEF_BUTTON_EXIT_LOOP].button }
617 { "Lock", 1270, 964, 584, UI_XSTR_COLOR_GREEN, -1, &Brief_buttons[1][BRIEF_BUTTON_MULTI_LOCK].button },
618 { "Skip Training", 1442, 805, 12, UI_XSTR_COLOR_GREEN, -1, &Brief_buttons[1][BRIEF_BUTTON_SKIP_TRAINING].button },
619 { "Exit Loop", 1477, 830, 12, UI_XSTR_COLOR_GREEN, -1, &Brief_buttons[1][BRIEF_BUTTON_EXIT_LOOP].button }
624 // coordinates for briefing title -- the x value is for the RIGHT side of the text
625 static int Title_coords[GR_NUM_RESOLUTIONS][2] = {
629 {575, 117}, // GR_640
631 {918, 194} // GR_1024
634 // coordinates for briefing title in multiplayer briefings -- the x value is for the LEFT side of the text
635 // third coord is max width of area for it to fit into (it is force fit there)
636 static int Title_coords_multi[GR_NUM_RESOLUTIONS][3] = {
640 {1, 105, 190}, // GR_640
642 {1, 174, 304} // GR_1024
645 // briefing line widths
646 int Brief_max_line_width[GR_NUM_RESOLUTIONS] = {
647 MAX_BRIEF_LINE_W_640, MAX_BRIEF_LINE_W_1024
650 // --------------------------------------------------------------------------------------
651 // Forward declarations
652 // --------------------------------------------------------------------------------------
653 int brief_setup_closeup(brief_icon *bi);
654 void brief_maybe_blit_scene_cut(float frametime);
655 void brief_transition_reset();
657 const char *brief_tooltip_handler(const char *str)
659 if (!SDL_strcasecmp(str, NOX("@close"))) {
661 return XSTR( "Close", 428);
667 static void skip_training_callback(int choice)
672 // do nothing, user hit 'No' or aborted the popup window
676 // page out mission messages
677 message_mission_shutdown();
679 if ( !(Game_mode & GM_CAMPAIGN_MODE) ){
680 gameseq_post_event( GS_EVENT_MAIN_MENU );
683 // tricky part. Need to move to the next mission in the campaign.
684 mission_goal_mark_objectives_complete();
685 mission_goal_fail_incomplete();
686 mission_campaign_store_goals_and_events();
688 mission_campaign_eval_next_mission();
689 mission_campaign_mission_over();
691 gameseq_post_event( GS_EVENT_START_GAME );
694 // brief_skip_training_pressed()
696 // called when the skip training button on the briefing screen is hit. When this happens,
697 // do a popup, then move to the next mission in the campaign.
698 void brief_skip_training_pressed()
700 popup_callback(skip_training_callback, 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));
703 #if defined(FS2_DEMO) || defined(FS1_DEMO)
704 extern void demo_reset_trailer_timer();
706 // --------------------------------------------------------------------------------------
707 // brief_do_next_pressed()
710 void brief_do_next_pressed(int play_sound)
713 now = timer_get_milliseconds();
715 if ( (now - Brief_last_auto_advance) < 500 ) {
719 #if defined(FS2_DEMO) || defined(FS1_DEMO)
720 demo_reset_trailer_timer();
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();
731 gamesnd_play_iface(SND_BRIEF_STAGE_CHG);
735 SDL_assert(Current_brief_stage >= 0);
738 // --------------------------------------------------------------------------------------
739 // brief_do_prev_pressed()
742 void brief_do_prev_pressed()
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();
751 gamesnd_play_iface(SND_BRIEF_STAGE_CHG);
753 SDL_assert(Current_brief_stage >= 0);
757 // --------------------------------------------------------------------------------------
758 // brief_do_start_pressed()
761 void brief_do_start_pressed()
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();
769 gamesnd_play_iface(SND_GENERAL_FAIL);
771 SDL_assert(Current_brief_stage >= 0);
774 // --------------------------------------------------------------------------------------
775 // brief_do_end_pressed()
778 void brief_do_end_pressed()
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();
787 gamesnd_play_iface(SND_GENERAL_FAIL);
789 SDL_assert(Current_brief_stage >= 0);
793 void brief_scroll_up_text()
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);
800 gamesnd_play_iface(SND_SCROLL);
804 void brief_scroll_down_text()
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);
811 gamesnd_play_iface(SND_SCROLL);
815 static void exit_loop_callback(int choice)
819 // bail if esc hit or no clicked
824 // handle the details
825 // this also posts the start game event
826 mission_campaign_exit_loop();
829 // handles the exit loop option
830 void brief_exit_loop_pressed()
832 popup_callback(exit_loop_callback, 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));
836 // -------------------------------------------------------------------------------------
837 // brief_select_button_do() do the button action for the specified pressed button
839 void brief_button_do(int i)
842 case BRIEF_BUTTON_LAST_STAGE:
843 brief_do_end_pressed();
846 case BRIEF_BUTTON_NEXT_STAGE:
847 brief_do_next_pressed(1);
850 case BRIEF_BUTTON_PREV_STAGE:
851 brief_do_prev_pressed();
854 case BRIEF_BUTTON_FIRST_STAGE:
855 brief_do_start_pressed();
858 case BRIEF_BUTTON_SCROLL_UP:
859 brief_scroll_up_text();
862 case BRIEF_BUTTON_SCROLL_DOWN:
863 brief_scroll_down_text();
866 case BRIEF_BUTTON_PAUSE:
867 gamesnd_play_iface(SND_USER_SELECT);
868 Player->auto_advance ^= 1;
871 case BRIEF_BUTTON_SKIP_TRAINING:
872 brief_skip_training_pressed();
875 case BRIEF_BUTTON_EXIT_LOOP:
876 brief_exit_loop_pressed();
879 case BRIEF_BUTTON_MULTI_LOCK:
880 SDL_assert(Game_mode & GM_MULTIPLAYER);
881 // the "lock" button has been pressed
882 multi_ts_lock_pressed();
884 // disable the button if it is now locked
885 if(multi_ts_is_locked()){
886 Brief_buttons[gr_screen.res][BRIEF_BUTTON_MULTI_LOCK].button.disable();
892 // -------------------------------------------------------------------
893 // brief_check_buttons()
895 // Iterate through the briefing buttons, checking if they are pressed
897 void brief_check_buttons()
902 for (i=0; i<NUM_BRIEF_BUTTONS; i++) {
903 b = &Brief_buttons[gr_screen.res][i].button;
904 if ( b->pressed() ) {
905 common_flash_button_init();
910 if (Closeup_close_button.pressed()) {
911 brief_turn_off_closeup_icon();
915 // -------------------------------------------------------------------
916 // brief_redraw_pressed_buttons()
918 // Redraw any briefing buttons that are pressed down. This function is needed
919 // since we sometimes need to draw pressed buttons last to ensure the entire
920 // button gets drawn (and not overlapped by other buttons)
922 void brief_redraw_pressed_buttons()
927 common_redraw_pressed_buttons();
929 for ( i = 0; i < NUM_BRIEF_BUTTONS; i++ ) {
930 b = &Brief_buttons[gr_screen.res][i].button;
931 if ( b->button_down() ) {
936 if ( !Player->auto_advance ) {
937 Brief_buttons[gr_screen.res][BRIEF_BUTTON_PAUSE].button.draw_forced(2);
941 void brief_buttons_init()
946 //if ( Briefing->num_stages <= 0 )
949 for ( i = 0; i < NUM_BRIEF_BUTTONS; i++ ) {
950 b = &Brief_buttons[gr_screen.res][i].button;
951 b->create( &Brief_ui_window, "", Brief_buttons[gr_screen.res][i].x, Brief_buttons[gr_screen.res][i].y, 60, 30, 0, 1 );
952 // set up callback for when a mouse first goes over a button
953 b->set_highlight_action( common_play_highlight_sound );
955 if ((i == BRIEF_BUTTON_SKIP_TRAINING) || (i == BRIEF_BUTTON_EXIT_LOOP)) {
956 b->set_bmaps(Brief_buttons[gr_screen.res][i].filename, 3, 0);
958 b->set_bmaps(Brief_buttons[gr_screen.res][i].filename);
960 b->link_hotspot(Brief_buttons[gr_screen.res][i].hotspot);
965 for(i=0; i<BRIEF_SELECT_NUM_TEXT; i++) {
966 Brief_ui_window.add_XSTR(&Brief_select_text[gr_screen.res][i]);
970 // Hide the 'skip training' button by default. Only enable and unhide if we are playing a training
972 Brief_buttons[gr_screen.res][BRIEF_BUTTON_SKIP_TRAINING].button.disable();
973 Brief_buttons[gr_screen.res][BRIEF_BUTTON_SKIP_TRAINING].button.hide();
974 if ( (Game_mode & GM_NORMAL) && (The_mission.game_type & MISSION_TYPE_TRAINING) ) {
975 Brief_buttons[gr_screen.res][BRIEF_BUTTON_SKIP_TRAINING].button.enable();
976 Brief_buttons[gr_screen.res][BRIEF_BUTTON_SKIP_TRAINING].button.unhide();
979 // Hide the 'exit loop' button by default. Only enable and unhide if we are playing a loop
981 Brief_buttons[gr_screen.res][BRIEF_BUTTON_EXIT_LOOP].button.disable();
982 Brief_buttons[gr_screen.res][BRIEF_BUTTON_EXIT_LOOP].button.hide();
983 if ( (Game_mode & GM_NORMAL) && (Campaign.loop_enabled) && (Game_mode & GM_CAMPAIGN_MODE) ) {
984 Brief_buttons[gr_screen.res][BRIEF_BUTTON_EXIT_LOOP].button.enable();
985 Brief_buttons[gr_screen.res][BRIEF_BUTTON_EXIT_LOOP].button.unhide();
988 // maybe disable the multi-lock button
989 if(!(Game_mode & GM_MULTIPLAYER)){
990 Brief_buttons[gr_screen.res][BRIEF_BUTTON_MULTI_LOCK].button.hide();
991 Brief_buttons[gr_screen.res][BRIEF_BUTTON_MULTI_LOCK].button.disable();
993 // if we're not the host of the game (or a tema captain in team vs. team mode), disable the lock button
994 if(Netgame.type_flags & NG_TYPE_TEAM){
995 if(!(Net_player->flags & NETINFO_FLAG_TEAM_CAPTAIN)){
996 Brief_buttons[gr_screen.res][BRIEF_BUTTON_MULTI_LOCK].button.disable();
999 if(!(Net_player->flags & NETINFO_FLAG_GAME_HOST)){
1000 Brief_buttons[gr_screen.res][BRIEF_BUTTON_MULTI_LOCK].button.disable();
1005 // create close button for closeup popup
1006 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 );
1007 Closeup_close_button.set_highlight_action( common_play_highlight_sound );
1008 Closeup_close_button.set_bmaps(Closeup_button_filename[gr_screen.res]);
1009 Closeup_close_button.link_hotspot(Closeup_button_hotspot);
1011 // set up hotkeys for buttons so we draw the correct animation frame when a key is pressed
1012 Brief_buttons[gr_screen.res][BRIEF_BUTTON_LAST_STAGE].button.set_hotkey(KEY_SHIFTED|SDLK_RIGHT);
1013 Brief_buttons[gr_screen.res][BRIEF_BUTTON_NEXT_STAGE].button.set_hotkey(SDLK_RIGHT);
1014 Brief_buttons[gr_screen.res][BRIEF_BUTTON_PREV_STAGE].button.set_hotkey(SDLK_LEFT);
1015 Brief_buttons[gr_screen.res][BRIEF_BUTTON_FIRST_STAGE].button.set_hotkey(KEY_SHIFTED|SDLK_LEFT);
1016 Brief_buttons[gr_screen.res][BRIEF_BUTTON_SCROLL_UP].button.set_hotkey(SDLK_UP);
1017 Brief_buttons[gr_screen.res][BRIEF_BUTTON_SCROLL_DOWN].button.set_hotkey(SDLK_DOWN);
1019 Closeup_close_button.disable();
1020 Closeup_close_button.hide();
1022 // if we have no briefing stages, hide and disable briefing buttons
1023 if(Num_brief_stages <= 0){
1024 Brief_buttons[gr_screen.res][BRIEF_BUTTON_LAST_STAGE].button.disable();
1025 Brief_buttons[gr_screen.res][BRIEF_BUTTON_LAST_STAGE].button.hide();
1026 Brief_buttons[gr_screen.res][BRIEF_BUTTON_NEXT_STAGE].button.disable();
1027 Brief_buttons[gr_screen.res][BRIEF_BUTTON_NEXT_STAGE].button.hide();
1028 Brief_buttons[gr_screen.res][BRIEF_BUTTON_PREV_STAGE].button.disable();
1029 Brief_buttons[gr_screen.res][BRIEF_BUTTON_PREV_STAGE].button.hide();
1030 Brief_buttons[gr_screen.res][BRIEF_BUTTON_FIRST_STAGE].button.disable();
1031 Brief_buttons[gr_screen.res][BRIEF_BUTTON_FIRST_STAGE].button.hide();
1032 Brief_buttons[gr_screen.res][BRIEF_BUTTON_SCROLL_UP].button.disable();
1033 Brief_buttons[gr_screen.res][BRIEF_BUTTON_SCROLL_UP].button.hide();
1034 Brief_buttons[gr_screen.res][BRIEF_BUTTON_SCROLL_DOWN].button.disable();
1035 Brief_buttons[gr_screen.res][BRIEF_BUTTON_SCROLL_DOWN].button.hide();
1036 Brief_buttons[gr_screen.res][BRIEF_BUTTON_PAUSE].button.disable();
1037 Brief_buttons[gr_screen.res][BRIEF_BUTTON_PAUSE].button.hide();
1041 // --------------------------------------------------------------------------------------
1042 // brief_get_closeup_icon()
1045 brief_icon *brief_get_closeup_icon()
1047 return Closeup_icon;
1050 // stop showing the closeup view of an icon
1051 void brief_turn_off_closeup_icon()
1054 if ( Closeup_icon != NULL ) {
1055 gamesnd_play_iface(SND_BRIEF_ICON_SELECT);
1056 Closeup_icon = NULL;
1057 Closeup_close_button.disable();
1058 Closeup_close_button.hide();
1062 // --------------------------------------------------------------------------------------
1063 // brief_load_bitmaps()
1066 void brief_load_bitmaps()
1068 Brief_text_bitmap = bm_load(Brief_infobox_filename[gr_screen.res]);
1069 Brief_grid_bitmap = bm_load(Brief_win_filename[gr_screen.res]);
1071 if ( Closeup_bitmap == -1 ) {
1072 Closeup_bitmap = bm_load(Closeup_background_filename[gr_screen.res]);
1076 MapWin01 = bm_load(NOX("MapWin01"));
1077 MapWin02 = bm_load(NOX("MapWin02"));
1078 MapWin03 = bm_load(NOX("MapWin03"));
1079 MapWin04 = bm_load(NOX("MapWin04"));
1083 // --------------------------------------------------------------------------------------
1087 void brief_ui_init()
1089 if(Game_mode & GM_MULTIPLAYER) {
1090 Brief_background_bitmap = bm_load(Brief_multi_filename[gr_screen.res]);
1092 Brief_background_bitmap = bm_load(Brief_filename[gr_screen.res]);
1095 if ( Num_brief_stages <= 0 ){
1099 brief_load_bitmaps();
1103 // --------------------------------------------------------------------------------------
1104 // brief_set_default_closeup()
1107 void brief_set_default_closeup()
1112 bs = &Briefing->stages[0];
1114 if ( Briefing->num_stages <= 0 ) {
1115 Closeup_icon = NULL;
1119 if ( bs->num_icons <= 0 ) {
1120 Closeup_icon = NULL;
1124 // check for the first highlighted icons to have as the default closeup
1125 for ( i = 0; i < bs->num_icons; i++ ) {
1126 if ( bs->icons[i].flags & BI_HIGHLIGHT )
1130 if ( i == bs->num_icons ) {
1131 brief_setup_closeup(&bs->icons[0]);
1134 brief_setup_closeup(&bs->icons[i]);
1138 // funciton to evaluate the sexpressions of the briefing stages eliminating those stages
1139 // which shouldn't get shown
1140 void brief_compact_stages()
1142 int num, before, result, i;
1145 if((Game_mode & GM_MULTIPLAYER) && (Netgame.campaign_mode == MP_CAMPAIGN) && !(Net_player->flags & NETINFO_FLAG_AM_MASTER)){
1146 Game_mode |= GM_CAMPAIGN_MODE;
1150 before = Briefing->num_stages;
1153 while ( num < Briefing->num_stages ) {
1154 result = eval_sexp( Briefing->stages[num].formula );
1156 if ( Briefing->stages[num].new_text ) {
1157 free( Briefing->stages[num].new_text );
1158 Briefing->stages[num].new_text = NULL;
1161 if ( Briefing->stages[num].icons ) {
1162 free( Briefing->stages[num].icons );
1163 Briefing->stages[num].icons = NULL;
1167 if ( Briefing->stages[num].lines ) {
1168 free( Briefing->stages[num].lines );
1169 Briefing->stages[num].lines = NULL;
1172 Briefing->stages[num].num_icons = 0;
1173 for ( i = num+1; i < Briefing->num_stages; i++ ) {
1174 Briefing->stages[i-1] = Briefing->stages[i];
1176 Briefing->num_stages--;
1182 // completely clear out the old entries (if any) so we don't access them by mistake - taylor
1183 if (before > Briefing->num_stages) {
1184 for (i = Briefing->num_stages; i < before; i++) {
1185 memset( &Briefing->stages[i], 0, sizeof(brief_stage) );
1190 if((Game_mode & GM_MULTIPLAYER) && (Netgame.campaign_mode == MP_CAMPAIGN) && !(Net_player->flags & NETINFO_FLAG_AM_MASTER)){
1191 Game_mode &= ~(GM_CAMPAIGN_MODE);
1197 // --------------------------------------------------------------------------------------
1200 int red_alert_mission(void);
1204 // Since first stage of briefing can take some time to arrive and play,
1205 // reset the trailer timer on briefing init.
1206 #if defined(FS2_DEMO) || defined(FS1_DEMO)
1207 demo_reset_trailer_timer();
1210 // for multiplayer, change the state in my netplayer structure
1211 // and initialize the briefing chat area thingy
1212 if ( Game_mode & GM_MULTIPLAYER ){
1213 Net_player->state = NETPLAYER_STATE_BRIEFING;
1216 // Non standard briefing in red alert mission
1217 if ( red_alert_mission() ) {
1218 gameseq_post_event(GS_EVENT_RED_ALERT);
1222 // get a pointer to the appropriate briefing structure
1223 if((Game_mode & GM_MULTIPLAYER) && (Netgame.type_flags & NG_TYPE_TEAM)){
1224 Briefing = &Briefings[Net_player->p_info.team];
1226 Briefing = &Briefings[0];
1229 Brief_last_auto_advance = 0;
1231 brief_compact_stages(); // compact the briefing array to eliminate unused stages
1233 common_set_interface_palette("BriefingPalette");
1235 ship_stop_animation();
1236 set_active_ui(&Brief_ui_window);
1237 Current_screen = ON_BRIEFING_SELECT;
1238 brief_restart_text_wipe();
1239 common_flash_button_init();
1240 common_music_init(SCORE_BRIEFING);
1243 help_overlay_set_state(BR_OVERLAY,0);
1245 if ( Brief_inited == TRUE ) {
1246 common_buttons_maybe_reload(&Brief_ui_window); // AL 11-21-97: this is necessary since we may returning from the hotkey
1247 // screen, which can release common button bitmaps.
1248 common_reset_buttons();
1249 nprintf(("Alan","brief_init() returning without doing anything\n"));
1253 if (The_mission.game_type & MISSION_TYPE_TRAINING)
1254 Num_brief_stages = Briefing->num_stages;
1256 Num_brief_stages = Briefing->num_stages + 1;
1258 Current_brief_stage = 0;
1259 Last_brief_stage = 0;
1261 // init the scene-cut data
1262 brief_transition_reset();
1264 #if !(defined(FS2_DEMO) || defined(FS1_DEMO))
1265 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]);
1266 hud_anim_load(&Fade_anim);
1269 nprintf(("Alan","Entering brief_init()\n"));
1270 common_select_init();
1272 if(Game_mode & GM_MULTIPLAYER) {
1273 BriefingMaskBitmap = bm_load(Brief_multi_mask_filename[gr_screen.res]);
1275 BriefingMaskBitmap = bm_load(Brief_mask_filename[gr_screen.res]);
1278 if (BriefingMaskBitmap < 0) {
1279 Error(LOCATION,"Could not load in 'brief-m'!");
1282 Briefing_mask_w = -1;
1283 Briefing_mask_h = -1;
1285 // get a pointer to bitmap by using bm_lock()
1286 BriefingMaskPtr = bm_lock(BriefingMaskBitmap, 8, BMP_AABITMAP);
1287 BriefingMaskData = (ubyte*)BriefingMaskPtr->data;
1288 bm_get_info(BriefingMaskBitmap, &Briefing_mask_w, &Briefing_mask_h);
1290 help_overlay_load(BR_OVERLAY);
1292 // Set up the mask regions
1293 // initialize the different regions of the menu that will react when the mouse moves over it
1294 Num_briefing_regions = 0;
1296 snazzy_menu_add_region(&Briefing_select_region[Num_briefing_regions++], "", COMMON_BRIEFING_REGION, 0);
1297 #ifndef FS1_DEMO // not available in demo
1298 snazzy_menu_add_region(&Briefing_select_region[Num_briefing_regions++], "", COMMON_SS_REGION, 0);
1299 snazzy_menu_add_region(&Briefing_select_region[Num_briefing_regions++], "", COMMON_WEAPON_REGION, 0);
1301 snazzy_menu_add_region(&Briefing_select_region[Num_briefing_regions++], "", COMMON_COMMIT_REGION, 0);
1302 snazzy_menu_add_region(&Briefing_select_region[Num_briefing_regions++], "", COMMON_HELP_REGION, 0);
1303 snazzy_menu_add_region(&Briefing_select_region[Num_briefing_regions++], "", COMMON_OPTIONS_REGION, 0);
1305 snazzy_menu_add_region(&Briefing_select_region[Num_briefing_regions++], "", BRIEF_LAST_STAGE_MASK, 0);
1306 snazzy_menu_add_region(&Briefing_select_region[Num_briefing_regions++], "", BRIEF_NEXT_STAGE_MASK, 0);
1307 snazzy_menu_add_region(&Briefing_select_region[Num_briefing_regions++], "", BRIEF_PREV_STAGE_MASK, 0);
1308 snazzy_menu_add_region(&Briefing_select_region[Num_briefing_regions++], "", BRIEF_FIRST_STAGE_MASK, 0);
1309 snazzy_menu_add_region(&Briefing_select_region[Num_briefing_regions++], "", BRIEF_TEXT_SCROLL_UP_MASK, 0);
1310 snazzy_menu_add_region(&Briefing_select_region[Num_briefing_regions++], "", BRIEF_TEXT_SCROLL_DOWN_MASK, 0);
1313 Brief_ui_window.create( 0, 0, gr_screen.max_w, gr_screen.max_h, 0 );
1315 if(Game_mode & GM_MULTIPLAYER){
1316 Brief_ui_window.set_mask_bmap(Brief_mask_multi[gr_screen.res]);
1318 Brief_ui_window.set_mask_bmap(Brief_mask_single[gr_screen.res]);
1321 Brief_ui_window.tooltip_handler = brief_tooltip_handler;
1322 common_buttons_init(&Brief_ui_window);
1323 brief_buttons_init();
1325 // if multiplayer, initialize a few other systems
1326 if(Game_mode & GM_MULTIPLAYER){
1327 // again, should not be necessary, but we'll leave it for now
1330 // force the chatbox to be small
1331 chatbox_force_small();
1334 // set up the screen regions
1335 brief_init_screen(Brief_multiplayer);
1337 // init briefing specific UI
1340 // init the briefing map
1343 // init the briefing voice playback
1345 brief_voice_load_all();
1347 // init objectives display stuff
1348 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]);
1350 // set the camera target
1351 if ( Briefing->num_stages > 0 ) {
1352 brief_set_new_stage(&Briefing->stages[0].camera_pos, &Briefing->stages[0].camera_orient, 0, Current_brief_stage);
1353 brief_reset_icons(Current_brief_stage);
1356 Brief_playing_fade_sound = 0;
1357 Brief_mouse_up_flag = 0;
1358 Closeup_font_height = gr_get_font_height();
1359 Closeup_icon = NULL;
1360 Brief_inited = TRUE;
1363 // -------------------------------------------------------------------------------------
1364 // brief_render_closeup_text()
1368 #define CLOSEUP_TEXT_OFFSET 2
1370 #define CLOSEUP_TEXT_OFFSET 10
1372 void brief_render_closeup_text()
1376 char line[MAX_ICON_TEXT_LINE_LEN];
1377 int n_lines, i, render_x, render_y;
1378 int n_chars[MAX_ICON_TEXT_LINES];
1379 char *p_str[MAX_ICON_TEXT_LINES];
1381 if ( Closeup_icon == NULL ) {
1388 render_x = Closeup_region[0];
1389 render_y = Closeup_region[1] + CLOSEUP_IMG_H;
1391 gr_set_clip(render_x+CLOSEUP_TEXT_OFFSET, render_y, CLOSEUP_W,CLOSEUP_TEXT_H);
1392 gr_set_color_fast(&Color_white);
1394 // n_lines = split_str(bi->text, CLOSEUP_W - 2*CLOSEUP_TEXT_OFFSET, n_chars, p_str, MAX_ICON_TEXT_LINES);
1395 SDL_assert(n_lines != -1);
1397 for ( i = 0; i < n_lines; i++ ) {
1398 SDL_assert(n_chars[i] < MAX_ICON_TEXT_LINE_LEN);
1399 strncpy(line, p_str[i], n_chars[i]);
1400 line[n_chars[i]] = 0;
1401 gr_printf(0,0+i*Closeup_font_height,line);
1406 // -------------------------------------------------------------------------------------
1407 // brief_render_closeup()
1410 void brief_render_closeup(int ship_class, float frametime)
1412 matrix view_orient = IDENTITY_MATRIX;
1420 if (Closeup_bitmap < 0)
1423 ang = PI2 * frametime/Closeup_one_revolution_time;
1424 if ( ang > MAX_ANG_CHG )
1427 Closeup_angles.h += ang;
1428 if ( Closeup_angles.h > PI2 )
1429 Closeup_angles.h -= PI2;
1430 vm_angles_2_matrix(&temp_matrix, &Closeup_angles );
1431 Closeup_orient = temp_matrix;
1433 w = Closeup_region[gr_screen.res][2];
1434 h = Closeup_region[gr_screen.res][3];
1435 gr_set_clip(Closeup_region[gr_screen.res][0], Closeup_region[gr_screen.res][1], w, h);
1439 g3_set_view_matrix(&Closeup_cam_pos, &view_orient, Closeup_zoom);
1440 model_clear_instance( Closeup_icon->modelnum );
1441 model_set_detail_level(0);
1443 int is_neb = The_mission.flags & MISSION_FLAG_FULLNEB;
1445 // maybe switch off nebula rendering
1447 The_mission.flags &= ~MISSION_FLAG_FULLNEB;
1450 int model_render_flags;
1451 if ( Closeup_icon->type == ICON_JUMP_NODE ) {
1452 model_set_outline_color(HUD_color_red, HUD_color_green, HUD_color_blue);
1453 model_render_flags = MR_NO_LIGHTING | MR_LOCK_DETAIL | MR_AUTOCENTER | MR_NO_POLYS | MR_SHOW_OUTLINE;
1455 model_render_flags = MR_NO_LIGHTING | MR_LOCK_DETAIL | MR_AUTOCENTER;
1458 model_render( Closeup_icon->modelnum, &Closeup_orient, &Closeup_pos, model_render_flags );
1461 The_mission.flags |= MISSION_FLAG_FULLNEB;
1466 gr_set_color_fast(&Color_bright_white);
1468 gr_printf(0x8000, CLOSEUP_TEXT_OFFSET, Closeup_icon->closeup_label);
1469 // brief_render_closeup_text();
1471 Closeup_close_button.enable();
1472 Closeup_close_button.unhide();
1477 // -------------------------------------------------------------------------------------
1480 // frametime is in seconds
1481 void brief_render(float frametime)
1486 if ( Num_brief_stages <= 0 ) {
1487 gr_set_color_fast(&Color_white);
1488 SDL_assert( Game_current_mission_filename != NULL );
1489 gr_printf(0x8000,200,XSTR( "No Briefing exists for mission: %s", 430), Game_current_mission_filename);
1492 gr_get_string_size(&w, &h, The_mission.name);
1493 gr_set_color_fast(&Color_normal);
1494 gr_printf(0x8000, 230, NOX("[filename: %s, last mod: %s]"), Mission_filename, The_mission.modified);
1500 gr_set_bitmap(Brief_grid_bitmap, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);
1501 gr_bitmap(Brief_bmap_coords[gr_screen.res][0], Brief_bmap_coords[gr_screen.res][1]);
1503 brief_render_map(Current_brief_stage, frametime);
1505 // draw the frame bitmaps
1506 gr_set_bitmap(Brief_text_bitmap, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);
1507 gr_bitmap(Brief_infobox_coords[gr_screen.res][0], Brief_infobox_coords[gr_screen.res][1]);
1508 brief_blit_stage_num(Current_brief_stage, Num_brief_stages);
1510 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);
1512 brief_voice_play(Current_brief_stage);
1515 // maybe output the "more" indicator
1516 if ( (Brief_text_max_lines[gr_screen.res] + Top_brief_text_line + 2) < Num_brief_text_lines[0] ) {
1517 // can be scrolled down
1518 int more_txt_x = Brief_text_coords[gr_screen.res][0] + (Brief_max_line_width[gr_screen.res]/2) - 10;
1519 int more_txt_y = Brief_text_coords[gr_screen.res][1] + Brief_text_coords[gr_screen.res][3] - 2; // located below brief text, centered
1520 gr_get_string_size(&w, &h, XSTR("more", 1469), strlen(XSTR("more", 1469)));
1521 gr_set_color_fast(&Color_black);
1522 gr_rect(more_txt_x-2, more_txt_y, w+3, h);
1523 gr_set_color_fast(&Color_red);
1524 gr_string(more_txt_x, more_txt_y, XSTR("more", 1469)); // base location on the input x and y?
1527 brief_maybe_blit_scene_cut(frametime);
1530 if (MapWin01 != -1) {
1531 gr_set_bitmap(MapWin01, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);
1535 if (MapWin02 != -1) {
1536 gr_set_bitmap(MapWin02, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);
1537 gr_bitmap(575, 122);
1540 if (MapWin03 != -1) {
1541 gr_set_bitmap(MapWin03, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);
1545 if (MapWin04 != -1) {
1546 gr_set_bitmap(MapWin04, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);
1551 #if !defined(NDEBUG) || defined(INTERPLAYQA)
1552 gr_set_color_fast(&Color_normal);
1553 int title_y_offset = (Game_mode & GM_MULTIPLAYER) ? 20 : 10;
1554 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);
1557 // output mission title
1559 gr_set_color_fast(&Color_bright_white);
1561 gr_set_color_fast(&Color_bright_blue);
1563 if (Game_mode & GM_MULTIPLAYER) {
1565 SDL_strlcpy(buf, The_mission.name, SDL_arraysize(buf));
1566 gr_force_fit_string(buf, 255, Title_coords_multi[gr_screen.res][2]);
1568 // align from the end of the string instead of the beginning
1569 gr_get_string_size(&w, NULL, buf);
1570 gr_string(Title_coords_multi[gr_screen.res][0] - w, Title_coords_multi[gr_screen.res][1], buf);
1572 gr_string(Title_coords_multi[gr_screen.res][0], Title_coords_multi[gr_screen.res][1], buf);
1575 gr_get_string_size(&w, NULL, The_mission.name);
1576 gr_string(Title_coords[gr_screen.res][0] - w, Title_coords[gr_screen.res][1], The_mission.name);
1579 // maybe do objectives
1580 if (Current_brief_stage == Briefing->num_stages) {
1581 ML_objectives_do_frame(0);
1585 // -------------------------------------------------------------------------------------
1586 // brief_set_closeup_pos()
1589 #define CLOSEUP_OFFSET 20
1590 void brief_set_closeup_pos(brief_icon *bi)
1593 Closeup_x1 = fl2i(320 - Closeup_coords[gr_screen.res][BRIEF_W_COORD]/2.0f + 0.5f);
1596 void brief_get_closeup_ship_modelnum(brief_icon *ci)
1601 // find the model number for the ship to display
1602 for ( objp = GET_FIRST(&obj_used_list); objp !=END_OF_LIST(&obj_used_list); objp = GET_NEXT(objp) ) {
1604 if ( objp == &obj_used_list || objp->type != OBJ_SHIP ) {
1608 sp = &Ships[objp->instance];
1609 if ( sp->ship_info_index == ci->ship_class ) {
1610 ci->ship_class = sp->ship_info_index;
1611 ci->modelnum = sp->modelnum;
1612 ci->radius = objp->radius;
1618 // cut any text off after (and including) '#' char
1619 void brief_truncate_label(char *src)
1621 char *pointer_to_last_char;
1623 pointer_to_last_char = strstr(src, NOX("#"));
1625 if ( pointer_to_last_char ) {
1626 *pointer_to_last_char = 0;
1630 // -------------------------------------------------------------------------------------
1631 // brief_setup_closeup()
1633 // exit: 0 => set-up icon sucessfully
1634 // -1 => could not setup closeup icon
1635 int brief_setup_closeup(brief_icon *bi)
1637 char pof_filename[NAME_LENGTH];
1638 ship_info *sip=NULL;
1642 Closeup_icon->ship_class = bi->ship_class;
1643 Closeup_icon->modelnum = -1;
1645 Closeup_one_revolution_time = ONE_REV_TIME;
1647 switch(Closeup_icon->type) {
1649 Closeup_icon = NULL;
1652 strcpy(pof_filename, NOX("planet.pof"));
1653 strcpy(Closeup_icon->closeup_label, XSTR("planet",-1));
1654 vm_vec_make(&Closeup_cam_pos, 0.0f, 0.0f, -8300.0f);
1655 Closeup_zoom = 0.5f;
1656 Closeup_one_revolution_time = ONE_REV_TIME * 3;
1659 case ICON_ASTEROID_FIELD:
1660 #if !(defined(FS2_DEMO) || defined(FS1_DEMO))
1661 SDL_strlcpy(pof_filename, Asteroid_info[ASTEROID_TYPE_BIG].pof_files[0], SDL_arraysize(pof_filename));
1662 SDL_strlcpy(Closeup_icon->closeup_label, XSTR( "asteroid", 431), SDL_arraysize(Closeup_icon->closeup_label));
1663 (void) vm_vec_make(&Closeup_cam_pos, 0.0f, 0.0f, -334.0f);
1664 Closeup_zoom = 0.5f;
1667 case ICON_JUMP_NODE:
1668 SDL_strlcpy(pof_filename, NOX("subspacenode.pof"), SDL_arraysize(pof_filename));
1669 SDL_strlcpy(Closeup_icon->closeup_label, XSTR( "jump node", 432), SDL_arraysize(Closeup_icon->closeup_label));
1670 (void) vm_vec_make(&Closeup_cam_pos, 0.0f, 0.0f, -2700.0f);
1671 Closeup_zoom = 0.5f;
1672 Closeup_one_revolution_time = ONE_REV_TIME * 3;
1675 case ICON_UNKNOWN_WING:
1676 SDL_strlcpy(pof_filename, NOX("unknownship.pof"), SDL_arraysize(pof_filename));
1677 SDL_strlcpy(Closeup_icon->closeup_label, XSTR( "unknown", 433), SDL_arraysize(Closeup_icon->closeup_label));
1678 (void) vm_vec_make(&Closeup_cam_pos, 0.0f, 0.0f, -22.0f);
1679 Closeup_zoom = 0.5f;
1682 brief_get_closeup_ship_modelnum(Closeup_icon);
1683 SDL_assert( Closeup_icon->ship_class != -1 );
1684 sip = &Ship_info[Closeup_icon->ship_class];
1686 SDL_strlcpy(Closeup_icon->closeup_label,sip->name, SDL_arraysize(Closeup_icon->closeup_label));
1688 // cut any text off after (and including) '#' char
1689 brief_truncate_label(Closeup_icon->closeup_label);
1691 if ( sip->flags & (SIF_SMALL_SHIP|SIF_BIG_SHIP|SIF_HUGE_SHIP|SIF_SENTRYGUN) ) {
1692 SDL_strlcat(Closeup_icon->closeup_label, XSTR( " class", 434), MAX_LABEL_LEN);
1697 if ( Closeup_icon->modelnum == -1 ) {
1698 if ( sip == NULL ) {
1699 Closeup_icon->modelnum = model_load(pof_filename, 0, NULL);
1701 Closeup_icon->modelnum = model_load(sip->pof_file, sip->n_subsystems, &sip->subsystems[0]);
1703 Closeup_icon->radius = model_get_radius(Closeup_icon->modelnum);
1706 vm_set_identity(&Closeup_orient);
1707 (void) vm_vec_make(&tvec, 0.0f, 0.0f, -1.0f);
1708 Closeup_orient.v.fvec = tvec;
1709 vm_vec_zero(&Closeup_pos);
1710 Closeup_angles.p = 0.0f;
1711 Closeup_angles.b = 0.0f;
1712 Closeup_angles.h = PI;
1714 brief_set_closeup_pos(bi);
1717 Closeup_cam_pos = sip->closeup_pos;
1718 Closeup_zoom = sip->closeup_zoom;
1724 // -------------------------------------------------------------------------------------
1725 // brief_update_closeup_icon()
1727 // input: mode => how to update the closeup view
1730 void brief_update_closeup_icon(int mode)
1734 int i, closeup_index;
1738 // mode 0 means disable the closeup icon
1739 if ( Closeup_icon != NULL ) {
1740 brief_turn_off_closeup_icon();
1745 if ( Closeup_icon == NULL )
1748 bs = &Briefing->stages[Current_brief_stage];
1751 // see if any icons are being highlighted this stage
1752 for ( i = 0; i < bs->num_icons; i++ ) {
1754 if ( bi->flags & BI_HIGHLIGHT ) {
1760 if ( closeup_index != -1 ) {
1761 bi = &bs->icons[closeup_index];
1762 brief_setup_closeup(bi);
1765 Closeup_icon = NULL;
1770 // -------------------------------------------------------------------------------------
1771 // brief_check_for_anim()
1774 void brief_check_for_anim()
1776 int mx, my, i, iw, ih, x, y;
1778 brief_icon *bi = NULL;
1780 bs = &Briefing->stages[Current_brief_stage];
1781 mouse_get_pos( &mx, &my );
1783 // if mouse click is over the VCR controls, don't launch an icon
1784 // FIXME - should prolly push these into defines instead of hardcoding this
1785 // if ( mx >= 0 && mx <= 115 && my >= 136 && my <= 148 ) {
1789 // same as above but without the hardcoded values, which were wrong anyway. don't know
1790 // how this will work longterm but will hopefully keep things working well - taylor
1791 for (i = 0; i <= BRIEF_BUTTON_FIRST_STAGE; i++) {
1792 Brief_buttons[gr_screen.res][i].button.get_dimensions(&x, &y, &iw, &ih);
1794 if (mx >= x && mx <= (x+iw) && my >= y && my <= (y+ih)) {
1799 // if mouse coords are outside the briefing screen, then go away
1800 my -= bscreen.map_y1;
1801 mx -= bscreen.map_x1;
1802 if ( my < 0 || mx < 0 || mx > (bscreen.map_x2-bscreen.map_x1+1) || my > (bscreen.map_y2-bscreen.map_y1+1) )
1805 for ( i = 0; i < bs->num_icons; i++ ) {
1807 brief_common_get_icon_dimensions(&iw, &ih, bi->type, bi->ship_class);
1808 if ( mx < bi->x ) continue;
1809 if ( mx > (bi->x + iw) ) continue;
1810 if ( my < bi->y ) continue;
1811 if ( my > (bi->y + ih) ) continue;
1812 // if we've got here, must be a hit
1816 if ( i == bs->num_icons ) {
1817 brief_turn_off_closeup_icon();
1821 if ( brief_setup_closeup(bi) == 0 ) {
1822 gamesnd_play_iface(SND_BRIEF_ICON_SELECT);
1824 gamesnd_play_iface(SND_GENERAL_FAIL);
1828 // maybe flash a button if player hasn't done anything for a while
1829 void brief_maybe_flash_button()
1833 if ( Num_brief_stages <= 0 )
1836 if ( Closeup_icon != NULL ) {
1837 common_flash_button_init();
1841 if ( common_flash_bright() ) {
1842 if ( Current_brief_stage == (Num_brief_stages-1) ) {
1844 // AL 4-4-98: Don't flash ship selection button on briefing in demo build
1845 #if defined(FS2_DEMO) || defined(FS1_DEMO)
1848 // AL 30-3-98: Don't flash ship selection button if in a training mission,
1849 if ( brief_only_allow_briefing() ) {
1853 b = &Common_buttons[Current_screen-1][gr_screen.res][1].button; // ship select button
1856 b = &Brief_buttons[gr_screen.res][1].button; // next stage button
1859 if ( b->button_hilighted() ) {
1860 common_flash_button_init();
1867 // -------------------------------------------------------------------------------------
1870 // frametime is in seconds
1872 void brief_do_frame(float frametime)
1874 int k, brief_choice;
1876 if ( red_alert_mission() ) {
1881 if ( !Brief_inited ){
1885 int snazzy_action = -1;
1886 brief_choice = snazzy_menu_do(BriefingMaskData, Briefing_mask_w, Briefing_mask_h, Num_briefing_regions, Briefing_select_region, &snazzy_action, 0);
1888 k = common_select_do(frametime);
1890 if ( Closeup_icon ) {
1891 Brief_mouse_up_flag = 0;
1894 if ( help_overlay_active(BR_OVERLAY) ) {
1895 common_flash_button_init();
1896 brief_turn_off_closeup_icon();
1899 // Check common keypresses
1900 common_check_keys(k);
1906 if ( Briefing->num_stages > 0 ) {
1908 // check for special keys
1912 case KEY_CTRLED | SDLK_PAGEUP: {
1913 if (Closeup_icon->ship_class) {
1914 Closeup_icon->ship_class--;
1916 ship_info *sip = &Ship_info[Closeup_icon->ship_class];
1917 if (sip->modelnum < 0)
1918 sip->modelnum = model_load(sip->pof_file, 0, NULL);
1920 mprintf(("Shiptype = %d (%s)\n", Closeup_icon->ship_class, sip->name));
1921 mprintf(("Modelnum = %d (%s)\n", sip->modelnum, sip->pof_file));
1922 brief_setup_closeup(Closeup_icon);
1928 case KEY_CTRLED | SDLK_PAGEDOWN: {
1929 if (Closeup_icon->ship_class < Num_ship_types - 1) {
1930 Closeup_icon->ship_class++;
1932 ship_info *sip = &Ship_info[Closeup_icon->ship_class];
1933 if (sip->modelnum < 0)
1934 sip->modelnum = model_load(sip->pof_file, 0, NULL);
1936 mprintf(("Shiptype = %d (%s)\n", Closeup_icon->ship_class, sip->name));
1937 mprintf(("Modelnum = %d (%s)\n", sip->modelnum, sip->pof_file));
1938 brief_setup_closeup(Closeup_icon);
1945 Closeup_cam_pos.xyz.z += 1;
1949 case SDLK_a + KEY_SHIFTED:
1950 Closeup_cam_pos.xyz.z += 10;
1955 Closeup_cam_pos.xyz.z -= 1;
1959 case SDLK_z + KEY_SHIFTED:
1960 Closeup_cam_pos.xyz.z -= 10;
1965 Closeup_cam_pos.xyz.y += 1;
1969 case SDLK_y + KEY_SHIFTED:
1970 Closeup_cam_pos.xyz.y += 10;
1975 Closeup_cam_pos.xyz.y -= 1;
1979 case SDLK_h + KEY_SHIFTED:
1980 Closeup_cam_pos.xyz.y -= 10;
1985 Closeup_zoom -= 0.1f;
1986 if ( Closeup_zoom < 0.1 )
1987 Closeup_zoom = 0.1f;
1991 case SDLK_COMMA+KEY_SHIFTED:
1992 Closeup_zoom -= 0.5f;
1993 if ( Closeup_zoom < 0.1 )
1994 Closeup_zoom = 0.1f;
1999 Closeup_zoom += 0.1f;
2003 case SDLK_PERIOD+KEY_SHIFTED:
2004 Closeup_zoom += 0.5f;
2008 case 1000: // need this to avoid warning about no case
2018 nprintf(("General","Camera pos: %.2f, %.2f %.2f // ", Closeup_cam_pos.xyz.x, Closeup_cam_pos.xyz.y, Closeup_cam_pos.xyz.z));
2019 nprintf(("General","Camera zoom: %.2f\n", Closeup_zoom));
2023 if ( brief_choice > -1 && snazzy_action == SNAZZY_OVER ) {
2024 Brief_mouse_up_flag = 0;
2029 common_check_buttons();
2030 // if ( Briefing->num_stages > 0 )
2031 brief_check_buttons();
2033 if ( brief_choice != -1 ) {
2034 Brief_mouse_up_flag = 0;
2039 common_render(frametime);
2041 if ( Current_brief_stage < (Num_brief_stages-1) ) {
2042 if ( !help_overlay_active(BR_OVERLAY) && brief_time_to_advance(Current_brief_stage, frametime) ) {
2043 brief_do_next_pressed(0);
2044 common_flash_button_init();
2045 Brief_last_auto_advance = timer_get_milliseconds();
2049 if ( !Background_playing ) {
2051 int check_jump_flag = 1;
2052 if ( Current_brief_stage != Last_brief_stage ) {
2054 // Check if we have a quick transition pending
2055 if ( Quick_transition_stage != -1 ) {
2056 Quick_transition_stage = -1;
2057 brief_reset_last_new_stage();
2059 check_jump_flag = 0;
2062 if ( check_jump_flag ) {
2063 if ( abs(Current_brief_stage - Last_brief_stage) > 1 ) {
2064 Quick_transition_stage = Current_brief_stage;
2065 Current_brief_stage = Last_brief_stage;
2066 SDL_assert(Current_brief_stage >= 0);
2067 Start_fade_up_anim = 1;
2068 goto Transition_done;
2073 if ( Current_brief_stage > Last_brief_stage ) {
2074 if ( Briefing->stages[Last_brief_stage].flags & BS_FORWARD_CUT ) {
2075 Quick_transition_stage = Current_brief_stage;
2076 Current_brief_stage = Last_brief_stage;
2077 SDL_assert(Current_brief_stage >= 0);
2078 Start_fade_up_anim = 1;
2079 goto Transition_done;
2081 time = Briefing->stages[Current_brief_stage].camera_time;
2085 if ( Briefing->stages[Last_brief_stage].flags & BS_BACKWARD_CUT ) {
2086 Quick_transition_stage = Current_brief_stage;
2087 Current_brief_stage = Last_brief_stage;
2088 SDL_assert(Current_brief_stage >= 0);
2089 Start_fade_up_anim = 1;
2090 goto Transition_done;
2092 time = Briefing->stages[Last_brief_stage].camera_time;
2097 brief_voice_stop(Last_brief_stage);
2099 if ( Current_brief_stage < 0 ) {
2101 Current_brief_stage=0;
2104 // set the camera target
2105 brief_set_new_stage(&Briefing->stages[Current_brief_stage].camera_pos,
2106 &Briefing->stages[Current_brief_stage].camera_orient,
2107 time, Current_brief_stage);
2109 Brief_playing_fade_sound = 0;
2110 Last_brief_stage = Current_brief_stage;
2111 brief_reset_icons(Current_brief_stage);
2112 brief_update_closeup_icon(0);
2117 if ( Brief_mouse_up_flag && !Closeup_icon) {
2118 brief_check_for_anim();
2121 brief_render(frametime);
2122 brief_camera_move(frametime, Current_brief_stage);
2124 if (Closeup_icon && (Closeup_bitmap >= 0)) {
2125 // blit closeup background
2126 gr_set_bitmap(Closeup_bitmap, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);
2127 gr_bitmap(Closeup_coords[gr_screen.res][BRIEF_X_COORD], Closeup_coords[gr_screen.res][BRIEF_Y_COORD]);
2130 Brief_ui_window.draw();
2131 brief_redraw_pressed_buttons();
2132 common_render_selected_screen_button();
2135 brief_render_closeup(Closeup_icon->ship_class, frametime);
2138 // render some extra stuff in multiplayer
2139 if (Game_mode & GM_MULTIPLAYER) {
2140 // should render this last so that it overlaps all controls
2143 // render the status indicator for the voice system
2144 multi_common_voice_display_status();
2146 // blit the "ships/players" locked button
2147 // multi_ts_blit_locked_button();
2149 // maybe blit the multiplayer "locked" button
2150 // if its locked, everyone blits it as such
2151 if(multi_ts_is_locked()){
2152 Brief_buttons[gr_screen.res][BRIEF_BUTTON_MULTI_LOCK].button.draw_forced(2);
2154 // anyone who can't hit the button sees it off, otherwise
2156 if( ((Netgame.type_flags & NG_TYPE_TEAM) && !(Net_player->flags & NETINFO_FLAG_TEAM_CAPTAIN)) ||
2157 ((Netgame.type_flags & NG_TYPE_TEAM) && !(Net_player->flags & NETINFO_FLAG_GAME_HOST)) ){
2158 Brief_buttons[gr_screen.res][BRIEF_BUTTON_MULTI_LOCK].button.draw_forced(0);
2160 Brief_buttons[gr_screen.res][BRIEF_BUTTON_MULTI_LOCK].button.draw();
2166 // maybe flash a button if player hasn't done anything for a while
2167 brief_maybe_flash_button();
2169 // blit help overlay if active
2170 help_overlay_maybe_blit(BR_OVERLAY);
2174 // If the commit button was pressed, do the commit button actions. Done at the end of the
2175 // loop so there isn't a skip in the animation (since ship_create() can take a long time if
2176 // the ship model is not in memory
2177 if (Commit_pressed) {
2178 if (Game_mode & GM_MULTIPLAYER) {
2179 multi_ts_commit_pressed();
2188 // --------------------------------------------------------------------------------------
2189 // brief_unload_bitmaps()
2192 void brief_unload_bitmaps()
2194 if ( BriefingMaskBitmap != -1 ) {
2195 bm_unload(BriefingMaskBitmap);
2196 BriefingMaskBitmap = -1;
2199 if ( Brief_text_bitmap != -1 ) {
2200 bm_unload(Brief_text_bitmap);
2201 Brief_text_bitmap = -1;
2204 if(Brief_grid_bitmap != -1){
2205 bm_unload(Brief_grid_bitmap);
2206 Brief_grid_bitmap = -1;
2209 if ( Brief_multitext_bitmap != -1 ) {
2210 bm_unload(Brief_multitext_bitmap);
2211 Brief_multitext_bitmap = -1;
2214 if ( Brief_background_bitmap != -1 ) {
2215 bm_unload(Brief_background_bitmap);
2216 Brief_background_bitmap = -1;
2220 if (MapWin01 != -1){
2221 bm_unload(MapWin01);
2225 if (MapWin02 != -1){
2226 bm_unload(MapWin02);
2230 if (MapWin03 != -1){
2231 bm_unload(MapWin03);
2235 if (MapWin04 != -1){
2236 bm_unload(MapWin04);
2241 help_overlay_unload(BR_OVERLAY);
2244 // ------------------------------------------------------------------------------------
2250 if ( Brief_inited == FALSE ) {
2251 nprintf(("Warning","brief_close() returning without doing anything\n"));
2255 nprintf(("Alan", "Entering brief_close()\n"));
2257 ML_objectives_close();
2259 // unload the audio streams used for voice playback
2260 brief_voice_unload_all();
2262 #if !(defined(FS2_DEMO) || defined(FS1_DEMO))
2263 hud_anim_release(&Fade_anim);
2266 // done mask bitmap, so unlock it
2267 bm_unlock(BriefingMaskBitmap);
2269 Brief_ui_window.destroy();
2273 common_free_interface_palette();
2276 // unload the bitmaps
2277 brief_unload_bitmaps();
2279 brief_common_close();
2281 Brief_inited = FALSE;
2284 void briefing_stop_music()
2286 if ( Briefing_music_handle != -1 ) {
2287 audiostream_close_file(Briefing_music_handle);
2288 Briefing_music_handle = -1;
2292 void briefing_load_music(const char* fname)
2294 if ( Cmdline_freespace_no_music ) {
2298 if ( Briefing_music_handle != -1 )
2302 Briefing_music_handle = audiostream_open( fname, ASF_EVENTMUSIC );
2305 void briefing_start_music()
2307 if ( Briefing_music_handle != -1 ) {
2308 if ( !audiostream_is_playing(Briefing_music_handle) )
2309 audiostream_play(Briefing_music_handle, Master_event_music_volume);
2312 nprintf(("Warning", "No music file exists to play music at this briefing!\n"));
2316 void brief_stop_voices()
2318 brief_voice_stop(Current_brief_stage);
2321 void brief_maybe_blit_scene_cut(float frametime)
2323 if ( Start_fade_up_anim ) {
2325 #if defined(FS2_DEMO) || defined(FS1_DEMO)
2326 Fade_anim.time_elapsed = 0.0f;
2327 Start_fade_up_anim = 0;
2328 Start_fade_down_anim = 1;
2329 Current_brief_stage = Quick_transition_stage;
2331 if ( Current_brief_stage < 0 ) {
2332 brief_transition_reset();
2333 Current_brief_stage = Last_brief_stage;
2335 goto Fade_down_anim_start;
2339 Fade_anim.time_elapsed += frametime;
2341 if ( !Brief_playing_fade_sound ) {
2342 gamesnd_play_iface(SND_BRIEFING_STATIC);
2343 Brief_playing_fade_sound = 1;
2346 if ( Fade_anim.time_elapsed > Fade_anim.total_time ) {
2347 Fade_anim.time_elapsed = 0.0f;
2348 Start_fade_up_anim = 0;
2349 Start_fade_down_anim = 1;
2350 Current_brief_stage = Quick_transition_stage;
2352 if ( Current_brief_stage < 0 ) {
2353 brief_transition_reset();
2354 Current_brief_stage = Last_brief_stage;
2357 SDL_assert(Current_brief_stage >= 0);
2358 goto Fade_down_anim_start;
2361 // draw the correct frame of animation
2362 framenum = fl2i( (Fade_anim.time_elapsed * Fade_anim.num_frames) / Fade_anim.total_time );
2365 if ( framenum >= Fade_anim.num_frames )
2366 framenum = Fade_anim.num_frames-1;
2368 // Blit the bitmap for this frame
2369 gr_set_bitmap(Fade_anim.first_frame + framenum, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);
2370 gr_bitmap(Fade_anim.sx, Fade_anim.sy);
2375 Fade_down_anim_start:
2376 if ( Start_fade_down_anim ) {
2378 #if defined(FS2_DEMO) || defined(FS1_DEMO)
2379 Fade_anim.time_elapsed = 0.0f;
2380 Start_fade_up_anim = 0;
2381 Start_fade_down_anim = 0;
2387 Fade_anim.time_elapsed += frametime;
2389 if ( Fade_anim.time_elapsed > Fade_anim.total_time ) {
2390 Fade_anim.time_elapsed = 0.0f;
2391 Start_fade_up_anim = 0;
2392 Start_fade_down_anim = 0;
2396 // draw the correct frame of animation
2397 framenum = fl2i( (Fade_anim.time_elapsed * Fade_anim.num_frames) / Fade_anim.total_time );
2400 if ( framenum >= Fade_anim.num_frames )
2401 framenum = Fade_anim.num_frames-1;
2403 // Blit the bitmap for this frame
2404 gr_set_bitmap(Fade_anim.first_frame + (Fade_anim.num_frames-1) - framenum, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);
2405 gr_bitmap(Fade_anim.sx, Fade_anim.sy);
2411 void brief_transition_reset()
2413 Quick_transition_stage = -1;
2414 Start_fade_up_anim = 0;
2415 Start_fade_down_anim = 0;
2416 Fade_anim.time_elapsed = 0.0f;
2419 // return 1 if this mission only allow players to use the briefing (and not ship or
2420 // weapon loadout). Otherwise return 0.
2421 int brief_only_allow_briefing()
2423 if ( The_mission.game_type & MISSION_TYPE_TRAINING ) {
2427 if ( The_mission.scramble || The_mission.red_alert) {