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