]> icculus.org git repositories - taylor/freespace2.git/blob - src/menuui/mainhallmenu.cpp
remove CDROM stuff from movie player
[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 // num pixels shader is above/below tooltip text
678 static int Main_hall_tooltip_padding[GR_NUM_RESOLUTIONS] = {
679         4,              // GR_640
680         7,              // GR_1024
681 };
682 static int Main_hall_f1_text_frame = 0;
683 static int F1_text_done = 0;
684
685 // read in main hall table
686 void main_hall_read_table();
687
688 // "press f1" for help stuff
689 #define MAIN_HALL_HELP_TIME             5000
690 int Main_hall_help_stamp = -1;
691 void main_hall_process_help_stuff();
692
693
694 // ----------------------------------------------------------------------------
695 // VOICE RECORDING STUFF
696 //
697
698 // are we currently recording voice?
699 int Recording = 0;
700
701
702 // called when multiplayer clicks on the ready room door.  May pop up dialog depending on network
703 // connection status and errors
704 void main_hall_do_multi_ready()
705 {
706         int error;
707
708         error = psnet_get_network_status();
709         switch( error ) {
710         case NETWORK_ERROR_NO_TYPE:
711                 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));
712                 break;
713         case NETWORK_ERROR_NO_WINSOCK:
714                 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));
715                 break;
716         case NETWORK_ERROR_NO_PROTOCOL:
717                 if(Multi_options_g.protocol == NET_TCP){
718                         popup( PF_NO_NETWORKING, 1, POPUP_OK, XSTR( "TCP/IP protocol not found.  This protocol is required for multiplayer FreeSpace.", 362));
719                 } else {
720                         Assert(Multi_options_g.protocol == NET_IPX);
721                         popup( PF_NO_NETWORKING, 1, POPUP_OK, XSTR( "IPX protocol not found.  This protocol is required for multiplayer FreeSpace.", 362));
722                 }
723                 break;
724         case NETWORK_ERROR_CONNECT_TO_ISP:
725                 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));
726                 break;
727         case NETWORK_ERROR_LAN_AND_RAS:
728                 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));
729                 break;
730
731         case NETWORK_ERROR_NONE:
732         default:
733                 break;
734         }
735
736         // if our selected protocol is not active
737         if((Multi_options_g.protocol == NET_TCP) && !Tcp_active){
738                 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));
739                 return;
740         } 
741         if((Multi_options_g.protocol == NET_IPX) && !Ipx_active){               
742                 popup( PF_NO_NETWORKING, 1, POPUP_OK, XSTR( "You have selected IPX for multiplayer Freespace, but the IPX protocol was not detected on your machine.", 1402));
743                 return;
744         } 
745
746         if ( error != NETWORK_ERROR_NONE ){
747                 return;
748         }
749
750         // 7/9/98 -- MWA.  Deal with the connection speed issue.  make a call to the multiplayer code to
751         // determine is a valid connection setting exists
752         if ( Multi_connection_speed == CONNECTION_SPEED_NONE ) {
753                 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) );
754                 return;
755         }
756
757         // go to parallax online
758 #ifdef MULTIPLAYER_BETA_BUILD // do we want this for FS2_DEMO
759         Multi_options_g.pxo = 1;
760         Multi_options_g.protocol = NET_TCP;     
761         gameseq_post_event( GS_EVENT_PXO );
762 #else
763         
764         // go to the regular join game screen   
765         gameseq_post_event( GS_EVENT_MULTI_JOIN_GAME ); 
766 #endif  
767
768         // select protocol
769         psnet_use_protocol(Multi_options_g.protocol);
770 }
771
772 // blit some small color indicators to show whether ships.tbl and weapons.tbl are valid
773 // green == valid, red == invalid.
774 // ships.tbl will be on the left, weapons.tbl on the right
775 int Mh_ship_table_status[GR_NUM_RESOLUTIONS][2] = {
776         { 1, 479 },
777         { 1, 767 }
778 };
779 int Mh_weapon_table_status[GR_NUM_RESOLUTIONS][2] = {
780         { 3, 479 },
781         { 3, 767 }
782 };
783 void main_hall_blit_table_status()
784 {
785         // blit ship table status
786         gr_set_color_fast(Game_ships_tbl_valid ? &Color_bright_green : &Color_bright_red);
787         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]);
788
789         // blit weapon table status
790         gr_set_color_fast(Game_weapons_tbl_valid ? &Color_bright_green : &Color_bright_red);
791         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]);
792 }
793
794 // bash the player to a specific mission in a campaign
795 void main_hall_campaign_cheat()
796 {
797         char *ret = popup_input(0, XSTR("Enter mission name.\n\n* This will destroy all legitimate progress in this campaign. *", -1));
798
799         // yay
800         if(ret != NULL) {
801                 // strcpy(Main_hall_campaign_cheat, ret);               
802                 mission_campaign_jump_to_mission(ret);
803         }
804 }
805
806 // -------------------------------------------------------------------------------------------------------------------
807 // FUNCTION DEFINITIONS BEGIN
808 //
809
810 // initialize the main hall proper 
811 void main_hall_init(int main_hall_num)
812 {
813         if ( Main_hall_inited ) {
814                 return;
815         }       
816
817         int idx,s_idx;
818         char temp[100], whee[100];      
819
820         // read in the main hall table
821         main_hall_read_table();
822
823         // create the snazzy interface and load up the info from the table
824         snazzy_menu_init();
825         read_menu_tbl(NOX("MAIN HALL"), temp, whee, Main_hall_region, &Main_hall_num_options, 0);
826
827         // assign the proper main hall data
828         Assert((main_hall_num >= 0) && (main_hall_num < NUM_MAIN_HALLS));
829         Main_hall = &Main_hall_defines[gr_screen.res][main_hall_num];   
830
831         // tooltip strings
832 #ifdef MAKE_FS1
833         Main_hall->region_descript[0] = XSTR( "Exit Freespace", 353);
834         Main_hall->region_descript[1] = XSTR( "Barracks - Manage your Freespace pilots", 354);
835         Main_hall->region_descript[2] = XSTR( "Ready room - Start or continue a campaign", 355);
836         Main_hall->region_descript[3] = XSTR( "Tech room - View specifications of Freespace ships and weaponry", 356);
837         Main_hall->region_descript[4] = XSTR( "Options - Change your Freespace options", 357);
838         Main_hall->region_descript[5] = XSTR( "Campaign Room - View all available campaigns", 358);
839         Main_hall->region_descript[6] = XSTR( "Multiplayer - Start or join a multiplayer game", 359);
840 #else
841         Main_hall->region_descript[0] = XSTR( "Exit FreeSpace 2", 353);
842         Main_hall->region_descript[1] = XSTR( "Barracks - Manage your FreeSpace 2 pilots", 354);
843         Main_hall->region_descript[2] = XSTR( "Ready room - Start or continue a campaign", 355);
844         Main_hall->region_descript[3] = XSTR( "Tech room - View specifications of FreeSpace 2 ships and weaponry", 356);
845         Main_hall->region_descript[4] = XSTR( "Options - Change your FreeSpace 2 options", 357);
846         Main_hall->region_descript[5] = XSTR( "Campaign Room - View all available campaigns", 358);
847         Main_hall->region_descript[6] = XSTR( "Multiplayer - Start or join a multiplayer game", 359);
848 #endif
849         
850         // init tooltip shader
851 #ifndef MAKE_FS1
852         float gray_intensity = 0.02f;                                                                                                   // nearly black
853         float c = (gr_screen.mode == GR_DIRECT3D || gr_screen.mode == GR_OPENGL) ? 0.11f : 0.07f;                       // adjust for renderer differences
854         gr_create_shader(&Main_hall_tooltip_shader, gray_intensity, gray_intensity, gray_intensity, c);
855 #endif
856
857         // load the background bitmap
858         Main_hall_bitmap = bm_load(Main_hall->bitmap);
859         if(Main_hall_bitmap < 0){
860                 nprintf(("General","WARNING! Couldn't load main hall background bitmap %s\n", Main_hall->bitmap));
861         }       
862
863         // remove any multiplayer flags from the game mode
864         Game_mode &= ~(GM_MULTIPLAYER);
865
866         // set the interface palette 
867 #ifndef HARDWARE_ONLY
868         palette_use_bm_palette(Main_hall_bitmap);       
869 #endif
870
871         Main_hall_mask_w = -1;
872         Main_hall_mask_h = -1;
873                 
874         // load the mask
875         Main_hall_mask = bm_load(Main_hall->mask);
876         if (Main_hall_mask < 0) {
877                 Error(LOCATION,"Could not load in %s!", Main_hall->mask);
878         } else {
879                 // get a pointer to bitmap by using bm_lock(), so we can feed it to he snazzy menu system
880                 Main_hall_mask_bitmap = bm_lock(Main_hall_mask, 8, BMP_AABITMAP);
881                 Main_hall_mask_data = (ubyte*)Main_hall_mask_bitmap->data;
882                 bm_get_info(Main_hall_mask, &Main_hall_mask_w, &Main_hall_mask_h);
883         }
884
885         // load up the misc animations, and nullify all the delay timestamps for the misc animations    
886         for(idx=0;idx<Main_hall->num_misc_animations;idx++) {
887                 Main_hall_misc_anim[idx] = NULL;
888                 Main_hall_misc_anim[idx] = anim_load(Main_hall->misc_anim_name[idx]);
889                 if(Main_hall_misc_anim[idx] == NULL) {
890                         nprintf(("General","WARNING!, Could not load misc %s anim in main hall\n",Main_hall->misc_anim_name));
891                 }
892
893                 // null out the animation instances
894                 Main_hall_misc_anim_instance[idx] = NULL;
895                 
896                 // null out the delay timestamps
897                 Main_hall->misc_anim_delay[idx][0] = -1;
898         }       
899
900         // load up the door animations
901         for(idx=0;idx<Main_hall->num_door_animations;idx++) {
902                 Main_hall_door_anim[idx] = NULL;
903                 Main_hall_door_anim[idx] = anim_load(Main_hall->door_anim_name[idx]);
904                 if(Main_hall_door_anim[idx] == NULL){
905                         nprintf(("General","WARNING!, Could not load door anim %s in main hall\n",Main_hall->door_anim_name[idx]));
906                 }
907
908                 // null out the animation instances
909                 Main_hall_door_anim_instance[idx] = NULL;
910         }       
911
912         // load in help overlay bitmap          
913         if(Main_hall == &Main_hall_defines[gr_screen.res][0]) {
914                 Main_hall_overlay_id = MH_OVERLAY;
915         } else {
916                 Assert(Main_hall == &Main_hall_defines[gr_screen.res][1]);
917                 Main_hall_overlay_id = MH2_OVERLAY;
918         }
919         help_overlay_load(Main_hall_overlay_id);
920         help_overlay_set_state(Main_hall_overlay_id,0);         
921
922         // check to see if the "very first pilot" flag is set, and load the overlay if so
923         if (!F1_text_done) {
924                 if (Main_hall_f1_text_frame == 0) {
925                         Main_hall_help_stamp = timestamp(MAIN_HALL_HELP_TIME);
926                 } else {
927                         F1_text_done = 1;
928                 }
929         }
930
931 /*
932         if(Player_select_very_first_pilot) {                            
933                 Main_hall_help_stamp = timestamp(MAIN_HALL_HELP_TIME);
934                 
935                 // don't display the "press f1" message more than once
936                 Player_select_very_first_pilot = 0;
937         } else {
938                 Main_hall_help_stamp = -1;
939         }
940 */
941         Main_hall_region_linger_stamp = -1;
942
943         strcpy(Main_hall_campaign_cheat, "");
944
945         // zero out the door sounds
946         for(idx=0;idx<Main_hall->num_door_sounds;idx++){
947                 Main_hall_door_sound_handles[idx] = -1;
948         }
949
950         // zero out the misc anim sounds
951         for(idx=0;idx<Main_hall->num_misc_animations;idx++){
952                 for(s_idx = 1;s_idx < 10;s_idx++){
953                         Main_hall->misc_anim_sound_handles[idx][s_idx] = -1;
954                         Main_hall->misc_anim_sound_flag[idx][s_idx] = 0;
955                 }
956         }
957
958         // skip the first frame
959         Main_hall_frame_skip = 1;
960
961         // initialize the music
962         main_hall_start_music();
963
964         // initialize the main hall notify text
965         Main_hall_notify_stamp = 1;
966
967         // initialize the random intercom sound stuff
968         Main_hall_next_intercom_sound = 0;              
969         Main_hall_next_intercom_sound_stamp = -1;
970         Main_hall_intercom_sound_handle = -1;
971
972         // set the placement of the mouse cursor (start at the ready room)
973         Main_hall_mouse_region = -1;
974         Main_hall_last_clicked_region = READY_ROOM_REGION;      
975         mouse_set_pos(Main_hall->door_anim_coords[READY_ROOM_REGION][2],Main_hall->door_anim_coords[READY_ROOM_REGION][3]);     
976
977         Main_hall_inited = 1;
978
979         // determine if we have a right click
980         Main_hall_right_click = mouse_down(MOUSE_RIGHT_BUTTON);
981
982         // set the game_mode based on the type of player
983         Assert( Player != NULL );
984         if ( Player->flags & PLAYER_FLAGS_IS_MULTI ){
985                 Game_mode = GM_MULTIPLAYER;
986         } else {
987                 Game_mode = GM_NORMAL;
988         }
989
990         if ( (Cmdline_start_netgame || (Cmdline_connect_addr != NULL)) && !Main_hall_netgame_started ) {
991                 Main_hall_netgame_started = 1;
992                 main_hall_do_multi_ready();
993         }
994 }
995
996 void main_hall_exit_game()
997 {
998 #if defined(NDEBUG) || defined(INTERPLAYQA)
999         int choice;
1000
1001         // stop music first
1002         main_hall_stop_music();
1003         main_hall_stop_ambient();
1004         choice = popup( PF_NO_NETWORKING | PF_BODY_BIG, 2, POPUP_NO, POPUP_YES, XSTR( "Exit Game?", 365));
1005         if ( choice == 1 ) {
1006                 gameseq_post_event(GS_EVENT_QUIT_GAME);
1007         } else {
1008                 main_hall_start_music();
1009                 main_hall_start_ambient();
1010         }
1011 #else
1012         gameseq_post_event(GS_EVENT_QUIT_GAME);
1013 #endif
1014 }
1015
1016
1017 // do a frame for the main hall
1018 void main_hall_do(float frametime)
1019 {
1020         int code, key, snazzy_action;   
1021
1022         // need to ensure ambient is playing, since it may be stopped by a playing movie
1023         main_hall_start_ambient();
1024
1025         // handle any animation details 
1026         main_hall_handle_misc_anims();
1027         main_hall_handle_region_anims();
1028
1029         // handle any random intercom sound details
1030         main_hall_handle_random_intercom_sounds();
1031
1032         // handle any mouse clicks
1033         main_hall_handle_right_clicks();        
1034
1035         // handle any sound details
1036         main_hall_cull_door_sounds();   
1037
1038         // process any keypresses/mouse events
1039         snazzy_action = -1;
1040         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);
1041
1042         if(key){
1043                 extern void game_process_cheats(int k);
1044                 game_process_cheats(key);
1045         }
1046         switch(key){
1047         case SDLK_RETURN:
1048                 snazzy_action = SNAZZY_CLICKED; 
1049                 break;
1050
1051 #if 0 //#ifndef NDEBUG  
1052         case SDLK_1:
1053                 movie_play("endprt2b.mve");
1054                 break;
1055         case SDLK_2:
1056                 movie_play_two("endprt2a.mve", "endprt2b.mve");
1057                 break;
1058         case SDLK_3:
1059                 main_hall_campaign_cheat();     
1060                 break;  
1061         case KEY_DEBUGGED + SDLK_d:
1062                 demo_start_playback("test.fsd");
1063                 break;
1064         }
1065 #else 
1066         }
1067 #endif
1068
1069         // do any processing based upon what happened to the snazzy menu
1070         switch (snazzy_action) {
1071         case SNAZZY_OVER:
1072                 main_hall_handle_mouse_location(code);
1073                 break;
1074
1075         case SNAZZY_CLICKED:
1076                 switch (code) {
1077                 // clicked on the exit region
1078                 case EXIT_REGION:
1079                         gamesnd_play_iface(SND_IFACE_MOUSE_CLICK);
1080                         main_hall_exit_game();
1081                         break;
1082
1083                 // clicked on the readyroom region
1084                 case READY_ROOM_REGION:
1085 #ifdef MULTIPLAYER_BETA_BUILD
1086                         gamesnd_play_iface(SND_IFACE_MOUSE_CLICK);
1087                         Player->flags |= PLAYER_FLAGS_IS_MULTI;
1088                         main_hall_do_multi_ready();
1089 #elif defined(E3_BUILD) || defined(PRESS_TOUR_BUILD)                                                                    
1090                         gameseq_post_event(GS_EVENT_NEW_CAMPAIGN);                      
1091 #else
1092                         if (Player->flags & PLAYER_FLAGS_IS_MULTI){
1093                                 gamesnd_play_iface(SND_IFACE_MOUSE_CLICK);
1094                                 main_hall_do_multi_ready();
1095                         } else {                                
1096                                 if(strlen(Main_hall_campaign_cheat)){
1097                                         gameseq_post_event(GS_EVENT_CAMPAIGN_CHEAT);
1098                                 } else {
1099                                         gameseq_post_event(GS_EVENT_NEW_CAMPAIGN);                              
1100                                 }
1101                                 gamesnd_play_iface(SND_IFACE_MOUSE_CLICK);                              
1102                         }
1103 #endif
1104                         break;
1105
1106                 // clicked on the tech room region
1107                 case TECH_ROOM_REGION:
1108 #if defined(FS2_DEMO) || defined(FS1_DEMO)
1109                         gamesnd_play_iface(SND_IFACE_MOUSE_CLICK);
1110                         game_feature_not_in_demo_popup();
1111 #else
1112                         gamesnd_play_iface(SND_IFACE_MOUSE_CLICK);
1113                         gameseq_post_event( GS_EVENT_TECH_MENU );
1114 #endif
1115                         break;
1116
1117                 // clicked on the options region
1118                 case OPTIONS_REGION:
1119                         gamesnd_play_iface(SND_IFACE_MOUSE_CLICK);
1120                         gameseq_post_event(GS_EVENT_OPTIONS_MENU);
1121                         break;
1122
1123                 // clicked on the campaign toom region
1124                 case CAMPAIGN_ROOM_REGION:
1125 #if !defined(MULTIPLAYER_BETA_BUILD) && !defined(E3_BUILD) && !defined(PRESS_TOUR_BUILD)
1126
1127 #if defined(FS2_DEMO) || defined(FS1_DEMO)
1128                         gamesnd_play_iface(SND_IFACE_MOUSE_CLICK);
1129                         {
1130                         //game_feature_not_in_demo_popup();
1131                         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.");
1132                         if (reset_campaign == 1) {
1133                                 mission_campaign_savefile_delete(Campaign.filename);
1134                                 mission_campaign_load(Campaign.filename);
1135                                 mission_campaign_next_mission();
1136                         }
1137                         }
1138
1139 #else
1140                         if(Player->flags & PLAYER_FLAGS_IS_MULTI){
1141                                 gamesnd_play_iface(SND_IFACE_MOUSE_CLICK);
1142                                 main_hall_set_notify_string(XSTR( "Campaign Room not valid for multiplayer pilots", 366));
1143                         } else {
1144                                 gamesnd_play_iface(SND_IFACE_MOUSE_CLICK);
1145                                 gameseq_post_event(GS_EVENT_CAMPAIGN_ROOM);                     
1146                         }
1147 #endif
1148
1149 #endif
1150                         break;
1151
1152                 // clicked on the multiplayer region
1153                 case MULTIPLAYER_REGION:
1154 #if defined(DEMO) || defined(OEM_BUILD) // not for FS2_DEMO
1155                         game_feature_not_in_demo_popup();
1156 #else
1157                         if (Player->flags & PLAYER_FLAGS_IS_MULTI){
1158                                 // NOTE : this isn't a great thing to be calling this anymore. But we'll leave it for now
1159                                 gameseq_post_event( GS_EVENT_MULTI_JOIN_GAME );
1160                         } else {
1161                                 main_hall_set_notify_string(XSTR( "Not a valid multiplayer pilot!!", 367));
1162                         }
1163 #endif
1164                         break;
1165
1166                 // load mission key was pressed
1167                 case LOAD_MISSION_REGION:
1168 #ifdef RELEASE_REAL
1169 #else
1170         #if !(defined(MULTIPLAYER_BETA_BUILD) || defined(FS2_DEMO) || defined(FS1_DEMO)) 
1171         //#if !defined(NDEBUG) || defined(INTERPLAYQA)
1172                                 if (Player->flags & PLAYER_FLAGS_IS_MULTI){
1173                                         gamesnd_play_iface(SND_IFACE_MOUSE_CLICK);
1174                                         main_hall_set_notify_string(XSTR( "Load Mission not valid for multiplayer pilots", 368));
1175                                 } else {
1176         #ifdef GAME_CD_CHECK
1177                                         // if ( !game_do_cd_check() ) {
1178                                                 // break;
1179                                         // }
1180         #endif
1181                                         gamesnd_play_iface(SND_IFACE_MOUSE_CLICK);
1182                                         gameseq_post_event( GS_EVENT_LOAD_MISSION_MENU );
1183                                 }
1184         //#endif
1185         #endif
1186 #endif
1187                         break;
1188
1189                 // quick start a game region
1190                 case QUICK_START_REGION:
1191 #if !defined(NDEBUG) && !(defined(FS2_DEMO) || defined(FS1_DEMO))
1192                         if (Player->flags & PLAYER_FLAGS_IS_MULTI){
1193                                 main_hall_set_notify_string(XSTR( "Quick Start not valid for multiplayer pilots", 369));
1194                         } else {
1195
1196                                 if (Num_recent_missions > 0)    {
1197                                         strncpy( Game_current_mission_filename, Recent_missions[0], MAX_FILENAME_LEN );
1198                                 } else {
1199                                         mission_load_up_campaign();
1200                                         strncpy( Game_current_mission_filename, Campaign.missions[0].name, MAX_FILENAME_LEN );
1201                                 }
1202
1203                                 Campaign.current_mission = -1;
1204                                 gameseq_post_event(GS_EVENT_START_GAME_QUICK);
1205                         }
1206 #endif
1207                         break;
1208
1209                 // clicked on the barracks region
1210                 case BARRACKS_REGION:                   
1211                         gamesnd_play_iface(SND_IFACE_MOUSE_CLICK);
1212                         gameseq_post_event( GS_EVENT_BARRACKS_MENU );
1213                         break;
1214
1215                 // increate the skill level
1216                 case SKILL_LEVEL_REGION: 
1217                         char temp[100];
1218
1219                         game_increase_skill_level();
1220                         sprintf(temp, XSTR( "Skill level set to %s.", 370), Skill_level_names(Game_skill_level));
1221                         main_hall_set_notify_string(temp);
1222                         break;                          
1223
1224                 // escape was pressed
1225                 case ESC_PRESSED:
1226                         // if there is a help overlay active, then don't quit the game - just kill the overlay
1227                         if(!help_overlay_active(Main_hall_overlay_id)){
1228                                 gamesnd_play_iface(SND_IFACE_MOUSE_CLICK);
1229                                 main_hall_exit_game();
1230                         }
1231                         // kill the overlay
1232                         else {
1233                                 help_overlay_set_state(Main_hall_overlay_id,0);
1234                         }
1235                         break;
1236                 }
1237
1238                 // if the escape key wasn't pressed handle any mouse position related events
1239                 if (code != ESC_PRESSED){
1240                         main_hall_handle_mouse_location(code);
1241                 }
1242                 break;
1243
1244                 default:
1245                         main_hall_handle_mouse_location(-1);
1246                         break;
1247         }
1248
1249         if ( mouse_down(MOUSE_LEFT_BUTTON) ) {
1250                 help_overlay_set_state(Main_hall_overlay_id, 0);
1251         }
1252
1253         // draw the background bitmap   
1254         gr_reset_clip();        
1255         GR_MAYBE_CLEAR_RES(Main_hall_bitmap);
1256         if(Main_hall_bitmap >= 0){
1257                 gr_set_bitmap(Main_hall_bitmap, GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);
1258                 gr_bitmap(0, 0);
1259         }
1260
1261         // draw any pending notification messages
1262         main_hall_notify_do();                  
1263
1264         // render misc animations
1265         main_hall_render_misc_anims(frametime);
1266
1267         // render door animtions
1268         main_hall_render_door_anims(frametime); 
1269
1270         // blit any appropriate tooltips
1271         main_hall_maybe_blit_tooltips();
1272
1273         // fishtank
1274         fishtank_process();
1275
1276         // process any help "hit f1" timestamps and display any messages if necessary
1277         if (!F1_text_done) {
1278                 main_hall_process_help_stuff();
1279         }
1280
1281         // blit help overlay if active
1282         help_overlay_maybe_blit(Main_hall_overlay_id);
1283
1284         // blit the freespace version #
1285         main_hall_blit_version();
1286
1287         // blit ship and weapon table status
1288         main_hall_blit_table_status();
1289
1290         // if we're in nice D3D texture format
1291 #ifndef NDEBUG
1292         gr_set_color_fast(&Color_white);
1293
1294         // d3d
1295         if(gr_screen.mode == GR_DIRECT3D){
1296                 if(Bm_pixel_format == BM_PIXEL_FORMAT_ARGB_D3D){                
1297                         gr_string(320, gr_screen.max_h - 10, "D3D ARGB");
1298                 }
1299                 extern int D3d_rendition_uvs;
1300                 extern int D3D_32bit;
1301                 extern int D3D_fog_mode;        
1302                 extern int D3D_zbias;
1303                 if(D3d_rendition_uvs){
1304                         gr_string(320, gr_screen.max_h - 20, "D3D rendition");
1305                 }
1306                 if(D3D_32bit){
1307                         gr_string(320, gr_screen.max_h - 30, "D3D 32bit");
1308                 }
1309                 gr_printf(320, gr_screen.max_h - 40, "Fog : %d", D3D_fog_mode);
1310                 gr_printf(320, gr_screen.max_h - 50, "Zbias : %d", D3D_zbias);
1311                 // extern void d3d_test();
1312                 // d3d_test();
1313         } else if(gr_screen.mode == GR_GLIDE){
1314 #ifndef PLAT_UNIX
1315                 extern int Glide_voodoo3;
1316                 if(Glide_voodoo3){
1317                         gr_string(320, gr_screen.max_h - 20, "VOODOO 3");
1318                 }
1319 #endif
1320         }
1321 #endif  
1322
1323         gr_flip();
1324
1325         // maybe run the player tips popup
1326 // #if defined(FS2_DEMO) && defined(NDEBUG)
1327         player_tips_popup();
1328 // #endif
1329
1330         // if we were supposed to skip a frame, then stop doing it after 1 frame
1331         if(Main_hall_frame_skip){
1332                 Main_hall_frame_skip = 0;
1333         }
1334 }
1335
1336 // close the main hall proper
1337 void main_hall_close()
1338 {
1339         int idx,s_idx;
1340
1341         if(!Main_hall_inited){
1342                 return;
1343         }       
1344
1345         // unload the main hall bitmap
1346         if(Main_hall_bitmap != -1){
1347                 bm_unload(Main_hall_bitmap);
1348         }
1349
1350         // unload any bitmaps
1351         if(Main_hall_mask >= 0){                
1352                 // make sure we unlock the mask bitmap so it can be unloaded
1353                 bm_unlock(Main_hall_mask);
1354                 if(!bm_unload(Main_hall_mask)){
1355                         nprintf(("General","WARNING! Couldn't unload main hall mask bitmap!\n"));
1356                 }
1357         }
1358
1359         // free up any (possibly) playing misc animation handles
1360         for(idx=0;idx<Main_hall->num_misc_animations;idx++){
1361                 if(Main_hall_misc_anim_instance[idx]!=NULL){
1362                         anim_stop_playing(Main_hall_misc_anim_instance[idx]);
1363                         Main_hall_misc_anim_instance[idx] = NULL;
1364                 }
1365         }
1366         
1367         // free up any (possibly) playing door animation handles
1368         for(idx=0;idx<Main_hall->num_door_animations;idx++){
1369                 if(Main_hall_door_anim_instance[idx]!=NULL){
1370                         anim_stop_playing(Main_hall_door_anim_instance[idx]);
1371                         Main_hall_door_anim_instance[idx] = NULL;
1372                 }
1373         }
1374         
1375
1376         // free up any misc animations/instances        
1377         for(idx=0;idx<Main_hall->num_misc_animations;idx++){
1378                 if((Main_hall_misc_anim_instance[idx]!=NULL) && (anim_playing(Main_hall_misc_anim_instance[idx]))){             
1379                         Main_hall_misc_anim_instance[idx] = NULL;
1380                 }
1381                 if(Main_hall_misc_anim[idx]!=NULL){
1382                         if(anim_free(Main_hall_misc_anim[idx]) == -1){
1383                                 nprintf(("General","WARNING!, Could not free up misc anim %s in main hall\n",Main_hall->misc_anim_name[idx]));
1384                         }
1385                 }       
1386         }
1387
1388         // free up any door animations/instances
1389         for(idx=0;idx<Main_hall->num_door_animations;idx++){
1390                 if((Main_hall_door_anim_instance[idx]!=NULL) && (anim_playing(Main_hall_door_anim_instance[idx]))){
1391                         Main_hall_door_anim_instance[idx] = NULL;                       
1392                 }
1393                 if(Main_hall_door_anim[idx]!=NULL){
1394                         if(anim_free(Main_hall_door_anim[idx]) == -1){
1395                                 nprintf(("General","WARNING!, Could not free up door anim %s in main hall\n",Main_hall->door_anim_name[idx]));
1396                         }
1397                 }               
1398         }       
1399
1400         // stop any playing door sounds
1401         for(idx=0;idx<Main_hall->num_door_sounds-2;idx++){      // don't cut off the glow sounds (requested by Dan)
1402                 if((Main_hall_door_sound_handles[idx] != -1) && snd_is_playing(Main_hall_door_sound_handles[idx])){
1403                         snd_stop(Main_hall_door_sound_handles[idx]);
1404                         Main_hall_door_sound_handles[idx] = -1;
1405                 }
1406         }       
1407
1408         // stop any playing misc animation sounds
1409         for(idx=0;idx<Main_hall->num_misc_animations;idx++){
1410                 for(s_idx=1;s_idx<10;s_idx++){
1411                         if(snd_is_playing(Main_hall->misc_anim_sound_handles[idx][s_idx])){
1412                                 snd_stop(Main_hall->misc_anim_sound_handles[idx][s_idx]);
1413                                 Main_hall->misc_anim_sound_handles[idx][s_idx] = -1;
1414                         }
1415                 }
1416         }
1417
1418         // unload the overlay bitmap
1419         help_overlay_unload(Main_hall_overlay_id);
1420
1421         // close any snazzy menu details
1422         snazzy_menu_close();
1423
1424         // restore
1425         palette_restore_palette();
1426
1427         // no fish
1428         fishtank_stop();        
1429
1430         // not inited anymore
1431         Main_hall_inited = 0;
1432 }
1433
1434 // start the main hall music playing
1435 void main_hall_start_music()
1436 {
1437         // start a looping ambient sound
1438         main_hall_start_ambient();
1439
1440         // if we have selected no music, then don't do this
1441         if ( Cmdline_freespace_no_music ) {
1442                 return;
1443         }
1444
1445         int main_hall_spooled_music_index = event_music_get_spooled_music_index(Main_hall->music);
1446         
1447         if ((Main_hall_music_handle == -1) && (main_hall_spooled_music_index != -1)) {
1448                 char *music_wavfile_name = Spooled_music[main_hall_spooled_music_index].filename;
1449                 if (music_wavfile_name != NULL) {
1450                                 Main_hall_music_handle = audiostream_open( music_wavfile_name, ASF_EVENTMUSIC );
1451                                 if ( Main_hall_music_handle != -1 )
1452                                         audiostream_play(Main_hall_music_handle, Master_event_music_volume);
1453                 }
1454                 else {
1455                         nprintf(("Warning", "No music file exists to play music at the main menu!\n"));
1456                 }
1457         }
1458 }
1459
1460 // stop the main hall music
1461 void main_hall_stop_music()
1462 {
1463         if ( Main_hall_music_handle != -1 ) {
1464                 audiostream_close_file(Main_hall_music_handle);
1465                 Main_hall_music_handle = -1;
1466         }
1467 }
1468
1469 // do any necessary instantiation of misc animations
1470 void main_hall_handle_misc_anims()
1471 {
1472         int idx,s_idx;
1473
1474         if(Main_hall_frame_skip)
1475                 return;
1476         
1477         for(idx=0;idx<Main_hall->num_misc_animations;idx++){
1478                 // if the anim isn't playing
1479                 if(Main_hall_misc_anim_instance[idx] == NULL){
1480                         // if the timestamp is -1, then reset it to some random value (based on MIN and MAX) and continue
1481                         if(Main_hall->misc_anim_delay[idx][0] == -1){
1482                                 Main_hall->misc_anim_delay[idx][0] = timestamp(Main_hall->misc_anim_delay[idx][1] + 
1483                                                                                                                       (int)(((float)myrand()/(float)MY_RAND_MAX) * (float)(Main_hall->misc_anim_delay[idx][2] - Main_hall->misc_anim_delay[idx][1])));
1484
1485                         // if the timestamp is not -1 and has popped, play the anim and make the timestap -1
1486                         } else if (timestamp_elapsed(Main_hall->misc_anim_delay[idx][0]) && Main_hall_misc_anim[idx]) {
1487                                 anim_play_struct aps;
1488
1489                                 anim_play_init(&aps, Main_hall_misc_anim[idx], Main_hall->misc_anim_coords[idx][0], Main_hall->misc_anim_coords[idx][1]);
1490                                 aps.screen_id = GS_STATE_MAIN_MENU;
1491                                 aps.framerate_independent = 1;
1492                                 
1493                                 Main_hall_misc_anim_instance[idx] = anim_play(&aps);                            
1494                                 
1495                                 // kill the timestamp   
1496                                 Main_hall->misc_anim_delay[idx][0] = -1;                                
1497
1498                                 // reset the "should be playing" flags
1499                                 for(s_idx=1;s_idx<10;s_idx++){
1500                                         Main_hall->misc_anim_sound_flag[idx][s_idx] = 0;
1501                                 }
1502                         }
1503                 }               
1504                 // if the anim is playing
1505                 else {
1506                         // check to see if any special trigger points have been reached by the animation
1507                         // since the frame triggers must be in ascending order, we will count down so that we don't trigger too many sounds
1508                         for(s_idx=Main_hall->misc_anim_special_sounds[idx][0]; s_idx > 0; s_idx--){
1509                                 // if we've passed the trigger point, then play the sound and break out of the loop
1510                                 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]){                                 
1511                                         Main_hall->misc_anim_sound_flag[idx][s_idx] = 1;
1512
1513                                         // if the sound is already playing, then kill it. This is a pretty safe thing to do since we can assume that
1514                                         // by the time we get to this point again, the sound will have been long finished
1515                                         if(snd_is_playing(Main_hall->misc_anim_sound_handles[idx][s_idx])){
1516                                                 snd_stop(Main_hall->misc_anim_sound_handles[idx][s_idx]);
1517                                                 Main_hall->misc_anim_sound_handles[idx][s_idx] = -1;
1518                                         }
1519                                         // play the sound
1520                                         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]);                                    
1521                                         break;
1522                                 }
1523                         }
1524
1525                         // if the animation mode is MISC_ANIM_MODE_HOLD, pause it at the last frame
1526                         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)){                           
1527                                 anim_pause(Main_hall_misc_anim_instance[idx]);
1528                                 Main_hall_misc_anim_instance[idx]->stop_now = FALSE;
1529                         }                       
1530
1531                         // if the animation mode is MISC_ANIM_MODE_LOOP, check to see if it should be looped
1532                         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)){                           
1533                                 anim_release_render_instance(Main_hall_misc_anim_instance[idx]);
1534
1535                                 // start it playing again
1536                                 anim_play_struct aps;
1537
1538                                 anim_play_init(&aps, Main_hall_misc_anim[idx], Main_hall->misc_anim_coords[idx][0], Main_hall->misc_anim_coords[idx][1]);
1539                                 aps.screen_id = GS_STATE_MAIN_MENU;
1540                                 aps.framerate_independent = 1;
1541                                 
1542                                 Main_hall_misc_anim_instance[idx] = anim_play(&aps);                            
1543                                 
1544                                 // kill the timestamp   
1545                                 Main_hall->misc_anim_delay[idx][0] = -1;                                
1546
1547                                 // reset the "should be playing" flags
1548                                 for(s_idx=1;s_idx<10;s_idx++){
1549                                         Main_hall->misc_anim_sound_flag[idx][s_idx] = 0;
1550                                 }
1551                         }                       
1552
1553                         // cull any misc animations which are marked as done (!is_playing)                              
1554                         if(!anim_playing(Main_hall_misc_anim_instance[idx])){                   
1555                                 Main_hall_misc_anim_instance[idx] = NULL;                               
1556                         }
1557                 }                       
1558         }       
1559 }
1560
1561 // render all playing misc animations
1562 void main_hall_render_misc_anims(float frametime)
1563 {
1564         int idx;
1565         
1566         // HACKETY HACK HACK - always render misc anim 3 first, if it is playing
1567         if(Main_hall_misc_anim_instance[2] != NULL){
1568                 anim_render_one(GS_STATE_MAIN_MENU,Main_hall_misc_anim_instance[2],frametime);
1569         }
1570
1571         // render all other animations
1572         for(idx=0;idx<MAX_MISC_ANIMATIONS;idx++){
1573                 // skip anim 3, which was previously rendered, if at all
1574                 if(idx == 2){
1575                         continue;
1576                 }
1577
1578                 // render it
1579                 if(Main_hall_misc_anim_instance[idx] != NULL){
1580                         anim_render_one(GS_STATE_MAIN_MENU,Main_hall_misc_anim_instance[idx],frametime);
1581                 }
1582         }
1583 }
1584
1585 // render all playing door animations
1586 void main_hall_render_door_anims(float frametime)
1587 {
1588         int idx;        
1589
1590         // render all door animations
1591         for(idx=0;idx<MAX_DOOR_ANIMATIONS;idx++){               
1592                 // render it
1593                 if(Main_hall_door_anim_instance[idx] != NULL){
1594                         anim_render_one(GS_STATE_MAIN_MENU,Main_hall_door_anim_instance[idx],frametime);
1595                 }
1596         }
1597 }
1598
1599 // handle starting, stopping and reversing "door" animations
1600 void main_hall_handle_region_anims()
1601 {
1602         int idx;
1603
1604         if(Main_hall_frame_skip)
1605                 return;
1606         
1607         // make sure we make any finished door animations NULL
1608         for(idx=0;idx<Main_hall->num_door_animations;idx++){
1609                 if((Main_hall_door_anim_instance[idx] != NULL) && !anim_playing(Main_hall_door_anim_instance[idx])){
1610                         Main_hall_door_anim_instance[idx] = NULL;
1611                 }
1612         }
1613         
1614         // go through each region animation
1615         for(idx=0;idx<Main_hall->num_door_animations;idx++){
1616                 // if the instance is not null and the animation is playing
1617                 if((Main_hall_door_anim_instance[idx] != NULL) && anim_playing(Main_hall_door_anim_instance[idx])){
1618                         // check to see if we should hold a given door "open"
1619                         if((Main_hall_mouse_region == idx) && (Main_hall_door_anim_instance[idx]->frame_num == Main_hall_door_anim_instance[idx]->stop_at)){
1620                                 anim_pause(Main_hall_door_anim_instance[idx]);
1621                                 Main_hall_door_anim_instance[idx]->stop_now = FALSE;
1622                         }
1623                         // check to see if we should close a door being held open
1624                         if((Main_hall_mouse_region != idx) && (Main_hall_door_anim_instance[idx]->paused)){
1625                                 anim_unpause(Main_hall_door_anim_instance[idx]);
1626                         }
1627                 }               
1628         }       
1629 }
1630
1631 // do any necessary processing based upon the mouse location
1632 void main_hall_handle_mouse_location(int cur_region)
1633 {
1634    if(Main_hall_frame_skip)
1635                 return;
1636
1637         if(cur_region > NUM_MAIN_HALL_MOUSE_REGIONS) {
1638                 // MWA -- inserted return since Int3() was tripped when hitting L from main
1639                 // menu.
1640                 return;         
1641         }
1642
1643         // if the mouse is now over a resgion
1644         if (cur_region != -1) {
1645                 // if we're still over the same region we were last frame, check stuff
1646                 if (cur_region == Main_hall_mouse_region) {
1647                         // if we have a linger timestamp set and it has expired, then get moving                        
1648                         if ((Main_hall_region_linger_stamp != -1) && timestamp_elapsed(Main_hall_region_linger_stamp)) {
1649                                 main_hall_mouse_grab_region(cur_region);                                
1650
1651                                 // release the region linger stamp
1652                                 Main_hall_region_linger_stamp = -1;
1653                         }
1654                 } else {
1655                         // if we're currently on another region, release it
1656                         if ((Main_hall_mouse_region != -1) && (cur_region != Main_hall_mouse_region)) {
1657                                 main_hall_mouse_release_region(Main_hall_mouse_region);
1658                         }
1659                 
1660                         // set the linger time
1661                         if (Main_hall_region_linger_stamp == -1) {
1662                                 Main_hall_mouse_region = cur_region;
1663                                 Main_hall_region_linger_stamp = timestamp(MAIN_HALL_REGION_LINGER);
1664                         }                       
1665                 }
1666         }
1667         // if it was over a region but isn't anymore, release that region
1668         else {
1669                 if (Main_hall_mouse_region != -1) {
1670                         main_hall_mouse_release_region(Main_hall_mouse_region);
1671                         Main_hall_mouse_region = -1;
1672
1673                         // release the region linger timestamp
1674                         Main_hall_region_linger_stamp = -1;
1675                 }
1676         }
1677 }
1678
1679 // if the mouse has moved off of the currently active region, handle the anim accordingly
1680 void main_hall_mouse_release_region(int region)
1681 {
1682         if(Main_hall_frame_skip){
1683                 return;
1684         }
1685
1686         // if the animation is currently playing in the forward direction, change direction and be done, otherwise don't do a thing
1687         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)){
1688                 anim_reverse_direction(Main_hall_door_anim_instance[region]);
1689         }
1690
1691         // check for door sounds, ignoring the OPTIONS_REGION (which isn't a door)
1692         if ((Main_hall_door_anim_instance[region] != NULL)) {
1693                 // don't stop the toaster oven or microwave regions from playing all the way through
1694                 if (Main_hall_door_sound_handles[region] != -1) {
1695                         snd_stop(Main_hall_door_sound_handles[region]);
1696                 }
1697                 Main_hall_door_sound_handles[region] = snd_play(&Snds_iface[Main_hall->door_sounds[region][1]], Main_hall->door_sound_pan[region]);
1698
1699                 // make sure to set the sound to play from the right spot
1700                 snd_set_pos(Main_hall_door_sound_handles[region], &Snds_iface[SND_MAIN_HALL_DOOR_CLOSE],
1701                                                 (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);                      
1702         }
1703 }
1704
1705 // if the mouse has moved on this region, handle it accordingly
1706 void main_hall_mouse_grab_region(int region)
1707 {
1708         if (Main_hall_frame_skip) {
1709                 return;
1710         }
1711
1712         // if the animation is not playing, start it playing
1713         if ( !Main_hall_door_anim_instance[region] ) {
1714                 if ( Main_hall_door_anim[region] ) {
1715                         anim_play_struct aps;
1716
1717                         anim_play_init(&aps, Main_hall_door_anim[region], Main_hall->door_anim_coords[region][0], Main_hall->door_anim_coords[region][1]);
1718                         aps.screen_id = GS_STATE_MAIN_MENU;
1719                         aps.framerate_independent = 1;
1720
1721                         Main_hall_door_anim_instance[region] = anim_play(&aps);
1722                 }
1723         } 
1724         // otherwise if its playing in the reverse direction, change it to the forward direction
1725         else if (Main_hall_door_anim_instance[region]->direction == ANIM_DIRECT_REVERSE) {
1726                 anim_reverse_direction(Main_hall_door_anim_instance[region]);
1727         }
1728
1729         // check for opening/starting sounds
1730         // kill the currently playing sounds if necessary
1731         if(Main_hall_door_sound_handles[region] != -1){                 
1732                 snd_stop(Main_hall_door_sound_handles[region]);
1733         }       
1734         Main_hall_door_sound_handles[region] = snd_play(&Snds_iface[Main_hall->door_sounds[region][0]],Main_hall->door_sound_pan[region]);                              
1735
1736         // start the sound playing at the right spot relative to the completion of the animation                
1737         if(Main_hall_door_anim_instance[region]->frame_num != -1){                      
1738                         snd_set_pos(Main_hall_door_sound_handles[region],&Snds_iface[SND_MAIN_HALL_DOOR_OPEN],
1739                                                         (float)Main_hall_door_anim_instance[region]->frame_num / (float)Main_hall_door_anim_instance[region]->parent->total_frames,1);
1740         }                               
1741 }
1742
1743 // handle any right clicks which may have occured
1744 void main_hall_handle_right_clicks()
1745 {
1746         int new_region;
1747
1748         if(Main_hall_frame_skip)
1749                 return;
1750
1751         // check to see if the button has been clicked
1752         if(!Main_hall_right_click){
1753                 if(mouse_down(MOUSE_RIGHT_BUTTON)){
1754                         // cycle through the available regions
1755                         if(Main_hall_last_clicked_region == NUM_MAIN_HALL_MOUSE_REGIONS - 1){
1756                                 new_region = 0;
1757                         } else
1758                                 new_region = Main_hall_last_clicked_region + 1;
1759
1760                         // set the position of the mouse cursor and the newly clicked region                    
1761                         mouse_set_pos(Main_hall->door_anim_coords[new_region][2],Main_hall->door_anim_coords[new_region][3]);                   
1762
1763                         main_hall_handle_mouse_location(new_region);
1764                         Main_hall_last_clicked_region = new_region;
1765                         
1766                         // set the mouse as being clicked
1767                         Main_hall_right_click = 1;
1768                 }
1769         } 
1770         // set the mouse as being unclicked
1771         else if(Main_hall_right_click && !(mouse_down(MOUSE_RIGHT_BUTTON))){
1772                 Main_hall_right_click = 0;
1773         }
1774 }
1775
1776 // cull any door sounds that have finished playing
1777 void main_hall_cull_door_sounds()
1778 {
1779         int idx;
1780         // 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
1781         for(idx=0;idx<Main_hall->num_door_sounds;idx++){
1782                 if((Main_hall_door_sound_handles[idx] != -1) && !snd_is_playing(Main_hall_door_sound_handles[idx])){                    
1783                         Main_hall_door_sound_handles[idx] = -1;
1784                 }
1785         }
1786 }
1787
1788 void main_hall_handle_random_intercom_sounds()
1789 {
1790         // if we have no timestamp for the next random sound, then set on
1791         if((Main_hall_next_intercom_sound_stamp == -1) && (Main_hall_intercom_sound_handle == -1)){
1792                 Main_hall_next_intercom_sound_stamp = timestamp((int)(((float)myrand()/(float)MY_RAND_MAX) * 
1793                                                                     (float)(Main_hall->intercom_delay[Main_hall_next_intercom_sound][1]
1794                                                                                                                                           - Main_hall->intercom_delay[Main_hall_intercom_sound_handle][0])) );          
1795         }
1796
1797         // if the there is no sound playing
1798         if(Main_hall_intercom_sound_handle == -1){
1799                 // if the timestamp has popped, play a sound
1800                 if((Main_hall_next_intercom_sound_stamp != -1) && (timestamp_elapsed(Main_hall_next_intercom_sound_stamp))){
1801                         // play the sound
1802                         Main_hall_intercom_sound_handle = snd_play(&Snds_iface[Main_hall->intercom_sounds[Main_hall_next_intercom_sound]]);                     
1803                         
1804                         // unset the timestamp
1805                         Main_hall_next_intercom_sound_stamp = -1;
1806                 }
1807         }
1808         // if the sound is playing
1809         else {
1810                 // if the sound has finished, set the timestamp and continue
1811                 if(!snd_is_playing(Main_hall_intercom_sound_handle)){
1812                         // increment the next sound
1813                         if(Main_hall_next_intercom_sound >= (Main_hall->num_random_intercom_sounds-1)){
1814                                 Main_hall_next_intercom_sound = 0;
1815                         } else {
1816                                 Main_hall_next_intercom_sound++;
1817                         }
1818
1819                         // set the timestamp
1820                         Main_hall_next_intercom_sound_stamp = timestamp((int)(((float)myrand()/(float)MY_RAND_MAX) * 
1821                                                                     (float)(Main_hall->intercom_delay[Main_hall_next_intercom_sound][1]
1822                                                                                                                                           - Main_hall->intercom_delay[Main_hall_next_intercom_sound][0])) );
1823
1824                         // release the sound handle
1825                         Main_hall_intercom_sound_handle = -1;
1826                 }
1827         }
1828 }
1829
1830 // set the notification string with its decay timeout
1831 void main_hall_set_notify_string(const char *str)
1832 {
1833         strcpy(Main_hall_notify_text,str);
1834         Main_hall_notify_stamp = timestamp(MAIN_HALL_NOTIFY_TIME);
1835 }
1836
1837 void main_hall_notify_do()
1838 {
1839         // check to see if we should try and do something
1840         if(Main_hall_notify_stamp != -1){
1841            // if the text time has expired
1842                 if(timestamp_elapsed(Main_hall_notify_stamp)){
1843                         strcpy(Main_hall_notify_text,"");
1844                         Main_hall_notify_stamp = -1;
1845                 } else {
1846                         int w,h;
1847                         gr_set_color_fast(&Color_bright);
1848
1849                         gr_get_string_size(&w,&h,Main_hall_notify_text);
1850                         gr_printf((gr_screen.max_w - w)/2, gr_screen.max_h - 40, Main_hall_notify_text);
1851                 }
1852         }
1853 }
1854
1855 // start a looping ambient sound for main hall
1856 void main_hall_start_ambient()
1857 {
1858         int play_ambient_loop = 0;
1859
1860         if ( Main_hall_ambient_loop == -1 ) {
1861                 play_ambient_loop = 1;
1862         } else {
1863                 if ( !snd_is_playing(Main_hall_ambient_loop) ) {
1864                         play_ambient_loop = 1;
1865                 }
1866         }
1867
1868         if ( play_ambient_loop ) {
1869                 Main_hall_ambient_loop = snd_play_looping(&Snds_iface[SND_MAIN_HALL_AMBIENT]);
1870         }
1871 }
1872
1873 // stop a looping ambient sound for the main hall
1874 void main_hall_stop_ambient()
1875 {
1876         if ( Main_hall_ambient_loop != -1 ) {
1877                 snd_stop(Main_hall_ambient_loop);
1878                 Main_hall_ambient_loop = -1;
1879         }
1880 }
1881
1882 // Reset the volume of the looping ambient sound.  This is called from the options 
1883 // screen when the looping ambient sound might be playing.
1884 void main_hall_reset_ambient_vol()
1885 {
1886         if ( Main_hall_ambient_loop >= 0 ) {
1887                 snd_set_volume(Main_hall_ambient_loop, Snds_iface[SND_MAIN_HALL_AMBIENT].default_volume);
1888         }
1889 }
1890
1891 // blit the freespace version #
1892 void main_hall_blit_version()
1893 {
1894         char version_string[100];
1895         int w;
1896
1897         // format the version string
1898         get_version_string(version_string);
1899
1900         // get the length of the string
1901         gr_get_string_size(&w,NULL,version_string);
1902
1903         // print the string out in the lower right corner
1904         gr_set_color_fast(&Color_white);
1905         gr_string(gr_screen.max_w - 55, gr_screen.max_h - 12, version_string);
1906 }
1907
1908 // blit any necessary tooltips
1909 void main_hall_maybe_blit_tooltips()
1910 {
1911         int w;
1912         int text_index;
1913
1914         // if we're over no region - don't blit anything
1915         if(Main_hall_mouse_region < 0) {
1916                 return;
1917         }
1918
1919         // get the index of the proper text to be using
1920         if(Main_hall_mouse_region == READY_ROOM_REGION) {
1921                 // if this is a multiplayer pilot, the ready room region becomes the multiplayer region
1922                 if(Player->flags & PLAYER_FLAGS_IS_MULTI){
1923                         text_index = NUM_REGIONS - 1;
1924                 } else {
1925                         text_index = READY_ROOM_REGION;
1926                 }
1927         } else {
1928                 text_index = Main_hall_mouse_region;
1929         }
1930
1931         // set the color and blit the string
1932         if(!help_overlay_active(Main_hall_overlay_id)) {
1933 #ifndef MAKE_FS1
1934                 int shader_y = (Main_hall->region_yval) - Main_hall_tooltip_padding[gr_screen.res];     // subtract more to pull higher
1935 #endif
1936                 // get the width of the string
1937                 gr_get_string_size(&w, NULL, Main_hall->region_descript[text_index]);
1938
1939 #ifndef MAKE_FS1
1940                 gr_set_shader(&Main_hall_tooltip_shader);
1941                 gr_shade(0, shader_y, gr_screen.clip_width, (gr_screen.clip_height - shader_y));
1942 #endif
1943 #ifdef MAKE_FS1
1944                 gr_set_color_fast(&Color_white);
1945 #else
1946                 gr_set_color_fast(&Color_bright_white);
1947 #endif
1948                 gr_string((gr_screen.max_w - w)/2, Main_hall->region_yval, Main_hall->region_descript[text_index]);
1949         }
1950 }
1951
1952
1953 void main_hall_process_help_stuff()
1954 {
1955         int w, h;
1956         char str[255];
1957         
1958         // if the timestamp has popped, don't do anything
1959         if(Main_hall_help_stamp == -1) {
1960                 return;
1961         }
1962
1963         // if the timestamp has popped, advance frame
1964         if(timestamp_elapsed(Main_hall_help_stamp)) {
1965                 Main_hall_f1_text_frame++;
1966         }
1967
1968         // otherwise print out the message
1969         strcpy(str, XSTR( "Press F1 for help", 371));
1970         gr_get_string_size(&w, &h, str);
1971
1972         int y_anim_offset = Main_hall_f1_text_frame;
1973
1974         // if anim is off the screen finally, stop altogether
1975         if ( (y_anim_offset >= (2*Main_hall_tooltip_padding[gr_screen.res]) + h) || (help_overlay_active(Main_hall_overlay_id)) ) {
1976                 Main_hall_f1_text_frame = -1;
1977                 Main_hall_help_stamp = -1;
1978                 F1_text_done = 1;
1979                 return;
1980         }
1981
1982         // set the color and print out text and shader
1983 #ifndef MAKE_FS1
1984         gr_set_color_fast(&Color_bright_white);
1985         gr_shade(0, 0, gr_screen.max_w, (2*Main_hall_tooltip_padding[gr_screen.res]) + h - y_anim_offset);
1986         gr_string((gr_screen.max_w - w)/2, Main_hall_tooltip_padding[gr_screen.res] - y_anim_offset, str);
1987 #else
1988         gr_set_color_fast(&Color_white);
1989         // no shading, no roll off screen
1990         gr_string((gr_screen.max_w - w)/2, Main_hall_tooltip_padding[gr_screen.res], str);
1991 #endif
1992 }
1993
1994 // what main hall we're on (should be 0 or 1)
1995 int main_hall_id()
1996 {       
1997         // only 1 of 2 main halls
1998         if(Main_hall == &Main_hall_defines[gr_screen.res][0]){
1999                 return 0;
2000         }
2001
2002         return 1;
2003
2004
2005 // read in main hall table
2006 void main_hall_read_table()
2007 {
2008 #ifndef MAKE_FS1
2009         main_hall_defines *m, temp;
2010         int count, idx, s_idx, m_idx;
2011
2012         // read the file in
2013         read_file_text("mainhall.tbl");
2014         reset_parse();
2015
2016         // go for it
2017         count = 0;
2018         while(!optional_string("#end")){
2019
2020                 // read in 2 resolutions
2021                 for(m_idx=0; m_idx<GR_NUM_RESOLUTIONS; m_idx++){
2022                         // maybe use a temp main hall stuct
2023                         if(count >= NUM_MAIN_HALLS){
2024                                 m = &temp;
2025                         } else {
2026                                 m = &Main_hall_defines[m_idx][count];
2027                         }
2028
2029                         // ready
2030                         required_string("$Main Hall");
2031
2032                         // bitmap and mask
2033                         required_string("+Bitmap:");
2034                         stuff_string(m->bitmap, F_NAME, NULL, MAX_FILENAME_LEN);
2035                         required_string("+Mask:");
2036                         stuff_string(m->mask, F_NAME, NULL, MAX_FILENAME_LEN);
2037 #ifndef FS2_DEMO
2038                         required_string("+Music:");
2039                         stuff_string(m->music, F_NAME, NULL, MAX_FILENAME_LEN);
2040 #endif
2041
2042                         // intercom sounds
2043                         required_string("+Num Intercom Sounds:");
2044                         stuff_int(&m->num_random_intercom_sounds);              
2045                         for(idx=0; idx<m->num_random_intercom_sounds; idx++){                   
2046                                 // intercom delay
2047                                 required_string("+Intercom delay:");
2048                                 stuff_int(&m->intercom_delay[idx][0]);
2049                                 stuff_int(&m->intercom_delay[idx][1]);
2050                         }
2051                         for(idx=0; idx<m->num_random_intercom_sounds; idx++){                   
2052                                 // intercom sound id
2053                                 required_string("+Intercom sound:");
2054                                 stuff_int(&m->intercom_sounds[idx]);                    
2055                         }                       
2056                         for(idx=0; idx<m->num_random_intercom_sounds; idx++){                   
2057                                 // intercom pan
2058                                 required_string("+Intercom pan:");
2059                                 stuff_float(&m->intercom_sound_pan[idx]);                       
2060                         }                       
2061
2062                         // misc animations
2063                         required_string("+Num Misc Animations:");
2064                         stuff_int(&m->num_misc_animations);
2065                         for(idx=0; idx<m->num_misc_animations; idx++){
2066                                 // anim names
2067                                 required_string("+Misc anim:");
2068                                 stuff_string(m->misc_anim_name[idx], F_NAME, NULL);
2069                         }
2070                         for(idx=0; idx<m->num_misc_animations; idx++){
2071                                 // anim delay
2072                                 required_string("+Misc anim delay:");
2073                                 stuff_int(&m->misc_anim_delay[idx][0]);
2074                                 stuff_int(&m->misc_anim_delay[idx][1]);
2075                                 stuff_int(&m->misc_anim_delay[idx][2]);
2076                         }
2077                         for(idx=0; idx<m->num_misc_animations; idx++){
2078                                 // anim coords
2079                                 required_string("+Misc anim coords:");
2080                                 stuff_int(&m->misc_anim_coords[idx][0]);
2081                                 stuff_int(&m->misc_anim_coords[idx][1]);
2082                         }
2083                         for(idx=0; idx<m->num_misc_animations; idx++){
2084                                 // anim mode
2085                                 required_string("+Misc anim mode:");
2086                                 stuff_int(&m->misc_anim_modes[idx]);                    
2087                         }
2088                         for(idx=0; idx<m->num_misc_animations; idx++){
2089                                 // anim pan
2090                                 required_string("+Misc anim pan:");
2091                                 stuff_float(&m->misc_anim_sound_pan[idx]);
2092                         }
2093                         for(idx=0; idx<m->num_misc_animations; idx++){
2094                                 // anim sound id
2095                                 required_string("+Misc anim sounds:");
2096                                 stuff_int(&m->misc_anim_special_sounds[idx][0]);
2097                                 for(s_idx=0; s_idx<m->misc_anim_special_sounds[idx][0]; s_idx++){
2098                                         stuff_int(&m->misc_anim_special_sounds[idx][s_idx + 1]);
2099                                 }
2100                         }
2101                         for(idx=0; idx<m->num_misc_animations; idx++){
2102                                 // anim sound triggers
2103                                 required_string("+Misc anim trigger:");
2104                                 stuff_int(&m->misc_anim_special_trigger[idx][0]);
2105                                 for(s_idx=0; s_idx<m->misc_anim_special_trigger[idx][0]; s_idx++){
2106                                         stuff_int(&m->misc_anim_special_trigger[idx][s_idx + 1]);
2107                                 }
2108                         }
2109                         for(idx=0; idx<m->num_misc_animations; idx++){
2110                                 // anim sound handles
2111                                 required_string("+Misc anim handles:");
2112                                 stuff_int(&m->misc_anim_sound_handles[idx][0]);                 
2113                         }
2114                         for(idx=0; idx<m->num_misc_animations; idx++){
2115                                 // anim sound flags
2116                                 required_string("+Misc anim flags:");
2117                                 stuff_int(&m->misc_anim_sound_flag[idx][0]);                    
2118                         }
2119
2120                         // door animations
2121                         required_string("+Num Door Animations:");
2122                         stuff_int(&m->num_door_animations);
2123                         for(idx=0; idx<m->num_door_animations; idx++){
2124                                 // door name
2125                                 required_string("+Door anim:");
2126                                 stuff_string(m->door_anim_name[idx], F_NAME, NULL);
2127                         }
2128                         for(idx=0; idx<m->num_door_animations; idx++){
2129                                 // door coords
2130                                 required_string("+Door coords:");
2131                                 stuff_int(&m->door_anim_coords[idx][0]);
2132                                 stuff_int(&m->door_anim_coords[idx][1]);
2133                                 stuff_int(&m->door_anim_coords[idx][2]);
2134                                 stuff_int(&m->door_anim_coords[idx][3]);
2135                         }
2136                         for(idx=0; idx<m->num_door_animations; idx++){
2137                                 // door open and close sounds
2138                                 required_string("+Door sounds:");
2139                                 stuff_int(&m->door_sounds[idx][0]);
2140                                 stuff_int(&m->door_sounds[idx][1]);                     
2141                         }
2142                         for(idx=0; idx<m->num_door_animations; idx++){
2143                                 // door pan value
2144                                 required_string("+Door pan:");
2145                                 stuff_float(&m->door_sound_pan[idx]);                   
2146                         }
2147
2148                         // tooltip y location
2149                         required_string("+Tooltip Y:");
2150                         stuff_int(&m->region_yval);
2151                         for(idx=0; idx<NUM_REGIONS; idx++){
2152                                 m->region_descript[idx] = NULL;
2153                         }
2154                 }
2155
2156                 if(count < NUM_MAIN_HALLS){
2157                         count++;
2158                 }
2159         }
2160 #else
2161         // hard coded values for FS1
2162         int idx;
2163
2164         // Terran main hall
2165         strncpy(Main_hall_defines[0][0].bitmap, "MainHall1", MAX_FILENAME_LEN);
2166         strncpy(Main_hall_defines[0][0].mask, "MainHall1-m", MAX_FILENAME_LEN);
2167         strncpy(Main_hall_defines[0][0].music, "main_amb", MAX_FILENAME_LEN);
2168         
2169         Main_hall_defines[0][0].num_random_intercom_sounds = 3;
2170         Main_hall_defines[0][0].intercom_delay[0][0] = 8000;
2171         Main_hall_defines[0][0].intercom_delay[0][1] = 15000;
2172         Main_hall_defines[0][0].intercom_delay[1][0] = 8000;
2173         Main_hall_defines[0][0].intercom_delay[1][1] = 15000;
2174         Main_hall_defines[0][0].intercom_delay[2][0] = 8000;
2175         Main_hall_defines[0][0].intercom_delay[2][1] = 15000;
2176         Main_hall_defines[0][0].intercom_sounds[0] = 38;
2177         Main_hall_defines[0][0].intercom_sounds[1] = 39;
2178         Main_hall_defines[0][0].intercom_sounds[2] = 40;
2179         Main_hall_defines[0][0].intercom_sound_pan[0] = 0.0f;
2180         Main_hall_defines[0][0].intercom_sound_pan[1] = 0.0f;
2181         Main_hall_defines[0][0].intercom_sound_pan[2] = 0.0f;
2182         
2183         Main_hall_defines[0][0].num_misc_animations = 2;
2184         strncpy(Main_hall_defines[0][0].misc_anim_name[0], "main1-m1", MAX_FILENAME_LEN);
2185         strncpy(Main_hall_defines[0][0].misc_anim_name[1], "main1-m2", MAX_FILENAME_LEN);
2186         Main_hall_defines[0][0].misc_anim_delay[0][0] = -1;
2187         Main_hall_defines[0][0].misc_anim_delay[0][1] = 15000;
2188         Main_hall_defines[0][0].misc_anim_delay[0][2] = 20000;
2189         Main_hall_defines[0][0].misc_anim_delay[1][0] = -1;
2190         Main_hall_defines[0][0].misc_anim_delay[1][1] = 9000;
2191         Main_hall_defines[0][0].misc_anim_delay[1][2] = 30000;
2192         Main_hall_defines[0][0].misc_anim_coords[0][0] = 14;
2193         Main_hall_defines[0][0].misc_anim_coords[0][1] = 14;
2194         Main_hall_defines[0][0].misc_anim_coords[1][0] = 174;
2195         Main_hall_defines[0][0].misc_anim_coords[1][1] = 198;
2196         Main_hall_defines[0][0].misc_anim_modes[0] = 0;
2197         Main_hall_defines[0][0].misc_anim_modes[1] = 2;
2198         Main_hall_defines[0][0].misc_anim_sound_pan[0] = -0.5f;
2199         Main_hall_defines[0][0].misc_anim_sound_pan[1] = -0.25f;
2200         Main_hall_defines[0][0].misc_anim_special_sounds[0][0] = 2;
2201         Main_hall_defines[0][0].misc_anim_special_sounds[0][1] = 34;
2202         Main_hall_defines[0][0].misc_anim_special_sounds[0][2] = 35;
2203         Main_hall_defines[0][0].misc_anim_special_sounds[1][0] = 3;
2204         Main_hall_defines[0][0].misc_anim_special_sounds[1][1] = 31;
2205         Main_hall_defines[0][0].misc_anim_special_sounds[1][2] = 32;
2206         Main_hall_defines[0][0].misc_anim_special_sounds[1][3] = 33;
2207         Main_hall_defines[0][0].misc_anim_special_trigger[0][0] = 4;
2208         Main_hall_defines[0][0].misc_anim_special_trigger[0][1] = 1;
2209         Main_hall_defines[0][0].misc_anim_special_trigger[0][2] = 20;
2210         Main_hall_defines[0][0].misc_anim_special_trigger[0][3] = 42;
2211         Main_hall_defines[0][0].misc_anim_special_trigger[0][4] = 96;
2212         Main_hall_defines[0][0].misc_anim_special_trigger[1][0] = 3;
2213         Main_hall_defines[0][0].misc_anim_special_trigger[1][1] = 25;
2214         Main_hall_defines[0][0].misc_anim_special_trigger[1][2] = 200;
2215         Main_hall_defines[0][0].misc_anim_special_trigger[1][3] = 274;
2216         Main_hall_defines[0][0].misc_anim_sound_handles[0][0] = 2;
2217         Main_hall_defines[0][0].misc_anim_sound_handles[1][0] = 3;
2218         Main_hall_defines[0][0].misc_anim_sound_flag[0][0] = 1;
2219         Main_hall_defines[0][0].misc_anim_sound_flag[1][0] = 2;
2220         
2221         Main_hall_defines[0][0].num_door_animations = 6;
2222         strncpy(Main_hall_defines[0][0].door_anim_name[0], "main1-d1", MAX_FILENAME_LEN);
2223         strncpy(Main_hall_defines[0][0].door_anim_name[1], "main1-d6", MAX_FILENAME_LEN);
2224         strncpy(Main_hall_defines[0][0].door_anim_name[2], "main1-d3", MAX_FILENAME_LEN);
2225         strncpy(Main_hall_defines[0][0].door_anim_name[3], "main1-d4", MAX_FILENAME_LEN);
2226         strncpy(Main_hall_defines[0][0].door_anim_name[4], "main1-d5", MAX_FILENAME_LEN);
2227         strncpy(Main_hall_defines[0][0].door_anim_name[5], "main1-d2", MAX_FILENAME_LEN);
2228         Main_hall_defines[0][0].door_anim_coords[0][0] = 68;
2229         Main_hall_defines[0][0].door_anim_coords[0][1] = 260;
2230         Main_hall_defines[0][0].door_anim_coords[0][2] = 103;
2231         Main_hall_defines[0][0].door_anim_coords[0][3] = 298;
2232         Main_hall_defines[0][0].door_anim_coords[1][0] = 309;
2233         Main_hall_defines[0][0].door_anim_coords[1][1] = 34;
2234         Main_hall_defines[0][0].door_anim_coords[1][2] = 110;
2235         Main_hall_defines[0][0].door_anim_coords[1][3] = 61;
2236         Main_hall_defines[0][0].door_anim_coords[2][0] = 312;
2237         Main_hall_defines[0][0].door_anim_coords[2][1] = 264;
2238         Main_hall_defines[0][0].door_anim_coords[2][2] = 385;
2239         Main_hall_defines[0][0].door_anim_coords[2][3] = 330;
2240         Main_hall_defines[0][0].door_anim_coords[3][0] = 457;
2241         Main_hall_defines[0][0].door_anim_coords[3][1] = 34;
2242         Main_hall_defines[0][0].door_anim_coords[3][2] = 404;
2243         Main_hall_defines[0][0].door_anim_coords[3][3] = 367;
2244         Main_hall_defines[0][0].door_anim_coords[4][0] = 530;
2245         Main_hall_defines[0][0].door_anim_coords[4][1] = 206;
2246         Main_hall_defines[0][0].door_anim_coords[4][2] = 174;
2247         Main_hall_defines[0][0].door_anim_coords[4][3] = 412;
2248         Main_hall_defines[0][0].door_anim_coords[5][0] = 305;
2249         Main_hall_defines[0][0].door_anim_coords[5][1] = 133;
2250         Main_hall_defines[0][0].door_anim_coords[5][2] = 385;
2251         Main_hall_defines[0][0].door_anim_coords[5][3] = 330;
2252         Main_hall_defines[0][0].door_sounds[0][0] = 23;
2253         Main_hall_defines[0][0].door_sounds[0][1] = 24;
2254         Main_hall_defines[0][0].door_sounds[1][0] = 23;
2255         Main_hall_defines[0][0].door_sounds[1][1] = 24;
2256         Main_hall_defines[0][0].door_sounds[2][0] = 23;
2257         Main_hall_defines[0][0].door_sounds[2][1] = 24;
2258         Main_hall_defines[0][0].door_sounds[3][0] = 25;
2259         Main_hall_defines[0][0].door_sounds[3][1] = 26;
2260         Main_hall_defines[0][0].door_sounds[4][0] = 25;
2261         Main_hall_defines[0][0].door_sounds[4][1] = 26;
2262         Main_hall_defines[0][0].door_sounds[5][0] = 23;
2263         Main_hall_defines[0][0].door_sounds[5][1] = 24;
2264         Main_hall_defines[0][0].door_sound_pan[0] = -0.7f;
2265         Main_hall_defines[0][0].door_sound_pan[1] = 0.07f;
2266         Main_hall_defines[0][0].door_sound_pan[2] = 0.2f;
2267         Main_hall_defines[0][0].door_sound_pan[3] = 0.73f;
2268         Main_hall_defines[0][0].door_sound_pan[4] = 0.75f;
2269         Main_hall_defines[0][0].door_sound_pan[5] = 0.11f;
2270         
2271         Main_hall_defines[0][0].region_yval = 455;
2272         
2273         for (idx = 0; idx < NUM_REGIONS; idx++) {
2274                 Main_hall_defines[0][0].region_descript[idx] = NULL;
2275         }
2276         
2277         
2278         // Vasudan main hall
2279         strncpy(Main_hall_defines[0][1].bitmap, "MainHall2", MAX_FILENAME_LEN);
2280         strncpy(Main_hall_defines[0][1].mask, "MainHall2-m", MAX_FILENAME_LEN);
2281         strncpy(Main_hall_defines[0][1].music, "main_amb", MAX_FILENAME_LEN);
2282         
2283         Main_hall_defines[0][1].num_random_intercom_sounds = 3;
2284         Main_hall_defines[0][1].intercom_delay[0][0] = 8000;
2285         Main_hall_defines[0][1].intercom_delay[0][1] = 15000;
2286         Main_hall_defines[0][1].intercom_delay[1][0] = 8000;
2287         Main_hall_defines[0][1].intercom_delay[1][1] = 15000;
2288         Main_hall_defines[0][1].intercom_delay[2][0] = 8000;
2289         Main_hall_defines[0][1].intercom_delay[2][1] = 15000;
2290         Main_hall_defines[0][1].intercom_sounds[0] = 49;
2291         Main_hall_defines[0][1].intercom_sounds[1] = 50;
2292         Main_hall_defines[0][1].intercom_sounds[2] = 51;
2293         Main_hall_defines[0][1].intercom_sound_pan[0] = 0.0f;
2294         Main_hall_defines[0][1].intercom_sound_pan[1] = 0.0f;
2295         Main_hall_defines[0][1].intercom_sound_pan[2] = 0.0f;
2296         
2297         Main_hall_defines[0][1].num_misc_animations = 4;
2298         strncpy(Main_hall_defines[0][1].misc_anim_name[0], "main2-m1", MAX_FILENAME_LEN);
2299         strncpy(Main_hall_defines[0][1].misc_anim_name[1], "main2-m2", MAX_FILENAME_LEN);
2300         strncpy(Main_hall_defines[0][1].misc_anim_name[2], "main2-m3", MAX_FILENAME_LEN);
2301         strncpy(Main_hall_defines[0][1].misc_anim_name[3], "main2-m4", MAX_FILENAME_LEN);
2302         Main_hall_defines[0][1].misc_anim_delay[0][0] = -1;
2303         Main_hall_defines[0][1].misc_anim_delay[0][1] = 0;
2304         Main_hall_defines[0][1].misc_anim_delay[0][2] = 0;
2305         Main_hall_defines[0][1].misc_anim_delay[1][0] = -1;
2306         Main_hall_defines[0][1].misc_anim_delay[1][1] = 0;
2307         Main_hall_defines[0][1].misc_anim_delay[1][2] = 0;
2308         Main_hall_defines[0][1].misc_anim_delay[2][0] = -1;
2309         Main_hall_defines[0][1].misc_anim_delay[2][1] = 0;
2310         Main_hall_defines[0][1].misc_anim_delay[2][2] = 0;
2311         Main_hall_defines[0][1].misc_anim_delay[3][0] = -1;
2312         Main_hall_defines[0][1].misc_anim_delay[3][1] = 5000;
2313         Main_hall_defines[0][1].misc_anim_delay[3][2] = 9000;
2314         Main_hall_defines[0][1].misc_anim_coords[0][0] = 0;
2315         Main_hall_defines[0][1].misc_anim_coords[0][1] = 37;
2316         Main_hall_defines[0][1].misc_anim_coords[1][0] = 59;
2317         Main_hall_defines[0][1].misc_anim_coords[1][1] = 0;
2318         Main_hall_defines[0][1].misc_anim_coords[2][0] = 80;
2319         Main_hall_defines[0][1].misc_anim_coords[2][1] = 115;
2320         Main_hall_defines[0][1].misc_anim_coords[3][0] = 0;
2321         Main_hall_defines[0][1].misc_anim_coords[3][1] = 182;
2322         Main_hall_defines[0][1].misc_anim_modes[0] = 0;
2323         Main_hall_defines[0][1].misc_anim_modes[1] = 0;
2324         Main_hall_defines[0][1].misc_anim_modes[2] = 0;
2325         Main_hall_defines[0][1].misc_anim_modes[3] = 1;
2326         Main_hall_defines[0][1].misc_anim_sound_pan[0] = -0.82f;
2327         Main_hall_defines[0][1].misc_anim_sound_pan[1] = -0.5f;
2328         Main_hall_defines[0][1].misc_anim_sound_pan[2] = -0.5f;
2329         Main_hall_defines[0][1].misc_anim_sound_pan[3] = -0.86f;
2330         Main_hall_defines[0][1].misc_anim_special_sounds[0][0] = 2;
2331         Main_hall_defines[0][1].misc_anim_special_sounds[0][1] = 43;
2332         Main_hall_defines[0][1].misc_anim_special_sounds[0][2] = 44;
2333         Main_hall_defines[0][1].misc_anim_special_sounds[1][0] = 2;
2334         Main_hall_defines[0][1].misc_anim_special_sounds[1][1] = 45;
2335         Main_hall_defines[0][1].misc_anim_special_sounds[1][2] = 46;
2336         Main_hall_defines[0][1].misc_anim_special_sounds[2][0] = 2;
2337         Main_hall_defines[0][1].misc_anim_special_sounds[2][1] = 45;
2338         Main_hall_defines[0][1].misc_anim_special_sounds[2][2] = 46;
2339         Main_hall_defines[0][1].misc_anim_special_sounds[3][0] = 2;
2340         Main_hall_defines[0][1].misc_anim_special_sounds[3][1] = 47;
2341         Main_hall_defines[0][1].misc_anim_special_sounds[3][2] = 48;
2342         Main_hall_defines[0][1].misc_anim_special_trigger[0][0] = 2;
2343         Main_hall_defines[0][1].misc_anim_special_trigger[0][1] = 0;
2344         Main_hall_defines[0][1].misc_anim_special_trigger[0][2] = 300;
2345         Main_hall_defines[0][1].misc_anim_special_trigger[1][0] = 2;
2346         Main_hall_defines[0][1].misc_anim_special_trigger[1][1] = 20;
2347         Main_hall_defines[0][1].misc_anim_special_trigger[1][2] = 262;
2348         Main_hall_defines[0][1].misc_anim_special_trigger[2][0] = 2;
2349         Main_hall_defines[0][1].misc_anim_special_trigger[2][1] = 0;
2350         Main_hall_defines[0][1].misc_anim_special_trigger[2][2] = 150;
2351         Main_hall_defines[0][1].misc_anim_special_trigger[3][0] = 2;
2352         Main_hall_defines[0][1].misc_anim_special_trigger[3][1] = 128;
2353         Main_hall_defines[0][1].misc_anim_special_trigger[3][2] = 300;
2354         Main_hall_defines[0][1].misc_anim_sound_handles[0][0] = 2;
2355         Main_hall_defines[0][1].misc_anim_sound_handles[1][0] = 2;
2356         Main_hall_defines[0][1].misc_anim_sound_handles[2][0] = 2;
2357         Main_hall_defines[0][1].misc_anim_sound_handles[3][0] = 2;
2358         Main_hall_defines[0][1].misc_anim_sound_flag[0][0] = 2;
2359         Main_hall_defines[0][1].misc_anim_sound_flag[1][0] = 2;
2360         Main_hall_defines[0][1].misc_anim_sound_flag[2][0] = 2;
2361         Main_hall_defines[0][1].misc_anim_sound_flag[3][0] = 2;
2362         
2363         Main_hall_defines[0][1].num_door_animations = 6;
2364         strncpy(Main_hall_defines[0][1].door_anim_name[0], "main2-d1", MAX_FILENAME_LEN);
2365         strncpy(Main_hall_defines[0][1].door_anim_name[1], "main2-d6", MAX_FILENAME_LEN);
2366         strncpy(Main_hall_defines[0][1].door_anim_name[2], "main2-d3", MAX_FILENAME_LEN);
2367         strncpy(Main_hall_defines[0][1].door_anim_name[3], "main2-d4", MAX_FILENAME_LEN);
2368         strncpy(Main_hall_defines[0][1].door_anim_name[4], "main2-d5", MAX_FILENAME_LEN);
2369         strncpy(Main_hall_defines[0][1].door_anim_name[5], "main2-d2", MAX_FILENAME_LEN);
2370         Main_hall_defines[0][1].door_anim_coords[0][0] = 199;
2371         Main_hall_defines[0][1].door_anim_coords[0][1] = 265;
2372         Main_hall_defines[0][1].door_anim_coords[0][2] = 263;
2373         Main_hall_defines[0][1].door_anim_coords[0][3] = 295;
2374         Main_hall_defines[0][1].door_anim_coords[1][0] = 296;
2375         Main_hall_defines[0][1].door_anim_coords[1][1] = 278;
2376         Main_hall_defines[0][1].door_anim_coords[1][2] = 331;
2377         Main_hall_defines[0][1].door_anim_coords[1][3] = 209;
2378         Main_hall_defines[0][1].door_anim_coords[2][0] = 423;
2379         Main_hall_defines[0][1].door_anim_coords[2][1] = 138;
2380         Main_hall_defines[0][1].door_anim_coords[2][2] = 531;
2381         Main_hall_defines[0][1].door_anim_coords[2][3] = 240;
2382         Main_hall_defines[0][1].door_anim_coords[3][0] = 363;
2383         Main_hall_defines[0][1].door_anim_coords[3][1] = 187;
2384         Main_hall_defines[0][1].door_anim_coords[3][2] = 395;
2385         Main_hall_defines[0][1].door_anim_coords[3][3] = 218;
2386         Main_hall_defines[0][1].door_anim_coords[4][0] = 47;
2387         Main_hall_defines[0][1].door_anim_coords[4][1] = 307;
2388         Main_hall_defines[0][1].door_anim_coords[4][2] = 101;
2389         Main_hall_defines[0][1].door_anim_coords[4][3] = 342;
2390         Main_hall_defines[0][1].door_anim_coords[5][0] = 325;
2391         Main_hall_defines[0][1].door_anim_coords[5][1] = 311;
2392         Main_hall_defines[0][1].door_anim_coords[5][2] = 362;
2393         Main_hall_defines[0][1].door_anim_coords[5][3] = 371;
2394         Main_hall_defines[0][1].door_sounds[0][0] = 23;
2395         Main_hall_defines[0][1].door_sounds[0][1] = 24;
2396         Main_hall_defines[0][1].door_sounds[1][0] = 23;
2397         Main_hall_defines[0][1].door_sounds[1][1] = 24;
2398         Main_hall_defines[0][1].door_sounds[2][0] = 23;
2399         Main_hall_defines[0][1].door_sounds[2][1] = 24;
2400         Main_hall_defines[0][1].door_sounds[3][0] = 25;
2401         Main_hall_defines[0][1].door_sounds[3][1] = 26;
2402         Main_hall_defines[0][1].door_sounds[4][0] = 25;
2403         Main_hall_defines[0][1].door_sounds[4][1] = 26;
2404         Main_hall_defines[0][1].door_sounds[5][0] = 23;
2405         Main_hall_defines[0][1].door_sounds[5][1] = 24;
2406         Main_hall_defines[0][1].door_sound_pan[0] = -0.2f;
2407         Main_hall_defines[0][1].door_sound_pan[1] = 0.12f;
2408         Main_hall_defines[0][1].door_sound_pan[2] = 0.62f;
2409         Main_hall_defines[0][1].door_sound_pan[3] = 0.2f;
2410         Main_hall_defines[0][1].door_sound_pan[4] = -0.63f;
2411         Main_hall_defines[0][1].door_sound_pan[5] = 0.35f;
2412         
2413         Main_hall_defines[0][1].region_yval = 425;
2414         
2415         for (idx = 0; idx < NUM_REGIONS; idx++) {
2416                 Main_hall_defines[0][1].region_descript[idx] = NULL;
2417         }
2418
2419 #endif
2420
2421         // are we funny?
2422         if(Vasudan_funny){
2423                 Main_hall_defines[GR_640][1].door_sounds[OPTIONS_REGION][0] = SND_VASUDAN_BUP;
2424                 Main_hall_defines[GR_640][1].door_sounds[OPTIONS_REGION][1] = SND_VASUDAN_BUP;
2425                 Main_hall_defines[GR_1024][1].door_sounds[OPTIONS_REGION][0] = SND_VASUDAN_BUP;
2426                 Main_hall_defines[GR_1024][1].door_sounds[OPTIONS_REGION][1] = SND_VASUDAN_BUP;
2427
2428                 // set head anim. hehe
2429                 strcpy(Main_hall_defines[GR_640][1].door_anim_name[OPTIONS_REGION], "vhallheads");
2430                 strcpy(Main_hall_defines[GR_1024][1].door_anim_name[OPTIONS_REGION], "2_vhallheads");
2431
2432                 // set the background
2433                 strcpy(Main_hall_defines[GR_640][1].bitmap, "vhallhead");
2434                 strcpy(Main_hall_defines[GR_1024][1].bitmap, "2_vhallhead");            
2435         }
2436 }
2437
2438 // make the vasudan main hall funny
2439 void main_hall_vasudan_funny()
2440 {
2441         Vasudan_funny = 1;
2442 }
2443
2444
2445 /*
2446 #include "3d.h"
2447 int argh = -1;
2448 matrix view = {
2449         0.0f, 0.0f, 0.0f,
2450         0.0f, 0.0f, 0.0f,
2451         0.0f, 0.0f, 1.0f
2452 };
2453 */
2454 void d3d_test()
2455 {
2456         /*      
2457         vertex p1;
2458         vector sun_pos = vmd_zero_vector;
2459         sun_pos.z = 1.0f;
2460
2461         if(argh == -1){
2462                 argh = bm_load("sun01");
2463                 bm_lock(argh, 16, BMP_TEX_XPARENT);
2464                 bm_unlock(argh);
2465         }
2466         
2467         g3_start_frame(1);
2468         g3_set_view_matrix(&vmd_zero_vector, &view, 0.5f);      
2469         g3_rotate_vertex(&p1, &sun_pos);
2470         g3_project_vertex(&p1);
2471         gr_zbuffer_set(GR_ZBUFF_NONE);
2472         gr_set_bitmap( argh );
2473         g3_draw_bitmap(&p1, 0, 0.05f, TMAP_FLAG_TEXTURED | TMAP_FLAG_XPARENT);          
2474         g3_end_frame();
2475         */
2476 }
2477