]> icculus.org git repositories - taylor/freespace2.git/blob - src/missionui/missioncmdbrief.cpp
GCC 3.4 fixes.
[taylor/freespace2.git] / src / missionui / missioncmdbrief.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/MissionCmdBrief.cpp $
11  * $Revision$
12  * $Date$
13  * $Author$
14  *
15  * Mission Command Briefing Screen
16  *
17  * $Log$
18  * Revision 1.6  2004/09/20 01:31:44  theoddone33
19  * GCC 3.4 fixes.
20  *
21  * Revision 1.5  2003/08/03 16:10:29  taylor
22  * cleanup; compile warning fixes
23  *
24  * Revision 1.4  2003/05/25 02:30:43  taylor
25  * Freespace 1 support
26  *
27  * Revision 1.3  2002/06/09 04:41:23  relnev
28  * added copyright header
29  *
30  * Revision 1.2  2002/05/07 03:16:46  theoddone33
31  * The Great Newline Fix
32  *
33  * Revision 1.1.1.1  2002/05/03 03:28:10  root
34  * Initial import.
35  *
36  * 
37  * 14    10/06/99 10:28a Jefff
38  * for OEM: cmd brief anim defaults to the default anim if load failure
39  * 
40  * 13    9/03/99 1:32a Dave
41  * CD checking by act. Added support to play 2 cutscenes in a row
42  * seamlessly. Fixed super low level cfile bug related to files in the
43  * root directory of a CD. Added cheat code to set campaign mission # in
44  * main hall.
45  * 
46  * 12    8/27/99 12:04a Dave
47  * Campaign loop screen.
48  * 
49  * 11    8/19/99 6:28p Jefff
50  * move animation in 640 a bit
51  * 
52  * 10    7/15/99 4:11p Andsager
53  * Leave command briefs in DEMO
54  * 
55  * 9     7/15/99 9:20a Andsager
56  * FS2_DEMO initial checkin
57  * 
58  * 8     7/09/99 10:32p Dave
59  * Command brief and red alert screens.
60  * 
61  * 7     2/08/99 5:06p Johnson
62  * Removed reference to a now non-existent palette.
63  * 
64  * 6     1/30/99 5:08p Dave
65  * More new hi-res stuff.Support for nice D3D textures.
66  * 
67  * 5     1/14/99 5:15p Neilk
68  * changed credits, command debrief interfaces to high resolution support
69  * 
70  * 4     10/16/98 9:40a Andsager
71  * Remove ".h" files from model.h
72  * 
73  * 3     10/13/98 9:28a Dave
74  * Started neatening up freespace.h. Many variables renamed and
75  * reorganized. Added AlphaColors.[h,cpp]
76  * 
77  * 2     10/07/98 10:53a Dave
78  * Initial checkin.
79  * 
80  * 1     10/07/98 10:49a Dave
81  * 
82  * 42    6/09/98 10:31a Hoffoss
83  * Created index numbers for all xstr() references.  Any new xstr() stuff
84  * added from here on out should be added to the end if the list.  The
85  * current list count can be found in FreeSpace.cpp (search for
86  * XSTR_SIZE).
87  * 
88  * 41    6/05/98 9:54a Lawrance
89  * OEM changes
90  * 
91  * 40    6/01/98 11:43a John
92  * JAS & MK:  Classified all strings for localization.
93  * 
94  * 39    5/26/98 11:10a Lawrance
95  * Fix bug where window controls get disabled when F1 pressed twice
96  * 
97  * 38    5/23/98 10:38p Lawrance
98  * Avoid doing a cfile refresh when running debug
99  * 
100  * 37    5/23/98 6:49p Lawrance
101  * Fix problems with refreshing the file list when a CD is inserted
102  * 
103  * 36    5/22/98 11:15a Lawrance
104  * Tweak how CD gets asked for
105  * 
106  * 35    5/21/98 6:57p Lawrance
107  * Only ask for the CD once
108  * 
109  * 34    5/20/98 9:46p John
110  * added code so the places in code that change half the palette don't
111  * have to clear the screen.
112  * 
113  * 33    5/20/98 6:41p Lawrance
114  * Add hook for command brief stage changes
115  * 
116  * 32    5/18/98 5:59p Hoffoss
117  * Made command briefing advanced now once the speech stops and animation
118  * has fully played once, whichever is longer.
119  * 
120  * 31    5/14/98 3:34p Hoffoss
121  * Made command brief screen wait until animation finishes before
122  * auto-advancing to the next state (in addition to the wait that was
123  * already implemented).
124  * 
125  * 30    5/08/98 5:32p Lawrance
126  * prompt for CD if can't load animations or voice
127  * 
128  * 29    5/06/98 11:49p Lawrance
129  * Add help overlay for command brief
130  * 
131  * 28    5/05/98 2:44p Hoffoss
132  * Fixed bug where not having a valid command brief ani would crash the
133  * cmd brief screen.
134  * 
135  * 27    4/28/98 4:16p Hoffoss
136  * Implemented auto-advancing functionality to command briefings.
137  * 
138  * 26    4/27/98 11:01a Hoffoss
139  * Changed code to utilize proper palette.
140  * 
141  * 25    4/26/98 5:11p Hoffoss
142  * Fixed bug where going to options screen and then returning to the cmd
143  * brief screen didn't start ani back up.
144  * 
145  * 24    4/13/98 11:00a Hoffoss
146  * Made the ani in a cmd brief continue playing if it's the same as the
147  * new stage.
148  * 
149  * 23    4/06/98 8:37p Hoffoss
150  * Fixed a few bugs with command brief screen.  Now the voice starts after
151  * the text has printed, and options screen doesn't reset cmd brief.
152  * 
153  * 22    4/06/98 11:24a Lawrance
154  * stop command brief music if returning to main menu
155  * 
156  * 21    4/02/98 11:40a Lawrance
157  * check for #ifdef DEMO instead of #ifdef DEMO_RELEASE
158  * 
159  * 20    3/31/98 5:18p John
160  * Removed demo/save/restore.  Made NDEBUG defined compile.  Removed a
161  * bunch of debug stuff out of player file.  Made model code be able to
162  * unload models and malloc out only however many models are needed.
163  *  
164  * 
165  * 19    3/31/98 12:00p Hoffoss
166  * Fixed bug with setting palette using <default> as filename.
167  * 
168  * 18    3/30/98 3:22p Hoffoss
169  * Changed Command Brief screen to merge current ani's palette with
170  * interface palette for better overall color.
171  * 
172  * 17    3/30/98 12:18a Lawrance
173  * change some DEMO_RELEASE code to not compile code rather than return
174  * early
175  * 
176  * 16    3/29/98 12:55a Lawrance
177  * Get demo build working with limited set of data.
178  * 
179  * 15    3/27/98 9:49a Lawrance
180  * AL: Ensure anim stops playing when leaving the command brief
181  * 
182  * 14    3/26/98 5:24p Hoffoss
183  * Changed Command Brief to use memory mapped ani files instead, so we
184  * avoid the huge pauses for huge anis that play!
185  * 
186  * 13    3/24/98 8:52a Jasen
187  * Updated coords for new button.
188  * 
189  * 12    3/23/98 4:21p Hoffoss
190  * Fixed bug where command brief screen couldn't be re-entered unless
191  * mission was reloaded.
192  * 
193  * 11    3/19/98 5:59p Hoffoss
194  * Added reset to cmd brief shutdown.
195  * 
196  * 10    3/19/98 5:32p Lawrance
197  * Added music to the background of command brief screen.
198  * 
199  * 9     3/19/98 4:25p Hoffoss
200  * Added remaining support for command brief screen (ANI and WAVE file
201  * playing).
202  * 
203  * 8     3/18/98 12:03p John
204  * Marked all the new strings as externalized or not.
205  * 
206  * 7     3/17/98 6:24p Hoffoss
207  * Added ani playing to command brief screen, which defaults to
208  * CB_default.ani.
209  * 
210  * 6     3/13/98 6:12p Frank
211  * AL: Fix bug caused by conflict with command brief and red alert
212  * missions
213  * 
214  * 5     3/13/98 3:44p Hoffoss
215  * Added stage indication to Mission Command Briefing screen.
216  * 
217  * 4     3/12/98 4:02p Hoffoss
218  * Added commit sound
219  * 
220  * 3     3/05/98 9:38p Hoffoss
221  * Finished up command brief screen.
222  * 
223  * 2     3/05/98 3:59p Hoffoss
224  * Added a bunch of new command brief stuff, and asteroid initialization
225  * to Fred.
226  * 
227  * 1     3/02/98 6:13p Hoffoss
228  *
229  * $NoKeywords: $
230  */
231
232 #include "ui.h"
233 #include "uidefs.h"
234 #include "gamesnd.h"
235 #include "gamesequence.h"
236 #include "missionscreencommon.h"
237 #include "key.h"
238 #include "bmpman.h"
239 #include "font.h"
240 #include "missionbriefcommon.h"
241 #include "missioncmdbrief.h"
242 #include "redalert.h"
243 #include "audiostr.h"
244 #include "timer.h"
245 #include "eventmusic.h"
246 #include "player.h"
247 #include "contexthelp.h"
248 #include "alphacolors.h"
249 #include "animplay.h"
250
251 char *Cmd_brief_fname[GR_NUM_RESOLUTIONS] = {
252         "CommandBrief",
253         "2_CommandBrief"
254 };
255
256 char *Cmd_brief_mask[GR_NUM_RESOLUTIONS] = {
257         "CommandBrief-m",
258         "2_Commandbrief-m"
259 };
260
261 // lookups for coordinates
262 #define CMD_X_COORD 0
263 #define CMD_Y_COORD 1
264 #define CMD_W_COORD 2
265 #define CMD_H_COORD 3
266
267 int Cmd_text_wnd_coords[GR_NUM_RESOLUTIONS][4] = {
268         {
269 #ifdef MAKE_FS1
270                 30, 165, 362, 271
271 #else
272                 17, 109, 606, 108                       // GR_640
273 #endif
274         },
275         {
276                 28, 174, 969, 174                       // GR_1024
277         }
278 };
279
280
281 int Cmd_stage_y[GR_NUM_RESOLUTIONS] = {
282 #ifdef MAKE_FS1
283         147,
284 #else
285         90,             // GR_640
286 #endif
287         145             // GR_1024
288 };
289
290 int Cmd_image_wnd_coords[GR_NUM_RESOLUTIONS][4] = {
291         {
292 #ifdef MAKE_FS1
293                 424, 140, 197, 148
294 #else
295                 26, 258, 441, 204                               // GR_640
296 #endif
297         },
298         {
299                 155, 475, 706, 327              // GR_1024
300         }
301 };
302
303 #define NUM_BUTTONS     8
304
305 #ifdef MAKE_FS1
306 #define FIRST_STAGE_BUTTON  0
307 #define PREV_STAGE_BUTTON   1
308 #define NEXT_STAGE_BUTTON   2
309 #define LAST_STAGE_BUTTON   3
310 #define HELP_BUTTON         4
311 #define OPTIONS_BUTTON      5
312 #define ACCEPT_BUTTON       6
313 #define PAUSE_BUTTON        7
314 #else
315 #define FIRST_STAGE_BUTTON      0
316 #define PREV_STAGE_BUTTON       1
317 #define PAUSE_BUTTON                    2
318 #define NEXT_STAGE_BUTTON       3
319 #define LAST_STAGE_BUTTON       4
320 #define HELP_BUTTON                     5
321 #define OPTIONS_BUTTON          6
322 #define ACCEPT_BUTTON           7
323 #endif
324
325 // buttons
326 ui_button_info Cmd_brief_buttons[GR_NUM_RESOLUTIONS][NUM_BUTTONS] = {
327         { // GR_640
328 #ifdef MAKE_FS1
329                 ui_button_info("CBB_00",        144,    442,    -1,     -1,     0),     // vcr - beginning
330                 ui_button_info("CBB_01",        169,    442,    -1,     -1,     1),     // vcr - reverse
331                 ui_button_info("CBB_02",        221,    442,    -1,     -1,     2),     // vcr - play
332                 ui_button_info("CBB_03",        247,    442,    -1,     -1,     3),     // vcr - end
333                 ui_button_info("CBB_04",        469,    424,    -1,     -1,     4),     // help
334                 ui_button_info("CBB_05",        447,    452,    -1,     -1,     5),     // options
335                 ui_button_info("CBB_06",        552,    411,    -1,     -1,     6),     // continue
336                 ui_button_info("CBB_07",        195,    442,    -1,     -1,     7),     // vcr - pause
337 #else
338                 ui_button_info("CBB_00",        504,    221,    -1,     -1,     0),
339                 ui_button_info("CBB_01",        527,    221,    -1,     -1,     1),
340                 ui_button_info("CBB_02",        555,    221,    -1,     -1,     2),
341                 ui_button_info("CBB_03",        583,    221,    -1,     -1,     3),
342                 ui_button_info("CBB_04",        607,    221,    -1,     -1,     4),
343                 ui_button_info("CBB_05",        539,    431,    -1,     -1,     5),
344                 ui_button_info("CBB_06",        538,    455,    -1,     -1,     6),
345                 ui_button_info("CBB_07",        575,    432,    -1,     -1,     7),
346 #endif
347         },
348         { // GR_1024
349                 ui_button_info("2_CBB_00",      806,    354,    -1,     -1,     0),
350                 ui_button_info("2_CBB_01",      844,    354,    -1,     -1,     1),
351                 ui_button_info("2_CBB_02",      888,    354,    -1,     -1,     2),
352                 ui_button_info("2_CBB_03",      933,    354,    -1,     -1,     3),
353                 ui_button_info("2_CBB_04",      971,    354,    -1,     -1,     4),
354                 ui_button_info("2_CBB_05",      863,    690,    -1,     -1,     5),
355                 ui_button_info("2_CBB_06",      861,    728,    -1,     -1,     6),
356                 ui_button_info("2_CBB_07",      920,    692,    -1,     -1,     7),
357         }
358 };
359
360 // text
361 #ifdef MAKE_FS1
362         #define CMD_BRIEF_NUM_TEXT              0
363 #else
364         #define CMD_BRIEF_NUM_TEXT              3
365 #endif
366 UI_XSTR Cmd_brief_text[GR_NUM_RESOLUTIONS][CMD_BRIEF_NUM_TEXT] = {
367         { // GR_640
368                 // not needed for FS1
369 #ifndef MAKE_FS1
370                 { "Help",               928,    500,    440,    UI_XSTR_COLOR_GREEN,    -1,     &Cmd_brief_buttons[0][HELP_BUTTON].button },
371                 { "Options",    1036,   479,    464,    UI_XSTR_COLOR_GREEN,    -1,     &Cmd_brief_buttons[0][OPTIONS_BUTTON].button },
372                 { "Continue",   1069,   564,    413,    UI_XSTR_COLOR_PINK,     -1,     &Cmd_brief_buttons[0][ACCEPT_BUTTON].button },
373 #endif
374         },
375         { // GR_1024
376                 // not needed for FS1
377 #ifndef MAKE_FS1
378                 { "Help",               928,    800,    704,    UI_XSTR_COLOR_GREEN,    -1,     &Cmd_brief_buttons[1][HELP_BUTTON].button },
379                 { "Options",    1036,   797,    743,    UI_XSTR_COLOR_GREEN,    -1,     &Cmd_brief_buttons[1][OPTIONS_BUTTON].button },
380                 { "Continue",   1069,   917,    661,    UI_XSTR_COLOR_PINK,     -1,     &Cmd_brief_buttons[1][ACCEPT_BUTTON].button },
381 #endif
382         }
383 };
384
385 static UI_WINDOW Ui_window;
386 static int Background_bitmap;                                   // bitmap for the background of the cmd_briefing
387 static int Cur_stage;
388 static int Scroll_offset;
389 static int Cmd_brief_inited = 0;
390 // static int Cmd_brief_ask_for_cd;
391 static int Voice_good_to_go = 0;
392 static int Voice_started_time = 0;
393 static int Voice_ended_time;
394 static int Anim_playing_id = -1;
395 static anim_instance *Cur_anim_instance = NULL;
396 static int Last_anim_frame_num;
397
398 static int Cmd_brief_last_voice;
399 //static int Palette_bmp = -1;          // no longer used
400 static ubyte Palette[768];
401 //static char Palette_name[128];        // no longer used
402
403 void cmd_brief_init_voice()
404 {
405         int i;
406
407         Assert(Cur_cmd_brief);
408         for (i=0; i<Cur_cmd_brief->num_stages; i++) {
409                 Cur_cmd_brief->stage[i].wave = -1;
410                 if (stricmp(Cur_cmd_brief->stage[i].wave_filename, NOX("none")) && Cur_cmd_brief->stage[i].wave_filename[0]) {
411                         Cur_cmd_brief->stage[i].wave = audiostream_open(Cur_cmd_brief->stage[i].wave_filename, ASF_VOICE);
412                         if (Cur_cmd_brief->stage[i].wave < 0) {
413                                 nprintf(("General", "Failed to load \"%s\"", Cur_cmd_brief->stage[i].wave_filename));
414                         }
415                 }
416         }
417
418         Cmd_brief_last_voice = -1;
419 }
420
421 int cmd_brief_check_stage_done()
422 {
423         if (!Voice_good_to_go)
424                 return 0;
425
426         if (Voice_ended_time && (timer_get_milliseconds() - Voice_ended_time >= 1000))
427                 return 1;
428
429         if (Briefing_voice_enabled && (Cmd_brief_last_voice >= 0)) {
430                 if (audiostream_is_playing(Cmd_brief_last_voice)){
431                         return 0;
432                 }
433
434                 if (!Voice_ended_time){
435                         Voice_ended_time = timer_get_milliseconds();
436                 }
437
438                 return 0;
439         }
440
441         // if we get here, there is no voice, so we simulate the time it would take instead
442         if (!Voice_ended_time)
443                 Voice_ended_time = Voice_started_time + max(5000, Num_brief_text_lines[0] * 3500);
444
445         return 0;
446 }
447
448 // start playback of the voice for a particular briefing stage
449 void cmd_brief_voice_play(int stage_num)
450 {
451         int voice = -1;
452
453         if (!Voice_good_to_go) {
454                 Voice_started_time = 0;
455                 return;
456         }
457
458         if (!Voice_started_time) {
459                 Voice_started_time = timer_get_milliseconds();
460                 Voice_ended_time = 0;
461         }
462
463         if (!Briefing_voice_enabled){
464                 return;
465         }
466
467         if (Cur_stage >= 0 && Cur_stage < Cur_cmd_brief->num_stages){
468                 voice = Cur_cmd_brief->stage[stage_num].wave;
469         }
470
471         // are we still on same voice that is currently playing/played?
472         if (Cmd_brief_last_voice == voice){
473                 return;  // no changes, nothing to do.
474         }
475
476         // if previous wave is still playing, stop it first.
477         if (Cmd_brief_last_voice >= 0) {
478                 audiostream_stop(Cmd_brief_last_voice);  // stream is automatically rewound
479                 Cmd_brief_last_voice = -1;
480         }
481
482         // ok, new wave needs playing, so we can start playing it now (and it becomes the current wave)
483         Cmd_brief_last_voice = voice;
484         if (voice >= 0){
485                 audiostream_play(voice, Master_voice_volume, 0);
486         }
487 }
488
489 // called to leave the command briefing screen
490 void cmd_brief_exit()
491 {
492         gameseq_post_event(GS_EVENT_START_BRIEFING);
493 }
494
495 void cmd_brief_stop_anim(int id)
496 {
497         if (Cur_anim_instance && (id != Anim_playing_id)) {
498                 anim_stop_playing(Cur_anim_instance);
499                 Cur_anim_instance = NULL;
500         }
501
502         Voice_good_to_go = 0;
503         if (Cmd_brief_last_voice >= 0) {
504                 audiostream_stop(Cmd_brief_last_voice);  // stream is automatically rewound
505                 Cmd_brief_last_voice = -1;
506         }
507 }
508
509 void cmd_brief_new_stage(int stage)
510 {
511         int i;
512         anim_play_struct aps;
513
514         if (stage < 0) {
515                 cmd_brief_stop_anim(-1);
516                 Cur_stage = -1;
517                 Anim_playing_id = -1;
518         }
519
520         Cur_stage = stage;
521         brief_color_text_init(Cur_cmd_brief->stage[stage].text, Cmd_text_wnd_coords[gr_screen.res][CMD_W_COORD]);
522
523         i = Cur_cmd_brief->stage[Cur_stage].anim_ref;
524         if (i < 0)
525                 i = Cur_stage;
526
527         cmd_brief_stop_anim(i);
528
529         if (i != Anim_playing_id) {
530                 if (Cur_cmd_brief->stage[i].anim) {
531                         anim_play_init(&aps, Cur_cmd_brief->stage[i].anim,Cmd_image_wnd_coords[gr_screen.res][CMD_X_COORD], Cmd_image_wnd_coords[gr_screen.res][CMD_Y_COORD]);
532                         aps.looped = 1;
533                         Cur_anim_instance = anim_play(&aps);
534                         Last_anim_frame_num = 0;
535                 }
536
537                 Anim_playing_id = i;
538         }
539
540         if (Cur_cmd_brief->stage[i].anim) {
541                 memcpy(Palette, Cur_cmd_brief->stage[i].anim->palette, 384);
542                 gr_set_palette(Cur_cmd_brief->stage[i].ani_filename, Palette, 1);
543         }
544 }
545
546 void cmd_brief_hold()
547 {
548         cmd_brief_stop_anim(-1);
549         Anim_playing_id = -1;
550 }
551
552 void cmd_brief_unhold()
553 {
554         cmd_brief_new_stage(Cur_stage);
555 }
556
557 void cmd_brief_button_pressed(int n)
558 {
559         switch (n) {
560                 case HELP_BUTTON:
561                         launch_context_help();
562                         gamesnd_play_iface(SND_HELP_PRESSED);
563                         break;
564
565                 case OPTIONS_BUTTON:
566                         gamesnd_play_iface(SND_SWITCH_SCREENS);
567                         gameseq_post_event(GS_EVENT_OPTIONS_MENU);
568                         break;
569
570                 case FIRST_STAGE_BUTTON:
571                         if (Cur_stage) {
572                                 cmd_brief_new_stage(0);
573                                 gamesnd_play_iface(SND_BRIEF_STAGE_CHG);
574                         } else {
575                                 gamesnd_play_iface(SND_GENERAL_FAIL);
576                         }
577
578                         break;
579
580                 case PREV_STAGE_BUTTON:
581                         if (Cur_stage) {
582                                 cmd_brief_new_stage(Cur_stage - 1);
583                                 gamesnd_play_iface(SND_BRIEF_STAGE_CHG);
584                         } else {
585                                 gamesnd_play_iface(SND_GENERAL_FAIL);
586                         }
587
588                         break;
589
590                 case NEXT_STAGE_BUTTON:
591                         if (Cur_stage < Cur_cmd_brief->num_stages - 1) {
592                                 cmd_brief_new_stage(Cur_stage + 1);
593                                 gamesnd_play_iface(SND_BRIEF_STAGE_CHG);
594                         } else {
595                                 gamesnd_play_iface(SND_GENERAL_FAIL);
596                         }
597
598                         break;
599
600                 case LAST_STAGE_BUTTON:
601                         if (Cur_stage < Cur_cmd_brief->num_stages - 1) {
602                                 cmd_brief_new_stage(Cur_cmd_brief->num_stages - 1);
603                                 gamesnd_play_iface(SND_BRIEF_STAGE_CHG);
604                         } else {
605                                 gamesnd_play_iface(SND_GENERAL_FAIL);
606                         }
607                         break;
608
609                 case ACCEPT_BUTTON:
610                         cmd_brief_exit();
611                         gamesnd_play_iface(SND_COMMIT_PRESSED);
612                         break;
613
614                 case PAUSE_BUTTON:
615                         gamesnd_play_iface(SND_USER_SELECT);
616                         Player->auto_advance ^= 1;
617                         break;
618         }
619 }
620
621 void cmd_brief_ani_wave_init(int index)
622 {
623         char *name;
624         int i;
625
626         // first, search and see if anim is already used in another stage
627         for (i=0; i<index; i++) {
628                 if (!stricmp(Cur_cmd_brief->stage[i].ani_filename, Cur_cmd_brief->stage[index].ani_filename)) {
629                         if (Cur_cmd_brief->stage[i].anim_ref >= 0)
630                                 Cur_cmd_brief->stage[index].anim_ref = Cur_cmd_brief->stage[i].anim_ref;
631                         else
632                                 Cur_cmd_brief->stage[index].anim_ref = i;
633
634                         return;
635                 }
636         }
637
638         // this is the first instance of the given anim filename
639         Cur_cmd_brief->stage[index].anim_ref = -1;
640         name = Cur_cmd_brief->stage[index].ani_filename;
641         if (!name[0] || !stricmp(name, NOX("<default>")) || !stricmp(name, NOX("none.ani"))) {
642                 name = NOX("CB_default");
643                 strcpy(Cur_cmd_brief->stage[index].ani_filename, name);
644         }
645
646         int load_attempts = 0;
647         while (1) {
648
649                 if ( load_attempts++ > 5 ) {
650                         break;
651                 }
652
653                 Cur_cmd_brief->stage[index].anim = anim_load(name, 1);
654                 if ( Cur_cmd_brief->stage[index].anim ) {
655                         break;
656                 }
657
658                 // couldn't load animation, ask user to insert CD (if necessary)
659                 // if ( Cmd_brief_ask_for_cd ) {
660                         // if ( game_do_cd_check() == 0 ) {
661                                 // Cmd_brief_ask_for_cd = 0;
662                                 // break;
663                         // }
664                 // }
665         }
666
667         // check to see if cb anim loaded, if not, try the default one
668         if ( !Cur_cmd_brief->stage[index].anim ) {
669                 Cur_cmd_brief->stage[index].anim = anim_load(NOX("CB_default"), 1);
670         }
671 }
672
673 void cmd_brief_init(int team)
674 {
675         common_music_init(SCORE_BRIEFING);
676
677 //#ifndef FS2_DEMO
678
679         int i;
680         ui_button_info *b;
681
682         Cmd_brief_inited = 0;
683         Cur_cmd_brief = &Cmd_briefs[team];
684
685         if ( red_alert_mission() ) {
686                 gameseq_post_event(GS_EVENT_RED_ALERT);
687                 return;
688         }
689
690         if (Cur_cmd_brief->num_stages <= 0)
691                 return;
692
693         gr_reset_clip();
694         gr_clear();
695         Mouse_hidden++;
696         gr_flip();
697         Mouse_hidden--;
698
699         /*
700         Palette_bmp = bm_load("BarracksPalette");       //CommandBriefPalette");
701         Assert(Palette_bmp);
702         bm_get_palette(Palette_bmp, Palette, Palette_name);  // get the palette for this bitmap
703         gr_set_palette(Palette_name, Palette, 1);
704         */
705
706 #ifdef MAKE_FS1
707         common_set_interface_palette("BarracksPalette");
708 #endif
709
710         Ui_window.create(0, 0, gr_screen.max_w, gr_screen.max_h, 0);
711         Ui_window.set_mask_bmap(Cmd_brief_mask[gr_screen.res]);
712
713         // Cmd_brief_ask_for_cd = 1;
714
715         for (i=0; i<NUM_BUTTONS; i++) {
716                 b = &Cmd_brief_buttons[gr_screen.res][i];
717
718                 b->button.create(&Ui_window, "", b->x, b->y, 60, 30, 0, 1);
719                 // set up callback for when a mouse first goes over a button
720                 b->button.set_highlight_action(common_play_highlight_sound);
721                 b->button.set_bmaps(b->filename);
722                 b->button.link_hotspot(b->hotspot);
723         }
724
725         // add text
726         for(i=0; i<CMD_BRIEF_NUM_TEXT; i++){
727                 Ui_window.add_XSTR(&Cmd_brief_text[gr_screen.res][i]);
728         }
729
730         // set up readyrooms for buttons so we draw the correct animation frame when a key is pressed
731         Cmd_brief_buttons[gr_screen.res][FIRST_STAGE_BUTTON].button.set_hotkey(KEY_SHIFTED | KEY_LEFT);
732         Cmd_brief_buttons[gr_screen.res][LAST_STAGE_BUTTON].button.set_hotkey(KEY_SHIFTED | KEY_RIGHT);
733         Cmd_brief_buttons[gr_screen.res][PREV_STAGE_BUTTON].button.set_hotkey(KEY_LEFT);
734         Cmd_brief_buttons[gr_screen.res][NEXT_STAGE_BUTTON].button.set_hotkey(KEY_RIGHT);
735         Cmd_brief_buttons[gr_screen.res][ACCEPT_BUTTON].button.set_hotkey(KEY_CTRLED | KEY_ENTER);
736         Cmd_brief_buttons[gr_screen.res][HELP_BUTTON].button.set_hotkey(KEY_F1);
737         Cmd_brief_buttons[gr_screen.res][OPTIONS_BUTTON].button.set_hotkey(KEY_F2);
738
739         // load in help overlay bitmap  
740         help_overlay_load(CMD_BRIEF_OVERLAY);
741         help_overlay_set_state(CMD_BRIEF_OVERLAY,0);
742
743         Background_bitmap = bm_load(Cmd_brief_fname[gr_screen.res]);
744
745         for (i=0; i<Cur_cmd_brief->num_stages; i++)
746                 cmd_brief_ani_wave_init(i);
747
748         cmd_brief_init_voice();
749         Scroll_offset = 0;
750         Cur_anim_instance = NULL;
751         cmd_brief_new_stage(0);
752         Cmd_brief_inited = 1;
753
754 //#endif
755 }
756
757 void cmd_brief_close()
758 {
759         int i;
760
761         if (Cmd_brief_inited) {
762                 cmd_brief_stop_anim(-1);
763                 Anim_playing_id = -1;
764                 for (i=0; i<Cur_cmd_brief->num_stages; i++) {
765                         if (Cur_cmd_brief->stage[i].wave >= 0)
766                                 audiostream_close_file(Cur_cmd_brief->stage[i].wave, 0);
767
768                         if (Cur_cmd_brief->stage[i].anim_ref < 0)
769                                 if (Cur_cmd_brief->stage[i].anim)
770                                         anim_free(Cur_cmd_brief->stage[i].anim);
771                 }
772
773                 if (Background_bitmap >= 0)
774                         bm_unload(Background_bitmap);
775
776                 // unload the overlay bitmap
777                 help_overlay_unload(CMD_BRIEF_OVERLAY);
778
779                 Ui_window.destroy();
780                 /*
781                 if (Palette_bmp){
782                         bm_unload(Palette_bmp);
783                 }
784                 */
785 #ifdef MAKE_FS1
786                 common_free_interface_palette();
787 #endif
788
789                 game_flush();
790                 Cmd_brief_inited = 0;
791         }
792 }
793
794 void cmd_brief_do_frame(float frametime)
795 {
796         char buf[40];
797         int i, k, w;            
798
799         // if no command briefing exists, skip this screen.
800         if (!Cmd_brief_inited) {
801                 cmd_brief_exit();
802                 return;
803         }
804
805         if ( help_overlay_active(CMD_BRIEF_OVERLAY) ) {
806                 Cmd_brief_buttons[gr_screen.res][HELP_BUTTON].button.reset_status();
807                 Ui_window.set_ignore_gadgets(1);
808         }
809
810         k = Ui_window.process() & ~KEY_DEBUGGED;
811
812         if ( (k > 0) || B1_JUST_RELEASED ) {
813                 if ( help_overlay_active(CMD_BRIEF_OVERLAY) ) {
814                         help_overlay_set_state(CMD_BRIEF_OVERLAY, 0);
815                         Ui_window.set_ignore_gadgets(0);
816                         k = 0;
817                 }
818         }
819
820         if ( !help_overlay_active(CMD_BRIEF_OVERLAY) ) {
821                 Ui_window.set_ignore_gadgets(0);
822         }
823
824         switch (k) {
825         case KEY_ESC:
826                 common_music_close();
827                 gameseq_post_event(GS_EVENT_MAIN_MENU);
828                 break;
829         }       // end switch
830
831         for (i=0; i<NUM_BUTTONS; i++){
832                 if (Cmd_brief_buttons[gr_screen.res][i].button.pressed()){
833                         cmd_brief_button_pressed(i);
834                 }
835         }
836
837         cmd_brief_voice_play(Cur_stage);
838         common_music_do();
839
840         if (cmd_brief_check_stage_done() && Player->auto_advance && (Cur_stage < Cur_cmd_brief->num_stages - 1)){
841 //              if (!Cur_anim_instance || (Cur_anim_instance->frame_num < Last_anim_frame_num))
842                 if (!Cur_anim_instance || Cur_anim_instance->loop_count){
843                         cmd_brief_new_stage(Cur_stage + 1);
844                 }
845         }
846
847         if (Cur_anim_instance){
848                 Last_anim_frame_num = Cur_anim_instance->frame_num;
849         }
850
851         GR_MAYBE_CLEAR_RES(Background_bitmap);
852         if (Background_bitmap >= 0) {
853                 gr_set_bitmap(Background_bitmap, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);
854                 gr_bitmap(0, 0);
855         } 
856
857         {
858                 // JAS: This code is hacked to allow the animation to use all 256 colors
859                 extern int Palman_allow_any_color;
860                 Palman_allow_any_color = 1;
861                 anim_render_all(0, frametime);
862                 Palman_allow_any_color = 0;
863         }
864         Ui_window.draw();
865
866         if (!Player->auto_advance){
867                 Cmd_brief_buttons[gr_screen.res][PAUSE_BUTTON].button.draw_forced(2);
868         }
869
870         gr_set_font(FONT1);
871         gr_set_color_fast(&Color_text_heading);
872
873         sprintf(buf, XSTR( "Stage %d of %d", 464), Cur_stage + 1, Cur_cmd_brief->num_stages);
874         gr_get_string_size(&w, NULL, buf);
875         gr_string(Cmd_text_wnd_coords[gr_screen.res][CMD_X_COORD] + Cmd_text_wnd_coords[gr_screen.res][CMD_W_COORD] - w, Cmd_stage_y[gr_screen.res], buf);
876
877         if (brief_render_text(Scroll_offset, Cmd_text_wnd_coords[gr_screen.res][CMD_X_COORD], Cmd_text_wnd_coords[gr_screen.res][CMD_Y_COORD], Cmd_text_wnd_coords[gr_screen.res][CMD_H_COORD], frametime, 0, 1)){
878                 Voice_good_to_go = 1;
879         }
880
881         // blit help overlay if active
882         help_overlay_maybe_blit(CMD_BRIEF_OVERLAY);
883
884         gr_flip();
885 }
886