]> icculus.org git repositories - taylor/freespace2.git/blob - src/menuui/mainhallmenu.cpp
fix tooltip text color for FS2
[taylor/freespace2.git] / src / menuui / mainhallmenu.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/MenuUI/MainHallMenu.cpp $
11  * $Revision$
12  * $Date$
13  * $Author$
14  *
15  * Header file for main-hall menu code
16  *
17  * $Log$
18  * Revision 1.9  2005/10/01 22:04:58  taylor
19  * fix FS1 (de)briefing voices, the directory names are different in FS1
20  * hard code the table values so that the fs1.vp file isn't needed
21  * hard code a mission fix for sm2-08a since a have no idea how to fix it otherwise
22  * generally cleanup some FS1 code
23  * fix volume sliders in the options screen that never went all the way up
24  *
25  * Revision 1.8  2004/09/20 01:31:44  theoddone33
26  * GCC 3.4 fixes.
27  *
28  * Revision 1.7  2003/05/25 02:30:42  taylor
29  * Freespace 1 support
30  *
31  * Revision 1.6  2002/07/24 00:20:42  relnev
32  * nothing interesting
33  *
34  * Revision 1.5  2002/06/09 04:41:22  relnev
35  * added copyright header
36  *
37  * Revision 1.4  2002/06/01 03:32:00  relnev
38  * fix texture loading mistake.
39  *
40  * enable some d3d stuff for opengl also
41  *
42  * Revision 1.3  2002/05/30 16:55:44  theoddone33
43  * now gets to another screen
44  *
45  * Revision 1.2  2002/05/27 22:43:02  theoddone33
46  * Fix more glide symbols
47  *
48  * Revision 1.1.1.1  2002/05/03 03:28:09  root
49  * Initial import.
50  *
51  * 
52  * 62    10/28/99 2:04a Jefff
53  * fixed a string
54  * 
55  * 61    9/15/99 6:28p Dave
56  * No load mission button in RELEASE_REAL
57  * 
58  * 60    9/13/99 4:52p Dave
59  * RESPAWN FIX
60  * 
61  * 59    9/13/99 11:30a Dave
62  * Added checkboxes and functionality for disabling PXO banners as well as
63  * disabling d3d zbuffer biasing.
64  * 
65  * 58    9/07/99 6:55p Jefff
66  * added jump-to-campaign-mission cheat
67  * 
68  * 57    9/07/99 4:01p Dave
69  * Fixed up a string.tbl paroblem (self destruct message). Make sure IPX
70  * does everything properly (setting up address when binding). Remove
71  * black rectangle background from UI_INPUTBOX.
72  * 
73  * 56    9/06/99 6:38p Dave
74  * Improved CD detection code.
75  * 
76  * 55    9/06/99 1:30a Dave
77  * Intermediate checkin. Started on enforcing CD-in-drive to play the
78  * game.
79  * 
80  * 54    9/03/99 1:31a Dave
81  * CD checking by act. Added support to play 2 cutscenes in a row
82  * seamlessly. Fixed super low level cfile bug related to files in the
83  * root directory of a CD. Added cheat code to set campaign mission # in
84  * main hall.
85  * 
86  * 53    9/01/99 11:02p Dave
87  * Made head guy look right when not animating.
88  * 
89  * 52    8/27/99 12:04a Dave
90  * Campaign loop screen.
91  * 
92  * 51    8/26/99 9:45a Dave
93  * First pass at easter eggs and cheats.
94  * 
95  * 50    8/25/99 11:57a Jefff
96  * freespace -> freespace 2 in tooltip strings
97  * 
98  * 49    8/25/99 10:50a Dave
99  * Added music to the mainhall.tbl
100  * 
101  * 48    8/24/99 8:55p Dave
102  * Make sure nondimming pixels work properly in tech menu.
103  * 
104  * 47    8/18/99 11:44a Jefff
105  * minor string fixes
106  * 
107  * 46    8/10/99 4:45p Jefff
108  * changed a string
109  * 
110  * 45    8/06/99 1:01p Andsager
111  * disable quick start (g) for demo
112  * 
113  * 44    8/05/99 10:34a Jefff
114  * more mouseover sound fixes
115  * 
116  * 43    8/04/99 9:12p Andsager
117  * Add campaign room popup allowing restart of campaign in demo.
118  * 
119  * 42    8/04/99 5:36p Dave
120  * Make glide and D3D switch out properly.
121  * 
122  * 41    8/04/99 4:35p Jefff
123  * fixed tech room & options sounds playing only once
124  * 
125  * 40    8/03/99 5:41p Jefff
126  * made "f1 for help" draw after animations, and stop if help overlay
127  * active
128  * 
129  * 39    8/03/99 4:42p Jefff
130  * small f1 text fix
131  * 
132  * 38    8/03/99 3:48p Jefff
133  * 
134  * 37    8/02/99 9:13p Dave
135  * Added popup tips.
136  * 
137  * 36    8/02/99 2:26p Jefff
138  * "press f1.." text reworked
139  * 
140  * 35    8/02/99 12:19p Andsager
141  * disable "L" load screen
142  * 
143  * 34    8/02/99 11:12a Jefff
144  * adjusted tooltip shader stuff for more a more pleasing effect.
145  * 
146  * 33    7/30/99 6:05p Jefff
147  * added shader behind tooltip text
148  * 
149  * 32    7/30/99 4:20p Andsager
150  * Added user click sounds to main hall
151  * 
152  * 31    7/29/99 10:47p Dave
153  * Standardized D3D fogging using vertex fog. Shook out Savage 4 bugs.
154  * 
155  * 30    7/27/99 6:53p Dave
156  * Hi-res main hall support.
157  * 
158  * 29    7/16/99 1:49p Dave
159  * 8 bit aabitmaps. yay.
160  * 
161  * 28    7/15/99 9:20a Andsager
162  * FS2_DEMO initial checkin
163  * 
164  * 27    7/13/99 1:15p Dave
165  * 32 bit support. Whee!
166  * 
167  * 26    6/25/99 2:51p Jasons
168  * Changed wording of network error message.
169  * 
170  * 25    6/21/99 1:30p Alanl
171  * changed main menu music tag
172  * 
173  * 24    6/19/99 3:56p Dave
174  * Moved main hall definitions into a table file. Whee!
175  * 
176  * 23    6/11/99 11:13a Dave
177  * last minute changes before press tour build.
178  * 
179  * 22    5/09/99 8:57p Dave
180  * Final E3 build preparations.
181  * 
182  * 21    4/25/99 3:02p Dave
183  * Build defines for the E3 build.
184  * 
185  * 20    4/12/99 10:07p Dave
186  * Made network startup more forgiving. Added checkmarks to dogfight
187  * screen for players who hit commit.
188  * 
189  * 19    3/28/99 5:58p Dave
190  * Added early demo code. Make objects move. Nice and framerate
191  * independant, but not much else. Don't use yet unless you're me :)
192  * 
193  * 18    3/25/99 5:47p Dave
194  * Removed the whee
195  * 
196  * 17    3/19/99 9:51a Dave
197  * Checkin to repair massive source safe crash. Also added support for
198  * pof-style nebulae, and some new weapons code.
199  * 
200  * 16    2/25/99 4:19p Dave
201  * Added multiplayer_beta defines. Added cd_check define. Fixed a few
202  * release build warnings. Added more data to the squad war request and
203  * response packets.
204  * 
205  * 15    2/03/99 11:44a Dave
206  * Fixed d3d transparent textures.
207  * 
208  * 14    1/30/99 5:08p Dave
209  * More new hi-res stuff.Support for nice D3D textures.
210  * 
211  * 13    1/27/99 9:56a Dave
212  * Temporary checkin of beam weapons for Dan to make cool sounds.
213  * 
214  * 12    12/31/98 11:23a Dave
215  * Put mini-indicators for status of ships.tbl and weapons.tbl in the
216  * lower left corner of the main hall.
217  * 
218  * 11    12/18/98 1:13a Dave
219  * Rough 1024x768 support for Direct3D. Proper detection and usage through
220  * the launcher.
221  * 
222  * 10    11/30/98 1:07p Dave
223  * 16 bit conversion, first run.
224  * 
225  * 9     11/20/98 4:08p Dave
226  * Fixed flak effect in multiplayer.
227  * 
228  * 8     11/20/98 11:16a Dave
229  * Fixed up IPX support a bit. Making sure that switching modes and
230  * loading/saving pilot files maintains proper state.
231  * 
232  * 7     11/19/98 4:57p Dave
233  * Ignore PXO option if IPX is selected.
234  * 
235  * 6     11/19/98 4:19p Dave
236  * Put IPX sockets back in psnet. Consolidated all multiplayer config
237  * files into one.
238  * 
239  * 5     11/05/98 5:55p Dave
240  * Big pass at reducing #includes
241  * 
242  * 4     11/05/98 4:18p Dave
243  * First run nebula support. Beefed up localization a bit. Removed all
244  * conditional compiles for foreign versions. Modified mission file
245  * format.
246  * 
247  * 3     10/13/98 9:28a Dave
248  * Started neatening up freespace.h. Many variables renamed and
249  * reorganized. Added AlphaColors.[h,cpp]
250  * 
251  * 2     10/07/98 10:53a Dave
252  * Initial checkin.
253  * 
254  * 1     10/07/98 10:49a Dave
255  * 
256  * 103   10/02/98 3:22p Allender
257  * fix up the -connect option and fix the -port option
258  * 
259  * 102   8/20/98 5:31p Dave
260  * Put in handy multiplayer logfile system. Now need to put in useful
261  * applications of it all over the code.
262  * 
263  * 101   8/07/98 10:40a Allender
264  * new command line flags for starting netgames.  Only starting currently
265  * works, and PXO isn't implemented yet
266  * 
267  * 100   7/13/98 10:46a Lawrance
268  * Index another localized string
269  * 
270  * 99    7/10/98 1:13a Allender
271  * lots of small multiplayer update changes.  Code in launcher to specify
272  * connection speed.  A couple of small fixes regarding empty mission
273  * files.  Time out players after 10 second when they don't connect on
274  * their reliable socket.
275  * 
276  * 98    6/09/98 10:31a Hoffoss
277  * Created index numbers for all xstr() references.  Any new xstr() stuff
278  * added from here on out should be added to the end if the list.  The
279  * current list count can be found in FreeSpace.cpp (search for
280  * XSTR_SIZE).
281  * 
282  * 97    6/05/98 9:50a Lawrance
283  * OEM changes
284  * 
285  * 96    6/01/98 11:43a John
286  * JAS & MK:  Classified all strings for localization.
287  * 
288  * 95    5/22/98 9:02p Allender
289  * remove G key from main hall
290  * 
291  * 94    5/22/98 10:54a Allender
292  * new dialog information for networking to tell user if connection type
293  * doesn't match the setup specified type
294  * 
295  * 93    5/15/98 5:15p Dave
296  * Fix a standalone resetting bug.Tweaked PXO interface. Display captaincy
297  * status for team vs. team. Put in asserts to check for invalid team vs.
298  * team situations.
299  * 
300  * 92    5/13/98 12:23a Lawrance
301  * Don't init main hall if already inited... not needed now, but may be
302  * useful if we don't always want to call main_hall_close() when switching
303  * states
304  * 
305  * 91    5/12/98 2:46a Dave
306  * Rudimentary communication between Parallax Online and freespace. Can
307  * get and store channel lists.
308  * 
309  * 90    5/08/98 5:33p Lawrance
310  * check for CD when trying to enter ready room in single player
311  *  
312  * 
313  * $NoKeywords: $
314  *
315  */
316
317 #include "mainhallmenu.h"
318 #include "palman.h"
319 #include "bmpman.h"
320 #include "2d.h"
321 #include "gamesequence.h"
322 #include "animplay.h"
323 #include "key.h"
324 #include "timer.h"
325 #include "ui.h"
326 #include "snazzyui.h"
327 #include "player.h"
328 #include "audiostr.h"
329 #include "gamesnd.h"
330 #include "eventmusic.h"
331 #include "mouse.h"
332 #include "contexthelp.h"
333 #include "cmdline.h"
334 #include "psnet.h"
335 #include "multiui.h"
336 #include "multiutil.h"
337 #include "popup.h"
338 #include "rtvoice.h"
339 #include "osapi.h"
340 #include "playermenu.h"
341 #include "freespace.h"
342 #include "multi_voice.h"
343 #include "multi.h"
344 #include "alphacolors.h"
345 #include "demo.h"
346 #include "fishtank.h"
347
348 // #include "movie.h"
349
350 // ----------------------------------------------------------------------------
351 // MAIN HALL DATA DEFINES
352 //
353 #define MAX_RANDOM_INTERCOM_SOUNDS                              10
354 #define NUM_RANDOM_INTERCOM_SOUNDS_0                    3
355 #define NUM_RANDOM_INTERCOM_SOUNDS_1                    3
356
357 #define MAX_MISC_ANIMATIONS                                             10
358 #define NUM_MISC_ANIMATIONS_0                                           2
359 #define NUM_MISC_ANIMATIONS_1                                           4
360
361 #define MAX_DOOR_ANIMATIONS                                             10
362 #define NUM_DOOR_ANIMATIONS_0                                           6
363 #define NUM_DOOR_ANIMATIONS_1                                           6
364
365 #define MAX_DOOR_SOUNDS                                                         10
366 #define NUM_DOOR_SOUNDS_0                                                       6
367 #define NUM_DOOR_SOUNDS_1                                                       6
368
369 #define MISC_ANIM_MODE_LOOP                                             0                               // loop the animation
370 #define MISC_ANIM_MODE_HOLD                                             1                               // play to the end and hold the animation
371 #define MISC_ANIM_MODE_TIMED                                            2                               // uses timestamps to determine when a finished anim should be checked again
372
373 #define NUM_REGIONS                                                                     7                               // (6 + 1 for multiplayer equivalent of campaign room)
374 typedef struct main_hall_defines {
375         // bitmap and mask
376         char bitmap[MAX_FILENAME_LEN+1];
377         char mask[MAX_FILENAME_LEN+1];
378
379         // music
380         char music[MAX_FILENAME_LEN+1];
381
382         // intercom defines -------------------
383         
384         // # of intercom sounds
385         int num_random_intercom_sounds;
386         
387         // random (min/max) delays between playing intercom sounds
388         int intercom_delay[MAX_RANDOM_INTERCOM_SOUNDS][2];
389         
390         // intercom sounds themselves
391         int intercom_sounds[MAX_RANDOM_INTERCOM_SOUNDS];
392
393         // intercom sound pan values
394         float intercom_sound_pan[MAX_RANDOM_INTERCOM_SOUNDS];
395
396
397         // misc animations --------------------
398
399         // # of misc animations
400         int num_misc_animations;
401
402         // filenames of the misc animations
403         char misc_anim_name[MAX_MISC_ANIMATIONS][MAX_FILENAME_LEN+1];
404
405         // Time until we will next play a given misc animation, min delay, and max delay
406         int misc_anim_delay[MAX_MISC_ANIMATIONS][3];
407
408         //      coords of where to play the misc anim
409         int misc_anim_coords[MAX_MISC_ANIMATIONS][2];
410         
411         // misc anim play modes (see MISC_ANIM_MODE_* above)
412         int misc_anim_modes[MAX_MISC_ANIMATIONS];
413
414         // panning values for each of the misc anims
415         float misc_anim_sound_pan[MAX_MISC_ANIMATIONS];
416
417         // [N][0] == # of sounds, [N][1-9] sound index
418         int misc_anim_special_sounds[MAX_MISC_ANIMATIONS][10];
419
420         // [N][0] == # of triggers, [N][1-9] >= frame num
421         int misc_anim_special_trigger[MAX_MISC_ANIMATIONS][10];
422
423         // [N][0] == # of handles, [N][1-9] == sound handle num
424         int misc_anim_sound_handles[MAX_MISC_ANIMATIONS][10];
425
426         // [N][0] == # of handles, [N][1-9] == sound "should" be playing
427         int misc_anim_sound_flag[MAX_MISC_ANIMATIONS][10];      
428
429
430         // door animations --------------------
431
432         // # of door animations
433         int num_door_animations;
434         
435         // filenames of the door animations
436         char door_anim_name[MAX_DOOR_ANIMATIONS][MAX_FILENAME_LEN+1];   
437
438         // first pair : coords of where to play a given door anim
439         // second pair : center of a given door anim in windowed mode
440         int door_anim_coords[MAX_DOOR_ANIMATIONS][4];
441         
442
443         // door sounds ------------------------
444
445         // # of door sounds
446         int num_door_sounds;
447
448         // sounds for each region (open/close)
449         int door_sounds[MAX_DOOR_SOUNDS][2];
450
451         // pan values for the door sounds
452         float door_sound_pan[MAX_DOOR_SOUNDS];
453
454         
455         // region descriptions ----------------
456         
457         // text (tooltip) description
458         const char *region_descript[NUM_REGIONS];
459
460         // y coord of where to draw tooltip text
461         int region_yval;
462
463 } main_hall_defines;
464
465
466 // use main hall 0 by default
467 main_hall_defines Main_hall_defines[GR_NUM_RESOLUTIONS][NUM_MAIN_HALLS];
468 main_hall_defines *Main_hall = &Main_hall_defines[0][0];
469
470 int Vasudan_funny = 0;
471 int Vasudan_funny_plate = -1;
472
473 char Main_hall_campaign_cheat[512] = "";
474         
475 // ----------------------------------------------------------------------------
476 // MISC interface data
477 //
478 // is the main hall inited (for reentrancy)
479 int Main_hall_inited = 0;
480
481 // handle to the playing music
482 int Main_hall_music_handle = -1;
483
484 // background bitmap handle
485 int Main_hall_bitmap;
486
487 // background bitmap mask handle
488 int Main_hall_mask;
489
490 // variable used for automatic netgame starting/joining
491 int Main_hall_netgame_started = 0;
492
493 // bitmap struct for th background mask bitmap
494 bitmap *Main_hall_mask_bitmap;
495
496 // actual data for the background mask bitmap
497 ubyte *Main_hall_mask_data;
498
499 int Main_hall_mask_w, Main_hall_mask_h;
500
501
502 // ----------------------------------------------------------------------------
503 // MOUSE clicking stuff
504 //
505 // indicates whether a right click occured
506 int Main_hall_right_click;
507
508 // use this to cycle through the selectable regions instead of the mouse's current region
509 int Main_hall_last_clicked_region;
510
511 // use this to determine how long the cursor has to linger on a region before it starts playing
512 #define MAIN_HALL_REGION_LINGER                         175                             // in ms
513 int Main_hall_region_linger_stamp = -1;
514
515 // handle any right clicks which may have occured
516 void main_hall_handle_right_clicks();
517
518
519 // ----------------------------------------------------------------------------
520 // RANDOM intercom sounds
521 //
522
523 // next random intercom sound to play
524 int Main_hall_next_intercom_sound = 0;  
525
526 // delay for the next intercom sound
527 int Main_hall_next_intercom_sound_stamp = -1;
528
529 // handle to any playing instance of a random intercom sound
530 int Main_hall_intercom_sound_handle = -1;
531
532 // handle any details related to random intercom sounds
533 void main_hall_handle_random_intercom_sounds();
534
535
536 // ----------------------------------------------------------------------------
537 // MISC animations
538 //
539
540 // the misc animations themselves
541 anim *Main_hall_misc_anim[MAX_MISC_ANIMATIONS];                                                 
542
543 // the instance of a given misc animation
544 anim_instance *Main_hall_misc_anim_instance[MAX_MISC_ANIMATIONS];       
545
546 // handle starting, stopping and randomizing misc animations
547 void main_hall_handle_misc_anims();                                                                     
548
549 // cull any finished misc animation instances
550 void main_hall_cull_misc_anim_instances();                                                              
551
552 // render all playing misc animations
553 void main_hall_render_misc_anims(float frametime);
554
555
556 // ----------------------------------------------------------------------------
557 // DOOR animations (not all of these are doors anymore, but they're doorlike _regions_)
558 //
559 #define DOOR_TEXT_X 100
560 #define DOOR_TEXT_Y 450
561
562 // the door animations themselves
563 anim *Main_hall_door_anim[MAX_DOOR_ANIMATIONS];                                                 
564
565 // the instance of a given door animation
566 anim_instance *Main_hall_door_anim_instance[MAX_DOOR_ANIMATIONS];       
567
568 // render all playing door animations
569 void main_hall_render_door_anims(float frametime);
570
571
572 // ----------------------------------------------------------------------------
573 // SNAZZY MENU stuff
574 //
575 #define NUM_MAIN_HALL_REGIONS 10
576 #define NUM_MAIN_HALL_MOUSE_REGIONS 6
577
578 // region mask #'s (identifiers)
579 #define EXIT_REGION                              0
580 #define BARRACKS_REGION                  1
581 #define READY_ROOM_REGION                2
582 #define TECH_ROOM_REGION                 3
583 #define OPTIONS_REGION                   4
584 #define CAMPAIGN_ROOM_REGION     5
585 #define MULTIPLAYER_REGION     10
586 #define LOAD_MISSION_REGION    11
587 #define QUICK_START_REGION     12
588 #define SKILL_LEVEL_REGION     13
589
590 // all the menu regions in the main hall
591 MENU_REGION Main_hall_region[NUM_MAIN_HALL_REGIONS];
592
593 // # of regions (options) on this screen. parsed from a table
594 int Main_hall_num_options;
595
596 // region over which the mouse is currently residing, or -1 if over no region
597 // NOTE : you should nevery change this directly. Always use main_hall_handle_mouse_location(int)
598 //        to do this. Otherwise, the door opening and closing animations will get screwed up
599 int Main_hall_mouse_region;     
600
601 // set this to skip a frame
602 int Main_hall_frame_skip;
603
604 // do any necessary processing based upon the mouse location
605 void main_hall_handle_mouse_location(int cur_region);
606
607 // if the mouse has moved off of the currently active region, handle the anim accordingly
608 void main_hall_mouse_release_region(int region);                                
609
610 // if the mouse has moved on this region, handle it accordingly
611 void main_hall_mouse_grab_region(int region);                                   
612
613
614 // ----------------------------------------------------------------------------
615 // SOUND data / handlers
616 // -
617
618 // toaster oven room sound idex
619 #define TOASTER_REGION          3
620
621 // everyone's favorite desk guardian
622 #define ALLENDER_REGION         4
623
624 // handles to the sound instances of the doors opening/closing
625 int Main_hall_door_sound_handles[MAX_DOOR_SOUNDS] = {           
626         -1,-1,-1,-1,-1,-1
627 };
628
629 // sound handle for looping ambient sound
630 int Main_hall_ambient_loop = -1;                        
631
632 // cull any door sounds that have finished playing
633 void main_hall_cull_door_sounds();
634
635 // handle starting, stopping and reversing "door" animations
636 void main_hall_handle_region_anims();                                                           
637
638
639 // ----------------------------------------------------------------------------
640 // warning/notification messages
641 //
642 #define MAIN_HALL_NOTIFY_TIME  3500
643
644 // timestamp for the notification messages
645 int Main_hall_notify_stamp = -1;
646
647 // text to display as the current notification message
648 char Main_hall_notify_text[300]="";
649
650 // set the current notification string and the associated timestamp
651 void main_hall_set_notify_string(const char *str);
652
653 // handle any drawing, culling, etc of notification messages
654 void main_hall_notify_do();
655
656
657 // ----------------------------------------------------------------------------
658 // MISC functions
659 //
660
661 // upper _RIGHT_ corner for the version text
662 #define MAIN_HALL_VERSION_X             630                     
663 #define MAIN_HALL_VERSION_Y             467
664
665 // main hall help overlay ID
666 int Main_hall_overlay_id;
667
668 // blit the freespace version #
669 void main_hall_blit_version();
670
671 // blit any necessary tooltips
672 void main_hall_maybe_blit_tooltips();
673
674 // shader for behind tooltips
675 shader Main_hall_tooltip_shader;
676
677 #ifndef MAKE_FS1
678 // num pixels shader is above/below tooltip text
679 static int Main_hall_tooltip_padding[GR_NUM_RESOLUTIONS] = {
680         4,              // GR_640
681         7,              // GR_1024
682 };
683
684 static int Main_hall_f1_text_frame = 0;
685 static int F1_text_done = 0;
686 #endif
687
688 // read in main hall table
689 void main_hall_read_table();
690
691 // "press f1" for help stuff
692 #define MAIN_HALL_HELP_TIME             5000
693 int Main_hall_help_stamp = -1;
694 void main_hall_process_help_stuff();
695
696
697 // ----------------------------------------------------------------------------
698 // VOICE RECORDING STUFF
699 //
700
701 // are we currently recording voice?
702 int Recording = 0;
703
704
705 // called when multiplayer clicks on the ready room door.  May pop up dialog depending on network
706 // connection status and errors
707 void main_hall_do_multi_ready()
708 {
709         int error;
710
711         error = psnet_get_network_status();
712         switch( error ) {
713         case NETWORK_ERROR_NO_TYPE:
714                 popup( PF_NO_NETWORKING, 1, POPUP_OK, XSTR( "You have not defined your type of Internet connection.  Please run the Launcher, hit the setup button, and go to the Network tab and choose your connection type.", 360));
715                 break;
716         case NETWORK_ERROR_NO_WINSOCK:
717                 popup( PF_NO_NETWORKING, 1, POPUP_OK, XSTR( "Winsock is not installed.  You must have TCP/IP and Winsock installed to play multiplayer FreeSpace.", 361));
718                 break;
719         case NETWORK_ERROR_NO_PROTOCOL:
720                 SDL_assert(Multi_options_g.protocol == NET_TCP);
721                 popup( PF_NO_NETWORKING, 1, POPUP_OK, XSTR( "TCP/IP protocol not found.  This protocol is required for multiplayer FreeSpace.", 362));
722                 break;
723         case NETWORK_ERROR_CONNECT_TO_ISP:
724                 popup( PF_NO_NETWORKING, 1, POPUP_OK, XSTR( "You have selected Dial Up Networking as your type of connection to the Internet.  You are not currently connected.  You must connect to your ISP before continuing on past this point.", 363));
725                 break;
726         case NETWORK_ERROR_LAN_AND_RAS:
727                 popup( PF_NO_NETWORKING, 1, POPUP_OK, XSTR( "You have indicated that you use a LAN for networking.  You also appear to be dialed into your ISP.  Please disconnect from your service provider, or choose Dial Up Networking.", 364));
728                 break;
729
730         case NETWORK_ERROR_NONE:
731         default:
732                 break;
733         }
734
735         // if our selected protocol is not active
736         if ( !Tcp_active ) {
737                 popup( PF_NO_NETWORKING, 1, POPUP_OK, XSTR( "You have selected TCP/IP for multiplayer Freespace, but the TCP/IP protocol was not detected on your machine.", 362));
738                 return;
739         } 
740
741         if ( error != NETWORK_ERROR_NONE ){
742                 return;
743         }
744
745         // 7/9/98 -- MWA.  Deal with the connection speed issue.  make a call to the multiplayer code to
746         // determine is a valid connection setting exists
747         if ( Multi_connection_speed == CONNECTION_SPEED_NONE ) {
748                 popup( PF_NO_NETWORKING, 1, POPUP_OK, XSTR( "You must define your connection speed.  Please run the Launcher, hit the setup button, and go to the Network tab and choose your connection speed.", 986) );
749                 return;
750         }
751
752         // go to parallax online
753 #ifdef MULTIPLAYER_BETA_BUILD // do we want this for FS2_DEMO
754         Multi_options_g.pxo = 1;
755         Multi_options_g.protocol = NET_TCP;     
756         gameseq_post_event( GS_EVENT_PXO );
757 #else
758         if (Multi_options_g.pxo == 1) {
759                 SDL_assert(Multi_options_g.protocol == NET_TCP);
760                 gameseq_post_event( GS_EVENT_PXO );
761         } else {
762                 // go to the regular join game screen
763                 gameseq_post_event( GS_EVENT_MULTI_JOIN_GAME );
764         }
765 #endif  
766
767         // select protocol
768         psnet_use_protocol(Multi_options_g.protocol);
769 }
770
771 // blit some small color indicators to show whether ships.tbl and weapons.tbl are valid
772 // green == valid, red == invalid.
773 // ships.tbl will be on the left, weapons.tbl on the right
774 int Mh_ship_table_status[GR_NUM_RESOLUTIONS][2] = {
775         { 1, 479 },
776         { 1, 767 }
777 };
778 int Mh_weapon_table_status[GR_NUM_RESOLUTIONS][2] = {
779         { 3, 479 },
780         { 3, 767 }
781 };
782 void main_hall_blit_table_status()
783 {
784         // blit ship table status
785         gr_set_color_fast(Game_ships_tbl_valid ? &Color_bright_green : &Color_bright_red);
786         gr_line(Mh_ship_table_status[gr_screen.res][0], Mh_ship_table_status[gr_screen.res][1], Mh_ship_table_status[gr_screen.res][0], Mh_ship_table_status[gr_screen.res][1]);
787
788         // blit weapon table status
789         gr_set_color_fast(Game_weapons_tbl_valid ? &Color_bright_green : &Color_bright_red);
790         gr_line(Mh_weapon_table_status[gr_screen.res][0], Mh_weapon_table_status[gr_screen.res][1], Mh_weapon_table_status[gr_screen.res][0], Mh_ship_table_status[gr_screen.res][1]);
791 }
792
793 // bash the player to a specific mission in a campaign
794 void main_hall_campaign_cheat()
795 {
796         char *ret = popup_input(0, XSTR("Enter mission name.\n\n* This will destroy all legitimate progress in this campaign. *", -1));
797
798         // yay
799         if(ret != NULL) {
800                 // strcpy(Main_hall_campaign_cheat, ret);               
801                 mission_campaign_jump_to_mission(ret);
802         }
803 }
804
805 // -------------------------------------------------------------------------------------------------------------------
806 // FUNCTION DEFINITIONS BEGIN
807 //
808
809 // initialize the main hall proper 
810 void main_hall_init(int main_hall_num)
811 {
812         if ( Main_hall_inited ) {
813                 return;
814         }       
815
816         int idx,s_idx;
817         char temp[100], whee[100];      
818
819         // read in the main hall table
820         try {
821                 main_hall_read_table();
822         } catch (parse_error_t rval) {
823                 Error(LOCATION, "Unable to parse mainhall.tbl!  Code = %i.\n", (int)rval);
824         }
825
826         // create the snazzy interface and load up the info from the table
827         snazzy_menu_init();
828         read_menu_tbl(NOX("MAIN HALL"), temp, SDL_arraysize(temp), whee, SDL_arraysize(whee), Main_hall_region, &Main_hall_num_options, 0);
829
830         // assign the proper main hall data
831         SDL_assert((main_hall_num >= 0) && (main_hall_num < NUM_MAIN_HALLS));
832         Main_hall = &Main_hall_defines[gr_screen.res][main_hall_num];   
833
834         // tooltip strings
835 #ifdef MAKE_FS1
836         Main_hall->region_descript[0] = XSTR( "Exit Freespace", 353);
837         Main_hall->region_descript[1] = XSTR( "Barracks - Manage your Freespace pilots", 354);
838         Main_hall->region_descript[2] = XSTR( "Ready room - Start or continue a campaign", 355);
839         Main_hall->region_descript[3] = XSTR( "Tech room - View specifications of Freespace ships and weaponry", 356);
840         Main_hall->region_descript[4] = XSTR( "Options - Change your Freespace options", 357);
841         Main_hall->region_descript[5] = XSTR( "Campaign Room - View all available campaigns", 358);
842         Main_hall->region_descript[6] = XSTR( "Multiplayer - Start or join a multiplayer game", 359);
843 #else
844         Main_hall->region_descript[0] = XSTR( "Exit FreeSpace 2", 353);
845         Main_hall->region_descript[1] = XSTR( "Barracks - Manage your FreeSpace 2 pilots", 354);
846         Main_hall->region_descript[2] = XSTR( "Ready room - Start or continue a campaign", 355);
847         Main_hall->region_descript[3] = XSTR( "Tech room - View specifications of FreeSpace 2 ships and weaponry", 356);
848         Main_hall->region_descript[4] = XSTR( "Options - Change your FreeSpace 2 options", 357);
849         Main_hall->region_descript[5] = XSTR( "Campaign Room - View all available campaigns", 358);
850         Main_hall->region_descript[6] = XSTR( "Multiplayer - Start or join a multiplayer game", 359);
851 #endif
852         
853         // init tooltip shader
854 #ifndef MAKE_FS1
855         float gray_intensity = 0.02f;                                                                                                   // nearly black
856 //      float c = (gr_screen.mode == GR_DIRECT3D || gr_screen.mode == GR_OPENGL) ? 0.11f : 0.07f;                       // adjust for renderer differences
857         gr_create_shader(&Main_hall_tooltip_shader, gray_intensity, gray_intensity, gray_intensity, 0.11f);
858 #endif
859
860         // load the background bitmap
861         Main_hall_bitmap = bm_load(Main_hall->bitmap);
862         if(Main_hall_bitmap < 0){
863                 nprintf(("General","WARNING! Couldn't load main hall background bitmap %s\n", Main_hall->bitmap));
864         }       
865
866         // remove any multiplayer flags from the game mode
867         Game_mode &= ~(GM_MULTIPLAYER);
868
869         Main_hall_mask_w = -1;
870         Main_hall_mask_h = -1;
871                 
872         // load the mask
873         Main_hall_mask = bm_load(Main_hall->mask);
874         if (Main_hall_mask < 0) {
875                 Error(LOCATION,"Could not load in %s!", Main_hall->mask);
876         } else {
877                 // get a pointer to bitmap by using bm_lock(), so we can feed it to he snazzy menu system
878                 Main_hall_mask_bitmap = bm_lock(Main_hall_mask, 8, BMP_AABITMAP);
879                 Main_hall_mask_data = (ubyte*)Main_hall_mask_bitmap->data;
880                 bm_get_info(Main_hall_mask, &Main_hall_mask_w, &Main_hall_mask_h);
881         }
882
883         // load up the misc animations, and nullify all the delay timestamps for the misc animations    
884         for(idx=0;idx<Main_hall->num_misc_animations;idx++) {
885                 Main_hall_misc_anim[idx] = NULL;
886                 Main_hall_misc_anim[idx] = anim_load(Main_hall->misc_anim_name[idx]);
887                 if(Main_hall_misc_anim[idx] == NULL) {
888                         nprintf(("General","WARNING!, Could not load misc %s anim in main hall\n",Main_hall->misc_anim_name));
889                 }
890
891                 // null out the animation instances
892                 Main_hall_misc_anim_instance[idx] = NULL;
893                 
894                 // null out the delay timestamps
895                 Main_hall->misc_anim_delay[idx][0] = -1;
896         }       
897
898         // load up the door animations
899         for(idx=0;idx<Main_hall->num_door_animations;idx++) {
900                 Main_hall_door_anim[idx] = NULL;
901                 Main_hall_door_anim[idx] = anim_load(Main_hall->door_anim_name[idx]);
902                 if(Main_hall_door_anim[idx] == NULL){
903                         nprintf(("General","WARNING!, Could not load door anim %s in main hall\n",Main_hall->door_anim_name[idx]));
904                 }
905
906                 // null out the animation instances
907                 Main_hall_door_anim_instance[idx] = NULL;
908         }       
909
910         // load in help overlay bitmap          
911         if(Main_hall == &Main_hall_defines[gr_screen.res][0]) {
912                 Main_hall_overlay_id = MH_OVERLAY;
913         } else {
914                 SDL_assert(Main_hall == &Main_hall_defines[gr_screen.res][1]);
915                 Main_hall_overlay_id = MH2_OVERLAY;
916         }
917         help_overlay_load(Main_hall_overlay_id);
918         help_overlay_set_state(Main_hall_overlay_id,0);         
919
920         // check to see if the "very first pilot" flag is set, and load the overlay if so
921 #ifndef MAKE_FS1
922         if (!F1_text_done) {
923                 if (Main_hall_f1_text_frame == 0) {
924                         Main_hall_help_stamp = timestamp(MAIN_HALL_HELP_TIME);
925                 } else {
926                         F1_text_done = 1;
927                 }
928         }
929 #else
930         if(Player_select_very_first_pilot) {
931                 Main_hall_help_stamp = timestamp(MAIN_HALL_HELP_TIME);
932                 
933                 // don't display the "press f1" message more than once
934                 Player_select_very_first_pilot = 0;
935         } else {
936                 Main_hall_help_stamp = -1;
937         }
938 #endif
939
940         Main_hall_region_linger_stamp = -1;
941
942         SDL_strlcpy(Main_hall_campaign_cheat, "", SDL_arraysize(Main_hall_campaign_cheat));
943
944         // zero out the door sounds
945         for(idx=0;idx<Main_hall->num_door_sounds;idx++){
946                 Main_hall_door_sound_handles[idx] = -1;
947         }
948
949         // zero out the misc anim sounds
950         for(idx=0;idx<Main_hall->num_misc_animations;idx++){
951                 for(s_idx = 1;s_idx < 10;s_idx++){
952                         Main_hall->misc_anim_sound_handles[idx][s_idx] = -1;
953                         Main_hall->misc_anim_sound_flag[idx][s_idx] = 0;
954                 }
955         }
956
957         // skip the first frame
958         Main_hall_frame_skip = 1;
959
960         // initialize the music
961         main_hall_start_music();
962
963         // initialize the main hall notify text
964         Main_hall_notify_stamp = 1;
965
966         // initialize the random intercom sound stuff
967         Main_hall_next_intercom_sound = 0;              
968         Main_hall_next_intercom_sound_stamp = -1;
969         Main_hall_intercom_sound_handle = -1;
970
971         // set the placement of the mouse cursor (start at the ready room)
972         Main_hall_mouse_region = -1;
973         Main_hall_last_clicked_region = READY_ROOM_REGION;      
974         mouse_set_pos(Main_hall->door_anim_coords[READY_ROOM_REGION][2],Main_hall->door_anim_coords[READY_ROOM_REGION][3]);     
975
976         Main_hall_inited = 1;
977
978         // determine if we have a right click
979         Main_hall_right_click = mouse_down(MOUSE_RIGHT_BUTTON);
980
981         // set the game_mode based on the type of player
982         SDL_assert( Player != NULL );
983         if ( Player->flags & PLAYER_FLAGS_IS_MULTI ){
984                 Game_mode = GM_MULTIPLAYER;
985         } else {
986                 Game_mode = GM_NORMAL;
987         }
988
989         if ( (Cmdline_start_netgame || (Cmdline_connect_addr != NULL)) && !Main_hall_netgame_started ) {
990                 Main_hall_netgame_started = 1;
991                 main_hall_do_multi_ready();
992         }
993 }
994
995 void main_hall_exit_game()
996 {
997 #if defined(NDEBUG) || defined(INTERPLAYQA)
998         int choice;
999
1000         // stop music first
1001         main_hall_stop_music();
1002         main_hall_stop_ambient();
1003         choice = popup( PF_NO_NETWORKING | PF_BODY_BIG, 2, POPUP_NO, POPUP_YES, XSTR( "Exit Game?", 365));
1004         if ( choice == 1 ) {
1005                 gameseq_post_event(GS_EVENT_QUIT_GAME);
1006         } else {
1007                 main_hall_start_music();
1008                 main_hall_start_ambient();
1009         }
1010 #else
1011         gameseq_post_event(GS_EVENT_QUIT_GAME);
1012 #endif
1013 }
1014
1015
1016 // do a frame for the main hall
1017 void main_hall_do(float frametime)
1018 {
1019         int code, key, snazzy_action;   
1020
1021         // need to ensure ambient is playing, since it may be stopped by a playing movie
1022         main_hall_start_ambient();
1023
1024         // handle any animation details 
1025         main_hall_handle_misc_anims();
1026         main_hall_handle_region_anims();
1027
1028         // handle any random intercom sound details
1029         main_hall_handle_random_intercom_sounds();
1030
1031         // handle any mouse clicks
1032         main_hall_handle_right_clicks();        
1033
1034         // handle any sound details
1035         main_hall_cull_door_sounds();   
1036
1037         // process any keypresses/mouse events
1038         snazzy_action = -1;
1039         code = snazzy_menu_do(Main_hall_mask_data, Main_hall_mask_w, Main_hall_mask_h, Main_hall_num_options, Main_hall_region, &snazzy_action, 1, &key);
1040
1041         if(key){
1042                 extern void game_process_cheats(int k);
1043                 game_process_cheats(key);
1044         }
1045         switch(key){
1046         case SDLK_RETURN:
1047                 snazzy_action = SNAZZY_CLICKED; 
1048                 break;
1049
1050 #if 0 //#ifndef NDEBUG  
1051         case SDLK_1:
1052                 movie_play("endprt2b.mve");
1053                 break;
1054         case SDLK_2:
1055                 movie_play_two("endprt2a.mve", "endprt2b.mve");
1056                 break;
1057         case SDLK_3:
1058                 main_hall_campaign_cheat();     
1059                 break;  
1060         case KEY_DEBUGGED + SDLK_d:
1061                 demo_start_playback("test.fsd");
1062                 break;
1063         }
1064 #else 
1065         }
1066 #endif
1067
1068         // do any processing based upon what happened to the snazzy menu
1069         switch (snazzy_action) {
1070         case SNAZZY_OVER:
1071                 main_hall_handle_mouse_location(code);
1072                 break;
1073
1074         case SNAZZY_CLICKED:
1075                 switch (code) {
1076                 // clicked on the exit region
1077                 case EXIT_REGION:
1078                         gamesnd_play_iface(SND_IFACE_MOUSE_CLICK);
1079                         main_hall_exit_game();
1080                         break;
1081
1082                 // clicked on the readyroom region
1083                 case READY_ROOM_REGION:
1084 #ifdef MULTIPLAYER_BETA_BUILD
1085                         gamesnd_play_iface(SND_IFACE_MOUSE_CLICK);
1086                         Player->flags |= PLAYER_FLAGS_IS_MULTI;
1087                         main_hall_do_multi_ready();
1088 #elif defined(E3_BUILD) || defined(PRESS_TOUR_BUILD)                                                                    
1089                         gameseq_post_event(GS_EVENT_NEW_CAMPAIGN);                      
1090 #else
1091                         if (Player->flags & PLAYER_FLAGS_IS_MULTI){
1092                                 gamesnd_play_iface(SND_IFACE_MOUSE_CLICK);
1093                                 main_hall_do_multi_ready();
1094                         } else {                                
1095                                 if(strlen(Main_hall_campaign_cheat)){
1096                                         gameseq_post_event(GS_EVENT_CAMPAIGN_CHEAT);
1097                                 } else {
1098                                         gameseq_post_event(GS_EVENT_NEW_CAMPAIGN);                              
1099                                 }
1100                                 gamesnd_play_iface(SND_IFACE_MOUSE_CLICK);                              
1101                         }
1102 #endif
1103                         break;
1104
1105                 // clicked on the tech room region
1106                 case TECH_ROOM_REGION:
1107 #if defined(FS2_DEMO) || defined(FS1_DEMO)
1108                         gamesnd_play_iface(SND_IFACE_MOUSE_CLICK);
1109                         game_feature_not_in_demo_popup();
1110 #else
1111                         gamesnd_play_iface(SND_IFACE_MOUSE_CLICK);
1112                         gameseq_post_event( GS_EVENT_TECH_MENU );
1113 #endif
1114                         break;
1115
1116                 // clicked on the options region
1117                 case OPTIONS_REGION:
1118                         gamesnd_play_iface(SND_IFACE_MOUSE_CLICK);
1119                         gameseq_post_event(GS_EVENT_OPTIONS_MENU);
1120                         break;
1121
1122                 // clicked on the campaign toom region
1123                 case CAMPAIGN_ROOM_REGION:
1124 #if !defined(MULTIPLAYER_BETA_BUILD) && !defined(E3_BUILD) && !defined(PRESS_TOUR_BUILD)
1125
1126 #if defined(FS2_DEMO) || defined(FS1_DEMO)
1127                         gamesnd_play_iface(SND_IFACE_MOUSE_CLICK);
1128                         {
1129                         //game_feature_not_in_demo_popup();
1130                         int reset_campaign = popup(PF_USE_AFFIRMATIVE_ICON|PF_BODY_BIG, 2, "Exit", "Restart Campaign", "Campaign Room only available in full version. However, you may restart the campaign.");
1131                         if (reset_campaign == 1) {
1132                                 mission_campaign_savefile_delete(Campaign.filename);
1133                                 mission_campaign_load(Campaign.filename);
1134                                 mission_campaign_next_mission();
1135                         }
1136                         }
1137
1138 #else
1139                         if(Player->flags & PLAYER_FLAGS_IS_MULTI){
1140                                 gamesnd_play_iface(SND_IFACE_MOUSE_CLICK);
1141                                 main_hall_set_notify_string(XSTR( "Campaign Room not valid for multiplayer pilots", 366));
1142                         } else {
1143                                 gamesnd_play_iface(SND_IFACE_MOUSE_CLICK);
1144                                 gameseq_post_event(GS_EVENT_CAMPAIGN_ROOM);                     
1145                         }
1146 #endif
1147
1148 #endif
1149                         break;
1150
1151                 // clicked on the multiplayer region
1152                 case MULTIPLAYER_REGION:
1153 #if defined(DEMO) || defined(OEM_BUILD) // not for FS2_DEMO
1154                         game_feature_not_in_demo_popup();
1155 #else
1156                         if (Player->flags & PLAYER_FLAGS_IS_MULTI){
1157                                 // NOTE : this isn't a great thing to be calling this anymore. But we'll leave it for now
1158                                 gameseq_post_event( GS_EVENT_MULTI_JOIN_GAME );
1159                         } else {
1160                                 main_hall_set_notify_string(XSTR( "Not a valid multiplayer pilot!!", 367));
1161                         }
1162 #endif
1163                         break;
1164
1165                 // load mission key was pressed
1166                 case LOAD_MISSION_REGION:
1167                         Int3();
1168                         break;
1169
1170                 // quick start a game region
1171                 case QUICK_START_REGION:
1172 #if !defined(NDEBUG) && !(defined(FS2_DEMO) || defined(FS1_DEMO))
1173                         if (Player->flags & PLAYER_FLAGS_IS_MULTI){
1174                                 main_hall_set_notify_string(XSTR( "Quick Start not valid for multiplayer pilots", 369));
1175                         } else {
1176
1177                                 if (Num_recent_missions > 0)    {
1178                                         SDL_strlcpy( Game_current_mission_filename, Recent_missions[0], SDL_arraysize(Game_current_mission_filename) );
1179                                 } else {
1180                                         mission_load_up_campaign();
1181                                         SDL_strlcpy( Game_current_mission_filename, Campaign.missions[0].name, SDL_arraysize(Game_current_mission_filename) );
1182                                 }
1183
1184                                 Campaign.current_mission = -1;
1185                                 gameseq_post_event(GS_EVENT_START_GAME_QUICK);
1186                         }
1187 #endif
1188                         break;
1189
1190                 // clicked on the barracks region
1191                 case BARRACKS_REGION:                   
1192                         gamesnd_play_iface(SND_IFACE_MOUSE_CLICK);
1193                         gameseq_post_event( GS_EVENT_BARRACKS_MENU );
1194                         break;
1195
1196                 // increate the skill level
1197                 case SKILL_LEVEL_REGION: 
1198                         char temp[100];
1199
1200                         game_increase_skill_level();
1201                         SDL_snprintf(temp, SDL_arraysize(temp), XSTR( "Skill level set to %s.", 370), Skill_level_names(Game_skill_level));
1202                         main_hall_set_notify_string(temp);
1203                         break;                          
1204
1205                 // escape was pressed
1206                 case ESC_PRESSED:
1207                         // if there is a help overlay active, then don't quit the game - just kill the overlay
1208                         if(!help_overlay_active(Main_hall_overlay_id)){
1209                                 gamesnd_play_iface(SND_IFACE_MOUSE_CLICK);
1210                                 main_hall_exit_game();
1211                         }
1212                         // kill the overlay
1213                         else {
1214                                 help_overlay_set_state(Main_hall_overlay_id,0);
1215                         }
1216                         break;
1217                 }
1218
1219                 // if the escape key wasn't pressed handle any mouse position related events
1220                 if (code != ESC_PRESSED){
1221                         main_hall_handle_mouse_location(code);
1222                 }
1223                 break;
1224
1225                 default:
1226                         main_hall_handle_mouse_location(-1);
1227                         break;
1228         }
1229
1230         if ( mouse_down(MOUSE_LEFT_BUTTON) ) {
1231                 help_overlay_set_state(Main_hall_overlay_id, 0);
1232         }
1233
1234         // draw the background bitmap   
1235         gr_reset_clip();        
1236         GR_MAYBE_CLEAR_RES(Main_hall_bitmap);
1237         if(Main_hall_bitmap >= 0){
1238                 gr_set_bitmap(Main_hall_bitmap, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);
1239                 gr_bitmap(0, 0);
1240         }
1241
1242         // draw any pending notification messages
1243         main_hall_notify_do();                  
1244
1245         // render misc animations
1246         main_hall_render_misc_anims(frametime);
1247
1248         // render door animtions
1249         main_hall_render_door_anims(frametime); 
1250
1251         // blit any appropriate tooltips
1252         main_hall_maybe_blit_tooltips();
1253
1254         // fishtank
1255         fishtank_process();
1256
1257         // process any help "hit f1" timestamps and display any messages if necessary
1258         if (Main_hall_help_stamp != -1) {
1259                 main_hall_process_help_stuff();
1260         }
1261
1262         // blit help overlay if active
1263         help_overlay_maybe_blit(Main_hall_overlay_id);
1264
1265         // blit the freespace version #
1266         main_hall_blit_version();
1267
1268         // blit ship and weapon table status
1269         main_hall_blit_table_status();
1270
1271         // if we're in nice D3D texture format
1272 #ifndef NDEBUG
1273         gr_set_color_fast(&Color_white);
1274
1275         // d3d
1276         gr_string(320, gr_screen.max_h - 10, "ARGB");
1277
1278         //      extern int D3D_fog_mode;
1279         //      extern int D3D_zbias;
1280
1281         if ( gr_is_32bit() ) {
1282                 gr_string(320, gr_screen.max_h - 30, "32bit");
1283         }
1284         //      gr_printf(320, gr_screen.max_h - 40, "Fog : %d", D3D_fog_mode);
1285         //      gr_printf(320, gr_screen.max_h - 50, "Zbias : %d", D3D_zbias);
1286         // extern void d3d_test();
1287         // d3d_test();
1288 #endif  
1289
1290         gr_flip();
1291
1292         // maybe run the player tips popup
1293 // #if defined(FS2_DEMO) && defined(NDEBUG)
1294         player_tips_popup();
1295 // #endif
1296
1297         // if we were supposed to skip a frame, then stop doing it after 1 frame
1298         if(Main_hall_frame_skip){
1299                 Main_hall_frame_skip = 0;
1300         }
1301 }
1302
1303 // close the main hall proper
1304 void main_hall_close()
1305 {
1306         int idx,s_idx;
1307
1308         if(!Main_hall_inited){
1309                 return;
1310         }       
1311
1312         // unload the main hall bitmap
1313         if(Main_hall_bitmap != -1){
1314                 bm_unload(Main_hall_bitmap);
1315         }
1316
1317         // unload any bitmaps
1318         if(Main_hall_mask >= 0){                
1319                 // make sure we unlock the mask bitmap so it can be unloaded
1320                 bm_unlock(Main_hall_mask);
1321                 if(!bm_unload(Main_hall_mask)){
1322                         nprintf(("General","WARNING! Couldn't unload main hall mask bitmap!\n"));
1323                 }
1324         }
1325
1326         // free up any (possibly) playing misc animation handles
1327         for(idx=0;idx<Main_hall->num_misc_animations;idx++){
1328                 if(Main_hall_misc_anim_instance[idx]!=NULL){
1329                         anim_stop_playing(Main_hall_misc_anim_instance[idx]);
1330                         Main_hall_misc_anim_instance[idx] = NULL;
1331                 }
1332         }
1333         
1334         // free up any (possibly) playing door animation handles
1335         for(idx=0;idx<Main_hall->num_door_animations;idx++){
1336                 if(Main_hall_door_anim_instance[idx]!=NULL){
1337                         anim_stop_playing(Main_hall_door_anim_instance[idx]);
1338                         Main_hall_door_anim_instance[idx] = NULL;
1339                 }
1340         }
1341         
1342
1343         // free up any misc animations/instances        
1344         for(idx=0;idx<Main_hall->num_misc_animations;idx++){
1345                 if((Main_hall_misc_anim_instance[idx]!=NULL) && (anim_playing(Main_hall_misc_anim_instance[idx]))){             
1346                         Main_hall_misc_anim_instance[idx] = NULL;
1347                 }
1348                 if(Main_hall_misc_anim[idx]!=NULL){
1349                         if(anim_free(Main_hall_misc_anim[idx]) == -1){
1350                                 nprintf(("General","WARNING!, Could not free up misc anim %s in main hall\n",Main_hall->misc_anim_name[idx]));
1351                         }
1352                 }       
1353         }
1354
1355         // free up any door animations/instances
1356         for(idx=0;idx<Main_hall->num_door_animations;idx++){
1357                 if((Main_hall_door_anim_instance[idx]!=NULL) && (anim_playing(Main_hall_door_anim_instance[idx]))){
1358                         Main_hall_door_anim_instance[idx] = NULL;                       
1359                 }
1360                 if(Main_hall_door_anim[idx]!=NULL){
1361                         if(anim_free(Main_hall_door_anim[idx]) == -1){
1362                                 nprintf(("General","WARNING!, Could not free up door anim %s in main hall\n",Main_hall->door_anim_name[idx]));
1363                         }
1364                 }               
1365         }       
1366
1367         // stop any playing door sounds
1368         for(idx=0;idx<Main_hall->num_door_sounds-2;idx++){      // don't cut off the glow sounds (requested by Dan)
1369                 if((Main_hall_door_sound_handles[idx] != -1) && snd_is_playing(Main_hall_door_sound_handles[idx])){
1370                         snd_stop(Main_hall_door_sound_handles[idx]);
1371                         Main_hall_door_sound_handles[idx] = -1;
1372                 }
1373         }       
1374
1375         // stop any playing misc animation sounds
1376         for(idx=0;idx<Main_hall->num_misc_animations;idx++){
1377                 for(s_idx=1;s_idx<10;s_idx++){
1378                         if(snd_is_playing(Main_hall->misc_anim_sound_handles[idx][s_idx])){
1379                                 snd_stop(Main_hall->misc_anim_sound_handles[idx][s_idx]);
1380                                 Main_hall->misc_anim_sound_handles[idx][s_idx] = -1;
1381                         }
1382                 }
1383         }
1384
1385         // unload the overlay bitmap
1386         help_overlay_unload(Main_hall_overlay_id);
1387
1388         // close any snazzy menu details
1389         snazzy_menu_close();
1390
1391         // restore
1392         palette_restore_palette();
1393
1394         // no fish
1395         fishtank_stop();        
1396
1397         // not inited anymore
1398         Main_hall_inited = 0;
1399 }
1400
1401 // start the main hall music playing
1402 void main_hall_start_music()
1403 {
1404         // start a looping ambient sound
1405         main_hall_start_ambient();
1406
1407         // if we have selected no music, then don't do this
1408         if ( Cmdline_freespace_no_music ) {
1409                 return;
1410         }
1411
1412         int main_hall_spooled_music_index = event_music_get_spooled_music_index(Main_hall->music);
1413         
1414         if ((Main_hall_music_handle == -1) && (main_hall_spooled_music_index != -1)) {
1415                 char *music_wavfile_name = Spooled_music[main_hall_spooled_music_index].filename;
1416                 if (music_wavfile_name != NULL) {
1417                                 Main_hall_music_handle = audiostream_open( music_wavfile_name, ASF_EVENTMUSIC );
1418                                 if ( Main_hall_music_handle != -1 )
1419                                         audiostream_play(Main_hall_music_handle, Master_event_music_volume);
1420                 }
1421                 else {
1422                         nprintf(("Warning", "No music file exists to play music at the main menu!\n"));
1423                 }
1424         }
1425 }
1426
1427 // stop the main hall music
1428 void main_hall_stop_music()
1429 {
1430         if ( Main_hall_music_handle != -1 ) {
1431                 audiostream_close_file(Main_hall_music_handle);
1432                 Main_hall_music_handle = -1;
1433         }
1434 }
1435
1436 // do any necessary instantiation of misc animations
1437 void main_hall_handle_misc_anims()
1438 {
1439         int idx,s_idx;
1440
1441         if(Main_hall_frame_skip)
1442                 return;
1443         
1444         for(idx=0;idx<Main_hall->num_misc_animations;idx++){
1445                 // if the anim isn't playing
1446                 if(Main_hall_misc_anim_instance[idx] == NULL){
1447                         // if the timestamp is -1, then reset it to some random value (based on MIN and MAX) and continue
1448                         if(Main_hall->misc_anim_delay[idx][0] == -1){
1449                                 Main_hall->misc_anim_delay[idx][0] = timestamp(Main_hall->misc_anim_delay[idx][1] + 
1450                                                                                                                       (int)(((float)myrand()/(float)MY_RAND_MAX) * (float)(Main_hall->misc_anim_delay[idx][2] - Main_hall->misc_anim_delay[idx][1])));
1451
1452                         // if the timestamp is not -1 and has popped, play the anim and make the timestap -1
1453                         } else if (timestamp_elapsed(Main_hall->misc_anim_delay[idx][0]) && Main_hall_misc_anim[idx]) {
1454                                 anim_play_struct aps;
1455
1456                                 anim_play_init(&aps, Main_hall_misc_anim[idx], Main_hall->misc_anim_coords[idx][0], Main_hall->misc_anim_coords[idx][1]);
1457                                 aps.screen_id = GS_STATE_MAIN_MENU;
1458                                 aps.framerate_independent = 1;
1459                                 
1460                                 Main_hall_misc_anim_instance[idx] = anim_play(&aps);                            
1461                                 
1462                                 // kill the timestamp   
1463                                 Main_hall->misc_anim_delay[idx][0] = -1;                                
1464
1465                                 // reset the "should be playing" flags
1466                                 for(s_idx=1;s_idx<10;s_idx++){
1467                                         Main_hall->misc_anim_sound_flag[idx][s_idx] = 0;
1468                                 }
1469                         }
1470                 }               
1471                 // if the anim is playing
1472                 else {
1473                         // check to see if any special trigger points have been reached by the animation
1474                         // since the frame triggers must be in ascending order, we will count down so that we don't trigger too many sounds
1475                         for(s_idx=Main_hall->misc_anim_special_sounds[idx][0]; s_idx > 0; s_idx--){
1476                                 // if we've passed the trigger point, then play the sound and break out of the loop
1477                                 if((Main_hall_misc_anim_instance[idx]->frame_num >= Main_hall->misc_anim_special_trigger[idx][s_idx]) && !Main_hall->misc_anim_sound_flag[idx][s_idx]){                                 
1478                                         Main_hall->misc_anim_sound_flag[idx][s_idx] = 1;
1479
1480                                         // if the sound is already playing, then kill it. This is a pretty safe thing to do since we can assume that
1481                                         // by the time we get to this point again, the sound will have been long finished
1482                                         if(snd_is_playing(Main_hall->misc_anim_sound_handles[idx][s_idx])){
1483                                                 snd_stop(Main_hall->misc_anim_sound_handles[idx][s_idx]);
1484                                                 Main_hall->misc_anim_sound_handles[idx][s_idx] = -1;
1485                                         }
1486                                         // play the sound
1487                                         Main_hall->misc_anim_sound_handles[idx][s_idx] = snd_play(&Snds_iface[Main_hall->misc_anim_special_sounds[idx][s_idx]],Main_hall->misc_anim_sound_pan[idx]);                                    
1488                                         break;
1489                                 }
1490                         }
1491
1492                         // if the animation mode is MISC_ANIM_MODE_HOLD, pause it at the last frame
1493                         if((Main_hall->misc_anim_modes[idx] == MISC_ANIM_MODE_HOLD) && (Main_hall_misc_anim_instance[idx]->frame_num == Main_hall_misc_anim_instance[idx]->stop_at)){                           
1494                                 anim_pause(Main_hall_misc_anim_instance[idx]);
1495                                 Main_hall_misc_anim_instance[idx]->stop_now = FALSE;
1496                         }                       
1497
1498                         // if the animation mode is MISC_ANIM_MODE_LOOP, check to see if it should be looped
1499                         if((Main_hall->misc_anim_modes[idx] == MISC_ANIM_MODE_LOOP) && (Main_hall_misc_anim_instance[idx]->frame_num == Main_hall_misc_anim_instance[idx]->stop_at)){                           
1500                                 anim_release_render_instance(Main_hall_misc_anim_instance[idx]);
1501
1502                                 // start it playing again
1503                                 anim_play_struct aps;
1504
1505                                 anim_play_init(&aps, Main_hall_misc_anim[idx], Main_hall->misc_anim_coords[idx][0], Main_hall->misc_anim_coords[idx][1]);
1506                                 aps.screen_id = GS_STATE_MAIN_MENU;
1507                                 aps.framerate_independent = 1;
1508                                 
1509                                 Main_hall_misc_anim_instance[idx] = anim_play(&aps);                            
1510                                 
1511                                 // kill the timestamp   
1512                                 Main_hall->misc_anim_delay[idx][0] = -1;                                
1513
1514                                 // reset the "should be playing" flags
1515                                 for(s_idx=1;s_idx<10;s_idx++){
1516                                         Main_hall->misc_anim_sound_flag[idx][s_idx] = 0;
1517                                 }
1518                         }                       
1519
1520                         // cull any misc animations which are marked as done (!is_playing)                              
1521                         if(!anim_playing(Main_hall_misc_anim_instance[idx])){                   
1522                                 Main_hall_misc_anim_instance[idx] = NULL;                               
1523                         }
1524                 }                       
1525         }       
1526 }
1527
1528 // render all playing misc animations
1529 void main_hall_render_misc_anims(float frametime)
1530 {
1531         int idx;
1532         
1533         // HACKETY HACK HACK - always render misc anim 3 first, if it is playing
1534         if(Main_hall_misc_anim_instance[2] != NULL){
1535                 anim_render_one(GS_STATE_MAIN_MENU,Main_hall_misc_anim_instance[2],frametime);
1536         }
1537
1538         // render all other animations
1539         for(idx=0;idx<MAX_MISC_ANIMATIONS;idx++){
1540                 // skip anim 3, which was previously rendered, if at all
1541                 if(idx == 2){
1542                         continue;
1543                 }
1544
1545                 // render it
1546                 if(Main_hall_misc_anim_instance[idx] != NULL){
1547                         anim_render_one(GS_STATE_MAIN_MENU,Main_hall_misc_anim_instance[idx],frametime);
1548                 }
1549         }
1550 }
1551
1552 // render all playing door animations
1553 void main_hall_render_door_anims(float frametime)
1554 {
1555         int idx;        
1556
1557         // render all door animations
1558         for(idx=0;idx<MAX_DOOR_ANIMATIONS;idx++){               
1559                 // render it
1560                 if(Main_hall_door_anim_instance[idx] != NULL){
1561                         anim_render_one(GS_STATE_MAIN_MENU,Main_hall_door_anim_instance[idx],frametime);
1562                 }
1563         }
1564 }
1565
1566 // handle starting, stopping and reversing "door" animations
1567 void main_hall_handle_region_anims()
1568 {
1569         int idx;
1570
1571         if(Main_hall_frame_skip)
1572                 return;
1573         
1574         // make sure we make any finished door animations NULL
1575         for(idx=0;idx<Main_hall->num_door_animations;idx++){
1576                 if((Main_hall_door_anim_instance[idx] != NULL) && !anim_playing(Main_hall_door_anim_instance[idx])){
1577                         Main_hall_door_anim_instance[idx] = NULL;
1578                 }
1579         }
1580         
1581         // go through each region animation
1582         for(idx=0;idx<Main_hall->num_door_animations;idx++){
1583                 // if the instance is not null and the animation is playing
1584                 if((Main_hall_door_anim_instance[idx] != NULL) && anim_playing(Main_hall_door_anim_instance[idx])){
1585                         // check to see if we should hold a given door "open"
1586                         if((Main_hall_mouse_region == idx) && (Main_hall_door_anim_instance[idx]->frame_num == Main_hall_door_anim_instance[idx]->stop_at)){
1587                                 anim_pause(Main_hall_door_anim_instance[idx]);
1588                                 Main_hall_door_anim_instance[idx]->stop_now = FALSE;
1589                         }
1590                         // check to see if we should close a door being held open
1591                         if((Main_hall_mouse_region != idx) && (Main_hall_door_anim_instance[idx]->paused)){
1592                                 anim_unpause(Main_hall_door_anim_instance[idx]);
1593                         }
1594                 }               
1595         }       
1596 }
1597
1598 // do any necessary processing based upon the mouse location
1599 void main_hall_handle_mouse_location(int cur_region)
1600 {
1601    if(Main_hall_frame_skip)
1602                 return;
1603
1604         if(cur_region > NUM_MAIN_HALL_MOUSE_REGIONS) {
1605                 // MWA -- inserted return since Int3() was tripped when hitting L from main
1606                 // menu.
1607                 return;         
1608         }
1609
1610         // if the mouse is now over a resgion
1611         if (cur_region != -1) {
1612                 // if we're still over the same region we were last frame, check stuff
1613                 if (cur_region == Main_hall_mouse_region) {
1614                         // if we have a linger timestamp set and it has expired, then get moving                        
1615                         if ((Main_hall_region_linger_stamp != -1) && timestamp_elapsed(Main_hall_region_linger_stamp)) {
1616                                 main_hall_mouse_grab_region(cur_region);                                
1617
1618                                 // release the region linger stamp
1619                                 Main_hall_region_linger_stamp = -1;
1620                         }
1621                 } else {
1622                         // if we're currently on another region, release it
1623                         if ((Main_hall_mouse_region != -1) && (cur_region != Main_hall_mouse_region)) {
1624                                 main_hall_mouse_release_region(Main_hall_mouse_region);
1625                         }
1626                 
1627                         // set the linger time
1628                         if (Main_hall_region_linger_stamp == -1) {
1629                                 Main_hall_mouse_region = cur_region;
1630                                 Main_hall_region_linger_stamp = timestamp(MAIN_HALL_REGION_LINGER);
1631                         }                       
1632                 }
1633         }
1634         // if it was over a region but isn't anymore, release that region
1635         else {
1636                 if (Main_hall_mouse_region != -1) {
1637                         main_hall_mouse_release_region(Main_hall_mouse_region);
1638                         Main_hall_mouse_region = -1;
1639
1640                         // release the region linger timestamp
1641                         Main_hall_region_linger_stamp = -1;
1642                 }
1643         }
1644 }
1645
1646 // if the mouse has moved off of the currently active region, handle the anim accordingly
1647 void main_hall_mouse_release_region(int region)
1648 {
1649         if(Main_hall_frame_skip){
1650                 return;
1651         }
1652
1653         // if the animation is currently playing in the forward direction, change direction and be done, otherwise don't do a thing
1654         if ( (Main_hall_door_anim_instance[region] != NULL) && anim_playing(Main_hall_door_anim_instance[region]) && (Main_hall_door_anim_instance[region]->direction == ANIM_DIRECT_FORWARD)){
1655                 anim_reverse_direction(Main_hall_door_anim_instance[region]);
1656         }
1657
1658         // check for door sounds, ignoring the OPTIONS_REGION (which isn't a door)
1659         if ((Main_hall_door_anim_instance[region] != NULL)) {
1660                 // don't stop the toaster oven or microwave regions from playing all the way through
1661                 if (Main_hall_door_sound_handles[region] != -1) {
1662                         snd_stop(Main_hall_door_sound_handles[region]);
1663                 }
1664                 Main_hall_door_sound_handles[region] = snd_play(&Snds_iface[Main_hall->door_sounds[region][1]], Main_hall->door_sound_pan[region]);
1665
1666                 // make sure to set the sound to play from the right spot
1667                 snd_set_pos(Main_hall_door_sound_handles[region], &Snds_iface[SND_MAIN_HALL_DOOR_CLOSE],
1668                                                 (float)(Main_hall_door_anim_instance[region]->start_at - Main_hall_door_anim_instance[region]->frame_num) / (float)Main_hall_door_anim_instance[region]->parent->total_frames, 1);                      
1669         }
1670 }
1671
1672 // if the mouse has moved on this region, handle it accordingly
1673 void main_hall_mouse_grab_region(int region)
1674 {
1675         if (Main_hall_frame_skip) {
1676                 return;
1677         }
1678
1679         // if the animation is not playing, start it playing
1680         if ( !Main_hall_door_anim_instance[region] ) {
1681                 if ( Main_hall_door_anim[region] ) {
1682                         anim_play_struct aps;
1683
1684                         anim_play_init(&aps, Main_hall_door_anim[region], Main_hall->door_anim_coords[region][0], Main_hall->door_anim_coords[region][1]);
1685                         aps.screen_id = GS_STATE_MAIN_MENU;
1686                         aps.framerate_independent = 1;
1687
1688                         Main_hall_door_anim_instance[region] = anim_play(&aps);
1689                 }
1690         } 
1691         // otherwise if its playing in the reverse direction, change it to the forward direction
1692         else if (Main_hall_door_anim_instance[region]->direction == ANIM_DIRECT_REVERSE) {
1693                 anim_reverse_direction(Main_hall_door_anim_instance[region]);
1694         }
1695
1696         // check for opening/starting sounds
1697         // kill the currently playing sounds if necessary
1698         if(Main_hall_door_sound_handles[region] != -1){                 
1699                 snd_stop(Main_hall_door_sound_handles[region]);
1700         }       
1701         Main_hall_door_sound_handles[region] = snd_play(&Snds_iface[Main_hall->door_sounds[region][0]],Main_hall->door_sound_pan[region]);                              
1702
1703         // start the sound playing at the right spot relative to the completion of the animation                
1704         if(Main_hall_door_anim_instance[region]->frame_num != -1){                      
1705                         snd_set_pos(Main_hall_door_sound_handles[region],&Snds_iface[SND_MAIN_HALL_DOOR_OPEN],
1706                                                         (float)Main_hall_door_anim_instance[region]->frame_num / (float)Main_hall_door_anim_instance[region]->parent->total_frames,1);
1707         }                               
1708 }
1709
1710 // handle any right clicks which may have occured
1711 void main_hall_handle_right_clicks()
1712 {
1713         int new_region;
1714
1715         if(Main_hall_frame_skip)
1716                 return;
1717
1718         // check to see if the button has been clicked
1719         if(!Main_hall_right_click){
1720                 if(mouse_down(MOUSE_RIGHT_BUTTON)){
1721                         // cycle through the available regions
1722                         if(Main_hall_last_clicked_region == NUM_MAIN_HALL_MOUSE_REGIONS - 1){
1723                                 new_region = 0;
1724                         } else
1725                                 new_region = Main_hall_last_clicked_region + 1;
1726
1727                         // set the position of the mouse cursor and the newly clicked region                    
1728                         mouse_set_pos(Main_hall->door_anim_coords[new_region][2],Main_hall->door_anim_coords[new_region][3]);                   
1729
1730                         main_hall_handle_mouse_location(new_region);
1731                         Main_hall_last_clicked_region = new_region;
1732                         
1733                         // set the mouse as being clicked
1734                         Main_hall_right_click = 1;
1735                 }
1736         } 
1737         // set the mouse as being unclicked
1738         else if(Main_hall_right_click && !(mouse_down(MOUSE_RIGHT_BUTTON))){
1739                 Main_hall_right_click = 0;
1740         }
1741 }
1742
1743 // cull any door sounds that have finished playing
1744 void main_hall_cull_door_sounds()
1745 {
1746         int idx;
1747         // basically just set the handle of any finished sound to be -1, so that we know its free any where else in the code we may need it
1748         for(idx=0;idx<Main_hall->num_door_sounds;idx++){
1749                 if((Main_hall_door_sound_handles[idx] != -1) && !snd_is_playing(Main_hall_door_sound_handles[idx])){                    
1750                         Main_hall_door_sound_handles[idx] = -1;
1751                 }
1752         }
1753 }
1754
1755 void main_hall_handle_random_intercom_sounds()
1756 {
1757         // if we have no timestamp for the next random sound, then set on
1758         if((Main_hall_next_intercom_sound_stamp == -1) && (Main_hall_intercom_sound_handle == -1)){
1759                 Main_hall_next_intercom_sound_stamp = timestamp((int)(((float)myrand()/(float)MY_RAND_MAX) * 
1760                                                                     (float)(Main_hall->intercom_delay[Main_hall_next_intercom_sound][1]
1761                                                                                                                                           - Main_hall->intercom_delay[Main_hall_intercom_sound_handle][0])) );          
1762         }
1763
1764         // if the there is no sound playing
1765         if(Main_hall_intercom_sound_handle == -1){
1766                 // if the timestamp has popped, play a sound
1767                 if((Main_hall_next_intercom_sound_stamp != -1) && (timestamp_elapsed(Main_hall_next_intercom_sound_stamp))){
1768                         // play the sound
1769                         Main_hall_intercom_sound_handle = snd_play(&Snds_iface[Main_hall->intercom_sounds[Main_hall_next_intercom_sound]]);                     
1770                         
1771                         // unset the timestamp
1772                         Main_hall_next_intercom_sound_stamp = -1;
1773                 }
1774         }
1775         // if the sound is playing
1776         else {
1777                 // if the sound has finished, set the timestamp and continue
1778                 if(!snd_is_playing(Main_hall_intercom_sound_handle)){
1779                         // increment the next sound
1780                         if(Main_hall_next_intercom_sound >= (Main_hall->num_random_intercom_sounds-1)){
1781                                 Main_hall_next_intercom_sound = 0;
1782                         } else {
1783                                 Main_hall_next_intercom_sound++;
1784                         }
1785
1786                         // set the timestamp
1787                         Main_hall_next_intercom_sound_stamp = timestamp((int)(((float)myrand()/(float)MY_RAND_MAX) * 
1788                                                                     (float)(Main_hall->intercom_delay[Main_hall_next_intercom_sound][1]
1789                                                                                                                                           - Main_hall->intercom_delay[Main_hall_next_intercom_sound][0])) );
1790
1791                         // release the sound handle
1792                         Main_hall_intercom_sound_handle = -1;
1793                 }
1794         }
1795 }
1796
1797 // set the notification string with its decay timeout
1798 void main_hall_set_notify_string(const char *str)
1799 {
1800         SDL_strlcpy(Main_hall_notify_text, str, SDL_arraysize(Main_hall_notify_text));
1801         Main_hall_notify_stamp = timestamp(MAIN_HALL_NOTIFY_TIME);
1802 }
1803
1804 void main_hall_notify_do()
1805 {
1806         // check to see if we should try and do something
1807         if(Main_hall_notify_stamp != -1){
1808            // if the text time has expired
1809                 if(timestamp_elapsed(Main_hall_notify_stamp)){
1810                         SDL_strlcpy(Main_hall_notify_text, "", SDL_arraysize(Main_hall_notify_text));
1811                         Main_hall_notify_stamp = -1;
1812                 } else {
1813                         int w,h;
1814                         gr_set_color_fast(&Color_bright);
1815
1816                         gr_get_string_size(&w,&h,Main_hall_notify_text);
1817                         gr_printf((gr_screen.max_w - w)/2, gr_screen.max_h - 40, Main_hall_notify_text);
1818                 }
1819         }
1820 }
1821
1822 // start a looping ambient sound for main hall
1823 void main_hall_start_ambient()
1824 {
1825         int play_ambient_loop = 0;
1826
1827         if ( Main_hall_ambient_loop == -1 ) {
1828                 play_ambient_loop = 1;
1829         } else {
1830                 if ( !snd_is_playing(Main_hall_ambient_loop) ) {
1831                         play_ambient_loop = 1;
1832                 }
1833         }
1834
1835         if ( play_ambient_loop ) {
1836                 Main_hall_ambient_loop = snd_play_looping(&Snds_iface[SND_MAIN_HALL_AMBIENT]);
1837         }
1838 }
1839
1840 // stop a looping ambient sound for the main hall
1841 void main_hall_stop_ambient()
1842 {
1843         if ( Main_hall_ambient_loop != -1 ) {
1844                 snd_stop(Main_hall_ambient_loop);
1845                 Main_hall_ambient_loop = -1;
1846         }
1847
1848         if ( Main_hall_intercom_sound_handle != -1 ) {
1849                 snd_stop(Main_hall_intercom_sound_handle);
1850                 Main_hall_intercom_sound_handle = -1;
1851         }
1852 }
1853
1854 // Reset the volume of the looping ambient sound.  This is called from the options 
1855 // screen when the looping ambient sound might be playing.
1856 void main_hall_reset_ambient_vol()
1857 {
1858         if ( Main_hall_ambient_loop >= 0 ) {
1859                 snd_set_volume(Main_hall_ambient_loop, Snds_iface[SND_MAIN_HALL_AMBIENT].default_volume);
1860         }
1861 }
1862
1863 // blit the freespace version #
1864 void main_hall_blit_version()
1865 {
1866         char version_string[100];
1867         int w;
1868
1869 #ifdef MAKE_FS1
1870         // don't show if help text or screen active
1871         if ( (Main_hall_help_stamp != -1) || help_overlay_active(Main_hall_overlay_id) ) {
1872                 return;
1873         }
1874 #endif
1875
1876         // format the version string
1877         get_version_string(version_string, SDL_arraysize(version_string));
1878
1879 #ifdef MAKE_FS1
1880         // tack on "EAX", since we have that :)
1881         SDL_strlcat(version_string, " EAX", sizeof(version_string));
1882 #endif
1883
1884         // get the length of the string
1885         gr_get_string_size(&w,NULL,version_string);
1886
1887         // print the string out in the lower right corner
1888         gr_set_color_fast(&Color_white);
1889 #ifdef MAKE_FS1
1890         gr_string(gr_screen.max_w - (w + 10), gr_screen.max_h - 12, version_string);
1891 #else
1892         gr_string(gr_screen.max_w - 55, gr_screen.max_h - 12, version_string);
1893 #endif
1894 }
1895
1896 // blit any necessary tooltips
1897 void main_hall_maybe_blit_tooltips()
1898 {
1899         int w;
1900         int text_index;
1901
1902         // if we're over no region - don't blit anything
1903         if(Main_hall_mouse_region < 0) {
1904                 return;
1905         }
1906
1907 #ifdef MAKE_FS1
1908         // if help text visible then don't show anything
1909         if (Main_hall_help_stamp != -1) {
1910                 return;
1911         }
1912 #endif
1913
1914         // get the index of the proper text to be using
1915         if(Main_hall_mouse_region == READY_ROOM_REGION) {
1916                 // if this is a multiplayer pilot, the ready room region becomes the multiplayer region
1917                 if(Player->flags & PLAYER_FLAGS_IS_MULTI){
1918                         text_index = NUM_REGIONS - 1;
1919                 } else {
1920                         text_index = READY_ROOM_REGION;
1921                 }
1922         } else {
1923                 text_index = Main_hall_mouse_region;
1924         }
1925
1926         // set the color and blit the string
1927         if(!help_overlay_active(Main_hall_overlay_id)) {
1928 #ifndef MAKE_FS1
1929                 int shader_y = (Main_hall->region_yval) - Main_hall_tooltip_padding[gr_screen.res];     // subtract more to pull higher
1930 #endif
1931                 // get the width of the string
1932                 gr_get_string_size(&w, NULL, Main_hall->region_descript[text_index]);
1933
1934 #ifndef MAKE_FS1
1935                 gr_set_shader(&Main_hall_tooltip_shader);
1936                 gr_shade(0, shader_y, gr_screen.clip_width, (gr_screen.clip_height - shader_y));
1937
1938                 gr_set_color_fast(&Color_bright_white);
1939 #else
1940                 gr_set_color_fast(&Color_white);
1941 #endif
1942                 gr_string((gr_screen.max_w - w)/2, Main_hall->region_yval, Main_hall->region_descript[text_index]);
1943         }
1944 }
1945
1946
1947 void main_hall_process_help_stuff()
1948 {
1949         int w, h;
1950         char str[255];
1951         
1952         // if the timestamp has popped, don't do anything
1953         if(Main_hall_help_stamp == -1) {
1954                 return;
1955         }
1956
1957 #ifndef MAKE_FS1
1958         // if the timestamp has popped, advance frame
1959         if(timestamp_elapsed(Main_hall_help_stamp)) {
1960                 Main_hall_f1_text_frame++;
1961         }
1962
1963         // otherwise print out the message
1964         SDL_strlcpy(str, XSTR( "Press F1 for help", 371), SDL_arraysize(str));
1965         gr_get_string_size(&w, &h, str);
1966
1967         int y_anim_offset = Main_hall_f1_text_frame;
1968
1969         // if anim is off the screen finally, stop altogether
1970         if ( (y_anim_offset >= (2*Main_hall_tooltip_padding[gr_screen.res]) + h) || (help_overlay_active(Main_hall_overlay_id)) ) {
1971                 Main_hall_f1_text_frame = -1;
1972                 Main_hall_help_stamp = -1;
1973                 F1_text_done = 1;
1974                 return;
1975         }
1976
1977         // set the color and print out text and shader
1978         gr_set_color_fast(&Color_bright_white);
1979         gr_shade(0, 0, gr_screen.max_w, (2*Main_hall_tooltip_padding[gr_screen.res]) + h - y_anim_offset);
1980         gr_string((gr_screen.max_w - w)/2, Main_hall_tooltip_padding[gr_screen.res] - y_anim_offset, str);
1981 #else
1982         // if the timestamp has popped, stop showing help message
1983         if ( timestamp_elapsed(Main_hall_help_stamp) ) {
1984                 Main_hall_help_stamp = -1;
1985                 return;
1986         }
1987
1988         // otherwise print out the message
1989         SDL_strlcpy(str, XSTR( "Press F1 for help", 371), SDL_arraysize(str));
1990         gr_get_string_size(&w, &h, str);
1991
1992         // set the color and print out text and shader
1993         gr_set_color_fast(&Color_white);
1994         gr_string((gr_screen.max_w - w)/2, 419, str);
1995 #endif
1996 }
1997
1998 // what main hall we're on (should be 0 or 1)
1999 int main_hall_id()
2000 {       
2001         // only 1 of 2 main halls
2002         if(Main_hall == &Main_hall_defines[gr_screen.res][0]){
2003                 return 0;
2004         }
2005
2006         return 1;
2007
2008
2009 // read in main hall table
2010 void main_hall_read_table()
2011 {
2012 #ifndef MAKE_FS1
2013         main_hall_defines *m, temp;
2014         int count, idx, s_idx, m_idx;
2015
2016         // read the file in
2017         read_file_text("mainhall.tbl");
2018         reset_parse();
2019
2020         // go for it
2021         count = 0;
2022         while(!optional_string("#end")){
2023
2024                 // read in 2 resolutions
2025                 for(m_idx=0; m_idx<GR_NUM_RESOLUTIONS; m_idx++){
2026                         // maybe use a temp main hall stuct
2027                         if(count >= NUM_MAIN_HALLS){
2028                                 m = &temp;
2029                         } else {
2030                                 m = &Main_hall_defines[m_idx][count];
2031                         }
2032
2033                         // ready
2034                         required_string("$Main Hall");
2035
2036                         // bitmap and mask
2037                         required_string("+Bitmap:");
2038                         stuff_string(m->bitmap, F_NAME, NULL, MAX_FILENAME_LEN);
2039                         required_string("+Mask:");
2040                         stuff_string(m->mask, F_NAME, NULL, MAX_FILENAME_LEN);
2041 #ifndef FS2_DEMO
2042                         required_string("+Music:");
2043                         stuff_string(m->music, F_NAME, NULL, MAX_FILENAME_LEN);
2044 #endif
2045
2046                         // intercom sounds
2047                         required_string("+Num Intercom Sounds:");
2048                         stuff_int(&m->num_random_intercom_sounds);              
2049                         for(idx=0; idx<m->num_random_intercom_sounds; idx++){                   
2050                                 // intercom delay
2051                                 required_string("+Intercom delay:");
2052                                 stuff_int(&m->intercom_delay[idx][0]);
2053                                 stuff_int(&m->intercom_delay[idx][1]);
2054                         }
2055                         for(idx=0; idx<m->num_random_intercom_sounds; idx++){                   
2056                                 // intercom sound id
2057                                 required_string("+Intercom sound:");
2058                                 stuff_int(&m->intercom_sounds[idx]);                    
2059                         }                       
2060                         for(idx=0; idx<m->num_random_intercom_sounds; idx++){                   
2061                                 // intercom pan
2062                                 required_string("+Intercom pan:");
2063                                 stuff_float(&m->intercom_sound_pan[idx]);                       
2064                         }                       
2065
2066                         // misc animations
2067                         required_string("+Num Misc Animations:");
2068                         stuff_int(&m->num_misc_animations);
2069                         for(idx=0; idx<m->num_misc_animations; idx++){
2070                                 // anim names
2071                                 required_string("+Misc anim:");
2072                                 stuff_string(m->misc_anim_name[idx], F_NAME, NULL);
2073                         }
2074                         for(idx=0; idx<m->num_misc_animations; idx++){
2075                                 // anim delay
2076                                 required_string("+Misc anim delay:");
2077                                 stuff_int(&m->misc_anim_delay[idx][0]);
2078                                 stuff_int(&m->misc_anim_delay[idx][1]);
2079                                 stuff_int(&m->misc_anim_delay[idx][2]);
2080                         }
2081                         for(idx=0; idx<m->num_misc_animations; idx++){
2082                                 // anim coords
2083                                 required_string("+Misc anim coords:");
2084                                 stuff_int(&m->misc_anim_coords[idx][0]);
2085                                 stuff_int(&m->misc_anim_coords[idx][1]);
2086                         }
2087                         for(idx=0; idx<m->num_misc_animations; idx++){
2088                                 // anim mode
2089                                 required_string("+Misc anim mode:");
2090                                 stuff_int(&m->misc_anim_modes[idx]);                    
2091                         }
2092                         for(idx=0; idx<m->num_misc_animations; idx++){
2093                                 // anim pan
2094                                 required_string("+Misc anim pan:");
2095                                 stuff_float(&m->misc_anim_sound_pan[idx]);
2096                         }
2097                         for(idx=0; idx<m->num_misc_animations; idx++){
2098                                 // anim sound id
2099                                 required_string("+Misc anim sounds:");
2100                                 stuff_int(&m->misc_anim_special_sounds[idx][0]);
2101                                 for(s_idx=0; s_idx<m->misc_anim_special_sounds[idx][0]; s_idx++){
2102                                         stuff_int(&m->misc_anim_special_sounds[idx][s_idx + 1]);
2103                                 }
2104                         }
2105                         for(idx=0; idx<m->num_misc_animations; idx++){
2106                                 // anim sound triggers
2107                                 required_string("+Misc anim trigger:");
2108                                 stuff_int(&m->misc_anim_special_trigger[idx][0]);
2109                                 for(s_idx=0; s_idx<m->misc_anim_special_trigger[idx][0]; s_idx++){
2110                                         stuff_int(&m->misc_anim_special_trigger[idx][s_idx + 1]);
2111                                 }
2112                         }
2113                         for(idx=0; idx<m->num_misc_animations; idx++){
2114                                 // anim sound handles
2115                                 required_string("+Misc anim handles:");
2116                                 stuff_int(&m->misc_anim_sound_handles[idx][0]);                 
2117                         }
2118                         for(idx=0; idx<m->num_misc_animations; idx++){
2119                                 // anim sound flags
2120                                 required_string("+Misc anim flags:");
2121                                 stuff_int(&m->misc_anim_sound_flag[idx][0]);                    
2122                         }
2123
2124                         // door animations
2125                         required_string("+Num Door Animations:");
2126                         stuff_int(&m->num_door_animations);
2127                         for(idx=0; idx<m->num_door_animations; idx++){
2128                                 // door name
2129                                 required_string("+Door anim:");
2130                                 stuff_string(m->door_anim_name[idx], F_NAME, NULL);
2131                         }
2132                         for(idx=0; idx<m->num_door_animations; idx++){
2133                                 // door coords
2134                                 required_string("+Door coords:");
2135                                 stuff_int(&m->door_anim_coords[idx][0]);
2136                                 stuff_int(&m->door_anim_coords[idx][1]);
2137                                 stuff_int(&m->door_anim_coords[idx][2]);
2138                                 stuff_int(&m->door_anim_coords[idx][3]);
2139                         }
2140                         for(idx=0; idx<m->num_door_animations; idx++){
2141                                 // door open and close sounds
2142                                 required_string("+Door sounds:");
2143                                 stuff_int(&m->door_sounds[idx][0]);
2144                                 stuff_int(&m->door_sounds[idx][1]);                     
2145                         }
2146                         for(idx=0; idx<m->num_door_animations; idx++){
2147                                 // door pan value
2148                                 required_string("+Door pan:");
2149                                 stuff_float(&m->door_sound_pan[idx]);                   
2150                         }
2151
2152                         // tooltip y location
2153                         required_string("+Tooltip Y:");
2154                         stuff_int(&m->region_yval);
2155                         for(idx=0; idx<NUM_REGIONS; idx++){
2156                                 m->region_descript[idx] = NULL;
2157                         }
2158                 }
2159
2160                 if(count < NUM_MAIN_HALLS){
2161                         count++;
2162                 }
2163         }
2164
2165         // are we funny?
2166         if(Vasudan_funny){
2167                 Main_hall_defines[GR_640][1].door_sounds[OPTIONS_REGION][0] = SND_VASUDAN_BUP;
2168                 Main_hall_defines[GR_640][1].door_sounds[OPTIONS_REGION][1] = SND_VASUDAN_BUP;
2169                 Main_hall_defines[GR_1024][1].door_sounds[OPTIONS_REGION][0] = SND_VASUDAN_BUP;
2170                 Main_hall_defines[GR_1024][1].door_sounds[OPTIONS_REGION][1] = SND_VASUDAN_BUP;
2171
2172                 // set head anim. hehe
2173                 SDL_strlcpy(Main_hall_defines[GR_640][1].door_anim_name[OPTIONS_REGION], "vhallheads", MAX_FILENAME_LEN);
2174                 SDL_strlcpy(Main_hall_defines[GR_1024][1].door_anim_name[OPTIONS_REGION], "2_vhallheads", MAX_FILENAME_LEN);
2175
2176                 // set the background
2177                 SDL_strlcpy(Main_hall_defines[GR_640][1].bitmap, "vhallhead", MAX_FILENAME_LEN);
2178                 SDL_strlcpy(Main_hall_defines[GR_1024][1].bitmap, "2_vhallhead", MAX_FILENAME_LEN);
2179         }
2180 #else
2181         // hard coded values for FS1
2182         int idx;
2183
2184         // Terran main hall
2185         SDL_strlcpy(Main_hall_defines[0][0].bitmap, "MainHall1", MAX_FILENAME_LEN);
2186         SDL_strlcpy(Main_hall_defines[0][0].mask, "MainHall1-m", MAX_FILENAME_LEN);
2187         SDL_strlcpy(Main_hall_defines[0][0].music, "Choco Mousse", MAX_FILENAME_LEN);
2188         
2189         Main_hall_defines[0][0].num_random_intercom_sounds = 3;
2190         Main_hall_defines[0][0].intercom_delay[0][0] = 8000;
2191         Main_hall_defines[0][0].intercom_delay[0][1] = 15000;
2192         Main_hall_defines[0][0].intercom_delay[1][0] = 8000;
2193         Main_hall_defines[0][0].intercom_delay[1][1] = 15000;
2194         Main_hall_defines[0][0].intercom_delay[2][0] = 8000;
2195         Main_hall_defines[0][0].intercom_delay[2][1] = 15000;
2196         Main_hall_defines[0][0].intercom_sounds[0] = 38;
2197         Main_hall_defines[0][0].intercom_sounds[1] = 39;
2198         Main_hall_defines[0][0].intercom_sounds[2] = 40;
2199         Main_hall_defines[0][0].intercom_sound_pan[0] = 0.0f;
2200         Main_hall_defines[0][0].intercom_sound_pan[1] = 0.0f;
2201         Main_hall_defines[0][0].intercom_sound_pan[2] = 0.0f;
2202         
2203         Main_hall_defines[0][0].num_misc_animations = 2;
2204         SDL_strlcpy(Main_hall_defines[0][0].misc_anim_name[0], "main1-m1", MAX_FILENAME_LEN);
2205         SDL_strlcpy(Main_hall_defines[0][0].misc_anim_name[1], "main1-m2", MAX_FILENAME_LEN);
2206         Main_hall_defines[0][0].misc_anim_delay[0][0] = -1;
2207         Main_hall_defines[0][0].misc_anim_delay[0][1] = 0;//15000;
2208         Main_hall_defines[0][0].misc_anim_delay[0][2] = 0;//20000;
2209         Main_hall_defines[0][0].misc_anim_delay[1][0] = -1;
2210         Main_hall_defines[0][0].misc_anim_delay[1][1] = 9000;
2211         Main_hall_defines[0][0].misc_anim_delay[1][2] = 30000;
2212         Main_hall_defines[0][0].misc_anim_coords[0][0] = 14;
2213         Main_hall_defines[0][0].misc_anim_coords[0][1] = 14;
2214         Main_hall_defines[0][0].misc_anim_coords[1][0] = 174;
2215         Main_hall_defines[0][0].misc_anim_coords[1][1] = 198;
2216         Main_hall_defines[0][0].misc_anim_modes[0] = 0;
2217         Main_hall_defines[0][0].misc_anim_modes[1] = 2;
2218         Main_hall_defines[0][0].misc_anim_sound_pan[0] = -0.5f;
2219         Main_hall_defines[0][0].misc_anim_sound_pan[1] = -0.25f;
2220         Main_hall_defines[0][0].misc_anim_special_sounds[0][0] = 4;
2221         Main_hall_defines[0][0].misc_anim_special_sounds[0][1] = 34;
2222         Main_hall_defines[0][0].misc_anim_special_sounds[0][2] = 35;
2223         Main_hall_defines[0][0].misc_anim_special_sounds[0][3] = 34;
2224         Main_hall_defines[0][0].misc_anim_special_sounds[0][4] = 35;
2225         Main_hall_defines[0][0].misc_anim_special_sounds[1][0] = 0;
2226         Main_hall_defines[0][0].misc_anim_special_trigger[0][0] = 4;
2227         Main_hall_defines[0][0].misc_anim_special_trigger[0][1] = 2;
2228         Main_hall_defines[0][0].misc_anim_special_trigger[0][2] = 20;
2229         Main_hall_defines[0][0].misc_anim_special_trigger[0][3] = 43;
2230         Main_hall_defines[0][0].misc_anim_special_trigger[0][4] = 97;
2231         Main_hall_defines[0][0].misc_anim_special_trigger[1][0] = 0;
2232         Main_hall_defines[0][0].misc_anim_sound_handles[0][0] = 4;
2233         Main_hall_defines[0][0].misc_anim_sound_handles[1][0] = 0;
2234         Main_hall_defines[0][0].misc_anim_sound_flag[0][0] = 0;
2235         Main_hall_defines[0][0].misc_anim_sound_flag[1][0] = 2;
2236         
2237         Main_hall_defines[0][0].num_door_animations = 6;
2238         SDL_strlcpy(Main_hall_defines[0][0].door_anim_name[0], "main1-d1", MAX_FILENAME_LEN);
2239         SDL_strlcpy(Main_hall_defines[0][0].door_anim_name[1], "main1-d6", MAX_FILENAME_LEN);
2240         SDL_strlcpy(Main_hall_defines[0][0].door_anim_name[2], "main1-d3", MAX_FILENAME_LEN);
2241         SDL_strlcpy(Main_hall_defines[0][0].door_anim_name[3], "main1-d4", MAX_FILENAME_LEN);
2242         SDL_strlcpy(Main_hall_defines[0][0].door_anim_name[4], "main1-d5", MAX_FILENAME_LEN);
2243         SDL_strlcpy(Main_hall_defines[0][0].door_anim_name[5], "main1-d2", MAX_FILENAME_LEN);
2244         Main_hall_defines[0][0].door_anim_coords[0][0] = 68;
2245         Main_hall_defines[0][0].door_anim_coords[0][1] = 260;
2246         Main_hall_defines[0][0].door_anim_coords[0][2] = 103;
2247         Main_hall_defines[0][0].door_anim_coords[0][3] = 298;
2248         Main_hall_defines[0][0].door_anim_coords[1][0] = 309;
2249         Main_hall_defines[0][0].door_anim_coords[1][1] = 34;
2250         Main_hall_defines[0][0].door_anim_coords[1][2] = 110;
2251         Main_hall_defines[0][0].door_anim_coords[1][3] = 61;
2252         Main_hall_defines[0][0].door_anim_coords[2][0] = 312;
2253         Main_hall_defines[0][0].door_anim_coords[2][1] = 264;
2254         Main_hall_defines[0][0].door_anim_coords[2][2] = 385;
2255         Main_hall_defines[0][0].door_anim_coords[2][3] = 330;
2256         Main_hall_defines[0][0].door_anim_coords[3][0] = 457;
2257         Main_hall_defines[0][0].door_anim_coords[3][1] = 34;
2258         Main_hall_defines[0][0].door_anim_coords[3][2] = 404;
2259         Main_hall_defines[0][0].door_anim_coords[3][3] = 367;
2260         Main_hall_defines[0][0].door_anim_coords[4][0] = 530;
2261         Main_hall_defines[0][0].door_anim_coords[4][1] = 206;
2262         Main_hall_defines[0][0].door_anim_coords[4][2] = 174;
2263         Main_hall_defines[0][0].door_anim_coords[4][3] = 412;
2264         Main_hall_defines[0][0].door_anim_coords[5][0] = 305;
2265         Main_hall_defines[0][0].door_anim_coords[5][1] = 133;
2266         Main_hall_defines[0][0].door_anim_coords[5][2] = 385;
2267         Main_hall_defines[0][0].door_anim_coords[5][3] = 330;
2268         Main_hall_defines[0][0].door_sounds[0][0] = 23;
2269         Main_hall_defines[0][0].door_sounds[0][1] = 24;
2270         Main_hall_defines[0][0].door_sounds[1][0] = 23;
2271         Main_hall_defines[0][0].door_sounds[1][1] = 24;
2272         Main_hall_defines[0][0].door_sounds[2][0] = 23;
2273         Main_hall_defines[0][0].door_sounds[2][1] = 24;
2274         Main_hall_defines[0][0].door_sounds[3][0] = 25;
2275         Main_hall_defines[0][0].door_sounds[3][1] = 26;
2276         Main_hall_defines[0][0].door_sounds[4][0] = 25;
2277         Main_hall_defines[0][0].door_sounds[4][1] = 26;
2278         Main_hall_defines[0][0].door_sounds[5][0] = 23;
2279         Main_hall_defines[0][0].door_sounds[5][1] = 24;
2280         Main_hall_defines[0][0].door_sound_pan[0] = -0.7f;
2281         Main_hall_defines[0][0].door_sound_pan[1] = 0.07f;
2282         Main_hall_defines[0][0].door_sound_pan[2] = 0.2f;
2283         Main_hall_defines[0][0].door_sound_pan[3] = 0.73f;
2284         Main_hall_defines[0][0].door_sound_pan[4] = 0.75f;
2285         Main_hall_defines[0][0].door_sound_pan[5] = 0.11f;
2286         
2287         Main_hall_defines[0][0].region_yval = 455;
2288         
2289         for (idx = 0; idx < NUM_REGIONS; idx++) {
2290                 Main_hall_defines[0][0].region_descript[idx] = NULL;
2291         }
2292         
2293         
2294         // Vasudan main hall
2295         SDL_strlcpy(Main_hall_defines[0][1].bitmap, "MainHall2", MAX_FILENAME_LEN);
2296         SDL_strlcpy(Main_hall_defines[0][1].mask, "MainHall2-m", MAX_FILENAME_LEN);
2297         SDL_strlcpy(Main_hall_defines[0][1].music, "Choco Mousse", MAX_FILENAME_LEN);
2298         
2299         Main_hall_defines[0][1].num_random_intercom_sounds = 3;
2300         Main_hall_defines[0][1].intercom_delay[0][0] = 8000;
2301         Main_hall_defines[0][1].intercom_delay[0][1] = 15000;
2302         Main_hall_defines[0][1].intercom_delay[1][0] = 8000;
2303         Main_hall_defines[0][1].intercom_delay[1][1] = 15000;
2304         Main_hall_defines[0][1].intercom_delay[2][0] = 8000;
2305         Main_hall_defines[0][1].intercom_delay[2][1] = 15000;
2306         Main_hall_defines[0][1].intercom_sounds[0] = 49;
2307         Main_hall_defines[0][1].intercom_sounds[1] = 50;
2308         Main_hall_defines[0][1].intercom_sounds[2] = 51;
2309         Main_hall_defines[0][1].intercom_sound_pan[0] = 0.0f;
2310         Main_hall_defines[0][1].intercom_sound_pan[1] = 0.0f;
2311         Main_hall_defines[0][1].intercom_sound_pan[2] = 0.0f;
2312         
2313         Main_hall_defines[0][1].num_misc_animations = 4;
2314         SDL_strlcpy(Main_hall_defines[0][1].misc_anim_name[0], "main2-m1", MAX_FILENAME_LEN);
2315         SDL_strlcpy(Main_hall_defines[0][1].misc_anim_name[1], "main2-m2", MAX_FILENAME_LEN);
2316         SDL_strlcpy(Main_hall_defines[0][1].misc_anim_name[2], "main2-m3", MAX_FILENAME_LEN);
2317         SDL_strlcpy(Main_hall_defines[0][1].misc_anim_name[3], "main2-m4", MAX_FILENAME_LEN);
2318         Main_hall_defines[0][1].misc_anim_delay[0][0] = -1;
2319         Main_hall_defines[0][1].misc_anim_delay[0][1] = 0;
2320         Main_hall_defines[0][1].misc_anim_delay[0][2] = 0;
2321         Main_hall_defines[0][1].misc_anim_delay[1][0] = -1;
2322         Main_hall_defines[0][1].misc_anim_delay[1][1] = 0;
2323         Main_hall_defines[0][1].misc_anim_delay[1][2] = 0;
2324         Main_hall_defines[0][1].misc_anim_delay[2][0] = -1;
2325         Main_hall_defines[0][1].misc_anim_delay[2][1] = 0;
2326         Main_hall_defines[0][1].misc_anim_delay[2][2] = 0;
2327         Main_hall_defines[0][1].misc_anim_delay[3][0] = -1;
2328         Main_hall_defines[0][1].misc_anim_delay[3][1] = 5000;
2329         Main_hall_defines[0][1].misc_anim_delay[3][2] = 9000;
2330         Main_hall_defines[0][1].misc_anim_coords[0][0] = 0;
2331         Main_hall_defines[0][1].misc_anim_coords[0][1] = 37;
2332         Main_hall_defines[0][1].misc_anim_coords[1][0] = 59;
2333         Main_hall_defines[0][1].misc_anim_coords[1][1] = 0;
2334         Main_hall_defines[0][1].misc_anim_coords[2][0] = 80;
2335         Main_hall_defines[0][1].misc_anim_coords[2][1] = 115;
2336         Main_hall_defines[0][1].misc_anim_coords[3][0] = 0;
2337         Main_hall_defines[0][1].misc_anim_coords[3][1] = 182;
2338         Main_hall_defines[0][1].misc_anim_modes[0] = 0;
2339         Main_hall_defines[0][1].misc_anim_modes[1] = 0;
2340         Main_hall_defines[0][1].misc_anim_modes[2] = 0;
2341         Main_hall_defines[0][1].misc_anim_modes[3] = 1;
2342         Main_hall_defines[0][1].misc_anim_sound_pan[0] = -0.82f;
2343         Main_hall_defines[0][1].misc_anim_sound_pan[1] = -0.5f;
2344         Main_hall_defines[0][1].misc_anim_sound_pan[2] = -0.5f;
2345         Main_hall_defines[0][1].misc_anim_sound_pan[3] = -0.86f;
2346         Main_hall_defines[0][1].misc_anim_special_sounds[0][0] = 2;
2347         Main_hall_defines[0][1].misc_anim_special_sounds[0][1] = 43;
2348         Main_hall_defines[0][1].misc_anim_special_sounds[0][2] = 44;
2349         Main_hall_defines[0][1].misc_anim_special_sounds[1][0] = 2;
2350         Main_hall_defines[0][1].misc_anim_special_sounds[1][1] = 45;
2351         Main_hall_defines[0][1].misc_anim_special_sounds[1][2] = 46;
2352         Main_hall_defines[0][1].misc_anim_special_sounds[2][0] = 2;
2353         Main_hall_defines[0][1].misc_anim_special_sounds[2][1] = 45;
2354         Main_hall_defines[0][1].misc_anim_special_sounds[2][2] = 46;
2355         Main_hall_defines[0][1].misc_anim_special_sounds[3][0] = 2;
2356         Main_hall_defines[0][1].misc_anim_special_sounds[3][1] = 47;
2357         Main_hall_defines[0][1].misc_anim_special_sounds[3][2] = 48;
2358         Main_hall_defines[0][1].misc_anim_special_trigger[0][0] = 2;
2359         Main_hall_defines[0][1].misc_anim_special_trigger[0][1] = 0;
2360         Main_hall_defines[0][1].misc_anim_special_trigger[0][2] = 300;
2361         Main_hall_defines[0][1].misc_anim_special_trigger[1][0] = 2;
2362         Main_hall_defines[0][1].misc_anim_special_trigger[1][1] = 20;
2363         Main_hall_defines[0][1].misc_anim_special_trigger[1][2] = 262;
2364         Main_hall_defines[0][1].misc_anim_special_trigger[2][0] = 2;
2365         Main_hall_defines[0][1].misc_anim_special_trigger[2][1] = 0;
2366         Main_hall_defines[0][1].misc_anim_special_trigger[2][2] = 150;
2367         Main_hall_defines[0][1].misc_anim_special_trigger[3][0] = 2;
2368         Main_hall_defines[0][1].misc_anim_special_trigger[3][1] = 128;
2369         Main_hall_defines[0][1].misc_anim_special_trigger[3][2] = 300;
2370         Main_hall_defines[0][1].misc_anim_sound_handles[0][0] = 2;
2371         Main_hall_defines[0][1].misc_anim_sound_handles[1][0] = 2;
2372         Main_hall_defines[0][1].misc_anim_sound_handles[2][0] = 2;
2373         Main_hall_defines[0][1].misc_anim_sound_handles[3][0] = 2;
2374         Main_hall_defines[0][1].misc_anim_sound_flag[0][0] = 2;
2375         Main_hall_defines[0][1].misc_anim_sound_flag[1][0] = 2;
2376         Main_hall_defines[0][1].misc_anim_sound_flag[2][0] = 2;
2377         Main_hall_defines[0][1].misc_anim_sound_flag[3][0] = 2;
2378         
2379         Main_hall_defines[0][1].num_door_animations = 6;
2380         SDL_strlcpy(Main_hall_defines[0][1].door_anim_name[0], "main2-d1", MAX_FILENAME_LEN);
2381         SDL_strlcpy(Main_hall_defines[0][1].door_anim_name[1], "main2-d6", MAX_FILENAME_LEN);
2382         SDL_strlcpy(Main_hall_defines[0][1].door_anim_name[2], "main2-d3", MAX_FILENAME_LEN);
2383         SDL_strlcpy(Main_hall_defines[0][1].door_anim_name[3], "main2-d4", MAX_FILENAME_LEN);
2384         SDL_strlcpy(Main_hall_defines[0][1].door_anim_name[4], "main2-d5", MAX_FILENAME_LEN);
2385         SDL_strlcpy(Main_hall_defines[0][1].door_anim_name[5], "main2-d2", MAX_FILENAME_LEN);
2386         Main_hall_defines[0][1].door_anim_coords[0][0] = 199;
2387         Main_hall_defines[0][1].door_anim_coords[0][1] = 265;
2388         Main_hall_defines[0][1].door_anim_coords[0][2] = 263;
2389         Main_hall_defines[0][1].door_anim_coords[0][3] = 295;
2390         Main_hall_defines[0][1].door_anim_coords[1][0] = 296;
2391         Main_hall_defines[0][1].door_anim_coords[1][1] = 278;
2392         Main_hall_defines[0][1].door_anim_coords[1][2] = 331;
2393         Main_hall_defines[0][1].door_anim_coords[1][3] = 209;
2394         Main_hall_defines[0][1].door_anim_coords[2][0] = 423;
2395         Main_hall_defines[0][1].door_anim_coords[2][1] = 138;
2396         Main_hall_defines[0][1].door_anim_coords[2][2] = 531;
2397         Main_hall_defines[0][1].door_anim_coords[2][3] = 240;
2398         Main_hall_defines[0][1].door_anim_coords[3][0] = 363;
2399         Main_hall_defines[0][1].door_anim_coords[3][1] = 187;
2400         Main_hall_defines[0][1].door_anim_coords[3][2] = 395;
2401         Main_hall_defines[0][1].door_anim_coords[3][3] = 218;
2402         Main_hall_defines[0][1].door_anim_coords[4][0] = 47;
2403         Main_hall_defines[0][1].door_anim_coords[4][1] = 307;
2404         Main_hall_defines[0][1].door_anim_coords[4][2] = 101;
2405         Main_hall_defines[0][1].door_anim_coords[4][3] = 342;
2406         Main_hall_defines[0][1].door_anim_coords[5][0] = 325;
2407         Main_hall_defines[0][1].door_anim_coords[5][1] = 311;
2408         Main_hall_defines[0][1].door_anim_coords[5][2] = 362;
2409         Main_hall_defines[0][1].door_anim_coords[5][3] = 371;
2410         Main_hall_defines[0][1].door_sounds[0][0] = 23;
2411         Main_hall_defines[0][1].door_sounds[0][1] = 24;
2412         Main_hall_defines[0][1].door_sounds[1][0] = 23;
2413         Main_hall_defines[0][1].door_sounds[1][1] = 24;
2414         Main_hall_defines[0][1].door_sounds[2][0] = 23;
2415         Main_hall_defines[0][1].door_sounds[2][1] = 24;
2416         Main_hall_defines[0][1].door_sounds[3][0] = 25;
2417         Main_hall_defines[0][1].door_sounds[3][1] = 26;
2418         Main_hall_defines[0][1].door_sounds[4][0] = 25;
2419         Main_hall_defines[0][1].door_sounds[4][1] = 26;
2420         Main_hall_defines[0][1].door_sounds[5][0] = 23;
2421         Main_hall_defines[0][1].door_sounds[5][1] = 24;
2422         Main_hall_defines[0][1].door_sound_pan[0] = -0.2f;
2423         Main_hall_defines[0][1].door_sound_pan[1] = 0.12f;
2424         Main_hall_defines[0][1].door_sound_pan[2] = 0.62f;
2425         Main_hall_defines[0][1].door_sound_pan[3] = 0.2f;
2426         Main_hall_defines[0][1].door_sound_pan[4] = -0.63f;
2427         Main_hall_defines[0][1].door_sound_pan[5] = 0.35f;
2428         
2429         Main_hall_defines[0][1].region_yval = 415;
2430         
2431         for (idx = 0; idx < NUM_REGIONS; idx++) {
2432                 Main_hall_defines[0][1].region_descript[idx] = NULL;
2433         }
2434 #endif
2435 }
2436
2437 // make the vasudan main hall funny
2438 void main_hall_vasudan_funny()
2439 {
2440         Vasudan_funny = 1;
2441 }
2442
2443
2444 /*
2445 #include "3d.h"
2446 int argh = -1;
2447 matrix view = {
2448         0.0f, 0.0f, 0.0f,
2449         0.0f, 0.0f, 0.0f,
2450         0.0f, 0.0f, 1.0f
2451 };
2452 */
2453 void d3d_test()
2454 {
2455         /*      
2456         vertex p1;
2457         vector sun_pos = vmd_zero_vector;
2458         sun_pos.z = 1.0f;
2459
2460         if(argh == -1){
2461                 argh = bm_load("sun01");
2462                 bm_lock(argh, 16, BMP_TEX_XPARENT);
2463                 bm_unlock(argh);
2464         }
2465         
2466         g3_start_frame(1);
2467         g3_set_view_matrix(&vmd_zero_vector, &view, 0.5f);      
2468         g3_rotate_vertex(&p1, &sun_pos);
2469         g3_project_vertex(&p1);
2470         gr_zbuffer_set(GR_ZBUFF_NONE);
2471         gr_set_bitmap( argh );
2472         g3_draw_bitmap(&p1, 0, 0.05f, TMAP_FLAG_TEXTURED | TMAP_FLAG_XPARENT);          
2473         g3_end_frame();
2474         */
2475 }
2476