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